From 7e36e2f5355ab87f8946041d044b34cda01e2077 Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Tue, 1 Apr 2008 10:53:23 +0100 Subject: [ARM] 4874/2: ixp4xx: Add support for the Freecom FSG-3 board The Freecom-FSG3 is a small network-attached-storage device with the following feature set: * Intel IXP422 * 4MB Flash (ixp4xx flash driver) * 64MB RAM * 4 USB 2.0 host ports (ehci and ohci drivers) * 1 WAN (eth1) and 3 LAN (eth0) ethernet ports * Supported by the open source ixp4xx ethernet driver * Via VT6421 disk controller (libata and sata-via drivers) * Internal hard disk (PATA supported, SATA not yet supported) * External SATA port (not yet supported) * ISL1208 RTC chip * Winbond 83782 temp sensor and fan controller * MiniPCI slot The ixp4xx_defconfig is also updated to support this device (the leds-fsg driver is to be submitted separately via the leds tree after this initial support is merged, as it depends on header gpio defines). Signed-off-by: Rod Whitby Signed-off-by: Russell King diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index efa0485..fc14932 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -165,6 +165,7 @@ CONFIG_ARCH_PRPMC1100=y CONFIG_MACH_NAS100D=y CONFIG_MACH_DSMG600=y CONFIG_ARCH_IXDP4XX=y +CONFIG_MACH_FSG=y CONFIG_CPU_IXP46X=y CONFIG_CPU_IXP43X=y CONFIG_MACH_GTWX5715=y @@ -770,7 +771,7 @@ CONFIG_ATA=y # CONFIG_SATA_SIL24 is not set # CONFIG_SATA_SIS is not set # CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set +CONFIG_SATA_VIA=y # CONFIG_SATA_VITESSE is not set # CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ALI is not set @@ -1143,7 +1144,7 @@ CONFIG_HWMON=y # 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_W83781D=y # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set @@ -1334,8 +1335,8 @@ CONFIG_LEDS_CLASS=y # # LED drivers # -# CONFIG_LEDS_IXP4XX is not set CONFIG_LEDS_GPIO=y +CONFIG_LEDS_FSG=y # # LED Triggers @@ -1367,7 +1368,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set +CONFIG_RTC_DRV_ISL1208=y CONFIG_RTC_DRV_X1205=y CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_PCF8583 is not set diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index e774447..db8b5fe 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -125,6 +125,15 @@ config ARCH_IXDP4XX depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435 default y +config MACH_FSG + bool + prompt "Freecom FSG-3" + select PCI + help + Say 'Y' here if you want your kernel to support Freecom's + FSG-3 device. For more information on this platform, + see http://www.nslu2-linux.org/wiki/FSG3/HomePage + # # Certain registers and IRQs are only enabled if supporting IXP465 CPUs # diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index c195688..2e6bbf9 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -15,6 +15,7 @@ obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o +obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o obj-y += common.o @@ -28,6 +29,7 @@ obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o +obj-$(CONFIG_MACH_FSG) += fsg-setup.o obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c new file mode 100644 index 0000000..f19f3f6 --- /dev/null +++ b/arch/arm/mach-ixp4xx/fsg-pci.c @@ -0,0 +1,71 @@ +/* + * arch/arch/mach-ixp4xx/fsg-pci.c + * + * FSG board-level PCI initialization + * + * Author: Rod Whitby + * Maintainer: http://www.nslu2-linux.org/ + * + * based on ixdp425-pci.c: + * Copyright (C) 2002 Intel Corporation. + * Copyright (C) 2003-2004 MontaVista Software, 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. + * + */ + +#include +#include +#include + +#include +#include + +void __init fsg_pci_preinit(void) +{ + set_irq_type(IRQ_FSG_PCI_INTA, IRQT_LOW); + set_irq_type(IRQ_FSG_PCI_INTB, IRQT_LOW); + set_irq_type(IRQ_FSG_PCI_INTC, IRQT_LOW); + + ixp4xx_pci_preinit(); +} + +static int __init fsg_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + static int pci_irq_table[FSG_PCI_IRQ_LINES] = { + IRQ_FSG_PCI_INTC, + IRQ_FSG_PCI_INTB, + IRQ_FSG_PCI_INTA, + }; + + int irq = -1; + slot = slot - 11; + + if (slot >= 1 && slot <= FSG_PCI_MAX_DEV && + pin >= 1 && pin <= FSG_PCI_IRQ_LINES) + irq = pci_irq_table[(slot - 1)]; + printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n", + __func__, slot, pin, irq); + + return irq; +} + +struct hw_pci fsg_pci __initdata = { + .nr_controllers = 1, + .preinit = fsg_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = fsg_map_irq, +}; + +int __init fsg_pci_init(void) +{ + if (machine_is_fsg()) + pci_common_init(&fsg_pci); + return 0; +} + +subsys_initcall(fsg_pci_init); diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c new file mode 100644 index 0000000..0db3a90 --- /dev/null +++ b/arch/arm/mach-ixp4xx/fsg-setup.c @@ -0,0 +1,276 @@ +/* + * arch/arm/mach-ixp4xx/fsg-setup.c + * + * FSG board-setup + * + * Copyright (C) 2008 Rod Whitby + * + * based on ixdp425-setup.c: + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * based on nslu2-power.c + * Copyright (C) 2005 Tower Technologies + * + * Author: Rod Whitby + * Maintainers: http://www.nslu2-linux.org/ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct flash_platform_data fsg_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource fsg_flash_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device fsg_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev = { + .platform_data = &fsg_flash_data, + }, + .num_resources = 1, + .resource = &fsg_flash_resource, +}; + +static struct i2c_gpio_platform_data fsg_i2c_gpio_data = { + .sda_pin = FSG_SDA_PIN, + .scl_pin = FSG_SCL_PIN, +}; + +static struct platform_device fsg_i2c_gpio = { + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &fsg_i2c_gpio_data, + }, +}; + +static struct i2c_board_info __initdata fsg_i2c_board_info [] = { + { + I2C_BOARD_INFO("rtc-isl1208", 0x6f), + }, +}; + +static struct resource fsg_uart_resources[] = { + { + .start = IXP4XX_UART1_BASE_PHYS, + .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + } +}; + +static struct plat_serial8250_port fsg_uart_data[] = { + { + .mapbase = IXP4XX_UART1_BASE_PHYS, + .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART1, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { } +}; + +static struct platform_device fsg_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = fsg_uart_data, + }, + .num_resources = ARRAY_SIZE(fsg_uart_resources), + .resource = fsg_uart_resources, +}; + +static struct platform_device fsg_leds = { + .name = "fsg-led", + .id = -1, +}; + +/* Built-in 10/100 Ethernet MAC interfaces */ +static struct eth_plat_info fsg_plat_eth[] = { + { + .phy = 5, + .rxq = 3, + .txreadyq = 20, + }, { + .phy = 4, + .rxq = 4, + .txreadyq = 21, + } +}; + +static struct platform_device fsg_eth[] = { + { + .name = "ixp4xx_eth", + .id = IXP4XX_ETH_NPEB, + .dev = { + .platform_data = fsg_plat_eth, + }, + }, { + .name = "ixp4xx_eth", + .id = IXP4XX_ETH_NPEC, + .dev = { + .platform_data = fsg_plat_eth + 1, + }, + } +}; + +static struct platform_device *fsg_devices[] __initdata = { + &fsg_i2c_gpio, + &fsg_flash, + &fsg_leds, + &fsg_eth[0], + &fsg_eth[1], +}; + +static irqreturn_t fsg_power_handler(int irq, void *dev_id) +{ + /* Signal init to do the ctrlaltdel action, this will bypass init if + * it hasn't started and do a kernel_restart. + */ + ctrl_alt_del(); + + return IRQ_HANDLED; +} + +static irqreturn_t fsg_reset_handler(int irq, void *dev_id) +{ + /* This is the paper-clip reset which does an emergency reboot. */ + printk(KERN_INFO "Restarting system.\n"); + machine_restart(NULL); + + /* This should never be reached. */ + return IRQ_HANDLED; +} + +static void __init fsg_init(void) +{ + DECLARE_MAC_BUF(mac_buf); + uint8_t __iomem *f; + int i; + + ixp4xx_sys_init(); + + fsg_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + fsg_flash_resource.end = + IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; + + *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; + *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; + + /* Configure CS2 for operation, 8bit and writable */ + *IXP4XX_EXP_CS2 = 0xbfff0002; + + i2c_register_board_info(0, fsg_i2c_board_info, + ARRAY_SIZE(fsg_i2c_board_info)); + + /* This is only useful on a modified machine, but it is valuable + * to have it first in order to see debug messages, and so that + * it does *not* get removed if platform_add_devices fails! + */ + (void)platform_device_register(&fsg_uart); + + platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices)); + + if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler, + IRQF_DISABLED | IRQF_TRIGGER_LOW, + "FSG reset button", NULL) < 0) { + + printk(KERN_DEBUG "Reset Button IRQ %d not available\n", + gpio_to_irq(FSG_RB_GPIO)); + } + + if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler, + IRQF_DISABLED | IRQF_TRIGGER_LOW, + "FSG power button", NULL) < 0) { + + printk(KERN_DEBUG "Power Button IRQ %d not available\n", + gpio_to_irq(FSG_SB_GPIO)); + } + + /* + * Map in a portion of the flash and read the MAC addresses. + * Since it is stored in BE in the flash itself, we need to + * byteswap it if we're in LE mode. + */ + f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x400000); + if (f) { +#ifdef __ARMEB__ + for (i = 0; i < 6; i++) { + fsg_plat_eth[0].hwaddr[i] = readb(f + 0x3C0422 + i); + fsg_plat_eth[1].hwaddr[i] = readb(f + 0x3C043B + i); + } +#else + + /* + Endian-swapped reads from unaligned addresses are + required to extract the two MACs from the big-endian + Redboot config area in flash. + */ + + fsg_plat_eth[0].hwaddr[0] = readb(f + 0x3C0421); + fsg_plat_eth[0].hwaddr[1] = readb(f + 0x3C0420); + fsg_plat_eth[0].hwaddr[2] = readb(f + 0x3C0427); + fsg_plat_eth[0].hwaddr[3] = readb(f + 0x3C0426); + fsg_plat_eth[0].hwaddr[4] = readb(f + 0x3C0425); + fsg_plat_eth[0].hwaddr[5] = readb(f + 0x3C0424); + + fsg_plat_eth[1].hwaddr[0] = readb(f + 0x3C0439); + fsg_plat_eth[1].hwaddr[1] = readb(f + 0x3C043F); + fsg_plat_eth[1].hwaddr[2] = readb(f + 0x3C043E); + fsg_plat_eth[1].hwaddr[3] = readb(f + 0x3C043D); + fsg_plat_eth[1].hwaddr[4] = readb(f + 0x3C043C); + fsg_plat_eth[1].hwaddr[5] = readb(f + 0x3C0443); +#endif + iounmap(f); + } + printk(KERN_INFO "FSG: Using MAC address %s for port 0\n", + print_mac(mac_buf, fsg_plat_eth[0].hwaddr)); + printk(KERN_INFO "FSG: Using MAC address %s for port 1\n", + print_mac(mac_buf, fsg_plat_eth[1].hwaddr)); + +} + +MACHINE_START(FSG, "Freecom FSG-3") + /* Maintainer: www.nslu2-linux.org */ + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixp4xx_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .boot_params = 0x0100, + .init_machine = fsg_init, +MACHINE_END + diff --git a/include/asm-arm/arch-ixp4xx/fsg.h b/include/asm-arm/arch-ixp4xx/fsg.h new file mode 100644 index 0000000..c0100cc --- /dev/null +++ b/include/asm-arm/arch-ixp4xx/fsg.h @@ -0,0 +1,50 @@ +/* + * include/asm-arm/arch-ixp4xx/fsg.h + * + * Freecom FSG-3 platform specific definitions + * + * Author: Rod Whitby + * Author: Tomasz Chmielewski + * Maintainers: http://www.nslu2-linux.org + * + * Based on coyote.h by + * Copyright 2004 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARCH_HARDWARE_H__ +#error "Do not include this directly, instead #include " +#endif + +#define FSG_SDA_PIN 12 +#define FSG_SCL_PIN 13 + +/* + * FSG PCI IRQs + */ +#define FSG_PCI_MAX_DEV 3 +#define FSG_PCI_IRQ_LINES 3 + + +/* PCI controller GPIO to IRQ pin mappings */ +#define FSG_PCI_INTA_PIN 6 +#define FSG_PCI_INTB_PIN 7 +#define FSG_PCI_INTC_PIN 5 + +/* Buttons */ + +#define FSG_SB_GPIO 4 /* sync button */ +#define FSG_RB_GPIO 9 /* reset button */ +#define FSG_UB_GPIO 10 /* usb button */ + +/* LEDs */ + +#define FSG_LED_WLAN_BIT 0 +#define FSG_LED_WAN_BIT 1 +#define FSG_LED_SATA_BIT 2 +#define FSG_LED_USB_BIT 4 +#define FSG_LED_RING_BIT 5 +#define FSG_LED_SYNC_BIT 7 diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h index 73e8dc3..fa723a6 100644 --- a/include/asm-arm/arch-ixp4xx/hardware.h +++ b/include/asm-arm/arch-ixp4xx/hardware.h @@ -45,5 +45,6 @@ #include "nslu2.h" #include "nas100d.h" #include "dsmg600.h" +#include "fsg.h" #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h index 1180160..674af4a 100644 --- a/include/asm-arm/arch-ixp4xx/irqs.h +++ b/include/asm-arm/arch-ixp4xx/irqs.h @@ -128,4 +128,11 @@ #define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7 #define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6 +/* + * Freecom FSG-3 Board IRQs + */ +#define IRQ_FSG_PCI_INTA IRQ_IXP4XX_GPIO6 +#define IRQ_FSG_PCI_INTB IRQ_IXP4XX_GPIO7 +#define IRQ_FSG_PCI_INTC IRQ_IXP4XX_GPIO5 + #endif -- cgit v0.10.2 From e055d5bff318845f99c0fbf93245767fab8dce88 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Apr 2008 01:43:27 +0100 Subject: [ARM] 5015/1: arm: remove ARCH_CO285 Trying to compile a kerel for ARCH_CO285 fails with the following error: <-- snip --> ... CC arch/arm/mach-footbridge/dc21285.o /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c: In function 'dc21285_base_address': /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:54: error: 'PCICFG0_BASE' undeclared (first use in this function) /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:54: error: (Each undeclared identifier is reported only once /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:54: error: for each function it appears in.) /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:57: error: 'PCICFG1_BASE' undeclared (first use in this function) /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c: In function 'dc21285_scan_bus': /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:286: error: implicit declaration of function 'pci_scan_bus' ... make[2]: *** [arch/arm/mach-footbridge/dc21285.o] Error 1 <-- snip --> This does not seem to be a recent breakage. The ARCH_CO285 support is old - kernel 2.2.0 contains first traces of it, an it seems to have been pretty complete in later 2.2 kernels. Since it seems to be completely dead code now this patch therefore removes it. Signed-off-by: Adrian Bunk Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4039a13..ab78d5c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -232,14 +232,6 @@ config ARCH_CLPS711X help Support for Cirrus Logic 711x/721x based boards. -config ARCH_CO285 - bool "Co-EBSA285" - select FOOTBRIDGE - select FOOTBRIDGE_ADDIN - select HAVE_IDE - help - Support for Intel's EBSA285 companion chip. - config ARCH_EBSA110 bool "EBSA-110" select ISA @@ -784,7 +776,7 @@ source "mm/Kconfig" config LEDS bool "Timer and CPU usage LEDs" - depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \ + depends on ARCH_CDB89712 || ARCH_EBSA110 || \ ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \ ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1a46496..79b8ca3 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -100,8 +100,6 @@ textofs-y := 0x00008000 incdir-$(CONFIG_ARCH_CLPS7500) := cl7500 machine-$(CONFIG_FOOTBRIDGE) := footbridge incdir-$(CONFIG_FOOTBRIDGE) := ebsa285 - machine-$(CONFIG_ARCH_CO285) := footbridge - incdir-$(CONFIG_ARCH_CO285) := ebsa285 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SA1100) := sa1100 ifeq ($(CONFIG_ARCH_SA1100),y) diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index 0694ad6..32f8609 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -14,12 +14,10 @@ pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o -leds-$(CONFIG_ARCH_CO285) += ebsa285-leds.o leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o -obj-$(CONFIG_ARCH_CO285) += co285.o dc21285-timer.o obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c deleted file mode 100644 index 4545576..0000000 --- a/arch/arm/mach-footbridge/co285.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * linux/arch/arm/mach-footbridge/co285.c - * - * CO285 machine fixup - */ -#include - -#include -#include - -#include - -#include "common.h" - -static void __init -fixup_coebsa285(struct machine_desc *desc, struct tag *tags, - char **cmdline, struct meminfo *mi) -{ - extern unsigned long boot_memory_end; - extern char boot_command_line[]; - - mi->nr_banks = 1; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].size = boot_memory_end; - mi->bank[0].node = 0; - - *cmdline = boot_command_line; -} - -MACHINE_START(CO285, "co-EBSA285") - /* Maintainer: Mark van Doesburg */ - .phys_io = DC21285_ARMCSR_BASE, - .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, - .fixup = fixup_coebsa285, - .map_io = footbridge_map_io, - .init_irq = footbridge_init_irq, - .timer = &footbridge_timer, -MACHINE_END - diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index ef29fc3..b08ab50 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -177,25 +177,6 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = { #endif }; -/* - * The CO-ebsa285 mapping. - */ -static struct map_desc co285_io_desc[] __initdata = { -#ifdef CONFIG_ARCH_CO285 - { - .virtual = PCIO_BASE, - .pfn = __phys_to_pfn(DC21285_PCI_IO), - .length = PCIO_SIZE, - .type = MT_DEVICE, - }, { - .virtual = PCIMEM_BASE, - .pfn = __phys_to_pfn(DC21285_PCI_MEM), - .length = PCIMEM_SIZE, - .type = MT_DEVICE, - }, -#endif -}; - void __init footbridge_map_io(void) { /* @@ -208,8 +189,6 @@ void __init footbridge_map_io(void) * Now, work out what we've got to map in addition on this * platform. */ - if (machine_is_co285()) - iotable_init(co285_io_desc, ARRAY_SIZE(co285_io_desc)); if (footbridge_cfn_mode()) iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc)); } diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c index a64e222..09c1fbc 100644 --- a/arch/arm/mach-footbridge/ebsa285-leds.c +++ b/arch/arm/mach-footbridge/ebsa285-leds.c @@ -128,7 +128,7 @@ static void ebsa285_leds_event(led_event_t evt) static int __init leds_init(void) { - if (machine_is_ebsa285() || machine_is_co285()) + if (machine_is_ebsa285()) leds_event = ebsa285_leds_event; leds_event(led_start); diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c index 5d02e95..d5cfcda 100644 --- a/arch/arm/mach-footbridge/time.c +++ b/arch/arm/mach-footbridge/time.c @@ -115,8 +115,7 @@ static int set_isa_cmos_time(void) void __init isa_rtc_init(void) { - if (machine_is_co285() || - machine_is_personal_server()) + if (machine_is_personal_server()) /* * Add-in 21285s shouldn't access the RTC */ diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h index daad8ee..74610c2 100644 --- a/include/asm-arm/arch-ebsa285/hardware.h +++ b/include/asm-arm/arch-ebsa285/hardware.h @@ -14,7 +14,6 @@ #include -#ifdef CONFIG_ARCH_FOOTBRIDGE /* Virtual Physical Size * 0xff800000 0x40000000 1MB X-Bus * 0xff000000 0x7c000000 1MB PCI I/O space @@ -50,31 +49,6 @@ #define PCIMEM_SIZE 0x01000000 #define PCIMEM_BASE 0xf0000000 -#elif defined(CONFIG_ARCH_CO285) -/* - * This is the COEBSA285 cut-down mapping - */ -#define PCIMEM_SIZE 0x80000000 -#define PCIMEM_BASE 0x80000000 - -#define WFLUSH_SIZE 0x01000000 -#define WFLUSH_BASE 0x7d000000 - -#define ARMCSR_SIZE 0x00100000 -#define ARMCSR_BASE 0x7cf00000 - -#define XBUS_SIZE 0x00020000 -#define XBUS_BASE 0x7cee0000 - -#define PCIO_SIZE 0x00010000 -#define PCIO_BASE 0x7ced0000 - -#else - -#error "Undefined footbridge architecture" - -#endif - #define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) #define XBUS_LED_AMBER (1 << 0) #define XBUS_LED_GREEN (1 << 1) diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h index cbd7ae6..9019a3b 100644 --- a/include/asm-arm/arch-ebsa285/memory.h +++ b/include/asm-arm/arch-ebsa285/memory.h @@ -42,8 +42,6 @@ extern unsigned long __bus_to_virt(unsigned long); #endif -#if defined(CONFIG_ARCH_FOOTBRIDGE) - /* Task size and page offset at 3GB */ #define TASK_SIZE UL(0xbf000000) #define PAGE_OFFSET UL(0xc0000000) @@ -53,23 +51,6 @@ extern unsigned long __bus_to_virt(unsigned long); */ #define FLUSH_BASE 0xf9000000 -#elif defined(CONFIG_ARCH_CO285) - -/* Task size and page offset at 1.5GB */ -#define TASK_SIZE UL(0x5f000000) -#define PAGE_OFFSET UL(0x60000000) - -/* - * Cache flushing area. - */ -#define FLUSH_BASE 0x7e000000 - -#else - -#error "Undefined footbridge architecture" - -#endif - /* * Physical DRAM offset. */ diff --git a/include/asm-arm/arch-ebsa285/vmalloc.h b/include/asm-arm/arch-ebsa285/vmalloc.h index 0259820..e487d7e 100644 --- a/include/asm-arm/arch-ebsa285/vmalloc.h +++ b/include/asm-arm/arch-ebsa285/vmalloc.h @@ -7,8 +7,4 @@ */ -#ifdef CONFIG_ARCH_FOOTBRIDGE #define VMALLOC_END (PAGE_OFFSET + 0x30000000) -#else -#define VMALLOC_END (PAGE_OFFSET + 0x20000000) -#endif -- cgit v0.10.2 From 205bee6ad804d7034773b5978c74dde495df2301 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 13:57:26 +0100 Subject: [ARM] dyntick: Remove obsolete and unused ARM dyntick support dyntick is superseded by the clocksource/clockevent infrastructure, using the NO_HZ configuration option. No one implements dyntick on ARM anymore, so it's pointless keeping it around. Remove dyntick support. Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68..167824e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -703,27 +703,6 @@ config PREEMPT Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. -config NO_IDLE_HZ - bool "Dynamic tick timer" - depends on !GENERIC_CLOCKEVENTS - help - Select this option if you want to disable continuous timer ticks - and have them programmed to occur as required. This option saves - power as the system can remain in idle state for longer. - - By default dynamic tick is disabled during the boot, and can be - manually enabled with: - - echo 1 > /sys/devices/system/timer/timer0/dyn_tick - - Alternatively, if you want dynamic tick automatically enabled - during boot, pass "dyntick=enable" via the kernel command string. - - Please note that dynamic tick may affect the accuracy of - timekeeping on some platforms depending on the implementation. - Currently at least OMAP, PXA2xx and SA11x0 platforms are known - to have accurate timekeeping with dynamic tick. - config HZ int default 128 if ARCH_L7200 diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig index e32e736..b8e73e9 100644 --- a/arch/arm/configs/at91cap9adk_defconfig +++ b/arch/arm/configs/at91cap9adk_defconfig @@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index 2dbbbc3..868fb7b 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -169,7 +169,6 @@ CONFIG_AT91_CF=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index 6e994f7..de43fc6 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -160,7 +160,6 @@ CONFIG_ISA_DMA_API=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig index f659c93..2011adf 100644 --- a/arch/arm/configs/at91sam9260ek_defconfig +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -220,7 +220,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig index 3802e85..4049768 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig index 32a0d74..fa1c5ae 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263ek_defconfig @@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig index 98e6746..d8ec5f9 100644 --- a/arch/arm/configs/at91sam9rlek_defconfig +++ b/arch/arm/configs/at91sam9rlek_defconfig @@ -211,7 +211,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig index d846a49..85c80f7 100644 --- a/arch/arm/configs/ateb9200_defconfig +++ b/arch/arm/configs/ateb9200_defconfig @@ -171,7 +171,6 @@ CONFIG_AT91_CF=m # Kernel Features # CONFIG_PREEMPT=y -CONFIG_NO_IDLE_HZ=y CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig index 5cab083..33b201c 100644 --- a/arch/arm/configs/cm_x270_defconfig +++ b/arch/arm/configs/cm_x270_defconfig @@ -194,7 +194,6 @@ CONFIG_PCI_HOST_ITE8152=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index 4264e27..f7622e6 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig @@ -166,7 +166,6 @@ CONFIG_PCMCIA_SA1100=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index e8980a9..9b8748a 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -165,7 +165,6 @@ CONFIG_PCMCIA_PXA2XX=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig index 90ed214..cfeb817 100644 --- a/arch/arm/configs/ecbat91_defconfig +++ b/arch/arm/configs/ecbat91_defconfig @@ -230,7 +230,6 @@ CONFIG_AT91_CF=y # # CONFIG_TICK_ONESHOT is not set CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index 6bea090..d3114c2 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig @@ -197,7 +197,6 @@ CONFIG_XSCALE_PMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 24a701a..21aa013 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -184,7 +184,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig index ed487b9..493ecee 100644 --- a/arch/arm/configs/eseries_pxa_defconfig +++ b/arch/arm/configs/eseries_pxa_defconfig @@ -251,7 +251,6 @@ CONFIG_PCMCIA_PXA2XX=m # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig index 988b4d1..482e570 100644 --- a/arch/arm/configs/iop13xx_defconfig +++ b/arch/arm/configs/iop13xx_defconfig @@ -197,7 +197,6 @@ CONFIG_PCI_LEGACY=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig index 83f40d4..8612f58 100644 --- a/arch/arm/configs/iop32x_defconfig +++ b/arch/arm/configs/iop32x_defconfig @@ -201,7 +201,6 @@ CONFIG_PCI_LEGACY=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig index 917afb5..8b0098d 100644 --- a/arch/arm/configs/iop33x_defconfig +++ b/arch/arm/configs/iop33x_defconfig @@ -197,7 +197,6 @@ CONFIG_PCI_LEGACY=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig index f8f9793..84680db 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixp2000_defconfig @@ -184,7 +184,6 @@ CONFIG_PCI=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig index 27cf022..4a2f7b2 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/ixp23xx_defconfig @@ -180,7 +180,6 @@ CONFIG_PCI=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig index ae51a40..6dd95a2 100644 --- a/arch/arm/configs/kafa_defconfig +++ b/arch/arm/configs/kafa_defconfig @@ -162,7 +162,6 @@ CONFIG_CPU_TLB_V4WBI=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig index c16537d..8e74c66 100644 --- a/arch/arm/configs/kb9202_defconfig +++ b/arch/arm/configs/kb9202_defconfig @@ -126,7 +126,6 @@ CONFIG_ISA_DMA_API=y # # Kernel Features # -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig index 8ab21a0..6077f2c 100644 --- a/arch/arm/configs/ks8695_defconfig +++ b/arch/arm/configs/ks8695_defconfig @@ -174,7 +174,6 @@ CONFIG_PCCARD_NONSTATIC=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index a3bf583..1a38d8e 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -173,7 +173,6 @@ CONFIG_XSCALE_PMU=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig index 46a0f7f..7a2e932 100644 --- a/arch/arm/configs/lpd7a404_defconfig +++ b/arch/arm/configs/lpd7a404_defconfig @@ -148,7 +148,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set # CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig index 57f32f3..0884f23 100644 --- a/arch/arm/configs/netx_defconfig +++ b/arch/arm/configs/netx_defconfig @@ -154,7 +154,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig index 650a248..418ca2f 100644 --- a/arch/arm/configs/onearm_defconfig +++ b/arch/arm/configs/onearm_defconfig @@ -202,7 +202,6 @@ CONFIG_AT91_CF=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig index 95a22f5..14826f0 100644 --- a/arch/arm/configs/picotux200_defconfig +++ b/arch/arm/configs/picotux200_defconfig @@ -201,7 +201,6 @@ CONFIG_ARM_THUMB=y # Kernel Features # # CONFIG_PREEMPT is not set -CONFIG_NO_IDLE_HZ=y CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig index b5e11aa..811b8f6 100644 --- a/arch/arm/configs/pnx4008_defconfig +++ b/arch/arm/configs/pnx4008_defconfig @@ -151,7 +151,6 @@ CONFIG_ARM_THUMB=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig index fc39ba1..0c09b23 100644 --- a/arch/arm/configs/realview-smp_defconfig +++ b/arch/arm/configs/realview-smp_defconfig @@ -177,7 +177,6 @@ CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y CONFIG_LOCAL_TIMERS=y # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index accbf52..907e543 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -126,7 +126,6 @@ CONFIG_ISA_DMA_API=y # # Kernel Features # -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index 5ddecb9..f62d181 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig @@ -190,7 +190,6 @@ CONFIG_ISA_DMA_API=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index f8a1645..6d03763 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -246,7 +246,6 @@ CONFIG_ISA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=200 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig index 484dc97..8688362 100644 --- a/arch/arm/configs/sam9_l9260_defconfig +++ b/arch/arm/configs/sam9_l9260_defconfig @@ -211,7 +211,6 @@ CONFIG_ARM_THUMB=y # # CONFIG_TICK_ONESHOT is not set CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index aa7a011..7d59fb1 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -164,7 +164,6 @@ CONFIG_PCMCIA_PXA2XX=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig index 576b833..07dfb98 100644 --- a/arch/arm/configs/tct_hammer_defconfig +++ b/arch/arm/configs/tct_hammer_defconfig @@ -247,7 +247,6 @@ CONFIG_ARM_THUMB=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=200 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 6db6392..8b7a431 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -195,7 +195,6 @@ CONFIG_PCMCIA_PXA2XX=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 48dca69..8355f88 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -151,7 +151,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 46bf2ede..199b368 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -133,10 +133,8 @@ static void default_idle(void) cpu_relax(); else { local_irq_disable(); - if (!need_resched()) { - timer_dyn_reprogram(); + if (!need_resched()) arch_idle(); - } local_irq_enable(); } } diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index b5867ec..cc5145b 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -365,108 +365,6 @@ static struct sysdev_class timer_sysclass = { .resume = timer_resume, }; -#ifdef CONFIG_NO_IDLE_HZ -static int timer_dyn_tick_enable(void) -{ - struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long flags; - int ret = -ENODEV; - - if (dyn_tick) { - spin_lock_irqsave(&dyn_tick->lock, flags); - ret = 0; - if (!(dyn_tick->state & DYN_TICK_ENABLED)) { - ret = dyn_tick->enable(); - - if (ret == 0) - dyn_tick->state |= DYN_TICK_ENABLED; - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); - } - - return ret; -} - -static int timer_dyn_tick_disable(void) -{ - struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long flags; - int ret = -ENODEV; - - if (dyn_tick) { - spin_lock_irqsave(&dyn_tick->lock, flags); - ret = 0; - if (dyn_tick->state & DYN_TICK_ENABLED) { - ret = dyn_tick->disable(); - - if (ret == 0) - dyn_tick->state &= ~DYN_TICK_ENABLED; - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); - } - - return ret; -} - -/* - * Reprogram the system timer for at least the calculated time interval. - * This function should be called from the idle thread with IRQs disabled, - * immediately before sleeping. - */ -void timer_dyn_reprogram(void) -{ - struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long next, seq, flags; - - if (!dyn_tick) - return; - - spin_lock_irqsave(&dyn_tick->lock, flags); - if (dyn_tick->state & DYN_TICK_ENABLED) { - next = next_timer_interrupt(); - do { - seq = read_seqbegin(&xtime_lock); - dyn_tick->reprogram(next - jiffies); - } while (read_seqretry(&xtime_lock, seq)); - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); -} - -static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) -{ - return sprintf(buf, "%i\n", - (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); -} - -static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, - size_t count) -{ - unsigned int enable = simple_strtoul(buf, NULL, 2); - - if (enable) - timer_dyn_tick_enable(); - else - timer_dyn_tick_disable(); - - return count; -} -static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); - -/* - * dyntick=enable|disable - */ -static char dyntick_str[4] __initdata = ""; - -static int __init dyntick_setup(char *str) -{ - if (str) - strlcpy(dyntick_str, str, sizeof(dyntick_str)); - return 1; -} - -__setup("dyntick=", dyntick_setup); -#endif - static int __init timer_init_sysfs(void) { int ret = sysdev_class_register(&timer_sysclass); @@ -475,19 +373,6 @@ static int __init timer_init_sysfs(void) ret = sysdev_register(&system_timer->dev); } -#ifdef CONFIG_NO_IDLE_HZ - if (ret == 0 && system_timer->dyn_tick) { - ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick); - - /* - * Turn on dynamic tick after calibrate delay - * for correct bogomips - */ - if (ret == 0 && dyntick_str[0] == 'e') - ret = timer_dyn_tick_enable(); - } -#endif - return ret; } @@ -500,10 +385,5 @@ void __init time_init(void) system_timer->offset = dummy_gettimeoffset; #endif system_timer->init(); - -#ifdef CONFIG_NO_IDLE_HZ - if (system_timer->dyn_tick) - spin_lock_init(&system_timer->dyn_tick->lock); -#endif } diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index e6c64e1..742f79e 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -116,13 +116,6 @@ void omap_pm_idle(void) return; } - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - #ifdef CONFIG_OMAP_MPU_TIMER #warning Enable 32kHz OS timer in order to allow sleep states in idle use_idlect1 = use_idlect1 & ~(1 << 9); diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index aad781d..d6c9de8 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -57,13 +57,6 @@ void omap2_pm_idle(void) return; } - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - omap2_sram_idle(); local_fiq_enable(); local_irq_enable(); diff --git a/include/asm-arm/dyntick.h b/include/asm-arm/dyntick.h deleted file mode 100644 index 19fab2d..0000000 --- a/include/asm-arm/dyntick.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASMARM_DYNTICK_H -#define _ASMARM_DYNTICK_H - -#include - -#endif /* _ASMARM_DYNTICK_H */ diff --git a/include/asm-arm/hw_irq.h b/include/asm-arm/hw_irq.h index 98d594a..f1a08a5 100644 --- a/include/asm-arm/hw_irq.h +++ b/include/asm-arm/hw_irq.h @@ -6,15 +6,4 @@ #include -#if defined(CONFIG_NO_IDLE_HZ) -# include -# define handle_dynamic_tick(action) \ - if (!(action->flags & IRQF_TIMER) && system_timer->dyn_tick) { \ - write_seqlock(&xtime_lock); \ - if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) \ - system_timer->dyn_tick->handler(irq, NULL); \ - write_sequnlock(&xtime_lock); \ - } -#endif - #endif diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h index 5dc3570..2fd36ea 100644 --- a/include/asm-arm/mach/time.h +++ b/include/asm-arm/mach/time.h @@ -41,30 +41,8 @@ struct sys_timer { #ifndef CONFIG_GENERIC_TIME unsigned long (*offset)(void); #endif - -#ifdef CONFIG_NO_IDLE_HZ - struct dyn_tick_timer *dyn_tick; -#endif -}; - -#ifdef CONFIG_NO_IDLE_HZ - -#define DYN_TICK_ENABLED (1 << 1) - -struct dyn_tick_timer { - spinlock_t lock; - unsigned int state; /* Current state */ - int (*enable)(void); /* Enables dynamic tick */ - int (*disable)(void); /* Disables dynamic tick */ - void (*reprogram)(unsigned long); /* Reprograms the timer */ - int (*handler)(int, void *); }; -void timer_dyn_reprogram(void); -#else -#define timer_dyn_reprogram() do { } while (0) -#endif - extern struct sys_timer *system_timer; extern void timer_tick(void); -- cgit v0.10.2 From ee9c578527a93c66becb526c4a122c5358a959c5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 13:59:33 +0100 Subject: dyntick: Remove last reminants of dyntick support Remove the last reminants of dyntick support from the generic kernel. Signed-off-by: Russell King diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 421be5f..543d9ca 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1078,7 +1078,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) } EXPORT_SYMBOL_GPL(hrtimer_get_remaining); -#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ) +#ifdef CONFIG_NO_HZ /** * hrtimer_get_next_event - get the time until next expiry event * diff --git a/kernel/sysctl.c b/kernel/sysctl.c index d7ffdc5..76426d9 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -131,8 +131,6 @@ extern int sysctl_userprocess_debug; extern int spin_retry; #endif -extern int sysctl_hz_timer; - #ifdef CONFIG_BSD_PROCESS_ACCT extern int acct_parm[]; #endif @@ -562,16 +560,6 @@ static struct ctl_table kern_table[] = { .proc_handler = &proc_dointvec, }, #endif -#ifdef CONFIG_NO_IDLE_HZ - { - .ctl_name = KERN_HZ_TIMER, - .procname = "hz_timer", - .data = &sysctl_hz_timer, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, -#endif { .ctl_name = KERN_S390_USER_DEBUG_LOGGING, .procname = "userprocess_debug", diff --git a/kernel/timer.c b/kernel/timer.c index ceacc66..ef3fa69 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -812,7 +812,7 @@ static inline void __run_timers(struct tvec_base *base) spin_unlock_irq(&base->lock); } -#if defined(CONFIG_NO_IDLE_HZ) || defined(CONFIG_NO_HZ) +#ifdef CONFIG_NO_HZ /* * Find out when the next timer event is due to happen. This * is used on S/390 to stop all activity when a cpus is idle. @@ -947,14 +947,6 @@ unsigned long get_next_timer_interrupt(unsigned long now) return cmp_next_hrtimer_event(now, expires); } - -#ifdef CONFIG_NO_IDLE_HZ -unsigned long next_timer_interrupt(void) -{ - return get_next_timer_interrupt(jiffies); -} -#endif - #endif #ifndef CONFIG_VIRT_CPU_ACCOUNTING -- cgit v0.10.2 From 150c9173031d43746d70582a17931350f3da8932 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 12 May 2008 17:37:21 +0100 Subject: dyntick: remove deferences from SH SH does not have a configuration option for NO_IDLE_HZ their Kconfig files, yet their defconfig files lists them. Remove those references. Signed-off-by: Russell King diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index f52db12..38f934a 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -226,7 +226,6 @@ CONFIG_CPU_HAS_PTEA=y # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index 9fa66d9..b68b6cd 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig @@ -231,7 +231,6 @@ CONFIG_CPU_HAS_PTEA=y # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=40000000 # diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 84717d8..490dcbc 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -239,7 +239,6 @@ CONFIG_CPU_HAS_SR_RB=y # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig index 240a1ce..2dd83af 100644 --- a/arch/sh/configs/se7712_defconfig +++ b/arch/sh/configs/se7712_defconfig @@ -236,7 +236,6 @@ CONFIG_CPU_HAS_SR_RB=y # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=66666666 # diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index c60b6fd..167786f 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -235,7 +235,6 @@ CONFIG_CPU_HAS_PTEA=y # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # -- cgit v0.10.2 From 88f85a55c0645c2b7e03bf34d2a90eddf6de34fa Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 12 May 2008 16:42:43 -0500 Subject: JFS: 0 is not valid errno value so return NULL from jfs_lookup Signed-off-by: Marcin Slusarz Signed-off-by: Dave Kleikamp Cc: jfs-discussion@lists.sourceforge.net Cc: Alexander Viro diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 0ba6778..2aba823 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1455,7 +1455,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc free_UCSname(&key); if (rc == -ENOENT) { d_add(dentry, NULL); - return ERR_PTR(0); + return NULL; } else if (rc) { jfs_err("jfs_lookup: dtSearch returned %d", rc); return ERR_PTR(rc); -- cgit v0.10.2 From b2e03ca7485cac033a0667d9e45e28d32fdee9a5 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 13 May 2008 08:22:10 -0500 Subject: JFS: switch to seq_files Signed-off-by: Alexey Dobriyan Signed-off-by: Dave Kleikamp diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index bf6ab19..6a73de8 100644 --- a/fs/jfs/jfs_debug.c +++ b/fs/jfs/jfs_debug.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "jfs_incore.h" #include "jfs_filsys.h" @@ -30,29 +31,19 @@ static struct proc_dir_entry *base; #ifdef CONFIG_JFS_DEBUG -static int loglevel_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int jfs_loglevel_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", jfsloglevel); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; + seq_printf(m, "%d\n", jfsloglevel); + return 0; +} - return len; +static int jfs_loglevel_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, jfs_loglevel_proc_show, NULL); } -static int loglevel_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t jfs_loglevel_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; @@ -65,22 +56,30 @@ static int loglevel_write(struct file *file, const char __user *buffer, jfsloglevel = c - '0'; return count; } + +static const struct file_operations jfs_loglevel_proc_fops = { + .owner = THIS_MODULE, + .open = jfs_loglevel_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = jfs_loglevel_proc_write, +}; #endif static struct { const char *name; - read_proc_t *read_fn; - write_proc_t *write_fn; + const struct file_operations *proc_fops; } Entries[] = { #ifdef CONFIG_JFS_STATISTICS - { "lmstats", jfs_lmstats_read, }, - { "txstats", jfs_txstats_read, }, - { "xtstat", jfs_xtstat_read, }, - { "mpstat", jfs_mpstat_read, }, + { "lmstats", &jfs_lmstats_proc_fops, }, + { "txstats", &jfs_txstats_proc_fops, }, + { "xtstat", &jfs_xtstat_proc_fops, }, + { "mpstat", &jfs_mpstat_proc_fops, }, #endif #ifdef CONFIG_JFS_DEBUG - { "TxAnchor", jfs_txanchor_read, }, - { "loglevel", loglevel_read, loglevel_write } + { "TxAnchor", &jfs_txanchor_proc_fops, }, + { "loglevel", &jfs_loglevel_proc_fops } #endif }; #define NPROCENT ARRAY_SIZE(Entries) @@ -93,13 +92,8 @@ void jfs_proc_init(void) return; base->owner = THIS_MODULE; - for (i = 0; i < NPROCENT; i++) { - struct proc_dir_entry *p; - if ((p = create_proc_entry(Entries[i].name, 0, base))) { - p->read_proc = Entries[i].read_fn; - p->write_proc = Entries[i].write_fn; - } - } + for (i = 0; i < NPROCENT; i++) + proc_create(Entries[i].name, 0, base, Entries[i].proc_fops); } void jfs_proc_clean(void) diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h index 044c1e6..eafd130 100644 --- a/fs/jfs/jfs_debug.h +++ b/fs/jfs/jfs_debug.h @@ -62,7 +62,7 @@ extern void jfs_proc_clean(void); extern int jfsloglevel; -extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *); +extern const struct file_operations jfs_txanchor_proc_fops; /* information message: e.g., configuration, major event */ #define jfs_info(fmt, arg...) do { \ @@ -105,10 +105,10 @@ extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *); * ---------- */ #ifdef CONFIG_JFS_STATISTICS -extern int jfs_lmstats_read(char *, char **, off_t, int, int *, void *); -extern int jfs_txstats_read(char *, char **, off_t, int, int *, void *); -extern int jfs_mpstat_read(char *, char **, off_t, int, int *, void *); -extern int jfs_xtstat_read(char *, char **, off_t, int, int *, void *); +extern const struct file_operations jfs_lmstats_proc_fops; +extern const struct file_operations jfs_txstats_proc_fops; +extern const struct file_operations jfs_mpstat_proc_fops; +extern const struct file_operations jfs_xtstat_proc_fops; #define INCREMENT(x) ((x)++) #define DECREMENT(x) ((x)--) diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 325a967..cd2ec29 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -69,6 +69,7 @@ #include #include #include +#include #include "jfs_incore.h" #include "jfs_filsys.h" #include "jfs_metapage.h" @@ -2503,13 +2504,9 @@ exit: } #ifdef CONFIG_JFS_STATISTICS -int jfs_lmstats_read(char *buffer, char **start, off_t offset, int length, - int *eof, void *data) +static int jfs_lmstats_proc_show(struct seq_file *m, void *v) { - int len = 0; - off_t begin; - - len += sprintf(buffer, + seq_printf(m, "JFS Logmgr stats\n" "================\n" "commits = %d\n" @@ -2522,19 +2519,19 @@ int jfs_lmstats_read(char *buffer, char **start, off_t offset, int length, lmStat.pagedone, lmStat.full_page, lmStat.partial_page); + return 0; +} - begin = offset; - *start = buffer + begin; - len -= begin; - - if (len > length) - len = length; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; +static int jfs_lmstats_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, jfs_lmstats_proc_show, NULL); } + +const struct file_operations jfs_lmstats_proc_fops = { + .owner = THIS_MODULE, + .open = jfs_lmstats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* CONFIG_JFS_STATISTICS */ diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index d1e64f2..854ff0e 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -19,10 +19,12 @@ #include #include +#include #include #include #include #include +#include #include "jfs_incore.h" #include "jfs_superblock.h" #include "jfs_filsys.h" @@ -804,13 +806,9 @@ void __invalidate_metapages(struct inode *ip, s64 addr, int len) } #ifdef CONFIG_JFS_STATISTICS -int jfs_mpstat_read(char *buffer, char **start, off_t offset, int length, - int *eof, void *data) +static int jfs_mpstat_proc_show(struct seq_file *m, void *v) { - int len = 0; - off_t begin; - - len += sprintf(buffer, + seq_printf(m, "JFS Metapage statistics\n" "=======================\n" "page allocations = %d\n" @@ -819,19 +817,19 @@ int jfs_mpstat_read(char *buffer, char **start, off_t offset, int length, mpStat.pagealloc, mpStat.pagefree, mpStat.lockwait); + return 0; +} - begin = offset; - *start = buffer + begin; - len -= begin; - - if (len > length) - len = length; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; +static int jfs_mpstat_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, jfs_mpstat_proc_show, NULL); } + +const struct file_operations jfs_mpstat_proc_fops = { + .owner = THIS_MODULE, + .open = jfs_mpstat_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index e7c60ae..f26e4d0 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "jfs_incore.h" #include "jfs_inode.h" #include "jfs_filsys.h" @@ -3009,11 +3010,8 @@ int jfs_sync(void *arg) } #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG) -int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length, - int *eof, void *data) +static int jfs_txanchor_proc_show(struct seq_file *m, void *v) { - int len = 0; - off_t begin; char *freewait; char *freelockwait; char *lowlockwait; @@ -3025,7 +3023,7 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length, lowlockwait = waitqueue_active(&TxAnchor.lowlockwait) ? "active" : "empty"; - len += sprintf(buffer, + seq_printf(m, "JFS TxAnchor\n" "============\n" "freetid = %d\n" @@ -3044,31 +3042,27 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length, TxAnchor.tlocksInUse, jfs_tlocks_low, list_empty(&TxAnchor.unlock_queue) ? "" : "not "); + return 0; +} - begin = offset; - *start = buffer + begin; - len -= begin; - - if (len > length) - len = length; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; +static int jfs_txanchor_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, jfs_txanchor_proc_show, NULL); } + +const struct file_operations jfs_txanchor_proc_fops = { + .owner = THIS_MODULE, + .open = jfs_txanchor_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_STATISTICS) -int jfs_txstats_read(char *buffer, char **start, off_t offset, int length, - int *eof, void *data) +static int jfs_txstats_proc_show(struct seq_file *m, void *v) { - int len = 0; - off_t begin; - - len += sprintf(buffer, + seq_printf(m, "JFS TxStats\n" "===========\n" "calls to txBegin = %d\n" @@ -3089,19 +3083,19 @@ int jfs_txstats_read(char *buffer, char **start, off_t offset, int length, TxStat.txBeginAnon_lockslow, TxStat.txLockAlloc, TxStat.txLockAlloc_freelock); + return 0; +} - begin = offset; - *start = buffer + begin; - len -= begin; - - if (len > length) - len = length; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; +static int jfs_txstats_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, jfs_txstats_proc_show, NULL); } + +const struct file_operations jfs_txstats_proc_fops = { + .owner = THIS_MODULE, + .open = jfs_txstats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index 5a61ebf..ae3acaf 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -20,7 +20,9 @@ */ #include +#include #include +#include #include "jfs_incore.h" #include "jfs_filsys.h" #include "jfs_metapage.h" @@ -4134,13 +4136,9 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) } #ifdef CONFIG_JFS_STATISTICS -int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length, - int *eof, void *data) +static int jfs_xtstat_proc_show(struct seq_file *m, void *v) { - int len = 0; - off_t begin; - - len += sprintf(buffer, + seq_printf(m, "JFS Xtree statistics\n" "====================\n" "searches = %d\n" @@ -4149,19 +4147,19 @@ int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length, xtStat.search, xtStat.fastSearch, xtStat.split); + return 0; +} - begin = offset; - *start = buffer + begin; - len -= begin; - - if (len > length) - len = length; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; +static int jfs_xtstat_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, jfs_xtstat_proc_show, NULL); } + +const struct file_operations jfs_xtstat_proc_fops = { + .owner = THIS_MODULE, + .open = jfs_xtstat_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif -- cgit v0.10.2 From 54ef0ec22a39071a4e7fbedd201cecac9ac6e8a7 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Fri, 2 May 2008 14:40:38 -0500 Subject: [POWERPC] Delete unused fec_8xx net driver This driver has been superseded by fs_enet and is no longer in use. Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d27f54a..009e8fd 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1884,7 +1884,6 @@ config NE_H8300 Say Y here if you want to use the NE2000 compatible controller on the Renesas H8/300 processor. -source "drivers/net/fec_8xx/Kconfig" source "drivers/net/fs_enet/Kconfig" endif # NET_ETHERNET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dcbfe84..9010e58 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -217,7 +217,6 @@ obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_SMC911X) += smc911x.o obj-$(CONFIG_BFIN_MAC) += bfin_mac.o obj-$(CONFIG_DM9000) += dm9000.o -obj-$(CONFIG_FEC_8XX) += fec_8xx/ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o obj-$(CONFIG_MLX4_CORE) += mlx4/ diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig deleted file mode 100644 index afb34de..0000000 --- a/drivers/net/fec_8xx/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -config FEC_8XX - tristate "Motorola 8xx FEC driver" - depends on 8XX - select MII - -config FEC_8XX_GENERIC_PHY - bool "Support any generic PHY" - depends on FEC_8XX - default y - -config FEC_8XX_DM9161_PHY - bool "Support DM9161 PHY" - depends on FEC_8XX - default n - -config FEC_8XX_LXT971_PHY - bool "Support LXT971/LXT972 PHY" - depends on FEC_8XX - default n - diff --git a/drivers/net/fec_8xx/Makefile b/drivers/net/fec_8xx/Makefile deleted file mode 100644 index 70c54f8..0000000 --- a/drivers/net/fec_8xx/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the Motorola 8xx FEC ethernet controller -# - -obj-$(CONFIG_FEC_8XX) += fec_8xx.o - -fec_8xx-objs := fec_main.o fec_mii.o - -# the platform instantatiation objects -ifeq ($(CONFIG_NETTA),y) -fec_8xx-objs += fec_8xx-netta.o -endif diff --git a/drivers/net/fec_8xx/fec_8xx-netta.c b/drivers/net/fec_8xx/fec_8xx-netta.c deleted file mode 100644 index 79deee2..0000000 --- a/drivers/net/fec_8xx/fec_8xx-netta.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * FEC instantatiation file for NETTA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "fec_8xx.h" - -/*************************************************/ - -static struct fec_platform_info fec1_info = { - .fec_no = 0, - .use_mdio = 1, - .phy_addr = 8, - .fec_irq = SIU_LEVEL1, - .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC6, - .rx_ring = 128, - .tx_ring = 16, - .rx_copybreak = 240, - .use_napi = 1, - .napi_weight = 17, -}; - -static struct fec_platform_info fec2_info = { - .fec_no = 1, - .use_mdio = 1, - .phy_addr = 2, - .fec_irq = SIU_LEVEL3, - .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC7, - .rx_ring = 128, - .tx_ring = 16, - .rx_copybreak = 240, - .use_napi = 1, - .napi_weight = 17, -}; - -static struct net_device *fec1_dev; -static struct net_device *fec2_dev; - -/* XXX custom u-boot & Linux startup needed */ -extern const char *__fw_getenv(const char *var); - -/* access ports */ -#define setbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) | (_v)) -#define clrbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) & ~(_v)) - -#define setbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) | (_v)) -#define clrbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) & ~(_v)) - -int fec_8xx_platform_init(void) -{ - immap_t *immap = (immap_t *)IMAP_ADDR; - bd_t *bd = (bd_t *) __res; - const char *s; - char *e; - int i; - - /* use MDC for MII */ - setbits16(immap->im_ioport.iop_pdpar, 0x0080); - clrbits16(immap->im_ioport.iop_pddir, 0x0080); - - /* configure FEC1 pins */ - setbits16(immap->im_ioport.iop_papar, 0xe810); - setbits16(immap->im_ioport.iop_padir, 0x0810); - clrbits16(immap->im_ioport.iop_padir, 0xe000); - - setbits32(immap->im_cpm.cp_pbpar, 0x00000001); - clrbits32(immap->im_cpm.cp_pbdir, 0x00000001); - - setbits32(immap->im_cpm.cp_cptr, 0x00000100); - clrbits32(immap->im_cpm.cp_cptr, 0x00000050); - - clrbits16(immap->im_ioport.iop_pcpar, 0x0200); - clrbits16(immap->im_ioport.iop_pcdir, 0x0200); - clrbits16(immap->im_ioport.iop_pcso, 0x0200); - setbits16(immap->im_ioport.iop_pcint, 0x0200); - - /* configure FEC2 pins */ - setbits32(immap->im_cpm.cp_pepar, 0x00039620); - setbits32(immap->im_cpm.cp_pedir, 0x00039620); - setbits32(immap->im_cpm.cp_peso, 0x00031000); - clrbits32(immap->im_cpm.cp_peso, 0x00008620); - - setbits32(immap->im_cpm.cp_cptr, 0x00000080); - clrbits32(immap->im_cpm.cp_cptr, 0x00000028); - - clrbits16(immap->im_ioport.iop_pcpar, 0x0200); - clrbits16(immap->im_ioport.iop_pcdir, 0x0200); - clrbits16(immap->im_ioport.iop_pcso, 0x0200); - setbits16(immap->im_ioport.iop_pcint, 0x0200); - - /* fill up */ - fec1_info.sys_clk = bd->bi_intfreq; - fec2_info.sys_clk = bd->bi_intfreq; - - s = __fw_getenv("ethaddr"); - if (s != NULL) { - for (i = 0; i < 6; i++) { - fec1_info.macaddr[i] = simple_strtoul(s, &e, 16); - if (*e) - s = e + 1; - } - } - - s = __fw_getenv("eth1addr"); - if (s != NULL) { - for (i = 0; i < 6; i++) { - fec2_info.macaddr[i] = simple_strtoul(s, &e, 16); - if (*e) - s = e + 1; - } - } - - fec_8xx_init_one(&fec1_info, &fec1_dev); - fec_8xx_init_one(&fec2_info, &fec2_dev); - - return fec1_dev != NULL && fec2_dev != NULL ? 0 : -1; -} - -void fec_8xx_platform_cleanup(void) -{ - if (fec2_dev != NULL) - fec_8xx_cleanup_one(fec2_dev); - - if (fec1_dev != NULL) - fec_8xx_cleanup_one(fec1_dev); -} diff --git a/drivers/net/fec_8xx/fec_8xx.h b/drivers/net/fec_8xx/fec_8xx.h deleted file mode 100644 index f3b1c6f..0000000 --- a/drivers/net/fec_8xx/fec_8xx.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef FEC_8XX_H -#define FEC_8XX_H - -#include -#include - -#include - -/* HW info */ - -/* CRC polynomium used by the FEC for the multicast group filtering */ -#define FEC_CRC_POLY 0x04C11DB7 - -#define MII_ADVERTISE_HALF (ADVERTISE_100HALF | \ - ADVERTISE_10HALF | ADVERTISE_CSMA) -#define MII_ADVERTISE_ALL (ADVERTISE_100FULL | \ - ADVERTISE_10FULL | MII_ADVERTISE_HALF) - -/* Interrupt events/masks. -*/ -#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ -#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ -#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ -#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ -#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ -#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ -#define FEC_ENET_RXF 0x02000000U /* Full frame received */ -#define FEC_ENET_RXB 0x01000000U /* A buffer was received */ -#define FEC_ENET_MII 0x00800000U /* MII interrupt */ -#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ - -#define FEC_ECNTRL_PINMUX 0x00000004 -#define FEC_ECNTRL_ETHER_EN 0x00000002 -#define FEC_ECNTRL_RESET 0x00000001 - -#define FEC_RCNTRL_BC_REJ 0x00000010 -#define FEC_RCNTRL_PROM 0x00000008 -#define FEC_RCNTRL_MII_MODE 0x00000004 -#define FEC_RCNTRL_DRT 0x00000002 -#define FEC_RCNTRL_LOOP 0x00000001 - -#define FEC_TCNTRL_FDEN 0x00000004 -#define FEC_TCNTRL_HBC 0x00000002 -#define FEC_TCNTRL_GTS 0x00000001 - -/* values for MII phy_status */ - -#define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ -#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ -#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ -#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ -#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ -#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ -#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ - -#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ -#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ -#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ -#define PHY_STAT_SPMASK 0xf000 /* mask for speed */ -#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ -#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ -#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ -#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ - -typedef struct phy_info { - unsigned int id; - const char *name; - void (*startup) (struct net_device * dev); - void (*shutdown) (struct net_device * dev); - void (*ack_int) (struct net_device * dev); -} phy_info_t; - -/* The FEC stores dest/src/type, data, and checksum for receive packets. - */ -#define MAX_MTU 1508 /* Allow fullsized pppoe packets over VLAN */ -#define MIN_MTU 46 /* this is data size */ -#define CRC_LEN 4 - -#define PKT_MAXBUF_SIZE (MAX_MTU+ETH_HLEN+CRC_LEN) -#define PKT_MINBUF_SIZE (MIN_MTU+ETH_HLEN+CRC_LEN) - -/* Must be a multiple of 4 */ -#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE+3) & ~3) -/* This is needed so that invalidate_xxx wont invalidate too much */ -#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE) - -/* platform interface */ - -struct fec_platform_info { - int fec_no; /* FEC index */ - int use_mdio; /* use external MII */ - int phy_addr; /* the phy address */ - int fec_irq, phy_irq; /* the irq for the controller */ - int rx_ring, tx_ring; /* number of buffers on rx */ - int sys_clk; /* system clock */ - __u8 macaddr[6]; /* mac address */ - int rx_copybreak; /* limit we copy small frames */ - int use_napi; /* use NAPI */ - int napi_weight; /* NAPI weight */ -}; - -/* forward declaration */ -struct fec; - -struct fec_enet_private { - spinlock_t lock; /* during all ops except TX pckt processing */ - spinlock_t tx_lock; /* during fec_start_xmit and fec_tx */ - struct net_device *dev; - struct napi_struct napi; - int fecno; - struct fec *fecp; - const struct fec_platform_info *fpi; - int rx_ring, tx_ring; - dma_addr_t ring_mem_addr; - void *ring_base; - struct sk_buff **rx_skbuff; - struct sk_buff **tx_skbuff; - cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ - cbd_t *tx_bd_base; - cbd_t *dirty_tx; /* ring entries to be free()ed. */ - cbd_t *cur_rx; - cbd_t *cur_tx; - int tx_free; - struct net_device_stats stats; - struct timer_list phy_timer_list; - const struct phy_info *phy; - unsigned int fec_phy_speed; - __u32 msg_enable; - struct mii_if_info mii_if; -}; - -/***************************************************************************/ - -void fec_restart(struct net_device *dev, int duplex, int speed); -void fec_stop(struct net_device *dev); - -/***************************************************************************/ - -int fec_mii_read(struct net_device *dev, int phy_id, int location); -void fec_mii_write(struct net_device *dev, int phy_id, int location, int value); - -int fec_mii_phy_id_detect(struct net_device *dev); -void fec_mii_startup(struct net_device *dev); -void fec_mii_shutdown(struct net_device *dev); -void fec_mii_ack_int(struct net_device *dev); - -void fec_mii_link_status_change_check(struct net_device *dev, int init_media); - -/***************************************************************************/ - -#define FEC1_NO 0x00 -#define FEC2_NO 0x01 -#define FEC3_NO 0x02 - -int fec_8xx_init_one(const struct fec_platform_info *fpi, - struct net_device **devp); -int fec_8xx_cleanup_one(struct net_device *dev); - -/***************************************************************************/ - -#define DRV_MODULE_NAME "fec_8xx" -#define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.1" -#define DRV_MODULE_RELDATE "May 6, 2004" - -/***************************************************************************/ - -int fec_8xx_platform_init(void); -void fec_8xx_platform_cleanup(void); - -/***************************************************************************/ - -/* FEC access macros */ -#if defined(CONFIG_8xx) -/* for a 8xx __raw_xxx's are sufficient */ -#define __fec_out32(addr, x) __raw_writel(x, addr) -#define __fec_out16(addr, x) __raw_writew(x, addr) -#define __fec_in32(addr) __raw_readl(addr) -#define __fec_in16(addr) __raw_readw(addr) -#else -/* for others play it safe */ -#define __fec_out32(addr, x) out_be32(addr, x) -#define __fec_out16(addr, x) out_be16(addr, x) -#define __fec_in32(addr) in_be32(addr) -#define __fec_in16(addr) in_be16(addr) -#endif - -/* write */ -#define FW(_fecp, _reg, _v) __fec_out32(&(_fecp)->fec_ ## _reg, (_v)) - -/* read */ -#define FR(_fecp, _reg) __fec_in32(&(_fecp)->fec_ ## _reg) - -/* set bits */ -#define FS(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) | (_v)) - -/* clear bits */ -#define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) - -/* buffer descriptor access macros */ - -/* write */ -#define CBDW_SC(_cbd, _sc) __fec_out16(&(_cbd)->cbd_sc, (_sc)) -#define CBDW_DATLEN(_cbd, _datlen) __fec_out16(&(_cbd)->cbd_datlen, (_datlen)) -#define CBDW_BUFADDR(_cbd, _bufaddr) __fec_out32(&(_cbd)->cbd_bufaddr, (_bufaddr)) - -/* read */ -#define CBDR_SC(_cbd) __fec_in16(&(_cbd)->cbd_sc) -#define CBDR_DATLEN(_cbd) __fec_in16(&(_cbd)->cbd_datlen) -#define CBDR_BUFADDR(_cbd) __fec_in32(&(_cbd)->cbd_bufaddr) - -/* set bits */ -#define CBDS_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) | (_sc)) - -/* clear bits */ -#define CBDC_SC(_cbd, _sc) CBDW_SC(_cbd, CBDR_SC(_cbd) & ~(_sc)) - -/***************************************************************************/ - -#endif diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c deleted file mode 100644 index ca8d2e8..0000000 --- a/drivers/net/fec_8xx/fec_main.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* - * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou - * - * Heavily based on original FEC driver by Dan Malek - * and modifications by Joakim Tjernlund - * - * Released under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "fec_8xx.h" - -/*************************************************/ - -#define FEC_MAX_MULTICAST_ADDRS 64 - -/*************************************************/ - -static char version[] __devinitdata = - DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; - -MODULE_AUTHOR("Pantelis Antoniou "); -MODULE_DESCRIPTION("Motorola 8xx FEC ethernet driver"); -MODULE_LICENSE("GPL"); - -int fec_8xx_debug = -1; /* -1 == use FEC_8XX_DEF_MSG_ENABLE as value */ -module_param(fec_8xx_debug, int, 0); -MODULE_PARM_DESC(fec_8xx_debug, - "FEC 8xx bitmapped debugging message enable value"); - - -/*************************************************/ - -/* - * Delay to wait for FEC reset command to complete (in us) - */ -#define FEC_RESET_DELAY 50 - -/*****************************************************************************************/ - -static void fec_whack_reset(fec_t * fecp) -{ - int i; - - /* - * Whack a reset. We should wait for this. - */ - FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET); - for (i = 0; - (FR(fecp, ecntrl) & FEC_ECNTRL_RESET) != 0 && i < FEC_RESET_DELAY; - i++) - udelay(1); - - if (i == FEC_RESET_DELAY) - printk(KERN_WARNING "FEC Reset timeout!\n"); - -} - -/****************************************************************************/ - -/* - * Transmitter timeout. - */ -#define TX_TIMEOUT (2*HZ) - -/****************************************************************************/ - -/* - * Returns the CRC needed when filling in the hash table for - * multicast group filtering - * pAddr must point to a MAC address (6 bytes) - */ -static __u32 fec_mulicast_calc_crc(char *pAddr) -{ - u8 byte; - int byte_count; - int bit_count; - __u32 crc = 0xffffffff; - u8 msb; - - for (byte_count = 0; byte_count < 6; byte_count++) { - byte = pAddr[byte_count]; - for (bit_count = 0; bit_count < 8; bit_count++) { - msb = crc >> 31; - crc <<= 1; - if (msb ^ (byte & 0x1)) { - crc ^= FEC_CRC_POLY; - } - byte >>= 1; - } - } - return (crc); -} - -/* - * Set or clear the multicast filter for this adaptor. - * Skeleton taken from sunlance driver. - * The CPM Ethernet implementation allows Multicast as well as individual - * MAC address filtering. Some of the drivers check to make sure it is - * a group multicast address, and discard those that are not. I guess I - * will do the same for now, but just remove the test if you want - * individual filtering as well (do the upper net layers want or support - * this kind of feature?). - */ -static void fec_set_multicast_list(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - struct dev_mc_list *pmc; - __u32 crc; - int temp; - __u32 csrVal; - int hash_index; - __u32 hthi, htlo; - unsigned long flags; - - - if ((dev->flags & IFF_PROMISC) != 0) { - - spin_lock_irqsave(&fep->lock, flags); - FS(fecp, r_cntrl, FEC_RCNTRL_PROM); - spin_unlock_irqrestore(&fep->lock, flags); - - /* - * Log any net taps. - */ - printk(KERN_WARNING DRV_MODULE_NAME - ": %s: Promiscuous mode enabled.\n", dev->name); - return; - - } - - if ((dev->flags & IFF_ALLMULTI) != 0 || - dev->mc_count > FEC_MAX_MULTICAST_ADDRS) { - /* - * Catch all multicast addresses, set the filter to all 1's. - */ - hthi = 0xffffffffU; - htlo = 0xffffffffU; - } else { - hthi = 0; - htlo = 0; - - /* - * Now populate the hash table - */ - for (pmc = dev->mc_list; pmc != NULL; pmc = pmc->next) { - crc = fec_mulicast_calc_crc(pmc->dmi_addr); - temp = (crc & 0x3f) >> 1; - hash_index = ((temp & 0x01) << 4) | - ((temp & 0x02) << 2) | - ((temp & 0x04)) | - ((temp & 0x08) >> 2) | - ((temp & 0x10) >> 4); - csrVal = (1 << hash_index); - if (crc & 1) - hthi |= csrVal; - else - htlo |= csrVal; - } - } - - spin_lock_irqsave(&fep->lock, flags); - FC(fecp, r_cntrl, FEC_RCNTRL_PROM); - FW(fecp, hash_table_high, hthi); - FW(fecp, hash_table_low, htlo); - spin_unlock_irqrestore(&fep->lock, flags); -} - -static int fec_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *mac = addr; - struct fec_enet_private *fep = netdev_priv(dev); - struct fec *fecp = fep->fecp; - int i; - __u32 addrhi, addrlo; - unsigned long flags; - - /* Get pointer to SCC area in parameter RAM. */ - for (i = 0; i < 6; i++) - dev->dev_addr[i] = mac->sa_data[i]; - - /* - * Set station address. - */ - addrhi = ((__u32) dev->dev_addr[0] << 24) | - ((__u32) dev->dev_addr[1] << 16) | - ((__u32) dev->dev_addr[2] << 8) | - (__u32) dev->dev_addr[3]; - addrlo = ((__u32) dev->dev_addr[4] << 24) | - ((__u32) dev->dev_addr[5] << 16); - - spin_lock_irqsave(&fep->lock, flags); - FW(fecp, addr_low, addrhi); - FW(fecp, addr_high, addrlo); - spin_unlock_irqrestore(&fep->lock, flags); - - return 0; -} - -/* - * This function is called to start or restart the FEC during a link - * change. This only happens when switching between half and full - * duplex. - */ -void fec_restart(struct net_device *dev, int duplex, int speed) -{ -#ifdef CONFIG_DUET - immap_t *immap = (immap_t *) IMAP_ADDR; - __u32 cptr; -#endif - struct fec_enet_private *fep = netdev_priv(dev); - struct fec *fecp = fep->fecp; - const struct fec_platform_info *fpi = fep->fpi; - cbd_t *bdp; - struct sk_buff *skb; - int i; - __u32 addrhi, addrlo; - - fec_whack_reset(fep->fecp); - - /* - * Set station address. - */ - addrhi = ((__u32) dev->dev_addr[0] << 24) | - ((__u32) dev->dev_addr[1] << 16) | - ((__u32) dev->dev_addr[2] << 8) | - (__u32) dev->dev_addr[3]; - addrlo = ((__u32) dev->dev_addr[4] << 24) | - ((__u32) dev->dev_addr[5] << 16); - FW(fecp, addr_low, addrhi); - FW(fecp, addr_high, addrlo); - - /* - * Reset all multicast. - */ - FW(fecp, hash_table_high, 0); - FW(fecp, hash_table_low, 0); - - /* - * Set maximum receive buffer size. - */ - FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); - FW(fecp, r_hash, PKT_MAXBUF_SIZE); - - /* - * Set receive and transmit descriptor base. - */ - FW(fecp, r_des_start, iopa((__u32) (fep->rx_bd_base))); - FW(fecp, x_des_start, iopa((__u32) (fep->tx_bd_base))); - - fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; - fep->tx_free = fep->tx_ring; - fep->cur_rx = fep->rx_bd_base; - - /* - * Reset SKB receive buffers - */ - for (i = 0; i < fep->rx_ring; i++) { - if ((skb = fep->rx_skbuff[i]) == NULL) - continue; - fep->rx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } - - /* - * Initialize the receive buffer descriptors. - */ - for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { - skb = dev_alloc_skb(ENET_RX_FRSIZE); - if (skb == NULL) { - printk(KERN_WARNING DRV_MODULE_NAME - ": %s Memory squeeze, unable to allocate skb\n", - dev->name); - fep->stats.rx_dropped++; - break; - } - fep->rx_skbuff[i] = skb; - skb->dev = dev; - CBDW_BUFADDR(bdp, dma_map_single(NULL, skb->data, - L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), - DMA_FROM_DEVICE)); - CBDW_DATLEN(bdp, 0); /* zero */ - CBDW_SC(bdp, BD_ENET_RX_EMPTY | - ((i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP)); - } - /* - * if we failed, fillup remainder - */ - for (; i < fep->rx_ring; i++, bdp++) { - fep->rx_skbuff[i] = NULL; - CBDW_SC(bdp, (i < fep->rx_ring - 1) ? 0 : BD_SC_WRAP); - } - - /* - * Reset SKB transmit buffers. - */ - for (i = 0; i < fep->tx_ring; i++) { - if ((skb = fep->tx_skbuff[i]) == NULL) - continue; - fep->tx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } - - /* - * ...and the same for transmit. - */ - for (i = 0, bdp = fep->tx_bd_base; i < fep->tx_ring; i++, bdp++) { - fep->tx_skbuff[i] = NULL; - CBDW_BUFADDR(bdp, virt_to_bus(NULL)); - CBDW_DATLEN(bdp, 0); - CBDW_SC(bdp, (i < fep->tx_ring - 1) ? 0 : BD_SC_WRAP); - } - - /* - * Enable big endian and don't care about SDMA FC. - */ - FW(fecp, fun_code, 0x78000000); - - /* - * Set MII speed. - */ - FW(fecp, mii_speed, fep->fec_phy_speed); - - /* - * Clear any outstanding interrupt. - */ - FW(fecp, ievent, 0xffc0); - FW(fecp, ivec, (fpi->fec_irq / 2) << 29); - - /* - * adjust to speed (only for DUET & RMII) - */ -#ifdef CONFIG_DUET - cptr = in_be32(&immap->im_cpm.cp_cptr); - switch (fpi->fec_no) { - case 0: - /* - * check if in RMII mode - */ - if ((cptr & 0x100) == 0) - break; - - if (speed == 10) - cptr |= 0x0000010; - else if (speed == 100) - cptr &= ~0x0000010; - break; - case 1: - /* - * check if in RMII mode - */ - if ((cptr & 0x80) == 0) - break; - - if (speed == 10) - cptr |= 0x0000008; - else if (speed == 100) - cptr &= ~0x0000008; - break; - default: - break; - } - out_be32(&immap->im_cpm.cp_cptr, cptr); -#endif - - FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - /* - * adjust to duplex mode - */ - if (duplex) { - FC(fecp, r_cntrl, FEC_RCNTRL_DRT); - FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ - } else { - FS(fecp, r_cntrl, FEC_RCNTRL_DRT); - FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ - } - - /* - * Enable interrupts we wish to service. - */ - FW(fecp, imask, FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB); - - /* - * And last, enable the transmit and receive processing. - */ - FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - FW(fecp, r_des_active, 0x01000000); -} - -void fec_stop(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - struct sk_buff *skb; - int i; - - if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) - return; /* already down */ - - FW(fecp, x_cntrl, 0x01); /* Graceful transmit stop */ - for (i = 0; ((FR(fecp, ievent) & 0x10000000) == 0) && - i < FEC_RESET_DELAY; i++) - udelay(1); - - if (i == FEC_RESET_DELAY) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s FEC timeout on graceful transmit stop\n", - dev->name); - /* - * Disable FEC. Let only MII interrupts. - */ - FW(fecp, imask, 0); - FW(fecp, ecntrl, ~FEC_ECNTRL_ETHER_EN); - - /* - * Reset SKB transmit buffers. - */ - for (i = 0; i < fep->tx_ring; i++) { - if ((skb = fep->tx_skbuff[i]) == NULL) - continue; - fep->tx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } - - /* - * Reset SKB receive buffers - */ - for (i = 0; i < fep->rx_ring; i++) { - if ((skb = fep->rx_skbuff[i]) == NULL) - continue; - fep->rx_skbuff[i] = NULL; - dev_kfree_skb(skb); - } -} - -/* common receive function */ -static int fec_enet_rx_common(struct fec_enet_private *ep, - struct net_device *dev, int budget) -{ - fec_t *fecp = fep->fecp; - const struct fec_platform_info *fpi = fep->fpi; - cbd_t *bdp; - struct sk_buff *skb, *skbn, *skbt; - int received = 0; - __u16 pkt_len, sc; - int curidx; - - /* - * First, grab all of the stats for the incoming packet. - * These get messed up if we get called due to a busy condition. - */ - bdp = fep->cur_rx; - - /* clear RX status bits for napi*/ - if (fpi->use_napi) - FW(fecp, ievent, FEC_ENET_RXF | FEC_ENET_RXB); - - while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { - - curidx = bdp - fep->rx_bd_base; - - /* - * Since we have allocated space to hold a complete frame, - * the last indicator should be set. - */ - if ((sc & BD_ENET_RX_LAST) == 0) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s rcv is not +last\n", - dev->name); - - /* - * Check for errors. - */ - if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_CL | - BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - fep->stats.rx_errors++; - /* Frame too long or too short. */ - if (sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) - fep->stats.rx_length_errors++; - /* Frame alignment */ - if (sc & (BD_ENET_RX_NO | BD_ENET_RX_CL)) - fep->stats.rx_frame_errors++; - /* CRC Error */ - if (sc & BD_ENET_RX_CR) - fep->stats.rx_crc_errors++; - /* FIFO overrun */ - if (sc & BD_ENET_RX_OV) - fep->stats.rx_crc_errors++; - - skbn = fep->rx_skbuff[curidx]; - BUG_ON(skbn == NULL); - - } else { - skb = fep->rx_skbuff[curidx]; - BUG_ON(skb == NULL); - - /* - * Process the incoming frame. - */ - fep->stats.rx_packets++; - pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */ - fep->stats.rx_bytes += pkt_len + 4; - - if (pkt_len <= fpi->rx_copybreak) { - /* +2 to make IP header L1 cache aligned */ - skbn = dev_alloc_skb(pkt_len + 2); - if (skbn != NULL) { - skb_reserve(skbn, 2); /* align IP header */ - skb_copy_from_linear_data(skb, - skbn->data, - pkt_len); - /* swap */ - skbt = skb; - skb = skbn; - skbn = skbt; - } - } else - skbn = dev_alloc_skb(ENET_RX_FRSIZE); - - if (skbn != NULL) { - skb_put(skb, pkt_len); /* Make room */ - skb->protocol = eth_type_trans(skb, dev); - received++; - if (!fpi->use_napi) - netif_rx(skb); - else - netif_receive_skb(skb); - } else { - printk(KERN_WARNING DRV_MODULE_NAME - ": %s Memory squeeze, dropping packet.\n", - dev->name); - fep->stats.rx_dropped++; - skbn = skb; - } - } - - fep->rx_skbuff[curidx] = skbn; - CBDW_BUFADDR(bdp, dma_map_single(NULL, skbn->data, - L1_CACHE_ALIGN(PKT_MAXBUF_SIZE), - DMA_FROM_DEVICE)); - CBDW_DATLEN(bdp, 0); - CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY); - - /* - * Update BD pointer to next entry. - */ - if ((sc & BD_ENET_RX_WRAP) == 0) - bdp++; - else - bdp = fep->rx_bd_base; - - /* - * Doing this here will keep the FEC running while we process - * incoming frames. On a heavily loaded network, we should be - * able to keep up at the expense of system resources. - */ - FW(fecp, r_des_active, 0x01000000); - - if (received >= budget) - break; - - } - - fep->cur_rx = bdp; - - if (fpi->use_napi) { - if (received < budget) { - netif_rx_complete(dev, &fep->napi); - - /* enable RX interrupt bits */ - FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); - } - } - - return received; -} - -static void fec_enet_tx(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - cbd_t *bdp; - struct sk_buff *skb; - int dirtyidx, do_wake; - __u16 sc; - - spin_lock(&fep->lock); - bdp = fep->dirty_tx; - - do_wake = 0; - while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) { - - dirtyidx = bdp - fep->tx_bd_base; - - if (fep->tx_free == fep->tx_ring) - break; - - skb = fep->tx_skbuff[dirtyidx]; - - /* - * Check for errors. - */ - if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | - BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { - fep->stats.tx_errors++; - if (sc & BD_ENET_TX_HB) /* No heartbeat */ - fep->stats.tx_heartbeat_errors++; - if (sc & BD_ENET_TX_LC) /* Late collision */ - fep->stats.tx_window_errors++; - if (sc & BD_ENET_TX_RL) /* Retrans limit */ - fep->stats.tx_aborted_errors++; - if (sc & BD_ENET_TX_UN) /* Underrun */ - fep->stats.tx_fifo_errors++; - if (sc & BD_ENET_TX_CSL) /* Carrier lost */ - fep->stats.tx_carrier_errors++; - } else - fep->stats.tx_packets++; - - if (sc & BD_ENET_TX_READY) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s HEY! Enet xmit interrupt and TX_READY.\n", - dev->name); - - /* - * Deferred means some collisions occurred during transmit, - * but we eventually sent the packet OK. - */ - if (sc & BD_ENET_TX_DEF) - fep->stats.collisions++; - - /* - * Free the sk buffer associated with this last transmit. - */ - dev_kfree_skb_irq(skb); - fep->tx_skbuff[dirtyidx] = NULL; - - /* - * Update pointer to next buffer descriptor to be transmitted. - */ - if ((sc & BD_ENET_TX_WRAP) == 0) - bdp++; - else - bdp = fep->tx_bd_base; - - /* - * Since we have freed up a buffer, the ring is no longer - * full. - */ - if (!fep->tx_free++) - do_wake = 1; - } - - fep->dirty_tx = bdp; - - spin_unlock(&fep->lock); - - if (do_wake && netif_queue_stopped(dev)) - netif_wake_queue(dev); -} - -/* - * The interrupt handler. - * This is called from the MPC core interrupt. - */ -static irqreturn_t -fec_enet_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct fec_enet_private *fep; - const struct fec_platform_info *fpi; - fec_t *fecp; - __u32 int_events; - __u32 int_events_napi; - - if (unlikely(dev == NULL)) - return IRQ_NONE; - - fep = netdev_priv(dev); - fecp = fep->fecp; - fpi = fep->fpi; - - /* - * Get the interrupt events that caused us to be here. - */ - while ((int_events = FR(fecp, ievent) & FR(fecp, imask)) != 0) { - - if (!fpi->use_napi) - FW(fecp, ievent, int_events); - else { - int_events_napi = int_events & ~(FEC_ENET_RXF | FEC_ENET_RXB); - FW(fecp, ievent, int_events_napi); - } - - if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR | - FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) - printk(KERN_WARNING DRV_MODULE_NAME - ": %s FEC ERROR(s) 0x%x\n", - dev->name, int_events); - - if ((int_events & FEC_ENET_RXF) != 0) { - if (!fpi->use_napi) - fec_enet_rx_common(fep, dev, ~0); - else { - if (netif_rx_schedule_prep(dev, &fep->napi)) { - /* disable rx interrupts */ - FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); - __netif_rx_schedule(dev, &fep->napi); - } else { - printk(KERN_ERR DRV_MODULE_NAME - ": %s driver bug! interrupt while in poll!\n", - dev->name); - FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); - } - } - } - - if ((int_events & FEC_ENET_TXF) != 0) - fec_enet_tx(dev); - } - - return IRQ_HANDLED; -} - -/* This interrupt occurs when the PHY detects a link change. */ -static irqreturn_t -fec_mii_link_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct fec_enet_private *fep; - const struct fec_platform_info *fpi; - - if (unlikely(dev == NULL)) - return IRQ_NONE; - - fep = netdev_priv(dev); - fpi = fep->fpi; - - if (!fpi->use_mdio) - return IRQ_NONE; - - /* - * Acknowledge the interrupt if possible. If we have not - * found the PHY yet we can't process or acknowledge the - * interrupt now. Instead we ignore this interrupt for now, - * which we can do since it is edge triggered. It will be - * acknowledged later by fec_enet_open(). - */ - if (!fep->phy) - return IRQ_NONE; - - fec_mii_ack_int(dev); - fec_mii_link_status_change_check(dev, 0); - - return IRQ_HANDLED; -} - - -/**********************************************************************************/ - -static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - cbd_t *bdp; - int curidx; - unsigned long flags; - - spin_lock_irqsave(&fep->tx_lock, flags); - - /* - * Fill in a Tx ring entry - */ - bdp = fep->cur_tx; - - if (!fep->tx_free || (CBDR_SC(bdp) & BD_ENET_TX_READY)) { - netif_stop_queue(dev); - spin_unlock_irqrestore(&fep->tx_lock, flags); - - /* - * Ooops. All transmit buffers are full. Bail out. - * This should not happen, since the tx queue should be stopped. - */ - printk(KERN_WARNING DRV_MODULE_NAME - ": %s tx queue full!.\n", dev->name); - return 1; - } - - curidx = bdp - fep->tx_bd_base; - /* - * Clear all of the status flags. - */ - CBDC_SC(bdp, BD_ENET_TX_STATS); - - /* - * Save skb pointer. - */ - fep->tx_skbuff[curidx] = skb; - - fep->stats.tx_bytes += skb->len; - - /* - * Push the data cache so the CPM does not get stale memory data. - */ - CBDW_BUFADDR(bdp, dma_map_single(NULL, skb->data, - skb->len, DMA_TO_DEVICE)); - CBDW_DATLEN(bdp, skb->len); - - dev->trans_start = jiffies; - - /* - * If this was the last BD in the ring, start at the beginning again. - */ - if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0) - fep->cur_tx++; - else - fep->cur_tx = fep->tx_bd_base; - - if (!--fep->tx_free) - netif_stop_queue(dev); - - /* - * Trigger transmission start - */ - CBDS_SC(bdp, BD_ENET_TX_READY | BD_ENET_TX_INTR | - BD_ENET_TX_LAST | BD_ENET_TX_TC); - FW(fecp, x_des_active, 0x01000000); - - spin_unlock_irqrestore(&fep->tx_lock, flags); - - return 0; -} - -static void fec_timeout(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fep->stats.tx_errors++; - - if (fep->tx_free) - netif_wake_queue(dev); - - /* check link status again */ - fec_mii_link_status_change_check(dev, 0); -} - -static int fec_enet_open(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - unsigned long flags; - - napi_enable(&fep->napi); - - /* Install our interrupt handler. */ - if (request_irq(fpi->fec_irq, fec_enet_interrupt, 0, "fec", dev) != 0) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s Could not allocate FEC IRQ!", dev->name); - napi_disable(&fep->napi); - return -EINVAL; - } - - /* Install our phy interrupt handler */ - if (fpi->phy_irq != -1 && - request_irq(fpi->phy_irq, fec_mii_link_interrupt, 0, "fec-phy", - dev) != 0) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s Could not allocate PHY IRQ!", dev->name); - free_irq(fpi->fec_irq, dev); - napi_disable(&fep->napi); - return -EINVAL; - } - - if (fpi->use_mdio) { - fec_mii_startup(dev); - netif_carrier_off(dev); - fec_mii_link_status_change_check(dev, 1); - } else { - spin_lock_irqsave(&fep->lock, flags); - fec_restart(dev, 1, 100); /* XXX this sucks */ - spin_unlock_irqrestore(&fep->lock, flags); - - netif_carrier_on(dev); - netif_start_queue(dev); - } - return 0; -} - -static int fec_enet_close(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - unsigned long flags; - - netif_stop_queue(dev); - napi_disable(&fep->napi); - netif_carrier_off(dev); - - if (fpi->use_mdio) - fec_mii_shutdown(dev); - - spin_lock_irqsave(&fep->lock, flags); - fec_stop(dev); - spin_unlock_irqrestore(&fep->lock, flags); - - /* release any irqs */ - if (fpi->phy_irq != -1) - free_irq(fpi->phy_irq, dev); - free_irq(fpi->fec_irq, dev); - - return 0; -} - -static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - return &fep->stats; -} - -static int fec_enet_poll(struct napi_struct *napi, int budget) -{ - struct fec_enet_private *fep = container_of(napi, struct fec_enet_private, napi); - struct net_device *dev = fep->dev; - - return fec_enet_rx_common(fep, dev, budget); -} - -/*************************************************************************/ - -static void fec_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRV_MODULE_NAME); - strcpy(info->version, DRV_MODULE_VERSION); -} - -static int fec_get_regs_len(struct net_device *dev) -{ - return sizeof(fec_t); -} - -static void fec_get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *p) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned long flags; - - if (regs->len < sizeof(fec_t)) - return; - - regs->version = 0; - spin_lock_irqsave(&fep->lock, flags); - memcpy_fromio(p, fep->fecp, sizeof(fec_t)); - spin_unlock_irqrestore(&fep->lock, flags); -} - -static int fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&fep->lock, flags); - rc = mii_ethtool_gset(&fep->mii_if, cmd); - spin_unlock_irqrestore(&fep->lock, flags); - - return rc; -} - -static int fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&fep->lock, flags); - rc = mii_ethtool_sset(&fep->mii_if, cmd); - spin_unlock_irqrestore(&fep->lock, flags); - - return rc; -} - -static int fec_nway_reset(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - return mii_nway_restart(&fep->mii_if); -} - -static __u32 fec_get_msglevel(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - return fep->msg_enable; -} - -static void fec_set_msglevel(struct net_device *dev, __u32 value) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fep->msg_enable = value; -} - -static const struct ethtool_ops fec_ethtool_ops = { - .get_drvinfo = fec_get_drvinfo, - .get_regs_len = fec_get_regs_len, - .get_settings = fec_get_settings, - .set_settings = fec_set_settings, - .nway_reset = fec_nway_reset, - .get_link = ethtool_op_get_link, - .get_msglevel = fec_get_msglevel, - .set_msglevel = fec_set_msglevel, - .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ - .set_sg = ethtool_op_set_sg, - .get_regs = fec_get_regs, -}; - -static int fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct fec_enet_private *fep = netdev_priv(dev); - struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; - unsigned long flags; - int rc; - - if (!netif_running(dev)) - return -EINVAL; - - spin_lock_irqsave(&fep->lock, flags); - rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); - spin_unlock_irqrestore(&fep->lock, flags); - return rc; -} - -int fec_8xx_init_one(const struct fec_platform_info *fpi, - struct net_device **devp) -{ - immap_t *immap = (immap_t *) IMAP_ADDR; - static int fec_8xx_version_printed = 0; - struct net_device *dev = NULL; - struct fec_enet_private *fep = NULL; - fec_t *fecp = NULL; - int i; - int err = 0; - int registered = 0; - __u32 siel; - - *devp = NULL; - - switch (fpi->fec_no) { - case 0: - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; - break; -#ifdef CONFIG_DUET - case 1: - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec2; - break; -#endif - default: - return -EINVAL; - } - - if (fec_8xx_version_printed++ == 0) - printk(KERN_INFO "%s", version); - - i = sizeof(*fep) + (sizeof(struct sk_buff **) * - (fpi->rx_ring + fpi->tx_ring)); - - dev = alloc_etherdev(i); - if (!dev) { - err = -ENOMEM; - goto err; - } - - fep = netdev_priv(dev); - fep->dev = dev; - - /* partial reset of FEC */ - fec_whack_reset(fecp); - - /* point rx_skbuff, tx_skbuff */ - fep->rx_skbuff = (struct sk_buff **)&fep[1]; - fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; - - fep->fecp = fecp; - fep->fpi = fpi; - - /* init locks */ - spin_lock_init(&fep->lock); - spin_lock_init(&fep->tx_lock); - - /* - * Set the Ethernet address. - */ - for (i = 0; i < 6; i++) - dev->dev_addr[i] = fpi->macaddr[i]; - - fep->ring_base = dma_alloc_coherent(NULL, - (fpi->tx_ring + fpi->rx_ring) * - sizeof(cbd_t), &fep->ring_mem_addr, - GFP_KERNEL); - if (fep->ring_base == NULL) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s dma alloc failed.\n", dev->name); - err = -ENOMEM; - goto err; - } - - /* - * Set receive and transmit descriptor base. - */ - fep->rx_bd_base = fep->ring_base; - fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; - - /* initialize ring size variables */ - fep->tx_ring = fpi->tx_ring; - fep->rx_ring = fpi->rx_ring; - - /* SIU interrupt */ - if (fpi->phy_irq != -1 && - (fpi->phy_irq >= SIU_IRQ0 && fpi->phy_irq < SIU_LEVEL7)) { - - siel = in_be32(&immap->im_siu_conf.sc_siel); - if ((fpi->phy_irq & 1) == 0) - siel |= (0x80000000 >> fpi->phy_irq); - else - siel &= ~(0x80000000 >> (fpi->phy_irq & ~1)); - out_be32(&immap->im_siu_conf.sc_siel, siel); - } - - /* - * The FEC Ethernet specific entries in the device structure. - */ - dev->open = fec_enet_open; - dev->hard_start_xmit = fec_enet_start_xmit; - dev->tx_timeout = fec_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - dev->stop = fec_enet_close; - dev->get_stats = fec_enet_get_stats; - dev->set_multicast_list = fec_set_multicast_list; - dev->set_mac_address = fec_set_mac_address; - netif_napi_add(dev, &fec->napi, - fec_enet_poll, fpi->napi_weight); - - dev->ethtool_ops = &fec_ethtool_ops; - dev->do_ioctl = fec_ioctl; - - fep->fec_phy_speed = - ((((fpi->sys_clk + 4999999) / 2500000) / 2) & 0x3F) << 1; - - init_timer(&fep->phy_timer_list); - - /* partial reset of FEC so that only MII works */ - FW(fecp, mii_speed, fep->fec_phy_speed); - FW(fecp, ievent, 0xffc0); - FW(fecp, ivec, (fpi->fec_irq / 2) << 29); - FW(fecp, imask, 0); - FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - FW(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - - netif_carrier_off(dev); - - err = register_netdev(dev); - if (err != 0) - goto err; - registered = 1; - - if (fpi->use_mdio) { - fep->mii_if.dev = dev; - fep->mii_if.mdio_read = fec_mii_read; - fep->mii_if.mdio_write = fec_mii_write; - fep->mii_if.phy_id_mask = 0x1f; - fep->mii_if.reg_num_mask = 0x1f; - fep->mii_if.phy_id = fec_mii_phy_id_detect(dev); - } - - *devp = dev; - - return 0; - - err: - if (dev != NULL) { - if (fecp != NULL) - fec_whack_reset(fecp); - - if (registered) - unregister_netdev(dev); - - if (fep != NULL) { - if (fep->ring_base) - dma_free_coherent(NULL, - (fpi->tx_ring + - fpi->rx_ring) * - sizeof(cbd_t), fep->ring_base, - fep->ring_mem_addr); - } - free_netdev(dev); - } - return err; -} - -int fec_8xx_cleanup_one(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp = fep->fecp; - const struct fec_platform_info *fpi = fep->fpi; - - fec_whack_reset(fecp); - - unregister_netdev(dev); - - dma_free_coherent(NULL, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), - fep->ring_base, fep->ring_mem_addr); - - free_netdev(dev); - - return 0; -} - -/**************************************************************************************/ -/**************************************************************************************/ -/**************************************************************************************/ - -static int __init fec_8xx_init(void) -{ - return fec_8xx_platform_init(); -} - -static void __exit fec_8xx_cleanup(void) -{ - fec_8xx_platform_cleanup(); -} - -/**************************************************************************************/ -/**************************************************************************************/ -/**************************************************************************************/ - -module_init(fec_8xx_init); -module_exit(fec_8xx_cleanup); diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c deleted file mode 100644 index 3b6ca29..0000000 --- a/drivers/net/fec_8xx/fec_mii.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou - * - * Heavily based on original FEC driver by Dan Malek - * and modifications by Joakim Tjernlund - * - * Released under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/*************************************************/ - -#include "fec_8xx.h" - -/*************************************************/ - -/* Make MII read/write commands for the FEC. -*/ -#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) -#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) -#define mk_mii_end 0 - -/*************************************************/ - -/* XXX both FECs use the MII interface of FEC1 */ -static DEFINE_SPINLOCK(fec_mii_lock); - -#define FEC_MII_LOOPS 10000 - -int fec_mii_read(struct net_device *dev, int phy_id, int location) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp; - int i, ret = -1; - unsigned long flags; - - /* XXX MII interface is only connected to FEC1 */ - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; - - spin_lock_irqsave(&fec_mii_lock, flags); - - if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) { - FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - FW(fecp, ievent, FEC_ENET_MII); - } - - /* Add PHY address to register command. */ - FW(fecp, mii_speed, fep->fec_phy_speed); - FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); - - for (i = 0; i < FEC_MII_LOOPS; i++) - if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) - break; - - if (i < FEC_MII_LOOPS) { - FW(fecp, ievent, FEC_ENET_MII); - ret = FR(fecp, mii_data) & 0xffff; - } - - spin_unlock_irqrestore(&fec_mii_lock, flags); - - return ret; -} - -void fec_mii_write(struct net_device *dev, int phy_id, int location, int value) -{ - struct fec_enet_private *fep = netdev_priv(dev); - fec_t *fecp; - unsigned long flags; - int i; - - /* XXX MII interface is only connected to FEC1 */ - fecp = &((immap_t *) IMAP_ADDR)->im_cpm.cp_fec; - - spin_lock_irqsave(&fec_mii_lock, flags); - - if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) { - FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - FW(fecp, ievent, FEC_ENET_MII); - } - - /* Add PHY address to register command. */ - FW(fecp, mii_speed, fep->fec_phy_speed); /* always adapt mii speed */ - FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); - - for (i = 0; i < FEC_MII_LOOPS; i++) - if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) - break; - - if (i < FEC_MII_LOOPS) - FW(fecp, ievent, FEC_ENET_MII); - - spin_unlock_irqrestore(&fec_mii_lock, flags); -} - -/*************************************************/ - -#ifdef CONFIG_FEC_8XX_GENERIC_PHY - -/* - * Generic PHY support. - * Should work for all PHYs, but link change is detected by polling - */ - -static void generic_timer_callback(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct fec_enet_private *fep = netdev_priv(dev); - - fep->phy_timer_list.expires = jiffies + HZ / 2; - - add_timer(&fep->phy_timer_list); - - fec_mii_link_status_change_check(dev, 0); -} - -static void generic_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ - fep->phy_timer_list.data = (unsigned long)dev; - fep->phy_timer_list.function = generic_timer_callback; - add_timer(&fep->phy_timer_list); -} - -static void generic_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - del_timer_sync(&fep->phy_timer_list); -} - -#endif - -#ifdef CONFIG_FEC_8XX_DM9161_PHY - -/* ------------------------------------------------------------------------- */ -/* The Davicom DM9161 is used on the NETTA board */ - -/* register definitions */ - -#define MII_DM9161_ACR 16 /* Aux. Config Register */ -#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ -#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ -#define MII_DM9161_INTR 21 /* Interrupt Register */ -#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ -#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ - -static void dm9161_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); -} - -static void dm9161_ack_int(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); -} - -static void dm9161_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); -} - -#endif - -#ifdef CONFIG_FEC_8XX_LXT971_PHY - -/* Support for LXT971/972 PHY */ - -#define MII_LXT971_PCR 16 /* Port Control Register */ -#define MII_LXT971_SR2 17 /* Status Register 2 */ -#define MII_LXT971_IER 18 /* Interrupt Enable Register */ -#define MII_LXT971_ISR 19 /* Interrupt Status Register */ -#define MII_LXT971_LCR 20 /* LED Control Register */ -#define MII_LXT971_TCR 30 /* Transmit Control Register */ - -static void lxt971_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x00F2); -} - -static void lxt971_ack_int(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_read(dev, fep->mii_if.phy_id, MII_LXT971_ISR); -} - -static void lxt971_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x0000); -} -#endif - -/**********************************************************************************/ - -static const struct phy_info phy_info[] = { -#ifdef CONFIG_FEC_8XX_DM9161_PHY - { - .id = 0x00181b88, - .name = "DM9161", - .startup = dm9161_startup, - .ack_int = dm9161_ack_int, - .shutdown = dm9161_shutdown, - }, -#endif -#ifdef CONFIG_FEC_8XX_LXT971_PHY - { - .id = 0x0001378e, - .name = "LXT971/972", - .startup = lxt971_startup, - .ack_int = lxt971_ack_int, - .shutdown = lxt971_shutdown, - }, -#endif -#ifdef CONFIG_FEC_8XX_GENERIC_PHY - { - .id = 0, - .name = "GENERIC", - .startup = generic_startup, - .shutdown = generic_shutdown, - }, -#endif -}; - -/**********************************************************************************/ - -int fec_mii_phy_id_detect(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - int i, r, start, end, phytype, physubtype; - const struct phy_info *phy; - int phy_hwid, phy_id; - - /* if no MDIO */ - if (fpi->use_mdio == 0) - return -1; - - phy_hwid = -1; - fep->phy = NULL; - - /* auto-detect? */ - if (fpi->phy_addr == -1) { - start = 0; - end = 32; - } else { /* direct */ - start = fpi->phy_addr; - end = start + 1; - } - - for (phy_id = start; phy_id < end; phy_id++) { - r = fec_mii_read(dev, phy_id, MII_PHYSID1); - if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) - continue; - r = fec_mii_read(dev, phy_id, MII_PHYSID2); - if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) - continue; - phy_hwid = (phytype << 16) | physubtype; - if (phy_hwid != -1) - break; - } - - if (phy_hwid == -1) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s No PHY detected!\n", dev->name); - return -1; - } - - for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) - if (phy->id == (phy_hwid >> 4) || phy->id == 0) - break; - - if (i >= ARRAY_SIZE(phy_info)) { - printk(KERN_ERR DRV_MODULE_NAME - ": %s PHY id 0x%08x is not supported!\n", - dev->name, phy_hwid); - return -1; - } - - fep->phy = phy; - - printk(KERN_INFO DRV_MODULE_NAME - ": %s Phy @ 0x%x, type %s (0x%08x)\n", - dev->name, phy_id, fep->phy->name, phy_hwid); - - return phy_id; -} - -void fec_mii_startup(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - - if (!fpi->use_mdio || fep->phy == NULL) - return; - - if (fep->phy->startup == NULL) - return; - - (*fep->phy->startup) (dev); -} - -void fec_mii_shutdown(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - - if (!fpi->use_mdio || fep->phy == NULL) - return; - - if (fep->phy->shutdown == NULL) - return; - - (*fep->phy->shutdown) (dev); -} - -void fec_mii_ack_int(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - const struct fec_platform_info *fpi = fep->fpi; - - if (!fpi->use_mdio || fep->phy == NULL) - return; - - if (fep->phy->ack_int == NULL) - return; - - (*fep->phy->ack_int) (dev); -} - -/* helper function */ -static int mii_negotiated(struct mii_if_info *mii) -{ - int advert, lpa, val; - - if (!mii_link_ok(mii)) - return 0; - - val = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_BMSR); - if ((val & BMSR_ANEGCOMPLETE) == 0) - return 0; - - advert = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_ADVERTISE); - lpa = (*mii->mdio_read) (mii->dev, mii->phy_id, MII_LPA); - - return mii_nway_result(advert & lpa); -} - -void fec_mii_link_status_change_check(struct net_device *dev, int init_media) -{ - struct fec_enet_private *fep = netdev_priv(dev); - unsigned int media; - unsigned long flags; - - if (mii_check_media(&fep->mii_if, netif_msg_link(fep), init_media) == 0) - return; - - media = mii_negotiated(&fep->mii_if); - - if (netif_carrier_ok(dev)) { - spin_lock_irqsave(&fep->lock, flags); - fec_restart(dev, !!(media & ADVERTISE_FULL), - (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) ? - 100 : 10); - spin_unlock_irqrestore(&fep->lock, flags); - - netif_start_queue(dev); - } else { - netif_stop_queue(dev); - - spin_lock_irqsave(&fep->lock, flags); - fec_stop(dev); - spin_unlock_irqrestore(&fep->lock, flags); - - } -} -- cgit v0.10.2 From ee1a08f963c5abb5ec2d8c5defffecee7c3f84c8 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Thu, 24 Apr 2008 08:32:26 +1000 Subject: [POWERPC] mpic_pasemi_msi: Failed allocation unnoticed bitmap_find_free_region(), called by mpic_msi_alloc_hwirqs() may return signed, but hwirq is unsigned. A failed allocation remains unnoticed. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index 33cbfb2..68aff60 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -95,6 +95,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) unsigned int virq; struct msi_desc *entry; struct msi_msg msg; + int ret; pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", pdev, nvec, type); @@ -108,8 +109,9 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) * few MSIs for someone, but restrictions will apply to how the * sources can be changed independently. */ - hwirq = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK); - if (hwirq < 0) { + ret = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK); + hwirq = ret; + if (ret < 0) { pr_debug("pasemi_msi: failed allocating hwirq\n"); return hwirq; } -- cgit v0.10.2 From 9d5f525b86453da921360727112161254accc8c1 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Thu, 24 Apr 2008 09:03:02 +1000 Subject: [POWERPC] mpic_u3msi: Failed allocation unnoticed bitmap_find_free_region(), called by mpic_msi_alloc_hwirqs() may return signed, but hwirq is unsigned. A failed allocation remains unnoticed. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index 1d5a408..6e2f868 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -115,17 +115,19 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) struct msi_desc *entry; struct msi_msg msg; u64 addr; + int ret; addr = find_ht_magic_addr(pdev); msg.address_lo = addr & 0xFFFFFFFF; msg.address_hi = addr >> 32; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = mpic_msi_alloc_hwirqs(msi_mpic, 1); - if (hwirq < 0) { + ret = mpic_msi_alloc_hwirqs(msi_mpic, 1); + if (ret < 0) { pr_debug("u3msi: failed allocating hwirq\n"); - return hwirq; + return ret; } + hwirq = ret; virq = irq_create_mapping(msi_mpic->irqhost, hwirq); if (virq == NO_IRQ) { -- cgit v0.10.2 From 140b932f8cb6cced10b96860651a198b1b89cbb9 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 24 Apr 2008 23:16:00 +1000 Subject: [POWERPC] Create modalias file in sysfs for of_platform bus Create /sys/bus/of_platform/devices/*/modalias file to allow autoloading of modules. Modalias files are already present for many other bus types. This adds also a newline to the devspec files. Also create a devspec file for mac-io devices. They were created as a side effect. Use correct buffer size for mac-io modalias buffer. Tested on iBook1 and Efika. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 112e5ef..9e9453b 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -44,7 +44,7 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, struct of_device *ofdev = to_of_device(dev); int len; - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE); + len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; @@ -52,6 +52,15 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, return len+1; } +static ssize_t devspec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s\n", ofdev->node->full_name); +} + macio_config_of_attr (name, "%s\n"); macio_config_of_attr (type, "%s\n"); @@ -60,5 +69,6 @@ struct device_attribute macio_dev_attrs[] = { __ATTR_RO(type), __ATTR_RO(compatible), __ATTR_RO(modalias), + __ATTR_RO(devspec), __ATTR_NULL }; diff --git a/drivers/of/device.c b/drivers/of/device.c index 29681c4..8fbfeee 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -48,16 +48,32 @@ void of_dev_put(struct of_device *dev) } EXPORT_SYMBOL(of_dev_put); -static ssize_t dev_show_devspec(struct device *dev, +static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, char *buf) { struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->node->full_name); } -static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); +static ssize_t modalias_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev = to_of_device(dev); + ssize_t len = 0; + + len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); + buf[len] = '\n'; + buf[len+1] = 0; + return len+1; +} + +struct device_attribute of_platform_device_attrs[] = { + __ATTR_RO(devspec), + __ATTR_RO(modalias), + __ATTR_NULL +}; /** * of_release_dev - free an of device structure when all users of it are finished. @@ -78,25 +94,13 @@ EXPORT_SYMBOL(of_release_dev); int of_device_register(struct of_device *ofdev) { - int rc; - BUG_ON(ofdev->node == NULL); - - rc = device_register(&ofdev->dev); - if (rc) - return rc; - - rc = device_create_file(&ofdev->dev, &dev_attr_devspec); - if (rc) - device_unregister(&ofdev->dev); - - return rc; + return device_register(&ofdev->dev); } EXPORT_SYMBOL(of_device_register); void of_device_unregister(struct of_device *ofdev) { - device_remove_file(&ofdev->dev, &dev_attr_devspec); device_unregister(&ofdev->dev); } EXPORT_SYMBOL(of_device_unregister); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ca09a63..298de0f 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -17,6 +17,8 @@ #include #include +extern struct device_attribute of_platform_device_attrs[]; + static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device *of_dev = to_of_device(dev); @@ -103,6 +105,7 @@ int of_bus_type_init(struct bus_type *bus, const char *name) bus->suspend = of_platform_device_suspend; bus->resume = of_platform_device_resume; bus->shutdown = of_platform_device_shutdown; + bus->dev_attrs = of_platform_device_attrs; return bus_register(bus); } -- cgit v0.10.2 From 7a10174eeafe737f3ccfcece5bdff749c3b044e0 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 28 Apr 2008 17:30:37 +1000 Subject: [POWERPC] Define and use TLF_RESTORE_SIGMASK Replace TIF_RESTORE_SIGMASK with TLF_RESTORE_SIGMASK and define our own set_restore_sigmask() function. This saves the costly SMP-safe set_bit operation, which we do not need for the sigmask flag since TIF_SIGPENDING always has to be set too. Signed-off-by: Roland McGrath Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0c8614d..3a05e9f 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -668,7 +668,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r9,TI_FLAGS(r9) - andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED) + andi. r0,r9,_TIF_USER_WORK_MASK bne do_work restore_user: @@ -925,7 +925,7 @@ recheck: lwz r9,TI_FLAGS(r9) andi. r0,r9,_TIF_NEED_RESCHED bne- do_resched - andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK + andi. r0,r9,_TIF_USER_WORK_MASK beq restore_user do_user_signal: /* r10 contains MSR_KERNEL here */ ori r10,r10,MSR_EE diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a65a44f..ad55488 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -120,7 +120,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) int ret; int is32 = is_32bit_task(); - if (test_thread_flag(TIF_RESTORE_SIGMASK)) + if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else if (!oldset) oldset = ¤t->blocked; @@ -131,9 +131,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { + struct thread_info *ti = current_thread_info(); /* No signal to deliver -- put the saved sigmask back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); + if (ti->local_flags & _TLF_RESTORE_SIGMASK) { + ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return 0; /* no signals delivered */ @@ -169,10 +170,9 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) /* * A signal was successfully delivered; the saved sigmask is in - * its frame, and we can clear the TIF_RESTORE_SIGMASK flag. + * its frame, and we can clear the TLF_RESTORE_SIGMASK flag. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); + current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; } return ret; diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index ad69434..4ae16d1 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -243,7 +243,7 @@ long sys_sigsuspend(old_sigset_t mask) current->state = TASK_INTERRUPTIBLE; schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); + set_restore_sigmask(); return -ERESTARTNOHAND; } diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 5f3a5d0..fcd830a 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -647,7 +647,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,18 lwz r9,TI_FLAGS(r9) - andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED) + andi. r0,r9,_TIF_USER_WORK_MASK bne do_work restore_user: @@ -898,7 +898,7 @@ recheck: lwz r9,TI_FLAGS(r9) andi. r0,r9,_TIF_NEED_RESCHED bne- do_resched - andi. r0,r9,_TIF_SIGPENDING + andi. r0,r9,_TIF_USER_WORK_MASK beq restore_user do_user_signal: /* r10 contains MSR_KERNEL here */ ori r10,r10,MSR_EE diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index d030f5c..e079e81 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -116,7 +116,6 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SECCOMP 10 /* secure computing */ #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12 /* Force successful syscall return */ -#define TIF_RESTORE_SIGMASK 13 /* Restore signal mask in do_signal */ #define TIF_FREEZE 14 /* Freezing for suspend */ #define TIF_RUNLATCH 15 /* Is the runlatch enabled? */ #define TIF_ABI_PENDING 16 /* 32/64 bit switch needed */ @@ -134,21 +133,31 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SECCOMP (1<local_flags |= _TLF_RESTORE_SIGMASK; + set_bit(TIF_SIGPENDING, &ti->flags); +} +#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ -- cgit v0.10.2 From 663276b7c6340e755ed62bed67a2b96f4fc3d513 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 30 Apr 2008 20:44:53 +1000 Subject: [POWERPC] Set lower flag bits in regs->trap to indicate debug level exception We use the low bits of regs->trap as flag bits. We already indicate critical and machine check level exceptions via this mechanism. Extend it to indicate debug level exceptions. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index aefafc6..721faef 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -272,7 +272,7 @@ label: /* continue normal handling for a critical exception... */ \ 2: mfspr r4,SPRN_DBSR; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ - EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc) + EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc) #define DEBUG_CRIT_EXCEPTION \ START_EXCEPTION(DebugCrit); \ diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h index 39023dd..38d87e5 100644 --- a/include/asm-powerpc/ptrace.h +++ b/include/asm-powerpc/ptrace.h @@ -119,6 +119,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno, #ifndef __powerpc64__ #define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0) #define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0) +#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0) #endif /* ! __powerpc64__ */ #define TRAP(regs) ((regs)->trap & ~0xF) #ifdef __powerpc64__ -- cgit v0.10.2 From 683307da07afd3a7ee55269ee8cb70c8053b0923 Mon Sep 17 00:00:00 2001 From: Remi Machet Date: Thu, 1 May 2008 10:40:44 +1000 Subject: [POWERPC] Create of_buses for MV64x60 devices For each mv64360 entry in the OpenFirmware database, add the registration of an of_bus to take care of devices connected to the MV64x60 asynchronous devices controller. This change makes it possible for those devices to be detected by drivers that support the of_platform without having a custom call for each of them in the board file. Signed-off-by: Remi Machet Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index a132e0d..32e0ad0 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -25,6 +26,11 @@ * PowerPC of_platform_bus_type. They support platform_bus_type instead. */ +static struct of_device_id __initdata of_mv64x60_devices[] = { + { .compatible = "marvell,mv64306-devctrl", }, + {} +}; + /* * Create MPSC platform devices */ @@ -484,6 +490,10 @@ static int __init mv64x60_device_setup(void) of_node_put(np); } + /* Now add every node that is on the device bus */ + for_each_compatible_node(np, NULL, "marvell,mv64360") + of_platform_bus_probe(np, of_mv64x60_devices, NULL); + return 0; } arch_initcall(mv64x60_device_setup); -- cgit v0.10.2 From 5f25f06529ecb4b20efc7ba00de599f5b9f4b63c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:07 +1000 Subject: [POWERPC] Move declaration of init_bootmem_done into system.h ... instead of having an extern declaration in a .c file. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 1952b4d..4541859 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "mmu_decl.h" @@ -76,8 +77,6 @@ void MMU_init(void); /* XXX should be in current.h -- paulus */ extern struct task_struct *current_set[NR_CPUS]; -extern int init_bootmem_done; - /* * this tells the system to map all of ram with the segregs * (i.e. page tables) instead of the bats. diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 2b6559a..df781ad 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -190,6 +190,7 @@ extern struct task_struct *_switch(struct thread_struct *prev, extern unsigned int rtas_data; extern int mem_init_done; /* set on boot once kmalloc can be called */ +extern int init_bootmem_done; /* set on !NUMA once bootmem is available */ extern unsigned long memory_limit; extern unsigned long klimit; -- cgit v0.10.2 From 09de9ff872bca25ba717a7075c9ee49b1bdb56d2 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:07 +1000 Subject: [POWERPC] Fix sparse warnings in arch/powerpc/mm Make two vmemmap helpers static in init_64.c Make stab variables static in stab.c Make psize defs static in hash_utils_64.c Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 2b5a399..1a4b4b3 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -117,7 +117,7 @@ static DEFINE_SPINLOCK(linear_map_hash_lock); /* Pre-POWER4 CPUs (4k pages only) */ -struct mmu_psize_def mmu_psize_defaults_old[] = { +static struct mmu_psize_def mmu_psize_defaults_old[] = { [MMU_PAGE_4K] = { .shift = 12, .sllp = 0, @@ -131,7 +131,7 @@ struct mmu_psize_def mmu_psize_defaults_old[] = { * * Support for 16Mb large pages */ -struct mmu_psize_def mmu_psize_defaults_gp[] = { +static struct mmu_psize_def mmu_psize_defaults_gp[] = { [MMU_PAGE_4K] = { .shift = 12, .sllp = 0, diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index c5ac532..1e52e97 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -183,7 +183,7 @@ void pgtable_cache_init(void) * do this by hand as the proffered address may not be correctly aligned. * Subtraction of non-aligned pointers produces undefined results. */ -unsigned long __meminit vmemmap_section_start(unsigned long page) +static unsigned long __meminit vmemmap_section_start(unsigned long page) { unsigned long offset = page - ((unsigned long)(vmemmap)); @@ -196,7 +196,7 @@ unsigned long __meminit vmemmap_section_start(unsigned long page) * which overlaps this vmemmap page is initialised then this page is * initialised already. */ -int __meminit vmemmap_populated(unsigned long start, int page_size) +static int __meminit vmemmap_populated(unsigned long start, int page_size) { unsigned long end = start + page_size; diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index efbbd13..60e6032 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c @@ -30,8 +30,8 @@ struct stab_entry { }; #define NR_STAB_CACHE_ENTRIES 8 -DEFINE_PER_CPU(long, stab_cache_ptr); -DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]); +static DEFINE_PER_CPU(long, stab_cache_ptr); +static DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]); /* * Create a segment table entry for the given esid/vsid pair. -- cgit v0.10.2 From 572fb578de59efaaa8d197b0183db43b1128a06e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:08 +1000 Subject: [POWERPC] Move declaration of tce variables into mmu-hash64.h ... instead of having extern declarations in a .c file. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 1a4b4b3..05f955f 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -509,8 +509,6 @@ void __init htab_initialize(void) unsigned long base = 0, size = 0, limit; int i; - extern unsigned long tce_alloc_start, tce_alloc_end; - DBG(" -> htab_initialize()\n"); /* Initialize segment sizes */ diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index 0dff767..f35d1e1 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h @@ -181,6 +181,7 @@ extern int mmu_io_psize; extern int mmu_kernel_ssize; extern int mmu_highuser_ssize; extern u16 mmu_slb_size; +extern unsigned long tce_alloc_start, tce_alloc_end; /* * If the processor supports 64k normal pages but not 64k cache -- cgit v0.10.2 From c884116ac375c5dd137109b58acaa9cf50164796 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:09 +1000 Subject: [POWERPC] Remove duplicate variable definitions in mm/tlb_64.c Somewhere along the way (e28f7faf05159f1cfd564596f5e6178edba6bd49, "Four level pagetables for ppc64") we ended up with duplicate definitions for pte_freelist_cur and pte_freelist_force_free. Somehow this compiles, but it would be better to just have one definition for each. The two definitions we end up with can be static too! Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c index e2d867c..509bc56 100644 --- a/arch/powerpc/mm/tlb_64.c +++ b/arch/powerpc/mm/tlb_64.c @@ -37,8 +37,8 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); * include/asm-powerpc/tlb.h file -- tgall */ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); -unsigned long pte_freelist_forced_free; +static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); +static unsigned long pte_freelist_forced_free; struct pte_freelist_batch { @@ -47,9 +47,6 @@ struct pte_freelist_batch pgtable_free_t tables[0]; }; -DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); -unsigned long pte_freelist_forced_free; - #define PTE_FREELIST_SIZE \ ((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \ / sizeof(pgtable_free_t)) -- cgit v0.10.2 From 8fa29d22dcb2aec97f1a508cd3741c6e0b4a9434 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:11 +1000 Subject: [POWERPC] sysdev/mpic_msi.c should include sysdev/mpic.h Some of the routines defined in mpic_msi.c are declared mpic.h, so the former should include the latter. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index d272a52..de3e5e8 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -16,6 +16,7 @@ #include #include +#include static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) { -- cgit v0.10.2 From 7d9e793463d854073f5c0dedea991a5b63336d6a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:13 +1000 Subject: [POWERPC] Add a declaration for xmon() Usually we call xmon() via debugger(), so this could be static. Sometimes when debugging it's nice to be able to call xmon() directly though, so add a declaration. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index 88320a0..81477f2 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h @@ -15,6 +15,8 @@ #ifdef CONFIG_XMON extern void xmon_setup(void); extern void xmon_register_spus(struct list_head *list); +struct pt_regs; +extern int xmon(struct pt_regs *excp); #else static inline void xmon_setup(void) { }; static inline void xmon_register_spus(struct list_head *list) { }; -- cgit v0.10.2 From af3b74df1b2fa4dbfb0534818167f6393f5ae7c7 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:15 +1000 Subject: [POWERPC] Move xmon_irq() declaration into xmon.h The typdef for irqreturn_t was moved into its own header a while back, so there's no reason we can't move xmon_irq() into xmon.h now. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 116babb..1ba7ce5 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -63,13 +63,6 @@ static struct mpic *chrp_mpic; DEFINE_PER_CPU(struct timer_list, heartbeat_timer); unsigned long event_scan_interval; -/* - * XXX this should be in xmon.h, but putting it there means xmon.h - * has to include (to get irqreturn_t), which - * causes all sorts of problems. -- paulus - */ -extern irqreturn_t xmon_irq(int, void *); - extern unsigned long loops_per_jiffy; /* To be replaced by RTAS when available */ diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 829b8b0..6d149ae 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -34,16 +34,10 @@ #include #include #include +#include #include "pmac.h" -/* - * XXX this should be in xmon.h, but putting it there means xmon.h - * has to include (to get irqreturn_t), which - * causes all sorts of problems. -- paulus - */ -extern irqreturn_t xmon_irq(int, void *); - #ifdef CONFIG_PPC32 struct pmac_irq_hw { unsigned int event; diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index 81477f2..d83da3c 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h @@ -12,11 +12,14 @@ #ifdef __KERNEL__ +#include + #ifdef CONFIG_XMON extern void xmon_setup(void); extern void xmon_register_spus(struct list_head *list); struct pt_regs; extern int xmon(struct pt_regs *excp); +extern irqreturn_t xmon_irq(int, void *); #else static inline void xmon_setup(void) { }; static inline void xmon_register_spus(struct list_head *list) { }; -- cgit v0.10.2 From 9f1067c2d98ac1c43f0c82892f5647774a6ac759 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:16 +1000 Subject: [POWERPC] Fix sparse warnings in xmon.c warning: Using plain integer as NULL pointer warning: Using plain integer as NULL pointer warning: symbol 'excprint' was not declared. Should it be static? warning: symbol 'prregs' was not declared. Should it be static? warning: symbol 'cacheflush' was not declared. Should it be static? warning: symbol 'read_spr' was not declared. Should it be static? warning: symbol 'write_spr' was not declared. Should it be static? warning: symbol 'super_regs' was not declared. Should it be static? warning: symbol 'mread' was not declared. Should it be static? warning: symbol 'mwrite' was not declared. Should it be static? warning: symbol 'byterev' was not declared. Should it be static? warning: symbol 'memex' was not declared. Should it be static? warning: symbol 'bsesc' was not declared. Should it be static? warning: symbol 'dump' was not declared. Should it be static? warning: symbol 'prdump' was not declared. Should it be static? warning: symbol 'generic_inst_dump' was not declared. Should it be static? warning: symbol 'ppc_inst_dump' was not declared. Should it be static? warning: symbol 'memops' was not declared. Should it be static? warning: symbol 'memdiffs' was not declared. Should it be static? warning: symbol 'memlocate' was not declared. Should it be static? warning: symbol 'memzcan' was not declared. Should it be static? warning: symbol 'proccall' was not declared. Should it be static? warning: symbol 'scannl' was not declared. Should it be static? warning: symbol 'hexdigit' was not declared. Should it be static? warning: symbol 'flush_input' was not declared. Should it be static? warning: symbol 'inchar' was not declared. Should it be static? warning: symbol 'take_input' was not declared. Should it be static? warning: symbol 'xmon_init' was not declared. Should it be static? Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1702de9..95f24c9 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -154,7 +154,7 @@ static int do_spu_cmd(void); static void dump_tlb_44x(void); #endif -int xmon_no_auto_backtrace; +static int xmon_no_auto_backtrace; extern void xmon_enter(void); extern void xmon_leave(void); @@ -593,7 +593,7 @@ static int xmon_iabr_match(struct pt_regs *regs) { if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) return 0; - if (iabr == 0) + if (iabr == NULL) return 0; xmon_core(regs, 0); return 1; @@ -1142,7 +1142,7 @@ bpt_cmds(void) } else { /* assume a breakpoint address */ bp = at_breakpoint(a); - if (bp == 0) { + if (bp == NULL) { printf("No breakpoint at %x\n", a); break; } @@ -1370,7 +1370,7 @@ static void print_bug_trap(struct pt_regs *regs) #endif } -void excprint(struct pt_regs *fp) +static void excprint(struct pt_regs *fp) { unsigned long trap; @@ -1408,7 +1408,7 @@ void excprint(struct pt_regs *fp) print_bug_trap(fp); } -void prregs(struct pt_regs *fp) +static void prregs(struct pt_regs *fp) { int n, trap; unsigned long base; @@ -1463,7 +1463,7 @@ void prregs(struct pt_regs *fp) printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); } -void cacheflush(void) +static void cacheflush(void) { int cmd; unsigned long nflush; @@ -1495,7 +1495,7 @@ void cacheflush(void) catch_memory_errors = 0; } -unsigned long +static unsigned long read_spr(int n) { unsigned int instrs[2]; @@ -1533,7 +1533,7 @@ read_spr(int n) return ret; } -void +static void write_spr(int n, unsigned long val) { unsigned int instrs[2]; @@ -1571,7 +1571,7 @@ static unsigned long regno; extern char exc_prolog; extern char dec_exc; -void super_regs(void) +static void super_regs(void) { int cmd; unsigned long val; @@ -1629,7 +1629,7 @@ void super_regs(void) /* * Stuff for reading and writing memory safely */ -int +static int mread(unsigned long adrs, void *buf, int size) { volatile int n; @@ -1666,7 +1666,7 @@ mread(unsigned long adrs, void *buf, int size) return n; } -int +static int mwrite(unsigned long adrs, void *buf, int size) { volatile int n; @@ -1731,7 +1731,7 @@ static int handle_fault(struct pt_regs *regs) #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) -void +static void byterev(unsigned char *val, int size) { int t; @@ -1793,7 +1793,7 @@ static char *memex_subcmd_help_string = " x exit this mode\n" ""; -void +static void memex(void) { int cmd, inc, i, nslash; @@ -1944,7 +1944,7 @@ memex(void) } } -int +static int bsesc(void) { int c; @@ -1984,7 +1984,7 @@ static void xmon_rawdump (unsigned long adrs, long ndump) #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ || ('a' <= (c) && (c) <= 'f') \ || ('A' <= (c) && (c) <= 'F')) -void +static void dump(void) { int c; @@ -2022,7 +2022,7 @@ dump(void) } } -void +static void prdump(unsigned long adrs, long ndump) { long n, m, c, r, nr; @@ -2066,7 +2066,7 @@ prdump(unsigned long adrs, long ndump) typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr); -int +static int generic_inst_dump(unsigned long adr, long count, int praddr, instruction_dump_func dump_func) { @@ -2104,7 +2104,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr, return adr - first_adr; } -int +static int ppc_inst_dump(unsigned long adr, long count, int praddr) { return generic_inst_dump(adr, count, praddr, print_insn_powerpc); @@ -2126,7 +2126,7 @@ static unsigned long mval; /* byte value to set memory to */ static unsigned long mcount; /* # bytes to affect */ static unsigned long mdiffs; /* max # differences to print */ -void +static void memops(int cmd) { scanhex((void *)&mdest); @@ -2152,7 +2152,7 @@ memops(int cmd) } } -void +static void memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) { unsigned n, prt; @@ -2170,7 +2170,7 @@ memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) static unsigned mend; static unsigned mask; -void +static void memlocate(void) { unsigned a, n; @@ -2203,7 +2203,7 @@ memlocate(void) static unsigned long mskip = 0x1000; static unsigned long mlim = 0xffffffff; -void +static void memzcan(void) { unsigned char v; @@ -2230,7 +2230,7 @@ memzcan(void) printf("%.8x\n", a - mskip); } -void proccall(void) +static void proccall(void) { unsigned long args[8]; unsigned long ret; @@ -2388,7 +2388,7 @@ scanhex(unsigned long *vp) return 1; } -void +static void scannl(void) { int c; @@ -2399,7 +2399,7 @@ scannl(void) c = inchar(); } -int hexdigit(int c) +static int hexdigit(int c) { if( '0' <= c && c <= '9' ) return c - '0'; @@ -2430,13 +2430,13 @@ getstring(char *s, int size) static char line[256]; static char *lineptr; -void +static void flush_input(void) { lineptr = NULL; } -int +static int inchar(void) { if (lineptr == NULL || *lineptr == 0) { @@ -2449,7 +2449,7 @@ inchar(void) return *lineptr++; } -void +static void take_input(char *str) { lineptr = str; @@ -2618,7 +2618,8 @@ static void dump_tlb_44x(void) } } #endif /* CONFIG_44x */ -void xmon_init(int enable) + +static void xmon_init(int enable) { #ifdef CONFIG_PPC_ISERIES if (firmware_has_feature(FW_FEATURE_ISERIES)) -- cgit v0.10.2 From 1c8950ff87de950a3b6ccfb26650fc0a56278836 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:17 +1000 Subject: [POWERPC] Make cpus_in_xmon static and remove extern mess from hvc_console.c This is a little messier than I'd like because xmon.h only exists on powerpc and we can't have a static inline and an extern declaration visible at the same time. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 95f24c9..6726da0 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -54,7 +54,7 @@ #define skipbl xmon_skipbl #ifdef CONFIG_SMP -cpumask_t cpus_in_xmon = CPU_MASK_NONE; +static cpumask_t cpus_in_xmon = CPU_MASK_NONE; static unsigned long xmon_taken = 1; static int xmon_owner; static int xmon_gate; @@ -327,6 +327,11 @@ static void release_output_lock(void) { xmon_speaker = 0; } + +int cpus_are_in_xmon(void) +{ + return !cpus_empty(cpus_in_xmon); +} #endif static int xmon_core(struct pt_regs *regs, int fromipi) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 44160d5..2f9759d 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -675,12 +675,6 @@ static int hvc_poll(struct hvc_struct *hp) return poll_mask; } -#if defined(CONFIG_XMON) && defined(CONFIG_SMP) -extern cpumask_t cpus_in_xmon; -#else -static const cpumask_t cpus_in_xmon = CPU_MASK_NONE; -#endif - /* * This kthread is either polling or interrupt driven. This is determined by * calling hvc_poll() who determines whether a console adapter support @@ -698,7 +692,7 @@ static int khvcd(void *unused) hvc_kicked = 0; try_to_freeze(); wmb(); - if (cpus_empty(cpus_in_xmon)) { + if (!cpus_are_in_xmon()) { spin_lock(&hvc_structs_lock); list_for_each_entry(hp, &hvc_structs, next) { poll_mask |= hvc_poll(hp); diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index 8c59818..42ffb17 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h @@ -60,4 +60,14 @@ extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ extern int __devexit hvc_remove(struct hvc_struct *hp); + +#if defined(CONFIG_XMON) && defined(CONFIG_SMP) +#include +#else +static inline int cpus_are_in_xmon(void) +{ + return 0; +} +#endif + #endif // HVC_CONSOLE_H diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index d83da3c..5eb8e59 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h @@ -25,5 +25,9 @@ static inline void xmon_setup(void) { }; static inline void xmon_register_spus(struct list_head *list) { }; #endif +#if defined(CONFIG_XMON) && defined(CONFIG_SMP) +extern int cpus_are_in_xmon(void); +#endif + #endif /* __KERNEL __ */ #endif /* __ASM_POWERPC_XMON_H */ -- cgit v0.10.2 From 1c21a2937b1f342a8f5d580203c3396557d53b6e Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:19 +1000 Subject: [POWERPC] Fix sparse warnings in arch/powerpc/kernel Make a few things static in lparcfg.c Make init and exit routines static in rtas_flash.c Make things static in rtas_pci.c Make some functions static in rtas.c Make fops static in rtas-proc.c Remove unneeded extern for do_gtod in smp.c Make clocksource_init() static in time.c Make last_tick_len and ticklen_to_xs static in time.c Move the declaration of the pvr per-cpu into smp.h Make kexec_smp_down() and kexec_stack static in machine_kexec_64.c Don't return void in arch_teardown_msi_irqs() in msi.c Move declaration of GregorianDay()into asm/time.h Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 1e656b4..827a572 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -573,7 +573,7 @@ static int lparcfg_open(struct inode *inode, struct file *file) return single_open(file, lparcfg_data, NULL); } -const struct file_operations lparcfg_fops = { +static const struct file_operations lparcfg_fops = { .owner = THIS_MODULE, .read = seq_read, .write = lparcfg_write, @@ -581,7 +581,7 @@ const struct file_operations lparcfg_fops = { .release = single_release, }; -int __init lparcfg_init(void) +static int __init lparcfg_init(void) { struct proc_dir_entry *ent; mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; @@ -601,7 +601,7 @@ int __init lparcfg_init(void) return 0; } -void __exit lparcfg_cleanup(void) +static void __exit lparcfg_cleanup(void) { if (proc_ppc64_lparcfg) remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 704375b..631dfd6 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -158,7 +158,7 @@ void kexec_copy_flush(struct kimage *image) * on calling the interrupts, but we would like to call it off irq level * so that the interrupt controller is clean. */ -void kexec_smp_down(void *arg) +static void kexec_smp_down(void *arg) { if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 1); @@ -249,7 +249,7 @@ static void kexec_prepare_cpus(void) * We could use a smaller stack if we don't care about anything using * current, but that audit has not been performed. */ -union thread_union kexec_stack +static union thread_union kexec_stack __attribute__((__section__(".data.init_task"))) = { }; /* Our assembly helper, in kexec_stub.S */ diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c index c62d101..3bb7d3d 100644 --- a/arch/powerpc/kernel/msi.c +++ b/arch/powerpc/kernel/msi.c @@ -34,5 +34,5 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) void arch_teardown_msi_irqs(struct pci_dev *dev) { - return ppc_md.teardown_msi_irqs(dev); + ppc_md.teardown_msi_irqs(dev); } diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index f9c6abc..1be9fe3 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -160,7 +160,7 @@ static int sensors_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_sensors_show, NULL); } -const struct file_operations ppc_rtas_sensors_operations = { +static const struct file_operations ppc_rtas_sensors_operations = { .open = sensors_open, .read = seq_read, .llseek = seq_lseek, @@ -172,7 +172,7 @@ static int poweron_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_poweron_show, NULL); } -const struct file_operations ppc_rtas_poweron_operations = { +static const struct file_operations ppc_rtas_poweron_operations = { .open = poweron_open, .read = seq_read, .llseek = seq_lseek, @@ -185,7 +185,7 @@ static int progress_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_progress_show, NULL); } -const struct file_operations ppc_rtas_progress_operations = { +static const struct file_operations ppc_rtas_progress_operations = { .open = progress_open, .read = seq_read, .llseek = seq_lseek, @@ -198,7 +198,7 @@ static int clock_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_clock_show, NULL); } -const struct file_operations ppc_rtas_clock_operations = { +static const struct file_operations ppc_rtas_clock_operations = { .open = clock_open, .read = seq_read, .llseek = seq_lseek, @@ -211,7 +211,7 @@ static int tone_freq_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_tone_freq_show, NULL); } -const struct file_operations ppc_rtas_tone_freq_operations = { +static const struct file_operations ppc_rtas_tone_freq_operations = { .open = tone_freq_open, .read = seq_read, .llseek = seq_lseek, @@ -224,7 +224,7 @@ static int tone_volume_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_tone_volume_show, NULL); } -const struct file_operations ppc_rtas_tone_volume_operations = { +static const struct file_operations ppc_rtas_tone_volume_operations = { .open = tone_volume_open, .read = seq_read, .llseek = seq_lseek, @@ -237,7 +237,7 @@ static int rmo_buf_open(struct inode *inode, struct file *file) return single_open(file, ppc_rtas_rmo_buf_show, NULL); } -const struct file_operations ppc_rtas_rmo_buf_ops = { +static const struct file_operations ppc_rtas_rmo_buf_ops = { .open = rmo_buf_open, .read = seq_read, .llseek = seq_lseek, diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 34843c3..2a60bd3 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -340,8 +340,8 @@ int rtas_get_error_log_max(void) EXPORT_SYMBOL(rtas_get_error_log_max); -char rtas_err_buf[RTAS_ERROR_LOG_MAX]; -int rtas_last_error_token; +static char rtas_err_buf[RTAS_ERROR_LOG_MAX]; +static int rtas_last_error_token; /** Return a copy of the detailed error text associated with the * most recent failed call to rtas. Because the error text @@ -484,7 +484,7 @@ unsigned int rtas_busy_delay(int status) } EXPORT_SYMBOL(rtas_busy_delay); -int rtas_error_rc(int rtas_rc) +static int rtas_error_rc(int rtas_rc) { int rc; diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 0a5e22b..09ded5c 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -731,7 +731,7 @@ static const struct file_operations validate_flash_operations = { .release = validate_flash_release, }; -int __init rtas_flash_init(void) +static int __init rtas_flash_init(void) { int rc; @@ -817,7 +817,7 @@ cleanup: return rc; } -void __exit rtas_flash_cleanup(void) +static void __exit rtas_flash_cleanup(void) { rtas_flash_term_hook = NULL; diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 3ab88a9..589a279 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -155,12 +155,12 @@ static int rtas_pci_write_config(struct pci_bus *bus, return PCIBIOS_DEVICE_NOT_FOUND; } -struct pci_ops rtas_pci_ops = { +static struct pci_ops rtas_pci_ops = { .read = rtas_pci_read_config, .write = rtas_pci_write_config, }; -int is_python(struct device_node *dev) +static int is_python(struct device_node *dev) { const char *model = of_get_property(dev, "model", NULL); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 1457aa0..ba7989f 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -365,12 +365,8 @@ void smp_call_function_interrupt(void) } } -extern struct gettimeofday_struct do_gtod; - struct thread_info *current_set[NR_CPUS]; -DECLARE_PER_CPU(unsigned int, pvr); - static void __devinit smp_store_cpu_info(int id) { per_cpu(pvr, id) = mfspr(SPRN_PVR); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 73401e8..c73fc33 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -129,7 +129,7 @@ static unsigned long __initdata iSeries_recal_titan; static signed long __initdata iSeries_recal_tb; /* Forward declaration is only needed for iSereis compiles */ -void __init clocksource_init(void); +static void __init clocksource_init(void); #endif #define XSEC_PER_SEC (1024*1024) @@ -150,8 +150,8 @@ u64 tb_to_xs; unsigned tb_to_us; #define TICKLEN_SCALE NTP_SCALE_SHIFT -u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ -u64 ticklen_to_xs; /* 0.64 fraction */ +static u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ +static u64 ticklen_to_xs; /* 0.64 fraction */ /* If last_tick_len corresponds to about 1/HZ seconds, then last_tick_len << TICKLEN_SHIFT will be about 2^63. */ @@ -164,7 +164,7 @@ static u64 tb_to_ns_scale __read_mostly; static unsigned tb_to_ns_shift __read_mostly; static unsigned long boot_tb __read_mostly; -struct gettimeofday_struct do_gtod; +static struct gettimeofday_struct do_gtod; extern struct timezone sys_tz; static long timezone_offset; @@ -832,7 +832,7 @@ void update_vsyscall_tz(void) ++vdso_data->tb_update_count; } -void __init clocksource_init(void) +static void __init clocksource_init(void) { struct clocksource *clock; diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c index 9f7579b..53bca13 100644 --- a/arch/powerpc/platforms/maple/time.c +++ b/arch/powerpc/platforms/maple/time.c @@ -41,8 +41,6 @@ #define DBG(x...) #endif -extern void GregorianDay(struct rtc_time * tm); - static int maple_rtc_addr; static int maple_clock_read(int addr) diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h index 505f35b..1cd43e3 100644 --- a/include/asm-powerpc/smp.h +++ b/include/asm-powerpc/smp.h @@ -37,6 +37,8 @@ extern void cpu_die(void); extern void smp_send_debugger_break(int cpu); extern void smp_message_recv(int); +DECLARE_PER_CPU(unsigned int, pvr); + #ifdef CONFIG_HOTPLUG_CPU extern void fixup_irqs(cpumask_t map); int generic_cpu_disable(void); diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index ce5de6e..febd581 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h @@ -33,6 +33,7 @@ extern unsigned tb_to_us; struct rtc_time; extern void to_tm(int tim, struct rtc_time * tm); +extern void GregorianDay(struct rtc_time *tm); extern time_t last_rtc_update; extern void generic_calibrate_decr(void); -- cgit v0.10.2 From 3ff1999b2c84e1486e80fbd3ca12b1663dc3408b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:21 +1000 Subject: [POWERPC] pseries/firmware.c should include pseries/pseries.h The declaration for fw_feature_init() is in pseries.h and implemented in firmware.c, so the latter should include the former. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index 9d3a40f..5a707da 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -26,6 +26,7 @@ #include #include +#include "pseries.h" typedef struct { unsigned long val; -- cgit v0.10.2 From 541b2755c2ef7dd2242ac606c115daa11e43ef69 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:23 +1000 Subject: [POWERPC] Fix sparse warnings in arch/powerpc/platforms/pseries Don't return void in pseries/iommu.c Make mce_data_buf static in pseries/ras.c Make things static in pseries/rtasd.c Make things static in pseries/setup.c vtermno may as well be static in platforms/pseries/lpar.c Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 176f1f39d..9a12908 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -135,9 +135,10 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, u64 rpn; long l, limit; - if (npages == 1) - return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, - direction); + if (npages == 1) { + tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction); + return; + } tcep = __get_cpu_var(tce_page); @@ -147,9 +148,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, if (!tcep) { tcep = (u64 *)__get_free_page(GFP_ATOMIC); /* If allocation fails, fall back to the loop implementation */ - if (!tcep) - return tce_build_pSeriesLP(tbl, tcenum, npages, - uaddr, direction); + if (!tcep) { + tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, + direction); + return; + } __get_cpu_var(tce_page) = tcep; } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 2cbaedb..3b4651b 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -52,7 +52,7 @@ EXPORT_SYMBOL(plpar_hcall_norets); extern void pSeries_find_serial_port(void); -int vtermno; /* virtual terminal# for udbg */ +static int vtermno; /* virtual terminal# for udbg */ #define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) static void udbg_hvsi_putc(char c) diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 2b548af..d20b96e 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -55,7 +55,7 @@ static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; static DEFINE_SPINLOCK(ras_log_buf_lock); -char mce_data_buf[RTAS_ERROR_LOG_MAX]; +static char mce_data_buf[RTAS_ERROR_LOG_MAX]; static int ras_get_sensor_state_token; static int ras_check_exception_token; diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index 7d3e2b0..c9ffd8c 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c @@ -32,7 +32,7 @@ static DEFINE_SPINLOCK(rtasd_log_lock); -DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait); +static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait); static char *rtas_log_buf; static unsigned long rtas_log_start; @@ -329,7 +329,7 @@ static unsigned int rtas_log_poll(struct file *file, poll_table * wait) return 0; } -const struct file_operations proc_rtas_log_operations = { +static const struct file_operations proc_rtas_log_operations = { .read = rtas_log_read, .poll = rtas_log_poll, .open = rtas_log_open, diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index f5d29f5..90beb44 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -109,7 +109,7 @@ static void __init fwnmi_init(void) fwnmi_active = 1; } -void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc) +static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc) { unsigned int cascade_irq = i8259_irq(); if (cascade_irq != NO_IRQ) @@ -482,7 +482,7 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) * possible with power button press. If ibm,power-off-ups token is used * it will allow auto poweron after power is restored. */ -void pSeries_power_off(void) +static void pSeries_power_off(void) { int rc; int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups"); -- cgit v0.10.2 From a560643e21e1ac10f7398b45111aecdd7f47a4a5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 14 May 2008 14:30:48 +1000 Subject: [POWERPC] Defer processing of interrupts when the CPU wakes from sleep mode This provides a way to defer processing of an interrupt that wakes the processor out of sleep mode. On 32-bit platforms that use an interrupt to wake the processor, we have to have interrupts enabled in hardware at the point where we go to sleep, otherwise the processor will never wake up. However, because interrupts are logically disabled at this point, we don't want to process the interrupt straight away. This is handled by setting the _TLF_SLEEPING flag. When we get an interrupt and _TLF_SLEEPING is set, we firstly clear the MSR_EE (external interrupt enable) bit in the saved MSR value, and secondly we then return to the address in the link register, like we do for _TLF_NAPPING, but without actually handling the interrupt. Note that this is handled somewhat differently on powerbooks, so this new code will only be used on non-Apple machines. Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 3a05e9f..888a364 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -147,6 +147,7 @@ transfer_to_handler: lwz r12,TI_LOCAL_FLAGS(r9) mtcrf 0x01,r12 bt- 31-TLF_NAPPING,4f + bt- 31-TLF_SLEEPING,7f #endif /* CONFIG_6xx */ .globl transfer_to_handler_cont transfer_to_handler_cont: @@ -164,6 +165,13 @@ transfer_to_handler_cont: 4: rlwinm r12,r12,0,~_TLF_NAPPING stw r12,TI_LOCAL_FLAGS(r9) b power_save_6xx_restore + +7: rlwinm r12,r12,0,~_TLF_SLEEPING + stw r12,TI_LOCAL_FLAGS(r9) + lwz r9,_MSR(r11) /* if sleeping, clear MSR.EE */ + rlwinm r9,r9,0,~MSR_EE + lwz r12,_LINK(r11) /* and return to address in LR */ + b fast_exception_return #endif /* diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index e079e81..b705c2a 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -144,9 +144,11 @@ static inline struct thread_info *current_thread_info(void) /* Bits in local_flags */ /* Don't move TLF_NAPPING without adjusting the code in entry_32.S */ #define TLF_NAPPING 0 /* idle thread enabled NAP mode */ -#define TLF_RESTORE_SIGMASK 1 /* Restore signal mask in do_signal */ +#define TLF_SLEEPING 1 /* suspend code enabled SLEEP mode */ +#define TLF_RESTORE_SIGMASK 2 /* Restore signal mask in do_signal */ #define _TLF_NAPPING (1 << TLF_NAPPING) +#define _TLF_SLEEPING (1 << TLF_SLEEPING) #define _TLF_RESTORE_SIGMASK (1 << TLF_RESTORE_SIGMASK) #ifndef __ASSEMBLY__ -- cgit v0.10.2 From 0b2cca804ee40495bc92449c3e22f3c3a3f2977a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 29 Apr 2008 01:38:13 +1000 Subject: [POWERPC] Add 6xx-style HID0_SLEEP support. This adds a function to put a 6xx/7xx/7xxx/83xx family CPU into sleep mode, and return after an interrupt has occurred. It expects to be called with interrupts disabled, and returns with interrupts disabled. Interrupts are enabled while the processor is asleep, but the interrupt that wakes the processor is not handled; it is still pending when this function returns. Signed-off-by: Scott Wood Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/sysdev/6xx-suspend.S b/arch/powerpc/sysdev/6xx-suspend.S new file mode 100644 index 0000000..21cda08 --- /dev/null +++ b/arch/powerpc/sysdev/6xx-suspend.S @@ -0,0 +1,52 @@ +/* + * Enter and leave sleep state on chips with 6xx-style HID0 + * power management bits, which don't leave sleep state via reset. + * + * Author: Scott Wood + * + * Copyright (c) 2006-2007 Freescale Semiconductor, 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. + */ + +#include +#include +#include +#include + +_GLOBAL(mpc6xx_enter_standby) + mflr r4 + + mfspr r5, SPRN_HID0 + rlwinm r5, r5, 0, ~(HID0_DOZE | HID0_NAP) + oris r5, r5, HID0_SLEEP@h + mtspr SPRN_HID0, r5 + isync + + lis r5, ret_from_standby@h + ori r5, r5, ret_from_standby@l + mtlr r5 + + rlwinm r5, r1, 0, 0, 31-THREAD_SHIFT + lwz r6, TI_LOCAL_FLAGS(r5) + ori r6, r6, _TLF_SLEEPING + stw r6, TI_LOCAL_FLAGS(r5) + + mfmsr r5 + ori r5, r5, MSR_EE + oris r5, r5, MSR_POW@h + sync + mtmsr r5 + isync + +1: b 1b + +ret_from_standby: + mfspr r5, SPRN_HID0 + rlwinm r5, r5, 0, ~HID0_SLEEP + mtspr SPRN_HID0, r5 + + mtlr r4 + blr diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 6d386d0..2cc5052 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -44,3 +44,7 @@ obj-$(CONFIG_PPC_DCR) += dcr.o obj-$(CONFIG_8xx) += mpc8xx_pic.o cpm1.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o endif + +ifeq ($(CONFIG_SUSPEND),y) +obj-$(CONFIG_6xx) += 6xx-suspend.o +endif diff --git a/include/asm-powerpc/mpc6xx.h b/include/asm-powerpc/mpc6xx.h new file mode 100644 index 0000000..effc229 --- /dev/null +++ b/include/asm-powerpc/mpc6xx.h @@ -0,0 +1,6 @@ +#ifndef __ASM_POWERPC_MPC6xx_H +#define __ASM_POWERPC_MPC6xx_H + +void mpc6xx_enter_standby(void); + +#endif -- cgit v0.10.2 From 7bc228b1ef71f395aeb89bdf81bf95556b08b374 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 15 May 2008 05:16:44 +1000 Subject: [POWERPC] Get most of ioctl.h content from Now that allows overriding of the most commonly changed macros, take advantage of that. Signed-off-by: Robert P. J. Day Signed-off-by: Paul Mackerras diff --git a/include/asm-powerpc/ioctl.h b/include/asm-powerpc/ioctl.h index 8eb9984..57d6830 100644 --- a/include/asm-powerpc/ioctl.h +++ b/include/asm-powerpc/ioctl.h @@ -1,69 +1,13 @@ #ifndef _ASM_POWERPC_IOCTL_H #define _ASM_POWERPC_IOCTL_H - -/* - * this was copied from the alpha as it's a bit cleaner there. - * -- Cort - */ - -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 #define _IOC_SIZEBITS 13 #define _IOC_DIRBITS 3 -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) - -/* - * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. - * And this turns out useful to catch old ioctl numbers in header - * files for us. - */ #define _IOC_NONE 1U #define _IOC_READ 2U #define _IOC_WRITE 4U -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -/* provoke compile error for invalid uses of size argument */ -extern unsigned int __invalid_size_argument_for_IOC; -#define _IOC_TYPECHECK(t) \ - ((sizeof(t) == sizeof(t[1]) && \ - sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ - sizeof(t) : __invalid_size_argument_for_IOC) - -/* used to create numbers */ -#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) - -/* used to decode them.. */ -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -/* various drivers, such as the pcmcia stuff, need these... */ -#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) -#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) -#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) -#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) -#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) +#include #endif /* _ASM_POWERPC_IOCTL_H */ -- cgit v0.10.2 From 09e67ca2c523544e6b38aa570a5f62a0cf20b87b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 16 May 2008 11:57:45 +1000 Subject: [POWERPC] Move of_device_get_modalias to drivers/of Commit 140b932f8cb6cced10b96860651a198b1b89cbb9 ("Create modalias file in sysfs for of_platform bus") needs this to avoid breaking the sparc builds. Just move the code and add whitespace around some binary operators. Signed-off-by: Stephen Rothwell Acked-by: David S. Miller Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 5748ddb..e9be908 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -89,54 +89,6 @@ struct of_device *of_device_alloc(struct device_node *np, } EXPORT_SYMBOL(of_device_alloc); -ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len) -{ - const char *compat; - int cplen, i; - ssize_t tsize, csize, repend; - - /* Name & Type */ - csize = snprintf(str, len, "of:N%sT%s", - ofdev->node->name, ofdev->node->type); - - /* Get compatible property if any */ - compat = of_get_property(ofdev->node, "compatible", &cplen); - if (!compat) - return csize; - - /* Find true end (we tolerate multiple \0 at the end */ - for (i=(cplen-1); i>=0 && !compat[i]; i--) - cplen--; - if (!cplen) - return csize; - cplen++; - - /* Check space (need cplen+1 chars including final \0) */ - tsize = csize + cplen; - repend = tsize; - - if (csize>=len) /* @ the limit, all is already filled */ - return tsize; - - if (tsize>=len) { /* limit compat list */ - cplen = len-csize-1; - repend = len; - } - - /* Copy and do char replacement */ - memcpy(&str[csize+1], compat, cplen); - for (i=csize; idev); } EXPORT_SYMBOL(of_device_unregister); + +ssize_t of_device_get_modalias(struct of_device *ofdev, + char *str, ssize_t len) +{ + const char *compat; + int cplen, i; + ssize_t tsize, csize, repend; + + /* Name & Type */ + csize = snprintf(str, len, "of:N%sT%s", + ofdev->node->name, ofdev->node->type); + + /* Get compatible property if any */ + compat = of_get_property(ofdev->node, "compatible", &cplen); + if (!compat) + return csize; + + /* Find true end (we tolerate multiple \0 at the end */ + for (i = (cplen - 1); i >= 0 && !compat[i]; i--) + cplen--; + if (!cplen) + return csize; + cplen++; + + /* Check space (need cplen+1 chars including final \0) */ + tsize = csize + cplen; + repend = tsize; + + if (csize >= len) /* @ the limit, all is already filled */ + return tsize; + + if (tsize >= len) { /* limit compat list */ + cplen = len - csize - 1; + repend = len; + } + + /* Copy and do char replacement */ + memcpy(&str[csize + 1], compat, cplen); + for (i = csize; i < repend; i++) { + char c = str[i]; + if (c == '\0') + str[i] = 'C'; + else if (c == ' ') + str[i] = '_'; + } + + return tsize; +} diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h index 6526e13..3c12399 100644 --- a/include/asm-powerpc/of_device.h +++ b/include/asm-powerpc/of_device.h @@ -21,8 +21,6 @@ extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -extern ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len); extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); diff --git a/include/linux/of_device.h b/include/linux/of_device.h index afe3382..d3a74e0 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -24,4 +24,7 @@ static inline void of_device_free(struct of_device *dev) of_release_dev(&dev->dev); } +extern ssize_t of_device_get_modalias(struct of_device *ofdev, + char *str, ssize_t len); + #endif /* _LINUX_OF_DEVICE_H */ -- cgit v0.10.2 From 493d35863dbb692c38c1415fd83d88dfb902ae37 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 14 May 2008 16:22:58 -0700 Subject: mutex-debug: check mutex magic before owner Currently, the mutex debug code checks the lock->owner before lock->magic, so a corrupt mutex will most likely result in failing the owner check, rather than the magic check. This change to debug_mutex_unlock does the magic check first, so we have a better idea of what breaks. Signed-off-by: Jeremy Kerr Acked-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c index 3aaa06c..1d94160 100644 --- a/kernel/mutex-debug.c +++ b/kernel/mutex-debug.c @@ -79,8 +79,8 @@ void debug_mutex_unlock(struct mutex *lock) if (unlikely(!debug_locks)) return; - DEBUG_LOCKS_WARN_ON(lock->owner != current_thread_info()); DEBUG_LOCKS_WARN_ON(lock->magic != lock); + DEBUG_LOCKS_WARN_ON(lock->owner != current_thread_info()); DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); DEBUG_LOCKS_WARN_ON(lock->owner != current_thread_info()); } -- cgit v0.10.2 From 75bd2ef1457998791cfc89cd59927574488fc22a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:09:23 -0600 Subject: bsg: cdev lock_kernel() pushdown Push the cdev lock_kernel call into bsg_open(). Signed-off-by: Jonathan Corbet diff --git a/block/bsg.c b/block/bsg.c index f0b7cd3..dbe3ffd 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -834,7 +835,11 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) static int bsg_open(struct inode *inode, struct file *file) { - struct bsg_device *bd = bsg_get_device(inode, file); + struct bsg_device *bd; + + lock_kernel(); + bd = bsg_get_device(inode, file); + unlock_kernel(); if (IS_ERR(bd)) return PTR_ERR(bd); -- cgit v0.10.2 From 0c401df37ef9f45f35390a5574e24cbf3f916acf Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:10:18 -0600 Subject: cris: cdev lock_kernel() pushdown Push the cdev lock_kernel() call into cris drivers. Signed-off-by: Jonathan Corbet diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index 68a998b..86048e6 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -323,6 +324,7 @@ gpio_open(struct inode *inode, struct file *filp) if (!priv) return -ENOMEM; + lock_kernel(); priv->minor = p; /* initialize the io/alarm struct */ @@ -357,6 +359,7 @@ gpio_open(struct inode *inode, struct file *filp) alarmlist = priv; spin_unlock_irqrestore(&gpio_lock, flags); + unlock_kernel(); return 0; } diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 069546e..91fea62 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -443,18 +444,21 @@ static int sync_serial_open(struct inode *inode, struct file *file) int dev = MINOR(inode->i_rdev); struct sync_port *port; int mode; + int err = -EBUSY; + lock_kernel(); DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); - return -ENODEV; + err = -ENODEV; + goto out; } port = &ports[dev]; /* Allow open this device twice (assuming one reader and one writer) */ if (port->busy == 2) { DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); - return -EBUSY; + goto out; } if (port->init_irqs) { if (port->use_dma) { @@ -465,14 +469,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[0])) { printk(KERN_CRIT "Can't alloc " "sync serial port 1 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(25, rx_interrupt, 0, "synchronous serial 1 dma rx", &ports[0])) { free_irq(24, &port[0]); printk(KERN_CRIT "Can't alloc " "sync serial port 1 IRQ"); - return -EBUSY; + goto out; } else if (cris_request_dma(8, "synchronous serial 1 dma tr", DMA_VERBOSE_ON_ERROR, @@ -482,7 +486,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 1 " "TX DMA channel"); - return -EBUSY; + goto out; } else if (cris_request_dma(9, "synchronous serial 1 dma rec", DMA_VERBOSE_ON_ERROR, @@ -493,7 +497,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 1 " "RX DMA channel"); - return -EBUSY; + goto out; } #endif RESET_DMA(8); WAIT_DMA(8); @@ -520,14 +524,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[1])) { printk(KERN_CRIT "Can't alloc " "sync serial port 3 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", &ports[1])) { free_irq(20, &ports[1]); printk(KERN_CRIT "Can't alloc " "sync serial port 3 IRQ"); - return -EBUSY; + goto out; } else if (cris_request_dma(4, "synchronous serial 3 dma tr", DMA_VERBOSE_ON_ERROR, @@ -537,7 +541,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 3 " "TX DMA channel"); - return -EBUSY; + goto out; } else if (cris_request_dma(5, "synchronous serial 3 dma rec", DMA_VERBOSE_ON_ERROR, @@ -548,7 +552,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 3 " "RX DMA channel"); - return -EBUSY; + goto out; } #endif RESET_DMA(4); WAIT_DMA(4); @@ -581,7 +585,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[0])) { printk(KERN_CRIT "Can't alloc " "sync serial manual irq"); - return -EBUSY; + goto out; } } else if (port == &ports[1]) { if (request_irq(8, @@ -591,7 +595,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[1])) { printk(KERN_CRIT "Can't alloc " "sync serial manual irq"); - return -EBUSY; + goto out; } } port->init_irqs = 0; @@ -620,7 +624,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); } - return 0; + ret = 0; + +out: + unlock_kernel(); + return ret; } static int sync_serial_release(struct inode *inode, struct file *file) diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c index de107da..ef98608 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/gpio.c +++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -390,6 +391,8 @@ static int gpio_open(struct inode *inode, struct file *filp) if (!priv) return -ENOMEM; + + lock_kernel(); memset(priv, 0, sizeof(*priv)); priv->minor = p; @@ -412,6 +415,7 @@ static int gpio_open(struct inode *inode, struct file *filp) spin_unlock_irq(&gpio_lock); } + unlock_kernel(); return 0; } diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c index 7863fd4..fe1fde8 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c +++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -426,9 +427,10 @@ gpio_open(struct inode *inode, struct file *filp) return -EINVAL; priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL); - if (!priv) return -ENOMEM; + + lock_kernel(); memset(priv, 0, sizeof(*priv)); priv->minor = p; @@ -449,6 +451,7 @@ gpio_open(struct inode *inode, struct file *filp) alarmlist = priv; spin_unlock_irq(&alarm_lock); + unlock_kernel(); return 0; } diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index 47c377d..d2a0fbf 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -429,23 +430,26 @@ static inline int sync_data_avail_to_end(struct sync_port *port) static int sync_serial_open(struct inode *inode, struct file *file) { int dev = iminor(inode); + int ret = -EBUSY; sync_port *port; reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes}; + lock_kernel(); DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) { DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); - return -ENODEV; + ret = -ENODEV; + goto out; } port = &ports[dev]; /* Allow open this device twice (assuming one reader and one writer) */ if (port->busy == 2) { DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); - return -EBUSY; + goto out; } @@ -459,7 +463,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial 0 dma tr", &ports[0])) { printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(DMA_IN_INTR_VECT, rx_interrupt, 0, @@ -467,7 +471,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[0])) { free_irq(DMA_OUT_INTR_VECT, &port[0]); printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); - return -EBUSY; + goto out; } else if (crisv32_request_dma(OUT_DMA_NBR, "synchronous serial 0 dma tr", DMA_VERBOSE_ON_ERROR, @@ -476,7 +480,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA_OUT_INTR_VECT, &port[0]); free_irq(DMA_IN_INTR_VECT, &port[0]); printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel"); - return -EBUSY; + goto out; } else if (crisv32_request_dma(IN_DMA_NBR, "synchronous serial 0 dma rec", DMA_VERBOSE_ON_ERROR, @@ -486,7 +490,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA_OUT_INTR_VECT, &port[0]); free_irq(DMA_IN_INTR_VECT, &port[0]); printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel"); - return -EBUSY; + goto out; } #endif } @@ -499,7 +503,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial 1 dma tr", &ports[1])) { printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(DMA7_INTR_VECT, rx_interrupt, 0, @@ -507,7 +511,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[1])) { free_irq(DMA6_INTR_VECT, &ports[1]); printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ"); - return -EBUSY; + goto out; } else if (crisv32_request_dma( SYNC_SER1_TX_DMA_NBR, "synchronous serial 1 dma tr", @@ -517,7 +521,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA6_INTR_VECT, &ports[1]); free_irq(DMA7_INTR_VECT, &ports[1]); printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel"); - return -EBUSY; + goto out; } else if (crisv32_request_dma( SYNC_SER1_RX_DMA_NBR, "synchronous serial 3 dma rec", @@ -528,7 +532,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA6_INTR_VECT, &ports[1]); free_irq(DMA7_INTR_VECT, &ports[1]); printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel"); - return -EBUSY; + goto out; } #endif } @@ -554,7 +558,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial manual irq", &ports[0])) { printk("Can't allocate sync serial manual irq"); - return -EBUSY; + goto out; } } #ifdef CONFIG_ETRAXFS @@ -565,7 +569,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial manual irq", &ports[1])) { printk(KERN_CRIT "Can't allocate sync serial manual irq"); - return -EBUSY; + goto out; } } #endif @@ -578,7 +582,10 @@ static int sync_serial_open(struct inode *inode, struct file *file) } /* port->init_irqs */ port->busy++; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int sync_serial_release(struct inode *inode, struct file *file) -- cgit v0.10.2 From 7558da942e51933b5e6aa5e851d4da1df0cd6752 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:10:50 -0600 Subject: mips: cdev lock_kernel() pushdown Push the cdev lock_kernel() call into MIPS-specific drivers. Signed-off-by: Jonathan Corbet diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index b88f1c1..b556419 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -392,8 +393,12 @@ out: static int file_open(struct inode *inode, struct file *filp) { int minor = iminor(inode); + int err; - return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); + lock_kernel(); + err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); + unlock_kernel(); + return err; } static int file_release(struct inode *inode, struct file *filp) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 2794501..972b2d2 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1050,17 +1051,20 @@ static int vpe_open(struct inode *inode, struct file *filp) enum vpe_state state; struct vpe_notifications *not; struct vpe *v; - int ret; + int ret, err = 0; + lock_kernel(); if (minor != iminor(inode)) { /* assume only 1 device at the moment. */ printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); - return -ENODEV; + err = -ENODEV; + goto out; } if ((v = get_vpe(tclimit)) == NULL) { printk(KERN_WARNING "VPE loader: unable to get vpe\n"); - return -ENODEV; + err = -ENODEV; + goto out; } state = xchg(&v->state, VPE_STATE_INUSE); @@ -1100,6 +1104,8 @@ static int vpe_open(struct inode *inode, struct file *filp) v->shared_ptr = NULL; v->__start = 0; +out: + unlock_kernel(); return 0; } diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c index 63b444e..28b012a 100644 --- a/arch/mips/sibyte/common/sb_tbprof.c +++ b/arch/mips/sibyte/common/sb_tbprof.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -402,18 +403,26 @@ static int sbprof_zbprof_stop(void) static int sbprof_tb_open(struct inode *inode, struct file *filp) { int minor; + int err = 0; + lock_kernel(); minor = iminor(inode); - if (minor != 0) - return -ENODEV; + if (minor != 0) { + err = -ENODEV; + goto out; + } - if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) - return -EBUSY; + if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) { + err = -EBUSY; + goto out; + } memset(&sbp, 0, sizeof(struct sbprof_tb)); sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); - if (!sbp.sbprof_tbbuf) - return -ENOMEM; + if (!sbp.sbprof_tbbuf) { + err = -ENOMEM; + goto out; + } memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); init_waitqueue_head(&sbp.tb_sync); init_waitqueue_head(&sbp.tb_read); @@ -421,7 +430,9 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp) sbp.open = SB_OPEN; - return 0; + out: + unlock_kernel(); + return err; } static int sbprof_tb_release(struct inode *inode, struct file *filp) -- cgit v0.10.2 From 1fa984b583a809423ddb1d88fa46484071f85f80 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:11:26 -0600 Subject: sh: cdev lock_kernel() pushdown Push the cdev lock_kernel() call down into the sh gio driver. Signed-off-by: Jonathan Corbet diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c index 1702508..0c15b0a 100644 --- a/arch/sh/boards/landisk/gio.c +++ b/arch/sh/boards/landisk/gio.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include #include @@ -32,17 +33,20 @@ static int openCnt; static int gio_open(struct inode *inode, struct file *filp) { int minor; + int ret = -ENOENT; + lock_kernel(); minor = MINOR(inode->i_rdev); if (minor < DEVCOUNT) { if (openCnt > 0) { - return -EALREADY; + ret = -EALREADY; } else { openCnt++; - return 0; + ret = 0; } } - return -ENOENT; + unlock_kernel(); + return ret; } static int gio_close(struct inode *inode, struct file *filp) -- cgit v0.10.2 From 5119e92efc733d730b34f9605a5ae61fdc4bf649 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:12:01 -0600 Subject: x86: cdev lock_kernel() pushdown Push the cdev lock_kernel() call down into the x86 msr and cpuid drivers. Signed-off-by: Jonathan Corbet diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index daff52a..71f1c26 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -107,15 +108,23 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, static int cpuid_open(struct inode *inode, struct file *file) { - unsigned int cpu = iminor(file->f_path.dentry->d_inode); - struct cpuinfo_x86 *c = &cpu_data(cpu); - - if (cpu >= NR_CPUS || !cpu_online(cpu)) - return -ENXIO; /* No such CPU */ + unsigned int cpu; + struct cpuinfo_x86 *c; + int ret = 0; + + lock_kernel(); + + cpu = iminor(file->f_path.dentry->d_inode); + if (cpu >= NR_CPUS || !cpu_online(cpu)) { + ret = -ENXIO; /* No such CPU */ + goto out; + } + c = &cpu_data(cpu); if (c->cpuid_level < 0) - return -EIO; /* CPUID not supported */ - - return 0; + ret = -EIO; /* CPUID not supported */ +out: + unlock_kernel(); + return ret; } /* diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 1f3abe0..a153b39 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -117,12 +117,20 @@ static int msr_open(struct inode *inode, struct file *file) { unsigned int cpu = iminor(file->f_path.dentry->d_inode); struct cpuinfo_x86 *c = &cpu_data(cpu); + int ret = 0; - if (cpu >= NR_CPUS || !cpu_online(cpu)) - return -ENXIO; /* No such CPU */ - if (!cpu_has(c, X86_FEATURE_MSR)) - return -EIO; /* MSR not supported */ + lock_kernel(); + cpu = iminor(file->f_path.dentry->d_inode); + if (cpu >= NR_CPUS || !cpu_online(cpu)) { + ret = -ENXIO; /* No such CPU */ + goto out; + } + c = &cpu_data(cpu); + if (!cpu_has(c, X86_FEATURE_MSR)) + ret = -EIO; /* MSR not supported */ +out: + unlock_kernel(); return 0; } -- cgit v0.10.2 From 3db633ee352bfe20d4a2b0c3c8a46ce31a6c7149 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:21:02 -0600 Subject: i2c: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index d34c14c..006a585 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -34,6 +34,7 @@ #include #include #include +#include #include static struct i2c_driver i2cdev_driver; @@ -441,14 +442,20 @@ static int i2cdev_open(struct inode *inode, struct file *file) struct i2c_client *client; struct i2c_adapter *adap; struct i2c_dev *i2c_dev; + int ret = 0; + lock_kernel(); i2c_dev = i2c_dev_get_by_minor(minor); - if (!i2c_dev) - return -ENODEV; + if (!i2c_dev) { + ret = -ENODEV; + goto out; + } adap = i2c_get_adapter(i2c_dev->adap->nr); - if (!adap) - return -ENODEV; + if (!adap) { + ret = -ENODEV; + goto out; + } /* This creates an anonymous i2c_client, which may later be * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. @@ -460,7 +467,8 @@ static int i2cdev_open(struct inode *inode, struct file *file) client = kzalloc(sizeof(*client), GFP_KERNEL); if (!client) { i2c_put_adapter(adap); - return -ENOMEM; + ret = -ENOMEM; + goto out; } snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); client->driver = &i2cdev_driver; @@ -468,7 +476,9 @@ static int i2cdev_open(struct inode *inode, struct file *file) client->adapter = adap; file->private_data = client; - return 0; +out: + unlock_kernel(); + return ret; } static int i2cdev_release(struct inode *inode, struct file *file) -- cgit v0.10.2 From 0911810755fc9f15659cc3cb43912633b90027a0 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:21:33 -0600 Subject: cosa: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index b0fce13..5827324 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -92,6 +92,7 @@ #include #include #include +#include #undef COSA_SLOW_IO /* for testing purposes only */ @@ -970,15 +971,21 @@ static int cosa_open(struct inode *inode, struct file *file) struct channel_data *chan; unsigned long flags; int n; + int ret = 0; + lock_kernel(); if ((n=iminor(file->f_path.dentry->d_inode)>>CARD_MINOR_BITS) - >= nr_cards) - return -ENODEV; + >= nr_cards) { + ret = -ENODEV; + goto out; + } cosa = cosa_cards+n; if ((n=iminor(file->f_path.dentry->d_inode) - & ((1<= cosa->nchannels) - return -ENODEV; + & ((1<= cosa->nchannels) { + ret = -ENODEV; + goto out; + } chan = cosa->chan + n; file->private_data = chan; @@ -987,7 +994,8 @@ static int cosa_open(struct inode *inode, struct file *file) if (chan->usage < 0) { /* in netdev mode */ spin_unlock_irqrestore(&cosa->lock, flags); - return -EBUSY; + ret = -EBUSY; + goto out; } cosa->usage++; chan->usage++; @@ -996,7 +1004,9 @@ static int cosa_open(struct inode *inode, struct file *file) chan->setup_rx = chrdev_setup_rx; chan->rx_done = chrdev_rx_done; spin_unlock_irqrestore(&cosa->lock, flags); - return 0; +out: + unlock_kernel(); + return ret; } static int cosa_release(struct inode *inode, struct file *file) -- cgit v0.10.2 From 0bec0bba7a507bdaf07312fcabdc00b5576abb32 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:25:03 -0600 Subject: pcmcia: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 5f186ab..138396e 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define IN_CARD_SERVICES @@ -397,20 +398,27 @@ static int ds_open(struct inode *inode, struct file *file) struct pcmcia_socket *s; user_info_t *user; static int warning_printed = 0; + int ret = 0; ds_dbg(0, "ds_open(socket %d)\n", i); + lock_kernel(); s = pcmcia_get_socket_by_nr(i); - if (!s) - return -ENODEV; + if (!s) { + ret = -ENODEV; + goto out; + } s = pcmcia_get_socket(s); - if (!s) - return -ENODEV; + if (!s) { + ret = -ENODEV; + goto out; + } if ((file->f_flags & O_ACCMODE) != O_RDONLY) { if (s->pcmcia_state.busy) { pcmcia_put_socket(s); - return -EBUSY; + ret = -EBUSY; + goto out; } else s->pcmcia_state.busy = 1; @@ -419,7 +427,8 @@ static int ds_open(struct inode *inode, struct file *file) user = kmalloc(sizeof(user_info_t), GFP_KERNEL); if (!user) { pcmcia_put_socket(s); - return -ENOMEM; + ret = -ENOMEM; + goto out; } user->event_tail = user->event_head = 0; user->next = s->user; @@ -441,7 +450,9 @@ static int ds_open(struct inode *inode, struct file *file) if (s->pcmcia_state.present) queue_event(user, CS_EVENT_CARD_INSERTION); - return 0; +out: + unlock_kernel(); + return ret; } /* ds_open */ /*====================================================================*/ -- cgit v0.10.2 From 8b09dee67f484e9b42114b1a1f068e080fd7aa56 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:05 +0200 Subject: rcupreempt: remove duplicate prototypes rcu_batches_completed and rcu_patches_completed_bh are both declared in rcuclassic.h and rcupreempt.h. This patch removes the extra prototypes for them from rcupdate.h. rcu_batches_completed_bh is defined as a static inline in the rcupreempt.h header file. Trying to export this as EXPORT_SYMBOL_GPL causes linking problems with the powerpc linker. There's no need to export a static inlined function. Modules must be compiled with the same type of RCU implementation as the kernel they are for. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index d42dbec..ec2fc5b 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -224,8 +224,6 @@ extern void call_rcu_bh(struct rcu_head *head, /* Exported common interfaces */ extern void synchronize_rcu(void); extern void rcu_barrier(void); -extern long rcu_batches_completed(void); -extern long rcu_batches_completed_bh(void); /* Internal to kernel */ extern void rcu_init(void); diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index e1cdf19..5e02b77 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -217,8 +217,6 @@ long rcu_batches_completed(void) } EXPORT_SYMBOL_GPL(rcu_batches_completed); -EXPORT_SYMBOL_GPL(rcu_batches_completed_bh); - void __rcu_read_lock(void) { int idx; -- cgit v0.10.2 From 4446a36ff8c74ac3b32feb009b651048e129c6af Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: rcu: add call_rcu_sched() Fourth cut of patch to provide the call_rcu_sched(). This is again to synchronize_sched() as call_rcu() is to synchronize_rcu(). Should be fine for experimental and -rt use, but not ready for inclusion. With some luck, I will be able to tell Andrew to come out of hiding on the next round. Passes multi-day rcutorture sessions with concurrent CPU hotplugging. Fixes since the first version include a bug that could result in indefinite blocking (spotted by Gautham Shenoy), better resiliency against CPU-hotplug operations, and other minor fixes. Fixes since the second version include reworking grace-period detection to avoid deadlocks that could happen when running concurrently with CPU hotplug, adding Mathieu's fix to avoid the softlockup messages, as well as Mathieu's fix to allow use earlier in boot. Fixes since the third version include a wrong-CPU bug spotted by Andrew, getting rid of the obsolete synchronize_kernel API that somehow snuck back in, merging spin_unlock() and local_irq_restore() in a few places, commenting the code that checks for quiescent states based on interrupting from user-mode execution or the idle loop, removing some inline attributes, and some code-style changes. Known/suspected shortcomings: o I still do not entirely trust the sleep/wakeup logic. Next step will be to use a private snapshot of the CPU online mask in rcu_sched_grace_period() -- if the CPU wasn't there at the start of the grace period, we don't need to hear from it. And the bit about accounting for changes in online CPUs inside of rcu_sched_grace_period() is ugly anyway. o It might be good for rcu_sched_grace_period() to invoke resched_cpu() when a given CPU wasn't responding quickly, but resched_cpu() is declared static... This patch also fixes a long-standing bug in the earlier preemptable-RCU implementation of synchronize_rcu() that could result in loss of concurrent external changes to a task's CPU affinity mask. I still cannot remember who reported this... Signed-off-by: Paul E. McKenney Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index b3aa05b..8c77490 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -151,7 +151,10 @@ extern struct lockdep_map rcu_lock_map; #define __synchronize_sched() synchronize_rcu() +#define call_rcu_sched(head, func) call_rcu(head, func) + extern void __rcu_init(void); +#define rcu_init_sched() do { } while (0) extern void rcu_check_callbacks(int cpu, int user); extern void rcu_restart_cpu(int cpu); diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index ec2fc5b..411969c 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -40,6 +40,7 @@ #include #include #include +#include /** * struct rcu_head - callback structure for use with RCU @@ -168,6 +169,27 @@ struct rcu_head { (p) = (v); \ }) +/* Infrastructure to implement the synchronize_() primitives. */ + +struct rcu_synchronize { + struct rcu_head head; + struct completion completion; +}; + +extern void wakeme_after_rcu(struct rcu_head *head); + +#define synchronize_rcu_xxx(name, func) \ +void name(void) \ +{ \ + struct rcu_synchronize rcu; \ + \ + init_completion(&rcu.completion); \ + /* Will wake me after RCU finished. */ \ + func(&rcu.head, wakeme_after_rcu); \ + /* Wait for it. */ \ + wait_for_completion(&rcu.completion); \ +} + /** * synchronize_sched - block until all CPUs have exited any non-preemptive * kernel code sequences. diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 8a05c7e..f04b64e 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -40,10 +40,39 @@ #include #include -#define rcu_qsctr_inc(cpu) +struct rcu_dyntick_sched { + int dynticks; + int dynticks_snap; + int sched_qs; + int sched_qs_snap; + int sched_dynticks_snap; +}; + +DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched); + +static inline void rcu_qsctr_inc(int cpu) +{ + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); + + rdssp->sched_qs++; +} #define rcu_bh_qsctr_inc(cpu) #define call_rcu_bh(head, rcu) call_rcu(head, rcu) +/** + * call_rcu_sched - Queue RCU callback for invocation after sched grace period. + * @head: structure to be used for queueing the RCU updates. + * @func: actual update function to be invoked after the grace period + * + * The update function will be invoked some time after a full + * synchronize_sched()-style grace period elapses, in other words after + * all currently executing preempt-disabled sections of code (including + * hardirq handlers, NMI handlers, and local_irq_save() blocks) have + * completed. + */ +extern void call_rcu_sched(struct rcu_head *head, + void (*func)(struct rcu_head *head)); + extern void __rcu_read_lock(void) __acquires(RCU); extern void __rcu_read_unlock(void) __releases(RCU); extern int rcu_pending(int cpu); @@ -55,6 +84,7 @@ extern int rcu_needs_cpu(int cpu); extern void __synchronize_sched(void); extern void __rcu_init(void); +extern void rcu_init_sched(void); extern void rcu_check_callbacks(int cpu, int user); extern void rcu_restart_cpu(int cpu); extern long rcu_batches_completed(void); @@ -81,20 +111,20 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); struct softirq_action; #ifdef CONFIG_NO_HZ -DECLARE_PER_CPU(long, dynticks_progress_counter); +DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched); static inline void rcu_enter_nohz(void) { smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ - __get_cpu_var(dynticks_progress_counter)++; - WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1); + __get_cpu_var(rcu_dyntick_sched).dynticks++; + WARN_ON(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1); } static inline void rcu_exit_nohz(void) { - __get_cpu_var(dynticks_progress_counter)++; smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ - WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1)); + __get_cpu_var(rcu_dyntick_sched).dynticks++; + WARN_ON(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1)); } #else /* CONFIG_NO_HZ */ diff --git a/init/main.c b/init/main.c index f7fb200..a9cc3e0 100644 --- a/init/main.c +++ b/init/main.c @@ -758,6 +758,7 @@ static void __init do_initcalls(void) */ static void __init do_basic_setup(void) { + rcu_init_sched(); /* needed by module_init stage. */ /* drivers will send hotplug events */ init_workqueues(); usermodehelper_init(); diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index c09605f..a4e329d 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -39,18 +39,12 @@ #include #include #include -#include #include #include #include #include #include -struct rcu_synchronize { - struct rcu_head head; - struct completion completion; -}; - static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; static atomic_t rcu_barrier_cpu_count; static DEFINE_MUTEX(rcu_barrier_mutex); @@ -60,7 +54,7 @@ static struct completion rcu_barrier_completion; * Awaken the corresponding synchronize_rcu() instance now that a * grace period has elapsed. */ -static void wakeme_after_rcu(struct rcu_head *head) +void wakeme_after_rcu(struct rcu_head *head) { struct rcu_synchronize *rcu; @@ -77,17 +71,7 @@ static void wakeme_after_rcu(struct rcu_head *head) * sections are delimited by rcu_read_lock() and rcu_read_unlock(), * and may be nested. */ -void synchronize_rcu(void) -{ - struct rcu_synchronize rcu; - - init_completion(&rcu.completion); - /* Will wake me after RCU finished */ - call_rcu(&rcu.head, wakeme_after_rcu); - - /* Wait for it */ - wait_for_completion(&rcu.completion); -} +synchronize_rcu_xxx(synchronize_rcu, call_rcu) EXPORT_SYMBOL_GPL(synchronize_rcu); static void rcu_barrier_callback(struct rcu_head *notused) diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 5e02b77..aaa7976 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -87,9 +88,14 @@ struct rcu_data { struct rcu_head **nexttail; struct rcu_head *waitlist[GP_STAGES]; struct rcu_head **waittail[GP_STAGES]; - struct rcu_head *donelist; + struct rcu_head *donelist; /* from waitlist & waitschedlist */ struct rcu_head **donetail; long rcu_flipctr[2]; + struct rcu_head *nextschedlist; + struct rcu_head **nextschedtail; + struct rcu_head *waitschedlist; + struct rcu_head **waitschedtail; + int rcu_sched_sleeping; #ifdef CONFIG_RCU_TRACE struct rcupreempt_trace trace; #endif /* #ifdef CONFIG_RCU_TRACE */ @@ -131,11 +137,24 @@ enum rcu_try_flip_states { rcu_try_flip_waitmb_state, }; +/* + * States for rcu_ctrlblk.rcu_sched_sleep. + */ + +enum rcu_sched_sleep_states { + rcu_sched_not_sleeping, /* Not sleeping, callbacks need GP. */ + rcu_sched_sleep_prep, /* Thinking of sleeping, rechecking. */ + rcu_sched_sleeping, /* Sleeping, awaken if GP needed. */ +}; + struct rcu_ctrlblk { spinlock_t fliplock; /* Protect state-machine transitions. */ long completed; /* Number of last completed batch. */ enum rcu_try_flip_states rcu_try_flip_state; /* The current state of the rcu state machine */ + spinlock_t schedlock; /* Protect rcu_sched sleep state. */ + enum rcu_sched_sleep_states sched_sleep; /* rcu_sched state. */ + wait_queue_head_t sched_wq; /* Place for rcu_sched to sleep. */ }; static DEFINE_PER_CPU(struct rcu_data, rcu_data); @@ -143,8 +162,12 @@ static struct rcu_ctrlblk rcu_ctrlblk = { .fliplock = __SPIN_LOCK_UNLOCKED(rcu_ctrlblk.fliplock), .completed = 0, .rcu_try_flip_state = rcu_try_flip_idle_state, + .schedlock = __SPIN_LOCK_UNLOCKED(rcu_ctrlblk.schedlock), + .sched_sleep = rcu_sched_not_sleeping, + .sched_wq = __WAIT_QUEUE_HEAD_INITIALIZER(rcu_ctrlblk.sched_wq), }; +static struct task_struct *rcu_sched_grace_period_task; #ifdef CONFIG_RCU_TRACE static char *rcu_try_flip_state_names[] = @@ -207,6 +230,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(enum rcu_mb_flag_values, rcu_mb_flag) */ #define RCU_TRACE_RDP(f, rdp) RCU_TRACE(f, &((rdp)->trace)); +#define RCU_SCHED_BATCH_TIME (HZ / 50) + /* * Return the number of RCU batches processed thus far. Useful * for debug and statistics. @@ -411,32 +436,34 @@ static void __rcu_advance_callbacks(struct rcu_data *rdp) } } -#ifdef CONFIG_NO_HZ +DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_dyntick_sched, rcu_dyntick_sched) = { + .dynticks = 1, +}; -DEFINE_PER_CPU(long, dynticks_progress_counter) = 1; -static DEFINE_PER_CPU(long, rcu_dyntick_snapshot); +#ifdef CONFIG_NO_HZ static DEFINE_PER_CPU(int, rcu_update_flag); /** * rcu_irq_enter - Called from Hard irq handlers and NMI/SMI. * * If the CPU was idle with dynamic ticks active, this updates the - * dynticks_progress_counter to let the RCU handling know that the + * rcu_dyntick_sched.dynticks to let the RCU handling know that the * CPU is active. */ void rcu_irq_enter(void) { int cpu = smp_processor_id(); + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); if (per_cpu(rcu_update_flag, cpu)) per_cpu(rcu_update_flag, cpu)++; /* * Only update if we are coming from a stopped ticks mode - * (dynticks_progress_counter is even). + * (rcu_dyntick_sched.dynticks is even). */ if (!in_interrupt() && - (per_cpu(dynticks_progress_counter, cpu) & 0x1) == 0) { + (rdssp->dynticks & 0x1) == 0) { /* * The following might seem like we could have a race * with NMI/SMIs. But this really isn't a problem. @@ -459,12 +486,12 @@ void rcu_irq_enter(void) * RCU read-side critical sections on this CPU would * have already completed. */ - per_cpu(dynticks_progress_counter, cpu)++; + rdssp->dynticks++; /* * The following memory barrier ensures that any * rcu_read_lock() primitives in the irq handler * are seen by other CPUs to follow the above - * increment to dynticks_progress_counter. This is + * increment to rcu_dyntick_sched.dynticks. This is * required in order for other CPUs to correctly * determine when it is safe to advance the RCU * grace-period state machine. @@ -472,7 +499,7 @@ void rcu_irq_enter(void) smp_mb(); /* see above block comment. */ /* * Since we can't determine the dynamic tick mode from - * the dynticks_progress_counter after this routine, + * the rcu_dyntick_sched.dynticks after this routine, * we use a second flag to acknowledge that we came * from an idle state with ticks stopped. */ @@ -480,7 +507,7 @@ void rcu_irq_enter(void) /* * If we take an NMI/SMI now, they will also increment * the rcu_update_flag, and will not update the - * dynticks_progress_counter on exit. That is for + * rcu_dyntick_sched.dynticks on exit. That is for * this IRQ to do. */ } @@ -490,12 +517,13 @@ void rcu_irq_enter(void) * rcu_irq_exit - Called from exiting Hard irq context. * * If the CPU was idle with dynamic ticks active, update the - * dynticks_progress_counter to put let the RCU handling be + * rcu_dyntick_sched.dynticks to put let the RCU handling be * aware that the CPU is going back to idle with no ticks. */ void rcu_irq_exit(void) { int cpu = smp_processor_id(); + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); /* * rcu_update_flag is set if we interrupted the CPU @@ -503,7 +531,7 @@ void rcu_irq_exit(void) * Once this occurs, we keep track of interrupt nesting * because a NMI/SMI could also come in, and we still * only want the IRQ that started the increment of the - * dynticks_progress_counter to be the one that modifies + * rcu_dyntick_sched.dynticks to be the one that modifies * it on exit. */ if (per_cpu(rcu_update_flag, cpu)) { @@ -515,28 +543,29 @@ void rcu_irq_exit(void) /* * If an NMI/SMI happens now we are still - * protected by the dynticks_progress_counter being odd. + * protected by the rcu_dyntick_sched.dynticks being odd. */ /* * The following memory barrier ensures that any * rcu_read_unlock() primitives in the irq handler * are seen by other CPUs to preceed the following - * increment to dynticks_progress_counter. This + * increment to rcu_dyntick_sched.dynticks. This * is required in order for other CPUs to determine * when it is safe to advance the RCU grace-period * state machine. */ smp_mb(); /* see above block comment. */ - per_cpu(dynticks_progress_counter, cpu)++; - WARN_ON(per_cpu(dynticks_progress_counter, cpu) & 0x1); + rdssp->dynticks++; + WARN_ON(rdssp->dynticks & 0x1); } } static void dyntick_save_progress_counter(int cpu) { - per_cpu(rcu_dyntick_snapshot, cpu) = - per_cpu(dynticks_progress_counter, cpu); + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); + + rdssp->dynticks_snap = rdssp->dynticks; } static inline int @@ -544,9 +573,10 @@ rcu_try_flip_waitack_needed(int cpu) { long curr; long snap; + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); - curr = per_cpu(dynticks_progress_counter, cpu); - snap = per_cpu(rcu_dyntick_snapshot, cpu); + curr = rdssp->dynticks; + snap = rdssp->dynticks_snap; smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ /* @@ -580,9 +610,10 @@ rcu_try_flip_waitmb_needed(int cpu) { long curr; long snap; + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); - curr = per_cpu(dynticks_progress_counter, cpu); - snap = per_cpu(rcu_dyntick_snapshot, cpu); + curr = rdssp->dynticks; + snap = rdssp->dynticks_snap; smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ /* @@ -609,14 +640,86 @@ rcu_try_flip_waitmb_needed(int cpu) return 1; } +static void dyntick_save_progress_counter_sched(int cpu) +{ + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); + + rdssp->sched_dynticks_snap = rdssp->dynticks; +} + +static int rcu_qsctr_inc_needed_dyntick(int cpu) +{ + long curr; + long snap; + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); + + curr = rdssp->dynticks; + snap = rdssp->sched_dynticks_snap; + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot be in the middle of an rcu_read_lock(), so + * the next rcu_read_lock() it executes must use the new value + * of the counter. Therefore, this CPU has been in a quiescent + * state the entire time, and we don't need to wait for it. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU passed through or entered a dynticks idle phase with + * no active irq handlers, then, as above, this CPU has already + * passed through a quiescent state. + */ + + if ((curr - snap) > 2 || (snap & 0x1) == 0) + return 0; + + /* We need this CPU to go through a quiescent state. */ + + return 1; +} + #else /* !CONFIG_NO_HZ */ -# define dyntick_save_progress_counter(cpu) do { } while (0) -# define rcu_try_flip_waitack_needed(cpu) (1) -# define rcu_try_flip_waitmb_needed(cpu) (1) +# define dyntick_save_progress_counter(cpu) do { } while (0) +# define rcu_try_flip_waitack_needed(cpu) (1) +# define rcu_try_flip_waitmb_needed(cpu) (1) + +# define dyntick_save_progress_counter_sched(cpu) do { } while (0) +# define rcu_qsctr_inc_needed_dyntick(cpu) (1) #endif /* CONFIG_NO_HZ */ +static void save_qsctr_sched(int cpu) +{ + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); + + rdssp->sched_qs_snap = rdssp->sched_qs; +} + +static inline int rcu_qsctr_inc_needed(int cpu) +{ + struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); + + /* + * If there has been a quiescent state, no more need to wait + * on this CPU. + */ + + if (rdssp->sched_qs != rdssp->sched_qs_snap) { + smp_mb(); /* force ordering with cpu entering schedule(). */ + return 0; + } + + /* We need this CPU to go through a quiescent state. */ + + return 1; +} + /* * Get here when RCU is idle. Decide whether we need to * move out of idle state, and return non-zero if so. @@ -819,6 +922,26 @@ void rcu_check_callbacks(int cpu, int user) unsigned long flags; struct rcu_data *rdp = RCU_DATA_CPU(cpu); + /* + * If this CPU took its interrupt from user mode or from the + * idle loop, and this is not a nested interrupt, then + * this CPU has to have exited all prior preept-disable + * sections of code. So increment the counter to note this. + * + * The memory barrier is needed to handle the case where + * writes from a preempt-disable section of code get reordered + * into schedule() by this CPU's write buffer. So the memory + * barrier makes sure that the rcu_qsctr_inc() is seen by other + * CPUs to happen after any such write. + */ + + if (user || + (idle_cpu(cpu) && !in_softirq() && + hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + smp_mb(); /* Guard against aggressive schedule(). */ + rcu_qsctr_inc(cpu); + } + rcu_check_mb(cpu); if (rcu_ctrlblk.completed == rdp->completed) rcu_try_flip(); @@ -869,6 +992,8 @@ void rcu_offline_cpu(int cpu) struct rcu_head *list = NULL; unsigned long flags; struct rcu_data *rdp = RCU_DATA_CPU(cpu); + struct rcu_head *schedlist = NULL; + struct rcu_head **schedtail = &schedlist; struct rcu_head **tail = &list; /* @@ -882,6 +1007,11 @@ void rcu_offline_cpu(int cpu) rcu_offline_cpu_enqueue(rdp->waitlist[i], rdp->waittail[i], list, tail); rcu_offline_cpu_enqueue(rdp->nextlist, rdp->nexttail, list, tail); + rcu_offline_cpu_enqueue(rdp->waitschedlist, rdp->waitschedtail, + schedlist, schedtail); + rcu_offline_cpu_enqueue(rdp->nextschedlist, rdp->nextschedtail, + schedlist, schedtail); + rdp->rcu_sched_sleeping = 0; spin_unlock_irqrestore(&rdp->lock, flags); rdp->waitlistcount = 0; @@ -916,22 +1046,40 @@ void rcu_offline_cpu(int cpu) * fix. */ - local_irq_save(flags); + local_irq_save(flags); /* disable preempt till we know what lock. */ rdp = RCU_DATA_ME(); spin_lock(&rdp->lock); *rdp->nexttail = list; if (list) rdp->nexttail = tail; + *rdp->nextschedtail = schedlist; + if (schedlist) + rdp->nextschedtail = schedtail; spin_unlock_irqrestore(&rdp->lock, flags); } void __devinit rcu_online_cpu(int cpu) { unsigned long flags; + struct rcu_data *rdp; spin_lock_irqsave(&rcu_ctrlblk.fliplock, flags); cpu_set(cpu, rcu_cpu_online_map); spin_unlock_irqrestore(&rcu_ctrlblk.fliplock, flags); + + /* + * The rcu_sched grace-period processing might have bypassed + * this CPU, given that it was not in the rcu_cpu_online_map + * when the grace-period scan started. This means that the + * grace-period task might sleep. So make sure that if this + * should happen, the first callback posted to this CPU will + * wake up the grace-period task if need be. + */ + + rdp = RCU_DATA_CPU(cpu); + spin_lock_irqsave(&rdp->lock, flags); + rdp->rcu_sched_sleeping = 1; + spin_unlock_irqrestore(&rdp->lock, flags); } #else /* #ifdef CONFIG_HOTPLUG_CPU */ @@ -986,31 +1134,196 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) *rdp->nexttail = head; rdp->nexttail = &head->next; RCU_TRACE_RDP(rcupreempt_trace_next_add, rdp); - spin_unlock(&rdp->lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&rdp->lock, flags); } EXPORT_SYMBOL_GPL(call_rcu); +void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) +{ + unsigned long flags; + struct rcu_data *rdp; + int wake_gp = 0; + + head->func = func; + head->next = NULL; + local_irq_save(flags); + rdp = RCU_DATA_ME(); + spin_lock(&rdp->lock); + *rdp->nextschedtail = head; + rdp->nextschedtail = &head->next; + if (rdp->rcu_sched_sleeping) { + + /* Grace-period processing might be sleeping... */ + + rdp->rcu_sched_sleeping = 0; + wake_gp = 1; + } + spin_unlock_irqrestore(&rdp->lock, flags); + if (wake_gp) { + + /* Wake up grace-period processing, unless someone beat us. */ + + spin_lock_irqsave(&rcu_ctrlblk.schedlock, flags); + if (rcu_ctrlblk.sched_sleep != rcu_sched_sleeping) + wake_gp = 0; + rcu_ctrlblk.sched_sleep = rcu_sched_not_sleeping; + spin_unlock_irqrestore(&rcu_ctrlblk.schedlock, flags); + if (wake_gp) + wake_up_interruptible(&rcu_ctrlblk.sched_wq); + } +} +EXPORT_SYMBOL_GPL(call_rcu_sched); + /* * Wait until all currently running preempt_disable() code segments * (including hardware-irq-disable segments) complete. Note that * in -rt this does -not- necessarily result in all currently executing * interrupt -handlers- having completed. */ -void __synchronize_sched(void) +synchronize_rcu_xxx(__synchronize_sched, call_rcu_sched) +EXPORT_SYMBOL_GPL(__synchronize_sched); + +/* + * kthread function that manages call_rcu_sched grace periods. + */ +static int rcu_sched_grace_period(void *arg) { - cpumask_t oldmask; + int couldsleep; /* might sleep after current pass. */ + int couldsleepnext = 0; /* might sleep after next pass. */ int cpu; + unsigned long flags; + struct rcu_data *rdp; + int ret; - if (sched_getaffinity(0, &oldmask) < 0) - oldmask = cpu_possible_map; - for_each_online_cpu(cpu) { - sched_setaffinity(0, &cpumask_of_cpu(cpu)); - schedule(); - } - sched_setaffinity(0, &oldmask); + /* + * Each pass through the following loop handles one + * rcu_sched grace period cycle. + */ + do { + /* Save each CPU's current state. */ + + for_each_online_cpu(cpu) { + dyntick_save_progress_counter_sched(cpu); + save_qsctr_sched(cpu); + } + + /* + * Sleep for about an RCU grace-period's worth to + * allow better batching and to consume less CPU. + */ + schedule_timeout_interruptible(RCU_SCHED_BATCH_TIME); + + /* + * If there was nothing to do last time, prepare to + * sleep at the end of the current grace period cycle. + */ + couldsleep = couldsleepnext; + couldsleepnext = 1; + if (couldsleep) { + spin_lock_irqsave(&rcu_ctrlblk.schedlock, flags); + rcu_ctrlblk.sched_sleep = rcu_sched_sleep_prep; + spin_unlock_irqrestore(&rcu_ctrlblk.schedlock, flags); + } + + /* + * Wait on each CPU in turn to have either visited + * a quiescent state or been in dynticks-idle mode. + */ + for_each_online_cpu(cpu) { + while (rcu_qsctr_inc_needed(cpu) && + rcu_qsctr_inc_needed_dyntick(cpu)) { + /* resched_cpu(cpu); @@@ */ + schedule_timeout_interruptible(1); + } + } + + /* Advance callbacks for each CPU. */ + + for_each_online_cpu(cpu) { + + rdp = RCU_DATA_CPU(cpu); + spin_lock_irqsave(&rdp->lock, flags); + + /* + * We are running on this CPU irq-disabled, so no + * CPU can go offline until we re-enable irqs. + * The current CPU might have already gone + * offline (between the for_each_offline_cpu and + * the spin_lock_irqsave), but in that case all its + * callback lists will be empty, so no harm done. + * + * Advance the callbacks! We share normal RCU's + * donelist, since callbacks are invoked the + * same way in either case. + */ + if (rdp->waitschedlist != NULL) { + *rdp->donetail = rdp->waitschedlist; + rdp->donetail = rdp->waitschedtail; + + /* + * Next rcu_check_callbacks() will + * do the required raise_softirq(). + */ + } + if (rdp->nextschedlist != NULL) { + rdp->waitschedlist = rdp->nextschedlist; + rdp->waitschedtail = rdp->nextschedtail; + couldsleep = 0; + couldsleepnext = 0; + } else { + rdp->waitschedlist = NULL; + rdp->waitschedtail = &rdp->waitschedlist; + } + rdp->nextschedlist = NULL; + rdp->nextschedtail = &rdp->nextschedlist; + + /* Mark sleep intention. */ + + rdp->rcu_sched_sleeping = couldsleep; + + spin_unlock_irqrestore(&rdp->lock, flags); + } + + /* If we saw callbacks on the last scan, go deal with them. */ + + if (!couldsleep) + continue; + + /* Attempt to block... */ + + spin_lock_irqsave(&rcu_ctrlblk.schedlock, flags); + if (rcu_ctrlblk.sched_sleep != rcu_sched_sleep_prep) { + + /* + * Someone posted a callback after we scanned. + * Go take care of it. + */ + spin_unlock_irqrestore(&rcu_ctrlblk.schedlock, flags); + couldsleepnext = 0; + continue; + } + + /* Block until the next person posts a callback. */ + + rcu_ctrlblk.sched_sleep = rcu_sched_sleeping; + spin_unlock_irqrestore(&rcu_ctrlblk.schedlock, flags); + ret = 0; + __wait_event_interruptible(rcu_ctrlblk.sched_wq, + rcu_ctrlblk.sched_sleep != rcu_sched_sleeping, + ret); + + /* + * Signals would prevent us from sleeping, and we cannot + * do much with them in any case. So flush them. + */ + if (ret) + flush_signals(current); + couldsleepnext = 0; + + } while (!kthread_should_stop()); + + return (0); } -EXPORT_SYMBOL_GPL(__synchronize_sched); /* * Check to see if any future RCU-related work will need to be done @@ -1027,7 +1340,9 @@ int rcu_needs_cpu(int cpu) return (rdp->donelist != NULL || !!rdp->waitlistcount || - rdp->nextlist != NULL); + rdp->nextlist != NULL || + rdp->nextschedlist != NULL || + rdp->waitschedlist != NULL); } int rcu_pending(int cpu) @@ -1038,7 +1353,9 @@ int rcu_pending(int cpu) if (rdp->donelist != NULL || !!rdp->waitlistcount || - rdp->nextlist != NULL) + rdp->nextlist != NULL || + rdp->nextschedlist != NULL || + rdp->waitschedlist != NULL) return 1; /* The RCU core needs an acknowledgement from this CPU. */ @@ -1105,6 +1422,11 @@ void __init __rcu_init(void) rdp->donetail = &rdp->donelist; rdp->rcu_flipctr[0] = 0; rdp->rcu_flipctr[1] = 0; + rdp->nextschedlist = NULL; + rdp->nextschedtail = &rdp->nextschedlist; + rdp->waitschedlist = NULL; + rdp->waitschedtail = &rdp->waitschedlist; + rdp->rcu_sched_sleeping = 0; } register_cpu_notifier(&rcu_nb); @@ -1127,11 +1449,15 @@ void __init __rcu_init(void) } /* - * Deprecated, use synchronize_rcu() or synchronize_sched() instead. + * Late-boot-time RCU initialization that must wait until after scheduler + * has been initialized. */ -void synchronize_kernel(void) +void __init rcu_init_sched(void) { - synchronize_rcu(); + rcu_sched_grace_period_task = kthread_run(rcu_sched_grace_period, + NULL, + "rcu_sched_grace_period"); + WARN_ON(IS_ERR(rcu_sched_grace_period_task)); } #ifdef CONFIG_RCU_TRACE -- cgit v0.10.2 From 8db559b83009bed92e1b5dd13a651ff273d9ff62 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: rcu: add memory barriers and comments to rcu_check_callbacks() Add comments to the logic that infers quiescent states when interrupting from either user mode or the idle loop. Also add a memory barrier: it appears that James Huang was in fact onto something, as the scheduler is much less synchronization happy than it once was, so we can no longer rely on its memory barriers in all cases. Signed-off-by: Paul E. McKenney Reported-by: James Huang Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index f4ffbd0..d834879 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c @@ -502,10 +502,38 @@ void rcu_check_callbacks(int cpu, int user) if (user || (idle_cpu(cpu) && !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + + /* + * Get here if this CPU took its interrupt from user + * mode or from the idle loop, and if this is not a + * nested interrupt. In this case, the CPU is in + * a quiescent state, so count it. + * + * Also do a memory barrier. This is needed to handle + * the case where writes from a preempt-disable section + * of code get reordered into schedule() by this CPU's + * write buffer. The memory barrier makes sure that + * the rcu_qsctr_inc() and rcu_bh_qsctr_inc() are see + * by other CPUs to happen after any such write. + */ + + smp_mb(); /* See above block comment. */ rcu_qsctr_inc(cpu); rcu_bh_qsctr_inc(cpu); - } else if (!in_softirq()) + + } else if (!in_softirq()) { + + /* + * Get here if this CPU did not take its interrupt from + * softirq, in other words, if it is not interrupting + * a rcu_bh read-side critical section. This is an _bh + * critical section, so count it. The memory barrier + * is needed for the same reason as is the above one. + */ + + smp_mb(); /* See above block comment. */ rcu_bh_qsctr_inc(cpu); + } raise_rcu_softirq(); } -- cgit v0.10.2 From 70f12f848d3e981479b4f6f751e73c14f7c13e5b Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: rcu: add rcu_barrier_sched() and rcu_barrier_bh() Add rcu_barrier_sched() and rcu_barrier_bh(). With these in place, rcutorture no longer gives the occasional oops when repeatedly starting and stopping torturing rcu_bh. Also adds the API needed to flush out pre-existing call_rcu_sched() callbacks. Signed-off-by: Paul E. McKenney Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 411969c..e8b4039 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -246,6 +246,8 @@ extern void call_rcu_bh(struct rcu_head *head, /* Exported common interfaces */ extern void synchronize_rcu(void); extern void rcu_barrier(void); +extern void rcu_barrier_bh(void); +extern void rcu_barrier_sched(void); /* Internal to kernel */ extern void rcu_init(void); diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index a4e329d..4a74b8d 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -45,6 +45,12 @@ #include #include +enum rcu_barrier { + RCU_BARRIER_STD, + RCU_BARRIER_BH, + RCU_BARRIER_SCHED, +}; + static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; static atomic_t rcu_barrier_cpu_count; static DEFINE_MUTEX(rcu_barrier_mutex); @@ -83,19 +89,30 @@ static void rcu_barrier_callback(struct rcu_head *notused) /* * Called with preemption disabled, and from cross-cpu IRQ context. */ -static void rcu_barrier_func(void *notused) +static void rcu_barrier_func(void *type) { int cpu = smp_processor_id(); struct rcu_head *head = &per_cpu(rcu_barrier_head, cpu); atomic_inc(&rcu_barrier_cpu_count); - call_rcu(head, rcu_barrier_callback); + switch ((enum rcu_barrier)type) { + case RCU_BARRIER_STD: + call_rcu(head, rcu_barrier_callback); + break; + case RCU_BARRIER_BH: + call_rcu_bh(head, rcu_barrier_callback); + break; + case RCU_BARRIER_SCHED: + call_rcu_sched(head, rcu_barrier_callback); + break; + } } -/** - * rcu_barrier - Wait until all the in-flight RCUs are complete. +/* + * Orchestrate the specified type of RCU barrier, waiting for all + * RCU callbacks of the specified type to complete. */ -void rcu_barrier(void) +static void _rcu_barrier(enum rcu_barrier type) { BUG_ON(in_interrupt()); /* Take cpucontrol mutex to protect against CPU hotplug */ @@ -111,13 +128,39 @@ void rcu_barrier(void) * until all the callbacks are queued. */ rcu_read_lock(); - on_each_cpu(rcu_barrier_func, NULL, 0, 1); + on_each_cpu(rcu_barrier_func, (void *)type, 0, 1); rcu_read_unlock(); wait_for_completion(&rcu_barrier_completion); mutex_unlock(&rcu_barrier_mutex); } + +/** + * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete. + */ +void rcu_barrier(void) +{ + _rcu_barrier(RCU_BARRIER_STD); +} EXPORT_SYMBOL_GPL(rcu_barrier); +/** + * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete. + */ +void rcu_barrier_bh(void) +{ + _rcu_barrier(RCU_BARRIER_BH); +} +EXPORT_SYMBOL_GPL(rcu_barrier_bh); + +/** + * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks. + */ +void rcu_barrier_sched(void) +{ + _rcu_barrier(RCU_BARRIER_SCHED); +} +EXPORT_SYMBOL_GPL(rcu_barrier_sched); + void __init rcu_init(void) { __rcu_init(); -- cgit v0.10.2 From 2326974df29988181b6b69ed6fbf42b17adf916f Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: rcu: add call_rcu_sched() and friends to rcutorture Add entry to rcu_torture_ops allowing the correct barrier function to be used upon exit from rcutorture. Also add torture options for the new call_rcu_sched() API. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index 33acc424..0334b6a 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c @@ -192,6 +192,7 @@ struct rcu_torture_ops { int (*completed)(void); void (*deferredfree)(struct rcu_torture *p); void (*sync)(void); + void (*cb_barrier)(void); int (*stats)(char *page); char *name; }; @@ -265,6 +266,7 @@ static struct rcu_torture_ops rcu_ops = { .completed = rcu_torture_completed, .deferredfree = rcu_torture_deferred_free, .sync = synchronize_rcu, + .cb_barrier = rcu_barrier, .stats = NULL, .name = "rcu" }; @@ -304,6 +306,7 @@ static struct rcu_torture_ops rcu_sync_ops = { .completed = rcu_torture_completed, .deferredfree = rcu_sync_torture_deferred_free, .sync = synchronize_rcu, + .cb_barrier = NULL, .stats = NULL, .name = "rcu_sync" }; @@ -364,6 +367,7 @@ static struct rcu_torture_ops rcu_bh_ops = { .completed = rcu_bh_torture_completed, .deferredfree = rcu_bh_torture_deferred_free, .sync = rcu_bh_torture_synchronize, + .cb_barrier = rcu_barrier_bh, .stats = NULL, .name = "rcu_bh" }; @@ -377,6 +381,7 @@ static struct rcu_torture_ops rcu_bh_sync_ops = { .completed = rcu_bh_torture_completed, .deferredfree = rcu_sync_torture_deferred_free, .sync = rcu_bh_torture_synchronize, + .cb_barrier = NULL, .stats = NULL, .name = "rcu_bh_sync" }; @@ -458,6 +463,7 @@ static struct rcu_torture_ops srcu_ops = { .completed = srcu_torture_completed, .deferredfree = rcu_sync_torture_deferred_free, .sync = srcu_torture_synchronize, + .cb_barrier = NULL, .stats = srcu_torture_stats, .name = "srcu" }; @@ -482,6 +488,11 @@ static int sched_torture_completed(void) return 0; } +static void rcu_sched_torture_deferred_free(struct rcu_torture *p) +{ + call_rcu_sched(&p->rtort_rcu, rcu_torture_cb); +} + static void sched_torture_synchronize(void) { synchronize_sched(); @@ -494,12 +505,27 @@ static struct rcu_torture_ops sched_ops = { .readdelay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = sched_torture_read_unlock, .completed = sched_torture_completed, - .deferredfree = rcu_sync_torture_deferred_free, + .deferredfree = rcu_sched_torture_deferred_free, .sync = sched_torture_synchronize, + .cb_barrier = rcu_barrier_sched, .stats = NULL, .name = "sched" }; +static struct rcu_torture_ops sched_ops_sync = { + .init = rcu_sync_torture_init, + .cleanup = NULL, + .readlock = sched_torture_read_lock, + .readdelay = rcu_read_delay, /* just reuse rcu's version. */ + .readunlock = sched_torture_read_unlock, + .completed = sched_torture_completed, + .deferredfree = rcu_sync_torture_deferred_free, + .sync = sched_torture_synchronize, + .cb_barrier = NULL, + .stats = NULL, + .name = "sched_sync" +}; + /* * RCU torture writer kthread. Repeatedly substitutes a new structure * for that pointed to by rcu_torture_current, freeing the old structure @@ -848,7 +874,9 @@ rcu_torture_cleanup(void) stats_task = NULL; /* Wait for all RCU callbacks to fire. */ - rcu_barrier(); + + if (cur_ops->cb_barrier != NULL) + cur_ops->cb_barrier(); rcu_torture_stats_print(); /* -After- the stats thread is stopped! */ @@ -868,7 +896,7 @@ rcu_torture_init(void) int firsterr = 0; static struct rcu_torture_ops *torture_ops[] = { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops, - &srcu_ops, &sched_ops, }; + &srcu_ops, &sched_ops, &sched_ops_sync, }; /* Process args and tell the world that the torturer is on the job. */ for (i = 0; i < ARRAY_SIZE(torture_ops); i++) { -- cgit v0.10.2 From 32300751b4079cb5688453baa94711579d4285d5 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:05 +0200 Subject: sched: 1Q08 RCU doc update, add call_rcu_sched() Long-delayed update to the RCU documentation, including adding the new call_rcu_sched() and rcu_barrier_sched() APIs. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/Documentation/RCU/NMI-RCU.txt b/Documentation/RCU/NMI-RCU.txt index c64158e..a6d32e6 100644 --- a/Documentation/RCU/NMI-RCU.txt +++ b/Documentation/RCU/NMI-RCU.txt @@ -93,6 +93,9 @@ Since NMI handlers disable preemption, synchronize_sched() is guaranteed not to return until all ongoing NMI handlers exit. It is therefore safe to free up the handler's data as soon as synchronize_sched() returns. +Important note: for this to work, the architecture in question must +invoke irq_enter() and irq_exit() on NMI entry and exit, respectively. + Answer to Quick Quiz diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt index 39ad8f5..9f711d2 100644 --- a/Documentation/RCU/RTFP.txt +++ b/Documentation/RCU/RTFP.txt @@ -52,6 +52,10 @@ of each iteration. Unfortunately, chaotic relaxation requires highly structured data, such as the matrices used in scientific programs, and is thus inapplicable to most data structures in operating-system kernels. +In 1992, Henry (now Alexia) Massalin completed a dissertation advising +parallel programmers to defer processing when feasible to simplify +synchronization. RCU makes extremely heavy use of this advice. + In 1993, Jacobson [Jacobson93] verbally described what is perhaps the simplest deferred-free technique: simply waiting a fixed amount of time before freeing blocks awaiting deferred free. Jacobson did not describe @@ -138,6 +142,13 @@ blocking in read-side critical sections appeared [PaulEMcKenney2006c], Robert Olsson described an RCU-protected trie-hash combination [RobertOlsson2006a]. +2007 saw the journal version of the award-winning RCU paper from 2006 +[ThomasEHart2007a], as well as a paper demonstrating use of Promela +and Spin to mechanically verify an optimization to Oleg Nesterov's +QRCU [PaulEMcKenney2007QRCUspin], a design document describing +preemptible RCU [PaulEMcKenney2007PreemptibleRCU], and the three-part +LWN "What is RCU?" series [PaulEMcKenney2007WhatIsRCUFundamentally, +PaulEMcKenney2008WhatIsRCUUsage, and PaulEMcKenney2008WhatIsRCUAPI]. Bibtex Entries @@ -202,6 +213,20 @@ Bibtex Entries ,Year="1991" } +@phdthesis{HMassalinPhD +,author="H. Massalin" +,title="Synthesis: An Efficient Implementation of Fundamental Operating +System Services" +,school="Columbia University" +,address="New York, NY" +,year="1992" +,annotation=" + Mondo optimizing compiler. + Wait-free stuff. + Good advice: defer work to avoid synchronization. +" +} + @unpublished{Jacobson93 ,author="Van Jacobson" ,title="Avoid Read-Side Locking Via Delayed Free" @@ -635,3 +660,86 @@ Revised: " } +@unpublished{PaulEMcKenney2007PreemptibleRCU +,Author="Paul E. McKenney" +,Title="The design of preemptible read-copy-update" +,month="October" +,day="8" +,year="2007" +,note="Available: +\url{http://lwn.net/Articles/253651/} +[Viewed October 25, 2007]" +,annotation=" + LWN article describing the design of preemptible RCU. +" +} + +######################################################################## +# +# "What is RCU?" LWN series. +# + +@unpublished{PaulEMcKenney2007WhatIsRCUFundamentally +,Author="Paul E. McKenney and Jonathan Walpole" +,Title="What is {RCU}, Fundamentally?" +,month="December" +,day="17" +,year="2007" +,note="Available: +\url{http://lwn.net/Articles/262464/} +[Viewed December 27, 2007]" +,annotation=" + Lays out the three basic components of RCU: (1) publish-subscribe, + (2) wait for pre-existing readers to complete, and (2) maintain + multiple versions. +" +} + +@unpublished{PaulEMcKenney2008WhatIsRCUUsage +,Author="Paul E. McKenney" +,Title="What is {RCU}? Part 2: Usage" +,month="January" +,day="4" +,year="2008" +,note="Available: +\url{http://lwn.net/Articles/263130/} +[Viewed January 4, 2008]" +,annotation=" + Lays out six uses of RCU: + 1. RCU is a Reader-Writer Lock Replacement + 2. RCU is a Restricted Reference-Counting Mechanism + 3. RCU is a Bulk Reference-Counting Mechanism + 4. RCU is a Poor Man's Garbage Collector + 5. RCU is a Way of Providing Existence Guarantees + 6. RCU is a Way of Waiting for Things to Finish +" +} + +@unpublished{PaulEMcKenney2008WhatIsRCUAPI +,Author="Paul E. McKenney" +,Title="{RCU} part 3: the {RCU} {API}" +,month="January" +,day="17" +,year="2008" +,note="Available: +\url{http://lwn.net/Articles/264090/} +[Viewed January 10, 2008]" +,annotation=" + Gives an overview of the Linux-kernel RCU API and a brief annotated RCU + bibliography. +" +} + +@article{DinakarGuniguntala2008IBMSysJ +,author="D. Guniguntala and P. E. McKenney and J. Triplett and J. Walpole" +,title="The read-copy-update mechanism for supporting real-time applications on shared-memory multiprocessor systems with {Linux}" +,Year="2008" +,Month="April" +,journal="IBM Systems Journal" +,volume="47" +,number="2" +,pages="@@-@@" +,annotation=" + RCU, realtime RCU, sleepable RCU, performance. +" +} diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index 42b01bc..cf5562c 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt @@ -13,10 +13,13 @@ over a rather long period of time, but improvements are always welcome! detailed performance measurements show that RCU is nonetheless the right tool for the job. - The other exception would be where performance is not an issue, - and RCU provides a simpler implementation. An example of this - situation is the dynamic NMI code in the Linux 2.6 kernel, - at least on architectures where NMIs are rare. + Another exception is where performance is not an issue, and RCU + provides a simpler implementation. An example of this situation + is the dynamic NMI code in the Linux 2.6 kernel, at least on + architectures where NMIs are rare. + + Yet another exception is where the low real-time latency of RCU's + read-side primitives is critically important. 1. Does the update code have proper mutual exclusion? @@ -39,9 +42,10 @@ over a rather long period of time, but improvements are always welcome! 2. Do the RCU read-side critical sections make proper use of rcu_read_lock() and friends? These primitives are needed - to suppress preemption (or bottom halves, in the case of - rcu_read_lock_bh()) in the read-side critical sections, - and are also an excellent aid to readability. + to prevent grace periods from ending prematurely, which + could result in data being unceremoniously freed out from + under your read-side code, which can greatly increase the + actuarial risk of your kernel. As a rough rule of thumb, any dereference of an RCU-protected pointer must be covered by rcu_read_lock() or rcu_read_lock_bh() @@ -54,15 +58,30 @@ over a rather long period of time, but improvements are always welcome! be running while updates are in progress. There are a number of ways to handle this concurrency, depending on the situation: - a. Make updates appear atomic to readers. For example, + a. Use the RCU variants of the list and hlist update + primitives to add, remove, and replace elements on an + RCU-protected list. Alternatively, use the RCU-protected + trees that have been added to the Linux kernel. + + This is almost always the best approach. + + b. Proceed as in (a) above, but also maintain per-element + locks (that are acquired by both readers and writers) + that guard per-element state. Of course, fields that + the readers refrain from accessing can be guarded by the + update-side lock. + + This works quite well, also. + + c. Make updates appear atomic to readers. For example, pointer updates to properly aligned fields will appear atomic, as will individual atomic primitives. Operations performed under a lock and sequences of multiple atomic primitives will -not- appear to be atomic. - This is almost always the best approach. + This can work, but is starting to get a bit tricky. - b. Carefully order the updates and the reads so that + d. Carefully order the updates and the reads so that readers see valid data at all phases of the update. This is often more difficult than it sounds, especially given modern CPUs' tendency to reorder memory references. @@ -123,18 +142,22 @@ over a rather long period of time, but improvements are always welcome! when publicizing a pointer to a structure that can be traversed by an RCU read-side critical section. -5. If call_rcu(), or a related primitive such as call_rcu_bh(), - is used, the callback function must be written to be called - from softirq context. In particular, it cannot block. +5. If call_rcu(), or a related primitive such as call_rcu_bh() or + call_rcu_sched(), is used, the callback function must be + written to be called from softirq context. In particular, + it cannot block. 6. Since synchronize_rcu() can block, it cannot be called from - any sort of irq context. + any sort of irq context. Ditto for synchronize_sched() and + synchronize_srcu(). 7. If the updater uses call_rcu(), then the corresponding readers must use rcu_read_lock() and rcu_read_unlock(). If the updater uses call_rcu_bh(), then the corresponding readers must use - rcu_read_lock_bh() and rcu_read_unlock_bh(). Mixing things up - will result in confusion and broken kernels. + rcu_read_lock_bh() and rcu_read_unlock_bh(). If the updater + uses call_rcu_sched(), then the corresponding readers must + disable preemption. Mixing things up will result in confusion + and broken kernels. One exception to this rule: rcu_read_lock() and rcu_read_unlock() may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh() @@ -143,9 +166,9 @@ over a rather long period of time, but improvements are always welcome! such cases is a must, of course! And the jury is still out on whether the increased speed is worth it. -8. Although synchronize_rcu() is a bit slower than is call_rcu(), - it usually results in simpler code. So, unless update - performance is critically important or the updaters cannot block, +8. Although synchronize_rcu() is slower than is call_rcu(), it + usually results in simpler code. So, unless update performance + is critically important or the updaters cannot block, synchronize_rcu() should be used in preference to call_rcu(). An especially important property of the synchronize_rcu() @@ -187,23 +210,23 @@ over a rather long period of time, but improvements are always welcome! number of updates per grace period. 9. All RCU list-traversal primitives, which include - list_for_each_rcu(), list_for_each_entry_rcu(), + rcu_dereference(), list_for_each_rcu(), list_for_each_entry_rcu(), list_for_each_continue_rcu(), and list_for_each_safe_rcu(), - must be within an RCU read-side critical section. RCU + must be either within an RCU read-side critical section or + must be protected by appropriate update-side locks. RCU read-side critical sections are delimited by rcu_read_lock() and rcu_read_unlock(), or by similar primitives such as rcu_read_lock_bh() and rcu_read_unlock_bh(). - Use of the _rcu() list-traversal primitives outside of an - RCU read-side critical section causes no harm other than - a slight performance degradation on Alpha CPUs. It can - also be quite helpful in reducing code bloat when common - code is shared between readers and updaters. + The reason that it is permissible to use RCU list-traversal + primitives when the update-side lock is held is that doing so + can be quite helpful in reducing code bloat when common code is + shared between readers and updaters. 10. Conversely, if you are in an RCU read-side critical section, - you -must- use the "_rcu()" variants of the list macros. - Failing to do so will break Alpha and confuse people reading - your code. + and you don't hold the appropriate update-side lock, you -must- + use the "_rcu()" variants of the list macros. Failing to do so + will break Alpha and confuse people reading your code. 11. Note that synchronize_rcu() -only- guarantees to wait until all currently executing rcu_read_lock()-protected RCU read-side @@ -230,6 +253,14 @@ over a rather long period of time, but improvements are always welcome! must use whatever locking or other synchronization is required to safely access and/or modify that data structure. + RCU callbacks are -usually- executed on the same CPU that executed + the corresponding call_rcu(), call_rcu_bh(), or call_rcu_sched(), + but are by -no- means guaranteed to be. For example, if a given + CPU goes offline while having an RCU callback pending, then that + RCU callback will execute on some surviving CPU. (If this was + not the case, a self-spawning RCU callback would prevent the + victim CPU from ever going offline.) + 14. SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu()) may only be invoked from process context. Unlike other forms of RCU, it -is- permissible to block in an SRCU read-side critical diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index e0d6d99..e04d643 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -1,3 +1,11 @@ +Please note that the "What is RCU?" LWN series is an excellent place +to start learning about RCU: + +1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ +2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ +3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ + + What is RCU? RCU is a synchronization mechanism that was added to the Linux kernel @@ -772,26 +780,18 @@ Linux-kernel source code, but it helps to have a full list of the APIs, since there does not appear to be a way to categorize them in docbook. Here is the list, by category. -Markers for RCU read-side critical sections: - - rcu_read_lock - rcu_read_unlock - rcu_read_lock_bh - rcu_read_unlock_bh - srcu_read_lock - srcu_read_unlock - RCU pointer/list traversal: rcu_dereference + list_for_each_entry_rcu + hlist_for_each_entry_rcu + list_for_each_rcu (to be deprecated in favor of list_for_each_entry_rcu) - list_for_each_entry_rcu list_for_each_continue_rcu (to be deprecated in favor of new list_for_each_entry_continue_rcu) - hlist_for_each_entry_rcu -RCU pointer update: +RCU pointer/list update: rcu_assign_pointer list_add_rcu @@ -799,16 +799,36 @@ RCU pointer update: list_del_rcu list_replace_rcu hlist_del_rcu + hlist_add_after_rcu + hlist_add_before_rcu hlist_add_head_rcu + hlist_replace_rcu + list_splice_init_rcu() -RCU grace period: +RCU: Critical sections Grace period Barrier + + rcu_read_lock synchronize_net rcu_barrier + rcu_read_unlock synchronize_rcu + call_rcu + + +bh: Critical sections Grace period Barrier + + rcu_read_lock_bh call_rcu_bh rcu_barrier_bh + rcu_read_unlock_bh + + +sched: Critical sections Grace period Barrier + + [preempt_disable] synchronize_sched rcu_barrier_sched + [and friends] call_rcu_sched + + +SRCU: Critical sections Grace period Barrier + + srcu_read_lock synchronize_srcu N/A + srcu_read_unlock - synchronize_net - synchronize_sched - synchronize_rcu - synchronize_srcu - call_rcu - call_rcu_bh See the comment headers in the source code (or the docbook generated from them) for more information. -- cgit v0.10.2 From 82524746c27fa418c250a56dd7606b9d3fc79826 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 12 May 2008 21:21:05 +0200 Subject: rcu: split list.h and move rcu-protected lists into rculist.h Move rcu-protected lists from list.h into a new header file rculist.h. This is done because list are a very used primitive structure all over the kernel and it's currently impossible to include other header files in this list.h without creating some circular dependencies. For example, list.h implements rcu-protected list and uses rcu_dereference() without including rcupdate.h. It actually compiles because users of rcu_dereference() are macros. Others RCU functions could be used too but aren't probably because of this. Therefore this patch creates rculist.h which includes rcupdates without to many changes/troubles. Signed-off-by: Franck Bui-Huu Acked-by: Paul E. McKenney Acked-by: Josh Triplett Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 53351c3..96c31b4 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c index c6e772f..095c798 100644 --- a/crypto/async_tx/async_tx.c +++ b/crypto/async_tx/async_tx.c @@ -23,6 +23,7 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * */ +#include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index e0ec540..5d830d8 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "ipath_kernel.h" #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c index 9e5abf9..d73e322 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c @@ -31,8 +31,7 @@ * SOFTWARE. */ -#include -#include +#include #include "ipath_verbs.h" diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index c36a03a..860d75d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 2a66394..1f5cebf 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include diff --git a/include/linux/list.h b/include/linux/list.h index 08cf4f6..139ec41 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -85,65 +85,6 @@ static inline void list_add_tail(struct list_head *new, struct list_head *head) } /* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add_rcu(struct list_head * new, - struct list_head * prev, struct list_head * next) -{ - new->next = next; - new->prev = prev; - smp_wmb(); - next->prev = new; - prev->next = new; -} - -/** - * list_add_rcu - add a new entry to rcu-protected list - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as list_add_rcu() - * or list_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * list_for_each_entry_rcu(). - */ -static inline void list_add_rcu(struct list_head *new, struct list_head *head) -{ - __list_add_rcu(new, head, head->next); -} - -/** - * list_add_tail_rcu - add a new entry to rcu-protected list - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as list_add_tail_rcu() - * or list_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * list_for_each_entry_rcu(). - */ -static inline void list_add_tail_rcu(struct list_head *new, - struct list_head *head) -{ - __list_add_rcu(new, head->prev, head); -} - -/* * Delete a list entry by making the prev/next entries * point to each other. * @@ -174,36 +115,6 @@ extern void list_del(struct list_head *entry); #endif /** - * list_del_rcu - deletes entry from list without re-initialization - * @entry: the element to delete from the list. - * - * Note: list_empty() on entry does not return true after this, - * the entry is in an undefined state. It is useful for RCU based - * lockfree traversal. - * - * In particular, it means that we can not poison the forward - * pointers that may still be used for walking the list. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as list_del_rcu() - * or list_add_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * list_for_each_entry_rcu(). - * - * Note that the caller is not permitted to immediately free - * the newly deleted entry. Instead, either synchronize_rcu() - * or call_rcu() must be used to defer freeing until an RCU - * grace period has elapsed. - */ -static inline void list_del_rcu(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->prev = LIST_POISON2; -} - -/** * list_replace - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert @@ -227,25 +138,6 @@ static inline void list_replace_init(struct list_head *old, } /** - * list_replace_rcu - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * The @old entry will be replaced with the @new entry atomically. - * Note: @old should not be empty. - */ -static inline void list_replace_rcu(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->prev = old->prev; - smp_wmb(); - new->next->prev = new; - new->prev->next = new; - old->prev = LIST_POISON2; -} - -/** * list_del_init - deletes entry from list and reinitialize it. * @entry: the element to delete from the list. */ @@ -369,62 +261,6 @@ static inline void list_splice_init(struct list_head *list, } /** - * list_splice_init_rcu - splice an RCU-protected list into an existing list. - * @list: the RCU-protected list to splice - * @head: the place in the list to splice the first list into - * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ... - * - * @head can be RCU-read traversed concurrently with this function. - * - * Note that this function blocks. - * - * Important note: the caller must take whatever action is necessary to - * prevent any other updates to @head. In principle, it is possible - * to modify the list as soon as sync() begins execution. - * If this sort of thing becomes necessary, an alternative version - * based on call_rcu() could be created. But only if -really- - * needed -- there is no shortage of RCU API members. - */ -static inline void list_splice_init_rcu(struct list_head *list, - struct list_head *head, - void (*sync)(void)) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - if (list_empty(head)) - return; - - /* "first" and "last" tracking list, so initialize it. */ - - INIT_LIST_HEAD(list); - - /* - * At this point, the list body still points to the source list. - * Wait for any readers to finish using the list before splicing - * the list body into the new list. Any new readers will see - * an empty list. - */ - - sync(); - - /* - * Readers are finished with the source list, so perform splice. - * The order is important if the new list is global and accessible - * to concurrent RCU readers. Note that RCU readers are not - * permitted to traverse the prev pointers without excluding - * this function. - */ - - last->next = at; - smp_wmb(); - head->next = first; - first->prev = head; - at->prev = last; -} - -/** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. @@ -629,57 +465,6 @@ static inline void list_splice_init_rcu(struct list_head *list, &pos->member != (head); \ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) -/** - * list_for_each_rcu - iterate over an rcu-protected list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_rcu(pos, head) \ - for (pos = rcu_dereference((head)->next); \ - prefetch(pos->next), pos != (head); \ - pos = rcu_dereference(pos->next)) - -#define __list_for_each_rcu(pos, head) \ - for (pos = rcu_dereference((head)->next); \ - pos != (head); \ - pos = rcu_dereference(pos->next)) - -/** - * list_for_each_entry_rcu - iterate over rcu list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_entry_rcu(pos, head, member) \ - for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member)) - - -/** - * list_for_each_continue_rcu - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * Iterate over an rcu-protected list, continuing after current point. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_continue_rcu(pos, head) \ - for ((pos) = rcu_dereference((pos)->next); \ - prefetch((pos)->next), (pos) != (head); \ - (pos) = rcu_dereference((pos)->next)) - /* * Double linked lists with a single pointer list head. * Mostly useful for hash tables where the two pointer list head is @@ -730,31 +515,6 @@ static inline void hlist_del(struct hlist_node *n) n->pprev = LIST_POISON2; } -/** - * hlist_del_rcu - deletes entry from hash list without re-initialization - * @n: the element to delete from the hash list. - * - * Note: list_unhashed() on entry does not return true after this, - * the entry is in an undefined state. It is useful for RCU based - * lockfree traversal. - * - * In particular, it means that we can not poison the forward - * pointers that may still be used for walking the hash list. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry(). - */ -static inline void hlist_del_rcu(struct hlist_node *n) -{ - __hlist_del(n); - n->pprev = LIST_POISON2; -} - static inline void hlist_del_init(struct hlist_node *n) { if (!hlist_unhashed(n)) { @@ -763,27 +523,6 @@ static inline void hlist_del_init(struct hlist_node *n) } } -/** - * hlist_replace_rcu - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * The @old entry will be replaced with the @new entry atomically. - */ -static inline void hlist_replace_rcu(struct hlist_node *old, - struct hlist_node *new) -{ - struct hlist_node *next = old->next; - - new->next = next; - new->pprev = old->pprev; - smp_wmb(); - if (next) - new->next->pprev = &new->next; - *new->pprev = new; - old->pprev = LIST_POISON2; -} - static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; @@ -794,38 +533,6 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) n->pprev = &h->first; } - -/** - * hlist_add_head_rcu - * @n: the element to add to the hash list. - * @h: the list to add to. - * - * Description: - * Adds the specified element to the specified hlist, - * while permitting racing traversals. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry_rcu(), used to prevent memory-consistency - * problems on Alpha CPUs. Regardless of the type of CPU, the - * list-traversal primitive must be guarded by rcu_read_lock(). - */ -static inline void hlist_add_head_rcu(struct hlist_node *n, - struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - n->pprev = &h->first; - smp_wmb(); - if (first) - first->pprev = &n->next; - h->first = n; -} - /* next must be != NULL */ static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) @@ -847,63 +554,6 @@ static inline void hlist_add_after(struct hlist_node *n, next->next->pprev = &next->next; } -/** - * hlist_add_before_rcu - * @n: the new element to add to the hash list. - * @next: the existing element to add the new element before. - * - * Description: - * Adds the specified element to the specified hlist - * before the specified node while permitting racing traversals. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry_rcu(), used to prevent memory-consistency - * problems on Alpha CPUs. - */ -static inline void hlist_add_before_rcu(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - smp_wmb(); - next->pprev = &n->next; - *(n->pprev) = n; -} - -/** - * hlist_add_after_rcu - * @prev: the existing element to add the new element after. - * @n: the new element to add to the hash list. - * - * Description: - * Adds the specified element to the specified hlist - * after the specified node while permitting racing traversals. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry_rcu(), used to prevent memory-consistency - * problems on Alpha CPUs. - */ -static inline void hlist_add_after_rcu(struct hlist_node *prev, - struct hlist_node *n) -{ - n->next = prev->next; - n->pprev = &prev->next; - smp_wmb(); - prev->next = n; - if (n->next) - n->next->pprev = &n->next; -} - #define hlist_entry(ptr, type, member) container_of(ptr,type,member) #define hlist_for_each(pos, head) \ @@ -964,21 +614,4 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = n) -/** - * hlist_for_each_entry_rcu - iterate over rcu list of given type - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as hlist_add_head_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define hlist_for_each_entry_rcu(tpos, pos, head, member) \ - for (pos = rcu_dereference((head)->first); \ - pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = rcu_dereference(pos->next)) - #endif diff --git a/include/linux/rculist.h b/include/linux/rculist.h new file mode 100644 index 0000000..aa9b3eb --- /dev/null +++ b/include/linux/rculist.h @@ -0,0 +1,396 @@ +#ifndef _LINUX_RCULIST_H +#define _LINUX_RCULIST_H + +#ifdef __KERNEL__ + +/* + * RCU-protected list version + */ +#include + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add_rcu(struct list_head *new, + struct list_head *prev, struct list_head *next) +{ + new->next = next; + new->prev = prev; + smp_wmb(); + next->prev = new; + prev->next = new; +} + +/** + * list_add_rcu - add a new entry to rcu-protected list + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as list_add_rcu() + * or list_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * list_for_each_entry_rcu(). + */ +static inline void list_add_rcu(struct list_head *new, struct list_head *head) +{ + __list_add_rcu(new, head, head->next); +} + +/** + * list_add_tail_rcu - add a new entry to rcu-protected list + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as list_add_tail_rcu() + * or list_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * list_for_each_entry_rcu(). + */ +static inline void list_add_tail_rcu(struct list_head *new, + struct list_head *head) +{ + __list_add_rcu(new, head->prev, head); +} + +/** + * list_del_rcu - deletes entry from list without re-initialization + * @entry: the element to delete from the list. + * + * Note: list_empty() on entry does not return true after this, + * the entry is in an undefined state. It is useful for RCU based + * lockfree traversal. + * + * In particular, it means that we can not poison the forward + * pointers that may still be used for walking the list. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as list_del_rcu() + * or list_add_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * list_for_each_entry_rcu(). + * + * Note that the caller is not permitted to immediately free + * the newly deleted entry. Instead, either synchronize_rcu() + * or call_rcu() must be used to defer freeing until an RCU + * grace period has elapsed. + */ +static inline void list_del_rcu(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->prev = LIST_POISON2; +} + +/** + * list_replace_rcu - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * The @old entry will be replaced with the @new entry atomically. + * Note: @old should not be empty. + */ +static inline void list_replace_rcu(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->prev = old->prev; + smp_wmb(); + new->next->prev = new; + new->prev->next = new; + old->prev = LIST_POISON2; +} + +/** + * list_splice_init_rcu - splice an RCU-protected list into an existing list. + * @list: the RCU-protected list to splice + * @head: the place in the list to splice the first list into + * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ... + * + * @head can be RCU-read traversed concurrently with this function. + * + * Note that this function blocks. + * + * Important note: the caller must take whatever action is necessary to + * prevent any other updates to @head. In principle, it is possible + * to modify the list as soon as sync() begins execution. + * If this sort of thing becomes necessary, an alternative version + * based on call_rcu() could be created. But only if -really- + * needed -- there is no shortage of RCU API members. + */ +static inline void list_splice_init_rcu(struct list_head *list, + struct list_head *head, + void (*sync)(void)) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + if (list_empty(head)) + return; + + /* "first" and "last" tracking list, so initialize it. */ + + INIT_LIST_HEAD(list); + + /* + * At this point, the list body still points to the source list. + * Wait for any readers to finish using the list before splicing + * the list body into the new list. Any new readers will see + * an empty list. + */ + + sync(); + + /* + * Readers are finished with the source list, so perform splice. + * The order is important if the new list is global and accessible + * to concurrent RCU readers. Note that RCU readers are not + * permitted to traverse the prev pointers without excluding + * this function. + */ + + last->next = at; + smp_wmb(); + head->next = first; + first->prev = head; + at->prev = last; +} + +/** + * list_for_each_rcu - iterate over an rcu-protected list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as list_add_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +#define list_for_each_rcu(pos, head) \ + for (pos = (head)->next; \ + prefetch(rcu_dereference(pos)->next), pos != (head); \ + pos = pos->next) + +#define __list_for_each_rcu(pos, head) \ + for (pos = (head)->next; \ + rcu_dereference(pos) != (head); \ + pos = pos->next) + +/** + * list_for_each_safe_rcu + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + * + * Iterate over an rcu-protected list, safe against removal of list entry. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as list_add_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +#define list_for_each_safe_rcu(pos, n, head) \ + for (pos = (head)->next; \ + n = rcu_dereference(pos)->next, pos != (head); \ + pos = n) + +/** + * list_for_each_entry_rcu - iterate over rcu list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as list_add_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +#define list_for_each_entry_rcu(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + prefetch(rcu_dereference(pos)->member.next), \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + + +/** + * list_for_each_continue_rcu + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + * + * Iterate over an rcu-protected list, continuing after current point. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as list_add_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +#define list_for_each_continue_rcu(pos, head) \ + for ((pos) = (pos)->next; \ + prefetch(rcu_dereference((pos))->next), (pos) != (head); \ + (pos) = (pos)->next) + +/** + * hlist_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. + * + * Note: list_unhashed() on entry does not return true after this, + * the entry is in an undefined state. It is useful for RCU based + * lockfree traversal. + * + * In particular, it means that we can not poison the forward + * pointers that may still be used for walking the hash list. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as hlist_add_head_rcu() + * or hlist_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * hlist_for_each_entry(). + */ +static inline void hlist_del_rcu(struct hlist_node *n) +{ + __hlist_del(n); + n->pprev = LIST_POISON2; +} + +/** + * hlist_replace_rcu - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * The @old entry will be replaced with the @new entry atomically. + */ +static inline void hlist_replace_rcu(struct hlist_node *old, + struct hlist_node *new) +{ + struct hlist_node *next = old->next; + + new->next = next; + new->pprev = old->pprev; + smp_wmb(); + if (next) + new->next->pprev = &new->next; + *new->pprev = new; + old->pprev = LIST_POISON2; +} + +/** + * hlist_add_head_rcu + * @n: the element to add to the hash list. + * @h: the list to add to. + * + * Description: + * Adds the specified element to the specified hlist, + * while permitting racing traversals. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as hlist_add_head_rcu() + * or hlist_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * hlist_for_each_entry_rcu(), used to prevent memory-consistency + * problems on Alpha CPUs. Regardless of the type of CPU, the + * list-traversal primitive must be guarded by rcu_read_lock(). + */ +static inline void hlist_add_head_rcu(struct hlist_node *n, + struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + n->pprev = &h->first; + smp_wmb(); + if (first) + first->pprev = &n->next; + h->first = n; +} + +/** + * hlist_add_before_rcu + * @n: the new element to add to the hash list. + * @next: the existing element to add the new element before. + * + * Description: + * Adds the specified element to the specified hlist + * before the specified node while permitting racing traversals. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as hlist_add_head_rcu() + * or hlist_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * hlist_for_each_entry_rcu(), used to prevent memory-consistency + * problems on Alpha CPUs. + */ +static inline void hlist_add_before_rcu(struct hlist_node *n, + struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + smp_wmb(); + next->pprev = &n->next; + *(n->pprev) = n; +} + +/** + * hlist_add_after_rcu + * @prev: the existing element to add the new element after. + * @n: the new element to add to the hash list. + * + * Description: + * Adds the specified element to the specified hlist + * after the specified node while permitting racing traversals. + * + * The caller must take whatever precautions are necessary + * (such as holding appropriate locks) to avoid racing + * with another list-mutation primitive, such as hlist_add_head_rcu() + * or hlist_del_rcu(), running on this same list. + * However, it is perfectly legal to run concurrently with + * the _rcu list-traversal primitives, such as + * hlist_for_each_entry_rcu(), used to prevent memory-consistency + * problems on Alpha CPUs. + */ +static inline void hlist_add_after_rcu(struct hlist_node *prev, + struct hlist_node *n) +{ + n->next = prev->next; + n->pprev = &prev->next; + smp_wmb(); + prev->next = n; + if (n->next) + n->next->pprev = &n->next; +} + +/** + * hlist_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_head_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + */ +#define hlist_for_each_entry_rcu(tpos, pos, head, member) \ + for (pos = (head)->first; \ + rcu_dereference(pos) && ({ prefetch(pos->next); 1; }) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ + pos = pos->next) + +#endif /* __KERNEL__ */ +#endif diff --git a/kernel/pid.c b/kernel/pid.c index 20d59fa..30bd5d4 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/lib/textsearch.c b/lib/textsearch.c index be8bda3..a3e500a 100644 --- a/lib/textsearch.c +++ b/lib/textsearch.c @@ -97,6 +97,7 @@ #include #include #include +#include #include #include #include diff --git a/net/802/psnap.c b/net/802/psnap.c index 31128cb..ea46439 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -20,6 +20,7 @@ #include #include #include +#include static LIST_HEAD(snap_list); static DEFINE_SPINLOCK(snap_lock); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 2a739ad..e7ddbfa 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 72c5976..142060f 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index e38034a..9e96ffc 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -13,6 +13,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include "br_private.h" #include "br_private_stp.h" diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 02c2f7c..643c032 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -30,8 +30,7 @@ */ #include -#include -#include +#include #include #include #include -- cgit v0.10.2 From 10aa9d2cf9878757b003023d33ff90a37aa3044b Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Mon, 12 May 2008 21:21:06 +0200 Subject: rculist.h: use the rcu API Make almost all list mutation primitives use rcu_assign_pointer(). The main point of this being readability improvement. Signed-off-by: Franck Bui-Huu Cc: "Paul E. McKenney" Cc: Josh Triplett Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/include/linux/rculist.h b/include/linux/rculist.h index aa9b3eb..8d2c81f 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -7,6 +7,7 @@ * RCU-protected list version */ #include +#include /* * Insert a new entry between two known consecutive entries. @@ -19,9 +20,8 @@ static inline void __list_add_rcu(struct list_head *new, { new->next = next; new->prev = prev; - smp_wmb(); + rcu_assign_pointer(prev->next, new); next->prev = new; - prev->next = new; } /** @@ -110,9 +110,8 @@ static inline void list_replace_rcu(struct list_head *old, { new->next = old->next; new->prev = old->prev; - smp_wmb(); + rcu_assign_pointer(new->prev->next, new); new->next->prev = new; - new->prev->next = new; old->prev = LIST_POISON2; } @@ -166,8 +165,7 @@ static inline void list_splice_init_rcu(struct list_head *list, */ last->next = at; - smp_wmb(); - head->next = first; + rcu_assign_pointer(head->next, first); first->prev = head; at->prev = last; } @@ -280,10 +278,9 @@ static inline void hlist_replace_rcu(struct hlist_node *old, new->next = next; new->pprev = old->pprev; - smp_wmb(); + rcu_assign_pointer(*new->pprev, new); if (next) new->next->pprev = &new->next; - *new->pprev = new; old->pprev = LIST_POISON2; } @@ -310,12 +307,12 @@ static inline void hlist_add_head_rcu(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; + n->next = first; n->pprev = &h->first; - smp_wmb(); + rcu_assign_pointer(h->first, n); if (first) first->pprev = &n->next; - h->first = n; } /** @@ -341,9 +338,8 @@ static inline void hlist_add_before_rcu(struct hlist_node *n, { n->pprev = next->pprev; n->next = next; - smp_wmb(); + rcu_assign_pointer(*(n->pprev), n); next->pprev = &n->next; - *(n->pprev) = n; } /** @@ -369,8 +365,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, { n->next = prev->next; n->pprev = &prev->next; - smp_wmb(); - prev->next = n; + rcu_assign_pointer(prev->next, n); if (n->next) n->next->pprev = &n->next; } -- cgit v0.10.2 From d7c0651390b6a03ad53f99faec0ba88109d7191d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:06 +0200 Subject: rcu: fix rcu_try_flip_waitack_needed() to prevent grace-period stall The comment was correct -- need to make the code match the comment. Without this patch, if a CPU goes dynticks idle (and stays there forever) in just the right phase of preemptible-RCU grace-period processing, grace periods stall. The offending sequence of events (courtesy of Promela/spin, at least after I got the liveness criterion coded correctly...) is as follows: o CPU 0 is in dynticks-idle mode. Its dynticks_progress_counter is (say) 10. o CPU 0 takes an interrupt, so rcu_irq_enter() increments CPU 0's dynticks_progress_counter to 11. o CPU 1 is doing RCU grace-period processing in rcu_try_flip_idle(), sees rcu_pending(), so invokes dyntick_save_progress_counter(), which in turn takes a snapshot of CPU 0's dynticks_progress_counter into CPU 0's rcu_dyntick_snapshot -- now set to 11. CPU 1 then updates the RCU grace-period state to rcu_try_flip_waitack(). o CPU 0 returns from its interrupt, so rcu_irq_exit() increments CPU 0's dynticks_progress_counter to 12. o CPU 1 later invokes rcu_try_flip_waitack(), which notices that CPU 0 has not yet responded, and hence in turn invokes rcu_try_flip_waitack_needed(). This function examines the state of CPU 0's dynticks_progress_counter and rcu_dyntick_snapshot variables, which it copies to curr (== 12) and snap (== 11), respectively. Because curr!=snap, the first condition fails. Because curr-snap is only 1 and snap is odd, the second condition fails. rcu_try_flip_waitack_needed() therefore incorrectly concludes that it must wait for CPU 0 to explicitly acknowledge the counter flip. o CPU 0 remains forever in dynticks-idle mode, never taking any more hardware interrupts or any NMIs, and never running any more tasks. (Of course, -something- will usually eventually happen, which might be why we haven't seen this one in the wild. Still should be fixed!) Therefore the grace period never ends. Fix is to make the code match the comment, as shown below. With this fix, the above scenario would be satisfied with curr being even, and allow the grace period to proceed. Signed-off-by: Paul E. McKenney Cc: Peter Zijlstra Cc: Josh Triplett Cc: Dipankar Sarma Cc: Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index aaa7976..27d0748 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -597,7 +597,7 @@ rcu_try_flip_waitack_needed(int cpu) * that this CPU already acknowledged the counter. */ - if ((curr - snap) > 2 || (snap & 0x1) == 0) + if ((curr - snap) > 2 || (curr & 0x1) == 0) return 0; /* We need this CPU to explicitly acknowledge the counter flip. */ -- cgit v0.10.2 From 78b0e0e9b27b62c4b22f05a147f7a80fa58b1ae3 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 12 May 2008 21:21:06 +0200 Subject: RCU, rculist.h: fix list iterators RCU list iterators: should prefetch ever be optimised out with no side-effects, the current version will lose the barrier completely. Pointed-out-by: Linus Torvalds Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 8d2c81f..b0f39be 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -180,31 +180,14 @@ static inline void list_splice_init_rcu(struct list_head *list, * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_rcu(pos, head) \ - for (pos = (head)->next; \ - prefetch(rcu_dereference(pos)->next), pos != (head); \ - pos = pos->next) + for (pos = rcu_dereference((head)->next); \ + prefetch(pos->next), pos != (head); \ + pos = rcu_dereference(pos->next)) #define __list_for_each_rcu(pos, head) \ - for (pos = (head)->next; \ - rcu_dereference(pos) != (head); \ - pos = pos->next) - -/** - * list_for_each_safe_rcu - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - * - * Iterate over an rcu-protected list, safe against removal of list entry. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_safe_rcu(pos, n, head) \ - for (pos = (head)->next; \ - n = rcu_dereference(pos)->next, pos != (head); \ - pos = n) + for (pos = rcu_dereference((head)->next); \ + pos != (head); \ + pos = rcu_dereference(pos->next)) /** * list_for_each_entry_rcu - iterate over rcu list of given type @@ -217,10 +200,9 @@ static inline void list_splice_init_rcu(struct list_head *list, * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_entry_rcu(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(rcu_dereference(pos)->member.next), \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \ + prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member)) /** @@ -235,9 +217,9 @@ static inline void list_splice_init_rcu(struct list_head *list, * as long as the traversal is guarded by rcu_read_lock(). */ #define list_for_each_continue_rcu(pos, head) \ - for ((pos) = (pos)->next; \ - prefetch(rcu_dereference((pos))->next), (pos) != (head); \ - (pos) = (pos)->next) + for ((pos) = rcu_dereference((pos)->next); \ + prefetch((pos)->next), (pos) != (head); \ + (pos) = rcu_dereference((pos)->next)) /** * hlist_del_rcu - deletes entry from hash list without re-initialization @@ -382,10 +364,10 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, * as long as the traversal is guarded by rcu_read_lock(). */ #define hlist_for_each_entry_rcu(tpos, pos, head, member) \ - for (pos = (head)->first; \ - rcu_dereference(pos) && ({ prefetch(pos->next); 1; }) && \ + for (pos = rcu_dereference((head)->first); \ + pos && ({ prefetch(pos->next); 1; }) && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) + pos = rcu_dereference(pos->next)) #endif /* __KERNEL__ */ #endif -- cgit v0.10.2 From e19a98967f49cb63352b3db4818983ea2cec24ba Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 14 May 2008 16:23:00 -0700 Subject: rcu: remove duplicated include in kernel/rcupreempt_trace.c Removed duplicated include file in kernel/rcupreempt_trace.c Signed-off-by: Huang Weiyi Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/rcupreempt_trace.c b/kernel/rcupreempt_trace.c index 49ac4947..5edf82c 100644 --- a/kernel/rcupreempt_trace.c +++ b/kernel/rcupreempt_trace.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 247ab1a80595100bd7ea61d174f8b7b7e5f8d4bb Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 14 May 2008 16:23:00 -0700 Subject: rcu: remove duplicated include in kernel/rcupreempt.c Removed duplicated include file in kernel/rcupreempt.c. Signed-off-by: Huang Weiyi Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 27d0748..b8e4cda 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 711bbdd659b685b45d3f28b29a00f17be6484f38 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 17 May 2008 08:26:25 +0200 Subject: rculist.h: fix include in net/netfilter/nf_conntrack_netlink.c this file has rculist dependency but did not explicitly include it, which broke the build. Signed-off-by: Ingo Molnar diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 0edefcf..077bcd2 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 4f9c16ccfa26691dbb9a5d9e7d5098eb934ccdbe Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 30 Apr 2008 16:20:19 +0200 Subject: [ALSA] soc - tlv320aic3x - revisit clock setup This patch cleans up the clocking setup for aic3x codecs. It drops the dividers table and determines the PLL control values programatically. Under certain conditions, the PLL is disabled entirely which could save some power. Signed-off-by: Daniel Mack Acked-by: Jarkko Nikula Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 09b1661..738b3b6 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -49,7 +49,7 @@ #include "tlv320aic3x.h" #define AUDIO_NAME "aic3x" -#define AIC3X_VERSION "0.1" +#define AIC3X_VERSION "0.2" /* codec private data */ struct aic3x_priv { @@ -648,81 +648,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec) return 0; } -struct aic3x_rate_divs { - u32 mclk; - u32 rate; - u32 fsref_reg; - u8 sr_reg:4; - u8 pllj_reg; - u16 plld_reg; -}; - -/* AIC3X codec mclk clock divider coefficients */ -static const struct aic3x_rate_divs aic3x_divs[] = { - /* 8k */ - {12000000, 8000, 48000, 0xa, 16, 3840}, - {19200000, 8000, 48000, 0xa, 10, 2400}, - {22579200, 8000, 48000, 0xa, 8, 7075}, - {33868800, 8000, 48000, 0xa, 5, 8049}, - /* 11.025k */ - {12000000, 11025, 44100, 0x6, 15, 528}, - {19200000, 11025, 44100, 0x6, 9, 4080}, - {22579200, 11025, 44100, 0x6, 8, 0}, - {33868800, 11025, 44100, 0x6, 5, 3333}, - /* 16k */ - {12000000, 16000, 48000, 0x4, 16, 3840}, - {19200000, 16000, 48000, 0x4, 10, 2400}, - {22579200, 16000, 48000, 0x4, 8, 7075}, - {33868800, 16000, 48000, 0x4, 5, 8049}, - /* 22.05k */ - {12000000, 22050, 44100, 0x2, 15, 528}, - {19200000, 22050, 44100, 0x2, 9, 4080}, - {22579200, 22050, 44100, 0x2, 8, 0}, - {33868800, 22050, 44100, 0x2, 5, 3333}, - /* 32k */ - {12000000, 32000, 48000, 0x1, 16, 3840}, - {19200000, 32000, 48000, 0x1, 10, 2400}, - {22579200, 32000, 48000, 0x1, 8, 7075}, - {33868800, 32000, 48000, 0x1, 5, 8049}, - /* 44.1k */ - {12000000, 44100, 44100, 0x0, 15, 528}, - {19200000, 44100, 44100, 0x0, 9, 4080}, - {22579200, 44100, 44100, 0x0, 8, 0}, - {33868800, 44100, 44100, 0x0, 5, 3333}, - /* 48k */ - {12000000, 48000, 48000, 0x0, 16, 3840}, - {19200000, 48000, 48000, 0x0, 10, 2400}, - {22579200, 48000, 48000, 0x0, 8, 7075}, - {33868800, 48000, 48000, 0x0, 5, 8049}, - /* 64k */ - {12000000, 64000, 96000, 0x1, 16, 3840}, - {19200000, 64000, 96000, 0x1, 10, 2400}, - {22579200, 64000, 96000, 0x1, 8, 7075}, - {33868800, 64000, 96000, 0x1, 5, 8049}, - /* 88.2k */ - {12000000, 88200, 88200, 0x0, 15, 528}, - {19200000, 88200, 88200, 0x0, 9, 4080}, - {22579200, 88200, 88200, 0x0, 8, 0}, - {33868800, 88200, 88200, 0x0, 5, 3333}, - /* 96k */ - {12000000, 96000, 96000, 0x0, 16, 3840}, - {19200000, 96000, 96000, 0x0, 10, 2400}, - {22579200, 96000, 96000, 0x0, 8, 7075}, - {33868800, 96000, 96000, 0x0, 5, 8049}, -}; - -static inline int aic3x_get_divs(int mclk, int rate) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(aic3x_divs); i++) { - if (aic3x_divs[i].rate == rate && aic3x_divs[i].mclk == mclk) - return i; - } - - return 0; -} - static int aic3x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -730,49 +655,107 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_codec *codec = socdev->codec; struct aic3x_priv *aic3x = codec->private_data; - int i; - u8 data, pll_p, pll_r, pll_j; - u16 pll_d; - - i = aic3x_get_divs(aic3x->sysclk, params_rate(params)); + int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; + u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; + u16 pll_d = 1; - /* Route Left DAC to left channel input and - * right DAC to right channel input */ - data = (LDAC2LCH | RDAC2RCH); - switch (aic3x_divs[i].fsref_reg) { - case 44100: - data |= FSREF_44100; + /* select data word length */ + data = + aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: break; - case 48000: - data |= FSREF_48000; + case SNDRV_PCM_FORMAT_S20_3LE: + data |= (0x01 << 4); break; - case 88200: - data |= FSREF_44100 | DUAL_RATE_MODE; + case SNDRV_PCM_FORMAT_S24_LE: + data |= (0x02 << 4); break; - case 96000: - data |= FSREF_48000 | DUAL_RATE_MODE; + case SNDRV_PCM_FORMAT_S32_LE: + data |= (0x03 << 4); break; } + aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data); + + /* Fsref can be 44100 or 48000 */ + fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000; + + /* Try to find a value for Q which allows us to bypass the PLL and + * generate CODEC_CLK directly. */ + for (pll_q = 2; pll_q < 18; pll_q++) + if (aic3x->sysclk / (128 * pll_q) == fsref) { + bypass_pll = 1; + break; + } + + if (bypass_pll) { + pll_q &= 0xf; + aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT); + aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV); + } else + aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV); + + /* Route Left DAC to left channel input and + * right DAC to right channel input */ + data = (LDAC2LCH | RDAC2RCH); + data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000; + if (params_rate(params) >= 64000) + data |= DUAL_RATE_MODE; aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data); /* codec sample rate select */ - data = aic3x_divs[i].sr_reg; + data = (fsref * 20) / params_rate(params); + if (params_rate(params) < 64000) + data /= 2; + data /= 5; + data -= 2; data |= (data << 4); aic3x_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data); - /* Use PLL for generation Fsref by equation: - * Fsref = (MCLK * K * R)/(2048 * P); - * Fix P = 2 and R = 1 and calculate K, if - * K = J.D, i.e. J - an interger portion of K and D is the fractional - * one with 4 digits of precision; - * Example: - * For MCLK = 22.5792 MHz and Fsref = 48kHz: - * Select P = 2, R= 1, K = 8.7074, which results in J = 8, D = 7074 + if (bypass_pll) + return 0; + + /* Use PLL + * find an apropriate setup for j, d, r and p by iterating over + * p and r - j and d are calculated for each fraction. + * Up to 128 values are probed, the closest one wins the game. + * The sysclk is divided by 1000 to prevent integer overflows. */ - pll_p = 2; - pll_r = 1; - pll_j = aic3x_divs[i].pllj_reg; - pll_d = aic3x_divs[i].plld_reg; + codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000); + + for (r = 1; r <= 16; r++) + for (p = 1; p <= 8; p++) { + int clk, tmp = (codec_clk * pll_r * 10) / pll_p; + u8 j = tmp / 10000; + u16 d = tmp % 10000; + + if (j > 63) + continue; + + if (d != 0 && aic3x->sysclk < 10000000) + continue; + + /* This is actually 1000 * ((j + (d/10000)) * r) / p + * The term had to be converted to get rid of the + * division by 10000 */ + clk = ((10000 * j * r) + (d * r)) / (10 * p); + + /* check whether this values get closer than the best + * ones we had before */ + if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) { + pll_j = j; pll_d = d; pll_r = r; pll_p = p; + last_clk = clk; + } + + /* Early exit for exact matches */ + if (clk == codec_clk) + break; + } + + if (last_clk == 0) { + printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); + return -EINVAL; + } data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); @@ -782,24 +765,6 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, aic3x_write(codec, AIC3X_PLL_PROGD_REG, (pll_d & 0x3F) << PLLD_LSB_SHIFT); - /* select data word length */ - data = - aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - data |= (0x01 << 4); - break; - case SNDRV_PCM_FORMAT_S24_LE: - data |= (0x02 << 4); - break; - case SNDRV_PCM_FORMAT_S32_LE: - data |= (0x03 << 4); - break; - } - aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data); - return 0; } @@ -826,16 +791,8 @@ static int aic3x_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; struct aic3x_priv *aic3x = codec->private_data; - switch (freq) { - case 12000000: - case 19200000: - case 22579200: - case 33868800: - aic3x->sysclk = freq; - return 0; - } - - return -EINVAL; + aic3x->sysclk = freq; + return 0; } static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index d0cdeeb..d49d001 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -109,6 +109,7 @@ #define LLOPM_CTRL 86 #define RLOPM_CTRL 93 /* Clock generation control register */ +#define AIC3X_GPIOB_REG 101 #define AIC3X_CLKGEN_CTRL_REG 102 /* Page select register bits */ @@ -128,12 +129,15 @@ /* PLL registers bitfields */ #define PLLP_SHIFT 0 +#define PLLQ_SHIFT 3 #define PLLR_SHIFT 0 #define PLLJ_SHIFT 2 #define PLLD_MSB_SHIFT 0 #define PLLD_LSB_SHIFT 2 /* Clock generation register bits */ +#define CODEC_CLKIN_PLLDIV 0 +#define CODEC_CLKIN_CLKDIV 1 #define PLL_CLKIN_SHIFT 4 #define MCLK_SOURCE 0x0 #define PLL_CLKDIV_SHIFT 0 -- cgit v0.10.2 From 54e7e6167d29a4a98207884b2fbd28b0b3fe91f6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 30 Apr 2008 16:20:52 +0200 Subject: [ALSA] soc - tlv320aic3x - add GPIO support This patch adds support for AIC3x GPIO lines. They can be configured for many possible functions as well as be driven manually. I also introduced i2c read functionality since the GPIO state register has to be read from hardware every time and can not be served from cache. Signed-off-by: Daniel Mack Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 738b3b6..957996e 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -138,6 +138,20 @@ static int aic3x_write(struct snd_soc_codec *codec, unsigned int reg, return -EIO; } +/* + * read from the aic3x register space + */ +static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg, + u8 *value) +{ + *value = reg & 0xff; + if (codec->hw_read(codec->control_data, value, 1) != 1) + return -EIO; + + aic3x_write_reg_cache(codec, reg, *value); + return 0; +} + #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ @@ -911,6 +925,33 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event) return 0; } +void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state) +{ + u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; + u8 bit = gpio ? 3: 0; + u8 val = aic3x_read_reg_cache(codec, reg) & ~(1 << bit); + aic3x_write(codec, reg, val | (!!state << bit)); +} +EXPORT_SYMBOL_GPL(aic3x_set_gpio); + +int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio) +{ + u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; + u8 val, bit = gpio ? 2: 1; + + aic3x_read(codec, reg, &val); + return (val >> bit) & 1; +} +EXPORT_SYMBOL_GPL(aic3x_get_gpio); + +int aic3x_headset_detected(struct snd_soc_codec *codec) +{ + u8 val; + aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val); + return (val >> 2) & 1; +} +EXPORT_SYMBOL_GPL(aic3x_headset_detected); + #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) @@ -977,6 +1018,7 @@ static int aic3x_resume(struct platform_device *pdev) static int aic3x_init(struct snd_soc_device *socdev) { struct snd_soc_codec *codec = socdev->codec; + struct aic3x_setup_data *setup = socdev->codec_data; int reg, ret = 0; codec->name = "aic3x"; @@ -1067,6 +1109,10 @@ static int aic3x_init(struct snd_soc_device *socdev) /* off, with power on */ aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + /* setup GPIO functions */ + aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); + aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); + aic3x_add_controls(codec); aic3x_add_widgets(codec); ret = snd_soc_register_card(socdev); @@ -1174,6 +1220,12 @@ static struct i2c_client client_template = { .name = "AIC3X", .driver = &aic3x_i2c_driver, }; + +static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) +{ + value[0] = i2c_smbus_read_byte_data(client, value[0]); + return (len == 1); +} #endif static int aic3x_probe(struct platform_device *pdev) @@ -1208,6 +1260,7 @@ static int aic3x_probe(struct platform_device *pdev) if (setup->i2c_address) { normal_i2c[0] = setup->i2c_address; codec->hw_write = (hw_write_t) i2c_master_send; + codec->hw_read = (hw_read_t) aic3x_i2c_read; ret = i2c_add_driver(&aic3x_i2c_driver); if (ret != 0) printk(KERN_ERR "can't add i2c driver"); diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index d49d001..c1dd1ac 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -108,8 +108,14 @@ #define DACR1_2_RLOPM_VOL 92 #define LLOPM_CTRL 86 #define RLOPM_CTRL 93 -/* Clock generation control register */ +/* GPIO/IRQ registers */ +#define AIC3X_STICKY_IRQ_FLAGS_REG 96 +#define AIC3X_RT_IRQ_FLAGS_REG 97 +#define AIC3X_GPIO1_REG 98 +#define AIC3X_GPIO2_REG 99 +#define AIC3X_GPIOA_REG 100 #define AIC3X_GPIOB_REG 101 +/* Clock generation control register */ #define AIC3X_CLKGEN_CTRL_REG 102 /* Page select register bits */ @@ -175,8 +181,49 @@ /* Default input volume */ #define DEFAULT_GAIN 0x20 +/* GPIO API */ +enum { + AIC3X_GPIO1_FUNC_DISABLED = 0, + AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1, + AIC3X_GPIO1_FUNC_CLOCK_MUX = 2, + AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3, + AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4, + AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5, + AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6, + AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7, + AIC3X_GPIO1_FUNC_INPUT = 8, + AIC3X_GPIO1_FUNC_OUTPUT = 9, + AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10, + AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11, + AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12, + AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13, + AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14, + AIC3X_GPIO1_FUNC_ALL_IRQ = 16 +}; + +enum { + AIC3X_GPIO2_FUNC_DISABLED = 0, + AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2, + AIC3X_GPIO2_FUNC_INPUT = 3, + AIC3X_GPIO2_FUNC_OUTPUT = 4, + AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5, + AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8, + AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9, + AIC3X_GPIO2_FUNC_ALL_IRQ = 10, + AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11, + AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12, + AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13, + AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14, + AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15 +}; + +void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); +int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); +int aic3x_headset_detected(struct snd_soc_codec *codec); + struct aic3x_setup_data { unsigned short i2c_address; + unsigned int gpio_func[2]; }; extern struct snd_soc_codec_dai aic3x_dai; -- cgit v0.10.2 From eeec12bf7b7d80d1c9cae5aae0dff7e2f928c64b Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 30 Apr 2008 19:27:40 +0200 Subject: [ALSA] soc - DAPM - add hook to read state of DAPM widget This adds a hook to read the power state of a DAPM widget, I use this in the gta02 driver to expose certain DAPM widgets in the mixer for ease of audio routing. Signed-off-by: Graeme Gregory Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index a105b01..40cc695 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -223,6 +223,8 @@ int snd_soc_dapm_sys_add(struct device *dev); /* 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_status(struct snd_soc_codec *codec, + char *pin); int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec); /* dapm widget types */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index af3326c..9fd5ee8 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1343,6 +1343,29 @@ int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, EXPORT_SYMBOL_GPL(snd_soc_dapm_set_endpoint); /** + * snd_soc_dapm_get_endpoint_status - 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_status(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_free - free dapm resources * @socdev: SoC device * -- cgit v0.10.2 From 650f6b13318bce6a8d59bfa48fe15b5832623cbc Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 1 May 2008 10:49:18 +0200 Subject: [ALSA] sound: fix export symbol typo Signed-off-by: Stephen Rothwell Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 9fd5ee8..c60200c 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1363,7 +1363,7 @@ int snd_soc_dapm_get_endpoint_status(struct snd_soc_codec *codec, return 0; } -EXPORT_SYMBOL_GPL(snd_soc_dapm_get_endpoint); +EXPORT_SYMBOL_GPL(snd_soc_dapm_get_endpoint_status); /** * snd_soc_dapm_free - free dapm resources -- cgit v0.10.2 From 1894c59fdb63692f5ba2576875cc558b856935ca Mon Sep 17 00:00:00 2001 From: Tim Niemeyer Date: Mon, 5 May 2008 14:16:12 +0200 Subject: [ALSA] soc - Patch to add debug messages to the neo1973_wm8753 (GTA01) sound driver Signed-off-by: Tim Niemeyer Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 0e9d1c5..e469186 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -43,6 +43,14 @@ #include "s3c24xx-pcm.h" #include "s3c24xx-i2s.h" +/* Debugging stuff */ +#define S3C24XX_SOC_NEO1973_WM8753_DEBUG 0 +#if S3C24XX_SOC_NEO1973_WM8753_DEBUG +#define DBG(x...) printk(KERN_DEBUG "s3c24xx-soc-neo1973-wm8753: " x) +#else +#define DBG(x...) +#endif + /* define the scenarios */ #define NEO_AUDIO_OFF 0 #define NEO_GSM_CALL_AUDIO_HANDSET 1 @@ -67,6 +75,8 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, int ret = 0; unsigned long iis_clkrate; + DBG("Entered %s\n", __func__); + iis_clkrate = s3c24xx_i2s_get_clockrate(); switch (params_rate(params)) { @@ -151,6 +161,8 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; + DBG("Entered %s\n", __func__); + /* disable the PLL */ return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0); } @@ -172,6 +184,8 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, int ret = 0; unsigned long iis_clkrate; + DBG("Entered %s\n", __func__); + iis_clkrate = s3c24xx_i2s_get_clockrate(); if (params_rate(params) != 8000) @@ -213,6 +227,8 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; + DBG("Entered %s\n", __func__); + /* disable the PLL */ return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0); } @@ -233,6 +249,8 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) { + DBG("Entered %s\n", __func__); + switch (neo1973_scenario) { case NEO_AUDIO_OFF: snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); @@ -315,6 +333,8 @@ static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + DBG("Entered %s\n", __func__); + if (neo1973_scenario == ucontrol->value.integer.value[0]) return 0; @@ -327,6 +347,8 @@ static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; static void lm4857_write_regs(void) { + DBG("Entered %s\n", __func__); + if (i2c_master_send(i2c, lm4857_regs, 4) != 4) printk(KERN_ERR "lm4857: i2c write failed\n"); } @@ -338,6 +360,8 @@ static int lm4857_get_reg(struct snd_kcontrol *kcontrol, int shift = (kcontrol->private_value >> 8) & 0x0F; int mask = (kcontrol->private_value >> 16) & 0xFF; + DBG("Entered %s\n", __func__); + ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; return 0; } @@ -364,6 +388,8 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol, { u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; + DBG("Entered %s\n", __func__); + if (value) value -= 5; @@ -376,6 +402,8 @@ static int lm4857_set_mode(struct snd_kcontrol *kcontrol, { u8 value = ucontrol->value.integer.value[0]; + DBG("Entered %s\n", __func__); + if (value) value += 5; @@ -483,6 +511,8 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) { int i, err; + DBG("Entered %s\n", __func__); + /* set up NC codec pins */ snd_soc_dapm_set_endpoint(codec, "LOUT2", 0); snd_soc_dapm_set_endpoint(codec, "ROUT2", 0); @@ -583,6 +613,8 @@ static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind) { int ret; + DBG("Entered %s\n", __func__); + client_template.adapter = adap; client_template.addr = addr; @@ -606,6 +638,8 @@ exit_err: static int lm4857_i2c_detach(struct i2c_client *client) { + DBG("Entered %s\n", __func__); + i2c_detach_client(client); kfree(client); return 0; @@ -613,6 +647,8 @@ static int lm4857_i2c_detach(struct i2c_client *client) static int lm4857_i2c_attach(struct i2c_adapter *adap) { + DBG("Entered %s\n", __func__); + return i2c_probe(adap, &addr_data, lm4857_amp_probe); } @@ -620,6 +656,8 @@ static u8 lm4857_state; static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) { + DBG("Entered %s\n", __func__); + dev_dbg(&dev->dev, "lm4857_suspend\n"); lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf; if (lm4857_state) { @@ -631,6 +669,8 @@ static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) static int lm4857_resume(struct i2c_client *dev) { + DBG("Entered %s\n", __func__); + if (lm4857_state) { lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f); lm4857_write_regs(); @@ -640,6 +680,8 @@ static int lm4857_resume(struct i2c_client *dev) static void lm4857_shutdown(struct i2c_client *dev) { + DBG("Entered %s\n", __func__); + dev_dbg(&dev->dev, "lm4857_shutdown\n"); lm4857_regs[LM4857_CTRL] &= 0xf0; lm4857_write_regs(); @@ -671,6 +713,8 @@ static int __init neo1973_init(void) { int ret; + DBG("Entered %s\n", __func__); + neo1973_snd_device = platform_device_alloc("soc-audio", -1); if (!neo1973_snd_device) return -ENOMEM; @@ -691,6 +735,8 @@ static int __init neo1973_init(void) static void __exit neo1973_exit(void) { + DBG("Entered %s\n", __func__); + i2c_del_driver(&lm4857_i2c_driver); platform_device_unregister(neo1973_snd_device); } -- cgit v0.10.2 From 87af38dafe4f930921b9217c21ec6d72cad56bcc Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 7 May 2008 12:05:10 +0200 Subject: [ALSA] ac97 - Add virtual master control to VT1616/VT1617A codec. Enable VMASTER for VT1616 / VT1617A codec. Signed-off-by: Daniel Jacobowitz Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 602b58e..159137b 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig @@ -58,6 +58,7 @@ config SND_AC97_CODEC tristate select SND_PCM select AC97_BUS + select SND_VMASTER config SND_DUMMY tristate "Dummy (/dev/null) soundcard" diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 1292dce..92817f7 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3352,8 +3352,66 @@ AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), }; +static const char *slave_vols_vt1616[] = { + "Front Playback Volume", + "Surround Playback Volume", + "Center Playback Volume", + "LFE Playback Volume", + NULL +}; + +static const char *slave_sws_vt1616[] = { + "Front Playback Switch", + "Surround Playback Switch", + "Center Playback Switch", + "LFE Playback Switch", + NULL +}; + +/* find a mixer control element with the given name */ +static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, + const char *name) +{ + struct snd_ctl_elem_id id; + memset(&id, 0, sizeof(id)); + id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + strcpy(id.name, name); + return snd_ctl_find_id(ac97->bus->card, &id); +} + +/* create a virtual master control and add slaves */ +int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, + const unsigned int *tlv, const char **slaves) +{ + struct snd_kcontrol *kctl; + const char **s; + int err; + + kctl = snd_ctl_make_virtual_master(name, tlv); + if (!kctl) + return -ENOMEM; + err = snd_ctl_add(ac97->bus->card, kctl); + if (err < 0) + return err; + + for (s = slaves; *s; s++) { + struct snd_kcontrol *sctl; + + sctl = snd_ac97_find_mixer_ctl(ac97, *s); + if (!sctl) { + snd_printdd("Cannot find slave %s, skipped\n", *s); + continue; + } + err = snd_ctl_add_slave(kctl, sctl); + if (err < 0) + return err; + } + return 0; +} + static int patch_vt1616_specific(struct snd_ac97 * ac97) { + struct snd_kcontrol *kctl; int err; if (snd_ac97_try_bit(ac97, 0x5a, 9)) @@ -3361,6 +3419,24 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97) return err; if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0) return err; + + /* There is already a misnamed master switch. Rename it. */ + kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume"); + if (!kctl) + return -EINVAL; + + snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback"); + + err = snd_ac97_add_vmaster(ac97, "Master Playback Volume", + kctl->tlv.p, slave_vols_vt1616); + if (err < 0) + return err; + + err = snd_ac97_add_vmaster(ac97, "Master Playback Switch", + NULL, slave_sws_vt1616); + if (err < 0) + return err; + return 0; } -- cgit v0.10.2 From 48008b598bb9cfffbd871512f49d84eb5b885a00 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 8 May 2008 13:01:32 +0200 Subject: [ALSA] i2c: cs8427.c use put_unaligned helper Signed-off-by: Harvey Harrison Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index e57e9cb..9c3d361 100644 --- a/sound/i2c/cs8427.c +++ b/sound/i2c/cs8427.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -264,10 +265,7 @@ int snd_cs8427_create(struct snd_i2c_bus *bus, goto __fail; } /* write default channel status bytes */ - buf[0] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 0)); - buf[1] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 8)); - buf[2] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 16)); - buf[3] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 24)); + put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf); memset(buf + 4, 0, 24 - 4); if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0) goto __fail; -- cgit v0.10.2 From f3e9d5d1fd6a164611043c053de585a35d76d6a9 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 8 May 2008 15:42:15 +0200 Subject: [ALSA] snd_usb_caiaq: add support for 'Session I/O' interface This patch adds suport for Native Instruments new 'Guitar Rig Session I/O' audio hardware. Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c index 24970a5..b3a6033 100644 --- a/sound/usb/caiaq/caiaq-audio.c +++ b/sound/usb/caiaq/caiaq-audio.c @@ -637,6 +637,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) switch (dev->chip.usb_id) { case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): dev->samplerates |= SNDRV_PCM_RATE_88200; dev->samplerates |= SNDRV_PCM_RATE_192000; break; diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index a972f77..8317508 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c @@ -42,14 +42,15 @@ #endif MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("caiaq USB audio, version 1.3.6"); +MODULE_DESCRIPTION("caiaq USB audio, version 1.3.8"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," "{Native Instruments, RigKontrol3}," "{Native Instruments, Kore Controller}," "{Native Instruments, Kore Controller 2}," - "{Native Instruments, Audio Kontrol 1}" - "{Native Instruments, Audio 8 DJ}}"); + "{Native Instruments, Audio Kontrol 1}," + "{Native Instruments, Audio 8 DJ}," + "{Native Instruments, Session I/O}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ @@ -110,6 +111,11 @@ static struct usb_device_id snd_usb_id_table[] = { .idVendor = USB_VID_NATIVEINSTRUMENTS, .idProduct = USB_PID_AUDIO8DJ }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_SESSIONIO + }, { /* terminator */ } }; diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h index 96a4913..f9fbdba 100644 --- a/sound/usb/caiaq/caiaq-device.h +++ b/sound/usb/caiaq/caiaq-device.h @@ -11,6 +11,7 @@ #define USB_PID_KORECONTROLLER2 0x4712 #define USB_PID_AK1 0x0815 #define USB_PID_AUDIO8DJ 0x1978 +#define USB_PID_SESSIONIO 0x1915 #define EP1_BUFSIZE 64 #define CAIAQ_USB_STR_LEN 0xff -- cgit v0.10.2 From c17cf06bfc4417a79d452c266e819c510f6a8344 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 May 2008 12:45:56 +0200 Subject: [ALSA] Remove unneeded ugly hack for i386 in memalloc.c The hack for dma_alloc_coherent() is no longer needed on 2.6.26 since the base code was improved. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 23b7bc0..f5d6d8d 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -80,68 +80,6 @@ struct snd_mem_list { #endif /* - * Hacks - */ - -#if defined(__i386__) -/* - * A hack to allocate large buffers via dma_alloc_coherent() - * - * since dma_alloc_coherent always tries GFP_DMA when the requested - * pci memory region is below 32bit, it happens quite often that even - * 2 order of pages cannot be allocated. - * - * so in the following, we allocate at first without dma_mask, so that - * allocation will be done without GFP_DMA. if the area doesn't match - * with the requested region, then realloate with the original dma_mask - * again. - * - * Really, we want to move this type of thing into dma_alloc_coherent() - * so dma_mask doesn't have to be messed with. - */ - -static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, - gfp_t flags) -{ - void *ret; - u64 dma_mask, coherent_dma_mask; - - if (dev == NULL || !dev->dma_mask) - return dma_alloc_coherent(dev, size, dma_handle, flags); - dma_mask = *dev->dma_mask; - coherent_dma_mask = dev->coherent_dma_mask; - *dev->dma_mask = 0xffffffff; /* do without masking */ - dev->coherent_dma_mask = 0xffffffff; /* do without masking */ - ret = dma_alloc_coherent(dev, size, dma_handle, flags); - *dev->dma_mask = dma_mask; /* restore */ - dev->coherent_dma_mask = coherent_dma_mask; /* restore */ - if (ret) { - /* obtained address is out of range? */ - if (((unsigned long)*dma_handle + size - 1) & ~dma_mask) { - /* reallocate with the proper mask */ - dma_free_coherent(dev, size, ret, *dma_handle); - ret = dma_alloc_coherent(dev, size, dma_handle, flags); - } - } else { - /* wish to success now with the proper mask... */ - if (dma_mask != 0xffffffffUL) { - /* allocation with GFP_ATOMIC to avoid the long stall */ - flags &= ~GFP_KERNEL; - flags |= GFP_ATOMIC; - ret = dma_alloc_coherent(dev, size, dma_handle, flags); - } - } - return ret; -} - -/* redefine dma_alloc_coherent for some architectures */ -#undef dma_alloc_coherent -#define dma_alloc_coherent snd_dma_hack_alloc_coherent - -#endif /* arch */ - -/* * * Generic memory allocators * -- cgit v0.10.2 From d023dc0aa25d6a4f7dd0d109179a2077d22a7ad2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:18:27 +0200 Subject: [ALSA] oxygen: fix version in MODULE_LICENSE Adjust the MODULE_LICENSE strings to properly reflect the actual license. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 090dd43..c5d2c86 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -28,7 +28,7 @@ MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("TempoTec HiFier driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 63f185c..c1b30cc 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -43,7 +43,7 @@ MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("C-Media CMI8788 driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 897697d..6e38795 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -32,7 +32,7 @@ MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("C-Media CMI8788 helper library"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 7f84fa5..4618a62 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -79,7 +79,7 @@ MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("Asus AVx00 driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -- cgit v0.10.2 From c13650079ba3bed1c0bdd9bf4a13274be7676ff6 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:19:53 +0200 Subject: [ALSA] oxygen: add symbol for I/O space size Remove another magic number - add a symbol for the size of the PCI I/O range. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index a71c6e0..6c6efed 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -16,6 +16,8 @@ #define PCM_AC97 5 #define PCM_COUNT 6 +#define OXYGEN_IO_SIZE 0x100 + /* model-specific configuration of outputs/inputs */ #define PLAYBACK_0_TO_I2S 0x001 #define PLAYBACK_1_TO_SPDIF 0x004 diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 6e38795..60bc159 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -173,7 +173,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, int i, j; snd_iprintf(buffer, "CMI8788\n\n"); - for (i = 0; i < 0x100; i += 0x10) { + for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; ++j) snd_iprintf(buffer, " %02x", oxygen_read8(chip, i + j)); @@ -455,7 +455,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, } if (!(pci_resource_flags(pci, 0) & IORESOURCE_IO) || - pci_resource_len(pci, 0) < 0x100) { + pci_resource_len(pci, 0) < OXYGEN_IO_SIZE) { snd_printk(KERN_ERR "invalid PCI I/O range\n"); err = -ENXIO; goto err_pci_regions; -- cgit v0.10.2 From e58aee95806c9d2bbcfc84cb85ce958e360165ef Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:20:51 +0200 Subject: [ALSA] oxygen: save register writes Save the written values of all CMI8788 and AC97 registers and of some of the DAC/ADC registers so that it is possible to restore the register state later. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index c1b30cc..8287ac2 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -80,6 +80,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); struct generic_data { u8 ak4396_ctl2; + u16 saved_wm8785_registers[2]; }; static void ak4396_write(struct oxygen *chip, unsigned int codec, @@ -99,12 +100,16 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec, static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) { + struct generic_data *data = chip->model_data; + oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | OXYGEN_SPI_DATA_LENGTH_2 | OXYGEN_SPI_CLOCK_160 | (3 << OXYGEN_SPI_CODEC_SHIFT) | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, (reg << 9) | value); + if (reg < ARRAY_SIZE(data->saved_wm8785_registers)) + data->saved_wm8785_registers[reg] = value; } static void ak4396_init(struct oxygen *chip) @@ -135,10 +140,16 @@ static void ak5385_init(struct oxygen *chip) static void wm8785_init(struct oxygen *chip) { + struct generic_data *data = chip->model_data; + + data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | + WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; + data->saved_wm8785_registers[1] = WM8785_WL_24; + wm8785_write(chip, WM8785_R7, 0); - wm8785_write(chip, WM8785_R0, WM8785_MCR_SLAVE | - WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST); - wm8785_write(chip, WM8785_R1, WM8785_WL_24); + wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]); + wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]); + snd_component_add(chip->card, "WM8785"); } diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 6c6efed..29c9fa4 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -80,6 +80,12 @@ struct oxygen { struct work_struct spdif_input_bits_work; struct work_struct gpio_work; wait_queue_head_t ac97_waitqueue; + union { + u8 _8[OXYGEN_IO_SIZE]; + __le16 _16[OXYGEN_IO_SIZE / 2]; + __le32 _32[OXYGEN_IO_SIZE / 4]; + } saved_registers; + u16 saved_ac97_registers[2][0x40]; }; struct oxygen_model { diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c index 5569606..83f135f 100644 --- a/sound/pci/oxygen/oxygen_io.c +++ b/sound/pci/oxygen/oxygen_io.c @@ -44,18 +44,21 @@ EXPORT_SYMBOL(oxygen_read32); void oxygen_write8(struct oxygen *chip, unsigned int reg, u8 value) { outb(value, chip->addr + reg); + chip->saved_registers._8[reg] = value; } EXPORT_SYMBOL(oxygen_write8); void oxygen_write16(struct oxygen *chip, unsigned int reg, u16 value) { outw(value, chip->addr + reg); + chip->saved_registers._16[reg / 2] = cpu_to_le16(value); } EXPORT_SYMBOL(oxygen_write16); void oxygen_write32(struct oxygen *chip, unsigned int reg, u32 value) { outl(value, chip->addr + reg); + chip->saved_registers._32[reg / 4] = cpu_to_le32(value); } EXPORT_SYMBOL(oxygen_write32); @@ -63,7 +66,10 @@ void oxygen_write8_masked(struct oxygen *chip, unsigned int reg, u8 value, u8 mask) { u8 tmp = inb(chip->addr + reg); - outb((tmp & ~mask) | (value & mask), chip->addr + reg); + tmp &= ~mask; + tmp |= value & mask; + outb(tmp, chip->addr + reg); + chip->saved_registers._8[reg] = tmp; } EXPORT_SYMBOL(oxygen_write8_masked); @@ -71,7 +77,10 @@ void oxygen_write16_masked(struct oxygen *chip, unsigned int reg, u16 value, u16 mask) { u16 tmp = inw(chip->addr + reg); - outw((tmp & ~mask) | (value & mask), chip->addr + reg); + tmp &= ~mask; + tmp |= value & mask; + outw(tmp, chip->addr + reg); + chip->saved_registers._16[reg / 2] = cpu_to_le16(tmp); } EXPORT_SYMBOL(oxygen_write16_masked); @@ -79,7 +88,10 @@ void oxygen_write32_masked(struct oxygen *chip, unsigned int reg, u32 value, u32 mask) { u32 tmp = inl(chip->addr + reg); - outl((tmp & ~mask) | (value & mask), chip->addr + reg); + tmp &= ~mask; + tmp |= value & mask; + outl(tmp, chip->addr + reg); + chip->saved_registers._32[reg / 4] = cpu_to_le32(tmp); } EXPORT_SYMBOL(oxygen_write32_masked); @@ -128,8 +140,10 @@ void oxygen_write_ac97(struct oxygen *chip, unsigned int codec, oxygen_write32(chip, OXYGEN_AC97_REGS, reg); /* require two "completed" writes, just to be sure */ if (oxygen_ac97_wait(chip, OXYGEN_AC97_INT_WRITE_DONE) >= 0 && - ++succeeded >= 2) + ++succeeded >= 2) { + chip->saved_ac97_registers[codec][index / 2] = data; return; + } } snd_printk(KERN_ERR "AC'97 write timeout\n"); } diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 4618a62..110786b 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -132,6 +132,9 @@ struct xonar_data { u8 ext_power_int_reg; u8 ext_power_bit; u8 has_power; + u8 pcm1796_oversampling; + u8 cs4398_fm; + u8 cs4362a_fm; }; static void pcm1796_write(struct oxygen *chip, unsigned int codec, @@ -186,12 +189,13 @@ static void xonar_d2_init(struct oxygen *chip) data->anti_pop_delay = 300; data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; + data->pcm1796_oversampling = PCM1796_OS_64; for (i = 0; i < 4; ++i) { pcm1796_write(chip, i, 18, PCM1796_MUTE | PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD); pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); - pcm1796_write(chip, i, 20, PCM1796_OS_64); + pcm1796_write(chip, i, 20, data->pcm1796_oversampling); pcm1796_write(chip, i, 21, 0); pcm1796_write(chip, i, 16, 0x0f); /* set ATL/ATR after ATLD */ pcm1796_write(chip, i, 17, 0x0f); @@ -226,6 +230,9 @@ static void xonar_dx_init(struct oxygen *chip) data->ext_power_reg = OXYGEN_GPI_DATA; data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; data->ext_power_bit = GPI_DX_EXT_POWER; + data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; + data->cs4362a_fm = CS4362A_FM_SINGLE | + CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, OXYGEN_2WIRE_LENGTH_8 | @@ -236,8 +243,7 @@ static void xonar_dx_init(struct oxygen *chip) cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN); cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); /* configure */ - cs4398_write(chip, 2, CS4398_FM_SINGLE | - CS4398_DEM_NONE | CS4398_DIF_LJUST); + cs4398_write(chip, 2, data->cs4398_fm); cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L); cs4398_write(chip, 4, CS4398_MUTEP_LOW | CS4398_PAMUTE); cs4398_write(chip, 5, 0xfe); @@ -249,16 +255,13 @@ static void xonar_dx_init(struct oxygen *chip) CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP); cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); cs4362a_write(chip, 0x05, 0); - cs4362a_write(chip, 0x06, CS4362A_FM_SINGLE | - CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L); + cs4362a_write(chip, 0x06, data->cs4362a_fm); cs4362a_write(chip, 0x07, 0x7f | CS4362A_MUTE); cs4362a_write(chip, 0x08, 0x7f | CS4362A_MUTE); - cs4362a_write(chip, 0x09, CS4362A_FM_SINGLE | - CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L); + cs4362a_write(chip, 0x09, data->cs4362a_fm); cs4362a_write(chip, 0x0a, 0x7f | CS4362A_MUTE); cs4362a_write(chip, 0x0b, 0x7f | CS4362A_MUTE); - cs4362a_write(chip, 0x0c, CS4362A_FM_SINGLE | - CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L); + cs4362a_write(chip, 0x0c, data->cs4362a_fm); cs4362a_write(chip, 0x0d, 0x7f | CS4362A_MUTE); cs4362a_write(chip, 0x0e, 0x7f | CS4362A_MUTE); /* clear power down */ @@ -294,12 +297,13 @@ static void xonar_dx_cleanup(struct oxygen *chip) static void set_pcm1796_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { + struct xonar_data *data = chip->model_data; unsigned int i; - u8 value; - value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; + data->pcm1796_oversampling = + params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; for (i = 0; i < 4; ++i) - pcm1796_write(chip, i, 20, value); + pcm1796_write(chip, i, 20, data->pcm1796_oversampling); } static void update_pcm1796_volume(struct oxygen *chip) @@ -342,24 +346,24 @@ static void set_cs53x1_params(struct oxygen *chip, static void set_cs43xx_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { - u8 fm_cs4398, fm_cs4362a; + struct xonar_data *data = chip->model_data; - fm_cs4398 = CS4398_DEM_NONE | CS4398_DIF_LJUST; - fm_cs4362a = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; + data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST; + data->cs4362a_fm = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; if (params_rate(params) <= 50000) { - fm_cs4398 |= CS4398_FM_SINGLE; - fm_cs4362a |= CS4362A_FM_SINGLE; + data->cs4398_fm |= CS4398_FM_SINGLE; + data->cs4362a_fm |= CS4362A_FM_SINGLE; } else if (params_rate(params) <= 100000) { - fm_cs4398 |= CS4398_FM_DOUBLE; - fm_cs4362a |= CS4362A_FM_DOUBLE; + data->cs4398_fm |= CS4398_FM_DOUBLE; + data->cs4362a_fm |= CS4362A_FM_DOUBLE; } else { - fm_cs4398 |= CS4398_FM_QUAD; - fm_cs4362a |= CS4362A_FM_QUAD; + data->cs4398_fm |= CS4398_FM_QUAD; + data->cs4362a_fm |= CS4362A_FM_QUAD; } - cs4398_write(chip, 2, fm_cs4398); - cs4362a_write(chip, 0x06, fm_cs4362a); - cs4362a_write(chip, 0x09, fm_cs4362a); - cs4362a_write(chip, 0x0c, fm_cs4362a); + cs4398_write(chip, 2, data->cs4398_fm); + cs4362a_write(chip, 0x06, data->cs4362a_fm); + cs4362a_write(chip, 0x09, data->cs4362a_fm); + cs4362a_write(chip, 0x0c, data->cs4362a_fm); } static void update_cs4362a_volumes(struct oxygen *chip) -- cgit v0.10.2 From bbbfb5526650cb9d01c5c230a4e3cbbc18474c41 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:21:48 +0200 Subject: [ALSA] oxygen: simplify DAC volume initialization When initializing the DAC volume registers, we can just use the generic volume update functions instead of setting the registers manually. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index c5d2c86..0e425d5 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -62,6 +62,12 @@ static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) AK4396_WRITE | (reg << 8) | value); } +static void update_ak4396_volume(struct oxygen *chip) +{ + ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); + ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); +} + static void hifier_init(struct oxygen *chip) { struct hifier_data *data = chip->model_data; @@ -70,8 +76,7 @@ static void hifier_init(struct oxygen *chip) ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2); ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); - ak4396_write(chip, AK4396_LCH_ATT, 0); - ak4396_write(chip, AK4396_RCH_ATT, 0); + update_ak4396_volume(chip); snd_component_add(chip->card, "AK4396"); snd_component_add(chip->card, "CS5340"); @@ -100,12 +105,6 @@ static void set_ak4396_params(struct oxygen *chip, ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); } -static void update_ak4396_volume(struct oxygen *chip) -{ - ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); - ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); -} - static void update_ak4396_mute(struct oxygen *chip) { struct hifier_data *data = chip->model_data; diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 8287ac2..ad8d950 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -112,6 +112,18 @@ static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) data->saved_wm8785_registers[reg] = value; } +static void update_ak4396_volume(struct oxygen *chip) +{ + unsigned int i; + + for (i = 0; i < 4; ++i) { + ak4396_write(chip, i, + AK4396_LCH_ATT, chip->dac_volume[i * 2]); + ak4396_write(chip, i, + AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]); + } +} + static void ak4396_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; @@ -125,9 +137,8 @@ static void ak4396_init(struct oxygen *chip) AK4396_CONTROL_2, data->ak4396_ctl2); ak4396_write(chip, i, AK4396_CONTROL_3, AK4396_PCM); - ak4396_write(chip, i, AK4396_LCH_ATT, 0); - ak4396_write(chip, i, AK4396_RCH_ATT, 0); } + update_ak4396_volume(chip); snd_component_add(chip->card, "AK4396"); } @@ -194,18 +205,6 @@ static void set_ak4396_params(struct oxygen *chip, } } -static void update_ak4396_volume(struct oxygen *chip) -{ - unsigned int i; - - for (i = 0; i < 4; ++i) { - ak4396_write(chip, i, - AK4396_LCH_ATT, chip->dac_volume[i * 2]); - ak4396_write(chip, i, - AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]); - } -} - static void update_ak4396_mute(struct oxygen *chip) { struct generic_data *data = chip->model_data; diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 110786b..bd9e285 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -182,6 +182,28 @@ static void xonar_common_init(struct oxygen *chip) oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); } +static void update_pcm1796_volume(struct oxygen *chip) +{ + unsigned int i; + + for (i = 0; i < 4; ++i) { + pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]); + pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]); + } +} + +static void update_pcm1796_mute(struct oxygen *chip) +{ + unsigned int i; + u8 value; + + value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; + if (chip->dac_mute) + value |= PCM1796_MUTE; + for (i = 0; i < 4; ++i) + pcm1796_write(chip, i, 18, value); +} + static void xonar_d2_init(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -192,14 +214,12 @@ static void xonar_d2_init(struct oxygen *chip) data->pcm1796_oversampling = PCM1796_OS_64; for (i = 0; i < 4; ++i) { - pcm1796_write(chip, i, 18, PCM1796_MUTE | PCM1796_DMF_DISABLED | - PCM1796_FMT_24_LJUST | PCM1796_ATLD); pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); pcm1796_write(chip, i, 20, data->pcm1796_oversampling); pcm1796_write(chip, i, 21, 0); - pcm1796_write(chip, i, 16, 0x0f); /* set ATL/ATR after ATLD */ - pcm1796_write(chip, i, 17, 0x0f); } + update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */ + update_pcm1796_volume(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT); @@ -221,6 +241,37 @@ static void xonar_d2x_init(struct oxygen *chip) xonar_d2_init(chip); } +static void update_cs4362a_volumes(struct oxygen *chip) +{ + u8 mute; + + mute = chip->dac_mute ? CS4362A_MUTE : 0; + cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute); + cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute); + cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute); + cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute); + cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute); + cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute); +} + +static void update_cs43xx_volume(struct oxygen *chip) +{ + cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2); + cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2); + update_cs4362a_volumes(chip); +} + +static void update_cs43xx_mute(struct oxygen *chip) +{ + u8 reg; + + reg = CS4398_MUTEP_LOW | CS4398_PAMUTE; + if (chip->dac_mute) + reg |= CS4398_MUTE_B | CS4398_MUTE_A; + cs4398_write(chip, 4, reg); + update_cs4362a_volumes(chip); +} + static void xonar_dx_init(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -245,9 +296,6 @@ static void xonar_dx_init(struct oxygen *chip) /* configure */ cs4398_write(chip, 2, data->cs4398_fm); cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L); - cs4398_write(chip, 4, CS4398_MUTEP_LOW | CS4398_PAMUTE); - cs4398_write(chip, 5, 0xfe); - cs4398_write(chip, 6, 0xfe); cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP | CS4398_ZERO_CROSS | CS4398_SOFT_RAMP); cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST); @@ -256,14 +304,10 @@ static void xonar_dx_init(struct oxygen *chip) cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); cs4362a_write(chip, 0x05, 0); cs4362a_write(chip, 0x06, data->cs4362a_fm); - cs4362a_write(chip, 0x07, 0x7f | CS4362A_MUTE); - cs4362a_write(chip, 0x08, 0x7f | CS4362A_MUTE); cs4362a_write(chip, 0x09, data->cs4362a_fm); - cs4362a_write(chip, 0x0a, 0x7f | CS4362A_MUTE); - cs4362a_write(chip, 0x0b, 0x7f | CS4362A_MUTE); cs4362a_write(chip, 0x0c, data->cs4362a_fm); - cs4362a_write(chip, 0x0d, 0x7f | CS4362A_MUTE); - cs4362a_write(chip, 0x0e, 0x7f | CS4362A_MUTE); + update_cs43xx_volume(chip); + update_cs43xx_mute(chip); /* clear power down */ cs4398_write(chip, 8, CS4398_CPEN); cs4362a_write(chip, 0x01, CS4362A_CPEN); @@ -306,28 +350,6 @@ static void set_pcm1796_params(struct oxygen *chip, pcm1796_write(chip, i, 20, data->pcm1796_oversampling); } -static void update_pcm1796_volume(struct oxygen *chip) -{ - unsigned int i; - - for (i = 0; i < 4; ++i) { - pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]); - pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]); - } -} - -static void update_pcm1796_mute(struct oxygen *chip) -{ - unsigned int i; - u8 value; - - value = PCM1796_FMT_24_LJUST | PCM1796_ATLD; - if (chip->dac_mute) - value |= PCM1796_MUTE; - for (i = 0; i < 4; ++i) - pcm1796_write(chip, i, 18, value); -} - static void set_cs53x1_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -366,37 +388,6 @@ static void set_cs43xx_params(struct oxygen *chip, cs4362a_write(chip, 0x0c, data->cs4362a_fm); } -static void update_cs4362a_volumes(struct oxygen *chip) -{ - u8 mute; - - mute = chip->dac_mute ? CS4362A_MUTE : 0; - cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute); - cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute); - cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute); - cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute); - cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute); - cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute); -} - -static void update_cs43xx_volume(struct oxygen *chip) -{ - cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2); - cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2); - update_cs4362a_volumes(chip); -} - -static void update_cs43xx_mute(struct oxygen *chip) -{ - u8 reg; - - reg = CS4398_MUTEP_LOW | CS4398_PAMUTE; - if (chip->dac_mute) - reg |= CS4398_MUTE_B | CS4398_MUTE_A; - cs4398_write(chip, 4, reg); - update_cs4362a_volumes(chip); -} - static void xonar_gpio_changed(struct oxygen *chip) { struct xonar_data *data = chip->model_data; -- cgit v0.10.2 From 75146fc0f9368ea41419792ac8bfdd19273b4473 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:22:43 +0200 Subject: [ALSA] oxygen: separate out hardware initialization code Create separate functions for the code that initializes the hardware, as opposed to initializing internal driver state, so that they can be reused for resume support. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 0e425d5..6e45a58 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -68,15 +68,22 @@ static void update_ak4396_volume(struct oxygen *chip) ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); } -static void hifier_init(struct oxygen *chip) +static void hifier_registers_init(struct oxygen *chip) { struct hifier_data *data = chip->model_data; - data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2); ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); update_ak4396_volume(chip); +} + +static void hifier_init(struct oxygen *chip) +{ + struct hifier_data *data = chip->model_data; + + data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; + hifier_registers_init(chip); snd_component_add(chip->card, "AK4396"); snd_component_add(chip->card, "CS5340"); diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index ad8d950..800ae30 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -124,12 +124,11 @@ static void update_ak4396_volume(struct oxygen *chip) } } -static void ak4396_init(struct oxygen *chip) +static void ak4396_registers_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; unsigned int i; - data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; for (i = 0; i < 4; ++i) { ak4396_write(chip, i, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); @@ -139,6 +138,14 @@ static void ak4396_init(struct oxygen *chip) AK4396_CONTROL_3, AK4396_PCM); } update_ak4396_volume(chip); +} + +static void ak4396_init(struct oxygen *chip) +{ + struct generic_data *data = chip->model_data; + + data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; + ak4396_registers_init(chip); snd_component_add(chip->card, "AK4396"); } @@ -149,18 +156,23 @@ static void ak5385_init(struct oxygen *chip) snd_component_add(chip->card, "AK5385"); } -static void wm8785_init(struct oxygen *chip) +static void wm8785_registers_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; - data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | - WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; - data->saved_wm8785_registers[1] = WM8785_WL_24; - wm8785_write(chip, WM8785_R7, 0); wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]); wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]); +} +static void wm8785_init(struct oxygen *chip) +{ + struct generic_data *data = chip->model_data; + + data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | + WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; + data->saved_wm8785_registers[1] = WM8785_WL_24; + wm8785_registers_init(chip); snd_component_add(chip->card, "WM8785"); } diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index bd9e285..e95dc57 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -204,15 +204,11 @@ static void update_pcm1796_mute(struct oxygen *chip) pcm1796_write(chip, i, 18, value); } -static void xonar_d2_init(struct oxygen *chip) +static void pcm1796_init(struct oxygen *chip) { struct xonar_data *data = chip->model_data; unsigned int i; - data->anti_pop_delay = 300; - data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; - data->pcm1796_oversampling = PCM1796_OS_64; - for (i = 0; i < 4; ++i) { pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); pcm1796_write(chip, i, 20, data->pcm1796_oversampling); @@ -220,6 +216,17 @@ static void xonar_d2_init(struct oxygen *chip) } update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */ update_pcm1796_volume(chip); +} + +static void xonar_d2_init(struct oxygen *chip) +{ + struct xonar_data *data = chip->model_data; + + data->anti_pop_delay = 300; + data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; + data->pcm1796_oversampling = PCM1796_OS_64; + + pcm1796_init(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT); @@ -272,24 +279,10 @@ static void update_cs43xx_mute(struct oxygen *chip) update_cs4362a_volumes(chip); } -static void xonar_dx_init(struct oxygen *chip) +static void cs43xx_init(struct oxygen *chip) { struct xonar_data *data = chip->model_data; - data->anti_pop_delay = 800; - data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; - data->ext_power_reg = OXYGEN_GPI_DATA; - data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; - data->ext_power_bit = GPI_DX_EXT_POWER; - data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; - data->cs4362a_fm = CS4362A_FM_SINGLE | - CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; - - oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, - OXYGEN_2WIRE_LENGTH_8 | - OXYGEN_2WIRE_INTERRUPT_MASK | - OXYGEN_2WIRE_SPEED_FAST); - /* set CPEN (control port mode) and power down */ cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN); cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); @@ -311,6 +304,27 @@ static void xonar_dx_init(struct oxygen *chip) /* clear power down */ cs4398_write(chip, 8, CS4398_CPEN); cs4362a_write(chip, 0x01, CS4362A_CPEN); +} + +static void xonar_dx_init(struct oxygen *chip) +{ + struct xonar_data *data = chip->model_data; + + data->anti_pop_delay = 800; + data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; + data->ext_power_reg = OXYGEN_GPI_DATA; + data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; + data->ext_power_bit = GPI_DX_EXT_POWER; + data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; + data->cs4362a_fm = CS4362A_FM_SINGLE | + CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; + + oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, + OXYGEN_2WIRE_LENGTH_8 | + OXYGEN_2WIRE_INTERRUPT_MASK | + OXYGEN_2WIRE_SPEED_FAST); + + cs43xx_init(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE); -- cgit v0.10.2 From 92215f3a178080bd9d7c65879499e9474e54d55c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:23:02 +0200 Subject: [ALSA] virtuoso: add xonar_enable_output() Move the setting of the output enable GPIO bit to a separate function. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index e95dc57..abd5313 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -162,6 +162,14 @@ static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value) oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value); } +static void xonar_enable_output(struct oxygen *chip) +{ + struct xonar_data *data = chip->model_data; + + msleep(data->anti_pop_delay); + oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); +} + static void xonar_common_init(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -173,13 +181,12 @@ static void xonar_common_init(struct oxygen *chip) data->has_power = !!(oxygen_read8(chip, data->ext_power_reg) & data->ext_power_bit); } - oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK); + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_CS53x1_M_MASK | data->output_enable_bit); oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK); oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); - msleep(data->anti_pop_delay); - oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit); - oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); + xonar_enable_output(chip); } static void update_pcm1796_volume(struct oxygen *chip) -- cgit v0.10.2 From 4a4bc53bc52978dd6c918531921da925fd047d95 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:24:39 +0200 Subject: [ALSA] oxygen: add PM support Add suspend/resume support. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 6e45a58..7442460 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -146,6 +146,7 @@ static const struct oxygen_model model_hifier = { .init = hifier_init, .control_filter = hifier_control_filter, .cleanup = hifier_cleanup, + .resume = hifier_registers_init, .set_dac_params = set_ak4396_params, .set_adc_params = set_cs5340_params, .update_dac_volume = update_ak4396_volume, @@ -186,6 +187,10 @@ static struct pci_driver hifier_driver = { .id_table = hifier_ids, .probe = hifier_probe, .remove = __devexit_p(oxygen_pci_remove), +#ifdef CONFIG_PM + .suspend = oxygen_pci_suspend, + .resume = oxygen_pci_resume, +#endif }; static int __init alsa_card_hifier_init(void) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 800ae30..7c8ae31 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -192,6 +192,12 @@ static void generic_cleanup(struct oxygen *chip) { } +static void generic_resume(struct oxygen *chip) +{ + ak4396_registers_init(chip); + wm8785_registers_init(chip); +} + static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -278,6 +284,7 @@ static const struct oxygen_model model_generic = { .owner = THIS_MODULE, .init = generic_init, .cleanup = generic_cleanup, + .resume = generic_resume, .set_dac_params = set_ak4396_params, .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, @@ -305,6 +312,7 @@ static const struct oxygen_model model_meridian = { .owner = THIS_MODULE, .init = meridian_init, .cleanup = generic_cleanup, + .resume = ak4396_registers_init, .set_dac_params = set_ak4396_params, .set_adc_params = set_ak5385_params, .update_dac_volume = update_ak4396_volume, @@ -353,6 +361,10 @@ static struct pci_driver oxygen_driver = { .id_table = oxygen_ids, .probe = generic_oxygen_probe, .remove = __devexit_p(oxygen_pci_remove), +#ifdef CONFIG_PM + .suspend = oxygen_pci_suspend, + .resume = oxygen_pci_resume, +#endif }; static int __init alsa_card_oxygen_init(void) diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 29c9fa4..74a6448 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -97,6 +97,8 @@ struct oxygen_model { int (*control_filter)(struct snd_kcontrol_new *template); int (*mixer_init)(struct oxygen *chip); void (*cleanup)(struct oxygen *chip); + void (*suspend)(struct oxygen *chip); + void (*resume)(struct oxygen *chip); void (*pcm_hardware_filter)(unsigned int channel, struct snd_pcm_hardware *hardware); void (*set_dac_params)(struct oxygen *chip, @@ -125,6 +127,10 @@ struct oxygen_model { int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, const struct oxygen_model *model); void oxygen_pci_remove(struct pci_dev *pci); +#ifdef CONFIG_PM +int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); +int oxygen_pci_resume(struct pci_dev *pci); +#endif /* oxygen_mixer.c */ diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 60bc159..22f3785 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -314,6 +314,10 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_SPDIF_LOCK_MASK | OXYGEN_SPDIF_RATE_MASK); oxygen_write32(chip, OXYGEN_SPDIF_OUTPUT_BITS, chip->spdif_bits); + oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, + OXYGEN_2WIRE_LENGTH_8 | + OXYGEN_2WIRE_INTERRUPT_MASK | + OXYGEN_2WIRE_SPEED_STANDARD); oxygen_clear_bits8(chip, OXYGEN_MPU401_CONTROL, OXYGEN_MPU401_LOOPBACK); oxygen_write8(chip, OXYGEN_GPI_INTERRUPT_MASK, 0); oxygen_write16(chip, OXYGEN_GPIO_INTERRUPT_MASK, 0); @@ -534,3 +538,99 @@ void oxygen_pci_remove(struct pci_dev *pci) pci_set_drvdata(pci, NULL); } EXPORT_SYMBOL(oxygen_pci_remove); + +#ifdef CONFIG_PM +int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) +{ + struct snd_card *card = pci_get_drvdata(pci); + struct oxygen *chip = card->private_data; + unsigned int i, saved_interrupt_mask; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + + for (i = 0; i < PCM_COUNT; ++i) + if (chip->streams[i]) + snd_pcm_suspend(chip->streams[i]); + + if (chip->model->suspend) + chip->model->suspend(chip); + + spin_lock_irq(&chip->reg_lock); + saved_interrupt_mask = chip->interrupt_mask; + chip->interrupt_mask = 0; + oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); + oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); + spin_unlock_irq(&chip->reg_lock); + + synchronize_irq(chip->irq); + flush_scheduled_work(); + chip->interrupt_mask = saved_interrupt_mask; + + pci_disable_device(pci); + pci_save_state(pci); + pci_set_power_state(pci, pci_choose_state(pci, state)); + return 0; +} +EXPORT_SYMBOL(oxygen_pci_suspend); + +static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = { + 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff, + 0x00300000, 0x00000fe4, 0x0ff7001f, 0x00000000 +}; +static const u32 ac97_registers_to_restore[2][0x40 / 32] = { + { 0x18284fa2, 0x03060000 }, + { 0x00007fa6, 0x00200000 } +}; + +static inline int is_bit_set(const u32 *bitmap, unsigned int bit) +{ + return bitmap[bit / 32] & (1 << (bit & 31)); +} + +static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec) +{ + unsigned int i; + + oxygen_write_ac97(chip, codec, AC97_RESET, 0); + msleep(1); + for (i = 1; i < 0x40; ++i) + if (is_bit_set(ac97_registers_to_restore[codec], i)) + oxygen_write_ac97(chip, codec, i * 2, + chip->saved_ac97_registers[codec][i]); +} + +int oxygen_pci_resume(struct pci_dev *pci) +{ + struct snd_card *card = pci_get_drvdata(pci); + struct oxygen *chip = card->private_data; + unsigned int i; + + pci_set_power_state(pci, PCI_D0); + pci_restore_state(pci); + if (pci_enable_device(pci) < 0) { + snd_printk(KERN_ERR "cannot reenable device"); + snd_card_disconnect(card); + return -EIO; + } + pci_set_master(pci); + + oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); + oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); + for (i = 0; i < OXYGEN_IO_SIZE; ++i) + if (is_bit_set(registers_to_restore, i)) + oxygen_write8(chip, i, chip->saved_registers._8[i]); + if (chip->has_ac97_0) + oxygen_restore_ac97(chip, 0); + if (chip->has_ac97_1) + oxygen_restore_ac97(chip, 1); + + if (chip->model->resume) + chip->model->resume(chip); + + oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); + + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +EXPORT_SYMBOL(oxygen_pci_resume); +#endif /* CONFIG_PM */ diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index b17c405..9680aa3 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -517,6 +517,7 @@ static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_SUSPEND: pausing = 0; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index abd5313..9a2c16b 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -359,6 +359,18 @@ static void xonar_dx_cleanup(struct oxygen *chip) oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); } +static void xonar_d2_resume(struct oxygen *chip) +{ + pcm1796_init(chip); + xonar_enable_output(chip); +} + +static void xonar_dx_resume(struct oxygen *chip) +{ + cs43xx_init(chip); + xonar_enable_output(chip); +} + static void set_pcm1796_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -551,6 +563,8 @@ static const struct oxygen_model xonar_models[] = { .control_filter = xonar_d2_control_filter, .mixer_init = xonar_mixer_init, .cleanup = xonar_cleanup, + .suspend = xonar_cleanup, + .resume = xonar_d2_resume, .set_dac_params = set_pcm1796_params, .set_adc_params = set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -579,6 +593,8 @@ static const struct oxygen_model xonar_models[] = { .control_filter = xonar_d2_control_filter, .mixer_init = xonar_mixer_init, .cleanup = xonar_cleanup, + .suspend = xonar_cleanup, + .resume = xonar_d2_resume, .set_dac_params = set_pcm1796_params, .set_adc_params = set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -608,6 +624,8 @@ static const struct oxygen_model xonar_models[] = { .control_filter = xonar_dx_control_filter, .mixer_init = xonar_dx_mixer_init, .cleanup = xonar_dx_cleanup, + .suspend = xonar_dx_cleanup, + .resume = xonar_dx_resume, .set_dac_params = set_cs43xx_params, .set_adc_params = set_cs53x1_params, .update_dac_volume = update_cs43xx_volume, @@ -652,6 +670,10 @@ static struct pci_driver xonar_driver = { .id_table = xonar_ids, .probe = xonar_probe, .remove = __devexit_p(oxygen_pci_remove), +#ifdef CONFIG_PM + .suspend = oxygen_pci_suspend, + .resume = oxygen_pci_resume, +#endif }; static int __init alsa_card_xonar_init(void) -- cgit v0.10.2 From d55d7a1cbbd069f8368ec5c67480d319e7b227b9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:25:39 +0200 Subject: [ALSA] oxygen: add symbols for buffer/period size constraints Introduce symbols for the buffer/period size constraints so that their limits and relationships become clearer. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 9680aa3..09a16e4 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -24,6 +24,16 @@ #include #include "oxygen.h" +/* most DMA channels have a 16-bit counter for 32-bit words */ +#define BUFFER_BYTES_MAX ((1 << 16) * 4) +/* the multichannel DMA channel has a 24-bit counter */ +#define BUFFER_BYTES_MAX_MULTICH ((1 << 24) * 4) + +#define PERIOD_BYTES_MIN 64 + +#define DEFAULT_BUFFER_BYTES (BUFFER_BYTES_MAX / 2) +#define DEFAULT_BUFFER_BYTES_MULTICH (1024 * 1024) + static const struct snd_pcm_hardware oxygen_stereo_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -44,11 +54,11 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = { .rate_max = 192000, .channels_min = 2, .channels_max = 2, - .buffer_bytes_max = 256 * 1024, - .period_bytes_min = 128, - .period_bytes_max = 128 * 1024, + .buffer_bytes_max = BUFFER_BYTES_MAX, + .period_bytes_min = PERIOD_BYTES_MIN, + .period_bytes_max = BUFFER_BYTES_MAX / 2, .periods_min = 2, - .periods_max = 2048, + .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, }; static const struct snd_pcm_hardware oxygen_multichannel_hardware = { .info = SNDRV_PCM_INFO_MMAP | @@ -70,11 +80,11 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = { .rate_max = 192000, .channels_min = 2, .channels_max = 8, - .buffer_bytes_max = 2048 * 1024, - .period_bytes_min = 128, - .period_bytes_max = 256 * 1024, + .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH, + .period_bytes_min = PERIOD_BYTES_MIN, + .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2, .periods_min = 2, - .periods_max = 16384, + .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN, }; static const struct snd_pcm_hardware oxygen_ac97_hardware = { .info = SNDRV_PCM_INFO_MMAP | @@ -88,11 +98,11 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = { .rate_max = 48000, .channels_min = 2, .channels_max = 2, - .buffer_bytes_max = 256 * 1024, - .period_bytes_min = 128, - .period_bytes_max = 128 * 1024, + .buffer_bytes_max = BUFFER_BYTES_MAX, + .period_bytes_min = PERIOD_BYTES_MIN, + .period_bytes_max = BUFFER_BYTES_MAX / 2, .periods_min = 2, - .periods_max = 2048, + .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, }; static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = { @@ -664,12 +674,14 @@ int oxygen_pcm_init(struct oxygen *chip) snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - 512 * 1024, 2048 * 1024); + DEFAULT_BUFFER_BYTES_MULTICH, + BUFFER_BYTES_MAX_MULTICH); if (ins) snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - 128 * 1024, 256 * 1024); + DEFAULT_BUFFER_BYTES, + BUFFER_BYTES_MAX); } outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); @@ -689,7 +701,8 @@ int oxygen_pcm_init(struct oxygen *chip) strcpy(pcm->name, "Digital"); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - 128 * 1024, 256 * 1024); + DEFAULT_BUFFER_BYTES, + BUFFER_BYTES_MAX); } if (chip->has_ac97_1) { @@ -719,7 +732,8 @@ int oxygen_pcm_init(struct oxygen *chip) strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - 128 * 1024, 256 * 1024); + DEFAULT_BUFFER_BYTES, + BUFFER_BYTES_MAX); } return 0; } -- cgit v0.10.2 From ca1f30ad6c3f002d1d9b9355a53b8bbf2fe70588 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 13 May 2008 09:26:01 +0200 Subject: [ALSA] virtuoso: restrict period time to less than 10 s Add a constraint for the period time so that there are less than ten seconds between interrupts so that ALSA does not assume that the device is dead. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 09a16e4..c4ad65a 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -165,6 +165,12 @@ static int oxygen_open(struct snd_pcm_substream *substream, if (err < 0) return err; } + if (channel == PCM_MULTICH) { + err = snd_pcm_hw_constraint_minmax + (runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000); + if (err < 0) + return err; + } snd_pcm_set_sync(substream); chip->streams[channel] = substream; -- cgit v0.10.2 From 4ba1327ab8ce179c40862f3dedb4ebaaa491d737 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:51:19 +0200 Subject: [ALSA] soc - DAPM - Add bulk control registration Most SoC drivers cut'n'paste a loop iterating over an array to register their DAPM controls. Provide a function they can call instead. Signed-off-by: Mark Brown Cc: Graeme Gregory Cc: Frank Mandarino Cc: Jarkko Nikula Cc: Richard Purdie Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 40cc695..1f30616 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -205,6 +205,9 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 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, + const struct snd_soc_dapm_widget *widget, + int num); /* dapm path setup */ int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c60200c..811d652 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1234,6 +1234,33 @@ int snd_soc_dapm_new_control(struct snd_soc_codec *codec, EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); /** + * snd_soc_dapm_new_controls - create new dapm controls + * @codec: audio codec + * @widget: widget array + * @num: number of widgets + * + * Creates new DAPM controls based upon the templates. + * + * Returns 0 for success else error. + */ +int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, + const struct snd_soc_dapm_widget *widget, + int num) +{ + int i, ret; + + for (i = 0; i < num; i++) { + ret = snd_soc_dapm_new_control(codec, widget); + if (ret < 0) + return ret; + widget++; + } + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); + + +/** * snd_soc_dapm_stream_event - send a stream event to the dapm core * @codec: audio codec * @stream: stream name -- cgit v0.10.2 From 105f1c28442301237d20b05a3d52d9987614016f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:52:19 +0200 Subject: [ALSA] soc - DAPM - Bulk route registration ASoC codecs and machine drivers that use DAPM routes all cut'n'paste a loop iterating over a null terminated array of routes. Factor out this into a bulk registration function, improving the error reporting for most users, and deprecate the old API to help out of tree users pick up the changes. Signed-off-by: Mark Brown Cc: Graeme Gregory Cc: Frank Mandarino Cc: Jarkko Nikula Cc: Richard Purdie Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 1f30616..bf4cf0c 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -193,6 +193,7 @@ struct snd_soc_dapm_widget; enum snd_soc_dapm_type; struct snd_soc_dapm_path; struct snd_soc_dapm_pin; +struct snd_soc_dapm_route; /* dapm controls */ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, @@ -210,10 +211,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, int num); /* dapm path setup */ -int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, +int __deprecated snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink_name, const char *control_name, const char *src_name); int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); void snd_soc_dapm_free(struct snd_soc_device *socdev); +int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, + const struct snd_soc_dapm_route *route, int num); /* dapm events */ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, @@ -250,6 +253,18 @@ enum snd_soc_dapm_type { snd_soc_dapm_post, /* machine specific post widget - exec last */ }; +/* + * DAPM audio route definition. + * + * Defines an audio route originating at source via control and finishing + * at sink. + */ +struct snd_soc_dapm_route { + const char *sink; + const char *control; + const char *source; +}; + /* dapm audio path between two widgets */ struct snd_soc_dapm_path { char *name; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 811d652..1ef6d94 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -841,21 +841,8 @@ int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_endpoints); -/** - * snd_soc_dapm_connect_input - connect dapm widgets - * @codec: audio codec - * @sink: name of target widget - * @control: mixer control name - * @source: name of source name - * - * Connects 2 dapm widgets together via a named audio path. The sink is - * the widget receiving the audio signal, whilst the source is the sender - * of the audio signal. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink, - const char * control, const char *source) +static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, + const char *sink, const char *control, const char *source) { struct snd_soc_dapm_path *path; struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; @@ -957,9 +944,64 @@ err: kfree(path); return ret; } + +/** + * snd_soc_dapm_connect_input - connect dapm widgets + * @codec: audio codec + * @sink: name of target widget + * @control: mixer control name + * @source: name of source name + * + * Connects 2 dapm widgets together via a named audio path. The sink is + * the widget receiving the audio signal, whilst the source is the sender + * of the audio signal. + * + * This function has been deprecated in favour of snd_soc_dapm_add_routes(). + * + * Returns 0 for success else error. + */ +int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink, + const char *control, const char *source) +{ + return snd_soc_dapm_add_route(codec, sink, control, source); +} EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input); /** + * snd_soc_dapm_add_routes - Add routes between DAPM widgets + * @codec: codec + * @route: audio routes + * @num: number of routes + * + * Connects 2 dapm widgets together via a named audio path. The sink is + * the widget receiving the audio signal, whilst the source is the sender + * of the audio signal. + * + * Returns 0 for success else error. On error all resources can be freed + * with a call to snd_soc_card_free(). + */ +int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, + const struct snd_soc_dapm_route *route, int num) +{ + int i, ret; + + for (i = 0; i < num; i++) { + ret = snd_soc_dapm_add_route(codec, route->sink, + route->control, route->source); + if (ret < 0) { + printk(KERN_ERR "Failed to add route %s->%s\n", + route->source, + route->sink); + return ret; + } + route++; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); + +/** * snd_soc_dapm_new_widgets - add new dapm widgets * @codec: audio codec * -- cgit v0.10.2 From d0cc0d3a95cc3c022ee118072d243d3670ec1663 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:55:22 +0200 Subject: [ALSA] soc - tlv320aic3x - Convert to use bulk registration APIs Signed-off-by: Mark Brown Cc: Jarkko Nikula Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 957996e..cb8365a 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -497,7 +497,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { SND_SOC_DAPM_INPUT("LINE2R"), }; -static const char *intercon[][3] = { +static const struct snd_soc_dapm_route intercon[] = { /* Left Output */ {"Left DAC Mux", "DAC_L1", "Left DAC"}, {"Left DAC Mux", "DAC_L2", "Left DAC"}, @@ -641,22 +641,15 @@ static const char *intercon[][3] = { {"Right Line Out", NULL, "Right Line2 Bypass Mixer"}, {"Mono Out", NULL, "Right Line2 Bypass Mixer"}, {"Right HP Out", NULL, "Right Line2 Bypass Mixer"}, - - /* terminator */ - {NULL, NULL, NULL}, }; static int aic3x_add_widgets(struct snd_soc_codec *codec) { - int i; - - for (i = 0; i < ARRAY_SIZE(aic3x_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &aic3x_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + ARRAY_SIZE(aic3x_dapm_widgets)); /* set up audio path interconnects */ - for (i = 0; intercon[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, intercon[i][0], - intercon[i][1], intercon[i][2]); + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); snd_soc_dapm_new_widgets(codec); return 0; -- cgit v0.10.2 From 25191c45aec54cd01b53391bb0b0e1e60377a5fc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:55:48 +0200 Subject: [ALSA] soc - Zaurus - Convert to bulk DAPM registration APIs Signed-off-by: Mark Brown Cc: Richard Purdie Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 7f32a11..852f16d 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -247,7 +247,7 @@ SND_SOC_DAPM_HP("Headset Jack", NULL), }; /* Corgi machine audio map (connections to the codec pins) */ -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* headset Jack - in = micin, out = LHPOUT*/ {"Headset Jack", NULL, "LHPOUT"}, @@ -265,8 +265,6 @@ static const char *audio_map[][3] = { /* Same as the above but no mic bias for line signals */ {"MICIN", NULL, "Line Jack"}, - - {NULL, NULL, NULL}, }; static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", @@ -303,13 +301,11 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec) } /* Add corgi specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + ARRAY_SIZE(wm8731_dapm_widgets)); /* Set up corgi specific audio path audio_map */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_sync_endpoints(codec); return 0; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 7e830b2..810f1fe 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -215,8 +215,8 @@ SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event), }; -/* Corgi machine audio_mapnections to the codec pins */ -static const char *audio_map[][3] = { +/* Corgi machine connections to the codec pins */ +static const struct snd_soc_dapm_route audio_map[] = { /* headphone connected to LHPOUT1, RHPOUT1 */ {"Headphone Jack", NULL, "LHPOUT"}, @@ -225,8 +225,6 @@ static const char *audio_map[][3] = { /* speaker connected to LOUT, ROUT */ {"Ext Spk", NULL, "ROUT"}, {"Ext Spk", NULL, "LOUT"}, - - {NULL, NULL, NULL}, }; static const char *jack_function[] = {"Off", "Headphone"}; @@ -263,13 +261,11 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec) } /* Add poodle specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + ARRAY_SIZE(wm8731_dapm_widgets)); /* Set up poodle specific audio path audio_map */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_sync_endpoints(codec); return 0; diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index d8b8372..73a6df8 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -250,7 +250,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { }; /* Spitz machine audio_map */ -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* headphone connected to LOUT1, ROUT1 */ {"Headphone Jack", NULL, "LOUT1"}, @@ -269,8 +269,6 @@ static const char *audio_map[][3] = { /* line is connected to input 1 - no bias */ {"LINPUT1", NULL, "Line Jack"}, - - {NULL, NULL, NULL}, }; static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", @@ -313,13 +311,11 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) } /* Add spitz specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + ARRAY_SIZE(wm8750_dapm_widgets)); - /* Set up spitz specific audio path audio_map */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + /* Set up spitz specific audio paths */ + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_sync_endpoints(codec); return 0; diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 7346d7e..fda2aa0 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -154,7 +154,7 @@ SND_SOC_DAPM_SPK("Speaker", NULL), }; /* tosa audio map */ -static const char *audio_map[][3] = { +static const snd_soc_dapm_route audio_map[] = { /* headphone connected to HPOUTL, HPOUTR */ {"Headphone Jack", NULL, "HPOUTL"}, @@ -173,8 +173,6 @@ static const char *audio_map[][3] = { {"Headset Jack", NULL, "HPOUTR"}, {"LINEINR", NULL, "Mic Bias"}, {"Mic Bias", NULL, "Headset Jack"}, - - {NULL, NULL, NULL}, }; static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", @@ -208,15 +206,11 @@ static int tosa_ac97_init(struct snd_soc_codec *codec) } /* add tosa specific widgets */ - for (i = 0; i < ARRAY_SIZE(tosa_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &tosa_dapm_widgets[i]); - } + snd_soc_dapm_new_controls(codec, &tosa_dapm_widgets, + ARRAY_SIZE(tosa_dapm_widgets)); /* set up tosa specific audio path audio_map */ - for (i = 0; audio_map[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); - } + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_sync_endpoints(codec); return 0; -- cgit v0.10.2 From 51e6a8411a9440f0fdba6cdd7d779e74f89debc4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:57:37 +0200 Subject: [ALSA] soc - eti_b1_wm8731 - Convert to use bulk DAPM control registration Signed-off-by: Mark Brown Cc: Frank Mandarino Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index 1347dcf..4a383a4 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -191,7 +191,7 @@ static const struct snd_soc_dapm_widget eti_b1_dapm_widgets[] = { SND_SOC_DAPM_SPK("Ext Spk", NULL), }; -static const char *intercon[][3] = { +static const struct snd_soc_dapm_route intercon[] = { /* speaker connected to LHPOUT */ {"Ext Spk", NULL, "LHPOUT"}, @@ -199,9 +199,6 @@ static const char *intercon[][3] = { /* mic is connected to Mic Jack, with WM8731 Mic Bias */ {"MICIN", NULL, "Mic Bias"}, {"Mic Bias", NULL, "Int Mic"}, - - /* terminator */ - {NULL, NULL, NULL}, }; /* @@ -209,20 +206,14 @@ static const char *intercon[][3] = { */ static int eti_b1_wm8731_init(struct snd_soc_codec *codec) { - int i; - DBG("eti_b1_wm8731_init() called\n"); /* Add specific widgets */ - for(i = 0; i < ARRAY_SIZE(eti_b1_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &eti_b1_dapm_widgets[i]); - } + snd_soc_dapm_new_controls(codec, eti_b1_dapm_widgets, + ARRAY_SIZE(eti_b1_dapm_widgets)); /* Set up specific audio path interconnects */ - for(i = 0; intercon[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, intercon[i][0], - intercon[i][1], intercon[i][2]); - } + snd_soc_dapm_add_route(codec, intercon, ARRAY_SIZE(intercon)); /* not connected */ snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); -- cgit v0.10.2 From 8f3112d7a847c2933a42ce29f17899f585d09106 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:58:03 +0200 Subject: [ALSA] soc - neo1973_wm8753 - Convert to bulk DAPM registration APIs Signed-off-by: Mark Brown Cc: Graeme Gregory Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index e469186..79c5027 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -425,8 +425,7 @@ static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { }; -/* example machine audio_mapnections */ -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route dapm_routes[] = { /* Connections to the lm4857 amp */ {"Audio Out", NULL, "LOUT1"}, @@ -449,8 +448,6 @@ static const char *audio_map[][3] = { /* Connect the ALC pins */ {"ACIN", NULL, "ACOP"}, - - {NULL, NULL, NULL}, }; static const char *lm4857_mode[] = { @@ -526,8 +523,8 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) set_scenario_endpoints(codec, NEO_AUDIO_OFF); /* Add neo1973 specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); /* add neo1973 specific controls */ for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { @@ -538,11 +535,9 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) return err; } - /* set up neo1973 specific audio path audio_mapnects */ - for (i = 0; audio_map[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); - } + /* set up neo1973 specific audio routes */ + err = snd_soc_dapm_add_routes(codec, dapm_routes, + ARRAY_SIZE(dapm_routes)); snd_soc_dapm_sync_endpoints(codec); return 0; -- cgit v0.10.2 From acf497f996aa08f03c62a3150abd7939ae23de4c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:58:30 +0200 Subject: [ALSA] soc - davinci-evm - Update for bulk DAPM registration APIs Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index fcd1652..4c70a0e 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -71,7 +71,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { }; /* davinci-evm machine audio_mapnections to the codec pins */ -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* Headphone connected to HPLOUT, HPROUT */ {"Headphone Jack", NULL, "HPLOUT"}, {"Headphone Jack", NULL, "HPROUT"}, @@ -90,23 +90,17 @@ static const char *audio_map[][3] = { {"LINE2L", NULL, "Line In"}, {"LINE1R", NULL, "Line In"}, {"LINE2R", NULL, "Line In"}, - - {NULL, NULL, NULL}, }; /* Logic for a aic3x as connected on a davinci-evm */ static int evm_aic3x_init(struct snd_soc_codec *codec) { - int i; - /* Add davinci-evm specific widgets */ - for (i = 0; i < ARRAY_SIZE(aic3x_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &aic3x_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + ARRAY_SIZE(aic3x_dapm_widgets)); /* Set up davinci-evm specific audio path audio_map */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); /* not connected */ snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0); -- cgit v0.10.2 From 1a2505988ea650b61bd07722e99080a40ff27653 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:58:57 +0200 Subject: [ALSA] soc - n810 - Update for bulk DAPM registration APIs Signed-off-by: Mark Brown Cc: Jarkko Nikula Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 6533563..c2afffb 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -177,7 +177,7 @@ static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event), }; -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { {"Headphone Jack", NULL, "HPLOUT"}, {"Headphone Jack", NULL, "HPROUT"}, @@ -217,13 +217,11 @@ static int n810_aic33_init(struct snd_soc_codec *codec) } /* Add N810 specific widgets */ - for (i = 0; i < ARRAY_SIZE(aic33_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &aic33_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, + ARRAY_SIZE(aic33_dapm_widgets)); /* Set up N810 specific audio path audio_map */ - for (i = 0; i < ARRAY_SIZE(audio_map); i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_sync_endpoints(codec); -- cgit v0.10.2 From f99a633a151686a599413bef758253dfd04887d1 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 15 May 2008 11:01:36 +0200 Subject: [ALSA] ASoC: Convert N810 machine driver to use gpiolib Use gpiolib since it is now available for OMAPs. Change also references to HW version RX44 to product name N810. Signed-off-by: Jarkko Nikula Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index c2afffb..c32487b 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -30,15 +30,15 @@ #include #include -#include +#include #include #include "omap-mcbsp.h" #include "omap-pcm.h" #include "../codecs/tlv320aic3x.h" -#define RX44_HEADSET_AMP_GPIO 10 -#define RX44_SPEAKER_AMP_GPIO 101 +#define N810_HEADSET_AMP_GPIO 10 +#define N810_SPEAKER_AMP_GPIO 101 static struct clk *sys_clkout2; static struct clk *sys_clkout2_src; @@ -154,9 +154,9 @@ static int n810_spk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) - omap_set_gpio_dataout(RX44_SPEAKER_AMP_GPIO, 1); + gpio_set_value(N810_SPEAKER_AMP_GPIO, 1); else - omap_set_gpio_dataout(RX44_SPEAKER_AMP_GPIO, 0); + gpio_set_value(N810_SPEAKER_AMP_GPIO, 0); return 0; } @@ -165,9 +165,9 @@ static int n810_jack_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) - omap_set_gpio_dataout(RX44_HEADSET_AMP_GPIO, 1); + gpio_set_value(N810_HEADSET_AMP_GPIO, 1); else - omap_set_gpio_dataout(RX44_HEADSET_AMP_GPIO, 0); + gpio_set_value(N810_HEADSET_AMP_GPIO, 0); return 0; } @@ -303,12 +303,12 @@ static int __init n810_soc_init(void) clk_set_parent(sys_clkout2_src, func96m_clk); clk_set_rate(sys_clkout2, 12000000); - if (omap_request_gpio(RX44_HEADSET_AMP_GPIO) < 0) + if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) BUG(); - if (omap_request_gpio(RX44_SPEAKER_AMP_GPIO) < 0) + if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0) BUG(); - omap_set_gpio_direction(RX44_HEADSET_AMP_GPIO, 0); - omap_set_gpio_direction(RX44_SPEAKER_AMP_GPIO, 0); + gpio_direction_output(N810_HEADSET_AMP_GPIO, 0); + gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); return 0; err2: @@ -323,6 +323,9 @@ err1: static void __exit n810_soc_exit(void) { + gpio_free(N810_SPEAKER_AMP_GPIO); + gpio_free(N810_HEADSET_AMP_GPIO); + platform_device_unregister(n810_snd_device); } -- cgit v0.10.2 From 02330fbaaded5b603cba112e4bbf62cdadec159a Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 16 May 2008 12:18:29 +0200 Subject: [ALSA] PCI168 snd-azt3328 Linux driver: another huge update - figured out 'Digital(ly) Enhanced Game Port' functionality, implemented support for it (eliminating gameport polling overhead) - removed optional joystick activation, gameport now enabled unconditionally, since we now support it via the PCI I/O space, not via conflict-prone legacy I/O (which I was thus able to DISABLE now)! - fix playback bug (a muted wave output would get unmuted upon start of playback, of course this is not what we want, thus remember mute state) - implement partial power management: when idle, lower clock rate and disable codec (reduced noise!), and disable gameport circuit when unused - instantiate OPL3 timer, too - much better implementation of snd_azf3328_mixer_write_volume_gradually() - slightly optimized interrupt handling - lots of cleanup This time, I also found a way to verify proper OPL3 operation via MIDI file playback (emulation via synth hardware). Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 5f63af6..b832333 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1,6 +1,6 @@ /* * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). - * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr + * Copyright (C) 2002, 2005 - 2008 by Andreas Mohr * * Framework borrowed from Bart Hartgers's als4000.c. * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), @@ -35,9 +35,20 @@ * (3 weeks' worth of evenings filled with driver work). * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros) * + * It is quite likely that the AZF3328 chip is the PCI cousin of the + * AZF3318 ("azt1020 pnp", "MM Pro 16") ISA chip, given very similar specs. + * * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name - * for compatibility reasons) has the following features: + * for compatibility reasons) from Azfin (joint-venture of Aztech and Fincitec, + * Fincitec acquired by National Semiconductor in 2002, together with the + * Fincitec-related company ARSmikro) has the following features: * + * - compatibility & compliance: + * - Microsoft PC 97 ("PC 97 Hardware Design Guide", + * http://www.microsoft.com/whdc/archive/pcguides.mspx) + * - Microsoft PC 98 Baseline Audio + * - MPU401 UART + * - Sound Blaster Emulation (DOS Box) * - builtin AC97 conformant codec (SNR over 80dB) * Note that "conformant" != "compliant"!! this chip's mixer register layout * *differs* from the standard AC97 layout: @@ -48,21 +59,28 @@ * addresses illegally. So far unfortunately it looks like the very flexible * ALSA AC97 support is still not enough to easily compensate for such a * grave layout violation despite all tweaks and quirks mechanisms it offers. - * - builtin genuine OPL3 + * - builtin genuine OPL3 - verified to work fine, 20080506 * - full duplex 16bit playback/record at independent sampling rate - * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? + * - MPU401 (+ legacy address support, claimed by one official spec sheet) + * FIXME: how to enable legacy addr?? * - game port (legacy address support) - * - builtin 3D enhancement (said to be YAMAHA Ymersion) * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven - * features supported) + * features supported). - See common term "Digital Enhanced Game Port"... + * (probably DirectInput 3.0 spec - confirm) + * - builtin 3D enhancement (said to be YAMAHA Ymersion) * - built-in General DirectX timer having a 20 bits counter * with 1us resolution (see below!) - * - I2S serial port for external DAC + * - I2S serial output port for external DAC * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI * - supports hardware volume control * - single chip low cost solution (128 pin QFP) * - supports programmable Sub-vendor and Sub-system ID * required for Microsoft's logo compliance (FIXME: where?) + * At least the Trident 4D Wave DX has one bit somewhere + * to enable writes to PCI subsystem VID registers, that should be it. + * This might easily be in extended PCI reg space, since PCI168 also has + * some custom data starting at 0x80. What kind of config settings + * are located in our extended PCI space anyway?? * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms * * Note that this driver now is actually *better* than the Windows driver, @@ -74,6 +92,24 @@ * - "timidity -iAv -B2,8 -Os -EFreverb=0" * - "pmidi -p 128:0 jazz.mid" * + * OPL3 hardware playback testing, try something like: + * cat /proc/asound/hwdep + * and + * aconnect -o + * Then use + * sbiload -Dhw:x,y --opl3 /usr/share/sounds/opl3/std.o3 ......./drums.o3 + * where x,y is the xx-yy number as given in hwdep. + * Then try + * pmidi -p a:b jazz.mid + * where a:b is the client number plus 0 usually, as given by aconnect above. + * Oh, and make sure to unmute the FM mixer control (doh!) + * NOTE: power use during OPL3 playback is _VERY_ high (70W --> 90W!) + * despite no CPU activity, possibly due to hindering ACPI idling somehow. + * Shouldn't be a problem of the AZF3328 chip itself, I'd hope. + * Higher PCM / FM mixer levels seem to conflict (causes crackling), + * at least sometimes. Maybe even use with hardware sequencer timer above :) + * adplay/adplug-utils might soon offer hardware-based OPL3 playback, too. + * * Certain PCI versions of this card are susceptible to DMA traffic underruns * in some systems (resulting in sound crackling/clicking/popping), * probably because they don't have a DMA FIFO buffer or so. @@ -87,6 +123,8 @@ * better than a VIA, yet ironically I still get crackling, like many other * people with the same chipset. * Possible remedies: + * - use speaker (amplifier) output instead of headphone output + * (in case crackling is due to overloaded output clipping) * - plug card into a different PCI slot, preferrably one that isn't shared * too much (this helps a lot, but not completely!) * - get rid of PCI VGA card, use AGP instead @@ -94,18 +132,23 @@ * - fiddle with PCI latency settings (setpci -v -s BUSID latency_timer=XX) * Not too helpful. * - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS - * + * * BUGS - * - full-duplex might *still* be problematic, not fully tested recently + * - full-duplex might *still* be problematic, however a recent test was fine * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated * if you set PCM output switch to "pre 3D" instead of "post 3D". * If this can't be set, then get a mixer application that Isn't Stupid (tm) * (e.g. kmix, gamix) - unfortunately several are!! - * + * - locking is not entirely clean, especially the audio stream activity + * ints --> may be racy + * - an _unconnected_ secondary joystick at the gameport will be reported + * to be "active" (floating values, not precisely -1) due to the way we need + * to read the Digital Enhanced Game Port. Not sure whether it is fixable. + * * TODO * - test MPU401 MIDI playback etc. - * - add some power micro-management (disable various units of the card - * as long as they're unused). However this requires I/O ports which I + * - add more power micro-management (disable various units of the card + * as long as they're unused). However this requires more I/O ports which I * haven't figured out yet and which thus might not even exist... * The standard suspend/resume functionality could probably make use of * some improvement, too... @@ -113,6 +156,7 @@ * - figure out some cleverly evil scheme to possibly make ALSA AC97 code * fully accept our quite incompatible ""AC97"" mixer and thus save some * code (but I'm not too optimistic that doing this is possible at all) + * - use MMIO (memory-mapped I/O)? Slightly faster access, e.g. for gameport. */ #include @@ -138,7 +182,7 @@ MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) -#define SUPPORT_JOYSTICK 1 +#define SUPPORT_GAMEPORT 1 #endif #define DEBUG_MISC 0 @@ -147,13 +191,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); #define DEBUG_PLAY_REC 0 #define DEBUG_IO 0 #define DEBUG_TIMER 0 +#define DEBUG_GAME 0 #define MIXER_TESTING 0 #if DEBUG_MISC #define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args) #else #define snd_azf3328_dbgmisc(format, args...) -#endif +#endif #if DEBUG_CALLS #define snd_azf3328_dbgcalls(format, args...) printk(format, ##args) @@ -163,25 +208,31 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); #define snd_azf3328_dbgcalls(format, args...) #define snd_azf3328_dbgcallenter() #define snd_azf3328_dbgcallleave() -#endif +#endif #if DEBUG_MIXER #define snd_azf3328_dbgmixer(format, args...) printk(format, ##args) #else #define snd_azf3328_dbgmixer(format, args...) -#endif +#endif #if DEBUG_PLAY_REC #define snd_azf3328_dbgplay(format, args...) printk(KERN_ERR format, ##args) #else #define snd_azf3328_dbgplay(format, args...) -#endif +#endif #if DEBUG_MISC #define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args) #else #define snd_azf3328_dbgtimer(format, args...) -#endif +#endif + +#if DEBUG_GAME +#define snd_azf3328_dbggame(format, args...) printk(KERN_ERR format, ##args) +#else +#define snd_azf3328_dbggame(format, args...) +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ module_param_array(index, int, NULL, 0444); @@ -195,39 +246,44 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card * module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard."); -#ifdef SUPPORT_JOYSTICK -static int joystick[SNDRV_CARDS]; -module_param_array(joystick, bool, NULL, 0444); -MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard."); -#endif - static int seqtimer_scaling = 128; module_param(seqtimer_scaling, int, 0444); MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); +struct snd_azf3328_audio_stream { + struct snd_pcm_substream *substream; + int enabled; + int running; + unsigned long portbase; +}; + +enum snd_azf3328_stream_index { + AZF_PLAYBACK = 0, + AZF_CAPTURE = 1, +}; + struct snd_azf3328 { /* often-used fields towards beginning, then grouped */ - unsigned long codec_port; - unsigned long io2_port; - unsigned long mpu_port; - unsigned long synth_port; - unsigned long mixer_port; + + unsigned long codec_io; /* usually 0xb000, size 128 */ + unsigned long game_io; /* usually 0xb400, size 8 */ + unsigned long mpu_io; /* usually 0xb800, size 4 */ + unsigned long opl3_io; /* usually 0xbc00, size 8 */ + unsigned long mixer_io; /* usually 0xc000, size 64 */ spinlock_t reg_lock; struct snd_timer *timer; - + struct snd_pcm *pcm; - struct snd_pcm_substream *playback_substream; - struct snd_pcm_substream *capture_substream; - unsigned int is_playing; - unsigned int is_recording; + struct snd_azf3328_audio_stream audio_stream[2]; struct snd_card *card; struct snd_rawmidi *rmidi; -#ifdef SUPPORT_JOYSTICK +#ifdef SUPPORT_GAMEPORT struct gameport *gameport; + int axes[4]; #endif struct pci_dev *pci; @@ -236,10 +292,10 @@ struct snd_azf3328 { #ifdef CONFIG_PM /* register value containers for power management * Note: not always full I/O range preserved (just like Win driver!) */ - u16 saved_regs_codec [AZF_IO_SIZE_CODEC_PM / 2]; - u16 saved_regs_io2 [AZF_IO_SIZE_IO2_PM / 2]; - u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2]; - u16 saved_regs_synth[AZF_IO_SIZE_SYNTH_PM / 2]; + u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2]; + u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2]; + u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2]; + u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2]; u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2]; #endif }; @@ -252,126 +308,181 @@ static const struct pci_device_id snd_azf3328_ids[] = { MODULE_DEVICE_TABLE(pci, snd_azf3328_ids); + +static int +snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set) +{ + u8 prev = inb(reg), new; + + new = (do_set) ? (prev|mask) : (prev & ~mask); + /* we need to always write the new value no matter whether it differs + * or not, since some register bits don't indicate their setting */ + outb(new, reg); + if (new != prev) + return 1; + + return 0; +} + +static int +snd_azf3328_io_reg_setw(unsigned reg, u16 mask, int do_set) +{ + u16 prev = inw(reg), new; + + new = (do_set) ? (prev|mask) : (prev & ~mask); + /* we need to always write the new value no matter whether it differs + * or not, since some register bits don't indicate their setting */ + outw(new, reg); + if (new != prev) + return 1; + + return 0; +} + static inline void -snd_azf3328_codec_outb(const struct snd_azf3328 *chip, int reg, u8 value) +snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value) { - outb(value, chip->codec_port + reg); + outb(value, chip->codec_io + reg); } static inline u8 -snd_azf3328_codec_inb(const struct snd_azf3328 *chip, int reg) +snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg) { - return inb(chip->codec_port + reg); + return inb(chip->codec_io + reg); } static inline void -snd_azf3328_codec_outw(const struct snd_azf3328 *chip, int reg, u16 value) +snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value) { - outw(value, chip->codec_port + reg); + outw(value, chip->codec_io + reg); } static inline u16 -snd_azf3328_codec_inw(const struct snd_azf3328 *chip, int reg) +snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg) +{ + return inw(chip->codec_io + reg); +} + +static inline void +snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value) +{ + outl(value, chip->codec_io + reg); +} + +static inline u32 +snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg) { - return inw(chip->codec_port + reg); + return inl(chip->codec_io + reg); } static inline void -snd_azf3328_codec_outl(const struct snd_azf3328 *chip, int reg, u32 value) +snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value) { - outl(value, chip->codec_port + reg); + outb(value, chip->game_io + reg); } static inline void -snd_azf3328_io2_outb(const struct snd_azf3328 *chip, int reg, u8 value) +snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value) { - outb(value, chip->io2_port + reg); + outw(value, chip->game_io + reg); } static inline u8 -snd_azf3328_io2_inb(const struct snd_azf3328 *chip, int reg) +snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg) +{ + return inb(chip->game_io + reg); +} + +static inline u16 +snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg) { - return inb(chip->io2_port + reg); + return inw(chip->game_io + reg); } static inline void -snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, int reg, u16 value) +snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value) { - outw(value, chip->mixer_port + reg); + outw(value, chip->mixer_io + reg); } static inline u16 -snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, int reg) +snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg) { - return inw(chip->mixer_port + reg); + return inw(chip->mixer_io + reg); } -static void -snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, int reg, int do_mute) +#define AZF_MUTE_BIT 0x80 + +static int +snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, + unsigned reg, int do_mute +) { - unsigned long portbase = chip->mixer_port + reg + 1; - unsigned char oldval; + unsigned long portbase = chip->mixer_io + reg + 1; + int updated; /* the mute bit is on the *second* (i.e. right) register of a * left/right channel setting */ - oldval = inb(portbase); - if (do_mute) - oldval |= 0x80; - else - oldval &= ~0x80; - outb(oldval, portbase); + updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute); + + /* indicate whether it was muted before */ + return (do_mute) ? !updated : updated; } static void -snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay) +snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, + unsigned reg, + unsigned char dst_vol_left, + unsigned char dst_vol_right, + int chan_sel, int delay +) { - unsigned long portbase = chip->mixer_port + reg; + unsigned long portbase = chip->mixer_io + reg; unsigned char curr_vol_left = 0, curr_vol_right = 0; - int left_done = 0, right_done = 0; - + int left_change = 0, right_change = 0; + snd_azf3328_dbgcallenter(); - if (chan_sel & SET_CHAN_LEFT) + + if (chan_sel & SET_CHAN_LEFT) { curr_vol_left = inb(portbase + 1); - else - left_done = 1; - if (chan_sel & SET_CHAN_RIGHT) + + /* take care of muting flag contained in left channel */ + if (curr_vol_left & AZF_MUTE_BIT) + dst_vol_left |= AZF_MUTE_BIT; + else + dst_vol_left &= ~AZF_MUTE_BIT; + + left_change = (curr_vol_left > dst_vol_left) ? -1 : 1; + } + + if (chan_sel & SET_CHAN_RIGHT) { curr_vol_right = inb(portbase + 0); - else - right_done = 1; - - /* take care of muting flag (0x80) contained in left channel */ - if (curr_vol_left & 0x80) - dst_vol_left |= 0x80; - else - dst_vol_left &= ~0x80; + + right_change = (curr_vol_right > dst_vol_right) ? -1 : 1; + } do { - if (!left_done) { - if (curr_vol_left > dst_vol_left) - curr_vol_left--; - else - if (curr_vol_left < dst_vol_left) - curr_vol_left++; - else - left_done = 1; - outb(curr_vol_left, portbase + 1); + if (left_change) { + if (curr_vol_left != dst_vol_left) { + curr_vol_left += left_change; + outb(curr_vol_left, portbase + 1); + } else + left_change = 0; } - if (!right_done) { - if (curr_vol_right > dst_vol_right) - curr_vol_right--; - else - if (curr_vol_right < dst_vol_right) - curr_vol_right++; - else - right_done = 1; + if (right_change) { + if (curr_vol_right != dst_vol_right) { + curr_vol_right += right_change; + /* during volume change, the right channel is crackling * somewhat more than the left channel, unfortunately. * This seems to be a hardware issue. */ - outb(curr_vol_right, portbase + 0); + outb(curr_vol_right, portbase + 0); + } else + right_change = 0; } if (delay) mdelay(delay); - } while ((!left_done) || (!right_done)); + } while ((left_change) || (right_change)); snd_azf3328_dbgcallleave(); } @@ -379,7 +490,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg * general mixer element */ struct azf3328_mixer_reg { - unsigned int reg; + unsigned reg; unsigned int lchan_shift, rchan_shift; unsigned int mask; unsigned int invert: 1; @@ -544,13 +655,14 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol, "Mix", "Mic" }; static const char * const texts3[] = { - "Mic", "CD", "Video", "Aux", + "Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone" }; static const char * const texts4[] = { "pre 3D", "post 3D" }; struct azf3328_mixer_reg reg; + const char *p = NULL; snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -561,18 +673,20 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol, if (reg.reg == IDX_MIXER_ADVCTL2) { switch(reg.lchan_shift) { case 8: /* modem out sel */ - strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]); + p = texts1[uinfo->value.enumerated.item]; break; case 9: /* mono sel source */ - strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]); + p = texts2[uinfo->value.enumerated.item]; break; case 15: /* PCM Out Path */ - strcpy(uinfo->value.enumerated.name, texts4[uinfo->value.enumerated.item]); + p = texts4[uinfo->value.enumerated.item]; break; } } else - strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item] -); + if (reg.reg == IDX_MIXER_REC_SELECT) + p = texts3[uinfo->value.enumerated.item]; + + strcpy(uinfo->value.enumerated.name, p); return 0; } @@ -583,7 +697,7 @@ snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol, struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); struct azf3328_mixer_reg reg; unsigned short val; - + snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); val = snd_azf3328_mixer_inw(chip, reg.reg); if (reg.reg == IDX_MIXER_REC_SELECT) { @@ -605,7 +719,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol, struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); struct azf3328_mixer_reg reg; unsigned int oreg, nreg, val; - + snd_azf3328_mixer_reg_decode(®, kcontrol->private_value); oreg = snd_azf3328_mixer_inw(chip, reg.reg); val = oreg; @@ -717,15 +831,16 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip) snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000); /* mute and zero volume channels */ - for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) { snd_azf3328_mixer_outw(chip, snd_azf3328_init_values[idx][0], snd_azf3328_init_values[idx][1]); } - + /* add mixer controls */ sw = snd_azf3328_mixer_controls; - for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls); idx++, sw++) { + for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls); + ++idx, ++sw) { if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0) return err; } @@ -757,8 +872,8 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream) } static void -snd_azf3328_setfmt(struct snd_azf3328 *chip, - unsigned int reg, +snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, + unsigned reg, unsigned int bitrate, unsigned int format_width, unsigned int channels @@ -769,24 +884,25 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip, snd_azf3328_dbgcallenter(); switch (bitrate) { - case 4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; - case 4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; - case 5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */ - case 6620: val |= SOUNDFORMAT_FREQ_6620; break; - case 8000: val |= SOUNDFORMAT_FREQ_8000; break; - case 9600: val |= SOUNDFORMAT_FREQ_9600; break; - case 11025: val |= SOUNDFORMAT_FREQ_11025; break; - case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; - case 16000: val |= SOUNDFORMAT_FREQ_16000; break; - case 22050: val |= SOUNDFORMAT_FREQ_22050; break; - case 32000: val |= SOUNDFORMAT_FREQ_32000; break; - case 44100: val |= SOUNDFORMAT_FREQ_44100; break; - case 48000: val |= SOUNDFORMAT_FREQ_48000; break; - case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; + case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; + case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; + case AZF_FREQ_5512: + /* the AZF3328 names it "5510" for some strange reason */ + val |= SOUNDFORMAT_FREQ_5510; break; + case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break; + case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break; + case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break; + case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break; + case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; + case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break; + case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break; + case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break; default: snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); - val |= SOUNDFORMAT_FREQ_44100; - break; + /* fall-through */ + case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break; + case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break; + case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; } /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ @@ -805,10 +921,10 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip, val |= SOUNDFORMAT_FLAG_16BIT; spin_lock_irqsave(&chip->reg_lock, flags); - + /* set bitrate/format */ snd_azf3328_codec_outw(chip, reg, val); - + /* changing the bitrate/format settings switches off the * audio output with an annoying click in case of 8/16bit format change * (maybe shutting down DAC/ADC?), thus immediately @@ -830,31 +946,81 @@ snd_azf3328_setfmt(struct snd_azf3328 *chip, snd_azf3328_dbgcallleave(); } +static inline void +snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, + unsigned reg +) +{ + /* choose lowest frequency for low power consumption. + * While this will cause louder noise due to rather coarse frequency, + * it should never matter since output should always + * get disabled properly when idle anyway. */ + snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1); +} + +static inline void +snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable) +{ + /* no idea what exactly is being done here, but I strongly assume it's + * PM related */ + snd_azf3328_io_reg_setw( + chip->codec_io+IDX_IO_6AH, + IO_6A_PAUSE_PLAYBACK_BIT8, + !enable + ); +} + +static void +snd_azf3328_codec_activity(struct snd_azf3328 *chip, + enum snd_azf3328_stream_index stream_type, + int enable +) +{ + int need_change = (chip->audio_stream[stream_type].running != enable); + + snd_azf3328_dbgplay( + "codec_activity: type %d, enable %d, need_change %d\n", + stream_type, enable, need_change + ); + if (need_change) { + enum snd_azf3328_stream_index other = + (stream_type == AZF_PLAYBACK) ? + AZF_CAPTURE : AZF_PLAYBACK; + /* small check to prevent shutting down the other party + * in case it's active */ + if ((enable) || !(chip->audio_stream[other].running)) + snd_azf3328_codec_enable(chip, enable); + + /* ...and adjust clock, too + * (reduce noise and power consumption) */ + if (!enable) + snd_azf3328_codec_setfmt_lowpower( + chip, + chip->audio_stream[stream_type].portbase + + IDX_IO_PLAY_SOUNDFORMAT + ); + } + chip->audio_stream[stream_type].running = enable; +} + static void snd_azf3328_setdmaa(struct snd_azf3328 *chip, long unsigned int addr, unsigned int count, unsigned int size, - int do_recording) + enum snd_azf3328_stream_index stream_type +) { - unsigned long flags, portbase; - unsigned int is_running; - snd_azf3328_dbgcallenter(); - if (do_recording) { - /* access capture registers, i.e. skip playback reg section */ - portbase = chip->codec_port + 0x20; - is_running = chip->is_recording; - } else { - /* access the playback register section */ - portbase = chip->codec_port + 0x00; - is_running = chip->is_playing; - } + if (!chip->audio_stream[stream_type].running) { + /* AZF3328 uses a two buffer pointer DMA playback approach */ + + unsigned long flags, portbase, addr_area2; + + /* width 32bit (prevent overflow): */ + unsigned long count_areas, count_tmp; - /* AZF3328 uses a two buffer pointer DMA playback approach */ - if (!is_running) { - unsigned long addr_area2; - unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */ + portbase = chip->audio_stream[stream_type].portbase; count_areas = size/2; addr_area2 = addr+count_areas; count_areas--; /* max. index */ @@ -884,11 +1050,11 @@ snd_azf3328_playback_prepare(struct snd_pcm_substream *substream) snd_azf3328_dbgcallenter(); #if 0 - snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, + snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels); - snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0); + snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK); #endif snd_azf3328_dbgcallleave(); return 0; @@ -906,11 +1072,11 @@ snd_azf3328_capture_prepare(struct snd_pcm_substream *substream) snd_azf3328_dbgcallenter(); #if 0 - snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, + snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels); - snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1); + snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE); #endif snd_azf3328_dbgcallleave(); return 0; @@ -923,6 +1089,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_pcm_runtime *runtime = substream->runtime; int result = 0; unsigned int status1; + int previously_muted; snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd); @@ -930,20 +1097,23 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: snd_azf3328_dbgplay("START PLAYBACK\n"); - /* mute WaveOut */ - snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); + /* mute WaveOut (avoid clicking during setup) */ + previously_muted = + snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); - snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, + snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels); spin_lock(&chip->reg_lock); - /* stop playback */ + /* first, remember current value: */ status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); + + /* stop playback */ status1 &= ~DMA_RESUME; snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); - + /* FIXME: clear interrupts or what??? */ snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff); spin_unlock(&chip->reg_lock); @@ -951,7 +1121,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd) snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), - 0); + AZF_PLAYBACK); spin_lock(&chip->reg_lock); #ifdef WIN9X @@ -978,30 +1148,35 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd) DMA_SOMETHING_ELSE); #endif spin_unlock(&chip->reg_lock); + snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1); /* now unmute WaveOut */ - snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); + if (!previously_muted) + snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); - chip->is_playing = 1; snd_azf3328_dbgplay("STARTED PLAYBACK\n"); break; case SNDRV_PCM_TRIGGER_RESUME: snd_azf3328_dbgplay("RESUME PLAYBACK\n"); /* resume playback if we were active */ - if (chip->is_playing) + spin_lock(&chip->reg_lock); + if (chip->audio_stream[AZF_PLAYBACK].running) snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME); + spin_unlock(&chip->reg_lock); break; case SNDRV_PCM_TRIGGER_STOP: snd_azf3328_dbgplay("STOP PLAYBACK\n"); - /* mute WaveOut */ - snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); + /* mute WaveOut (avoid clicking during setup) */ + previously_muted = + snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); spin_lock(&chip->reg_lock); - /* stop playback */ + /* first, remember current value: */ status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); + /* stop playback */ status1 &= ~DMA_RESUME; snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); @@ -1013,10 +1188,12 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd) status1 &= ~DMA_PLAY_SOMETHING1; snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); spin_unlock(&chip->reg_lock); - + snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0); + /* now unmute WaveOut */ - snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); - chip->is_playing = 0; + if (!previously_muted) + snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); + snd_azf3328_dbgplay("STOPPED PLAYBACK\n"); break; case SNDRV_PCM_TRIGGER_SUSPEND: @@ -1035,7 +1212,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd) printk(KERN_ERR "FIXME: unknown trigger mode!\n"); return -EINVAL; } - + snd_azf3328_dbgcallleave(); return result; } @@ -1057,17 +1234,19 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd) snd_azf3328_dbgplay("START CAPTURE\n"); - snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, + snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels); spin_lock(&chip->reg_lock); - /* stop recording */ + /* first, remember current value: */ status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS); + + /* stop recording */ status1 &= ~DMA_RESUME; snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); - + /* FIXME: clear interrupts or what??? */ snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff); spin_unlock(&chip->reg_lock); @@ -1075,7 +1254,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd) snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), - 1); + AZF_CAPTURE); spin_lock(&chip->reg_lock); #ifdef WIN9X @@ -1102,24 +1281,27 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd) DMA_SOMETHING_ELSE); #endif spin_unlock(&chip->reg_lock); + snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1); - chip->is_recording = 1; snd_azf3328_dbgplay("STARTED CAPTURE\n"); break; case SNDRV_PCM_TRIGGER_RESUME: snd_azf3328_dbgplay("RESUME CAPTURE\n"); /* resume recording if we were active */ - if (chip->is_recording) + spin_lock(&chip->reg_lock); + if (chip->audio_stream[AZF_CAPTURE].running) snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME); + spin_unlock(&chip->reg_lock); break; case SNDRV_PCM_TRIGGER_STOP: snd_azf3328_dbgplay("STOP CAPTURE\n"); spin_lock(&chip->reg_lock); - /* stop recording */ + /* first, remember current value: */ status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS); + /* stop recording */ status1 &= ~DMA_RESUME; snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); @@ -1129,8 +1311,8 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd) status1 &= ~DMA_PLAY_SOMETHING1; snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1); spin_unlock(&chip->reg_lock); - - chip->is_recording = 0; + snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0); + snd_azf3328_dbgplay("STOPPED CAPTURE\n"); break; case SNDRV_PCM_TRIGGER_SUSPEND: @@ -1149,7 +1331,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd) printk(KERN_ERR "FIXME: unknown trigger mode!\n"); return -EINVAL; } - + snd_azf3328_dbgcallleave(); return result; } @@ -1162,11 +1344,11 @@ snd_azf3328_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t frmres; #ifdef QUERY_HARDWARE - bufptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_START_1); + bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1); #else bufptr = substream->runtime->dma_addr; #endif - result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS); + result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS); /* calculate offset */ result -= bufptr; @@ -1183,11 +1365,11 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t frmres; #ifdef QUERY_HARDWARE - bufptr = inl(chip->codec_port+IDX_IO_REC_DMA_START_1); + bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1); #else bufptr = substream->runtime->dma_addr; #endif - result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS); + result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS); /* calculate offset */ result -= bufptr; @@ -1196,27 +1378,233 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream) return frmres; } +/******************************************************************/ + +#ifdef SUPPORT_GAMEPORT +static inline void +snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable) +{ + snd_azf3328_io_reg_setb( + chip->game_io+IDX_GAME_HWCONFIG, + GAME_HWCFG_IRQ_ENABLE, + enable + ); +} + +static inline void +snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable) +{ + snd_azf3328_io_reg_setb( + chip->game_io+IDX_GAME_HWCONFIG, + GAME_HWCFG_LEGACY_ADDRESS_ENABLE, + enable + ); +} + +static inline void +snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable) +{ + snd_azf3328_io_reg_setw( + chip->codec_io+IDX_IO_6AH, + IO_6A_SOMETHING2_GAMEPORT, + !enable + ); +} + +static inline void +snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip) +{ + /* + * skeleton handler only + * (we do not want axis reading in interrupt handler - too much load!) + */ + snd_azf3328_dbggame("gameport irq\n"); + + /* this should ACK the gameport IRQ properly, hopefully. */ + snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE); +} + +static int +snd_azf3328_gameport_open(struct gameport *gameport, int mode) +{ + struct snd_azf3328 *chip = gameport_get_port_data(gameport); + int res; + + snd_azf3328_dbggame("gameport_open, mode %d\n", mode); + switch (mode) { + case GAMEPORT_MODE_COOKED: + case GAMEPORT_MODE_RAW: + res = 0; + break; + default: + res = -1; + break; + } + + snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0)); + + return res; +} + +static void +snd_azf3328_gameport_close(struct gameport *gameport) +{ + struct snd_azf3328 *chip = gameport_get_port_data(gameport); + + snd_azf3328_dbggame("gameport_close\n"); + snd_azf3328_gameport_axis_circuit_enable(chip, 0); +} + +static int +snd_azf3328_gameport_cooked_read(struct gameport *gameport, + int *axes, + int *buttons +) +{ + struct snd_azf3328 *chip = gameport_get_port_data(gameport); + int i; + u8 val; + unsigned long flags; + + snd_assert(chip, return 0); + + spin_lock_irqsave(&chip->reg_lock, flags); + val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE); + *buttons = (~(val) >> 4) & 0xf; + + /* ok, this one is a bit dirty: cooked_read is being polled by a timer, + * thus we're atomic and cannot actively wait in here + * (which would be useful for us since it probably would be better + * to trigger a measurement in here, then wait a short amount of + * time until it's finished, then read values of _this_ measurement). + * + * Thus we simply resort to reading values if they're available already + * and trigger the next measurement. + */ + + val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG); + if (val & GAME_AXES_SAMPLING_READY) { + for (i = 0; i < 4; ++i) { + /* configure the axis to read */ + val = (i << 4) | 0x0f; + snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val); + + chip->axes[i] = snd_azf3328_game_inw( + chip, IDX_GAME_AXIS_VALUE + ); + } + } + + /* trigger next axes sampling, to be evaluated the next time we + * enter this function */ + + /* for some very, very strange reason we cannot enable + * Measurement Ready monitoring for all axes here, + * at least not when only one joystick connected */ + val = 0x03; /* we're able to monitor axes 1 and 2 only */ + snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val); + + snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff); + spin_unlock_irqrestore(&chip->reg_lock, flags); + + for (i = 0; i < 4; i++) { + axes[i] = chip->axes[i]; + if (axes[i] == 0xffff) + axes[i] = -1; + } + + snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n", + axes[0], axes[1], axes[2], axes[3], *buttons + ); + + return 0; +} + +static int __devinit +snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) +{ + struct gameport *gp; + + int io_port = chip->game_io; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n"); + return -ENOMEM; + } + + gameport_set_name(gp, "AZF3328 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gameport_set_dev_parent(gp, &chip->pci->dev); + gp->io = io_port; + gameport_set_port_data(gp, chip); + + gp->open = snd_azf3328_gameport_open; + gp->close = snd_azf3328_gameport_close; + gp->fuzz = 16; /* seems ok */ + gp->cooked_read = snd_azf3328_gameport_cooked_read; + + /* DISABLE legacy address: we don't need it! */ + snd_azf3328_gameport_legacy_address_enable(chip, 0); + + snd_azf3328_gameport_axis_circuit_enable(chip, 0); + + gameport_register_port(chip->gameport); + + return 0; +} + +static void +snd_azf3328_gameport_free(struct snd_azf3328 *chip) +{ + if (chip->gameport) { + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + } + snd_azf3328_gameport_irq_enable(chip, 0); +} +#else +static inline int +snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; } +static inline void +snd_azf3328_gameport_free(struct snd_azf3328 *chip) { } +static inline void +snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip) +{ + printk(KERN_WARNING "huh, game port IRQ occurred!?\n"); +} +#endif /* SUPPORT_GAMEPORT */ + +/******************************************************************/ + static irqreturn_t snd_azf3328_interrupt(int irq, void *dev_id) { struct snd_azf3328 *chip = dev_id; u8 status, which; +#if DEBUG_PLAY_REC static unsigned long irq_count; +#endif status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS); /* fast path out, to ease interrupt sharing */ - if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER))) + if (!(status & + (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER) + )) return IRQ_NONE; /* must be interrupt for another device */ snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n", - irq_count, + irq_count++ /* debug-only */, snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS), snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE), status); - + if (status & IRQ_TIMER) { - /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */ + /* snd_azf3328_dbgplay("timer %ld\n", + snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE) + & TIMER_VALUE_MASK + ); */ if (chip->timer) snd_timer_interrupt(chip->timer, chip->timer->sticks); /* ACK timer */ @@ -1232,11 +1620,16 @@ snd_azf3328_interrupt(int irq, void *dev_id) snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which); spin_unlock(&chip->reg_lock); - if (chip->pcm && chip->playback_substream) { - snd_pcm_period_elapsed(chip->playback_substream); + if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) { + snd_pcm_period_elapsed( + chip->audio_stream[AZF_PLAYBACK].substream + ); snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n", which, - inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS)); + snd_azf3328_codec_inl( + chip, IDX_IO_PLAY_DMA_CURRPOS + ) + ); } else snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); if (which & IRQ_PLAY_SOMETHING) @@ -1249,16 +1642,23 @@ snd_azf3328_interrupt(int irq, void *dev_id) snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which); spin_unlock(&chip->reg_lock); - if (chip->pcm && chip->capture_substream) { - snd_pcm_period_elapsed(chip->capture_substream); + if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) { + snd_pcm_period_elapsed( + chip->audio_stream[AZF_CAPTURE].substream + ); snd_azf3328_dbgplay("REC period done (#%x), @ %x\n", which, - inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS)); + snd_azf3328_codec_inl( + chip, IDX_IO_REC_DMA_CURRPOS + ) + ); } else snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); if (which & IRQ_REC_SOMETHING) snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n"); } + if (status & IRQ_GAMEPORT) + snd_azf3328_gameport_interrupt(chip); /* MPU401 has less critical IRQ requirements * than timer and playback/recording, right? */ if (status & IRQ_MPU401) { @@ -1268,7 +1668,6 @@ snd_azf3328_interrupt(int irq, void *dev_id) * If so, then I don't know how... */ snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n"); } - irq_count++; return IRQ_HANDLED; } @@ -1287,8 +1686,8 @@ static const struct snd_pcm_hardware snd_azf3328_playback = .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT, - .rate_min = 4000, - .rate_max = 66200, + .rate_min = AZF_FREQ_4000, + .rate_max = AZF_FREQ_66200, .channels_min = 1, .channels_max = 2, .buffer_bytes_max = 65536, @@ -1315,8 +1714,8 @@ static const struct snd_pcm_hardware snd_azf3328_capture = .rates = SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT, - .rate_min = 4000, - .rate_max = 66200, + .rate_min = AZF_FREQ_4000, + .rate_max = AZF_FREQ_66200, .channels_min = 1, .channels_max = 2, .buffer_bytes_max = 65536, @@ -1329,10 +1728,24 @@ static const struct snd_pcm_hardware snd_azf3328_capture = static unsigned int snd_azf3328_fixed_rates[] = { - 4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000, - 44100, 48000, 66200 }; + AZF_FREQ_4000, + AZF_FREQ_4800, + AZF_FREQ_5512, + AZF_FREQ_6620, + AZF_FREQ_8000, + AZF_FREQ_9600, + AZF_FREQ_11025, + AZF_FREQ_13240, + AZF_FREQ_16000, + AZF_FREQ_22050, + AZF_FREQ_32000, + AZF_FREQ_44100, + AZF_FREQ_48000, + AZF_FREQ_66200 +}; + static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = { - .count = ARRAY_SIZE(snd_azf3328_fixed_rates), + .count = ARRAY_SIZE(snd_azf3328_fixed_rates), .list = snd_azf3328_fixed_rates, .mask = 0, }; @@ -1346,7 +1759,7 @@ snd_azf3328_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; snd_azf3328_dbgcallenter(); - chip->playback_substream = substream; + chip->audio_stream[AZF_PLAYBACK].substream = substream; runtime->hw = snd_azf3328_playback; snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &snd_azf3328_hw_constraints_rates); @@ -1361,7 +1774,7 @@ snd_azf3328_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; snd_azf3328_dbgcallenter(); - chip->capture_substream = substream; + chip->audio_stream[AZF_CAPTURE].substream = substream; runtime->hw = snd_azf3328_capture; snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &snd_azf3328_hw_constraints_rates); @@ -1375,7 +1788,7 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream) struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); snd_azf3328_dbgcallenter(); - chip->playback_substream = NULL; + chip->audio_stream[AZF_PLAYBACK].substream = NULL; snd_azf3328_dbgcallleave(); return 0; } @@ -1386,7 +1799,7 @@ snd_azf3328_capture_close(struct snd_pcm_substream *substream) struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); snd_azf3328_dbgcallenter(); - chip->capture_substream = NULL; + chip->audio_stream[AZF_CAPTURE].substream = NULL; snd_azf3328_dbgcallleave(); return 0; } @@ -1441,102 +1854,8 @@ snd_azf3328_pcm(struct snd_azf3328 *chip, int device) /******************************************************************/ -#ifdef SUPPORT_JOYSTICK -static int __devinit -snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev) -{ - struct gameport *gp; - struct resource *r; - - if (!joystick[dev]) - return -ENODEV; - - if (!(r = request_region(0x200, 8, "AZF3328 gameport"))) { - printk(KERN_WARNING "azt3328: cannot reserve joystick ports\n"); - return -EBUSY; - } - - chip->gameport = gp = gameport_allocate_port(); - if (!gp) { - printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n"); - release_and_free_resource(r); - return -ENOMEM; - } - - gameport_set_name(gp, "AZF3328 Gameport"); - gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); - gameport_set_dev_parent(gp, &chip->pci->dev); - gp->io = 0x200; - gameport_set_port_data(gp, r); - - snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR, - snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY); - - gameport_register_port(chip->gameport); - - return 0; -} - -static void -snd_azf3328_free_joystick(struct snd_azf3328 *chip) -{ - if (chip->gameport) { - struct resource *r = gameport_get_port_data(chip->gameport); - - gameport_unregister_port(chip->gameport); - chip->gameport = NULL; - /* disable gameport */ - snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR, - snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY); - release_and_free_resource(r); - } -} -#else -static inline int -snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev) { return -ENOSYS; } -static inline void -snd_azf3328_free_joystick(struct snd_azf3328 *chip) { } -#endif - -/******************************************************************/ - -static int -snd_azf3328_free(struct snd_azf3328 *chip) -{ - if (chip->irq < 0) - goto __end_hw; - - /* reset (close) mixer */ - snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */ - snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000); - - /* interrupt setup - mask everything (FIXME!) */ - /* well, at least we know how to disable the timer IRQ */ - snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); - - if (chip->irq >= 0) - synchronize_irq(chip->irq); -__end_hw: - snd_azf3328_free_joystick(chip); - if (chip->irq >= 0) - free_irq(chip->irq, chip); - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - - kfree(chip); - return 0; -} - -static int -snd_azf3328_dev_free(struct snd_device *device) -{ - struct snd_azf3328 *chip = device->device_data; - return snd_azf3328_free(chip); -} - -/******************************************************************/ - -/*** NOTE: the physical timer resolution actually is 1024000 ticks per second, +/*** NOTE: the physical timer resolution actually is 1024000 ticks per second + *** (probably derived from main crystal via a divider of 24), *** but announcing those attributes to user-space would make programs *** configure the timer to a 1 tick value, resulting in an absolutely fatal *** timer IRQ storm. @@ -1564,7 +1883,7 @@ snd_azf3328_timer_start(struct snd_timer *timer) delay = 49; /* minimum time is 49 ticks */ } snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); - delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ; + delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; spin_lock_irqsave(&chip->reg_lock, flags); snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay); spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -1582,7 +1901,7 @@ snd_azf3328_timer_stop(struct snd_timer *timer) chip = snd_timer_chip(timer); spin_lock_irqsave(&chip->reg_lock, flags); /* disable timer countdown and interrupt */ - /* FIXME: should we write TIMER_ACK_IRQ here? */ + /* FIXME: should we write TIMER_IRQ_ACK here? */ snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_azf3328_dbgcallleave(); @@ -1626,9 +1945,10 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device) snd_azf3328_timer_hw.resolution *= seqtimer_scaling; snd_azf3328_timer_hw.ticks /= seqtimer_scaling; - if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) { + + err = snd_timer_new(chip->card, "AZF3328", &tid, &timer); + if (err < 0) goto out; - } strcpy(timer->name, "AZF3328 timer"); timer->private_data = chip; @@ -1636,6 +1956,8 @@ snd_azf3328_timer(struct snd_azf3328 *chip, int device) chip->timer = timer; + snd_azf3328_timer_stop(timer); + err = 0; out: @@ -1645,10 +1967,44 @@ out: /******************************************************************/ +static int +snd_azf3328_free(struct snd_azf3328 *chip) +{ + if (chip->irq < 0) + goto __end_hw; + + /* reset (close) mixer: + * first mute master volume, then reset + */ + snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); + snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000); + + snd_azf3328_timer_stop(chip->timer); + snd_azf3328_gameport_free(chip); + + if (chip->irq >= 0) + synchronize_irq(chip->irq); +__end_hw: + if (chip->irq >= 0) + free_irq(chip->irq, chip); + pci_release_regions(chip->pci); + pci_disable_device(chip->pci); + + kfree(chip); + return 0; +} + +static int +snd_azf3328_dev_free(struct snd_device *device) +{ + struct snd_azf3328 *chip = device->device_data; + return snd_azf3328_free(chip); +} + #if 0 /* check whether a bit can be modified */ static void -snd_azf3328_test_bit(unsigned int reg, int bit) +snd_azf3328_test_bit(unsigned unsigned reg, int bit) { unsigned char val, valoff, valon; @@ -1659,42 +2015,74 @@ snd_azf3328_test_bit(unsigned int reg, int bit) outb(val|(1 << bit), reg); valon = inb(reg); - + outb(val, reg); - printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", reg, bit, val, valoff, valon); + printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", + reg, bit, val, valoff, valon + ); } #endif -#if DEBUG_MISC -static void +static inline void snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) { +#if DEBUG_MISC u16 tmp; - snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); - - snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5)); - - for (tmp=0; tmp <= 0x01; tmp += 1) - snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); + snd_azf3328_dbgmisc( + "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, " + "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n", + chip->codec_io, chip->game_io, chip->mpu_io, + chip->opl3_io, chip->mixer_io, chip->irq + ); + + snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n", + snd_azf3328_game_inb(chip, 0), + snd_azf3328_game_inb(chip, 1), + snd_azf3328_game_inb(chip, 2), + snd_azf3328_game_inb(chip, 3), + snd_azf3328_game_inb(chip, 4), + snd_azf3328_game_inb(chip, 5) + ); + + for (tmp = 0; tmp < 0x07; tmp += 1) + snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp)); + + for (tmp = 0; tmp <= 0x07; tmp += 1) + snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n", + tmp, inb(0x200 + tmp), inb(0x208 + tmp)); + + for (tmp = 0; tmp <= 0x01; tmp += 1) + snd_azf3328_dbgmisc( + "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, " + "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n", + tmp, + inb(0x300 + tmp), + inb(0x310 + tmp), + inb(0x320 + tmp), + inb(0x330 + tmp), + inb(0x388 + tmp), + inb(0x38c + tmp) + ); for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) - snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); + snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", + tmp, snd_azf3328_codec_inw(chip, tmp) + ); for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) - snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); + snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", + tmp, snd_azf3328_mixer_inw(chip, tmp) + ); +#endif /* DEBUG_MISC */ } -#else -static inline void -snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {} -#endif static int __devinit snd_azf3328_create(struct snd_card *card, - struct pci_dev *pci, - unsigned long device_type, - struct snd_azf3328 ** rchip) + struct pci_dev *pci, + unsigned long device_type, + struct snd_azf3328 **rchip) { struct snd_azf3328 *chip; int err; @@ -1705,7 +2093,8 @@ snd_azf3328_create(struct snd_card *card, *rchip = NULL; - if ((err = pci_enable_device(pci)) < 0) + err = pci_enable_device(pci); + if (err < 0) return err; chip = kzalloc(sizeof(*chip), GFP_KERNEL); @@ -1721,20 +2110,25 @@ snd_azf3328_create(struct snd_card *card, /* check if we can restrict PCI DMA transfers to 24 bits */ if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 || pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) { - snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n"); + snd_printk(KERN_ERR "architecture does not support " + "24bit PCI busmaster DMA\n" + ); err = -ENXIO; goto out_err; } - if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) { + err = pci_request_regions(pci, "Aztech AZF3328"); + if (err < 0) goto out_err; - } - chip->codec_port = pci_resource_start(pci, 0); - chip->io2_port = pci_resource_start(pci, 1); - chip->mpu_port = pci_resource_start(pci, 2); - chip->synth_port = pci_resource_start(pci, 3); - chip->mixer_port = pci_resource_start(pci, 4); + chip->codec_io = pci_resource_start(pci, 0); + chip->game_io = pci_resource_start(pci, 1); + chip->mpu_io = pci_resource_start(pci, 2); + chip->opl3_io = pci_resource_start(pci, 3); + chip->mixer_io = pci_resource_start(pci, 4); + + chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00; + chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20; if (request_irq(pci->irq, snd_azf3328_interrupt, IRQF_SHARED, card->shortname, chip)) { @@ -1747,29 +2141,29 @@ snd_azf3328_create(struct snd_card *card, synchronize_irq(chip->irq); snd_azf3328_debug_show_ports(chip); - - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { + + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) goto out_err; - } /* create mixer interface & switches */ - if ((err = snd_azf3328_mixer_new(chip)) < 0) + err = snd_azf3328_mixer_new(chip); + if (err < 0) goto out_err; -#if 0 - /* set very low bitrate to reduce noise and power consumption? */ - snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 5512, 8, 1); -#endif + /* shutdown codecs to save power */ + /* have snd_azf3328_codec_activity() act properly */ + chip->audio_stream[AZF_PLAYBACK].running = 1; + snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0); /* standard chip init stuff */ - /* default IRQ init value */ + /* default IRQ init value */ tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE; spin_lock_irq(&chip->reg_lock); snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp); snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp); snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp); - snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */ spin_unlock_irq(&chip->reg_lock); snd_card_set_dev(card, &pci->dev); @@ -1805,52 +2199,61 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) return -ENOENT; } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0 ); + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; strcpy(card->driver, "AZF3328"); strcpy(card->shortname, "Aztech AZF3328 (PCI168)"); - if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) { + err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip); + if (err < 0) goto out_err; - } card->private_data = chip; - if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401, - chip->mpu_port, MPU401_INFO_INTEGRATED, - pci->irq, 0, &chip->rmidi)) < 0) { - snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port); + err = snd_mpu401_uart_new( + card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED, + pci->irq, 0, &chip->rmidi + ); + if (err < 0) { + snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", + chip->mpu_io + ); goto out_err; } - if ((err = snd_azf3328_timer(chip, 0)) < 0) { + err = snd_azf3328_timer(chip, 0); + if (err < 0) goto out_err; - } - if ((err = snd_azf3328_pcm(chip, 0)) < 0) { + err = snd_azf3328_pcm(chip, 0); + if (err < 0) goto out_err; - } - if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2, + if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2, OPL3_HW_AUTO, 1, &opl3) < 0) { snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n", - chip->synth_port, chip->synth_port+2 ); + chip->opl3_io, chip->opl3_io+2 + ); } else { - if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { + /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */ + err = snd_opl3_timer_new(opl3, 1, 2); + if (err < 0) + goto out_err; + err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (err < 0) goto out_err; - } } opl3->private_data = chip; sprintf(card->longname, "%s at 0x%lx, irq %i", - card->shortname, chip->codec_port, chip->irq); + card->shortname, chip->codec_io, chip->irq); - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err < 0) goto out_err; - } #ifdef MODULE printk( @@ -1861,19 +2264,18 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 1024000 / seqtimer_scaling, seqtimer_scaling); #endif - if (snd_azf3328_config_joystick(chip, dev) < 0) - snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR, - snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY); + snd_azf3328_gameport(chip, dev); pci_set_drvdata(pci, card); dev++; err = 0; goto out; - + out_err: + snd_printk(KERN_ERR "azf3328: something failed, exiting\n"); snd_card_free(card); - + out: snd_azf3328_dbgcallleave(); return err; @@ -1894,27 +2296,27 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct snd_azf3328 *chip = card->private_data; - int reg; + unsigned reg; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - + snd_pcm_suspend_all(chip->pcm); - for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++) - chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg) + chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2); /* make sure to disable master volume etc. to prevent looping sound */ snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); - - for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++) - chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) - chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++) - chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) - chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2); + + for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg) + chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg) + chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg) + chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg) + chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2); pci_disable_device(pci); pci_save_state(pci); @@ -1927,7 +2329,7 @@ snd_azf3328_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct snd_azf3328 *chip = card->private_data; - int reg; + unsigned reg; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); @@ -1939,23 +2341,21 @@ snd_azf3328_resume(struct pci_dev *pci) } pci_set_master(pci); - for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++) - outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++) - outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++) - outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++) - outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2); - for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++) - outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg) + outw(chip->saved_regs_game[reg], chip->game_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg) + outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg) + outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg) + outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2); + for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg) + outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } -#endif - - +#endif /* CONFIG_PM */ static struct pci_driver driver = { diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h index 679fa99..3448fd6 100644 --- a/sound/pci/azt3328.h +++ b/sound/pci/azt3328.h @@ -54,7 +54,10 @@ #define SOUNDFORMAT_XTAL1 0x00 #define SOUNDFORMAT_XTAL2 0x01 /* all _SUSPECTED_ values are not used by Windows drivers, so we don't - * have any hard facts, only rough measurements */ + * have any hard facts, only rough measurements. + * All we know is that the crystal used on the board has 24.576MHz, + * like many soundcards (which results in the frequencies below when + * using certain divider values selected by the values below) */ #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1 #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1 #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2 @@ -72,6 +75,26 @@ #define SOUNDFORMAT_FLAG_16BIT 0x0010 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020 +/* define frequency helpers, for maximum value safety */ +enum { +#define AZF_FREQ(rate) AZF_FREQ_##rate = rate + AZF_FREQ(4000), + AZF_FREQ(4800), + AZF_FREQ(5512), + AZF_FREQ(6620), + AZF_FREQ(8000), + AZF_FREQ(9600), + AZF_FREQ(11025), + AZF_FREQ(13240), + AZF_FREQ(16000), + AZF_FREQ(22050), + AZF_FREQ(32000), + AZF_FREQ(44100), + AZF_FREQ(48000), + AZF_FREQ(66200), +#undef AZF_FREQ +} AZF_FREQUENCIES; + /** recording area (see also: playback bit flag definitions) **/ #define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */ #define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */ @@ -97,40 +120,164 @@ /** DirectX timer, main interrupt area (FIXME: and something else?) **/ #define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */ - #define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */ - #define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */ - #define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */ - #define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */ + /* timer countdown value; triggers IRQ when timer is finished */ + #define TIMER_VALUE_MASK 0x000fffffUL + /* activate timer countdown */ + #define TIMER_COUNTDOWN_ENABLE 0x01000000UL + /* trigger timer IRQ on zero transition */ + #define TIMER_IRQ_ENABLE 0x02000000UL + /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) + * had 0x0020 set upon IRQ handler */ + #define TIMER_IRQ_ACK 0x04000000UL #define IDX_IO_IRQSTATUS 0x64 - #define IRQ_PLAYBACK 0x0001 - #define IRQ_RECORDING 0x0002 - #define IRQ_MPU401 0x0010 - #define IRQ_TIMER 0x0020 /* DirectX timer */ - #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ - #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ + /* some IRQ bit in here might also be used to signal a power-management timer + * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing). + * Some OPL3 hardware (e.g. in LM4560) has some special timer hardware which + * can trigger an OPL3 timer IRQ, so maybe there's such a thing as well... */ + + #define IRQ_PLAYBACK 0x0001 + #define IRQ_RECORDING 0x0002 + #define IRQ_UNKNOWN1 0x0004 /* most probably I2S port */ + #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */ + #define IRQ_MPU401 0x0010 + #define IRQ_TIMER 0x0020 /* DirectX timer */ + #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly I2S port? */ + #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly I2S port? */ #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ -#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ -#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ - #define IO_6A_PAUSE_PLAYBACK 0x0200 /* bit 9; sure, this pauses playback, but what the heck is this really about?? */ -#define IDX_IO_6CH 0x6C -#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */ -/* further I/O indices not saved/restored, so probably not used */ + /* this is set to e.g. 0x3ff or 0x300, and writable; + * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */ +#define IDX_IO_SOME_VALUE 0x68 + #define IO_68_RANDOM_TOGGLE1 0x0100 /* toggles randomly */ + #define IO_68_RANDOM_TOGGLE2 0x0200 /* toggles randomly */ + /* umm, nope, behaviour of these bits changes depending on what we wrote + * to 0x6b!! */ + +/* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); + * actually inhibits PCM playback!!! maybe power management??: */ +#define IDX_IO_6AH 0x6A + /* bit 5: enabling this will activate permanent counting of bytes 2/3 + * at gameport I/O (0xb402/3) (equal values each) and cause + * gameport legacy I/O at 0x0200 to be _DISABLED_! + * Is this Digital Enhanced Game Port Enable??? Or maybe it's Testmode + * for Enhanced Digital Gameport (see 4D Wave DX card): */ + #define IO_6A_SOMETHING1_GAMEPORT 0x0020 + /* bit 8; sure, this _pauses_ playback (later resumes at same spot!), + * but what the heck is this really about??: */ + #define IO_6A_PAUSE_PLAYBACK_BIT8 0x0100 + /* bit 9; sure, this _pauses_ playback (later resumes at same spot!), + * but what the heck is this really about??: */ + #define IO_6A_PAUSE_PLAYBACK_BIT9 0x0200 + /* BIT8 and BIT9 are _NOT_ able to affect OPL3 MIDI playback, + * thus it suggests influence on PCM only!! + * However OTOH there seems to be no bit anywhere around here + * which is able to disable OPL3... */ + /* bit 10: enabling this actually changes values at legacy gameport + * I/O address (0x200); is this enabling of the Digital Enhanced Game Port??? + * Or maybe this simply switches off the NE558 circuit, since enabling this + * still lets us evaluate button states, but not axis states */ + #define IO_6A_SOMETHING2_GAMEPORT 0x0400 + /* writing 0x0300: causes quite some crackling during + * PC activity such as switching windows (PCI traffic?? + * --> FIFO/timing settings???) */ + /* writing 0x0100 plus/or 0x0200 inhibits playback */ + /* since the Windows .INF file has Flag_Enable_JoyStick and + * Flag_Enable_SB_DOS_Emulation directly together, it stands to reason + * that some other bit in this same register might be responsible + * for SB DOS Emulation activation (note that the file did NOT define + * a switch for OPL3!) */ +#define IDX_IO_6CH 0x6C /* unknown; fully read-writable */ +#define IDX_IO_6EH 0x6E + /* writing 0xffff returns 0x83fe (or 0x03fe only). + * writing 0x83 (and only 0x83!!) to 0x6f will cause 0x6c to switch + * from 0000 to ffff. */ +/* further I/O indices not saved/restored and not readable after writing, + * so probably not used */ -/*** I/O 2 area port indices ***/ + +/*** Gameport area port indices ***/ /* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ -#define AZF_IO_SIZE_IO2 0x08 -#define AZF_IO_SIZE_IO2_PM 0x06 +#define AZF_IO_SIZE_GAME 0x08 +#define AZF_IO_SIZE_GAME_PM 0x06 + +enum { + AZF_GAME_LEGACY_IO_PORT = 0x200 +} AZF_GAME_CONFIGS; + +#define IDX_GAME_LEGACY_COMPATIBLE 0x00 + /* in some operation mode, writing anything to this port + * triggers an interrupt: + * yup, that's in case IDX_GAME_01H has one of the + * axis measurement bits enabled + * (and of course one needs to have GAME_HWCFG_IRQ_ENABLE, too) */ + +#define IDX_GAME_AXES_CONFIG 0x01 + /* NOTE: layout of this register awfully similar (read: "identical??") + * to AD1815JS.pdf (p.29) */ + + /* enables axis 1 (X axis) measurement: */ + #define GAME_AXES_ENABLE_1 0x01 + /* enables axis 2 (Y axis) measurement: */ + #define GAME_AXES_ENABLE_2 0x02 + /* enables axis 3 (X axis) measurement: */ + #define GAME_AXES_ENABLE_3 0x04 + /* enables axis 4 (Y axis) measurement: */ + #define GAME_AXES_ENABLE_4 0x08 + /* selects the current axis to read the measured value of + * (at IDX_GAME_AXIS_VALUE): + * 00 = axis 1, 01 = axis 2, 10 = axis 3, 11 = axis 4: */ + #define GAME_AXES_READ_MASK 0x30 + /* enable to have the latch continuously accept ADC values + * (and continuously cause interrupts in case interrupts are enabled); + * AD1815JS.pdf says it's ~16ms interval there: */ + #define GAME_AXES_LATCH_ENABLE 0x40 + /* joystick data (measured axes) ready for reading: */ + #define GAME_AXES_SAMPLING_READY 0x80 + + /* NOTE: other card specs (SiS960 and others!) state that the + * game position latches should be frozen when reading and be freed + * (== reset?) after reading!!! + * Freezing most likely means disabling 0x40 (GAME_AXES_LATCH_ENABLE), + * but how to free the value? */ + /* An internet search for "gameport latch ADC" should provide some insight + * into how to program such a gameport system. */ + + /* writing 0xf0 to 01H once reset both counters to 0, in some special mode!? + * yup, in case 6AH 0x20 is not enabled + * (and 0x40 is sufficient, 0xf0 is not needed) */ + +#define IDX_GAME_AXIS_VALUE 0x02 + /* R: value of currently configured axis (word value!); + * W: trigger axis measurement */ + +#define IDX_GAME_HWCONFIG 0x04 + /* note: bits 4 to 7 are never set (== 0) when reading! + * --> reserved bits? */ + /* enables IRQ notification upon axes measurement ready: */ + #define GAME_HWCFG_IRQ_ENABLE 0x01 + /* these bits choose a different frequency for the + * internal ADC counter increment. + * hmm, seems to be a combo of bits: + * 00 --> standard frequency + * 10 --> 1/2 + * 01 --> 1/20 + * 11 --> 1/200: */ + #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06 -#define IDX_IO2_LEGACY_ADDR 0x04 - #define LEGACY_SOMETHING 0x01 /* OPL3?? */ - #define LEGACY_JOY 0x08 + /* enable gameport legacy I/O address (0x200) + * I was unable to locate any configurability for a different address: */ + #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08 +/*** MPU401 ***/ #define AZF_IO_SIZE_MPU 0x04 #define AZF_IO_SIZE_MPU_PM 0x04 -#define AZF_IO_SIZE_SYNTH 0x08 -#define AZF_IO_SIZE_SYNTH_PM 0x06 +/*** OPL3 synth ***/ +#define AZF_IO_SIZE_OPL3 0x08 +#define AZF_IO_SIZE_OPL3_PM 0x06 +/* hmm, given that a standard OPL3 has 4 registers only, + * there might be some enhanced functionality lurking at the end + * (especially since register 0x04 has a "non-empty" value 0xfe) */ /*** mixer I/O area port indices ***/ /* (only 0x22 of 0x40 bytes saved/restored by Windows driver) -- cgit v0.10.2 From 9ad593f6d326e7a4664e3856520f6c042f82a37f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 16 May 2008 12:34:47 +0200 Subject: [ALSA] hda - Fix DMA position inaccuracy Many HD-audio controllers seem inaccurate about the IRQ timing of PCM period updates. This has caused problems on audio quality; e.g. JACK doesn't work with two periods. This patch fixes the problem by checking the current DMA position at IRQ handler and delays the period-update via a workq if it's inaccurate. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b3a618e..6ba7ac0 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -285,6 +285,7 @@ struct azx_dev { u32 *posbuf; /* position buffer pointer */ unsigned int bufsize; /* size of the play buffer in bytes */ + unsigned int period_bytes; /* size of the period in bytes */ unsigned int frags; /* number for period in the play buffer */ unsigned int fifo_size; /* FIFO size */ @@ -301,11 +302,10 @@ struct azx_dev { */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ - /* for sanity check of position buffer */ - unsigned int period_intr; unsigned int opened :1; unsigned int running :1; + unsigned int irq_pending: 1; }; /* CORB/RIRB */ @@ -369,6 +369,9 @@ struct azx { /* for debugging */ unsigned int last_cmd; /* last issued command (to sync) */ + + /* for pending irqs */ + struct work_struct irq_pending_work; }; /* driver types */ @@ -908,6 +911,8 @@ static void azx_init_pci(struct azx *chip) } +static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); + /* * interrupt handler */ @@ -930,11 +935,18 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) azx_dev = &chip->azx_dev[i]; if (status & azx_dev->sd_int_sta_mask) { azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); - if (azx_dev->substream && azx_dev->running) { - azx_dev->period_intr++; + if (!azx_dev->substream || !azx_dev->running) + continue; + /* check whether this IRQ is really acceptable */ + if (azx_position_ok(chip, azx_dev)) { + azx_dev->irq_pending = 0; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(azx_dev->substream); spin_lock(&chip->reg_lock); + } else { + /* bogus IRQ, process it later */ + azx_dev->irq_pending = 1; + schedule_work(&chip->irq_pending_work); } } } @@ -973,6 +985,7 @@ static int azx_setup_periods(struct snd_pcm_substream *substream, azx_sd_writel(azx_dev, SD_BDLPU, 0); period_bytes = snd_pcm_lib_period_bytes(substream); + azx_dev->period_bytes = period_bytes; periods = azx_dev->bufsize / period_bytes; /* program the initial BDL entries */ @@ -1421,27 +1434,16 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return 0; } -static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) +static unsigned int azx_get_position(struct azx *chip, + struct azx_dev *azx_dev) { - struct azx_pcm *apcm = snd_pcm_substream_chip(substream); - struct azx *chip = apcm->chip; - struct azx_dev *azx_dev = get_azx_dev(substream); unsigned int pos; if (chip->position_fix == POS_FIX_POSBUF || chip->position_fix == POS_FIX_AUTO) { /* use the position buffer */ pos = le32_to_cpu(*azx_dev->posbuf); - if (chip->position_fix == POS_FIX_AUTO && - azx_dev->period_intr == 1 && !pos) { - printk(KERN_WARNING - "hda-intel: Invalid position buffer, " - "using LPIB read method instead.\n"); - chip->position_fix = POS_FIX_NONE; - goto read_lpib; - } } else { - read_lpib: /* read LPIB */ pos = azx_sd_readl(azx_dev, SD_LPIB); if (chip->position_fix == POS_FIX_FIFO) @@ -1449,7 +1451,90 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) } if (pos >= azx_dev->bufsize) pos = 0; - return bytes_to_frames(substream->runtime, pos); + return pos; +} + +static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct azx_pcm *apcm = snd_pcm_substream_chip(substream); + struct azx *chip = apcm->chip; + struct azx_dev *azx_dev = get_azx_dev(substream); + return bytes_to_frames(substream->runtime, + azx_get_position(chip, azx_dev)); +} + +/* + * Check whether the current DMA position is acceptable for updating + * periods. Returns non-zero if it's OK. + * + * Many HD-audio controllers appear pretty inaccurate about + * the update-IRQ timing. The IRQ is issued before actually the + * data is processed. So, we need to process it afterwords in a + * workqueue. + */ +static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) +{ + unsigned int pos; + + pos = azx_get_position(chip, azx_dev); + if (chip->position_fix == POS_FIX_AUTO) { + if (!pos) { + printk(KERN_WARNING + "hda-intel: Invalid position buffer, " + "using LPIB read method instead.\n"); + chip->position_fix = POS_FIX_NONE; + pos = azx_get_position(chip, azx_dev); + } else + chip->position_fix = POS_FIX_POSBUF; + } + + if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) + return 0; /* NG - it's below the period boundary */ + return 1; /* OK, it's fine */ +} + +/* + * The work for pending PCM period updates. + */ +static void azx_irq_pending_work(struct work_struct *work) +{ + struct azx *chip = container_of(work, struct azx, irq_pending_work); + int i, pending; + + for (;;) { + pending = 0; + spin_lock_irq(&chip->reg_lock); + for (i = 0; i < chip->num_streams; i++) { + struct azx_dev *azx_dev = &chip->azx_dev[i]; + if (!azx_dev->irq_pending || + !azx_dev->substream || + !azx_dev->running) + continue; + if (azx_position_ok(chip, azx_dev)) { + azx_dev->irq_pending = 0; + spin_unlock(&chip->reg_lock); + snd_pcm_period_elapsed(azx_dev->substream); + spin_lock(&chip->reg_lock); + } else + pending++; + } + spin_unlock_irq(&chip->reg_lock); + if (!pending) + return; + cond_resched(); + } +} + +/* clear irq_pending flags and assure no on-going workq */ +static void azx_clear_irq_pending(struct azx *chip) +{ + int i; + + spin_lock_irq(&chip->reg_lock); + for (i = 0; i < chip->num_streams; i++) + chip->azx_dev[i].irq_pending = 0; + spin_unlock_irq(&chip->reg_lock); + flush_scheduled_work(); } static struct snd_pcm_ops azx_pcm_ops = { @@ -1676,6 +1761,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + azx_clear_irq_pending(chip); for (i = 0; i < AZX_MAX_PCMS; i++) snd_pcm_suspend_all(chip->pcm[i]); if (chip->initialized) @@ -1732,6 +1818,7 @@ static int azx_free(struct azx *chip) int i; if (chip->initialized) { + azx_clear_irq_pending(chip); for (i = 0; i < chip->num_streams; i++) azx_stream_stop(chip, &chip->azx_dev[i]); azx_stop_chip(chip); @@ -1857,6 +1944,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->irq = -1; chip->driver_type = driver_type; chip->msi = enable_msi; + INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); chip->position_fix = check_position_fix(chip, position_fix[dev]); check_probe_mask(chip, dev); -- cgit v0.10.2 From b2efbbfba24efc8456d68d5af42d082ab1c2febc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:30:58 +0200 Subject: [ALSA] ASoC: Remove in-code changelogs The overwhelming majority just say 'initial version' anyway. Signed-off-by: Mark Brown Acked-by: Ben Dooks Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 2a1ffe3..7bf2081 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -10,9 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 17th Oct 2005 Initial version. - * * Generic AC97 support. */ diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 76c1e2d..89efe40 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -9,9 +9,6 @@ * 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. - * - * Revision history - * 4th Feb 2006 Initial version. */ #include diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 1f24116..9e6b2fd 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -10,9 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 4th Feb 2006 Initial version. - * * Features:- * * o Support for AC97 Codec, Voice DAC and Aux DAC diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 852f16d..edeea63 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -11,10 +11,6 @@ * 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. - * - * Revision history - * 30th Nov 2005 Initial version. - * */ #include diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 4250710..35090c2 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -9,9 +9,6 @@ * 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. - * - * Revision history - * 12th Aug 2005 Initial version. */ #include diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 73a6df8..092b5c7 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -12,9 +12,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 30th Nov 2005 Initial version. - * */ #include diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index fda2aa0..465ff0f 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -12,9 +12,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 30th Nov 2005 Initial version. - * * GPIO's * 1 - Jack Insertion * 5 - Hookswitch (headset answer/hang up switch) diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 79c5027..c1a0161 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -10,10 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 20th Jan 2007 Initial version. - * 05th Feb 2007 Rename all to Neo1973 - * */ #include diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c index e81d9a6..0eed140 100644 --- a/sound/soc/s3c24xx/s3c2443-ac97.c +++ b/sound/soc/s3c24xx/s3c2443-ac97.c @@ -10,9 +10,6 @@ * 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. - * - * Revision history - * 21st Mar 2007 Initial Version */ #include diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 1ed6afd..ddf8724 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -12,11 +12,6 @@ * 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. - * - * - * Revision history - * 11th Dec 2006 Merged with Simtec driver - * 10th Nov 2006 Initial version. */ #include diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c index 7806ae6..ef59974 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -12,10 +12,6 @@ * 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. - * - * Revision history - * 11th Dec 2006 Merged with Simtec driver - * 10th Nov 2006 Initial version. */ #include diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index b4a5630..8515d6f 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -10,9 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 8th Mar 2007 Initial version. - * */ #include diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index e148db9..0318d8a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -14,10 +14,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 12th Aug 2005 Initial version. - * 25th Oct 2005 Working Codec, Interface and Platform registration. - * * TODO: * o Add hw rules to enforce rates, etc. * o More testing with other codecs/machines. diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1ef6d94..8a3192b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -10,11 +10,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * Revision history - * 12th Aug 2005 Initial version. - * 25th Oct 2005 Implemented path power domain. - * 18th Dec 2005 Implemented machine and stream level power domain. - * * Features: * o Changes power status of internal codec blocks depending on the * dynamic configuration of codec internal audio paths and active -- cgit v0.10.2 From 1ef6ab75c7deef931d6308af282ed7d8e480e77f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:31:55 +0200 Subject: [ALSA] ASoC: Make CPU and codec DAI operations have same type The CPU and codec DAI operations differ only in the presence of the digital mute operation for the codec so they may as well be the same type. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc.h b/include/sound/soc.h index d3c8c03..73accbc 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -272,9 +272,9 @@ struct snd_soc_ops { int (*trigger)(struct snd_pcm_substream *, int); }; -/* ASoC codec DAI ops */ -struct snd_soc_codec_ops { - /* codec DAI clocking configuration */ +/* ASoC DAI ops */ +struct snd_soc_dai_ops { + /* DAI clocking configuration */ int (*set_sysclk)(struct snd_soc_codec_dai *codec_dai, int clk_id, unsigned int freq, int dir); int (*set_pll)(struct snd_soc_codec_dai *codec_dai, @@ -282,7 +282,7 @@ struct snd_soc_codec_ops { int (*set_clkdiv)(struct snd_soc_codec_dai *codec_dai, int div_id, int div); - /* CPU DAI format configuration */ + /* DAI format configuration */ int (*set_fmt)(struct snd_soc_codec_dai *codec_dai, unsigned int fmt); int (*set_tdm_slot)(struct snd_soc_codec_dai *codec_dai, @@ -293,24 +293,6 @@ struct snd_soc_codec_ops { int (*digital_mute)(struct snd_soc_codec_dai *, int mute); }; -/* ASoC cpu DAI ops */ -struct snd_soc_cpu_ops { - /* CPU DAI clocking configuration */ - int (*set_sysclk)(struct snd_soc_cpu_dai *cpu_dai, - int clk_id, unsigned int freq, int dir); - int (*set_clkdiv)(struct snd_soc_cpu_dai *cpu_dai, - int div_id, int div); - int (*set_pll)(struct snd_soc_cpu_dai *cpu_dai, - int pll_id, unsigned int freq_in, unsigned int freq_out); - - /* CPU DAI format configuration */ - int (*set_fmt)(struct snd_soc_cpu_dai *cpu_dai, - unsigned int fmt); - int (*set_tdm_slot)(struct snd_soc_cpu_dai *cpu_dai, - unsigned int mask, int slots); - int (*set_tristate)(struct snd_soc_cpu_dai *, int tristate); -}; - /* SoC Codec DAI */ struct snd_soc_codec_dai { char *name; @@ -328,7 +310,7 @@ struct snd_soc_codec_dai { /* ops */ struct snd_soc_ops ops; - struct snd_soc_codec_ops dai_ops; + struct snd_soc_dai_ops dai_ops; /* DAI private data */ void *private_data; @@ -352,7 +334,7 @@ struct snd_soc_cpu_dai { /* ops */ struct snd_soc_ops ops; - struct snd_soc_cpu_ops dai_ops; + struct snd_soc_dai_ops dai_ops; /* DAI capabilities */ struct snd_soc_pcm_stream capture; -- cgit v0.10.2 From 1a189b97190d3f0f8cf0379a799d3555b2d648bb Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 13 Apr 2008 21:41:55 +0100 Subject: [ARM] pxa: Add bare bones PWM API Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68..c274dbb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -22,6 +22,9 @@ config ARM Europe. There is an ARM Linux project with a web page at . +config HAVE_PWM + bool + config SYS_SUPPORTS_APM_EMULATION bool diff --git a/include/linux/pwm.h b/include/linux/pwm.h new file mode 100644 index 0000000..3945f80 --- /dev/null +++ b/include/linux/pwm.h @@ -0,0 +1,31 @@ +#ifndef __LINUX_PWM_H +#define __LINUX_PWM_H + +struct pwm_device; + +/* + * pwm_request - request a PWM device + */ +struct pwm_device *pwm_request(int pwm_id, const char *label); + +/* + * pwm_free - free a PWM device + */ +void pwm_free(struct pwm_device *pwm); + +/* + * pwm_config - change a PWM device configuration + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); + +/* + * pwm_enable - start a PWM output toggling + */ +int pwm_enable(struct pwm_device *pwm); + +/* + * pwm_disable - stop a PWM output toggling + */ +void pwm_disable(struct pwm_device *pwm); + +#endif /* __ASM_ARCH_PWM_H */ -- cgit v0.10.2 From 75540c1ac3c7bd72ac8e092058f9714875239995 Mon Sep 17 00:00:00 2001 From: eric miao Date: Sun, 13 Apr 2008 21:44:04 +0100 Subject: [ARM] pxa: Add PXA support for PWM API Patch mainly from Eric Miao, with minor edits by rmk. Note: PWM0 and PWM2 share the same register I/O space and clock gating on pxa{27x, 3xx}, thus PWM2 is treated in the driver as a child PWM of PWM0. And this is also true for PWM1/3. Signed-off-by: eric miao Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5da7a68..9c01505 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -273,4 +273,9 @@ config PXA_SSP tristate help Enable support for PXA2xx SSP ports + +config PXA_PWM + tristate + help + Enable support for PXA2xx/PXA3xx PWM controllers endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0e6d05b..02cbc3c 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o # Generic drivers that other drivers may depend upon obj-$(CONFIG_PXA_SSP) += ssp.o +obj-$(CONFIG_PXA_PWM) += pwm.o # SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index d6c05b6..794a107 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -280,6 +280,36 @@ struct platform_device pxa_device_rtc = { #ifdef CONFIG_PXA25x +static struct resource pxa25x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm0 = { + .name = "pxa25x-pwm", + .id = 0, + .resource = pxa25x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm0), +}; + +static struct resource pxa25x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm1 = { + .name = "pxa25x-pwm", + .id = 1, + .resource = pxa25x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm1), +}; + static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32); static struct resource pxa25x_resource_ssp[] = { @@ -568,6 +598,36 @@ struct platform_device pxa27x_device_ssp3 = { .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), }; +static struct resource pxa27x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm0 = { + .name = "pxa27x-pwm", + .id = 0, + .resource = pxa27x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm0), +}; + +static struct resource pxa27x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm1 = { + .name = "pxa27x-pwm", + .id = 1, + .resource = pxa27x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), +}; + static struct resource pxa27x_resource_camera[] = { [0] = { .start = 0x50000000, diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index fcab017..e620a33 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -24,4 +24,9 @@ extern struct platform_device pxa27x_device_ssp2; extern struct platform_device pxa27x_device_ssp3; extern struct platform_device pxa3xx_device_ssp4; +extern struct platform_device pxa25x_device_pwm0; +extern struct platform_device pxa25x_device_pwm1; +extern struct platform_device pxa27x_device_pwm0; +extern struct platform_device pxa27x_device_pwm1; + void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c new file mode 100644 index 0000000..70fb3ca --- /dev/null +++ b/arch/arm/mach-pxa/pwm.c @@ -0,0 +1,299 @@ +/* + * linux/arch/arm/mach-pxa/pwm.c + * + * simple driver for PWM (Pulse Width Modulator) 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. + * + * 2008-02-13 initial version + * eric miao + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +struct pwm_device { + struct list_head node; + struct platform_device *pdev; + + const char *label; + struct clk *clk; + void __iomem *mmio_base; + + unsigned int use_count; + unsigned int pwm_id; +}; + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + + c = clk_get_rate(pwm->clk); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 0) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + clk_enable(pwm->clk); + __raw_writel(prescale, pwm->mmio_base + PWMCR); + __raw_writel(dc, pwm->mmio_base + PWMDCR); + __raw_writel(pv, pwm->mmio_base + PWMPCR); + clk_disable(pwm->clk); + + return 0; +} +EXPORT_SYMBOL(pwm_config); + +int pwm_enable(struct pwm_device *pwm) +{ + return clk_enable(pwm->clk); +} +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + clk_disable(pwm->clk); +} +EXPORT_SYMBOL(pwm_disable); + +static DEFINE_MUTEX(pwm_lock); +static LIST_HEAD(pwm_list); + +struct pwm_device *pwm_request(int pwm_id, const char *label) +{ + struct pwm_device *pwm; + int found = 0; + + mutex_lock(&pwm_lock); + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->pwm_id == pwm_id && pwm->use_count == 0) { + pwm->use_count++; + pwm->label = label; + found = 1; + break; + } + } + + mutex_unlock(&pwm_lock); + + return (found) ? pwm : NULL; +} +EXPORT_SYMBOL(pwm_request); + +void pwm_free(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + + if (pwm->use_count) { + pwm->use_count--; + pwm->label = NULL; + } else + pr_warning("PWM device already freed\n"); + + mutex_unlock(&pwm_lock); +} +EXPORT_SYMBOL(pwm_free); + +static inline void __add_pwm(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + list_add_tail(&pwm->node, &pwm_list); + mutex_unlock(&pwm_lock); +} + +static struct pwm_device *pwm_probe(struct platform_device *pdev, + unsigned int pwm_id, struct pwm_device *parent_pwm) +{ + struct pwm_device *pwm; + struct resource *r; + int ret = 0; + + pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (pwm == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return ERR_PTR(-ENOMEM); + } + + pwm->clk = clk_get(&pdev->dev, "PWMCLK"); + if (IS_ERR(pwm->clk)) { + ret = PTR_ERR(pwm->clk); + goto err_free; + } + + pwm->use_count = 0; + pwm->pwm_id = pwm_id; + pwm->pdev = pdev; + + if (parent_pwm != NULL) { + /* registers for the second PWM has offset of 0x10 */ + pwm->mmio_base = parent_pwm->mmio_base + 0x10; + __add_pwm(pwm); + return pwm; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + if (r == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + if (pwm->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + __add_pwm(pwm); + platform_set_drvdata(pdev, pwm); + return pwm; + +err_free_mem: + release_mem_region(r->start, r->end - r->start + 1); +err_free_clk: + clk_put(pwm->clk); +err_free: + kfree(pwm); + return ERR_PTR(ret); +} + +static int __devinit pxa25x_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL); + + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + return 0; +} + +static int __devinit pxa27x_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm; + + pwm = pwm_probe(pdev, pdev->id * 2, NULL); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + pwm = pwm_probe(pdev, pdev->id * 2 + 1, pwm); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + return 0; +} + +static int __devexit pwm_remove(struct platform_device *pdev) +{ + struct pwm_device *pwm; + struct resource *r; + + pwm = platform_get_drvdata(pdev); + if (pwm == NULL) + return -ENODEV; + + mutex_lock(&pwm_lock); + list_del(&pwm->node); + mutex_unlock(&pwm_lock); + + iounmap(pwm->mmio_base); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, r->end - r->start + 1); + + clk_put(pwm->clk); + kfree(pwm); + return 0; +} + +static struct platform_driver pxa25x_pwm_driver = { + .driver = { + .name = "pxa25x-pwm", + }, + .probe = pxa25x_pwm_probe, + .remove = __devexit_p(pwm_remove), +}; + +static struct platform_driver pxa27x_pwm_driver = { + .driver = { + .name = "pxa27x-pwm", + }, + .probe = pxa27x_pwm_probe, + .remove = __devexit_p(pwm_remove), +}; + +static int __init pwm_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&pxa25x_pwm_driver); + if (ret) { + printk(KERN_ERR "failed to register pxa25x_pwm_driver\n"); + return ret; + } + + ret = platform_driver_register(&pxa27x_pwm_driver); + if (ret) { + printk(KERN_ERR "failed to register pxa27x_pwm_driver\n"); + return ret; + } + + return ret; +} +arch_initcall(pwm_init); + +static void __exit pwm_exit(void) +{ + platform_driver_unregister(&pxa25x_pwm_driver); + platform_driver_unregister(&pxa27x_pwm_driver); +} +module_exit(pwm_exit); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e5b417d..2bed3f9 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -129,12 +129,12 @@ static struct clk pxa25x_clks[] = { INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), + INIT_CKEN("PWMCLK", PWM0, 3686400, 0, &pxa25x_device_pwm0.dev), + INIT_CKEN("PWMCLK", PWM1, 3686400, 0, &pxa25x_device_pwm1.dev), INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), /* - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), */ INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), @@ -269,6 +269,8 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_ssp, &pxa25x_device_nssp, &pxa25x_device_assp, + &pxa25x_device_pwm0, + &pxa25x_device_pwm1, }; static struct sys_device pxa25x_sysdev[] = { diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e94583..bc2e80f 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -157,12 +157,13 @@ static struct clk pxa27x_clks[] = { INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), + INIT_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), + INIT_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), INIT_CKEN("AC97CONFCLK", AC97CONF, 24576000, 0, NULL), /* - INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), @@ -363,6 +364,8 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp1, &pxa27x_device_ssp2, &pxa27x_device_ssp3, + &pxa27x_device_pwm0, + &pxa27x_device_pwm1, }; static struct sys_device pxa27x_sysdev[] = { diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 644550b..0f717df 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -239,6 +239,8 @@ static struct clk pxa3xx_clks[] = { PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev), + PXA3xx_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), + PXA3xx_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), @@ -530,6 +532,8 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp2, &pxa27x_device_ssp3, &pxa3xx_device_ssp4, + &pxa27x_device_pwm0, + &pxa27x_device_pwm1, }; static struct sys_device pxa3xx_sysdev[] = { -- cgit v0.10.2 From 02a8e76979f9b439642e67955edb865c112926f6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:15:32 +0100 Subject: [ARM] pxa: corgibl_limit_intensity build errors If CONFIG_BACKLIGHT_CORGI is not selected, then corgibl_limit_intensity() is not present. However, both corgi_pm.c and sharp_pm.c reference this symbol, resulting in a link error. Wrap the references with the relevant ifdefs, and avoid the resulting NULL pointer dereference by making the code in sharpsl_pm.c also conditional on the config symbol. Signed-off-by: Russell King diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 5bba525..5736c98 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -157,6 +157,7 @@ static void sharpsl_battery_thread(struct work_struct *private_) dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage, sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); +#ifdef CONFIG_BACKLIGHT_CORGI /* If battery is low. limit backlight intensity to save power. */ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) || @@ -169,6 +170,7 @@ static void sharpsl_battery_thread(struct work_struct *private_) sharpsl_pm.machinfo->backlight_limit(0); sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT; } +#endif /* Suspend if critical battery level */ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 0a85f70..ae91c4b 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -204,7 +204,9 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .read_devdata = corgipm_read_devdata, .charger_wakeup = corgi_charger_wakeup, .should_wakeup = corgi_should_wakeup, +#ifdef CONFIG_BACKLIGHT_CORGI .backlight_limit = corgibl_limit_intensity, +#endif .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 23f050f..48396f4 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -207,7 +207,9 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = { .read_devdata = spitzpm_read_devdata, .charger_wakeup = spitz_charger_wakeup, .should_wakeup = spitz_should_wakeup, +#ifdef CONFIG_BACKLIGHT_CORGI .backlight_limit = corgibl_limit_intensity, +#endif .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, -- cgit v0.10.2 From 284d115ec9b70d7c38752d10ad393a198db07a4b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:32:16 +0100 Subject: [ARM] pxa: separate PXA25x and PXA27x UDC register definitions The PXA25x and PXA27x USB device controller register definitions are different. Currently, they live side by side in pxa-regs.h, but only one set is available depending on the setting of PXA25x or PXA27x. This means that if we build to support both PXA25x and PXA27x, the PXA27x definitions are unavailable, even to PXA27x specific code. Remove these definitions from pxa-regs.h, and place them in separate files. Include these files where appropriate. Note: according to the dependencies in drivers/usb/gadget/Kconfig, we do not support the UDC on PXA27x nor PXA3xx CPUs, so remove the platform devices from pxa27x.c and pxa3xx.c. Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index edc4f07..1269ac9 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e94583..cdaf573 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -353,7 +353,7 @@ void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 644550b..7fbe786 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -520,7 +520,7 @@ void __init pxa3xx_init_irq(void) */ static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 08f699b..63db96a 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -46,19 +46,25 @@ #include #include #include +#include #include #include #include -#include #include #include #include -#include #include #include +/* + * This driver is PXA25x only. Grab the right register definitions. + */ +#ifdef CONFIG_ARCH_PXA +#include +#endif + #include diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 4b2ea1e..68d7428 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -600,418 +600,6 @@ /* - * USB Device Controller - * PXA25x and PXA27x USB device controller registers are different. - */ -#if defined(CONFIG_PXA25x) - -#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ -#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ -#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ - -#define UDCCR __REG(0x40600000) /* UDC Control Register */ -#define UDCCR_UDE (1 << 0) /* UDC enable */ -#define UDCCR_UDA (1 << 1) /* UDC active */ -#define UDCCR_RSM (1 << 2) /* Device resume */ -#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */ -#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */ -#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */ -#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */ -#define UDCCR_REM (1 << 7) /* Reset interrupt mask */ - -#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */ -#define UDCCS0_OPR (1 << 0) /* OUT packet ready */ -#define UDCCS0_IPR (1 << 1) /* IN packet ready */ -#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */ -#define UDCCS0_SST (1 << 4) /* Sent stall */ -#define UDCCS0_FST (1 << 5) /* Force stall */ -#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */ -#define UDCCS0_SA (1 << 7) /* Setup active */ - -/* Bulk IN - Endpoint 1,6,11 */ -#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */ -#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */ -#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */ - -#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */ -#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */ -#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */ -#define UDCCS_BI_SST (1 << 4) /* Sent stall */ -#define UDCCS_BI_FST (1 << 5) /* Force stall */ -#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */ - -/* Bulk OUT - Endpoint 2,7,12 */ -#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */ -#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */ -#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */ - -#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */ -#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */ -#define UDCCS_BO_DME (1 << 3) /* DMA enable */ -#define UDCCS_BO_SST (1 << 4) /* Sent stall */ -#define UDCCS_BO_FST (1 << 5) /* Force stall */ -#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */ -#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */ - -/* Isochronous IN - Endpoint 3,8,13 */ -#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */ -#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */ -#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */ - -#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */ -#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */ -#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */ -#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */ - -/* Isochronous OUT - Endpoint 4,9,14 */ -#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */ -#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */ -#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */ - -#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */ -#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */ -#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */ -#define UDCCS_IO_DME (1 << 3) /* DMA enable */ -#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */ -#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */ - -/* Interrupt IN - Endpoint 5,10,15 */ -#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */ -#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */ -#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */ - -#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */ -#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */ -#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */ -#define UDCCS_INT_SST (1 << 4) /* Sent stall */ -#define UDCCS_INT_FST (1 << 5) /* Force stall */ -#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */ - -#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */ -#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */ -#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */ -#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */ -#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */ -#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */ -#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */ -#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */ -#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */ -#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */ -#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */ -#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */ -#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */ -#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */ -#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */ -#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */ -#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */ -#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */ -#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */ -#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */ -#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */ -#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */ -#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */ -#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */ - -#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */ - -#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */ -#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */ -#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */ -#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */ -#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */ -#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */ -#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */ -#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */ - -#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */ - -#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */ -#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */ -#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */ -#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */ -#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */ -#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */ -#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */ -#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */ - -#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */ - -#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */ -#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */ -#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */ -#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */ -#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */ -#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */ -#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */ -#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */ - -#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */ - -#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */ -#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */ -#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */ -#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */ -#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */ -#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */ -#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */ -#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */ - -#elif defined(CONFIG_PXA27x) - -#define UDCCR __REG(0x40600000) /* UDC Control Register */ -#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ -#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation - Protocol Port Support */ -#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol - Support */ -#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol - Enable */ -#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ -#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ -#define UDCCR_ACN_S 11 -#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ -#define UDCCR_AIN_S 8 -#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface - Setting Number */ -#define UDCCR_AAISN_S 5 -#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active - Configuration */ -#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration - Error */ -#define UDCCR_UDR (1 << 2) /* UDC Resume */ -#define UDCCR_UDA (1 << 1) /* UDC Active */ -#define UDCCR_UDE (1 << 0) /* UDC Enable */ - -#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ -#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ -#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ -#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ - -#define UDC_INT_FIFOERROR (0x2) -#define UDC_INT_PACKETCMP (0x1) - -#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ -#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ -#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ -#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ -#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ - -#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ -#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ -#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ -#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ -#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ -#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ -#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ - -#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ -#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ -#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ -#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt - Rising Edge Interrupt Enable */ -#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt - Falling Edge Interrupt Enable */ -#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising - Edge Interrupt Enable */ -#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling - Edge Interrupt Enable */ -#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge - Interrupt Enable */ - -#define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */ - -#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ -#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ -#define UP2OCR_DPPDE (1 << 2) /* Host Port 2 Transceiver D+ Pull Down Enable */ -#define UP2OCR_DMPDE (1 << 3) /* Host Port 2 Transceiver D- Pull Down Enable */ -#define UP2OCR_DPPUE (1 << 4) /* Host Port 2 Transceiver D+ Pull Up Enable */ -#define UP2OCR_DMPUE (1 << 5) /* Host Port 2 Transceiver D- Pull Up Enable */ -#define UP2OCR_DPPUBE (1 << 6) /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */ -#define UP2OCR_DMPUBE (1 << 7) /* Host Port 2 Transceiver D- Pull Up Bypass Enable */ -#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ -#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ -#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ -#define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */ -#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ -#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ - -#define UDCCSN(x) __REG2(0x40600100, (x) << 2) -#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ -#define UDCCSR0_SA (1 << 7) /* Setup Active */ -#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ -#define UDCCSR0_FST (1 << 5) /* Force Stall */ -#define UDCCSR0_SST (1 << 4) /* Sent Stall */ -#define UDCCSR0_DME (1 << 3) /* DMA Enable */ -#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ -#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ -#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ - -#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ -#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ -#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ -#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ -#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ -#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ -#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ -#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ -#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ -#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ -#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ -#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ -#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ -#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ -#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ -#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ -#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ -#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ -#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ -#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ -#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ -#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ -#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ - -#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ -#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ -#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ -#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ -#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ -#define UDCCSR_FST (1 << 5) /* Force STALL */ -#define UDCCSR_SST (1 << 4) /* Sent STALL */ -#define UDCCSR_DME (1 << 3) /* DMA Enable */ -#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ -#define UDCCSR_PC (1 << 1) /* Packet Complete */ -#define UDCCSR_FS (1 << 0) /* FIFO needs service */ - -#define UDCBCN(x) __REG2(0x40600200, (x)<<2) -#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ -#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ -#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ -#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ -#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ -#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ -#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ -#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ -#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ -#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ -#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ -#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ -#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ -#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ -#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ -#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ -#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ -#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ -#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ -#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ -#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ -#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ -#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ -#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ - -#define UDCDN(x) __REG2(0x40600300, (x)<<2) -#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) -#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) -#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ -#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ -#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ -#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ -#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ -#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ -#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ -#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ -#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ -#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ -#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ -#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ -#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ -#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ -#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ -#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ -#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ -#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ -#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ -#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ -#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ -#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ -#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ -#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ - -#define UDCCN(x) __REG2(0x40600400, (x)<<2) -#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ -#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ -#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ -#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ -#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ -#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ -#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ -#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ -#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ -#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ -#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ -#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ -#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ -#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ -#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ -#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ -#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ -#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ -#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ -#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ -#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ -#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ -#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ - -#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ -#define UDCCONR_CN_S (25) -#define UDCCONR_IN (0x07 << 22) /* Interface Number */ -#define UDCCONR_IN_S (22) -#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ -#define UDCCONR_AISN_S (19) -#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ -#define UDCCONR_EN_S (15) -#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ -#define UDCCONR_ET_S (13) -#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ -#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ -#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ -#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ -#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ -#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ -#define UDCCONR_MPS_S (2) -#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ -#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ - - -#define UDC_INT_FIFOERROR (0x2) -#define UDC_INT_PACKETCMP (0x1) - -#define UDC_FNR_MASK (0x7ff) - -#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) -#define UDC_BCR_MASK (0x3ff) -#endif - -/* * Fast Infrared Communication Port */ diff --git a/include/asm-arm/arch-pxa/pxa25x-udc.h b/include/asm-arm/arch-pxa/pxa25x-udc.h new file mode 100644 index 0000000..8403059 --- /dev/null +++ b/include/asm-arm/arch-pxa/pxa25x-udc.h @@ -0,0 +1,163 @@ +#ifndef _ASM_ARCH_PXA25X_UDC_H +#define _ASM_ARCH_PXA25X_UDC_H + +#ifdef _ASM_ARCH_PXA27X_UDC_H +#error You can't include both PXA25x and PXA27x UDC support +#endif + +#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ +#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ +#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ + +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_UDE (1 << 0) /* UDC enable */ +#define UDCCR_UDA (1 << 1) /* UDC active */ +#define UDCCR_RSM (1 << 2) /* Device resume */ +#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */ +#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */ +#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */ +#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */ +#define UDCCR_REM (1 << 7) /* Reset interrupt mask */ + +#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */ +#define UDCCS0_OPR (1 << 0) /* OUT packet ready */ +#define UDCCS0_IPR (1 << 1) /* IN packet ready */ +#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */ +#define UDCCS0_SST (1 << 4) /* Sent stall */ +#define UDCCS0_FST (1 << 5) /* Force stall */ +#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */ +#define UDCCS0_SA (1 << 7) /* Setup active */ + +/* Bulk IN - Endpoint 1,6,11 */ +#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */ +#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */ +#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */ + +#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_BI_SST (1 << 4) /* Sent stall */ +#define UDCCS_BI_FST (1 << 5) /* Force stall */ +#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */ + +/* Bulk OUT - Endpoint 2,7,12 */ +#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */ +#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */ +#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */ + +#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */ +#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */ +#define UDCCS_BO_DME (1 << 3) /* DMA enable */ +#define UDCCS_BO_SST (1 << 4) /* Sent stall */ +#define UDCCS_BO_FST (1 << 5) /* Force stall */ +#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */ +#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */ + +/* Isochronous IN - Endpoint 3,8,13 */ +#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */ +#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */ +#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */ + +#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */ + +/* Isochronous OUT - Endpoint 4,9,14 */ +#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */ +#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */ +#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */ + +#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */ +#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */ +#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */ +#define UDCCS_IO_DME (1 << 3) /* DMA enable */ +#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */ +#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */ + +/* Interrupt IN - Endpoint 5,10,15 */ +#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */ +#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */ +#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */ + +#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_INT_SST (1 << 4) /* Sent stall */ +#define UDCCS_INT_FST (1 << 5) /* Force stall */ +#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */ + +#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */ +#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */ +#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */ +#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */ +#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */ +#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */ +#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */ +#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */ +#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */ +#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */ +#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */ +#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */ +#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */ +#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */ +#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */ +#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */ +#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */ +#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */ +#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */ +#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */ +#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */ +#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */ +#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */ +#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */ + +#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */ + +#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */ +#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */ +#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */ +#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */ +#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */ +#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */ +#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */ +#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */ + +#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */ + +#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */ +#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */ +#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */ +#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */ +#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */ +#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */ +#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */ +#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */ + +#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */ + +#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */ +#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */ +#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */ +#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */ +#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */ +#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */ +#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */ +#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */ + +#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */ + +#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */ +#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */ +#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */ +#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */ +#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */ +#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */ +#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */ +#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */ + +#endif diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h new file mode 100644 index 0000000..9cf0b1f --- /dev/null +++ b/include/asm-arm/arch-pxa/pxa27x-udc.h @@ -0,0 +1,256 @@ +#ifndef _ASM_ARCH_PXA27X_UDC_H +#define _ASM_ARCH_PXA27X_UDC_H + +#ifdef _ASM_ARCH_PXA25X_UDC_H +#error You can't include both PXA25x and PXA27x UDC support +#endif + +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ +#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation + Protocol Port Support */ +#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol + Support */ +#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol + Enable */ +#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ +#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ +#define UDCCR_ACN_S 11 +#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ +#define UDCCR_AIN_S 8 +#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface + Setting Number */ +#define UDCCR_AAISN_S 5 +#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active + Configuration */ +#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration + Error */ +#define UDCCR_UDR (1 << 2) /* UDC Resume */ +#define UDCCR_UDA (1 << 1) /* UDC Active */ +#define UDCCR_UDE (1 << 0) /* UDC Enable */ + +#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ +#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ +#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ +#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ +#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ +#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ +#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ +#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ + +#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ +#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ +#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ +#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ +#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ +#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ +#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ + +#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ +#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ +#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ +#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt + Rising Edge Interrupt Enable */ +#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt + Falling Edge Interrupt Enable */ +#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising + Edge Interrupt Enable */ +#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling + Edge Interrupt Enable */ +#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge + Interrupt Enable */ + +#define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */ + +#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ +#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ +#define UP2OCR_DPPDE (1 << 2) /* Host Port 2 Transceiver D+ Pull Down Enable */ +#define UP2OCR_DMPDE (1 << 3) /* Host Port 2 Transceiver D- Pull Down Enable */ +#define UP2OCR_DPPUE (1 << 4) /* Host Port 2 Transceiver D+ Pull Up Enable */ +#define UP2OCR_DMPUE (1 << 5) /* Host Port 2 Transceiver D- Pull Up Enable */ +#define UP2OCR_DPPUBE (1 << 6) /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */ +#define UP2OCR_DMPUBE (1 << 7) /* Host Port 2 Transceiver D- Pull Up Bypass Enable */ +#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ +#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ +#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ +#define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */ +#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ +#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ + +#define UDCCSN(x) __REG2(0x40600100, (x) << 2) +#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ +#define UDCCSR0_SA (1 << 7) /* Setup Active */ +#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ +#define UDCCSR0_FST (1 << 5) /* Force Stall */ +#define UDCCSR0_SST (1 << 4) /* Sent Stall */ +#define UDCCSR0_DME (1 << 3) /* DMA Enable */ +#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ +#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ +#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ + +#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ +#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ +#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ +#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ +#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ +#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ +#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ +#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ +#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ +#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ +#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ +#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ +#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ +#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ +#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ +#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ +#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ +#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ +#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ +#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ +#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ +#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ +#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ + +#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ +#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ +#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ +#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ +#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ +#define UDCCSR_FST (1 << 5) /* Force STALL */ +#define UDCCSR_SST (1 << 4) /* Sent STALL */ +#define UDCCSR_DME (1 << 3) /* DMA Enable */ +#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ +#define UDCCSR_PC (1 << 1) /* Packet Complete */ +#define UDCCSR_FS (1 << 0) /* FIFO needs service */ + +#define UDCBCN(x) __REG2(0x40600200, (x)<<2) +#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ +#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ +#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ +#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ +#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ +#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ +#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ +#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ +#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ +#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ +#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ +#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ +#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ +#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ +#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ +#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ +#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ +#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ +#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ +#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ +#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ +#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ +#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ +#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ + +#define UDCDN(x) __REG2(0x40600300, (x)<<2) +#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) +#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) +#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ +#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ +#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ +#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ +#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ +#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ +#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ +#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ +#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ +#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ +#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ +#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ +#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ +#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ +#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ +#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ +#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ +#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ +#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ +#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ +#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ +#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ +#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ +#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ + +#define UDCCN(x) __REG2(0x40600400, (x)<<2) +#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ +#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ +#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ +#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ +#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ +#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ +#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ +#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ +#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ +#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ +#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ +#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ +#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ +#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ +#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ +#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ +#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ +#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ +#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ +#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ +#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ +#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ +#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ + +#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ +#define UDCCONR_CN_S (25) +#define UDCCONR_IN (0x07 << 22) /* Interface Number */ +#define UDCCONR_IN_S (22) +#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ +#define UDCCONR_AISN_S (19) +#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ +#define UDCCONR_EN_S (15) +#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ +#define UDCCONR_ET_S (13) +#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ +#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ +#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ +#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ +#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ +#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ +#define UDCCONR_MPS_S (2) +#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ +#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ + + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDC_FNR_MASK (0x7ff) + +#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) +#define UDC_BCR_MASK (0x3ff) + +#endif -- cgit v0.10.2 From 0be9898adb6f58fee44f0fec0bbc0eac997ea9eb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:31:28 +0200 Subject: [ALSA] ASoC: Clarify API for bias configuration Currently the ASoC core configures the bias levels in the system using a callback on codecs and machines called 'dapm_event', passing it PCI style power levels as SNDRV_CTL_POWER_ constants. This is more obscure than it needs to be and has caused confusion to driver authors, especially given that DAPM is also performing power management. Address this by renaming the callback function to 'set_bias_level' and using constants explicitly representing the off, standby, pre-on and on states which DAPM transitions through. Also unexport the API for setting bias level: there are currently no in-tree users of this API other than the core itself and it is likely that the core would need to be extended to cater for any users. Signed-off-by: Mark Brown Cc: Jarkko Nikula Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index bf4cf0c..f8223fa 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -221,7 +221,8 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, /* dapm events */ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, int event); -int snd_soc_dapm_device_event(struct snd_soc_device *socdev, int event); +int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, + enum snd_soc_bias_level level); /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); diff --git a/include/sound/soc.h b/include/sound/soc.h index 73accbc..bca9538 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -103,6 +103,24 @@ .private_value = (unsigned long)&xenum } /* + * Bias levels + * + * @ON: Bias is fully on for audio playback and capture operations. + * @PREPARE: Prepare for audio operations. Called before DAPM switching for + * stream start and stop operations. + * @STANDBY: Low power standby state when no playback/capture operations are + * in progress. NOTE: The transition time between STANDBY and ON + * should be as fast as possible and no longer than 10ms. + * @OFF: Power Off. No restrictions on transition times. + */ +enum snd_soc_bias_level { + SND_SOC_BIAS_ON, + SND_SOC_BIAS_PREPARE, + SND_SOC_BIAS_STANDBY, + SND_SOC_BIAS_OFF, +}; + +/* * Digital Audio Interface (DAI) types */ #define SND_SOC_DAI_AC97 0x1 @@ -356,7 +374,8 @@ struct snd_soc_codec { struct mutex mutex; /* callbacks */ - int (*dapm_event)(struct snd_soc_codec *codec, int event); + int (*set_bias_level)(struct snd_soc_codec *, + enum snd_soc_bias_level level); /* runtime */ struct snd_card *card; @@ -378,8 +397,8 @@ struct snd_soc_codec { /* dapm */ struct list_head dapm_widgets; struct list_head dapm_paths; - unsigned int dapm_state; - unsigned int suspend_dapm_state; + enum snd_soc_bias_level bias_level; + enum snd_soc_bias_level suspend_bias_level; struct delayed_work delayed_work; /* codec DAI's */ @@ -449,7 +468,8 @@ struct snd_soc_machine { int (*resume_post)(struct platform_device *pdev); /* callbacks */ - int (*dapm_event)(struct snd_soc_machine *, int event); + int (*set_bias_level)(struct snd_soc_machine *, + enum snd_soc_bias_level level); /* CPU <--> Codec DAI links */ struct snd_soc_dai_link *dai_link; diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index cb8365a..dc8a38d 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -847,13 +847,14 @@ static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return 0; } -static int aic3x_dapm_event(struct snd_soc_codec *codec, int event) +static int aic3x_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { struct aic3x_priv *aic3x = codec->private_data; u8 reg; - switch (event) { - case SNDRV_CTL_POWER_D0: + switch (level) { + case SND_SOC_BIAS_ON: /* all power is driven by DAPM system */ if (aic3x->master) { /* enable pll */ @@ -862,10 +863,9 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event) reg | PLL_ENABLE); } break; - case SNDRV_CTL_POWER_D1: - case SNDRV_CTL_POWER_D2: + case SND_SOC_BIAS_PREPARE: break; - case SNDRV_CTL_POWER_D3hot: + case SND_SOC_BIAS_STANDBY: /* * all power is driven by DAPM system, * so output power is safe if bypass was set @@ -877,7 +877,7 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event) reg & ~PLL_ENABLE); } break; - case SNDRV_CTL_POWER_D3cold: + case SND_SOC_BIAS_OFF: /* force all power off */ reg = aic3x_read_reg_cache(codec, LINE1L_2_LADC_CTRL); aic3x_write(codec, LINE1L_2_LADC_CTRL, reg & ~LADC_PWR_ON); @@ -913,7 +913,7 @@ static int aic3x_dapm_event(struct snd_soc_codec *codec, int event) } break; } - codec->dapm_state = event; + codec->bias_level = level; return 0; } @@ -979,7 +979,7 @@ static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->codec; - aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -999,7 +999,7 @@ static int aic3x_resume(struct platform_device *pdev) codec->hw_write(codec->control_data, data, 2); } - aic3x_dapm_event(codec, codec->suspend_dapm_state); + aic3x_set_bias_level(codec, codec->suspend_bias_level); return 0; } @@ -1018,7 +1018,7 @@ static int aic3x_init(struct snd_soc_device *socdev) codec->owner = THIS_MODULE; codec->read = aic3x_read_reg_cache; codec->write = aic3x_write; - codec->dapm_event = aic3x_dapm_event; + codec->set_bias_level = aic3x_set_bias_level; codec->dai = &aic3x_dai; codec->num_dai = 1; codec->reg_cache_size = sizeof(aic3x_reg); @@ -1100,7 +1100,7 @@ static int aic3x_init(struct snd_soc_device *socdev) aic3x_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); /* off, with power on */ - aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* setup GPIO functions */ aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); @@ -1271,7 +1271,7 @@ static int aic3x_remove(struct platform_device *pdev) /* power down chip */ if (codec->control_data) - aic3x_dapm_event(codec, SNDRV_CTL_POWER_D3); + aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 0cf9265..0f28aa4 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -435,29 +435,29 @@ static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return 0; } -static int wm8731_dapm_event(struct snd_soc_codec *codec, int event) +static int wm8731_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ + switch (level) { + case SND_SOC_BIAS_ON: /* vref/mid, osc on, dac unmute */ wm8731_write(codec, WM8731_PWR, reg); break; - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ + case SND_SOC_BIAS_PREPARE: break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + case SND_SOC_BIAS_STANDBY: /* everything off except vref/vmid, */ wm8731_write(codec, WM8731_PWR, reg | 0x0040); break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + case SND_SOC_BIAS_OFF: /* everything off, dac mute, inactive */ wm8731_write(codec, WM8731_ACTIVE, 0x0); wm8731_write(codec, WM8731_PWR, 0xffff); break; } - codec->dapm_state = event; + codec->bias_level = level; return 0; } @@ -503,7 +503,7 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) struct snd_soc_codec *codec = socdev->codec; wm8731_write(codec, WM8731_ACTIVE, 0x0); - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -521,8 +521,8 @@ static int wm8731_resume(struct platform_device *pdev) data[1] = cache[i] & 0x00ff; codec->hw_write(codec->control_data, data, 2); } - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); - wm8731_dapm_event(codec, codec->suspend_dapm_state); + wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + wm8731_set_bias_level(codec, codec->suspend_bias_level); return 0; } @@ -539,7 +539,7 @@ static int wm8731_init(struct snd_soc_device *socdev) codec->owner = THIS_MODULE; codec->read = wm8731_read_reg_cache; codec->write = wm8731_write; - codec->dapm_event = wm8731_dapm_event; + codec->set_bias_level = wm8731_set_bias_level; codec->dai = &wm8731_dai; codec->num_dai = 1; codec->reg_cache_size = sizeof(wm8731_reg); @@ -557,7 +557,7 @@ static int wm8731_init(struct snd_soc_device *socdev) } /* power on device */ - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* set the update bits */ reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); @@ -730,7 +730,7 @@ static int wm8731_remove(struct platform_device *pdev) struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 16cd5d4..62423f4 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -686,29 +686,29 @@ static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute) return 0; } -static int wm8750_dapm_event(struct snd_soc_codec *codec, int event) +static int wm8750_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ + switch (level) { + case SND_SOC_BIAS_ON: /* set vmid to 50k and unmute dac */ wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); break; - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ + case SND_SOC_BIAS_PREPARE: /* set vmid to 5k for quick power up */ wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + case SND_SOC_BIAS_STANDBY: /* mute dac and set vmid to 500k, enable VREF */ wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + case SND_SOC_BIAS_OFF: wm8750_write(codec, WM8750_PWR1, 0x0001); break; } - codec->dapm_state = event; + codec->bias_level = level; return 0; } @@ -748,7 +748,7 @@ static void wm8750_work(struct work_struct *work) { struct snd_soc_codec *codec = container_of(work, struct snd_soc_codec, delayed_work.work); - wm8750_dapm_event(codec, codec->dapm_state); + wm8750_set_bias_level(codec, codec->bias_level); } static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) @@ -756,7 +756,7 @@ static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->codec; - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -777,12 +777,12 @@ static int wm8750_resume(struct platform_device *pdev) codec->hw_write(codec->control_data, data, 2); } - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge wm8750 caps */ - if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); - codec->dapm_state = SNDRV_CTL_POWER_D0; + if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); + codec->bias_level = SND_SOC_BIAS_ON; schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); } @@ -803,7 +803,7 @@ static int wm8750_init(struct snd_soc_device *socdev) codec->owner = THIS_MODULE; codec->read = wm8750_read_reg_cache; codec->write = wm8750_write; - codec->dapm_event = wm8750_dapm_event; + codec->set_bias_level = wm8750_set_bias_level; codec->dai = &wm8750_dai; codec->num_dai = 1; codec->reg_cache_size = sizeof(wm8750_reg); @@ -821,8 +821,8 @@ static int wm8750_init(struct snd_soc_device *socdev) } /* charge output caps */ - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); - codec->dapm_state = SNDRV_CTL_POWER_D3hot; + wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); + codec->bias_level = SND_SOC_BIAS_STANDBY; schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); /* set the update bits */ @@ -1021,7 +1021,7 @@ static int wm8750_remove(struct platform_device *pdev) struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); run_delayed_work(&codec->delayed_work); snd_soc_free_pcms(socdev); snd_soc_dapm_free(socdev); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index fb41826..9032b0c 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1274,29 +1274,29 @@ static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute) return 0; } -static int wm8753_dapm_event(struct snd_soc_codec *codec, int event) +static int wm8753_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ + switch (level) { + case SND_SOC_BIAS_ON: /* set vmid to 50k and unmute dac */ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); break; - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ + case SND_SOC_BIAS_PREPARE: /* set vmid to 5k for quick power up */ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + case SND_SOC_BIAS_STANDBY: /* mute dac and set vmid to 500k, enable VREF */ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + case SND_SOC_BIAS_OFF: wm8753_write(codec, WM8753_PWR1, 0x0001); break; } - codec->dapm_state = event; + codec->bias_level = level; return 0; } @@ -1500,7 +1500,7 @@ static void wm8753_work(struct work_struct *work) { struct snd_soc_codec *codec = container_of(work, struct snd_soc_codec, delayed_work.work); - wm8753_dapm_event(codec, codec->dapm_state); + wm8753_set_bias_level(codec, codec->bias_level); } static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) @@ -1512,7 +1512,7 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) if (!codec->card) return 0; - wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -1537,12 +1537,12 @@ static int wm8753_resume(struct platform_device *pdev) codec->hw_write(codec->control_data, data, 2); } - wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge wm8753 caps */ - if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { - wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); - codec->dapm_state = SNDRV_CTL_POWER_D0; + if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); + codec->bias_level = SND_SOC_BIAS_ON; schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(caps_charge)); } @@ -1563,7 +1563,7 @@ static int wm8753_init(struct snd_soc_device *socdev) codec->owner = THIS_MODULE; codec->read = wm8753_read_reg_cache; codec->write = wm8753_write; - codec->dapm_event = wm8753_dapm_event; + codec->set_bias_level = wm8753_set_bias_level; codec->dai = wm8753_dai; codec->num_dai = 2; codec->reg_cache_size = sizeof(wm8753_reg); @@ -1584,8 +1584,8 @@ static int wm8753_init(struct snd_soc_device *socdev) } /* charge output caps */ - wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); - codec->dapm_state = SNDRV_CTL_POWER_D3hot; + 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)); @@ -1792,7 +1792,7 @@ static int wm8753_remove(struct platform_device *pdev) struct snd_soc_codec *codec = socdev->codec; if (codec->control_data) - wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + 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); diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 89efe40..e26cfcf 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -571,23 +571,23 @@ struct snd_soc_codec_dai wm9712_dai[] = { }; EXPORT_SYMBOL_GPL(wm9712_dai); -static int wm9712_dapm_event(struct snd_soc_codec *codec, int event) +static int wm9712_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ + switch (level) { + case SND_SOC_BIAS_ON: + case SND_SOC_BIAS_PREPARE: break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + case SND_SOC_BIAS_STANDBY: ac97_write(codec, AC97_POWERDOWN, 0x0000); break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + case SND_SOC_BIAS_OFF: /* disable everything including AC link */ ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->dapm_state = event; + codec->bias_level = level; return 0; } @@ -615,7 +615,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->codec; - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } @@ -632,7 +632,7 @@ static int wm9712_soc_resume(struct platform_device *pdev) return ret; } - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); if (ret == 0) { /* Sync reg_cache with the hardware after cold reset */ @@ -644,8 +644,8 @@ static int wm9712_soc_resume(struct platform_device *pdev) } } - if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D0); + if (codec->suspend_bias_level == SND_SOC_BIAS_ON) + wm9712_set_bias_level(codec, SND_SOC_BIAS_ON); return ret; } @@ -679,7 +679,7 @@ static int wm9712_soc_probe(struct platform_device *pdev) codec->num_dai = ARRAY_SIZE(wm9712_dai); codec->write = ac97_write; codec->read = ac97_read; - codec->dapm_event = wm9712_dapm_event; + codec->set_bias_level = wm9712_set_bias_level; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -703,7 +703,7 @@ static int wm9712_soc_probe(struct platform_device *pdev) /* set alc mux to none */ ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); wm9712_add_controls(codec); wm9712_add_widgets(codec); ret = snd_soc_register_card(socdev); diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 9e6b2fd..4863636 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1094,33 +1094,33 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm) } EXPORT_SYMBOL_GPL(wm9713_reset); -static int wm9713_dapm_event(struct snd_soc_codec *codec, int event) +static int wm9713_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) { u16 reg; - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ + switch (level) { + case SND_SOC_BIAS_ON: /* enable thermal shutdown */ reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff; ac97_write(codec, AC97_EXTENDED_MID, reg); break; - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ + case SND_SOC_BIAS_PREPARE: break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + case SND_SOC_BIAS_STANDBY: /* enable master bias and vmid */ reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff; ac97_write(codec, AC97_EXTENDED_MID, reg); ac97_write(codec, AC97_POWERDOWN, 0x0000); break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + case SND_SOC_BIAS_OFF: /* disable everything including AC link */ ac97_write(codec, AC97_EXTENDED_MID, 0xffff); ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->dapm_state = event; + codec->bias_level = level; return 0; } @@ -1157,7 +1157,7 @@ static int wm9713_soc_resume(struct platform_device *pdev) return ret; } - wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* do we need to re-start the PLL ? */ if (wm9713->pll_out) @@ -1173,8 +1173,8 @@ static int wm9713_soc_resume(struct platform_device *pdev) } } - if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) - wm9713_dapm_event(codec, SNDRV_CTL_POWER_D0); + if (codec->suspend_bias_level == SND_SOC_BIAS_ON) + wm9713_set_bias_level(codec, SND_SOC_BIAS_ON); return ret; } @@ -1213,7 +1213,7 @@ static int wm9713_soc_probe(struct platform_device *pdev) codec->num_dai = ARRAY_SIZE(wm9713_dai); codec->write = ac97_write; codec->read = ac97_read; - codec->dapm_event = wm9713_dapm_event; + codec->set_bias_level = wm9713_set_bias_level; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); @@ -1235,7 +1235,7 @@ static int wm9713_soc_probe(struct platform_device *pdev) goto reset_err; } - wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + wm9713_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* unmute the adc - move to kcontrol */ reg = ac97_read(codec, AC97_CD) & 0x7fff; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 0318d8a..a05b345 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -283,12 +283,12 @@ static void close_delayed_work(struct work_struct *work) /* are we waiting on this codec DAI stream */ if (codec_dai->pop_wait == 1) { - /* power down the codec to D1 if no longer active */ + /* Reduce power if no longer active */ if (codec->active == 0) { dbg("pop wq D1 %s %s\n", codec->name, codec_dai->playback.stream_name); - snd_soc_dapm_device_event(socdev, - SNDRV_CTL_POWER_D1); + snd_soc_dapm_set_bias_level(socdev, + SND_SOC_BIAS_PREPARE); } codec_dai->pop_wait = 0; @@ -296,12 +296,12 @@ static void close_delayed_work(struct work_struct *work) codec_dai->playback.stream_name, SND_SOC_DAPM_STREAM_STOP); - /* power down the codec power domain if no longer active */ + /* Fall into standby if no longer active */ if (codec->active == 0) { dbg("pop wq D3 %s %s\n", codec->name, codec_dai->playback.stream_name); - snd_soc_dapm_device_event(socdev, - SNDRV_CTL_POWER_D3hot); + snd_soc_dapm_set_bias_level(socdev, + SND_SOC_BIAS_STANDBY); } } } @@ -361,8 +361,8 @@ static int soc_codec_close(struct snd_pcm_substream *substream) SND_SOC_DAPM_STREAM_STOP); if (codec->active == 0 && codec_dai->pop_wait == 0) - snd_soc_dapm_device_event(socdev, - SNDRV_CTL_POWER_D3hot); + snd_soc_dapm_set_bias_level(socdev, + SND_SOC_BIAS_STANDBY); } mutex_unlock(&pcm_mutex); @@ -435,9 +435,10 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) } } else { /* no delayed work - do we need to power up codec */ - if (codec->dapm_state != SNDRV_CTL_POWER_D0) { + if (codec->bias_level != SND_SOC_BIAS_ON) { - snd_soc_dapm_device_event(socdev, SNDRV_CTL_POWER_D1); + snd_soc_dapm_set_bias_level(socdev, + SND_SOC_BIAS_PREPARE); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) snd_soc_dapm_stream_event(codec, @@ -448,7 +449,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) codec_dai->capture.stream_name, SND_SOC_DAPM_STREAM_START); - snd_soc_dapm_device_event(socdev, SNDRV_CTL_POWER_D0); + snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); if (codec_dai->dai_ops.digital_mute) codec_dai->dai_ops.digital_mute(codec_dai, 0); @@ -658,7 +659,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) /* close any waiting streams and save state */ run_delayed_work(&socdev->delayed_work); - codec->suspend_dapm_state = codec->dapm_state; + codec->suspend_bias_level = codec->bias_level; for(i = 0; i < codec->num_dai; i++) { char *stream = codec->dai[i].playback.stream_name; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8a3192b..728f3ac 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -763,21 +763,18 @@ static ssize_t dapm_widget_show(struct device *dev, } } - switch(codec->dapm_state){ - case SNDRV_CTL_POWER_D0: - state = "D0"; + switch (codec->bias_level) { + case SND_SOC_BIAS_ON: + state = "On"; break; - case SNDRV_CTL_POWER_D1: - state = "D1"; + case SND_SOC_BIAS_PREPARE: + state = "Prepare"; break; - case SNDRV_CTL_POWER_D2: - state = "D2"; + case SND_SOC_BIAS_STANDBY: + state = "Standby"; break; - case SNDRV_CTL_POWER_D3hot: - state = "D3hot"; - break; - case SNDRV_CTL_POWER_D3cold: - state = "D3cold"; + case SND_SOC_BIAS_OFF: + state = "Off"; break; } count += sprintf(buf + count, "PM State: %s\n", state); @@ -1358,27 +1355,28 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); /** - * snd_soc_dapm_device_event - send a device event to the dapm core + * snd_soc_dapm_set_bias_level - set the bias level for the system * @socdev: audio device - * @event: device event + * @level: level to configure * - * Sends a device event to the dapm core. The core then makes any - * necessary machine or codec power changes.. + * Configure the bias (power) levels for the SoC audio device. * * Returns 0 for success else error. */ -int snd_soc_dapm_device_event(struct snd_soc_device *socdev, int event) +int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, + enum snd_soc_bias_level level) { struct snd_soc_codec *codec = socdev->codec; struct snd_soc_machine *machine = socdev->machine; + int ret = 0; - if (machine->dapm_event) - machine->dapm_event(machine, event); - if (codec->dapm_event) - codec->dapm_event(codec, event); - return 0; + if (machine->set_bias_level) + ret = machine->set_bias_level(machine, level); + if (ret == 0 && codec->set_bias_level) + ret = codec->set_bias_level(codec, level); + + return ret; } -EXPORT_SYMBOL_GPL(snd_soc_dapm_device_event); /** * snd_soc_dapm_set_endpoint - set audio endpoint status -- cgit v0.10.2 From 3ff3f64ba04b3e5a86dce5239b10268798f68ad7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 May 2008 12:32:25 +0200 Subject: [ALSA] ASoC: core checkpatch cleanups Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a05b345..a3f091e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -108,9 +108,9 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) } #endif -static inline const char* get_dai_name(int type) +static inline const char *get_dai_name(int type) { - switch(type) { + switch (type) { case SND_SOC_DAI_AC97_BUS: case SND_SOC_DAI_AC97: return "AC97"; @@ -178,9 +178,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) /* Check that the codec and cpu DAI's are compatible */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { runtime->hw.rate_min = - max(codec_dai->playback.rate_min, cpu_dai->playback.rate_min); + max(codec_dai->playback.rate_min, + cpu_dai->playback.rate_min); runtime->hw.rate_max = - min(codec_dai->playback.rate_max, cpu_dai->playback.rate_max); + min(codec_dai->playback.rate_max, + cpu_dai->playback.rate_max); runtime->hw.channels_min = max(codec_dai->playback.channels_min, cpu_dai->playback.channels_min); @@ -193,9 +195,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) codec_dai->playback.rates & cpu_dai->playback.rates; } else { runtime->hw.rate_min = - max(codec_dai->capture.rate_min, cpu_dai->capture.rate_min); + max(codec_dai->capture.rate_min, + cpu_dai->capture.rate_min); runtime->hw.rate_max = - min(codec_dai->capture.rate_max, cpu_dai->capture.rate_max); + min(codec_dai->capture.rate_max, + cpu_dai->capture.rate_max); runtime->hw.channels_min = max(codec_dai->capture.channels_min, cpu_dai->capture.channels_min); @@ -225,7 +229,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) goto machine_err; } - dbg("asoc: %s <-> %s info:\n",codec_dai->name, cpu_dai->name); + dbg("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); dbg("asoc: rate mask 0x%x\n", runtime->hw.rates); dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, runtime->hw.channels_max); @@ -272,7 +276,7 @@ static void close_delayed_work(struct work_struct *work) int i; mutex_lock(&pcm_mutex); - for(i = 0; i < codec->num_dai; i++) { + for (i = 0; i < codec->num_dai; i++) { codec_dai = &codec->dai[i]; dbg("pop wq checking: %s status: %s waiting: %s\n", @@ -511,7 +515,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (cpu_dai->ops.hw_params) { ret = cpu_dai->ops.hw_params(substream, params); if (ret < 0) { - printk(KERN_ERR "asoc: can't set interface %s hw params\n", + printk(KERN_ERR "asoc: interface %s hw params failed\n", cpu_dai->name); goto interface_err; } @@ -520,7 +524,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, if (platform->pcm_ops->hw_params) { ret = platform->pcm_ops->hw_params(substream, params); if (ret < 0) { - printk(KERN_ERR "asoc: can't set platform %s hw params\n", + printk(KERN_ERR "asoc: platform %s hw params failed\n", platform->name); goto platform_err; } @@ -539,7 +543,7 @@ interface_err: codec_dai->ops.hw_free(substream); codec_err: - if(machine->ops && machine->ops->hw_free) + if (machine->ops && machine->ops->hw_free) machine->ops->hw_free(substream); mutex_unlock(&pcm_mutex); @@ -628,15 +632,15 @@ static struct snd_pcm_ops soc_pcm_ops = { /* powers down audio subsystem for suspend */ static int soc_suspend(struct platform_device *pdev, pm_message_t state) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_codec_device *codec_dev = socdev->codec_dev; + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_machine *machine = socdev->machine; + struct snd_soc_platform *platform = socdev->platform; + struct snd_soc_codec_device *codec_dev = socdev->codec_dev; struct snd_soc_codec *codec = socdev->codec; int i; /* mute any active DAC's */ - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; if (dai->dai_ops.digital_mute && dai->playback.active) dai->dai_ops.digital_mute(dai, 1); @@ -649,7 +653,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) if (machine->suspend_pre) machine->suspend_pre(pdev, state); - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) cpu_dai->suspend(pdev, cpu_dai); @@ -661,7 +665,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) run_delayed_work(&socdev->delayed_work); codec->suspend_bias_level = codec->bias_level; - for(i = 0; i < codec->num_dai; i++) { + for (i = 0; i < codec->num_dai; i++) { char *stream = codec->dai[i].playback.stream_name; if (stream != NULL) snd_soc_dapm_stream_event(codec, stream, @@ -675,7 +679,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) if (codec_dev->suspend) codec_dev->suspend(pdev, state); - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) cpu_dai->suspend(pdev, cpu_dai); @@ -690,17 +694,17 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) /* powers up audio subsystem after a suspend */ static int soc_resume(struct platform_device *pdev) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_codec_device *codec_dev = socdev->codec_dev; + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_machine *machine = socdev->machine; + struct snd_soc_platform *platform = socdev->platform; + struct snd_soc_codec_device *codec_dev = socdev->codec_dev; struct snd_soc_codec *codec = socdev->codec; int i; if (machine->resume_pre) machine->resume_pre(pdev); - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) cpu_dai->resume(pdev, cpu_dai); @@ -709,8 +713,8 @@ static int soc_resume(struct platform_device *pdev) if (codec_dev->resume) codec_dev->resume(pdev); - for(i = 0; i < codec->num_dai; i++) { - char* stream = codec->dai[i].playback.stream_name; + for (i = 0; i < codec->num_dai; i++) { + char *stream = codec->dai[i].playback.stream_name; if (stream != NULL) snd_soc_dapm_stream_event(codec, stream, SND_SOC_DAPM_STREAM_RESUME); @@ -720,14 +724,14 @@ static int soc_resume(struct platform_device *pdev) SND_SOC_DAPM_STREAM_RESUME); } - /* unmute any active DAC's */ - for(i = 0; i < machine->num_links; i++) { + /* unmute any active DACs */ + for (i = 0; i < machine->num_links; i++) { struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; if (dai->dai_ops.digital_mute && dai->playback.active) dai->dai_ops.digital_mute(dai, 0); } - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) cpu_dai->resume(pdev, cpu_dai); @@ -757,7 +761,7 @@ static int soc_probe(struct platform_device *pdev) if (machine->probe) { ret = machine->probe(pdev); - if(ret < 0) + if (ret < 0) return ret; } @@ -765,20 +769,20 @@ static int soc_probe(struct platform_device *pdev) struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->probe) { ret = cpu_dai->probe(pdev); - if(ret < 0) + if (ret < 0) goto cpu_dai_err; } } if (codec_dev->probe) { ret = codec_dev->probe(pdev); - if(ret < 0) + if (ret < 0) goto cpu_dai_err; } if (platform->probe) { ret = platform->probe(pdev); - if(ret < 0) + if (ret < 0) goto platform_err; } @@ -865,7 +869,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev, codec_dai->codec = socdev->codec; /* check client and interface hw capabilities */ - sprintf(new_name, "%s %s-%s-%d",dai_link->stream_name, codec_dai->name, + sprintf(new_name, "%s %s-%s-%d", dai_link->stream_name, codec_dai->name, get_dai_name(cpu_dai->type), num); if (codec_dai->playback.channels_min) @@ -876,7 +880,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev, ret = snd_pcm_new(codec->card, new_name, codec->pcm_devs++, playback, capture, &pcm); if (ret < 0) { - printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); + printk(KERN_ERR "asoc: can't create pcm for codec %s\n", + codec->name); kfree(rtd); return ret; } @@ -925,8 +930,9 @@ static ssize_t codec_reg_show(struct device *dev, step = codec->reg_cache_step; count += sprintf(buf, "%s registers\n", codec->name); - for(i = 0; i < codec->reg_cache_size; i += step) - count += sprintf(buf + count, "%2x: %4x\n", i, codec->read(codec, i)); + for (i = 0; i < codec->reg_cache_size; i += step) + count += sprintf(buf + count, "%2x: %4x\n", i, + codec->read(codec, i)); return count; } @@ -1069,7 +1075,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); /* create the pcms */ - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { ret = soc_new_pcm(socdev, &machine->dai_link[i], i); if (ret < 0) { printk(KERN_ERR "asoc: can't create pcm %s\n", @@ -1099,7 +1105,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev) struct snd_soc_machine *machine = socdev->machine; int ret = 0, i, ac97 = 0, err = 0; - for(i = 0; i < machine->num_links; i++) { + for (i = 0; i < machine->num_links; i++) { if (socdev->machine->dai_link[i].init) { err = socdev->machine->dai_link[i].init(codec); if (err < 0) { @@ -1108,7 +1114,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev) continue; } } - if (socdev->machine->dai_link[i].codec_dai->type == + if (socdev->machine->dai_link[i].codec_dai->type == SND_SOC_DAI_AC97_BUS) ac97 = 1; } @@ -1119,7 +1125,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev) ret = snd_card_register(codec->card); if (ret < 0) { - printk(KERN_ERR "asoc: failed to register soundcard for codec %s\n", + printk(KERN_ERR "asoc: failed to register soundcard for %s\n", codec->name); goto out; } @@ -1143,7 +1149,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev) err = device_create_file(socdev->dev, &dev_attr_codec_reg); if (err < 0) - printk(KERN_WARNING "asoc: failed to add codec sysfs entries\n"); + printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); mutex_unlock(&codec->mutex); @@ -1169,7 +1175,7 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev) mutex_lock(&codec->mutex); #ifdef CONFIG_SND_SOC_AC97_BUS - for(i = 0; i < codec->num_dai; i++) { + for (i = 0; i < codec->num_dai; i++) { codec_dai = &codec->dai[i]; if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) { soc_ac97_dev_unregister(codec); @@ -1279,7 +1285,8 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) ; val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); + ucontrol->value.enumerated.item[0] + = (val >> e->shift_l) & (bitmask - 1); if (e->shift_l != e->shift_r) ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (bitmask - 1); @@ -1573,7 +1580,8 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, val = val << shift; val2 = val2 << shift; - if ((err = snd_soc_update_bits(codec, reg, val_mask, val)) < 0) + err = snd_soc_update_bits(codec, reg, val_mask, val); + if (err < 0) return err; err = snd_soc_update_bits(codec, reg2, val_mask, val2); @@ -1589,7 +1597,7 @@ static int __devinit snd_soc_init(void) static void snd_soc_exit(void) { - platform_driver_unregister(&soc_driver); + platform_driver_unregister(&soc_driver); } module_init(snd_soc_init); -- cgit v0.10.2 From a65f0568f6cc8433877fb71dd7d36b551854b0bc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 May 2008 14:54:43 +0200 Subject: [ALSA] soc - Convert Wolfson codec drivers to use bulk DAPM registration Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 0f28aa4..5acf43a 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -193,7 +193,7 @@ SND_SOC_DAPM_INPUT("RLINEIN"), SND_SOC_DAPM_INPUT("LLINEIN"), }; -static const char *intercon[][3] = { +static const struct snd_soc_dapm_route intercon[] = { /* output mixer */ {"Output Mixer", "Line Bypass Switch", "Line Input"}, {"Output Mixer", "HiFi Playback Switch", "DAC"}, @@ -214,22 +214,14 @@ static const char *intercon[][3] = { {"Line Input", NULL, "LLINEIN"}, {"Line Input", NULL, "RLINEIN"}, {"Mic Bias", NULL, "MICIN"}, - - /* terminator */ - {NULL, NULL, NULL}, }; static int wm8731_add_widgets(struct snd_soc_codec *codec) { - int i; - - for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + ARRAY_SIZE(wm8731_dapm_widgets)); - /* set up audio path interconnects */ - for (i = 0; intercon[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, intercon[i][0], - intercon[i][1], intercon[i][2]); + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); snd_soc_dapm_new_widgets(codec); return 0; diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 62423f4..1f11ad2 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -378,7 +378,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { SND_SOC_DAPM_INPUT("RINPUT3"), }; -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* left mixer */ {"Left Mixer", "Playback Switch", "Left DAC"}, {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, @@ -470,22 +470,14 @@ static const char *audio_map[][3] = { /* ADC */ {"Left ADC", NULL, "Left ADC Mux"}, {"Right ADC", NULL, "Right ADC Mux"}, - - /* terminator */ - {NULL, NULL, NULL}, }; static int wm8750_add_widgets(struct snd_soc_codec *codec) { - int i; - - for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + ARRAY_SIZE(wm8750_dapm_widgets)); - /* set up audio path audio_mapnects */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_new_widgets(codec); return 0; diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 9032b0c..c32e632 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -523,7 +523,7 @@ SND_SOC_DAPM_INPUT("MIC2"), SND_SOC_DAPM_VMID("VREF"), }; -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* left mixer */ {"Left Mixer", "Left Playback Switch", "Left DAC"}, {"Left Mixer", "Voice Playback Switch", "Voice DAC"}, @@ -674,23 +674,14 @@ static const char *audio_map[][3] = { /* ACOP */ {"ACOP", NULL, "ALC Mixer"}, - - /* terminator */ - {NULL, NULL, NULL}, }; static int wm8753_add_widgets(struct snd_soc_codec *codec) { - int i; + snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); - for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); - - /* set up the WM8753 audio map */ - for (i = 0; audio_map[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); - } + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_new_widgets(codec); return 0; diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index e26cfcf..d9789f1 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -348,7 +348,7 @@ SND_SOC_DAPM_INPUT("MIC1"), SND_SOC_DAPM_INPUT("MIC2"), }; -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* virtual mixer - mixes left & right channels for spk and mono */ {"AC97 Mixer", NULL, "Left DAC"}, {"AC97 Mixer", NULL, "Right DAC"}, @@ -443,21 +443,14 @@ static const char *audio_map[][3] = { {"Speaker PGA", NULL, "Speaker Mux"}, {"LOUT2", NULL, "Speaker PGA"}, {"ROUT2", NULL, "Speaker PGA"}, - - {NULL, NULL, NULL}, }; static int wm9712_add_widgets(struct snd_soc_codec *codec) { - int i; - - for (i = 0; i < ARRAY_SIZE(wm9712_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm9712_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets, + ARRAY_SIZE(wm9712_dapm_widgets)); - /* set up audio path connects */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_new_widgets(codec); return 0; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 4863636..4f516a5 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -453,7 +453,7 @@ SND_SOC_DAPM_INPUT("MIC2B"), SND_SOC_DAPM_VMID("VMID"), }; -static const char *audio_map[][3] = { +static const struct snd_soc_dapm_route audio_map[] = { /* left HP mixer */ {"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, @@ -604,21 +604,14 @@ static const char *audio_map[][3] = { {"Capture Mono Mux", "Stereo", "Capture Mixer"}, {"Capture Mono Mux", "Left", "Left Capture Source"}, {"Capture Mono Mux", "Right", "Right Capture Source"}, - - {NULL, NULL, NULL}, }; static int wm9713_add_widgets(struct snd_soc_codec *codec) { - int i; - - for (i = 0; i < ARRAY_SIZE(wm9713_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm9713_dapm_widgets[i]); + snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets, + ARRAY_SIZE(wm9713_dapm_widgets)); - /* set up audio path audio_mapnects */ - for (i = 0; audio_map[i][0] != NULL; i++) - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_new_widgets(codec); return 0; -- cgit v0.10.2 From 33e5b22285f63ede858c00456f3ffbc2ea79d6cf Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 14 Apr 2008 14:26:44 +0200 Subject: [ALSA] soc - Fix s3c24xx-i2s LR sync while timer ticks are disabled When timer ticks are disabled when calling sound/soc/s3c24xx/s3c24xx-i2s.c:s3c24xx_snd_lrsync and the LR signal never happens, we loop forever. This has been observed in the following call chain: snd_pcm_common_ioctl1 -> snd_pcm_action_lock_irq -> snd_pcm_action_single -> snd_pcm_do_resume -> soc_pcm_trigger -> s3c24xx_i2s_trigger The patch below changes the timeout mechanism to use udelay, which doesn't need timer ticks. Signed-off-by: Werner Almesberger Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index ddf8724..4c52f79 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -175,7 +175,7 @@ static void s3c24xx_snd_rxctrl(int on) static int s3c24xx_snd_lrsync(void) { u32 iiscon; - unsigned long timeout = jiffies + msecs_to_jiffies(5); + int timeout = 50; /* 5ms */ DBG("Entered %s\n", __func__); @@ -184,8 +184,9 @@ static int s3c24xx_snd_lrsync(void) if (iiscon & S3C2410_IISCON_LRINDEX) break; - if (time_after(jiffies, timeout)) + if (!timeout--) return -ETIMEDOUT; + udelay(100); } return 0; -- cgit v0.10.2 From aea3bfbcfb0453217c8da6cfdc1b2394d214bee5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 20 May 2008 14:22:44 +0200 Subject: [ALSA] ice1724: fix MIDI The VT1724 MIDI port is not MPU-401 compatible; remove the hacks that try to make the MPU-401 library work with it, and just use some simple device-specific code. Signed-off-by: Clemens Ladisch Tested-by: Pavel Hofman diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 7e47421..d95fbb2 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -692,7 +692,7 @@ config SND_ICE1712 config SND_ICE1724 tristate "ICE/VT1724/1720 (Envy24HT/PT)" depends on SND - select SND_MPU401_UART + select SND_RAWMIDI select SND_AC97_CODEC select SND_VMASTER help diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h index 43b9e3e..a0c5e00 100644 --- a/sound/pci/ice1712/envy24ht.h +++ b/sound/pci/ice1712/envy24ht.h @@ -93,9 +93,13 @@ enum { #define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/ #define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/ -//are these 2 the wrong way around? they don't seem to be used yet anyway -#define VT1724_REG_MPU_CTRL 0x0c /* byte */ -#define VT1724_REG_MPU_DATA 0x0d /* byte */ +#define VT1724_REG_MPU_DATA 0x0c /* byte */ +#define VT1724_REG_MPU_CTRL 0x0d /* byte */ +#define VT1724_MPU_UART 0x01 +#define VT1724_MPU_TX_EMPTY 0x02 +#define VT1724_MPU_TX_FULL 0x04 +#define VT1724_MPU_RX_EMPTY 0x08 +#define VT1724_MPU_RX_FULL 0x10 #define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/ #define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 3208901..762fbd7 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -333,6 +333,8 @@ struct snd_ice1712 { unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */ unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */ + unsigned int midi_output: 1; /* VT1720/4: MIDI output triggered */ + unsigned int midi_input: 1; /* VT1720/4: MIDI input triggered */ unsigned int num_total_dacs; /* total DACs */ unsigned int num_total_adcs; /* total ADCs */ unsigned int cur_rate; /* current rate */ diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 6735090..e596d77 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -223,30 +223,153 @@ static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice) } /* - * MPU401 accessor + * MIDI */ -static unsigned char snd_vt1724_mpu401_read(struct snd_mpu401 *mpu, - unsigned long addr) + +static void vt1724_midi_clear_rx(struct snd_ice1712 *ice) +{ + unsigned int count; + + for (count = inb(ICEREG1724(ice, MPU_RXFIFO)); count > 0; --count) + inb(ICEREG1724(ice, MPU_DATA)); +} + +static inline struct snd_rawmidi_substream * +get_rawmidi_substream(struct snd_ice1712 *ice, unsigned int stream) { - /* fix status bits to the standard position */ - /* only RX_EMPTY and TX_FULL are checked */ - if (addr == MPU401C(mpu)) - return (inb(addr) & 0x0c) << 4; + return list_first_entry(&ice->rmidi[0]->streams[stream].substreams, + struct snd_rawmidi_substream, list); +} + +static void vt1724_midi_write(struct snd_ice1712 *ice) +{ + struct snd_rawmidi_substream *s; + int count, i; + u8 buffer[32]; + + s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_OUTPUT); + count = 31 - inb(ICEREG1724(ice, MPU_TXFIFO)); + if (count > 0) { + count = snd_rawmidi_transmit(s, buffer, count); + for (i = 0; i < count; ++i) + outb(buffer[i], ICEREG1724(ice, MPU_DATA)); + } +} + +static void vt1724_midi_read(struct snd_ice1712 *ice) +{ + struct snd_rawmidi_substream *s; + int count, i; + u8 buffer[32]; + + s = get_rawmidi_substream(ice, SNDRV_RAWMIDI_STREAM_INPUT); + count = inb(ICEREG1724(ice, MPU_RXFIFO)); + if (count > 0) { + count = min(count, 32); + for (i = 0; i < count; ++i) + buffer[i] = inb(ICEREG1724(ice, MPU_DATA)); + snd_rawmidi_receive(s, buffer, count); + } +} + +static void vt1724_enable_midi_irq(struct snd_rawmidi_substream *substream, + u8 flag, int enable) +{ + struct snd_ice1712 *ice = substream->rmidi->private_data; + u8 mask; + + spin_lock_irq(&ice->reg_lock); + mask = inb(ICEREG1724(ice, IRQMASK)); + if (enable) + mask &= ~flag; else - return inb(addr); + mask |= flag; + outb(mask, ICEREG1724(ice, IRQMASK)); + spin_unlock_irq(&ice->reg_lock); } -static void snd_vt1724_mpu401_write(struct snd_mpu401 *mpu, - unsigned char data, unsigned long addr) +static int vt1724_midi_output_open(struct snd_rawmidi_substream *s) { - if (addr == MPU401C(mpu)) { - if (data == MPU401_ENTER_UART) - outb(0x01, addr); - /* what else? */ - } else - outb(data, addr); + vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 1); + return 0; +} + +static int vt1724_midi_output_close(struct snd_rawmidi_substream *s) +{ + vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_TX, 0); + return 0; } +static void vt1724_midi_output_trigger(struct snd_rawmidi_substream *s, int up) +{ + struct snd_ice1712 *ice = s->rmidi->private_data; + unsigned long flags; + + spin_lock_irqsave(&ice->reg_lock, flags); + if (up) { + ice->midi_output = 1; + vt1724_midi_write(ice); + } else { + ice->midi_output = 0; + } + spin_unlock_irqrestore(&ice->reg_lock, flags); +} + +static void vt1724_midi_output_drain(struct snd_rawmidi_substream *s) +{ + struct snd_ice1712 *ice = s->rmidi->private_data; + unsigned long timeout; + + /* 32 bytes should be transmitted in less than about 12 ms */ + timeout = jiffies + msecs_to_jiffies(15); + do { + if (inb(ICEREG1724(ice, MPU_CTRL)) & VT1724_MPU_TX_EMPTY) + break; + schedule_timeout_uninterruptible(1); + } while (time_after(timeout, jiffies)); +} + +static struct snd_rawmidi_ops vt1724_midi_output_ops = { + .open = vt1724_midi_output_open, + .close = vt1724_midi_output_close, + .trigger = vt1724_midi_output_trigger, + .drain = vt1724_midi_output_drain, +}; + +static int vt1724_midi_input_open(struct snd_rawmidi_substream *s) +{ + vt1724_midi_clear_rx(s->rmidi->private_data); + vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 1); + return 0; +} + +static int vt1724_midi_input_close(struct snd_rawmidi_substream *s) +{ + vt1724_enable_midi_irq(s, VT1724_IRQ_MPU_RX, 0); + return 0; +} + +static void vt1724_midi_input_trigger(struct snd_rawmidi_substream *s, int up) +{ + struct snd_ice1712 *ice = s->rmidi->private_data; + unsigned long flags; + + spin_lock_irqsave(&ice->reg_lock, flags); + if (up) { + ice->midi_input = 1; + vt1724_midi_read(ice); + } else { + ice->midi_input = 0; + } + spin_unlock_irqrestore(&ice->reg_lock, flags); +} + +static struct snd_rawmidi_ops vt1724_midi_input_ops = { + .open = vt1724_midi_input_open, + .close = vt1724_midi_input_close, + .trigger = vt1724_midi_input_trigger, +}; + /* * Interrupt handler @@ -278,13 +401,10 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) #endif handled = 1; if (status & VT1724_IRQ_MPU_TX) { - if (ice->rmidi[0]) - snd_mpu401_uart_interrupt_tx(irq, - ice->rmidi[0]->private_data); - else /* disable TX to be sure */ - outb(inb(ICEREG1724(ice, IRQMASK)) | - VT1724_IRQ_MPU_TX, - ICEREG1724(ice, IRQMASK)); + spin_lock(&ice->reg_lock); + if (ice->midi_output) + vt1724_midi_write(ice); + spin_unlock(&ice->reg_lock); /* Due to mysterical reasons, MPU_TX is always * generated (and can't be cleared) when a PCM * playback is going. So let's ignore at the @@ -293,13 +413,12 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) status_mask &= ~VT1724_IRQ_MPU_TX; } if (status & VT1724_IRQ_MPU_RX) { - if (ice->rmidi[0]) - snd_mpu401_uart_interrupt(irq, - ice->rmidi[0]->private_data); - else /* disable RX to be sure */ - outb(inb(ICEREG1724(ice, IRQMASK)) | - VT1724_IRQ_MPU_RX, - ICEREG1724(ice, IRQMASK)); + spin_lock(&ice->reg_lock); + if (ice->midi_input) + vt1724_midi_read(ice); + else + vt1724_midi_clear_rx(ice); + spin_unlock(&ice->reg_lock); } /* ack MPU irq */ outb(status, ICEREG1724(ice, IRQSTAT)); @@ -2425,28 +2544,30 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, if (! c->no_mpu401) { if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { - struct snd_mpu401 *mpu; - if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, - ICEREG1724(ice, MPU_CTRL), - (MPU401_INFO_INTEGRATED | - MPU401_INFO_NO_ACK | - MPU401_INFO_TX_IRQ), - ice->irq, 0, - &ice->rmidi[0])) < 0) { + struct snd_rawmidi *rmidi; + + err = snd_rawmidi_new(card, "MIDI", 0, 1, 1, &rmidi); + if (err < 0) { snd_card_free(card); return err; } - mpu = ice->rmidi[0]->private_data; - mpu->read = snd_vt1724_mpu401_read; - mpu->write = snd_vt1724_mpu401_write; - /* unmask MPU RX/TX irqs */ - outb(inb(ICEREG1724(ice, IRQMASK)) & - ~(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX), - ICEREG1724(ice, IRQMASK)); + ice->rmidi[0] = rmidi; + rmidi->private_data = ice; + strcpy(rmidi->name, "ICE1724 MIDI"); + rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | + SNDRV_RAWMIDI_INFO_INPUT | + SNDRV_RAWMIDI_INFO_DUPLEX; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &vt1724_midi_output_ops); + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &vt1724_midi_input_ops); + /* set watermarks */ outb(VT1724_MPU_RX_FIFO | 0x1, ICEREG1724(ice, MPU_FIFO_WM)); outb(0x1, ICEREG1724(ice, MPU_FIFO_WM)); + /* set UART mode */ + outb(VT1724_MPU_UART, ICEREG1724(ice, MPU_CTRL)); } } -- cgit v0.10.2 From 6536d2891ba2c4e837ba8478dc13bb173ed24a23 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 21 May 2008 10:45:16 -0500 Subject: JFS: skip bad iput() call in error path If jfs_iget() fails, we can't call iput() on the returned error. Thanks to Eric Sesterhenn's fuzzer testing for reporting the problem. Signed-off-by: Dave Kleikamp diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 50ea654..0288e6d 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -499,7 +499,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) inode = jfs_iget(sb, ROOT_I); if (IS_ERR(inode)) { ret = PTR_ERR(inode); - goto out_no_root; + goto out_no_rw; } sb->s_root = d_alloc_root(inode); if (!sb->s_root) @@ -521,9 +521,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) return 0; out_no_root: - jfs_err("jfs_read_super: get root inode failed"); - if (inode) - iput(inode); + jfs_err("jfs_read_super: get root dentry failed"); + iput(inode); out_no_rw: rc = jfs_umount(sb); -- cgit v0.10.2 From 2ba4cc319ab26c56205d4f23724c4748a553c845 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 13 May 2008 15:37:05 +0200 Subject: rcu: fix nf_conntrack_helper.c build bug Signed-off-by: Ingo Molnar diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 7d1b117..8e0b4c8 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From f70c5253b41444fd2779e1f76bfe25811d9b8c23 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:22:36 +0100 Subject: [RTC] remove references to asm/mach/time.h asm/mach/time.h is the ARM header file for setting up kernel ticker timekeeping (be that the old jiffy interrupt or the new clocksource.) RTC drivers have no business using this header file, and in fact do not require it. Build tested on at91sam9rl, omap and s3c2410 configurations. Acked-by: Alessandro Zummo Acked-by: Andrew Victor Signed-off-by: Russell King diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 39e64ab..2af1e6f 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -31,8 +31,6 @@ #include #include -#include - #include diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 38d8742..f0246ef 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 58f81c7..eb23d84 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -22,7 +22,6 @@ #include #include -#include /* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index f26e0ca..2c6e467 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -28,8 +28,6 @@ #include #include -#include - #include /* I have yet to find an S3C implementation with more than one -- cgit v0.10.2 From 2dba8518b7761aee3ba757b298efa15dd34eff18 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:08:04 +0100 Subject: [RTC] rtc-pl031: use proper resources, use proper apis, clean up includes Clean up PL031 RTC includes, make driver use proper resource checking, and use amba bus specific accessors. Acked-by: Alessandro Zummo Signed-off-by: Russell King diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 2fd49ed..08b4610 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -12,23 +12,12 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#include #include #include #include -#include #include -#include -#include -#include - #include - -#include -#include -#include -#include +#include /* * Register definitions @@ -142,13 +131,12 @@ static int pl031_remove(struct amba_device *adev) { struct pl031_local *ldata = dev_get_drvdata(&adev->dev); - if (ldata) { - dev_set_drvdata(&adev->dev, NULL); - free_irq(adev->irq[0], ldata->rtc); - rtc_device_unregister(ldata->rtc); - iounmap(ldata->base); - kfree(ldata); - } + amba_set_drvdata(adev, NULL); + free_irq(adev->irq[0], ldata->rtc); + rtc_device_unregister(ldata->rtc); + iounmap(ldata->base); + kfree(ldata); + amba_release_regions(adev); return 0; } @@ -158,13 +146,15 @@ static int pl031_probe(struct amba_device *adev, void *id) int ret; struct pl031_local *ldata; + ret = amba_request_regions(adev, NULL); + if (ret) + goto err_req; ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL); if (!ldata) { ret = -ENOMEM; goto out; } - dev_set_drvdata(&adev->dev, ldata); ldata->base = ioremap(adev->res.start, adev->res.end - adev->res.start + 1); @@ -173,6 +163,8 @@ static int pl031_probe(struct amba_device *adev, void *id) goto out_no_remap; } + amba_set_drvdata(adev, ldata); + if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED, "rtc-pl031", ldata->rtc)) { ret = -EIO; @@ -192,10 +184,12 @@ out_no_rtc: free_irq(adev->irq[0], ldata->rtc); out_no_irq: iounmap(ldata->base); + amba_set_drvdata(adev, NULL); out_no_remap: - dev_set_drvdata(&adev->dev, NULL); kfree(ldata); out: + amba_release_regions(adev); +err_req: return ret; } -- cgit v0.10.2 From a190901c6b5f1f4a31681e8c69d811a4f9426e2b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:08:36 +0100 Subject: [RTC] rtc-pl030: add driver, remove old non-rtc lib driver Convert Integrator PL030 RTC driver to use the RTC class interfaces. Acked-by: Alessandro Zummo Signed-off-by: Russell King diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index 158daaf..6a5ef8d 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := clock.o core.o lm.o time.o +obj-y := clock.o core.o lm.o obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c deleted file mode 100644 index 8508a0d..0000000 --- a/arch/arm/mach-integrator/time.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * linux/arch/arm/mach-integrator/time.c - * - * Copyright (C) 2000-2001 Deep Blue Solutions 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define RTC_DR (0) -#define RTC_MR (4) -#define RTC_STAT (8) -#define RTC_EOI (8) -#define RTC_LR (12) -#define RTC_CR (16) -#define RTC_CR_MIE (1 << 0) - -extern int (*set_rtc)(void); -static void __iomem *rtc_base; - -static int integrator_set_rtc(void) -{ - __raw_writel(xtime.tv_sec, rtc_base + RTC_LR); - return 1; -} - -static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm) -{ - rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); - return 0; -} - -static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm) -{ - unsigned long time; - int ret; - - /* - * At the moment, we can only deal with non-wildcarded alarm times. - */ - ret = rtc_valid_tm(&alrm->time); - if (ret == 0) - ret = rtc_tm_to_time(&alrm->time, &time); - if (ret == 0) - writel(time, rtc_base + RTC_MR); - return ret; -} - -static int integrator_rtc_read_time(struct rtc_time *tm) -{ - rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); - return 0; -} - -/* - * Set the RTC time. Unfortunately, we can't accurately set - * the point at which the counter updates. - * - * Also, since RTC_LR is transferred to RTC_CR on next rising - * edge of the 1Hz clock, we must write the time one second - * in advance. - */ -static inline int integrator_rtc_set_time(struct rtc_time *tm) -{ - unsigned long time; - int ret; - - ret = rtc_tm_to_time(tm, &time); - if (ret == 0) - writel(time + 1, rtc_base + RTC_LR); - - return ret; -} - -static struct rtc_ops rtc_ops = { - .owner = THIS_MODULE, - .read_time = integrator_rtc_read_time, - .set_time = integrator_rtc_set_time, - .read_alarm = integrator_rtc_read_alarm, - .set_alarm = integrator_rtc_set_alarm, -}; - -static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id) -{ - writel(0, rtc_base + RTC_EOI); - return IRQ_HANDLED; -} - -static int rtc_probe(struct amba_device *dev, void *id) -{ - int ret; - - if (rtc_base) - return -EBUSY; - - ret = amba_request_regions(dev, NULL); - if (ret) - goto out; - - rtc_base = ioremap(dev->res.start, SZ_4K); - if (!rtc_base) { - ret = -ENOMEM; - goto res_out; - } - - __raw_writel(0, rtc_base + RTC_CR); - __raw_writel(0, rtc_base + RTC_EOI); - - xtime.tv_sec = __raw_readl(rtc_base + RTC_DR); - - /* note that 'dev' is merely used for irq disambiguation; - * it is not actually referenced in the irq handler - */ - ret = request_irq(dev->irq[0], arm_rtc_interrupt, IRQF_DISABLED, - "rtc-pl030", dev); - if (ret) - goto map_out; - - ret = register_rtc(&rtc_ops); - if (ret) - goto irq_out; - - set_rtc = integrator_set_rtc; - return 0; - - irq_out: - free_irq(dev->irq[0], dev); - map_out: - iounmap(rtc_base); - rtc_base = NULL; - res_out: - amba_release_regions(dev); - out: - return ret; -} - -static int rtc_remove(struct amba_device *dev) -{ - set_rtc = NULL; - - writel(0, rtc_base + RTC_CR); - - free_irq(dev->irq[0], dev); - unregister_rtc(&rtc_ops); - - iounmap(rtc_base); - rtc_base = NULL; - amba_release_regions(dev); - - return 0; -} - -static struct timespec rtc_delta; - -static int rtc_suspend(struct amba_device *dev, pm_message_t state) -{ - struct timespec rtc; - - rtc.tv_sec = readl(rtc_base + RTC_DR); - rtc.tv_nsec = 0; - save_time_delta(&rtc_delta, &rtc); - - return 0; -} - -static int rtc_resume(struct amba_device *dev) -{ - struct timespec rtc; - - rtc.tv_sec = readl(rtc_base + RTC_DR); - rtc.tv_nsec = 0; - restore_time_delta(&rtc_delta, &rtc); - - return 0; -} - -static struct amba_id rtc_ids[] = { - { - .id = 0x00041030, - .mask = 0x000fffff, - }, - { 0, 0 }, -}; - -static struct amba_driver rtc_driver = { - .drv = { - .name = "rtc-pl030", - }, - .probe = rtc_probe, - .remove = rtc_remove, - .suspend = rtc_suspend, - .resume = rtc_resume, - .id_table = rtc_ids, -}; - -static int __init integrator_rtc_init(void) -{ - return amba_driver_register(&rtc_driver); -} - -static void __exit integrator_rtc_exit(void) -{ - amba_driver_unregister(&rtc_driver); -} - -module_init(integrator_rtc_init); -module_exit(integrator_rtc_exit); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6cc2c03..1b26eeb 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -458,6 +458,16 @@ config RTC_DRV_VR41XX To compile this driver as a module, choose M here: the module will be called rtc-vr41xx. +config RTC_DRV_PL030 + tristate "ARM AMBA PL030 RTC" + depends on ARM_AMBA + help + If you say Y here you will get access to ARM AMBA + PrimeCell PL030 RTC found on certain ARM SOCs. + + To compile this driver as a module, choose M here: the + module will be called rtc-pl030. + config RTC_DRV_PL031 tristate "ARM AMBA PL031 RTC" depends on ARM_AMBA diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 872f1218f..af3ee66 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o +obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c new file mode 100644 index 0000000..8448eeb --- /dev/null +++ b/drivers/rtc/rtc-pl030.c @@ -0,0 +1,217 @@ +/* + * linux/drivers/rtc/rtc-pl030.c + * + * Copyright (C) 2000-2001 Deep Blue Solutions 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 +#include +#include +#include +#include +#include + +#define RTC_DR (0) +#define RTC_MR (4) +#define RTC_STAT (8) +#define RTC_EOI (8) +#define RTC_LR (12) +#define RTC_CR (16) +#define RTC_CR_MIE (1 << 0) + +struct pl030_rtc { + struct rtc_device *rtc; + void __iomem *base; +}; + +static irqreturn_t pl030_interrupt(int irq, void *dev_id) +{ + struct pl030_rtc *rtc = dev_id; + writel(0, rtc->base + RTC_EOI); + return IRQ_HANDLED; +} + +static int pl030_open(struct device *dev) +{ + return 0; +} + +static void pl030_release(struct device *dev) +{ +} + +static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + +static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pl030_rtc *rtc = dev_get_drvdata(dev); + + rtc_time_to_tm(readl(rtc->base + RTC_MR), &alrm->time); + return 0; +} + +static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pl030_rtc *rtc = dev_get_drvdata(dev); + unsigned long time; + int ret; + + /* + * At the moment, we can only deal with non-wildcarded alarm times. + */ + ret = rtc_valid_tm(&alrm->time); + if (ret == 0) + ret = rtc_tm_to_time(&alrm->time, &time); + if (ret == 0) + writel(time, rtc->base + RTC_MR); + return ret; +} + +static int pl030_read_time(struct device *dev, struct rtc_time *tm) +{ + struct pl030_rtc *rtc = dev_get_drvdata(dev); + + rtc_time_to_tm(readl(rtc->base + RTC_DR), tm); + + return 0; +} + +/* + * Set the RTC time. Unfortunately, we can't accurately set + * the point at which the counter updates. + * + * Also, since RTC_LR is transferred to RTC_CR on next rising + * edge of the 1Hz clock, we must write the time one second + * in advance. + */ +static int pl030_set_time(struct device *dev, struct rtc_time *tm) +{ + struct pl030_rtc *rtc = dev_get_drvdata(dev); + unsigned long time; + int ret; + + ret = rtc_tm_to_time(tm, &time); + if (ret == 0) + writel(time + 1, rtc->base + RTC_LR); + + return ret; +} + +static const struct rtc_class_ops pl030_ops = { + .open = pl030_open, + .release = pl030_release, + .ioctl = pl030_ioctl, + .read_time = pl030_read_time, + .set_time = pl030_set_time, + .read_alarm = pl030_read_alarm, + .set_alarm = pl030_set_alarm, +}; + +static int pl030_probe(struct amba_device *dev, void *id) +{ + struct pl030_rtc *rtc; + int ret; + + ret = amba_request_regions(dev, NULL); + if (ret) + goto err_req; + + rtc = kmalloc(sizeof(*rtc), GFP_KERNEL); + if (!rtc) { + ret = -ENOMEM; + goto err_rtc; + } + + rtc->base = ioremap(dev->res.start, SZ_4K); + if (!rtc->base) { + ret = -ENOMEM; + goto err_map; + } + + __raw_writel(0, rtc->base + RTC_CR); + __raw_writel(0, rtc->base + RTC_EOI); + + amba_set_drvdata(dev, rtc); + + ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED, + "rtc-pl030", rtc); + if (ret) + goto err_irq; + + rtc->rtc = rtc_device_register("pl030", &dev->dev, &pl030_ops, + THIS_MODULE); + if (IS_ERR(rtc->rtc)) { + ret = PTR_ERR(rtc->rtc); + goto err_reg; + } + + return 0; + + err_reg: + free_irq(dev->irq[0], rtc); + err_irq: + iounmap(rtc->base); + err_map: + kfree(rtc); + err_rtc: + amba_release_regions(dev); + err_req: + return ret; +} + +static int pl030_remove(struct amba_device *dev) +{ + struct pl030_rtc *rtc = amba_get_drvdata(dev); + + amba_set_drvdata(dev, NULL); + + writel(0, rtc->base + RTC_CR); + + free_irq(dev->irq[0], rtc); + rtc_device_unregister(rtc->rtc); + iounmap(rtc->base); + kfree(rtc); + amba_release_regions(dev); + + return 0; +} + +static struct amba_id pl030_ids[] = { + { + .id = 0x00041030, + .mask = 0x000fffff, + }, + { 0, 0 }, +}; + +static struct amba_driver pl030_driver = { + .drv = { + .name = "rtc-pl030", + }, + .probe = pl030_probe, + .remove = pl030_remove, + .id_table = pl030_ids, +}; + +static int __init pl030_init(void) +{ + return amba_driver_register(&pl030_driver); +} + +static void __exit pl030_exit(void) +{ + amba_driver_unregister(&pl030_driver); +} + +module_init(pl030_init); +module_exit(pl030_exit); + +MODULE_AUTHOR("Russell King "); +MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 7da285b626860eb6d35e08ae33eba90f0e83ad58 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:26:48 +0100 Subject: [RTC] remove unused asm/rtc.h includes from ARM RTC drivers On ARM, asm/rtc.h only contains definitions for the predecessor to the RTC class support. RTC class drivers should not be including this include. Build tested on at91sam9rl and s3c2410 configurations. Acked-by: Alessandro Zummo Signed-off-by: Russell King diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 2af1e6f..9c3db93 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -29,8 +29,6 @@ #include #include -#include - #include diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 2c6e467..fed86e5 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -26,8 +26,6 @@ #include #include #include -#include - #include /* I have yet to find an S3C implementation with more than one -- cgit v0.10.2 From 797276ec9e4d2ee210e11068a2ce815394fe8c58 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:30:41 +0100 Subject: [RTC] rtc-sa1100: remove dependence on asm/rtc.h Move the two functions rtc-sa1100 wants from the old ARM RTC library into the rtc-sa1100 driver. Acked-by: Alessandro Zummo Signed-off-by: Russell King diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 82f62d2..e31a687 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -33,7 +33,6 @@ #include #include -#include #ifdef CONFIG_ARCH_PXA #include @@ -47,6 +46,42 @@ static unsigned long rtc_freq = 1024; static struct rtc_time rtc_alarm; static DEFINE_SPINLOCK(sa1100_rtc_lock); +static inline int rtc_periodic_alarm(struct rtc_time *tm) +{ + return (tm->tm_year == -1) || + ((unsigned)tm->tm_mon >= 12) || + ((unsigned)(tm->tm_mday - 1) >= 31) || + ((unsigned)tm->tm_hour > 23) || + ((unsigned)tm->tm_min > 59) || + ((unsigned)tm->tm_sec > 59); +} + +/* + * Calculate the next alarm time given the requested alarm time mask + * and the current time. + */ +static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) +{ + unsigned long next_time; + unsigned long now_time; + + next->tm_year = now->tm_year; + next->tm_mon = now->tm_mon; + next->tm_mday = now->tm_mday; + next->tm_hour = alrm->tm_hour; + next->tm_min = alrm->tm_min; + next->tm_sec = alrm->tm_sec; + + rtc_tm_to_time(now, &now_time); + rtc_tm_to_time(next, &next_time); + + if (next_time < now_time) { + /* Advance one day */ + next_time += 60 * 60 * 24; + rtc_time_to_tm(next_time, next); + } +} + static int rtc_update_alarm(struct rtc_time *alrm) { struct rtc_time alarm_tm, now_tm; -- cgit v0.10.2 From bedd78ca786c1d18c2a2785c7e40593dc9c9870f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:31:29 +0100 Subject: [RTC] remove old ARM rtc library code Now that all drivers using it are gone, remove the old ARM RTC library. Acked-by: Alessandro Zummo Signed-off-by: Russell King diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 3d0b9fa..325e4b6 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -2,7 +2,6 @@ # Makefile for the linux kernel. # -obj-y += rtctime.o obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ARM_VIC) += vic.o obj-$(CONFIG_ICST525) += icst525.o diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c deleted file mode 100644 index aa8f773..0000000 --- a/arch/arm/common/rtctime.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * linux/arch/arm/common/rtctime.c - * - * Copyright (C) 2003 Deep Blue Solutions Ltd. - * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre. - * Based on rtc.c by Paul Gortmaker - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); -static struct fasync_struct *rtc_async_queue; - -/* - * rtc_lock protects rtc_irq_data - */ -static DEFINE_SPINLOCK(rtc_lock); -static unsigned long rtc_irq_data; - -/* - * rtc_sem protects rtc_inuse and rtc_ops - */ -static DEFINE_MUTEX(rtc_mutex); -static unsigned long rtc_inuse; -static struct rtc_ops *rtc_ops; - -#define rtc_epoch 1900UL - -/* - * Calculate the next alarm time given the requested alarm time mask - * and the current time. - */ -void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) -{ - unsigned long next_time; - unsigned long now_time; - - next->tm_year = now->tm_year; - next->tm_mon = now->tm_mon; - next->tm_mday = now->tm_mday; - next->tm_hour = alrm->tm_hour; - next->tm_min = alrm->tm_min; - next->tm_sec = alrm->tm_sec; - - rtc_tm_to_time(now, &now_time); - rtc_tm_to_time(next, &next_time); - - if (next_time < now_time) { - /* Advance one day */ - next_time += 60 * 60 * 24; - rtc_time_to_tm(next_time, next); - } -} -EXPORT_SYMBOL(rtc_next_alarm_time); - -static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) -{ - memset(tm, 0, sizeof(struct rtc_time)); - return ops->read_time(tm); -} - -static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) -{ - int ret; - - ret = rtc_valid_tm(tm); - if (ret == 0) - ret = ops->set_time(tm); - - return ret; -} - -static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -{ - int ret = -EINVAL; - if (ops->read_alarm) { - memset(alrm, 0, sizeof(struct rtc_wkalrm)); - ret = ops->read_alarm(alrm); - } - return ret; -} - -static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -{ - int ret = -EINVAL; - if (ops->set_alarm) - ret = ops->set_alarm(alrm); - return ret; -} - -void rtc_update(unsigned long num, unsigned long events) -{ - spin_lock(&rtc_lock); - rtc_irq_data = (rtc_irq_data + (num << 8)) | events; - spin_unlock(&rtc_lock); - - wake_up_interruptible(&rtc_wait); - kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); -} -EXPORT_SYMBOL(rtc_update); - - -static ssize_t -rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - DECLARE_WAITQUEUE(wait, current); - unsigned long data; - ssize_t ret; - - if (count < sizeof(unsigned long)) - return -EINVAL; - - add_wait_queue(&rtc_wait, &wait); - do { - __set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irq(&rtc_lock); - data = rtc_irq_data; - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - if (data != 0) { - ret = 0; - break; - } - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - schedule(); - } while (1); - set_current_state(TASK_RUNNING); - remove_wait_queue(&rtc_wait, &wait); - - if (ret == 0) { - ret = put_user(data, (unsigned long __user *)buf); - if (ret == 0) - ret = sizeof(unsigned long); - } - return ret; -} - -static unsigned int rtc_poll(struct file *file, poll_table *wait) -{ - unsigned long data; - - poll_wait(file, &rtc_wait, wait); - - spin_lock_irq(&rtc_lock); - data = rtc_irq_data; - spin_unlock_irq(&rtc_lock); - - return data != 0 ? POLLIN | POLLRDNORM : 0; -} - -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct rtc_ops *ops = file->private_data; - struct rtc_time tm; - struct rtc_wkalrm alrm; - void __user *uarg = (void __user *)arg; - int ret = -EINVAL; - - switch (cmd) { - case RTC_ALM_READ: - ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); - if (ret) - ret = -EFAULT; - break; - - case RTC_ALM_SET: - ret = copy_from_user(&alrm.time, uarg, sizeof(tm)); - if (ret) { - ret = -EFAULT; - break; - } - alrm.enabled = 0; - alrm.pending = 0; - alrm.time.tm_mday = -1; - alrm.time.tm_mon = -1; - alrm.time.tm_year = -1; - alrm.time.tm_wday = -1; - alrm.time.tm_yday = -1; - alrm.time.tm_isdst = -1; - ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_RD_TIME: - ret = rtc_arm_read_time(ops, &tm); - if (ret) - break; - ret = copy_to_user(uarg, &tm, sizeof(tm)); - if (ret) - ret = -EFAULT; - break; - - case RTC_SET_TIME: - if (!capable(CAP_SYS_TIME)) { - ret = -EACCES; - break; - } - ret = copy_from_user(&tm, uarg, sizeof(tm)); - if (ret) { - ret = -EFAULT; - break; - } - ret = rtc_arm_set_time(ops, &tm); - break; - - case RTC_EPOCH_SET: -#ifndef rtc_epoch - /* - * There were no RTC clocks before 1900. - */ - if (arg < 1900) { - ret = -EINVAL; - break; - } - if (!capable(CAP_SYS_TIME)) { - ret = -EACCES; - break; - } - rtc_epoch = arg; - ret = 0; -#endif - break; - - case RTC_EPOCH_READ: - ret = put_user(rtc_epoch, (unsigned long __user *)uarg); - break; - - case RTC_WKALM_SET: - ret = copy_from_user(&alrm, uarg, sizeof(alrm)); - if (ret) { - ret = -EFAULT; - break; - } - ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_WKALM_RD: - ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm, sizeof(alrm)); - if (ret) - ret = -EFAULT; - break; - - default: - if (ops->ioctl) - ret = ops->ioctl(cmd, arg); - break; - } - return ret; -} - -static int rtc_open(struct inode *inode, struct file *file) -{ - int ret; - - mutex_lock(&rtc_mutex); - - if (rtc_inuse) { - ret = -EBUSY; - } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) { - ret = -ENODEV; - } else { - file->private_data = rtc_ops; - - ret = rtc_ops->open ? rtc_ops->open() : 0; - if (ret == 0) { - spin_lock_irq(&rtc_lock); - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - rtc_inuse = 1; - } - } - mutex_unlock(&rtc_mutex); - - return ret; -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - struct rtc_ops *ops = file->private_data; - - if (ops->release) - ops->release(); - - spin_lock_irq(&rtc_lock); - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - module_put(rtc_ops->owner); - rtc_inuse = 0; - - return 0; -} - -static int rtc_fasync(int fd, struct file *file, int on) -{ - return fasync_helper(fd, file, on, &rtc_async_queue); -} - -static const struct file_operations rtc_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = rtc_read, - .poll = rtc_poll, - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, - .fasync = rtc_fasync, -}; - -static struct miscdevice rtc_miscdev = { - .minor = RTC_MINOR, - .name = "rtc", - .fops = &rtc_fops, -}; - - -static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - struct rtc_ops *ops = data; - struct rtc_wkalrm alrm; - struct rtc_time tm; - char *p = page; - - if (rtc_arm_read_time(ops, &tm) == 0) { - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" - "rtc_epoch\t: %04lu\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - rtc_epoch); - } - - if (rtc_arm_read_alarm(ops, &alrm) == 0) { - p += sprintf(p, "alrm_time\t: "); - if ((unsigned int)alrm.time.tm_hour <= 24) - p += sprintf(p, "%02d:", alrm.time.tm_hour); - else - p += sprintf(p, "**:"); - if ((unsigned int)alrm.time.tm_min <= 59) - p += sprintf(p, "%02d:", alrm.time.tm_min); - else - p += sprintf(p, "**:"); - if ((unsigned int)alrm.time.tm_sec <= 59) - p += sprintf(p, "%02d\n", alrm.time.tm_sec); - else - p += sprintf(p, "**\n"); - - p += sprintf(p, "alrm_date\t: "); - if ((unsigned int)alrm.time.tm_year <= 200) - p += sprintf(p, "%04d-", alrm.time.tm_year + 1900); - else - p += sprintf(p, "****-"); - if ((unsigned int)alrm.time.tm_mon <= 11) - p += sprintf(p, "%02d-", alrm.time.tm_mon + 1); - else - p += sprintf(p, "**-"); - if ((unsigned int)alrm.time.tm_mday <= 31) - p += sprintf(p, "%02d\n", alrm.time.tm_mday); - else - p += sprintf(p, "**\n"); - p += sprintf(p, "alrm_wakeup\t: %s\n", - alrm.enabled ? "yes" : "no"); - p += sprintf(p, "alrm_pending\t: %s\n", - alrm.pending ? "yes" : "no"); - } - - if (ops->proc) - p += ops->proc(p); - - return p - page; -} - -int register_rtc(struct rtc_ops *ops) -{ - int ret = -EBUSY; - - mutex_lock(&rtc_mutex); - if (rtc_ops == NULL) { - rtc_ops = ops; - - ret = misc_register(&rtc_miscdev); - if (ret == 0) - create_proc_read_entry("driver/rtc", 0, NULL, - rtc_read_proc, ops); - } - mutex_unlock(&rtc_mutex); - - return ret; -} -EXPORT_SYMBOL(register_rtc); - -void unregister_rtc(struct rtc_ops *rtc) -{ - mutex_lock(&rtc_mutex); - if (rtc == rtc_ops) { - remove_proc_entry("driver/rtc", NULL); - misc_deregister(&rtc_miscdev); - rtc_ops = NULL; - } - mutex_unlock(&rtc_mutex); -} -EXPORT_SYMBOL(unregister_rtc); diff --git a/include/asm-arm/rtc.h b/include/asm-arm/rtc.h deleted file mode 100644 index 1a5c923..0000000 --- a/include/asm-arm/rtc.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/include/asm-arm/rtc.h - * - * Copyright (C) 2003 Deep Blue Solutions 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. - */ -#ifndef ASMARM_RTC_H -#define ASMARM_RTC_H - -struct module; - -struct rtc_ops { - struct module *owner; - int (*open)(void); - void (*release)(void); - int (*ioctl)(unsigned int, unsigned long); - - int (*read_time)(struct rtc_time *); - int (*set_time)(struct rtc_time *); - int (*read_alarm)(struct rtc_wkalrm *); - int (*set_alarm)(struct rtc_wkalrm *); - int (*proc)(char *buf); -}; - -void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); -void rtc_update(unsigned long, unsigned long); -int register_rtc(struct rtc_ops *); -void unregister_rtc(struct rtc_ops *); - -static inline int rtc_periodic_alarm(struct rtc_time *tm) -{ - return (tm->tm_year == -1) || - ((unsigned)tm->tm_mon >= 12) || - ((unsigned)(tm->tm_mday - 1) >= 31) || - ((unsigned)tm->tm_hour > 23) || - ((unsigned)tm->tm_min > 59) || - ((unsigned)tm->tm_sec > 59); -} - -#endif -- cgit v0.10.2 From 21451155d8858773ee764e9218de2ca0f4d6fc38 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Apr 2008 00:05:24 +1000 Subject: [POWERPC] of/gpio: Use dynamic base allocation Since the "gpiolib: dynamic gpio number allocation" patch was recently merged into Linus' tree (commit 8d0aab2f16c4fa170f32e7a74a52cd0122bbafef), we can use dynamic GPIO base allocation now. This, in turn, removes number of gpios per chip constraint. Signed-off-by: Anton Vorontsov Signed-off-by: Paul Mackerras diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 000681e..1c9cab8 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -137,38 +137,6 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, } EXPORT_SYMBOL(of_gpio_simple_xlate); -/* Should be sufficient for now, later we'll use dynamic bases. */ -#if defined(CONFIG_PPC32) || defined(CONFIG_SPARC32) -#define GPIOS_PER_CHIP 32 -#else -#define GPIOS_PER_CHIP 64 -#endif - -static int of_get_gpiochip_base(struct device_node *np) -{ - struct device_node *gc = NULL; - int gpiochip_base = 0; - - while ((gc = of_find_all_nodes(gc))) { - if (!of_get_property(gc, "gpio-controller", NULL)) - continue; - - if (gc != np) { - gpiochip_base += GPIOS_PER_CHIP; - continue; - } - - of_node_put(gc); - - if (gpiochip_base >= ARCH_NR_GPIOS) - return -ENOSPC; - - return gpiochip_base; - } - - return -ENOENT; -} - /** * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) * @np: device node of the GPIO chip @@ -205,11 +173,7 @@ int of_mm_gpiochip_add(struct device_node *np, if (!mm_gc->regs) goto err1; - gc->base = of_get_gpiochip_base(np); - if (gc->base < 0) { - ret = gc->base; - goto err1; - } + gc->base = -1; if (!of_gc->xlate) of_gc->xlate = of_gpio_simple_xlate; -- cgit v0.10.2 From 2ca7633dc73405ee775a2e9b7961b47a38bc882d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 11 May 2008 10:40:47 +1000 Subject: [POWERPC] Tweak VDSO linker script to avoid upsetting old binutils This works around bugs in older binutils' objcopy. The placement of these sections does not really matter, but it confused the buggy old BFD libraries. Signed-off-by: Roland McGrath Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 932b3fd..7d6585f 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -43,15 +43,15 @@ SECTIONS .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } + .dynamic : { *(.dynamic) } :text :dynamic + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr .eh_frame : { KEEP (*(.eh_frame)) } :text .gcc_except_table : { *(.gcc_except_table) } + .rela.dyn ALIGN(8) : { *(.rela.dyn) } .opd ALIGN(8) : { KEEP (*(.opd)) } .got ALIGN(8) : { *(.got .toc) } - .rela.dyn ALIGN(8) : { *(.rela.dyn) } - - .dynamic : { *(.dynamic) } :text :dynamic _end = .; PROVIDE(end = .); diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 2dbd4e7..ef96bfd 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h @@ -356,6 +356,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define toreal(rd) #define fromreal(rd) +/* + * We use addis to ensure compatibility with the "classic" ppc versions of + * these macros, which use rs = 0 to get the tophys offset in rd, rather than + * converting the address in r0, and so this version has to do that too + * (i.e. set register rd to 0 when rs == 0). + */ #define tophys(rd,rs) \ addis rd,rs,0 -- cgit v0.10.2 From 475ca391b490a683d66bf19999a8a7a24913f139 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 22 May 2008 06:59:23 +1000 Subject: [POWERPC] mpic: Deal with bogus NIRQ in Feature Reporting Register Some chips (like the SoCs from Freescale) report the wrong value in NIRQ and this causes issues if its doesn't match or exceed the value of irq_count. Add a flag that board code can set to just use irq_count instead of FRR[NIRQ]. Eventually we'll add a device tree property with the number of sources. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 8619f2a..466e218 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1144,9 +1144,12 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; if (isu_size == 0) - mpic->num_sources = - ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) - >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; + if (flags & MPIC_BROKEN_FRR_NIRQS) + mpic->num_sources = mpic->irq_count; + else + mpic->num_sources = + ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) + >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index 943c5a3..6802570 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h @@ -353,6 +353,8 @@ struct mpic #define MPIC_ENABLE_MCK 0x00000200 /* Disable bias among target selection, spread interrupts evenly */ #define MPIC_NO_BIAS 0x00000400 +/* Ignore NIRQS as reported by FRR */ +#define MPIC_BROKEN_FRR_NIRQS 0x00000800 /* MPIC HW modification ID */ #define MPIC_REGSET_MASK 0xf0000000 -- cgit v0.10.2 From 72cac213fda6a2dd402e91692b70e175795eab7d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 May 2008 14:21:30 +1000 Subject: [POWERPC] Add debugging trigger to Axon MSI code This adds some debugging code to the Axon MSI driver. It creates a file per MSIC in /sys/kernel/debug/powerpc, which allows the user to trigger a fake MSI interrupt by writing to the file. This can be used to test some of the MSI generation path. In particular, that the MSIC recognises a write to the MSI address, generates an interrupt and writes the MSI packet into the ring buffer. All the code is inside #ifdef DEBUG so it causes no harm unless it's enabled. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index c39f5c2..8b055bc 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -69,8 +70,19 @@ struct axon_msic { dma_addr_t fifo_phys; dcr_host_t dcr_host; u32 read_offset; +#ifdef DEBUG + u32 __iomem *trigger; +#endif }; +#ifdef DEBUG +void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic); +#else +static inline void axon_msi_debug_setup(struct device_node *dn, + struct axon_msic *msic) { } +#endif + + static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) { pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); @@ -381,6 +393,8 @@ static int axon_msi_probe(struct of_device *device, ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; ppc_md.msi_check_device = axon_msi_check_device; + axon_msi_debug_setup(dn, msic); + printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); return 0; @@ -418,3 +432,47 @@ static int __init axon_msi_init(void) return of_register_platform_driver(&axon_msi_driver); } subsys_initcall(axon_msi_init); + + +#ifdef DEBUG +static int msic_set(void *data, u64 val) +{ + struct axon_msic *msic = data; + out_le32(msic->trigger, val); + return 0; +} + +static int msic_get(void *data, u64 *val) +{ + *val = 0; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_msic, msic_get, msic_set, "%llu\n"); + +void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic) +{ + char name[8]; + u64 addr; + + addr = of_translate_address(dn, of_get_property(dn, "reg", NULL)); + if (addr == OF_BAD_ADDR) { + pr_debug("axon_msi: couldn't translate reg property\n"); + return; + } + + msic->trigger = ioremap(addr, 0x4); + if (!msic->trigger) { + pr_debug("axon_msi: ioremap failed\n"); + return; + } + + snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn)); + + if (!debugfs_create_file(name, 0600, powerpc_debugfs_root, + msic, &fops_msic)) { + pr_debug("axon_msi: debugfs_create_file failed!\n"); + return; + } +} +#endif /* DEBUG */ -- cgit v0.10.2 From 80d267f9aee6f1b5df602b5a19fb7b4923f17db2 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 23 May 2008 14:22:21 +1000 Subject: [POWERPC] Remove unnecessary cast in arch_deref_entry_point() func_descr_t->entry is already an unsigned long. Mea culpa. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index c176c51..23545a2 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -498,7 +498,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, #ifdef CONFIG_PPC64 unsigned long arch_deref_entry_point(void *entry) { - return (unsigned long)(((func_descr_t *)entry)->entry); + return ((func_descr_t *)entry)->entry; } #endif -- cgit v0.10.2 From bd3bff9e20f454b242d979ec2f9a4dca0d5fa06f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:41 +0200 Subject: sched: add latency tracer callbacks to the scheduler add 3 lightweight callbacks to the tracer backend. zero impact if tracing is turned off. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 5395a61..717cab8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2117,6 +2117,32 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) } #endif +#ifdef CONFIG_CONTEXT_SWITCH_TRACER +extern void +ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next); +#else +static inline void +ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) +{ +} +#endif + +#ifdef CONFIG_SCHED_TRACER +extern void +ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr); +extern void +ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr); +#else +static inline void +ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) +{ +} +static inline void +ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr) +{ +} +#endif + extern long sched_setaffinity(pid_t pid, const cpumask_t *new_mask); extern long sched_getaffinity(pid_t pid, cpumask_t *mask); diff --git a/kernel/sched.c b/kernel/sched.c index cfa222a..463dcdb 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2467,6 +2467,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) out_activate: #endif /* CONFIG_SMP */ + ftrace_wake_up_task(p, rq->curr); schedstat_inc(p, se.nr_wakeups); if (sync) schedstat_inc(p, se.nr_wakeups_sync); @@ -2611,6 +2612,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) p->sched_class->task_new(rq, p); inc_nr_running(rq); } + ftrace_wake_up_new_task(p, rq->curr); check_preempt_curr(rq, p); #ifdef CONFIG_SMP if (p->sched_class->task_wake_up) @@ -2783,6 +2785,7 @@ context_switch(struct rq *rq, struct task_struct *prev, struct mm_struct *mm, *oldmm; prepare_task_switch(rq, prev, next); + ftrace_ctx_switch(prev, next); mm = next->mm; oldmm = prev->active_mm; /* -- cgit v0.10.2 From 7c731e0a495e25e79dc1e9e68772a67a55721a65 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:41 +0200 Subject: ftrace: make the task state char-string visible to all The tracer wants to be able to convert the state number into a user visible character. This patch pulls that conversion string out the scheduler into the header. This way if it were to ever change, other parts of the kernel will know. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 717cab8..6e26f1f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2237,6 +2237,8 @@ static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p) } #endif /* CONFIG_MM_OWNER */ +#define TASK_STATE_TO_CHAR_STR "RSDTtZX" + #endif /* __KERNEL__ */ #endif diff --git a/kernel/sched.c b/kernel/sched.c index 463dcdb..73e6008 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5729,7 +5729,7 @@ out_unlock: return retval; } -static const char stat_nam[] = "RSDTtZX"; +static const char stat_nam[] = TASK_STATE_TO_CHAR_STR; void sched_show_task(struct task_struct *p) { -- cgit v0.10.2 From 502825282e6f79c975a644afc124432ec1744de4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:41 +0200 Subject: ftrace: add preempt_enable/disable notrace macros The tracer may need to call preempt_enable and disable functions for time keeping and such. The trace gets ugly when we see these functions show up for all traces. To make the output cleaner this patch adds preempt_enable_notrace and preempt_disable_notrace to be used by tracer (and debugging) functions. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 23f0c54..36b03d5 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -52,6 +52,34 @@ do { \ preempt_check_resched(); \ } while (0) +/* For debugging and tracer internals only! */ +#define add_preempt_count_notrace(val) \ + do { preempt_count() += (val); } while (0) +#define sub_preempt_count_notrace(val) \ + do { preempt_count() -= (val); } while (0) +#define inc_preempt_count_notrace() add_preempt_count_notrace(1) +#define dec_preempt_count_notrace() sub_preempt_count_notrace(1) + +#define preempt_disable_notrace() \ +do { \ + inc_preempt_count_notrace(); \ + barrier(); \ +} while (0) + +#define preempt_enable_no_resched_notrace() \ +do { \ + barrier(); \ + dec_preempt_count_notrace(); \ +} while (0) + +/* preempt_check_resched is OK to trace */ +#define preempt_enable_notrace() \ +do { \ + preempt_enable_no_resched_notrace(); \ + barrier(); \ + preempt_check_resched(); \ +} while (0) + #else #define preempt_disable() do { } while (0) @@ -59,6 +87,10 @@ do { \ #define preempt_enable() do { } while (0) #define preempt_check_resched() do { } while (0) +#define preempt_disable_notrace() do { } while (0) +#define preempt_enable_no_resched_notrace() do { } while (0) +#define preempt_enable_notrace() do { } while (0) + #endif #ifdef CONFIG_PREEMPT_NOTIFIERS -- cgit v0.10.2 From ffdc1a09ae7e2cbd714a446ee38a27f625b5f1c8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:41 +0200 Subject: tracing: add notrace to linkage.h notrace signals that a function should not be traced. Most of the time this is used by tracers to annotate code that cannot be traced - it's in a volatile state (such as in user vdso context or NMI context) or it's in the tracer internals. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 2119610..14f329c 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -3,6 +3,8 @@ #include +#define notrace __attribute__((no_instrument_function)) + #ifdef __cplusplus #define CPP_ASMLINKAGE extern "C" #else -- cgit v0.10.2 From 23adec554a7648f99c8acc0caf49c66320cd2b84 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:41 +0200 Subject: x86: add notrace annotations to vsyscall. Add the notrace annotations to the vsyscall functions - there we are not in kernel context yet, so the tracer function cannot (and must not) be called. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 61efa2f..4063dfa 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -42,7 +42,8 @@ #include #include -#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) +#define __vsyscall(nr) \ + __attribute__ ((unused, __section__(".vsyscall_" #nr))) notrace #define __syscall_clobber "r11","cx","memory" /* diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index 23476c2..5cb8f75 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c @@ -23,7 +23,7 @@ #define gtod vdso_vsyscall_gtod_data -static long vdso_fallback_gettime(long clock, struct timespec *ts) +notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) { long ret; asm("syscall" : "=a" (ret) : @@ -31,7 +31,7 @@ static long vdso_fallback_gettime(long clock, struct timespec *ts) return ret; } -static inline long vgetns(void) +notrace static inline long vgetns(void) { long v; cycles_t (*vread)(void); @@ -40,7 +40,7 @@ static inline long vgetns(void) return (v * gtod->clock.mult) >> gtod->clock.shift; } -static noinline int do_realtime(struct timespec *ts) +notrace static noinline int do_realtime(struct timespec *ts) { unsigned long seq, ns; do { @@ -54,7 +54,8 @@ static noinline int do_realtime(struct timespec *ts) } /* Copy of the version in kernel/time.c which we cannot directly access */ -static void vset_normalized_timespec(struct timespec *ts, long sec, long nsec) +notrace static void +vset_normalized_timespec(struct timespec *ts, long sec, long nsec) { while (nsec >= NSEC_PER_SEC) { nsec -= NSEC_PER_SEC; @@ -68,7 +69,7 @@ static void vset_normalized_timespec(struct timespec *ts, long sec, long nsec) ts->tv_nsec = nsec; } -static noinline int do_monotonic(struct timespec *ts) +notrace static noinline int do_monotonic(struct timespec *ts) { unsigned long seq, ns, secs; do { @@ -82,7 +83,7 @@ static noinline int do_monotonic(struct timespec *ts) return 0; } -int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) +notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) { if (likely(gtod->sysctl_enabled && gtod->clock.vread)) switch (clock) { @@ -96,7 +97,7 @@ int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) int clock_gettime(clockid_t, struct timespec *) __attribute__((weak, alias("__vdso_clock_gettime"))); -int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) +notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) { long ret; if (likely(gtod->sysctl_enabled && gtod->clock.vread)) { diff --git a/arch/x86/vdso/vgetcpu.c b/arch/x86/vdso/vgetcpu.c index c8097f1..9fbc6b2 100644 --- a/arch/x86/vdso/vgetcpu.c +++ b/arch/x86/vdso/vgetcpu.c @@ -13,7 +13,8 @@ #include #include "vextern.h" -long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) +notrace long +__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) { unsigned int p; diff --git a/include/asm-x86/vsyscall.h b/include/asm-x86/vsyscall.h index 17b3700..6b66ff9 100644 --- a/include/asm-x86/vsyscall.h +++ b/include/asm-x86/vsyscall.h @@ -24,7 +24,8 @@ enum vsyscall_num { ((unused, __section__ (".vsyscall_gtod_data"),aligned(16))) #define __section_vsyscall_clock __attribute__ \ ((unused, __section__ (".vsyscall_clock"),aligned(16))) -#define __vsyscall_fn __attribute__ ((unused,__section__(".vsyscall_fn"))) +#define __vsyscall_fn \ + __attribute__ ((unused, __section__(".vsyscall_fn"))) notrace #define VGETCPU_RDTSCP 1 #define VGETCPU_LSL 2 -- cgit v0.10.2 From 6e766410c4babd37bc7cd5e25009c179781742c8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 May 2008 21:20:41 +0200 Subject: ftrace: annotate core code that should not be traced Mark with "notrace" functions in core code that should not be traced. The "notrace" attribute will prevent gcc from adding a call to ftrace on the annotated funtions. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 6c90fb9..e555ab6 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -7,7 +7,7 @@ #include #include -unsigned int debug_smp_processor_id(void) +notrace unsigned int debug_smp_processor_id(void) { unsigned long preempt_count = preempt_count(); int this_cpu = raw_smp_processor_id(); -- cgit v0.10.2 From 16444a8a40d4c7b4f6de34af0cae1f76a4f6c901 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: add basic support for gcc profiler instrumentation If CONFIG_FTRACE is selected and /proc/sys/kernel/ftrace_enabled is set to a non-zero value the ftrace routine will be called everytime we enter a kernel function that is not marked with the "notrace" attribute. The ftrace routine will then call a registered function if a function happens to be registered. [ This code has been highly hacked by Steven Rostedt and Ingo Molnar, so don't blame Arnaldo for all of this ;-) ] Update: It is now possible to register more than one ftrace function. If only one ftrace function is registered, that will be the function that ftrace calls directly. If more than one function is registered, then ftrace will call a function that will loop through the functions to call. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/Makefile b/Makefile index 20b3235..b4a273f 100644 --- a/Makefile +++ b/Makefile @@ -528,6 +528,10 @@ KBUILD_CFLAGS += -g KBUILD_AFLAGS += -gdwarf-2 endif +ifdef CONFIG_FTRACE +KBUILD_CFLAGS += -pg +endif + # We trigger additional mismatches with less inlining ifdef CONFIG_DEBUG_SECTION_MISMATCH KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index fe361ae..c742dfe 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -23,6 +23,7 @@ config X86 select HAVE_OPROFILE select HAVE_KPROBES select HAVE_KRETPROBES + select HAVE_FTRACE select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 2a609dc..f47b9b5 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1109,6 +1109,33 @@ ENDPROC(xen_failsafe_callback) #endif /* CONFIG_XEN */ +#ifdef CONFIG_FTRACE +ENTRY(mcount) + cmpl $ftrace_stub, ftrace_trace_function + jnz trace + +.globl ftrace_stub +ftrace_stub: + ret + + /* taken from glibc */ +trace: + pushl %eax + pushl %ecx + pushl %edx + movl 0xc(%esp), %eax + movl 0x4(%ebp), %edx + + call *ftrace_trace_function + + popl %edx + popl %ecx + popl %eax + + jmp ftrace_stub +END(mcount) +#endif + .section .rodata,"a" #include "syscall_table_32.S" diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 556a8df..f046e0c 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -54,6 +54,43 @@ .code64 +#ifdef CONFIG_FTRACE +ENTRY(mcount) + cmpq $ftrace_stub, ftrace_trace_function + jnz trace +.globl ftrace_stub +ftrace_stub: + retq + +trace: + /* taken from glibc */ + subq $0x38, %rsp + movq %rax, (%rsp) + movq %rcx, 8(%rsp) + movq %rdx, 16(%rsp) + movq %rsi, 24(%rsp) + movq %rdi, 32(%rsp) + movq %r8, 40(%rsp) + movq %r9, 48(%rsp) + + movq 0x38(%rsp), %rdi + movq 8(%rbp), %rsi + + call *ftrace_trace_function + + movq 48(%rsp), %r9 + movq 40(%rsp), %r8 + movq 32(%rsp), %rdi + movq 24(%rsp), %rsi + movq 16(%rsp), %rdx + movq 8(%rsp), %rcx + movq (%rsp), %rax + addq $0x38, %rsp + + jmp ftrace_stub +END(mcount) +#endif + #ifndef CONFIG_PREEMPT #define retint_kernel retint_restore_args #endif diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h new file mode 100644 index 0000000..b96ef14 --- /dev/null +++ b/include/linux/ftrace.h @@ -0,0 +1,38 @@ +#ifndef _LINUX_FTRACE_H +#define _LINUX_FTRACE_H + +#ifdef CONFIG_FTRACE + +#include + +#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +#define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1)) +#define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2)) + +typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); + +struct ftrace_ops { + ftrace_func_t func; + struct ftrace_ops *next; +}; + +/* + * The ftrace_ops must be a static and should also + * be read_mostly. These functions do modify read_mostly variables + * so use them sparely. Never free an ftrace_op or modify the + * next pointer after it has been registered. Even after unregistering + * it, the next pointer may still be used internally. + */ +int register_ftrace_function(struct ftrace_ops *ops); +int unregister_ftrace_function(struct ftrace_ops *ops); +void clear_ftrace_function(void); + +extern void ftrace_stub(unsigned long a0, unsigned long a1); +extern void mcount(void); + +#else /* !CONFIG_FTRACE */ +# define register_ftrace_function(ops) do { } while (0) +# define unregister_ftrace_function(ops) do { } while (0) +# define clear_ftrace_function(ops) do { } while (0) +#endif /* CONFIG_FTRACE */ +#endif /* _LINUX_FTRACE_H */ diff --git a/kernel/Makefile b/kernel/Makefile index 1c9938a..fa05f6d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o obj-$(CONFIG_MARKERS) += marker.o obj-$(CONFIG_LATENCYTOP) += latencytop.o +obj-$(CONFIG_FTRACE) += trace/ ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig new file mode 100644 index 0000000..8185c91 --- /dev/null +++ b/kernel/trace/Kconfig @@ -0,0 +1,5 @@ +# +# Architectures that offer an FTRACE implementation should select HAVE_FTRACE: +# +config HAVE_FTRACE + bool diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile new file mode 100644 index 0000000..bf4fd21 --- /dev/null +++ b/kernel/trace/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_FTRACE) += libftrace.o + +libftrace-y := ftrace.o diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c new file mode 100644 index 0000000..b6a80b9 --- /dev/null +++ b/kernel/trace/ftrace.c @@ -0,0 +1,138 @@ +/* + * Infrastructure for profiling code inserted by 'gcc -pg'. + * + * Copyright (C) 2007-2008 Steven Rostedt + * Copyright (C) 2004-2008 Ingo Molnar + * + * Originally ported from the -rt patch by: + * Copyright (C) 2007 Arnaldo Carvalho de Melo + * + * Based on code in the latency_tracer, that is: + * + * Copyright (C) 2004-2006 Ingo Molnar + * Copyright (C) 2004 William Lee Irwin III + */ + +#include +#include + +static DEFINE_SPINLOCK(ftrace_func_lock); +static struct ftrace_ops ftrace_list_end __read_mostly = +{ + .func = ftrace_stub, +}; + +static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end; +ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; + +/* mcount is defined per arch in assembly */ +EXPORT_SYMBOL(mcount); + +notrace void ftrace_list_func(unsigned long ip, unsigned long parent_ip) +{ + struct ftrace_ops *op = ftrace_list; + + /* in case someone actually ports this to alpha! */ + read_barrier_depends(); + + while (op != &ftrace_list_end) { + /* silly alpha */ + read_barrier_depends(); + op->func(ip, parent_ip); + op = op->next; + }; +} + +/** + * register_ftrace_function - register a function for profiling + * @ops - ops structure that holds the function for profiling. + * + * Register a function to be called by all functions in the + * kernel. + * + * Note: @ops->func and all the functions it calls must be labeled + * with "notrace", otherwise it will go into a + * recursive loop. + */ +int register_ftrace_function(struct ftrace_ops *ops) +{ + unsigned long flags; + + spin_lock_irqsave(&ftrace_func_lock, flags); + ops->next = ftrace_list; + /* + * We are entering ops into the ftrace_list but another + * CPU might be walking that list. We need to make sure + * the ops->next pointer is valid before another CPU sees + * the ops pointer included into the ftrace_list. + */ + smp_wmb(); + ftrace_list = ops; + /* + * For one func, simply call it directly. + * For more than one func, call the chain. + */ + if (ops->next == &ftrace_list_end) + ftrace_trace_function = ops->func; + else + ftrace_trace_function = ftrace_list_func; + spin_unlock_irqrestore(&ftrace_func_lock, flags); + + return 0; +} + +/** + * unregister_ftrace_function - unresgister a function for profiling. + * @ops - ops structure that holds the function to unregister + * + * Unregister a function that was added to be called by ftrace profiling. + */ +int unregister_ftrace_function(struct ftrace_ops *ops) +{ + unsigned long flags; + struct ftrace_ops **p; + int ret = 0; + + spin_lock_irqsave(&ftrace_func_lock, flags); + + /* + * If we are the only function, then the ftrace pointer is + * pointing directly to that function. + */ + if (ftrace_list == ops && ops->next == &ftrace_list_end) { + ftrace_trace_function = ftrace_stub; + ftrace_list = &ftrace_list_end; + goto out; + } + + for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next) + if (*p == ops) + break; + + if (*p != ops) { + ret = -1; + goto out; + } + + *p = (*p)->next; + + /* If we only have one func left, then call that directly */ + if (ftrace_list->next == &ftrace_list_end) + ftrace_trace_function = ftrace_list->func; + + out: + spin_unlock_irqrestore(&ftrace_func_lock, flags); + + return 0; +} + +/** + * clear_ftrace_function - reset the ftrace function + * + * This NULLs the ftrace function and in essence stops + * tracing. There may be lag + */ +void clear_ftrace_function(void) +{ + ftrace_trace_function = ftrace_stub; +} diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d2099f4..d8b6279 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -634,6 +634,8 @@ config LATENCYTOP Enable this option if you want to use the LatencyTOP tool to find out which userspace is blocking on what kernel operations. +source kernel/trace/Kconfig + config PROVIDE_OHCI1394_DMA_INIT bool "Remote debugging over FireWire early on boot" depends on PCI && X86 -- cgit v0.10.2 From bc0c38d139ec7fcd5c030aea16b008f3732e42ac Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: latency tracer infrastructure This patch adds the latency tracer infrastructure. This patch does not add anything that will select and turn it on, but will be used by later patches. If it were to be compiled, it would add the following files to the debugfs: The root tracing directory: /debugfs/tracing/ This patch also adds the following files: available_tracers list of available tracers. Currently no tracers are available. Looking into this file only shows "none" which is used to unregister all tracers. current_tracer The trace that is currently active. Empty on start up. To switch to a tracer simply echo one of the tracers that are listed in available_tracers: example: (used with later patches) echo function > /debugfs/tracing/current_tracer To disable the tracer: echo disable > /debugfs/tracing/current_tracer tracing_enabled echoing "1" into this file starts the ftrace function tracing (if sysctl kernel.ftrace_enabled=1) echoing "0" turns it off. latency_trace This file is readonly and holds the result of the trace. trace This file outputs a easier to read version of the trace. iter_ctrl Controls the way the output of traces look. So far there's two controls: echoing in "symonly" will only show the kallsyms variables without the addresses (if kallsyms was configured) echoing in "verbose" will change the output to show a lot more data, but not very easy to understand by humans. echoing in "nosymonly" turns off symonly. echoing in "noverbose" turns off verbose. Signed-off-by: Steven Rostedt Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/Makefile b/kernel/Makefile index fa05f6d..7e344e7 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o obj-$(CONFIG_MARKERS) += marker.o obj-$(CONFIG_LATENCYTOP) += latencytop.o obj-$(CONFIG_FTRACE) += trace/ +obj-$(CONFIG_TRACING) += trace/ ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 8185c91..ce70677 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -3,3 +3,8 @@ # config HAVE_FTRACE bool + +config TRACING + bool + select DEBUG_FS + diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index bf4fd21..7af4031 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -1,3 +1,5 @@ obj-$(CONFIG_FTRACE) += libftrace.o +obj-$(CONFIG_TRACING) += trace.o + libftrace-y := ftrace.o diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c new file mode 100644 index 0000000..1b8eca7 --- /dev/null +++ b/kernel/trace/trace.c @@ -0,0 +1,1547 @@ +/* + * ring buffer based function tracer + * + * Copyright (C) 2007-2008 Steven Rostedt + * Copyright (C) 2008 Ingo Molnar + * + * Originally taken from the RT patch by: + * Arnaldo Carvalho de Melo + * + * Based on code from the latency_tracer, that is: + * Copyright (C) 2004-2006 Ingo Molnar + * Copyright (C) 2004 William Lee Irwin III + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; +unsigned long __read_mostly tracing_thresh; + +static long notrace +ns2usecs(cycle_t nsec) +{ + nsec += 500; + do_div(nsec, 1000); + return nsec; +} + +static atomic_t tracer_counter; +static struct trace_array global_trace; + +static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); + +static struct trace_array max_tr; + +static DEFINE_PER_CPU(struct trace_array_cpu, max_data); + +static int tracer_enabled; +static unsigned long trace_nr_entries = 4096UL; + +static struct tracer *trace_types __read_mostly; +static struct tracer *current_trace __read_mostly; +static int max_tracer_type_len; + +static DEFINE_MUTEX(trace_types_lock); + +static int __init set_nr_entries(char *str) +{ + if (!str) + return 0; + trace_nr_entries = simple_strtoul(str, &str, 0); + return 1; +} +__setup("trace_entries=", set_nr_entries); + +enum trace_type { + __TRACE_FIRST_TYPE = 0, + + TRACE_FN, + TRACE_CTX, + + __TRACE_LAST_TYPE +}; + +enum trace_flag_type { + TRACE_FLAG_IRQS_OFF = 0x01, + TRACE_FLAG_NEED_RESCHED = 0x02, + TRACE_FLAG_HARDIRQ = 0x04, + TRACE_FLAG_SOFTIRQ = 0x08, +}; + +enum trace_iterator_flags { + TRACE_ITER_PRINT_PARENT = 0x01, + TRACE_ITER_SYM_OFFSET = 0x02, + TRACE_ITER_SYM_ADDR = 0x04, + TRACE_ITER_VERBOSE = 0x08, +}; + +#define TRACE_ITER_SYM_MASK \ + (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) + +/* These must match the bit postions above */ +static const char *trace_options[] = { + "print-parent", + "sym-offset", + "sym-addr", + "verbose", + NULL +}; + +static unsigned trace_flags; + + +/* + * Copy the new maximum trace into the separate maximum-trace + * structure. (this way the maximum trace is permanently saved, + * for later retrieval via /debugfs/tracing/latency_trace) + */ +static void notrace +__update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) +{ + struct trace_array_cpu *data = tr->data[cpu]; + + max_tr.cpu = cpu; + max_tr.time_start = data->preempt_timestamp; + + data = max_tr.data[cpu]; + data->saved_latency = tracing_max_latency; + + memcpy(data->comm, tsk->comm, TASK_COMM_LEN); + data->pid = tsk->pid; + data->uid = tsk->uid; + data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; + data->policy = tsk->policy; + data->rt_priority = tsk->rt_priority; + + /* record this tasks comm */ + tracing_record_cmdline(current); +} + +notrace void +update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) +{ + struct trace_array_cpu *data; + void *save_trace; + int i; + + /* clear out all the previous traces */ + for_each_possible_cpu(i) { + data = tr->data[i]; + save_trace = max_tr.data[i]->trace; + memcpy(max_tr.data[i], data, sizeof(*data)); + data->trace = save_trace; + } + + __update_max_tr(tr, tsk, cpu); +} + +/** + * update_max_tr_single - only copy one trace over, and reset the rest + * @tr - tracer + * @tsk - task with the latency + * @cpu - the cpu of the buffer to copy. + */ +notrace void +update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) +{ + struct trace_array_cpu *data = tr->data[cpu]; + void *save_trace; + int i; + + for_each_possible_cpu(i) + tracing_reset(max_tr.data[i]); + + save_trace = max_tr.data[cpu]->trace; + memcpy(max_tr.data[cpu], data, sizeof(*data)); + data->trace = save_trace; + + __update_max_tr(tr, tsk, cpu); +} + +int register_tracer(struct tracer *type) +{ + struct tracer *t; + int len; + int ret = 0; + + if (!type->name) { + pr_info("Tracer must have a name\n"); + return -1; + } + + mutex_lock(&trace_types_lock); + for (t = trace_types; t; t = t->next) { + if (strcmp(type->name, t->name) == 0) { + /* already found */ + pr_info("Trace %s already registered\n", + type->name); + ret = -1; + goto out; + } + } + + type->next = trace_types; + trace_types = type; + len = strlen(type->name); + if (len > max_tracer_type_len) + max_tracer_type_len = len; + out: + mutex_unlock(&trace_types_lock); + + return ret; +} + +void unregister_tracer(struct tracer *type) +{ + struct tracer **t; + int len; + + mutex_lock(&trace_types_lock); + for (t = &trace_types; *t; t = &(*t)->next) { + if (*t == type) + goto found; + } + pr_info("Trace %s not registered\n", type->name); + goto out; + + found: + *t = (*t)->next; + if (strlen(type->name) != max_tracer_type_len) + goto out; + + max_tracer_type_len = 0; + for (t = &trace_types; *t; t = &(*t)->next) { + len = strlen((*t)->name); + if (len > max_tracer_type_len) + max_tracer_type_len = len; + } + out: + mutex_unlock(&trace_types_lock); +} + +void notrace tracing_reset(struct trace_array_cpu *data) +{ + data->trace_idx = 0; + atomic_set(&data->underrun, 0); +} + +#ifdef CONFIG_FTRACE +static void notrace +function_trace_call(unsigned long ip, unsigned long parent_ip) +{ + struct trace_array *tr = &global_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (unlikely(!tracer_enabled)) + return; + + raw_local_irq_save(flags); + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + ftrace(tr, data, ip, parent_ip, flags); + + atomic_dec(&data->disabled); + raw_local_irq_restore(flags); +} + +static struct ftrace_ops trace_ops __read_mostly = +{ + .func = function_trace_call, +}; +#endif + +notrace void tracing_start_function_trace(void) +{ + register_ftrace_function(&trace_ops); +} + +notrace void tracing_stop_function_trace(void) +{ + unregister_ftrace_function(&trace_ops); +} + +#define SAVED_CMDLINES 128 +static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; +static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; +static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; +static int cmdline_idx; +static DEFINE_SPINLOCK(trace_cmdline_lock); +atomic_t trace_record_cmdline_disabled; + +static void trace_init_cmdlines(void) +{ + memset(&map_pid_to_cmdline, -1, sizeof(map_pid_to_cmdline)); + memset(&map_cmdline_to_pid, -1, sizeof(map_cmdline_to_pid)); + cmdline_idx = 0; +} + +notrace void trace_stop_cmdline_recording(void); + +static void notrace trace_save_cmdline(struct task_struct *tsk) +{ + unsigned map; + unsigned idx; + + if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT)) + return; + + /* + * It's not the end of the world if we don't get + * the lock, but we also don't want to spin + * nor do we want to disable interrupts, + * so if we miss here, then better luck next time. + */ + if (!spin_trylock(&trace_cmdline_lock)) + return; + + idx = map_pid_to_cmdline[tsk->pid]; + if (idx >= SAVED_CMDLINES) { + idx = (cmdline_idx + 1) % SAVED_CMDLINES; + + map = map_cmdline_to_pid[idx]; + if (map <= PID_MAX_DEFAULT) + map_pid_to_cmdline[map] = (unsigned)-1; + + map_pid_to_cmdline[tsk->pid] = idx; + + cmdline_idx = idx; + } + + memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); + + spin_unlock(&trace_cmdline_lock); +} + +static notrace char *trace_find_cmdline(int pid) +{ + char *cmdline = "<...>"; + unsigned map; + + if (!pid) + return ""; + + if (pid > PID_MAX_DEFAULT) + goto out; + + map = map_pid_to_cmdline[pid]; + if (map >= SAVED_CMDLINES) + goto out; + + cmdline = saved_cmdlines[map]; + + out: + return cmdline; +} + +notrace void tracing_record_cmdline(struct task_struct *tsk) +{ + if (atomic_read(&trace_record_cmdline_disabled)) + return; + + trace_save_cmdline(tsk); +} + +static inline notrace struct trace_entry * +tracing_get_trace_entry(struct trace_array *tr, + struct trace_array_cpu *data) +{ + unsigned long idx, idx_next; + struct trace_entry *entry; + + idx = data->trace_idx; + idx_next = idx + 1; + + if (unlikely(idx_next >= tr->entries)) { + atomic_inc(&data->underrun); + idx_next = 0; + } + + data->trace_idx = idx_next; + + if (unlikely(idx_next != 0 && atomic_read(&data->underrun))) + atomic_inc(&data->underrun); + + entry = data->trace + idx * TRACE_ENTRY_SIZE; + + return entry; +} + +static inline notrace void +tracing_generic_entry_update(struct trace_entry *entry, + unsigned long flags) +{ + struct task_struct *tsk = current; + unsigned long pc; + + pc = preempt_count(); + + entry->idx = atomic_inc_return(&tracer_counter); + entry->preempt_count = pc & 0xff; + entry->pid = tsk->pid; + entry->t = now(raw_smp_processor_id()); + entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | + ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | + ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | + (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); +} + +notrace void +ftrace(struct trace_array *tr, struct trace_array_cpu *data, + unsigned long ip, unsigned long parent_ip, + unsigned long flags) +{ + struct trace_entry *entry; + + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, flags); + entry->type = TRACE_FN; + entry->fn.ip = ip; + entry->fn.parent_ip = parent_ip; +} + +notrace void +tracing_sched_switch_trace(struct trace_array *tr, + struct trace_array_cpu *data, + struct task_struct *prev, struct task_struct *next, + unsigned long flags) +{ + struct trace_entry *entry; + + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, flags); + entry->type = TRACE_CTX; + entry->ctx.prev_pid = prev->pid; + entry->ctx.prev_prio = prev->prio; + entry->ctx.prev_state = prev->state; + entry->ctx.next_pid = next->pid; + entry->ctx.next_prio = next->prio; +} + +enum trace_file_type { + TRACE_FILE_LAT_FMT = 1, +}; + +static struct trace_entry * +trace_entry_idx(struct trace_array *tr, unsigned long idx, int cpu) +{ + struct trace_entry *array = tr->data[cpu]->trace; + unsigned long underrun; + + if (idx >= tr->entries) + return NULL; + + underrun = atomic_read(&tr->data[cpu]->underrun); + if (underrun) + idx = ((underrun - 1) + idx) % tr->entries; + else if (idx >= tr->data[cpu]->trace_idx) + return NULL; + + return &array[idx]; +} + +static struct notrace trace_entry * +find_next_entry(struct trace_iterator *iter, int *ent_cpu) +{ + struct trace_array *tr = iter->tr; + struct trace_entry *ent, *next = NULL; + int next_cpu = -1; + int cpu; + + for_each_possible_cpu(cpu) { + if (!tr->data[cpu]->trace) + continue; + ent = trace_entry_idx(tr, iter->next_idx[cpu], cpu); + if (ent && + (!next || (long)(next->idx - ent->idx) > 0)) { + next = ent; + next_cpu = cpu; + } + } + + if (ent_cpu) + *ent_cpu = next_cpu; + + return next; +} + +static void *find_next_entry_inc(struct trace_iterator *iter) +{ + struct trace_entry *next; + int next_cpu = -1; + + next = find_next_entry(iter, &next_cpu); + + if (next) { + iter->next_idx[next_cpu]++; + iter->idx++; + } + iter->ent = next; + iter->cpu = next_cpu; + + return next ? iter : NULL; +} + +static void notrace * +s_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct trace_iterator *iter = m->private; + void *ent; + void *last_ent = iter->ent; + int i = (int)*pos; + + (*pos)++; + + /* can't go backwards */ + if (iter->idx > i) + return NULL; + + if (iter->idx < 0) + ent = find_next_entry_inc(iter); + else + ent = iter; + + while (ent && iter->idx < i) + ent = find_next_entry_inc(iter); + + iter->pos = *pos; + + if (last_ent && !ent) + seq_puts(m, "\n\nvim:ft=help\n"); + + return ent; +} + +static void *s_start(struct seq_file *m, loff_t *pos) +{ + struct trace_iterator *iter = m->private; + void *p = NULL; + loff_t l = 0; + int i; + + mutex_lock(&trace_types_lock); + + if (!current_trace || current_trace != iter->trace) + return NULL; + + atomic_inc(&trace_record_cmdline_disabled); + + /* let the tracer grab locks here if needed */ + if (current_trace->start) + current_trace->start(iter); + + if (*pos != iter->pos) { + iter->ent = NULL; + iter->cpu = 0; + iter->idx = -1; + + for (i = 0; i < NR_CPUS; i++) + iter->next_idx[i] = 0; + + for (p = iter; p && l < *pos; p = s_next(m, p, &l)) + ; + + } else { + l = *pos; + p = s_next(m, p, &l); + } + + return p; +} + +static void s_stop(struct seq_file *m, void *p) +{ + struct trace_iterator *iter = m->private; + + atomic_dec(&trace_record_cmdline_disabled); + + /* let the tracer release locks here if needed */ + if (current_trace && current_trace == iter->trace && iter->trace->stop) + iter->trace->stop(iter); + + mutex_unlock(&trace_types_lock); +} + +static void +seq_print_sym_short(struct seq_file *m, const char *fmt, unsigned long address) +{ +#ifdef CONFIG_KALLSYMS + char str[KSYM_SYMBOL_LEN]; + + kallsyms_lookup(address, NULL, NULL, NULL, str); + + seq_printf(m, fmt, str); +#endif +} + +static void +seq_print_sym_offset(struct seq_file *m, const char *fmt, unsigned long address) +{ +#ifdef CONFIG_KALLSYMS + char str[KSYM_SYMBOL_LEN]; + + sprint_symbol(str, address); + seq_printf(m, fmt, str); +#endif +} + +#ifndef CONFIG_64BIT +# define IP_FMT "%08lx" +#else +# define IP_FMT "%016lx" +#endif + +static void notrace +seq_print_ip_sym(struct seq_file *m, unsigned long ip, unsigned long sym_flags) +{ + if (!ip) { + seq_printf(m, "0"); + return; + } + + if (sym_flags & TRACE_ITER_SYM_OFFSET) + seq_print_sym_offset(m, "%s", ip); + else + seq_print_sym_short(m, "%s", ip); + + if (sym_flags & TRACE_ITER_SYM_ADDR) + seq_printf(m, " <" IP_FMT ">", ip); +} + +static void notrace print_lat_help_header(struct seq_file *m) +{ + seq_puts(m, "# _------=> CPU# \n"); + seq_puts(m, "# / _-----=> irqs-off \n"); + seq_puts(m, "# | / _----=> need-resched \n"); + seq_puts(m, "# || / _---=> hardirq/softirq \n"); + seq_puts(m, "# ||| / _--=> preempt-depth \n"); + seq_puts(m, "# |||| / \n"); + seq_puts(m, "# ||||| delay \n"); + seq_puts(m, "# cmd pid ||||| time | caller \n"); + seq_puts(m, "# \\ / ||||| \\ | / \n"); +} + +static void notrace print_func_help_header(struct seq_file *m) +{ + seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); + seq_puts(m, "# | | | | |\n"); +} + + +static void notrace +print_trace_header(struct seq_file *m, struct trace_iterator *iter) +{ + unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); + struct trace_array *tr = iter->tr; + struct trace_array_cpu *data = tr->data[tr->cpu]; + struct tracer *type = current_trace; + unsigned long underruns = 0; + unsigned long underrun; + unsigned long entries = 0; + int cpu; + const char *name = "preemption"; + + if (type) + name = type->name; + + for_each_possible_cpu(cpu) { + if (tr->data[cpu]->trace) { + underrun = atomic_read(&tr->data[cpu]->underrun); + if (underrun) { + underruns += underrun; + entries += tr->entries; + } else + entries += tr->data[cpu]->trace_idx; + } + } + + seq_printf(m, "%s latency trace v1.1.5 on %s\n", + name, UTS_RELEASE); + seq_puts(m, "-----------------------------------" + "---------------------------------\n"); + seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d |" + " (M:%s VP:%d, KP:%d, SP:%d HP:%d", + data->saved_latency, + entries, + (entries + underruns), + tr->cpu, +#if defined(CONFIG_PREEMPT_NONE) + "server", +#elif defined(CONFIG_PREEMPT_VOLUNTARY) + "desktop", +#elif defined(CONFIG_PREEMPT_DESKTOP) + "preempt", +#else + "unknown", +#endif + /* These are reserved for later use */ + 0, 0, 0, 0); +#ifdef CONFIG_SMP + seq_printf(m, " #P:%d)\n", num_online_cpus()); +#else + seq_puts(m, ")\n"); +#endif + seq_puts(m, " -----------------\n"); + seq_printf(m, " | task: %.16s-%d " + "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n", + data->comm, data->pid, data->uid, data->nice, + data->policy, data->rt_priority); + seq_puts(m, " -----------------\n"); + + if (data->critical_start) { + seq_puts(m, " => started at: "); + seq_print_ip_sym(m, data->critical_start, sym_flags); + seq_puts(m, "\n => ended at: "); + seq_print_ip_sym(m, data->critical_end, sym_flags); + seq_puts(m, "\n"); + } + + seq_puts(m, "\n"); +} + +unsigned long nsecs_to_usecs(unsigned long nsecs) +{ + return nsecs / 1000; +} + +static void notrace +lat_print_generic(struct seq_file *m, struct trace_entry *entry, int cpu) +{ + int hardirq, softirq; + char *comm; + + comm = trace_find_cmdline(entry->pid); + + seq_printf(m, "%8.8s-%-5d ", comm, entry->pid); + seq_printf(m, "%d", cpu); + seq_printf(m, "%c%c", + (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.', + ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.')); + + hardirq = entry->flags & TRACE_FLAG_HARDIRQ; + softirq = entry->flags & TRACE_FLAG_SOFTIRQ; + if (hardirq && softirq) + seq_putc(m, 'H'); + else { + if (hardirq) + seq_putc(m, 'h'); + else { + if (softirq) + seq_putc(m, 's'); + else + seq_putc(m, '.'); + } + } + + if (entry->preempt_count) + seq_printf(m, "%x", entry->preempt_count); + else + seq_puts(m, "."); +} + +unsigned long preempt_mark_thresh = 100; + +static void notrace +lat_print_timestamp(struct seq_file *m, unsigned long long abs_usecs, + unsigned long rel_usecs) +{ + seq_printf(m, " %4lldus", abs_usecs); + if (rel_usecs > preempt_mark_thresh) + seq_puts(m, "!: "); + else if (rel_usecs > 1) + seq_puts(m, "+: "); + else + seq_puts(m, " : "); +} + +static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; + +static void notrace +print_lat_fmt(struct seq_file *m, struct trace_iterator *iter, + unsigned int trace_idx, int cpu) +{ + unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); + struct trace_entry *next_entry = find_next_entry(iter, NULL); + unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); + struct trace_entry *entry = iter->ent; + unsigned long abs_usecs; + unsigned long rel_usecs; + char *comm; + int S; + + if (!next_entry) + next_entry = entry; + rel_usecs = ns2usecs(next_entry->t - entry->t); + abs_usecs = ns2usecs(entry->t - iter->tr->time_start); + + if (verbose) { + comm = trace_find_cmdline(entry->pid); + seq_printf(m, "%16s %5d %d %d %08x %08x [%08lx]" + " %ld.%03ldms (+%ld.%03ldms): ", + comm, + entry->pid, cpu, entry->flags, + entry->preempt_count, trace_idx, + ns2usecs(entry->t), + abs_usecs/1000, + abs_usecs % 1000, rel_usecs/1000, rel_usecs % 1000); + } else { + lat_print_generic(m, entry, cpu); + lat_print_timestamp(m, abs_usecs, rel_usecs); + } + switch (entry->type) { + case TRACE_FN: + seq_print_ip_sym(m, entry->fn.ip, sym_flags); + seq_puts(m, " ("); + seq_print_ip_sym(m, entry->fn.parent_ip, sym_flags); + seq_puts(m, ")\n"); + break; + case TRACE_CTX: + S = entry->ctx.prev_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.prev_state] : 'X'; + comm = trace_find_cmdline(entry->ctx.next_pid); + seq_printf(m, " %d:%d:%c --> %d:%d %s\n", + entry->ctx.prev_pid, + entry->ctx.prev_prio, + S, + entry->ctx.next_pid, + entry->ctx.next_prio, + comm); + break; + } +} + +static void notrace +print_trace_fmt(struct seq_file *m, struct trace_iterator *iter) +{ + unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); + struct trace_entry *entry = iter->ent; + unsigned long usec_rem; + unsigned long long t; + unsigned long secs; + char *comm; + int S; + + comm = trace_find_cmdline(iter->ent->pid); + + t = ns2usecs(entry->t); + usec_rem = do_div(t, 1000000ULL); + secs = (unsigned long)t; + + seq_printf(m, "%16s-%-5d ", comm, entry->pid); + seq_printf(m, "[%02d] ", iter->cpu); + seq_printf(m, "%5lu.%06lu: ", secs, usec_rem); + + switch (entry->type) { + case TRACE_FN: + seq_print_ip_sym(m, entry->fn.ip, sym_flags); + if ((sym_flags & TRACE_ITER_PRINT_PARENT) && + entry->fn.parent_ip) { + seq_printf(m, " <-"); + seq_print_ip_sym(m, entry->fn.parent_ip, sym_flags); + } + break; + case TRACE_CTX: + S = entry->ctx.prev_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.prev_state] : 'X'; + seq_printf(m, " %d:%d:%c ==> %d:%d\n", + entry->ctx.prev_pid, + entry->ctx.prev_prio, + S, + entry->ctx.next_pid, + entry->ctx.next_prio); + break; + } + seq_printf(m, "\n"); +} + +static int trace_empty(struct trace_iterator *iter) +{ + struct trace_array_cpu *data; + int cpu; + + for_each_possible_cpu(cpu) { + data = iter->tr->data[cpu]; + + if (data->trace && + (data->trace_idx || + atomic_read(&data->underrun))) + return 0; + } + return 1; +} + +static int s_show(struct seq_file *m, void *v) +{ + struct trace_iterator *iter = v; + + if (iter->ent == NULL) { + if (iter->tr) { + seq_printf(m, "# tracer: %s\n", iter->trace->name); + seq_puts(m, "#\n"); + } + if (iter->iter_flags & TRACE_FILE_LAT_FMT) { + /* print nothing if the buffers are empty */ + if (trace_empty(iter)) + return 0; + print_trace_header(m, iter); + if (!(trace_flags & TRACE_ITER_VERBOSE)) + print_lat_help_header(m); + } else { + if (!(trace_flags & TRACE_ITER_VERBOSE)) + print_func_help_header(m); + } + } else { + if (iter->iter_flags & TRACE_FILE_LAT_FMT) + print_lat_fmt(m, iter, iter->idx, iter->cpu); + else + print_trace_fmt(m, iter); + } + + return 0; +} + +static struct seq_operations tracer_seq_ops = { + .start = s_start, + .next = s_next, + .stop = s_stop, + .show = s_show, +}; + +static struct trace_iterator notrace * +__tracing_open(struct inode *inode, struct file *file, int *ret) +{ + struct trace_iterator *iter; + + iter = kzalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) { + *ret = -ENOMEM; + goto out; + } + + mutex_lock(&trace_types_lock); + if (current_trace && current_trace->print_max) + iter->tr = &max_tr; + else + iter->tr = inode->i_private; + iter->trace = current_trace; + iter->pos = -1; + + /* TODO stop tracer */ + *ret = seq_open(file, &tracer_seq_ops); + if (!*ret) { + struct seq_file *m = file->private_data; + m->private = iter; + + /* stop the trace while dumping */ + if (iter->tr->ctrl) + tracer_enabled = 0; + + if (iter->trace && iter->trace->open) + iter->trace->open(iter); + } else { + kfree(iter); + iter = NULL; + } + mutex_unlock(&trace_types_lock); + + out: + return iter; +} + +int tracing_open_generic(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + +int tracing_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = (struct seq_file *)file->private_data; + struct trace_iterator *iter = m->private; + + mutex_lock(&trace_types_lock); + if (iter->trace && iter->trace->close) + iter->trace->close(iter); + + /* reenable tracing if it was previously enabled */ + if (iter->tr->ctrl) + tracer_enabled = 1; + mutex_unlock(&trace_types_lock); + + seq_release(inode, file); + kfree(iter); + return 0; +} + +static int tracing_open(struct inode *inode, struct file *file) +{ + int ret; + + __tracing_open(inode, file, &ret); + + return ret; +} + +static int tracing_lt_open(struct inode *inode, struct file *file) +{ + struct trace_iterator *iter; + int ret; + + iter = __tracing_open(inode, file, &ret); + + if (!ret) + iter->iter_flags |= TRACE_FILE_LAT_FMT; + + return ret; +} + + +static void notrace * +t_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct tracer *t = m->private; + + (*pos)++; + + if (t) + t = t->next; + + m->private = t; + + return t; +} + +static void *t_start(struct seq_file *m, loff_t *pos) +{ + struct tracer *t = m->private; + loff_t l = 0; + + mutex_lock(&trace_types_lock); + for (; t && l < *pos; t = t_next(m, t, &l)) + ; + + return t; +} + +static void t_stop(struct seq_file *m, void *p) +{ + mutex_unlock(&trace_types_lock); +} + +static int t_show(struct seq_file *m, void *v) +{ + struct tracer *t = v; + + if (!t) + return 0; + + seq_printf(m, "%s", t->name); + if (t->next) + seq_putc(m, ' '); + else + seq_putc(m, '\n'); + + return 0; +} + +static struct seq_operations show_traces_seq_ops = { + .start = t_start, + .next = t_next, + .stop = t_stop, + .show = t_show, +}; + +static int show_traces_open(struct inode *inode, struct file *file) +{ + int ret; + + ret = seq_open(file, &show_traces_seq_ops); + if (!ret) { + struct seq_file *m = file->private_data; + m->private = trace_types; + } + + return ret; +} + +static struct file_operations tracing_fops = { + .open = tracing_open, + .read = seq_read, + .llseek = seq_lseek, + .release = tracing_release, +}; + +static struct file_operations tracing_lt_fops = { + .open = tracing_lt_open, + .read = seq_read, + .llseek = seq_lseek, + .release = tracing_release, +}; + +static struct file_operations show_traces_fops = { + .open = show_traces_open, + .read = seq_read, + .release = seq_release, +}; + +static ssize_t +tracing_iter_ctrl_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char *buf; + int r = 0; + int len = 0; + int i; + + /* calulate max size */ + for (i = 0; trace_options[i]; i++) { + len += strlen(trace_options[i]); + len += 3; /* "no" and space */ + } + + /* +2 for \n and \0 */ + buf = kmalloc(len + 2, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (i = 0; trace_options[i]; i++) { + if (trace_flags & (1 << i)) + r += sprintf(buf + r, "%s ", trace_options[i]); + else + r += sprintf(buf + r, "no%s ", trace_options[i]); + } + + r += sprintf(buf + r, "\n"); + WARN_ON(r >= len + 2); + + r = simple_read_from_buffer(ubuf, cnt, ppos, + buf, r); + + kfree(buf); + + return r; +} + +static ssize_t +tracing_iter_ctrl_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + char *cmp = buf; + int neg = 0; + int i; + + if (cnt > 63) + cnt = 63; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + if (strncmp(buf, "no", 2) == 0) { + neg = 1; + cmp += 2; + } + + for (i = 0; trace_options[i]; i++) { + int len = strlen(trace_options[i]); + + if (strncmp(cmp, trace_options[i], len) == 0) { + if (neg) + trace_flags &= ~(1 << i); + else + trace_flags |= (1 << i); + break; + } + } + + filp->f_pos += cnt; + + return cnt; +} + +static struct file_operations tracing_iter_fops = { + .open = tracing_open_generic, + .read = tracing_iter_ctrl_read, + .write = tracing_iter_ctrl_write, +}; + +static ssize_t +tracing_ctrl_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct trace_array *tr = filp->private_data; + char buf[64]; + int r; + + r = sprintf(buf, "%ld\n", tr->ctrl); + return simple_read_from_buffer(ubuf, cnt, ppos, + buf, r); +} + +static ssize_t +tracing_ctrl_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct trace_array *tr = filp->private_data; + long val; + char buf[64]; + + if (cnt > 63) + cnt = 63; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + val = simple_strtoul(buf, NULL, 10); + + val = !!val; + + mutex_lock(&trace_types_lock); + if (tr->ctrl ^ val) { + if (val) + tracer_enabled = 1; + else + tracer_enabled = 0; + + tr->ctrl = val; + + if (current_trace && current_trace->ctrl_update) + current_trace->ctrl_update(tr); + } + mutex_unlock(&trace_types_lock); + + filp->f_pos += cnt; + + return cnt; +} + +static ssize_t +tracing_set_trace_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[max_tracer_type_len+2]; + int r; + + mutex_lock(&trace_types_lock); + if (current_trace) + r = sprintf(buf, "%s\n", current_trace->name); + else + r = sprintf(buf, "\n"); + mutex_unlock(&trace_types_lock); + + return simple_read_from_buffer(ubuf, cnt, ppos, + buf, r); +} + +static ssize_t +tracing_set_trace_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct trace_array *tr = &global_trace; + struct tracer *t; + char buf[max_tracer_type_len+1]; + int i; + + if (cnt > max_tracer_type_len) + cnt = max_tracer_type_len; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + /* strip ending whitespace. */ + for (i = cnt - 1; i > 0 && isspace(buf[i]); i--) + buf[i] = 0; + + mutex_lock(&trace_types_lock); + for (t = trace_types; t; t = t->next) { + if (strcmp(t->name, buf) == 0) + break; + } + if (!t || t == current_trace) + goto out; + + if (current_trace && current_trace->reset) + current_trace->reset(tr); + + current_trace = t; + if (t->init) + t->init(tr); + + out: + mutex_unlock(&trace_types_lock); + + filp->f_pos += cnt; + + return cnt; +} + +static ssize_t +tracing_max_lat_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + unsigned long *ptr = filp->private_data; + char buf[64]; + int r; + + r = snprintf(buf, 64, "%ld\n", + *ptr == (unsigned long)-1 ? -1 : nsecs_to_usecs(*ptr)); + if (r > 64) + r = 64; + return simple_read_from_buffer(ubuf, cnt, ppos, + buf, r); +} + +static ssize_t +tracing_max_lat_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + long *ptr = filp->private_data; + long val; + char buf[64]; + + if (cnt > 63) + cnt = 63; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + val = simple_strtoul(buf, NULL, 10); + + *ptr = val * 1000; + + return cnt; +} + +static struct file_operations tracing_max_lat_fops = { + .open = tracing_open_generic, + .read = tracing_max_lat_read, + .write = tracing_max_lat_write, +}; + +static struct file_operations tracing_ctrl_fops = { + .open = tracing_open_generic, + .read = tracing_ctrl_read, + .write = tracing_ctrl_write, +}; + +static struct file_operations set_tracer_fops = { + .open = tracing_open_generic, + .read = tracing_set_trace_read, + .write = tracing_set_trace_write, +}; + +#ifdef CONFIG_DYNAMIC_FTRACE + +static ssize_t +tracing_read_long(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + unsigned long *p = filp->private_data; + char buf[64]; + int r; + + r = sprintf(buf, "%ld\n", *p); + return simple_read_from_buffer(ubuf, cnt, ppos, + buf, r); +} + +static struct file_operations tracing_read_long_fops = { + .open = tracing_open_generic, + .read = tracing_read_long, +}; +#endif + +static struct dentry *d_tracer; + +struct dentry *tracing_init_dentry(void) +{ + static int once; + + if (d_tracer) + return d_tracer; + + d_tracer = debugfs_create_dir("tracing", NULL); + + if (!d_tracer && !once) { + once = 1; + pr_warning("Could not create debugfs directory 'tracing'\n"); + return NULL; + } + + return d_tracer; +} + +static __init void tracer_init_debugfs(void) +{ + struct dentry *d_tracer; + struct dentry *entry; + + d_tracer = tracing_init_dentry(); + + entry = debugfs_create_file("tracing_enabled", 0644, d_tracer, + &global_trace, &tracing_ctrl_fops); + if (!entry) + pr_warning("Could not create debugfs 'tracing_enabled' entry\n"); + + entry = debugfs_create_file("iter_ctrl", 0644, d_tracer, + NULL, &tracing_iter_fops); + if (!entry) + pr_warning("Could not create debugfs 'iter_ctrl' entry\n"); + + entry = debugfs_create_file("latency_trace", 0444, d_tracer, + &global_trace, &tracing_lt_fops); + if (!entry) + pr_warning("Could not create debugfs 'latency_trace' entry\n"); + + entry = debugfs_create_file("trace", 0444, d_tracer, + &global_trace, &tracing_fops); + if (!entry) + pr_warning("Could not create debugfs 'trace' entry\n"); + + entry = debugfs_create_file("available_tracers", 0444, d_tracer, + &global_trace, &show_traces_fops); + if (!entry) + pr_warning("Could not create debugfs 'trace' entry\n"); + + entry = debugfs_create_file("current_tracer", 0444, d_tracer, + &global_trace, &set_tracer_fops); + if (!entry) + pr_warning("Could not create debugfs 'trace' entry\n"); + + entry = debugfs_create_file("tracing_max_latency", 0644, d_tracer, + &tracing_max_latency, + &tracing_max_lat_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'tracing_max_latency' entry\n"); + + entry = debugfs_create_file("tracing_thresh", 0644, d_tracer, + &tracing_thresh, &tracing_max_lat_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'tracing_threash' entry\n"); + +#ifdef CONFIG_DYNAMIC_FTRACE + entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, + &ftrace_update_tot_cnt, + &tracing_read_long_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'dyn_ftrace_total_info' entry\n"); +#endif +} + +/* dummy trace to disable tracing */ +static struct tracer no_tracer __read_mostly = +{ + .name = "none", +}; + +static inline notrace int page_order(const unsigned long size) +{ + const unsigned long nr_pages = DIV_ROUND_UP(size, PAGE_SIZE); + return ilog2(roundup_pow_of_two(nr_pages)); +} + +__init static int tracer_alloc_buffers(void) +{ + const int order = page_order(trace_nr_entries * TRACE_ENTRY_SIZE); + const unsigned long size = (1UL << order) << PAGE_SHIFT; + struct trace_entry *array; + int i; + + for_each_possible_cpu(i) { + global_trace.data[i] = &per_cpu(global_trace_cpu, i); + max_tr.data[i] = &per_cpu(max_data, i); + + array = (struct trace_entry *) + __get_free_pages(GFP_KERNEL, order); + if (array == NULL) { + printk(KERN_ERR "tracer: failed to allocate" + " %ld bytes for trace buffer!\n", size); + goto free_buffers; + } + global_trace.data[i]->trace = array; + +/* Only allocate if we are actually using the max trace */ +#ifdef CONFIG_TRACER_MAX_TRACE + array = (struct trace_entry *) + __get_free_pages(GFP_KERNEL, order); + if (array == NULL) { + printk(KERN_ERR "wakeup tracer: failed to allocate" + " %ld bytes for trace buffer!\n", size); + goto free_buffers; + } + max_tr.data[i]->trace = array; +#endif + } + + /* + * Since we allocate by orders of pages, we may be able to + * round up a bit. + */ + global_trace.entries = size / TRACE_ENTRY_SIZE; + max_tr.entries = global_trace.entries; + + pr_info("tracer: %ld bytes allocated for %ld", + size, trace_nr_entries); + pr_info(" entries of %ld bytes\n", (long)TRACE_ENTRY_SIZE); + pr_info(" actual entries %ld\n", global_trace.entries); + + tracer_init_debugfs(); + + trace_init_cmdlines(); + + register_tracer(&no_tracer); + current_trace = &no_tracer; + + return 0; + + free_buffers: + for (i-- ; i >= 0; i--) { + struct trace_array_cpu *data = global_trace.data[i]; + + if (data && data->trace) { + free_pages((unsigned long)data->trace, order); + data->trace = NULL; + } + +#ifdef CONFIG_TRACER_MAX_TRACE + data = max_tr.data[i]; + if (data && data->trace) { + free_pages((unsigned long)data->trace, order); + data->trace = NULL; + } +#endif + } + return -ENOMEM; +} + +device_initcall(tracer_alloc_buffers); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h new file mode 100644 index 0000000..3173a93 --- /dev/null +++ b/kernel/trace/trace.h @@ -0,0 +1,184 @@ +#ifndef _LINUX_KERNEL_TRACE_H +#define _LINUX_KERNEL_TRACE_H + +#include +#include +#include +#include + +/* + * Function trace entry - function address and parent function addres: + */ +struct ftrace_entry { + unsigned long ip; + unsigned long parent_ip; +}; + +/* + * Context switch trace entry - which task (and prio) we switched from/to: + */ +struct ctx_switch_entry { + unsigned int prev_pid; + unsigned char prev_prio; + unsigned char prev_state; + unsigned int next_pid; + unsigned char next_prio; +}; + +/* + * The trace entry - the most basic unit of tracing. This is what + * is printed in the end as a single line in the trace output, such as: + * + * bash-15816 [01] 235.197585: idle_cpu <- irq_enter + */ +struct trace_entry { + char type; + char cpu; + char flags; + char preempt_count; + int pid; + cycle_t t; + unsigned long idx; + union { + struct ftrace_entry fn; + struct ctx_switch_entry ctx; + }; +}; + +#define TRACE_ENTRY_SIZE sizeof(struct trace_entry) + +/* + * The CPU trace array - it consists of thousands of trace entries + * plus some other descriptor data: (for example which task started + * the trace, etc.) + */ +struct trace_array_cpu { + void *trace; + unsigned long trace_idx; + atomic_t disabled; + atomic_t underrun; + unsigned long saved_latency; + unsigned long critical_start; + unsigned long critical_end; + unsigned long critical_sequence; + unsigned long nice; + unsigned long policy; + unsigned long rt_priority; + cycle_t preempt_timestamp; + pid_t pid; + uid_t uid; + char comm[TASK_COMM_LEN]; +}; + +struct trace_iterator; + +/* + * The trace array - an array of per-CPU trace arrays. This is the + * highest level data structure that individual tracers deal with. + * They have on/off state as well: + */ +struct trace_array { + unsigned long entries; + long ctrl; + int cpu; + cycle_t time_start; + struct trace_array_cpu *data[NR_CPUS]; +}; + +/* + * A specific tracer, represented by methods that operate on a trace array: + */ +struct tracer { + const char *name; + void (*init)(struct trace_array *tr); + void (*reset)(struct trace_array *tr); + void (*open)(struct trace_iterator *iter); + void (*close)(struct trace_iterator *iter); + void (*start)(struct trace_iterator *iter); + void (*stop)(struct trace_iterator *iter); + void (*ctrl_update)(struct trace_array *tr); + struct tracer *next; + int print_max; +}; + +/* + * Trace iterator - used by printout routines who present trace + * results to users and which routines might sleep, etc: + */ +struct trace_iterator { + struct trace_array *tr; + struct tracer *trace; + struct trace_entry *ent; + unsigned long iter_flags; + loff_t pos; + unsigned long next_idx[NR_CPUS]; + int cpu; + int idx; +}; + +void notrace tracing_reset(struct trace_array_cpu *data); +int tracing_open_generic(struct inode *inode, struct file *filp); +struct dentry *tracing_init_dentry(void); +void ftrace(struct trace_array *tr, + struct trace_array_cpu *data, + unsigned long ip, + unsigned long parent_ip, + unsigned long flags); +void tracing_sched_switch_trace(struct trace_array *tr, + struct trace_array_cpu *data, + struct task_struct *prev, + struct task_struct *next, + unsigned long flags); +void tracing_record_cmdline(struct task_struct *tsk); + +void tracing_start_function_trace(void); +void tracing_stop_function_trace(void); +int register_tracer(struct tracer *type); +void unregister_tracer(struct tracer *type); + +extern unsigned long nsecs_to_usecs(unsigned long nsecs); + +extern unsigned long tracing_max_latency; +extern unsigned long tracing_thresh; + +void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); +void update_max_tr_single(struct trace_array *tr, + struct task_struct *tsk, int cpu); + +static inline notrace cycle_t now(int cpu) +{ + return cpu_clock(cpu); +} + +#ifdef CONFIG_SCHED_TRACER +extern void notrace +wakeup_sched_switch(struct task_struct *prev, struct task_struct *next); +#else +static inline void +wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) +{ +} +#endif + +#ifdef CONFIG_CONTEXT_SWITCH_TRACER +typedef void +(*tracer_switch_func_t)(void *private, + struct task_struct *prev, + struct task_struct *next); + +struct tracer_switch_ops { + tracer_switch_func_t func; + void *private; + struct tracer_switch_ops *next; +}; + +extern int register_tracer_switch(struct tracer_switch_ops *ops); +extern int unregister_tracer_switch(struct tracer_switch_ops *ops); + +#endif /* CONFIG_CONTEXT_SWITCH_TRACER */ + +#ifdef CONFIG_DYNAMIC_FTRACE +extern unsigned long ftrace_update_tot_cnt; +#endif + +#endif /* _LINUX_KERNEL_TRACE_H */ -- cgit v0.10.2 From 1b29b01887e6032dcaf818c14999c7a39593b4e7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: function tracer This is a simple trace that uses the ftrace infrastructure. It is designed to be fast and small, and easy to use. It is useful to record things that happen over a very short period of time, and not to analyze the system in general. Updates: available_tracers "function" is added to this file. current_tracer To enable the function tracer: echo function > /debugfs/tracing/current_tracer To disable the tracer: echo disable > /debugfs/tracing/current_tracer The output of the function_trace file is as follows "echo noverbose > /debugfs/tracing/iter_ctrl" preemption latency trace v1.1.5 on 2.6.24-rc7-tst Signed-off-by: Ingo Molnar -------------------------------------------------------------------- latency: 0 us, #419428/4361791, CPU#1 | (M:desktop VP:0, KP:0, SP:0 HP:0 #P:4) ----------------- | task: -0 (uid:0 nice:0 policy:0 rt_prio:0) ----------------- _------=> CPU# / _-----=> irqs-off | / _----=> need-resched || / _---=> hardirq/softirq ||| / _--=> preempt-depth |||| / ||||| delay cmd pid ||||| time | caller \ / ||||| \ | / swapper-0 0d.h. 1595128us+: set_normalized_timespec+0x8/0x2d (ktime_get_ts+0x4a/0x4e ) swapper-0 0d.h. 1595131us+: _spin_lock+0x8/0x18 (hrtimer_interrupt+0x6e/0x1b0 ) Or with verbose turned on: "echo verbose > /debugfs/tracing/iter_ctrl" preemption latency trace v1.1.5 on 2.6.24-rc7-tst -------------------------------------------------------------------- latency: 0 us, #419428/4361791, CPU#1 | (M:desktop VP:0, KP:0, SP:0 HP:0 #P:4) ----------------- | task: -0 (uid:0 nice:0 policy:0 rt_prio:0) ----------------- swapper 0 0 9 00000000 00000000 [f3675f41] 1595.128ms (+0.003ms): set_normalized_timespec+0x8/0x2d (ktime_get_ts+0x4a/0x4e ) swapper 0 0 9 00000000 00000001 [f3675f45] 1595.131ms (+0.003ms): _spin_lock+0x8/0x18 (hrtimer_interrupt+0x6e/0x1b0 ) swapper 0 0 9 00000000 00000002 [f3675f48] 1595.135ms (+0.003ms): _spin_lock+0x8/0x18 (hrtimer_interrupt+0x6e/0x1b0 ) The "trace" file is not affected by the verbose mode, but is by the symonly. echo "nosymonly" > /debugfs/tracing/iter_ctrl tracer: [ 81.479967] CPU 0: bash:3154 register_ftrace_function+0x5f/0x66 <-- _spin_unlock_irqrestore+0xe/0x5a [ 81.479967] CPU 0: bash:3154 _spin_unlock_irqrestore+0x3e/0x5a <-- sub_preempt_count+0xc/0x7a [ 81.479968] CPU 0: bash:3154 sub_preempt_count+0x30/0x7a <-- in_lock_functions+0x9/0x24 [ 81.479968] CPU 0: bash:3154 vfs_write+0x11d/0x155 <-- dnotify_parent+0x12/0x78 [ 81.479968] CPU 0: bash:3154 dnotify_parent+0x2d/0x78 <-- _spin_lock+0xe/0x70 [ 81.479969] CPU 0: bash:3154 _spin_lock+0x1b/0x70 <-- add_preempt_count+0xe/0x77 [ 81.479969] CPU 0: bash:3154 add_preempt_count+0x3e/0x77 <-- in_lock_functions+0x9/0x24 echo "symonly" > /debugfs/tracing/iter_ctrl tracer: [ 81.479913] CPU 0: bash:3154 register_ftrace_function+0x5f/0x66 <-- _spin_unlock_irqrestore+0xe/0x5a [ 81.479913] CPU 0: bash:3154 _spin_unlock_irqrestore+0x3e/0x5a <-- sub_preempt_count+0xc/0x7a [ 81.479913] CPU 0: bash:3154 sub_preempt_count+0x30/0x7a <-- in_lock_functions+0x9/0x24 [ 81.479914] CPU 0: bash:3154 vfs_write+0x11d/0x155 <-- dnotify_parent+0x12/0x78 [ 81.479914] CPU 0: bash:3154 dnotify_parent+0x2d/0x78 <-- _spin_lock+0xe/0x70 [ 81.479914] CPU 0: bash:3154 _spin_lock+0x1b/0x70 <-- add_preempt_count+0xe/0x77 [ 81.479914] CPU 0: bash:3154 add_preempt_count+0x3e/0x77 <-- in_lock_functions+0x9/0x24 Signed-off-by: Steven Rostedt Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index ce70677..1399f37 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -8,3 +8,16 @@ config TRACING bool select DEBUG_FS +config FTRACE + bool "Kernel Function Tracer" + depends on DEBUG_KERNEL && HAVE_FTRACE + select FRAME_POINTER + select TRACING + help + Enable the kernel to trace every kernel function. This is done + by using a compiler feature to insert a small, 5-byte No-Operation + instruction to the beginning of every kernel function, which NOP + sequence is then dynamically patched into a tracer call when + tracing is enabled by the administrator. If it's runtime disabled + (the bootup default), then the overhead of the instructions is very + small and not measurable even in micro-benchmarks. diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 7af4031..6bb5e50 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_FTRACE) += libftrace.o obj-$(CONFIG_TRACING) += trace.o +obj-$(CONFIG_FTRACE) += trace_functions.o libftrace-y := ftrace.o diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c new file mode 100644 index 0000000..82988c5 --- /dev/null +++ b/kernel/trace/trace_functions.c @@ -0,0 +1,73 @@ +/* + * ring buffer based function tracer + * + * Copyright (C) 2007-2008 Steven Rostedt + * Copyright (C) 2008 Ingo Molnar + * + * Based on code from the latency_tracer, that is: + * + * Copyright (C) 2004-2006 Ingo Molnar + * Copyright (C) 2004 William Lee Irwin III + */ +#include +#include +#include +#include + +#include "trace.h" + +static notrace void function_reset(struct trace_array *tr) +{ + int cpu; + + tr->time_start = now(tr->cpu); + + for_each_online_cpu(cpu) + tracing_reset(tr->data[cpu]); +} + +static notrace void start_function_trace(struct trace_array *tr) +{ + function_reset(tr); + tracing_start_function_trace(); +} + +static notrace void stop_function_trace(struct trace_array *tr) +{ + tracing_stop_function_trace(); +} + +static notrace void function_trace_init(struct trace_array *tr) +{ + if (tr->ctrl) + start_function_trace(tr); +} + +static notrace void function_trace_reset(struct trace_array *tr) +{ + if (tr->ctrl) + stop_function_trace(tr); +} + +static notrace void function_trace_ctrl_update(struct trace_array *tr) +{ + if (tr->ctrl) + start_function_trace(tr); + else + stop_function_trace(tr); +} + +static struct tracer function_trace __read_mostly = +{ + .name = "ftrace", + .init = function_trace_init, + .reset = function_trace_reset, + .ctrl_update = function_trace_ctrl_update, +}; + +static __init int init_function_trace(void) +{ + return register_tracer(&function_trace); +} + +device_initcall(init_function_trace); -- cgit v0.10.2 From 35e8e302e5d6e32675df2fc1dd3a53dfa6630dc1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: add tracing of context switches This patch adds context switch tracing, of the format of: _------=> CPU# / _-----=> irqs-off | / _----=> need-resched || / _---=> hardirq/softirq ||| / _--=> preempt-depth |||| / ||||| delay cmd pid ||||| time | pid:prio:state \ / ||||| \ | / swapper-0 1d..3 137us+: 0:140:R --> 2912:120 sshd-2912 1d..3 216us+: 2912:120:S --> 0:140 swapper-0 1d..3 261us+: 0:140:R --> 2912:120 bash-2920 0d..3 267us+: 2920:120:S --> 0:140 sshd-2912 1d..3 330us!: 2912:120:S --> 0:140 swapper-0 1d..3 2389us+: 0:140:R --> 2847:120 yum-upda-2847 1d..3 2411us!: 2847:120:S --> 0:140 swapper-0 0d..3 11089us+: 0:140:R --> 3139:120 gdm-bina-3139 0d..3 11113us!: 3139:120:S --> 0:140 swapper-0 1d..3 102328us+: 0:140:R --> 2847:120 yum-upda-2847 1d..3 102348us!: 2847:120:S --> 0:140 "sched_switch" is added to /debugfs/tracing/available_tracers [ Eugene Teo Cc: Mathieu Desnoyers Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 1399f37..5d6aa92 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -13,6 +13,7 @@ config FTRACE depends on DEBUG_KERNEL && HAVE_FTRACE select FRAME_POINTER select TRACING + select CONTEXT_SWITCH_TRACER help Enable the kernel to trace every kernel function. This is done by using a compiler feature to insert a small, 5-byte No-Operation @@ -21,3 +22,13 @@ config FTRACE tracing is enabled by the administrator. If it's runtime disabled (the bootup default), then the overhead of the instructions is very small and not measurable even in micro-benchmarks. + +config CONTEXT_SWITCH_TRACER + bool "Trace process context switches" + depends on DEBUG_KERNEL + select TRACING + select MARKERS + help + This tracer gets called from the context switch and records + all switching of tasks. + diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 6bb5e50..6b54ceb 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_FTRACE) += libftrace.o obj-$(CONFIG_TRACING) += trace.o +obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o obj-$(CONFIG_FTRACE) += trace_functions.o libftrace-y := ftrace.o diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c new file mode 100644 index 0000000..3e4771d --- /dev/null +++ b/kernel/trace/trace_sched_switch.c @@ -0,0 +1,116 @@ +/* + * trace context switch + * + * Copyright (C) 2007 Steven Rostedt + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +static struct trace_array *ctx_trace; +static int __read_mostly tracer_enabled; + +static void notrace +ctx_switch_func(struct task_struct *prev, struct task_struct *next) +{ + struct trace_array *tr = ctx_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (!tracer_enabled) + return; + + raw_local_irq_save(flags); + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + tracing_sched_switch_trace(tr, data, prev, next, flags); + + atomic_dec(&data->disabled); + raw_local_irq_restore(flags); +} + +void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) +{ + tracing_record_cmdline(prev); + + /* + * If tracer_switch_func only points to the local + * switch func, it still needs the ptr passed to it. + */ + ctx_switch_func(prev, next); + + /* + * Chain to the wakeup tracer (this is a NOP if disabled): + */ + wakeup_sched_switch(prev, next); +} + +static notrace void sched_switch_reset(struct trace_array *tr) +{ + int cpu; + + tr->time_start = now(tr->cpu); + + for_each_online_cpu(cpu) + tracing_reset(tr->data[cpu]); +} + +static notrace void start_sched_trace(struct trace_array *tr) +{ + sched_switch_reset(tr); + tracer_enabled = 1; +} + +static notrace void stop_sched_trace(struct trace_array *tr) +{ + tracer_enabled = 0; +} + +static notrace void sched_switch_trace_init(struct trace_array *tr) +{ + ctx_trace = tr; + + if (tr->ctrl) + start_sched_trace(tr); +} + +static notrace void sched_switch_trace_reset(struct trace_array *tr) +{ + if (tr->ctrl) + stop_sched_trace(tr); +} + +static void sched_switch_trace_ctrl_update(struct trace_array *tr) +{ + /* When starting a new trace, reset the buffers */ + if (tr->ctrl) + start_sched_trace(tr); + else + stop_sched_trace(tr); +} + +static struct tracer sched_switch_trace __read_mostly = +{ + .name = "sched_switch", + .init = sched_switch_trace_init, + .reset = sched_switch_trace_reset, + .ctrl_update = sched_switch_trace_ctrl_update, +}; + +__init static int init_sched_switch_trace(void) +{ + return register_tracer(&sched_switch_trace); +} +device_initcall(init_sched_switch_trace); -- cgit v0.10.2 From 352ad25aa4a189c667cb2af333948d34692a2d27 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: tracer for scheduler wakeup latency This patch adds the tracer that tracks the wakeup latency of the highest priority waking task. "wakeup" is added to /debugfs/tracing/available_tracers Also added to /debugfs/tracing tracing_max_latency holds the current max latency for the wakeup wakeup_thresh if set to other than zero, a log will be recorded for every wakeup that takes longer than the number entered in here (usecs for all counters) (deletes previous trace) Examples: (with ftrace_enabled = 0) ============ preemption latency trace v1.1.5 on 2.6.24-rc8 Signed-off-by: Ingo Molnar -------------------------------------------------------------------- latency: 26 us, #2/2, CPU#1 | (M:rt VP:0, KP:0, SP:0 HP:0 #P:2) ----------------- | task: migration/0-3 (uid:0 nice:-5 policy:1 rt_prio:99) ----------------- _------=> CPU# / _-----=> irqs-off | / _----=> need-resched || / _---=> hardirq/softirq ||| / _--=> preempt-depth |||| / ||||| delay cmd pid ||||| time | caller \ / ||||| \ | / quilt-8551 0d..3 0us+: wake_up_process+0x15/0x17 (sched_exec+0xc9/0x100 ) quilt-8551 0d..4 26us : sched_switch_callback+0x73/0x81 (schedule+0x483/0x6d5 ) vim:ft=help ============ (with ftrace_enabled = 1) ============ preemption latency trace v1.1.5 on 2.6.24-rc8 -------------------------------------------------------------------- latency: 36 us, #45/45, CPU#0 | (M:rt VP:0, KP:0, SP:0 HP:0 #P:2) ----------------- | task: migration/1-5 (uid:0 nice:-5 policy:1 rt_prio:99) ----------------- _------=> CPU# / _-----=> irqs-off | / _----=> need-resched || / _---=> hardirq/softirq ||| / _--=> preempt-depth |||| / ||||| delay cmd pid ||||| time | caller \ / ||||| \ | / bash-10653 1d..3 0us : wake_up_process+0x15/0x17 (sched_exec+0xc9/0x100 ) bash-10653 1d..3 1us : try_to_wake_up+0x271/0x2e7 (sub_preempt_count+0xc/0x7a ) bash-10653 1d..2 2us : try_to_wake_up+0x296/0x2e7 (update_rq_clock+0x9/0x20 ) bash-10653 1d..2 2us : update_rq_clock+0x1e/0x20 (__update_rq_clock+0xc/0x90 ) bash-10653 1d..2 3us : __update_rq_clock+0x1b/0x90 (sched_clock+0x9/0x29 ) bash-10653 1d..2 4us : try_to_wake_up+0x2a6/0x2e7 (activate_task+0xc/0x3f ) bash-10653 1d..2 4us : activate_task+0x2d/0x3f (enqueue_task+0xe/0x66 ) bash-10653 1d..2 5us : enqueue_task+0x5b/0x66 (enqueue_task_rt+0x9/0x3c ) bash-10653 1d..2 6us : try_to_wake_up+0x2ba/0x2e7 (check_preempt_wakeup+0x12/0x99 ) [...] bash-10653 1d..5 33us : tracing_record_cmdline+0xcf/0xd4 (_spin_unlock+0x9/0x33 ) bash-10653 1d..5 34us : _spin_unlock+0x19/0x33 (sub_preempt_count+0xc/0x7a ) bash-10653 1d..4 35us : wakeup_sched_switch+0x65/0x2ff (_spin_lock_irqsave+0xc/0xa9 ) bash-10653 1d..4 35us : _spin_lock_irqsave+0x19/0xa9 (add_preempt_count+0xe/0x77 ) bash-10653 1d..4 36us : sched_switch_callback+0x73/0x81 (schedule+0x483/0x6d5 ) vim:ft=help ============ The [...] was added here to not waste your email box space. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b96ef14..db8a5e7 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -5,10 +5,6 @@ #include -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) -#define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1)) -#define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2)) - typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); struct ftrace_ops { @@ -35,4 +31,23 @@ extern void mcount(void); # define unregister_ftrace_function(ops) do { } while (0) # define clear_ftrace_function(ops) do { } while (0) #endif /* CONFIG_FTRACE */ + + +#ifdef CONFIG_FRAME_POINTER +/* TODO: need to fix this for ARM */ +# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1)) +# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2)) +# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3)) +# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4)) +# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5)) +#else +# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +# define CALLER_ADDR1 0UL +# define CALLER_ADDR2 0UL +# define CALLER_ADDR3 0UL +# define CALLER_ADDR4 0UL +# define CALLER_ADDR5 0UL +#endif + #endif /* _LINUX_FTRACE_H */ diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 5d6aa92..892ecc9 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -4,6 +4,9 @@ config HAVE_FTRACE bool +config TRACER_MAX_TRACE + bool + config TRACING bool select DEBUG_FS @@ -23,6 +26,16 @@ config FTRACE (the bootup default), then the overhead of the instructions is very small and not measurable even in micro-benchmarks. +config SCHED_TRACER + bool "Scheduling Latency Tracer" + depends on DEBUG_KERNEL + select TRACING + select CONTEXT_SWITCH_TRACER + select TRACER_MAX_TRACE + help + This tracer tracks the latency of the highest priority task + to be scheduled in, starting from the point it has woken up. + config CONTEXT_SWITCH_TRACER bool "Trace process context switches" depends on DEBUG_KERNEL diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 6b54ceb..5508cdb 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -3,5 +3,6 @@ obj-$(CONFIG_FTRACE) += libftrace.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o obj-$(CONFIG_FTRACE) += trace_functions.o +obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o libftrace-y := ftrace.o diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c new file mode 100644 index 0000000..7c3ccef --- /dev/null +++ b/kernel/trace/trace_sched_wakeup.c @@ -0,0 +1,310 @@ +/* + * trace task wakeup timings + * + * Copyright (C) 2007-2008 Steven Rostedt + * Copyright (C) 2008 Ingo Molnar + * + * Based on code from the latency_tracer, that is: + * + * Copyright (C) 2004-2006 Ingo Molnar + * Copyright (C) 2004 William Lee Irwin III + */ +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +static struct trace_array *wakeup_trace; +static int __read_mostly tracer_enabled; + +static struct task_struct *wakeup_task; +static int wakeup_cpu; +static unsigned wakeup_prio = -1; + +static DEFINE_SPINLOCK(wakeup_lock); + +static void notrace __wakeup_reset(struct trace_array *tr); + +/* + * Should this new latency be reported/recorded? + */ +static int notrace report_latency(cycle_t delta) +{ + if (tracing_thresh) { + if (delta < tracing_thresh) + return 0; + } else { + if (delta <= tracing_max_latency) + return 0; + } + return 1; +} + +void notrace +wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) +{ + unsigned long latency = 0, t0 = 0, t1 = 0; + struct trace_array *tr = wakeup_trace; + struct trace_array_cpu *data; + cycle_t T0, T1, delta; + unsigned long flags; + long disabled; + int cpu; + + if (unlikely(!tracer_enabled)) + return; + + /* + * When we start a new trace, we set wakeup_task to NULL + * and then set tracer_enabled = 1. We want to make sure + * that another CPU does not see the tracer_enabled = 1 + * and the wakeup_task with an older task, that might + * actually be the same as next. + */ + smp_rmb(); + + if (next != wakeup_task) + return; + + /* The task we are waitng for is waking up */ + data = tr->data[wakeup_cpu]; + + /* disable local data, not wakeup_cpu data */ + cpu = raw_smp_processor_id(); + disabled = atomic_inc_return(&tr->data[cpu]->disabled); + if (likely(disabled != 1)) + goto out; + + spin_lock_irqsave(&wakeup_lock, flags); + + /* We could race with grabbing wakeup_lock */ + if (unlikely(!tracer_enabled || next != wakeup_task)) + goto out_unlock; + + ftrace(tr, data, CALLER_ADDR1, CALLER_ADDR2, flags); + + /* + * usecs conversion is slow so we try to delay the conversion + * as long as possible: + */ + T0 = data->preempt_timestamp; + T1 = now(cpu); + delta = T1-T0; + + if (!report_latency(delta)) + goto out_unlock; + + latency = nsecs_to_usecs(delta); + + tracing_max_latency = delta; + t0 = nsecs_to_usecs(T0); + t1 = nsecs_to_usecs(T1); + + update_max_tr(tr, wakeup_task, wakeup_cpu); + + if (tracing_thresh) { + printk(KERN_INFO "(%16s-%-5d|#%d): %lu us wakeup latency " + "violates %lu us threshold.\n" + " => started at timestamp %lu: ", + wakeup_task->comm, wakeup_task->pid, + raw_smp_processor_id(), + latency, nsecs_to_usecs(tracing_thresh), t0); + } else { + printk(KERN_INFO "(%16s-%-5d|#%d): new %lu us maximum " + "wakeup latency.\n => started at timestamp %lu: ", + wakeup_task->comm, wakeup_task->pid, + cpu, latency, t0); + } + + printk(KERN_CONT " ended at timestamp %lu: ", t1); + dump_stack(); + t1 = nsecs_to_usecs(now(cpu)); + printk(KERN_CONT " dump-end timestamp %lu\n\n", t1); + +out_unlock: + __wakeup_reset(tr); + spin_unlock_irqrestore(&wakeup_lock, flags); +out: + atomic_dec(&tr->data[cpu]->disabled); +} + +static void notrace __wakeup_reset(struct trace_array *tr) +{ + struct trace_array_cpu *data; + int cpu; + + assert_spin_locked(&wakeup_lock); + + for_each_possible_cpu(cpu) { + data = tr->data[cpu]; + tracing_reset(data); + } + + wakeup_cpu = -1; + wakeup_prio = -1; + + if (wakeup_task) + put_task_struct(wakeup_task); + + wakeup_task = NULL; +} + +static void notrace wakeup_reset(struct trace_array *tr) +{ + unsigned long flags; + + spin_lock_irqsave(&wakeup_lock, flags); + __wakeup_reset(tr); + spin_unlock_irqrestore(&wakeup_lock, flags); +} + +static notrace void +wakeup_check_start(struct trace_array *tr, struct task_struct *p, + struct task_struct *curr) +{ + int cpu = smp_processor_id(); + unsigned long flags; + long disabled; + + if (likely(!rt_task(p)) || + p->prio >= wakeup_prio || + p->prio >= curr->prio) + return; + + disabled = atomic_inc_return(&tr->data[cpu]->disabled); + if (unlikely(disabled != 1)) + goto out; + + /* interrupts should be off from try_to_wake_up */ + spin_lock(&wakeup_lock); + + /* check for races. */ + if (!tracer_enabled || p->prio >= wakeup_prio) + goto out_locked; + + /* reset the trace */ + __wakeup_reset(tr); + + wakeup_cpu = task_cpu(p); + wakeup_prio = p->prio; + + wakeup_task = p; + get_task_struct(wakeup_task); + + local_save_flags(flags); + + tr->data[wakeup_cpu]->preempt_timestamp = now(cpu); + ftrace(tr, tr->data[wakeup_cpu], CALLER_ADDR1, CALLER_ADDR2, flags); + +out_locked: + spin_unlock(&wakeup_lock); +out: + atomic_dec(&tr->data[cpu]->disabled); +} + +notrace void +ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) +{ + if (likely(!tracer_enabled)) + return; + + wakeup_check_start(wakeup_trace, wakee, curr); +} + +notrace void +ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr) +{ + if (likely(!tracer_enabled)) + return; + + wakeup_check_start(wakeup_trace, wakee, curr); +} + +static notrace void start_wakeup_tracer(struct trace_array *tr) +{ + wakeup_reset(tr); + + /* + * Don't let the tracer_enabled = 1 show up before + * the wakeup_task is reset. This may be overkill since + * wakeup_reset does a spin_unlock after setting the + * wakeup_task to NULL, but I want to be safe. + * This is a slow path anyway. + */ + smp_wmb(); + + tracer_enabled = 1; + + return; +} + +static notrace void stop_wakeup_tracer(struct trace_array *tr) +{ + tracer_enabled = 0; +} + +static notrace void wakeup_tracer_init(struct trace_array *tr) +{ + wakeup_trace = tr; + + if (tr->ctrl) + start_wakeup_tracer(tr); +} + +static notrace void wakeup_tracer_reset(struct trace_array *tr) +{ + if (tr->ctrl) { + stop_wakeup_tracer(tr); + /* make sure we put back any tasks we are tracing */ + wakeup_reset(tr); + } +} + +static void wakeup_tracer_ctrl_update(struct trace_array *tr) +{ + if (tr->ctrl) + start_wakeup_tracer(tr); + else + stop_wakeup_tracer(tr); +} + +static void notrace wakeup_tracer_open(struct trace_iterator *iter) +{ + /* stop the trace while dumping */ + if (iter->tr->ctrl) + stop_wakeup_tracer(iter->tr); +} + +static void notrace wakeup_tracer_close(struct trace_iterator *iter) +{ + /* forget about any processes we were recording */ + if (iter->tr->ctrl) + start_wakeup_tracer(iter->tr); +} + +static struct tracer wakeup_tracer __read_mostly = +{ + .name = "wakeup", + .init = wakeup_tracer_init, + .reset = wakeup_tracer_reset, + .open = wakeup_tracer_open, + .close = wakeup_tracer_close, + .ctrl_update = wakeup_tracer_ctrl_update, + .print_max = 1, +}; + +__init static int init_wakeup_tracer(void) +{ + int ret; + + ret = register_tracer(&wakeup_tracer); + if (ret) + return ret; + + return 0; +} +device_initcall(init_wakeup_tracer); -- cgit v0.10.2 From 81d68a96a39844853b37f20cc8282d9b65b78ef3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: trace irq disabled critical timings This patch adds latency tracing for critical timings (how long interrupts are disabled for). "irqsoff" is added to /debugfs/tracing/available_tracers Note: tracing_max_latency also holds the max latency for irqsoff (in usecs). (default to large number so one must start latency tracing) tracing_thresh threshold (in usecs) to always print out if irqs off is detected to be longer than stated here. If irq_thresh is non-zero, then max_irq_latency is ignored. Here's an example of a trace with ftrace_enabled = 0 ======= preemption latency trace v1.1.5 on 2.6.24-rc7 Signed-off-by: Ingo Molnar -------------------------------------------------------------------- latency: 100 us, #3/3, CPU#1 | (M:rt VP:0, KP:0, SP:0 HP:0 #P:2) ----------------- | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0) ----------------- => started at: _spin_lock_irqsave+0x2a/0xb7 => ended at: _spin_unlock_irqrestore+0x32/0x5f _------=> CPU# / _-----=> irqs-off | / _----=> need-resched || / _---=> hardirq/softirq ||| / _--=> preempt-depth |||| / ||||| delay cmd pid ||||| time | caller \ / ||||| \ | / swapper-0 1d.s3 0us+: _spin_lock_irqsave+0x2a/0xb7 (e1000_update_stats+0x47/0x64c [e1000]) swapper-0 1d.s3 100us : _spin_unlock_irqrestore+0x32/0x5f (e1000_update_stats+0x641/0x64c [e1000]) swapper-0 1d.s3 100us : trace_hardirqs_on_caller+0x75/0x89 (_spin_unlock_irqrestore+0x32/0x5f) vim:ft=help ======= And this is a trace with ftrace_enabled == 1 ======= preemption latency trace v1.1.5 on 2.6.24-rc7 -------------------------------------------------------------------- latency: 102 us, #12/12, CPU#1 | (M:rt VP:0, KP:0, SP:0 HP:0 #P:2) ----------------- | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0) ----------------- => started at: _spin_lock_irqsave+0x2a/0xb7 => ended at: _spin_unlock_irqrestore+0x32/0x5f _------=> CPU# / _-----=> irqs-off | / _----=> need-resched || / _---=> hardirq/softirq ||| / _--=> preempt-depth |||| / ||||| delay cmd pid ||||| time | caller \ / ||||| \ | / swapper-0 1dNs3 0us+: _spin_lock_irqsave+0x2a/0xb7 (e1000_update_stats+0x47/0x64c [e1000]) swapper-0 1dNs3 46us : e1000_read_phy_reg+0x16/0x225 [e1000] (e1000_update_stats+0x5e2/0x64c [e1000]) swapper-0 1dNs3 46us : e1000_swfw_sync_acquire+0x10/0x99 [e1000] (e1000_read_phy_reg+0x49/0x225 [e1000]) swapper-0 1dNs3 46us : e1000_get_hw_eeprom_semaphore+0x12/0xa6 [e1000] (e1000_swfw_sync_acquire+0x36/0x99 [e1000]) swapper-0 1dNs3 47us : __const_udelay+0x9/0x47 (e1000_read_phy_reg+0x116/0x225 [e1000]) swapper-0 1dNs3 47us+: __delay+0x9/0x50 (__const_udelay+0x45/0x47) swapper-0 1dNs3 97us : preempt_schedule+0xc/0x84 (__delay+0x4e/0x50) swapper-0 1dNs3 98us : e1000_swfw_sync_release+0xc/0x55 [e1000] (e1000_read_phy_reg+0x211/0x225 [e1000]) swapper-0 1dNs3 99us+: e1000_put_hw_eeprom_semaphore+0x9/0x35 [e1000] (e1000_swfw_sync_release+0x50/0x55 [e1000]) swapper-0 1dNs3 101us : _spin_unlock_irqrestore+0xe/0x5f (e1000_update_stats+0x641/0x64c [e1000]) swapper-0 1dNs3 102us : _spin_unlock_irqrestore+0x32/0x5f (e1000_update_stats+0x641/0x64c [e1000]) swapper-0 1dNs3 102us : trace_hardirqs_on_caller+0x75/0x89 (_spin_unlock_irqrestore+0x32/0x5f) vim:ft=help ======= Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e2319f3..dd349c9 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -165,7 +165,10 @@ void cpu_idle(void) */ local_irq_disable(); enter_idle(); + /* Don't trace irqs off for idle */ + stop_critical_timings(); idle(); + start_critical_timings(); /* In many cases the interrupt that ended idle has already called exit_idle. But some idle loops can be woken up without interrupt. */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 76f60f5..84aa288 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_SMP) := msr-on-cpu.o lib-y := delay_$(BITS).o +lib-y += thunk_$(BITS).o lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o lib-y += memcpy_$(BITS).o diff --git a/arch/x86/lib/thunk_32.S b/arch/x86/lib/thunk_32.S new file mode 100644 index 0000000..650b11e --- /dev/null +++ b/arch/x86/lib/thunk_32.S @@ -0,0 +1,47 @@ +/* + * Trampoline to trace irqs off. (otherwise CALLER_ADDR1 might crash) + * Copyright 2008 by Steven Rostedt, Red Hat, Inc + * (inspired by Andi Kleen's thunk_64.S) + * Subject to the GNU public license, v.2. No warranty of any kind. + */ + + #include + +#define ARCH_TRACE_IRQS_ON \ + pushl %eax; \ + pushl %ecx; \ + pushl %edx; \ + call trace_hardirqs_on; \ + popl %edx; \ + popl %ecx; \ + popl %eax; + +#define ARCH_TRACE_IRQS_OFF \ + pushl %eax; \ + pushl %ecx; \ + pushl %edx; \ + call trace_hardirqs_off; \ + popl %edx; \ + popl %ecx; \ + popl %eax; + +#ifdef CONFIG_TRACE_IRQFLAGS + /* put return address in eax (arg1) */ + .macro thunk_ra name,func + .globl \name +\name: + pushl %eax + pushl %ecx + pushl %edx + /* Place EIP in the arg1 */ + movl 3*4(%esp), %eax + call \func + popl %edx + popl %ecx + popl %eax + ret + .endm + + thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller + thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller +#endif diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index e009251..bf9a7d5 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S @@ -2,6 +2,7 @@ * Save registers before calling assembly functions. This avoids * disturbance of register allocation in some inline assembly constructs. * Copyright 2001,2002 by Andi Kleen, SuSE Labs. + * Added trace_hardirqs callers - Copyright 2007 Steven Rostedt, Red Hat, Inc. * Subject to the GNU public license, v.2. No warranty of any kind. */ @@ -42,8 +43,22 @@ #endif #ifdef CONFIG_TRACE_IRQFLAGS - thunk trace_hardirqs_on_thunk,trace_hardirqs_on - thunk trace_hardirqs_off_thunk,trace_hardirqs_off + /* put return address in rdi (arg1) */ + .macro thunk_ra name,func + .globl \name +\name: + CFI_STARTPROC + SAVE_ARGS + /* SAVE_ARGS pushs 9 elements */ + /* the next element would be the rip */ + movq 9*8(%rsp), %rdi + call \func + jmp restore + CFI_ENDPROC + .endm + + thunk_ra trace_hardirqs_on_thunk,trace_hardirqs_on_caller + thunk_ra trace_hardirqs_off_thunk,trace_hardirqs_off_caller #endif #ifdef CONFIG_DEBUG_LOCK_ALLOC diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h index c242527..24d71b1 100644 --- a/include/asm-x86/irqflags.h +++ b/include/asm-x86/irqflags.h @@ -179,8 +179,6 @@ static inline void trace_hardirqs_fixup(void) * have a reliable stack. x86_64 only. */ #define SWAPGS_UNSAFE_STACK swapgs -#define ARCH_TRACE_IRQS_ON call trace_hardirqs_on_thunk -#define ARCH_TRACE_IRQS_OFF call trace_hardirqs_off_thunk #define ARCH_LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk #define ARCH_LOCKDEP_SYS_EXIT_IRQ \ TRACE_IRQS_ON; \ @@ -192,24 +190,6 @@ static inline void trace_hardirqs_fixup(void) TRACE_IRQS_OFF; #else -#define ARCH_TRACE_IRQS_ON \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call trace_hardirqs_on; \ - popl %edx; \ - popl %ecx; \ - popl %eax; - -#define ARCH_TRACE_IRQS_OFF \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call trace_hardirqs_off; \ - popl %edx; \ - popl %ecx; \ - popl %eax; - #define ARCH_LOCKDEP_SYS_EXIT \ pushl %eax; \ pushl %ecx; \ @@ -223,8 +203,8 @@ static inline void trace_hardirqs_fixup(void) #endif #ifdef CONFIG_TRACE_IRQFLAGS -# define TRACE_IRQS_ON ARCH_TRACE_IRQS_ON -# define TRACE_IRQS_OFF ARCH_TRACE_IRQS_OFF +# define TRACE_IRQS_ON call trace_hardirqs_on_thunk; +# define TRACE_IRQS_OFF call trace_hardirqs_off_thunk; #else # define TRACE_IRQS_ON # define TRACE_IRQS_OFF diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index db8a5e7..0a20445 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -50,4 +50,12 @@ extern void mcount(void); # define CALLER_ADDR5 0UL #endif +#ifdef CONFIG_IRQSOFF_TRACER + extern void notrace time_hardirqs_on(unsigned long a0, unsigned long a1); + extern void notrace time_hardirqs_off(unsigned long a0, unsigned long a1); +#else +# define time_hardirqs_on(a0, a1) do { } while (0) +# define time_hardirqs_off(a0, a1) do { } while (0) +#endif + #endif /* _LINUX_FTRACE_H */ diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index e600c4e..5b711d4 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -12,10 +12,10 @@ #define _LINUX_TRACE_IRQFLAGS_H #ifdef CONFIG_TRACE_IRQFLAGS - extern void trace_hardirqs_on(void); - extern void trace_hardirqs_off(void); extern void trace_softirqs_on(unsigned long ip); extern void trace_softirqs_off(unsigned long ip); + extern void trace_hardirqs_on(void); + extern void trace_hardirqs_off(void); # define trace_hardirq_context(p) ((p)->hardirq_context) # define trace_softirq_context(p) ((p)->softirq_context) # define trace_hardirqs_enabled(p) ((p)->hardirqs_enabled) @@ -41,6 +41,14 @@ # define INIT_TRACE_IRQFLAGS #endif +#ifdef CONFIG_IRQSOFF_TRACER + extern void stop_critical_timings(void); + extern void start_critical_timings(void); +#else +# define stop_critical_timings() do { } while (0) +# define start_critical_timings() do { } while (0) +#endif + #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT #include diff --git a/kernel/fork.c b/kernel/fork.c index 19908b2..d66d676 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -909,7 +909,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, rt_mutex_init_task(p); -#ifdef CONFIG_TRACE_IRQFLAGS +#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_LOCKDEP) DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); #endif diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 81a4e4a..e219243 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -982,7 +983,7 @@ check_noncircular(struct lock_class *source, unsigned int depth) return 1; } -#ifdef CONFIG_TRACE_IRQFLAGS +#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) /* * Forwards and backwards subgraph searching, for the purposes of * proving that two subgraphs can be connected by a new dependency @@ -1680,7 +1681,7 @@ valid_state(struct task_struct *curr, struct held_lock *this, static int mark_lock(struct task_struct *curr, struct held_lock *this, enum lock_usage_bit new_bit); -#ifdef CONFIG_TRACE_IRQFLAGS +#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) /* * print irq inversion bug: @@ -2013,11 +2014,13 @@ void early_boot_irqs_on(void) /* * Hardirqs will be enabled: */ -void trace_hardirqs_on(void) +void notrace trace_hardirqs_on_caller(unsigned long a0) { struct task_struct *curr = current; unsigned long ip; + time_hardirqs_on(CALLER_ADDR0, a0); + if (unlikely(!debug_locks || current->lockdep_recursion)) return; @@ -2055,16 +2058,23 @@ void trace_hardirqs_on(void) curr->hardirq_enable_event = ++curr->irq_events; debug_atomic_inc(&hardirqs_on_events); } +EXPORT_SYMBOL(trace_hardirqs_on_caller); +void notrace trace_hardirqs_on(void) +{ + trace_hardirqs_on_caller(CALLER_ADDR0); +} EXPORT_SYMBOL(trace_hardirqs_on); /* * Hardirqs were disabled: */ -void trace_hardirqs_off(void) +void notrace trace_hardirqs_off_caller(unsigned long a0) { struct task_struct *curr = current; + time_hardirqs_off(CALLER_ADDR0, a0); + if (unlikely(!debug_locks || current->lockdep_recursion)) return; @@ -2082,7 +2092,12 @@ void trace_hardirqs_off(void) } else debug_atomic_inc(&redundant_hardirqs_off); } +EXPORT_SYMBOL(trace_hardirqs_off_caller); +void notrace trace_hardirqs_off(void) +{ + trace_hardirqs_off_caller(CALLER_ADDR0); +} EXPORT_SYMBOL(trace_hardirqs_off); /* diff --git a/kernel/printk.c b/kernel/printk.c index 8fb01c3..ae7d5b9 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1041,7 +1041,9 @@ void release_console_sem(void) _log_end = log_end; con_start = log_end; /* Flush */ spin_unlock(&logbuf_lock); + stop_critical_timings(); /* don't trace print latency */ call_console_drivers(_con_start, _log_end); + start_critical_timings(); local_irq_restore(flags); } console_locked = 0; diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 892ecc9..896df1c 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -26,6 +26,24 @@ config FTRACE (the bootup default), then the overhead of the instructions is very small and not measurable even in micro-benchmarks. +config IRQSOFF_TRACER + bool "Interrupts-off Latency Tracer" + default n + depends on TRACE_IRQFLAGS_SUPPORT + depends on GENERIC_TIME + select TRACE_IRQFLAGS + select TRACING + select TRACER_MAX_TRACE + help + This option measures the time spent in irqs-off critical + sections, with microsecond accuracy. + + The default measurement method is a maximum search, which is + disabled by default and can be runtime (re-)started + via: + + echo 0 > /debugfs/tracing/tracing_max_latency + config SCHED_TRACER bool "Scheduling Latency Tracer" depends on DEBUG_KERNEL diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 5508cdb..46be864 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_FTRACE) += libftrace.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o obj-$(CONFIG_FTRACE) += trace_functions.o +obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o libftrace-y := ftrace.o diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c new file mode 100644 index 0000000..a9131b0 --- /dev/null +++ b/kernel/trace/trace_irqsoff.c @@ -0,0 +1,402 @@ +/* + * trace irqs off criticall timings + * + * Copyright (C) 2007-2008 Steven Rostedt + * Copyright (C) 2008 Ingo Molnar + * + * From code in the latency_tracer, that is: + * + * Copyright (C) 2004-2006 Ingo Molnar + * Copyright (C) 2004 William Lee Irwin III + */ +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +static struct trace_array *irqsoff_trace __read_mostly; +static int tracer_enabled __read_mostly; + +/* + * Sequence count - we record it when starting a measurement and + * skip the latency if the sequence has changed - some other section + * did a maximum and could disturb our measurement with serial console + * printouts, etc. Truly coinciding maximum latencies should be rare + * and what happens together happens separately as well, so this doesnt + * decrease the validity of the maximum found: + */ +static __cacheline_aligned_in_smp unsigned long max_sequence; + +#ifdef CONFIG_FTRACE +/* + * irqsoff uses its own tracer function to keep the overhead down: + */ +static void notrace +irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) +{ + struct trace_array *tr = irqsoff_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (likely(!tracer_enabled)) + return; + + local_save_flags(flags); + + if (!irqs_disabled_flags(flags)) + return; + + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + ftrace(tr, data, ip, parent_ip, flags); + + atomic_dec(&data->disabled); +} + +static struct ftrace_ops trace_ops __read_mostly = +{ + .func = irqsoff_tracer_call, +}; +#endif /* CONFIG_FTRACE */ + +/* + * Should this new latency be reported/recorded? + */ +static int notrace report_latency(cycle_t delta) +{ + if (tracing_thresh) { + if (delta < tracing_thresh) + return 0; + } else { + if (delta <= tracing_max_latency) + return 0; + } + return 1; +} + +static void notrace +check_critical_timing(struct trace_array *tr, + struct trace_array_cpu *data, + unsigned long parent_ip, + int cpu) +{ + unsigned long latency, t0, t1; + cycle_t T0, T1, T2, delta; + unsigned long flags; + + /* + * usecs conversion is slow so we try to delay the conversion + * as long as possible: + */ + T0 = data->preempt_timestamp; + T1 = now(cpu); + delta = T1-T0; + + local_save_flags(flags); + + if (!report_latency(delta)) + goto out; + + ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); + /* + * Update the timestamp, because the trace entry above + * might change it (it can only get larger so the latency + * is fair to be reported): + */ + T2 = now(cpu); + + delta = T2-T0; + + latency = nsecs_to_usecs(delta); + + if (data->critical_sequence != max_sequence) + goto out; + + tracing_max_latency = delta; + t0 = nsecs_to_usecs(T0); + t1 = nsecs_to_usecs(T1); + + data->critical_end = parent_ip; + + update_max_tr_single(tr, current, cpu); + + if (tracing_thresh) + printk(KERN_INFO "(%16s-%-5d|#%d): %lu us critical section " + "violates %lu us threshold.\n" + " => started at timestamp %lu: ", + current->comm, current->pid, + raw_smp_processor_id(), + latency, nsecs_to_usecs(tracing_thresh), t0); + else + printk(KERN_INFO "(%16s-%-5d|#%d):" + " new %lu us maximum-latency " + "critical section.\n => started at timestamp %lu: ", + current->comm, current->pid, + raw_smp_processor_id(), + latency, t0); + + print_symbol(KERN_CONT "<%s>\n", data->critical_start); + printk(KERN_CONT " => ended at timestamp %lu: ", t1); + print_symbol(KERN_CONT "<%s>\n", data->critical_end); + dump_stack(); + t1 = nsecs_to_usecs(now(cpu)); + printk(KERN_CONT " => dump-end timestamp %lu\n\n", t1); + + max_sequence++; + +out: + data->critical_sequence = max_sequence; + data->preempt_timestamp = now(cpu); + tracing_reset(data); + ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); +} + +static inline void notrace +start_critical_timing(unsigned long ip, unsigned long parent_ip) +{ + int cpu; + struct trace_array *tr = irqsoff_trace; + struct trace_array_cpu *data; + unsigned long flags; + + if (likely(!tracer_enabled)) + return; + + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + + if (unlikely(!data) || unlikely(!data->trace) || + data->critical_start || atomic_read(&data->disabled)) + return; + + atomic_inc(&data->disabled); + + data->critical_sequence = max_sequence; + data->preempt_timestamp = now(cpu); + data->critical_start = parent_ip; + tracing_reset(data); + + local_save_flags(flags); + ftrace(tr, data, ip, parent_ip, flags); + + atomic_dec(&data->disabled); +} + +static inline void notrace +stop_critical_timing(unsigned long ip, unsigned long parent_ip) +{ + int cpu; + struct trace_array *tr = irqsoff_trace; + struct trace_array_cpu *data; + unsigned long flags; + + if (likely(!tracer_enabled)) + return; + + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + + if (unlikely(!data) || unlikely(!data->trace) || + !data->critical_start || atomic_read(&data->disabled)) + return; + + atomic_inc(&data->disabled); + local_save_flags(flags); + ftrace(tr, data, ip, parent_ip, flags); + check_critical_timing(tr, data, parent_ip, cpu); + data->critical_start = 0; + atomic_dec(&data->disabled); +} + +void notrace start_critical_timings(void) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); +} + +void notrace stop_critical_timings(void) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); +} + +#ifdef CONFIG_PROVE_LOCKING +void notrace time_hardirqs_on(unsigned long a0, unsigned long a1) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + stop_critical_timing(a0, a1); +} + +void notrace time_hardirqs_off(unsigned long a0, unsigned long a1) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + start_critical_timing(a0, a1); +} + +#else /* !CONFIG_PROVE_LOCKING */ + +/* + * Stubs: + */ + +void early_boot_irqs_off(void) +{ +} + +void early_boot_irqs_on(void) +{ +} + +void trace_softirqs_on(unsigned long ip) +{ +} + +void trace_softirqs_off(unsigned long ip) +{ +} + +inline void print_irqtrace_events(struct task_struct *curr) +{ +} + +/* + * We are only interested in hardirq on/off events: + */ +void notrace trace_hardirqs_on(void) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); +} +EXPORT_SYMBOL(trace_hardirqs_on); + +void notrace trace_hardirqs_off(void) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); +} +EXPORT_SYMBOL(trace_hardirqs_off); + +void notrace trace_hardirqs_on_caller(unsigned long caller_addr) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + stop_critical_timing(CALLER_ADDR0, caller_addr); +} +EXPORT_SYMBOL(trace_hardirqs_on_caller); + +void notrace trace_hardirqs_off_caller(unsigned long caller_addr) +{ + unsigned long flags; + + local_save_flags(flags); + + if (irqs_disabled_flags(flags)) + start_critical_timing(CALLER_ADDR0, caller_addr); +} +EXPORT_SYMBOL(trace_hardirqs_off_caller); + +#endif /* CONFIG_PROVE_LOCKING */ + +static void start_irqsoff_tracer(struct trace_array *tr) +{ + tracer_enabled = 1; + register_ftrace_function(&trace_ops); +} + +static void stop_irqsoff_tracer(struct trace_array *tr) +{ + unregister_ftrace_function(&trace_ops); + tracer_enabled = 0; +} + +static void irqsoff_tracer_init(struct trace_array *tr) +{ + irqsoff_trace = tr; + /* make sure that the tracer is visibel */ + smp_wmb(); + + if (tr->ctrl) + start_irqsoff_tracer(tr); +} + +static void irqsoff_tracer_reset(struct trace_array *tr) +{ + if (tr->ctrl) + stop_irqsoff_tracer(tr); +} + +static void irqsoff_tracer_ctrl_update(struct trace_array *tr) +{ + if (tr->ctrl) + start_irqsoff_tracer(tr); + else + stop_irqsoff_tracer(tr); +} + +static void notrace irqsoff_tracer_open(struct trace_iterator *iter) +{ + /* stop the trace while dumping */ + if (iter->tr->ctrl) + stop_irqsoff_tracer(iter->tr); +} + +static void notrace irqsoff_tracer_close(struct trace_iterator *iter) +{ + if (iter->tr->ctrl) + start_irqsoff_tracer(iter->tr); +} + +static struct tracer irqsoff_tracer __read_mostly = +{ + .name = "irqsoff", + .init = irqsoff_tracer_init, + .reset = irqsoff_tracer_reset, + .open = irqsoff_tracer_open, + .close = irqsoff_tracer_close, + .ctrl_update = irqsoff_tracer_ctrl_update, + .print_max = 1, +}; + +__init static int init_irqsoff_tracer(void) +{ + register_tracer(&irqsoff_tracer); + + return 0; +} +device_initcall(init_irqsoff_tracer); -- cgit v0.10.2 From 6cd8a4bb2f97527a9ceb30bc77ea4e959c6a95e3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: trace preempt off critical timings Add preempt off timings. A lot of kernel core code is taken from the RT patch latency trace that was written by Ingo Molnar. This adds "preemptoff" and "preemptirqsoff" to /debugfs/tracing/available_tracers Now instead of just tracing irqs off, preemption off can be selected to be recorded. When this is selected, it shares the same files as irqs off timings. One can either trace preemption off, irqs off, or one or the other off. By echoing "preemptoff" into /debugfs/tracing/current_tracer, recording of preempt off only is performed. "irqsoff" will only record the time irqs are disabled, but "preemptirqsoff" will take the total time irqs or preemption are disabled. Runtime switching of these options is now supported by simpling echoing in the appropriate trace name into /debugfs/tracing/current_tracer. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f8476df..a30aa1f 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -185,7 +185,10 @@ void cpu_idle(void) local_irq_disable(); __get_cpu_var(irq_stat).idle_timestamp = jiffies; + /* Don't trace irqs off for idle */ + stop_critical_timings(); idle(); + start_critical_timings(); } tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 0a20445..740c97d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -58,4 +58,12 @@ extern void mcount(void); # define time_hardirqs_off(a0, a1) do { } while (0) #endif +#ifdef CONFIG_PREEMPT_TRACER + extern void notrace trace_preempt_on(unsigned long a0, unsigned long a1); + extern void notrace trace_preempt_off(unsigned long a0, unsigned long a1); +#else +# define trace_preempt_on(a0, a1) do { } while (0) +# define trace_preempt_off(a0, a1) do { } while (0) +#endif + #endif /* _LINUX_FTRACE_H */ diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 5b711d4..2b1c2e5 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -41,7 +41,8 @@ # define INIT_TRACE_IRQFLAGS #endif -#ifdef CONFIG_IRQSOFF_TRACER +#if defined(CONFIG_IRQSOFF_TRACER) || \ + defined(CONFIG_PREEMPT_TRACER) extern void stop_critical_timings(void); extern void start_critical_timings(void); #else diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 36b03d5..72b1a10 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -10,7 +10,7 @@ #include #include -#ifdef CONFIG_DEBUG_PREEMPT +#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER) extern void add_preempt_count(int val); extern void sub_preempt_count(int val); #else diff --git a/kernel/sched.c b/kernel/sched.c index 73e6008..328494e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include @@ -4365,26 +4366,44 @@ void scheduler_tick(void) #endif } -#if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT) +#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ + defined(CONFIG_PREEMPT_TRACER)) + +static inline unsigned long get_parent_ip(unsigned long addr) +{ + if (in_lock_functions(addr)) { + addr = CALLER_ADDR2; + if (in_lock_functions(addr)) + addr = CALLER_ADDR3; + } + return addr; +} void __kprobes add_preempt_count(int val) { +#ifdef CONFIG_DEBUG_PREEMPT /* * Underflow? */ if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0))) return; +#endif preempt_count() += val; +#ifdef CONFIG_DEBUG_PREEMPT /* * Spinlock count overflowing soon? */ DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >= PREEMPT_MASK - 10); +#endif + if (preempt_count() == val) + trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); } EXPORT_SYMBOL(add_preempt_count); void __kprobes sub_preempt_count(int val) { +#ifdef CONFIG_DEBUG_PREEMPT /* * Underflow? */ @@ -4396,7 +4415,10 @@ void __kprobes sub_preempt_count(int val) if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) && !(preempt_count() & PREEMPT_MASK))) return; +#endif + if (preempt_count() == val) + trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); preempt_count() -= val; } EXPORT_SYMBOL(sub_preempt_count); diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 896df1c..6430016 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -44,6 +44,31 @@ config IRQSOFF_TRACER echo 0 > /debugfs/tracing/tracing_max_latency + (Note that kernel size and overhead increases with this option + enabled. This option and the preempt-off timing option can be + used together or separately.) + +config PREEMPT_TRACER + bool "Preemption-off Latency Tracer" + default n + depends on GENERIC_TIME + depends on PREEMPT + select TRACING + select TRACER_MAX_TRACE + help + This option measures the time spent in preemption off critical + sections, with microsecond accuracy. + + The default measurement method is a maximum search, which is + disabled by default and can be runtime (re-)started + via: + + echo 0 > /debugfs/tracing/tracing_max_latency + + (Note that kernel size and overhead increases with this option + enabled. This option and the irqs-off timing option can be + used together or separately.) + config SCHED_TRACER bool "Scheduling Latency Tracer" depends on DEBUG_KERNEL diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 46be864..3fec653 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o obj-$(CONFIG_FTRACE) += trace_functions.o obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o +obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o libftrace-y := ftrace.o diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index a9131b0..8b12316 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -21,6 +21,36 @@ static struct trace_array *irqsoff_trace __read_mostly; static int tracer_enabled __read_mostly; +static DEFINE_PER_CPU(int, tracing_cpu); + +enum { + TRACER_IRQS_OFF = (1 << 1), + TRACER_PREEMPT_OFF = (1 << 2), +}; + +static int trace_type __read_mostly; + +#ifdef CONFIG_PREEMPT_TRACER +static inline int notrace +preempt_trace(void) +{ + return ((trace_type & TRACER_PREEMPT_OFF) && preempt_count()); +} +#else +# define preempt_trace() (0) +#endif + +#ifdef CONFIG_IRQSOFF_TRACER +static inline int notrace +irq_trace(void) +{ + return ((trace_type & TRACER_IRQS_OFF) && + irqs_disabled()); +} +#else +# define irq_trace() (0) +#endif + /* * Sequence count - we record it when starting a measurement and * skip the latency if the sequence has changed - some other section @@ -44,14 +74,11 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) long disabled; int cpu; - if (likely(!tracer_enabled)) + if (likely(!__get_cpu_var(tracing_cpu))) return; local_save_flags(flags); - if (!irqs_disabled_flags(flags)) - return; - cpu = raw_smp_processor_id(); data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); @@ -171,23 +198,29 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) if (likely(!tracer_enabled)) return; + if (__get_cpu_var(tracing_cpu)) + return; + cpu = raw_smp_processor_id(); data = tr->data[cpu]; if (unlikely(!data) || unlikely(!data->trace) || - data->critical_start || atomic_read(&data->disabled)) + atomic_read(&data->disabled)) return; atomic_inc(&data->disabled); data->critical_sequence = max_sequence; data->preempt_timestamp = now(cpu); - data->critical_start = parent_ip; + data->critical_start = parent_ip ? : ip; tracing_reset(data); local_save_flags(flags); + ftrace(tr, data, ip, parent_ip, flags); + __get_cpu_var(tracing_cpu) = 1; + atomic_dec(&data->disabled); } @@ -199,7 +232,13 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) struct trace_array_cpu *data; unsigned long flags; - if (likely(!tracer_enabled)) + /* Always clear the tracing cpu on stopping the trace */ + if (unlikely(__get_cpu_var(tracing_cpu))) + __get_cpu_var(tracing_cpu) = 0; + else + return; + + if (!tracer_enabled) return; cpu = raw_smp_processor_id(); @@ -212,49 +251,35 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) atomic_inc(&data->disabled); local_save_flags(flags); ftrace(tr, data, ip, parent_ip, flags); - check_critical_timing(tr, data, parent_ip, cpu); + check_critical_timing(tr, data, parent_ip ? : ip, cpu); data->critical_start = 0; atomic_dec(&data->disabled); } +/* start and stop critical timings used to for stoppage (in idle) */ void notrace start_critical_timings(void) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (preempt_trace() || irq_trace()) start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } void notrace stop_critical_timings(void) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (preempt_trace() || irq_trace()) stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } +#ifdef CONFIG_IRQSOFF_TRACER #ifdef CONFIG_PROVE_LOCKING void notrace time_hardirqs_on(unsigned long a0, unsigned long a1) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (!preempt_trace() && irq_trace()) stop_critical_timing(a0, a1); } void notrace time_hardirqs_off(unsigned long a0, unsigned long a1) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (!preempt_trace() && irq_trace()) start_critical_timing(a0, a1); } @@ -289,49 +314,46 @@ inline void print_irqtrace_events(struct task_struct *curr) */ void notrace trace_hardirqs_on(void) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (!preempt_trace() && irq_trace()) stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } EXPORT_SYMBOL(trace_hardirqs_on); void notrace trace_hardirqs_off(void) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (!preempt_trace() && irq_trace()) start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } EXPORT_SYMBOL(trace_hardirqs_off); void notrace trace_hardirqs_on_caller(unsigned long caller_addr) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (!preempt_trace() && irq_trace()) stop_critical_timing(CALLER_ADDR0, caller_addr); } EXPORT_SYMBOL(trace_hardirqs_on_caller); void notrace trace_hardirqs_off_caller(unsigned long caller_addr) { - unsigned long flags; - - local_save_flags(flags); - - if (irqs_disabled_flags(flags)) + if (!preempt_trace() && irq_trace()) start_critical_timing(CALLER_ADDR0, caller_addr); } EXPORT_SYMBOL(trace_hardirqs_off_caller); #endif /* CONFIG_PROVE_LOCKING */ +#endif /* CONFIG_IRQSOFF_TRACER */ + +#ifdef CONFIG_PREEMPT_TRACER +void notrace trace_preempt_on(unsigned long a0, unsigned long a1) +{ + stop_critical_timing(a0, a1); +} + +void notrace trace_preempt_off(unsigned long a0, unsigned long a1) +{ + start_critical_timing(a0, a1); +} +#endif /* CONFIG_PREEMPT_TRACER */ static void start_irqsoff_tracer(struct trace_array *tr) { @@ -345,7 +367,7 @@ static void stop_irqsoff_tracer(struct trace_array *tr) tracer_enabled = 0; } -static void irqsoff_tracer_init(struct trace_array *tr) +static void __irqsoff_tracer_init(struct trace_array *tr) { irqsoff_trace = tr; /* make sure that the tracer is visibel */ @@ -382,6 +404,13 @@ static void notrace irqsoff_tracer_close(struct trace_iterator *iter) start_irqsoff_tracer(iter->tr); } +#ifdef CONFIG_IRQSOFF_TRACER +static void irqsoff_tracer_init(struct trace_array *tr) +{ + trace_type = TRACER_IRQS_OFF; + + __irqsoff_tracer_init(tr); +} static struct tracer irqsoff_tracer __read_mostly = { .name = "irqsoff", @@ -392,10 +421,65 @@ static struct tracer irqsoff_tracer __read_mostly = .ctrl_update = irqsoff_tracer_ctrl_update, .print_max = 1, }; +# define register_irqsoff(trace) register_tracer(&trace) +#else +# define register_irqsoff(trace) do { } while (0) +#endif + +#ifdef CONFIG_PREEMPT_TRACER +static void preemptoff_tracer_init(struct trace_array *tr) +{ + trace_type = TRACER_PREEMPT_OFF; + + __irqsoff_tracer_init(tr); +} + +static struct tracer preemptoff_tracer __read_mostly = +{ + .name = "preemptoff", + .init = preemptoff_tracer_init, + .reset = irqsoff_tracer_reset, + .open = irqsoff_tracer_open, + .close = irqsoff_tracer_close, + .ctrl_update = irqsoff_tracer_ctrl_update, + .print_max = 1, +}; +# define register_preemptoff(trace) register_tracer(&trace) +#else +# define register_preemptoff(trace) do { } while (0) +#endif + +#if defined(CONFIG_IRQSOFF_TRACER) && \ + defined(CONFIG_PREEMPT_TRACER) + +static void preemptirqsoff_tracer_init(struct trace_array *tr) +{ + trace_type = TRACER_IRQS_OFF | TRACER_PREEMPT_OFF; + + __irqsoff_tracer_init(tr); +} + +static struct tracer preemptirqsoff_tracer __read_mostly = +{ + .name = "preemptirqsoff", + .init = preemptirqsoff_tracer_init, + .reset = irqsoff_tracer_reset, + .open = irqsoff_tracer_open, + .close = irqsoff_tracer_close, + .ctrl_update = irqsoff_tracer_ctrl_update, + .print_max = 1, +}; + +# define register_preemptirqsoff(trace) register_tracer(&trace) +#else +# define register_preemptirqsoff(trace) do { } while (0) +#endif __init static int init_irqsoff_tracer(void) { - register_tracer(&irqsoff_tracer); + register_irqsoff(irqsoff_tracer); + register_preemptoff(preemptoff_tracer); + register_preemptirqsoff(preemptirqsoff_tracer); return 0; } -- cgit v0.10.2 From 3d0833953e1b98b79ddf491dd49229eef9baeac1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:42 +0200 Subject: ftrace: dynamic enabling/disabling of function calls This patch adds a feature to dynamically replace the ftrace code with the jmps to allow a kernel with ftrace configured to run as fast as it can without it configured. The way this works, is on bootup (if ftrace is enabled), a ftrace function is registered to record the instruction pointer of all places that call the function. Later, if there's still any code to patch, a kthread is awoken (rate limited to at most once a second) that performs a stop_machine, and replaces all the code that was called with a jmp over the call to ftrace. It only replaces what was found the previous time. Typically the system reaches equilibrium quickly after bootup and there's no code patching needed at all. e.g. call ftrace /* 5 bytes */ is replaced with jmp 3f /* jmp is 2 bytes and we jump 3 forward */ 3: When we want to enable ftrace for function tracing, the IP recording is removed, and stop_machine is called again to replace all the locations of that were recorded back to the call of ftrace. When it is disabled, we replace the code back to the jmp. Allocation is done by the kthread. If the ftrace recording function is called, and we don't have any record slots available, then we simply skip that call. Once a second a new page (if needed) is allocated for recording new ftrace function calls. A large batch is allocated at boot up to get most of the calls there. Because we do this via stop_machine, we don't have to worry about another CPU executing a ftrace call as we modify it. But we do need to worry about NMI's so all functions that might be called via nmi must be annotated with notrace_nmi. When this code is configured in, the NMI code will not call notrace. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 5e618c3..e142091 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic_$(BITS).o nmi_$(BITS).o obj-$(CONFIG_X86_IO_APIC) += io_apic_$(BITS).o obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c new file mode 100644 index 0000000..5dd5813 --- /dev/null +++ b/arch/x86/kernel/ftrace.c @@ -0,0 +1,237 @@ +/* + * Code for replacing ftrace calls with jumps. + * + * Copyright (C) 2007-2008 Steven Rostedt + * + * Thanks goes to Ingo Molnar, for suggesting the idea. + * Mathieu Desnoyers, for suggesting postponing the modifications. + * Arjan van de Ven, for keeping me straight, and explaining to me + * the dangers of modifying code on the run. + */ + +#include +#include +#include +#include +#include +#include + +#define CALL_BACK 5 + +#define JMPFWD 0x03eb + +static unsigned short ftrace_jmp = JMPFWD; + +struct ftrace_record { + struct dyn_ftrace rec; + int failed; +} __attribute__((packed)); + +struct ftrace_page { + struct ftrace_page *next; + int index; + struct ftrace_record records[]; +} __attribute__((packed)); + +#define ENTRIES_PER_PAGE \ + ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct ftrace_record)) + +/* estimate from running different kernels */ +#define NR_TO_INIT 10000 + +#define MCOUNT_ADDR ((long)(&mcount)) + +union ftrace_code_union { + char code[5]; + struct { + char e8; + int offset; + } __attribute__((packed)); +}; + +static struct ftrace_page *ftrace_pages_start; +static struct ftrace_page *ftrace_pages; + +notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip) +{ + struct ftrace_record *rec; + unsigned short save; + + ip -= CALL_BACK; + save = *(short *)ip; + + /* If this was already converted, skip it */ + if (save == JMPFWD) + return NULL; + + if (ftrace_pages->index == ENTRIES_PER_PAGE) { + if (!ftrace_pages->next) + return NULL; + ftrace_pages = ftrace_pages->next; + } + + rec = &ftrace_pages->records[ftrace_pages->index++]; + + return &rec->rec; +} + +static int notrace +ftrace_modify_code(unsigned long ip, unsigned char *old_code, + unsigned char *new_code) +{ + unsigned short old = *(unsigned short *)old_code; + unsigned short new = *(unsigned short *)new_code; + unsigned short replaced; + int faulted = 0; + + /* + * Note: Due to modules and __init, code can + * disappear and change, we need to protect against faulting + * as well as code changing. + * + * No real locking needed, this code is run through + * kstop_machine. + */ + asm volatile ( + "1: lock\n" + " cmpxchg %w3, (%2)\n" + "2:\n" + ".section .fixup, \"ax\"\n" + " movl $1, %0\n" + "3: jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) + : "=r"(faulted), "=a"(replaced) + : "r"(ip), "r"(new), "0"(faulted), "a"(old) + : "memory"); + sync_core(); + + if (replaced != old) + faulted = 2; + + return faulted; +} + +static int notrace ftrace_calc_offset(long ip) +{ + return (int)(MCOUNT_ADDR - ip); +} + +notrace void ftrace_code_disable(struct dyn_ftrace *rec) +{ + unsigned long ip; + union ftrace_code_union save; + struct ftrace_record *r = + container_of(rec, struct ftrace_record, rec); + + ip = rec->ip; + + save.e8 = 0xe8; + save.offset = ftrace_calc_offset(ip); + + /* move the IP back to the start of the call */ + ip -= CALL_BACK; + + r->failed = ftrace_modify_code(ip, save.code, (char *)&ftrace_jmp); +} + +static void notrace ftrace_replace_code(int saved) +{ + unsigned char *new = NULL, *old = NULL; + struct ftrace_record *rec; + struct ftrace_page *pg; + unsigned long ip; + int i; + + if (saved) + old = (char *)&ftrace_jmp; + else + new = (char *)&ftrace_jmp; + + for (pg = ftrace_pages_start; pg; pg = pg->next) { + for (i = 0; i < pg->index; i++) { + union ftrace_code_union calc; + rec = &pg->records[i]; + + /* don't modify code that has already faulted */ + if (rec->failed) + continue; + + ip = rec->rec.ip; + + calc.e8 = 0xe8; + calc.offset = ftrace_calc_offset(ip); + + if (saved) + new = calc.code; + else + old = calc.code; + + ip -= CALL_BACK; + + rec->failed = ftrace_modify_code(ip, old, new); + } + } + +} + +notrace void ftrace_startup_code(void) +{ + ftrace_replace_code(1); +} + +notrace void ftrace_shutdown_code(void) +{ + ftrace_replace_code(0); +} + +notrace void ftrace_shutdown_replenish(void) +{ + if (ftrace_pages->next) + return; + + /* allocate another page */ + ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); +} + +notrace int ftrace_shutdown_arch_init(void) +{ + struct ftrace_page *pg; + int cnt; + int i; + + /* allocate a few pages */ + ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL); + if (!ftrace_pages_start) + return -1; + + /* + * Allocate a few more pages. + * + * TODO: have some parser search vmlinux before + * final linking to find all calls to ftrace. + * Then we can: + * a) know how many pages to allocate. + * and/or + * b) set up the table then. + * + * The dynamic code is still necessary for + * modules. + */ + + pg = ftrace_pages = ftrace_pages_start; + + cnt = NR_TO_INIT / ENTRIES_PER_PAGE; + + for (i = 0; i < cnt; i++) { + pg->next = (void *)get_zeroed_page(GFP_KERNEL); + + /* If we fail, we'll try later anyway */ + if (!pg->next) + break; + + pg = pg->next; + } + + return 0; +} diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 740c97d..90dbc0e 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -32,6 +32,24 @@ extern void mcount(void); # define clear_ftrace_function(ops) do { } while (0) #endif /* CONFIG_FTRACE */ +#ifdef CONFIG_DYNAMIC_FTRACE +# define FTRACE_HASHBITS 10 +# define FTRACE_HASHSIZE (1< +#include +#include +#include +#include +#include #include +#include +#include +#include + +#include "trace.h" -static DEFINE_SPINLOCK(ftrace_func_lock); +static DEFINE_SPINLOCK(ftrace_lock); static struct ftrace_ops ftrace_list_end __read_mostly = { .func = ftrace_stub, @@ -44,21 +53,21 @@ notrace void ftrace_list_func(unsigned long ip, unsigned long parent_ip) } /** - * register_ftrace_function - register a function for profiling - * @ops - ops structure that holds the function for profiling. - * - * Register a function to be called by all functions in the - * kernel. + * clear_ftrace_function - reset the ftrace function * - * Note: @ops->func and all the functions it calls must be labeled - * with "notrace", otherwise it will go into a - * recursive loop. + * This NULLs the ftrace function and in essence stops + * tracing. There may be lag */ -int register_ftrace_function(struct ftrace_ops *ops) +void clear_ftrace_function(void) { - unsigned long flags; + ftrace_trace_function = ftrace_stub; +} + +static int notrace __register_ftrace_function(struct ftrace_ops *ops) +{ + /* Should never be called by interrupts */ + spin_lock(&ftrace_lock); - spin_lock_irqsave(&ftrace_func_lock, flags); ops->next = ftrace_list; /* * We are entering ops into the ftrace_list but another @@ -68,6 +77,7 @@ int register_ftrace_function(struct ftrace_ops *ops) */ smp_wmb(); ftrace_list = ops; + /* * For one func, simply call it directly. * For more than one func, call the chain. @@ -76,28 +86,22 @@ int register_ftrace_function(struct ftrace_ops *ops) ftrace_trace_function = ops->func; else ftrace_trace_function = ftrace_list_func; - spin_unlock_irqrestore(&ftrace_func_lock, flags); + + spin_unlock(&ftrace_lock); return 0; } -/** - * unregister_ftrace_function - unresgister a function for profiling. - * @ops - ops structure that holds the function to unregister - * - * Unregister a function that was added to be called by ftrace profiling. - */ -int unregister_ftrace_function(struct ftrace_ops *ops) +static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) { - unsigned long flags; struct ftrace_ops **p; int ret = 0; - spin_lock_irqsave(&ftrace_func_lock, flags); + spin_lock(&ftrace_lock); /* - * If we are the only function, then the ftrace pointer is - * pointing directly to that function. + * If we are removing the last function, then simply point + * to the ftrace_stub. */ if (ftrace_list == ops && ops->next == &ftrace_list_end) { ftrace_trace_function = ftrace_stub; @@ -117,22 +121,310 @@ int unregister_ftrace_function(struct ftrace_ops *ops) *p = (*p)->next; /* If we only have one func left, then call that directly */ - if (ftrace_list->next == &ftrace_list_end) + if (ftrace_list == &ftrace_list_end || + ftrace_list->next == &ftrace_list_end) ftrace_trace_function = ftrace_list->func; out: - spin_unlock_irqrestore(&ftrace_func_lock, flags); + spin_unlock(&ftrace_lock); + + return ret; +} + +#ifdef CONFIG_DYNAMIC_FTRACE + +static struct hlist_head ftrace_hash[FTRACE_HASHSIZE]; + +static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu); + +static DEFINE_SPINLOCK(ftrace_shutdown_lock); +static DEFINE_MUTEX(ftraced_lock); + +static int ftraced_trigger; +static int ftraced_suspend; + +static int ftrace_record_suspend; + +static inline int +notrace ftrace_ip_in_hash(unsigned long ip, unsigned long key) +{ + struct dyn_ftrace *p; + struct hlist_node *t; + int found = 0; + + hlist_for_each_entry(p, t, &ftrace_hash[key], node) { + if (p->ip == ip) { + found = 1; + break; + } + } + + return found; +} + +static inline void notrace +ftrace_add_hash(struct dyn_ftrace *node, unsigned long key) +{ + hlist_add_head(&node->node, &ftrace_hash[key]); +} + +static void notrace +ftrace_record_ip(unsigned long ip, unsigned long parent_ip) +{ + struct dyn_ftrace *node; + unsigned long flags; + unsigned long key; + int resched; + int atomic; + + resched = need_resched(); + preempt_disable_notrace(); + + /* We simply need to protect against recursion */ + __get_cpu_var(ftrace_shutdown_disable_cpu)++; + if (__get_cpu_var(ftrace_shutdown_disable_cpu) != 1) + goto out; + + if (unlikely(ftrace_record_suspend)) + goto out; + + key = hash_long(ip, FTRACE_HASHBITS); + + WARN_ON_ONCE(key >= FTRACE_HASHSIZE); + + if (ftrace_ip_in_hash(ip, key)) + goto out; + + atomic = irqs_disabled(); + + spin_lock_irqsave(&ftrace_shutdown_lock, flags); + + /* This ip may have hit the hash before the lock */ + if (ftrace_ip_in_hash(ip, key)) + goto out_unlock; + + /* + * There's a slight race that the ftraced will update the + * hash and reset here. The arch alloc is responsible + * for seeing if the IP has already changed, and if + * it has, the alloc will fail. + */ + node = ftrace_alloc_shutdown_node(ip); + if (!node) + goto out_unlock; + + node->ip = ip; + + ftrace_add_hash(node, key); + + ftraced_trigger = 1; + + out_unlock: + spin_unlock_irqrestore(&ftrace_shutdown_lock, flags); + out: + __get_cpu_var(ftrace_shutdown_disable_cpu)--; + + /* prevent recursion with scheduler */ + if (resched) + preempt_enable_no_resched_notrace(); + else + preempt_enable_notrace(); +} + +static struct ftrace_ops ftrace_shutdown_ops __read_mostly = +{ + .func = ftrace_record_ip, +}; + + +static int notrace __ftrace_modify_code(void *data) +{ + void (*func)(void) = data; + + func(); + return 0; +} + +static void notrace ftrace_run_startup_code(void) +{ + stop_machine_run(__ftrace_modify_code, ftrace_startup_code, NR_CPUS); +} + +static void notrace ftrace_run_shutdown_code(void) +{ + stop_machine_run(__ftrace_modify_code, ftrace_shutdown_code, NR_CPUS); +} + +static void notrace ftrace_startup(void) +{ + mutex_lock(&ftraced_lock); + ftraced_suspend++; + if (ftraced_suspend != 1) + goto out; + __unregister_ftrace_function(&ftrace_shutdown_ops); + + ftrace_run_startup_code(); + out: + mutex_unlock(&ftraced_lock); +} + +static void notrace ftrace_shutdown(void) +{ + mutex_lock(&ftraced_lock); + ftraced_suspend--; + if (ftraced_suspend) + goto out; + + ftrace_run_shutdown_code(); + + __register_ftrace_function(&ftrace_shutdown_ops); + out: + mutex_unlock(&ftraced_lock); +} + +static cycle_t ftrace_update_time; +static unsigned long ftrace_update_cnt; +unsigned long ftrace_update_tot_cnt; + +static int notrace __ftrace_update_code(void *ignore) +{ + struct dyn_ftrace *p; + struct hlist_head head; + struct hlist_node *t; + cycle_t start, stop; + int i; + + /* Don't be calling ftrace ops now */ + __unregister_ftrace_function(&ftrace_shutdown_ops); + + start = now(raw_smp_processor_id()); + ftrace_update_cnt = 0; + + /* No locks needed, the machine is stopped! */ + for (i = 0; i < FTRACE_HASHSIZE; i++) { + if (hlist_empty(&ftrace_hash[i])) + continue; + + head = ftrace_hash[i]; + INIT_HLIST_HEAD(&ftrace_hash[i]); + + /* all CPUS are stopped, we are safe to modify code */ + hlist_for_each_entry(p, t, &head, node) { + ftrace_code_disable(p); + ftrace_update_cnt++; + } + + } + + stop = now(raw_smp_processor_id()); + ftrace_update_time = stop - start; + ftrace_update_tot_cnt += ftrace_update_cnt; + + __register_ftrace_function(&ftrace_shutdown_ops); return 0; } +static void notrace ftrace_update_code(void) +{ + stop_machine_run(__ftrace_update_code, NULL, NR_CPUS); +} + +static int notrace ftraced(void *ignore) +{ + unsigned long usecs; + + set_current_state(TASK_INTERRUPTIBLE); + + while (!kthread_should_stop()) { + + /* check once a second */ + schedule_timeout(HZ); + + mutex_lock(&ftraced_lock); + if (ftraced_trigger && !ftraced_suspend) { + ftrace_record_suspend++; + ftrace_update_code(); + usecs = nsecs_to_usecs(ftrace_update_time); + if (ftrace_update_tot_cnt > 100000) { + ftrace_update_tot_cnt = 0; + pr_info("hm, dftrace overflow: %lu change%s" + " (%lu total) in %lu usec%s\n", + ftrace_update_cnt, + ftrace_update_cnt != 1 ? "s" : "", + ftrace_update_tot_cnt, + usecs, usecs != 1 ? "s" : ""); + WARN_ON_ONCE(1); + } + ftraced_trigger = 0; + ftrace_record_suspend--; + } + mutex_unlock(&ftraced_lock); + + ftrace_shutdown_replenish(); + + set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); + return 0; +} + +static int __init notrace ftrace_shutdown_init(void) +{ + struct task_struct *p; + int ret; + + ret = ftrace_shutdown_arch_init(); + if (ret) + return ret; + + p = kthread_run(ftraced, NULL, "ftraced"); + if (IS_ERR(p)) + return -1; + + __register_ftrace_function(&ftrace_shutdown_ops); + + return 0; +} + +core_initcall(ftrace_shutdown_init); +#else +# define ftrace_startup() do { } while (0) +# define ftrace_shutdown() do { } while (0) +#endif /* CONFIG_DYNAMIC_FTRACE */ + /** - * clear_ftrace_function - reset the ftrace function + * register_ftrace_function - register a function for profiling + * @ops - ops structure that holds the function for profiling. * - * This NULLs the ftrace function and in essence stops - * tracing. There may be lag + * Register a function to be called by all functions in the + * kernel. + * + * Note: @ops->func and all the functions it calls must be labeled + * with "notrace", otherwise it will go into a + * recursive loop. */ -void clear_ftrace_function(void) +int register_ftrace_function(struct ftrace_ops *ops) { - ftrace_trace_function = ftrace_stub; + ftrace_startup(); + + return __register_ftrace_function(ops); +} + +/** + * unregister_ftrace_function - unresgister a function for profiling. + * @ops - ops structure that holds the function to unregister + * + * Unregister a function that was added to be called by ftrace profiling. + */ +int unregister_ftrace_function(struct ftrace_ops *ops) +{ + int ret; + + ret = __unregister_ftrace_function(ops); + + if (ftrace_list == &ftrace_list_end) + ftrace_shutdown(); + + return ret; } -- cgit v0.10.2 From b0fc494fae96a7089f3651cb451f461c7291244c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: add ftrace_enabled sysctl to disable mcount function This patch adds back the sysctl ftrace_enabled. This time it is defaulted to on, if DYNAMIC_FTRACE is configured. When ftrace_enabled is disabled, the ftrace function is set to the stub return. If DYNAMIC_FTRACE is also configured, on ftrace_enabled = 0, the registered ftrace functions will all be set to jmps, but no more new calls to ftrace recording (used to find the ftrace calling sites) will be called. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 90dbc0e..ccd8537 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -5,6 +5,12 @@ #include +extern int ftrace_enabled; +extern int +ftrace_enable_sysctl(struct ctl_table *table, int write, + struct file *filp, void __user *buffer, size_t *lenp, + loff_t *ppos); + typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); struct ftrace_ops { diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 2911665..efaf7c5 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -455,6 +456,16 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = &proc_dointvec, }, +#ifdef CONFIG_FTRACE + { + .ctl_name = CTL_UNNUMBERED, + .procname = "ftrace_enabled", + .data = &ftrace_enabled, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &ftrace_enable_sysctl, + }, +#endif #ifdef CONFIG_KMOD { .ctl_name = KERN_MODPROBE, diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d1ae2ba..d3de372 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -20,12 +20,24 @@ #include #include #include +#include #include #include #include "trace.h" +#ifdef CONFIG_DYNAMIC_FTRACE +# define FTRACE_ENABLED_INIT 1 +#else +# define FTRACE_ENABLED_INIT 0 +#endif + +int ftrace_enabled = FTRACE_ENABLED_INIT; +static int last_ftrace_enabled = FTRACE_ENABLED_INIT; + static DEFINE_SPINLOCK(ftrace_lock); +static DEFINE_MUTEX(ftrace_sysctl_lock); + static struct ftrace_ops ftrace_list_end __read_mostly = { .func = ftrace_stub, @@ -78,14 +90,16 @@ static int notrace __register_ftrace_function(struct ftrace_ops *ops) smp_wmb(); ftrace_list = ops; - /* - * For one func, simply call it directly. - * For more than one func, call the chain. - */ - if (ops->next == &ftrace_list_end) - ftrace_trace_function = ops->func; - else - ftrace_trace_function = ftrace_list_func; + if (ftrace_enabled) { + /* + * For one func, simply call it directly. + * For more than one func, call the chain. + */ + if (ops->next == &ftrace_list_end) + ftrace_trace_function = ops->func; + else + ftrace_trace_function = ftrace_list_func; + } spin_unlock(&ftrace_lock); @@ -120,10 +134,12 @@ static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) *p = (*p)->next; - /* If we only have one func left, then call that directly */ - if (ftrace_list == &ftrace_list_end || - ftrace_list->next == &ftrace_list_end) - ftrace_trace_function = ftrace_list->func; + if (ftrace_enabled) { + /* If we only have one func left, then call that directly */ + if (ftrace_list == &ftrace_list_end || + ftrace_list->next == &ftrace_list_end) + ftrace_trace_function = ftrace_list->func; + } out: spin_unlock(&ftrace_lock); @@ -263,7 +279,8 @@ static void notrace ftrace_startup(void) goto out; __unregister_ftrace_function(&ftrace_shutdown_ops); - ftrace_run_startup_code(); + if (ftrace_enabled) + ftrace_run_startup_code(); out: mutex_unlock(&ftraced_lock); } @@ -275,13 +292,32 @@ static void notrace ftrace_shutdown(void) if (ftraced_suspend) goto out; - ftrace_run_shutdown_code(); + if (ftrace_enabled) + ftrace_run_shutdown_code(); __register_ftrace_function(&ftrace_shutdown_ops); out: mutex_unlock(&ftraced_lock); } +static void notrace ftrace_startup_sysctl(void) +{ + mutex_lock(&ftraced_lock); + /* ftraced_suspend is true if we want ftrace running */ + if (ftraced_suspend) + ftrace_run_startup_code(); + mutex_unlock(&ftraced_lock); +} + +static void notrace ftrace_shutdown_sysctl(void) +{ + mutex_lock(&ftraced_lock); + /* ftraced_suspend is true if ftrace is running */ + if (ftraced_suspend) + ftrace_run_shutdown_code(); + mutex_unlock(&ftraced_lock); +} + static cycle_t ftrace_update_time; static unsigned long ftrace_update_cnt; unsigned long ftrace_update_tot_cnt; @@ -341,8 +377,9 @@ static int notrace ftraced(void *ignore) /* check once a second */ schedule_timeout(HZ); + mutex_lock(&ftrace_sysctl_lock); mutex_lock(&ftraced_lock); - if (ftraced_trigger && !ftraced_suspend) { + if (ftrace_enabled && ftraced_trigger && !ftraced_suspend) { ftrace_record_suspend++; ftrace_update_code(); usecs = nsecs_to_usecs(ftrace_update_time); @@ -360,6 +397,7 @@ static int notrace ftraced(void *ignore) ftrace_record_suspend--; } mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_sysctl_lock); ftrace_shutdown_replenish(); @@ -389,8 +427,10 @@ static int __init notrace ftrace_shutdown_init(void) core_initcall(ftrace_shutdown_init); #else -# define ftrace_startup() do { } while (0) -# define ftrace_shutdown() do { } while (0) +# define ftrace_startup() do { } while (0) +# define ftrace_shutdown() do { } while (0) +# define ftrace_startup_sysctl() do { } while (0) +# define ftrace_shutdown_sysctl() do { } while (0) #endif /* CONFIG_DYNAMIC_FTRACE */ /** @@ -406,9 +446,15 @@ core_initcall(ftrace_shutdown_init); */ int register_ftrace_function(struct ftrace_ops *ops) { + int ret; + + mutex_lock(&ftrace_sysctl_lock); ftrace_startup(); - return __register_ftrace_function(ops); + ret = __register_ftrace_function(ops); + mutex_unlock(&ftrace_sysctl_lock); + + return ret; } /** @@ -421,10 +467,53 @@ int unregister_ftrace_function(struct ftrace_ops *ops) { int ret; + mutex_lock(&ftrace_sysctl_lock); ret = __unregister_ftrace_function(ops); if (ftrace_list == &ftrace_list_end) ftrace_shutdown(); + mutex_unlock(&ftrace_sysctl_lock); + + return ret; +} + +notrace int +ftrace_enable_sysctl(struct ctl_table *table, int write, + struct file *filp, void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret; + + mutex_lock(&ftrace_sysctl_lock); + + ret = proc_dointvec(table, write, filp, buffer, lenp, ppos); + + if (ret || !write || (last_ftrace_enabled == ftrace_enabled)) + goto out; + + last_ftrace_enabled = ftrace_enabled; + + if (ftrace_enabled) { + + ftrace_startup_sysctl(); + + /* we are starting ftrace again */ + if (ftrace_list != &ftrace_list_end) { + if (ftrace_list->next == &ftrace_list_end) + ftrace_trace_function = ftrace_list->func; + else + ftrace_trace_function = ftrace_list_func; + } + + } else { + /* stopping ftrace calls (just send to ftrace_stub) */ + ftrace_trace_function = ftrace_stub; + + ftrace_shutdown_sysctl(); + } + + out: + mutex_unlock(&ftrace_sysctl_lock); return ret; } -- cgit v0.10.2 From dfa60aba04dae7833d75b2e2be124bb7cfb8239f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: use nops instead of jmp This patch patches the call to mcount with nops instead of a jmp over the mcount call. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 65c7857..de240ba 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -143,7 +143,7 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { #ifdef CONFIG_X86_64 extern char __vsyscall_0; -static inline const unsigned char*const * find_nop_table(void) +const unsigned char *const *find_nop_table(void) { return boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || boot_cpu_data.x86 < 6 ? k8_nops : p6_nops; @@ -162,7 +162,7 @@ static const struct nop { { -1, NULL } }; -static const unsigned char*const * find_nop_table(void) +const unsigned char *const *find_nop_table(void) { const unsigned char *const *noptable = intel_nops; int i; diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 5dd5813..2e060c5 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -16,11 +16,12 @@ #include #include -#define CALL_BACK 5 +#include -#define JMPFWD 0x03eb +#define CALL_BACK 5 -static unsigned short ftrace_jmp = JMPFWD; +/* Long is fine, even if it is only 4 bytes ;-) */ +static long *ftrace_nop; struct ftrace_record { struct dyn_ftrace rec; @@ -55,13 +56,13 @@ static struct ftrace_page *ftrace_pages; notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip) { struct ftrace_record *rec; - unsigned short save; + unsigned long save; ip -= CALL_BACK; - save = *(short *)ip; + save = *(long *)ip; /* If this was already converted, skip it */ - if (save == JMPFWD) + if (save == *ftrace_nop) return NULL; if (ftrace_pages->index == ENTRIES_PER_PAGE) { @@ -79,9 +80,10 @@ static int notrace ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code) { - unsigned short old = *(unsigned short *)old_code; - unsigned short new = *(unsigned short *)new_code; - unsigned short replaced; + unsigned replaced; + unsigned old = *(unsigned *)old_code; /* 4 bytes */ + unsigned new = *(unsigned *)new_code; /* 4 bytes */ + unsigned char newch = new_code[4]; int faulted = 0; /* @@ -94,7 +96,9 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, */ asm volatile ( "1: lock\n" - " cmpxchg %w3, (%2)\n" + " cmpxchg %3, (%2)\n" + " jnz 2f\n" + " movb %b4, 4(%2)\n" "2:\n" ".section .fixup, \"ax\"\n" " movl $1, %0\n" @@ -102,11 +106,12 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, ".previous\n" _ASM_EXTABLE(1b, 3b) : "=r"(faulted), "=a"(replaced) - : "r"(ip), "r"(new), "0"(faulted), "a"(old) + : "r"(ip), "r"(new), "r"(newch), + "0"(faulted), "a"(old) : "memory"); sync_core(); - if (replaced != old) + if (replaced != old && replaced != new) faulted = 2; return faulted; @@ -132,7 +137,7 @@ notrace void ftrace_code_disable(struct dyn_ftrace *rec) /* move the IP back to the start of the call */ ip -= CALL_BACK; - r->failed = ftrace_modify_code(ip, save.code, (char *)&ftrace_jmp); + r->failed = ftrace_modify_code(ip, save.code, (char *)ftrace_nop); } static void notrace ftrace_replace_code(int saved) @@ -144,9 +149,9 @@ static void notrace ftrace_replace_code(int saved) int i; if (saved) - old = (char *)&ftrace_jmp; + old = (char *)ftrace_nop; else - new = (char *)&ftrace_jmp; + new = (char *)ftrace_nop; for (pg = ftrace_pages_start; pg; pg = pg->next) { for (i = 0; i < pg->index; i++) { @@ -194,12 +199,15 @@ notrace void ftrace_shutdown_replenish(void) ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); } -notrace int ftrace_shutdown_arch_init(void) +notrace int __init ftrace_shutdown_arch_init(void) { + const unsigned char *const *noptable = find_nop_table(); struct ftrace_page *pg; int cnt; int i; + ftrace_nop = (unsigned long *)noptable[CALL_BACK]; + /* allocate a few pages */ ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL); if (!ftrace_pages_start) diff --git a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h index 1f6a9ca..f6aa18e 100644 --- a/include/asm-x86/alternative.h +++ b/include/asm-x86/alternative.h @@ -72,6 +72,8 @@ static inline void alternatives_smp_module_del(struct module *mod) {} static inline void alternatives_smp_switch(int smp) {} #endif /* CONFIG_SMP */ +const unsigned char *const *find_nop_table(void); + /* * Alternative instructions for different CPU types or capabilities. * -- cgit v0.10.2 From 3c1720f00bb619302ba19d55986ab565e74d06db Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: move memory management out of arch code This patch moves the memory management of the ftrace records out of the arch code and into the generic code making the arch code simpler. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 2e060c5..b69795e 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -23,25 +23,6 @@ /* Long is fine, even if it is only 4 bytes ;-) */ static long *ftrace_nop; -struct ftrace_record { - struct dyn_ftrace rec; - int failed; -} __attribute__((packed)); - -struct ftrace_page { - struct ftrace_page *next; - int index; - struct ftrace_record records[]; -} __attribute__((packed)); - -#define ENTRIES_PER_PAGE \ - ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct ftrace_record)) - -/* estimate from running different kernels */ -#define NR_TO_INIT 10000 - -#define MCOUNT_ADDR ((long)(&mcount)) - union ftrace_code_union { char code[5]; struct { @@ -50,33 +31,41 @@ union ftrace_code_union { } __attribute__((packed)); }; -static struct ftrace_page *ftrace_pages_start; -static struct ftrace_page *ftrace_pages; - -notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip) +notrace int ftrace_ip_converted(unsigned long ip) { - struct ftrace_record *rec; unsigned long save; ip -= CALL_BACK; save = *(long *)ip; - /* If this was already converted, skip it */ - if (save == *ftrace_nop) - return NULL; + return save == *ftrace_nop; +} - if (ftrace_pages->index == ENTRIES_PER_PAGE) { - if (!ftrace_pages->next) - return NULL; - ftrace_pages = ftrace_pages->next; - } +static int notrace ftrace_calc_offset(long ip, long addr) +{ + return (int)(addr - ip); +} - rec = &ftrace_pages->records[ftrace_pages->index++]; +notrace unsigned char *ftrace_nop_replace(void) +{ + return (char *)ftrace_nop; +} + +notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +{ + static union ftrace_code_union calc; - return &rec->rec; + calc.e8 = 0xe8; + calc.offset = ftrace_calc_offset(ip, addr); + + /* + * No locking needed, this must be called via kstop_machine + * which in essence is like running on a uniprocessor machine. + */ + return calc.code; } -static int notrace +notrace int ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code) { @@ -86,6 +75,9 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char newch = new_code[4]; int faulted = 0; + /* move the IP back to the start of the call */ + ip -= CALL_BACK; + /* * Note: Due to modules and __init, code can * disappear and change, we need to protect against faulting @@ -117,129 +109,12 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, return faulted; } -static int notrace ftrace_calc_offset(long ip) -{ - return (int)(MCOUNT_ADDR - ip); -} - -notrace void ftrace_code_disable(struct dyn_ftrace *rec) -{ - unsigned long ip; - union ftrace_code_union save; - struct ftrace_record *r = - container_of(rec, struct ftrace_record, rec); - - ip = rec->ip; - - save.e8 = 0xe8; - save.offset = ftrace_calc_offset(ip); - - /* move the IP back to the start of the call */ - ip -= CALL_BACK; - - r->failed = ftrace_modify_code(ip, save.code, (char *)ftrace_nop); -} - -static void notrace ftrace_replace_code(int saved) -{ - unsigned char *new = NULL, *old = NULL; - struct ftrace_record *rec; - struct ftrace_page *pg; - unsigned long ip; - int i; - - if (saved) - old = (char *)ftrace_nop; - else - new = (char *)ftrace_nop; - - for (pg = ftrace_pages_start; pg; pg = pg->next) { - for (i = 0; i < pg->index; i++) { - union ftrace_code_union calc; - rec = &pg->records[i]; - - /* don't modify code that has already faulted */ - if (rec->failed) - continue; - - ip = rec->rec.ip; - - calc.e8 = 0xe8; - calc.offset = ftrace_calc_offset(ip); - - if (saved) - new = calc.code; - else - old = calc.code; - - ip -= CALL_BACK; - - rec->failed = ftrace_modify_code(ip, old, new); - } - } - -} - -notrace void ftrace_startup_code(void) -{ - ftrace_replace_code(1); -} - -notrace void ftrace_shutdown_code(void) -{ - ftrace_replace_code(0); -} - -notrace void ftrace_shutdown_replenish(void) -{ - if (ftrace_pages->next) - return; - - /* allocate another page */ - ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); -} - -notrace int __init ftrace_shutdown_arch_init(void) +int __init ftrace_dyn_arch_init(void) { const unsigned char *const *noptable = find_nop_table(); - struct ftrace_page *pg; - int cnt; - int i; ftrace_nop = (unsigned long *)noptable[CALL_BACK]; - /* allocate a few pages */ - ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL); - if (!ftrace_pages_start) - return -1; - - /* - * Allocate a few more pages. - * - * TODO: have some parser search vmlinux before - * final linking to find all calls to ftrace. - * Then we can: - * a) know how many pages to allocate. - * and/or - * b) set up the table then. - * - * The dynamic code is still necessary for - * modules. - */ - - pg = ftrace_pages = ftrace_pages_start; - - cnt = NR_TO_INIT / ENTRIES_PER_PAGE; - - for (i = 0; i < cnt; i++) { - pg->next = (void *)get_zeroed_page(GFP_KERNEL); - - /* If we fail, we'll try later anyway */ - if (!pg->next) - break; - - pg = pg->next; - } - return 0; } + diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ccd8537..d509ad6 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -42,19 +42,23 @@ extern void mcount(void); # define FTRACE_HASHBITS 10 # define FTRACE_HASHSIZE (1<node, &ftrace_hash[key]); } +static notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip) +{ + /* If this was already converted, skip it */ + if (ftrace_ip_converted(ip)) + return NULL; + + if (ftrace_pages->index == ENTRIES_PER_PAGE) { + if (!ftrace_pages->next) + return NULL; + ftrace_pages = ftrace_pages->next; + } + + return &ftrace_pages->records[ftrace_pages->index++]; +} + static void notrace ftrace_record_ip(unsigned long ip, unsigned long parent_ip) { @@ -252,6 +282,62 @@ static struct ftrace_ops ftrace_shutdown_ops __read_mostly = .func = ftrace_record_ip, }; +#define MCOUNT_ADDR ((long)(&mcount)) + +static void notrace ftrace_replace_code(int saved) +{ + unsigned char *new = NULL, *old = NULL; + struct dyn_ftrace *rec; + struct ftrace_page *pg; + unsigned long ip; + int failed; + int i; + + if (saved) + old = ftrace_nop_replace(); + else + new = ftrace_nop_replace(); + + for (pg = ftrace_pages_start; pg; pg = pg->next) { + for (i = 0; i < pg->index; i++) { + rec = &pg->records[i]; + + /* don't modify code that has already faulted */ + if (rec->flags & FTRACE_FL_FAILED) + continue; + + ip = rec->ip; + + if (saved) + new = ftrace_call_replace(ip, MCOUNT_ADDR); + else + old = ftrace_call_replace(ip, MCOUNT_ADDR); + + failed = ftrace_modify_code(ip, old, new); + if (failed) + rec->flags |= FTRACE_FL_FAILED; + } + } +} + +static notrace void ftrace_startup_code(void) +{ + ftrace_replace_code(1); +} + +static notrace void ftrace_shutdown_code(void) +{ + ftrace_replace_code(0); +} + +static notrace void ftrace_shutdown_replenish(void) +{ + if (ftrace_pages->next) + return; + + /* allocate another page */ + ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); +} static int notrace __ftrace_modify_code(void *data) { @@ -261,6 +347,23 @@ static int notrace __ftrace_modify_code(void *data) return 0; } +static notrace void +ftrace_code_disable(struct dyn_ftrace *rec, unsigned long addr) +{ + unsigned long ip; + unsigned char *nop, *call; + int failed; + + ip = rec->ip; + + nop = ftrace_nop_replace(); + call = ftrace_call_replace(ip, addr); + + failed = ftrace_modify_code(ip, call, nop); + if (failed) + rec->flags |= FTRACE_FL_FAILED; +} + static void notrace ftrace_run_startup_code(void) { stop_machine_run(__ftrace_modify_code, ftrace_startup_code, NR_CPUS); @@ -346,7 +449,7 @@ static int notrace __ftrace_update_code(void *ignore) /* all CPUS are stopped, we are safe to modify code */ hlist_for_each_entry(p, t, &head, node) { - ftrace_code_disable(p); + ftrace_code_disable(p, MCOUNT_ADDR); ftrace_update_cnt++; } @@ -407,12 +510,59 @@ static int notrace ftraced(void *ignore) return 0; } +static int __init ftrace_dyn_table_alloc(void) +{ + struct ftrace_page *pg; + int cnt; + int i; + int ret; + + ret = ftrace_dyn_arch_init(); + if (ret) + return ret; + + /* allocate a few pages */ + ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL); + if (!ftrace_pages_start) + return -1; + + /* + * Allocate a few more pages. + * + * TODO: have some parser search vmlinux before + * final linking to find all calls to ftrace. + * Then we can: + * a) know how many pages to allocate. + * and/or + * b) set up the table then. + * + * The dynamic code is still necessary for + * modules. + */ + + pg = ftrace_pages = ftrace_pages_start; + + cnt = NR_TO_INIT / ENTRIES_PER_PAGE; + + for (i = 0; i < cnt; i++) { + pg->next = (void *)get_zeroed_page(GFP_KERNEL); + + /* If we fail, we'll try later anyway */ + if (!pg->next) + break; + + pg = pg->next; + } + + return 0; +} + static int __init notrace ftrace_shutdown_init(void) { struct task_struct *p; int ret; - ret = ftrace_shutdown_arch_init(); + ret = ftrace_dyn_table_alloc(); if (ret) return ret; -- cgit v0.10.2 From d61f82d06672f57fca410da6f7fffd15867db622 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: use dynamic patching for updating mcount calls This patch replaces the indirect call to the mcount function pointer with a direct call that will be patched by the dynamic ftrace routines. On boot up, the mcount function calls the ftace_stub function. When the dynamic ftrace code is initialized, the ftrace_stub is replaced with a call to the ftrace_record_ip, which records the instruction pointers of the locations that call it. Later, the ftraced daemon will call kstop_machine and patch all the locations to nops. When a ftrace is enabled, the original calls to mcount will now be set top call ftrace_caller, which will do a direct call to the registered ftrace function. This direct call is also patched when the function that should be called is updated. All patching is performed by a kstop_machine routine to prevent any type of race conditions that is associated with modifying code on the fly. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index f47b9b5..e6517ce 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1110,10 +1110,50 @@ ENDPROC(xen_failsafe_callback) #endif /* CONFIG_XEN */ #ifdef CONFIG_FTRACE +#ifdef CONFIG_DYNAMIC_FTRACE + +ENTRY(mcount) + pushl %eax + pushl %ecx + pushl %edx + movl 0xc(%esp), %eax + +.globl mcount_call +mcount_call: + call ftrace_stub + + popl %edx + popl %ecx + popl %eax + + ret +END(mcount) + +ENTRY(ftrace_caller) + pushl %eax + pushl %ecx + pushl %edx + movl 0xc(%esp), %eax + movl 0x4(%ebp), %edx + +.globl ftrace_call +ftrace_call: + call ftrace_stub + + popl %edx + popl %ecx + popl %eax + +.globl ftrace_stub +ftrace_stub: + ret +END(ftrace_caller) + +#else /* ! CONFIG_DYNAMIC_FTRACE */ + ENTRY(mcount) cmpl $ftrace_stub, ftrace_trace_function jnz trace - .globl ftrace_stub ftrace_stub: ret @@ -1126,7 +1166,7 @@ trace: movl 0xc(%esp), %eax movl 0x4(%ebp), %edx - call *ftrace_trace_function + call *ftrace_trace_function popl %edx popl %ecx @@ -1134,7 +1174,8 @@ trace: jmp ftrace_stub END(mcount) -#endif +#endif /* CONFIG_DYNAMIC_FTRACE */ +#endif /* CONFIG_FTRACE */ .section .rodata,"a" #include "syscall_table_32.S" diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index f046e0c..fe25e5f 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -55,6 +55,70 @@ .code64 #ifdef CONFIG_FTRACE +#ifdef CONFIG_DYNAMIC_FTRACE +ENTRY(mcount) + + subq $0x38, %rsp + movq %rax, (%rsp) + movq %rcx, 8(%rsp) + movq %rdx, 16(%rsp) + movq %rsi, 24(%rsp) + movq %rdi, 32(%rsp) + movq %r8, 40(%rsp) + movq %r9, 48(%rsp) + + movq 0x38(%rsp), %rdi + +.globl mcount_call +mcount_call: + call ftrace_stub + + movq 48(%rsp), %r9 + movq 40(%rsp), %r8 + movq 32(%rsp), %rdi + movq 24(%rsp), %rsi + movq 16(%rsp), %rdx + movq 8(%rsp), %rcx + movq (%rsp), %rax + addq $0x38, %rsp + + retq +END(mcount) + +ENTRY(ftrace_caller) + + /* taken from glibc */ + subq $0x38, %rsp + movq %rax, (%rsp) + movq %rcx, 8(%rsp) + movq %rdx, 16(%rsp) + movq %rsi, 24(%rsp) + movq %rdi, 32(%rsp) + movq %r8, 40(%rsp) + movq %r9, 48(%rsp) + + movq 0x38(%rsp), %rdi + movq 8(%rbp), %rsi + +.globl ftrace_call +ftrace_call: + call ftrace_stub + + movq 48(%rsp), %r9 + movq 40(%rsp), %r8 + movq 32(%rsp), %rdi + movq 24(%rsp), %rsi + movq 16(%rsp), %rdx + movq 8(%rsp), %rcx + movq (%rsp), %rax + addq $0x38, %rsp + +.globl ftrace_stub +ftrace_stub: + retq +END(ftrace_caller) + +#else /* ! CONFIG_DYNAMIC_FTRACE */ ENTRY(mcount) cmpq $ftrace_stub, ftrace_trace_function jnz trace @@ -89,7 +153,8 @@ trace: jmp ftrace_stub END(mcount) -#endif +#endif /* CONFIG_DYNAMIC_FTRACE */ +#endif /* CONFIG_FTRACE */ #ifndef CONFIG_PREEMPT #define retint_kernel retint_restore_args diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index b69795e..9f44623 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -109,10 +109,49 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, return faulted; } -int __init ftrace_dyn_arch_init(void) +notrace int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned long ip = (unsigned long)(&ftrace_call); + unsigned char old[5], *new; + int ret; + + ip += CALL_BACK; + + memcpy(old, &ftrace_call, 5); + new = ftrace_call_replace(ip, (unsigned long)func); + ret = ftrace_modify_code(ip, old, new); + + return ret; +} + +notrace int ftrace_mcount_set(unsigned long *data) +{ + unsigned long ip = (long)(&mcount_call); + unsigned long *addr = data; + unsigned char old[5], *new; + + /* ip is at the location, but modify code will subtact this */ + ip += CALL_BACK; + + /* + * Replace the mcount stub with a pointer to the + * ip recorder function. + */ + memcpy(old, &mcount_call, 5); + new = ftrace_call_replace(ip, *addr); + *addr = ftrace_modify_code(ip, old, new); + + return 0; +} + +int __init ftrace_dyn_arch_init(void *data) { const unsigned char *const *noptable = find_nop_table(); + /* This is running in kstop_machine */ + + ftrace_mcount_set(data); + ftrace_nop = (unsigned long *)noptable[CALL_BACK]; return 0; diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index d509ad6..b0dd009 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -56,9 +56,14 @@ struct dyn_ftrace { extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); -extern int ftrace_dyn_arch_init(void); +extern int ftrace_dyn_arch_init(void *data); +extern int ftrace_mcount_set(unsigned long *data); extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code); +extern int ftrace_update_ftrace_func(ftrace_func_t func); +extern void ftrace_caller(void); +extern void ftrace_call(void); +extern void mcount_call(void); #endif #ifdef CONFIG_FRAME_POINTER diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index f6d9af3..88544f9 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -26,14 +26,8 @@ #include "trace.h" -#ifdef CONFIG_DYNAMIC_FTRACE -# define FTRACE_ENABLED_INIT 1 -#else -# define FTRACE_ENABLED_INIT 0 -#endif - -int ftrace_enabled = FTRACE_ENABLED_INIT; -static int last_ftrace_enabled = FTRACE_ENABLED_INIT; +int ftrace_enabled; +static int last_ftrace_enabled; static DEFINE_SPINLOCK(ftrace_lock); static DEFINE_MUTEX(ftrace_sysctl_lock); @@ -149,6 +143,14 @@ static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) #ifdef CONFIG_DYNAMIC_FTRACE +enum { + FTRACE_ENABLE_CALLS = (1 << 0), + FTRACE_DISABLE_CALLS = (1 << 1), + FTRACE_UPDATE_TRACE_FUNC = (1 << 2), + FTRACE_ENABLE_MCOUNT = (1 << 3), + FTRACE_DISABLE_MCOUNT = (1 << 4), +}; + static struct hlist_head ftrace_hash[FTRACE_HASHSIZE]; static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu); @@ -199,12 +201,8 @@ ftrace_add_hash(struct dyn_ftrace *node, unsigned long key) hlist_add_head(&node->node, &ftrace_hash[key]); } -static notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip) +static notrace struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) { - /* If this was already converted, skip it */ - if (ftrace_ip_converted(ip)) - return NULL; - if (ftrace_pages->index == ENTRIES_PER_PAGE) { if (!ftrace_pages->next) return NULL; @@ -215,7 +213,7 @@ static notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip) } static void notrace -ftrace_record_ip(unsigned long ip, unsigned long parent_ip) +ftrace_record_ip(unsigned long ip) { struct dyn_ftrace *node; unsigned long flags; @@ -223,6 +221,9 @@ ftrace_record_ip(unsigned long ip, unsigned long parent_ip) int resched; int atomic; + if (!ftrace_enabled) + return; + resched = need_resched(); preempt_disable_notrace(); @@ -251,11 +252,12 @@ ftrace_record_ip(unsigned long ip, unsigned long parent_ip) /* * There's a slight race that the ftraced will update the - * hash and reset here. The arch alloc is responsible - * for seeing if the IP has already changed, and if - * it has, the alloc will fail. + * hash and reset here. If it is already converted, skip it. */ - node = ftrace_alloc_shutdown_node(ip); + if (ftrace_ip_converted(ip)) + goto out_unlock; + + node = ftrace_alloc_dyn_node(ip); if (!node) goto out_unlock; @@ -277,11 +279,7 @@ ftrace_record_ip(unsigned long ip, unsigned long parent_ip) preempt_enable_notrace(); } -static struct ftrace_ops ftrace_shutdown_ops __read_mostly = -{ - .func = ftrace_record_ip, -}; - +#define FTRACE_ADDR ((long)(&ftrace_caller)) #define MCOUNT_ADDR ((long)(&mcount)) static void notrace ftrace_replace_code(int saved) @@ -309,9 +307,9 @@ static void notrace ftrace_replace_code(int saved) ip = rec->ip; if (saved) - new = ftrace_call_replace(ip, MCOUNT_ADDR); + new = ftrace_call_replace(ip, FTRACE_ADDR); else - old = ftrace_call_replace(ip, MCOUNT_ADDR); + old = ftrace_call_replace(ip, FTRACE_ADDR); failed = ftrace_modify_code(ip, old, new); if (failed) @@ -320,16 +318,6 @@ static void notrace ftrace_replace_code(int saved) } } -static notrace void ftrace_startup_code(void) -{ - ftrace_replace_code(1); -} - -static notrace void ftrace_shutdown_code(void) -{ - ftrace_replace_code(0); -} - static notrace void ftrace_shutdown_replenish(void) { if (ftrace_pages->next) @@ -339,16 +327,8 @@ static notrace void ftrace_shutdown_replenish(void) ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); } -static int notrace __ftrace_modify_code(void *data) -{ - void (*func)(void) = data; - - func(); - return 0; -} - static notrace void -ftrace_code_disable(struct dyn_ftrace *rec, unsigned long addr) +ftrace_code_disable(struct dyn_ftrace *rec) { unsigned long ip; unsigned char *nop, *call; @@ -357,67 +337,113 @@ ftrace_code_disable(struct dyn_ftrace *rec, unsigned long addr) ip = rec->ip; nop = ftrace_nop_replace(); - call = ftrace_call_replace(ip, addr); + call = ftrace_call_replace(ip, MCOUNT_ADDR); failed = ftrace_modify_code(ip, call, nop); if (failed) rec->flags |= FTRACE_FL_FAILED; } -static void notrace ftrace_run_startup_code(void) +static int notrace __ftrace_modify_code(void *data) { - stop_machine_run(__ftrace_modify_code, ftrace_startup_code, NR_CPUS); + unsigned long addr; + int *command = data; + + if (*command & FTRACE_ENABLE_CALLS) + ftrace_replace_code(1); + else if (*command & FTRACE_DISABLE_CALLS) + ftrace_replace_code(0); + + if (*command & FTRACE_UPDATE_TRACE_FUNC) + ftrace_update_ftrace_func(ftrace_trace_function); + + if (*command & FTRACE_ENABLE_MCOUNT) { + addr = (unsigned long)ftrace_record_ip; + ftrace_mcount_set(&addr); + } else if (*command & FTRACE_DISABLE_MCOUNT) { + addr = (unsigned long)ftrace_stub; + ftrace_mcount_set(&addr); + } + + return 0; } -static void notrace ftrace_run_shutdown_code(void) +static void notrace ftrace_run_update_code(int command) { - stop_machine_run(__ftrace_modify_code, ftrace_shutdown_code, NR_CPUS); + stop_machine_run(__ftrace_modify_code, &command, NR_CPUS); } +static ftrace_func_t saved_ftrace_func; + static void notrace ftrace_startup(void) { + int command = 0; + mutex_lock(&ftraced_lock); ftraced_suspend++; - if (ftraced_suspend != 1) + if (ftraced_suspend == 1) + command |= FTRACE_ENABLE_CALLS; + + if (saved_ftrace_func != ftrace_trace_function) { + saved_ftrace_func = ftrace_trace_function; + command |= FTRACE_UPDATE_TRACE_FUNC; + } + + if (!command || !ftrace_enabled) goto out; - __unregister_ftrace_function(&ftrace_shutdown_ops); - if (ftrace_enabled) - ftrace_run_startup_code(); + ftrace_run_update_code(command); out: mutex_unlock(&ftraced_lock); } static void notrace ftrace_shutdown(void) { + int command = 0; + mutex_lock(&ftraced_lock); ftraced_suspend--; - if (ftraced_suspend) - goto out; + if (!ftraced_suspend) + command |= FTRACE_DISABLE_CALLS; - if (ftrace_enabled) - ftrace_run_shutdown_code(); + if (saved_ftrace_func != ftrace_trace_function) { + saved_ftrace_func = ftrace_trace_function; + command |= FTRACE_UPDATE_TRACE_FUNC; + } - __register_ftrace_function(&ftrace_shutdown_ops); + if (!command || !ftrace_enabled) + goto out; + + ftrace_run_update_code(command); out: mutex_unlock(&ftraced_lock); } static void notrace ftrace_startup_sysctl(void) { + int command = FTRACE_ENABLE_MCOUNT; + mutex_lock(&ftraced_lock); + /* Force update next time */ + saved_ftrace_func = NULL; /* ftraced_suspend is true if we want ftrace running */ if (ftraced_suspend) - ftrace_run_startup_code(); + command |= FTRACE_ENABLE_CALLS; + + ftrace_run_update_code(command); mutex_unlock(&ftraced_lock); } static void notrace ftrace_shutdown_sysctl(void) { + int command = FTRACE_DISABLE_MCOUNT; + mutex_lock(&ftraced_lock); /* ftraced_suspend is true if ftrace is running */ if (ftraced_suspend) - ftrace_run_shutdown_code(); + command |= FTRACE_DISABLE_CALLS; + + ftrace_run_update_code(command); mutex_unlock(&ftraced_lock); } @@ -430,11 +456,13 @@ static int notrace __ftrace_update_code(void *ignore) struct dyn_ftrace *p; struct hlist_head head; struct hlist_node *t; + int save_ftrace_enabled; cycle_t start, stop; int i; - /* Don't be calling ftrace ops now */ - __unregister_ftrace_function(&ftrace_shutdown_ops); + /* Don't be recording funcs now */ + save_ftrace_enabled = ftrace_enabled; + ftrace_enabled = 0; start = now(raw_smp_processor_id()); ftrace_update_cnt = 0; @@ -449,7 +477,7 @@ static int notrace __ftrace_update_code(void *ignore) /* all CPUS are stopped, we are safe to modify code */ hlist_for_each_entry(p, t, &head, node) { - ftrace_code_disable(p, MCOUNT_ADDR); + ftrace_code_disable(p); ftrace_update_cnt++; } @@ -459,7 +487,7 @@ static int notrace __ftrace_update_code(void *ignore) ftrace_update_time = stop - start; ftrace_update_tot_cnt += ftrace_update_cnt; - __register_ftrace_function(&ftrace_shutdown_ops); + ftrace_enabled = save_ftrace_enabled; return 0; } @@ -515,11 +543,6 @@ static int __init ftrace_dyn_table_alloc(void) struct ftrace_page *pg; int cnt; int i; - int ret; - - ret = ftrace_dyn_arch_init(); - if (ret) - return ret; /* allocate a few pages */ ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL); @@ -557,11 +580,19 @@ static int __init ftrace_dyn_table_alloc(void) return 0; } -static int __init notrace ftrace_shutdown_init(void) +static int __init notrace ftrace_dynamic_init(void) { struct task_struct *p; + unsigned long addr; int ret; + addr = (unsigned long)ftrace_record_ip; + stop_machine_run(ftrace_dyn_arch_init, &addr, NR_CPUS); + + /* ftrace_dyn_arch_init places the return code in addr */ + if (addr) + return addr; + ret = ftrace_dyn_table_alloc(); if (ret) return ret; @@ -570,12 +601,12 @@ static int __init notrace ftrace_shutdown_init(void) if (IS_ERR(p)) return -1; - __register_ftrace_function(&ftrace_shutdown_ops); + last_ftrace_enabled = ftrace_enabled = 1; return 0; } -core_initcall(ftrace_shutdown_init); +core_initcall(ftrace_dynamic_init); #else # define ftrace_startup() do { } while (0) # define ftrace_shutdown() do { } while (0) @@ -599,9 +630,8 @@ int register_ftrace_function(struct ftrace_ops *ops) int ret; mutex_lock(&ftrace_sysctl_lock); - ftrace_startup(); - ret = __register_ftrace_function(ops); + ftrace_startup(); mutex_unlock(&ftrace_sysctl_lock); return ret; @@ -619,10 +649,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops) mutex_lock(&ftrace_sysctl_lock); ret = __unregister_ftrace_function(ops); - - if (ftrace_list == &ftrace_list_end) - ftrace_shutdown(); - + ftrace_shutdown(); mutex_unlock(&ftrace_sysctl_lock); return ret; -- cgit v0.10.2 From 5072c59fd45e9976d02ee6f18c7336ef97623cbc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: add filter select functions to trace This patch adds two files to the debugfs system: /debugfs/tracing/available_filter_functions and /debugfs/tracing/set_ftrace_filter The available_filter_functions lists all functions that has been recorded by the ftraced that has called the ftrace_record_ip function. This is to allow users to see what functions have been converted to nops and can be enabled for tracing. To enable functions, simply echo the names (whitespace delimited) into set_ftrace_filter. Simple wildcards are also allowed. echo 'scheduler' > /debugfs/tracing/set_ftrace_filter Will have only the scheduler be activated when tracing is enabled. echo 'sched_*' > /debugfs/tracing/set_ftrace_filter Will have only the functions starting with 'sched_' be activated. echo '*lock' > /debugfs/tracing/set_ftrace_filter Will have only functions ending with 'lock' be activated. echo '*lock*' > /debugfs/tracing/set_ftrace_filter Will have only functions with 'lock' in its name be activated. Note: 'sched*lock' will not work. The only wildcards that are allowed is an asterisk and the beginning and or end of the string passed in. Multiple names can be passed in with whitespace delimited: echo 'scheduler *lock *acpi*' > /debugfs/tracing/set_ftrace_filter is also the same as: echo 'scheduler' > /debugfs/tracing/set_ftrace_filter echo '*lock' >> /debugfs/tracing/set_ftrace_filter echo '*acpi*' >> /debugfs/tracing/set_ftrace_filter Appending does just that. It appends to the list. To disable all filters simply echo an empty line in: echo > /debugfs/tracing/set_ftrace_filter Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b0dd009..f5911d2 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -43,7 +43,9 @@ extern void mcount(void); # define FTRACE_HASHSIZE (1< #include #include +#include +#include #include #include #include -#include +#include #include #include +#include #include #include "trace.h" @@ -151,12 +154,15 @@ enum { FTRACE_DISABLE_MCOUNT = (1 << 4), }; +static int ftrace_filtered; + static struct hlist_head ftrace_hash[FTRACE_HASHSIZE]; static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu); static DEFINE_SPINLOCK(ftrace_shutdown_lock); static DEFINE_MUTEX(ftraced_lock); +static DEFINE_MUTEX(ftrace_filter_lock); struct ftrace_page { struct ftrace_page *next; @@ -282,16 +288,82 @@ ftrace_record_ip(unsigned long ip) #define FTRACE_ADDR ((long)(&ftrace_caller)) #define MCOUNT_ADDR ((long)(&mcount)) -static void notrace ftrace_replace_code(int saved) +static void notrace +__ftrace_replace_code(struct dyn_ftrace *rec, + unsigned char *old, unsigned char *new, int enable) +{ + unsigned long ip; + int failed; + + ip = rec->ip; + + if (ftrace_filtered && enable) { + unsigned long fl; + /* + * If filtering is on: + * + * If this record is set to be filtered and + * is enabled then do nothing. + * + * If this record is set to be filtered and + * it is not enabled, enable it. + * + * If this record is not set to be filtered + * and it is not enabled do nothing. + * + * If this record is not set to be filtered and + * it is enabled, disable it. + */ + fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED); + + if ((fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) || + (fl == 0)) + return; + + /* + * If it is enabled disable it, + * otherwise enable it! + */ + if (fl == FTRACE_FL_ENABLED) { + /* swap new and old */ + new = old; + old = ftrace_call_replace(ip, FTRACE_ADDR); + rec->flags &= ~FTRACE_FL_ENABLED; + } else { + new = ftrace_call_replace(ip, FTRACE_ADDR); + rec->flags |= FTRACE_FL_ENABLED; + } + } else { + + if (enable) + new = ftrace_call_replace(ip, FTRACE_ADDR); + else + old = ftrace_call_replace(ip, FTRACE_ADDR); + + if (enable) { + if (rec->flags & FTRACE_FL_ENABLED) + return; + rec->flags |= FTRACE_FL_ENABLED; + } else { + if (!(rec->flags & FTRACE_FL_ENABLED)) + return; + rec->flags &= ~FTRACE_FL_ENABLED; + } + } + + failed = ftrace_modify_code(ip, old, new); + if (failed) + rec->flags |= FTRACE_FL_FAILED; +} + +static void notrace ftrace_replace_code(int enable) { unsigned char *new = NULL, *old = NULL; struct dyn_ftrace *rec; struct ftrace_page *pg; - unsigned long ip; - int failed; int i; - if (saved) + if (enable) old = ftrace_nop_replace(); else new = ftrace_nop_replace(); @@ -304,16 +376,7 @@ static void notrace ftrace_replace_code(int saved) if (rec->flags & FTRACE_FL_FAILED) continue; - ip = rec->ip; - - if (saved) - new = ftrace_call_replace(ip, FTRACE_ADDR); - else - old = ftrace_call_replace(ip, FTRACE_ADDR); - - failed = ftrace_modify_code(ip, old, new); - if (failed) - rec->flags |= FTRACE_FL_FAILED; + __ftrace_replace_code(rec, old, new, enable); } } } @@ -580,6 +643,436 @@ static int __init ftrace_dyn_table_alloc(void) return 0; } +enum { + FTRACE_ITER_FILTER = (1 << 0), + FTRACE_ITER_CONT = (1 << 1), +}; + +#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ + +struct ftrace_iterator { + loff_t pos; + struct ftrace_page *pg; + unsigned idx; + unsigned flags; + unsigned char buffer[FTRACE_BUFF_MAX+1]; + unsigned buffer_idx; + unsigned filtered; +}; + +static void notrace * +t_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct ftrace_iterator *iter = m->private; + struct dyn_ftrace *rec = NULL; + + (*pos)++; + + retry: + if (iter->idx >= iter->pg->index) { + if (iter->pg->next) { + iter->pg = iter->pg->next; + iter->idx = 0; + goto retry; + } + } else { + rec = &iter->pg->records[iter->idx++]; + if ((rec->flags & FTRACE_FL_FAILED) || + ((iter->flags & FTRACE_ITER_FILTER) && + !(rec->flags & FTRACE_FL_FILTER))) { + rec = NULL; + goto retry; + } + } + + iter->pos = *pos; + + return rec; +} + +static void *t_start(struct seq_file *m, loff_t *pos) +{ + struct ftrace_iterator *iter = m->private; + void *p = NULL; + loff_t l = -1; + + if (*pos != iter->pos) { + for (p = t_next(m, p, &l); p && l < *pos; p = t_next(m, p, &l)) + ; + } else { + l = *pos; + p = t_next(m, p, &l); + } + + return p; +} + +static void t_stop(struct seq_file *m, void *p) +{ +} + +static int t_show(struct seq_file *m, void *v) +{ + struct dyn_ftrace *rec = v; + char str[KSYM_SYMBOL_LEN]; + + if (!rec) + return 0; + + kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); + + seq_printf(m, "%s\n", str); + + return 0; +} + +static struct seq_operations show_ftrace_seq_ops = { + .start = t_start, + .next = t_next, + .stop = t_stop, + .show = t_show, +}; + +static int notrace +ftrace_avail_open(struct inode *inode, struct file *file) +{ + struct ftrace_iterator *iter; + int ret; + + iter = kzalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) + return -ENOMEM; + + iter->pg = ftrace_pages_start; + iter->pos = -1; + + ret = seq_open(file, &show_ftrace_seq_ops); + if (!ret) { + struct seq_file *m = file->private_data; + m->private = iter; + } else + kfree(iter); + + return ret; +} + +int ftrace_avail_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = (struct seq_file *)file->private_data; + struct ftrace_iterator *iter = m->private; + + seq_release(inode, file); + kfree(iter); + return 0; +} + +static void notrace ftrace_filter_reset(void) +{ + struct ftrace_page *pg; + struct dyn_ftrace *rec; + unsigned i; + + /* keep kstop machine from running */ + preempt_disable(); + ftrace_filtered = 0; + pg = ftrace_pages_start; + while (pg) { + for (i = 0; i < pg->index; i++) { + rec = &pg->records[i]; + if (rec->flags & FTRACE_FL_FAILED) + continue; + rec->flags &= ~FTRACE_FL_FILTER; + } + pg = pg->next; + } + preempt_enable(); +} + +static int notrace +ftrace_filter_open(struct inode *inode, struct file *file) +{ + struct ftrace_iterator *iter; + int ret = 0; + + iter = kzalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) + return -ENOMEM; + + mutex_lock(&ftrace_filter_lock); + if ((file->f_mode & FMODE_WRITE) && + !(file->f_flags & O_APPEND)) + ftrace_filter_reset(); + + if (file->f_mode & FMODE_READ) { + iter->pg = ftrace_pages_start; + iter->pos = -1; + iter->flags = FTRACE_ITER_FILTER; + + ret = seq_open(file, &show_ftrace_seq_ops); + if (!ret) { + struct seq_file *m = file->private_data; + m->private = iter; + } else + kfree(iter); + } else + file->private_data = iter; + mutex_unlock(&ftrace_filter_lock); + + return ret; +} + +static ssize_t notrace +ftrace_filter_read(struct file *file, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + if (file->f_mode & FMODE_READ) + return seq_read(file, ubuf, cnt, ppos); + else + return -EPERM; +} + +static loff_t notrace +ftrace_filter_lseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret; + + if (file->f_mode & FMODE_READ) + ret = seq_lseek(file, offset, origin); + else + file->f_pos = ret = 1; + + return ret; +} + +enum { + MATCH_FULL, + MATCH_FRONT_ONLY, + MATCH_MIDDLE_ONLY, + MATCH_END_ONLY, +}; + +static void notrace +ftrace_match(unsigned char *buff, int len) +{ + char str[KSYM_SYMBOL_LEN]; + char *search = NULL; + struct ftrace_page *pg; + struct dyn_ftrace *rec; + int type = MATCH_FULL; + unsigned i, match = 0, search_len = 0; + + for (i = 0; i < len; i++) { + if (buff[i] == '*') { + if (!i) { + search = buff + i + 1; + type = MATCH_END_ONLY; + search_len = len - (i + 1); + } else { + if (type == MATCH_END_ONLY) { + type = MATCH_MIDDLE_ONLY; + } else { + match = i; + type = MATCH_FRONT_ONLY; + } + buff[i] = 0; + break; + } + } + } + + /* keep kstop machine from running */ + preempt_disable(); + ftrace_filtered = 1; + pg = ftrace_pages_start; + while (pg) { + for (i = 0; i < pg->index; i++) { + int matched = 0; + char *ptr; + + rec = &pg->records[i]; + if (rec->flags & FTRACE_FL_FAILED) + continue; + kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); + switch (type) { + case MATCH_FULL: + if (strcmp(str, buff) == 0) + matched = 1; + break; + case MATCH_FRONT_ONLY: + if (memcmp(str, buff, match) == 0) + matched = 1; + break; + case MATCH_MIDDLE_ONLY: + if (strstr(str, search)) + matched = 1; + break; + case MATCH_END_ONLY: + ptr = strstr(str, search); + if (ptr && (ptr[search_len] == 0)) + matched = 1; + break; + } + if (matched) + rec->flags |= FTRACE_FL_FILTER; + } + pg = pg->next; + } + preempt_enable(); +} + +static ssize_t notrace +ftrace_filter_write(struct file *file, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct ftrace_iterator *iter; + char ch; + size_t read = 0; + ssize_t ret; + + if (!cnt || cnt < 0) + return 0; + + mutex_lock(&ftrace_filter_lock); + + if (file->f_mode & FMODE_READ) { + struct seq_file *m = file->private_data; + iter = m->private; + } else + iter = file->private_data; + + if (!*ppos) { + iter->flags &= ~FTRACE_ITER_CONT; + iter->buffer_idx = 0; + } + + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + + if (!(iter->flags & ~FTRACE_ITER_CONT)) { + /* skip white space */ + while (cnt && isspace(ch)) { + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + } + + + if (isspace(ch)) { + file->f_pos += read; + ret = read; + goto out; + } + + iter->buffer_idx = 0; + } + + while (cnt && !isspace(ch)) { + if (iter->buffer_idx < FTRACE_BUFF_MAX) + iter->buffer[iter->buffer_idx++] = ch; + else { + ret = -EINVAL; + goto out; + } + ret = get_user(ch, ubuf++); + if (ret) + goto out; + read++; + cnt--; + } + + if (isspace(ch)) { + iter->filtered++; + iter->buffer[iter->buffer_idx] = 0; + ftrace_match(iter->buffer, iter->buffer_idx); + iter->buffer_idx = 0; + } else + iter->flags |= FTRACE_ITER_CONT; + + + file->f_pos += read; + + ret = read; + out: + mutex_unlock(&ftrace_filter_lock); + + return ret; +} + +static int notrace +ftrace_filter_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = (struct seq_file *)file->private_data; + struct ftrace_iterator *iter; + + mutex_lock(&ftrace_filter_lock); + if (file->f_mode & FMODE_READ) { + iter = m->private; + + seq_release(inode, file); + } else + iter = file->private_data; + + if (iter->buffer_idx) { + iter->filtered++; + iter->buffer[iter->buffer_idx] = 0; + ftrace_match(iter->buffer, iter->buffer_idx); + } + + mutex_lock(&ftrace_sysctl_lock); + mutex_lock(&ftraced_lock); + if (iter->filtered && ftraced_suspend && ftrace_enabled) + ftrace_run_update_code(FTRACE_ENABLE_CALLS); + mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_sysctl_lock); + + kfree(iter); + mutex_unlock(&ftrace_filter_lock); + return 0; +} + +static struct file_operations ftrace_avail_fops = { + .open = ftrace_avail_open, + .read = seq_read, + .llseek = seq_lseek, + .release = ftrace_avail_release, +}; + +static struct file_operations ftrace_filter_fops = { + .open = ftrace_filter_open, + .read = ftrace_filter_read, + .write = ftrace_filter_write, + .llseek = ftrace_filter_lseek, + .release = ftrace_filter_release, +}; + +static __init int ftrace_init_debugfs(void) +{ + struct dentry *d_tracer; + struct dentry *entry; + + d_tracer = tracing_init_dentry(); + + entry = debugfs_create_file("available_filter_functions", 0444, + d_tracer, NULL, &ftrace_avail_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'available_filter_functions' entry\n"); + + entry = debugfs_create_file("set_ftrace_filter", 0644, d_tracer, + NULL, &ftrace_filter_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'set_ftrace_filter' entry\n"); + return 0; +} + +fs_initcall(ftrace_init_debugfs); + static int __init notrace ftrace_dynamic_init(void) { struct task_struct *p; @@ -657,14 +1150,14 @@ int unregister_ftrace_function(struct ftrace_ops *ops) notrace int ftrace_enable_sysctl(struct ctl_table *table, int write, - struct file *filp, void __user *buffer, size_t *lenp, + struct file *file, void __user *buffer, size_t *lenp, loff_t *ppos) { int ret; mutex_lock(&ftrace_sysctl_lock); - ret = proc_dointvec(table, write, filp, buffer, lenp, ppos); + ret = proc_dointvec(table, write, file, buffer, lenp, ppos); if (ret || !write || (last_ftrace_enabled == ftrace_enabled)) goto out; -- cgit v0.10.2 From 4c11d7aed389375253b59e2b1865eec96663c65d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: convert single large buffer into single pages. Allocating large buffers for the tracer may fail easily. This patch converts the buffer from a large ordered allocation to single pages. It uses the struct page LRU field to link the pages together. Later patches may also implement dynamic increasing and decreasing of the trace buffers. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1b8eca7..d7ad030 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,7 @@ static struct trace_array max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_data); static int tracer_enabled; -static unsigned long trace_nr_entries = 4096UL; +static unsigned long trace_nr_entries = 16384UL; static struct tracer *trace_types __read_mostly; static struct tracer *current_trace __read_mostly; @@ -57,6 +58,8 @@ static int max_tracer_type_len; static DEFINE_MUTEX(trace_types_lock); +#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry)) + static int __init set_nr_entries(char *str) { if (!str) @@ -103,6 +106,7 @@ static const char *trace_options[] = { static unsigned trace_flags; +static DEFINE_SPINLOCK(ftrace_max_lock); /* * Copy the new maximum trace into the separate maximum-trace @@ -136,17 +140,23 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data; void *save_trace; + struct list_head save_pages; int i; + WARN_ON_ONCE(!irqs_disabled()); + spin_lock(&ftrace_max_lock); /* clear out all the previous traces */ for_each_possible_cpu(i) { data = tr->data[i]; save_trace = max_tr.data[i]->trace; + save_pages = max_tr.data[i]->trace_pages; memcpy(max_tr.data[i], data, sizeof(*data)); data->trace = save_trace; + data->trace_pages = save_pages; } __update_max_tr(tr, tsk, cpu); + spin_unlock(&ftrace_max_lock); } /** @@ -160,16 +170,22 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data = tr->data[cpu]; void *save_trace; + struct list_head save_pages; int i; + WARN_ON_ONCE(!irqs_disabled()); + spin_lock(&ftrace_max_lock); for_each_possible_cpu(i) tracing_reset(max_tr.data[i]); save_trace = max_tr.data[cpu]->trace; + save_pages = max_tr.data[cpu]->trace_pages; memcpy(max_tr.data[cpu], data, sizeof(*data)); data->trace = save_trace; + data->trace_pages = save_pages; __update_max_tr(tr, tsk, cpu); + spin_unlock(&ftrace_max_lock); } int register_tracer(struct tracer *type) @@ -236,7 +252,8 @@ void unregister_tracer(struct tracer *type) void notrace tracing_reset(struct trace_array_cpu *data) { data->trace_idx = 0; - atomic_set(&data->underrun, 0); + data->trace_current = data->trace; + data->trace_current_idx = 0; } #ifdef CONFIG_FTRACE @@ -367,21 +384,27 @@ tracing_get_trace_entry(struct trace_array *tr, { unsigned long idx, idx_next; struct trace_entry *entry; + struct page *page; + struct list_head *next; - idx = data->trace_idx; + data->trace_idx++; + idx = data->trace_current_idx; idx_next = idx + 1; - if (unlikely(idx_next >= tr->entries)) { - atomic_inc(&data->underrun); + entry = data->trace_current + idx * TRACE_ENTRY_SIZE; + + if (unlikely(idx_next >= ENTRIES_PER_PAGE)) { + page = virt_to_page(data->trace_current); + if (unlikely(&page->lru == data->trace_pages.prev)) + next = data->trace_pages.next; + else + next = page->lru.next; + page = list_entry(next, struct page, lru); + data->trace_current = page_address(page); idx_next = 0; } - data->trace_idx = idx_next; - - if (unlikely(idx_next != 0 && atomic_read(&data->underrun))) - atomic_inc(&data->underrun); - - entry = data->trace + idx * TRACE_ENTRY_SIZE; + data->trace_current_idx = idx_next; return entry; } @@ -442,21 +465,38 @@ enum trace_file_type { }; static struct trace_entry * -trace_entry_idx(struct trace_array *tr, unsigned long idx, int cpu) +trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, + struct trace_iterator *iter, int cpu) { - struct trace_entry *array = tr->data[cpu]->trace; - unsigned long underrun; + struct page *page; + struct trace_entry *array; - if (idx >= tr->entries) + if (iter->next_idx[cpu] >= tr->entries || + iter->next_idx[cpu] >= data->trace_idx) return NULL; - underrun = atomic_read(&tr->data[cpu]->underrun); - if (underrun) - idx = ((underrun - 1) + idx) % tr->entries; - else if (idx >= tr->data[cpu]->trace_idx) - return NULL; + if (!iter->next_page[cpu]) { + /* + * Initialize. If the count of elements in + * this buffer is greater than the max entries + * we had an underrun. Which means we looped around. + * We can simply use the current pointer as our + * starting point. + */ + if (data->trace_idx >= tr->entries) { + page = virt_to_page(data->trace_current); + iter->next_page[cpu] = &page->lru; + iter->next_page_idx[cpu] = data->trace_current_idx; + } else { + iter->next_page[cpu] = data->trace_pages.next; + iter->next_page_idx[cpu] = 0; + } + } - return &array[idx]; + page = list_entry(iter->next_page[cpu], struct page, lru); + array = page_address(page); + + return &array[iter->next_page_idx[cpu]]; } static struct notrace trace_entry * @@ -470,7 +510,7 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) for_each_possible_cpu(cpu) { if (!tr->data[cpu]->trace) continue; - ent = trace_entry_idx(tr, iter->next_idx[cpu], cpu); + ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu); if (ent && (!next || (long)(next->idx - ent->idx) > 0)) { next = ent; @@ -492,8 +532,19 @@ static void *find_next_entry_inc(struct trace_iterator *iter) next = find_next_entry(iter, &next_cpu); if (next) { - iter->next_idx[next_cpu]++; iter->idx++; + iter->next_idx[next_cpu]++; + iter->next_page_idx[next_cpu]++; + if (iter->next_page_idx[next_cpu] >= ENTRIES_PER_PAGE) { + struct trace_array_cpu *data = iter->tr->data[next_cpu]; + + iter->next_page_idx[next_cpu] = 0; + iter->next_page[next_cpu] = + iter->next_page[next_cpu]->next; + if (iter->next_page[next_cpu] == &data->trace_pages) + iter->next_page[next_cpu] = + data->trace_pages.next; + } } iter->ent = next; iter->cpu = next_cpu; @@ -554,14 +605,16 @@ static void *s_start(struct seq_file *m, loff_t *pos) iter->cpu = 0; iter->idx = -1; - for (i = 0; i < NR_CPUS; i++) + for_each_possible_cpu(i) { iter->next_idx[i] = 0; + iter->next_page[i] = NULL; + } for (p = iter; p && l < *pos; p = s_next(m, p, &l)) ; } else { - l = *pos; + l = *pos - 1; p = s_next(m, p, &l); } @@ -654,9 +707,8 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) struct trace_array *tr = iter->tr; struct trace_array_cpu *data = tr->data[tr->cpu]; struct tracer *type = current_trace; - unsigned long underruns = 0; - unsigned long underrun; - unsigned long entries = 0; + unsigned long total = 0; + unsigned long entries = 0; int cpu; const char *name = "preemption"; @@ -665,11 +717,10 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) for_each_possible_cpu(cpu) { if (tr->data[cpu]->trace) { - underrun = atomic_read(&tr->data[cpu]->underrun); - if (underrun) { - underruns += underrun; + total += tr->data[cpu]->trace_idx; + if (tr->data[cpu]->trace_idx > tr->entries) entries += tr->entries; - } else + else entries += tr->data[cpu]->trace_idx; } } @@ -682,7 +733,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) " (M:%s VP:%d, KP:%d, SP:%d HP:%d", data->saved_latency, entries, - (entries + underruns), + total, tr->cpu, #if defined(CONFIG_PREEMPT_NONE) "server", @@ -882,8 +933,7 @@ static int trace_empty(struct trace_iterator *iter) data = iter->tr->data[cpu]; if (data->trace && - (data->trace_idx || - atomic_read(&data->underrun))) + data->trace_idx) return 0; } return 1; @@ -1464,42 +1514,109 @@ static struct tracer no_tracer __read_mostly = .name = "none", }; -static inline notrace int page_order(const unsigned long size) +static int trace_alloc_page(void) { - const unsigned long nr_pages = DIV_ROUND_UP(size, PAGE_SIZE); - return ilog2(roundup_pow_of_two(nr_pages)); + struct trace_array_cpu *data; + void *array; + struct page *page, *tmp; + LIST_HEAD(pages); + int i; + + /* first allocate a page for each CPU */ + for_each_possible_cpu(i) { + array = (void *)__get_free_page(GFP_KERNEL); + if (array == NULL) { + printk(KERN_ERR "tracer: failed to allocate page" + "for trace buffer!\n"); + goto free_pages; + } + + page = virt_to_page(array); + list_add(&page->lru, &pages); + +/* Only allocate if we are actually using the max trace */ +#ifdef CONFIG_TRACER_MAX_TRACE + array = (void *)__get_free_page(GFP_KERNEL); + if (array == NULL) { + printk(KERN_ERR "tracer: failed to allocate page" + "for trace buffer!\n"); + goto free_pages; + } + page = virt_to_page(array); + list_add(&page->lru, &pages); +#endif + } + + /* Now that we successfully allocate a page per CPU, add them */ + for_each_possible_cpu(i) { + data = global_trace.data[i]; + page = list_entry(pages.next, struct page, lru); + list_del(&page->lru); + list_add_tail(&page->lru, &data->trace_pages); + ClearPageLRU(page); + +#ifdef CONFIG_TRACER_MAX_TRACE + data = max_tr.data[i]; + page = list_entry(pages.next, struct page, lru); + list_del(&page->lru); + list_add_tail(&page->lru, &data->trace_pages); + SetPageLRU(page); +#endif + } + global_trace.entries += ENTRIES_PER_PAGE; + + return 0; + + free_pages: + list_for_each_entry_safe(page, tmp, &pages, lru) { + list_del(&page->lru); + __free_page(page); + } + return -ENOMEM; } __init static int tracer_alloc_buffers(void) { - const int order = page_order(trace_nr_entries * TRACE_ENTRY_SIZE); - const unsigned long size = (1UL << order) << PAGE_SHIFT; - struct trace_entry *array; + struct trace_array_cpu *data; + void *array; + struct page *page; + int pages = 0; int i; + /* Allocate the first page for all buffers */ for_each_possible_cpu(i) { - global_trace.data[i] = &per_cpu(global_trace_cpu, i); + data = global_trace.data[i] = &per_cpu(global_trace_cpu, i); max_tr.data[i] = &per_cpu(max_data, i); - array = (struct trace_entry *) - __get_free_pages(GFP_KERNEL, order); + array = (void *)__get_free_page(GFP_KERNEL); if (array == NULL) { - printk(KERN_ERR "tracer: failed to allocate" - " %ld bytes for trace buffer!\n", size); + printk(KERN_ERR "tracer: failed to allocate page" + "for trace buffer!\n"); goto free_buffers; } - global_trace.data[i]->trace = array; + data->trace = array; + + /* set the array to the list */ + INIT_LIST_HEAD(&data->trace_pages); + page = virt_to_page(array); + list_add(&page->lru, &data->trace_pages); + /* use the LRU flag to differentiate the two buffers */ + ClearPageLRU(page); /* Only allocate if we are actually using the max trace */ #ifdef CONFIG_TRACER_MAX_TRACE - array = (struct trace_entry *) - __get_free_pages(GFP_KERNEL, order); + array = (void *)__get_free_page(GFP_KERNEL); if (array == NULL) { - printk(KERN_ERR "wakeup tracer: failed to allocate" - " %ld bytes for trace buffer!\n", size); + printk(KERN_ERR "tracer: failed to allocate page" + "for trace buffer!\n"); goto free_buffers; } max_tr.data[i]->trace = array; + + INIT_LIST_HEAD(&max_tr.data[i]->trace_pages); + page = virt_to_page(array); + list_add(&page->lru, &max_tr.data[i]->trace_pages); + SetPageLRU(page); #endif } @@ -1507,11 +1624,18 @@ __init static int tracer_alloc_buffers(void) * Since we allocate by orders of pages, we may be able to * round up a bit. */ - global_trace.entries = size / TRACE_ENTRY_SIZE; + global_trace.entries = ENTRIES_PER_PAGE; max_tr.entries = global_trace.entries; + pages++; + + while (global_trace.entries < trace_nr_entries) { + if (trace_alloc_page()) + break; + pages++; + } - pr_info("tracer: %ld bytes allocated for %ld", - size, trace_nr_entries); + pr_info("tracer: %d pages allocated for %ld", + pages, trace_nr_entries); pr_info(" entries of %ld bytes\n", (long)TRACE_ENTRY_SIZE); pr_info(" actual entries %ld\n", global_trace.entries); @@ -1526,17 +1650,26 @@ __init static int tracer_alloc_buffers(void) free_buffers: for (i-- ; i >= 0; i--) { + struct page *page, *tmp; struct trace_array_cpu *data = global_trace.data[i]; if (data && data->trace) { - free_pages((unsigned long)data->trace, order); + list_for_each_entry_safe(page, tmp, + &data->trace_pages, lru) { + list_del(&page->lru); + __free_page(page); + } data->trace = NULL; } #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; if (data && data->trace) { - free_pages((unsigned long)data->trace, order); + list_for_each_entry_safe(page, tmp, + &data->trace_pages, lru) { + list_del(&page->lru); + __free_page(page); + } data->trace = NULL; } #endif diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 3173a93..83e257e 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -54,9 +54,11 @@ struct trace_entry { */ struct trace_array_cpu { void *trace; + void *trace_current; + unsigned trace_current_idx; + struct list_head trace_pages; unsigned long trace_idx; atomic_t disabled; - atomic_t underrun; unsigned long saved_latency; unsigned long critical_start; unsigned long critical_end; @@ -112,8 +114,10 @@ struct trace_iterator { unsigned long iter_flags; loff_t pos; unsigned long next_idx[NR_CPUS]; + struct list_head *next_page[NR_CPUS]; + unsigned next_page_idx[NR_CPUS]; + long idx; int cpu; - int idx; }; void notrace tracing_reset(struct trace_array_cpu *data); -- cgit v0.10.2 From f43fdad8627fec2d21df92799b254dceb66c9c3c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:43 +0200 Subject: ftrace: fix kexec disable the tracer while kexec pulls the rug from under the old kernel. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index d0b234c..88923fd 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -11,6 +11,8 @@ #include #include #include +#include + #include #include #include @@ -107,6 +109,8 @@ NORET_TYPE void machine_kexec(struct kimage *image) unsigned long page_list[PAGES_NR]; void *control_page; + tracer_disable(); + /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 576a03d..1558fdc 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -11,6 +11,8 @@ #include #include #include +#include + #include #include #include @@ -184,6 +186,8 @@ NORET_TYPE void machine_kexec(struct kimage *image) unsigned long page_list[PAGES_NR]; void *control_page; + tracer_disable(); + /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index f5911d2..a42390c 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -68,6 +68,13 @@ extern void ftrace_call(void); extern void mcount_call(void); #endif +static inline void tracer_disable(void) +{ +#ifdef CONFIG_FTRACE + ftrace_enabled = 0; +#endif +} + #ifdef CONFIG_FRAME_POINTER /* TODO: need to fix this for ARM */ # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) -- cgit v0.10.2 From 5568b139f4d196273958ae2947a736fdf1ffeece Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: debug smp_processor_id, use notrace preempt disable The debug smp_processor_id caused a recursive fault in debugging the irqsoff tracer. The tracer used a smp_processor_id in the ftrace callback, and this function called preempt_disable which also is traced. This caused a recursive fault (stack overload). Since using smp_processor_id without debugging on does not cause faults with the tracer (even when the tracer is wrong), the debug version should not cause a system reboot. This changes the debug_smp_processor_id to use the notrace versions of preempt_disable and enable. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index e555ab6..3b4dc09 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -37,7 +37,7 @@ notrace unsigned int debug_smp_processor_id(void) /* * Avoid recursion: */ - preempt_disable(); + preempt_disable_notrace(); if (!printk_ratelimit()) goto out_enable; @@ -49,7 +49,7 @@ notrace unsigned int debug_smp_processor_id(void) dump_stack(); out_enable: - preempt_enable_no_resched(); + preempt_enable_no_resched_notrace(); out: return this_cpu; } -- cgit v0.10.2 From 361943ad0ba3f16e66859e30a408915e008ba91e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: irqs off smp_processor_id() fix The irqsoff function tracer did a __get_cpu_var to determine if it should trace the function or not. The problem is that __get_cpu_var can preempt between getting the CPU and reading the cpu variable. This means that the cpu variable that is being read is not from the cpu being run on. At worst, this can give a false positive, where we trace the function when we should not. It will never give a false negative since we only want to trace when interrupts are disabled and we never preempt when they are. This fix adds a check after reading the irq flags to only trace if the interrupts are actually disabled. It also changes the reading of the cpu variable to use a raw_smp_processor_id since we now don't care if we preempt. We still catch that fact. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 8b12316..bd3f881 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -74,12 +74,21 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) long disabled; int cpu; - if (likely(!__get_cpu_var(tracing_cpu))) + /* + * Does not matter if we preempt. We test the flags + * afterward, to see if irqs are disabled or not. + * If we preempt and get a false positive, the flags + * test will fail. + */ + cpu = raw_smp_processor_id(); + if (likely(!per_cpu(tracing_cpu, cpu))) return; local_save_flags(flags); + /* slight chance to get a false positive on tracing_cpu */ + if (!irqs_disabled_flags(flags)) + return; - cpu = raw_smp_processor_id(); data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); -- cgit v0.10.2 From 0764d23cf066c52de42b653144605b481d3fbdbc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: lockdep notrace annotations Add notrace annotations to lockdep to keep ftrace from causing recursive problems with lock tracing and debugging. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/lockdep.c b/kernel/lockdep.c index e219243..ac46847 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -271,14 +271,14 @@ static struct list_head chainhash_table[CHAINHASH_SIZE]; ((key1) >> (64-MAX_LOCKDEP_KEYS_BITS)) ^ \ (key2)) -void lockdep_off(void) +notrace void lockdep_off(void) { current->lockdep_recursion++; } EXPORT_SYMBOL(lockdep_off); -void lockdep_on(void) +notrace void lockdep_on(void) { current->lockdep_recursion--; } @@ -1041,7 +1041,7 @@ find_usage_forwards(struct lock_class *source, unsigned int depth) * Return 1 otherwise and keep unchanged. * Return 0 on error. */ -static noinline int +static noinline notrace int find_usage_backwards(struct lock_class *source, unsigned int depth) { struct lock_list *entry; @@ -1591,7 +1591,7 @@ static inline int validate_chain(struct task_struct *curr, * We are building curr_chain_key incrementally, so double-check * it from scratch, to make sure that it's done correctly: */ -static void check_chain_key(struct task_struct *curr) +static notrace void check_chain_key(struct task_struct *curr) { #ifdef CONFIG_DEBUG_LOCKDEP struct held_lock *hlock, *prev_hlock = NULL; @@ -1967,7 +1967,7 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, /* * Mark all held locks with a usage bit: */ -static int +static notrace int mark_held_locks(struct task_struct *curr, int hardirq) { enum lock_usage_bit usage_bit; @@ -2260,8 +2260,8 @@ static inline int separate_irq_context(struct task_struct *curr, /* * Mark a lock with a usage bit, and validate the state transition: */ -static int mark_lock(struct task_struct *curr, struct held_lock *this, - enum lock_usage_bit new_bit) +static notrace int mark_lock(struct task_struct *curr, struct held_lock *this, + enum lock_usage_bit new_bit) { unsigned int new_mask = 1 << new_bit, ret = 1; @@ -2663,7 +2663,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) /* * Check whether we follow the irq-flags state precisely: */ -static void check_flags(unsigned long flags) +static notrace void check_flags(unsigned long flags) { #if defined(CONFIG_DEBUG_LOCKDEP) && defined(CONFIG_TRACE_IRQFLAGS) if (!debug_locks) @@ -2700,8 +2700,8 @@ static void check_flags(unsigned long flags) * We are not always called with irqs disabled - do that here, * and also avoid lockdep recursion: */ -void lock_acquire(struct lockdep_map *lock, unsigned int subclass, - int trylock, int read, int check, unsigned long ip) +notrace void lock_acquire(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, unsigned long ip) { unsigned long flags; @@ -2723,7 +2723,8 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, EXPORT_SYMBOL_GPL(lock_acquire); -void lock_release(struct lockdep_map *lock, int nested, unsigned long ip) +notrace void lock_release(struct lockdep_map *lock, int nested, + unsigned long ip) { unsigned long flags; diff --git a/kernel/spinlock.c b/kernel/spinlock.c index ae28c82..a1fb54c 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -436,7 +436,7 @@ int __lockfunc _spin_trylock_bh(spinlock_t *lock) } EXPORT_SYMBOL(_spin_trylock_bh); -int in_lock_functions(unsigned long addr) +notrace int in_lock_functions(unsigned long addr) { /* Linker adds these: start and end of __lockfunc functions */ extern char __lock_text_start[], __lock_text_end[]; -- cgit v0.10.2 From 18cef379d30f5ded20cc31d7f2d342639d39919d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: don't use raw_local_irq_save/restore Using raw_local_irq_save/restore confuses lockdep. It's fine to use the normal ones. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d7ad030..9175ce9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -269,7 +269,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip) if (unlikely(!tracer_enabled)) return; - raw_local_irq_save(flags); + local_irq_save(flags); cpu = raw_smp_processor_id(); data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); @@ -278,7 +278,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip) ftrace(tr, data, ip, parent_ip, flags); atomic_dec(&data->disabled); - raw_local_irq_restore(flags); + local_irq_restore(flags); } static struct ftrace_ops trace_ops __read_mostly = diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 3e4771d..2715267 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -29,7 +29,7 @@ ctx_switch_func(struct task_struct *prev, struct task_struct *next) if (!tracer_enabled) return; - raw_local_irq_save(flags); + local_irq_save(flags); cpu = raw_smp_processor_id(); data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); @@ -38,7 +38,7 @@ ctx_switch_func(struct task_struct *prev, struct task_struct *next) tracing_sched_switch_trace(tr, data, prev, next, flags); atomic_dec(&data->disabled); - raw_local_irq_restore(flags); + local_irq_restore(flags); } void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) -- cgit v0.10.2 From 89b2f97819dd074297bbe3e19eaa4afcc98845ad Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: fix updates to max trace This patch fixes some bugs to the updating of the max trace that was caused by implementing the new buffering. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9175ce9..9596656 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -153,6 +153,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) memcpy(max_tr.data[i], data, sizeof(*data)); data->trace = save_trace; data->trace_pages = save_pages; + tracing_reset(data); } __update_max_tr(tr, tsk, cpu); @@ -183,6 +184,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) memcpy(max_tr.data[cpu], data, sizeof(*data)); data->trace = save_trace; data->trace_pages = save_pages; + tracing_reset(data); __update_max_tr(tr, tsk, cpu); spin_unlock(&ftrace_max_lock); @@ -877,6 +879,8 @@ print_lat_fmt(struct seq_file *m, struct trace_iterator *iter, entry->ctx.next_prio, comm); break; + default: + seq_printf(m, "Unknown type %d\n", entry->type); } } @@ -1625,7 +1629,6 @@ __init static int tracer_alloc_buffers(void) * round up a bit. */ global_trace.entries = ENTRIES_PER_PAGE; - max_tr.entries = global_trace.entries; pages++; while (global_trace.entries < trace_nr_entries) { @@ -1633,6 +1636,7 @@ __init static int tracer_alloc_buffers(void) break; pages++; } + max_tr.entries = global_trace.entries; pr_info("tracer: %d pages allocated for %ld", pages, trace_nr_entries); diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index bd3f881..74165f6 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -23,6 +23,8 @@ static int tracer_enabled __read_mostly; static DEFINE_PER_CPU(int, tracing_cpu); +static DEFINE_SPINLOCK(max_trace_lock); + enum { TRACER_IRQS_OFF = (1 << 1), TRACER_PREEMPT_OFF = (1 << 2), @@ -126,7 +128,7 @@ check_critical_timing(struct trace_array *tr, int cpu) { unsigned long latency, t0, t1; - cycle_t T0, T1, T2, delta; + cycle_t T0, T1, delta; unsigned long flags; /* @@ -142,20 +144,18 @@ check_critical_timing(struct trace_array *tr, if (!report_latency(delta)) goto out; - ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); - /* - * Update the timestamp, because the trace entry above - * might change it (it can only get larger so the latency - * is fair to be reported): - */ - T2 = now(cpu); + spin_lock(&max_trace_lock); - delta = T2-T0; + /* check if we are still the max latency */ + if (!report_latency(delta)) + goto out_unlock; + + ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); latency = nsecs_to_usecs(delta); if (data->critical_sequence != max_sequence) - goto out; + goto out_unlock; tracing_max_latency = delta; t0 = nsecs_to_usecs(T0); @@ -189,6 +189,9 @@ check_critical_timing(struct trace_array *tr, max_sequence++; +out_unlock: + spin_unlock(&max_trace_lock); + out: data->critical_sequence = max_sequence; data->preempt_timestamp = now(cpu); @@ -366,14 +369,14 @@ void notrace trace_preempt_off(unsigned long a0, unsigned long a1) static void start_irqsoff_tracer(struct trace_array *tr) { - tracer_enabled = 1; register_ftrace_function(&trace_ops); + tracer_enabled = 1; } static void stop_irqsoff_tracer(struct trace_array *tr) { - unregister_ftrace_function(&trace_ops); tracer_enabled = 0; + unregister_ftrace_function(&trace_ops); } static void __irqsoff_tracer_init(struct trace_array *tr) -- cgit v0.10.2 From 57f50be14d57b0dbf88dd019e7bb0ff3a3dc7b81 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: fix max latency Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9596656..9bad237 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -69,6 +69,11 @@ static int __init set_nr_entries(char *str) } __setup("trace_entries=", set_nr_entries); +unsigned long nsecs_to_usecs(unsigned long nsecs) +{ + return nsecs / 1000; +} + enum trace_type { __TRACE_FIRST_TYPE = 0, @@ -733,7 +738,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) "---------------------------------\n"); seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d |" " (M:%s VP:%d, KP:%d, SP:%d HP:%d", - data->saved_latency, + nsecs_to_usecs(data->saved_latency), entries, total, tr->cpu, @@ -771,11 +776,6 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) seq_puts(m, "\n"); } -unsigned long nsecs_to_usecs(unsigned long nsecs) -{ - return nsecs / 1000; -} - static void notrace lat_print_generic(struct seq_file *m, struct trace_entry *entry, int cpu) { -- cgit v0.10.2 From e1c08bdd9fa73e44096e5a82c0d5928b04ab02c8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: force recording Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a42390c..2c1670c 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -54,6 +54,8 @@ struct dyn_ftrace { unsigned long flags; }; +int ftrace_force_update(void); + /* defined in arch */ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); @@ -66,6 +68,8 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); +#else +# define ftrace_force_update() do { } while (0) #endif static inline void tracer_disable(void) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 97d5cb7..4facf5c 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -146,6 +146,10 @@ static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) #ifdef CONFIG_DYNAMIC_FTRACE +static struct task_struct *ftraced_task; +static DECLARE_WAIT_QUEUE_HEAD(ftraced_waiters); +static unsigned long ftraced_iteration_counter; + enum { FTRACE_ENABLE_CALLS = (1 << 0), FTRACE_DISABLE_CALLS = (1 << 1), @@ -590,9 +594,12 @@ static int notrace ftraced(void *ignore) ftraced_trigger = 0; ftrace_record_suspend--; } + ftraced_iteration_counter++; mutex_unlock(&ftraced_lock); mutex_unlock(&ftrace_sysctl_lock); + wake_up_interruptible(&ftraced_waiters); + ftrace_shutdown_replenish(); set_current_state(TASK_INTERRUPTIBLE); @@ -1050,6 +1057,49 @@ static struct file_operations ftrace_filter_fops = { .release = ftrace_filter_release, }; +/** + * ftrace_force_update - force an update to all recording ftrace functions + * + * The ftrace dynamic update daemon only wakes up once a second. + * There may be cases where an update needs to be done immediately + * for tests or internal kernel tracing to begin. This function + * wakes the daemon to do an update and will not return until the + * update is complete. + */ +int ftrace_force_update(void) +{ + unsigned long last_counter; + DECLARE_WAITQUEUE(wait, current); + int ret = 0; + + if (!ftraced_task) + return -ENODEV; + + mutex_lock(&ftraced_lock); + last_counter = ftraced_iteration_counter; + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&ftraced_waiters, &wait); + + do { + mutex_unlock(&ftraced_lock); + wake_up_process(ftraced_task); + schedule(); + mutex_lock(&ftraced_lock); + if (signal_pending(current)) { + ret = -EINTR; + break; + } + set_current_state(TASK_INTERRUPTIBLE); + } while (last_counter == ftraced_iteration_counter); + + mutex_unlock(&ftraced_lock); + remove_wait_queue(&ftraced_waiters, &wait); + set_current_state(TASK_RUNNING); + + return ret; +} + static __init int ftrace_init_debugfs(void) { struct dentry *d_tracer; @@ -1095,6 +1145,7 @@ static int __init notrace ftrace_dynamic_init(void) return -1; last_ftrace_enabled = ftrace_enabled = 1; + ftraced_task = p; return 0; } -- cgit v0.10.2 From 60a11774b38fef1ab90b18c5353bd1c7c4d311c8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:44 +0200 Subject: ftrace: add self-tests Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index cad9db1..3f73a17 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -105,3 +105,16 @@ config DYNAMIC_FTRACE wakes up once a second and checks to see if any ftrace calls were made. If so, it runs stop_machine (stops all CPUS) and modifies the code to jump over the call to ftrace. + +config FTRACE_SELFTEST + bool + +config FTRACE_STARTUP_TEST + bool "Perform a startup test on ftrace" + depends on TRACING + select FTRACE_SELFTEST + help + This option performs a series of startup tests on ftrace. On bootup + a series of tests are made to verify that the tracer is + functioning properly. It will do tests on all the configured + tracers of ftrace. diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9bad237..f6d026f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -32,6 +32,8 @@ unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; unsigned long __read_mostly tracing_thresh; +static int tracing_disabled = 1; + static long notrace ns2usecs(cycle_t nsec) { @@ -217,11 +219,48 @@ int register_tracer(struct tracer *type) } } +#ifdef CONFIG_FTRACE_STARTUP_TEST + if (type->selftest) { + struct tracer *saved_tracer = current_trace; + struct trace_array_cpu *data; + struct trace_array *tr = &global_trace; + int saved_ctrl = tr->ctrl; + int i; + /* + * Run a selftest on this tracer. + * Here we reset the trace buffer, and set the current + * tracer to be this tracer. The tracer can then run some + * internal tracing to verify that everything is in order. + * If we fail, we do not register this tracer. + */ + for_each_possible_cpu(i) { + if (!data->trace) + continue; + data = tr->data[i]; + tracing_reset(data); + } + current_trace = type; + tr->ctrl = 0; + /* the test is responsible for initializing and enabling */ + pr_info("Testing tracer %s: ", type->name); + ret = type->selftest(type, tr); + /* the test is responsible for resetting too */ + current_trace = saved_tracer; + tr->ctrl = saved_ctrl; + if (ret) { + printk(KERN_CONT "FAILED!\n"); + goto out; + } + printk(KERN_CONT "PASSED\n"); + } +#endif + type->next = trace_types; trace_types = type; len = strlen(type->name); if (len > max_tracer_type_len) max_tracer_type_len = len; + out: mutex_unlock(&trace_types_lock); @@ -985,6 +1024,11 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) { struct trace_iterator *iter; + if (tracing_disabled) { + *ret = -ENODEV; + return NULL; + } + iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (!iter) { *ret = -ENOMEM; @@ -1023,6 +1067,9 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) int tracing_open_generic(struct inode *inode, struct file *filp) { + if (tracing_disabled) + return -ENODEV; + filp->private_data = inode->i_private; return 0; } @@ -1128,6 +1175,9 @@ static int show_traces_open(struct inode *inode, struct file *file) { int ret; + if (tracing_disabled) + return -ENODEV; + ret = seq_open(file, &show_traces_seq_ops); if (!ret) { struct seq_file *m = file->private_data; @@ -1452,6 +1502,11 @@ struct dentry *tracing_init_dentry(void) return d_tracer; } +#ifdef CONFIG_FTRACE_SELFTEST +/* Let selftest have access to static functions in this file */ +#include "trace_selftest.c" +#endif + static __init void tracer_init_debugfs(void) { struct dentry *d_tracer; @@ -1585,6 +1640,7 @@ __init static int tracer_alloc_buffers(void) void *array; struct page *page; int pages = 0; + int ret = -ENOMEM; int i; /* Allocate the first page for all buffers */ @@ -1650,6 +1706,9 @@ __init static int tracer_alloc_buffers(void) register_tracer(&no_tracer); current_trace = &no_tracer; + /* All seems OK, enable tracing */ + tracing_disabled = 0; + return 0; free_buffers: @@ -1678,7 +1737,7 @@ __init static int tracer_alloc_buffers(void) } #endif } - return -ENOMEM; + return ret; } -device_initcall(tracer_alloc_buffers); +fs_initcall(tracer_alloc_buffers); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 83e257e..88edbf1 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -99,6 +99,10 @@ struct tracer { void (*start)(struct trace_iterator *iter); void (*stop)(struct trace_iterator *iter); void (*ctrl_update)(struct trace_array *tr); +#ifdef CONFIG_FTRACE_STARTUP_TEST + int (*selftest)(struct tracer *trace, + struct trace_array *tr); +#endif struct tracer *next; int print_max; }; @@ -185,4 +189,31 @@ extern int unregister_tracer_switch(struct tracer_switch_ops *ops); extern unsigned long ftrace_update_tot_cnt; #endif +#ifdef CONFIG_FTRACE_STARTUP_TEST +#ifdef CONFIG_FTRACE +extern int trace_selftest_startup_function(struct tracer *trace, + struct trace_array *tr); +#endif +#ifdef CONFIG_IRQSOFF_TRACER +extern int trace_selftest_startup_irqsoff(struct tracer *trace, + struct trace_array *tr); +#endif +#ifdef CONFIG_PREEMPT_TRACER +extern int trace_selftest_startup_preemptoff(struct tracer *trace, + struct trace_array *tr); +#endif +#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER) +extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace, + struct trace_array *tr); +#endif +#ifdef CONFIG_SCHED_TRACER +extern int trace_selftest_startup_wakeup(struct tracer *trace, + struct trace_array *tr); +#endif +#ifdef CONFIG_CONTEXT_SWITCH_TRACER +extern int trace_selftest_startup_sched_switch(struct tracer *trace, + struct trace_array *tr); +#endif +#endif /* CONFIG_FTRACE_STARTUP_TEST */ + #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 82988c5..5d8ad7a 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -63,6 +63,9 @@ static struct tracer function_trace __read_mostly = .init = function_trace_init, .reset = function_trace_reset, .ctrl_update = function_trace_ctrl_update, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_function, +#endif }; static __init int init_function_trace(void) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 74165f6..14183b8 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -432,6 +432,9 @@ static struct tracer irqsoff_tracer __read_mostly = .close = irqsoff_tracer_close, .ctrl_update = irqsoff_tracer_ctrl_update, .print_max = 1, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_irqsoff, +#endif }; # define register_irqsoff(trace) register_tracer(&trace) #else @@ -455,6 +458,9 @@ static struct tracer preemptoff_tracer __read_mostly = .close = irqsoff_tracer_close, .ctrl_update = irqsoff_tracer_ctrl_update, .print_max = 1, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_preemptoff, +#endif }; # define register_preemptoff(trace) register_tracer(&trace) #else @@ -480,6 +486,9 @@ static struct tracer preemptirqsoff_tracer __read_mostly = .close = irqsoff_tracer_close, .ctrl_update = irqsoff_tracer_ctrl_update, .print_max = 1, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_preemptirqsoff, +#endif }; # define register_preemptirqsoff(trace) register_tracer(&trace) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 2715267..6c92841 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -107,6 +107,9 @@ static struct tracer sched_switch_trace __read_mostly = .init = sched_switch_trace_init, .reset = sched_switch_trace_reset, .ctrl_update = sched_switch_trace_ctrl_update, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_sched_switch, +#endif }; __init static int init_sched_switch_trace(void) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 7c3ccef..3d10ff0 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -295,6 +295,9 @@ static struct tracer wakeup_tracer __read_mostly = .close = wakeup_tracer_close, .ctrl_update = wakeup_tracer_ctrl_update, .print_max = 1, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_wakeup, +#endif }; __init static int init_wakeup_tracer(void) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c new file mode 100644 index 0000000..ef4d3cc --- /dev/null +++ b/kernel/trace/trace_selftest.c @@ -0,0 +1,415 @@ +/* Include in trace.c */ + +#include + +static inline int trace_valid_entry(struct trace_entry *entry) +{ + switch (entry->type) { + case TRACE_FN: + case TRACE_CTX: + return 1; + } + return 0; +} + +static int +trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data) +{ + struct page *page; + struct trace_entry *entries; + int idx = 0; + int i; + + page = list_entry(data->trace_pages.next, struct page, lru); + entries = page_address(page); + + if (data->trace != entries) + goto failed; + + /* + * The starting trace buffer always has valid elements, + * if any element exits. + */ + entries = data->trace; + + for (i = 0; i < tr->entries; i++) { + + if (i < data->trace_idx && + !trace_valid_entry(&entries[idx])) { + printk(KERN_CONT ".. invalid entry %d ", entries[idx].type); + goto failed; + } + + idx++; + if (idx >= ENTRIES_PER_PAGE) { + page = virt_to_page(entries); + if (page->lru.next == &data->trace_pages) { + if (i != tr->entries - 1) { + printk(KERN_CONT ".. entries buffer mismatch"); + goto failed; + } + } else { + page = list_entry(page->lru.next, struct page, lru); + entries = page_address(page); + } + idx = 0; + } + } + + page = virt_to_page(entries); + if (page->lru.next != &data->trace_pages) { + printk(KERN_CONT ".. too many entries"); + goto failed; + } + + return 0; + + failed: + printk(KERN_CONT ".. corrupted trace buffer .. "); + return -1; +} + +/* + * Test the trace buffer to see if all the elements + * are still sane. + */ +static int trace_test_buffer(struct trace_array *tr, unsigned long *count) +{ + unsigned long cnt = 0; + int cpu; + int ret = 0; + + for_each_possible_cpu(cpu) { + if (!tr->data[cpu]->trace) + continue; + + cnt += tr->data[cpu]->trace_idx; + printk("%d: count = %ld\n", cpu, cnt); + + ret = trace_test_buffer_cpu(tr, tr->data[cpu]); + if (ret) + break; + } + + if (count) + *count = cnt; + + return ret; +} + +#ifdef CONFIG_FTRACE +/* + * Simple verification test of ftrace function tracer. + * Enable ftrace, sleep 1/10 second, and then read the trace + * buffer to see if all is in order. + */ +int +trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) +{ + unsigned long count; + int ret; + + /* make sure functions have been recorded */ + ret = ftrace_force_update(); + if (ret) { + printk(KERN_CONT ".. ftraced failed .. "); + return ret; + } + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + /* Sleep for a 1/10 of a second */ + msleep(100); + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check the trace buffer */ + ret = trace_test_buffer(tr, &count); + trace->reset(tr); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + } + + return ret; +} +#endif /* CONFIG_FTRACE */ + +#ifdef CONFIG_IRQSOFF_TRACER +int +trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr) +{ + unsigned long save_max = tracing_max_latency; + unsigned long count; + int ret; + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + /* reset the max latency */ + tracing_max_latency = 0; + /* disable interrupts for a bit */ + local_irq_disable(); + udelay(100); + local_irq_enable(); + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check both trace buffers */ + ret = trace_test_buffer(tr, NULL); + if (!ret) + ret = trace_test_buffer(&max_tr, &count); + trace->reset(tr); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + } + + tracing_max_latency = save_max; + + return ret; +} +#endif /* CONFIG_IRQSOFF_TRACER */ + +#ifdef CONFIG_PREEMPT_TRACER +int +trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr) +{ + unsigned long save_max = tracing_max_latency; + unsigned long count; + int ret; + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + /* reset the max latency */ + tracing_max_latency = 0; + /* disable preemption for a bit */ + preempt_disable(); + udelay(100); + preempt_enable(); + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check both trace buffers */ + ret = trace_test_buffer(tr, NULL); + if (!ret) + ret = trace_test_buffer(&max_tr, &count); + trace->reset(tr); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + } + + tracing_max_latency = save_max; + + return ret; +} +#endif /* CONFIG_PREEMPT_TRACER */ + +#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER) +int +trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *tr) +{ + unsigned long save_max = tracing_max_latency; + unsigned long count; + int ret; + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + + /* reset the max latency */ + tracing_max_latency = 0; + + /* disable preemption and interrupts for a bit */ + preempt_disable(); + local_irq_disable(); + udelay(100); + preempt_enable(); + /* reverse the order of preempt vs irqs */ + local_irq_enable(); + + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check both trace buffers */ + ret = trace_test_buffer(tr, NULL); + if (ret) + goto out; + + ret = trace_test_buffer(&max_tr, &count); + if (ret) + goto out; + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + goto out; + } + + /* do the test by disabling interrupts first this time */ + tracing_max_latency = 0; + tr->ctrl = 1; + trace->ctrl_update(tr); + preempt_disable(); + local_irq_disable(); + udelay(100); + preempt_enable(); + /* reverse the order of preempt vs irqs */ + local_irq_enable(); + + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check both trace buffers */ + ret = trace_test_buffer(tr, NULL); + if (ret) + goto out; + + ret = trace_test_buffer(&max_tr, &count); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + goto out; + } + + out: + trace->reset(tr); + tracing_max_latency = save_max; + + return ret; +} +#endif /* CONFIG_IRQSOFF_TRACER && CONFIG_PREEMPT_TRACER */ + +#ifdef CONFIG_SCHED_TRACER +static int trace_wakeup_test_thread(void *data) +{ + struct completion *x = data; + + /* Make this a RT thread, doesn't need to be too high */ + + rt_mutex_setprio(current, MAX_RT_PRIO - 5); + + /* Make it know we have a new prio */ + complete(x); + + /* now go to sleep and let the test wake us up */ + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + + /* we are awake, now wait to disappear */ + while (!kthread_should_stop()) { + /* + * This is an RT task, do short sleeps to let + * others run. + */ + msleep(100); + } + + return 0; +} + +int +trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) +{ + unsigned long save_max = tracing_max_latency; + struct task_struct *p; + struct completion isrt; + unsigned long count; + int ret; + + init_completion(&isrt); + + /* create a high prio thread */ + p = kthread_run(trace_wakeup_test_thread, &isrt, "ftrace-test"); + if (!IS_ERR(p)) { + printk(KERN_CONT "Failed to create ftrace wakeup test thread "); + return -1; + } + + /* make sure the thread is running at an RT prio */ + wait_for_completion(&isrt); + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + /* reset the max latency */ + tracing_max_latency = 0; + + /* sleep to let the RT thread sleep too */ + msleep(100); + + /* + * Yes this is slightly racy. It is possible that for some + * strange reason that the RT thread we created, did not + * call schedule for 100ms after doing the completion, + * and we do a wakeup on a task that already is awake. + * But that is extremely unlikely, and the worst thing that + * happens in such a case, is that we disable tracing. + * Honestly, if this race does happen something is horrible + * wrong with the system. + */ + + wake_up_process(p); + + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check both trace buffers */ + ret = trace_test_buffer(tr, NULL); + if (!ret) + ret = trace_test_buffer(&max_tr, &count); + + + trace->reset(tr); + + tracing_max_latency = save_max; + + /* kill the thread */ + kthread_stop(p); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + } + + return ret; +} +#endif /* CONFIG_SCHED_TRACER */ + +#ifdef CONFIG_CONTEXT_SWITCH_TRACER +int +trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr) +{ + unsigned long count; + int ret; + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + /* Sleep for a 1/10 of a second */ + msleep(100); + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check the trace buffer */ + ret = trace_test_buffer(tr, &count); + trace->reset(tr); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + } + + return ret; +} +#endif /* CONFIG_CONTEXT_SWITCH_TRACER */ + +#ifdef CONFIG_DYNAMIC_FTRACE +#endif /* CONFIG_DYNAMIC_FTRACE */ -- cgit v0.10.2 From c7aafc549766b87819285d3480648fc652a47bc4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: cleanups factor out code and clean it up. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 2c1670c..953a36d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -69,7 +69,7 @@ extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); #else -# define ftrace_force_update() do { } while (0) +# define ftrace_force_update() ({ 0; }) #endif static inline void tracer_disable(void) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 4facf5c..6d4d2e8 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1152,10 +1152,10 @@ static int __init notrace ftrace_dynamic_init(void) core_initcall(ftrace_dynamic_init); #else -# define ftrace_startup() do { } while (0) -# define ftrace_shutdown() do { } while (0) -# define ftrace_startup_sysctl() do { } while (0) -# define ftrace_shutdown_sysctl() do { } while (0) +# define ftrace_startup() do { } while (0) +# define ftrace_shutdown() do { } while (0) +# define ftrace_startup_sysctl() do { } while (0) +# define ftrace_shutdown_sysctl() do { } while (0) #endif /* CONFIG_DYNAMIC_FTRACE */ /** diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f6d026f..61d2f02 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -142,12 +142,59 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) tracing_record_cmdline(current); } +void check_pages(struct trace_array_cpu *data) +{ + struct page *page, *tmp; + + BUG_ON(data->trace_pages.next->prev != &data->trace_pages); + BUG_ON(data->trace_pages.prev->next != &data->trace_pages); + + list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) { + BUG_ON(page->lru.next->prev != &page->lru); + BUG_ON(page->lru.prev->next != &page->lru); + } +} + +void *head_page(struct trace_array_cpu *data) +{ + struct page *page; + + check_pages(data); + if (list_empty(&data->trace_pages)) + return NULL; + + page = list_entry(data->trace_pages.next, struct page, lru); + BUG_ON(&page->lru == &data->trace_pages); + + return page_address(page); +} + +notrace static void +flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) +{ + struct list_head flip_pages; + + INIT_LIST_HEAD(&flip_pages); + + tr1->trace_current = NULL; + memcpy(&tr1->trace_current_idx, &tr2->trace_current_idx, + sizeof(struct trace_array_cpu) - + offsetof(struct trace_array_cpu, trace_current_idx)); + + check_pages(tr1); + check_pages(tr2); + list_splice_init(&tr1->trace_pages, &flip_pages); + list_splice_init(&tr2->trace_pages, &tr1->trace_pages); + list_splice_init(&flip_pages, &tr2->trace_pages); + BUG_ON(!list_empty(&flip_pages)); + check_pages(tr1); + check_pages(tr2); +} + notrace void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data; - void *save_trace; - struct list_head save_pages; int i; WARN_ON_ONCE(!irqs_disabled()); @@ -155,11 +202,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) /* clear out all the previous traces */ for_each_possible_cpu(i) { data = tr->data[i]; - save_trace = max_tr.data[i]->trace; - save_pages = max_tr.data[i]->trace_pages; - memcpy(max_tr.data[i], data, sizeof(*data)); - data->trace = save_trace; - data->trace_pages = save_pages; + flip_trace(max_tr.data[i], data); tracing_reset(data); } @@ -177,8 +220,6 @@ notrace void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data = tr->data[cpu]; - void *save_trace; - struct list_head save_pages; int i; WARN_ON_ONCE(!irqs_disabled()); @@ -186,11 +227,8 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) for_each_possible_cpu(i) tracing_reset(max_tr.data[i]); - save_trace = max_tr.data[cpu]->trace; - save_pages = max_tr.data[cpu]->trace_pages; - memcpy(max_tr.data[cpu], data, sizeof(*data)); - data->trace = save_trace; - data->trace_pages = save_pages; + flip_trace(max_tr.data[cpu], data); + tracing_reset(data); __update_max_tr(tr, tsk, cpu); @@ -234,9 +272,9 @@ int register_tracer(struct tracer *type) * If we fail, we do not register this tracer. */ for_each_possible_cpu(i) { - if (!data->trace) - continue; data = tr->data[i]; + if (!head_page(data)) + continue; tracing_reset(data); } current_trace = type; @@ -298,7 +336,7 @@ void unregister_tracer(struct tracer *type) void notrace tracing_reset(struct trace_array_cpu *data) { data->trace_idx = 0; - data->trace_current = data->trace; + data->trace_current = head_page(data); data->trace_current_idx = 0; } @@ -425,26 +463,31 @@ notrace void tracing_record_cmdline(struct task_struct *tsk) } static inline notrace struct trace_entry * -tracing_get_trace_entry(struct trace_array *tr, - struct trace_array_cpu *data) +tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data) { unsigned long idx, idx_next; struct trace_entry *entry; - struct page *page; struct list_head *next; + struct page *page; data->trace_idx++; idx = data->trace_current_idx; idx_next = idx + 1; + BUG_ON(idx * TRACE_ENTRY_SIZE >= PAGE_SIZE); + entry = data->trace_current + idx * TRACE_ENTRY_SIZE; if (unlikely(idx_next >= ENTRIES_PER_PAGE)) { page = virt_to_page(data->trace_current); - if (unlikely(&page->lru == data->trace_pages.prev)) - next = data->trace_pages.next; - else - next = page->lru.next; + /* + * Roundrobin - but skip the head (which is not a real page): + */ + next = page->lru.next; + if (unlikely(next == &data->trace_pages)) + next = next->next; + BUG_ON(next == &data->trace_pages); + page = list_entry(next, struct page, lru); data->trace_current = page_address(page); idx_next = 0; @@ -456,18 +499,17 @@ tracing_get_trace_entry(struct trace_array *tr, } static inline notrace void -tracing_generic_entry_update(struct trace_entry *entry, - unsigned long flags) +tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) { struct task_struct *tsk = current; unsigned long pc; pc = preempt_count(); - entry->idx = atomic_inc_return(&tracer_counter); - entry->preempt_count = pc & 0xff; - entry->pid = tsk->pid; - entry->t = now(raw_smp_processor_id()); + entry->idx = atomic_inc_return(&tracer_counter); + entry->preempt_count = pc & 0xff; + entry->pid = tsk->pid; + entry->t = now(raw_smp_processor_id()); entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | @@ -476,16 +518,15 @@ tracing_generic_entry_update(struct trace_entry *entry, notrace void ftrace(struct trace_array *tr, struct trace_array_cpu *data, - unsigned long ip, unsigned long parent_ip, - unsigned long flags) + unsigned long ip, unsigned long parent_ip, unsigned long flags) { struct trace_entry *entry; - entry = tracing_get_trace_entry(tr, data); + entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); - entry->type = TRACE_FN; - entry->fn.ip = ip; - entry->fn.parent_ip = parent_ip; + entry->type = TRACE_FN; + entry->fn.ip = ip; + entry->fn.parent_ip = parent_ip; } notrace void @@ -496,7 +537,7 @@ tracing_sched_switch_trace(struct trace_array *tr, { struct trace_entry *entry; - entry = tracing_get_trace_entry(tr, data); + entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_CTX; entry->ctx.prev_pid = prev->pid; @@ -540,6 +581,8 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, } page = list_entry(iter->next_page[cpu], struct page, lru); + BUG_ON(&data->trace_pages == &page->lru); + array = page_address(page); return &array[iter->next_page_idx[cpu]]; @@ -554,7 +597,7 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) int cpu; for_each_possible_cpu(cpu) { - if (!tr->data[cpu]->trace) + if (!head_page(tr->data[cpu])) continue; ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu); if (ent && @@ -762,7 +805,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) name = type->name; for_each_possible_cpu(cpu) { - if (tr->data[cpu]->trace) { + if (head_page(tr->data[cpu])) { total += tr->data[cpu]->trace_idx; if (tr->data[cpu]->trace_idx > tr->entries) entries += tr->entries; @@ -975,8 +1018,7 @@ static int trace_empty(struct trace_iterator *iter) for_each_possible_cpu(cpu) { data = iter->tr->data[cpu]; - if (data->trace && - data->trace_idx) + if (head_page(data) && data->trace_idx) return 0; } return 1; @@ -1576,9 +1618,9 @@ static struct tracer no_tracer __read_mostly = static int trace_alloc_page(void) { struct trace_array_cpu *data; - void *array; struct page *page, *tmp; LIST_HEAD(pages); + void *array; int i; /* first allocate a page for each CPU */ @@ -1610,14 +1652,14 @@ static int trace_alloc_page(void) for_each_possible_cpu(i) { data = global_trace.data[i]; page = list_entry(pages.next, struct page, lru); - list_del(&page->lru); + list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); ClearPageLRU(page); #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; page = list_entry(pages.next, struct page, lru); - list_del(&page->lru); + list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); SetPageLRU(page); #endif @@ -1628,7 +1670,7 @@ static int trace_alloc_page(void) free_pages: list_for_each_entry_safe(page, tmp, &pages, lru) { - list_del(&page->lru); + list_del_init(&page->lru); __free_page(page); } return -ENOMEM; @@ -1654,7 +1696,6 @@ __init static int tracer_alloc_buffers(void) "for trace buffer!\n"); goto free_buffers; } - data->trace = array; /* set the array to the list */ INIT_LIST_HEAD(&data->trace_pages); @@ -1671,7 +1712,6 @@ __init static int tracer_alloc_buffers(void) "for trace buffer!\n"); goto free_buffers; } - max_tr.data[i]->trace = array; INIT_LIST_HEAD(&max_tr.data[i]->trace_pages); page = virt_to_page(array); @@ -1716,24 +1756,22 @@ __init static int tracer_alloc_buffers(void) struct page *page, *tmp; struct trace_array_cpu *data = global_trace.data[i]; - if (data && data->trace) { + if (data) { list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) { - list_del(&page->lru); + list_del_init(&page->lru); __free_page(page); } - data->trace = NULL; } #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; - if (data && data->trace) { + if (data) { list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) { - list_del(&page->lru); + list_del_init(&page->lru); __free_page(page); } - data->trace = NULL; } #endif } diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 88edbf1..cc1d34b 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -53,12 +53,12 @@ struct trace_entry { * the trace, etc.) */ struct trace_array_cpu { - void *trace; void *trace_current; - unsigned trace_current_idx; struct list_head trace_pages; - unsigned long trace_idx; atomic_t disabled; + /* these fields get copied into max-trace: */ + unsigned trace_current_idx; + unsigned long trace_idx; unsigned long saved_latency; unsigned long critical_start; unsigned long critical_end; @@ -216,4 +216,6 @@ extern int trace_selftest_startup_sched_switch(struct tracer *trace, #endif #endif /* CONFIG_FTRACE_STARTUP_TEST */ +extern void *head_page(struct trace_array_cpu *data); + #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 14183b8..2dfebb6 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -144,7 +144,7 @@ check_critical_timing(struct trace_array *tr, if (!report_latency(delta)) goto out; - spin_lock(&max_trace_lock); + spin_lock_irqsave(&max_trace_lock, flags); /* check if we are still the max latency */ if (!report_latency(delta)) @@ -165,32 +165,24 @@ check_critical_timing(struct trace_array *tr, update_max_tr_single(tr, current, cpu); - if (tracing_thresh) - printk(KERN_INFO "(%16s-%-5d|#%d): %lu us critical section " - "violates %lu us threshold.\n" - " => started at timestamp %lu: ", + if (tracing_thresh) { + printk(KERN_INFO "(%16s-%-5d|#%d):" + " %lu us critical section violates %lu us threshold.\n", current->comm, current->pid, raw_smp_processor_id(), - latency, nsecs_to_usecs(tracing_thresh), t0); - else + latency, nsecs_to_usecs(tracing_thresh)); + } else { printk(KERN_INFO "(%16s-%-5d|#%d):" - " new %lu us maximum-latency " - "critical section.\n => started at timestamp %lu: ", + " new %lu us maximum-latency critical section.\n", current->comm, current->pid, raw_smp_processor_id(), - latency, t0); - - print_symbol(KERN_CONT "<%s>\n", data->critical_start); - printk(KERN_CONT " => ended at timestamp %lu: ", t1); - print_symbol(KERN_CONT "<%s>\n", data->critical_end); - dump_stack(); - t1 = nsecs_to_usecs(now(cpu)); - printk(KERN_CONT " => dump-end timestamp %lu\n\n", t1); + latency); + } max_sequence++; out_unlock: - spin_unlock(&max_trace_lock); + spin_unlock_irqrestore(&max_trace_lock, flags); out: data->critical_sequence = max_sequence; @@ -216,7 +208,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) cpu = raw_smp_processor_id(); data = tr->data[cpu]; - if (unlikely(!data) || unlikely(!data->trace) || + if (unlikely(!data) || unlikely(!head_page(data)) || atomic_read(&data->disabled)) return; @@ -256,7 +248,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) cpu = raw_smp_processor_id(); data = tr->data[cpu]; - if (unlikely(!data) || unlikely(!data->trace) || + if (unlikely(!data) || unlikely(!head_page(data)) || !data->critical_start || atomic_read(&data->disabled)) return; diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 3d10ff0..688df96 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -107,24 +107,18 @@ wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) update_max_tr(tr, wakeup_task, wakeup_cpu); if (tracing_thresh) { - printk(KERN_INFO "(%16s-%-5d|#%d): %lu us wakeup latency " - "violates %lu us threshold.\n" - " => started at timestamp %lu: ", + printk(KERN_INFO "(%16s-%-5d|#%d):" + " %lu us wakeup latency violates %lu us threshold.\n", wakeup_task->comm, wakeup_task->pid, raw_smp_processor_id(), - latency, nsecs_to_usecs(tracing_thresh), t0); + latency, nsecs_to_usecs(tracing_thresh)); } else { - printk(KERN_INFO "(%16s-%-5d|#%d): new %lu us maximum " - "wakeup latency.\n => started at timestamp %lu: ", + printk(KERN_INFO "(%16s-%-5d|#%d):" + " new %lu us maximum wakeup latency.\n", wakeup_task->comm, wakeup_task->pid, - cpu, latency, t0); + cpu, latency); } - printk(KERN_CONT " ended at timestamp %lu: ", t1); - dump_stack(); - t1 = nsecs_to_usecs(now(cpu)); - printk(KERN_CONT " dump-end timestamp %lu\n\n", t1); - out_unlock: __wakeup_reset(tr); spin_unlock_irqrestore(&wakeup_lock, flags); diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index ef4d3cc..c01874c 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -1,6 +1,7 @@ /* Include in trace.c */ #include +#include static inline int trace_valid_entry(struct trace_entry *entry) { @@ -15,28 +16,29 @@ static inline int trace_valid_entry(struct trace_entry *entry) static int trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data) { - struct page *page; struct trace_entry *entries; + struct page *page; int idx = 0; int i; + BUG_ON(list_empty(&data->trace_pages)); page = list_entry(data->trace_pages.next, struct page, lru); entries = page_address(page); - if (data->trace != entries) + if (head_page(data) != entries) goto failed; /* * The starting trace buffer always has valid elements, - * if any element exits. + * if any element exists. */ - entries = data->trace; + entries = head_page(data); for (i = 0; i < tr->entries; i++) { - if (i < data->trace_idx && - !trace_valid_entry(&entries[idx])) { - printk(KERN_CONT ".. invalid entry %d ", entries[idx].type); + if (i < data->trace_idx && !trace_valid_entry(&entries[idx])) { + printk(KERN_CONT ".. invalid entry %d ", + entries[idx].type); goto failed; } @@ -80,11 +82,10 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) int ret = 0; for_each_possible_cpu(cpu) { - if (!tr->data[cpu]->trace) + if (!head_page(tr->data[cpu])) continue; cnt += tr->data[cpu]->trace_idx; - printk("%d: count = %ld\n", cpu, cnt); ret = trace_test_buffer_cpu(tr, tr->data[cpu]); if (ret) @@ -117,6 +118,8 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) } /* start the tracing */ + ftrace_enabled = 1; + tr->ctrl = 1; trace->init(tr); /* Sleep for a 1/10 of a second */ @@ -124,6 +127,8 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) /* stop the tracing. */ tr->ctrl = 0; trace->ctrl_update(tr); + ftrace_enabled = 0; + /* check the trace buffer */ ret = trace_test_buffer(tr, &count); trace->reset(tr); @@ -328,7 +333,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) /* create a high prio thread */ p = kthread_run(trace_wakeup_test_thread, &isrt, "ftrace-test"); - if (!IS_ERR(p)) { + if (IS_ERR(p)) { printk(KERN_CONT "Failed to create ftrace wakeup test thread "); return -1; } -- cgit v0.10.2 From 7bd2f24c2f769e3f8f1d4fc8b9fddf689825f6a7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: add README make it easier for newbies to find their way around. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 61d2f02..c736dd2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -995,6 +995,7 @@ print_trace_fmt(struct seq_file *m, struct trace_iterator *iter) seq_printf(m, " <-"); seq_print_ip_sym(m, entry->fn.parent_ip, sym_flags); } + seq_printf(m, "\n"); break; case TRACE_CTX: S = entry->ctx.prev_state < sizeof(state_to_char) ? @@ -1007,7 +1008,6 @@ print_trace_fmt(struct seq_file *m, struct trace_iterator *iter) entry->ctx.next_prio); break; } - seq_printf(m, "\n"); } static int trace_empty(struct trace_iterator *iter) @@ -1332,6 +1332,39 @@ static struct file_operations tracing_iter_fops = { .write = tracing_iter_ctrl_write, }; +static const char readme_msg[] = + "tracing mini-HOWTO:\n\n" + "# mkdir /debug\n" + "# mount -t debugfs nodev /debug\n\n" + "# cat /debug/tracing/available_tracers\n" + "wakeup preemptirqsoff preemptoff irqsoff ftrace sched_switch none\n\n" + "# cat /debug/tracing/current_tracer\n" + "none\n" + "# echo sched_switch > /debug/tracing/current_tracer\n" + "# cat /debug/tracing/current_tracer\n" + "sched_switch\n" + "# cat /debug/tracing/iter_ctrl\n" + "noprint-parent nosym-offset nosym-addr noverbose\n" + "# echo print-parent > /debug/tracing/iter_ctrl\n" + "# echo 1 > /debug/tracing/tracing_enabled\n" + "# cat /debug/tracing/trace > /tmp/trace.txt\n" + "echo 0 > /debug/tracing/tracing_enabled\n" +; + +static ssize_t +tracing_readme_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + return simple_read_from_buffer(ubuf, cnt, ppos, + readme_msg, strlen(readme_msg)); +} + +static struct file_operations tracing_readme_fops = { + .open = tracing_open_generic, + .read = tracing_readme_read, +}; + + static ssize_t tracing_ctrl_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) @@ -1598,6 +1631,11 @@ static __init void tracer_init_debugfs(void) if (!entry) pr_warning("Could not create debugfs " "'tracing_threash' entry\n"); + entry = debugfs_create_file("README", 0644, d_tracer, + NULL, &tracing_readme_fops); + if (!entry) + pr_warning("Could not create debugfs 'README' entry\n"); + #ifdef CONFIG_DYNAMIC_FTRACE entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, -- cgit v0.10.2 From 77a2b37d227483fe52aead242652aee406c25bf0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: startup tester on dynamic tracing. This patch adds a startup self test on dynamic code modification and filters. The test filters on a specific function, makes sure that no other function is traced, exectutes the function, then makes sure that the function is traced. This patch also fixes a slight bug with the ftrace selftest, where tracer_enabled was not being set. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 953a36d..a842d96 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -55,6 +55,7 @@ struct dyn_ftrace { }; int ftrace_force_update(void); +void ftrace_set_filter(unsigned char *buf, int len, int reset); /* defined in arch */ extern int ftrace_ip_converted(unsigned long ip); @@ -70,6 +71,7 @@ extern void ftrace_call(void); extern void mcount_call(void); #else # define ftrace_force_update() ({ 0; }) +# define ftrace_set_filter(buf, len, reset) do { } while (0) #endif static inline void tracer_disable(void) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 6d4d2e8..5e9389f 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1010,6 +1010,25 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, return ret; } +/** + * ftrace_set_filter - set a function to filter on in ftrace + * @buf - the string that holds the function filter text. + * @len - the length of the string. + * @reset - non zero to reset all filters before applying this filter. + * + * Filters denote which functions should be enabled when tracing is enabled. + * If @buf is NULL and reset is set, all functions will be enabled for tracing. + */ +notrace void ftrace_set_filter(unsigned char *buf, int len, int reset) +{ + mutex_lock(&ftrace_filter_lock); + if (reset) + ftrace_filter_reset(); + if (buf) + ftrace_match(buf, len); + mutex_unlock(&ftrace_filter_lock); +} + static int notrace ftrace_filter_release(struct inode *inode, struct file *file) { diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index c01874c..4c8a1b2 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -99,6 +99,100 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) } #ifdef CONFIG_FTRACE + +#ifdef CONFIG_DYNAMIC_FTRACE + +#define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func +#define __STR(x) #x +#define STR(x) __STR(x) +static int DYN_FTRACE_TEST_NAME(void) +{ + /* used to call mcount */ + return 0; +} + +/* Test dynamic code modification and ftrace filters */ +int trace_selftest_startup_dynamic_tracing(struct tracer *trace, + struct trace_array *tr, + int (*func)(void)) +{ + unsigned long count; + int ret; + int save_ftrace_enabled = ftrace_enabled; + int save_tracer_enabled = tracer_enabled; + + /* The ftrace test PASSED */ + printk(KERN_CONT "PASSED\n"); + pr_info("Testing dynamic ftrace: "); + + /* enable tracing, and record the filter function */ + ftrace_enabled = 1; + tracer_enabled = 1; + + /* passed in by parameter to fool gcc from optimizing */ + func(); + + /* update the records */ + ret = ftrace_force_update(); + if (ret) { + printk(KERN_CONT ".. ftraced failed .. "); + return ret; + } + + /* filter only on our function */ + ftrace_set_filter(STR(DYN_FTRACE_TEST_NAME), + sizeof(STR(DYN_FTRACE_TEST_NAME)), 1); + + /* enable tracing */ + tr->ctrl = 1; + trace->init(tr); + /* Sleep for a 1/10 of a second */ + msleep(100); + + /* we should have nothing in the buffer */ + ret = trace_test_buffer(tr, &count); + if (ret) + goto out; + + if (count) { + ret = -1; + printk(KERN_CONT ".. filter did not filter .. "); + goto out; + } + + /* call our function again */ + func(); + + /* sleep again */ + msleep(100); + + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + ftrace_enabled = 0; + + /* check the trace buffer */ + ret = trace_test_buffer(tr, &count); + trace->reset(tr); + + /* we should only have one item */ + if (!ret && count != 1) { + printk(KERN_CONT ".. filter failed .."); + ret = -1; + goto out; + } + out: + ftrace_enabled = save_ftrace_enabled; + tracer_enabled = save_tracer_enabled; + + /* Enable tracing on all functions again */ + ftrace_set_filter(NULL, 0, 1); + + return ret; +} +#else +# define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; }) +#endif /* CONFIG_DYNAMIC_FTRACE */ /* * Simple verification test of ftrace function tracer. * Enable ftrace, sleep 1/10 second, and then read the trace @@ -109,8 +203,13 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) { unsigned long count; int ret; + int save_ftrace_enabled = ftrace_enabled; + int save_tracer_enabled = tracer_enabled; - /* make sure functions have been recorded */ + /* make sure msleep has been recorded */ + msleep(1); + + /* force the recorded functions to be traced */ ret = ftrace_force_update(); if (ret) { printk(KERN_CONT ".. ftraced failed .. "); @@ -119,6 +218,7 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) /* start the tracing */ ftrace_enabled = 1; + tracer_enabled = 1; tr->ctrl = 1; trace->init(tr); @@ -136,8 +236,16 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) if (!ret && !count) { printk(KERN_CONT ".. no entries found .."); ret = -1; + goto out; } + ret = trace_selftest_startup_dynamic_tracing(trace, tr, + DYN_FTRACE_TEST_NAME); + + out: + ftrace_enabled = save_ftrace_enabled; + tracer_enabled = save_tracer_enabled; + return ret; } #endif /* CONFIG_FTRACE */ @@ -415,6 +523,3 @@ trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr return ret; } #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ - -#ifdef CONFIG_DYNAMIC_FTRACE -#endif /* CONFIG_DYNAMIC_FTRACE */ -- cgit v0.10.2 From 4e3c3333f3bd7eedfd21b1155b3c7cd24fc7f754 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: fix time offset fix time offset calculations and ordering, plus make code more consistent. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c736dd2..8755a43 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -120,7 +120,7 @@ static DEFINE_SPINLOCK(ftrace_max_lock); * structure. (this way the maximum trace is permanently saved, * for later retrieval via /debugfs/tracing/latency_trace) */ -static void notrace +static notrace void __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data = tr->data[cpu]; @@ -333,15 +333,16 @@ void unregister_tracer(struct tracer *type) mutex_unlock(&trace_types_lock); } -void notrace tracing_reset(struct trace_array_cpu *data) +notrace void tracing_reset(struct trace_array_cpu *data) { data->trace_idx = 0; data->trace_current = head_page(data); data->trace_current_idx = 0; + data->time_offset = 0; } #ifdef CONFIG_FTRACE -static void notrace +static notrace void function_trace_call(unsigned long ip, unsigned long parent_ip) { struct trace_array *tr = &global_trace; @@ -398,7 +399,7 @@ static void trace_init_cmdlines(void) notrace void trace_stop_cmdline_recording(void); -static void notrace trace_save_cmdline(struct task_struct *tsk) +static notrace void trace_save_cmdline(struct task_struct *tsk) { unsigned map; unsigned idx; @@ -624,6 +625,7 @@ static void *find_next_entry_inc(struct trace_iterator *iter) iter->idx++; iter->next_idx[next_cpu]++; iter->next_page_idx[next_cpu]++; + if (iter->next_page_idx[next_cpu] >= ENTRIES_PER_PAGE) { struct trace_array_cpu *data = iter->tr->data[next_cpu]; @@ -635,19 +637,21 @@ static void *find_next_entry_inc(struct trace_iterator *iter) data->trace_pages.next; } } + iter->prev_ent = iter->ent; + iter->prev_cpu = iter->cpu; + iter->ent = next; iter->cpu = next_cpu; return next ? iter : NULL; } -static void notrace * -s_next(struct seq_file *m, void *v, loff_t *pos) +static notrace void *s_next(struct seq_file *m, void *v, loff_t *pos) { struct trace_iterator *iter = m->private; - void *ent; void *last_ent = iter->ent; int i = (int)*pos; + void *ent; (*pos)++; @@ -693,6 +697,8 @@ static void *s_start(struct seq_file *m, loff_t *pos) iter->ent = NULL; iter->cpu = 0; iter->idx = -1; + iter->prev_ent = NULL; + iter->prev_cpu = -1; for_each_possible_cpu(i) { iter->next_idx[i] = 0; @@ -752,7 +758,7 @@ seq_print_sym_offset(struct seq_file *m, const char *fmt, unsigned long address) # define IP_FMT "%016lx" #endif -static void notrace +static notrace void seq_print_ip_sym(struct seq_file *m, unsigned long ip, unsigned long sym_flags) { if (!ip) { @@ -769,7 +775,7 @@ seq_print_ip_sym(struct seq_file *m, unsigned long ip, unsigned long sym_flags) seq_printf(m, " <" IP_FMT ">", ip); } -static void notrace print_lat_help_header(struct seq_file *m) +static notrace void print_lat_help_header(struct seq_file *m) { seq_puts(m, "# _------=> CPU# \n"); seq_puts(m, "# / _-----=> irqs-off \n"); @@ -782,14 +788,14 @@ static void notrace print_lat_help_header(struct seq_file *m) seq_puts(m, "# \\ / ||||| \\ | / \n"); } -static void notrace print_func_help_header(struct seq_file *m) +static notrace void print_func_help_header(struct seq_file *m) { seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); seq_puts(m, "# | | | | |\n"); } -static void notrace +static notrace void print_trace_header(struct seq_file *m, struct trace_iterator *iter) { unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); @@ -858,7 +864,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) seq_puts(m, "\n"); } -static void notrace +static notrace void lat_print_generic(struct seq_file *m, struct trace_entry *entry, int cpu) { int hardirq, softirq; @@ -895,7 +901,7 @@ lat_print_generic(struct seq_file *m, struct trace_entry *entry, int cpu) unsigned long preempt_mark_thresh = 100; -static void notrace +static notrace void lat_print_timestamp(struct seq_file *m, unsigned long long abs_usecs, unsigned long rel_usecs) { @@ -910,7 +916,7 @@ lat_print_timestamp(struct seq_file *m, unsigned long long abs_usecs, static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; -static void notrace +static notrace void print_lat_fmt(struct seq_file *m, struct trace_iterator *iter, unsigned int trace_idx, int cpu) { @@ -966,20 +972,50 @@ print_lat_fmt(struct seq_file *m, struct trace_iterator *iter, } } -static void notrace +static notrace void sync_time_offset(struct trace_iterator *iter) +{ + struct trace_array_cpu *prev_array, *array; + struct trace_entry *prev_entry, *entry; + cycle_t prev_t, t; + + entry = iter->ent; + prev_entry = iter->prev_ent; + if (!prev_entry) + return; + + prev_array = iter->tr->data[iter->prev_cpu]; + array = iter->tr->data[iter->cpu]; + + prev_t = prev_entry->t + prev_array->time_offset; + t = entry->t + array->time_offset; + + /* + * If time goes backwards we increase the offset of + * the current array, to not have observable time warps. + * This will quickly synchronize the time offsets of + * multiple CPUs: + */ + if (t < prev_t) + array->time_offset += prev_t - t; +} + +static notrace void print_trace_fmt(struct seq_file *m, struct trace_iterator *iter) { unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); - struct trace_entry *entry = iter->ent; + struct trace_entry *entry; unsigned long usec_rem; unsigned long long t; unsigned long secs; char *comm; int S; + sync_time_offset(iter); + entry = iter->ent; + comm = trace_find_cmdline(iter->ent->pid); - t = ns2usecs(entry->t); + t = ns2usecs(entry->t + iter->tr->data[iter->cpu]->time_offset); usec_rem = do_div(t, 1000000ULL); secs = (unsigned long)t; @@ -1158,7 +1194,7 @@ static int tracing_lt_open(struct inode *inode, struct file *file) } -static void notrace * +static notrace void * t_next(struct seq_file *m, void *v, loff_t *pos) { struct tracer *t = m->private; @@ -1374,8 +1410,7 @@ tracing_ctrl_read(struct file *filp, char __user *ubuf, int r; r = sprintf(buf, "%ld\n", tr->ctrl); - return simple_read_from_buffer(ubuf, cnt, ppos, - buf, r); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index cc1d34b..5df8ff2 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -56,6 +56,8 @@ struct trace_array_cpu { void *trace_current; struct list_head trace_pages; atomic_t disabled; + cycle_t time_offset; + /* these fields get copied into max-trace: */ unsigned trace_current_idx; unsigned long trace_idx; @@ -114,14 +116,19 @@ struct tracer { struct trace_iterator { struct trace_array *tr; struct tracer *trace; + struct trace_entry *ent; + int cpu; + + struct trace_entry *prev_ent; + int prev_cpu; + unsigned long iter_flags; loff_t pos; unsigned long next_idx[NR_CPUS]; struct list_head *next_page[NR_CPUS]; unsigned next_page_idx[NR_CPUS]; long idx; - int cpu; }; void notrace tracing_reset(struct trace_array_cpu *data); -- cgit v0.10.2 From 08bafa0efcf29fe18ec39c2147077b597368b018 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: disable all tracers on corrupted buffer If the trace buffer is detected to be corrupted, then we disable all tracers. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 4c8a1b2..a6f1ed7 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -67,6 +67,8 @@ trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data) return 0; failed: + /* disable tracing */ + tracing_disabled = 1; printk(KERN_CONT ".. corrupted trace buffer .. "); return -1; } -- cgit v0.10.2 From 1d4db00a5e30c7b8f8dc2a1b19e886fd942be143 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: reset selftests The tests may leave stuff in the buffers. This resets the buffers after each test is run. If a test fails, it does not reset the buffer to avoid touching a buffer that is corrupted. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8755a43..6580e7e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -289,6 +289,13 @@ int register_tracer(struct tracer *type) printk(KERN_CONT "FAILED!\n"); goto out; } + /* Only reset on passing, to avoid touching corrupted buffers */ + for_each_possible_cpu(i) { + data = tr->data[i]; + if (!head_page(data)) + continue; + tracing_reset(data); + } printk(KERN_CONT "PASSED\n"); } #endif -- cgit v0.10.2 From 93a588f459da134be6ab17c4104e28441beb0d22 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:45 +0200 Subject: ftrace: change buffers to producer consumer This patch changes the way the CPU trace buffers are handled. Instead of always starting from the trace page head, the logic is changed to a producer consumer logic. This allows for the buffers to be drained while they are alive. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6580e7e..777b859 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -176,10 +176,9 @@ flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) INIT_LIST_HEAD(&flip_pages); - tr1->trace_current = NULL; - memcpy(&tr1->trace_current_idx, &tr2->trace_current_idx, + memcpy(&tr1->trace_head_idx, &tr2->trace_head_idx, sizeof(struct trace_array_cpu) - - offsetof(struct trace_array_cpu, trace_current_idx)); + offsetof(struct trace_array_cpu, trace_head_idx)); check_pages(tr1); check_pages(tr2); @@ -228,7 +227,6 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) tracing_reset(max_tr.data[i]); flip_trace(max_tr.data[cpu], data); - tracing_reset(data); __update_max_tr(tr, tsk, cpu); @@ -343,9 +341,9 @@ void unregister_tracer(struct tracer *type) notrace void tracing_reset(struct trace_array_cpu *data) { data->trace_idx = 0; - data->trace_current = head_page(data); - data->trace_current_idx = 0; - data->time_offset = 0; + data->trace_head = data->trace_tail = head_page(data); + data->trace_head_idx = 0; + data->trace_tail_idx = 0; } #ifdef CONFIG_FTRACE @@ -470,38 +468,65 @@ notrace void tracing_record_cmdline(struct task_struct *tsk) trace_save_cmdline(tsk); } +static inline notrace struct list_head * +trace_next_list(struct trace_array_cpu *data, struct list_head *next) +{ + /* + * Roundrobin - but skip the head (which is not a real page): + */ + next = next->next; + if (unlikely(next == &data->trace_pages)) + next = next->next; + BUG_ON(next == &data->trace_pages); + + return next; +} + +static inline notrace void * +trace_next_page(struct trace_array_cpu *data, void *addr) +{ + struct list_head *next; + struct page *page; + + page = virt_to_page(addr); + + next = trace_next_list(data, &page->lru); + page = list_entry(next, struct page, lru); + + return page_address(page); +} + static inline notrace struct trace_entry * tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data) { unsigned long idx, idx_next; struct trace_entry *entry; - struct list_head *next; - struct page *page; data->trace_idx++; - idx = data->trace_current_idx; + idx = data->trace_head_idx; idx_next = idx + 1; BUG_ON(idx * TRACE_ENTRY_SIZE >= PAGE_SIZE); - entry = data->trace_current + idx * TRACE_ENTRY_SIZE; + entry = data->trace_head + idx * TRACE_ENTRY_SIZE; if (unlikely(idx_next >= ENTRIES_PER_PAGE)) { - page = virt_to_page(data->trace_current); - /* - * Roundrobin - but skip the head (which is not a real page): - */ - next = page->lru.next; - if (unlikely(next == &data->trace_pages)) - next = next->next; - BUG_ON(next == &data->trace_pages); - - page = list_entry(next, struct page, lru); - data->trace_current = page_address(page); + data->trace_head = trace_next_page(data, data->trace_head); idx_next = 0; } - data->trace_current_idx = idx_next; + if (data->trace_head == data->trace_tail && + idx_next == data->trace_tail_idx) { + /* overrun */ + data->trace_tail_idx++; + if (data->trace_tail_idx >= ENTRIES_PER_PAGE) { + data->trace_tail = + trace_next_page(data, data->trace_tail); + data->trace_tail_idx = 0; + } + } + + data->trace_head_idx = idx_next; return entry; } @@ -571,21 +596,11 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, return NULL; if (!iter->next_page[cpu]) { - /* - * Initialize. If the count of elements in - * this buffer is greater than the max entries - * we had an underrun. Which means we looped around. - * We can simply use the current pointer as our - * starting point. - */ - if (data->trace_idx >= tr->entries) { - page = virt_to_page(data->trace_current); - iter->next_page[cpu] = &page->lru; - iter->next_page_idx[cpu] = data->trace_current_idx; - } else { - iter->next_page[cpu] = data->trace_pages.next; - iter->next_page_idx[cpu] = 0; - } + /* Initialize the iterator for this cpu trace buffer */ + WARN_ON(!data->trace_tail); + page = virt_to_page(data->trace_tail); + iter->next_page[cpu] = &page->lru; + iter->next_page_idx[cpu] = data->trace_tail_idx; } page = list_entry(iter->next_page[cpu], struct page, lru); @@ -593,6 +608,12 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, array = page_address(page); + /* Still possible to catch up to the tail */ + if (iter->next_idx[cpu] && array == data->trace_tail && + iter->next_page_idx[cpu] == data->trace_tail_idx) + return NULL; + + WARN_ON(iter->next_page_idx[cpu] >= ENTRIES_PER_PAGE); return &array[iter->next_page_idx[cpu]]; } @@ -638,10 +659,8 @@ static void *find_next_entry_inc(struct trace_iterator *iter) iter->next_page_idx[next_cpu] = 0; iter->next_page[next_cpu] = - iter->next_page[next_cpu]->next; - if (iter->next_page[next_cpu] == &data->trace_pages) - iter->next_page[next_cpu] = - data->trace_pages.next; + trace_next_list(data, iter->next_page[next_cpu]); + } } iter->prev_ent = iter->ent; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 5df8ff2..0ce1274 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -53,13 +53,15 @@ struct trace_entry { * the trace, etc.) */ struct trace_array_cpu { - void *trace_current; struct list_head trace_pages; atomic_t disabled; cycle_t time_offset; /* these fields get copied into max-trace: */ - unsigned trace_current_idx; + unsigned trace_head_idx; + unsigned trace_tail_idx; + void *trace_head; /* producer */ + void *trace_tail; /* consumer */ unsigned long trace_idx; unsigned long saved_latency; unsigned long critical_start; -- cgit v0.10.2 From 214023c3d13a71525e463b5e54e360b926b4dc90 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: add a buffer for output Later patches will need to print the same things as the seq output does. But those outputs will not use the seq utility. This patch adds a buffer to the iterator, that can be used by either the seq utility or other output. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 777b859..d39f4fa 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -169,6 +169,66 @@ void *head_page(struct trace_array_cpu *data) return page_address(page); } +static notrace int +trace_seq_printf(struct trace_seq *s, const char *fmt, ...) +{ + int len = (PAGE_SIZE - 1) - s->len; + va_list ap; + + if (!len) + return 0; + + va_start(ap, fmt); + len = vsnprintf(s->buffer + s->len, len, fmt, ap); + va_end(ap); + + s->len += len; + + return len; +} + +static notrace int +trace_seq_puts(struct trace_seq *s, const char *str) +{ + int len = strlen(str); + + if (len > ((PAGE_SIZE - 1) - s->len)) + len = (PAGE_SIZE - 1) - s->len; + + memcpy(s->buffer + s->len, str, len); + s->len += len; + + return len; +} + +static notrace int +trace_seq_putc(struct trace_seq *s, unsigned char c) +{ + if (s->len >= (PAGE_SIZE - 1)) + return 0; + + s->buffer[s->len++] = c; + + return 1; +} + +static notrace void +trace_seq_reset(struct trace_seq *s) +{ + s->len = 0; +} + +static notrace void +trace_print_seq(struct seq_file *m, struct trace_seq *s) +{ + int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; + + s->buffer[len] = 0; + seq_puts(m, s->buffer); + + trace_seq_reset(s); +} + notrace static void flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) { @@ -756,25 +816,26 @@ static void s_stop(struct seq_file *m, void *p) } static void -seq_print_sym_short(struct seq_file *m, const char *fmt, unsigned long address) +seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) { #ifdef CONFIG_KALLSYMS char str[KSYM_SYMBOL_LEN]; kallsyms_lookup(address, NULL, NULL, NULL, str); - seq_printf(m, fmt, str); + trace_seq_printf(s, fmt, str); #endif } static void -seq_print_sym_offset(struct seq_file *m, const char *fmt, unsigned long address) +seq_print_sym_offset(struct trace_seq *s, const char *fmt, + unsigned long address) { #ifdef CONFIG_KALLSYMS char str[KSYM_SYMBOL_LEN]; sprint_symbol(str, address); - seq_printf(m, fmt, str); + trace_seq_printf(s, fmt, str); #endif } @@ -785,20 +846,20 @@ seq_print_sym_offset(struct seq_file *m, const char *fmt, unsigned long address) #endif static notrace void -seq_print_ip_sym(struct seq_file *m, unsigned long ip, unsigned long sym_flags) +seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) { if (!ip) { - seq_printf(m, "0"); + trace_seq_printf(s, "0"); return; } if (sym_flags & TRACE_ITER_SYM_OFFSET) - seq_print_sym_offset(m, "%s", ip); + seq_print_sym_offset(s, "%s", ip); else - seq_print_sym_short(m, "%s", ip); + seq_print_sym_short(s, "%s", ip); if (sym_flags & TRACE_ITER_SYM_ADDR) - seq_printf(m, " <" IP_FMT ">", ip); + trace_seq_printf(s, " <" IP_FMT ">", ip); } static notrace void print_lat_help_header(struct seq_file *m) @@ -881,9 +942,11 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) if (data->critical_start) { seq_puts(m, " => started at: "); - seq_print_ip_sym(m, data->critical_start, sym_flags); + seq_print_ip_sym(&iter->seq, data->critical_start, sym_flags); + trace_print_seq(m, &iter->seq); seq_puts(m, "\n => ended at: "); - seq_print_ip_sym(m, data->critical_end, sym_flags); + seq_print_ip_sym(&iter->seq, data->critical_end, sym_flags); + trace_print_seq(m, &iter->seq); seq_puts(m, "\n"); } @@ -891,61 +954,61 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) } static notrace void -lat_print_generic(struct seq_file *m, struct trace_entry *entry, int cpu) +lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) { int hardirq, softirq; char *comm; comm = trace_find_cmdline(entry->pid); - seq_printf(m, "%8.8s-%-5d ", comm, entry->pid); - seq_printf(m, "%d", cpu); - seq_printf(m, "%c%c", - (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.', - ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.')); + trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid); + trace_seq_printf(s, "%d", cpu); + trace_seq_printf(s, "%c%c", + (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.', + ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.')); hardirq = entry->flags & TRACE_FLAG_HARDIRQ; softirq = entry->flags & TRACE_FLAG_SOFTIRQ; if (hardirq && softirq) - seq_putc(m, 'H'); + trace_seq_putc(s, 'H'); else { if (hardirq) - seq_putc(m, 'h'); + trace_seq_putc(s, 'h'); else { if (softirq) - seq_putc(m, 's'); + trace_seq_putc(s, 's'); else - seq_putc(m, '.'); + trace_seq_putc(s, '.'); } } if (entry->preempt_count) - seq_printf(m, "%x", entry->preempt_count); + trace_seq_printf(s, "%x", entry->preempt_count); else - seq_puts(m, "."); + trace_seq_puts(s, "."); } unsigned long preempt_mark_thresh = 100; static notrace void -lat_print_timestamp(struct seq_file *m, unsigned long long abs_usecs, +lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs, unsigned long rel_usecs) { - seq_printf(m, " %4lldus", abs_usecs); + trace_seq_printf(s, " %4lldus", abs_usecs); if (rel_usecs > preempt_mark_thresh) - seq_puts(m, "!: "); + trace_seq_puts(s, "!: "); else if (rel_usecs > 1) - seq_puts(m, "+: "); + trace_seq_puts(s, "+: "); else - seq_puts(m, " : "); + trace_seq_puts(s, " : "); } static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; static notrace void -print_lat_fmt(struct seq_file *m, struct trace_iterator *iter, - unsigned int trace_idx, int cpu) +print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) { + struct trace_seq *s = &iter->seq; unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); struct trace_entry *next_entry = find_next_entry(iter, NULL); unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); @@ -962,39 +1025,40 @@ print_lat_fmt(struct seq_file *m, struct trace_iterator *iter, if (verbose) { comm = trace_find_cmdline(entry->pid); - seq_printf(m, "%16s %5d %d %d %08x %08x [%08lx]" - " %ld.%03ldms (+%ld.%03ldms): ", - comm, - entry->pid, cpu, entry->flags, - entry->preempt_count, trace_idx, - ns2usecs(entry->t), - abs_usecs/1000, - abs_usecs % 1000, rel_usecs/1000, rel_usecs % 1000); + trace_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]" + " %ld.%03ldms (+%ld.%03ldms): ", + comm, + entry->pid, cpu, entry->flags, + entry->preempt_count, trace_idx, + ns2usecs(entry->t), + abs_usecs/1000, + abs_usecs % 1000, rel_usecs/1000, + rel_usecs % 1000); } else { - lat_print_generic(m, entry, cpu); - lat_print_timestamp(m, abs_usecs, rel_usecs); + lat_print_generic(s, entry, cpu); + lat_print_timestamp(s, abs_usecs, rel_usecs); } switch (entry->type) { case TRACE_FN: - seq_print_ip_sym(m, entry->fn.ip, sym_flags); - seq_puts(m, " ("); - seq_print_ip_sym(m, entry->fn.parent_ip, sym_flags); - seq_puts(m, ")\n"); + seq_print_ip_sym(s, entry->fn.ip, sym_flags); + trace_seq_puts(s, " ("); + seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); + trace_seq_puts(s, ")\n"); break; case TRACE_CTX: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; comm = trace_find_cmdline(entry->ctx.next_pid); - seq_printf(m, " %d:%d:%c --> %d:%d %s\n", - entry->ctx.prev_pid, - entry->ctx.prev_prio, - S, - entry->ctx.next_pid, - entry->ctx.next_prio, - comm); + trace_seq_printf(s, " %d:%d:%c --> %d:%d %s\n", + entry->ctx.prev_pid, + entry->ctx.prev_prio, + S, + entry->ctx.next_pid, + entry->ctx.next_prio, + comm); break; default: - seq_printf(m, "Unknown type %d\n", entry->type); + trace_seq_printf(s, "Unknown type %d\n", entry->type); } } @@ -1026,8 +1090,9 @@ static notrace void sync_time_offset(struct trace_iterator *iter) } static notrace void -print_trace_fmt(struct seq_file *m, struct trace_iterator *iter) +print_trace_fmt(struct trace_iterator *iter) { + struct trace_seq *s = &iter->seq; unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); struct trace_entry *entry; unsigned long usec_rem; @@ -1045,29 +1110,29 @@ print_trace_fmt(struct seq_file *m, struct trace_iterator *iter) usec_rem = do_div(t, 1000000ULL); secs = (unsigned long)t; - seq_printf(m, "%16s-%-5d ", comm, entry->pid); - seq_printf(m, "[%02d] ", iter->cpu); - seq_printf(m, "%5lu.%06lu: ", secs, usec_rem); + trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); + trace_seq_printf(s, "[%02d] ", iter->cpu); + trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); switch (entry->type) { case TRACE_FN: - seq_print_ip_sym(m, entry->fn.ip, sym_flags); + seq_print_ip_sym(s, entry->fn.ip, sym_flags); if ((sym_flags & TRACE_ITER_PRINT_PARENT) && entry->fn.parent_ip) { - seq_printf(m, " <-"); - seq_print_ip_sym(m, entry->fn.parent_ip, sym_flags); + trace_seq_printf(s, " <-"); + seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); } - seq_printf(m, "\n"); + trace_seq_printf(s, "\n"); break; case TRACE_CTX: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; - seq_printf(m, " %d:%d:%c ==> %d:%d\n", - entry->ctx.prev_pid, - entry->ctx.prev_prio, - S, - entry->ctx.next_pid, - entry->ctx.next_prio); + trace_seq_printf(s, " %d:%d:%c ==> %d:%d\n", + entry->ctx.prev_pid, + entry->ctx.prev_prio, + S, + entry->ctx.next_pid, + entry->ctx.next_prio); break; } } @@ -1108,9 +1173,10 @@ static int s_show(struct seq_file *m, void *v) } } else { if (iter->iter_flags & TRACE_FILE_LAT_FMT) - print_lat_fmt(m, iter, iter->idx, iter->cpu); + print_lat_fmt(iter, iter->idx, iter->cpu); else - print_trace_fmt(m, iter); + print_trace_fmt(iter); + trace_print_seq(m, &iter->seq); } return 0; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 0ce1274..f5b32ca 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -111,11 +111,17 @@ struct tracer { int print_max; }; +struct trace_seq { + unsigned char buffer[PAGE_SIZE]; + unsigned int len; +}; + /* * Trace iterator - used by printout routines who present trace * results to users and which routines might sleep, etc: */ struct trace_iterator { + struct trace_seq seq; struct trace_array *tr; struct tracer *trace; -- cgit v0.10.2 From b3806b4316306dc9c542eff6c23d7d42918f3504 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: user run time file reading This patch creates a file called trace_pipe in the tracing debug directory. This file is a consumer of the trace buffers. This means that reads of this file consumes the entries from the trace buffers so that they will not be read a second time, as contrast to the static buffers latency_trace and trace. Reading from the trace_pipe will remove the entries from trace and latency_trace too. The advantage that trace_pipe has is that it can record live traces. It will block when there is nothing in the buffer, and read the entries as they are entered. An EOF happens when tracing is disabled (tracing_enabled = 0). Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d39f4fa..a40687a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -174,15 +174,20 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { int len = (PAGE_SIZE - 1) - s->len; va_list ap; + int ret; if (!len) return 0; va_start(ap, fmt); - len = vsnprintf(s->buffer + s->len, len, fmt, ap); + ret = vsnprintf(s->buffer + s->len, len, fmt, ap); va_end(ap); - s->len += len; + /* If we can't write it all, don't bother writing anything */ + if (ret > len) + return 0; + + s->len += ret; return len; } @@ -193,7 +198,7 @@ trace_seq_puts(struct trace_seq *s, const char *str) int len = strlen(str); if (len > ((PAGE_SIZE - 1) - s->len)) - len = (PAGE_SIZE - 1) - s->len; + return 0; memcpy(s->buffer + s->len, str, len); s->len += len; @@ -615,11 +620,13 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, { struct trace_entry *entry; + spin_lock(&data->lock); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_FN; entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; + spin_unlock(&data->lock); } notrace void @@ -630,6 +637,7 @@ tracing_sched_switch_trace(struct trace_array *tr, { struct trace_entry *entry; + spin_lock(&data->lock); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_CTX; @@ -638,6 +646,7 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.prev_state = prev->state; entry->ctx.next_pid = next->pid; entry->ctx.next_prio = next->prio; + spin_unlock(&data->lock); } enum trace_file_type { @@ -652,7 +661,9 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, struct trace_entry *array; if (iter->next_idx[cpu] >= tr->entries || - iter->next_idx[cpu] >= data->trace_idx) + iter->next_idx[cpu] >= data->trace_idx || + (data->trace_head == data->trace_tail && + data->trace_head_idx == data->trace_tail_idx)) return NULL; if (!iter->next_page[cpu]) { @@ -702,33 +713,57 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) return next; } -static void *find_next_entry_inc(struct trace_iterator *iter) +static notrace void +trace_iterator_increment(struct trace_iterator *iter) { - struct trace_entry *next; - int next_cpu = -1; + iter->idx++; + iter->next_idx[iter->cpu]++; + iter->next_page_idx[iter->cpu]++; + if (iter->next_page_idx[iter->cpu] >= ENTRIES_PER_PAGE) { + struct trace_array_cpu *data = iter->tr->data[iter->cpu]; - next = find_next_entry(iter, &next_cpu); + iter->next_page_idx[iter->cpu] = 0; + iter->next_page[iter->cpu] = + trace_next_list(data, iter->next_page[iter->cpu]); + } +} - if (next) { - iter->idx++; - iter->next_idx[next_cpu]++; - iter->next_page_idx[next_cpu]++; +static notrace void +trace_consume(struct trace_iterator *iter) +{ + struct trace_array_cpu *data = iter->tr->data[iter->cpu]; + + data->trace_tail_idx++; + if (data->trace_tail_idx >= ENTRIES_PER_PAGE) { + data->trace_tail = trace_next_page(data, data->trace_tail); + data->trace_tail_idx = 0; + } - if (iter->next_page_idx[next_cpu] >= ENTRIES_PER_PAGE) { - struct trace_array_cpu *data = iter->tr->data[next_cpu]; + /* Check if we empty it, then reset the index */ + if (data->trace_head == data->trace_tail && + data->trace_head_idx == data->trace_tail_idx) + data->trace_idx = 0; - iter->next_page_idx[next_cpu] = 0; - iter->next_page[next_cpu] = - trace_next_list(data, iter->next_page[next_cpu]); + trace_iterator_increment(iter); +} + +static notrace void * +find_next_entry_inc(struct trace_iterator *iter) +{ + struct trace_entry *next; + int next_cpu = -1; + + next = find_next_entry(iter, &next_cpu); - } - } iter->prev_ent = iter->ent; iter->prev_cpu = iter->cpu; iter->ent = next; iter->cpu = next_cpu; + if (next) + trace_iterator_increment(iter); + return next ? iter : NULL; } @@ -815,7 +850,7 @@ static void s_stop(struct seq_file *m, void *p) mutex_unlock(&trace_types_lock); } -static void +static int seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) { #ifdef CONFIG_KALLSYMS @@ -823,11 +858,12 @@ seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) kallsyms_lookup(address, NULL, NULL, NULL, str); - trace_seq_printf(s, fmt, str); + return trace_seq_printf(s, fmt, str); #endif + return 1; } -static void +static int seq_print_sym_offset(struct trace_seq *s, const char *fmt, unsigned long address) { @@ -835,8 +871,9 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt, char str[KSYM_SYMBOL_LEN]; sprint_symbol(str, address); - trace_seq_printf(s, fmt, str); + return trace_seq_printf(s, fmt, str); #endif + return 1; } #ifndef CONFIG_64BIT @@ -845,21 +882,25 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt, # define IP_FMT "%016lx" #endif -static notrace void +static notrace int seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) { - if (!ip) { - trace_seq_printf(s, "0"); - return; - } + int ret; + + if (!ip) + return trace_seq_printf(s, "0"); if (sym_flags & TRACE_ITER_SYM_OFFSET) - seq_print_sym_offset(s, "%s", ip); + ret = seq_print_sym_offset(s, "%s", ip); else - seq_print_sym_short(s, "%s", ip); + ret = seq_print_sym_short(s, "%s", ip); + + if (!ret) + return 0; if (sym_flags & TRACE_ITER_SYM_ADDR) - trace_seq_printf(s, " <" IP_FMT ">", ip); + ret = trace_seq_printf(s, " <" IP_FMT ">", ip); + return ret; } static notrace void print_lat_help_header(struct seq_file *m) @@ -1089,7 +1130,7 @@ static notrace void sync_time_offset(struct trace_iterator *iter) array->time_offset += prev_t - t; } -static notrace void +static notrace int print_trace_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; @@ -1100,6 +1141,7 @@ print_trace_fmt(struct trace_iterator *iter) unsigned long secs; char *comm; int S; + int ret; sync_time_offset(iter); entry = iter->ent; @@ -1110,31 +1152,49 @@ print_trace_fmt(struct trace_iterator *iter) usec_rem = do_div(t, 1000000ULL); secs = (unsigned long)t; - trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); - trace_seq_printf(s, "[%02d] ", iter->cpu); - trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); + if (!ret) + return 0; + ret = trace_seq_printf(s, "[%02d] ", iter->cpu); + if (!ret) + return 0; + ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + if (!ret) + return 0; switch (entry->type) { case TRACE_FN: - seq_print_ip_sym(s, entry->fn.ip, sym_flags); + ret = seq_print_ip_sym(s, entry->fn.ip, sym_flags); + if (!ret) + return 0; if ((sym_flags & TRACE_ITER_PRINT_PARENT) && entry->fn.parent_ip) { - trace_seq_printf(s, " <-"); - seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); + ret = trace_seq_printf(s, " <-"); + if (!ret) + return 0; + ret = seq_print_ip_sym(s, entry->fn.parent_ip, + sym_flags); + if (!ret) + return 0; } - trace_seq_printf(s, "\n"); + ret = trace_seq_printf(s, "\n"); + if (!ret) + return 0; break; case TRACE_CTX: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; - trace_seq_printf(s, " %d:%d:%c ==> %d:%d\n", - entry->ctx.prev_pid, - entry->ctx.prev_prio, - S, - entry->ctx.next_pid, - entry->ctx.next_prio); + ret = trace_seq_printf(s, " %d:%d:%c ==> %d:%d\n", + entry->ctx.prev_pid, + entry->ctx.prev_prio, + S, + entry->ctx.next_pid, + entry->ctx.next_prio); + if (!ret) + return 0; break; } + return 1; } static int trace_empty(struct trace_iterator *iter) @@ -1145,7 +1205,9 @@ static int trace_empty(struct trace_iterator *iter) for_each_possible_cpu(cpu) { data = iter->tr->data[cpu]; - if (head_page(data) && data->trace_idx) + if (head_page(data) && data->trace_idx && + (data->trace_tail != data->trace_head || + data->trace_tail_idx != data->trace_head_idx)) return 0; } return 1; @@ -1645,6 +1707,192 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, return cnt; } +static atomic_t tracing_reader; + +static int tracing_open_pipe(struct inode *inode, struct file *filp) +{ + struct trace_iterator *iter; + + if (tracing_disabled) + return -ENODEV; + + /* We only allow for reader of the pipe */ + if (atomic_inc_return(&tracing_reader) != 1) { + atomic_dec(&tracing_reader); + return -EBUSY; + } + + /* create a buffer to store the information to pass to userspace */ + iter = kzalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) + return -ENOMEM; + + iter->tr = &global_trace; + + filp->private_data = iter; + + return 0; +} + +static int tracing_release_pipe(struct inode *inode, struct file *file) +{ + struct trace_iterator *iter = file->private_data; + + kfree(iter); + atomic_dec(&tracing_reader); + + return 0; +} + +/* + * Consumer reader. + */ +static ssize_t +tracing_read_pipe(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct trace_iterator *iter = filp->private_data; + struct trace_array_cpu *data; + static cpumask_t mask; + struct trace_entry *entry; + static int start; + unsigned long flags; + int read = 0; + int cpu; + int len; + int ret; + + /* return any leftover data */ + if (iter->seq.len > start) { + len = iter->seq.len - start; + if (cnt > len) + cnt = len; + ret = copy_to_user(ubuf, iter->seq.buffer + start, cnt); + if (ret) + cnt = -EFAULT; + + start += len; + + return cnt; + } + + trace_seq_reset(&iter->seq); + start = 0; + + while (trace_empty(iter)) { + /* + * This is a make-shift waitqueue. The reason we don't use + * an actual wait queue is because: + * 1) we only ever have one waiter + * 2) the tracing, traces all functions, we don't want + * the overhead of calling wake_up and friends + * (and tracing them too) + * Anyway, this is really very primitive wakeup. + */ + set_current_state(TASK_INTERRUPTIBLE); + iter->tr->waiter = current; + + /* sleep for one second, and try again. */ + schedule_timeout(HZ); + + iter->tr->waiter = NULL; + + if (signal_pending(current)) + return -EINTR; + + /* + * We block until we read something and tracing is disabled. + * We still block if tracing is disabled, but we have never + * read anything. This allows a user to cat this file, and + * then enable tracing. But after we have read something, + * we give an EOF when tracing is again disabled. + * + * iter->pos will be 0 if we haven't read anything. + */ + if (!tracer_enabled && iter->pos) + break; + + continue; + } + + /* stop when tracing is finished */ + if (trace_empty(iter)) + return 0; + + if (cnt >= PAGE_SIZE) + cnt = PAGE_SIZE - 1; + + memset(iter, 0, sizeof(*iter)); + iter->tr = &global_trace; + iter->pos = -1; + + /* + * We need to stop all tracing on all CPUS to read the + * the next buffer. This is a bit expensive, but is + * not done often. We fill all what we can read, + * and then release the locks again. + */ + + cpus_clear(mask); + local_irq_save(flags); + for_each_possible_cpu(cpu) { + data = iter->tr->data[cpu]; + + if (!head_page(data) || !data->trace_idx) + continue; + + atomic_inc(&data->disabled); + spin_lock(&data->lock); + cpu_set(cpu, mask); + } + + while ((entry = find_next_entry(iter, &cpu))) { + + if (!entry) + break; + + iter->ent = entry; + iter->cpu = cpu; + + ret = print_trace_fmt(iter); + if (!ret) + break; + + trace_consume(iter); + + if (iter->seq.len >= cnt) + break; + + } + + for_each_possible_cpu(cpu) { + data = iter->tr->data[cpu]; + + if (!cpu_isset(cpu, mask)) + continue; + spin_unlock(&data->lock); + atomic_dec(&data->disabled); + } + local_irq_restore(flags); + + /* Now copy what we have to the user */ + read = iter->seq.len; + if (read > cnt) + read = cnt; + + ret = copy_to_user(ubuf, iter->seq.buffer, read); + + if (read < iter->seq.len) + start = read; + else + trace_seq_reset(&iter->seq); + + if (ret) + read = -EFAULT; + + return read; +} + static struct file_operations tracing_max_lat_fops = { .open = tracing_open_generic, .read = tracing_max_lat_read, @@ -1663,6 +1911,12 @@ static struct file_operations set_tracer_fops = { .write = tracing_set_trace_write, }; +static struct file_operations tracing_pipe_fops = { + .open = tracing_open_pipe, + .read = tracing_read_pipe, + .release = tracing_release_pipe, +}; + #ifdef CONFIG_DYNAMIC_FTRACE static ssize_t @@ -1763,6 +2017,11 @@ static __init void tracer_init_debugfs(void) if (!entry) pr_warning("Could not create debugfs 'README' entry\n"); + entry = debugfs_create_file("trace_pipe", 0644, d_tracer, + NULL, &tracing_pipe_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'tracing_threash' entry\n"); #ifdef CONFIG_DYNAMIC_FTRACE entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, @@ -1816,6 +2075,7 @@ static int trace_alloc_page(void) /* Now that we successfully allocate a page per CPU, add them */ for_each_possible_cpu(i) { data = global_trace.data[i]; + spin_lock_init(&data->lock); page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); @@ -1823,6 +2083,7 @@ static int trace_alloc_page(void) #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; + spin_lock_init(&data->lock); page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index f5b32ca..29a7ea5 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -55,6 +55,7 @@ struct trace_entry { struct trace_array_cpu { struct list_head trace_pages; atomic_t disabled; + spinlock_t lock; cycle_t time_offset; /* these fields get copied into max-trace: */ @@ -88,6 +89,7 @@ struct trace_array { long ctrl; int cpu; cycle_t time_start; + struct task_struct *waiter; struct trace_array_cpu *data[NR_CPUS]; }; -- cgit v0.10.2 From d4c5a2f5870939d837293de87b41dda0012a4572 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: fix locking we can hold all cpu trace buffer locks at once - put each into a separate lock class. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a40687a..b3811ca 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1865,11 +1865,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, } - for_each_possible_cpu(cpu) { + for_each_cpu_mask(cpu, mask) { data = iter->tr->data[cpu]; - - if (!cpu_isset(cpu, mask)) - continue; spin_unlock(&data->lock); atomic_dec(&data->disabled); } @@ -2076,6 +2073,7 @@ static int trace_alloc_page(void) for_each_possible_cpu(i) { data = global_trace.data[i]; spin_lock_init(&data->lock); + lockdep_set_class(&data->lock, &data->lock_key); page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); @@ -2084,6 +2082,7 @@ static int trace_alloc_page(void) #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; spin_lock_init(&data->lock); + lockdep_set_class(&data->lock, &data->lock_key); page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); @@ -2203,5 +2202,4 @@ __init static int tracer_alloc_buffers(void) } return ret; } - fs_initcall(tracer_alloc_buffers); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 29a7ea5..b040835 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -56,6 +56,7 @@ struct trace_array_cpu { struct list_head trace_pages; atomic_t disabled; spinlock_t lock; + struct lock_class_key lock_key; cycle_t time_offset; /* these fields get copied into max-trace: */ -- cgit v0.10.2 From 4bf39a9411a4ce8712954e03a9bd1592ee345919 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: cleanups no code changed. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 5e9389f..97c4086 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -756,9 +756,11 @@ ftrace_avail_open(struct inode *inode, struct file *file) ret = seq_open(file, &show_ftrace_seq_ops); if (!ret) { struct seq_file *m = file->private_data; + m->private = iter; - } else + } else { kfree(iter); + } return ret; } @@ -770,6 +772,7 @@ int ftrace_avail_release(struct inode *inode, struct file *file) seq_release(inode, file); kfree(iter); + return 0; } diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b3811ca..4550afd 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1245,10 +1245,10 @@ static int s_show(struct seq_file *m, void *v) } static struct seq_operations tracer_seq_ops = { - .start = s_start, - .next = s_next, - .stop = s_stop, - .show = s_show, + .start = s_start, + .next = s_next, + .stop = s_stop, + .show = s_show, }; static struct trace_iterator notrace * @@ -1397,10 +1397,10 @@ static int t_show(struct seq_file *m, void *v) } static struct seq_operations show_traces_seq_ops = { - .start = t_start, - .next = t_next, - .stop = t_stop, - .show = t_show, + .start = t_start, + .next = t_next, + .stop = t_stop, + .show = t_show, }; static int show_traces_open(struct inode *inode, struct file *file) @@ -1420,17 +1420,17 @@ static int show_traces_open(struct inode *inode, struct file *file) } static struct file_operations tracing_fops = { - .open = tracing_open, - .read = seq_read, - .llseek = seq_lseek, - .release = tracing_release, + .open = tracing_open, + .read = seq_read, + .llseek = seq_lseek, + .release = tracing_release, }; static struct file_operations tracing_lt_fops = { - .open = tracing_lt_open, - .read = seq_read, - .llseek = seq_lseek, - .release = tracing_release, + .open = tracing_lt_open, + .read = seq_read, + .llseek = seq_lseek, + .release = tracing_release, }; static struct file_operations show_traces_fops = { @@ -1620,8 +1620,7 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf, r = sprintf(buf, "\n"); mutex_unlock(&trace_types_lock); - return simple_read_from_buffer(ubuf, cnt, ppos, - buf, r); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t @@ -1680,8 +1679,7 @@ tracing_max_lat_read(struct file *filp, char __user *ubuf, *ptr == (unsigned long)-1 ? -1 : nsecs_to_usecs(*ptr)); if (r > 64) r = 64; - return simple_read_from_buffer(ubuf, cnt, ppos, - buf, r); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t @@ -1891,27 +1889,27 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, } static struct file_operations tracing_max_lat_fops = { - .open = tracing_open_generic, - .read = tracing_max_lat_read, - .write = tracing_max_lat_write, + .open = tracing_open_generic, + .read = tracing_max_lat_read, + .write = tracing_max_lat_write, }; static struct file_operations tracing_ctrl_fops = { - .open = tracing_open_generic, - .read = tracing_ctrl_read, - .write = tracing_ctrl_write, + .open = tracing_open_generic, + .read = tracing_ctrl_read, + .write = tracing_ctrl_write, }; static struct file_operations set_tracer_fops = { - .open = tracing_open_generic, - .read = tracing_set_trace_read, - .write = tracing_set_trace_write, + .open = tracing_open_generic, + .read = tracing_set_trace_read, + .write = tracing_set_trace_write, }; static struct file_operations tracing_pipe_fops = { - .open = tracing_open_pipe, - .read = tracing_read_pipe, - .release = tracing_release_pipe, + .open = tracing_open_pipe, + .read = tracing_read_pipe, + .release = tracing_release_pipe, }; #ifdef CONFIG_DYNAMIC_FTRACE @@ -1925,13 +1923,13 @@ tracing_read_long(struct file *filp, char __user *ubuf, int r; r = sprintf(buf, "%ld\n", *p); - return simple_read_from_buffer(ubuf, cnt, ppos, - buf, r); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static struct file_operations tracing_read_long_fops = { - .open = tracing_open_generic, - .read = tracing_read_long, + .open = tracing_open_generic, + .read = tracing_read_long, }; #endif @@ -2033,7 +2031,7 @@ static __init void tracer_init_debugfs(void) /* dummy trace to disable tracing */ static struct tracer no_tracer __read_mostly = { - .name = "none", + .name = "none", }; static int trace_alloc_page(void) -- cgit v0.10.2 From 750ed1a40783432d0dcb0e6c2e813a12615d7664 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: timestamp syncing, prepare rename and uninline now() to ftrace_now(). Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 97c4086..a15e068 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -531,7 +531,7 @@ static int notrace __ftrace_update_code(void *ignore) save_ftrace_enabled = ftrace_enabled; ftrace_enabled = 0; - start = now(raw_smp_processor_id()); + start = ftrace_now(raw_smp_processor_id()); ftrace_update_cnt = 0; /* No locks needed, the machine is stopped! */ @@ -550,7 +550,7 @@ static int notrace __ftrace_update_code(void *ignore) } - stop = now(raw_smp_processor_id()); + stop = ftrace_now(raw_smp_processor_id()); ftrace_update_time = stop - start; ftrace_update_tot_cnt += ftrace_update_cnt; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4550afd..e3778ab 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -42,6 +42,11 @@ ns2usecs(cycle_t nsec) return nsec; } +notrace cycle_t ftrace_now(int cpu) +{ + return cpu_clock(cpu); +} + static atomic_t tracer_counter; static struct trace_array global_trace; @@ -607,7 +612,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) entry->idx = atomic_inc_return(&tracer_counter); entry->preempt_count = pc & 0xff; entry->pid = tsk->pid; - entry->t = now(raw_smp_processor_id()); + entry->t = ftrace_now(raw_smp_processor_id()); entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b040835..30cad67 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -171,10 +171,7 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu); -static inline notrace cycle_t now(int cpu) -{ - return cpu_clock(cpu); -} +extern notrace cycle_t ftrace_now(int cpu); #ifdef CONFIG_SCHED_TRACER extern void notrace diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 5d8ad7a..e5d34b7 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -20,7 +20,7 @@ static notrace void function_reset(struct trace_array *tr) { int cpu; - tr->time_start = now(tr->cpu); + tr->time_start = ftrace_now(tr->cpu); for_each_online_cpu(cpu) tracing_reset(tr->data[cpu]); diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 2dfebb6..d2a6e6f 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -136,7 +136,7 @@ check_critical_timing(struct trace_array *tr, * as long as possible: */ T0 = data->preempt_timestamp; - T1 = now(cpu); + T1 = ftrace_now(cpu); delta = T1-T0; local_save_flags(flags); @@ -186,7 +186,7 @@ out_unlock: out: data->critical_sequence = max_sequence; - data->preempt_timestamp = now(cpu); + data->preempt_timestamp = ftrace_now(cpu); tracing_reset(data); ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); } @@ -215,7 +215,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) atomic_inc(&data->disabled); data->critical_sequence = max_sequence; - data->preempt_timestamp = now(cpu); + data->preempt_timestamp = ftrace_now(cpu); data->critical_start = parent_ip ? : ip; tracing_reset(data); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 6c92841..8d65667 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -61,7 +61,7 @@ static notrace void sched_switch_reset(struct trace_array *tr) { int cpu; - tr->time_start = now(tr->cpu); + tr->time_start = ftrace_now(tr->cpu); for_each_online_cpu(cpu) tracing_reset(tr->data[cpu]); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 688df96..b7df825 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -92,7 +92,7 @@ wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) * as long as possible: */ T0 = data->preempt_timestamp; - T1 = now(cpu); + T1 = ftrace_now(cpu); delta = T1-T0; if (!report_latency(delta)) @@ -191,7 +191,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p, local_save_flags(flags); - tr->data[wakeup_cpu]->preempt_timestamp = now(cpu); + tr->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu); ftrace(tr, tr->data[wakeup_cpu], CALLER_ADDR1, CALLER_ADDR2, flags); out_locked: -- cgit v0.10.2 From 53c37c17aafcf50f7c6fddaf01dda8f9d7e31ddf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: fast, scalable, synchronized timestamps implement globally synchronized, fast and scalable time source for tracing. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e3778ab..9a931c7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -42,9 +42,61 @@ ns2usecs(cycle_t nsec) return nsec; } +static const int time_sync_freq_max = 128; +static const cycle_t time_sync_thresh = 100000; + +static DEFINE_PER_CPU(cycle_t, time_offset); +static DEFINE_PER_CPU(cycle_t, prev_cpu_time); +static DEFINE_PER_CPU(int, time_sync_count); +static DEFINE_PER_CPU(int, time_sync_freq); + +/* + * Global lock which we take every now and then to synchronize + * the CPUs time. This method is not warp-safe, but it's good + * enough to synchronize slowly diverging time sources and thus + * it's good enough for tracing: + */ +static DEFINE_SPINLOCK(time_sync_lock); +static cycle_t prev_global_time; + +static notrace cycle_t __ftrace_now_sync(cycles_t time, int cpu) +{ + unsigned long flags; + + spin_lock_irqsave(&time_sync_lock, flags); + + /* + * Update the synchronization frequency: + */ + if (per_cpu(time_sync_freq, cpu) < time_sync_freq_max) + per_cpu(time_sync_freq, cpu) *= 2; + per_cpu(time_sync_count, cpu) = per_cpu(time_sync_freq, cpu); + + if (time < prev_global_time) { + per_cpu(time_offset, cpu) += prev_global_time - time; + time = prev_global_time; + } else { + prev_global_time = time; + } + + spin_unlock_irqrestore(&time_sync_lock, flags); + + return time; +} + notrace cycle_t ftrace_now(int cpu) { - return cpu_clock(cpu); + cycle_t prev_cpu_time, time, delta_time; + + prev_cpu_time = per_cpu(prev_cpu_time, cpu); + time = sched_clock() + per_cpu(time_offset, cpu); + delta_time = time-prev_cpu_time; + + if (unlikely(delta_time > time_sync_thresh || + --per_cpu(time_sync_count, cpu) <= 0)) + time = __ftrace_now_sync(time, cpu); + + return time; } static atomic_t tracer_counter; -- cgit v0.10.2 From cdd31cd2d7a0dcbec2cce3974f7129dd4fc8c879 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: remove-idx-sync remove idx syncing - it's expensive on SMP. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9a931c7..ce8ceb8 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -99,7 +99,6 @@ notrace cycle_t ftrace_now(int cpu) return time; } -static atomic_t tracer_counter; static struct trace_array global_trace; static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); @@ -661,7 +660,6 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) pc = preempt_count(); - entry->idx = atomic_inc_return(&tracer_counter); entry->preempt_count = pc & 0xff; entry->pid = tsk->pid; entry->t = ftrace_now(raw_smp_processor_id()); @@ -757,8 +755,10 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) if (!head_page(tr->data[cpu])) continue; ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu); - if (ent && - (!next || (long)(next->idx - ent->idx) > 0)) { + /* + * Pick the entry with the smallest timestamp: + */ + if (ent && (!next || ent->t < next->t)) { next = ent; next_cpu = cpu; } @@ -800,8 +800,6 @@ trace_consume(struct trace_iterator *iter) if (data->trace_head == data->trace_tail && data->trace_head_idx == data->trace_tail_idx) data->trace_idx = 0; - - trace_iterator_increment(iter); } static notrace void * @@ -1160,33 +1158,6 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) } } -static notrace void sync_time_offset(struct trace_iterator *iter) -{ - struct trace_array_cpu *prev_array, *array; - struct trace_entry *prev_entry, *entry; - cycle_t prev_t, t; - - entry = iter->ent; - prev_entry = iter->prev_ent; - if (!prev_entry) - return; - - prev_array = iter->tr->data[iter->prev_cpu]; - array = iter->tr->data[iter->cpu]; - - prev_t = prev_entry->t + prev_array->time_offset; - t = entry->t + array->time_offset; - - /* - * If time goes backwards we increase the offset of - * the current array, to not have observable time warps. - * This will quickly synchronize the time offsets of - * multiple CPUs: - */ - if (t < prev_t) - array->time_offset += prev_t - t; -} - static notrace int print_trace_fmt(struct trace_iterator *iter) { @@ -1200,12 +1171,11 @@ print_trace_fmt(struct trace_iterator *iter) int S; int ret; - sync_time_offset(iter); entry = iter->ent; comm = trace_find_cmdline(iter->ent->pid); - t = ns2usecs(entry->t + iter->tr->data[iter->cpu]->time_offset); + t = ns2usecs(entry->t); usec_rem = do_div(t, 1000000ULL); secs = (unsigned long)t; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 30cad67..27fa2d0 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -38,7 +38,6 @@ struct trace_entry { char preempt_count; int pid; cycle_t t; - unsigned long idx; union { struct ftrace_entry fn; struct ctx_switch_entry ctx; @@ -57,7 +56,6 @@ struct trace_array_cpu { atomic_t disabled; spinlock_t lock; struct lock_class_key lock_key; - cycle_t time_offset; /* these fields get copied into max-trace: */ unsigned trace_head_idx; -- cgit v0.10.2 From 8c523a9d82dbc4f3f7d972df8c0f1eacd83d0d55 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:46 +0200 Subject: ftrace: clean-up-pipe-iteration Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ce8ceb8..42f1926 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -770,12 +770,12 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) return next; } -static notrace void -trace_iterator_increment(struct trace_iterator *iter) +static notrace void trace_iterator_increment(struct trace_iterator *iter) { iter->idx++; iter->next_idx[iter->cpu]++; iter->next_page_idx[iter->cpu]++; + if (iter->next_page_idx[iter->cpu] >= ENTRIES_PER_PAGE) { struct trace_array_cpu *data = iter->tr->data[iter->cpu]; @@ -785,8 +785,7 @@ trace_iterator_increment(struct trace_iterator *iter) } } -static notrace void -trace_consume(struct trace_iterator *iter) +static notrace void trace_consume(struct trace_iterator *iter) { struct trace_array_cpu *data = iter->tr->data[iter->cpu]; @@ -802,8 +801,7 @@ trace_consume(struct trace_iterator *iter) data->trace_idx = 0; } -static notrace void * -find_next_entry_inc(struct trace_iterator *iter) +static notrace void *find_next_entry_inc(struct trace_iterator *iter) { struct trace_entry *next; int next_cpu = -1; @@ -1871,14 +1869,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, cpu_set(cpu, mask); } - while ((entry = find_next_entry(iter, &cpu))) { - - if (!entry) - break; - - iter->ent = entry; - iter->cpu = cpu; - + while ((entry = find_next_entry_inc(iter)) != NULL) { ret = print_trace_fmt(iter); if (!ret) break; @@ -1887,7 +1878,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, if (iter->seq.len >= cnt) break; - } for_each_cpu_mask(cpu, mask) { -- cgit v0.10.2 From f9896bf30928922a3913a3810a4ab7908da6cfe7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: add raw output Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 42f1926..bebd263 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -153,6 +153,7 @@ enum trace_iterator_flags { TRACE_ITER_SYM_OFFSET = 0x02, TRACE_ITER_SYM_ADDR = 0x04, TRACE_ITER_VERBOSE = 0x08, + TRACE_ITER_RAW = 0x10, }; #define TRACE_ITER_SYM_MASK \ @@ -164,6 +165,7 @@ static const char *trace_options[] = { "sym-offset", "sym-addr", "verbose", + "raw", NULL }; @@ -1099,7 +1101,7 @@ lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs, static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; -static notrace void +static notrace int print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) { struct trace_seq *s = &iter->seq; @@ -1154,10 +1156,10 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) default: trace_seq_printf(s, "Unknown type %d\n", entry->type); } + return 1; } -static notrace int -print_trace_fmt(struct trace_iterator *iter) +static notrace int print_trace_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); @@ -1222,6 +1224,43 @@ print_trace_fmt(struct trace_iterator *iter) return 1; } +static notrace int print_raw_fmt(struct trace_iterator *iter) +{ + struct trace_seq *s = &iter->seq; + struct trace_entry *entry; + int ret; + int S; + + entry = iter->ent; + + ret = trace_seq_printf(s, "%d %d %llu ", + entry->pid, iter->cpu, entry->t); + if (!ret) + return 0; + + switch (entry->type) { + case TRACE_FN: + ret = trace_seq_printf(s, "%x %x\n", + entry->fn.ip, entry->fn.parent_ip); + if (!ret) + return 0; + break; + case TRACE_CTX: + S = entry->ctx.prev_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.prev_state] : 'X'; + ret = trace_seq_printf(s, "%d %d %c %d %d\n", + entry->ctx.prev_pid, + entry->ctx.prev_prio, + S, + entry->ctx.next_pid, + entry->ctx.next_prio); + if (!ret) + return 0; + break; + } + return 1; +} + static int trace_empty(struct trace_iterator *iter) { struct trace_array_cpu *data; @@ -1238,6 +1277,17 @@ static int trace_empty(struct trace_iterator *iter) return 1; } +static int print_trace_line(struct trace_iterator *iter) +{ + if (trace_flags & TRACE_ITER_RAW) + return print_raw_fmt(iter); + + if (iter->iter_flags & TRACE_FILE_LAT_FMT) + return print_lat_fmt(iter, iter->idx, iter->cpu); + + return print_trace_fmt(iter); +} + static int s_show(struct seq_file *m, void *v) { struct trace_iterator *iter = v; @@ -1259,10 +1309,7 @@ static int s_show(struct seq_file *m, void *v) print_func_help_header(m); } } else { - if (iter->iter_flags & TRACE_FILE_LAT_FMT) - print_lat_fmt(iter, iter->idx, iter->cpu); - else - print_trace_fmt(iter); + print_trace_line(iter); trace_print_seq(m, &iter->seq); } @@ -1870,7 +1917,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, } while ((entry = find_next_entry_inc(iter)) != NULL) { - ret = print_trace_fmt(iter); + ret = print_trace_line(iter); if (!ret) break; -- cgit v0.10.2 From cb0f12aae8d085140d37ada351aa5a8e76c3f9b0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: bin-output Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bebd263..d78cbc4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -154,6 +154,7 @@ enum trace_iterator_flags { TRACE_ITER_SYM_ADDR = 0x04, TRACE_ITER_VERBOSE = 0x08, TRACE_ITER_RAW = 0x10, + TRACE_ITER_BIN = 0x20, }; #define TRACE_ITER_SYM_MASK \ @@ -166,6 +167,7 @@ static const char *trace_options[] = { "sym-addr", "verbose", "raw", + "bin", NULL }; @@ -275,6 +277,18 @@ trace_seq_putc(struct trace_seq *s, unsigned char c) return 1; } +static notrace int +trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) +{ + if (len > ((PAGE_SIZE - 1) - s->len)) + return 0; + + memcpy(s->buffer + s->len, mem, len); + s->len += len; + + return len; +} + static notrace void trace_seq_reset(struct trace_seq *s) { @@ -1261,6 +1275,39 @@ static notrace int print_raw_fmt(struct trace_iterator *iter) return 1; } +#define SEQ_PUT_FIELD_RET(s, x) \ +do { \ + if (!trace_seq_putmem(s, &(x), sizeof(x))) \ + return 0; \ +} while (0) + +static notrace int print_bin_fmt(struct trace_iterator *iter) +{ + struct trace_seq *s = &iter->seq; + struct trace_entry *entry; + + entry = iter->ent; + + SEQ_PUT_FIELD_RET(s, entry->pid); + SEQ_PUT_FIELD_RET(s, entry->cpu); + SEQ_PUT_FIELD_RET(s, entry->t); + + switch (entry->type) { + case TRACE_FN: + SEQ_PUT_FIELD_RET(s, entry->fn.ip); + SEQ_PUT_FIELD_RET(s, entry->fn.parent_ip); + break; + case TRACE_CTX: + SEQ_PUT_FIELD_RET(s, entry->ctx.prev_pid); + SEQ_PUT_FIELD_RET(s, entry->ctx.prev_prio); + SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state); + SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid); + SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio); + break; + } + return 1; +} + static int trace_empty(struct trace_iterator *iter) { struct trace_array_cpu *data; @@ -1279,6 +1326,9 @@ static int trace_empty(struct trace_iterator *iter) static int print_trace_line(struct trace_iterator *iter) { + if (trace_flags & TRACE_ITER_BIN) + return print_bin_fmt(iter); + if (trace_flags & TRACE_ITER_RAW) return print_raw_fmt(iter); -- cgit v0.10.2 From f0a920d5752e1788c0cba2add103076bcc0f7a49 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: add trace_special() for ad-hoc tracing. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d78cbc4..fa13059 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -137,6 +137,7 @@ enum trace_type { TRACE_FN, TRACE_CTX, + TRACE_SPECIAL, __TRACE_LAST_TYPE }; @@ -701,6 +702,22 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, } notrace void +trace_special(struct trace_array *tr, struct trace_array_cpu *data, + unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + struct trace_entry *entry; + + spin_lock(&data->lock); + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, 0); + entry->type = TRACE_SPECIAL; + entry->special.arg1 = arg1; + entry->special.arg2 = arg2; + entry->special.arg3 = arg3; + spin_unlock(&data->lock); +} + +notrace void tracing_sched_switch_trace(struct trace_array *tr, struct trace_array_cpu *data, struct task_struct *prev, struct task_struct *next, @@ -1167,6 +1184,12 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) entry->ctx.next_prio, comm); break; + case TRACE_SPECIAL: + trace_seq_printf(s, " %lx %lx %lx\n", + entry->special.arg1, + entry->special.arg2, + entry->special.arg3); + break; default: trace_seq_printf(s, "Unknown type %d\n", entry->type); } @@ -1234,6 +1257,14 @@ static notrace int print_trace_fmt(struct trace_iterator *iter) if (!ret) return 0; break; + case TRACE_SPECIAL: + ret = trace_seq_printf(s, " %lx %lx %lx\n", + entry->special.arg1, + entry->special.arg2, + entry->special.arg3); + if (!ret) + return 0; + break; } return 1; } @@ -1271,6 +1302,14 @@ static notrace int print_raw_fmt(struct trace_iterator *iter) if (!ret) return 0; break; + case TRACE_SPECIAL: + ret = trace_seq_printf(s, " %lx %lx %lx\n", + entry->special.arg1, + entry->special.arg2, + entry->special.arg3); + if (!ret) + return 0; + break; } return 1; } @@ -1304,6 +1343,11 @@ static notrace int print_bin_fmt(struct trace_iterator *iter) SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid); SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio); break; + case TRACE_SPECIAL: + SEQ_PUT_FIELD_RET(s, entry->special.arg1); + SEQ_PUT_FIELD_RET(s, entry->special.arg2); + SEQ_PUT_FIELD_RET(s, entry->special.arg3); + break; } return 1; } diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 27fa2d0..7bdfef3 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -26,6 +26,15 @@ struct ctx_switch_entry { }; /* + * Special (free-form) trace entry: + */ +struct special_entry { + unsigned long arg1; + unsigned long arg2; + unsigned long arg3; +}; + +/* * The trace entry - the most basic unit of tracing. This is what * is printed in the end as a single line in the trace output, such as: * @@ -41,6 +50,7 @@ struct trace_entry { union { struct ftrace_entry fn; struct ctx_switch_entry ctx; + struct special_entry special; }; }; @@ -154,6 +164,11 @@ void tracing_sched_switch_trace(struct trace_array *tr, struct task_struct *next, unsigned long flags); void tracing_record_cmdline(struct task_struct *tsk); +void trace_special(struct trace_array *tr, + struct trace_array_cpu *data, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3); void tracing_start_function_trace(void); void tracing_stop_function_trace(void); -- cgit v0.10.2 From dcb6308f2b56720599f6b9d5a01c33e67e69bde4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace, locking fix should be an irq-safe lock ... Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index fa13059..70f94fa 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -691,14 +691,15 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, unsigned long ip, unsigned long parent_ip, unsigned long flags) { struct trace_entry *entry; + unsigned long irq_flags; - spin_lock(&data->lock); + spin_lock_irqsave(&data->lock, irq_flags); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_FN; entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; - spin_unlock(&data->lock); + spin_unlock_irqrestore(&data->lock, irq_flags); } notrace void @@ -706,15 +707,16 @@ trace_special(struct trace_array *tr, struct trace_array_cpu *data, unsigned long arg1, unsigned long arg2, unsigned long arg3) { struct trace_entry *entry; + unsigned long irq_flags; - spin_lock(&data->lock); + spin_lock_irqsave(&data->lock, irq_flags); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, 0); entry->type = TRACE_SPECIAL; entry->special.arg1 = arg1; entry->special.arg2 = arg2; entry->special.arg3 = arg3; - spin_unlock(&data->lock); + spin_unlock_irqrestore(&data->lock, irq_flags); } notrace void @@ -724,8 +726,9 @@ tracing_sched_switch_trace(struct trace_array *tr, unsigned long flags) { struct trace_entry *entry; + unsigned long irq_flags; - spin_lock(&data->lock); + spin_lock_irqsave(&data->lock, irq_flags); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_CTX; @@ -734,7 +737,7 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.prev_state = prev->state; entry->ctx.next_pid = next->pid; entry->ctx.next_prio = next->prio; - spin_unlock(&data->lock); + spin_unlock_irqrestore(&data->lock, irq_flags); } enum trace_file_type { -- cgit v0.10.2 From 088b1e427dbba2af93cb6a7d39258c10ff58dd27 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace: pipe fixes Some fixes for better output with the trace pipe. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 70f94fa..c56fc5e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -770,11 +770,6 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, array = page_address(page); - /* Still possible to catch up to the tail */ - if (iter->next_idx[cpu] && array == data->trace_tail && - iter->next_page_idx[cpu] == data->trace_tail_idx) - return NULL; - WARN_ON(iter->next_page_idx[cpu] >= ENTRIES_PER_PAGE); return &array[iter->next_page_idx[cpu]]; } @@ -1921,7 +1916,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, struct trace_iterator *iter = filp->private_data; struct trace_array_cpu *data; static cpumask_t mask; - struct trace_entry *entry; static int start; unsigned long flags; int read = 0; @@ -2013,10 +2007,15 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, cpu_set(cpu, mask); } - while ((entry = find_next_entry_inc(iter)) != NULL) { + while (find_next_entry_inc(iter) != NULL) { + int len = iter->seq.len; + ret = print_trace_line(iter); - if (!ret) + if (!ret) { + /* don't print partial lines */ + iter->seq.len = len; break; + } trace_consume(iter); -- cgit v0.10.2 From 37ad508419f0fdfda7b378756eb1f35cfd26d96d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace - fix dynamic ftrace memory leak The ftrace dynamic function update allocates a record to store the instruction pointers that are being modified. If the modified instruction pointer fails to update, then the record is marked as failed and nothing more is done. Worse, if the modification fails, but the record ip function is still called, it will allocate a new record and try again. In just a matter of time, will this cause a serious memory leak and crash the system. This patch plugs this memory leak. When a record fails, it is included back into the pool of records to be used. Now a record may fail over and over again, but the number of allocated records will not increase. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a842d96..61e757b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -43,9 +43,10 @@ extern void mcount(void); # define FTRACE_HASHSIZE (1<node, &ftrace_hash[key]); } +static notrace void ftrace_free_rec(struct dyn_ftrace *rec) +{ + /* no locking, only called from kstop_machine */ + + rec->ip = (unsigned long)ftrace_free_records; + ftrace_free_records = rec; + rec->flags |= FTRACE_FL_FREE; +} + static notrace struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) { + struct dyn_ftrace *rec; + + /* First check for freed records */ + if (ftrace_free_records) { + rec = ftrace_free_records; + + /* todo, disable tracing altogether on this warning */ + if (unlikely(!(rec->flags & FTRACE_FL_FREE))) { + WARN_ON_ONCE(1); + ftrace_free_records = NULL; + return NULL; + } + + ftrace_free_records = (void *)rec->ip; + memset(rec, 0, sizeof(*rec)); + return rec; + } + if (ftrace_pages->index == ENTRIES_PER_PAGE) { if (!ftrace_pages->next) return NULL; @@ -356,8 +385,16 @@ __ftrace_replace_code(struct dyn_ftrace *rec, } failed = ftrace_modify_code(ip, old, new); - if (failed) - rec->flags |= FTRACE_FL_FAILED; + if (failed) { + unsigned long key; + /* It is possible that the function hasn't been converted yet */ + key = hash_long(ip, FTRACE_HASHBITS); + if (!ftrace_ip_in_hash(ip, key)) { + rec->flags |= FTRACE_FL_FAILED; + ftrace_free_rec(rec); + } + + } } static void notrace ftrace_replace_code(int enable) @@ -407,8 +444,10 @@ ftrace_code_disable(struct dyn_ftrace *rec) call = ftrace_call_replace(ip, MCOUNT_ADDR); failed = ftrace_modify_code(ip, call, nop); - if (failed) + if (failed) { rec->flags |= FTRACE_FL_FAILED; + ftrace_free_rec(rec); + } } static int notrace __ftrace_modify_code(void *data) -- cgit v0.10.2 From 4eebcc81a33fbc45e28542b50197ed7b3c486d90 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace: disable tracing on failure Since ftrace touches practically every function. If we detect any anomaly, we want to fully disable ftrace. This patch adds code to try shutdown ftrace as much as possible without doing any more harm is something is detected not quite correct. This only kills ftrace, this patch does have checks for other parts of the tracer (irqsoff, wakeup, etc.). Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 61e757b..4650a31 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -58,6 +58,9 @@ struct dyn_ftrace { int ftrace_force_update(void); void ftrace_set_filter(unsigned char *buf, int len, int reset); +/* totally disable ftrace - can not re-enable after this */ +void ftrace_kill(void); + /* defined in arch */ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8e02aa6..ff42345 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -29,9 +29,16 @@ #include "trace.h" -int ftrace_enabled; +/* ftrace_enabled is a method to turn ftrace on or off */ +int ftrace_enabled __read_mostly; static int last_ftrace_enabled; +/* + * ftrace_disabled is set when an anomaly is discovered. + * ftrace_disabled is much stronger than ftrace_enabled. + */ +static int ftrace_disabled __read_mostly; + static DEFINE_SPINLOCK(ftrace_lock); static DEFINE_MUTEX(ftrace_sysctl_lock); @@ -230,10 +237,11 @@ static notrace struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) if (ftrace_free_records) { rec = ftrace_free_records; - /* todo, disable tracing altogether on this warning */ if (unlikely(!(rec->flags & FTRACE_FL_FREE))) { WARN_ON_ONCE(1); ftrace_free_records = NULL; + ftrace_disabled = 1; + ftrace_enabled = 0; return NULL; } @@ -260,7 +268,7 @@ ftrace_record_ip(unsigned long ip) int resched; int atomic; - if (!ftrace_enabled) + if (!ftrace_enabled || ftrace_disabled) return; resched = need_resched(); @@ -485,6 +493,9 @@ static void notrace ftrace_startup(void) { int command = 0; + if (unlikely(ftrace_disabled)) + return; + mutex_lock(&ftraced_lock); ftraced_suspend++; if (ftraced_suspend == 1) @@ -507,6 +518,9 @@ static void notrace ftrace_shutdown(void) { int command = 0; + if (unlikely(ftrace_disabled)) + return; + mutex_lock(&ftraced_lock); ftraced_suspend--; if (!ftraced_suspend) @@ -529,6 +543,9 @@ static void notrace ftrace_startup_sysctl(void) { int command = FTRACE_ENABLE_MCOUNT; + if (unlikely(ftrace_disabled)) + return; + mutex_lock(&ftraced_lock); /* Force update next time */ saved_ftrace_func = NULL; @@ -544,6 +561,9 @@ static void notrace ftrace_shutdown_sysctl(void) { int command = FTRACE_DISABLE_MCOUNT; + if (unlikely(ftrace_disabled)) + return; + mutex_lock(&ftraced_lock); /* ftraced_suspend is true if ftrace is running */ if (ftraced_suspend) @@ -600,6 +620,9 @@ static int notrace __ftrace_update_code(void *ignore) static void notrace ftrace_update_code(void) { + if (unlikely(ftrace_disabled)) + return; + stop_machine_run(__ftrace_update_code, NULL, NR_CPUS); } @@ -614,6 +637,9 @@ static int notrace ftraced(void *ignore) /* check once a second */ schedule_timeout(HZ); + if (unlikely(ftrace_disabled)) + continue; + mutex_lock(&ftrace_sysctl_lock); mutex_lock(&ftraced_lock); if (ftrace_enabled && ftraced_trigger && !ftraced_suspend) { @@ -628,6 +654,7 @@ static int notrace ftraced(void *ignore) ftrace_update_cnt != 1 ? "s" : "", ftrace_update_tot_cnt, usecs, usecs != 1 ? "s" : ""); + ftrace_disabled = 1; WARN_ON_ONCE(1); } ftraced_trigger = 0; @@ -785,6 +812,9 @@ ftrace_avail_open(struct inode *inode, struct file *file) struct ftrace_iterator *iter; int ret; + if (unlikely(ftrace_disabled)) + return -ENODEV; + iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (!iter) return -ENOMEM; @@ -843,6 +873,9 @@ ftrace_filter_open(struct inode *inode, struct file *file) struct ftrace_iterator *iter; int ret = 0; + if (unlikely(ftrace_disabled)) + return -ENODEV; + iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (!iter) return -ENOMEM; @@ -1063,6 +1096,9 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, */ notrace void ftrace_set_filter(unsigned char *buf, int len, int reset) { + if (unlikely(ftrace_disabled)) + return; + mutex_lock(&ftrace_filter_lock); if (reset) ftrace_filter_reset(); @@ -1133,7 +1169,7 @@ int ftrace_force_update(void) DECLARE_WAITQUEUE(wait, current); int ret = 0; - if (!ftraced_task) + if (unlikely(ftrace_disabled)) return -ENODEV; mutex_lock(&ftraced_lock); @@ -1142,6 +1178,11 @@ int ftrace_force_update(void) set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&ftraced_waiters, &wait); + if (unlikely(!ftraced_task)) { + ret = -ENODEV; + goto out; + } + do { mutex_unlock(&ftraced_lock); wake_up_process(ftraced_task); @@ -1154,6 +1195,7 @@ int ftrace_force_update(void) set_current_state(TASK_INTERRUPTIBLE); } while (last_counter == ftraced_iteration_counter); + out: mutex_unlock(&ftraced_lock); remove_wait_queue(&ftraced_waiters, &wait); set_current_state(TASK_RUNNING); @@ -1161,6 +1203,22 @@ int ftrace_force_update(void) return ret; } +static void ftrace_force_shutdown(void) +{ + struct task_struct *task; + int command = FTRACE_DISABLE_CALLS | FTRACE_UPDATE_TRACE_FUNC; + + mutex_lock(&ftraced_lock); + task = ftraced_task; + ftraced_task = NULL; + ftraced_suspend = -1; + ftrace_run_update_code(command); + mutex_unlock(&ftraced_lock); + + if (task) + kthread_stop(task); +} + static __init int ftrace_init_debugfs(void) { struct dentry *d_tracer; @@ -1194,21 +1252,29 @@ static int __init notrace ftrace_dynamic_init(void) stop_machine_run(ftrace_dyn_arch_init, &addr, NR_CPUS); /* ftrace_dyn_arch_init places the return code in addr */ - if (addr) - return addr; + if (addr) { + ret = (int)addr; + goto failed; + } ret = ftrace_dyn_table_alloc(); if (ret) - return ret; + goto failed; p = kthread_run(ftraced, NULL, "ftraced"); - if (IS_ERR(p)) - return -1; + if (IS_ERR(p)) { + ret = -1; + goto failed; + } last_ftrace_enabled = ftrace_enabled = 1; ftraced_task = p; return 0; + + failed: + ftrace_disabled = 1; + return ret; } core_initcall(ftrace_dynamic_init); @@ -1217,9 +1283,31 @@ core_initcall(ftrace_dynamic_init); # define ftrace_shutdown() do { } while (0) # define ftrace_startup_sysctl() do { } while (0) # define ftrace_shutdown_sysctl() do { } while (0) +# define ftrace_force_shutdown() do { } while (0) #endif /* CONFIG_DYNAMIC_FTRACE */ /** + * ftrace_kill - totally shutdown ftrace + * + * This is a safety measure. If something was detected that seems + * wrong, calling this function will keep ftrace from doing + * any more modifications, and updates. + * used when something went wrong. + */ +void ftrace_kill(void) +{ + mutex_lock(&ftrace_sysctl_lock); + ftrace_disabled = 1; + ftrace_enabled = 0; + + clear_ftrace_function(); + mutex_unlock(&ftrace_sysctl_lock); + + /* Try to totally disable ftrace */ + ftrace_force_shutdown(); +} + +/** * register_ftrace_function - register a function for profiling * @ops - ops structure that holds the function for profiling. * @@ -1234,6 +1322,9 @@ int register_ftrace_function(struct ftrace_ops *ops) { int ret; + if (unlikely(ftrace_disabled)) + return -1; + mutex_lock(&ftrace_sysctl_lock); ret = __register_ftrace_function(ops); ftrace_startup(); @@ -1267,6 +1358,9 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, { int ret; + if (unlikely(ftrace_disabled)) + return -ENODEV; + mutex_lock(&ftrace_sysctl_lock); ret = proc_dointvec(table, write, file, buffer, lenp, ppos); diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index a6f1ed7..85715b8 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -248,6 +248,10 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) ftrace_enabled = save_ftrace_enabled; tracer_enabled = save_tracer_enabled; + /* kill ftrace totally if we failed */ + if (ret) + ftrace_kill(); + return ret; } #endif /* CONFIG_FTRACE */ -- cgit v0.10.2 From 26994ead1fc8cced63f17e9848edc1771036664e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace: enabled tracing by default This patch is the correct way to have tracing enabled by default. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c56fc5e..3dc6eac 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -107,7 +107,7 @@ static struct trace_array max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_data); -static int tracer_enabled; +static int tracer_enabled = 1; static unsigned long trace_nr_entries = 16384UL; static struct tracer *trace_types __read_mostly; @@ -2268,6 +2268,8 @@ __init static int tracer_alloc_buffers(void) int ret = -ENOMEM; int i; + global_trace.ctrl = tracer_enabled; + /* Allocate the first page for all buffers */ for_each_possible_cpu(i) { data = global_trace.data[i] = &per_cpu(global_trace_cpu, i); -- cgit v0.10.2 From 0fd9e0dac9026df09986a4b201518ae015814aef Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace: use cpu clock again Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3dc6eac..d74c039 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -42,61 +42,9 @@ ns2usecs(cycle_t nsec) return nsec; } -static const int time_sync_freq_max = 128; -static const cycle_t time_sync_thresh = 100000; - -static DEFINE_PER_CPU(cycle_t, time_offset); -static DEFINE_PER_CPU(cycle_t, prev_cpu_time); -static DEFINE_PER_CPU(int, time_sync_count); -static DEFINE_PER_CPU(int, time_sync_freq); - -/* - * Global lock which we take every now and then to synchronize - * the CPUs time. This method is not warp-safe, but it's good - * enough to synchronize slowly diverging time sources and thus - * it's good enough for tracing: - */ -static DEFINE_SPINLOCK(time_sync_lock); -static cycle_t prev_global_time; - -static notrace cycle_t __ftrace_now_sync(cycles_t time, int cpu) -{ - unsigned long flags; - - spin_lock_irqsave(&time_sync_lock, flags); - - /* - * Update the synchronization frequency: - */ - if (per_cpu(time_sync_freq, cpu) < time_sync_freq_max) - per_cpu(time_sync_freq, cpu) *= 2; - per_cpu(time_sync_count, cpu) = per_cpu(time_sync_freq, cpu); - - if (time < prev_global_time) { - per_cpu(time_offset, cpu) += prev_global_time - time; - time = prev_global_time; - } else { - prev_global_time = time; - } - - spin_unlock_irqrestore(&time_sync_lock, flags); - - return time; -} - notrace cycle_t ftrace_now(int cpu) { - cycle_t prev_cpu_time, time, delta_time; - - prev_cpu_time = per_cpu(prev_cpu_time, cpu); - time = sched_clock() + per_cpu(time_offset, cpu); - delta_time = time-prev_cpu_time; - - if (unlikely(delta_time > time_sync_thresh || - --per_cpu(time_sync_count, cpu) <= 0)) - time = __ftrace_now_sync(time, cpu); - - return time; + return cpu_clock(cpu); } static struct trace_array global_trace; -- cgit v0.10.2 From 2e0f57618529a2739a5e1570e6c445c9c966b595 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: build fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d74c039..71b25b7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -432,47 +432,6 @@ notrace void tracing_reset(struct trace_array_cpu *data) data->trace_tail_idx = 0; } -#ifdef CONFIG_FTRACE -static notrace void -function_trace_call(unsigned long ip, unsigned long parent_ip) -{ - struct trace_array *tr = &global_trace; - struct trace_array_cpu *data; - unsigned long flags; - long disabled; - int cpu; - - if (unlikely(!tracer_enabled)) - return; - - local_irq_save(flags); - cpu = raw_smp_processor_id(); - data = tr->data[cpu]; - disabled = atomic_inc_return(&data->disabled); - - if (likely(disabled == 1)) - ftrace(tr, data, ip, parent_ip, flags); - - atomic_dec(&data->disabled); - local_irq_restore(flags); -} - -static struct ftrace_ops trace_ops __read_mostly = -{ - .func = function_trace_call, -}; -#endif - -notrace void tracing_start_function_trace(void) -{ - register_ftrace_function(&trace_ops); -} - -notrace void tracing_stop_function_trace(void) -{ - unregister_ftrace_function(&trace_ops); -} - #define SAVED_CMDLINES 128 static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; @@ -635,8 +594,8 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) } notrace void -ftrace(struct trace_array *tr, struct trace_array_cpu *data, - unsigned long ip, unsigned long parent_ip, unsigned long flags) +__ftrace(struct trace_array *tr, struct trace_array_cpu *data, + unsigned long ip, unsigned long parent_ip, unsigned long flags) { struct trace_entry *entry; unsigned long irq_flags; @@ -651,6 +610,14 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, } notrace void +ftrace(struct trace_array *tr, struct trace_array_cpu *data, + unsigned long ip, unsigned long parent_ip, unsigned long flags) +{ + if (likely(!atomic_read(&data->disabled))) + __ftrace(tr, data, ip, parent_ip, flags); +} + +notrace void trace_special(struct trace_array *tr, struct trace_array_cpu *data, unsigned long arg1, unsigned long arg2, unsigned long arg3) { @@ -688,6 +655,47 @@ tracing_sched_switch_trace(struct trace_array *tr, spin_unlock_irqrestore(&data->lock, irq_flags); } +#ifdef CONFIG_FTRACE +static notrace void +function_trace_call(unsigned long ip, unsigned long parent_ip) +{ + struct trace_array *tr = &global_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (unlikely(!tracer_enabled)) + return; + + local_irq_save(flags); + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + __ftrace(tr, data, ip, parent_ip, flags); + + atomic_dec(&data->disabled); + local_irq_restore(flags); +} + +static struct ftrace_ops trace_ops __read_mostly = +{ + .func = function_trace_call, +}; + +notrace void tracing_start_function_trace(void) +{ + register_ftrace_function(&trace_ops); +} + +notrace void tracing_stop_function_trace(void) +{ + unregister_ftrace_function(&trace_ops); +} +#endif + enum trace_file_type { TRACE_FILE_LAT_FMT = 1, }; @@ -722,7 +730,7 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, return &array[iter->next_page_idx[cpu]]; } -static struct notrace trace_entry * +static struct trace_entry * notrace find_next_entry(struct trace_iterator *iter, int *ent_cpu) { struct trace_array *tr = iter->tr; @@ -1866,6 +1874,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, static cpumask_t mask; static int start; unsigned long flags; + int ftrace_save; int read = 0; int cpu; int len; @@ -1944,6 +1953,9 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, cpus_clear(mask); local_irq_save(flags); + ftrace_save = ftrace_enabled; + ftrace_enabled = 0; + smp_wmb(); for_each_possible_cpu(cpu) { data = iter->tr->data[cpu]; @@ -1951,10 +1963,14 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, continue; atomic_inc(&data->disabled); - spin_lock(&data->lock); cpu_set(cpu, mask); } + for_each_cpu_mask(cpu, mask) { + data = iter->tr->data[cpu]; + spin_lock(&data->lock); + } + while (find_next_entry_inc(iter) != NULL) { int len = iter->seq.len; @@ -1974,8 +1990,13 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, for_each_cpu_mask(cpu, mask) { data = iter->tr->data[cpu]; spin_unlock(&data->lock); + } + + for_each_cpu_mask(cpu, mask) { + data = iter->tr->data[cpu]; atomic_dec(&data->disabled); } + ftrace_enabled = ftrace_save; local_irq_restore(flags); /* Now copy what we have to the user */ diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index e5d34b7..69a0eb0 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -9,10 +9,10 @@ * Copyright (C) 2004-2006 Ingo Molnar * Copyright (C) 2004 William Lee Irwin III */ -#include #include #include #include +#include #include "trace.h" -- cgit v0.10.2 From 5e3ca0ec76fce92daa4eed0d02de9c79b1fe3920 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: introduce the "hex" output method Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 71b25b7..6974b21 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -103,7 +103,8 @@ enum trace_iterator_flags { TRACE_ITER_SYM_ADDR = 0x04, TRACE_ITER_VERBOSE = 0x08, TRACE_ITER_RAW = 0x10, - TRACE_ITER_BIN = 0x20, + TRACE_ITER_HEX = 0x20, + TRACE_ITER_BIN = 0x40, }; #define TRACE_ITER_SYM_MASK \ @@ -116,6 +117,7 @@ static const char *trace_options[] = { "sym-addr", "verbose", "raw", + "hex", "bin", NULL }; @@ -238,6 +240,47 @@ trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) return len; } +#define HEX_CHARS 17 + +static notrace int +trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len) +{ + unsigned char hex[HEX_CHARS]; + unsigned char *data; + unsigned char byte; + int i, j; + + BUG_ON(len >= HEX_CHARS); + + data = mem; + +#ifdef __BIG_ENDIAN + for (i = 0, j = 0; i < len; i++) { +#else + for (i = len-1, j = 0; i >= 0; i--) { +#endif + byte = data[i]; + + hex[j] = byte & 0x0f; + if (hex[j] >= 10) + hex[j] += 'a' - 10; + else + hex[j] += '0'; + j++; + + hex[j] = byte >> 4; + if (hex[j] >= 10) + hex[j] += 'a' - 10; + else + hex[j] += '0'; + j++; + } + hex[j] = ' '; + j++; + + return trace_seq_putmem(s, hex, j); +} + static notrace void trace_seq_reset(struct trace_seq *s) { @@ -1274,6 +1317,51 @@ do { \ return 0; \ } while (0) +#define SEQ_PUT_HEX_FIELD_RET(s, x) \ +do { \ + if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \ + return 0; \ +} while (0) + +static notrace int print_hex_fmt(struct trace_iterator *iter) +{ + struct trace_seq *s = &iter->seq; + unsigned char newline = '\n'; + struct trace_entry *entry; + int S; + + entry = iter->ent; + + SEQ_PUT_HEX_FIELD_RET(s, entry->pid); + SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); + SEQ_PUT_HEX_FIELD_RET(s, entry->t); + + switch (entry->type) { + case TRACE_FN: + SEQ_PUT_HEX_FIELD_RET(s, entry->fn.ip); + SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); + break; + case TRACE_CTX: + S = entry->ctx.prev_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.prev_state] : 'X'; + SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid); + SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio); + SEQ_PUT_HEX_FIELD_RET(s, S); + SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_pid); + SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_prio); + SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); + break; + case TRACE_SPECIAL: + SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg1); + SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg2); + SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg3); + break; + } + SEQ_PUT_FIELD_RET(s, newline); + + return 1; +} + static notrace int print_bin_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; @@ -1327,6 +1415,9 @@ static int print_trace_line(struct trace_iterator *iter) if (trace_flags & TRACE_ITER_BIN) return print_bin_fmt(iter); + if (trace_flags & TRACE_ITER_HEX) + return print_hex_fmt(iter); + if (trace_flags & TRACE_ITER_RAW) return print_raw_fmt(iter); -- cgit v0.10.2 From 2577046740fe6d77864128c6187c11125c2449ea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: build fix no need to backmerge, only affects ftrace-enabled kernels. (which is not the default) Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6974b21..958c4d7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1965,7 +1965,9 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, static cpumask_t mask; static int start; unsigned long flags; +#ifdef CONFIG_FTRACE int ftrace_save; +#endif int read = 0; int cpu; int len; @@ -2044,8 +2046,10 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, cpus_clear(mask); local_irq_save(flags); +#ifdef CONFIG_FTRACE ftrace_save = ftrace_enabled; ftrace_enabled = 0; +#endif smp_wmb(); for_each_possible_cpu(cpu) { data = iter->tr->data[cpu]; @@ -2087,7 +2091,9 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, data = iter->tr->data[cpu]; atomic_dec(&data->disabled); } +#ifdef CONFIG_FTRACE ftrace_enabled = ftrace_save; +#endif local_irq_restore(flags); /* Now copy what we have to the user */ -- cgit v0.10.2 From aeaee8a2c9cb4489f166ca0e39c568e8254faaa6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: build fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 4650a31..08fbef1 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -58,9 +58,6 @@ struct dyn_ftrace { int ftrace_force_update(void); void ftrace_set_filter(unsigned char *buf, int len, int reset); -/* totally disable ftrace - can not re-enable after this */ -void ftrace_kill(void); - /* defined in arch */ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); @@ -74,10 +71,13 @@ extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); #else -# define ftrace_force_update() ({ 0; }) -# define ftrace_set_filter(buf, len, reset) do { } while (0) +# define ftrace_force_update() ({ 0; }) +# define ftrace_set_filter(buf, len, reset) do { } while (0) #endif +/* totally disable ftrace - can not re-enable after this */ +void ftrace_kill(void); + static inline void tracer_disable(void) { #ifdef CONFIG_FTRACE -- cgit v0.10.2 From 2a2cc8f7c4d0dfd75720867f7dc58d24f075edfc Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Pedersen Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: allow the event pipe to be polled Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 958c4d7..d041578 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,7 @@ static struct tracer *current_trace __read_mostly; static int max_tracer_type_len; static DEFINE_MUTEX(trace_types_lock); +static DECLARE_WAIT_QUEUE_HEAD (trace_wait); #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry)) @@ -105,6 +107,7 @@ enum trace_iterator_flags { TRACE_ITER_RAW = 0x10, TRACE_ITER_HEX = 0x20, TRACE_ITER_BIN = 0x40, + TRACE_ITER_BLOCK = 0x80, }; #define TRACE_ITER_SYM_MASK \ @@ -119,6 +122,7 @@ static const char *trace_options[] = { "raw", "hex", "bin", + "block", NULL }; @@ -650,6 +654,9 @@ __ftrace(struct trace_array *tr, struct trace_array_cpu *data, entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; spin_unlock_irqrestore(&data->lock, irq_flags); + + if (!(trace_flags & TRACE_ITER_BLOCK)) + wake_up (&trace_wait); } notrace void @@ -675,6 +682,9 @@ trace_special(struct trace_array *tr, struct trace_array_cpu *data, entry->special.arg2 = arg2; entry->special.arg3 = arg3; spin_unlock_irqrestore(&data->lock, irq_flags); + + if (!(trace_flags & TRACE_ITER_BLOCK)) + wake_up (&trace_wait); } notrace void @@ -696,6 +706,9 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.next_pid = next->pid; entry->ctx.next_prio = next->prio; spin_unlock_irqrestore(&data->lock, irq_flags); + + if (!(trace_flags & TRACE_ITER_BLOCK)) + wake_up (&trace_wait); } #ifdef CONFIG_FTRACE @@ -1765,7 +1778,6 @@ static struct file_operations tracing_readme_fops = { .read = tracing_readme_read, }; - static ssize_t tracing_ctrl_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) @@ -1953,6 +1965,28 @@ static int tracing_release_pipe(struct inode *inode, struct file *file) return 0; } +static unsigned int +tracing_poll_pipe(struct file *filp, poll_table *poll_table) +{ + struct trace_iterator *iter = filp->private_data; + + if (trace_flags & TRACE_ITER_BLOCK) { + /* + * Always select as readable when in blocking mode + */ + return POLLIN | POLLRDNORM; + } + else { + if (!trace_empty(iter)) + return POLLIN | POLLRDNORM; + poll_wait(filp, &trace_wait, poll_table); + if (!trace_empty(iter)) + return POLLIN | POLLRDNORM; + + return 0; + } +} + /* * Consumer reader. */ @@ -1991,6 +2025,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, start = 0; while (trace_empty(iter)) { + if (!(trace_flags & TRACE_ITER_BLOCK)) + return -EWOULDBLOCK; /* * This is a make-shift waitqueue. The reason we don't use * an actual wait queue is because: @@ -2134,6 +2170,7 @@ static struct file_operations set_tracer_fops = { static struct file_operations tracing_pipe_fops = { .open = tracing_open_pipe, + .poll = tracing_poll_pipe, .read = tracing_read_pipe, .release = tracing_release_pipe, }; -- cgit v0.10.2 From 6fb44b717c10ecf37beaaebd312f3afa93fed714 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: add trace_function api for other tracers to use A new check was added in the ftrace function that wont trace if the CPU trace buffer is disabled. Unfortunately, other tracers used ftrace() to write to the buffer after they disabled it. The new disable check makes these calls into a nop. This patch changes the __ftrace that is called without the check into a new api for the other tracers to use, called "trace_function". The other tracers use this interface instead when the trace CPU buffer is already disabled. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d041578..9022c35 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -641,8 +641,8 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) } notrace void -__ftrace(struct trace_array *tr, struct trace_array_cpu *data, - unsigned long ip, unsigned long parent_ip, unsigned long flags) +trace_function(struct trace_array *tr, struct trace_array_cpu *data, + unsigned long ip, unsigned long parent_ip, unsigned long flags) { struct trace_entry *entry; unsigned long irq_flags; @@ -664,7 +664,7 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, unsigned long ip, unsigned long parent_ip, unsigned long flags) { if (likely(!atomic_read(&data->disabled))) - __ftrace(tr, data, ip, parent_ip, flags); + trace_function(tr, data, ip, parent_ip, flags); } notrace void @@ -730,7 +730,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip) disabled = atomic_inc_return(&data->disabled); if (likely(disabled == 1)) - __ftrace(tr, data, ip, parent_ip, flags); + trace_function(tr, data, ip, parent_ip, flags); atomic_dec(&data->disabled); local_irq_restore(flags); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 7bdfef3..faf9f67 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -169,6 +169,11 @@ void trace_special(struct trace_array *tr, unsigned long arg1, unsigned long arg2, unsigned long arg3); +void trace_function(struct trace_array *tr, + struct trace_array_cpu *data, + unsigned long ip, + unsigned long parent_ip, + unsigned long flags); void tracing_start_function_trace(void); void tracing_stop_function_trace(void); diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index d2a6e6f..3269f4f 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -95,7 +95,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) disabled = atomic_inc_return(&data->disabled); if (likely(disabled == 1)) - ftrace(tr, data, ip, parent_ip, flags); + trace_function(tr, data, ip, parent_ip, flags); atomic_dec(&data->disabled); } @@ -150,7 +150,7 @@ check_critical_timing(struct trace_array *tr, if (!report_latency(delta)) goto out_unlock; - ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); + trace_function(tr, data, CALLER_ADDR0, parent_ip, flags); latency = nsecs_to_usecs(delta); @@ -188,7 +188,7 @@ out: data->critical_sequence = max_sequence; data->preempt_timestamp = ftrace_now(cpu); tracing_reset(data); - ftrace(tr, data, CALLER_ADDR0, parent_ip, flags); + trace_function(tr, data, CALLER_ADDR0, parent_ip, flags); } static inline void notrace @@ -221,7 +221,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) local_save_flags(flags); - ftrace(tr, data, ip, parent_ip, flags); + trace_function(tr, data, ip, parent_ip, flags); __get_cpu_var(tracing_cpu) = 1; @@ -254,7 +254,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) atomic_inc(&data->disabled); local_save_flags(flags); - ftrace(tr, data, ip, parent_ip, flags); + trace_function(tr, data, ip, parent_ip, flags); check_critical_timing(tr, data, parent_ip ? : ip, cpu); data->critical_start = 0; atomic_dec(&data->disabled); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index b7df825..3549e41 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -85,7 +85,7 @@ wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) if (unlikely(!tracer_enabled || next != wakeup_task)) goto out_unlock; - ftrace(tr, data, CALLER_ADDR1, CALLER_ADDR2, flags); + trace_function(tr, data, CALLER_ADDR1, CALLER_ADDR2, flags); /* * usecs conversion is slow so we try to delay the conversion @@ -192,7 +192,8 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p, local_save_flags(flags); tr->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu); - ftrace(tr, tr->data[wakeup_cpu], CALLER_ADDR1, CALLER_ADDR2, flags); + trace_function(tr, tr->data[wakeup_cpu], + CALLER_ADDR1, CALLER_ADDR2, flags); out_locked: spin_unlock(&wakeup_lock); -- cgit v0.10.2 From 9ff9cdb2d3b0971f89e899b3420aadd91bddc215 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:50 +0200 Subject: ftrace: cleanups clean up recent code. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ff42345..425b1fe 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -197,8 +197,8 @@ static int ftrace_record_suspend; static struct dyn_ftrace *ftrace_free_records; -static inline int -notrace ftrace_ip_in_hash(unsigned long ip, unsigned long key) +static inline int notrace +ftrace_ip_in_hash(unsigned long ip, unsigned long key) { struct dyn_ftrace *p; struct hlist_node *t; @@ -1249,6 +1249,7 @@ static int __init notrace ftrace_dynamic_init(void) int ret; addr = (unsigned long)ftrace_record_ip; + stop_machine_run(ftrace_dyn_arch_init, &addr, NR_CPUS); /* ftrace_dyn_arch_init places the return code in addr */ diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 3269f4f..2ac0d09 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -309,7 +309,7 @@ void trace_softirqs_off(unsigned long ip) { } -inline void print_irqtrace_events(struct task_struct *curr) +inline notrace void print_irqtrace_events(struct task_struct *curr) { } diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 85715b8..546307d 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -3,7 +3,7 @@ #include #include -static inline int trace_valid_entry(struct trace_entry *entry) +static notrace inline int trace_valid_entry(struct trace_entry *entry) { switch (entry->type) { case TRACE_FN: -- cgit v0.10.2 From caf8cdebfb6c1cff50ea8077f1a07c2333d6d1fd Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:50 +0200 Subject: ftrace: remove address of function names PowerPC is very fragile when it comes to use of function names and function addresses. ftrace needs to either use all function addresses or function names (i.e. my_func as suppose to &my_func). This patch chooses to use the names and not the addresses, and makes ftrace consistent. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 425b1fe..57350cb 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -326,8 +326,8 @@ ftrace_record_ip(unsigned long ip) preempt_enable_notrace(); } -#define FTRACE_ADDR ((long)(&ftrace_caller)) -#define MCOUNT_ADDR ((long)(&mcount)) +#define FTRACE_ADDR ((long)(ftrace_caller)) +#define MCOUNT_ADDR ((long)(mcount)) static void notrace __ftrace_replace_code(struct dyn_ftrace *rec, -- cgit v0.10.2 From 3594136ad67a54d77bcb2547e70011754a2f91d5 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:50 +0200 Subject: ftrace: do not profile lib/string.o Most archs define the string and memory compare functions in assembly. Some do not. But these functions may be used in some archs at early boot up. Since most archs define this code in assembly and they are not usually traced, there's no need to trace them when they are not defined in assembly. This patch removes the -pg from the CFLAGS for lib/string.o. This prevents the string functions use in either vdso or early bootup from crashing the system. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/lib/Makefile b/lib/Makefile index 74b0cfb..6ca9e6e 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -8,6 +8,14 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o prio_heap.o ratelimit.o +ifdef CONFIG_FTRACE +# Do not profile string.o, since it may be used in early boot or vdso +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(if $(subst string,,$(basename $(notdir $@))), \ + $(ORIG_CFLAGS), \ + $(subst -pg,,$(ORIG_CFLAGS))) +endif + lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o -- cgit v0.10.2 From b53dde9d34f2df396540988ebc65c33400f57b04 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: ftrace: disable -pg for the tracer itself Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 3fec653..c25a6cd 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -1,3 +1,11 @@ + +# Do not instrument the tracer itself: + +ifdef CONFIG_FTRACE +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) +endif + obj-$(CONFIG_FTRACE) += libftrace.o obj-$(CONFIG_TRACING) += trace.o -- cgit v0.10.2 From e309b41dd65aa953f86765eeeecc941d8e1e8b8f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: ftrace: remove notrace now that we have a kbuild method for notrace, no need to pollute the C code with the annotations. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 57350cb..281d97a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -53,7 +53,7 @@ ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; /* mcount is defined per arch in assembly */ EXPORT_SYMBOL(mcount); -notrace void ftrace_list_func(unsigned long ip, unsigned long parent_ip) +void ftrace_list_func(unsigned long ip, unsigned long parent_ip) { struct ftrace_ops *op = ftrace_list; @@ -79,7 +79,7 @@ void clear_ftrace_function(void) ftrace_trace_function = ftrace_stub; } -static int notrace __register_ftrace_function(struct ftrace_ops *ops) +static int __register_ftrace_function(struct ftrace_ops *ops) { /* Should never be called by interrupts */ spin_lock(&ftrace_lock); @@ -110,7 +110,7 @@ static int notrace __register_ftrace_function(struct ftrace_ops *ops) return 0; } -static int notrace __unregister_ftrace_function(struct ftrace_ops *ops) +static int __unregister_ftrace_function(struct ftrace_ops *ops) { struct ftrace_ops **p; int ret = 0; @@ -197,7 +197,7 @@ static int ftrace_record_suspend; static struct dyn_ftrace *ftrace_free_records; -static inline int notrace +static inline int ftrace_ip_in_hash(unsigned long ip, unsigned long key) { struct dyn_ftrace *p; @@ -214,13 +214,13 @@ ftrace_ip_in_hash(unsigned long ip, unsigned long key) return found; } -static inline void notrace +static inline void ftrace_add_hash(struct dyn_ftrace *node, unsigned long key) { hlist_add_head(&node->node, &ftrace_hash[key]); } -static notrace void ftrace_free_rec(struct dyn_ftrace *rec) +static void ftrace_free_rec(struct dyn_ftrace *rec) { /* no locking, only called from kstop_machine */ @@ -229,7 +229,7 @@ static notrace void ftrace_free_rec(struct dyn_ftrace *rec) rec->flags |= FTRACE_FL_FREE; } -static notrace struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) +static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) { struct dyn_ftrace *rec; @@ -259,7 +259,7 @@ static notrace struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) return &ftrace_pages->records[ftrace_pages->index++]; } -static void notrace +static void ftrace_record_ip(unsigned long ip) { struct dyn_ftrace *node; @@ -329,7 +329,7 @@ ftrace_record_ip(unsigned long ip) #define FTRACE_ADDR ((long)(ftrace_caller)) #define MCOUNT_ADDR ((long)(mcount)) -static void notrace +static void __ftrace_replace_code(struct dyn_ftrace *rec, unsigned char *old, unsigned char *new, int enable) { @@ -405,7 +405,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, } } -static void notrace ftrace_replace_code(int enable) +static void ftrace_replace_code(int enable) { unsigned char *new = NULL, *old = NULL; struct dyn_ftrace *rec; @@ -430,7 +430,7 @@ static void notrace ftrace_replace_code(int enable) } } -static notrace void ftrace_shutdown_replenish(void) +static void ftrace_shutdown_replenish(void) { if (ftrace_pages->next) return; @@ -439,7 +439,7 @@ static notrace void ftrace_shutdown_replenish(void) ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); } -static notrace void +static void ftrace_code_disable(struct dyn_ftrace *rec) { unsigned long ip; @@ -458,7 +458,7 @@ ftrace_code_disable(struct dyn_ftrace *rec) } } -static int notrace __ftrace_modify_code(void *data) +static int __ftrace_modify_code(void *data) { unsigned long addr; int *command = data; @@ -482,14 +482,14 @@ static int notrace __ftrace_modify_code(void *data) return 0; } -static void notrace ftrace_run_update_code(int command) +static void ftrace_run_update_code(int command) { stop_machine_run(__ftrace_modify_code, &command, NR_CPUS); } static ftrace_func_t saved_ftrace_func; -static void notrace ftrace_startup(void) +static void ftrace_startup(void) { int command = 0; @@ -514,7 +514,7 @@ static void notrace ftrace_startup(void) mutex_unlock(&ftraced_lock); } -static void notrace ftrace_shutdown(void) +static void ftrace_shutdown(void) { int command = 0; @@ -539,7 +539,7 @@ static void notrace ftrace_shutdown(void) mutex_unlock(&ftraced_lock); } -static void notrace ftrace_startup_sysctl(void) +static void ftrace_startup_sysctl(void) { int command = FTRACE_ENABLE_MCOUNT; @@ -557,7 +557,7 @@ static void notrace ftrace_startup_sysctl(void) mutex_unlock(&ftraced_lock); } -static void notrace ftrace_shutdown_sysctl(void) +static void ftrace_shutdown_sysctl(void) { int command = FTRACE_DISABLE_MCOUNT; @@ -577,7 +577,7 @@ static cycle_t ftrace_update_time; static unsigned long ftrace_update_cnt; unsigned long ftrace_update_tot_cnt; -static int notrace __ftrace_update_code(void *ignore) +static int __ftrace_update_code(void *ignore) { struct dyn_ftrace *p; struct hlist_head head; @@ -618,7 +618,7 @@ static int notrace __ftrace_update_code(void *ignore) return 0; } -static void notrace ftrace_update_code(void) +static void ftrace_update_code(void) { if (unlikely(ftrace_disabled)) return; @@ -626,7 +626,7 @@ static void notrace ftrace_update_code(void) stop_machine_run(__ftrace_update_code, NULL, NR_CPUS); } -static int notrace ftraced(void *ignore) +static int ftraced(void *ignore) { unsigned long usecs; @@ -733,7 +733,7 @@ struct ftrace_iterator { unsigned filtered; }; -static void notrace * +static void * t_next(struct seq_file *m, void *v, loff_t *pos) { struct ftrace_iterator *iter = m->private; @@ -806,7 +806,7 @@ static struct seq_operations show_ftrace_seq_ops = { .show = t_show, }; -static int notrace +static int ftrace_avail_open(struct inode *inode, struct file *file) { struct ftrace_iterator *iter; @@ -845,7 +845,7 @@ int ftrace_avail_release(struct inode *inode, struct file *file) return 0; } -static void notrace ftrace_filter_reset(void) +static void ftrace_filter_reset(void) { struct ftrace_page *pg; struct dyn_ftrace *rec; @@ -867,7 +867,7 @@ static void notrace ftrace_filter_reset(void) preempt_enable(); } -static int notrace +static int ftrace_filter_open(struct inode *inode, struct file *file) { struct ftrace_iterator *iter; @@ -903,7 +903,7 @@ ftrace_filter_open(struct inode *inode, struct file *file) return ret; } -static ssize_t notrace +static ssize_t ftrace_filter_read(struct file *file, char __user *ubuf, size_t cnt, loff_t *ppos) { @@ -913,7 +913,7 @@ ftrace_filter_read(struct file *file, char __user *ubuf, return -EPERM; } -static loff_t notrace +static loff_t ftrace_filter_lseek(struct file *file, loff_t offset, int origin) { loff_t ret; @@ -933,7 +933,7 @@ enum { MATCH_END_ONLY, }; -static void notrace +static void ftrace_match(unsigned char *buff, int len) { char str[KSYM_SYMBOL_LEN]; @@ -1002,7 +1002,7 @@ ftrace_match(unsigned char *buff, int len) preempt_enable(); } -static ssize_t notrace +static ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) { @@ -1094,7 +1094,7 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, * Filters denote which functions should be enabled when tracing is enabled. * If @buf is NULL and reset is set, all functions will be enabled for tracing. */ -notrace void ftrace_set_filter(unsigned char *buf, int len, int reset) +void ftrace_set_filter(unsigned char *buf, int len, int reset) { if (unlikely(ftrace_disabled)) return; @@ -1107,7 +1107,7 @@ notrace void ftrace_set_filter(unsigned char *buf, int len, int reset) mutex_unlock(&ftrace_filter_lock); } -static int notrace +static int ftrace_filter_release(struct inode *inode, struct file *file) { struct seq_file *m = (struct seq_file *)file->private_data; @@ -1242,7 +1242,7 @@ static __init int ftrace_init_debugfs(void) fs_initcall(ftrace_init_debugfs); -static int __init notrace ftrace_dynamic_init(void) +static int __init ftrace_dynamic_init(void) { struct task_struct *p; unsigned long addr; @@ -1352,7 +1352,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops) return ret; } -notrace int +int ftrace_enable_sysctl(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *lenp, loff_t *ppos) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9022c35..f589805 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -35,7 +35,7 @@ unsigned long __read_mostly tracing_thresh; static int tracing_disabled = 1; -static long notrace +static long ns2usecs(cycle_t nsec) { nsec += 500; @@ -43,7 +43,7 @@ ns2usecs(cycle_t nsec) return nsec; } -notrace cycle_t ftrace_now(int cpu) +cycle_t ftrace_now(int cpu) { return cpu_clock(cpu); } @@ -135,7 +135,7 @@ static DEFINE_SPINLOCK(ftrace_max_lock); * structure. (this way the maximum trace is permanently saved, * for later retrieval via /debugfs/tracing/latency_trace) */ -static notrace void +static void __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data = tr->data[cpu]; @@ -184,7 +184,7 @@ void *head_page(struct trace_array_cpu *data) return page_address(page); } -static notrace int +static int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { int len = (PAGE_SIZE - 1) - s->len; @@ -207,7 +207,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) return len; } -static notrace int +static int trace_seq_puts(struct trace_seq *s, const char *str) { int len = strlen(str); @@ -221,7 +221,7 @@ trace_seq_puts(struct trace_seq *s, const char *str) return len; } -static notrace int +static int trace_seq_putc(struct trace_seq *s, unsigned char c) { if (s->len >= (PAGE_SIZE - 1)) @@ -232,7 +232,7 @@ trace_seq_putc(struct trace_seq *s, unsigned char c) return 1; } -static notrace int +static int trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) { if (len > ((PAGE_SIZE - 1) - s->len)) @@ -246,7 +246,7 @@ trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) #define HEX_CHARS 17 -static notrace int +static int trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len) { unsigned char hex[HEX_CHARS]; @@ -285,13 +285,13 @@ trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len) return trace_seq_putmem(s, hex, j); } -static notrace void +static void trace_seq_reset(struct trace_seq *s) { s->len = 0; } -static notrace void +static void trace_print_seq(struct seq_file *m, struct trace_seq *s) { int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; @@ -302,7 +302,7 @@ trace_print_seq(struct seq_file *m, struct trace_seq *s) trace_seq_reset(s); } -notrace static void +static void flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) { struct list_head flip_pages; @@ -323,7 +323,7 @@ flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) check_pages(tr2); } -notrace void +void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data; @@ -348,7 +348,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) * @tsk - task with the latency * @cpu - the cpu of the buffer to copy. */ -notrace void +void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data = tr->data[cpu]; @@ -471,7 +471,7 @@ void unregister_tracer(struct tracer *type) mutex_unlock(&trace_types_lock); } -notrace void tracing_reset(struct trace_array_cpu *data) +void tracing_reset(struct trace_array_cpu *data) { data->trace_idx = 0; data->trace_head = data->trace_tail = head_page(data); @@ -494,9 +494,9 @@ static void trace_init_cmdlines(void) cmdline_idx = 0; } -notrace void trace_stop_cmdline_recording(void); +void trace_stop_cmdline_recording(void); -static notrace void trace_save_cmdline(struct task_struct *tsk) +static void trace_save_cmdline(struct task_struct *tsk) { unsigned map; unsigned idx; @@ -531,7 +531,7 @@ static notrace void trace_save_cmdline(struct task_struct *tsk) spin_unlock(&trace_cmdline_lock); } -static notrace char *trace_find_cmdline(int pid) +static char *trace_find_cmdline(int pid) { char *cmdline = "<...>"; unsigned map; @@ -552,7 +552,7 @@ static notrace char *trace_find_cmdline(int pid) return cmdline; } -notrace void tracing_record_cmdline(struct task_struct *tsk) +void tracing_record_cmdline(struct task_struct *tsk) { if (atomic_read(&trace_record_cmdline_disabled)) return; @@ -560,7 +560,7 @@ notrace void tracing_record_cmdline(struct task_struct *tsk) trace_save_cmdline(tsk); } -static inline notrace struct list_head * +static inline struct list_head * trace_next_list(struct trace_array_cpu *data, struct list_head *next) { /* @@ -574,7 +574,7 @@ trace_next_list(struct trace_array_cpu *data, struct list_head *next) return next; } -static inline notrace void * +static inline void * trace_next_page(struct trace_array_cpu *data, void *addr) { struct list_head *next; @@ -588,7 +588,7 @@ trace_next_page(struct trace_array_cpu *data, void *addr) return page_address(page); } -static inline notrace struct trace_entry * +static inline struct trace_entry * tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data) { unsigned long idx, idx_next; @@ -623,7 +623,7 @@ tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data) return entry; } -static inline notrace void +static inline void tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) { struct task_struct *tsk = current; @@ -640,7 +640,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); } -notrace void +void trace_function(struct trace_array *tr, struct trace_array_cpu *data, unsigned long ip, unsigned long parent_ip, unsigned long flags) { @@ -659,7 +659,7 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, wake_up (&trace_wait); } -notrace void +void ftrace(struct trace_array *tr, struct trace_array_cpu *data, unsigned long ip, unsigned long parent_ip, unsigned long flags) { @@ -667,7 +667,7 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, trace_function(tr, data, ip, parent_ip, flags); } -notrace void +void trace_special(struct trace_array *tr, struct trace_array_cpu *data, unsigned long arg1, unsigned long arg2, unsigned long arg3) { @@ -687,7 +687,7 @@ trace_special(struct trace_array *tr, struct trace_array_cpu *data, wake_up (&trace_wait); } -notrace void +void tracing_sched_switch_trace(struct trace_array *tr, struct trace_array_cpu *data, struct task_struct *prev, struct task_struct *next, @@ -712,7 +712,7 @@ tracing_sched_switch_trace(struct trace_array *tr, } #ifdef CONFIG_FTRACE -static notrace void +static void function_trace_call(unsigned long ip, unsigned long parent_ip) { struct trace_array *tr = &global_trace; @@ -741,12 +741,12 @@ static struct ftrace_ops trace_ops __read_mostly = .func = function_trace_call, }; -notrace void tracing_start_function_trace(void) +void tracing_start_function_trace(void) { register_ftrace_function(&trace_ops); } -notrace void tracing_stop_function_trace(void) +void tracing_stop_function_trace(void) { unregister_ftrace_function(&trace_ops); } @@ -786,7 +786,7 @@ trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data, return &array[iter->next_page_idx[cpu]]; } -static struct trace_entry * notrace +static struct trace_entry * find_next_entry(struct trace_iterator *iter, int *ent_cpu) { struct trace_array *tr = iter->tr; @@ -813,7 +813,7 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) return next; } -static notrace void trace_iterator_increment(struct trace_iterator *iter) +static void trace_iterator_increment(struct trace_iterator *iter) { iter->idx++; iter->next_idx[iter->cpu]++; @@ -828,7 +828,7 @@ static notrace void trace_iterator_increment(struct trace_iterator *iter) } } -static notrace void trace_consume(struct trace_iterator *iter) +static void trace_consume(struct trace_iterator *iter) { struct trace_array_cpu *data = iter->tr->data[iter->cpu]; @@ -844,7 +844,7 @@ static notrace void trace_consume(struct trace_iterator *iter) data->trace_idx = 0; } -static notrace void *find_next_entry_inc(struct trace_iterator *iter) +static void *find_next_entry_inc(struct trace_iterator *iter) { struct trace_entry *next; int next_cpu = -1; @@ -863,7 +863,7 @@ static notrace void *find_next_entry_inc(struct trace_iterator *iter) return next ? iter : NULL; } -static notrace void *s_next(struct seq_file *m, void *v, loff_t *pos) +static void *s_next(struct seq_file *m, void *v, loff_t *pos) { struct trace_iterator *iter = m->private; void *last_ent = iter->ent; @@ -978,7 +978,7 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt, # define IP_FMT "%016lx" #endif -static notrace int +static int seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) { int ret; @@ -999,7 +999,7 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) return ret; } -static notrace void print_lat_help_header(struct seq_file *m) +static void print_lat_help_header(struct seq_file *m) { seq_puts(m, "# _------=> CPU# \n"); seq_puts(m, "# / _-----=> irqs-off \n"); @@ -1012,14 +1012,14 @@ static notrace void print_lat_help_header(struct seq_file *m) seq_puts(m, "# \\ / ||||| \\ | / \n"); } -static notrace void print_func_help_header(struct seq_file *m) +static void print_func_help_header(struct seq_file *m) { seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); seq_puts(m, "# | | | | |\n"); } -static notrace void +static void print_trace_header(struct seq_file *m, struct trace_iterator *iter) { unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); @@ -1090,7 +1090,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) seq_puts(m, "\n"); } -static notrace void +static void lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) { int hardirq, softirq; @@ -1127,7 +1127,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) unsigned long preempt_mark_thresh = 100; -static notrace void +static void lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs, unsigned long rel_usecs) { @@ -1142,7 +1142,7 @@ lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs, static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; -static notrace int +static int print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) { struct trace_seq *s = &iter->seq; @@ -1206,7 +1206,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) return 1; } -static notrace int print_trace_fmt(struct trace_iterator *iter) +static int print_trace_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); @@ -1279,7 +1279,7 @@ static notrace int print_trace_fmt(struct trace_iterator *iter) return 1; } -static notrace int print_raw_fmt(struct trace_iterator *iter) +static int print_raw_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; struct trace_entry *entry; @@ -1336,7 +1336,7 @@ do { \ return 0; \ } while (0) -static notrace int print_hex_fmt(struct trace_iterator *iter) +static int print_hex_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; unsigned char newline = '\n'; @@ -1375,7 +1375,7 @@ static notrace int print_hex_fmt(struct trace_iterator *iter) return 1; } -static notrace int print_bin_fmt(struct trace_iterator *iter) +static int print_bin_fmt(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; struct trace_entry *entry; @@ -1475,7 +1475,7 @@ static struct seq_operations tracer_seq_ops = { .show = s_show, }; -static struct trace_iterator notrace * +static struct trace_iterator * __tracing_open(struct inode *inode, struct file *file, int *ret) { struct trace_iterator *iter; @@ -1572,7 +1572,7 @@ static int tracing_lt_open(struct inode *inode, struct file *file) } -static notrace void * +static void * t_next(struct seq_file *m, void *v, loff_t *pos) { struct tracer *t = m->private; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index faf9f67..2b7352b 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -150,7 +150,7 @@ struct trace_iterator { long idx; }; -void notrace tracing_reset(struct trace_array_cpu *data); +void tracing_reset(struct trace_array_cpu *data); int tracing_open_generic(struct inode *inode, struct file *filp); struct dentry *tracing_init_dentry(void); void ftrace(struct trace_array *tr, @@ -189,10 +189,10 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu); -extern notrace cycle_t ftrace_now(int cpu); +extern cycle_t ftrace_now(int cpu); #ifdef CONFIG_SCHED_TRACER -extern void notrace +extern void wakeup_sched_switch(struct task_struct *prev, struct task_struct *next); #else static inline void diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 69a0eb0..4165d34 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -16,7 +16,7 @@ #include "trace.h" -static notrace void function_reset(struct trace_array *tr) +static void function_reset(struct trace_array *tr) { int cpu; @@ -26,30 +26,30 @@ static notrace void function_reset(struct trace_array *tr) tracing_reset(tr->data[cpu]); } -static notrace void start_function_trace(struct trace_array *tr) +static void start_function_trace(struct trace_array *tr) { function_reset(tr); tracing_start_function_trace(); } -static notrace void stop_function_trace(struct trace_array *tr) +static void stop_function_trace(struct trace_array *tr) { tracing_stop_function_trace(); } -static notrace void function_trace_init(struct trace_array *tr) +static void function_trace_init(struct trace_array *tr) { if (tr->ctrl) start_function_trace(tr); } -static notrace void function_trace_reset(struct trace_array *tr) +static void function_trace_reset(struct trace_array *tr) { if (tr->ctrl) stop_function_trace(tr); } -static notrace void function_trace_ctrl_update(struct trace_array *tr) +static void function_trace_ctrl_update(struct trace_array *tr) { if (tr->ctrl) start_function_trace(tr); diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 2ac0d09..7a4dc01 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -33,7 +33,7 @@ enum { static int trace_type __read_mostly; #ifdef CONFIG_PREEMPT_TRACER -static inline int notrace +static inline int preempt_trace(void) { return ((trace_type & TRACER_PREEMPT_OFF) && preempt_count()); @@ -43,7 +43,7 @@ preempt_trace(void) #endif #ifdef CONFIG_IRQSOFF_TRACER -static inline int notrace +static inline int irq_trace(void) { return ((trace_type & TRACER_IRQS_OFF) && @@ -67,7 +67,7 @@ static __cacheline_aligned_in_smp unsigned long max_sequence; /* * irqsoff uses its own tracer function to keep the overhead down: */ -static void notrace +static void irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) { struct trace_array *tr = irqsoff_trace; @@ -109,7 +109,7 @@ static struct ftrace_ops trace_ops __read_mostly = /* * Should this new latency be reported/recorded? */ -static int notrace report_latency(cycle_t delta) +static int report_latency(cycle_t delta) { if (tracing_thresh) { if (delta < tracing_thresh) @@ -121,7 +121,7 @@ static int notrace report_latency(cycle_t delta) return 1; } -static void notrace +static void check_critical_timing(struct trace_array *tr, struct trace_array_cpu *data, unsigned long parent_ip, @@ -191,7 +191,7 @@ out: trace_function(tr, data, CALLER_ADDR0, parent_ip, flags); } -static inline void notrace +static inline void start_critical_timing(unsigned long ip, unsigned long parent_ip) { int cpu; @@ -228,7 +228,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) atomic_dec(&data->disabled); } -static inline void notrace +static inline void stop_critical_timing(unsigned long ip, unsigned long parent_ip) { int cpu; @@ -261,13 +261,13 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) } /* start and stop critical timings used to for stoppage (in idle) */ -void notrace start_critical_timings(void) +void start_critical_timings(void) { if (preempt_trace() || irq_trace()) start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } -void notrace stop_critical_timings(void) +void stop_critical_timings(void) { if (preempt_trace() || irq_trace()) stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); @@ -275,13 +275,13 @@ void notrace stop_critical_timings(void) #ifdef CONFIG_IRQSOFF_TRACER #ifdef CONFIG_PROVE_LOCKING -void notrace time_hardirqs_on(unsigned long a0, unsigned long a1) +void time_hardirqs_on(unsigned long a0, unsigned long a1) { if (!preempt_trace() && irq_trace()) stop_critical_timing(a0, a1); } -void notrace time_hardirqs_off(unsigned long a0, unsigned long a1) +void time_hardirqs_off(unsigned long a0, unsigned long a1) { if (!preempt_trace() && irq_trace()) start_critical_timing(a0, a1); @@ -309,35 +309,35 @@ void trace_softirqs_off(unsigned long ip) { } -inline notrace void print_irqtrace_events(struct task_struct *curr) +inline void print_irqtrace_events(struct task_struct *curr) { } /* * We are only interested in hardirq on/off events: */ -void notrace trace_hardirqs_on(void) +void trace_hardirqs_on(void) { if (!preempt_trace() && irq_trace()) stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } EXPORT_SYMBOL(trace_hardirqs_on); -void notrace trace_hardirqs_off(void) +void trace_hardirqs_off(void) { if (!preempt_trace() && irq_trace()) start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } EXPORT_SYMBOL(trace_hardirqs_off); -void notrace trace_hardirqs_on_caller(unsigned long caller_addr) +void trace_hardirqs_on_caller(unsigned long caller_addr) { if (!preempt_trace() && irq_trace()) stop_critical_timing(CALLER_ADDR0, caller_addr); } EXPORT_SYMBOL(trace_hardirqs_on_caller); -void notrace trace_hardirqs_off_caller(unsigned long caller_addr) +void trace_hardirqs_off_caller(unsigned long caller_addr) { if (!preempt_trace() && irq_trace()) start_critical_timing(CALLER_ADDR0, caller_addr); @@ -348,12 +348,12 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller); #endif /* CONFIG_IRQSOFF_TRACER */ #ifdef CONFIG_PREEMPT_TRACER -void notrace trace_preempt_on(unsigned long a0, unsigned long a1) +void trace_preempt_on(unsigned long a0, unsigned long a1) { stop_critical_timing(a0, a1); } -void notrace trace_preempt_off(unsigned long a0, unsigned long a1) +void trace_preempt_off(unsigned long a0, unsigned long a1) { start_critical_timing(a0, a1); } @@ -395,14 +395,14 @@ static void irqsoff_tracer_ctrl_update(struct trace_array *tr) stop_irqsoff_tracer(tr); } -static void notrace irqsoff_tracer_open(struct trace_iterator *iter) +static void irqsoff_tracer_open(struct trace_iterator *iter) { /* stop the trace while dumping */ if (iter->tr->ctrl) stop_irqsoff_tracer(iter->tr); } -static void notrace irqsoff_tracer_close(struct trace_iterator *iter) +static void irqsoff_tracer_close(struct trace_iterator *iter) { if (iter->tr->ctrl) start_irqsoff_tracer(iter->tr); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 8d65667..b738eac 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -17,7 +17,7 @@ static struct trace_array *ctx_trace; static int __read_mostly tracer_enabled; -static void notrace +static void ctx_switch_func(struct task_struct *prev, struct task_struct *next) { struct trace_array *tr = ctx_trace; @@ -57,7 +57,7 @@ void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) wakeup_sched_switch(prev, next); } -static notrace void sched_switch_reset(struct trace_array *tr) +static void sched_switch_reset(struct trace_array *tr) { int cpu; @@ -67,18 +67,18 @@ static notrace void sched_switch_reset(struct trace_array *tr) tracing_reset(tr->data[cpu]); } -static notrace void start_sched_trace(struct trace_array *tr) +static void start_sched_trace(struct trace_array *tr) { sched_switch_reset(tr); tracer_enabled = 1; } -static notrace void stop_sched_trace(struct trace_array *tr) +static void stop_sched_trace(struct trace_array *tr) { tracer_enabled = 0; } -static notrace void sched_switch_trace_init(struct trace_array *tr) +static void sched_switch_trace_init(struct trace_array *tr) { ctx_trace = tr; @@ -86,7 +86,7 @@ static notrace void sched_switch_trace_init(struct trace_array *tr) start_sched_trace(tr); } -static notrace void sched_switch_trace_reset(struct trace_array *tr) +static void sched_switch_trace_reset(struct trace_array *tr) { if (tr->ctrl) stop_sched_trace(tr); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 3549e41..662679c 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -27,12 +27,12 @@ static unsigned wakeup_prio = -1; static DEFINE_SPINLOCK(wakeup_lock); -static void notrace __wakeup_reset(struct trace_array *tr); +static void __wakeup_reset(struct trace_array *tr); /* * Should this new latency be reported/recorded? */ -static int notrace report_latency(cycle_t delta) +static int report_latency(cycle_t delta) { if (tracing_thresh) { if (delta < tracing_thresh) @@ -44,7 +44,7 @@ static int notrace report_latency(cycle_t delta) return 1; } -void notrace +void wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) { unsigned long latency = 0, t0 = 0, t1 = 0; @@ -126,7 +126,7 @@ out: atomic_dec(&tr->data[cpu]->disabled); } -static void notrace __wakeup_reset(struct trace_array *tr) +static void __wakeup_reset(struct trace_array *tr) { struct trace_array_cpu *data; int cpu; @@ -147,7 +147,7 @@ static void notrace __wakeup_reset(struct trace_array *tr) wakeup_task = NULL; } -static void notrace wakeup_reset(struct trace_array *tr) +static void wakeup_reset(struct trace_array *tr) { unsigned long flags; @@ -156,7 +156,7 @@ static void notrace wakeup_reset(struct trace_array *tr) spin_unlock_irqrestore(&wakeup_lock, flags); } -static notrace void +static void wakeup_check_start(struct trace_array *tr, struct task_struct *p, struct task_struct *curr) { @@ -201,7 +201,7 @@ out: atomic_dec(&tr->data[cpu]->disabled); } -notrace void +void ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) { if (likely(!tracer_enabled)) @@ -210,7 +210,7 @@ ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) wakeup_check_start(wakeup_trace, wakee, curr); } -notrace void +void ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr) { if (likely(!tracer_enabled)) @@ -219,7 +219,7 @@ ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr) wakeup_check_start(wakeup_trace, wakee, curr); } -static notrace void start_wakeup_tracer(struct trace_array *tr) +static void start_wakeup_tracer(struct trace_array *tr) { wakeup_reset(tr); @@ -237,12 +237,12 @@ static notrace void start_wakeup_tracer(struct trace_array *tr) return; } -static notrace void stop_wakeup_tracer(struct trace_array *tr) +static void stop_wakeup_tracer(struct trace_array *tr) { tracer_enabled = 0; } -static notrace void wakeup_tracer_init(struct trace_array *tr) +static void wakeup_tracer_init(struct trace_array *tr) { wakeup_trace = tr; @@ -250,7 +250,7 @@ static notrace void wakeup_tracer_init(struct trace_array *tr) start_wakeup_tracer(tr); } -static notrace void wakeup_tracer_reset(struct trace_array *tr) +static void wakeup_tracer_reset(struct trace_array *tr) { if (tr->ctrl) { stop_wakeup_tracer(tr); @@ -267,14 +267,14 @@ static void wakeup_tracer_ctrl_update(struct trace_array *tr) stop_wakeup_tracer(tr); } -static void notrace wakeup_tracer_open(struct trace_iterator *iter) +static void wakeup_tracer_open(struct trace_iterator *iter) { /* stop the trace while dumping */ if (iter->tr->ctrl) stop_wakeup_tracer(iter->tr); } -static void notrace wakeup_tracer_close(struct trace_iterator *iter) +static void wakeup_tracer_close(struct trace_iterator *iter) { /* forget about any processes we were recording */ if (iter->tr->ctrl) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 546307d..85715b8 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -3,7 +3,7 @@ #include #include -static notrace inline int trace_valid_entry(struct trace_entry *entry) +static inline int trace_valid_entry(struct trace_entry *entry) { switch (entry->type) { case TRACE_FN: -- cgit v0.10.2 From 57422797dc009fc83766bcf230d29dbe6e08e21e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: ftrace: add wakeup events to sched tracer Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f589805..192c135 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -57,7 +57,7 @@ static struct trace_array max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_data); static int tracer_enabled = 1; -static unsigned long trace_nr_entries = 16384UL; +static unsigned long trace_nr_entries = 65536UL; static struct tracer *trace_types __read_mostly; static struct tracer *current_trace __read_mostly; @@ -87,6 +87,7 @@ enum trace_type { TRACE_FN, TRACE_CTX, + TRACE_WAKE, TRACE_SPECIAL, __TRACE_LAST_TYPE @@ -711,6 +712,30 @@ tracing_sched_switch_trace(struct trace_array *tr, wake_up (&trace_wait); } +void +tracing_sched_wakeup_trace(struct trace_array *tr, + struct trace_array_cpu *data, + struct task_struct *wakee, struct task_struct *curr, + unsigned long flags) +{ + struct trace_entry *entry; + unsigned long irq_flags; + + spin_lock_irqsave(&data->lock, irq_flags); + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, flags); + entry->type = TRACE_WAKE; + entry->ctx.prev_pid = curr->pid; + entry->ctx.prev_prio = curr->prio; + entry->ctx.prev_state = curr->state; + entry->ctx.next_pid = wakee->pid; + entry->ctx.next_prio = wakee->prio; + spin_unlock_irqrestore(&data->lock, irq_flags); + + if (!(trace_flags & TRACE_ITER_BLOCK)) + wake_up(&trace_wait); +} + #ifdef CONFIG_FTRACE static void function_trace_call(unsigned long ip, unsigned long parent_ip) @@ -1183,13 +1208,14 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) trace_seq_puts(s, ")\n"); break; case TRACE_CTX: + case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; comm = trace_find_cmdline(entry->ctx.next_pid); - trace_seq_printf(s, " %d:%d:%c --> %d:%d %s\n", + trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d %s\n", entry->ctx.prev_pid, entry->ctx.prev_prio, - S, + S, entry->type == TRACE_CTX ? "==>" : " +", entry->ctx.next_pid, entry->ctx.next_prio, comm); @@ -1256,12 +1282,14 @@ static int print_trace_fmt(struct trace_iterator *iter) return 0; break; case TRACE_CTX: + case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; - ret = trace_seq_printf(s, " %d:%d:%c ==> %d:%d\n", + ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d\n", entry->ctx.prev_pid, entry->ctx.prev_prio, S, + entry->type == TRACE_CTX ? "==>" : " +", entry->ctx.next_pid, entry->ctx.next_prio); if (!ret) @@ -1301,8 +1329,11 @@ static int print_raw_fmt(struct trace_iterator *iter) return 0; break; case TRACE_CTX: + case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; + if (entry->type == TRACE_WAKE) + S = '+'; ret = trace_seq_printf(s, "%d %d %c %d %d\n", entry->ctx.prev_pid, entry->ctx.prev_prio, @@ -1355,8 +1386,11 @@ static int print_hex_fmt(struct trace_iterator *iter) SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); break; case TRACE_CTX: + case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; + if (entry->type == TRACE_WAKE) + S = '+'; SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid); SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio); SEQ_PUT_HEX_FIELD_RET(s, S); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 2b7352b..90e0ba0 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -164,6 +164,12 @@ void tracing_sched_switch_trace(struct trace_array *tr, struct task_struct *next, unsigned long flags); void tracing_record_cmdline(struct task_struct *tsk); + +void tracing_sched_wakeup_trace(struct trace_array *tr, + struct trace_array_cpu *data, + struct task_struct *wakee, + struct task_struct *cur, + unsigned long flags); void trace_special(struct trace_array *tr, struct trace_array_cpu *data, unsigned long arg1, @@ -194,11 +200,17 @@ extern cycle_t ftrace_now(int cpu); #ifdef CONFIG_SCHED_TRACER extern void wakeup_sched_switch(struct task_struct *prev, struct task_struct *next); +extern void +wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr); #else static inline void wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) { } +static inline void +wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) +{ +} #endif #ifdef CONFIG_CONTEXT_SWITCH_TRACER diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index b738eac..8b1cf1a 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -41,6 +41,29 @@ ctx_switch_func(struct task_struct *prev, struct task_struct *next) local_irq_restore(flags); } +static void wakeup_func(struct task_struct *wakee, struct task_struct *curr) +{ + struct trace_array *tr = ctx_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (!tracer_enabled) + return; + + local_irq_save(flags); + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + tracing_sched_wakeup_trace(tr, data, wakee, curr, flags); + + atomic_dec(&data->disabled); + local_irq_restore(flags); +} + void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) { tracing_record_cmdline(prev); @@ -57,6 +80,19 @@ void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) wakeup_sched_switch(prev, next); } +void +ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) +{ + tracing_record_cmdline(curr); + + wakeup_func(wakee, curr); + + /* + * Chain to the wakeup tracer (this is a NOP if disabled): + */ + wakeup_sched_wakeup(wakee, curr); +} + static void sched_switch_reset(struct trace_array *tr) { int cpu; diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 662679c..87fa7b2 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -202,7 +202,7 @@ out: } void -ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) +wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) { if (likely(!tracer_enabled)) return; diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 85715b8..39dd452 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -8,6 +8,7 @@ static inline int trace_valid_entry(struct trace_entry *entry) switch (entry->type) { case TRACE_FN: case TRACE_CTX: + case TRACE_WAKE: return 1; } return 0; -- cgit v0.10.2 From 86387f7ee5d3273ff4859e2c64ce656639b6ca65 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: ftrace: add stack tracing Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 08fbef1..0d3714e 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -93,6 +93,7 @@ static inline void tracer_disable(void) # define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3)) # define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4)) # define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5)) +# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6)) #else # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) # define CALLER_ADDR1 0UL @@ -100,6 +101,7 @@ static inline void tracer_disable(void) # define CALLER_ADDR3 0UL # define CALLER_ADDR4 0UL # define CALLER_ADDR5 0UL +# define CALLER_ADDR6 0UL #endif #ifdef CONFIG_IRQSOFF_TRACER diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 3f73a17..eb1988e 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -10,6 +10,7 @@ config TRACER_MAX_TRACE config TRACING bool select DEBUG_FS + select STACKTRACE config FTRACE bool "Kernel Function Tracer" diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 192c135..b4b1b4f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -28,6 +28,8 @@ #include #include +#include + #include "trace.h" unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; @@ -88,6 +90,7 @@ enum trace_type { TRACE_FN, TRACE_CTX, TRACE_WAKE, + TRACE_STACK, TRACE_SPECIAL, __TRACE_LAST_TYPE @@ -109,6 +112,7 @@ enum trace_iterator_flags { TRACE_ITER_HEX = 0x20, TRACE_ITER_BIN = 0x40, TRACE_ITER_BLOCK = 0x80, + TRACE_ITER_STACKTRACE = 0x100, }; #define TRACE_ITER_SYM_MASK \ @@ -124,10 +128,11 @@ static const char *trace_options[] = { "hex", "bin", "block", + "stacktrace", NULL }; -static unsigned trace_flags; +static unsigned trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_STACKTRACE; static DEFINE_SPINLOCK(ftrace_max_lock); @@ -657,7 +662,7 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, spin_unlock_irqrestore(&data->lock, irq_flags); if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up (&trace_wait); + wake_up(&trace_wait); } void @@ -685,13 +690,39 @@ trace_special(struct trace_array *tr, struct trace_array_cpu *data, spin_unlock_irqrestore(&data->lock, irq_flags); if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up (&trace_wait); + wake_up(&trace_wait); +} + +void __trace_stack(struct trace_array *tr, + struct trace_array_cpu *data, + unsigned long flags, + int skip) +{ + struct trace_entry *entry; + struct stack_trace trace; + + if (!(trace_flags & TRACE_ITER_STACKTRACE)) + return; + + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, flags); + entry->type = TRACE_STACK; + + memset(&entry->stack, 0, sizeof(entry->stack)); + + trace.nr_entries = 0; + trace.max_entries = FTRACE_STACK_ENTRIES; + trace.skip = skip; + trace.entries = entry->stack.caller; + + save_stack_trace(&trace); } void tracing_sched_switch_trace(struct trace_array *tr, struct trace_array_cpu *data, - struct task_struct *prev, struct task_struct *next, + struct task_struct *prev, + struct task_struct *next, unsigned long flags) { struct trace_entry *entry; @@ -706,16 +737,18 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.prev_state = prev->state; entry->ctx.next_pid = next->pid; entry->ctx.next_prio = next->prio; + __trace_stack(tr, data, flags, 4); spin_unlock_irqrestore(&data->lock, irq_flags); if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up (&trace_wait); + wake_up(&trace_wait); } void tracing_sched_wakeup_trace(struct trace_array *tr, struct trace_array_cpu *data, - struct task_struct *wakee, struct task_struct *curr, + struct task_struct *wakee, + struct task_struct *curr, unsigned long flags) { struct trace_entry *entry; @@ -730,6 +763,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->ctx.prev_state = curr->state; entry->ctx.next_pid = wakee->pid; entry->ctx.next_prio = wakee->prio; + __trace_stack(tr, data, flags, 5); spin_unlock_irqrestore(&data->lock, irq_flags); if (!(trace_flags & TRACE_ITER_BLOCK)) @@ -1179,6 +1213,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) unsigned long rel_usecs; char *comm; int S; + int i; if (!next_entry) next_entry = entry; @@ -1197,8 +1232,10 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) abs_usecs % 1000, rel_usecs/1000, rel_usecs % 1000); } else { - lat_print_generic(s, entry, cpu); - lat_print_timestamp(s, abs_usecs, rel_usecs); + if (entry->type != TRACE_STACK) { + lat_print_generic(s, entry, cpu); + lat_print_timestamp(s, abs_usecs, rel_usecs); + } } switch (entry->type) { case TRACE_FN: @@ -1226,6 +1263,14 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) entry->special.arg2, entry->special.arg3); break; + case TRACE_STACK: + for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { + if (i) + trace_seq_puts(s, " <= "); + seq_print_ip_sym(s, entry->stack.caller[i], sym_flags); + } + trace_seq_puts(s, "\n"); + break; default: trace_seq_printf(s, "Unknown type %d\n", entry->type); } @@ -1241,8 +1286,9 @@ static int print_trace_fmt(struct trace_iterator *iter) unsigned long long t; unsigned long secs; char *comm; - int S; int ret; + int S; + int i; entry = iter->ent; @@ -1252,15 +1298,17 @@ static int print_trace_fmt(struct trace_iterator *iter) usec_rem = do_div(t, 1000000ULL); secs = (unsigned long)t; - ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); - if (!ret) - return 0; - ret = trace_seq_printf(s, "[%02d] ", iter->cpu); - if (!ret) - return 0; - ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); - if (!ret) - return 0; + if (entry->type != TRACE_STACK) { + ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); + if (!ret) + return 0; + ret = trace_seq_printf(s, "[%02d] ", iter->cpu); + if (!ret) + return 0; + ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + if (!ret) + return 0; + } switch (entry->type) { case TRACE_FN: @@ -1303,6 +1351,22 @@ static int print_trace_fmt(struct trace_iterator *iter) if (!ret) return 0; break; + case TRACE_STACK: + for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { + if (i) { + ret = trace_seq_puts(s, " <= "); + if (!ret) + return 0; + } + ret = seq_print_ip_sym(s, entry->stack.caller[i], + sym_flags); + if (!ret) + return 0; + } + ret = trace_seq_puts(s, "\n"); + if (!ret) + return 0; + break; } return 1; } @@ -1344,6 +1408,7 @@ static int print_raw_fmt(struct trace_iterator *iter) return 0; break; case TRACE_SPECIAL: + case TRACE_STACK: ret = trace_seq_printf(s, " %lx %lx %lx\n", entry->special.arg1, entry->special.arg2, @@ -1399,6 +1464,7 @@ static int print_hex_fmt(struct trace_iterator *iter) SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); break; case TRACE_SPECIAL: + case TRACE_STACK: SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg1); SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg2); SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg3); @@ -1433,6 +1499,7 @@ static int print_bin_fmt(struct trace_iterator *iter) SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio); break; case TRACE_SPECIAL: + case TRACE_STACK: SEQ_PUT_FIELD_RET(s, entry->special.arg1); SEQ_PUT_FIELD_RET(s, entry->special.arg2); SEQ_PUT_FIELD_RET(s, entry->special.arg3); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 90e0ba0..387bdcf 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -35,6 +35,16 @@ struct special_entry { }; /* + * Stack-trace entry: + */ + +#define FTRACE_STACK_ENTRIES 5 + +struct stack_entry { + unsigned long caller[FTRACE_STACK_ENTRIES]; +}; + +/* * The trace entry - the most basic unit of tracing. This is what * is printed in the end as a single line in the trace output, such as: * @@ -51,6 +61,7 @@ struct trace_entry { struct ftrace_entry fn; struct ctx_switch_entry ctx; struct special_entry special; + struct stack_entry stack; }; }; -- cgit v0.10.2 From 8ac0fca4ccb355ce50471d7aa3f10f5900b28b95 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: ftrace: sched tracer fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 6e26f1f..05744f9 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2130,17 +2130,11 @@ ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) #ifdef CONFIG_SCHED_TRACER extern void ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr); -extern void -ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr); #else static inline void ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) { } -static inline void -ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr) -{ -} #endif extern long sched_setaffinity(pid_t pid, const cpumask_t *new_mask); diff --git a/kernel/sched.c b/kernel/sched.c index 328494e..53ab117 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2613,7 +2613,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) p->sched_class->task_new(rq, p); inc_nr_running(rq); } - ftrace_wake_up_new_task(p, rq->curr); + ftrace_wake_up_task(p, rq->curr); check_preempt_curr(rq, p); #ifdef CONFIG_SMP if (p->sched_class->task_wake_up) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 87fa7b2..2a01242 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -201,20 +201,13 @@ out: atomic_dec(&tr->data[cpu]->disabled); } -void -wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) +void wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) { if (likely(!tracer_enabled)) return; - wakeup_check_start(wakeup_trace, wakee, curr); -} - -void -ftrace_wake_up_new_task(struct task_struct *wakee, struct task_struct *curr) -{ - if (likely(!tracer_enabled)) - return; + tracing_record_cmdline(curr); + tracing_record_cmdline(wakee); wakeup_check_start(wakeup_trace, wakee, curr); } -- cgit v0.10.2 From 4c1f4d4f0175129934d5dbc19a39296430937a05 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:51 +0200 Subject: ftrace: make nostacktrace the default Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b4b1b4f..0e4b711 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -132,7 +132,7 @@ static const char *trace_options[] = { NULL }; -static unsigned trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_STACKTRACE; +static unsigned trace_flags = TRACE_ITER_PRINT_PARENT; static DEFINE_SPINLOCK(ftrace_max_lock); -- cgit v0.10.2 From 4e65551905fb0300ae7e667cbaa41ee2e3f29a13 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: sched tracer, trace full rbtree Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 05744f9..652d380 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2119,20 +2119,34 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) #ifdef CONFIG_CONTEXT_SWITCH_TRACER extern void -ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next); +ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next); +extern void +ftrace_wake_up_task(void *rq, struct task_struct *wakee, + struct task_struct *curr); +extern void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data); +extern void +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3); #else static inline void -ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) +ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next) +{ +} +static inline void +sched_trace_special(unsigned long p1, unsigned long p2, unsigned long p3) +{ +} +static inline void +ftrace_wake_up_task(void *rq, struct task_struct *wakee, + struct task_struct *curr) +{ +} +static inline void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) { } -#endif - -#ifdef CONFIG_SCHED_TRACER -extern void -ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr); -#else static inline void -ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3) { } #endif diff --git a/kernel/sched.c b/kernel/sched.c index 53ab117..b9208a0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2394,6 +2394,35 @@ static int sched_balance_self(int cpu, int flag) #endif /* CONFIG_SMP */ +#ifdef CONFIG_CONTEXT_SWITCH_TRACER + +void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) +{ + struct sched_entity *se; + struct task_struct *p; + struct rb_node *curr; + struct rq *rq = __rq; + + curr = first_fair(&rq->cfs); + if (!curr) + return; + + while (curr) { + se = rb_entry(curr, struct sched_entity, run_node); + if (!entity_is_task(se)) + continue; + + p = task_of(se); + + __trace_special(__tr, __data, + p->pid, p->se.vruntime, p->se.sum_exec_runtime); + + curr = rb_next(curr); + } +} + +#endif + /*** * try_to_wake_up - wake up a thread * @p: the to-be-woken-up thread @@ -2468,7 +2497,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) out_activate: #endif /* CONFIG_SMP */ - ftrace_wake_up_task(p, rq->curr); + ftrace_wake_up_task(rq, p, rq->curr); schedstat_inc(p, se.nr_wakeups); if (sync) schedstat_inc(p, se.nr_wakeups_sync); @@ -2613,7 +2642,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) p->sched_class->task_new(rq, p); inc_nr_running(rq); } - ftrace_wake_up_task(p, rq->curr); + ftrace_wake_up_task(rq, p, rq->curr); check_preempt_curr(rq, p); #ifdef CONFIG_SMP if (p->sched_class->task_wake_up) @@ -2786,7 +2815,7 @@ context_switch(struct rq *rq, struct task_struct *prev, struct mm_struct *mm, *oldmm; prepare_task_switch(rq, prev, next); - ftrace_ctx_switch(prev, next); + ftrace_ctx_switch(rq, prev, next); mm = next->mm; oldmm = prev->active_mm; /* diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0e4b711..65173b1 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -66,7 +66,18 @@ static struct tracer *current_trace __read_mostly; static int max_tracer_type_len; static DEFINE_MUTEX(trace_types_lock); -static DECLARE_WAIT_QUEUE_HEAD (trace_wait); +static DECLARE_WAIT_QUEUE_HEAD(trace_wait); + +unsigned long trace_flags = TRACE_ITER_PRINT_PARENT; + +/* + * FIXME: where should this be called? + */ +void trace_wake_up(void) +{ + if (!(trace_flags & TRACE_ITER_BLOCK)) + wake_up(&trace_wait); +} #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry)) @@ -103,18 +114,6 @@ enum trace_flag_type { TRACE_FLAG_SOFTIRQ = 0x08, }; -enum trace_iterator_flags { - TRACE_ITER_PRINT_PARENT = 0x01, - TRACE_ITER_SYM_OFFSET = 0x02, - TRACE_ITER_SYM_ADDR = 0x04, - TRACE_ITER_VERBOSE = 0x08, - TRACE_ITER_RAW = 0x10, - TRACE_ITER_HEX = 0x20, - TRACE_ITER_BIN = 0x40, - TRACE_ITER_BLOCK = 0x80, - TRACE_ITER_STACKTRACE = 0x100, -}; - #define TRACE_ITER_SYM_MASK \ (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) @@ -132,8 +131,6 @@ static const char *trace_options[] = { NULL }; -static unsigned trace_flags = TRACE_ITER_PRINT_PARENT; - static DEFINE_SPINLOCK(ftrace_max_lock); /* @@ -660,9 +657,6 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; spin_unlock_irqrestore(&data->lock, irq_flags); - - if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up(&trace_wait); } void @@ -673,10 +667,14 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, trace_function(tr, data, ip, parent_ip, flags); } +#ifdef CONFIG_CONTEXT_SWITCH_TRACER + void -trace_special(struct trace_array *tr, struct trace_array_cpu *data, - unsigned long arg1, unsigned long arg2, unsigned long arg3) +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3) { + struct trace_array_cpu *data = __data; + struct trace_array *tr = __tr; struct trace_entry *entry; unsigned long irq_flags; @@ -688,11 +686,10 @@ trace_special(struct trace_array *tr, struct trace_array_cpu *data, entry->special.arg2 = arg2; entry->special.arg3 = arg3; spin_unlock_irqrestore(&data->lock, irq_flags); - - if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up(&trace_wait); } +#endif + void __trace_stack(struct trace_array *tr, struct trace_array_cpu *data, unsigned long flags, @@ -739,9 +736,6 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.next_prio = next->prio; __trace_stack(tr, data, flags, 4); spin_unlock_irqrestore(&data->lock, irq_flags); - - if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up(&trace_wait); } void @@ -765,9 +759,6 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->ctx.next_prio = wakee->prio; __trace_stack(tr, data, flags, 5); spin_unlock_irqrestore(&data->lock, irq_flags); - - if (!(trace_flags & TRACE_ITER_BLOCK)) - wake_up(&trace_wait); } #ifdef CONFIG_FTRACE @@ -1258,7 +1249,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) comm); break; case TRACE_SPECIAL: - trace_seq_printf(s, " %lx %lx %lx\n", + trace_seq_printf(s, " %ld %ld %ld\n", entry->special.arg1, entry->special.arg2, entry->special.arg3); @@ -1344,7 +1335,7 @@ static int print_trace_fmt(struct trace_iterator *iter) return 0; break; case TRACE_SPECIAL: - ret = trace_seq_printf(s, " %lx %lx %lx\n", + ret = trace_seq_printf(s, " %ld %ld %ld\n", entry->special.arg1, entry->special.arg2, entry->special.arg3); @@ -1409,7 +1400,7 @@ static int print_raw_fmt(struct trace_iterator *iter) break; case TRACE_SPECIAL: case TRACE_STACK: - ret = trace_seq_printf(s, " %lx %lx %lx\n", + ret = trace_seq_printf(s, " %ld %ld %ld\n", entry->special.arg1, entry->special.arg2, entry->special.arg3); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 387bdcf..75e2374 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -274,4 +274,18 @@ extern int trace_selftest_startup_sched_switch(struct tracer *trace, extern void *head_page(struct trace_array_cpu *data); +extern unsigned long trace_flags; + +enum trace_iterator_flags { + TRACE_ITER_PRINT_PARENT = 0x01, + TRACE_ITER_SYM_OFFSET = 0x02, + TRACE_ITER_SYM_ADDR = 0x04, + TRACE_ITER_VERBOSE = 0x08, + TRACE_ITER_RAW = 0x10, + TRACE_ITER_HEX = 0x20, + TRACE_ITER_BIN = 0x40, + TRACE_ITER_BLOCK = 0x80, + TRACE_ITER_STACKTRACE = 0x100, +}; + #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 8b1cf1a..12658b3 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -18,7 +18,7 @@ static struct trace_array *ctx_trace; static int __read_mostly tracer_enabled; static void -ctx_switch_func(struct task_struct *prev, struct task_struct *next) +ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) { struct trace_array *tr = ctx_trace; struct trace_array_cpu *data; @@ -34,14 +34,17 @@ ctx_switch_func(struct task_struct *prev, struct task_struct *next) data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); - if (likely(disabled == 1)) + if (likely(disabled == 1)) { tracing_sched_switch_trace(tr, data, prev, next, flags); + ftrace_all_fair_tasks(__rq, tr, data); + } atomic_dec(&data->disabled); local_irq_restore(flags); } -static void wakeup_func(struct task_struct *wakee, struct task_struct *curr) +static void +wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) { struct trace_array *tr = ctx_trace; struct trace_array_cpu *data; @@ -57,14 +60,18 @@ static void wakeup_func(struct task_struct *wakee, struct task_struct *curr) data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); - if (likely(disabled == 1)) + if (likely(disabled == 1)) { tracing_sched_wakeup_trace(tr, data, wakee, curr, flags); + ftrace_all_fair_tasks(__rq, tr, data); + } atomic_dec(&data->disabled); local_irq_restore(flags); } -void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) +void +ftrace_ctx_switch(void *__rq, struct task_struct *prev, + struct task_struct *next) { tracing_record_cmdline(prev); @@ -72,7 +79,7 @@ void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) * If tracer_switch_func only points to the local * switch func, it still needs the ptr passed to it. */ - ctx_switch_func(prev, next); + ctx_switch_func(__rq, prev, next); /* * Chain to the wakeup tracer (this is a NOP if disabled): @@ -81,11 +88,12 @@ void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) } void -ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) +ftrace_wake_up_task(void *__rq, struct task_struct *wakee, + struct task_struct *curr) { tracing_record_cmdline(curr); - wakeup_func(wakee, curr); + wakeup_func(__rq, wakee, curr); /* * Chain to the wakeup tracer (this is a NOP if disabled): -- cgit v0.10.2 From 24cd5d111e8c713e62cda7ca1d01232402e3d3c9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: trace curr/next tasks Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/sched.c b/kernel/sched.c index b9208a0..673b588 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2398,8 +2398,8 @@ static int sched_balance_self(int cpu, int flag) void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) { - struct sched_entity *se; struct task_struct *p; + struct sched_entity *se; struct rb_node *curr; struct rq *rq = __rq; @@ -2407,6 +2407,17 @@ void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) if (!curr) return; + if (rq->cfs.curr) { + p = task_of(rq->cfs.curr); + __trace_special(__tr, __data, + p->pid, p->se.vruntime, p->se.sum_exec_runtime); + } + if (rq->cfs.next) { + p = task_of(rq->cfs.next); + __trace_special(__tr, __data, + p->pid, p->se.vruntime, p->se.sum_exec_runtime); + } + while (curr) { se = rb_entry(curr, struct sched_entity, run_node); if (!entity_is_task(se)) -- cgit v0.10.2 From 017730c11241e26577673eb9d957cfc66172ea91 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: fix wakeups Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 652d380..a3970b5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -246,6 +246,8 @@ extern asmlinkage void schedule_tail(struct task_struct *prev); extern void init_idle(struct task_struct *idle, int cpu); extern void init_idle_bootup_task(struct task_struct *idle); +extern int runqueue_is_locked(void); + extern cpumask_t nohz_cpu_mask; #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) extern int select_nohz_load_balancer(int cpu); diff --git a/kernel/sched.c b/kernel/sched.c index 673b588..9ca4a2e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -642,6 +642,24 @@ static inline void update_rq_clock(struct rq *rq) # define const_debug static const #endif +/** + * runqueue_is_locked + * + * Returns true if the current cpu runqueue is locked. + * This interface allows printk to be called with the runqueue lock + * held and know whether or not it is OK to wake up the klogd. + */ +int runqueue_is_locked(void) +{ + int cpu = get_cpu(); + struct rq *rq = cpu_rq(cpu); + int ret; + + ret = spin_is_locked(&rq->lock); + put_cpu(); + return ret; +} + /* * Debugging: various feature bits */ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 65173b1..2ca9d66 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -70,12 +70,13 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); unsigned long trace_flags = TRACE_ITER_PRINT_PARENT; -/* - * FIXME: where should this be called? - */ void trace_wake_up(void) { - if (!(trace_flags & TRACE_ITER_BLOCK)) + /* + * The runqueue_is_locked() can fail, but this is the best we + * have for now: + */ + if (!(trace_flags & TRACE_ITER_BLOCK) && !runqueue_is_locked()) wake_up(&trace_wait); } @@ -657,6 +658,8 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; spin_unlock_irqrestore(&data->lock, irq_flags); + + trace_wake_up(); } void @@ -686,6 +689,8 @@ __trace_special(void *__tr, void *__data, entry->special.arg2 = arg2; entry->special.arg3 = arg3; spin_unlock_irqrestore(&data->lock, irq_flags); + + trace_wake_up(); } #endif @@ -759,6 +764,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->ctx.next_prio = wakee->prio; __trace_stack(tr, data, flags, 5); spin_unlock_irqrestore(&data->lock, irq_flags); + + trace_wake_up(); } #ifdef CONFIG_FTRACE -- cgit v0.10.2 From 1a3c3034336320554a3342572dae98d69e054fc7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: fix __trace_special() Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index a3970b5..5b186be 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2119,6 +2119,18 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) } #endif +#ifdef CONFIG_TRACING +extern void +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3); +#else +static inline void +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ +} +#endif + #ifdef CONFIG_CONTEXT_SWITCH_TRACER extern void ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next); @@ -2126,9 +2138,6 @@ extern void ftrace_wake_up_task(void *rq, struct task_struct *wakee, struct task_struct *curr); extern void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data); -extern void -__trace_special(void *__tr, void *__data, - unsigned long arg1, unsigned long arg2, unsigned long arg3); #else static inline void ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next) @@ -2146,11 +2155,6 @@ ftrace_wake_up_task(void *rq, struct task_struct *wakee, static inline void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) { } -static inline void -__trace_special(void *__tr, void *__data, - unsigned long arg1, unsigned long arg2, unsigned long arg3) -{ -} #endif extern long sched_setaffinity(pid_t pid, const cpumask_t *new_mask); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2ca9d66..65d2c0a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -670,8 +670,6 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, trace_function(tr, data, ip, parent_ip, flags); } -#ifdef CONFIG_CONTEXT_SWITCH_TRACER - void __trace_special(void *__tr, void *__data, unsigned long arg1, unsigned long arg2, unsigned long arg3) @@ -693,8 +691,6 @@ __trace_special(void *__tr, void *__data, trace_wake_up(); } -#endif - void __trace_stack(struct trace_array *tr, struct trace_array_cpu *data, unsigned long flags, -- cgit v0.10.2 From 4ac3ba41d372e3a9e420b36bc43589662b188a14 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: trace scheduler rbtree Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 65d2c0a..06380dc 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -129,6 +129,7 @@ static const char *trace_options[] = { "bin", "block", "stacktrace", + "sched-tree", NULL }; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 75e2374..a520157 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -286,6 +286,7 @@ enum trace_iterator_flags { TRACE_ITER_BIN = 0x40, TRACE_ITER_BLOCK = 0x80, TRACE_ITER_STACKTRACE = 0x100, + TRACE_ITER_SCHED_TREE = 0x200, }; #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 12658b3..5555b90 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -36,7 +36,8 @@ ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) if (likely(disabled == 1)) { tracing_sched_switch_trace(tr, data, prev, next, flags); - ftrace_all_fair_tasks(__rq, tr, data); + if (trace_flags & TRACE_ITER_SCHED_TREE) + ftrace_all_fair_tasks(__rq, tr, data); } atomic_dec(&data->disabled); @@ -62,7 +63,8 @@ wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) if (likely(disabled == 1)) { tracing_sched_wakeup_trace(tr, data, wakee, curr, flags); - ftrace_all_fair_tasks(__rq, tr, data); + if (trace_flags & TRACE_ITER_SCHED_TREE) + ftrace_all_fair_tasks(__rq, tr, data); } atomic_dec(&data->disabled); -- cgit v0.10.2 From c7078de1aaf562a31b20984409c38cc1b40fa8a3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: add tracing_cpumask Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 06380dc..18f0ab8 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -70,6 +70,23 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); unsigned long trace_flags = TRACE_ITER_PRINT_PARENT; +/* + * Only trace on a CPU if the bitmask is set: + */ +static cpumask_t tracing_cpumask __read_mostly = CPU_MASK_ALL; + +/* + * The tracer itself will not take this lock, but still we want + * to provide a consistent cpumask to user-space: + */ +static DEFINE_MUTEX(tracing_cpumask_update_lock); + +/* + * Temporary storage for the character representation of the + * CPU bitmask: + */ +static char mask_str[NR_CPUS]; + void trace_wake_up(void) { /* @@ -1754,9 +1771,49 @@ static struct file_operations tracing_lt_fops = { }; static struct file_operations show_traces_fops = { - .open = show_traces_open, - .read = seq_read, - .release = seq_release, + .open = show_traces_open, + .read = seq_read, + .release = seq_release, +}; + +static ssize_t +tracing_cpumask_read(struct file *filp, char __user *ubuf, + size_t count, loff_t *ppos) +{ + int err; + + count = min(count, (size_t)NR_CPUS); + + mutex_lock(&tracing_cpumask_update_lock); + cpumask_scnprintf(mask_str, NR_CPUS, tracing_cpumask); + err = copy_to_user(ubuf, mask_str, count); + if (err) + count = -EFAULT; + mutex_unlock(&tracing_cpumask_update_lock); + + return count; +} + +static ssize_t +tracing_cpumask_write(struct file *filp, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + int err; + + mutex_lock(&tracing_cpumask_update_lock); + err = cpumask_parse_user(ubuf, count, tracing_cpumask); + mutex_unlock(&tracing_cpumask_update_lock); + + if (err) + return err; + + return count; +} + +static struct file_operations tracing_cpumask_fops = { + .open = tracing_open_generic, + .read = tracing_cpumask_read, + .write = tracing_cpumask_write, }; static ssize_t @@ -1837,9 +1894,9 @@ tracing_iter_ctrl_write(struct file *filp, const char __user *ubuf, } static struct file_operations tracing_iter_fops = { - .open = tracing_open_generic, - .read = tracing_iter_ctrl_read, - .write = tracing_iter_ctrl_write, + .open = tracing_open_generic, + .read = tracing_iter_ctrl_read, + .write = tracing_iter_ctrl_write, }; static const char readme_msg[] = @@ -1870,8 +1927,8 @@ tracing_readme_read(struct file *filp, char __user *ubuf, } static struct file_operations tracing_readme_fops = { - .open = tracing_open_generic, - .read = tracing_readme_read, + .open = tracing_open_generic, + .read = tracing_readme_read, }; static ssize_t @@ -2334,6 +2391,11 @@ static __init void tracer_init_debugfs(void) if (!entry) pr_warning("Could not create debugfs 'iter_ctrl' entry\n"); + entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer, + NULL, &tracing_cpumask_fops); + if (!entry) + pr_warning("Could not create debugfs 'tracing_cpumask' entry\n"); + entry = debugfs_create_file("latency_trace", 0444, d_tracer, &global_trace, &tracing_lt_fops); if (!entry) -- cgit v0.10.2 From 36dfe9252bd4c9b55e8454363fb7e444c92c5030 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:52 +0200 Subject: ftrace: make use of tracing_cpumask Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 18f0ab8..3ae17e2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -70,23 +70,6 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); unsigned long trace_flags = TRACE_ITER_PRINT_PARENT; -/* - * Only trace on a CPU if the bitmask is set: - */ -static cpumask_t tracing_cpumask __read_mostly = CPU_MASK_ALL; - -/* - * The tracer itself will not take this lock, but still we want - * to provide a consistent cpumask to user-space: - */ -static DEFINE_MUTEX(tracing_cpumask_update_lock); - -/* - * Temporary storage for the character representation of the - * CPU bitmask: - */ -static char mask_str[NR_CPUS]; - void trace_wake_up(void) { /* @@ -1776,19 +1759,46 @@ static struct file_operations show_traces_fops = { .release = seq_release, }; +/* + * Only trace on a CPU if the bitmask is set: + */ +static cpumask_t tracing_cpumask = CPU_MASK_ALL; + +/* + * When tracing/tracing_cpu_mask is modified then this holds + * the new bitmask we are about to install: + */ +static cpumask_t tracing_cpumask_new; + +/* + * The tracer itself will not take this lock, but still we want + * to provide a consistent cpumask to user-space: + */ +static DEFINE_MUTEX(tracing_cpumask_update_lock); + +/* + * Temporary storage for the character representation of the + * CPU bitmask (and one more byte for the newline): + */ +static char mask_str[NR_CPUS + 1]; + static ssize_t tracing_cpumask_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) { - int err; - - count = min(count, (size_t)NR_CPUS); + int len; mutex_lock(&tracing_cpumask_update_lock); - cpumask_scnprintf(mask_str, NR_CPUS, tracing_cpumask); - err = copy_to_user(ubuf, mask_str, count); - if (err) - count = -EFAULT; + + len = cpumask_scnprintf(mask_str, count, tracing_cpumask); + if (count - len < 2) { + count = -EINVAL; + goto out_err; + } + len += sprintf(mask_str + len, "\n"); + count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1); + +out_err: mutex_unlock(&tracing_cpumask_update_lock); return count; @@ -1798,16 +1808,40 @@ static ssize_t tracing_cpumask_write(struct file *filp, const char __user *ubuf, size_t count, loff_t *ppos) { - int err; + int err, cpu; mutex_lock(&tracing_cpumask_update_lock); - err = cpumask_parse_user(ubuf, count, tracing_cpumask); - mutex_unlock(&tracing_cpumask_update_lock); - + err = cpumask_parse_user(ubuf, count, tracing_cpumask_new); if (err) - return err; + goto err_unlock; + + spin_lock_irq(&ftrace_max_lock); + for_each_possible_cpu(cpu) { + /* + * Increase/decrease the disabled counter if we are + * about to flip a bit in the cpumask: + */ + if (cpu_isset(cpu, tracing_cpumask) && + !cpu_isset(cpu, tracing_cpumask_new)) { + atomic_inc(&global_trace.data[cpu]->disabled); + } + if (!cpu_isset(cpu, tracing_cpumask) && + cpu_isset(cpu, tracing_cpumask_new)) { + atomic_dec(&global_trace.data[cpu]->disabled); + } + } + spin_unlock_irq(&ftrace_max_lock); + + tracing_cpumask = tracing_cpumask_new; + + mutex_unlock(&tracing_cpumask_update_lock); return count; + +err_unlock: + mutex_unlock(&tracing_cpumask_update_lock); + + return err; } static struct file_operations tracing_cpumask_fops = { @@ -1846,8 +1880,7 @@ tracing_iter_ctrl_read(struct file *filp, char __user *ubuf, r += sprintf(buf + r, "\n"); WARN_ON(r >= len + 2); - r = simple_read_from_buffer(ubuf, cnt, ppos, - buf, r); + r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); kfree(buf); -- cgit v0.10.2 From d9af56fbd8b37181bffaad060f74aa2e17382874 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: fix cmdline tracing Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 5555b90..5a217e8 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -29,6 +29,8 @@ ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) if (!tracer_enabled) return; + tracing_record_cmdline(prev); + local_irq_save(flags); cpu = raw_smp_processor_id(); data = tr->data[cpu]; @@ -56,6 +58,8 @@ wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) if (!tracer_enabled) return; + tracing_record_cmdline(curr); + local_irq_save(flags); cpu = raw_smp_processor_id(); data = tr->data[cpu]; @@ -75,8 +79,6 @@ void ftrace_ctx_switch(void *__rq, struct task_struct *prev, struct task_struct *next) { - tracing_record_cmdline(prev); - /* * If tracer_switch_func only points to the local * switch func, it still needs the ptr passed to it. @@ -93,8 +95,6 @@ void ftrace_wake_up_task(void *__rq, struct task_struct *wakee, struct task_struct *curr) { - tracing_record_cmdline(curr); - wakeup_func(__rq, wakee, curr); /* -- cgit v0.10.2 From 442e544ce52d4415a024920b84fb95c5f9aa0855 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: iter ctrl fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3ae17e2..688b4cf 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1920,6 +1920,11 @@ tracing_iter_ctrl_write(struct file *filp, const char __user *ubuf, break; } } + /* + * If no option could be set, return an error: + */ + if (!trace_options[i]) + return -EINVAL; filp->f_pos += cnt; -- cgit v0.10.2 From f29c73fe3404f8799ed57aaf48859e0b55fc071f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: include cpu in stacktrace Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 688b4cf..3a40324 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1227,10 +1227,8 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) abs_usecs % 1000, rel_usecs/1000, rel_usecs % 1000); } else { - if (entry->type != TRACE_STACK) { - lat_print_generic(s, entry, cpu); - lat_print_timestamp(s, abs_usecs, rel_usecs); - } + lat_print_generic(s, entry, cpu); + lat_print_timestamp(s, abs_usecs, rel_usecs); } switch (entry->type) { case TRACE_FN: @@ -1293,17 +1291,15 @@ static int print_trace_fmt(struct trace_iterator *iter) usec_rem = do_div(t, 1000000ULL); secs = (unsigned long)t; - if (entry->type != TRACE_STACK) { - ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); - if (!ret) - return 0; - ret = trace_seq_printf(s, "[%02d] ", iter->cpu); - if (!ret) - return 0; - ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); - if (!ret) - return 0; - } + ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid); + if (!ret) + return 0; + ret = trace_seq_printf(s, "[%02d] ", iter->cpu); + if (!ret) + return 0; + ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem); + if (!ret) + return 0; switch (entry->type) { case TRACE_FN: -- cgit v0.10.2 From 36fc25a9f48deacd8aa08cd2d1c186a4e412604f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: sched tree fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/sched.c b/kernel/sched.c index 9ca4a2e..3bc7c53 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2414,6 +2414,23 @@ static int sched_balance_self(int cpu, int flag) #ifdef CONFIG_CONTEXT_SWITCH_TRACER +void ftrace_task(struct task_struct *p, void *__tr, void *__data) +{ +#if 0 + /* + * trace timeline tree + */ + __trace_special(__tr, __data, + p->pid, p->se.vruntime, p->se.sum_exec_runtime); +#else + /* + * trace balance metrics + */ + __trace_special(__tr, __data, + p->pid, p->se.avg_overlap, 0); +#endif +} + void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) { struct task_struct *p; @@ -2421,32 +2438,22 @@ void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) struct rb_node *curr; struct rq *rq = __rq; - curr = first_fair(&rq->cfs); - if (!curr) - return; - if (rq->cfs.curr) { p = task_of(rq->cfs.curr); - __trace_special(__tr, __data, - p->pid, p->se.vruntime, p->se.sum_exec_runtime); + ftrace_task(p, __tr, __data); } if (rq->cfs.next) { p = task_of(rq->cfs.next); - __trace_special(__tr, __data, - p->pid, p->se.vruntime, p->se.sum_exec_runtime); + ftrace_task(p, __tr, __data); } - while (curr) { + for (curr = first_fair(&rq->cfs); curr; curr = rb_next(curr)) { se = rb_entry(curr, struct sched_entity, run_node); if (!entity_is_task(se)) continue; p = task_of(se); - - __trace_special(__tr, __data, - p->pid, p->se.vruntime, p->se.sum_exec_runtime); - - curr = rb_next(curr); + ftrace_task(p, __tr, __data); } } -- cgit v0.10.2 From 88a4216c3ec4281fc7e6725cc3a3ccd01fb1aa14 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: sched special Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 5b186be..360ca99 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2138,6 +2138,8 @@ extern void ftrace_wake_up_task(void *rq, struct task_struct *wakee, struct task_struct *curr); extern void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data); +extern void +ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); #else static inline void ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next) @@ -2155,6 +2157,10 @@ ftrace_wake_up_task(void *rq, struct task_struct *wakee, static inline void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) { } +static inline void +ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ +} #endif extern long sched_setaffinity(pid_t pid, const cpumask_t *new_mask); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index e24ecd3..dc1856f 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1061,6 +1061,8 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq, if (!(this_sd->flags & SD_WAKE_AFFINE)) return 0; + ftrace_special(__LINE__, curr->se.avg_overlap, sync); + ftrace_special(__LINE__, p->se.avg_overlap, -1); /* * If the currently running task will sleep within * a reasonable amount of time then attract this newly @@ -1238,6 +1240,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p) if (unlikely(se == pse)) return; + ftrace_special(__LINE__, p->pid, se->last_wakeup); cfs_rq_of(pse)->next = pse; /* diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3a40324..b87a264 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1251,7 +1251,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) comm); break; case TRACE_SPECIAL: - trace_seq_printf(s, " %ld %ld %ld\n", + trace_seq_printf(s, "# %ld %ld %ld\n", entry->special.arg1, entry->special.arg2, entry->special.arg3); @@ -1335,7 +1335,7 @@ static int print_trace_fmt(struct trace_iterator *iter) return 0; break; case TRACE_SPECIAL: - ret = trace_seq_printf(s, " %ld %ld %ld\n", + ret = trace_seq_printf(s, "# %ld %ld %ld\n", entry->special.arg1, entry->special.arg2, entry->special.arg3); @@ -1400,7 +1400,7 @@ static int print_raw_fmt(struct trace_iterator *iter) break; case TRACE_SPECIAL: case TRACE_STACK: - ret = trace_seq_printf(s, " %ld %ld %ld\n", + ret = trace_seq_printf(s, "# %ld %ld %ld\n", entry->special.arg1, entry->special.arg2, entry->special.arg3); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 5a217e8..bddf676 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -103,6 +103,30 @@ ftrace_wake_up_task(void *__rq, struct task_struct *wakee, wakeup_sched_wakeup(wakee, curr); } +void +ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + struct trace_array *tr = ctx_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (!tracer_enabled) + return; + + local_irq_save(flags); + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + __trace_special(tr, data, arg1, arg2, arg3); + + atomic_dec(&data->disabled); + local_irq_restore(flags); +} + static void sched_switch_reset(struct trace_array *tr) { int cpu; -- cgit v0.10.2 From bac524d3f3dfeffa3a9d44f2c64035b88bcaacb4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: trace next state Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b87a264..b63fe90 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -736,6 +736,7 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.prev_state = prev->state; entry->ctx.next_pid = next->pid; entry->ctx.next_prio = next->prio; + entry->ctx.next_state = next->state; __trace_stack(tr, data, flags, 4); spin_unlock_irqrestore(&data->lock, irq_flags); } @@ -759,6 +760,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->ctx.prev_state = curr->state; entry->ctx.next_pid = wakee->pid; entry->ctx.next_prio = wakee->prio; + entry->ctx.next_state = wakee->state; __trace_stack(tr, data, flags, 5); spin_unlock_irqrestore(&data->lock, irq_flags); @@ -1207,7 +1209,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) unsigned long abs_usecs; unsigned long rel_usecs; char *comm; - int S; + int S, T; int i; if (!next_entry) @@ -1241,14 +1243,17 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; + T = entry->ctx.next_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.next_state] : 'X'; + comm = trace_find_cmdline(entry->ctx.next_pid); - trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d %s\n", + trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n", entry->ctx.prev_pid, entry->ctx.prev_prio, S, entry->type == TRACE_CTX ? "==>" : " +", entry->ctx.next_pid, entry->ctx.next_prio, - comm); + T, comm); break; case TRACE_SPECIAL: trace_seq_printf(s, "# %ld %ld %ld\n", @@ -1280,7 +1285,7 @@ static int print_trace_fmt(struct trace_iterator *iter) unsigned long secs; char *comm; int ret; - int S; + int S, T; int i; entry = iter->ent; @@ -1324,13 +1329,16 @@ static int print_trace_fmt(struct trace_iterator *iter) case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; - ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d\n", + T = entry->ctx.next_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.next_state] : 'X'; + ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c\n", entry->ctx.prev_pid, entry->ctx.prev_prio, S, entry->type == TRACE_CTX ? "==>" : " +", entry->ctx.next_pid, - entry->ctx.next_prio); + entry->ctx.next_prio, + T); if (!ret) return 0; break; @@ -1367,7 +1375,7 @@ static int print_raw_fmt(struct trace_iterator *iter) struct trace_seq *s = &iter->seq; struct trace_entry *entry; int ret; - int S; + int S, T; entry = iter->ent; @@ -1387,14 +1395,17 @@ static int print_raw_fmt(struct trace_iterator *iter) case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; + T = entry->ctx.next_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.next_state] : 'X'; if (entry->type == TRACE_WAKE) S = '+'; - ret = trace_seq_printf(s, "%d %d %c %d %d\n", + ret = trace_seq_printf(s, "%d %d %c %d %d %c\n", entry->ctx.prev_pid, entry->ctx.prev_prio, S, entry->ctx.next_pid, - entry->ctx.next_prio); + entry->ctx.next_prio, + T); if (!ret) return 0; break; @@ -1428,7 +1439,7 @@ static int print_hex_fmt(struct trace_iterator *iter) struct trace_seq *s = &iter->seq; unsigned char newline = '\n'; struct trace_entry *entry; - int S; + int S, T; entry = iter->ent; @@ -1445,6 +1456,8 @@ static int print_hex_fmt(struct trace_iterator *iter) case TRACE_WAKE: S = entry->ctx.prev_state < sizeof(state_to_char) ? state_to_char[entry->ctx.prev_state] : 'X'; + T = entry->ctx.next_state < sizeof(state_to_char) ? + state_to_char[entry->ctx.next_state] : 'X'; if (entry->type == TRACE_WAKE) S = '+'; SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid); @@ -1453,6 +1466,7 @@ static int print_hex_fmt(struct trace_iterator *iter) SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_pid); SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_prio); SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); + SEQ_PUT_HEX_FIELD_RET(s, T); break; case TRACE_SPECIAL: case TRACE_STACK: @@ -1488,6 +1502,7 @@ static int print_bin_fmt(struct trace_iterator *iter) SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state); SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid); SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio); + SEQ_PUT_FIELD_RET(s, entry->ctx.next_state); break; case TRACE_SPECIAL: case TRACE_STACK: diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index a520157..96951a8 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -23,6 +23,7 @@ struct ctx_switch_entry { unsigned char prev_state; unsigned int next_pid; unsigned char next_prio; + unsigned char next_state; }; /* -- cgit v0.10.2 From 5429db2d26a59903c81a4f6c6dae7eb9daaea5fc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 12 May 2008 21:20:53 +0200 Subject: ftrace: fix wakeup callback Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/sched.c b/kernel/sched.c index 3bc7c53..1ec3fb2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2533,7 +2533,6 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) out_activate: #endif /* CONFIG_SMP */ - ftrace_wake_up_task(rq, p, rq->curr); schedstat_inc(p, se.nr_wakeups); if (sync) schedstat_inc(p, se.nr_wakeups_sync); @@ -2548,6 +2547,7 @@ out_activate: success = 1; out_running: + ftrace_wake_up_task(rq, p, rq->curr); check_preempt_curr(rq, p); p->state = TASK_RUNNING; -- cgit v0.10.2 From 694379e9ed4f2f6babe111bf001c69e2e263338b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:54 +0200 Subject: ftrace: make it more available in the Kconfig Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index eb1988e..ebc158e 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -14,7 +14,7 @@ config TRACING config FTRACE bool "Kernel Function Tracer" - depends on DEBUG_KERNEL && HAVE_FTRACE + depends on HAVE_FTRACE select FRAME_POINTER select TRACING select CONTEXT_SWITCH_TRACER @@ -72,7 +72,6 @@ config PREEMPT_TRACER config SCHED_TRACER bool "Scheduling Latency Tracer" - depends on DEBUG_KERNEL select TRACING select CONTEXT_SWITCH_TRACER select TRACER_MAX_TRACE @@ -82,7 +81,6 @@ config SCHED_TRACER config CONTEXT_SWITCH_TRACER bool "Trace process context switches" - depends on DEBUG_KERNEL select TRACING select MARKERS help -- cgit v0.10.2 From 8f96da02c14d722ad9a3713cd7273ce28c9036ad Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: ftrace: remove wakeup from function trace trace_function is called by mcount and calling wake_up from that can have unpredictable results. This patch removes the wakeup from trace_function. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b63fe90..736dcfb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -659,8 +659,6 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; spin_unlock_irqrestore(&data->lock, irq_flags); - - trace_wake_up(); } void -- cgit v0.10.2 From 4fe8c3048cd8280a54256bca9cac2007bd546c33 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: ftrace: printk and trace irqsoff and wakeups printk called from wakeup critical timings and irqs off can cause deadlocks since printk might do a wakeup itself. If the call to printk happens with the runqueue lock held, it can deadlock. This patch protects the printk from being called in trace irqs off with a test to see if the runqueue for the current CPU is locked. If it is locked, the printk is skipped. The wakeup always holds the runqueue lock, so the printk is simply removed. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 7a4dc01..d0c1748 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -165,18 +165,20 @@ check_critical_timing(struct trace_array *tr, update_max_tr_single(tr, current, cpu); - if (tracing_thresh) { - printk(KERN_INFO "(%16s-%-5d|#%d):" - " %lu us critical section violates %lu us threshold.\n", - current->comm, current->pid, - raw_smp_processor_id(), - latency, nsecs_to_usecs(tracing_thresh)); - } else { - printk(KERN_INFO "(%16s-%-5d|#%d):" - " new %lu us maximum-latency critical section.\n", - current->comm, current->pid, - raw_smp_processor_id(), - latency); + if (!runqueue_is_locked()) { + if (tracing_thresh) { + printk(KERN_INFO "(%16s-%-5d|#%d): %lu us critical" + " section violates %lu us threshold.\n", + current->comm, current->pid, + raw_smp_processor_id(), + latency, nsecs_to_usecs(tracing_thresh)); + } else { + printk(KERN_INFO "(%16s-%-5d|#%d): new %lu us" + " maximum-latency critical section.\n", + current->comm, current->pid, + raw_smp_processor_id(), + latency); + } } max_sequence++; diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 2a01242..5948011 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -106,19 +106,6 @@ wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) update_max_tr(tr, wakeup_task, wakeup_cpu); - if (tracing_thresh) { - printk(KERN_INFO "(%16s-%-5d|#%d):" - " %lu us wakeup latency violates %lu us threshold.\n", - wakeup_task->comm, wakeup_task->pid, - raw_smp_processor_id(), - latency, nsecs_to_usecs(tracing_thresh)); - } else { - printk(KERN_INFO "(%16s-%-5d|#%d):" - " new %lu us maximum wakeup latency.\n", - wakeup_task->comm, wakeup_task->pid, - cpu, latency); - } - out_unlock: __wakeup_reset(tr); spin_unlock_irqrestore(&wakeup_lock, flags); -- cgit v0.10.2 From 06fa75ab566c50e01bfd7b055bde85cf9b1bc98a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: ftrace: add TRACE_STACK and TRACE_SPECIAL to selftest validation The selftest validation code checks for valid entries in the trace buffer. TRACE_STACK and TRACE_SPECIAL have been added to the code but not to the validator. This patch adds the two to prevent them from flagging a failure in the selftest. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 39dd452..92f4acb 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -9,6 +9,8 @@ static inline int trace_valid_entry(struct trace_entry *entry) case TRACE_FN: case TRACE_CTX: case TRACE_WAKE: + case TRACE_STACK: + case TRACE_SPECIAL: return 1; } return 0; @@ -180,7 +182,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, /* we should only have one item */ if (!ret && count != 1) { - printk(KERN_CONT ".. filter failed .."); + printk(KERN_CONT ".. filter failed count=%ld ..", count); ret = -1; goto out; } -- cgit v0.10.2 From d05cdb25d80f06f77aa6bddb53cd1390d4d91a0b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:54 +0200 Subject: ftrace: fix dynamic ftrace selftest With the adding of the configuration changes in the Makefile to prevent tracing of functions in the ftrace code, all tracing of all the ftrace code has been removed. Unfortunately, one of the selftests, relied on a function to be traced. With the new change, the function was no longer traced and the test failed. This patch separates out the test function into its own file so that we can add the "-pg" flag to the compilation of that function and the adding of the mcount call to that function. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index c25a6cd..d9efbbf 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -4,6 +4,10 @@ ifdef CONFIG_FTRACE ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) + +# selftest needs instrumentation +CFLAGS_trace_selftest_dynamic.o = -pg +obj-y += trace_selftest_dynamic.o endif obj-$(CONFIG_FTRACE) += libftrace.o diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 96951a8..98cbfd0 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -244,6 +244,8 @@ extern int unregister_tracer_switch(struct tracer_switch_ops *ops); #ifdef CONFIG_DYNAMIC_FTRACE extern unsigned long ftrace_update_tot_cnt; +#define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func +extern int DYN_FTRACE_TEST_NAME(void); #endif #ifdef CONFIG_FTRACE_STARTUP_TEST diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 92f4acb..83e55a2 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -107,14 +107,8 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) #ifdef CONFIG_DYNAMIC_FTRACE -#define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func #define __STR(x) #x #define STR(x) __STR(x) -static int DYN_FTRACE_TEST_NAME(void) -{ - /* used to call mcount */ - return 0; -} /* Test dynamic code modification and ftrace filters */ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, diff --git a/kernel/trace/trace_selftest_dynamic.c b/kernel/trace/trace_selftest_dynamic.c new file mode 100644 index 0000000..54dd77c --- /dev/null +++ b/kernel/trace/trace_selftest_dynamic.c @@ -0,0 +1,7 @@ +#include "trace.h" + +int DYN_FTRACE_TEST_NAME(void) +{ + /* used to call mcount */ + return 0; +} -- cgit v0.10.2 From 4d9493c90f8e6e1b164aede3814010a290161abb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:54 +0200 Subject: ftrace: remove add-hoc code Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/sched.c b/kernel/sched.c index 1ec3fb2..ad95cca 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2412,53 +2412,6 @@ static int sched_balance_self(int cpu, int flag) #endif /* CONFIG_SMP */ -#ifdef CONFIG_CONTEXT_SWITCH_TRACER - -void ftrace_task(struct task_struct *p, void *__tr, void *__data) -{ -#if 0 - /* - * trace timeline tree - */ - __trace_special(__tr, __data, - p->pid, p->se.vruntime, p->se.sum_exec_runtime); -#else - /* - * trace balance metrics - */ - __trace_special(__tr, __data, - p->pid, p->se.avg_overlap, 0); -#endif -} - -void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) -{ - struct task_struct *p; - struct sched_entity *se; - struct rb_node *curr; - struct rq *rq = __rq; - - if (rq->cfs.curr) { - p = task_of(rq->cfs.curr); - ftrace_task(p, __tr, __data); - } - if (rq->cfs.next) { - p = task_of(rq->cfs.next); - ftrace_task(p, __tr, __data); - } - - for (curr = first_fair(&rq->cfs); curr; curr = rb_next(curr)) { - se = rb_entry(curr, struct sched_entity, run_node); - if (!entity_is_task(se)) - continue; - - p = task_of(se); - ftrace_task(p, __tr, __data); - } -} - -#endif - /*** * try_to_wake_up - wake up a thread * @p: the to-be-woken-up thread diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index dc1856f..e24ecd3 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1061,8 +1061,6 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq, if (!(this_sd->flags & SD_WAKE_AFFINE)) return 0; - ftrace_special(__LINE__, curr->se.avg_overlap, sync); - ftrace_special(__LINE__, p->se.avg_overlap, -1); /* * If the currently running task will sleep within * a reasonable amount of time then attract this newly @@ -1240,7 +1238,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p) if (unlikely(se == pse)) return; - ftrace_special(__LINE__, p->pid, se->last_wakeup); cfs_rq_of(pse)->next = pse; /* diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index bddf676..5671db0 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -36,11 +36,8 @@ ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); - if (likely(disabled == 1)) { + if (likely(disabled == 1)) tracing_sched_switch_trace(tr, data, prev, next, flags); - if (trace_flags & TRACE_ITER_SCHED_TREE) - ftrace_all_fair_tasks(__rq, tr, data); - } atomic_dec(&data->disabled); local_irq_restore(flags); @@ -65,11 +62,8 @@ wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) data = tr->data[cpu]; disabled = atomic_inc_return(&data->disabled); - if (likely(disabled == 1)) { + if (likely(disabled == 1)) tracing_sched_wakeup_trace(tr, data, wakee, curr, flags); - if (trace_flags & TRACE_ITER_SCHED_TREE) - ftrace_all_fair_tasks(__rq, tr, data); - } atomic_dec(&data->disabled); local_irq_restore(flags); -- cgit v0.10.2 From c5f888cae49dfe3e86d9d1e0dab2b63ceb057be3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: ftrace: irqsoff use raw_smp_processor_id This patch changes the use of __get_cpu_var to explicitly calling raw_smp_processor_id and using the per_cpu() macro. On some debug configurations, the use of __get_cpu_var may cause ftrace to trigger and this can cause problems with the irqsoff tracing. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index d0c1748..761f3ec 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -204,14 +204,14 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) if (likely(!tracer_enabled)) return; - if (__get_cpu_var(tracing_cpu)) + cpu = raw_smp_processor_id(); + + if (per_cpu(tracing_cpu, cpu)) return; - cpu = raw_smp_processor_id(); data = tr->data[cpu]; - if (unlikely(!data) || unlikely(!head_page(data)) || - atomic_read(&data->disabled)) + if (unlikely(!data) || atomic_read(&data->disabled)) return; atomic_inc(&data->disabled); @@ -225,7 +225,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip) trace_function(tr, data, ip, parent_ip, flags); - __get_cpu_var(tracing_cpu) = 1; + per_cpu(tracing_cpu, cpu) = 1; atomic_dec(&data->disabled); } @@ -238,16 +238,16 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) struct trace_array_cpu *data; unsigned long flags; + cpu = raw_smp_processor_id(); /* Always clear the tracing cpu on stopping the trace */ - if (unlikely(__get_cpu_var(tracing_cpu))) - __get_cpu_var(tracing_cpu) = 0; + if (unlikely(per_cpu(tracing_cpu, cpu))) + per_cpu(tracing_cpu, cpu) = 0; else return; if (!tracer_enabled) return; - cpu = raw_smp_processor_id(); data = tr->data[cpu]; if (unlikely(!data) || unlikely(!head_page(data)) || @@ -255,6 +255,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip) return; atomic_inc(&data->disabled); + local_save_flags(flags); trace_function(tr, data, ip, parent_ip, flags); check_critical_timing(tr, data, parent_ip ? : ip, cpu); @@ -376,7 +377,7 @@ static void stop_irqsoff_tracer(struct trace_array *tr) static void __irqsoff_tracer_init(struct trace_array *tr) { irqsoff_trace = tr; - /* make sure that the tracer is visibel */ + /* make sure that the tracer is visible */ smp_wmb(); if (tr->ctrl) -- cgit v0.10.2 From 92205c2343527a863d660360599a4bf8cede77b0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: ftrace: user raw_spin_lock in tracing Lock debugging enabled cause huge performance problems for tracing. Having the lock verification happening for every function that is called because mcount calls spin_lock can cripple the system. This patch converts the spin_locks used by ftrace into raw_spin_locks. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 736dcfb..3009aaf 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -133,7 +133,8 @@ static const char *trace_options[] = { NULL }; -static DEFINE_SPINLOCK(ftrace_max_lock); +static raw_spinlock_t ftrace_max_lock = + (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; /* * Copy the new maximum trace into the separate maximum-trace @@ -335,7 +336,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) int i; WARN_ON_ONCE(!irqs_disabled()); - spin_lock(&ftrace_max_lock); + __raw_spin_lock(&ftrace_max_lock); /* clear out all the previous traces */ for_each_possible_cpu(i) { data = tr->data[i]; @@ -344,7 +345,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) } __update_max_tr(tr, tsk, cpu); - spin_unlock(&ftrace_max_lock); + __raw_spin_unlock(&ftrace_max_lock); } /** @@ -360,7 +361,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) int i; WARN_ON_ONCE(!irqs_disabled()); - spin_lock(&ftrace_max_lock); + __raw_spin_lock(&ftrace_max_lock); for_each_possible_cpu(i) tracing_reset(max_tr.data[i]); @@ -368,7 +369,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) tracing_reset(data); __update_max_tr(tr, tsk, cpu); - spin_unlock(&ftrace_max_lock); + __raw_spin_unlock(&ftrace_max_lock); } int register_tracer(struct tracer *type) @@ -652,13 +653,15 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, struct trace_entry *entry; unsigned long irq_flags; - spin_lock_irqsave(&data->lock, irq_flags); + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_FN; entry->fn.ip = ip; entry->fn.parent_ip = parent_ip; - spin_unlock_irqrestore(&data->lock, irq_flags); + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); } void @@ -678,14 +681,16 @@ __trace_special(void *__tr, void *__data, struct trace_entry *entry; unsigned long irq_flags; - spin_lock_irqsave(&data->lock, irq_flags); + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, 0); entry->type = TRACE_SPECIAL; entry->special.arg1 = arg1; entry->special.arg2 = arg2; entry->special.arg3 = arg3; - spin_unlock_irqrestore(&data->lock, irq_flags); + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); trace_wake_up(); } @@ -725,7 +730,8 @@ tracing_sched_switch_trace(struct trace_array *tr, struct trace_entry *entry; unsigned long irq_flags; - spin_lock_irqsave(&data->lock, irq_flags); + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_CTX; @@ -736,7 +742,8 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.next_prio = next->prio; entry->ctx.next_state = next->state; __trace_stack(tr, data, flags, 4); - spin_unlock_irqrestore(&data->lock, irq_flags); + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); } void @@ -749,7 +756,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr, struct trace_entry *entry; unsigned long irq_flags; - spin_lock_irqsave(&data->lock, irq_flags); + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, flags); entry->type = TRACE_WAKE; @@ -760,7 +768,8 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->ctx.next_prio = wakee->prio; entry->ctx.next_state = wakee->state; __trace_stack(tr, data, flags, 5); - spin_unlock_irqrestore(&data->lock, irq_flags); + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); trace_wake_up(); } @@ -1824,7 +1833,8 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, if (err) goto err_unlock; - spin_lock_irq(&ftrace_max_lock); + raw_local_irq_disable(); + __raw_spin_lock(&ftrace_max_lock); for_each_possible_cpu(cpu) { /* * Increase/decrease the disabled counter if we are @@ -1839,7 +1849,8 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, atomic_dec(&global_trace.data[cpu]->disabled); } } - spin_unlock_irq(&ftrace_max_lock); + __raw_spin_unlock(&ftrace_max_lock); + raw_local_irq_enable(); tracing_cpumask = tracing_cpumask_new; @@ -2299,7 +2310,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, for_each_cpu_mask(cpu, mask) { data = iter->tr->data[cpu]; - spin_lock(&data->lock); + __raw_spin_lock(&data->lock); } while (find_next_entry_inc(iter) != NULL) { @@ -2320,7 +2331,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, for_each_cpu_mask(cpu, mask) { data = iter->tr->data[cpu]; - spin_unlock(&data->lock); + __raw_spin_unlock(&data->lock); } for_each_cpu_mask(cpu, mask) { @@ -2538,8 +2549,7 @@ static int trace_alloc_page(void) /* Now that we successfully allocate a page per CPU, add them */ for_each_possible_cpu(i) { data = global_trace.data[i]; - spin_lock_init(&data->lock); - lockdep_set_class(&data->lock, &data->lock_key); + data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); @@ -2547,8 +2557,7 @@ static int trace_alloc_page(void) #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; - spin_lock_init(&data->lock); - lockdep_set_class(&data->lock, &data->lock_key); + data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 98cbfd0..25cba28 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -76,7 +76,7 @@ struct trace_entry { struct trace_array_cpu { struct list_head trace_pages; atomic_t disabled; - spinlock_t lock; + raw_spinlock_t lock; struct lock_class_key lock_key; /* these fields get copied into max-trace: */ -- cgit v0.10.2 From 9d0a420b737f72d84fabebf29634d800cbf54538 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: ftrace: remove function tracing from spinlock debug The debug functions in spin_lock debugging pollute the output of the function tracer. This patch adds the debug files in the lib director to those that should not be compiled with mcount tracing. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/lib/Makefile b/lib/Makefile index 6ca9e6e..d97ad11 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -10,8 +10,9 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ ifdef CONFIG_FTRACE # Do not profile string.o, since it may be used in early boot or vdso +# Also do not profile any debug utilities ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(if $(subst string,,$(basename $(notdir $@))), \ +KBUILD_CFLAGS = $(if $(filter-out %debug debug% string%,$(basename $(notdir $@))), \ $(ORIG_CFLAGS), \ $(subst -pg,,$(ORIG_CFLAGS))) endif -- cgit v0.10.2 From 1d09daa55d2e9bab7e7d30f0d05e5a7bc60b2a4a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: ftrace: use Makefile to remove tracing from lockdep This patch removes the "notrace" annotation from lockdep and adds the debugging files in the kernel director to those that should not be compiled with "-pg" mcount tracing. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/Makefile b/kernel/Makefile index 7e344e7..d2f80ea 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -11,6 +11,14 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o +ifdef CONFIG_FTRACE +# Do not profile debug utilities +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(if $(filter-out lockdep% %debug,$(basename $(notdir $@))), \ + $(ORIG_CFLAGS), \ + $(subst -pg,,$(ORIG_CFLAGS))) +endif + obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += time/ diff --git a/kernel/lockdep.c b/kernel/lockdep.c index ac46847..90a440c 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -271,14 +271,14 @@ static struct list_head chainhash_table[CHAINHASH_SIZE]; ((key1) >> (64-MAX_LOCKDEP_KEYS_BITS)) ^ \ (key2)) -notrace void lockdep_off(void) +void lockdep_off(void) { current->lockdep_recursion++; } EXPORT_SYMBOL(lockdep_off); -notrace void lockdep_on(void) +void lockdep_on(void) { current->lockdep_recursion--; } @@ -1041,7 +1041,7 @@ find_usage_forwards(struct lock_class *source, unsigned int depth) * Return 1 otherwise and keep unchanged. * Return 0 on error. */ -static noinline notrace int +static noinline int find_usage_backwards(struct lock_class *source, unsigned int depth) { struct lock_list *entry; @@ -1591,7 +1591,7 @@ static inline int validate_chain(struct task_struct *curr, * We are building curr_chain_key incrementally, so double-check * it from scratch, to make sure that it's done correctly: */ -static notrace void check_chain_key(struct task_struct *curr) +static void check_chain_key(struct task_struct *curr) { #ifdef CONFIG_DEBUG_LOCKDEP struct held_lock *hlock, *prev_hlock = NULL; @@ -1967,7 +1967,7 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, /* * Mark all held locks with a usage bit: */ -static notrace int +static int mark_held_locks(struct task_struct *curr, int hardirq) { enum lock_usage_bit usage_bit; @@ -2014,7 +2014,7 @@ void early_boot_irqs_on(void) /* * Hardirqs will be enabled: */ -void notrace trace_hardirqs_on_caller(unsigned long a0) +void trace_hardirqs_on_caller(unsigned long a0) { struct task_struct *curr = current; unsigned long ip; @@ -2060,7 +2060,7 @@ void notrace trace_hardirqs_on_caller(unsigned long a0) } EXPORT_SYMBOL(trace_hardirqs_on_caller); -void notrace trace_hardirqs_on(void) +void trace_hardirqs_on(void) { trace_hardirqs_on_caller(CALLER_ADDR0); } @@ -2069,7 +2069,7 @@ EXPORT_SYMBOL(trace_hardirqs_on); /* * Hardirqs were disabled: */ -void notrace trace_hardirqs_off_caller(unsigned long a0) +void trace_hardirqs_off_caller(unsigned long a0) { struct task_struct *curr = current; @@ -2094,7 +2094,7 @@ void notrace trace_hardirqs_off_caller(unsigned long a0) } EXPORT_SYMBOL(trace_hardirqs_off_caller); -void notrace trace_hardirqs_off(void) +void trace_hardirqs_off(void) { trace_hardirqs_off_caller(CALLER_ADDR0); } @@ -2260,7 +2260,7 @@ static inline int separate_irq_context(struct task_struct *curr, /* * Mark a lock with a usage bit, and validate the state transition: */ -static notrace int mark_lock(struct task_struct *curr, struct held_lock *this, +static int mark_lock(struct task_struct *curr, struct held_lock *this, enum lock_usage_bit new_bit) { unsigned int new_mask = 1 << new_bit, ret = 1; @@ -2663,7 +2663,7 @@ __lock_release(struct lockdep_map *lock, int nested, unsigned long ip) /* * Check whether we follow the irq-flags state precisely: */ -static notrace void check_flags(unsigned long flags) +static void check_flags(unsigned long flags) { #if defined(CONFIG_DEBUG_LOCKDEP) && defined(CONFIG_TRACE_IRQFLAGS) if (!debug_locks) @@ -2700,7 +2700,7 @@ static notrace void check_flags(unsigned long flags) * We are not always called with irqs disabled - do that here, * and also avoid lockdep recursion: */ -notrace void lock_acquire(struct lockdep_map *lock, unsigned int subclass, +void lock_acquire(struct lockdep_map *lock, unsigned int subclass, int trylock, int read, int check, unsigned long ip) { unsigned long flags; @@ -2723,7 +2723,7 @@ notrace void lock_acquire(struct lockdep_map *lock, unsigned int subclass, EXPORT_SYMBOL_GPL(lock_acquire); -notrace void lock_release(struct lockdep_map *lock, int nested, +void lock_release(struct lockdep_map *lock, int nested, unsigned long ip) { unsigned long flags; -- cgit v0.10.2 From c1d2327b36f2261ffa8ff7227321ba900c7eee7f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:55 +0200 Subject: ftrace: restrict tracing to HAVE_FTRACE architectures Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index ebc158e..f300571 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -32,6 +32,7 @@ config IRQSOFF_TRACER default n depends on TRACE_IRQFLAGS_SUPPORT depends on GENERIC_TIME + depends on HAVE_FTRACE select TRACE_IRQFLAGS select TRACING select TRACER_MAX_TRACE @@ -54,6 +55,7 @@ config PREEMPT_TRACER default n depends on GENERIC_TIME depends on PREEMPT + depends on HAVE_FTRACE select TRACING select TRACER_MAX_TRACE help @@ -72,6 +74,7 @@ config PREEMPT_TRACER config SCHED_TRACER bool "Scheduling Latency Tracer" + depends on HAVE_FTRACE select TRACING select CONTEXT_SWITCH_TRACER select TRACER_MAX_TRACE @@ -81,6 +84,7 @@ config SCHED_TRACER config CONTEXT_SWITCH_TRACER bool "Trace process context switches" + depends on HAVE_FTRACE select TRACING select MARKERS help -- cgit v0.10.2 From 07a267cdd2fd7d1de9455b1e36a1635ace7276c7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:55 +0200 Subject: ftrace: add UNINTERRUPTIBLE state for kftraced on disable When dynamic ftrace fails and sets itself disabled, the ftraced daemon will go back to sleep everytime it wakes up. The setting of the ftraced state to UNINTERRUPTIBLE is skipped in this process, and the daemon takes up 100% of the CPU. This patch makes sure the ftraced daemon sets itself to UNINTERRUPTIBLE in that loop. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 281d97a..40f64f7 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -630,10 +630,10 @@ static int ftraced(void *ignore) { unsigned long usecs; - set_current_state(TASK_INTERRUPTIBLE); - while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); + /* check once a second */ schedule_timeout(HZ); @@ -667,8 +667,6 @@ static int ftraced(void *ignore) wake_up_interruptible(&ftraced_waiters); ftrace_shutdown_replenish(); - - set_current_state(TASK_INTERRUPTIBLE); } __set_current_state(TASK_RUNNING); return 0; -- cgit v0.10.2 From d15f57f23eaba975309a153b23699cd0c0236974 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: ftrace: fix mutex unlock in trace output If the trace output changes on reading the trace files, there is a chance that the start function will return NULL. If the start function of a sequence returns NULL the stop equivalent is not called. In this case, all locks that are taken must be released even if they are released in the stop function. This patch fixes a case that a mutex was not released on return of NULL in the start sequence function. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3009aaf..ea11f4e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -964,8 +964,10 @@ static void *s_start(struct seq_file *m, loff_t *pos) mutex_lock(&trace_types_lock); - if (!current_trace || current_trace != iter->trace) + if (!current_trace || current_trace != iter->trace) { + mutex_unlock(&trace_types_lock); return NULL; + } atomic_inc(&trace_record_cmdline_disabled); -- cgit v0.10.2 From 30afdcb1de0a37a2086145a82ca3febebe47d019 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: ftrace: selftest protect againt max flip There is a slight race condition in the selftest where the max update of the wakeup and irqs/preemption off tests can be doing a max update as the buffers are being tested. If this happens the system can crash with a GPF. This patch adds the max update spinlock around the checking of the buffers to prevent such a race. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 83e55a2..395274e 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -82,10 +82,12 @@ trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data) */ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) { - unsigned long cnt = 0; - int cpu; - int ret = 0; + unsigned long flags, cnt = 0; + int cpu, ret = 0; + /* Don't allow flipping of max traces now */ + raw_local_irq_save(flags); + __raw_spin_lock(&ftrace_max_lock); for_each_possible_cpu(cpu) { if (!head_page(tr->data[cpu])) continue; @@ -96,6 +98,8 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) if (ret) break; } + __raw_spin_unlock(&ftrace_max_lock); + raw_local_irq_restore(flags); if (count) *count = cnt; -- cgit v0.10.2 From a56be3fe2f65f9f776e727bfd382e35db75911d6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: ftrace: fix the fault label in updating code The fault label to jump to on fault of updating the code was misplaced preventing the fault from being recorded. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 9f44623..498608c 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -93,8 +93,8 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, " movb %b4, 4(%2)\n" "2:\n" ".section .fixup, \"ax\"\n" - " movl $1, %0\n" - "3: jmp 2b\n" + "3: movl $1, %0\n" + " jmp 2b\n" ".previous\n" _ASM_EXTABLE(1b, 3b) : "=r"(faulted), "=a"(replaced) -- cgit v0.10.2 From 8f0f996e80b980fba07d11961d96a5fefb60976a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:56 +0200 Subject: ftrace: dont write protect kernel text Dynamic ftrace cant work when the kernel has its text write protected. This patch keeps the kernel from being write protected when dynamic ftrace is in place. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index ec30d10..f96eca2 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -710,6 +710,8 @@ void mark_rodata_ro(void) unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; +#ifndef CONFIG_DYNAMIC_FTRACE + /* Dynamic tracing modifies the kernel text section */ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); @@ -722,6 +724,8 @@ void mark_rodata_ro(void) printk(KERN_INFO "Testing CPA: write protecting again\n"); set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); #endif +#endif /* CONFIG_DYNAMIC_FTRACE */ + start += size; size = (unsigned long)__end_rodata - start; set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 32ba13b..41824e7 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -766,6 +766,13 @@ EXPORT_SYMBOL_GPL(rodata_test_data); void mark_rodata_ro(void) { unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata); + unsigned long rodata_start = + ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; + +#ifdef CONFIG_DYNAMIC_FTRACE + /* Dynamic tracing modifies the kernel text section */ + start = rodata_start; +#endif printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", (end - start) >> 10); @@ -775,8 +782,7 @@ void mark_rodata_ro(void) * The rodata section (but not the kernel text!) should also be * not-executable. */ - start = ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; - set_memory_nx(start, (end - start) >> PAGE_SHIFT); + set_memory_nx(rodata_start, (end - start) >> PAGE_SHIFT); rodata_test(); -- cgit v0.10.2 From 86069782d62e731b4835a0cf8eb7d1d0e17cf306 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: x86: add a list for custom page fault handlers. Provides kernel modules a way to register custom page fault handlers. On every page fault this will call a list of registered functions. The functions may handle the fault and force do_page_fault() to return immediately. This functionality is similar to the now removed page fault notifiers. Custom page fault handlers are used by debugging and reverse engineering tools. Mmiotrace is one such tool and a patch to add it into the tree will follow. The custom page fault handlers are called earlier in do_page_fault() than the page fault notifiers were. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index ac1e31b..9431a83 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -168,6 +168,14 @@ config IOMMU_LEAK 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 PAGE_FAULT_HANDLERS + bool "Custom page fault handlers" + depends on DEBUG_KERNEL + help + Allow the use of custom page fault handlers. A kernel module may + register a function that is called on every page fault. Custom + handlers are used by some debugging and reverse engineering tools. + # # IO delay types: # diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index fd7e179..343f5c1 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -49,6 +49,60 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) +#ifdef CONFIG_PAGE_FAULT_HANDLERS +static HLIST_HEAD(pf_handlers); /* protected by RCU */ +static DEFINE_SPINLOCK(pf_handlers_writer); + +void register_page_fault_handler(struct pf_handler *new_pfh) +{ + unsigned long flags; + spin_lock_irqsave(&pf_handlers_writer, flags); + hlist_add_head_rcu(&new_pfh->hlist, &pf_handlers); + spin_unlock_irqrestore(&pf_handlers_writer, flags); +} +EXPORT_SYMBOL_GPL(register_page_fault_handler); + +/** + * unregister_page_fault_handler: + * The caller must ensure @old_pfh is not in use anymore before freeing it. + * This function does not guarantee it. The list of handlers is protected by + * RCU, so you can do this by e.g. calling synchronize_rcu(). + */ +void unregister_page_fault_handler(struct pf_handler *old_pfh) +{ + unsigned long flags; + spin_lock_irqsave(&pf_handlers_writer, flags); + hlist_del_rcu(&old_pfh->hlist); + spin_unlock_irqrestore(&pf_handlers_writer, flags); +} +EXPORT_SYMBOL_GPL(unregister_page_fault_handler); +#endif + +/* returns non-zero if do_page_fault() should return */ +static int handle_custom_pf(struct pt_regs *regs, unsigned long error_code, + unsigned long address) +{ +#ifdef CONFIG_PAGE_FAULT_HANDLERS + int ret = 0; + struct pf_handler *cur; + struct hlist_node *ncur; + + if (hlist_empty(&pf_handlers)) + return 0; + + rcu_read_lock(); + hlist_for_each_entry_rcu(cur, ncur, &pf_handlers, hlist) { + ret = cur->handler(regs, error_code, address); + if (ret) + break; + } + rcu_read_unlock(); + return ret; +#else + return 0; +#endif +} + static inline int notify_page_fault(struct pt_regs *regs) { #ifdef CONFIG_KPROBES @@ -601,6 +655,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) if (notify_page_fault(regs)) return; + if (handle_custom_pf(regs, error_code, address)) + return; /* * We fault-in kernel-space virtual memory on-demand. The diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index 96651bb..a80f2d6 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -35,4 +35,13 @@ extern void show_regs(struct pt_regs *regs); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); +struct pf_handler { + struct hlist_node hlist; + int (*handler)(struct pt_regs *regs, unsigned long error_code, + unsigned long address); +}; + +extern void register_page_fault_handler(struct pf_handler *new_pfh); +extern void unregister_page_fault_handler(struct pf_handler *old_pfh); + #endif -- cgit v0.10.2 From 72829bc3d63cdc592d8f7dd86ad3b3fe8900fb74 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 21:37:28 +0200 Subject: ftrace: move enums to ftrace.h and make helper function global picked from the mmiotracer patches to distangle the patch queues. Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ea11f4e..0eef050 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -37,7 +37,7 @@ unsigned long __read_mostly tracing_thresh; static int tracing_disabled = 1; -static long +long ns2usecs(cycle_t nsec) { nsec += 500; @@ -96,18 +96,6 @@ unsigned long nsecs_to_usecs(unsigned long nsecs) return nsecs / 1000; } -enum trace_type { - __TRACE_FIRST_TYPE = 0, - - TRACE_FN, - TRACE_CTX, - TRACE_WAKE, - TRACE_STACK, - TRACE_SPECIAL, - - __TRACE_LAST_TYPE -}; - enum trace_flag_type { TRACE_FLAG_IRQS_OFF = 0x01, TRACE_FLAG_NEED_RESCHED = 0x02, @@ -190,7 +178,7 @@ void *head_page(struct trace_array_cpu *data) return page_address(page); } -static int +int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { int len = (PAGE_SIZE - 1) - s->len; @@ -205,7 +193,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) va_end(ap); /* If we can't write it all, don't bother writing anything */ - if (ret > len) + if (ret >= len) return 0; s->len += ret; @@ -638,7 +626,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags) pc = preempt_count(); entry->preempt_count = pc & 0xff; - entry->pid = tsk->pid; + entry->pid = (tsk) ? tsk->pid : 0; entry->t = ftrace_now(raw_smp_processor_id()); entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | @@ -1541,6 +1529,9 @@ static int trace_empty(struct trace_iterator *iter) static int print_trace_line(struct trace_iterator *iter) { + if (iter->trace && iter->trace->print_line) + return iter->trace->print_line(iter); + if (trace_flags & TRACE_ITER_BIN) return print_bin_fmt(iter); @@ -2162,6 +2153,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) return -ENOMEM; iter->tr = &global_trace; + iter->trace = current_trace; filp->private_data = iter; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 25cba28..b0ca747 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -6,6 +6,18 @@ #include #include +enum trace_type { + __TRACE_FIRST_TYPE = 0, + + TRACE_FN, + TRACE_CTX, + TRACE_WAKE, + TRACE_STACK, + TRACE_SPECIAL, + + __TRACE_LAST_TYPE +}; + /* * Function trace entry - function address and parent function addres: */ @@ -130,6 +142,7 @@ struct tracer { int (*selftest)(struct tracer *trace, struct trace_array *tr); #endif + int (*print_line)(struct trace_iterator *iter); struct tracer *next; int print_max; }; @@ -276,6 +289,8 @@ extern int trace_selftest_startup_sched_switch(struct tracer *trace, #endif /* CONFIG_FTRACE_STARTUP_TEST */ extern void *head_page(struct trace_array_cpu *data); +extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); +extern long ns2usecs(cycle_t nsec); extern unsigned long trace_flags; -- cgit v0.10.2 From d17d969160c18b631a19c2b34d260691402650f8 Mon Sep 17 00:00:00 2001 From: Ankita Garg Date: Mon, 12 May 2008 21:20:58 +0200 Subject: ftrace: fix conversion of task state to char in latency tracer The conversion of task states to a character in the sched_switch tracer (part of latency tracer infrastructure), seems to be incorrect. We currently do it by indexing into the state_to_char array using the state value. The state values do not map directly into the array index and are thus incorrect. The following patch addresses this issue. This is also what is being done even in the show_task() routine in kernel/sched.c The patch has been compile and run tested. Signed-off-by: Ankita Garg Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0eef050..9197782 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1208,6 +1208,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) char *comm; int S, T; int i; + unsigned state; if (!next_entry) next_entry = entry; @@ -1238,11 +1239,11 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) break; case TRACE_CTX: case TRACE_WAKE: - S = entry->ctx.prev_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.prev_state] : 'X'; T = entry->ctx.next_state < sizeof(state_to_char) ? state_to_char[entry->ctx.next_state] : 'X'; + state = entry->ctx.prev_state ? __ffs(entry->ctx.prev_state) + 1 : 0; + S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X'; comm = trace_find_cmdline(entry->ctx.next_pid); trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n", entry->ctx.prev_pid, -- cgit v0.10.2 From 8487c23765b6e0444ec6b5f1530766d63fe68e35 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: ftrace: allow trace_pipe to block on all reads We expect things like "cat" to block on reads to trace_pipe. That's what trace_pipe is for. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9197782..fd4ecc2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2231,8 +2231,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, start = 0; while (trace_empty(iter)) { - if (!(trace_flags & TRACE_ITER_BLOCK)) - return -EWOULDBLOCK; /* * This is a make-shift waitqueue. The reason we don't use * an actual wait queue is because: -- cgit v0.10.2 From b5685aede3b7b65e72ddc73b951aa1f70798a614 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: ftrace: restore iterator trace in pipe read The trace iterator is reset in the read. We still need to restore the tracer that the trace_pipe was opened with. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index fd4ecc2..d141fc9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2202,6 +2202,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, { struct trace_iterator *iter = filp->private_data; struct trace_array_cpu *data; + struct trace_array *tr = iter->tr; + struct tracer *tracer = iter->trace; static cpumask_t mask; static int start; unsigned long flags; @@ -2274,7 +2276,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, cnt = PAGE_SIZE - 1; memset(iter, 0, sizeof(*iter)); - iter->tr = &global_trace; + iter->tr = tr; + iter->trace = tracer; iter->pos = -1; /* -- cgit v0.10.2 From 845279972f1736c3463c9cebd1bad92a0a347176 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: ftrace: return EOF in trace_pipe on change of tracer Break out of while loop with EOF when the current_trace changes. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d141fc9..2af9404 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2253,6 +2253,9 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, if (signal_pending(current)) return -EINTR; + if (iter->trace != current_trace) + return 0; + /* * We block until we read something and tracing is disabled. * We still block if tracing is disabled, but we have never -- cgit v0.10.2 From 2dc8f09571a61d9cb3dc47bba6608689dfe15d16 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:58 +0200 Subject: ftrace: trace_pipe implement NONBLOCK This patch implements "NONBLOCK" for trace_pipe. If the trace_pipe is opened with O_NONBLOCK, then the trace_pipe read will not block when buffer is empty. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2af9404..3b4eaf3 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2233,6 +2233,10 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, start = 0; while (trace_empty(iter)) { + + if ((filp->f_flags & O_NONBLOCK)) + return -EAGAIN; + /* * This is a make-shift waitqueue. The reason we don't use * an actual wait queue is because: -- cgit v0.10.2 From 05bd68c514579e007b46e4fa0461b78416a3f4c2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:59 +0200 Subject: ftrace: user proper API for setting RT prios in selftest The wakeup selftest used an internal API for setting the test task priority. This patch fixes it to use the proper API for performing such a task. Thanks goes to Randy Dunlap for pointing out this build failure. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 395274e..a5f6001 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -410,11 +410,11 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * #ifdef CONFIG_SCHED_TRACER static int trace_wakeup_test_thread(void *data) { - struct completion *x = data; - /* Make this a RT thread, doesn't need to be too high */ + struct sched_param param = { .sched_priority = 5 }; + struct completion *x = data; - rt_mutex_setprio(current, MAX_RT_PRIO - 5); + sched_setscheduler(current, SCHED_FIFO, ¶m); /* Make it know we have a new prio */ complete(x); -- cgit v0.10.2 From a98a3c3fde3ae7614f19758a043691b6f59dac53 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:20:59 +0200 Subject: ftrace: trace_entries to dynamically change trace buffer size This patch adds /debug/tracing/trace_entries that allows users to see as well as modify the number of trace entries the buffers hold. The number of entries only increments in ENTRIES_PER_PAGE which is calculated by the size of an entry with the number of entries that can fit in a page. The user does not need to use an exact size, but the entries will be rounded to one of the increments. Trying to set the entries to 0 will return with -EINVAL. To avoid race conditions, the modification of the buffer size can only be done when tracing is completely disabled (current_tracer == none). A info message will be printed if a user tries to modify the buffer size when not set to none. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3b4eaf3..4723e01 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -35,6 +35,15 @@ unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; unsigned long __read_mostly tracing_thresh; +/* dummy trace to disable tracing */ +static struct tracer no_tracer __read_mostly = +{ + .name = "none", +}; + +static int trace_alloc_page(void); +static int trace_free_page(void); + static int tracing_disabled = 1; long @@ -2364,6 +2373,70 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, return read; } +static ssize_t +tracing_entries_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct trace_array *tr = filp->private_data; + char buf[64]; + int r; + + r = sprintf(buf, "%lu\n", tr->entries); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t +tracing_entries_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + unsigned long val; + char buf[64]; + + if (cnt > 63) + cnt = 63; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + val = simple_strtoul(buf, NULL, 10); + + /* must have at least 1 entry */ + if (!val) + return -EINVAL; + + mutex_lock(&trace_types_lock); + + if (current_trace != &no_tracer) { + cnt = -EBUSY; + pr_info("ftrace: set current_tracer to none" + " before modifying buffer size\n"); + goto out; + } + + if (val > global_trace.entries) { + while (global_trace.entries < val) { + if (trace_alloc_page()) { + cnt = -ENOMEM; + goto out; + } + } + } else { + /* include the number of entries in val (inc of page entries) */ + while (global_trace.entries > val + (ENTRIES_PER_PAGE - 1)) + trace_free_page(); + } + + filp->f_pos += cnt; + + out: + max_tr.entries = global_trace.entries; + mutex_unlock(&trace_types_lock); + + return cnt; +} + static struct file_operations tracing_max_lat_fops = { .open = tracing_open_generic, .read = tracing_max_lat_read, @@ -2389,6 +2462,12 @@ static struct file_operations tracing_pipe_fops = { .release = tracing_release_pipe, }; +static struct file_operations tracing_entries_fops = { + .open = tracing_open_generic, + .read = tracing_entries_read, + .write = tracing_entries_write, +}; + #ifdef CONFIG_DYNAMIC_FTRACE static ssize_t @@ -2500,6 +2579,12 @@ static __init void tracer_init_debugfs(void) pr_warning("Could not create debugfs " "'tracing_threash' entry\n"); + entry = debugfs_create_file("trace_entries", 0644, d_tracer, + &global_trace, &tracing_entries_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'tracing_threash' entry\n"); + #ifdef CONFIG_DYNAMIC_FTRACE entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, &ftrace_update_tot_cnt, @@ -2510,12 +2595,6 @@ static __init void tracer_init_debugfs(void) #endif } -/* dummy trace to disable tracing */ -static struct tracer no_tracer __read_mostly = -{ - .name = "none", -}; - static int trace_alloc_page(void) { struct trace_array_cpu *data; @@ -2552,7 +2631,6 @@ static int trace_alloc_page(void) /* Now that we successfully allocate a page per CPU, add them */ for_each_possible_cpu(i) { data = global_trace.data[i]; - data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); @@ -2560,7 +2638,6 @@ static int trace_alloc_page(void) #ifdef CONFIG_TRACER_MAX_TRACE data = max_tr.data[i]; - data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); list_add_tail(&page->lru, &data->trace_pages); @@ -2579,6 +2656,55 @@ static int trace_alloc_page(void) return -ENOMEM; } +static int trace_free_page(void) +{ + struct trace_array_cpu *data; + struct page *page; + struct list_head *p; + int i; + int ret = 0; + + /* free one page from each buffer */ + for_each_possible_cpu(i) { + data = global_trace.data[i]; + p = data->trace_pages.next; + if (p == &data->trace_pages) { + /* should never happen */ + WARN_ON(1); + tracing_disabled = 1; + ret = -1; + break; + } + page = list_entry(p, struct page, lru); + ClearPageLRU(page); + list_del(&page->lru); + __free_page(page); + + tracing_reset(data); + +#ifdef CONFIG_TRACER_MAX_TRACE + data = max_tr.data[i]; + p = data->trace_pages.next; + if (p == &data->trace_pages) { + /* should never happen */ + WARN_ON(1); + tracing_disabled = 1; + ret = -1; + break; + } + page = list_entry(p, struct page, lru); + ClearPageLRU(page); + list_del(&page->lru); + __free_page(page); + + tracing_reset(data); +#endif + } + global_trace.entries -= ENTRIES_PER_PAGE; + + return ret; +} + __init static int tracer_alloc_buffers(void) { struct trace_array_cpu *data; @@ -2609,6 +2735,9 @@ __init static int tracer_alloc_buffers(void) /* use the LRU flag to differentiate the two buffers */ ClearPageLRU(page); + data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + max_tr.data[i]->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + /* Only allocate if we are actually using the max trace */ #ifdef CONFIG_TRACER_MAX_TRACE array = (void *)__get_free_page(GFP_KERNEL); -- cgit v0.10.2 From bb065afb8ebd07a03155502dba29ebf0f6fe67e8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: lockdep: update lockdep_recursion on graph_lock With the introduction of ftrace, it is possible to recurse into the lockdep functions via the mcount call. To prevent possible lockups, updating the lockdep_recursion counter on grabbing the internal lockdep_lock should prevent deadlocks. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 90a440c..65548ef 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -82,6 +82,8 @@ static int graph_lock(void) __raw_spin_unlock(&lockdep_lock); return 0; } + /* prevent any recursions within lockdep from causing deadlocks */ + current->lockdep_recursion++; return 1; } @@ -90,6 +92,7 @@ static inline int graph_unlock(void) if (debug_locks && !__raw_spin_is_locked(&lockdep_lock)) return DEBUG_LOCKS_WARN_ON(1); + current->lockdep_recursion--; __raw_spin_unlock(&lockdep_lock); return 0; } -- cgit v0.10.2 From 93dcc6ea096c51cc30ad0f6647ed05fead2439bf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: simplify hexprint simplify hex to ascii conversion. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 4723e01..627e399 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -248,19 +248,18 @@ trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) } #define HEX_CHARS 17 +static const char hex2asc[] = "0123456789abcdef"; static int trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len) { unsigned char hex[HEX_CHARS]; - unsigned char *data; + unsigned char *data = mem; unsigned char byte; int i, j; BUG_ON(len >= HEX_CHARS); - data = mem; - #ifdef __BIG_ENDIAN for (i = 0, j = 0; i < len; i++) { #else @@ -268,22 +267,10 @@ trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len) #endif byte = data[i]; - hex[j] = byte & 0x0f; - if (hex[j] >= 10) - hex[j] += 'a' - 10; - else - hex[j] += '0'; - j++; - - hex[j] = byte >> 4; - if (hex[j] >= 10) - hex[j] += 'a' - 10; - else - hex[j] += '0'; - j++; + hex[j++] = hex2asc[byte & 0x0f]; + hex[j++] = hex2asc[byte >> 4]; } - hex[j] = ' '; - j++; + hex[j++] = ' '; return trace_seq_putmem(s, hex, j); } -- cgit v0.10.2 From afc2abc0ae4265730a0fc48618012193a09a1d10 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: cleanups no code changed. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 627e399..d6b6057 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1155,12 +1155,12 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) hardirq = entry->flags & TRACE_FLAG_HARDIRQ; softirq = entry->flags & TRACE_FLAG_SOFTIRQ; - if (hardirq && softirq) + if (hardirq && softirq) { trace_seq_putc(s, 'H'); - else { - if (hardirq) + } else { + if (hardirq) { trace_seq_putc(s, 'h'); - else { + } else { if (softirq) trace_seq_putc(s, 's'); else @@ -2177,8 +2177,7 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table) * Always select as readable when in blocking mode */ return POLLIN | POLLRDNORM; - } - else { + } else { if (!trace_empty(iter)) return POLLIN | POLLRDNORM; poll_wait(filp, &trace_wait, poll_table); -- cgit v0.10.2 From cffae437cdfbc8a5370d38cefbff1dfe34dad6ca Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: simple clean ups Andrew Morton mentioned some clean ups that should be done to ftrace. This patch does some of the simple clean ups. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d6b6057..0a36736 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -36,8 +36,7 @@ unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; unsigned long __read_mostly tracing_thresh; /* dummy trace to disable tracing */ -static struct tracer no_tracer __read_mostly = -{ +static struct tracer no_tracer __read_mostly = { .name = "none", }; @@ -1906,8 +1905,8 @@ tracing_iter_ctrl_write(struct file *filp, const char __user *ubuf, int neg = 0; int i; - if (cnt > 63) - cnt = 63; + if (cnt >= sizeof(buf)) + return -EINVAL; if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; @@ -1999,8 +1998,8 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf, long val; char buf[64]; - if (cnt > 63) - cnt = 63; + if (cnt >= sizeof(buf)) + return -EINVAL; if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; @@ -2099,10 +2098,10 @@ tracing_max_lat_read(struct file *filp, char __user *ubuf, char buf[64]; int r; - r = snprintf(buf, 64, "%ld\n", + r = snprintf(buf, sizeof(buf), "%ld\n", *ptr == (unsigned long)-1 ? -1 : nsecs_to_usecs(*ptr)); - if (r > 64) - r = 64; + if (r > sizeof(buf)) + r = sizeof(buf); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -2114,8 +2113,8 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, long val; char buf[64]; - if (cnt > 63) - cnt = 63; + if (cnt >= sizeof(buf)) + return -EINVAL; if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; @@ -2378,8 +2377,8 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, unsigned long val; char buf[64]; - if (cnt > 63) - cnt = 63; + if (cnt >= sizeof(buf)) + return -EINVAL; if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; -- cgit v0.10.2 From c6caeeb142cd3a03c46107aac45c8effc02bbadb Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: replace simple_strtoul with strict_strtoul Andrew Morton suggested using strict_strtoul over simple_strtoul. This patch replaces them in ftrace. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0a36736..290e9da 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -92,9 +92,16 @@ void trace_wake_up(void) static int __init set_nr_entries(char *str) { + unsigned long nr_entries; + int ret; + if (!str) return 0; - trace_nr_entries = simple_strtoul(str, &str, 0); + ret = strict_strtoul(str, 0, &nr_entries); + /* nr_entries can not be zero */ + if (ret < 0 || nr_entries == 0) + return 0; + trace_nr_entries = nr_entries; return 1; } __setup("trace_entries=", set_nr_entries); @@ -1995,8 +2002,9 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { struct trace_array *tr = filp->private_data; - long val; char buf[64]; + long val; + int ret; if (cnt >= sizeof(buf)) return -EINVAL; @@ -2006,7 +2014,9 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf, buf[cnt] = 0; - val = simple_strtoul(buf, NULL, 10); + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + return ret; val = !!val; @@ -2110,8 +2120,9 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { long *ptr = filp->private_data; - long val; char buf[64]; + long val; + int ret; if (cnt >= sizeof(buf)) return -EINVAL; @@ -2121,7 +2132,9 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, buf[cnt] = 0; - val = simple_strtoul(buf, NULL, 10); + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + return ret; *ptr = val * 1000; @@ -2376,6 +2389,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, { unsigned long val; char buf[64]; + int ret; if (cnt >= sizeof(buf)) return -EINVAL; @@ -2385,7 +2399,9 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, buf[cnt] = 0; - val = simple_strtoul(buf, NULL, 10); + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + return ret; /* must have at least 1 entry */ if (!val) -- cgit v0.10.2 From ab46428c6969d50ecf6f6e97b7a84abba6274368 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: modulize the number of CPU buffers Currently ftrace allocates a trace buffer for every possible CPU. Work is being done to change it to only online CPUs and add hooks to hotplug CPUS. This patch lays out the infrastructure for such a change. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 290e9da..5da391c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -35,6 +35,12 @@ unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; unsigned long __read_mostly tracing_thresh; +static unsigned long __read_mostly tracing_nr_buffers; +static cpumask_t __read_mostly tracing_buffer_mask; + +#define for_each_tracing_cpu(cpu) \ + for_each_cpu_mask(cpu, tracing_buffer_mask) + /* dummy trace to disable tracing */ static struct tracer no_tracer __read_mostly = { .name = "none", @@ -328,7 +334,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) WARN_ON_ONCE(!irqs_disabled()); __raw_spin_lock(&ftrace_max_lock); /* clear out all the previous traces */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { data = tr->data[i]; flip_trace(max_tr.data[i], data); tracing_reset(data); @@ -352,7 +358,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) WARN_ON_ONCE(!irqs_disabled()); __raw_spin_lock(&ftrace_max_lock); - for_each_possible_cpu(i) + for_each_tracing_cpu(i) tracing_reset(max_tr.data[i]); flip_trace(max_tr.data[cpu], data); @@ -398,7 +404,7 @@ int register_tracer(struct tracer *type) * internal tracing to verify that everything is in order. * If we fail, we do not register this tracer. */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { data = tr->data[i]; if (!head_page(data)) continue; @@ -417,7 +423,7 @@ int register_tracer(struct tracer *type) goto out; } /* Only reset on passing, to avoid touching corrupted buffers */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { data = tr->data[i]; if (!head_page(data)) continue; @@ -847,7 +853,7 @@ find_next_entry(struct trace_iterator *iter, int *ent_cpu) int next_cpu = -1; int cpu; - for_each_possible_cpu(cpu) { + for_each_tracing_cpu(cpu) { if (!head_page(tr->data[cpu])) continue; ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu); @@ -972,7 +978,7 @@ static void *s_start(struct seq_file *m, loff_t *pos) iter->prev_ent = NULL; iter->prev_cpu = -1; - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { iter->next_idx[i] = 0; iter->next_page[i] = NULL; } @@ -1089,7 +1095,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) if (type) name = type->name; - for_each_possible_cpu(cpu) { + for_each_tracing_cpu(cpu) { if (head_page(tr->data[cpu])) { total += tr->data[cpu]->trace_idx; if (tr->data[cpu]->trace_idx > tr->entries) @@ -1519,7 +1525,7 @@ static int trace_empty(struct trace_iterator *iter) struct trace_array_cpu *data; int cpu; - for_each_possible_cpu(cpu) { + for_each_tracing_cpu(cpu) { data = iter->tr->data[cpu]; if (head_page(data) && data->trace_idx && @@ -1831,7 +1837,7 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, raw_local_irq_disable(); __raw_spin_lock(&ftrace_max_lock); - for_each_possible_cpu(cpu) { + for_each_tracing_cpu(cpu) { /* * Increase/decrease the disabled counter if we are * about to flip a bit in the cpumask: @@ -2308,7 +2314,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, ftrace_enabled = 0; #endif smp_wmb(); - for_each_possible_cpu(cpu) { + for_each_tracing_cpu(cpu) { data = iter->tr->data[cpu]; if (!head_page(data) || !data->trace_idx) @@ -2605,7 +2611,7 @@ static int trace_alloc_page(void) int i; /* first allocate a page for each CPU */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { array = (void *)__get_free_page(GFP_KERNEL); if (array == NULL) { printk(KERN_ERR "tracer: failed to allocate page" @@ -2630,7 +2636,7 @@ static int trace_alloc_page(void) } /* Now that we successfully allocate a page per CPU, add them */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { data = global_trace.data[i]; page = list_entry(pages.next, struct page, lru); list_del_init(&page->lru); @@ -2666,7 +2672,7 @@ static int trace_free_page(void) int ret = 0; /* free one page from each buffer */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { data = global_trace.data[i]; p = data->trace_pages.next; if (p == &data->trace_pages) { @@ -2717,8 +2723,12 @@ __init static int tracer_alloc_buffers(void) global_trace.ctrl = tracer_enabled; + /* TODO: make the number of buffers hot pluggable with CPUS */ + tracing_nr_buffers = num_possible_cpus(); + tracing_buffer_mask = cpu_possible_map; + /* Allocate the first page for all buffers */ - for_each_possible_cpu(i) { + for_each_tracing_cpu(i) { data = global_trace.data[i] = &per_cpu(global_trace_cpu, i); max_tr.data[i] = &per_cpu(max_data, i); -- cgit v0.10.2 From 4fcdae83cebda24b519a89d3dd976081fff1ca80 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: comment code This is first installment of adding documentation to the ftrace. Expect many more patches of this kind in the near future. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 5da391c..a102b11 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -64,26 +64,79 @@ cycle_t ftrace_now(int cpu) return cpu_clock(cpu); } +/* + * The global_trace is the descriptor that holds the tracing + * buffers for the live tracing. For each CPU, it contains + * a link list of pages that will store trace entries. The + * page descriptor of the pages in the memory is used to hold + * the link list by linking the lru item in the page descriptor + * to each of the pages in the buffer per CPU. + * + * For each active CPU there is a data field that holds the + * pages for the buffer for that CPU. Each CPU has the same number + * of pages allocated for its buffer. + */ static struct trace_array global_trace; static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); +/* + * The max_tr is used to snapshot the global_trace when a maximum + * latency is reached. Some tracers will use this to store a maximum + * trace while it continues examining live traces. + * + * The buffers for the max_tr are set up the same as the global_trace. + * When a snapshot is taken, the link list of the max_tr is swapped + * with the link list of the global_trace and the buffers are reset for + * the global_trace so the tracing can continue. + */ static struct trace_array max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_data); +/* tracer_enabled is used to toggle activation of a tracer */ static int tracer_enabled = 1; + +/* + * trace_nr_entries is the number of entries that is allocated + * for a buffer. Note, the number of entries is always rounded + * to ENTRIES_PER_PAGE. + */ static unsigned long trace_nr_entries = 65536UL; +/* trace_types holds a link list of available tracers. */ static struct tracer *trace_types __read_mostly; + +/* current_trace points to the tracer that is currently active */ static struct tracer *current_trace __read_mostly; + +/* + * max_tracer_type_len is used to simplify the allocating of + * buffers to read userspace tracer names. We keep track of + * the longest tracer name registered. + */ static int max_tracer_type_len; +/* + * trace_types_lock is used to protect the trace_types list. + * This lock is also used to keep user access serialized. + * Accesses from userspace will grab this lock while userspace + * activities happen inside the kernel. + */ static DEFINE_MUTEX(trace_types_lock); + +/* trace_wait is a waitqueue for tasks blocked on trace_poll */ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); +/* trace_flags holds iter_ctrl options */ unsigned long trace_flags = TRACE_ITER_PRINT_PARENT; +/** + * trace_wake_up - wake up tasks waiting for trace input + * + * Simply wakes up any task that is blocked on the trace_wait + * queue. These is used with trace_poll for tasks polling the trace. + */ void trace_wake_up(void) { /* @@ -117,6 +170,14 @@ unsigned long nsecs_to_usecs(unsigned long nsecs) return nsecs / 1000; } +/* + * trace_flag_type is an enumeration that holds different + * states when a trace occurs. These are: + * IRQS_OFF - interrupts were disabled + * NEED_RESCED - reschedule is requested + * HARDIRQ - inside an interrupt handler + * SOFTIRQ - inside a softirq handler + */ enum trace_flag_type { TRACE_FLAG_IRQS_OFF = 0x01, TRACE_FLAG_NEED_RESCHED = 0x02, @@ -124,10 +185,14 @@ enum trace_flag_type { TRACE_FLAG_SOFTIRQ = 0x08, }; +/* + * TRACE_ITER_SYM_MASK masks the options in trace_flags that + * control the output of kernel symbols. + */ #define TRACE_ITER_SYM_MASK \ (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) -/* These must match the bit postions above */ +/* These must match the bit postions in trace_iterator_flags */ static const char *trace_options[] = { "print-parent", "sym-offset", @@ -142,6 +207,15 @@ static const char *trace_options[] = { NULL }; +/* + * ftrace_max_lock is used to protect the swapping of buffers + * when taking a max snapshot. The buffers themselves are + * protected by per_cpu spinlocks. But the action of the swap + * needs its own lock. + * + * This is defined as a raw_spinlock_t in order to help + * with performance when lockdep debugging is enabled. + */ static raw_spinlock_t ftrace_max_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; @@ -172,6 +246,13 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) tracing_record_cmdline(current); } +/** + * check_pages - integrity check of trace buffers + * + * As a safty measure we check to make sure the data pages have not + * been corrupted. TODO: configure to disable this because it adds + * a bit of overhead. + */ void check_pages(struct trace_array_cpu *data) { struct page *page, *tmp; @@ -185,6 +266,13 @@ void check_pages(struct trace_array_cpu *data) } } +/** + * head_page - page address of the first page in per_cpu buffer. + * + * head_page returns the page address of the first page in + * a per_cpu buffer. This also preforms various consistency + * checks to make sure the buffer has not been corrupted. + */ void *head_page(struct trace_array_cpu *data) { struct page *page; @@ -199,6 +287,17 @@ void *head_page(struct trace_array_cpu *data) return page_address(page); } +/** + * trace_seq_printf - sequence printing of trace information + * @s: trace sequence descriptor + * @fmt: printf format string + * + * The tracer may use either sequence operations or its own + * copy to user routines. To simplify formating of a trace + * trace_seq_printf is used to store strings into a special + * buffer (@s). Then the output may be either used by + * the sequencer or pulled into another buffer. + */ int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { @@ -222,6 +321,16 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) return len; } +/** + * trace_seq_puts - trace sequence printing of simple string + * @s: trace sequence descriptor + * @str: simple string to record + * + * The tracer may use either the sequence operations or its own + * copy to user routines. This function records a simple string + * into a special buffer (@s) for later retrieval by a sequencer + * or other mechanism. + */ static int trace_seq_puts(struct trace_seq *s, const char *str) { @@ -304,6 +413,13 @@ trace_print_seq(struct seq_file *m, struct trace_seq *s) trace_seq_reset(s); } +/* + * flip the trace buffers between two trace descriptors. + * This usually is the buffers between the global_trace and + * the max_tr to record a snapshot of a current trace. + * + * The ftrace_max_lock must be held. + */ static void flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) { @@ -325,6 +441,15 @@ flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2) check_pages(tr2); } +/** + * update_max_tr - snapshot all trace buffers from global_trace to max_tr + * @tr: tracer + * @tsk: the task with the latency + * @cpu: The cpu that initiated the trace. + * + * Flip the buffers between the @tr and the max_tr and record information + * about which task was the cause of this latency. + */ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { @@ -349,6 +474,8 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) * @tr - tracer * @tsk - task with the latency * @cpu - the cpu of the buffer to copy. + * + * Flip the trace of a single CPU buffer between the @tr and the max_tr. */ void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) @@ -368,6 +495,12 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) __raw_spin_unlock(&ftrace_max_lock); } +/** + * register_tracer - register a tracer with the ftrace system. + * @type - the plugin for the tracer + * + * Register a new plugin tracer. + */ int register_tracer(struct tracer *type) { struct tracer *t; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b0ca747..21c29ee 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -294,6 +294,13 @@ extern long ns2usecs(cycle_t nsec); extern unsigned long trace_flags; +/* + * trace_iterator_flags is an enumeration that defines bit + * positions into trace_flags that controls the output. + * + * NOTE: These bits must match the trace_options array in + * trace.c. + */ enum trace_iterator_flags { TRACE_ITER_PRINT_PARENT = 0x01, TRACE_ITER_SYM_OFFSET = 0x02, -- cgit v0.10.2 From 25b0b44a1c732ccfc58095cdd8438955a0a19fff Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:00 +0200 Subject: ftrace: fix comm on function trace output In cleaning up of the sched_switch code, the function trace recording of task comms was removed. This patch adds back the recording of comms for function trace. The output of ftrace now has the task comm instead of <...>. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a102b11..1281969 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -620,7 +620,12 @@ static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; static int cmdline_idx; static DEFINE_SPINLOCK(trace_cmdline_lock); -atomic_t trace_record_cmdline_disabled; + +/* trace in all context switches */ +atomic_t trace_record_cmdline_enabled __read_mostly; + +/* temporary disable recording */ +atomic_t trace_record_cmdline_disabled __read_mostly; static void trace_init_cmdlines(void) { diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 21c29ee..8991c5e 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -216,6 +216,8 @@ extern unsigned long nsecs_to_usecs(unsigned long nsecs); extern unsigned long tracing_max_latency; extern unsigned long tracing_thresh; +extern atomic_t trace_record_cmdline_enabled; + void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu); diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 4165d34..0a08465 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -29,12 +29,14 @@ static void function_reset(struct trace_array *tr) static void start_function_trace(struct trace_array *tr) { function_reset(tr); + atomic_inc(&trace_record_cmdline_enabled); tracing_start_function_trace(); } static void stop_function_trace(struct trace_array *tr) { tracing_stop_function_trace(); + atomic_dec(&trace_record_cmdline_enabled); } static void function_trace_init(struct trace_array *tr) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 5671db0..a337647 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -29,8 +29,6 @@ ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) if (!tracer_enabled) return; - tracing_record_cmdline(prev); - local_irq_save(flags); cpu = raw_smp_processor_id(); data = tr->data[cpu]; @@ -73,6 +71,9 @@ void ftrace_ctx_switch(void *__rq, struct task_struct *prev, struct task_struct *next) { + if (unlikely(atomic_read(&trace_record_cmdline_enabled))) + tracing_record_cmdline(prev); + /* * If tracer_switch_func only points to the local * switch func, it still needs the ptr passed to it. @@ -134,11 +135,13 @@ static void sched_switch_reset(struct trace_array *tr) static void start_sched_trace(struct trace_array *tr) { sched_switch_reset(tr); + atomic_inc(&trace_record_cmdline_enabled); tracer_enabled = 1; } static void stop_sched_trace(struct trace_array *tr) { + atomic_dec(&trace_record_cmdline_enabled); tracer_enabled = 0; } -- cgit v0.10.2 From 72b59d67f80983f7bb587b086fb4cb1bc95263a4 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:01 +0200 Subject: x86_64: fix kernel rodata NX setting Without CONFIG_DYNAMIC_FTRACE, mark_rodata_ro() would mark a wrong number of pages as no-execute. The bug was introduced in the patch "ftrace: dont write protect kernel text". The symptom was machine reboot after a CPU hotplug. Signed-off-by: Pekka Paalanen Acked-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 41824e7..295be1d 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -782,7 +782,7 @@ void mark_rodata_ro(void) * The rodata section (but not the kernel text!) should also be * not-executable. */ - set_memory_nx(rodata_start, (end - start) >> PAGE_SHIFT); + set_memory_nx(rodata_start, (end - rodata_start) >> PAGE_SHIFT); rodata_test(); -- cgit v0.10.2 From 53d0aa773053ab18287781e25d52c5faf9e0e09e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:01 +0200 Subject: ftrace: add logic to record overruns This patch sets up the infrastructure to record overruns of the tracing buffer. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1281969..b9126ef 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -609,6 +609,7 @@ void unregister_tracer(struct tracer *type) void tracing_reset(struct trace_array_cpu *data) { data->trace_idx = 0; + data->overrun = 0; data->trace_head = data->trace_tail = head_page(data); data->trace_head_idx = 0; data->trace_tail_idx = 0; @@ -750,6 +751,7 @@ tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data) if (data->trace_head == data->trace_tail && idx_next == data->trace_tail_idx) { /* overrun */ + data->overrun++; data->trace_tail_idx++; if (data->trace_tail_idx >= ENTRIES_PER_PAGE) { data->trace_tail = @@ -2353,8 +2355,6 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, { struct trace_iterator *iter = filp->private_data; struct trace_array_cpu *data; - struct trace_array *tr = iter->tr; - struct tracer *tracer = iter->trace; static cpumask_t mask; static int start; unsigned long flags; @@ -2433,10 +2433,11 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, if (cnt >= PAGE_SIZE) cnt = PAGE_SIZE - 1; - memset(iter, 0, sizeof(*iter)); - iter->tr = tr; - iter->trace = tracer; + /* reset all but tr, trace, and overruns */ iter->pos = -1; + memset(&iter->seq, 0, + sizeof(struct trace_iterator) - + offsetof(struct trace_iterator, seq)); /* * We need to stop all tracing on all CPUS to read the @@ -2465,6 +2466,11 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, for_each_cpu_mask(cpu, mask) { data = iter->tr->data[cpu]; __raw_spin_lock(&data->lock); + + if (data->overrun > iter->last_overrun[cpu]) + iter->overrun[cpu] += + data->overrun - iter->last_overrun[cpu]; + iter->last_overrun[cpu] = data->overrun; } while (find_next_entry_inc(iter) != NULL) { diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8991c5e..c1ec134 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -97,6 +97,7 @@ struct trace_array_cpu { void *trace_head; /* producer */ void *trace_tail; /* consumer */ unsigned long trace_idx; + unsigned long overrun; unsigned long saved_latency; unsigned long critical_start; unsigned long critical_end; @@ -157,10 +158,13 @@ struct trace_seq { * results to users and which routines might sleep, etc: */ struct trace_iterator { - struct trace_seq seq; struct trace_array *tr; struct tracer *trace; + long last_overrun[NR_CPUS]; + long overrun[NR_CPUS]; + /* The below is zeroed out in pipe_read */ + struct trace_seq seq; struct trace_entry *ent; int cpu; -- cgit v0.10.2 From 107bad8bef5ab2c3a3bff7648c18c9dc3abdc13b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:01 +0200 Subject: ftrace: add trace pipe header pluggin This patch adds a method for open_pipe and open_read to the pluggins so that they can add a header to the trace pipe call. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b9126ef..32f9106 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2307,11 +2307,15 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) if (!iter) return -ENOMEM; + mutex_lock(&trace_types_lock); iter->tr = &global_trace; iter->trace = current_trace; - filp->private_data = iter; + if (iter->trace->pipe_open) + iter->trace->pipe_open(iter); + mutex_unlock(&trace_types_lock); + return 0; } @@ -2380,13 +2384,24 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, return cnt; } + mutex_lock(&trace_types_lock); + if (iter->trace->read) { + ret = iter->trace->read(iter, filp, ubuf, cnt, ppos); + if (ret) { + read = ret; + goto out; + } + } + trace_seq_reset(&iter->seq); start = 0; while (trace_empty(iter)) { - if ((filp->f_flags & O_NONBLOCK)) - return -EAGAIN; + if ((filp->f_flags & O_NONBLOCK)) { + read = -EAGAIN; + goto out; + } /* * This is a make-shift waitqueue. The reason we don't use @@ -2400,16 +2415,22 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, set_current_state(TASK_INTERRUPTIBLE); iter->tr->waiter = current; + mutex_unlock(&trace_types_lock); + /* sleep for one second, and try again. */ schedule_timeout(HZ); + mutex_lock(&trace_types_lock); + iter->tr->waiter = NULL; - if (signal_pending(current)) - return -EINTR; + if (signal_pending(current)) { + read = -EINTR; + goto out; + } if (iter->trace != current_trace) - return 0; + goto out; /* * We block until we read something and tracing is disabled. @@ -2428,7 +2449,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, /* stop when tracing is finished */ if (trace_empty(iter)) - return 0; + goto out; if (cnt >= PAGE_SIZE) cnt = PAGE_SIZE - 1; @@ -2518,6 +2539,9 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, if (ret) read = -EFAULT; +out: + mutex_unlock(&trace_types_lock); + return read; } diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c1ec134..ee53d70 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -135,9 +135,13 @@ struct tracer { void (*init)(struct trace_array *tr); void (*reset)(struct trace_array *tr); void (*open)(struct trace_iterator *iter); + void (*pipe_open)(struct trace_iterator *iter); void (*close)(struct trace_iterator *iter); void (*start)(struct trace_iterator *iter); void (*stop)(struct trace_iterator *iter); + ssize_t (*read)(struct trace_iterator *iter, + struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos); void (*ctrl_update)(struct trace_array *tr); #ifdef CONFIG_FTRACE_STARTUP_TEST int (*selftest)(struct tracer *trace, @@ -160,6 +164,7 @@ struct trace_seq { struct trace_iterator { struct trace_array *tr; struct tracer *trace; + void *private; long last_overrun[NR_CPUS]; long overrun[NR_CPUS]; -- cgit v0.10.2 From 2f1dafe50cc4e58a239fd81bd47f87f32042a1ee Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:01 +0200 Subject: x86: fix SMP alternatives: use mutex instead of spinlock, text_poke is sleepable text_poke is sleepable. The original fix by Mathieu Desnoyers . Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index de240ba..2763cb3 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -279,7 +279,7 @@ struct smp_alt_module { struct list_head next; }; static LIST_HEAD(smp_alt_modules); -static DEFINE_SPINLOCK(smp_alt); +static DEFINE_MUTEX(smp_alt); static int smp_mode = 1; /* protected by smp_alt */ void alternatives_smp_module_add(struct module *mod, char *name, @@ -312,12 +312,12 @@ void alternatives_smp_module_add(struct module *mod, char *name, __func__, smp->locks, smp->locks_end, smp->text, smp->text_end, smp->name); - spin_lock(&smp_alt); + mutex_lock(&smp_alt); list_add_tail(&smp->next, &smp_alt_modules); if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(smp->locks, smp->locks_end, smp->text, smp->text_end); - spin_unlock(&smp_alt); + mutex_unlock(&smp_alt); } void alternatives_smp_module_del(struct module *mod) @@ -327,17 +327,17 @@ void alternatives_smp_module_del(struct module *mod) if (smp_alt_once || noreplace_smp) return; - spin_lock(&smp_alt); + mutex_lock(&smp_alt); list_for_each_entry(item, &smp_alt_modules, next) { if (mod != item->mod) continue; list_del(&item->next); - spin_unlock(&smp_alt); + mutex_unlock(&smp_alt); DPRINTK("%s: %s\n", __func__, item->name); kfree(item); return; } - spin_unlock(&smp_alt); + mutex_unlock(&smp_alt); } void alternatives_smp_switch(int smp) @@ -359,7 +359,7 @@ void alternatives_smp_switch(int smp) return; BUG_ON(!smp && (num_online_cpus() > 1)); - spin_lock(&smp_alt); + mutex_lock(&smp_alt); /* * Avoid unnecessary switches because it forces JIT based VMs to @@ -383,7 +383,7 @@ void alternatives_smp_switch(int smp) mod->text, mod->text_end); } smp_mode = smp; - spin_unlock(&smp_alt); + mutex_unlock(&smp_alt); } #endif -- cgit v0.10.2 From 4823ed7eadf35e4b57ce581327e21d39585f1f32 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:01 +0200 Subject: ftrace: fix setting of pos in read_pipe In resetting the iterator in read_pipe, the reset of pos was postitioned in the wrong location with respect to the memset operation. The current code sets pos, incorrectly, to zero. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 32f9106..49e1663 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2455,10 +2455,10 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, cnt = PAGE_SIZE - 1; /* reset all but tr, trace, and overruns */ - iter->pos = -1; memset(&iter->seq, 0, sizeof(struct trace_iterator) - offsetof(struct trace_iterator, seq)); + iter->pos = -1; /* * We need to stop all tracing on all CPUS to read the -- cgit v0.10.2 From 9fe068e92f6290e89e19adc521441661a1229f00 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:02 +0200 Subject: ftrace: trace faster Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 49e1663..ca0d6ff 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2417,8 +2417,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, mutex_unlock(&trace_types_lock); - /* sleep for one second, and try again. */ - schedule_timeout(HZ); + /* sleep for 100 msecs, and try again. */ + schedule_timeout(HZ/10); mutex_lock(&trace_types_lock); -- cgit v0.10.2 From a4feb8348b62fe76a63cdb5569f5c920f5283c06 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:02 +0200 Subject: ftrace: special stacktrace Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ca0d6ff..c232d82 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -808,29 +808,6 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, trace_function(tr, data, ip, parent_ip, flags); } -void -__trace_special(void *__tr, void *__data, - unsigned long arg1, unsigned long arg2, unsigned long arg3) -{ - struct trace_array_cpu *data = __data; - struct trace_array *tr = __tr; - struct trace_entry *entry; - unsigned long irq_flags; - - raw_local_irq_save(irq_flags); - __raw_spin_lock(&data->lock); - entry = tracing_get_trace_entry(tr, data); - tracing_generic_entry_update(entry, 0); - entry->type = TRACE_SPECIAL; - entry->special.arg1 = arg1; - entry->special.arg2 = arg2; - entry->special.arg3 = arg3; - __raw_spin_unlock(&data->lock); - raw_local_irq_restore(irq_flags); - - trace_wake_up(); -} - void __trace_stack(struct trace_array *tr, struct trace_array_cpu *data, unsigned long flags, @@ -857,6 +834,30 @@ void __trace_stack(struct trace_array *tr, } void +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + struct trace_array_cpu *data = __data; + struct trace_array *tr = __tr; + struct trace_entry *entry; + unsigned long irq_flags; + + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, 0); + entry->type = TRACE_SPECIAL; + entry->special.arg1 = arg1; + entry->special.arg2 = arg2; + entry->special.arg3 = arg3; + __trace_stack(tr, data, irq_flags, 4); + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); + + trace_wake_up(); +} + +void tracing_sched_switch_trace(struct trace_array *tr, struct trace_array_cpu *data, struct task_struct *prev, -- cgit v0.10.2 From 2bb6f8d6389cbfadd657e7dc069f6986abf35e4f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:02 +0200 Subject: ftrace: use raw_smp_processor_id for mcount functions Due to debug hooks in the kernel that can change the way smp_processor_id works, use raw_smp_processor_id in mcount called functions (namely ftrace_record_ip). Currently we annotate most debug functions from calling mcount, but we should not rely on that to prevent kernel lockups. This patch uses the raw_smp_processor_id to prevent a recusive crash that can happen if a debug hook in smp_processor_id calls mcount. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 40f64f7..af5ad89 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -267,6 +267,7 @@ ftrace_record_ip(unsigned long ip) unsigned long key; int resched; int atomic; + int cpu; if (!ftrace_enabled || ftrace_disabled) return; @@ -274,9 +275,15 @@ ftrace_record_ip(unsigned long ip) resched = need_resched(); preempt_disable_notrace(); - /* We simply need to protect against recursion */ - __get_cpu_var(ftrace_shutdown_disable_cpu)++; - if (__get_cpu_var(ftrace_shutdown_disable_cpu) != 1) + /* + * We simply need to protect against recursion. + * Use the the raw version of smp_processor_id and not + * __get_cpu_var which can call debug hooks that can + * cause a recursive crash here. + */ + cpu = raw_smp_processor_id(); + per_cpu(ftrace_shutdown_disable_cpu, cpu)++; + if (per_cpu(ftrace_shutdown_disable_cpu, cpu) != 1) goto out; if (unlikely(ftrace_record_suspend)) @@ -317,7 +324,7 @@ ftrace_record_ip(unsigned long ip) out_unlock: spin_unlock_irqrestore(&ftrace_shutdown_lock, flags); out: - __get_cpu_var(ftrace_shutdown_disable_cpu)--; + per_cpu(ftrace_shutdown_disable_cpu, cpu)--; /* prevent recursion with scheduler */ if (resched) -- cgit v0.10.2 From 6c6c27969a4c6024e6c8838829546c02aaddca18 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: ftrace: add readpos to struct trace_seq; add trace_seq_to_user() Refactor code from tracing_read_pipe() and create trace_seq_to_user(). Moved trace_seq_reset() call before iter->trace->read() call so that when all leftover data is returned, trace_seq is reset automatically. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c232d82..82ced40 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -400,6 +400,26 @@ static void trace_seq_reset(struct trace_seq *s) { s->len = 0; + s->readpos = 0; +} + +ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) +{ + int len; + int ret; + + if (s->len <= s->readpos) + return -EBUSY; + + len = s->len - s->readpos; + if (cnt > len) + cnt = len; + ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt); + if (ret) + return -EFAULT; + + s->readpos += len; + return cnt; } static void @@ -2361,46 +2381,32 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, struct trace_iterator *iter = filp->private_data; struct trace_array_cpu *data; static cpumask_t mask; - static int start; unsigned long flags; #ifdef CONFIG_FTRACE int ftrace_save; #endif - int read = 0; int cpu; - int len; - int ret; + ssize_t sret; /* return any leftover data */ - if (iter->seq.len > start) { - len = iter->seq.len - start; - if (cnt > len) - cnt = len; - ret = copy_to_user(ubuf, iter->seq.buffer + start, cnt); - if (ret) - cnt = -EFAULT; - - start += len; + sret = trace_seq_to_user(&iter->seq, ubuf, cnt); + if (sret != -EBUSY) + return sret; + sret = 0; - return cnt; - } + trace_seq_reset(&iter->seq); mutex_lock(&trace_types_lock); if (iter->trace->read) { - ret = iter->trace->read(iter, filp, ubuf, cnt, ppos); - if (ret) { - read = ret; + sret = iter->trace->read(iter, filp, ubuf, cnt, ppos); + if (sret) goto out; - } } - trace_seq_reset(&iter->seq); - start = 0; - while (trace_empty(iter)) { if ((filp->f_flags & O_NONBLOCK)) { - read = -EAGAIN; + sret = -EAGAIN; goto out; } @@ -2426,7 +2432,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, iter->tr->waiter = NULL; if (signal_pending(current)) { - read = -EINTR; + sret = -EINTR; goto out; } @@ -2496,6 +2502,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, } while (find_next_entry_inc(iter) != NULL) { + int ret; int len = iter->seq.len; ret = print_trace_line(iter); @@ -2526,24 +2533,16 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, local_irq_restore(flags); /* Now copy what we have to the user */ - read = iter->seq.len; - if (read > cnt) - read = cnt; - - ret = copy_to_user(ubuf, iter->seq.buffer, read); - - if (read < iter->seq.len) - start = read; - else + sret = trace_seq_to_user(&iter->seq, ubuf, cnt); + if (iter->seq.readpos >= iter->seq.len) trace_seq_reset(&iter->seq); - - if (ret) - read = -EFAULT; + if (sret == -EBUSY) + sret = 0; out: mutex_unlock(&trace_types_lock); - return read; + return sret; } static ssize_t diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index ee53d70..8845033 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -155,6 +155,7 @@ struct tracer { struct trace_seq { unsigned char buffer[PAGE_SIZE]; unsigned int len; + unsigned int readpos; }; /* @@ -301,6 +302,8 @@ extern int trace_selftest_startup_sched_switch(struct tracer *trace, extern void *head_page(struct trace_array_cpu *data); extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); +extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, + size_t cnt); extern long ns2usecs(cycle_t nsec); extern unsigned long trace_flags; -- cgit v0.10.2 From 3eefae994d9224fb7771a3ddb683868363c23510 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 12 May 2008 21:21:04 +0200 Subject: ftrace: limit trace entries Currently there is no protection from the root user to use up all of memory for trace buffers. If the root user allocates too many entries, the OOM killer might start kill off all tasks. This patch adds an algorith to check the following condition: pages_requested > (freeable_memory + current_trace_buffer_pages) / 4 If the above is met then the allocation fails. The above prevents more than 1/4th of freeable memory from being used by trace buffers. To determine the freeable_memory, I made determine_dirtyable_memory in mm/page-writeback.c global. Special thanks goes to Peter Zijlstra for suggesting the above calculation. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/writeback.h b/include/linux/writeback.h index f462439..bd91987 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -105,6 +105,8 @@ extern int vm_highmem_is_dirtyable; extern int block_dump; extern int laptop_mode; +extern unsigned long determine_dirtyable_memory(void); + extern int dirty_ratio_handler(struct ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 82ced40..2824cf48 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -51,6 +52,8 @@ static int trace_free_page(void); static int tracing_disabled = 1; +static unsigned long tracing_pages_allocated; + long ns2usecs(cycle_t nsec) { @@ -2591,12 +2594,41 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, } if (val > global_trace.entries) { + long pages_requested; + unsigned long freeable_pages; + + /* make sure we have enough memory before mapping */ + pages_requested = + (val + (ENTRIES_PER_PAGE-1)) / ENTRIES_PER_PAGE; + + /* account for each buffer (and max_tr) */ + pages_requested *= tracing_nr_buffers * 2; + + /* Check for overflow */ + if (pages_requested < 0) { + cnt = -ENOMEM; + goto out; + } + + freeable_pages = determine_dirtyable_memory(); + + /* we only allow to request 1/4 of useable memory */ + if (pages_requested > + ((freeable_pages + tracing_pages_allocated) / 4)) { + cnt = -ENOMEM; + goto out; + } + while (global_trace.entries < val) { if (trace_alloc_page()) { cnt = -ENOMEM; goto out; } + /* double check that we don't go over the known pages */ + if (tracing_pages_allocated > pages_requested) + break; } + } else { /* include the number of entries in val (inc of page entries) */ while (global_trace.entries > val + (ENTRIES_PER_PAGE - 1)) @@ -2776,6 +2808,7 @@ static int trace_alloc_page(void) struct page *page, *tmp; LIST_HEAD(pages); void *array; + unsigned pages_allocated = 0; int i; /* first allocate a page for each CPU */ @@ -2787,6 +2820,7 @@ static int trace_alloc_page(void) goto free_pages; } + pages_allocated++; page = virt_to_page(array); list_add(&page->lru, &pages); @@ -2798,6 +2832,7 @@ static int trace_alloc_page(void) "for trace buffer!\n"); goto free_pages; } + pages_allocated++; page = virt_to_page(array); list_add(&page->lru, &pages); #endif @@ -2819,6 +2854,7 @@ static int trace_alloc_page(void) SetPageLRU(page); #endif } + tracing_pages_allocated += pages_allocated; global_trace.entries += ENTRIES_PER_PAGE; return 0; @@ -2853,6 +2889,8 @@ static int trace_free_page(void) page = list_entry(p, struct page, lru); ClearPageLRU(page); list_del(&page->lru); + tracing_pages_allocated--; + tracing_pages_allocated--; __free_page(page); tracing_reset(data); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 789b6ad..b38f700 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -126,8 +126,6 @@ static void background_writeout(unsigned long _min_pages); static struct prop_descriptor vm_completions; static struct prop_descriptor vm_dirties; -static unsigned long determine_dirtyable_memory(void); - /* * couple the period to the dirty_ratio: * @@ -347,7 +345,13 @@ static unsigned long highmem_dirtyable_memory(unsigned long total) #endif } -static unsigned long determine_dirtyable_memory(void) +/** + * determine_dirtyable_memory - amount of memory that may be used + * + * Returns the numebr of pages that can currently be freed and used + * by the kernel for direct mappings. + */ +unsigned long determine_dirtyable_memory(void) { unsigned long x; -- cgit v0.10.2 From dc102a8fae2d0d6bf5223fc549247f2e23959ae6 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 12 May 2008 21:21:09 +0200 Subject: Markers - remove extra format argument Denys Vlasenko : > Not in this patch, but I noticed: > > #define __trace_mark(name, call_private, format, args...) \ > do { \ > static const char __mstrtab_##name[] \ > __attribute__((section("__markers_strings"))) \ > = #name "\0" format; \ > static struct marker __mark_##name \ > __attribute__((section("__markers"), aligned(8))) = \ > { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \ > 0, 0, marker_probe_cb, \ > { __mark_empty_function, NULL}, NULL }; \ > __mark_check_format(format, ## args); \ > if (unlikely(__mark_##name.state)) { \ > (*__mark_##name.call) \ > (&__mark_##name, call_private, \ > format, ## args); \ > } \ > } while (0) > > In this call: > > (*__mark_##name.call) \ > (&__mark_##name, call_private, \ > format, ## args); \ > > you make gcc allocate duplicate format string. You can use > &__mstrtab_##name[sizeof(#name)] instead since it holds the same string, > or drop ", format," above and "const char *fmt" from here: > > void (*call)(const struct marker *mdata, /* Probe wrapper */ > void *call_private, const char *fmt, ...); > > since mdata->format is the same and all callees which need it can take it there. Very good point. I actually thought about dropping it, since it would remove an unnecessary argument from the stack. And actually, since I now have the marker_probe_cb sitting between the marker site and the callbacks, there is no API change required. Thanks :) Mathieu Signed-off-by: Mathieu Desnoyers CC: Denys Vlasenko Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/marker.h b/include/linux/marker.h index 430f6ad..338533a 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -44,8 +44,8 @@ struct marker { */ char state; /* Marker state. */ char ptype; /* probe type : 0 : single, 1 : multi */ - void (*call)(const struct marker *mdata, /* Probe wrapper */ - void *call_private, const char *fmt, ...); + /* Probe wrapper */ + void (*call)(const struct marker *mdata, void *call_private, ...); struct marker_probe_closure single; struct marker_probe_closure *multi; } __attribute__((aligned(8))); @@ -72,8 +72,7 @@ struct marker { __mark_check_format(format, ## args); \ if (unlikely(__mark_##name.state)) { \ (*__mark_##name.call) \ - (&__mark_##name, call_private, \ - format, ## args); \ + (&__mark_##name, call_private, ## args);\ } \ } while (0) @@ -117,9 +116,9 @@ static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...) extern marker_probe_func __mark_empty_function; extern void marker_probe_cb(const struct marker *mdata, - void *call_private, const char *fmt, ...); + void *call_private, ...); extern void marker_probe_cb_noarg(const struct marker *mdata, - void *call_private, const char *fmt, ...); + void *call_private, ...); /* * Connect a probe to a marker. diff --git a/kernel/marker.c b/kernel/marker.c index b5a9fe1..1abfb92 100644 --- a/kernel/marker.c +++ b/kernel/marker.c @@ -55,8 +55,8 @@ static DEFINE_MUTEX(markers_mutex); struct marker_entry { struct hlist_node hlist; char *format; - void (*call)(const struct marker *mdata, /* Probe wrapper */ - void *call_private, const char *fmt, ...); + /* Probe wrapper */ + void (*call)(const struct marker *mdata, void *call_private, ...); struct marker_probe_closure single; struct marker_probe_closure *multi; int refcount; /* Number of times armed. 0 if disarmed. */ @@ -91,15 +91,13 @@ EXPORT_SYMBOL_GPL(__mark_empty_function); * marker_probe_cb Callback that prepares the variable argument list for probes. * @mdata: pointer of type struct marker * @call_private: caller site private data - * @fmt: format string * @...: Variable argument list. * * Since we do not use "typical" pointer based RCU in the 1 argument case, we * need to put a full smp_rmb() in this branch. This is why we do not use * rcu_dereference() for the pointer read. */ -void marker_probe_cb(const struct marker *mdata, void *call_private, - const char *fmt, ...) +void marker_probe_cb(const struct marker *mdata, void *call_private, ...) { va_list args; char ptype; @@ -120,8 +118,9 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, /* Must read the ptr before private data. They are not data * dependant, so we put an explicit smp_rmb() here. */ smp_rmb(); - va_start(args, fmt); - func(mdata->single.probe_private, call_private, fmt, &args); + va_start(args, call_private); + func(mdata->single.probe_private, call_private, mdata->format, + &args); va_end(args); } else { struct marker_probe_closure *multi; @@ -136,9 +135,9 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, smp_read_barrier_depends(); multi = mdata->multi; for (i = 0; multi[i].func; i++) { - va_start(args, fmt); - multi[i].func(multi[i].probe_private, call_private, fmt, - &args); + va_start(args, call_private); + multi[i].func(multi[i].probe_private, call_private, + mdata->format, &args); va_end(args); } } @@ -150,13 +149,11 @@ EXPORT_SYMBOL_GPL(marker_probe_cb); * marker_probe_cb Callback that does not prepare the variable argument list. * @mdata: pointer of type struct marker * @call_private: caller site private data - * @fmt: format string * @...: Variable argument list. * * Should be connected to markers "MARK_NOARGS". */ -void marker_probe_cb_noarg(const struct marker *mdata, - void *call_private, const char *fmt, ...) +void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...) { va_list args; /* not initialized */ char ptype; @@ -172,7 +169,8 @@ void marker_probe_cb_noarg(const struct marker *mdata, /* Must read the ptr before private data. They are not data * dependant, so we put an explicit smp_rmb() here. */ smp_rmb(); - func(mdata->single.probe_private, call_private, fmt, &args); + func(mdata->single.probe_private, call_private, mdata->format, + &args); } else { struct marker_probe_closure *multi; int i; @@ -186,8 +184,8 @@ void marker_probe_cb_noarg(const struct marker *mdata, smp_read_barrier_depends(); multi = mdata->multi; for (i = 0; multi[i].func; i++) - multi[i].func(multi[i].probe_private, call_private, fmt, - &args); + multi[i].func(multi[i].probe_private, call_private, + mdata->format, &args); } preempt_enable(); } -- cgit v0.10.2 From 0aa977f592f17004f9d1d545f2e1bb9ea71896c3 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 12 May 2008 21:21:10 +0200 Subject: Markers - define non optimized marker To support the forthcoming "immediate values" marker optimization, we must have a way to declare markers in few code paths that does not use instruction modification based enable. This will be the case of printk(), some traps and eventually lockdep instrumentation. Changelog : - Fix reversed boolean logic of "generic". Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/marker.h b/include/linux/marker.h index 338533a..1290653 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -58,8 +58,12 @@ struct marker { * Make sure the alignment of the structure in the __markers section will * not add unwanted padding between the beginning of the section and the * structure. Force alignment to the same alignment as the section start. + * + * The "generic" argument controls which marker enabling mechanism must be used. + * If generic is true, a variable read is used. + * If generic is false, immediate values are used. */ -#define __trace_mark(name, call_private, format, args...) \ +#define __trace_mark(generic, name, call_private, format, args...) \ do { \ static const char __mstrtab_##name[] \ __attribute__((section("__markers_strings"))) \ @@ -79,7 +83,7 @@ struct marker { extern void marker_update_probe_range(struct marker *begin, struct marker *end); #else /* !CONFIG_MARKERS */ -#define __trace_mark(name, call_private, format, args...) \ +#define __trace_mark(generic, name, call_private, format, args...) \ __mark_check_format(format, ## args) static inline void marker_update_probe_range(struct marker *begin, struct marker *end) @@ -87,15 +91,30 @@ static inline void marker_update_probe_range(struct marker *begin, #endif /* CONFIG_MARKERS */ /** - * trace_mark - Marker + * trace_mark - Marker using code patching * @name: marker name, not quoted. * @format: format string * @args...: variable argument list * - * Places a marker. + * Places a marker using optimized code patching technique (imv_read()) + * to be enabled when immediate values are present. */ #define trace_mark(name, format, args...) \ - __trace_mark(name, NULL, format, ## args) + __trace_mark(0, name, NULL, format, ## args) + +/** + * _trace_mark - Marker using variable read + * @name: marker name, not quoted. + * @format: format string + * @args...: variable argument list + * + * Places a marker using a standard memory read (_imv_read()) to be + * enabled. Should be used for markers in code paths where instruction + * modification based enabling is not welcome. (__init and __exit functions, + * lockdep, some traps, printk). + */ +#define _trace_mark(name, format, args...) \ + __trace_mark(1, name, NULL, format, ## args) /** * MARK_NOARGS - Format string for a marker with no argument. -- cgit v0.10.2 From 5b82a1b08a00b2adca3d9dd9777efff40b7aaaa1 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 12 May 2008 21:21:10 +0200 Subject: Port ftrace to markers Porting ftrace to the marker infrastructure. Don't need to chain to the wakeup tracer from the sched tracer, because markers support multiple probes connected. Signed-off-by: Mathieu Desnoyers CC: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/sched.h b/include/linux/sched.h index 360ca99..c0b1c69 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2131,38 +2131,6 @@ __trace_special(void *__tr, void *__data, } #endif -#ifdef CONFIG_CONTEXT_SWITCH_TRACER -extern void -ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next); -extern void -ftrace_wake_up_task(void *rq, struct task_struct *wakee, - struct task_struct *curr); -extern void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data); -extern void -ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); -#else -static inline void -ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next) -{ -} -static inline void -sched_trace_special(unsigned long p1, unsigned long p2, unsigned long p3) -{ -} -static inline void -ftrace_wake_up_task(void *rq, struct task_struct *wakee, - struct task_struct *curr) -{ -} -static inline void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) -{ -} -static inline void -ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) -{ -} -#endif - extern long sched_setaffinity(pid_t pid, const cpumask_t *new_mask); extern long sched_getaffinity(pid_t pid, cpumask_t *mask); diff --git a/kernel/sched.c b/kernel/sched.c index ad95cca..e2e985e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2500,7 +2500,9 @@ out_activate: success = 1; out_running: - ftrace_wake_up_task(rq, p, rq->curr); + trace_mark(kernel_sched_wakeup, + "pid %d state %ld ## rq %p task %p rq->curr %p", + p->pid, p->state, rq, p, rq->curr); check_preempt_curr(rq, p); p->state = TASK_RUNNING; @@ -2631,7 +2633,9 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) p->sched_class->task_new(rq, p); inc_nr_running(rq); } - ftrace_wake_up_task(rq, p, rq->curr); + trace_mark(kernel_sched_wakeup_new, + "pid %d state %ld ## rq %p task %p rq->curr %p", + p->pid, p->state, rq, p, rq->curr); check_preempt_curr(rq, p); #ifdef CONFIG_SMP if (p->sched_class->task_wake_up) @@ -2804,7 +2808,11 @@ context_switch(struct rq *rq, struct task_struct *prev, struct mm_struct *mm, *oldmm; prepare_task_switch(rq, prev, next); - ftrace_ctx_switch(rq, prev, next); + trace_mark(kernel_sched_schedule, + "prev_pid %d next_pid %d prev_state %ld " + "## rq %p prev %p next %p", + prev->pid, next->pid, prev->state, + rq, prev, next); mm = next->mm; oldmm = prev->active_mm; /* diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8845033..f5de060 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -234,25 +234,10 @@ void update_max_tr_single(struct trace_array *tr, extern cycle_t ftrace_now(int cpu); -#ifdef CONFIG_SCHED_TRACER -extern void -wakeup_sched_switch(struct task_struct *prev, struct task_struct *next); -extern void -wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr); -#else -static inline void -wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) -{ -} -static inline void -wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) -{ -} -#endif - #ifdef CONFIG_CONTEXT_SWITCH_TRACER typedef void (*tracer_switch_func_t)(void *private, + void *__rq, struct task_struct *prev, struct task_struct *next); @@ -262,9 +247,6 @@ struct tracer_switch_ops { struct tracer_switch_ops *next; }; -extern int register_tracer_switch(struct tracer_switch_ops *ops); -extern int unregister_tracer_switch(struct tracer_switch_ops *ops); - #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ #ifdef CONFIG_DYNAMIC_FTRACE diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index a337647..d25ffa5 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -16,11 +16,14 @@ static struct trace_array *ctx_trace; static int __read_mostly tracer_enabled; +static atomic_t sched_ref; static void -ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) +sched_switch_func(void *private, void *__rq, struct task_struct *prev, + struct task_struct *next) { - struct trace_array *tr = ctx_trace; + struct trace_array **ptr = private; + struct trace_array *tr = *ptr; struct trace_array_cpu *data; unsigned long flags; long disabled; @@ -41,10 +44,40 @@ ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) local_irq_restore(flags); } +static notrace void +sched_switch_callback(void *probe_data, void *call_data, + const char *format, va_list *args) +{ + struct task_struct *prev; + struct task_struct *next; + struct rq *__rq; + + if (!atomic_read(&sched_ref)) + return; + + /* skip prev_pid %d next_pid %d prev_state %ld */ + (void)va_arg(*args, int); + (void)va_arg(*args, int); + (void)va_arg(*args, long); + __rq = va_arg(*args, typeof(__rq)); + prev = va_arg(*args, typeof(prev)); + next = va_arg(*args, typeof(next)); + + tracing_record_cmdline(prev); + + /* + * If tracer_switch_func only points to the local + * switch func, it still needs the ptr passed to it. + */ + sched_switch_func(probe_data, __rq, prev, next); +} + static void -wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) +wakeup_func(void *private, void *__rq, struct task_struct *wakee, struct + task_struct *curr) { - struct trace_array *tr = ctx_trace; + struct trace_array **ptr = private; + struct trace_array *tr = *ptr; struct trace_array_cpu *data; unsigned long flags; long disabled; @@ -67,35 +100,29 @@ wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) local_irq_restore(flags); } -void -ftrace_ctx_switch(void *__rq, struct task_struct *prev, - struct task_struct *next) +static notrace void +wake_up_callback(void *probe_data, void *call_data, + const char *format, va_list *args) { - if (unlikely(atomic_read(&trace_record_cmdline_enabled))) - tracing_record_cmdline(prev); + struct task_struct *curr; + struct task_struct *task; + struct rq *__rq; - /* - * If tracer_switch_func only points to the local - * switch func, it still needs the ptr passed to it. - */ - ctx_switch_func(__rq, prev, next); + if (likely(!tracer_enabled)) + return; - /* - * Chain to the wakeup tracer (this is a NOP if disabled): - */ - wakeup_sched_switch(prev, next); -} + /* Skip pid %d state %ld */ + (void)va_arg(*args, int); + (void)va_arg(*args, long); + /* now get the meat: "rq %p task %p rq->curr %p" */ + __rq = va_arg(*args, typeof(__rq)); + task = va_arg(*args, typeof(task)); + curr = va_arg(*args, typeof(curr)); -void -ftrace_wake_up_task(void *__rq, struct task_struct *wakee, - struct task_struct *curr) -{ - wakeup_func(__rq, wakee, curr); + tracing_record_cmdline(task); + tracing_record_cmdline(curr); - /* - * Chain to the wakeup tracer (this is a NOP if disabled): - */ - wakeup_sched_wakeup(wakee, curr); + wakeup_func(probe_data, __rq, task, curr); } void @@ -132,15 +159,95 @@ static void sched_switch_reset(struct trace_array *tr) tracing_reset(tr->data[cpu]); } +static int tracing_sched_register(void) +{ + int ret; + + ret = marker_probe_register("kernel_sched_wakeup", + "pid %d state %ld ## rq %p task %p rq->curr %p", + wake_up_callback, + &ctx_trace); + if (ret) { + pr_info("wakeup trace: Couldn't add marker" + " probe to kernel_sched_wakeup\n"); + return ret; + } + + ret = marker_probe_register("kernel_sched_wakeup_new", + "pid %d state %ld ## rq %p task %p rq->curr %p", + wake_up_callback, + &ctx_trace); + if (ret) { + pr_info("wakeup trace: Couldn't add marker" + " probe to kernel_sched_wakeup_new\n"); + goto fail_deprobe; + } + + ret = marker_probe_register("kernel_sched_schedule", + "prev_pid %d next_pid %d prev_state %ld " + "## rq %p prev %p next %p", + sched_switch_callback, + &ctx_trace); + if (ret) { + pr_info("sched trace: Couldn't add marker" + " probe to kernel_sched_schedule\n"); + goto fail_deprobe_wake_new; + } + + return ret; +fail_deprobe_wake_new: + marker_probe_unregister("kernel_sched_wakeup_new", + wake_up_callback, + &ctx_trace); +fail_deprobe: + marker_probe_unregister("kernel_sched_wakeup", + wake_up_callback, + &ctx_trace); + return ret; +} + +static void tracing_sched_unregister(void) +{ + marker_probe_unregister("kernel_sched_schedule", + sched_switch_callback, + &ctx_trace); + marker_probe_unregister("kernel_sched_wakeup_new", + wake_up_callback, + &ctx_trace); + marker_probe_unregister("kernel_sched_wakeup", + wake_up_callback, + &ctx_trace); +} + +void tracing_start_sched_switch(void) +{ + long ref; + + ref = atomic_inc_return(&sched_ref); + if (ref == 1) + tracing_sched_register(); +} + +void tracing_stop_sched_switch(void) +{ + long ref; + + ref = atomic_dec_and_test(&sched_ref); + if (ref) + tracing_sched_unregister(); +} + static void start_sched_trace(struct trace_array *tr) { sched_switch_reset(tr); atomic_inc(&trace_record_cmdline_enabled); tracer_enabled = 1; + tracing_start_sched_switch(); } static void stop_sched_trace(struct trace_array *tr) { + tracing_stop_sched_switch(); atomic_dec(&trace_record_cmdline_enabled); tracer_enabled = 0; } @@ -181,6 +288,14 @@ static struct tracer sched_switch_trace __read_mostly = __init static int init_sched_switch_trace(void) { + int ret = 0; + + if (atomic_read(&sched_ref)) + ret = tracing_sched_register(); + if (ret) { + pr_info("error registering scheduler trace\n"); + return ret; + } return register_tracer(&sched_switch_trace); } device_initcall(init_sched_switch_trace); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 5948011..5d2fb48 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "trace.h" @@ -44,11 +45,13 @@ static int report_latency(cycle_t delta) return 1; } -void -wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) +static void notrace +wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, + struct task_struct *next) { unsigned long latency = 0, t0 = 0, t1 = 0; - struct trace_array *tr = wakeup_trace; + struct trace_array **ptr = private; + struct trace_array *tr = *ptr; struct trace_array_cpu *data; cycle_t T0, T1, delta; unsigned long flags; @@ -113,6 +116,31 @@ out: atomic_dec(&tr->data[cpu]->disabled); } +static notrace void +sched_switch_callback(void *probe_data, void *call_data, + const char *format, va_list *args) +{ + struct task_struct *prev; + struct task_struct *next; + struct rq *__rq; + + /* skip prev_pid %d next_pid %d prev_state %ld */ + (void)va_arg(*args, int); + (void)va_arg(*args, int); + (void)va_arg(*args, long); + __rq = va_arg(*args, typeof(__rq)); + prev = va_arg(*args, typeof(prev)); + next = va_arg(*args, typeof(next)); + + tracing_record_cmdline(prev); + + /* + * If tracer_switch_func only points to the local + * switch func, it still needs the ptr passed to it. + */ + wakeup_sched_switch(probe_data, __rq, prev, next); +} + static void __wakeup_reset(struct trace_array *tr) { struct trace_array_cpu *data; @@ -188,19 +216,68 @@ out: atomic_dec(&tr->data[cpu]->disabled); } -void wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) +static notrace void +wake_up_callback(void *probe_data, void *call_data, + const char *format, va_list *args) { + struct trace_array **ptr = probe_data; + struct trace_array *tr = *ptr; + struct task_struct *curr; + struct task_struct *task; + struct rq *__rq; + if (likely(!tracer_enabled)) return; + /* Skip pid %d state %ld */ + (void)va_arg(*args, int); + (void)va_arg(*args, long); + /* now get the meat: "rq %p task %p rq->curr %p" */ + __rq = va_arg(*args, typeof(__rq)); + task = va_arg(*args, typeof(task)); + curr = va_arg(*args, typeof(curr)); + + tracing_record_cmdline(task); tracing_record_cmdline(curr); - tracing_record_cmdline(wakee); - wakeup_check_start(wakeup_trace, wakee, curr); + wakeup_check_start(tr, task, curr); } static void start_wakeup_tracer(struct trace_array *tr) { + int ret; + + ret = marker_probe_register("kernel_sched_wakeup", + "pid %d state %ld ## rq %p task %p rq->curr %p", + wake_up_callback, + &wakeup_trace); + if (ret) { + pr_info("wakeup trace: Couldn't add marker" + " probe to kernel_sched_wakeup\n"); + return; + } + + ret = marker_probe_register("kernel_sched_wakeup_new", + "pid %d state %ld ## rq %p task %p rq->curr %p", + wake_up_callback, + &wakeup_trace); + if (ret) { + pr_info("wakeup trace: Couldn't add marker" + " probe to kernel_sched_wakeup_new\n"); + goto fail_deprobe; + } + + ret = marker_probe_register("kernel_sched_schedule", + "prev_pid %d next_pid %d prev_state %ld " + "## rq %p prev %p next %p", + sched_switch_callback, + &wakeup_trace); + if (ret) { + pr_info("sched trace: Couldn't add marker" + " probe to kernel_sched_schedule\n"); + goto fail_deprobe_wake_new; + } + wakeup_reset(tr); /* @@ -215,11 +292,28 @@ static void start_wakeup_tracer(struct trace_array *tr) tracer_enabled = 1; return; +fail_deprobe_wake_new: + marker_probe_unregister("kernel_sched_wakeup_new", + wake_up_callback, + &wakeup_trace); +fail_deprobe: + marker_probe_unregister("kernel_sched_wakeup", + wake_up_callback, + &wakeup_trace); } static void stop_wakeup_tracer(struct trace_array *tr) { tracer_enabled = 0; + marker_probe_unregister("kernel_sched_schedule", + sched_switch_callback, + &wakeup_trace); + marker_probe_unregister("kernel_sched_wakeup_new", + wake_up_callback, + &wakeup_trace); + marker_probe_unregister("kernel_sched_wakeup", + wake_up_callback, + &wakeup_trace); } static void wakeup_tracer_init(struct trace_array *tr) -- cgit v0.10.2 From 74f4e369fc5b52433ad824cef32d3bf1304549be Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:15 +0200 Subject: ftrace: stacktrace fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 0d3714e..017ab44 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -120,4 +120,12 @@ static inline void tracer_disable(void) # define trace_preempt_off(a0, a1) do { } while (0) #endif +#ifdef CONFIG_CONTEXT_SWITCH_TRACER +extern void +ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); +#else +static inline void +ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } +#endif + #endif /* _LINUX_FTRACE_H */ diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 5c2942e..1a064ad 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -31,6 +31,7 @@ #include #include #include +#include static noinline void __down(struct semaphore *sem); static noinline int __down_interruptible(struct semaphore *sem); @@ -53,6 +54,7 @@ void down(struct semaphore *sem) { unsigned long flags; + ftrace_special(sem->count, 0, __LINE__); spin_lock_irqsave(&sem->lock, flags); if (likely(sem->count > 0)) sem->count--; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2824cf48..3271916 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -901,7 +901,7 @@ tracing_sched_switch_trace(struct trace_array *tr, entry->ctx.next_pid = next->pid; entry->ctx.next_prio = next->prio; entry->ctx.next_state = next->state; - __trace_stack(tr, data, flags, 4); + __trace_stack(tr, data, flags, 5); __raw_spin_unlock(&data->lock); raw_local_irq_restore(irq_flags); } @@ -927,7 +927,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->ctx.next_pid = wakee->pid; entry->ctx.next_prio = wakee->prio; entry->ctx.next_state = wakee->state; - __trace_stack(tr, data, flags, 5); + __trace_stack(tr, data, flags, 6); __raw_spin_unlock(&data->lock); raw_local_irq_restore(irq_flags); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index f5de060..c460e85 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -51,7 +51,7 @@ struct special_entry { * Stack-trace entry: */ -#define FTRACE_STACK_ENTRIES 5 +#define FTRACE_STACK_ENTRIES 8 struct stack_entry { unsigned long caller[FTRACE_STACK_ENTRIES]; -- cgit v0.10.2 From aa5e5ceaf52a882a29d9b86531a20733f5116066 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 13 May 2008 22:06:56 -0700 Subject: ftrace: remove packed attribute on ftrace_page. It causes unaligned access traps on platforms like sparc (ftrace_page may be marked packed, but once we return a dyn_ftrace sub-object from this array to another piece of code, the "packed" part of the typing information doesn't propagate). But also, it didn't serve any purpose either. Even if packed, on 64-bit or 32-bit, it didn't give us any more dyn_ftrace entries per-page. Signed-off-by: David S. Miller Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index af5ad89..07b2a14 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -177,9 +177,9 @@ static DEFINE_MUTEX(ftrace_filter_lock); struct ftrace_page { struct ftrace_page *next; - int index; + unsigned long index; struct dyn_ftrace records[]; -} __attribute__((packed)); +}; #define ENTRIES_PER_PAGE \ ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace)) -- cgit v0.10.2 From d05f5f9906740474eb768823004ffcd775b12ca6 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 13 May 2008 22:06:59 -0700 Subject: sparc64: add ftrace support. Signed-off-by: David S. Miller Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index eb36f3b..a480df6 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -11,6 +11,7 @@ config SPARC config SPARC64 bool default y + select HAVE_FTRACE select HAVE_IDE select HAVE_LMB select HAVE_ARCH_KGDB diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index 6a4d28a..d6d32d1 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug @@ -33,7 +33,7 @@ config DEBUG_PAGEALLOC config MCOUNT bool - depends on STACK_DEBUG + depends on STACK_DEBUG || FTRACE default y config FRAME_POINTER diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index ec4f5eb..418b578 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ power.o sbus.o sparc64_ksyms.o chmc.o \ visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o pci_common.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ diff --git a/arch/sparc64/kernel/ftrace.c b/arch/sparc64/kernel/ftrace.c new file mode 100644 index 0000000..f449e6d --- /dev/null +++ b/arch/sparc64/kernel/ftrace.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include + +static const u32 ftrace_nop = 0x01000000; + +notrace int ftrace_ip_converted(unsigned long ip) +{ + u32 insn = *(u32 *) ip; + + return (insn == ftrace_nop); +} + +notrace unsigned char *ftrace_nop_replace(void) +{ + return (char *)&ftrace_nop; +} + +notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +{ + static u32 call; + s32 off; + + off = ((s32)addr - (s32)ip); + call = 0x40000000 | ((u32)off >> 2); + + return (unsigned char *) &call; +} + +notrace int +ftrace_modify_code(unsigned long ip, unsigned char *old_code, + unsigned char *new_code) +{ + u32 old = *(u32 *)old_code; + u32 new = *(u32 *)new_code; + u32 replaced; + int faulted; + + __asm__ __volatile__( + "1: cas [%[ip]], %[old], %[new]\n" + " flush %[ip]\n" + " mov 0, %[faulted]\n" + "2:\n" + " .section .fixup,#alloc,#execinstr\n" + " .align 4\n" + "3: sethi %%hi(2b), %[faulted]\n" + " jmpl %[faulted] + %%lo(2b), %%g0\n" + " mov 1, %[faulted]\n" + " .previous\n" + " .section __ex_table,\"a\"\n" + " .align 4\n" + " .word 1b, 3b\n" + " .previous\n" + : "=r" (replaced), [faulted] "=r" (faulted) + : [new] "0" (new), [old] "r" (old), [ip] "r" (ip) + : "memory"); + + if (replaced != old && replaced != new) + faulted = 2; + + return faulted; +} + +notrace int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned long ip = (unsigned long)(&ftrace_call); + unsigned char old[4], *new; + + memcpy(old, &ftrace_call, 4); + new = ftrace_call_replace(ip, (unsigned long)func); + return ftrace_modify_code(ip, old, new); +} + +notrace int ftrace_mcount_set(unsigned long *data) +{ + unsigned long ip = (long)(&mcount_call); + unsigned long *addr = data; + unsigned char old[4], *new; + + /* + * Replace the mcount stub with a pointer to the + * ip recorder function. + */ + memcpy(old, &mcount_call, 4); + new = ftrace_call_replace(ip, *addr); + *addr = ftrace_modify_code(ip, old, new); + + return 0; +} + + +int __init ftrace_dyn_arch_init(void *data) +{ + ftrace_mcount_set(data); + return 0; +} diff --git a/arch/sparc64/lib/mcount.S b/arch/sparc64/lib/mcount.S index 9e4534b..7735a7a 100644 --- a/arch/sparc64/lib/mcount.S +++ b/arch/sparc64/lib/mcount.S @@ -28,10 +28,13 @@ ovstack: .skip OVSTACKSIZE #endif .text - .align 32 - .globl mcount, _mcount -mcount: + .align 32 + .globl _mcount + .type _mcount,#function + .globl mcount + .type mcount,#function _mcount: +mcount: #ifdef CONFIG_STACK_DEBUG /* * Check whether %sp is dangerously low. @@ -55,6 +58,53 @@ _mcount: or %g3, %lo(panicstring), %o0 call prom_halt nop +1: +#endif +#ifdef CONFIG_FTRACE +#ifdef CONFIG_DYNAMIC_FTRACE + mov %o7, %o0 + .globl mcount_call +mcount_call: + call ftrace_stub + mov %o0, %o7 +#else + sethi %hi(ftrace_trace_function), %g1 + sethi %hi(ftrace_stub), %g2 + ldx [%g1 + %lo(ftrace_trace_function)], %g1 + or %g2, %lo(ftrace_stub), %g2 + cmp %g1, %g2 + be,pn %icc, 1f + mov %i7, %o1 + jmpl %g1, %g0 + mov %o7, %o0 + /* not reached */ +1: #endif -1: retl +#endif + retl nop + .size _mcount,.-_mcount + .size mcount,.-mcount + +#ifdef CONFIG_FTRACE + .globl ftrace_stub + .type ftrace_stub,#function +ftrace_stub: + retl + nop + .size ftrace_stub,.-ftrace_stub +#ifdef CONFIG_DYNAMIC_FTRACE + .globl ftrace_caller + .type ftrace_caller,#function +ftrace_caller: + mov %i7, %o1 + mov %o7, %o0 + .globl ftrace_call +ftrace_call: + call ftrace_stub + mov %o0, %o7 + retl + nop + .size ftrace_caller,.-ftrace_caller +#endif +#endif -- cgit v0.10.2 From 37135677e653537ffc6e7def679443272a1c03c3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 14 May 2008 08:10:31 +0200 Subject: ftrace: fix mcount export bug David S. Miller noticed the following bug: the -pg instrumentation function callback is named differently on each platform. On x86 it is mcount, on sparc it is _mcount. So the export does not make sense in kernel/trace/ftrace.c - move it to x86. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index deb4378..29999db 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c @@ -1,7 +1,14 @@ +#include #include + #include -#include #include +#include + +#ifdef CONFIG_FTRACE +/* mcount is defined in assembly */ +EXPORT_SYMBOL(mcount); +#endif /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_generic); diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index f6c05d0..122885b 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -1,15 +1,22 @@ /* Exports for assembly files. All C exports should go in the respective C files. */ +#include #include -#include #include +#include + #include -#include #include +#include #include +#ifdef CONFIG_FTRACE +/* mcount is defined in assembly */ +EXPORT_SYMBOL(mcount); +#endif + EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(__get_user_1); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 07b2a14..a3e47f4 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -50,9 +50,6 @@ static struct ftrace_ops ftrace_list_end __read_mostly = static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end; ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; -/* mcount is defined per arch in assembly */ -EXPORT_SYMBOL(mcount); - void ftrace_list_func(unsigned long ip, unsigned long parent_ip) { struct ftrace_ops *op = ftrace_list; -- cgit v0.10.2 From 2d8b820b2e81954754277723379ae9ed5de316fa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 23 Feb 2008 16:55:50 +0100 Subject: ftrace: cleanups factor out code and clean it up. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index a3e47f4..89bd9a6 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -18,13 +18,13 @@ #include #include #include -#include #include -#include +#include #include +#include #include -#include #include +#include #include #include "trace.h" -- cgit v0.10.2 From d49dbf33f0bf8748ee3662b973eb57e60525d622 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 16 May 2008 10:41:53 +0200 Subject: ftrace: fix include file dependency Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 017ab44..911d5d8 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -4,6 +4,7 @@ #ifdef CONFIG_FTRACE #include +#include extern int ftrace_enabled; extern int -- cgit v0.10.2 From 489f139614596cbc956a06f5e4bb41288e276fe3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 25 Feb 2008 13:38:05 +0100 Subject: ftrace: fix build bug Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 911d5d8..922e23d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -106,16 +106,16 @@ static inline void tracer_disable(void) #endif #ifdef CONFIG_IRQSOFF_TRACER - extern void notrace time_hardirqs_on(unsigned long a0, unsigned long a1); - extern void notrace time_hardirqs_off(unsigned long a0, unsigned long a1); + extern void time_hardirqs_on(unsigned long a0, unsigned long a1); + extern void time_hardirqs_off(unsigned long a0, unsigned long a1); #else # define time_hardirqs_on(a0, a1) do { } while (0) # define time_hardirqs_off(a0, a1) do { } while (0) #endif #ifdef CONFIG_PREEMPT_TRACER - extern void notrace trace_preempt_on(unsigned long a0, unsigned long a1); - extern void notrace trace_preempt_off(unsigned long a0, unsigned long a1); + extern void trace_preempt_on(unsigned long a0, unsigned long a1); + extern void trace_preempt_off(unsigned long a0, unsigned long a1); #else # define trace_preempt_on(a0, a1) do { } while (0) # define trace_preempt_off(a0, a1) do { } while (0) -- cgit v0.10.2 From e0eca07badc023a675a61906020b397da20f07c3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 23:49:43 -0400 Subject: ftrace, POWERPC: add irqs_disabled_flags to ppc PPC doesn't have the irqs_disabled_flags needed by ftrace. This patch adds it. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h index ad8c9f7..f75a5fc 100644 --- a/include/asm-powerpc/hw_irq.h +++ b/include/asm-powerpc/hw_irq.h @@ -59,6 +59,11 @@ extern void iseries_handle_interrupts(void); get_paca()->hard_enabled = 0; \ } while(0) +static inline int irqs_disabled_flags(unsigned long flags) +{ + return flags == 0; +} + #else #if defined(CONFIG_BOOKE) @@ -113,6 +118,11 @@ static inline void local_irq_save_ptr(unsigned long *flags) #define hard_irq_enable() local_irq_enable() #define hard_irq_disable() local_irq_disable() +static inline int irqs_disabled_flags(unsigned long flags) +{ + return (flags & MSR_EE) == 0; +} + #endif /* CONFIG_PPC64 */ /* -- cgit v0.10.2 From 4e491d14f2506b218d678935c25a7027b79178b1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 23:49:44 -0400 Subject: ftrace: support for PowerPC This patch adds full support for ftrace for PowerPC (both 64 and 32 bit). This includes dynamic tracing and function filtering. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3934e26..62d034a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -105,11 +105,12 @@ config ARCH_NO_VIRT_TO_BUS config PPC bool default y + select HAVE_FTRACE select HAVE_IDE - select HAVE_OPROFILE select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_LMB + select HAVE_OPROFILE config EARLY_PRINTK bool diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 2346d27..f3f5e26 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -12,6 +12,18 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif +ifdef CONFIG_FTRACE +# Do not trace early boot code +CFLAGS_REMOVE_cputable.o = -pg +CFLAGS_REMOVE_prom_init.o = -pg + +ifdef CONFIG_DYNAMIC_FTRACE +# dynamic ftrace setup. +CFLAGS_REMOVE_ftrace.o = -pg +endif + +endif + obj-y := cputable.o ptrace.o syscalls.o \ irq.o align.o signal_32.o pmc.o vdso.o \ init_task.o process.o systbl.o idle.o \ @@ -78,6 +90,8 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o + obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o ifneq ($(CONFIG_PPC_INDIRECT_IO),y) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0c8614d..0e62218 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -1035,3 +1035,133 @@ machine_check_in_rtas: /* XXX load up BATs and panic */ #endif /* CONFIG_PPC_RTAS */ + +#ifdef CONFIG_FTRACE +#ifdef CONFIG_DYNAMIC_FTRACE +_GLOBAL(mcount) +_GLOBAL(_mcount) + stwu r1,-48(r1) + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) + mflr r3 + stw r7, 28(r1) + mfcr r5 + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) + .globl mcount_call +mcount_call: + bl ftrace_stub + nop + lwz r6, 8(r1) + lwz r0, 44(r1) + lwz r3, 12(r1) + mtctr r0 + lwz r4, 16(r1) + mtcr r6 + lwz r5, 20(r1) + lwz r6, 24(r1) + lwz r0, 52(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + mtlr r0 + lwz r9, 36(r1) + lwz r10,40(r1) + addi r1, r1, 48 + bctr + +_GLOBAL(ftrace_caller) + /* Based off of objdump optput from glibc */ + stwu r1,-48(r1) + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) + mflr r3 + lwz r4, 52(r1) + mfcr r5 + stw r7, 28(r1) + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) +.globl ftrace_call +ftrace_call: + bl ftrace_stub + nop + lwz r6, 8(r1) + lwz r0, 44(r1) + lwz r3, 12(r1) + mtctr r0 + lwz r4, 16(r1) + mtcr r6 + lwz r5, 20(r1) + lwz r6, 24(r1) + lwz r0, 52(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + mtlr r0 + lwz r9, 36(r1) + lwz r10,40(r1) + addi r1, r1, 48 + bctr +#else +_GLOBAL(mcount) +_GLOBAL(_mcount) + stwu r1,-48(r1) + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) + mflr r3 + lwz r4, 52(r1) + mfcr r5 + stw r7, 28(r1) + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) + + LOAD_REG_ADDR(r5, ftrace_trace_function) +#if 0 + mtctr r3 + mr r1, r5 + bctrl +#endif + lwz r5,0(r5) +#if 1 + mtctr r5 + bctrl +#else + bl ftrace_stub +#endif + nop + + lwz r6, 8(r1) + lwz r0, 44(r1) + lwz r3, 12(r1) + mtctr r0 + lwz r4, 16(r1) + mtcr r6 + lwz r5, 20(r1) + lwz r6, 24(r1) + lwz r0, 52(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + mtlr r0 + lwz r9, 36(r1) + lwz r10,40(r1) + addi r1, r1, 48 + bctr +#endif + +_GLOBAL(ftrace_stub) + blr + +#endif /* CONFIG_MCOUNT */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index c0db5b7..2c4d9e0 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -870,3 +870,65 @@ _GLOBAL(enter_prom) ld r0,16(r1) mtlr r0 blr + +#ifdef CONFIG_FTRACE +#ifdef CONFIG_DYNAMIC_FTRACE +_GLOBAL(mcount) +_GLOBAL(_mcount) + /* Taken from output of objdump from lib64/glibc */ + mflr r3 + stdu r1, -112(r1) + std r3, 128(r1) + .globl mcount_call +mcount_call: + bl ftrace_stub + nop + ld r0, 128(r1) + mtlr r0 + addi r1, r1, 112 + blr + +_GLOBAL(ftrace_caller) + /* Taken from output of objdump from lib64/glibc */ + mflr r3 + ld r11, 0(r1) + stdu r1, -112(r1) + std r3, 128(r1) + ld r4, 16(r11) +.globl ftrace_call +ftrace_call: + bl ftrace_stub + nop + ld r0, 128(r1) + mtlr r0 + addi r1, r1, 112 +_GLOBAL(ftrace_stub) + blr +#else +_GLOBAL(mcount) + blr + +_GLOBAL(_mcount) + /* Taken from output of objdump from lib64/glibc */ + mflr r3 + ld r11, 0(r1) + stdu r1, -112(r1) + std r3, 128(r1) + ld r4, 16(r11) + + + LOAD_REG_ADDR(r5,ftrace_trace_function) + ld r5,0(r5) + ld r5,0(r5) + mtctr r5 + bctrl + + nop + ld r0, 128(r1) + mtlr r0 + addi r1, r1, 112 +_GLOBAL(ftrace_stub) + blr + +#endif +#endif diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c new file mode 100644 index 0000000..5a4993f --- /dev/null +++ b/arch/powerpc/kernel/ftrace.c @@ -0,0 +1,165 @@ +/* + * Code for replacing ftrace calls with jumps. + * + * Copyright (C) 2007-2008 Steven Rostedt + * + * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box. + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define CALL_BACK 4 + +static unsigned int ftrace_nop = 0x60000000; + +#ifdef CONFIG_PPC32 +# define GET_ADDR(addr) addr +#else +/* PowerPC64's functions are data that points to the functions */ +# define GET_ADDR(addr) *(unsigned long *)addr +#endif + +notrace int ftrace_ip_converted(unsigned long ip) +{ + unsigned int save; + + ip -= CALL_BACK; + save = *(unsigned int *)ip; + + return save == ftrace_nop; +} + +static unsigned int notrace ftrace_calc_offset(long ip, long addr) +{ + return (int)((addr + CALL_BACK) - ip); +} + +notrace unsigned char *ftrace_nop_replace(void) +{ + return (char *)&ftrace_nop; +} + +notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +{ + static unsigned int op; + + addr = GET_ADDR(addr); + + /* Set to "bl addr" */ + op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffe); + + /* + * No locking needed, this must be called via kstop_machine + * which in essence is like running on a uniprocessor machine. + */ + return (unsigned char *)&op; +} + +#ifdef CONFIG_PPC64 +# define _ASM_ALIGN " .align 3 " +# define _ASM_PTR " .llong " +#else +# define _ASM_ALIGN " .align 2 " +# define _ASM_PTR " .long " +#endif + +notrace int +ftrace_modify_code(unsigned long ip, unsigned char *old_code, + unsigned char *new_code) +{ + unsigned replaced; + unsigned old = *(unsigned *)old_code; + unsigned new = *(unsigned *)new_code; + int faulted = 0; + + /* move the IP back to the start of the call */ + ip -= CALL_BACK; + + /* + * Note: Due to modules and __init, code can + * disappear and change, we need to protect against faulting + * as well as code changing. + * + * No real locking needed, this code is run through + * kstop_machine. + */ + asm volatile ( + "1: lwz %1, 0(%2)\n" + " cmpw %1, %5\n" + " bne 2f\n" + " stwu %3, 0(%2)\n" + "2:\n" + ".section .fixup, \"ax\"\n" + "3: li %0, 1\n" + " b 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + _ASM_ALIGN "\n" + _ASM_PTR "1b, 3b\n" + ".previous" + : "=r"(faulted), "=r"(replaced) + : "r"(ip), "r"(new), + "0"(faulted), "r"(old) + : "memory"); + + if (replaced != old && replaced != new) + faulted = 2; + + if (!faulted) + flush_icache_range(ip, ip + 8); + + return faulted; +} + +notrace int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned long ip = (unsigned long)(&ftrace_call); + unsigned char old[4], *new; + int ret; + + ip += CALL_BACK; + + memcpy(old, &ftrace_call, 4); + new = ftrace_call_replace(ip, (unsigned long)func); + ret = ftrace_modify_code(ip, old, new); + + return ret; +} + +notrace int ftrace_mcount_set(unsigned long *data) +{ + unsigned long ip = (long)(&mcount_call); + unsigned long *addr = data; + unsigned char old[4], *new; + + /* ip is at the location, but modify code will subtact this */ + ip += CALL_BACK; + + /* + * Replace the mcount stub with a pointer to the + * ip recorder function. + */ + memcpy(old, &mcount_call, 4); + new = ftrace_call_replace(ip, *addr); + *addr = ftrace_modify_code(ip, old, new); + + return 0; +} + +int __init ftrace_dyn_arch_init(void *data) +{ + /* This is running in kstop_machine */ + + ftrace_mcount_set(data); + + return 0; +} + diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c index e31aca92..1882bf4 100644 --- a/arch/powerpc/kernel/io.c +++ b/arch/powerpc/kernel/io.c @@ -120,7 +120,8 @@ EXPORT_SYMBOL(_outsl_ns); #define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0) -void _memset_io(volatile void __iomem *addr, int c, unsigned long n) +notrace void +_memset_io(volatile void __iomem *addr, int c, unsigned long n) { void *p = (void __force *)addr; u32 lc = c; diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 2f73f70..6e01eb0 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -98,7 +98,7 @@ EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; -static inline unsigned long get_hard_enabled(void) +static inline notrace unsigned long get_hard_enabled(void) { unsigned long enabled; @@ -108,13 +108,13 @@ static inline unsigned long get_hard_enabled(void) return enabled; } -static inline void set_soft_enabled(unsigned long enable) +static inline notrace void set_soft_enabled(unsigned long enable) { __asm__ __volatile__("stb %0,%1(13)" : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled))); } -void raw_local_irq_restore(unsigned long en) +notrace void raw_local_irq_restore(unsigned long en) { /* * get_paca()->soft_enabled = en; diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 5112a4a..22f8e2b 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -47,6 +47,11 @@ #include #endif +#ifdef CONFIG_FTRACE +extern void _mcount(void); +EXPORT_SYMBOL(_mcount); +#endif + extern void bootx_init(unsigned long r4, unsigned long phys); int boot_cpuid; @@ -81,7 +86,7 @@ int ucache_bsize; * from the address that it was linked at, so we must use RELOC/PTRRELOC * to access static data (including strings). -- paulus */ -unsigned long __init early_init(unsigned long dt_ptr) +notrace unsigned long __init early_init(unsigned long dt_ptr) { unsigned long offset = reloc_offset(); struct cpu_spec *spec; @@ -111,7 +116,7 @@ unsigned long __init early_init(unsigned long dt_ptr) * This is called very early on the boot process, after a minimal * MMU environment has been set up but before MMU_init is called. */ -void __init machine_init(unsigned long dt_ptr, unsigned long phys) +notrace void __init machine_init(unsigned long dt_ptr, unsigned long phys) { /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); @@ -133,7 +138,7 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) #ifdef CONFIG_BOOKE_WDT /* Checks wdt=x and wdt_period=xx command-line option */ -int __init early_parse_wdt(char *p) +notrace int __init early_parse_wdt(char *p) { if (p && strncmp(p, "0", 1) != 0) booke_wdt_enabled = 1; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 098fd96..277bf18 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -85,6 +85,11 @@ struct ppc64_caches ppc64_caches = { }; EXPORT_SYMBOL_GPL(ppc64_caches); +#ifdef CONFIG_FTRACE +extern void _mcount(void); +EXPORT_SYMBOL(_mcount); +#endif + /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 4d72c8f..8977417 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -1,5 +1,10 @@ CFLAGS_bootx_init.o += -fPIC +ifdef CONFIG_FTRACE +# Do not trace early boot code +CFLAGS_REMOVE_bootx_init.o = -pg +endif + obj-y += pic.o setup.o time.o feature.o pci.o \ sleep.o low_i2c.o cache.o pfunc_core.o \ pfunc_base.o diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index a5f6001..3877dd9 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -123,6 +123,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, int ret; int save_ftrace_enabled = ftrace_enabled; int save_tracer_enabled = tracer_enabled; + char *func_name; /* The ftrace test PASSED */ printk(KERN_CONT "PASSED\n"); @@ -142,9 +143,15 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, return ret; } + /* + * Some archs *cough*PowerPC*cough* add charachters to the + * start of the function names. We simply put a '*' to + * accomodate them. + */ + func_name = "*" STR(DYN_FTRACE_TEST_NAME); + /* filter only on our function */ - ftrace_set_filter(STR(DYN_FTRACE_TEST_NAME), - sizeof(STR(DYN_FTRACE_TEST_NAME)), 1); + ftrace_set_filter(func_name, strlen(func_name), 1); /* enable tracing */ tr->ctrl = 1; -- cgit v0.10.2 From 656ee82cc855027b2e994ad218519b09fa652cc1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:29 -0400 Subject: kbuild: create new CFLAGS_REMOVE_(basename).o option We currently have a way to add special CFLAGS to code, but we do not have a way to remove them if needed. With the case of ftrace, some files should simply not be profiled. Adding the -pg flag to these files is simply a waste, and adding "notrace" to each and every function is ugly. Currently we put in "Makefile turd" [1] to stop the compiler from adding -pg to certain files. This was clumsy and awkward. This patch now adds the revese of CFLAGS_(basename).o with CFLAGS_REMOVE_(basename).o. This allows developers to prevent certain CFLAGS from being used to compile files. For example, we can now do CFLAGS_REMOVE_string.o = -pg to remove the -pg option from the string.o file in the lib directory. Note: a space delimited list of options may be added to the REMOVE macro. [1] - what David Miller called the workaronud to remove -pg Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8e44023..ea48b82 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -96,7 +96,8 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) +orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) +_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) -- cgit v0.10.2 From 6ec562328fda585be2d7f472cfac99d3b44d362a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:30 -0400 Subject: ftrace: use the new kbuild CFLAGS_REMOVE for kernel directory This patch removes the Makefile turd and uses the nice CFLAGS_REMOVE macro in the kernel directory. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/Makefile b/kernel/Makefile index d2f80ea..ca2433e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -11,12 +11,16 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o +CFLAGS_REMOVE_sched.o = -pg -mno-spe + ifdef CONFIG_FTRACE -# Do not profile debug utilities -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(if $(filter-out lockdep% %debug,$(basename $(notdir $@))), \ - $(ORIG_CFLAGS), \ - $(subst -pg,,$(ORIG_CFLAGS))) +# Do not trace debug files and internal ftrace files +CFLAGS_REMOVE_lockdep.o = -pg +CFLAGS_REMOVE_lockdep_proc.o = -pg +CFLAGS_REMOVE_mutex-debug.o = -pg +CFLAGS_REMOVE_rtmutex-debug.o = -pg +CFLAGS_REMOVE_cgroup-debug.o = -pg +CFLAGS_REMOVE_sched_clock.o = -pg endif obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o -- cgit v0.10.2 From 654e4787689faffdd2137fe91f59fd3ef3363ad2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:31 -0400 Subject: ftrace: use the new kbuild CFLAGS_REMOVE for lib directory This patch removes the Makefile turd and uses the nice CFLAGS_REMOVE macro in the lib directory. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/lib/Makefile b/lib/Makefile index d97ad11..4b836a5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -10,11 +10,11 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ ifdef CONFIG_FTRACE # Do not profile string.o, since it may be used in early boot or vdso +CFLAGS_REMOVE_string.o = -pg # Also do not profile any debug utilities -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(if $(filter-out %debug debug% string%,$(basename $(notdir $@))), \ - $(ORIG_CFLAGS), \ - $(subst -pg,,$(ORIG_CFLAGS))) +CFLAGS_REMOVE_spinlock_debug.o = -pg +CFLAGS_REMOVE_list_debug.o = -pg +CFLAGS_REMOVE_debugobjects.o = -pg endif lib-$(CONFIG_MMU) += ioremap.o -- cgit v0.10.2 From 7fa09f24b477ad41b821713eba757b3aa7a2864a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 May 2008 21:30:32 -0400 Subject: ftrace: use the new kbuild CFLAGS_REMOVE for x86/kernel directory This patch removes the Makefile turd and uses the nice CFLAGS_REMOVE macro in the x86/kernel directory. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index e142091..739d49a 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -6,6 +6,13 @@ extra-y := head_$(BITS).o head$(BITS).o init_task.o vmlinux.lds CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) +ifdef CONFIG_FTRACE +# Do not profile debug utilities +CFLAGS_REMOVE_tsc_64.o = -pg +CFLAGS_REMOVE_tsc_32.o = -pg +CFLAGS_REMOVE_rtc.o = -pg +endif + # # vsyscalls (which work on the user stack) should have # no stack-protector checks: -- cgit v0.10.2 From 677aa9f77e8de3791b481a0cec6c8b84d1eec626 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 17 May 2008 00:01:36 -0400 Subject: ftrace: add have dynamic ftrace config for archs Now that ftrace is being ported to other architectures, it has become apparent that DYNAMIC_FTRACE is dependent on whether or not that architecture implements dynamic ftrace. FTRACE itself may be ported to an architecture without porting dynamic ftrace. This patch adds HAVE_DYNAMIC_FTRACE to allow architectures to port ftrace without having to also port the dynamic aspect as well. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 62d034a..a5e9912 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -105,6 +105,7 @@ config ARCH_NO_VIRT_TO_BUS config PPC bool default y + select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE select HAVE_IDE select HAVE_KPROBES diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index a480df6..fca9246 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -11,6 +11,7 @@ config SPARC config SPARC64 bool default y + select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE select HAVE_IDE select HAVE_LMB diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c742dfe..fc86c54 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -23,6 +23,7 @@ config X86 select HAVE_OPROFILE select HAVE_KPROBES select HAVE_KRETPROBES + select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index f300571..5c2295b 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -4,6 +4,9 @@ config HAVE_FTRACE bool +config HAVE_DYNAMIC_FTRACE + bool + config TRACER_MAX_TRACE bool @@ -94,6 +97,7 @@ config CONTEXT_SWITCH_TRACER config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" depends on FTRACE + depends on HAVE_DYNAMIC_FTRACE default y help This option will modify all the calls to ftrace dynamically -- cgit v0.10.2 From f06c38103ea9dbca27c3f4d77f444ddefb5477cd Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: add sysprof plugin very first baby version. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 5c2295b..e101c9a 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -75,6 +75,14 @@ config PREEMPT_TRACER enabled. This option and the irqs-off timing option can be used together or separately.) +config SYSPROF_TRACER + bool "Sysprof Tracer" + depends on DEBUG_KERNEL + select TRACING + help + This tracer provides the trace needed by the 'Sysprof' userspace + tool. + config SCHED_TRACER bool "Scheduling Latency Tracer" depends on HAVE_FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index d9efbbf..7aec123 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_FTRACE) += libftrace.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o +obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o obj-$(CONFIG_FTRACE) += trace_functions.o obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c new file mode 100644 index 0000000..6c139bc --- /dev/null +++ b/kernel/trace/trace_sysprof.c @@ -0,0 +1,80 @@ +/* + * trace stack traces + * + * Copyright (C) 2007 Steven Rostedt + * Copyright (C) 2008 Ingo Molnar + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +static struct trace_array *ctx_trace; +static int __read_mostly tracer_enabled; + +static notrace void stack_reset(struct trace_array *tr) +{ + int cpu; + + tr->time_start = ftrace_now(tr->cpu); + + for_each_online_cpu(cpu) + tracing_reset(tr->data[cpu]); +} + +static notrace void start_stack_trace(struct trace_array *tr) +{ + stack_reset(tr); + tracer_enabled = 1; +} + +static notrace void stop_stack_trace(struct trace_array *tr) +{ + tracer_enabled = 0; +} + +static notrace void stack_trace_init(struct trace_array *tr) +{ + ctx_trace = tr; + + if (tr->ctrl) + start_stack_trace(tr); +} + +static notrace void stack_trace_reset(struct trace_array *tr) +{ + if (tr->ctrl) + stop_stack_trace(tr); +} + +static void stack_trace_ctrl_update(struct trace_array *tr) +{ + /* When starting a new trace, reset the buffers */ + if (tr->ctrl) + start_stack_trace(tr); + else + stop_stack_trace(tr); +} + +static struct tracer stack_trace __read_mostly = +{ + .name = "sysprof", + .init = stack_trace_init, + .reset = stack_trace_reset, + .ctrl_update = stack_trace_ctrl_update, +#ifdef CONFIG_FTRACE_SELFTEST + .selftest = trace_selftest_startup_stack, +#endif +}; + +__init static int init_stack_trace(void) +{ + return register_tracer(&stack_trace); +} +device_initcall(init_stack_trace); -- cgit v0.10.2 From 0075fa80305f3231a2d5df97b00d7f55a48ea27e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: extend sysprof plugin add per CPU hrtimers. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 6c139bc..ba55b87 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -5,19 +5,76 @@ * Copyright (C) 2008 Ingo Molnar * */ -#include -#include -#include #include +#include +#include #include -#include #include +#include +#include #include "trace.h" static struct trace_array *ctx_trace; static int __read_mostly tracer_enabled; +static const unsigned long sample_period = 1000000; + +/* + * Per CPU hrtimers that do the profiling: + */ +static DEFINE_PER_CPU(struct hrtimer, stack_trace_hrtimer); + +static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer) +{ + /* trace here */ + panic_timeout++; + + hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period)); + + return HRTIMER_RESTART; +} + +static void start_stack_timer(int cpu) +{ + struct hrtimer *hrtimer = &per_cpu(stack_trace_hrtimer, cpu); + + hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer->function = stack_trace_timer_fn; + hrtimer->cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; + + hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL); +} + +static void start_stack_timers(void) +{ + cpumask_t saved_mask = current->cpus_allowed; + int cpu; + + for_each_online_cpu(cpu) { + set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); + start_stack_timer(cpu); + printk("started timer on cpu%d\n", cpu); + } + set_cpus_allowed_ptr(current, &saved_mask); +} + +static void stop_stack_timer(int cpu) +{ + struct hrtimer *hrtimer = &per_cpu(stack_trace_hrtimer, cpu); + + hrtimer_cancel(hrtimer); + printk("cancelled timer on cpu%d\n", cpu); +} + +static void stop_stack_timers(void) +{ + int cpu; + + for_each_online_cpu(cpu) + stop_stack_timer(cpu); +} + static notrace void stack_reset(struct trace_array *tr) { int cpu; @@ -31,11 +88,13 @@ static notrace void stack_reset(struct trace_array *tr) static notrace void start_stack_trace(struct trace_array *tr) { stack_reset(tr); + start_stack_timers(); tracer_enabled = 1; } static notrace void stop_stack_trace(struct trace_array *tr) { + stop_stack_timers(); tracer_enabled = 0; } -- cgit v0.10.2 From 56a08bdcff20f0022bd9160c1093e56f763499aa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: extend sysprof plugin some more Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index ba55b87..b1137c1 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -3,7 +3,7 @@ * * Copyright (C) 2007 Steven Rostedt * Copyright (C) 2008 Ingo Molnar - * + * Copyright (C) 2004, 2005, Soeren Sandmann */ #include #include @@ -11,13 +11,17 @@ #include #include #include +#include #include #include "trace.h" -static struct trace_array *ctx_trace; +static struct trace_array *sysprof_trace; static int __read_mostly tracer_enabled; +/* + * 10 msecs for now: + */ static const unsigned long sample_period = 1000000; /* @@ -25,10 +29,78 @@ static const unsigned long sample_period = 1000000; */ static DEFINE_PER_CPU(struct hrtimer, stack_trace_hrtimer); +struct stack_frame { + const void __user *next_fp; + unsigned long return_address; +}; + +static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) +{ + if (!access_ok(VERIFY_READ, fp, sizeof(*frame))) + return 0; + + if (__copy_from_user_inatomic(frame, frame_pointer, sizeof(*frame))) + return 0; + + return 1; +} + +#define SYSPROF_MAX_ADDRESSES 512 + +static void timer_notify(struct pt_regs *regs, int cpu) +{ + const void __user *frame_pointer; + struct trace_array_cpu *data; + struct stack_frame frame; + struct trace_array *tr; + int is_user; + int i; + + if (!regs) + return; + + tr = sysprof_trace; + data = tr->data[cpu]; + is_user = user_mode(regs); + + if (!current || current->pid == 0) + return; + + if (is_user && current->state != TASK_RUNNING) + return; + + if (!is_user) { + /* kernel */ + ftrace(tr, data, current->pid, 1, 0); + return; + + } + + trace_special(tr, data, 0, current->pid, regs->ip); + + frame_pointer = (void __user *)regs->bp; + + for (i = 0; i < SYSPROF_MAX_ADDRESSES; i++) { + if (!copy_stack_frame(frame_pointer, &frame)) + break; + if ((unsigned long)frame_pointer < regs->sp) + break; + + trace_special(tr, data, 1, frame.return_address, + (unsigned long)frame_pointer); + frame_pointer = frame.next_fp; + } + + trace_special(tr, data, 2, current->pid, i); + + if (i == SYSPROF_MAX_ADDRESSES) + trace_special(tr, data, -1, -1, -1); +} + static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer) { /* trace here */ - panic_timeout++; + timer_notify(get_irq_regs(), smp_processor_id()); hrtimer_forward_now(hrtimer, ns_to_ktime(sample_period)); @@ -100,7 +172,7 @@ static notrace void stop_stack_trace(struct trace_array *tr) static notrace void stack_trace_init(struct trace_array *tr) { - ctx_trace = tr; + sysprof_trace = tr; if (tr->ctrl) start_stack_trace(tr); -- cgit v0.10.2 From a6dd24f8d00cbccb560b19a723e6fb9bdfb20799 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: sysprof-plugin, add self-tests Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c460e85..b2198bc 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -280,6 +280,10 @@ extern int trace_selftest_startup_wakeup(struct tracer *trace, extern int trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr); #endif +#ifdef CONFIG_SYSPROF_TRACER +extern int trace_selftest_startup_sysprof(struct tracer *trace, + struct trace_array *tr); +#endif #endif /* CONFIG_FTRACE_STARTUP_TEST */ extern void *head_page(struct trace_array_cpu *data); diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 3877dd9..033a6fb 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -537,3 +537,31 @@ trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr return ret; } #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ + +#ifdef CONFIG_SYSPROF_TRACER +int +trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr) +{ + unsigned long count; + int ret; + + /* start the tracing */ + tr->ctrl = 1; + trace->init(tr); + /* Sleep for a 1/10 of a second */ + msleep(100); + /* stop the tracing. */ + tr->ctrl = 0; + trace->ctrl_update(tr); + /* check the trace buffer */ + ret = trace_test_buffer(tr, &count); + trace->reset(tr); + + if (!ret && !count) { + printk(KERN_CONT ".. no entries found .."); + ret = -1; + } + + return ret; +} +#endif /* CONFIG_SYSPROF_TRACER */ diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index b1137c1..b78f12f 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -126,7 +126,7 @@ static void start_stack_timers(void) for_each_online_cpu(cpu) { set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); start_stack_timer(cpu); - printk("started timer on cpu%d\n", cpu); + printk(KERN_INFO "started sysprof timer on cpu%d\n", cpu); } set_cpus_allowed_ptr(current, &saved_mask); } @@ -136,7 +136,7 @@ static void stop_stack_timer(int cpu) struct hrtimer *hrtimer = &per_cpu(stack_trace_hrtimer, cpu); hrtimer_cancel(hrtimer); - printk("cancelled timer on cpu%d\n", cpu); + printk(KERN_INFO "cancelled sysprof timer on cpu%d\n", cpu); } static void stop_stack_timers(void) @@ -200,7 +200,7 @@ static struct tracer stack_trace __read_mostly = .reset = stack_trace_reset, .ctrl_update = stack_trace_ctrl_update, #ifdef CONFIG_FTRACE_SELFTEST - .selftest = trace_selftest_startup_stack, + .selftest = trace_selftest_startup_sysprof, #endif }; -- cgit v0.10.2 From 842af315e8b0adad58fc642eaa5e6f53525e0534 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:47 +0200 Subject: ftrace: sysprof plugin improvement add sample maximum depth. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index b78f12f..7f6fccc 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -23,6 +23,7 @@ static int __read_mostly tracer_enabled; * 10 msecs for now: */ static const unsigned long sample_period = 1000000; +static const unsigned int sample_max_depth = 512; /* * Per CPU hrtimers that do the profiling: @@ -45,8 +46,6 @@ static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) return 1; } -#define SYSPROF_MAX_ADDRESSES 512 - static void timer_notify(struct pt_regs *regs, int cpu) { const void __user *frame_pointer; @@ -80,7 +79,7 @@ static void timer_notify(struct pt_regs *regs, int cpu) frame_pointer = (void __user *)regs->bp; - for (i = 0; i < SYSPROF_MAX_ADDRESSES; i++) { + for (i = 0; i < sample_max_depth; i++) { if (!copy_stack_frame(frame_pointer, &frame)) break; if ((unsigned long)frame_pointer < regs->sp) @@ -93,7 +92,7 @@ static void timer_notify(struct pt_regs *regs, int cpu) trace_special(tr, data, 2, current->pid, i); - if (i == SYSPROF_MAX_ADDRESSES) + if (i == sample_max_depth) trace_special(tr, data, -1, -1, -1); } @@ -126,7 +125,6 @@ static void start_stack_timers(void) for_each_online_cpu(cpu) { set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); start_stack_timer(cpu); - printk(KERN_INFO "started sysprof timer on cpu%d\n", cpu); } set_cpus_allowed_ptr(current, &saved_mask); } @@ -136,7 +134,6 @@ static void stop_stack_timer(int cpu) struct hrtimer *hrtimer = &per_cpu(stack_trace_hrtimer, cpu); hrtimer_cancel(hrtimer); - printk(KERN_INFO "cancelled sysprof timer on cpu%d\n", cpu); } static void stop_stack_timers(void) -- cgit v0.10.2 From ef4ab15ff34fd9c65e92bee70f58e7179da881c5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace: make sysprof dependent on x86 for now that's the only tested platform for now. If there's interest we can make it generic easily. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e101c9a..9b49526 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -77,7 +77,7 @@ config PREEMPT_TRACER config SYSPROF_TRACER bool "Sysprof Tracer" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && X86 select TRACING help This tracer provides the trace needed by the 'Sysprof' userspace diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 033a6fb..5588ecc 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -557,11 +557,6 @@ trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr) ret = trace_test_buffer(tr, &count); trace->reset(tr); - if (!ret && !count) { - printk(KERN_CONT ".. no entries found .."); - ret = -1; - } - return ret; } #endif /* CONFIG_SYSPROF_TRACER */ -- cgit v0.10.2 From 9f6b4e3f4a24f2590f1c96f117fc45fbea9b0fa4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:48 +0200 Subject: ftrace: sysprof fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 7f6fccc..f9a09fe 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -37,21 +37,26 @@ struct stack_frame { static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) { + int ret; + if (!access_ok(VERIFY_READ, fp, sizeof(*frame))) return 0; - if (__copy_from_user_inatomic(frame, frame_pointer, sizeof(*frame))) - return 0; + ret = 1; + pagefault_disable(); + if (__copy_from_user_inatomic(frame, fp, sizeof(*frame))) + ret = 0; + pagefault_enable(); - return 1; + return ret; } static void timer_notify(struct pt_regs *regs, int cpu) { - const void __user *frame_pointer; struct trace_array_cpu *data; struct stack_frame frame; struct trace_array *tr; + const void __user *fp; int is_user; int i; @@ -77,21 +82,26 @@ static void timer_notify(struct pt_regs *regs, int cpu) trace_special(tr, data, 0, current->pid, regs->ip); - frame_pointer = (void __user *)regs->bp; + fp = (void __user *)regs->bp; for (i = 0; i < sample_max_depth; i++) { - if (!copy_stack_frame(frame_pointer, &frame)) + frame.next_fp = 0; + frame.return_address = 0; + if (!copy_stack_frame(fp, &frame)) break; - if ((unsigned long)frame_pointer < regs->sp) + if ((unsigned long)fp < regs->sp) break; trace_special(tr, data, 1, frame.return_address, - (unsigned long)frame_pointer); - frame_pointer = frame.next_fp; + (unsigned long)fp); + fp = frame.next_fp; } trace_special(tr, data, 2, current->pid, i); + /* + * Special trace entry if we overflow the max depth: + */ if (i == sample_max_depth) trace_special(tr, data, -1, -1, -1); } -- cgit v0.10.2 From d618b3e6e50970a6248ac857653fdd49bcd3c045 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:49 +0200 Subject: ftrace: sysprof updates make the sample period configurable. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3271916..95b7c48 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2800,6 +2800,9 @@ static __init void tracer_init_debugfs(void) pr_warning("Could not create debugfs " "'dyn_ftrace_total_info' entry\n"); #endif +#ifdef CONFIG_SYSPROF_TRACER + init_tracer_sysprof_debugfs(d_tracer); +#endif } static int trace_alloc_page(void) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b2198bc..b7f85d9 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -188,6 +188,8 @@ struct trace_iterator { void tracing_reset(struct trace_array_cpu *data); int tracing_open_generic(struct inode *inode, struct file *filp); struct dentry *tracing_init_dentry(void); +void init_tracer_sysprof_debugfs(struct dentry *d_tracer); + void ftrace(struct trace_array *tr, struct trace_array_cpu *data, unsigned long ip, diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index f9a09fe..1940623 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -20,11 +20,12 @@ static struct trace_array *sysprof_trace; static int __read_mostly tracer_enabled; /* - * 10 msecs for now: + * 1 msec sample interval by default: */ -static const unsigned long sample_period = 1000000; +static unsigned long sample_period = 1000000; static const unsigned int sample_max_depth = 512; +static DEFINE_MUTEX(sample_timer_lock); /* * Per CPU hrtimers that do the profiling: */ @@ -166,15 +167,19 @@ static notrace void stack_reset(struct trace_array *tr) static notrace void start_stack_trace(struct trace_array *tr) { + mutex_lock(&sample_timer_lock); stack_reset(tr); start_stack_timers(); tracer_enabled = 1; + mutex_unlock(&sample_timer_lock); } static notrace void stop_stack_trace(struct trace_array *tr) { + mutex_lock(&sample_timer_lock); stop_stack_timers(); tracer_enabled = 0; + mutex_unlock(&sample_timer_lock); } static notrace void stack_trace_init(struct trace_array *tr) @@ -216,3 +221,64 @@ __init static int init_stack_trace(void) return register_tracer(&stack_trace); } device_initcall(init_stack_trace); + +#define MAX_LONG_DIGITS 22 + +static ssize_t +sysprof_sample_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[MAX_LONG_DIGITS]; + int r; + + r = sprintf(buf, "%ld\n", nsecs_to_usecs(sample_period)); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t +sysprof_sample_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[MAX_LONG_DIGITS]; + unsigned long val; + + if (cnt > MAX_LONG_DIGITS-1) + cnt = MAX_LONG_DIGITS-1; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + buf[cnt] = 0; + + val = simple_strtoul(buf, NULL, 10); + /* + * Enforce a minimum sample period of 100 usecs: + */ + if (val < 100) + val = 100; + + mutex_lock(&sample_timer_lock); + stop_stack_timers(); + sample_period = val * 1000; + start_stack_timers(); + mutex_unlock(&sample_timer_lock); + + return cnt; +} + +static struct file_operations sysprof_sample_fops = { + .read = sysprof_sample_read, + .write = sysprof_sample_write, +}; + +void init_tracer_sysprof_debugfs(struct dentry *d_tracer) +{ + struct dentry *entry; + + entry = debugfs_create_file("sysprof_sample_period", 0644, + d_tracer, NULL, &sysprof_sample_fops); + if (entry) + return; + pr_warning("Could not create debugfs 'dyn_ftrace_total_info' entry\n"); +} -- cgit v0.10.2 From ada6b835067dc022f11cdae1c313a3710d3d977c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 23:50:41 +0200 Subject: ftrace: remove notrace Remove the notrace annotations. The build logic takes care of that. Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 1940623..3b1e4ba 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -155,7 +155,7 @@ static void stop_stack_timers(void) stop_stack_timer(cpu); } -static notrace void stack_reset(struct trace_array *tr) +static void stack_reset(struct trace_array *tr) { int cpu; @@ -165,7 +165,7 @@ static notrace void stack_reset(struct trace_array *tr) tracing_reset(tr->data[cpu]); } -static notrace void start_stack_trace(struct trace_array *tr) +static void start_stack_trace(struct trace_array *tr) { mutex_lock(&sample_timer_lock); stack_reset(tr); @@ -174,7 +174,7 @@ static notrace void start_stack_trace(struct trace_array *tr) mutex_unlock(&sample_timer_lock); } -static notrace void stop_stack_trace(struct trace_array *tr) +static void stop_stack_trace(struct trace_array *tr) { mutex_lock(&sample_timer_lock); stop_stack_timers(); @@ -182,7 +182,7 @@ static notrace void stop_stack_trace(struct trace_array *tr) mutex_unlock(&sample_timer_lock); } -static notrace void stack_trace_init(struct trace_array *tr) +static void stack_trace_init(struct trace_array *tr) { sysprof_trace = tr; @@ -190,7 +190,7 @@ static notrace void stack_trace_init(struct trace_array *tr) start_stack_trace(tr); } -static notrace void stack_trace_reset(struct trace_array *tr) +static void stack_trace_reset(struct trace_array *tr) { if (tr->ctrl) stop_stack_trace(tr); -- cgit v0.10.2 From 9caee613d3b860ae81b79370eeae9ac967c07536 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 23:55:54 +0200 Subject: ftrace: fix __trace_special() Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 3b1e4ba..76dd953 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -81,7 +81,7 @@ static void timer_notify(struct pt_regs *regs, int cpu) } - trace_special(tr, data, 0, current->pid, regs->ip); + __trace_special(tr, data, 0, current->pid, regs->ip); fp = (void __user *)regs->bp; @@ -93,18 +93,18 @@ static void timer_notify(struct pt_regs *regs, int cpu) if ((unsigned long)fp < regs->sp) break; - trace_special(tr, data, 1, frame.return_address, + __trace_special(tr, data, 1, frame.return_address, (unsigned long)fp); fp = frame.next_fp; } - trace_special(tr, data, 2, current->pid, i); + __trace_special(tr, data, 2, current->pid, i); /* * Special trace entry if we overflow the max depth: */ if (i == sample_max_depth) - trace_special(tr, data, -1, -1, -1); + __trace_special(tr, data, -1, -1, -1); } static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer) -- cgit v0.10.2 From 5fc4511c756860149b81aead6eca5bdf5c438ea7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 23 May 2008 23:58:21 +0200 Subject: ftrace: make it more available in the Kconfig Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 9b49526..e101c9a 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -77,7 +77,7 @@ config PREEMPT_TRACER config SYSPROF_TRACER bool "Sysprof Tracer" - depends on DEBUG_KERNEL && X86 + depends on DEBUG_KERNEL select TRACING help This tracer provides the trace needed by the 'Sysprof' userspace -- cgit v0.10.2 From cd2134b1dda92fd450e6a1e12b1c7960dd6a2178 Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Pedersen Date: Mon, 12 May 2008 21:20:54 +0200 Subject: sysprof: kernel trace add kernel backtracing to the sysprof tracer. change the format of the data, so that type=0 means beginning of stack trace, 1 means kernel address, 2 means user address, and 3 means end of trace. EIP addresses are no longer distinguished from return addresses, mostly because sysprof userspace doesn't make use of it. It may be worthwhile adding this back in though, just in case it becomes interesting. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index 76dd953..ebcb66d 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -14,6 +14,8 @@ #include #include +#include + #include "trace.h" static struct trace_array *sysprof_trace; @@ -52,6 +54,77 @@ static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) return ret; } +struct backtrace_info { + struct trace_array_cpu *data; + struct trace_array *tr; + int pos; +}; + +static void +backtrace_warning_symbol(void *data, char *msg, unsigned long symbol) +{ + /* Ignore warnings */ +} + +static void backtrace_warning(void *data, char *msg) +{ + /* Ignore warnings */ +} + +static int backtrace_stack(void *data, char *name) +{ + /* Don't bother with IRQ stacks for now */ + return -1; +} + +static void backtrace_address(void *data, unsigned long addr, int reliable) +{ + struct backtrace_info *info = data; + + if (info->pos < sample_max_depth && reliable) { + __trace_special(info->tr, info->data, 1, addr, 0); + + info->pos++; + } +} + +const static struct stacktrace_ops backtrace_ops = { + .warning = backtrace_warning, + .warning_symbol = backtrace_warning_symbol, + .stack = backtrace_stack, + .address = backtrace_address, +}; + +static struct pt_regs * +trace_kernel(struct pt_regs *regs, struct trace_array *tr, + struct trace_array_cpu *data) +{ + struct backtrace_info info; + unsigned long bp; + char *user_stack; + char *stack; + + info.tr = tr; + info.data = data; + info.pos = 1; + + __trace_special(info.tr, info.data, 1, regs->ip, 0); + + stack = ((char *)regs + sizeof(struct pt_regs)); +#ifdef CONFIG_FRAME_POINTER + bp = regs->bp; +#else + bp = 0; +#endif + + dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, &info); + + /* Now trace the user stack */ + user_stack = ((char *)current->thread.sp0 - sizeof(struct pt_regs)); + + return (struct pt_regs *)user_stack; +} + static void timer_notify(struct pt_regs *regs, int cpu) { struct trace_array_cpu *data; @@ -74,17 +147,15 @@ static void timer_notify(struct pt_regs *regs, int cpu) if (is_user && current->state != TASK_RUNNING) return; - if (!is_user) { - /* kernel */ - ftrace(tr, data, current->pid, 1, 0); - return; + __trace_special(tr, data, 0, 0, current->pid); - } - - __trace_special(tr, data, 0, current->pid, regs->ip); + if (!is_user) + regs = trace_kernel(regs, tr, data); fp = (void __user *)regs->bp; + __trace_special(tr, data, 2, regs->ip, 0); + for (i = 0; i < sample_max_depth; i++) { frame.next_fp = 0; frame.return_address = 0; @@ -93,12 +164,12 @@ static void timer_notify(struct pt_regs *regs, int cpu) if ((unsigned long)fp < regs->sp) break; - __trace_special(tr, data, 1, frame.return_address, + __trace_special(tr, data, 2, frame.return_address, (unsigned long)fp); fp = frame.next_fp; } - __trace_special(tr, data, 2, current->pid, i); + __trace_special(tr, data, 3, current->pid, i); /* * Special trace entry if we overflow the max depth: -- cgit v0.10.2 From 8a9e94c1fbfdac45a3b6811b880777c4116aa309 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:54 +0200 Subject: sysprof: update copyrights Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index ebcb66d..fe23d6d 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -1,9 +1,9 @@ /* * trace stack traces * + * Copyright (C) 2004-2008, Soeren Sandmann * Copyright (C) 2007 Steven Rostedt * Copyright (C) 2008 Ingo Molnar - * Copyright (C) 2004, 2005, Soeren Sandmann */ #include #include -- cgit v0.10.2 From cf3271a73b612a03da00681ecd9bfefab37c74c9 Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Date: Mon, 12 May 2008 05:28:50 +0200 Subject: ftrace/sysprof: don't trace the user stack if we are a kernel thread. Check that current->mm is non-NULL before attempting to trace the user stack. Also take depth of the kernel stack into account when comparing against sample_max_depth. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index fe23d6d..2301e1e 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -95,13 +95,12 @@ const static struct stacktrace_ops backtrace_ops = { .address = backtrace_address, }; -static struct pt_regs * +static int trace_kernel(struct pt_regs *regs, struct trace_array *tr, struct trace_array_cpu *data) { struct backtrace_info info; unsigned long bp; - char *user_stack; char *stack; info.tr = tr; @@ -119,10 +118,7 @@ trace_kernel(struct pt_regs *regs, struct trace_array *tr, dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, &info); - /* Now trace the user stack */ - user_stack = ((char *)current->thread.sp0 - sizeof(struct pt_regs)); - - return (struct pt_regs *)user_stack; + return info.pos; } static void timer_notify(struct pt_regs *regs, int cpu) @@ -150,32 +146,44 @@ static void timer_notify(struct pt_regs *regs, int cpu) __trace_special(tr, data, 0, 0, current->pid); if (!is_user) - regs = trace_kernel(regs, tr, data); + i = trace_kernel(regs, tr, data); + else + i = 0; - fp = (void __user *)regs->bp; + /* + * Trace user stack if we are not a kernel thread + */ + if (current->mm && i < sample_max_depth) { + regs = (struct pt_regs *)current->thread.sp0 - 1; - __trace_special(tr, data, 2, regs->ip, 0); + fp = (void __user *)regs->bp; - for (i = 0; i < sample_max_depth; i++) { - frame.next_fp = 0; - frame.return_address = 0; - if (!copy_stack_frame(fp, &frame)) - break; - if ((unsigned long)fp < regs->sp) - break; + __trace_special(tr, data, 2, regs->ip, 0); - __trace_special(tr, data, 2, frame.return_address, - (unsigned long)fp); - fp = frame.next_fp; - } + while (i < sample_max_depth) { + frame.next_fp = 0; + frame.return_address = 0; + if (!copy_stack_frame(fp, &frame)) + break; + if ((unsigned long)fp < regs->sp) + break; - __trace_special(tr, data, 3, current->pid, i); + __trace_special(tr, data, 2, frame.return_address, + (unsigned long)fp); + fp = frame.next_fp; + + i++; + } + + } /* * Special trace entry if we overflow the max depth: */ if (i == sample_max_depth) __trace_special(tr, data, -1, -1, -1); + + __trace_special(tr, data, 3, current->pid, i); } static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer) -- cgit v0.10.2 From bfeeeeb991cf75081e6c2f74d44ae5da05b50a94 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 May 2008 21:21:14 +0200 Subject: stacktrace: don't crash on invalid stack trace structs This patch makes the stacktrace printout code \warn when the entries pointer is unset rather than crashing when trying to access it in an attempt to make it a bit more robust. I was saving a stacktrace into an skb and forgot to copy it across skb copies... I have since fixed the code, but it would have been easier had the kernel not crashed in an interrupt. Signed-off-by: Johannes Berg Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c index b71816e..0914d0c 100644 --- a/kernel/stacktrace.c +++ b/kernel/stacktrace.c @@ -13,6 +13,9 @@ void print_stack_trace(struct stack_trace *trace, int spaces) { int i, j; + if (WARN_ON(!trace->entries)) + return; + for (i = 0; i < trace->nr_entries; i++) { unsigned long ip = trace->entries[i]; -- cgit v0.10.2 From 8b7d89d02ef3c6a7c73d6596f28cea7632850af4 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: x86: mmiotrace - trace memory mapped IO Mmiotrace is a tool for trapping memory mapped IO (MMIO) accesses within the kernel. It is used for debugging and especially for reverse engineering evil binary drivers. Mmiotrace works by wrapping the ioremap family of kernel functions and marking the returned pages as not present. Access to the IO memory triggers a page fault, which will be handled by mmiotrace's custom page fault handler. This will single-step the faulted instruction with the MMIO page marked as present. Access logs are directed to user space via relay and debug_fs. This page fault approach is necessary, because binary drivers have readl/writel etc. calls inlined and therefore extremely difficult to trap with with e.g. kprobes. This patch depends on the custom page fault handlers patch. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9431a83..7c6496e 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -176,6 +176,33 @@ config PAGE_FAULT_HANDLERS register a function that is called on every page fault. Custom handlers are used by some debugging and reverse engineering tools. +config MMIOTRACE + tristate "Memory mapped IO tracing" + depends on DEBUG_KERNEL && PAGE_FAULT_HANDLERS && RELAY && DEBUG_FS + default n + help + This will build a kernel module called mmiotrace. + + Mmiotrace traces Memory Mapped I/O access and is meant for debugging + and reverse engineering. The kernel module offers wrapped + versions of the ioremap family of functions. The driver to be traced + must be modified to call these wrappers. A user space program is + required to collect the MMIO data. + + See http://nouveau.freedesktop.org/wiki/MmioTrace + If you are not helping to develop drivers, say N. + +config MMIOTRACE_TEST + tristate "Test module for mmiotrace" + depends on MMIOTRACE && m + default n + 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 --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 739d49a..a51ac15 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -79,6 +79,8 @@ obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_VM86) += vm86_32.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_MMIOTRACE) += mmiotrace/ + obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index a4f93b4..027a5b6 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c @@ -15,6 +15,7 @@ static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */ +EXPORT_SYMBOL_GPL(init_mm); /* * Initial thread structure. diff --git a/arch/x86/kernel/mmiotrace/Makefile b/arch/x86/kernel/mmiotrace/Makefile new file mode 100644 index 0000000..d6905f7 --- /dev/null +++ b/arch/x86/kernel/mmiotrace/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MMIOTRACE) += mmiotrace.o +mmiotrace-objs := pf_in.o kmmio.o mmio-mod.o + +obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c new file mode 100644 index 0000000..8ba48f9 --- /dev/null +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -0,0 +1,391 @@ +/* Support for MMIO probes. + * Benfit many code from kprobes + * (C) 2002 Louis Zhuang . + * 2007 Alexander Eichner + * 2008 Pekka Paalanen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kmmio.h" + +#define KMMIO_HASH_BITS 6 +#define KMMIO_TABLE_SIZE (1 << KMMIO_HASH_BITS) +#define KMMIO_PAGE_HASH_BITS 4 +#define KMMIO_PAGE_TABLE_SIZE (1 << KMMIO_PAGE_HASH_BITS) + +struct kmmio_context { + struct kmmio_fault_page *fpage; + struct kmmio_probe *probe; + unsigned long saved_flags; + int active; +}; + +static int kmmio_page_fault(struct pt_regs *regs, unsigned long error_code, + unsigned long address); +static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, + void *args); + +static DEFINE_SPINLOCK(kmmio_lock); + +/* These are protected by kmmio_lock */ +unsigned int kmmio_count; +static unsigned int handler_registered; +static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; +static LIST_HEAD(kmmio_probes); + +static struct kmmio_context kmmio_ctx[NR_CPUS]; + +static struct pf_handler kmmio_pf_hook = { + .handler = kmmio_page_fault +}; + +static struct notifier_block nb_die = { + .notifier_call = kmmio_die_notifier +}; + +int init_kmmio(void) +{ + int i; + for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) + INIT_LIST_HEAD(&kmmio_page_table[i]); + + register_die_notifier(&nb_die); + return 0; +} + +void cleanup_kmmio(void) +{ + /* + * Assume the following have been already cleaned by calling + * unregister_kmmio_probe() appropriately: + * kmmio_page_table, kmmio_probes + */ + if (handler_registered) { + unregister_page_fault_handler(&kmmio_pf_hook); + synchronize_rcu(); + } + unregister_die_notifier(&nb_die); +} + +/* + * this is basically a dynamic stabbing problem: + * Could use the existing prio tree code or + * Possible better implementations: + * The Interval Skip List: A Data Structure for Finding All Intervals That + * Overlap a Point (might be simple) + * Space Efficient Dynamic Stabbing with Fast Queries - Mikkel Thorup + */ +/* Get the kmmio at this addr (if any). You must be holding kmmio_lock. */ +static struct kmmio_probe *get_kmmio_probe(unsigned long addr) +{ + struct kmmio_probe *p; + list_for_each_entry(p, &kmmio_probes, list) { + if (addr >= p->addr && addr <= (p->addr + p->len)) + return p; + } + return NULL; +} + +static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) +{ + struct list_head *head, *tmp; + + page &= PAGE_MASK; + head = &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)]; + list_for_each(tmp, head) { + struct kmmio_fault_page *p + = list_entry(tmp, struct kmmio_fault_page, list); + if (p->page == page) + return p; + } + + return NULL; +} + +static void arm_kmmio_fault_page(unsigned long page, int *large) +{ + unsigned long address = page & PAGE_MASK; + pgd_t *pgd = pgd_offset_k(address); + pud_t *pud = pud_offset(pgd, address); + pmd_t *pmd = pmd_offset(pud, address); + pte_t *pte = pte_offset_kernel(pmd, address); + + if (pmd_large(*pmd)) { + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_PRESENT)); + if (large) + *large = 1; + } else { + set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); + } + + __flush_tlb_one(page); +} + +static void disarm_kmmio_fault_page(unsigned long page, int *large) +{ + unsigned long address = page & PAGE_MASK; + pgd_t *pgd = pgd_offset_k(address); + pud_t *pud = pud_offset(pgd, address); + pmd_t *pmd = pmd_offset(pud, address); + pte_t *pte = pte_offset_kernel(pmd, address); + + if (large && *large) { + set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_PRESENT)); + *large = 0; + } else { + set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); + } + + __flush_tlb_one(page); +} + +/* + * Interrupts are disabled on entry as trap3 is an interrupt gate + * and they remain disabled thorough out this function. + */ +static int kmmio_handler(struct pt_regs *regs, unsigned long addr) +{ + struct kmmio_context *ctx; + int cpu; + + /* + * Preemption is now disabled to prevent process switch during + * single stepping. We can only handle one active kmmio trace + * per cpu, so ensure that we finish it before something else + * gets to run. + * + * XXX what if an interrupt occurs between returning from + * do_page_fault() and entering the single-step exception handler? + * And that interrupt triggers a kmmio trap? + */ + preempt_disable(); + cpu = smp_processor_id(); + ctx = &kmmio_ctx[cpu]; + + /* interrupts disabled and CPU-local data => atomicity guaranteed. */ + if (ctx->active) { + /* + * This avoids a deadlock with kmmio_lock. + * If this page fault really was due to kmmio trap, + * all hell breaks loose. + */ + printk(KERN_EMERG "mmiotrace: recursive probe hit on CPU %d, " + "for address %lu. Ignoring.\n", + cpu, addr); + goto no_kmmio; + } + ctx->active++; + + /* + * Acquire the kmmio lock to prevent changes affecting + * get_kmmio_fault_page() and get_kmmio_probe(), since we save their + * returned pointers. + * The lock is released in post_kmmio_handler(). + * XXX: could/should get_kmmio_*() be using RCU instead of spinlock? + */ + spin_lock(&kmmio_lock); + + ctx->fpage = get_kmmio_fault_page(addr); + if (!ctx->fpage) { + /* this page fault is not caused by kmmio */ + goto no_kmmio_locked; + } + + ctx->probe = get_kmmio_probe(addr); + ctx->saved_flags = (regs->flags & (TF_MASK|IF_MASK)); + + if (ctx->probe && ctx->probe->pre_handler) + ctx->probe->pre_handler(ctx->probe, regs, addr); + + regs->flags |= TF_MASK; + regs->flags &= ~IF_MASK; + + /* We hold lock, now we set present bit in PTE and single step. */ + disarm_kmmio_fault_page(ctx->fpage->page, NULL); + + return 1; + +no_kmmio_locked: + spin_unlock(&kmmio_lock); + ctx->active--; +no_kmmio: + preempt_enable_no_resched(); + /* page fault not handled by kmmio */ + return 0; +} + +/* + * Interrupts are disabled on entry as trap1 is an interrupt gate + * and they remain disabled thorough out this function. + * And we hold kmmio lock. + */ +static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + struct kmmio_context *ctx = &kmmio_ctx[cpu]; + + if (!ctx->active) + return 0; + + if (ctx->probe && ctx->probe->post_handler) + ctx->probe->post_handler(ctx->probe, condition, regs); + + arm_kmmio_fault_page(ctx->fpage->page, NULL); + + regs->flags &= ~TF_MASK; + regs->flags |= ctx->saved_flags; + + /* These were acquired in kmmio_handler(). */ + ctx->active--; + spin_unlock(&kmmio_lock); + preempt_enable_no_resched(); + + /* + * if somebody else is singlestepping across a probe point, flags + * will have TF set, in which case, continue the remaining processing + * of do_debug, as if this is not a probe hit. + */ + if (regs->flags & TF_MASK) + return 0; + + return 1; +} + +static int add_kmmio_fault_page(unsigned long page) +{ + struct kmmio_fault_page *f; + + page &= PAGE_MASK; + f = get_kmmio_fault_page(page); + if (f) { + f->count++; + return 0; + } + + f = kmalloc(sizeof(*f), GFP_ATOMIC); + if (!f) + return -1; + + f->count = 1; + f->page = page; + list_add(&f->list, + &kmmio_page_table[hash_long(f->page, KMMIO_PAGE_HASH_BITS)]); + + arm_kmmio_fault_page(f->page, NULL); + + return 0; +} + +static void release_kmmio_fault_page(unsigned long page) +{ + struct kmmio_fault_page *f; + + page &= PAGE_MASK; + f = get_kmmio_fault_page(page); + if (!f) + return; + + f->count--; + if (!f->count) { + disarm_kmmio_fault_page(f->page, NULL); + list_del(&f->list); + } +} + +int register_kmmio_probe(struct kmmio_probe *p) +{ + int ret = 0; + unsigned long size = 0; + + spin_lock_irq(&kmmio_lock); + kmmio_count++; + if (get_kmmio_probe(p->addr)) { + ret = -EEXIST; + goto out; + } + list_add(&p->list, &kmmio_probes); + /*printk("adding fault pages...\n");*/ + while (size < p->len) { + if (add_kmmio_fault_page(p->addr + size)) + printk(KERN_ERR "mmio: Unable to set page fault.\n"); + size += PAGE_SIZE; + } + + if (!handler_registered) { + register_page_fault_handler(&kmmio_pf_hook); + handler_registered++; + } + +out: + spin_unlock_irq(&kmmio_lock); + /* + * XXX: What should I do here? + * Here was a call to global_flush_tlb(), but it does not exist + * anymore. + */ + return ret; +} + +void unregister_kmmio_probe(struct kmmio_probe *p) +{ + unsigned long size = 0; + + spin_lock_irq(&kmmio_lock); + while (size < p->len) { + release_kmmio_fault_page(p->addr + size); + size += PAGE_SIZE; + } + list_del(&p->list); + kmmio_count--; + spin_unlock_irq(&kmmio_lock); +} + +/* + * According to 2.6.20, mainly x86_64 arch: + * This is being called from do_page_fault(), via the page fault notifier + * chain. The chain is called for both user space faults and kernel space + * faults (address >= TASK_SIZE64), except not on faults serviced by + * vmalloc_fault(). + * + * We may be in an interrupt or a critical section. Also prefecthing may + * trigger a page fault. We may be in the middle of process switch. + * The page fault hook functionality has put us inside RCU read lock. + * + * Local interrupts are disabled, so preemption cannot happen. + * Do not enable interrupts, do not sleep, and watch out for other CPUs. + */ +static int kmmio_page_fault(struct pt_regs *regs, unsigned long error_code, + unsigned long address) +{ + if (is_kmmio_active()) + if (kmmio_handler(regs, address) == 1) + return -1; + return 0; +} + +static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, + void *args) +{ + struct die_args *arg = args; + + if (val == DIE_DEBUG) + if (post_kmmio_handler(arg->err, arg->regs) == 1) + return NOTIFY_STOP; + + return NOTIFY_DONE; +} diff --git a/arch/x86/kernel/mmiotrace/kmmio.h b/arch/x86/kernel/mmiotrace/kmmio.h new file mode 100644 index 0000000..85b7f68 --- /dev/null +++ b/arch/x86/kernel/mmiotrace/kmmio.h @@ -0,0 +1,58 @@ +#ifndef _LINUX_KMMIO_H +#define _LINUX_KMMIO_H + +#include +#include +#include +#include +#include +#include +#include + +struct kmmio_probe; +struct kmmio_fault_page; +struct pt_regs; + +typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *, + struct pt_regs *, unsigned long addr); +typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, + unsigned long condition, struct pt_regs *); + +struct kmmio_probe { + struct list_head list; + + /* start location of the probe point */ + unsigned long addr; + + /* length of the probe region */ + unsigned long len; + + /* Called before addr is executed. */ + kmmio_pre_handler_t pre_handler; + + /* Called after addr is executed, unless... */ + kmmio_post_handler_t post_handler; +}; + +struct kmmio_fault_page { + struct list_head list; + + /* location of the fault page */ + unsigned long page; + + int count; +}; + +/* kmmio is active by some kmmio_probes? */ +static inline int is_kmmio_active(void) +{ + extern unsigned int kmmio_count; + return kmmio_count; +} + +int init_kmmio(void); +void cleanup_kmmio(void); +int register_kmmio_probe(struct kmmio_probe *p); +void unregister_kmmio_probe(struct kmmio_probe *p); + +#endif /* _LINUX_KMMIO_H */ diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c new file mode 100644 index 0000000..73561fe --- /dev/null +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -0,0 +1,527 @@ +/* + * 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) IBM Corporation, 2005 + * Jeff Muizelaar, 2006, 2007 + * Pekka Paalanen, 2008 + * + * Derived from the read-mod example from relay-examples by Tom Zanussi. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for ISA_START_ADDRESS */ + +#include "kmmio.h" +#include "pf_in.h" + +/* This app's relay channel files will appear in /debug/mmio-trace */ +#define APP_DIR "mmio-trace" +/* the marker injection file in /proc */ +#define MARKER_FILE "mmio-marker" + +#define MODULE_NAME "mmiotrace" + +struct trap_reason { + unsigned long addr; + unsigned long ip; + enum reason_type type; + int active_traces; +}; + +static struct trap_reason pf_reason[NR_CPUS]; +static struct mm_io_header_rw cpu_trace[NR_CPUS]; + +static struct file_operations mmio_fops = { + .owner = THIS_MODULE, +}; + +static const size_t subbuf_size = 256*1024; +static struct rchan *chan; +static struct dentry *dir; +static int suspended; /* XXX should this be per cpu? */ +static struct proc_dir_entry *proc_marker_file; + +/* module parameters */ +static unsigned int n_subbufs = 32*4; +static unsigned long filter_offset; +static int nommiotrace; +static int ISA_trace; +static int trace_pc; + +module_param(n_subbufs, uint, 0); +module_param(filter_offset, ulong, 0); +module_param(nommiotrace, bool, 0); +module_param(ISA_trace, bool, 0); +module_param(trace_pc, bool, 0); + +MODULE_PARM_DESC(n_subbufs, "Number of 256kB buffers, default 128."); +MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); +MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); +MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); +MODULE_PARM_DESC(trace_pc, "Record address of faulting instructions."); + +static void record_timestamp(struct mm_io_header *header) +{ + struct timespec now; + + getnstimeofday(&now); + header->sec = now.tv_sec; + header->nsec = now.tv_nsec; +} + +/* + * Write callback for the /proc entry: + * Read a marker and write it to the mmio trace log + */ +static int write_marker(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + char *event = NULL; + struct mm_io_header *headp; + int len = (count > 65535) ? 65535 : count; + + event = kzalloc(sizeof(*headp) + len, GFP_KERNEL); + if (!event) + return -ENOMEM; + + headp = (struct mm_io_header *)event; + headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT); + headp->data_len = len; + record_timestamp(headp); + + if (copy_from_user(event + sizeof(*headp), buffer, len)) { + kfree(event); + return -EFAULT; + } + + relay_write(chan, event, sizeof(*headp) + len); + kfree(event); + return len; +} + +static void print_pte(unsigned long address) +{ + pgd_t *pgd = pgd_offset_k(address); + pud_t *pud = pud_offset(pgd, address); + pmd_t *pmd = pmd_offset(pud, address); + if (pmd_large(*pmd)) { + printk(KERN_EMERG MODULE_NAME ": 4MB pages are not " + "currently supported: %lx\n", + address); + BUG(); + } + printk(KERN_DEBUG MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", + address, + pte_val(*pte_offset_kernel(pmd, address)), + pte_val(*pte_offset_kernel(pmd, address)) & _PAGE_PRESENT); +} + +/* + * For some reason the pre/post pairs have been called in an + * unmatched order. Report and die. + */ +static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) +{ + const unsigned long cpu = smp_processor_id(); + printk(KERN_EMERG MODULE_NAME ": unexpected fault for address: %lx, " + "last fault for address: %lx\n", + addr, pf_reason[cpu].addr); + print_pte(addr); +#ifdef __i386__ + print_symbol(KERN_EMERG "faulting EIP is at %s\n", regs->ip); + print_symbol(KERN_EMERG "last faulting EIP was at %s\n", + pf_reason[cpu].ip); + printk(KERN_EMERG + "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", + regs->ax, regs->bx, regs->cx, regs->dx); + printk(KERN_EMERG + "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", + regs->si, regs->di, regs->bp, regs->sp); +#else + print_symbol(KERN_EMERG "faulting RIP is at %s\n", regs->ip); + print_symbol(KERN_EMERG "last faulting RIP was at %s\n", + pf_reason[cpu].ip); + printk(KERN_EMERG "rax: %016lx rcx: %016lx rdx: %016lx\n", + regs->ax, regs->cx, regs->dx); + printk(KERN_EMERG "rsi: %016lx rdi: %016lx " + "rbp: %016lx rsp: %016lx\n", + regs->si, regs->di, regs->bp, regs->sp); +#endif + BUG(); +} + +static void pre(struct kmmio_probe *p, struct pt_regs *regs, + unsigned long addr) +{ + const unsigned long cpu = smp_processor_id(); + const unsigned long instptr = instruction_pointer(regs); + const enum reason_type type = get_ins_type(instptr); + + /* it doesn't make sense to have more than one active trace per cpu */ + if (pf_reason[cpu].active_traces) + die_kmmio_nesting_error(regs, addr); + else + pf_reason[cpu].active_traces++; + + pf_reason[cpu].type = type; + pf_reason[cpu].addr = addr; + pf_reason[cpu].ip = instptr; + + cpu_trace[cpu].header.type = MMIO_MAGIC; + cpu_trace[cpu].header.pid = 0; + cpu_trace[cpu].header.data_len = sizeof(struct mm_io_rw); + cpu_trace[cpu].rw.address = addr; + + /* + * Only record the program counter when requested. + * It may taint clean-room reverse engineering. + */ + if (trace_pc) + cpu_trace[cpu].rw.pc = instptr; + else + cpu_trace[cpu].rw.pc = 0; + + record_timestamp(&cpu_trace[cpu].header); + + switch (type) { + case REG_READ: + cpu_trace[cpu].header.type |= + (MMIO_READ << MMIO_OPCODE_SHIFT) | + (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); + break; + case REG_WRITE: + cpu_trace[cpu].header.type |= + (MMIO_WRITE << MMIO_OPCODE_SHIFT) | + (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); + cpu_trace[cpu].rw.value = get_ins_reg_val(instptr, regs); + break; + case IMM_WRITE: + cpu_trace[cpu].header.type |= + (MMIO_WRITE << MMIO_OPCODE_SHIFT) | + (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); + cpu_trace[cpu].rw.value = get_ins_imm_val(instptr); + break; + default: + { + unsigned char *ip = (unsigned char *)instptr; + cpu_trace[cpu].header.type |= + (MMIO_UNKNOWN_OP << MMIO_OPCODE_SHIFT); + cpu_trace[cpu].rw.value = (*ip) << 16 | + *(ip + 1) << 8 | + *(ip + 2); + } + } +} + +static void post(struct kmmio_probe *p, unsigned long condition, + struct pt_regs *regs) +{ + const unsigned long cpu = smp_processor_id(); + + /* this should always return the active_trace count to 0 */ + pf_reason[cpu].active_traces--; + if (pf_reason[cpu].active_traces) { + printk(KERN_EMERG MODULE_NAME ": unexpected post handler"); + BUG(); + } + + switch (pf_reason[cpu].type) { + case REG_READ: + cpu_trace[cpu].rw.value = get_ins_reg_val(pf_reason[cpu].ip, + regs); + break; + default: + break; + } + relay_write(chan, &cpu_trace[cpu], sizeof(struct mm_io_header_rw)); +} + +/* + * subbuf_start() relay callback. + * + * Defined so that we know when events are dropped due to the buffer-full + * condition. + */ +static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, + void *prev_subbuf, size_t prev_padding) +{ + if (relay_buf_full(buf)) { + if (!suspended) { + suspended = 1; + printk(KERN_ERR MODULE_NAME + ": cpu %d buffer full!!!\n", + smp_processor_id()); + } + return 0; + } else if (suspended) { + suspended = 0; + printk(KERN_ERR MODULE_NAME + ": cpu %d buffer no longer full.\n", + smp_processor_id()); + } + + return 1; +} + +/* file_create() callback. Creates relay file in debugfs. */ +static struct dentry *create_buf_file_handler(const char *filename, + struct dentry *parent, + int mode, + struct rchan_buf *buf, + int *is_global) +{ + struct dentry *buf_file; + + mmio_fops.read = relay_file_operations.read; + mmio_fops.open = relay_file_operations.open; + mmio_fops.poll = relay_file_operations.poll; + mmio_fops.mmap = relay_file_operations.mmap; + mmio_fops.release = relay_file_operations.release; + mmio_fops.splice_read = relay_file_operations.splice_read; + + buf_file = debugfs_create_file(filename, mode, parent, buf, + &mmio_fops); + + return buf_file; +} + +/* file_remove() default callback. Removes relay file in debugfs. */ +static int remove_buf_file_handler(struct dentry *dentry) +{ + debugfs_remove(dentry); + return 0; +} + +static struct rchan_callbacks relay_callbacks = { + .subbuf_start = subbuf_start_handler, + .create_buf_file = create_buf_file_handler, + .remove_buf_file = remove_buf_file_handler, +}; + +/* + * create_channel - creates channel /debug/APP_DIR/cpuXXX + * Returns channel on success, NULL otherwise + */ +static struct rchan *create_channel(unsigned size, unsigned n) +{ + return relay_open("cpu", dir, size, n, &relay_callbacks, NULL); +} + +/* destroy_channel - destroys channel /debug/APP_DIR/cpuXXX */ +static void destroy_channel(void) +{ + if (chan) { + relay_close(chan); + chan = NULL; + } +} + +struct remap_trace { + struct list_head list; + struct kmmio_probe probe; +}; +static LIST_HEAD(trace_list); +static DEFINE_SPINLOCK(trace_list_lock); + +static void do_ioremap_trace_core(unsigned long offset, unsigned long size, + void __iomem *addr) +{ + struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); + struct mm_io_header_map event = { + .header = { + .type = MMIO_MAGIC | + (MMIO_PROBE << MMIO_OPCODE_SHIFT), + .sec = 0, + .nsec = 0, + .pid = 0, + .data_len = sizeof(struct mm_io_map) + }, + .map = { + .phys = offset, + .addr = (unsigned long)addr, + .len = size, + .pc = 0 + } + }; + record_timestamp(&event.header); + + *trace = (struct remap_trace) { + .probe = { + .addr = (unsigned long)addr, + .len = size, + .pre_handler = pre, + .post_handler = post, + } + }; + + relay_write(chan, &event, sizeof(event)); + spin_lock(&trace_list_lock); + list_add_tail(&trace->list, &trace_list); + spin_unlock(&trace_list_lock); + if (!nommiotrace) + register_kmmio_probe(&trace->probe); +} + +static void ioremap_trace_core(unsigned long offset, unsigned long size, + void __iomem *addr) +{ + if ((filter_offset) && (offset != filter_offset)) + return; + + /* Don't trace the low PCI/ISA area, it's always mapped.. */ + if (!ISA_trace && (offset < ISA_END_ADDRESS) && + (offset + size > ISA_START_ADDRESS)) { + printk(KERN_NOTICE MODULE_NAME ": Ignoring map of low " + "PCI/ISA area (0x%lx-0x%lx)\n", + offset, offset + size); + return; + } + do_ioremap_trace_core(offset, size, addr); +} + +void __iomem *ioremap_cache_trace(unsigned long offset, unsigned long size) +{ + void __iomem *p = ioremap_cache(offset, size); + printk(KERN_DEBUG MODULE_NAME ": ioremap_cache(0x%lx, 0x%lx) = %p\n", + offset, size, p); + ioremap_trace_core(offset, size, p); + return p; +} +EXPORT_SYMBOL(ioremap_cache_trace); + +void __iomem *ioremap_nocache_trace(unsigned long offset, unsigned long size) +{ + void __iomem *p = ioremap_nocache(offset, size); + printk(KERN_DEBUG MODULE_NAME ": ioremap_nocache(0x%lx, 0x%lx) = %p\n", + offset, size, p); + ioremap_trace_core(offset, size, p); + return p; +} +EXPORT_SYMBOL(ioremap_nocache_trace); + +void iounmap_trace(volatile void __iomem *addr) +{ + struct mm_io_header_map event = { + .header = { + .type = MMIO_MAGIC | + (MMIO_UNPROBE << MMIO_OPCODE_SHIFT), + .sec = 0, + .nsec = 0, + .pid = 0, + .data_len = sizeof(struct mm_io_map) + }, + .map = { + .phys = 0, + .addr = (unsigned long)addr, + .len = 0, + .pc = 0 + } + }; + struct remap_trace *trace; + struct remap_trace *tmp; + printk(KERN_DEBUG MODULE_NAME ": Unmapping %p.\n", addr); + record_timestamp(&event.header); + + spin_lock(&trace_list_lock); + list_for_each_entry_safe(trace, tmp, &trace_list, list) { + if ((unsigned long)addr == trace->probe.addr) { + if (!nommiotrace) + unregister_kmmio_probe(&trace->probe); + list_del(&trace->list); + kfree(trace); + break; + } + } + spin_unlock(&trace_list_lock); + relay_write(chan, &event, sizeof(event)); + iounmap(addr); +} +EXPORT_SYMBOL(iounmap_trace); + +static void clear_trace_list(void) +{ + struct remap_trace *trace; + struct remap_trace *tmp; + + spin_lock(&trace_list_lock); + list_for_each_entry_safe(trace, tmp, &trace_list, list) { + printk(KERN_WARNING MODULE_NAME ": purging non-iounmapped " + "trace @0x%08lx, size 0x%lx.\n", + trace->probe.addr, trace->probe.len); + if (!nommiotrace) + unregister_kmmio_probe(&trace->probe); + list_del(&trace->list); + kfree(trace); + break; + } + spin_unlock(&trace_list_lock); +} + +static int __init init(void) +{ + if (n_subbufs < 2) + return -EINVAL; + + dir = debugfs_create_dir(APP_DIR, NULL); + if (!dir) { + printk(KERN_ERR MODULE_NAME + ": Couldn't create relay app directory.\n"); + return -ENOMEM; + } + + chan = create_channel(subbuf_size, n_subbufs); + if (!chan) { + debugfs_remove(dir); + printk(KERN_ERR MODULE_NAME + ": relay app channel creation failed\n"); + return -ENOMEM; + } + + init_kmmio(); + + proc_marker_file = create_proc_entry(MARKER_FILE, 0, NULL); + if (proc_marker_file) + proc_marker_file->write_proc = write_marker; + + printk(KERN_DEBUG MODULE_NAME ": loaded.\n"); + if (nommiotrace) + printk(KERN_DEBUG MODULE_NAME ": MMIO tracing disabled.\n"); + if (ISA_trace) + printk(KERN_WARNING MODULE_NAME + ": Warning! low ISA range will be traced.\n"); + return 0; +} + +static void __exit cleanup(void) +{ + printk(KERN_DEBUG MODULE_NAME ": unload...\n"); + clear_trace_list(); + cleanup_kmmio(); + remove_proc_entry(MARKER_FILE, NULL); + destroy_channel(); + if (dir) + debugfs_remove(dir); +} + +module_init(init); +module_exit(cleanup); +MODULE_LICENSE("GPL"); diff --git a/arch/x86/kernel/mmiotrace/pf_in.c b/arch/x86/kernel/mmiotrace/pf_in.c new file mode 100644 index 0000000..67ea520 --- /dev/null +++ b/arch/x86/kernel/mmiotrace/pf_in.c @@ -0,0 +1,489 @@ +/* + * Fault Injection Test harness (FI) + * Copyright (C) Intel Crop. + * + * 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. + * + */ + +/* $Id: pf_in.c,v 1.1.1.1 2002/11/12 05:56:32 brlock Exp $ + * Copyright by Intel Crop., 2002 + * Louis Zhuang (louis.zhuang@intel.com) + * + * Bjorn Steinbrink (B.Steinbrink@gmx.de), 2007 + */ + +#include +#include /* struct pt_regs */ +#include "pf_in.h" + +#ifdef __i386__ +/* IA32 Manual 3, 2-1 */ +static unsigned char prefix_codes[] = { + 0xF0, 0xF2, 0xF3, 0x2E, 0x36, 0x3E, 0x26, 0x64, + 0x65, 0x2E, 0x3E, 0x66, 0x67 +}; +/* IA32 Manual 3, 3-432*/ +static unsigned int reg_rop[] = { + 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +static unsigned int reg_wop[] = { 0x88, 0x89 }; +static unsigned int imm_wop[] = { 0xC6, 0xC7 }; +/* IA32 Manual 3, 3-432*/ +static unsigned int rw8[] = { 0x88, 0x8A, 0xC6 }; +static unsigned int rw32[] = { + 0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F }; +static unsigned int mw16[] = { 0xB70F, 0xBF0F }; +static unsigned int mw32[] = { 0x89, 0x8B, 0xC7 }; +static unsigned int mw64[] = {}; +#else /* not __i386__ */ +static unsigned char prefix_codes[] = { + 0x66, 0x67, 0x2E, 0x3E, 0x26, 0x64, 0x65, 0x36, + 0xF0, 0xF3, 0xF2, + /* REX Prefixes */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; +/* AMD64 Manual 3, Appendix A*/ +static unsigned int reg_rop[] = { + 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +static unsigned int reg_wop[] = { 0x88, 0x89 }; +static unsigned int imm_wop[] = { 0xC6, 0xC7 }; +static unsigned int rw8[] = { 0xC6, 0x88, 0x8A }; +static unsigned int rw32[] = { + 0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +/* 8 bit only */ +static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F }; +/* 16 bit only */ +static unsigned int mw16[] = { 0xB70F, 0xBF0F }; +/* 16 or 32 bit */ +static unsigned int mw32[] = { 0xC7 }; +/* 16, 32 or 64 bit */ +static unsigned int mw64[] = { 0x89, 0x8B }; +#endif /* not __i386__ */ + +static int skip_prefix(unsigned char *addr, int *shorted, int *enlarged, + int *rexr) +{ + int i; + unsigned char *p = addr; + *shorted = 0; + *enlarged = 0; + *rexr = 0; + +restart: + for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) { + if (*p == prefix_codes[i]) { + if (*p == 0x66) + *shorted = 1; +#ifdef __amd64__ + if ((*p & 0xf8) == 0x48) + *enlarged = 1; + if ((*p & 0xf4) == 0x44) + *rexr = 1; +#endif + p++; + goto restart; + } + } + + return (p - addr); +} + +static int get_opcode(unsigned char *addr, unsigned int *opcode) +{ + int len; + + if (*addr == 0x0F) { + /* 0x0F is extension instruction */ + *opcode = *(unsigned short *)addr; + len = 2; + } else { + *opcode = *addr; + len = 1; + } + + return len; +} + +#define CHECK_OP_TYPE(opcode, array, type) \ + for (i = 0; i < ARRAY_SIZE(array); i++) { \ + if (array[i] == opcode) { \ + rv = type; \ + goto exit; \ + } \ + } + +enum reason_type get_ins_type(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char *p; + int shorted, enlarged, rexr; + int i; + enum reason_type rv = OTHERS; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + + CHECK_OP_TYPE(opcode, reg_rop, REG_READ); + CHECK_OP_TYPE(opcode, reg_wop, REG_WRITE); + CHECK_OP_TYPE(opcode, imm_wop, IMM_WRITE); + +exit: + return rv; +} +#undef CHECK_OP_TYPE + +static unsigned int get_ins_reg_width(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char *p; + int i, shorted, enlarged, rexr; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + + for (i = 0; i < ARRAY_SIZE(rw8); i++) + if (rw8[i] == opcode) + return 1; + + for (i = 0; i < ARRAY_SIZE(rw32); i++) + if (rw32[i] == opcode) + return (shorted ? 2 : (enlarged ? 8 : 4)); + + printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); + return 0; +} + +unsigned int get_ins_mem_width(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char *p; + int i, shorted, enlarged, rexr; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + + for (i = 0; i < ARRAY_SIZE(mw8); i++) + if (mw8[i] == opcode) + return 1; + + for (i = 0; i < ARRAY_SIZE(mw16); i++) + if (mw16[i] == opcode) + return 2; + + for (i = 0; i < ARRAY_SIZE(mw32); i++) + if (mw32[i] == opcode) + return shorted ? 2 : 4; + + for (i = 0; i < ARRAY_SIZE(mw64); i++) + if (mw64[i] == opcode) + return shorted ? 2 : (enlarged ? 8 : 4); + + printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); + return 0; +} + +/* + * Define register ident in mod/rm byte. + * Note: these are NOT the same as in ptrace-abi.h. + */ +enum { + arg_AL = 0, + arg_CL = 1, + arg_DL = 2, + arg_BL = 3, + arg_AH = 4, + arg_CH = 5, + arg_DH = 6, + arg_BH = 7, + + arg_AX = 0, + arg_CX = 1, + arg_DX = 2, + arg_BX = 3, + arg_SP = 4, + arg_BP = 5, + arg_SI = 6, + arg_DI = 7, +#ifdef __amd64__ + arg_R8 = 8, + arg_R9 = 9, + arg_R10 = 10, + arg_R11 = 11, + arg_R12 = 12, + arg_R13 = 13, + arg_R14 = 14, + arg_R15 = 15 +#endif +}; + +static unsigned char *get_reg_w8(int no, struct pt_regs *regs) +{ + unsigned char *rv = NULL; + + switch (no) { + case arg_AL: + rv = (unsigned char *)®s->ax; + break; + case arg_BL: + rv = (unsigned char *)®s->bx; + break; + case arg_CL: + rv = (unsigned char *)®s->cx; + break; + case arg_DL: + rv = (unsigned char *)®s->dx; + break; + case arg_AH: + rv = 1 + (unsigned char *)®s->ax; + break; + case arg_BH: + rv = 1 + (unsigned char *)®s->bx; + break; + case arg_CH: + rv = 1 + (unsigned char *)®s->cx; + break; + case arg_DH: + rv = 1 + (unsigned char *)®s->dx; + break; +#ifdef __amd64__ + case arg_R8: + rv = (unsigned char *)®s->r8; + break; + case arg_R9: + rv = (unsigned char *)®s->r9; + break; + case arg_R10: + rv = (unsigned char *)®s->r10; + break; + case arg_R11: + rv = (unsigned char *)®s->r11; + break; + case arg_R12: + rv = (unsigned char *)®s->r12; + break; + case arg_R13: + rv = (unsigned char *)®s->r13; + break; + case arg_R14: + rv = (unsigned char *)®s->r14; + break; + case arg_R15: + rv = (unsigned char *)®s->r15; + break; +#endif + default: + printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); + break; + } + return rv; +} + +static unsigned long *get_reg_w32(int no, struct pt_regs *regs) +{ + unsigned long *rv = NULL; + + switch (no) { + case arg_AX: + rv = ®s->ax; + break; + case arg_BX: + rv = ®s->bx; + break; + case arg_CX: + rv = ®s->cx; + break; + case arg_DX: + rv = ®s->dx; + break; + case arg_SP: + rv = ®s->sp; + break; + case arg_BP: + rv = ®s->bp; + break; + case arg_SI: + rv = ®s->si; + break; + case arg_DI: + rv = ®s->di; + break; +#ifdef __amd64__ + case arg_R8: + rv = ®s->r8; + break; + case arg_R9: + rv = ®s->r9; + break; + case arg_R10: + rv = ®s->r10; + break; + case arg_R11: + rv = ®s->r11; + break; + case arg_R12: + rv = ®s->r12; + break; + case arg_R13: + rv = ®s->r13; + break; + case arg_R14: + rv = ®s->r14; + break; + case arg_R15: + rv = ®s->r15; + break; +#endif + default: + printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); + } + + return rv; +} + +unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs) +{ + unsigned int opcode; + unsigned char mod_rm; + int reg; + unsigned char *p; + int i, shorted, enlarged, rexr; + unsigned long rv; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + for (i = 0; i < ARRAY_SIZE(reg_rop); i++) + if (reg_rop[i] == opcode) { + rv = REG_READ; + goto do_work; + } + + for (i = 0; i < ARRAY_SIZE(reg_wop); i++) + if (reg_wop[i] == opcode) { + rv = REG_WRITE; + goto do_work; + } + + printk(KERN_ERR "mmiotrace: Not a register instruction, opcode " + "0x%02x\n", opcode); + goto err; + +do_work: + mod_rm = *p; + reg = ((mod_rm >> 3) & 0x7) | (rexr << 3); + switch (get_ins_reg_width(ins_addr)) { + case 1: + return *get_reg_w8(reg, regs); + + case 2: + return *(unsigned short *)get_reg_w32(reg, regs); + + case 4: + return *(unsigned int *)get_reg_w32(reg, regs); + +#ifdef __amd64__ + case 8: + return *(unsigned long *)get_reg_w32(reg, regs); +#endif + + default: + printk(KERN_ERR "mmiotrace: Error width# %d\n", reg); + } + +err: + return 0; +} + +unsigned long get_ins_imm_val(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char mod_rm; + unsigned char mod; + unsigned char *p; + int i, shorted, enlarged, rexr; + unsigned long rv; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + for (i = 0; i < ARRAY_SIZE(imm_wop); i++) + if (imm_wop[i] == opcode) { + rv = IMM_WRITE; + goto do_work; + } + + printk(KERN_ERR "mmiotrace: Not an immediate instruction, opcode " + "0x%02x\n", opcode); + goto err; + +do_work: + mod_rm = *p; + mod = mod_rm >> 6; + p++; + switch (mod) { + case 0: + /* if r/m is 5 we have a 32 disp (IA32 Manual 3, Table 2-2) */ + /* AMD64: XXX Check for address size prefix? */ + if ((mod_rm & 0x7) == 0x5) + p += 4; + break; + + case 1: + p += 1; + break; + + case 2: + p += 4; + break; + + case 3: + default: + printk(KERN_ERR "mmiotrace: not a memory access instruction " + "at 0x%lx, rm_mod=0x%02x\n", + ins_addr, mod_rm); + } + + switch (get_ins_reg_width(ins_addr)) { + case 1: + return *(unsigned char *)p; + + case 2: + return *(unsigned short *)p; + + case 4: + return *(unsigned int *)p; + +#ifdef __amd64__ + case 8: + return *(unsigned long *)p; +#endif + + default: + printk(KERN_ERR "mmiotrace: Error: width.\n"); + } + +err: + return 0; +} diff --git a/arch/x86/kernel/mmiotrace/pf_in.h b/arch/x86/kernel/mmiotrace/pf_in.h new file mode 100644 index 0000000..e05341a --- /dev/null +++ b/arch/x86/kernel/mmiotrace/pf_in.h @@ -0,0 +1,39 @@ +/* + * Fault Injection Test harness (FI) + * Copyright (C) Intel Crop. + * + * 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 __PF_H_ +#define __PF_H_ + +enum reason_type { + NOT_ME, /* page fault is not in regions */ + NOTHING, /* access others point in regions */ + REG_READ, /* read from addr to reg */ + REG_WRITE, /* write from reg to addr */ + IMM_WRITE, /* write from imm to addr */ + OTHERS /* Other instructions can not intercept */ +}; + +enum reason_type get_ins_type(unsigned long ins_addr); +unsigned int get_ins_mem_width(unsigned long ins_addr); +unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs); +unsigned long get_ins_imm_val(unsigned long ins_addr); + +#endif /* __PF_H_ */ diff --git a/arch/x86/kernel/mmiotrace/testmmiotrace.c b/arch/x86/kernel/mmiotrace/testmmiotrace.c new file mode 100644 index 0000000..40e66b0 --- /dev/null +++ b/arch/x86/kernel/mmiotrace/testmmiotrace.c @@ -0,0 +1,77 @@ +/* + * Written by Pekka Paalanen, 2008 + */ +#include +#include + +extern void __iomem *ioremap_nocache_trace(unsigned long offset, + unsigned long size); +extern void iounmap_trace(volatile void __iomem *addr); + +#define MODULE_NAME "testmmiotrace" + +static unsigned long mmio_address; +module_param(mmio_address, ulong, 0); +MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB."); + +static void do_write_test(void __iomem *p) +{ + unsigned int i; + for (i = 0; i < 256; i++) + iowrite8(i, p + i); + for (i = 1024; i < (5 * 1024); i += 2) + iowrite16(i * 12 + 7, p + i); + for (i = (5 * 1024); i < (16 * 1024); i += 4) + iowrite32(i * 212371 + 13, p + i); +} + +static void do_read_test(void __iomem *p) +{ + unsigned int i; + volatile unsigned int v; + for (i = 0; i < 256; i++) + v = ioread8(p + i); + for (i = 1024; i < (5 * 1024); i += 2) + v = ioread16(p + i); + for (i = (5 * 1024); i < (16 * 1024); i += 4) + v = ioread32(p + i); +} + +static void do_test(void) +{ + void __iomem *p = ioremap_nocache_trace(mmio_address, 0x4000); + if (!p) { + printk(KERN_ERR MODULE_NAME ": could not ioremap IO memory, " + "aborting.\n"); + return; + } + do_write_test(p); + do_read_test(p); + iounmap_trace(p); +} + +static int __init init(void) +{ + if (mmio_address == 0) { + printk(KERN_ERR MODULE_NAME ": you have to use the module " + "argument mmio_address.\n"); + printk(KERN_ERR MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" + " YOU REALLY KNOW WHAT YOU ARE DOING!\n"); + return -ENXIO; + } + + printk(KERN_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; +} + +static void __exit cleanup(void) +{ + printk(KERN_DEBUG MODULE_NAME ": unloaded.\n"); +} + +module_init(init); +module_exit(cleanup); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h new file mode 100644 index 0000000..cb24782 --- /dev/null +++ b/include/linux/mmiotrace.h @@ -0,0 +1,62 @@ +#ifndef MMIOTRACE_H +#define MMIOTRACE_H + +#include + +#define MMIO_VERSION 0x04 + +/* mm_io_header.type */ +#define MMIO_OPCODE_MASK 0xff +#define MMIO_OPCODE_SHIFT 0 +#define MMIO_WIDTH_MASK 0xff00 +#define MMIO_WIDTH_SHIFT 8 +#define MMIO_MAGIC (0x6f000000 | (MMIO_VERSION<<16)) +#define MMIO_MAGIC_MASK 0xffff0000 + +enum mm_io_opcode { /* payload type: */ + MMIO_READ = 0x1, /* struct mm_io_rw */ + MMIO_WRITE = 0x2, /* struct mm_io_rw */ + MMIO_PROBE = 0x3, /* struct mm_io_map */ + MMIO_UNPROBE = 0x4, /* struct mm_io_map */ + MMIO_MARKER = 0x5, /* raw char data */ + MMIO_UNKNOWN_OP = 0x6, /* struct mm_io_rw */ +}; + +struct mm_io_header { + __u32 type; + __u32 sec; /* timestamp */ + __u32 nsec; + __u32 pid; /* PID of the process, or 0 for kernel core */ + __u16 data_len; /* length of the following payload */ +}; + +struct mm_io_rw { + __u64 address; /* virtual address of register */ + __u64 value; + __u64 pc; /* optional program counter */ +}; + +struct mm_io_map { + __u64 phys; /* base address in PCI space */ + __u64 addr; /* base virtual address */ + __u64 len; /* mapping size */ + __u64 pc; /* optional program counter */ +}; + + +/* + * These structures are used to allow a single relay_write() + * call to write a full packet. + */ + +struct mm_io_header_rw { + struct mm_io_header header; + struct mm_io_rw rw; +} __attribute__((packed)); + +struct mm_io_header_map { + struct mm_io_header header; + struct mm_io_map map; +} __attribute__((packed)); + +#endif /* MMIOTRACE_H */ -- cgit v0.10.2 From 75bb88350e0501b3cf5ac096a1008757844414a9 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: x86 mmiotrace: use lookup_address() Use lookup_address() from pageattr.c instead of doing the same manually. Also had to EXPORT_SYMBOL_GPL(lookup_address) to make this work for modules. This also fixes "undefined symbol 'init_mm'" compile error for x86_32. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index 8ba48f9..28411da 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "kmmio.h" @@ -117,40 +118,55 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) return NULL; } -static void arm_kmmio_fault_page(unsigned long page, int *large) +static void arm_kmmio_fault_page(unsigned long page, int *page_level) { unsigned long address = page & PAGE_MASK; - pgd_t *pgd = pgd_offset_k(address); - pud_t *pud = pud_offset(pgd, address); - pmd_t *pmd = pmd_offset(pud, address); - pte_t *pte = pte_offset_kernel(pmd, address); + int level; + pte_t *pte = lookup_address(address, &level); - if (pmd_large(*pmd)) { + if (!pte) { + printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", + __FUNCTION__, page); + return; + } + + if (level == PG_LEVEL_2M) { + pmd_t *pmd = (pmd_t *)pte; set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_PRESENT)); - if (large) - *large = 1; } else { + /* PG_LEVEL_4K */ set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); } + if (page_level) + *page_level = level; + __flush_tlb_one(page); } -static void disarm_kmmio_fault_page(unsigned long page, int *large) +static void disarm_kmmio_fault_page(unsigned long page, int *page_level) { unsigned long address = page & PAGE_MASK; - pgd_t *pgd = pgd_offset_k(address); - pud_t *pud = pud_offset(pgd, address); - pmd_t *pmd = pmd_offset(pud, address); - pte_t *pte = pte_offset_kernel(pmd, address); + int level; + pte_t *pte = lookup_address(address, &level); - if (large && *large) { + if (!pte) { + printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", + __FUNCTION__, page); + return; + } + + if (level == PG_LEVEL_2M) { + pmd_t *pmd = (pmd_t *)pte; set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_PRESENT)); - *large = 0; } else { + /* PG_LEVEL_4K */ set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); } + if (page_level) + *page_level = level; + __flush_tlb_one(page); } diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index 73561fe..e43947d 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -120,19 +120,24 @@ static int write_marker(struct file *file, const char __user *buffer, static void print_pte(unsigned long address) { - pgd_t *pgd = pgd_offset_k(address); - pud_t *pud = pud_offset(pgd, address); - pmd_t *pmd = pmd_offset(pud, address); - if (pmd_large(*pmd)) { + int level; + pte_t *pte = lookup_address(address, &level); + + if (!pte) { + printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", + __FUNCTION__, address); + return; + } + + if (level == PG_LEVEL_2M) { printk(KERN_EMERG MODULE_NAME ": 4MB pages are not " "currently supported: %lx\n", address); BUG(); } printk(KERN_DEBUG MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", - address, - pte_val(*pte_offset_kernel(pmd, address)), - pte_val(*pte_offset_kernel(pmd, address)) & _PAGE_PRESENT); + address, pte_val(*pte), + pte_val(*pte) & _PAGE_PRESENT); } /* diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 60bcb5b..57970f2 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -227,6 +227,7 @@ pte_t *lookup_address(unsigned long address, unsigned int *level) return pte_offset_kernel(pmd, address); } +EXPORT_SYMBOL_GPL(lookup_address); /* * Set the new pmd in all the pgds we know about: -- cgit v0.10.2 From fe1ffafa80f6673101c6560c2bacfe3df10372ee Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:56 +0200 Subject: x86 mmiotrace: fix relay-buffer-full flag for SMP Relay has per-cpu buffers, but mmiotrace was using only a single flag for detecting buffer full/not-full transitions. The new code makes this per-cpu and actually counts missed events. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index e43947d..0019dcd 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -29,6 +29,7 @@ #include #include #include /* for ISA_START_ADDRESS */ +#include #include "kmmio.h" #include "pf_in.h" @@ -47,9 +48,13 @@ struct trap_reason { int active_traces; }; +/* Accessed per-cpu. */ static struct trap_reason pf_reason[NR_CPUS]; static struct mm_io_header_rw cpu_trace[NR_CPUS]; +/* Access to this is not per-cpu. */ +static atomic_t dropped[NR_CPUS]; + static struct file_operations mmio_fops = { .owner = THIS_MODULE, }; @@ -57,7 +62,6 @@ static struct file_operations mmio_fops = { static const size_t subbuf_size = 256*1024; static struct rchan *chan; static struct dentry *dir; -static int suspended; /* XXX should this be per cpu? */ static struct proc_dir_entry *proc_marker_file; /* module parameters */ @@ -269,19 +273,21 @@ static void post(struct kmmio_probe *p, unsigned long condition, static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { + unsigned int cpu = buf->cpu; + atomic_t *drop = &dropped[cpu]; + int count; if (relay_buf_full(buf)) { - if (!suspended) { - suspended = 1; - printk(KERN_ERR MODULE_NAME - ": cpu %d buffer full!!!\n", - smp_processor_id()); + if (atomic_inc_return(drop) == 1) { + printk(KERN_ERR MODULE_NAME ": cpu %d buffer full!\n", + cpu); } return 0; - } else if (suspended) { - suspended = 0; + } else if ((count = atomic_read(drop))) { printk(KERN_ERR MODULE_NAME - ": cpu %d buffer no longer full.\n", - smp_processor_id()); + ": cpu %d buffer no longer full, " + "missed %d events.\n", + cpu, count); + atomic_sub(count, drop); } return 1; -- cgit v0.10.2 From 63ffa3e456c1a9884a3ebac997d91e3fdae18d78 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: x86 mmiotrace: comment about user space ABI Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index cb24782..6ec288f 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -3,6 +3,10 @@ #include +/* + * If you change anything here, you must bump MMIO_VERSION. + * This is the relay data format for user space. + */ #define MMIO_VERSION 0x04 /* mm_io_header.type */ @@ -23,7 +27,7 @@ enum mm_io_opcode { /* payload type: */ }; struct mm_io_header { - __u32 type; + __u32 type; /* see MMIO_* macros above */ __u32 sec; /* timestamp */ __u32 nsec; __u32 pid; /* PID of the process, or 0 for kernel core */ -- cgit v0.10.2 From 10c43d2eb50c9a5ad60388b9d3c41c31150049e6 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: x86: explicit call to mmiotrace in do_page_fault() The custom page fault handler list is replaced with a single function pointer. All related functions and variables are renamed for mmiotrace. Signed-off-by: Pekka Paalanen Cc: Christoph Hellwig Cc: Arjan van de Ven Cc: pq@iki.fi Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 7c6496e..9491c0a 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -168,20 +168,18 @@ config IOMMU_LEAK 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 PAGE_FAULT_HANDLERS - bool "Custom page fault handlers" - depends on DEBUG_KERNEL - help - Allow the use of custom page fault handlers. A kernel module may - register a function that is called on every page fault. Custom - handlers are used by some debugging and reverse engineering tools. +config MMIOTRACE_HOOKS + bool + default n config MMIOTRACE tristate "Memory mapped IO tracing" - depends on DEBUG_KERNEL && PAGE_FAULT_HANDLERS && RELAY && DEBUG_FS + depends on DEBUG_KERNEL && RELAY && DEBUG_FS + select MMIOTRACE_HOOKS default n help This will build a kernel module called mmiotrace. + Making this a built-in is heavily discouraged. Mmiotrace traces Memory Mapped I/O access and is meant for debugging and reverse engineering. The kernel module offers wrapped diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index 28411da..e759f7c 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -51,10 +51,6 @@ static LIST_HEAD(kmmio_probes); static struct kmmio_context kmmio_ctx[NR_CPUS]; -static struct pf_handler kmmio_pf_hook = { - .handler = kmmio_page_fault -}; - static struct notifier_block nb_die = { .notifier_call = kmmio_die_notifier }; @@ -77,7 +73,8 @@ void cleanup_kmmio(void) * kmmio_page_table, kmmio_probes */ if (handler_registered) { - unregister_page_fault_handler(&kmmio_pf_hook); + if (mmiotrace_unregister_pf(&kmmio_page_fault)) + BUG(); synchronize_rcu(); } unregister_die_notifier(&nb_die); @@ -343,8 +340,11 @@ int register_kmmio_probe(struct kmmio_probe *p) } if (!handler_registered) { - register_page_fault_handler(&kmmio_pf_hook); - handler_registered++; + if (mmiotrace_register_pf(&kmmio_page_fault)) + printk(KERN_ERR "mmiotrace: Cannot register page " + "fault handler.\n"); + else + handler_registered++; } out: diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 343f5c1..e9a086a 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -49,53 +49,55 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) -#ifdef CONFIG_PAGE_FAULT_HANDLERS -static HLIST_HEAD(pf_handlers); /* protected by RCU */ -static DEFINE_SPINLOCK(pf_handlers_writer); +#ifdef CONFIG_MMIOTRACE_HOOKS +static pf_handler_func mmiotrace_pf_handler; /* protected by RCU */ +static DEFINE_SPINLOCK(mmiotrace_handler_lock); -void register_page_fault_handler(struct pf_handler *new_pfh) +int mmiotrace_register_pf(pf_handler_func new_pfh) { + int ret = 0; unsigned long flags; - spin_lock_irqsave(&pf_handlers_writer, flags); - hlist_add_head_rcu(&new_pfh->hlist, &pf_handlers); - spin_unlock_irqrestore(&pf_handlers_writer, flags); + spin_lock_irqsave(&mmiotrace_handler_lock, flags); + if (mmiotrace_pf_handler) + ret = -EBUSY; + else + mmiotrace_pf_handler = new_pfh; + spin_unlock_irqrestore(&mmiotrace_handler_lock, flags); + return ret; } -EXPORT_SYMBOL_GPL(register_page_fault_handler); +EXPORT_SYMBOL_GPL(mmiotrace_register_pf); /** - * unregister_page_fault_handler: + * mmiotrace_unregister_pf: * The caller must ensure @old_pfh is not in use anymore before freeing it. - * This function does not guarantee it. The list of handlers is protected by - * RCU, so you can do this by e.g. calling synchronize_rcu(). + * This function does not guarantee it. The handler function pointer is + * protected by RCU, so you can do this by e.g. calling synchronize_rcu(). */ -void unregister_page_fault_handler(struct pf_handler *old_pfh) +int mmiotrace_unregister_pf(pf_handler_func old_pfh) { + int ret = 0; unsigned long flags; - spin_lock_irqsave(&pf_handlers_writer, flags); - hlist_del_rcu(&old_pfh->hlist); - spin_unlock_irqrestore(&pf_handlers_writer, flags); + spin_lock_irqsave(&mmiotrace_handler_lock, flags); + if (mmiotrace_pf_handler != old_pfh) + ret = -EPERM; + else + mmiotrace_pf_handler = NULL; + spin_unlock_irqrestore(&mmiotrace_handler_lock, flags); + return ret; } -EXPORT_SYMBOL_GPL(unregister_page_fault_handler); -#endif +EXPORT_SYMBOL_GPL(mmiotrace_unregister_pf); +#endif /* CONFIG_MMIOTRACE_HOOKS */ /* returns non-zero if do_page_fault() should return */ -static int handle_custom_pf(struct pt_regs *regs, unsigned long error_code, - unsigned long address) +static inline int call_mmiotrace(struct pt_regs *regs, + unsigned long error_code, + unsigned long address) { -#ifdef CONFIG_PAGE_FAULT_HANDLERS +#ifdef CONFIG_MMIOTRACE_HOOKS int ret = 0; - struct pf_handler *cur; - struct hlist_node *ncur; - - if (hlist_empty(&pf_handlers)) - return 0; - rcu_read_lock(); - hlist_for_each_entry_rcu(cur, ncur, &pf_handlers, hlist) { - ret = cur->handler(regs, error_code, address); - if (ret) - break; - } + if (mmiotrace_pf_handler) + ret = mmiotrace_pf_handler(regs, error_code, address); rcu_read_unlock(); return ret; #else @@ -655,7 +657,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) if (notify_page_fault(regs)) return; - if (handle_custom_pf(regs, error_code, address)) + if (call_mmiotrace(regs, error_code, address)) return; /* diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index a80f2d6..7063281 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -35,13 +35,11 @@ extern void show_regs(struct pt_regs *regs); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); -struct pf_handler { - struct hlist_node hlist; - int (*handler)(struct pt_regs *regs, unsigned long error_code, - unsigned long address); -}; +typedef int (*pf_handler_func)(struct pt_regs *regs, + unsigned long error_code, + unsigned long address); -extern void register_page_fault_handler(struct pf_handler *new_pfh); -extern void unregister_page_fault_handler(struct pf_handler *old_pfh); +extern int mmiotrace_register_pf(pf_handler_func new_pfh); +extern int mmiotrace_unregister_pf(pf_handler_func old_pfh); #endif -- cgit v0.10.2 From f513638030ca384b0bace4df64f0b82f6ae1e4c6 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: x86 mmiotrace: Use percpu instead of arrays. Signed-off-by: Pekka Paalanen Cc: Eric Dumazet Cc: pq@iki.fi Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index e759f7c..5e239d0 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,8 @@ static unsigned int handler_registered; static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; static LIST_HEAD(kmmio_probes); -static struct kmmio_context kmmio_ctx[NR_CPUS]; +/* Accessed per-cpu */ +static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx); static struct notifier_block nb_die = { .notifier_call = kmmio_die_notifier @@ -173,8 +175,7 @@ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) */ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) { - struct kmmio_context *ctx; - int cpu; + struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); /* * Preemption is now disabled to prevent process switch during @@ -187,8 +188,6 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) * And that interrupt triggers a kmmio trap? */ preempt_disable(); - cpu = smp_processor_id(); - ctx = &kmmio_ctx[cpu]; /* interrupts disabled and CPU-local data => atomicity guaranteed. */ if (ctx->active) { @@ -199,7 +198,7 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) */ printk(KERN_EMERG "mmiotrace: recursive probe hit on CPU %d, " "for address %lu. Ignoring.\n", - cpu, addr); + smp_processor_id(), addr); goto no_kmmio; } ctx->active++; @@ -231,6 +230,7 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) /* We hold lock, now we set present bit in PTE and single step. */ disarm_kmmio_fault_page(ctx->fpage->page, NULL); + put_cpu_var(kmmio_ctx); return 1; no_kmmio_locked: @@ -238,6 +238,7 @@ no_kmmio_locked: ctx->active--; no_kmmio: preempt_enable_no_resched(); + put_cpu_var(kmmio_ctx); /* page fault not handled by kmmio */ return 0; } @@ -249,11 +250,11 @@ no_kmmio: */ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) { - int cpu = smp_processor_id(); - struct kmmio_context *ctx = &kmmio_ctx[cpu]; + int ret = 0; + struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); if (!ctx->active) - return 0; + goto out; if (ctx->probe && ctx->probe->post_handler) ctx->probe->post_handler(ctx->probe, condition, regs); @@ -273,10 +274,12 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) * will have TF set, in which case, continue the remaining processing * of do_debug, as if this is not a probe hit. */ - if (regs->flags & TF_MASK) - return 0; + if (!(regs->flags & TF_MASK)) + ret = 1; - return 1; +out: + put_cpu_var(kmmio_ctx); + return ret; } static int add_kmmio_fault_page(unsigned long page) diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index 0019dcd..f9c6092 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -30,6 +30,7 @@ #include #include /* for ISA_START_ADDRESS */ #include +#include #include "kmmio.h" #include "pf_in.h" @@ -49,11 +50,11 @@ struct trap_reason { }; /* Accessed per-cpu. */ -static struct trap_reason pf_reason[NR_CPUS]; -static struct mm_io_header_rw cpu_trace[NR_CPUS]; +static DEFINE_PER_CPU(struct trap_reason, pf_reason); +static DEFINE_PER_CPU(struct mm_io_header_rw, cpu_trace); /* Access to this is not per-cpu. */ -static atomic_t dropped[NR_CPUS]; +static DEFINE_PER_CPU(atomic_t, dropped); static struct file_operations mmio_fops = { .owner = THIS_MODULE, @@ -150,15 +151,15 @@ static void print_pte(unsigned long address) */ static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) { - const unsigned long cpu = smp_processor_id(); + const struct trap_reason *my_reason = &get_cpu_var(pf_reason); printk(KERN_EMERG MODULE_NAME ": unexpected fault for address: %lx, " "last fault for address: %lx\n", - addr, pf_reason[cpu].addr); + addr, my_reason->addr); print_pte(addr); #ifdef __i386__ print_symbol(KERN_EMERG "faulting EIP is at %s\n", regs->ip); print_symbol(KERN_EMERG "last faulting EIP was at %s\n", - pf_reason[cpu].ip); + my_reason->ip); printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->ax, regs->bx, regs->cx, regs->dx); @@ -168,100 +169,105 @@ static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) #else print_symbol(KERN_EMERG "faulting RIP is at %s\n", regs->ip); print_symbol(KERN_EMERG "last faulting RIP was at %s\n", - pf_reason[cpu].ip); + my_reason->ip); printk(KERN_EMERG "rax: %016lx rcx: %016lx rdx: %016lx\n", regs->ax, regs->cx, regs->dx); printk(KERN_EMERG "rsi: %016lx rdi: %016lx " "rbp: %016lx rsp: %016lx\n", regs->si, regs->di, regs->bp, regs->sp); #endif + put_cpu_var(pf_reason); BUG(); } static void pre(struct kmmio_probe *p, struct pt_regs *regs, unsigned long addr) { - const unsigned long cpu = smp_processor_id(); + struct trap_reason *my_reason = &get_cpu_var(pf_reason); + struct mm_io_header_rw *my_trace = &get_cpu_var(cpu_trace); const unsigned long instptr = instruction_pointer(regs); const enum reason_type type = get_ins_type(instptr); /* it doesn't make sense to have more than one active trace per cpu */ - if (pf_reason[cpu].active_traces) + if (my_reason->active_traces) die_kmmio_nesting_error(regs, addr); else - pf_reason[cpu].active_traces++; + my_reason->active_traces++; - pf_reason[cpu].type = type; - pf_reason[cpu].addr = addr; - pf_reason[cpu].ip = instptr; + my_reason->type = type; + my_reason->addr = addr; + my_reason->ip = instptr; - cpu_trace[cpu].header.type = MMIO_MAGIC; - cpu_trace[cpu].header.pid = 0; - cpu_trace[cpu].header.data_len = sizeof(struct mm_io_rw); - cpu_trace[cpu].rw.address = addr; + my_trace->header.type = MMIO_MAGIC; + my_trace->header.pid = 0; + my_trace->header.data_len = sizeof(struct mm_io_rw); + my_trace->rw.address = addr; /* * Only record the program counter when requested. * It may taint clean-room reverse engineering. */ if (trace_pc) - cpu_trace[cpu].rw.pc = instptr; + my_trace->rw.pc = instptr; else - cpu_trace[cpu].rw.pc = 0; + my_trace->rw.pc = 0; - record_timestamp(&cpu_trace[cpu].header); + record_timestamp(&my_trace->header); switch (type) { case REG_READ: - cpu_trace[cpu].header.type |= + my_trace->header.type |= (MMIO_READ << MMIO_OPCODE_SHIFT) | (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); break; case REG_WRITE: - cpu_trace[cpu].header.type |= + my_trace->header.type |= (MMIO_WRITE << MMIO_OPCODE_SHIFT) | (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); - cpu_trace[cpu].rw.value = get_ins_reg_val(instptr, regs); + my_trace->rw.value = get_ins_reg_val(instptr, regs); break; case IMM_WRITE: - cpu_trace[cpu].header.type |= + my_trace->header.type |= (MMIO_WRITE << MMIO_OPCODE_SHIFT) | (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); - cpu_trace[cpu].rw.value = get_ins_imm_val(instptr); + my_trace->rw.value = get_ins_imm_val(instptr); break; default: { unsigned char *ip = (unsigned char *)instptr; - cpu_trace[cpu].header.type |= + my_trace->header.type |= (MMIO_UNKNOWN_OP << MMIO_OPCODE_SHIFT); - cpu_trace[cpu].rw.value = (*ip) << 16 | - *(ip + 1) << 8 | - *(ip + 2); + my_trace->rw.value = (*ip) << 16 | *(ip + 1) << 8 | + *(ip + 2); } } + put_cpu_var(cpu_trace); + put_cpu_var(pf_reason); } static void post(struct kmmio_probe *p, unsigned long condition, struct pt_regs *regs) { - const unsigned long cpu = smp_processor_id(); + struct trap_reason *my_reason = &get_cpu_var(pf_reason); + struct mm_io_header_rw *my_trace = &get_cpu_var(cpu_trace); /* this should always return the active_trace count to 0 */ - pf_reason[cpu].active_traces--; - if (pf_reason[cpu].active_traces) { + my_reason->active_traces--; + if (my_reason->active_traces) { printk(KERN_EMERG MODULE_NAME ": unexpected post handler"); BUG(); } - switch (pf_reason[cpu].type) { + switch (my_reason->type) { case REG_READ: - cpu_trace[cpu].rw.value = get_ins_reg_val(pf_reason[cpu].ip, - regs); + my_trace->rw.value = get_ins_reg_val(my_reason->ip, regs); break; default: break; } - relay_write(chan, &cpu_trace[cpu], sizeof(struct mm_io_header_rw)); + relay_write(chan, my_trace, sizeof(*my_trace)); + put_cpu_var(cpu_trace); + put_cpu_var(pf_reason); } /* @@ -274,7 +280,7 @@ static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { unsigned int cpu = buf->cpu; - atomic_t *drop = &dropped[cpu]; + atomic_t *drop = &per_cpu(dropped, cpu); int count; if (relay_buf_full(buf)) { if (atomic_inc_return(drop) == 1) { -- cgit v0.10.2 From 0fd0e3da4557c479b820b9a4a7afa25b4637ddf2 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: x86: mmiotrace full patch, preview 1 kmmio.c handles the list of mmio probes with callbacks, list of traced pages, and attaching into the page fault handler and die notifier. It arms, traps and disarms the given pages, this is the core of mmiotrace. mmio-mod.c is a user interface, hooking into ioremap functions and registering the mmio probes. It also decodes the required information from trapped mmio accesses via the pre and post callbacks in each probe. Currently, hooking into ioremap functions works by redefining the symbols of the target (binary) kernel module, so that it calls the traced versions of the functions. The most notable changes done since the last discussion are: - kmmio.c is a built-in, not part of the module - direct call from fault.c to kmmio.c, removing all dynamic hooks - prepare for unregistering probes at any time - make kmmio re-initializable and accessible to more than one user - rewrite kmmio locking to remove all spinlocks from page fault path Can I abuse call_rcu() like I do in kmmio.c:unregister_kmmio_probe() or is there a better way? The function called via call_rcu() itself calls call_rcu() again, will this work or break? There I need a second grace period for RCU after the first grace period for page faults. Mmiotrace itself (mmio-mod.c) is still a module, I am going to attack that next. At some point I will start looking into how to make mmiotrace a tracer component of ftrace (thanks for the hint, Ingo). Ftrace should make the user space part of mmiotracing as simple as 'cat /debug/trace/mmio > dump.txt'. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 027a5b6..a4f93b4 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c @@ -15,7 +15,6 @@ static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */ -EXPORT_SYMBOL_GPL(init_mm); /* * Initial thread structure. diff --git a/arch/x86/kernel/mmiotrace/Makefile b/arch/x86/kernel/mmiotrace/Makefile index d6905f7..cf1e747 100644 --- a/arch/x86/kernel/mmiotrace/Makefile +++ b/arch/x86/kernel/mmiotrace/Makefile @@ -1,4 +1,4 @@ -obj-$(CONFIG_MMIOTRACE) += mmiotrace.o -mmiotrace-objs := pf_in.o kmmio.o mmio-mod.o - -obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o +obj-$(CONFIG_MMIOTRACE_HOOKS) += kmmio.o +obj-$(CONFIG_MMIOTRACE) += mmiotrace.o +mmiotrace-objs := pf_in.o mmio-mod.o +obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index 5e239d0..539a9b1 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -17,70 +18,119 @@ #include #include #include +#include #include #include #include #include #include -#include "kmmio.h" +#include -#define KMMIO_HASH_BITS 6 -#define KMMIO_TABLE_SIZE (1 << KMMIO_HASH_BITS) #define KMMIO_PAGE_HASH_BITS 4 #define KMMIO_PAGE_TABLE_SIZE (1 << KMMIO_PAGE_HASH_BITS) +struct kmmio_fault_page { + struct list_head list; + struct kmmio_fault_page *release_next; + unsigned long page; /* location of the fault page */ + + /* + * 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). + */ + int count; +}; + +struct kmmio_delayed_release { + struct rcu_head rcu; + struct kmmio_fault_page *release_list; +}; + struct kmmio_context { struct kmmio_fault_page *fpage; struct kmmio_probe *probe; unsigned long saved_flags; + unsigned long addr; int active; }; -static int kmmio_page_fault(struct pt_regs *regs, unsigned long error_code, - unsigned long address); static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args); +static DECLARE_MUTEX(kmmio_init_mutex); static DEFINE_SPINLOCK(kmmio_lock); /* These are protected by kmmio_lock */ +static int kmmio_initialized; unsigned int kmmio_count; -static unsigned int handler_registered; + +/* Read-protected by RCU, write-protected by kmmio_lock. */ static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; static LIST_HEAD(kmmio_probes); +static struct list_head *kmmio_page_list(unsigned long page) +{ + return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)]; +} + /* Accessed per-cpu */ static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx); +/* protected by kmmio_init_mutex */ static struct notifier_block nb_die = { .notifier_call = kmmio_die_notifier }; -int init_kmmio(void) +/** + * Makes sure kmmio is initialized and usable. + * This must be called before any other kmmio function defined here. + * May sleep. + */ +void reference_kmmio(void) { - int i; - for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) - INIT_LIST_HEAD(&kmmio_page_table[i]); - - register_die_notifier(&nb_die); - return 0; + down(&kmmio_init_mutex); + spin_lock_irq(&kmmio_lock); + if (!kmmio_initialized) { + int i; + for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) + INIT_LIST_HEAD(&kmmio_page_table[i]); + if (register_die_notifier(&nb_die)) + BUG(); + } + kmmio_initialized++; + spin_unlock_irq(&kmmio_lock); + up(&kmmio_init_mutex); } +EXPORT_SYMBOL_GPL(reference_kmmio); -void cleanup_kmmio(void) +/** + * Clean up kmmio after use. This must be called for every call to + * reference_kmmio(). All probes registered after the corresponding + * reference_kmmio() must have been unregistered when calling this. + * May sleep. + */ +void unreference_kmmio(void) { - /* - * Assume the following have been already cleaned by calling - * unregister_kmmio_probe() appropriately: - * kmmio_page_table, kmmio_probes - */ - if (handler_registered) { - if (mmiotrace_unregister_pf(&kmmio_page_fault)) - BUG(); - synchronize_rcu(); + bool unreg = false; + + down(&kmmio_init_mutex); + spin_lock_irq(&kmmio_lock); + + if (kmmio_initialized == 1) { + BUG_ON(is_kmmio_active()); + unreg = true; } - unregister_die_notifier(&nb_die); + kmmio_initialized--; + BUG_ON(kmmio_initialized < 0); + spin_unlock_irq(&kmmio_lock); + + if (unreg) + unregister_die_notifier(&nb_die); /* calls sync_rcu() */ + up(&kmmio_init_mutex); } +EXPORT_SYMBOL(unreference_kmmio); /* * this is basically a dynamic stabbing problem: @@ -90,33 +140,33 @@ void cleanup_kmmio(void) * Overlap a Point (might be simple) * Space Efficient Dynamic Stabbing with Fast Queries - Mikkel Thorup */ -/* Get the kmmio at this addr (if any). You must be holding kmmio_lock. */ +/* Get the kmmio at this addr (if any). You must be holding RCU read lock. */ static struct kmmio_probe *get_kmmio_probe(unsigned long addr) { struct kmmio_probe *p; - list_for_each_entry(p, &kmmio_probes, list) { + list_for_each_entry_rcu(p, &kmmio_probes, list) { if (addr >= p->addr && addr <= (p->addr + p->len)) return p; } return NULL; } +/* You must be holding RCU read lock. */ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) { - struct list_head *head, *tmp; + struct list_head *head; + struct kmmio_fault_page *p; page &= PAGE_MASK; - head = &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)]; - list_for_each(tmp, head) { - struct kmmio_fault_page *p - = list_entry(tmp, struct kmmio_fault_page, list); + head = kmmio_page_list(page); + list_for_each_entry_rcu(p, head, list) { if (p->page == page) return p; } - return NULL; } +/** Mark the given page as not present. Access to it will trigger a fault. */ static void arm_kmmio_fault_page(unsigned long page, int *page_level) { unsigned long address = page & PAGE_MASK; @@ -124,8 +174,8 @@ static void arm_kmmio_fault_page(unsigned long page, int *page_level) pte_t *pte = lookup_address(address, &level); if (!pte) { - printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", - __FUNCTION__, page); + pr_err("kmmio: Error in %s: no pte for page 0x%08lx\n", + __func__, page); return; } @@ -143,6 +193,7 @@ static void arm_kmmio_fault_page(unsigned long page, int *page_level) __flush_tlb_one(page); } +/** Mark the given page as present. */ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) { unsigned long address = page & PAGE_MASK; @@ -150,8 +201,8 @@ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) pte_t *pte = lookup_address(address, &level); if (!pte) { - printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", - __FUNCTION__, page); + pr_err("kmmio: Error in %s: no pte for page 0x%08lx\n", + __func__, page); return; } @@ -170,12 +221,24 @@ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) } /* + * This is being called from do_page_fault(). + * + * We may be in an interrupt or a critical section. Also prefecthing may + * trigger a page fault. We may be in the middle of process switch. + * We cannot take any locks, because we could be executing especially + * within a kmmio critical section. + * + * Local interrupts are disabled, so preemption cannot happen. + * Do not enable interrupts, do not sleep, and watch out for other CPUs. + */ +/* * Interrupts are disabled on entry as trap3 is an interrupt gate * and they remain disabled thorough out this function. */ -static int kmmio_handler(struct pt_regs *regs, unsigned long addr) +int kmmio_handler(struct pt_regs *regs, unsigned long addr) { - struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); + struct kmmio_context *ctx; + struct kmmio_fault_page *faultpage; /* * Preemption is now disabled to prevent process switch during @@ -186,40 +249,40 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) * XXX what if an interrupt occurs between returning from * do_page_fault() and entering the single-step exception handler? * And that interrupt triggers a kmmio trap? + * XXX If we tracing an interrupt service routine or whatever, is + * this enough to keep it on the current cpu? */ preempt_disable(); - /* interrupts disabled and CPU-local data => atomicity guaranteed. */ + rcu_read_lock(); + faultpage = get_kmmio_fault_page(addr); + if (!faultpage) { + /* + * Either this page fault is not caused by kmmio, or + * another CPU just pulled the kmmio probe from under + * our feet. In the latter case all hell breaks loose. + */ + goto no_kmmio; + } + + ctx = &get_cpu_var(kmmio_ctx); if (ctx->active) { /* - * This avoids a deadlock with kmmio_lock. + * Prevent overwriting already in-flight context. * If this page fault really was due to kmmio trap, * all hell breaks loose. */ - printk(KERN_EMERG "mmiotrace: recursive probe hit on CPU %d, " - "for address %lu. Ignoring.\n", + pr_emerg("kmmio: recursive probe hit on CPU %d, " + "for address 0x%08lx. Ignoring.\n", smp_processor_id(), addr); - goto no_kmmio; + goto no_kmmio_ctx; } ctx->active++; - /* - * Acquire the kmmio lock to prevent changes affecting - * get_kmmio_fault_page() and get_kmmio_probe(), since we save their - * returned pointers. - * The lock is released in post_kmmio_handler(). - * XXX: could/should get_kmmio_*() be using RCU instead of spinlock? - */ - spin_lock(&kmmio_lock); - - ctx->fpage = get_kmmio_fault_page(addr); - if (!ctx->fpage) { - /* this page fault is not caused by kmmio */ - goto no_kmmio_locked; - } - + ctx->fpage = faultpage; ctx->probe = get_kmmio_probe(addr); ctx->saved_flags = (regs->flags & (TF_MASK|IF_MASK)); + ctx->addr = addr; if (ctx->probe && ctx->probe->pre_handler) ctx->probe->pre_handler(ctx->probe, regs, addr); @@ -227,46 +290,62 @@ static int kmmio_handler(struct pt_regs *regs, unsigned long addr) regs->flags |= TF_MASK; regs->flags &= ~IF_MASK; - /* We hold lock, now we set present bit in PTE and single step. */ + /* Now we set present bit in PTE and single step. */ disarm_kmmio_fault_page(ctx->fpage->page, NULL); put_cpu_var(kmmio_ctx); + rcu_read_unlock(); return 1; -no_kmmio_locked: - spin_unlock(&kmmio_lock); - ctx->active--; +no_kmmio_ctx: + put_cpu_var(kmmio_ctx); no_kmmio: + rcu_read_unlock(); preempt_enable_no_resched(); - put_cpu_var(kmmio_ctx); - /* page fault not handled by kmmio */ - return 0; + return 0; /* page fault not handled by kmmio */ } /* * Interrupts are disabled on entry as trap1 is an interrupt gate * and they remain disabled thorough out this function. - * And we hold kmmio lock. + * This must always get called as the pair to kmmio_handler(). */ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) { int ret = 0; + struct kmmio_probe *probe; + struct kmmio_fault_page *faultpage; struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); if (!ctx->active) goto out; + rcu_read_lock(); + + faultpage = get_kmmio_fault_page(ctx->addr); + probe = get_kmmio_probe(ctx->addr); + if (faultpage != ctx->fpage || probe != ctx->probe) { + /* + * The trace setup changed after kmmio_handler() and before + * running this respective post handler. User does not want + * the result anymore. + */ + ctx->probe = NULL; + ctx->fpage = NULL; + } + if (ctx->probe && ctx->probe->post_handler) ctx->probe->post_handler(ctx->probe, condition, regs); - arm_kmmio_fault_page(ctx->fpage->page, NULL); + if (ctx->fpage) + arm_kmmio_fault_page(ctx->fpage->page, NULL); regs->flags &= ~TF_MASK; regs->flags |= ctx->saved_flags; /* These were acquired in kmmio_handler(). */ ctx->active--; - spin_unlock(&kmmio_lock); + BUG_ON(ctx->active); preempt_enable_no_resched(); /* @@ -277,11 +356,13 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) if (!(regs->flags & TF_MASK)) ret = 1; + rcu_read_unlock(); out: put_cpu_var(kmmio_ctx); return ret; } +/* You must be holding kmmio_lock. */ static int add_kmmio_fault_page(unsigned long page) { struct kmmio_fault_page *f; @@ -289,6 +370,8 @@ static int add_kmmio_fault_page(unsigned long page) page &= PAGE_MASK; f = get_kmmio_fault_page(page); if (f) { + if (!f->count) + arm_kmmio_fault_page(f->page, NULL); f->count++; return 0; } @@ -299,15 +382,16 @@ static int add_kmmio_fault_page(unsigned long page) f->count = 1; f->page = page; - list_add(&f->list, - &kmmio_page_table[hash_long(f->page, KMMIO_PAGE_HASH_BITS)]); + list_add_rcu(&f->list, kmmio_page_list(f->page)); arm_kmmio_fault_page(f->page, NULL); return 0; } -static void release_kmmio_fault_page(unsigned long page) +/* You must be holding kmmio_lock. */ +static void release_kmmio_fault_page(unsigned long page, + struct kmmio_fault_page **release_list) { struct kmmio_fault_page *f; @@ -317,9 +401,11 @@ static void release_kmmio_fault_page(unsigned long page) return; f->count--; + BUG_ON(f->count < 0); if (!f->count) { disarm_kmmio_fault_page(f->page, NULL); - list_del(&f->list); + f->release_next = *release_list; + *release_list = f; } } @@ -334,68 +420,113 @@ int register_kmmio_probe(struct kmmio_probe *p) ret = -EEXIST; goto out; } - list_add(&p->list, &kmmio_probes); - /*printk("adding fault pages...\n");*/ + list_add_rcu(&p->list, &kmmio_probes); while (size < p->len) { if (add_kmmio_fault_page(p->addr + size)) - printk(KERN_ERR "mmio: Unable to set page fault.\n"); + pr_err("kmmio: Unable to set page fault.\n"); size += PAGE_SIZE; } - - if (!handler_registered) { - if (mmiotrace_register_pf(&kmmio_page_fault)) - printk(KERN_ERR "mmiotrace: Cannot register page " - "fault handler.\n"); - else - handler_registered++; - } - out: spin_unlock_irq(&kmmio_lock); /* * XXX: What should I do here? * Here was a call to global_flush_tlb(), but it does not exist - * anymore. + * anymore. It seems it's not needed after all. */ return ret; } +EXPORT_SYMBOL(register_kmmio_probe); +static void rcu_free_kmmio_fault_pages(struct rcu_head *head) +{ + struct kmmio_delayed_release *dr = container_of( + head, + struct kmmio_delayed_release, + rcu); + struct kmmio_fault_page *p = dr->release_list; + while (p) { + struct kmmio_fault_page *next = p->release_next; + BUG_ON(p->count); + kfree(p); + p = next; + } + kfree(dr); +} + +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_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) + list_del_rcu(&p->list); + 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); +} + +/* + * Remove a kmmio probe. You have to synchronize_rcu() before you can be + * sure that the callbacks will not be called anymore. + * + * Unregistering a kmmio fault page has three steps: + * 1. release_kmmio_fault_page() + * Disarm the page, wait a grace period to let all faults finish. + * 2. remove_kmmio_fault_pages() + * Remove the pages from kmmio_page_table. + * 3. rcu_free_kmmio_fault_pages() + * Actally free the kmmio_fault_page structs as with RCU. + */ void unregister_kmmio_probe(struct kmmio_probe *p) { unsigned long size = 0; + struct kmmio_fault_page *release_list = NULL; + struct kmmio_delayed_release *drelease; spin_lock_irq(&kmmio_lock); while (size < p->len) { - release_kmmio_fault_page(p->addr + size); + release_kmmio_fault_page(p->addr + size, &release_list); size += PAGE_SIZE; } - list_del(&p->list); + list_del_rcu(&p->list); kmmio_count--; spin_unlock_irq(&kmmio_lock); -} -/* - * According to 2.6.20, mainly x86_64 arch: - * This is being called from do_page_fault(), via the page fault notifier - * chain. The chain is called for both user space faults and kernel space - * faults (address >= TASK_SIZE64), except not on faults serviced by - * vmalloc_fault(). - * - * We may be in an interrupt or a critical section. Also prefecthing may - * trigger a page fault. We may be in the middle of process switch. - * The page fault hook functionality has put us inside RCU read lock. - * - * Local interrupts are disabled, so preemption cannot happen. - * Do not enable interrupts, do not sleep, and watch out for other CPUs. - */ -static int kmmio_page_fault(struct pt_regs *regs, unsigned long error_code, - unsigned long address) -{ - if (is_kmmio_active()) - if (kmmio_handler(regs, address) == 1) - return -1; - return 0; + drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); + if (!drelease) { + pr_crit("kmmio: leaking kmmio_fault_page objects.\n"); + return; + } + drelease->release_list = release_list; + + /* + * This is not really RCU here. We have just disarmed a set of + * pages so that they cannot trigger page faults anymore. However, + * we cannot remove the pages from kmmio_page_table, + * because a probe hit might be in flight on another CPU. The + * pages are collected into a list, and they will be removed from + * kmmio_page_table when it is certain that no probe hit related to + * these pages can be in flight. RCU grace period sounds like a + * good choice. + * + * If we removed the pages too early, kmmio page fault handler might + * not find the respective kmmio_fault_page and determine it's not + * a kmmio fault, when it actually is. This would lead to madness. + */ + call_rcu(&drelease->rcu, remove_kmmio_fault_pages); } +EXPORT_SYMBOL(unregister_kmmio_probe); static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args) diff --git a/arch/x86/kernel/mmiotrace/kmmio.h b/arch/x86/kernel/mmiotrace/kmmio.h deleted file mode 100644 index 85b7f68..0000000 --- a/arch/x86/kernel/mmiotrace/kmmio.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _LINUX_KMMIO_H -#define _LINUX_KMMIO_H - -#include -#include -#include -#include -#include -#include -#include - -struct kmmio_probe; -struct kmmio_fault_page; -struct pt_regs; - -typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *, - struct pt_regs *, unsigned long addr); -typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, - unsigned long condition, struct pt_regs *); - -struct kmmio_probe { - struct list_head list; - - /* start location of the probe point */ - unsigned long addr; - - /* length of the probe region */ - unsigned long len; - - /* Called before addr is executed. */ - kmmio_pre_handler_t pre_handler; - - /* Called after addr is executed, unless... */ - kmmio_post_handler_t post_handler; -}; - -struct kmmio_fault_page { - struct list_head list; - - /* location of the fault page */ - unsigned long page; - - int count; -}; - -/* kmmio is active by some kmmio_probes? */ -static inline int is_kmmio_active(void) -{ - extern unsigned int kmmio_count; - return kmmio_count; -} - -int init_kmmio(void); -void cleanup_kmmio(void); -int register_kmmio_probe(struct kmmio_probe *p); -void unregister_kmmio_probe(struct kmmio_probe *p); - -#endif /* _LINUX_KMMIO_H */ diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index f9c6092..e1a5085 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -32,7 +32,6 @@ #include #include -#include "kmmio.h" #include "pf_in.h" /* This app's relay channel files will appear in /debug/mmio-trace */ @@ -129,18 +128,17 @@ static void print_pte(unsigned long address) pte_t *pte = lookup_address(address, &level); if (!pte) { - printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", - __FUNCTION__, address); + pr_err(MODULE_NAME ": Error in %s: no pte for page 0x%08lx\n", + __func__, address); return; } if (level == PG_LEVEL_2M) { - printk(KERN_EMERG MODULE_NAME ": 4MB pages are not " - "currently supported: %lx\n", - address); + pr_emerg(MODULE_NAME ": 4MB pages are not currently " + "supported: %lx\n", address); BUG(); } - printk(KERN_DEBUG MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", + pr_info(MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", address, pte_val(*pte), pte_val(*pte) & _PAGE_PRESENT); } @@ -152,7 +150,7 @@ static void print_pte(unsigned long address) static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) { const struct trap_reason *my_reason = &get_cpu_var(pf_reason); - printk(KERN_EMERG MODULE_NAME ": unexpected fault for address: %lx, " + pr_emerg(MODULE_NAME ": unexpected fault for address: %lx, " "last fault for address: %lx\n", addr, my_reason->addr); print_pte(addr); @@ -160,20 +158,17 @@ static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) print_symbol(KERN_EMERG "faulting EIP is at %s\n", regs->ip); print_symbol(KERN_EMERG "last faulting EIP was at %s\n", my_reason->ip); - printk(KERN_EMERG - "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", + pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->ax, regs->bx, regs->cx, regs->dx); - printk(KERN_EMERG - "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", + pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", regs->si, regs->di, regs->bp, regs->sp); #else print_symbol(KERN_EMERG "faulting RIP is at %s\n", regs->ip); print_symbol(KERN_EMERG "last faulting RIP was at %s\n", my_reason->ip); - printk(KERN_EMERG "rax: %016lx rcx: %016lx rdx: %016lx\n", + pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", regs->ax, regs->cx, regs->dx); - printk(KERN_EMERG "rsi: %016lx rdi: %016lx " - "rbp: %016lx rsp: %016lx\n", + pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", regs->si, regs->di, regs->bp, regs->sp); #endif put_cpu_var(pf_reason); @@ -251,10 +246,15 @@ static void post(struct kmmio_probe *p, unsigned long condition, struct trap_reason *my_reason = &get_cpu_var(pf_reason); struct mm_io_header_rw *my_trace = &get_cpu_var(cpu_trace); + /* + * XXX: This might not get called, if the probe is removed while + * trace hit is on flight. + */ + /* this should always return the active_trace count to 0 */ my_reason->active_traces--; if (my_reason->active_traces) { - printk(KERN_EMERG MODULE_NAME ": unexpected post handler"); + pr_emerg(MODULE_NAME ": unexpected post handler"); BUG(); } @@ -283,16 +283,15 @@ static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, atomic_t *drop = &per_cpu(dropped, cpu); int count; if (relay_buf_full(buf)) { - if (atomic_inc_return(drop) == 1) { - printk(KERN_ERR MODULE_NAME ": cpu %d buffer full!\n", - cpu); - } + if (atomic_inc_return(drop) == 1) + pr_err(MODULE_NAME ": cpu %d buffer full!\n", cpu); return 0; - } else if ((count = atomic_read(drop))) { - printk(KERN_ERR MODULE_NAME - ": cpu %d buffer no longer full, " - "missed %d events.\n", - cpu, count); + } + count = atomic_read(drop); + if (count) { + pr_err(MODULE_NAME ": cpu %d buffer no longer full, " + "missed %d events.\n", + cpu, count); atomic_sub(count, drop); } @@ -407,8 +406,8 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, /* Don't trace the low PCI/ISA area, it's always mapped.. */ if (!ISA_trace && (offset < ISA_END_ADDRESS) && (offset + size > ISA_START_ADDRESS)) { - printk(KERN_NOTICE MODULE_NAME ": Ignoring map of low " - "PCI/ISA area (0x%lx-0x%lx)\n", + pr_notice(MODULE_NAME ": Ignoring map of low PCI/ISA area " + "(0x%lx-0x%lx)\n", offset, offset + size); return; } @@ -418,7 +417,7 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, void __iomem *ioremap_cache_trace(unsigned long offset, unsigned long size) { void __iomem *p = ioremap_cache(offset, size); - printk(KERN_DEBUG MODULE_NAME ": ioremap_cache(0x%lx, 0x%lx) = %p\n", + pr_debug(MODULE_NAME ": ioremap_cache(0x%lx, 0x%lx) = %p\n", offset, size, p); ioremap_trace_core(offset, size, p); return p; @@ -428,7 +427,7 @@ EXPORT_SYMBOL(ioremap_cache_trace); void __iomem *ioremap_nocache_trace(unsigned long offset, unsigned long size) { void __iomem *p = ioremap_nocache(offset, size); - printk(KERN_DEBUG MODULE_NAME ": ioremap_nocache(0x%lx, 0x%lx) = %p\n", + pr_debug(MODULE_NAME ": ioremap_nocache(0x%lx, 0x%lx) = %p\n", offset, size, p); ioremap_trace_core(offset, size, p); return p; @@ -455,7 +454,7 @@ void iounmap_trace(volatile void __iomem *addr) }; struct remap_trace *trace; struct remap_trace *tmp; - printk(KERN_DEBUG MODULE_NAME ": Unmapping %p.\n", addr); + pr_debug(MODULE_NAME ": Unmapping %p.\n", addr); record_timestamp(&event.header); spin_lock(&trace_list_lock); @@ -481,7 +480,7 @@ static void clear_trace_list(void) spin_lock(&trace_list_lock); list_for_each_entry_safe(trace, tmp, &trace_list, list) { - printk(KERN_WARNING MODULE_NAME ": purging non-iounmapped " + pr_warning(MODULE_NAME ": purging non-iounmapped " "trace @0x%08lx, size 0x%lx.\n", trace->probe.addr, trace->probe.len); if (!nommiotrace) @@ -500,39 +499,37 @@ static int __init init(void) dir = debugfs_create_dir(APP_DIR, NULL); if (!dir) { - printk(KERN_ERR MODULE_NAME - ": Couldn't create relay app directory.\n"); + pr_err(MODULE_NAME ": Couldn't create relay app directory.\n"); return -ENOMEM; } chan = create_channel(subbuf_size, n_subbufs); if (!chan) { debugfs_remove(dir); - printk(KERN_ERR MODULE_NAME - ": relay app channel creation failed\n"); + pr_err(MODULE_NAME ": relay app channel creation failed\n"); return -ENOMEM; } - init_kmmio(); + reference_kmmio(); proc_marker_file = create_proc_entry(MARKER_FILE, 0, NULL); if (proc_marker_file) proc_marker_file->write_proc = write_marker; - printk(KERN_DEBUG MODULE_NAME ": loaded.\n"); + pr_debug(MODULE_NAME ": loaded.\n"); if (nommiotrace) - printk(KERN_DEBUG MODULE_NAME ": MMIO tracing disabled.\n"); + pr_info(MODULE_NAME ": MMIO tracing disabled.\n"); if (ISA_trace) - printk(KERN_WARNING MODULE_NAME - ": Warning! low ISA range will be traced.\n"); + pr_warning(MODULE_NAME ": Warning! low ISA range will be " + "traced.\n"); return 0; } static void __exit cleanup(void) { - printk(KERN_DEBUG MODULE_NAME ": unload...\n"); + pr_debug(MODULE_NAME ": unload...\n"); clear_trace_list(); - cleanup_kmmio(); + unreference_kmmio(); remove_proc_entry(MARKER_FILE, NULL); destroy_channel(); if (dir) diff --git a/arch/x86/kernel/mmiotrace/pf_in.c b/arch/x86/kernel/mmiotrace/pf_in.c index 67ea520..efa1911 100644 --- a/arch/x86/kernel/mmiotrace/pf_in.c +++ b/arch/x86/kernel/mmiotrace/pf_in.c @@ -19,7 +19,7 @@ * */ -/* $Id: pf_in.c,v 1.1.1.1 2002/11/12 05:56:32 brlock Exp $ +/* Id: pf_in.c,v 1.1.1.1 2002/11/12 05:56:32 brlock Exp * Copyright by Intel Crop., 2002 * Louis Zhuang (louis.zhuang@intel.com) * diff --git a/arch/x86/kernel/mmiotrace/testmmiotrace.c b/arch/x86/kernel/mmiotrace/testmmiotrace.c index 40e66b0..5ecff57 100644 --- a/arch/x86/kernel/mmiotrace/testmmiotrace.c +++ b/arch/x86/kernel/mmiotrace/testmmiotrace.c @@ -41,8 +41,7 @@ static void do_test(void) { void __iomem *p = ioremap_nocache_trace(mmio_address, 0x4000); if (!p) { - printk(KERN_ERR MODULE_NAME ": could not ioremap IO memory, " - "aborting.\n"); + pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); return; } do_write_test(p); @@ -53,14 +52,14 @@ static void do_test(void) static int __init init(void) { if (mmio_address == 0) { - printk(KERN_ERR MODULE_NAME ": you have to use the module " - "argument mmio_address.\n"); - printk(KERN_ERR MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" + pr_err(MODULE_NAME ": you have to use the module argument " + "mmio_address.\n"); + pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" " YOU REALLY KNOW WHAT YOU ARE DOING!\n"); return -ENXIO; } - printk(KERN_WARNING MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx " + pr_warning(MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx " "in PCI address space, and writing " "rubbish in there.\n", mmio_address); do_test(); @@ -69,7 +68,7 @@ static int __init init(void) static void __exit cleanup(void) { - printk(KERN_DEBUG MODULE_NAME ": unloaded.\n"); + pr_debug(MODULE_NAME ": unloaded.\n"); } module_init(init); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e9a086a..8c828a6 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -49,60 +50,14 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) -#ifdef CONFIG_MMIOTRACE_HOOKS -static pf_handler_func mmiotrace_pf_handler; /* protected by RCU */ -static DEFINE_SPINLOCK(mmiotrace_handler_lock); - -int mmiotrace_register_pf(pf_handler_func new_pfh) -{ - int ret = 0; - unsigned long flags; - spin_lock_irqsave(&mmiotrace_handler_lock, flags); - if (mmiotrace_pf_handler) - ret = -EBUSY; - else - mmiotrace_pf_handler = new_pfh; - spin_unlock_irqrestore(&mmiotrace_handler_lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(mmiotrace_register_pf); - -/** - * mmiotrace_unregister_pf: - * The caller must ensure @old_pfh is not in use anymore before freeing it. - * This function does not guarantee it. The handler function pointer is - * protected by RCU, so you can do this by e.g. calling synchronize_rcu(). - */ -int mmiotrace_unregister_pf(pf_handler_func old_pfh) -{ - int ret = 0; - unsigned long flags; - spin_lock_irqsave(&mmiotrace_handler_lock, flags); - if (mmiotrace_pf_handler != old_pfh) - ret = -EPERM; - else - mmiotrace_pf_handler = NULL; - spin_unlock_irqrestore(&mmiotrace_handler_lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(mmiotrace_unregister_pf); -#endif /* CONFIG_MMIOTRACE_HOOKS */ - -/* returns non-zero if do_page_fault() should return */ -static inline int call_mmiotrace(struct pt_regs *regs, - unsigned long error_code, - unsigned long address) +static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) { #ifdef CONFIG_MMIOTRACE_HOOKS - int ret = 0; - rcu_read_lock(); - if (mmiotrace_pf_handler) - ret = mmiotrace_pf_handler(regs, error_code, address); - rcu_read_unlock(); - return ret; -#else - return 0; + if (unlikely(is_kmmio_active())) + if (kmmio_handler(regs, addr) == 1) + return -1; #endif + return 0; } static inline int notify_page_fault(struct pt_regs *regs) @@ -657,7 +612,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) if (notify_page_fault(regs)) return; - if (call_mmiotrace(regs, error_code, address)) + if (unlikely(kmmio_fault(regs, address))) return; /* diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index 7063281..96651bb 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -35,11 +35,4 @@ extern void show_regs(struct pt_regs *regs); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); -typedef int (*pf_handler_func)(struct pt_regs *regs, - unsigned long error_code, - unsigned long address); - -extern int mmiotrace_register_pf(pf_handler_func new_pfh); -extern int mmiotrace_unregister_pf(pf_handler_func old_pfh); - #endif diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 6ec288f..d87a6cd 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -3,6 +3,44 @@ #include +#ifdef __KERNEL__ + +#include + +struct kmmio_probe; +struct pt_regs; + +typedef void (*kmmio_pre_handler_t)(struct kmmio_probe *, + struct pt_regs *, unsigned long addr); +typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, + unsigned long condition, struct pt_regs *); + +struct kmmio_probe { + struct list_head list; + unsigned long addr; /* start location of the probe point */ + unsigned long len; /* length of the probe region */ + kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */ + kmmio_post_handler_t post_handler; /* Called after addr is executed */ +}; + +/* kmmio is active by some kmmio_probes? */ +static inline int is_kmmio_active(void) +{ + extern unsigned int kmmio_count; + return kmmio_count; +} + +extern void reference_kmmio(void); +extern void unreference_kmmio(void); +extern int register_kmmio_probe(struct kmmio_probe *p); +extern void unregister_kmmio_probe(struct kmmio_probe *p); + +/* Called from page fault handler. */ +extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); + +#endif /* __KERNEL__ */ + + /* * If you change anything here, you must bump MMIO_VERSION. * This is the relay data format for user space. -- cgit v0.10.2 From d61fc44853f46fb002228b18aa5f30db21fcd4ac Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: x86: mmiotrace, preview 2 Kconfig.debug, Makefile and testmmiotrace.c style fixes. Use real mutex instead of mutex. Fix failure path in register probe func. kmmio: RCU read-locked over single stepping. Generate mapping id's. Make mmio-mod.c built-in and rewrite its locking. Add debugfs file to enable/disable mmiotracing. kmmio: use irqsave spinlocks. Lots of cleanups in mmio-mod.c Marker file moved from /proc into debugfs. Call mmiotrace entrypoints directly from ioremap.c. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9491c0a..aa0d646 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -170,22 +170,19 @@ config IOMMU_LEAK config MMIOTRACE_HOOKS bool - default n config MMIOTRACE - tristate "Memory mapped IO tracing" + bool "Memory mapped IO tracing" depends on DEBUG_KERNEL && RELAY && DEBUG_FS select MMIOTRACE_HOOKS - default n + default y help - This will build a kernel module called mmiotrace. - Making this a built-in is heavily discouraged. - - Mmiotrace traces Memory Mapped I/O access and is meant for debugging - and reverse engineering. The kernel module offers wrapped - versions of the ioremap family of functions. The driver to be traced - must be modified to call these wrappers. A user space program is - required to collect the MMIO data. + 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. A user space program is + required to collect the MMIO data from debugfs files. + Tracing is disabled by default and can be enabled from a debugfs + file. See http://nouveau.freedesktop.org/wiki/MmioTrace If you are not helping to develop drivers, say N. @@ -193,7 +190,6 @@ config MMIOTRACE config MMIOTRACE_TEST tristate "Test module for mmiotrace" depends on MMIOTRACE && m - default n 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. diff --git a/arch/x86/kernel/mmiotrace/Makefile b/arch/x86/kernel/mmiotrace/Makefile index cf1e747..dbcd8d5 100644 --- a/arch/x86/kernel/mmiotrace/Makefile +++ b/arch/x86/kernel/mmiotrace/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_MMIOTRACE_HOOKS) += kmmio.o obj-$(CONFIG_MMIOTRACE) += mmiotrace.o -mmiotrace-objs := pf_in.o mmio-mod.o +mmiotrace-y := pf_in.o mmio-mod.o obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index 539a9b1..efb4679 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +60,7 @@ struct kmmio_context { static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args); -static DECLARE_MUTEX(kmmio_init_mutex); +static DEFINE_MUTEX(kmmio_init_mutex); static DEFINE_SPINLOCK(kmmio_lock); /* These are protected by kmmio_lock */ @@ -90,7 +91,7 @@ static struct notifier_block nb_die = { */ void reference_kmmio(void) { - down(&kmmio_init_mutex); + mutex_lock(&kmmio_init_mutex); spin_lock_irq(&kmmio_lock); if (!kmmio_initialized) { int i; @@ -101,7 +102,7 @@ void reference_kmmio(void) } kmmio_initialized++; spin_unlock_irq(&kmmio_lock); - up(&kmmio_init_mutex); + mutex_unlock(&kmmio_init_mutex); } EXPORT_SYMBOL_GPL(reference_kmmio); @@ -115,7 +116,7 @@ void unreference_kmmio(void) { bool unreg = false; - down(&kmmio_init_mutex); + mutex_lock(&kmmio_init_mutex); spin_lock_irq(&kmmio_lock); if (kmmio_initialized == 1) { @@ -128,7 +129,7 @@ void unreference_kmmio(void) if (unreg) unregister_die_notifier(&nb_die); /* calls sync_rcu() */ - up(&kmmio_init_mutex); + mutex_unlock(&kmmio_init_mutex); } EXPORT_SYMBOL(unreference_kmmio); @@ -244,17 +245,13 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) * Preemption is now disabled to prevent process switch during * single stepping. We can only handle one active kmmio trace * per cpu, so ensure that we finish it before something else - * gets to run. - * - * XXX what if an interrupt occurs between returning from - * do_page_fault() and entering the single-step exception handler? - * And that interrupt triggers a kmmio trap? - * XXX If we tracing an interrupt service routine or whatever, is - * this enough to keep it on the current cpu? + * gets to run. We also hold the RCU read lock over single + * stepping to avoid looking up the probe and kmmio_fault_page + * again. */ preempt_disable(); - rcu_read_lock(); + faultpage = get_kmmio_fault_page(addr); if (!faultpage) { /* @@ -287,14 +284,24 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) if (ctx->probe && ctx->probe->pre_handler) ctx->probe->pre_handler(ctx->probe, regs, addr); + /* + * Enable single-stepping and disable interrupts for the faulting + * context. Local interrupts must not get enabled during stepping. + */ regs->flags |= TF_MASK; regs->flags &= ~IF_MASK; /* Now we set present bit in PTE and single step. */ disarm_kmmio_fault_page(ctx->fpage->page, NULL); + /* + * If another cpu accesses the same page while we are stepping, + * the access will not be caught. It will simply succeed and the + * only downside is we lose the event. If this becomes a problem, + * the user should drop to single cpu before tracing. + */ + put_cpu_var(kmmio_ctx); - rcu_read_unlock(); return 1; no_kmmio_ctx: @@ -313,32 +320,15 @@ no_kmmio: static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) { int ret = 0; - struct kmmio_probe *probe; - struct kmmio_fault_page *faultpage; struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); if (!ctx->active) goto out; - rcu_read_lock(); - - faultpage = get_kmmio_fault_page(ctx->addr); - probe = get_kmmio_probe(ctx->addr); - if (faultpage != ctx->fpage || probe != ctx->probe) { - /* - * The trace setup changed after kmmio_handler() and before - * running this respective post handler. User does not want - * the result anymore. - */ - ctx->probe = NULL; - ctx->fpage = NULL; - } - if (ctx->probe && ctx->probe->post_handler) ctx->probe->post_handler(ctx->probe, condition, regs); - if (ctx->fpage) - arm_kmmio_fault_page(ctx->fpage->page, NULL); + arm_kmmio_fault_page(ctx->fpage->page, NULL); regs->flags &= ~TF_MASK; regs->flags |= ctx->saved_flags; @@ -346,6 +336,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) /* These were acquired in kmmio_handler(). */ ctx->active--; BUG_ON(ctx->active); + rcu_read_unlock(); preempt_enable_no_resched(); /* @@ -355,8 +346,6 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) */ if (!(regs->flags & TF_MASK)) ret = 1; - - rcu_read_unlock(); out: put_cpu_var(kmmio_ctx); return ret; @@ -411,15 +400,16 @@ static void release_kmmio_fault_page(unsigned long page, int register_kmmio_probe(struct kmmio_probe *p) { + unsigned long flags; int ret = 0; unsigned long size = 0; - spin_lock_irq(&kmmio_lock); - kmmio_count++; + spin_lock_irqsave(&kmmio_lock, flags); if (get_kmmio_probe(p->addr)) { ret = -EEXIST; goto out; } + kmmio_count++; list_add_rcu(&p->list, &kmmio_probes); while (size < p->len) { if (add_kmmio_fault_page(p->addr + size)) @@ -427,7 +417,7 @@ int register_kmmio_probe(struct kmmio_probe *p) size += PAGE_SIZE; } out: - spin_unlock_irq(&kmmio_lock); + spin_unlock_irqrestore(&kmmio_lock, flags); /* * XXX: What should I do here? * Here was a call to global_flush_tlb(), but it does not exist @@ -478,7 +468,8 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) /* * Remove a kmmio probe. You have to synchronize_rcu() before you can be - * sure that the callbacks will not be called anymore. + * sure that the callbacks will not be called anymore. Only after that + * you may actually release your struct kmmio_probe. * * Unregistering a kmmio fault page has three steps: * 1. release_kmmio_fault_page() @@ -490,18 +481,19 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) */ void unregister_kmmio_probe(struct kmmio_probe *p) { + unsigned long flags; unsigned long size = 0; struct kmmio_fault_page *release_list = NULL; struct kmmio_delayed_release *drelease; - spin_lock_irq(&kmmio_lock); + spin_lock_irqsave(&kmmio_lock, flags); while (size < p->len) { release_kmmio_fault_page(p->addr + size, &release_list); size += PAGE_SIZE; } list_del_rcu(&p->list); kmmio_count--; - spin_unlock_irq(&kmmio_lock); + spin_unlock_irqrestore(&kmmio_lock, flags); drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); if (!drelease) { diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index e1a5085..7386440 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -19,6 +19,8 @@ * * Derived from the read-mod example from relay-examples by Tom Zanussi. */ +#define DEBUG 1 + #include #include #include @@ -34,12 +36,12 @@ #include "pf_in.h" -/* This app's relay channel files will appear in /debug/mmio-trace */ -#define APP_DIR "mmio-trace" -/* the marker injection file in /proc */ -#define MARKER_FILE "mmio-marker" +#define NAME "mmiotrace: " -#define MODULE_NAME "mmiotrace" +/* This app's relay channel files will appear in /debug/mmio-trace */ +static const char APP_DIR[] = "mmio-trace"; +/* the marker injection file in /debug/APP_DIR */ +static const char MARKER_FILE[] = "mmio-marker"; struct trap_reason { unsigned long addr; @@ -48,6 +50,15 @@ struct trap_reason { int active_traces; }; +struct remap_trace { + struct list_head list; + struct kmmio_probe probe; + unsigned long phys; + unsigned long id; +}; + +static const size_t subbuf_size = 256*1024; + /* Accessed per-cpu. */ static DEFINE_PER_CPU(struct trap_reason, pf_reason); static DEFINE_PER_CPU(struct mm_io_header_rw, cpu_trace); @@ -55,33 +66,53 @@ static DEFINE_PER_CPU(struct mm_io_header_rw, cpu_trace); /* Access to this is not per-cpu. */ static DEFINE_PER_CPU(atomic_t, dropped); -static struct file_operations mmio_fops = { - .owner = THIS_MODULE, -}; +static struct dentry *dir; +static struct dentry *enabled_file; +static struct dentry *marker_file; -static const size_t subbuf_size = 256*1024; +static DEFINE_MUTEX(mmiotrace_mutex); +static DEFINE_SPINLOCK(trace_lock); +static atomic_t mmiotrace_enabled; +static LIST_HEAD(trace_list); /* struct remap_trace */ static struct rchan *chan; -static struct dentry *dir; -static struct proc_dir_entry *proc_marker_file; + +/* + * Locking in this file: + * - mmiotrace_mutex enforces enable/disable_mmiotrace() critical sections. + * - mmiotrace_enabled may be modified only when holding mmiotrace_mutex + * and trace_lock. + * - Routines depending on is_enabled() must take trace_lock. + * - trace_list users must hold trace_lock. + * - is_enabled() guarantees that chan is valid. + * - pre/post callbacks assume the effect of is_enabled() being true. + */ /* module parameters */ -static unsigned int n_subbufs = 32*4; -static unsigned long filter_offset; -static int nommiotrace; -static int ISA_trace; -static int trace_pc; +static unsigned int n_subbufs = 32*4; +static unsigned long filter_offset; +static int nommiotrace; +static int ISA_trace; +static int trace_pc; +static int enable_now; module_param(n_subbufs, uint, 0); module_param(filter_offset, ulong, 0); module_param(nommiotrace, bool, 0); module_param(ISA_trace, bool, 0); module_param(trace_pc, bool, 0); +module_param(enable_now, bool, 0); MODULE_PARM_DESC(n_subbufs, "Number of 256kB buffers, default 128."); MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); MODULE_PARM_DESC(trace_pc, "Record address of faulting instructions."); +MODULE_PARM_DESC(enable_now, "Start mmiotracing immediately on module load."); + +static bool is_enabled(void) +{ + return atomic_read(&mmiotrace_enabled); +} static void record_timestamp(struct mm_io_header *header) { @@ -93,15 +124,15 @@ static void record_timestamp(struct mm_io_header *header) } /* - * Write callback for the /proc entry: + * Write callback for the debugfs entry: * Read a marker and write it to the mmio trace log */ -static int write_marker(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t write_marker(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) { char *event = NULL; struct mm_io_header *headp; - int len = (count > 65535) ? 65535 : count; + ssize_t len = (count > 65535) ? 65535 : count; event = kzalloc(sizeof(*headp) + len, GFP_KERNEL); if (!event) @@ -117,7 +148,12 @@ static int write_marker(struct file *file, const char __user *buffer, return -EFAULT; } - relay_write(chan, event, sizeof(*headp) + len); + spin_lock_irq(&trace_lock); + if (is_enabled()) + relay_write(chan, event, sizeof(*headp) + len); + else + len = -EINVAL; + spin_unlock_irq(&trace_lock); kfree(event); return len; } @@ -128,19 +164,18 @@ static void print_pte(unsigned long address) pte_t *pte = lookup_address(address, &level); if (!pte) { - pr_err(MODULE_NAME ": Error in %s: no pte for page 0x%08lx\n", + pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", __func__, address); return; } if (level == PG_LEVEL_2M) { - pr_emerg(MODULE_NAME ": 4MB pages are not currently " - "supported: %lx\n", address); + pr_emerg(NAME "4MB pages are not currently supported: " + "0x%08lx\n", address); BUG(); } - pr_info(MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", - address, pte_val(*pte), - pte_val(*pte) & _PAGE_PRESENT); + pr_info(NAME "pte for 0x%lx: 0x%lx 0x%lx\n", address, pte_val(*pte), + pte_val(*pte) & _PAGE_PRESENT); } /* @@ -150,22 +185,18 @@ static void print_pte(unsigned long address) static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) { const struct trap_reason *my_reason = &get_cpu_var(pf_reason); - pr_emerg(MODULE_NAME ": unexpected fault for address: %lx, " - "last fault for address: %lx\n", + pr_emerg(NAME "unexpected fault for address: 0x%08lx, " + "last fault for address: 0x%08lx\n", addr, my_reason->addr); print_pte(addr); + print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); + print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); #ifdef __i386__ - print_symbol(KERN_EMERG "faulting EIP is at %s\n", regs->ip); - print_symbol(KERN_EMERG "last faulting EIP was at %s\n", - my_reason->ip); pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->ax, regs->bx, regs->cx, regs->dx); pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", regs->si, regs->di, regs->bp, regs->sp); #else - print_symbol(KERN_EMERG "faulting RIP is at %s\n", regs->ip); - print_symbol(KERN_EMERG "last faulting RIP was at %s\n", - my_reason->ip); pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", regs->ax, regs->cx, regs->dx); pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", @@ -197,6 +228,10 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs, my_trace->header.pid = 0; my_trace->header.data_len = sizeof(struct mm_io_rw); my_trace->rw.address = addr; + /* + * struct remap_trace *trace = p->user_data; + * phys = addr - trace->probe.addr + trace->phys; + */ /* * Only record the program counter when requested. @@ -246,15 +281,10 @@ static void post(struct kmmio_probe *p, unsigned long condition, struct trap_reason *my_reason = &get_cpu_var(pf_reason); struct mm_io_header_rw *my_trace = &get_cpu_var(cpu_trace); - /* - * XXX: This might not get called, if the probe is removed while - * trace hit is on flight. - */ - /* this should always return the active_trace count to 0 */ my_reason->active_traces--; if (my_reason->active_traces) { - pr_emerg(MODULE_NAME ": unexpected post handler"); + pr_emerg(NAME "unexpected post handler"); BUG(); } @@ -284,20 +314,23 @@ static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, int count; if (relay_buf_full(buf)) { if (atomic_inc_return(drop) == 1) - pr_err(MODULE_NAME ": cpu %d buffer full!\n", cpu); + pr_err(NAME "cpu %d buffer full!\n", cpu); return 0; } count = atomic_read(drop); if (count) { - pr_err(MODULE_NAME ": cpu %d buffer no longer full, " - "missed %d events.\n", - cpu, count); + pr_err(NAME "cpu %d buffer no longer full, missed %d events.\n", + cpu, count); atomic_sub(count, drop); } return 1; } +static struct file_operations mmio_fops = { + .owner = THIS_MODULE, +}; + /* file_create() callback. Creates relay file in debugfs. */ static struct dentry *create_buf_file_handler(const char *filename, struct dentry *parent, @@ -333,34 +366,10 @@ static struct rchan_callbacks relay_callbacks = { .remove_buf_file = remove_buf_file_handler, }; -/* - * create_channel - creates channel /debug/APP_DIR/cpuXXX - * Returns channel on success, NULL otherwise - */ -static struct rchan *create_channel(unsigned size, unsigned n) -{ - return relay_open("cpu", dir, size, n, &relay_callbacks, NULL); -} - -/* destroy_channel - destroys channel /debug/APP_DIR/cpuXXX */ -static void destroy_channel(void) -{ - if (chan) { - relay_close(chan); - chan = NULL; - } -} - -struct remap_trace { - struct list_head list; - struct kmmio_probe probe; -}; -static LIST_HEAD(trace_list); -static DEFINE_SPINLOCK(trace_list_lock); - -static void do_ioremap_trace_core(unsigned long offset, unsigned long size, +static void ioremap_trace_core(unsigned long offset, unsigned long size, void __iomem *addr) { + static atomic_t next_id; struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); struct mm_io_header_map event = { .header = { @@ -380,61 +389,49 @@ static void do_ioremap_trace_core(unsigned long offset, unsigned long size, }; record_timestamp(&event.header); + if (!trace) { + pr_err(NAME "kmalloc failed in ioremap\n"); + return; + } + *trace = (struct remap_trace) { .probe = { .addr = (unsigned long)addr, .len = size, .pre_handler = pre, .post_handler = post, - } + .user_data = trace + }, + .phys = offset, + .id = atomic_inc_return(&next_id) }; + spin_lock_irq(&trace_lock); + if (!is_enabled()) + goto not_enabled; + relay_write(chan, &event, sizeof(event)); - spin_lock(&trace_list_lock); list_add_tail(&trace->list, &trace_list); - spin_unlock(&trace_list_lock); if (!nommiotrace) register_kmmio_probe(&trace->probe); + +not_enabled: + spin_unlock_irq(&trace_lock); } -static void ioremap_trace_core(unsigned long offset, unsigned long size, - void __iomem *addr) +void +mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) { - if ((filter_offset) && (offset != filter_offset)) + if (!is_enabled()) /* recheck and proper locking in *_core() */ return; - /* Don't trace the low PCI/ISA area, it's always mapped.. */ - if (!ISA_trace && (offset < ISA_END_ADDRESS) && - (offset + size > ISA_START_ADDRESS)) { - pr_notice(MODULE_NAME ": Ignoring map of low PCI/ISA area " - "(0x%lx-0x%lx)\n", - offset, offset + size); + pr_debug(NAME "ioremap_*(0x%lx, 0x%lx) = %p\n", offset, size, addr); + if ((filter_offset) && (offset != filter_offset)) return; - } - do_ioremap_trace_core(offset, size, addr); -} - -void __iomem *ioremap_cache_trace(unsigned long offset, unsigned long size) -{ - void __iomem *p = ioremap_cache(offset, size); - pr_debug(MODULE_NAME ": ioremap_cache(0x%lx, 0x%lx) = %p\n", - offset, size, p); - ioremap_trace_core(offset, size, p); - return p; + ioremap_trace_core(offset, size, addr); } -EXPORT_SYMBOL(ioremap_cache_trace); -void __iomem *ioremap_nocache_trace(unsigned long offset, unsigned long size) -{ - void __iomem *p = ioremap_nocache(offset, size); - pr_debug(MODULE_NAME ": ioremap_nocache(0x%lx, 0x%lx) = %p\n", - offset, size, p); - ioremap_trace_core(offset, size, p); - return p; -} -EXPORT_SYMBOL(ioremap_nocache_trace); - -void iounmap_trace(volatile void __iomem *addr) +static void iounmap_trace_core(volatile void __iomem *addr) { struct mm_io_header_map event = { .header = { @@ -454,84 +451,212 @@ void iounmap_trace(volatile void __iomem *addr) }; struct remap_trace *trace; struct remap_trace *tmp; - pr_debug(MODULE_NAME ": Unmapping %p.\n", addr); + struct remap_trace *found_trace = NULL; + + pr_debug(NAME "Unmapping %p.\n", addr); record_timestamp(&event.header); - spin_lock(&trace_list_lock); + spin_lock_irq(&trace_lock); + if (!is_enabled()) + goto not_enabled; + list_for_each_entry_safe(trace, tmp, &trace_list, list) { if ((unsigned long)addr == trace->probe.addr) { if (!nommiotrace) unregister_kmmio_probe(&trace->probe); list_del(&trace->list); - kfree(trace); + found_trace = trace; break; } } - spin_unlock(&trace_list_lock); relay_write(chan, &event, sizeof(event)); - iounmap(addr); + +not_enabled: + spin_unlock_irq(&trace_lock); + if (found_trace) { + synchronize_rcu(); /* unregister_kmmio_probe() requirement */ + kfree(found_trace); + } +} + +void mmiotrace_iounmap(volatile void __iomem *addr) +{ + might_sleep(); + if (is_enabled()) /* recheck and proper locking in *_core() */ + iounmap_trace_core(addr); } -EXPORT_SYMBOL(iounmap_trace); static void clear_trace_list(void) { struct remap_trace *trace; struct remap_trace *tmp; - spin_lock(&trace_list_lock); - list_for_each_entry_safe(trace, tmp, &trace_list, list) { - pr_warning(MODULE_NAME ": purging non-iounmapped " + /* + * No locking required, because the caller ensures we are in a + * critical section via mutex, and is_enabled() is false, + * i.e. nothing can traverse or modify this list. + * Caller also ensures is_enabled() cannot change. + */ + list_for_each_entry(trace, &trace_list, list) { + pr_notice(NAME "purging non-iounmapped " "trace @0x%08lx, size 0x%lx.\n", trace->probe.addr, trace->probe.len); if (!nommiotrace) unregister_kmmio_probe(&trace->probe); + } + synchronize_rcu(); /* unregister_kmmio_probe() requirement */ + + list_for_each_entry_safe(trace, tmp, &trace_list, list) { list_del(&trace->list); kfree(trace); + } +} + +static ssize_t read_enabled_file_bool(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[3]; + + if (is_enabled()) + buf[0] = '1'; + else + buf[0] = '0'; + buf[1] = '\n'; + buf[2] = '\0'; + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static void enable_mmiotrace(void); +static void disable_mmiotrace(void); + +static ssize_t write_enabled_file_bool(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[32]; + int buf_size = min(count, (sizeof(buf)-1)); + + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + switch (buf[0]) { + case 'y': + case 'Y': + case '1': + enable_mmiotrace(); + break; + case 'n': + case 'N': + case '0': + disable_mmiotrace(); break; } - spin_unlock(&trace_list_lock); + + return count; +} + +/* this ripped from kernel/kprobes.c */ +static struct file_operations fops_enabled = { + .owner = THIS_MODULE, + .read = read_enabled_file_bool, + .write = write_enabled_file_bool +}; + +static struct file_operations fops_marker = { + .owner = THIS_MODULE, + .write = write_marker +}; + +static void enable_mmiotrace(void) +{ + mutex_lock(&mmiotrace_mutex); + if (is_enabled()) + goto out; + + chan = relay_open("cpu", dir, subbuf_size, n_subbufs, + &relay_callbacks, NULL); + if (!chan) { + pr_err(NAME "relay app channel creation failed.\n"); + goto out; + } + + reference_kmmio(); + + marker_file = debugfs_create_file("marker", 0660, dir, NULL, + &fops_marker); + if (!marker_file) + pr_err(NAME "marker file creation failed.\n"); + + if (nommiotrace) + pr_info(NAME "MMIO tracing disabled.\n"); + if (ISA_trace) + pr_warning(NAME "Warning! low ISA range will be traced.\n"); + spin_lock_irq(&trace_lock); + atomic_inc(&mmiotrace_enabled); + spin_unlock_irq(&trace_lock); + pr_info(NAME "enabled.\n"); +out: + mutex_unlock(&mmiotrace_mutex); +} + +static void disable_mmiotrace(void) +{ + mutex_lock(&mmiotrace_mutex); + if (!is_enabled()) + goto out; + + spin_lock_irq(&trace_lock); + atomic_dec(&mmiotrace_enabled); + BUG_ON(is_enabled()); + spin_unlock_irq(&trace_lock); + + clear_trace_list(); /* guarantees: no more kmmio callbacks */ + unreference_kmmio(); + if (marker_file) { + debugfs_remove(marker_file); + marker_file = NULL; + } + if (chan) { + relay_close(chan); + chan = NULL; + } + + pr_info(NAME "disabled.\n"); +out: + mutex_unlock(&mmiotrace_mutex); } static int __init init(void) { + pr_debug(NAME "load...\n"); if (n_subbufs < 2) return -EINVAL; dir = debugfs_create_dir(APP_DIR, NULL); if (!dir) { - pr_err(MODULE_NAME ": Couldn't create relay app directory.\n"); + pr_err(NAME "Couldn't create relay app directory.\n"); return -ENOMEM; } - chan = create_channel(subbuf_size, n_subbufs); - if (!chan) { + enabled_file = debugfs_create_file("enabled", 0600, dir, NULL, + &fops_enabled); + if (!enabled_file) { + pr_err(NAME "Couldn't create enabled file.\n"); debugfs_remove(dir); - pr_err(MODULE_NAME ": relay app channel creation failed\n"); return -ENOMEM; } - reference_kmmio(); - - proc_marker_file = create_proc_entry(MARKER_FILE, 0, NULL); - if (proc_marker_file) - proc_marker_file->write_proc = write_marker; + if (enable_now) + enable_mmiotrace(); - pr_debug(MODULE_NAME ": loaded.\n"); - if (nommiotrace) - pr_info(MODULE_NAME ": MMIO tracing disabled.\n"); - if (ISA_trace) - pr_warning(MODULE_NAME ": Warning! low ISA range will be " - "traced.\n"); return 0; } static void __exit cleanup(void) { - pr_debug(MODULE_NAME ": unload...\n"); - clear_trace_list(); - unreference_kmmio(); - remove_proc_entry(MARKER_FILE, NULL); - destroy_channel(); + pr_debug(NAME "unload...\n"); + if (enabled_file) + debugfs_remove(enabled_file); + disable_mmiotrace(); if (dir) debugfs_remove(dir); } diff --git a/arch/x86/kernel/mmiotrace/testmmiotrace.c b/arch/x86/kernel/mmiotrace/testmmiotrace.c index 5ecff57..cfa60b2 100644 --- a/arch/x86/kernel/mmiotrace/testmmiotrace.c +++ b/arch/x86/kernel/mmiotrace/testmmiotrace.c @@ -4,10 +4,6 @@ #include #include -extern void __iomem *ioremap_nocache_trace(unsigned long offset, - unsigned long size); -extern void iounmap_trace(volatile void __iomem *addr); - #define MODULE_NAME "testmmiotrace" static unsigned long mmio_address; @@ -28,25 +24,24 @@ static void do_write_test(void __iomem *p) static void do_read_test(void __iomem *p) { unsigned int i; - volatile unsigned int v; for (i = 0; i < 256; i++) - v = ioread8(p + i); + ioread8(p + i); for (i = 1024; i < (5 * 1024); i += 2) - v = ioread16(p + i); + ioread16(p + i); for (i = (5 * 1024); i < (16 * 1024); i += 4) - v = ioread32(p + i); + ioread32(p + i); } static void do_test(void) { - void __iomem *p = ioremap_nocache_trace(mmio_address, 0x4000); + void __iomem *p = ioremap_nocache(mmio_address, 0x4000); if (!p) { pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); return; } do_write_test(p); do_read_test(p); - iounmap_trace(p); + iounmap(p); } static int __init init(void) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 71bb315..8927c87 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -126,6 +127,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, unsigned long new_prot_val; pgprot_t prot; int retval; + void __iomem *ret_addr; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -233,7 +235,10 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, return NULL; } - return (void __iomem *) (vaddr + offset); + ret_addr = (void __iomem *) (vaddr + offset); + mmiotrace_ioremap(phys_addr, size, ret_addr); + + return ret_addr; } /** @@ -325,6 +330,8 @@ void iounmap(volatile void __iomem *addr) addr = (volatile void __iomem *) (PAGE_MASK & (unsigned long __force)addr); + mmiotrace_iounmap(addr); + /* Use the vm area unlocked, assuming the caller ensures there isn't another iounmap for the same address in parallel. Reuse of the virtual address is prevented by diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index d87a6cd..cb5efd0 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -16,11 +16,12 @@ typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, unsigned long condition, struct pt_regs *); struct kmmio_probe { - struct list_head list; + struct list_head list; /* kmmio internal list */ unsigned long addr; /* start location of the probe point */ unsigned long len; /* length of the probe region */ kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */ kmmio_post_handler_t post_handler; /* Called after addr is executed */ + void *user_data; }; /* kmmio is active by some kmmio_probes? */ @@ -38,6 +39,21 @@ extern void unregister_kmmio_probe(struct kmmio_probe *p); /* Called from page fault handler. */ extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); +/* Called from ioremap.c */ +#ifdef CONFIG_MMIOTRACE +extern void +mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr); +extern void mmiotrace_iounmap(volatile void __iomem *addr); +#else +static inline void +mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) +{ +} +static inline void mmiotrace_iounmap(volatile void __iomem *addr) +{ +} +#endif /* CONFIG_MMIOTRACE_HOOKS */ + #endif /* __KERNEL__ */ -- cgit v0.10.2 From f984b51e0779a6dd30feedc41404013ca54e5d05 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: ftrace: add mmiotrace plugin On Sat, 22 Mar 2008 13:07:47 +0100 Ingo Molnar wrote: > > > i'd suggest the following: pull x86.git and sched-devel.git into a > > > single tree [the two will combine without rejects]. Then try to add a > > > kernel/tracing/trace_mmiotrace.c ftrace plugin. The trace_sysprof.c > > > plugin might be a good example. > > > > I did this and now I have mmiotrace enabled/disabled via the tracing > > framework (what do we call this, since ftrace is one of the tracers?). > > cool! could you send the patches for that? (even if they are not fully > functional yet) Patch attached in the end. Nice to see how much code disappeared. I tried to mark all the features I had to break with XXX-comments. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index aa0d646..7e4b849 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -173,7 +173,8 @@ config MMIOTRACE_HOOKS config MMIOTRACE bool "Memory mapped IO tracing" - depends on DEBUG_KERNEL && RELAY && DEBUG_FS + depends on DEBUG_KERNEL && RELAY + select TRACING select MMIOTRACE_HOOKS default y help diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index 7386440..c7a67d7 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -22,9 +22,8 @@ #define DEBUG 1 #include -#include #include -#include +#include #include #include #include @@ -63,18 +62,18 @@ static const size_t subbuf_size = 256*1024; static DEFINE_PER_CPU(struct trap_reason, pf_reason); static DEFINE_PER_CPU(struct mm_io_header_rw, cpu_trace); +#if 0 /* XXX: no way gather this info anymore */ /* Access to this is not per-cpu. */ static DEFINE_PER_CPU(atomic_t, dropped); +#endif static struct dentry *dir; -static struct dentry *enabled_file; static struct dentry *marker_file; static DEFINE_MUTEX(mmiotrace_mutex); static DEFINE_SPINLOCK(trace_lock); static atomic_t mmiotrace_enabled; static LIST_HEAD(trace_list); /* struct remap_trace */ -static struct rchan *chan; /* * Locking in this file: @@ -93,36 +92,24 @@ static unsigned long filter_offset; static int nommiotrace; static int ISA_trace; static int trace_pc; -static int enable_now; module_param(n_subbufs, uint, 0); module_param(filter_offset, ulong, 0); module_param(nommiotrace, bool, 0); module_param(ISA_trace, bool, 0); module_param(trace_pc, bool, 0); -module_param(enable_now, bool, 0); MODULE_PARM_DESC(n_subbufs, "Number of 256kB buffers, default 128."); MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); MODULE_PARM_DESC(trace_pc, "Record address of faulting instructions."); -MODULE_PARM_DESC(enable_now, "Start mmiotracing immediately on module load."); static bool is_enabled(void) { return atomic_read(&mmiotrace_enabled); } -static void record_timestamp(struct mm_io_header *header) -{ - struct timespec now; - - getnstimeofday(&now); - header->sec = now.tv_sec; - header->nsec = now.tv_nsec; -} - /* * Write callback for the debugfs entry: * Read a marker and write it to the mmio trace log @@ -141,7 +128,6 @@ static ssize_t write_marker(struct file *file, const char __user *buffer, headp = (struct mm_io_header *)event; headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT); headp->data_len = len; - record_timestamp(headp); if (copy_from_user(event + sizeof(*headp), buffer, len)) { kfree(event); @@ -149,9 +135,11 @@ static ssize_t write_marker(struct file *file, const char __user *buffer, } spin_lock_irq(&trace_lock); +#if 0 /* XXX: convert this to use tracing */ if (is_enabled()) relay_write(chan, event, sizeof(*headp) + len); else +#endif len = -EINVAL; spin_unlock_irq(&trace_lock); kfree(event); @@ -242,7 +230,11 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs, else my_trace->rw.pc = 0; - record_timestamp(&my_trace->header); + /* + * XXX: the timestamp recorded will be *after* the tracing has been + * done, not at the time we hit the instruction. SMP implications + * on event ordering? + */ switch (type) { case REG_READ: @@ -295,77 +287,19 @@ static void post(struct kmmio_probe *p, unsigned long condition, default: break; } - relay_write(chan, my_trace, sizeof(*my_trace)); + + /* + * XXX: Several required values are ignored: + * - mapping id + * - program counter + * Also the address should be physical, not virtual. + */ + mmio_trace_record(my_trace->header.type, my_trace->rw.address, + my_trace->rw.value); put_cpu_var(cpu_trace); put_cpu_var(pf_reason); } -/* - * subbuf_start() relay callback. - * - * Defined so that we know when events are dropped due to the buffer-full - * condition. - */ -static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, - void *prev_subbuf, size_t prev_padding) -{ - unsigned int cpu = buf->cpu; - atomic_t *drop = &per_cpu(dropped, cpu); - int count; - if (relay_buf_full(buf)) { - if (atomic_inc_return(drop) == 1) - pr_err(NAME "cpu %d buffer full!\n", cpu); - return 0; - } - count = atomic_read(drop); - if (count) { - pr_err(NAME "cpu %d buffer no longer full, missed %d events.\n", - cpu, count); - atomic_sub(count, drop); - } - - return 1; -} - -static struct file_operations mmio_fops = { - .owner = THIS_MODULE, -}; - -/* file_create() callback. Creates relay file in debugfs. */ -static struct dentry *create_buf_file_handler(const char *filename, - struct dentry *parent, - int mode, - struct rchan_buf *buf, - int *is_global) -{ - struct dentry *buf_file; - - mmio_fops.read = relay_file_operations.read; - mmio_fops.open = relay_file_operations.open; - mmio_fops.poll = relay_file_operations.poll; - mmio_fops.mmap = relay_file_operations.mmap; - mmio_fops.release = relay_file_operations.release; - mmio_fops.splice_read = relay_file_operations.splice_read; - - buf_file = debugfs_create_file(filename, mode, parent, buf, - &mmio_fops); - - return buf_file; -} - -/* file_remove() default callback. Removes relay file in debugfs. */ -static int remove_buf_file_handler(struct dentry *dentry) -{ - debugfs_remove(dentry); - return 0; -} - -static struct rchan_callbacks relay_callbacks = { - .subbuf_start = subbuf_start_handler, - .create_buf_file = create_buf_file_handler, - .remove_buf_file = remove_buf_file_handler, -}; - static void ioremap_trace_core(unsigned long offset, unsigned long size, void __iomem *addr) { @@ -387,7 +321,6 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, .pc = 0 } }; - record_timestamp(&event.header); if (!trace) { pr_err(NAME "kmalloc failed in ioremap\n"); @@ -410,7 +343,10 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, if (!is_enabled()) goto not_enabled; - relay_write(chan, &event, sizeof(event)); + /* + * XXX: Insufficient data recorded! + */ + mmio_trace_record(event.header.type, event.map.addr, event.map.len); list_add_tail(&trace->list, &trace_list); if (!nommiotrace) register_kmmio_probe(&trace->probe); @@ -454,7 +390,6 @@ static void iounmap_trace_core(volatile void __iomem *addr) struct remap_trace *found_trace = NULL; pr_debug(NAME "Unmapping %p.\n", addr); - record_timestamp(&event.header); spin_lock_irq(&trace_lock); if (!is_enabled()) @@ -469,7 +404,8 @@ static void iounmap_trace_core(volatile void __iomem *addr) break; } } - relay_write(chan, &event, sizeof(event)); + mmio_trace_record(event.header.type, event.map.addr, + found_trace ? found_trace->id : -1); not_enabled: spin_unlock_irq(&trace_lock); @@ -512,77 +448,23 @@ static void clear_trace_list(void) } } -static ssize_t read_enabled_file_bool(struct file *file, - char __user *user_buf, size_t count, loff_t *ppos) -{ - char buf[3]; - - if (is_enabled()) - buf[0] = '1'; - else - buf[0] = '0'; - buf[1] = '\n'; - buf[2] = '\0'; - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); -} - -static void enable_mmiotrace(void); -static void disable_mmiotrace(void); - -static ssize_t write_enabled_file_bool(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - char buf[32]; - int buf_size = min(count, (sizeof(buf)-1)); - - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - switch (buf[0]) { - case 'y': - case 'Y': - case '1': - enable_mmiotrace(); - break; - case 'n': - case 'N': - case '0': - disable_mmiotrace(); - break; - } - - return count; -} - -/* this ripped from kernel/kprobes.c */ -static struct file_operations fops_enabled = { - .owner = THIS_MODULE, - .read = read_enabled_file_bool, - .write = write_enabled_file_bool -}; - static struct file_operations fops_marker = { .owner = THIS_MODULE, .write = write_marker }; -static void enable_mmiotrace(void) +void enable_mmiotrace(void) { mutex_lock(&mmiotrace_mutex); if (is_enabled()) goto out; - chan = relay_open("cpu", dir, subbuf_size, n_subbufs, - &relay_callbacks, NULL); - if (!chan) { - pr_err(NAME "relay app channel creation failed.\n"); - goto out; - } - reference_kmmio(); +#if 0 /* XXX: tracing does not support text entries */ marker_file = debugfs_create_file("marker", 0660, dir, NULL, &fops_marker); +#endif if (!marker_file) pr_err(NAME "marker file creation failed.\n"); @@ -598,7 +480,7 @@ out: mutex_unlock(&mmiotrace_mutex); } -static void disable_mmiotrace(void) +void disable_mmiotrace(void) { mutex_lock(&mmiotrace_mutex); if (!is_enabled()) @@ -615,17 +497,13 @@ static void disable_mmiotrace(void) debugfs_remove(marker_file); marker_file = NULL; } - if (chan) { - relay_close(chan); - chan = NULL; - } pr_info(NAME "disabled.\n"); out: mutex_unlock(&mmiotrace_mutex); } -static int __init init(void) +int __init init_mmiotrace(void) { pr_debug(NAME "load...\n"); if (n_subbufs < 2) @@ -636,31 +514,5 @@ static int __init init(void) pr_err(NAME "Couldn't create relay app directory.\n"); return -ENOMEM; } - - enabled_file = debugfs_create_file("enabled", 0600, dir, NULL, - &fops_enabled); - if (!enabled_file) { - pr_err(NAME "Couldn't create enabled file.\n"); - debugfs_remove(dir); - return -ENOMEM; - } - - if (enable_now) - enable_mmiotrace(); - return 0; } - -static void __exit cleanup(void) -{ - pr_debug(NAME "unload...\n"); - if (enabled_file) - debugfs_remove(enabled_file); - disable_mmiotrace(); - if (dir) - debugfs_remove(dir); -} - -module_init(init); -module_exit(cleanup); -MODULE_LICENSE("GPL"); diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index cb5efd0..579b3b06 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -54,6 +54,12 @@ static inline void mmiotrace_iounmap(volatile void __iomem *addr) } #endif /* CONFIG_MMIOTRACE_HOOKS */ +/* in kernel/trace/trace_mmiotrace.c */ +extern int __init init_mmiotrace(void); +extern void enable_mmiotrace(void); +extern void disable_mmiotrace(void); +extern void mmio_trace_record(u32 type, unsigned long addr, unsigned long arg); + #endif /* __KERNEL__ */ diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index d9efbbf..c44a7dc 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_FTRACE) += trace_functions.o obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o +obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o libftrace-y := ftrace.o diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c new file mode 100644 index 0000000..e4dd03c --- /dev/null +++ b/kernel/trace/trace_mmiotrace.c @@ -0,0 +1,84 @@ +/* + * Memory mapped I/O tracing + * + * Copyright (C) 2008 Pekka Paalanen + */ + +#define DEBUG 1 + +#include +#include + +#include "trace.h" + +extern void +__trace_special(void *__tr, void *__data, + unsigned long arg1, unsigned long arg2, unsigned long arg3); + +static struct trace_array *mmio_trace_array; + + +static void mmio_trace_init(struct trace_array *tr) +{ + pr_debug("in %s\n", __func__); + mmio_trace_array = tr; + if (tr->ctrl) + enable_mmiotrace(); +} + +static void mmio_trace_reset(struct trace_array *tr) +{ + pr_debug("in %s\n", __func__); + if (tr->ctrl) + disable_mmiotrace(); +} + +static void mmio_trace_ctrl_update(struct trace_array *tr) +{ + pr_debug("in %s\n", __func__); + if (tr->ctrl) + enable_mmiotrace(); + else + disable_mmiotrace(); +} + +static struct tracer mmio_tracer __read_mostly = +{ + .name = "mmiotrace", + .init = mmio_trace_init, + .reset = mmio_trace_reset, + .ctrl_update = mmio_trace_ctrl_update, +}; + +__init static int init_mmio_trace(void) +{ + int ret = init_mmiotrace(); + if (ret) + return ret; + return register_tracer(&mmio_tracer); +} +device_initcall(init_mmio_trace); + +void mmio_trace_record(u32 type, unsigned long addr, unsigned long arg) +{ + struct trace_array *tr = mmio_trace_array; + struct trace_array_cpu *data = tr->data[smp_processor_id()]; + + if (!current || current->pid == 0) { + /* + * XXX: This is a problem. We need to able to record, no + * matter what. tracing_generic_entry_update() would crash. + */ + static unsigned limit; + if (limit++ < 12) + pr_err("Error in %s: no current.\n", __func__); + return; + } + if (!tr || !data) { + static unsigned limit; + if (limit++ < 12) + pr_err("%s: no tr or data\n", __func__); + return; + } + __trace_special(tr, data, type, addr, arg); +} -- cgit v0.10.2 From bd8ac686c73c7e925fcfe0b02dc4e7b947127864 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:57 +0200 Subject: ftrace: mmiotrace, updates here is a patch that makes mmiotrace work almost well within the tracing framework. The patch applies on top of my previous patch. I have my own output formatting in place now. Summary of changes: - fix the NULL dereference that was due to not calling tracing_reset() - add print_line() callback into struct tracer - implement print_line() for mmiotrace, producing up-to-spec text - add my output header, but that is not really called in the right place - rewrote the main structs in mmiotrace - added two new trace entry types: TRACE_MMIO_RW and TRACE_MMIO_MAP - made some functions in trace.c non-static - check current==NULL in tracing_generic_entry_update() - fix(?) comparison in trace_seq_printf() Things seem to work fine except a few issues. Markers (text lines injected into mmiotrace log) are missing, I did not feel hacking them in before we have variable length entries. My output header is printed only for 'trace' file, but not 'trace_pipe'. For some reason, despite my quick fix, iter->trace is NULL in print_trace_line() when called from 'trace_pipe' file, which means I don't get proper output formatting. I only tried by loading nouveau.ko, which just detects the card, and that is traced fine. I didn't try further. Map, two reads and unmap. Works perfectly. I am missing the information about overflows, I'd prefer to have a counter for lost events. I didn't try, but I guess currently there is no way of knowning when it overflows? So, not too far from being fully operational, it seems :-) And looking at the diffstat, there also is some 700-900 lines of user space code that just became obsolete. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 7e4b849..1d6de0d 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -173,7 +173,7 @@ config MMIOTRACE_HOOKS config MMIOTRACE bool "Memory mapped IO tracing" - depends on DEBUG_KERNEL && RELAY + depends on DEBUG_KERNEL select TRACING select MMIOTRACE_HOOKS default y diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index c7a67d7..62abc28 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -37,11 +37,6 @@ #define NAME "mmiotrace: " -/* This app's relay channel files will appear in /debug/mmio-trace */ -static const char APP_DIR[] = "mmio-trace"; -/* the marker injection file in /debug/APP_DIR */ -static const char MARKER_FILE[] = "mmio-marker"; - struct trap_reason { unsigned long addr; unsigned long ip; @@ -56,18 +51,15 @@ struct remap_trace { unsigned long id; }; -static const size_t subbuf_size = 256*1024; - /* Accessed per-cpu. */ static DEFINE_PER_CPU(struct trap_reason, pf_reason); -static DEFINE_PER_CPU(struct mm_io_header_rw, cpu_trace); +static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace); #if 0 /* XXX: no way gather this info anymore */ /* Access to this is not per-cpu. */ static DEFINE_PER_CPU(atomic_t, dropped); #endif -static struct dentry *dir; static struct dentry *marker_file; static DEFINE_MUTEX(mmiotrace_mutex); @@ -82,24 +74,21 @@ static LIST_HEAD(trace_list); /* struct remap_trace */ * and trace_lock. * - Routines depending on is_enabled() must take trace_lock. * - trace_list users must hold trace_lock. - * - is_enabled() guarantees that chan is valid. + * - is_enabled() guarantees that mmio_trace_record is allowed. * - pre/post callbacks assume the effect of is_enabled() being true. */ /* module parameters */ -static unsigned int n_subbufs = 32*4; static unsigned long filter_offset; static int nommiotrace; static int ISA_trace; static int trace_pc; -module_param(n_subbufs, uint, 0); module_param(filter_offset, ulong, 0); module_param(nommiotrace, bool, 0); module_param(ISA_trace, bool, 0); module_param(trace_pc, bool, 0); -MODULE_PARM_DESC(n_subbufs, "Number of 256kB buffers, default 128."); MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); @@ -110,6 +99,7 @@ static bool is_enabled(void) return atomic_read(&mmiotrace_enabled); } +#if 0 /* XXX: needs rewrite */ /* * Write callback for the debugfs entry: * Read a marker and write it to the mmio trace log @@ -145,6 +135,7 @@ static ssize_t write_marker(struct file *file, const char __user *buffer, kfree(event); return len; } +#endif static void print_pte(unsigned long address) { @@ -198,9 +189,10 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs, unsigned long addr) { struct trap_reason *my_reason = &get_cpu_var(pf_reason); - struct mm_io_header_rw *my_trace = &get_cpu_var(cpu_trace); + struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); const unsigned long instptr = instruction_pointer(regs); const enum reason_type type = get_ins_type(instptr); + struct remap_trace *trace = p->user_data; /* it doesn't make sense to have more than one active trace per cpu */ if (my_reason->active_traces) @@ -212,23 +204,17 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs, my_reason->addr = addr; my_reason->ip = instptr; - my_trace->header.type = MMIO_MAGIC; - my_trace->header.pid = 0; - my_trace->header.data_len = sizeof(struct mm_io_rw); - my_trace->rw.address = addr; - /* - * struct remap_trace *trace = p->user_data; - * phys = addr - trace->probe.addr + trace->phys; - */ + my_trace->phys = addr - trace->probe.addr + trace->phys; + my_trace->map_id = trace->id; /* * Only record the program counter when requested. * It may taint clean-room reverse engineering. */ if (trace_pc) - my_trace->rw.pc = instptr; + my_trace->pc = instptr; else - my_trace->rw.pc = 0; + my_trace->pc = 0; /* * XXX: the timestamp recorded will be *after* the tracing has been @@ -238,28 +224,25 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs, switch (type) { case REG_READ: - my_trace->header.type |= - (MMIO_READ << MMIO_OPCODE_SHIFT) | - (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); + my_trace->opcode = MMIO_READ; + my_trace->width = get_ins_mem_width(instptr); break; case REG_WRITE: - my_trace->header.type |= - (MMIO_WRITE << MMIO_OPCODE_SHIFT) | - (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); - my_trace->rw.value = get_ins_reg_val(instptr, regs); + my_trace->opcode = MMIO_WRITE; + my_trace->width = get_ins_mem_width(instptr); + my_trace->value = get_ins_reg_val(instptr, regs); break; case IMM_WRITE: - my_trace->header.type |= - (MMIO_WRITE << MMIO_OPCODE_SHIFT) | - (get_ins_mem_width(instptr) << MMIO_WIDTH_SHIFT); - my_trace->rw.value = get_ins_imm_val(instptr); + my_trace->opcode = MMIO_WRITE; + my_trace->width = get_ins_mem_width(instptr); + my_trace->value = get_ins_imm_val(instptr); break; default: { unsigned char *ip = (unsigned char *)instptr; - my_trace->header.type |= - (MMIO_UNKNOWN_OP << MMIO_OPCODE_SHIFT); - my_trace->rw.value = (*ip) << 16 | *(ip + 1) << 8 | + my_trace->opcode = MMIO_UNKNOWN_OP; + my_trace->width = 0; + my_trace->value = (*ip) << 16 | *(ip + 1) << 8 | *(ip + 2); } } @@ -271,7 +254,7 @@ static void post(struct kmmio_probe *p, unsigned long condition, struct pt_regs *regs) { struct trap_reason *my_reason = &get_cpu_var(pf_reason); - struct mm_io_header_rw *my_trace = &get_cpu_var(cpu_trace); + struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); /* this should always return the active_trace count to 0 */ my_reason->active_traces--; @@ -282,20 +265,13 @@ static void post(struct kmmio_probe *p, unsigned long condition, switch (my_reason->type) { case REG_READ: - my_trace->rw.value = get_ins_reg_val(my_reason->ip, regs); + my_trace->value = get_ins_reg_val(my_reason->ip, regs); break; default: break; } - /* - * XXX: Several required values are ignored: - * - mapping id - * - program counter - * Also the address should be physical, not virtual. - */ - mmio_trace_record(my_trace->header.type, my_trace->rw.address, - my_trace->rw.value); + mmio_trace_rw(my_trace); put_cpu_var(cpu_trace); put_cpu_var(pf_reason); } @@ -305,21 +281,11 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, { static atomic_t next_id; struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); - struct mm_io_header_map event = { - .header = { - .type = MMIO_MAGIC | - (MMIO_PROBE << MMIO_OPCODE_SHIFT), - .sec = 0, - .nsec = 0, - .pid = 0, - .data_len = sizeof(struct mm_io_map) - }, - .map = { - .phys = offset, - .addr = (unsigned long)addr, - .len = size, - .pc = 0 - } + struct mmiotrace_map map = { + .phys = offset, + .virt = (unsigned long)addr, + .len = size, + .opcode = MMIO_PROBE }; if (!trace) { @@ -338,15 +304,13 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, .phys = offset, .id = atomic_inc_return(&next_id) }; + map.map_id = trace->id; spin_lock_irq(&trace_lock); if (!is_enabled()) goto not_enabled; - /* - * XXX: Insufficient data recorded! - */ - mmio_trace_record(event.header.type, event.map.addr, event.map.len); + mmio_trace_mapping(&map); list_add_tail(&trace->list, &trace_list); if (!nommiotrace) register_kmmio_probe(&trace->probe); @@ -369,21 +333,11 @@ mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) static void iounmap_trace_core(volatile void __iomem *addr) { - struct mm_io_header_map event = { - .header = { - .type = MMIO_MAGIC | - (MMIO_UNPROBE << MMIO_OPCODE_SHIFT), - .sec = 0, - .nsec = 0, - .pid = 0, - .data_len = sizeof(struct mm_io_map) - }, - .map = { - .phys = 0, - .addr = (unsigned long)addr, - .len = 0, - .pc = 0 - } + struct mmiotrace_map map = { + .phys = 0, + .virt = (unsigned long)addr, + .len = 0, + .opcode = MMIO_UNPROBE }; struct remap_trace *trace; struct remap_trace *tmp; @@ -404,8 +358,8 @@ static void iounmap_trace_core(volatile void __iomem *addr) break; } } - mmio_trace_record(event.header.type, event.map.addr, - found_trace ? found_trace->id : -1); + map.map_id = (found_trace) ? found_trace->id : -1; + mmio_trace_mapping(&map); not_enabled: spin_unlock_irq(&trace_lock); @@ -448,10 +402,12 @@ static void clear_trace_list(void) } } +#if 0 /* XXX: out of order */ static struct file_operations fops_marker = { .owner = THIS_MODULE, .write = write_marker }; +#endif void enable_mmiotrace(void) { @@ -464,9 +420,9 @@ void enable_mmiotrace(void) #if 0 /* XXX: tracing does not support text entries */ marker_file = debugfs_create_file("marker", 0660, dir, NULL, &fops_marker); -#endif if (!marker_file) pr_err(NAME "marker file creation failed.\n"); +#endif if (nommiotrace) pr_info(NAME "MMIO tracing disabled.\n"); @@ -502,17 +458,3 @@ void disable_mmiotrace(void) out: mutex_unlock(&mmiotrace_mutex); } - -int __init init_mmiotrace(void) -{ - pr_debug(NAME "load...\n"); - if (n_subbufs < 2) - return -EINVAL; - - dir = debugfs_create_dir(APP_DIR, NULL); - if (!dir) { - pr_err(NAME "Couldn't create relay app directory.\n"); - return -ENOMEM; - } - return 0; -} diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 579b3b06..c88a9c1 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -54,73 +54,38 @@ static inline void mmiotrace_iounmap(volatile void __iomem *addr) } #endif /* CONFIG_MMIOTRACE_HOOKS */ -/* in kernel/trace/trace_mmiotrace.c */ -extern int __init init_mmiotrace(void); -extern void enable_mmiotrace(void); -extern void disable_mmiotrace(void); -extern void mmio_trace_record(u32 type, unsigned long addr, unsigned long arg); - -#endif /* __KERNEL__ */ - - -/* - * If you change anything here, you must bump MMIO_VERSION. - * This is the relay data format for user space. - */ -#define MMIO_VERSION 0x04 - -/* mm_io_header.type */ -#define MMIO_OPCODE_MASK 0xff -#define MMIO_OPCODE_SHIFT 0 -#define MMIO_WIDTH_MASK 0xff00 -#define MMIO_WIDTH_SHIFT 8 -#define MMIO_MAGIC (0x6f000000 | (MMIO_VERSION<<16)) -#define MMIO_MAGIC_MASK 0xffff0000 - -enum mm_io_opcode { /* payload type: */ - MMIO_READ = 0x1, /* struct mm_io_rw */ - MMIO_WRITE = 0x2, /* struct mm_io_rw */ - MMIO_PROBE = 0x3, /* struct mm_io_map */ - MMIO_UNPROBE = 0x4, /* struct mm_io_map */ +enum mm_io_opcode { + MMIO_READ = 0x1, /* struct mmiotrace_rw */ + MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ + MMIO_PROBE = 0x3, /* struct mmiotrace_map */ + MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ MMIO_MARKER = 0x5, /* raw char data */ - MMIO_UNKNOWN_OP = 0x6, /* struct mm_io_rw */ + MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */ }; -struct mm_io_header { - __u32 type; /* see MMIO_* macros above */ - __u32 sec; /* timestamp */ - __u32 nsec; - __u32 pid; /* PID of the process, or 0 for kernel core */ - __u16 data_len; /* length of the following payload */ +struct mmiotrace_rw { + unsigned long phys; /* PCI address of register */ + unsigned long value; + unsigned long pc; /* optional program counter */ + int map_id; + unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ + unsigned char width; /* size of register access in bytes */ }; -struct mm_io_rw { - __u64 address; /* virtual address of register */ - __u64 value; - __u64 pc; /* optional program counter */ +struct mmiotrace_map { + unsigned long phys; /* base address in PCI space */ + unsigned long virt; /* base virtual address */ + unsigned long len; /* mapping size */ + int map_id; + unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */ }; -struct mm_io_map { - __u64 phys; /* base address in PCI space */ - __u64 addr; /* base virtual address */ - __u64 len; /* mapping size */ - __u64 pc; /* optional program counter */ -}; - - -/* - * These structures are used to allow a single relay_write() - * call to write a full packet. - */ - -struct mm_io_header_rw { - struct mm_io_header header; - struct mm_io_rw rw; -} __attribute__((packed)); +/* in kernel/trace/trace_mmiotrace.c */ +extern void enable_mmiotrace(void); +extern void disable_mmiotrace(void); +extern void mmio_trace_rw(struct mmiotrace_rw *rw); +extern void mmio_trace_mapping(struct mmiotrace_map *map); -struct mm_io_header_map { - struct mm_io_header header; - struct mm_io_map map; -} __attribute__((packed)); +#endif /* __KERNEL__ */ #endif /* MMIOTRACE_H */ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3271916..d14fe49 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -831,6 +831,40 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, trace_function(tr, data, ip, parent_ip, flags); } +#ifdef CONFIG_MMIOTRACE +void __trace_mmiotrace_rw(struct trace_array *tr, struct trace_array_cpu *data, + struct mmiotrace_rw *rw) +{ + struct trace_entry *entry; + unsigned long irq_flags; + + spin_lock_irqsave(&data->lock, irq_flags); + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, 0); + entry->type = TRACE_MMIO_RW; + entry->mmiorw = *rw; + spin_unlock_irqrestore(&data->lock, irq_flags); + + trace_wake_up(); +} + +void __trace_mmiotrace_map(struct trace_array *tr, struct trace_array_cpu *data, + struct mmiotrace_map *map) +{ + struct trace_entry *entry; + unsigned long irq_flags; + + spin_lock_irqsave(&data->lock, irq_flags); + entry = tracing_get_trace_entry(tr, data); + tracing_generic_entry_update(entry, 0); + entry->type = TRACE_MMIO_MAP; + entry->mmiomap = *map; + spin_unlock_irqrestore(&data->lock, irq_flags); + + trace_wake_up(); +} +#endif + void __trace_stack(struct trace_array *tr, struct trace_array_cpu *data, unsigned long flags, diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c460e85..0ef9ef7 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -5,6 +5,7 @@ #include #include #include +#include enum trace_type { __TRACE_FIRST_TYPE = 0, @@ -14,6 +15,8 @@ enum trace_type { TRACE_WAKE, TRACE_STACK, TRACE_SPECIAL, + TRACE_MMIO_RW, + TRACE_MMIO_MAP, __TRACE_LAST_TYPE }; @@ -75,6 +78,8 @@ struct trace_entry { struct ctx_switch_entry ctx; struct special_entry special; struct stack_entry stack; + struct mmiotrace_rw mmiorw; + struct mmiotrace_map mmiomap; }; }; @@ -255,6 +260,15 @@ extern unsigned long ftrace_update_tot_cnt; extern int DYN_FTRACE_TEST_NAME(void); #endif +#ifdef CONFIG_MMIOTRACE +extern void __trace_mmiotrace_rw(struct trace_array *tr, + struct trace_array_cpu *data, + struct mmiotrace_rw *rw); +extern void __trace_mmiotrace_map(struct trace_array *tr, + struct trace_array_cpu *data, + struct mmiotrace_map *map); +#endif + #ifdef CONFIG_FTRACE_STARTUP_TEST #ifdef CONFIG_FTRACE extern int trace_selftest_startup_function(struct tracer *trace, diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index e4dd03c..3a12b1a 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -11,19 +11,26 @@ #include "trace.h" -extern void -__trace_special(void *__tr, void *__data, - unsigned long arg1, unsigned long arg2, unsigned long arg3); - static struct trace_array *mmio_trace_array; +static void mmio_reset_data(struct trace_array *tr) +{ + int cpu; + + tr->time_start = ftrace_now(tr->cpu); + + for_each_online_cpu(cpu) + tracing_reset(tr->data[cpu]); +} static void mmio_trace_init(struct trace_array *tr) { pr_debug("in %s\n", __func__); mmio_trace_array = tr; - if (tr->ctrl) + if (tr->ctrl) { + mmio_reset_data(tr); enable_mmiotrace(); + } } static void mmio_trace_reset(struct trace_array *tr) @@ -31,15 +38,110 @@ static void mmio_trace_reset(struct trace_array *tr) pr_debug("in %s\n", __func__); if (tr->ctrl) disable_mmiotrace(); + mmio_reset_data(tr); + mmio_trace_array = NULL; } static void mmio_trace_ctrl_update(struct trace_array *tr) { pr_debug("in %s\n", __func__); - if (tr->ctrl) + if (tr->ctrl) { + mmio_reset_data(tr); enable_mmiotrace(); - else + } else { disable_mmiotrace(); + } +} + +/* XXX: This is not called for trace_pipe file! */ +void mmio_print_header(struct trace_iterator *iter) +{ + struct trace_seq *s = &iter->seq; + trace_seq_printf(s, "VERSION broken 20070824\n"); + /* TODO: print /proc/bus/pci/devices contents as PCIDEV lines */ +} + +static int mmio_print_rw(struct trace_iterator *iter) +{ + struct trace_entry *entry = iter->ent; + struct mmiotrace_rw *rw = &entry->mmiorw; + struct trace_seq *s = &iter->seq; + unsigned long long t = ns2usecs(entry->t); + unsigned long usec_rem = do_div(t, 1000000ULL); + unsigned secs = (unsigned long)t; + int ret = 1; + + switch (entry->mmiorw.opcode) { + case MMIO_READ: + ret = trace_seq_printf(s, + "R %d %lu.%06lu %d 0x%lx 0x%lx 0x%lx %d\n", + rw->width, secs, usec_rem, rw->map_id, rw->phys, + rw->value, rw->pc, entry->pid); + break; + case MMIO_WRITE: + ret = trace_seq_printf(s, + "W %d %lu.%06lu %d 0x%lx 0x%lx 0x%lx %d\n", + rw->width, secs, usec_rem, rw->map_id, rw->phys, + rw->value, rw->pc, entry->pid); + break; + case MMIO_UNKNOWN_OP: + ret = trace_seq_printf(s, + "UNKNOWN %lu.%06lu %d 0x%lx %02x,%02x,%02x 0x%lx %d\n", + secs, usec_rem, rw->map_id, rw->phys, + (rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff, + (rw->value >> 0) & 0xff, rw->pc, entry->pid); + break; + default: + ret = trace_seq_printf(s, "rw what?\n"); + break; + } + if (ret) + return 1; + return 0; +} + +static int mmio_print_map(struct trace_iterator *iter) +{ + struct trace_entry *entry = iter->ent; + struct mmiotrace_map *m = &entry->mmiomap; + struct trace_seq *s = &iter->seq; + unsigned long long t = ns2usecs(entry->t); + unsigned long usec_rem = do_div(t, 1000000ULL); + unsigned secs = (unsigned long)t; + int ret = 1; + + switch (entry->mmiorw.opcode) { + case MMIO_PROBE: + ret = trace_seq_printf(s, + "MAP %lu.%06lu %d 0x%lx 0x%lx 0x%lx 0x%lx %d\n", + secs, usec_rem, m->map_id, m->phys, m->virt, m->len, + 0UL, entry->pid); + break; + case MMIO_UNPROBE: + ret = trace_seq_printf(s, + "UNMAP %lu.%06lu %d 0x%lx %d\n", + secs, usec_rem, m->map_id, 0UL, entry->pid); + break; + default: + ret = trace_seq_printf(s, "map what?\n"); + break; + } + if (ret) + return 1; + return 0; +} + +/* return 0 to abort printing without consuming current entry in pipe mode */ +static int mmio_print_line(struct trace_iterator *iter) +{ + switch (iter->ent->type) { + case TRACE_MMIO_RW: + return mmio_print_rw(iter); + case TRACE_MMIO_MAP: + return mmio_print_map(iter); + default: + return 1; /* ignore unknown entries */ + } } static struct tracer mmio_tracer __read_mostly = @@ -47,38 +149,31 @@ static struct tracer mmio_tracer __read_mostly = .name = "mmiotrace", .init = mmio_trace_init, .reset = mmio_trace_reset, + .open = mmio_print_header, .ctrl_update = mmio_trace_ctrl_update, + .print_line = mmio_print_line, }; __init static int init_mmio_trace(void) { - int ret = init_mmiotrace(); - if (ret) - return ret; return register_tracer(&mmio_tracer); } device_initcall(init_mmio_trace); -void mmio_trace_record(u32 type, unsigned long addr, unsigned long arg) +void mmio_trace_rw(struct mmiotrace_rw *rw) { struct trace_array *tr = mmio_trace_array; struct trace_array_cpu *data = tr->data[smp_processor_id()]; + __trace_mmiotrace_rw(tr, data, rw); +} - if (!current || current->pid == 0) { - /* - * XXX: This is a problem. We need to able to record, no - * matter what. tracing_generic_entry_update() would crash. - */ - static unsigned limit; - if (limit++ < 12) - pr_err("Error in %s: no current.\n", __func__); - return; - } - if (!tr || !data) { - static unsigned limit; - if (limit++ < 12) - pr_err("%s: no tr or data\n", __func__); - return; - } - __trace_special(tr, data, type, addr, arg); +void mmio_trace_mapping(struct mmiotrace_map *map) +{ + struct trace_array *tr = mmio_trace_array; + struct trace_array_cpu *data; + + preempt_disable(); + data = tr->data[smp_processor_id()]; + __trace_mmiotrace_map(tr, data, map); + preempt_enable(); } -- cgit v0.10.2 From 138295373ccf7625fcb0218dfea114837983bc39 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:58 +0200 Subject: ftrace: mmiotrace update, #2 another weekend, another patch. This should apply on top of my previous patch from March 23rd. Summary of changes: - Print PCI device list in output header - work around recursive probe hits on SMP - refactor dis/arm_kmmio_fault_page() and add check for page levels - remove un/reference_kmmio(), the die notifier hook is registered permanently into the list - explicitly check for single stepping in die notifier callback I have tested this version on my UP Athlon64 desktop with Nouveau, and SMP Core 2 Duo laptop with the proprietary nvidia driver. Both systems are 64-bit. One previously unknown bug crept into daylight: the ftrace framework's output routines print the first entry last after buffer has wrapped around. The most important regressions compared to non-ftrace mmiotrace at this time are: - failure of trace_pipe file - illegal lines in output file - unaware of losing data due to buffer full Personally I'd like to see these three solved before submitting to mainline. Other issues may come up once we know when we lose events. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index efb4679..cd0d95f 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -5,15 +5,12 @@ * 2008 Pekka Paalanen */ -#include #include #include #include #include #include -#include #include -#include #include #include #include @@ -22,10 +19,9 @@ #include #include #include -#include #include -#include - +#include +#include #include #define KMMIO_PAGE_HASH_BITS 4 @@ -57,14 +53,9 @@ struct kmmio_context { int active; }; -static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, - void *args); - -static DEFINE_MUTEX(kmmio_init_mutex); static DEFINE_SPINLOCK(kmmio_lock); -/* These are protected by kmmio_lock */ -static int kmmio_initialized; +/* Protected by kmmio_lock */ unsigned int kmmio_count; /* Read-protected by RCU, write-protected by kmmio_lock. */ @@ -79,60 +70,6 @@ static struct list_head *kmmio_page_list(unsigned long page) /* Accessed per-cpu */ static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx); -/* protected by kmmio_init_mutex */ -static struct notifier_block nb_die = { - .notifier_call = kmmio_die_notifier -}; - -/** - * Makes sure kmmio is initialized and usable. - * This must be called before any other kmmio function defined here. - * May sleep. - */ -void reference_kmmio(void) -{ - mutex_lock(&kmmio_init_mutex); - spin_lock_irq(&kmmio_lock); - if (!kmmio_initialized) { - int i; - for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) - INIT_LIST_HEAD(&kmmio_page_table[i]); - if (register_die_notifier(&nb_die)) - BUG(); - } - kmmio_initialized++; - spin_unlock_irq(&kmmio_lock); - mutex_unlock(&kmmio_init_mutex); -} -EXPORT_SYMBOL_GPL(reference_kmmio); - -/** - * Clean up kmmio after use. This must be called for every call to - * reference_kmmio(). All probes registered after the corresponding - * reference_kmmio() must have been unregistered when calling this. - * May sleep. - */ -void unreference_kmmio(void) -{ - bool unreg = false; - - mutex_lock(&kmmio_init_mutex); - spin_lock_irq(&kmmio_lock); - - if (kmmio_initialized == 1) { - BUG_ON(is_kmmio_active()); - unreg = true; - } - kmmio_initialized--; - BUG_ON(kmmio_initialized < 0); - spin_unlock_irq(&kmmio_lock); - - if (unreg) - unregister_die_notifier(&nb_die); /* calls sync_rcu() */ - mutex_unlock(&kmmio_init_mutex); -} -EXPORT_SYMBOL(unreference_kmmio); - /* * this is basically a dynamic stabbing problem: * Could use the existing prio tree code or @@ -167,58 +104,56 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) return NULL; } -/** Mark the given page as not present. Access to it will trigger a fault. */ -static void arm_kmmio_fault_page(unsigned long page, int *page_level) +static void set_page_present(unsigned long addr, bool present, int *pglevel) { - unsigned long address = page & PAGE_MASK; + pteval_t pteval; + pmdval_t pmdval; int level; - pte_t *pte = lookup_address(address, &level); + pmd_t *pmd; + pte_t *pte = lookup_address(addr, &level); if (!pte) { - pr_err("kmmio: Error in %s: no pte for page 0x%08lx\n", - __func__, page); + pr_err("kmmio: no pte for page 0x%08lx\n", addr); return; } - if (level == PG_LEVEL_2M) { - pmd_t *pmd = (pmd_t *)pte; - set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_PRESENT)); - } else { - /* PG_LEVEL_4K */ - set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); + if (pglevel) + *pglevel = level; + + switch (level) { + case PG_LEVEL_2M: + 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: + 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; } - if (page_level) - *page_level = level; + __flush_tlb_one(addr); +} - __flush_tlb_one(page); +/** Mark the given page as not present. Access to it will trigger a fault. */ +static void arm_kmmio_fault_page(unsigned long page, int *page_level) +{ + set_page_present(page & PAGE_MASK, false, page_level); } /** Mark the given page as present. */ static void disarm_kmmio_fault_page(unsigned long page, int *page_level) { - unsigned long address = page & PAGE_MASK; - int level; - pte_t *pte = lookup_address(address, &level); - - if (!pte) { - pr_err("kmmio: Error in %s: no pte for page 0x%08lx\n", - __func__, page); - return; - } - - if (level == PG_LEVEL_2M) { - pmd_t *pmd = (pmd_t *)pte; - set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_PRESENT)); - } else { - /* PG_LEVEL_4K */ - set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); - } - - if (page_level) - *page_level = level; - - __flush_tlb_one(page); + set_page_present(page & PAGE_MASK, true, page_level); } /* @@ -240,6 +175,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) { struct kmmio_context *ctx; struct kmmio_fault_page *faultpage; + int ret = 0; /* default to fault not handled */ /* * Preemption is now disabled to prevent process switch during @@ -257,21 +193,35 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) /* * Either this page fault is not caused by kmmio, or * another CPU just pulled the kmmio probe from under - * our feet. In the latter case all hell breaks loose. + * our feet. The latter case should not be possible. */ goto no_kmmio; } ctx = &get_cpu_var(kmmio_ctx); if (ctx->active) { + disarm_kmmio_fault_page(faultpage->page, NULL); + if (addr == ctx->addr) { + /* + * On SMP we sometimes get recursive probe hits on the + * same address. Context is already saved, fall out. + */ + 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. - * If this page fault really was due to kmmio trap, - * all hell breaks loose. + * 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); goto no_kmmio_ctx; } ctx->active++; @@ -302,14 +252,14 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) */ put_cpu_var(kmmio_ctx); - return 1; + return 1; /* fault handled */ no_kmmio_ctx: put_cpu_var(kmmio_ctx); no_kmmio: rcu_read_unlock(); preempt_enable_no_resched(); - return 0; /* page fault not handled by kmmio */ + return ret; } /* @@ -322,8 +272,11 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) int ret = 0; struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); - if (!ctx->active) + if (!ctx->active) { + pr_debug("kmmio: spurious debug trap on CPU %d.\n", + smp_processor_id()); goto out; + } if (ctx->probe && ctx->probe->post_handler) ctx->probe->post_handler(ctx->probe, condition, regs); @@ -525,9 +478,22 @@ static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, { struct die_args *arg = args; - if (val == DIE_DEBUG) + if (val == DIE_DEBUG && (arg->err & DR_STEP)) if (post_kmmio_handler(arg->err, arg->regs) == 1) return NOTIFY_STOP; return NOTIFY_DONE; } + +static struct notifier_block nb_die = { + .notifier_call = kmmio_die_notifier +}; + +static int __init init_kmmio(void) +{ + int i; + for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) + INIT_LIST_HEAD(&kmmio_page_table[i]); + return register_die_notifier(&nb_die); +} +fs_initcall(init_kmmio); /* should be before device_initcall() */ diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index 62abc28..8256546 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c @@ -415,8 +415,6 @@ void enable_mmiotrace(void) if (is_enabled()) goto out; - reference_kmmio(); - #if 0 /* XXX: tracing does not support text entries */ marker_file = debugfs_create_file("marker", 0660, dir, NULL, &fops_marker); @@ -448,7 +446,6 @@ void disable_mmiotrace(void) spin_unlock_irq(&trace_lock); clear_trace_list(); /* guarantees: no more kmmio callbacks */ - unreference_kmmio(); if (marker_file) { debugfs_remove(marker_file); marker_file = NULL; diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index c88a9c1..dd6b64b 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -31,8 +31,6 @@ static inline int is_kmmio_active(void) return kmmio_count; } -extern void reference_kmmio(void); -extern void unreference_kmmio(void); extern int register_kmmio_probe(struct kmmio_probe *p); extern void unregister_kmmio_probe(struct kmmio_probe *p); diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 3a12b1a..361472b 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -8,6 +8,7 @@ #include #include +#include #include "trace.h" @@ -53,12 +54,52 @@ static void mmio_trace_ctrl_update(struct trace_array *tr) } } +static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) +{ + int ret = 0; + int i; + resource_size_t start, end; + const struct pci_driver *drv = pci_dev_driver(dev); + + /* XXX: incomplete checks for trace_seq_printf() return value */ + ret += trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x", + dev->bus->number, dev->devfn, + dev->vendor, dev->device, dev->irq); + /* + * XXX: is pci_resource_to_user() appropriate, since we are + * supposed to interpret the __ioremap() phys_addr argument based on + * these printed values? + */ + for (i = 0; i < 7; i++) { + pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); + ret += trace_seq_printf(s, " %llx", + (unsigned long long)(start | + (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); + } + for (i = 0; i < 7; i++) { + pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); + ret += trace_seq_printf(s, " %llx", + dev->resource[i].start < dev->resource[i].end ? + (unsigned long long)(end - start) + 1 : 0); + } + if (drv) + ret += trace_seq_printf(s, " %s\n", drv->name); + else + ret += trace_seq_printf(s, " \n"); + return ret; +} + /* XXX: This is not called for trace_pipe file! */ -void mmio_print_header(struct trace_iterator *iter) +static void mmio_print_header(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; - trace_seq_printf(s, "VERSION broken 20070824\n"); - /* TODO: print /proc/bus/pci/devices contents as PCIDEV lines */ + struct pci_dev *dev = NULL; + + trace_seq_printf(s, "VERSION 20070824\n"); + + for_each_pci_dev(dev) + mmio_print_pcidev(s, dev); + /* XXX: return value? What if header is very long? */ } static int mmio_print_rw(struct trace_iterator *iter) -- cgit v0.10.2 From 801a175bf601f9a9d5e86e92dee9adeeb6625da8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:58 +0200 Subject: mmiotrace: ftrace fix Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d14fe49..4dcc4e8 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -838,12 +838,16 @@ void __trace_mmiotrace_rw(struct trace_array *tr, struct trace_array_cpu *data, struct trace_entry *entry; unsigned long irq_flags; - spin_lock_irqsave(&data->lock, irq_flags); + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); + entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, 0); entry->type = TRACE_MMIO_RW; entry->mmiorw = *rw; - spin_unlock_irqrestore(&data->lock, irq_flags); + + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); trace_wake_up(); } @@ -854,12 +858,16 @@ void __trace_mmiotrace_map(struct trace_array *tr, struct trace_array_cpu *data, struct trace_entry *entry; unsigned long irq_flags; - spin_lock_irqsave(&data->lock, irq_flags); + raw_local_irq_save(irq_flags); + __raw_spin_lock(&data->lock); + entry = tracing_get_trace_entry(tr, data); tracing_generic_entry_update(entry, 0); entry->type = TRACE_MMIO_MAP; entry->mmiomap = *map; - spin_unlock_irqrestore(&data->lock, irq_flags); + + __raw_spin_unlock(&data->lock); + raw_local_irq_restore(irq_flags); trace_wake_up(); } -- cgit v0.10.2 From 49023168261a7f9a2fd4a1ca1adbfea922556015 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:20:58 +0200 Subject: mmiotrace: cleanup Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index cd0d95f..3ad27b8 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c @@ -228,7 +228,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) ctx->fpage = faultpage; ctx->probe = get_kmmio_probe(addr); - ctx->saved_flags = (regs->flags & (TF_MASK|IF_MASK)); + ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF)); ctx->addr = addr; if (ctx->probe && ctx->probe->pre_handler) @@ -238,8 +238,8 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) * Enable single-stepping and disable interrupts for the faulting * context. Local interrupts must not get enabled during stepping. */ - regs->flags |= TF_MASK; - regs->flags &= ~IF_MASK; + regs->flags |= X86_EFLAGS_TF; + regs->flags &= ~X86_EFLAGS_IF; /* Now we set present bit in PTE and single step. */ disarm_kmmio_fault_page(ctx->fpage->page, NULL); @@ -283,7 +283,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) arm_kmmio_fault_page(ctx->fpage->page, NULL); - regs->flags &= ~TF_MASK; + regs->flags &= ~X86_EFLAGS_TF; regs->flags |= ctx->saved_flags; /* These were acquired in kmmio_handler(). */ @@ -297,7 +297,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) * will have TF set, in which case, continue the remaining processing * of do_debug, as if this is not a probe hit. */ - if (!(regs->flags & TF_MASK)) + if (!(regs->flags & X86_EFLAGS_TF)) ret = 1; out: put_cpu_var(kmmio_ctx); -- cgit v0.10.2 From ff3a3e9ba5e4273a8bc10570adab4a390fb90757 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: x86 mmiotrace: move files into arch/x86/mm/. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a51ac15..739d49a 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -79,8 +79,6 @@ obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_VM86) += vm86_32.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_MMIOTRACE) += mmiotrace/ - obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o diff --git a/arch/x86/kernel/mmiotrace/Makefile b/arch/x86/kernel/mmiotrace/Makefile deleted file mode 100644 index dbcd8d5..0000000 --- a/arch/x86/kernel/mmiotrace/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_MMIOTRACE_HOOKS) += kmmio.o -obj-$(CONFIG_MMIOTRACE) += mmiotrace.o -mmiotrace-y := pf_in.o mmio-mod.o -obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c deleted file mode 100644 index 3ad27b8..0000000 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ /dev/null @@ -1,499 +0,0 @@ -/* Support for MMIO probes. - * Benfit many code from kprobes - * (C) 2002 Louis Zhuang . - * 2007 Alexander Eichner - * 2008 Pekka Paalanen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KMMIO_PAGE_HASH_BITS 4 -#define KMMIO_PAGE_TABLE_SIZE (1 << KMMIO_PAGE_HASH_BITS) - -struct kmmio_fault_page { - struct list_head list; - struct kmmio_fault_page *release_next; - unsigned long page; /* location of the fault page */ - - /* - * 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). - */ - int count; -}; - -struct kmmio_delayed_release { - struct rcu_head rcu; - struct kmmio_fault_page *release_list; -}; - -struct kmmio_context { - struct kmmio_fault_page *fpage; - struct kmmio_probe *probe; - unsigned long saved_flags; - unsigned long addr; - int active; -}; - -static DEFINE_SPINLOCK(kmmio_lock); - -/* Protected by kmmio_lock */ -unsigned int kmmio_count; - -/* Read-protected by RCU, write-protected by kmmio_lock. */ -static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; -static LIST_HEAD(kmmio_probes); - -static struct list_head *kmmio_page_list(unsigned long page) -{ - return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)]; -} - -/* Accessed per-cpu */ -static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx); - -/* - * this is basically a dynamic stabbing problem: - * Could use the existing prio tree code or - * Possible better implementations: - * The Interval Skip List: A Data Structure for Finding All Intervals That - * Overlap a Point (might be simple) - * Space Efficient Dynamic Stabbing with Fast Queries - Mikkel Thorup - */ -/* Get the kmmio at this addr (if any). You must be holding RCU read lock. */ -static struct kmmio_probe *get_kmmio_probe(unsigned long addr) -{ - struct kmmio_probe *p; - list_for_each_entry_rcu(p, &kmmio_probes, list) { - if (addr >= p->addr && addr <= (p->addr + p->len)) - return p; - } - return NULL; -} - -/* You must be holding RCU read lock. */ -static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) -{ - struct list_head *head; - struct kmmio_fault_page *p; - - page &= PAGE_MASK; - head = kmmio_page_list(page); - list_for_each_entry_rcu(p, head, list) { - if (p->page == page) - return p; - } - return NULL; -} - -static void set_page_present(unsigned long addr, bool present, int *pglevel) -{ - pteval_t pteval; - pmdval_t pmdval; - 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; - } - - if (pglevel) - *pglevel = level; - - switch (level) { - case PG_LEVEL_2M: - 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: - 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; - } - - __flush_tlb_one(addr); -} - -/** Mark the given page as not present. Access to it will trigger a fault. */ -static void arm_kmmio_fault_page(unsigned long page, int *page_level) -{ - set_page_present(page & PAGE_MASK, false, page_level); -} - -/** Mark the given page as present. */ -static void disarm_kmmio_fault_page(unsigned long page, int *page_level) -{ - set_page_present(page & PAGE_MASK, true, page_level); -} - -/* - * This is being called from do_page_fault(). - * - * We may be in an interrupt or a critical section. Also prefecthing may - * trigger a page fault. We may be in the middle of process switch. - * We cannot take any locks, because we could be executing especially - * within a kmmio critical section. - * - * Local interrupts are disabled, so preemption cannot happen. - * Do not enable interrupts, do not sleep, and watch out for other CPUs. - */ -/* - * Interrupts are disabled on entry as trap3 is an interrupt gate - * and they remain disabled thorough out this function. - */ -int kmmio_handler(struct pt_regs *regs, unsigned long addr) -{ - struct kmmio_context *ctx; - struct kmmio_fault_page *faultpage; - int ret = 0; /* default to fault not handled */ - - /* - * Preemption is now disabled to prevent process switch during - * single stepping. We can only handle one active kmmio trace - * per cpu, so ensure that we finish it before something else - * gets to run. We also hold the RCU read lock over single - * stepping to avoid looking up the probe and kmmio_fault_page - * again. - */ - preempt_disable(); - rcu_read_lock(); - - faultpage = get_kmmio_fault_page(addr); - if (!faultpage) { - /* - * Either this page fault is not caused by kmmio, or - * another CPU just pulled the kmmio probe from under - * our feet. The latter case should not be possible. - */ - goto no_kmmio; - } - - ctx = &get_cpu_var(kmmio_ctx); - if (ctx->active) { - disarm_kmmio_fault_page(faultpage->page, NULL); - if (addr == ctx->addr) { - /* - * On SMP we sometimes get recursive probe hits on the - * same address. Context is already saved, fall out. - */ - 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); - goto no_kmmio_ctx; - } - ctx->active++; - - ctx->fpage = faultpage; - ctx->probe = get_kmmio_probe(addr); - ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF)); - ctx->addr = addr; - - if (ctx->probe && ctx->probe->pre_handler) - ctx->probe->pre_handler(ctx->probe, regs, addr); - - /* - * Enable single-stepping and disable interrupts for the faulting - * context. Local interrupts must not get enabled during stepping. - */ - regs->flags |= X86_EFLAGS_TF; - regs->flags &= ~X86_EFLAGS_IF; - - /* Now we set present bit in PTE and single step. */ - disarm_kmmio_fault_page(ctx->fpage->page, NULL); - - /* - * If another cpu accesses the same page while we are stepping, - * the access will not be caught. It will simply succeed and the - * only downside is we lose the event. If this becomes a problem, - * the user should drop to single cpu before tracing. - */ - - put_cpu_var(kmmio_ctx); - return 1; /* fault handled */ - -no_kmmio_ctx: - put_cpu_var(kmmio_ctx); -no_kmmio: - rcu_read_unlock(); - preempt_enable_no_resched(); - return ret; -} - -/* - * Interrupts are disabled on entry as trap1 is an interrupt gate - * and they remain disabled thorough out this function. - * This must always get called as the pair to kmmio_handler(). - */ -static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) -{ - int ret = 0; - struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); - - if (!ctx->active) { - pr_debug("kmmio: spurious debug trap on CPU %d.\n", - smp_processor_id()); - goto out; - } - - if (ctx->probe && ctx->probe->post_handler) - ctx->probe->post_handler(ctx->probe, condition, regs); - - arm_kmmio_fault_page(ctx->fpage->page, NULL); - - regs->flags &= ~X86_EFLAGS_TF; - regs->flags |= ctx->saved_flags; - - /* These were acquired in kmmio_handler(). */ - ctx->active--; - BUG_ON(ctx->active); - rcu_read_unlock(); - preempt_enable_no_resched(); - - /* - * if somebody else is singlestepping across a probe point, flags - * will have TF set, in which case, continue the remaining processing - * of do_debug, as if this is not a probe hit. - */ - if (!(regs->flags & X86_EFLAGS_TF)) - ret = 1; -out: - put_cpu_var(kmmio_ctx); - return ret; -} - -/* You must be holding kmmio_lock. */ -static int add_kmmio_fault_page(unsigned long page) -{ - struct kmmio_fault_page *f; - - page &= PAGE_MASK; - f = get_kmmio_fault_page(page); - if (f) { - if (!f->count) - arm_kmmio_fault_page(f->page, NULL); - f->count++; - return 0; - } - - f = kmalloc(sizeof(*f), GFP_ATOMIC); - if (!f) - return -1; - - f->count = 1; - f->page = page; - list_add_rcu(&f->list, kmmio_page_list(f->page)); - - arm_kmmio_fault_page(f->page, NULL); - - return 0; -} - -/* You must be holding kmmio_lock. */ -static void release_kmmio_fault_page(unsigned long page, - struct kmmio_fault_page **release_list) -{ - struct kmmio_fault_page *f; - - page &= PAGE_MASK; - f = get_kmmio_fault_page(page); - if (!f) - return; - - f->count--; - BUG_ON(f->count < 0); - if (!f->count) { - disarm_kmmio_fault_page(f->page, NULL); - f->release_next = *release_list; - *release_list = f; - } -} - -int register_kmmio_probe(struct kmmio_probe *p) -{ - unsigned long flags; - int ret = 0; - unsigned long size = 0; - - spin_lock_irqsave(&kmmio_lock, flags); - if (get_kmmio_probe(p->addr)) { - ret = -EEXIST; - goto out; - } - kmmio_count++; - list_add_rcu(&p->list, &kmmio_probes); - while (size < p->len) { - if (add_kmmio_fault_page(p->addr + size)) - pr_err("kmmio: Unable to set page fault.\n"); - size += PAGE_SIZE; - } -out: - spin_unlock_irqrestore(&kmmio_lock, flags); - /* - * XXX: What should I do here? - * Here was a call to global_flush_tlb(), but it does not exist - * anymore. It seems it's not needed after all. - */ - return ret; -} -EXPORT_SYMBOL(register_kmmio_probe); - -static void rcu_free_kmmio_fault_pages(struct rcu_head *head) -{ - struct kmmio_delayed_release *dr = container_of( - head, - struct kmmio_delayed_release, - rcu); - struct kmmio_fault_page *p = dr->release_list; - while (p) { - struct kmmio_fault_page *next = p->release_next; - BUG_ON(p->count); - kfree(p); - p = next; - } - kfree(dr); -} - -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_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) - list_del_rcu(&p->list); - 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); -} - -/* - * Remove a kmmio probe. You have to synchronize_rcu() before you can be - * sure that the callbacks will not be called anymore. Only after that - * you may actually release your struct kmmio_probe. - * - * Unregistering a kmmio fault page has three steps: - * 1. release_kmmio_fault_page() - * Disarm the page, wait a grace period to let all faults finish. - * 2. remove_kmmio_fault_pages() - * Remove the pages from kmmio_page_table. - * 3. rcu_free_kmmio_fault_pages() - * Actally free the kmmio_fault_page structs as with RCU. - */ -void unregister_kmmio_probe(struct kmmio_probe *p) -{ - unsigned long flags; - unsigned long size = 0; - struct kmmio_fault_page *release_list = NULL; - struct kmmio_delayed_release *drelease; - - spin_lock_irqsave(&kmmio_lock, flags); - while (size < p->len) { - release_kmmio_fault_page(p->addr + size, &release_list); - size += PAGE_SIZE; - } - list_del_rcu(&p->list); - kmmio_count--; - spin_unlock_irqrestore(&kmmio_lock, flags); - - drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); - if (!drelease) { - pr_crit("kmmio: leaking kmmio_fault_page objects.\n"); - return; - } - drelease->release_list = release_list; - - /* - * This is not really RCU here. We have just disarmed a set of - * pages so that they cannot trigger page faults anymore. However, - * we cannot remove the pages from kmmio_page_table, - * because a probe hit might be in flight on another CPU. The - * pages are collected into a list, and they will be removed from - * kmmio_page_table when it is certain that no probe hit related to - * these pages can be in flight. RCU grace period sounds like a - * good choice. - * - * If we removed the pages too early, kmmio page fault handler might - * not find the respective kmmio_fault_page and determine it's not - * a kmmio fault, when it actually is. This would lead to madness. - */ - call_rcu(&drelease->rcu, remove_kmmio_fault_pages); -} -EXPORT_SYMBOL(unregister_kmmio_probe); - -static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, - void *args) -{ - struct die_args *arg = args; - - if (val == DIE_DEBUG && (arg->err & DR_STEP)) - if (post_kmmio_handler(arg->err, arg->regs) == 1) - return NOTIFY_STOP; - - return NOTIFY_DONE; -} - -static struct notifier_block nb_die = { - .notifier_call = kmmio_die_notifier -}; - -static int __init init_kmmio(void) -{ - int i; - for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) - INIT_LIST_HEAD(&kmmio_page_table[i]); - return register_die_notifier(&nb_die); -} -fs_initcall(init_kmmio); /* should be before device_initcall() */ diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c deleted file mode 100644 index 8256546..0000000 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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) IBM Corporation, 2005 - * Jeff Muizelaar, 2006, 2007 - * Pekka Paalanen, 2008 - * - * Derived from the read-mod example from relay-examples by Tom Zanussi. - */ -#define DEBUG 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for ISA_START_ADDRESS */ -#include -#include - -#include "pf_in.h" - -#define NAME "mmiotrace: " - -struct trap_reason { - unsigned long addr; - unsigned long ip; - enum reason_type type; - int active_traces; -}; - -struct remap_trace { - struct list_head list; - struct kmmio_probe probe; - unsigned long phys; - unsigned long id; -}; - -/* Accessed per-cpu. */ -static DEFINE_PER_CPU(struct trap_reason, pf_reason); -static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace); - -#if 0 /* XXX: no way gather this info anymore */ -/* Access to this is not per-cpu. */ -static DEFINE_PER_CPU(atomic_t, dropped); -#endif - -static struct dentry *marker_file; - -static DEFINE_MUTEX(mmiotrace_mutex); -static DEFINE_SPINLOCK(trace_lock); -static atomic_t mmiotrace_enabled; -static LIST_HEAD(trace_list); /* struct remap_trace */ - -/* - * Locking in this file: - * - mmiotrace_mutex enforces enable/disable_mmiotrace() critical sections. - * - mmiotrace_enabled may be modified only when holding mmiotrace_mutex - * and trace_lock. - * - Routines depending on is_enabled() must take trace_lock. - * - trace_list users must hold trace_lock. - * - is_enabled() guarantees that mmio_trace_record is allowed. - * - pre/post callbacks assume the effect of is_enabled() being true. - */ - -/* module parameters */ -static unsigned long filter_offset; -static int nommiotrace; -static int ISA_trace; -static int trace_pc; - -module_param(filter_offset, ulong, 0); -module_param(nommiotrace, bool, 0); -module_param(ISA_trace, bool, 0); -module_param(trace_pc, bool, 0); - -MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); -MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); -MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); -MODULE_PARM_DESC(trace_pc, "Record address of faulting instructions."); - -static bool is_enabled(void) -{ - return atomic_read(&mmiotrace_enabled); -} - -#if 0 /* XXX: needs rewrite */ -/* - * Write callback for the debugfs entry: - * Read a marker and write it to the mmio trace log - */ -static ssize_t write_marker(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - char *event = NULL; - struct mm_io_header *headp; - ssize_t len = (count > 65535) ? 65535 : count; - - event = kzalloc(sizeof(*headp) + len, GFP_KERNEL); - if (!event) - return -ENOMEM; - - headp = (struct mm_io_header *)event; - headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT); - headp->data_len = len; - - if (copy_from_user(event + sizeof(*headp), buffer, len)) { - kfree(event); - return -EFAULT; - } - - spin_lock_irq(&trace_lock); -#if 0 /* XXX: convert this to use tracing */ - if (is_enabled()) - relay_write(chan, event, sizeof(*headp) + len); - else -#endif - len = -EINVAL; - spin_unlock_irq(&trace_lock); - kfree(event); - return len; -} -#endif - -static void print_pte(unsigned long address) -{ - int level; - pte_t *pte = lookup_address(address, &level); - - if (!pte) { - pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", - __func__, address); - return; - } - - if (level == PG_LEVEL_2M) { - pr_emerg(NAME "4MB pages are not currently supported: " - "0x%08lx\n", address); - BUG(); - } - pr_info(NAME "pte for 0x%lx: 0x%lx 0x%lx\n", address, pte_val(*pte), - pte_val(*pte) & _PAGE_PRESENT); -} - -/* - * For some reason the pre/post pairs have been called in an - * unmatched order. Report and die. - */ -static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) -{ - const struct trap_reason *my_reason = &get_cpu_var(pf_reason); - pr_emerg(NAME "unexpected fault for address: 0x%08lx, " - "last fault for address: 0x%08lx\n", - addr, my_reason->addr); - print_pte(addr); - print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); - print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); -#ifdef __i386__ - pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", - regs->ax, regs->bx, regs->cx, regs->dx); - pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", - regs->si, regs->di, regs->bp, regs->sp); -#else - pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", - regs->ax, regs->cx, regs->dx); - pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", - regs->si, regs->di, regs->bp, regs->sp); -#endif - put_cpu_var(pf_reason); - BUG(); -} - -static void pre(struct kmmio_probe *p, struct pt_regs *regs, - unsigned long addr) -{ - struct trap_reason *my_reason = &get_cpu_var(pf_reason); - struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); - const unsigned long instptr = instruction_pointer(regs); - const enum reason_type type = get_ins_type(instptr); - struct remap_trace *trace = p->user_data; - - /* it doesn't make sense to have more than one active trace per cpu */ - if (my_reason->active_traces) - die_kmmio_nesting_error(regs, addr); - else - my_reason->active_traces++; - - my_reason->type = type; - my_reason->addr = addr; - my_reason->ip = instptr; - - my_trace->phys = addr - trace->probe.addr + trace->phys; - my_trace->map_id = trace->id; - - /* - * Only record the program counter when requested. - * It may taint clean-room reverse engineering. - */ - if (trace_pc) - my_trace->pc = instptr; - else - my_trace->pc = 0; - - /* - * XXX: the timestamp recorded will be *after* the tracing has been - * done, not at the time we hit the instruction. SMP implications - * on event ordering? - */ - - switch (type) { - case REG_READ: - my_trace->opcode = MMIO_READ; - my_trace->width = get_ins_mem_width(instptr); - break; - case REG_WRITE: - my_trace->opcode = MMIO_WRITE; - my_trace->width = get_ins_mem_width(instptr); - my_trace->value = get_ins_reg_val(instptr, regs); - break; - case IMM_WRITE: - my_trace->opcode = MMIO_WRITE; - my_trace->width = get_ins_mem_width(instptr); - my_trace->value = get_ins_imm_val(instptr); - break; - default: - { - unsigned char *ip = (unsigned char *)instptr; - my_trace->opcode = MMIO_UNKNOWN_OP; - my_trace->width = 0; - my_trace->value = (*ip) << 16 | *(ip + 1) << 8 | - *(ip + 2); - } - } - put_cpu_var(cpu_trace); - put_cpu_var(pf_reason); -} - -static void post(struct kmmio_probe *p, unsigned long condition, - struct pt_regs *regs) -{ - struct trap_reason *my_reason = &get_cpu_var(pf_reason); - struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); - - /* this should always return the active_trace count to 0 */ - my_reason->active_traces--; - if (my_reason->active_traces) { - pr_emerg(NAME "unexpected post handler"); - BUG(); - } - - switch (my_reason->type) { - case REG_READ: - my_trace->value = get_ins_reg_val(my_reason->ip, regs); - break; - default: - break; - } - - mmio_trace_rw(my_trace); - put_cpu_var(cpu_trace); - put_cpu_var(pf_reason); -} - -static void ioremap_trace_core(unsigned long offset, unsigned long size, - void __iomem *addr) -{ - static atomic_t next_id; - struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); - struct mmiotrace_map map = { - .phys = offset, - .virt = (unsigned long)addr, - .len = size, - .opcode = MMIO_PROBE - }; - - if (!trace) { - pr_err(NAME "kmalloc failed in ioremap\n"); - return; - } - - *trace = (struct remap_trace) { - .probe = { - .addr = (unsigned long)addr, - .len = size, - .pre_handler = pre, - .post_handler = post, - .user_data = trace - }, - .phys = offset, - .id = atomic_inc_return(&next_id) - }; - map.map_id = trace->id; - - spin_lock_irq(&trace_lock); - if (!is_enabled()) - goto not_enabled; - - mmio_trace_mapping(&map); - list_add_tail(&trace->list, &trace_list); - if (!nommiotrace) - register_kmmio_probe(&trace->probe); - -not_enabled: - spin_unlock_irq(&trace_lock); -} - -void -mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) -{ - if (!is_enabled()) /* recheck and proper locking in *_core() */ - return; - - pr_debug(NAME "ioremap_*(0x%lx, 0x%lx) = %p\n", offset, size, addr); - if ((filter_offset) && (offset != filter_offset)) - return; - ioremap_trace_core(offset, size, addr); -} - -static void iounmap_trace_core(volatile void __iomem *addr) -{ - struct mmiotrace_map map = { - .phys = 0, - .virt = (unsigned long)addr, - .len = 0, - .opcode = MMIO_UNPROBE - }; - struct remap_trace *trace; - struct remap_trace *tmp; - struct remap_trace *found_trace = NULL; - - pr_debug(NAME "Unmapping %p.\n", addr); - - spin_lock_irq(&trace_lock); - if (!is_enabled()) - goto not_enabled; - - list_for_each_entry_safe(trace, tmp, &trace_list, list) { - if ((unsigned long)addr == trace->probe.addr) { - if (!nommiotrace) - unregister_kmmio_probe(&trace->probe); - list_del(&trace->list); - found_trace = trace; - break; - } - } - map.map_id = (found_trace) ? found_trace->id : -1; - mmio_trace_mapping(&map); - -not_enabled: - spin_unlock_irq(&trace_lock); - if (found_trace) { - synchronize_rcu(); /* unregister_kmmio_probe() requirement */ - kfree(found_trace); - } -} - -void mmiotrace_iounmap(volatile void __iomem *addr) -{ - might_sleep(); - if (is_enabled()) /* recheck and proper locking in *_core() */ - iounmap_trace_core(addr); -} - -static void clear_trace_list(void) -{ - struct remap_trace *trace; - struct remap_trace *tmp; - - /* - * No locking required, because the caller ensures we are in a - * critical section via mutex, and is_enabled() is false, - * i.e. nothing can traverse or modify this list. - * Caller also ensures is_enabled() cannot change. - */ - list_for_each_entry(trace, &trace_list, list) { - pr_notice(NAME "purging non-iounmapped " - "trace @0x%08lx, size 0x%lx.\n", - trace->probe.addr, trace->probe.len); - if (!nommiotrace) - unregister_kmmio_probe(&trace->probe); - } - synchronize_rcu(); /* unregister_kmmio_probe() requirement */ - - list_for_each_entry_safe(trace, tmp, &trace_list, list) { - list_del(&trace->list); - kfree(trace); - } -} - -#if 0 /* XXX: out of order */ -static struct file_operations fops_marker = { - .owner = THIS_MODULE, - .write = write_marker -}; -#endif - -void enable_mmiotrace(void) -{ - mutex_lock(&mmiotrace_mutex); - if (is_enabled()) - goto out; - -#if 0 /* XXX: tracing does not support text entries */ - marker_file = debugfs_create_file("marker", 0660, dir, NULL, - &fops_marker); - if (!marker_file) - pr_err(NAME "marker file creation failed.\n"); -#endif - - if (nommiotrace) - pr_info(NAME "MMIO tracing disabled.\n"); - if (ISA_trace) - pr_warning(NAME "Warning! low ISA range will be traced.\n"); - spin_lock_irq(&trace_lock); - atomic_inc(&mmiotrace_enabled); - spin_unlock_irq(&trace_lock); - pr_info(NAME "enabled.\n"); -out: - mutex_unlock(&mmiotrace_mutex); -} - -void disable_mmiotrace(void) -{ - mutex_lock(&mmiotrace_mutex); - if (!is_enabled()) - goto out; - - spin_lock_irq(&trace_lock); - atomic_dec(&mmiotrace_enabled); - BUG_ON(is_enabled()); - spin_unlock_irq(&trace_lock); - - clear_trace_list(); /* guarantees: no more kmmio callbacks */ - if (marker_file) { - debugfs_remove(marker_file); - marker_file = NULL; - } - - pr_info(NAME "disabled.\n"); -out: - mutex_unlock(&mmiotrace_mutex); -} diff --git a/arch/x86/kernel/mmiotrace/pf_in.c b/arch/x86/kernel/mmiotrace/pf_in.c deleted file mode 100644 index efa1911..0000000 --- a/arch/x86/kernel/mmiotrace/pf_in.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Fault Injection Test harness (FI) - * Copyright (C) Intel Crop. - * - * 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. - * - */ - -/* Id: pf_in.c,v 1.1.1.1 2002/11/12 05:56:32 brlock Exp - * Copyright by Intel Crop., 2002 - * Louis Zhuang (louis.zhuang@intel.com) - * - * Bjorn Steinbrink (B.Steinbrink@gmx.de), 2007 - */ - -#include -#include /* struct pt_regs */ -#include "pf_in.h" - -#ifdef __i386__ -/* IA32 Manual 3, 2-1 */ -static unsigned char prefix_codes[] = { - 0xF0, 0xF2, 0xF3, 0x2E, 0x36, 0x3E, 0x26, 0x64, - 0x65, 0x2E, 0x3E, 0x66, 0x67 -}; -/* IA32 Manual 3, 3-432*/ -static unsigned int reg_rop[] = { - 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F -}; -static unsigned int reg_wop[] = { 0x88, 0x89 }; -static unsigned int imm_wop[] = { 0xC6, 0xC7 }; -/* IA32 Manual 3, 3-432*/ -static unsigned int rw8[] = { 0x88, 0x8A, 0xC6 }; -static unsigned int rw32[] = { - 0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F -}; -static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F }; -static unsigned int mw16[] = { 0xB70F, 0xBF0F }; -static unsigned int mw32[] = { 0x89, 0x8B, 0xC7 }; -static unsigned int mw64[] = {}; -#else /* not __i386__ */ -static unsigned char prefix_codes[] = { - 0x66, 0x67, 0x2E, 0x3E, 0x26, 0x64, 0x65, 0x36, - 0xF0, 0xF3, 0xF2, - /* REX Prefixes */ - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f -}; -/* AMD64 Manual 3, Appendix A*/ -static unsigned int reg_rop[] = { - 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F -}; -static unsigned int reg_wop[] = { 0x88, 0x89 }; -static unsigned int imm_wop[] = { 0xC6, 0xC7 }; -static unsigned int rw8[] = { 0xC6, 0x88, 0x8A }; -static unsigned int rw32[] = { - 0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F -}; -/* 8 bit only */ -static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F }; -/* 16 bit only */ -static unsigned int mw16[] = { 0xB70F, 0xBF0F }; -/* 16 or 32 bit */ -static unsigned int mw32[] = { 0xC7 }; -/* 16, 32 or 64 bit */ -static unsigned int mw64[] = { 0x89, 0x8B }; -#endif /* not __i386__ */ - -static int skip_prefix(unsigned char *addr, int *shorted, int *enlarged, - int *rexr) -{ - int i; - unsigned char *p = addr; - *shorted = 0; - *enlarged = 0; - *rexr = 0; - -restart: - for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) { - if (*p == prefix_codes[i]) { - if (*p == 0x66) - *shorted = 1; -#ifdef __amd64__ - if ((*p & 0xf8) == 0x48) - *enlarged = 1; - if ((*p & 0xf4) == 0x44) - *rexr = 1; -#endif - p++; - goto restart; - } - } - - return (p - addr); -} - -static int get_opcode(unsigned char *addr, unsigned int *opcode) -{ - int len; - - if (*addr == 0x0F) { - /* 0x0F is extension instruction */ - *opcode = *(unsigned short *)addr; - len = 2; - } else { - *opcode = *addr; - len = 1; - } - - return len; -} - -#define CHECK_OP_TYPE(opcode, array, type) \ - for (i = 0; i < ARRAY_SIZE(array); i++) { \ - if (array[i] == opcode) { \ - rv = type; \ - goto exit; \ - } \ - } - -enum reason_type get_ins_type(unsigned long ins_addr) -{ - unsigned int opcode; - unsigned char *p; - int shorted, enlarged, rexr; - int i; - enum reason_type rv = OTHERS; - - p = (unsigned char *)ins_addr; - p += skip_prefix(p, &shorted, &enlarged, &rexr); - p += get_opcode(p, &opcode); - - CHECK_OP_TYPE(opcode, reg_rop, REG_READ); - CHECK_OP_TYPE(opcode, reg_wop, REG_WRITE); - CHECK_OP_TYPE(opcode, imm_wop, IMM_WRITE); - -exit: - return rv; -} -#undef CHECK_OP_TYPE - -static unsigned int get_ins_reg_width(unsigned long ins_addr) -{ - unsigned int opcode; - unsigned char *p; - int i, shorted, enlarged, rexr; - - p = (unsigned char *)ins_addr; - p += skip_prefix(p, &shorted, &enlarged, &rexr); - p += get_opcode(p, &opcode); - - for (i = 0; i < ARRAY_SIZE(rw8); i++) - if (rw8[i] == opcode) - return 1; - - for (i = 0; i < ARRAY_SIZE(rw32); i++) - if (rw32[i] == opcode) - return (shorted ? 2 : (enlarged ? 8 : 4)); - - printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); - return 0; -} - -unsigned int get_ins_mem_width(unsigned long ins_addr) -{ - unsigned int opcode; - unsigned char *p; - int i, shorted, enlarged, rexr; - - p = (unsigned char *)ins_addr; - p += skip_prefix(p, &shorted, &enlarged, &rexr); - p += get_opcode(p, &opcode); - - for (i = 0; i < ARRAY_SIZE(mw8); i++) - if (mw8[i] == opcode) - return 1; - - for (i = 0; i < ARRAY_SIZE(mw16); i++) - if (mw16[i] == opcode) - return 2; - - for (i = 0; i < ARRAY_SIZE(mw32); i++) - if (mw32[i] == opcode) - return shorted ? 2 : 4; - - for (i = 0; i < ARRAY_SIZE(mw64); i++) - if (mw64[i] == opcode) - return shorted ? 2 : (enlarged ? 8 : 4); - - printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); - return 0; -} - -/* - * Define register ident in mod/rm byte. - * Note: these are NOT the same as in ptrace-abi.h. - */ -enum { - arg_AL = 0, - arg_CL = 1, - arg_DL = 2, - arg_BL = 3, - arg_AH = 4, - arg_CH = 5, - arg_DH = 6, - arg_BH = 7, - - arg_AX = 0, - arg_CX = 1, - arg_DX = 2, - arg_BX = 3, - arg_SP = 4, - arg_BP = 5, - arg_SI = 6, - arg_DI = 7, -#ifdef __amd64__ - arg_R8 = 8, - arg_R9 = 9, - arg_R10 = 10, - arg_R11 = 11, - arg_R12 = 12, - arg_R13 = 13, - arg_R14 = 14, - arg_R15 = 15 -#endif -}; - -static unsigned char *get_reg_w8(int no, struct pt_regs *regs) -{ - unsigned char *rv = NULL; - - switch (no) { - case arg_AL: - rv = (unsigned char *)®s->ax; - break; - case arg_BL: - rv = (unsigned char *)®s->bx; - break; - case arg_CL: - rv = (unsigned char *)®s->cx; - break; - case arg_DL: - rv = (unsigned char *)®s->dx; - break; - case arg_AH: - rv = 1 + (unsigned char *)®s->ax; - break; - case arg_BH: - rv = 1 + (unsigned char *)®s->bx; - break; - case arg_CH: - rv = 1 + (unsigned char *)®s->cx; - break; - case arg_DH: - rv = 1 + (unsigned char *)®s->dx; - break; -#ifdef __amd64__ - case arg_R8: - rv = (unsigned char *)®s->r8; - break; - case arg_R9: - rv = (unsigned char *)®s->r9; - break; - case arg_R10: - rv = (unsigned char *)®s->r10; - break; - case arg_R11: - rv = (unsigned char *)®s->r11; - break; - case arg_R12: - rv = (unsigned char *)®s->r12; - break; - case arg_R13: - rv = (unsigned char *)®s->r13; - break; - case arg_R14: - rv = (unsigned char *)®s->r14; - break; - case arg_R15: - rv = (unsigned char *)®s->r15; - break; -#endif - default: - printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); - break; - } - return rv; -} - -static unsigned long *get_reg_w32(int no, struct pt_regs *regs) -{ - unsigned long *rv = NULL; - - switch (no) { - case arg_AX: - rv = ®s->ax; - break; - case arg_BX: - rv = ®s->bx; - break; - case arg_CX: - rv = ®s->cx; - break; - case arg_DX: - rv = ®s->dx; - break; - case arg_SP: - rv = ®s->sp; - break; - case arg_BP: - rv = ®s->bp; - break; - case arg_SI: - rv = ®s->si; - break; - case arg_DI: - rv = ®s->di; - break; -#ifdef __amd64__ - case arg_R8: - rv = ®s->r8; - break; - case arg_R9: - rv = ®s->r9; - break; - case arg_R10: - rv = ®s->r10; - break; - case arg_R11: - rv = ®s->r11; - break; - case arg_R12: - rv = ®s->r12; - break; - case arg_R13: - rv = ®s->r13; - break; - case arg_R14: - rv = ®s->r14; - break; - case arg_R15: - rv = ®s->r15; - break; -#endif - default: - printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); - } - - return rv; -} - -unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs) -{ - unsigned int opcode; - unsigned char mod_rm; - int reg; - unsigned char *p; - int i, shorted, enlarged, rexr; - unsigned long rv; - - p = (unsigned char *)ins_addr; - p += skip_prefix(p, &shorted, &enlarged, &rexr); - p += get_opcode(p, &opcode); - for (i = 0; i < ARRAY_SIZE(reg_rop); i++) - if (reg_rop[i] == opcode) { - rv = REG_READ; - goto do_work; - } - - for (i = 0; i < ARRAY_SIZE(reg_wop); i++) - if (reg_wop[i] == opcode) { - rv = REG_WRITE; - goto do_work; - } - - printk(KERN_ERR "mmiotrace: Not a register instruction, opcode " - "0x%02x\n", opcode); - goto err; - -do_work: - mod_rm = *p; - reg = ((mod_rm >> 3) & 0x7) | (rexr << 3); - switch (get_ins_reg_width(ins_addr)) { - case 1: - return *get_reg_w8(reg, regs); - - case 2: - return *(unsigned short *)get_reg_w32(reg, regs); - - case 4: - return *(unsigned int *)get_reg_w32(reg, regs); - -#ifdef __amd64__ - case 8: - return *(unsigned long *)get_reg_w32(reg, regs); -#endif - - default: - printk(KERN_ERR "mmiotrace: Error width# %d\n", reg); - } - -err: - return 0; -} - -unsigned long get_ins_imm_val(unsigned long ins_addr) -{ - unsigned int opcode; - unsigned char mod_rm; - unsigned char mod; - unsigned char *p; - int i, shorted, enlarged, rexr; - unsigned long rv; - - p = (unsigned char *)ins_addr; - p += skip_prefix(p, &shorted, &enlarged, &rexr); - p += get_opcode(p, &opcode); - for (i = 0; i < ARRAY_SIZE(imm_wop); i++) - if (imm_wop[i] == opcode) { - rv = IMM_WRITE; - goto do_work; - } - - printk(KERN_ERR "mmiotrace: Not an immediate instruction, opcode " - "0x%02x\n", opcode); - goto err; - -do_work: - mod_rm = *p; - mod = mod_rm >> 6; - p++; - switch (mod) { - case 0: - /* if r/m is 5 we have a 32 disp (IA32 Manual 3, Table 2-2) */ - /* AMD64: XXX Check for address size prefix? */ - if ((mod_rm & 0x7) == 0x5) - p += 4; - break; - - case 1: - p += 1; - break; - - case 2: - p += 4; - break; - - case 3: - default: - printk(KERN_ERR "mmiotrace: not a memory access instruction " - "at 0x%lx, rm_mod=0x%02x\n", - ins_addr, mod_rm); - } - - switch (get_ins_reg_width(ins_addr)) { - case 1: - return *(unsigned char *)p; - - case 2: - return *(unsigned short *)p; - - case 4: - return *(unsigned int *)p; - -#ifdef __amd64__ - case 8: - return *(unsigned long *)p; -#endif - - default: - printk(KERN_ERR "mmiotrace: Error: width.\n"); - } - -err: - return 0; -} diff --git a/arch/x86/kernel/mmiotrace/pf_in.h b/arch/x86/kernel/mmiotrace/pf_in.h deleted file mode 100644 index e05341a..0000000 --- a/arch/x86/kernel/mmiotrace/pf_in.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Fault Injection Test harness (FI) - * Copyright (C) Intel Crop. - * - * 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 __PF_H_ -#define __PF_H_ - -enum reason_type { - NOT_ME, /* page fault is not in regions */ - NOTHING, /* access others point in regions */ - REG_READ, /* read from addr to reg */ - REG_WRITE, /* write from reg to addr */ - IMM_WRITE, /* write from imm to addr */ - OTHERS /* Other instructions can not intercept */ -}; - -enum reason_type get_ins_type(unsigned long ins_addr); -unsigned int get_ins_mem_width(unsigned long ins_addr); -unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs); -unsigned long get_ins_imm_val(unsigned long ins_addr); - -#endif /* __PF_H_ */ diff --git a/arch/x86/kernel/mmiotrace/testmmiotrace.c b/arch/x86/kernel/mmiotrace/testmmiotrace.c deleted file mode 100644 index cfa60b2..0000000 --- a/arch/x86/kernel/mmiotrace/testmmiotrace.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Written by Pekka Paalanen, 2008 - */ -#include -#include - -#define MODULE_NAME "testmmiotrace" - -static unsigned long mmio_address; -module_param(mmio_address, ulong, 0); -MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB."); - -static void do_write_test(void __iomem *p) -{ - unsigned int i; - for (i = 0; i < 256; i++) - iowrite8(i, p + i); - for (i = 1024; i < (5 * 1024); i += 2) - iowrite16(i * 12 + 7, p + i); - for (i = (5 * 1024); i < (16 * 1024); i += 4) - iowrite32(i * 212371 + 13, p + i); -} - -static void do_read_test(void __iomem *p) -{ - unsigned int i; - for (i = 0; i < 256; i++) - ioread8(p + i); - for (i = 1024; i < (5 * 1024); i += 2) - ioread16(p + i); - for (i = (5 * 1024); i < (16 * 1024); i += 4) - ioread32(p + i); -} - -static void do_test(void) -{ - void __iomem *p = ioremap_nocache(mmio_address, 0x4000); - if (!p) { - pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); - return; - } - do_write_test(p); - do_read_test(p); - iounmap(p); -} - -static int __init init(void) -{ - if (mmio_address == 0) { - pr_err(MODULE_NAME ": you have to use the module argument " - "mmio_address.\n"); - pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" - " YOU REALLY KNOW WHAT YOU ARE DOING!\n"); - return -ENXIO; - } - - 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; -} - -static void __exit cleanup(void) -{ - pr_debug(MODULE_NAME ": unloaded.\n"); -} - -module_init(init); -module_exit(cleanup); -MODULE_LICENSE("GPL"); diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index b7b3e4c..07dab50 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -8,6 +8,11 @@ obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o obj-$(CONFIG_HIGHMEM) += highmem_32.o +obj-$(CONFIG_MMIOTRACE_HOOKS) += kmmio.o +obj-$(CONFIG_MMIOTRACE) += mmiotrace.o +mmiotrace-y := pf_in.o mmio-mod.o +obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o + ifeq ($(CONFIG_X86_32),y) obj-$(CONFIG_NUMA) += discontig_32.o else diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c new file mode 100644 index 0000000..3ad27b8 --- /dev/null +++ b/arch/x86/mm/kmmio.c @@ -0,0 +1,499 @@ +/* Support for MMIO probes. + * Benfit many code from kprobes + * (C) 2002 Louis Zhuang . + * 2007 Alexander Eichner + * 2008 Pekka Paalanen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KMMIO_PAGE_HASH_BITS 4 +#define KMMIO_PAGE_TABLE_SIZE (1 << KMMIO_PAGE_HASH_BITS) + +struct kmmio_fault_page { + struct list_head list; + struct kmmio_fault_page *release_next; + unsigned long page; /* location of the fault page */ + + /* + * 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). + */ + int count; +}; + +struct kmmio_delayed_release { + struct rcu_head rcu; + struct kmmio_fault_page *release_list; +}; + +struct kmmio_context { + struct kmmio_fault_page *fpage; + struct kmmio_probe *probe; + unsigned long saved_flags; + unsigned long addr; + int active; +}; + +static DEFINE_SPINLOCK(kmmio_lock); + +/* Protected by kmmio_lock */ +unsigned int kmmio_count; + +/* Read-protected by RCU, write-protected by kmmio_lock. */ +static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; +static LIST_HEAD(kmmio_probes); + +static struct list_head *kmmio_page_list(unsigned long page) +{ + return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)]; +} + +/* Accessed per-cpu */ +static DEFINE_PER_CPU(struct kmmio_context, kmmio_ctx); + +/* + * this is basically a dynamic stabbing problem: + * Could use the existing prio tree code or + * Possible better implementations: + * The Interval Skip List: A Data Structure for Finding All Intervals That + * Overlap a Point (might be simple) + * Space Efficient Dynamic Stabbing with Fast Queries - Mikkel Thorup + */ +/* Get the kmmio at this addr (if any). You must be holding RCU read lock. */ +static struct kmmio_probe *get_kmmio_probe(unsigned long addr) +{ + struct kmmio_probe *p; + list_for_each_entry_rcu(p, &kmmio_probes, list) { + if (addr >= p->addr && addr <= (p->addr + p->len)) + return p; + } + return NULL; +} + +/* You must be holding RCU read lock. */ +static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) +{ + struct list_head *head; + struct kmmio_fault_page *p; + + page &= PAGE_MASK; + head = kmmio_page_list(page); + list_for_each_entry_rcu(p, head, list) { + if (p->page == page) + return p; + } + return NULL; +} + +static void set_page_present(unsigned long addr, bool present, int *pglevel) +{ + pteval_t pteval; + pmdval_t pmdval; + 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; + } + + if (pglevel) + *pglevel = level; + + switch (level) { + case PG_LEVEL_2M: + 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: + 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; + } + + __flush_tlb_one(addr); +} + +/** Mark the given page as not present. Access to it will trigger a fault. */ +static void arm_kmmio_fault_page(unsigned long page, int *page_level) +{ + set_page_present(page & PAGE_MASK, false, page_level); +} + +/** Mark the given page as present. */ +static void disarm_kmmio_fault_page(unsigned long page, int *page_level) +{ + set_page_present(page & PAGE_MASK, true, page_level); +} + +/* + * This is being called from do_page_fault(). + * + * We may be in an interrupt or a critical section. Also prefecthing may + * trigger a page fault. We may be in the middle of process switch. + * We cannot take any locks, because we could be executing especially + * within a kmmio critical section. + * + * Local interrupts are disabled, so preemption cannot happen. + * Do not enable interrupts, do not sleep, and watch out for other CPUs. + */ +/* + * Interrupts are disabled on entry as trap3 is an interrupt gate + * and they remain disabled thorough out this function. + */ +int kmmio_handler(struct pt_regs *regs, unsigned long addr) +{ + struct kmmio_context *ctx; + struct kmmio_fault_page *faultpage; + int ret = 0; /* default to fault not handled */ + + /* + * Preemption is now disabled to prevent process switch during + * single stepping. We can only handle one active kmmio trace + * per cpu, so ensure that we finish it before something else + * gets to run. We also hold the RCU read lock over single + * stepping to avoid looking up the probe and kmmio_fault_page + * again. + */ + preempt_disable(); + rcu_read_lock(); + + faultpage = get_kmmio_fault_page(addr); + if (!faultpage) { + /* + * Either this page fault is not caused by kmmio, or + * another CPU just pulled the kmmio probe from under + * our feet. The latter case should not be possible. + */ + goto no_kmmio; + } + + ctx = &get_cpu_var(kmmio_ctx); + if (ctx->active) { + disarm_kmmio_fault_page(faultpage->page, NULL); + if (addr == ctx->addr) { + /* + * On SMP we sometimes get recursive probe hits on the + * same address. Context is already saved, fall out. + */ + 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); + goto no_kmmio_ctx; + } + ctx->active++; + + ctx->fpage = faultpage; + ctx->probe = get_kmmio_probe(addr); + ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF)); + ctx->addr = addr; + + if (ctx->probe && ctx->probe->pre_handler) + ctx->probe->pre_handler(ctx->probe, regs, addr); + + /* + * Enable single-stepping and disable interrupts for the faulting + * context. Local interrupts must not get enabled during stepping. + */ + regs->flags |= X86_EFLAGS_TF; + regs->flags &= ~X86_EFLAGS_IF; + + /* Now we set present bit in PTE and single step. */ + disarm_kmmio_fault_page(ctx->fpage->page, NULL); + + /* + * If another cpu accesses the same page while we are stepping, + * the access will not be caught. It will simply succeed and the + * only downside is we lose the event. If this becomes a problem, + * the user should drop to single cpu before tracing. + */ + + put_cpu_var(kmmio_ctx); + return 1; /* fault handled */ + +no_kmmio_ctx: + put_cpu_var(kmmio_ctx); +no_kmmio: + rcu_read_unlock(); + preempt_enable_no_resched(); + return ret; +} + +/* + * Interrupts are disabled on entry as trap1 is an interrupt gate + * and they remain disabled thorough out this function. + * This must always get called as the pair to kmmio_handler(). + */ +static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) +{ + int ret = 0; + struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); + + if (!ctx->active) { + pr_debug("kmmio: spurious debug trap on CPU %d.\n", + smp_processor_id()); + goto out; + } + + if (ctx->probe && ctx->probe->post_handler) + ctx->probe->post_handler(ctx->probe, condition, regs); + + arm_kmmio_fault_page(ctx->fpage->page, NULL); + + regs->flags &= ~X86_EFLAGS_TF; + regs->flags |= ctx->saved_flags; + + /* These were acquired in kmmio_handler(). */ + ctx->active--; + BUG_ON(ctx->active); + rcu_read_unlock(); + preempt_enable_no_resched(); + + /* + * if somebody else is singlestepping across a probe point, flags + * will have TF set, in which case, continue the remaining processing + * of do_debug, as if this is not a probe hit. + */ + if (!(regs->flags & X86_EFLAGS_TF)) + ret = 1; +out: + put_cpu_var(kmmio_ctx); + return ret; +} + +/* You must be holding kmmio_lock. */ +static int add_kmmio_fault_page(unsigned long page) +{ + struct kmmio_fault_page *f; + + page &= PAGE_MASK; + f = get_kmmio_fault_page(page); + if (f) { + if (!f->count) + arm_kmmio_fault_page(f->page, NULL); + f->count++; + return 0; + } + + f = kmalloc(sizeof(*f), GFP_ATOMIC); + if (!f) + return -1; + + f->count = 1; + f->page = page; + list_add_rcu(&f->list, kmmio_page_list(f->page)); + + arm_kmmio_fault_page(f->page, NULL); + + return 0; +} + +/* You must be holding kmmio_lock. */ +static void release_kmmio_fault_page(unsigned long page, + struct kmmio_fault_page **release_list) +{ + struct kmmio_fault_page *f; + + page &= PAGE_MASK; + f = get_kmmio_fault_page(page); + if (!f) + return; + + f->count--; + BUG_ON(f->count < 0); + if (!f->count) { + disarm_kmmio_fault_page(f->page, NULL); + f->release_next = *release_list; + *release_list = f; + } +} + +int register_kmmio_probe(struct kmmio_probe *p) +{ + unsigned long flags; + int ret = 0; + unsigned long size = 0; + + spin_lock_irqsave(&kmmio_lock, flags); + if (get_kmmio_probe(p->addr)) { + ret = -EEXIST; + goto out; + } + kmmio_count++; + list_add_rcu(&p->list, &kmmio_probes); + while (size < p->len) { + if (add_kmmio_fault_page(p->addr + size)) + pr_err("kmmio: Unable to set page fault.\n"); + size += PAGE_SIZE; + } +out: + spin_unlock_irqrestore(&kmmio_lock, flags); + /* + * XXX: What should I do here? + * Here was a call to global_flush_tlb(), but it does not exist + * anymore. It seems it's not needed after all. + */ + return ret; +} +EXPORT_SYMBOL(register_kmmio_probe); + +static void rcu_free_kmmio_fault_pages(struct rcu_head *head) +{ + struct kmmio_delayed_release *dr = container_of( + head, + struct kmmio_delayed_release, + rcu); + struct kmmio_fault_page *p = dr->release_list; + while (p) { + struct kmmio_fault_page *next = p->release_next; + BUG_ON(p->count); + kfree(p); + p = next; + } + kfree(dr); +} + +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_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) + list_del_rcu(&p->list); + 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); +} + +/* + * Remove a kmmio probe. You have to synchronize_rcu() before you can be + * sure that the callbacks will not be called anymore. Only after that + * you may actually release your struct kmmio_probe. + * + * Unregistering a kmmio fault page has three steps: + * 1. release_kmmio_fault_page() + * Disarm the page, wait a grace period to let all faults finish. + * 2. remove_kmmio_fault_pages() + * Remove the pages from kmmio_page_table. + * 3. rcu_free_kmmio_fault_pages() + * Actally free the kmmio_fault_page structs as with RCU. + */ +void unregister_kmmio_probe(struct kmmio_probe *p) +{ + unsigned long flags; + unsigned long size = 0; + struct kmmio_fault_page *release_list = NULL; + struct kmmio_delayed_release *drelease; + + spin_lock_irqsave(&kmmio_lock, flags); + while (size < p->len) { + release_kmmio_fault_page(p->addr + size, &release_list); + size += PAGE_SIZE; + } + list_del_rcu(&p->list); + kmmio_count--; + spin_unlock_irqrestore(&kmmio_lock, flags); + + drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); + if (!drelease) { + pr_crit("kmmio: leaking kmmio_fault_page objects.\n"); + return; + } + drelease->release_list = release_list; + + /* + * This is not really RCU here. We have just disarmed a set of + * pages so that they cannot trigger page faults anymore. However, + * we cannot remove the pages from kmmio_page_table, + * because a probe hit might be in flight on another CPU. The + * pages are collected into a list, and they will be removed from + * kmmio_page_table when it is certain that no probe hit related to + * these pages can be in flight. RCU grace period sounds like a + * good choice. + * + * If we removed the pages too early, kmmio page fault handler might + * not find the respective kmmio_fault_page and determine it's not + * a kmmio fault, when it actually is. This would lead to madness. + */ + call_rcu(&drelease->rcu, remove_kmmio_fault_pages); +} +EXPORT_SYMBOL(unregister_kmmio_probe); + +static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val, + void *args) +{ + struct die_args *arg = args; + + if (val == DIE_DEBUG && (arg->err & DR_STEP)) + if (post_kmmio_handler(arg->err, arg->regs) == 1) + return NOTIFY_STOP; + + return NOTIFY_DONE; +} + +static struct notifier_block nb_die = { + .notifier_call = kmmio_die_notifier +}; + +static int __init init_kmmio(void) +{ + int i; + for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) + INIT_LIST_HEAD(&kmmio_page_table[i]); + return register_die_notifier(&nb_die); +} +fs_initcall(init_kmmio); /* should be before device_initcall() */ diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c new file mode 100644 index 0000000..8256546 --- /dev/null +++ b/arch/x86/mm/mmio-mod.c @@ -0,0 +1,457 @@ +/* + * 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) IBM Corporation, 2005 + * Jeff Muizelaar, 2006, 2007 + * Pekka Paalanen, 2008 + * + * Derived from the read-mod example from relay-examples by Tom Zanussi. + */ +#define DEBUG 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for ISA_START_ADDRESS */ +#include +#include + +#include "pf_in.h" + +#define NAME "mmiotrace: " + +struct trap_reason { + unsigned long addr; + unsigned long ip; + enum reason_type type; + int active_traces; +}; + +struct remap_trace { + struct list_head list; + struct kmmio_probe probe; + unsigned long phys; + unsigned long id; +}; + +/* Accessed per-cpu. */ +static DEFINE_PER_CPU(struct trap_reason, pf_reason); +static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace); + +#if 0 /* XXX: no way gather this info anymore */ +/* Access to this is not per-cpu. */ +static DEFINE_PER_CPU(atomic_t, dropped); +#endif + +static struct dentry *marker_file; + +static DEFINE_MUTEX(mmiotrace_mutex); +static DEFINE_SPINLOCK(trace_lock); +static atomic_t mmiotrace_enabled; +static LIST_HEAD(trace_list); /* struct remap_trace */ + +/* + * Locking in this file: + * - mmiotrace_mutex enforces enable/disable_mmiotrace() critical sections. + * - mmiotrace_enabled may be modified only when holding mmiotrace_mutex + * and trace_lock. + * - Routines depending on is_enabled() must take trace_lock. + * - trace_list users must hold trace_lock. + * - is_enabled() guarantees that mmio_trace_record is allowed. + * - pre/post callbacks assume the effect of is_enabled() being true. + */ + +/* module parameters */ +static unsigned long filter_offset; +static int nommiotrace; +static int ISA_trace; +static int trace_pc; + +module_param(filter_offset, ulong, 0); +module_param(nommiotrace, bool, 0); +module_param(ISA_trace, bool, 0); +module_param(trace_pc, bool, 0); + +MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); +MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); +MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); +MODULE_PARM_DESC(trace_pc, "Record address of faulting instructions."); + +static bool is_enabled(void) +{ + return atomic_read(&mmiotrace_enabled); +} + +#if 0 /* XXX: needs rewrite */ +/* + * Write callback for the debugfs entry: + * Read a marker and write it to the mmio trace log + */ +static ssize_t write_marker(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + char *event = NULL; + struct mm_io_header *headp; + ssize_t len = (count > 65535) ? 65535 : count; + + event = kzalloc(sizeof(*headp) + len, GFP_KERNEL); + if (!event) + return -ENOMEM; + + headp = (struct mm_io_header *)event; + headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT); + headp->data_len = len; + + if (copy_from_user(event + sizeof(*headp), buffer, len)) { + kfree(event); + return -EFAULT; + } + + spin_lock_irq(&trace_lock); +#if 0 /* XXX: convert this to use tracing */ + if (is_enabled()) + relay_write(chan, event, sizeof(*headp) + len); + else +#endif + len = -EINVAL; + spin_unlock_irq(&trace_lock); + kfree(event); + return len; +} +#endif + +static void print_pte(unsigned long address) +{ + int level; + pte_t *pte = lookup_address(address, &level); + + if (!pte) { + pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", + __func__, address); + return; + } + + if (level == PG_LEVEL_2M) { + pr_emerg(NAME "4MB pages are not currently supported: " + "0x%08lx\n", address); + BUG(); + } + pr_info(NAME "pte for 0x%lx: 0x%lx 0x%lx\n", address, pte_val(*pte), + pte_val(*pte) & _PAGE_PRESENT); +} + +/* + * For some reason the pre/post pairs have been called in an + * unmatched order. Report and die. + */ +static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) +{ + const struct trap_reason *my_reason = &get_cpu_var(pf_reason); + pr_emerg(NAME "unexpected fault for address: 0x%08lx, " + "last fault for address: 0x%08lx\n", + addr, my_reason->addr); + print_pte(addr); + print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); + print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); +#ifdef __i386__ + pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", + regs->ax, regs->bx, regs->cx, regs->dx); + pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", + regs->si, regs->di, regs->bp, regs->sp); +#else + pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", + regs->ax, regs->cx, regs->dx); + pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", + regs->si, regs->di, regs->bp, regs->sp); +#endif + put_cpu_var(pf_reason); + BUG(); +} + +static void pre(struct kmmio_probe *p, struct pt_regs *regs, + unsigned long addr) +{ + struct trap_reason *my_reason = &get_cpu_var(pf_reason); + struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); + const unsigned long instptr = instruction_pointer(regs); + const enum reason_type type = get_ins_type(instptr); + struct remap_trace *trace = p->user_data; + + /* it doesn't make sense to have more than one active trace per cpu */ + if (my_reason->active_traces) + die_kmmio_nesting_error(regs, addr); + else + my_reason->active_traces++; + + my_reason->type = type; + my_reason->addr = addr; + my_reason->ip = instptr; + + my_trace->phys = addr - trace->probe.addr + trace->phys; + my_trace->map_id = trace->id; + + /* + * Only record the program counter when requested. + * It may taint clean-room reverse engineering. + */ + if (trace_pc) + my_trace->pc = instptr; + else + my_trace->pc = 0; + + /* + * XXX: the timestamp recorded will be *after* the tracing has been + * done, not at the time we hit the instruction. SMP implications + * on event ordering? + */ + + switch (type) { + case REG_READ: + my_trace->opcode = MMIO_READ; + my_trace->width = get_ins_mem_width(instptr); + break; + case REG_WRITE: + my_trace->opcode = MMIO_WRITE; + my_trace->width = get_ins_mem_width(instptr); + my_trace->value = get_ins_reg_val(instptr, regs); + break; + case IMM_WRITE: + my_trace->opcode = MMIO_WRITE; + my_trace->width = get_ins_mem_width(instptr); + my_trace->value = get_ins_imm_val(instptr); + break; + default: + { + unsigned char *ip = (unsigned char *)instptr; + my_trace->opcode = MMIO_UNKNOWN_OP; + my_trace->width = 0; + my_trace->value = (*ip) << 16 | *(ip + 1) << 8 | + *(ip + 2); + } + } + put_cpu_var(cpu_trace); + put_cpu_var(pf_reason); +} + +static void post(struct kmmio_probe *p, unsigned long condition, + struct pt_regs *regs) +{ + struct trap_reason *my_reason = &get_cpu_var(pf_reason); + struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); + + /* this should always return the active_trace count to 0 */ + my_reason->active_traces--; + if (my_reason->active_traces) { + pr_emerg(NAME "unexpected post handler"); + BUG(); + } + + switch (my_reason->type) { + case REG_READ: + my_trace->value = get_ins_reg_val(my_reason->ip, regs); + break; + default: + break; + } + + mmio_trace_rw(my_trace); + put_cpu_var(cpu_trace); + put_cpu_var(pf_reason); +} + +static void ioremap_trace_core(unsigned long offset, unsigned long size, + void __iomem *addr) +{ + static atomic_t next_id; + struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); + struct mmiotrace_map map = { + .phys = offset, + .virt = (unsigned long)addr, + .len = size, + .opcode = MMIO_PROBE + }; + + if (!trace) { + pr_err(NAME "kmalloc failed in ioremap\n"); + return; + } + + *trace = (struct remap_trace) { + .probe = { + .addr = (unsigned long)addr, + .len = size, + .pre_handler = pre, + .post_handler = post, + .user_data = trace + }, + .phys = offset, + .id = atomic_inc_return(&next_id) + }; + map.map_id = trace->id; + + spin_lock_irq(&trace_lock); + if (!is_enabled()) + goto not_enabled; + + mmio_trace_mapping(&map); + list_add_tail(&trace->list, &trace_list); + if (!nommiotrace) + register_kmmio_probe(&trace->probe); + +not_enabled: + spin_unlock_irq(&trace_lock); +} + +void +mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) +{ + if (!is_enabled()) /* recheck and proper locking in *_core() */ + return; + + pr_debug(NAME "ioremap_*(0x%lx, 0x%lx) = %p\n", offset, size, addr); + if ((filter_offset) && (offset != filter_offset)) + return; + ioremap_trace_core(offset, size, addr); +} + +static void iounmap_trace_core(volatile void __iomem *addr) +{ + struct mmiotrace_map map = { + .phys = 0, + .virt = (unsigned long)addr, + .len = 0, + .opcode = MMIO_UNPROBE + }; + struct remap_trace *trace; + struct remap_trace *tmp; + struct remap_trace *found_trace = NULL; + + pr_debug(NAME "Unmapping %p.\n", addr); + + spin_lock_irq(&trace_lock); + if (!is_enabled()) + goto not_enabled; + + list_for_each_entry_safe(trace, tmp, &trace_list, list) { + if ((unsigned long)addr == trace->probe.addr) { + if (!nommiotrace) + unregister_kmmio_probe(&trace->probe); + list_del(&trace->list); + found_trace = trace; + break; + } + } + map.map_id = (found_trace) ? found_trace->id : -1; + mmio_trace_mapping(&map); + +not_enabled: + spin_unlock_irq(&trace_lock); + if (found_trace) { + synchronize_rcu(); /* unregister_kmmio_probe() requirement */ + kfree(found_trace); + } +} + +void mmiotrace_iounmap(volatile void __iomem *addr) +{ + might_sleep(); + if (is_enabled()) /* recheck and proper locking in *_core() */ + iounmap_trace_core(addr); +} + +static void clear_trace_list(void) +{ + struct remap_trace *trace; + struct remap_trace *tmp; + + /* + * No locking required, because the caller ensures we are in a + * critical section via mutex, and is_enabled() is false, + * i.e. nothing can traverse or modify this list. + * Caller also ensures is_enabled() cannot change. + */ + list_for_each_entry(trace, &trace_list, list) { + pr_notice(NAME "purging non-iounmapped " + "trace @0x%08lx, size 0x%lx.\n", + trace->probe.addr, trace->probe.len); + if (!nommiotrace) + unregister_kmmio_probe(&trace->probe); + } + synchronize_rcu(); /* unregister_kmmio_probe() requirement */ + + list_for_each_entry_safe(trace, tmp, &trace_list, list) { + list_del(&trace->list); + kfree(trace); + } +} + +#if 0 /* XXX: out of order */ +static struct file_operations fops_marker = { + .owner = THIS_MODULE, + .write = write_marker +}; +#endif + +void enable_mmiotrace(void) +{ + mutex_lock(&mmiotrace_mutex); + if (is_enabled()) + goto out; + +#if 0 /* XXX: tracing does not support text entries */ + marker_file = debugfs_create_file("marker", 0660, dir, NULL, + &fops_marker); + if (!marker_file) + pr_err(NAME "marker file creation failed.\n"); +#endif + + if (nommiotrace) + pr_info(NAME "MMIO tracing disabled.\n"); + if (ISA_trace) + pr_warning(NAME "Warning! low ISA range will be traced.\n"); + spin_lock_irq(&trace_lock); + atomic_inc(&mmiotrace_enabled); + spin_unlock_irq(&trace_lock); + pr_info(NAME "enabled.\n"); +out: + mutex_unlock(&mmiotrace_mutex); +} + +void disable_mmiotrace(void) +{ + mutex_lock(&mmiotrace_mutex); + if (!is_enabled()) + goto out; + + spin_lock_irq(&trace_lock); + atomic_dec(&mmiotrace_enabled); + BUG_ON(is_enabled()); + spin_unlock_irq(&trace_lock); + + clear_trace_list(); /* guarantees: no more kmmio callbacks */ + if (marker_file) { + debugfs_remove(marker_file); + marker_file = NULL; + } + + pr_info(NAME "disabled.\n"); +out: + mutex_unlock(&mmiotrace_mutex); +} diff --git a/arch/x86/mm/pf_in.c b/arch/x86/mm/pf_in.c new file mode 100644 index 0000000..efa1911 --- /dev/null +++ b/arch/x86/mm/pf_in.c @@ -0,0 +1,489 @@ +/* + * Fault Injection Test harness (FI) + * Copyright (C) Intel Crop. + * + * 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. + * + */ + +/* Id: pf_in.c,v 1.1.1.1 2002/11/12 05:56:32 brlock Exp + * Copyright by Intel Crop., 2002 + * Louis Zhuang (louis.zhuang@intel.com) + * + * Bjorn Steinbrink (B.Steinbrink@gmx.de), 2007 + */ + +#include +#include /* struct pt_regs */ +#include "pf_in.h" + +#ifdef __i386__ +/* IA32 Manual 3, 2-1 */ +static unsigned char prefix_codes[] = { + 0xF0, 0xF2, 0xF3, 0x2E, 0x36, 0x3E, 0x26, 0x64, + 0x65, 0x2E, 0x3E, 0x66, 0x67 +}; +/* IA32 Manual 3, 3-432*/ +static unsigned int reg_rop[] = { + 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +static unsigned int reg_wop[] = { 0x88, 0x89 }; +static unsigned int imm_wop[] = { 0xC6, 0xC7 }; +/* IA32 Manual 3, 3-432*/ +static unsigned int rw8[] = { 0x88, 0x8A, 0xC6 }; +static unsigned int rw32[] = { + 0x89, 0x8B, 0xC7, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +static unsigned int mw8[] = { 0x88, 0x8A, 0xC6, 0xB60F, 0xBE0F }; +static unsigned int mw16[] = { 0xB70F, 0xBF0F }; +static unsigned int mw32[] = { 0x89, 0x8B, 0xC7 }; +static unsigned int mw64[] = {}; +#else /* not __i386__ */ +static unsigned char prefix_codes[] = { + 0x66, 0x67, 0x2E, 0x3E, 0x26, 0x64, 0x65, 0x36, + 0xF0, 0xF3, 0xF2, + /* REX Prefixes */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; +/* AMD64 Manual 3, Appendix A*/ +static unsigned int reg_rop[] = { + 0x8A, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +static unsigned int reg_wop[] = { 0x88, 0x89 }; +static unsigned int imm_wop[] = { 0xC6, 0xC7 }; +static unsigned int rw8[] = { 0xC6, 0x88, 0x8A }; +static unsigned int rw32[] = { + 0xC7, 0x89, 0x8B, 0xB60F, 0xB70F, 0xBE0F, 0xBF0F +}; +/* 8 bit only */ +static unsigned int mw8[] = { 0xC6, 0x88, 0x8A, 0xB60F, 0xBE0F }; +/* 16 bit only */ +static unsigned int mw16[] = { 0xB70F, 0xBF0F }; +/* 16 or 32 bit */ +static unsigned int mw32[] = { 0xC7 }; +/* 16, 32 or 64 bit */ +static unsigned int mw64[] = { 0x89, 0x8B }; +#endif /* not __i386__ */ + +static int skip_prefix(unsigned char *addr, int *shorted, int *enlarged, + int *rexr) +{ + int i; + unsigned char *p = addr; + *shorted = 0; + *enlarged = 0; + *rexr = 0; + +restart: + for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) { + if (*p == prefix_codes[i]) { + if (*p == 0x66) + *shorted = 1; +#ifdef __amd64__ + if ((*p & 0xf8) == 0x48) + *enlarged = 1; + if ((*p & 0xf4) == 0x44) + *rexr = 1; +#endif + p++; + goto restart; + } + } + + return (p - addr); +} + +static int get_opcode(unsigned char *addr, unsigned int *opcode) +{ + int len; + + if (*addr == 0x0F) { + /* 0x0F is extension instruction */ + *opcode = *(unsigned short *)addr; + len = 2; + } else { + *opcode = *addr; + len = 1; + } + + return len; +} + +#define CHECK_OP_TYPE(opcode, array, type) \ + for (i = 0; i < ARRAY_SIZE(array); i++) { \ + if (array[i] == opcode) { \ + rv = type; \ + goto exit; \ + } \ + } + +enum reason_type get_ins_type(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char *p; + int shorted, enlarged, rexr; + int i; + enum reason_type rv = OTHERS; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + + CHECK_OP_TYPE(opcode, reg_rop, REG_READ); + CHECK_OP_TYPE(opcode, reg_wop, REG_WRITE); + CHECK_OP_TYPE(opcode, imm_wop, IMM_WRITE); + +exit: + return rv; +} +#undef CHECK_OP_TYPE + +static unsigned int get_ins_reg_width(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char *p; + int i, shorted, enlarged, rexr; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + + for (i = 0; i < ARRAY_SIZE(rw8); i++) + if (rw8[i] == opcode) + return 1; + + for (i = 0; i < ARRAY_SIZE(rw32); i++) + if (rw32[i] == opcode) + return (shorted ? 2 : (enlarged ? 8 : 4)); + + printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); + return 0; +} + +unsigned int get_ins_mem_width(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char *p; + int i, shorted, enlarged, rexr; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + + for (i = 0; i < ARRAY_SIZE(mw8); i++) + if (mw8[i] == opcode) + return 1; + + for (i = 0; i < ARRAY_SIZE(mw16); i++) + if (mw16[i] == opcode) + return 2; + + for (i = 0; i < ARRAY_SIZE(mw32); i++) + if (mw32[i] == opcode) + return shorted ? 2 : 4; + + for (i = 0; i < ARRAY_SIZE(mw64); i++) + if (mw64[i] == opcode) + return shorted ? 2 : (enlarged ? 8 : 4); + + printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); + return 0; +} + +/* + * Define register ident in mod/rm byte. + * Note: these are NOT the same as in ptrace-abi.h. + */ +enum { + arg_AL = 0, + arg_CL = 1, + arg_DL = 2, + arg_BL = 3, + arg_AH = 4, + arg_CH = 5, + arg_DH = 6, + arg_BH = 7, + + arg_AX = 0, + arg_CX = 1, + arg_DX = 2, + arg_BX = 3, + arg_SP = 4, + arg_BP = 5, + arg_SI = 6, + arg_DI = 7, +#ifdef __amd64__ + arg_R8 = 8, + arg_R9 = 9, + arg_R10 = 10, + arg_R11 = 11, + arg_R12 = 12, + arg_R13 = 13, + arg_R14 = 14, + arg_R15 = 15 +#endif +}; + +static unsigned char *get_reg_w8(int no, struct pt_regs *regs) +{ + unsigned char *rv = NULL; + + switch (no) { + case arg_AL: + rv = (unsigned char *)®s->ax; + break; + case arg_BL: + rv = (unsigned char *)®s->bx; + break; + case arg_CL: + rv = (unsigned char *)®s->cx; + break; + case arg_DL: + rv = (unsigned char *)®s->dx; + break; + case arg_AH: + rv = 1 + (unsigned char *)®s->ax; + break; + case arg_BH: + rv = 1 + (unsigned char *)®s->bx; + break; + case arg_CH: + rv = 1 + (unsigned char *)®s->cx; + break; + case arg_DH: + rv = 1 + (unsigned char *)®s->dx; + break; +#ifdef __amd64__ + case arg_R8: + rv = (unsigned char *)®s->r8; + break; + case arg_R9: + rv = (unsigned char *)®s->r9; + break; + case arg_R10: + rv = (unsigned char *)®s->r10; + break; + case arg_R11: + rv = (unsigned char *)®s->r11; + break; + case arg_R12: + rv = (unsigned char *)®s->r12; + break; + case arg_R13: + rv = (unsigned char *)®s->r13; + break; + case arg_R14: + rv = (unsigned char *)®s->r14; + break; + case arg_R15: + rv = (unsigned char *)®s->r15; + break; +#endif + default: + printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); + break; + } + return rv; +} + +static unsigned long *get_reg_w32(int no, struct pt_regs *regs) +{ + unsigned long *rv = NULL; + + switch (no) { + case arg_AX: + rv = ®s->ax; + break; + case arg_BX: + rv = ®s->bx; + break; + case arg_CX: + rv = ®s->cx; + break; + case arg_DX: + rv = ®s->dx; + break; + case arg_SP: + rv = ®s->sp; + break; + case arg_BP: + rv = ®s->bp; + break; + case arg_SI: + rv = ®s->si; + break; + case arg_DI: + rv = ®s->di; + break; +#ifdef __amd64__ + case arg_R8: + rv = ®s->r8; + break; + case arg_R9: + rv = ®s->r9; + break; + case arg_R10: + rv = ®s->r10; + break; + case arg_R11: + rv = ®s->r11; + break; + case arg_R12: + rv = ®s->r12; + break; + case arg_R13: + rv = ®s->r13; + break; + case arg_R14: + rv = ®s->r14; + break; + case arg_R15: + rv = ®s->r15; + break; +#endif + default: + printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no); + } + + return rv; +} + +unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs) +{ + unsigned int opcode; + unsigned char mod_rm; + int reg; + unsigned char *p; + int i, shorted, enlarged, rexr; + unsigned long rv; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + for (i = 0; i < ARRAY_SIZE(reg_rop); i++) + if (reg_rop[i] == opcode) { + rv = REG_READ; + goto do_work; + } + + for (i = 0; i < ARRAY_SIZE(reg_wop); i++) + if (reg_wop[i] == opcode) { + rv = REG_WRITE; + goto do_work; + } + + printk(KERN_ERR "mmiotrace: Not a register instruction, opcode " + "0x%02x\n", opcode); + goto err; + +do_work: + mod_rm = *p; + reg = ((mod_rm >> 3) & 0x7) | (rexr << 3); + switch (get_ins_reg_width(ins_addr)) { + case 1: + return *get_reg_w8(reg, regs); + + case 2: + return *(unsigned short *)get_reg_w32(reg, regs); + + case 4: + return *(unsigned int *)get_reg_w32(reg, regs); + +#ifdef __amd64__ + case 8: + return *(unsigned long *)get_reg_w32(reg, regs); +#endif + + default: + printk(KERN_ERR "mmiotrace: Error width# %d\n", reg); + } + +err: + return 0; +} + +unsigned long get_ins_imm_val(unsigned long ins_addr) +{ + unsigned int opcode; + unsigned char mod_rm; + unsigned char mod; + unsigned char *p; + int i, shorted, enlarged, rexr; + unsigned long rv; + + p = (unsigned char *)ins_addr; + p += skip_prefix(p, &shorted, &enlarged, &rexr); + p += get_opcode(p, &opcode); + for (i = 0; i < ARRAY_SIZE(imm_wop); i++) + if (imm_wop[i] == opcode) { + rv = IMM_WRITE; + goto do_work; + } + + printk(KERN_ERR "mmiotrace: Not an immediate instruction, opcode " + "0x%02x\n", opcode); + goto err; + +do_work: + mod_rm = *p; + mod = mod_rm >> 6; + p++; + switch (mod) { + case 0: + /* if r/m is 5 we have a 32 disp (IA32 Manual 3, Table 2-2) */ + /* AMD64: XXX Check for address size prefix? */ + if ((mod_rm & 0x7) == 0x5) + p += 4; + break; + + case 1: + p += 1; + break; + + case 2: + p += 4; + break; + + case 3: + default: + printk(KERN_ERR "mmiotrace: not a memory access instruction " + "at 0x%lx, rm_mod=0x%02x\n", + ins_addr, mod_rm); + } + + switch (get_ins_reg_width(ins_addr)) { + case 1: + return *(unsigned char *)p; + + case 2: + return *(unsigned short *)p; + + case 4: + return *(unsigned int *)p; + +#ifdef __amd64__ + case 8: + return *(unsigned long *)p; +#endif + + default: + printk(KERN_ERR "mmiotrace: Error: width.\n"); + } + +err: + return 0; +} diff --git a/arch/x86/mm/pf_in.h b/arch/x86/mm/pf_in.h new file mode 100644 index 0000000..e05341a --- /dev/null +++ b/arch/x86/mm/pf_in.h @@ -0,0 +1,39 @@ +/* + * Fault Injection Test harness (FI) + * Copyright (C) Intel Crop. + * + * 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 __PF_H_ +#define __PF_H_ + +enum reason_type { + NOT_ME, /* page fault is not in regions */ + NOTHING, /* access others point in regions */ + REG_READ, /* read from addr to reg */ + REG_WRITE, /* write from reg to addr */ + IMM_WRITE, /* write from imm to addr */ + OTHERS /* Other instructions can not intercept */ +}; + +enum reason_type get_ins_type(unsigned long ins_addr); +unsigned int get_ins_mem_width(unsigned long ins_addr); +unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs); +unsigned long get_ins_imm_val(unsigned long ins_addr); + +#endif /* __PF_H_ */ diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c new file mode 100644 index 0000000..cfa60b2 --- /dev/null +++ b/arch/x86/mm/testmmiotrace.c @@ -0,0 +1,71 @@ +/* + * Written by Pekka Paalanen, 2008 + */ +#include +#include + +#define MODULE_NAME "testmmiotrace" + +static unsigned long mmio_address; +module_param(mmio_address, ulong, 0); +MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB."); + +static void do_write_test(void __iomem *p) +{ + unsigned int i; + for (i = 0; i < 256; i++) + iowrite8(i, p + i); + for (i = 1024; i < (5 * 1024); i += 2) + iowrite16(i * 12 + 7, p + i); + for (i = (5 * 1024); i < (16 * 1024); i += 4) + iowrite32(i * 212371 + 13, p + i); +} + +static void do_read_test(void __iomem *p) +{ + unsigned int i; + for (i = 0; i < 256; i++) + ioread8(p + i); + for (i = 1024; i < (5 * 1024); i += 2) + ioread16(p + i); + for (i = (5 * 1024); i < (16 * 1024); i += 4) + ioread32(p + i); +} + +static void do_test(void) +{ + void __iomem *p = ioremap_nocache(mmio_address, 0x4000); + if (!p) { + pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); + return; + } + do_write_test(p); + do_read_test(p); + iounmap(p); +} + +static int __init init(void) +{ + if (mmio_address == 0) { + pr_err(MODULE_NAME ": you have to use the module argument " + "mmio_address.\n"); + pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS" + " YOU REALLY KNOW WHAT YOU ARE DOING!\n"); + return -ENXIO; + } + + 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; +} + +static void __exit cleanup(void) +{ + pr_debug(MODULE_NAME ": unloaded.\n"); +} + +module_init(init); +module_exit(cleanup); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From e4b37ee68609037ffcaa2fcfae47cd31a605bb9e Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: x86 mmiotrace: remove ISA_trace parameter. This had become a no-op. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 8256546..ab2bb77 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -81,17 +81,14 @@ static LIST_HEAD(trace_list); /* struct remap_trace */ /* module parameters */ static unsigned long filter_offset; static int nommiotrace; -static int ISA_trace; static int trace_pc; module_param(filter_offset, ulong, 0); module_param(nommiotrace, bool, 0); -module_param(ISA_trace, bool, 0); module_param(trace_pc, bool, 0); MODULE_PARM_DESC(filter_offset, "Start address of traced mappings."); MODULE_PARM_DESC(nommiotrace, "Disable actual MMIO tracing."); -MODULE_PARM_DESC(ISA_trace, "Do not exclude the low ISA range."); MODULE_PARM_DESC(trace_pc, "Record address of faulting instructions."); static bool is_enabled(void) @@ -424,8 +421,6 @@ void enable_mmiotrace(void) if (nommiotrace) pr_info(NAME "MMIO tracing disabled.\n"); - if (ISA_trace) - pr_warning(NAME "Warning! low ISA range will be traced.\n"); spin_lock_irq(&trace_lock); atomic_inc(&mmiotrace_enabled); spin_unlock_irq(&trace_lock); -- cgit v0.10.2 From 736ca61fa81874b3fee205a593251b1869d0bcf1 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: x86 mmiotrace: Do not print bogus pid Non-zero pid indicates the MMIO access originated in user space. We do not catch that kind of accesses yet, so always print zero for now. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 361472b..79be4a1 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -117,20 +117,20 @@ static int mmio_print_rw(struct trace_iterator *iter) ret = trace_seq_printf(s, "R %d %lu.%06lu %d 0x%lx 0x%lx 0x%lx %d\n", rw->width, secs, usec_rem, rw->map_id, rw->phys, - rw->value, rw->pc, entry->pid); + rw->value, rw->pc, 0); break; case MMIO_WRITE: ret = trace_seq_printf(s, "W %d %lu.%06lu %d 0x%lx 0x%lx 0x%lx %d\n", rw->width, secs, usec_rem, rw->map_id, rw->phys, - rw->value, rw->pc, entry->pid); + rw->value, rw->pc, 0); break; case MMIO_UNKNOWN_OP: ret = trace_seq_printf(s, "UNKNOWN %lu.%06lu %d 0x%lx %02x,%02x,%02x 0x%lx %d\n", secs, usec_rem, rw->map_id, rw->phys, (rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff, - (rw->value >> 0) & 0xff, rw->pc, entry->pid); + (rw->value >> 0) & 0xff, rw->pc, 0); break; default: ret = trace_seq_printf(s, "rw what?\n"); -- cgit v0.10.2 From c6c67c1afcce71335b18ed8769b1165c468bfb03 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:20:59 +0200 Subject: mmiotrace: add user documentation Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/tracers/mmiotrace.txt new file mode 100644 index 0000000..84246f7 --- /dev/null +++ b/Documentation/tracers/mmiotrace.txt @@ -0,0 +1,153 @@ + In-kernel memory-mapped I/O tracing + + +Home page and links to optional user space tools: + + http://nouveau.freedesktop.org/wiki/MmioTrace + +MMIO tracing was originally developed by Intel around 2003 for their Fault +Injection Test Harness. In Dec 2006 - Jan 2007, using the code from Intel, +Jeff Muizelaar created a tool for tracing MMIO accesses with the Nouveau +project in mind. Since then many people have contributed. + +Mmiotrace was built for reverse engineering any memory-mapped IO device with +the Nouveau project as the first real user. Only x86 and x86_64 architectures +are supported. + +Out-of-tree mmiotrace was originally modified for mainline inclusion and +ftrace framework by Pekka Paalanen . + + +Preparation +----------- + +Mmiotrace feature is compiled in by the CONFIG_MMIOTRACE option. Tracing is +disabled by default, so it is safe to have this set to yes. SMP systems are +supported, but tracing is unreliable and may miss events if more than one CPU +is on-line, therefore mmiotrace takes all but one CPU off-line during run-time +activation [not implemented]. + + +Usage Quick Reference +--------------------- + +$ mount -t debugfs debugfs /debug +$ echo mmiotrace > /debug/tracing/current_tracer +$ cat /debug/tracing/trace_pipe > mydump.txt & +Start X or whatever. +$ echo "X is up" > /debug/tracing/marker +$ echo none > /debug/tracing/current_tracer +Check kernel log. + + +Usage +----- + +Make sure debugfs is mounted to /debug. If not, (requires root privileges) +$ mount -t debugfs debugfs /debug + +Check that the driver you are about to trace is not loaded. + +Activate mmiotrace (requires root privileges): +$ echo mmiotrace > /debug/tracing/current_tracer + +Start storing the trace: +$ cat /debug/tracing/trace_pipe > mydump.txt & +The 'cat' process should stay running (sleeping) in the background. + +Load the driver you want to trace and use it. Mmiotrace will only catch MMIO +accesses to areas that are ioremapped while mmiotrace is active. + +[Unimplemented feature:] +During tracing you can place comments (markers) into the trace by +$ echo "X is up" > /debug/tracing/marker +This makes it easier to see which part of the (huge) trace corresponds to +which action. It is recommended to place descriptive markers about what you +do. + +Shut down mmiotrace (requires root privileges): +$ echo none > /debug/tracing/current_tracer +The 'cat' process exits. If it does not, kill it by 'fg' and pressing ctrl+c. + +[This feature is not implemented yet!] +Check your kernel log. If there are messages about mmiotrace losing events, +this is due to buffer overrun, and the trace is incomplete. You should enlarge +the buffers and try again. [How?] + +If you are doing a trace for a driver project, e.g. Nouveau, you should also +do the following before sending your results: +$ lspci -vvv > lspci.txt +$ dmesg > dmesg.txt +$ tar zcf pciid-nick-mmiotrace.tar.gz mydump.txt lspci.txt dmesg.txt +and then send the .tar.gz file. The trace compresses considerably. Replace +"pciid" and "nick" with the PCI ID or model name of your piece of hardware +under investigation and your nick name. + + +How Mmiotrace Works +------------------- + +Access to hardware IO-memory is gained by mapping addresses from PCI bus by +calling one of the ioremap_*() functions. Mmiotrace is hooked into the +__ioremap() function and gets called whenever a mapping is created. Mapping is +an event that is recorded into the trace log. Note, that ISA range mappings +are not caught, since the mapping always exists and is returned directly. + +MMIO accesses are recorded via page faults. Just before __ioremap() returns, +the mapped pages are marked as not present. Any access to the pages causes a +fault. The page fault handler calls mmiotrace to handle the fault. Mmiotrace +marks the page present, sets TF flag to achieve single stepping and exits the +fault handler. The instruction that faulted is executed and debug trap is +entered. Here mmiotrace again marks the page as not present. The instruction +is decoded to get the type of operation (read/write), data width and the value +read or written. These are stored to the trace log. + +Setting the page present in the page fault handler has a race condition on SMP +machines. During the single stepping other CPUs may run freely on that page +and events can be missed without a notice. Re-enabling other CPUs during +tracing is discouraged. + + +Trace Log Format +---------------- + +The raw log is text and easily filtered with e.g. grep and awk. One record is +one line in the log. A record starts with a keyword, followed by keyword +dependant arguments. Arguments are separated by a space, or continue until the +end of line. The format for version 20070824 is as follows: + +Explanation Keyword Space separated arguments +--------------------------------------------------------------------------- + +read event R width, timestamp, map id, physical, value, PC, PID +write event W width, timestamp, map id, physical, value, PC, PID +ioremap event MAP timestamp, map id, physical, virtual, length, PC, PID +iounmap event UNMAP timestamp, map id, PC, PID +marker MARK timestamp, text +version VERSION the string "20070824" +info for reader LSPCI one line from lspci -v +PCI address map PCIDEV space separated /proc/bus/pci/devices data +unk. opcode UNKNOWN timestamp, map id, physical, data, PC, PID + +Timestamp is in seconds with decimals. Physical is a PCI bus address, virtual +is a kernel virtual address. Width is the data width in bytes and value is the +data value. Map id is an arbitrary id number identifying the mapping that was +used in an operation. PC is the program counter and PID is process id. PC is +zero if it is not recorded. PID is always zero as tracing MMIO accesses +originating in user space memory is not yet supported. + +For instance, the following awk filter will pass all 32-bit writes that target +physical addresses in the range [0xfb73ce40, 0xfb800000[ + +$ awk '/W 4 / { adr=strtonum($5); if (adr >= 0xfb73ce40 && +adr < 0xfb800000) print; }' + + +Tools for Developers +-------------------- + +The user space tools include utilities for: +- replacing numeric addresses and values with hardware register names +- replaying MMIO logs, i.e., re-executing the recorded writes + + diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 1d6de0d..b28ace2 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -180,12 +180,10 @@ config MMIOTRACE 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. A user space program is - required to collect the MMIO data from debugfs files. - Tracing is disabled by default and can be enabled from a debugfs - file. + implementation and works via page faults. Tracing is disabled by + default and can be enabled run-time. - See http://nouveau.freedesktop.org/wiki/MmioTrace + See Documentation/tracers/mmiotrace.txt. If you are not helping to develop drivers, say N. config MMIOTRACE_TEST -- cgit v0.10.2 From 0663bb6cd9a457fbd8ca95c627bb762d07321a39 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 12 May 2008 21:20:59 +0200 Subject: mmiotrace: fix printk format Fix gcc printk format warnings: next-20080415/arch/x86/mm/mmio-mod.c: In function 'print_pte': next-20080415/arch/x86/mm/mmio-mod.c:154: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'pteval_t' next-20080415/arch/x86/mm/mmio-mod.c:154: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'pteval_t' next-20080415/arch/x86/mm/mmio-mod.c: At top level: next-20080415/arch/x86/mm/mmio-mod.c:403: warning: 'downed_cpus' defined but not used Signed-off-by: Randy Dunlap Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index ab2bb77..6d6cac8 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -150,8 +150,9 @@ static void print_pte(unsigned long address) "0x%08lx\n", address); BUG(); } - pr_info(NAME "pte for 0x%lx: 0x%lx 0x%lx\n", address, pte_val(*pte), - pte_val(*pte) & _PAGE_PRESENT); + pr_info(NAME "pte for 0x%lx: 0x%llx 0x%llx\n", address, + (unsigned long long)pte_val(*pte), + (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); } /* -- cgit v0.10.2 From 37b3619257d3190f47f233d7ed626d4b9916462c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 12 May 2008 21:20:59 +0200 Subject: x86/mmiotrace: uses/depends on PCI Don't try to build mmiotrace when CONFIG_PCI=n. next-20080416/kernel/trace/trace_mmiotrace.c: In function 'mmio_print_pcidev': next-20080416/kernel/trace/trace_mmiotrace.c:62: error: implicit declaration of function 'pci_dev_driver' Signed-off-by: Randy Dunlap Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index b28ace2..1e53df0 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -173,7 +173,7 @@ config MMIOTRACE_HOOKS config MMIOTRACE bool "Memory mapped IO tracing" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PCI select TRACING select MMIOTRACE_HOOKS default y @@ -181,7 +181,7 @@ config MMIOTRACE 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 run-time. + default and can be enabled at run-time. See Documentation/tracers/mmiotrace.txt. If you are not helping to develop drivers, say N. -- cgit v0.10.2 From 7423d1115f18627666d475fccc7c62394406ff8c Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: x86 mmiotrace: dynamically disable non-boot CPUs From 8979ee55cb6a429c4edd72ebec2244b849f6a79a Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 12 Apr 2008 00:18:57 +0300 Mmiotrace is not reliable with multiple CPUs and may miss events. Drop to single CPU when mmiotrace is activated. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 6d6cac8..1f77d85 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -32,6 +32,7 @@ #include /* for ISA_START_ADDRESS */ #include #include +#include #include "pf_in.h" @@ -400,6 +401,64 @@ static void clear_trace_list(void) } } +#ifdef CONFIG_HOTPLUG_CPU +static cpumask_t downed_cpus; + +static void enter_uniprocessor(void) +{ + int cpu; + int err; + + get_online_cpus(); + downed_cpus = cpu_online_map; + cpu_clear(first_cpu(cpu_online_map), downed_cpus); + if (num_online_cpus() > 1) + pr_notice(NAME "Disabling non-boot CPUs...\n"); + put_online_cpus(); + + for_each_cpu_mask(cpu, downed_cpus) { + err = cpu_down(cpu); + if (!err) { + pr_info(NAME "CPU%d is down.\n", cpu); + } else { + pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err); + } + } + if (num_online_cpus() > 1) + pr_warning(NAME "multiple CPUs still online, " + "may miss events.\n"); +} + +static void leave_uniprocessor(void) +{ + int cpu; + int err; + + if (cpus_weight(downed_cpus) == 0) + return; + pr_notice(NAME "Re-enabling CPUs...\n"); + for_each_cpu_mask(cpu, downed_cpus) { + err = cpu_up(cpu); + if (!err) + pr_info(NAME "enabled CPU%d.\n", cpu); + else + pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err); + } +} + +#else /* !CONFIG_HOTPLUG_CPU */ +static void enter_uniprocessor(void) +{ + if (num_online_cpus() > 1) + pr_warning(NAME "multiple CPUs are online, may miss events. " + "Suggest booting with maxcpus=1 kernel argument.\n"); +} + +static void leave_uniprocessor(void) +{ +} +#endif + #if 0 /* XXX: out of order */ static struct file_operations fops_marker = { .owner = THIS_MODULE, @@ -422,6 +481,7 @@ void enable_mmiotrace(void) if (nommiotrace) pr_info(NAME "MMIO tracing disabled.\n"); + enter_uniprocessor(); spin_lock_irq(&trace_lock); atomic_inc(&mmiotrace_enabled); spin_unlock_irq(&trace_lock); @@ -442,6 +502,7 @@ void disable_mmiotrace(void) spin_unlock_irq(&trace_lock); clear_trace_list(); /* guarantees: no more kmmio callbacks */ + leave_uniprocessor(); if (marker_file) { debugfs_remove(marker_file); marker_file = NULL; -- cgit v0.10.2 From d0a7e8ca5b996d36219e6fc002907291c8ee677b Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: mmiotrace: print header using the read hook. Now the header is printed only for `trace_pipe' file. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 79be4a1..6d2edbd 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -12,6 +12,10 @@ #include "trace.h" +struct header_iter { + struct pci_dev *dev; +}; + static struct trace_array *mmio_trace_array; static void mmio_reset_data(struct trace_array *tr) @@ -89,17 +93,57 @@ static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) return ret; } -/* XXX: This is not called for trace_pipe file! */ -static void mmio_print_header(struct trace_iterator *iter) +static void destroy_header_iter(struct header_iter *hiter) +{ + if (!hiter) + return; + pci_dev_put(hiter->dev); + kfree(hiter); +} + +static void mmio_pipe_open(struct trace_iterator *iter) { + struct header_iter *hiter; struct trace_seq *s = &iter->seq; - struct pci_dev *dev = NULL; trace_seq_printf(s, "VERSION 20070824\n"); - for_each_pci_dev(dev) - mmio_print_pcidev(s, dev); - /* XXX: return value? What if header is very long? */ + hiter = kzalloc(sizeof(*hiter), GFP_KERNEL); + if (!hiter) + return; + + hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); + iter->private = hiter; +} + +/* XXX: This is not called when the pipe is closed! */ +static void mmio_close(struct trace_iterator *iter) +{ + struct header_iter *hiter = iter->private; + destroy_header_iter(hiter); + iter->private = NULL; +} + +static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp, + char __user *ubuf, size_t cnt, loff_t *ppos) +{ + ssize_t ret; + struct header_iter *hiter = iter->private; + struct trace_seq *s = &iter->seq; + + if (!hiter) + return 0; + + mmio_print_pcidev(s, hiter->dev); + hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev); + + if (!hiter->dev) { + destroy_header_iter(hiter); + iter->private = NULL; + } + + ret = trace_seq_to_user(s, ubuf, cnt); + return (ret == -EBUSY) ? 0 : ret; } static int mmio_print_rw(struct trace_iterator *iter) @@ -190,7 +234,9 @@ static struct tracer mmio_tracer __read_mostly = .name = "mmiotrace", .init = mmio_trace_init, .reset = mmio_trace_reset, - .open = mmio_print_header, + .pipe_open = mmio_pipe_open, + .close = mmio_close, + .read = mmio_read, .ctrl_update = mmio_trace_ctrl_update, .print_line = mmio_print_line, }; -- cgit v0.10.2 From 2039238b79b51a50f8477f53f33750e1c3fc146a Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: mmiotrace: print overrun counts Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 6d2edbd..d0f649a 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -17,11 +17,13 @@ struct header_iter { }; static struct trace_array *mmio_trace_array; +static bool overrun_detected; static void mmio_reset_data(struct trace_array *tr) { int cpu; + overrun_detected = false; tr->time_start = ftrace_now(tr->cpu); for_each_online_cpu(cpu) @@ -124,12 +126,34 @@ static void mmio_close(struct trace_iterator *iter) iter->private = NULL; } +static unsigned long count_overruns(struct trace_iterator *iter) +{ + int cpu; + unsigned long cnt = 0; + for_each_online_cpu(cpu) { + cnt += iter->overrun[cpu]; + iter->overrun[cpu] = 0; + } + return cnt; +} + static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { ssize_t ret; struct header_iter *hiter = iter->private; struct trace_seq *s = &iter->seq; + unsigned long n; + + n = count_overruns(iter); + if (n) { + /* XXX: This is later than where events were lost. */ + trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n); + if (!overrun_detected) + pr_warning("mmiotrace has lost events.\n"); + overrun_detected = true; + goto print_out; + } if (!hiter) return 0; @@ -142,6 +166,7 @@ static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp, iter->private = NULL; } +print_out: ret = trace_seq_to_user(s, ubuf, cnt); return (ret == -EBUSY) ? 0 : ret; } -- cgit v0.10.2 From e0fd5c2fa188311667267c02a702ae699a9fc2bd Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:02 +0200 Subject: mmiotrace: do not print bogus pid for maps either Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index d0f649a..3c1dacd 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -225,12 +225,12 @@ static int mmio_print_map(struct trace_iterator *iter) ret = trace_seq_printf(s, "MAP %lu.%06lu %d 0x%lx 0x%lx 0x%lx 0x%lx %d\n", secs, usec_rem, m->map_id, m->phys, m->virt, m->len, - 0UL, entry->pid); + 0UL, 0); break; case MMIO_UNPROBE: ret = trace_seq_printf(s, "UNMAP %lu.%06lu %d 0x%lx %d\n", - secs, usec_rem, m->map_id, 0UL, entry->pid); + secs, usec_rem, m->map_id, 0UL, 0); break; default: ret = trace_seq_printf(s, "map what?\n"); -- cgit v0.10.2 From 6f6f394d9ca61fcc73ecfd2f2bf58e92dc1ab269 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: doc: update mmiotrace doc to current status Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/tracers/mmiotrace.txt index 84246f7..a4afb56 100644 --- a/Documentation/tracers/mmiotrace.txt +++ b/Documentation/tracers/mmiotrace.txt @@ -25,7 +25,8 @@ Mmiotrace feature is compiled in by the CONFIG_MMIOTRACE option. Tracing is disabled by default, so it is safe to have this set to yes. SMP systems are supported, but tracing is unreliable and may miss events if more than one CPU is on-line, therefore mmiotrace takes all but one CPU off-line during run-time -activation [not implemented]. +activation. You can re-enable CPUs by hand, but you have been warned, there +is no way to automatically detect if you are losing events due to CPUs racing. Usage Quick Reference @@ -37,7 +38,7 @@ $ cat /debug/tracing/trace_pipe > mydump.txt & Start X or whatever. $ echo "X is up" > /debug/tracing/marker $ echo none > /debug/tracing/current_tracer -Check kernel log. +Check for lost events. Usage @@ -67,12 +68,22 @@ do. Shut down mmiotrace (requires root privileges): $ echo none > /debug/tracing/current_tracer -The 'cat' process exits. If it does not, kill it by 'fg' and pressing ctrl+c. - -[This feature is not implemented yet!] -Check your kernel log. If there are messages about mmiotrace losing events, -this is due to buffer overrun, and the trace is incomplete. You should enlarge -the buffers and try again. [How?] +The 'cat' process exits. If it does not, kill it by issuing 'fg' command and +pressing ctrl+c. + +Check that mmiotrace did not lose events due to a buffer filling up. Either +$ grep -i lost mydump.txt +which tells you exactly how many events were lost, or use +$ dmesg +to view your kernel log and look for "mmiotrace has lost events" warning. If +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/trace_entries +gives you a number. Approximately double this number and write it back, for +instance: +$ echo 128000 > /debug/tracing/trace_entries +Then start again from the top. If you are doing a trace for a driver project, e.g. Nouveau, you should also do the following before sending your results: -- cgit v0.10.2 From 970e6fa03885f32cc43e42cb08c73a5f54cd8bd9 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: mmiotrace: code style cleanups From c2da03771e29159627c5c7b9509ec70bce9f91ee Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 28 Apr 2008 21:25:22 +0300 Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 3ad27b8..6a92d91 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -17,10 +17,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 1f77d85..a8d2a00 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -418,11 +418,10 @@ static void enter_uniprocessor(void) for_each_cpu_mask(cpu, downed_cpus) { err = cpu_down(cpu); - if (!err) { + if (!err) pr_info(NAME "CPU%d is down.\n", cpu); - } else { + else pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err); - } } if (num_online_cpus() > 1) pr_warning(NAME "multiple CPUs still online, " diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c index cfa60b2..d877c5b 100644 --- a/arch/x86/mm/testmmiotrace.c +++ b/arch/x86/mm/testmmiotrace.c @@ -2,7 +2,7 @@ * Written by Pekka Paalanen, 2008 */ #include -#include +#include #define MODULE_NAME "testmmiotrace" diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index dd6b64b..de8e912 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -1,9 +1,7 @@ #ifndef MMIOTRACE_H #define MMIOTRACE_H -#include - -#ifdef __KERNEL__ +#include #include @@ -84,6 +82,4 @@ extern void disable_mmiotrace(void); extern void mmio_trace_rw(struct mmiotrace_rw *rw); extern void mmio_trace_mapping(struct mmiotrace_map *map); -#endif /* __KERNEL__ */ - #endif /* MMIOTRACE_H */ -- cgit v0.10.2 From 87e547fe41a8b57d6d80afc67a0031fbe477eb0d Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: x86 mmiotrace: fix page-unaligned ioremaps mmiotrace_ioremap() expects to receive the original unaligned map phys address and size. Also fix {un,}register_kmmio_probe() to deal properly with unaligned size. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 8927c87..a7c80a6 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -123,6 +123,8 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, { unsigned long pfn, offset, vaddr; resource_size_t last_addr; + const resource_size_t unaligned_phys_addr = phys_addr; + const unsigned long unaligned_size = size; struct vm_struct *area; unsigned long new_prot_val; pgprot_t prot; @@ -236,7 +238,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, } ret_addr = (void __iomem *) (vaddr + offset); - mmiotrace_ioremap(phys_addr, size, ret_addr); + mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr); return ret_addr; } diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 6a92d91..93b1797 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -351,11 +351,19 @@ static void release_kmmio_fault_page(unsigned long page, } } +/* + * With page-unaligned ioremaps, one or two armed pages may contain + * addresses from outside the intended mapping. Events for these addresses + * are currently silently dropped. The events may result only from programming + * mistakes by accessing addresses before the beginning or past the end of a + * mapping. + */ int register_kmmio_probe(struct kmmio_probe *p) { unsigned long flags; int ret = 0; unsigned long size = 0; + const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); spin_lock_irqsave(&kmmio_lock, flags); if (get_kmmio_probe(p->addr)) { @@ -364,7 +372,7 @@ int register_kmmio_probe(struct kmmio_probe *p) } kmmio_count++; list_add_rcu(&p->list, &kmmio_probes); - while (size < p->len) { + while (size < size_lim) { if (add_kmmio_fault_page(p->addr + size)) pr_err("kmmio: Unable to set page fault.\n"); size += PAGE_SIZE; @@ -436,11 +444,12 @@ void unregister_kmmio_probe(struct kmmio_probe *p) { unsigned long flags; unsigned long size = 0; + const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); struct kmmio_fault_page *release_list = NULL; struct kmmio_delayed_release *drelease; spin_lock_irqsave(&kmmio_lock, flags); - while (size < p->len) { + while (size < size_lim) { release_kmmio_fault_page(p->addr + size, &release_list); size += PAGE_SIZE; } diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index a8d2a00..278998c 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -280,6 +280,7 @@ static void ioremap_trace_core(unsigned long offset, unsigned long size, { static atomic_t next_id; struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); + /* These are page-unaligned. */ struct mmiotrace_map map = { .phys = offset, .virt = (unsigned long)addr, -- cgit v0.10.2 From dee310d0adf41019aca476052ac3085ff286d9be Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: x86 mmiotrace: use resource_size_t for phys addresses Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 278998c..3b04a01 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -48,7 +48,7 @@ struct trap_reason { struct remap_trace { struct list_head list; struct kmmio_probe probe; - unsigned long phys; + resource_size_t phys; unsigned long id; }; @@ -275,7 +275,7 @@ static void post(struct kmmio_probe *p, unsigned long condition, put_cpu_var(pf_reason); } -static void ioremap_trace_core(unsigned long offset, unsigned long size, +static void ioremap_trace_core(resource_size_t offset, unsigned long size, void __iomem *addr) { static atomic_t next_id; @@ -319,13 +319,14 @@ not_enabled: spin_unlock_irq(&trace_lock); } -void -mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) +void mmiotrace_ioremap(resource_size_t offset, unsigned long size, + void __iomem *addr) { if (!is_enabled()) /* recheck and proper locking in *_core() */ return; - pr_debug(NAME "ioremap_*(0x%lx, 0x%lx) = %p\n", offset, size, addr); + pr_debug(NAME "ioremap_*(0x%llx, 0x%lx) = %p\n", + (unsigned long long)offset, size, addr); if ((filter_offset) && (offset != filter_offset)) return; ioremap_trace_core(offset, size, addr); diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index de8e912..5cbbc37 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -2,7 +2,6 @@ #define MMIOTRACE_H #include - #include struct kmmio_probe; @@ -37,14 +36,15 @@ extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); /* Called from ioremap.c */ #ifdef CONFIG_MMIOTRACE -extern void -mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr); +extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, + void __iomem *addr); extern void mmiotrace_iounmap(volatile void __iomem *addr); #else -static inline void -mmiotrace_ioremap(unsigned long offset, unsigned long size, void __iomem *addr) +static inline void mmiotrace_ioremap(resource_size_t offset, + unsigned long size, void __iomem *addr) { } + static inline void mmiotrace_iounmap(volatile void __iomem *addr) { } @@ -60,7 +60,7 @@ enum mm_io_opcode { }; struct mmiotrace_rw { - unsigned long phys; /* PCI address of register */ + resource_size_t phys; /* PCI address of register */ unsigned long value; unsigned long pc; /* optional program counter */ int map_id; @@ -69,7 +69,7 @@ struct mmiotrace_rw { }; struct mmiotrace_map { - unsigned long phys; /* base address in PCI space */ + resource_size_t phys; /* base address in PCI space */ unsigned long virt; /* base virtual address */ unsigned long len; /* mapping size */ int map_id; diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 3c1dacd..b13dc19 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -184,20 +184,23 @@ static int mmio_print_rw(struct trace_iterator *iter) switch (entry->mmiorw.opcode) { case MMIO_READ: ret = trace_seq_printf(s, - "R %d %lu.%06lu %d 0x%lx 0x%lx 0x%lx %d\n", - rw->width, secs, usec_rem, rw->map_id, rw->phys, + "R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", + rw->width, secs, usec_rem, rw->map_id, + (unsigned long long)rw->phys, rw->value, rw->pc, 0); break; case MMIO_WRITE: ret = trace_seq_printf(s, - "W %d %lu.%06lu %d 0x%lx 0x%lx 0x%lx %d\n", - rw->width, secs, usec_rem, rw->map_id, rw->phys, + "W %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", + rw->width, secs, usec_rem, rw->map_id, + (unsigned long long)rw->phys, rw->value, rw->pc, 0); break; case MMIO_UNKNOWN_OP: ret = trace_seq_printf(s, - "UNKNOWN %lu.%06lu %d 0x%lx %02x,%02x,%02x 0x%lx %d\n", - secs, usec_rem, rw->map_id, rw->phys, + "UNKNOWN %lu.%06lu %d 0x%llx %02x,%02x,%02x 0x%lx %d\n", + secs, usec_rem, rw->map_id, + (unsigned long long)rw->phys, (rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff, (rw->value >> 0) & 0xff, rw->pc, 0); break; @@ -223,8 +226,9 @@ static int mmio_print_map(struct trace_iterator *iter) switch (entry->mmiorw.opcode) { case MMIO_PROBE: ret = trace_seq_printf(s, - "MAP %lu.%06lu %d 0x%lx 0x%lx 0x%lx 0x%lx %d\n", - secs, usec_rem, m->map_id, m->phys, m->virt, m->len, + "MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n", + secs, usec_rem, m->map_id, + (unsigned long long)m->phys, m->virt, m->len, 0UL, 0); break; case MMIO_UNPROBE: -- cgit v0.10.2 From a50445d76c22a34ae149704ea5adaef171c8acb7 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:03 +0200 Subject: mmiotrace: rename kmmio_probe::user_data to :private. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 3b04a01..ed0e0e9 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -191,7 +191,7 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs, struct mmiotrace_rw *my_trace = &get_cpu_var(cpu_trace); const unsigned long instptr = instruction_pointer(regs); const enum reason_type type = get_ins_type(instptr); - struct remap_trace *trace = p->user_data; + struct remap_trace *trace = p->private; /* it doesn't make sense to have more than one active trace per cpu */ if (my_reason->active_traces) @@ -299,7 +299,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size, .len = size, .pre_handler = pre, .post_handler = post, - .user_data = trace + .private = trace }, .phys = offset, .id = atomic_inc_return(&next_id) diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 5cbbc37..61d19e1 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -18,7 +18,7 @@ struct kmmio_probe { unsigned long len; /* length of the probe region */ kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */ kmmio_post_handler_t post_handler; /* Called after addr is executed */ - void *user_data; + void *private; }; /* kmmio is active by some kmmio_probes? */ -- cgit v0.10.2 From 790e2a290b499b0400254e6870ec27969065d122 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 12 May 2008 21:21:14 +0200 Subject: x86 mmiotrace: page level is unsigned Fixes some sparse warnings. Signed-off-by: Pekka Paalanen Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 93b1797..b65871e 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -104,11 +104,12 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) return NULL; } -static void set_page_present(unsigned long addr, bool present, int *pglevel) +static void set_page_present(unsigned long addr, bool present, + unsigned int *pglevel) { pteval_t pteval; pmdval_t pmdval; - int level; + unsigned int level; pmd_t *pmd; pte_t *pte = lookup_address(addr, &level); @@ -145,15 +146,15 @@ static void set_page_present(unsigned long addr, bool present, int *pglevel) } /** Mark the given page as not present. Access to it will trigger a fault. */ -static void arm_kmmio_fault_page(unsigned long page, int *page_level) +static void arm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) { - set_page_present(page & PAGE_MASK, false, page_level); + set_page_present(page & PAGE_MASK, false, pglevel); } /** Mark the given page as present. */ -static void disarm_kmmio_fault_page(unsigned long page, int *page_level) +static void disarm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) { - set_page_present(page & PAGE_MASK, true, page_level); + set_page_present(page & PAGE_MASK, true, pglevel); } /* diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index ed0e0e9..e7397e1 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -137,7 +137,7 @@ static ssize_t write_marker(struct file *file, const char __user *buffer, static void print_pte(unsigned long address) { - int level; + unsigned int level; pte_t *pte = lookup_address(address, &level); if (!pte) { -- cgit v0.10.2 From 4d2df795f0c3eb91f97a666f47716121a2f166ed Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 24 May 2008 15:00:46 +0200 Subject: sysprof: make it depend on X86 Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e101c9a..263e9e6 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -77,7 +77,7 @@ config PREEMPT_TRACER config SYSPROF_TRACER bool "Sysprof Tracer" - depends on DEBUG_KERNEL + depends on X86 select TRACING help This tracer provides the trace needed by the 'Sysprof' userspace -- cgit v0.10.2 From 81d50bb254ed53a0da45a65988e4e1fa08e8a541 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 15 May 2008 19:42:49 -0700 Subject: posix-timers: print RT watchdog message It's useful to detect which process is killed by RT watchdog. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index f1525ad..c42a03a 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1037,6 +1037,9 @@ static void check_thread_timers(struct task_struct *tsk, sig->rlim[RLIMIT_RTTIME].rlim_cur += USEC_PER_SEC; } + printk(KERN_INFO + "RT Watchdog Timeout: %s[%d]\n", + tsk->comm, task_pid_nr(tsk)); __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); } } -- cgit v0.10.2 From 7f6f3a39d258adf51f0fb1fe0dab52272a1c61a4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 24 May 2008 23:12:18 +0200 Subject: namespacecheck: fix kernel printk.c Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/printk.c b/kernel/printk.c index 8fb01c3..b620e3d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -231,7 +231,7 @@ static inline void boot_delay_msec(void) /* * Return the number of unread characters in the log buffer. */ -int log_buf_get_len(void) +static int log_buf_get_len(void) { return logged_chars; } @@ -270,7 +270,7 @@ int log_buf_copy(char *dest, int idx, int len) /* * Extract a single character from the log buffer. */ -int log_buf_read(int idx) +static int log_buf_read(int idx) { char ret; -- cgit v0.10.2 From 42fdfa238a23643226910acf922ea930b3286032 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 24 May 2008 23:14:51 +0200 Subject: namespacecheck: more kernel/printk.c fixes [ Stephen Rothwell : build fix ] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 792bf0a..f2a668c 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -184,9 +184,6 @@ asmlinkage int vprintk(const char *fmt, va_list args) __attribute__ ((format (printf, 1, 0))); asmlinkage int printk(const char * fmt, ...) __attribute__ ((format (printf, 1, 2))) __cold; -extern int log_buf_get_len(void); -extern int log_buf_read(int idx); -extern int log_buf_copy(char *dest, int idx, int len); extern int printk_ratelimit_jiffies; extern int printk_ratelimit_burst; @@ -202,9 +199,6 @@ static inline int vprintk(const char *s, va_list args) { return 0; } static inline int printk(const char *s, ...) __attribute__ ((format (printf, 1, 2))); static inline int __cold printk(const char *s, ...) { return 0; } -static inline int log_buf_get_len(void) { return 0; } -static inline int log_buf_read(int idx) { return 0; } -static inline int log_buf_copy(char *dest, int idx, int len) { return 0; } static inline int printk_ratelimit(void) { return 0; } static inline int __printk_ratelimit(int ratelimit_jiffies, \ int ratelimit_burst) { return 0; } diff --git a/kernel/printk.c b/kernel/printk.c index b620e3d..55d16e5 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -268,19 +268,6 @@ int log_buf_copy(char *dest, int idx, int len) } /* - * Extract a single character from the log buffer. - */ -static int log_buf_read(int idx) -{ - char ret; - - if (log_buf_copy(&ret, idx, 1) == 1) - return ret; - else - return -1; -} - -/* * Commands to do_syslog: * * 0 -- Close the log. Currently a NOP. -- cgit v0.10.2 From 3b8945e8d40645eecdb7d2357ca531f9b4dd9f71 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 12 May 2008 21:21:04 +0200 Subject: printk: clean up recursion check related static variables Make printk_recursion_bug_msg static and drop printk prefix from recursion variables. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/printk.c b/kernel/printk.c index 55d16e5..8b42f87 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -652,16 +652,14 @@ static int acquire_console_semaphore_for_printk(unsigned int cpu) spin_unlock(&logbuf_lock); return retval; } - -const char printk_recursion_bug_msg [] = - KERN_CRIT "BUG: recent printk recursion!\n"; -static int printk_recursion_bug; +static const char recursion_bug_msg [] = + KERN_CRIT "BUG: recent printk recursion!\n"; +static int recursion_bug; +static int log_level_unknown = 1; +static char printk_buf[1024]; asmlinkage int vprintk(const char *fmt, va_list args) { - static int log_level_unknown = 1; - static char printk_buf[1024]; - unsigned long flags; int printed_len = 0; int this_cpu; @@ -686,7 +684,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) * it can be printed at the next appropriate moment: */ if (!oops_in_progress) { - printk_recursion_bug = 1; + recursion_bug = 1; goto out_restore_irqs; } zap_locks(); @@ -696,10 +694,10 @@ asmlinkage int vprintk(const char *fmt, va_list args) spin_lock(&logbuf_lock); printk_cpu = this_cpu; - if (printk_recursion_bug) { - printk_recursion_bug = 0; - strcpy(printk_buf, printk_recursion_bug_msg); - printed_len = sizeof(printk_recursion_bug_msg); + if (recursion_bug) { + recursion_bug = 0; + strcpy(printk_buf, recursion_bug_msg); + printed_len = sizeof(recursion_bug_msg); } /* Emit the output into the temporary buffer */ printed_len += vscnprintf(printk_buf + printed_len, -- cgit v0.10.2 From cd3a1b8562d28490b334a61d5eb05df3d722d91e Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 12 May 2008 21:21:04 +0200 Subject: printk: don't prefer unsuited consoles on registration console election: If some console happens to be registered first which does not provide a tty binding (!console->device), it prevents that more suited consoles which are registered later on can enter the candidate pool for console_device(). This is observable with KGDB's console which may already be registered (and exploited!) during early debugger connections, that is before any regular console registration. This patch fixes the issue by postponing the final, automated preferred_console selection until someone with a non-NULL device handler comes around. Signed-off-by: Jan Kiszka Cc: Jason Wessel Cc: Gerd Hoffmann Cc: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/printk.c b/kernel/printk.c index 8b42f87..7d55561 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1157,8 +1157,11 @@ void register_console(struct console *console) console->index = 0; if (console->setup == NULL || console->setup(console, NULL) == 0) { - console->flags |= CON_ENABLED | CON_CONSDEV; - preferred_console = 0; + console->flags |= CON_ENABLED; + if (console->device) { + console->flags |= CON_CONSDEV; + preferred_console = 0; + } } } -- cgit v0.10.2 From ac60ad7413ca8208094609a3b88ed9b1ed012fbc Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Mon, 12 May 2008 21:21:04 +0200 Subject: printk: refactor processing of line severity tokens Restructure the logic of vprintk() so the processing of the leading 3 characters of each input line is in one place, regardless whether printk_time is enabled. This makes the code smaller and easier to understand. size reduction in kernel/printk.o: text data bss dec hex filename 6157 397 1049804 1056358 101e66 printk.o.before 6117 397 1049804 1056318 101e3e printk.o.after and some style uncleanlinesses removed as well as a side-effect: Before: total: 19 errors, 22 warnings, 1340 lines checked After: total: 17 errors, 22 warnings, 1333 lines checked Signed-off-by: Nick Andrew Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/printk.c b/kernel/printk.c index 7d55561..98ca1b7 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -655,13 +655,13 @@ static int acquire_console_semaphore_for_printk(unsigned int cpu) static const char recursion_bug_msg [] = KERN_CRIT "BUG: recent printk recursion!\n"; static int recursion_bug; -static int log_level_unknown = 1; + static int new_text_line = 1; static char printk_buf[1024]; asmlinkage int vprintk(const char *fmt, va_list args) { - unsigned long flags; int printed_len = 0; + unsigned long flags; int this_cpu; char *p; @@ -703,61 +703,54 @@ asmlinkage int vprintk(const char *fmt, va_list args) printed_len += vscnprintf(printk_buf + printed_len, sizeof(printk_buf) - printed_len, fmt, args); + /* * Copy the output into log_buf. If the caller didn't provide * appropriate log level tags, we insert them here */ for (p = printk_buf; *p; p++) { - if (log_level_unknown) { - /* log_level_unknown signals the start of a new line */ + if (new_text_line) { + int current_log_level = default_message_loglevel; + /* If a token, set current_log_level and skip over */ + if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' && + p[2] == '>') { + current_log_level = p[1] - '0'; + p += 3; + printed_len -= 3; + } + + /* Always output the token */ + emit_log_char('<'); + emit_log_char(current_log_level + '0'); + emit_log_char('>'); + printed_len += 3; + new_text_line = 0; + if (printk_time) { - int loglev_char; + /* Follow the token with the time */ char tbuf[50], *tp; unsigned tlen; unsigned long long t; unsigned long nanosec_rem; - /* - * force the log level token to be - * before the time output. - */ - if (p[0] == '<' && p[1] >='0' && - p[1] <= '7' && p[2] == '>') { - loglev_char = p[1]; - p += 3; - printed_len -= 3; - } else { - loglev_char = default_message_loglevel - + '0'; - } t = cpu_clock(printk_cpu); nanosec_rem = do_div(t, 1000000000); - tlen = sprintf(tbuf, - "<%c>[%5lu.%06lu] ", - loglev_char, - (unsigned long)t, - nanosec_rem/1000); + tlen = sprintf(tbuf, "[%5lu.%06lu] ", + (unsigned long) t, + nanosec_rem / 1000); for (tp = tbuf; tp < tbuf + tlen; tp++) emit_log_char(*tp); printed_len += tlen; - } else { - if (p[0] != '<' || p[1] < '0' || - p[1] > '7' || p[2] != '>') { - emit_log_char('<'); - emit_log_char(default_message_loglevel - + '0'); - emit_log_char('>'); - printed_len += 3; - } } - log_level_unknown = 0; + if (!*p) break; } + emit_log_char(*p); if (*p == '\n') - log_level_unknown = 1; + new_text_line = 1; } /* -- cgit v0.10.2 From 091593080533a752ce66d12858d8c4105c8e1793 Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Mon, 12 May 2008 21:21:04 +0200 Subject: printk: remember the message level for multi-line output printk(KERN_ALERT "Danger Will Robinson!\nAlien Approaching!\n"); At present this will result in one message at ALERT level and one at the current default message loglevel (e.g. WARNING). This is non-intuitive. Modify vprintk() to remember the message loglevel each time it is specified and use it for subsequent lines of output which do not specify one, within the same call to printk. Signed-off-by: Nick Andrew Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/printk.c b/kernel/printk.c index 98ca1b7..475fc22 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -661,6 +661,7 @@ static char printk_buf[1024]; asmlinkage int vprintk(const char *fmt, va_list args) { int printed_len = 0; + int current_log_level = default_message_loglevel; unsigned long flags; int this_cpu; char *p; @@ -710,7 +711,6 @@ asmlinkage int vprintk(const char *fmt, va_list args) */ for (p = printk_buf; *p; p++) { if (new_text_line) { - int current_log_level = default_message_loglevel; /* If a token, set current_log_level and skip over */ if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' && p[2] == '>') { -- cgit v0.10.2 From 6360b1fbb4a939efd34fc770c2ebd927c55506e0 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 12 May 2008 15:44:41 +0200 Subject: move BUG_TABLE into RODATA Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S index 481cfd4..bc932c9 100644 --- a/arch/avr32/kernel/vmlinux.lds.S +++ b/arch/avr32/kernel/vmlinux.lds.S @@ -93,8 +93,6 @@ SECTIONS __stop___ex_table = .; } - BUG_TABLE - RODATA . = ALIGN(THREAD_SIZE); diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 50b4a3a..ff7d4ff 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -66,7 +66,6 @@ SECTIONS _etext = .; RODATA - BUG_TABLE /* writeable */ /* Make sure this is page aligned so diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 0c3000b..53d57d1 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -64,8 +64,6 @@ SECTIONS NOTES - BUG_TABLE - /* * Init sections discarded at runtime */ diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index b460715..76c1e60 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -40,7 +40,6 @@ SECTIONS _etext = .; /* End of text section */ NOTES :text :note - BUG_TABLE :text RODATA diff --git a/arch/sh/kernel/vmlinux_32.lds.S b/arch/sh/kernel/vmlinux_32.lds.S index c711378..7b4b82b 100644 --- a/arch/sh/kernel/vmlinux_32.lds.S +++ b/arch/sh/kernel/vmlinux_32.lds.S @@ -44,7 +44,6 @@ SECTIONS _etext = .; /* End of text section */ - BUG_TABLE NOTES RO_DATA(PAGE_SIZE) diff --git a/arch/sh/kernel/vmlinux_64.lds.S b/arch/sh/kernel/vmlinux_64.lds.S index d1e1770..33fa464 100644 --- a/arch/sh/kernel/vmlinux_64.lds.S +++ b/arch/sh/kernel/vmlinux_64.lds.S @@ -65,7 +65,6 @@ SECTIONS _etext = .; /* End of text section */ - BUG_TABLE NOTES RO_DATA(PAGE_SIZE) diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index ce5ed08..aa08554 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S @@ -49,16 +49,14 @@ SECTIONS _etext = .; /* End of text section */ } :text = 0x9090 + NOTES :text :note + . = ALIGN(16); /* Exception table */ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { __start___ex_table = .; *(__ex_table) __stop___ex_table = .; - } - - NOTES :text :note - - BUG_TABLE :text + } :text = 0x9090 . = ALIGN(4); .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index fad3674..d123747 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -19,7 +19,7 @@ PHDRS { data PT_LOAD FLAGS(7); /* RWE */ user PT_LOAD FLAGS(7); /* RWE */ data.init PT_LOAD FLAGS(7); /* RWE */ - note PT_NOTE FLAGS(4); /* R__ */ + note PT_NOTE FLAGS(0); /* ___ */ } SECTIONS { @@ -40,16 +40,14 @@ SECTIONS _etext = .; /* End of text section */ } :text = 0x9090 + NOTES :text :note + . = ALIGN(16); /* Exception table */ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { __start___ex_table = .; *(__ex_table) __stop___ex_table = .; - } - - NOTES :text :note - - BUG_TABLE :text + } :text = 0x9090 RODATA diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f054778..dd2cc81 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -67,6 +67,8 @@ *(.rodata1) \ } \ \ + BUG_TABLE \ + \ /* PCI quirks */ \ .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \ @@ -310,6 +312,7 @@ .stab.indexstr 0 : { *(.stab.indexstr) } \ .comment 0 : { *(.comment) } +#ifdef CONFIG_GENERIC_BUG #define BUG_TABLE \ . = ALIGN(8); \ __bug_table : AT(ADDR(__bug_table) - LOAD_OFFSET) { \ @@ -317,6 +320,9 @@ *(__bug_table) \ __stop___bug_table = .; \ } +#else +#define BUG_TABLE +#endif #define NOTES \ .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ -- cgit v0.10.2 From 962cf36c5bf6d2840b8d66ee9a606fae2f540bbd Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Thu, 15 May 2008 11:15:37 -0300 Subject: Remove argument from open_softirq which is always NULL As git-grep shows, open_softirq() is always called with the last argument being NULL block/blk-core.c: open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); kernel/hrtimer.c: open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq, NULL); kernel/rcuclassic.c: open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); kernel/rcupreempt.c: open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); kernel/sched.c: open_softirq(SCHED_SOFTIRQ, run_rebalance_domains, NULL); kernel/softirq.c: open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL); kernel/softirq.c: open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL); kernel/timer.c: open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL); net/core/dev.c: open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); net/core/dev.c: open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); This observation has already been made by Matthew Wilcox in June 2002 (http://www.cs.helsinki.fi/linux/linux-kernel/2002-25/0687.html) "I notice that none of the current softirq routines use the data element passed to them." and the situation hasn't changed since them. So it appears we can safely remove that extra argument to save 128 (54) bytes of kernel data (text). Signed-off-by: Carlos R. Mafra Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/block/blk-core.c b/block/blk-core.c index 6a9cc0d..75fdc65 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2048,7 +2048,7 @@ int __init blk_dev_init(void) for_each_possible_cpu(i) INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); - open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); + open_softirq(BLOCK_SOFTIRQ, blk_done_softirq); register_hotcpu_notifier(&blk_cpu_notifier); return 0; diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index f1fc747..a86186d 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -285,12 +285,11 @@ enum struct softirq_action { void (*action)(struct softirq_action *); - void *data; }; asmlinkage void do_softirq(void); asmlinkage void __do_softirq(void); -extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data); +extern void open_softirq(int nr, void (*action)(struct softirq_action *)); extern void softirq_init(void); #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) extern void raise_softirq_irqoff(unsigned int nr); diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 421be5f..861b408 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1669,7 +1669,7 @@ void __init hrtimers_init(void) (void *)(long)smp_processor_id()); register_cpu_notifier(&hrtimers_nb); #ifdef CONFIG_HIGH_RES_TIMERS - open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq, NULL); + open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq); #endif } diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index f4ffbd0..f6e01f3 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c @@ -529,7 +529,7 @@ static void __cpuinit rcu_online_cpu(int cpu) rcu_init_percpu_data(cpu, &rcu_ctrlblk, rdp); rcu_init_percpu_data(cpu, &rcu_bh_ctrlblk, bh_rdp); - open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); + open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); } static int __cpuinit rcu_cpu_notify(struct notifier_block *self, diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index e1cdf19..9dd827d 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -1125,7 +1125,7 @@ void __init __rcu_init(void) for_each_online_cpu(cpu) rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long) cpu); - open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL); + open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); } /* diff --git a/kernel/sched.c b/kernel/sched.c index cfa222a..56ea3a2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -8154,7 +8154,7 @@ void __init sched_init(void) #endif #ifdef CONFIG_SMP - open_softirq(SCHED_SOFTIRQ, run_rebalance_domains, NULL); + open_softirq(SCHED_SOFTIRQ, run_rebalance_domains); #endif #ifdef CONFIG_RT_MUTEXES diff --git a/kernel/softirq.c b/kernel/softirq.c index 36e0617..0592568 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -347,9 +347,8 @@ void raise_softirq(unsigned int nr) local_irq_restore(flags); } -void open_softirq(int nr, void (*action)(struct softirq_action*), void *data) +void open_softirq(int nr, void (*action)(struct softirq_action *)) { - softirq_vec[nr].data = data; softirq_vec[nr].action = action; } @@ -503,8 +502,8 @@ void __init softirq_init(void) &per_cpu(tasklet_hi_vec, cpu).head; } - open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL); - open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL); + open_softirq(TASKLET_SOFTIRQ, tasklet_action); + open_softirq(HI_SOFTIRQ, tasklet_hi_action); } static int ksoftirqd(void * __bind_cpu) diff --git a/kernel/timer.c b/kernel/timer.c index ceacc66..b4da888 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1502,7 +1502,7 @@ void __init init_timers(void) BUG_ON(err == NOTIFY_BAD); register_cpu_notifier(&timers_nb); - open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL); + open_softirq(TIMER_SOFTIRQ, run_timer_softirq); } /** diff --git a/net/core/dev.c b/net/core/dev.c index 5829630..cf0e167 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4563,8 +4563,8 @@ static int __init net_dev_init(void) dev_boot_phase = 0; - open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); - open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); + open_softirq(NET_TX_SOFTIRQ, net_tx_action); + open_softirq(NET_RX_SOFTIRQ, net_rx_action); hotcpu_notifier(dev_cpu_callback, 0); dst_init(); -- cgit v0.10.2 From 668a6c3654560aef8741642478973e205a4f02bf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 19 May 2008 13:35:24 +0200 Subject: - fix mmioftrace + rcu merge interaction Signed-off-by: Thomas Gleixner diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index b65871e..93d8203 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include -- cgit v0.10.2 From 886dd58258e6ddebe20e7aebef7b167a24bad7ee Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 15:44:38 +0200 Subject: debugging: make stacktrace independent from DEBUG_KERNEL Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d2099f4..9c17fb9 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -419,7 +419,6 @@ config DEBUG_LOCKING_API_SELFTESTS config STACKTRACE bool - depends on DEBUG_KERNEL depends on STACKTRACE_SUPPORT config DEBUG_KOBJECT -- cgit v0.10.2 From c6531cce6e6e4b99bcda46b6268d6f2d9e30aea4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 21:21:14 +0200 Subject: sched: do not trace sched_clock The tracer uses sched_clock, so do not trace it. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/kernel/sched.c b/kernel/sched.c index e2e985e..6590a82 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -884,12 +884,12 @@ static unsigned long long __cpu_clock(int cpu) * For kernel-internal use: high-speed (but slightly incorrect) per-cpu * clock constructed from sched_clock(): */ -unsigned long long cpu_clock(int cpu) +unsigned long long notrace cpu_clock(int cpu) { unsigned long long prev_cpu_time, time, delta_time; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); prev_cpu_time = per_cpu(prev_cpu_time, cpu); time = __cpu_clock(cpu) + per_cpu(time_offset, cpu); delta_time = time-prev_cpu_time; @@ -898,7 +898,7 @@ unsigned long long cpu_clock(int cpu) time = __sync_cpu_clock(time, cpu); per_cpu(prev_cpu_time, cpu) = time; } - local_irq_restore(flags); + raw_local_irq_restore(flags); return time; } -- cgit v0.10.2 From 19384c0314342222b18d4c7f09cdce1ca74dfd2a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:16 -0400 Subject: ftrace: limit use of check pages The check_pages function is called often enough that it can cause problems with trace outputs or even bringing the system to a halt. This patch limits the check_pages to the places that are most likely to have problems. The check is made at the flip between the global array and the max save array, as well as when the size of the buffers changes and the self tests. This patch also removes the BUG_ON from check_pages and replaces it with a WARN_ON and disabling of the tracer. Signed-off-by: Steven Rostedt Cc: pq@iki.fi Cc: proski@gnu.org Cc: sandmann@redhat.com Cc: a.p.zijlstra@chello.nl Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3271916..0567f51 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -249,24 +249,32 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) tracing_record_cmdline(current); } +#define CHECK_COND(cond) \ + if (unlikely(cond)) { \ + tracing_disabled = 1; \ + WARN_ON(1); \ + return -1; \ + } + /** * check_pages - integrity check of trace buffers * * As a safty measure we check to make sure the data pages have not - * been corrupted. TODO: configure to disable this because it adds - * a bit of overhead. + * been corrupted. */ -void check_pages(struct trace_array_cpu *data) +int check_pages(struct trace_array_cpu *data) { struct page *page, *tmp; - BUG_ON(data->trace_pages.next->prev != &data->trace_pages); - BUG_ON(data->trace_pages.prev->next != &data->trace_pages); + CHECK_COND(data->trace_pages.next->prev != &data->trace_pages); + CHECK_COND(data->trace_pages.prev->next != &data->trace_pages); list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) { - BUG_ON(page->lru.next->prev != &page->lru); - BUG_ON(page->lru.prev->next != &page->lru); + CHECK_COND(page->lru.next->prev != &page->lru); + CHECK_COND(page->lru.prev->next != &page->lru); } + + return 0; } /** @@ -280,7 +288,6 @@ void *head_page(struct trace_array_cpu *data) { struct page *page; - check_pages(data); if (list_empty(&data->trace_pages)) return NULL; @@ -2566,7 +2573,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, { unsigned long val; char buf[64]; - int ret; + int i, ret; if (cnt >= sizeof(buf)) return -EINVAL; @@ -2635,8 +2642,15 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, trace_free_page(); } + /* check integrity */ + for_each_tracing_cpu(i) + check_pages(global_trace.data[i]); + filp->f_pos += cnt; + /* If check pages failed, return ENOMEM */ + if (tracing_disabled) + cnt = -ENOMEM; out: max_tr.entries = global_trace.entries; mutex_unlock(&trace_types_lock); diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 3877dd9..18c5423 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -28,6 +28,7 @@ trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data) page = list_entry(data->trace_pages.next, struct page, lru); entries = page_address(page); + check_pages(data); if (head_page(data) != entries) goto failed; -- cgit v0.10.2 From 4902f8849da6d2805bd291551a6dfd48f1b4f604 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:18 -0400 Subject: ftrace: move ftrace_special to trace.c Move the ftrace_special out of sched_switch to trace.c. Signed-off-by: Steven Rostedt Cc: pq@iki.fi Cc: proski@gnu.org Cc: sandmann@redhat.com Cc: a.p.zijlstra@chello.nl Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0567f51..583fe24 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -941,6 +941,30 @@ tracing_sched_wakeup_trace(struct trace_array *tr, trace_wake_up(); } +void +ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + struct trace_array *tr = &global_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int cpu; + + if (tracing_disabled || current_trace == &no_tracer || !tr->ctrl) + return; + + local_irq_save(flags); + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + + if (likely(disabled == 1)) + __trace_special(tr, data, arg1, arg2, arg3); + + atomic_dec(&data->disabled); + local_irq_restore(flags); +} + #ifdef CONFIG_FTRACE static void function_trace_call(unsigned long ip, unsigned long parent_ip) @@ -2941,8 +2965,6 @@ __init static int tracer_alloc_buffers(void) int ret = -ENOMEM; int i; - global_trace.ctrl = tracer_enabled; - /* TODO: make the number of buffers hot pluggable with CPUS */ tracing_nr_buffers = num_possible_cpus(); tracing_buffer_mask = cpu_possible_map; @@ -3012,6 +3034,7 @@ __init static int tracer_alloc_buffers(void) current_trace = &no_tracer; /* All seems OK, enable tracing */ + global_trace.ctrl = tracer_enabled; tracing_disabled = 0; return 0; diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index d25ffa5..798ec0d 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -125,30 +125,6 @@ wake_up_callback(void *probe_data, void *call_data, wakeup_func(probe_data, __rq, task, curr); } -void -ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) -{ - struct trace_array *tr = ctx_trace; - struct trace_array_cpu *data; - unsigned long flags; - long disabled; - int cpu; - - if (!tracer_enabled) - return; - - local_irq_save(flags); - cpu = raw_smp_processor_id(); - data = tr->data[cpu]; - disabled = atomic_inc_return(&data->disabled); - - if (likely(disabled == 1)) - __trace_special(tr, data, arg1, arg2, arg3); - - atomic_dec(&data->disabled); - local_irq_restore(flags); -} - static void sched_switch_reset(struct trace_array *tr) { int cpu; -- cgit v0.10.2 From 7e18d8e701b6798a5df11e0a16881a60ab1018b6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:19 -0400 Subject: ftrace: add function tracing to wake up tracing This patch adds function tracing to the functions that are called on the CPU of the task being traced. Signed-off-by: Steven Rostedt Cc: pq@iki.fi Cc: proski@gnu.org Cc: sandmann@redhat.com Cc: a.p.zijlstra@chello.nl Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 5d2fb48..bf7e91c 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -30,6 +30,69 @@ static DEFINE_SPINLOCK(wakeup_lock); static void __wakeup_reset(struct trace_array *tr); +#ifdef CONFIG_FTRACE +/* + * irqsoff uses its own tracer function to keep the overhead down: + */ +static void +wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) +{ + struct trace_array *tr = wakeup_trace; + struct trace_array_cpu *data; + unsigned long flags; + long disabled; + int resched; + int cpu; + + if (likely(!wakeup_task)) + return; + + resched = need_resched(); + preempt_disable_notrace(); + + cpu = raw_smp_processor_id(); + data = tr->data[cpu]; + disabled = atomic_inc_return(&data->disabled); + if (unlikely(disabled != 1)) + goto out; + + spin_lock_irqsave(&wakeup_lock, flags); + + if (unlikely(!wakeup_task)) + goto unlock; + + /* + * The task can't disappear because it needs to + * wake up first, and we have the wakeup_lock. + */ + if (task_cpu(wakeup_task) != cpu) + goto unlock; + + trace_function(tr, data, ip, parent_ip, flags); + + unlock: + spin_unlock_irqrestore(&wakeup_lock, flags); + + out: + atomic_dec(&data->disabled); + + /* + * To prevent recursion from the scheduler, if the + * resched flag was set before we entered, then + * don't reschedule. + */ + if (resched) + preempt_enable_no_resched_notrace(); + else + preempt_enable_notrace(); +} + +static struct ftrace_ops trace_ops __read_mostly = +{ + .func = wakeup_tracer_call, +}; +#endif /* CONFIG_FTRACE */ + /* * Should this new latency be reported/recorded? */ @@ -73,7 +136,7 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, if (next != wakeup_task) return; - /* The task we are waitng for is waking up */ + /* The task we are waiting for is waking up */ data = tr->data[wakeup_cpu]; /* disable local data, not wakeup_cpu data */ @@ -290,6 +353,7 @@ static void start_wakeup_tracer(struct trace_array *tr) smp_wmb(); tracer_enabled = 1; + register_ftrace_function(&trace_ops); return; fail_deprobe_wake_new: @@ -305,6 +369,7 @@ fail_deprobe: static void stop_wakeup_tracer(struct trace_array *tr) { tracer_enabled = 0; + unregister_ftrace_function(&trace_ops); marker_probe_unregister("kernel_sched_schedule", sched_switch_callback, &wakeup_trace); -- cgit v0.10.2 From da89a7a2536c46e76a1a4351a70a8b8417e5fed1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 00:22:20 -0400 Subject: ftrace: remove printks from irqsoff trace Printing out new max latencies was fine for the old RT tracer. But for mainline it is a bit messy. We also need to test if the run queue is locked before we can do the print. This means that we may not be printing out latencies if the run queue is locked on another CPU. This produces inconsistencies in the output. This patch simply removes the print altogether. Signed-off-by: Steven Rostedt Cc: pq@iki.fi Cc: proski@gnu.org Cc: sandmann@redhat.com Cc: a.p.zijlstra@chello.nl Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 761f3ec..421d6fe 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -165,22 +165,6 @@ check_critical_timing(struct trace_array *tr, update_max_tr_single(tr, current, cpu); - if (!runqueue_is_locked()) { - if (tracing_thresh) { - printk(KERN_INFO "(%16s-%-5d|#%d): %lu us critical" - " section violates %lu us threshold.\n", - current->comm, current->pid, - raw_smp_processor_id(), - latency, nsecs_to_usecs(tracing_thresh)); - } else { - printk(KERN_INFO "(%16s-%-5d|#%d): new %lu us" - " maximum-latency critical section.\n", - current->comm, current->pid, - raw_smp_processor_id(), - latency); - } - } - max_sequence++; out_unlock: -- cgit v0.10.2 From 41c52c0db9607e59f90da7da5309489fa06e887f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 11:46:33 -0400 Subject: ftrace: set_ftrace_notrace feature While debugging latencies in the RT kernel, I found that it would be nice to be able to filter away functions from the trace than just to filter on functions. I added a new interface to the debugfs tracing directory called set_ftrace_notrace When dynamic frace is enabled, this lets you filter away functions that will not be recorded in the trace. It is similar to adding 'notrace' to those functions but by doing it without recompiling the kernel. Here's how set_ftrace_filter and set_ftrace_notrace interact. Remember, if set_ftrace_filter is set, it removes all functions from the trace execpt for those listed in the set_ftrace_filter. set_ftrace_notrace will prevent those functions from being traced. If you were to set one function in both set_ftrace_filter and set_ftrace_notrace and that function was the same, then you would end up with an empty trace. the set of functions to trace is: set_ftrace_filter == empty then all functions not in set_ftrace_notrace else set of the set_ftrace_filter and not in set of set_ftrace_notrace. Signed-off-by: Steven Rostedt Signed-off-by: Thomas Gleixner diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 922e23d..ffbbd54 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -48,6 +48,7 @@ enum { FTRACE_FL_FAILED = (1 << 1), FTRACE_FL_FILTER = (1 << 2), FTRACE_FL_ENABLED = (1 << 3), + FTRACE_FL_NOTRACE = (1 << 4), }; struct dyn_ftrace { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 89bd9a6..2552454 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -170,7 +170,7 @@ static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu); static DEFINE_SPINLOCK(ftrace_shutdown_lock); static DEFINE_MUTEX(ftraced_lock); -static DEFINE_MUTEX(ftrace_filter_lock); +static DEFINE_MUTEX(ftrace_regex_lock); struct ftrace_page { struct ftrace_page *next; @@ -337,13 +337,12 @@ static void __ftrace_replace_code(struct dyn_ftrace *rec, unsigned char *old, unsigned char *new, int enable) { - unsigned long ip; + unsigned long ip, fl; int failed; ip = rec->ip; if (ftrace_filtered && enable) { - unsigned long fl; /* * If filtering is on: * @@ -356,13 +355,16 @@ __ftrace_replace_code(struct dyn_ftrace *rec, * If this record is not set to be filtered * and it is not enabled do nothing. * + * If this record is set not to trace then + * do nothing. + * * If this record is not set to be filtered and * it is enabled, disable it. */ fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED); if ((fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) || - (fl == 0)) + (fl == 0) || (rec->flags & FTRACE_FL_NOTRACE)) return; /* @@ -380,9 +382,17 @@ __ftrace_replace_code(struct dyn_ftrace *rec, } } else { - if (enable) + if (enable) { + /* + * If this record is set not to trace and is + * not enabled, do nothing. + */ + fl = rec->flags & (FTRACE_FL_NOTRACE | FTRACE_FL_ENABLED); + if (fl == FTRACE_FL_NOTRACE) + return; + new = ftrace_call_replace(ip, FTRACE_ADDR); - else + } else old = ftrace_call_replace(ip, FTRACE_ADDR); if (enable) { @@ -721,6 +731,7 @@ static int __init ftrace_dyn_table_alloc(void) enum { FTRACE_ITER_FILTER = (1 << 0), FTRACE_ITER_CONT = (1 << 1), + FTRACE_ITER_NOTRACE = (1 << 2), }; #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ @@ -754,7 +765,9 @@ t_next(struct seq_file *m, void *v, loff_t *pos) rec = &iter->pg->records[iter->idx++]; if ((rec->flags & FTRACE_FL_FAILED) || ((iter->flags & FTRACE_ITER_FILTER) && - !(rec->flags & FTRACE_FL_FILTER))) { + !(rec->flags & FTRACE_FL_FILTER)) || + ((iter->flags & FTRACE_ITER_NOTRACE) && + !(rec->flags & FTRACE_FL_NOTRACE))) { rec = NULL; goto retry; } @@ -847,22 +860,24 @@ int ftrace_avail_release(struct inode *inode, struct file *file) return 0; } -static void ftrace_filter_reset(void) +static void ftrace_filter_reset(int enable) { struct ftrace_page *pg; struct dyn_ftrace *rec; + unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; unsigned i; /* keep kstop machine from running */ preempt_disable(); - ftrace_filtered = 0; + if (enable) + ftrace_filtered = 0; pg = ftrace_pages_start; while (pg) { for (i = 0; i < pg->index; i++) { rec = &pg->records[i]; if (rec->flags & FTRACE_FL_FAILED) continue; - rec->flags &= ~FTRACE_FL_FILTER; + rec->flags &= ~type; } pg = pg->next; } @@ -870,7 +885,7 @@ static void ftrace_filter_reset(void) } static int -ftrace_filter_open(struct inode *inode, struct file *file) +ftrace_regex_open(struct inode *inode, struct file *file, int enable) { struct ftrace_iterator *iter; int ret = 0; @@ -882,15 +897,16 @@ ftrace_filter_open(struct inode *inode, struct file *file) if (!iter) return -ENOMEM; - mutex_lock(&ftrace_filter_lock); + mutex_lock(&ftrace_regex_lock); if ((file->f_mode & FMODE_WRITE) && !(file->f_flags & O_APPEND)) - ftrace_filter_reset(); + ftrace_filter_reset(enable); if (file->f_mode & FMODE_READ) { iter->pg = ftrace_pages_start; iter->pos = -1; - iter->flags = FTRACE_ITER_FILTER; + iter->flags = enable ? FTRACE_ITER_FILTER : + FTRACE_ITER_NOTRACE; ret = seq_open(file, &show_ftrace_seq_ops); if (!ret) { @@ -900,13 +916,25 @@ ftrace_filter_open(struct inode *inode, struct file *file) kfree(iter); } else file->private_data = iter; - mutex_unlock(&ftrace_filter_lock); + mutex_unlock(&ftrace_regex_lock); return ret; } +static int +ftrace_filter_open(struct inode *inode, struct file *file) +{ + return ftrace_regex_open(inode, file, 1); +} + +static int +ftrace_notrace_open(struct inode *inode, struct file *file) +{ + return ftrace_regex_open(inode, file, 0); +} + static ssize_t -ftrace_filter_read(struct file *file, char __user *ubuf, +ftrace_regex_read(struct file *file, char __user *ubuf, size_t cnt, loff_t *ppos) { if (file->f_mode & FMODE_READ) @@ -916,7 +944,7 @@ ftrace_filter_read(struct file *file, char __user *ubuf, } static loff_t -ftrace_filter_lseek(struct file *file, loff_t offset, int origin) +ftrace_regex_lseek(struct file *file, loff_t offset, int origin) { loff_t ret; @@ -936,13 +964,14 @@ enum { }; static void -ftrace_match(unsigned char *buff, int len) +ftrace_match(unsigned char *buff, int len, int enable) { char str[KSYM_SYMBOL_LEN]; char *search = NULL; struct ftrace_page *pg; struct dyn_ftrace *rec; int type = MATCH_FULL; + unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; unsigned i, match = 0, search_len = 0; for (i = 0; i < len; i++) { @@ -966,7 +995,8 @@ ftrace_match(unsigned char *buff, int len) /* keep kstop machine from running */ preempt_disable(); - ftrace_filtered = 1; + if (enable) + ftrace_filtered = 1; pg = ftrace_pages_start; while (pg) { for (i = 0; i < pg->index; i++) { @@ -997,7 +1027,7 @@ ftrace_match(unsigned char *buff, int len) break; } if (matched) - rec->flags |= FTRACE_FL_FILTER; + rec->flags |= flag; } pg = pg->next; } @@ -1005,8 +1035,8 @@ ftrace_match(unsigned char *buff, int len) } static ssize_t -ftrace_filter_write(struct file *file, const char __user *ubuf, - size_t cnt, loff_t *ppos) +ftrace_regex_write(struct file *file, const char __user *ubuf, + size_t cnt, loff_t *ppos, int enable) { struct ftrace_iterator *iter; char ch; @@ -1016,7 +1046,7 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, if (!cnt || cnt < 0) return 0; - mutex_lock(&ftrace_filter_lock); + mutex_lock(&ftrace_regex_lock); if (file->f_mode & FMODE_READ) { struct seq_file *m = file->private_data; @@ -1045,7 +1075,6 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, cnt--; } - if (isspace(ch)) { file->f_pos += read; ret = read; @@ -1072,7 +1101,7 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, if (isspace(ch)) { iter->filtered++; iter->buffer[iter->buffer_idx] = 0; - ftrace_match(iter->buffer, iter->buffer_idx); + ftrace_match(iter->buffer, iter->buffer_idx, enable); iter->buffer_idx = 0; } else iter->flags |= FTRACE_ITER_CONT; @@ -1082,11 +1111,39 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, ret = read; out: - mutex_unlock(&ftrace_filter_lock); + mutex_unlock(&ftrace_regex_lock); return ret; } +static ssize_t +ftrace_filter_write(struct file *file, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + return ftrace_regex_write(file, ubuf, cnt, ppos, 1); +} + +static ssize_t +ftrace_notrace_write(struct file *file, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + return ftrace_regex_write(file, ubuf, cnt, ppos, 0); +} + +static void +ftrace_set_regex(unsigned char *buf, int len, int reset, int enable) +{ + if (unlikely(ftrace_disabled)) + return; + + mutex_lock(&ftrace_regex_lock); + if (reset) + ftrace_filter_reset(enable); + if (buf) + ftrace_match(buf, len, enable); + mutex_unlock(&ftrace_regex_lock); +} + /** * ftrace_set_filter - set a function to filter on in ftrace * @buf - the string that holds the function filter text. @@ -1098,24 +1155,31 @@ ftrace_filter_write(struct file *file, const char __user *ubuf, */ void ftrace_set_filter(unsigned char *buf, int len, int reset) { - if (unlikely(ftrace_disabled)) - return; + ftrace_set_regex(buf, len, reset, 1); +} - mutex_lock(&ftrace_filter_lock); - if (reset) - ftrace_filter_reset(); - if (buf) - ftrace_match(buf, len); - mutex_unlock(&ftrace_filter_lock); +/** + * ftrace_set_notrace - set a function to not trace in ftrace + * @buf - the string that holds the function notrace text. + * @len - the length of the string. + * @reset - non zero to reset all filters before applying this filter. + * + * Notrace Filters denote which functions should not be enabled when tracing + * is enabled. If @buf is NULL and reset is set, all functions will be enabled + * for tracing. + */ +void ftrace_set_notrace(unsigned char *buf, int len, int reset) +{ + ftrace_set_regex(buf, len, reset, 0); } static int -ftrace_filter_release(struct inode *inode, struct file *file) +ftrace_regex_release(struct inode *inode, struct file *file, int enable) { struct seq_file *m = (struct seq_file *)file->private_data; struct ftrace_iterator *iter; - mutex_lock(&ftrace_filter_lock); + mutex_lock(&ftrace_regex_lock); if (file->f_mode & FMODE_READ) { iter = m->private; @@ -1126,7 +1190,7 @@ ftrace_filter_release(struct inode *inode, struct file *file) if (iter->buffer_idx) { iter->filtered++; iter->buffer[iter->buffer_idx] = 0; - ftrace_match(iter->buffer, iter->buffer_idx); + ftrace_match(iter->buffer, iter->buffer_idx, enable); } mutex_lock(&ftrace_sysctl_lock); @@ -1137,10 +1201,22 @@ ftrace_filter_release(struct inode *inode, struct file *file) mutex_unlock(&ftrace_sysctl_lock); kfree(iter); - mutex_unlock(&ftrace_filter_lock); + mutex_unlock(&ftrace_regex_lock); return 0; } +static int +ftrace_filter_release(struct inode *inode, struct file *file) +{ + return ftrace_regex_release(inode, file, 1); +} + +static int +ftrace_notrace_release(struct inode *inode, struct file *file) +{ + return ftrace_regex_release(inode, file, 0); +} + static struct file_operations ftrace_avail_fops = { .open = ftrace_avail_open, .read = seq_read, @@ -1150,12 +1226,20 @@ static struct file_operations ftrace_avail_fops = { static struct file_operations ftrace_filter_fops = { .open = ftrace_filter_open, - .read = ftrace_filter_read, + .read = ftrace_regex_read, .write = ftrace_filter_write, - .llseek = ftrace_filter_lseek, + .llseek = ftrace_regex_lseek, .release = ftrace_filter_release, }; +static struct file_operations ftrace_notrace_fops = { + .open = ftrace_notrace_open, + .read = ftrace_regex_read, + .write = ftrace_notrace_write, + .llseek = ftrace_regex_lseek, + .release = ftrace_notrace_release, +}; + /** * ftrace_force_update - force an update to all recording ftrace functions * @@ -1239,6 +1323,12 @@ static __init int ftrace_init_debugfs(void) if (!entry) pr_warning("Could not create debugfs " "'set_ftrace_filter' entry\n"); + + entry = debugfs_create_file("set_ftrace_notrace", 0644, d_tracer, + NULL, &ftrace_notrace_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'set_ftrace_notrace' entry\n"); return 0; } -- cgit v0.10.2 From 41bc8144d02028133bcd1d545023c6f49e8b2411 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 11:49:22 -0400 Subject: ftrace: fix up cmdline recording The new work with converting the trace hooks over to markers broke the command line recording of ftrace. This patch fixes it again. Signed-off-by: Steven Rostedt Cc: Peter Zijlstra Cc: Mathieu Desnoyers Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 583fe24..0feae23 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -652,9 +652,6 @@ static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; static int cmdline_idx; static DEFINE_SPINLOCK(trace_cmdline_lock); -/* trace in all context switches */ -atomic_t trace_record_cmdline_enabled __read_mostly; - /* temporary disable recording */ atomic_t trace_record_cmdline_disabled __read_mostly; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c460e85..6b8bd88 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -218,6 +218,8 @@ void trace_function(struct trace_array *tr, void tracing_start_function_trace(void); void tracing_stop_function_trace(void); +void tracing_start_cmdline_record(void); +void tracing_stop_cmdline_record(void); int register_tracer(struct tracer *type); void unregister_tracer(struct tracer *type); @@ -226,8 +228,6 @@ extern unsigned long nsecs_to_usecs(unsigned long nsecs); extern unsigned long tracing_max_latency; extern unsigned long tracing_thresh; -extern atomic_t trace_record_cmdline_enabled; - void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu); diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 0a08465..7ee7dcd 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -29,14 +29,14 @@ static void function_reset(struct trace_array *tr) static void start_function_trace(struct trace_array *tr) { function_reset(tr); - atomic_inc(&trace_record_cmdline_enabled); + tracing_start_cmdline_record(); tracing_start_function_trace(); } static void stop_function_trace(struct trace_array *tr) { tracing_stop_function_trace(); - atomic_dec(&trace_record_cmdline_enabled); + tracing_stop_cmdline_record(); } static void function_trace_init(struct trace_array *tr) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 798ec0d..c16935d 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -29,6 +29,9 @@ sched_switch_func(void *private, void *__rq, struct task_struct *prev, long disabled; int cpu; + tracing_record_cmdline(prev); + tracing_record_cmdline(next); + if (!tracer_enabled) return; @@ -63,8 +66,6 @@ sched_switch_callback(void *probe_data, void *call_data, prev = va_arg(*args, typeof(prev)); next = va_arg(*args, typeof(next)); - tracing_record_cmdline(prev); - /* * If tracer_switch_func only points to the local * switch func, it still needs the ptr passed to it. @@ -213,18 +214,26 @@ void tracing_stop_sched_switch(void) tracing_sched_unregister(); } +void tracing_start_cmdline_record(void) +{ + tracing_start_sched_switch(); +} + +void tracing_stop_cmdline_record(void) +{ + tracing_stop_sched_switch(); +} + static void start_sched_trace(struct trace_array *tr) { sched_switch_reset(tr); - atomic_inc(&trace_record_cmdline_enabled); tracer_enabled = 1; - tracing_start_sched_switch(); + tracing_start_cmdline_record(); } static void stop_sched_trace(struct trace_array *tr) { - tracing_stop_sched_switch(); - atomic_dec(&trace_record_cmdline_enabled); + tracing_stop_cmdline_record(); tracer_enabled = 0; } -- cgit v0.10.2 From ccbfac2923c9febaeaf07a50054027a92b502718 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 22 May 2008 14:31:07 -0400 Subject: ftrace: powerpc clean ups This patch cleans up the ftrace code in PowerPC based on the comments from Michael Ellerman. Signed-off-by: Steven Rostedt Cc: Michael Ellerman Cc: proski@gnu.org Cc: a.p.zijlstra@chello.nl Cc: Pekka Paalanen Cc: Steven Rostedt Cc: linuxppc-dev@ozlabs.org Cc: Soeren Sandmann Pedersen Cc: paulus@samba.org Signed-off-by: Thomas Gleixner diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0e62218..3b1dd29 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -1129,18 +1129,11 @@ _GLOBAL(_mcount) stw r5, 8(r1) LOAD_REG_ADDR(r5, ftrace_trace_function) -#if 0 - mtctr r3 - mr r1, r5 - bctrl -#endif lwz r5,0(r5) -#if 1 + mtctr r5 bctrl -#else - bl ftrace_stub -#endif + nop lwz r6, 8(r1) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 5a4993f..69ed412 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -51,10 +51,16 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) { static unsigned int op; + /* + * It would be nice to just use create_function_call, but that will + * update the code itself. Here we need to just return the + * instruction that is going to be modified, without modifying the + * code. + */ addr = GET_ADDR(addr); /* Set to "bl addr" */ - op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffe); + op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc); /* * No locking needed, this must be called via kstop_machine diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index cf6b5a7..4300db5 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -43,6 +43,7 @@ #include #include #include +#include #ifdef CONFIG_PPC32 extern void transfer_to_handler(void); @@ -68,6 +69,10 @@ EXPORT_SYMBOL(single_step_exception); EXPORT_SYMBOL(sys_sigreturn); #endif +#ifdef CONFIG_FTRACE +EXPORT_SYMBOL(_mcount); +#endif + EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strcat); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 22f8e2b..19e8fcb 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -47,11 +47,6 @@ #include #endif -#ifdef CONFIG_FTRACE -extern void _mcount(void); -EXPORT_SYMBOL(_mcount); -#endif - extern void bootx_init(unsigned long r4, unsigned long phys); int boot_cpuid; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 277bf18..098fd96 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -85,11 +85,6 @@ struct ppc64_caches ppc64_caches = { }; EXPORT_SYMBOL_GPL(ppc64_caches); -#ifdef CONFIG_FTRACE -extern void _mcount(void); -EXPORT_SYMBOL(_mcount); -#endif - /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. diff --git a/include/asm-powerpc/ftrace.h b/include/asm-powerpc/ftrace.h new file mode 100644 index 0000000..b1bfa70 --- /dev/null +++ b/include/asm-powerpc/ftrace.h @@ -0,0 +1,6 @@ +#ifndef _ASM_POWERPC_FTRACE +#define _ASM_POWERPC_FTRACE + +extern void _mcount(void); + +#endif -- cgit v0.10.2 From ffdaa3582b6b39d625d585d07e329ffdc925e971 Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 24 May 2008 23:45:02 +0530 Subject: ftrace: safe traversal of ftrace_hash hlist Hi Steven, I noticed that concurrent instances of ftrace_record_ip() have a race between ftrace_hash list traversal during ftrace_ip_in_hash() (before acquiring ftrace_shutdown_lock) and ftrace_add_hash(). If it's so then this should fix it. Signed-off-by: Abhishek Sagar Cc: rostedt@goodmis.org Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 2552454..9b7c54f 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -201,7 +201,7 @@ ftrace_ip_in_hash(unsigned long ip, unsigned long key) struct hlist_node *t; int found = 0; - hlist_for_each_entry(p, t, &ftrace_hash[key], node) { + hlist_for_each_entry_rcu(p, t, &ftrace_hash[key], node) { if (p->ip == ip) { found = 1; break; @@ -214,7 +214,7 @@ ftrace_ip_in_hash(unsigned long ip, unsigned long key) static inline void ftrace_add_hash(struct dyn_ftrace *node, unsigned long key) { - hlist_add_head(&node->node, &ftrace_hash[key]); + hlist_add_head_rcu(&node->node, &ftrace_hash[key]); } static void ftrace_free_rec(struct dyn_ftrace *rec) -- cgit v0.10.2 From 492a7ea5bcf263ee02a9eb6a3ab0222a1946fade Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sun, 25 May 2008 00:10:04 +0530 Subject: ftrace: fix updating of ftrace_update_cnt Hi Ingo/Steven, Ftrace currently maintains an update count which includes false updates, i.e, updates which failed. If anything, such failures should be tracked by some separate variable, but this patch provides a minimal fix. Signed-off-by: Abhishek Sagar Cc: rostedt@goodmis.org Signed-off-by: Thomas Gleixner diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 9b7c54f..1843edc 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -453,7 +453,7 @@ static void ftrace_shutdown_replenish(void) ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); } -static void +static int ftrace_code_disable(struct dyn_ftrace *rec) { unsigned long ip; @@ -469,7 +469,9 @@ ftrace_code_disable(struct dyn_ftrace *rec) if (failed) { rec->flags |= FTRACE_FL_FAILED; ftrace_free_rec(rec); + return 0; } + return 1; } static int __ftrace_modify_code(void *data) @@ -617,8 +619,8 @@ static int __ftrace_update_code(void *ignore) /* all CPUS are stopped, we are safe to modify code */ hlist_for_each_entry(p, t, &head, node) { - ftrace_code_disable(p); - ftrace_update_cnt++; + if (ftrace_code_disable(p)) + ftrace_update_cnt++; } } -- cgit v0.10.2 From d031476408ae0f5196e3c579f519dfdefb099b67 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 23 May 2008 14:41:19 +0100 Subject: hrtimer: remove warning in hres_timers_resume hres_timers_resume() warns if there appears to be more than one cpu online. This warning makes sense when the suspend/resume mechanism offlines all cpus but one during the suspend/resume process. However, Xen suspend does not need to offline the other cpus; it merely keeps them tied up in stop_machine() while the virtual machine is suspended. The warning hres_timers_resume issues is therefore spurious. Signed-off-by: Jeremy Fitzhardinge Cc: xen-devel Cc: "Rafael J. Wysocki" Signed-off-by: Thomas Gleixner diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 421be5f..493c4b8 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -632,8 +632,6 @@ void clock_was_set(void) */ void hres_timers_resume(void) { - WARN_ON_ONCE(num_online_cpus() > 1); - /* Retrigger the CPU local events: */ retrigger_next_event(NULL); } -- cgit v0.10.2 From 900cfa46191a7d87cf1891924cb90499287fd235 Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Thu, 22 May 2008 19:25:11 -0300 Subject: hrtimer: Remove unused variables in ktime_divns() The variables dns and inc are not used, remove them. Signed-off-by: Carlos R. Mafra Cc: tglx@linutronix.de Signed-off-by: Thomas Gleixner diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 493c4b8..635739d 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -300,11 +300,10 @@ EXPORT_SYMBOL_GPL(ktime_sub_ns); */ u64 ktime_divns(const ktime_t kt, s64 div) { - u64 dclc, inc, dns; + u64 dclc; int sft = 0; - dclc = dns = ktime_to_ns(kt); - inc = div; + dclc = ktime_to_ns(kt); /* Make sure the divisor is less than 2^32: */ while (div >> 32) { sft++; -- cgit v0.10.2 From 62b126315369d52e40ad604e1798ff5b6265287e Mon Sep 17 00:00:00 2001 From: Chris Mennie Date: Mon, 19 May 2008 16:21:33 +0200 Subject: [ALSA] usb-audio - Support for Roland SonicCell sound module Added entry into usbquirks.h to recognize Roland SonicCell sound module by mostly duplicating the entry for the Roland SH-201. USB MIDI works just fine, though the USB audio is a little unreliable (but still works well enough). Signed-off-by: Chris Mennie Signed-off-by: Takashi Iwai diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 82a8d14..b7ab3ee 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -1379,6 +1379,39 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, +{ + /* Roland SonicCell */ + USB_DEVICE(0x0582, 0x00c2), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Roland", + .product_name = "SonicCell", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } + } + } +}, + + /* Guillemot devices */ { /* -- cgit v0.10.2 From a72e72469a166c825196c3f20dabd352877fec2b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 01:06:55 +0300 Subject: [ALSA] remove CVS keywords This patch removes CVS keywords that weren't updated for a long time from comments. Signed-off-by: Adrian Bunk Signed-off-by: Takashi Iwai diff --git a/include/sound/uda1341.h b/include/sound/uda1341.h index 2e564bf..110d5dc 100644 --- a/include/sound/uda1341.h +++ b/include/sound/uda1341.h @@ -15,8 +15,6 @@ * features support */ -/* $Id: uda1341.h,v 1.8 2005/11/17 14:17:21 tiwai Exp $ */ - #define UDA1341_ALSA_NAME "snd-uda1341" /* diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index 0eff33c..faeddf3 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c @@ -21,8 +21,6 @@ * merged HAL layer (patches from Brian) */ -/* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */ - /*************************************************************************************************** * * To understand what Alsa Drivers should be doing look at "Writing an Alsa Driver" by Takashi Iwai diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c index bfa5d2c..1f4942e 100644 --- a/sound/i2c/l3/uda1341.c +++ b/sound/i2c/l3/uda1341.c @@ -17,8 +17,6 @@ * 2002-05-12 Tomas Kasparek another code cleanup */ -/* $Id: uda1341.c,v 1.18 2005/11/17 14:17:21 tiwai Exp $ */ - #include #include #include diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c index bc212f4..e291aa5 100644 --- a/sound/pci/au88x0/au88x0_game.c +++ b/sound/pci/au88x0/au88x0_game.c @@ -1,6 +1,4 @@ /* - * $Id: au88x0_game.c,v 1.9 2003/09/22 03:51:28 mjander Exp $ - * * Manuel Jander. * * Based on the work of: -- cgit v0.10.2 From 06b5fb97cec1a3ca61d10164118b00fe98a6a866 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 00:59:35 +0300 Subject: sound: sound/oss/: remove CVS keywords This patch removes CVS keywords that weren't updated for a long time from comments. Signed-off-by: Adrian Bunk Signed-off-by: Takashi Iwai diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c index ba38d62..e4282d9 100644 --- a/sound/oss/msnd.c +++ b/sound/oss/msnd.c @@ -20,8 +20,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd.c,v 1.17 1999/03/21 16:50:09 andrewtv Exp $ - * ********************************************************************/ #include diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h index d0ca582..61b3955 100644 --- a/sound/oss/msnd.h +++ b/sound/oss/msnd.h @@ -24,8 +24,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd.h,v 1.36 1999/03/21 17:05:42 andrewtv Exp $ - * ********************************************************************/ #ifndef __MSND_H #define __MSND_H diff --git a/sound/oss/msnd_classic.h b/sound/oss/msnd_classic.h index 7ffea52..1a17dde 100644 --- a/sound/oss/msnd_classic.h +++ b/sound/oss/msnd_classic.h @@ -24,8 +24,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd_classic.h,v 1.10 1999/03/21 17:36:09 andrewtv Exp $ - * ********************************************************************/ #ifndef __MSND_CLASSIC_H #define __MSND_CLASSIC_H diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index f1f49eb..bf27e00 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c @@ -29,13 +29,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $ - * * 12-3-2000 Modified IO port validation Steve Sycamore * - * - * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $ - * ********************************************************************/ #include diff --git a/sound/oss/msnd_pinnacle.h b/sound/oss/msnd_pinnacle.h index cce9114..c18d66c 100644 --- a/sound/oss/msnd_pinnacle.h +++ b/sound/oss/msnd_pinnacle.h @@ -24,8 +24,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd_pinnacle.h,v 1.11 1999/03/21 17:36:09 andrewtv Exp $ - * ********************************************************************/ #ifndef __MSND_PINNACLE_H #define __MSND_PINNACLE_H -- cgit v0.10.2 From 89fe5117928b2c1272c9376362131ded561c91ad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 May 2008 16:10:37 +0200 Subject: sound: Convert to menuconfig Convert menu in sound Kconfig files to menuconfig and if. Signed-off-by: Takashi Iwai diff --git a/sound/Kconfig b/sound/Kconfig index 4247406..a37bee0 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -1,11 +1,9 @@ # sound/Config.in # -menu "Sound" - depends on HAS_IOMEM - -config SOUND +menuconfig SOUND tristate "Sound card support" + depends on HAS_IOMEM help If you have a sound card in your computer, i.e. if it can say more than an occasional beep, say Y. Be sure to have all the information @@ -28,22 +26,22 @@ config SOUND and read ; the module will be called soundcore. +if SOUND + source "sound/oss/dmasound/Kconfig" if !M68K -menu "Advanced Linux Sound Architecture" - depends on SOUND!=n - -config SND +menuconfig SND tristate "Advanced Linux Sound Architecture" - depends on SOUND help Say 'Y' or 'M' to enable ALSA (Advanced Linux Sound Architecture), the new base sound system. For more information, see +if SND + source "sound/core/Kconfig" source "sound/drivers/Kconfig" @@ -58,9 +56,7 @@ source "sound/aoa/Kconfig" source "sound/arm/Kconfig" -if SPI source "sound/spi/Kconfig" -endif source "sound/mips/Kconfig" @@ -80,22 +76,20 @@ source "sound/parisc/Kconfig" source "sound/soc/Kconfig" -endmenu +endif # SND -menu "Open Sound System" - depends on SOUND!=n - -config SOUND_PRIME +menuconfig SOUND_PRIME tristate "Open Sound System (DEPRECATED)" - depends on SOUND help Say 'Y' or 'M' to enable Open Sound System drivers. +if SOUND_PRIME + source "sound/oss/Kconfig" -endmenu +endif # SOUND_PRIME -endif +endif # !M68K config AC97_BUS tristate @@ -105,4 +99,4 @@ config AC97_BUS sound although they're sharing the AC97 bus. Concerned drivers should "select" this. -endmenu +endif # SOUND diff --git a/sound/aoa/Kconfig b/sound/aoa/Kconfig index 5d5813c..c081e18 100644 --- a/sound/aoa/Kconfig +++ b/sound/aoa/Kconfig @@ -1,18 +1,17 @@ -menu "Apple Onboard Audio driver" - depends on SND!=n && PPC_PMAC - -config SND_AOA +menuconfig SND_AOA tristate "Apple Onboard Audio driver" - depends on SND + depends on PPC_PMAC select SND_PCM ---help--- This option enables the new driver for the various Apple Onboard Audio components. +if SND_AOA + source "sound/aoa/fabrics/Kconfig" source "sound/aoa/codecs/Kconfig" source "sound/aoa/soundbus/Kconfig" -endmenu +endif # SND_AOA diff --git a/sound/aoa/codecs/Kconfig b/sound/aoa/codecs/Kconfig index d5fbd60..808eb11 100644 --- a/sound/aoa/codecs/Kconfig +++ b/sound/aoa/codecs/Kconfig @@ -1,6 +1,5 @@ config SND_AOA_ONYX tristate "support Onyx chip" - depends on SND_AOA select I2C select I2C_POWERMAC ---help--- @@ -10,7 +9,6 @@ config SND_AOA_ONYX #config SND_AOA_TOPAZ # tristate "support Topaz chips" -# depends on SND_AOA # ---help--- # This option enables support for the Topaz (CS84xx) # codec chips found in the latest Apple machines, @@ -19,7 +17,6 @@ config SND_AOA_ONYX config SND_AOA_TAS tristate "support TAS chips" - depends on SND_AOA select I2C select I2C_POWERMAC ---help--- @@ -29,7 +26,6 @@ config SND_AOA_TAS config SND_AOA_TOONIE tristate "support Toonie chip" - depends on SND_AOA ---help--- This option enables support for the toonie codec found in the Mac Mini. If you have a Mac Mini and diff --git a/sound/aoa/fabrics/Kconfig b/sound/aoa/fabrics/Kconfig index 50d7021..3ca475a 100644 --- a/sound/aoa/fabrics/Kconfig +++ b/sound/aoa/fabrics/Kconfig @@ -1,6 +1,5 @@ config SND_AOA_FABRIC_LAYOUT tristate "layout-id fabric" - depends on SND_AOA select SND_AOA_SOUNDBUS select SND_AOA_SOUNDBUS_I2S ---help--- diff --git a/sound/aoa/soundbus/Kconfig b/sound/aoa/soundbus/Kconfig index 7368b7d..839d113 100644 --- a/sound/aoa/soundbus/Kconfig +++ b/sound/aoa/soundbus/Kconfig @@ -1,6 +1,5 @@ config SND_AOA_SOUNDBUS tristate "Apple Soundbus support" - depends on SOUND select SND_PCM ---help--- This option enables the generic driver for the soundbus diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig index 2e4a5e0..351e19e 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig @@ -1,11 +1,19 @@ # ALSA ARM drivers -menu "ALSA ARM devices" - depends on SND!=n && ARM +menuconfig SND_ARM + bool "ARM sound devices" + depends on ARM + default y + help + Support for sound devices specific to ARM architectures. + Drivers that are implemented on ASoC can be found in + "ALSA for SoC audio support" section. + +if SND_ARM config SND_SA11XX_UDA1341 tristate "SA11xx UDA1341TS driver (iPaq H3600)" - depends on ARCH_SA1100 && SND && L3 + depends on ARCH_SA1100 && L3 select SND_PCM help Say Y here if you have a Compaq iPaq H3x00 handheld computer @@ -16,7 +24,7 @@ config SND_SA11XX_UDA1341 config SND_ARMAACI tristate "ARM PrimeCell PL041 AC Link support" - depends on SND && ARM_AMBA + depends on ARM_AMBA select SND_PCM select SND_AC97_CODEC @@ -26,11 +34,12 @@ config SND_PXA2XX_PCM config SND_PXA2XX_AC97 tristate "AC97 driver for the Intel PXA2xx chip" - depends on ARCH_PXA && SND + depends on ARCH_PXA select SND_PXA2XX_PCM select SND_AC97_CODEC help Say Y or M if you want to support any AC97 codec attached to the PXA2xx AC97 interface. -endmenu +endif # SND_ARM + diff --git a/sound/core/Kconfig b/sound/core/Kconfig index a8d71c6..db21113 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -1,24 +1,19 @@ # ALSA soundcard-configuration config SND_TIMER tristate - depends on SND config SND_PCM tristate select SND_TIMER - depends on SND config SND_HWDEP tristate - depends on SND config SND_RAWMIDI tristate - depends on SND config SND_SEQUENCER tristate "Sequencer support" - depends on SND select SND_TIMER help Say Y or M to enable MIDI sequencer and router support. This @@ -44,11 +39,9 @@ config SND_SEQ_DUMMY config SND_OSSEMUL bool - depends on SND config SND_MIXER_OSS tristate "OSS Mixer API" - depends on SND select SND_OSSEMUL help To enable OSS mixer API emulation (/dev/mixer*), say Y here @@ -61,7 +54,6 @@ config SND_MIXER_OSS config SND_PCM_OSS tristate "OSS PCM (digital audio) API" - depends on SND select SND_OSSEMUL select SND_PCM help @@ -84,7 +76,7 @@ config SND_PCM_OSS_PLUGINS config SND_SEQUENCER_OSS bool "OSS Sequencer API" - depends on SND && SND_SEQUENCER + depends on SND_SEQUENCER select SND_OSSEMUL help Say Y here to enable OSS sequencer emulation (both @@ -98,7 +90,7 @@ config SND_SEQUENCER_OSS config SND_RTCTIMER tristate "RTC Timer support" - depends on SND && RTC + depends on RTC select SND_TIMER help Say Y here to enable RTC timer support for ALSA. ALSA uses @@ -123,7 +115,6 @@ config SND_SEQ_RTCTIMER_DEFAULT config SND_DYNAMIC_MINORS bool "Dynamic device file minor numbers" - depends on SND help If you say Y here, the minor numbers of ALSA device files in /dev/snd/ are allocated dynamically. This allows you to have @@ -134,7 +125,6 @@ config SND_DYNAMIC_MINORS config SND_SUPPORT_OLD_API bool "Support old ALSA API" - depends on SND default y help Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 @@ -142,7 +132,7 @@ config SND_SUPPORT_OLD_API config SND_VERBOSE_PROCFS bool "Verbose procfs contents" - depends on SND && PROC_FS + depends on PROC_FS default y help Say Y here to include code for verbose procfs contents (provides @@ -151,7 +141,6 @@ config SND_VERBOSE_PROCFS config SND_VERBOSE_PRINTK bool "Verbose printk" - depends on SND help Say Y here to enable verbose log messages. These messages will help to identify source file and position containing @@ -161,7 +150,6 @@ config SND_VERBOSE_PRINTK config SND_DEBUG bool "Debug" - depends on SND help Say Y here to enable ALSA debug code. @@ -184,4 +172,3 @@ config SND_PCM_XRUN_DEBUG config SND_VMASTER bool - depends on SND diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 159137b..79b4d3f 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig @@ -1,15 +1,41 @@ -# ALSA generic drivers +config SND_MPU401_UART + tristate + select SND_RAWMIDI -menu "Generic devices" - depends on SND!=n +config SND_OPL3_LIB + tristate + select SND_TIMER + select SND_HWDEP +config SND_OPL4_LIB + tristate + select SND_TIMER + select SND_HWDEP + +config SND_VX_LIB + tristate + select SND_HWDEP + select SND_PCM + +config SND_AC97_CODEC + tristate + select SND_PCM + select AC97_BUS + select SND_VMASTER + +menuconfig SND_DRIVERS + bool "Generic sound devices" + default y + help + Support for generic sound devices. + +if SND_DRIVERS config SND_PCSP tristate "PC-Speaker support (READ HELP!)" depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS depends on INPUT depends on EXPERIMENTAL - depends on SND select SND_PCM help If you don't have a sound card in your computer, you can include a @@ -35,34 +61,8 @@ config SND_PCSP Say M if you don't. Say Y only if you really know what you do. -config SND_MPU401_UART - tristate - select SND_RAWMIDI - -config SND_OPL3_LIB - tristate - select SND_TIMER - select SND_HWDEP - -config SND_OPL4_LIB - tristate - select SND_TIMER - select SND_HWDEP - -config SND_VX_LIB - tristate - select SND_HWDEP - select SND_PCM - -config SND_AC97_CODEC - tristate - select SND_PCM - select AC97_BUS - select SND_VMASTER - config SND_DUMMY tristate "Dummy (/dev/null) soundcard" - depends on SND select SND_PCM help Say Y here to include the dummy driver. This driver does @@ -91,7 +91,6 @@ config SND_VIRMIDI config SND_MTPAV tristate "MOTU MidiTimePiece AV multiport MIDI" - depends on SND select SND_RAWMIDI help To use a MOTU MidiTimePiece AV multiport MIDI adapter @@ -103,7 +102,7 @@ config SND_MTPAV config SND_MTS64 tristate "ESI Miditerminal 4140 driver" - depends on SND && PARPORT + depends on PARPORT select SND_RAWMIDI help The ESI Miditerminal 4140 is a 4 In 4 Out MIDI Interface with @@ -116,7 +115,6 @@ config SND_MTS64 config SND_SERIAL_U16550 tristate "UART16550 serial MIDI driver" - depends on SND select SND_RAWMIDI help To include support for MIDI serial port interfaces, say Y here @@ -132,7 +130,6 @@ config SND_SERIAL_U16550 config SND_MPU401 tristate "Generic MPU-401 UART driver" - depends on SND select SND_MPU401_UART help Say Y here to include support for MIDI ports compatible with @@ -143,7 +140,7 @@ config SND_MPU401 config SND_PORTMAN2X4 tristate "Portman 2x4 driver" - depends on SND && PARPORT + depends on PARPORT select SND_RAWMIDI help Say Y here to include support for Midiman Portman 2x4 parallel @@ -154,7 +151,7 @@ config SND_PORTMAN2X4 config SND_ML403_AC97CR tristate "Xilinx ML403 AC97 Controller Reference" - depends on SND && XILINX_VIRTEX + depends on XILINX_VIRTEX select SND_AC97_CODEC help Say Y here to include support for the @@ -164,4 +161,4 @@ config SND_ML403_AC97CR To compile this driver as a module, choose M here: the module will be called snd-ml403_ac97cr. -endmenu +endif # SND_DRIVERS diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 2639a6a..4575ba8 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -21,12 +21,17 @@ config SND_SB16_DSP select SND_PCM select SND_SB_COMMON -menu "ISA devices" - depends on SND!=n && ISA && ISA_DMA_API +menuconfig SND_ISA + bool "ISA sound devices" + depends on ISA && ISA_DMA_API + default y + help + Support for sound devices connected via the ISA bus. + +if SND_ISA config SND_ADLIB tristate "AdLib FM card" - depends on SND select SND_OPL3_LIB help Say Y here to include support for AdLib FM cards. @@ -36,7 +41,7 @@ config SND_ADLIB config SND_AD1816A tristate "Analog Devices SoundPort AD1816A" - depends on SND && PNP && ISA + depends on PNP select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART @@ -50,7 +55,6 @@ config SND_AD1816A config SND_AD1848 tristate "Generic AD1848/CS4248 driver" - depends on SND select SND_AD1848_LIB help Say Y here to include support for AD1848 (Analog Devices) or @@ -64,7 +68,7 @@ config SND_AD1848 config SND_ALS100 tristate "Avance Logic ALS100/ALS120" - depends on SND && PNP && ISA + depends on PNP select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART @@ -78,7 +82,7 @@ config SND_ALS100 config SND_AZT2320 tristate "Aztech Systems AZT2320" - depends on SND && PNP && ISA + depends on PNP select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART @@ -92,7 +96,6 @@ config SND_AZT2320 config SND_CMI8330 tristate "C-Media CMI8330" - depends on SND select SND_AD1848_LIB select SND_SB16_DSP help @@ -104,7 +107,6 @@ config SND_CMI8330 config SND_CS4231 tristate "Generic Cirrus Logic CS4231 driver" - depends on SND select SND_MPU401_UART select SND_CS4231_LIB help @@ -116,7 +118,6 @@ config SND_CS4231 config SND_CS4232 tristate "Generic Cirrus Logic CS4232 driver" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -129,7 +130,6 @@ config SND_CS4232 config SND_CS4236 tristate "Generic Cirrus Logic CS4236+ driver" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -142,7 +142,7 @@ config SND_CS4236 config SND_DT019X tristate "Diamond Technologies DT-019X, Avance Logic ALS-007" - depends on SND && PNP && ISA + depends on PNP select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART @@ -156,7 +156,7 @@ config SND_DT019X config SND_ES968 tristate "Generic ESS ES968 driver" - depends on SND && PNP && ISA + depends on PNP select ISAPNP select SND_MPU401_UART select SND_SB8_DSP @@ -168,7 +168,6 @@ config SND_ES968 config SND_ES1688 tristate "Generic ESS ES688/ES1688 driver" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM @@ -181,7 +180,6 @@ config SND_ES1688 config SND_ES18XX tristate "Generic ESS ES18xx driver" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM @@ -193,7 +191,7 @@ config SND_ES18XX config SND_SC6000 tristate "Gallant SC-6000, Audio Excel DSP 16" - depends on SND && HAS_IOPORT + depends on HAS_IOPORT select SND_AD1848_LIB select SND_OPL3_LIB select SND_MPU401_UART @@ -209,7 +207,6 @@ config SND_GUS_SYNTH config SND_GUSCLASSIC tristate "Gravis UltraSound Classic" - depends on SND select SND_RAWMIDI select SND_PCM select SND_GUS_SYNTH @@ -222,7 +219,6 @@ config SND_GUSCLASSIC config SND_GUSEXTREME tristate "Gravis UltraSound Extreme" - depends on SND select SND_HWDEP select SND_MPU401_UART select SND_PCM @@ -236,7 +232,6 @@ config SND_GUSEXTREME config SND_GUSMAX tristate "Gravis UltraSound MAX" - depends on SND select SND_RAWMIDI select SND_CS4231_LIB select SND_GUS_SYNTH @@ -249,7 +244,7 @@ config SND_GUSMAX config SND_INTERWAVE tristate "AMD InterWave, Gravis UltraSound PnP" - depends on SND && PNP && ISA + depends on PNP select SND_RAWMIDI select SND_CS4231_LIB select SND_GUS_SYNTH @@ -263,7 +258,7 @@ config SND_INTERWAVE config SND_INTERWAVE_STB tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)" - depends on SND && PNP && ISA + depends on PNP select SND_RAWMIDI select SND_CS4231_LIB select SND_GUS_SYNTH @@ -277,7 +272,6 @@ config SND_INTERWAVE_STB config SND_OPL3SA2 tristate "Yamaha OPL3-SA2/SA3" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -290,7 +284,6 @@ config SND_OPL3SA2 config SND_OPTI92X_AD1848 tristate "OPTi 82C92x - AD1848" - depends on SND select SND_OPL3_LIB select SND_OPL4_LIB select SND_MPU401_UART @@ -304,7 +297,6 @@ config SND_OPTI92X_AD1848 config SND_OPTI92X_CS4231 tristate "OPTi 82C92x - CS4231" - depends on SND select SND_OPL3_LIB select SND_OPL4_LIB select SND_MPU401_UART @@ -318,7 +310,6 @@ config SND_OPTI92X_CS4231 config SND_OPTI93X tristate "OPTi 82C93x" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM @@ -331,7 +322,6 @@ config SND_OPTI93X config SND_MIRO tristate "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" - depends on SND select SND_OPL4_LIB select SND_CS4231_LIB select SND_MPU401_UART @@ -345,7 +335,6 @@ config SND_MIRO config SND_SB8 tristate "Sound Blaster 1.0/2.0/Pro (8-bit)" - depends on SND select SND_OPL3_LIB select SND_RAWMIDI select SND_SB8_DSP @@ -358,7 +347,6 @@ config SND_SB8 config SND_SB16 tristate "Sound Blaster 16 (PnP)" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_SB16_DSP @@ -371,7 +359,6 @@ config SND_SB16 config SND_SBAWE tristate "Sound Blaster AWE (32,64) (PnP)" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_SB16_DSP @@ -402,7 +389,6 @@ config SND_SB16_CSP_FIRMWARE_IN_KERNEL config SND_SGALAXY tristate "Aztech Sound Galaxy" - depends on SND select SND_AD1848_LIB help Say Y here to include support for Aztech Sound Galaxy @@ -413,7 +399,6 @@ config SND_SGALAXY config SND_SSCAPE tristate "Ensoniq SoundScape PnP driver" - depends on SND select SND_HWDEP select SND_MPU401_UART select SND_CS4231_LIB @@ -426,7 +411,6 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" - depends on SND select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART @@ -448,4 +432,5 @@ config SND_WAVEFRONT_FIRMWARE_IN_KERNEL you need to install the firmware files from the alsa-firmware package. -endmenu +endif # SND_ISA + diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index 531f8ba..bb26f6c 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig @@ -1,15 +1,21 @@ # ALSA MIPS drivers -menu "ALSA MIPS devices" - depends on SND!=n && MIPS +menuconfig SND_MIPS + bool "MIPS sound devices" + depends on MIPS + default y + help + Support for sound devices of MIPS architectures. + +if SND_MIPS config SND_AU1X00 tristate "Au1x00 AC97 Port Driver" - depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND + depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 select SND_PCM select SND_AC97_CODEC help ALSA Sound driver for the Au1x00's AC97 port. -endmenu +endif # SND_MIPS diff --git a/sound/parisc/Kconfig b/sound/parisc/Kconfig index a5a7f9d..9b61d95 100644 --- a/sound/parisc/Kconfig +++ b/sound/parisc/Kconfig @@ -1,15 +1,20 @@ # ALSA PA-RISC drivers -menu "GSC devices" - depends on SND!=n && GSC +menuconfig SND_GSC + bool "GSC sound devices" + depends on GSC + default y + help + Support for GSC sound devices on PA-RISC architectures. + +if SND_GSC config SND_HARMONY tristate "Harmony/Vivace sound chip" - depends on SND select SND_PCM help Say 'Y' or 'M' to include support for the Harmony/Vivace sound chip found in most GSC-based PA-RISC workstations. It's frequently provided as part of the Lasi multi-function IC. -endmenu +endif # SND_GSC diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index d95fbb2..b148c0b 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -1,11 +1,16 @@ # ALSA PCI drivers -menu "PCI devices" - depends on SND!=n && PCI +menuconfig SND_PCI + bool "PCI sound devices" + depends on PCI + default y + help + Support for sound devices connected via the PCI bus. + +if SND_PCI config SND_AD1889 tristate "Analog Devices AD1889" - depends on SND select SND_AC97_CODEC help Say Y here to include support for the integrated AC97 sound @@ -17,7 +22,6 @@ config SND_AD1889 config SND_ALS300 tristate "Avance Logic ALS300/ALS300+" - depends on SND select SND_PCM select SND_AC97_CODEC select SND_OPL3_LIB @@ -29,7 +33,7 @@ config SND_ALS300 config SND_ALS4000 tristate "Avance Logic ALS4000" - depends on SND && ISA_DMA_API + depends on ISA_DMA_API select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM @@ -43,7 +47,6 @@ config SND_ALS4000 config SND_ALI5451 tristate "ALi M5451 PCI Audio Controller" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -57,7 +60,6 @@ config SND_ALI5451 config SND_ATIIXP tristate "ATI IXP AC97 Controller" - depends on SND select SND_AC97_CODEC help Say Y here to include support for the integrated AC97 sound @@ -69,7 +71,6 @@ config SND_ATIIXP config SND_ATIIXP_MODEM tristate "ATI IXP Modem" - depends on SND select SND_AC97_CODEC help Say Y here to include support for the integrated MC97 modem on @@ -80,7 +81,6 @@ config SND_ATIIXP_MODEM config SND_AU8810 tristate "Aureal Advantage" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -95,7 +95,6 @@ config SND_AU8810 config SND_AU8820 tristate "Aureal Vortex" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -109,7 +108,6 @@ config SND_AU8820 config SND_AU8830 tristate "Aureal Vortex 2" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -124,7 +122,6 @@ config SND_AU8830 config SND_AW2 tristate "Emagic Audiowerk 2" - depends on SND help Say Y here to include support for Emagic Audiowerk 2 soundcards. @@ -139,7 +136,7 @@ config SND_AW2 config SND_AZT3328 tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)" - depends on SND && EXPERIMENTAL + depends on EXPERIMENTAL select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM @@ -152,7 +149,6 @@ config SND_AZT3328 config SND_BT87X tristate "Bt87x Audio Capture" - depends on SND select SND_PCM help If you want to record audio from TV cards based on @@ -174,7 +170,6 @@ config SND_BT87X_OVERCLOCK config SND_CA0106 tristate "SB Audigy LS / Live 24bit" - depends on SND select SND_AC97_CODEC select SND_RAWMIDI select SND_VMASTER @@ -187,7 +182,6 @@ config SND_CA0106 config SND_CMIPCI tristate "C-Media 8338, 8738, 8768, 8770" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM @@ -201,13 +195,11 @@ config SND_CMIPCI config SND_OXYGEN_LIB tristate - depends on SND select SND_PCM select SND_MPU401_UART config SND_OXYGEN tristate "C-Media 8788 (Oxygen)" - depends on SND select SND_OXYGEN_LIB help Say Y here to include support for sound cards based on the @@ -225,7 +217,6 @@ config SND_OXYGEN config SND_CS4281 tristate "Cirrus Logic (Sound Fusion) CS4281" - depends on SND select SND_OPL3_LIB select SND_RAWMIDI select SND_AC97_CODEC @@ -237,7 +228,6 @@ config SND_CS4281 config SND_CS46XX tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x" - depends on SND select SND_RAWMIDI select SND_AC97_CODEC help @@ -258,7 +248,7 @@ config SND_CS46XX_NEW_DSP config SND_CS5530 tristate "CS5530 Audio" - depends on SND && ISA_DMA_API + depends on ISA_DMA_API select SND_SB16_DSP help Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips. @@ -268,7 +258,7 @@ config SND_CS5530 config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" - depends on SND && X86 && !X86_64 + depends on X86 && !X86_64 select SND_PCM select SND_AC97_CODEC help @@ -286,7 +276,6 @@ config SND_CS5535AUDIO config SND_DARLA20 tristate "(Echoaudio) Darla20" - depends on SND select FW_LOADER select SND_PCM help @@ -297,7 +286,6 @@ config SND_DARLA20 config SND_GINA20 tristate "(Echoaudio) Gina20" - depends on SND select FW_LOADER select SND_PCM help @@ -308,7 +296,6 @@ config SND_GINA20 config SND_LAYLA20 tristate "(Echoaudio) Layla20" - depends on SND select FW_LOADER select SND_RAWMIDI select SND_PCM @@ -320,7 +307,6 @@ config SND_LAYLA20 config SND_DARLA24 tristate "(Echoaudio) Darla24" - depends on SND select FW_LOADER select SND_PCM help @@ -331,7 +317,6 @@ config SND_DARLA24 config SND_GINA24 tristate "(Echoaudio) Gina24" - depends on SND select FW_LOADER select SND_PCM help @@ -342,7 +327,6 @@ config SND_GINA24 config SND_LAYLA24 tristate "(Echoaudio) Layla24" - depends on SND select FW_LOADER select SND_RAWMIDI select SND_PCM @@ -354,7 +338,6 @@ config SND_LAYLA24 config SND_MONA tristate "(Echoaudio) Mona" - depends on SND select FW_LOADER select SND_RAWMIDI select SND_PCM @@ -366,7 +349,6 @@ config SND_MONA config SND_MIA tristate "(Echoaudio) Mia" - depends on SND select FW_LOADER select SND_RAWMIDI select SND_PCM @@ -378,7 +360,6 @@ config SND_MIA config SND_ECHO3G tristate "(Echoaudio) 3G cards" - depends on SND select FW_LOADER select SND_RAWMIDI select SND_PCM @@ -390,7 +371,6 @@ config SND_ECHO3G config SND_INDIGO tristate "(Echoaudio) Indigo" - depends on SND select FW_LOADER select SND_PCM help @@ -401,7 +381,6 @@ config SND_INDIGO config SND_INDIGOIO tristate "(Echoaudio) Indigo IO" - depends on SND select FW_LOADER select SND_PCM help @@ -412,7 +391,6 @@ config SND_INDIGOIO config SND_INDIGODJ tristate "(Echoaudio) Indigo DJ" - depends on SND select FW_LOADER select SND_PCM help @@ -423,7 +401,6 @@ config SND_INDIGODJ config SND_EMU10K1 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" - depends on SND select FW_LOADER select SND_HWDEP select SND_RAWMIDI @@ -441,7 +418,6 @@ config SND_EMU10K1 config SND_EMU10K1X tristate "Emu10k1X (Dell OEM Version)" - depends on SND select SND_AC97_CODEC select SND_RAWMIDI help @@ -453,7 +429,6 @@ config SND_EMU10K1X config SND_ENS1370 tristate "(Creative) Ensoniq AudioPCI 1370" - depends on SND select SND_RAWMIDI select SND_PCM help @@ -464,7 +439,6 @@ config SND_ENS1370 config SND_ENS1371 tristate "(Creative) Ensoniq AudioPCI 1371/1373" - depends on SND select SND_RAWMIDI select SND_AC97_CODEC help @@ -476,7 +450,6 @@ config SND_ENS1371 config SND_ES1938 tristate "ESS ES1938/1946/1969 (Solo-1)" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -489,7 +462,6 @@ config SND_ES1938 config SND_ES1968 tristate "ESS ES1968/1978 (Maestro-1/2/2E)" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -501,7 +473,6 @@ config SND_ES1968 config SND_FM801 tristate "ForteMedia FM801" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -528,7 +499,6 @@ config SND_FM801_TEA575X config SND_HDA_INTEL tristate "Intel HD Audio" - depends on SND select SND_PCM select SND_VMASTER help @@ -637,7 +607,6 @@ config SND_HDA_POWER_SAVE_DEFAULT config SND_HDSP tristate "RME Hammerfall DSP Audio" - depends on SND select SND_HWDEP select SND_RAWMIDI select SND_PCM @@ -650,7 +619,6 @@ config SND_HDSP config SND_HDSPM tristate "RME Hammerfall DSP MADI" - depends on SND select SND_HWDEP select SND_RAWMIDI select SND_PCM @@ -663,7 +631,6 @@ config SND_HDSPM config SND_HIFIER tristate "TempoTec HiFier Fantasia" - depends on SND select SND_OXYGEN_LIB help Say Y here to include support for the MediaTek/TempoTec HiFier @@ -674,7 +641,6 @@ config SND_HIFIER config SND_ICE1712 tristate "ICEnsemble ICE1712 (Envy24)" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -691,7 +657,6 @@ config SND_ICE1712 config SND_ICE1724 tristate "ICE/VT1724/1720 (Envy24HT/PT)" - depends on SND select SND_RAWMIDI select SND_AC97_CODEC select SND_VMASTER @@ -709,7 +674,6 @@ config SND_ICE1724 config SND_INTEL8X0 tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller" - depends on SND select SND_AC97_CODEC help Say Y here to include support for the integrated AC97 sound @@ -722,7 +686,6 @@ config SND_INTEL8X0 config SND_INTEL8X0M tristate "Intel/SiS/nVidia/AMD MC97 Modem" - depends on SND select SND_AC97_CODEC help Say Y here to include support for the integrated MC97 modem on @@ -733,7 +696,6 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" - depends on SND select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL select SND_PCM help @@ -753,7 +715,6 @@ config SND_KORG1212_FIRMWARE_IN_KERNEL config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" - depends on SND select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL select SND_AC97_CODEC help @@ -774,7 +735,6 @@ config SND_MAESTRO3_FIRMWARE_IN_KERNEL config SND_MIXART tristate "Digigram miXart" - depends on SND select SND_HWDEP select SND_PCM help @@ -786,7 +746,6 @@ config SND_MIXART config SND_NM256 tristate "NeoMagic NM256AV/ZX" - depends on SND select SND_AC97_CODEC help Say Y here to include support for NeoMagic NM256AV/ZX chips. @@ -796,7 +755,6 @@ config SND_NM256 config SND_PCXHR tristate "Digigram PCXHR" - depends on SND select SND_PCM select SND_HWDEP help @@ -807,7 +765,6 @@ config SND_PCXHR config SND_RIPTIDE tristate "Conexant Riptide" - depends on SND select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART @@ -820,7 +777,6 @@ config SND_RIPTIDE config SND_RME32 tristate "RME Digi32, 32/8, 32 PRO" - depends on SND select SND_PCM help Say Y to include support for RME Digi32, Digi32 PRO and @@ -832,7 +788,6 @@ config SND_RME32 config SND_RME96 tristate "RME Digi96, 96/8, 96/8 PRO" - depends on SND select SND_PCM help Say Y here to include support for RME Digi96, Digi96/8 and @@ -843,7 +798,6 @@ config SND_RME96 config SND_RME9652 tristate "RME Digi9652 (Hammerfall)" - depends on SND select SND_PCM help Say Y here to include support for RME Hammerfall (RME @@ -854,7 +808,7 @@ config SND_RME9652 config SND_SIS7019 tristate "SiS 7019 Audio Accelerator" - depends on SND && X86 && !X86_64 + depends on X86 && !X86_64 select SND_AC97_CODEC help Say Y here to include support for the SiS 7019 Audio Accelerator. @@ -864,7 +818,6 @@ config SND_SIS7019 config SND_SONICVIBES tristate "S3 SonicVibes" - depends on SND select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -877,7 +830,6 @@ config SND_SONICVIBES config SND_TRIDENT tristate "Trident 4D-Wave DX/NX; SiS 7018" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -889,7 +841,6 @@ config SND_TRIDENT config SND_VIA82XX tristate "VIA 82C686A/B, 8233/8235 AC97 Controller" - depends on SND select SND_MPU401_UART select SND_AC97_CODEC help @@ -901,7 +852,6 @@ config SND_VIA82XX config SND_VIA82XX_MODEM tristate "VIA 82C686A/B, 8233 based Modems" - depends on SND select SND_AC97_CODEC help Say Y here to include support for the integrated MC97 modem on @@ -912,7 +862,6 @@ config SND_VIA82XX_MODEM config SND_VIRTUOSO tristate "Asus Virtuoso 100/200 (Xonar)" - depends on SND select SND_OXYGEN_LIB help Say Y here to include support for sound cards based on the @@ -923,7 +872,6 @@ config SND_VIRTUOSO config SND_VX222 tristate "Digigram VX222" - depends on SND select SND_VX_LIB help Say Y here to include support for Digigram VX222 soundcards. @@ -933,7 +881,6 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" - depends on SND select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART @@ -975,4 +922,4 @@ config SND_AC97_POWER_SAVE_DEFAULT The default time-out value in seconds for AC97 automatic power-save mode. 0 means to disable the power-save mode. -endmenu +endif # SND_PCI diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig index c9fa1a2..7fbb190 100644 --- a/sound/pcmcia/Kconfig +++ b/sound/pcmcia/Kconfig @@ -1,11 +1,16 @@ # ALSA PCMCIA drivers -menu "PCMCIA devices" - depends on SND!=n && PCMCIA +menuconfig SND_PCMCIA + bool "PCMCIA sound devices" + depends on PCMCIA + default y + help + Support for sound devices connected via the PCMCIA bus. + +if SND_PCMCIA && PCMCIA config SND_VXPOCKET tristate "Digigram VXpocket" - depends on SND && PCMCIA select SND_VX_LIB help Say Y here to include support for Digigram VXpocket and @@ -16,7 +21,6 @@ config SND_VXPOCKET config SND_PDAUDIOCF tristate "Sound Core PDAudioCF" - depends on SND && PCMCIA select SND_PCM help Say Y here to include support for Sound Core PDAudioCF @@ -25,4 +29,5 @@ config SND_PDAUDIOCF To compile this driver as a module, choose M here: the module will be called snd-pdaudiocf. -endmenu +endif # SND_PCMCIA + diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig index cacb0b1..777de2b 100644 --- a/sound/ppc/Kconfig +++ b/sound/ppc/Kconfig @@ -1,17 +1,17 @@ # ALSA PowerMac drivers -menu "ALSA PowerMac devices" - depends on SND!=n && PPC - -comment "ALSA PowerMac requires I2C" - depends on SND && I2C=n +menuconfig SND_PPC + bool "PowerPC sound devices" + depends on PPC64 || PPC32 + default y + help + Support for sound devices specific to PowerPC architectures. -comment "ALSA PowerMac requires INPUT" - depends on SND && INPUT=n +if SND_PPC config SND_POWERMAC tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)" - depends on SND && I2C && INPUT && PPC_PMAC + depends on I2C && INPUT && PPC_PMAC select SND_PCM help Say Y here to include support for the integrated sound device. @@ -32,14 +32,9 @@ config SND_POWERMAC_AUTO_DRC Note that you can turn on/off DRC manually even without this option. -endmenu - -menu "ALSA PowerPC devices" - depends on SND!=n && ( PPC64 || PPC32 ) - config SND_PS3 tristate "PS3 Audio support" - depends on SND && PS3_PS3AV + depends on PS3_PS3AV select SND_PCM default m help @@ -52,4 +47,5 @@ config SND_PS3_DEFAULT_START_DELAY int "Startup delay time in ms" depends on SND_PS3 default "2000" -endmenu + +endif # SND_PPC diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig index b7e08ef..cfc1439 100644 --- a/sound/sh/Kconfig +++ b/sound/sh/Kconfig @@ -1,14 +1,22 @@ # ALSA SH drivers -menu "SUPERH devices" - depends on SND!=n && SUPERH +menuconfig SND_SUPERH + bool "SUPERH sound devices" + depends on SUPERH + default y + help + Support for sound devices specific to SUPERH architectures. + Drivers that are implemented on ASoC can be found in + "ALSA for SoC audio support" section. + +if SND_SUPERH config SND_AICA tristate "Dreamcast Yamaha AICA sound" - depends on SH_DREAMCAST && SND + depends on SH_DREAMCAST select SND_PCM help ALSA Sound driver for the SEGA Dreamcast console. -endmenu +endif # SND_SUPERH diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 18f28ac..fd7bc4f 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -2,15 +2,8 @@ # SoC audio configuration # -menu "System on Chip audio support" - depends on SND!=n - -config SND_SOC_AC97_BUS - bool - -config SND_SOC +menuconfig SND_SOC tristate "ALSA for SoC audio support" - depends on SND select SND_PCM ---help--- @@ -23,6 +16,11 @@ config SND_SOC This ASoC audio support can also be built as a module. If so, the module will be called snd-soc-core. +if SND_SOC + +config SND_SOC_AC97_BUS + bool + # All the supported Soc's source "sound/soc/at91/Kconfig" source "sound/soc/pxa/Kconfig" @@ -35,4 +33,5 @@ source "sound/soc/omap/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" -endmenu +endif # SND_SOC + diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig index 5cb93fd..9051865 100644 --- a/sound/soc/at91/Kconfig +++ b/sound/soc/at91/Kconfig @@ -1,6 +1,6 @@ config SND_AT91_SOC tristate "SoC Audio for the Atmel AT91 System-on-Chip" - depends on ARCH_AT91 && SND_SOC + depends on ARCH_AT91 help Say Y or M if you want to add support for codecs attached to the AT91 SSC interface. You will also need diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 3903ab7..d4a5fe4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1,31 +1,25 @@ config SND_SOC_AC97_CODEC tristate - depends on SND_SOC + select SND_AC97_CODEC config SND_SOC_WM8731 tristate - depends on SND_SOC config SND_SOC_WM8750 tristate - depends on SND_SOC config SND_SOC_WM8753 tristate - depends on SND_SOC config SND_SOC_WM9712 tristate - depends on SND_SOC config SND_SOC_WM9713 tristate - depends on SND_SOC # Cirrus Logic CS4270 Codec config SND_SOC_CS4270 tristate - depends on SND_SOC # Cirrus Logic CS4270 Codec Hardware Mute Support # Select if you have external muting circuitry attached to your CS4270. @@ -43,4 +37,4 @@ config SND_SOC_CS4270_VD33_ERRATA config SND_SOC_TLV320AIC3X tristate - depends on SND_SOC && I2C + depends on I2C diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 20680c5..8f7e338 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -1,6 +1,6 @@ config SND_DAVINCI_SOC tristate "SoC Audio for the TI DAVINCI chip" - depends on ARCH_DAVINCI && SND_SOC + depends on ARCH_DAVINCI help Say Y or M if you want to add support for codecs attached to the DAVINCI AC97 or I2S interface. You will also need diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 257101f..19802e2 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -2,7 +2,7 @@ menu "ALSA SoC audio for Freescale SOCs" config SND_SOC_MPC8610 bool "ALSA SoC support for the MPC8610 SOC" - depends on SND_SOC && MPC8610_HPCD + depends on MPC8610_HPCD default y if MPC8610 help Say Y if you want to add support for codecs attached to the SSI diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 484f883..18a40dc 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -1,6 +1,6 @@ config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" - depends on ARCH_PXA && SND_SOC + depends on ARCH_PXA help Say Y or M if you want to add support for codecs attached to the PXA2xx AC97, I2S or SSP interface. You will also need diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 1f6dbfc..b9f2353 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -1,7 +1,6 @@ config SND_S3C24XX_SOC tristate "SoC Audio for the Samsung S3C24XX chips" - depends on ARCH_S3C2410 && SND_SOC - select SND_PCM + depends on ARCH_S3C2410 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 @@ -16,7 +15,6 @@ config SND_S3C2412_SOC_I2S config SND_S3C2443_SOC_AC97 tristate select AC97_BUS - select SND_AC97_CODEC select SND_SOC_AC97_BUS config SND_S3C24XX_SOC_NEO1973_WM8753 diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 4c1e013..54bd604 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -3,7 +3,7 @@ menu "SoC Audio support for SuperH" config SND_SOC_PCM_SH7760 tristate "SoC Audio support for Renesas SH7760" - depends on CPU_SUBTYPE_SH7760 && SND_SOC && SH_DMABRG + depends on CPU_SUBTYPE_SH7760 && SH_DMABRG help Enable this option for SH7760 AC97/I2S audio support. @@ -13,10 +13,9 @@ config SND_SOC_PCM_SH7760 ## config SND_SOC_SH4_HAC + tristate select AC97_BUS select SND_SOC_AC97_BUS - select SND_AC97_CODEC - tristate config SND_SOC_SH4_SSI tristate diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig index 079e22a..d75deba 100644 --- a/sound/sparc/Kconfig +++ b/sound/sparc/Kconfig @@ -1,11 +1,17 @@ # ALSA Sparc drivers -menu "ALSA Sparc devices" - depends on SND!=n && SPARC +menuconfig SND_SPARC + bool "Sparc sound devices" + depends on SPARC + default y + help + Support for sound devices specific to Sun SPARC architectures. + +if SND_SPARC config SND_SUN_AMD7930 tristate "Sun AMD7930" - depends on SBUS && SND + depends on SBUS select SND_PCM help Say Y here to include support for AMD7930 sound device on Sun. @@ -15,7 +21,6 @@ config SND_SUN_AMD7930 config SND_SUN_CS4231 tristate "Sun CS4231" - depends on SND select SND_PCM help Say Y here to include support for CS4231 sound device on Sun. @@ -25,7 +30,7 @@ config SND_SUN_CS4231 config SND_SUN_DBRI tristate "Sun DBRI" - depends on SND && SBUS + depends on SBUS select SND_PCM help Say Y here to include support for DBRI sound device on Sun. @@ -33,4 +38,4 @@ config SND_SUN_DBRI To compile this driver as a module, choose M here: the module will be called snd-sun-dbri. -endmenu +endif # SND_SPARC diff --git a/sound/spi/Kconfig b/sound/spi/Kconfig index 0d08c29..e6485be 100644 --- a/sound/spi/Kconfig +++ b/sound/spi/Kconfig @@ -1,7 +1,13 @@ #SPI drivers -menu "SPI devices" - depends on SND != n +menuconfig SND_SPI + bool "SPI sound devices" + depends on SPI + default y + help + Support for sound devices connected via the SPI bus. + +if SND_SPI config SND_AT73C213 tristate "Atmel AT73C213 DAC driver" @@ -28,4 +34,5 @@ config SND_AT73C213_TARGET_BITRATE Set to 48000 Hz by default. -endmenu +endif # SND_SPI + diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 9351b8a..ffcdc8f 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -1,11 +1,16 @@ # ALSA USB drivers -menu "USB devices" - depends on SND!=n && USB!=n +menuconfig SND_USB + bool "USB sound devices" + depends on USB + default y + help + Support for sound devices connected via the USB bus. + +if SND_USB && USB config SND_USB_AUDIO tristate "USB Audio/MIDI driver" - depends on SND && USB select SND_HWDEP select SND_RAWMIDI select SND_PCM @@ -18,7 +23,7 @@ config SND_USB_AUDIO config SND_USB_USX2Y tristate "Tascam US-122, US-224 and US-428 USB driver" - depends on SND && USB && (X86 || PPC || ALPHA) + depends on X86 || PPC || ALPHA select SND_HWDEP select SND_RAWMIDI select SND_PCM @@ -31,7 +36,6 @@ config SND_USB_USX2Y config SND_USB_CAIAQ tristate "Native Instruments USB audio devices" - depends on SND && USB select SND_HWDEP select SND_RAWMIDI select SND_PCM @@ -63,5 +67,5 @@ config SND_USB_CAIAQ_INPUT * Native Instruments Kore Controller 2 * Native Instruments Audio Kontrol 1 -endmenu +endif # SND_USB -- cgit v0.10.2 From 6938d6b2a90d5e2ffaef037852652a1333502519 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 23 May 2008 16:11:26 +0200 Subject: [ALSA] Fix AC97 kconfig items The kconfig items related with AC97-powersave must be outside the CONFIG_SND_PCI range. And it'd be better together with CONFIG_SND_AC97. Signed-off-by: Takashi Iwai diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 79b4d3f..255fd18 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig @@ -161,4 +161,25 @@ config SND_ML403_AC97CR To compile this driver as a module, choose M here: the module will be called snd-ml403_ac97cr. +config SND_AC97_POWER_SAVE + bool "AC97 Power-Saving Mode" + depends on SND_AC97_CODEC && EXPERIMENTAL + default n + help + Say Y here to enable the aggressive power-saving support of + AC97 codecs. In this mode, the power-mode is dynamically + controlled at each open/close. + + The mode is activated by passing power_save=1 option to + snd-ac97-codec driver. You can toggle it dynamically over + sysfs, too. + +config SND_AC97_POWER_SAVE_DEFAULT + int "Default time-out for AC97 power-save mode" + depends on SND_AC97_POWER_SAVE + default 0 + help + The default time-out value in seconds for AC97 automatic + power-save mode. 0 means to disable the power-save mode. + endif # SND_DRIVERS diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index b148c0b..8fe5dac 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -901,25 +901,4 @@ config SND_YMFPCI_FIRMWARE_IN_KERNEL for the YMFPCI driver. If you choose N here, you need to install the firmware files from the alsa-firmware package. -config SND_AC97_POWER_SAVE - bool "AC97 Power-Saving Mode" - depends on SND_AC97_CODEC && EXPERIMENTAL - default n - help - Say Y here to enable the aggressive power-saving support of - AC97 codecs. In this mode, the power-mode is dynamically - controlled at each open/close. - - The mode is activated by passing power_save=1 option to - snd-ac97-codec driver. You can toggle it dynamically over - sysfs, too. - -config SND_AC97_POWER_SAVE_DEFAULT - int "Default time-out for AC97 power-save mode" - depends on SND_AC97_POWER_SAVE - default 0 - help - The default time-out value in seconds for AC97 automatic - power-save mode. 0 means to disable the power-save mode. - endif # SND_PCI -- cgit v0.10.2 From 62cf872a8eec1f11aacbec0ac3fe3698bfa9b403 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 May 2008 12:15:15 +0200 Subject: [ALSA] Replace CONFIG_SND_DEBUG_DETECT with CONFIG_SND_DEBUG_VERBOSE Replace CONFIG_SND_DEBUG_DETECT with CONFIG_SND_DEBUG_VERBOSE to represent its meaning more better. This config isn't provided only for the detection but for more verbose debug prints in general. Signed-off-by: Takashi Iwai diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 0bbee38..e595694 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1091,7 +1091,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This occurs when the access to non-existing or non-working codec slot (likely a modem one) causes a stall of the communication via HD-audio bus. You can see which codec slots are probed by enabling - CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec + CONFIG_SND_DEBUG_VERBOSE, or simply from the file name of the codec proc files. Then limit the slots to probe by probe_mask option. For example, probe_mask=1 means to probe only the first slot, and probe_mask=4 means only the third slot. diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index b03df4d4..e13c4e6 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -6127,8 +6127,8 @@ struct _snd_pcm_runtime { snd_printdd() is compiled in only when - CONFIG_SND_DEBUG_DETECT is set. Please note - that DEBUG_DETECT is not set as default + CONFIG_SND_DEBUG_VERBOSE is set. Please note + that CONFIG_SND_DEBUG_VERBOSE is not set as default even if you configure the alsa-driver with option. You need to give explicitly option instead. diff --git a/include/sound/core.h b/include/sound/core.h index 695ee53..558b962 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -412,13 +412,13 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) #endif /* CONFIG_SND_DEBUG */ -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE /** * snd_printdd - debug printk * @format: format string * * Works like snd_printk() for debugging purposes. - * Ignored when CONFIG_SND_DEBUG_DETECT is not set. + * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. */ #define snd_printdd(format, args...) snd_printk(format, ##args) #else @@ -442,7 +442,7 @@ struct snd_pci_quirk { unsigned short subvendor; /* PCI subvendor ID */ unsigned short subdevice; /* PCI subdevice ID */ int value; /* value */ -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE const char *name; /* name of the device (optional) */ #endif }; @@ -450,7 +450,7 @@ struct snd_pci_quirk { #define _SND_PCI_QUIRK_ID(vend,dev) \ .subvendor = (vend), .subdevice = (dev) #define SND_PCI_QUIRK_ID(vend,dev) {_SND_PCI_QUIRK_ID(vend, dev)} -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE #define SND_PCI_QUIRK(vend,dev,xname,val) \ {_SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname)} #else diff --git a/sound/core/Kconfig b/sound/core/Kconfig index db21113..335d45e 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -153,12 +153,14 @@ config SND_DEBUG help Say Y here to enable ALSA debug code. -config SND_DEBUG_DETECT - bool "Debug detection" +config SND_DEBUG_VERBOSE + bool "More verbose debug" depends on SND_DEBUG help - Say Y here to enable extra-verbose log messages printed when - detecting devices. + Say Y here to enable extra-verbose debugging messages. + + Let me repeat: it enables EXTRA-VERBOSE DEBUGGING messages. + So, say Y only if you are ready to be annoyed. config SND_PCM_XRUN_DEBUG bool "Enable PCM ring buffer overrun/underrun debugging" diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a6be6e3..d2e1093 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2335,7 +2335,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, if (!tbl) return -1; if (tbl->value >= 0 && tbl->value < num_configs) { -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE char tmp[10]; const char *model = NULL; if (models) diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 2177d9a..6e18a42 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -88,7 +88,7 @@ static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) { -#ifndef CONFIG_SND_DEBUG_DETECT +#ifndef CONFIG_SND_DEBUG_VERBOSE if (!capable(CAP_SYS_RAWIO)) return -EACCES; #endif diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 7fdcdc8..2c7e253 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -516,7 +516,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) int capture_mask = 0; int playback_mask = 0; -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE struct timeval my_tv1, my_tv2; do_gettimeofday(&my_tv1); #endif @@ -623,7 +623,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) mutex_unlock(&mgr->setup_mutex); -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE do_gettimeofday(&my_tv2); snd_printdd("***TRIGGER TASKLET*** TIME = %ld (err = %x)\n", (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 78aa81f..abe5c59 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -473,7 +473,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = { [CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, }; -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE static char* cmd_names[] = { [CMD_VERSION] = "CMD_VERSION", [CMD_SUPPORTED] = "CMD_SUPPORTED", @@ -549,7 +549,7 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh) } } } -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE if (rmh->cmd_idx < CMD_LAST_INDEX) snd_printdd(" stat[%d]=%x\n", i, data); #endif @@ -597,7 +597,7 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh) data |= 0x008000; /* MASK_MORE_THAN_1_WORD_COMMAND */ else data &= 0xff7fff; /* MASK_1_WORD_COMMAND */ -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE if (rmh->cmd_idx < CMD_LAST_INDEX) snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]); #endif @@ -624,7 +624,7 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh) for (i=1; i < rmh->cmd_len; i++) { /* send other words */ data = rmh->cmd[i]; -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE if (rmh->cmd_idx < CMD_LAST_INDEX) snd_printdd(" cmd[%d]=%x\n", i, data); #endif @@ -847,7 +847,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m int state, i, err; int audio_mask; -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE struct timeval my_tv1, my_tv2; do_gettimeofday(&my_tv1); #endif @@ -894,7 +894,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m if (err) return err; } -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE do_gettimeofday(&my_tv2); snd_printdd("***SET PIPE STATE*** TIME = %ld (err = %x)\n", (long)(my_tv2.tv_usec - my_tv1.tv_usec), err); @@ -951,7 +951,7 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err, enum pcxhr_async_err_src err_src, int pipe, int is_capture) { -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE static char* err_src_name[] = { [PCXHR_ERR_PIPE] = "Pipe", [PCXHR_ERR_STREAM] = "Stream", @@ -1169,7 +1169,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) mgr->dsp_time_last, dsp_time_new); mgr->dsp_time_err++; } -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE if (dsp_time_diff == 0) snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new); else if (dsp_time_diff >= (2*PCXHR_GRANULARITY)) @@ -1208,7 +1208,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) mgr->src_it_dsp = reg; tasklet_hi_schedule(&mgr->msg_taskq); } -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE if (reg & PCXHR_FATAL_DSP_ERR) snd_printdd("FATAL DSP ERROR : %x\n", reg); #endif -- cgit v0.10.2 From 142054a389ebf7972b4eee822ad7c55ff852b649 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Mon, 26 May 2008 12:59:16 +0300 Subject: [ALSA] Add EM-X270 ASoC driver This patch adds ASoC support for EM-X270 machine. Signed-off-by: Mike Rapoport Signed-off-by: Takashi Iwai diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 18a40dc..12f6ac9 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -62,3 +62,12 @@ config SND_PXA2XX_SOC_E800 help Say Y if you want to add support for SoC audio on the Toshiba e800 PDA + +config SND_PXA2XX_SOC_EM_X270 + tristate "SoC Audio support for CompuLab EM-x270" + depends on SND_PXA2XX_SOC && MACH_EM_X270 + select SND_PXA2XX_SOC_AC97 + select SND_SOC_WM9712 + help + Say Y if you want to add support for SoC audio on + CompuLab EM-x270. diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index 04e5646..5bc8edf 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -13,10 +13,11 @@ snd-soc-poodle-objs := poodle.o snd-soc-tosa-objs := tosa.o snd-soc-e800-objs := e800_wm9712.o snd-soc-spitz-objs := spitz.o +snd-soc-em-x270-objs := em-x270.o obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o - +obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c new file mode 100644 index 0000000..02dcac3 --- /dev/null +++ b/sound/soc/pxa/em-x270.c @@ -0,0 +1,102 @@ +/* + * em-x270.c -- SoC audio for EM-X270 + * + * Copyright 2007 CompuLab, Ltd. + * + * Author: Mike Rapoport + * + * Copied from tosa.c: + * Copyright 2005 Wolfson Microelectronics PLC. + * Copyright 2005 Openedhand Ltd. + * + * Authors: Liam Girdwood + * 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; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../codecs/wm9712.h" +#include "pxa2xx-pcm.h" +#include "pxa2xx-ac97.h" + +static struct snd_soc_dai_link em_x270_dai[] = { + { + .name = "AC97", + .stream_name = "AC97 HiFi", + .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], + .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], + }, + { + .name = "AC97 Aux", + .stream_name = "AC97 Aux", + .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], + .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], + }, +}; + +static struct snd_soc_machine em_x270 = { + .name = "EM-X270", + .dai_link = em_x270_dai, + .num_links = ARRAY_SIZE(em_x270_dai), +}; + +static struct snd_soc_device em_x270_snd_devdata = { + .machine = &em_x270, + .platform = &pxa2xx_soc_platform, + .codec_dev = &soc_codec_dev_wm9712, +}; + +static struct platform_device *em_x270_snd_device; + +static int __init em_x270_init(void) +{ + int ret; + + if (!machine_is_em_x270()) + return -ENODEV; + + em_x270_snd_device = platform_device_alloc("soc-audio", -1); + if (!em_x270_snd_device) + return -ENOMEM; + + platform_set_drvdata(em_x270_snd_device, &em_x270_snd_devdata); + em_x270_snd_devdata.dev = &em_x270_snd_device->dev; + ret = platform_device_add(em_x270_snd_device); + + if (ret) + platform_device_put(em_x270_snd_device); + + return ret; +} + +static void __exit em_x270_exit(void) +{ + platform_device_unregister(em_x270_snd_device); +} + +module_init(em_x270_init); +module_exit(em_x270_exit); + +/* Module information */ +MODULE_AUTHOR("Mike Rapoport"); +MODULE_DESCRIPTION("ALSA SoC EM-X270"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f269002e61446ed3410d8ca5f06ebca1e2760cb5 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 11:44:55 +0200 Subject: [ALSA] hda - Add support of Teradici controller Add the new PCI ID 0x6549 0x1200 Teradici controller. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6ba7ac0..7f62196 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -197,6 +197,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define ATIHDMI_NUM_CAPTURE 0 #define ATIHDMI_NUM_PLAYBACK 1 +/* TERA has 4 playback and 3 capture */ +#define TERA_NUM_CAPTURE 3 +#define TERA_NUM_PLAYBACK 4 + /* this number is statically defined for simplicity */ #define MAX_AZX_DEV 16 @@ -384,6 +388,7 @@ enum { AZX_DRIVER_SIS, AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, + AZX_DRIVER_TERA, }; static char *driver_short_names[] __devinitdata = { @@ -395,6 +400,7 @@ static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", + [AZX_DRIVER_TERA] = "HDA Teradici", }; /* @@ -1106,6 +1112,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ + [AZX_DRIVER_TERA] = 1, }; static int __devinit azx_codec_create(struct azx *chip, const char *model, @@ -2229,6 +2236,8 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, + /* Teradici */ + { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); -- cgit v0.10.2 From abbc9d1b25637b1948a4718fa8f7b257233136bc Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 11:48:01 +0200 Subject: [ALSA] hda - Add ICH9 controller support (8086:2911) Added the missing PCI ID for ICH9 controller (8086:2911) Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7f62196..6e2dc4f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2184,6 +2184,7 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH }, + { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, -- cgit v0.10.2 From 6dda9f4a95905f2b38e79e3737da5e25397e6acb Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:05:31 +0200 Subject: [ALSA] hda - Add ALC663 support Added the support of ALC663 codec, including specific models for ASUS M51VA, ASUS G71V, ASUS H13 and ASUS G50V. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index e595694..f48939e 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -845,7 +845,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC269 basic Basic preset - ALC662 + ALC662/663 3stack-dig 3-stack (2-channel) with SPDIF 3stack-6ch 3-stack (6-channel) 3stack-6ch-dig 3-stack (6-channel) with SPDIF @@ -853,6 +853,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. lenovo-101e Lenovo laptop eeepc-p701 ASUS Eeepc P701 eeepc-ep20 ASUS Eeepc EP20 + m51va ASUS M51VA + g71v ASUS G71V + h13 ASUS H13 + g50v ASUS G50V auto auto-config reading BIOS (default) ALC882/885 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b0a2a26..c659588 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -163,6 +163,10 @@ enum { ALC662_LENOVO_101E, ALC662_ASUS_EEEPC_P701, ALC662_ASUS_EEEPC_EP20, + ALC663_ASUS_M51VA, + ALC663_ASUS_G71V, + ALC663_ASUS_H13, + ALC663_ASUS_G50V, ALC662_AUTO, ALC662_MODEL_LAST, }; @@ -13251,6 +13255,23 @@ static struct hda_input_mux alc662_eeepc_capture_source = { }, }; +static struct hda_input_mux alc663_capture_source = { + .num_items = 3, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; + +static struct hda_input_mux alc663_m51va_capture_source = { + .num_items = 2, + .items = { + { "Ext-Mic", 0x0 }, + { "D-Mic", 0x9 }, + }, +}; + #define alc662_mux_enum_info alc_mux_enum_info #define alc662_mux_enum_get alc_mux_enum_get #define alc662_mux_enum_put alc882_mux_enum_put @@ -13431,6 +13452,44 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc663_m51va_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_g71v_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_g50v_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc662_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -13501,6 +13560,11 @@ static struct hda_verb alc662_init_verbs[] = { {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + /* always trun on EAPD */ + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } }; @@ -13571,6 +13635,43 @@ static struct hda_verb alc662_auto_init_verbs[] = { { } }; +static struct hda_verb alc663_m51va_init_verbs[] = { + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_g71v_init_verbs[] = { + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ + /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ + + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_g50v_init_verbs[] = { + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + /* capture mixer elements */ static struct snd_kcontrol_new alc662_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), @@ -13692,6 +13793,125 @@ static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) alc662_eeepc_ep20_automute(codec); } +static void alc663_m51va_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); +} + +static void alc663_m51va_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); + snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); +} + +static void alc663_m51va_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_m51va_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc663_m51va_mic_automute(codec); + break; + } +} + +static void alc663_m51va_inithook(struct hda_codec *codec) +{ + alc663_m51va_speaker_automute(codec); + alc663_m51va_mic_automute(codec); +} + +static void alc663_g71v_hp_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); +} + +static void alc663_g71v_front_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); +} + +static void alc663_g71v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_g71v_hp_automute(codec); + break; + case ALC880_FRONT_EVENT: + alc663_g71v_front_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_g71v_inithook(struct hda_codec *codec) +{ + alc663_g71v_front_automute(codec); + alc663_g71v_hp_automute(codec); + alc662_eeepc_mic_automute(codec); +} + +static void alc663_g50v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_m51va_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_g50v_inithook(struct hda_codec *codec) +{ + alc663_m51va_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} + #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc662_loopbacks alc880_loopbacks #endif @@ -13714,14 +13934,24 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { [ALC662_LENOVO_101E] = "lenovo-101e", [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", + [ALC663_ASUS_M51VA] = "m51va", + [ALC663_ASUS_G71V] = "g71v", + [ALC663_ASUS_H13] = "h13", + [ALC663_ASUS_G50V] = "g50v", [ALC662_AUTO] = "auto", }; static struct snd_pci_quirk alc662_cfg_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V), + SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), + SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V), SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), + SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), + SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), {} }; @@ -13809,7 +14039,53 @@ static struct alc_config_preset alc662_presets[] = { .unsol_event = alc662_eeepc_ep20_unsol_event, .init_hook = alc662_eeepc_ep20_inithook, }, - + [ALC663_ASUS_M51VA] = { + .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc663_m51va_capture_source, + .unsol_event = alc663_m51va_unsol_event, + .init_hook = alc663_m51va_inithook, + }, + [ALC663_ASUS_G71V] = { + .mixers = { alc663_g71v_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_g71v_unsol_event, + .init_hook = alc663_g71v_inithook, + }, + [ALC663_ASUS_H13] = { + .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc663_m51va_capture_source, + .unsol_event = alc663_m51va_unsol_event, + .init_hook = alc663_m51va_inithook, + }, + [ALC663_ASUS_G50V] = { + .mixers = { alc663_g50v_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .input_mux = &alc663_capture_source, + .unsol_event = alc663_g50v_unsol_event, + .init_hook = alc663_g50v_inithook, + }, }; @@ -14108,11 +14384,17 @@ static int patch_alc662(struct hda_codec *codec) if (board_config != ALC662_AUTO) setup_preset(spec, &alc662_presets[board_config]); - spec->stream_name_analog = "ALC662 Analog"; + if (codec->vendor_id == 0x10ec0663) { + spec->stream_name_analog = "ALC663 Analog"; + spec->stream_name_digital = "ALC663 Digital"; + } else { + spec->stream_name_analog = "ALC662 Analog"; + spec->stream_name_digital = "ALC662 Digital"; + } + spec->stream_analog_playback = &alc662_pcm_analog_playback; spec->stream_analog_capture = &alc662_pcm_analog_capture; - spec->stream_name_digital = "ALC662 Digital"; spec->stream_digital_playback = &alc662_pcm_digital_playback; spec->stream_digital_capture = &alc662_pcm_digital_capture; @@ -14151,6 +14433,7 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc883 }, { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", .patch = patch_alc662 }, + { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, -- cgit v0.10.2 From 531240ff520406c793a110e1c0f187d931f47d66 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:10:25 +0200 Subject: [ALSA] hda - Fix vref pincap check in alc882 auto-detection Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c659588..8174050 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6357,7 +6357,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) continue; vref = PIN_IN; if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { - if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) & + unsigned int pincap; + pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); + if ((pincap >> AC_PINCAP_VREF_SHIFT) & AC_PINCAP_VREF_80) vref = PIN_VREF80; } -- cgit v0.10.2 From 2f8932863d243a744ccd3dc005490ad9d2eae478 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:14:47 +0200 Subject: [ALSA] hda - show correct codec chip in PCM stream names Show more exact codec chip name in the PCM stream name strings. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8174050..5770b9c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6491,14 +6491,20 @@ static int patch_alc882(struct hda_codec *codec) if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); - spec->stream_name_analog = "ALC882 Analog"; + if (codec->vendor_id == 0x10ec0885) { + spec->stream_name_analog = "ALC885 Analog"; + spec->stream_name_digital = "ALC885 Digital"; + } else { + spec->stream_name_analog = "ALC882 Analog"; + spec->stream_name_digital = "ALC882 Digital"; + } + spec->stream_analog_playback = &alc882_pcm_analog_playback; spec->stream_analog_capture = &alc882_pcm_analog_capture; /* FIXME: setup DAC5 */ /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; - spec->stream_name_digital = "ALC882 Digital"; spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; @@ -8177,12 +8183,25 @@ static int patch_alc883(struct hda_codec *codec) if (board_config != ALC883_AUTO) setup_preset(spec, &alc883_presets[board_config]); - spec->stream_name_analog = "ALC883 Analog"; + switch (codec->vendor_id) { + case 0x10ec0888: + spec->stream_name_analog = "ALC888 Analog"; + spec->stream_name_digital = "ALC888 Digital"; + break; + case 0x10ec0889: + spec->stream_name_analog = "ALC889 Analog"; + spec->stream_name_digital = "ALC889 Digital"; + break; + default: + spec->stream_name_analog = "ALC883 Analog"; + spec->stream_name_digital = "ALC883 Digital"; + break; + } + spec->stream_analog_playback = &alc883_pcm_analog_playback; spec->stream_analog_capture = &alc883_pcm_analog_capture; spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; - spec->stream_name_digital = "ALC883 Digital"; spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; @@ -10680,12 +10699,18 @@ static int patch_alc268(struct hda_codec *codec) if (board_config != ALC268_AUTO) setup_preset(spec, &alc268_presets[board_config]); - spec->stream_name_analog = "ALC268 Analog"; + if (codec->vendor_id == 0x10ec0267) { + spec->stream_name_analog = "ALC267 Analog"; + spec->stream_name_digital = "ALC267 Digital"; + } else { + spec->stream_name_analog = "ALC268 Analog"; + spec->stream_name_digital = "ALC268 Digital"; + } + spec->stream_analog_playback = &alc268_pcm_analog_playback; spec->stream_analog_capture = &alc268_pcm_analog_capture; spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; - spec->stream_name_digital = "ALC268 Digital"; spec->stream_digital_playback = &alc268_pcm_digital_playback; if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) @@ -13174,11 +13199,17 @@ static int patch_alc861vd(struct hda_codec *codec) if (board_config != ALC861VD_AUTO) setup_preset(spec, &alc861vd_presets[board_config]); - spec->stream_name_analog = "ALC861VD Analog"; + if (codec->vendor_id == 0x10ec0660) { + spec->stream_name_analog = "ALC660-VD Analog"; + spec->stream_name_digital = "ALC660-VD Digital"; + } else { + spec->stream_name_analog = "ALC861VD Analog"; + spec->stream_name_digital = "ALC861VD Digital"; + } + spec->stream_analog_playback = &alc861vd_pcm_analog_playback; spec->stream_analog_capture = &alc861vd_pcm_analog_capture; - spec->stream_name_digital = "ALC861VD Digital"; spec->stream_digital_playback = &alc861vd_pcm_digital_playback; spec->stream_digital_capture = &alc861vd_pcm_digital_capture; -- cgit v0.10.2 From f9423e7a94eb2dfef3503dde76d17eaf342ab962 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:32:25 +0200 Subject: [ALSA] hda - Fix EAPD and COEF setups for realtek codecs Fixed EAPD and COEF setups for Realtek ALC662/663, 660-VD and 888 codecs. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5770b9c..cb3e028 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -780,6 +780,24 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) alc_sku_automute(codec); } +/* additional initialization for ALC888 variants */ +static void alc888_coef_init(struct hda_codec *codec) +{ + unsigned int tmp; + + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); + tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); + if ((tmp & 0xf0) == 2) + /* alc888S-VC */ + snd_hda_codec_read(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, 0x830); + else + /* alc888-VB */ + snd_hda_codec_read(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, 0x3030); +} + /* 32-bit subsystem ID for BIOS loading in HD Audio codec. * 31 ~ 16 : Manufacture ID * 15 ~ 8 : SKU ID @@ -855,8 +873,10 @@ do_sku: case 0x10ec0267: case 0x10ec0268: case 0x10ec0269: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: case 0x10ec0862: - case 0x10ec0662: case 0x10ec0889: snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_EAPD_BTLENABLE, 2); @@ -881,7 +901,6 @@ do_sku: case 0x10ec0882: case 0x10ec0883: case 0x10ec0885: - case 0x10ec0888: case 0x10ec0889: snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -893,6 +912,9 @@ do_sku: AC_VERB_SET_PROC_COEF, tmp | 0x2010); break; + case 0x10ec0888: + alc888_coef_init(codec); + break; case 0x10ec0267: case 0x10ec0268: snd_hda_codec_write(codec, 0x20, 0, @@ -8214,6 +8236,9 @@ static int patch_alc883(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC883_AUTO) spec->init_hook = alc883_auto_init; + else if (codec->vendor_id == 0x10ec0888) + spec->init_hook = alc888_coef_init; + #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc883_loopbacks; @@ -12662,6 +12687,12 @@ static struct hda_verb alc861vd_eapd_verbs[] = { { } }; +static struct hda_verb alc660vd_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -13202,6 +13233,8 @@ static int patch_alc861vd(struct hda_codec *codec) if (codec->vendor_id == 0x10ec0660) { spec->stream_name_analog = "ALC660-VD Analog"; spec->stream_name_digital = "ALC660-VD Digital"; + /* always turn on EAPD */ + spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs; } else { spec->stream_name_analog = "ALC861VD Analog"; spec->stream_name_digital = "ALC861VD Digital"; -- cgit v0.10.2 From b1829d2705daa7cb72eb1e08bdc8b7e9fad34266 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 28 May 2008 01:22:08 +0200 Subject: ftrace: fix merge Signed-off-by: Ingo Molnar diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ffbbd54..b482fe8 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -122,7 +122,7 @@ static inline void tracer_disable(void) # define trace_preempt_off(a0, a1) do { } while (0) #endif -#ifdef CONFIG_CONTEXT_SWITCH_TRACER +#ifdef CONFIG_TRACING extern void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); #else -- cgit v0.10.2 From a93bbaa77ea61c6bad684263a65f812b31bf9791 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 27 May 2008 17:59:24 +0200 Subject: [ALSA] Improve the slots option handling Fix and improve the slots option handling. The sound core tries to find the slot with the given module name first and assign if it's still available. If all pre-given slots are unavailable, then try to find another free slot. Also, when a module name begins with '!', it means the negative match: the slot will be given for any modules but that one. Signed-off-by: Takashi Iwai diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index f48939e..529073d 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -2271,6 +2271,10 @@ case above again, the first two slots are already reserved. If any other driver (e.g. snd-usb-audio) is loaded before snd-interwave or snd-ens1371, it will be assigned to the third or later slot. +When a module name is given with '!', the slot will be given for any +modules but that name. For example, "slots=!snd-pcsp" will reserve +the first slot for any modules but snd-pcsp. + ALSA PCM devices to OSS devices mapping ======================================= diff --git a/sound/core/init.c b/sound/core/init.c index ac05734..5c254d4 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -46,17 +46,24 @@ static char *slots[SNDRV_CARDS]; module_param_array(slots, charp, NULL, 0444); MODULE_PARM_DESC(slots, "Module names assigned to the slots."); -/* return non-zero if the given index is already reserved for another +/* return non-zero if the given index is reserved for the given * module via slots option */ -static int module_slot_mismatch(struct module *module, int idx) +static int module_slot_match(struct module *module, int idx) { + int match = 1; #ifdef MODULE - char *s1, *s2; + const char *s1, *s2; + if (!module || !module->name || !slots[idx]) return 0; - s1 = slots[idx]; - s2 = module->name; + + s1 = module->name; + s2 = slots[idx]; + if (*s2 == '!') { + match = 0; /* negative match */ + s2++; + } /* compare module name strings * hyphens are handled as equivalent with underscore */ @@ -68,12 +75,12 @@ static int module_slot_mismatch(struct module *module, int idx) if (c2 == '-') c2 = '_'; if (c1 != c2) - return 1; + return !match; if (!c1) break; } -#endif - return 0; +#endif /* MODULE */ + return match; } #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) @@ -129,7 +136,7 @@ struct snd_card *snd_card_new(int idx, const char *xid, struct module *module, int extra_size) { struct snd_card *card; - int err; + int err, idx2; if (extra_size < 0) extra_size = 0; @@ -144,35 +151,41 @@ struct snd_card *snd_card_new(int idx, const char *xid, err = 0; mutex_lock(&snd_card_mutex); if (idx < 0) { - int idx2; for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) /* idx == -1 == 0xffff means: take any free slot */ if (~snd_cards_lock & idx & 1<= snd_ecards_limit) - snd_ecards_limit = idx + 1; - break; + if (module_slot_match(module, idx2)) { + idx = idx2; + break; + } + } + } + if (idx < 0) { + for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) + /* idx == -1 == 0xffff means: take any free slot */ + if (~snd_cards_lock & idx & 1<= SNDRV_CARDS) + err = -ENODEV; + if (err < 0) { mutex_unlock(&snd_card_mutex); snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n", idx, snd_ecards_limit - 1, err); goto __error; } snd_cards_lock |= 1 << idx; /* lock it */ + if (idx >= snd_ecards_limit) + snd_ecards_limit = idx + 1; /* increase the limit */ mutex_unlock(&snd_card_mutex); card->number = idx; card->module = module; -- cgit v0.10.2 From 3c65e8743bf8b5cf0f90e8d767bf1d8b50c14c76 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 28 May 2008 08:58:56 -0500 Subject: JFS: diAlloc() should return -EIO rather than EIO The comment above the function says one of its return value is -EIO, and also the caller of diAlloc() checks for -EIO: struct inode *ialloc(struct inode *parent, umode_t mode) { ... rc = diAlloc(parent, S_ISDIR(mode), inode); if (rc) { jfs_warn("ialloc: diAlloc returned %d!", rc); if (rc == -EIO) make_bad_inode(inode); ... Signed-off-by: Li Zefan Signed-off-by: Dave Kleikamp diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 734ec91..d6363d8 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -1520,7 +1520,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) jfs_error(ip->i_sb, "diAlloc: can't find free bit " "in wmap"); - return EIO; + return -EIO; } /* determine the inode number within the -- cgit v0.10.2 From e13ac2e9b18bde51cf32c69c2209df25791ab3e5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 May 2008 17:58:05 +0100 Subject: [ALSA] ASoC: Add SOC_DOUBLE_S8_TLV control type The SOC_DOUBLE_S8_TLV control type was originally implemented in the UDA1380 driver by Philipp Zabel and was moved into the core by me. Signed-off-by: Philipp Zabel Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai diff --git a/include/sound/soc.h b/include/sound/soc.h index bca9538..9fa2093 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -73,6 +73,15 @@ .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ .private_value = (reg_left) | ((shift) << 8) | \ ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) } +#define SOC_DOUBLE_S8_TLV(xname, reg, min, max, tlv_array) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_READWRITE, \ + .tlv.p = (tlv_array), \ + .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ + .put = snd_soc_put_volsw_s8, \ + .private_value = (reg) | (((signed char)max) << 16) | \ + (((signed char)min) << 24) } #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ .mask = xmask, .texts = xtexts } @@ -267,6 +276,12 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); /* SoC PCM stream information */ struct snd_soc_pcm_stream { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a3f091e..f594ab8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1589,6 +1589,78 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); +/** + * snd_soc_info_volsw_s8 - signed mixer info callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to provide information about a signed mixer control. + * + * Returns 0 for success. + */ +int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int max = (signed char)((kcontrol->private_value >> 16) & 0xff); + int min = (signed char)((kcontrol->private_value >> 24) & 0xff); + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = max-min; + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); + +/** + * snd_soc_get_volsw_s8 - signed mixer get callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to get the value of a signed mixer control. + * + * Returns 0 for success. + */ +int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int min = (signed char)((kcontrol->private_value >> 24) & 0xff); + int val = snd_soc_read(codec, reg); + + ucontrol->value.integer.value[0] = + ((signed char)(val & 0xff))-min; + ucontrol->value.integer.value[1] = + ((signed char)((val >> 8) & 0xff))-min; + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8); + +/** + * snd_soc_put_volsw_sgn - signed mixer put callback + * @kcontrol: mixer control + * @uinfo: control element information + * + * Callback to set the value of a signed mixer control. + * + * Returns 0 for success. + */ +int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int min = (signed char)((kcontrol->private_value >> 24) & 0xff); + unsigned short val; + + val = (ucontrol->value.integer.value[0]+min) & 0xff; + val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; + + return snd_soc_update_bits(codec, reg, 0xffff, val); +} +EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); + static int __devinit snd_soc_init(void) { printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); -- cgit v0.10.2 From b7482f52789266e2548be5d0f6420c9fc12428d8 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 28 May 2008 17:58:06 +0100 Subject: [ALSA] ASoC: Add UDA1380 driver The UDA1380 codec is used by the HTC Magician and a number of Samsung reference boards. This driver has had a long out of tree history, having originally been written by Giorgio Padrin and converted to ASoC by Richard Purdie. Since conversion to ASoC most of the work on the driver has been done by Philipp Zabel with some review and updates for new APIs by Liam Girdwood and Mark Brown. Signed-off-by: Richard Purdie Signed-off-by: Philipp Zabel Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index d4a5fe4..7beefcc 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -2,6 +2,9 @@ config SND_SOC_AC97_CODEC tristate select SND_AC97_CODEC +config SND_SOC_UDA1380 + tristate + config SND_SOC_WM8731 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 4e1314c..d5926a1 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -1,4 +1,5 @@ snd-soc-ac97-objs := ac97.o +snd-soc-uda1380-objs := uda1380.o snd-soc-wm8731-objs := wm8731.o snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o @@ -8,6 +9,7 @@ snd-soc-cs4270-objs := cs4270.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o +obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c new file mode 100644 index 0000000..cb50486 --- /dev/null +++ b/sound/soc/codecs/uda1380.c @@ -0,0 +1,852 @@ +/* + * uda1380.c - Philips UDA1380 ALSA SoC audio 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. + * + * Copyright (c) 2007 Philipp Zabel + * Improved support for DAPM and audio routing/mixing capabilities, + * added TLV support. + * + * Modified by Richard Purdie to fit into SoC + * codec model. + * + * Copyright (c) 2005 Giorgio Padrin + * Copyright 2005 Openedhand Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uda1380.h" + +#define UDA1380_VERSION "0.6" +#define AUDIO_NAME "uda1380" + +/* + * uda1380 register cache + */ +static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = { + 0x0502, 0x0000, 0x0000, 0x3f3f, + 0x0202, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xff00, 0x0000, 0x4800, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8000, 0x0002, 0x0000, +}; + +/* + * read uda1380 register cache + */ +static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u16 *cache = codec->reg_cache; + if (reg == UDA1380_RESET) + return 0; + if (reg >= UDA1380_CACHEREGNUM) + return -1; + return cache[reg]; +} + +/* + * write uda1380 register cache + */ +static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, + u16 reg, unsigned int value) +{ + u16 *cache = codec->reg_cache; + if (reg >= UDA1380_CACHEREGNUM) + return; + cache[reg] = value; +} + +/* + * write to the UDA1380 register space + */ +static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + u8 data[3]; + + /* data is + * data[0] is register offset + * data[1] is MS byte + * data[2] is LS byte + */ + data[0] = reg; + data[1] = (value & 0xff00) >> 8; + data[2] = value & 0x00ff; + + uda1380_write_reg_cache(codec, reg, value); + + /* the interpolator & decimator regs must only be written when the + * codec DAI is active. + */ + if (!codec->active && (reg >= UDA1380_MVOL)) + return 0; + pr_debug("uda1380: hw write %x val %x\n", reg, value); + if (codec->hw_write(codec->control_data, data, 3) == 3) { + unsigned int val; + i2c_master_send(codec->control_data, data, 1); + i2c_master_recv(codec->control_data, data, 2); + val = (data[0]<<8) | data[1]; + if (val != value) { + pr_debug("uda1380: READ BACK VAL %x\n", + (data[0]<<8) | data[1]); + return -EIO; + } + return 0; + } else + return -EIO; +} + +#define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0) + +/* declarations of ALSA reg_elem_REAL controls */ +static const char *uda1380_deemp[] = { + "None", + "32kHz", + "44.1kHz", + "48kHz", + "96kHz", +}; +static const char *uda1380_input_sel[] = { + "Line", + "Mic + Line R", + "Line L", + "Mic", +}; +static const char *uda1380_output_sel[] = { + "DAC", + "Analog Mixer", +}; +static const char *uda1380_spf_mode[] = { + "Flat", + "Minimum1", + "Minimum2", + "Maximum" +}; +static const char *uda1380_capture_sel[] = { + "ADC", + "Digital Mixer" +}; +static const char *uda1380_sel_ns[] = { + "3rd-order", + "5th-order" +}; +static const char *uda1380_mix_control[] = { + "off", + "PCM only", + "before sound processing", + "after sound processing" +}; +static const char *uda1380_sdet_setting[] = { + "3200", + "4800", + "9600", + "19200" +}; +static const char *uda1380_os_setting[] = { + "single-speed", + "double-speed (no mixing)", + "quad-speed (no mixing)" +}; + +static const struct soc_enum uda1380_deemp_enum[] = { + SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp), + SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp), +}; +static const struct soc_enum uda1380_input_sel_enum = + SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel); /* SEL_MIC, SEL_LNA */ +static const struct soc_enum uda1380_output_sel_enum = + SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel); /* R02_EN_AVC */ +static const struct soc_enum uda1380_spf_enum = + SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode); /* M */ +static const struct soc_enum uda1380_capture_sel_enum = + SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel); /* SEL_SOURCE */ +static const struct soc_enum uda1380_sel_ns_enum = + SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns); /* SEL_NS */ +static const struct soc_enum uda1380_mix_enum = + SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control); /* MIX, MIX_POS */ +static const struct soc_enum uda1380_sdet_enum = + SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting); /* SD_VALUE */ +static const struct soc_enum uda1380_os_enum = + SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting); /* OS */ + +/* + * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB) + */ +static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1); + +/* + * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored), + * from -66 dB in 0.5 dB steps (2 dB steps, really) and + * from -52 dB in 0.25 dB steps + */ +static const unsigned int mvol_tlv[] = { + TLV_DB_RANGE_HEAD(3), + 0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1), + 16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0), + 44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0), +}; + +/* + * from -72 dB in 1.5 dB steps (6 dB steps really), + * from -66 dB in 0.75 dB steps (3 dB steps really), + * from -60 dB in 0.5 dB steps (2 dB steps really) and + * from -46 dB in 0.25 dB steps + */ +static const unsigned int vc_tlv[] = { + TLV_DB_RANGE_HEAD(4), + 0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1), + 8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0), + 16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0), + 44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0), +}; + +/* from 0 to 6 dB in 2 dB steps if SPF mode != flat */ +static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0); + +/* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts + * off at 18 dB max) */ +static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0); + +/* from -63 to 24 dB in 0.5 dB steps (-128...48) */ +static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1); + +/* from 0 to 24 dB in 3 dB steps */ +static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); + +/* from 0 to 30 dB in 2 dB steps */ +static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0); + +static const struct snd_kcontrol_new uda1380_snd_controls[] = { + SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv), /* AVCR, AVCL */ + SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv), /* MVCL, MVCR */ + SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv), /* VC2 */ + SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv), /* VC1 */ + SOC_ENUM("Sound Processing Filter", uda1380_spf_enum), /* M */ + SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), /* TRL, TRR */ + SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv), /* BBL, BBR */ +/**/ SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1), /* MTM */ + SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1), /* MT2 from decimation filter */ + SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]), /* DE2 */ + SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1), /* MT1, from digital data input */ + SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]), /* DE1 */ + SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */ + SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */ + SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */ + SOC_SINGLE("Silence Switch", UDA1380_MIXER, 7, 1, 0), /* SILENCE, force DAC output to silence */ + SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */ + SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */ + SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */ + SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv), /* ML_DEC, MR_DEC */ +/**/ SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1), /* MT_ADC */ + SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */ + SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0), /* ADCPOL_INV */ + SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv), /* VGA_CTRL */ + SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0), /* SKIP_DCFIL (before decimator) */ + SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0), /* EN_DCFIL (at output of decimator) */ + SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0), /* TODO: enum, see table 62 */ + SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1), /* AGC_LEVEL */ + /* -5.5, -8, -11.5, -14 dBFS */ + SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0), +}; + +/* add non dapm controls */ +static int uda1380_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&uda1380_snd_controls[i], codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + +/* Input mux */ +static const struct snd_kcontrol_new uda1380_input_mux_control = + SOC_DAPM_ENUM("Route", uda1380_input_sel_enum); + +/* Output mux */ +static const struct snd_kcontrol_new uda1380_output_mux_control = + SOC_DAPM_ENUM("Route", uda1380_output_sel_enum); + +/* Capture mux */ +static const struct snd_kcontrol_new uda1380_capture_mux_control = + SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum); + + +static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { + SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, + &uda1380_input_mux_control), + SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0, + &uda1380_output_mux_control), + SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, + &uda1380_capture_mux_control), + SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0), + SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0), + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0), + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0), + SND_SOC_DAPM_INPUT("VINM"), + SND_SOC_DAPM_INPUT("VINL"), + SND_SOC_DAPM_INPUT("VINR"), + SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0), + SND_SOC_DAPM_OUTPUT("VOUTLHP"), + SND_SOC_DAPM_OUTPUT("VOUTRHP"), + SND_SOC_DAPM_OUTPUT("VOUTL"), + SND_SOC_DAPM_OUTPUT("VOUTR"), + SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0), + SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + + /* output mux */ + {"HeadPhone Driver", NULL, "Output Mux"}, + {"VOUTR", NULL, "Output Mux"}, + {"VOUTL", NULL, "Output Mux"}, + + {"Analog Mixer", NULL, "VINR"}, + {"Analog Mixer", NULL, "VINL"}, + {"Analog Mixer", NULL, "DAC"}, + + {"Output Mux", "DAC", "DAC"}, + {"Output Mux", "Analog Mixer", "Analog Mixer"}, + + /* {"DAC", "Digital Mixer", "I2S" } */ + + /* headphone driver */ + {"VOUTLHP", NULL, "HeadPhone Driver"}, + {"VOUTRHP", NULL, "HeadPhone Driver"}, + + /* input mux */ + {"Left ADC", NULL, "Input Mux"}, + {"Input Mux", "Mic", "Mic LNA"}, + {"Input Mux", "Mic + Line R", "Mic LNA"}, + {"Input Mux", "Line L", "Left PGA"}, + {"Input Mux", "Line", "Left PGA"}, + + /* right input */ + {"Right ADC", "Mic + Line R", "Right PGA"}, + {"Right ADC", "Line", "Right PGA"}, + + /* inputs */ + {"Mic LNA", NULL, "VINM"}, + {"Left PGA", NULL, "VINL"}, + {"Right PGA", NULL, "VINR"}, +}; + +static int uda1380_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, + ARRAY_SIZE(uda1380_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +static int uda1380_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + int iface; + + /* set up DAI based upon fmt */ + iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); + iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK); + + /* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= R01_SFORI_I2S | R01_SFORO_I2S; + break; + case SND_SOC_DAIFMT_LSB: + iface |= R01_SFORI_LSB16 | R01_SFORO_I2S; + break; + case SND_SOC_DAIFMT_MSB: + iface |= R01_SFORI_MSB | R01_SFORO_I2S; + } + + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) + iface |= R01_SIM; + + uda1380_write(codec, UDA1380_IFACE, iface); + + return 0; +} + +/* + * Flush reg cache + * We can only write the interpolator and decimator registers + * when the DAI is being clocked by the CPU DAI. It's up to the + * machine and cpu DAI driver to do this before we are called. + */ +static int uda1380_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + int reg, reg_start, reg_end, clk; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + reg_start = UDA1380_MVOL; + reg_end = UDA1380_MIXER; + } else { + reg_start = UDA1380_DEC; + reg_end = UDA1380_AGC; + } + + /* FIXME disable DAC_CLK */ + clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK); + + for (reg = reg_start; reg <= reg_end; reg++) { + pr_debug("uda1380: flush reg %x val %x:", reg, + uda1380_read_reg_cache(codec, reg)); + uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); + } + + /* FIXME enable DAC_CLK */ + uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK); + + return 0; +} + +static int uda1380_pcm_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_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + + /* set WSPLL power and divider if running from this clock */ + if (clk & R00_DAC_CLK) { + int rate = params_rate(params); + u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM); + clk &= ~0x3; /* clear SEL_LOOP_DIV */ + switch (rate) { + case 6250 ... 12500: + clk |= 0x0; + break; + case 12501 ... 25000: + clk |= 0x1; + break; + case 25001 ... 50000: + clk |= 0x2; + break; + case 50001 ... 100000: + clk |= 0x3; + break; + } + uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm); + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + clk |= R00_EN_DAC | R00_EN_INT; + else + clk |= R00_EN_ADC | R00_EN_DEC; + + uda1380_write(codec, UDA1380_CLK, clk); + return 0; +} + +static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + + /* shut down WSPLL power if running from this clock */ + if (clk & R00_DAC_CLK) { + u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM); + uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm); + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + clk &= ~(R00_EN_DAC | R00_EN_INT); + else + clk &= ~(R00_EN_ADC | R00_EN_DEC); + + uda1380_write(codec, UDA1380_CLK, clk); +} + +static int uda1380_mute(struct snd_soc_codec_dai *codec_dai, int mute) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM; + + /* FIXME: mute(codec,0) is called when the magician clock is already + * set to WSPLL, but for some unknown reason writing to interpolator + * registers works only when clocked by SYSCLK */ + u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); + uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk); + if (mute) + uda1380_write(codec, UDA1380_DEEMP, mute_reg | R13_MTM); + else + uda1380_write(codec, UDA1380_DEEMP, mute_reg); + uda1380_write(codec, UDA1380_CLK, clk); + return 0; +} + +static int uda1380_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + int pm = uda1380_read_reg_cache(codec, UDA1380_PM); + + switch (level) { + case SND_SOC_BIAS_ON: + case SND_SOC_BIAS_PREPARE: + uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); + break; + case SND_SOC_BIAS_STANDBY: + uda1380_write(codec, UDA1380_PM, R02_PON_BIAS); + break; + case SND_SOC_BIAS_OFF: + uda1380_write(codec, UDA1380_PM, 0x0); + break; + } + codec->bias_level = level; + return 0; +} + +#define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) + +struct snd_soc_codec_dai uda1380_dai[] = { +{ + .name = "UDA1380", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = UDA1380_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = UDA1380_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = { + .hw_params = uda1380_pcm_hw_params, + .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, + }, + .dai_ops = { + .digital_mute = uda1380_mute, + .set_fmt = uda1380_set_dai_fmt, + }, +}, +{ /* playback only - dual interface */ + .name = "UDA1380", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = UDA1380_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = { + .hw_params = uda1380_pcm_hw_params, + .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, + }, + .dai_ops = { + .digital_mute = uda1380_mute, + .set_fmt = uda1380_set_dai_fmt, + }, +}, +{ /* capture only - dual interface*/ + .name = "UDA1380", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = UDA1380_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = { + .hw_params = uda1380_pcm_hw_params, + .shutdown = uda1380_pcm_shutdown, + .prepare = uda1380_pcm_prepare, + }, + .dai_ops = { + .set_fmt = uda1380_set_dai_fmt, + }, +}, +}; +EXPORT_SYMBOL_GPL(uda1380_dai); + +static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int uda1380_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + int i; + u8 data[2]; + u16 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware */ + for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) { + data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); + data[1] = cache[i] & 0x00ff; + codec->hw_write(codec->control_data, data, 2); + } + uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + uda1380_set_bias_level(codec, codec->suspend_bias_level); + return 0; +} + +/* + * initialise the UDA1380 driver + * register mixer and dsp interfaces with the kernel + */ +static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) +{ + struct snd_soc_codec *codec = socdev->codec; + int ret = 0; + + codec->name = "UDA1380"; + codec->owner = THIS_MODULE; + codec->read = uda1380_read_reg_cache; + codec->write = uda1380_write; + codec->set_bias_level = uda1380_set_bias_level; + codec->dai = uda1380_dai; + codec->num_dai = ARRAY_SIZE(uda1380_dai); + codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg), + GFP_KERNEL); + if (codec->reg_cache == NULL) + return -ENOMEM; + codec->reg_cache_size = sizeof(uda1380_reg); + codec->reg_cache_step = 2; + uda1380_reset(codec); + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + pr_err("uda1380: failed to create pcms\n"); + goto pcm_err; + } + + /* power on device */ + uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + /* set clock input */ + switch (dac_clk) { + case UDA1380_DAC_CLK_SYSCLK: + uda1380_write(codec, UDA1380_CLK, 0); + break; + case UDA1380_DAC_CLK_WSPLL: + uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK); + break; + } + + /* uda1380 init */ + uda1380_add_controls(codec); + uda1380_add_widgets(codec); + ret = snd_soc_register_card(socdev); + if (ret < 0) { + pr_err("uda1380: failed to register card\n"); + goto card_err; + } + + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + kfree(codec->reg_cache); + return ret; +} + +static struct snd_soc_device *uda1380_socdev; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + +#define I2C_DRIVERID_UDA1380 0xfefe /* liam - need a proper id */ + +static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; + +/* Magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; + +static struct i2c_driver uda1380_i2c_driver; +static struct i2c_client client_template; + +/* If the i2c layer weren't so broken, we could pass this kind of data + around */ + +static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) +{ + struct snd_soc_device *socdev = uda1380_socdev; + struct uda1380_setup_data *setup = socdev->codec_data; + struct snd_soc_codec *codec = socdev->codec; + struct i2c_client *i2c; + int ret; + + if (addr != setup->i2c_address) + return -ENODEV; + + client_template.adapter = adap; + client_template.addr = addr; + + i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); + if (i2c == NULL) { + kfree(codec); + return -ENOMEM; + } + i2c_set_clientdata(i2c, codec); + codec->control_data = i2c; + + ret = i2c_attach_client(i2c); + if (ret < 0) { + pr_err("uda1380: failed to attach codec at addr %x\n", addr); + goto err; + } + + ret = uda1380_init(socdev, setup->dac_clk); + if (ret < 0) { + pr_err("uda1380: failed to initialise UDA1380\n"); + goto err; + } + return ret; + +err: + kfree(codec); + kfree(i2c); + return ret; +} + +static int uda1380_i2c_detach(struct i2c_client *client) +{ + struct snd_soc_codec *codec = i2c_get_clientdata(client); + i2c_detach_client(client); + kfree(codec->reg_cache); + kfree(client); + return 0; +} + +static int uda1380_i2c_attach(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, uda1380_codec_probe); +} + +static struct i2c_driver uda1380_i2c_driver = { + .driver = { + .name = "UDA1380 I2C Codec", + .owner = THIS_MODULE, + }, + .id = I2C_DRIVERID_UDA1380, + .attach_adapter = uda1380_i2c_attach, + .detach_client = uda1380_i2c_detach, + .command = NULL, +}; + +static struct i2c_client client_template = { + .name = "UDA1380", + .driver = &uda1380_i2c_driver, +}; +#endif + +static int uda1380_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct uda1380_setup_data *setup; + struct snd_soc_codec *codec; + int ret = 0; + + pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION); + + setup = socdev->codec_data; + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; + + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + uda1380_socdev = socdev; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + if (setup->i2c_address) { + normal_i2c[0] = setup->i2c_address; + codec->hw_write = (hw_write_t)i2c_master_send; + ret = i2c_add_driver(&uda1380_i2c_driver); + if (ret != 0) + printk(KERN_ERR "can't add i2c driver"); + } +#else + /* Add other interfaces here */ +#endif + return ret; +} + +/* power down chip */ +static int uda1380_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + if (codec->control_data) + uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&uda1380_i2c_driver); +#endif + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_uda1380 = { + .probe = uda1380_probe, + .remove = uda1380_remove, + .suspend = uda1380_suspend, + .resume = uda1380_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); + +MODULE_AUTHOR("Giorgio Padrin"); +MODULE_DESCRIPTION("Audio support for codec Philips UDA1380"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h new file mode 100644 index 0000000..f9d885c8 --- /dev/null +++ b/sound/soc/codecs/uda1380.h @@ -0,0 +1,89 @@ +/* + * Audio support for Philips UDA1380 + * + * 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. + * + * Copyright (c) 2005 Giorgio Padrin + */ + +#ifndef _UDA1380_H +#define _UDA1380_H + +#define UDA1380_CLK 0x00 +#define UDA1380_IFACE 0x01 +#define UDA1380_PM 0x02 +#define UDA1380_AMIX 0x03 +#define UDA1380_HP 0x04 +#define UDA1380_MVOL 0x10 +#define UDA1380_MIXVOL 0x11 +#define UDA1380_MODE 0x12 +#define UDA1380_DEEMP 0x13 +#define UDA1380_MIXER 0x14 +#define UDA1380_INTSTAT 0x18 +#define UDA1380_DEC 0x20 +#define UDA1380_PGA 0x21 +#define UDA1380_ADC 0x22 +#define UDA1380_AGC 0x23 +#define UDA1380_DECSTAT 0x28 +#define UDA1380_RESET 0x7f + +#define UDA1380_CACHEREGNUM 0x24 + +/* Register flags */ +#define R00_EN_ADC 0x0800 +#define R00_EN_DEC 0x0400 +#define R00_EN_DAC 0x0200 +#define R00_EN_INT 0x0100 +#define R00_DAC_CLK 0x0010 +#define R01_SFORI_I2S 0x0000 +#define R01_SFORI_LSB16 0x0100 +#define R01_SFORI_LSB18 0x0200 +#define R01_SFORI_LSB20 0x0300 +#define R01_SFORI_MSB 0x0500 +#define R01_SFORI_MASK 0x0700 +#define R01_SFORO_I2S 0x0000 +#define R01_SFORO_LSB16 0x0001 +#define R01_SFORO_LSB18 0x0002 +#define R01_SFORO_LSB20 0x0003 +#define R01_SFORO_LSB24 0x0004 +#define R01_SFORO_MSB 0x0005 +#define R01_SFORO_MASK 0x0007 +#define R01_SEL_SOURCE 0x0040 +#define R01_SIM 0x0010 +#define R02_PON_PLL 0x8000 +#define R02_PON_HP 0x2000 +#define R02_PON_DAC 0x0400 +#define R02_PON_BIAS 0x0100 +#define R02_EN_AVC 0x0080 +#define R02_PON_AVC 0x0040 +#define R02_PON_LNA 0x0010 +#define R02_PON_PGAL 0x0008 +#define R02_PON_ADCL 0x0004 +#define R02_PON_PGAR 0x0002 +#define R02_PON_ADCR 0x0001 +#define R13_MTM 0x4000 +#define R14_SILENCE 0x0080 +#define R14_SDET_ON 0x0040 +#define R21_MT_ADC 0x8000 +#define R22_SEL_LNA 0x0008 +#define R22_SEL_MIC 0x0004 +#define R22_SKIP_DCFIL 0x0002 +#define R23_AGC_EN 0x0001 + +struct uda1380_setup_data { + unsigned short i2c_address; + int dac_clk; +#define UDA1380_DAC_CLK_SYSCLK 0 +#define UDA1380_DAC_CLK_WSPLL 1 +}; + +#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */ +#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ +#define UDA1380_DAI_CAPTURE 2 /* capture DAI */ + +extern struct snd_soc_codec_dai uda1380_dai[3]; +extern struct snd_soc_codec_device soc_codec_dev_uda1380; + +#endif /* _UDA1380_H */ -- cgit v0.10.2 From b786af117b360843349cf66165c4efa0217ca2a7 Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Wed, 7 May 2008 04:29:17 +1000 Subject: [POWERPC] Refactor DCR code Previously, DCR support was configured at compile time to either use MMIO or native dcr instructions. Although this works for most platforms, it fails on FPGA platforms: 1) Systems may include more than one DCR bus. 2) Systems may be native DCR capable and still use memory mapped DCR interface. This patch provides runtime support based on the device trees for the case where CONFIG_PPC_DCR_MMIO and CONFIG_PPC_DCR_NATIVE are both selected. Previously, this was a poorly defined configuration, which happened to provide NATIVE support. The runtime selection is made based on the dcr-controller having a 'dcr-access-method' attribute in the device tree. If only one of the above options is selected, then the code uses #defines to select only the used code in order to avoid introducing overhead in existing usage. Signed-off-by: Stephen Neuendorffer Signed-off-by: Josh Boyer diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 437e48d..5f39a79 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -23,6 +23,105 @@ #include #include +static struct device_node *find_dcr_parent(struct device_node *node) +{ + struct device_node *par, *tmp; + const u32 *p; + + for (par = of_node_get(node); par;) { + if (of_get_property(par, "dcr-controller", NULL)) + break; + p = of_get_property(par, "dcr-parent", NULL); + tmp = par; + if (p == NULL) + par = of_get_parent(par); + else + par = of_find_node_by_phandle(*p); + of_node_put(tmp); + } + return par; +} + +#if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) + +bool dcr_map_ok_generic(dcr_host_t host) +{ + if (host.type == DCR_HOST_NATIVE) + return dcr_map_ok_native(host.host.native); + else if (host.type == DCR_HOST_MMIO) + return dcr_map_ok_mmio(host.host.mmio); + else + return 0; +} +EXPORT_SYMBOL_GPL(dcr_map_ok_generic); + +dcr_host_t dcr_map_generic(struct device_node *dev, + unsigned int dcr_n, + unsigned int dcr_c) +{ + dcr_host_t host; + struct device_node *dp; + const char *prop; + + host.type = DCR_HOST_INVALID; + + dp = find_dcr_parent(dev); + if (dp == NULL) + return host; + + prop = of_get_property(dp, "dcr-access-method", NULL); + + pr_debug("dcr_map_generic(dcr-access-method = %s)\n", prop); + + if (!strcmp(prop, "native")) { + host.type = DCR_HOST_NATIVE; + host.host.native = dcr_map_native(dev, dcr_n, dcr_c); + } else if (!strcmp(prop, "mmio")) { + host.type = DCR_HOST_MMIO; + host.host.mmio = dcr_map_mmio(dev, dcr_n, dcr_c); + } + + of_node_put(dp); + return host; +} +EXPORT_SYMBOL_GPL(dcr_map_generic); + +void dcr_unmap_generic(dcr_host_t host, unsigned int dcr_c) +{ + if (host.type == DCR_HOST_NATIVE) + dcr_unmap_native(host.host.native, dcr_c); + else if (host.type == DCR_HOST_MMIO) + dcr_unmap_mmio(host.host.mmio, dcr_c); + else /* host.type == DCR_HOST_INVALID */ + WARN_ON(true); +} +EXPORT_SYMBOL_GPL(dcr_unmap_generic); + +u32 dcr_read_generic(dcr_host_t host, unsigned int dcr_n) +{ + if (host.type == DCR_HOST_NATIVE) + return dcr_read_native(host.host.native, dcr_n); + else if (host.type == DCR_HOST_MMIO) + return dcr_read_mmio(host.host.mmio, dcr_n); + else /* host.type == DCR_HOST_INVALID */ + WARN_ON(true); + return 0; +} +EXPORT_SYMBOL_GPL(dcr_read_generic); + +void dcr_write_generic(dcr_host_t host, unsigned int dcr_n, u32 value) +{ + if (host.type == DCR_HOST_NATIVE) + dcr_write_native(host.host.native, dcr_n, value); + else if (host.type == DCR_HOST_MMIO) + dcr_write_mmio(host.host.mmio, dcr_n, value); + else /* host.type == DCR_HOST_INVALID */ + WARN_ON(true); +} +EXPORT_SYMBOL_GPL(dcr_write_generic); + +#endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */ + unsigned int dcr_resource_start(struct device_node *np, unsigned int index) { unsigned int ds; @@ -47,26 +146,7 @@ unsigned int dcr_resource_len(struct device_node *np, unsigned int index) } EXPORT_SYMBOL_GPL(dcr_resource_len); -#ifndef CONFIG_PPC_DCR_NATIVE - -static struct device_node * find_dcr_parent(struct device_node * node) -{ - struct device_node *par, *tmp; - const u32 *p; - - for (par = of_node_get(node); par;) { - if (of_get_property(par, "dcr-controller", NULL)) - break; - p = of_get_property(par, "dcr-parent", NULL); - tmp = par; - if (p == NULL) - par = of_get_parent(par); - else - par = of_find_node_by_phandle(*p); - of_node_put(tmp); - } - return par; -} +#ifdef CONFIG_PPC_DCR_MMIO u64 of_translate_dcr_address(struct device_node *dev, unsigned int dcr_n, @@ -75,7 +155,7 @@ u64 of_translate_dcr_address(struct device_node *dev, struct device_node *dp; const u32 *p; unsigned int stride; - u64 ret; + u64 ret = OF_BAD_ADDR; dp = find_dcr_parent(dev); if (dp == NULL) @@ -90,7 +170,7 @@ u64 of_translate_dcr_address(struct device_node *dev, if (p == NULL) p = of_get_property(dp, "dcr-mmio-space", NULL); if (p == NULL) - return OF_BAD_ADDR; + goto done; /* Maybe could do some better range checking here */ ret = of_translate_address(dp, p); @@ -98,21 +178,25 @@ u64 of_translate_dcr_address(struct device_node *dev, ret += (u64)(stride) * (u64)dcr_n; if (out_stride) *out_stride = stride; + + done: + of_node_put(dp); return ret; } -dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, - unsigned int dcr_c) +dcr_host_mmio_t dcr_map_mmio(struct device_node *dev, + unsigned int dcr_n, + unsigned int dcr_c) { - dcr_host_t ret = { .token = NULL, .stride = 0, .base = dcr_n }; + dcr_host_mmio_t ret = { .token = NULL, .stride = 0, .base = dcr_n }; u64 addr; pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", dev->full_name, dcr_n, dcr_c); addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); - pr_debug("translates to addr: 0x%lx, stride: 0x%x\n", - addr, ret.stride); + pr_debug("translates to addr: 0x%llx, stride: 0x%x\n", + (unsigned long long) addr, ret.stride); if (addr == OF_BAD_ADDR) return ret; pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride); @@ -124,11 +208,11 @@ dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, ret.token -= dcr_n * ret.stride; return ret; } -EXPORT_SYMBOL_GPL(dcr_map); +EXPORT_SYMBOL_GPL(dcr_map_mmio); -void dcr_unmap(dcr_host_t host, unsigned int dcr_c) +void dcr_unmap_mmio(dcr_host_mmio_t host, unsigned int dcr_c) { - dcr_host_t h = host; + dcr_host_mmio_t h = host; if (h.token == NULL) return; @@ -136,7 +220,11 @@ void dcr_unmap(dcr_host_t host, unsigned int dcr_c) iounmap(h.token); h.token = NULL; } -EXPORT_SYMBOL_GPL(dcr_unmap); -#else /* defined(CONFIG_PPC_DCR_NATIVE) */ +EXPORT_SYMBOL_GPL(dcr_unmap_mmio); + +#endif /* defined(CONFIG_PPC_DCR_MMIO) */ + +#ifdef CONFIG_PPC_DCR_NATIVE DEFINE_SPINLOCK(dcr_ind_lock); -#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ +#endif /* defined(CONFIG_PPC_DCR_NATIVE) */ + diff --git a/include/asm-powerpc/dcr-generic.h b/include/asm-powerpc/dcr-generic.h new file mode 100644 index 0000000..35b7159 --- /dev/null +++ b/include/asm-powerpc/dcr-generic.h @@ -0,0 +1,49 @@ +/* + * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. + * + * + * 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_POWERPC_DCR_GENERIC_H +#define _ASM_POWERPC_DCR_GENERIC_H +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +enum host_type_t {DCR_HOST_MMIO, DCR_HOST_NATIVE, DCR_HOST_INVALID}; + +typedef struct { + enum host_type_t type; + union { + dcr_host_mmio_t mmio; + dcr_host_native_t native; + } host; +} dcr_host_t; + +extern bool dcr_map_ok_generic(dcr_host_t host); + +extern dcr_host_t dcr_map_generic(struct device_node *dev, unsigned int dcr_n, + unsigned int dcr_c); +extern void dcr_unmap_generic(dcr_host_t host, unsigned int dcr_c); + +extern u32 dcr_read_generic(dcr_host_t host, unsigned int dcr_n); + +extern void dcr_write_generic(dcr_host_t host, unsigned int dcr_n, u32 value); + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_DCR_GENERIC_H */ + + diff --git a/include/asm-powerpc/dcr-mmio.h b/include/asm-powerpc/dcr-mmio.h index 08532ff..acd491d 100644 --- a/include/asm-powerpc/dcr-mmio.h +++ b/include/asm-powerpc/dcr-mmio.h @@ -27,20 +27,26 @@ typedef struct { void __iomem *token; unsigned int stride; unsigned int base; -} dcr_host_t; +} dcr_host_mmio_t; -#define DCR_MAP_OK(host) ((host).token != NULL) +static inline bool dcr_map_ok_mmio(dcr_host_mmio_t host) +{ + return host.token != NULL; +} -extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, - unsigned int dcr_c); -extern void dcr_unmap(dcr_host_t host, unsigned int dcr_c); +extern dcr_host_mmio_t dcr_map_mmio(struct device_node *dev, + unsigned int dcr_n, + unsigned int dcr_c); +extern void dcr_unmap_mmio(dcr_host_mmio_t host, unsigned int dcr_c); -static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n) +static inline u32 dcr_read_mmio(dcr_host_mmio_t host, unsigned int dcr_n) { return in_be32(host.token + ((host.base + dcr_n) * host.stride)); } -static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value) +static inline void dcr_write_mmio(dcr_host_mmio_t host, + unsigned int dcr_n, + u32 value) { out_be32(host.token + ((host.base + dcr_n) * host.stride), value); } diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h index f8398ce..72d2b72 100644 --- a/include/asm-powerpc/dcr-native.h +++ b/include/asm-powerpc/dcr-native.h @@ -26,14 +26,18 @@ typedef struct { unsigned int base; -} dcr_host_t; +} dcr_host_native_t; -#define DCR_MAP_OK(host) (1) +static inline bool dcr_map_ok_native(dcr_host_native_t host) +{ + return 1; +} -#define dcr_map(dev, dcr_n, dcr_c) ((dcr_host_t){ .base = (dcr_n) }) -#define dcr_unmap(host, dcr_c) do {} while (0) -#define dcr_read(host, dcr_n) mfdcr(dcr_n + host.base) -#define dcr_write(host, dcr_n, value) mtdcr(dcr_n + host.base, value) +#define dcr_map_native(dev, dcr_n, dcr_c) \ + ((dcr_host_native_t){ .base = (dcr_n) }) +#define dcr_unmap_native(host, dcr_c) do {} while (0) +#define dcr_read_native(host, dcr_n) mfdcr(dcr_n + host.base) +#define dcr_write_native(host, dcr_n, value) mtdcr(dcr_n + host.base, value) /* Device Control Registers */ void __mtdcr(int reg, unsigned int val); diff --git a/include/asm-powerpc/dcr.h b/include/asm-powerpc/dcr.h index 9338d50..53b2830 100644 --- a/include/asm-powerpc/dcr.h +++ b/include/asm-powerpc/dcr.h @@ -20,14 +20,50 @@ #ifndef _ASM_POWERPC_DCR_H #define _ASM_POWERPC_DCR_H #ifdef __KERNEL__ +#ifndef __ASSEMBLY__ #ifdef CONFIG_PPC_DCR #ifdef CONFIG_PPC_DCR_NATIVE #include -#else +#endif + +#ifdef CONFIG_PPC_DCR_MMIO #include #endif + +/* Indirection layer for providing both NATIVE and MMIO support. */ + +#if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) + +#include + +#define DCR_MAP_OK(host) dcr_map_ok_generic(host) +#define dcr_map(dev, dcr_n, dcr_c) dcr_map_generic(dev, dcr_n, dcr_c) +#define dcr_unmap(host, dcr_c) dcr_unmap_generic(host, dcr_c) +#define dcr_read(host, dcr_n) dcr_read_generic(host, dcr_n) +#define dcr_write(host, dcr_n, value) dcr_write_generic(host, dcr_n, value) + +#else + +#ifdef CONFIG_PPC_DCR_NATIVE +typedef dcr_host_native_t dcr_host_t; +#define DCR_MAP_OK(host) dcr_map_ok_native(host) +#define dcr_map(dev, dcr_n, dcr_c) dcr_map_native(dev, dcr_n, dcr_c) +#define dcr_unmap(host, dcr_c) dcr_unmap_native(host, dcr_c) +#define dcr_read(host, dcr_n) dcr_read_native(host, dcr_n) +#define dcr_write(host, dcr_n, value) dcr_write_native(host, dcr_n, value) +#else +typedef dcr_host_mmio_t dcr_host_t; +#define DCR_MAP_OK(host) dcr_map_ok_mmio(host) +#define dcr_map(dev, dcr_n, dcr_c) dcr_map_mmio(dev, dcr_n, dcr_c) +#define dcr_unmap(host, dcr_c) dcr_unmap_mmio(host, dcr_c) +#define dcr_read(host, dcr_n) dcr_read_mmio(host, dcr_n) +#define dcr_write(host, dcr_n, value) dcr_write_mmio(host, dcr_n, value) +#endif + +#endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */ + /* * On CONFIG_PPC_MERGE, we have additional helpers to read the DCR * base from the device-tree @@ -41,5 +77,6 @@ extern unsigned int dcr_resource_len(struct device_node *np, #endif /* CONFIG_PPC_MERGE */ #endif /* CONFIG_PPC_DCR */ +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_DCR_H */ -- cgit v0.10.2 From 71f349799b34c8b6ce3df42126b4de6cfa16456d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 15 May 2008 16:46:39 +1000 Subject: [POWERPC] Convert remaining dts-v0 files to v1 At the moment we have a mixture of left-over version 0 and new-format version 1 files in arch/powerpc/boot/dts. This is potentially confusing to people new to the dts format attempting to figure it out. So, this patch converts all the as-yet unconverted dts v0 files and converts them to v1. They're mechanically-converted, and not hand tweaked so in some cases they're not 100% in keeping with usual v1 style, but the convertor program does have some heuristics so the discrepancies aren't too bad. I have checked that this patch produces no changes to the resulting dtb binaries. Signed-off-by: David Gibson Acked-by: Josh Boyer Acked-by: Geoff Levand Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts index ba2521b..6ce0cc2 100644 --- a/arch/powerpc/boot/dts/bamboo.dts +++ b/arch/powerpc/boot/dts/bamboo.dts @@ -11,12 +11,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,bamboo"; compatible = "amcc,bamboo"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -34,13 +36,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440EP"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -48,14 +50,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -65,22 +67,22 @@ compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-440ep"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440ep"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -92,29 +94,29 @@ SDRAM0: sdram { compatible = "ibm,sdram-440ep", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; DMA0: dma { compatible = "ibm,dma-440ep", "ibm,dma-440gp"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440ep", "ibm,mcmal-440gp", "ibm,mcmal"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <4>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; + interrupt-map = ; }; POB0: opb { @@ -124,101 +126,101 @@ /* Bamboo is oddball in the 44x world and doesn't use the ERPN * bits. */ - ranges = <00000000 0 00000000 80000000 - 80000000 0 80000000 80000000>; + ranges = <0x00000000 0x00000000 0x00000000 0x80000000 + 0x80000000 0x00000000 0x80000000 0x80000000>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by zImage */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; }; UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; + current-speed = <115200>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@ef600500 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; UART3: serial@ef600600 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <4 4>; + interrupts = <0x4 0x4>; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600800 { compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = ; + reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; EMAC0: ethernet@ef600e00 { device_type = "network"; compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = ; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0 1>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; }; @@ -227,26 +229,26 @@ device_type = "network"; compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1e 4 1f 4>; - reg = ; + interrupts = <0x1e 0x4 0x1f 0x4>; + reg = <0xef600f00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <2 3>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <1>; }; usb@ef601000 { compatible = "ohci-be"; - reg = ; - interrupts = <8 1 9 1>; + reg = <0xef601000 0x00000080>; + interrupts = <0x8 0x1 0x9 0x1>; interrupt-parent = < &UIC1 >; }; }; @@ -258,35 +260,35 @@ #address-cells = <3>; compatible = "ibm,plb440ep-pci", "ibm,plb-pci"; primary; - reg = <0 eec00000 8 /* Config space access */ - 0 eed00000 4 /* IACK */ - 0 eed00000 4 /* Special cycle */ - 0 ef400000 40>; /* Internal registers */ + reg = <0x00000000 0xeec00000 0x00000008 /* Config space access */ + 0x00000000 0xeed00000 0x00000004 /* IACK */ + 0x00000000 0xeed00000 0x00000004 /* Special cycle */ + 0x00000000 0xef400000 0x00000040>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <02000000 0 a0000000 0 a0000000 0 20000000 - 01000000 0 00000000 0 e8000000 0 00010000>; + ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x20000000 + 0x01000000 0x00000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* Bamboo has all 4 IRQ pins tied together per slot */ - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x0>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 0 &UIC0 1c 8 + 0x800 0x0 0x0 0x0 &UIC0 0x1c 0x8 /* IDSEL 2 */ - 1000 0 0 0 &UIC0 1b 8 + 0x1000 0x0 0x0 0x0 &UIC0 0x1b 0x8 /* IDSEL 3 */ - 1800 0 0 0 &UIC0 1a 8 + 0x1800 0x0 0x0 0x0 &UIC0 0x1a 0x8 /* IDSEL 4 */ - 2000 0 0 0 &UIC0 19 8 + 0x2000 0x0 0x0 0x0 &UIC0 0x19 0x8 >; }; }; diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index 3963412..f9fe032 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts @@ -8,12 +8,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,canyonlands"; compatible = "amcc,canyonlands"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -29,13 +31,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,460EX"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by U-Boot */ timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -43,14 +45,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by U-Boot */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-460ex","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -60,11 +62,11 @@ compatible = "ibm,uic-460ex","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -72,11 +74,11 @@ compatible = "ibm,uic-460ex","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = ; /* cascade */ + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -84,22 +86,22 @@ compatible = "ibm,uic-460ex","ibm,uic"; interrupt-controller; cell-index = <3>; - dcr-reg = <0f0 009>; + dcr-reg = <0x0f0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <10 4 11 4>; /* cascade */ + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-460ex"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-460ex"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -111,74 +113,74 @@ SDRAM0: sdram { compatible = "ibm,sdram-460ex", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL0: mcmal { compatible = "ibm,mcmal-460ex", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; - num-rx-chans = <10>; + num-rx-chans = <16>; #address-cells = <0>; #size-cells = <0>; interrupt-parent = <&UIC2>; - interrupts = < /*TXEOB*/ 6 4 - /*RXEOB*/ 7 4 - /*SERR*/ 3 4 - /*TXDE*/ 4 4 - /*RXDE*/ 5 4>; + interrupts = < /*TXEOB*/ 0x6 0x4 + /*RXEOB*/ 0x7 0x4 + /*SERR*/ 0x3 0x4 + /*TXDE*/ 0x4 0x4 + /*RXDE*/ 0x5 0x4>; }; POB0: opb { compatible = "ibm,opb-460ex", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = ; + ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; clock-frequency = <0>; /* Filled in by U-Boot */ EBC0: ebc { compatible = "ibm,ebc-460ex", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by U-Boot */ /* ranges property is supplied by U-Boot */ - interrupts = <6 4>; + interrupts = <0x6 0x4>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl512n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "kernel"; - reg = <0 1e0000>; + reg = <0x00000000 0x001e0000>; }; partition@1e0000 { label = "dtb"; - reg = <1e0000 20000>; + reg = <0x001e0000 0x00020000>; }; partition@200000 { label = "ramdisk"; - reg = <200000 1400000>; + reg = <0x00200000 0x01400000>; }; partition@1600000 { label = "jffs2"; - reg = <1600000 400000>; + reg = <0x01600000 0x00400000>; }; partition@1a00000 { label = "user"; - reg = <1a00000 2560000>; + reg = <0x01a00000 0x02560000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; }; @@ -186,103 +188,103 @@ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC1>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@ef600500 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC1>; - interrupts = <1d 4>; + interrupts = <0x1d 0x4>; }; UART3: serial@ef600600 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC1>; - interrupts = <1e 4>; + interrupts = <0x1e 0x4>; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-460ex", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600800 { compatible = "ibm,iic-460ex", "ibm,iic"; - reg = ; + reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-460ex", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; RGMII0: emac-rgmii@ef601500 { compatible = "ibm,rgmii-460ex", "ibm,rgmii"; - reg = ; + reg = <0xef601500 0x00000008>; has-mdio; }; TAH0: emac-tah@ef601350 { compatible = "ibm,tah-460ex", "ibm,tah"; - reg = ; + reg = <0xef601350 0x00000030>; }; TAH1: emac-tah@ef601450 { compatible = "ibm,tah-460ex", "ibm,tah"; - reg = ; + reg = <0xef601450 0x00000030>; }; EMAC0: ethernet@ef600e00 { device_type = "network"; compatible = "ibm,emac-460ex", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; tah-device = <&TAH0>; @@ -295,23 +297,23 @@ device_type = "network"; compatible = "ibm,emac-460ex", "ibm,emac4"; interrupt-parent = <&EMAC1>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600f00 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <8>; cell-index = <1>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; tah-device = <&TAH1>; @@ -331,27 +333,27 @@ primary; large-inbound-windows; enable-msi-hole; - reg = ; /* Internal messaging registers */ + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000d 80000000 0 80000000 - 01000000 0 00000000 0000000c 08000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0 to 0x3f */ - bus-range = <0 3f>; + bus-range = <0x0 0x3f>; /* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */ - interrupt-map-mask = <0000 0 0 0>; - interrupt-map = < 0000 0 0 0 &UIC1 0 8 >; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = < 0x0 0x0 0x0 0x0 &UIC1 0x0 0x8 >; }; PCIE0: pciex@d00000000 { @@ -361,23 +363,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; primary; - port = <0>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <100 020>; - sdr-base = <300>; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x08010000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000e 00000000 0 80000000 - 01000000 0 00000000 0000000f 80000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 40 to 0x7f */ - bus-range = <40 7f>; + bus-range = <0x40 0x7f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -387,12 +389,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 c 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 d 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 e 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 f 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0xc 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0xd 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>; }; PCIE1: pciex@d20000000 { @@ -402,23 +404,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; primary; - port = <1>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <120 020>; - sdr-base = <340>; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x08011000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000e 80000000 0 80000000 - 01000000 0 00000000 0000000f 80010000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 80 to 0xbf */ - bus-range = <80 bf>; + bus-range = <0x80 0xbf>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -428,12 +430,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 10 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 11 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 12 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 13 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0x10 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x11 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>; }; }; }; diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts index 5079dc8..ec2d142 100644 --- a/arch/powerpc/boot/dts/ebony.dts +++ b/arch/powerpc/boot/dts/ebony.dts @@ -11,12 +11,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "ibm,ebony"; compatible = "ibm,ebony"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -32,13 +34,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440GP"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; // Filled in by zImage timebase-frequency = <0>; // Filled in by zImage - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; /* 32 kB */ - d-cache-size = <8000>; /* 32 kB */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; /* 32 kB */ + d-cache-size = <32768>; /* 32 kB */ dcr-controller; dcr-access-method = "native"; }; @@ -46,14 +48,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; // Filled in by zImage + reg = <0x00000000 0x00000000 0x00000000>; // Filled in by zImage }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440gp", "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -64,17 +66,17 @@ compatible = "ibm,uic-440gp", "ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; CPC0: cpc { compatible = "ibm,cpc-440gp"; - dcr-reg = <0b0 003 0e0 010>; + dcr-reg = <0x0b0 0x003 0x0e0 0x010>; // FIXME: anything else? }; @@ -87,37 +89,37 @@ SDRAM0: memory-controller { compatible = "ibm,sdram-440gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; // FIXME: anything else? }; SRAM0: sram { compatible = "ibm,sram-440gp"; - dcr-reg = <020 8 00a 1>; + dcr-reg = <0x020 0x008 0x00a 0x001>; }; DMA0: dma { // FIXME: ??? compatible = "ibm,dma-440gp"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440gp", "ibm,mcmal"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <4>; num-rx-chans = <4>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; POB0: opb { @@ -126,34 +128,34 @@ #size-cells = <1>; /* Wish there was a nicer way of specifying a full 32-bit range */ - ranges = <00000000 1 00000000 80000000 - 80000000 1 80000000 80000000>; - dcr-reg = <090 00b>; + ranges = <0x00000000 0x00000001 0x00000000 0x80000000 + 0x80000000 0x00000001 0x80000000 0x80000000>; + dcr-reg = <0x090 0x00b>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; clock-frequency = <0>; // Filled in by zImage EBC0: ebc { compatible = "ibm,ebc-440gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; // Filled in by zImage // ranges property is supplied by zImage // based on firmware's configuration of the // EBC bridge - interrupts = <5 4>; + interrupts = <0x5 0x4>; interrupt-parent = <&UIC1>; small-flash@0,80000 { compatible = "jedec-flash"; bank-width = <1>; - reg = <0 80000 80000>; + reg = <0x00000000 0x00080000 0x00080000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "OpenBIOS"; - reg = <0 80000>; + reg = <0x00000000 0x00080000>; read-only; }; }; @@ -161,101 +163,101 @@ nvram@1,0 { /* NVRAM & RTC */ compatible = "ds1743-nvram"; - #bytes = <2000>; - reg = <1 0 2000>; + #bytes = <0x2000>; + reg = <0x00000001 0x00000000 0x00002000>; }; large-flash@2,0 { compatible = "jedec-flash"; bank-width = <1>; - reg = <2 0 400000>; + reg = <0x00000002 0x00000000 0x00400000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "fs"; - reg = <0 380000>; + reg = <0x00000000 0x00380000>; }; partition@380000 { label = "firmware"; - reg = <380000 80000>; + reg = <0x00380000 0x00080000>; }; }; ir@3,0 { - reg = <3 0 10>; + reg = <0x00000003 0x00000000 0x00000010>; }; fpga@7,0 { compatible = "Ebony-FPGA"; - reg = <7 0 10>; - virtual-reg = ; + reg = <0x00000007 0x00000000 0x00000010>; + virtual-reg = <0xe8300000>; }; }; UART0: serial@40000200 { device_type = "serial"; compatible = "ns16550"; - reg = <40000200 8>; - virtual-reg = ; - clock-frequency = ; - current-speed = <2580>; + reg = <0x40000200 0x00000008>; + virtual-reg = <0xe0000200>; + clock-frequency = <11059200>; + current-speed = <9600>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@40000300 { device_type = "serial"; compatible = "ns16550"; - reg = <40000300 8>; - virtual-reg = ; - clock-frequency = ; - current-speed = <2580>; + reg = <0x40000300 0x00000008>; + virtual-reg = <0xe0000300>; + clock-frequency = <11059200>; + current-speed = <9600>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC0: i2c@40000400 { /* FIXME */ compatible = "ibm,iic-440gp", "ibm,iic"; - reg = <40000400 14>; + reg = <0x40000400 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@40000500 { /* FIXME */ compatible = "ibm,iic-440gp", "ibm,iic"; - reg = <40000500 14>; + reg = <0x40000500 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; GPIO0: gpio@40000700 { /* FIXME */ compatible = "ibm,gpio-440gp"; - reg = <40000700 20>; + reg = <0x40000700 0x00000020>; }; ZMII0: emac-zmii@40000780 { compatible = "ibm,zmii-440gp", "ibm,zmii"; - reg = <40000780 c>; + reg = <0x40000780 0x0000000c>; }; EMAC0: ethernet@40000800 { device_type = "network"; compatible = "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = <40000800 70>; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0x40000800 0x00000070>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <0 1>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000001>; + phy-map = <0x00000001>; zmii-device = <&ZMII0>; zmii-channel = <0>; }; @@ -263,18 +265,18 @@ device_type = "network"; compatible = "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1e 4 1f 4>; - reg = <40000900 70>; + interrupts = <0x1e 0x4 0x1f 0x4>; + reg = <0x40000900 0x00000070>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <2 3>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000001>; + phy-map = <0x00000001>; zmii-device = <&ZMII0>; zmii-channel = <1>; }; @@ -282,9 +284,9 @@ GPT0: gpt@40000a00 { /* FIXME */ - reg = <40000a00 d4>; + reg = <0x40000a00 0x000000d4>; interrupt-parent = <&UIC0>; - interrupts = <12 4 13 4 14 4 15 4 16 4>; + interrupts = <0x12 0x4 0x13 0x4 0x14 0x4 0x15 0x4 0x16 0x4>; }; }; @@ -296,35 +298,35 @@ #address-cells = <3>; compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix"; primary; - reg = <2 0ec00000 8 /* Config space access */ - 0 0 0 /* no IACK cycles */ - 2 0ed00000 4 /* Special cycles */ - 2 0ec80000 f0 /* Internal registers */ - 2 0ec80100 fc>; /* Internal messaging registers */ + reg = <0x00000002 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x00000002 0x0ed00000 0x00000004 /* Special cycles */ + 0x00000002 0x0ec80000 0x000000f0 /* Internal registers */ + 0x00000002 0x0ec80100 0x000000fc>; /* Internal messaging registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 00000003 80000000 0 80000000 - 01000000 0 00000000 00000002 08000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x00000003 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x00000002 0x08000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* Ebony has all 4 IRQ pins tied together per slot */ - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x0>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 0 &UIC0 17 8 + 0x800 0x0 0x0 0x0 &UIC0 0x17 0x8 /* IDSEL 2 */ - 1000 0 0 0 &UIC0 18 8 + 0x1000 0x0 0x0 0x0 &UIC0 0x18 0x8 /* IDSEL 3 */ - 1800 0 0 0 &UIC0 19 8 + 0x1800 0x0 0x0 0x0 &UIC0 0x19 0x8 /* IDSEL 4 */ - 2000 0 0 0 &UIC0 1a 8 + 0x2000 0x0 0x0 0x0 &UIC0 0x1a 0x8 >; }; }; diff --git a/arch/powerpc/boot/dts/ep405.dts b/arch/powerpc/boot/dts/ep405.dts index 9293855..53ef06c 100644 --- a/arch/powerpc/boot/dts/ep405.dts +++ b/arch/powerpc/boot/dts/ep405.dts @@ -9,12 +9,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <1>; #size-cells = <1>; model = "ep405"; compatible = "ep405"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC; @@ -29,13 +31,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,405GP"; - reg = <0>; - clock-frequency = ; /* Filled in by zImage */ + reg = <0x00000000>; + clock-frequency = <200000000>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <4000>; - d-cache-size = <4000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; + d-cache-size = <16384>; dcr-controller; dcr-access-method = "native"; }; @@ -43,14 +45,14 @@ memory { device_type = "memory"; - reg = <0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller { compatible = "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 9>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -65,91 +67,91 @@ SDRAM0: memory-controller { compatible = "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL: mcmal { compatible = "ibm,mcmal-405gp", "ibm,mcmal"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <1>; num-rx-chans = <1>; interrupt-parent = <&UIC0>; interrupts = < - b 4 /* TXEOB */ - c 4 /* RXEOB */ - a 4 /* SERR */ - d 4 /* TXDE */ - e 4 /* RXDE */>; + 0xb 0x4 /* TXEOB */ + 0xc 0x4 /* RXEOB */ + 0xa 0x4 /* SERR */ + 0xd 0x4 /* TXDE */ + 0xe 0x4 /* RXDE */>; }; POB0: opb { compatible = "ibm,opb-405gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = ; - dcr-reg = <0a0 5>; + ranges = <0xef600000 0xef600000 0x00a00000>; + dcr-reg = <0x0a0 0x005>; clock-frequency = <0>; /* Filled in by zImage */ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <2580>; + current-speed = <9600>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <2580>; + current-speed = <9600>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC: i2c@ef600500 { compatible = "ibm,iic-405gp", "ibm,iic"; - reg = ; + reg = <0xef600500 0x00000011>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; GPIO: gpio@ef600700 { compatible = "ibm,gpio-405gp"; - reg = ; + reg = <0xef600700 0x00000020>; }; EMAC: ethernet@ef600800 { - linux,network-index = <0>; + linux,network-index = <0x0>; device_type = "network"; compatible = "ibm,emac-405gp", "ibm,emac"; interrupt-parent = <&UIC0>; interrupts = < - f 4 /* Ethernet */ - 9 4 /* Ethernet Wake Up */>; + 0xf 0x4 /* Ethernet */ + 0x9 0x4 /* Ethernet Wake Up */>; local-mac-address = [000000000000]; /* Filled in by zImage */ - reg = ; + reg = <0xef600800 0x00000070>; mal-device = <&MAL>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; }; }; EBC0: ebc { compatible = "ibm,ebc-405gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; @@ -163,13 +165,13 @@ /* NVRAM and RTC */ nvrtc@4,200000 { compatible = "ds1742"; - reg = <4 200000 0>; /* size fixed up by zImage */ + reg = <0x00000004 0x00200000 0x00000000>; /* size fixed up by zImage */ }; /* "BCSR" CPLD contains a PCI irq controller */ bcsr@4,0 { compatible = "ep405-bcsr"; - reg = <4 0 10>; + reg = <0x00000004 0x00000000 0x00000010>; interrupt-controller; /* Routing table */ irq-routing = [ 00 /* SYSERR */ @@ -198,26 +200,26 @@ #address-cells = <3>; compatible = "ibm,plb405gp-pci", "ibm,plb-pci"; primary; - reg = ; /* Internal registers */ + reg = <0xeec00000 0x00000008 /* Config space access */ + 0xeed80000 0x00000004 /* IACK */ + 0xeed80000 0x00000004 /* Special cycle */ + 0xef480000 0x00000040>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <02000000 0 80000000 80000000 0 20000000 - 01000000 0 00000000 e8000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000 + 0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* That's all I know about IRQs on that thing ... */ - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x0>; interrupt-map = < /* USB */ - 7000 0 0 0 &UIC0 1e 8 /* IRQ5 */ + 0x7000 0x0 0x0 0x0 &UIC0 0x1e 0x8 /* IRQ5 */ >; }; }; diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts index 0f2fc07..463650c 100644 --- a/arch/powerpc/boot/dts/glacier.dts +++ b/arch/powerpc/boot/dts/glacier.dts @@ -8,12 +8,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,glacier"; compatible = "amcc,glacier", "amcc,canyonlands"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -31,13 +33,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,460GT"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by U-Boot */ timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -45,14 +47,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by U-Boot */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-460gt","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -62,11 +64,11 @@ compatible = "ibm,uic-460gt","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -74,11 +76,11 @@ compatible = "ibm,uic-460gt","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = ; /* cascade */ + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -86,22 +88,22 @@ compatible = "ibm,uic-460gt","ibm,uic"; interrupt-controller; cell-index = <3>; - dcr-reg = <0f0 009>; + dcr-reg = <0x0f0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <10 4 11 4>; /* cascade */ + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-460gt"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-460gt"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -113,75 +115,75 @@ SDRAM0: sdram { compatible = "ibm,sdram-460gt", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL0: mcmal { compatible = "ibm,mcmal-460gt", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <4>; - num-rx-chans = <20>; + num-rx-chans = <32>; #address-cells = <0>; #size-cells = <0>; interrupt-parent = <&UIC2>; - interrupts = < /*TXEOB*/ 6 4 - /*RXEOB*/ 7 4 - /*SERR*/ 3 4 - /*TXDE*/ 4 4 - /*RXDE*/ 5 4>; - desc-base-addr-high = <8>; + interrupts = < /*TXEOB*/ 0x6 0x4 + /*RXEOB*/ 0x7 0x4 + /*SERR*/ 0x3 0x4 + /*TXDE*/ 0x4 0x4 + /*RXDE*/ 0x5 0x4>; + desc-base-addr-high = <0x8>; }; POB0: opb { compatible = "ibm,opb-460gt", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = ; + ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; clock-frequency = <0>; /* Filled in by U-Boot */ EBC0: ebc { compatible = "ibm,ebc-460gt", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by U-Boot */ /* ranges property is supplied by U-Boot */ - interrupts = <6 4>; + interrupts = <0x6 0x4>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl512n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "kernel"; - reg = <0 1e0000>; + reg = <0x00000000 0x001e0000>; }; partition@1e0000 { label = "dtb"; - reg = <1e0000 20000>; + reg = <0x001e0000 0x00020000>; }; partition@200000 { label = "ramdisk"; - reg = <200000 1400000>; + reg = <0x00200000 0x01400000>; }; partition@1600000 { label = "jffs2"; - reg = <1600000 400000>; + reg = <0x01600000 0x00400000>; }; partition@1a00000 { label = "user"; - reg = <1a00000 2560000>; + reg = <0x01a00000 0x02560000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; }; @@ -189,109 +191,109 @@ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC1>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@ef600500 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC1>; - interrupts = <1d 4>; + interrupts = <0x1d 0x4>; }; UART3: serial@ef600600 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; /* Filled in by U-Boot */ interrupt-parent = <&UIC1>; - interrupts = <1e 4>; + interrupts = <0x1e 0x4>; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-460gt", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600800 { compatible = "ibm,iic-460gt", "ibm,iic"; - reg = ; + reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-460gt", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; RGMII0: emac-rgmii@ef601500 { compatible = "ibm,rgmii-460gt", "ibm,rgmii"; - reg = ; + reg = <0xef601500 0x00000008>; has-mdio; }; RGMII1: emac-rgmii@ef601600 { compatible = "ibm,rgmii-460gt", "ibm,rgmii"; - reg = ; + reg = <0xef601600 0x00000008>; has-mdio; }; TAH0: emac-tah@ef601350 { compatible = "ibm,tah-460gt", "ibm,tah"; - reg = ; + reg = <0xef601350 0x00000030>; }; TAH1: emac-tah@ef601450 { compatible = "ibm,tah-460gt", "ibm,tah"; - reg = ; + reg = <0xef601450 0x00000030>; }; EMAC0: ethernet@ef600e00 { device_type = "network"; compatible = "ibm,emac-460gt", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; tah-device = <&TAH0>; @@ -304,23 +306,23 @@ device_type = "network"; compatible = "ibm,emac-460gt", "ibm,emac4"; interrupt-parent = <&EMAC1>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600f00 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <8>; cell-index = <1>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; tah-device = <&TAH1>; @@ -334,23 +336,23 @@ device_type = "network"; compatible = "ibm,emac-460gt", "ibm,emac4"; interrupt-parent = <&EMAC2>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef601100 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <2>; - mal-rx-channel = <10>; + mal-rx-channel = <16>; cell-index = <2>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII1>; rgmii-channel = <0>; has-inverted-stacr-oc; @@ -362,23 +364,23 @@ device_type = "network"; compatible = "ibm,emac-460gt", "ibm,emac4"; interrupt-parent = <&EMAC3>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef601200 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <3>; - mal-rx-channel = <18>; + mal-rx-channel = <24>; cell-index = <3>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII1>; rgmii-channel = <1>; has-inverted-stacr-oc; @@ -396,27 +398,27 @@ primary; large-inbound-windows; enable-msi-hole; - reg = ; /* Internal messaging registers */ + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000d 80000000 0 80000000 - 01000000 0 00000000 0000000c 08000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0 to 0x3f */ - bus-range = <0 3f>; + bus-range = <0x0 0x3f>; /* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */ - interrupt-map-mask = <0000 0 0 0>; - interrupt-map = < 0000 0 0 0 &UIC1 0 8 >; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = < 0x0 0x0 0x0 0x0 &UIC1 0x0 0x8 >; }; PCIE0: pciex@d00000000 { @@ -426,23 +428,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; primary; - port = <0>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <100 020>; - sdr-base = <300>; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x08010000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000e 00000000 0 80000000 - 01000000 0 00000000 0000000f 80000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 40 to 0x7f */ - bus-range = <40 7f>; + bus-range = <0x40 0x7f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -452,12 +454,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 c 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 d 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 e 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 f 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0xc 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0xd 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>; }; PCIE1: pciex@d20000000 { @@ -467,23 +469,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; primary; - port = <1>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <120 020>; - sdr-base = <340>; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x08011000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000e 80000000 0 80000000 - 01000000 0 00000000 0000000f 80010000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 80 to 0xbf */ - bus-range = <80 bf>; + bus-range = <0x80 0xbf>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -493,12 +495,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 10 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 11 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 12 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 13 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0x10 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x11 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>; }; }; }; diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index b5d95ac..2c2fcea 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -8,12 +8,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <1>; #size-cells = <1>; model = "amcc,haleakala"; compatible = "amcc,haleakala", "amcc,kilauea"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -28,13 +30,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,405EXr"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by U-Boot */ timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <4000>; /* 16 kB */ - d-cache-size = <4000>; /* 16 kB */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; /* 16 kB */ + d-cache-size = <16384>; /* 16 kB */ dcr-controller; dcr-access-method = "native"; }; @@ -42,14 +44,14 @@ memory { device_type = "memory"; - reg = <0 0>; /* Filled in by U-Boot */ + reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */ }; UIC0: interrupt-controller { compatible = "ibm,uic-405exr", "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -59,11 +61,11 @@ compatible = "ibm,uic-405exr","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -71,11 +73,11 @@ compatible = "ibm,uic-405exr","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1c 4 1d 4>; /* cascade */ + interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -88,72 +90,72 @@ SDRAM0: memory-controller { compatible = "ibm,sdram-405exr"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL0: mcmal { compatible = "ibm,mcmal-405exr", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; POB0: opb { compatible = "ibm,opb-405exr", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <80000000 80000000 10000000 - ef600000 ef600000 a00000 - f0000000 f0000000 10000000>; - dcr-reg = <0a0 5>; + ranges = <0x80000000 0x80000000 0x10000000 + 0xef600000 0xef600000 0x00a00000 + 0xf0000000 0xf0000000 0x10000000>; + dcr-reg = <0x0a0 0x005>; clock-frequency = <0>; /* Filled in by U-Boot */ EBC0: ebc { compatible = "ibm,ebc-405exr", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by U-Boot */ /* ranges property is supplied by U-Boot */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl512n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "kernel"; - reg = <0 200000>; + reg = <0x00000000 0x00200000>; }; partition@200000 { label = "root"; - reg = <200000 200000>; + reg = <0x00200000 0x00200000>; }; partition@400000 { label = "user"; - reg = <400000 3b60000>; + reg = <0x00400000 0x03b60000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; }; @@ -161,68 +163,68 @@ UART0: serial@ef600200 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600200 0x00000008>; + virtual-reg = <0xef600200>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1a 4>; + interrupts = <0x1a 0x4>; }; UART1: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC0: i2c@ef600400 { compatible = "ibm,iic-405exr", "ibm,iic"; - reg = ; + reg = <0xef600400 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600500 { compatible = "ibm,iic-405exr", "ibm,iic"; - reg = ; + reg = <0xef600500 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; RGMII0: emac-rgmii@ef600b00 { compatible = "ibm,rgmii-405exr", "ibm,rgmii"; - reg = ; + reg = <0xef600b00 0x00000104>; has-mdio; }; EMAC0: ethernet@ef600900 { - linux,network-index = <0>; + linux,network-index = <0x0>; device_type = "network"; compatible = "ibm,emac-405exr", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600900 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; has-inverted-stacr-oc; @@ -237,23 +239,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; - port = <0>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <040 020>; - sdr-base = <400>; + port = <0x0>; /* port number */ + reg = <0xa0000000 0x20000000 /* Config space access */ + 0xef000000 0x00001000>; /* Registers */ + dcr-reg = <0x040 0x020>; + sdr-base = <0x400>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 90000000 0 08000000 - 01000000 0 00000000 e0000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x90000000 0x00000000 0x08000000 + 0x01000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0x00 to 0x3f */ - bus-range = <00 3f>; + bus-range = <0x0 0x3f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -263,12 +265,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC2 0 4 /* swizzled int A */ - 0000 0 0 2 &UIC2 1 4 /* swizzled int B */ - 0000 0 0 3 &UIC2 2 4 /* swizzled int C */ - 0000 0 0 4 &UIC2 3 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC2 0x0 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC2 0x1 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC2 0x2 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>; }; }; }; diff --git a/arch/powerpc/boot/dts/holly.dts b/arch/powerpc/boot/dts/holly.dts index b5d8789..f87fe7b 100644 --- a/arch/powerpc/boot/dts/holly.dts +++ b/arch/powerpc/boot/dts/holly.dts @@ -10,6 +10,8 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { model = "41K7339"; compatible = "ibm,holly"; @@ -21,22 +23,22 @@ #size-cells =<0>; PowerPC,750CL@0 { device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; - i-cache-line-size = <20>; - d-cache-size = <8000>; - i-cache-size = <8000>; - d-cache-sets = <80>; - i-cache-sets = <80>; - timebase-frequency = <2faf080>; - clock-frequency = <23c34600>; - bus-frequency = ; + reg = <0x00000000>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + d-cache-sets = <128>; + i-cache-sets = <128>; + timebase-frequency = <50000000>; + clock-frequency = <600000000>; + bus-frequency = <200000000>; }; }; memory@0 { device_type = "memory"; - reg = <00000000 20000000>; + reg = <0x00000000 0x20000000>; }; tsi109@c0000000 { @@ -44,33 +46,33 @@ compatible = "tsi109-bridge", "tsi108-bridge"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 c0000000 00010000>; - reg = ; + ranges = <0x00000000 0xc0000000 0x00010000>; + reg = <0xc0000000 0x00010000>; i2c@7000 { device_type = "i2c"; compatible = "tsi109-i2c", "tsi108-i2c"; interrupt-parent = <&MPIC>; - interrupts = ; - reg = <7000 400>; + interrupts = <0xe 0x2>; + reg = <0x00007000 0x00000400>; }; MDIO: mdio@6000 { device_type = "mdio"; compatible = "tsi109-mdio", "tsi108-mdio"; - reg = <6000 50>; + reg = <0x00006000 0x00000050>; #address-cells = <1>; #size-cells = <0>; PHY1: ethernet-phy@1 { compatible = "bcm5461a"; - reg = <1>; + reg = <0x00000001>; txc-rxc-delay-disable; }; PHY2: ethernet-phy@2 { compatible = "bcm5461a"; - reg = <2>; + reg = <0x00000002>; txc-rxc-delay-disable; }; }; @@ -80,10 +82,10 @@ compatible = "tsi109-ethernet", "tsi108-ethernet"; #address-cells = <1>; #size-cells = <0>; - reg = <6000 200>; + reg = <0x00006000 0x00000200>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupt-parent = <&MPIC>; - interrupts = <10 2>; + interrupts = <0x10 0x2>; mdio-handle = <&MDIO>; phy-handle = <&PHY1>; }; @@ -93,10 +95,10 @@ compatible = "tsi109-ethernet", "tsi108-ethernet"; #address-cells = <1>; #size-cells = <0>; - reg = <6400 200>; + reg = <0x00006400 0x00000200>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupt-parent = <&MPIC>; - interrupts = <11 2>; + interrupts = <0x11 0x2>; mdio-handle = <&MDIO>; phy-handle = <&PHY2>; }; @@ -104,23 +106,23 @@ serial@7808 { device_type = "serial"; compatible = "ns16550"; - reg = <7808 200>; - virtual-reg = ; - clock-frequency = <3F9C6000>; - current-speed = <1c200>; + reg = <0x00007808 0x00000200>; + virtual-reg = <0xc0007808>; + clock-frequency = <1067212800>; + current-speed = <115200>; interrupt-parent = <&MPIC>; - interrupts = ; + interrupts = <0xc 0x2>; }; serial@7c08 { device_type = "serial"; compatible = "ns16550"; - reg = <7c08 200>; - virtual-reg = ; - clock-frequency = <3F9C6000>; - current-speed = <1c200>; + reg = <0x00007c08 0x00000200>; + virtual-reg = <0xc0007c08>; + clock-frequency = <1067212800>; + current-speed = <115200>; interrupt-parent = <&MPIC>; - interrupts = ; + interrupts = <0xd 0x2>; }; MPIC: pic@7400 { @@ -128,7 +130,7 @@ compatible = "chrp,open-pic"; interrupt-controller; #interrupt-cells = <2>; - reg = <7400 400>; + reg = <0x00007400 0x00000400>; big-endian; }; @@ -138,42 +140,42 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <1000 1000>; - bus-range = <0 0>; + reg = <0x00001000 0x00001000>; + bus-range = <0x0 0x0>; /*----------------------------------------------------+ | PCI memory range. | 01 denotes I/O space | 02 denotes 32-bit memory space +----------------------------------------------------*/ - ranges = <02000000 0 40000000 40000000 0 10000000 - 01000000 0 00000000 7e000000 0 00010000>; - clock-frequency = <7f28154>; + ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000 + 0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>; + clock-frequency = <133333332>; interrupt-parent = <&MPIC>; - interrupts = <17 2>; - interrupt-map-mask = ; + interrupts = <0x17 0x2>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; /*----------------------------------------------------+ | The INTA, INTB, INTC, INTD are shared. +----------------------------------------------------*/ interrupt-map = < - 0800 0 0 1 &RT0 24 0 - 0800 0 0 2 &RT0 25 0 - 0800 0 0 3 &RT0 26 0 - 0800 0 0 4 &RT0 27 0 - - 1000 0 0 1 &RT0 25 0 - 1000 0 0 2 &RT0 26 0 - 1000 0 0 3 &RT0 27 0 - 1000 0 0 4 &RT0 24 0 - - 1800 0 0 1 &RT0 26 0 - 1800 0 0 2 &RT0 27 0 - 1800 0 0 3 &RT0 24 0 - 1800 0 0 4 &RT0 25 0 - - 2000 0 0 1 &RT0 27 0 - 2000 0 0 2 &RT0 24 0 - 2000 0 0 3 &RT0 25 0 - 2000 0 0 4 &RT0 26 0 + 0x800 0x0 0x0 0x1 &RT0 0x24 0x0 + 0x800 0x0 0x0 0x2 &RT0 0x25 0x0 + 0x800 0x0 0x0 0x3 &RT0 0x26 0x0 + 0x800 0x0 0x0 0x4 &RT0 0x27 0x0 + + 0x1000 0x0 0x0 0x1 &RT0 0x25 0x0 + 0x1000 0x0 0x0 0x2 &RT0 0x26 0x0 + 0x1000 0x0 0x0 0x3 &RT0 0x27 0x0 + 0x1000 0x0 0x0 0x4 &RT0 0x24 0x0 + + 0x1800 0x0 0x0 0x1 &RT0 0x26 0x0 + 0x1800 0x0 0x0 0x2 &RT0 0x27 0x0 + 0x1800 0x0 0x0 0x3 &RT0 0x24 0x0 + 0x1800 0x0 0x0 0x4 &RT0 0x25 0x0 + + 0x2000 0x0 0x0 0x1 &RT0 0x27 0x0 + 0x2000 0x0 0x0 0x2 &RT0 0x24 0x0 + 0x2000 0x0 0x0 0x3 &RT0 0x25 0x0 + 0x2000 0x0 0x0 0x4 &RT0 0x26 0x0 >; RT0: router@1180 { @@ -183,7 +185,7 @@ clock-frequency = <0>; #address-cells = <0>; #interrupt-cells = <2>; - interrupts = <17 2>; + interrupts = <0x17 0x2>; interrupt-parent = <&MPIC>; }; }; diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index cc2873a..b94bf61 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -12,12 +12,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,katmai"; compatible = "amcc,katmai"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -33,13 +35,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440SPe"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -47,14 +49,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440spe","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -64,11 +66,11 @@ compatible = "ibm,uic-440spe","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -76,11 +78,11 @@ compatible = "ibm,uic-440spe","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = ; /* cascade */ + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -88,22 +90,22 @@ compatible = "ibm,uic-440spe","ibm,uic"; interrupt-controller; cell-index = <3>; - dcr-reg = <0f0 009>; + dcr-reg = <0x0f0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <10 4 11 4>; /* cascade */ + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-440spe"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440spe"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -115,108 +117,108 @@ SDRAM0: sdram { compatible = "ibm,sdram-440spe", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL0: mcmal { compatible = "ibm,mcmal-440spe", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; num-rx-chans = <1>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; + interrupt-map = ; }; POB0: opb { compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 4 e0000000 20000000>; + ranges = <0x00000000 0x00000004 0xe0000000 0x20000000>; clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by zImage */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; }; UART0: serial@10000200 { device_type = "serial"; compatible = "ns16550"; - reg = <10000200 8>; - virtual-reg = ; + reg = <0x10000200 0x00000008>; + virtual-reg = <0xa0000200>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; + current-speed = <115200>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@10000300 { device_type = "serial"; compatible = "ns16550"; - reg = <10000300 8>; - virtual-reg = ; + reg = <0x10000300 0x00000008>; + virtual-reg = <0xa0000300>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@10000600 { device_type = "serial"; compatible = "ns16550"; - reg = <10000600 8>; - virtual-reg = ; + reg = <0x10000600 0x00000008>; + virtual-reg = <0xa0000600>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC1>; - interrupts = <5 4>; + interrupts = <0x5 0x4>; }; IIC0: i2c@10000400 { compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; - reg = <10000400 14>; + reg = <0x10000400 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@10000500 { compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; - reg = <10000500 14>; + reg = <0x10000500 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; EMAC0: ethernet@10000800 { - linux,network-index = <0>; + linux,network-index = <0x0>; device_type = "network"; compatible = "ibm,emac-440spe", "ibm,emac4"; interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = <10000800 70>; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0x10000800 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "gmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; has-inverted-stacr-oc; has-new-stacr-staopc; }; @@ -231,23 +233,23 @@ primary; large-inbound-windows; enable-msi-hole; - reg = ; /* Internal messaging registers */ + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000d 80000000 0 80000000 - 01000000 0 00000000 0000000c 08000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0 to 0xf */ - bus-range = <0 f>; + bus-range = <0x0 0xf>; /* * On Katmai, the following PCI-X interrupts signals @@ -258,13 +260,13 @@ * INTC: J2: 1-2 * INTD: J1: 1-2 */ - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 1 &UIC1 14 8 - 0800 0 0 2 &UIC1 13 8 - 0800 0 0 3 &UIC1 12 8 - 0800 0 0 4 &UIC1 11 8 + 0x800 0x0 0x0 0x1 &UIC1 0x14 0x8 + 0x800 0x0 0x0 0x2 &UIC1 0x13 0x8 + 0x800 0x0 0x0 0x3 &UIC1 0x12 0x8 + 0x800 0x0 0x0 0x4 &UIC1 0x11 0x8 >; }; @@ -275,23 +277,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; primary; - port = <0>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <100 020>; - sdr-base = <300>; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x10000000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000e 00000000 0 80000000 - 01000000 0 00000000 0000000f 80000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 10 to 0x1f */ - bus-range = <10 1f>; + bus-range = <0x10 0x1f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -301,12 +303,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 0 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 1 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 2 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 3 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>; }; PCIE1: pciex@d20000000 { @@ -316,23 +318,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; primary; - port = <1>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <120 020>; - sdr-base = <340>; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x10001000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000e 80000000 0 80000000 - 01000000 0 00000000 0000000f 80010000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 10 to 0x1f */ - bus-range = <20 2f>; + bus-range = <0x20 0x2f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -342,12 +344,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 4 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 5 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 6 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 7 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>; }; PCIE2: pciex@d40000000 { @@ -357,23 +359,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; primary; - port = <2>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <140 020>; - sdr-base = <370>; + port = <0x2>; /* port number */ + reg = <0x0000000d 0x40000000 0x20000000 /* Config space access */ + 0x0000000c 0x10002000 0x00001000>; /* Registers */ + dcr-reg = <0x140 0x020>; + sdr-base = <0x370>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 0000000f 00000000 0 80000000 - 01000000 0 00000000 0000000f 80020000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 10 to 0x1f */ - bus-range = <30 3f>; + bus-range = <0x30 0x3f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -383,12 +385,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC3 8 4 /* swizzled int A */ - 0000 0 0 2 &UIC3 9 4 /* swizzled int B */ - 0000 0 0 3 &UIC3 a 4 /* swizzled int C */ - 0000 0 0 4 &UIC3 b 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; }; }; diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts index 48c9a6e..3ed6a8f 100644 --- a/arch/powerpc/boot/dts/kilauea.dts +++ b/arch/powerpc/boot/dts/kilauea.dts @@ -8,12 +8,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <1>; #size-cells = <1>; model = "amcc,kilauea"; compatible = "amcc,kilauea"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -29,13 +31,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,405EX"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by U-Boot */ timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <4000>; /* 16 kB */ - d-cache-size = <4000>; /* 16 kB */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; /* 16 kB */ + d-cache-size = <16384>; /* 16 kB */ dcr-controller; dcr-access-method = "native"; }; @@ -43,14 +45,14 @@ memory { device_type = "memory"; - reg = <0 0>; /* Filled in by U-Boot */ + reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */ }; UIC0: interrupt-controller { compatible = "ibm,uic-405ex", "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -60,11 +62,11 @@ compatible = "ibm,uic-405ex","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -72,11 +74,11 @@ compatible = "ibm,uic-405ex","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1c 4 1d 4>; /* cascade */ + interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -89,72 +91,72 @@ SDRAM0: memory-controller { compatible = "ibm,sdram-405ex"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL0: mcmal { compatible = "ibm,mcmal-405ex", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; POB0: opb { compatible = "ibm,opb-405ex", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <80000000 80000000 10000000 - ef600000 ef600000 a00000 - f0000000 f0000000 10000000>; - dcr-reg = <0a0 5>; + ranges = <0x80000000 0x80000000 0x10000000 + 0xef600000 0xef600000 0x00a00000 + 0xf0000000 0xf0000000 0x10000000>; + dcr-reg = <0x0a0 0x005>; clock-frequency = <0>; /* Filled in by U-Boot */ EBC0: ebc { compatible = "ibm,ebc-405ex", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by U-Boot */ /* ranges property is supplied by U-Boot */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl512n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "kernel"; - reg = <0 200000>; + reg = <0x00000000 0x00200000>; }; partition@200000 { label = "root"; - reg = <200000 200000>; + reg = <0x00200000 0x00200000>; }; partition@400000 { label = "user"; - reg = <400000 3b60000>; + reg = <0x00400000 0x03b60000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; }; @@ -162,68 +164,68 @@ UART0: serial@ef600200 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600200 0x00000008>; + virtual-reg = <0xef600200>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1a 4>; + interrupts = <0x1a 0x4>; }; UART1: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC0: i2c@ef600400 { compatible = "ibm,iic-405ex", "ibm,iic"; - reg = ; + reg = <0xef600400 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600500 { compatible = "ibm,iic-405ex", "ibm,iic"; - reg = ; + reg = <0xef600500 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; RGMII0: emac-rgmii@ef600b00 { compatible = "ibm,rgmii-405ex", "ibm,rgmii"; - reg = ; + reg = <0xef600b00 0x00000104>; has-mdio; }; EMAC0: ethernet@ef600900 { - linux,network-index = <0>; + linux,network-index = <0x0>; device_type = "network"; compatible = "ibm,emac-405ex", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600900 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; has-inverted-stacr-oc; @@ -231,27 +233,27 @@ }; EMAC1: ethernet@ef600a00 { - linux,network-index = <1>; + linux,network-index = <0x1>; device_type = "network"; compatible = "ibm,emac-405ex", "ibm,emac4"; interrupt-parent = <&EMAC1>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600a00 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; has-inverted-stacr-oc; @@ -266,23 +268,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; - port = <0>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <040 020>; - sdr-base = <400>; + port = <0x0>; /* port number */ + reg = <0xa0000000 0x20000000 /* Config space access */ + 0xef000000 0x00001000>; /* Registers */ + dcr-reg = <0x040 0x020>; + sdr-base = <0x400>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 90000000 0 08000000 - 01000000 0 00000000 e0000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x90000000 0x00000000 0x08000000 + 0x01000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0x00 to 0x3f */ - bus-range = <00 3f>; + bus-range = <0x0 0x3f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -292,12 +294,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC2 0 4 /* swizzled int A */ - 0000 0 0 2 &UIC2 1 4 /* swizzled int B */ - 0000 0 0 3 &UIC2 2 4 /* swizzled int C */ - 0000 0 0 4 &UIC2 3 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC2 0x0 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC2 0x1 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC2 0x2 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>; }; PCIE1: pciex@0c0000000 { @@ -307,23 +309,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; - port = <1>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <060 020>; - sdr-base = <440>; + port = <0x1>; /* port number */ + reg = <0xc0000000 0x20000000 /* Config space access */ + 0xef001000 0x00001000>; /* Registers */ + dcr-reg = <0x060 0x020>; + sdr-base = <0x440>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 98000000 0 08000000 - 01000000 0 00000000 e0010000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x98000000 0x00000000 0x08000000 + 0x01000000 0x00000000 0x00000000 0xe0010000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0x40 to 0x7f */ - bus-range = <40 7f>; + bus-range = <0x40 0x7f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -333,12 +335,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC2 b 4 /* swizzled int A */ - 0000 0 0 2 &UIC2 c 4 /* swizzled int B */ - 0000 0 0 3 &UIC2 d 4 /* swizzled int C */ - 0000 0 0 4 &UIC2 e 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC2 0xb 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC2 0xc 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>; }; }; }; diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts index 84cc5e7..1dfcd7e 100644 --- a/arch/powerpc/boot/dts/makalu.dts +++ b/arch/powerpc/boot/dts/makalu.dts @@ -8,12 +8,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <1>; #size-cells = <1>; model = "amcc,makalu"; compatible = "amcc,makalu"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -29,13 +31,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,405EX"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by U-Boot */ timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <4000>; /* 16 kB */ - d-cache-size = <4000>; /* 16 kB */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; /* 16 kB */ + d-cache-size = <16384>; /* 16 kB */ dcr-controller; dcr-access-method = "native"; }; @@ -43,14 +45,14 @@ memory { device_type = "memory"; - reg = <0 0>; /* Filled in by U-Boot */ + reg = <0x00000000 0x00000000>; /* Filled in by U-Boot */ }; UIC0: interrupt-controller { compatible = "ibm,uic-405ex", "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -60,11 +62,11 @@ compatible = "ibm,uic-405ex","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -72,11 +74,11 @@ compatible = "ibm,uic-405ex","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1c 4 1d 4>; /* cascade */ + interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -89,72 +91,72 @@ SDRAM0: memory-controller { compatible = "ibm,sdram-405ex"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL0: mcmal { compatible = "ibm,mcmal-405ex", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; POB0: opb { compatible = "ibm,opb-405ex", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <80000000 80000000 10000000 - ef600000 ef600000 a00000 - f0000000 f0000000 10000000>; - dcr-reg = <0a0 5>; + ranges = <0x80000000 0x80000000 0x10000000 + 0xef600000 0xef600000 0x00a00000 + 0xf0000000 0xf0000000 0x10000000>; + dcr-reg = <0x0a0 0x005>; clock-frequency = <0>; /* Filled in by U-Boot */ EBC0: ebc { compatible = "ibm,ebc-405ex", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by U-Boot */ /* ranges property is supplied by U-Boot */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl512n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "kernel"; - reg = <0 200000>; + reg = <0x00000000 0x00200000>; }; partition@200000 { label = "root"; - reg = <200000 200000>; + reg = <0x00200000 0x00200000>; }; partition@400000 { label = "user"; - reg = <400000 3b60000>; + reg = <0x00400000 0x03b60000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; }; @@ -162,68 +164,68 @@ UART0: serial@ef600200 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600200 0x00000008>; + virtual-reg = <0xef600200>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1a 4>; + interrupts = <0x1a 0x4>; }; UART1: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by U-Boot */ current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC0: i2c@ef600400 { compatible = "ibm,iic-405ex", "ibm,iic"; - reg = ; + reg = <0xef600400 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600500 { compatible = "ibm,iic-405ex", "ibm,iic"; - reg = ; + reg = <0xef600500 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; RGMII0: emac-rgmii@ef600b00 { compatible = "ibm,rgmii-405ex", "ibm,rgmii"; - reg = ; + reg = <0xef600b00 0x00000104>; has-mdio; }; EMAC0: ethernet@ef600900 { - linux,network-index = <0>; + linux,network-index = <0x0>; device_type = "network"; compatible = "ibm,emac-405ex", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600900 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <0000003f>; /* Start at 6 */ + phy-map = <0x0000003f>; /* Start at 6 */ rgmii-device = <&RGMII0>; rgmii-channel = <0>; has-inverted-stacr-oc; @@ -231,27 +233,27 @@ }; EMAC1: ethernet@ef600a00 { - linux,network-index = <1>; + linux,network-index = <0x1>; device_type = "network"; compatible = "ibm,emac-405ex", "ibm,emac4"; interrupt-parent = <&EMAC1>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600a00 0x00000070>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; has-inverted-stacr-oc; @@ -266,23 +268,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; - port = <0>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <040 020>; - sdr-base = <400>; + port = <0x0>; /* port number */ + reg = <0xa0000000 0x20000000 /* Config space access */ + 0xef000000 0x00001000>; /* Registers */ + dcr-reg = <0x040 0x020>; + sdr-base = <0x400>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 90000000 0 08000000 - 01000000 0 00000000 e0000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x90000000 0x00000000 0x08000000 + 0x01000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0x00 to 0x3f */ - bus-range = <00 3f>; + bus-range = <0x0 0x3f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -292,12 +294,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC2 0 4 /* swizzled int A */ - 0000 0 0 2 &UIC2 1 4 /* swizzled int B */ - 0000 0 0 3 &UIC2 2 4 /* swizzled int C */ - 0000 0 0 4 &UIC2 3 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC2 0x0 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC2 0x1 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC2 0x2 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC2 0x3 0x4 /* swizzled int D */>; }; PCIE1: pciex@0c0000000 { @@ -307,23 +309,23 @@ #address-cells = <3>; compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; - port = <1>; /* port number */ - reg = ; /* Registers */ - dcr-reg = <060 020>; - sdr-base = <440>; + port = <0x1>; /* port number */ + reg = <0xc0000000 0x20000000 /* Config space access */ + 0xef001000 0x00001000>; /* Registers */ + dcr-reg = <0x060 0x020>; + sdr-base = <0x440>; /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 98000000 0 08000000 - 01000000 0 00000000 e0010000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x98000000 0x00000000 0x08000000 + 0x01000000 0x00000000 0x00000000 0xe0010000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* This drives busses 0x40 to 0x7f */ - bus-range = <40 7f>; + bus-range = <0x40 0x7f>; /* Legacy interrupts (note the weird polarity, the bridge seems * to invert PCIe legacy interrupts). @@ -333,12 +335,12 @@ * below are basically de-swizzled numbers. * The real slot is on idsel 0, so the swizzling is 1:1 */ - interrupt-map-mask = <0000 0 0 7>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = < - 0000 0 0 1 &UIC2 b 4 /* swizzled int A */ - 0000 0 0 2 &UIC2 c 4 /* swizzled int B */ - 0000 0 0 3 &UIC2 d 4 /* swizzled int C */ - 0000 0 0 4 &UIC2 e 4 /* swizzled int D */>; + 0x0 0x0 0x0 0x1 &UIC2 0xb 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC2 0xc 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>; }; }; }; diff --git a/arch/powerpc/boot/dts/ps3.dts b/arch/powerpc/boot/dts/ps3.dts index 379ded2..96ba5b5 100644 --- a/arch/powerpc/boot/dts/ps3.dts +++ b/arch/powerpc/boot/dts/ps3.dts @@ -18,6 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/dts-v1/; + / { model = "SonyPS3"; compatible = "sony,ps3"; @@ -34,7 +36,7 @@ memory { device_type = "memory"; - reg = <0 0 0 0>; + reg = <0x00000000 0x00000000 0x00000000 0x00000000>; }; /* @@ -55,14 +57,14 @@ cpu@0 { device_type = "cpu"; - reg = <0>; - ibm,ppc-interrupt-server#s = <0 1>; + reg = <0x00000000>; + ibm,ppc-interrupt-server#s = <0x0 0x1>; clock-frequency = <0>; timebase-frequency = <0>; - i-cache-size = <8000>; - d-cache-size = <8000>; - i-cache-line-size = <80>; - d-cache-line-size = <80>; + i-cache-size = <32768>; + d-cache-size = <32768>; + i-cache-line-size = <128>; + d-cache-line-size = <128>; }; }; }; diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts index 6a8fa70..2cd87f6 100644 --- a/arch/powerpc/boot/dts/rainier.dts +++ b/arch/powerpc/boot/dts/rainier.dts @@ -12,12 +12,14 @@ * */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,rainier"; compatible = "amcc,rainier"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -35,13 +37,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440GRx"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -49,14 +51,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440grx","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -66,11 +68,11 @@ compatible = "ibm,uic-440grx","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -78,22 +80,22 @@ compatible = "ibm,uic-440grx","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1c 4 1d 4>; /* cascade */ + interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-440grx", "ibm,sdr-440ep"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440grx", "ibm,cpr-440ep"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -105,80 +107,80 @@ SDRAM0: sdram { compatible = "ibm,sdram-440grx", "ibm,sdram-44x-ddr2denali"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; DMA0: dma { compatible = "ibm,dma-440grx", "ibm,dma-4xx"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440grx", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; POB0: opb { compatible = "ibm,opb-440grx", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 1 00000000 80000000 - 80000000 1 80000000 80000000>; + ranges = <0x00000000 0x00000001 0x00000000 0x80000000 + 0x80000000 0x00000001 0x80000000 0x80000000>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440grx", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by zImage */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl256n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "Kernel"; - reg = <0 180000>; + reg = <0x00000000 0x00180000>; }; partition@180000 { label = "ramdisk"; - reg = <180000 200000>; + reg = <0x00180000 0x00200000>; }; partition@380000 { label = "file system"; - reg = <380000 3aa0000>; + reg = <0x00380000 0x03aa0000>; }; partition@3e20000 { label = "kozio"; - reg = <3e20000 140000>; + reg = <0x03e20000 0x00140000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; @@ -187,69 +189,69 @@ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; + current-speed = <115200>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@ef600500 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC1>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; UART3: serial@ef600600 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC1>; - interrupts = <4 4>; + interrupts = <0x4 0x4>; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-440grx", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600800 { compatible = "ibm,iic-440grx", "ibm,iic"; - reg = ; + reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-440grx", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; RGMII0: emac-rgmii@ef601000 { compatible = "ibm,rgmii-440grx", "ibm,rgmii"; - reg = ; + reg = <0xef601000 0x00000008>; has-mdio; }; @@ -257,23 +259,23 @@ device_type = "network"; compatible = "ibm,emac-440grx", "ibm,emac-440epx", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; rgmii-device = <&RGMII0>; @@ -286,23 +288,23 @@ device_type = "network"; compatible = "ibm,emac-440grx", "ibm,emac-440epx", "ibm,emac4"; interrupt-parent = <&EMAC1>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600f00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <1>; rgmii-device = <&RGMII0>; @@ -319,24 +321,24 @@ #address-cells = <3>; compatible = "ibm,plb440grx-pci", "ibm,plb-pci"; primary; - reg = <1 eec00000 8 /* Config space access */ - 1 eed00000 4 /* IACK */ - 1 eed00000 4 /* Special cycle */ - 1 ef400000 40>; /* Internal registers */ + reg = <0x00000001 0xeec00000 0x00000008 /* Config space access */ + 0x00000001 0xeed00000 0x00000004 /* IACK */ + 0x00000001 0xeed00000 0x00000004 /* Special cycle */ + 0x00000001 0xef400000 0x00000040>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <02000000 0 80000000 1 80000000 0 10000000 - 01000000 0 00000000 1 e8000000 0 00100000>; + ranges = <0x02000000 0x00000000 0x80000000 0x00000001 0x80000000 0x00000000 0x10000000 + 0x01000000 0x00000000 0x00000000 0x00000001 0xe8000000 0x00000000 0x00100000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* All PCI interrupts are routed to IRQ 67 */ - interrupt-map-mask = <0000 0 0 0>; - interrupt-map = < 0000 0 0 0 &UIC2 3 8 >; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = < 0x0 0x0 0x0 0x0 &UIC2 0x3 0x8 >; }; }; diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts index 72d6756..149dabc 100644 --- a/arch/powerpc/boot/dts/sequoia.dts +++ b/arch/powerpc/boot/dts/sequoia.dts @@ -12,12 +12,14 @@ * */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,sequoia"; compatible = "amcc,sequoia"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -35,13 +37,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440EPx"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -49,14 +51,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440epx","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -66,11 +68,11 @@ compatible = "ibm,uic-440epx","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; @@ -78,22 +80,22 @@ compatible = "ibm,uic-440epx","ibm,uic"; interrupt-controller; cell-index = <2>; - dcr-reg = <0e0 009>; + dcr-reg = <0x0e0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1c 4 1d 4>; /* cascade */ + interrupts = <0x1c 0x4 0x1d 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-440epx", "ibm,sdr-440ep"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440epx", "ibm,cpr-440ep"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -105,44 +107,44 @@ SDRAM0: sdram { compatible = "ibm,sdram-440epx", "ibm,sdram-44x-ddr2denali"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; DMA0: dma { compatible = "ibm,dma-440epx", "ibm,dma-4xx"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440epx", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <2>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; USB1: usb@e0000400 { compatible = "ohci-be"; - reg = <0 e0000400 60>; + reg = <0x00000000 0xe0000400 0x00000060>; interrupt-parent = <&UIC0>; - interrupts = <15 8>; + interrupts = <0x15 0x8>; }; USB0: ehci@e0000300 { compatible = "ibm,usb-ehci-440epx", "usb-ehci"; interrupt-parent = <&UIC0>; - interrupts = <1a 4>; - reg = <0 e0000300 90 0 e0000390 70>; + interrupts = <0x1a 0x4>; + reg = <0x00000000 0xe0000300 0x00000090 0x00000000 0xe0000390 0x00000070>; big-endian; }; @@ -150,50 +152,50 @@ compatible = "ibm,opb-440epx", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 1 00000000 80000000 - 80000000 1 80000000 80000000>; + ranges = <0x00000000 0x00000001 0x00000000 0x80000000 + 0x80000000 0x00000001 0x80000000 0x80000000>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440epx", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by zImage */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; nor_flash@0,0 { compatible = "amd,s29gl256n", "cfi-flash"; bank-width = <2>; - reg = <0 000000 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "Kernel"; - reg = <0 180000>; + reg = <0x00000000 0x00180000>; }; partition@180000 { label = "ramdisk"; - reg = <180000 200000>; + reg = <0x00180000 0x00200000>; }; partition@380000 { label = "file system"; - reg = <380000 3aa0000>; + reg = <0x00380000 0x03aa0000>; }; partition@3e20000 { label = "kozio"; - reg = <3e20000 140000>; + reg = <0x03e20000 0x00140000>; }; partition@3f60000 { label = "env"; - reg = <3f60000 40000>; + reg = <0x03f60000 0x00040000>; }; partition@3fa0000 { label = "u-boot"; - reg = <3fa0000 60000>; + reg = <0x03fa0000 0x00060000>; }; }; @@ -202,69 +204,69 @@ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; + current-speed = <115200>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@ef600500 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC1>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; UART3: serial@ef600600 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC1>; - interrupts = <4 4>; + interrupts = <0x4 0x4>; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-440epx", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600800 { compatible = "ibm,iic-440epx", "ibm,iic"; - reg = ; + reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-440epx", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; RGMII0: emac-rgmii@ef601000 { compatible = "ibm,rgmii-440epx", "ibm,rgmii"; - reg = ; + reg = <0xef601000 0x00000008>; has-mdio; }; @@ -272,23 +274,23 @@ device_type = "network"; compatible = "ibm,emac-440epx", "ibm,emac4"; interrupt-parent = <&EMAC0>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; rgmii-device = <&RGMII0>; @@ -301,23 +303,23 @@ device_type = "network"; compatible = "ibm,emac-440epx", "ibm,emac4"; interrupt-parent = <&EMAC1>; - interrupts = <0 1>; + interrupts = <0x0 0x1>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - reg = ; + interrupt-map = ; + reg = <0xef600f00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <1>; rgmii-device = <&RGMII0>; @@ -334,10 +336,10 @@ #address-cells = <3>; compatible = "ibm,plb440epx-pci", "ibm,plb-pci"; primary; - reg = <1 eec00000 8 /* Config space access */ - 1 eed00000 4 /* IACK */ - 1 eed00000 4 /* Special cycle */ - 1 ef400000 40>; /* Internal registers */ + reg = <0x00000001 0xeec00000 0x00000008 /* Config space access */ + 0x00000001 0xeed00000 0x00000004 /* IACK */ + 0x00000001 0xeed00000 0x00000004 /* Special cycle */ + 0x00000001 0xef400000 0x00000040>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second @@ -347,16 +349,16 @@ * I/O 1 E800 0000 1 E800 FFFF 64KB * I/O 1 E880 0000 1 EBFF FFFF 56MB */ - ranges = <02000000 0 80000000 1 80000000 0 40000000 - 01000000 0 00000000 1 e8000000 0 00010000 - 01000000 0 00000000 1 e8800000 0 03800000>; + ranges = <0x02000000 0x00000000 0x80000000 0x00000001 0x80000000 0x00000000 0x40000000 + 0x01000000 0x00000000 0x00000000 0x00000001 0xe8000000 0x00000000 0x00010000 + 0x01000000 0x00000000 0x00000000 0x00000001 0xe8800000 0x00000000 0x03800000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* All PCI interrupts are routed to IRQ 67 */ - interrupt-map-mask = <0000 0 0 0>; - interrupt-map = < 0000 0 0 0 &UIC2 3 8 >; + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = < 0x0 0x0 0x0 0x0 &UIC2 0x3 0x8 >; }; }; diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts index e808e1c..dcb7498 100644 --- a/arch/powerpc/boot/dts/taishan.dts +++ b/arch/powerpc/boot/dts/taishan.dts @@ -10,12 +10,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,taishan"; compatible = "amcc,taishan"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC2; @@ -31,13 +33,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440GX"; - reg = <0>; - clock-frequency = <2FAF0800>; // 800MHz + reg = <0x00000000>; + clock-frequency = <800000000>; // 800MHz timebase-frequency = <0>; // Filled in by zImage - i-cache-line-size = <32>; - d-cache-line-size = <32>; - i-cache-size = <8000>; /* 32 kB */ - d-cache-size = <8000>; /* 32 kB */ + i-cache-line-size = <50>; + d-cache-line-size = <50>; + i-cache-size = <32768>; /* 32 kB */ + d-cache-size = <32768>; /* 32 kB */ dcr-controller; dcr-access-method = "native"; }; @@ -45,7 +47,7 @@ memory { device_type = "memory"; - reg = <0 0 0>; // Filled in by zImage + reg = <0x00000000 0x00000000 0x00000000>; // Filled in by zImage }; @@ -53,7 +55,7 @@ compatible = "ibm,uic-440gx", "ibm,uic"; interrupt-controller; cell-index = <3>; - dcr-reg = <200 009>; + dcr-reg = <0x200 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -64,11 +66,11 @@ compatible = "ibm,uic-440gx", "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <01 4 00 4>; /* cascade - first non-critical */ + interrupts = <0x1 0x4 0x0 0x4>; /* cascade - first non-critical */ interrupt-parent = <&UICB0>; }; @@ -77,11 +79,11 @@ compatible = "ibm,uic-440gx", "ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <03 4 02 4>; /* cascade */ + interrupts = <0x3 0x4 0x2 0x4>; /* cascade */ interrupt-parent = <&UICB0>; }; @@ -89,29 +91,29 @@ compatible = "ibm,uic-440gx", "ibm,uic"; interrupt-controller; cell-index = <2>; /* was 1 */ - dcr-reg = <210 009>; + dcr-reg = <0x210 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <05 4 04 4>; /* cascade */ + interrupts = <0x5 0x4 0x4 0x4>; /* cascade */ interrupt-parent = <&UICB0>; }; CPC0: cpc { compatible = "ibm,cpc-440gp"; - dcr-reg = <0b0 003 0e0 010>; + dcr-reg = <0x0b0 0x003 0x0e0 0x010>; // FIXME: anything else? }; L2C0: l2c { compatible = "ibm,l2-cache-440gx", "ibm,l2-cache"; - dcr-reg = <20 8 /* Internal SRAM DCR's */ - 30 8>; /* L2 cache DCR's */ - cache-line-size = <20>; /* 32 bytes */ - cache-size = <40000>; /* L2, 256K */ + dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */ + 0x030 0x008>; /* L2 cache DCR's */ + cache-line-size = <32>; /* 32 bytes */ + cache-size = <262144>; /* L2, 256K */ interrupt-parent = <&UIC2>; - interrupts = <17 1>; + interrupts = <0x17 0x1>; }; plb { @@ -119,41 +121,41 @@ #address-cells = <2>; #size-cells = <1>; ranges; - clock-frequency = <9896800>; // 160MHz + clock-frequency = <160000000>; // 160MHz SDRAM0: memory-controller { compatible = "ibm,sdram-440gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; // FIXME: anything else? }; SRAM0: sram { compatible = "ibm,sram-440gp"; - dcr-reg = <020 8 00a 1>; + dcr-reg = <0x020 0x008 0x00a 0x001>; }; DMA0: dma { // FIXME: ??? compatible = "ibm,dma-440gp"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440gx", "ibm,mcmal2"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <4>; num-rx-chans = <4>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; + interrupt-map = ; + interrupt-map-mask = <0xffffffff>; }; POB0: opb { @@ -162,26 +164,26 @@ #size-cells = <1>; /* Wish there was a nicer way of specifying a full 32-bit range */ - ranges = <00000000 1 00000000 80000000 - 80000000 1 80000000 80000000>; - dcr-reg = <090 00b>; + ranges = <0x00000000 0x00000001 0x00000000 0x80000000 + 0x80000000 0x00000001 0x80000000 0x80000000>; + dcr-reg = <0x090 0x00b>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; - clock-frequency = <4C4B400>; // 80MHz + interrupts = <0x7 0x4>; + clock-frequency = <80000000>; // 80MHz EBC0: ebc { compatible = "ibm,ebc-440gx", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; - clock-frequency = <4C4B400>; // 80MHz + clock-frequency = <80000000>; // 80MHz /* ranges property is supplied by zImage * based on firmware's configuration of the * EBC bridge */ - interrupts = <5 4>; + interrupts = <0x5 0x4>; interrupt-parent = <&UIC1>; /* TODO: Add other EBC devices */ @@ -192,103 +194,103 @@ UART0: serial@40000200 { device_type = "serial"; compatible = "ns16550"; - reg = <40000200 8>; - virtual-reg = ; - clock-frequency = ; - current-speed = <1C200>; /* 115200 */ + reg = <0x40000200 0x00000008>; + virtual-reg = <0xe0000200>; + clock-frequency = <11059200>; + current-speed = <115200>; /* 115200 */ interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@40000300 { device_type = "serial"; compatible = "ns16550"; - reg = <40000300 8>; - virtual-reg = ; - clock-frequency = ; - current-speed = <1C200>; /* 115200 */ + reg = <0x40000300 0x00000008>; + virtual-reg = <0xe0000300>; + clock-frequency = <11059200>; + current-speed = <115200>; /* 115200 */ interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC0: i2c@40000400 { /* FIXME */ compatible = "ibm,iic-440gp", "ibm,iic"; - reg = <40000400 14>; + reg = <0x40000400 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@40000500 { /* FIXME */ compatible = "ibm,iic-440gp", "ibm,iic"; - reg = <40000500 14>; + reg = <0x40000500 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; }; GPIO0: gpio@40000700 { /* FIXME */ compatible = "ibm,gpio-440gp"; - reg = <40000700 20>; + reg = <0x40000700 0x00000020>; }; ZMII0: emac-zmii@40000780 { compatible = "ibm,zmii-440gx", "ibm,zmii"; - reg = <40000780 c>; + reg = <0x40000780 0x0000000c>; }; RGMII0: emac-rgmii@40000790 { compatible = "ibm,rgmii"; - reg = <40000790 8>; + reg = <0x40000790 0x00000008>; }; TAH0: emac-tah@40000b50 { compatible = "ibm,tah-440gx", "ibm,tah"; - reg = <40000b50 30>; + reg = <0x40000b50 0x00000030>; }; TAH1: emac-tah@40000d50 { compatible = "ibm,tah-440gx", "ibm,tah"; - reg = <40000d50 30>; + reg = <0x40000d50 0x00000030>; }; EMAC0: ethernet@40000800 { - unused = <1>; + unused = <0x1>; device_type = "network"; compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = <40000800 70>; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0x40000800 0x00000070>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000001>; + phy-map = <0x00000001>; zmii-device = <&ZMII0>; zmii-channel = <0>; }; EMAC1: ethernet@40000900 { - unused = <1>; + unused = <0x1>; device_type = "network"; compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC1>; - interrupts = <1e 4 1f 4>; - reg = <40000900 70>; + interrupts = <0x1e 0x4 0x1f 0x4>; + reg = <0x40000900 0x00000070>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <1>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000001>; + phy-map = <0x00000001>; zmii-device = <&ZMII0>; zmii-channel = <1>; }; @@ -297,18 +299,18 @@ device_type = "network"; compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC2>; - interrupts = <0 4 1 4>; - reg = <40000c00 70>; + interrupts = <0x0 0x4 0x1 0x4>; + reg = <0x40000c00 0x00000070>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <2>; mal-rx-channel = <2>; cell-index = <2>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000001>; + phy-map = <0x00000001>; rgmii-device = <&RGMII0>; rgmii-channel = <0>; zmii-device = <&ZMII0>; @@ -321,18 +323,18 @@ device_type = "network"; compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC2>; - interrupts = <2 4 3 4>; - reg = <40000e00 70>; + interrupts = <0x2 0x4 0x3 0x4>; + reg = <0x40000e00 0x00000070>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <3>; mal-rx-channel = <3>; cell-index = <3>; - max-frame-size = <2328>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rgmii"; - phy-map = <00000003>; + phy-map = <0x00000003>; rgmii-device = <&RGMII0>; rgmii-channel = <1>; zmii-device = <&ZMII0>; @@ -344,9 +346,9 @@ GPT0: gpt@40000a00 { /* FIXME */ - reg = <40000a00 d4>; + reg = <0x40000a00 0x000000d4>; interrupt-parent = <&UIC0>; - interrupts = <12 4 13 4 14 4 15 4 16 4>; + interrupts = <0x12 0x4 0x13 0x4 0x14 0x4 0x15 0x4 0x16 0x4>; }; }; @@ -360,34 +362,34 @@ primary; large-inbound-windows; enable-msi-hole; - reg = <2 0ec00000 8 /* Config space access */ - 0 0 0 /* no IACK cycles */ - 2 0ed00000 4 /* Special cycles */ - 2 0ec80000 100 /* Internal registers */ - 2 0ec80100 fc>; /* Internal messaging registers */ + reg = <0x00000002 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x00000002 0x0ed00000 0x00000004 /* Special cycles */ + 0x00000002 0x0ec80000 0x00000100 /* Internal registers */ + 0x00000002 0x0ec80100 0x000000fc>; /* Internal messaging registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed */ - ranges = <02000000 0 80000000 00000003 80000000 0 80000000 - 01000000 0 00000000 00000002 08000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x00000003 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x00000002 0x08000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 1 &UIC0 17 8 - 0800 0 0 2 &UIC0 18 8 - 0800 0 0 3 &UIC0 19 8 - 0800 0 0 4 &UIC0 1a 8 + 0x800 0x0 0x0 0x1 &UIC0 0x17 0x8 + 0x800 0x0 0x0 0x2 &UIC0 0x18 0x8 + 0x800 0x0 0x0 0x3 &UIC0 0x19 0x8 + 0x800 0x0 0x0 0x4 &UIC0 0x1a 0x8 /* IDSEL 2 */ - 1000 0 0 1 &UIC0 18 8 - 1000 0 0 2 &UIC0 19 8 - 1000 0 0 3 &UIC0 1a 8 - 1000 0 0 4 &UIC0 17 8 + 0x1000 0x0 0x0 0x1 &UIC0 0x18 0x8 + 0x1000 0x0 0x0 0x2 &UIC0 0x19 0x8 + 0x1000 0x0 0x0 0x3 &UIC0 0x1a 0x8 + 0x1000 0x0 0x0 0x4 &UIC0 0x17 0x8 >; }; }; diff --git a/arch/powerpc/boot/dts/walnut.dts b/arch/powerpc/boot/dts/walnut.dts index a328607..4a9f726 100644 --- a/arch/powerpc/boot/dts/walnut.dts +++ b/arch/powerpc/boot/dts/walnut.dts @@ -9,12 +9,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <1>; #size-cells = <1>; model = "ibm,walnut"; compatible = "ibm,walnut"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC; @@ -29,13 +31,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,405GP"; - reg = <0>; - clock-frequency = ; /* Filled in by zImage */ + reg = <0x00000000>; + clock-frequency = <200000000>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <4000>; - d-cache-size = <4000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; + d-cache-size = <16384>; dcr-controller; dcr-access-method = "native"; }; @@ -43,14 +45,14 @@ memory { device_type = "memory"; - reg = <0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller { compatible = "ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 9>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -65,63 +67,63 @@ SDRAM0: memory-controller { compatible = "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; MAL: mcmal { compatible = "ibm,mcmal-405gp", "ibm,mcmal"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <1>; num-rx-chans = <1>; interrupt-parent = <&UIC0>; interrupts = < - b 4 /* TXEOB */ - c 4 /* RXEOB */ - a 4 /* SERR */ - d 4 /* TXDE */ - e 4 /* RXDE */>; + 0xb 0x4 /* TXEOB */ + 0xc 0x4 /* RXEOB */ + 0xa 0x4 /* SERR */ + 0xd 0x4 /* TXDE */ + 0xe 0x4 /* RXDE */>; }; POB0: opb { compatible = "ibm,opb-405gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = ; - dcr-reg = <0a0 5>; + ranges = <0xef600000 0xef600000 0x00a00000>; + dcr-reg = <0x0a0 0x005>; clock-frequency = <0>; /* Filled in by zImage */ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <2580>; + current-speed = <9600>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <2580>; + current-speed = <9600>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; IIC: i2c@ef600500 { compatible = "ibm,iic-405gp", "ibm,iic"; - reg = ; + reg = <0xef600500 0x00000011>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; GPIO: gpio@ef600700 { compatible = "ibm,gpio-405gp"; - reg = ; + reg = <0xef600700 0x00000020>; }; EMAC: ethernet@ef600800 { @@ -129,26 +131,26 @@ compatible = "ibm,emac-405gp", "ibm,emac"; interrupt-parent = <&UIC0>; interrupts = < - f 4 /* Ethernet */ - 9 4 /* Ethernet Wake Up */>; + 0xf 0x4 /* Ethernet */ + 0x9 0x4 /* Ethernet Wake Up */>; local-mac-address = [000000000000]; /* Filled in by zImage */ - reg = ; + reg = <0xef600800 0x00000070>; mal-device = <&MAL>; mal-tx-channel = <0>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000001>; + phy-map = <0x00000001>; }; }; EBC0: ebc { compatible = "ibm,ebc-405gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; /* The ranges property is supplied by the bootwrapper @@ -158,18 +160,18 @@ clock-frequency = <0>; /* Filled in by zImage */ sram@0,0 { - reg = <0 0 80000>; + reg = <0x00000000 0x00000000 0x00080000>; }; flash@0,80000 { compatible = "jedec-flash"; bank-width = <1>; - reg = <0 80000 80000>; + reg = <0x00000000 0x00080000 0x00080000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "OpenBIOS"; - reg = <0 80000>; + reg = <0x00000000 0x00080000>; read-only; }; }; @@ -177,24 +179,24 @@ nvram@1,0 { /* NVRAM and RTC */ compatible = "ds1743-nvram"; - #bytes = <2000>; - reg = <1 0 2000>; + #bytes = <0x2000>; + reg = <0x00000001 0x00000000 0x00002000>; }; keyboard@2,0 { compatible = "intel,82C42PC"; - reg = <2 0 2>; + reg = <0x00000002 0x00000000 0x00000002>; }; ir@3,0 { compatible = "ti,TIR2000PAG"; - reg = <3 0 10>; + reg = <0x00000003 0x00000000 0x00000010>; }; fpga@7,0 { compatible = "Walnut-FPGA"; - reg = <7 0 10>; - virtual-reg = ; + reg = <0x00000007 0x00000000 0x00000010>; + virtual-reg = <0xf0300005>; }; }; @@ -205,35 +207,35 @@ #address-cells = <3>; compatible = "ibm,plb405gp-pci", "ibm,plb-pci"; primary; - reg = ; /* Internal registers */ + reg = <0xeec00000 0x00000008 /* Config space access */ + 0xeed80000 0x00000004 /* IACK */ + 0xeed80000 0x00000004 /* Special cycle */ + 0xef480000 0x00000040>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <02000000 0 80000000 80000000 0 20000000 - 01000000 0 00000000 e8000000 0 00010000>; + ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000 + 0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>; /* Walnut has all 4 IRQ pins tied together per slot */ - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x0>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 0 &UIC0 1c 8 + 0x800 0x0 0x0 0x0 &UIC0 0x1c 0x8 /* IDSEL 2 */ - 1000 0 0 0 &UIC0 1d 8 + 0x1000 0x0 0x0 0x0 &UIC0 0x1d 0x8 /* IDSEL 3 */ - 1800 0 0 0 &UIC0 1e 8 + 0x1800 0x0 0x0 0x0 &UIC0 0x1e 0x8 /* IDSEL 4 */ - 2000 0 0 0 &UIC0 1f 8 + 0x2000 0x0 0x0 0x0 &UIC0 0x1f 0x8 >; }; }; diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index b04a52e..c52e4fb 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts @@ -9,12 +9,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "pika,warp"; compatible = "pika,warp"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -28,13 +30,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440EP"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -42,14 +44,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -59,22 +61,22 @@ compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-440ep"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440ep"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -86,86 +88,86 @@ SDRAM0: sdram { compatible = "ibm,sdram-440ep", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; DMA0: dma { compatible = "ibm,dma-440ep", "ibm,dma-440gp"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440ep", "ibm,mcmal-440gp", "ibm,mcmal"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <4>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; + interrupt-map = ; }; POB0: opb { compatible = "ibm,opb-440ep", "ibm,opb-440gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 0 00000000 80000000 - 80000000 0 80000000 80000000>; + ranges = <0x00000000 0x00000000 0x00000000 0x80000000 + 0x80000000 0x00000000 0x80000000 0x80000000>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by zImage */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; fpga@2,0 { compatible = "pika,fpga"; - reg = <2 0 2200>; - interrupts = <18 8>; + reg = <0x00000002 0x00000000 0x00002200>; + interrupts = <0x18 0x8>; interrupt-parent = <&UIC0>; }; nor_flash@0,0 { compatible = "amd,s29gl512n", "cfi-flash"; bank-width = <2>; - reg = <0 0 4000000>; + reg = <0x00000000 0x00000000 0x04000000>; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "kernel"; - reg = <0 180000>; + reg = <0x00000000 0x00180000>; }; partition@180000 { label = "root"; - reg = <180000 3480000>; + reg = <0x00180000 0x03480000>; }; partition@3600000 { label = "user"; - reg = <3600000 900000>; + reg = <0x03600000 0x00900000>; }; partition@3f00000 { label = "fpga"; - reg = <3f00000 40000>; + reg = <0x03f00000 0x00040000>; }; partition@3f40000 { label = "env"; - reg = <3f40000 40000>; + reg = <0x03f40000 0x00040000>; }; partition@3f80000 { label = "u-boot"; - reg = <3f80000 80000>; + reg = <0x03f80000 0x00080000>; }; }; }; @@ -173,60 +175,60 @@ UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; + current-speed = <115200>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; GPIO0: gpio@ef600b00 { compatible = "ibm,gpio-440ep"; - reg = ; + reg = <0xef600b00 0x00000048>; }; GPIO1: gpio@ef600c00 { compatible = "ibm,gpio-440ep"; - reg = ; + reg = <0xef600c00 0x00000048>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; EMAC0: ethernet@ef600e00 { device_type = "network"; compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = ; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0 1>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; }; usb@ef601000 { compatible = "ohci-be"; - reg = ; - interrupts = <8 1 9 1>; + reg = <0xef601000 0x00000080>; + interrupts = <0x8 0x1 0x9 0x1>; interrupt-parent = < &UIC1 >; }; }; diff --git a/arch/powerpc/boot/dts/yosemite.dts b/arch/powerpc/boot/dts/yosemite.dts index 0d6d332..e39422a 100644 --- a/arch/powerpc/boot/dts/yosemite.dts +++ b/arch/powerpc/boot/dts/yosemite.dts @@ -9,12 +9,14 @@ * any warranty of any kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <2>; #size-cells = <1>; model = "amcc,yosemite"; compatible = "amcc,yosemite","amcc,bamboo"; - dcr-parent = <&/cpus/cpu@0>; + dcr-parent = <&{/cpus/cpu@0}>; aliases { ethernet0 = &EMAC0; @@ -32,13 +34,13 @@ cpu@0 { device_type = "cpu"; model = "PowerPC,440EP"; - reg = <0>; + reg = <0x00000000>; clock-frequency = <0>; /* Filled in by zImage */ timebase-frequency = <0>; /* Filled in by zImage */ - i-cache-line-size = <20>; - d-cache-line-size = <20>; - i-cache-size = <8000>; - d-cache-size = <8000>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; }; @@ -46,14 +48,14 @@ memory { device_type = "memory"; - reg = <0 0 0>; /* Filled in by zImage */ + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by zImage */ }; UIC0: interrupt-controller0 { compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; cell-index = <0>; - dcr-reg = <0c0 009>; + dcr-reg = <0x0c0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; @@ -63,22 +65,22 @@ compatible = "ibm,uic-440ep","ibm,uic"; interrupt-controller; cell-index = <1>; - dcr-reg = <0d0 009>; + dcr-reg = <0x0d0 0x009>; #address-cells = <0>; #size-cells = <0>; #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ interrupt-parent = <&UIC0>; }; SDR0: sdr { compatible = "ibm,sdr-440ep"; - dcr-reg = <00e 002>; + dcr-reg = <0x00e 0x002>; }; CPR0: cpr { compatible = "ibm,cpr-440ep"; - dcr-reg = <00c 002>; + dcr-reg = <0x00c 0x002>; }; plb { @@ -90,29 +92,29 @@ SDRAM0: sdram { compatible = "ibm,sdram-440ep", "ibm,sdram-405gp"; - dcr-reg = <010 2>; + dcr-reg = <0x010 0x002>; }; DMA0: dma { compatible = "ibm,dma-440ep", "ibm,dma-440gp"; - dcr-reg = <100 027>; + dcr-reg = <0x100 0x027>; }; MAL0: mcmal { compatible = "ibm,mcmal-440ep", "ibm,mcmal-440gp", "ibm,mcmal"; - dcr-reg = <180 62>; + dcr-reg = <0x180 0x062>; num-tx-chans = <4>; num-rx-chans = <2>; interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = ; + interrupt-map = ; }; POB0: opb { @@ -122,110 +124,110 @@ /* Bamboo is oddball in the 44x world and doesn't use the ERPN * bits. */ - ranges = <00000000 0 00000000 80000000 - 80000000 0 80000000 80000000>; + ranges = <0x00000000 0x00000000 0x00000000 0x80000000 + 0x80000000 0x00000000 0x80000000 0x80000000>; interrupt-parent = <&UIC1>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc"; - dcr-reg = <012 2>; + dcr-reg = <0x012 0x002>; #address-cells = <2>; #size-cells = <1>; clock-frequency = <0>; /* Filled in by zImage */ - interrupts = <5 1>; + interrupts = <0x5 0x1>; interrupt-parent = <&UIC1>; }; UART0: serial@ef600300 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; + current-speed = <115200>; interrupt-parent = <&UIC0>; - interrupts = <0 4>; + interrupts = <0x0 0x4>; }; UART1: serial@ef600400 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <1 4>; + interrupts = <0x1 0x4>; }; UART2: serial@ef600500 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <3 4>; + interrupts = <0x3 0x4>; status = "disabled"; }; UART3: serial@ef600600 { device_type = "serial"; compatible = "ns16550"; - reg = ; - virtual-reg = ; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; clock-frequency = <0>; current-speed = <0>; interrupt-parent = <&UIC0>; - interrupts = <4 4>; + interrupts = <0x4 0x4>; status = "disabled"; }; IIC0: i2c@ef600700 { compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = ; + reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <2 4>; + interrupts = <0x2 0x4>; }; IIC1: i2c@ef600800 { compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; - reg = ; + reg = <0xef600800 0x00000014>; interrupt-parent = <&UIC0>; - interrupts = <7 4>; + interrupts = <0x7 0x4>; }; spi@ef600900 { compatible = "amcc,spi-440ep"; - reg = ; - interrupts = <8 4>; + reg = <0xef600900 0x00000006>; + interrupts = <0x8 0x4>; interrupt-parent = <&UIC0>; }; ZMII0: emac-zmii@ef600d00 { compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii"; - reg = ; + reg = <0xef600d00 0x0000000c>; }; EMAC0: ethernet@ef600e00 { device_type = "network"; compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = ; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0xef600e00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0 1>; mal-rx-channel = <0>; cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <0>; }; @@ -234,26 +236,26 @@ device_type = "network"; compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac"; interrupt-parent = <&UIC1>; - interrupts = <1e 4 1f 4>; - reg = ; + interrupts = <0x1e 0x4 0x1f 0x4>; + reg = <0xef600f00 0x00000070>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <2 3>; mal-rx-channel = <1>; cell-index = <1>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; phy-mode = "rmii"; - phy-map = <00000000>; + phy-map = <0x00000000>; zmii-device = <&ZMII0>; zmii-channel = <1>; }; usb@ef601000 { compatible = "ohci-be"; - reg = ; - interrupts = <8 4 9 4>; + reg = <0xef601000 0x00000080>; + interrupts = <0x8 0x4 0x9 0x4>; interrupt-parent = < &UIC1 >; }; }; @@ -265,35 +267,35 @@ #address-cells = <3>; compatible = "ibm,plb440ep-pci", "ibm,plb-pci"; primary; - reg = <0 eec00000 8 /* Config space access */ - 0 eed00000 4 /* IACK */ - 0 eed00000 4 /* Special cycle */ - 0 ef400000 40>; /* Internal registers */ + reg = <0x00000000 0xeec00000 0x00000008 /* Config space access */ + 0x00000000 0xeed00000 0x00000004 /* IACK */ + 0x00000000 0xeed00000 0x00000004 /* Special cycle */ + 0x00000000 0xef400000 0x00000040>; /* Internal registers */ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <02000000 0 a0000000 0 a0000000 0 20000000 - 01000000 0 00000000 0 e8000000 0 00010000>; + ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x20000000 + 0x01000000 0x00000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>; /* Inbound 2GB range starting at 0 */ - dma-ranges = <42000000 0 0 0 0 0 80000000>; + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; /* Bamboo has all 4 IRQ pins tied together per slot */ - interrupt-map-mask = ; + interrupt-map-mask = <0xf800 0x0 0x0 0x0>; interrupt-map = < /* IDSEL 1 */ - 0800 0 0 0 &UIC0 1c 8 + 0x800 0x0 0x0 0x0 &UIC0 0x1c 0x8 /* IDSEL 2 */ - 1000 0 0 0 &UIC0 1b 8 + 0x1000 0x0 0x0 0x0 &UIC0 0x1b 0x8 /* IDSEL 3 */ - 1800 0 0 0 &UIC0 1a 8 + 0x1800 0x0 0x0 0x0 &UIC0 0x1a 0x8 /* IDSEL 4 */ - 2000 0 0 0 &UIC0 19 8 + 0x2000 0x0 0x0 0x0 &UIC0 0x19 0x8 >; }; }; -- cgit v0.10.2 From 6f031101f5c6bb44762911909da575127f676eb8 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Fri, 16 May 2008 00:41:23 +1000 Subject: [POWERPC] 4xx: Fix PCI mem in rainier DTS This fixes the PCI node in the Rainier to match the spec from AMCC. A similar fix was done for 440EPx, which shares the same values as 440GRx. Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts index 2cd87f6..2afb63a 100644 --- a/arch/powerpc/boot/dts/rainier.dts +++ b/arch/powerpc/boot/dts/rainier.dts @@ -330,8 +330,9 @@ * later cannot be changed. Chip supports a second * IO range but we don't use it for now */ - ranges = <0x02000000 0x00000000 0x80000000 0x00000001 0x80000000 0x00000000 0x10000000 - 0x01000000 0x00000000 0x00000000 0x00000001 0xe8000000 0x00000000 0x00100000>; + ranges = <0x02000000 0x0 0x80000000 0x1 0x80000000 0x0 0x40000000 + 0x01000000 0x0 0x00000000 0x1 0xe8000000 0x0 0x00010000 + 0x01000000 0x0 0x00000000 0x1 0xe8800000 0x0 0x03800000>; /* Inbound 2GB range starting at 0 */ dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; -- cgit v0.10.2 From 0393cb615f369b6ea0e636dd4d1e25675657dc75 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 29 Apr 2008 13:27:46 +1000 Subject: [POWERPC] PIKA Warp: Update DTS to support Rev B boards * Switched from 64M NOR/64M NAND to 4M NOR/256M NAND. * Added led entries. * Added fpga-sd entry. * Added ad7414 entry. Signed-off-by: Sean MacLennan Acked-by: Grant Likely Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index c52e4fb..340018c 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts @@ -134,40 +134,33 @@ fpga@2,0 { compatible = "pika,fpga"; - reg = <0x00000002 0x00000000 0x00002200>; + reg = <0x00000002 0x00000000 0x00001000>; interrupts = <0x18 0x8>; interrupt-parent = <&UIC0>; }; + fpga@2,4000 { + compatible = "pika,fpga-sd"; + reg = <0x00000002 0x00004000 0x00000A00>; + }; + nor_flash@0,0 { - compatible = "amd,s29gl512n", "cfi-flash"; + compatible = "amd,s29gl032a", "cfi-flash"; bank-width = <2>; - reg = <0x00000000 0x00000000 0x04000000>; + reg = <0x00000000 0x00000000 0x00400000>; #address-cells = <1>; #size-cells = <1>; - partition@0 { - label = "kernel"; - reg = <0x00000000 0x00180000>; - }; - partition@180000 { - label = "root"; - reg = <0x00180000 0x03480000>; - }; - partition@3600000 { - label = "user"; - reg = <0x03600000 0x00900000>; - }; - partition@3f00000 { + partition@300000 { label = "fpga"; - reg = <0x03f00000 0x00040000>; + reg = <0x0030000 0x00040000>; }; - partition@3f40000 { + partition@340000 { label = "env"; - reg = <0x03f40000 0x00040000>; + reg = <0x0340000 0x00040000>; }; - partition@3f80000 { + partition@380000 { label = "u-boot"; - reg = <0x03f80000 0x00080000>; + reg = <0x0380000 0x00080000>; }; }; }; @@ -188,16 +181,36 @@ reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; interrupts = <0x2 0x4>; + index = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + ad7414@4a { + compatible = "adi,ad7414"; + reg = <0x4a>; + interrupts = <0x19 0x8>; + interrupt-parent = <&UIC0>; + }; }; GPIO0: gpio@ef600b00 { compatible = "ibm,gpio-440ep"; reg = <0xef600b00 0x00000048>; + #gpio-cells = <2>; + gpio-controller; }; GPIO1: gpio@ef600c00 { compatible = "ibm,gpio-440ep"; reg = <0xef600c00 0x00000048>; + #gpio-cells = <2>; + gpio-controller; + + led@31 { + compatible = "linux,gpio-led"; + linux,name = ":green:"; + gpios = <&GPIO1 0x30 0>; + }; }; ZMII0: emac-zmii@ef600d00 { -- cgit v0.10.2 From 4ebef31fa6e013e5cd3d4522e6018eb6d55046be Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 20 May 2008 08:28:52 -0500 Subject: [POWERPC] PIKA Warp: Update platform code to support Rev B boards * Switched from 64M NOR/64M NAND to 4M NOR/256M NAND. * Full DTM support including critical temperature. * Added POST information. * Removed LED function, moved to new LED driver. * Moved ad7414 to new style I2C initialization. Signed-off-by: Sean MacLennan Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c index eb108a8..2178021 100644 --- a/arch/powerpc/boot/cuboot-warp.c +++ b/arch/powerpc/boot/cuboot-warp.c @@ -10,6 +10,7 @@ #include "ops.h" #include "4xx.h" #include "cuboot.h" +#include "stdio.h" #define TARGET_4xx #define TARGET_44x @@ -17,14 +18,54 @@ static bd_t bd; -static void warp_fixups(void) +static void warp_fixup_one_nor(u32 from, u32 to) { - unsigned long sysclk = 66000000; + void *devp; + char name[50]; + u32 v[2]; + + sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from); + + devp = finddevice(name); + if (!devp) + return; + + if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) { + v[0] = to; + setprop(devp, "reg", v, sizeof(v)); + + printf("NOR 64M fixup %x -> %x\r\n", from, to); + } +} + - ibm440ep_fixup_clocks(sysclk, 11059200, 50000000); +static void warp_fixups(void) +{ + ibm440ep_fixup_clocks(66000000, 11059200, 50000000); ibm4xx_sdram_fixup_memsize(); ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); + + /* Fixup for 64M flash on Rev A boards. */ + if (bd.bi_flashsize == 0x4000000) { + void *devp; + u32 v[3]; + + devp = finddevice("/plb/opb/ebc/nor_flash@0,0"); + if (!devp) + return; + + /* Fixup the size */ + if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) { + v[2] = bd.bi_flashsize; + setprop(devp, "reg", v, sizeof(v)); + } + + /* Fixup parition offsets */ + warp_fixup_one_nor(0x300000, 0x3f00000); + warp_fixup_one_nor(0x340000, 0x3f40000); + warp_fixup_one_nor(0x380000, 0x3f80000); + } } diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c index 9150318..d293c70 100644 --- a/arch/powerpc/platforms/44x/warp-nand.c +++ b/arch/powerpc/platforms/44x/warp-nand.c @@ -11,8 +11,10 @@ #include #include #include +#include #include + #ifdef CONFIG_MTD_NAND_NDFC #define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */ @@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = { { .name = "root", .offset = 0x0200000, - .size = 0x3400000 + .size = 0x3E00000 + }, + { + .name = "persistent", + .offset = 0x4000000, + .size = 0x4000000 }, { - .name = "user", - .offset = 0x3600000, - .size = 0x0A00000 + .name = "persistent1", + .offset = 0x8000000, + .size = 0x4000000 }, + { + .name = "persistent2", + .offset = 0xC000000, + .size = 0x4000000 + } }; struct ndfc_controller_settings warp_ndfc_settings = { @@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = { .resource = &warp_ndfc, }; -static struct nand_ecclayout nand_oob_16 = { - .eccbytes = 3, - .eccpos = { 0, 1, 2, 3, 6, 7 }, - .oobfree = { {.offset = 8, .length = 16} } -}; - +/* Do NOT set the ecclayout: let it default so it is correct for both + * 64M and 256M flash chips. + */ static struct platform_nand_chip warp_nand_chip0 = { .nr_chips = 1, .chip_offset = CS_NAND_0, .nr_partitions = ARRAY_SIZE(nand_parts), .partitions = nand_parts, - .chip_delay = 50, - .ecclayout = &nand_oob_16, + .chip_delay = 20, .priv = &warp_chip0_settings, }; @@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = { static int warp_setup_nand_flash(void) { + struct device_node *np; + + /* Try to detect a rev A based on NOR size. */ + np = of_find_compatible_node(NULL, NULL, "cfi-flash"); + if (np) { + struct property *pp; + + pp = of_find_property(np, "reg", NULL); + if (pp && (pp->length == 12)) { + u32 *v = pp->value; + if (v[2] == 0x4000000) + /* Rev A = 64M NAND */ + warp_nand_chip0.nr_partitions = 2; + } + of_node_put(np); + } + platform_device_register(&warp_ndfc_device); platform_device_register(&warp_nand_device); diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index 39cf615..9565995 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include #include @@ -27,6 +30,18 @@ static __initdata struct of_device_id warp_of_bus[] = { {}, }; +static __initdata struct i2c_board_info warp_i2c_info[] = { + { I2C_BOARD_INFO("ad7414", 0x4a) } +}; + +static int __init warp_arch_init(void) +{ + /* This should go away once support is moved to the dts. */ + i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info)); + return 0; +} +machine_arch_initcall(warp, warp_arch_init); + static int __init warp_device_probe(void) { of_platform_bus_probe(NULL, warp_of_bus, NULL); @@ -52,61 +67,232 @@ define_machine(warp) { }; -#define LED_GREEN (0x80000000 >> 0) -#define LED_RED (0x80000000 >> 1) +/* I am not sure this is the best place for this... */ +static int __init warp_post_info(void) +{ + struct device_node *np; + void __iomem *fpga; + u32 post1, post2; + + /* Sighhhh... POST information is in the sd area. */ + np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd"); + if (np == NULL) + return -ENOENT; + + fpga = of_iomap(np, 0); + of_node_put(np); + if (fpga == NULL) + return -ENOENT; + + post1 = in_be32(fpga + 0x40); + post2 = in_be32(fpga + 0x44); + + iounmap(fpga); + + if (post1 || post2) + printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2); + else + printk(KERN_INFO "Warp POST OK\n"); + + return 0; +} +machine_late_initcall(warp, warp_post_info); + + +#ifdef CONFIG_SENSORS_AD7414 + +static LIST_HEAD(dtm_shutdown_list); +static void __iomem *dtm_fpga; +static void __iomem *gpio_base; + + +struct dtm_shutdown { + struct list_head list; + void (*func)(void *arg); + void *arg; +}; -/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */ -void warp_set_power_leds(int green, int red) +int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) { - static void __iomem *gpio_base = NULL; - unsigned leds; - - if (gpio_base == NULL) { - struct device_node *np; - - /* Power LEDS are on the second GPIO controller */ - np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP"); - if (np) - np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP"); - if (np == NULL) { - printk(KERN_ERR __FILE__ ": Unable to find gpio\n"); - return; + struct dtm_shutdown *shutdown; + + shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL); + if (shutdown == NULL) + return -ENOMEM; + + shutdown->func = func; + shutdown->arg = arg; + + list_add(&shutdown->list, &dtm_shutdown_list); + + return 0; +} + +int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) +{ + struct dtm_shutdown *shutdown; + + list_for_each_entry(shutdown, &dtm_shutdown_list, list) + if (shutdown->func == func && shutdown->arg == arg) { + list_del(&shutdown->list); + kfree(shutdown); + return 0; + } + + return -EINVAL; +} + +static irqreturn_t temp_isr(int irq, void *context) +{ + struct dtm_shutdown *shutdown; + + local_irq_disable(); + + /* Run through the shutdown list. */ + list_for_each_entry(shutdown, &dtm_shutdown_list, list) + shutdown->func(shutdown->arg); + + printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n"); + + while (1) { + if (dtm_fpga) { + unsigned reset = in_be32(dtm_fpga + 0x14); + out_be32(dtm_fpga + 0x14, reset); } - gpio_base = of_iomap(np, 0); - of_node_put(np); - if (gpio_base == NULL) { - printk(KERN_ERR __FILE__ ": Unable to map gpio"); - return; + if (gpio_base) { + unsigned leds = in_be32(gpio_base); + + /* green off, red toggle */ + leds &= ~0x80000000; + leds ^= 0x40000000; + + out_be32(gpio_base, leds); } + + mdelay(500); + } +} + +static int pika_setup_leds(void) +{ + struct device_node *np; + const u32 *gpios; + int len; + + np = of_find_compatible_node(NULL, NULL, "linux,gpio-led"); + if (!np) { + printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n"); + return -ENOENT; } - leds = in_be32(gpio_base); + gpios = of_get_property(np, "gpios", &len); + of_node_put(np); + if (!gpios || len < 4) { + printk(KERN_ERR __FILE__ + ": Unable to get gpios property (%d)\n", len); + return -ENOENT; + } - switch (green) { - case 0: leds &= ~LED_GREEN; break; - case 1: leds |= LED_GREEN; break; + np = of_find_node_by_phandle(gpios[0]); + if (!np) { + printk(KERN_ERR __FILE__ ": Unable to find gpio\n"); + return -ENOENT; } - switch (red) { - case 0: leds &= ~LED_RED; break; - case 1: leds |= LED_RED; break; + + gpio_base = of_iomap(np, 0); + of_node_put(np); + if (!gpio_base) { + printk(KERN_ERR __FILE__ ": Unable to map gpio"); + return -ENOMEM; } - out_be32(gpio_base, leds); + return 0; } -EXPORT_SYMBOL(warp_set_power_leds); +static void pika_setup_critical_temp(struct i2c_client *client) +{ + struct device_node *np; + int irq, rc; + + /* Do this before enabling critical temp interrupt since we + * may immediately interrupt. + */ + pika_setup_leds(); + + /* These registers are in 1 degree increments. */ + i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ + i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */ + + np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); + if (np == NULL) { + printk(KERN_ERR __FILE__ ": Unable to find ad7414\n"); + return; + } + + irq = irq_of_parse_and_map(np, 0); + of_node_put(np); + if (irq == NO_IRQ) { + printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); + return; + } + + rc = request_irq(irq, temp_isr, 0, "ad7414", NULL); + if (rc) { + printk(KERN_ERR __FILE__ + ": Unable to request ad7414 irq %d = %d\n", irq, rc); + return; + } +} + +static inline void pika_dtm_check_fan(void __iomem *fpga) +{ + static int fan_state; + u32 fan = in_be32(fpga + 0x34) & (1 << 14); + + if (fan_state != fan) { + fan_state = fan; + if (fan) + printk(KERN_WARNING "Fan rotation error detected." + " Please check hardware.\n"); + } +} -#ifdef CONFIG_SENSORS_AD7414 static int pika_dtm_thread(void __iomem *fpga) { - extern int ad7414_get_temp(int index); + struct i2c_adapter *adap; + struct i2c_client *client; + + /* We loop in case either driver was compiled as a module and + * has not been insmoded yet. + */ + while (!(adap = i2c_get_adapter(0))) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + } + + while (1) { + list_for_each_entry(client, &adap->clients, list) + if (client->addr == 0x4a) + goto found_it; + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + } + +found_it: + i2c_put_adapter(adap); + + pika_setup_critical_temp(client); + + printk(KERN_INFO "PIKA DTM thread running.\n"); while (!kthread_should_stop()) { - int temp = ad7414_get_temp(0); + u16 temp = swab16(i2c_smbus_read_word_data(client, 0)); + out_be32(fpga + 0x20, temp); - out_be32(fpga, temp); + pika_dtm_check_fan(fpga); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); @@ -115,37 +301,44 @@ static int pika_dtm_thread(void __iomem *fpga) return 0; } + static int __init pika_dtm_start(void) { struct task_struct *dtm_thread; struct device_node *np; - struct resource res; - void __iomem *fpga; np = of_find_compatible_node(NULL, NULL, "pika,fpga"); if (np == NULL) return -ENOENT; - /* We do not call of_iomap here since it would map in the entire - * fpga space, which is over 8k. - */ - if (of_address_to_resource(np, 0, &res)) { - of_node_put(np); - return -ENOENT; - } + dtm_fpga = of_iomap(np, 0); of_node_put(np); - - fpga = ioremap(res.start, 0x24); - if (fpga == NULL) + if (dtm_fpga == NULL) return -ENOENT; - dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm"); + dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm"); if (IS_ERR(dtm_thread)) { - iounmap(fpga); + iounmap(dtm_fpga); return PTR_ERR(dtm_thread); } return 0; } -device_initcall(pika_dtm_start); +machine_late_initcall(warp, pika_dtm_start); + +#else /* !CONFIG_SENSORS_AD7414 */ + +int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg) +{ + return 0; +} + +int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg) +{ + return 0; +} + #endif + +EXPORT_SYMBOL(pika_dtm_register_shutdown); +EXPORT_SYMBOL(pika_dtm_unregister_shutdown); -- cgit v0.10.2 From 0723abd0b2c9d4603b8c51d6615800c2439a328e Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 20 May 2008 07:59:23 -0500 Subject: [POWERPC] 4xx: Fix compiler warning on DCR_NATIVE only builds With the recent DCR code rework, we get a compiler warning about find_dcr_parent being defined but not used. This fixes it by only defining the function if CONFIG_PPC_DCR_MMIO is set. Signed-off-by: Josh Boyer diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 5f39a79..a8ba998 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -23,6 +23,7 @@ #include #include +#ifdef CONFIG_PPC_DCR_MMIO static struct device_node *find_dcr_parent(struct device_node *node) { struct device_node *par, *tmp; @@ -41,6 +42,7 @@ static struct device_node *find_dcr_parent(struct device_node *node) } return par; } +#endif #if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) -- cgit v0.10.2 From c18f68e4d809a517ed8df540bac2993a4f14d9a4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 29 May 2008 18:53:05 +0200 Subject: [ALSA] Clean up sound/pci/ac97/Makefile Signed-off-by: Takashi Iwai diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 0be48b1..ae36950 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -3,16 +3,11 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o - -ifneq ($(CONFIG_PROC_FS),) -snd-ac97-codec-objs += ac97_proc.o -endif +snd-ac97-codec-y := ac97_codec.o ac97_pcm.o +snd-ac97-codec-$(CONFIG_PROC_FS) += ac97_proc.o snd-ak4531-codec-objs := ak4531_codec.o # Toplevel Module Dependency obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o - -obj-m := $(sort $(obj-m)) -- cgit v0.10.2 From 23ce1547638443f0053dd674e728062c48ff0e39 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 09:22:22 +0200 Subject: [ALSA] Make ak4531 local to ens1370 driver The ak4531 module is used only by ens1370 driver (and unlikely that any other will use it ever). Let's make it local to ens1370. Signed-off-by: Takashi Iwai diff --git a/sound/pci/Makefile b/sound/pci/Makefile index 85ef14b..65b25d2 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile @@ -13,7 +13,7 @@ snd-bt87x-objs := bt87x.o snd-cmipci-objs := cmipci.o snd-cs4281-objs := cs4281.o snd-cs5530-objs := cs5530.o -snd-ens1370-objs := ens1370.o +snd-ens1370-objs := ens1370.o ak4531_codec.o snd-ens1371-objs := ens1371.o snd-es1938-objs := es1938.o snd-es1968-objs := es1968.o diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index ae36950..41fa322 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -6,8 +6,5 @@ snd-ac97-codec-y := ac97_codec.o ac97_pcm.o snd-ac97-codec-$(CONFIG_PROC_FS) += ac97_proc.o -snd-ak4531-codec-objs := ak4531_codec.o - # Toplevel Module Dependency obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o -obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c deleted file mode 100644 index c0c16339..0000000 --- a/sound/pci/ac97/ak4531_codec.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (c) by Jaroslav Kysela - * Universal routines for AK4531 codec - * - * - * 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 -#include -#include -#include - -#include -#include -#include - -MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Universal routines for AK4531 codec"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_PROC_FS -static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531); -#else -#define snd_ak4531_proc_init(card,ak) -#endif - -/* - * - */ - -#if 0 - -static void snd_ak4531_dump(struct snd_ak4531 *ak4531) -{ - int idx; - - for (idx = 0; idx < 0x19; idx++) - printk("ak4531 0x%x: 0x%x\n", idx, ak4531->regs[idx]); -} - -#endif - -/* - * - */ - -#define AK4531_SINGLE(xname, xindex, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_ak4531_info_single, \ - .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \ - .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22) } -#define AK4531_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .name = xname, .index = xindex, \ - .info = snd_ak4531_info_single, \ - .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \ - .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22), \ - .tlv = { .p = (xtlv) } } - -static int snd_ak4531_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 24) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 16) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - int val; - - mutex_lock(&ak4531->reg_mutex); - val = (ak4531->regs[reg] >> shift) & mask; - mutex_unlock(&ak4531->reg_mutex); - if (invert) { - val = mask - val; - } - ucontrol->value.integer.value[0] = val; - return 0; -} - -static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 16) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - int change; - int val; - - val = ucontrol->value.integer.value[0] & mask; - if (invert) { - val = mask - val; - } - val <<= shift; - mutex_lock(&ak4531->reg_mutex); - val = (ak4531->regs[reg] & ~(mask << shift)) | val; - change = val != ak4531->regs[reg]; - ak4531->write(ak4531, reg, ak4531->regs[reg] = val); - mutex_unlock(&ak4531->reg_mutex); - return change; -} - -#define AK4531_DOUBLE(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_ak4531_info_double, \ - .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \ - .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22) } -#define AK4531_DOUBLE_TLV(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert, xtlv) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .name = xname, .index = xindex, \ - .info = snd_ak4531_info_double, \ - .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \ - .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22), \ - .tlv = { .p = (xtlv) } } - -static int snd_ak4531_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 24) & 0xff; - - uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} - -static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); - int left_reg = kcontrol->private_value & 0xff; - int right_reg = (kcontrol->private_value >> 8) & 0xff; - int left_shift = (kcontrol->private_value >> 16) & 0x07; - int right_shift = (kcontrol->private_value >> 19) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - int left, right; - - mutex_lock(&ak4531->reg_mutex); - left = (ak4531->regs[left_reg] >> left_shift) & mask; - right = (ak4531->regs[right_reg] >> right_shift) & mask; - mutex_unlock(&ak4531->reg_mutex); - if (invert) { - left = mask - left; - right = mask - right; - } - ucontrol->value.integer.value[0] = left; - ucontrol->value.integer.value[1] = right; - return 0; -} - -static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); - int left_reg = kcontrol->private_value & 0xff; - int right_reg = (kcontrol->private_value >> 8) & 0xff; - int left_shift = (kcontrol->private_value >> 16) & 0x07; - int right_shift = (kcontrol->private_value >> 19) & 0x07; - int mask = (kcontrol->private_value >> 24) & 0xff; - int invert = (kcontrol->private_value >> 22) & 1; - int change; - int left, right; - - left = ucontrol->value.integer.value[0] & mask; - right = ucontrol->value.integer.value[1] & mask; - if (invert) { - left = mask - left; - right = mask - right; - } - left <<= left_shift; - right <<= right_shift; - mutex_lock(&ak4531->reg_mutex); - if (left_reg == right_reg) { - left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; - change = left != ak4531->regs[left_reg]; - ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); - } else { - left = (ak4531->regs[left_reg] & ~(mask << left_shift)) | left; - right = (ak4531->regs[right_reg] & ~(mask << right_shift)) | right; - change = left != ak4531->regs[left_reg] || right != ak4531->regs[right_reg]; - ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); - ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); - } - mutex_unlock(&ak4531->reg_mutex); - return change; -} - -#define AK4531_INPUT_SW(xname, xindex, reg1, reg2, left_shift, right_shift) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_ak4531_info_input_sw, \ - .get = snd_ak4531_get_input_sw, .put = snd_ak4531_put_input_sw, \ - .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) } - -static int snd_ak4531_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 4; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); - int reg1 = kcontrol->private_value & 0xff; - int reg2 = (kcontrol->private_value >> 8) & 0xff; - int left_shift = (kcontrol->private_value >> 16) & 0x0f; - int right_shift = (kcontrol->private_value >> 24) & 0x0f; - - mutex_lock(&ak4531->reg_mutex); - ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; - ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; - ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; - ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; - mutex_unlock(&ak4531->reg_mutex); - return 0; -} - -static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); - int reg1 = kcontrol->private_value & 0xff; - int reg2 = (kcontrol->private_value >> 8) & 0xff; - int left_shift = (kcontrol->private_value >> 16) & 0x0f; - int right_shift = (kcontrol->private_value >> 24) & 0x0f; - int change; - int val1, val2; - - mutex_lock(&ak4531->reg_mutex); - val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); - val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); - val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; - val2 |= (ucontrol->value.integer.value[1] & 1) << left_shift; - val1 |= (ucontrol->value.integer.value[2] & 1) << right_shift; - val2 |= (ucontrol->value.integer.value[3] & 1) << right_shift; - change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; - ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); - ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); - mutex_unlock(&ak4531->reg_mutex); - return change; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); - -static struct snd_kcontrol_new snd_ak4531_controls[] = { - -AK4531_DOUBLE_TLV("Master Playback Switch", 0, - AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1, - db_scale_master), -AK4531_DOUBLE("Master Playback Volume", 0, AK4531_LMASTER, AK4531_RMASTER, 0, 0, 0x1f, 1), - -AK4531_SINGLE_TLV("Master Mono Playback Switch", 0, AK4531_MONO_OUT, 7, 1, 1, - db_scale_mono), -AK4531_SINGLE("Master Mono Playback Volume", 0, AK4531_MONO_OUT, 0, 0x07, 1), - -AK4531_DOUBLE("PCM Switch", 0, AK4531_LVOICE, AK4531_RVOICE, 7, 7, 1, 1), -AK4531_DOUBLE_TLV("PCM Volume", 0, AK4531_LVOICE, AK4531_RVOICE, 0, 0, 0x1f, 1, - db_scale_input), -AK4531_DOUBLE("PCM Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 3, 2, 1, 0), -AK4531_DOUBLE("PCM Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 2, 2, 1, 0), - -AK4531_DOUBLE("PCM Switch", 1, AK4531_LFM, AK4531_RFM, 7, 7, 1, 1), -AK4531_DOUBLE_TLV("PCM Volume", 1, AK4531_LFM, AK4531_RFM, 0, 0, 0x1f, 1, - db_scale_input), -AK4531_DOUBLE("PCM Playback Switch", 1, AK4531_OUT_SW1, AK4531_OUT_SW1, 6, 5, 1, 0), -AK4531_INPUT_SW("PCM Capture Route", 1, AK4531_LIN_SW1, AK4531_RIN_SW1, 6, 5), - -AK4531_DOUBLE("CD Switch", 0, AK4531_LCD, AK4531_RCD, 7, 7, 1, 1), -AK4531_DOUBLE_TLV("CD Volume", 0, AK4531_LCD, AK4531_RCD, 0, 0, 0x1f, 1, - db_scale_input), -AK4531_DOUBLE("CD Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 2, 1, 1, 0), -AK4531_INPUT_SW("CD Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 2, 1), - -AK4531_DOUBLE("Line Switch", 0, AK4531_LLINE, AK4531_RLINE, 7, 7, 1, 1), -AK4531_DOUBLE_TLV("Line Volume", 0, AK4531_LLINE, AK4531_RLINE, 0, 0, 0x1f, 1, - db_scale_input), -AK4531_DOUBLE("Line Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 4, 3, 1, 0), -AK4531_INPUT_SW("Line Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 4, 3), - -AK4531_DOUBLE("Aux Switch", 0, AK4531_LAUXA, AK4531_RAUXA, 7, 7, 1, 1), -AK4531_DOUBLE_TLV("Aux Volume", 0, AK4531_LAUXA, AK4531_RAUXA, 0, 0, 0x1f, 1, - db_scale_input), -AK4531_DOUBLE("Aux Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 5, 4, 1, 0), -AK4531_INPUT_SW("Aux Capture Route", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 4, 3), - -AK4531_SINGLE("Mono Switch", 0, AK4531_MONO1, 7, 1, 1), -AK4531_SINGLE_TLV("Mono Volume", 0, AK4531_MONO1, 0, 0x1f, 1, db_scale_input), -AK4531_SINGLE("Mono Playback Switch", 0, AK4531_OUT_SW2, 0, 1, 0), -AK4531_DOUBLE("Mono Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 0, 0, 1, 0), - -AK4531_SINGLE("Mono Switch", 1, AK4531_MONO2, 7, 1, 1), -AK4531_SINGLE_TLV("Mono Volume", 1, AK4531_MONO2, 0, 0x1f, 1, db_scale_input), -AK4531_SINGLE("Mono Playback Switch", 1, AK4531_OUT_SW2, 1, 1, 0), -AK4531_DOUBLE("Mono Capture Switch", 1, AK4531_LIN_SW2, AK4531_RIN_SW2, 1, 1, 1, 0), - -AK4531_SINGLE_TLV("Mic Volume", 0, AK4531_MIC, 0, 0x1f, 1, db_scale_input), -AK4531_SINGLE("Mic Switch", 0, AK4531_MIC, 7, 1, 1), -AK4531_SINGLE("Mic Playback Switch", 0, AK4531_OUT_SW1, 0, 1, 0), -AK4531_DOUBLE("Mic Capture Switch", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 0, 0, 1, 0), - -AK4531_DOUBLE("Mic Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 7, 7, 1, 0), -AK4531_DOUBLE("Mono1 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 6, 6, 1, 0), -AK4531_DOUBLE("Mono2 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 5, 5, 1, 0), - -AK4531_SINGLE("AD Input Select", 0, AK4531_AD_IN, 0, 1, 0), -AK4531_SINGLE("Mic Boost (+30dB)", 0, AK4531_MIC_GAIN, 0, 1, 0) -}; - -static int snd_ak4531_free(struct snd_ak4531 *ak4531) -{ - if (ak4531) { - if (ak4531->private_free) - ak4531->private_free(ak4531); - kfree(ak4531); - } - return 0; -} - -static int snd_ak4531_dev_free(struct snd_device *device) -{ - struct snd_ak4531 *ak4531 = device->device_data; - return snd_ak4531_free(ak4531); -} - -static u8 snd_ak4531_initial_map[0x19 + 1] = { - 0x9f, /* 00: Master Volume Lch */ - 0x9f, /* 01: Master Volume Rch */ - 0x9f, /* 02: Voice Volume Lch */ - 0x9f, /* 03: Voice Volume Rch */ - 0x9f, /* 04: FM Volume Lch */ - 0x9f, /* 05: FM Volume Rch */ - 0x9f, /* 06: CD Audio Volume Lch */ - 0x9f, /* 07: CD Audio Volume Rch */ - 0x9f, /* 08: Line Volume Lch */ - 0x9f, /* 09: Line Volume Rch */ - 0x9f, /* 0a: Aux Volume Lch */ - 0x9f, /* 0b: Aux Volume Rch */ - 0x9f, /* 0c: Mono1 Volume */ - 0x9f, /* 0d: Mono2 Volume */ - 0x9f, /* 0e: Mic Volume */ - 0x87, /* 0f: Mono-out Volume */ - 0x00, /* 10: Output Mixer SW1 */ - 0x00, /* 11: Output Mixer SW2 */ - 0x00, /* 12: Lch Input Mixer SW1 */ - 0x00, /* 13: Rch Input Mixer SW1 */ - 0x00, /* 14: Lch Input Mixer SW2 */ - 0x00, /* 15: Rch Input Mixer SW2 */ - 0x00, /* 16: Reset & Power Down */ - 0x00, /* 17: Clock Select */ - 0x00, /* 18: AD Input Select */ - 0x01 /* 19: Mic Amp Setup */ -}; - -int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, - struct snd_ak4531 **rak4531) -{ - unsigned int idx; - int err; - struct snd_ak4531 *ak4531; - static struct snd_device_ops ops = { - .dev_free = snd_ak4531_dev_free, - }; - - snd_assert(rak4531 != NULL, return -EINVAL); - *rak4531 = NULL; - snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL); - ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL); - if (ak4531 == NULL) - return -ENOMEM; - *ak4531 = *_ak4531; - mutex_init(&ak4531->reg_mutex); - if ((err = snd_component_add(card, "AK4531")) < 0) { - snd_ak4531_free(ak4531); - return err; - } - strcpy(card->mixername, "Asahi Kasei AK4531"); - ak4531->write(ak4531, AK4531_RESET, 0x03); /* no RST, PD */ - udelay(100); - ak4531->write(ak4531, AK4531_CLOCK, 0x00); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off LRCLK2 PLL */ - for (idx = 0; idx <= 0x19; idx++) { - if (idx == AK4531_RESET || idx == AK4531_CLOCK) - continue; - ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]); /* recording source is mixer */ - } - for (idx = 0; idx < ARRAY_SIZE(snd_ak4531_controls); idx++) { - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531))) < 0) { - snd_ak4531_free(ak4531); - return err; - } - } - snd_ak4531_proc_init(card, ak4531); - if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) { - snd_ak4531_free(ak4531); - return err; - } - -#if 0 - snd_ak4531_dump(ak4531); -#endif - *rak4531 = ak4531; - return 0; -} - -/* - * power management - */ -#ifdef CONFIG_PM -void snd_ak4531_suspend(struct snd_ak4531 *ak4531) -{ - /* mute */ - ak4531->write(ak4531, AK4531_LMASTER, 0x9f); - ak4531->write(ak4531, AK4531_RMASTER, 0x9f); - /* powerdown */ - ak4531->write(ak4531, AK4531_RESET, 0x01); -} - -void snd_ak4531_resume(struct snd_ak4531 *ak4531) -{ - int idx; - - /* initialize */ - ak4531->write(ak4531, AK4531_RESET, 0x03); - udelay(100); - ak4531->write(ak4531, AK4531_CLOCK, 0x00); - /* restore mixer registers */ - for (idx = 0; idx <= 0x19; idx++) { - if (idx == AK4531_RESET || idx == AK4531_CLOCK) - continue; - ak4531->write(ak4531, idx, ak4531->regs[idx]); - } -} -#endif - -#ifdef CONFIG_PROC_FS -/* - * /proc interface - */ - -static void snd_ak4531_proc_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_ak4531 *ak4531 = entry->private_data; - - snd_iprintf(buffer, "Asahi Kasei AK4531\n\n"); - snd_iprintf(buffer, "Recording source : %s\n" - "MIC gain : %s\n", - ak4531->regs[AK4531_AD_IN] & 1 ? "external" : "mixer", - ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB"); -} - -static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531) -{ - struct snd_info_entry *entry; - - if (! snd_card_proc_new(card, "ak4531", &entry)) - snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read); -} -#endif - -EXPORT_SYMBOL(snd_ak4531_mixer); -#ifdef CONFIG_PM -EXPORT_SYMBOL(snd_ak4531_suspend); -EXPORT_SYMBOL(snd_ak4531_resume); -#endif - -/* - * INIT part - */ - -static int __init alsa_ak4531_init(void) -{ - return 0; -} - -static void __exit alsa_ak4531_exit(void) -{ -} - -module_init(alsa_ak4531_init) -module_exit(alsa_ak4531_exit) diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c new file mode 100644 index 0000000..6a99eed --- /dev/null +++ b/sound/pci/ak4531_codec.c @@ -0,0 +1,488 @@ +/* + * Copyright (c) by Jaroslav Kysela + * Universal routines for AK4531 codec + * + * + * 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 +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_DESCRIPTION("Universal routines for AK4531 codec"); +MODULE_LICENSE("GPL"); + +#ifdef CONFIG_PROC_FS +static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531); +#else +#define snd_ak4531_proc_init(card,ak) +#endif + +/* + * + */ + +#if 0 + +static void snd_ak4531_dump(struct snd_ak4531 *ak4531) +{ + int idx; + + for (idx = 0; idx < 0x19; idx++) + printk("ak4531 0x%x: 0x%x\n", idx, ak4531->regs[idx]); +} + +#endif + +/* + * + */ + +#define AK4531_SINGLE(xname, xindex, reg, shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_ak4531_info_single, \ + .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \ + .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22) } +#define AK4531_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ + .name = xname, .index = xindex, \ + .info = snd_ak4531_info_single, \ + .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \ + .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22), \ + .tlv = { .p = (xtlv) } } + +static int snd_ak4531_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + int mask = (kcontrol->private_value >> 24) & 0xff; + + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mask; + return 0; +} + +static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 16) & 0x07; + int mask = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 22) & 1; + int val; + + mutex_lock(&ak4531->reg_mutex); + val = (ak4531->regs[reg] >> shift) & mask; + mutex_unlock(&ak4531->reg_mutex); + if (invert) { + val = mask - val; + } + ucontrol->value.integer.value[0] = val; + return 0; +} + +static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 16) & 0x07; + int mask = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 22) & 1; + int change; + int val; + + val = ucontrol->value.integer.value[0] & mask; + if (invert) { + val = mask - val; + } + val <<= shift; + mutex_lock(&ak4531->reg_mutex); + val = (ak4531->regs[reg] & ~(mask << shift)) | val; + change = val != ak4531->regs[reg]; + ak4531->write(ak4531, reg, ak4531->regs[reg] = val); + mutex_unlock(&ak4531->reg_mutex); + return change; +} + +#define AK4531_DOUBLE(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_ak4531_info_double, \ + .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \ + .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22) } +#define AK4531_DOUBLE_TLV(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert, xtlv) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ + .name = xname, .index = xindex, \ + .info = snd_ak4531_info_double, \ + .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \ + .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22), \ + .tlv = { .p = (xtlv) } } + +static int snd_ak4531_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + int mask = (kcontrol->private_value >> 24) & 0xff; + + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mask; + return 0; +} + +static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); + int left_reg = kcontrol->private_value & 0xff; + int right_reg = (kcontrol->private_value >> 8) & 0xff; + int left_shift = (kcontrol->private_value >> 16) & 0x07; + int right_shift = (kcontrol->private_value >> 19) & 0x07; + int mask = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 22) & 1; + int left, right; + + mutex_lock(&ak4531->reg_mutex); + left = (ak4531->regs[left_reg] >> left_shift) & mask; + right = (ak4531->regs[right_reg] >> right_shift) & mask; + mutex_unlock(&ak4531->reg_mutex); + if (invert) { + left = mask - left; + right = mask - right; + } + ucontrol->value.integer.value[0] = left; + ucontrol->value.integer.value[1] = right; + return 0; +} + +static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); + int left_reg = kcontrol->private_value & 0xff; + int right_reg = (kcontrol->private_value >> 8) & 0xff; + int left_shift = (kcontrol->private_value >> 16) & 0x07; + int right_shift = (kcontrol->private_value >> 19) & 0x07; + int mask = (kcontrol->private_value >> 24) & 0xff; + int invert = (kcontrol->private_value >> 22) & 1; + int change; + int left, right; + + left = ucontrol->value.integer.value[0] & mask; + right = ucontrol->value.integer.value[1] & mask; + if (invert) { + left = mask - left; + right = mask - right; + } + left <<= left_shift; + right <<= right_shift; + mutex_lock(&ak4531->reg_mutex); + if (left_reg == right_reg) { + left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; + change = left != ak4531->regs[left_reg]; + ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); + } else { + left = (ak4531->regs[left_reg] & ~(mask << left_shift)) | left; + right = (ak4531->regs[right_reg] & ~(mask << right_shift)) | right; + change = left != ak4531->regs[left_reg] || right != ak4531->regs[right_reg]; + ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); + ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); + } + mutex_unlock(&ak4531->reg_mutex); + return change; +} + +#define AK4531_INPUT_SW(xname, xindex, reg1, reg2, left_shift, right_shift) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_ak4531_info_input_sw, \ + .get = snd_ak4531_get_input_sw, .put = snd_ak4531_put_input_sw, \ + .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) } + +static int snd_ak4531_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 4; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); + int reg1 = kcontrol->private_value & 0xff; + int reg2 = (kcontrol->private_value >> 8) & 0xff; + int left_shift = (kcontrol->private_value >> 16) & 0x0f; + int right_shift = (kcontrol->private_value >> 24) & 0x0f; + + mutex_lock(&ak4531->reg_mutex); + ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; + ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; + ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; + ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; + mutex_unlock(&ak4531->reg_mutex); + return 0; +} + +static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol); + int reg1 = kcontrol->private_value & 0xff; + int reg2 = (kcontrol->private_value >> 8) & 0xff; + int left_shift = (kcontrol->private_value >> 16) & 0x0f; + int right_shift = (kcontrol->private_value >> 24) & 0x0f; + int change; + int val1, val2; + + mutex_lock(&ak4531->reg_mutex); + val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); + val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); + val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; + val2 |= (ucontrol->value.integer.value[1] & 1) << left_shift; + val1 |= (ucontrol->value.integer.value[2] & 1) << right_shift; + val2 |= (ucontrol->value.integer.value[3] & 1) << right_shift; + change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; + ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); + ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); + mutex_unlock(&ak4531->reg_mutex); + return change; +} + +static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); +static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); +static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); + +static struct snd_kcontrol_new snd_ak4531_controls[] __devinitdata = { + +AK4531_DOUBLE_TLV("Master Playback Switch", 0, + AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1, + db_scale_master), +AK4531_DOUBLE("Master Playback Volume", 0, AK4531_LMASTER, AK4531_RMASTER, 0, 0, 0x1f, 1), + +AK4531_SINGLE_TLV("Master Mono Playback Switch", 0, AK4531_MONO_OUT, 7, 1, 1, + db_scale_mono), +AK4531_SINGLE("Master Mono Playback Volume", 0, AK4531_MONO_OUT, 0, 0x07, 1), + +AK4531_DOUBLE("PCM Switch", 0, AK4531_LVOICE, AK4531_RVOICE, 7, 7, 1, 1), +AK4531_DOUBLE_TLV("PCM Volume", 0, AK4531_LVOICE, AK4531_RVOICE, 0, 0, 0x1f, 1, + db_scale_input), +AK4531_DOUBLE("PCM Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 3, 2, 1, 0), +AK4531_DOUBLE("PCM Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 2, 2, 1, 0), + +AK4531_DOUBLE("PCM Switch", 1, AK4531_LFM, AK4531_RFM, 7, 7, 1, 1), +AK4531_DOUBLE_TLV("PCM Volume", 1, AK4531_LFM, AK4531_RFM, 0, 0, 0x1f, 1, + db_scale_input), +AK4531_DOUBLE("PCM Playback Switch", 1, AK4531_OUT_SW1, AK4531_OUT_SW1, 6, 5, 1, 0), +AK4531_INPUT_SW("PCM Capture Route", 1, AK4531_LIN_SW1, AK4531_RIN_SW1, 6, 5), + +AK4531_DOUBLE("CD Switch", 0, AK4531_LCD, AK4531_RCD, 7, 7, 1, 1), +AK4531_DOUBLE_TLV("CD Volume", 0, AK4531_LCD, AK4531_RCD, 0, 0, 0x1f, 1, + db_scale_input), +AK4531_DOUBLE("CD Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 2, 1, 1, 0), +AK4531_INPUT_SW("CD Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 2, 1), + +AK4531_DOUBLE("Line Switch", 0, AK4531_LLINE, AK4531_RLINE, 7, 7, 1, 1), +AK4531_DOUBLE_TLV("Line Volume", 0, AK4531_LLINE, AK4531_RLINE, 0, 0, 0x1f, 1, + db_scale_input), +AK4531_DOUBLE("Line Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 4, 3, 1, 0), +AK4531_INPUT_SW("Line Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 4, 3), + +AK4531_DOUBLE("Aux Switch", 0, AK4531_LAUXA, AK4531_RAUXA, 7, 7, 1, 1), +AK4531_DOUBLE_TLV("Aux Volume", 0, AK4531_LAUXA, AK4531_RAUXA, 0, 0, 0x1f, 1, + db_scale_input), +AK4531_DOUBLE("Aux Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 5, 4, 1, 0), +AK4531_INPUT_SW("Aux Capture Route", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 4, 3), + +AK4531_SINGLE("Mono Switch", 0, AK4531_MONO1, 7, 1, 1), +AK4531_SINGLE_TLV("Mono Volume", 0, AK4531_MONO1, 0, 0x1f, 1, db_scale_input), +AK4531_SINGLE("Mono Playback Switch", 0, AK4531_OUT_SW2, 0, 1, 0), +AK4531_DOUBLE("Mono Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 0, 0, 1, 0), + +AK4531_SINGLE("Mono Switch", 1, AK4531_MONO2, 7, 1, 1), +AK4531_SINGLE_TLV("Mono Volume", 1, AK4531_MONO2, 0, 0x1f, 1, db_scale_input), +AK4531_SINGLE("Mono Playback Switch", 1, AK4531_OUT_SW2, 1, 1, 0), +AK4531_DOUBLE("Mono Capture Switch", 1, AK4531_LIN_SW2, AK4531_RIN_SW2, 1, 1, 1, 0), + +AK4531_SINGLE_TLV("Mic Volume", 0, AK4531_MIC, 0, 0x1f, 1, db_scale_input), +AK4531_SINGLE("Mic Switch", 0, AK4531_MIC, 7, 1, 1), +AK4531_SINGLE("Mic Playback Switch", 0, AK4531_OUT_SW1, 0, 1, 0), +AK4531_DOUBLE("Mic Capture Switch", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 0, 0, 1, 0), + +AK4531_DOUBLE("Mic Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 7, 7, 1, 0), +AK4531_DOUBLE("Mono1 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 6, 6, 1, 0), +AK4531_DOUBLE("Mono2 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 5, 5, 1, 0), + +AK4531_SINGLE("AD Input Select", 0, AK4531_AD_IN, 0, 1, 0), +AK4531_SINGLE("Mic Boost (+30dB)", 0, AK4531_MIC_GAIN, 0, 1, 0) +}; + +static int snd_ak4531_free(struct snd_ak4531 *ak4531) +{ + if (ak4531) { + if (ak4531->private_free) + ak4531->private_free(ak4531); + kfree(ak4531); + } + return 0; +} + +static int snd_ak4531_dev_free(struct snd_device *device) +{ + struct snd_ak4531 *ak4531 = device->device_data; + return snd_ak4531_free(ak4531); +} + +static u8 snd_ak4531_initial_map[0x19 + 1] = { + 0x9f, /* 00: Master Volume Lch */ + 0x9f, /* 01: Master Volume Rch */ + 0x9f, /* 02: Voice Volume Lch */ + 0x9f, /* 03: Voice Volume Rch */ + 0x9f, /* 04: FM Volume Lch */ + 0x9f, /* 05: FM Volume Rch */ + 0x9f, /* 06: CD Audio Volume Lch */ + 0x9f, /* 07: CD Audio Volume Rch */ + 0x9f, /* 08: Line Volume Lch */ + 0x9f, /* 09: Line Volume Rch */ + 0x9f, /* 0a: Aux Volume Lch */ + 0x9f, /* 0b: Aux Volume Rch */ + 0x9f, /* 0c: Mono1 Volume */ + 0x9f, /* 0d: Mono2 Volume */ + 0x9f, /* 0e: Mic Volume */ + 0x87, /* 0f: Mono-out Volume */ + 0x00, /* 10: Output Mixer SW1 */ + 0x00, /* 11: Output Mixer SW2 */ + 0x00, /* 12: Lch Input Mixer SW1 */ + 0x00, /* 13: Rch Input Mixer SW1 */ + 0x00, /* 14: Lch Input Mixer SW2 */ + 0x00, /* 15: Rch Input Mixer SW2 */ + 0x00, /* 16: Reset & Power Down */ + 0x00, /* 17: Clock Select */ + 0x00, /* 18: AD Input Select */ + 0x01 /* 19: Mic Amp Setup */ +}; + +int __devinit snd_ak4531_mixer(struct snd_card *card, + struct snd_ak4531 *_ak4531, + struct snd_ak4531 **rak4531) +{ + unsigned int idx; + int err; + struct snd_ak4531 *ak4531; + static struct snd_device_ops ops = { + .dev_free = snd_ak4531_dev_free, + }; + + snd_assert(rak4531 != NULL, return -EINVAL); + *rak4531 = NULL; + snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL); + ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL); + if (ak4531 == NULL) + return -ENOMEM; + *ak4531 = *_ak4531; + mutex_init(&ak4531->reg_mutex); + if ((err = snd_component_add(card, "AK4531")) < 0) { + snd_ak4531_free(ak4531); + return err; + } + strcpy(card->mixername, "Asahi Kasei AK4531"); + ak4531->write(ak4531, AK4531_RESET, 0x03); /* no RST, PD */ + udelay(100); + ak4531->write(ak4531, AK4531_CLOCK, 0x00); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off LRCLK2 PLL */ + for (idx = 0; idx <= 0x19; idx++) { + if (idx == AK4531_RESET || idx == AK4531_CLOCK) + continue; + ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]); /* recording source is mixer */ + } + for (idx = 0; idx < ARRAY_SIZE(snd_ak4531_controls); idx++) { + if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531))) < 0) { + snd_ak4531_free(ak4531); + return err; + } + } + snd_ak4531_proc_init(card, ak4531); + if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) { + snd_ak4531_free(ak4531); + return err; + } + +#if 0 + snd_ak4531_dump(ak4531); +#endif + *rak4531 = ak4531; + return 0; +} + +/* + * power management + */ +#ifdef CONFIG_PM +void snd_ak4531_suspend(struct snd_ak4531 *ak4531) +{ + /* mute */ + ak4531->write(ak4531, AK4531_LMASTER, 0x9f); + ak4531->write(ak4531, AK4531_RMASTER, 0x9f); + /* powerdown */ + ak4531->write(ak4531, AK4531_RESET, 0x01); +} + +void snd_ak4531_resume(struct snd_ak4531 *ak4531) +{ + int idx; + + /* initialize */ + ak4531->write(ak4531, AK4531_RESET, 0x03); + udelay(100); + ak4531->write(ak4531, AK4531_CLOCK, 0x00); + /* restore mixer registers */ + for (idx = 0; idx <= 0x19; idx++) { + if (idx == AK4531_RESET || idx == AK4531_CLOCK) + continue; + ak4531->write(ak4531, idx, ak4531->regs[idx]); + } +} +#endif + +#ifdef CONFIG_PROC_FS +/* + * /proc interface + */ + +static void snd_ak4531_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_ak4531 *ak4531 = entry->private_data; + + snd_iprintf(buffer, "Asahi Kasei AK4531\n\n"); + snd_iprintf(buffer, "Recording source : %s\n" + "MIC gain : %s\n", + ak4531->regs[AK4531_AD_IN] & 1 ? "external" : "mixer", + ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB"); +} + +static void __devinit +snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531) +{ + struct snd_info_entry *entry; + + if (! snd_card_proc_new(card, "ak4531", &entry)) + snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read); +} +#endif -- cgit v0.10.2 From 8bb8b453cb458d8f62411e78a4cfd6d860b503b6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 09:47:45 +0200 Subject: [ALSA] trident - clean up obsolete synth codes Clean up the unused synth codes in the memory handling of trident driver. Signed-off-by: Takashi Iwai diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index df9b487..3fd7f1b 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -310,181 +310,3 @@ int snd_trident_free_pages(struct snd_trident *trident, mutex_unlock(&hdr->block_mutex); return 0; } - - -/*---------------------------------------------------------------- - * memory allocation using multiple pages (for synth) - *---------------------------------------------------------------- - * Unlike the DMA allocation above, non-contiguous pages are - * assigned to TLB. - *----------------------------------------------------------------*/ - -/* - */ -static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk); -static int synth_free_pages(struct snd_trident *hw, struct snd_util_memblk *blk); - -/* - * allocate a synth sample area - */ -struct snd_util_memblk * -snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size) -{ - struct snd_util_memblk *blk; - struct snd_util_memhdr *hdr = hw->tlb.memhdr; - - mutex_lock(&hdr->block_mutex); - blk = __snd_util_mem_alloc(hdr, size); - if (blk == NULL) { - mutex_unlock(&hdr->block_mutex); - return NULL; - } - if (synth_alloc_pages(hw, blk)) { - __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); - return NULL; - } - mutex_unlock(&hdr->block_mutex); - return blk; -} - -EXPORT_SYMBOL(snd_trident_synth_alloc); - -/* - * free a synth sample area - */ -int -snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk) -{ - struct snd_util_memhdr *hdr = hw->tlb.memhdr; - - mutex_lock(&hdr->block_mutex); - synth_free_pages(hw, blk); - __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); - return 0; -} - -EXPORT_SYMBOL(snd_trident_synth_free); - -/* - * reset TLB entry and free kernel page - */ -static void clear_tlb(struct snd_trident *trident, int page) -{ - void *ptr = page_to_ptr(trident, page); - dma_addr_t addr = page_to_addr(trident, page); - set_silent_tlb(trident, page); - if (ptr) { - struct snd_dma_buffer dmab; - dmab.dev.type = SNDRV_DMA_TYPE_DEV; - dmab.dev.dev = snd_dma_pci_data(trident->pci); - dmab.area = ptr; - dmab.addr = addr; - dmab.bytes = ALIGN_PAGE_SIZE; - snd_dma_free_pages(&dmab); - } -} - -/* check new allocation range */ -static void get_single_page_range(struct snd_util_memhdr *hdr, - struct snd_util_memblk *blk, - int *first_page_ret, int *last_page_ret) -{ - struct list_head *p; - struct snd_util_memblk *q; - int first_page, last_page; - first_page = firstpg(blk); - if ((p = blk->list.prev) != &hdr->block) { - q = list_entry(p, struct snd_util_memblk, list); - if (lastpg(q) == first_page) - first_page++; /* first page was already allocated */ - } - last_page = lastpg(blk); - if ((p = blk->list.next) != &hdr->block) { - q = list_entry(p, struct snd_util_memblk, list); - if (firstpg(q) == last_page) - last_page--; /* last page was already allocated */ - } - *first_page_ret = first_page; - *last_page_ret = last_page; -} - -/* - * allocate kernel pages and assign them to TLB - */ -static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk) -{ - int page, first_page, last_page; - struct snd_dma_buffer dmab; - - firstpg(blk) = get_aligned_page(blk->offset); - lastpg(blk) = get_aligned_page(blk->offset + blk->size - 1); - get_single_page_range(hw->tlb.memhdr, blk, &first_page, &last_page); - - /* allocate a kernel page for each Trident page - - * fortunately Trident page size and kernel PAGE_SIZE is identical! - */ - for (page = first_page; page <= last_page; page++) { - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(hw->pci), - ALIGN_PAGE_SIZE, &dmab) < 0) - goto __fail; - if (! is_valid_page(dmab.addr)) { - snd_dma_free_pages(&dmab); - goto __fail; - } - set_tlb_bus(hw, page, (unsigned long)dmab.area, dmab.addr); - } - return 0; - -__fail: - /* release allocated pages */ - last_page = page - 1; - for (page = first_page; page <= last_page; page++) - clear_tlb(hw, page); - - return -ENOMEM; -} - -/* - * free pages - */ -static int synth_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk) -{ - int page, first_page, last_page; - - get_single_page_range(trident->tlb.memhdr, blk, &first_page, &last_page); - for (page = first_page; page <= last_page; page++) - clear_tlb(trident, page); - - return 0; -} - -/* - * copy_from_user(blk + offset, data, size) - */ -int snd_trident_synth_copy_from_user(struct snd_trident *trident, - struct snd_util_memblk *blk, - int offset, const char __user *data, int size) -{ - int page, nextofs, end_offset, temp, temp1; - - offset += blk->offset; - end_offset = offset + size; - page = get_aligned_page(offset) + 1; - do { - nextofs = aligned_page_offset(page); - temp = nextofs - offset; - temp1 = end_offset - offset; - if (temp1 < temp) - temp = temp1; - if (copy_from_user(offset_ptr(trident, offset), data, temp)) - return -EFAULT; - offset = nextofs; - data += temp; - page++; - } while (offset < end_offset); - return 0; -} - -EXPORT_SYMBOL(snd_trident_synth_copy_from_user); -- cgit v0.10.2 From 8ff7f2a46bd8831e1f1f2a694ec13921720180b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 21 Feb 2008 16:30:10 +0100 Subject: There is no need to have BOOT_PARAMS_SIZE known outside of atags.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit atags.c was the only user of KEXEC_BOOT_PARAMS_SIZE and kexec.h was only included to get that definition. Signed-off-by: Uwe Kleine-König Acked-by: Uli Luckas diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c index 64c4208..56fef9a 100644 --- a/arch/arm/kernel/atags.c +++ b/arch/arm/kernel/atags.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -42,14 +41,14 @@ create_proc_entries(void) return 0; } - -static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE]; +#define BOOT_PARAMS_SIZE 1536 +static char __initdata atags_copy_buf[BOOT_PARAMS_SIZE]; static char __initdata *atags_copy; void __init save_atags(const struct tag *tags) { atags_copy = atags_copy_buf; - memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE); + memcpy(atags_copy, tags, sizeof(atags_copy_buf)); } diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h index 47fe34d..c8986bb 100644 --- a/include/asm-arm/kexec.h +++ b/include/asm-arm/kexec.h @@ -14,8 +14,6 @@ #define KEXEC_ARCH KEXEC_ARCH_ARM -#define KEXEC_BOOT_PARAMS_SIZE 1536 - #define KEXEC_ARM_ATAGS_OFFSET 0x1000 #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000 -- cgit v0.10.2 From f7b0b939d54b457ba172e088f477af2012aef9b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 21 Feb 2008 15:04:40 +0100 Subject: clean up atags exporting code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This gets rid of two static variables (one of them being __initdata) and a static function. Signed-off-by: Uwe Kleine-König Acked-by: Uli Luckas diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c index 56fef9a..42a1a14 100644 --- a/arch/arm/kernel/atags.c +++ b/arch/arm/kernel/atags.c @@ -6,9 +6,8 @@ struct buffer { size_t size; - char *data; + char data[]; }; -static struct buffer tags_buffer; static int read_buffer(char* page, char** start, off_t off, int count, @@ -28,58 +27,57 @@ read_buffer(char* page, char** start, off_t off, int count, return count; } - -static int -create_proc_entries(void) -{ - struct proc_dir_entry* tags_entry; - - tags_entry = create_proc_read_entry("atags", 0400, NULL, read_buffer, &tags_buffer); - if (!tags_entry) - return -ENOMEM; - - return 0; -} - #define BOOT_PARAMS_SIZE 1536 -static char __initdata atags_copy_buf[BOOT_PARAMS_SIZE]; -static char __initdata *atags_copy; +static char __initdata atags_copy[BOOT_PARAMS_SIZE]; void __init save_atags(const struct tag *tags) { - atags_copy = atags_copy_buf; - memcpy(atags_copy, tags, sizeof(atags_copy_buf)); + memcpy(atags_copy, tags, sizeof(atags_copy)); } - static int __init init_atags_procfs(void) { - struct tag *tag; - int error; + /* + * This cannot go into save_atags() because kmalloc and proc don't work + * yet when it is called. + */ + struct proc_dir_entry *tags_entry; + struct tag *tag = (struct tag *)atags_copy; + struct buffer *b; + size_t size; - if (!atags_copy) { - printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n"); - return -EIO; + if (tag->hdr.tag != ATAG_CORE) { + printk(KERN_INFO "No ATAGs?"); + return -EINVAL; } - for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag)) + for (; tag->hdr.size; tag = tag_next(tag)) ; - tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr); - tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL); - if (tags_buffer.data == NULL) - return -ENOMEM; - memcpy(tags_buffer.data, atags_copy, tags_buffer.size); - - error = create_proc_entries(); - if (error) { - printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); - kfree(tags_buffer.data); - tags_buffer.size = 0; - tags_buffer.data = NULL; - } + /* include the terminating ATAG_NONE */ + size = (char *)tag - atags_copy + sizeof(struct tag_header); - return error; -} + WARN_ON(tag->hdr.tag != ATAG_NONE); + + b = kmalloc(sizeof(*b) + size, GFP_KERNEL); + if (!b) + goto nomem; + b->size = size; + memcpy(b->data, atags_copy, size); + + tags_entry = create_proc_read_entry("atags", 0400, + NULL, read_buffer, b); + + if (!tags_entry) + goto nomem; + + return 0; + +nomem: + kfree(b); + printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); + + return -ENOMEM; +} arch_initcall(init_atags_procfs); -- cgit v0.10.2 From a4831fbe096a6f4f691fd71b041ce27add54088e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 21 May 2008 10:17:07 +0200 Subject: ns9xxx: fix assembler version of __REG2 to be consistent with the C version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not very critical because __REG2 isn't used in assembler code currently. Additionally some white space noise is fixed. Signed-off-by: Uwe Kleine-König diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h index 0b7b346..0dca11c 100644 --- a/include/asm-arm/arch-ns9xxx/hardware.h +++ b/include/asm-arm/arch-ns9xxx/hardware.h @@ -66,13 +66,13 @@ __REGGET(var, reg ## _ ## field) / __REGSHIFT(reg ## _ ## field) # define REGGETIM_IDX(var, reg, field, idx) \ - __REGGET(var, reg ## _ ## field((idx))) / \ + __REGGET(var, reg ## _ ## field((idx))) / \ __REGSHIFT(reg ## _ ## field((idx))) #else # define __REG(x) io_p2v(x) -# define __REG2(x, y) io_p2v((x) + (y)) +# define __REG2(x, y) io_p2v((x) + 4 * (y)) #endif -- cgit v0.10.2 From 72860b0f3c4a303498c9e16c8a4a38ddf23d56de Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 11:25:03 +0200 Subject: sound: Clean up sound/oss/Kconfig Removed unnecessary dependencies, fix a wrong selection, and make CONFIG_SOUND_OSS menuconfig to simplify. Signed-off-by: Takashi Iwai diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 3be2dc1..3394013 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -7,7 +7,7 @@ config SOUND_BCM_CS4297A tristate "Crystal Sound CS4297a (for Swarm)" - depends on SOUND_PRIME && SIBYTE_SWARM + depends on SIBYTE_SWARM help The BCM91250A has a Crystal CS4297a on synchronous serial port B (in addition to the DB-9 serial port). Say Y or M @@ -17,7 +17,7 @@ config SOUND_BCM_CS4297A config SOUND_VWSND tristate "SGI Visual Workstation Sound" - depends on SOUND_PRIME && X86_VISWS + depends on X86_VISWS help Say Y or M if you have an SGI Visual Workstation and you want to be able to use its on-board audio. Read @@ -26,19 +26,18 @@ config SOUND_VWSND config SOUND_HAL2 tristate "SGI HAL2 sound (EXPERIMENTAL)" - depends on SOUND_PRIME && SGI_IP22 && EXPERIMENTAL + depends on SGI_IP22 && EXPERIMENTAL help Say Y or M if you have an SGI Indy or Indigo2 system and want to be able to use its on-board A2 audio system. config SOUND_AU1550_AC97 tristate "Au1550/Au1200 AC97 Sound" - select SND_AC97_CODEC - depends on SOUND_PRIME && (SOC_AU1550 || SOC_AU1200) + depends on SOC_AU1550 || SOC_AU1200 config SOUND_TRIDENT tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" - depends on SOUND_PRIME && PCI + depends on PCI ---help--- Say Y or M if you have a PCI sound card utilizing the Trident 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 @@ -79,7 +78,7 @@ config SOUND_TRIDENT config SOUND_MSNDCLAS tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" - depends on SOUND_PRIME && (m || !STANDALONE) && ISA + depends on (m || !STANDALONE) && ISA help Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or Monterey (not for the Pinnacle or Fiji). @@ -143,7 +142,7 @@ config MSNDCLAS_IO config SOUND_MSNDPIN tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji" - depends on SOUND_PRIME && (m || !STANDALONE) && ISA + depends on (m || !STANDALONE) && ISA help Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji. See for important information @@ -229,7 +228,7 @@ config MSNDPIN_NONPNP configure the card's resources. comment "MSND Pinnacle DSP section will be configured to above parameters." - depends on SOUND_PRIME && SOUND_MSNDPIN=y && MSNDPIN_NONPNP + depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP config MSNDPIN_CFG hex "MSND Pinnacle config port 250,260,270" @@ -242,7 +241,7 @@ config MSNDPIN_CFG Mode". comment "Pinnacle-specific Device Configuration (0 disables)" - depends on SOUND_PRIME && SOUND_MSNDPIN=y && MSNDPIN_NONPNP + depends on SOUND_MSNDPIN=y && MSNDPIN_NONPNP config MSNDPIN_MPU_IO hex "MSND Pinnacle MPU I/O (e.g. 330)" @@ -294,7 +293,7 @@ config MSNDPIN_JOYSTICK_IO config MSND_FIFOSIZE int "MSND buffer size (kB)" - depends on SOUND_PRIME && (SOUND_MSNDPIN=y || SOUND_MSNDCLAS=y) + depends on SOUND_MSNDPIN=y || SOUND_MSNDCLAS=y default "128" help Configures the size of each audio buffer, in kilobytes, for @@ -302,9 +301,9 @@ config MSND_FIFOSIZE and Pinnacle). Larger values reduce the chance of data overruns at the expense of overall latency. If unsure, use the default. -config SOUND_OSS +menuconfig SOUND_OSS tristate "OSS sound modules" - depends on SOUND_PRIME && ISA_DMA_API && VIRT_TO_BUS + depends on ISA_DMA_API && VIRT_TO_BUS help OSS is the Open Sound System suite of sound card drivers. They make sound programming easier since they provide a common API. Say Y or @@ -312,16 +311,16 @@ config SOUND_OSS driver for your sound card above, then pick your driver from the list below. +if SOUND_OSS + config SOUND_TRACEINIT bool "Verbose initialisation" - depends on SOUND_OSS help Verbose soundcard initialization -- affects the format of autoprobe and initialization messages at boot time. config SOUND_DMAP bool "Persistent DMA buffers" - depends on SOUND_OSS ---help--- Linux can often have problems allocating DMA buffers for ISA sound cards on machines with more than 16MB of RAM. This is because ISA @@ -338,8 +337,6 @@ config SOUND_DMAP config SOUND_SSCAPE tristate "Ensoniq SoundScape support" - depends on SOUND_OSS - depends on VIRT_TO_BUS help Answer Y if you have a sound card based on the Ensoniq SoundScape chipset. Such cards are being manufactured at least by Ensoniq, Spea @@ -352,13 +349,11 @@ config SOUND_SSCAPE config SOUND_VMIDI tristate "Loopback MIDI device support" - depends on SOUND_OSS help Support for MIDI loopback on port 1 or 2. config SOUND_TRIX tristate "MediaTrix AudioTrix Pro support" - depends on SOUND_OSS help Answer Y if you have the AudioTriX Pro sound card manufactured by MediaTrix. @@ -382,7 +377,6 @@ config TRIX_BOOT_FILE config SOUND_MSS tristate "Microsoft Sound System support" - depends on SOUND_OSS ---help--- Again think carefully before answering Y to this question. It's safe to answer Y if you have the original Windows Sound System card @@ -414,7 +408,6 @@ config SOUND_MSS config SOUND_MPU401 tristate "MPU-401 support (NOT for SB16)" - depends on SOUND_OSS ---help--- Be careful with this question. The MPU401 interface is supported by all sound cards. However, some natively supported cards have their @@ -430,7 +423,6 @@ config SOUND_MPU401 config SOUND_PAS tristate "ProAudioSpectrum 16 support" - depends on SOUND_OSS ---help--- Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio 16 or Logitech SoundMan 16 sound card. Answer N if you have some @@ -452,7 +444,6 @@ config PAS_JOYSTICK config SOUND_PSS tristate "PSS (AD1848, ADSP-2115, ESC614) support" - depends on SOUND_OSS help Answer Y or M if you have an Orchid SW32, Cardinal DSP16, Beethoven ADSP-16 or some other card based on the PSS chipset (AD1848 codec + @@ -495,7 +486,6 @@ config PSS_BOOT_FILE config SOUND_SB tristate "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support" - depends on SOUND_OSS ---help--- Answer Y if you have an original Sound Blaster card made by Creative Labs or a 100% hardware compatible clone (like the Thunderboard or @@ -522,7 +512,6 @@ config SOUND_SB config SOUND_YM3812 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" - depends on SOUND_OSS ---help--- Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). Answering Y is usually a safe and recommended choice, however some @@ -538,7 +527,6 @@ config SOUND_YM3812 config SOUND_UART6850 tristate "6850 UART support" - depends on SOUND_OSS help This option enables support for MIDI interfaces based on the 6850 UART chip. This interface is rarely found on sound cards. It's safe @@ -549,7 +537,6 @@ config SOUND_UART6850 config SOUND_AEDSP16 tristate "Gallant Audio Cards (SC-6000 and SC-6600 based)" - depends on SOUND_OSS ---help--- Answer Y if you have a Gallant's Audio Excel DSP 16 card. This driver supports Audio Excel DSP 16 but not the III nor PnP versions @@ -630,14 +617,14 @@ endchoice config SOUND_VIDC tristate "VIDC 16-bit sound" - depends on ARM && (ARCH_ACORN || ARCH_CLPS7500) && SOUND_OSS + depends on ARM && (ARCH_ACORN || ARCH_CLPS7500) help 16-bit support for the VIDC onboard sound hardware found on Acorn machines. config SOUND_WAVEARTIST tristate "Netwinder WaveArtist" - depends on ARM && SOUND_OSS && ARCH_NETWINDER + depends on ARM && ARCH_NETWINDER help Say Y here to include support for the Rockwell WaveArtist sound system. This driver is mainly for the NetWinder. @@ -646,9 +633,11 @@ config SOUND_KAHLUA tristate "XpressAudio Sound Blaster emulation" depends on SOUND_SB +endif # SOUND_OSS + config SOUND_SH_DAC_AUDIO tristate "SuperH DAC audio support" - depends on SOUND_PRIME && CPU_SH3 + depends on CPU_SH3 config SOUND_SH_DAC_AUDIO_CHANNEL int "DAC channel" -- cgit v0.10.2 From 2621f0338ce4e3e57cc32a967f5a3d2999390fe3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 11:27:24 +0200 Subject: [ALSA] trivial clean up of sound/isa/sb/Makefile Remove unneeded sort in sound/isa/sb/Makefile. Signed-off-by: Takashi Iwai diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index c9d1c98..1098a56 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -34,5 +34,3 @@ ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o endif obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o - -obj-m := $(sort $(obj-m)) -- cgit v0.10.2 From a5003fc04113c217370409beac812831cbf6e0ac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 May 2008 09:49:41 +0200 Subject: [ALSA] emu10k1 - simplify page allocation for synth Simplify the page allocation of emu10k1 driver for emux synth support. Since these pages aren't be necessarily coherent, we can avoid expensive DMA-coherent routines. Signed-off-by: Takashi Iwai diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 916c1db..128eaca 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -437,43 +437,46 @@ static void get_single_page_range(struct snd_util_memhdr *hdr, *last_page_ret = last_page; } +/* release allocated pages */ +static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page, + int last_page) +{ + int page; + + for (page = first_page; page <= last_page; page++) { + free_page((unsigned long)emu->page_ptr_table[page]); + emu->page_addr_table[page] = 0; + emu->page_ptr_table[page] = NULL; + } +} + /* * allocate kernel pages */ static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) { int page, first_page, last_page; - struct snd_dma_buffer dmab; emu10k1_memblk_init(blk); get_single_page_range(emu->memhdr, blk, &first_page, &last_page); /* allocate kernel pages */ for (page = first_page; page <= last_page; page++) { - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), - PAGE_SIZE, &dmab) < 0) - goto __fail; - if (! is_valid_page(emu, dmab.addr)) { - snd_dma_free_pages(&dmab); - goto __fail; + /* first try to allocate from <4GB zone */ + struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 | + __GFP_NOWARN); + if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) + /* try to allocate from <16MB zone */ + p = alloc_page(GFP_DMA | + __GFP_NORETRY | /* no OOM-killer */ + __GFP_NOWARN); + if (!p) { + __synth_free_pages(emu, first_page, page - 1); + return -ENOMEM; } - emu->page_addr_table[page] = dmab.addr; - emu->page_ptr_table[page] = dmab.area; + emu->page_addr_table[page] = page_to_phys(p); + emu->page_ptr_table[page] = page_address(p); } return 0; - -__fail: - /* release allocated pages */ - last_page = page - 1; - for (page = first_page; page <= last_page; page++) { - dmab.area = emu->page_ptr_table[page]; - dmab.addr = emu->page_addr_table[page]; - dmab.bytes = PAGE_SIZE; - snd_dma_free_pages(&dmab); - emu->page_addr_table[page] = 0; - emu->page_ptr_table[page] = NULL; - } - - return -ENOMEM; } /* @@ -481,23 +484,10 @@ __fail: */ static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) { - int page, first_page, last_page; - struct snd_dma_buffer dmab; + int first_page, last_page; get_single_page_range(emu->memhdr, blk, &first_page, &last_page); - dmab.dev.type = SNDRV_DMA_TYPE_DEV; - dmab.dev.dev = snd_dma_pci_data(emu->pci); - for (page = first_page; page <= last_page; page++) { - if (emu->page_ptr_table[page] == NULL) - continue; - dmab.area = emu->page_ptr_table[page]; - dmab.addr = emu->page_addr_table[page]; - dmab.bytes = PAGE_SIZE; - snd_dma_free_pages(&dmab); - emu->page_addr_table[page] = 0; - emu->page_ptr_table[page] = NULL; - } - + __synth_free_pages(emu, first_page, last_page); return 0; } -- cgit v0.10.2 From 7a14ce1d8c1d3a6118d406e64eaf9aa70375e085 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 May 2008 15:43:53 +0200 Subject: nohz: reduce jiffies polling overhead Signed-off-by: Ingo Molnar diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index b854a89..cb75394 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -48,6 +48,13 @@ static void tick_do_update_jiffies64(ktime_t now) unsigned long ticks = 0; ktime_t delta; + /* + * Do a quick check without holding xtime_lock: + */ + delta = ktime_sub(now, last_jiffies_update); + if (delta.tv64 < tick_period.tv64) + return; + /* Reevalute with xtime_lock held */ write_seqlock(&xtime_lock); -- cgit v0.10.2 From 014c257cce65e9d1cd2d28ec1c89a37c536b151d Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 31 May 2008 14:23:50 +0530 Subject: ftrace: core support for ARM Core ftrace support for the ARM architecture, which includes support for dynamic function tracing. Signed-off-by: Abhishek Sagar Signed-off-by: Ingo Molnar diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68..3845e5c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -14,6 +14,8 @@ config ARM select HAVE_OPROFILE select HAVE_KPROBES if (!XIP_KERNEL) select HAVE_KRETPROBES if (HAVE_KPROBES) + select HAVE_FTRACE if (!XIP_KERNEL) + select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE) help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index de9d9ee..95baac4 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -69,6 +69,12 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ head.o misc.o $(OBJS) + +ifeq ($(CONFIG_FTRACE),y) +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) +endif + EXTRA_CFLAGS := -fpic -fno-builtin EXTRA_AFLAGS := diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index ad455ff..eb9092c 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -4,6 +4,10 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) +ifdef CONFIG_DYNAMIC_FTRACE +CFLAGS_REMOVE_ftrace.o = -pg +endif + # Object file lists. obj-y := compat.o entry-armv.o entry-common.o irq.o \ @@ -18,6 +22,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o obj-$(CONFIG_ATAGS_PROC) += atags.o diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 688b7b1..3b13221 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -48,6 +48,11 @@ extern void __aeabi_ulcmp(void); extern void fpundefinstr(void); extern void fp_enter(void); +#ifdef CONFIG_FTRACE +extern void mcount(void); +EXPORT_SYMBOL(mcount); +#endif + /* * This has a special calling convention; it doesn't * modify any of the usual registers, except for LR. diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 597ed00..8f79a47 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -99,6 +99,53 @@ ENTRY(ret_from_fork) #undef CALL #define CALL(x) .long x +#ifdef CONFIG_FTRACE +#ifdef CONFIG_DYNAMIC_FTRACE +ENTRY(mcount) + stmdb sp!, {r0-r3, lr} + mov r0, lr + + .globl mcount_call +mcount_call: + bl ftrace_stub + ldmia sp!, {r0-r3, pc} + +ENTRY(ftrace_caller) + stmdb sp!, {r0-r3, lr} + ldr r1, [fp, #-4] + mov r0, lr + + .globl ftrace_call +ftrace_call: + bl ftrace_stub + ldmia sp!, {r0-r3, pc} + +#else + +ENTRY(mcount) + stmdb sp!, {r0-r3, lr} + ldr r0, =ftrace_trace_function + ldr r2, [r0] + adr r0, ftrace_stub + cmp r0, r2 + bne trace + ldmia sp!, {r0-r3, pc} + +trace: + ldr r1, [fp, #-4] + mov r0, lr + mov lr, pc + mov pc, r2 + ldmia sp!, {r0-r3, pc} + +#endif /* CONFIG_DYNAMIC_FTRACE */ + + .globl ftrace_stub +ftrace_stub: + mov pc, lr + +#endif /* CONFIG_FTRACE */ + /*============================================================================= * SWI handler *----------------------------------------------------------------------------- diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c new file mode 100644 index 0000000..f4cb4cc --- /dev/null +++ b/arch/arm/kernel/ftrace.c @@ -0,0 +1,128 @@ +/* + * Dynamic function tracing support. + * + * Copyright (C) 2008 Abhishek Sagar + * + * For licencing details, see COPYING. + * + * Defines low-level handling of mcount calls when the kernel + * is compiled with the -pg flag. When using dynamic ftrace, the + * mcount call-sites get patched lazily with NOP till they are + * enabled. All code mutation routines here take effect atomically. + */ + +#include +#include + +#define INSN_SIZE 4 +#define PC_OFFSET 8 +#define BL_OPCODE 0xeb000000 +#define BL_OFFSET_MASK 0x00ffffff + +static unsigned long bl_insn; +static const unsigned long NOP = 0xe1a00000; /* mov r0, r0 */ + +/* return true if mcount call site is already patched/no-op'ed */ +int ftrace_ip_converted(unsigned long pc) +{ + unsigned long save; + + pc -= INSN_SIZE; + save = *(unsigned long *)pc; + return save == NOP; +} + +unsigned char *ftrace_nop_replace(void) +{ + return (char *)&NOP; +} + +/* construct a branch (BL) instruction to addr */ +unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr) +{ + long offset; + + offset = (long)addr - (long)(pc - INSN_SIZE + PC_OFFSET); + if (unlikely(offset < -33554432 || offset > 33554428)) { + /* Can't generate branches that far (from ARM ARM). Ftrace + * doesn't generate branches outside of core kernel text. + */ + WARN_ON_ONCE(1); + return NULL; + } + offset = (offset >> 2) & BL_OFFSET_MASK; + bl_insn = BL_OPCODE | offset; + return (unsigned char *)&bl_insn; +} + +int ftrace_modify_code(unsigned long pc, unsigned char *old_code, + unsigned char *new_code) +{ + unsigned long err = 0, replaced = 0, old, new; + + old = *(unsigned long *)old_code; + new = *(unsigned long *)new_code; + pc -= INSN_SIZE; + + __asm__ __volatile__ ( + "1: ldr %1, [%2] \n" + " cmp %1, %4 \n" + "2: streq %3, [%2] \n" + " cmpne %1, %3 \n" + " movne %0, #2 \n" + "3:\n" + + ".section .fixup, \"ax\"\n" + "4: mov %0, #1 \n" + " b 3b \n" + ".previous\n" + + ".section __ex_table, \"a\"\n" + " .long 1b, 4b \n" + " .long 2b, 4b \n" + ".previous\n" + + : "=r"(err), "=r"(replaced) + : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced) + : "memory"); + + if (!err && (replaced == old)) + flush_icache_range(pc, pc + INSN_SIZE); + + return err; +} + +int ftrace_update_ftrace_func(ftrace_func_t func) +{ + int ret; + unsigned long pc, old; + unsigned char *new; + + pc = (unsigned long)&ftrace_call; + pc += INSN_SIZE; + memcpy(&old, &ftrace_call, INSN_SIZE); + new = ftrace_call_replace(pc, (unsigned long)func); + ret = ftrace_modify_code(pc, (unsigned char *)&old, new); + return ret; +} + +int ftrace_mcount_set(unsigned long *data) +{ + unsigned long pc, old; + unsigned long *addr = data; + unsigned char *new; + + pc = (unsigned long)&mcount_call; + pc += INSN_SIZE; + memcpy(&old, &mcount_call, INSN_SIZE); + new = ftrace_call_replace(pc, *addr); + *addr = ftrace_modify_code(pc, (unsigned char *)&old, new); + return 0; +} + +/* run from kstop_machine */ +int __init ftrace_dyn_arch_init(void *data) +{ + ftrace_mcount_set(data); + return 0; +} -- cgit v0.10.2 From d2cd74b158d7214a556226e3312f9fb1de64d7ae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 2 Jun 2008 11:45:53 +0200 Subject: [ALSA] emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2 On Audigy2 Platinum, the Analog/Digital mixer switch is inverted. https://bugzilla.novell.com/show_bug.cgi?id=396204 The patch adds a simple workaround. There might be another device requiring a similar fix, too (or fix for audigy2 generically), but right now I fix only the known broken one. Signed-off-by: Takashi Iwai diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 7b7b9b1..10ee28e 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -1670,6 +1670,7 @@ struct snd_emu_chip_details { unsigned char spi_dac; /* SPI interface for DAC */ unsigned char i2c_adc; /* I2C interface for ADC */ unsigned char adc_1361t; /* Use Philips 1361T ADC */ + unsigned char invert_shared_spdif; /* analog/digital switch inverted */ const char *driver; const char *name; const char *id; /* for backward compatibility - can be NULL if not needed */ diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 548c9cc..2f283ea 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1528,6 +1528,7 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ca0151_chip = 1, .spk71 = 1, .spdif_bug = 1, + .invert_shared_spdif = 1, /* digital/analog switch swapped */ .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index fd22120..f34bbfb 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; else ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; + if (emu->card_capabilities->invert_shared_spdif) + ucontrol->value.integer.value[0] = + !ucontrol->value.integer.value[0]; + return 0; } @@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, { unsigned long flags; struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int reg, val; + unsigned int reg, val, sw; int change = 0; + sw = ucontrol->value.integer.value[0]; + if (emu->card_capabilities->invert_shared_spdif) + sw = !sw; spin_lock_irqsave(&emu->reg_lock, flags); if ( emu->card_capabilities->i2c_adc) { /* Do nothing for Audigy 2 ZS Notebook */ } else if (emu->audigy) { reg = inl(emu->port + A_IOCFG); - val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0; + val = sw ? A_IOCFG_GPOUT0 : 0; change = (reg & A_IOCFG_GPOUT0) != val; if (change) { reg &= ~A_IOCFG_GPOUT0; @@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, } } reg = inl(emu->port + HCFG); - val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0; + val = sw ? HCFG_GPOUT0 : 0; change |= (reg & HCFG_GPOUT0) != val; if (change) { reg &= ~HCFG_GPOUT0; -- cgit v0.10.2 From 76094a2cf46e4ab776055d4086615b884408568c Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Wed, 28 May 2008 00:03:18 +0530 Subject: ftrace: distinguish kretprobe'd functions in trace logs Tracing functions via ftrace which have a kretprobe installed on them, can produce misleading output in their trace logs. E.g, consider the correct trace of the following sequence: do_IRQ() { ~ irq_enter(); ~ } Trace log (sample): -0 [00] 4154504455.781616: irq_enter <- do_IRQ But if irq_enter() has a kretprobe installed on it, the return value stored on the stack at each invocation is modified to divert the return to a kprobe trampoline function called kretprobe_trampoline(). So with this the trace would (currently) look like: -0 [00] 4154504455.781616: irq_enter <- kretprobe_trampoline Now this is quite misleading to the end user, as it suggests something that didn't actually happen. So just to avoid such misinterpretations, the inlined patch aims to output such a log as: -0 [00] 4154504455.781616: irq_enter <- [unknown/kretprobe'd] Signed-off-by: Abhishek Sagar Acked-by: Steven Rostedt Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0feae23..12f5e81 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1199,6 +1200,20 @@ static void s_stop(struct seq_file *m, void *p) mutex_unlock(&trace_types_lock); } +#define KRETPROBE_MSG "[unknown/kretprobe'd]" + +#ifdef CONFIG_KRETPROBES +static inline int kretprobed(unsigned long addr) +{ + return addr == (unsigned long)kretprobe_trampoline; +} +#else +static inline int kretprobed(unsigned long addr) +{ + return 0; +} +#endif /* CONFIG_KRETPROBES */ + static int seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) { @@ -1434,7 +1449,10 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) case TRACE_FN: seq_print_ip_sym(s, entry->fn.ip, sym_flags); trace_seq_puts(s, " ("); - seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); + if (kretprobed(entry->fn.parent_ip)) + trace_seq_puts(s, KRETPROBE_MSG); + else + seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); trace_seq_puts(s, ")\n"); break; case TRACE_CTX: @@ -1514,8 +1532,11 @@ static int print_trace_fmt(struct trace_iterator *iter) ret = trace_seq_printf(s, " <-"); if (!ret) return 0; - ret = seq_print_ip_sym(s, entry->fn.parent_ip, - sym_flags); + if (kretprobed(entry->fn.parent_ip)) + ret = trace_seq_puts(s, KRETPROBE_MSG); + else + ret = seq_print_ip_sym(s, entry->fn.parent_ip, + sym_flags); if (!ret) return 0; } -- cgit v0.10.2 From ad90c0e3ce8d20d6873b57e36181ef6d7a0097fe Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 27 May 2008 20:48:37 -0400 Subject: ftrace: user update and disable dynamic ftrace daemon In dynamic ftrace, the mcount function starts off pointing to a stub function that just returns. On start up, the call to the stub is modified to point to a "record_ip" function. The job of the record_ip function is to add the function to a pre-allocated hash list. If the function is already there, it simply is ignored, otherwise it is added to the list. Later, a ftraced daemon wakes up and calls kstop_machine if any functions have been recorded, and changes the calls to the recorded functions to a simple nop. If no functions were recorded, the daemon goes back to sleep. The daemon wakes up once a second to see if it needs to update any newly recorded functions into nops. Usually it does not, but if a lot of code has been executed for the first time in the kernel, the ftraced daemon will call kstop_machine to update those into nops. The problem currently is that there's no way to stop the daemon from doing this, and it can cause unneeded latencies (800us which for some is bothersome). This patch adds a new file /debugfs/tracing/ftraced_enabled. If the daemon is active, reading this will return "enabled\n" and "disabled\n" when the daemon is not running. To disable the daemon, the user can echo "0" or "disable" into this file, and "1" or "enable" to re-enable the daemon. Since the daemon is used to convert the functions into nops to increase the performance of the system, I also added that anytime something is written into the ftraced_enabled file, kstop_machine will run if there are new functions that have been detected that need to be converted. This way the user can disable the daemon but still be able to control the conversion of the mcount calls to nops by simply, "echo 0 > /debugfs/tracing/ftraced_enabled" when they need to do more conversions. To see the number of converted functions: "cat /debugfs/tracing/dyn_ftrace_total_info" Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b482fe8..6238194 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -72,9 +72,15 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); + +void ftrace_disable_daemon(void); +void ftrace_enable_daemon(void); + #else # define ftrace_force_update() ({ 0; }) # define ftrace_set_filter(buf, len, reset) do { } while (0) +# define ftrace_disable_daemon() do { } while (0) +# define ftrace_enable_daemon() do { } while (0) #endif /* totally disable ftrace - can not re-enable after this */ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 1843edc..f762f5a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -151,8 +151,6 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) #ifdef CONFIG_DYNAMIC_FTRACE static struct task_struct *ftraced_task; -static DECLARE_WAIT_QUEUE_HEAD(ftraced_waiters); -static unsigned long ftraced_iteration_counter; enum { FTRACE_ENABLE_CALLS = (1 << 0), @@ -189,6 +187,7 @@ static struct ftrace_page *ftrace_pages; static int ftraced_trigger; static int ftraced_suspend; +static int ftraced_stop; static int ftrace_record_suspend; @@ -474,14 +473,21 @@ ftrace_code_disable(struct dyn_ftrace *rec) return 1; } +static int __ftrace_update_code(void *ignore); + static int __ftrace_modify_code(void *data) { unsigned long addr; int *command = data; - if (*command & FTRACE_ENABLE_CALLS) + if (*command & FTRACE_ENABLE_CALLS) { + /* + * Update any recorded ips now that we have the + * machine stopped + */ + __ftrace_update_code(NULL); ftrace_replace_code(1); - else if (*command & FTRACE_DISABLE_CALLS) + } else if (*command & FTRACE_DISABLE_CALLS) ftrace_replace_code(0); if (*command & FTRACE_UPDATE_TRACE_FUNC) @@ -503,6 +509,25 @@ static void ftrace_run_update_code(int command) stop_machine_run(__ftrace_modify_code, &command, NR_CPUS); } +void ftrace_disable_daemon(void) +{ + /* Stop the daemon from calling kstop_machine */ + mutex_lock(&ftraced_lock); + ftraced_stop = 1; + mutex_unlock(&ftraced_lock); + + ftrace_force_update(); +} + +void ftrace_enable_daemon(void) +{ + mutex_lock(&ftraced_lock); + ftraced_stop = 0; + mutex_unlock(&ftraced_lock); + + ftrace_force_update(); +} + static ftrace_func_t saved_ftrace_func; static void ftrace_startup(void) @@ -603,6 +628,7 @@ static int __ftrace_update_code(void *ignore) int i; /* Don't be recording funcs now */ + ftrace_record_suspend++; save_ftrace_enabled = ftrace_enabled; ftrace_enabled = 0; @@ -628,18 +654,23 @@ static int __ftrace_update_code(void *ignore) stop = ftrace_now(raw_smp_processor_id()); ftrace_update_time = stop - start; ftrace_update_tot_cnt += ftrace_update_cnt; + ftraced_trigger = 0; ftrace_enabled = save_ftrace_enabled; + ftrace_record_suspend--; return 0; } -static void ftrace_update_code(void) +static int ftrace_update_code(void) { - if (unlikely(ftrace_disabled)) - return; + if (unlikely(ftrace_disabled) || + !ftrace_enabled || !ftraced_trigger) + return 0; stop_machine_run(__ftrace_update_code, NULL, NR_CPUS); + + return 1; } static int ftraced(void *ignore) @@ -658,14 +689,13 @@ static int ftraced(void *ignore) mutex_lock(&ftrace_sysctl_lock); mutex_lock(&ftraced_lock); - if (ftrace_enabled && ftraced_trigger && !ftraced_suspend) { - ftrace_record_suspend++; - ftrace_update_code(); + if (!ftraced_suspend && !ftraced_stop && + ftrace_update_code()) { usecs = nsecs_to_usecs(ftrace_update_time); if (ftrace_update_tot_cnt > 100000) { ftrace_update_tot_cnt = 0; pr_info("hm, dftrace overflow: %lu change%s" - " (%lu total) in %lu usec%s\n", + " (%lu total) in %lu usec%s\n", ftrace_update_cnt, ftrace_update_cnt != 1 ? "s" : "", ftrace_update_tot_cnt, @@ -673,15 +703,10 @@ static int ftraced(void *ignore) ftrace_disabled = 1; WARN_ON_ONCE(1); } - ftraced_trigger = 0; - ftrace_record_suspend--; } - ftraced_iteration_counter++; mutex_unlock(&ftraced_lock); mutex_unlock(&ftrace_sysctl_lock); - wake_up_interruptible(&ftraced_waiters); - ftrace_shutdown_replenish(); } __set_current_state(TASK_RUNNING); @@ -1219,6 +1244,55 @@ ftrace_notrace_release(struct inode *inode, struct file *file) return ftrace_regex_release(inode, file, 0); } +static ssize_t +ftraced_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + /* don't worry about races */ + char *buf = ftraced_stop ? "disabled\n" : "enabled\n"; + int r = strlen(buf); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t +ftraced_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + long val; + int ret; + + if (cnt >= sizeof(buf)) + return -EINVAL; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + if (strncmp(buf, "enable", 6) == 0) + val = 1; + else if (strncmp(buf, "disable", 7) == 0) + val = 0; + else { + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + return ret; + + val = !!val; + } + + if (val) + ftrace_enable_daemon(); + else + ftrace_disable_daemon(); + + filp->f_pos += cnt; + + return cnt; +} + static struct file_operations ftrace_avail_fops = { .open = ftrace_avail_open, .read = seq_read, @@ -1242,51 +1316,34 @@ static struct file_operations ftrace_notrace_fops = { .release = ftrace_notrace_release, }; +static struct file_operations ftraced_fops = { + .open = tracing_open_generic, + .read = ftraced_read, + .write = ftraced_write, +}; + /** * ftrace_force_update - force an update to all recording ftrace functions - * - * The ftrace dynamic update daemon only wakes up once a second. - * There may be cases where an update needs to be done immediately - * for tests or internal kernel tracing to begin. This function - * wakes the daemon to do an update and will not return until the - * update is complete. */ int ftrace_force_update(void) { - unsigned long last_counter; - DECLARE_WAITQUEUE(wait, current); int ret = 0; if (unlikely(ftrace_disabled)) return -ENODEV; + mutex_lock(&ftrace_sysctl_lock); mutex_lock(&ftraced_lock); - last_counter = ftraced_iteration_counter; - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&ftraced_waiters, &wait); - if (unlikely(!ftraced_task)) { - ret = -ENODEV; - goto out; - } - - do { - mutex_unlock(&ftraced_lock); - wake_up_process(ftraced_task); - schedule(); - mutex_lock(&ftraced_lock); - if (signal_pending(current)) { - ret = -EINTR; - break; - } - set_current_state(TASK_INTERRUPTIBLE); - } while (last_counter == ftraced_iteration_counter); + /* + * If ftraced_trigger is not set, then there is nothing + * to update. + */ + if (ftraced_trigger && !ftrace_update_code()) + ret = -EBUSY; - out: mutex_unlock(&ftraced_lock); - remove_wait_queue(&ftraced_waiters, &wait); - set_current_state(TASK_RUNNING); + mutex_unlock(&ftrace_sysctl_lock); return ret; } @@ -1331,6 +1388,12 @@ static __init int ftrace_init_debugfs(void) if (!entry) pr_warning("Could not create debugfs " "'set_ftrace_notrace' entry\n"); + + entry = debugfs_create_file("ftraced_enabled", 0644, d_tracer, + NULL, &ftraced_fops); + if (!entry) + pr_warning("Could not create debugfs " + "'ftraced_enabled' entry\n"); return 0; } -- cgit v0.10.2 From e0773410247f1e5fc6f7c52a4c5f3c6c9873d527 Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 31 May 2008 14:24:02 +0530 Subject: ftrace: export kretprobe_trampoline for function tracer Follow suit from kprobe implementations on other archs and make kretprobe_trampoline non-static. Ftrace implmentation (more specifically, kernel/trace/trace.c) requires access to it (see-> http://kerneltrap.org/mailarchive/linux-kernel/2008/5/27/1955234). Signed-off-by: Abhishek Sagar Signed-off-by: Ingo Molnar diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 5593dd2..5ee39e1 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -274,7 +274,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, * for kretprobe handlers which should normally be interested in r0 only * anyway. */ -static void __attribute__((naked)) __kprobes kretprobe_trampoline(void) +void __naked __kprobes kretprobe_trampoline(void) { __asm__ __volatile__ ( "stmdb sp!, {r0 - r11} \n\t" diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h index c042194..b1a3787 100644 --- a/include/asm-arm/kprobes.h +++ b/include/asm-arm/kprobes.h @@ -59,6 +59,7 @@ struct kprobe_ctlblk { }; void arch_remove_kprobe(struct kprobe *); +void kretprobe_trampoline(void); int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr); int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); -- cgit v0.10.2 From 1a7e612fa5ea0311232bd5418a40ec7280557789 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 31 May 2008 16:18:11 +0100 Subject: [ARM] 5074/1: fix warning: missing terminating ' character Signed-off-by: Dmitry Baryshkov Acked-by: Richard Purdie Signed-off-by: Russell King diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h index 9cf0b1f..2d4e9cd 100644 --- a/include/asm-arm/arch-pxa/pxa27x-udc.h +++ b/include/asm-arm/arch-pxa/pxa27x-udc.h @@ -2,7 +2,7 @@ #define _ASM_ARCH_PXA27X_UDC_H #ifdef _ASM_ARCH_PXA25X_UDC_H -#error You can't include both PXA25x and PXA27x UDC support +#error You cannot include both PXA25x and PXA27x UDC support #endif #define UDCCR __REG(0x40600000) /* UDC Control Register */ -- cgit v0.10.2 From 720046de27ec2a96d4497dbca8ee98657efa059c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:13:36 +0100 Subject: [ARM] pxa: don't register lpd270 cpld_irq sysdev if !lpd270 Don't register the LPD270 cpld_irq system device when we're not running on a LPD270 machine - "cpld_irq" is also registered (separately) by Lubbock and Mainstone. Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index a20e4b1..6fd7b8b 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -134,9 +134,12 @@ static struct sys_device lpd270_irq_device = { static int __init lpd270_irq_device_init(void) { - int ret = sysdev_class_register(&lpd270_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&lpd270_irq_device); + int ret = -ENODEV; + if (machine_is_logicpd_pxa270()) { + ret = sysdev_class_register(&lpd270_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&lpd270_irq_device); + } return ret; } -- cgit v0.10.2 From 04ba0f656f7580d8a51a5b3441e088309141b67a Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:23:25 +0100 Subject: [ARM] pxa: avoid registering multiple pxa2xx_pcmcia devices cm_x270 and mainstone both register their PCMCIA devices using the same name, resulting in a warning message from the kernel. Avoid this by making the cm_x270 and mainstone PCMCIA initialisation conditional on the machine type we're running on. Signed-off-by: Russell King diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index e7ab060..4a6c020 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -147,6 +148,9 @@ static int __init cmx270_pcmcia_init(void) { int ret; + if (!machine_is_armcore()) + return -ENODEV; + cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); if (!cmx270_pcmcia_device) diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 145b85e..36a5996 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -153,6 +154,9 @@ static int __init mst_pcmcia_init(void) { int ret; + if (!machine_is_mainstone()) + return -ENODEV; + mst_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); if (!mst_pcmcia_device) return -ENOMEM; -- cgit v0.10.2 From 4e5e8de0dbdeb08df2b4c15fa2b0ba2216091793 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:28:11 +0100 Subject: [ARM] pxa: avoid kfreeing static data if platform device fails to register When a dynamically allocated platform device is 'put', the platform device's platform_data is kfree'd. This is bad if it's pointing at static data. Use the provided function to register platform data for these devices. This also means we can mark the pcmcia ops structures as __initdata. Signed-off-by: Russell King diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index 4a6c020..f123fce 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -131,7 +131,7 @@ static void cmx270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) } -static struct pcmcia_low_level cmx270_pcmcia_ops = { +static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = cmx270_pcmcia_hw_init, .hw_shutdown = cmx270_pcmcia_shutdown, @@ -156,10 +156,13 @@ static int __init cmx270_pcmcia_init(void) if (!cmx270_pcmcia_device) return -ENOMEM; - cmx270_pcmcia_device->dev.platform_data = &cmx270_pcmcia_ops; + ret = platform_device_add_data(cmx270_pcmcia_device, &cmx270_pcmcia_ops, + sizeof(cmx270_pcmcia_ops)); - printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n"); - ret = platform_device_add(cmx270_pcmcia_device); + if (ret == 0) { + printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n"); + ret = platform_device_add(cmx270_pcmcia_device); + } if (ret) platform_device_put(cmx270_pcmcia_device); diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 36a5996..92d1cc3 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -137,7 +137,7 @@ static void mst_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { } -static struct pcmcia_low_level mst_pcmcia_ops = { +static struct pcmcia_low_level mst_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = mst_pcmcia_hw_init, .hw_shutdown = mst_pcmcia_hw_shutdown, @@ -161,9 +161,10 @@ static int __init mst_pcmcia_init(void) if (!mst_pcmcia_device) return -ENOMEM; - mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; - - ret = platform_device_add(mst_pcmcia_device); + ret = platform_device_add_data(mst_pcmcia_device, &mst_pcmcia_ops, + sizeof(mst_pcmcia_ops)); + if (ret == 0) + ret = platform_device_add(mst_pcmcia_device); if (ret) platform_device_put(mst_pcmcia_device); diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index d5c33bd..d71f93d 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -222,7 +222,7 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) sharpsl_pcmcia_init_reset(skt); } -static struct pcmcia_low_level sharpsl_pcmcia_ops = { +static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = sharpsl_pcmcia_hw_init, .hw_shutdown = sharpsl_pcmcia_hw_shutdown, @@ -261,10 +261,12 @@ static int __init sharpsl_pcmcia_init(void) if (!sharpsl_pcmcia_device) return -ENOMEM; - sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; - sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; - - ret = platform_device_add(sharpsl_pcmcia_device); + ret = platform_device_add_data(sharpsl_pcmcia_device, + &sharpsl_pcmcia_ops, sizeof(sharpsl_pcmcia_ops)); + if (ret == 0) { + sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; + ret = platform_device_add(sharpsl_pcmcia_device); + } if (ret) platform_device_put(sharpsl_pcmcia_device); -- cgit v0.10.2 From ffdf786291636137ef2d51c3a5d340793032aa28 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 May 2008 14:57:59 +0100 Subject: [ARM] pxa: Add PXA3_ prefix to PXA3 specific constants standby.S contains both PXA2 and PXA3 specific code. The PXA3 specific constants clash with the PXA2 ones, so give them a prefix. Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index 167412e..a37ef1c 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -35,20 +35,20 @@ ENTRY(pxa_cpu_standby) #ifdef CONFIG_PXA3xx -#define MDCNFG 0x0000 -#define MDCNFG_DMCEN (1 << 30) -#define DDR_HCAL 0x0060 -#define DDR_HCAL_HCRNG 0x1f -#define DDR_HCAL_HCPROG (1 << 28) -#define DDR_HCAL_HCEN (1 << 31) -#define DMCIER 0x0070 -#define DMCIER_EDLP (1 << 29) -#define DMCISR 0x0078 -#define RCOMP 0x0100 -#define RCOMP_SWEVAL (1 << 31) +#define PXA3_MDCNFG 0x0000 +#define PXA3_MDCNFG_DMCEN (1 << 30) +#define PXA3_DDR_HCAL 0x0060 +#define PXA3_DDR_HCAL_HCRNG 0x1f +#define PXA3_DDR_HCAL_HCPROG (1 << 28) +#define PXA3_DDR_HCAL_HCEN (1 << 31) +#define PXA3_DMCIER 0x0070 +#define PXA3_DMCIER_EDLP (1 << 29) +#define PXA3_DMCISR 0x0078 +#define PXA3_RCOMP 0x0100 +#define PXA3_RCOMP_SWEVAL (1 << 31) ENTRY(pm_enter_standby_start) - mov r1, #0xf6000000 @ DMEMC_REG_BASE (MDCNFG) + mov r1, #0xf6000000 @ DMEMC_REG_BASE (PXA3_MDCNFG) add r1, r1, #0x00100000 /* @@ -59,54 +59,54 @@ ENTRY(pm_enter_standby_start) * This also means that only the dynamic memory controller * can be reliably accessed in the code following standby. */ - ldr r2, [r1] @ Dummy read MDCNFG + ldr r2, [r1] @ Dummy read PXA3_MDCNFG mcr p14, 0, r0, c7, c0, 0 .rept 8 nop .endr - ldr r0, [r1, #DDR_HCAL] @ Clear (and wait for) HCEN - bic r0, r0, #DDR_HCAL_HCEN - str r0, [r1, #DDR_HCAL] -1: ldr r0, [r1, #DDR_HCAL] - tst r0, #DDR_HCAL_HCEN + ldr r0, [r1, #PXA3_DDR_HCAL] @ Clear (and wait for) HCEN + bic r0, r0, #PXA3_DDR_HCAL_HCEN + str r0, [r1, #PXA3_DDR_HCAL] +1: ldr r0, [r1, #PXA3_DDR_HCAL] + tst r0, #PXA3_DDR_HCAL_HCEN bne 1b - ldr r0, [r1, #RCOMP] @ Initiate RCOMP - orr r0, r0, #RCOMP_SWEVAL - str r0, [r1, #RCOMP] + ldr r0, [r1, #PXA3_RCOMP] @ Initiate RCOMP + orr r0, r0, #PXA3_RCOMP_SWEVAL + str r0, [r1, #PXA3_RCOMP] - mov r0, #~0 @ Clear interrupts - str r0, [r1, #DMCISR] + mov r0, #~0 @ Clear interrupts + str r0, [r1, #PXA3_DMCISR] - ldr r0, [r1, #DMCIER] @ set DMIER[EDLP] - orr r0, r0, #DMCIER_EDLP - str r0, [r1, #DMCIER] + ldr r0, [r1, #PXA3_DMCIER] @ set DMIER[EDLP] + orr r0, r0, #PXA3_DMCIER_EDLP + str r0, [r1, #PXA3_DMCIER] - ldr r0, [r1, #DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN - bic r0, r0, #DDR_HCAL_HCRNG - orr r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG - str r0, [r1, #DDR_HCAL] + ldr r0, [r1, #PXA3_DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN + bic r0, r0, #PXA3_DDR_HCAL_HCRNG + orr r0, r0, #PXA3_DDR_HCAL_HCEN | PXA3_DDR_HCAL_HCPROG + str r0, [r1, #PXA3_DDR_HCAL] -1: ldr r0, [r1, #DMCISR] - tst r0, #DMCIER_EDLP +1: ldr r0, [r1, #PXA3_DMCISR] + tst r0, #PXA3_DMCIER_EDLP beq 1b - ldr r0, [r1, #MDCNFG] @ set MDCNFG[DMCEN] - orr r0, r0, #MDCNFG_DMCEN - str r0, [r1, #MDCNFG] -1: ldr r0, [r1, #MDCNFG] - tst r0, #MDCNFG_DMCEN + ldr r0, [r1, #PXA3_MDCNFG] @ set PXA3_MDCNFG[DMCEN] + orr r0, r0, #PXA3_MDCNFG_DMCEN + str r0, [r1, #PXA3_MDCNFG] +1: ldr r0, [r1, #PXA3_MDCNFG] + tst r0, #PXA3_MDCNFG_DMCEN beq 1b - ldr r0, [r1, #DDR_HCAL] @ set DDR_HCAL[HCRNG] + ldr r0, [r1, #PXA3_DDR_HCAL] @ set PXA3_DDR_HCAL[HCRNG] orr r0, r0, #2 @ HCRNG - str r0, [r1, #DDR_HCAL] + str r0, [r1, #PXA3_DDR_HCAL] - ldr r0, [r1, #DMCIER] @ Clear the interrupt + ldr r0, [r1, #PXA3_DMCIER] @ Clear the interrupt bic r0, r0, #0x20000000 - str r0, [r1, #DMCIER] + str r0, [r1, #PXA3_DMCIER] mov pc, lr ENTRY(pm_enter_standby_end) -- cgit v0.10.2 From e3ba22db09408baee721897fb1b50e16f071d916 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Sat, 24 May 2008 17:06:45 +0100 Subject: [ARM] 5056/1: [AT91] Cleanup YL9200 board file Cleanup the YL9200 board-support file. Other things fixed are: - Use new-style UART initialization - Register all LEDs as gpio_leds. - NOR Flash error noted in comments fixed by increasing YL9200_FLASH_SIZE - The only I2C device is the AT24C eeprom. - Setup of NWAIT pin and programming of SMC controller for the LCD/VGA. - Configure touchscreen interrupt pin. Also adding the board to the KConfig and Makefile. Signed-off-by: Andrew Victor Signed-off-by: Russell King diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 0fc07b6..3d549a9 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -126,6 +126,12 @@ config MACH_ECBAT91 Select this if you are using emQbit's ECB_AT91 board. +config MACH_YL9200 + bool "ucDragon YL-9200" + depends on ARCH_AT91RM9200 + help + Select this if you are using the ucDragon YL-9200 board. + endif # ---------------------------------------------------------- diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 8d9bc01..995be14 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o +obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o # AT91SAM9260 board-specific support obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index b571710..7079050 100755 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -1,11 +1,10 @@ /* * linux/arch/arm/mach-at91/board-yl-9200.c * - * Adapted from: - *various board files in - * /arch/arm/mach-at91 - * modifications to convert to YL-9200 platform - * Copyright (C) 2007 S.Birtles + * Adapted from various board files in arch/arm/mach-at91 + * + * Modifications for YL-9200 platform: + * Copyright (C) 2007 S. Birtles * * 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 @@ -26,13 +25,14 @@ #include #include #include +#include #include #include -/*#include */ #include #include +#include +#include -/*#include */ #include #include #include @@ -45,179 +45,108 @@ #include #include #include -#include -#include #include "generic.h" -#include -#define YL_9200_FLASH_BASE AT91_CHIPSELECT_0 -#define YL_9200_FLASH_SIZE 0x800000 -/* - * Serial port configuration. - * 0 .. 3 = USART0 .. USART3 - * 4 = DBGU - *atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL - *atmel_usart.1: ttyS1 at MMIO 0xfffc0000 (irq = 6) is a ATMEL_SERIAL - *atmel_usart.2: ttyS2 at MMIO 0xfffc4000 (irq = 7) is a ATMEL_SERIAL - *atmel_usart.3: ttyS3 at MMIO 0xfffc8000 (irq = 8) is a ATMEL_SERIAL - *atmel_usart.4: ttyS4 at MMIO 0xfffcc000 (irq = 9) is a ATMEL_SERIAL - * on the YL-9200 we are sitting at the following - *ttyS0 at MMIO 0xfefff200 (irq = 1) is a AT91_SERIAL - *ttyS1 at MMIO 0xfefc4000 (irq = 7) is a AT91_SERIAL - */ +static void __init yl9200_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_PQFP); -/* extern void __init yl_9200_add_device_sounder(struct gpio_sounder *sounders, int nr);*/ + /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */ + at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17); -static struct at91_uart_config __initdata yl_9200_uart_config = { - .console_tty = 0, /* ttyS0 */ - .nr_tty = 3, - .tty_map = { 4, 1, 0, -1, -1 } /* ttyS0, ..., ttyS4 */ -}; + /* DBGU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); -static void __init yl_9200_map_io(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - /*Also initialises register clocks & gpio*/ - at91rm9200_initialize(18432000, AT91RM9200_PQFP); /*we have a 3 bank system*/ + /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); - /* Setup the serial ports and console */ - at91_init_serial(&yl_9200_uart_config); + /* USART0 on ttyS2. (Rx & Tx only to JP3) */ + at91_register_uart(AT91RM9200_ID_US0, 2, 0); - /* Setup the LEDs D2=PB17,D3=PB16 */ - at91_init_leds(AT91_PIN_PB16,AT91_PIN_PB17); /*cpu-led,timer-led*/ + /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */ + at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); } -static void __init yl_9200_init_irq(void) +static void __init yl9200_init_irq(void) { at91rm9200_init_interrupts(NULL); } -static struct at91_eth_data __initdata yl_9200_eth_data = { - .phy_irq_pin = AT91_PIN_PB28, - .is_rmii = 1, -}; -static struct at91_usbh_data __initdata yl_9200_usbh_data = { - .ports = 1, /* this should be 1 not 2 for the Yl9200*/ +/* + * LEDs + */ +static struct gpio_led yl9200_leds[] = { + { /* D2 */ + .name = "led2", + .gpio = AT91_PIN_PB17, + .active_low = 1, + .default_trigger = "timer", + }, + { /* D3 */ + .name = "led3", + .gpio = AT91_PIN_PB16, + .active_low = 1, + .default_trigger = "heartbeat", + }, + { /* D4 */ + .name = "led4", + .gpio = AT91_PIN_PB15, + .active_low = 1, + }, + { /* D5 */ + .name = "led5", + .gpio = AT91_PIN_PB8, + .active_low = 1, + } }; -static struct at91_udc_data __initdata yl_9200_udc_data = { -/*on sheet 7 Schemitic rev 1.0*/ - .pullup_pin = AT91_PIN_PC4, - .vbus_pin= AT91_PIN_PC5, - .pullup_active_low = 1, /*ACTIVE LOW!! due to PNP transistor on page 7*/ - -}; /* -static struct at91_cf_data __initdata yl_9200_cf_data = { -TODO S.BIRTLES - .det_pin = AT91_PIN_xxx, - .rst_pin = AT91_PIN_xxx, - .irq_pin = ... not connected - .vcc_pin = ... always powered - + * Ethernet + */ +static struct at91_eth_data __initdata yl9200_eth_data = { + .phy_irq_pin = AT91_PIN_PB28, + .is_rmii = 1, }; -*/ -static struct at91_mmc_data __initdata yl_9200_mmc_data = { - .det_pin = AT91_PIN_PB9, /*THIS LOOKS CORRECT SHEET7*/ -/* .wp_pin = ... not connected SHEET7*/ - .slot_b = 0, - .wire4 = 1, +/* + * USB Host + */ +static struct at91_usbh_data __initdata yl9200_usbh_data = { + .ports = 1, /* PQFP version of AT91RM9200 */ }; -/* -------------------------------------------------------------------- - * Touch screen - * -------------------------------------------------------------------- */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */ -} - -static void __init at91_init_device_ts(void) -{ -/*IMPORTANT NOTE THE SPI INTERFACE IS ALREADY CONFIGURED BY XXX_DEVICES.C -THAT IS TO SAY THAT MISO,MOSI,SPCK AND CS are already configured -we only need to enable the other datapins which are: -PB10/RK1 BUSY -*/ -/* Touchscreen BUSY signal , pin,use pullup ( TODO not currently used in the ADS7843/6.c driver)*/ -at91_set_gpio_input(AT91_PIN_PB10, 1); -} - -#else -static void __init at91_init_device_ts(void) {} -#endif - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, -/* for a 8" touch screen*/ - //.x_plate_ohms = 603, //= 450, S.Birtles TODO - //.y_plate_ohms = 332, //= 250, S.Birtles TODO -/*for a 10.4" touch screen*/ - //.x_plate_ohms =611, - //.y_plate_ohms =325, - - .x_plate_ohms = 576, - .y_plate_ohms = 366, - // - .pressure_max = 15000, /*generally nonsense on the 7843*/ - /*number of times to send query to chip in a given run 0 equals one time (do not set to 0!! ,there is a bug in ADS 7846 code)*/ - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; +/* + * USB Device + */ +static struct at91_udc_data __initdata yl9200_udc_data = { + .pullup_pin = AT91_PIN_PC4, + .vbus_pin = AT91_PIN_PC5, + .pullup_active_low = 1, /* Active Low due to PNP transistor (pg 7) */ -/*static struct canbus_platform_data can_info = { - .model = 2510, }; -*/ - -static struct spi_board_info yl_9200_spi_devices[] = { -/*this sticks it at: - /sys/devices/platform/atmel_spi.0/spi0.0 - /sys/bus/platform/devices/ -Documentation/spi IIRC*/ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - /*(this IS correct 04-NOV-2007)*/ - { - .modalias = "ads7846", /* because the driver is called ads7846*/ - .chip_select = 0, /*THIS MUST BE AN INDEX INTO AN ARRAY OF pins */ -/*this is ONLY TO BE USED if chipselect above is not used, it passes a pin directly for the chip select*/ - /*.controller_data =AT91_PIN_PA3 ,*/ - .max_speed_hz = 5000*26, /*(4700 * 26)-125000 * 26, (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = AT91_PIN_PB11, - }, -#endif -/*we need to put our CAN driver data here!!*/ -/*THIS IS ALL DUMMY DATA*/ -/* { - .modalias = "mcp2510", //DUMMY for MCP2510 chip - .chip_select = 1,*/ /*THIS MUST BE AN INDEX INTO AN ARRAY OF pins */ - /*this is ONLY TO BE USED if chipselect above is not used, it passes a pin directly for the chip select */ - /* .controller_data =AT91_PIN_PA4 , - .max_speed_hz = 25000 * 26, - .bus_num = 0, - .platform_data = &can_info, - .irq = AT91_PIN_PC0, - }, - */ - //max SPI chip needs to go here +/* + * MMC + */ +static struct at91_mmc_data __initdata yl9200_mmc_data = { + .det_pin = AT91_PIN_PB9, + // .wp_pin = ... not connected + .wire4 = 1, }; -static struct mtd_partition __initdata yl_9200_nand_partition[] = { +/* + * NAND Flash + */ +static struct mtd_partition __initdata yl9200_nand_partition[] = { { .name = "AT91 NAND partition 1, boot", .offset = 0, @@ -242,442 +171,434 @@ static struct mtd_partition __initdata yl_9200_nand_partition[] = { .name = "AT91 NAND partition 5, ext-fs", .offset = 32 * SZ_1M, .size = 32 * SZ_1M - }, + } }; static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) { - *num_partitions = ARRAY_SIZE(yl_9200_nand_partition); - return yl_9200_nand_partition; + *num_partitions = ARRAY_SIZE(yl9200_nand_partition); + return yl9200_nand_partition; } -static struct at91_nand_data __initdata yl_9200_nand_data = { - .ale= 6, - .cle= 7, - /*.det_pin = AT91_PIN_PCxx,*/ /*we don't have a det pin because NandFlash is fixed to board*/ - .rdy_pin = AT91_PIN_PC14, /*R/!B Sheet10*/ - .enable_pin = AT91_PIN_PC15, /*!CE Sheet10 */ +static struct at91_nand_data __initdata yl9200_nand_data = { + .ale = 6, + .cle = 7, + // .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ + .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ .partition_info = nand_partitions, }; - - /* -TODO S.Birtles -potentially a problem with the size above -physmap platform flash device: 00800000 at 10000000 -physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank -NOR chip too large to fit in mapping. Attempting to cope... - Intel/Sharp Extended Query Table at 0x0031 -Using buffer write method -cfi_cmdset_0001: Erase suspend on write enabled -Reducing visibility of 16384KiB chip to 8192KiB -*/ + * NOR Flash + */ +#define YL9200_FLASH_BASE AT91_CHIPSELECT_0 +#define YL9200_FLASH_SIZE 0x1000000 -static struct mtd_partition yl_9200_flash_partitions[] = { +static struct mtd_partition yl9200_flash_partitions[] = { + { + .name = "Bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { - .name = "Bootloader", - .size = 0x00040000, - .offset = 0, - .mask_flags = MTD_WRITEABLE /* force read-only */ - },{ - .name = "Kernel", - .size = 0x001C0000, - .offset = 0x00040000, - },{ - .name = "Filesystem", - .size = MTDPART_SIZ_FULL, - .offset = 0x00200000 + .name = "Kernel", + .size = 0x001C0000, + .offset = 0x00040000, + }, + { + .name = "Filesystem", + .size = MTDPART_SIZ_FULL, + .offset = 0x00200000 } - }; -static struct physmap_flash_data yl_9200_flash_data = { - .width = 2, - .parts = yl_9200_flash_partitions, - .nr_parts = ARRAY_SIZE(yl_9200_flash_partitions), +static struct physmap_flash_data yl9200_flash_data = { + .width = 2, + .parts = yl9200_flash_partitions, + .nr_parts = ARRAY_SIZE(yl9200_flash_partitions), }; -static struct resource yl_9200_flash_resources[] = { -{ - .start = YL_9200_FLASH_BASE, - .end = YL_9200_FLASH_BASE + YL_9200_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, +static struct resource yl9200_flash_resources[] = { + { + .start = YL9200_FLASH_BASE, + .end = YL9200_FLASH_BASE + YL9200_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, } }; -static struct platform_device yl_9200_flash = { +static struct platform_device yl9200_flash = { .name = "physmap-flash", .id = 0, .dev = { - .platform_data = &yl_9200_flash_data, + .platform_data = &yl9200_flash_data, }, - .resource = yl_9200_flash_resources, - .num_resources = ARRAY_SIZE(yl_9200_flash_resources), + .resource = yl9200_flash_resources, + .num_resources = ARRAY_SIZE(yl9200_flash_resources), }; - -static struct gpio_led yl_9200_leds[] = { -/*D2 &D3 are passed directly in via at91_init_leds*/ - { - .name = "led4", /*D4*/ - .gpio = AT91_PIN_PB15, - .active_low = 1, - .default_trigger = "heartbeat", - /*.default_trigger = "timer",*/ - }, - { - .name = "led5", /*D5*/ - .gpio = AT91_PIN_PB8, - .active_low = 1, - .default_trigger = "heartbeat", - } -}; - -//static struct gpio_sounder yl_9200_sounder[] = {*/ -/*This is a simple speaker attached to a gpo line*/ - -// { -// .name = "Speaker", /*LS1*/ -// .gpio = AT91_PIN_PA22, -// .active_low = 0, -// .default_trigger = "heartbeat", - /*.default_trigger = "timer",*/ -// }, -//}; - - - -static struct i2c_board_info __initdata yl_9200_i2c_devices[] = { - { - /*TODO*/ - I2C_BOARD_INFO("CS4334", 0x00), +/* + * I2C (TWI) + */ +static struct i2c_board_info __initdata yl9200_i2c_devices[] = { + { /* EEPROM */ + I2C_BOARD_INFO("24c128", 0x50), } }; - - /* +/* * GPIO Buttons - */ +*/ #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button yl_9200_buttons[] = { +static struct gpio_keys_button yl9200_buttons[] = { { .gpio = AT91_PIN_PA24, - .code = BTN_2, + .code = BTN_2, .desc = "SW2", .active_low = 1, .wakeup = 1, }, { .gpio = AT91_PIN_PB1, - .code = BTN_3, + .code = BTN_3, .desc = "SW3", .active_low = 1, .wakeup = 1, }, { .gpio = AT91_PIN_PB2, - .code = BTN_4, + .code = BTN_4, .desc = "SW4", .active_low = 1, .wakeup = 1, }, { .gpio = AT91_PIN_PB6, - .code = BTN_5, + .code = BTN_5, .desc = "SW5", .active_low = 1, .wakeup = 1, - }, - + } }; -static struct gpio_keys_platform_data yl_9200_button_data = { - .buttons = yl_9200_buttons, - .nbuttons = ARRAY_SIZE(yl_9200_buttons), +static struct gpio_keys_platform_data yl9200_button_data = { + .buttons = yl9200_buttons, + .nbuttons = ARRAY_SIZE(yl9200_buttons), }; -static struct platform_device yl_9200_button_device = { +static struct platform_device yl9200_button_device = { .name = "gpio-keys", .id = -1, .num_resources = 0, .dev = { - .platform_data = &yl_9200_button_data, + .platform_data = &yl9200_button_data, } }; -static void __init yl_9200_add_device_buttons(void) +static void __init yl9200_add_device_buttons(void) { - //SW2 - at91_set_gpio_input(AT91_PIN_PA24, 0); + at91_set_gpio_input(AT91_PIN_PA24, 1); /* SW2 */ at91_set_deglitch(AT91_PIN_PA24, 1); - - //SW3 - at91_set_gpio_input(AT91_PIN_PB1, 0); + at91_set_gpio_input(AT91_PIN_PB1, 1); /* SW3 */ at91_set_deglitch(AT91_PIN_PB1, 1); - //SW4 - at91_set_gpio_input(AT91_PIN_PB2, 0); + at91_set_gpio_input(AT91_PIN_PB2, 1); /* SW4 */ at91_set_deglitch(AT91_PIN_PB2, 1); - - //SW5 - at91_set_gpio_input(AT91_PIN_PB6, 0); + at91_set_gpio_input(AT91_PIN_PB6, 1); /* SW5 */ at91_set_deglitch(AT91_PIN_PB6, 1); + /* Enable buttons (Sheet 5) */ + at91_set_gpio_output(AT91_PIN_PB7, 1); + + platform_device_register(&yl9200_button_device); +} +#else +static void __init yl9200_add_device_buttons(void) {} +#endif + +/* + * Touchscreen + */ +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 150, + .x_max = 3830, + .y_min = 190, + .y_max = 3830, + .vref_delay_usecs = 100, + + /* For a 8" touch-screen */ + // .x_plate_ohms = 603, + // .y_plate_ohms = 332, + + /* For a 10.4" touch-screen */ + // .x_plate_ohms = 611, + // .y_plate_ohms = 325, + + .x_plate_ohms = 576, + .y_plate_ohms = 366, + + .pressure_max = 15000, /* generally nonsense on the 7843 */ + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7843_pendown_state, +}; - at91_set_gpio_output(AT91_PIN_PB7, 1); /* #TURN BUTTONS ON, SHEET 5 of schematics */ - platform_device_register(&yl_9200_button_device); +static void __init yl9200_add_device_ts(void) +{ + at91_set_gpio_input(AT91_PIN_PB11, 1); /* Touchscreen interrupt pin */ + at91_set_gpio_input(AT91_PIN_PB10, 1); /* Touchscreen BUSY signal - not used! */ } #else -static void __init yl_9200_add_device_buttons(void) {} +static void __init yl9200_add_device_ts(void) {} +#endif + +/* + * SPI devices + */ +static struct spi_board_info yl9200_spi_devices[] = { +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { /* Touchscreen */ + .modalias = "ads7846", + .chip_select = 0, + .max_speed_hz = 5000 * 26, + .platform_data = &ads_info, + .irq = AT91_PIN_PB11, + }, #endif + { /* CAN */ + .modalias = "mcp2510", + .chip_select = 1, + .max_speed_hz = 25000 * 26, + .irq = AT91_PIN_PC0, + } +}; +/* + * LCD / VGA + * + * EPSON S1D13806 FB (discontinued chip) + * EPSON S1D13506 FB + */ #if defined(CONFIG_FB_S1D135XX) || defined(CONFIG_FB_S1D13XXX_MODULE) #include
with the' + @echo ' name of a dts file from the arch/$(ARCH)/boot/dts/ directory' + @echo ' (minus the .dts extension).' endef install: -- cgit v0.10.2 From 1d46e379aae7349069f459618f53fd5193c2fd29 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 4 Jul 2008 00:59:37 -0600 Subject: powerpc/bootwrapper: add missing bit of simpleImage target The wrapper script is missing the bits needed for building generic simpleImage targets (targets which don't depend on any particular firmware interface and retrieve all their data from the device tree). Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 592a6ea..644bf9d 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -214,6 +214,10 @@ simpleboot-virtex440-*) platformo="$object/simpleboot.o $object/virtex.o" binary=y ;; +simpleboot-*) + platformo="$object/simpleboot.o" + binary=y + ;; asp834x-redboot) platformo="$object/fixed-head.o $object/redboot-83xx.o" binary=y -- cgit v0.10.2 From 823ed72e8fe566983b121e8cc3147dd50ce63a8a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 09:28:32 +0200 Subject: block: use get_unaligned_* helpers Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 41f818b..2f17462 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -1003,7 +1003,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) * Enough people have their dip switches set backwards to * warrant a loud message for this special case. */ - aoemajor = be16_to_cpu(get_unaligned(&h->major)); + aoemajor = get_unaligned_be16(&h->major); if (aoemajor == 0xfff) { printk(KERN_ERR "aoe: Warning: shelf address is all ones. " "Check shelf dip switches.\n"); -- cgit v0.10.2 From 72f6befeea7dc634a83219287d5b874734b85637 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Fri, 4 Jul 2008 09:33:03 +0200 Subject: avr32: Fix typo of IFSR in a comment in the PIO header file Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h index 7795116..9484dfc 100644 --- a/arch/avr32/mach-at32ap/pio.h +++ b/arch/avr32/mach-at32ap/pio.h @@ -57,7 +57,7 @@ /* Bitfields in IFDR */ -/* Bitfields in ISFR */ +/* Bitfields in IFSR */ /* Bitfields in SODR */ -- cgit v0.10.2 From be1fd70fea1100c57f3aa1934ebb93abc474e50c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jul 2008 09:51:21 +0200 Subject: paride: push ioctl down into driver Leaves us with lock_kernel for two methods. Also remove a bogus printk with no printk level and return -ENOTTY not -EINVAL for correctness. Signed-off-by: Alan Cox Signed-off-by: Andrew Morton (Jens: added smp_lock.h include to pt.c, otherwise it wont compile because of missing {un}lock_kernel() definition) Signed-off-by: Jens Axboe diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 8b9549a..27455ee 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; #include #include #include /* current, TASK_*, schedule_timeout() */ +#include #include @@ -189,8 +190,7 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_LOG_SENSE 0x4d static int pt_open(struct inode *inode, struct file *file); -static int pt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int pt_release(struct inode *inode, struct file *file); static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos); @@ -236,7 +236,7 @@ static const struct file_operations pt_fops = { .owner = THIS_MODULE, .read = pt_read, .write = pt_write, - .ioctl = pt_ioctl, + .unlocked_ioctl = pt_ioctl, .open = pt_open, .release = pt_release, }; @@ -685,8 +685,7 @@ out: return err; } -static int pt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct pt_unit *tape = file->private_data; struct mtop __user *p = (void __user *)arg; @@ -700,23 +699,26 @@ static int pt_ioctl(struct inode *inode, struct file *file, switch (mtop.mt_op) { case MTREW: + lock_kernel(); pt_rewind(tape); + unlock_kernel(); return 0; case MTWEOF: + lock_kernel(); pt_write_fm(tape); + unlock_kernel(); return 0; default: - printk("%s: Unimplemented mt_op %d\n", tape->name, + /* FIXME: rate limit ?? */ + printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name, mtop.mt_op); return -EINVAL; } default: - printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd); - return -EINVAL; - + return -ENOTTY; } } -- cgit v0.10.2 From 5b6155ee70e9c4d2ad7e6f514c8eee06e2711c3a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jul 2008 09:29:16 +0200 Subject: pktcdvd: push BKL down into driver Push the lock_kernel down into the driver and switch to unlocked_ioctl [akpm@linux-foundation.org: build fix] Signed-off-by: Alan Cox Acked-by: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 589850c..85e44d0 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -2797,9 +2798,14 @@ out_mem: return ret; } -static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; + struct inode *inode = file->f_path.dentry->d_inode; + struct pktcdvd_device *pd; + long ret; + + lock_kernel(); + pd = inode->i_bdev->bd_disk->private_data; VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); @@ -2812,7 +2818,8 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u case CDROM_LAST_WRITTEN: case CDROM_SEND_PACKET: case SCSI_IOCTL_SEND_COMMAND: - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + break; case CDROMEJECT: /* @@ -2821,14 +2828,15 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u */ if (pd->refcnt == 1) pkt_lock_door(pd, 0); - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + break; default: VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); - return -ENOTTY; + ret = -ENOTTY; } - - return 0; + unlock_kernel(); + return ret; } static int pkt_media_changed(struct gendisk *disk) @@ -2850,7 +2858,7 @@ static struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .ioctl = pkt_ioctl, + .unlocked_ioctl = pkt_ioctl, .media_changed = pkt_media_changed, }; @@ -3015,7 +3023,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) mutex_unlock(&ctl_mutex); } -static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; struct pkt_ctrl_command ctrl_cmd; @@ -3032,16 +3041,22 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm case PKT_CTRL_CMD_SETUP: if (!capable(CAP_SYS_ADMIN)) return -EPERM; + lock_kernel(); ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev); ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev); + unlock_kernel(); break; case PKT_CTRL_CMD_TEARDOWN: if (!capable(CAP_SYS_ADMIN)) return -EPERM; + lock_kernel(); ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev)); + unlock_kernel(); break; case PKT_CTRL_CMD_STATUS: + lock_kernel(); pkt_get_status(&ctrl_cmd); + unlock_kernel(); break; default: return -ENOTTY; @@ -3054,7 +3069,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm static const struct file_operations pkt_ctl_fops = { - .ioctl = pkt_ctl_ioctl, + .unlocked_ioctl = pkt_ctl_ioctl, .owner = THIS_MODULE, }; -- cgit v0.10.2 From 2610324fcacf38a24b630090ebcb802538763187 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 4 Jul 2008 09:29:31 +0200 Subject: DAC960: push down BKL Signed-off-by: Alan Cox Cc: Richard Knutsson Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index cd03473..a002a38 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -6628,15 +6628,18 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller) * DAC960_gam_ioctl is the ioctl function for performing RAID operations. */ -static int DAC960_gam_ioctl(struct inode *inode, struct file *file, - unsigned int Request, unsigned long Argument) +static long DAC960_gam_ioctl(struct file *file, unsigned int Request, + unsigned long Argument) { - int ErrorCode = 0; + long ErrorCode = 0; if (!capable(CAP_SYS_ADMIN)) return -EACCES; + + lock_kernel(); switch (Request) { case DAC960_IOCTL_GET_CONTROLLER_COUNT: - return DAC960_ControllerCount; + ErrorCode = DAC960_ControllerCount; + break; case DAC960_IOCTL_GET_CONTROLLER_INFO: { DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = @@ -6644,15 +6647,20 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, DAC960_ControllerInfo_T ControllerInfo; DAC960_Controller_T *Controller; int ControllerNumber; - if (UserSpaceControllerInfo == NULL) return -EINVAL; - ErrorCode = get_user(ControllerNumber, + if (UserSpaceControllerInfo == NULL) + ErrorCode = -EINVAL; + else ErrorCode = get_user(ControllerNumber, &UserSpaceControllerInfo->ControllerNumber); - if (ErrorCode != 0) return ErrorCode; + if (ErrorCode != 0) + break;; + ErrorCode = -ENXIO; if (ControllerNumber < 0 || - ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + ControllerNumber > DAC960_ControllerCount - 1) { + break; + } Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; + if (Controller == NULL) + break;; memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); ControllerInfo.ControllerNumber = ControllerNumber; ControllerInfo.FirmwareType = Controller->FirmwareType; @@ -6665,8 +6673,9 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, ControllerInfo.PCI_Address = Controller->PCI_Address; strcpy(ControllerInfo.ModelName, Controller->ModelName); strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); - return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, + ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); + break; } case DAC960_IOCTL_V1_EXECUTE_COMMAND: { @@ -6684,30 +6693,39 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, int ControllerNumber, DataTransferLength; unsigned char *DataTransferBuffer = NULL; dma_addr_t DataTransferBufferDMA; - if (UserSpaceUserCommand == NULL) return -EINVAL; + if (UserSpaceUserCommand == NULL) { + ErrorCode = -EINVAL; + break; + } if (copy_from_user(&UserCommand, UserSpaceUserCommand, sizeof(DAC960_V1_UserCommand_T))) { ErrorCode = -EFAULT; - goto Failure1a; + break; } ControllerNumber = UserCommand.ControllerNumber; + ErrorCode = -ENXIO; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + break; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; + if (Controller == NULL) + break; + ErrorCode = -EINVAL; + if (Controller->FirmwareType != DAC960_V1_Controller) + break; CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; DataTransferLength = UserCommand.DataTransferLength; - if (CommandOpcode & 0x80) return -EINVAL; + if (CommandOpcode & 0x80) + break; if (CommandOpcode == DAC960_V1_DCDB) { if (copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T))) { ErrorCode = -EFAULT; - goto Failure1a; + break; } - if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; + if (DCDB.Channel >= DAC960_V1_MaxChannels) + break; if (!((DataTransferLength == 0 && DCDB.Direction == DAC960_V1_DCDB_NoDataTransfer) || @@ -6717,38 +6735,37 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, (DataTransferLength < 0 && DCDB.Direction == DAC960_V1_DCDB_DataTransferSystemToDevice))) - return -EINVAL; + break; if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) != abs(DataTransferLength)) - return -EINVAL; + break; DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); - if (DCDB_IOBUF == NULL) - return -ENOMEM; + if (DCDB_IOBUF == NULL) { + ErrorCode = -ENOMEM; + break; + } } + ErrorCode = -ENOMEM; if (DataTransferLength > 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) { - ErrorCode = -ENOMEM; - goto Failure1; - } + if (DataTransferBuffer == NULL) + break; memset(DataTransferBuffer, 0, DataTransferLength); } else if (DataTransferLength < 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) { - ErrorCode = -ENOMEM; - goto Failure1; - } + if (DataTransferBuffer == NULL) + break; if (copy_from_user(DataTransferBuffer, UserCommand.DataTransferBuffer, -DataTransferLength)) { ErrorCode = -EFAULT; - goto Failure1; + break; } } if (CommandOpcode == DAC960_V1_DCDB) @@ -6825,8 +6842,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, if (DCDB_IOBUF != NULL) pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), DCDB_IOBUF, DCDB_IOBUFDMA); - Failure1a: - return ErrorCode; + break; } case DAC960_IOCTL_V2_EXECUTE_COMMAND: { @@ -6844,32 +6860,43 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, dma_addr_t DataTransferBufferDMA; unsigned char *RequestSenseBuffer = NULL; dma_addr_t RequestSenseBufferDMA; - if (UserSpaceUserCommand == NULL) return -EINVAL; + + ErrorCode = -EINVAL; + if (UserSpaceUserCommand == NULL) + break; if (copy_from_user(&UserCommand, UserSpaceUserCommand, sizeof(DAC960_V2_UserCommand_T))) { ErrorCode = -EFAULT; - goto Failure2a; + break; } + ErrorCode = -ENXIO; ControllerNumber = UserCommand.ControllerNumber; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + break; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; + if (Controller == NULL) + break; + if (Controller->FirmwareType != DAC960_V2_Controller){ + ErrorCode = -EINVAL; + break; + } DataTransferLength = UserCommand.DataTransferLength; + ErrorCode = -ENOMEM; if (DataTransferLength > 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) return -ENOMEM; + if (DataTransferBuffer == NULL) + break; memset(DataTransferBuffer, 0, DataTransferLength); } else if (DataTransferLength < 0) { DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, -DataTransferLength, &DataTransferBufferDMA); - if (DataTransferBuffer == NULL) return -ENOMEM; + if (DataTransferBuffer == NULL) + break; if (copy_from_user(DataTransferBuffer, UserCommand.DataTransferBuffer, -DataTransferLength)) { @@ -6979,8 +7006,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, if (RequestSenseBuffer != NULL) pci_free_consistent(Controller->PCIDevice, RequestSenseLength, RequestSenseBuffer, RequestSenseBufferDMA); - Failure2a: - return ErrorCode; + break; } case DAC960_IOCTL_V2_GET_HEALTH_STATUS: { @@ -6990,21 +7016,33 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; DAC960_Controller_T *Controller; int ControllerNumber; - if (UserSpaceGetHealthStatus == NULL) return -EINVAL; + if (UserSpaceGetHealthStatus == NULL) { + ErrorCode = -EINVAL; + break; + } if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, - sizeof(DAC960_V2_GetHealthStatus_T))) - return -EFAULT; + sizeof(DAC960_V2_GetHealthStatus_T))) { + ErrorCode = -EFAULT; + break; + } + ErrorCode = -ENXIO; ControllerNumber = GetHealthStatus.ControllerNumber; if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1) - return -ENXIO; + break; Controller = DAC960_Controllers[ControllerNumber]; - if (Controller == NULL) return -ENXIO; - if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; + if (Controller == NULL) + break; + if (Controller->FirmwareType != DAC960_V2_Controller) { + ErrorCode = -EINVAL; + break; + } if (copy_from_user(&HealthStatusBuffer, GetHealthStatus.HealthStatusBuffer, - sizeof(DAC960_V2_HealthStatusBuffer_T))) - return -EFAULT; + sizeof(DAC960_V2_HealthStatusBuffer_T))) { + ErrorCode = -EFAULT; + break; + } while (Controller->V2.HealthStatusBuffer->StatusChangeCounter == HealthStatusBuffer.StatusChangeCounter && Controller->V2.HealthStatusBuffer->NextEventSequenceNumber @@ -7012,21 +7050,28 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, { interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, DAC960_MonitoringTimerInterval); - if (signal_pending(current)) return -EINTR; + if (signal_pending(current)) { + ErrorCode = -EINTR; + break; + } } if (copy_to_user(GetHealthStatus.HealthStatusBuffer, Controller->V2.HealthStatusBuffer, sizeof(DAC960_V2_HealthStatusBuffer_T))) - return -EFAULT; - return 0; + ErrorCode = -EFAULT; + else + ErrorCode = 0; } + default: + ErrorCode = -ENOTTY; } - return -EINVAL; + unlock_kernel(); + return ErrorCode; } static const struct file_operations DAC960_gam_fops = { .owner = THIS_MODULE, - .ioctl = DAC960_gam_ioctl + .unlocked_ioctl = DAC960_gam_ioctl }; static struct miscdevice DAC960_gam_dev = { -- cgit v0.10.2 From 27f8221af406e43b529a5425bc99c9b1e9bdf521 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:30:03 +0200 Subject: block: add blk_queue_update_dma_pad This adds blk_queue_update_dma_pad to prevent LLDs from overwriting the dma pad mask wrongly (we added blk_queue_update_dma_alignment due to the same reason). This also converts libata to use blk_queue_update_dma_pad instead of blk_queue_dma_pad. Signed-off-by: FUJITA Tomonori Cc: Tejun Heo Cc: Bartlomiej Zolnierkiewicz Cc: Thomas Bogendoerfer Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/block/blk-settings.c b/block/blk-settings.c index 8dd8641..dfc7701 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -302,11 +302,10 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * @q: the request queue for the device * @mask: pad mask * - * Set pad mask. Direct IO requests are padded to the mask specified. + * Set dma pad mask. * - * Appending pad buffer to a request modifies ->data_len such that it - * includes the pad buffer. The original requested data length can be - * obtained using blk_rq_raw_data_len(). + * Appending pad buffer to a request modifies the last entry of a + * scatter list such that it includes the pad buffer. **/ void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) { @@ -315,6 +314,23 @@ void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) EXPORT_SYMBOL(blk_queue_dma_pad); /** + * blk_queue_update_dma_pad - update pad mask + * @q: the request queue for the device + * @mask: pad mask + * + * Update dma pad mask. + * + * Appending pad buffer to a request modifies the last entry of a + * scatter list such that it includes the pad buffer. + **/ +void blk_queue_update_dma_pad(struct request_queue *q, unsigned int mask) +{ + if (mask > q->dma_pad_mask) + q->dma_pad_mask = mask; +} +EXPORT_SYMBOL(blk_queue_update_dma_pad); + +/** * blk_queue_dma_drain - Set up a drain buffer for excess dma. * @q: the request queue for the device * @dma_drain_needed: fn which returns non-zero if drain is necessary diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 57a4364..499ccc6 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -885,7 +885,8 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, /* set the min alignment and padding */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); - blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); + blk_queue_update_dma_pad(sdev->request_queue, + ATA_DMA_PAD_SZ - 1); /* configure draining */ buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e04c4ac..1ffd8bf 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -776,6 +776,7 @@ extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); extern void blk_queue_dma_pad(struct request_queue *, unsigned int); +extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int); extern int blk_queue_dma_drain(struct request_queue *q, dma_drain_needed_fn *dma_drain_needed, void *buf, unsigned int size); -- cgit v0.10.2 From 30c00eda73d5db5bd64dd0c370161abd8df5ba4a Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:31:11 +0200 Subject: block: blk_rq_map_kern uses the bounce buffers for stack buffers blk_rq_map_kern is used for kernel internal I/Os. Some callers use this function with stack buffers but DMA to/from the stack buffers leads to memory corruption on a non-coherent platform. This patch make blk_rq_map_kern uses the bounce buffers if a caller passes a stack buffer (on the all platforms for simplicity). Signed-off-by: FUJITA Tomonori Cc: Bartlomiej Zolnierkiewicz Cc: Thomas Bogendoerfer Cc: Tejun Heo Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/block/blk-map.c b/block/blk-map.c index 813011e..ddd96fb 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -269,6 +269,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, int reading = rq_data_dir(rq) == READ; int do_copy = 0; struct bio *bio; + unsigned long stack_mask = ~(THREAD_SIZE - 1); if (len > (q->max_hw_sectors << 9)) return -EINVAL; @@ -279,6 +280,10 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, alignment = queue_dma_alignment(q) | q->dma_pad_mask; do_copy = ((kaddr & alignment) || (len & alignment)); + if (!((kaddr & stack_mask) ^ + ((unsigned long)current->stack & stack_mask))) + do_copy = 1; + if (do_copy) bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); else -- cgit v0.10.2 From 62858dacc8dea55c5bdb474ccd8acb0657e23dd0 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:31:50 +0200 Subject: scsi: sr avoids useless buffer allocation blk_rq_map_kern can handle the stack buffers correctly (avoid DMA from/to the stack buffers by using the bounce buffer) so we don't need to complicate the code by allocating just 8 bytes. Signed-off-by: FUJITA Tomonori Cc: James Bottomley Cc: Bartlomiej Zolnierkiewicz Cc: Thomas Bogendoerfer Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c82df8b..27f5bfd 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -673,24 +673,20 @@ fail: static void get_sectorsize(struct scsi_cd *cd) { unsigned char cmd[10]; - unsigned char *buffer; + unsigned char buffer[8]; int the_result, retries = 3; int sector_size; struct request_queue *queue; - buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); - if (!buffer) - goto Enomem; - do { cmd[0] = READ_CAPACITY; memset((void *) &cmd[1], 0, 9); - memset(buffer, 0, 8); + memset(buffer, 0, sizeof(buffer)); /* Do the command and wait.. */ the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, - buffer, 8, NULL, SR_TIMEOUT, - MAX_RETRIES); + buffer, sizeof(buffer), NULL, + SR_TIMEOUT, MAX_RETRIES); retries--; @@ -745,14 +741,8 @@ static void get_sectorsize(struct scsi_cd *cd) queue = cd->device->request_queue; blk_queue_hardsect_size(queue, sector_size); -out: - kfree(buffer); - return; -Enomem: - cd->capacity = 0x1fffff; - cd->device->sector_size = 2048; /* A guess, just in case */ - goto out; + return; } static void get_capabilities(struct scsi_cd *cd) -- cgit v0.10.2 From fce5384755e8e0e56c5609d2972db4702990d592 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 4 Jul 2008 09:33:01 +0200 Subject: cdrom: revert commit 22a9189 (cdrom: use kmalloced buffers instead of buffers on stack) The commit 22a9189fd073db3d03a4cf8b8c098aa207602de1 (cdrom: use kmalloced buffers instead of buffers on stack) is introduced to use kmalloced buffers for packet commands to avoid stack corruption on non coherent platforms. SCSI cdrom uses blk_rq_map_kern, which properly avoids DMA on the stack by using the bounce buffers. IDE cdrom also has the mechnism to avoids DMA on the stack. So we don't need this extra complexitiy in cdrom.c, such as allocating just 8 bytes. The lower layers can handle it. Signed-off-by: FUJITA Tomonori Cc: Thomas Bogendoerfer Cc: Bartlomiej Zolnierkiewicz Cc: Thomas Bogendoerfer Cc: Tejun Heo Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 69f26eb..a5da356 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -461,37 +461,27 @@ int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med) { struct packet_command cgc; - unsigned char *buffer; - struct event_header *eh; - int ret = 1; - - buffer = kmalloc(8, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + unsigned char buffer[8]; + struct event_header *eh = (struct event_header *) buffer; - eh = (struct event_header *)buffer; - - init_cdrom_command(&cgc, buffer, 8, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION; cgc.cmd[1] = 1; /* IMMED */ cgc.cmd[4] = 1 << 4; /* media event */ - cgc.cmd[8] = 8; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if (cdi->ops->generic_packet(cdi, &cgc)) - goto err; + return 1; if (be16_to_cpu(eh->data_len) < sizeof(*med)) - goto err; + return 1; if (eh->nea || eh->notification_class != 0x4) - goto err; + return 1; - memcpy(med, buffer + sizeof(*eh), sizeof(*med)); - ret = 0; -err: - kfree(buffer); - return ret; + memcpy(med, &buffer[sizeof(*eh)], sizeof(*med)); + return 0; } /* @@ -501,82 +491,68 @@ err: static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) { struct packet_command cgc; - char *buffer; - int ret = 1; - - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + char buffer[16]; - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.timeout = HZ; cgc.quiet = 1; if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) { cdi->mrw_mode_page = MRW_MODE_PC; - ret = 0; + return 0; } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) { cdi->mrw_mode_page = MRW_MODE_PC_PRE1; - ret = 0; + return 0; } - kfree(buffer); - return ret; + + return 1; } static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) { struct packet_command cgc; struct mrw_feature_desc *mfd; - unsigned char *buffer; + unsigned char buffer[16]; int ret; *write = 0; - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[3] = CDF_MRW; - cgc.cmd[8] = 16; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - goto err; + return ret; mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)]; - if (be16_to_cpu(mfd->feature_code) != CDF_MRW) { - ret = 1; - goto err; - } + if (be16_to_cpu(mfd->feature_code) != CDF_MRW) + return 1; *write = mfd->write; if ((ret = cdrom_mrw_probe_pc(cdi))) { *write = 0; + return ret; } -err: - kfree(buffer); - return ret; + + return 0; } static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) { struct packet_command cgc; - unsigned char *buffer; + unsigned char buffer[12]; int ret; printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : ""); - buffer = kmalloc(12, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - /* * FmtData bit set (bit 4), format type is 1 */ - init_cdrom_command(&cgc, buffer, 12, CGC_DATA_WRITE); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE); cgc.cmd[0] = GPCMD_FORMAT_UNIT; cgc.cmd[1] = (1 << 4) | 1; @@ -603,7 +579,6 @@ static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) if (ret) printk(KERN_INFO "cdrom: bgformat failed\n"); - kfree(buffer); return ret; } @@ -663,17 +638,16 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) { struct packet_command cgc; struct mode_page_header *mph; - char *buffer; + char buffer[16]; int ret, offset, size; - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + cgc.buffer = buffer; + cgc.buflen = sizeof(buffer); if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0))) - goto err; + return ret; mph = (struct mode_page_header *) buffer; offset = be16_to_cpu(mph->desc_length); @@ -683,70 +657,55 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) cgc.buflen = size; if ((ret = cdrom_mode_select(cdi, &cgc))) - goto err; + return ret; printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]); - ret = 0; -err: - kfree(buffer); - return ret; + return 0; } static int cdrom_get_random_writable(struct cdrom_device_info *cdi, struct rwrt_feature_desc *rfd) { struct packet_command cgc; - char *buffer; + char buffer[24]; int ret; - buffer = kmalloc(24, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - init_cdrom_command(&cgc, buffer, 24, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */ - cgc.cmd[8] = 24; /* often 0x18 */ + cgc.cmd[8] = sizeof(buffer); /* often 0x18 */ cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - goto err; + return ret; memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd)); - ret = 0; -err: - kfree(buffer); - return ret; + return 0; } static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) { struct packet_command cgc; - char *buffer; + char buffer[16]; __be16 *feature_code; int ret; - buffer = kmalloc(16, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[3] = CDF_HWDM; - cgc.cmd[8] = 16; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) - goto err; + return ret; feature_code = (__be16 *) &buffer[sizeof(struct feature_header)]; if (be16_to_cpu(*feature_code) == CDF_HWDM) - ret = 0; -err: - kfree(buffer); - return ret; + return 0; + + return 1; } @@ -837,14 +796,10 @@ static int cdrom_mrw_open_write(struct cdrom_device_info *cdi) static int mo_open_write(struct cdrom_device_info *cdi) { struct packet_command cgc; - char *buffer; + char buffer[255]; int ret; - buffer = kmalloc(255, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - init_cdrom_command(&cgc, buffer, 4, CGC_DATA_READ); + init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ); cgc.quiet = 1; /* @@ -861,15 +816,10 @@ static int mo_open_write(struct cdrom_device_info *cdi) } /* drive gave us no info, let the user go ahead */ - if (ret) { - ret = 0; - goto err; - } + if (ret) + return 0; - ret = buffer[3] & 0x80; -err: - kfree(buffer); - return ret; + return buffer[3] & 0x80; } static int cdrom_ram_open_write(struct cdrom_device_info *cdi) @@ -892,19 +842,15 @@ static int cdrom_ram_open_write(struct cdrom_device_info *cdi) static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) { struct packet_command cgc; - char *buffer; + char buffer[32]; int ret, mmc3_profile; - buffer = kmalloc(32, GFP_KERNEL); - if (!buffer) - return; - - init_cdrom_command(&cgc, buffer, 32, CGC_DATA_READ); + init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); cgc.cmd[0] = GPCMD_GET_CONFIGURATION; cgc.cmd[1] = 0; cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */ - cgc.cmd[8] = 32; /* Allocation Length */ + cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) @@ -913,7 +859,6 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) mmc3_profile = (buffer[6] << 8) | buffer[7]; cdi->mmc3_profile = mmc3_profile; - kfree(buffer); } static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) @@ -1628,15 +1573,12 @@ static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned t static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) { int ret; - u_char *buf; + u_char buf[20]; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - rpc_state_t *rpc_state; - - buf = kzalloc(20, GFP_KERNEL); - if (!buf) - return -ENOMEM; + rpc_state_t rpc_state; + memset(buf, 0, sizeof(buf)); init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ); switch (ai->type) { @@ -1647,7 +1589,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsa.agid, 0); if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; ai->lsa.agid = buf[7] >> 6; /* Returning data, let host change state */ @@ -1658,7 +1600,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsk.agid, 2); if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; copy_key(ai->lsk.key, &buf[4]); /* Returning data, let host change state */ @@ -1669,7 +1611,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsc.agid, 1); if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; copy_chal(ai->lsc.chal, &buf[4]); /* Returning data, let host change state */ @@ -1686,7 +1628,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) cgc.cmd[2] = ai->lstk.lba >> 24; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; ai->lstk.cpm = (buf[4] >> 7) & 1; ai->lstk.cp_sec = (buf[4] >> 6) & 1; @@ -1700,7 +1642,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) setup_report_key(&cgc, ai->lsasf.agid, 5); if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; ai->lsasf.asf = buf[7] & 1; break; @@ -1713,7 +1655,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) copy_chal(&buf[4], ai->hsc.chal); if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; ai->type = DVD_LU_SEND_KEY1; break; @@ -1726,7 +1668,7 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) if ((ret = cdo->generic_packet(cdi, &cgc))) { ai->type = DVD_AUTH_FAILURE; - goto err; + return ret; } ai->type = DVD_AUTH_ESTABLISHED; break; @@ -1737,23 +1679,24 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); setup_report_key(&cgc, ai->lsa.agid, 0x3f); if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; break; /* Get region settings */ case DVD_LU_SEND_RPC_STATE: cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n"); setup_report_key(&cgc, 0, 8); + memset(&rpc_state, 0, sizeof(rpc_state_t)); + cgc.buffer = (char *) &rpc_state; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; - rpc_state = (rpc_state_t *)buf; - ai->lrpcs.type = rpc_state->type_code; - ai->lrpcs.vra = rpc_state->vra; - ai->lrpcs.ucca = rpc_state->ucca; - ai->lrpcs.region_mask = rpc_state->region_mask; - ai->lrpcs.rpc_scheme = rpc_state->rpc_scheme; + ai->lrpcs.type = rpc_state.type_code; + ai->lrpcs.vra = rpc_state.vra; + ai->lrpcs.ucca = rpc_state.ucca; + ai->lrpcs.region_mask = rpc_state.region_mask; + ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme; break; /* Set region settings */ @@ -1764,23 +1707,20 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) buf[4] = ai->hrpcs.pdrc; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; break; default: cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type); - ret = -ENOTTY; - goto err; + return -ENOTTY; } - ret = 0; -err: - kfree(buf); - return ret; + + return 0; } static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) { - unsigned char *buf, *base; + unsigned char buf[21], *base; struct dvd_layer *layer; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; @@ -1789,11 +1729,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) if (layer_num >= DVD_LAYERS) return -EINVAL; - buf = kmalloc(21, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - init_cdrom_command(&cgc, buf, 21, CGC_DATA_READ); + init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[6] = layer_num; cgc.cmd[7] = s->type; @@ -1805,7 +1741,7 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) cgc.quiet = 1; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; base = &buf[4]; layer = &s->physical.layer[layer_num]; @@ -1829,24 +1765,17 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15]; layer->bca = base[16] >> 7; - ret = 0; -err: - kfree(buf); - return ret; + return 0; } static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) { int ret; - u_char *buf; + u_char buf[8]; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - buf = kmalloc(8, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - init_cdrom_command(&cgc, buf, 8, CGC_DATA_READ); + init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[6] = s->copyright.layer_num; cgc.cmd[7] = s->type; @@ -1854,15 +1783,12 @@ static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) cgc.cmd[9] = cgc.buflen & 0xff; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; s->copyright.cpst = buf[4]; s->copyright.rmi = buf[5]; - ret = 0; -err: - kfree(buf); - return ret; + return 0; } static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) @@ -1894,33 +1820,26 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) { int ret; - u_char *buf; + u_char buf[4 + 188]; struct packet_command cgc; struct cdrom_device_ops *cdo = cdi->ops; - buf = kmalloc(4 + 188, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - init_cdrom_command(&cgc, buf, 4 + 188, CGC_DATA_READ); + init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[7] = s->type; cgc.cmd[9] = cgc.buflen & 0xff; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; s->bca.len = buf[0] << 8 | buf[1]; if (s->bca.len < 12 || s->bca.len > 188) { cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); - ret = -EIO; - goto err; + return -EIO; } memcpy(s->bca.value, &buf[4], s->bca.len); - ret = 0; -err: - kfree(buf); - return ret; + + return 0; } static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) @@ -2020,13 +1939,9 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, { struct cdrom_device_ops *cdo = cdi->ops; struct packet_command cgc; - char *buffer; + char buffer[32]; int ret; - buffer = kmalloc(32, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; cgc.cmd[1] = 2; /* MSF addressing */ @@ -2035,7 +1950,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, cgc.cmd[8] = 16; if ((ret = cdo->generic_packet(cdi, &cgc))) - goto err; + return ret; subchnl->cdsc_audiostatus = cgc.buffer[1]; subchnl->cdsc_format = CDROM_MSF; @@ -2050,10 +1965,7 @@ static int cdrom_read_subchannel(struct cdrom_device_info *cdi, subchnl->cdsc_absaddr.msf.second = cgc.buffer[10]; subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11]; - ret = 0; -err: - kfree(buffer); - return ret; + return 0; } /* -- cgit v0.10.2 From 7c0c0b5b19611ac15eec69043cb5588f6cbfbd7b Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Fri, 4 Jul 2008 09:33:17 +0200 Subject: drivers/block/pktcdvd.c: avoid useless memset Avoid the 'memset(...,0, ...)' before calling 'init_cdrom_command' because this function already does it. Signed-off-by: Christophe Jaillet Acked-by: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 85e44d0..45bee91 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2080,7 +2080,6 @@ static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd, unsigned char buf[64]; int ret; - memset(buf, 0, sizeof(buf)); init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.sense = &sense; cgc.buflen = pd->mode_offset + 12; @@ -2127,7 +2126,6 @@ static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned char *cap_buf; int ret, offset; - memset(buf, 0, sizeof(buf)); cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_UNKNOWN); cgc.sense = &sense; -- cgit v0.10.2 From 8b3d3567f72aa61d5d6f4ce89d289b154e1ea866 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Fri, 4 Jul 2008 09:33:33 +0200 Subject: ramfs: enable splice write Signed-off-by: Octavian Purdila Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 9590b90..78f613c 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c @@ -45,6 +45,7 @@ const struct file_operations ramfs_file_operations = { .mmap = generic_file_mmap, .fsync = simple_sync_file, .splice_read = generic_file_splice_read, + .splice_write = generic_file_splice_write, .llseek = generic_file_llseek, }; diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 0989bc2..52312ec 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -43,6 +43,7 @@ const struct file_operations ramfs_file_operations = { .aio_write = generic_file_aio_write, .fsync = simple_sync_file, .splice_read = generic_file_splice_read, + .splice_write = generic_file_splice_write, .llseek = generic_file_llseek, }; -- cgit v0.10.2 From 32502b8413a77b54b9e19809404109590c32dfb7 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 4 Jul 2008 09:35:17 +0200 Subject: splice: fix generic_file_splice_read() race with page invalidation If a page was invalidated during splicing from file to a pipe, then generic_file_splice_read() could return a short or zero count. This manifested itself in rare I/O errors seen on nfs exported fuse filesystems. This is because nfsd uses splice_direct_to_actor() to read files, and fuse uses invalidate_inode_pages2() to invalidate stale data on open. Fix by redoing the page find/create if it was found to be truncated (invalidated). Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/fs/splice.c b/fs/splice.c index aa5f6f6..3994421 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -379,13 +379,22 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, lock_page(page); /* - * page was truncated, stop here. if this isn't the - * first page, we'll just complete what we already - * added + * Page was truncated, or invalidated by the + * filesystem. Redo the find/create, but this time the + * page is kept locked, so there's no chance of another + * race with truncate/invalidate. */ if (!page->mapping) { unlock_page(page); - break; + page = find_or_create_page(mapping, index, + mapping_gfp_mask(mapping)); + + if (!page) { + error = -ENOMEM; + break; + } + page_cache_release(pages[page_nr]); + pages[page_nr] = page; } /* * page was already under io and is now done, great -- cgit v0.10.2 From ba8dd03ac09f51a69c154b8cb508b701d713a2cd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 4 Jul 2008 11:26:40 +0200 Subject: generic-ipi: fix s390 build bug forgot to remove #include from linux/smp.h while fixing the original s390 build bug. Patch below fixes this build bug caused by header inclusion dependencies: CC kernel/timer.o In file included from include/linux/spinlock.h:87, from include/linux/smp.h:11, from include/linux/kernel_stat.h:4, from kernel/timer.c:22: include/asm/spinlock.h: In function '__raw_spin_lock': include/asm/spinlock.h:69: error: implicit declaration of function 'smp_processor_id' Signed-off-by: Heiko Carstens Signed-off-by: Ingo Molnar diff --git a/include/linux/smp.h b/include/linux/smp.h index 5526110..48262f8 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -8,7 +8,6 @@ #include #include -#include #include extern void cpu_idle(void); -- cgit v0.10.2 From c4acb2c0669c5c5c9b28e9d02a34b5c67edf7092 Mon Sep 17 00:00:00 2001 From: Gregory Haskins Date: Fri, 27 Jun 2008 14:29:55 -0600 Subject: sched: terminate newidle balancing once at least one task has moved over Inspired by Peter Zijlstra. Signed-off-by: Gregory Haskins Cc: npiggin@suse.de Cc: rostedt@goodmis.org Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 677c80b..d99aeab 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3013,6 +3013,10 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, max_load_move - total_load_moved, sd, idle, all_pinned, &this_best_prio); class = class->next; + + if (idle == CPU_NEWLY_IDLE && this_rq->nr_running) + break; + } while (class && max_load_move > total_load_moved); return total_load_moved > 0; -- cgit v0.10.2 From 2087a1ad822cd3a68b73338457047fcc54da726b Mon Sep 17 00:00:00 2001 From: Gregory Haskins Date: Fri, 27 Jun 2008 14:30:00 -0600 Subject: sched: add avg-overlap support to RT tasks We have the notion of tracking process-coupling (a.k.a. buddy-wake) via the p->se.last_wake / p->se.avg_overlap facilities, but it is only used for cfs to cfs interactions. There is no reason why an rt to cfs interaction cannot share in establishing a relationhip in a similar manner. Because PREEMPT_RT runs many kernel threads as FIFO priority, we often times have heavy interaction between RT threads waking CFS applications. This patch offers a substantial boost (50-60%+) in perfomance under those circumstances. Signed-off-by: Gregory Haskins Cc: npiggin@suse.de Cc: rostedt@goodmis.org Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index d99aeab..bbc40c3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1693,6 +1693,12 @@ static void set_load_weight(struct task_struct *p) p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO]; } +static void update_avg(u64 *avg, u64 sample) +{ + s64 diff = sample - *avg; + *avg += diff >> 3; +} + static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup) { sched_info_queued(p); @@ -1702,6 +1708,12 @@ static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup) static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep) { + if (sleep && p->se.last_wakeup) { + update_avg(&p->se.avg_overlap, + p->se.sum_exec_runtime - p->se.last_wakeup); + p->se.last_wakeup = 0; + } + p->sched_class->dequeue_task(rq, p, sleep); p->se.on_rq = 0; } @@ -2313,6 +2325,8 @@ out_running: p->sched_class->task_wake_up(rq, p); #endif out: + current->se.last_wakeup = current->se.sum_exec_runtime; + task_rq_unlock(rq, &flags); return success; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 2e43d4a..f2aa987 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -726,21 +726,6 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) __enqueue_entity(cfs_rq, se); } -static void update_avg(u64 *avg, u64 sample) -{ - s64 diff = sample - *avg; - *avg += diff >> 3; -} - -static void update_avg_stats(struct cfs_rq *cfs_rq, struct sched_entity *se) -{ - if (!se->last_wakeup) - return; - - update_avg(&se->avg_overlap, se->sum_exec_runtime - se->last_wakeup); - se->last_wakeup = 0; -} - static void dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) { @@ -751,7 +736,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) update_stats_dequeue(cfs_rq, se); if (sleep) { - update_avg_stats(cfs_rq, se); #ifdef CONFIG_SCHEDSTATS if (entity_is_task(se)) { struct task_struct *tsk = task_of(se); @@ -1196,9 +1180,9 @@ wake_affine(struct rq *rq, struct sched_domain *this_sd, struct rq *this_rq, * a reasonable amount of time then attract this newly * woken task: */ - if (sync && balanced && curr->sched_class == &fair_sched_class) { + if (sync && balanced) { if (curr->se.avg_overlap < sysctl_sched_migration_cost && - p->se.avg_overlap < sysctl_sched_migration_cost) + p->se.avg_overlap < sysctl_sched_migration_cost) return 1; } @@ -1359,7 +1343,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p) return; } - se->last_wakeup = se->sum_exec_runtime; if (unlikely(se == pse)) return; -- cgit v0.10.2 From 46ac22bab42cc868b9c1d0e915ddbc8e8065a44d Mon Sep 17 00:00:00 2001 From: Ankita Garg Date: Tue, 1 Jul 2008 14:30:06 +0530 Subject: sched: fix accounting in task delay accounting & migration On Thu, Jun 19, 2008 at 12:27:14PM +0200, Peter Zijlstra wrote: > On Thu, 2008-06-05 at 10:50 +0530, Ankita Garg wrote: > > > Thanks Peter for the explanation... > > > > I agree with the above and that is the reason why I did not see weird > > values with cpu_time. But, run_delay still would suffer skews as the end > > points for delta could be taken on different cpus due to migration (more > > so on RT kernel due to the push-pull operations). With the below patch, > > I could not reproduce the issue I had seen earlier. After every dequeue, > > we take the delta and start wait measurements from zero when moved to a > > different rq. > > OK, so task delay delay accounting is broken because it doesn't take > migration into account. > > What you've done is make it symmetric wrt enqueue, and account it like > > cpu0 cpu1 > > enqueue > > dequeue > enqueue > > run > > Where you add both d1 and d2 to the run_delay,.. right? > Thanks for reviewing the patch. The above is exactly what I have done. > This seems like a good fix, however it looks like the patch will break > compilation in !CONFIG_SCHEDSTATS && !CONFIG_TASK_DELAY_ACCT, of it > failing to provide a stub for sched_info_dequeue() in that case. Fixed. Pl. find the new patch below. Signed-off-by: Ankita Garg Acked-by: Peter Zijlstra Cc: Gregory Haskins Cc: rostedt@goodmis.org Cc: suresh.b.siddha@intel.com Cc: aneesh.kumar@linux.vnet.ibm.com Cc: dhaval@linux.vnet.ibm.com Cc: vatsa@linux.vnet.ibm.com Cc: David Bahi Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index bbc40c3..996bc15 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1714,6 +1714,7 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep) p->se.last_wakeup = 0; } + sched_info_dequeued(p); p->sched_class->dequeue_task(rq, p, sleep); p->se.on_rq = 0; } diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index 80179ef..8385d43 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h @@ -118,6 +118,13 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta) if (rq) rq->rq_sched_info.cpu_time += delta; } + +static inline void +rq_sched_info_dequeued(struct rq *rq, unsigned long long delta) +{ + if (rq) + rq->rq_sched_info.run_delay += delta; +} # define schedstat_inc(rq, field) do { (rq)->field++; } while (0) # define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0) # define schedstat_set(var, val) do { var = (val); } while (0) @@ -126,6 +133,9 @@ static inline void rq_sched_info_arrive(struct rq *rq, unsigned long long delta) {} static inline void +rq_sched_info_dequeued(struct rq *rq, unsigned long long delta) +{} +static inline void rq_sched_info_depart(struct rq *rq, unsigned long long delta) {} # define schedstat_inc(rq, field) do { } while (0) @@ -134,6 +144,11 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta) #endif #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) +static inline void sched_info_reset_dequeued(struct task_struct *t) +{ + t->sched_info.last_queued = 0; +} + /* * Called when a process is dequeued from the active array and given * the cpu. We should note that with the exception of interactive @@ -143,15 +158,22 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta) * active queue, thus delaying tasks in the expired queue from running; * see scheduler_tick()). * - * This function is only called from sched_info_arrive(), rather than - * dequeue_task(). Even though a task may be queued and dequeued multiple - * times as it is shuffled about, we're really interested in knowing how - * long it was from the *first* time it was queued to the time that it - * finally hit a cpu. + * Though we are interested in knowing how long it was from the *first* time a + * task was queued to the time that it finally hit a cpu, we call this routine + * from dequeue_task() to account for possible rq->clock skew across cpus. The + * delta taken on each cpu would annul the skew. */ static inline void sched_info_dequeued(struct task_struct *t) { - t->sched_info.last_queued = 0; + unsigned long long now = task_rq(t)->clock, delta = 0; + + if (unlikely(sched_info_on())) + if (t->sched_info.last_queued) + delta = now - t->sched_info.last_queued; + sched_info_reset_dequeued(t); + t->sched_info.run_delay += delta; + + rq_sched_info_dequeued(task_rq(t), delta); } /* @@ -165,7 +187,7 @@ static void sched_info_arrive(struct task_struct *t) if (t->sched_info.last_queued) delta = now - t->sched_info.last_queued; - sched_info_dequeued(t); + sched_info_reset_dequeued(t); t->sched_info.run_delay += delta; t->sched_info.last_arrival = now; t->sched_info.pcount++; @@ -242,7 +264,9 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next) __sched_info_switch(prev, next); } #else -#define sched_info_queued(t) do { } while (0) -#define sched_info_switch(t, next) do { } while (0) +#define sched_info_queued(t) do { } while (0) +#define sched_info_reset_dequeued(t) do { } while (0) +#define sched_info_dequeued(t) do { } while (0) +#define sched_info_switch(t, next) do { } while (0) #endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */ -- cgit v0.10.2 From 5b2d281acb04a29fcdc76ced5ca6099565a0747f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 27 Jun 2008 14:43:20 -0700 Subject: IB/uverbs: BKL is not needed for ib_uverbs_open() Remove explicit lock_kernel() calls and document why the code is safe. Signed-off-by: Roland Dreier Signed-off-by: Jonathan Corbet diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 8ede1e4..fdfcf79 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -45,7 +45,6 @@ #include #include #include -#include #include @@ -611,23 +610,32 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) return file->device->ib_dev->mmap(file->ucontext, vma); } +/* + * ib_uverbs_open() does not need the BKL: + * + * - dev_table[] accesses are protected by map_lock, the + * ib_uverbs_device structures are properly reference counted, and + * everything else is purely local to the file being created, so + * races against other open calls are not a problem; + * - there is no ioctl method to race against; + * - the device is added to dev_table[] as the last part of module + * initialization, the open method will either immediately run + * -ENXIO, or all required initialization will be done. + */ static int ib_uverbs_open(struct inode *inode, struct file *filp) { struct ib_uverbs_device *dev; struct ib_uverbs_file *file; int ret; - lock_kernel(); spin_lock(&map_lock); dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; if (dev) kref_get(&dev->ref); spin_unlock(&map_lock); - if (!dev) { - unlock_kernel(); + if (!dev) return -ENXIO; - } if (!try_module_get(dev->ib_dev->owner)) { ret = -ENODEV; @@ -648,7 +656,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) filp->private_data = file; - unlock_kernel(); return 0; err_module: @@ -656,7 +663,6 @@ err_module: err: kref_put(&dev->ref, ib_uverbs_release_dev); - unlock_kernel(); return ret; } -- cgit v0.10.2 From 63dd10846d4917534e9ec7bddf43be786effe8b8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:43 +0200 Subject: MXC: do not include board specific header from architecture include do not include board-mx31ads.h from hardware.h, instead include it directly only where needed. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 7e89bdc..5addbb7 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -29,6 +29,7 @@ #include #include #include +#include /*! * @file mx31ads.c diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h index e87ff06..4ed2d80 100644 --- a/include/asm-arm/arch-mxc/hardware.h +++ b/include/asm-arm/arch-mxc/hardware.h @@ -1,11 +1,20 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, 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. + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ #ifndef __ASM_ARCH_MXC_HARDWARE_H__ @@ -19,13 +28,4 @@ #include -/* - * --------------------------------------------------------------------------- - * Board specific defines - * --------------------------------------------------------------------------- - */ -#ifdef CONFIG_MACH_MX31ADS -# include -#endif - #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ -- cgit v0.10.2 From 036bb15ec94216e28cb1550af0fdcdfb90c549df Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:44 +0200 Subject: IMX UART: do not assume 16MHz reference frequency We assumed a 16MHz reference frequency for the UART. While this is true for i.MX1 most of the time it is not true for MX27/MX31. Also, add handling for the ONEMS register which is present on newer versions of the chip and pass a sane minimum baudrate to uart_get_baud_rate(). Signed-off-by: Sascha Hauer diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 5a375bf..6226e66 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -589,6 +589,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long flags; unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; + unsigned int div, num, denom, ufcr; /* * If we don't support modem control lines, don't allow @@ -634,7 +635,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, /* * Ask the core to calculate the divisor for us. */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); @@ -684,14 +685,41 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, sport->port.membase + UCR2); old_txrxen &= (UCR2_TXEN | UCR2_RXEN); - /* set the baud rate. We assume uartclk = 16 MHz - * - * baud * 16 UBIR - 1 - * --------- = -------- - * uartclk UBMR - 1 - */ - writel((baud / 100) - 1, sport->port.membase + UBIR); - writel(10000 - 1, sport->port.membase + UBMR); + div = sport->port.uartclk / (baud * 16); + if (div > 7) + div = 7; + if (!div) + div = 1; + + num = baud; + denom = port->uartclk / div / 16; + + /* shift num and denom right until they fit into 16 bits */ + while (num > 0x10000 || denom > 0x10000) { + num >>= 1; + denom >>= 1; + } + if (num > 0) + num -= 1; + if (denom > 0) + denom -= 1; + + writel(num, sport->port.membase + UBIR); + writel(denom, sport->port.membase + UBMR); + + if (div == 7) + div = 6; /* 6 in RFDIV means divide by 7 */ + else + div = 6 - div; + + ufcr = readl(sport->port.membase + UFCR); + ufcr = (ufcr & (~UFCR_RFDIV)) | + (div << 7); + writel(ufcr, sport->port.membase + UFCR); + +#ifdef ONEMS + writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); +#endif writel(old_ucr1, sport->port.membase + UCR1); @@ -812,7 +840,6 @@ static struct imx_port imx_ports[] = { .membase = (void *)IMX_UART1_BASE, .mapbase = 0x00206000, .irq = UART1_MINT_RX, - .uartclk = 16000000, .fifosize = 32, .flags = UPF_BOOT_AUTOCONF, .ops = &imx_pops, @@ -828,7 +855,6 @@ static struct imx_port imx_ports[] = { .membase = (void *)IMX_UART2_BASE, .mapbase = 0x00207000, .irq = UART2_MINT_RX, - .uartclk = 16000000, .fifosize = 32, .flags = UPF_BOOT_AUTOCONF, .ops = &imx_pops, @@ -858,6 +884,8 @@ static void __init imx_init_ports(void) init_timer(&imx_ports[i].timer); imx_ports[i].timer.function = imx_timeout; imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; + + imx_ports[i].port.uartclk = imx_get_perclk1(); } } -- cgit v0.10.2 From 2582d8c1655f2eda42d5358a242b256fd6e88571 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:45 +0200 Subject: IMX UART: Add board specific init/exit functions Add platform specific init functions. Also rename the struct platform_device dev into pdev. Signed-off-by: Sascha Hauer diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 6226e66..7796843 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -1078,30 +1078,40 @@ static int serial_imx_resume(struct platform_device *dev) return 0; } -static int serial_imx_probe(struct platform_device *dev) +static int serial_imx_probe(struct platform_device *pdev) { struct imxuart_platform_data *pdata; - imx_ports[dev->id].port.dev = &dev->dev; + imx_ports[pdev->id].port.dev = &pdev->dev; - pdata = (struct imxuart_platform_data *)dev->dev.platform_data; + pdata = pdev->dev.platform_data; if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) - imx_ports[dev->id].have_rtscts = 1; + imx_ports[pdev->id].have_rtscts = 1; + + if (pdata->init) + pdata->init(pdev); + + uart_add_one_port(&imx_reg, &imx_ports[pdev->id].port); + platform_set_drvdata(pdev, &imx_ports[pdev->id]); - uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); - platform_set_drvdata(dev, &imx_ports[dev->id]); return 0; } -static int serial_imx_remove(struct platform_device *dev) +static int serial_imx_remove(struct platform_device *pdev) { - struct imx_port *sport = platform_get_drvdata(dev); + struct imxuart_platform_data *pdata; + struct imx_port *sport = platform_get_drvdata(pdev); - platform_set_drvdata(dev, NULL); + pdata = pdev->dev.platform_data; + + platform_set_drvdata(pdev, NULL); if (sport) uart_remove_one_port(&imx_reg, &sport->port); + if (pdata->exit) + pdata->exit(pdev); + return 0; } diff --git a/include/asm-arm/arch-imx/imx-uart.h b/include/asm-arm/arch-imx/imx-uart.h index 3a685e1..d54eb1d 100644 --- a/include/asm-arm/arch-imx/imx-uart.h +++ b/include/asm-arm/arch-imx/imx-uart.h @@ -4,6 +4,8 @@ #define IMXUART_HAVE_RTSCTS (1<<0) struct imxuart_platform_data { + int (*init)(struct platform_device *pdev); + void (*exit)(struct platform_device *pdev); unsigned int flags; }; -- cgit v0.10.2 From dbff4e9ea2e83fda89143389bfb229cb29425a32 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:45 +0200 Subject: IMX UART: remove statically initialized tables This patch removes the statically initialized tables from the i.MX serial driver and makes the driver fully dependent on the information provided by the platform_device. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index a9778c1..9635d58 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -69,6 +69,11 @@ static struct resource imx_uart1_resources[] = { .end = (UART1_MINT_TX), .flags = IORESOURCE_IRQ, }, + [3] = { + .start = UART1_MINT_RTS, + .end = UART1_MINT_RTS, + .flags = IORESOURCE_IRQ, + }, }; static struct platform_device imx_uart1_device = { @@ -97,6 +102,11 @@ static struct resource imx_uart2_resources[] = { .end = (UART2_MINT_TX), .flags = IORESOURCE_IRQ, }, + [3] = { + .start = UART2_MINT_RTS, + .end = UART2_MINT_RTS, + .flags = IORESOURCE_IRQ, + }, }; static struct platform_device imx_uart2_device = { diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 7796843..8d6cb74 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -176,6 +176,8 @@ #define DRIVER_NAME "IMX-uart" +#define UART_NR 8 + struct imx_port { struct uart_port port; struct timer_list timer; @@ -829,65 +831,7 @@ static struct uart_ops imx_pops = { .verify_port = imx_verify_port, }; -static struct imx_port imx_ports[] = { - { - .txirq = UART1_MINT_TX, - .rxirq = UART1_MINT_RX, - .rtsirq = UART1_MINT_RTS, - .port = { - .type = PORT_IMX, - .iotype = UPIO_MEM, - .membase = (void *)IMX_UART1_BASE, - .mapbase = 0x00206000, - .irq = UART1_MINT_RX, - .fifosize = 32, - .flags = UPF_BOOT_AUTOCONF, - .ops = &imx_pops, - .line = 0, - }, - }, { - .txirq = UART2_MINT_TX, - .rxirq = UART2_MINT_RX, - .rtsirq = UART2_MINT_RTS, - .port = { - .type = PORT_IMX, - .iotype = UPIO_MEM, - .membase = (void *)IMX_UART2_BASE, - .mapbase = 0x00207000, - .irq = UART2_MINT_RX, - .fifosize = 32, - .flags = UPF_BOOT_AUTOCONF, - .ops = &imx_pops, - .line = 1, - }, - } -}; - -/* - * Setup the IMX serial ports. - * Note also that we support "console=ttySMXx" where "x" is either 0 or 1. - * Which serial port this ends up being depends on the machine you're - * running this kernel on. I'm not convinced that this is a good idea, - * but that's the way it traditionally works. - * - */ -static void __init imx_init_ports(void) -{ - static int first = 1; - int i; - - if (!first) - return; - first = 0; - - for (i = 0; i < ARRAY_SIZE(imx_ports); i++) { - init_timer(&imx_ports[i].timer); - imx_ports[i].timer.function = imx_timeout; - imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; - - imx_ports[i].port.uartclk = imx_get_perclk1(); - } -} +static struct imx_port *imx_ports[UART_NR]; #ifdef CONFIG_SERIAL_IMX_CONSOLE static void imx_console_putchar(struct uart_port *port, int ch) @@ -906,7 +850,7 @@ static void imx_console_putchar(struct uart_port *port, int ch) static void imx_console_write(struct console *co, const char *s, unsigned int count) { - struct imx_port *sport = &imx_ports[co->index]; + struct imx_port *sport = imx_ports[co->index]; unsigned int old_ucr1, old_ucr2; /* @@ -1012,7 +956,7 @@ imx_console_setup(struct console *co, char *options) */ if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) co->index = 0; - sport = &imx_ports[co->index]; + sport = imx_ports[co->index]; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -1035,14 +979,6 @@ static struct console imx_console = { .data = &imx_reg, }; -static int __init imx_rs_console_init(void) -{ - imx_init_ports(); - register_console(&imx_console); - return 0; -} -console_initcall(imx_rs_console_init); - #define IMX_CONSOLE &imx_console #else #define IMX_CONSOLE NULL @@ -1080,21 +1016,63 @@ static int serial_imx_resume(struct platform_device *dev) static int serial_imx_probe(struct platform_device *pdev) { + struct imx_port *sport; struct imxuart_platform_data *pdata; + void __iomem *base; + int ret = 0; + struct resource *res; + + sport = kzalloc(sizeof(*sport), GFP_KERNEL); + if (!sport) + return -ENOMEM; - imx_ports[pdev->id].port.dev = &pdev->dev; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto free; + } + + base = ioremap(res->start, PAGE_SIZE); + if (!base) { + ret = -ENOMEM; + goto free; + } + + sport->port.dev = &pdev->dev; + sport->port.mapbase = res->start; + sport->port.membase = base; + sport->port.type = PORT_IMX, + sport->port.iotype = UPIO_MEM; + sport->port.irq = platform_get_irq(pdev, 0); + sport->rxirq = platform_get_irq(pdev, 0); + sport->txirq = platform_get_irq(pdev, 1); + sport->rtsirq = platform_get_irq(pdev, 2); + sport->port.fifosize = 32; + sport->port.ops = &imx_pops; + sport->port.flags = UPF_BOOT_AUTOCONF; + sport->port.line = pdev->id; + init_timer(&sport->timer); + sport->timer.function = imx_timeout; + sport->timer.data = (unsigned long)sport; + sport->port.uartclk = imx_get_perclk1(); + + imx_ports[pdev->id] = sport; pdata = pdev->dev.platform_data; if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) - imx_ports[pdev->id].have_rtscts = 1; + sport->have_rtscts = 1; if (pdata->init) pdata->init(pdev); - uart_add_one_port(&imx_reg, &imx_ports[pdev->id].port); - platform_set_drvdata(pdev, &imx_ports[pdev->id]); + uart_add_one_port(&imx_reg, &sport->port); + platform_set_drvdata(pdev, &sport->port); return 0; +free: + kfree(sport); + + return ret; } static int serial_imx_remove(struct platform_device *pdev) @@ -1112,6 +1090,9 @@ static int serial_imx_remove(struct platform_device *pdev) if (pdata->exit) pdata->exit(pdev); + iounmap(sport->port.membase); + kfree(sport); + return 0; } @@ -1133,8 +1114,6 @@ static int __init imx_serial_init(void) printk(KERN_INFO "Serial: IMX driver\n"); - imx_init_ports(); - ret = uart_register_driver(&imx_reg); if (ret) return ret; -- cgit v0.10.2 From 38a41fdf94c449c165213e4665c3f8a0d30f8aba Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:46 +0200 Subject: IMX: introduce clock API This patch introduces the clock API for i.MX and converts all in-Kernel drivers to use it. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 88d5e61..b047c7e 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y += irq.o time.o dma.o generic.o +obj-y += irq.o time.o dma.o generic.o clock.o obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o diff --git a/arch/arm/mach-imx/clock.c b/arch/arm/mach-imx/clock.c new file mode 100644 index 0000000..6a90fe5 --- /dev/null +++ b/arch/arm/mach-imx/clock.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2008 Sascha Hauer , Pengutronix + * + * 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 +#include +#include +#include +#include + +#include +#include + +/* + * Very simple approach: We can't disable clocks, so we do + * not need refcounting + */ + +struct clk { + struct list_head node; + const char *name; + unsigned long (*get_rate)(void); +}; + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +static unsigned long imx_decode_pll(unsigned int pll, u32 f_ref) +{ + unsigned long long ll; + unsigned long quot; + + u32 mfi = (pll >> 10) & 0xf; + u32 mfn = pll & 0x3ff; + u32 mfd = (pll >> 16) & 0x3ff; + u32 pd = (pll >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + + ll = 2 * (unsigned long long)f_ref * + ((mfi << 16) + (mfn << 16) / (mfd + 1)); + quot = (pd + 1) * (1 << 16); + ll += quot / 2; + do_div(ll, quot); + return (unsigned long)ll; +} + +static unsigned long imx_get_system_clk(void) +{ + u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); + + return imx_decode_pll(SPCTL0, f_ref); +} + +static unsigned long imx_get_mcu_clk(void) +{ + return imx_decode_pll(MPCTL0, CLK32 * 512); +} + +/* + * get peripheral clock 1 ( UART[12], Timer[12], PWM ) + */ +static unsigned long imx_get_perclk1(void) +{ + return imx_get_system_clk() / (((PCDR) & 0xf)+1); +} + +/* + * get peripheral clock 2 ( LCD, SD, SPI[12] ) + */ +static unsigned long imx_get_perclk2(void) +{ + return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); +} + +/* + * get peripheral clock 3 ( SSI ) + */ +static unsigned long imx_get_perclk3(void) +{ + return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); +} + +/* + * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) + */ +static unsigned long imx_get_hclk(void) +{ + return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); +} + +static struct clk clk_system_clk = { + .name = "system_clk", + .get_rate = imx_get_system_clk, +}; + +static struct clk clk_hclk = { + .name = "hclk", + .get_rate = imx_get_hclk, +}; + +static struct clk clk_mcu_clk = { + .name = "mcu_clk", + .get_rate = imx_get_mcu_clk, +}; + +static struct clk clk_perclk1 = { + .name = "perclk1", + .get_rate = imx_get_perclk1, +}; + +static struct clk clk_uart_clk = { + .name = "uart_clk", + .get_rate = imx_get_perclk1, +}; + +static struct clk clk_perclk2 = { + .name = "perclk2", + .get_rate = imx_get_perclk2, +}; + +static struct clk clk_perclk3 = { + .name = "perclk3", + .get_rate = imx_get_perclk3, +}; + +static struct clk *clks[] = { + &clk_perclk1, + &clk_perclk2, + &clk_perclk3, + &clk_system_clk, + &clk_hclk, + &clk_mcu_clk, + &clk_uart_clk, +}; + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + mutex_lock(&clocks_mutex); + list_for_each_entry(p, &clocks, node) { + if (!strcmp(p->name, id)) { + clk = p; + goto found; + } + } + +found: + mutex_unlock(&clocks_mutex); + + return clk; +} + +void clk_put(struct clk *clk) +{ +} + +int clk_enable(struct clk *clk) +{ + return 0; +} + +void clk_disable(struct clk *clk) +{ +} + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->get_rate(); +} + +int imx_clocks_init(void) +{ + int i; + + mutex_lock(&clocks_mutex); + for (i = 0; i < ARRAY_SIZE(clks); i++) + list_add(&clks[i]->node, &clocks); + mutex_unlock(&clocks_mutex); + + return 0; +} + diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c index e548ba7..be0809b 100644 --- a/arch/arm/mach-imx/cpufreq.c +++ b/arch/arm/mach-imx/cpufreq.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include @@ -52,6 +54,8 @@ static u32 mpctl0_at_boot; static u32 bclk_div_at_boot; +static struct clk *system_clk, *mcu_clk; + static void imx_set_async_mode(void) { adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE); @@ -160,10 +164,10 @@ static unsigned int imx_get_speed(unsigned int cpu) cr = get_cr(); if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) { - freq = imx_get_system_clk(); + freq = clk_get_rate(system_clk); freq = (freq + bclk_div/2) / bclk_div; } else { - freq = imx_get_mcu_clk(); + freq = clk_get_rate(mcu_clk); if (cscr & CSCR_MPU_PRESC) freq /= 2; } @@ -201,7 +205,7 @@ static int imx_set_target(struct cpufreq_policy *policy, pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n", freq, mpctl0_at_boot); - sysclk = imx_get_system_clk(); + sysclk = clk_get_rate(system_clk); if (freq > sysclk / bclk_div_at_boot + 1000000) { freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation); @@ -290,6 +294,16 @@ static int __init imx_cpufreq_init(void) bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1; mpctl0_at_boot = 0; + system_clk = clk_get(NULL, "system_clk"); + if (IS_ERR(system_clk)) + return PTR_ERR(system_clk); + + mcu_clk = clk_get(NULL, "mcu_clk"); + if (IS_ERR(mcu_clk)) { + clk_put(system_clk); + return PTR_ERR(mcu_clk); + } + if((CSCR & CSCR_MPEN) && ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE)) mpctl0_at_boot = MPCTL0; diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 4cfc9d3..98ddd8a 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -214,82 +214,6 @@ int imx_irq_to_gpio(unsigned irq) EXPORT_SYMBOL(imx_irq_to_gpio); -/* - * get the system pll clock in Hz - * - * mfi + mfn / (mfd +1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ -static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref) -{ - unsigned long long ll; - unsigned long quot; - - u32 mfi = (pll >> 10) & 0xf; - u32 mfn = pll & 0x3ff; - u32 mfd = (pll >> 16) & 0x3ff; - u32 pd = (pll >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - - ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) ); - quot = (pd+1) * (1<<16); - ll += quot / 2; - do_div(ll, quot); - return (unsigned int) ll; -} - -unsigned int imx_get_system_clk(void) -{ - u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); - - return imx_decode_pll(SPCTL0, f_ref); -} -EXPORT_SYMBOL(imx_get_system_clk); - -unsigned int imx_get_mcu_clk(void) -{ - return imx_decode_pll(MPCTL0, CLK32 * 512); -} -EXPORT_SYMBOL(imx_get_mcu_clk); - -/* - * get peripheral clock 1 ( UART[12], Timer[12], PWM ) - */ -unsigned int imx_get_perclk1(void) -{ - return imx_get_system_clk() / (((PCDR) & 0xf)+1); -} -EXPORT_SYMBOL(imx_get_perclk1); - -/* - * get peripheral clock 2 ( LCD, SD, SPI[12] ) - */ -unsigned int imx_get_perclk2(void) -{ - return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); -} -EXPORT_SYMBOL(imx_get_perclk2); - -/* - * get peripheral clock 3 ( SSI ) - */ -unsigned int imx_get_perclk3(void) -{ - return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); -} -EXPORT_SYMBOL(imx_get_perclk3); - -/* - * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) - */ -unsigned int imx_get_hclk(void) -{ - return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); -} -EXPORT_SYMBOL(imx_get_hclk); - static struct resource imx_mmc_resources[] = { [0] = { .start = 0x00214000, diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index d86d124..5a41e96 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -86,10 +87,10 @@ static struct clocksource clocksource_imx = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static int __init imx_clocksource_init(void) +static int __init imx_clocksource_init(unsigned long rate) { clocksource_imx.mult = - clocksource_hz2mult(imx_get_perclk1(), clocksource_imx.shift); + clocksource_hz2mult(rate, clocksource_imx.shift); clocksource_register(&clocksource_imx); return 0; @@ -174,9 +175,9 @@ static struct clock_event_device clockevent_imx = { .rating = 200, }; -static int __init imx_clockevent_init(void) +static int __init imx_clockevent_init(unsigned long rate) { - clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, + clockevent_imx.mult = div_sc(rate, NSEC_PER_SEC, clockevent_imx.shift); clockevent_imx.max_delta_ns = clockevent_delta2ns(0xfffffffe, &clockevent_imx); @@ -190,13 +191,23 @@ static int __init imx_clockevent_init(void) return 0; } +extern int imx_clocks_init(void); static void __init imx_timer_init(void) { + struct clk *clk; + unsigned long rate; + + imx_clocks_init(); + + clk = clk_get(NULL, "perclk1"); + clk_enable(clk); + rate = clk_get_rate(clk); + imx_timer_hardware_init(); - imx_clocksource_init(); + imx_clocksource_init(rate); - imx_clockevent_init(); + imx_clockevent_init(rate); /* * Make irqs happen for the system timer diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 95f33e8..ef2f6fc 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,8 @@ struct imxmci_host { unsigned char actual_bus_width; int prev_cmd_code; + + struct clk *clk; }; #define IMXMCI_PEND_IRQ_b 0 @@ -841,7 +844,7 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* The prescaler is 5 for PERCLK2 equal to 96MHz * then 96MHz / 5 = 19.2 MHz */ - clk=imx_get_perclk2(); + clk = clk_get_rate(host->clk); prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE; switch(prescaler) { case 0: @@ -994,6 +997,13 @@ static int imxmci_probe(struct platform_device *pdev) host->res = r; host->irq = irq; + host->clk = clk_get(&pdev->dev, "perclk2"); + if (IS_ERR(host->clk)) { + ret = PTR_ERR(host->clk); + goto out; + } + clk_enable(host->clk); + imx_gpio_mode(PB8_PF_SD_DAT0); imx_gpio_mode(PB9_PF_SD_DAT1); imx_gpio_mode(PB10_PF_SD_DAT2); @@ -1053,6 +1063,10 @@ out: imx_dma_free(host->dma); host->dma_allocated=0; } + if (host->clk) { + clk_disable(host->clk); + clk_put(host->clk); + } } if (mmc) mmc_free_host(mmc); @@ -1082,6 +1096,9 @@ static int imxmci_remove(struct platform_device *pdev) tasklet_kill(&host->tasklet); + clk_disable(host->clk); + clk_put(host->clk); + release_resource(host->res); mmc_free_host(mmc); diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 8d6cb74..9e2162e 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -184,6 +185,7 @@ struct imx_port { unsigned int old_status; int txirq,rxirq,rtsirq; int have_rtscts:1; + struct clk *clk; }; /* @@ -479,7 +481,8 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) * RFDIV is set such way to satisfy requested uartclk value */ val = TXTL << 10 | RXTL; - ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; + ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2) + / sport->port.uartclk; if(!ufcr_rfdiv) ufcr_rfdiv = 1; @@ -916,7 +919,7 @@ imx_console_get_options(struct imx_port *sport, int *baud, else ucfr_rfdiv = 6 - ucfr_rfdiv; - uartclk = imx_get_perclk1(); + uartclk = clk_get_rate(sport->clk); uartclk /= ucfr_rfdiv; { /* @@ -1054,7 +1057,15 @@ static int serial_imx_probe(struct platform_device *pdev) init_timer(&sport->timer); sport->timer.function = imx_timeout; sport->timer.data = (unsigned long)sport; - sport->port.uartclk = imx_get_perclk1(); + + sport->clk = clk_get(&pdev->dev, "uart_clk"); + if (IS_ERR(sport->clk)) { + ret = PTR_ERR(sport->clk); + goto unmap; + } + clk_enable(sport->clk); + + sport->port.uartclk = clk_get_rate(sport->clk); imx_ports[pdev->id] = sport; @@ -1069,6 +1080,8 @@ static int serial_imx_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &sport->port); return 0; +unmap: + iounmap(sport->port.membase); free: kfree(sport); @@ -1084,8 +1097,12 @@ static int serial_imx_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - if (sport) + if (sport) { uart_remove_one_port(&imx_reg, &sport->port); + clk_put(sport->clk); + } + + clk_disable(sport->clk); if (pdata->exit) pdata->exit(pdev); diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index c730d05..bd0729b 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -250,6 +251,8 @@ struct driver_data { int tx_dma_needs_unmap; size_t tx_map_len; u32 dummy_dma_buf ____cacheline_aligned; + + struct clk *clk; }; /* Runtime state */ @@ -855,15 +858,15 @@ static irqreturn_t spi_int(int irq, void *dev_id) return drv_data->transfer_handler(drv_data); } -static inline u32 spi_speed_hz(u32 data_rate) +static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate) { - return imx_get_perclk2() / (4 << ((data_rate) >> 13)); + return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13)); } -static u32 spi_data_rate(u32 speed_hz) +static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz) { u32 div; - u32 quantized_hz = imx_get_perclk2() >> 2; + u32 quantized_hz = clk_get_rate(drv_data->clk) >> 2; for (div = SPI_PERCLK2_DIV_MIN; div <= SPI_PERCLK2_DIV_MAX; @@ -947,7 +950,7 @@ static void pump_transfers(unsigned long data) tmp = transfer->speed_hz; if (tmp == 0) tmp = chip->max_speed_hz; - tmp = spi_data_rate(tmp); + tmp = spi_data_rate(drv_data, tmp); u32_EDIT(control, SPI_CONTROL_DATARATE, tmp); writel(control, regs + SPI_CONTROL); @@ -1109,7 +1112,7 @@ static int transfer(struct spi_device *spi, struct spi_message *msg) msg->actual_length = 0; /* Per transfer setup check */ - min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN); + min_speed_hz = spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN); max_speed_hz = spi->max_speed_hz; list_for_each_entry(trans, &msg->transfers, transfer_list) { tmp = trans->bits_per_word; @@ -1176,6 +1179,7 @@ msg_rejected: applied and notified to the calling driver. */ static int setup(struct spi_device *spi) { + struct driver_data *drv_data = spi_master_get_devdata(spi->master); struct spi_imx_chip *chip_info; struct chip_data *chip; int first_setup = 0; @@ -1304,14 +1308,14 @@ static int setup(struct spi_device *spi) chip->n_bytes = (tmp <= 8) ? 1 : 2; /* SPI datarate */ - tmp = spi_data_rate(spi->max_speed_hz); + tmp = spi_data_rate(drv_data, spi->max_speed_hz); if (tmp == SPI_CONTROL_DATARATE_BAD) { status = -EINVAL; dev_err(&spi->dev, "setup - " "HW min speed (%d Hz) exceeds required " "max speed (%d Hz)\n", - spi_speed_hz(SPI_CONTROL_DATARATE_MIN), + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), spi->max_speed_hz); if (first_setup) goto err_first_setup; @@ -1321,7 +1325,7 @@ static int setup(struct spi_device *spi) } else { u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp); /* Actual rounded max_speed_hz */ - tmp = spi_speed_hz(tmp); + tmp = spi_speed_hz(drv_data, tmp); spi->max_speed_hz = tmp; chip->max_speed_hz = tmp; } @@ -1352,7 +1356,7 @@ static int setup(struct spi_device *spi) chip->period & SPI_PERIOD_WAIT, spi->mode, spi->bits_per_word, - spi_speed_hz(SPI_CONTROL_DATARATE_MIN), + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), spi->max_speed_hz); return status; @@ -1465,6 +1469,14 @@ static int __init spi_imx_probe(struct platform_device *pdev) goto err_no_pdata; } + drv_data->clk = clk_get(&pdev->dev, "perclk2"); + if (IS_ERR(drv_data->clk)) { + dev_err(&pdev->dev, "probe - cannot get get\n"); + status = PTR_ERR(drv_data->clk); + goto err_no_clk; + } + clk_enable(drv_data->clk); + /* Allocate master with space for drv_data */ master = spi_alloc_master(dev, sizeof(struct driver_data)); if (!master) { @@ -1623,6 +1635,9 @@ err_no_iores: spi_master_put(master); err_no_pdata: + clk_disable(drv_data->clk); + clk_put(drv_data->clk); +err_no_clk: err_no_mem: return status; } @@ -1662,6 +1677,9 @@ static int __exit spi_imx_remove(struct platform_device *pdev) if (irq >= 0) free_irq(irq, drv_data); + clk_disable(drv_data->clk); + clk_put(drv_data->clk); + /* Release map resources */ iounmap(drv_data->regs); release_resource(drv_data->ioarea); diff --git a/include/asm-arm/arch-imx/hardware.h b/include/asm-arm/arch-imx/hardware.h index adffb6a..6542ca5 100644 --- a/include/asm-arm/arch-imx/hardware.h +++ b/include/asm-arm/arch-imx/hardware.h @@ -73,14 +73,6 @@ */ extern void imx_gpio_mode( int gpio_mode ); -/* get frequencies in Hz */ -extern unsigned int imx_get_system_clk(void); -extern unsigned int imx_get_mcu_clk(void); -extern unsigned int imx_get_perclk1(void); /* UART[12], Timer[12], PWM */ -extern unsigned int imx_get_perclk2(void); /* LCD, SD, SPI[12] */ -extern unsigned int imx_get_perclk3(void); /* SSI */ -extern unsigned int imx_get_hclk(void); /* SDRAM, CSI, Memory Stick,*/ - /* I2C, DMA */ #endif #define MAXIRQNUM 62 -- cgit v0.10.2 From c0db2ea4e366c94dd3f880928c02534156e3d1b9 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:47 +0200 Subject: MXC family: Add clock handling Internal clock path handling for the mxc CPUs. Changed against the original Freescale code (and against clocklib for example): - clock rate is always calculated whenever one ask for the current rate (means struct clk has no more a member called "rate"). So switching the PLL base frequency will propagate immediately to all other clocks that are depending on this frequency. Signed-off-by: Juergen Beisert diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index f96dc03..3eb181c 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := irq.o +obj-y := irq.o clock.o diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c new file mode 100644 index 0000000..1aa86fd --- /dev/null +++ b/arch/arm/plat-mxc/clock.c @@ -0,0 +1,331 @@ +/* + * Based on arch/arm/plat-omap/clock.c + * + * Copyright (C) 2004 - 2005 Nokia corporation + * Written by Tuukka Tikkanen + * Modified for omap shared clock framework by Tony Lindgren + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* #define DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +/*------------------------------------------------------------------------- + * Standard clock functions defined in include/linux/clk.h + *-------------------------------------------------------------------------*/ + +/* + * Retrieve a clock by name. + * + * Note that we first try to use device id on the bus + * and clock name. If this fails, we try to use ".". If this fails, + * we try to use clock name only. + * The reference count to the clock's module owner ref count is incremented. + */ +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + int idno; + const char *str; + + if (id == NULL) + return clk; + + if (dev == NULL || dev->bus != &platform_bus_type) + idno = -1; + else + idno = to_platform_device(dev)->id; + + mutex_lock(&clocks_mutex); + + list_for_each_entry(p, &clocks, node) { + if (p->id == idno && + strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + goto found; + } + } + + str = strrchr(id, '.'); + if (str) { + int cnt = str - id; + str++; + idno = simple_strtol(str, NULL, 10); + list_for_each_entry(p, &clocks, node) { + if (p->id == idno && + strlen(p->name) == cnt && + strncmp(id, p->name, cnt) == 0 && + try_module_get(p->owner)) { + clk = p; + goto found; + } + } + } + + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + goto found; + } + } + + printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id); + +found: + mutex_unlock(&clocks_mutex); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +static void __clk_disable(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + __clk_disable(clk->parent); + __clk_disable(clk->secondary); + + if (!(--clk->usecount) && clk->disable) + clk->disable(clk); +} + +static int __clk_enable(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + __clk_enable(clk->parent); + __clk_enable(clk->secondary); + + if (clk->usecount++ == 0 && clk->enable) + clk->enable(clk); + + return 0; +} + +/* This function increments the reference count on the clock and enables the + * clock if not already enabled. The parent clock tree is recursively enabled + */ +int clk_enable(struct clk *clk) +{ + int ret = 0; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + ret = __clk_enable(clk); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL(clk_enable); + +/* This function decrements the reference count on the clock and disables + * the clock when reference count is 0. The parent clock tree is + * recursively disabled + */ +void clk_disable(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + mutex_lock(&clocks_mutex); + __clk_disable(clk); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clk_disable); + +/* Retrieve the *current* clock rate. If the clock itself + * does not provide a special calculation routine, ask + * its parent and so on, until one is able to return + * a valid clock rate + */ +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return 0UL; + + if (clk->get_rate) + return clk->get_rate(clk); + + return clk_get_rate(clk->parent); +} +EXPORT_SYMBOL(clk_get_rate); + +/* Decrement the clock's module reference count */ +void clk_put(struct clk *clk) +{ + if (clk && !IS_ERR(clk)) + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +/* Round the requested clock rate to the nearest supported + * rate that is less than or equal to the requested rate. + * This is dependent on the clock's current parent. + */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (clk == NULL || IS_ERR(clk) || !clk->round_rate) + return 0; + + return clk->round_rate(clk, rate); +} +EXPORT_SYMBOL(clk_round_rate); + +/* Set the clock to the requested clock rate. The rate must + * match a supported rate exactly based on what clk_round_rate returns + */ +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EINVAL; + + if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0) + return ret; + + mutex_lock(&clocks_mutex); + ret = clk->set_rate(clk, rate); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +/* Set the clock's parent to another clock source */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + int ret = -EINVAL; + + if (clk == NULL || IS_ERR(clk) || parent == NULL || + IS_ERR(parent) || clk->set_parent == NULL) + return ret; + + mutex_lock(&clocks_mutex); + ret = clk->set_parent(clk, parent); + if (ret == 0) + clk->parent = parent; + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL(clk_set_parent); + +/* Retrieve the clock's parent clock source */ +struct clk *clk_get_parent(struct clk *clk) +{ + struct clk *ret = NULL; + + if (clk == NULL || IS_ERR(clk)) + return ret; + + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +/* + * Add a new clock to the clock tree. + */ +int clk_register(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + list_add(&clk->node, &clocks); + mutex_unlock(&clocks_mutex); + + return 0; +} +EXPORT_SYMBOL(clk_register); + +/* Remove a clock from the clock tree */ +void clk_unregister(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + mutex_lock(&clocks_mutex); + list_del(&clk->node); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clk_unregister); + +#ifdef CONFIG_PROC_FS +static int mxc_clock_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct clk *clkp; + char *p = page; + int len; + + list_for_each_entry(clkp, &clocks, node) { + p += sprintf(p, "%s-%d:\t\t%lu, %d", clkp->name, clkp->id, + clk_get_rate(clkp), clkp->usecount); + if (clkp->parent) + p += sprintf(p, ", %s-%d\n", clkp->parent->name, + clkp->parent->id); + else + p += sprintf(p, "\n"); + } + + len = (p - page) - off; + if (len < 0) + len = 0; + + *eof = (len <= count) ? 1 : 0; + *start = page + off; + + return len; +} + +static int __init mxc_setup_proc_entry(void) +{ + struct proc_dir_entry *res; + + res = create_proc_read_entry("cpu/clocks", 0, NULL, + mxc_clock_read_proc, NULL); + if (!res) { + printk(KERN_ERR "Failed to create proc/cpu/clocks\n"); + return -ENOMEM; + } + return 0; +} + +late_initcall(mxc_setup_proc_entry); +#endif diff --git a/include/asm-arm/arch-mxc/clock.h b/include/asm-arm/arch-mxc/clock.h new file mode 100644 index 0000000..24caa2b --- /dev/null +++ b/include/asm-arm/arch-mxc/clock.h @@ -0,0 +1,67 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_CLOCK_H__ +#define __ASM_ARCH_MXC_CLOCK_H__ + +#ifndef __ASSEMBLY__ +#include + +struct module; + +struct clk { + struct list_head node; + struct module *owner; + const char *name; + int id; + /* Source clock this clk depends on */ + struct clk *parent; + /* Secondary clock to enable/disable with this clock */ + struct clk *secondary; + /* Reference count of clock enable/disable */ + __s8 usecount; + /* Register bit position for clock's enable/disable control. */ + u8 enable_shift; + /* Register address for clock's enable/disable control. */ + u32 enable_reg; + u32 flags; + /* get the current clock rate (always a fresh value) */ + unsigned long (*get_rate) (struct clk *); + /* Function ptr to set the clock to a new rate. The rate must match a + supported rate returned from round_rate. Leave blank if clock is not + programmable */ + int (*set_rate) (struct clk *, unsigned long); + /* Function ptr to round the requested clock rate to the nearest + supported rate that is less than or equal to the requested rate. */ + unsigned long (*round_rate) (struct clk *, unsigned long); + /* Function ptr to enable the clock. Leave blank if clock can not + be gated. */ + int (*enable) (struct clk *); + /* Function ptr to disable the clock. Leave blank if clock can not + be gated. */ + void (*disable) (struct clk *); + /* Function ptr to set the parent clock of the clock. */ + int (*set_parent) (struct clk *, struct clk *); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_ARCH_MXC_CLOCK_H__ */ -- cgit v0.10.2 From df1bf4bdb2a3a26d4bde8ae1aefc16385dd4898f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: i.MX3: introduce clock API This patch introduces the clock API for for arch-mxc Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index cbec997..febb37f 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o +obj-y := mm.o time.o clock.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c new file mode 100644 index 0000000..2f36359 --- /dev/null +++ b/arch/arm/mach-mx3/clock.c @@ -0,0 +1,1147 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crm_regs.h" + +#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ + +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) +{ + u32 min_pre, temp_pre, old_err, err; + + if (div >= 512) { + *pre = 8; + *post = 64; + } else if (div >= 64) { + min_pre = (div - 1) / 64 + 1; + old_err = 8; + for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { + err = div % temp_pre; + if (err == 0) { + *pre = temp_pre; + break; + } + err = temp_pre - err; + if (err < old_err) { + old_err = err; + *pre = temp_pre; + } + } + *post = (div + *pre - 1) / *pre; + } else if (div <= 8) { + *pre = div; + *post = 1; + } else { + *pre = 1; + *post = div; + } +} + +static struct clk mcu_pll_clk; +static struct clk mcu_main_clk; +static struct clk usb_pll_clk; +static struct clk serial_pll_clk; +static struct clk ipg_clk; +static struct clk ckih_clk; +static struct clk ahb_clk; + +static int _clk_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg |= 3 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + + return 0; +} + +static void _clk_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(3 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static void _clk_emi_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(3 << clk->enable_shift); + reg |= (1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + signed long pd = 1; /* Pre-divider */ + signed long mfi; /* Multiplication Factor (Integer part) */ + signed long mfn; /* Multiplication Factor (Integer part) */ + signed long mfd; /* Multiplication Factor (Denominator Part) */ + signed long tmp; + u32 ref_freq = clk_get_rate(clk->parent); + + while (((ref_freq / pd) * 10) > rate) + pd++; + + if ((ref_freq / pd) < PRE_DIV_MIN_FREQ) + return -EINVAL; + + /* the ref_freq/2 in the following is to round up */ + mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; + if (mfi < 5 || mfi > 15) + return -EINVAL; + + /* pick a mfd value that will work + * then solve for mfn */ + mfd = ref_freq / 50000; + + /* + * pll_freq * pd * mfd + * mfn = -------------------- - (mfi * mfd) + * 2 * ref_freq + */ + /* the tmp/2 is for rounding */ + tmp = ref_freq / 10000; + mfn = + ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - + (mfi * mfd); + + mfn = mfn & 0x3ff; + pd--; + mfd--; + + /* Change the Pll value */ + reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) | + (mfn << MXC_CCM_PCTL_MFN_OFFSET) | + (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET); + + if (clk == &mcu_pll_clk) + __raw_writel(reg, MXC_CCM_MPCTL); + else if (clk == &usb_pll_clk) + __raw_writel(reg, MXC_CCM_UPCTL); + else if (clk == &serial_pll_clk) + __raw_writel(reg, MXC_CCM_SRPCTL); + + return 0; +} + +static unsigned long _clk_pll_get_rate(struct clk *clk) +{ + long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; + unsigned long reg, ccmr; + s64 temp; + unsigned int prcs; + + ccmr = __raw_readl(MXC_CCM_CCMR); + prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; + if (prcs == 0x1) + ref_clk = CKIL_CLK_FREQ * 1024; + else + ref_clk = clk_get_rate(&ckih_clk); + + if (clk == &mcu_pll_clk) { + if ((ccmr & MXC_CCM_CCMR_MPE) == 0) + return ref_clk; + if ((ccmr & MXC_CCM_CCMR_MDS) != 0) + return ref_clk; + reg = __raw_readl(MXC_CCM_MPCTL); + } else if (clk == &usb_pll_clk) + reg = __raw_readl(MXC_CCM_UPCTL); + else if (clk == &serial_pll_clk) + reg = __raw_readl(MXC_CCM_SRPCTL); + else { + BUG(); + return 0; + } + + pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET; + mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET; + mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET; + mfi = (mfi <= 5) ? 5 : mfi; + mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK; + + if (mfn >= 0x200) { + mfn |= 0xFFFFFE00; + mfn_abs = -mfn; + } + + ref_clk *= 2; + ref_clk /= pdf + 1; + + temp = (u64) ref_clk * mfn_abs; + do_div(temp, mfd + 1); + if (mfn < 0) + temp = -temp; + temp = (ref_clk * mfi) + temp; + + return temp; +} + +static int _clk_usb_pll_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg |= MXC_CCM_CCMR_UPE; + __raw_writel(reg, MXC_CCM_CCMR); + + /* No lock bit on MX31, so using max time from spec */ + udelay(80); + + return 0; +} + +static void _clk_usb_pll_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg &= ~MXC_CCM_CCMR_UPE; + __raw_writel(reg, MXC_CCM_CCMR); +} + +static int _clk_serial_pll_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg |= MXC_CCM_CCMR_SPE; + __raw_writel(reg, MXC_CCM_CCMR); + + /* No lock bit on MX31, so using max time from spec */ + udelay(80); + + return 0; +} + +static void _clk_serial_pll_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg &= ~MXC_CCM_CCMR_SPE; + __raw_writel(reg, MXC_CCM_CCMR); +} + +#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off) +#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) +#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) + +static unsigned long _clk_mcu_main_get_rate(struct clk *clk) +{ + u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); + + if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) + return clk_get_rate(&serial_pll_clk); + else + return clk_get_rate(&mcu_pll_clk); +} + +static unsigned long _clk_hclk_get_rate(struct clk *clk) +{ + unsigned long max_pdf; + + max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK, + MXC_CCM_PDR0_MAX_PODF_OFFSET); + return clk_get_rate(clk->parent) / (max_pdf + 1); +} + +static unsigned long _clk_ipg_get_rate(struct clk *clk) +{ + unsigned long ipg_pdf; + + ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK, + MXC_CCM_PDR0_IPG_PODF_OFFSET); + return clk_get_rate(clk->parent) / (ipg_pdf + 1); +} + +static unsigned long _clk_nfc_get_rate(struct clk *clk) +{ + unsigned long nfc_pdf; + + nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK, + MXC_CCM_PDR0_NFC_PODF_OFFSET); + return clk_get_rate(clk->parent) / (nfc_pdf + 1); +} + +static unsigned long _clk_hsp_get_rate(struct clk *clk) +{ + unsigned long hsp_pdf; + + hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK, + MXC_CCM_PDR0_HSP_PODF_OFFSET); + return clk_get_rate(clk->parent) / (hsp_pdf + 1); +} + +static unsigned long _clk_usb_get_rate(struct clk *clk) +{ + unsigned long usb_pdf, usb_prepdf; + + usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK, + MXC_CCM_PDR1_USB_PODF_OFFSET); + usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK, + MXC_CCM_PDR1_USB_PRDF_OFFSET); + return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); +} + +static unsigned long _clk_csi_get_rate(struct clk *clk) +{ + u32 reg, pre, post; + + reg = __raw_readl(MXC_CCM_PDR0); + pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >> + MXC_CCM_PDR0_CSI_PRDF_OFFSET; + pre++; + post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >> + MXC_CCM_PDR0_CSI_PODF_OFFSET; + post++; + return clk_get_rate(clk->parent) / (pre * post); +} + +static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) +{ + u32 pre, post, parent = clk_get_rate(clk->parent); + u32 div = parent / rate; + + if (parent % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return parent / (pre * post); +} + +static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if ((parent / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set CSI clock divider */ + reg = __raw_readl(MXC_CCM_PDR0) & + ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK); + reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET; + __raw_writel(reg, MXC_CCM_PDR0); + + return 0; +} + +static unsigned long _clk_per_get_rate(struct clk *clk) +{ + unsigned long per_pdf; + + per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK, + MXC_CCM_PDR0_PER_PODF_OFFSET); + return clk_get_rate(clk->parent) / (per_pdf + 1); +} + +static unsigned long _clk_ssi1_get_rate(struct clk *clk) +{ + unsigned long ssi1_pdf, ssi1_prepdf; + + ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK, + MXC_CCM_PDR1_SSI1_PODF_OFFSET); + ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK, + MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET); + return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); +} + +static unsigned long _clk_ssi2_get_rate(struct clk *clk) +{ + unsigned long ssi2_pdf, ssi2_prepdf; + + ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK, + MXC_CCM_PDR1_SSI2_PODF_OFFSET); + ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK, + MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET); + return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); +} + +static unsigned long _clk_firi_get_rate(struct clk *clk) +{ + unsigned long firi_pdf, firi_prepdf; + + firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK, + MXC_CCM_PDR1_FIRI_PODF_OFFSET); + firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK, + MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET); + return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); +} + +static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) +{ + u32 pre, post; + u32 parent = clk_get_rate(clk->parent); + u32 div = parent / rate; + + if (parent % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return parent / (pre * post); + +} + +static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if ((parent / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set FIRI clock divider */ + reg = __raw_readl(MXC_CCM_PDR1) & + ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK); + reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET; + reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_PDR1); + + return 0; +} + +static unsigned long _clk_mbx_get_rate(struct clk *clk) +{ + return clk_get_rate(clk->parent) / 2; +} + +static unsigned long _clk_mstick1_get_rate(struct clk *clk) +{ + unsigned long msti_pdf; + + msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK, + MXC_CCM_PDR2_MST1_PDF_OFFSET); + return clk_get_rate(clk->parent) / (msti_pdf + 1); +} + +static unsigned long _clk_mstick2_get_rate(struct clk *clk) +{ + unsigned long msti_pdf; + + msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK, + MXC_CCM_PDR2_MST2_PDF_OFFSET); + return clk_get_rate(clk->parent) / (msti_pdf + 1); +} + +static unsigned long ckih_rate; + +static unsigned long clk_ckih_get_rate(struct clk *clk) +{ + return ckih_rate; +} + +static struct clk ckih_clk = { + .name = "ckih", + .get_rate = clk_ckih_get_rate, +}; + +static unsigned long clk_ckil_get_rate(struct clk *clk) +{ + return CKIL_CLK_FREQ; +} + +static struct clk ckil_clk = { + .name = "ckil", + .get_rate = clk_ckil_get_rate, +}; + +static struct clk mcu_pll_clk = { + .name = "mcu_pll", + .parent = &ckih_clk, + .set_rate = _clk_pll_set_rate, + .get_rate = _clk_pll_get_rate, +}; + +static struct clk mcu_main_clk = { + .name = "mcu_main_clk", + .parent = &mcu_pll_clk, + .get_rate = _clk_mcu_main_get_rate, +}; + +static struct clk serial_pll_clk = { + .name = "serial_pll", + .parent = &ckih_clk, + .set_rate = _clk_pll_set_rate, + .get_rate = _clk_pll_get_rate, + .enable = _clk_serial_pll_enable, + .disable = _clk_serial_pll_disable, +}; + +static struct clk usb_pll_clk = { + .name = "usb_pll", + .parent = &ckih_clk, + .set_rate = _clk_pll_set_rate, + .get_rate = _clk_pll_get_rate, + .enable = _clk_usb_pll_enable, + .disable = _clk_usb_pll_disable, +}; + +static struct clk ahb_clk = { + .name = "ahb_clk", + .parent = &mcu_main_clk, + .get_rate = _clk_hclk_get_rate, +}; + +static struct clk per_clk = { + .name = "per_clk", + .parent = &usb_pll_clk, + .get_rate = _clk_per_get_rate, +}; + +static struct clk perclk_clk = { + .name = "perclk_clk", + .parent = &ipg_clk, +}; + +static struct clk cspi_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET, + .disable = _clk_disable,}, + { + .name = "cspi_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET, + .disable = _clk_disable,}, + { + .name = "cspi_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .get_rate = _clk_ipg_get_rate, +}; + +static struct clk emi_clk = { + .name = "emi_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_EMI_OFFSET, + .disable = _clk_emi_disable, +}; + +static struct clk gpt_clk = { + .name = "gpt_clk", + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_GPT_OFFSET, + .disable = _clk_disable, +}; + +static struct clk pwm_clk = { + .name = "pwm_clk", + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR1_PWM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk epit_clk[] = { + { + .name = "epit_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET, + .disable = _clk_disable,}, + { + .name = "epit_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk nfc_clk = { + .name = "nfc_clk", + .parent = &ahb_clk, + .get_rate = _clk_nfc_get_rate, +}; + +static struct clk scc_clk = { + .name = "scc_clk", + .parent = &ipg_clk, +}; + +static struct clk ipu_clk = { + .name = "ipu_clk", + .parent = &mcu_main_clk, + .get_rate = _clk_hsp_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_IPU_OFFSET, + .disable = _clk_disable, +}; + +static struct clk kpp_clk = { + .name = "kpp_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_KPP_OFFSET, + .disable = _clk_disable, +}; + +static struct clk wdog_clk = { + .name = "wdog_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET, + .disable = _clk_disable, +}; +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_RTC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk usb_clk[] = { + { + .name = "usb_clk", + .parent = &usb_pll_clk, + .get_rate = _clk_usb_get_rate,}, + { + .name = "usb_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk csi_clk = { + .name = "csi_clk", + .parent = &serial_pll_clk, + .get_rate = _clk_csi_get_rate, + .round_rate = _clk_csi_round_rate, + .set_rate = _clk_csi_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_CSI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk uart_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_UART1_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_UART2_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 2, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART3_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 3, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART4_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 4, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART5_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 2, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk owire_clk = { + .name = "owire_clk", + .parent = &perclk_clk, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk sdhc_clk[] = { + { + .name = "sdhc_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET, + .disable = _clk_disable,}, + { + .name = "sdhc_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk ssi_clk[] = { + { + .name = "ssi_clk", + .parent = &serial_pll_clk, + .get_rate = _clk_ssi1_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET, + .disable = _clk_disable,}, + { + .name = "ssi_clk", + .id = 1, + .parent = &serial_pll_clk, + .get_rate = _clk_ssi2_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk firi_clk = { + .name = "firi_clk", + .parent = &usb_pll_clk, + .round_rate = _clk_firi_round_rate, + .set_rate = _clk_firi_set_rate, + .get_rate = _clk_firi_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk ata_clk = { + .name = "ata_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_ATA_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mbx_clk = { + .name = "mbx_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, + .get_rate = _clk_mbx_get_rate, +}; + +static struct clk vpu_clk = { + .name = "vpu_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, + .get_rate = _clk_mbx_get_rate, +}; + +static struct clk rtic_clk = { + .name = "rtic_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rng_clk = { + .name = "rng_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_RNG_OFFSET, + .disable = _clk_disable, +}; + +static struct clk sdma_clk[] = { + { + .name = "sdma_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET, + .disable = _clk_disable,}, + { + .name = "sdma_ipg_clk", + .parent = &ipg_clk,} +}; + +static struct clk mpeg4_clk = { + .name = "mpeg4_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk vl2cc_clk = { + .name = "vl2cc_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mstick_clk[] = { + { + .name = "mstick_clk", + .id = 0, + .parent = &usb_pll_clk, + .get_rate = _clk_mstick1_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET, + .disable = _clk_disable,}, + { + .name = "mstick_clk", + .id = 1, + .parent = &usb_pll_clk, + .get_rate = _clk_mstick2_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk iim_clk = { + .name = "iim_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_IIM_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div, parent = clk_get_rate(clk->parent); + + div = parent / rate; + if (parent % rate) + div++; + + if (div > 8) + div = 16; + else if (div > 4) + div = 8; + else if (div > 2) + div = 4; + + return parent / div; +} + +static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if (div == 16) + div = 4; + else if (div == 8) + div = 3; + else if (div == 4) + div = 2; + else if (div == 2) + div = 1; + else if (div == 1) + div = 0; + else + return -EINVAL; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK; + reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET; + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static unsigned long _clk_cko1_get_rate(struct clk *clk) +{ + u32 div; + + div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >> + MXC_CCM_COSR_CLKOUTDIV_OFFSET; + + return clk_get_rate(clk->parent) / (1 << div); +} + +static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK; + + if (parent == &mcu_main_clk) + reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ipg_clk) + reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &usb_pll_clk) + reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == mcu_main_clk.parent) + reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ahb_clk) + reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &serial_pll_clk) + reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ckih_clk) + reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &emi_clk) + reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ipu_clk) + reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &nfc_clk) + reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &uart_clk[0]) + reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET; + else + return -EINVAL; + + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static int _clk_cko1_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN; + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static void _clk_cko1_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN; + __raw_writel(reg, MXC_CCM_COSR); +} + +static struct clk cko1_clk = { + .name = "cko1_clk", + .get_rate = _clk_cko1_get_rate, + .set_rate = _clk_cko1_set_rate, + .round_rate = _clk_cko1_round_rate, + .set_parent = _clk_cko1_set_parent, + .enable = _clk_cko1_enable, + .disable = _clk_cko1_disable, +}; + +static struct clk *mxc_clks[] = { + &ckih_clk, + &ckil_clk, + &mcu_pll_clk, + &usb_pll_clk, + &serial_pll_clk, + &mcu_main_clk, + &ahb_clk, + &per_clk, + &perclk_clk, + &cko1_clk, + &emi_clk, + &cspi_clk[0], + &cspi_clk[1], + &cspi_clk[2], + &ipg_clk, + &gpt_clk, + &pwm_clk, + &wdog_clk, + &rtc_clk, + &epit_clk[0], + &epit_clk[1], + &nfc_clk, + &ipu_clk, + &kpp_clk, + &usb_clk[0], + &usb_clk[1], + &csi_clk, + &uart_clk[0], + &uart_clk[1], + &uart_clk[2], + &uart_clk[3], + &uart_clk[4], + &i2c_clk[0], + &i2c_clk[1], + &i2c_clk[2], + &owire_clk, + &sdhc_clk[0], + &sdhc_clk[1], + &ssi_clk[0], + &ssi_clk[1], + &firi_clk, + &ata_clk, + &rtic_clk, + &rng_clk, + &sdma_clk[0], + &sdma_clk[1], + &mstick_clk[0], + &mstick_clk[1], + &scc_clk, + &iim_clk, +}; + +int __init mxc_clocks_init(unsigned long fref) +{ + u32 reg; + struct clk **clkp; + + ckih_rate = fref; + + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) + clk_register(*clkp); + + if (cpu_is_mx31()) { + clk_register(&mpeg4_clk); + clk_register(&mbx_clk); + } else { + clk_register(&vpu_clk); + clk_register(&vl2cc_clk); + } + + /* Turn off all possible clocks */ + __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0); + __raw_writel(0, MXC_CCM_CGR1); + + __raw_writel(MXC_CCM_CGR2_EMI_MASK | + MXC_CCM_CGR2_IPMUX1_MASK | + MXC_CCM_CGR2_IPMUX2_MASK | + MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */ + MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */ + MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */ + 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for + MX32, but still required to be set */ + MXC_CCM_CGR2); + + clk_disable(&cko1_clk); + clk_disable(&usb_pll_clk); + + pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); + + clk_enable(&gpt_clk); + clk_enable(&emi_clk); + clk_enable(&iim_clk); + + clk_enable(&serial_pll_clk); + + if (mx31_revision() >= CHIP_REV_2_0) { + reg = __raw_readl(MXC_CCM_PMCR1); + /* No PLL restart on DVFS switch; enable auto EMI handshake */ + reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN; + __raw_writel(reg, MXC_CCM_PMCR1); + } + + return 0; +} + diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h new file mode 100644 index 0000000..4a0e0ed --- /dev/null +++ b/arch/arm/mach-mx3/crm_regs.h @@ -0,0 +1,401 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__ + +#define CKIH_CLK_FREQ 26000000 +#define CKIH_CLK_FREQ_27MHZ 27000000 +#define CKIL_CLK_FREQ 32768 + +#define MXC_CCM_BASE IO_ADDRESS(CCM_BASE_ADDR) + +/* Register addresses */ +#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) +#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04) +#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08) +#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C) +#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10) +#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14) +#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18) +#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C) +#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20) +#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24) +#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28) +#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C) +#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30) +#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34) +#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38) +#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C) +#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40) +#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44) +#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48) +#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C) +#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50) +#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54) +#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58) +#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C) +#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60) +#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64) + +/* Register bit definitions */ +#define MXC_CCM_CCMR_WBEN (1 << 27) +#define MXC_CCM_CCMR_CSCS (1 << 25) +#define MXC_CCM_CCMR_PERCS (1 << 24) +#define MXC_CCM_CCMR_SSI1S_OFFSET 18 +#define MXC_CCM_CCMR_SSI1S_MASK (0x3 << 18) +#define MXC_CCM_CCMR_SSI2S_OFFSET 21 +#define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21) +#define MXC_CCM_CCMR_LPM_OFFSET 14 +#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14) +#define MXC_CCM_CCMR_FIRS_OFFSET 11 +#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11) +#define MXC_CCM_CCMR_UPE (1 << 9) +#define MXC_CCM_CCMR_SPE (1 << 8) +#define MXC_CCM_CCMR_MDS (1 << 7) +#define MXC_CCM_CCMR_SBYCS (1 << 4) +#define MXC_CCM_CCMR_MPE (1 << 3) +#define MXC_CCM_CCMR_PRCS_OFFSET 1 +#define MXC_CCM_CCMR_PRCS_MASK (0x3 << 1) + +#define MXC_CCM_PDR0_CSI_PODF_OFFSET 26 +#define MXC_CCM_PDR0_CSI_PODF_MASK (0x3F << 26) +#define MXC_CCM_PDR0_CSI_PRDF_OFFSET 23 +#define MXC_CCM_PDR0_CSI_PRDF_MASK (0x7 << 23) +#define MXC_CCM_PDR0_PER_PODF_OFFSET 16 +#define MXC_CCM_PDR0_PER_PODF_MASK (0x1F << 16) +#define MXC_CCM_PDR0_HSP_PODF_OFFSET 11 +#define MXC_CCM_PDR0_HSP_PODF_MASK (0x7 << 11) +#define MXC_CCM_PDR0_NFC_PODF_OFFSET 8 +#define MXC_CCM_PDR0_NFC_PODF_MASK (0x7 << 8) +#define MXC_CCM_PDR0_IPG_PODF_OFFSET 6 +#define MXC_CCM_PDR0_IPG_PODF_MASK (0x3 << 6) +#define MXC_CCM_PDR0_MAX_PODF_OFFSET 3 +#define MXC_CCM_PDR0_MAX_PODF_MASK (0x7 << 3) +#define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 +#define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 + +#define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11) +#define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11) +#define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11) +#define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11) +#define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11) +#define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11) +#define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11) +#define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11) + +#define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6) +#define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6) +#define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6) +#define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6) + +#define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3) +#define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3) +#define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3) +#define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3) +#define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3) +#define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3) +#define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3) +#define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3) + +#define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8) +#define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8) +#define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8) +#define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8) +#define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8) +#define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8) +#define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8) +#define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8) + +#define MXC_CCM_PDR0_MCU_DIV_1 0x0 +#define MXC_CCM_PDR0_MCU_DIV_2 0x1 +#define MXC_CCM_PDR0_MCU_DIV_3 0x2 +#define MXC_CCM_PDR0_MCU_DIV_4 0x3 +#define MXC_CCM_PDR0_MCU_DIV_5 0x4 +#define MXC_CCM_PDR0_MCU_DIV_6 0x5 +#define MXC_CCM_PDR0_MCU_DIV_7 0x6 +#define MXC_CCM_PDR0_MCU_DIV_8 0x7 + +#define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 +#define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) +#define MXC_CCM_PDR1_USB_PODF_OFFSET 27 +#define MXC_CCM_PDR1_USB_PODF_MASK (0x7 << 27) +#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET 24 +#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK (0x7 << 24) +#define MXC_CCM_PDR1_FIRI_PODF_OFFSET 18 +#define MXC_CCM_PDR1_FIRI_PODF_MASK (0x3F << 18) +#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET 15 +#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK (0x7 << 15) +#define MXC_CCM_PDR1_SSI2_PODF_OFFSET 9 +#define MXC_CCM_PDR1_SSI2_PODF_MASK (0x3F << 9) +#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET 6 +#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK (0x7 << 6) +#define MXC_CCM_PDR1_SSI1_PODF_OFFSET 0 +#define MXC_CCM_PDR1_SSI1_PODF_MASK 0x3F + +/* Bit definitions for RCSR */ +#define MXC_CCM_RCSR_NF16B 0x80000000 + +/* Bit definitions for both MCU, USB and SR PLL control registers */ +#define MXC_CCM_PCTL_BRM 0x80000000 +#define MXC_CCM_PCTL_PD_OFFSET 26 +#define MXC_CCM_PCTL_PD_MASK (0xF << 26) +#define MXC_CCM_PCTL_MFD_OFFSET 16 +#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16) +#define MXC_CCM_PCTL_MFI_OFFSET 10 +#define MXC_CCM_PCTL_MFI_MASK (0xF << 10) +#define MXC_CCM_PCTL_MFN_OFFSET 0 +#define MXC_CCM_PCTL_MFN_MASK 0x3FF + +#define MXC_CCM_CGR0_SD_MMC1_OFFSET 0 +#define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0) +#define MXC_CCM_CGR0_SD_MMC2_OFFSET 2 +#define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2) +#define MXC_CCM_CGR0_GPT_OFFSET 4 +#define MXC_CCM_CGR0_GPT_MASK (0x3 << 4) +#define MXC_CCM_CGR0_EPIT1_OFFSET 6 +#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6) +#define MXC_CCM_CGR0_EPIT2_OFFSET 8 +#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8) +#define MXC_CCM_CGR0_IIM_OFFSET 10 +#define MXC_CCM_CGR0_IIM_MASK (0x3 << 10) +#define MXC_CCM_CGR0_ATA_OFFSET 12 +#define MXC_CCM_CGR0_ATA_MASK (0x3 << 12) +#define MXC_CCM_CGR0_SDMA_OFFSET 14 +#define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14) +#define MXC_CCM_CGR0_CSPI3_OFFSET 16 +#define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16) +#define MXC_CCM_CGR0_RNG_OFFSET 18 +#define MXC_CCM_CGR0_RNG_MASK (0x3 << 18) +#define MXC_CCM_CGR0_UART1_OFFSET 20 +#define MXC_CCM_CGR0_UART1_MASK (0x3 << 20) +#define MXC_CCM_CGR0_UART2_OFFSET 22 +#define MXC_CCM_CGR0_UART2_MASK (0x3 << 22) +#define MXC_CCM_CGR0_SSI1_OFFSET 24 +#define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24) +#define MXC_CCM_CGR0_I2C1_OFFSET 26 +#define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26) +#define MXC_CCM_CGR0_I2C2_OFFSET 28 +#define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28) +#define MXC_CCM_CGR0_I2C3_OFFSET 30 +#define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30) + +#define MXC_CCM_CGR1_HANTRO_OFFSET 0 +#define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0) +#define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2 +#define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2) +#define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4 +#define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4) +#define MXC_CCM_CGR1_CSI_OFFSET 6 +#define MXC_CCM_CGR1_CSI_MASK (0x3 << 6) +#define MXC_CCM_CGR1_RTC_OFFSET 8 +#define MXC_CCM_CGR1_RTC_MASK (0x3 << 8) +#define MXC_CCM_CGR1_WDOG_OFFSET 10 +#define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10) +#define MXC_CCM_CGR1_PWM_OFFSET 12 +#define MXC_CCM_CGR1_PWM_MASK (0x3 << 12) +#define MXC_CCM_CGR1_SIM_OFFSET 14 +#define MXC_CCM_CGR1_SIM_MASK (0x3 << 14) +#define MXC_CCM_CGR1_ECT_OFFSET 16 +#define MXC_CCM_CGR1_ECT_MASK (0x3 << 16) +#define MXC_CCM_CGR1_USBOTG_OFFSET 18 +#define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18) +#define MXC_CCM_CGR1_KPP_OFFSET 20 +#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20) +#define MXC_CCM_CGR1_IPU_OFFSET 22 +#define MXC_CCM_CGR1_IPU_MASK (0x3 << 22) +#define MXC_CCM_CGR1_UART3_OFFSET 24 +#define MXC_CCM_CGR1_UART3_MASK (0x3 << 24) +#define MXC_CCM_CGR1_UART4_OFFSET 26 +#define MXC_CCM_CGR1_UART4_MASK (0x3 << 26) +#define MXC_CCM_CGR1_UART5_OFFSET 28 +#define MXC_CCM_CGR1_UART5_MASK (0x3 << 28) +#define MXC_CCM_CGR1_OWIRE_OFFSET 30 +#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30) + +#define MXC_CCM_CGR2_SSI2_OFFSET 0 +#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0) +#define MXC_CCM_CGR2_CSPI1_OFFSET 2 +#define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2) +#define MXC_CCM_CGR2_CSPI2_OFFSET 4 +#define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4) +#define MXC_CCM_CGR2_GACC_OFFSET 6 +#define MXC_CCM_CGR2_GACC_MASK (0x3 << 6) +#define MXC_CCM_CGR2_EMI_OFFSET 8 +#define MXC_CCM_CGR2_EMI_MASK (0x3 << 8) +#define MXC_CCM_CGR2_RTIC_OFFSET 10 +#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10) +#define MXC_CCM_CGR2_FIRI_OFFSET 12 +#define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12) +#define MXC_CCM_CGR2_IPMUX1_OFFSET 14 +#define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14) +#define MXC_CCM_CGR2_IPMUX2_OFFSET 16 +#define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16) + +/* These new CGR2 bits are added in MX32 */ +#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18 +#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18) +#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20 +#define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20) +#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22 +#define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22) +#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24 +#define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24) +#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25 +#define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25) +#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26 +#define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26) +#define MXC_CCM_CGR2_APMENA_OFFSET 30 +#define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30) + +/* + * LTR0 register offsets + */ +#define MXC_CCM_LTR0_DIV3CK_OFFSET 1 +#define MXC_CCM_LTR0_DIV3CK_MASK (0x3 << 1) +#define MXC_CCM_LTR0_DNTHR_OFFSET 16 +#define MXC_CCM_LTR0_DNTHR_MASK (0x3F << 16) +#define MXC_CCM_LTR0_UPTHR_OFFSET 22 +#define MXC_CCM_LTR0_UPTHR_MASK (0x3F << 22) + +/* + * LTR1 register offsets + */ +#define MXC_CCM_LTR1_PNCTHR_OFFSET 0 +#define MXC_CCM_LTR1_PNCTHR_MASK 0x3F +#define MXC_CCM_LTR1_UPCNT_OFFSET 6 +#define MXC_CCM_LTR1_UPCNT_MASK (0xFF << 6) +#define MXC_CCM_LTR1_DNCNT_OFFSET 14 +#define MXC_CCM_LTR1_DNCNT_MASK (0xFF << 14) +#define MXC_CCM_LTR1_LTBRSR_MASK 0x400000 +#define MXC_CCM_LTR1_LTBRSR_OFFSET 22 +#define MXC_CCM_LTR1_LTBRSR 0x400000 +#define MXC_CCM_LTR1_LTBRSH 0x800000 + +/* + * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15 + */ +#define MXC_CCM_LTR2_WSW_OFFSET(x) (11 + (x) * 3) +#define MXC_CCM_LTR2_WSW_MASK(x) (0x7 << \ + MXC_CCM_LTR2_WSW_OFFSET((x))) +#define MXC_CCM_LTR2_EMAC_OFFSET 0 +#define MXC_CCM_LTR2_EMAC_MASK 0x1FF + +/* + * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8 + */ +#define MXC_CCM_LTR3_WSW_OFFSET(x) (5 + (x) * 3) +#define MXC_CCM_LTR3_WSW_MASK(x) (0x7 << \ + MXC_CCM_LTR3_WSW_OFFSET((x))) + +#define MXC_CCM_PMCR0_DFSUP1 0x80000000 +#define MXC_CCM_PMCR0_DFSUP1_SPLL (0 << 31) +#define MXC_CCM_PMCR0_DFSUP1_MPLL (1 << 31) +#define MXC_CCM_PMCR0_DFSUP0 0x40000000 +#define MXC_CCM_PMCR0_DFSUP0_PLL (0 << 30) +#define MXC_CCM_PMCR0_DFSUP0_PDR (1 << 30) +#define MXC_CCM_PMCR0_DFSUP_MASK (0x3 << 30) + +#define DVSUP_TURBO 0 +#define DVSUP_HIGH 1 +#define DVSUP_MEDIUM 2 +#define DVSUP_LOW 3 +#define MXC_CCM_PMCR0_DVSUP_TURBO (DVSUP_TURBO << 28) +#define MXC_CCM_PMCR0_DVSUP_HIGH (DVSUP_HIGH << 28) +#define MXC_CCM_PMCR0_DVSUP_MEDIUM (DVSUP_MEDIUM << 28) +#define MXC_CCM_PMCR0_DVSUP_LOW (DVSUP_LOW << 28) +#define MXC_CCM_PMCR0_DVSUP_OFFSET 28 +#define MXC_CCM_PMCR0_DVSUP_MASK (0x3 << 28) +#define MXC_CCM_PMCR0_UDSC 0x08000000 +#define MXC_CCM_PMCR0_UDSC_MASK (1 << 27) +#define MXC_CCM_PMCR0_UDSC_UP (1 << 27) +#define MXC_CCM_PMCR0_UDSC_DOWN (0 << 27) + +#define MXC_CCM_PMCR0_VSCNT_1 (0x0 << 24) +#define MXC_CCM_PMCR0_VSCNT_2 (0x1 << 24) +#define MXC_CCM_PMCR0_VSCNT_3 (0x2 << 24) +#define MXC_CCM_PMCR0_VSCNT_4 (0x3 << 24) +#define MXC_CCM_PMCR0_VSCNT_5 (0x4 << 24) +#define MXC_CCM_PMCR0_VSCNT_6 (0x5 << 24) +#define MXC_CCM_PMCR0_VSCNT_7 (0x6 << 24) +#define MXC_CCM_PMCR0_VSCNT_8 (0x7 << 24) +#define MXC_CCM_PMCR0_VSCNT_OFFSET 24 +#define MXC_CCM_PMCR0_VSCNT_MASK (0x7 << 24) +#define MXC_CCM_PMCR0_DVFEV 0x00800000 +#define MXC_CCM_PMCR0_DVFIS 0x00400000 +#define MXC_CCM_PMCR0_LBMI 0x00200000 +#define MXC_CCM_PMCR0_LBFL 0x00100000 +#define MXC_CCM_PMCR0_LBCF_4 (0x0 << 18) +#define MXC_CCM_PMCR0_LBCF_8 (0x1 << 18) +#define MXC_CCM_PMCR0_LBCF_12 (0x2 << 18) +#define MXC_CCM_PMCR0_LBCF_16 (0x3 << 18) +#define MXC_CCM_PMCR0_LBCF_OFFSET 18 +#define MXC_CCM_PMCR0_LBCF_MASK (0x3 << 18) +#define MXC_CCM_PMCR0_PTVIS 0x00020000 +#define MXC_CCM_PMCR0_UPDTEN 0x00010000 +#define MXC_CCM_PMCR0_UPDTEN_MASK (0x1 << 16) +#define MXC_CCM_PMCR0_FSVAIM 0x00008000 +#define MXC_CCM_PMCR0_FSVAI_OFFSET 13 +#define MXC_CCM_PMCR0_FSVAI_MASK (0x3 << 13) +#define MXC_CCM_PMCR0_DPVCR 0x00001000 +#define MXC_CCM_PMCR0_DPVV 0x00000800 +#define MXC_CCM_PMCR0_WFIM 0x00000400 +#define MXC_CCM_PMCR0_DRCE3 0x00000200 +#define MXC_CCM_PMCR0_DRCE2 0x00000100 +#define MXC_CCM_PMCR0_DRCE1 0x00000080 +#define MXC_CCM_PMCR0_DRCE0 0x00000040 +#define MXC_CCM_PMCR0_DCR 0x00000020 +#define MXC_CCM_PMCR0_DVFEN 0x00000010 +#define MXC_CCM_PMCR0_PTVAIM 0x00000008 +#define MXC_CCM_PMCR0_PTVAI_OFFSET 1 +#define MXC_CCM_PMCR0_PTVAI_MASK (0x3 << 1) +#define MXC_CCM_PMCR0_DPTEN 0x00000001 + +#define MXC_CCM_PMCR1_DVGP_OFFSET 0 +#define MXC_CCM_PMCR1_DVGP_MASK (0xF) + +#define MXC_CCM_PMCR1_PLLRDIS (0x1 << 7) +#define MXC_CCM_PMCR1_EMIRQ_EN (0x1 << 8) + +#define MXC_CCM_DCVR_ULV_MASK (0x3FF << 22) +#define MXC_CCM_DCVR_ULV_OFFSET 22 +#define MXC_CCM_DCVR_LLV_MASK (0x3FF << 12) +#define MXC_CCM_DCVR_LLV_OFFSET 12 +#define MXC_CCM_DCVR_ELV_MASK (0x3FF << 2) +#define MXC_CCM_DCVR_ELV_OFFSET 2 + +#define MXC_CCM_PDR2_MST2_PDF_MASK (0x3F << 7) +#define MXC_CCM_PDR2_MST2_PDF_OFFSET 7 +#define MXC_CCM_PDR2_MST1_PDF_MASK 0x3F +#define MXC_CCM_PDR2_MST1_PDF_OFFSET 0 + +#define MXC_CCM_COSR_CLKOSEL_MASK 0x0F +#define MXC_CCM_COSR_CLKOSEL_OFFSET 0 +#define MXC_CCM_COSR_CLKOUTDIV_MASK (0x07 << 6) +#define MXC_CCM_COSR_CLKOUTDIV_OFFSET 6 +#define MXC_CCM_COSR_CLKOEN (1 << 9) + +/* + * PMCR0 register offsets + */ +#define MXC_CCM_PMCR0_LBFL_OFFSET 20 +#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30 +#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31 + +#endif /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */ diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h index 23b4350..c6d4aa3 100644 --- a/include/asm-arm/arch-mxc/common.h +++ b/include/asm-arm/arch-mxc/common.h @@ -16,5 +16,6 @@ struct sys_timer; extern void mxc_map_io(void); extern void mxc_init_irq(void); extern struct sys_timer mxc_timer; +extern int mxc_clocks_init(unsigned long fref); #endif -- cgit v0.10.2 From e3d13ff4b9d3b05d7a969153e2c049548e25deea Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: mxc: add MX3 support for i.MX internal UART driver This patch adds MX3 support for the i.MX internal uart driver. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index febb37f..a788cb0 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o +obj-y := mm.o time.o clock.o devices.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c new file mode 100644 index 0000000..1bc6d23 --- /dev/null +++ b/arch/arm/mach-mx3/devices.c @@ -0,0 +1,153 @@ +/* + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Sascha Hauer, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +static struct resource uart0[] = { + { + .start = UART1_BASE_ADDR, + .end = UART1_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART1, + .end = MXC_INT_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device0 = { + .name = "imx-uart", + .id = 0, + .resource = uart0, + .num_resources = ARRAY_SIZE(uart0), +}; + +static struct resource uart1[] = { + { + .start = UART2_BASE_ADDR, + .end = UART2_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART2, + .end = MXC_INT_UART2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device1 = { + .name = "imx-uart", + .id = 1, + .resource = uart1, + .num_resources = ARRAY_SIZE(uart1), +}; + +static struct resource uart2[] = { + { + .start = UART3_BASE_ADDR, + .end = UART3_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART3, + .end = MXC_INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "imx-uart", + .id = 2, + .resource = uart2, + .num_resources = ARRAY_SIZE(uart2), +}; + +static struct resource uart3[] = { + { + .start = UART4_BASE_ADDR, + .end = UART4_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART4, + .end = MXC_INT_UART4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device3 = { + .name = "imx-uart", + .id = 3, + .resource = uart3, + .num_resources = ARRAY_SIZE(uart3), +}; + +static struct resource uart4[] = { + { + .start = UART5_BASE_ADDR, + .end = UART5_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART5, + .end = MXC_INT_UART5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device4 = { + .name = "imx-uart", + .id = 4, + .resource = uart4, + .num_resources = ARRAY_SIZE(uart4), +}; + +/* + * Register only those UARTs that physically exist + */ +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata) +{ + switch (uart_no) { + case 0: + mxc_uart_device0.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device0); + break; + case 1: + mxc_uart_device1.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device1); + break; + case 2: + mxc_uart_device2.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device2); + break; + case 3: + mxc_uart_device3.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device3); + break; + case 4: + mxc_uart_device4.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device4); + break; + default: + return -ENODEV; + } + + return 0; +} + diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9bc4276..0843c54 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -753,7 +753,7 @@ config BFIN_UART3_CTSRTS config SERIAL_IMX bool "IMX serial port support" - depends on ARM && ARCH_IMX + depends on ARM && (ARCH_IMX || ARCH_MXC) select SERIAL_CORE help If you have a machine based on a Motorola IMX CPU you diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 9e2162e..549440b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -62,6 +62,11 @@ #define UBIR 0xa4 /* BRM Incremental Register */ #define UBMR 0xa8 /* BRM Modulator Register */ #define UBRC 0xac /* Baud Rate Count Register */ +#ifdef CONFIG_ARCH_MX3 +#define ONEMS 0xb0 /* One Millisecond register */ +#define UTS 0xb4 /* UART Test Register */ +#endif +#ifdef CONFIG_ARCH_IMX #define BIPR1 0xb0 /* Incremental Preset Register 1 */ #define BIPR2 0xb4 /* Incremental Preset Register 2 */ #define BIPR3 0xb8 /* Incremental Preset Register 3 */ @@ -71,6 +76,7 @@ #define BMPR3 0xc8 /* BRM Modulator Register 3 */ #define BMPR4 0xcc /* BRM Modulator Register 4 */ #define UTS 0xd0 /* UART Test Register */ +#endif /* UART Control Register Bit Fields.*/ #define URXD_CHARRDY (1<<15) @@ -90,7 +96,12 @@ #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ #define UCR1_SNDBRK (1<<4) /* Send break */ #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ +#ifdef CONFIG_ARCH_IMX #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ +#endif +#ifdef CONFIG_ARCH_MX3 +#define UCR1_UARTCLKEN (0) /* not present on mx2/mx3 */ +#endif #define UCR1_DOZE (1<<1) /* Doze */ #define UCR1_UARTEN (1<<0) /* UART enabled */ #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ @@ -164,8 +175,19 @@ #define UTS_SOFTRST (1<<0) /* Software reset */ /* We've been assigned a range on the "Low-density serial ports" major */ +#ifdef CONFIG_ARCH_IMX #define SERIAL_IMX_MAJOR 204 #define MINOR_START 41 +#define DEV_NAME "ttySMX" +#define MAX_INTERNAL_IRQ IMX_IRQS +#endif + +#ifdef CONFIG_ARCH_MX3 +#define SERIAL_IMX_MAJOR 207 +#define MINOR_START 16 +#define DEV_NAME "ttymxc" +#define MAX_INTERNAL_IRQ MXC_MAX_INT_LINES +#endif /* * This determines how often we check the modem status signals @@ -409,6 +431,26 @@ out: return IRQ_HANDLED; } +static irqreturn_t imx_int(int irq, void *dev_id) +{ + struct imx_port *sport = dev_id; + unsigned int sts; + + sts = readl(sport->port.membase + USR1); + + if (sts & USR1_RRDY) + imx_rxint(irq, dev_id); + + if (sts & USR1_TRDY && + readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) + imx_txint(irq, dev_id); + + if (sts & USR1_RTSS) + imx_rtsint(irq, dev_id); + + return IRQ_HANDLED; +} + /* * Return TIOCSER_TEMT when transmitter is not busy. */ @@ -514,21 +556,34 @@ static int imx_startup(struct uart_port *port) writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); /* - * Allocate the IRQ + * Allocate the IRQ(s) i.MX1 has three interrupts whereas later + * chips only have one interrupt. */ - retval = request_irq(sport->rxirq, imx_rxint, 0, - DRIVER_NAME, sport); - if (retval) goto error_out1; - - retval = request_irq(sport->txirq, imx_txint, 0, - DRIVER_NAME, sport); - if (retval) goto error_out2; - - retval = request_irq(sport->rtsirq, imx_rtsint, - (sport->rtsirq < IMX_IRQS) ? 0 : + if (sport->txirq > 0) { + retval = request_irq(sport->rxirq, imx_rxint, 0, + DRIVER_NAME, sport); + if (retval) + goto error_out1; + + retval = request_irq(sport->txirq, imx_txint, 0, + DRIVER_NAME, sport); + if (retval) + goto error_out2; + + retval = request_irq(sport->rtsirq, imx_rtsint, + (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 : IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - DRIVER_NAME, sport); - if (retval) goto error_out3; + DRIVER_NAME, sport); + if (retval) + goto error_out3; + } else { + retval = request_irq(sport->port.irq, imx_int, 0, + DRIVER_NAME, sport); + if (retval) { + free_irq(sport->port.irq, sport); + goto error_out1; + } + } /* * Finally, clear and enable interrupts @@ -553,9 +608,11 @@ static int imx_startup(struct uart_port *port) return 0; error_out3: - free_irq(sport->txirq, sport); + if (sport->txirq) + free_irq(sport->txirq, sport); error_out2: - free_irq(sport->rxirq, sport); + if (sport->rxirq) + free_irq(sport->rxirq, sport); error_out1: return retval; } @@ -573,9 +630,12 @@ static void imx_shutdown(struct uart_port *port) /* * Free the interrupts */ - free_irq(sport->rtsirq, sport); - free_irq(sport->txirq, sport); - free_irq(sport->rxirq, sport); + if (sport->txirq > 0) { + free_irq(sport->rtsirq, sport); + free_irq(sport->txirq, sport); + free_irq(sport->rxirq, sport); + } else + free_irq(sport->port.irq, sport); /* * Disable all interrupts, port and break condition. @@ -973,7 +1033,7 @@ imx_console_setup(struct console *co, char *options) static struct uart_driver imx_reg; static struct console imx_console = { - .name = "ttySMX", + .name = DEV_NAME, .write = imx_console_write, .device = uart_console_device, .setup = imx_console_setup, @@ -990,7 +1050,7 @@ static struct console imx_console = { static struct uart_driver imx_reg = { .owner = THIS_MODULE, .driver_name = DRIVER_NAME, - .dev_name = "ttySMX", + .dev_name = DEV_NAME, .major = SERIAL_IMX_MAJOR, .minor = MINOR_START, .nr = ARRAY_SIZE(imx_ports), diff --git a/include/asm-arm/arch-mxc/imx-uart.h b/include/asm-arm/arch-mxc/imx-uart.h new file mode 100644 index 0000000..83fb72c4 --- /dev/null +++ b/include/asm-arm/arch-mxc/imx-uart.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef ASMARM_ARCH_UART_H +#define ASMARM_ARCH_UART_H + +#define IMXUART_HAVE_RTSCTS (1<<0) + +struct imxuart_platform_data { + int (*init)(struct platform_device *pdev); + int (*exit)(struct platform_device *pdev); + unsigned int flags; +}; + +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata); + +#endif -- cgit v0.10.2 From 07bd1a6cc7cbb3f373fbe49b204c6cde5e9155fc Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:49 +0200 Subject: MXC arch: Add gpio support for the whole platform This patch bases on the one from Daniel Mack. The most important change to Daniel's patch is to be more generic. This gpio routine supports at least the i.MX27 and i.MX31 processors. Signed-off-by: Juergen Beisert Acked-by: Daniel Mack diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68..5c8c1a8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -368,6 +368,8 @@ config ARCH_NS9XXX config ARCH_MXC bool "Freescale MXC/iMX-based" select ARCH_MTD_XIP + select GENERIC_GPIO + select HAVE_GPIO_LIB help Support for Freescale MXC/iMX-based family of processors diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 1bc6d23..5c0320f 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -151,3 +152,29 @@ int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata) return 0; } +/* GPIO port description */ +static struct mxc_gpio_port imx_gpio_ports[] = { + [0] = { + .chip.label = "gpio-0", + .base = IO_ADDRESS(GPIO1_BASE_ADDR), + .irq = MXC_INT_GPIO1, + .virtual_irq_start = MXC_GPIO_INT_BASE + }, + [1] = { + .chip.label = "gpio-1", + .base = IO_ADDRESS(GPIO2_BASE_ADDR), + .irq = MXC_INT_GPIO2, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN + }, + [2] = { + .chip.label = "gpio-2", + .base = IO_ADDRESS(GPIO3_BASE_ADDR), + .irq = MXC_INT_GPIO3, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2 + } +}; + +int __init mxc_register_gpios(void) +{ + return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); +} diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 3eb181c..66272a6 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := irq.o clock.o +obj-y := irq.o clock.o gpio.o diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c new file mode 100644 index 0000000..4a77367 --- /dev/null +++ b/arch/arm/plat-mxc/gpio.c @@ -0,0 +1,253 @@ +/* + * MXC GPIO support. (c) 2008 Daniel Mack + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * Based on code from Freescale, + * Copyright 2004-2006 Freescale Semiconductor, 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. + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +static struct mxc_gpio_port *mxc_gpio_ports; +static int gpio_table_size; + +/* Note: This driver assumes 32 GPIOs are handled in one register */ + +static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) +{ + __raw_writel(1 << index, port->base + GPIO_ISR); +} + +static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, + int enable) +{ + u32 l; + + l = __raw_readl(port->base + GPIO_IMR); + l = (l & (~(1 << index))) | (!!enable << index); + __raw_writel(l, port->base + GPIO_IMR); +} + +static void gpio_ack_irq(u32 irq) +{ + u32 gpio = irq_to_gpio(irq); + _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); +} + +static void gpio_mask_irq(u32 irq) +{ + u32 gpio = irq_to_gpio(irq); + _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); +} + +static void gpio_unmask_irq(u32 irq) +{ + u32 gpio = irq_to_gpio(irq); + _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); +} + +static int gpio_set_irq_type(u32 irq, u32 type) +{ + u32 gpio = irq_to_gpio(irq); + struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; + u32 bit, val; + int edge; + void __iomem *reg = port->base; + + switch (type) { + case IRQT_RISING: + edge = GPIO_INT_RISE_EDGE; + break; + case IRQT_FALLING: + edge = GPIO_INT_FALL_EDGE; + break; + case IRQT_LOW: + edge = GPIO_INT_LOW_LEV; + break; + case IRQT_HIGH: + edge = GPIO_INT_HIGH_LEV; + break; + default: /* this includes IRQT_BOTHEDGE */ + return -EINVAL; + } + + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ + bit = gpio & 0xf; + val = __raw_readl(reg) & ~(0x3 << (bit << 1)); + __raw_writel(val | (edge << (bit << 1)), reg); + _clear_gpio_irqstatus(port, gpio & 0x1f); + + return 0; +} + +/* handle n interrupts in one status register */ +static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) +{ + u32 gpio_irq_no; + + gpio_irq_no = port->virtual_irq_start; + for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { + + if ((irq_stat & 1) == 0) + continue; + + BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); + irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, + &irq_desc[gpio_irq_no]); + } +} + +#ifdef CONFIG_ARCH_MX3 +/* MX3 has one interrupt *per* gpio port */ +static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) +{ + u32 irq_stat; + struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); + + irq_stat = __raw_readl(port->base + GPIO_ISR) & + __raw_readl(port->base + GPIO_IMR); + BUG_ON(!irq_stat); + mxc_gpio_irq_handler(port, irq_stat); +} +#endif + +#ifdef CONFIG_ARCH_MX2 +/* MX2 has one interrupt *for all* gpio ports */ +static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) +{ + int i; + u32 irq_msk, irq_stat; + struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); + + /* walk through all interrupt status registers */ + for (i = 0; i < gpio_table_size; i++) { + irq_msk = __raw_readl(port[i].base + GPIO_IMR); + if (!irq_msk) + continue; + + irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; + if (irq_stat) + mxc_gpio_irq_handler(&port[i], irq_stat); + } +} +#endif + +static struct irq_chip gpio_irq_chip = { + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, + .set_type = gpio_set_irq_type, +}; + +static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, + int dir) +{ + struct mxc_gpio_port *port = + container_of(chip, struct mxc_gpio_port, chip); + u32 l; + + l = __raw_readl(port->base + GPIO_GDIR); + if (dir) + l |= 1 << offset; + else + l &= ~(1 << offset); + __raw_writel(l, port->base + GPIO_GDIR); +} + +static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct mxc_gpio_port *port = + container_of(chip, struct mxc_gpio_port, chip); + void __iomem *reg = port->base + GPIO_DR; + u32 l; + + l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); + __raw_writel(l, reg); +} + +static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct mxc_gpio_port *port = + container_of(chip, struct mxc_gpio_port, chip); + + return (__raw_readl(port->base + GPIO_DR) >> offset) & 1; +} + +static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + _set_gpio_direction(chip, offset, 0); + return 0; +} + +static int mxc_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + _set_gpio_direction(chip, offset, 1); + mxc_gpio_set(chip, offset, value); + return 0; +} + +int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) +{ + int i, j; + + /* save for local usage */ + mxc_gpio_ports = port; + gpio_table_size = cnt; + + printk(KERN_INFO "MXC GPIO hardware\n"); + + for (i = 0; i < cnt; i++) { + /* disable the interrupt and clear the status */ + __raw_writel(0, port[i].base + GPIO_IMR); + __raw_writel(~0, port[i].base + GPIO_ISR); + for (j = port[i].virtual_irq_start; + j < port[i].virtual_irq_start + 32; j++) { + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_edge_irq); + set_irq_flags(j, IRQF_VALID); + } + + /* register gpio chip */ + port[i].chip.direction_input = mxc_gpio_direction_input; + port[i].chip.direction_output = mxc_gpio_direction_output; + port[i].chip.get = mxc_gpio_get; + port[i].chip.set = mxc_gpio_set; + port[i].chip.base = i * 32; + port[i].chip.ngpio = 32; + + /* its a serious configuration bug when it fails */ + BUG_ON( gpiochip_add(&port[i].chip) < 0 ); + +#ifdef CONFIG_ARCH_MX3 + /* setup one handler for each entry */ + set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); + set_irq_data(port[i].irq, &port[i]); +#endif + } + +#ifdef CONFIG_ARCH_MX2 + /* setup one handler for all GPIO interrupts */ + set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler); + set_irq_data(port[0].irq, port); +#endif + return 0; +} diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c index 2ad5a69..88f0cfa 100644 --- a/arch/arm/plat-mxc/irq.c +++ b/arch/arm/plat-mxc/irq.c @@ -71,5 +71,8 @@ void __init mxc_init_irq(void) reg |= (0xF << 28); __raw_writel(reg, AVIC_NIPRIORITY6); + /* init architectures chained interrupt handler */ + mxc_register_gpios(); + printk(KERN_INFO "MXC IRQ initialized\n"); } diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h index c6d4aa3..8774783 100644 --- a/include/asm-arm/arch-mxc/common.h +++ b/include/asm-arm/arch-mxc/common.h @@ -17,5 +17,6 @@ extern void mxc_map_io(void); extern void mxc_init_irq(void); extern struct sys_timer mxc_timer; extern int mxc_clocks_init(unsigned long fref); +extern int mxc_register_gpios(void); #endif diff --git a/include/asm-arm/arch-mxc/gpio.h b/include/asm-arm/arch-mxc/gpio.h new file mode 100644 index 0000000..d393e15 --- /dev/null +++ b/include/asm-arm/arch-mxc/gpio.h @@ -0,0 +1,42 @@ +/* + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_GPIO_H__ +#define __ASM_ARCH_MXC_GPIO_H__ + +#include +#include + +/* use gpiolib dispatchers */ +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +#define gpio_to_irq(gpio) (MXC_MAX_INT_LINES + (gpio)) +#define irq_to_gpio(irq) ((irq) - MXC_MAX_INT_LINES) + +struct mxc_gpio_port { + void __iomem *base; + int irq; + int virtual_irq_start; + struct gpio_chip chip; +}; + +int mxc_gpio_init(struct mxc_gpio_port*, int); + +#endif diff --git a/include/asm-arm/arch-mxc/mx31.h b/include/asm-arm/arch-mxc/mx31.h index 36a1af4..98e6a4c 100644 --- a/include/asm-arm/arch-mxc/mx31.h +++ b/include/asm-arm/arch-mxc/mx31.h @@ -347,6 +347,25 @@ #define SYSTEM_REV_MIN CHIP_REV_1_0 #define SYSTEM_REV_NUM 3 +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x00 +#define GPIO_GDIR 0x04 +#define GPIO_PSR 0x08 +#define GPIO_ICR1 0x0C +#define GPIO_ICR2 0x10 +#define GPIO_IMR 0x14 +#define GPIO_ISR 0x18 +#define GPIO_INT_LOW_LEV 0x0 +#define GPIO_INT_HIGH_LEV 0x1 +#define GPIO_INT_RISE_EDGE 0x2 +#define GPIO_INT_FALL_EDGE 0x3 +#define GPIO_INT_NONE 0x4 + +/* Mandatory defines used globally */ + +/* this CPU supports up to 96 GPIOs */ +#define ARCH_NR_GPIOS 96 + #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) /* this is a i.MX31 CPU */ -- cgit v0.10.2 From 90292ea60f1c730efb9fea02b2e12676da89ebef Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:50 +0200 Subject: MXC: add io multiplexing functions for mx3 This patch adds functions to use the io multiplexer on mx3 platforms. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index a788cb0..68f062b 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o devices.o +obj-y := mm.o time.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c new file mode 100644 index 0000000..adc51fe --- /dev/null +++ b/arch/arm/mach-mx3/iomux.c @@ -0,0 +1,111 @@ +/* + * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * IOMUX register (base) addresses + */ +#define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) +#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000) +#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004) +#define IOMUXGPR (IOMUX_BASE + 0x008) +#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C) +#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154) + +static DEFINE_SPINLOCK(gpio_mux_lock); + +#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) +/* + * set the mode for a IOMUX pin. + */ +int mxc_iomux_mode(unsigned int pin_mode) +{ + u32 reg, field, l, mode, ret = 0; + + reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK); + field = pin_mode & 0x3; + mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; + + pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n", + __func__, (pin_mode & IOMUX_REG_MASK), field, mode); + + spin_lock(&gpio_mux_lock); + + l = __raw_readl(reg); + l &= ~(0xff << (field * 8)); + l |= mode << (field * 8); + __raw_writel(l, reg); + + spin_unlock(&gpio_mux_lock); + + return ret; +} +EXPORT_SYMBOL(mxc_iomux_mode); + +/* + * This function configures the pad value for a IOMUX pin. + */ +void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) +{ + u32 reg, field, l; + + reg = IOMUXSW_PAD_CTL + (pin + 2) / 3; + field = (pin + 2) % 3; + + pr_debug("%s: reg offset = 0x%x field = %d\n", + __func__, (pin + 2) / 3, field); + + spin_lock(&gpio_mux_lock); + + l = __raw_readl(reg); + l &= ~(0x1ff << (field * 9)); + l |= config << (field * 9); + __raw_writel(l, reg); + + spin_unlock(&gpio_mux_lock); +} +EXPORT_SYMBOL(mxc_iomux_set_pad); + +/* + * This function enables/disables the general purpose function for a particular + * signal. + */ +void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) +{ + u32 l; + + spin_lock(&gpio_mux_lock); + l = __raw_readl(IOMUXGPR); + if (en) + l |= gp; + else + l &= ~gp; + + __raw_writel(l, IOMUXGPR); + spin_unlock(&gpio_mux_lock); +} +EXPORT_SYMBOL(mxc_iomux_set_gpr); + diff --git a/include/asm-arm/arch-mxc/iomux-mx3.h b/include/asm-arm/arch-mxc/iomux-mx3.h new file mode 100644 index 0000000..7509e76 --- /dev/null +++ b/include/asm-arm/arch-mxc/iomux-mx3.h @@ -0,0 +1,501 @@ +/* + * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __MACH_MX31_IOMUX_H__ +#define __MACH_MX31_IOMUX_H__ + +#include + +/* + * various IOMUX output functions + */ + +#define IOMUX_OCONFIG_GPIO (0 << 4) /* used as GPIO */ +#define IOMUX_OCONFIG_FUNC (1 << 4) /* used as function */ +#define IOMUX_OCONFIG_ALT1 (2 << 4) /* used as alternate function 1 */ +#define IOMUX_OCONFIG_ALT2 (3 << 4) /* used as alternate function 2 */ +#define IOMUX_OCONFIG_ALT3 (4 << 4) /* used as alternate function 3 */ +#define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */ +#define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */ +#define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */ +#define IOMUX_ICONFIG_NONE 0 /* not configured for input */ +#define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */ +#define IOMUX_ICONFIG_FUNC 2 /* used as function */ +#define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */ +#define IOMUX_ICONFIG_ALT2 8 /* used as alternate function 2 */ + +#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO) +#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC) +#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1) +#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2) + +/* + * various IOMUX pad functions + */ +enum iomux_pad_config { + PAD_CTL_NOLOOPBACK = 0x0 << 9, + PAD_CTL_LOOPBACK = 0x1 << 9, + PAD_CTL_PKE_NONE = 0x0 << 8, + PAD_CTL_PKE_ENABLE = 0x1 << 8, + PAD_CTL_PUE_KEEPER = 0x0 << 7, + PAD_CTL_PUE_PUD = 0x1 << 7, + PAD_CTL_100K_PD = 0x0 << 5, + PAD_CTL_100K_PU = 0x1 << 5, + PAD_CTL_47K_PU = 0x2 << 5, + PAD_CTL_22K_PU = 0x3 << 5, + PAD_CTL_HYS_CMOS = 0x0 << 4, + PAD_CTL_HYS_SCHMITZ = 0x1 << 4, + PAD_CTL_ODE_CMOS = 0x0 << 3, + PAD_CTL_ODE_OpenDrain = 0x1 << 3, + PAD_CTL_DRV_NORMAL = 0x0 << 1, + PAD_CTL_DRV_HIGH = 0x1 << 1, + PAD_CTL_DRV_MAX = 0x2 << 1, + PAD_CTL_SRE_SLOW = 0x0 << 0, + PAD_CTL_SRE_FAST = 0x1 << 0 +}; + +/* + * various IOMUX general purpose functions + */ +enum iomux_gp_func { + MUX_PGP_FIRI = 1 << 0, + MUX_DDR_MODE = 1 << 1, + MUX_PGP_CSPI_BB = 1 << 2, + MUX_PGP_ATA_1 = 1 << 3, + MUX_PGP_ATA_2 = 1 << 4, + MUX_PGP_ATA_3 = 1 << 5, + MUX_PGP_ATA_4 = 1 << 6, + MUX_PGP_ATA_5 = 1 << 7, + MUX_PGP_ATA_6 = 1 << 8, + MUX_PGP_ATA_7 = 1 << 9, + MUX_PGP_ATA_8 = 1 << 10, + MUX_PGP_UH2 = 1 << 11, + MUX_SDCTL_CSD0_SEL = 1 << 12, + MUX_SDCTL_CSD1_SEL = 1 << 13, + MUX_CSPI1_UART3 = 1 << 14, + MUX_EXTDMAREQ2_MBX_SEL = 1 << 15, + MUX_TAMPER_DETECT_EN = 1 << 16, + MUX_PGP_USB_4WIRE = 1 << 17, + MUX_PGB_USB_COMMON = 1 << 18, + MUX_SDHC_MEMSTICK1 = 1 << 19, + MUX_SDHC_MEMSTICK2 = 1 << 20, + MUX_PGP_SPLL_BYP = 1 << 21, + MUX_PGP_UPLL_BYP = 1 << 22, + MUX_PGP_MSHC1_CLK_SEL = 1 << 23, + MUX_PGP_MSHC2_CLK_SEL = 1 << 24, + MUX_CSPI3_UART5_SEL = 1 << 25, + MUX_PGP_ATA_9 = 1 << 26, + MUX_PGP_USB_SUSPEND = 1 << 27, + MUX_PGP_USB_OTG_LOOPBACK = 1 << 28, + MUX_PGP_USB_HS1_LOOPBACK = 1 << 29, + MUX_PGP_USB_HS2_LOOPBACK = 1 << 30, + MUX_CLKO_DDR_MODE = 1 << 31, +}; + +/* + * This function enables/disables the general purpose function for a particular + * signal. + */ +void iomux_config_gpr(enum iomux_gp_func , bool); + +/* + * set the mode for a IOMUX pin. + */ +int mxc_iomux_mode(unsigned int); + +/* + * This function enables/disables the general purpose function for a particular + * signal. + */ +void mxc_iomux_set_gpr(enum iomux_gp_func, bool); + +#define IOMUX_PADNUM_MASK 0x1ff +#define IOMUX_GPIONUM_SHIFT 9 +#define IOMUX_GPIONUM_MASK (0xff << IOMUX_GPIONUM_SHIFT) +#define IOMUX_MODE_SHIFT 17 +#define IOMUX_MODE_MASK (0xff << IOMUX_MODE_SHIFT) + +#define IOMUX_PIN(gpionum, padnum) \ + (((gpionum << IOMUX_GPIONUM_SHIFT) & IOMUX_GPIONUM_MASK) | \ + (padnum & IOMUX_PADNUM_MASK)) + +#define IOMUX_MODE(pin, mode) (pin | mode << IOMUX_MODE_SHIFT) + +#define IOMUX_TO_GPIO(iomux_pin) \ + ((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) +#define IOMUX_TO_IRQ(iomux_pin) \ + (((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \ + MXC_GPIO_INT_BASE) + +/* + * This enumeration is constructed based on the Section + * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated + * value is constructed based on the rules described above. + */ + +enum iomux_pins { + MX31_PIN_TTM_PAD = IOMUX_PIN(0xff, 0), + MX31_PIN_CSPI3_SPI_RDY = IOMUX_PIN(0xff, 1), + MX31_PIN_CSPI3_SCLK = IOMUX_PIN(0xff, 2), + MX31_PIN_CSPI3_MISO = IOMUX_PIN(0xff, 3), + MX31_PIN_CSPI3_MOSI = IOMUX_PIN(0xff, 4), + MX31_PIN_CLKSS = IOMUX_PIN(0xff, 5), + MX31_PIN_CE_CONTROL = IOMUX_PIN(0xff, 6), + MX31_PIN_ATA_RESET_B = IOMUX_PIN(95, 7), + MX31_PIN_ATA_DMACK = IOMUX_PIN(94, 8), + MX31_PIN_ATA_DIOW = IOMUX_PIN(93, 9), + MX31_PIN_ATA_DIOR = IOMUX_PIN(92, 10), + MX31_PIN_ATA_CS1 = IOMUX_PIN(91, 11), + MX31_PIN_ATA_CS0 = IOMUX_PIN(90, 12), + MX31_PIN_SD1_DATA3 = IOMUX_PIN(63, 13), + MX31_PIN_SD1_DATA2 = IOMUX_PIN(62, 14), + MX31_PIN_SD1_DATA1 = IOMUX_PIN(61, 15), + MX31_PIN_SD1_DATA0 = IOMUX_PIN(60, 16), + MX31_PIN_SD1_CLK = IOMUX_PIN(59, 17), + MX31_PIN_SD1_CMD = IOMUX_PIN(58, 18), + MX31_PIN_D3_SPL = IOMUX_PIN(0xff, 19), + MX31_PIN_D3_CLS = IOMUX_PIN(0xff, 20), + MX31_PIN_D3_REV = IOMUX_PIN(0xff, 21), + MX31_PIN_CONTRAST = IOMUX_PIN(0xff, 22), + MX31_PIN_VSYNC3 = IOMUX_PIN(0xff, 23), + MX31_PIN_READ = IOMUX_PIN(0xff, 24), + MX31_PIN_WRITE = IOMUX_PIN(0xff, 25), + MX31_PIN_PAR_RS = IOMUX_PIN(0xff, 26), + MX31_PIN_SER_RS = IOMUX_PIN(89, 27), + MX31_PIN_LCS1 = IOMUX_PIN(88, 28), + MX31_PIN_LCS0 = IOMUX_PIN(87, 29), + MX31_PIN_SD_D_CLK = IOMUX_PIN(86, 30), + MX31_PIN_SD_D_IO = IOMUX_PIN(85, 31), + MX31_PIN_SD_D_I = IOMUX_PIN(84, 32), + MX31_PIN_DRDY0 = IOMUX_PIN(0xff, 33), + MX31_PIN_FPSHIFT = IOMUX_PIN(0xff, 34), + MX31_PIN_HSYNC = IOMUX_PIN(0xff, 35), + MX31_PIN_VSYNC0 = IOMUX_PIN(0xff, 36), + MX31_PIN_LD17 = IOMUX_PIN(0xff, 37), + MX31_PIN_LD16 = IOMUX_PIN(0xff, 38), + MX31_PIN_LD15 = IOMUX_PIN(0xff, 39), + MX31_PIN_LD14 = IOMUX_PIN(0xff, 40), + MX31_PIN_LD13 = IOMUX_PIN(0xff, 41), + MX31_PIN_LD12 = IOMUX_PIN(0xff, 42), + MX31_PIN_LD11 = IOMUX_PIN(0xff, 43), + MX31_PIN_LD10 = IOMUX_PIN(0xff, 44), + MX31_PIN_LD9 = IOMUX_PIN(0xff, 45), + MX31_PIN_LD8 = IOMUX_PIN(0xff, 46), + MX31_PIN_LD7 = IOMUX_PIN(0xff, 47), + MX31_PIN_LD6 = IOMUX_PIN(0xff, 48), + MX31_PIN_LD5 = IOMUX_PIN(0xff, 49), + MX31_PIN_LD4 = IOMUX_PIN(0xff, 50), + MX31_PIN_LD3 = IOMUX_PIN(0xff, 51), + MX31_PIN_LD2 = IOMUX_PIN(0xff, 52), + MX31_PIN_LD1 = IOMUX_PIN(0xff, 53), + MX31_PIN_LD0 = IOMUX_PIN(0xff, 54), + MX31_PIN_USBH2_DATA1 = IOMUX_PIN(0xff, 55), + MX31_PIN_USBH2_DATA0 = IOMUX_PIN(0xff, 56), + MX31_PIN_USBH2_NXT = IOMUX_PIN(0xff, 57), + MX31_PIN_USBH2_STP = IOMUX_PIN(0xff, 58), + MX31_PIN_USBH2_DIR = IOMUX_PIN(0xff, 59), + MX31_PIN_USBH2_CLK = IOMUX_PIN(0xff, 60), + MX31_PIN_USBOTG_DATA7 = IOMUX_PIN(0xff, 61), + MX31_PIN_USBOTG_DATA6 = IOMUX_PIN(0xff, 62), + MX31_PIN_USBOTG_DATA5 = IOMUX_PIN(0xff, 63), + MX31_PIN_USBOTG_DATA4 = IOMUX_PIN(0xff, 64), + MX31_PIN_USBOTG_DATA3 = IOMUX_PIN(0xff, 65), + MX31_PIN_USBOTG_DATA2 = IOMUX_PIN(0xff, 66), + MX31_PIN_USBOTG_DATA1 = IOMUX_PIN(0xff, 67), + MX31_PIN_USBOTG_DATA0 = IOMUX_PIN(0xff, 68), + MX31_PIN_USBOTG_NXT = IOMUX_PIN(0xff, 69), + MX31_PIN_USBOTG_STP = IOMUX_PIN(0xff, 70), + MX31_PIN_USBOTG_DIR = IOMUX_PIN(0xff, 71), + MX31_PIN_USBOTG_CLK = IOMUX_PIN(0xff, 72), + MX31_PIN_USB_BYP = IOMUX_PIN(31, 73), + MX31_PIN_USB_OC = IOMUX_PIN(30, 74), + MX31_PIN_USB_PWR = IOMUX_PIN(29, 75), + MX31_PIN_SJC_MOD = IOMUX_PIN(0xff, 76), + MX31_PIN_DE_B = IOMUX_PIN(0xff, 77), + MX31_PIN_TRSTB = IOMUX_PIN(0xff, 78), + MX31_PIN_TDO = IOMUX_PIN(0xff, 79), + MX31_PIN_TDI = IOMUX_PIN(0xff, 80), + MX31_PIN_TMS = IOMUX_PIN(0xff, 81), + MX31_PIN_TCK = IOMUX_PIN(0xff, 82), + MX31_PIN_RTCK = IOMUX_PIN(0xff, 83), + MX31_PIN_KEY_COL7 = IOMUX_PIN(57, 84), + MX31_PIN_KEY_COL6 = IOMUX_PIN(56, 85), + MX31_PIN_KEY_COL5 = IOMUX_PIN(55, 86), + MX31_PIN_KEY_COL4 = IOMUX_PIN(54, 87), + MX31_PIN_KEY_COL3 = IOMUX_PIN(0xff, 88), + MX31_PIN_KEY_COL2 = IOMUX_PIN(0xff, 89), + MX31_PIN_KEY_COL1 = IOMUX_PIN(0xff, 90), + MX31_PIN_KEY_COL0 = IOMUX_PIN(0xff, 91), + MX31_PIN_KEY_ROW7 = IOMUX_PIN(53, 92), + MX31_PIN_KEY_ROW6 = IOMUX_PIN(52, 93), + MX31_PIN_KEY_ROW5 = IOMUX_PIN(51, 94), + MX31_PIN_KEY_ROW4 = IOMUX_PIN(50, 95), + MX31_PIN_KEY_ROW3 = IOMUX_PIN(0xff, 96), + MX31_PIN_KEY_ROW2 = IOMUX_PIN(0xff, 97), + MX31_PIN_KEY_ROW1 = IOMUX_PIN(0xff, 98), + MX31_PIN_KEY_ROW0 = IOMUX_PIN(0xff, 99), + MX31_PIN_BATT_LINE = IOMUX_PIN(49, 100), + MX31_PIN_CTS2 = IOMUX_PIN(0xff, 101), + MX31_PIN_RTS2 = IOMUX_PIN(0xff, 102), + MX31_PIN_TXD2 = IOMUX_PIN(28, 103), + MX31_PIN_RXD2 = IOMUX_PIN(27, 104), + MX31_PIN_DTR_DCE2 = IOMUX_PIN(48, 105), + MX31_PIN_DCD_DTE1 = IOMUX_PIN(47, 106), + MX31_PIN_RI_DTE1 = IOMUX_PIN(46, 107), + MX31_PIN_DSR_DTE1 = IOMUX_PIN(45, 108), + MX31_PIN_DTR_DTE1 = IOMUX_PIN(44, 109), + MX31_PIN_DCD_DCE1 = IOMUX_PIN(43, 110), + MX31_PIN_RI_DCE1 = IOMUX_PIN(42, 111), + MX31_PIN_DSR_DCE1 = IOMUX_PIN(41, 112), + MX31_PIN_DTR_DCE1 = IOMUX_PIN(40, 113), + MX31_PIN_CTS1 = IOMUX_PIN(39, 114), + MX31_PIN_RTS1 = IOMUX_PIN(38, 115), + MX31_PIN_TXD1 = IOMUX_PIN(37, 116), + MX31_PIN_RXD1 = IOMUX_PIN(36, 117), + MX31_PIN_CSPI2_SPI_RDY = IOMUX_PIN(0xff, 118), + MX31_PIN_CSPI2_SCLK = IOMUX_PIN(0xff, 119), + MX31_PIN_CSPI2_SS2 = IOMUX_PIN(0xff, 120), + MX31_PIN_CSPI2_SS1 = IOMUX_PIN(0xff, 121), + MX31_PIN_CSPI2_SS0 = IOMUX_PIN(0xff, 122), + MX31_PIN_CSPI2_MISO = IOMUX_PIN(0xff, 123), + MX31_PIN_CSPI2_MOSI = IOMUX_PIN(0xff, 124), + MX31_PIN_CSPI1_SPI_RDY = IOMUX_PIN(0xff, 125), + MX31_PIN_CSPI1_SCLK = IOMUX_PIN(0xff, 126), + MX31_PIN_CSPI1_SS2 = IOMUX_PIN(0xff, 127), + MX31_PIN_CSPI1_SS1 = IOMUX_PIN(0xff, 128), + MX31_PIN_CSPI1_SS0 = IOMUX_PIN(0xff, 129), + MX31_PIN_CSPI1_MISO = IOMUX_PIN(0xff, 130), + MX31_PIN_CSPI1_MOSI = IOMUX_PIN(0xff, 131), + MX31_PIN_SFS6 = IOMUX_PIN(26, 132), + MX31_PIN_SCK6 = IOMUX_PIN(25, 133), + MX31_PIN_SRXD6 = IOMUX_PIN(24, 134), + MX31_PIN_STXD6 = IOMUX_PIN(23, 135), + MX31_PIN_SFS5 = IOMUX_PIN(0xff, 136), + MX31_PIN_SCK5 = IOMUX_PIN(0xff, 137), + MX31_PIN_SRXD5 = IOMUX_PIN(22, 138), + MX31_PIN_STXD5 = IOMUX_PIN(21, 139), + MX31_PIN_SFS4 = IOMUX_PIN(0xff, 140), + MX31_PIN_SCK4 = IOMUX_PIN(0xff, 141), + MX31_PIN_SRXD4 = IOMUX_PIN(20, 142), + MX31_PIN_STXD4 = IOMUX_PIN(19, 143), + MX31_PIN_SFS3 = IOMUX_PIN(0xff, 144), + MX31_PIN_SCK3 = IOMUX_PIN(0xff, 145), + MX31_PIN_SRXD3 = IOMUX_PIN(18, 146), + MX31_PIN_STXD3 = IOMUX_PIN(17, 147), + MX31_PIN_I2C_DAT = IOMUX_PIN(0xff, 148), + MX31_PIN_I2C_CLK = IOMUX_PIN(0xff, 149), + MX31_PIN_CSI_PIXCLK = IOMUX_PIN(83, 150), + MX31_PIN_CSI_HSYNC = IOMUX_PIN(82, 151), + MX31_PIN_CSI_VSYNC = IOMUX_PIN(81, 152), + MX31_PIN_CSI_MCLK = IOMUX_PIN(80, 153), + MX31_PIN_CSI_D15 = IOMUX_PIN(79, 154), + MX31_PIN_CSI_D14 = IOMUX_PIN(78, 155), + MX31_PIN_CSI_D13 = IOMUX_PIN(77, 156), + MX31_PIN_CSI_D12 = IOMUX_PIN(76, 157), + MX31_PIN_CSI_D11 = IOMUX_PIN(75, 158), + MX31_PIN_CSI_D10 = IOMUX_PIN(74, 159), + MX31_PIN_CSI_D9 = IOMUX_PIN(73, 160), + MX31_PIN_CSI_D8 = IOMUX_PIN(72, 161), + MX31_PIN_CSI_D7 = IOMUX_PIN(71, 162), + MX31_PIN_CSI_D6 = IOMUX_PIN(70, 163), + MX31_PIN_CSI_D5 = IOMUX_PIN(69, 164), + MX31_PIN_CSI_D4 = IOMUX_PIN(68, 165), + MX31_PIN_M_GRANT = IOMUX_PIN(0xff, 166), + MX31_PIN_M_REQUEST = IOMUX_PIN(0xff, 167), + MX31_PIN_PC_POE = IOMUX_PIN(0xff, 168), + MX31_PIN_PC_RW_B = IOMUX_PIN(0xff, 169), + MX31_PIN_IOIS16 = IOMUX_PIN(0xff, 170), + MX31_PIN_PC_RST = IOMUX_PIN(0xff, 171), + MX31_PIN_PC_BVD2 = IOMUX_PIN(0xff, 172), + MX31_PIN_PC_BVD1 = IOMUX_PIN(0xff, 173), + MX31_PIN_PC_VS2 = IOMUX_PIN(0xff, 174), + MX31_PIN_PC_VS1 = IOMUX_PIN(0xff, 175), + MX31_PIN_PC_PWRON = IOMUX_PIN(0xff, 176), + MX31_PIN_PC_READY = IOMUX_PIN(0xff, 177), + MX31_PIN_PC_WAIT_B = IOMUX_PIN(0xff, 178), + MX31_PIN_PC_CD2_B = IOMUX_PIN(0xff, 179), + MX31_PIN_PC_CD1_B = IOMUX_PIN(0xff, 180), + MX31_PIN_D0 = IOMUX_PIN(0xff, 181), + MX31_PIN_D1 = IOMUX_PIN(0xff, 182), + MX31_PIN_D2 = IOMUX_PIN(0xff, 183), + MX31_PIN_D3 = IOMUX_PIN(0xff, 184), + MX31_PIN_D4 = IOMUX_PIN(0xff, 185), + MX31_PIN_D5 = IOMUX_PIN(0xff, 186), + MX31_PIN_D6 = IOMUX_PIN(0xff, 187), + MX31_PIN_D7 = IOMUX_PIN(0xff, 188), + MX31_PIN_D8 = IOMUX_PIN(0xff, 189), + MX31_PIN_D9 = IOMUX_PIN(0xff, 190), + MX31_PIN_D10 = IOMUX_PIN(0xff, 191), + MX31_PIN_D11 = IOMUX_PIN(0xff, 192), + MX31_PIN_D12 = IOMUX_PIN(0xff, 193), + MX31_PIN_D13 = IOMUX_PIN(0xff, 194), + MX31_PIN_D14 = IOMUX_PIN(0xff, 195), + MX31_PIN_D15 = IOMUX_PIN(0xff, 196), + MX31_PIN_NFRB = IOMUX_PIN(16, 197), + MX31_PIN_NFCE_B = IOMUX_PIN(15, 198), + MX31_PIN_NFWP_B = IOMUX_PIN(14, 199), + MX31_PIN_NFCLE = IOMUX_PIN(13, 200), + MX31_PIN_NFALE = IOMUX_PIN(12, 201), + MX31_PIN_NFRE_B = IOMUX_PIN(11, 202), + MX31_PIN_NFWE_B = IOMUX_PIN(10, 203), + MX31_PIN_SDQS3 = IOMUX_PIN(0xff, 204), + MX31_PIN_SDQS2 = IOMUX_PIN(0xff, 205), + MX31_PIN_SDQS1 = IOMUX_PIN(0xff, 206), + MX31_PIN_SDQS0 = IOMUX_PIN(0xff, 207), + MX31_PIN_SDCLK_B = IOMUX_PIN(0xff, 208), + MX31_PIN_SDCLK = IOMUX_PIN(0xff, 209), + MX31_PIN_SDCKE1 = IOMUX_PIN(0xff, 210), + MX31_PIN_SDCKE0 = IOMUX_PIN(0xff, 211), + MX31_PIN_SDWE = IOMUX_PIN(0xff, 212), + MX31_PIN_CAS = IOMUX_PIN(0xff, 213), + MX31_PIN_RAS = IOMUX_PIN(0xff, 214), + MX31_PIN_RW = IOMUX_PIN(0xff, 215), + MX31_PIN_BCLK = IOMUX_PIN(0xff, 216), + MX31_PIN_LBA = IOMUX_PIN(0xff, 217), + MX31_PIN_ECB = IOMUX_PIN(0xff, 218), + MX31_PIN_CS5 = IOMUX_PIN(0xff, 219), + MX31_PIN_CS4 = IOMUX_PIN(0xff, 220), + MX31_PIN_CS3 = IOMUX_PIN(0xff, 221), + MX31_PIN_CS2 = IOMUX_PIN(0xff, 222), + MX31_PIN_CS1 = IOMUX_PIN(0xff, 223), + MX31_PIN_CS0 = IOMUX_PIN(0xff, 224), + MX31_PIN_OE = IOMUX_PIN(0xff, 225), + MX31_PIN_EB1 = IOMUX_PIN(0xff, 226), + MX31_PIN_EB0 = IOMUX_PIN(0xff, 227), + MX31_PIN_DQM3 = IOMUX_PIN(0xff, 228), + MX31_PIN_DQM2 = IOMUX_PIN(0xff, 229), + MX31_PIN_DQM1 = IOMUX_PIN(0xff, 230), + MX31_PIN_DQM0 = IOMUX_PIN(0xff, 231), + MX31_PIN_SD31 = IOMUX_PIN(0xff, 232), + MX31_PIN_SD30 = IOMUX_PIN(0xff, 233), + MX31_PIN_SD29 = IOMUX_PIN(0xff, 234), + MX31_PIN_SD28 = IOMUX_PIN(0xff, 235), + MX31_PIN_SD27 = IOMUX_PIN(0xff, 236), + MX31_PIN_SD26 = IOMUX_PIN(0xff, 237), + MX31_PIN_SD25 = IOMUX_PIN(0xff, 238), + MX31_PIN_SD24 = IOMUX_PIN(0xff, 239), + MX31_PIN_SD23 = IOMUX_PIN(0xff, 240), + MX31_PIN_SD22 = IOMUX_PIN(0xff, 241), + MX31_PIN_SD21 = IOMUX_PIN(0xff, 242), + MX31_PIN_SD20 = IOMUX_PIN(0xff, 243), + MX31_PIN_SD19 = IOMUX_PIN(0xff, 244), + MX31_PIN_SD18 = IOMUX_PIN(0xff, 245), + MX31_PIN_SD17 = IOMUX_PIN(0xff, 246), + MX31_PIN_SD16 = IOMUX_PIN(0xff, 247), + MX31_PIN_SD15 = IOMUX_PIN(0xff, 248), + MX31_PIN_SD14 = IOMUX_PIN(0xff, 249), + MX31_PIN_SD13 = IOMUX_PIN(0xff, 250), + MX31_PIN_SD12 = IOMUX_PIN(0xff, 251), + MX31_PIN_SD11 = IOMUX_PIN(0xff, 252), + MX31_PIN_SD10 = IOMUX_PIN(0xff, 253), + MX31_PIN_SD9 = IOMUX_PIN(0xff, 254), + MX31_PIN_SD8 = IOMUX_PIN(0xff, 255), + MX31_PIN_SD7 = IOMUX_PIN(0xff, 256), + MX31_PIN_SD6 = IOMUX_PIN(0xff, 257), + MX31_PIN_SD5 = IOMUX_PIN(0xff, 258), + MX31_PIN_SD4 = IOMUX_PIN(0xff, 259), + MX31_PIN_SD3 = IOMUX_PIN(0xff, 260), + MX31_PIN_SD2 = IOMUX_PIN(0xff, 261), + MX31_PIN_SD1 = IOMUX_PIN(0xff, 262), + MX31_PIN_SD0 = IOMUX_PIN(0xff, 263), + MX31_PIN_SDBA0 = IOMUX_PIN(0xff, 264), + MX31_PIN_SDBA1 = IOMUX_PIN(0xff, 265), + MX31_PIN_A25 = IOMUX_PIN(0xff, 266), + MX31_PIN_A24 = IOMUX_PIN(0xff, 267), + MX31_PIN_A23 = IOMUX_PIN(0xff, 268), + MX31_PIN_A22 = IOMUX_PIN(0xff, 269), + MX31_PIN_A21 = IOMUX_PIN(0xff, 270), + MX31_PIN_A20 = IOMUX_PIN(0xff, 271), + MX31_PIN_A19 = IOMUX_PIN(0xff, 272), + MX31_PIN_A18 = IOMUX_PIN(0xff, 273), + MX31_PIN_A17 = IOMUX_PIN(0xff, 274), + MX31_PIN_A16 = IOMUX_PIN(0xff, 275), + MX31_PIN_A14 = IOMUX_PIN(0xff, 276), + MX31_PIN_A15 = IOMUX_PIN(0xff, 277), + MX31_PIN_A13 = IOMUX_PIN(0xff, 278), + MX31_PIN_A12 = IOMUX_PIN(0xff, 279), + MX31_PIN_A11 = IOMUX_PIN(0xff, 280), + MX31_PIN_MA10 = IOMUX_PIN(0xff, 281), + MX31_PIN_A10 = IOMUX_PIN(0xff, 282), + MX31_PIN_A9 = IOMUX_PIN(0xff, 283), + MX31_PIN_A8 = IOMUX_PIN(0xff, 284), + MX31_PIN_A7 = IOMUX_PIN(0xff, 285), + MX31_PIN_A6 = IOMUX_PIN(0xff, 286), + MX31_PIN_A5 = IOMUX_PIN(0xff, 287), + MX31_PIN_A4 = IOMUX_PIN(0xff, 288), + MX31_PIN_A3 = IOMUX_PIN(0xff, 289), + MX31_PIN_A2 = IOMUX_PIN(0xff, 290), + MX31_PIN_A1 = IOMUX_PIN(0xff, 291), + MX31_PIN_A0 = IOMUX_PIN(0xff, 292), + MX31_PIN_VPG1 = IOMUX_PIN(0xff, 293), + MX31_PIN_VPG0 = IOMUX_PIN(0xff, 294), + MX31_PIN_DVFS1 = IOMUX_PIN(0xff, 295), + MX31_PIN_DVFS0 = IOMUX_PIN(0xff, 296), + MX31_PIN_VSTBY = IOMUX_PIN(0xff, 297), + MX31_PIN_POWER_FAIL = IOMUX_PIN(0xff, 298), + MX31_PIN_CKIL = IOMUX_PIN(0xff, 299), + MX31_PIN_BOOT_MODE4 = IOMUX_PIN(0xff, 300), + MX31_PIN_BOOT_MODE3 = IOMUX_PIN(0xff, 301), + MX31_PIN_BOOT_MODE2 = IOMUX_PIN(0xff, 302), + MX31_PIN_BOOT_MODE1 = IOMUX_PIN(0xff, 303), + MX31_PIN_BOOT_MODE0 = IOMUX_PIN(0xff, 304), + MX31_PIN_CLKO = IOMUX_PIN(0xff, 305), + MX31_PIN_POR_B = IOMUX_PIN(0xff, 306), + MX31_PIN_RESET_IN_B = IOMUX_PIN(0xff, 307), + MX31_PIN_CKIH = IOMUX_PIN(0xff, 308), + MX31_PIN_SIMPD0 = IOMUX_PIN(35, 309), + MX31_PIN_SRX0 = IOMUX_PIN(34, 310), + MX31_PIN_STX0 = IOMUX_PIN(33, 311), + MX31_PIN_SVEN0 = IOMUX_PIN(32, 312), + MX31_PIN_SRST0 = IOMUX_PIN(67, 313), + MX31_PIN_SCLK0 = IOMUX_PIN(66, 314), + MX31_PIN_GPIO3_1 = IOMUX_PIN(65, 315), + MX31_PIN_GPIO3_0 = IOMUX_PIN(64, 316), + MX31_PIN_GPIO1_6 = IOMUX_PIN( 6, 317), + MX31_PIN_GPIO1_5 = IOMUX_PIN( 5, 318), + MX31_PIN_GPIO1_4 = IOMUX_PIN( 4, 319), + MX31_PIN_GPIO1_3 = IOMUX_PIN( 3, 320), + MX31_PIN_GPIO1_2 = IOMUX_PIN( 2, 321), + MX31_PIN_GPIO1_1 = IOMUX_PIN( 1, 322), + MX31_PIN_GPIO1_0 = IOMUX_PIN( 0, 323), + MX31_PIN_PWMO = IOMUX_PIN( 9, 324), + MX31_PIN_WATCHDOG_RST = IOMUX_PIN(0xff, 325), + MX31_PIN_COMPARE = IOMUX_PIN( 8, 326), + MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327), +}; + +/* + * Convenience values for use with mxc_iomux_mode() + * + * Format here is MX31_PIN_(pin name)__(function) + */ +#define MX31_PIN_CSPI3_MOSI__RXD3 IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_ALT1) +#define MX31_PIN_CSPI3_MISO__TXD3 IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_ALT1) +#define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC) + +/* + * This function configures the pad value for a IOMUX pin. + */ +void mxc_iomux_set_pad(enum iomux_pins, u32); + +#endif + -- cgit v0.10.2 From d0f349fbce2905607e0473d2358f97f48866e52c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:50 +0200 Subject: i.MXC family: Adding timer support This patch adds timer support for the i.MX machine family. This code can be used on the following machs: - i.MX1 (tested) - i.MX2 (i.MX21 (to be tested), i.MX27 (tested)) - i.MX3 (i.MX31 (tested)) TODO: It seems impossible to build a kernel for more than one CPU because the timer do not follow the platform device rules. So it does only work if timer 1 can be accessed on all CPUs at the same address. Signed-off-by: Juergen Beisert Signed-off-by: Sascha Hauer diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5c8c1a8..8a9a84c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -367,6 +367,8 @@ config ARCH_NS9XXX config ARCH_MXC bool "Freescale MXC/iMX-based" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS select ARCH_MTD_XIP select GENERIC_GPIO select HAVE_GPIO_LIB diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 68f062b..562c75d 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o devices.o iomux.o +obj-y := mm.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 5addbb7..eba3e0c 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,16 @@ static void __init mxc_board_init(void) mxc_init_extuart(); } +static void __init mx31ads_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("ipg_clk.0"); +} + +struct sys_timer mx31ads_timer = { + .init = mx31ads_timer_init, +}; + /* * The following uses standard kernel macros defined in arch.h in order to * initialize __mach_desc_MX31ADS data structure. @@ -139,5 +150,5 @@ MACHINE_START(MX31ADS, "Freescale MX31ADS") .map_io = mx31ads_map_io, .init_irq = mxc_init_irq, .init_machine = mxc_board_init, - .timer = &mxc_timer, + .timer = &mx31ads_timer, MACHINE_END diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c deleted file mode 100644 index fb565c9..0000000 --- a/arch/arm/mach-mx3/time.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * System Timer Interrupt reconfigured to run in free-run mode. - * Author: Vitaly Wool - * Copyright 2004 MontaVista Software Inc. - * Copyright 2004-2007 Freescale Semiconductor, 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. - */ - -/*! - * @file time.c - * @brief This file contains OS tick and wdog timer implementations. - * - * This file contains OS tick and wdog timer implementations. - * - * @ingroup Timers - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/*! - * This is the timer interrupt service routine to do required tasks. - * It also services the WDOG timer at the frequency of twice per WDOG - * timeout value. For example, if the WDOG's timeout value is 4 (2 - * seconds since the WDOG runs at 0.5Hz), it will be serviced once - * every 2/2=1 second. - * - * @param irq GPT interrupt source number (not used) - * @param dev_id this parameter is not used - * @return always returns \b IRQ_HANDLED as defined in - * include/linux/interrupt.h. - */ -static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) -{ - unsigned int next_match; - - if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { - do { - timer_tick(); - next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH; - __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR); - __raw_writel(next_match, MXC_GPT_GPTOCR1); - } while ((signed long)(next_match - - __raw_readl(MXC_GPT_GPTCNT)) <= 0); - } - - return IRQ_HANDLED; -} - -/*! - * This function is used to obtain the number of microseconds since the last - * timer interrupt. Note that interrupts is disabled by do_gettimeofday(). - * - * @return the number of microseconds since the last timer interrupt. - */ -static unsigned long mxc_gettimeoffset(void) -{ - unsigned long ticks_to_match, elapsed, usec, tick_usec, i; - - /* Get ticks before next timer match */ - ticks_to_match = - __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT); - - /* We need elapsed ticks since last match */ - elapsed = LATCH - ticks_to_match; - - /* Now convert them to usec */ - /* Insure no overflow when calculating the usec below */ - for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) { - tick_usec /= i; - if ((0xFFFFFFFF / tick_usec) > elapsed) - break; - } - usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i); - - return usec; -} - -/*! - * The OS tick timer interrupt structure. - */ -static struct irqaction timer_irq = { - .name = "MXC Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER, - .handler = mxc_timer_interrupt -}; - -/*! - * This function is used to initialize the GPT to produce an interrupt - * based on HZ. It is called by start_kernel() during system startup. - */ -void __init mxc_init_time(void) -{ - u32 reg, v; - reg = __raw_readl(MXC_GPT_GPTCR); - reg &= ~GPTCR_ENABLE; - __raw_writel(reg, MXC_GPT_GPTCR); - reg |= GPTCR_SWR; - __raw_writel(reg, MXC_GPT_GPTCR); - - while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0) - cpu_relax(); - - reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ; - __raw_writel(reg, MXC_GPT_GPTCR); - - /* TODO: get timer rate from clk driver */ - v = 66500000; - - __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR); - - if ((v % CLOCK_TICK_RATE) != 0) { - pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n", - CLOCK_TICK_RATE); - } - pr_info("Actual CLOCK_TICK_RATE is %d Hz\n", - v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1)); - - reg = __raw_readl(MXC_GPT_GPTCNT); - reg += LATCH; - __raw_writel(reg, MXC_GPT_GPTOCR1); - - setup_irq(MXC_INT_GPT, &timer_irq); - - reg = __raw_readl(MXC_GPT_GPTCR); - reg = - GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN | - GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE; - __raw_writel(reg, MXC_GPT_GPTCR); - - __raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR); -} - -struct sys_timer mxc_timer = { - .init = mxc_init_time, - .offset = mxc_gettimeoffset, -}; diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 66272a6..e3cc25c 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := irq.o clock.o gpio.o +obj-y := irq.o clock.o gpio.o time.o diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c new file mode 100644 index 0000000..3bf8634 --- /dev/null +++ b/arch/arm/plat-mxc/time.c @@ -0,0 +1,228 @@ +/* + * linux/arch/arm/plat-mxc/time.c + * + * Copyright (C) 2000-2001 Deep Blue Solutions + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct clock_event_device clockevent_mxc; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; + +/* clock source for the timer */ +static struct clk *timer_clk; + +/* clock source */ + +static cycle_t mxc_get_cycles(void) +{ + return __raw_readl(TIMER_BASE + MXC_TCN); +} + +static struct clocksource clocksource_mxc = { + .name = "mxc_timer1", + .rating = 200, + .read = mxc_get_cycles, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init mxc_clocksource_init(void) +{ + unsigned int clock; + + clock = clk_get_rate(timer_clk); + + clocksource_mxc.mult = clocksource_hz2mult(clock, + clocksource_mxc.shift); + clocksource_register(&clocksource_mxc); + + return 0; +} + +/* clock event */ + +static int mxc_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long tcmp; + + tcmp = __raw_readl(TIMER_BASE + MXC_TCN) + evt; + __raw_writel(tcmp, TIMER_BASE + MXC_TCMP); + + return (int)(tcmp - __raw_readl(TIMER_BASE + MXC_TCN)) < 0 ? + -ETIME : 0; +} + +#ifdef DEBUG +static const char *clock_event_mode_label[] = { + [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", + [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", + [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", + [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED" +}; +#endif /* DEBUG */ + +static void mxc_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long flags; + + /* + * The timer interrupt generation is disabled at least + * for enough time to call mxc_set_next_event() + */ + local_irq_save(flags); + + /* Disable interrupt in GPT module */ + gpt_irq_disable(); + + if (mode != clockevent_mode) { + /* Set event time into far-far future */ + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCN) - 3, + TIMER_BASE + MXC_TCMP); + /* Clear pending interrupt */ + gpt_irq_acknowledge(); + } + +#ifdef DEBUG + printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", + clock_event_mode_label[clockevent_mode], + clock_event_mode_label[mode]); +#endif /* DEBUG */ + + /* Remember timer mode */ + clockevent_mode = mode; + local_irq_restore(flags); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + printk(KERN_ERR"mxc_set_mode: Periodic mode is not " + "supported for i.MX\n"); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* + * Do not put overhead of interrupt enable/disable into + * mxc_set_next_event(), the core has about 4 minutes + * to call mxc_set_next_event() or shutdown clock after + * mode switching + */ + local_irq_save(flags); + gpt_irq_enable(); + local_irq_restore(flags); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + /* Left event sources disabled, no more interrupts appear */ + break; + } +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_mxc; + uint32_t tstat; + + tstat = __raw_readl(TIMER_BASE + MXC_TSTAT); + + gpt_irq_acknowledge(); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction mxc_timer_irq = { + .name = "i.MX Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = mxc_timer_interrupt, +}; + +static struct clock_event_device clockevent_mxc = { + .name = "mxc_timer1", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_mode = mxc_set_mode, + .set_next_event = mxc_set_next_event, + .rating = 200, +}; + +static int __init mxc_clockevent_init(void) +{ + unsigned int clock; + + clock = clk_get_rate(timer_clk); + + clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC, + clockevent_mxc.shift); + clockevent_mxc.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_mxc); + clockevent_mxc.min_delta_ns = + clockevent_delta2ns(0xff, &clockevent_mxc); + + clockevent_mxc.cpumask = cpumask_of_cpu(0); + + clockevents_register_device(&clockevent_mxc); + + return 0; +} + +void __init mxc_timer_init(const char *clk_timer) +{ + timer_clk = clk_get(NULL, clk_timer); + if (!timer_clk) { + printk(KERN_ERR"Cannot determine timer clock. Giving up.\n"); + return; + } + + clk_enable(timer_clk); + + /* + * Initialise to a known state (all timers off, and timing reset) + */ + __raw_writel(0, TIMER_BASE + MXC_TCTL); + __raw_writel(0, TIMER_BASE + MXC_TPRER); /* see datasheet note */ + + __raw_writel(TCTL_FRR | /* free running */ + TCTL_VAL | /* set clocksource and arch specific bits */ + TCTL_TEN, /* start the timer */ + TIMER_BASE + MXC_TCTL); + + /* init and register the timer to the framework */ + mxc_clocksource_init(); + mxc_clockevent_init(); + + /* Make irqs happen */ + setup_irq(TIMER_INTERRUPT, &mxc_timer_irq); +} + diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h index 8774783..a6d2e24 100644 --- a/include/asm-arm/arch-mxc/common.h +++ b/include/asm-arm/arch-mxc/common.h @@ -11,11 +11,9 @@ #ifndef __ASM_ARCH_MXC_COMMON_H__ #define __ASM_ARCH_MXC_COMMON_H__ -struct sys_timer; - extern void mxc_map_io(void); extern void mxc_init_irq(void); -extern struct sys_timer mxc_timer; +extern void mxc_timer_init(const char *clk_timer); extern int mxc_clocks_init(unsigned long fref); extern int mxc_register_gpios(void); diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h index 146d3f6..1df4e2f 100644 --- a/include/asm-arm/arch-mxc/mxc.h +++ b/include/asm-arm/arch-mxc/mxc.h @@ -1,11 +1,20 @@ /* * Copyright 2004-2007 Freescale Semiconductor, 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. + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ #ifndef __ASM_ARCH_MXC_H__ @@ -22,97 +31,6 @@ /* ***************************************** - * GPT Register definitions * - ***************************************** - */ -#define MXC_GPT_GPTCR IO_ADDRESS(GPT1_BASE_ADDR + 0x00) -#define MXC_GPT_GPTPR IO_ADDRESS(GPT1_BASE_ADDR + 0x04) -#define MXC_GPT_GPTSR IO_ADDRESS(GPT1_BASE_ADDR + 0x08) -#define MXC_GPT_GPTIR IO_ADDRESS(GPT1_BASE_ADDR + 0x0C) -#define MXC_GPT_GPTOCR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x10) -#define MXC_GPT_GPTOCR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x14) -#define MXC_GPT_GPTOCR3 IO_ADDRESS(GPT1_BASE_ADDR + 0x18) -#define MXC_GPT_GPTICR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x1C) -#define MXC_GPT_GPTICR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x20) -#define MXC_GPT_GPTCNT IO_ADDRESS(GPT1_BASE_ADDR + 0x24) - -/* GPT Control register bit definitions */ -#define GPTCR_FO3 (1 << 31) -#define GPTCR_FO2 (1 << 30) -#define GPTCR_FO1 (1 << 29) - -#define GPTCR_OM3_SHIFT 26 -#define GPTCR_OM3_MASK (7 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_DISCONNECTED (0 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_TOGGLE (1 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_CLEAR (2 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_SET (3 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_GENERATE_LOW (7 << GPTCR_OM3_SHIFT) - -#define GPTCR_OM2_SHIFT 23 -#define GPTCR_OM2_MASK (7 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_DISCONNECTED (0 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_TOGGLE (1 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_CLEAR (2 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_SET (3 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_GENERATE_LOW (7 << GPTCR_OM2_SHIFT) - -#define GPTCR_OM1_SHIFT 20 -#define GPTCR_OM1_MASK (7 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_DISCONNECTED (0 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_TOGGLE (1 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_CLEAR (2 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_SET (3 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_GENERATE_LOW (7 << GPTCR_OM1_SHIFT) - -#define GPTCR_IM2_SHIFT 18 -#define GPTCR_IM2_MASK (3 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_DISABLE (0 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_RISING (1 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_FALLING (2 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_BOTH (3 << GPTCR_IM2_SHIFT) - -#define GPTCR_IM1_SHIFT 16 -#define GPTCR_IM1_MASK (3 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_DISABLE (0 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_RISING (1 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_FALLING (2 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_BOTH (3 << GPTCR_IM1_SHIFT) - -#define GPTCR_SWR (1 << 15) -#define GPTCR_FRR (1 << 9) - -#define GPTCR_CLKSRC_SHIFT 6 -#define GPTCR_CLKSRC_MASK (7 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_NOCLOCK (0 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_HIGHFREQ (2 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_CLKIN (3 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_CLK32K (7 << GPTCR_CLKSRC_SHIFT) - -#define GPTCR_STOPEN (1 << 5) -#define GPTCR_DOZEN (1 << 4) -#define GPTCR_WAITEN (1 << 3) -#define GPTCR_DBGEN (1 << 2) - -#define GPTCR_ENMOD (1 << 1) -#define GPTCR_ENABLE (1 << 0) - -#define GPTSR_OF1 (1 << 0) -#define GPTSR_OF2 (1 << 1) -#define GPTSR_OF3 (1 << 2) -#define GPTSR_IF1 (1 << 3) -#define GPTSR_IF2 (1 << 4) -#define GPTSR_ROV (1 << 5) - -#define GPTIR_OF1IE GPTSR_OF1 -#define GPTIR_OF2IE GPTSR_OF2 -#define GPTIR_OF3IE GPTSR_OF3 -#define GPTIR_IF1IE GPTSR_IF1 -#define GPTIR_IF2IE GPTSR_IF2 -#define GPTIR_ROVIE GPTSR_ROV - -/* - ***************************************** * AVIC Registers * ***************************************** */ diff --git a/include/asm-arm/arch-mxc/mxc_timer.h b/include/asm-arm/arch-mxc/mxc_timer.h new file mode 100644 index 0000000..6cb11f4 --- /dev/null +++ b/include/asm-arm/arch-mxc/mxc_timer.h @@ -0,0 +1,158 @@ +/* + * mxc_timer.h + * + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * Platform independent (i.MX1, i.MX2, i.MX3) definition for timer handling. + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PLAT_MXC_TIMER_H +#define __PLAT_MXC_TIMER_H + +#include +#include + +#ifdef CONFIG_ARCH_IMX +#define TIMER_BASE IO_ADDRESS(TIM1_BASE_ADDR) +#define TIMER_INTERRUPT TIM1_INT + +#define TCTL_VAL TCTL_CLK_PCLK1 +#define TCTL_IRQEN (1<<4) +#define TCTL_FRR (1<<8) +#define TCTL_CLK_PCLK1 (1<<1) +#define TCTL_CLK_PCLK1_4 (2<<1) +#define TCTL_CLK_TIN (3<<1) +#define TCTL_CLK_32 (4<<1) + +#define MXC_TCTL 0x00 +#define MXC_TPRER 0x04 +#define MXC_TCMP 0x08 +#define MXC_TCR 0x0c +#define MXC_TCN 0x10 +#define MXC_TSTAT 0x14 +#define TSTAT_CAPT (1<<1) +#define TSTAT_COMP (1<<0) + +static inline void gpt_irq_disable(void) +{ + unsigned int tmp; + + tmp = __raw_readl(TIMER_BASE + MXC_TCTL); + __raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL); +} + +static inline void gpt_irq_enable(void) +{ + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN, + TIMER_BASE + MXC_TCTL); +} + +static void gpt_irq_acknowledge(void) +{ + __raw_writel(0, TIMER_BASE + MXC_TSTAT); +} +#endif /* CONFIG_ARCH_IMX */ + +#ifdef CONFIG_ARCH_MX2 +#define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) +#define TIMER_INTERRUPT MXC_INT_GPT1 + +#define MXC_TCTL 0x00 +#define TCTL_VAL TCTL_CLK_PCLK1 +#define TCTL_CLK_PCLK1 (1<<1) +#define TCTL_CLK_PCLK1_4 (2<<1) +#define TCTL_IRQEN (1<<4) +#define TCTL_FRR (1<<8) +#define MXC_TPRER 0x04 +#define MXC_TCMP 0x08 +#define MXC_TCR 0x0c +#define MXC_TCN 0x10 +#define MXC_TSTAT 0x14 +#define TSTAT_CAPT (1<<1) +#define TSTAT_COMP (1<<0) + +static inline void gpt_irq_disable(void) +{ + unsigned int tmp; + + tmp = __raw_readl(TIMER_BASE + MXC_TCTL); + __raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL); +} + +static inline void gpt_irq_enable(void) +{ + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN, + TIMER_BASE + MXC_TCTL); +} + +static void gpt_irq_acknowledge(void) +{ + __raw_writel(TSTAT_CAPT | TSTAT_COMP, TIMER_BASE + MXC_TSTAT); +} +#endif /* CONFIG_ARCH_MX2 */ + +#ifdef CONFIG_ARCH_MX3 +#define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) +#define TIMER_INTERRUPT MXC_INT_GPT + +#define MXC_TCTL 0x00 +#define TCTL_VAL (TCTL_CLK_IPG | TCTL_WAITEN) +#define TCTL_CLK_IPG (1<<6) +#define TCTL_FRR (1<<9) +#define TCTL_WAITEN (1<<3) + +#define MXC_TPRER 0x04 +#define MXC_TSTAT 0x08 +#define TSTAT_OF1 (1<<0) +#define TSTAT_OF2 (1<<1) +#define TSTAT_OF3 (1<<2) +#define TSTAT_IF1 (1<<3) +#define TSTAT_IF2 (1<<4) +#define TSTAT_ROV (1<<5) +#define MXC_IR 0x0c +#define MXC_TCMP 0x10 +#define MXC_TCMP2 0x14 +#define MXC_TCMP3 0x18 +#define MXC_TCR 0x1c +#define MXC_TCN 0x24 + +static inline void gpt_irq_disable(void) +{ + __raw_writel(0, TIMER_BASE + MXC_IR); +} + +static inline void gpt_irq_enable(void) +{ + __raw_writel(1<<0, TIMER_BASE + MXC_IR); +} + +static inline void gpt_irq_acknowledge(void) +{ + __raw_writel(TSTAT_OF1, TIMER_BASE + MXC_TSTAT); +} +#endif /* CONFIG_ARCH_MX3 */ + +#define TCTL_SWR (1<<15) +#define TCTL_CC (1<<10) +#define TCTL_OM (1<<9) +#define TCTL_CAP_RIS (1<<6) +#define TCTL_CAP_FAL (2<<6) +#define TCTL_CAP_RIS_FAL (3<<6) +#define TCTL_CAP_ENA (1<<5) +#define TCTL_TEN (1<<0) + +#endif -- cgit v0.10.2 From 4bc256501a159abc7e9fee43f63c68894f6a11d8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:51 +0200 Subject: MXC: add debug-macro.S for mxc This patch adds debug-macro.S for arch-mxc Disadvantage: Due to the board specific UART definition, these macros (and compile time) will fail for multi board kernels. Signed-off-by: Sascha Hauer diff --git a/include/asm-arm/arch-mxc/board-mx31ads.h b/include/asm-arm/arch-mxc/board-mx31ads.h index 8590127..1bc6fb0 100644 --- a/include/asm-arm/arch-mxc/board-mx31ads.h +++ b/include/asm-arm/arch-mxc/board-mx31ads.h @@ -109,4 +109,9 @@ #define MXC_MAX_EXP_IO_LINES 16 +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + #endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S new file mode 100644 index 0000000..34befbb --- /dev/null +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -0,0 +1,38 @@ +/* linux/include/asm-arm/arch-imx/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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 + +#ifdef CONFIG_MACH_MX31ADS +#include +#endif + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =MXC_LL_UART_PADDR @ physical + ldrne \rx, =MXC_LL_UART_VADDR @ virtual + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #0x40] @ TXDATA + .endm + + .macro waituart,rd,rx + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #0x98] @ SR2 + tst \rd, #1 << 3 @ TXDC + beq 1002b @ wait until transmit done + .endm -- cgit v0.10.2 From 1b53218bfa4c0e17fc16ff7fadb85b82bbd3c77c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:51 +0200 Subject: i.MX3: Add a basic default config for the imx31ads (reference only) Currently there is a mx31ads BSP file in the kernel, but no default config file. This patch adds a basic default config for the imx31ads but it is for test purposes only to ensure the i.MX2 patch stack doesn't break the i.MX3. Note: For reference only. This configuration is untested as I have no access to an mx31ads. Signed-off-by: Juergen Beisert diff --git a/arch/arm/configs/mx31ads_defconfig b/arch/arm/configs/mx31ads_defconfig new file mode 100644 index 0000000..e052717 --- /dev/null +++ b/arch/arm/configs/mx31ads_defconfig @@ -0,0 +1,839 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Fri Jun 20 16:21:11 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=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 is not set +# 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=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_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=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=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_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_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_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# 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=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +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 + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +# CONFIG_ARCH_MX2 is not set +CONFIG_ARCH_MX3=y + +# +# MX3 Options +# +CONFIG_MACH_MX31ADS=y +# CONFIG_MACH_PCM037 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +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 is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# 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_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 + +# +# 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 + +# +# 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 +# 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=m +# 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=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# 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 +# CONFIG_MTD_OOPS 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=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# 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 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP 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=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# 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=y +# 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_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# 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 +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 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_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT 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_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 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_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 + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_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_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# 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_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# 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_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# 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 +# CONFIG_CIFS 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 is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +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 is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER 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_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 +# CONFIG_CRYPTO_HW is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- cgit v0.10.2 From ce8ffef0bfd6e55d5da3923d8e9af27c3b5c4eff Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:52 +0200 Subject: MX31: add basic pcm037 board support This patch adds basic board support for phytecs pmc037 board. Signed-off-by: Sascha Hauer diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig new file mode 100644 index 0000000..6274745 --- /dev/null +++ b/arch/arm/configs/pcm037_defconfig @@ -0,0 +1,748 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Wed Jun 25 11:52:42 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=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 is not set +# 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=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_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=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=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_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_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_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# 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=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +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 + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX3=y + +# +# MX3 Options +# +# CONFIG_MACH_MX31ADS is not set +CONFIG_MACH_PCM037=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# 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_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 + +# +# 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 + +# +# 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 +# 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=m +# 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_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# 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 +# CONFIG_MTD_OOPS 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_CFI_NOSWAP is not set +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP 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 is not set +# CONFIG_MTD_CFI_STAA is not set +# 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_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# 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 + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# 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 +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_SMC91X=y +# CONFIG_DM9000 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_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT 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_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 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_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 + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_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_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# 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_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN 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_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# 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 +# CONFIG_CIFS 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 is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# 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_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 5fe8606..8b7b49a 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -8,5 +8,11 @@ config MACH_MX31ADS Include support for MX31ADS platform. This includes specific configurations for the board and its peripherals. +config MACH_PCM037 + bool "Support Phytec pcm037 platforms" + help + Include support for Phytec pcm037 platform. This includes + specific configurations for the board and its peripherals. + endmenu diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 562c75d..b09ca60 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -6,3 +6,4 @@ obj-y := mm.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o +obj-$(CONFIG_MACH_PCM037) += pcm037.o diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c new file mode 100644 index 0000000..a34ae6d --- /dev/null +++ b/arch/arm/mach-mx3/pcm037.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2008 Sascha Hauer, Pengutronix + * + * 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 +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct physmap_flash_data pcm037_flash_data = { + .width = 2, +}; + +static struct resource pcm037_flash_resource = { + .start = 0xa0000000, + .end = 0xa1ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device pcm037_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &pcm037_flash_data, + }, + .resource = &pcm037_flash_resource, + .num_resources = 1, +}; + +static struct imxuart_platform_data uart_pdata = { + .flags = 0, +}; + +static struct platform_device *devices[] __initdata = { + &pcm037_flash, +}; + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); + + mxc_iomux_mode(MX31_PIN_CTS1__CTS1); + mxc_iomux_mode(MX31_PIN_RTS1__RTS1); + mxc_iomux_mode(MX31_PIN_TXD1__TXD1); + mxc_iomux_mode(MX31_PIN_RXD1__RXD1); + + imx_init_uart(0, &uart_pdata); + + mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3); + mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3); + + imx_init_uart(2, &uart_pdata); +} + +/* + * This structure defines static mappings for the pcm037 board. + */ +static struct map_desc pcm037_io_desc[] __initdata = { + { + .virtual = AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_DEVICE + }, { + .virtual = AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_DEVICE + }, +}; + +/* + * Set up static virtual mappings. + */ +void __init pcm037_map_io(void) +{ + mxc_map_io(); + iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc)); +} + +static void __init pcm037_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("ipg_clk.0"); +} + +struct sys_timer pcm037_timer = { + .init = pcm037_timer_init, +}; + +MACHINE_START(PCM037, "Phytec Phycore pcm037") + /* Maintainer: Pengutronix */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = pcm037_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &pcm037_timer, +MACHINE_END + diff --git a/include/asm-arm/arch-mxc/board-pcm037.h b/include/asm-arm/arch-mxc/board-pcm037.h new file mode 100644 index 0000000..82232ba --- /dev/null +++ b/include/asm-arm/arch-mxc/board-pcm037.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008 Sascha Hauer, Pengutronix + * + * 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_MXC_BOARD_PCM037_H__ +#define __ASM_ARCH_MXC_BOARD_PCM037_H__ + +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +#endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index 34befbb..81caa0a 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -16,6 +16,9 @@ #ifdef CONFIG_MACH_MX31ADS #include #endif +#ifdef CONFIG_MACH_PCM037 +#include +#endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 -- cgit v0.10.2 From 9a4cd7a5c836e189a1712c9ffd2d76b2302ce212 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 5 Jul 2008 10:02:53 +0200 Subject: MX3: Add basic support for LogicPD i.MX31 LiteKit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds basic support for i.MX31 LiteKit by LogicPD. With printascii() in kernel/printk.c, it boots right into the rootfs-panic. Note: This is a modified version of Daniel's patch to fit into this patch stack. > On 09.06.2008, at 17:26, Russell King - ARM Linux wrote: > > > I would much prefer it if board specific includes were included by the > > code which needs them rather than in asm/arch/hardware.h.  With the > > device model, drivers shouldn't need to include any board specific > > includes - only the board specific C file should need it. > > The new version of this patch (#5102) has been uploaded to the patch > tracker this morning. Signed-off-by: Daniel Mack -- arch/arm/configs/mx31litekit_defconfig | 1100 ++++++++++++++++++++++++++++++ arch/arm/mach-mx3/Kconfig | 7 arch/arm/mach-mx3/Makefile | 1 arch/arm/mach-mx3/mx31lite.c | 96 ++ include/asm-arm/arch-mxc/board-mx31lite.h | 38 + include/asm-arm/arch-mxc/debug-macro.S | 3 6 files changed, 1245 insertions(+) diff --git a/arch/arm/configs/mx31litekit_defconfig b/arch/arm/configs/mx31litekit_defconfig new file mode 100644 index 0000000..4f41c41 --- /dev/null +++ b/arch/arm/configs/mx31litekit_defconfig @@ -0,0 +1,1100 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc5 +# Fri Jun 13 14:23:39 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +# CONFIG_GENERIC_TIME is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=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 is not set +# 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=14 +# 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 +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=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=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_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_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# 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=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +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 + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX3=y + +# +# MX3 Options +# +# CONFIG_MACH_MX31ADS is not set +CONFIG_MACH_MX31LITE=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +# CONFIG_PCMCIA is not set + +# +# PC-card bridges +# + +# +# Kernel Features +# +# CONFIG_TICK_ONESHOT is not set +CONFIG_PREEMPT=y +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +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 is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# 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_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 + +# +# 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 + +# +# 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 +# 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=m +# 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 +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# 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 +# CONFIG_MTD_OOPS 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=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# 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 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP 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=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# 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=y +# 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_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# 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 is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# 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 is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# 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 is not set +# 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_DEBUG is not set +# 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 +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 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_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# 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_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN 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 is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# 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 is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE 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=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 + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# 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_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL 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 is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# 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 +# +# CONFIG_USB_DEVICEFS is not set +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_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB 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_SL811_HCD is not set +# CONFIG_USB_R8A66597_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 + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# 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_AUERSWALD 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_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_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_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# 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_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# 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_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# 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 +# CONFIG_CIFS 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 is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +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 is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +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_PREEMPT=y +# 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_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT 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_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER 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_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 +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 8b7b49a..db9431d 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -14,5 +14,12 @@ config MACH_PCM037 Include support for Phytec pcm037 platform. This includes specific configurations for the board and its peripherals. +config MACH_MX31LITE + bool "Support MX31 LITEKIT (LogicPD)" + default n + help + Include support for MX31 LITEKIT platform. This includes specific + configurations for the board and its peripherals. + endmenu diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index b09ca60..8b21abb 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -6,4 +6,5 @@ obj-y := mm.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o +obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o obj-$(CONFIG_MACH_PCM037) += pcm037.o diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c new file mode 100644 index 0000000..ea23a8e --- /dev/null +++ b/arch/arm/mach-mx3/mx31lite.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2005-2007 Freescale Semiconductor, 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. + * + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This file contains the board-specific initialization routines. + */ + +/* + * This structure defines the MX31 memory map. + */ +static struct map_desc mx31lite_io_desc[] __initdata = { + { + .virtual = AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_NONSHARED_DEVICE + }, { + .virtual = SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_NONSHARED_DEVICE + }, { + .virtual = AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_NONSHARED_DEVICE + }, { + .virtual = CS4_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(CS4_BASE_ADDR), + .length = CS4_SIZE, + .type = MT_DEVICE + } +}; + +/* + * Set up static virtual mappings. + */ +void __init mx31lite_map_io(void) +{ + mxc_map_io(); + iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc)); +} + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ +} + +/* + * The following uses standard kernel macros defined in arch.h in order to + * initialize __mach_desc_MX31LITE data structure. + */ + +MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT") + /* Maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx31lite_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/include/asm-arm/arch-mxc/board-mx31lite.h b/include/asm-arm/arch-mxc/board-mx31lite.h new file mode 100644 index 0000000..e4e5cf5 --- /dev/null +++ b/include/asm-arm/arch-mxc/board-mx31lite.h @@ -0,0 +1,38 @@ +/* + * Copyright 2007 Freescale Semiconductor, 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. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__ +#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__ + +#define MXC_MAX_EXP_IO_LINES 16 + + +/* + * Memory Size parameters + */ + +/* + * Size of SDRAM memory + */ +#define SDRAM_MEM_SIZE SZ_128M +/* + * Size of MBX buffer memory + */ +#define MXC_MBX_MEM_SIZE SZ_16M +/* + * Size of memory available to kernel + */ +#define MEM_SIZE (SDRAM_MEM_SIZE - MXC_MBX_MEM_SIZE) + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ + diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index 81caa0a..5add48b 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -19,6 +19,9 @@ #ifdef CONFIG_MACH_PCM037 #include #endif +#ifdef CONFIG_MACH_MX31LITE +#include +#endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 -- cgit v0.10.2 From 9e8a30dce1bd38cf7b941c707da504d28a907f5c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:53 +0200 Subject: MX3: Adapt mx31lite to new timer init style This patch converts the external "add_mx31lite-basic_defconfig.diff" to our MXC implementation. Note: This patch fixes a board reference only. Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index ea23a8e..1372c1a 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,16 @@ static void __init mxc_board_init(void) { } +static void __init mx31lite_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("ipg_clk.0"); +} + +struct sys_timer mx31lite_timer = { + .init = mx31lite_timer_init, +}; + /* * The following uses standard kernel macros defined in arch.h in order to * initialize __mach_desc_MX31LITE data structure. @@ -92,5 +103,5 @@ MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT") .map_io = mx31lite_map_io, .init_irq = mxc_init_irq, .init_machine = mxc_board_init, - .timer = &mxc_timer, + .timer = &mx31lite_timer, MACHINE_END -- cgit v0.10.2 From 259bcaae9a2f28d7e3303b202b64a1fb0a9ab9e4 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:54 +0200 Subject: MXC arch: Simplify architecture's irq sources Simplify architecture's irq headers and sources, to share these files between MXC3 and MXC2. Signed-off-by: Juergen Beisert diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c index 88f0cfa..1fbe01d 100644 --- a/arch/arm/plat-mxc/irq.c +++ b/arch/arm/plat-mxc/irq.c @@ -1,24 +1,59 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ -/* - * 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 -#include -#include -#include -#include -#include +#include #include -#include -#include #include +#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR) +#define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */ +#define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */ +#define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */ +#define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */ +#define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */ +#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ +#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ +#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ +#define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ +#define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */ +#define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */ +#define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */ +#define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */ +#define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */ +#define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */ +#define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */ +#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ +#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ +#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ +#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */ +#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */ +#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */ +#define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */ +#define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */ +#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */ +#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */ + +#define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) +#define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) +#define IIM_PROD_REV_SH 3 +#define IIM_PROD_REV_LEN 5 + /* Disable interrupt number "irq" in the AVIC */ static void mxc_mask_irq(unsigned int irq) { @@ -32,7 +67,7 @@ static void mxc_unmask_irq(unsigned int irq) } static struct irq_chip mxc_avic_chip = { - .mask_ack = mxc_mask_irq, + .ack = mxc_mask_irq, .mask = mxc_mask_irq, .unmask = mxc_unmask_irq, }; diff --git a/include/asm-arm/arch-mxc/irqs.h b/include/asm-arm/arch-mxc/irqs.h index b2c5205..f416130 100644 --- a/include/asm-arm/arch-mxc/irqs.h +++ b/include/asm-arm/arch-mxc/irqs.h @@ -13,17 +13,4 @@ #include -#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) - -#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_GPIO_INT_BASE) -#define MXC_GPIO_TO_IRQ(x) (MXC_GPIO_INT_BASE + x) - -/* Number of normal interrupts */ -#define NR_IRQS (MXC_MAX_INT_LINES + \ - MXC_MAX_GPIO_LINES + \ - MXC_MAX_VIRTUAL_INTS) - -/* Number of fast interrupts */ -#define NR_FIQS MXC_MAX_INTS - #endif /* __ASM_ARCH_MXC_IRQS_H__ */ diff --git a/include/asm-arm/arch-mxc/mx31.h b/include/asm-arm/arch-mxc/mx31.h index 98e6a4c..a7373e4 100644 --- a/include/asm-arm/arch-mxc/mx31.h +++ b/include/asm-arm/arch-mxc/mx31.h @@ -320,6 +320,8 @@ #define MXC_MAX_GPIO_LINES (GPIO_NUM_PIN * GPIO_PORT_NUM) #define MXC_MAX_VIRTUAL_INTS 16 +#define NR_IRQS (MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES + MXC_MAX_VIRTUAL_INTS) + /*! * Number of GPIO port as defined in the IC Spec */ diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h index 1df4e2f..3e1c4de 100644 --- a/include/asm-arm/arch-mxc/mxc.h +++ b/include/asm-arm/arch-mxc/mxc.h @@ -29,42 +29,4 @@ # define cpu_is_mx31() (0) #endif -/* - ***************************************** - * AVIC Registers * - ***************************************** - */ -#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR) -#define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */ -#define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */ -#define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */ -#define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */ -#define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */ -#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ -#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ -#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ -#define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ -#define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */ -#define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */ -#define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */ -#define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */ -#define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */ -#define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */ -#define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */ -#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ -#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ -#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ -#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */ -#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */ -#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */ -#define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */ -#define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */ -#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */ -#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */ - -#define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) -#define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) -#define IIM_PROD_REV_SH 3 -#define IIM_PROD_REV_LEN 5 - #endif /* __ASM_ARCH_MXC_H__ */ -- cgit v0.10.2 From aa10abd381b9493a88f6b9e111adc79e33d548fa Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:55 +0200 Subject: i.MX2 family: Add GPIO multiplexing support This patch adds GPIO multiplexing support for the imx1/mxc2 family of procesors. Signed-off-by: Juergen Beisert diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index e3cc25c..db66e9a 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -4,3 +4,5 @@ # Common support obj-y := irq.o clock.o gpio.o time.o + +obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o diff --git a/arch/arm/plat-mxc/iomux-mx1-mx2.c b/arch/arm/plat-mxc/iomux-mx1-mx2.c new file mode 100644 index 0000000..1985571 --- /dev/null +++ b/arch/arm/plat-mxc/iomux-mx1-mx2.c @@ -0,0 +1,156 @@ +/* + * arch/arm/mach-mxc/generic.c + * + * author: Sascha Hauer + * Created: april 20th, 2004 + * Copyright: Synertronixx GmbH + * + * Common code for i.MX machines + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include + +void mxc_gpio_mode(int gpio_mode) +{ + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; + unsigned int tmp; + + /* Pullup enable */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port)); + if (gpio_mode & GPIO_PUEN) + tmp |= (1 << pin); + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port)); + + /* Data direction */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port)); + if (gpio_mode & GPIO_OUT) + tmp |= 1 << pin; + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port)); + + /* Primary / alternate function */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port)); + if (gpio_mode & GPIO_AF) + tmp |= (1 << pin); + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port)); + + /* use as gpio? */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port)); + if (gpio_mode & (GPIO_PF | GPIO_AF)) + tmp &= ~(1 << pin); + else + tmp |= (1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); + + if (pin < 16) { + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); + } else { + pin -= 16; + + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port)); + } +} +EXPORT_SYMBOL(mxc_gpio_mode); + +int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, + int alloc_mode, const char *label) +{ + const int *p = pin_list; + int i; + unsigned gpio; + unsigned mode; + + for (i = 0; i < count; i++) { + gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); + mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK); + + if (gpio >= (GPIO_PORT_MAX + 1) * 32) + goto setup_error; + + if (alloc_mode & MXC_GPIO_ALLOC_MODE_RELEASE) + gpio_free(gpio); + else if (!(alloc_mode & MXC_GPIO_ALLOC_MODE_NO_ALLOC)) + if (gpio_request(gpio, label) + && !(alloc_mode & MXC_GPIO_ALLOC_MODE_TRY_ALLOC)) + goto setup_error; + + if (!(alloc_mode & (MXC_GPIO_ALLOC_MODE_ALLOC_ONLY | + MXC_GPIO_ALLOC_MODE_RELEASE))) + mxc_gpio_mode(gpio | mode); + + p++; + } + return 0; + +setup_error: + if (alloc_mode & (MXC_GPIO_ALLOC_MODE_NO_ALLOC | + MXC_GPIO_ALLOC_MODE_TRY_ALLOC)) + return -EINVAL; + + while (p != pin_list) { + p--; + gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); + gpio_free(gpio); + } + + return -EINVAL; +} +EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins); + diff --git a/include/asm-arm/arch-mxc/iomux-mx1-mx2.h b/include/asm-arm/arch-mxc/iomux-mx1-mx2.h new file mode 100644 index 0000000..076d37b --- /dev/null +++ b/include/asm-arm/arch-mxc/iomux-mx1-mx2.h @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef _MXC_GPIO_MX1_MX2_H +#define _MXC_GPIO_MX1_MX2_H + +#include + +#define MXC_GPIO_ALLOC_MODE_NORMAL 0 +#define MXC_GPIO_ALLOC_MODE_NO_ALLOC 1 +#define MXC_GPIO_ALLOC_MODE_TRY_ALLOC 2 +#define MXC_GPIO_ALLOC_MODE_ALLOC_ONLY 4 +#define MXC_GPIO_ALLOC_MODE_RELEASE 8 + +/* + * GPIO Module and I/O Multiplexer + * x = 0..3 for reg_A, reg_B, reg_C, reg_D + */ +#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) +#define MXC_DDIR(x) (0x00 + ((x) << 8)) +#define MXC_OCR1(x) (0x04 + ((x) << 8)) +#define MXC_OCR2(x) (0x08 + ((x) << 8)) +#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) +#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) +#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) +#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) +#define MXC_DR(x) (0x1c + ((x) << 8)) +#define MXC_GIUS(x) (0x20 + ((x) << 8)) +#define MXC_SSR(x) (0x24 + ((x) << 8)) +#define MXC_ICR1(x) (0x28 + ((x) << 8)) +#define MXC_ICR2(x) (0x2c + ((x) << 8)) +#define MXC_IMR(x) (0x30 + ((x) << 8)) +#define MXC_ISR(x) (0x34 + ((x) << 8)) +#define MXC_GPR(x) (0x38 + ((x) << 8)) +#define MXC_SWR(x) (0x3c + ((x) << 8)) +#define MXC_PUEN(x) (0x40 + ((x) << 8)) + +#ifdef CONFIG_ARCH_MX1 +# define GPIO_PORT_MAX 3 +#endif +#ifdef CONFIG_ARCH_MX2 +# define GPIO_PORT_MAX 5 +#endif + +#ifndef GPIO_PORT_MAX +# error "GPIO config port count unknown!" +#endif + +#define GPIO_PIN_MASK 0x1f + +#define GPIO_PORT_SHIFT 5 +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) + +#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) + +#define GPIO_OUT (1 << 8) +#define GPIO_IN (0 << 8) +#define GPIO_PUEN (1 << 9) + +#define GPIO_PF (1 << 10) +#define GPIO_AF (1 << 11) + +#define GPIO_OCR_SHIFT 12 +#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) +#define GPIO_AIN (0 << GPIO_OCR_SHIFT) +#define GPIO_BIN (1 << GPIO_OCR_SHIFT) +#define GPIO_CIN (2 << GPIO_OCR_SHIFT) +#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) + +#define GPIO_AOUT_SHIFT 14 +#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) + +#define GPIO_BOUT_SHIFT 16 +#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) + +extern void mxc_gpio_mode(int gpio_mode); +extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, + int alloc_mode, const char *label); + +/*-------------------------------------------------------------------------*/ + +/* assignements for GPIO alternate/primary functions */ + +/* FIXME: This list is not completed. The correct directions are + * missing on some (many) pins + */ +#ifdef CONFIG_ARCH_MX1 +#define PA0_AIN_SPI2_CLK (GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 0) +#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0) +#define PA1_AOUT_SPI2_RXD (GPIO_GIUS | GPIO_PORTA | GPIO_IN | 1) +#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1) +#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 2) +#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3) +#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4) +#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5) +#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6) +#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7) +#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8) +#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9) +#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10) +#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11) +#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12) +#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13) +#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14) +#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15) +#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16) +#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17) +#define PA17_AIN_SPI2_SS (GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 17) +#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18) +#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19) +#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20) +#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21) +#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22) +#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23) +#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24) +#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24) +#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25) +#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25) +#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26) +#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26) +#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27) +#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27) +#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28) +#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28) +#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29) +#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29) +#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30) +#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30) +#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31) +#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31) +#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8) +#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8) +#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9) +#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9) +#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10) +#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10) +#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11) +#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11) +#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12) +#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12) +#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13) +#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13) +#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14) +#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15) +#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_IN | GPIO_AF | 16) +#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_OUT | GPIO_AF | 17) +#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18) +#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19) +#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20) +#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21) +#define PB22_PFUSBD_RCV (GPIO_PORTB | GPIO_PF | 22) +#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23) +#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24) +#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25) +#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26) +#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27) +#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_OUT | GPIO_PF | 28) +#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 29) +#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_OUT | GPIO_PF | 30) +#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_IN | GPIO_PF | 31) +#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3) +#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4) +#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_IN | GPIO_PF | 5) +#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_OUT | GPIO_PF | 6) +#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7) +#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8) +#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9) +#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_IN | GPIO_PF | 10) +#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11) +#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 12) +#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13) +#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14) +#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15) +#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16) +#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17) +#define PC24_BIN_UART3_RI (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24) +#define PC25_BIN_UART3_DSR (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25) +#define PC26_AOUT_UART3_DTR (GPIO_GIUS | GPIO_PORTC | GPIO_IN | 26) +#define PC27_BIN_UART3_DCD (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27) +#define PC28_BIN_UART3_CTS (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28) +#define PC29_AOUT_UART3_RTS (GPIO_GIUS | GPIO_PORTC | GPIO_IN | 29) +#define PC30_BIN_UART3_TX (GPIO_GIUS | GPIO_PORTC | GPIO_BIN | 30) +#define PC31_AOUT_UART3_RX (GPIO_GIUS | GPIO_PORTC | GPIO_IN | 31) +#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 6) +#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7) +#define PD7_AF_UART2_DTR (GPIO_GIUS | GPIO_PORTD | GPIO_IN | GPIO_AF | 7) +#define PD7_AIN_SPI2_SCLK (GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 7) +#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8) +#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_OUT | GPIO_AF | 8) +#define PD8_AIN_SPI2_SS (GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 8) +#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9) +#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_OUT | GPIO_AF | 9) +#define PD9_AOUT_SPI2_RXD (GPIO_GIUS | GPIO_PORTD | GPIO_IN | 9) +#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_OUT | GPIO_PF | 10) +#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_OUT | GPIO_AF | 10) +#define PD10_AIN_SPI2_TXD (GPIO_GIUS | GPIO_PORTD | GPIO_OUT | 10) +#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_OUT | GPIO_PF | 11) +#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_OUT | GPIO_PF | 12) +#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 13) +#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 14) +#define PD15_PF_LD0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 15) +#define PD16_PF_LD1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 16) +#define PD17_PF_LD2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) +#define PD18_PF_LD3 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) +#define PD19_PF_LD4 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 19) +#define PD20_PF_LD5 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 20) +#define PD21_PF_LD6 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 21) +#define PD22_PF_LD7 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 22) +#define PD23_PF_LD8 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 23) +#define PD24_PF_LD9 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 24) +#define PD25_PF_LD10 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) +#define PD26_PF_LD11 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) +#define PD27_PF_LD12 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) +#define PD28_PF_LD13 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) +#define PD29_PF_LD14 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) +#define PD30_PF_LD15 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 30) +#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31) +#define PD31_BIN_SPI2_TXD (GPIO_GIUS | GPIO_PORTD | GPIO_BIN | 31) +#endif + +#ifdef CONFIG_ARCH_MX2 +#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_OUT | GPIO_PF | 5) +#define PA6_PF_LD0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 6) +#define PA7_PF_LD1 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 7) +#define PA8_PF_LD2 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 8) +#define PA9_PF_LD3 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 9) +#define PA10_PF_LD4 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 10) +#define PA11_PF_LD5 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 11) +#define PA12_PF_LD6 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 12) +#define PA13_PF_LD7 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 13) +#define PA14_PF_LD8 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 14) +#define PA15_PF_LD9 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15) +#define PA16_PF_LD10 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16) +#define PA17_PF_LD11 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 17) +#define PA18_PF_LD12 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 18) +#define PA19_PF_LD13 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 19) +#define PA20_PF_LD14 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 20) +#define PA21_PF_LD15 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 21) +#define PA22_PF_LD16 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 22) +#define PA23_PF_LD17 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 23) +#define PA24_PF_REV (GPIO_PORTA | GPIO_OUT | GPIO_PF | 24) +#define PA25_PF_CLS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 25) +#define PA26_PF_PS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 26) +#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_OUT | GPIO_PF | 27) +#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 28) +#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 29) +#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_OUT | GPIO_PF | 30) +#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_OUT | GPIO_PF | 31) +#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 10) +#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 10) +#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 11) +#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 11) +#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 12) +#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 12) +#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 13) +#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 13) +#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 14) +#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 15) +#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 16) +#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 17) +#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 18) +#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 18) +#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 19) +#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 19) +#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 20) +#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 20) +#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 21) +#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 21) +#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 26) +#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 28) +#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 29) +#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 31) +#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_IN | GPIO_PF | 5) +#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_IN | GPIO_PF | 6) +#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 16) +#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 17) +#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 18) +#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 19) +#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 20) +#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 21) +#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 22) +#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 23) +#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 24) +#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 25) +#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 26) +#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 27) +#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 28) +#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 29) +#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 30) +#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 31) +#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 0) +#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 1) +#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 2) +#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 3) +#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 4) +#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 5) +#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 6) +#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 7) +#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_IN | GPIO_AF | 8) +#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 9) +#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 10) +#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 11) +#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 12) +#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 13) +#define PD14_AOUT_FEC_CLR (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 14) +#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 15) +#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16) +#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) +#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) +#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) +#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) +#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) +#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) +#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) +#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_IN | GPIO_PF | 30) +#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_OUT | GPIO_PF | 31) +#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_OUT | GPIO_AIN | 23) +#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 3) +#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 4) +#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 6) +#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 7) +#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 8) +#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 9) +#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 10) +#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 11) +#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12) +#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13) +#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14) +#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 15) +#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_IN | GPIO_AF | 18) +#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_OUT | GPIO_AF | 21) +#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_OUT | GPIO_AF | 22) +#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_OUT | GPIO_AF | 23) +#endif + +/* decode irq number to use with IMR(x), ISR(x) and friends */ +#define IRQ_TO_REG(irq) ((irq - MXC_MAX_INT_LINES) >> 5) + +#define IRQ_GPIOA(x) (MXC_MAX_INT_LINES + x) +#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) +#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) +#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) + +#endif /* _MXC_GPIO_MX1_MX2_H */ -- cgit v0.10.2 From eea643f7ff04fe17c3ff71d41a9487c0753bd821 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:56 +0200 Subject: i.MX2 family: Add basic mach support (sources) This patch adds basic mach support for the mx2 processor family, based on the original freescale code and adapted to mainline kernel coding style. Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig new file mode 100644 index 0000000..23def05 --- /dev/null +++ b/arch/arm/mach-mx2/Kconfig @@ -0,0 +1,5 @@ +comment "MX2 family CPU support" + depends on ARCH_MX2 + +comment "MX2 Platforms" + depends on ARCH_MX2 diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile new file mode 100644 index 0000000..937192d --- /dev/null +++ b/arch/arm/mach-mx2/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := system.o generic.o diff --git a/arch/arm/mach-mx2/Makefile.boot b/arch/arm/mach-mx2/Makefile.boot new file mode 100644 index 0000000..696831d --- /dev/null +++ b/arch/arm/mach-mx2/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0xA0008000 +params_phys-y := 0xA0000100 +initrd_phys-y := 0xA0800000 diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c new file mode 100644 index 0000000..07875cf --- /dev/null +++ b/arch/arm/mach-mx2/generic.c @@ -0,0 +1,74 @@ +/* + * generic.c + * + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +/* MX27 memory map definition */ +static struct map_desc mxc_io_desc[] __initdata = { + /* + * this fixed mapping covers: + * - AIPI1 + * - AIPI2 + * - AITC + * - ROM Patch + * - and some reserved space + */ + { + .virtual = AIPI_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPI_BASE_ADDR), + .length = AIPI_SIZE, + .type = MT_DEVICE + }, + /* + * this fixed mapping covers: + * - CSI + * - ATA + */ + { + .virtual = SAHB1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SAHB1_BASE_ADDR), + .length = SAHB1_SIZE, + .type = MT_DEVICE + }, + /* + * this fixed mapping covers: + * - EMI + */ + { + .virtual = X_MEMC_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), + .length = X_MEMC_SIZE, + .type = MT_DEVICE + } +}; + +/* + * Initialize the memory map. It is called during the + * system startup to create static physical to virtual + * memory map for the IO modules. + */ +void __init mxc_map_io(void) +{ + iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); +} diff --git a/arch/arm/mach-mx2/system.c b/arch/arm/mach-mx2/system.c new file mode 100644 index 0000000..9930464 --- /dev/null +++ b/arch/arm/mach-mx2/system.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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 +#include +#include + +#include +#include +#include + +/* + * Put the CPU into idle mode. It is called by default_idle() + * in process.c file. + */ +void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks. + */ + cpu_do_idle(); +} + +#define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR) +#define WDOG_WCR_SRS (1 << 4) + +/* + * Reset the system. It is called by machine_restart(). + */ +void arch_reset(char mode) +{ + struct clk *clk; + + clk = clk_get(NULL, "wdog_clk"); + if (!clk) { + printk(KERN_ERR"Cannot activate the watchdog. Giving up\n"); + return; + } + + clk_enable(clk); + + /* Assert SRS signal */ + __raw_writew(__raw_readw(WDOG_WCR_REG) & ~WDOG_WCR_SRS, WDOG_WCR_REG); +} -- cgit v0.10.2 From 32dc80c9cb13a7ce686bcc26efcf39e35719b466 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:56 +0200 Subject: i.MX2 family: Add basic mach support (headers) This patch adds basic mach support for the mx2 processor family, based on the original freescale code and adapted to mainline kernel coding style. Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h new file mode 100644 index 0000000..a40a9b9 --- /dev/null +++ b/arch/arm/mach-mx2/crm_regs.h @@ -0,0 +1,273 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ARCH_ARM_MACH_MX2_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX2_CRM_REGS_H__ + +#include + +/* Register offsets */ +#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0) +#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4) +#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8) +#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC) +#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c) +#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c) +#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) + +#define CCM_CSCR_USB_OFFSET 28 +#define CCM_CSCR_USB_MASK (0x7 << 28) +#define CCM_CSCR_SD_OFFSET 24 +#define CCM_CSCR_SD_MASK (0x3 << 24) +#define CCM_CSCR_SSI2 (1 << 23) +#define CCM_CSCR_SSI2_OFFSET 23 +#define CCM_CSCR_SSI1 (1 << 22) +#define CCM_CSCR_SSI1_OFFSET 22 +#define CCM_CSCR_VPU (1 << 21) +#define CCM_CSCR_VPU_OFFSET 21 +#define CCM_CSCR_MSHC (1 << 20) +#define CCM_CSCR_SPLLRES (1 << 19) +#define CCM_CSCR_MPLLRES (1 << 18) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_ARM_SRC (1 << 15) +#define CCM_CSCR_ARM_OFFSET 12 +#define CCM_CSCR_ARM_MASK (0x3 << 12) +/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_PRESC_OFFSET 13 +#define CCM_CSCR_PRESC_MASK (0x7 << 13) +#define CCM_CSCR_BCLK_OFFSET 9 +#define CCM_CSCR_BCLK_MASK (0xf << 9) +#define CCM_CSCR_IPDIV_OFFSET 8 +#define CCM_CSCR_IPDIV (1 << 8) +/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_AHB_OFFSET 8 +#define CCM_CSCR_AHB_MASK (0x3 << 8) +/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN 1 + +#define CCM_MPCTL0_CPLM (1 << 31) +#define CCM_MPCTL0_PD_OFFSET 26 +#define CCM_MPCTL0_PD_MASK (0xf << 26) +#define CCM_MPCTL0_MFD_OFFSET 16 +#define CCM_MPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_MPCTL0_MFI_OFFSET 10 +#define CCM_MPCTL0_MFI_MASK (0xf << 10) +#define CCM_MPCTL0_MFN_OFFSET 0 +#define CCM_MPCTL0_MFN_MASK 0x3ff + +#define CCM_MPCTL1_LF (1 << 15) +#define CCM_MPCTL1_BRMO (1 << 6) + +#define CCM_SPCTL0_CPLM (1 << 31) +#define CCM_SPCTL0_PD_OFFSET 26 +#define CCM_SPCTL0_PD_MASK (0xf << 26) +#define CCM_SPCTL0_MFD_OFFSET 16 +#define CCM_SPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_SPCTL0_MFI_OFFSET 10 +#define CCM_SPCTL0_MFI_MASK (0xf << 10) +#define CCM_SPCTL0_MFN_OFFSET 0 +#define CCM_SPCTL0_MFN_MASK 0x3ff + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +#define CCM_OSC26MCTL_PEAK_OFFSET 16 +#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) +#define CCM_OSC26MCTL_AGC_OFFSET 8 +#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) +#define CCM_OSC26MCTL_ANATEST_OFFSET 0 +#define CCM_OSC26MCTL_ANATEST_MASK 0x3f + +#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 +#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) +#define CCM_PCDR0_CLKO_EN 25 +#define CCM_PCDR0_CLKODIV_OFFSET 22 +#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22) +#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 +#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) +/*The difinition for i.MX27 TO2*/ +#define CCM_PCDR0_VPUDIV2_OFFSET 10 +#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10) +#define CCM_PCDR0_NFCDIV2_OFFSET 6 +#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6) +#define CCM_PCDR0_MSHCDIV2_MASK 0x3f +/*The difinition for i.MX27 TO2*/ +#define CCM_PCDR0_NFCDIV_OFFSET 12 +#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) +#define CCM_PCDR0_VPUDIV_OFFSET 8 +#define CCM_PCDR0_VPUDIV_MASK (0xf << 8) +#define CCM_PCDR0_MSHCDIV_OFFSET 0 +#define CCM_PCDR0_MSHCDIV_MASK 0x1f + +#define CCM_PCDR1_PERDIV4_OFFSET 24 +#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) +#define CCM_PCDR1_PERDIV3_OFFSET 16 +#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) +#define CCM_PCDR1_PERDIV2_OFFSET 8 +#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) +#define CCM_PCDR1_PERDIV1_OFFSET 0 +#define CCM_PCDR1_PERDIV1_MASK 0x3f + +#define CCM_PCCR0_CSPI1_OFFSET 31 +#define CCM_PCCR0_CSPI1_MASK (1 << 31) +#define CCM_PCCR0_CSPI2_OFFSET 30 +#define CCM_PCCR0_CSPI2_MASK (1 << 30) +#define CCM_PCCR0_CSPI3_OFFSET 29 +#define CCM_PCCR0_CSPI3_MASK (1 << 29) +#define CCM_PCCR0_DMA_OFFSET 28 +#define CCM_PCCR0_DMA_MASK (1 << 28) +#define CCM_PCCR0_EMMA_OFFSET 27 +#define CCM_PCCR0_EMMA_MASK (1 << 27) +#define CCM_PCCR0_FEC_OFFSET 26 +#define CCM_PCCR0_FEC_MASK (1 << 26) +#define CCM_PCCR0_GPIO_OFFSET 25 +#define CCM_PCCR0_GPIO_MASK (1 << 25) +#define CCM_PCCR0_GPT1_OFFSET 24 +#define CCM_PCCR0_GPT1_MASK (1 << 24) +#define CCM_PCCR0_GPT2_OFFSET 23 +#define CCM_PCCR0_GPT2_MASK (1 << 23) +#define CCM_PCCR0_GPT3_OFFSET 22 +#define CCM_PCCR0_GPT3_MASK (1 << 22) +#define CCM_PCCR0_GPT4_OFFSET 21 +#define CCM_PCCR0_GPT4_MASK (1 << 21) +#define CCM_PCCR0_GPT5_OFFSET 20 +#define CCM_PCCR0_GPT5_MASK (1 << 20) +#define CCM_PCCR0_GPT6_OFFSET 19 +#define CCM_PCCR0_GPT6_MASK (1 << 19) +#define CCM_PCCR0_I2C1_OFFSET 18 +#define CCM_PCCR0_I2C1_MASK (1 << 18) +#define CCM_PCCR0_I2C2_OFFSET 17 +#define CCM_PCCR0_I2C2_MASK (1 << 17) +#define CCM_PCCR0_IIM_OFFSET 16 +#define CCM_PCCR0_IIM_MASK (1 << 16) +#define CCM_PCCR0_KPP_OFFSET 15 +#define CCM_PCCR0_KPP_MASK (1 << 15) +#define CCM_PCCR0_LCDC_OFFSET 14 +#define CCM_PCCR0_LCDC_MASK (1 << 14) +#define CCM_PCCR0_MSHC_OFFSET 13 +#define CCM_PCCR0_MSHC_MASK (1 << 13) +#define CCM_PCCR0_OWIRE_OFFSET 12 +#define CCM_PCCR0_OWIRE_MASK (1 << 12) +#define CCM_PCCR0_PWM_OFFSET 11 +#define CCM_PCCR0_PWM_MASK (1 << 11) +#define CCM_PCCR0_RTC_OFFSET 9 +#define CCM_PCCR0_RTC_MASK (1 << 9) +#define CCM_PCCR0_RTIC_OFFSET 8 +#define CCM_PCCR0_RTIC_MASK (1 << 8) +#define CCM_PCCR0_SAHARA_OFFSET 7 +#define CCM_PCCR0_SAHARA_MASK (1 << 7) +#define CCM_PCCR0_SCC_OFFSET 6 +#define CCM_PCCR0_SCC_MASK (1 << 6) +#define CCM_PCCR0_SDHC1_OFFSET 5 +#define CCM_PCCR0_SDHC1_MASK (1 << 5) +#define CCM_PCCR0_SDHC2_OFFSET 4 +#define CCM_PCCR0_SDHC2_MASK (1 << 4) +#define CCM_PCCR0_SDHC3_OFFSET 3 +#define CCM_PCCR0_SDHC3_MASK (1 << 3) +#define CCM_PCCR0_SLCDC_OFFSET 2 +#define CCM_PCCR0_SLCDC_MASK (1 << 2) +#define CCM_PCCR0_SSI1_IPG_OFFSET 1 +#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1) +#define CCM_PCCR0_SSI2_IPG_OFFSET 0 +#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0) + +#define CCM_PCCR1_UART1_OFFSET 31 +#define CCM_PCCR1_UART1_MASK (1 << 31) +#define CCM_PCCR1_UART2_OFFSET 30 +#define CCM_PCCR1_UART2_MASK (1 << 30) +#define CCM_PCCR1_UART3_OFFSET 29 +#define CCM_PCCR1_UART3_MASK (1 << 29) +#define CCM_PCCR1_UART4_OFFSET 28 +#define CCM_PCCR1_UART4_MASK (1 << 28) +#define CCM_PCCR1_UART5_OFFSET 27 +#define CCM_PCCR1_UART5_MASK (1 << 27) +#define CCM_PCCR1_UART6_OFFSET 26 +#define CCM_PCCR1_UART6_MASK (1 << 26) +#define CCM_PCCR1_USBOTG_OFFSET 25 +#define CCM_PCCR1_USBOTG_MASK (1 << 25) +#define CCM_PCCR1_WDT_OFFSET 24 +#define CCM_PCCR1_WDT_MASK (1 << 24) +#define CCM_PCCR1_HCLK_ATA_OFFSET 23 +#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23) +#define CCM_PCCR1_HCLK_BROM_OFFSET 22 +#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22) +#define CCM_PCCR1_HCLK_CSI_OFFSET 21 +#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21) +#define CCM_PCCR1_HCLK_DMA_OFFSET 20 +#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20) +#define CCM_PCCR1_HCLK_EMI_OFFSET 19 +#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19) +#define CCM_PCCR1_HCLK_EMMA_OFFSET 18 +#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18) +#define CCM_PCCR1_HCLK_FEC_OFFSET 17 +#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17) +#define CCM_PCCR1_HCLK_VPU_OFFSET 16 +#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16) +#define CCM_PCCR1_HCLK_LCDC_OFFSET 15 +#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15) +#define CCM_PCCR1_HCLK_RTIC_OFFSET 14 +#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14) +#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13 +#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13) +#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12 +#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12) +#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11 +#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11) +#define CCM_PCCR1_PERCLK1_OFFSET 10 +#define CCM_PCCR1_PERCLK1_MASK (1 << 10) +#define CCM_PCCR1_PERCLK2_OFFSET 9 +#define CCM_PCCR1_PERCLK2_MASK (1 << 9) +#define CCM_PCCR1_PERCLK3_OFFSET 8 +#define CCM_PCCR1_PERCLK3_MASK (1 << 8) +#define CCM_PCCR1_PERCLK4_OFFSET 7 +#define CCM_PCCR1_PERCLK4_MASK (1 << 7) +#define CCM_PCCR1_VPU_BAUD_OFFSET 6 +#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6) +#define CCM_PCCR1_SSI1_BAUD_OFFSET 5 +#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5) +#define CCM_PCCR1_SSI2_BAUD_OFFSET 4 +#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4) +#define CCM_PCCR1_NFC_BAUD_OFFSET 3 +#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3) +#define CCM_PCCR1_MSHC_BAUD_OFFSET 2 +#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2) + +#define CCM_CCSR_32KSR (1 << 15) +#define CCM_CCSR_CLKMODE1 (1 << 9) +#define CCM_CCSR_CLKMODE0 (1 << 8) +#define CCM_CCSR_CLKOSEL_OFFSET 0 +#define CCM_CCSR_CLKOSEL_MASK 0x1f + +#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ +#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ + +#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */ diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h index 4ed2d80..f841127 100644 --- a/include/asm-arm/arch-mxc/hardware.h +++ b/include/asm-arm/arch-mxc/hardware.h @@ -26,6 +26,9 @@ # include #endif +#ifdef CONFIG_ARCH_MX2 +#endif + #include #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ diff --git a/include/asm-arm/arch-mxc/iim.h b/include/asm-arm/arch-mxc/iim.h new file mode 100644 index 0000000..315bffa --- /dev/null +++ b/include/asm-arm/arch-mxc/iim.h @@ -0,0 +1,77 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_IIM_H__ +#define __ASM_ARCH_MXC_IIM_H__ + +/* Register offsets */ +#define MXC_IIMSTAT 0x0000 +#define MXC_IIMSTATM 0x0004 +#define MXC_IIMERR 0x0008 +#define MXC_IIMEMASK 0x000C +#define MXC_IIMFCTL 0x0010 +#define MXC_IIMUA 0x0014 +#define MXC_IIMLA 0x0018 +#define MXC_IIMSDAT 0x001C +#define MXC_IIMPREV 0x0020 +#define MXC_IIMSREV 0x0024 +#define MXC_IIMPRG_P 0x0028 +#define MXC_IIMSCS0 0x002C +#define MXC_IIMSCS1 0x0030 +#define MXC_IIMSCS2 0x0034 +#define MXC_IIMSCS3 0x0038 +#define MXC_IIMFBAC0 0x0800 +#define MXC_IIMJAC 0x0804 +#define MXC_IIMHWV1 0x0808 +#define MXC_IIMHWV2 0x080C +#define MXC_IIMHAB0 0x0810 +#define MXC_IIMHAB1 0x0814 +/* Definitions for i.MX27 TO2 */ +#define MXC_IIMMAC 0x0814 +#define MXC_IIMPREV_FUSE 0x0818 +#define MXC_IIMSREV_FUSE 0x081C +#define MXC_IIMSJC_CHALL_0 0x0820 +#define MXC_IIMSJC_CHALL_7 0x083C +#define MXC_IIMFB0UC17 0x0840 +#define MXC_IIMFB0UC255 0x0BFC +#define MXC_IIMFBAC1 0x0C00 +/* Definitions for i.MX27 TO2 */ +#define MXC_IIMSUID 0x0C04 +#define MXC_IIMKEY0 0x0C04 +#define MXC_IIMKEY20 0x0C54 +#define MXC_IIMSJC_RESP_0 0x0C58 +#define MXC_IIMSJC_RESP_7 0x0C74 +#define MXC_IIMFB1UC30 0x0C78 +#define MXC_IIMFB1UC255 0x0FFC + +/* Bit definitions */ + +#define MXC_IIMHWV1_WLOCK (0x1 << 7) +#define MXC_IIMHWV1_MCU_ENDIAN (0x1 << 6) +#define MXC_IIMHWV1_DSP_ENDIAN (0x1 << 5) +#define MXC_IIMHWV1_BOOT_INT (0x1 << 4) +#define MXC_IIMHWV1_SCC_DISABLE (0x1 << 3) +#define MXC_IIMHWV1_HANTRO_DISABLE (0x1 << 2) +#define MXC_IIMHWV1_MEMSTICK_DIS (0x1 << 1) + +#define MXC_IIMHWV2_WLOCK (0x1 << 7) +#define MXC_IIMHWV2_BP_SDMA (0x1 << 6) +#define MXC_IIMHWV2_SCM_DCM (0x1 << 5) + +#endif /* __ASM_ARCH_MXC_IIM_H__ */ -- cgit v0.10.2 From fc80a5e3d0480d416e4f53b0680aaf525b5076d8 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:57 +0200 Subject: i.MX2 family: Add basic device support This patch adds a few on-chip devices for i.MX21/i.MX27 procesors. Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index 937192d..db4d9c6 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -4,4 +4,4 @@ # Object file lists. -obj-y := system.o generic.o +obj-y := system.o generic.o devices.o diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c new file mode 100644 index 0000000..a1f44c3 --- /dev/null +++ b/arch/arm/mach-mx2/devices.c @@ -0,0 +1,231 @@ +/* + * Author: MontaVista Software, Inc. + * + * + * Based on the OMAP devices.c + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include + +#include + +/* + * Resource definition for the MXC IrDA + */ +static struct resource mxc_irda_resources[] = { + [0] = { + .start = UART3_BASE_ADDR, + .end = UART3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_UART3, + .end = MXC_INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +/* Platform Data for MXC IrDA */ +struct platform_device mxc_irda_device = { + .name = "mxc_irda", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_irda_resources), + .resource = mxc_irda_resources, +}; + +/* + * General Purpose Timer + * - i.MX1: 2 timer (slighly different register handling) + * - i.MX21: 3 timer + * - i.MX27: 6 timer + */ + +/* We use gpt0 as system timer, so do not add a device for this one */ + +static struct resource timer1_resources[] = { + [0] = { + .start = GPT2_BASE_ADDR, + .end = GPT2_BASE_ADDR + 0x17, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = MXC_INT_GPT2, + .end = MXC_INT_GPT2, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device mxc_gpt1 = { + .name = "imx_gpt", + .id = 1, + .num_resources = ARRAY_SIZE(timer1_resources), + .resource = timer1_resources +}; + +static struct resource timer2_resources[] = { + [0] = { + .start = GPT3_BASE_ADDR, + .end = GPT3_BASE_ADDR + 0x17, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = MXC_INT_GPT3, + .end = MXC_INT_GPT3, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device mxc_gpt2 = { + .name = "imx_gpt", + .id = 2, + .num_resources = ARRAY_SIZE(timer2_resources), + .resource = timer2_resources +}; + +#ifdef CONFIG_MACH_MX27 +static struct resource timer3_resources[] = { + [0] = { + .start = GPT4_BASE_ADDR, + .end = GPT4_BASE_ADDR + 0x17, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = MXC_INT_GPT4, + .end = MXC_INT_GPT4, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device mxc_gpt3 = { + .name = "imx_gpt", + .id = 3, + .num_resources = ARRAY_SIZE(timer3_resources), + .resource = timer3_resources +}; + +static struct resource timer4_resources[] = { + [0] = { + .start = GPT5_BASE_ADDR, + .end = GPT5_BASE_ADDR + 0x17, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = MXC_INT_GPT5, + .end = MXC_INT_GPT5, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device mxc_gpt4 = { + .name = "imx_gpt", + .id = 4, + .num_resources = ARRAY_SIZE(timer4_resources), + .resource = timer4_resources +}; + +static struct resource timer5_resources[] = { + [0] = { + .start = GPT6_BASE_ADDR, + .end = GPT6_BASE_ADDR + 0x17, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = MXC_INT_GPT6, + .end = MXC_INT_GPT6, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device mxc_gpt5 = { + .name = "imx_gpt", + .id = 5, + .num_resources = ARRAY_SIZE(timer5_resources), + .resource = timer5_resources +}; +#endif + +/* + * Watchdog: + * - i.MX1 + * - i.MX21 + * - i.MX27 + */ +static struct resource mxc_wdt_resources[] = { + { + .start = WDOG_BASE_ADDR, + .end = WDOG_BASE_ADDR + 0x30, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device mxc_wdt = { + .name = "mxc_wdt", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_wdt_resources), + .resource = mxc_wdt_resources, +}; + +/* GPIO port description */ +static struct mxc_gpio_port imx_gpio_ports[] = { + [0] = { + .chip.label = "gpio-0", + .irq = MXC_INT_GPIO, + .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0), + .virtual_irq_start = MXC_MAX_INT_LINES, + }, + [1] = { + .chip.label = "gpio-1", + .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1), + .virtual_irq_start = MXC_MAX_INT_LINES + 32, + }, + [2] = { + .chip.label = "gpio-2", + .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2), + .virtual_irq_start = MXC_MAX_INT_LINES + 64, + }, + [3] = { + .chip.label = "gpio-3", + .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3), + .virtual_irq_start = MXC_MAX_INT_LINES + 96, + }, + [4] = { + .chip.label = "gpio-4", + .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4), + .virtual_irq_start = MXC_MAX_INT_LINES + 128, + }, + [5] = { + .chip.label = "gpio-5", + .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5), + .virtual_irq_start = MXC_MAX_INT_LINES + 160, + } +}; + +int __init mxc_register_gpios(void) +{ + return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); +} -- cgit v0.10.2 From 604cbadce2292d979749e2f5c6c3f75ee10f4c9e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:58 +0200 Subject: MX2 add support for mx2 in i.MX serial driver add support for mx2 in i.MX serial driver Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index db4d9c6..f8f8ecb 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -4,4 +4,4 @@ # Object file lists. -obj-y := system.o generic.o devices.o +obj-y := system.o generic.o devices.o serial.o diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c new file mode 100644 index 0000000..570c02b --- /dev/null +++ b/arch/arm/mach-mx2/serial.c @@ -0,0 +1,177 @@ +/* + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +static struct resource uart0[] = { + { + .start = UART1_BASE_ADDR, + .end = UART1_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART1, + .end = MXC_INT_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device0 = { + .name = "imx-uart", + .id = 0, + .resource = uart0, + .num_resources = ARRAY_SIZE(uart0), +}; + +static struct resource uart1[] = { + { + .start = UART2_BASE_ADDR, + .end = UART2_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART2, + .end = MXC_INT_UART2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device1 = { + .name = "imx-uart", + .id = 1, + .resource = uart1, + .num_resources = ARRAY_SIZE(uart1), +}; + +static struct resource uart2[] = { + { + .start = UART3_BASE_ADDR, + .end = UART3_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART3, + .end = MXC_INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "imx-uart", + .id = 2, + .resource = uart2, + .num_resources = ARRAY_SIZE(uart2), +}; + +static struct resource uart3[] = { + { + .start = UART4_BASE_ADDR, + .end = UART4_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART4, + .end = MXC_INT_UART4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device3 = { + .name = "imx-uart", + .id = 3, + .resource = uart3, + .num_resources = ARRAY_SIZE(uart3), +}; + +static struct resource uart4[] = { + { + .start = UART5_BASE_ADDR, + .end = UART5_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART5, + .end = MXC_INT_UART5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device4 = { + .name = "imx-uart", + .id = 4, + .resource = uart4, + .num_resources = ARRAY_SIZE(uart4), +}; + +static struct resource uart5[] = { + { + .start = UART6_BASE_ADDR, + .end = UART6_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART6, + .end = MXC_INT_UART6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device5 = { + .name = "imx-uart", + .id = 5, + .resource = uart5, + .num_resources = ARRAY_SIZE(uart5), +}; + +/* + * Register only those UARTs that physically exists + */ +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata) +{ + switch (uart_no) { + case 0: + mxc_uart_device0.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device0); + break; + case 1: + mxc_uart_device1.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device1); + break; +#ifndef CONFIG_MXC_IRDA + case 2: + mxc_uart_device2.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device2); + break; +#endif + case 3: + mxc_uart_device3.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device3); + break; + case 4: + mxc_uart_device4.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device4); + break; + case 5: + mxc_uart_device5.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device5); + break; + default: + return -ENODEV; + } + + return 0; +} diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 549440b..64acb39 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -62,7 +62,7 @@ #define UBIR 0xa4 /* BRM Incremental Register */ #define UBMR 0xa8 /* BRM Modulator Register */ #define UBRC 0xac /* Baud Rate Count Register */ -#ifdef CONFIG_ARCH_MX3 +#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2 #define ONEMS 0xb0 /* One Millisecond register */ #define UTS 0xb4 /* UART Test Register */ #endif @@ -99,7 +99,7 @@ #ifdef CONFIG_ARCH_IMX #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ #endif -#ifdef CONFIG_ARCH_MX3 +#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2 #define UCR1_UARTCLKEN (0) /* not present on mx2/mx3 */ #endif #define UCR1_DOZE (1<<1) /* Doze */ @@ -182,7 +182,7 @@ #define MAX_INTERNAL_IRQ IMX_IRQS #endif -#ifdef CONFIG_ARCH_MX3 +#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2 #define SERIAL_IMX_MAJOR 207 #define MINOR_START 16 #define DEV_NAME "ttymxc" -- cgit v0.10.2 From f31405cc4cc568baad28273c7f45b0563b57a17d Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:59 +0200 Subject: i.MX27 CPU: Add basic i.MX27 CPU support Add basic i.MX27 CPU support Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 23def05..6e7d724 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -1,5 +1,11 @@ comment "MX2 family CPU support" depends on ARCH_MX2 +config MACH_MX27 + bool "i.MX27 support" + depends on ARCH_MX2 + help + This enables support for Freescale's MX2 based i.MX27 processor. + comment "MX2 Platforms" depends on ARCH_MX2 diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index f8f8ecb..c9eac3b 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -5,3 +5,5 @@ # Object file lists. obj-y := system.o generic.o devices.o serial.o + +obj-$(CONFIG_MACH_MX27) += cpu_imx27.o diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-mx2/cpu_imx27.c new file mode 100644 index 0000000..d6b5c2e --- /dev/null +++ b/arch/arm/mach-mx2/cpu_imx27.c @@ -0,0 +1,63 @@ +/* + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* + * i.MX27 specific CPU detection code + */ + +#include +#include + +#include + +#include "crm_regs.h" + +static int cpu_silicon_rev = -1; +static int cpu_partnumber; + +static void query_silicon_parameter(void) +{ + u32 val; + /* + * now we have access to the IO registers. As we need + * the silicon revision very early we read it here to + * avoid any further hooks + */ + val = __raw_readl(IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_CHIP_ID); + + cpu_silicon_rev = (int)(val >> 28); + cpu_partnumber = (int)((val >> 12) & 0xFFFF); +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx27 + */ +int mx27_revision(void) +{ + if (cpu_silicon_rev == -1) + query_silicon_parameter(); + + if (cpu_partnumber != 0x8821) + return -EINVAL; + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx27_revision); diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h index f841127..37cddba 100644 --- a/include/asm-arm/arch-mxc/hardware.h +++ b/include/asm-arm/arch-mxc/hardware.h @@ -27,6 +27,9 @@ #endif #ifdef CONFIG_ARCH_MX2 +# ifdef CONFIG_MACH_MX27 +# include +# endif #endif #include diff --git a/include/asm-arm/arch-mxc/mx27.h b/include/asm-arm/arch-mxc/mx27.h new file mode 100644 index 0000000..212ecc2 --- /dev/null +++ b/include/asm-arm/arch-mxc/mx27.h @@ -0,0 +1,302 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_MX27_H__ +#define __ASM_ARCH_MXC_MX27_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + +/* IRAM */ +#define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */ + +/* Register offests */ +#define AIPI_BASE_ADDR 0x10000000 +#define AIPI_BASE_ADDR_VIRT 0xF4000000 +#define AIPI_SIZE SZ_1M + +#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000) +#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000) +#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000) +#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000) +#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000) +#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000) +#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000) +#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000) +#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000) +#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000) +#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000) +#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000) +#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000) +#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000) +#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000) +#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000) +#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000) +#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000) +#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000) +#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000) +#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000) + +#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000) +#define MSHC_BASE_ADDR (AIPI_BASE_ADDR + 0x18000) +#define GPT5_BASE_ADDR (AIPI_BASE_ADDR + 0x19000) +#define GPT4_BASE_ADDR (AIPI_BASE_ADDR + 0x1A000) +#define UART5_BASE_ADDR (AIPI_BASE_ADDR + 0x1B000) +#define UART6_BASE_ADDR (AIPI_BASE_ADDR + 0x1C000) +#define I2C2_BASE_ADDR (AIPI_BASE_ADDR + 0x1D000) +#define SDHC3_BASE_ADDR (AIPI_BASE_ADDR + 0x1E000) +#define GPT6_BASE_ADDR (AIPI_BASE_ADDR + 0x1F000) + +#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000) +#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000) +#define VPU_BASE_ADDR (AIPI_BASE_ADDR + 0x23000) +#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000) +/* for mx27*/ +#define OTG_BASE_ADDR USBOTG_BASE_ADDR +#define SAHARA_BASE_ADDR (AIPI_BASE_ADDR + 0x25000) +#define EMMA_BASE_ADDR (AIPI_BASE_ADDR + 0x26400) +#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000) +#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800) +#define IIM_BASE_ADDR (AIPI_BASE_ADDR + 0x28000) + +#define RTIC_BASE_ADDR (AIPI_BASE_ADDR + 0x2A000) +#define FEC_BASE_ADDR (AIPI_BASE_ADDR + 0x2B000) +#define SCC_BASE_ADDR (AIPI_BASE_ADDR + 0x2C000) +#define ETB_BASE_ADDR (AIPI_BASE_ADDR + 0x3B000) +#define ETB_RAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3C000) + +#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000) +#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000) + +/* ROMP and AVIC */ +#define ROMP_BASE_ADDR 0x10041000 + +#define AVIC_BASE_ADDR 0x10040000 + +#define SAHB1_BASE_ADDR 0x80000000 +#define SAHB1_BASE_ADDR_VIRT 0xF4100000 +#define SAHB1_SIZE SZ_1M + +#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000) +#define ATA_BASE_ADDR (SAHB1_BASE_ADDR + 0x1000) + +/* NAND, SDRAM, WEIM, M3IF, EMI controllers */ +#define X_MEMC_BASE_ADDR 0xD8000000 +#define X_MEMC_BASE_ADDR_VIRT 0xF4200000 +#define X_MEMC_SIZE SZ_1M + +#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR) +#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) +#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) +#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) +#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) + +/* Memory regions and CS */ +#define SDRAM_BASE_ADDR 0xA0000000 +#define CSD1_BASE_ADDR 0xB0000000 + +#define CS0_BASE_ADDR 0xC0000000 +#define CS1_BASE_ADDR 0xC8000000 +#define CS2_BASE_ADDR 0xD0000000 +#define CS3_BASE_ADDR 0xD2000000 +#define CS4_BASE_ADDR 0xD4000000 +#define CS5_BASE_ADDR 0xD6000000 +#define PCMCIA_MEM_BASE_ADDR 0xDC000000 + +/* + * This macro defines the physical to virtual address mapping for all the + * peripheral modules. It is used by passing in the physical address as x + * and returning the virtual address. If the physical address is not mapped, + * it returns 0xDEADBEEF + */ +#define IO_ADDRESS(x) \ + (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \ + AIPI_IO_ADDRESS(x) : \ + ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ + SAHB1_IO_ADDRESS(x) : \ + ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \ + X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF) + +/* define the address mapping macros: in physical address order */ +#define AIPI_IO_ADDRESS(x) \ + (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT) + +#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x) + +#define SAHB1_IO_ADDRESS(x) \ + (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT) + +#define CS4_IO_ADDRESS(x) \ + (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) + +#define X_MEMC_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +#define PCMCIA_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +/* fixed interrput numbers */ +#define MXC_INT_CCM 63 +#define MXC_INT_IIM 62 +#define MXC_INT_LCDC 61 +#define MXC_INT_SLCDC 60 +#define MXC_INT_SAHARA 59 +#define MXC_INT_SCC_SCM 58 +#define MXC_INT_SCC_SMN 57 +#define MXC_INT_USB3 56 +#define MXC_INT_USB2 55 +#define MXC_INT_USB1 54 +#define MXC_INT_VPU 53 +#define MXC_INT_EMMAPP 52 +#define MXC_INT_EMMAPRP 51 +#define MXC_INT_FEC 50 +#define MXC_INT_UART5 49 +#define MXC_INT_UART6 48 +#define MXC_INT_DMACH15 47 +#define MXC_INT_DMACH14 46 +#define MXC_INT_DMACH13 45 +#define MXC_INT_DMACH12 44 +#define MXC_INT_DMACH11 43 +#define MXC_INT_DMACH10 42 +#define MXC_INT_DMACH9 41 +#define MXC_INT_DMACH8 40 +#define MXC_INT_DMACH7 39 +#define MXC_INT_DMACH6 38 +#define MXC_INT_DMACH5 37 +#define MXC_INT_DMACH4 36 +#define MXC_INT_DMACH3 35 +#define MXC_INT_DMACH2 34 +#define MXC_INT_DMACH1 33 +#define MXC_INT_DMACH0 32 +#define MXC_INT_CSI 31 +#define MXC_INT_ATA 30 +#define MXC_INT_NANDFC 29 +#define MXC_INT_PCMCIA 28 +#define MXC_INT_WDOG 27 +#define MXC_INT_GPT1 26 +#define MXC_INT_GPT2 25 +#define MXC_INT_GPT3 24 +#define MXC_INT_GPT INT_GPT1 +#define MXC_INT_PWM 23 +#define MXC_INT_RTC 22 +#define MXC_INT_KPP 21 +#define MXC_INT_UART1 20 +#define MXC_INT_UART2 19 +#define MXC_INT_UART3 18 +#define MXC_INT_UART4 17 +#define MXC_INT_CSPI1 16 +#define MXC_INT_CSPI2 15 +#define MXC_INT_SSI1 14 +#define MXC_INT_SSI2 13 +#define MXC_INT_I2C 12 +#define MXC_INT_SDHC1 11 +#define MXC_INT_SDHC2 10 +#define MXC_INT_SDHC3 9 +#define MXC_INT_GPIO 8 +#define MXC_INT_SDHC 7 +#define MXC_INT_CSPI3 6 +#define MXC_INT_RTIC 5 +#define MXC_INT_GPT4 4 +#define MXC_INT_GPT5 3 +#define MXC_INT_GPT6 2 +#define MXC_INT_I2C2 1 + +/* fixed DMA request numbers */ +#define DMA_REQ_NFC 37 +#define DMA_REQ_SDHC3 36 +#define DMA_REQ_UART6_RX 35 +#define DMA_REQ_UART6_TX 34 +#define DMA_REQ_UART5_RX 33 +#define DMA_REQ_UART5_TX 32 +#define DMA_REQ_CSI_RX 31 +#define DMA_REQ_CSI_STAT 30 +#define DMA_REQ_ATA_RCV 29 +#define DMA_REQ_ATA_TX 28 +#define DMA_REQ_UART1_TX 27 +#define DMA_REQ_UART1_RX 26 +#define DMA_REQ_UART2_TX 25 +#define DMA_REQ_UART2_RX 24 +#define DMA_REQ_UART3_TX 23 +#define DMA_REQ_UART3_RX 22 +#define DMA_REQ_UART4_TX 21 +#define DMA_REQ_UART4_RX 20 +#define DMA_REQ_CSPI1_TX 19 +#define DMA_REQ_CSPI1_RX 18 +#define DMA_REQ_CSPI2_TX 17 +#define DMA_REQ_CSPI2_RX 16 +#define DMA_REQ_SSI1_TX1 15 +#define DMA_REQ_SSI1_RX1 14 +#define DMA_REQ_SSI1_TX0 13 +#define DMA_REQ_SSI1_RX0 12 +#define DMA_REQ_SSI2_TX1 11 +#define DMA_REQ_SSI2_RX1 10 +#define DMA_REQ_SSI2_TX0 9 +#define DMA_REQ_SSI2_RX0 8 +#define DMA_REQ_SDHC1 7 +#define DMA_REQ_SDHC2 6 +#define DMA_REQ_MSHC 4 +#define DMA_REQ_EXT 3 +#define DMA_REQ_CSPI3_TX 2 +#define DMA_REQ_CSPI3_RX 1 + +/* silicon revisions specific to i.MX27 */ +#define CHIP_REV_1_0 0x00 +#define CHIP_REV_2_0 0x01 + +#ifndef __ASSEMBLY__ +extern int mx27_revision(void); +#endif + +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x1C +#define GPIO_GDIR 0x00 +#define GPIO_PSR 0x24 +#define GPIO_ICR1 0x28 +#define GPIO_ICR2 0x2C +#define GPIO_IMR 0x30 +#define GPIO_ISR 0x34 +#define GPIO_INT_LOW_LEV 0x3 +#define GPIO_INT_HIGH_LEV 0x2 +#define GPIO_INT_RISE_EDGE 0x0 +#define GPIO_INT_FALL_EDGE 0x1 +#define GPIO_INT_NONE 0x4 + +/* Mandatory defines used globally */ + +/* this is an i.MX27 CPU */ +#define cpu_is_mx27() (1) + +/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */ +#define ARCH_NR_GPIOS (192 + 16) + +/* OS clock tick rate */ +#define CLOCK_TICK_RATE 13300000 + +/* Start of RAM */ +#define PHYS_OFFSET SDRAM_BASE_ADDR + +/* max interrupt lines count */ +#define NR_IRQS 256 + +/* count of internal interrupt sources */ +#define MXC_MAX_INT_LINES 64 + +#endif /* __ASM_ARCH_MXC_MX27_H__ */ diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h index 3e1c4de..332eda4 100644 --- a/include/asm-arm/arch-mxc/mxc.h +++ b/include/asm-arm/arch-mxc/mxc.h @@ -29,4 +29,8 @@ # define cpu_is_mx31() (0) #endif +#ifndef CONFIG_MACH_MX27 +# define cpu_is_mx27() (0) +#endif + #endif /* __ASM_ARCH_MXC_H__ */ -- cgit v0.10.2 From c46f5856517c2d4f438df87dac81f2295931ee93 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:59 +0200 Subject: i.MX2 family: Add clock handling for i.MX27 CPU Internal clock path handling for the i.MX27 CPU. Changed against the original Freescale code (and against clocklib for example): - clock rate is always calculated whenever one ask for the current rate. (means no "rate" member in the clock structure). So switching the PLL base frequency will propagate immediately to all other clocks that are depending on this frequency. TODO: - Check if the i.MX21 CPU can share the same code. Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index c9eac3b..74fb9b3 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -7,3 +7,4 @@ obj-y := system.o generic.o devices.o serial.o obj-$(CONFIG_MACH_MX27) += cpu_imx27.o +obj-$(CONFIG_MACH_MX27) += clock_imx27.o diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c new file mode 100644 index 0000000..0a29ef2 --- /dev/null +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -0,0 +1,1626 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "crm_regs.h" + +static struct clk ckil_clk; +static struct clk mpll_clk; +static struct clk mpll_main_clk[]; +static struct clk spll_clk; + +static int _clk_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(clk->enable_reg); + reg |= 1 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + + return 0; +} + +static void _clk_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static int _clk_spll_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_CSCR); + reg |= CCM_CSCR_SPEN; + __raw_writel(reg, CCM_CSCR); + + while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) + ; + + return 0; +} + +static void _clk_spll_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_CSCR); + reg &= ~CCM_CSCR_SPEN; + __raw_writel(reg, CCM_CSCR); +} + +static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR0); + reg |= mask0; + __raw_writel(reg, CCM_PCCR0); + + reg = __raw_readl(CCM_PCCR1); + reg |= mask1; + __raw_writel(reg, CCM_PCCR1); + +} + +static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR0); + reg &= ~mask0; + __raw_writel(reg, CCM_PCCR0); + + reg = __raw_readl(CCM_PCCR1); + reg &= ~mask1; + __raw_writel(reg, CCM_PCCR1); +} + +static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg |= mask1; + __raw_writel(reg, CCM_PCCR1); + + reg = __raw_readl(CCM_PCCR0); + reg |= mask0; + __raw_writel(reg, CCM_PCCR0); +} + +static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg &= ~mask1; + __raw_writel(reg, CCM_PCCR1); + + reg = __raw_readl(CCM_PCCR0); + reg &= ~mask0; + __raw_writel(reg, CCM_PCCR0); +} + +static int _clk_dma_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK); + + return 0; +} + +static void _clk_dma_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK); +} + +static int _clk_rtic_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK); + + return 0; +} + +static void _clk_rtic_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK); +} + +static int _clk_emma_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK); + + return 0; +} + +static void _clk_emma_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK); +} + +static int _clk_slcdc_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK); + + return 0; +} + +static void _clk_slcdc_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK); +} + +static int _clk_fec_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK); + + return 0; +} + +static void _clk_fec_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK); +} + +static int _clk_vpu_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK; + __raw_writel(reg, CCM_PCCR1); + + return 0; +} + +static void _clk_vpu_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK); + __raw_writel(reg, CCM_PCCR1); +} + +static int _clk_sahara2_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK); + + return 0; +} + +static void _clk_sahara2_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK); +} + +static int _clk_mstick1_enable(struct clk *clk) +{ + _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); + + return 0; +} + +static void _clk_mstick1_disable(struct clk *clk) +{ + _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); +} + +#define CSCR() (__raw_readl(CCM_CSCR)) +#define PCDR0() (__raw_readl(CCM_PCDR0)) +#define PCDR1() (__raw_readl(CCM_PCDR1)) + +static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent) +{ + int cscr = CSCR(); + + if (clk->parent == parent) + return 0; + + if (mx27_revision() >= CHIP_REV_2_0) { + if (parent == &mpll_main_clk[0]) { + cscr |= CCM_CSCR_ARM_SRC; + } else { + if (parent == &mpll_main_clk[1]) + cscr &= ~CCM_CSCR_ARM_SRC; + else + return -EINVAL; + } + __raw_writel(cscr, CCM_CSCR); + } else + return -ENODEV; + + clk->parent = parent; + return 0; +} + +static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) +{ + int div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = parent_rate / rate; + if (parent_rate % rate) + div++; + + if (div > 4) + div = 4; + + return parent_rate / div; +} + +static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int div; + uint32_t reg; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = parent_rate / rate; + + if (div > 4 || div < 1 || ((parent_rate / div) != rate)) + return -EINVAL; + + div--; + + reg = __raw_readl(CCM_CSCR); + if (mx27_revision() >= CHIP_REV_2_0) { + reg &= ~CCM_CSCR_ARM_MASK; + reg |= div << CCM_CSCR_ARM_OFFSET; + reg &= ~0x06; + __raw_writel(reg | 0x80000000, CCM_CSCR); + } else { + printk(KERN_ERR "Cant set CPU frequency!\n"); + } + + return 0; +} + +static unsigned long _clk_perclkx_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = parent_rate / rate; + if (parent_rate % rate) + div++; + + if (div > 64) + div = 64; + + return parent_rate / div; +} + +static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (clk->id < 0 || clk->id > 3) + return -EINVAL; + + div = parent_rate / rate; + if (div > 64 || div < 1 || ((parent_rate / div) != rate)) + return -EINVAL; + div--; + + reg = + __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK << + (clk->id << 3)); + reg |= div << (clk->id << 3); + __raw_writel(reg, CCM_PCDR1); + + return 0; +} + +static unsigned long _clk_usb_recalc(struct clk *clk) +{ + unsigned long usb_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; + + return parent_rate / (usb_pdf + 1U); +} + +static unsigned long _clk_ssi1_recalc(struct clk *clk) +{ + unsigned long ssi1_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >> + CCM_PCDR0_SSI1BAUDDIV_OFFSET; + + if (mx27_revision() >= CHIP_REV_2_0) + ssi1_pdf += 4; + else + ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf; + + return 2UL * parent_rate / ssi1_pdf; +} + +static unsigned long _clk_ssi2_recalc(struct clk *clk) +{ + unsigned long ssi2_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >> + CCM_PCDR0_SSI2BAUDDIV_OFFSET; + + if (mx27_revision() >= CHIP_REV_2_0) + ssi2_pdf += 4; + else + ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf; + + return 2UL * parent_rate / ssi2_pdf; +} + +static unsigned long _clk_nfc_recalc(struct clk *clk) +{ + unsigned long nfc_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (mx27_revision() >= CHIP_REV_2_0) { + nfc_pdf = + (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >> + CCM_PCDR0_NFCDIV2_OFFSET; + } else { + nfc_pdf = + (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >> + CCM_PCDR0_NFCDIV_OFFSET; + } + + return parent_rate / (nfc_pdf + 1); +} + +static unsigned long _clk_vpu_recalc(struct clk *clk) +{ + unsigned long vpu_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (mx27_revision() >= CHIP_REV_2_0) { + vpu_pdf = + (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >> + CCM_PCDR0_VPUDIV2_OFFSET; + vpu_pdf += 4; + } else { + vpu_pdf = + (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >> + CCM_PCDR0_VPUDIV_OFFSET; + vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; + } + return 2UL * parent_rate / vpu_pdf; +} + +static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) +{ + return clk->parent->round_rate(clk->parent, rate); +} + +static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) +{ + return clk->parent->set_rate(clk->parent, rate); +} + +/* in Hz */ +static unsigned long external_high_reference = 26000000; + +static unsigned long get_high_reference_clock_rate(struct clk *clk) +{ + return external_high_reference; +} + +/* + * the high frequency external clock reference + * Default case is 26MHz. Could be changed at runtime + * with a call to change_external_high_reference() + */ +static struct clk ckih_clk = { + .name = "ckih", + .get_rate = get_high_reference_clock_rate, +}; + +/* in Hz */ +static unsigned long external_low_reference = 32768; + +static unsigned long get_low_reference_clock_rate(struct clk *clk) +{ + return external_low_reference; +} + +/* + * the low frequency external clock reference + * Default case is 32.768kHz Could be changed at runtime + * with a call to change_external_low_reference() + */ +static struct clk ckil_clk = { + .name = "ckil", + .get_rate = get_low_reference_clock_rate, +}; + +static unsigned long get_mpll_clk(struct clk *clk) +{ + uint32_t reg; + unsigned long ref_clk; + unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; + unsigned long long temp; + + ref_clk = clk_get_rate(clk->parent); + + reg = __raw_readl(CCM_MPCTL0); + pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET; + mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET; + mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET; + mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET; + + mfi = (mfi <= 5) ? 5 : mfi; + temp = 2LL * ref_clk * mfn; + do_div(temp, mfd + 1); + temp = 2LL * ref_clk * mfi + temp; + do_div(temp, pdf + 1); + + return (unsigned long)temp; +} + +static struct clk mpll_clk = { + .name = "mpll", + .parent = &ckih_clk, + .get_rate = get_mpll_clk, +}; + +static unsigned long _clk_mpll_main_get_rate(struct clk *clk) +{ + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + /* i.MX27 TO2: + * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2 + * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3 + */ + + if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1) + return 2UL * parent_rate / 3UL; + + return parent_rate; +} + +static struct clk mpll_main_clk[] = { + { + /* For i.MX27 TO2, it is the MPLL path 1 of ARM core + * It provide the clock source whose rate is same as MPLL + */ + .name = "mpll_main", + .id = 0, + .parent = &mpll_clk, + .get_rate = _clk_mpll_main_get_rate + }, { + /* For i.MX27 TO2, it is the MPLL path 2 of ARM core + * It provide the clock source whose rate is same MPLL * 2/3 + */ + .name = "mpll_main", + .id = 1, + .parent = &mpll_clk, + .get_rate = _clk_mpll_main_get_rate + } +}; + +static unsigned long get_spll_clk(struct clk *clk) +{ + uint32_t reg; + unsigned long ref_clk; + unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; + unsigned long long temp; + + ref_clk = clk_get_rate(clk->parent); + + reg = __raw_readl(CCM_SPCTL0); + /*TODO: This is TO2 Bug */ + if (mx27_revision() >= CHIP_REV_2_0) + __raw_writel(reg, CCM_SPCTL0); + + pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; + mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET; + mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET; + mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET; + + mfi = (mfi <= 5) ? 5 : mfi; + temp = 2LL * ref_clk * mfn; + do_div(temp, mfd + 1); + temp = 2LL * ref_clk * mfi + temp; + do_div(temp, pdf + 1); + + return (unsigned long)temp; +} + +static struct clk spll_clk = { + .name = "spll", + .parent = &ckih_clk, + .get_rate = get_spll_clk, + .enable = _clk_spll_enable, + .disable = _clk_spll_disable, +}; + +static unsigned long get_cpu_clk(struct clk *clk) +{ + u32 div; + unsigned long rate; + + if (mx27_revision() >= CHIP_REV_2_0) + div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET; + else + div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; + + rate = clk_get_rate(clk->parent); + return rate / (div + 1); +} + +static struct clk cpu_clk = { + .name = "cpu_clk", + .parent = &mpll_main_clk[1], + .set_parent = _clk_cpu_set_parent, + .round_rate = _clk_cpu_round_rate, + .get_rate = get_cpu_clk, + .set_rate = _clk_cpu_set_rate, +}; + +static unsigned long get_ahb_clk(struct clk *clk) +{ + unsigned long rate; + unsigned long bclk_pdf; + + if (mx27_revision() >= CHIP_REV_2_0) + bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK) + >> CCM_CSCR_AHB_OFFSET; + else + bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) + >> CCM_CSCR_BCLK_OFFSET; + + rate = clk_get_rate(clk->parent); + return rate / (bclk_pdf + 1); +} + +static struct clk ahb_clk = { + .name = "ahb_clk", + .parent = &mpll_main_clk[1], + .get_rate = get_ahb_clk, +}; + +static unsigned long get_ipg_clk(struct clk *clk) +{ + unsigned long rate; + unsigned long ipg_pdf; + + if (mx27_revision() >= CHIP_REV_2_0) + return clk_get_rate(clk->parent); + else + ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; + + rate = clk_get_rate(clk->parent); + return rate / (ipg_pdf + 1); +} + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .get_rate = get_ipg_clk, +}; + +static unsigned long _clk_perclkx_recalc(struct clk *clk) +{ + unsigned long perclk_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (clk->id < 0 || clk->id > 3) + return 0; + + perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; + + return parent_rate / (perclk_pdf + 1); +} + +static struct clk per_clk[] = { + { + .name = "per_clk", + .id = 0, + .parent = &mpll_main_clk[1], + .get_rate = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK1_OFFSET, + .disable = _clk_disable, + }, { + .name = "per_clk", + .id = 1, + .parent = &mpll_main_clk[1], + .get_rate = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK2_OFFSET, + .disable = _clk_disable, + }, { + .name = "per_clk", + .id = 2, + .parent = &mpll_main_clk[1], + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .get_rate = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK3_OFFSET, + .disable = _clk_disable, + }, { + .name = "per_clk", + .id = 3, + .parent = &mpll_main_clk[1], + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .get_rate = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK4_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart1_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &per_clk[0], + .secondary = &uart1_clk[1], + }, { + .name = "uart_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart2_clk[] = { + { + .name = "uart_clk", + .id = 1, + .parent = &per_clk[0], + .secondary = &uart2_clk[1], + }, { + .name = "uart_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart3_clk[] = { + { + .name = "uart_clk", + .id = 2, + .parent = &per_clk[0], + .secondary = &uart3_clk[1], + }, { + .name = "uart_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART3_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart4_clk[] = { + { + .name = "uart_clk", + .id = 3, + .parent = &per_clk[0], + .secondary = &uart4_clk[1], + }, { + .name = "uart_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART4_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart5_clk[] = { + { + .name = "uart_clk", + .id = 4, + .parent = &per_clk[0], + .secondary = &uart5_clk[1], + }, { + .name = "uart_ipg_clk", + .id = 4, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART5_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart6_clk[] = { + { + .name = "uart_clk", + .id = 5, + .parent = &per_clk[0], + .secondary = &uart6_clk[1], + }, { + .name = "uart_ipg_clk", + .id = 5, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART6_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt1_clk[] = { + { + .name = "gpt_clk", + .id = 0, + .parent = &per_clk[0], + .secondary = &gpt1_clk[1], + }, { + .name = "gpt_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT1_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt2_clk[] = { + { + .name = "gpt_clk", + .id = 1, + .parent = &per_clk[0], + .secondary = &gpt2_clk[1], + }, { + .name = "gpt_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT2_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt3_clk[] = { + { + .name = "gpt_clk", + .id = 2, + .parent = &per_clk[0], + .secondary = &gpt3_clk[1], + }, { + .name = "gpt_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt4_clk[] = { + { + .name = "gpt_clk", + .id = 3, + .parent = &per_clk[0], + .secondary = &gpt4_clk[1], + }, { + .name = "gpt_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT4_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt5_clk[] = { + { + .name = "gpt_clk", + .id = 4, + .parent = &per_clk[0], + .secondary = &gpt5_clk[1], + }, { + .name = "gpt_ipg_clk", + .id = 4, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT5_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt6_clk[] = { + { + .name = "gpt_clk", + .id = 5, + .parent = &per_clk[0], + .secondary = &gpt6_clk[1], + }, { + .name = "gpt_ipg_clk", + .id = 5, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT6_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk pwm_clk[] = { + { + .name = "pwm_clk", + .parent = &per_clk[0], + .secondary = &pwm_clk[1], + }, { + .name = "pwm_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_PWM_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk sdhc1_clk[] = { + { + .name = "sdhc_clk", + .id = 0, + .parent = &per_clk[1], + .secondary = &sdhc1_clk[1], + }, { + .name = "sdhc_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SDHC1_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk sdhc2_clk[] = { + { + .name = "sdhc_clk", + .id = 1, + .parent = &per_clk[1], + .secondary = &sdhc2_clk[1], + }, { + .name = "sdhc_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SDHC2_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk sdhc3_clk[] = { + { + .name = "sdhc_clk", + .id = 2, + .parent = &per_clk[1], + .secondary = &sdhc3_clk[1], + }, { + .name = "sdhc_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SDHC3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk cspi1_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &per_clk[1], + .secondary = &cspi1_clk[1], + }, { + .name = "cspi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_CSPI1_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk cspi2_clk[] = { + { + .name = "cspi_clk", + .id = 1, + .parent = &per_clk[1], + .secondary = &cspi2_clk[1], + }, { + .name = "cspi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_CSPI2_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk cspi3_clk[] = { + { + .name = "cspi_clk", + .id = 2, + .parent = &per_clk[1], + .secondary = &cspi3_clk[1], + }, { + .name = "cspi_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_CSPI3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk lcdc_clk[] = { + { + .name = "lcdc_clk", + .parent = &per_clk[2], + .secondary = &lcdc_clk[1], + .round_rate = _clk_parent_round_rate, + .set_rate = _clk_parent_set_rate, + }, { + .name = "lcdc_ipg_clk", + .parent = &ipg_clk, + .secondary = &lcdc_clk[2], + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_LCDC_OFFSET, + .disable = _clk_disable, + }, { + .name = "lcdc_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk csi_clk[] = { + { + .name = "csi_perclk", + .parent = &per_clk[3], + .secondary = &csi_clk[1], + .round_rate = _clk_parent_round_rate, + .set_rate = _clk_parent_set_rate, + }, { + .name = "csi_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk usb_clk[] = { + { + .name = "usb_clk", + .parent = &spll_clk, + .get_rate = _clk_usb_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_USBOTG_OFFSET, + .disable = _clk_disable, + }, { + .name = "usb_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET, + .disable = _clk_disable, + } +}; + +static struct clk ssi1_clk[] = { + { + .name = "ssi_clk", + .id = 0, + .parent = &mpll_main_clk[1], + .secondary = &ssi1_clk[1], + .get_rate = _clk_ssi1_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET, + .disable = _clk_disable, + }, { + .name = "ssi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk ssi2_clk[] = { + { + .name = "ssi_clk", + .id = 1, + .parent = &mpll_main_clk[1], + .secondary = &ssi2_clk[1], + .get_rate = _clk_ssi2_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET, + .disable = _clk_disable, + }, { + .name = "ssi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk nfc_clk = { + .name = "nfc_clk", + .parent = &cpu_clk, + .get_rate = _clk_nfc_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET, + .disable = _clk_disable, +}; + +static struct clk vpu_clk = { + .name = "vpu_clk", + .parent = &mpll_main_clk[1], + .get_rate = _clk_vpu_recalc, + .enable = _clk_vpu_enable, + .disable = _clk_vpu_disable, +}; + +static struct clk dma_clk = { + .name = "dma_clk", + .parent = &ahb_clk, + .enable = _clk_dma_enable, + .disable = _clk_dma_disable, +}; + +static struct clk rtic_clk = { + .name = "rtic_clk", + .parent = &ahb_clk, + .enable = _clk_rtic_enable, + .disable = _clk_rtic_disable, +}; + +static struct clk brom_clk = { + .name = "brom_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk emma_clk = { + .name = "emma_clk", + .parent = &ahb_clk, + .enable = _clk_emma_enable, + .disable = _clk_emma_disable, +}; + +static struct clk slcdc_clk = { + .name = "slcdc_clk", + .parent = &ahb_clk, + .enable = _clk_slcdc_enable, + .disable = _clk_slcdc_disable, +}; + +static struct clk fec_clk = { + .name = "fec_clk", + .parent = &ahb_clk, + .enable = _clk_fec_enable, + .disable = _clk_fec_disable, +}; + +static struct clk emi_clk = { + .name = "emi_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk sahara2_clk = { + .name = "sahara_clk", + .parent = &ahb_clk, + .enable = _clk_sahara2_enable, + .disable = _clk_sahara2_disable, +}; + +static struct clk ata_clk = { + .name = "ata_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mstick1_clk = { + .name = "mstick1_clk", + .parent = &ipg_clk, + .enable = _clk_mstick1_enable, + .disable = _clk_mstick1_disable, +}; + +static struct clk wdog_clk = { + .name = "wdog_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_WDT_OFFSET, + .disable = _clk_disable, +}; + +static struct clk gpio_clk = { + .name = "gpio_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR0_GPIO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_I2C1_OFFSET, + .disable = _clk_disable, + }, { + .name = "i2c_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_I2C2_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk iim_clk = { + .name = "iim_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_IIM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk kpp_clk = { + .name = "kpp_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_KPP_OFFSET, + .disable = _clk_disable, +}; + +static struct clk owire_clk = { + .name = "owire_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_OWIRE_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_RTC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk scc_clk = { + .name = "scc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SCC_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + div = parent_rate / rate; + if (parent_rate % rate) + div++; + + if (div > 8) + div = 8; + + return parent_rate / div; +} + +static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = parent_rate / rate; + + if (div > 8 || div < 1 || ((parent_rate / div) != rate)) + return -EINVAL; + div--; + + reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK; + reg |= div << CCM_PCDR0_CLKODIV_OFFSET; + __raw_writel(reg, CCM_PCDR0); + + return 0; +} + +static unsigned long _clk_clko_recalc(struct clk *clk) +{ + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >> + CCM_PCDR0_CLKODIV_OFFSET; + div++; + + return parent_rate / div; +} + +static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK; + + if (parent == &ckil_clk) + reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ckih_clk) + reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == mpll_clk.parent) + reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == spll_clk.parent) + reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &mpll_clk) + reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &spll_clk) + reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &cpu_clk) + reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ahb_clk) + reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ipg_clk) + reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[0]) + reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[1]) + reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[2]) + reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[3]) + reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ssi1_clk[0]) + reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ssi2_clk[0]) + reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &nfc_clk) + reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &mstick1_clk) + reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &vpu_clk) + reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &usb_clk[0]) + reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET; + else + return -EINVAL; + + __raw_writel(reg, CCM_CCSR); + + return 0; +} + +static int _clk_clko_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN; + __raw_writel(reg, CCM_PCDR0); + + return 0; +} + +static void _clk_clko_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN; + __raw_writel(reg, CCM_PCDR0); +} + +static struct clk clko_clk = { + .name = "clko_clk", + .get_rate = _clk_clko_recalc, + .set_rate = _clk_clko_set_rate, + .round_rate = _clk_clko_round_rate, + .set_parent = _clk_clko_set_parent, + .enable = _clk_clko_enable, + .disable = _clk_clko_disable, +}; + +static struct clk *mxc_clks[] = { + &ckih_clk, + &ckil_clk, + &mpll_clk, + &mpll_main_clk[0], + &mpll_main_clk[1], + &spll_clk, + &cpu_clk, + &ahb_clk, + &ipg_clk, + &per_clk[0], + &per_clk[1], + &per_clk[2], + &per_clk[3], + &clko_clk, + &uart1_clk[0], + &uart1_clk[1], + &uart2_clk[0], + &uart2_clk[1], + &uart3_clk[0], + &uart3_clk[1], + &uart4_clk[0], + &uart4_clk[1], + &uart5_clk[0], + &uart5_clk[1], + &uart6_clk[0], + &uart6_clk[1], + &gpt1_clk[0], + &gpt1_clk[1], + &gpt2_clk[0], + &gpt2_clk[1], + &gpt3_clk[0], + &gpt3_clk[1], + &gpt4_clk[0], + &gpt4_clk[1], + &gpt5_clk[0], + &gpt5_clk[1], + &gpt6_clk[0], + &gpt6_clk[1], + &pwm_clk[0], + &pwm_clk[1], + &sdhc1_clk[0], + &sdhc1_clk[1], + &sdhc2_clk[0], + &sdhc2_clk[1], + &sdhc3_clk[0], + &sdhc3_clk[1], + &cspi1_clk[0], + &cspi1_clk[1], + &cspi2_clk[0], + &cspi2_clk[1], + &cspi3_clk[0], + &cspi3_clk[1], + &lcdc_clk[0], + &lcdc_clk[1], + &lcdc_clk[2], + &csi_clk[0], + &csi_clk[1], + &usb_clk[0], + &usb_clk[1], + &ssi1_clk[0], + &ssi1_clk[1], + &ssi2_clk[0], + &ssi2_clk[1], + &nfc_clk, + &vpu_clk, + &dma_clk, + &rtic_clk, + &brom_clk, + &emma_clk, + &slcdc_clk, + &fec_clk, + &emi_clk, + &sahara2_clk, + &ata_clk, + &mstick1_clk, + &wdog_clk, + &gpio_clk, + &i2c_clk[0], + &i2c_clk[1], + &iim_clk, + &kpp_clk, + &owire_clk, + &rtc_clk, + &scc_clk, +}; + +void __init change_external_low_reference(unsigned long new_ref) +{ + external_low_reference = new_ref; +} + +unsigned long __init clk_early_get_timer_rate(void) +{ + return clk_get_rate(&per_clk[0]); +} + +static void __init probe_mxc_clocks(void) +{ + int i; + + if (mx27_revision() >= CHIP_REV_2_0) { + if (CSCR() & 0x8000) + cpu_clk.parent = &mpll_main_clk[0]; + + if (!(CSCR() & 0x00800000)) + ssi2_clk[0].parent = &spll_clk; + + if (!(CSCR() & 0x00400000)) + ssi1_clk[0].parent = &spll_clk; + + if (!(CSCR() & 0x00200000)) + vpu_clk.parent = &spll_clk; + } else { + cpu_clk.parent = &mpll_clk; + cpu_clk.set_parent = NULL; + cpu_clk.round_rate = NULL; + cpu_clk.set_rate = NULL; + ahb_clk.parent = &mpll_clk; + + for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++) + per_clk[i].parent = &mpll_clk; + + ssi1_clk[0].parent = &mpll_clk; + ssi2_clk[0].parent = &mpll_clk; + + vpu_clk.parent = &mpll_clk; + } +} + +/* + * must be called very early to get information about the + * available clock rate when the timer framework starts + */ +int __init mxc_clocks_init(unsigned long fref) +{ + u32 cscr; + struct clk **clkp; + + external_high_reference = fref; + + /* detect clock reference for both system PLL */ + cscr = CSCR(); + if (cscr & CCM_CSCR_MCU) + mpll_clk.parent = &ckih_clk; + else + mpll_clk.parent = &ckil_clk; + + if (cscr & CCM_CSCR_SP) + spll_clk.parent = &ckih_clk; + else + spll_clk.parent = &ckil_clk; + + probe_mxc_clocks(); + + per_clk[0].enable(&per_clk[0]); + gpt1_clk[1].enable(&gpt1_clk[1]); + + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) + clk_register(*clkp); + + /* Turn off all possible clocks */ + __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0); + __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK, + CCM_PCCR1); + spll_clk.disable(&spll_clk); + + /* This will propagate to all children and init all the clock rates */ + + clk_enable(&emi_clk); + clk_enable(&gpio_clk); + clk_enable(&iim_clk); + clk_enable(&gpt1_clk[0]); +#ifdef CONFIG_DEBUG_LL_CONSOLE + clk_enable(&uart1_clk[0]); +#endif + return 0; +} -- cgit v0.10.2 From 80eedae6f0322dafc749140b67986b2472473745 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:00 +0200 Subject: i.MX27: Add ADS platform support This patch adds basic support for the Freescale MX27ADS reference board. Currently only a serial console can be used. Signed-off-by: Juergen Beisert diff --git a/arch/arm/configs/imx27ads_defconfig b/arch/arm/configs/imx27ads_defconfig new file mode 100644 index 0000000..bcd95b8 --- /dev/null +++ b/arch/arm/configs/imx27ads_defconfig @@ -0,0 +1,826 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Fri Jun 20 16:29:34 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +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 is not set +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_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_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_EXTRA_PASS=y +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_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_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# 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=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD 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 + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX2=y +# CONFIG_ARCH_MX3 is not set + +# +# MX2 family CPU support +# +CONFIG_MACH_MX27=y + +# +# MX2 Platforms +# +CONFIG_MACH_MX27ADS=y +# CONFIG_MACH_PCM038 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# 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=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# 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 is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# 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_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 + +# +# 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 + +# +# 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 +# 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 is not set +# 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_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# 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 +# CONFIG_MTD_OOPS 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=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# 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 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# 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_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x00000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# 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 + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# 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 +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 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_B44 is not set +# CONFIG_FEC_OLD is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN 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 is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# 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=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 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_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_IMX is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 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_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 + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_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_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# 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_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN 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_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# 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 +# CONFIG_CIFS 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 is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# 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 is not set +CONFIG_NLS_ISO8859_1=y +# 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=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# 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=1024 +# 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_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 6e7d724..6f98355 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -9,3 +9,10 @@ config MACH_MX27 comment "MX2 Platforms" depends on ARCH_MX2 + +config MACH_MX27ADS + bool "MX27ADS platform" + depends on MACH_MX27 + help + Include support for MX27ADS platform. This includes specific + configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index 74fb9b3..f6764eb 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -8,3 +8,5 @@ obj-y := system.o generic.o devices.o serial.o obj-$(CONFIG_MACH_MX27) += cpu_imx27.o obj-$(CONFIG_MACH_MX27) += clock_imx27.o + +obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c new file mode 100644 index 0000000..a9ff01f --- /dev/null +++ b/arch/arm/mach-mx2/mx27ads.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2006-2007 Freescale Semiconductor, 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ADS's NOR flash */ +static struct physmap_flash_data mx27ads_flash_data = { + .width = 2, +}; + +static struct resource mx27ads_flash_resource = { + .start = 0xc0000000, + .end = 0xc0000000 + 0x02000000 - 1, + .flags = IORESOURCE_MEM, + +}; + +static struct platform_device mx27ads_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &mx27ads_flash_data, + }, + .num_resources = 1, + .resource = &mx27ads_flash_resource, +}; + +static int mxc_uart0_pins[] = { + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS +}; + +static int uart_mxc_port0_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART0"); +} + +static int uart_mxc_port0_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART0"); +} + +static int mxc_uart1_pins[] = { + PE3_PF_UART2_CTS, + PE4_PF_UART2_RTS, + PE6_PF_UART2_TXD, + PE7_PF_UART2_RXD +}; + +static int uart_mxc_port1_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART1"); +} + +static int uart_mxc_port1_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART1"); +} + +static int mxc_uart2_pins[] = { + PE8_PF_UART3_TXD, + PE9_PF_UART3_RXD, + PE10_PF_UART3_CTS, + PE11_PF_UART3_RTS +}; + +static int uart_mxc_port2_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART2"); +} + +static int uart_mxc_port2_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART2"); +} + +static int mxc_uart3_pins[] = { + PB26_AF_UART4_RTS, + PB28_AF_UART4_TXD, + PB29_AF_UART4_CTS, + PB31_AF_UART4_RXD +}; + +static int uart_mxc_port3_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart3_pins, + ARRAY_SIZE(mxc_uart3_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART3"); +} + +static int uart_mxc_port3_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart3_pins, + ARRAY_SIZE(mxc_uart3_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART3"); +} + +static int mxc_uart4_pins[] = { + PB18_AF_UART5_TXD, + PB19_AF_UART5_RXD, + PB20_AF_UART5_CTS, + PB21_AF_UART5_RTS +}; + +static int uart_mxc_port4_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart4_pins, + ARRAY_SIZE(mxc_uart4_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART4"); +} + +static int uart_mxc_port4_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart4_pins, + ARRAY_SIZE(mxc_uart4_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART4"); +} + +static int mxc_uart5_pins[] = { + PB10_AF_UART6_TXD, + PB12_AF_UART6_CTS, + PB11_AF_UART6_RXD, + PB13_AF_UART6_RTS +}; + +static int uart_mxc_port5_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart5_pins, + ARRAY_SIZE(mxc_uart5_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART5"); +} + +static int uart_mxc_port5_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart5_pins, + ARRAY_SIZE(mxc_uart5_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART5"); +} + +static struct platform_device *platform_devices[] __initdata = { + &mx27ads_nor_mtd_device, +}; + +static int mxc_fec_pins[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_CLR, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN +}; + +static void gpio_fec_active(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "FEC"); +} + +static void gpio_fec_inactive(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "FEC"); +} + +static struct imxuart_platform_data uart_pdata[] = { + { + .init = uart_mxc_port0_init, + .exit = uart_mxc_port0_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port1_init, + .exit = uart_mxc_port1_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port2_init, + .exit = uart_mxc_port2_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port3_init, + .exit = uart_mxc_port3_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port4_init, + .exit = uart_mxc_port4_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port5_init, + .exit = uart_mxc_port5_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +static void __init mx27ads_board_init(void) +{ + int i; + + gpio_fec_active(); + + for (i = 0; i < 6; i++) + imx_init_uart(i, &uart_pdata[i]); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +static void __init mx27ads_timer_init(void) +{ + unsigned long fref = 26000000; + + if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) + fref = 27000000; + + mxc_clocks_init(fref); + mxc_timer_init("gpt_clk.0"); +} + +struct sys_timer mx27ads_timer = { + .init = mx27ads_timer_init, +}; + +static struct map_desc mx27ads_io_desc[] __initdata = { + { + .virtual = PBC_BASE_ADDRESS, + .pfn = __phys_to_pfn(CS4_BASE_ADDR), + .length = SZ_1M, + .type = MT_DEVICE, + }, +}; + +void __init mx27ads_map_io(void) +{ + mxc_map_io(); + iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc)); +} + +MACHINE_START(MX27ADS, "Freescale i.MX27ADS") + /* maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx27ads_map_io, + .init_irq = mxc_init_irq, + .init_machine = mx27ads_board_init, + .timer = &mx27ads_timer, +MACHINE_END + diff --git a/include/asm-arm/arch-mxc/board-mx27ads.h b/include/asm-arm/arch-mxc/board-mx27ads.h new file mode 100644 index 0000000..61e66da --- /dev/null +++ b/include/asm-arm/arch-mxc/board-mx27ads.h @@ -0,0 +1,354 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX27ADS_H__ +#define __ASM_ARCH_MXC_BOARD_MX27ADS_H__ + +/* external interrupt multiplexer */ +#define MXC_EXP_IO_BASE (MXC_GPIO_BASE + MXC_MAX_GPIO_LINES) + +#define MXC_VIRTUAL_INTS_BASE (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES) +#define MXC_SDIO1_CARD_IRQ MXC_VIRTUAL_INTS_BASE +#define MXC_SDIO2_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 1) +#define MXC_SDIO3_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 2) + +#define MXC_MAX_BOARD_INTS (MXC_MAX_EXP_IO_LINES + \ + MXC_MAX_VIRTUAL_INTS) + +/* + * MXC UART EVB board level configurations + */ + +#define MXC_LL_EXTUART_PADDR (CS4_BASE_ADDR + 0x20000) +#define MXC_LL_EXTUART_VADDR (CS4_BASE_ADDR_VIRT + 0x20000) +#define MXC_LL_EXTUART_16BIT_BUS + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR) + +/* + * @name Memory Size parameters + */ + +/* + * Size of SDRAM memory + */ +#define SDRAM_MEM_SIZE SZ_128M + +/* + * PBC Controller parameters + */ + +/* + * Base address of PBC controller, CS4 + */ +#define PBC_BASE_ADDRESS 0xEB000000 +#define PBC_REG_ADDR(offset) (PBC_BASE_ADDRESS + (offset)) + +/* + * PBC Interupt name definitions + */ +#define PBC_GPIO1_0 0 +#define PBC_GPIO1_1 1 +#define PBC_GPIO1_2 2 +#define PBC_GPIO1_3 3 +#define PBC_GPIO1_4 4 +#define PBC_GPIO1_5 5 + +#define PBC_INTR_MAX_NUM 6 +#define PBC_INTR_SHARED_MAX_NUM 8 + +/* When the PBC address connection is fixed in h/w, defined as 1 */ +#define PBC_ADDR_SH 0 + +/* Offsets for the PBC Controller register */ +/* + * PBC Board version register offset + */ +#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH) +/* + * PBC Board control register 1 set address. + */ +#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH) +/* + * PBC Board control register 1 clear address. + */ +#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH) +/* + * PBC Board control register 2 set address. + */ +#define PBC_BCTRL2_SET_REG PBC_REG_ADDR(0x00010 >> PBC_ADDR_SH) +/* + * PBC Board control register 2 clear address. + */ +#define PBC_BCTRL2_CLEAR_REG PBC_REG_ADDR(0x00014 >> PBC_ADDR_SH) +/* + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL3_SET_REG PBC_REG_ADDR(0x00018 >> PBC_ADDR_SH) +/* + * PBC Board control register 3 clear address. + */ +#define PBC_BCTRL3_CLEAR_REG PBC_REG_ADDR(0x0001C >> PBC_ADDR_SH) +/* + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL4_SET_REG PBC_REG_ADDR(0x00020 >> PBC_ADDR_SH) +/* + * PBC Board control register 4 clear address. + */ +#define PBC_BCTRL4_CLEAR_REG PBC_REG_ADDR(0x00024 >> PBC_ADDR_SH) +/*PBC_ADDR_SH + * PBC Board status register 1. + */ +#define PBC_BSTAT1_REG PBC_REG_ADDR(0x00028 >> PBC_ADDR_SH) +/* + * PBC Board interrupt status register. + */ +#define PBC_INTSTATUS_REG PBC_REG_ADDR(0x0002C >> PBC_ADDR_SH) +/* + * PBC Board interrupt current status register. + */ +#define PBC_INTCURR_STATUS_REG PBC_REG_ADDR(0x00034 >> PBC_ADDR_SH) +/* + * PBC Interrupt mask register set address. + */ +#define PBC_INTMASK_SET_REG PBC_REG_ADDR(0x00038 >> PBC_ADDR_SH) +/* + * PBC Interrupt mask register clear address. + */ +#define PBC_INTMASK_CLEAR_REG PBC_REG_ADDR(0x0003C >> PBC_ADDR_SH) +/* + * External UART A. + */ +#define PBC_SC16C652_UARTA_REG PBC_REG_ADDR(0x20000 >> PBC_ADDR_SH) +/* + * UART 4 Expanding Signal Status. + */ +#define PBC_UART_STATUS_REG PBC_REG_ADDR(0x22000 >> PBC_ADDR_SH) +/* + * UART 4 Expanding Signal Control Set. + */ +#define PBC_UCTRL_SET_REG PBC_REG_ADDR(0x24000 >> PBC_ADDR_SH) +/* + * UART 4 Expanding Signal Control Clear. + */ +#define PBC_UCTRL_CLR_REG PBC_REG_ADDR(0x26000 >> PBC_ADDR_SH) +/* + * Ethernet Controller IO base address. + */ +#define PBC_CS8900A_IOBASE_REG PBC_REG_ADDR(0x40000 >> PBC_ADDR_SH) +/* + * Ethernet Controller Memory base address. + */ +#define PBC_CS8900A_MEMBASE_REG PBC_REG_ADDR(0x42000 >> PBC_ADDR_SH) +/* + * Ethernet Controller DMA base address. + */ +#define PBC_CS8900A_DMABASE_REG PBC_REG_ADDR(0x44000 >> PBC_ADDR_SH) + +/* PBC Board Version Register bit definition */ +#define PBC_VERSION_ADS 0x8000 /* Bit15=1 means version for ads */ +#define PBC_VERSION_EVB_REVB 0x4000 /* BIT14=1 means version for evb revb */ + +/* PBC Board Control Register 1 bit definitions */ +#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */ +#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */ +#define PBC_BCTRL1_FRST 0x0004 /* FEC Reset */ +#define PBC_BCTRL1_ESLEEP 0x0010 /* Enable ethernet Sleep */ +#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */ + +/* PBC Board Control Register 2 bit definitions */ +#define PBC_BCTRL2_VCC_EN 0x0004 /* Enable VCC */ +#define PBC_BCTRL2_VPP_EN 0x0008 /* Enable Vpp */ +#define PBC_BCTRL2_ATAFEC_EN 0X0010 +#define PBC_BCTRL2_ATAFEC_SEL 0X0020 +#define PBC_BCTRL2_ATA_EN 0X0040 +#define PBC_BCTRL2_IRDA_SD 0X0080 +#define PBC_BCTRL2_IRDA_EN 0X0100 +#define PBC_BCTRL2_CCTL10 0X0200 +#define PBC_BCTRL2_CCTL11 0X0400 + +/* PBC Board Control Register 3 bit definitions */ +#define PBC_BCTRL3_HSH_EN 0X0020 +#define PBC_BCTRL3_FSH_MOD 0X0040 +#define PBC_BCTRL3_OTG_HS_EN 0X0080 +#define PBC_BCTRL3_OTG_VBUS_EN 0X0100 +#define PBC_BCTRL3_FSH_VBUS_EN 0X0200 +#define PBC_BCTRL3_USB_OTG_ON 0X0800 +#define PBC_BCTRL3_USB_FSH_ON 0X1000 + +/* PBC Board Control Register 4 bit definitions */ +#define PBC_BCTRL4_REGEN_SEL 0X0001 +#define PBC_BCTRL4_USER_OFF 0X0002 +#define PBC_BCTRL4_VIB_EN 0X0004 +#define PBC_BCTRL4_PWRGT1_EN 0X0008 +#define PBC_BCTRL4_PWRGT2_EN 0X0010 +#define PBC_BCTRL4_STDBY_PRI 0X0020 + +#ifndef __ASSEMBLY__ +/* + * Enumerations for SD cards and memory stick card. This corresponds to + * the card EN bits in the IMR: SD1_EN | MS_EN | SD3_EN | SD2_EN. + */ +enum mxc_card_no { + MXC_CARD_SD2 = 0, + MXC_CARD_SD3, + MXC_CARD_MS, + MXC_CARD_SD1, + MXC_CARD_MIN = MXC_CARD_SD2, + MXC_CARD_MAX = MXC_CARD_SD1, +}; +#endif + +#define MXC_CPLD_VER_1_50 0x01 + +/* + * PBC BSTAT Register bit definitions + */ +#define PBC_BSTAT_PRI_INT 0X0001 +#define PBC_BSTAT_USB_BYP 0X0002 +#define PBC_BSTAT_ATA_IOCS16 0X0004 +#define PBC_BSTAT_ATA_CBLID 0X0008 +#define PBC_BSTAT_ATA_DASP 0X0010 +#define PBC_BSTAT_PWR_RDY 0X0020 +#define PBC_BSTAT_SD3_WP 0X0100 +#define PBC_BSTAT_SD2_WP 0X0200 +#define PBC_BSTAT_SD1_WP 0X0400 +#define PBC_BSTAT_SD3_DET 0X0800 +#define PBC_BSTAT_SD2_DET 0X1000 +#define PBC_BSTAT_SD1_DET 0X2000 +#define PBC_BSTAT_MS_DET 0X4000 +#define PBC_BSTAT_SD3_DET_BIT 11 +#define PBC_BSTAT_SD2_DET_BIT 12 +#define PBC_BSTAT_SD1_DET_BIT 13 +#define PBC_BSTAT_MS_DET_BIT 14 +#define MXC_BSTAT_BIT(n) ((n == MXC_CARD_SD2) ? PBC_BSTAT_SD2_DET : \ + ((n == MXC_CARD_SD3) ? PBC_BSTAT_SD3_DET : \ + ((n == MXC_CARD_SD1) ? PBC_BSTAT_SD1_DET : \ + ((n == MXC_CARD_MS) ? PBC_BSTAT_MS_DET : \ + 0x0)))) + +/* + * PBC UART Control Register bit definitions + */ +#define PBC_UCTRL_DCE_DCD 0X0001 +#define PBC_UCTRL_DCE_DSR 0X0002 +#define PBC_UCTRL_DCE_RI 0X0004 +#define PBC_UCTRL_DTE_DTR 0X0100 + +/* + * PBC UART Status Register bit definitions + */ +#define PBC_USTAT_DTE_DCD 0X0001 +#define PBC_USTAT_DTE_DSR 0X0002 +#define PBC_USTAT_DTE_RI 0X0004 +#define PBC_USTAT_DCE_DTR 0X0100 + +/* + * PBC Interupt mask register bit definitions + */ +#define PBC_INTR_SD3_R_EN_BIT 4 +#define PBC_INTR_SD2_R_EN_BIT 0 +#define PBC_INTR_SD1_R_EN_BIT 6 +#define PBC_INTR_MS_R_EN_BIT 5 +#define PBC_INTR_SD3_EN_BIT 13 +#define PBC_INTR_SD2_EN_BIT 12 +#define PBC_INTR_MS_EN_BIT 14 +#define PBC_INTR_SD1_EN_BIT 15 + +#define PBC_INTR_SD2_R_EN 0x0001 +#define PBC_INTR_LOW_BAT 0X0002 +#define PBC_INTR_OTG_FSOVER 0X0004 +#define PBC_INTR_FSH_OVER 0X0008 +#define PBC_INTR_SD3_R_EN 0x0010 +#define PBC_INTR_MS_R_EN 0x0020 +#define PBC_INTR_SD1_R_EN 0x0040 +#define PBC_INTR_FEC_INT 0X0080 +#define PBC_INTR_ENET_INT 0X0100 +#define PBC_INTR_OTGFS_INT 0X0200 +#define PBC_INTR_XUART_INT 0X0400 +#define PBC_INTR_CCTL12 0X0800 +#define PBC_INTR_SD2_EN 0x1000 +#define PBC_INTR_SD3_EN 0x2000 +#define PBC_INTR_MS_EN 0x4000 +#define PBC_INTR_SD1_EN 0x8000 + + + +/* For interrupts like xuart, enet etc */ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX27_PIN_TIN) +#define MXC_MAX_EXP_IO_LINES 16 + +/* + * This corresponds to PBC_INTMASK_SET_REG at offset 0x38. + * + */ +#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4) +#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5) +#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6) +#define EXPIO_INT_FEC (MXC_EXP_IO_BASE + 7) +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9) +#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) +#define EXPIO_INT_CCTL12_INT (MXC_EXP_IO_BASE + 11) +#define EXPIO_INT_SD2_EN (MXC_EXP_IO_BASE + 12) +#define EXPIO_INT_SD3_EN (MXC_EXP_IO_BASE + 13) +#define EXPIO_INT_MS_EN (MXC_EXP_IO_BASE + 14) +#define EXPIO_INT_SD1_EN (MXC_EXP_IO_BASE + 15) + +/* + * This is System IRQ used by CS8900A for interrupt generation + * taken from platform.h + */ +#define CS8900AIRQ EXPIO_INT_ENET_INT +/* This is I/O Base address used to access registers of CS8900A on MXC ADS */ +#define CS8900A_BASE_ADDRESS (PBC_CS8900A_IOBASE_REG + 0x300) + +#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX27_PIN_TOUT) + +/* +* This is used to detect if the CPLD version is for mx27 evb board rev-a +*/ +#define PBC_CPLD_VERSION_IS_REVA() \ + ((__raw_readw(PBC_VERSION_REG) & \ + (PBC_VERSION_ADS | PBC_VERSION_EVB_REVB))\ + == 0) + +/* This is used to active or inactive ata signal in CPLD . + * It is dependent with hardware + */ +#define PBC_ATA_SIGNAL_ACTIVE() \ + __raw_writew( \ + PBC_BCTRL2_ATAFEC_EN|PBC_BCTRL2_ATAFEC_SEL|PBC_BCTRL2_ATA_EN, \ + PBC_BCTRL2_CLEAR_REG) + +#define PBC_ATA_SIGNAL_INACTIVE() \ + __raw_writew( \ + PBC_BCTRL2_ATAFEC_EN|PBC_BCTRL2_ATAFEC_SEL|PBC_BCTRL2_ATA_EN, \ + PBC_BCTRL2_SET_REG) + +#define MXC_BD_LED1 (1 << 5) +#define MXC_BD_LED2 (1 << 6) +#define MXC_BD_LED_ON(led) \ + __raw_writew(led, PBC_BCTRL1_SET_REG) +#define MXC_BD_LED_OFF(led) \ + __raw_writew(led, PBC_BCTRL1_CLEAR_REG) + +/* to determine the correct external crystal reference */ +#define CKIH_27MHZ_BIT_SET (1 << 3) + +#endif /* __ASM_ARCH_MXC_BOARD_MX27ADS_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index 5add48b..c6c5680 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -22,7 +22,9 @@ #ifdef CONFIG_MACH_MX31LITE #include #endif - +#ifdef CONFIG_MACH_MX27ADS +#include +#endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? -- cgit v0.10.2 From 7e5e9f5457f5cd019fd7e2f3da94e9fc72cc9ff6 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:00 +0200 Subject: i.MX27: Adding PCM038 platform support This patch adds support for the phyCORE-i.MX27 cpu module (aka pcm038). It is as generic as possible in order to support any kind of baseboard. Note: This CPU module implementation can't work without a baseboard support. Baseboard support can be added by the PCM-970 (included in this patch stack) or any custom variant. Signed-off-by: Juergen Beisert diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig new file mode 100644 index 0000000..6b798c2 --- /dev/null +++ b/arch/arm/configs/pcm038_defconfig @@ -0,0 +1,1008 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Fri Jun 20 16:38:36 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +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 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=y +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# 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_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +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_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_PROC_PAGE_MONITOR 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 is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD 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 + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX2=y +# CONFIG_ARCH_MX3 is not set + +# +# MX2 family CPU support +# +CONFIG_MACH_MX27=y + +# +# MX2 Platforms +# +# CONFIG_MACH_MX27ADS is not set +CONFIG_MACH_PCM038=y +CONFIG_MACH_PCM970_BASEBOARD=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# 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=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# 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 is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# 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_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 + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE 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 + +# +# 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 +# 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_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_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# 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 +# CONFIG_MTD_OOPS 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=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# 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 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# 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_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x00000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# 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 +# 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 + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# 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 +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_AX88796 is not set +# CONFIG_SMC91X 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_B44 is not set +CONFIG_FEC_OLD=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN 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 is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# 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=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 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=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 + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM 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 is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_PLATFORM is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_TPS65010 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=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# 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_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL 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 is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO 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_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_PCF8563=y +# 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 + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_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_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# 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_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN 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_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# 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 +# CONFIG_CIFS 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 is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# 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 is not set +CONFIG_NLS_ISO8859_1=y +# 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=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# 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=1024 +# 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_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 6f98355..4c19e1c 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -16,3 +16,10 @@ config MACH_MX27ADS help Include support for MX27ADS platform. This includes specific configurations for the board and its peripherals. + +config MACH_PCM038 + bool "Phytec phyCORE-i.MX27 CPU module (pcm038)" + depends on MACH_MX27 + help + Include support for phyCORE-i.MX27 (aka pcm038) platform. This + includes specific configurations for the module and its peripherals. diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index f6764eb..f8d3836 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_MACH_MX27) += cpu_imx27.o obj-$(CONFIG_MACH_MX27) += clock_imx27.o obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o +obj-$(CONFIG_MACH_PCM038) += pcm038.o diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c new file mode 100644 index 0000000..46fc026 --- /dev/null +++ b/arch/arm/mach-mx2/pcm038.c @@ -0,0 +1,200 @@ +/* + * Copyright 2007 Robert Schwebel , Pengutronix + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Phytec's phyCORE-i.MX27 comes with 32MiB flash, + * 16 bit width + */ +static struct physmap_flash_data pcm038_flash_data = { + .width = 2, +}; + +static struct resource pcm038_flash_resource = { + .start = 0xc0000000, + .end = 0xc1ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device pcm038_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &pcm038_flash_data, + }, + .num_resources = 1, + .resource = &pcm038_flash_resource, +}; + +static int mxc_uart0_pins[] = { + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS +}; + +static int uart_mxc_port0_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART0"); +} + +static int uart_mxc_port0_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART0"); +} + +static int mxc_uart1_pins[] = { + PE3_PF_UART2_CTS, + PE4_PF_UART2_RTS, + PE6_PF_UART2_TXD, + PE7_PF_UART2_RXD +}; + +static int uart_mxc_port1_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART1"); +} + +static int uart_mxc_port1_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART1"); +} + +static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS, + PE9_PF_UART3_RXD, + PE10_PF_UART3_CTS, + PE9_PF_UART3_RXD }; + +static int uart_mxc_port2_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART2"); +} + +static int uart_mxc_port2_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART2"); +} + +static struct imxuart_platform_data uart_pdata[] = { + { + .init = uart_mxc_port0_init, + .exit = uart_mxc_port0_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port1_init, + .exit = uart_mxc_port1_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port2_init, + .exit = uart_mxc_port2_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +static int mxc_fec_pins[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_CLR, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN +}; + +static void gpio_fec_active(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "FEC"); +} + +static void gpio_fec_inactive(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "FEC"); +} + +static struct platform_device *platform_devices[] __initdata = { + &pcm038_nor_mtd_device, +}; + +static void __init pcm038_init(void) +{ + int i; + gpio_fec_active(); + + for (i = 0; i < 3; i++) + imx_init_uart(i, &uart_pdata[i]); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +static void __init pcm038_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("gpt_clk.0"); +} + +struct sys_timer pcm038_timer = { + .init = pcm038_timer_init, +}; + +MACHINE_START(PCM038, "phyCORE-i.MX27") + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mxc_map_io, + .init_irq = mxc_init_irq, + .init_machine = pcm038_init, + .timer = &pcm038_timer, +MACHINE_END diff --git a/include/asm-arm/arch-mxc/board-pcm038.h b/include/asm-arm/arch-mxc/board-pcm038.h new file mode 100644 index 0000000..300467e --- /dev/null +++ b/include/asm-arm/arch-mxc/board-pcm038.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__ +#define __ASM_ARCH_MXC_BOARD_PCM038_H__ + +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000) + +#ifndef __ASSEMBLY__ +/* + * This CPU module needs a baseboard to work. After basic initializing + * its own devices, it calls baseboard's init function. + * TODO: Add your own baseboard init function and call it from + * inside pcm038_init(). + */ +#endif + +#endif /* __ASM_ARCH_MXC_BOARD_PCM038_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index c6c5680..575087f 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -25,6 +25,9 @@ #ifdef CONFIG_MACH_MX27ADS #include #endif +#ifdef CONFIG_MACH_PCM038 +#include +#endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? -- cgit v0.10.2 From ff6552e4f3505da9c2886098773146be71c872e3 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:01 +0200 Subject: i.MX27 family: Add the Phytec PCM970 evaluation board The Phytec phyCORE-i.MX27 CPU module is delivered with the PCM970 baseboard by default. This patch adds support for the hardware. This code is only an empty stub; it is filled up with functionality in a later patch series. Signed-off-by: Juergen Beisert diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 4c19e1c..1eaa97c 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -23,3 +23,17 @@ config MACH_PCM038 help Include support for phyCORE-i.MX27 (aka pcm038) platform. This includes specific configurations for the module and its peripherals. + +choice + prompt "Baseboard" + depends on MACH_PCM038 + default MACH_PCM970_BASEBOARD + +config MACH_PCM970_BASEBOARD + prompt "PHYTEC PCM970 development board" + bool + help + This adds board specific devices that can be found on Phytec's + PCM970 evaluation board. + +endchoice diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index f8d3836..382d860 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_MACH_MX27) += clock_imx27.o obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o obj-$(CONFIG_MACH_PCM038) += pcm038.o +obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index 46fc026..a9a28f5 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -177,6 +177,10 @@ static void __init pcm038_init(void) imx_init_uart(i, &uart_pdata[i]); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + +#ifdef CONFIG_MACH_PCM970_BASEBOARD + pcm970_baseboard_init(); +#endif } static void __init pcm038_timer_init(void) diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c new file mode 100644 index 0000000..028ac4d --- /dev/null +++ b/arch/arm/mach-mx2/pcm970-baseboard.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +/* + * system init for baseboard usage. Will be called by pcm038 init. + * + * Add platform devices present on this baseboard and init + * them from CPU side as far as required to use them later on + */ +void __init pcm970_baseboard_init(void) +{ +} diff --git a/include/asm-arm/arch-mxc/board-pcm038.h b/include/asm-arm/arch-mxc/board-pcm038.h index 300467e..750c62a 100644 --- a/include/asm-arm/arch-mxc/board-pcm038.h +++ b/include/asm-arm/arch-mxc/board-pcm038.h @@ -30,7 +30,12 @@ * its own devices, it calls baseboard's init function. * TODO: Add your own baseboard init function and call it from * inside pcm038_init(). + * + * This example here is for the development board. Refer pcm970-baseboard.c */ + +extern void pcm970_baseboard_init(void); + #endif #endif /* __ASM_ARCH_MXC_BOARD_PCM038_H__ */ -- cgit v0.10.2 From 1bd55a436f1f90de0e7f476e514e01bd67497b88 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:02 +0200 Subject: i.MX2 family: Add basic mach support This patch adds basic mach support for the mx2 processor family, based on the original freescale code and adapted to mainline kernel coding style. This part adds the global build only. Signed-off-by: Juergen Beisert diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e72db27..009d4fe 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -137,6 +137,7 @@ endif machine-$(CONFIG_ARCH_DAVINCI) := davinci machine-$(CONFIG_ARCH_KS8695) := ks8695 incdir-$(CONFIG_ARCH_MXC) := mxc + machine-$(CONFIG_ARCH_MX2) := mx2 machine-$(CONFIG_ARCH_MX3) := mx3 machine-$(CONFIG_ARCH_ORION5X) := orion5x machine-$(CONFIG_ARCH_MSM7X00A) := msm diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 33ed048..68ea247 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -180,8 +180,8 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI - default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2 + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2 select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_PABRT_NOIFAR diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index bb6e127..e14eaad 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -3,9 +3,14 @@ if ARCH_MXC menu "Freescale MXC Implementations" choice - prompt "MXC/iMX System Type" + prompt "MXC/iMX Base Type" default ARCH_MX3 +config ARCH_MX2 + bool "MX2-based" + help + This enables support for systems based on the Freescale i.MX2 family + config ARCH_MX3 bool "MX3-based" help @@ -13,6 +18,7 @@ config ARCH_MX3 endchoice +source "arch/arm/mach-mx2/Kconfig" source "arch/arm/mach-mx3/Kconfig" endmenu -- cgit v0.10.2 From 5e374fb62621aca9522f76c2317c9acda75a8e88 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 1 Jul 2008 13:12:04 +0200 Subject: generic-ipi: fixlet create proper stackframe. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 56546e8..361b7a4 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -198,7 +198,7 @@ void smp_call_function_interrupt(struct pt_regs *regs) irq_exit(); } -void smp_call_function_single_interrupt(void) +void smp_call_function_single_interrupt(struct pt_regs *regs) { ack_APIC_irq(); irq_enter(); -- cgit v0.10.2 From 265d529cef6fd57698d79b3c0edd3a8178059ea6 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 7 Jul 2008 10:02:36 +0100 Subject: [GFS2] Fix delayed demote race There is a race in the delayed demote code where it does the wrong thing if a demotion to UN has occurred for other reasons before the delay has expired. This patch adds an assert to catch that condition as well as fixing the root cause by adding an additional check for the UN state. Signed-off-by: Steven Whitehouse Cc: Bob Peterson diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 8d5450f..cd0aa21 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -587,6 +587,7 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock) if (nonblock) goto out_sched; set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); + GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE); gl->gl_target = gl->gl_demote_state; } else { if (test_bit(GLF_DEMOTE, &gl->gl_flags)) @@ -617,7 +618,9 @@ static void glock_work_func(struct work_struct *work) if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) finish_xmote(gl, gl->gl_reply); spin_lock(&gl->gl_spin); - if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags)) { + if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && + gl->gl_state != LM_ST_UNLOCKED && + gl->gl_demote_state != LM_ST_EXCLUSIVE) { unsigned long holdtime, now = jiffies; holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; if (time_before(now, holdtime)) -- cgit v0.10.2 From 209806aba9d540dde3db0a5ce72307f85f33468f Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 7 Jul 2008 10:07:28 +0100 Subject: [GFS2] Allow local DF locks when holding a cached EX glock We already allow local SH locks while we hold a cached EX glock, so here we allow DF locks as well. This works only because we rely on the VFS's invalidation for locally cached data, and because if we hold an EX lock, then we know that no other node can be caching data relating to this file. It dramatically speeds up initial writes to O_DIRECT files since we fall back to buffered I/O for this and would otherwise bounce between DF and EX modes on each and every write call. The lessons to be learned from that are to ensure that (for the time being anyway) O_DIRECT files are preallocated and that they are written to using reasonably large I/O sizes. Even so this change fixes that corner case nicely Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index cd0aa21..13391e5 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -267,8 +267,12 @@ static inline int may_grant(const struct gfs2_glock *gl, const struct gfs2_holde return 1; if (gh->gh_flags & GL_EXACT) return 0; - if (gh->gh_state == LM_ST_SHARED && gl->gl_state == LM_ST_EXCLUSIVE) - return 1; + if (gl->gl_state == LM_ST_EXCLUSIVE) { + if (gh->gh_state == LM_ST_SHARED && gh_head->gh_state == LM_ST_SHARED) + return 1; + if (gh->gh_state == LM_ST_DEFERRED && gh_head->gh_state == LM_ST_DEFERRED) + return 1; + } if (gl->gl_state != LM_ST_UNLOCKED && (gh->gh_flags & LM_FLAG_ANY)) return 1; return 0; -- cgit v0.10.2 From 5a2cc50f166babc26103279c4fbc9f2bf73b79de Mon Sep 17 00:00:00 2001 From: eric miao Date: Mon, 26 May 2008 03:28:09 +0100 Subject: [ARM] 5063/1: pxa: add clk support for pxa2xx I2S Signed-off-by: Eric Miao Acked-by: Mark Brown Signed-off-by: Russell King diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 4250710..e130346 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ struct pxa_i2s_port { u32 fmt; }; static struct pxa_i2s_port pxa_i2s; +static struct clk *clk_i2s; static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { .name = "I2S PCM Stereo out", @@ -82,6 +84,10 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + clk_i2s = clk_get(NULL, "I2SCLK"); + if (IS_ERR(clk_i2s)) + return PTR_ERR(clk_i2s); + if (!cpu_dai->active) { SACR0 |= SACR0_RST; SACR0 = 0; @@ -149,7 +155,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm); pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk); - pxa_set_cken(CKEN_I2S, 1); + clk_enable(clk_i2s); pxa_i2s_wait(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -234,8 +240,10 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { SACR0 &= ~SACR0_ENB; pxa_i2s_wait(); - pxa_set_cken(CKEN_I2S, 0); + clk_disable(clk_i2s); } + + clk_put(clk_i2s); } #ifdef CONFIG_PM -- cgit v0.10.2 From 9f17f2874834f4cdbe48cc05676d8f7558793204 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Sun, 22 Jun 2008 04:27:28 +0100 Subject: [ARM] 5118/1: pxafb: add exit and remove handlers This patch adds exit and remove handlers to pxafb so that it can be loaded and unloaded as a module. Signed-off-by: Jaya Kumar Acked-by: Krzysztof Helt Acked-by: Eric Miao Signed-off-by: Russell King diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3ee314b..3682bbd 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1777,11 +1777,49 @@ failed: return ret; } +static int __devexit pxafb_remove(struct platform_device *dev) +{ + struct pxafb_info *fbi = platform_get_drvdata(dev); + struct resource *r; + int irq; + struct fb_info *info; + + if (!fbi) + return 0; + + info = &fbi->fb; + + unregister_framebuffer(info); + + pxafb_disable_controller(fbi); + + if (fbi->fb.cmap.len) + fb_dealloc_cmap(&fbi->fb.cmap); + + irq = platform_get_irq(dev, 0); + free_irq(irq, fbi); + + dma_free_writecombine(&dev->dev, fbi->map_size, + fbi->map_cpu, fbi->map_dma); + + iounmap(fbi->mmio_base); + + r = platform_get_resource(dev, IORESOURCE_MEM, 0); + release_mem_region(r->start, r->end - r->start + 1); + + clk_put(fbi->clk); + kfree(fbi); + + return 0; +} + static struct platform_driver pxafb_driver = { .probe = pxafb_probe, + .remove = pxafb_remove, .suspend = pxafb_suspend, .resume = pxafb_resume, .driver = { + .owner = THIS_MODULE, .name = "pxa2xx-fb", }, }; @@ -1794,7 +1832,13 @@ static int __devinit pxafb_init(void) return platform_driver_register(&pxafb_driver); } +static void __exit pxafb_exit(void) +{ + platform_driver_unregister(&pxafb_driver); +} + module_init(pxafb_init); +module_exit(pxafb_exit); MODULE_DESCRIPTION("loadable framebuffer driver for PXA"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From f1b23586c1f50d4c5684e56395140ec1cd8b688d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 30 Jun 2008 18:08:11 +0100 Subject: [ARM] 5135/1: pxa: drop superfluous asm/arch/pxa2xx-gpio.h includes Both i2c-pxa.c and irq.c still include pxa2xx-gpio.h although is is not needed anymore. Signed-off-by: Philipp Zabel Acked-by: Eric Miao Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index a9a0c3f..fbff557 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "generic.h" diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index eb69fba..eb26d2a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -39,7 +39,6 @@ #include #include #include -#include struct pxa_i2c { spinlock_t lock; -- cgit v0.10.2 From 5e329d1c7f5fe6adfee99c783fa98bda7dae8ac5 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 6 Jun 2008 10:12:37 +0100 Subject: [ARM] 5079/1: Warn people when using pxa2xx-gpio.h Warn people when using pxa2xx-gpio.h as it is only here for backwards compatibility. The new mfp-pxa2[57]x.h and the relevant API should be used instead. Signed-off-by: Stefan Schmidt Signed-off-by: Russell King diff --git a/include/asm-arm/arch-pxa/pxa2xx-gpio.h b/include/asm-arm/arch-pxa/pxa2xx-gpio.h index 763313c..a6e60f6 100644 --- a/include/asm-arm/arch-pxa/pxa2xx-gpio.h +++ b/include/asm-arm/arch-pxa/pxa2xx-gpio.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARCH_PXA2XX_GPIO_H #define __ASM_ARCH_PXA2XX_GPIO_H +#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h + /* GPIO alternate function assignments */ #define GPIO1_RST 1 /* reset */ -- cgit v0.10.2 From 4ed47896935573c8423d05bddda3f269d6e6c613 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 3 Jul 2008 16:11:06 +0100 Subject: [ARM] mach-types update Update mach-types. Remove invalid or incorrect entries. Signed-off-by: Russell King diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 207a8b5..0be5630 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Sat Apr 19 11:23:38 2008 +# Last update: Mon Jul 7 16:25:39 2008 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -560,7 +560,6 @@ husky MACH_HUSKY HUSKY 543 boxer MACH_BOXER BOXER 544 shepherd MACH_SHEPHERD SHEPHERD 545 aml42800aa MACH_AML42800AA AML42800AA 546 -ml674001 MACH_MACH_TYPE_ML674001 MACH_TYPE_ML674001 547 lpc2294 MACH_LPC2294 LPC2294 548 switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 ens_cmu MACH_ENS_CMU ENS_CMU 550 @@ -748,7 +747,6 @@ anubis MACH_ANUBIS ANUBIS 734 ite8152 MACH_ITE8152 ITE8152 735 lpc3xxx MACH_LPC3XXX LPC3XXX 736 puppeteer MACH_PUPPETEER PUPPETEER 737 -vt001 MACH_MACH_VADATECH MACH_VADATECH 738 e570 MACH_E570 E570 739 x50 MACH_X50 X50 740 recon MACH_RECON RECON 741 @@ -839,7 +837,7 @@ ccxp270 MACH_CCXP CCXP 825 omap_gsample MACH_OMAP_GSAMPLE OMAP_GSAMPLE 826 realview_eb MACH_REALVIEW_EB REALVIEW_EB 827 samoa MACH_SAMOA SAMOA 828 -t3xscale MACH_T3XSCALE T3XSCALE 829 +palmt3 MACH_PALMT3 PALMT3 829 i878 MACH_I878 I878 830 borzoi MACH_BORZOI BORZOI 831 gecko MACH_GECKO GECKO 832 @@ -895,7 +893,7 @@ mio8390 MACH_MIO8390 MIO8390 881 omi_board MACH_OMI_BOARD OMI_BOARD 882 mx21civ MACH_MX21CIV MX21CIV 883 mahi_cdac MACH_MAHI_CDAC MAHI_CDAC 884 -xscale_palmtx MACH_XSCALE_PALMTX XSCALE_PALMTX 885 +palmtx MACH_PALMTX PALMTX 885 s3c2413 MACH_S3C2413 S3C2413 887 samsys_ep0 MACH_SAMSYS_EP0 SAMSYS_EP0 888 wg302v1 MACH_WG302V1 WG302V1 889 @@ -918,7 +916,7 @@ nxdb500 MACH_NXDB500 NXDB500 905 apf9328 MACH_APF9328 APF9328 906 omap_wipoq MACH_OMAP_WIPOQ OMAP_WIPOQ 907 omap_twip MACH_OMAP_TWIP OMAP_TWIP 908 -xscale_treo650 MACH_XSCALE_PALMTREO650 XSCALE_PALMTREO650 909 +palmtreo650 MACH_PALMTREO650 PALMTREO650 909 acumen MACH_ACUMEN ACUMEN 910 xp100 MACH_XP100 XP100 911 fs2410 MACH_FS2410 FS2410 912 @@ -926,8 +924,8 @@ pxa270_cerf MACH_PXA270_CERF PXA270_CERF 913 sq2ftlpalm MACH_SQ2FTLPALM SQ2FTLPALM 914 bsemserver MACH_BSEMSERVER BSEMSERVER 915 netclient MACH_NETCLIENT NETCLIENT 916 -xscale_palmtt5 MACH_XSCALE_PALMTT5 XSCALE_PALMTT5 917 -xscale_palmtc MACH_OMAP_PALMTC OMAP_PALMTC 918 +palmt5 MACH_PALMT5 PALMT5 917 +palmtc MACH_PALMTC PALMTC 918 omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 rea_2d MACH_REA_2D REA_2D 921 @@ -1220,7 +1218,6 @@ empca400 MACH_EMPCA400 EMPCA400 1211 em7210 MACH_EM7210 EM7210 1212 htchermes MACH_HTCHERMES HTCHERMES 1213 eti_c1 MACH_ETI_C1 ETI_C1 1214 -mach_dep2410 MACH_MACH_DEP2410 MACH_DEP2410 1215 ac100 MACH_AC100 AC100 1216 sneetch MACH_SNEETCH SNEETCH 1217 studentmate MACH_STUDENTMATE STUDENTMATE 1218 @@ -1421,10 +1418,10 @@ looxc550 MACH_LOOXC550 LOOXC550 1417 cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418 app3xx MACH_APP3XX APP3XX 1419 sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420 -xscale_palmt700p MACH_XSCALE_PALMT700P XSCALE_PALMT700P 1421 -xscale_palmt700w MACH_XSCALE_PALMT700W XSCALE_PALMT700W 1422 -xscale_palmt750 MACH_XSCALE_PALMT750 XSCALE_PALMT750 1423 -xscale_palmt755p MACH_XSCALE_PALMT755P XSCALE_PALMT755P 1424 +palmtreo700p MACH_PALMTREO700P PALMTREO700P 1421 +palmtreo700w MACH_PALMTREO700W PALMTREO700W 1422 +palmtreo750 MACH_PALMTREO750 PALMTREO750 1423 +palmtreo755p MACH_PALMTREO755P PALMTREO755P 1424 ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425 sarge MACH_SARGE SARGE 1426 a696 MACH_A696 A696 1427 @@ -1463,7 +1460,7 @@ artemis MACH_ARTEMIS ARTEMIS 1462 htctitan MACH_HTCTITAN HTCTITAN 1463 qranium MACH_QRANIUM QRANIUM 1464 adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465 -adx_medcom MACH_ADX_MEDINET ADX_MEDINET 1466 +adx_medcom MACH_ADX_MEDCOM ADX_MEDCOM 1466 bboard MACH_BBOARD BBOARD 1467 cambria MACH_CAMBRIA CAMBRIA 1468 mt7xxx MACH_MT7XXX MT7XXX 1469 @@ -1519,7 +1516,7 @@ wp188 MACH_WP188 WP188 1518 corsica MACH_CORSICA CORSICA 1519 bigeye MACH_BIGEYE BIGEYE 1520 tll5000 MACH_TLL5000 TLL5000 1522 -hni270 MACH_HNI_X270 HNI_X270 1523 +bebot MACH_BEBOT BEBOT 1523 qong MACH_QONG QONG 1524 tcompact MACH_TCOMPACT TCOMPACT 1525 puma5 MACH_PUMA5 PUMA5 1526 @@ -1636,7 +1633,6 @@ awlug4lcu MACH_AWLUG4LCU AWLUG4LCU 1637 palermoc MACH_PALERMOC PALERMOC 1638 omap_ldp MACH_OMAP_LDP OMAP_LDP 1639 ip500 MACH_IP500 IP500 1640 -mx35ads MACH_MACH_MX35ADS MACH_MX35ADS 1641 ase2 MACH_ASE2 ASE2 1642 mx35evb MACH_MX35EVB MX35EVB 1643 aml_m8050 MACH_AML_M8050 AML_M8050 1644 @@ -1647,7 +1643,7 @@ badger MACH_BADGER BADGER 1648 trizeps4wl MACH_TRIZEPS4WL TRIZEPS4WL 1649 trizeps5 MACH_TRIZEPS5 TRIZEPS5 1650 marlin MACH_MARLIN MARLIN 1651 -ts7800 MACH_TS7800 TS7800 1652 +ts78xx MACH_TS78XX TS78XX 1652 hpipaq214 MACH_HPIPAQ214 HPIPAQ214 1653 at572d940dcm MACH_AT572D940DCM AT572D940DCM 1654 ne1board MACH_NE1BOARD NE1BOARD 1655 @@ -1720,3 +1716,99 @@ htc_kaiser MACH_HTC_KAISER HTC_KAISER 1724 lg_ks20 MACH_LG_KS20 LG_KS20 1725 hhgps MACH_HHGPS HHGPS 1726 nokia_n810_wimax MACH_NOKIA_N810_WIMAX NOKIA_N810_WIMAX 1727 +insight MACH_INSIGHT INSIGHT 1728 +sapphire MACH_SAPPHIRE SAPPHIRE 1729 +csb637xo MACH_CSB637XO CSB637XO 1730 +evisiong MACH_EVISIONG EVISIONG 1731 +stmp37xx MACH_STMP37XX STMP37XX 1732 +stmp378x MACH_STMP38XX STMP38XX 1733 +tnt MACH_TNT TNT 1734 +tbxt MACH_TBXT TBXT 1735 +playmate MACH_PLAYMATE PLAYMATE 1736 +pns10 MACH_PNS10 PNS10 1737 +eznavi MACH_EZNAVI EZNAVI 1738 +ps4000 MACH_PS4000 PS4000 1739 +ezx_a780 MACH_EZX_A780 EZX_A780 1740 +ezx_e680 MACH_EZX_E680 EZX_E680 1741 +ezx_a1200 MACH_EZX_A1200 EZX_A1200 1742 +ezx_e6 MACH_EZX_E6 EZX_E6 1743 +ezx_e2 MACH_EZX_E2 EZX_E2 1744 +ezx_a910 MACH_EZX_A910 EZX_A910 1745 +cwmx31 MACH_CWMX31 CWMX31 1746 +sl2312 MACH_SL2312 SL2312 1747 +blenny MACH_BLENNY BLENNY 1748 +ds107 MACH_DS107 DS107 1749 +dsx07 MACH_DSX07 DSX07 1750 +picocom1 MACH_PICOCOM1 PICOCOM1 1751 +lynx_wolverine MACH_LYNX_WOLVERINE LYNX_WOLVERINE 1752 +ubisys_p9_sc19 MACH_UBISYS_P9_SC19 UBISYS_P9_SC19 1753 +kratos_low MACH_KRATOS_LOW KRATOS_LOW 1754 +m700 MACH_M700 M700 1755 +edmini_v2 MACH_EDMINI_V2 EDMINI_V2 1756 +zipit2 MACH_ZIPIT2 ZIPIT2 1757 +hslfemtocell MACH_HSLFEMTOCELL HSLFEMTOCELL 1758 +daintree_at91 MACH_DAINTREE_AT91 DAINTREE_AT91 1759 +sg560usb MACH_SG560USB SG560USB 1760 +omap3_pandora MACH_OMAP3_PANDORA OMAP3_PANDORA 1761 +usr8200 MACH_USR8200 USR8200 1762 +s1s65k MACH_S1S65K S1S65K 1763 +s2s65a MACH_S2S65A S2S65A 1764 +icore MACH_ICORE ICORE 1765 +mss2 MACH_MSS2 MSS2 1766 +belmont MACH_BELMONT BELMONT 1767 +asusp525 MACH_ASUSP525 ASUSP525 1768 +lb88rc8480 MACH_LB88RC8480 LB88RC8480 1769 +hipxa MACH_HIPXA HIPXA 1770 +mx25_3ds MACH_MX25_3DS MX25_3DS 1771 +m800 MACH_M800 M800 1772 +omap3530_lv_som MACH_OMAP3530_LV_SOM OMAP3530_LV_SOM 1773 +prima_evb MACH_PRIMA_EVB PRIMA_EVB 1774 +mx31bt1 MACH_MX31BT1 MX31BT1 1775 +atlas4_evb MACH_ATLAS4_EVB ATLAS4_EVB 1776 +mx31cicada MACH_MX31CICADA MX31CICADA 1777 +mi424wr MACH_MI424WR MI424WR 1778 +axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779 +at572d940deb MACH_AT572D940DEB AT572D940DEB 1780 +davinci_da8xx_evm MACH_DAVINCI_DA8XX_EVM DAVINCI_DA8XX_EVM 1781 +ep9302 MACH_EP9302 EP9302 1782 +at572d940hfeb MACH_AT572D940HFEB AT572D940HFEB 1783 +cybook3 MACH_CYBOOK3 CYBOOK3 1784 +wdg002 MACH_WDG002 WDG002 1785 +sg560adsl MACH_SG560ADSL SG560ADSL 1786 +nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787 +marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789 +vandihud MACH_VANDIHUD VANDIHUD 1790 +magx_e8 MACH_MAGX_E8 MAGX_E8 1791 +magx_z6 MACH_MAGX_Z6 MAGX_Z6 1792 +magx_v8 MACH_MAGX_V8 MAGX_V8 1793 +magx_u9 MACH_MAGX_U9 MAGX_U9 1794 +toughcf08 MACH_TOUGHCF08 TOUGHCF08 1795 +zw4400 MACH_ZW4400 ZW4400 1796 +marat91 MACH_MARAT91 MARAT91 1797 +overo MACH_OVERO OVERO 1798 +at2440evb MACH_AT2440EVB AT2440EVB 1799 +neocore926 MACH_NEOCORE926 NEOCORE926 1800 +wnr854t MACH_WNR854T WNR854T 1801 +imx27 MACH_IMX27 IMX27 1802 +moose_db MACH_MOOSE_DB MOOSE_DB 1803 +fab4 MACH_FAB4 FAB4 1804 +htcdiamond MACH_HTCDIAMOND HTCDIAMOND 1805 +fiona MACH_FIONA FIONA 1806 +mxc30030_x MACH_MXC30030_X MXC30030_X 1807 +bmp1000 MACH_BMP1000 BMP1000 1808 +logi9200 MACH_LOGI9200 LOGI9200 1809 +tqma31 MACH_TQMA31 TQMA31 1810 +ccw9p9215js MACH_CCW9P9215JS CCW9P9215JS 1811 +rd88f5181l_ge MACH_RD88F5181L_GE RD88F5181L_GE 1812 +sifmain MACH_SIFMAIN SIFMAIN 1813 +sam9_l9261 MACH_SAM9_L9261 SAM9_L9261 1814 +cc9m2443js MACH_CC9M2443JS CC9M2443JS 1815 +xaria300 MACH_XARIA300 XARIA300 1816 +it9200 MACH_IT9200 IT9200 1817 +rd88f5181l_fxo MACH_RD88F5181L_FXO RD88F5181L_FXO 1818 +kriss_sensor MACH_KRISS_SENSOR KRISS_SENSOR 1819 +pilz_pmi5 MACH_PILZ_PMI5 PILZ_PMI5 1820 +jade MACH_JADE JADE 1821 +ks8695_softplc MACH_KS8695_SOFTPLC KS8695_SOFTPLC 1822 +gprisc4 MACH_GPRISC4 GPRISC4 1823 +stamp9260 MACH_STAMP9260 STAMP9260 1824 -- cgit v0.10.2 From 4ab9897172b7ff3a1a37b65b53f71c5795a577b0 Mon Sep 17 00:00:00 2001 From: Ramax Lo Date: Mon, 7 Jul 2008 18:12:36 +0100 Subject: [ARM] S3C2440: Add AT2440EVB board support Add basic support for AT2440EVB board based on Samsung S3C2440 SoC. Signed-off-by: Ben Dooks Signed-off-by: Ramax Lo diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index dcaa4db..25de042 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -68,6 +68,11 @@ config SMDK2440_CPU2440 default y if ARCH_S3C2440 select CPU_S3C2440 +config MACH_AT2440EVB + bool "Avantech AT2440EVB development board" + select CPU_S3C2440 + help + Say Y here if you are using the AT2440EVB development board endmenu diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile index c81ed62..0b4440e 100644 --- a/arch/arm/mach-s3c2440/Makefile +++ b/arch/arm/mach-s3c2440/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o +obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c new file mode 100644 index 0000000..99f6605 --- /dev/null +++ b/arch/arm/mach-s3c2440/mach-at2440evb.c @@ -0,0 +1,162 @@ +/* linux/arch/arm/mach-s3c2440/mach-at2440evb.c + * + * Copyright (c) 2008 Ramax Lo + * Based on mach-anubis.c by Ben Dooks + * and modifications by SBZ and + * Weibing + * + * For product information, visit http://www.arm9e.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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +static struct map_desc at2440evb_iodesc[] __initdata = { + /* Nothing here */ +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) +#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) + +static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = { + [0] = { + .name = "uclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "pclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + } +}; + + +static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = at2440evb_serial_clocks, + .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks), + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = at2440evb_serial_clocks, + .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks), + }, +}; + +/* NAND Flash on AT2440EVB board */ + +static struct mtd_partition at2440evb_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_256K, + .offset = 0, + }, + [1] = { + .name = "Kernel", + .size = SZ_2M, + .offset = SZ_256K, + }, + [2] = { + .name = "Root", + .offset = SZ_256K + SZ_2M, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct s3c2410_nand_set at2440evb_nand_sets[] = { + [0] = { + .name = "nand", + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(at2440evb_default_nand_part), + .partitions = at2440evb_default_nand_part, + }, +}; + +static struct s3c2410_platform_nand at2440evb_nand_info = { + .tacls = 25, + .twrph0 = 55, + .twrph1 = 40, + .nr_sets = ARRAY_SIZE(at2440evb_nand_sets), + .sets = at2440evb_nand_sets, +}; + +static struct platform_device *at2440evb_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_wdt, + &s3c_device_adc, + &s3c_device_i2c, + &s3c_device_rtc, + &s3c_device_nand, +}; + +static void __init at2440evb_map_io(void) +{ + s3c_device_nand.dev.platform_data = &at2440evb_nand_info; + + s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); + s3c24xx_init_clocks(16934400); + s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); +} + +static void __init at2440evb_init(void) +{ + platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices)); +} + + +MACHINE_START(AT2440EVB, "AT2440EVB") + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = at2440evb_map_io, + .init_machine = at2440evb_init, + .init_irq = s3c24xx_init_irq, + .timer = &s3c24xx_timer, +MACHINE_END -- cgit v0.10.2 From 66493c2d88d5086399c5a485d6e41cb76b241a1f Mon Sep 17 00:00:00 2001 From: Ramax Lo Date: Mon, 7 Jul 2008 18:12:37 +0100 Subject: [ARM] AT2440EVB: Add DM9000A network controller support. Add DM9000AEP network controller support for AT2440EVB. Signed-off-by: Ramax Lo Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c index 99f6605..f5e3c7f 100644 --- a/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/arch/arm/mach-s3c2440/mach-at2440evb.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -127,6 +128,40 @@ static struct s3c2410_platform_nand at2440evb_nand_info = { .sets = at2440evb_nand_sets, }; +/* DM9000AEP 10/100 ethernet controller */ + +static struct resource at2440evb_dm9k_resource[] = { + [0] = { + .start = S3C2410_CS3, + .end = S3C2410_CS3 + 3, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = S3C2410_CS3 + 4, + .end = S3C2410_CS3 + 7, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = IRQ_EINT7, + .end = IRQ_EINT7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct dm9000_plat_data at2440evb_dm9k_pdata = { + .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), +}; + +static struct platform_device at2440evb_device_eth = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(at2440evb_dm9k_resource), + .resource = at2440evb_dm9k_resource, + .dev = { + .platform_data = &at2440evb_dm9k_pdata, + }, +}; + static struct platform_device *at2440evb_devices[] __initdata = { &s3c_device_usb, &s3c_device_wdt, @@ -134,6 +169,7 @@ static struct platform_device *at2440evb_devices[] __initdata = { &s3c_device_i2c, &s3c_device_rtc, &s3c_device_nand, + &at2440evb_device_eth, }; static void __init at2440evb_map_io(void) -- cgit v0.10.2 From 29a7bcfd144a577b5cdb3b735c58e20d0489b30e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:38 +0100 Subject: [ARM] S3C2443: Fix s3c2443_clkcon_enable_p() using wrong register. s3c2443_clkcon_enable_p() was reading from the correct register S3C2443_PCLKCON, but then writing the value back to the wrong register S3C2443_HCLKCON. Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index b42f956..24da9241 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -81,7 +81,7 @@ static int s3c2443_clkcon_enable_p(struct clk *clk, int enable) else clkcon &= ~clocks; - __raw_writel(clkcon, S3C2443_HCLKCON); + __raw_writel(clkcon, S3C2443_PCLKCON); return 0; } -- cgit v0.10.2 From ba7622a19fabb853b8bbb918a5d76557f88e4274 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:39 +0100 Subject: [ARM] S3C2443: Add armdiv and arm clocks Add the armdiv and arm clocks to the S3C2443 clock framework and ensure they are correctly setup. Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 24da9241..d34f3d3 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -221,7 +221,6 @@ static struct clk clk_mdivclk = { .get_rate = s3c2443_getrate_mdivclk, }; - static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) { unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); @@ -249,6 +248,46 @@ static struct clk clk_msysclk = { .set_parent = s3c2443_setparent_msysclk, }; +/* armdiv + * + * this clock is sourced from msysclk and can have a number of + * divider values applied to it to then be fed into armclk. +*/ + +static struct clk clk_armdiv = { + .name = "armdiv", + .id = -1, + .parent = &clk_msysclk, +}; + +/* armclk + * + * this is the clock fed into the ARM core itself, either from + * armdiv or from hclk. + */ + +static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent) +{ + unsigned long clkdiv0; + + clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + if (parent == &clk_armdiv) + clkdiv0 &= ~S3C2443_CLKDIV0_DVS; + else if (parent == &clk_h) + clkdiv0 |= S3C2443_CLKDIV0_DVS; + else + return -EINVAL; + + __raw_writel(clkdiv0, S3C2443_CLKDIV0); + return 0; +} + +static struct clk clk_arm = { + .name = "armclk", + .id = -1, + .set_parent = s3c2443_setparent_armclk, +}; /* esysclk * @@ -887,6 +926,15 @@ static void __init s3c2443_clk_initparents(void) } clk_init_set_parent(&clk_msysclk, parent); + + /* arm */ + + if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS) + parent = &clk_h; + else + parent = &clk_armdiv; + + clk_init_set_parent(&clk_arm, parent); } /* armdiv divisor table */ @@ -936,6 +984,8 @@ static struct clk *clks[] __initdata = { &clk_hsspi, &clk_hsmmc_div, &clk_hsmmc, + &clk_armdiv, + &clk_arm, }; void __init s3c2443_init_clocks(int xtal) @@ -958,6 +1008,8 @@ void __init s3c2443_init_clocks(int xtal) hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); + clk_armdiv.rate = fclk; + s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", -- cgit v0.10.2 From 2e16c27aa379793c354012e5fae0aae89103b19b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:40 +0100 Subject: [ARM] S3C2443: Add prediv clk and fix setting of h and p clocks Update the S3C2443 clock support to add the prediv clock that is sourced via a divider from msysclk. Also fix the setting of p and h clocks from this prediv clock. Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index d34f3d3..17f064f 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -678,6 +678,29 @@ static struct clk clk_display = { .round_rate = s3c2443_roundrate_clksrc256, }; +/* prediv + * + * this divides the msysclk down to pass to h/p/etc. + */ + +static unsigned long s3c2443_prediv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK; + clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT; + + return rate / (clkdiv0 + 1); +} + +static struct clk clk_prediv = { + .name = "prediv", + .id = -1, + .parent = &clk_msysclk, + .get_rate = s3c2443_prediv_getrate, +}; + /* standard clock definitions */ static struct clk init_clocks_disable[] = { @@ -957,10 +980,9 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0) return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; } -static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0) +static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) { - clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK; - clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT; + clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; return clkcon0 + 1; } @@ -986,6 +1008,7 @@ static struct clk *clks[] __initdata = { &clk_hsmmc, &clk_armdiv, &clk_arm, + &clk_prediv, }; void __init s3c2443_init_clocks(int xtal) @@ -1001,15 +1024,19 @@ void __init s3c2443_init_clocks(int xtal) int ret; int ptr; + /* s3c2443 parents h and p clocks from prediv */ + clk_h.parent = &clk_prediv; + clk_p.parent = &clk_prediv; + pll = s3c2443_get_mpll(mpllcon, xtal); + clk_msysclk.rate = pll; fclk = pll / s3c2443_fclk_div(clkdiv0); - hclk = fclk / s3c2443_get_prediv(clkdiv0); + hclk = s3c2443_prediv_getrate(&clk_prediv); + hclk = hclk / s3c2443_get_hdiv(clkdiv0); hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); - clk_armdiv.rate = fclk; - s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", -- cgit v0.10.2 From 196a047574e1465b89bc41fda573efc9b9be70e5 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:41 +0100 Subject: [ARM] Acer n30: Source file cleanups. Clean up some junk from the official kernel. The compile-command is something that's only useful for me personally and doesn't belong in the mainstream kernel. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 621f548..fc54e07 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-s3c2410/mach-n30.c +/* Machine specific code for the Acer n30 PDA. * * Copyright (c) 2003-2005 Simtec Electronics * Ben Dooks * - * Copyright (c) 2005 Christer Weinigel + * Copyright (c) 2005-2008 Christer Weinigel * * There is a wiki with more information about the n30 port at * http://handhelds.org/moin/moin.cgi/AcerN30Documentation . @@ -15,32 +15,32 @@ #include #include -#include -#include -#include -#include + #include -#include +#include +#include #include -#include - -#include -#include -#include +#include +#include #include #include #include #include -#include #include + +#include +#include +#include + #include +#include -#include #include -#include #include +#include +#include static struct map_desc n30_iodesc[] __initdata = { /* nothing here yet */ @@ -75,11 +75,11 @@ static struct s3c2410_uartcfg n30_uartcfgs[] = { }; static struct platform_device *n30_devices[] __initdata = { - &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c, &s3c_device_iis, + &s3c_device_usb, &s3c_device_usbgadget, }; @@ -130,10 +130,3 @@ MACHINE_START(N30, "Acer-N30") .init_irq = n30_init_irq, .map_io = n30_map_io, MACHINE_END - -/* - Local variables: - compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.." - c-basic-offset: 8 - End: -*/ -- cgit v0.10.2 From d088e5fe586287da003341e7bbfdad15e0f432f7 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:42 +0100 Subject: [ARM] Acer n30: USB bus pull-up support. Add support for the USB D+ pull up on the Acer N30. This is needed for the USB gadget to work properly. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index fc54e07..8edc0c0 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -41,6 +41,7 @@ #include #include #include +#include static struct map_desc n30_iodesc[] __initdata = { /* nothing here yet */ @@ -74,6 +75,29 @@ static struct s3c2410_uartcfg n30_uartcfgs[] = { }, }; +static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd) +{ + switch (cmd) + { + case S3C2410_UDC_P_ENABLE : + s3c2410_gpio_setpin(S3C2410_GPB3, 1); + break; + case S3C2410_UDC_P_DISABLE : + s3c2410_gpio_setpin(S3C2410_GPB3, 0); + break; + case S3C2410_UDC_P_RESET : + break; + default: + break; + } +} + +static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = { + .udc_command = n30_udc_pullup, + .vbus_pin = S3C2410_GPG1, + .vbus_pin_inverted = 0, +}; + static struct platform_device *n30_devices[] __initdata = { &s3c_device_lcd, &s3c_device_wdt, @@ -107,6 +131,7 @@ static void __init n30_init_irq(void) static void __init n30_init(void) { s3c_device_i2c.dev.platform_data = &n30_i2ccfg; + s3c24xx_udc_set_platdata(&n30_udc_cfg); /* Turn off suspend on both USB ports, and switch the * selectable USB port to USB device mode. */ -- cgit v0.10.2 From 620657500263cca4a4d9845eeaeba47e03447075 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:43 +0100 Subject: [ARM] Acer n30: GPIO buttons support Add support for the GPIO buttons on the Acer N30. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 8edc0c0..631f3a9 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -17,7 +17,9 @@ #include #include +#include #include +#include #include #include #include @@ -98,6 +100,70 @@ static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = { .vbus_pin_inverted = 0, }; +static struct gpio_keys_button n30_buttons[] = { + { + .gpio = S3C2410_GPF0, + .code = KEY_POWER, + .desc = "Power", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG9, + .code = KEY_UP, + .desc = "Thumbwheel Up", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG8, + .code = KEY_DOWN, + .desc = "Thumbwheel Down", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG7, + .code = KEY_ENTER, + .desc = "Thumbwheel Press", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF7, + .code = KEY_HOMEPAGE, + .desc = "Home", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF6, + .code = KEY_CALENDAR, + .desc = "Calendar", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF5, + .code = KEY_ADDRESSBOOK, + .desc = "Contacts", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF4, + .code = KEY_MAIL, + .desc = "Mail", + .active_low = 0, + }, +}; + +static struct gpio_keys_platform_data n30_button_data = { + .buttons = n30_buttons, + .nbuttons = ARRAY_SIZE(n30_buttons), +}; + +static struct platform_device n30_button_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &n30_button_data, + } +}; + static struct platform_device *n30_devices[] __initdata = { &s3c_device_lcd, &s3c_device_wdt, @@ -105,6 +171,7 @@ static struct platform_device *n30_devices[] __initdata = { &s3c_device_iis, &s3c_device_usb, &s3c_device_usbgadget, + &n30_button_device, }; static struct s3c2410_platform_i2c n30_i2ccfg = { -- cgit v0.10.2 From 865cc639a636b58612becfb6a337945c022596ac Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:44 +0100 Subject: [ARM] Acer n30: LED support. Add support for the LEDs on the Acer N30. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 631f3a9..e1351a7 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -164,6 +165,40 @@ static struct platform_device n30_button_device = { } }; +/* This is the bluetooth LED on the device. */ +static struct s3c24xx_led_platdata n30_blue_led_pdata = { + .name = "blue_led", + .gpio = S3C2410_GPG6, + .def_trigger = "", +}; + +/* This LED is driven by the battery microcontroller, and is blinking + * red, blinking green or solid green when the battery is low, + * charging or full respectively. By driving GPD9 low, it's possible + * to force the LED to blink red, so call that warning LED. */ +static struct s3c24xx_led_platdata n30_warning_led_pdata = { + .name = "warning_led", + .flags = S3C24XX_LEDF_ACTLOW, + .gpio = S3C2410_GPD9, + .def_trigger = "", +}; + +static struct platform_device n30_blue_led = { + .name = "s3c24xx_led", + .id = 1, + .dev = { + .platform_data = &n30_blue_led_pdata, + }, +}; + +static struct platform_device n30_warning_led = { + .name = "s3c24xx_led", + .id = 2, + .dev = { + .platform_data = &n30_warning_led_pdata, + }, +}; + static struct platform_device *n30_devices[] __initdata = { &s3c_device_lcd, &s3c_device_wdt, @@ -172,6 +207,8 @@ static struct platform_device *n30_devices[] __initdata = { &s3c_device_usb, &s3c_device_usbgadget, &n30_button_device, + &n30_blue_led, + &n30_warning_led, }; static struct s3c2410_platform_i2c n30_i2ccfg = { -- cgit v0.10.2 From 9579087331ee0cd220d29aa5bda79ff55b33c228 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:45 +0100 Subject: [ARM] Acer n30: Add support for n35 and related devices. Add support for the Acer N35 and related devices. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 1a7d01b..99fdc73 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -72,10 +72,11 @@ config PM_H1940 Internal node for H1940 and related PM config MACH_N30 - bool "Acer N30" + bool "Acer N30 family" select CPU_S3C2410 help - Say Y here if you are using the Acer N30 + Say Y here if you want suppt for the Acer N30, Acer N35, + Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index e1351a7..621b343 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -1,4 +1,5 @@ -/* Machine specific code for the Acer n30 PDA. +/* Machine specific code for the Acer n30, Acer N35, Navman PiN 570, + * Yakumo AlphaX and Airis NC05 PDAs. * * Copyright (c) 2003-2005 Simtec Electronics * Ben Dooks @@ -11,7 +12,7 @@ * 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 #include @@ -68,7 +69,8 @@ static struct s3c2410_uartcfg n30_uartcfgs[] = { .ulcon = 0x43, .ufcon = 0x51, }, - /* The BlueTooth controller is connected to port 2 */ + /* On the N30 the bluetooth controller is connected here. + * On the N35 and variants the GPS receiver is connected here. */ [2] = { .hwport = 2, .flags = 0, @@ -165,6 +167,95 @@ static struct platform_device n30_button_device = { } }; +static struct gpio_keys_button n35_buttons[] = { + { + .gpio = S3C2410_GPF0, + .code = KEY_POWER, + .desc = "Power", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG9, + .code = KEY_UP, + .desc = "Joystick Up", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG8, + .code = KEY_DOWN, + .desc = "Joystick Down", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG6, + .code = KEY_DOWN, + .desc = "Joystick Left", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG5, + .code = KEY_DOWN, + .desc = "Joystick Right", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG7, + .code = KEY_ENTER, + .desc = "Joystick Press", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF7, + .code = KEY_HOMEPAGE, + .desc = "Home", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF6, + .code = KEY_CALENDAR, + .desc = "Calendar", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF5, + .code = KEY_ADDRESSBOOK, + .desc = "Contacts", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF4, + .code = KEY_MAIL, + .desc = "Mail", + .active_low = 0, + }, + { + .gpio = S3C2410_GPF3, + .code = SW_RADIO, + .desc = "GPS Antenna", + .active_low = 0, + }, + { + .gpio = S3C2410_GPG2, + .code = SW_HEADPHONE_INSERT, + .desc = "Headphone", + .active_low = 0, + }, +}; + +static struct gpio_keys_platform_data n35_button_data = { + .buttons = n35_buttons, + .nbuttons = ARRAY_SIZE(n35_buttons), +}; + +static struct platform_device n35_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &n35_button_data, + } +}; + /* This is the bluetooth LED on the device. */ static struct s3c24xx_led_platdata n30_blue_led_pdata = { .name = "blue_led", @@ -211,6 +302,15 @@ static struct platform_device *n30_devices[] __initdata = { &n30_warning_led, }; +static struct platform_device *n35_devices[] __initdata = { + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &s3c_device_usbgadget, + &n35_button_device, +}; + static struct s3c2410_platform_i2c n30_i2ccfg = { .flags = 0, .slave_addr = 0x10, @@ -244,7 +344,32 @@ static void __init n30_init(void) S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1, 0x0); - platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices)); + if (machine_is_n30()) { + /* Turn off suspend on both USB ports, and switch the + * selectable USB port to USB device mode. */ + s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | + S3C2410_MISCCR_USBSUSPND0 | + S3C2410_MISCCR_USBSUSPND1, 0x0); + + platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices)); + } + + if (machine_is_n35()) { + /* Turn off suspend and switch the selectable USB port + * to USB device mode. Turn on suspend for the host + * port since it is not connected on the N35. + * + * Actually, the host port is available at some pads + * on the back of the device, so it would actually be + * possible to add a USB device inside the N35 if you + * are willing to do some hardware modifications. */ + s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | + S3C2410_MISCCR_USBSUSPND0 | + S3C2410_MISCCR_USBSUSPND1, + S3C2410_MISCCR_USBSUSPND1); + + platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices)); + } } MACHINE_START(N30, "Acer-N30") @@ -259,3 +384,15 @@ MACHINE_START(N30, "Acer-N30") .init_irq = n30_init_irq, .map_io = n30_map_io, MACHINE_END + +MACHINE_START(N35, "Acer-N35") + /* Maintainer: Christer Weinigel + */ + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .timer = &s3c24xx_timer, + .init_machine = n30_init, + .init_irq = n30_init_irq, + .map_io = n30_map_io, +MACHINE_END -- cgit v0.10.2 From e43f238390168a13416d4f21803f76b1ff45fb95 Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:46 +0100 Subject: [ARM] Acer n30: LCD support. This patch adds the configuration needed for the LCD display on the n30. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 621b343..476b15c 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -31,8 +31,10 @@ #include #include +#include #include #include +#include #include #include @@ -290,6 +292,31 @@ static struct platform_device n30_warning_led = { }, }; +static struct s3c2410fb_display n30_display __initdata = { + .type = S3C2410_LCDCON1_TFT, + .width = 240, + .height = 320, + .pixclock = 170000, + .xres = 240, + .yres = 320, + .bpp = 16, + .left_margin = 3, + .right_margin = 40, + .hsync_len = 40, + .upper_margin = 2, + .lower_margin = 3, + .vsync_len = 2, + + .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME, +}; + +static struct s3c2410fb_mach_info n30_fb_info __initdata = { + .displays = &n30_display, + .num_displays = 1, + .default_display = 0, + .lpcsel= 0x06, +}; + static struct platform_device *n30_devices[] __initdata = { &s3c_device_lcd, &s3c_device_wdt, @@ -334,6 +361,7 @@ static void __init n30_init_irq(void) static void __init n30_init(void) { + s3c24xx_fb_set_platdata(&n30_fb_info); s3c_device_i2c.dev.platform_data = &n30_i2ccfg; s3c24xx_udc_set_platdata(&n30_udc_cfg); -- cgit v0.10.2 From 9a2ddb7866c2887352e85c6443dfb5e679140aff Mon Sep 17 00:00:00 2001 From: Christer Weinigel Date: Mon, 7 Jul 2008 18:12:47 +0100 Subject: [ARM] Acer n30: Hardware initialisation. Initialise the hardware register settings on boot, to allow the device to function correctly. Signed-off-by: Christer Weinigel Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 476b15c..450d108 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -345,9 +345,148 @@ static struct s3c2410_platform_i2c n30_i2ccfg = { .max_freq = 10*1000, }; +/* Lots of hardcoded stuff, but it sets up the hardware in a useful + * state so that we can boot Linux directly from flash. */ +static void __init n30_hwinit(void) +{ + /* GPA0-11 special functions -- unknown what they do + * GPA12 N30 special function -- unknown what it does + * N35/PiN output -- unknown what it does + * + * A12 is nGCS1 on the N30 and an output on the N35/PiN. I + * don't think it does anything useful on the N30, so I ought + * to make it an output there too since it always driven to 0 + * as far as I can tell. */ + if (machine_is_n30()) + __raw_writel(0x007fffff, S3C2410_GPACON); + if (machine_is_n35()) + __raw_writel(0x007fefff, S3C2410_GPACON); + __raw_writel(0x00000000, S3C2410_GPADAT); + + /* GPB0 TOUT0 backlight level + * GPB1 output 1=backlight on + * GPB2 output IrDA enable 0=transceiver enabled, 1=disabled + * GPB3 output USB D+ pull up 0=disabled, 1=enabled + * GPB4 N30 output -- unknown function + * N30/PiN GPS control 0=GPS enabled, 1=GPS disabled + * GPB5 output -- unknown function + * GPB6 input -- unknown function + * GPB7 output -- unknown function + * GPB8 output -- probably LCD driver enable + * GPB9 output -- probably LCD VSYNC driver enable + * GPB10 output -- probably LCD HSYNC driver enable + */ + __raw_writel(0x00154556, S3C2410_GPBCON); + __raw_writel(0x00000750, S3C2410_GPBDAT); + __raw_writel(0x00000073, S3C2410_GPBUP); + + /* GPC0 input RS232 DCD/DSR/RI + * GPC1 LCD + * GPC2 output RS232 DTR? + * GPC3 input RS232 DCD/DSR/RI + * GPC4 LCD + * GPC5 output 0=NAND write enabled, 1=NAND write protect + * GPC6 input -- unknown function + * GPC7 input charger status 0=charger connected + * this input can be triggered by power on the USB device + * port too, but will go back to disconnected soon after. + * GPC8 N30/N35 output -- unknown function, always driven to 1 + * PiN input -- unknown function, always read as 1 + * Make it an input with a pull up for all models. + * GPC9-15 LCD + */ + __raw_writel(0xaaa80618, S3C2410_GPCCON); + __raw_writel(0x0000014c, S3C2410_GPCDAT); + __raw_writel(0x0000fef2, S3C2410_GPCUP); + + /* GPD0 input -- unknown function + * GPD1-D7 LCD + * GPD8 N30 output -- unknown function + * N35/PiN output 1=GPS LED on + * GPD9 output 0=power led blinks red, 1=normal power led function + * GPD10 output -- unknown function + * GPD11-15 LCD drivers + */ + __raw_writel(0xaa95aaa4, S3C2410_GPDCON); + __raw_writel(0x00000601, S3C2410_GPDDAT); + __raw_writel(0x0000fbfe, S3C2410_GPDUP); + + /* GPE0-4 I2S audio bus + * GPE5-10 SD/MMC bus + * E11-13 outputs -- unknown function, probably power management + * E14-15 I2C bus connected to the battery controller + */ + __raw_writel(0xa56aaaaa, S3C2410_GPECON); + __raw_writel(0x0000efc5, S3C2410_GPEDAT); + __raw_writel(0x0000f81f, S3C2410_GPEUP); + + /* GPF0 input 0=power button pressed + * GPF1 input SD/MMC switch 0=card present + * GPF2 N30 1=reset button pressed (inverted compared to the rest) + * N35/PiN 0=reset button pressed + * GPF3 N30/PiN input -- unknown function + * N35 input GPS antenna position, 0=antenna closed, 1=open + * GPF4 input 0=button 4 pressed + * GPF5 input 0=button 3 pressed + * GPF6 input 0=button 2 pressed + * GPF7 input 0=button 1 pressed + */ + __raw_writel(0x0000aaaa, S3C2410_GPFCON); + __raw_writel(0x00000000, S3C2410_GPFDAT); + __raw_writel(0x000000ff, S3C2410_GPFUP); + + /* GPG0 input RS232 DCD/DSR/RI + * GPG1 input 1=USB gadget port has power from a host + * GPG2 N30 input -- unknown function + * N35/PiN input 0=headphones plugged in, 1=not plugged in + * GPG3 N30 output -- unknown function + * N35/PiN input with unknown function + * GPG4 N30 output 0=MMC enabled, 1=MMC disabled + * GPG5 N30 output 0=BlueTooth chip disabled, 1=enabled + * N35/PiN input joystick right + * GPG6 N30 output 0=blue led on, 1=off + * N35/PiN input joystick left + * GPG7 input 0=thumbwheel pressed + * GPG8 input 0=thumbwheel down + * GPG9 input 0=thumbwheel up + * GPG10 input SD/MMC write protect switch + * GPG11 N30 input -- unknown function + * N35 output 0=GPS antenna powered, 1=not powered + * PiN output -- unknown function + * GPG12-15 touch screen functions + * + * The pullups differ between the models, so enable all + * pullups that are enabled on any of the models. + */ + if (machine_is_n30()) + __raw_writel(0xff0a956a, S3C2410_GPGCON); + if (machine_is_n35()) + __raw_writel(0xff4aa92a, S3C2410_GPGCON); + __raw_writel(0x0000e800, S3C2410_GPGDAT); + __raw_writel(0x0000f86f, S3C2410_GPGUP); + + /* GPH0/1/2/3 RS232 serial port + * GPH4/5 IrDA serial port + * GPH6/7 N30 BlueTooth serial port + * N35/PiN GPS receiver + * GPH8 input -- unknown function + * GPH9 CLKOUT0 HCLK -- unknown use + * GPH10 CLKOUT1 FCLK -- unknown use + * + * The pull ups for H6/H7 are enabled on N30 but not on the + * N35/PiN. I suppose is useful for a budget model of the N30 + * with no bluetooh. It doesn't hurt to have the pull ups + * enabled on the N35, so leave them enabled for all models. + */ + __raw_writel(0x0028aaaa, S3C2410_GPHCON); + __raw_writel(0x000005ef, S3C2410_GPHDAT); + __raw_writel(0x0000063f, S3C2410_GPHUP); +} + static void __init n30_map_io(void) { s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc)); + n30_hwinit(); s3c24xx_init_clocks(0); s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); } -- cgit v0.10.2 From a67557801aeda1f9f19e4606a00c948f6054417c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:48 +0100 Subject: [ARM] Acer n30: Minor style and indentation fixes. Minor style fixes. Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 450d108..43c2e91 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -84,18 +84,17 @@ static struct s3c2410_uartcfg n30_uartcfgs[] = { static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd) { - switch (cmd) - { - case S3C2410_UDC_P_ENABLE : - s3c2410_gpio_setpin(S3C2410_GPB3, 1); - break; - case S3C2410_UDC_P_DISABLE : - s3c2410_gpio_setpin(S3C2410_GPB3, 0); - break; - case S3C2410_UDC_P_RESET : - break; - default: - break; + switch (cmd) { + case S3C2410_UDC_P_ENABLE : + s3c2410_gpio_setpin(S3C2410_GPB3, 1); + break; + case S3C2410_UDC_P_DISABLE : + s3c2410_gpio_setpin(S3C2410_GPB3, 0); + break; + case S3C2410_UDC_P_RESET : + break; + default: + break; } } @@ -293,28 +292,29 @@ static struct platform_device n30_warning_led = { }; static struct s3c2410fb_display n30_display __initdata = { - .type = S3C2410_LCDCON1_TFT, - .width = 240, - .height = 320, - .pixclock = 170000, - .xres = 240, - .yres = 320, - .bpp = 16, - .left_margin = 3, - .right_margin = 40, - .hsync_len = 40, - .upper_margin = 2, - .lower_margin = 3, - .vsync_len = 2, + .type = S3C2410_LCDCON1_TFT, + .width = 240, + .height = 320, + .pixclock = 170000, + + .xres = 240, + .yres = 320, + .bpp = 16, + .left_margin = 3, + .right_margin = 40, + .hsync_len = 40, + .upper_margin = 2, + .lower_margin = 3, + .vsync_len = 2, .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME, }; static struct s3c2410fb_mach_info n30_fb_info __initdata = { - .displays = &n30_display, - .num_displays = 1, + .displays = &n30_display, + .num_displays = 1, .default_display = 0, - .lpcsel= 0x06, + .lpcsel = 0x06, }; static struct platform_device *n30_devices[] __initdata = { -- cgit v0.10.2 From 7ba06b17a1931b2c9e1bee525a8c36920f5be0e0 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 Jul 2008 18:12:49 +0100 Subject: [ARM] s3c2410_defconfig: update for current build Update the s3c2410_defconfig for the current set of added patches. Signed-off-by: Ben Dooks diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 1a0434b..3796397 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.26-rc8 -# Thu Jul 3 11:48:41 2008 +# Mon Jul 7 16:59:23 2008 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -12,7 +12,6 @@ CONFIG_MMU=y CONFIG_NO_IOPORT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_HARDIRQS_SW_RESEND=y @@ -24,7 +23,6 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ZONE_DMA=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -133,6 +131,7 @@ CONFIG_CLASSIC_RCU=y # CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set @@ -146,11 +145,8 @@ CONFIG_CLASSIC_RCU=y # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_KIRKWOOD is not set # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set # CONFIG_ARCH_MXC is not set # CONFIG_ARCH_ORION5X is not set # CONFIG_ARCH_PNX4008 is not set @@ -165,6 +161,7 @@ CONFIG_ARCH_S3C2410=y # CONFIG_ARCH_MSM7X00A is not set CONFIG_PLAT_S3C24XX=y CONFIG_CPU_S3C244X=y +# CONFIG_S3C24XX_PWM is not set CONFIG_PM_SIMTEC=y CONFIG_S3C2410_DMA=y # CONFIG_S3C2410_DMA_DEBUG is not set @@ -194,6 +191,8 @@ CONFIG_CPU_S3C2410_DMA=y CONFIG_S3C2410_PM=y CONFIG_S3C2410_GPIO=y CONFIG_S3C2410_CLOCK=y +CONFIG_SIMTEC_NOR=y +CONFIG_MACH_BAST_IDE=y # # S3C2410 Machines @@ -216,6 +215,7 @@ CONFIG_S3C2412_PM=y # # S3C2412 Machines # +# CONFIG_MACH_JIVE is not set CONFIG_MACH_SMDK2413=y CONFIG_MACH_S3C2413=y # CONFIG_MACH_SMDK2412 is not set @@ -232,6 +232,7 @@ CONFIG_MACH_RX3715=y CONFIG_ARCH_S3C2440=y CONFIG_MACH_NEXCODER_2440=y CONFIG_SMDK2440_CPU2440=y +# CONFIG_MACH_AT2440EVB is not set CONFIG_CPU_S3C2442=y # @@ -712,6 +713,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_ATA is not set +CONFIG_HAVE_PATA_PLATFORM=y # CONFIG_MD is not set CONFIG_NETDEVICES=y # CONFIG_NETDEVICES_MULTIQUEUE is not set @@ -926,6 +928,7 @@ CONFIG_SENSORS_EEPROM=m # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_TPS65010 is not set # CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set @@ -951,6 +954,23 @@ CONFIG_SPI_S3C24XX_GPIO=m # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# +# CONFIG_DEBUG_GPIO is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y @@ -1036,6 +1056,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501=y # CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set # @@ -1552,7 +1573,6 @@ CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set # CONFIG_SAMPLES is not set CONFIG_DEBUG_USER=y CONFIG_DEBUG_ERRORS=y -- cgit v0.10.2 From 2f8209788d774c66efb5e2991affc06b1d1c7314 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Thu, 26 Jun 2008 01:30:41 +0200 Subject: [ARM] Orion: add Netgear WNR854T support Signed-off-by: Imre Kaloz Signed-off-by: Lennert Buytenhek diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index f8b91ea..99b35b7 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -74,6 +74,12 @@ config MACH_MSS2 Say 'Y' here if you want your kernel to support the Maxtor Shared Storage II platform. +config MACH_WNR854T + bool "Netgear WNR854T" + help + Say 'Y' here if you want your kernel to support the + Netgear WNR854T platform. + endmenu endif diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index 65b2fc6..26a62ed 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o obj-$(CONFIG_MACH_MSS2) += mss2-setup.o +obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c new file mode 100644 index 0000000..1af093f --- /dev/null +++ b/arch/arm/mach-orion5x/wnr854t-setup.c @@ -0,0 +1,164 @@ +/* + * arch/arm/mach-orion5x/wnr854t-setup.c + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct orion5x_mpp_mode wnr854t_mpp_modes[] __initdata = { + { 0, MPP_GPIO }, /* Power LED green (0=on) */ + { 1, MPP_GPIO }, /* Reset Button (0=off) */ + { 2, MPP_GPIO }, /* Power LED blink (0=off) */ + { 3, MPP_GPIO }, /* WAN Status LED amber (0=off) */ + { 4, MPP_GPIO }, /* PCI int */ + { 5, MPP_GPIO }, /* ??? */ + { 6, MPP_GPIO }, /* ??? */ + { 7, MPP_GPIO }, /* ??? */ + { 8, MPP_UNUSED }, /* ??? */ + { 9, MPP_GIGE }, /* GE_RXERR */ + { 10, MPP_UNUSED }, /* ??? */ + { 11, MPP_UNUSED }, /* ??? */ + { 12, MPP_GIGE }, /* GE_TXD[4] */ + { 13, MPP_GIGE }, /* GE_TXD[5] */ + { 14, MPP_GIGE }, /* GE_TXD[6] */ + { 15, MPP_GIGE }, /* GE_TXD[7] */ + { 16, MPP_GIGE }, /* GE_RXD[4] */ + { 17, MPP_GIGE }, /* GE_RXD[5] */ + { 18, MPP_GIGE }, /* GE_RXD[6] */ + { 19, MPP_GIGE }, /* GE_RXD[7] */ + { -1 }, +}; + +/* + * 8M NOR flash Device bus boot chip select + */ +#define WNR854T_NOR_BOOT_BASE 0xf4000000 +#define WNR854T_NOR_BOOT_SIZE SZ_8M + +static struct mtd_partition wnr854t_nor_flash_partitions[] = { + { + .name = "kernel", + .offset = 0x00000000, + .size = 0x00100000, + }, { + .name = "rootfs", + .offset = 0x00100000, + .size = 0x00660000, + }, { + .name = "uboot", + .offset = 0x00760000, + .size = 0x00040000, + }, +}; + +static struct physmap_flash_data wnr854t_nor_flash_data = { + .width = 2, + .parts = wnr854t_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(wnr854t_nor_flash_partitions), +}; + +static struct resource wnr854t_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = WNR854T_NOR_BOOT_BASE, + .end = WNR854T_NOR_BOOT_BASE + WNR854T_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device wnr854t_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &wnr854t_nor_flash_data, + }, + .num_resources = 1, + .resource = &wnr854t_nor_flash_resource, +}; + +static struct mv643xx_eth_platform_data wnr854t_eth_data = { + .phy_addr = -1, +}; + +static void __init wnr854t_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(wnr854t_mpp_modes); + + /* + * Configure peripherals. + */ + orion5x_eth_init(&wnr854t_eth_data); + orion5x_uart0_init(); + + orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE, + WNR854T_NOR_BOOT_SIZE); + platform_device_register(&wnr854t_nor_flash); +} + +static int __init wnr854t_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + /* + * Check for devices with hard-wired IRQs. + */ + irq = orion5x_pci_map_irq(dev, slot, pin); + if (irq != -1) + return irq; + + /* + * Mini-PCI slot. + */ + if (slot == 7) + return gpio_to_irq(4); + + return -1; +} + +static struct hw_pci wnr854t_pci __initdata = { + .nr_controllers = 2, + .swizzle = pci_std_swizzle, + .setup = orion5x_pci_sys_setup, + .scan = orion5x_pci_sys_scan_bus, + .map_irq = wnr854t_pci_map_irq, +}; + +static int __init wnr854t_pci_init(void) +{ + if (machine_is_wnr854t()) + pci_common_init(&wnr854t_pci); + + return 0; +} +subsys_initcall(wnr854t_pci_init); + +MACHINE_START(WNR854T, "Netgear WNR854T") + /* Maintainer: Imre Kaloz */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = wnr854t_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END -- cgit v0.10.2 From 70129132322cdbb6683ab9e90419cd5a6f8294d3 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 30 Jun 2008 14:25:24 -0400 Subject: [ARM] Orion: add RD88F5181L-GE support This patch adds support for the Marvell Orion-VoIP RD2-88F5181L-GE Reference Design, and enables use of the ethernet, USB, Cardbus and mini-PCIe ports. Signed-off-by: Lennert Buytenhek diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 99b35b7..709e901 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -80,6 +80,12 @@ config MACH_WNR854T Say 'Y' here if you want your kernel to support the Netgear WNR854T platform. +config MACH_RD88F5181L_GE + bool "Marvell Orion-VoIP GE Reference Design" + help + Say 'Y' here if you want your kernel to support the + Marvell Orion-VoIP GE (88F5181L) RD. + endmenu endif diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index 26a62ed..ec8374a 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o obj-$(CONFIG_MACH_MSS2) += mss2-setup.o obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o +obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c new file mode 100644 index 0000000..b56447d --- /dev/null +++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c @@ -0,0 +1,172 @@ +/* + * arch/arm/mach-orion5x/rd88f5181l-ge-setup.c + * + * Marvell Orion-VoIP GE Reference Design Setup + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * RD-88F5181L GE Info + ****************************************************************************/ +/* + * 16M NOR flash Device bus boot chip select + */ +#define RD88F5181L_GE_NOR_BOOT_BASE 0xff000000 +#define RD88F5181L_GE_NOR_BOOT_SIZE SZ_16M + + +/***************************************************************************** + * 16M NOR Flash on Device bus Boot chip select + ****************************************************************************/ +static struct physmap_flash_data rd88f5181l_ge_nor_boot_flash_data = { + .width = 1, +}; + +static struct resource rd88f5181l_ge_nor_boot_flash_resource = { + .flags = IORESOURCE_MEM, + .start = RD88F5181L_GE_NOR_BOOT_BASE, + .end = RD88F5181L_GE_NOR_BOOT_BASE + + RD88F5181L_GE_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device rd88f5181l_ge_nor_boot_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &rd88f5181l_ge_nor_boot_flash_data, + }, + .num_resources = 1, + .resource = &rd88f5181l_ge_nor_boot_flash_resource, +}; + + +/***************************************************************************** + * General Setup + ****************************************************************************/ +static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = { + { 0, MPP_GPIO }, /* LED1 */ + { 1, MPP_GPIO }, /* LED5 */ + { 2, MPP_GPIO }, /* LED4 */ + { 3, MPP_GPIO }, /* LED3 */ + { 4, MPP_GPIO }, /* PCI_intA */ + { 5, MPP_GPIO }, /* RTC interrupt */ + { 6, MPP_PCI_CLK }, /* CPU PCI refclk */ + { 7, MPP_PCI_CLK }, /* PCI/PCIe refclk */ + { 8, MPP_GPIO }, /* 88e6131 interrupt */ + { 9, MPP_GPIO }, /* GE_RXERR */ + { 10, MPP_GPIO }, /* PCI_intB */ + { 11, MPP_GPIO }, /* LED2 */ + { 12, MPP_GIGE }, /* GE_TXD[4] */ + { 13, MPP_GIGE }, /* GE_TXD[5] */ + { 14, MPP_GIGE }, /* GE_TXD[6] */ + { 15, MPP_GIGE }, /* GE_TXD[7] */ + { 16, MPP_GIGE }, /* GE_RXD[4] */ + { 17, MPP_GIGE }, /* GE_RXD[5] */ + { 18, MPP_GIGE }, /* GE_RXD[6] */ + { 19, MPP_GIGE }, /* GE_RXD[7] */ + { -1 }, +}; + +static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = { + .phy_addr = -1, +}; + +static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = { + I2C_BOARD_INFO("ds1338", 0x68), +}; + +static void __init rd88f5181l_ge_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(rd88f5181l_ge_mpp_modes); + + /* + * Configure peripherals. + */ + orion5x_ehci0_init(); + orion5x_eth_init(&rd88f5181l_ge_eth_data); + orion5x_i2c_init(); + orion5x_uart0_init(); + + orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE, + RD88F5181L_GE_NOR_BOOT_SIZE); + platform_device_register(&rd88f5181l_ge_nor_boot_flash); + + i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1); +} + +static int __init +rd88f5181l_ge_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + /* + * Check for devices with hard-wired IRQs. + */ + irq = orion5x_pci_map_irq(dev, slot, pin); + if (irq != -1) + return irq; + + /* + * Cardbus slot. + */ + if (pin == 1) + return gpio_to_irq(4); + else + return gpio_to_irq(10); +} + +static struct hw_pci rd88f5181l_ge_pci __initdata = { + .nr_controllers = 2, + .swizzle = pci_std_swizzle, + .setup = orion5x_pci_sys_setup, + .scan = orion5x_pci_sys_scan_bus, + .map_irq = rd88f5181l_ge_pci_map_irq, +}; + +static int __init rd88f5181l_ge_pci_init(void) +{ + if (machine_is_rd88f5181l_ge()) { + orion5x_pci_set_cardbus_mode(); + pci_common_init(&rd88f5181l_ge_pci); + } + + return 0; +} +subsys_initcall(rd88f5181l_ge_pci_init); + +MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design") + /* Maintainer: Lennert Buytenhek */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = rd88f5181l_ge_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END -- cgit v0.10.2 From 6b5cdf0f6d4dc3d98de20d6b0abe8500046f1cb1 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 27 Jun 2008 18:56:22 -0400 Subject: [ARM] Orion: add RD88F5181L-FXO support This patch adds support for the Marvell Orion-VoIP RD-88F5181L-FXO Reference Design, and enables use of the ethernet, USB, Cardbus and mini-PCIe ports. Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 709e901..ddcd41b 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -86,6 +86,12 @@ config MACH_RD88F5181L_GE Say 'Y' here if you want your kernel to support the Marvell Orion-VoIP GE (88F5181L) RD. +config MACH_RD88F5181L_FXO + bool "Marvell Orion-VoIP FXO Reference Design" + help + Say 'Y' here if you want your kernel to support the + Marvell Orion-VoIP FXO (88F5181L) RD. + endmenu endif diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index ec8374a..fcc48a8 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o obj-$(CONFIG_MACH_MSS2) += mss2-setup.o obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o +obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c new file mode 100644 index 0000000..d50e365 --- /dev/null +++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c @@ -0,0 +1,161 @@ +/* + * arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c + * + * Marvell Orion-VoIP FXO Reference Design Setup + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * RD-88F5181L FXO Info + ****************************************************************************/ +/* + * 8M NOR flash Device bus boot chip select + */ +#define RD88F5181L_FXO_NOR_BOOT_BASE 0xff800000 +#define RD88F5181L_FXO_NOR_BOOT_SIZE SZ_8M + + +/***************************************************************************** + * 8M NOR Flash on Device bus Boot chip select + ****************************************************************************/ +static struct physmap_flash_data rd88f5181l_fxo_nor_boot_flash_data = { + .width = 1, +}; + +static struct resource rd88f5181l_fxo_nor_boot_flash_resource = { + .flags = IORESOURCE_MEM, + .start = RD88F5181L_FXO_NOR_BOOT_BASE, + .end = RD88F5181L_FXO_NOR_BOOT_BASE + + RD88F5181L_FXO_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device rd88f5181l_fxo_nor_boot_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &rd88f5181l_fxo_nor_boot_flash_data, + }, + .num_resources = 1, + .resource = &rd88f5181l_fxo_nor_boot_flash_resource, +}; + + +/***************************************************************************** + * General Setup + ****************************************************************************/ +static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = { + { 0, MPP_GPIO }, /* LED1 CardBus LED (front panel) */ + { 1, MPP_GPIO }, /* PCI_intA */ + { 2, MPP_GPIO }, /* Hard Reset / Factory Init*/ + { 3, MPP_GPIO }, /* FXS or DAA select */ + { 4, MPP_GPIO }, /* LED6 - phone LED (front panel) */ + { 5, MPP_GPIO }, /* LED5 - phone LED (front panel) */ + { 6, MPP_PCI_CLK }, /* CPU PCI refclk */ + { 7, MPP_PCI_CLK }, /* PCI/PCIe refclk */ + { 8, MPP_GPIO }, /* CardBus reset */ + { 9, MPP_GPIO }, /* GE_RXERR */ + { 10, MPP_GPIO }, /* LED2 MiniPCI LED (front panel) */ + { 11, MPP_GPIO }, /* Lifeline control */ + { 12, MPP_GIGE }, /* GE_TXD[4] */ + { 13, MPP_GIGE }, /* GE_TXD[5] */ + { 14, MPP_GIGE }, /* GE_TXD[6] */ + { 15, MPP_GIGE }, /* GE_TXD[7] */ + { 16, MPP_GIGE }, /* GE_RXD[4] */ + { 17, MPP_GIGE }, /* GE_RXD[5] */ + { 18, MPP_GIGE }, /* GE_RXD[6] */ + { 19, MPP_GIGE }, /* GE_RXD[7] */ + { -1 }, +}; + +static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = { + .phy_addr = -1, +}; + +static void __init rd88f5181l_fxo_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(rd88f5181l_fxo_mpp_modes); + + /* + * Configure peripherals. + */ + orion5x_ehci0_init(); + orion5x_eth_init(&rd88f5181l_fxo_eth_data); + orion5x_uart0_init(); + + orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE, + RD88F5181L_FXO_NOR_BOOT_SIZE); + platform_device_register(&rd88f5181l_fxo_nor_boot_flash); +} + +static int __init +rd88f5181l_fxo_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + /* + * Check for devices with hard-wired IRQs. + */ + irq = orion5x_pci_map_irq(dev, slot, pin); + if (irq != -1) + return irq; + + /* + * Mini-PCI / Cardbus slot. + */ + return gpio_to_irq(1); +} + +static struct hw_pci rd88f5181l_fxo_pci __initdata = { + .nr_controllers = 2, + .swizzle = pci_std_swizzle, + .setup = orion5x_pci_sys_setup, + .scan = orion5x_pci_sys_scan_bus, + .map_irq = rd88f5181l_fxo_pci_map_irq, +}; + +static int __init rd88f5181l_fxo_pci_init(void) +{ + if (machine_is_rd88f5181l_fxo()) { + orion5x_pci_set_cardbus_mode(); + pci_common_init(&rd88f5181l_fxo_pci); + } + + return 0; +} +subsys_initcall(rd88f5181l_fxo_pci_init); + +MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design") + /* Maintainer: Nicolas Pitre */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = rd88f5181l_fxo_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END -- cgit v0.10.2 From 2e1117d307dba8185a72bac94e57f057e70590ca Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Mon, 7 Jul 2008 21:23:09 +0300 Subject: [ARM] Orion: LED support for HP mv2120 The HP mv2120 has several LEDs that are controlled through gpio. Export the health LED, the red SATA LEDs as well as two gpios that control the brightness of _all_ LEDs to userland. The Ethernet and power LEDs can't be controlled through gpio and the blue SATA LEDs are handled via the SATA driver. Signed-off-by: Martin Michlmayr Signed-off-by: Nicolas Pitre diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 8a7cabf..9578b5d 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -1077,7 +1077,7 @@ CONFIG_LEDS_CLASS=y # # LED drivers # -# CONFIG_LEDS_GPIO is not set +CONFIG_LEDS_GPIO=y # # LED Triggers @@ -1085,7 +1085,7 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c index f1dcad3..55f3b0f 100644 --- a/arch/arm/mach-orion5x/mv2120-setup.c +++ b/arch/arm/mach-orion5x/mv2120-setup.c @@ -137,6 +137,50 @@ static struct i2c_board_info __initdata mv2120_i2c_rtc = { .irq = 0, }; +static struct gpio_led mv2120_led_pins[] = { + { + .name = "mv2120:blue:health", + .gpio = 0, + }, + { + .name = "mv2120:red:health", + .gpio = 1, + }, + { + .name = "mv2120:led:bright", + .gpio = 4, + .default_trigger = "default-on", + }, + { + .name = "mv2120:led:dimmed", + .gpio = 5, + }, + { + .name = "mv2120:red:sata0", + .gpio = 8, + .active_low = 1, + }, + { + .name = "mv2120:red:sata1", + .gpio = 9, + .active_low = 1, + }, + +}; + +static struct gpio_led_platform_data mv2120_led_data = { + .leds = mv2120_led_pins, + .num_leds = ARRAY_SIZE(mv2120_led_pins), +}; + +static struct platform_device mv2120_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &mv2120_led_data, + } +}; + static void mv2120_power_off(void) { pr_info("%s: triggering power-off...\n", __func__); @@ -172,6 +216,7 @@ static void __init mv2120_init(void) gpio_free(MV2120_GPIO_RTC_IRQ); } i2c_register_board_info(0, &mv2120_i2c_rtc, 1); + platform_device_register(&mv2120_leds); /* register mv2120 specific power-off method */ if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 || -- cgit v0.10.2 From 188237e28d7fece0471640ba86f6d8cd164ed085 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Wed, 2 Jul 2008 06:06:32 -1100 Subject: [ARM] Feroceon: don't disable BPU on boot On Feroceon platforms that have a branch prediction unit, bit 11 of the cp15 control register controls the BPU. This patch keeps the old value of this bit instead of always clearing it. Signed-off-by: Saeed Bishara Signed-off-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index 63ca1ea..f2e5884 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -493,14 +493,15 @@ __feroceon_setup: .size __feroceon_setup, . - __feroceon_setup /* - * R - * .RVI ZFRS BLDP WCAM - * .011 0001 ..11 0101 + * B + * R P + * .RVI UFRS BLDP WCAM + * .011 .001 ..11 0101 * */ .type feroceon_crval, #object feroceon_crval: - crval clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134 + crval clear=0x0000773f, mmuset=0x00003135, ucset=0x00001134 __INITDATA -- cgit v0.10.2 From c6c4f070a61b2b6e5cd317a5fbf25255878688a2 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 3 Jul 2008 09:49:39 -0700 Subject: PCI: make pci_name use dev_name Also fixes up the sparc code that was assuming this is not a constant. Acked-by: David S. Miller Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jesse Barnes diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 112b09f..d00a365 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -408,7 +408,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->class = class >> 8; dev->revision = class & 0xff; - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + sprintf(dev->dev.bus_id, "%04x:%02x:%02x.%d", pci_domain_nr(bus), dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); if (ofpci_verbose) diff --git a/include/linux/pci.h b/include/linux/pci.h index 96ebaa8..4c80dc3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -996,9 +996,9 @@ static inline void pci_set_drvdata(struct pci_dev *pdev, void *data) /* If you want to know what to call your pci_dev, ask this function. * Again, it's a wrapper around the generic device. */ -static inline char *pci_name(struct pci_dev *pdev) +static inline const char *pci_name(struct pci_dev *pdev) { - return pdev->dev.bus_id; + return dev_name(&pdev->dev); } -- cgit v0.10.2 From 3737b2b1046900660b42e25c904b85e78139d25b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:30:55 +0200 Subject: ACPI: Introduce acpi_bus_power_manageable function Introduce function acpi_bus_power_manageable() allowing other (dependent) subsystems to check if ACPI is able to power manage given device. This may be useful, for example, for PCI device power management. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Jesse Barnes diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a6dbcf4..b9b69d9 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -295,6 +295,17 @@ int acpi_bus_set_power(acpi_handle handle, int state) EXPORT_SYMBOL(acpi_bus_set_power); +bool acpi_bus_power_manageable(acpi_handle handle) +{ + struct acpi_device *device; + int result; + + result = acpi_bus_get_device(handle, &device); + return result ? false : device->flags.power_manageable; +} + +EXPORT_SYMBOL(acpi_bus_power_manageable); + /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index db90a74..0c21ea3 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -335,6 +335,7 @@ void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_set_power(acpi_handle handle, int state); +bool acpi_bus_power_manageable(acpi_handle handle); #ifdef CONFIG_ACPI_PROC_EVENT int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); -- cgit v0.10.2 From 961d9120fa6f078492a1c762dd91f2c097e56c83 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:32:02 +0200 Subject: PCI: Introduce platform_pci_power_manageable function Introduce function pointer platform_pci_power_manageable to be used by the platform-related code to point to a function allowing us to check if given device is power manageable by the platform. Introduce acpi_pci_power_manageable() playing that role for ACPI. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 056ea80..e4df71ab 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -215,7 +215,6 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) } EXPORT_SYMBOL(pci_osc_control_set); -#ifdef CONFIG_ACPI_SLEEP /* * _SxD returns the D-state with the highest power * (lowest D-state number) supported in the S-state "x". @@ -259,7 +258,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) } return PCI_POWER_ERROR; } -#endif + +static bool acpi_pci_power_manageable(struct pci_dev *dev) +{ + acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); + + return handle ? acpi_bus_power_manageable(handle) : false; +} static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) { @@ -290,6 +295,11 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) return -EINVAL; } +static struct pci_platform_pm_ops acpi_pci_platform_pm = { + .is_manageable = acpi_pci_power_manageable, + .set_state = acpi_pci_set_power_state, + .choose_state = acpi_pci_choose_state, +}; /* ACPI bus type */ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) @@ -341,10 +351,7 @@ static int __init acpi_pci_init(void) ret = register_acpi_bus_type(&acpi_pci_bus); if (ret) return 0; -#ifdef CONFIG_ACPI_SLEEP - platform_pci_choose_state = acpi_pci_choose_state; -#endif - platform_pci_set_power_state = acpi_pci_set_power_state; + pci_set_platform_pm(&acpi_pci_platform_pm); return 0; } arch_initcall(acpi_pci_init); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8e8ecc1..f807452 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -376,7 +376,32 @@ pci_restore_bars(struct pci_dev *dev) pci_update_resource(dev, &dev->resource[i], i); } -int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); +static struct pci_platform_pm_ops *pci_platform_pm; + +int pci_set_platform_pm(struct pci_platform_pm_ops *ops) +{ + if (!ops->is_manageable || !ops->set_state || !ops->choose_state) + return -EINVAL; + pci_platform_pm = ops; + return 0; +} + +static inline bool platform_pci_power_manageable(struct pci_dev *dev) +{ + return pci_platform_pm ? pci_platform_pm->is_manageable(dev) : false; +} + +static inline int platform_pci_set_power_state(struct pci_dev *dev, + pci_power_t t) +{ + return pci_platform_pm ? pci_platform_pm->set_state(dev, t) : -ENOSYS; +} + +static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) +{ + return pci_platform_pm ? + pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; +} /** * pci_set_power_state - Set the power state of a PCI device @@ -479,8 +504,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) * Give firmware a chance to be called, such as ACPI _PRx, _PSx * Firmware method after native method ? */ - if (platform_pci_set_power_state) - platform_pci_set_power_state(dev, state); + platform_pci_set_power_state(dev, state); dev->current_state = state; @@ -505,8 +529,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) return 0; } -pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev); - /** * pci_choose_state - Choose the power state of a PCI device * @dev: PCI device to be suspended @@ -524,11 +546,9 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) if (!pci_find_capability(dev, PCI_CAP_ID_PM)) return PCI_D0; - if (platform_pci_choose_state) { - ret = platform_pci_choose_state(dev); - if (ret != PCI_POWER_ERROR) - return ret; - } + ret = platform_pci_choose_state(dev); + if (ret != PCI_POWER_ERROR) + return ret; switch (state.event) { case PM_EVENT_ON: diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e0eff35..0cd2e71 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -5,10 +5,28 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); -/* Firmware callbacks */ -extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev); -extern int (*platform_pci_set_power_state)(struct pci_dev *dev, - pci_power_t state); +/** + * Firmware PM callbacks + * + * @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 + * + * @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 + * + * If given platform is generally capable of power managing PCI devices, all of + * these callbacks are mandatory. + */ +struct pci_platform_pm_ops { + bool (*is_manageable)(struct pci_dev *dev); + int (*set_state)(struct pci_dev *dev, pci_power_t state); + pci_power_t (*choose_state)(struct pci_dev *dev); +}; + +extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); -- cgit v0.10.2 From 44e4e66eeae5338b3ca0b28f8352e60bf18d5ba8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:32:52 +0200 Subject: PCI: rework pci_set_power_state function to call platform first Rework pci_set_power_state() so that the platform callback is invoked before the native mechanism, if necessary. Also, make the function check if the device is power manageable by the platform before invoking the platform callback. This may matter if the device dependent on additional power resources controlled by the platform is being put into D0, in which case those power resources must be turned on before we attempt to handle the device itself. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e4df71ab..6bc0d8c 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -277,12 +277,11 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) [PCI_D3hot] = ACPI_STATE_D3, [PCI_D3cold] = ACPI_STATE_D3 }; + int error = -EINVAL; - if (!handle) - return -ENODEV; /* If the ACPI device has _EJ0, ignore the device */ - if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) - return 0; + if (!handle || ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) + return -ENODEV; switch (state) { case PCI_D0: @@ -290,9 +289,14 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) case PCI_D2: case PCI_D3hot: case PCI_D3cold: - return acpi_bus_set_power(handle, state_conv[state]); + error = acpi_bus_set_power(handle, state_conv[state]); } - return -EINVAL; + + if (!error) + dev_printk(KERN_INFO, &dev->dev, + "power state changed by ACPI to D%d\n", state); + + return error; } static struct pci_platform_pm_ops acpi_pci_platform_pm = { diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f807452..20e2807 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -404,67 +404,56 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) } /** - * pci_set_power_state - Set the power state of a PCI device - * @dev: PCI device to be suspended - * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering + * pci_raw_set_power_state - Use PCI PM registers to set the power state of + * given PCI device + * @dev: PCI device to handle. + * @pm: PCI PM capability offset of the device. + * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. * - * Transition a device to a new power state, using the Power Management - * Capabilities in the device's config space. - * - * RETURN VALUE: - * -EINVAL if trying to enter a lower state than we're already in. - * 0 if we're already in the requested state. - * -EIO if device does not support PCI PM. - * 0 if we can successfully change the power state. + * RETURN VALUE: + * -EINVAL if the requested state is invalid. + * -EIO if device does not support PCI PM or its PM capabilities register has a + * wrong version, or device doesn't support the requested state. + * 0 if device already is in the requested state. + * 0 if device's power state has been successfully changed. */ -int -pci_set_power_state(struct pci_dev *dev, pci_power_t state) +static int +pci_raw_set_power_state(struct pci_dev *dev, int pm, pci_power_t state) { - int pm, need_restore = 0; u16 pmcsr, pmc; + bool need_restore = false; - /* bound the state we're entering */ - if (state > PCI_D3hot) - state = PCI_D3hot; - - /* - * If the device or the parent bridge can't support PCI PM, ignore - * the request if we're doing anything besides putting it into D0 - * (which would only happen on boot). - */ - if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) - return 0; - - /* find PCI PM capability in list */ - pm = pci_find_capability(dev, PCI_CAP_ID_PM); - - /* abort if the device doesn't support PM capabilities */ if (!pm) return -EIO; + if (state < PCI_D0 || state > PCI_D3hot) + return -EINVAL; + /* Validate current state: * Can enter D0 from any state, but if we can only go deeper * to sleep if we're already in a low power state */ - if (state != PCI_D0 && dev->current_state > state) { + if (dev->current_state == state) { + /* we're already there */ + return 0; + } else if (state != PCI_D0 && dev->current_state <= PCI_D3cold + && dev->current_state > state) { dev_err(&dev->dev, "invalid power transition " "(from state %d to %d)\n", dev->current_state, state); return -EINVAL; - } else if (dev->current_state == state) - return 0; /* we're already there */ + } + pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); - pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc); if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { - dev_printk(KERN_DEBUG, &dev->dev, "unsupported PM cap regs " - "version (%u)\n", pmc & PCI_PM_CAP_VER_MASK); + dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", + pmc & PCI_PM_CAP_VER_MASK); return -EIO; } /* check if this device supports the desired state */ - if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1)) - return -EIO; - else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2)) + if ((state == PCI_D1 && !(pmc & PCI_PM_CAP_D1)) + || (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))) return -EIO; pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); @@ -483,7 +472,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) case PCI_UNKNOWN: /* Boot-up */ if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) - need_restore = 1; + need_restore = true; /* Fall-through: force to D0 */ default: pmcsr = 0; @@ -500,12 +489,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) else if (state == PCI_D2 || dev->current_state == PCI_D2) udelay(200); - /* - * Give firmware a chance to be called, such as ACPI _PRx, _PSx - * Firmware method after native method ? - */ - platform_pci_set_power_state(dev, state); - dev->current_state = state; /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT @@ -530,6 +513,81 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) } /** + * pci_update_current_state - Read PCI power state of given device from its + * PCI PM registers and cache it + * @dev: PCI device to handle. + * @pm: PCI PM capability offset of the device. + */ +static void pci_update_current_state(struct pci_dev *dev, int pm) +{ + if (pm) { + u16 pmcsr; + + pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); + } +} + +/** + * pci_set_power_state - Set the power state of a PCI device + * @dev: PCI device to handle. + * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. + * + * Transition a device to a new power state, using the platform formware and/or + * the device's PCI PM registers. + * + * RETURN VALUE: + * -EINVAL if the requested state is invalid. + * -EIO if device does not support PCI PM or its PM capabilities register has a + * wrong version, or device doesn't support the requested state. + * 0 if device already is in the requested state. + * 0 if device's power state has been successfully changed. + */ +int pci_set_power_state(struct pci_dev *dev, pci_power_t state) +{ + int pm, error; + + /* bound the state we're entering */ + if (state > PCI_D3hot) + state = PCI_D3hot; + else if (state < PCI_D0) + state = PCI_D0; + else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) + /* + * If the device or the parent bridge do not support PCI PM, + * ignore the request if we're doing anything other than putting + * it into D0 (which would only happen on boot). + */ + return 0; + + /* Find PCI PM capability in the list */ + pm = pci_find_capability(dev, PCI_CAP_ID_PM); + + if (state == PCI_D0 && platform_pci_power_manageable(dev)) { + /* + * Allow the platform to change the state, for example via ACPI + * _PR0, _PS0 and some such, but do not trust it. + */ + int ret = platform_pci_set_power_state(dev, PCI_D0); + if (!ret) + pci_update_current_state(dev, pm); + } + + error = pci_raw_set_power_state(dev, pm, state); + + if (state > PCI_D0 && platform_pci_power_manageable(dev)) { + /* Allow the platform to finalize the transition */ + int ret = platform_pci_set_power_state(dev, state); + if (!ret) { + pci_update_current_state(dev, pm); + error = 0; + } + } + + return error; +} + +/** * pci_choose_state - Choose the power state of a PCI device * @dev: PCI device to be suspended * @state: target sleep state for the whole system. This is the value -- cgit v0.10.2 From 77e766099efc29d8b01db4b8244ff64fa3d3d0ca Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:33:34 +0200 Subject: ACPI: Introduce acpi_device_sleep_wake function The currect ACPI code attempts to execute _PSW at three different places and in one of them only it tries to execute _DSW before _PSW, which is inconsistent with the other two cases. Move the execution of _DSW and _PSW into a separate function called acpi_device_sleep_wake() and call it wherever appropriate instead of executing _DSW and/or _PSW directly. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Jesse Barnes diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 81e4f08..2e959aa 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -292,69 +292,115 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) return 0; } +/** + * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in + * ACPI 3.0) _PSW (Power State Wake) + * @dev: Device to handle. + * @enable: 0 - disable, 1 - enable the wake capabilities of the device. + * @sleep_state: Target sleep state of the system. + * @dev_state: Target power state of the device. + * + * Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power + * State Wake) for the device, if present. On failure reset the device's + * wakeup.flags.valid flag. + * + * RETURN VALUE: + * 0 if either _DSW or _PSW has been successfully executed + * 0 if neither _DSW nor _PSW has been found + * -ENODEV if the execution of either _DSW or _PSW has failed + */ +int acpi_device_sleep_wake(struct acpi_device *dev, + int enable, int sleep_state, int dev_state) +{ + union acpi_object in_arg[3]; + struct acpi_object_list arg_list = { 3, in_arg }; + acpi_status status = AE_OK; + + /* + * Try to execute _DSW first. + * + * Three agruments are needed for the _DSW object: + * Argument 0: enable/disable the wake capabilities + * Argument 1: target system state + * Argument 2: target device state + * When _DSW object is called to disable the wake capabilities, maybe + * the first argument is filled. The values of the other two agruments + * are meaningless. + */ + in_arg[0].type = ACPI_TYPE_INTEGER; + in_arg[0].integer.value = enable; + in_arg[1].type = ACPI_TYPE_INTEGER; + in_arg[1].integer.value = sleep_state; + in_arg[2].type = ACPI_TYPE_INTEGER; + in_arg[2].integer.value = dev_state; + status = acpi_evaluate_object(dev->handle, "_DSW", &arg_list, NULL); + if (ACPI_SUCCESS(status)) { + return 0; + } else if (status != AE_NOT_FOUND) { + printk(KERN_ERR PREFIX "_DSW execution failed\n"); + dev->wakeup.flags.valid = 0; + return -ENODEV; + } + + /* Execute _PSW */ + arg_list.count = 1; + in_arg[0].integer.value = enable; + status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); + if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { + printk(KERN_ERR PREFIX "_PSW execution failed\n"); + dev->wakeup.flags.valid = 0; + return -ENODEV; + } + + return 0; +} + /* * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229): * 1. Power on the power resources required for the wakeup device - * 2. Enable _PSW (power state wake) for the device if present + * 2. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power + * State Wake) for the device, if present */ -int acpi_enable_wakeup_device_power(struct acpi_device *dev) +int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) { - union acpi_object arg = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &arg }; - acpi_status status = AE_OK; int i; - int ret = 0; if (!dev || !dev->wakeup.flags.valid) - return -1; + return -EINVAL; - arg.integer.value = 1; /* Open power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { - ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); + int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; - return -1; + return -ENODEV; } } - /* Execute PSW */ - status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); - if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { - printk(KERN_ERR PREFIX "Evaluate _PSW\n"); - dev->wakeup.flags.valid = 0; - ret = -1; - } - - return ret; + /* + * Passing 3 as the third argument below means the device may be placed + * in arbitrary power state afterwards. + */ + return acpi_device_sleep_wake(dev, 1, sleep_state, 3); } /* * Shutdown a wakeup device, counterpart of above method - * 1. Disable _PSW (power state wake) + * 1. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power + * State Wake) for the device, if present * 2. Shutdown down the power resources */ int acpi_disable_wakeup_device_power(struct acpi_device *dev) { - union acpi_object arg = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &arg }; - acpi_status status = AE_OK; - int i; - int ret = 0; - + int i, ret; if (!dev || !dev->wakeup.flags.valid) - return -1; + return -EINVAL; - arg.integer.value = 0; - /* Execute PSW */ - status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); - if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { - printk(KERN_ERR PREFIX "Evaluate _PSW\n"); - dev->wakeup.flags.valid = 0; - return -1; - } + ret = acpi_device_sleep_wake(dev, 0, 0, 0); + if (ret) + return ret; /* Close power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { @@ -362,7 +408,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; - return -1; + return -ENODEV; } } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 6d85289..f276890 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -691,9 +691,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *package = NULL; - union acpi_object in_arg[3]; - struct acpi_object_list arg_list = { 3, in_arg }; - acpi_status psw_status = AE_OK; + int psw_error; struct acpi_device_id button_device_ids[] = { {"PNP0C0D", 0}, @@ -725,39 +723,11 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) * So it is necessary to call _DSW object first. Only when it is not * present will the _PSW object used. */ - /* - * Three agruments are needed for the _DSW object. - * Argument 0: enable/disable the wake capabilities - * When _DSW object is called to disable the wake capabilities, maybe - * the first argument is filled. The value of the other two agruments - * is meaningless. - */ - in_arg[0].type = ACPI_TYPE_INTEGER; - in_arg[0].integer.value = 0; - in_arg[1].type = ACPI_TYPE_INTEGER; - in_arg[1].integer.value = 0; - in_arg[2].type = ACPI_TYPE_INTEGER; - in_arg[2].integer.value = 0; - psw_status = acpi_evaluate_object(device->handle, "_DSW", - &arg_list, NULL); - if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n")); - /* - * When the _DSW object is not present, OSPM will call _PSW object. - */ - if (psw_status == AE_NOT_FOUND) { - /* - * Only one agruments is required for the _PSW object. - * agrument 0: enable/disable the wake capabilities - */ - arg_list.count = 1; - in_arg[0].integer.value = 0; - psw_status = acpi_evaluate_object(device->handle, "_PSW", - &arg_list, NULL); - if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in " - "evaluate _PSW\n")); - } + psw_error = acpi_device_sleep_wake(device, 0, 0, 0); + if (psw_error) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "error in _DSW or _PSW evaluation\n")); + /* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids(device, button_device_ids)) device->wakeup.flags.run_wake = 1; diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index ed8e41b..7422a22 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c @@ -42,7 +42,7 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) continue; spin_unlock(&acpi_device_lock); - acpi_enable_wakeup_device_power(dev); + acpi_enable_wakeup_device_power(dev, sleep_state); spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 9757a04..e5f38e5 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -87,7 +87,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI_POWER -int acpi_enable_wakeup_device_power(struct acpi_device *dev); +int acpi_device_sleep_wake(struct acpi_device *dev, + int enable, int sleep_state, int dev_state); +int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); int acpi_power_get_inferred_state(struct acpi_device *device); int acpi_power_transition(struct acpi_device *device, int state); -- cgit v0.10.2 From 0af4b8c4fb31193dc666f4893107a18fef82baab Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:34:11 +0200 Subject: ACPI: Introduce new device wakeup flag 'prepared' Introduce additional flag 'prepared' in struct acpi_device_wakeup_flags and use it to prevent devices from being enable/disabled do wake up the system multiple times in a row (this does not happen currently, but will be possible after some of the following patches). Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 2e959aa..4ab21cb 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -363,11 +363,18 @@ int acpi_device_sleep_wake(struct acpi_device *dev, */ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) { - int i; + int i, err; if (!dev || !dev->wakeup.flags.valid) return -EINVAL; + /* + * Do not execute the code below twice in a row without calling + * acpi_disable_wakeup_device_power() in between for the same device + */ + if (dev->wakeup.flags.prepared) + return 0; + /* Open power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); @@ -382,7 +389,11 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) * Passing 3 as the third argument below means the device may be placed * in arbitrary power state afterwards. */ - return acpi_device_sleep_wake(dev, 1, sleep_state, 3); + err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); + if (!err) + dev->wakeup.flags.prepared = 1; + + return err; } /* @@ -398,6 +409,15 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) if (!dev || !dev->wakeup.flags.valid) return -EINVAL; + /* + * Do not execute the code below twice in a row without calling + * acpi_enable_wakeup_device_power() in between for the same device + */ + if (!dev->wakeup.flags.prepared) + return 0; + + dev->wakeup.flags.prepared = 0; + ret = acpi_device_sleep_wake(dev, 0, 0, 0); if (ret) return ret; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0c21ea3..071daf8 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -259,6 +259,7 @@ struct acpi_device_perf { /* Wakeup Management */ struct acpi_device_wakeup_flags { u8 valid:1; /* Can successfully enable wakeup? */ + u8 prepared:1; /* Has the wake-up capability been enabled? */ u8 run_wake:1; /* Run-Wake GPE devices */ }; -- cgit v0.10.2 From eb9d0fe40e313c0a74115ef456a2e43a6c8da72f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:34:48 +0200 Subject: PCI ACPI: Rework PCI handling of wake-up * Introduce function acpi_pm_device_sleep_wake() for enabling and disabling the system wake-up capability of devices that are power manageable by ACPI. * Introduce function acpi_bus_can_wakeup() allowing other (dependent) subsystems to check if ACPI is able to enable the system wake-up capability of given device. * Introduce callback .sleep_wake() in struct pci_platform_pm_ops and for the ACPI PCI 'driver' make it use acpi_pm_device_sleep_wake(). * Introduce callback .can_wakeup() in struct pci_platform_pm_ops and for the ACPI 'driver' make it use acpi_bus_can_wakeup(). * Move the PME# handlig code out of pci_enable_wake() and split it into two functions, pci_pme_capable() and pci_pme_active(), allowing the caller to check if given device is capable of generating PME# from given power state and to enable/disable the device's PME# functionality, respectively. * Modify pci_enable_wake() to use the new ACPI callbacks and the new PME#-related functions. * Drop the generic .platform_enable_wakeup() callback that is not used any more. * Introduce device_set_wakeup_capable() that will set the power.can_wakeup flag of given device. * Rework PCI device PM initialization so that, if given device is capable of generating wake-up events, either natively through the PME# mechanism, or with the help of the platform, its power.can_wakeup flag is set and its power.should_wakeup flag is unset as appropriate. * Make ACPI set the power.can_wakeup flag for devices found to be wake-up capable by it. * Make the ACPI wake-up code enable/disable GPEs for devices that have the wakeup.flags.prepared flag set (which means that their wake-up power has been enabled). Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b9b69d9..fc1110d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -306,6 +306,17 @@ bool acpi_bus_power_manageable(acpi_handle handle) EXPORT_SYMBOL(acpi_bus_power_manageable); +bool acpi_bus_can_wakeup(acpi_handle handle) +{ + struct acpi_device *device; + int result; + + result = acpi_bus_get_device(handle, &device); + return result ? false : device->wakeup.flags.valid; +} + +EXPORT_SYMBOL(acpi_bus_can_wakeup); + /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 06f8634..87c5d45 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -166,6 +166,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) "firmware_node"); ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, "physical_node"); + if (acpi_dev->wakeup.flags.valid) + device_set_wakeup_capable(dev, true); } return 0; diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 4addf8a..af7f466 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -468,6 +468,31 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) *d_min_p = d_min; return d_max; } + +/** + * acpi_pm_device_sleep_wake - enable or disable the system wake-up + * capability of given device + * @dev: device to handle + * @enable: 'true' - enable, 'false' - disable the wake-up capability + */ +int acpi_pm_device_sleep_wake(struct device *dev, bool enable) +{ + acpi_handle handle; + struct acpi_device *adev; + + if (!device_may_wakeup(dev)) + return -EINVAL; + + handle = DEVICE_ACPI_HANDLE(dev); + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + printk(KERN_DEBUG "ACPI handle has no context!\n"); + return -ENODEV; + } + + return enable ? + acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : + acpi_disable_wakeup_device_power(adev); +} #endif static void acpi_power_off_prepare(void) diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index 7422a22..38655eb 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c @@ -66,13 +66,15 @@ void acpi_enable_wakeup_device(u8 sleep_state) list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); + if (!dev->wakeup.flags.valid) continue; + /* If users want to disable run-wake GPE, * we only disable it for wake and leave it for runtime */ - if (!dev->wakeup.state.enabled || - sleep_state > (u32) dev->wakeup.sleep_state) { + if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) + || sleep_state > (u32) dev->wakeup.sleep_state) { if (dev->wakeup.flags.run_wake) { spin_unlock(&acpi_device_lock); /* set_gpe_type will disable GPE, leave it like that */ @@ -110,8 +112,9 @@ void acpi_disable_wakeup_device(u8 sleep_state) if (!dev->wakeup.flags.valid) continue; - if (!dev->wakeup.state.enabled || - sleep_state > (u32) dev->wakeup.sleep_state) { + + if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) + || sleep_state > (u32) dev->wakeup.sleep_state) { if (dev->wakeup.flags.run_wake) { spin_unlock(&acpi_device_lock); acpi_set_gpe_type(dev->wakeup.gpe_device, diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index d11f74b..596aeec 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -6,9 +6,6 @@ #include #include "power.h" -int (*platform_enable_wakeup)(struct device *dev, int is_on); - - /* * wakeup - Report/change current wakeup option for device * diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 6bc0d8c..7764768b 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -299,10 +299,30 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) return error; } +static bool acpi_pci_can_wakeup(struct pci_dev *dev) +{ + acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); + + return handle ? acpi_bus_can_wakeup(handle) : false; +} + +static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) +{ + int error = acpi_pm_device_sleep_wake(&dev->dev, enable); + + if (!error) + dev_printk(KERN_INFO, &dev->dev, + "wake-up capability %s by ACPI\n", + enable ? "enabled" : "disabled"); + return error; +} + static struct pci_platform_pm_ops acpi_pci_platform_pm = { .is_manageable = acpi_pci_power_manageable, .set_state = acpi_pci_set_power_state, .choose_state = acpi_pci_choose_state, + .can_wakeup = acpi_pci_can_wakeup, + .sleep_wake = acpi_pci_sleep_wake, }; /* ACPI bus type */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 20e2807..a6b1b6f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -380,7 +380,8 @@ static struct pci_platform_pm_ops *pci_platform_pm; int pci_set_platform_pm(struct pci_platform_pm_ops *ops) { - if (!ops->is_manageable || !ops->set_state || !ops->choose_state) + if (!ops->is_manageable || !ops->set_state || !ops->choose_state + || !ops->sleep_wake || !ops->can_wakeup) return -EINVAL; pci_platform_pm = ops; return 0; @@ -403,6 +404,17 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; } +static inline bool platform_pci_can_wakeup(struct pci_dev *dev) +{ + return pci_platform_pm ? pci_platform_pm->can_wakeup(dev) : false; +} + +static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) +{ + return pci_platform_pm ? + pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; +} + /** * pci_raw_set_power_state - Use PCI PM registers to set the power state of * given PCI device @@ -1036,6 +1048,56 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) } /** + * pci_pme_capable - check the capability of PCI device to generate PME# + * @dev: PCI device to handle. + * @pm: PCI PM capability offset of the device. + * @state: PCI state from which device will issue PME#. + */ +static bool pci_pme_capable(struct pci_dev *dev, int pm, pci_power_t state) +{ + u16 pmc; + + if (!pm) + return false; + + /* Check device's ability to generate PME# from given state */ + pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); + + pmc &= PCI_PM_CAP_PME_MASK; + pmc >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ + + return !!(pmc & (1 << state)); +} + +/** + * pci_pme_active - enable or disable PCI device's PME# function + * @dev: PCI device to handle. + * @pm: PCI PM capability offset of the device. + * @enable: 'true' to enable PME# generation; 'false' to disable it. + * + * The caller must verify that the device is capable of generating PME# before + * calling this function with @enable equal to 'true'. + */ +static void pci_pme_active(struct pci_dev *dev, int pm, bool enable) +{ + u16 pmcsr; + + if (!pm) + return; + + pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + /* Clear PME_Status by writing 1 to it and enable PME# */ + pmcsr |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE; + if (!enable) + pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; + + pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr); + + dev_printk(KERN_INFO, &dev->dev, "PME# %s\n", + enable ? "enabled" : "disabled"); +} + +/** * pci_enable_wake - enable PCI device as wakeup event source * @dev: PCI device affected * @state: PCI state from which device will issue wakeup events @@ -1046,66 +1108,83 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) * called automatically by this routine. * * Devices with legacy power management (no standard PCI PM capabilities) - * always require such platform hooks. Depending on the platform, devices - * supporting the standard PCI PME# signal may require such platform hooks; - * they always update bits in config space to allow PME# generation. + * always require such platform hooks. * - * -EIO is returned if the device can't ever be a wakeup event source. - * -EINVAL is returned if the device can't generate wakeup events from - * the specified PCI state. Returns zero if the operation is successful. + * RETURN VALUE: + * 0 is returned on success + * -EINVAL is returned if device is not supposed to wake up the system + * Error code depending on the platform is returned if both the platform and + * the native mechanism fail to enable the generation of wake-up events */ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { int pm; - int status; - u16 value; - - /* Note that drivers should verify device_may_wakeup(&dev->dev) - * before calling this function. Platform code should report - * errors when drivers try to enable wakeup on devices that - * can't issue wakeups, or on which wakeups were disabled by - * userspace updating the /sys/devices.../power/wakeup file. - */ + int error = 0; + bool pme_done = false; - status = call_platform_enable_wakeup(&dev->dev, enable); - - /* find PCI PM capability in list */ - pm = pci_find_capability(dev, PCI_CAP_ID_PM); + if (!device_may_wakeup(&dev->dev)) + return -EINVAL; - /* If device doesn't support PM Capabilities, but caller wants to - * disable wake events, it's a NOP. Otherwise fail unless the - * platform hooks handled this legacy device already. + /* + * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don + * Anderson we should be doing PME# wake enable followed by ACPI wake + * enable. To disable wake-up we call the platform first, for symmetry. */ - if (!pm) - return enable ? status : 0; - /* Check device's ability to generate PME# */ - pci_read_config_word(dev,pm+PCI_PM_PMC,&value); + if (!enable && platform_pci_can_wakeup(dev)) + error = platform_pci_sleep_wake(dev, false); - value &= PCI_PM_CAP_PME_MASK; - value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ - - /* Check if it can generate PME# from requested state. */ - if (!value || !(value & (1 << state))) { - /* if it can't, revert what the platform hook changed, - * always reporting the base "EINVAL, can't PME#" error - */ - if (enable) - call_platform_enable_wakeup(&dev->dev, 0); - return enable ? -EINVAL : 0; + pm = pci_find_capability(dev, PCI_CAP_ID_PM); + if (!enable || pci_pme_capable(dev, pm, state)) { + pci_pme_active(dev, pm, enable); + pme_done = true; } - pci_read_config_word(dev, pm + PCI_PM_CTRL, &value); + if (enable && platform_pci_can_wakeup(dev)) + error = platform_pci_sleep_wake(dev, true); - /* Clear PME_Status by writing 1 to it and enable PME# */ - value |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE; + return pme_done ? 0 : error; +} - if (!enable) - value &= ~PCI_PM_CTRL_PME_ENABLE; +/** + * pci_pm_init - Initialize PM functions of given PCI device + * @dev: PCI device to handle. + */ +void pci_pm_init(struct pci_dev *dev) +{ + int pm; + u16 pmc; - pci_write_config_word(dev, pm + PCI_PM_CTRL, value); + /* find PCI PM capability in list */ + pm = pci_find_capability(dev, PCI_CAP_ID_PM); + if (!pm) + return; + /* Check device's ability to generate PME# */ + pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); - return 0; + if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { + dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", + pmc & PCI_PM_CAP_VER_MASK); + return; + } + + if (pmc & PCI_PM_CAP_PME_MASK) { + dev_printk(KERN_INFO, &dev->dev, + "PME# supported from%s%s%s%s%s\n", + (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", + (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", + (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", + (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", + (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); + /* + * Make device's PM flags reflect the wake-up capability, but + * let the user space enable it to wake up the system as needed. + */ + device_set_wakeup_capable(&dev->dev, true); + device_set_wakeup_enable(&dev->dev, false); + /* Disable the PME# generation functionality */ + pci_pme_active(dev, pm, false); + } } int diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0cd2e71..b08dfc9 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -17,6 +17,11 @@ extern void pci_cleanup_rom(struct pci_dev *dev); * 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 + * + * @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. */ @@ -24,9 +29,12 @@ struct pci_platform_pm_ops { bool (*is_manageable)(struct pci_dev *dev); int (*set_state)(struct pci_dev *dev, pci_power_t state); pci_power_t (*choose_state)(struct pci_dev *dev); + bool (*can_wakeup)(struct pci_dev *dev); + int (*sleep_wake)(struct pci_dev *dev, bool enable); }; extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); +extern void pci_pm_init(struct pci_dev *dev); extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2f0ae70..b1724cf 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -860,49 +860,6 @@ int pci_cfg_space_size_ext(struct pci_dev *dev) return PCI_CFG_SPACE_SIZE; } -/** - * pci_disable_pme - Disable the PME function of PCI device - * @dev: PCI device affected - * -EINVAL is returned if PCI device doesn't support PME. - * Zero is returned if the PME is supported and can be disabled. - */ -static int pci_disable_pme(struct pci_dev *dev) -{ - int pm; - u16 value; - - /* find PCI PM capability in list */ - pm = pci_find_capability(dev, PCI_CAP_ID_PM); - - /* If device doesn't support PM Capabilities, it means that PME is - * not supported. - */ - if (!pm) - return -EINVAL; - /* Check device's ability to generate PME# */ - pci_read_config_word(dev, pm + PCI_PM_PMC, &value); - - value &= PCI_PM_CAP_PME_MASK; - /* Check if it can generate PME# */ - if (!value) { - /* - * If it is zero, it means that PME is still unsupported - * although there exists the PM capability. - */ - return -EINVAL; - } - - pci_read_config_word(dev, pm + PCI_PM_CTRL, &value); - - /* Clear PME_Status by writing 1 to it */ - value |= PCI_PM_CTRL_PME_STATUS ; - /* Disable PME enable bit */ - value &= ~PCI_PM_CTRL_PME_ENABLE; - pci_write_config_word(dev, pm + PCI_PM_CTRL, value); - - return 0; -} - int pci_cfg_space_size(struct pci_dev *dev) { int pos; @@ -1010,7 +967,6 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) } pci_vpd_pci22_init(dev); - pci_disable_pme(dev); return dev; } @@ -1031,6 +987,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) /* Fix up broken headers */ pci_fixup_device(pci_fixup_header, dev); + /* Initialize power management of the device */ + pci_pm_init(dev); + /* * Add the device to our list of discovered devices * and the bus list for fixup functions, etc. diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 071daf8..7ab5a61 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -337,6 +337,7 @@ int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_set_power(acpi_handle handle, int state); bool acpi_bus_power_manageable(acpi_handle handle); +bool acpi_bus_can_wakeup(acpi_handle handle); #ifdef CONFIG_ACPI_PROC_EVENT int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); @@ -379,6 +380,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); #ifdef CONFIG_PM_SLEEP int acpi_pm_device_sleep_state(struct device *, int *); +int acpi_pm_device_sleep_wake(struct device *, bool); #else /* !CONFIG_PM_SLEEP */ static inline int acpi_pm_device_sleep_state(struct device *d, int *p) { diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index f0d0b2c..3af0c8d 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -35,6 +35,11 @@ static inline void device_init_wakeup(struct device *dev, int val) dev->power.can_wakeup = dev->power.should_wakeup = !!val; } +static inline void device_set_wakeup_capable(struct device *dev, int val) +{ + dev->power.can_wakeup = !!val; +} + static inline int device_can_wakeup(struct device *dev) { return dev->power.can_wakeup; @@ -47,21 +52,7 @@ static inline void device_set_wakeup_enable(struct device *dev, int val) static inline int device_may_wakeup(struct device *dev) { - return dev->power.can_wakeup & dev->power.should_wakeup; -} - -/* - * Platform hook to activate device wakeup capability, if that's not already - * handled by enable_irq_wake() etc. - * Returns zero on success, else negative errno - */ -extern int (*platform_enable_wakeup)(struct device *dev, int is_on); - -static inline int call_platform_enable_wakeup(struct device *dev, int is_on) -{ - if (platform_enable_wakeup) - return (*platform_enable_wakeup)(dev, is_on); - return 0; + return dev->power.can_wakeup && dev->power.should_wakeup; } #else /* !CONFIG_PM */ @@ -80,11 +71,6 @@ static inline int device_can_wakeup(struct device *dev) #define device_set_wakeup_enable(dev, val) do {} while (0) #define device_may_wakeup(dev) 0 -static inline int call_platform_enable_wakeup(struct device *dev, int is_on) -{ - return 0; -} - #endif /* !CONFIG_PM */ #endif /* _LINUX_PM_WAKEUP_H */ -- cgit v0.10.2 From 404cc2d8ce41ed4031958fba8e633767e8a2e028 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:35:26 +0200 Subject: PCI PM: Introduce pci_prepare_to_sleep and pci_back_from_sleep Introduce functions pci_prepare_to_sleep() and pci_back_from_sleep(), to be used by the PCI drivers that want to place their devices into the lowest power state appropiate for them (PCI_D3hot, if the device is not supposed to wake up the system, or the deepest state from which the wake-up is possible, otherwise) while the system is being prepared to go into a sleeping state and to put them back into D0 during the subsequent transition to the working state. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a6b1b6f..1b0ec45 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1147,6 +1147,87 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) } /** + * pci_prepare_to_sleep - prepare PCI device for system-wide transition into + * a sleep state + * @dev: Device to handle. + * + * Choose the power state appropriate for the device depending on whether + * it can wake up the system and/or is power manageable by the platform + * (PCI_D3hot is the default) and put the device into that state. + */ +int pci_prepare_to_sleep(struct pci_dev *dev) +{ + pci_power_t target_state = PCI_D3hot; + int pm = pci_find_capability(dev, PCI_CAP_ID_PM); + int error; + + if (platform_pci_power_manageable(dev)) { + /* + * Call the platform to choose the target state of the device + * and enable wake-up from this state if supported. + */ + pci_power_t state = platform_pci_choose_state(dev); + + switch (state) { + case PCI_POWER_ERROR: + case PCI_UNKNOWN: + break; + case PCI_D1: + case PCI_D2: + if (pci_no_d1d2(dev)) + break; + default: + target_state = state; + pci_enable_wake(dev, target_state, true); + } + } else if (device_may_wakeup(&dev->dev)) { + /* + * Find the deepest state from which the device can generate + * wake-up events, make it the target state and enable device + * to generate PME#. + */ + u16 pmc; + + if (!pm) + return -EIO; + + pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); + if (pmc & PCI_PM_CAP_PME_MASK) { + if (!(pmc & PCI_PM_CAP_PME_D3)) { + /* Device cannot generate PME# from D3_hot */ + if (pmc & PCI_PM_CAP_PME_D2) + target_state = PCI_D2; + else if (pmc & PCI_PM_CAP_PME_D1) + target_state = PCI_D1; + else + target_state = PCI_D0; + } + pci_pme_active(dev, pm, true); + } + } + + error = pci_set_power_state(dev, target_state); + + if (error) + pci_enable_wake(dev, target_state, false); + + return error; +} + +/** + * pci_back_from_sleep - turn PCI device on during system-wide transition into + * the working state a sleep state + * @dev: Device to handle. + * + * Disable device's sytem wake-up capability and put it into D0. + */ +int pci_back_from_sleep(struct pci_dev *dev) +{ + pci_enable_wake(dev, PCI_D0, false); + return pci_set_power_state(dev, PCI_D0); +} + +/** * pci_pm_init - Initialize PM functions of given PCI device * @dev: PCI device to handle. */ @@ -1853,5 +1934,7 @@ EXPORT_SYMBOL(pci_set_power_state); EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); +EXPORT_SYMBOL(pci_prepare_to_sleep); +EXPORT_SYMBOL(pci_back_from_sleep); EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); diff --git a/include/linux/pci.h b/include/linux/pci.h index 4c80dc3..52ac06d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -632,6 +632,8 @@ int pci_restore_state(struct pci_dev *dev); int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); +int pci_prepare_to_sleep(struct pci_dev *dev); +int pci_back_from_sleep(struct pci_dev *dev); /* Functions for PCI Hotplug drivers to use */ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); -- cgit v0.10.2 From 337001b6c42938f49a880b1b8306c3ed771a7e61 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 7 Jul 2008 03:36:24 +0200 Subject: PCI: Simplify PCI device PM code If the offset of PCI device's PM capability in its configuration space, the mask of states that the device supports PME# from and the D1 and D2 support bits are cached in the corresponding struct pci_dev, the PCI device PM code can be simplified quite a bit. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b0ec45..e632a58 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -419,7 +419,6 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) * pci_raw_set_power_state - Use PCI PM registers to set the power state of * given PCI device * @dev: PCI device to handle. - * @pm: PCI PM capability offset of the device. * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. * * RETURN VALUE: @@ -430,12 +429,12 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) * 0 if device's power state has been successfully changed. */ static int -pci_raw_set_power_state(struct pci_dev *dev, int pm, pci_power_t state) +pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) { - u16 pmcsr, pmc; + u16 pmcsr; bool need_restore = false; - if (!pm) + if (!dev->pm_cap) return -EIO; if (state < PCI_D0 || state > PCI_D3hot) @@ -455,20 +454,12 @@ pci_raw_set_power_state(struct pci_dev *dev, int pm, pci_power_t state) return -EINVAL; } - pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); - - if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { - dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", - pmc & PCI_PM_CAP_VER_MASK); - return -EIO; - } - /* check if this device supports the desired state */ - if ((state == PCI_D1 && !(pmc & PCI_PM_CAP_D1)) - || (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))) + if ((state == PCI_D1 && !dev->d1_support) + || (state == PCI_D2 && !dev->d2_support)) return -EIO; - pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); /* If we're (effectively) in D3, force entire word to 0. * This doesn't affect PME_Status, disables PME_En, and @@ -492,7 +483,7 @@ pci_raw_set_power_state(struct pci_dev *dev, int pm, pci_power_t state) } /* enter specified state */ - pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr); + pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); /* Mandatory power management transition delays */ /* see PCI PM 1.1 5.6.1 table 18 */ @@ -528,14 +519,13 @@ pci_raw_set_power_state(struct pci_dev *dev, int pm, pci_power_t state) * pci_update_current_state - Read PCI power state of given device from its * PCI PM registers and cache it * @dev: PCI device to handle. - * @pm: PCI PM capability offset of the device. */ -static void pci_update_current_state(struct pci_dev *dev, int pm) +static void pci_update_current_state(struct pci_dev *dev) { - if (pm) { + if (dev->pm_cap) { u16 pmcsr; - pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } } @@ -557,7 +547,7 @@ static void pci_update_current_state(struct pci_dev *dev, int pm) */ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { - int pm, error; + int error; /* bound the state we're entering */ if (state > PCI_D3hot) @@ -572,9 +562,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) */ return 0; - /* Find PCI PM capability in the list */ - pm = pci_find_capability(dev, PCI_CAP_ID_PM); - if (state == PCI_D0 && platform_pci_power_manageable(dev)) { /* * Allow the platform to change the state, for example via ACPI @@ -582,16 +569,16 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) */ int ret = platform_pci_set_power_state(dev, PCI_D0); if (!ret) - pci_update_current_state(dev, pm); + pci_update_current_state(dev); } - error = pci_raw_set_power_state(dev, pm, state); + error = pci_raw_set_power_state(dev, state); if (state > PCI_D0 && platform_pci_power_manageable(dev)) { /* Allow the platform to finalize the transition */ int ret = platform_pci_set_power_state(dev, state); if (!ret) { - pci_update_current_state(dev, pm); + pci_update_current_state(dev); error = 0; } } @@ -1050,48 +1037,38 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) /** * pci_pme_capable - check the capability of PCI device to generate PME# * @dev: PCI device to handle. - * @pm: PCI PM capability offset of the device. * @state: PCI state from which device will issue PME#. */ -static bool pci_pme_capable(struct pci_dev *dev, int pm, pci_power_t state) +static bool pci_pme_capable(struct pci_dev *dev, pci_power_t state) { - u16 pmc; - - if (!pm) + if (!dev->pm_cap) return false; - /* Check device's ability to generate PME# from given state */ - pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); - - pmc &= PCI_PM_CAP_PME_MASK; - pmc >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ - - return !!(pmc & (1 << state)); + return !!(dev->pme_support & (1 << state)); } /** * pci_pme_active - enable or disable PCI device's PME# function * @dev: PCI device to handle. - * @pm: PCI PM capability offset of the device. * @enable: 'true' to enable PME# generation; 'false' to disable it. * * The caller must verify that the device is capable of generating PME# before * calling this function with @enable equal to 'true'. */ -static void pci_pme_active(struct pci_dev *dev, int pm, bool enable) +static void pci_pme_active(struct pci_dev *dev, bool enable) { u16 pmcsr; - if (!pm) + if (!dev->pm_cap) return; - pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); /* Clear PME_Status by writing 1 to it and enable PME# */ pmcsr |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE; if (!enable) pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; - pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr); + pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); dev_printk(KERN_INFO, &dev->dev, "PME# %s\n", enable ? "enabled" : "disabled"); @@ -1118,7 +1095,6 @@ static void pci_pme_active(struct pci_dev *dev, int pm, bool enable) */ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { - int pm; int error = 0; bool pme_done = false; @@ -1134,9 +1110,8 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) if (!enable && platform_pci_can_wakeup(dev)) error = platform_pci_sleep_wake(dev, false); - pm = pci_find_capability(dev, PCI_CAP_ID_PM); - if (!enable || pci_pme_capable(dev, pm, state)) { - pci_pme_active(dev, pm, enable); + if (!enable || pci_pme_capable(dev, state)) { + pci_pme_active(dev, enable); pme_done = true; } @@ -1158,7 +1133,6 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) int pci_prepare_to_sleep(struct pci_dev *dev) { pci_power_t target_state = PCI_D3hot; - int pm = pci_find_capability(dev, PCI_CAP_ID_PM); int error; if (platform_pci_power_manageable(dev)) { @@ -1186,23 +1160,14 @@ int pci_prepare_to_sleep(struct pci_dev *dev) * wake-up events, make it the target state and enable device * to generate PME#. */ - u16 pmc; - - if (!pm) + if (!dev->pm_cap) return -EIO; - pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); - if (pmc & PCI_PM_CAP_PME_MASK) { - if (!(pmc & PCI_PM_CAP_PME_D3)) { - /* Device cannot generate PME# from D3_hot */ - if (pmc & PCI_PM_CAP_PME_D2) - target_state = PCI_D2; - else if (pmc & PCI_PM_CAP_PME_D1) - target_state = PCI_D1; - else - target_state = PCI_D0; - } - pci_pme_active(dev, pm, true); + if (dev->pme_support) { + while (target_state + && !(dev->pme_support & (1 << target_state))) + target_state--; + pci_pme_active(dev, true); } } @@ -1236,6 +1201,8 @@ void pci_pm_init(struct pci_dev *dev) int pm; u16 pmc; + dev->pm_cap = 0; + /* find PCI PM capability in list */ pm = pci_find_capability(dev, PCI_CAP_ID_PM); if (!pm) @@ -1249,7 +1216,23 @@ void pci_pm_init(struct pci_dev *dev) return; } - if (pmc & PCI_PM_CAP_PME_MASK) { + dev->pm_cap = pm; + + dev->d1_support = false; + dev->d2_support = false; + if (!pci_no_d1d2(dev)) { + if (pmc & PCI_PM_CAP_D1) { + dev_printk(KERN_DEBUG, &dev->dev, "supports D1\n"); + dev->d1_support = true; + } + if (pmc & PCI_PM_CAP_D2) { + dev_printk(KERN_DEBUG, &dev->dev, "supports D2\n"); + dev->d2_support = true; + } + } + + pmc &= PCI_PM_CAP_PME_MASK; + if (pmc) { dev_printk(KERN_INFO, &dev->dev, "PME# supported from%s%s%s%s%s\n", (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", @@ -1257,6 +1240,7 @@ void pci_pm_init(struct pci_dev *dev) (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); + dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; /* * Make device's PM flags reflect the wake-up capability, but * let the user space enable it to wake up the system as needed. @@ -1264,7 +1248,9 @@ void pci_pm_init(struct pci_dev *dev) device_set_wakeup_capable(&dev->dev, true); device_set_wakeup_enable(&dev->dev, false); /* Disable the PME# generation functionality */ - pci_pme_active(dev, pm, false); + pci_pme_active(dev, false); + } else { + dev->pme_support = 0; } } diff --git a/include/linux/pci.h b/include/linux/pci.h index 52ac06d..68a29f0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -177,6 +177,13 @@ struct pci_dev { pci_power_t current_state; /* Current operating state. In ACPI-speak, this is D0-D3, D0 being fully functional, and D3 being off. */ + int pm_cap; /* PM capability offset in the + configuration space */ + unsigned int pme_support:5; /* Bitmask of states from which PME# + can be generated */ + unsigned int d1_support:1; /* Low power state D1 is supported */ + unsigned int d2_support:1; /* Low power state D2 is supported */ + unsigned int no_d1d2:1; /* Only allow D0 and D3 */ #ifdef CONFIG_PCIEASPM struct pcie_link_state *link_state; /* ASPM link state. */ @@ -201,7 +208,6 @@ struct pci_dev { unsigned int is_added:1; unsigned int is_busmaster:1; /* device is busmaster */ unsigned int no_msi:1; /* device may not use msi */ - unsigned int no_d1d2:1; /* only allow d0 or d3 */ unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ unsigned int broken_parity_status:1; /* Device generates false positive parity */ unsigned int msi_enabled:1; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index c0c1223..19958b9 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -231,6 +231,7 @@ #define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */ #define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */ #define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ +#define PCI_PM_CAP_PME_SHIFT 11 /* Start of the PME Mask in PMC */ #define PCI_PM_CTRL 4 /* PM control and status register */ #define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ #define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */ -- cgit v0.10.2 From a05fe0389b72f43b9e29d6fbfc5885084be2f96f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 8 Jul 2008 22:15:40 +1000 Subject: stacktrace: fix build failure on sparc64 Today's linux-next build (spac64 allmodconfig) failed like this: arch/sparc64/kernel/stacktrace.c:50: warning: type defaults to `int' in declaration of `EXPORT_SYMBOL_GPL' arch/sparc64/kernel/stacktrace.c:50: warning: parameter names (without types) in function declaration arch/sparc64/kernel/stacktrace.c:50: warning: data definition has no type or storage class Signed-off-by: Stephen Rothwell Cc: "David S. Miller" Signed-off-by: Ingo Molnar diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index 49656ed..b3e3737 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From 69ac9cd629ca96e59f34eb4ccd12d00b2c8276a7 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Fri, 27 Jun 2008 13:12:54 +0200 Subject: sysfs: add /sys/firmware/memmap This patch adds /sys/firmware/memmap interface that represents the BIOS (or Firmware) provided memory map. The tree looks like: /sys/firmware/memmap/0/start (hex number) end (hex number) type (string) ... /1/start end type With the following shell snippet one can print the memory map in the same form the kernel prints itself when booting on x86 (the E820 map). --------- 8< -------------------------- #!/bin/sh cd /sys/firmware/memmap for dir in * ; do start=$(cat $dir/start) end=$(cat $dir/end) type=$(cat $dir/type) printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type" done --------- >8 -------------------------- That patch only provides the needed interface: 1. The sysfs interface. 2. The structure and enumeration definition. 3. The function firmware_map_add() and firmware_map_add_early() that should be called from architecture code (E820/EFI, for example) to add the contents to the interface. If the kernel is compiled without CONFIG_FIRMWARE_MEMMAP, the interface does nothing without cluttering the architecture-specific code with #ifdef's. The purpose of the new interface is kexec: While /proc/iomem represents the *used* memory map (e.g. modified via kernel parameters like 'memmap' and 'mem'), the /sys/firmware/memmap tree represents the unmodified memory map provided via the firmware. So kexec can: - use the original memory map for rebooting, - use the /proc/iomem for setting up the ELF core headers for kdump case that should only represent the memory of the system. The patch has been tested on i386 and x86_64. Signed-off-by: Bernhard Walle Acked-by: Greg KH Acked-by: Vivek Goyal Cc: kexec@lists.infradead.org Cc: yhlu.kernel@gmail.com Signed-off-by: Ingo Molnar diff --git a/Documentation/ABI/testing/sysfs-firmware-memmap b/Documentation/ABI/testing/sysfs-firmware-memmap new file mode 100644 index 0000000..0d99ee6 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-memmap @@ -0,0 +1,71 @@ +What: /sys/firmware/memmap/ +Date: June 2008 +Contact: Bernhard Walle +Description: + On all platforms, the firmware provides a memory map which the + kernel reads. The resources from that memory map are registered + in the kernel resource tree and exposed to userspace via + /proc/iomem (together with other resources). + + However, on most architectures that firmware-provided memory + map is modified afterwards by the kernel itself, either because + the kernel merges that memory map with other information or + just because the user overwrites that memory map via command + line. + + kexec needs the raw firmware-provided memory map to setup the + parameter segment of the kernel that should be booted with + kexec. Also, the raw memory map is useful for debugging. For + that reason, /sys/firmware/memmap is an interface that provides + the raw memory map to userspace. + + The structure is as follows: Under /sys/firmware/memmap there + are subdirectories with the number of the entry as their name: + + /sys/firmware/memmap/0 + /sys/firmware/memmap/1 + /sys/firmware/memmap/2 + /sys/firmware/memmap/3 + ... + + The maximum depends on the number of memory map entries provided + by the firmware. The order is just the order that the firmware + provides. + + Each directory contains three files: + + start : The start address (as hexadecimal number with the + '0x' prefix). + end : The end address, inclusive (regardless whether the + firmware provides inclusive or exclusive ranges). + type : Type of the entry as string. See below for a list of + valid types. + + So, for example: + + /sys/firmware/memmap/0/start + /sys/firmware/memmap/0/end + /sys/firmware/memmap/0/type + /sys/firmware/memmap/1/start + ... + + Currently following types exist: + + - System RAM + - ACPI Tables + - ACPI Non-volatile Storage + - reserved + + Following shell snippet can be used to display that memory + map in a human-readable format: + + -------------------- 8< ---------------------------------------- + #!/bin/bash + cd /sys/firmware/memmap + for dir in * ; do + start=$(cat $dir/start) + end=$(cat $dir/end) + type=$(cat $dir/type) + printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type" + done + -------------------- >8 ---------------------------------------- diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index dc2cec6..ebb9e51 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -26,6 +26,16 @@ config EDD_OFF kernel. Say N if you want EDD enabled by default. EDD can be dynamically set using the kernel parameter 'edd={on|skipmbr|off}'. +config FIRMWARE_MEMMAP + bool "Add firmware-provided memory map to sysfs" if EMBEDDED + default (X86_64 || X86_32) + help + Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap. + That memory map is used for example by kexec to set up parameter area + for the next kernel, but can also be used for debugging purposes. + + See also Documentation/ABI/testing/sysfs-firmware-memmap. + config EFI_VARS tristate "EFI Variable Support via sysfs" depends on EFI diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 4c91471..1c3c173 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_DCDBAS) += dcdbas.o obj-$(CONFIG_DMIID) += dmi-id.o obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o +obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c new file mode 100644 index 0000000..e23399c --- /dev/null +++ b/drivers/firmware/memmap.c @@ -0,0 +1,205 @@ +/* + * linux/drivers/firmware/memmap.c + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle + * + * 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 + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +/* + * Data types ------------------------------------------------------------------ + */ + +/* + * Firmware map entry. Because firmware memory maps are flat and not + * hierarchical, it's ok to organise them in a linked list. No parent + * information is necessary as for the resource tree. + */ +struct firmware_map_entry { + resource_size_t start; /* start of the memory range */ + resource_size_t end; /* end of the memory range (incl.) */ + const char *type; /* type of the memory range */ + struct list_head list; /* entry for the linked list */ + struct kobject kobj; /* kobject for each entry */ +}; + +/* + * Forward declarations -------------------------------------------------------- + */ +static ssize_t memmap_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf); +static ssize_t start_show(struct firmware_map_entry *entry, char *buf); +static ssize_t end_show(struct firmware_map_entry *entry, char *buf); +static ssize_t type_show(struct firmware_map_entry *entry, char *buf); + +/* + * Static data ----------------------------------------------------------------- + */ + +struct memmap_attribute { + struct attribute attr; + ssize_t (*show)(struct firmware_map_entry *entry, char *buf); +}; + +struct memmap_attribute memmap_start_attr = __ATTR_RO(start); +struct memmap_attribute memmap_end_attr = __ATTR_RO(end); +struct memmap_attribute memmap_type_attr = __ATTR_RO(type); + +/* + * These are default attributes that are added for every memmap entry. + */ +static struct attribute *def_attrs[] = { + &memmap_start_attr.attr, + &memmap_end_attr.attr, + &memmap_type_attr.attr, + NULL +}; + +static struct sysfs_ops memmap_attr_ops = { + .show = memmap_attr_show, +}; + +static struct kobj_type memmap_ktype = { + .sysfs_ops = &memmap_attr_ops, + .default_attrs = def_attrs, +}; + +/* + * Registration functions ------------------------------------------------------ + */ + +/* + * Firmware memory map entries + */ +static LIST_HEAD(map_entries); + +/** + * Common implementation of firmware_map_add() and firmware_map_add_early() + * which expects a pre-allocated struct firmware_map_entry. + * + * @start: Start of the memory range. + * @end: End of the memory range (inclusive). + * @type: Type of the memory range. + * @entry: Pre-allocated (either kmalloc() or bootmem allocator), uninitialised + * entry. + */ +static int firmware_map_add_entry(resource_size_t start, resource_size_t end, + const char *type, + struct firmware_map_entry *entry) +{ + BUG_ON(start > end); + + entry->start = start; + entry->end = end; + entry->type = type; + INIT_LIST_HEAD(&entry->list); + kobject_init(&entry->kobj, &memmap_ktype); + + list_add_tail(&entry->list, &map_entries); + + return 0; +} + +/* + * See for documentation. + */ +int firmware_map_add(resource_size_t start, resource_size_t end, + const char *type) +{ + struct firmware_map_entry *entry; + + entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC); + WARN_ON(!entry); + if (!entry) + return -ENOMEM; + + return firmware_map_add_entry(start, end, type, entry); +} + +/* + * See for documentation. + */ +int __init firmware_map_add_early(resource_size_t start, resource_size_t end, + const char *type) +{ + struct firmware_map_entry *entry; + + entry = alloc_bootmem_low(sizeof(struct firmware_map_entry)); + WARN_ON(!entry); + if (!entry) + return -ENOMEM; + + return firmware_map_add_entry(start, end, type, entry); +} + +/* + * Sysfs functions ------------------------------------------------------------- + */ + +static ssize_t start_show(struct firmware_map_entry *entry, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->start); +} + +static ssize_t end_show(struct firmware_map_entry *entry, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->end); +} + +static ssize_t type_show(struct firmware_map_entry *entry, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", entry->type); +} + +#define to_memmap_attr(_attr) container_of(_attr, struct memmap_attribute, attr) +#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj) + +static ssize_t memmap_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct firmware_map_entry *entry = to_memmap_entry(kobj); + struct memmap_attribute *memmap_attr = to_memmap_attr(attr); + + return memmap_attr->show(entry, buf); +} + +/* + * Initialises stuff and adds the entries in the map_entries list to + * sysfs. Important is that firmware_map_add() and firmware_map_add_early() + * must be called before late_initcall. + */ +static int __init memmap_init(void) +{ + int i = 0; + struct firmware_map_entry *entry; + struct kset *memmap_kset; + + memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj); + WARN_ON(!memmap_kset); + if (!memmap_kset) + return -ENOMEM; + + list_for_each_entry(entry, &map_entries, list) { + entry->kobj.kset = memmap_kset; + kobject_add(&entry->kobj, NULL, "%d", i++); + } + + return 0; +} +late_initcall(memmap_init); + diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h new file mode 100644 index 0000000..acbdbcc --- /dev/null +++ b/include/linux/firmware-map.h @@ -0,0 +1,74 @@ +/* + * include/linux/firmware-map.h: + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle + * + * 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 + * 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. + * + */ +#ifndef _LINUX_FIRMWARE_MAP_H +#define _LINUX_FIRMWARE_MAP_H + +#include +#include + +/* + * provide a dummy interface if CONFIG_FIRMWARE_MEMMAP is disabled + */ +#ifdef CONFIG_FIRMWARE_MEMMAP + +/** + * Adds a firmware mapping entry. This function uses kmalloc() for memory + * allocation. Use firmware_map_add_early() if you want to use the bootmem + * allocator. + * + * That function must be called before late_initcall. + * + * @start: Start of the memory range. + * @end: End of the memory range (inclusive). + * @type: Type of the memory range. + * + * Returns 0 on success, or -ENOMEM if no memory could be allocated. + */ +int firmware_map_add(resource_size_t start, resource_size_t end, + const char *type); + +/** + * Adds a firmware mapping entry. This function uses the bootmem allocator + * for memory allocation. Use firmware_map_add() if you want to use kmalloc(). + * + * That function must be called before late_initcall. + * + * @start: Start of the memory range. + * @end: End of the memory range (inclusive). + * @type: Type of the memory range. + * + * Returns 0 on success, or -ENOMEM if no memory could be allocated. + */ +int firmware_map_add_early(resource_size_t start, resource_size_t end, + const char *type); + +#else /* CONFIG_FIRMWARE_MEMMAP */ + +static inline int firmware_map_add(resource_size_t start, resource_size_t end, + const char *type) +{ + return 0; +} + +static inline int firmware_map_add_early(resource_size_t start, + resource_size_t end, const char *type) +{ + return 0; +} + +#endif /* CONFIG_FIRMWARE_MEMMAP */ + +#endif /* _LINUX_FIRMWARE_MAP_H */ -- cgit v0.10.2 From 5dfcf14d5b28174f94cbe9b4fb35d415db61c64a Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Fri, 27 Jun 2008 13:12:55 +0200 Subject: x86: use FIRMWARE_MEMMAP on x86/E820 This patch uses the /sys/firmware/memmap interface provided in the last patch on the x86 architecture when E820 is used. The patch copies the E820 memory map very early, and registers the E820 map afterwards via firmware_map_add_early(). Signed-off-by: Bernhard Walle Acked-by: Greg KH Acked-by: Vivek Goyal Cc: kexec@lists.infradead.org Cc: yhlu.kernel@gmail.com Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index d033585..fc1d579 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,22 @@ #include #include +/* + * The e820 map is the map that gets modified e.g. with command line parameters + * and that is also registered with modifications in the kernel resource tree + * with the iomem_resource as parent. + * + * The e820_saved is directly saved after the BIOS-provided memory map is + * copied. It doesn't get modified afterwards. It's registered for the + * /sys/firmware/memmap interface. + * + * That memory map is not modified and is used as base for kexec. The kexec'd + * kernel should get the same memory map as the firmware provides. Then the + * user can e.g. boot the original kernel with mem=1G while still booting the + * next kernel with full memory. + */ struct e820map e820; +struct e820map e820_saved; /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0xaeedbabe; @@ -1198,6 +1214,17 @@ void __init finish_e820_parsing(void) } } +static inline const char *e820_type_to_string(int e820_type) +{ + switch (e820_type) { + case E820_RESERVED_KERN: + case E820_RAM: return "System RAM"; + case E820_ACPI: return "ACPI Tables"; + case E820_NVS: return "ACPI Non-volatile Storage"; + default: return "reserved"; + } +} + /* * Mark e820 reserved areas as busy for the resource manager. */ @@ -1209,13 +1236,6 @@ void __init e820_reserve_resources(void) res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map); for (i = 0; i < e820.nr_map; i++) { - switch (e820.map[i].type) { - case E820_RESERVED_KERN: - case E820_RAM: res->name = "System RAM"; break; - case E820_ACPI: res->name = "ACPI Tables"; break; - case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; - default: res->name = "reserved"; - } end = e820.map[i].addr + e820.map[i].size - 1; #ifndef CONFIG_RESOURCES_64BIT if (end > 0x100000000ULL) { @@ -1223,6 +1243,7 @@ void __init e820_reserve_resources(void) continue; } #endif + res->name = e820_type_to_string(e820.map[i].type); res->start = e820.map[i].addr; res->end = end; @@ -1230,6 +1251,13 @@ void __init e820_reserve_resources(void) insert_resource(&iomem_resource, res); res++; } + + for (i = 0; i < e820_saved.nr_map; i++) { + struct e820entry *entry = &e820_saved.map[i]; + firmware_map_add_early(entry->addr, + entry->addr + entry->size - 1, + e820_type_to_string(entry->type)); + } } char *__init default_machine_specific_memory_setup(void) @@ -1266,6 +1294,8 @@ char *__init default_machine_specific_memory_setup(void) e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM); } + memcpy(&e820_saved, &e820, sizeof(struct e820map)); + /* In case someone cares... */ return who; } diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 4b26604..a20d0a7f 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -59,7 +59,9 @@ struct e820map { struct e820entry map[E820_X_MAX]; }; +/* see comment in arch/x86/kernel/e820.c */ extern struct e820map e820; +extern struct e820map e820_saved; extern int e820_any_mapped(u64 start, u64 end, unsigned type); extern int e820_all_mapped(u64 start, u64 end, unsigned type); -- cgit v0.10.2 From f7a1b86095bf7fd1578ef54067545b9cb7084713 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 15:00:54 +0100 Subject: Fix acpi_pm_device_sleep_wake() by providing a stub for CONFIG_PM_SLEEP=n So that one of the several config option permutations will build again. Tested-by: Alexander Beregalov Signed-off-by: David Howells Signed-off-by: Jesse Barnes diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 7ab5a61..a5ac0bc 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -388,6 +388,10 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p) *p = ACPI_STATE_D0; return ACPI_STATE_D3; } +static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) +{ + return -ENODEV; +} #endif /* !CONFIG_PM_SLEEP */ #endif /* CONFIG_ACPI */ -- cgit v0.10.2 From 46deed69b34d0aa6065e92ad79685e103d4ccd35 Mon Sep 17 00:00:00 2001 From: Luke Browning Date: Mon, 16 Jun 2008 11:36:43 +1000 Subject: powerpc/spufs: provide context debug file Add a ctxt file to spufs that shows spu context information that is used in scheduling. This info can be used for debugging spufs scheduler issues, and to isolate between application and spufs problems as it shows a lot of state such as priorities and dispatch counts. This file contains internal spufs state and is subject to change at any time, and therefore no applications should depend on it. The file is intended for the use of spufs kernel developers. Signed-off-by: Luke Browning Signed-off-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index f742599..fc595d0 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2555,6 +2555,58 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx, wake_up(&ctx->switch_log->wait); } +static int spufs_show_ctx(struct seq_file *s, void *private) +{ + struct spu_context *ctx = s->private; + u64 mfc_control_RW; + + mutex_lock(&ctx->state_mutex); + if (ctx->spu) { + struct spu *spu = ctx->spu; + struct spu_priv2 __iomem *priv2 = spu->priv2; + + spin_lock_irq(&spu->register_lock); + mfc_control_RW = in_be64(&priv2->mfc_control_RW); + spin_unlock_irq(&spu->register_lock); + } else { + struct spu_state *csa = &ctx->csa; + + mfc_control_RW = csa->priv2.mfc_control_RW; + } + + seq_printf(s, "%c flgs(%lx) sflgs(%lx) pri(%d) ts(%d) spu(%02d)" + " %c %lx %lx %lx %lx %x %x\n", + ctx->state == SPU_STATE_SAVED ? 'S' : 'R', + ctx->flags, + ctx->sched_flags, + ctx->prio, + ctx->time_slice, + ctx->spu ? ctx->spu->number : -1, + !list_empty(&ctx->rq) ? 'q' : ' ', + ctx->csa.class_0_pending, + ctx->csa.class_0_dar, + ctx->csa.class_1_dsisr, + mfc_control_RW, + ctx->ops->runcntl_read(ctx), + ctx->ops->status_read(ctx)); + + mutex_unlock(&ctx->state_mutex); + + return 0; +} + +static int spufs_ctx_open(struct inode *inode, struct file *file) +{ + return single_open(file, spufs_show_ctx, SPUFS_I(inode)->i_ctx); +} + +static const struct file_operations spufs_ctx_fops = { + .open = spufs_ctx_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + struct tree_descr spufs_dir_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, { "mem", &spufs_mem_fops, 0666, }, @@ -2591,6 +2643,7 @@ struct tree_descr spufs_dir_contents[] = { { "tid", &spufs_tid_fops, 0444, }, { "stat", &spufs_stat_fops, 0444, }, { "switch_log", &spufs_switch_log_fops, 0444 }, + { ".ctx", &spufs_ctx_fops, 0444, }, {}, }; @@ -2616,6 +2669,7 @@ struct tree_descr spufs_dir_nosched_contents[] = { { "object-id", &spufs_object_id_ops, 0666, }, { "tid", &spufs_tid_fops, 0444, }, { "stat", &spufs_stat_fops, 0444, }, + { ".ctx", &spufs_ctx_fops, 0444, }, {}, }; -- cgit v0.10.2 From 2442a8ba5abe2c27c572bc522da1c33df98c6ec7 Mon Sep 17 00:00:00 2001 From: Luke Browning Date: Fri, 6 Jun 2008 11:26:54 +0800 Subject: powerpc/spufs: don't extend time time slice if context is not in spu_run An spu context shouldn't get an extra tick if the time slice code couldn't find something else to run. This means contexts that are not within spu_run (ie, SPU_SCHED_SPU_RUN is cleared) will not receive extra ticks while we have no other contexts waiting. Signed-off-by: Luke Browning Signed-off-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index e929e70..afb92d4 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -899,7 +899,8 @@ static noinline void spusched_tick(struct spu_context *ctx) spu_add_to_rq(ctx); } else { spu_context_nospu_trace(spusched_tick__newslice, ctx); - ctx->time_slice++; + if (!ctx->time_slice) + ctx->time_slice++; } out: spu_release(ctx); -- cgit v0.10.2 From 87ff6090bfe416c71730654ab53cd4ecffdd675e Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 1 Jul 2008 10:22:50 +1000 Subject: powerpc/spufs: avoid magic numbers for mapping sizes Use a set of #defines for the size of context mappings, instead of magic numbers. Signed-off-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 177735f..6653ddb 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -130,17 +130,17 @@ void spu_unmap_mappings(struct spu_context *ctx) if (ctx->local_store) unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); if (ctx->mfc) - unmap_mapping_range(ctx->mfc, 0, 0x1000, 1); + unmap_mapping_range(ctx->mfc, 0, SPUFS_MFC_MAP_SIZE, 1); if (ctx->cntl) - unmap_mapping_range(ctx->cntl, 0, 0x1000, 1); + unmap_mapping_range(ctx->cntl, 0, SPUFS_CNTL_MAP_SIZE, 1); if (ctx->signal1) - unmap_mapping_range(ctx->signal1, 0, PAGE_SIZE, 1); + unmap_mapping_range(ctx->signal1, 0, SPUFS_SIGNAL_MAP_SIZE, 1); if (ctx->signal2) - unmap_mapping_range(ctx->signal2, 0, PAGE_SIZE, 1); + unmap_mapping_range(ctx->signal2, 0, SPUFS_SIGNAL_MAP_SIZE, 1); if (ctx->mss) - unmap_mapping_range(ctx->mss, 0, 0x1000, 1); + unmap_mapping_range(ctx->mss, 0, SPUFS_MSS_MAP_SIZE, 1); if (ctx->psmap) - unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); + unmap_mapping_range(ctx->psmap, 0, SPUFS_PS_MAP_SIZE, 1); mutex_unlock(&ctx->mapping_lock); } diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index fc595d0..d0a497d 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -410,7 +410,7 @@ refault: static int spufs_cntl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_fault(vma, vmf, 0x4000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x4000, SPUFS_CNTL_MAP_SIZE); } static struct vm_operations_struct spufs_cntl_mmap_vmops = { @@ -1102,13 +1102,13 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, static int spufs_signal1_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { -#if PAGE_SIZE == 0x1000 - return spufs_ps_fault(vma, vmf, 0x14000, 0x1000); -#elif PAGE_SIZE == 0x10000 +#if SPUFS_SIGNAL_MAP_SIZE == 0x1000 + return spufs_ps_fault(vma, vmf, 0x14000, SPUFS_SIGNAL_MAP_SIZE); +#elif SPUFS_SIGNAL_MAP_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_fault(vma, vmf, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE); #else #error unsupported page size #endif @@ -1239,13 +1239,13 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, static int spufs_signal2_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { -#if PAGE_SIZE == 0x1000 - return spufs_ps_fault(vma, vmf, 0x1c000, 0x1000); -#elif PAGE_SIZE == 0x10000 +#if SPUFS_SIGNAL_MAP_SIZE == 0x1000 + return spufs_ps_fault(vma, vmf, 0x1c000, SPUFS_SIGNAL_MAP_SIZE); +#elif SPUFS_SIGNAL_MAP_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_fault(vma, vmf, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE); #else #error unsupported page size #endif @@ -1367,7 +1367,7 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, static int spufs_mss_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_fault(vma, vmf, 0x0000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_MSS_MAP_SIZE); } static struct vm_operations_struct spufs_mss_mmap_vmops = { @@ -1429,7 +1429,7 @@ static const struct file_operations spufs_mss_fops = { static int spufs_psmap_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_fault(vma, vmf, 0x0000, 0x20000); + return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_PS_MAP_SIZE); } static struct vm_operations_struct spufs_psmap_mmap_vmops = { @@ -1489,7 +1489,7 @@ static const struct file_operations spufs_psmap_fops = { static int spufs_mfc_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_fault(vma, vmf, 0x3000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x3000, SPUFS_MFC_MAP_SIZE); } static struct vm_operations_struct spufs_mfc_mmap_vmops = { diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 454c277..433dece 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -32,6 +32,13 @@ #include #include +#define SPUFS_PS_MAP_SIZE 0x20000 +#define SPUFS_MFC_MAP_SIZE 0x1000 +#define SPUFS_CNTL_MAP_SIZE 0x1000 +#define SPUFS_CNTL_MAP_SIZE 0x1000 +#define SPUFS_SIGNAL_MAP_SIZE PAGE_SIZE +#define SPUFS_MSS_MAP_SIZE 0x1000 + /* The magic number for our file system */ enum { SPUFS_MAGIC = 0x23c9b64e, -- cgit v0.10.2 From 23d893f51cde7013e4c29094da2237cce4f20035 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 30 Jun 2008 12:17:28 +1000 Subject: powerpc/spufs: allow spufs files to specify sizes Currently, spufs never specifies the i_size for the files in context directories, so stat() always reports 0-byte files. This change adds allows the spufs_dir_(nosched_)contents arrays to specify a file size. This allows stat() to report correct file sizes, and makes SEEK_END work. Signed-off-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index d0a497d..9533a8a 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2607,7 +2607,7 @@ static const struct file_operations spufs_ctx_fops = { .release = single_release, }; -struct tree_descr spufs_dir_contents[] = { +struct spufs_tree_descr spufs_dir_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, { "mem", &spufs_mem_fops, 0666, }, { "regs", &spufs_regs_fops, 0666, }, @@ -2647,7 +2647,7 @@ struct tree_descr spufs_dir_contents[] = { {}, }; -struct tree_descr spufs_dir_nosched_contents[] = { +struct spufs_tree_descr spufs_dir_nosched_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, { "mem", &spufs_mem_fops, 0666, }, { "mbox", &spufs_mbox_fops, 0444, }, diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index f407b24..c662ca7 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -109,7 +109,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr) static int spufs_new_file(struct super_block *sb, struct dentry *dentry, const struct file_operations *fops, int mode, - struct spu_context *ctx) + size_t size, struct spu_context *ctx) { static struct inode_operations spufs_file_iops = { .setattr = spufs_setattr, @@ -125,6 +125,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, ret = 0; inode->i_op = &spufs_file_iops; inode->i_fop = fops; + inode->i_size = size; inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); d_add(dentry, inode); out: @@ -177,7 +178,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir) return simple_rmdir(parent, dir); } -static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, +static int spufs_fill_dir(struct dentry *dir, struct spufs_tree_descr *files, int mode, struct spu_context *ctx) { struct dentry *dentry, *tmp; @@ -189,7 +190,7 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, if (!dentry) goto out; ret = spufs_new_file(dir->d_sb, dentry, files->ops, - files->mode & mode, ctx); + files->mode & mode, files->size, ctx); if (ret) goto out; files++; diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 433dece..4136054 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -235,8 +235,15 @@ struct spufs_inode_info { #define SPUFS_I(inode) \ container_of(inode, struct spufs_inode_info, vfs_inode) -extern struct tree_descr spufs_dir_contents[]; -extern struct tree_descr spufs_dir_nosched_contents[]; +struct spufs_tree_descr { + const char *name; + const struct file_operations *ops; + int mode; + size_t size; +}; + +extern struct spufs_tree_descr spufs_dir_contents[]; +extern struct spufs_tree_descr spufs_dir_nosched_contents[]; /* system call implementation */ extern struct spufs_calls spufs_calls; -- cgit v0.10.2 From 6f7dde812defe5bc49cf463ac1579ffeda5cbfd4 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 30 Jun 2008 14:38:37 +1000 Subject: powerpc/spufs: add sizes for context files Populate the size member of a few context files. Leave out files that have different semantics with read vs mmap, or contain a variable-length hex string. Signed-off-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 9533a8a..fee645b 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2609,20 +2609,20 @@ static const struct file_operations spufs_ctx_fops = { struct spufs_tree_descr spufs_dir_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, - { "mem", &spufs_mem_fops, 0666, }, - { "regs", &spufs_regs_fops, 0666, }, + { "mem", &spufs_mem_fops, 0666, LS_SIZE, }, + { "regs", &spufs_regs_fops, 0666, sizeof(struct spu_reg128[128]), }, { "mbox", &spufs_mbox_fops, 0444, }, { "ibox", &spufs_ibox_fops, 0444, }, { "wbox", &spufs_wbox_fops, 0222, }, - { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, - { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, - { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, + { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), }, + { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), }, + { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), }, { "signal1", &spufs_signal1_fops, 0666, }, { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, - { "fpcr", &spufs_fpcr_fops, 0666, }, + { "fpcr", &spufs_fpcr_fops, 0666, sizeof(struct spu_reg128), }, { "lslr", &spufs_lslr_ops, 0444, }, { "mfc", &spufs_mfc_fops, 0666, }, { "mss", &spufs_mss_fops, 0666, }, @@ -2632,14 +2632,16 @@ struct spufs_tree_descr spufs_dir_contents[] = { { "decr_status", &spufs_decr_status_ops, 0666, }, { "event_mask", &spufs_event_mask_ops, 0666, }, { "event_status", &spufs_event_status_ops, 0444, }, - { "psmap", &spufs_psmap_fops, 0666, }, + { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, - { "mbox_info", &spufs_mbox_info_fops, 0444, }, - { "ibox_info", &spufs_ibox_info_fops, 0444, }, - { "wbox_info", &spufs_wbox_info_fops, 0444, }, - { "dma_info", &spufs_dma_info_fops, 0444, }, - { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, + { "mbox_info", &spufs_mbox_info_fops, 0444, sizeof(u32), }, + { "ibox_info", &spufs_ibox_info_fops, 0444, sizeof(u32), }, + { "wbox_info", &spufs_wbox_info_fops, 0444, sizeof(u32), }, + { "dma_info", &spufs_dma_info_fops, 0444, + sizeof(struct spu_dma_info), }, + { "proxydma_info", &spufs_proxydma_info_fops, 0444, + sizeof(struct spu_proxydma_info)}, { "tid", &spufs_tid_fops, 0444, }, { "stat", &spufs_stat_fops, 0444, }, { "switch_log", &spufs_switch_log_fops, 0444 }, @@ -2649,13 +2651,13 @@ struct spufs_tree_descr spufs_dir_contents[] = { struct spufs_tree_descr spufs_dir_nosched_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, - { "mem", &spufs_mem_fops, 0666, }, + { "mem", &spufs_mem_fops, 0666, LS_SIZE, }, { "mbox", &spufs_mbox_fops, 0444, }, { "ibox", &spufs_ibox_fops, 0444, }, { "wbox", &spufs_wbox_fops, 0222, }, - { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, - { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, - { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, + { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), }, + { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), }, + { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), }, { "signal1", &spufs_signal1_nosched_fops, 0222, }, { "signal2", &spufs_signal2_nosched_fops, 0222, }, { "signal1_type", &spufs_signal1_type, 0666, }, @@ -2664,7 +2666,7 @@ struct spufs_tree_descr spufs_dir_nosched_contents[] = { { "mfc", &spufs_mfc_fops, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, { "npc", &spufs_npc_ops, 0666, }, - { "psmap", &spufs_psmap_fops, 0666, }, + { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, { "tid", &spufs_tid_fops, 0444, }, -- cgit v0.10.2 From 2c3e47871d18f93b8bc2892fb41432111201356d Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 3 Jul 2008 11:42:20 +1000 Subject: powerpc/spufs: only add ".ctx" file with "debug" mount option Currently, the .ctx debug file in spu context directories is always present. We'd prefer to prevent users from relying on this file, so add a "debug" mount option to spufs. The .ctx file will only be added to the context directories when this option is present. Signed-off-by: Jeremy Kerr diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index fee645b..99c7306 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2645,7 +2645,6 @@ struct spufs_tree_descr spufs_dir_contents[] = { { "tid", &spufs_tid_fops, 0444, }, { "stat", &spufs_stat_fops, 0444, }, { "switch_log", &spufs_switch_log_fops, 0444 }, - { ".ctx", &spufs_ctx_fops, 0444, }, {}, }; @@ -2671,6 +2670,10 @@ struct spufs_tree_descr spufs_dir_nosched_contents[] = { { "object-id", &spufs_object_id_ops, 0666, }, { "tid", &spufs_tid_fops, 0444, }, { "stat", &spufs_stat_fops, 0444, }, + {}, +}; + +struct spufs_tree_descr spufs_dir_debug_contents[] = { { ".ctx", &spufs_ctx_fops, 0444, }, {}, }; diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index c662ca7..7123472 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -42,10 +42,19 @@ #include "spufs.h" +struct spufs_sb_info { + int debug; +}; + static struct kmem_cache *spufs_inode_cache; char *isolated_loader; static int isolated_loader_size; +static struct spufs_sb_info *spufs_get_sb_info(struct super_block *sb) +{ + return sb->s_fs_info; +} + static struct inode * spufs_alloc_inode(struct super_block *sb) { @@ -280,6 +289,13 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, if (ret) goto out_free_ctx; + if (spufs_get_sb_info(dir->i_sb)->debug) + ret = spufs_fill_dir(dentry, spufs_dir_debug_contents, + mode, ctx); + + if (ret) + goto out_free_ctx; + d_instantiate(dentry, inode); dget(dentry); dir->i_nlink++; @@ -640,18 +656,19 @@ out: /* File system initialization */ enum { - Opt_uid, Opt_gid, Opt_mode, Opt_err, + Opt_uid, Opt_gid, Opt_mode, Opt_debug, Opt_err, }; static match_table_t spufs_tokens = { - { Opt_uid, "uid=%d" }, - { Opt_gid, "gid=%d" }, - { Opt_mode, "mode=%o" }, - { Opt_err, NULL }, + { Opt_uid, "uid=%d" }, + { Opt_gid, "gid=%d" }, + { Opt_mode, "mode=%o" }, + { Opt_debug, "debug" }, + { Opt_err, NULL }, }; static int -spufs_parse_options(char *options, struct inode *root) +spufs_parse_options(struct super_block *sb, char *options, struct inode *root) { char *p; substring_t args[MAX_OPT_ARGS]; @@ -679,6 +696,9 @@ spufs_parse_options(char *options, struct inode *root) return 0; root->i_mode = option | S_IFDIR; break; + case Opt_debug: + spufs_get_sb_info(sb)->debug = 1; + break; default: return 0; } @@ -737,7 +757,7 @@ spufs_create_root(struct super_block *sb, void *data) SPUFS_I(inode)->i_ctx = NULL; ret = -EINVAL; - if (!spufs_parse_options(data, inode)) + if (!spufs_parse_options(sb, data, inode)) goto out_iput; ret = -ENOMEM; @@ -755,6 +775,7 @@ out: static int spufs_fill_super(struct super_block *sb, void *data, int silent) { + struct spufs_sb_info *info; static struct super_operations s_ops = { .alloc_inode = spufs_alloc_inode, .destroy_inode = spufs_destroy_inode, @@ -766,11 +787,16 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) save_mount_options(sb, data); + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = SPUFS_MAGIC; sb->s_op = &s_ops; + sb->s_fs_info = info; return spufs_create_root(sb, data); } diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 4136054..8ae8ef9 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -244,6 +244,7 @@ struct spufs_tree_descr { extern struct spufs_tree_descr spufs_dir_contents[]; extern struct spufs_tree_descr spufs_dir_nosched_contents[]; +extern struct spufs_tree_descr spufs_dir_debug_contents[]; /* system call implementation */ extern struct spufs_calls spufs_calls; -- cgit v0.10.2 From 0be15526beb4c228e0477221c62ec8ab0fc7440f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 3 Jul 2008 11:35:37 -0700 Subject: x86: move saving e820_saved to setup_memory_map so other path that will override memory_setup or machine_specific_memory_setup could have e820_saved too. Signed-off-by: Yinghai Lu Cc: Jeremy Fitzhardinge Cc: Bernhard Walle Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index fc1d579..13e3298 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1294,8 +1294,6 @@ char *__init default_machine_specific_memory_setup(void) e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM); } - memcpy(&e820_saved, &e820, sizeof(struct e820map)); - /* In case someone cares... */ return who; } @@ -1313,8 +1311,12 @@ char * __init __attribute__((weak)) memory_setup(void) void __init setup_memory_map(void) { + char *who; + + who = memory_setup(); + memcpy(&e820_saved, &e820, sizeof(struct e820map)); printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - e820_print_map(memory_setup()); + e820_print_map(who); } #ifdef CONFIG_X86_64 -- cgit v0.10.2 From a0a0becd2da0ba0d7f0204a61d1905926cdb163d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 3 Jul 2008 11:37:13 -0700 Subject: x86: make e820_saved have update from setup_data seperate reserve_setup_data into e820_reserved_setup_data, and reserve_early_setup_data. So could use e820_reserved_setup_data to backup e820 with setup_data. Signed-off-by: Yinghai Lu Cc: Bernhard Walle Cc: Ying Huang Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index cfcfbef..bea8ae7 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -394,11 +394,10 @@ static void __init parse_setup_data(void) } } -static void __init reserve_setup_data(void) +static void __init e820_reserve_setup_data(void) { struct setup_data *data; u64 pa_data; - char buf[32]; int found = 0; if (boot_params.hdr.version < 0x0209) @@ -406,8 +405,6 @@ static void __init reserve_setup_data(void) pa_data = boot_params.hdr.setup_data; while (pa_data) { data = early_ioremap(pa_data, sizeof(*data)); - sprintf(buf, "setup data %x", data->type); - reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf); e820_update_range(pa_data, sizeof(*data)+data->len, E820_RAM, E820_RESERVED_KERN); found = 1; @@ -418,10 +415,29 @@ static void __init reserve_setup_data(void) return; sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); + memcpy(&e820_saved, &e820, sizeof(struct e820map)); printk(KERN_INFO "extended physical RAM map:\n"); e820_print_map("reserve setup_data"); } +static void __init reserve_early_setup_data(void) +{ + struct setup_data *data; + u64 pa_data; + char buf[32]; + + if (boot_params.hdr.version < 0x0209) + return; + pa_data = boot_params.hdr.setup_data; + while (pa_data) { + data = early_ioremap(pa_data, sizeof(*data)); + sprintf(buf, "setup data %x", data->type); + reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf); + pa_data = data->next; + early_iounmap(data, sizeof(*data)); + } +} + /* * --------- Crashkernel reservation ------------------------------ */ @@ -626,6 +642,8 @@ void __init setup_arch(char **cmdline_p) setup_memory_map(); parse_setup_data(); + /* update the e820_saved too */ + e820_reserve_setup_data(); copy_edd(); @@ -656,7 +674,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); /* after early param, so could get panic from serial */ - reserve_setup_data(); + reserve_early_setup_data(); if (acpi_mps_check()) { #ifdef CONFIG_X86_LOCAL_APIC -- cgit v0.10.2 From fc9036ea1a4b14229788e6df3936b451a6abac98 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 3 Jul 2008 11:39:00 -0700 Subject: x86: let early_reserve_e820 update e820_saved too so when it is called after early_param, e820_saved get updated too. esp for mpc update. Signed-off-by: Yinghai Lu Cc: Bernhard Walle Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 13e3298..e07d401 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -414,8 +414,9 @@ static int __init append_e820_map(struct e820entry *biosmap, int nr_map) return __append_e820_map(biosmap, nr_map); } -u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, - unsigned new_type) +static u64 __init e820_update_range_map(struct e820map *e820x, u64 start, + u64 size, unsigned old_type, + unsigned new_type) { int i; u64 real_updated_size = 0; @@ -426,7 +427,7 @@ u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, size = ULLONG_MAX - start; for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; + struct e820entry *ei = &e820x->map[i]; u64 final_start, final_end; if (ei->type != old_type) continue; @@ -454,6 +455,19 @@ u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, return real_updated_size; } +u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, + unsigned new_type) +{ + return e820_update_range_map(&e820, start, size, old_type, new_type); +} + +static u64 __init e820_update_range_saved(u64 start, u64 size, + unsigned old_type, unsigned new_type) +{ + return e820_update_range_map(&e820_saved, start, size, old_type, + new_type); +} + /* make e820 not cover the range */ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, int checktype) @@ -503,6 +517,15 @@ void __init update_e820(void) printk(KERN_INFO "modified physical RAM map:\n"); e820_print_map("modified"); } +static void __init update_e820_saved(void) +{ + int nr_map; + + nr_map = e820_saved.nr_map; + if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map)) + return; + e820_saved.nr_map = nr_map; +} #define MAX_GAP_END 0x100000000ull /* * Search for a gap in the e820 memory space from start_addr to end_addr. @@ -1007,8 +1030,10 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) addr = round_down(start + size - sizet, align); e820_update_range(addr, sizet, E820_RAM, E820_RESERVED); + e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED); printk(KERN_INFO "update e820 for early_reserve_e820\n"); update_e820(); + update_e820_saved(); return addr; } -- cgit v0.10.2 From 3a9e189d69479736a0d0901c87ad08c9e328b389 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 1 Jul 2008 14:45:32 -0500 Subject: x86: map UV chipset space - pagetable Add boot-time function for creating additional 2MB page table entries for mapping chipset specific cached/uncached ranges. Signed-off-by: Jack Steiner Cc: linux-mm@kvack.org Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 77d129d..57d5eff 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -202,6 +202,46 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval) } /* + * Create large page table mappings for a range of physical addresses. + */ +static void __init __init_extra_mapping(unsigned long phys, unsigned long size, + pgprot_t prot) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + + BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK)); + for (; size; phys += PMD_SIZE, size -= PMD_SIZE) { + pgd = pgd_offset_k((unsigned long)__va(phys)); + if (pgd_none(*pgd)) { + pud = (pud_t *) spp_getpage(); + set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE | + _PAGE_USER)); + } + pud = pud_offset(pgd, (unsigned long)__va(phys)); + if (pud_none(*pud)) { + pmd = (pmd_t *) spp_getpage(); + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | + _PAGE_USER)); + } + pmd = pmd_offset(pud, phys); + BUG_ON(!pmd_none(*pmd)); + set_pmd(pmd, __pmd(phys | pgprot_val(prot))); + } +} + +void __init init_extra_mapping_wb(unsigned long phys, unsigned long size) +{ + __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE); +} + +void __init init_extra_mapping_uc(unsigned long phys, unsigned long size) +{ + __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE_NOCACHE); +} + +/* * The head.S code sets up the kernel high mapping: * * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text) diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 010d12d..c6916c8 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -91,6 +91,10 @@ extern unsigned long init_memory_mapping(unsigned long start, unsigned long end); extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); + +extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); +extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); + #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_FLATMEM diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 64de07e..49cbd76 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -91,6 +91,7 @@ #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) #define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) #define PAGE_KERNEL __pgprot(__PAGE_KERNEL) @@ -102,6 +103,7 @@ #define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS) #define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE) #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_NOCACHE __pgprot(__PAGE_KERNEL_LARGE_NOCACHE) #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) #define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) #define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE) -- cgit v0.10.2 From 83f5d894ca5280bfcd904dfeb1347c2da2b19aac Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 1 Jul 2008 14:45:38 -0500 Subject: x86: map UV chipset space - UV support Create page table entries to map the SGI UV chipset GRU. local MMR & global MMR ranges. Signed-off-by: Jack Steiner Cc: linux-mm@kvack.org Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 45e84ac..711f11c 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -8,6 +8,7 @@ * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. */ +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include @@ -208,14 +210,79 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) BUG(); } +static __init void map_low_mmrs(void) +{ + init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE); + init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE); +} + +enum map_type {map_wb, map_uc}; + +static void map_high(char *id, unsigned long base, int shift, enum map_type map_type) +{ + unsigned long bytes, paddr; + + paddr = base << shift; + bytes = (1UL << shift); + printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, + paddr + bytes); + if (map_type == map_uc) + init_extra_mapping_uc(paddr, bytes); + else + init_extra_mapping_wb(paddr, bytes); + +} +static __init void map_gru_high(int max_pnode) +{ + union uvh_rh_gam_gru_overlay_config_mmr_u gru; + int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; + + gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); + if (gru.s.enable) + map_high("GRU", gru.s.base, shift, map_wb); +} + +static __init void map_config_high(int max_pnode) +{ + union uvh_rh_gam_cfg_overlay_config_mmr_u cfg; + int shift = UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT; + + cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR); + if (cfg.s.enable) + map_high("CONFIG", cfg.s.base, shift, map_uc); +} + +static __init void map_mmr_high(int max_pnode) +{ + union uvh_rh_gam_mmr_overlay_config_mmr_u mmr; + int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT; + + mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); + if (mmr.s.enable) + map_high("MMR", mmr.s.base, shift, map_uc); +} + +static __init void map_mmioh_high(int max_pnode) +{ + union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; + int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; + + mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); + if (mmioh.s.enable) + map_high("MMIOH", mmioh.s.base, shift, map_uc); +} + static __init void uv_system_init(void) { union uvh_si_addr_map_config_u m_n_config; union uvh_node_id_u node_id; unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; + int max_pnode = 0; unsigned long mmr_base, present; + map_low_mmrs(); + m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); m_val = m_n_config.s.m_skt; n_val = m_n_config.s.n_skt; @@ -281,12 +348,18 @@ static __init void uv_system_init(void) uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */ uv_node_to_blade[nid] = blade; uv_cpu_to_blade[cpu] = blade; + max_pnode = max(pnode, max_pnode); - printk(KERN_DEBUG "UV cpu %d, apicid 0x%x, pnode %d, nid %d, " + printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, " "lcpu %d, blade %d\n", cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid, lcpu, blade); } + + map_gru_high(max_pnode); + map_mmr_high(max_pnode); + map_config_high(max_pnode); + map_mmioh_high(max_pnode); } /* diff --git a/include/asm-x86/uv/uv_hub.h b/include/asm-x86/uv/uv_hub.h index 6500488..a4ef26e 100644 --- a/include/asm-x86/uv/uv_hub.h +++ b/include/asm-x86/uv/uv_hub.h @@ -149,6 +149,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); #define UV_LOCAL_MMR_BASE 0xf4000000UL #define UV_GLOBAL_MMR32_BASE 0xf8000000UL #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) +#define UV_LOCAL_MMR_SIZE (64UL * 1024 * 1024) +#define UV_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024) #define UV_GLOBAL_MMR32_PNODE_SHIFT 15 #define UV_GLOBAL_MMR64_PNODE_SHIFT 26 diff --git a/include/asm-x86/uv/uv_mmrs.h b/include/asm-x86/uv/uv_mmrs.h index ac98460..37113f5 100644 --- a/include/asm-x86/uv/uv_mmrs.h +++ b/include/asm-x86/uv/uv_mmrs.h @@ -713,6 +713,26 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { }; /* ========================================================================= */ +/* UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR 0x1600020UL + +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT 26 +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL + +union uvh_rh_gam_cfg_overlay_config_mmr_u { + unsigned long v; + struct uvh_rh_gam_cfg_overlay_config_mmr_s { + unsigned long rsvd_0_25: 26; /* */ + unsigned long base : 20; /* RW */ + unsigned long rsvd_46_62: 17; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL @@ -740,6 +760,32 @@ union uvh_rh_gam_gru_overlay_config_mmr_u { }; /* ========================================================================= */ +/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL + +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL + +union uvh_rh_gam_mmioh_overlay_config_mmr_u { + unsigned long v; + struct uvh_rh_gam_mmioh_overlay_config_mmr_s { + unsigned long rsvd_0_29: 30; /* */ + unsigned long base : 16; /* RW */ + unsigned long m_io : 6; /* RW */ + unsigned long n_io : 4; /* RW */ + unsigned long rsvd_56_62: 7; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ /* UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL -- cgit v0.10.2 From 5d061e397db1ee7a62783a881833f3f9b89f6dc8 Mon Sep 17 00:00:00 2001 From: Dimitri Sivanich Date: Wed, 2 Jul 2008 15:39:35 -0500 Subject: x86, uv: update x86 mmr list for SGI uv This patch updates the X86 mmr list for SGI uv. Signed-off-by: Dimitri Sivanich Cc: Jack Steiner Cc: Russ Anderson Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uv/uv_mmrs.h b/include/asm-x86/uv/uv_mmrs.h index 37113f5..eb59201 100644 --- a/include/asm-x86/uv/uv_mmrs.h +++ b/include/asm-x86/uv/uv_mmrs.h @@ -17,7 +17,7 @@ /* UVH_BAU_DATA_CONFIG */ /* ========================================================================= */ #define UVH_BAU_DATA_CONFIG 0x61680UL -#define UVH_BAU_DATA_CONFIG_32 0x0450 +#define UVH_BAU_DATA_CONFIG_32 0x0438 #define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0 #define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL @@ -53,10 +53,248 @@ union uvh_bau_data_config_u { }; /* ========================================================================= */ +/* UVH_EVENT_OCCURRED0 */ +/* ========================================================================= */ +#define UVH_EVENT_OCCURRED0 0x70000UL +#define UVH_EVENT_OCCURRED0_32 0x005e8 + +#define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0 +#define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL +#define UVH_EVENT_OCCURRED0_GR0_HCERR_SHFT 1 +#define UVH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL +#define UVH_EVENT_OCCURRED0_GR1_HCERR_SHFT 2 +#define UVH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL +#define UVH_EVENT_OCCURRED0_LH_HCERR_SHFT 3 +#define UVH_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL +#define UVH_EVENT_OCCURRED0_RH_HCERR_SHFT 4 +#define UVH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL +#define UVH_EVENT_OCCURRED0_XN_HCERR_SHFT 5 +#define UVH_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL +#define UVH_EVENT_OCCURRED0_SI_HCERR_SHFT 6 +#define UVH_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL +#define UVH_EVENT_OCCURRED0_LB_AOERR0_SHFT 7 +#define UVH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL +#define UVH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8 +#define UVH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL +#define UVH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9 +#define UVH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL +#define UVH_EVENT_OCCURRED0_LH_AOERR0_SHFT 10 +#define UVH_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL +#define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 +#define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL +#define UVH_EVENT_OCCURRED0_XN_AOERR0_SHFT 12 +#define UVH_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL +#define UVH_EVENT_OCCURRED0_SI_AOERR0_SHFT 13 +#define UVH_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL +#define UVH_EVENT_OCCURRED0_LB_AOERR1_SHFT 14 +#define UVH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL +#define UVH_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15 +#define UVH_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL +#define UVH_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16 +#define UVH_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL +#define UVH_EVENT_OCCURRED0_LH_AOERR1_SHFT 17 +#define UVH_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL +#define UVH_EVENT_OCCURRED0_RH_AOERR1_SHFT 18 +#define UVH_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL +#define UVH_EVENT_OCCURRED0_XN_AOERR1_SHFT 19 +#define UVH_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL +#define UVH_EVENT_OCCURRED0_SI_AOERR1_SHFT 20 +#define UVH_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL +#define UVH_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21 +#define UVH_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL +#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22 +#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38 +#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL +#define UVH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39 +#define UVH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL +#define UVH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40 +#define UVH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL +#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41 +#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL +#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42 +#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL +#define UVH_EVENT_OCCURRED0_LTC_INT_SHFT 43 +#define UVH_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL +#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44 +#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL +#define UVH_EVENT_OCCURRED0_IPI_INT_SHFT 45 +#define UVH_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL +#define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46 +#define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL +#define UVH_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47 +#define UVH_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL +#define UVH_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48 +#define UVH_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL +#define UVH_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49 +#define UVH_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL +#define UVH_EVENT_OCCURRED0_PROFILE_INT_SHFT 50 +#define UVH_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL +#define UVH_EVENT_OCCURRED0_RTC0_SHFT 51 +#define UVH_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL +#define UVH_EVENT_OCCURRED0_RTC1_SHFT 52 +#define UVH_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL +#define UVH_EVENT_OCCURRED0_RTC2_SHFT 53 +#define UVH_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL +#define UVH_EVENT_OCCURRED0_RTC3_SHFT 54 +#define UVH_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL +#define UVH_EVENT_OCCURRED0_BAU_DATA_SHFT 55 +#define UVH_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL +#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56 +#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL +union uvh_event_occurred0_u { + unsigned long v; + struct uvh_event_occurred0_s { + unsigned long lb_hcerr : 1; /* RW, W1C */ + unsigned long gr0_hcerr : 1; /* RW, W1C */ + unsigned long gr1_hcerr : 1; /* RW, W1C */ + unsigned long lh_hcerr : 1; /* RW, W1C */ + unsigned long rh_hcerr : 1; /* RW, W1C */ + unsigned long xn_hcerr : 1; /* RW, W1C */ + unsigned long si_hcerr : 1; /* RW, W1C */ + unsigned long lb_aoerr0 : 1; /* RW, W1C */ + unsigned long gr0_aoerr0 : 1; /* RW, W1C */ + unsigned long gr1_aoerr0 : 1; /* RW, W1C */ + unsigned long lh_aoerr0 : 1; /* RW, W1C */ + unsigned long rh_aoerr0 : 1; /* RW, W1C */ + unsigned long xn_aoerr0 : 1; /* RW, W1C */ + unsigned long si_aoerr0 : 1; /* RW, W1C */ + unsigned long lb_aoerr1 : 1; /* RW, W1C */ + unsigned long gr0_aoerr1 : 1; /* RW, W1C */ + unsigned long gr1_aoerr1 : 1; /* RW, W1C */ + unsigned long lh_aoerr1 : 1; /* RW, W1C */ + unsigned long rh_aoerr1 : 1; /* RW, W1C */ + unsigned long xn_aoerr1 : 1; /* RW, W1C */ + unsigned long si_aoerr1 : 1; /* RW, W1C */ + unsigned long rh_vpi_int : 1; /* RW, W1C */ + unsigned long system_shutdown_int : 1; /* RW, W1C */ + unsigned long lb_irq_int_0 : 1; /* RW, W1C */ + unsigned long lb_irq_int_1 : 1; /* RW, W1C */ + unsigned long lb_irq_int_2 : 1; /* RW, W1C */ + unsigned long lb_irq_int_3 : 1; /* RW, W1C */ + unsigned long lb_irq_int_4 : 1; /* RW, W1C */ + unsigned long lb_irq_int_5 : 1; /* RW, W1C */ + unsigned long lb_irq_int_6 : 1; /* RW, W1C */ + unsigned long lb_irq_int_7 : 1; /* RW, W1C */ + unsigned long lb_irq_int_8 : 1; /* RW, W1C */ + unsigned long lb_irq_int_9 : 1; /* RW, W1C */ + unsigned long lb_irq_int_10 : 1; /* RW, W1C */ + unsigned long lb_irq_int_11 : 1; /* RW, W1C */ + unsigned long lb_irq_int_12 : 1; /* RW, W1C */ + unsigned long lb_irq_int_13 : 1; /* RW, W1C */ + unsigned long lb_irq_int_14 : 1; /* RW, W1C */ + unsigned long lb_irq_int_15 : 1; /* RW, W1C */ + unsigned long l1_nmi_int : 1; /* RW, W1C */ + unsigned long stop_clock : 1; /* RW, W1C */ + unsigned long asic_to_l1 : 1; /* RW, W1C */ + unsigned long l1_to_asic : 1; /* RW, W1C */ + unsigned long ltc_int : 1; /* RW, W1C */ + unsigned long la_seq_trigger : 1; /* RW, W1C */ + unsigned long ipi_int : 1; /* RW, W1C */ + unsigned long extio_int0 : 1; /* RW, W1C */ + unsigned long extio_int1 : 1; /* RW, W1C */ + unsigned long extio_int2 : 1; /* RW, W1C */ + unsigned long extio_int3 : 1; /* RW, W1C */ + unsigned long profile_int : 1; /* RW, W1C */ + unsigned long rtc0 : 1; /* RW, W1C */ + unsigned long rtc1 : 1; /* RW, W1C */ + unsigned long rtc2 : 1; /* RW, W1C */ + unsigned long rtc3 : 1; /* RW, W1C */ + unsigned long bau_data : 1; /* RW, W1C */ + unsigned long power_management_req : 1; /* RW, W1C */ + unsigned long rsvd_57_63 : 7; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_EVENT_OCCURRED0_ALIAS */ +/* ========================================================================= */ +#define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL +#define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0 + +/* ========================================================================= */ +/* UVH_INT_CMPB */ +/* ========================================================================= */ +#define UVH_INT_CMPB 0x22080UL + +#define UVH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 +#define UVH_INT_CMPB_REAL_TIME_CMPB_MASK 0x00ffffffffffffffUL + +union uvh_int_cmpb_u { + unsigned long v; + struct uvh_int_cmpb_s { + unsigned long real_time_cmpb : 56; /* RW */ + unsigned long rsvd_56_63 : 8; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_INT_CMPC */ +/* ========================================================================= */ +#define UVH_INT_CMPC 0x22100UL + +#define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 +#define UVH_INT_CMPC_REAL_TIME_CMPC_MASK 0x00ffffffffffffffUL + +union uvh_int_cmpc_u { + unsigned long v; + struct uvh_int_cmpc_s { + unsigned long real_time_cmpc : 56; /* RW */ + unsigned long rsvd_56_63 : 8; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_INT_CMPD */ +/* ========================================================================= */ +#define UVH_INT_CMPD 0x22180UL + +#define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 +#define UVH_INT_CMPD_REAL_TIME_CMPD_MASK 0x00ffffffffffffffUL + +union uvh_int_cmpd_u { + unsigned long v; + struct uvh_int_cmpd_s { + unsigned long real_time_cmpd : 56; /* RW */ + unsigned long rsvd_56_63 : 8; /* */ + } s; +}; + +/* ========================================================================= */ /* UVH_IPI_INT */ /* ========================================================================= */ #define UVH_IPI_INT 0x60500UL -#define UVH_IPI_INT_32 0x0360 +#define UVH_IPI_INT_32 0x0348 #define UVH_IPI_INT_VECTOR_SHFT 0 #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL @@ -86,7 +324,7 @@ union uvh_ipi_int_u { /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST */ /* ========================================================================= */ #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x009f0 +#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x009c0 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL @@ -108,7 +346,7 @@ union uvh_lb_bau_intd_payload_queue_first_u { /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST */ /* ========================================================================= */ #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x009f8 +#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x009c8 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL @@ -126,7 +364,7 @@ union uvh_lb_bau_intd_payload_queue_last_u { /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL */ /* ========================================================================= */ #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x00a00 +#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x009d0 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL @@ -144,7 +382,7 @@ union uvh_lb_bau_intd_payload_queue_tail_u { /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE */ /* ========================================================================= */ #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL -#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0x0aa0 +#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0x0a68 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL @@ -205,13 +443,13 @@ union uvh_lb_bau_intd_software_acknowledge_u { /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS */ /* ========================================================================= */ #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL -#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0aa8 +#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70 /* ========================================================================= */ /* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ /* ========================================================================= */ #define UVH_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x009d8 +#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x009a8 #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0 #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL @@ -234,7 +472,7 @@ union uvh_lb_bau_sb_activation_control_u { /* UVH_LB_BAU_SB_ACTIVATION_STATUS_0 */ /* ========================================================================= */ #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x009e0 +#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x009b0 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL @@ -250,7 +488,7 @@ union uvh_lb_bau_sb_activation_status_0_u { /* UVH_LB_BAU_SB_ACTIVATION_STATUS_1 */ /* ========================================================================= */ #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x009e8 +#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x009b8 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL @@ -266,7 +504,7 @@ union uvh_lb_bau_sb_activation_status_1_u { /* UVH_LB_BAU_SB_DESCRIPTOR_BASE */ /* ========================================================================= */ #define UVH_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL -#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x009d0 +#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x009a0 #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12 #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL @@ -333,46 +571,48 @@ union uvh_lb_bau_sb_descriptor_base_u { #define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_MASK 0x0000000000100000UL #define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_SHFT 21 #define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_MASK 0x0000000000200000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_TIMEOUT_SHFT 22 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_TIMEOUT_MASK 0x0000000000400000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_SHFT 23 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_MASK 0x0000000000800000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_SHFT 24 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_MASK 0x0000000001000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_SHFT 25 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_MASK 0x0000000002000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_SHFT 26 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_MASK 0x0000000004000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_SHFT 27 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_MASK 0x0000000008000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_SHFT 28 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_MASK 0x0000000010000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_SHFT 29 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_MASK 0x0000000020000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_SHFT 30 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_MASK 0x0000000040000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_SHFT 31 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_MASK 0x0000000080000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_SHFT 32 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_MASK 0x0000000100000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_SHFT 33 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_MASK 0x0000000200000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_SHFT 34 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_MASK 0x0000000400000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_SHFT 35 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_MASK 0x0000000800000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_SHFT 36 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_MASK 0x0000001000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_SHFT 37 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_MASK 0x0000002000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_SHFT 38 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_MASK 0x0000004000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_SHFT 39 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_MASK 0x0000008000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_SHFT 40 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_MASK 0x0000010000000000UL -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_SHFT 41 -#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_MASK 0x0000020000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_SHFT 22 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_MASK 0x0000000000400000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_SHFT 23 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_MASK 0x0000000000800000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_SHFT 24 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_MASK 0x0000000001000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_SHFT 25 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_MASK 0x0000000002000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_SHFT 26 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_MASK 0x0000000004000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_SHFT 27 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_MASK 0x0000000008000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_SHFT 28 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_MASK 0x0000000010000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_SHFT 29 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_MASK 0x0000000020000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_SHFT 30 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_MASK 0x0000000040000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_SHFT 31 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_MASK 0x0000000080000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_SHFT 32 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_MASK 0x0000000100000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_SHFT 33 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_MASK 0x0000000200000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_SHFT 34 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_MASK 0x0000000400000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_SHFT 35 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_MASK 0x0000000800000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_SHFT 36 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_MASK 0x0000001000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_SHFT 37 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_MASK 0x0000002000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_SHFT 38 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_MASK 0x0000004000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_SHFT 39 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_MASK 0x0000008000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_SHFT 40 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_MASK 0x0000010000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_SHFT 41 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_MASK 0x0000020000000000UL +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_SHFT 42 +#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_MASK 0x0000040000000000UL union uvh_lb_mcast_aoerr0_rpt_enable_u { unsigned long v; @@ -399,7 +639,8 @@ union uvh_lb_mcast_aoerr0_rpt_enable_u { unsigned long macc_rep_runt_msg : 1; /* RW */ unsigned long macc_rep_obese_msg : 1; /* RW */ unsigned long macc_rep_data_sb_err : 1; /* RW */ - unsigned long macc_timeout : 1; /* RW */ + unsigned long macc_amo_timeout : 1; /* RW */ + unsigned long macc_put_timeout : 1; /* RW */ unsigned long macc_spurious_event : 1; /* RW */ unsigned long ioh_destination_table_parity : 1; /* RW */ unsigned long get_had_error_reply : 1; /* RW */ @@ -419,7 +660,7 @@ union uvh_lb_mcast_aoerr0_rpt_enable_u { unsigned long int_rep_obese_msg : 1; /* RW */ unsigned long int_rep_command_err : 1; /* RW */ unsigned long int_timeout : 1; /* RW */ - unsigned long rsvd_42_63 : 22; /* */ + unsigned long rsvd_43_63 : 21; /* */ } s; }; @@ -733,14 +974,34 @@ union uvh_rh_gam_cfg_overlay_config_mmr_u { }; /* ========================================================================= */ +/* UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR 0x1600020UL + +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT 26 +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 +#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL + +union uvh_rh_gam_cfg_overlay_config_mmr_u { + unsigned long v; + struct uvh_rh_gam_cfg_overlay_config_mmr_s { + unsigned long rsvd_0_25: 26; /* */ + unsigned long base : 20; /* RW */ + unsigned long rsvd_46_62: 17; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 46 -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0000400000000000UL +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48 +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 @@ -751,8 +1012,9 @@ union uvh_rh_gam_gru_overlay_config_mmr_u { struct uvh_rh_gam_gru_overlay_config_mmr_s { unsigned long rsvd_0_27: 28; /* */ unsigned long base : 18; /* RW */ + unsigned long rsvd_46_47: 2; /* */ unsigned long gr4 : 1; /* RW */ - unsigned long rsvd_47_51: 5; /* */ + unsigned long rsvd_49_51: 3; /* */ unsigned long n_gru : 4; /* RW */ unsigned long rsvd_56_62: 7; /* */ unsigned long enable : 1; /* RW */ @@ -786,6 +1048,32 @@ union uvh_rh_gam_mmioh_overlay_config_mmr_u { }; /* ========================================================================= */ +/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR */ +/* ========================================================================= */ +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL + +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL + +union uvh_rh_gam_mmioh_overlay_config_mmr_u { + unsigned long v; + struct uvh_rh_gam_mmioh_overlay_config_mmr_s { + unsigned long rsvd_0_29: 30; /* */ + unsigned long base : 16; /* RW */ + unsigned long m_io : 6; /* RW */ + unsigned long n_io : 4; /* RW */ + unsigned long rsvd_56_62: 7; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ /* UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL @@ -811,7 +1099,7 @@ union uvh_rh_gam_mmr_overlay_config_mmr_u { /* ========================================================================= */ /* UVH_RTC */ /* ========================================================================= */ -#define UVH_RTC 0x28000UL +#define UVH_RTC 0x340000UL #define UVH_RTC_REAL_TIME_CLOCK_SHFT 0 #define UVH_RTC_REAL_TIME_CLOCK_MASK 0x00ffffffffffffffUL @@ -825,6 +1113,139 @@ union uvh_rtc_u { }; /* ========================================================================= */ +/* UVH_RTC1_INT_CONFIG */ +/* ========================================================================= */ +#define UVH_RTC1_INT_CONFIG 0x615c0UL + +#define UVH_RTC1_INT_CONFIG_VECTOR_SHFT 0 +#define UVH_RTC1_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVH_RTC1_INT_CONFIG_DM_SHFT 8 +#define UVH_RTC1_INT_CONFIG_DM_MASK 0x0000000000000700UL +#define UVH_RTC1_INT_CONFIG_DESTMODE_SHFT 11 +#define UVH_RTC1_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVH_RTC1_INT_CONFIG_STATUS_SHFT 12 +#define UVH_RTC1_INT_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVH_RTC1_INT_CONFIG_P_SHFT 13 +#define UVH_RTC1_INT_CONFIG_P_MASK 0x0000000000002000UL +#define UVH_RTC1_INT_CONFIG_T_SHFT 15 +#define UVH_RTC1_INT_CONFIG_T_MASK 0x0000000000008000UL +#define UVH_RTC1_INT_CONFIG_M_SHFT 16 +#define UVH_RTC1_INT_CONFIG_M_MASK 0x0000000000010000UL +#define UVH_RTC1_INT_CONFIG_APIC_ID_SHFT 32 +#define UVH_RTC1_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL + +union uvh_rtc1_int_config_u { + unsigned long v; + struct uvh_rtc1_int_config_s { + unsigned long vector_ : 8; /* RW */ + unsigned long dm : 3; /* RW */ + unsigned long destmode : 1; /* RW */ + unsigned long status : 1; /* RO */ + unsigned long p : 1; /* RO */ + unsigned long rsvd_14 : 1; /* */ + unsigned long t : 1; /* RO */ + unsigned long m : 1; /* RW */ + unsigned long rsvd_17_31: 15; /* */ + unsigned long apic_id : 32; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RTC2_INT_CONFIG */ +/* ========================================================================= */ +#define UVH_RTC2_INT_CONFIG 0x61600UL + +#define UVH_RTC2_INT_CONFIG_VECTOR_SHFT 0 +#define UVH_RTC2_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVH_RTC2_INT_CONFIG_DM_SHFT 8 +#define UVH_RTC2_INT_CONFIG_DM_MASK 0x0000000000000700UL +#define UVH_RTC2_INT_CONFIG_DESTMODE_SHFT 11 +#define UVH_RTC2_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVH_RTC2_INT_CONFIG_STATUS_SHFT 12 +#define UVH_RTC2_INT_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVH_RTC2_INT_CONFIG_P_SHFT 13 +#define UVH_RTC2_INT_CONFIG_P_MASK 0x0000000000002000UL +#define UVH_RTC2_INT_CONFIG_T_SHFT 15 +#define UVH_RTC2_INT_CONFIG_T_MASK 0x0000000000008000UL +#define UVH_RTC2_INT_CONFIG_M_SHFT 16 +#define UVH_RTC2_INT_CONFIG_M_MASK 0x0000000000010000UL +#define UVH_RTC2_INT_CONFIG_APIC_ID_SHFT 32 +#define UVH_RTC2_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL + +union uvh_rtc2_int_config_u { + unsigned long v; + struct uvh_rtc2_int_config_s { + unsigned long vector_ : 8; /* RW */ + unsigned long dm : 3; /* RW */ + unsigned long destmode : 1; /* RW */ + unsigned long status : 1; /* RO */ + unsigned long p : 1; /* RO */ + unsigned long rsvd_14 : 1; /* */ + unsigned long t : 1; /* RO */ + unsigned long m : 1; /* RW */ + unsigned long rsvd_17_31: 15; /* */ + unsigned long apic_id : 32; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RTC3_INT_CONFIG */ +/* ========================================================================= */ +#define UVH_RTC3_INT_CONFIG 0x61640UL + +#define UVH_RTC3_INT_CONFIG_VECTOR_SHFT 0 +#define UVH_RTC3_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVH_RTC3_INT_CONFIG_DM_SHFT 8 +#define UVH_RTC3_INT_CONFIG_DM_MASK 0x0000000000000700UL +#define UVH_RTC3_INT_CONFIG_DESTMODE_SHFT 11 +#define UVH_RTC3_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVH_RTC3_INT_CONFIG_STATUS_SHFT 12 +#define UVH_RTC3_INT_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVH_RTC3_INT_CONFIG_P_SHFT 13 +#define UVH_RTC3_INT_CONFIG_P_MASK 0x0000000000002000UL +#define UVH_RTC3_INT_CONFIG_T_SHFT 15 +#define UVH_RTC3_INT_CONFIG_T_MASK 0x0000000000008000UL +#define UVH_RTC3_INT_CONFIG_M_SHFT 16 +#define UVH_RTC3_INT_CONFIG_M_MASK 0x0000000000010000UL +#define UVH_RTC3_INT_CONFIG_APIC_ID_SHFT 32 +#define UVH_RTC3_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL + +union uvh_rtc3_int_config_u { + unsigned long v; + struct uvh_rtc3_int_config_s { + unsigned long vector_ : 8; /* RW */ + unsigned long dm : 3; /* RW */ + unsigned long destmode : 1; /* RW */ + unsigned long status : 1; /* RO */ + unsigned long p : 1; /* RO */ + unsigned long rsvd_14 : 1; /* */ + unsigned long t : 1; /* RO */ + unsigned long m : 1; /* RW */ + unsigned long rsvd_17_31: 15; /* */ + unsigned long apic_id : 32; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_RTC_INC_RATIO */ +/* ========================================================================= */ +#define UVH_RTC_INC_RATIO 0x350000UL + +#define UVH_RTC_INC_RATIO_FRACTION_SHFT 0 +#define UVH_RTC_INC_RATIO_FRACTION_MASK 0x00000000000fffffUL +#define UVH_RTC_INC_RATIO_RATIO_SHFT 20 +#define UVH_RTC_INC_RATIO_RATIO_MASK 0x0000000000700000UL + +union uvh_rtc_inc_ratio_u { + unsigned long v; + struct uvh_rtc_inc_ratio_s { + unsigned long fraction : 20; /* RW */ + unsigned long ratio : 3; /* RW */ + unsigned long rsvd_23_63: 41; /* */ + } s; +}; + +/* ========================================================================= */ /* UVH_SI_ADDR_MAP_CONFIG */ /* ========================================================================= */ #define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL -- cgit v0.10.2 From 746f2eb790e75676ddc3b816ba18bac4179cc744 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 1 Jul 2008 21:43:52 +0400 Subject: x86: apic_32.c - add lapic resource Add lapic resource into kernel resource map and mark it as busy Signed-off-by: Cyrill Gorcunov Cc: "Maciej W. Rozycki" Signed-off-by: Ingo Molnar CC: Maciej W. Rozycki diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 6dea830..3e94720 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c @@ -82,6 +82,11 @@ int pic_mode; /* Have we found an MP table */ int smp_found_config; +static struct resource lapic_resource = { + .name = "Local APIC", + .flags = IORESOURCE_MEM | IORESOURCE_BUSY, +}; + static unsigned int calibration_result; static int lapic_next_event(unsigned long delta, @@ -1720,3 +1725,21 @@ static int __init apic_set_verbosity(char *str) } __setup("apic=", apic_set_verbosity); +static int __init lapic_insert_resource(void) +{ + if (!apic_phys) + return -1; + + /* Put local APIC into the resource map. */ + lapic_resource.start = apic_phys; + lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; + insert_resource(&iomem_resource, &lapic_resource); + + return 0; +} + +/* + * need call insert after e820_reserve_resources() + * that is using request_resource + */ +late_initcall(lapic_insert_resource); -- cgit v0.10.2 From 0ef95533326a7b37d16025af9edc0c18e644b346 Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 1 Jul 2008 11:43:18 -0700 Subject: x86: merge sched_clock handling Move the basic global variable definitions and sched_clock handling in the common "tsc.c" file. - Unify notsc kernel command line handling for 32 bit and 64bit. - Functional changes for 64bit. - "tsc_disabled" is updated if "notsc" is passed at boottime. - Fallback to jiffies for sched_clock, incase notsc is passed on commandline. Signed-off-by: Alok N Kataria Signed-off-by: Dan Hecht Cc: Dan Hecht Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 54829e2..ca904ee 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o obj-y += alternative.o i8253.o pci-nommu.o -obj-y += tsc_$(BITS).o io_delay.o rtc.o +obj-y += tsc_$(BITS).o io_delay.o rtc.o tsc.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-y += process.o diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c index 5f29f12..059ca6e 100644 --- a/arch/x86/kernel/time_32.c +++ b/arch/x86/kernel/time_32.c @@ -39,9 +39,6 @@ #include "do_timer.h" -unsigned int cpu_khz; /* Detected as we calibrate the TSC */ -EXPORT_SYMBOL(cpu_khz); - int timer_ack; unsigned long profile_pc(struct pt_regs *regs) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c new file mode 100644 index 0000000..5d0be77 --- /dev/null +++ b/arch/x86/kernel/tsc.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +unsigned int cpu_khz; /* TSC clocks / usec, not used here */ +EXPORT_SYMBOL(cpu_khz); +unsigned int tsc_khz; +EXPORT_SYMBOL(tsc_khz); + +/* + * TSC can be unstable due to cpufreq or due to unsynced TSCs + */ +int tsc_unstable; + +/* native_sched_clock() is called before tsc_init(), so + we must start with the TSC soft disabled to prevent + erroneous rdtsc usage on !cpu_has_tsc processors */ +int tsc_disabled = -1; + +/* + * Scheduler clock - returns current time in nanosec units. + */ +u64 native_sched_clock(void) +{ + u64 this_offset; + + /* + * Fall back to jiffies if there's no TSC available: + * ( But note that we still use it if the TSC is marked + * unstable. We do this because unlike Time Of Day, + * the scheduler clock tolerates small errors and it's + * very important for it to be as fast as the platform + * can achive it. ) + */ + if (unlikely(tsc_disabled)) { + /* No locking but a rare wrong value is not a big deal: */ + return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); + } + + /* read the Time Stamp Counter: */ + rdtscll(this_offset); + + /* return the value in ns */ + return cycles_2_ns(this_offset); +} + +/* We need to define a real function for sched_clock, to override the + weak default version */ +#ifdef CONFIG_PARAVIRT +unsigned long long sched_clock(void) +{ + return paravirt_sched_clock(); +} +#else +unsigned long long +sched_clock(void) __attribute__((alias("native_sched_clock"))); +#endif + +int check_tsc_unstable(void) +{ + return tsc_unstable; +} +EXPORT_SYMBOL_GPL(check_tsc_unstable); + +#ifdef CONFIG_X86_TSC +int __init notsc_setup(char *str) +{ + printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " + "cannot disable TSC completely.\n"); + tsc_disabled = 1; + return 1; +} +#else +/* + * disable flag for tsc. Takes effect by clearing the TSC cpu flag + * in cpu/common.c + */ +int __init notsc_setup(char *str) +{ + setup_clear_cpu_cap(X86_FEATURE_TSC); + return 1; +} +#endif + +__setup("notsc", notsc_setup); diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index 6240922..dc89900 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -15,52 +15,8 @@ #include "mach_timer.h" -/* native_sched_clock() is called before tsc_init(), so - we must start with the TSC soft disabled to prevent - erroneous rdtsc usage on !cpu_has_tsc processors */ -static int tsc_disabled = -1; - -/* - * On some systems the TSC frequency does not - * change with the cpu frequency. So we need - * an extra value to store the TSC freq - */ -unsigned int tsc_khz; -EXPORT_SYMBOL_GPL(tsc_khz); - -#ifdef CONFIG_X86_TSC -static int __init tsc_setup(char *str) -{ - printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " - "cannot disable TSC completely.\n"); - tsc_disabled = 1; - return 1; -} -#else -/* - * disable flag for tsc. Takes effect by clearing the TSC cpu flag - * in cpu/common.c - */ -static int __init tsc_setup(char *str) -{ - setup_clear_cpu_cap(X86_FEATURE_TSC); - return 1; -} -#endif - -__setup("notsc", tsc_setup); - -/* - * code to mark and check if the TSC is unstable - * due to cpufreq or due to unsynced TSCs - */ -static int tsc_unstable; - -int check_tsc_unstable(void) -{ - return tsc_unstable; -} -EXPORT_SYMBOL_GPL(check_tsc_unstable); +extern int tsc_unstable; +extern int tsc_disabled; /* Accelerators for sched_clock() * convert from cycles(64bits) => nanoseconds (64bits) @@ -109,44 +65,6 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) local_irq_restore(flags); } -/* - * Scheduler clock - returns current time in nanosec units. - */ -unsigned long long native_sched_clock(void) -{ - unsigned long long this_offset; - - /* - * Fall back to jiffies if there's no TSC available: - * ( But note that we still use it if the TSC is marked - * unstable. We do this because unlike Time Of Day, - * the scheduler clock tolerates small errors and it's - * very important for it to be as fast as the platform - * can achive it. ) - */ - if (unlikely(tsc_disabled)) - /* No locking but a rare wrong value is not a big deal: */ - return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); - - /* read the Time Stamp Counter: */ - rdtscll(this_offset); - - /* return the value in ns */ - return cycles_2_ns(this_offset); -} - -/* We need to define a real function for sched_clock, to override the - weak default version */ -#ifdef CONFIG_PARAVIRT -unsigned long long sched_clock(void) -{ - return paravirt_sched_clock(); -} -#else -unsigned long long sched_clock(void) - __attribute__((alias("native_sched_clock"))); -#endif - unsigned long native_calculate_cpu_khz(void) { unsigned long long start, end; diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index 9898fb0..69cbe4c 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c @@ -13,12 +13,8 @@ #include #include -static int notsc __initdata = 0; - -unsigned int cpu_khz; /* TSC clocks / usec, not used here */ -EXPORT_SYMBOL(cpu_khz); -unsigned int tsc_khz; -EXPORT_SYMBOL(tsc_khz); +extern int tsc_unstable; +extern int tsc_disabled; /* Accelerators for sched_clock() * convert from cycles(64bits) => nanoseconds (64bits) @@ -41,6 +37,7 @@ EXPORT_SYMBOL(tsc_khz); * * -johnstul@us.ibm.com "math is hard, lets go shopping!" */ + DEFINE_PER_CPU(unsigned long, cyc2ns); static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) @@ -63,41 +60,6 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) local_irq_restore(flags); } -unsigned long long native_sched_clock(void) -{ - unsigned long a = 0; - - /* Could do CPU core sync here. Opteron can execute rdtsc speculatively, - * which means it is not completely exact and may not be monotonous - * between CPUs. But the errors should be too small to matter for - * scheduling purposes. - */ - - rdtscll(a); - return cycles_2_ns(a); -} - -/* We need to define a real function for sched_clock, to override the - weak default version */ -#ifdef CONFIG_PARAVIRT -unsigned long long sched_clock(void) -{ - return paravirt_sched_clock(); -} -#else -unsigned long long -sched_clock(void) __attribute__((alias("native_sched_clock"))); -#endif - - -static int tsc_unstable; - -int check_tsc_unstable(void) -{ - return tsc_unstable; -} -EXPORT_SYMBOL_GPL(check_tsc_unstable); - #ifdef CONFIG_CPU_FREQ /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency @@ -281,14 +243,6 @@ __cpuinit int unsynchronized_tsc(void) return num_present_cpus() > 1; } -int __init notsc_setup(char *s) -{ - notsc = 1; - return 1; -} - -__setup("notsc", notsc_setup); - static struct clocksource clocksource_tsc; /* @@ -346,12 +300,13 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); void __init init_tsc_clocksource(void) { - if (!notsc) { - clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, - clocksource_tsc.shift); - if (check_tsc_unstable()) - clocksource_tsc.rating = 0; + if (tsc_disabled > 0) + return; - clocksource_register(&clocksource_tsc); - } + clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, + clocksource_tsc.shift); + if (check_tsc_unstable()) + clocksource_tsc.rating = 0; + + clocksource_register(&clocksource_tsc); } -- cgit v0.10.2 From bfc0f5947afa5e3a13e55867f4478c8a92c11dca Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 1 Jul 2008 11:43:24 -0700 Subject: x86: merge tsc calibration Merge the tsc calibration code for the 32bit and 64bit kernel. The paravirtualized calculate_cpu_khz for 64bit now points to the correct tsc_calibrate code as in 32bit. Original native_calculate_cpu_khz for 64 bit is now called as calibrate_cpu. Also moved the recalibrate_cpu_khz function in the common file. Note that this function is called only from powernow K7 cpu freq driver. Signed-off-by: Alok N Kataria Signed-off-by: Dan Hecht Cc: Dan Hecht Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index 39ae851..c6ac4da 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c @@ -56,7 +56,7 @@ static irqreturn_t timer_event_interrupt(int irq, void *dev_id) /* calibrate_cpu is used on systems with fixed rate TSCs to determine * processor frequency */ #define TICK_COUNT 100000000 -unsigned long __init native_calculate_cpu_khz(void) +static unsigned long __init calibrate_cpu(void) { int tsc_start, tsc_now; int i, no_ctr_free; @@ -114,14 +114,18 @@ void __init hpet_time_init(void) setup_irq(0, &irq0); } +extern void set_cyc2ns_scale(unsigned long cpu_khz, int cpu); + void __init time_init(void) { - tsc_calibrate(); + int cpu; + + cpu_khz = calculate_cpu_khz(); + tsc_khz = cpu_khz; - cpu_khz = tsc_khz; if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && - (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) - cpu_khz = calculate_cpu_khz(); + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) + cpu_khz = calibrate_cpu(); lpj_fine = ((unsigned long)tsc_khz * 1000)/HZ; @@ -134,7 +138,17 @@ void __init time_init(void) vgetcpu_mode = VGETCPU_LSL; printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); + cpu_khz / 1000, cpu_khz % 1000); + + /* + * Secondary CPUs do not run through tsc_init(), so set up + * all the scale factors for all CPUs, assuming the same + * speed as the bootup CPU. (cpufreq notifiers will fix this + * up if their speed diverges) + */ + for_each_possible_cpu(cpu) + set_cyc2ns_scale(cpu_khz, cpu); + init_tsc_clocksource(); late_time_init = choose_time_init(); } diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 5d0be77..e6ee145 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -1,7 +1,11 @@ +#include #include #include #include #include +#include + +#include unsigned int cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); @@ -84,3 +88,130 @@ int __init notsc_setup(char *str) #endif __setup("notsc", notsc_setup); + +#define MAX_RETRIES 5 +#define SMI_TRESHOLD 50000 + +/* + * Read TSC and the reference counters. Take care of SMI disturbance + */ +static u64 __init tsc_read_refs(u64 *pm, u64 *hpet) +{ + u64 t1, t2; + int i; + + for (i = 0; i < MAX_RETRIES; i++) { + t1 = get_cycles(); + if (hpet) + *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; + else + *pm = acpi_pm_read_early(); + t2 = get_cycles(); + if ((t2 - t1) < SMI_TRESHOLD) + return t2; + } + return ULLONG_MAX; +} + +/** + * tsc_calibrate - calibrate the tsc on boot + */ +static unsigned int __init tsc_calibrate(void) +{ + unsigned long flags; + u64 tsc1, tsc2, tr1, tr2, delta, pm1, pm2, hpet1, hpet2; + int hpet = is_hpet_enabled(); + unsigned int tsc_khz_val = 0; + + local_irq_save(flags); + + tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); + + outb((inb(0x61) & ~0x02) | 0x01, 0x61); + + outb(0xb0, 0x43); + outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); + outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); + tr1 = get_cycles(); + while ((inb(0x61) & 0x20) == 0); + tr2 = get_cycles(); + + tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); + + local_irq_restore(flags); + + /* + * Preset the result with the raw and inaccurate PIT + * calibration value + */ + delta = (tr2 - tr1); + do_div(delta, 50); + tsc_khz_val = delta; + + /* hpet or pmtimer available ? */ + if (!hpet && !pm1 && !pm2) { + printk(KERN_INFO "TSC calibrated against PIT\n"); + goto out; + } + + /* Check, whether the sampling was disturbed by an SMI */ + if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) { + printk(KERN_WARNING "TSC calibration disturbed by SMI, " + "using PIT calibration result\n"); + goto out; + } + + tsc2 = (tsc2 - tsc1) * 1000000LL; + + if (hpet) { + printk(KERN_INFO "TSC calibrated against HPET\n"); + if (hpet2 < hpet1) + hpet2 += 0x100000000ULL; + hpet2 -= hpet1; + tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); + do_div(tsc1, 1000000); + } else { + printk(KERN_INFO "TSC calibrated against PM_TIMER\n"); + if (pm2 < pm1) + pm2 += (u64)ACPI_PM_OVRRUN; + pm2 -= pm1; + tsc1 = pm2 * 1000000000LL; + do_div(tsc1, PMTMR_TICKS_PER_SEC); + } + + do_div(tsc2, tsc1); + tsc_khz_val = tsc2; + +out: + return tsc_khz_val; +} + +unsigned long native_calculate_cpu_khz(void) +{ + return tsc_calibrate(); +} + +#ifdef CONFIG_X86_32 +/* Only called from the Powernow K7 cpu freq driver */ +int recalibrate_cpu_khz(void) +{ +#ifndef CONFIG_SMP + unsigned long cpu_khz_old = cpu_khz; + + if (cpu_has_tsc) { + cpu_khz = calculate_cpu_khz(); + tsc_khz = cpu_khz; + cpu_data(0).loops_per_jiffy = + cpufreq_scale(cpu_data(0).loops_per_jiffy, + cpu_khz_old, cpu_khz); + return 0; + } else + return -ENODEV; +#else + return -ENODEV; +#endif +} + +EXPORT_SYMBOL(recalibrate_cpu_khz); + +#endif /* CONFIG_X86_32 */ diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index dc89900..40c0aaf 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -42,7 +42,7 @@ extern int tsc_disabled; DEFINE_PER_CPU(unsigned long, cyc2ns); -static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) +void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) { unsigned long long tsc_now, ns_now; unsigned long flags, *scale; @@ -65,78 +65,6 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) local_irq_restore(flags); } -unsigned long native_calculate_cpu_khz(void) -{ - unsigned long long start, end; - unsigned long count; - u64 delta64 = (u64)ULLONG_MAX; - int i; - unsigned long flags; - - local_irq_save(flags); - - /* run 3 times to ensure the cache is warm and to get an accurate reading */ - for (i = 0; i < 3; i++) { - mach_prepare_counter(); - rdtscll(start); - mach_countup(&count); - rdtscll(end); - - /* - * Error: ECTCNEVERSET - * The CTC wasn't reliable: we got a hit on the very first read, - * or the CPU was so fast/slow that the quotient wouldn't fit in - * 32 bits.. - */ - if (count <= 1) - continue; - - /* cpu freq too slow: */ - if ((end - start) <= CALIBRATE_TIME_MSEC) - continue; - - /* - * We want the minimum time of all runs in case one of them - * is inaccurate due to SMI or other delay - */ - delta64 = min(delta64, (end - start)); - } - - /* cpu freq too fast (or every run was bad): */ - if (delta64 > (1ULL<<32)) - goto err; - - delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ - do_div(delta64,CALIBRATE_TIME_MSEC); - - local_irq_restore(flags); - return (unsigned long)delta64; -err: - local_irq_restore(flags); - return 0; -} - -int recalibrate_cpu_khz(void) -{ -#ifndef CONFIG_SMP - unsigned long cpu_khz_old = cpu_khz; - - if (cpu_has_tsc) { - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; - cpu_data(0).loops_per_jiffy = - cpufreq_scale(cpu_data(0).loops_per_jiffy, - cpu_khz_old, cpu_khz); - return 0; - } else - return -ENODEV; -#else - return -ENODEV; -#endif -} - -EXPORT_SYMBOL(recalibrate_cpu_khz); - #ifdef CONFIG_CPU_FREQ /* diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index 69cbe4c..c852ff9 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c @@ -40,7 +40,7 @@ extern int tsc_disabled; DEFINE_PER_CPU(unsigned long, cyc2ns); -static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) +void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) { unsigned long long tsc_now, ns_now; unsigned long flags, *scale; @@ -130,98 +130,6 @@ core_initcall(cpufreq_tsc); #endif -#define MAX_RETRIES 5 -#define SMI_TRESHOLD 50000 - -/* - * Read TSC and the reference counters. Take care of SMI disturbance - */ -static unsigned long __init tsc_read_refs(unsigned long *pm, - unsigned long *hpet) -{ - unsigned long t1, t2; - int i; - - for (i = 0; i < MAX_RETRIES; i++) { - t1 = get_cycles(); - if (hpet) - *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; - else - *pm = acpi_pm_read_early(); - t2 = get_cycles(); - if ((t2 - t1) < SMI_TRESHOLD) - return t2; - } - return ULONG_MAX; -} - -/** - * tsc_calibrate - calibrate the tsc on boot - */ -void __init tsc_calibrate(void) -{ - unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2; - int hpet = is_hpet_enabled(), cpu; - - local_irq_save(flags); - - tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); - - outb((inb(0x61) & ~0x02) | 0x01, 0x61); - - outb(0xb0, 0x43); - outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); - outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); - tr1 = get_cycles(); - while ((inb(0x61) & 0x20) == 0); - tr2 = get_cycles(); - - tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); - - local_irq_restore(flags); - - /* - * Preset the result with the raw and inaccurate PIT - * calibration value - */ - tsc_khz = (tr2 - tr1) / 50; - - /* hpet or pmtimer available ? */ - if (!hpet && !pm1 && !pm2) { - printk(KERN_INFO "TSC calibrated against PIT\n"); - goto out; - } - - /* Check, whether the sampling was disturbed by an SMI */ - if (tsc1 == ULONG_MAX || tsc2 == ULONG_MAX) { - printk(KERN_WARNING "TSC calibration disturbed by SMI, " - "using PIT calibration result\n"); - goto out; - } - - tsc2 = (tsc2 - tsc1) * 1000000L; - - if (hpet) { - printk(KERN_INFO "TSC calibrated against HPET\n"); - if (hpet2 < hpet1) - hpet2 += 0x100000000UL; - hpet2 -= hpet1; - tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000; - } else { - printk(KERN_INFO "TSC calibrated against PM_TIMER\n"); - if (pm2 < pm1) - pm2 += ACPI_PM_OVRRUN; - pm2 -= pm1; - tsc1 = (pm2 * 1000000000) / PMTMR_TICKS_PER_SEC; - } - - tsc_khz = tsc2 / tsc1; - -out: - for_each_possible_cpu(cpu) - set_cyc2ns_scale(tsc_khz, cpu); -} - /* * Make an educated guess if the TSC is trustworthy and synchronized * over all CPUs. diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h index 6a9b4ac..82f1ac6 100644 --- a/include/asm-x86/hpet.h +++ b/include/asm-x86/hpet.h @@ -86,8 +86,8 @@ extern void hpet_unregister_irq_handler(rtc_irq_handler handler); #else /* CONFIG_HPET_TIMER */ static inline int hpet_enable(void) { return 0; } -static inline unsigned long hpet_readl(unsigned long a) { return 0; } static inline int is_hpet_enabled(void) { return 0; } +#define hpet_readl(a) 0 #endif #endif /* ASM_X86_HPET_H */ diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index 548873a..761054d 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -58,7 +58,6 @@ int check_tsc_unstable(void); extern void check_tsc_sync_source(int cpu); extern void check_tsc_sync_target(void); -extern void tsc_calibrate(void); extern int notsc_setup(char *); #endif -- cgit v0.10.2 From 2dbe06faf37b39f9ecffc054dd173b2a1dc2adcd Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 1 Jul 2008 11:43:31 -0700 Subject: x86: merge the TSC cpu-freq code Unify the TSC cpufreq code. Signed-off-by: Alok N Kataria Signed-off-by: Dan Hecht Cc: Dan Hecht Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index e6ee145..595f78a 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -215,3 +216,116 @@ int recalibrate_cpu_khz(void) EXPORT_SYMBOL(recalibrate_cpu_khz); #endif /* CONFIG_X86_32 */ + +/* Accelerators for sched_clock() + * convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_khz * 10^3)) + * ns = cycles * (10^6 / cpu_khz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^6 * SC / cpu_khz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * + * We can use khz divisor instead of mhz to keep a better precision, since + * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. + * (mathieu.desnoyers@polymtl.ca) + * + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ + +DEFINE_PER_CPU(unsigned long, cyc2ns); + +void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) +{ + unsigned long long tsc_now, ns_now; + unsigned long flags, *scale; + + local_irq_save(flags); + sched_clock_idle_sleep_event(); + + scale = &per_cpu(cyc2ns, cpu); + + rdtscll(tsc_now); + ns_now = __cycles_2_ns(tsc_now); + + if (cpu_khz) + *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; + + sched_clock_idle_wakeup_event(0); + local_irq_restore(flags); +} + +#ifdef CONFIG_CPU_FREQ + +/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency + * changes. + * + * RED-PEN: On SMP we assume all CPUs run with the same frequency. It's + * not that important because current Opteron setups do not support + * scaling on SMP anyroads. + * + * Should fix up last_tsc too. Currently gettimeofday in the + * first tick after the change will be slightly wrong. + */ + +static unsigned int ref_freq; +static unsigned long loops_per_jiffy_ref; +static unsigned long tsc_khz_ref; + +static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct cpufreq_freqs *freq = data; + unsigned long *lpj, dummy; + + if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC)) + return 0; + + lpj = &dummy; + if (!(freq->flags & CPUFREQ_CONST_LOOPS)) +#ifdef CONFIG_SMP + lpj = &cpu_data(freq->cpu).loops_per_jiffy; +#else + lpj = &boot_cpu_data.loops_per_jiffy; +#endif + + if (!ref_freq) { + ref_freq = freq->old; + loops_per_jiffy_ref = *lpj; + tsc_khz_ref = tsc_khz; + } + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || + (val == CPUFREQ_RESUMECHANGE)) { + *lpj = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); + + tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); + if (!(freq->flags & CPUFREQ_CONST_LOOPS)) + mark_tsc_unstable("cpufreq changes"); + } + + set_cyc2ns_scale(tsc_khz_ref, freq->cpu); + + return 0; +} + +static struct notifier_block time_cpufreq_notifier_block = { + .notifier_call = time_cpufreq_notifier +}; + +static int __init cpufreq_tsc(void) +{ + cpufreq_register_notifier(&time_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + return 0; +} + +core_initcall(cpufreq_tsc); + +#endif /* CONFIG_CPU_FREQ */ diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index 40c0aaf..bbc153d 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -18,119 +18,6 @@ extern int tsc_unstable; extern int tsc_disabled; -/* Accelerators for sched_clock() - * convert from cycles(64bits) => nanoseconds (64bits) - * basic equation: - * ns = cycles / (freq / ns_per_sec) - * ns = cycles * (ns_per_sec / freq) - * ns = cycles * (10^9 / (cpu_khz * 10^3)) - * ns = cycles * (10^6 / cpu_khz) - * - * Then we use scaling math (suggested by george@mvista.com) to get: - * ns = cycles * (10^6 * SC / cpu_khz) / SC - * ns = cycles * cyc2ns_scale / SC - * - * And since SC is a constant power of two, we can convert the div - * into a shift. - * - * We can use khz divisor instead of mhz to keep a better precision, since - * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. - * (mathieu.desnoyers@polymtl.ca) - * - * -johnstul@us.ibm.com "math is hard, lets go shopping!" - */ - -DEFINE_PER_CPU(unsigned long, cyc2ns); - -void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) -{ - unsigned long long tsc_now, ns_now; - unsigned long flags, *scale; - - local_irq_save(flags); - sched_clock_idle_sleep_event(); - - scale = &per_cpu(cyc2ns, cpu); - - rdtscll(tsc_now); - ns_now = __cycles_2_ns(tsc_now); - - if (cpu_khz) - *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; - - /* - * Start smoothly with the new frequency: - */ - sched_clock_idle_wakeup_event(0); - local_irq_restore(flags); -} - -#ifdef CONFIG_CPU_FREQ - -/* - * if the CPU frequency is scaled, TSC-based delays will need a different - * loops_per_jiffy value to function properly. - */ -static unsigned int ref_freq; -static unsigned long loops_per_jiffy_ref; -static unsigned long cpu_khz_ref; - -static int -time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) -{ - struct cpufreq_freqs *freq = data; - - if (!ref_freq) { - if (!freq->old){ - ref_freq = freq->new; - return 0; - } - ref_freq = freq->old; - loops_per_jiffy_ref = cpu_data(freq->cpu).loops_per_jiffy; - cpu_khz_ref = cpu_khz; - } - - if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || - (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || - (val == CPUFREQ_RESUMECHANGE)) { - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - cpu_data(freq->cpu).loops_per_jiffy = - cpufreq_scale(loops_per_jiffy_ref, - ref_freq, freq->new); - - if (cpu_khz) { - - if (num_online_cpus() == 1) - cpu_khz = cpufreq_scale(cpu_khz_ref, - ref_freq, freq->new); - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { - tsc_khz = cpu_khz; - set_cyc2ns_scale(cpu_khz, freq->cpu); - /* - * TSC based sched_clock turns - * to junk w/ cpufreq - */ - mark_tsc_unstable("cpufreq changes"); - } - } - } - - return 0; -} - -static struct notifier_block time_cpufreq_notifier_block = { - .notifier_call = time_cpufreq_notifier -}; - -static int __init cpufreq_tsc(void) -{ - return cpufreq_register_notifier(&time_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); -} -core_initcall(cpufreq_tsc); - -#endif - /* clock source code */ static struct clocksource clocksource_tsc; diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index c852ff9..80a274b 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c @@ -16,120 +16,6 @@ extern int tsc_unstable; extern int tsc_disabled; -/* Accelerators for sched_clock() - * convert from cycles(64bits) => nanoseconds (64bits) - * basic equation: - * ns = cycles / (freq / ns_per_sec) - * ns = cycles * (ns_per_sec / freq) - * ns = cycles * (10^9 / (cpu_khz * 10^3)) - * ns = cycles * (10^6 / cpu_khz) - * - * Then we use scaling math (suggested by george@mvista.com) to get: - * ns = cycles * (10^6 * SC / cpu_khz) / SC - * ns = cycles * cyc2ns_scale / SC - * - * And since SC is a constant power of two, we can convert the div - * into a shift. - * - * We can use khz divisor instead of mhz to keep a better precision, since - * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. - * (mathieu.desnoyers@polymtl.ca) - * - * -johnstul@us.ibm.com "math is hard, lets go shopping!" - */ - -DEFINE_PER_CPU(unsigned long, cyc2ns); - -void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) -{ - unsigned long long tsc_now, ns_now; - unsigned long flags, *scale; - - local_irq_save(flags); - sched_clock_idle_sleep_event(); - - scale = &per_cpu(cyc2ns, cpu); - - rdtscll(tsc_now); - ns_now = __cycles_2_ns(tsc_now); - - if (cpu_khz) - *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; - - sched_clock_idle_wakeup_event(0); - local_irq_restore(flags); -} - -#ifdef CONFIG_CPU_FREQ - -/* Frequency scaling support. Adjust the TSC based timer when the cpu frequency - * changes. - * - * RED-PEN: On SMP we assume all CPUs run with the same frequency. It's - * not that important because current Opteron setups do not support - * scaling on SMP anyroads. - * - * Should fix up last_tsc too. Currently gettimeofday in the - * first tick after the change will be slightly wrong. - */ - -static unsigned int ref_freq; -static unsigned long loops_per_jiffy_ref; -static unsigned long tsc_khz_ref; - -static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct cpufreq_freqs *freq = data; - unsigned long *lpj, dummy; - - if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC)) - return 0; - - lpj = &dummy; - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) -#ifdef CONFIG_SMP - lpj = &cpu_data(freq->cpu).loops_per_jiffy; -#else - lpj = &boot_cpu_data.loops_per_jiffy; -#endif - - if (!ref_freq) { - ref_freq = freq->old; - loops_per_jiffy_ref = *lpj; - tsc_khz_ref = tsc_khz; - } - if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || - (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || - (val == CPUFREQ_RESUMECHANGE)) { - *lpj = - cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); - - tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); - if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - mark_tsc_unstable("cpufreq changes"); - } - - set_cyc2ns_scale(tsc_khz_ref, freq->cpu); - - return 0; -} - -static struct notifier_block time_cpufreq_notifier_block = { - .notifier_call = time_cpufreq_notifier -}; - -static int __init cpufreq_tsc(void) -{ - cpufreq_register_notifier(&time_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - return 0; -} - -core_initcall(cpufreq_tsc); - -#endif - /* * Make an educated guess if the TSC is trustworthy and synchronized * over all CPUs. -- cgit v0.10.2 From 8fbbc4b45ce3e4c0eeb15004c79c72b6896a79c2 Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 1 Jul 2008 11:43:34 -0700 Subject: x86: merge tsc_init and clocksource code Unify the clocksource code. Unify the tsc_init code. Signed-off-by: Alok N Kataria Signed-off-by: Dan Hecht Cc: Dan Hecht Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index ca904ee..59b14c9 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o obj-y += alternative.o i8253.o pci-nommu.o -obj-y += tsc_$(BITS).o io_delay.o rtc.o tsc.o +obj-y += tsc.o io_delay.o rtc.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-y += process.o diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index c6ac4da..e3d49c5 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c @@ -56,7 +56,7 @@ static irqreturn_t timer_event_interrupt(int irq, void *dev_id) /* calibrate_cpu is used on systems with fixed rate TSCs to determine * processor frequency */ #define TICK_COUNT 100000000 -static unsigned long __init calibrate_cpu(void) +unsigned long __init calibrate_cpu(void) { int tsc_start, tsc_now; int i, no_ctr_free; @@ -114,41 +114,13 @@ void __init hpet_time_init(void) setup_irq(0, &irq0); } -extern void set_cyc2ns_scale(unsigned long cpu_khz, int cpu); - void __init time_init(void) { - int cpu; - - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; - - if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && - (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) - cpu_khz = calibrate_cpu(); - - lpj_fine = ((unsigned long)tsc_khz * 1000)/HZ; - - if (unsynchronized_tsc()) - mark_tsc_unstable("TSCs unsynchronized"); - + tsc_init(); if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) vgetcpu_mode = VGETCPU_RDTSCP; else vgetcpu_mode = VGETCPU_LSL; - printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - - /* - * Secondary CPUs do not run through tsc_init(), so set up - * all the scale factors for all CPUs, assuming the same - * speed as the bootup CPU. (cpufreq notifiers will fix this - * up if their speed diverges) - */ - for_each_possible_cpu(cpu) - set_cyc2ns_scale(cpu_khz, cpu); - - init_tsc_clocksource(); late_time_init = choose_time_init(); } diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 595f78a..94c16bd 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -5,8 +5,16 @@ #include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include unsigned int cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); @@ -16,12 +24,12 @@ EXPORT_SYMBOL(tsc_khz); /* * TSC can be unstable due to cpufreq or due to unsynced TSCs */ -int tsc_unstable; +static int tsc_unstable; /* native_sched_clock() is called before tsc_init(), so we must start with the TSC soft disabled to prevent erroneous rdtsc usage on !cpu_has_tsc processors */ -int tsc_disabled = -1; +static int tsc_disabled = -1; /* * Scheduler clock - returns current time in nanosec units. @@ -241,7 +249,7 @@ EXPORT_SYMBOL(recalibrate_cpu_khz); DEFINE_PER_CPU(unsigned long, cyc2ns); -void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) +static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) { unsigned long long tsc_now, ns_now; unsigned long flags, *scale; @@ -329,3 +337,201 @@ static int __init cpufreq_tsc(void) core_initcall(cpufreq_tsc); #endif /* CONFIG_CPU_FREQ */ + +/* clocksource code */ + +static struct clocksource clocksource_tsc; + +/* + * We compare the TSC to the cycle_last value in the clocksource + * structure to avoid a nasty time-warp. This can be observed in a + * very small window right after one CPU updated cycle_last under + * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which + * is smaller than the cycle_last reference value due to a TSC which + * is slighty behind. This delta is nowhere else observable, but in + * that case it results in a forward time jump in the range of hours + * due to the unsigned delta calculation of the time keeping core + * code, which is necessary to support wrapping clocksources like pm + * timer. + */ +static cycle_t read_tsc(void) +{ + cycle_t ret = (cycle_t)get_cycles(); + + return ret >= clocksource_tsc.cycle_last ? + ret : clocksource_tsc.cycle_last; +} + +static cycle_t __vsyscall_fn vread_tsc(void) +{ + cycle_t ret = (cycle_t)vget_cycles(); + + return ret >= __vsyscall_gtod_data.clock.cycle_last ? + ret : __vsyscall_gtod_data.clock.cycle_last; +} + +static struct clocksource clocksource_tsc = { + .name = "tsc", + .rating = 300, + .read = read_tsc, + .mask = CLOCKSOURCE_MASK(64), + .shift = 22, + .flags = CLOCK_SOURCE_IS_CONTINUOUS | + CLOCK_SOURCE_MUST_VERIFY, +#ifdef CONFIG_X86_64 + .vread = vread_tsc, +#endif +}; + +void mark_tsc_unstable(char *reason) +{ + if (!tsc_unstable) { + tsc_unstable = 1; + printk("Marking TSC unstable due to %s\n", reason); + /* Change only the rating, when not registered */ + if (clocksource_tsc.mult) + clocksource_change_rating(&clocksource_tsc, 0); + else + clocksource_tsc.rating = 0; + } +} + +EXPORT_SYMBOL_GPL(mark_tsc_unstable); + +static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d) +{ + printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", + d->ident); + tsc_unstable = 1; + return 0; +} + +/* List of systems that have known TSC problems */ +static struct dmi_system_id __initdata bad_tsc_dmi_table[] = { + { + .callback = dmi_mark_tsc_unstable, + .ident = "IBM Thinkpad 380XD", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), + }, + }, + {} +}; + +/* + * Geode_LX - the OLPC CPU has a possibly a very reliable TSC + */ +#ifdef CONFIG_MGEODE_LX +/* RTSC counts during suspend */ +#define RTSC_SUSP 0x100 + +static void __init check_geode_tsc_reliable(void) +{ + unsigned long res_low, res_high; + + rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); + if (res_low & RTSC_SUSP) + clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; +} +#else +static inline void check_geode_tsc_reliable(void) { } +#endif + +/* + * Make an educated guess if the TSC is trustworthy and synchronized + * over all CPUs. + */ +__cpuinit int unsynchronized_tsc(void) +{ + if (!cpu_has_tsc || tsc_unstable) + return 1; + +#ifdef CONFIG_SMP + if (apic_is_clustered_box()) + return 1; +#endif + + if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) + return 0; + /* + * Intel systems are normally all synchronized. + * Exceptions must mark TSC as unstable: + */ + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { + /* assume multi socket systems are not synchronized: */ + if (num_possible_cpus() > 1) + tsc_unstable = 1; + } + + return tsc_unstable; +} + +static void __init init_tsc_clocksource(void) +{ + clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, + clocksource_tsc.shift); + /* lower the rating if we already know its unstable: */ + if (check_tsc_unstable()) { + clocksource_tsc.rating = 0; + clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; + } + clocksource_register(&clocksource_tsc); +} + +void __init tsc_init(void) +{ + u64 lpj; + int cpu; + + if (!cpu_has_tsc) + return; + + cpu_khz = calculate_cpu_khz(); + tsc_khz = cpu_khz; + + if (!cpu_khz) { + mark_tsc_unstable("could not calculate TSC khz"); + return; + } + +#ifdef CONFIG_X86_64 + if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) + cpu_khz = calibrate_cpu(); +#endif + + lpj = ((u64)tsc_khz * 1000); + do_div(lpj, HZ); + lpj_fine = lpj; + + printk("Detected %lu.%03lu MHz processor.\n", + (unsigned long)cpu_khz / 1000, + (unsigned long)cpu_khz % 1000); + + /* + * Secondary CPUs do not run through tsc_init(), so set up + * all the scale factors for all CPUs, assuming the same + * speed as the bootup CPU. (cpufreq notifiers will fix this + * up if their speed diverges) + */ + for_each_possible_cpu(cpu) + set_cyc2ns_scale(cpu_khz, cpu); + + if (tsc_disabled > 0) + return; + + /* now allow native_sched_clock() to use rdtsc */ + tsc_disabled = 0; + + use_tsc_delay(); + /* Check and install the TSC clocksource */ + dmi_check_system(bad_tsc_dmi_table); + + if (unsynchronized_tsc()) + mark_tsc_unstable("TSCs unsynchronized"); + + check_geode_tsc_reliable(); + init_tsc_clocksource(); +} + diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c deleted file mode 100644 index bbc153d..0000000 --- a/arch/x86/kernel/tsc_32.c +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mach_timer.h" - -extern int tsc_unstable; -extern int tsc_disabled; - -/* clock source code */ - -static struct clocksource clocksource_tsc; - -/* - * We compare the TSC to the cycle_last value in the clocksource - * structure to avoid a nasty time-warp issue. This can be observed in - * a very small window right after one CPU updated cycle_last under - * xtime lock and the other CPU reads a TSC value which is smaller - * than the cycle_last reference value due to a TSC which is slighty - * behind. This delta is nowhere else observable, but in that case it - * results in a forward time jump in the range of hours due to the - * unsigned delta calculation of the time keeping core code, which is - * necessary to support wrapping clocksources like pm timer. - */ -static cycle_t read_tsc(void) -{ - cycle_t ret; - - rdtscll(ret); - - return ret >= clocksource_tsc.cycle_last ? - ret : clocksource_tsc.cycle_last; -} - -static struct clocksource clocksource_tsc = { - .name = "tsc", - .rating = 300, - .read = read_tsc, - .mask = CLOCKSOURCE_MASK(64), - .mult = 0, /* to be set */ - .shift = 22, - .flags = CLOCK_SOURCE_IS_CONTINUOUS | - CLOCK_SOURCE_MUST_VERIFY, -}; - -void mark_tsc_unstable(char *reason) -{ - if (!tsc_unstable) { - tsc_unstable = 1; - printk("Marking TSC unstable due to: %s.\n", reason); - /* Can be called before registration */ - if (clocksource_tsc.mult) - clocksource_change_rating(&clocksource_tsc, 0); - else - clocksource_tsc.rating = 0; - } -} -EXPORT_SYMBOL_GPL(mark_tsc_unstable); - -static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d) -{ - printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", - d->ident); - tsc_unstable = 1; - return 0; -} - -/* List of systems that have known TSC problems */ -static struct dmi_system_id __initdata bad_tsc_dmi_table[] = { - { - .callback = dmi_mark_tsc_unstable, - .ident = "IBM Thinkpad 380XD", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), - }, - }, - {} -}; - -/* - * Make an educated guess if the TSC is trustworthy and synchronized - * over all CPUs. - */ -__cpuinit int unsynchronized_tsc(void) -{ - if (!cpu_has_tsc || tsc_unstable) - return 1; - - /* Anything with constant TSC should be synchronized */ - if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) - return 0; - - /* - * Intel systems are normally all synchronized. - * Exceptions must mark TSC as unstable: - */ - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { - /* assume multi socket systems are not synchronized: */ - if (num_possible_cpus() > 1) - tsc_unstable = 1; - } - return tsc_unstable; -} - -/* - * Geode_LX - the OLPC CPU has a possibly a very reliable TSC - */ -#ifdef CONFIG_MGEODE_LX -/* RTSC counts during suspend */ -#define RTSC_SUSP 0x100 - -static void __init check_geode_tsc_reliable(void) -{ - unsigned long res_low, res_high; - - rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); - if (res_low & RTSC_SUSP) - clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -} -#else -static inline void check_geode_tsc_reliable(void) { } -#endif - - -void __init tsc_init(void) -{ - int cpu; - u64 lpj; - - if (!cpu_has_tsc || tsc_disabled > 0) - return; - - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; - - if (!cpu_khz) { - mark_tsc_unstable("could not calculate TSC khz"); - return; - } - - lpj = ((u64)tsc_khz * 1000); - do_div(lpj, HZ); - lpj_fine = lpj; - - /* now allow native_sched_clock() to use rdtsc */ - tsc_disabled = 0; - - printk("Detected %lu.%03lu MHz processor.\n", - (unsigned long)cpu_khz / 1000, - (unsigned long)cpu_khz % 1000); - - /* - * Secondary CPUs do not run through tsc_init(), so set up - * all the scale factors for all CPUs, assuming the same - * speed as the bootup CPU. (cpufreq notifiers will fix this - * up if their speed diverges) - */ - for_each_possible_cpu(cpu) - set_cyc2ns_scale(cpu_khz, cpu); - - use_tsc_delay(); - - /* Check and install the TSC clocksource */ - dmi_check_system(bad_tsc_dmi_table); - - unsynchronized_tsc(); - check_geode_tsc_reliable(); - clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, - clocksource_tsc.shift); - /* lower the rating if we already know its unstable: */ - if (check_tsc_unstable()) { - clocksource_tsc.rating = 0; - clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; - } - clocksource_register(&clocksource_tsc); -} diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c deleted file mode 100644 index 80a274b..0000000 --- a/arch/x86/kernel/tsc_64.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -extern int tsc_unstable; -extern int tsc_disabled; - -/* - * Make an educated guess if the TSC is trustworthy and synchronized - * over all CPUs. - */ -__cpuinit int unsynchronized_tsc(void) -{ - if (tsc_unstable) - return 1; - -#ifdef CONFIG_SMP - if (apic_is_clustered_box()) - return 1; -#endif - - if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) - return 0; - - /* Assume multi socket systems are not synchronized */ - return num_present_cpus() > 1; -} - -static struct clocksource clocksource_tsc; - -/* - * We compare the TSC to the cycle_last value in the clocksource - * structure to avoid a nasty time-warp. This can be observed in a - * very small window right after one CPU updated cycle_last under - * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which - * is smaller than the cycle_last reference value due to a TSC which - * is slighty behind. This delta is nowhere else observable, but in - * that case it results in a forward time jump in the range of hours - * due to the unsigned delta calculation of the time keeping core - * code, which is necessary to support wrapping clocksources like pm - * timer. - */ -static cycle_t read_tsc(void) -{ - cycle_t ret = (cycle_t)get_cycles(); - - return ret >= clocksource_tsc.cycle_last ? - ret : clocksource_tsc.cycle_last; -} - -static cycle_t __vsyscall_fn vread_tsc(void) -{ - cycle_t ret = (cycle_t)vget_cycles(); - - return ret >= __vsyscall_gtod_data.clock.cycle_last ? - ret : __vsyscall_gtod_data.clock.cycle_last; -} - -static struct clocksource clocksource_tsc = { - .name = "tsc", - .rating = 300, - .read = read_tsc, - .mask = CLOCKSOURCE_MASK(64), - .shift = 22, - .flags = CLOCK_SOURCE_IS_CONTINUOUS | - CLOCK_SOURCE_MUST_VERIFY, - .vread = vread_tsc, -}; - -void mark_tsc_unstable(char *reason) -{ - if (!tsc_unstable) { - tsc_unstable = 1; - printk("Marking TSC unstable due to %s\n", reason); - /* Change only the rating, when not registered */ - if (clocksource_tsc.mult) - clocksource_change_rating(&clocksource_tsc, 0); - else - clocksource_tsc.rating = 0; - } -} -EXPORT_SYMBOL_GPL(mark_tsc_unstable); - -void __init init_tsc_clocksource(void) -{ - if (tsc_disabled > 0) - return; - - clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, - clocksource_tsc.shift); - if (check_tsc_unstable()) - clocksource_tsc.rating = 0; - - clocksource_register(&clocksource_tsc); -} diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index a298077..4e2c1e5 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -121,12 +121,17 @@ extern void enable_NMI_through_LVT0(void); */ #ifdef CONFIG_X86_64 extern void early_init_lapic_mapping(void); +extern int apic_is_clustered_box(void); +#else +static inline int apic_is_clustered_box(void) +{ + return 0; +} #endif extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask); extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask); -extern int apic_is_clustered_box(void); #else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown(void) { } diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h index 409a649..bb80880 100644 --- a/include/asm-x86/delay.h +++ b/include/asm-x86/delay.h @@ -26,6 +26,10 @@ extern void __delay(unsigned long loops); ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) +#ifdef CONFIG_X86_32 void use_tsc_delay(void); +#else +#define use_tsc_delay() {} +#endif #endif /* _ASM_X86_DELAY_H */ diff --git a/include/asm-x86/time.h b/include/asm-x86/time.h index bce72d7..a17fa47 100644 --- a/include/asm-x86/time.h +++ b/include/asm-x86/time.h @@ -56,4 +56,6 @@ static inline int native_set_wallclock(unsigned long nowtime) #endif /* CONFIG_PARAVIRT */ +extern unsigned long __init calibrate_cpu(void); + #endif diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index 761054d..cb6f6ee 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -48,7 +48,6 @@ static __always_inline cycles_t vget_cycles(void) extern void tsc_init(void); extern void mark_tsc_unstable(char *reason); extern int unsynchronized_tsc(void); -extern void init_tsc_clocksource(void); int check_tsc_unstable(void); /* -- cgit v0.10.2 From e93ef949fd9a3f237aedfb8e64414b28980530b8 Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 1 Jul 2008 11:43:36 -0700 Subject: x86: rename paravirtualized TSC functions Rename the paravirtualized calculate_cpu_khz to calibrate_tsc. In all cases, we actually calibrate_tsc and use that as the cpu_khz value. Signed-off-by: Alok N Kataria Signed-off-by: Dan Hecht Cc: Dan Hecht Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index e7e5652..e0f571d 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -285,7 +285,7 @@ struct pv_time_ops pv_time_ops = { .get_wallclock = native_get_wallclock, .set_wallclock = native_set_wallclock, .sched_clock = native_sched_clock, - .get_cpu_khz = native_calculate_cpu_khz, + .get_tsc_khz = native_calibrate_tsc, }; struct pv_irq_ops pv_irq_ops = { diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 94c16bd..3c36f92 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -123,9 +123,9 @@ static u64 __init tsc_read_refs(u64 *pm, u64 *hpet) } /** - * tsc_calibrate - calibrate the tsc on boot + * native_calibrate_tsc - calibrate the tsc on boot */ -static unsigned int __init tsc_calibrate(void) +unsigned long native_calibrate_tsc(void) { unsigned long flags; u64 tsc1, tsc2, tr1, tr2, delta, pm1, pm2, hpet1, hpet2; @@ -195,10 +195,6 @@ out: return tsc_khz_val; } -unsigned long native_calculate_cpu_khz(void) -{ - return tsc_calibrate(); -} #ifdef CONFIG_X86_32 /* Only called from the Powernow K7 cpu freq driver */ @@ -208,8 +204,8 @@ int recalibrate_cpu_khz(void) unsigned long cpu_khz_old = cpu_khz; if (cpu_has_tsc) { - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; + tsc_khz = calibrate_tsc(); + cpu_khz = tsc_khz; cpu_data(0).loops_per_jiffy = cpufreq_scale(cpu_data(0).loops_per_jiffy, cpu_khz_old, cpu_khz); @@ -487,10 +483,10 @@ void __init tsc_init(void) if (!cpu_has_tsc) return; - cpu_khz = calculate_cpu_khz(); - tsc_khz = cpu_khz; + tsc_khz = calibrate_tsc(); + cpu_khz = tsc_khz; - if (!cpu_khz) { + if (!tsc_khz) { mark_tsc_unstable("could not calculate TSC khz"); return; } diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index 946bf13..b153460 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c @@ -932,7 +932,7 @@ static inline int __init activate_vmi(void) pv_apic_ops.setup_secondary_clock = vmi_time_ap_init; #endif pv_time_ops.sched_clock = vmi_sched_clock; - pv_time_ops.get_cpu_khz = vmi_cpu_khz; + pv_time_ops.get_tsc_khz = vmi_tsc_khz; /* We have true wallclock functions; disable CMOS clock sync */ no_sync_cmos_clock = 1; diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index ba7d19e..6953859 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -69,8 +69,8 @@ unsigned long long vmi_sched_clock(void) return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE)); } -/* paravirt_ops.get_cpu_khz = vmi_cpu_khz */ -unsigned long vmi_cpu_khz(void) +/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */ +unsigned long vmi_tsc_khz(void) { unsigned long long khz; khz = vmi_timer_ops.get_cycle_frequency(); diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index e72cf07..50dad44 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -607,7 +607,7 @@ static unsigned long lguest_get_wallclock(void) * what speed it runs at, or 0 if it's unusable as a reliable clock source. * This matches what we want here: if we return 0 from this function, the x86 * TSC clock will give up and not register itself. */ -static unsigned long lguest_cpu_khz(void) +static unsigned long lguest_tsc_khz(void) { return lguest_data.tsc_khz; } @@ -998,7 +998,7 @@ __init void lguest_init(void) /* time operations */ pv_time_ops.get_wallclock = lguest_get_wallclock; pv_time_ops.time_init = lguest_time_init; - pv_time_ops.get_cpu_khz = lguest_cpu_khz; + pv_time_ops.get_tsc_khz = lguest_tsc_khz; /* Now is a good time to look at the implementations of these functions * before returning to the rest of lguest_init(). */ diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 3b98083..dcd4e51 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1062,7 +1062,7 @@ static const struct pv_time_ops xen_time_ops __initdata = { .set_wallclock = xen_set_wallclock, .get_wallclock = xen_get_wallclock, - .get_cpu_khz = xen_cpu_khz, + .get_tsc_khz = xen_tsc_khz, .sched_clock = xen_sched_clock, }; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 64f0038..685b774 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -197,8 +197,8 @@ unsigned long long xen_sched_clock(void) } -/* Get the CPU speed from Xen */ -unsigned long xen_cpu_khz(void) +/* Get the TSC speed from Xen */ +unsigned long xen_tsc_khz(void) { u64 xen_khz = 1000000ULL << 32; const struct pvclock_vcpu_time_info *info = diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 9a05559..d852ddb 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -32,7 +32,7 @@ void __init xen_build_dynamic_phys_to_machine(void); void xen_setup_timer(int cpu); void xen_setup_cpu_clockevents(void); -unsigned long xen_cpu_khz(void); +unsigned long xen_tsc_khz(void); void __init xen_time_init(void); unsigned long xen_get_wallclock(void); int xen_set_wallclock(unsigned long time); diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 6d8966f..ef5e8ec 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -84,7 +84,7 @@ struct pv_time_ops { int (*set_wallclock)(unsigned long); unsigned long long (*sched_clock)(void); - unsigned long (*get_cpu_khz)(void); + unsigned long (*get_tsc_khz)(void); }; struct pv_cpu_ops { @@ -779,7 +779,7 @@ static inline unsigned long long paravirt_sched_clock(void) { return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock); } -#define calculate_cpu_khz() (pv_time_ops.get_cpu_khz()) +#define calibrate_tsc() (pv_time_ops.get_tsc_khz()) static inline unsigned long long paravirt_read_pmc(int counter) { diff --git a/include/asm-x86/timer.h b/include/asm-x86/timer.h index 4f6fcb0..fb2a4dd 100644 --- a/include/asm-x86/timer.h +++ b/include/asm-x86/timer.h @@ -7,14 +7,14 @@ #define TICK_SIZE (tick_nsec / 1000) unsigned long long native_sched_clock(void); -unsigned long native_calculate_cpu_khz(void); +unsigned long native_calibrate_tsc(void); extern int timer_ack; extern int no_timer_check; extern int recalibrate_cpu_khz(void); #ifndef CONFIG_PARAVIRT -#define calculate_cpu_khz() native_calculate_cpu_khz() +#define calibrate_tsc() native_calibrate_tsc() #endif /* Accelerators for sched_clock() diff --git a/include/asm-x86/vmi_time.h b/include/asm-x86/vmi_time.h index 4781881..c3118c3 100644 --- a/include/asm-x86/vmi_time.h +++ b/include/asm-x86/vmi_time.h @@ -50,7 +50,7 @@ extern void __init vmi_time_init(void); extern unsigned long vmi_get_wallclock(void); extern int vmi_set_wallclock(unsigned long now); extern unsigned long long vmi_sched_clock(void); -extern unsigned long vmi_cpu_khz(void); +extern unsigned long vmi_tsc_khz(void); #ifdef CONFIG_X86_LOCAL_APIC extern void __devinit vmi_time_bsp_init(void); -- cgit v0.10.2 From a8c1be9d2e78d8608892c86791837acf12da4bf6 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 01:29:44 +0200 Subject: x86: initial changes to unify traps_32.c and traps_64.c This patch does not change the generated object files. Signed-off-by: Alexander van Heukelum Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index d7cc292..9243969 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -1,5 +1,6 @@ /* * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs * * Pentium III FXSR, SSE support * Gareth Hughes , May 2000 @@ -130,7 +131,8 @@ void printk_address(unsigned long address, int reliable) #endif } -static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size) +static inline int valid_stack_ptr(struct thread_info *tinfo, + void *p, unsigned int size) { return p > (void *)tinfo && p <= (void *)tinfo + THREAD_SIZE - size; @@ -138,14 +140,14 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned s /* The form of the top of the frame on the stack */ struct stack_frame { - struct stack_frame *next_frame; - unsigned long return_address; + struct stack_frame *next_frame; + unsigned long return_address; }; static inline unsigned long print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) + unsigned long *stack, unsigned long bp, + const struct stacktrace_ops *ops, void *data) { struct stack_frame *frame = (struct stack_frame *)bp; @@ -167,8 +169,6 @@ print_context_stack(struct thread_info *tinfo, return bp; } -#define MSG(msg) ops->warning(data, msg) - void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data) @@ -178,7 +178,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!stack) { unsigned long dummy; - stack = &dummy; if (task != current) stack = (unsigned long *)task->thread.sp; @@ -196,7 +195,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, } #endif - while (1) { + for (;;) { struct thread_info *context; context = (struct thread_info *) @@ -248,10 +247,10 @@ static void print_trace_address(void *data, unsigned long addr, int reliable) } static const struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, + .warning = print_trace_warning, + .warning_symbol = print_trace_warning_symbol, + .stack = print_trace_stack, + .address = print_trace_address, }; static void @@ -351,15 +350,14 @@ void show_registers(struct pt_regs *regs) printk(KERN_EMERG "Code: "); ip = (u8 *)regs->ip - code_prologue; - if (ip < (u8 *)PAGE_OFFSET || - probe_kernel_address(ip, c)) { + if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at EIP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || - probe_kernel_address(ip, c)) { + probe_kernel_address(ip, c)) { printk(" Bad EIP value."); break; } @@ -546,7 +544,7 @@ void do_##name(struct pt_regs *regs, long error_code) \ { \ trace_hardirqs_fixup(); \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ - == NOTIFY_STOP) \ + == NOTIFY_STOP) \ return; \ do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ } @@ -562,7 +560,7 @@ void do_##name(struct pt_regs *regs, long error_code) \ info.si_code = sicode; \ info.si_addr = (void __user *)siaddr; \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ - == NOTIFY_STOP) \ + == NOTIFY_STOP) \ return; \ do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ } @@ -571,7 +569,7 @@ void do_##name(struct pt_regs *regs, long error_code) \ void do_##name(struct pt_regs *regs, long error_code) \ { \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ - == NOTIFY_STOP) \ + == NOTIFY_STOP) \ return; \ do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ } @@ -586,22 +584,22 @@ void do_##name(struct pt_regs *regs, long error_code) \ info.si_addr = (void __user *)siaddr; \ trace_hardirqs_fixup(); \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ - == NOTIFY_STOP) \ + == NOTIFY_STOP) \ return; \ do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ } -DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) +DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) #ifndef CONFIG_KPROBES DO_VM86_ERROR(3, SIGTRAP, "int3", int3) #endif DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds) -DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) -DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0) +DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) -DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) -DO_ERROR(12, SIGBUS, "stack segment", stack_segment) +DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) +DO_ERROR(12, SIGBUS, "stack segment", stack_segment) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) @@ -799,7 +797,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) - == NOTIFY_STOP) + == NOTIFY_STOP) return; #ifdef CONFIG_X86_LOCAL_APIC /* @@ -818,6 +816,8 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) return; + + /* AK: following checks seem to be broken on modern chipsets. FIXME */ if (reason & 0x80) mem_parity_error(reason, regs); if (reason & 0x40) @@ -915,7 +915,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code) tsk->thread.debugctlmsr = 0; if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, - SIGTRAP) == NOTIFY_STOP) + SIGTRAP) == NOTIFY_STOP) return; /* It's safe to allow irq's after DR6 has been saved */ if (regs->flags & X86_EFLAGS_IF) @@ -997,7 +997,7 @@ void math_error(void __user *ip) * C1 reg you need in case of a stack fault, 0x040 is the stack * fault bit. We should only be taking one exception at a time, * so if this combination doesn't produce any single exception, - * then we have a bad program that isn't syncronizing its FPU usage + * then we have a bad program that isn't synchronizing its FPU usage * and it will suffer the consequences since we won't be able to * fully reproduce the context of the exception */ @@ -1006,7 +1006,7 @@ void math_error(void __user *ip) switch (swd & ~cwd & 0x3f) { case 0x000: /* No unmasked exception */ return; - default: /* Multiple exceptions */ + default: /* Multiple exceptions */ break; case 0x001: /* Invalid Op */ /* @@ -1198,16 +1198,16 @@ void __init trap_init(void) early_iounmap(p, 4); #endif - set_trap_gate(0, ÷_error); - set_intr_gate(1, &debug); - set_intr_gate(2, &nmi); - set_system_intr_gate(3, &int3); /* int3/4 can be called from all */ - set_system_gate(4, &overflow); - set_trap_gate(5, &bounds); - set_trap_gate(6, &invalid_op); - set_trap_gate(7, &device_not_available); - set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); - set_trap_gate(9, &coprocessor_segment_overrun); + set_trap_gate(0, ÷_error); + set_intr_gate(1, &debug); + set_intr_gate(2, &nmi); + set_system_intr_gate(3, &int3); /* int3 can be called from all */ + set_system_gate(4, &overflow); /* int4 can be called from all */ + set_trap_gate(5, &bounds); + set_trap_gate(6, &invalid_op); + set_trap_gate(7, &device_not_available); + set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); + set_trap_gate(9, &coprocessor_segment_overrun); set_trap_gate(10, &invalid_TSS); set_trap_gate(11, &segment_not_present); set_trap_gate(12, &stack_segment); diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 80ba6d3..686074e 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -205,8 +205,6 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } -#define MSG(txt) ops->warning(data, txt) - /* * x86-64 can have up to three kernel stacks: * process stack @@ -233,11 +231,11 @@ struct stack_frame { unsigned long return_address; }; - -static inline unsigned long print_context_stack(struct thread_info *tinfo, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data, - unsigned long *end) +static inline unsigned long +print_context_stack(struct thread_info *tinfo, + unsigned long *stack, unsigned long bp, + const struct stacktrace_ops *ops, void *data, + unsigned long *end) { struct stack_frame *frame = (struct stack_frame *)bp; @@ -259,7 +257,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, return bp; } -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, +void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data) { @@ -268,31 +266,29 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned used = 0; struct thread_info *tinfo; - if (!tsk) - tsk = current; - tinfo = task_thread_info(tsk); + if (!task) + task = current; + tinfo = task_thread_info(task); if (!stack) { unsigned long dummy; stack = &dummy; - if (tsk && tsk != current) - stack = (unsigned long *)tsk->thread.sp; + if (task && task != current) + stack = (unsigned long *)task->thread.sp; } #ifdef CONFIG_FRAME_POINTER if (!bp) { - if (tsk == current) { + if (task == current) { /* Grab bp right from our regs */ - asm("movq %%rbp, %0" : "=r" (bp):); + asm("movq %%rbp, %0" : "=r" (bp) :); } else { /* bp is the last reg pushed by switch_to */ - bp = *(unsigned long *) tsk->thread.sp; + bp = *(unsigned long *) task->thread.sp; } } #endif - - /* * Print function call entries in all stacks, starting at the * current stack address. If the stacks consist of nested @@ -382,18 +378,17 @@ static const struct stacktrace_ops print_trace_ops = { .address = print_trace_address, }; -void -show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, - unsigned long bp) +void show_trace(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, unsigned long bp) { printk("\nCall Trace:\n"); - dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL); + dump_trace(task, regs, stack, bp, &print_trace_ops, NULL); printk("\n"); } static void -_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp, - unsigned long bp) +_show_stack(struct task_struct *task, struct pt_regs *regs, + unsigned long *sp, unsigned long bp) { unsigned long *stack; int i; @@ -405,14 +400,14 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp, // back trace for this cpu. if (sp == NULL) { - if (tsk) - sp = (unsigned long *)tsk->thread.sp; + if (task) + sp = (unsigned long *)task->thread.sp; else sp = (unsigned long *)&sp; } stack = sp; - for(i=0; i < kstack_depth_to_print; i++) { + for (i = 0; i < kstack_depth_to_print; i++) { if (stack >= irqstack && stack <= irqstack_end) { if (stack == irqstack_end) { stack = (unsigned long *) (irqstack_end[-1]); @@ -427,12 +422,12 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp, printk(" %016lx", *stack++); touch_nmi_watchdog(); } - show_trace(tsk, regs, sp, bp); + show_trace(task, regs, sp, bp); } -void show_stack(struct task_struct *tsk, unsigned long * sp) +void show_stack(struct task_struct *task, unsigned long *sp) { - _show_stack(tsk, NULL, sp, 0); + _show_stack(task, NULL, sp, 0); } /* @@ -440,7 +435,7 @@ void show_stack(struct task_struct *tsk, unsigned long * sp) */ void dump_stack(void) { - unsigned long dummy; + unsigned long stack; unsigned long bp = 0; #ifdef CONFIG_FRAME_POINTER @@ -453,7 +448,7 @@ void dump_stack(void) init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); - show_trace(NULL, NULL, &dummy, bp); + show_trace(NULL, NULL, &stack, bp); } EXPORT_SYMBOL(dump_stack); @@ -488,7 +483,7 @@ void show_registers(struct pt_regs *regs) printk(KERN_EMERG "Code: "); if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at RIP */ - ip = (u8 *) regs->ip; + ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { @@ -504,7 +499,7 @@ void show_registers(struct pt_regs *regs) } } printk("\n"); -} +} int is_valid_bugaddr(unsigned long ip) { @@ -576,8 +571,10 @@ int __kprobes __die(const char * str, struct pt_regs * regs, long err) printk("DEBUG_PAGEALLOC"); #endif printk("\n"); - if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) + if (notify_die(DIE_OOPS, str, regs, err, + current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) return 1; + show_registers(regs); add_taint(TAINT_DIE); /* Executive summary in case the oops scrolled away */ @@ -589,7 +586,7 @@ int __kprobes __die(const char * str, struct pt_regs * regs, long err) return 0; } -void die(const char * str, struct pt_regs * regs, long err) +void die(const char * str, struct pt_regs *regs, long err) { unsigned long flags = oops_begin(); @@ -606,8 +603,7 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic) { unsigned long flags; - if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == - NOTIFY_STOP) + if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP) return; flags = oops_begin(); @@ -629,9 +625,9 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic) do_exit(SIGBUS); } -static void __kprobes do_trap(int trapnr, int signr, char *str, - struct pt_regs * regs, long error_code, - siginfo_t *info) +static void __kprobes +do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, + long error_code, siginfo_t *info) { struct task_struct *tsk = current; @@ -676,38 +672,38 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, } #define DO_ERROR(trapnr, signr, str, name) \ -asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ -{ \ - if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ - == NOTIFY_STOP) \ - return; \ +asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ +{ \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ + == NOTIFY_STOP) \ + return; \ conditional_sti(regs); \ - do_trap(trapnr, signr, str, regs, error_code, NULL); \ + do_trap(trapnr, signr, str, regs, error_code, NULL); \ } -#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ -asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ -{ \ - siginfo_t info; \ - info.si_signo = signr; \ - info.si_errno = 0; \ - info.si_code = sicode; \ - info.si_addr = (void __user *)siaddr; \ - trace_hardirqs_fixup(); \ - if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ - == NOTIFY_STOP) \ - return; \ +#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ +asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ +{ \ + siginfo_t info; \ + info.si_signo = signr; \ + info.si_errno = 0; \ + info.si_code = sicode; \ + info.si_addr = (void __user *)siaddr; \ + trace_hardirqs_fixup(); \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ + == NOTIFY_STOP) \ + return; \ conditional_sti(regs); \ - do_trap(trapnr, signr, str, regs, error_code, &info); \ + do_trap(trapnr, signr, str, regs, error_code, &info); \ } -DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) -DO_ERROR( 4, SIGSEGV, "overflow", overflow) -DO_ERROR( 5, SIGSEGV, "bounds", bounds) -DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip) -DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) +DO_ERROR(4, SIGSEGV, "overflow", overflow) +DO_ERROR(5, SIGSEGV, "bounds", bounds) +DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip) +DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) -DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) +DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) /* Runs on IST stack */ @@ -775,14 +771,14 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, } static notrace __kprobes void -mem_parity_error(unsigned char reason, struct pt_regs * regs) +mem_parity_error(unsigned char reason, struct pt_regs *regs) { printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", reason); printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); #if defined(CONFIG_EDAC) - if(edac_handler_set()) { + if (edac_handler_set()) { edac_atomic_assert_error(); return; } @@ -799,7 +795,7 @@ mem_parity_error(unsigned char reason, struct pt_regs * regs) } static notrace __kprobes void -io_check_error(unsigned char reason, struct pt_regs * regs) +io_check_error(unsigned char reason, struct pt_regs *regs) { printk("NMI: IOCK error (debug interrupt?)\n"); show_registers(regs); @@ -836,7 +832,7 @@ asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) cpu = smp_processor_id(); - /* Only the BSP gets external NMIs from the system. */ + /* Only the BSP gets external NMIs from the system. */ if (!cpu) reason = get_nmi_reason(); @@ -848,18 +844,17 @@ asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog_tick(regs,reason)) + if (nmi_watchdog_tick(regs, reason)) return; - if (!do_nmi_callback(regs,cpu)) + if (!do_nmi_callback(regs, cpu)) unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) - return; + return; /* AK: following checks seem to be broken on modern chipsets. FIXME */ - if (reason & 0x80) mem_parity_error(reason, regs); if (reason & 0x40) @@ -870,9 +865,12 @@ asmlinkage notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) { nmi_enter(); + add_pda(__nmi_count, 1); + if (!ignore_nmis) default_do_nmi(regs); + nmi_exit(); } @@ -889,13 +887,14 @@ void restart_nmi(void) } /* runs on IST stack. */ -asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code) +asmlinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) { trace_hardirqs_fixup(); - if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) { + if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) + == NOTIFY_STOP) return; - } + preempt_conditional_sti(regs); do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); preempt_conditional_cli(regs); @@ -948,21 +947,19 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs, /* Mask out spurious debug traps due to lazy DR7 setting */ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { - if (!tsk->thread.debugreg7) { + if (!tsk->thread.debugreg7) goto clear_dr7; - } } tsk->thread.debugreg6 = condition; - /* * Single-stepping through TF: make sure we ignore any events in * kernel space (but re-enable TF when returning to user mode). */ if (condition & DR_STEP) { - if (!user_mode(regs)) - goto clear_TF_reenable; + if (!user_mode(regs)) + goto clear_TF_reenable; } /* Ok, finally something we can handle */ @@ -975,7 +972,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs, force_sig_info(SIGTRAP, &info, tsk); clear_dr7: - set_debugreg(0UL, 7); + set_debugreg(0, 7); preempt_conditional_cli(regs); return; @@ -983,6 +980,7 @@ clear_TF_reenable: set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs->flags &= ~X86_EFLAGS_TF; preempt_conditional_cli(regs); + return; } static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) @@ -1005,7 +1003,7 @@ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) asmlinkage void do_coprocessor_error(struct pt_regs *regs) { void __user *ip = (void __user *)(regs->ip); - struct task_struct * task; + struct task_struct *task; siginfo_t info; unsigned short cwd, swd; @@ -1038,30 +1036,30 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs) cwd = get_fpu_cwd(task); swd = get_fpu_swd(task); switch (swd & ~cwd & 0x3f) { - case 0x000: - default: - break; - case 0x001: /* Invalid Op */ - /* - * swd & 0x240 == 0x040: Stack Underflow - * swd & 0x240 == 0x240: Stack Overflow - * User must clear the SF bit (0x40) if set - */ - info.si_code = FPE_FLTINV; - break; - case 0x002: /* Denormalize */ - case 0x010: /* Underflow */ - info.si_code = FPE_FLTUND; - break; - case 0x004: /* Zero Divide */ - info.si_code = FPE_FLTDIV; - break; - case 0x008: /* Overflow */ - info.si_code = FPE_FLTOVF; - break; - case 0x020: /* Precision */ - info.si_code = FPE_FLTRES; - break; + case 0x000: /* No unmasked exception */ + default: /* Multiple exceptions */ + break; + case 0x001: /* Invalid Op */ + /* + * swd & 0x240 == 0x040: Stack Underflow + * swd & 0x240 == 0x240: Stack Overflow + * User must clear the SF bit (0x40) if set + */ + info.si_code = FPE_FLTINV; + break; + case 0x002: /* Denormalize */ + case 0x010: /* Underflow */ + info.si_code = FPE_FLTUND; + break; + case 0x004: /* Zero Divide */ + info.si_code = FPE_FLTDIV; + break; + case 0x008: /* Overflow */ + info.si_code = FPE_FLTOVF; + break; + case 0x020: /* Precision */ + info.si_code = FPE_FLTRES; + break; } force_sig_info(SIGFPE, &info, task); } @@ -1074,7 +1072,7 @@ asmlinkage void bad_intr(void) asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) { void __user *ip = (void __user *)(regs->ip); - struct task_struct * task; + struct task_struct *task; siginfo_t info; unsigned short mxcsr; @@ -1102,25 +1100,25 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) */ mxcsr = get_fpu_mxcsr(task); switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) { - case 0x000: - default: - break; - case 0x001: /* Invalid Op */ - info.si_code = FPE_FLTINV; - break; - case 0x002: /* Denormalize */ - case 0x010: /* Underflow */ - info.si_code = FPE_FLTUND; - break; - case 0x004: /* Zero Divide */ - info.si_code = FPE_FLTDIV; - break; - case 0x008: /* Overflow */ - info.si_code = FPE_FLTOVF; - break; - case 0x020: /* Precision */ - info.si_code = FPE_FLTRES; - break; + case 0x000: + default: + break; + case 0x001: /* Invalid Op */ + info.si_code = FPE_FLTINV; + break; + case 0x002: /* Denormalize */ + case 0x010: /* Underflow */ + info.si_code = FPE_FLTUND; + break; + case 0x004: /* Zero Divide */ + info.si_code = FPE_FLTDIV; + break; + case 0x008: /* Overflow */ + info.si_code = FPE_FLTOVF; + break; + case 0x020: /* Precision */ + info.si_code = FPE_FLTRES; + break; } force_sig_info(SIGFPE, &info, task); } @@ -1138,7 +1136,7 @@ asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void) } /* - * 'math_state_restore()' saves the current math information in the + * 'math_state_restore()' saves the current math information in the * old math state array, and gets the new ones from the current task * * Careful.. There are problems with IBM-designed IRQ13 behaviour. @@ -1163,7 +1161,7 @@ asmlinkage void math_state_restore(void) local_irq_disable(); } - clts(); /* Allow maths ops (or we recurse) */ + clts(); /* Allow maths ops (or we recurse) */ restore_fpu_checking(&me->thread.xstate->fxsave); task_thread_info(me)->status |= TS_USEDFPU; me->fpu_counter++; @@ -1172,64 +1170,61 @@ EXPORT_SYMBOL_GPL(math_state_restore); void __init trap_init(void) { - set_intr_gate(0,÷_error); - set_intr_gate_ist(1,&debug,DEBUG_STACK); - set_intr_gate_ist(2,&nmi,NMI_STACK); - set_system_gate_ist(3,&int3,DEBUG_STACK); /* int3 can be called from all */ - set_system_gate(4,&overflow); /* int4 can be called from all */ - set_intr_gate(5,&bounds); - set_intr_gate(6,&invalid_op); - set_intr_gate(7,&device_not_available); - set_intr_gate_ist(8,&double_fault, DOUBLEFAULT_STACK); - set_intr_gate(9,&coprocessor_segment_overrun); - set_intr_gate(10,&invalid_TSS); - set_intr_gate(11,&segment_not_present); - set_intr_gate_ist(12,&stack_segment,STACKFAULT_STACK); - set_intr_gate(13,&general_protection); - set_intr_gate(14,&page_fault); - set_intr_gate(15,&spurious_interrupt_bug); - set_intr_gate(16,&coprocessor_error); - set_intr_gate(17,&alignment_check); + set_intr_gate(0, ÷_error); + set_intr_gate_ist(1, &debug, DEBUG_STACK); + set_intr_gate_ist(2, &nmi, NMI_STACK); + set_system_gate_ist(3, &int3, DEBUG_STACK); /* int3 can be called from all */ + set_system_gate(4, &overflow); /* int4 can be called from all */ + set_intr_gate(5, &bounds); + set_intr_gate(6, &invalid_op); + set_intr_gate(7, &device_not_available); + set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK); + set_intr_gate(9, &coprocessor_segment_overrun); + set_intr_gate(10, &invalid_TSS); + set_intr_gate(11, &segment_not_present); + set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK); + set_intr_gate(13, &general_protection); + set_intr_gate(14, &page_fault); + set_intr_gate(15, &spurious_interrupt_bug); + set_intr_gate(16, &coprocessor_error); + set_intr_gate(17, &alignment_check); #ifdef CONFIG_X86_MCE - set_intr_gate_ist(18,&machine_check, MCE_STACK); + set_intr_gate_ist(18, &machine_check, MCE_STACK); #endif - set_intr_gate(19,&simd_coprocessor_error); + set_intr_gate(19, &simd_coprocessor_error); #ifdef CONFIG_IA32_EMULATION set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall); #endif - /* * initialize the per thread extended state: */ init_thread_xstate(); /* - * Should be a barrier for any external CPU state. + * Should be a barrier for any external CPU state: */ cpu_init(); } - static int __init oops_setup(char *s) -{ +{ if (!s) return -EINVAL; if (!strcmp(s, "panic")) panic_on_oops = 1; return 0; -} +} early_param("oops", oops_setup); static int __init kstack_setup(char *s) { if (!s) return -EINVAL; - kstack_depth_to_print = simple_strtoul(s,NULL,0); + kstack_depth_to_print = simple_strtoul(s, NULL, 0); return 0; } early_param("kstack", kstack_setup); - static int __init code_bytes_setup(char *s) { code_bytes = simple_strtoul(s, NULL, 0); -- cgit v0.10.2 From badc76527f7e29302f0bde3d366c59101fb2ab87 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 01:30:30 +0200 Subject: x86: traps_xx: shuffle headers and globals Reorder headers and collect globals in traps_32.c and traps_64.c Code size and data size are unaffected by the changes. Code itself is changed due to different ordering of data and bss. The bss segment changed size due to a change in the packing of the variables. Signed-off-by: Alexander van Heukelum Acked-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 9243969..5339af4 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -61,8 +61,6 @@ #include "mach_traps.h" -int panic_on_unrecovered_nmi; - DECLARE_BITMAP(used_vectors, NR_VECTORS); EXPORT_SYMBOL_GPL(used_vectors); @@ -99,8 +97,11 @@ asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); +int panic_on_unrecovered_nmi; int kstack_depth_to_print = 24; static unsigned int code_bytes = 64; +static int ignore_nmis; +static int die_counter; void printk_address(unsigned long address, int reliable) { @@ -382,8 +383,6 @@ int is_valid_bugaddr(unsigned long ip) return ud2 == 0x0b0f; } -static int die_counter; - int __kprobes __die(const char *str, struct pt_regs *regs, long err) { unsigned short ss; @@ -829,8 +828,6 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) reassert_nmi(); } -static int ignore_nmis; - notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) { int cpu; diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 686074e..03d63b0 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -10,49 +10,49 @@ * 'Traps.c' handles hardware traps and faults after we have saved some * state in 'entry.S'. */ -#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include #include -#include +#include +#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include - -#include +#include +#include #if defined(CONFIG_EDAC) #include #endif -#include -#include -#include +#include +#include #include +#include +#include +#include #include #include -#include -#include +#include #include +#include #include -#include #include -#include -#include +#include + +#include asmlinkage void divide_error(void); asmlinkage void debug(void); @@ -72,12 +72,14 @@ asmlinkage void page_fault(void); asmlinkage void coprocessor_error(void); asmlinkage void simd_coprocessor_error(void); asmlinkage void alignment_check(void); -asmlinkage void machine_check(void); asmlinkage void spurious_interrupt_bug(void); +asmlinkage void machine_check(void); int panic_on_unrecovered_nmi; +int kstack_depth_to_print = 12; static unsigned int code_bytes = 64; -static unsigned ignore_nmis; +static int ignore_nmis; +static int die_counter; static inline void conditional_sti(struct pt_regs *regs) { @@ -101,8 +103,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) dec_preempt_count(); } -int kstack_depth_to_print = 12; - void printk_address(unsigned long address, int reliable) { #ifdef CONFIG_KALLSYMS @@ -559,7 +559,6 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) int __kprobes __die(const char * str, struct pt_regs * regs, long err) { - static int die_counter; printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); -- cgit v0.10.2 From e423f49fc8ccd761618748d7139638d8ddc1d16f Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 01:31:03 +0200 Subject: x86: traps_xx: modify __die if (cond) block -> if (!cond) goto end_of_block Signed-off-by: Alexander van Heukelum Acked-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 5339af4..5afd94a 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -399,26 +399,22 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) printk("DEBUG_PAGEALLOC"); #endif printk("\n"); - if (notify_die(DIE_OOPS, str, regs, err, - current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) { - - show_registers(regs); - /* Executive summary in case the oops scrolled away */ - sp = (unsigned long) (®s->sp); - savesegment(ss, ss); - if (user_mode(regs)) { - sp = regs->sp; - ss = regs->ss & 0xffff; - } - printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); - print_symbol("%s", regs->ip); - printk(" SS:ESP %04x:%08lx\n", ss, sp); + current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) + return 1; - return 0; + show_registers(regs); + /* Executive summary in case the oops scrolled away */ + sp = (unsigned long) (®s->sp); + savesegment(ss, ss); + if (user_mode(regs)) { + sp = regs->sp; + ss = regs->ss & 0xffff; } - - return 1; + printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); + print_symbol("%s", regs->ip); + printk(" SS:ESP %04x:%08lx\n", ss, sp); + return 0; } /* diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 03d63b0..019a06f 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -557,9 +557,9 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) do_exit(signr); } -int __kprobes __die(const char * str, struct pt_regs * regs, long err) +int __kprobes __die(const char *str, struct pt_regs *regs, long err) { - printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); + printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); #endif -- cgit v0.10.2 From a7bbb0ce1d1f956c8491b925c74767adf654f373 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 01:31:34 +0200 Subject: x86: traps_xx: modify do_trap if (cond) block -> if (!cond) goto end_of_block Signed-off-by: Alexander van Heukelum Acked-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 019a06f..1c2d533 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -630,38 +630,38 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, { struct task_struct *tsk = current; - if (user_mode(regs)) { - /* - * We want error_code and trap_no set for userspace - * faults and kernelspace faults which result in - * die(), but not kernelspace faults which are fixed - * up. die() gives the process no chance to handle - * the signal and notice the kernel fault information, - * so that won't result in polluting the information - * about previously queued, but not yet delivered, - * faults. See also do_general_protection below. - */ - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; - - if (show_unhandled_signals && unhandled_signal(tsk, signr) && - printk_ratelimit()) { - printk(KERN_INFO - "%s[%d] trap %s ip:%lx sp:%lx error:%lx", - tsk->comm, tsk->pid, str, - regs->ip, regs->sp, error_code); - print_vma_addr(" in ", regs->ip); - printk("\n"); - } + if (!user_mode(regs)) + goto kernel_trap; - if (info) - force_sig_info(signr, info, tsk); - else - force_sig(signr, tsk); - return; + /* + * We want error_code and trap_no set for userspace faults and + * kernelspace faults which result in die(), but not + * kernelspace faults which are fixed up. die() gives the + * process no chance to handle the signal and notice the + * kernel fault information, so that won't result in polluting + * the information about previously queued, but not yet + * delivered, faults. See also do_general_protection below. + */ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + + if (show_unhandled_signals && unhandled_signal(tsk, signr) && + printk_ratelimit()) { + printk(KERN_INFO + "%s[%d] trap %s ip:%lx sp:%lx error:%lx", + tsk->comm, tsk->pid, str, + regs->ip, regs->sp, error_code); + print_vma_addr(" in ", regs->ip); + printk("\n"); } + if (info) + force_sig_info(signr, info, tsk); + else + force_sig(signr, tsk); + return; +kernel_trap: if (!fixup_exception(regs)) { tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; -- cgit v0.10.2 From 13485ab55bc77f02024e80bcca0374950b0becb3 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 01:32:04 +0200 Subject: x86: traps_xx: restructure do_general_protection() - if (cond) block -> if (!cond) goto end_of_block - local caching of current Signed-off-by: Alexander van Heukelum Acked-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 5afd94a..c9a0120 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -598,8 +598,10 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) -void __kprobes do_general_protection(struct pt_regs *regs, long error_code) +void __kprobes +do_general_protection(struct pt_regs *regs, long error_code) { + struct task_struct *tsk; struct thread_struct *thread; struct tss_struct *tss; int cpu; @@ -640,23 +642,24 @@ void __kprobes do_general_protection(struct pt_regs *regs, long error_code) if (regs->flags & X86_VM_MASK) goto gp_in_vm86; + tsk = current; if (!user_mode(regs)) goto gp_in_kernel; - current->thread.error_code = error_code; - current->thread.trap_no = 13; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; - if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && - printk_ratelimit()) { + if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && + printk_ratelimit()) { printk(KERN_INFO - "%s[%d] general protection ip:%lx sp:%lx error:%lx", - current->comm, task_pid_nr(current), - regs->ip, regs->sp, error_code); + "%s[%d] general protection ip:%lx sp:%lx error:%lx", + tsk->comm, task_pid_nr(tsk), + regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); printk("\n"); } - force_sig(SIGSEGV, current); + force_sig(SIGSEGV, tsk); return; gp_in_vm86: @@ -665,14 +668,15 @@ gp_in_vm86: return; gp_in_kernel: - if (!fixup_exception(regs)) { - current->thread.error_code = error_code; - current->thread.trap_no = 13; - if (notify_die(DIE_GPF, "general protection fault", regs, + if (fixup_exception(regs)) + return; + + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) - return; - die("general protection fault", regs, error_code); - } + return; + die("general protection fault", regs, error_code); } static notrace __kprobes void diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 1c2d533..bc21ddc 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -733,31 +733,34 @@ asmlinkage void do_double_fault(struct pt_regs * regs, long error_code) die(str, regs, error_code); } -asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, - long error_code) +asmlinkage void __kprobes +do_general_protection(struct pt_regs *regs, long error_code) { - struct task_struct *tsk = current; + struct task_struct *tsk; conditional_sti(regs); - if (user_mode(regs)) { - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 13; - - if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && - printk_ratelimit()) { - printk(KERN_INFO - "%s[%d] general protection ip:%lx sp:%lx error:%lx", - tsk->comm, tsk->pid, - regs->ip, regs->sp, error_code); - print_vma_addr(" in ", regs->ip); - printk("\n"); - } + tsk = current; + if (!user_mode(regs)) + goto gp_in_kernel; - force_sig(SIGSEGV, tsk); - return; - } + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + + if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && + printk_ratelimit()) { + printk(KERN_INFO + "%s[%d] general protection ip:%lx sp:%lx error:%lx", + tsk->comm, tsk->pid, + regs->ip, regs->sp, error_code); + print_vma_addr(" in ", regs->ip); + printk("\n"); + } + + force_sig(SIGSEGV, tsk); + return; +gp_in_kernel: if (fixup_exception(regs)) return; -- cgit v0.10.2 From abd348072798aa88d48fe9f182ac3440fcb7ae47 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 18:39:01 +0200 Subject: x86: traps_xx: modify default_do_nmi - local caching of smp_processor_id() in default_do_nmi() - v2: do not split default_do_nmi over two lines On Wed, Jul 02, 2008 at 08:12:20PM +0400, Cyrill Gorcunov wrote: > | -static notrace __kprobes void default_do_nmi(struct pt_regs *regs) > | +static notrace __kprobes void > | +default_do_nmi(struct pt_regs *regs) > | [ ... ] > | -asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) > | +asmlinkage notrace __kprobes void > | +default_do_nmi(struct pt_regs *regs) > > Hi Alexander, good done, thanks! But why did you split default_do_nmi > definition by two lines? I think it would be better to keep them as it > was before, ie by a single line > > static notrace __kprobes void default_do_nmi(struct pt_regs *regs) Thanks! Here is the replacement patch with default_do_nmi left on a single line. Signed-off-by: Alexander van Heukelum Acked-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index c9a0120..fb8e3cc 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -789,9 +789,12 @@ void notrace __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) static notrace __kprobes void default_do_nmi(struct pt_regs *regs) { unsigned char reason = 0; + int cpu; + + cpu = smp_processor_id(); - /* Only the BSP gets external NMIs from the system: */ - if (!smp_processor_id()) + /* Only the BSP gets external NMIs from the system. */ + if (!cpu) reason = get_nmi_reason(); if (!(reason & 0xc0)) { @@ -805,7 +808,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs) */ if (nmi_watchdog_tick(regs, reason)) return; - if (!do_nmi_callback(regs, smp_processor_id())) + if (!do_nmi_callback(regs, cpu)) unknown_nmi_error(reason, regs); #else unknown_nmi_error(reason, regs); diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index bc21ddc..9b9245f 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -827,7 +827,7 @@ unknown_nmi_error(unsigned char reason, struct pt_regs * regs) /* Runs on IST stack. This code must keep interrupts off all the time. Nested NMIs are prevented by the CPU. */ -asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) +asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) { unsigned char reason = 0; int cpu; -- cgit v0.10.2 From 7b4fd4bb2e7fad2c41afab4683a44ab77f6f35d0 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 2 Jul 2008 01:33:14 +0200 Subject: x86: traps_xx: various small changes - order of local variable declarations - minor code changes Signed-off-by: Alexander van Heukelum Acked-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index fb8e3cc..8a76897 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -106,13 +106,13 @@ static int die_counter; void printk_address(unsigned long address, int reliable) { #ifdef CONFIG_KALLSYMS - char namebuf[KSYM_NAME_LEN]; unsigned long offset = 0; unsigned long symsize; const char *symname; - char reliab[4] = ""; - char *delim = ":"; char *modname; + char *delim = ":"; + char namebuf[KSYM_NAME_LEN]; + char reliab[4] = ""; symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); @@ -135,8 +135,8 @@ void printk_address(unsigned long address, int reliable) static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned int size) { - return p > (void *)tinfo && - p <= (void *)tinfo + THREAD_SIZE - size; + void *t = tinfo; + return p > t && p <= t + THREAD_SIZE - size; } /* The form of the top of the frame on the stack */ @@ -976,9 +976,8 @@ clear_TF_reenable: void math_error(void __user *ip) { struct task_struct *task; - unsigned short cwd; - unsigned short swd; siginfo_t info; + unsigned short cwd, swd; /* * Save the info for the exception handler and clear the error. @@ -1042,8 +1041,8 @@ void do_coprocessor_error(struct pt_regs *regs, long error_code) static void simd_math_error(void __user *ip) { struct task_struct *task; - unsigned short mxcsr; siginfo_t info; + unsigned short mxcsr; /* * Save the info for the exception handler and clear the error. diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 9b9245f..74e9929 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -268,7 +268,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!task) task = current; - tinfo = task_thread_info(task); if (!stack) { unsigned long dummy; @@ -294,6 +293,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, * current stack address. If the stacks consist of nested * exceptions */ + tinfo = task_thread_info(task); for (;;) { char *id; unsigned long *estack_end; @@ -435,8 +435,8 @@ void show_stack(struct task_struct *task, unsigned long *sp) */ void dump_stack(void) { - unsigned long stack; unsigned long bp = 0; + unsigned long stack; #ifdef CONFIG_FRAME_POINTER if (!bp) @@ -459,12 +459,8 @@ void show_registers(struct pt_regs *regs) unsigned long sp; const int cpu = smp_processor_id(); struct task_struct *cur = cpu_pda(cpu)->pcurrent; - u8 *ip; - unsigned int code_prologue = code_bytes * 43 / 64; - unsigned int code_len = code_bytes; sp = regs->sp; - ip = (u8 *) regs->ip - code_prologue; printk("CPU %d ", cpu); __show_regs(regs); printk("Process %s (pid: %d, threadinfo %p, task %p)\n", @@ -475,12 +471,18 @@ void show_registers(struct pt_regs *regs) * time of the fault.. */ if (!user_mode(regs)) { + unsigned int code_prologue = code_bytes * 43 / 64; + unsigned int code_len = code_bytes; unsigned char c; + u8 *ip; + printk("Stack: "); _show_stack(NULL, regs, (unsigned long *)sp, regs->bp); printk("\n"); printk(KERN_EMERG "Code: "); + + ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at RIP */ ip = (u8 *)regs->ip; @@ -585,7 +587,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) return 0; } -void die(const char * str, struct pt_regs *regs, long err) +void die(const char *str, struct pt_regs *regs, long err) { unsigned long flags = oops_begin(); @@ -927,8 +929,8 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) asmlinkage void __kprobes do_debug(struct pt_regs * regs, unsigned long error_code) { - unsigned long condition; struct task_struct *tsk = current; + unsigned long condition; siginfo_t info; trace_hardirqs_fixup(); @@ -1201,7 +1203,7 @@ void __init trap_init(void) /* * initialize the per thread extended state: */ - init_thread_xstate(); + init_thread_xstate(); /* * Should be a barrier for any external CPU state: */ -- cgit v0.10.2 From 6f585e01614f38195599c1bc5379d3c9dae6be47 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 4 Jul 2008 12:36:21 +0200 Subject: arch/x86/kernel/smpboot.c: fix warning arch/x86/kernel/smpboot.c: In function 'do_boot_cpu': arch/x86/kernel/smpboot.c:943: warning: label 'restore_state' defined but not used Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index e1200b2..f35c2d8 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -939,9 +939,9 @@ do_rest: inquire_remote_apic(apicid); } } - +#ifdef CONFIG_X86_64 restore_state: - +#endif if (boot_error) { /* Try to put things back the way they were before ... */ numa_remove_cpu(cpu); /* was set by numa_add_cpu */ -- cgit v0.10.2 From 5ed4273af8469ca4723d4bf1bcd3abe2cc792e9f Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 4 Jul 2008 12:36:21 +0200 Subject: arch/x86/mm/pgtable_32.c: remove unused variable `fixmaps' arch/x86/mm/pgtable_32.c:144: warning: 'fixmaps' defined but not used Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 828907d..b4becbf 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -141,7 +141,6 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) __flush_tlb_one(vaddr); } -static int fixmaps; unsigned long __FIXADDR_TOP = 0xfffff000; EXPORT_SYMBOL(__FIXADDR_TOP); -- cgit v0.10.2 From e407dffd17dcb592e1605a2b3dbbb81f9f3cbc21 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 9 Jul 2008 08:00:15 +0200 Subject: x86, uv: build fix for "x86, uv: update x86 mmr list for SGI uv" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: In file included from arch/x86/kernel/genx2apic_uv_x.c:25: include/asm/uv/uv_mmrs.h:986: error: redefinition of ‘union uvh_rh_gam_cfg_overlay_config_mmr_u’ include/asm/uv/uv_mmrs.h:988: error: redefinition of ‘struct uvh_rh_gam_cfg_overlay_config_mmr_s’ include/asm/uv/uv_mmrs.h:1064: error: redefinition of ‘union uvh_rh_gam_mmioh_overlay_config_mmr_u’ include/asm/uv/uv_mmrs.h:1066: error: redefinition of ‘struct uvh_rh_gam_mmioh_overlay_config_mmr_s’ caused by duplicate section (cut & paste error) in commit 5d061e397db1 "x86, uv: update x86 mmr list for SGI uv". Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uv/uv_mmrs.h b/include/asm-x86/uv/uv_mmrs.h index eb59201..a8a1ad5 100644 --- a/include/asm-x86/uv/uv_mmrs.h +++ b/include/asm-x86/uv/uv_mmrs.h @@ -974,26 +974,6 @@ union uvh_rh_gam_cfg_overlay_config_mmr_u { }; /* ========================================================================= */ -/* UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR 0x1600020UL - -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_cfg_overlay_config_mmr_u { - unsigned long v; - struct uvh_rh_gam_cfg_overlay_config_mmr_s { - unsigned long rsvd_0_25: 26; /* */ - unsigned long base : 20; /* RW */ - unsigned long rsvd_46_62: 17; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL -- cgit v0.10.2 From 26e9e57b106445bbd8c965985e4e8af5293ae005 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 9 Jul 2008 08:02:54 +0200 Subject: x86, uv: build fix #2 for "x86, uv: update x86 mmr list for SGI uv" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: In file included from arch/x86/kernel/tlb_uv.c:14: include/asm/uv/uv_mmrs.h:986: error: redefinition of ‘union uvh_rh_gam_cfg_overlay_config_mmr_u’ include/asm/uv/uv_mmrs.h:988: error: redefinition of ‘struct uvh_rh_gam_cfg_overlay_config_mmr_s’ include/asm/uv/uv_mmrs.h:1064: error: redefinition of ‘union uvh_rh_gam_mmioh_overlay_config_mmr_u’ include/asm/uv/uv_mmrs.h:1066: error: redefinition of ‘struct uvh_rh_gam_mmioh_overlay_config_mmr_s’ caused by another duplicate section (cut & paste error) in commit 5d061e397db1 "x86, uv: update x86 mmr list for SGI uv". Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uv/uv_mmrs.h b/include/asm-x86/uv/uv_mmrs.h index a8a1ad5..151fd7f 100644 --- a/include/asm-x86/uv/uv_mmrs.h +++ b/include/asm-x86/uv/uv_mmrs.h @@ -1028,32 +1028,6 @@ union uvh_rh_gam_mmioh_overlay_config_mmr_u { }; /* ========================================================================= */ -/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_mmioh_overlay_config_mmr_u { - unsigned long v; - struct uvh_rh_gam_mmioh_overlay_config_mmr_s { - unsigned long rsvd_0_29: 30; /* */ - unsigned long base : 16; /* RW */ - unsigned long m_io : 6; /* RW */ - unsigned long n_io : 4; /* RW */ - unsigned long rsvd_56_62: 7; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ /* UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL -- cgit v0.10.2 From 88b90c96b787ecb5c72384b6873468f814cce650 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Wed, 2 Jul 2008 04:17:05 +1000 Subject: powerpc/ps3: Quiet system bus match output Reduce the output verbosity of ps3_system_bus_match(). Signed-off-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 43c493f..cf215e9 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -349,9 +349,14 @@ static int ps3_system_bus_match(struct device *_dev, result = dev->match_id == drv->match_id; - pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__, - dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name, - (result ? "match" : "miss")); + if (result) + pr_info("%s:%d: dev=%u(%s), drv=%u(%s): match\n", __func__, + __LINE__, dev->match_id, dev->core.bus_id, + drv->match_id, drv->core.name); + else + pr_debug("%s:%d: dev=%u(%s), drv=%u(%s): miss\n", __func__, + __LINE__, dev->match_id, dev->core.bus_id, + drv->match_id, drv->core.name); return result; } @@ -362,7 +367,7 @@ static int ps3_system_bus_probe(struct device *_dev) struct ps3_system_bus_driver *drv; BUG_ON(!dev); - pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); + pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); drv = ps3_system_bus_dev_to_system_bus_drv(dev); BUG_ON(!drv); @@ -370,10 +375,10 @@ static int ps3_system_bus_probe(struct device *_dev) if (drv->probe) result = drv->probe(dev); else - pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, + pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__, dev->core.bus_id); - pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); + pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); return result; } @@ -384,7 +389,7 @@ static int ps3_system_bus_remove(struct device *_dev) struct ps3_system_bus_driver *drv; BUG_ON(!dev); - pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); + pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); drv = ps3_system_bus_dev_to_system_bus_drv(dev); BUG_ON(!drv); @@ -395,7 +400,7 @@ static int ps3_system_bus_remove(struct device *_dev) dev_dbg(&dev->core, "%s:%d %s: no remove method\n", __func__, __LINE__, drv->core.name); - pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); + pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); return result; } -- cgit v0.10.2 From fabb657005edbbcb0d13ee49a40f1f4b042a1d19 Mon Sep 17 00:00:00 2001 From: Maxim Shchetynin Date: Sat, 5 Jul 2008 05:05:39 +1000 Subject: powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info As nr_active counter includes also spus waiting for syscalls to return we need a seperate counter that only counts spus that are currently running on spu side. This counter shall be used by a cpufreq governor that targets a frequency dependent from the number of running spus. Signed-off-by: Christian Krafft Acked-by: Jeremy Kerr Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index afb92d4..3465474 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -994,6 +994,7 @@ void spuctx_switch_state(struct spu_context *ctx, struct timespec ts; struct spu *spu; enum spu_utilization_state old_state; + int node; ktime_get_ts(&ts); curtime = timespec_to_ns(&ts); @@ -1015,6 +1016,11 @@ void spuctx_switch_state(struct spu_context *ctx, spu->stats.times[old_state] += delta; spu->stats.util_state = new_state; spu->stats.tstamp = curtime; + node = spu->node; + if (old_state == SPU_UTIL_USER) + atomic_dec(&cbe_spu_info[node].busy_spus); + if (new_state == SPU_UTIL_USER); + atomic_inc(&cbe_spu_info[node].busy_spus); } } diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index 99348c1..8b2eb04 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -191,6 +191,7 @@ struct cbe_spu_info { struct list_head spus; int n_spus; int nr_active; + atomic_t busy_spus; atomic_t reserved_spus; }; -- cgit v0.10.2 From c8692362db3db3a6f644e05a477161d967430aac Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:41 +1000 Subject: powerpc/dma: Add struct iommu_table argument to iommu_map_sg() Make iommu_map_sg take a struct iommu_table. It did so before commit 740c3ce66700640a6e6136ff679b067e92125794 (iommu sg merging: ppc: make iommu respect the segment size limits). This stops the function looking in the archdata.dma_data for the iommu table because in the future it will be called with a device that has no table there. This also has the nice side effect of making iommu_map_sg() match the other map functions. Signed-off-by: Mark Nelson Signed-off-by: Arnd Bergmann Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 3a317cb..73974450 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -68,7 +68,7 @@ static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle, static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction) { - return iommu_map_sg(dev, sglist, nelems, + return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems, device_to_mask(dev), direction); } diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 0c66366..ccf00fe 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -267,11 +267,10 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, spin_unlock_irqrestore(&(tbl->it_lock), flags); } -int iommu_map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, unsigned long mask, - enum dma_data_direction direction) +int iommu_map_sg(struct device *dev, struct iommu_table *tbl, + struct scatterlist *sglist, int nelems, + unsigned long mask, enum dma_data_direction direction) { - struct iommu_table *tbl = dev->archdata.dma_data; dma_addr_t dma_next = 0, dma_addr; unsigned long flags; struct scatterlist *s, *outs, *segstart; diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index 852e15f..65f6682 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h @@ -79,9 +79,9 @@ extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, int nid); -extern int iommu_map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, unsigned long mask, - enum dma_data_direction direction); +extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, + struct scatterlist *sglist, int nelems, + unsigned long mask, enum dma_data_direction direction); extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, int nelems, enum dma_data_direction direction); -- cgit v0.10.2 From 3affedc4e1ce837033b6c5e9289d2ce2f5a62d31 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:42 +1000 Subject: powerpc/dma: implement new dma_*map*_attrs() interfaces Update powerpc to use the new dma_*map*_attrs() interfaces. In doing so update struct dma_mapping_ops to accept a struct dma_attrs and propagate these changes through to all users of the code (generic IOMMU and the 64bit DMA code, and the iseries and ps3 platform code). The old dma_*map_*() interfaces are reimplemented as calls to the corresponding new interfaces. Signed-off-by: Mark Nelson Signed-off-by: Arnd Bergmann Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f2a0f50..462c86a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -110,6 +110,7 @@ config PPC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_LMB + select HAVE_DMA_ATTRS config EARLY_PRINTK bool diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 73974450..3ae0c35 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -50,32 +50,38 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size, */ static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { return iommu_map_single(dev, dev->archdata.dma_data, vaddr, size, - device_to_mask(dev), direction); + device_to_mask(dev), direction, attrs); } static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { - iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction); + iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction, + attrs); } static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs) { return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems, - device_to_mask(dev), direction); + device_to_mask(dev), direction, attrs); } static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs) { - iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction); + iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction, + attrs); } /* We support DMA to/from any memory page via the iommu */ @@ -148,19 +154,22 @@ static void dma_direct_free_coherent(struct device *dev, size_t size, static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { return virt_to_abs(ptr) + get_dma_direct_offset(dev); } static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { } static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) { struct scatterlist *sg; int i; @@ -174,7 +183,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, } static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) { } diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 9971159..e3b1fcd 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -82,7 +82,8 @@ static void ibmebus_free_coherent(struct device *dev, static dma_addr_t ibmebus_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { return (dma_addr_t)(ptr); } @@ -90,14 +91,16 @@ static dma_addr_t ibmebus_map_single(struct device *dev, static void ibmebus_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { return; } static int ibmebus_map_sg(struct device *dev, struct scatterlist *sgl, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) { struct scatterlist *sg; int i; @@ -112,7 +115,8 @@ static int ibmebus_map_sg(struct device *dev, static void ibmebus_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) { return; } diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ccf00fe..8c68ee9 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -269,7 +269,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, int iommu_map_sg(struct device *dev, struct iommu_table *tbl, struct scatterlist *sglist, int nelems, - unsigned long mask, enum dma_data_direction direction) + unsigned long mask, enum dma_data_direction direction, + struct dma_attrs *attrs) { dma_addr_t dma_next = 0, dma_addr; unsigned long flags; @@ -411,7 +412,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs) { struct scatterlist *sg; unsigned long flags; @@ -553,7 +555,7 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name) */ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, void *vaddr, size_t size, unsigned long mask, - enum dma_data_direction direction) + enum dma_data_direction direction, struct dma_attrs *attrs) { dma_addr_t dma_handle = DMA_ERROR_CODE; unsigned long uaddr; @@ -586,7 +588,8 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, } void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction) + size_t size, enum dma_data_direction direction, + struct dma_attrs *attrs) { unsigned int npages; diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 11fa3c7..ab5d868 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -214,13 +214,13 @@ dma_addr_t iseries_hv_map(void *vaddr, size_t size, enum dma_data_direction direction) { return iommu_map_single(NULL, &vio_iommu_table, vaddr, size, - DMA_32BIT_MASK, direction); + DMA_32BIT_MASK, direction, NULL); } void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); + iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction, NULL); } void __init iommu_vio_init(void) diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index cf215e9..d66c362 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -555,7 +555,7 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, */ static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, struct dma_attrs *attrs) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); int result; @@ -575,7 +575,8 @@ static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size, static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, size_t size, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); int result; @@ -608,7 +609,7 @@ static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, } static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) + size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); int result; @@ -622,7 +623,7 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, } static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, struct dma_attrs *attrs) { #if defined(CONFIG_PS3_DYNAMIC_DMA) BUG_ON("do"); @@ -651,14 +652,15 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl, static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) + enum dma_data_direction direction, + struct dma_attrs *attrs) { BUG(); return 0; } static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, struct dma_attrs *attrs) { #if defined(CONFIG_PS3_DYNAMIC_DMA) BUG_ON("do"); @@ -666,7 +668,8 @@ static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg, } static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) { BUG(); } diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index bbefb69..de13950 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -13,6 +13,7 @@ /* need struct page definitions */ #include #include +#include #include #define DMA_ERROR_CODE (~(dma_addr_t)0x0) @@ -53,13 +54,17 @@ struct dma_mapping_ops { void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_single)(struct device *dev, void *ptr, - size_t size, enum dma_data_direction direction); + size_t size, enum dma_data_direction direction, + struct dma_attrs *attrs); void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction); + size_t size, enum dma_data_direction direction, + struct dma_attrs *attrs); int (*map_sg)(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction); + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs); void (*unmap_sg)(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction); + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs); int (*dma_supported)(struct device *dev, u64 mask); int (*set_dma_mask)(struct device *dev, u64 dma_mask); }; @@ -109,6 +114,77 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } +static inline dma_addr_t dma_map_single_attrs(struct device *dev, + void *cpu_addr, + size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + return dma_ops->map_single(dev, cpu_addr, size, direction, attrs); +} + +static inline void dma_unmap_single_attrs(struct device *dev, + dma_addr_t dma_addr, + size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + dma_ops->unmap_single(dev, dma_addr, size, direction, attrs); +} + +static inline dma_addr_t dma_map_page_attrs(struct device *dev, + struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + return dma_ops->map_single(dev, page_address(page) + offset, size, + direction, attrs); +} + +static inline void dma_unmap_page_attrs(struct device *dev, + dma_addr_t dma_address, + size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + dma_ops->unmap_single(dev, dma_address, size, direction, attrs); +} + +static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + return dma_ops->map_sg(dev, sg, nents, direction, attrs); +} + +static inline void dma_unmap_sg_attrs(struct device *dev, + struct scatterlist *sg, + int nhwentries, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs); +} + static inline void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { @@ -131,63 +207,43 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - return dma_ops->map_single(dev, cpu_addr, size, direction); + return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL); } static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - dma_ops->unmap_single(dev, dma_addr, size, direction); + dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL); } static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - return dma_ops->map_single(dev, page_address(page) + offset, size, - direction); + return dma_map_page_attrs(dev, page, offset, size, direction, NULL); } static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - dma_ops->unmap_single(dev, dma_address, size, direction); + dma_unmap_page_attrs(dev, dma_address, size, direction, NULL); } static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - return dma_ops->map_sg(dev, sg, nents, direction); + return dma_map_sg_attrs(dev, sg, nents, direction, NULL); } static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - dma_ops->unmap_sg(dev, sg, nhwentries, direction); + dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL); } - /* * Available generic sets of operations */ diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index 65f6682..51ecfef 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h @@ -81,9 +81,11 @@ extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, struct scatterlist *sglist, int nelems, - unsigned long mask, enum dma_data_direction direction); + unsigned long mask, enum dma_data_direction direction, + struct dma_attrs *attrs); extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction); + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs); extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl, size_t size, dma_addr_t *dma_handle, @@ -92,9 +94,11 @@ extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle); extern dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl, void *vaddr, size_t size, unsigned long mask, - enum dma_data_direction direction); + enum dma_data_direction direction, + struct dma_attrs *attrs); extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction); + size_t size, enum dma_data_direction direction, + struct dma_attrs *attrs); extern void iommu_init_early_pSeries(void); extern void iommu_init_early_iSeries(void); -- cgit v0.10.2 From 7e5f8105030038de94b44a74cd7b64dd000830fc Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:44 +1000 Subject: powerpc/cell: cell_dma_dev_setup_iommu() return the iommu table Make cell_dma_dev_setup_iommu() return a pointer to the struct iommu_table (or NULL if no table can be found) rather than putting this pointer into dev->archdata.dma_data (let the caller do that), and rename this function to cell_get_iommu_table() to reflect this change. This will allow us to get the iommu table for a device that doesn't have the table in the archdata. Signed-off-by: Mark Nelson Signed-off-by: Arnd Bergmann Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 45646b2..eeacb3a 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -540,7 +540,7 @@ static unsigned long cell_dma_direct_offset; static unsigned long dma_iommu_fixed_base; struct dma_mapping_ops dma_iommu_fixed_ops; -static void cell_dma_dev_setup_iommu(struct device *dev) +static struct iommu_table *cell_get_iommu_table(struct device *dev) { struct iommu_window *window; struct cbe_iommu *iommu; @@ -555,11 +555,11 @@ static void cell_dma_dev_setup_iommu(struct device *dev) printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", archdata->of_node ? archdata->of_node->full_name : "?", archdata->numa_node); - return; + return NULL; } window = list_entry(iommu->windows.next, struct iommu_window, list); - archdata->dma_data = &window->table; + return &window->table; } static void cell_dma_dev_setup_fixed(struct device *dev); @@ -572,7 +572,7 @@ static void cell_dma_dev_setup(struct device *dev) if (get_dma_ops(dev) == &dma_iommu_fixed_ops) cell_dma_dev_setup_fixed(dev); else if (get_pci_dma_ops() == &dma_iommu_ops) - cell_dma_dev_setup_iommu(dev); + archdata->dma_data = cell_get_iommu_table(dev); else if (get_pci_dma_ops() == &dma_direct_ops) archdata->dma_data = (void *)cell_dma_direct_offset; else -- cgit v0.10.2 From 3a4c6f0b1540811110a59112b4c83f55c229728c Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Sat, 5 Jul 2008 05:05:45 +1000 Subject: powerpc: move device_to_mask() to dma-mapping.h Move device_to_mask() to dma-mapping.h because we need to use it from outside dma_64.c in a later patch. Signed-off-by: Mark Nelson Signed-off-by: Arnd Bergmann Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 3ae0c35..ae5708e 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -15,15 +15,6 @@ * Generic iommu implementation */ -static inline unsigned long device_to_mask(struct device *dev) -{ - if (dev->dma_mask && *dev->dma_mask) - return *dev->dma_mask; - /* Assume devices without mask can take 32 bit addresses */ - return 0xfffffffful; -} - - /* Allocates a contiguous real buffer and creates mappings over it. * Returns the virtual address of the buffer and sets dma_handle * to the dma address (mapping) of the first page. diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index de13950..74c5497 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -45,6 +45,15 @@ extern void __dma_sync_page(struct page *page, unsigned long offset, #endif /* ! CONFIG_NOT_COHERENT_CACHE */ #ifdef CONFIG_PPC64 + +static inline unsigned long device_to_mask(struct device *dev) +{ + if (dev->dma_mask && *dev->dma_mask) + return *dev->dma_mask; + /* Assume devices without mask can take 32 bit addresses */ + return 0xfffffffful; +} + /* * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO */ -- cgit v0.10.2 From 058c78f4ba89df7b2de82ac271452f09e2b8fa05 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2008 13:44:31 +1000 Subject: powerpc: Use new printk extension %pS to print symbols on oops This changes the oops and backtrace code to use the new %pS printk extension to print out symbols rather than manually calling print_symbol. Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 85e5573..0a4eb08 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -485,10 +485,8 @@ void show_regs(struct pt_regs * regs) * Lookup NIP late so we have the best change of getting the * above info out without failing */ - printk("NIP ["REG"] ", regs->nip); - print_symbol("%s\n", regs->nip); - printk("LR ["REG"] ", regs->link); - print_symbol("%s\n", regs->link); + printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); + printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); #endif show_stack(current, (unsigned long *) regs->gpr[1]); if (!user_mode(regs)) @@ -976,8 +974,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) newsp = stack[0]; ip = stack[STACK_FRAME_LR_SAVE]; if (!firstframe || ip != lr) { - printk("["REG"] ["REG"] ", sp, ip); - print_symbol("%s", ip); + printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); if (firstframe) printk(" (unreliable)"); printk("\n"); @@ -992,10 +989,9 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { struct pt_regs *regs = (struct pt_regs *) (sp + STACK_FRAME_OVERHEAD); - printk("--- Exception: %lx", regs->trap); - print_symbol(" at %s\n", regs->nip); lr = regs->link; - print_symbol(" LR = %s\n", lr); + printk("--- Exception: %lx at %pS\n LR = %pS\n", + regs->trap, (void *)regs->nip, (void *)lr); firstframe = 1; } -- cgit v0.10.2 From e5093ff05d36c64e8f36a9ddb26358256dc133ea Mon Sep 17 00:00:00 2001 From: Srinivasa Ds Date: Tue, 8 Jul 2008 00:22:27 +1000 Subject: powerpc: Implement task_pt_regs() accessor The task_pt_regs() macro allows access to the pt_regs of a given task. This macro is not currently defined for the powerpc architecture, but we need it for some upcoming utrace additions. Signed-off-by: Srinivasa DS Signed-off-by: Benjamin Herrenschmidt diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h index 061cd17..101ed87 100644 --- a/include/asm-powerpc/processor.h +++ b/include/asm-powerpc/processor.h @@ -234,6 +234,8 @@ struct thread_struct { #define thread_saved_pc(tsk) \ ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) +#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.regs) + unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) -- cgit v0.10.2 From b845f313d78e4e259ec449909e3bbadf77b53a6d Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:51 +1000 Subject: mm: Allow architectures to define additional protection bits This patch allows architectures to define functions to deal with additional protections bits for mmap() and mprotect(). arch_calc_vm_prot_bits() maps additonal protection bits to vm_flags arch_vm_get_page_prot() maps additional vm_flags to the vma's vm_page_prot arch_validate_prot() checks for valid values of the protection bits Note: vm_get_page_prot() is now pretty ugly, but the generated code should be identical for architectures that don't define additional protection bits. Signed-off-by: Dave Kleikamp Acked-by: Andrew Morton Acked-by: Hugh Dickins Signed-off-by: Benjamin Herrenschmidt diff --git a/include/linux/mman.h b/include/linux/mman.h index dab8892..30d1073 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -34,6 +34,32 @@ static inline void vm_unacct_memory(long pages) } /* + * Allow architectures to handle additional protection bits + */ + +#ifndef arch_calc_vm_prot_bits +#define arch_calc_vm_prot_bits(prot) 0 +#endif + +#ifndef arch_vm_get_page_prot +#define arch_vm_get_page_prot(vm_flags) __pgprot(0) +#endif + +#ifndef arch_validate_prot +/* + * This is called from mprotect(). PROT_GROWSDOWN and PROT_GROWSUP have + * already been masked out. + * + * Returns true if the prot flags are valid + */ +static inline int arch_validate_prot(unsigned long prot) +{ + return (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM)) == 0; +} +#define arch_validate_prot arch_validate_prot +#endif + +/* * Optimisation macro. It is equivalent to: * (x & bit1) ? bit2 : 0 * but this version is faster. @@ -51,7 +77,8 @@ calc_vm_prot_bits(unsigned long prot) { return _calc_vm_trans(prot, PROT_READ, VM_READ ) | _calc_vm_trans(prot, PROT_WRITE, VM_WRITE) | - _calc_vm_trans(prot, PROT_EXEC, VM_EXEC ); + _calc_vm_trans(prot, PROT_EXEC, VM_EXEC) | + arch_calc_vm_prot_bits(prot); } /* diff --git a/mm/mmap.c b/mm/mmap.c index 3354fdd..1d102b9 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -72,8 +72,9 @@ pgprot_t protection_map[16] = { pgprot_t vm_get_page_prot(unsigned long vm_flags) { - return protection_map[vm_flags & - (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; + return __pgprot(pgprot_val(protection_map[vm_flags & + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) | + pgprot_val(arch_vm_get_page_prot(vm_flags))); } EXPORT_SYMBOL(vm_get_page_prot); diff --git a/mm/mprotect.c b/mm/mprotect.c index a5bf31c..ecfaa58 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -239,7 +239,7 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot) end = start + len; if (end <= start) return -ENOMEM; - if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM)) + if (!arch_validate_prot(prot)) return -EINVAL; reqprot = prot; -- cgit v0.10.2 From aba46c5027cb59d98052231b36efcbbde9c77a1d Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:52 +1000 Subject: powerpc/mm: Define flags for Strong Access Ordering This patch defines: - PROT_SAO, which is passed into mmap() and mprotect() in the prot field - VM_SAO in vma->vm_flags, and - _PAGE_SAO, the combination of WIMG bits in the pte that enables strong access ordering for the page. Signed-off-by: Dave Kleikamp Signed-off-by: Benjamin Herrenschmidt diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index 24cf664..0c46bf2 100644 --- a/include/asm-powerpc/mman.h +++ b/include/asm-powerpc/mman.h @@ -10,6 +10,8 @@ * 2 of the License, or (at your option) any later version. */ +#define PROT_SAO 0x10 /* Strong Access Ordering */ + #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ #define MAP_LOCKED 0x80 diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h index b2754d4..d09599c 100644 --- a/include/asm-powerpc/pgtable-ppc64.h +++ b/include/asm-powerpc/pgtable-ppc64.h @@ -93,6 +93,9 @@ #define _PAGE_RW 0x0200 /* software: user write access allowed */ #define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */ +/* Strong Access Ordering */ +#define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT) + #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT) #define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY) diff --git a/include/linux/mm.h b/include/linux/mm.h index 586a943..6891844 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -108,6 +108,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */ #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */ +#define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS -- cgit v0.10.2 From 379070491e1e744a59e69e5bcf3765012d15ecb4 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:53 +1000 Subject: powerpc/mm: Add SAO Feature bit to the cputable Add the CPU feature bit for the new Strong Access Ordering facility of Power7 Signed-off-by: Dave Kleikamp Signed-off-by: Joel Schopp Signed-off-by: Benjamin Herrenschmidt diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 3171ac9..4fd7689 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -186,6 +186,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, #define CPU_FTR_1T_SEGMENT LONG_ASM_CONST(0x0004000000000000) #define CPU_FTR_NO_SLBIE_B LONG_ASM_CONST(0x0008000000000000) #define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000) +#define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000) #ifndef __ASSEMBLY__ @@ -401,7 +402,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ - CPU_FTR_DSCR) + CPU_FTR_DSCR | CPU_FTR_SAO) #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ -- cgit v0.10.2 From ef3d3246a0d06be622867d21af25f997aeeb105f Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:54 +1000 Subject: powerpc/mm: Add Strong Access Ordering support Allow an application to enable Strong Access Ordering on specific pages of memory on Power 7 hardware. Currently, power has a weaker memory model than x86. Implementing a stronger memory model allows an emulator to more efficiently translate x86 code into power code, resulting in faster code execution. On Power 7 hardware, storing 0b1110 in the WIMG bits of the hpte enables strong access ordering mode for the memory page. This patchset allows a user to specify which pages are thus enabled by passing a new protection bit through mmap() and mprotect(). I have defined PROT_SAO to be 0x10. Signed-off-by: Dave Kleikamp Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 4fe69ca..c04832c 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -143,6 +143,9 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len, struct file * file = NULL; unsigned long ret = -EINVAL; + if (!arch_validate_prot(prot)) + goto out; + if (shift) { if (off & ((1 << shift) - 1)) goto out; diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index 0c46bf2..f8a32e2 100644 --- a/include/asm-powerpc/mman.h +++ b/include/asm-powerpc/mman.h @@ -1,7 +1,9 @@ #ifndef _ASM_POWERPC_MMAN_H #define _ASM_POWERPC_MMAN_H +#include #include +#include /* * This program is free software; you can redistribute it and/or @@ -26,4 +28,32 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#ifdef CONFIG_PPC64 +/* + * This file is included by linux/mman.h, so we can't use cacl_vm_prot_bits() + * here. How important is the optimization? + */ +static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot) +{ + return (prot & PROT_SAO) ? VM_SAO : 0; +} +#define arch_calc_vm_prot_bits(prot) arch_calc_vm_prot_bits(prot) + +static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) +{ + return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : 0; +} +#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) + +static inline int arch_validate_prot(unsigned long prot) +{ + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_SAO)) + return 0; + if ((prot & PROT_SAO) && !cpu_has_feature(CPU_FTR_SAO)) + return 0; + return 1; +} +#define arch_validate_prot(prot) arch_validate_prot(prot) + +#endif /* CONFIG_PPC64 */ #endif /* _ASM_POWERPC_MMAN_H */ -- cgit v0.10.2 From 801eb73f45371accc78ca9d6d22d647eeb722c11 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 8 Jul 2008 00:28:55 +1000 Subject: powerpc/mm: Don't clear _PAGE_COHERENT when _PAGE_SAO is set The current low level hash code on LPAR configurations clears _PAGE_COHERENT (M) when either _PAGE_GUARDED (G) or _PAGE_NO_CACHE (I) is set. This conflicts with _PAGE_SAO which has M, I and W bits sets at once (normally invalid combo) to indicate the new SAO attribute. This changes the code to allow that case. Signed-off-by: Dave Kleikamp Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 3b4651b..38b5927 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -305,7 +305,8 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, flags = 0; /* Make pHyp happy */ - if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + if ((rflags & _PAGE_GUARDED) || + ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))) hpte_r &= ~_PAGE_COHERENT; lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); -- cgit v0.10.2 From 05781ccd74c63c6c8567f99101587d5c07c163e0 Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Tue, 8 Jul 2008 08:03:11 +1000 Subject: ibm_newemac: Parameterize EMAC Multicast Match Handling Various instances of the EMAC core have varying: 1) number of address match slots, 2) width of the registers for handling address match slots, 3) number of registers for handling address match slots and 4) base offset for those registers. As the driver stands today, it assumes that all EMACs have 4 IAHT and GAHT 32-bit registers, starting at offset 0x30 from the register base, with only 16-bits of each used for a total of 64 match slots. The 405EX(r) and 460EX now use the EMAC4SYNC core rather than the EMAC4 core. This core has 8 IAHT and GAHT registers, starting at offset 0x80 from the register base, with ALL 32-bits of each used for a total of 256 match slots. This adds a new compatible device tree entry "emac4sync" and a new, related feature flag "EMAC_FTR_EMAC4SYNC" along with a series of macros and inlines which supply the appropriate parameterized value based on the presence or absence of the EMAC4SYNC feature. The code has further been reworked where appropriate to use those macros and inlines. In addition, the register size passed to ioremap is now taken from the device tree: c4 for EMAC4SYNC cores 74 for EMAC4 cores 70 for EMAC cores rather than sizeof (emac_regs). Finally, the device trees have been updated with the appropriate compatible entries and resource sizes. This has been tested on an AMCC Haleakala board such that: 1) inbound ICMP requests to 'haleakala.local' via MDNS from both Mac OS X 10.4.11 and Ubuntu 8.04 systems as well as 2) outbound ICMP requests from 'haleakala.local' to those same systems in the '.local' domain via MDNS now work. Signed-off-by: Grant Erickson Acked-by: Jeff Garzik Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index f9fe032..79fe412 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts @@ -266,7 +266,7 @@ EMAC0: ethernet@ef600e00 { device_type = "network"; - compatible = "ibm,emac-460ex", "ibm,emac4"; + compatible = "ibm,emac-460ex", "ibm,emac4sync"; interrupt-parent = <&EMAC0>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -274,7 +274,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600e00 0x00000070>; + reg = <0xef600e00 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -295,7 +295,7 @@ EMAC1: ethernet@ef600f00 { device_type = "network"; - compatible = "ibm,emac-460ex", "ibm,emac4"; + compatible = "ibm,emac-460ex", "ibm,emac4sync"; interrupt-parent = <&EMAC1>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -303,7 +303,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600f00 0x00000070>; + reg = <0xef600f00 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts index 463650c..24cf0db 100644 --- a/arch/powerpc/boot/dts/glacier.dts +++ b/arch/powerpc/boot/dts/glacier.dts @@ -283,7 +283,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600e00 0x00000070>; + reg = <0xef600e00 0x00000074>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -312,7 +312,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600f00 0x00000070>; + reg = <0xef600f00 0x00000074>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; @@ -342,7 +342,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef601100 0x00000070>; + reg = <0xef601100 0x00000074>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <2>; @@ -370,7 +370,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef601200 0x00000070>; + reg = <0xef601200 0x00000074>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <3>; diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index 2c2fcea..513bc43 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -206,7 +206,7 @@ EMAC0: ethernet@ef600900 { linux,network-index = <0x0>; device_type = "network"; - compatible = "ibm,emac-405exr", "ibm,emac4"; + compatible = "ibm,emac-405exr", "ibm,emac4sync"; interrupt-parent = <&EMAC0>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -214,7 +214,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600900 0x00000070>; + reg = <0xef600900 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index b94bf61..077819b 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -208,7 +208,7 @@ compatible = "ibm,emac-440spe", "ibm,emac4"; interrupt-parent = <&UIC1>; interrupts = <0x1c 0x4 0x1d 0x4>; - reg = <0x10000800 0x00000070>; + reg = <0x10000800 0x00000074>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0>; diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts index 3ed6a8f..dececc4 100644 --- a/arch/powerpc/boot/dts/kilauea.dts +++ b/arch/powerpc/boot/dts/kilauea.dts @@ -207,7 +207,7 @@ EMAC0: ethernet@ef600900 { linux,network-index = <0x0>; device_type = "network"; - compatible = "ibm,emac-405ex", "ibm,emac4"; + compatible = "ibm,emac-405ex", "ibm,emac4sync"; interrupt-parent = <&EMAC0>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -215,7 +215,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600900 0x00000070>; + reg = <0xef600900 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -235,7 +235,7 @@ EMAC1: ethernet@ef600a00 { linux,network-index = <0x1>; device_type = "network"; - compatible = "ibm,emac-405ex", "ibm,emac4"; + compatible = "ibm,emac-405ex", "ibm,emac4sync"; interrupt-parent = <&EMAC1>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -243,7 +243,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600a00 0x00000070>; + reg = <0xef600a00 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts index 1dfcd7e..945508c 100644 --- a/arch/powerpc/boot/dts/makalu.dts +++ b/arch/powerpc/boot/dts/makalu.dts @@ -207,7 +207,7 @@ EMAC0: ethernet@ef600900 { linux,network-index = <0x0>; device_type = "network"; - compatible = "ibm,emac-405ex", "ibm,emac4"; + compatible = "ibm,emac-405ex", "ibm,emac4sync"; interrupt-parent = <&EMAC0>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -215,7 +215,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600900 0x00000070>; + reg = <0xef600900 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -235,7 +235,7 @@ EMAC1: ethernet@ef600a00 { linux,network-index = <0x1>; device_type = "network"; - compatible = "ibm,emac-405ex", "ibm,emac4"; + compatible = "ibm,emac-405ex", "ibm,emac4sync"; interrupt-parent = <&EMAC1>; interrupts = <0x0 0x1>; #interrupt-cells = <1>; @@ -243,7 +243,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600a00 0x00000070>; + reg = <0xef600a00 0x000000c4>; local-mac-address = [000000000000]; /* Filled in by U-Boot */ mal-device = <&MAL0>; mal-tx-channel = <1>; diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts index 2afb63a..9684c80 100644 --- a/arch/powerpc/boot/dts/rainier.dts +++ b/arch/powerpc/boot/dts/rainier.dts @@ -265,7 +265,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600e00 0x00000070>; + reg = <0xef600e00 0x00000074>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -294,7 +294,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600f00 0x00000070>; + reg = <0xef600f00 0x00000074>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <1>; diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts index 149dabc..72d15f0 100644 --- a/arch/powerpc/boot/dts/sequoia.dts +++ b/arch/powerpc/boot/dts/sequoia.dts @@ -280,7 +280,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600e00 0x00000070>; + reg = <0xef600e00 0x00000074>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -309,7 +309,7 @@ #size-cells = <0>; interrupt-map = ; - reg = <0xef600f00 0x00000070>; + reg = <0xef600f00 0x00000074>; local-mac-address = [000000000000]; mal-device = <&MAL0>; mal-tx-channel = <1>; diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts index d4867de..058438f 100644 --- a/arch/powerpc/boot/dts/taishan.dts +++ b/arch/powerpc/boot/dts/taishan.dts @@ -287,7 +287,7 @@ compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC1>; interrupts = <0x1c 0x4 0x1d 0x4>; - reg = <0x40000800 0x00000070>; + reg = <0x40000800 0x00000074>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <0>; @@ -307,7 +307,7 @@ compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC1>; interrupts = <0x1e 0x4 0x1f 0x4>; - reg = <0x40000900 0x00000070>; + reg = <0x40000900 0x00000074>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <1>; @@ -327,7 +327,7 @@ compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC2>; interrupts = <0x0 0x4 0x1 0x4>; - reg = <0x40000c00 0x00000070>; + reg = <0x40000c00 0x00000074>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <2>; @@ -351,7 +351,7 @@ compatible = "ibm,emac-440gx", "ibm,emac4"; interrupt-parent = <&UIC2>; interrupts = <0x2 0x4 0x3 0x4>; - reg = <0x40000e00 0x00000070>; + reg = <0x40000e00 0x00000074>; local-mac-address = [000000000000]; // Filled in by zImage mal-device = <&MAL0>; mal-tx-channel = <3>; diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 5d2108c..ed24a1d 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -363,25 +363,31 @@ static int emac_reset(struct emac_instance *dev) static void emac_hash_mc(struct emac_instance *dev) { - struct emac_regs __iomem *p = dev->emacp; - u16 gaht[4] = { 0 }; + const int regs = EMAC_XAHT_REGS(dev); + u32 *gaht_base = emac_gaht_base(dev); + u32 gaht_temp[regs]; struct dev_mc_list *dmi; + int i; DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count); + memset(gaht_temp, 0, sizeof (gaht_temp)); + for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { - int bit; + int slot, reg, mask; DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL, dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); - bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26); - gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f); + slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr)); + reg = EMAC_XAHT_SLOT_TO_REG(dev, slot); + mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot); + + gaht_temp[reg] |= mask; } - out_be32(&p->gaht1, gaht[0]); - out_be32(&p->gaht2, gaht[1]); - out_be32(&p->gaht3, gaht[2]); - out_be32(&p->gaht4, gaht[3]); + + for (i = 0; i < regs; i++) + out_be32(gaht_base + i, gaht_temp[i]); } static inline u32 emac_iff2rmr(struct net_device *ndev) @@ -398,7 +404,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) r |= EMAC_RMR_PME; - else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32) + else if (ndev->flags & IFF_ALLMULTI || + (ndev->mc_count > EMAC_XAHT_SLOTS(dev))) r |= EMAC_RMR_PMME; else if (ndev->mc_count > 0) r |= EMAC_RMR_MAE; @@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev) /* Put some arbitrary OUI, Manuf & Rev IDs so we can * identify this GPCS PHY later. */ - out_be32(&p->ipcr, 0xdeadbeef); + out_be32(&p->u1.emac4.ipcr, 0xdeadbeef); } else mr1 |= EMAC_MR1_MF_1000; @@ -2015,10 +2022,10 @@ static int emac_get_regs_len(struct emac_instance *dev) { if (emac_has_feature(dev, EMAC_FTR_EMAC4)) return sizeof(struct emac_ethtool_regs_subhdr) + - EMAC4_ETHTOOL_REGS_SIZE; + EMAC4_ETHTOOL_REGS_SIZE(dev); else return sizeof(struct emac_ethtool_regs_subhdr) + - EMAC_ETHTOOL_REGS_SIZE; + EMAC_ETHTOOL_REGS_SIZE(dev); } static int emac_ethtool_get_regs_len(struct net_device *ndev) @@ -2045,12 +2052,12 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf) hdr->index = dev->cell_index; if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { hdr->version = EMAC4_ETHTOOL_REGS_VER; - memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE); - return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE); + memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev)); + return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev)); } else { hdr->version = EMAC_ETHTOOL_REGS_VER; - memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE); - return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE); + memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev)); + return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev)); } } @@ -2540,7 +2547,9 @@ static int __devinit emac_init_config(struct emac_instance *dev) } /* Check EMAC version */ - if (of_device_is_compatible(np, "ibm,emac4")) { + if (of_device_is_compatible(np, "ibm,emac4sync")) { + dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC); + } else if (of_device_is_compatible(np, "ibm,emac4")) { dev->features |= EMAC_FTR_EMAC4; if (of_device_is_compatible(np, "ibm,emac-440gx")) dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX; @@ -2601,6 +2610,15 @@ static int __devinit emac_init_config(struct emac_instance *dev) } memcpy(dev->ndev->dev_addr, p, 6); + /* IAHT and GAHT filter parameterization */ + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) { + dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT; + dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT; + } else { + dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT; + dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT; + } + DBG(dev, "features : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE); DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige); DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige); @@ -2672,7 +2690,8 @@ static int __devinit emac_probe(struct of_device *ofdev, goto err_irq_unmap; } // TODO : request_mem_region - dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs)); + dev->emacp = ioremap(dev->rsrc_regs.start, + dev->rsrc_regs.end - dev->rsrc_regs.start + 1); if (dev->emacp == NULL) { printk(KERN_ERR "%s: Can't map device registers!\n", np->full_name); @@ -2884,6 +2903,10 @@ static struct of_device_id emac_match[] = .type = "network", .compatible = "ibm,emac4", }, + { + .type = "network", + .compatible = "ibm,emac4sync", + }, {}, }; diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 2230904..6545e69 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -235,6 +235,10 @@ struct emac_instance { u32 fifo_entry_size; u32 mal_burst_size; /* move to MAL ? */ + /* IAHT and GAHT filter parameterization */ + u32 xaht_slots_shift; + u32 xaht_width_shift; + /* Descriptor management */ struct mal_descriptor *tx_desc; @@ -309,6 +313,10 @@ struct emac_instance { * Set if we need phy clock workaround for 440ep or 440gr */ #define EMAC_FTR_440EP_PHY_CLK_FIX 0x00000100 +/* + * The 405EX and 460EX contain the EMAC4SYNC core + */ +#define EMAC_FTR_EMAC4SYNC 0x00000200 /* Right now, we don't quite handle the always/possible masks on the @@ -320,7 +328,8 @@ enum { EMAC_FTRS_POSSIBLE = #ifdef CONFIG_IBM_NEW_EMAC_EMAC4 - EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR | + EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC | + EMAC_FTR_HAS_NEW_STACR | EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX | #endif #ifdef CONFIG_IBM_NEW_EMAC_TAH @@ -342,6 +351,71 @@ static inline int emac_has_feature(struct emac_instance *dev, (EMAC_FTRS_POSSIBLE & dev->features & feature); } +/* + * Various instances of the EMAC core have varying 1) number of + * address match slots, 2) width of the registers for handling address + * match slots, 3) number of registers for handling address match + * slots and 4) base offset for those registers. + * + * These macros and inlines handle these differences based on + * parameters supplied by the device structure which are, in turn, + * initialized based on the "compatible" entry in the device tree. + */ + +#define EMAC4_XAHT_SLOTS_SHIFT 6 +#define EMAC4_XAHT_WIDTH_SHIFT 4 + +#define EMAC4SYNC_XAHT_SLOTS_SHIFT 8 +#define EMAC4SYNC_XAHT_WIDTH_SHIFT 5 + +#define EMAC_XAHT_SLOTS(dev) (1 << (dev)->xaht_slots_shift) +#define EMAC_XAHT_WIDTH(dev) (1 << (dev)->xaht_width_shift) +#define EMAC_XAHT_REGS(dev) (1 << ((dev)->xaht_slots_shift - \ + (dev)->xaht_width_shift)) + +#define EMAC_XAHT_CRC_TO_SLOT(dev, crc) \ + ((EMAC_XAHT_SLOTS(dev) - 1) - \ + ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) - \ + (dev)->xaht_slots_shift))) + +#define EMAC_XAHT_SLOT_TO_REG(dev, slot) \ + ((slot) >> (dev)->xaht_width_shift) + +#define EMAC_XAHT_SLOT_TO_MASK(dev, slot) \ + ((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >> \ + ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1))) + +static inline u32 *emac_xaht_base(struct emac_instance *dev) +{ + struct emac_regs __iomem *p = dev->emacp; + int offset; + + /* The first IAHT entry always is the base of the block of + * IAHT and GAHT registers. + */ + if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) + offset = offsetof(struct emac_regs, u1.emac4sync.iaht1); + else + offset = offsetof(struct emac_regs, u0.emac4.iaht1); + + return ((u32 *)((ptrdiff_t)p + offset)); +} + +static inline u32 *emac_gaht_base(struct emac_instance *dev) +{ + /* GAHT registers always come after an identical number of + * IAHT registers. + */ + return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev)); +} + +static inline u32 *emac_iaht_base(struct emac_instance *dev) +{ + /* IAHT registers always come before an identical number of + * GAHT registers. + */ + return (emac_xaht_base(dev)); +} /* Ethtool get_regs complex data. * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH @@ -366,4 +440,11 @@ struct emac_ethtool_regs_subhdr { u32 index; }; +#define EMAC_ETHTOOL_REGS_VER 0 +#define EMAC_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ + (dev)->rsrc_regs.start + 1) +#define EMAC4_ETHTOOL_REGS_VER 1 +#define EMAC4_ETHTOOL_REGS_SIZE(dev) ((dev)->rsrc_regs.end - \ + (dev)->rsrc_regs.start + 1) + #endif /* __IBM_NEWEMAC_CORE_H */ diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 86b756a..775c850 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c @@ -67,29 +67,55 @@ static void emac_desc_dump(struct emac_instance *p) static void emac_mac_dump(struct emac_instance *dev) { struct emac_regs __iomem *p = dev->emacp; + const int xaht_regs = EMAC_XAHT_REGS(dev); + u32 *gaht_base = emac_gaht_base(dev); + u32 *iaht_base = emac_iaht_base(dev); + int emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC); + int n; printk("** EMAC %s registers **\n" "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" - "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n" - "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x " - "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n" - "LSA = %04x%08x IPGVR = 0x%04x\n" - "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" - "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n", + "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n", dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), in_be32(&p->tmr0), in_be32(&p->tmr1), in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), - in_be32(&p->vtci), - in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3), - in_be32(&p->iaht4), - in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3), - in_be32(&p->gaht4), + in_be32(&p->vtci) + ); + + if (emac4sync) + printk("MAR = %04x%08x MMAR = %04x%08x\n", + in_be32(&p->u0.emac4sync.mahr), + in_be32(&p->u0.emac4sync.malr), + in_be32(&p->u0.emac4sync.mmahr), + in_be32(&p->u0.emac4sync.mmalr) + ); + + for (n = 0; n < xaht_regs; n++) + printk("IAHT%02d = 0x%08x\n", n + 1, in_be32(iaht_base + n)); + + for (n = 0; n < xaht_regs; n++) + printk("GAHT%02d = 0x%08x\n", n + 1, in_be32(gaht_base + n)); + + printk("LSA = %04x%08x IPGVR = 0x%04x\n" + "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n" + "OCTX = 0x%08x OCRX = 0x%08x\n", in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr), in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr), - in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr) - ); + in_be32(&p->octx), in_be32(&p->ocrx) + ); + + if (!emac4sync) { + printk("IPCR = 0x%08x\n", + in_be32(&p->u1.emac4.ipcr) + ); + } else { + printk("REVID = 0x%08x TPC = 0x%08x\n", + in_be32(&p->u1.emac4sync.revid), + in_be32(&p->u1.emac4sync.tpc) + ); + } emac_desc_dump(dev); } diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index 91cb096..0afc2cf 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h @@ -27,37 +27,80 @@ #include -/* EMAC registers Write Access rules */ +/* EMAC registers Write Access rules */ struct emac_regs { - u32 mr0; /* special */ - u32 mr1; /* Reset */ - u32 tmr0; /* special */ - u32 tmr1; /* special */ - u32 rmr; /* Reset */ - u32 isr; /* Always */ - u32 iser; /* Reset */ - u32 iahr; /* Reset, R, T */ - u32 ialr; /* Reset, R, T */ - u32 vtpid; /* Reset, R, T */ - u32 vtci; /* Reset, R, T */ - u32 ptr; /* Reset, T */ - u32 iaht1; /* Reset, R */ - u32 iaht2; /* Reset, R */ - u32 iaht3; /* Reset, R */ - u32 iaht4; /* Reset, R */ - u32 gaht1; /* Reset, R */ - u32 gaht2; /* Reset, R */ - u32 gaht3; /* Reset, R */ - u32 gaht4; /* Reset, R */ + /* Common registers across all EMAC implementations. */ + u32 mr0; /* Special */ + u32 mr1; /* Reset */ + u32 tmr0; /* Special */ + u32 tmr1; /* Special */ + u32 rmr; /* Reset */ + u32 isr; /* Always */ + u32 iser; /* Reset */ + u32 iahr; /* Reset, R, T */ + u32 ialr; /* Reset, R, T */ + u32 vtpid; /* Reset, R, T */ + u32 vtci; /* Reset, R, T */ + u32 ptr; /* Reset, T */ + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 mahr; /* Reset, R, T */ + u32 malr; /* Reset, R, T */ + u32 mmahr; /* Reset, R, T */ + u32 mmalr; /* Reset, R, T */ + u32 rsvd0[4]; + } emac4sync; + } u0; + /* Common registers across all EMAC implementations. */ u32 lsah; u32 lsal; - u32 ipgvr; /* Reset, T */ - u32 stacr; /* special */ - u32 trtr; /* special */ - u32 rwmr; /* Reset */ + u32 ipgvr; /* Reset, T */ + u32 stacr; /* Special */ + u32 trtr; /* Special */ + u32 rwmr; /* Reset */ u32 octx; u32 ocrx; - u32 ipcr; + union { + /* Registers unique to EMAC4 implementations */ + struct { + u32 ipcr; + } emac4; + /* Registers unique to EMAC4SYNC implementations */ + struct { + u32 rsvd1; + u32 revid; + u32 rsvd2[2]; + u32 iaht1; /* Reset, R */ + u32 iaht2; /* Reset, R */ + u32 iaht3; /* Reset, R */ + u32 iaht4; /* Reset, R */ + u32 iaht5; /* Reset, R */ + u32 iaht6; /* Reset, R */ + u32 iaht7; /* Reset, R */ + u32 iaht8; /* Reset, R */ + u32 gaht1; /* Reset, R */ + u32 gaht2; /* Reset, R */ + u32 gaht3; /* Reset, R */ + u32 gaht4; /* Reset, R */ + u32 gaht5; /* Reset, R */ + u32 gaht6; /* Reset, R */ + u32 gaht7; /* Reset, R */ + u32 gaht8; /* Reset, R */ + u32 tpc; /* Reset, T */ + } emac4sync; + } u1; }; /* @@ -73,12 +116,6 @@ struct emac_regs { #define PHY_MODE_RTBI 7 #define PHY_MODE_SGMII 8 - -#define EMAC_ETHTOOL_REGS_VER 0 -#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32)) -#define EMAC4_ETHTOOL_REGS_VER 1 -#define EMAC4_ETHTOOL_REGS_SIZE sizeof(struct emac_regs) - /* EMACx_MR0 */ #define EMAC_MR0_RXI 0x80000000 #define EMAC_MR0_TXI 0x40000000 -- cgit v0.10.2 From 1b17adf19b4d66858f366acd82b4e81cba5edc93 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 8 Jul 2008 08:42:09 +1000 Subject: powerpc/ibmebus: more meaningful variable name Choose a more meaningful name for better System.map readability and autopsy value etc. Signed-off-by: Paul Gortmaker Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index e3b1fcd..9d42eb5 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -53,7 +53,7 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */ struct bus_type ibmebus_bus_type; /* These devices will automatically be added to the bus during init */ -static struct of_device_id __initdata builtin_matches[] = { +static struct of_device_id __initdata ibmebus_matches[] = { { .compatible = "IBM,lhca" }, { .compatible = "IBM,lhea" }, {}, @@ -354,7 +354,7 @@ static int __init ibmebus_bus_init(void) return err; } - err = ibmebus_create_devices(builtin_matches); + err = ibmebus_create_devices(ibmebus_matches); if (err) { device_unregister(&ibmebus_bus_device); bus_unregister(&ibmebus_bus_type); -- cgit v0.10.2 From c1cb299ead405f0ac065c4430729549b187e5b32 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 8 Jul 2008 18:43:41 +1000 Subject: powerpc: fix swapcontext backwards compat. with VSX ucontext changes When the ucontext changed to add the VSX context, this broke backwards compatibly on swapcontext. swapcontext only compares the ucontext size passed in from the user to the new kernel ucontext size. This adds a check against the old ucontext size (with VMX but without VSX). It also adds some sanity check for ucontexts without VSX, but where VSX is used according the MSR. Fixes for both 32 and 64bit processes on 64bit kernels Kudos to Paulus for noticing. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 9991e2a..6f6810d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -68,6 +68,13 @@ #define ucontext ucontext32 /* + * Userspace code may pass a ucontext which doesn't include VSX added + * at the end. We need to check for this case. + */ +#define UCONTEXTSIZEWITHOUTVSX \ + (sizeof(struct ucontext) - sizeof(elf_vsrreghalf_t32)) + +/* * Returning 0 means we return to userspace via * ret_from_except and thus restore all user * registers from *regs. This is what we need @@ -930,12 +937,42 @@ long sys_swapcontext(struct ucontext __user *old_ctx, { unsigned char tmp; +#ifdef CONFIG_PPC64 + unsigned long new_msr = 0; + + if (new_ctx && + __get_user(new_msr, &new_ctx->uc_mcontext.mc_gregs[PT_MSR])) + return -EFAULT; + /* + * Check that the context is not smaller than the original + * size (with VMX but without VSX) + */ + if (ctx_size < UCONTEXTSIZEWITHOUTVSX) + return -EINVAL; + /* + * If the new context state sets the MSR VSX bits but + * it doesn't provide VSX state. + */ + if ((ctx_size < sizeof(struct ucontext)) && + (new_msr & MSR_VSX)) + return -EINVAL; +#ifdef CONFIG_VSX + /* + * If userspace doesn't provide enough room for VSX data, + * but current thread has used VSX, we don't have anywhere + * to store the full context back into. + */ + if ((ctx_size < sizeof(struct ucontext)) && + (current->thread.used_vsr && old_ctx)) + return -EINVAL; +#endif +#else /* Context size is for future use. Right now, we only make sure * we are passed something we understand */ if (ctx_size < sizeof(struct ucontext)) return -EINVAL; - +#endif if (old_ctx != NULL) { struct mcontext __user *mctx; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 93ebfb6..5f9d2ef 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -268,6 +268,13 @@ static long setup_trampoline(unsigned int syscall, unsigned int __user *tramp) } /* + * Userspace code may pass a ucontext which doesn't include VSX added + * at the end. We need to check for this case. + */ +#define UCONTEXTSIZEWITHOUTVSX \ + (sizeof(struct ucontext) - 32*sizeof(long)) + +/* * Handle {get,set,swap}_context operations */ int sys_swapcontext(struct ucontext __user *old_ctx, @@ -276,13 +283,34 @@ int sys_swapcontext(struct ucontext __user *old_ctx, { unsigned char tmp; sigset_t set; + unsigned long new_msr = 0; - /* Context size is for future use. Right now, we only make sure - * we are passed something we understand + if (new_ctx && + __get_user(new_msr, &new_ctx->uc_mcontext.gp_regs[PT_MSR])) + return -EFAULT; + /* + * Check that the context is not smaller than the original + * size (with VMX but without VSX) */ - if (ctx_size < sizeof(struct ucontext)) + if (ctx_size < UCONTEXTSIZEWITHOUTVSX) return -EINVAL; - + /* + * If the new context state sets the MSR VSX bits but + * it doesn't provide VSX state. + */ + if ((ctx_size < sizeof(struct ucontext)) && + (new_msr & MSR_VSX)) + return -EINVAL; +#ifdef CONFIG_VSX + /* + * If userspace doesn't provide enough room for VSX data, + * but current thread has used VSX, we don't have anywhere + * to store the full context back into. + */ + if ((ctx_size < sizeof(struct ucontext)) && + (current->thread.used_vsr && old_ctx)) + return -EINVAL; +#endif if (old_ctx != NULL) { if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) || setup_sigcontext(&old_ctx->uc_mcontext, regs, 0, NULL, 0) -- cgit v0.10.2 From b887ec620a7575f54fa025d38fa1008dc8a3b12a Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 8 Jul 2008 18:53:03 +1000 Subject: powerpc: remove unused variable in emulate_fp_pair regs is not used in emulate_fp_pair so remove it. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index c95954c..f22b5d0 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -363,8 +363,8 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, * Only POWER6 has these instructions, and it does true little-endian, * so we don't need the address swizzling. */ -static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr, - unsigned int reg, unsigned int flags) +static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, + unsigned int flags) { char *ptr = (char *) ¤t->thread.TS_FPR(reg); int i, ret; @@ -759,7 +759,7 @@ int fix_alignment(struct pt_regs *regs) /* Special case for 16-byte FP loads and stores */ if (nb == 16) - return emulate_fp_pair(regs, addr, reg, flags); + return emulate_fp_pair(addr, reg, flags); /* If we are loading, get the data from user space, else * get it from register values -- cgit v0.10.2 From cde274c0c789404df8ece3f9e7d6506caf0127e2 Mon Sep 17 00:00:00 2001 From: Mike Mason Date: Wed, 9 Jul 2008 02:04:35 +1000 Subject: powerpc/eeh: PERR/SERR bit settings during EEH device recovery The following patch restores the PERR and SERR bits in the PCI command register during an EEH device recovery. We have found at least one case (an Agilent test card) where the PERR/SERR bits are set to 1 by firmware at boot time, but are not restored to 1 during EEH recovery. The patch fixes the Agilent card problem. It has been tested on several other EEH-enabled cards with no regressions. Signed-off-by: Mike Mason Acked-by: Linas Vepstas Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 6f544ba..c027f0a 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -812,6 +812,7 @@ int rtas_set_slot_reset(struct pci_dn *pdn) static inline void __restore_bars (struct pci_dn *pdn) { int i; + u32 cmd; if (NULL==pdn->phb) return; for (i=4; i<10; i++) { @@ -832,6 +833,19 @@ static inline void __restore_bars (struct pci_dn *pdn) /* max latency, min grant, interrupt pin and line */ rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]); + + /* Restore PERR & SERR bits, some devices require it, + don't touch the other command bits */ + rtas_read_config(pdn, PCI_COMMAND, 4, &cmd); + if (pdn->config_space[1] & PCI_COMMAND_PARITY) + cmd |= PCI_COMMAND_PARITY; + else + cmd &= ~PCI_COMMAND_PARITY; + if (pdn->config_space[1] & PCI_COMMAND_SERR) + cmd |= PCI_COMMAND_SERR; + else + cmd &= ~PCI_COMMAND_SERR; + rtas_write_config(pdn, PCI_COMMAND, 4, cmd); } /** -- cgit v0.10.2 From ff1b15b646177c6cc465ac2dd0be6ae16e965654 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 09:27:19 -0300 Subject: x86: don't use size specifiers. Remove the "l" from inline asm at arch/x86/lib/delay_32.c. It is not needed. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c index ef69131..54013f8 100644 --- a/arch/x86/lib/delay_32.c +++ b/arch/x86/lib/delay_32.c @@ -38,9 +38,9 @@ static void delay_loop(unsigned long loops) "1: jmp 2f \n" ".align 16 \n" - "2: decl %0 \n" + "2: dec %0 \n" " jnz 2b \n" - "3: decl %0 \n" + "3: dec %0 \n" : /* we don't need output */ :"a" (loops) -- cgit v0.10.2 From 0a4d8a472f645d99f86303db1462b64e371b090d Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 09:34:08 -0300 Subject: x86: provide delay loop for x86_64. This is for consistency with i386. We call use_tsc_delay() at tsc initialization for x86_64, so we'll be always using it. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 3c36f92..4a775d0 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -513,6 +513,7 @@ void __init tsc_init(void) */ for_each_possible_cpu(cpu) set_cyc2ns_scale(cpu_khz, cpu); + use_tsc_delay(); if (tsc_disabled > 0) return; diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c index 4c441be..d0326d0 100644 --- a/arch/x86/lib/delay_64.c +++ b/arch/x86/lib/delay_64.c @@ -22,13 +22,28 @@ #include #endif -int __devinit read_current_timer(unsigned long *timer_value) +/* simple loop based delay: */ +static void delay_loop(unsigned long loops) { - rdtscll(*timer_value); - return 0; + asm volatile( + " test %0,%0 \n" + " jz 3f \n" + " jmp 1f \n" + + ".align 16 \n" + "1: jmp 2f \n" + + ".align 16 \n" + "2: dec %0 \n" + " jnz 2b \n" + "3: dec %0 \n" + + : /* we don't need output */ + :"a" (loops) + ); } -void __delay(unsigned long loops) +static void delay_tsc(unsigned long loops) { unsigned bclock, now; int cpu; @@ -63,6 +78,27 @@ void __delay(unsigned long loops) } preempt_enable(); } + +static void (*delay_fn)(unsigned long) = delay_loop; + +void use_tsc_delay(void) +{ + delay_fn = delay_tsc; +} + +int __devinit read_current_timer(unsigned long *timer_value) +{ + if (delay_fn == delay_tsc) { + rdtscll(*timer_value); + return 0; + } + return -1; +} + +void __delay(unsigned long loops) +{ + delay_fn(loops); +} EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) -- cgit v0.10.2 From a76febe975997b933b7285b6e20bb0a21c09d453 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 09:52:36 -0300 Subject: x86: use rdtscll in read_current_timer for i386. This way we achieve the same code for both arches. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c index 54013f8..bf6de05 100644 --- a/arch/x86/lib/delay_32.c +++ b/arch/x86/lib/delay_32.c @@ -98,7 +98,7 @@ void use_tsc_delay(void) int __devinit read_current_timer(unsigned long *timer_val) { if (delay_fn == delay_tsc) { - rdtscl(*timer_val); + rdtscll(*timer_val); return 0; } return -1; -- cgit v0.10.2 From 7e58818d32c18197602d1869b22cfda99efd05fe Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 10:21:25 -0300 Subject: x86: explicitly use edx in const delay function. For x86_64, we can't just use %0, as it would generate a mul against rdx, which is not really what we want (note the ">> 32" in x86_64 version). Using a u64 variable with a shift in i386 generates bad code, so the solution is to explicitly use %%edx in inline assembly for both. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c index bf6de05..0b659a3 100644 --- a/arch/x86/lib/delay_32.c +++ b/arch/x86/lib/delay_32.c @@ -114,7 +114,7 @@ inline void __const_udelay(unsigned long xloops) int d0; xloops *= 4; - __asm__("mull %0" + __asm__("mull %%edx" :"=d" (xloops), "=&a" (d0) :"1" (xloops), "0" (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c index d0326d0..ff3dfec 100644 --- a/arch/x86/lib/delay_64.c +++ b/arch/x86/lib/delay_64.c @@ -103,9 +103,16 @@ EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { - __delay(((xloops * HZ * - cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1); + int d0; + xloops *= 4; + __asm__("mull %%edx" + :"=d" (xloops), "=&a" (d0) + :"1" (xloops), "0" + (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); + + __delay(++xloops); } + EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) -- cgit v0.10.2 From f0fbf0abc093ec8bf64506eee4ede9e5daf40ffd Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 3 Jul 2008 12:35:41 -0300 Subject: x86: integrate delay functions. delay_32.c, delay_64.c are now equal, and are integrated into delay.c. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 76f60f5..86960a6 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_SMP) := msr-on-cpu.o -lib-y := delay_$(BITS).o +lib-y := delay.o lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o lib-y += memcpy_$(BITS).o diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c new file mode 100644 index 0000000..f456860 --- /dev/null +++ b/arch/x86/lib/delay.c @@ -0,0 +1,137 @@ +/* + * Precise Delay Loops for i386 + * + * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 1997 Martin Mares + * Copyright (C) 2008 Jiri Hladky + * + * The __delay function must _NOT_ be inlined as its execution time + * depends wildly on alignment on many x86 processors. The additional + * jump magic is needed to get the timing stable on all the CPU's + * we have to worry about. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_SMP +# include +#endif + +/* simple loop based delay: */ +static void delay_loop(unsigned long loops) +{ + asm volatile( + " test %0,%0 \n" + " jz 3f \n" + " jmp 1f \n" + + ".align 16 \n" + "1: jmp 2f \n" + + ".align 16 \n" + "2: dec %0 \n" + " jnz 2b \n" + "3: dec %0 \n" + + : /* we don't need output */ + :"a" (loops) + ); +} + +/* TSC based delay: */ +static void delay_tsc(unsigned long loops) +{ + unsigned long bclock, now; + int cpu; + + preempt_disable(); + cpu = smp_processor_id(); + rdtscl(bclock); + for (;;) { + rdtscl(now); + if ((now - bclock) >= loops) + break; + + /* Allow RT tasks to run */ + preempt_enable(); + rep_nop(); + preempt_disable(); + + /* + * It is possible that we moved to another CPU, and + * since TSC's are per-cpu we need to calculate + * that. The delay must guarantee that we wait "at + * least" the amount of time. Being moved to another + * CPU could make the wait longer but we just need to + * make sure we waited long enough. Rebalance the + * counter for this CPU. + */ + if (unlikely(cpu != smp_processor_id())) { + loops -= (now - bclock); + cpu = smp_processor_id(); + rdtscl(bclock); + } + } + preempt_enable(); +} + +/* + * Since we calibrate only once at boot, this + * function should be set once at boot and not changed + */ +static void (*delay_fn)(unsigned long) = delay_loop; + +void use_tsc_delay(void) +{ + delay_fn = delay_tsc; +} + +int __devinit read_current_timer(unsigned long *timer_val) +{ + if (delay_fn == delay_tsc) { + rdtscll(*timer_val); + return 0; + } + return -1; +} + +void __delay(unsigned long loops) +{ + delay_fn(loops); +} +EXPORT_SYMBOL(__delay); + +inline void __const_udelay(unsigned long xloops) +{ + int d0; + + xloops *= 4; + asm("mull %%edx" + :"=d" (xloops), "=&a" (d0) + :"1" (xloops), "0" + (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); + + __delay(++xloops); +} +EXPORT_SYMBOL(__const_udelay); + +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ +} +EXPORT_SYMBOL(__udelay); + +void __ndelay(unsigned long nsecs) +{ + __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ +} +EXPORT_SYMBOL(__ndelay); diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c deleted file mode 100644 index 0b659a3..0000000 --- a/arch/x86/lib/delay_32.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Precise Delay Loops for i386 - * - * Copyright (C) 1993 Linus Torvalds - * Copyright (C) 1997 Martin Mares - * Copyright (C) 2008 Jiri Hladky - * - * The __delay function must _NOT_ be inlined as its execution time - * depends wildly on alignment on many x86 processors. The additional - * jump magic is needed to get the timing stable on all the CPU's - * we have to worry about. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef CONFIG_SMP -# include -#endif - -/* simple loop based delay: */ -static void delay_loop(unsigned long loops) -{ - __asm__ __volatile__( - " test %0,%0 \n" - " jz 3f \n" - " jmp 1f \n" - - ".align 16 \n" - "1: jmp 2f \n" - - ".align 16 \n" - "2: dec %0 \n" - " jnz 2b \n" - "3: dec %0 \n" - - : /* we don't need output */ - :"a" (loops) - ); -} - -/* TSC based delay: */ -static void delay_tsc(unsigned long loops) -{ - unsigned long bclock, now; - int cpu; - - preempt_disable(); - cpu = smp_processor_id(); - rdtscl(bclock); - for (;;) { - rdtscl(now); - if ((now - bclock) >= loops) - break; - - /* Allow RT tasks to run */ - preempt_enable(); - rep_nop(); - preempt_disable(); - - /* - * It is possible that we moved to another CPU, and - * since TSC's are per-cpu we need to calculate - * that. The delay must guarantee that we wait "at - * least" the amount of time. Being moved to another - * CPU could make the wait longer but we just need to - * make sure we waited long enough. Rebalance the - * counter for this CPU. - */ - if (unlikely(cpu != smp_processor_id())) { - loops -= (now - bclock); - cpu = smp_processor_id(); - rdtscl(bclock); - } - } - preempt_enable(); -} - -/* - * Since we calibrate only once at boot, this - * function should be set once at boot and not changed - */ -static void (*delay_fn)(unsigned long) = delay_loop; - -void use_tsc_delay(void) -{ - delay_fn = delay_tsc; -} - -int __devinit read_current_timer(unsigned long *timer_val) -{ - if (delay_fn == delay_tsc) { - rdtscll(*timer_val); - return 0; - } - return -1; -} - -void __delay(unsigned long loops) -{ - delay_fn(loops); -} - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - - xloops *= 4; - __asm__("mull %%edx" - :"=d" (xloops), "=&a" (d0) - :"1" (xloops), "0" - (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} - -EXPORT_SYMBOL(__delay); -EXPORT_SYMBOL(__const_udelay); -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__ndelay); diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c deleted file mode 100644 index ff3dfec..0000000 --- a/arch/x86/lib/delay_64.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Precise Delay Loops for x86-64 - * - * Copyright (C) 1993 Linus Torvalds - * Copyright (C) 1997 Martin Mares - * - * The __delay function must _NOT_ be inlined as its execution time - * depends wildly on alignment on many x86 processors. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef CONFIG_SMP -#include -#endif - -/* simple loop based delay: */ -static void delay_loop(unsigned long loops) -{ - asm volatile( - " test %0,%0 \n" - " jz 3f \n" - " jmp 1f \n" - - ".align 16 \n" - "1: jmp 2f \n" - - ".align 16 \n" - "2: dec %0 \n" - " jnz 2b \n" - "3: dec %0 \n" - - : /* we don't need output */ - :"a" (loops) - ); -} - -static void delay_tsc(unsigned long loops) -{ - unsigned bclock, now; - int cpu; - - preempt_disable(); - cpu = smp_processor_id(); - rdtscl(bclock); - for (;;) { - rdtscl(now); - if ((now - bclock) >= loops) - break; - - /* Allow RT tasks to run */ - preempt_enable(); - rep_nop(); - preempt_disable(); - - /* - * It is possible that we moved to another CPU, and - * since TSC's are per-cpu we need to calculate - * that. The delay must guarantee that we wait "at - * least" the amount of time. Being moved to another - * CPU could make the wait longer but we just need to - * make sure we waited long enough. Rebalance the - * counter for this CPU. - */ - if (unlikely(cpu != smp_processor_id())) { - loops -= (now - bclock); - cpu = smp_processor_id(); - rdtscl(bclock); - } - } - preempt_enable(); -} - -static void (*delay_fn)(unsigned long) = delay_loop; - -void use_tsc_delay(void) -{ - delay_fn = delay_tsc; -} - -int __devinit read_current_timer(unsigned long *timer_value) -{ - if (delay_fn == delay_tsc) { - rdtscll(*timer_value); - return 0; - } - return -1; -} - -void __delay(unsigned long loops) -{ - delay_fn(loops); -} -EXPORT_SYMBOL(__delay); - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - xloops *= 4; - __asm__("mull %%edx" - :"=d" (xloops), "=&a" (d0) - :"1" (xloops), "0" - (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} - -EXPORT_SYMBOL(__const_udelay); - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} -EXPORT_SYMBOL(__ndelay); -- cgit v0.10.2 From f8dd0d3c62164160c59034a96eb17d69ac8a0328 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 9 Jul 2008 09:12:55 +0200 Subject: x86: delay lib unification build fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: arch/x86/lib/delay.c:93:24: error: macro "use_tsc_delay" passed 1 arguments, but takes just 0 arch/x86/lib/delay.c:94: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h index bb80880..409a649 100644 --- a/include/asm-x86/delay.h +++ b/include/asm-x86/delay.h @@ -26,10 +26,6 @@ extern void __delay(unsigned long loops); ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) -#ifdef CONFIG_X86_32 void use_tsc_delay(void); -#else -#define use_tsc_delay() {} -#endif #endif /* _ASM_X86_DELAY_H */ -- cgit v0.10.2 From edf10162b2c5ad78ada8e63e960f9d0949c6c219 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 13 Jun 2008 16:35:52 -0300 Subject: x86: don't clobber r8 nor use rcx. There's really no reason to clobber r8 or pass the address in rcx. We can safely use only two registers (which we already have to touch anyway) to do the job. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S index 5448876..2b003d3 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser_64.S @@ -36,10 +36,10 @@ .text ENTRY(__get_user_1) CFI_STARTPROC - GET_THREAD_INFO(%r8) - cmpq threadinfo_addr_limit(%r8),%rcx + GET_THREAD_INFO(%rdx) + cmpq threadinfo_addr_limit(%rdx),%rax jae bad_get_user -1: movzb (%rcx),%edx +1: movzb (%rax),%edx xorl %eax,%eax ret CFI_ENDPROC @@ -47,48 +47,48 @@ ENDPROC(__get_user_1) ENTRY(__get_user_2) CFI_STARTPROC - GET_THREAD_INFO(%r8) - addq $1,%rcx + GET_THREAD_INFO(%rdx) + addq $1,%rax jc 20f - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq threadinfo_addr_limit(%rdx),%rax jae 20f - decq %rcx -2: movzwl (%rcx),%edx + decq %rax +2: movzwl (%rax),%edx xorl %eax,%eax ret -20: decq %rcx +20: decq %rax jmp bad_get_user CFI_ENDPROC ENDPROC(__get_user_2) ENTRY(__get_user_4) CFI_STARTPROC - GET_THREAD_INFO(%r8) - addq $3,%rcx + GET_THREAD_INFO(%rdx) + addq $3,%rax jc 30f - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq threadinfo_addr_limit(%rdx),%rax jae 30f - subq $3,%rcx -3: movl (%rcx),%edx + subq $3,%rax +3: movl (%rax),%edx xorl %eax,%eax ret -30: subq $3,%rcx +30: subq $3,%rax jmp bad_get_user CFI_ENDPROC ENDPROC(__get_user_4) ENTRY(__get_user_8) CFI_STARTPROC - GET_THREAD_INFO(%r8) - addq $7,%rcx + GET_THREAD_INFO(%rdx) + addq $7,%rax jc 40f - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq threadinfo_addr_limit(%rdx),%rax jae 40f - subq $7,%rcx -4: movq (%rcx),%rdx + subq $7,%rax +4: movq (%rax),%rdx xorl %eax,%eax ret -40: subq $7,%rcx +40: subq $7,%rax jmp bad_get_user CFI_ENDPROC ENDPROC(__get_user_8) diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index b8a2f43..a2d4907 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -90,8 +90,7 @@ extern int fixup_exception(struct pt_regs *regs); #define __get_user_x(size, ret, x, ptr) \ asm volatile("call __get_user_" #size \ : "=a" (ret),"=d" (x) \ - : "c" (ptr) \ - : "r8") + : "0" (ptr)) \ /* Careful: we have to cast the result to the type of the pointer * for sign reasons */ -- cgit v0.10.2 From 9aa038815b5756e20a00b8e1efd5740434b37aea Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 13 Jun 2008 22:41:51 -0300 Subject: x86: don't use word-size specifiers. Since the instructions refer to registers, they'll be able to figure it out. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S index 6d84b53..8200fde 100644 --- a/arch/x86/lib/getuser_32.S +++ b/arch/x86/lib/getuser_32.S @@ -29,44 +29,44 @@ ENTRY(__get_user_1) CFI_STARTPROC GET_THREAD_INFO(%edx) - cmpl TI_addr_limit(%edx),%eax + cmp TI_addr_limit(%edx),%eax jae bad_get_user -1: movzbl (%eax),%edx - xorl %eax,%eax +1: movzb (%eax),%edx + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_1) ENTRY(__get_user_2) CFI_STARTPROC - addl $1,%eax + add $1,%eax jc bad_get_user GET_THREAD_INFO(%edx) - cmpl TI_addr_limit(%edx),%eax + cmp TI_addr_limit(%edx),%eax jae bad_get_user 2: movzwl -1(%eax),%edx - xorl %eax,%eax + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_2) ENTRY(__get_user_4) CFI_STARTPROC - addl $3,%eax + add $3,%eax jc bad_get_user GET_THREAD_INFO(%edx) - cmpl TI_addr_limit(%edx),%eax + cmp TI_addr_limit(%edx),%eax jae bad_get_user -3: movl -3(%eax),%edx - xorl %eax,%eax +3: mov -3(%eax),%edx + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_4) bad_get_user: CFI_STARTPROC - xorl %edx,%edx - movl $-14,%eax + xor %edx,%edx + mov $-14,%eax ret CFI_ENDPROC END(bad_get_user) -- cgit v0.10.2 From 9262875395cf22b5a90dd8a640e1070cedf55d0e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 11:13:16 -0300 Subject: x86: adapt x86_64 getuser functions. Instead of doing a sub after the addition, use the offset directly at the memory operand of the mov instructions. This is the way i386 do. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S index 2b003d3..df37d3a 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser_64.S @@ -47,49 +47,40 @@ ENDPROC(__get_user_1) ENTRY(__get_user_2) CFI_STARTPROC - GET_THREAD_INFO(%rdx) addq $1,%rax - jc 20f + jc bad_get_user + GET_THREAD_INFO(%rdx) cmpq threadinfo_addr_limit(%rdx),%rax - jae 20f - decq %rax -2: movzwl (%rax),%edx + jae bad_get_user +2: movzwl -1(%rax),%edx xorl %eax,%eax ret -20: decq %rax - jmp bad_get_user CFI_ENDPROC ENDPROC(__get_user_2) ENTRY(__get_user_4) CFI_STARTPROC - GET_THREAD_INFO(%rdx) addq $3,%rax - jc 30f + jc bad_get_user + GET_THREAD_INFO(%rdx) cmpq threadinfo_addr_limit(%rdx),%rax - jae 30f - subq $3,%rax -3: movl (%rax),%edx + jae bad_get_user +3: movl -3(%rax),%edx xorl %eax,%eax ret -30: subq $3,%rax - jmp bad_get_user CFI_ENDPROC ENDPROC(__get_user_4) ENTRY(__get_user_8) CFI_STARTPROC - GET_THREAD_INFO(%rdx) addq $7,%rax - jc 40f + jc bad_get_user + GET_THREAD_INFO(%rdx) cmpq threadinfo_addr_limit(%rdx),%rax - jae 40f - subq $7,%rax -4: movq (%rax),%rdx + jae bad_get_user +4: movq -7(%rax),%rdx xorl %eax,%eax ret -40: subq $7,%rax - jmp bad_get_user CFI_ENDPROC ENDPROC(__get_user_8) -- cgit v0.10.2 From 26ccb8a7183eed424ff9c874c83af20dafe7cdef Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 11:19:35 -0300 Subject: x86: rename threadinfo to TI. This is for consistency with i386. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 24e4d49..20371d0 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -116,7 +116,7 @@ ENTRY(ia32_sysenter_target) pushfq CFI_ADJUST_CFA_OFFSET 8 /*CFI_REL_OFFSET rflags,0*/ - movl 8*3-THREAD_SIZE+threadinfo_sysenter_return(%rsp), %r10d + movl 8*3-THREAD_SIZE+TI_sysenter_return(%rsp), %r10d CFI_REGISTER rip,r10 pushq $__USER32_CS CFI_ADJUST_CFA_OFFSET 8 @@ -136,8 +136,9 @@ ENTRY(ia32_sysenter_target) .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) - orl $TS_COMPAT,threadinfo_status(%r10) - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) + orl $TS_COMPAT,TI_status(%r10) + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ + TI_flags(%r10) CFI_REMEMBER_STATE jnz sysenter_tracesys sysenter_do_call: @@ -149,9 +150,9 @@ sysenter_do_call: GET_THREAD_INFO(%r10) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) + testl $_TIF_ALLWORK_MASK,TI_flags(%r10) jnz int_ret_from_sys_call - andl $~TS_COMPAT,threadinfo_status(%r10) + andl $~TS_COMPAT,TI_status(%r10) /* clear IF, that popfq doesn't enable interrupts early */ andl $~0x200,EFLAGS-R11(%rsp) movl RIP-R11(%rsp),%edx /* User %eip */ @@ -240,8 +241,9 @@ ENTRY(ia32_cstar_target) .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) - orl $TS_COMPAT,threadinfo_status(%r10) - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) + orl $TS_COMPAT,TI_status(%r10) + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ + TI_flags(%r10) CFI_REMEMBER_STATE jnz cstar_tracesys cstar_do_call: @@ -253,9 +255,9 @@ cstar_do_call: GET_THREAD_INFO(%r10) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) + testl $_TIF_ALLWORK_MASK,TI_flags(%r10) jnz int_ret_from_sys_call - andl $~TS_COMPAT,threadinfo_status(%r10) + andl $~TS_COMPAT,TI_status(%r10) RESTORE_ARGS 1,-ARG_SKIP,1,1,1 movl RIP-ARGOFFSET(%rsp),%ecx CFI_REGISTER rip,rcx @@ -333,8 +335,9 @@ ENTRY(ia32_syscall) this could be a problem. */ SAVE_ARGS 0,0,1 GET_THREAD_INFO(%r10) - orl $TS_COMPAT,threadinfo_status(%r10) - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) + orl $TS_COMPAT,TI_status(%r10) + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ + TI_flags(%r10) jnz ia32_tracesys ia32_do_syscall: cmpl $(IA32_NR_syscalls-1),%eax diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 3295e7c..bacf5de 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -34,7 +34,7 @@ int main(void) ENTRY(pid); BLANK(); #undef ENTRY -#define ENTRY(entry) DEFINE(threadinfo_ ## entry, offsetof(struct thread_info, entry)) +#define ENTRY(entry) DEFINE(TI_ ## entry, offsetof(struct thread_info, entry)) ENTRY(flags); ENTRY(addr_limit); ENTRY(preempt_count); diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 07d69f2..466b928 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -168,13 +168,13 @@ ENTRY(ret_from_fork) CFI_ADJUST_CFA_OFFSET -4 call schedule_tail GET_THREAD_INFO(%rcx) - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx) + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%rcx) jnz rff_trace rff_action: RESTORE_REST testl $3,CS-ARGOFFSET(%rsp) # from kernel_thread? je int_ret_from_sys_call - testl $_TIF_IA32,threadinfo_flags(%rcx) + testl $_TIF_IA32,TI_flags(%rcx) jnz int_ret_from_sys_call RESTORE_TOP_OF_STACK %rdi,ARGOFFSET jmp ret_from_sys_call @@ -243,7 +243,8 @@ ENTRY(system_call_after_swapgs) movq %rcx,RIP-ARGOFFSET(%rsp) CFI_REL_OFFSET rip,RIP-ARGOFFSET GET_THREAD_INFO(%rcx) - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx) + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ + TI_flags(%rcx) jnz tracesys cmpq $__NR_syscall_max,%rax ja badsys @@ -262,7 +263,7 @@ sysret_check: GET_THREAD_INFO(%rcx) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - movl threadinfo_flags(%rcx),%edx + movl TI_flags(%rcx),%edx andl %edi,%edx jnz sysret_careful CFI_REMEMBER_STATE @@ -347,10 +348,10 @@ int_ret_from_sys_call: int_with_check: LOCKDEP_SYS_EXIT_IRQ GET_THREAD_INFO(%rcx) - movl threadinfo_flags(%rcx),%edx + movl TI_flags(%rcx),%edx andl %edi,%edx jnz int_careful - andl $~TS_COMPAT,threadinfo_status(%rcx) + andl $~TS_COMPAT,TI_status(%rcx) jmp retint_swapgs /* Either reschedule or signal or syscall exit tracking needed. */ @@ -558,7 +559,7 @@ retint_with_reschedule: movl $_TIF_WORK_MASK,%edi retint_check: LOCKDEP_SYS_EXIT_IRQ - movl threadinfo_flags(%rcx),%edx + movl TI_flags(%rcx),%edx andl %edi,%edx CFI_REMEMBER_STATE jnz retint_careful @@ -654,9 +655,9 @@ retint_signal: /* Returning to kernel space. Check if we need preemption */ /* rcx: threadinfo. interrupts off. */ ENTRY(retint_kernel) - cmpl $0,threadinfo_preempt_count(%rcx) + cmpl $0,TI_preempt_count(%rcx) jnz retint_restore_args - bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx) + bt $TIF_NEED_RESCHED,TI_flags(%rcx) jnc retint_restore_args bt $9,EFLAGS-ARGOFFSET(%rsp) /* interrupts off? */ jnc retint_restore_args @@ -819,7 +820,7 @@ paranoid_restore\trace: jmp irq_return paranoid_userspace\trace: GET_THREAD_INFO(%rcx) - movl threadinfo_flags(%rcx),%ebx + movl TI_flags(%rcx),%ebx andl $_TIF_WORK_MASK,%ebx jz paranoid_swapgs\trace movq %rsp,%rdi /* &pt_regs */ @@ -917,7 +918,7 @@ error_exit: testl %eax,%eax jne retint_kernel LOCKDEP_SYS_EXIT_IRQ - movl threadinfo_flags(%rcx),%edx + movl TI_flags(%rcx),%edx movl $_TIF_WORK_MASK,%edi andl %edi,%edx jnz retint_careful diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index ee1c3f6..7eaaf01 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -40,7 +40,7 @@ ENTRY(copy_to_user) movq %rdi,%rcx addq %rdx,%rcx jc bad_to_user - cmpq threadinfo_addr_limit(%rax),%rcx + cmpq TI_addr_limit(%rax),%rcx jae bad_to_user xorl %eax,%eax /* clear zero flag */ ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string @@ -65,7 +65,7 @@ ENTRY(copy_from_user) movq %rsi,%rcx addq %rdx,%rcx jc bad_from_user - cmpq threadinfo_addr_limit(%rax),%rcx + cmpq TI_addr_limit(%rax),%rcx jae bad_from_user movl $1,%ecx /* set zero flag */ ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S index df37d3a..0ec7890 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser_64.S @@ -37,7 +37,7 @@ ENTRY(__get_user_1) CFI_STARTPROC GET_THREAD_INFO(%rdx) - cmpq threadinfo_addr_limit(%rdx),%rax + cmpq TI_addr_limit(%rdx),%rax jae bad_get_user 1: movzb (%rax),%edx xorl %eax,%eax @@ -50,7 +50,7 @@ ENTRY(__get_user_2) addq $1,%rax jc bad_get_user GET_THREAD_INFO(%rdx) - cmpq threadinfo_addr_limit(%rdx),%rax + cmpq TI_addr_limit(%rdx),%rax jae bad_get_user 2: movzwl -1(%rax),%edx xorl %eax,%eax @@ -63,7 +63,7 @@ ENTRY(__get_user_4) addq $3,%rax jc bad_get_user GET_THREAD_INFO(%rdx) - cmpq threadinfo_addr_limit(%rdx),%rax + cmpq TI_addr_limit(%rdx),%rax jae bad_get_user 3: movl -3(%rax),%edx xorl %eax,%eax @@ -76,7 +76,7 @@ ENTRY(__get_user_8) addq $7,%rax jc bad_get_user GET_THREAD_INFO(%rdx) - cmpq threadinfo_addr_limit(%rdx),%rax + cmpq TI_addr_limit(%rdx),%rax jae bad_get_user 4: movq -7(%rax),%rdx xorl %eax,%eax diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index 4989f5a..940796f 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -35,7 +35,7 @@ ENTRY(__put_user_1) CFI_STARTPROC GET_THREAD_INFO(%r8) - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%r8),%rcx jae bad_put_user 1: movb %dl,(%rcx) xorl %eax,%eax @@ -48,7 +48,7 @@ ENTRY(__put_user_2) GET_THREAD_INFO(%r8) addq $1,%rcx jc 20f - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%r8),%rcx jae 20f decq %rcx 2: movw %dx,(%rcx) @@ -64,7 +64,7 @@ ENTRY(__put_user_4) GET_THREAD_INFO(%r8) addq $3,%rcx jc 30f - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%r8),%rcx jae 30f subq $3,%rcx 3: movl %edx,(%rcx) @@ -80,7 +80,7 @@ ENTRY(__put_user_8) GET_THREAD_INFO(%r8) addq $7,%rcx jc 40f - cmpq threadinfo_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%r8),%rcx jae 40f subq $7,%rcx 4: movq %rdx,(%rcx) -- cgit v0.10.2 From ef8c1a2d0e990d0f4f15e1d45eeb262755e3d4c3 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 11:21:53 -0300 Subject: x86: don't use word-size specifiers on getuser_64. The instructions access registers, so the size is unambiguous. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S index 0ec7890..6134752 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser_64.S @@ -37,57 +37,57 @@ ENTRY(__get_user_1) CFI_STARTPROC GET_THREAD_INFO(%rdx) - cmpq TI_addr_limit(%rdx),%rax + cmp TI_addr_limit(%rdx),%rax jae bad_get_user 1: movzb (%rax),%edx - xorl %eax,%eax + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_1) ENTRY(__get_user_2) CFI_STARTPROC - addq $1,%rax + add $1,%rax jc bad_get_user GET_THREAD_INFO(%rdx) - cmpq TI_addr_limit(%rdx),%rax + cmp TI_addr_limit(%rdx),%rax jae bad_get_user 2: movzwl -1(%rax),%edx - xorl %eax,%eax + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_2) ENTRY(__get_user_4) CFI_STARTPROC - addq $3,%rax + add $3,%rax jc bad_get_user GET_THREAD_INFO(%rdx) - cmpq TI_addr_limit(%rdx),%rax + cmp TI_addr_limit(%rdx),%rax jae bad_get_user -3: movl -3(%rax),%edx - xorl %eax,%eax +3: mov -3(%rax),%edx + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_4) ENTRY(__get_user_8) CFI_STARTPROC - addq $7,%rax + add $7,%rax jc bad_get_user GET_THREAD_INFO(%rdx) - cmpq TI_addr_limit(%rdx),%rax + cmp TI_addr_limit(%rdx),%rax jae bad_get_user 4: movq -7(%rax),%rdx - xorl %eax,%eax + xor %eax,%eax ret CFI_ENDPROC ENDPROC(__get_user_8) bad_get_user: CFI_STARTPROC - xorl %edx,%edx - movq $(-EFAULT),%rax + xor %edx,%edx + mov $(-EFAULT),%rax ret CFI_ENDPROC END(bad_get_user) -- cgit v0.10.2 From 40faf463e62de0b29722910eded7dd26cd8b684b Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 11:37:57 -0300 Subject: x86: introduce __ASM_REG macro. There are situations in which the architecture wants to use the register that represents its word-size, whatever it is. For those, introduce __ASM_REG in asm.h, along with the first users _ASM_AX and _ASM_DX. They have users waiting for it, namely the getuser functions. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S index 8200fde..2cc3cee 100644 --- a/arch/x86/lib/getuser_32.S +++ b/arch/x86/lib/getuser_32.S @@ -11,6 +11,7 @@ #include #include #include +#include /* @@ -28,10 +29,10 @@ .text ENTRY(__get_user_1) CFI_STARTPROC - GET_THREAD_INFO(%edx) - cmp TI_addr_limit(%edx),%eax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -1: movzb (%eax),%edx +1: movzb (%_ASM_AX),%edx xor %eax,%eax ret CFI_ENDPROC @@ -39,12 +40,12 @@ ENDPROC(__get_user_1) ENTRY(__get_user_2) CFI_STARTPROC - add $1,%eax + add $1,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%edx) - cmp TI_addr_limit(%edx),%eax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -2: movzwl -1(%eax),%edx +2: movzwl -1(%_ASM_AX),%edx xor %eax,%eax ret CFI_ENDPROC @@ -52,12 +53,12 @@ ENDPROC(__get_user_2) ENTRY(__get_user_4) CFI_STARTPROC - add $3,%eax + add $3,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%edx) - cmp TI_addr_limit(%edx),%eax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -3: mov -3(%eax),%edx +3: mov -3(%_ASM_AX),%edx xor %eax,%eax ret CFI_ENDPROC @@ -66,7 +67,7 @@ ENDPROC(__get_user_4) bad_get_user: CFI_STARTPROC xor %edx,%edx - mov $-14,%eax + mov $-14,%_ASM_AX ret CFI_ENDPROC END(bad_get_user) diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S index 6134752..63b0e5c 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser_64.S @@ -13,14 +13,13 @@ /* * __get_user_X * - * Inputs: %rcx contains the address. + * Inputs: %rax contains the address. * The register is modified, but all changes are undone * before returning because the C code doesn't know about it. * * Outputs: %rax is error code (0 or -EFAULT) * %rdx contains zero-extended value * - * %r8 is destroyed. * * These functions should not modify any other registers, * as they get called from within inline assembly. @@ -32,14 +31,15 @@ #include #include #include +#include .text ENTRY(__get_user_1) CFI_STARTPROC - GET_THREAD_INFO(%rdx) - cmp TI_addr_limit(%rdx),%rax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -1: movzb (%rax),%edx +1: movzb (%_ASM_AX),%edx xor %eax,%eax ret CFI_ENDPROC @@ -47,12 +47,12 @@ ENDPROC(__get_user_1) ENTRY(__get_user_2) CFI_STARTPROC - add $1,%rax + add $1,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%rdx) - cmp TI_addr_limit(%rdx),%rax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -2: movzwl -1(%rax),%edx +2: movzwl -1(%_ASM_AX),%edx xor %eax,%eax ret CFI_ENDPROC @@ -60,12 +60,12 @@ ENDPROC(__get_user_2) ENTRY(__get_user_4) CFI_STARTPROC - add $3,%rax + add $3,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%rdx) - cmp TI_addr_limit(%rdx),%rax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -3: mov -3(%rax),%edx +3: mov -3(%_ASM_AX),%edx xor %eax,%eax ret CFI_ENDPROC @@ -73,12 +73,12 @@ ENDPROC(__get_user_4) ENTRY(__get_user_8) CFI_STARTPROC - add $7,%rax + add $7,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%rdx) - cmp TI_addr_limit(%rdx),%rax + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user -4: movq -7(%rax),%rdx +4: movq -7(%_ASM_AX),%_ASM_DX xor %eax,%eax ret CFI_ENDPROC @@ -87,7 +87,7 @@ ENDPROC(__get_user_8) bad_get_user: CFI_STARTPROC xor %edx,%edx - mov $(-EFAULT),%rax + mov $(-EFAULT),%_ASM_AX ret CFI_ENDPROC END(bad_get_user) diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h index 70939820..435402e 100644 --- a/include/asm-x86/asm.h +++ b/include/asm-x86/asm.h @@ -14,6 +14,7 @@ #endif #define __ASM_SIZE(inst) __ASM_SEL(inst##l, inst##q) +#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg) #define _ASM_PTR __ASM_SEL(.long, .quad) #define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8) @@ -24,6 +25,8 @@ #define _ASM_ADD __ASM_SIZE(add) #define _ASM_SUB __ASM_SIZE(sub) #define _ASM_XADD __ASM_SIZE(xadd) +#define _ASM_AX __ASM_REG(ax) +#define _ASM_DX __ASM_REG(dx) /* Exception table entry */ # define _ASM_EXTABLE(from,to) \ -- cgit v0.10.2 From 87e2f1e7f6ab66306320403d4502d7938d3c703e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 12:02:44 -0300 Subject: x86: use _ASM_PTR instead of explicit word-size pointers. Switch .long and .quad with _ASM_PTR in getuser*.S. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S index 2cc3cee..2bb0a18 100644 --- a/arch/x86/lib/getuser_32.S +++ b/arch/x86/lib/getuser_32.S @@ -73,7 +73,7 @@ bad_get_user: END(bad_get_user) .section __ex_table,"a" - .long 1b,bad_get_user - .long 2b,bad_get_user - .long 3b,bad_get_user + _ASM_PTR 1b,bad_get_user + _ASM_PTR 2b,bad_get_user + _ASM_PTR 3b,bad_get_user .previous diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S index 63b0e5c..e333884 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser_64.S @@ -93,8 +93,8 @@ bad_get_user: END(bad_get_user) .section __ex_table,"a" - .quad 1b,bad_get_user - .quad 2b,bad_get_user - .quad 3b,bad_get_user - .quad 4b,bad_get_user + _ASM_PTR 1b,bad_get_user + _ASM_PTR 2b,bad_get_user + _ASM_PTR 3b,bad_get_user + _ASM_PTR 4b,bad_get_user .previous -- cgit v0.10.2 From 6c2d458680d49d939ffd4b4cdc84d9e004d65910 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 12:05:11 -0300 Subject: x86: merge getuser asm functions. getuser_32.S and getuser_64.S are merged into getuser.S. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 86960a6..e929482 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SMP) := msr-on-cpu.o lib-y := delay.o -lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o +lib-y += usercopy_$(BITS).o getuser.o putuser_$(BITS).o lib-y += memcpy_$(BITS).o ifeq ($(CONFIG_X86_32),y) diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S new file mode 100644 index 0000000..ad37400 --- /dev/null +++ b/arch/x86/lib/getuser.S @@ -0,0 +1,104 @@ +/* + * __get_user functions. + * + * (C) Copyright 1998 Linus Torvalds + * (C) Copyright 2005 Andi Kleen + * (C) Copyright 2008 Glauber Costa + * + * These functions have a non-standard call interface + * to make them more efficient, especially as they + * return an error value in addition to the "real" + * return value. + */ + +/* + * __get_user_X + * + * Inputs: %[r|e]ax contains the address. + * The register is modified, but all changes are undone + * before returning because the C code doesn't know about it. + * + * Outputs: %[r|e]ax is error code (0 or -EFAULT) + * %[r|e]dx contains zero-extended value + * + * + * These functions should not modify any other registers, + * as they get called from within inline assembly. + */ + +#include +#include +#include +#include +#include +#include +#include + + .text +ENTRY(__get_user_1) + CFI_STARTPROC + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user +1: movzb (%_ASM_AX),%edx + xor %eax,%eax + ret + CFI_ENDPROC +ENDPROC(__get_user_1) + +ENTRY(__get_user_2) + CFI_STARTPROC + add $1,%_ASM_AX + jc bad_get_user + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user +2: movzwl -1(%_ASM_AX),%edx + xor %eax,%eax + ret + CFI_ENDPROC +ENDPROC(__get_user_2) + +ENTRY(__get_user_4) + CFI_STARTPROC + add $3,%_ASM_AX + jc bad_get_user + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user +3: mov -3(%_ASM_AX),%edx + xor %eax,%eax + ret + CFI_ENDPROC +ENDPROC(__get_user_4) + +#ifdef CONFIG_X86_64 +ENTRY(__get_user_8) + CFI_STARTPROC + add $7,%_ASM_AX + jc bad_get_user + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user +4: movq -7(%_ASM_AX),%_ASM_DX + xor %eax,%eax + ret + CFI_ENDPROC +ENDPROC(__get_user_8) +#endif + +bad_get_user: + CFI_STARTPROC + xor %edx,%edx + mov $(-EFAULT),%_ASM_AX + ret + CFI_ENDPROC +END(bad_get_user) + +.section __ex_table,"a" + _ASM_PTR 1b,bad_get_user + _ASM_PTR 2b,bad_get_user + _ASM_PTR 3b,bad_get_user +#ifdef CONFIG_X86_64 + _ASM_PTR 4b,bad_get_user +#endif diff --git a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S deleted file mode 100644 index 2bb0a18..0000000 --- a/arch/x86/lib/getuser_32.S +++ /dev/null @@ -1,79 +0,0 @@ -/* - * __get_user functions. - * - * (C) Copyright 1998 Linus Torvalds - * - * These functions have a non-standard call interface - * to make them more efficient, especially as they - * return an error value in addition to the "real" - * return value. - */ -#include -#include -#include -#include - - -/* - * __get_user_X - * - * Inputs: %eax contains the address - * - * Outputs: %eax is error code (0 or -EFAULT) - * %edx contains zero-extended value - * - * These functions should not modify any other registers, - * as they get called from within inline assembly. - */ - -.text -ENTRY(__get_user_1) - CFI_STARTPROC - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -1: movzb (%_ASM_AX),%edx - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_1) - -ENTRY(__get_user_2) - CFI_STARTPROC - add $1,%_ASM_AX - jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -2: movzwl -1(%_ASM_AX),%edx - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_2) - -ENTRY(__get_user_4) - CFI_STARTPROC - add $3,%_ASM_AX - jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -3: mov -3(%_ASM_AX),%edx - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_4) - -bad_get_user: - CFI_STARTPROC - xor %edx,%edx - mov $-14,%_ASM_AX - ret - CFI_ENDPROC -END(bad_get_user) - -.section __ex_table,"a" - _ASM_PTR 1b,bad_get_user - _ASM_PTR 2b,bad_get_user - _ASM_PTR 3b,bad_get_user -.previous diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser_64.S deleted file mode 100644 index e333884..0000000 --- a/arch/x86/lib/getuser_64.S +++ /dev/null @@ -1,100 +0,0 @@ -/* - * __get_user functions. - * - * (C) Copyright 1998 Linus Torvalds - * (C) Copyright 2005 Andi Kleen - * - * These functions have a non-standard call interface - * to make them more efficient, especially as they - * return an error value in addition to the "real" - * return value. - */ - -/* - * __get_user_X - * - * Inputs: %rax contains the address. - * The register is modified, but all changes are undone - * before returning because the C code doesn't know about it. - * - * Outputs: %rax is error code (0 or -EFAULT) - * %rdx contains zero-extended value - * - * - * These functions should not modify any other registers, - * as they get called from within inline assembly. - */ - -#include -#include -#include -#include -#include -#include -#include - - .text -ENTRY(__get_user_1) - CFI_STARTPROC - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -1: movzb (%_ASM_AX),%edx - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_1) - -ENTRY(__get_user_2) - CFI_STARTPROC - add $1,%_ASM_AX - jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -2: movzwl -1(%_ASM_AX),%edx - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_2) - -ENTRY(__get_user_4) - CFI_STARTPROC - add $3,%_ASM_AX - jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -3: mov -3(%_ASM_AX),%edx - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_4) - -ENTRY(__get_user_8) - CFI_STARTPROC - add $7,%_ASM_AX - jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX - jae bad_get_user -4: movq -7(%_ASM_AX),%_ASM_DX - xor %eax,%eax - ret - CFI_ENDPROC -ENDPROC(__get_user_8) - -bad_get_user: - CFI_STARTPROC - xor %edx,%edx - mov $(-EFAULT),%_ASM_AX - ret - CFI_ENDPROC -END(bad_get_user) - -.section __ex_table,"a" - _ASM_PTR 1b,bad_get_user - _ASM_PTR 2b,bad_get_user - _ASM_PTR 3b,bad_get_user - _ASM_PTR 4b,bad_get_user -.previous diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h index 435402e..57750a9 100644 --- a/include/asm-x86/asm.h +++ b/include/asm-x86/asm.h @@ -3,8 +3,10 @@ #ifdef __ASSEMBLY__ # define __ASM_FORM(x) x +# define __ASM_EX_SEC .section __ex_table #else # define __ASM_FORM(x) " " #x " " +# define __ASM_EX_SEC " .section __ex_table,\"a\"\n" #endif #ifdef CONFIG_X86_32 @@ -30,7 +32,7 @@ /* Exception table entry */ # define _ASM_EXTABLE(from,to) \ - " .section __ex_table,\"a\"\n" \ + __ASM_EX_SEC \ _ASM_ALIGN "\n" \ _ASM_PTR #from "," #to "\n" \ " .previous\n" -- cgit v0.10.2 From 268cf048c890d10bd3a86bd87922ed8a722d502f Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 12:40:55 -0300 Subject: x86: don't save ebx in putuser_32.S. Clobber it in the inline asm macros, and let the compiler do this for us. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser_32.S index f58fba1..5b2a926 100644 --- a/arch/x86/lib/putuser_32.S +++ b/arch/x86/lib/putuser_32.S @@ -26,14 +26,8 @@ */ #define ENTER CFI_STARTPROC ; \ - pushl %ebx ; \ - CFI_ADJUST_CFA_OFFSET 4 ; \ - CFI_REL_OFFSET ebx, 0 ; \ GET_THREAD_INFO(%ebx) -#define EXIT popl %ebx ; \ - CFI_ADJUST_CFA_OFFSET -4 ; \ - CFI_RESTORE ebx ; \ - ret ; \ +#define EXIT ret ; \ CFI_ENDPROC .text @@ -81,10 +75,7 @@ ENTRY(__put_user_8) ENDPROC(__put_user_8) bad_put_user: - CFI_STARTPROC simple - CFI_DEF_CFA esp, 2*4 - CFI_OFFSET eip, -1*4 - CFI_OFFSET ebx, -2*4 + CFI_STARTPROC movl $-14,%eax EXIT END(bad_put_user) diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 8e7595c..0ecfe47 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -188,23 +188,23 @@ extern void __put_user_8(void); #define __put_user_1(x, ptr) \ asm volatile("call __put_user_1" : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr)) + : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #define __put_user_2(x, ptr) \ asm volatile("call __put_user_2" : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr)) + : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #define __put_user_4(x, ptr) \ asm volatile("call __put_user_4" : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr)) + : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #define __put_user_8(x, ptr) \ asm volatile("call __put_user_8" : "=a" (__ret_pu) \ - : "A" ((typeof(*(ptr)))(x)), "c" (ptr)) + : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #define __put_user_X(x, ptr) \ asm volatile("call __put_user_X" : "=a" (__ret_pu) \ - : "c" (ptr)) + : "c" (ptr): "ebx") /** * put_user: - Write a simple value into user space. -- cgit v0.10.2 From 70706e432ee5618abf59381101d8dea7b8d97a7d Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 15:02:31 -0300 Subject: x86: user put_user_x instead of all variants. Follow the pattern, and define a single put_user_x, instead of defining macros for all available sizes. Exception is put_user_8, since the "A" constraint does not give us enough power to specify which register (a or d) to use in the 32-bit common case. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 0ecfe47..f8abc12 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -186,25 +186,14 @@ extern void __put_user_2(void); extern void __put_user_4(void); extern void __put_user_8(void); -#define __put_user_1(x, ptr) \ - asm volatile("call __put_user_1" : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") - -#define __put_user_2(x, ptr) \ - asm volatile("call __put_user_2" : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") - -#define __put_user_4(x, ptr) \ - asm volatile("call __put_user_4" : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") +#define __put_user_x(size, x, ptr) \ + asm volatile("call __put_user_" #size : "=a" (__ret_pu) \ + :"0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #define __put_user_8(x, ptr) \ asm volatile("call __put_user_8" : "=a" (__ret_pu) \ : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") -#define __put_user_X(x, ptr) \ - asm volatile("call __put_user_X" : "=a" (__ret_pu) \ - : "c" (ptr): "ebx") /** * put_user: - Write a simple value into user space. @@ -232,19 +221,19 @@ extern void __put_user_8(void); __pu_val = x; \ switch (sizeof(*(ptr))) { \ case 1: \ - __put_user_1(__pu_val, ptr); \ + __put_user_x(1, __pu_val, ptr); \ break; \ case 2: \ - __put_user_2(__pu_val, ptr); \ + __put_user_x(2, __pu_val, ptr); \ break; \ case 4: \ - __put_user_4(__pu_val, ptr); \ + __put_user_x(4, __pu_val, ptr); \ break; \ case 8: \ __put_user_8(__pu_val, ptr); \ break; \ default: \ - __put_user_X(__pu_val, ptr); \ + __put_user_x(X, __pu_val, ptr); \ break; \ } \ __ret_pu; \ -- cgit v0.10.2 From 770546b99fb99e71a3aa4181980d42664f9c18bd Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 15:03:40 -0300 Subject: x86: clobber rbx in putuser_64.S. Instead of clobbering r8, clobber rbx, which is the i386 way. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index 940796f..0702885 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -18,7 +18,7 @@ * * Outputs: %rax is error code (0 or -EFAULT) * - * %r8 is destroyed. + * %rbx is destroyed. * * These functions should not modify any other registers, * as they get called from within inline assembly. @@ -34,8 +34,8 @@ .text ENTRY(__put_user_1) CFI_STARTPROC - GET_THREAD_INFO(%r8) - cmpq TI_addr_limit(%r8),%rcx + GET_THREAD_INFO(%rbx) + cmpq TI_addr_limit(%rbx),%rcx jae bad_put_user 1: movb %dl,(%rcx) xorl %eax,%eax @@ -45,10 +45,10 @@ ENDPROC(__put_user_1) ENTRY(__put_user_2) CFI_STARTPROC - GET_THREAD_INFO(%r8) + GET_THREAD_INFO(%rbx) addq $1,%rcx jc 20f - cmpq TI_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%rbx),%rcx jae 20f decq %rcx 2: movw %dx,(%rcx) @@ -61,10 +61,10 @@ ENDPROC(__put_user_2) ENTRY(__put_user_4) CFI_STARTPROC - GET_THREAD_INFO(%r8) + GET_THREAD_INFO(%rbx) addq $3,%rcx jc 30f - cmpq TI_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%rbx),%rcx jae 30f subq $3,%rcx 3: movl %edx,(%rcx) @@ -77,10 +77,10 @@ ENDPROC(__put_user_4) ENTRY(__put_user_8) CFI_STARTPROC - GET_THREAD_INFO(%r8) + GET_THREAD_INFO(%rbx) addq $7,%rcx jc 40f - cmpq TI_addr_limit(%r8),%rcx + cmpq TI_addr_limit(%rbx),%rcx jae 40f subq $7,%rcx 4: movq %rdx,(%rcx) diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index a2d4907..21fda9e 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -131,7 +131,7 @@ extern void __put_user_bad(void); asm volatile("call __put_user_" #size \ :"=a" (ret) \ :"c" (ptr),"d" (x) \ - :"r8") + :"ebx") #define put_user(x, ptr) \ __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) -- cgit v0.10.2 From 0ada3164031162b4e1b7ff6b36ba8cc80ff7fe96 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 16:44:39 -0300 Subject: x86: pass argument to putuser_64 functions in ax register. This is consistent with i386 usage. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index 0702885..ce5fcd5 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -37,7 +37,7 @@ ENTRY(__put_user_1) GET_THREAD_INFO(%rbx) cmpq TI_addr_limit(%rbx),%rcx jae bad_put_user -1: movb %dl,(%rcx) +1: movb %al,(%rcx) xorl %eax,%eax ret CFI_ENDPROC @@ -51,7 +51,7 @@ ENTRY(__put_user_2) cmpq TI_addr_limit(%rbx),%rcx jae 20f decq %rcx -2: movw %dx,(%rcx) +2: movw %ax,(%rcx) xorl %eax,%eax ret 20: decq %rcx @@ -67,7 +67,7 @@ ENTRY(__put_user_4) cmpq TI_addr_limit(%rbx),%rcx jae 30f subq $3,%rcx -3: movl %edx,(%rcx) +3: movl %eax,(%rcx) xorl %eax,%eax ret 30: subq $3,%rcx @@ -83,7 +83,7 @@ ENTRY(__put_user_8) cmpq TI_addr_limit(%rbx),%rcx jae 40f subq $7,%rcx -4: movq %rdx,(%rcx) +4: movq %rax,(%rcx) xorl %eax,%eax ret 40: subq $7,%rcx diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 21fda9e..f822a36 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -130,7 +130,7 @@ extern void __put_user_bad(void); #define __put_user_x(size, ret, x, ptr) \ asm volatile("call __put_user_" #size \ :"=a" (ret) \ - :"c" (ptr),"d" (x) \ + :"c" (ptr),"a" (x) \ :"ebx") #define put_user(x, ptr) \ -- cgit v0.10.2 From 663aa96df32af9c4141ef3179282f95c7537643a Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 16:51:59 -0300 Subject: x86: change testing logic in putuser_64.S. Instead of operating over a register we need to put back into normal state afterwards (the memory position), just sub from rbx, which is trashed anyway. We can save a few instructions. Also, this is the i386 way. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index ce5fcd5..a96bd8a 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -46,48 +46,39 @@ ENDPROC(__put_user_1) ENTRY(__put_user_2) CFI_STARTPROC GET_THREAD_INFO(%rbx) - addq $1,%rcx - jc 20f - cmpq TI_addr_limit(%rbx),%rcx - jae 20f - decq %rcx + mov TI_addr_limit(%rbx),%rbx + sub $1, %rbx + cmpq %rbx ,%rcx + jae bad_put_user 2: movw %ax,(%rcx) xorl %eax,%eax ret -20: decq %rcx - jmp bad_put_user CFI_ENDPROC ENDPROC(__put_user_2) ENTRY(__put_user_4) CFI_STARTPROC GET_THREAD_INFO(%rbx) - addq $3,%rcx - jc 30f - cmpq TI_addr_limit(%rbx),%rcx - jae 30f - subq $3,%rcx + mov TI_addr_limit(%rbx),%rbx + sub $3, %rbx + cmp %rbx, %rcx + jae bad_put_user 3: movl %eax,(%rcx) xorl %eax,%eax ret -30: subq $3,%rcx - jmp bad_put_user CFI_ENDPROC ENDPROC(__put_user_4) ENTRY(__put_user_8) CFI_STARTPROC GET_THREAD_INFO(%rbx) - addq $7,%rcx - jc 40f - cmpq TI_addr_limit(%rbx),%rcx - jae 40f - subq $7,%rcx + mov TI_addr_limit(%rbx),%rbx + sub $7, %rbx + cmp %rbx, %rcx + jae bad_put_user 4: movq %rax,(%rcx) xorl %eax,%eax ret -40: subq $7,%rcx - jmp bad_put_user CFI_ENDPROC ENDPROC(__put_user_8) -- cgit v0.10.2 From 766ed4282114eab616741107745b0dd11075e496 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 16:56:30 -0300 Subject: x86: replace function headers by macros. In putuser_64.S, do it the i386 way, and replace the code in beginning and end of functions with macros, since it's always the same thing. Save lines. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index a96bd8a..6d7513b 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -31,62 +31,58 @@ #include #include +#define ENTER CFI_STARTPROC ; \ + GET_THREAD_INFO(%rbx) +#define EXIT ret ; \ + CFI_ENDPROC + .text ENTRY(__put_user_1) - CFI_STARTPROC - GET_THREAD_INFO(%rbx) + ENTER cmpq TI_addr_limit(%rbx),%rcx jae bad_put_user 1: movb %al,(%rcx) xorl %eax,%eax - ret - CFI_ENDPROC + EXIT ENDPROC(__put_user_1) ENTRY(__put_user_2) - CFI_STARTPROC - GET_THREAD_INFO(%rbx) + ENTER mov TI_addr_limit(%rbx),%rbx sub $1, %rbx cmpq %rbx ,%rcx jae bad_put_user 2: movw %ax,(%rcx) xorl %eax,%eax - ret - CFI_ENDPROC + EXIT ENDPROC(__put_user_2) ENTRY(__put_user_4) - CFI_STARTPROC - GET_THREAD_INFO(%rbx) + ENTER mov TI_addr_limit(%rbx),%rbx sub $3, %rbx cmp %rbx, %rcx jae bad_put_user 3: movl %eax,(%rcx) xorl %eax,%eax - ret - CFI_ENDPROC + EXIT ENDPROC(__put_user_4) ENTRY(__put_user_8) - CFI_STARTPROC - GET_THREAD_INFO(%rbx) + ENTER mov TI_addr_limit(%rbx),%rbx sub $7, %rbx cmp %rbx, %rcx jae bad_put_user 4: movq %rax,(%rcx) xorl %eax,%eax - ret - CFI_ENDPROC + EXIT ENDPROC(__put_user_8) bad_put_user: CFI_STARTPROC movq $(-EFAULT),%rax - ret - CFI_ENDPROC + EXIT END(bad_put_user) .section __ex_table,"a" -- cgit v0.10.2 From efea505d83873cfc8a7cdbb8a2a11d2c67467843 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 16:59:05 -0300 Subject: x86: don't use word-size specifiers in putuser files. Remove them where unambiguous. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser_32.S index 5b2a926..b67a37c 100644 --- a/arch/x86/lib/putuser_32.S +++ b/arch/x86/lib/putuser_32.S @@ -33,44 +33,44 @@ .text ENTRY(__put_user_1) ENTER - cmpl TI_addr_limit(%ebx),%ecx + cmp TI_addr_limit(%ebx),%ecx jae bad_put_user 1: movb %al,(%ecx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_1) ENTRY(__put_user_2) ENTER - movl TI_addr_limit(%ebx),%ebx - subl $1,%ebx - cmpl %ebx,%ecx + mov TI_addr_limit(%ebx),%ebx + sub $1,%ebx + cmp %ebx,%ecx jae bad_put_user 2: movw %ax,(%ecx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_2) ENTRY(__put_user_4) ENTER - movl TI_addr_limit(%ebx),%ebx - subl $3,%ebx - cmpl %ebx,%ecx + mov TI_addr_limit(%ebx),%ebx + sub $3,%ebx + cmp %ebx,%ecx jae bad_put_user 3: movl %eax,(%ecx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_4) ENTRY(__put_user_8) ENTER - movl TI_addr_limit(%ebx),%ebx - subl $7,%ebx - cmpl %ebx,%ecx + mov TI_addr_limit(%ebx),%ebx + sub $7,%ebx + cmp %ebx,%ecx jae bad_put_user 4: movl %eax,(%ecx) 5: movl %edx,4(%ecx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_8) diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index 6d7513b..c18fc0f 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -39,10 +39,10 @@ .text ENTRY(__put_user_1) ENTER - cmpq TI_addr_limit(%rbx),%rcx + cmp TI_addr_limit(%rbx),%rcx jae bad_put_user 1: movb %al,(%rcx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_1) @@ -50,10 +50,10 @@ ENTRY(__put_user_2) ENTER mov TI_addr_limit(%rbx),%rbx sub $1, %rbx - cmpq %rbx ,%rcx + cmp %rbx ,%rcx jae bad_put_user 2: movw %ax,(%rcx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_2) @@ -64,7 +64,7 @@ ENTRY(__put_user_4) cmp %rbx, %rcx jae bad_put_user 3: movl %eax,(%rcx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_4) @@ -75,13 +75,13 @@ ENTRY(__put_user_8) cmp %rbx, %rcx jae bad_put_user 4: movq %rax,(%rcx) - xorl %eax,%eax + xor %eax,%eax EXIT ENDPROC(__put_user_8) bad_put_user: CFI_STARTPROC - movq $(-EFAULT),%rax + mov $(-EFAULT),%rax EXIT END(bad_put_user) -- cgit v0.10.2 From 2528de431ddb200653d1dc6ca90074bad9520f09 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 17:36:31 -0300 Subject: x86: use macros from asm.h. In putuser_32.S and putuser_64.S, replace things like .quad, .long, and explicit references to [r|e]ax for the apropriate macros in asm/asm.h. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser_32.S index b67a37c..e7eda34 100644 --- a/arch/x86/lib/putuser_32.S +++ b/arch/x86/lib/putuser_32.S @@ -11,6 +11,7 @@ #include #include #include +#include /* @@ -26,50 +27,50 @@ */ #define ENTER CFI_STARTPROC ; \ - GET_THREAD_INFO(%ebx) + GET_THREAD_INFO(%_ASM_BX) #define EXIT ret ; \ CFI_ENDPROC .text ENTRY(__put_user_1) ENTER - cmp TI_addr_limit(%ebx),%ecx + cmp TI_addr_limit(%_ASM_BX),%_ASM_CX jae bad_put_user -1: movb %al,(%ecx) +1: movb %al,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_1) ENTRY(__put_user_2) ENTER - mov TI_addr_limit(%ebx),%ebx - sub $1,%ebx - cmp %ebx,%ecx + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $1,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX jae bad_put_user -2: movw %ax,(%ecx) +2: movw %ax,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_2) ENTRY(__put_user_4) ENTER - mov TI_addr_limit(%ebx),%ebx - sub $3,%ebx - cmp %ebx,%ecx + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $3,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX jae bad_put_user -3: movl %eax,(%ecx) +3: movl %eax,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_4) ENTRY(__put_user_8) ENTER - mov TI_addr_limit(%ebx),%ebx - sub $7,%ebx - cmp %ebx,%ecx + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $7,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX jae bad_put_user -4: movl %eax,(%ecx) -5: movl %edx,4(%ecx) +4: movl %_ASM_AX,(%_ASM_CX) +5: movl %edx,4(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_8) @@ -81,9 +82,9 @@ bad_put_user: END(bad_put_user) .section __ex_table,"a" - .long 1b,bad_put_user - .long 2b,bad_put_user - .long 3b,bad_put_user - .long 4b,bad_put_user - .long 5b,bad_put_user + _ASM_PTR 1b,bad_put_user + _ASM_PTR 2b,bad_put_user + _ASM_PTR 3b,bad_put_user + _ASM_PTR 4b,bad_put_user + _ASM_PTR 5b,bad_put_user .previous diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S index c18fc0f..d496cc8 100644 --- a/arch/x86/lib/putuser_64.S +++ b/arch/x86/lib/putuser_64.S @@ -30,64 +30,65 @@ #include #include #include +#include #define ENTER CFI_STARTPROC ; \ - GET_THREAD_INFO(%rbx) + GET_THREAD_INFO(%_ASM_BX) #define EXIT ret ; \ CFI_ENDPROC .text ENTRY(__put_user_1) ENTER - cmp TI_addr_limit(%rbx),%rcx + cmp TI_addr_limit(%_ASM_BX),%_ASM_CX jae bad_put_user -1: movb %al,(%rcx) +1: movb %al,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_1) ENTRY(__put_user_2) ENTER - mov TI_addr_limit(%rbx),%rbx - sub $1, %rbx - cmp %rbx ,%rcx + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $1, %_ASM_BX + cmp %_ASM_BX ,%_ASM_CX jae bad_put_user -2: movw %ax,(%rcx) +2: movw %ax,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_2) ENTRY(__put_user_4) ENTER - mov TI_addr_limit(%rbx),%rbx - sub $3, %rbx - cmp %rbx, %rcx + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $3, %_ASM_BX + cmp %_ASM_BX, %_ASM_CX jae bad_put_user -3: movl %eax,(%rcx) +3: movl %eax,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_4) ENTRY(__put_user_8) ENTER - mov TI_addr_limit(%rbx),%rbx - sub $7, %rbx - cmp %rbx, %rcx + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $7, %_ASM_BX + cmp %_ASM_BX, %_ASM_CX jae bad_put_user -4: movq %rax,(%rcx) +4: movq %_ASM_AX,(%_ASM_CX) xor %eax,%eax EXIT ENDPROC(__put_user_8) bad_put_user: CFI_STARTPROC - mov $(-EFAULT),%rax + mov $(-EFAULT),%eax EXIT END(bad_put_user) .section __ex_table,"a" - .quad 1b,bad_put_user - .quad 2b,bad_put_user - .quad 3b,bad_put_user - .quad 4b,bad_put_user + _ASM_PTR 1b,bad_put_user + _ASM_PTR 2b,bad_put_user + _ASM_PTR 3b,bad_put_user + _ASM_PTR 4b,bad_put_user .previous diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h index 57750a9..9722032 100644 --- a/include/asm-x86/asm.h +++ b/include/asm-x86/asm.h @@ -28,6 +28,8 @@ #define _ASM_SUB __ASM_SIZE(sub) #define _ASM_XADD __ASM_SIZE(xadd) #define _ASM_AX __ASM_REG(ax) +#define _ASM_BX __ASM_REG(bx) +#define _ASM_CX __ASM_REG(cx) #define _ASM_DX __ASM_REG(dx) /* Exception table entry */ -- cgit v0.10.2 From 5cbbc3b1eb37bdc72eefd2de03b39f5e784400c2 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Tue, 24 Jun 2008 17:40:14 -0300 Subject: x86: merge putuser asm functions. putuser_32.S and putuser_64.S are merged into putuser.S. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index e929482..83226e0 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SMP) := msr-on-cpu.o lib-y := delay.o -lib-y += usercopy_$(BITS).o getuser.o putuser_$(BITS).o +lib-y += usercopy_$(BITS).o getuser.o putuser.o lib-y += memcpy_$(BITS).o ifeq ($(CONFIG_X86_32),y) diff --git a/arch/x86/lib/putuser.S b/arch/x86/lib/putuser.S new file mode 100644 index 0000000..36b0d15 --- /dev/null +++ b/arch/x86/lib/putuser.S @@ -0,0 +1,97 @@ +/* + * __put_user functions. + * + * (C) Copyright 2005 Linus Torvalds + * (C) Copyright 2005 Andi Kleen + * (C) Copyright 2008 Glauber Costa + * + * These functions have a non-standard call interface + * to make them more efficient, especially as they + * return an error value in addition to the "real" + * return value. + */ +#include +#include +#include +#include +#include + + +/* + * __put_user_X + * + * Inputs: %eax[:%edx] contains the data + * %ecx contains the address + * + * Outputs: %eax is error code (0 or -EFAULT) + * + * These functions should not modify any other registers, + * as they get called from within inline assembly. + */ + +#define ENTER CFI_STARTPROC ; \ + GET_THREAD_INFO(%_ASM_BX) +#define EXIT ret ; \ + CFI_ENDPROC + +.text +ENTRY(__put_user_1) + ENTER + cmp TI_addr_limit(%_ASM_BX),%_ASM_CX + jae bad_put_user +1: movb %al,(%_ASM_CX) + xor %eax,%eax + EXIT +ENDPROC(__put_user_1) + +ENTRY(__put_user_2) + ENTER + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $1,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX + jae bad_put_user +2: movw %ax,(%_ASM_CX) + xor %eax,%eax + EXIT +ENDPROC(__put_user_2) + +ENTRY(__put_user_4) + ENTER + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $3,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX + jae bad_put_user +3: movl %eax,(%_ASM_CX) + xor %eax,%eax + EXIT +ENDPROC(__put_user_4) + +ENTRY(__put_user_8) + ENTER + mov TI_addr_limit(%_ASM_BX),%_ASM_BX + sub $7,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX + jae bad_put_user +4: mov %_ASM_AX,(%_ASM_CX) +#ifdef CONFIG_X86_32 +5: movl %edx,4(%_ASM_CX) +#endif + xor %eax,%eax + EXIT +ENDPROC(__put_user_8) + +bad_put_user: + CFI_STARTPROC + movl $-EFAULT,%eax + EXIT +END(bad_put_user) + +.section __ex_table,"a" + _ASM_PTR 1b,bad_put_user + _ASM_PTR 2b,bad_put_user + _ASM_PTR 3b,bad_put_user + _ASM_PTR 4b,bad_put_user +#ifdef CONFIG_X86_32 + _ASM_PTR 5b,bad_put_user +#endif +.previous diff --git a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser_32.S deleted file mode 100644 index e7eda34..0000000 --- a/arch/x86/lib/putuser_32.S +++ /dev/null @@ -1,90 +0,0 @@ -/* - * __put_user functions. - * - * (C) Copyright 2005 Linus Torvalds - * - * These functions have a non-standard call interface - * to make them more efficient, especially as they - * return an error value in addition to the "real" - * return value. - */ -#include -#include -#include -#include - - -/* - * __put_user_X - * - * Inputs: %eax[:%edx] contains the data - * %ecx contains the address - * - * Outputs: %eax is error code (0 or -EFAULT) - * - * These functions should not modify any other registers, - * as they get called from within inline assembly. - */ - -#define ENTER CFI_STARTPROC ; \ - GET_THREAD_INFO(%_ASM_BX) -#define EXIT ret ; \ - CFI_ENDPROC - -.text -ENTRY(__put_user_1) - ENTER - cmp TI_addr_limit(%_ASM_BX),%_ASM_CX - jae bad_put_user -1: movb %al,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_1) - -ENTRY(__put_user_2) - ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX - sub $1,%_ASM_BX - cmp %_ASM_BX,%_ASM_CX - jae bad_put_user -2: movw %ax,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_2) - -ENTRY(__put_user_4) - ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX - sub $3,%_ASM_BX - cmp %_ASM_BX,%_ASM_CX - jae bad_put_user -3: movl %eax,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_4) - -ENTRY(__put_user_8) - ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX - sub $7,%_ASM_BX - cmp %_ASM_BX,%_ASM_CX - jae bad_put_user -4: movl %_ASM_AX,(%_ASM_CX) -5: movl %edx,4(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_8) - -bad_put_user: - CFI_STARTPROC - movl $-14,%eax - EXIT -END(bad_put_user) - -.section __ex_table,"a" - _ASM_PTR 1b,bad_put_user - _ASM_PTR 2b,bad_put_user - _ASM_PTR 3b,bad_put_user - _ASM_PTR 4b,bad_put_user - _ASM_PTR 5b,bad_put_user -.previous diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S deleted file mode 100644 index d496cc8..0000000 --- a/arch/x86/lib/putuser_64.S +++ /dev/null @@ -1,94 +0,0 @@ -/* - * __put_user functions. - * - * (C) Copyright 1998 Linus Torvalds - * (C) Copyright 2005 Andi Kleen - * - * These functions have a non-standard call interface - * to make them more efficient, especially as they - * return an error value in addition to the "real" - * return value. - */ - -/* - * __put_user_X - * - * Inputs: %rcx contains the address - * %rdx contains new value - * - * Outputs: %rax is error code (0 or -EFAULT) - * - * %rbx is destroyed. - * - * These functions should not modify any other registers, - * as they get called from within inline assembly. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define ENTER CFI_STARTPROC ; \ - GET_THREAD_INFO(%_ASM_BX) -#define EXIT ret ; \ - CFI_ENDPROC - - .text -ENTRY(__put_user_1) - ENTER - cmp TI_addr_limit(%_ASM_BX),%_ASM_CX - jae bad_put_user -1: movb %al,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_1) - -ENTRY(__put_user_2) - ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX - sub $1, %_ASM_BX - cmp %_ASM_BX ,%_ASM_CX - jae bad_put_user -2: movw %ax,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_2) - -ENTRY(__put_user_4) - ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX - sub $3, %_ASM_BX - cmp %_ASM_BX, %_ASM_CX - jae bad_put_user -3: movl %eax,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_4) - -ENTRY(__put_user_8) - ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX - sub $7, %_ASM_BX - cmp %_ASM_BX, %_ASM_CX - jae bad_put_user -4: movq %_ASM_AX,(%_ASM_CX) - xor %eax,%eax - EXIT -ENDPROC(__put_user_8) - -bad_put_user: - CFI_STARTPROC - mov $(-EFAULT),%eax - EXIT -END(bad_put_user) - -.section __ex_table,"a" - _ASM_PTR 1b,bad_put_user - _ASM_PTR 2b,bad_put_user - _ASM_PTR 3b,bad_put_user - _ASM_PTR 4b,bad_put_user -.previous -- cgit v0.10.2 From 53938a68a2f971058bc53aaa8c70f9f24f684cdc Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 10:14:13 -0300 Subject: x86: commonize __range_not_ok. For i386, __range_not_ok is a better name than __range_ok, since it returns 0 when it is in fact okay. Other than that, both versions does not need the word size specifiers, and we remove them. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index f8abc12..8d3f02d 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -56,11 +56,11 @@ extern struct movsl_mask { * * This needs 33-bit arithmetic. We have a carry... */ -#define __range_ok(addr, size) \ +#define __range_not_ok(addr, size) \ ({ \ unsigned long flag, roksum; \ __chk_user_ptr(addr); \ - asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \ + asm("add %3,%1 ; sbb %0,%0; cmp %1,%4; sbb $0,%0" \ :"=&r" (flag), "=r" (roksum) \ :"1" (addr), "g" ((int)(size)), \ "rm" (current_thread_info()->addr_limit.seg)); \ @@ -86,7 +86,7 @@ extern struct movsl_mask { * checks that the pointer is in the user space range - after calling * this function, memory access functions may still return -EFAULT. */ -#define access_ok(type, addr, size) (likely(__range_ok(addr, size) == 0)) +#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) /* * The exception table consists of pairs of addresses: the first is the diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index f822a36..012cba3 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -41,8 +41,7 @@ ({ \ unsigned long flag, roksum; \ __chk_user_ptr(addr); \ - asm("# range_ok\n\r" \ - "addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0" \ + asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ : "=&r" (flag), "=r" (roksum) \ : "1" (addr), "g" ((long)(size)), \ "g" (current_thread_info()->addr_limit.seg)); \ -- cgit v0.10.2 From c28b95d9bb7da0c3be22826c56a05899e21e5ece Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Mon, 30 Jun 2008 17:07:51 -0300 Subject: x86: change asm constraint. Our integration efforts broke a build with this function being used with i386. Reason is "g" can put the operand in an imm32, which according to The Book (tm), is invalid as the second operand. This is actually a bug in x86_64 too, since the x86_64 instruction set reference does not list it as valid. We probably didn't trigger this before due to the ammount of registers available for 64-bit platforms. But that's just my guess. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 012cba3..dc6dde0 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -44,7 +44,7 @@ asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ : "=&r" (flag), "=r" (roksum) \ : "1" (addr), "g" ((long)(size)), \ - "g" (current_thread_info()->addr_limit.seg)); \ + "rm" (current_thread_info()->addr_limit.seg)); \ flag; \ }) -- cgit v0.10.2 From 8b0a8aaf05325a1a96f53b45708f77599da35161 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Mon, 30 Jun 2008 17:34:39 -0300 Subject: x86: introduce likely in macro. Put the likely hint in access_ok. Just for bisectability. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index dc6dde0..0077dbe 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -48,7 +48,7 @@ flag; \ }) -#define access_ok(type, addr, size) (__range_not_ok(addr, size) == 0) +#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) /* * The exception table consists of pairs of addresses: the first is the -- cgit v0.10.2 From 1dc186e82c1ab476ef83080adca43a70969b01cd Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Mon, 30 Jun 2008 17:37:08 -0300 Subject: x86: use long instead of int. Do not refer to the processor word-size with int, as it won't work with x86_64. Use long instead. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 8d3f02d..eed8d94 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -62,7 +62,7 @@ extern struct movsl_mask { __chk_user_ptr(addr); \ asm("add %3,%1 ; sbb %0,%0; cmp %1,%4; sbb $0,%0" \ :"=&r" (flag), "=r" (roksum) \ - :"1" (addr), "g" ((int)(size)), \ + :"1" (addr), "g" ((long)(size)), \ "rm" (current_thread_info()->addr_limit.seg)); \ flag; \ }) -- cgit v0.10.2 From be9d06bfd48934fbd56ccb7476eabccfa31b4afe Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 13 Jun 2008 21:01:46 -0300 Subject: x86: use something common for both architectures. Using explicit hexa (0xFFFFFFUL) introduces an unnecessary difference between i386 and x86_64 because of the size of their long. Use -1UL instead. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index eed8d94..2676b48 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -25,7 +25,7 @@ #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFUL) +#define KERNEL_DS MAKE_MM_SEG(-1UL) #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) #define get_ds() (KERNEL_DS) diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 0077dbe..3a81775 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -22,7 +22,7 @@ #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFFUL) +#define KERNEL_DS MAKE_MM_SEG(-1UL) #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) #define get_ds() (KERNEL_DS) -- cgit v0.10.2 From ca23386216b9d4fc3bb211101205077d2b2916ae Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 13 Jun 2008 14:39:25 -0300 Subject: x86: merge common parts of uaccess. Common parts of uaccess_32.h and uaccess_64.h are put in uaccess.h. Bits in uaccess_32.h and uaccess_64.h that come to this file are equal except for comments and whitespaces differences. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 9fefd29..2fc30c2 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -1,5 +1,129 @@ +#ifndef _ASM_UACCES_H_ +#define _ASM_UACCES_H_ +/* + * User space memory access functions + */ +#include +#include +#include +#include +#include +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + +#define KERNEL_DS MAKE_MM_SEG(-1UL) +#define USER_DS MAKE_MM_SEG(PAGE_OFFSET) + +#define get_ds() (KERNEL_DS) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) + +#define segment_eq(a, b) ((a).seg == (b).seg) + +/* + * Test whether a block of memory is a valid user space address. + * Returns 0 if the range is valid, nonzero otherwise. + * + * This is equivalent to the following test: + * (u33)addr + (u33)size >= (u33)current->addr_limit.seg (u65 for x86_64) + * + * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry... + */ + +#define __range_not_ok(addr, size) \ +({ \ + unsigned long flag, roksum; \ + __chk_user_ptr(addr); \ + asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ + : "=&r" (flag), "=r" (roksum) \ + : "1" (addr), "g" ((long)(size)), \ + "rm" (current_thread_info()->addr_limit.seg)); \ + flag; \ +}) + +/** + * access_ok: - Checks if a user space pointer is valid + * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that + * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe + * to write to a block, it is always safe to read from it. + * @addr: User space pointer to start of block to check + * @size: Size of block to check + * + * Context: User context only. This function may sleep. + * + * Checks if a pointer to a block of memory in user space is valid. + * + * Returns true (nonzero) if the memory block may be valid, false (zero) + * if it is definitely invalid. + * + * Note that, depending on architecture, this function probably just + * checks that the pointer is in the user space range - after calling + * this function, memory access functions may still return -EFAULT. + */ +#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry { + unsigned long insn, fixup; +}; + +extern int fixup_exception(struct pt_regs *regs); + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + * + * This gets kind of ugly. We want to return _two_ values in "get_user()" + * and yet we don't want to do any pointers, because that is too much + * of a performance impact. Thus we have a few rather ugly macros here, + * and hide all the ugliness from the user. + * + * The "__xxx" versions of the user access functions are versions that + * do not verify the address space, that must have been done previously + * with a separate "access_ok()" call (this is used when we do multiple + * accesses to the same area of user memory). + */ + +extern int __get_user_1(void); +extern int __get_user_2(void); +extern int __get_user_4(void); +extern int __get_user_8(void); +extern int __get_user_bad(void); + +#define __get_user_x(size, ret, x, ptr) \ + asm volatile("call __get_user_" #size \ + : "=a" (ret),"=d" (x) \ + : "0" (ptr)) \ + #ifdef CONFIG_X86_32 # include "uaccess_32.h" #else # include "uaccess_64.h" #endif + +#endif diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 2676b48..92ad19e 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -11,29 +11,6 @@ #include #include -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons, these macros are grossly misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - - -#define KERNEL_DS MAKE_MM_SEG(-1UL) -#define USER_DS MAKE_MM_SEG(PAGE_OFFSET) - -#define get_ds() (KERNEL_DS) -#define get_fs() (current_thread_info()->addr_limit) -#define set_fs(x) (current_thread_info()->addr_limit = (x)) - -#define segment_eq(a, b) ((a).seg == (b).seg) - /* * movsl can be slow when source and dest are not both 8-byte aligned */ @@ -47,91 +24,6 @@ extern struct movsl_mask { ((unsigned long __force)(addr) < \ (current_thread_info()->addr_limit.seg)) -/* - * Test whether a block of memory is a valid user space address. - * Returns 0 if the range is valid, nonzero otherwise. - * - * This is equivalent to the following test: - * (u33)addr + (u33)size >= (u33)current->addr_limit.seg - * - * This needs 33-bit arithmetic. We have a carry... - */ -#define __range_not_ok(addr, size) \ -({ \ - unsigned long flag, roksum; \ - __chk_user_ptr(addr); \ - asm("add %3,%1 ; sbb %0,%0; cmp %1,%4; sbb $0,%0" \ - :"=&r" (flag), "=r" (roksum) \ - :"1" (addr), "g" ((long)(size)), \ - "rm" (current_thread_info()->addr_limit.seg)); \ - flag; \ -}) - -/** - * access_ok: - Checks if a user space pointer is valid - * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that - * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe - * to write to a block, it is always safe to read from it. - * @addr: User space pointer to start of block to check - * @size: Size of block to check - * - * Context: User context only. This function may sleep. - * - * Checks if a pointer to a block of memory in user space is valid. - * - * Returns true (nonzero) if the memory block may be valid, false (zero) - * if it is definitely invalid. - * - * Note that, depending on architecture, this function probably just - * checks that the pointer is in the user space range - after calling - * this function, memory access functions may still return -EFAULT. - */ -#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); - -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - * - * This gets kind of ugly. We want to return _two_ values in "get_user()" - * and yet we don't want to do any pointers, because that is too much - * of a performance impact. Thus we have a few rather ugly macros here, - * and hide all the ugliness from the user. - * - * The "__xxx" versions of the user access functions are versions that - * do not verify the address space, that must have been done previously - * with a separate "access_ok()" call (this is used when we do multiple - * accesses to the same area of user memory). - */ - -extern void __get_user_1(void); -extern void __get_user_2(void); -extern void __get_user_4(void); - -#define __get_user_x(size, ret, x, ptr) \ - asm volatile("call __get_user_" #size \ - :"=a" (ret),"=d" (x) \ - :"0" (ptr)) - - /* Careful: we have to cast the result to the type of the pointer * for sign reasons */ @@ -386,8 +278,6 @@ struct __large_struct { unsigned long buf[100]; }; __gu_err; \ }) -extern long __get_user_bad(void); - #define __get_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 3a81775..243dbb4 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -9,88 +9,11 @@ #include #include -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons, these macros are grossly misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(-1UL) -#define USER_DS MAKE_MM_SEG(PAGE_OFFSET) - -#define get_ds() (KERNEL_DS) -#define get_fs() (current_thread_info()->addr_limit) -#define set_fs(x) (current_thread_info()->addr_limit = (x)) - -#define segment_eq(a, b) ((a).seg == (b).seg) - #define __addr_ok(addr) (!((unsigned long)(addr) & \ (current_thread_info()->addr_limit.seg))) -/* - * Uhhuh, this needs 65-bit arithmetic. We have a carry.. - */ -#define __range_not_ok(addr, size) \ -({ \ - unsigned long flag, roksum; \ - __chk_user_ptr(addr); \ - asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ - : "=&r" (flag), "=r" (roksum) \ - : "1" (addr), "g" ((long)(size)), \ - "rm" (current_thread_info()->addr_limit.seg)); \ - flag; \ -}) - -#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); - #define ARCH_HAS_SEARCH_EXTABLE -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - * - * This gets kind of ugly. We want to return _two_ values in "get_user()" - * and yet we don't want to do any pointers, because that is too much - * of a performance impact. Thus we have a few rather ugly macros here, - * and hide all the ugliness from the user. - * - * The "__xxx" versions of the user access functions are versions that - * do not verify the address space, that must have been done previously - * with a separate "access_ok()" call (this is used when we do multiple - * accesses to the same area of user memory). - */ - -#define __get_user_x(size, ret, x, ptr) \ - asm volatile("call __get_user_" #size \ - : "=a" (ret),"=d" (x) \ - : "0" (ptr)) \ - /* Careful: we have to cast the result to the type of the pointer * for sign reasons */ @@ -226,12 +149,6 @@ struct __large_struct { unsigned long buf[100]; }; __gu_err; \ }) -extern int __get_user_1(void); -extern int __get_user_2(void); -extern int __get_user_4(void); -extern int __get_user_8(void); -extern int __get_user_bad(void); - #define __get_user_size(x, ptr, size, retval) \ do { \ retval = 0; \ -- cgit v0.10.2 From 865e5b76505cdade261773bde32f785b3ce579f1 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 11:05:11 -0300 Subject: x86: merge getuser. Merge versions of getuser from uaccess_32.h and uaccess_64.h into uaccess.h. There is a part which is 64-bit only (for now), and for that, we use a __get_user_8 macro. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 2fc30c2..8cb580c 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -120,6 +120,61 @@ extern int __get_user_bad(void); : "=a" (ret),"=d" (x) \ : "0" (ptr)) \ +/* Careful: we have to cast the result to the type of the pointer + * for sign reasons */ + +/** + * get_user: - Get a simple variable from user space. + * @x: Variable to store result. + * @ptr: Source address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple variable from user space to kernel + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and the result of + * dereferencing @ptr must be assignable to @x without a cast. + * + * Returns zero on success, or -EFAULT on error. + * On error, the variable @x is set to zero. + */ +#ifdef CONFIG_X86_32 +#define __get_user_8(__ret_gu, __val_gu, ptr) \ + __get_user_x(X, __ret_gu, __val_gu, ptr) +#else +#define __get_user_8(__ret_gu, __val_gu, ptr) \ + __get_user_x(8, __ret_gu, __val_gu, ptr) +#endif + +#define get_user(x, ptr) \ +({ \ + int __ret_gu; \ + unsigned long __val_gu; \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_x(1, __ret_gu, __val_gu, ptr); \ + break; \ + case 2: \ + __get_user_x(2, __ret_gu, __val_gu, ptr); \ + break; \ + case 4: \ + __get_user_x(4, __ret_gu, __val_gu, ptr); \ + break; \ + case 8: \ + __get_user_8(__ret_gu, __val_gu, ptr); \ + break; \ + default: \ + __get_user_x(X, __ret_gu, __val_gu, ptr); \ + break; \ + } \ + (x) = (__typeof__(*(ptr)))__val_gu; \ + __ret_gu; \ +}) + + #ifdef CONFIG_X86_32 # include "uaccess_32.h" #else diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 92ad19e..3cc3236 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -24,49 +24,6 @@ extern struct movsl_mask { ((unsigned long __force)(addr) < \ (current_thread_info()->addr_limit.seg)) -/* Careful: we have to cast the result to the type of the pointer - * for sign reasons */ - -/** - * get_user: - Get a simple variable from user space. - * @x: Variable to store result. - * @ptr: Source address, in user space. - * - * Context: User context only. This function may sleep. - * - * This macro copies a single simple variable from user space to kernel - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and the result of - * dereferencing @ptr must be assignable to @x without a cast. - * - * Returns zero on success, or -EFAULT on error. - * On error, the variable @x is set to zero. - */ -#define get_user(x, ptr) \ -({ \ - int __ret_gu; \ - unsigned long __val_gu; \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_x(1, __ret_gu, __val_gu, ptr); \ - break; \ - case 2: \ - __get_user_x(2, __ret_gu, __val_gu, ptr); \ - break; \ - case 4: \ - __get_user_x(4, __ret_gu, __val_gu, ptr); \ - break; \ - default: \ - __get_user_x(X, __ret_gu, __val_gu, ptr); \ - break; \ - } \ - (x) = (__typeof__(*(ptr)))__val_gu; \ - __ret_gu; \ -}) - extern void __put_user_bad(void); /* diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 243dbb4..4a44b90 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -14,35 +14,6 @@ #define ARCH_HAS_SEARCH_EXTABLE -/* Careful: we have to cast the result to the type of the pointer - * for sign reasons */ - -#define get_user(x, ptr) \ -({ \ - unsigned long __val_gu; \ - int __ret_gu; \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_x(1, __ret_gu, __val_gu, ptr); \ - break; \ - case 2: \ - __get_user_x(2, __ret_gu, __val_gu, ptr); \ - break; \ - case 4: \ - __get_user_x(4, __ret_gu, __val_gu, ptr); \ - break; \ - case 8: \ - __get_user_x(8, __ret_gu, __val_gu, ptr); \ - break; \ - default: \ - __get_user_bad(); \ - break; \ - } \ - (x) = (__force typeof(*(ptr)))__val_gu; \ - __ret_gu; \ -}) - extern void __put_user_1(void); extern void __put_user_2(void); extern void __put_user_4(void); -- cgit v0.10.2 From 002ca1690c3d0a495e6aedd608281aeb01ce6385 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 11:08:51 -0300 Subject: x86: move __addr_ok to uaccess.h. Take it out of uaccess_32.h. Since it seems that no users of the x86_64 exists, we simply pick the i386 version. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 8cb580c..8a1e45f 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -33,6 +33,10 @@ #define segment_eq(a, b) ((a).seg == (b).seg) +#define __addr_ok(addr) \ + ((unsigned long __force)(addr) < \ + (current_thread_info()->addr_limit.seg)) + /* * Test whether a block of memory is a valid user space address. * Returns 0 if the range is valid, nonzero otherwise. diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 3cc3236..87b1aed 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -20,10 +20,6 @@ extern struct movsl_mask { } ____cacheline_aligned_in_smp movsl_mask; #endif -#define __addr_ok(addr) \ - ((unsigned long __force)(addr) < \ - (current_thread_info()->addr_limit.seg)) - extern void __put_user_bad(void); /* diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 4a44b90..8130876 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -9,9 +9,6 @@ #include #include -#define __addr_ok(addr) (!((unsigned long)(addr) & \ - (current_thread_info()->addr_limit.seg))) - #define ARCH_HAS_SEARCH_EXTABLE extern void __put_user_1(void); -- cgit v0.10.2 From 5e322163b19735fbef3e294c297d38e0d2ba8f7e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 11:35:06 -0300 Subject: x86: use k modifier for 4-byte access. Do it in a separate patch for bisectability. Goal is to have put_user_size integrated. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 87b1aed..4c47a5b 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -180,7 +180,7 @@ do { \ __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ break; \ case 4: \ - __put_user_asm(x, ptr, retval, "l", "", "ir", errret); \ + __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\ break; \ case 8: \ __put_user_u64((__typeof__(*ptr))(x), ptr, retval); \ -- cgit v0.10.2 From 293e6a2524ae775fef41d21d17af288d4b2ee91e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 11:40:42 -0300 Subject: x86: mark x86_64 as having a working WP. Select X86_WP_WORKS_OK for x86_64 too. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 3d22bb8..abff1b8 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -344,7 +344,7 @@ config X86_F00F_BUG config X86_WP_WORKS_OK def_bool y - depends on X86_32 && !M386 + depends on !M386 config X86_INVLPG def_bool y -- cgit v0.10.2 From d42e6af613375be7a9a431628ecd742e87230554 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 12:00:44 -0300 Subject: x86: don't always use EFAULT on __put_user_size. Let the user of the macro specify the desired return. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 8130876..6532d63 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -37,7 +37,7 @@ extern void __put_user_bad(void); #define __put_user_nocheck(x, ptr, size) \ ({ \ int __pu_err; \ - __put_user_size((x), (ptr), (size), __pu_err); \ + __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ __pu_err; \ }) @@ -65,22 +65,22 @@ extern void __put_user_bad(void); __pu_err; \ }) -#define __put_user_size(x, ptr, size, retval) \ +#define __put_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ - __put_user_asm(x, ptr, retval, "b", "b", "iq", -EFAULT);\ + __put_user_asm(x, ptr, retval, "b", "b", "iq", errret);\ break; \ case 2: \ - __put_user_asm(x, ptr, retval, "w", "w", "ir", -EFAULT);\ + __put_user_asm(x, ptr, retval, "w", "w", "ir", errret);\ break; \ case 4: \ - __put_user_asm(x, ptr, retval, "l", "k", "ir", -EFAULT);\ + __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\ break; \ case 8: \ - __put_user_asm(x, ptr, retval, "q", "", "Zr", -EFAULT); \ + __put_user_asm(x, ptr, retval, "q", "", "Zr", errret); \ break; \ default: \ __put_user_bad(); \ -- cgit v0.10.2 From dc70ddf4098de043ac52f623c7573a11f2ae3d09 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 11:48:29 -0300 Subject: x86: merge __put_user_asm and its user. Move both __put_user_asm and __put_user_size to uaccess.h. i386 already had a special function for 64-bit access, so for x86_64, we just define a macro with the same name. Note that for X86_64, CONFIG_X86_WP_WORKS_OK will always be defined, so the #else part will never be even compiled in. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 8a1e45f..bcda5d0 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -178,6 +178,90 @@ extern int __get_user_bad(void); __ret_gu; \ }) +#ifdef CONFIG_X86_32 +#define __put_user_u64(x, addr, err) \ + asm volatile("1: movl %%eax,0(%2)\n" \ + "2: movl %%edx,4(%2)\n" \ + "3:\n" \ + ".section .fixup,\"ax\"\n" \ + "4: movl %3,%0\n" \ + " jmp 3b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 4b) \ + _ASM_EXTABLE(2b, 4b) \ + : "=r" (err) \ + : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err)) +#else +#define __put_user_u64(x, ptr, retval) \ + __put_user_asm(x, ptr, retval, "q", "", "Zr", -EFAULT) +#endif + +#ifdef CONFIG_X86_WP_WORKS_OK + +#define __put_user_size(x, ptr, size, retval, errret) \ +do { \ + retval = 0; \ + __chk_user_ptr(ptr); \ + switch (size) { \ + case 1: \ + __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ + break; \ + case 2: \ + __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ + break; \ + case 4: \ + __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\ + break; \ + case 8: \ + __put_user_u64((__typeof__(*ptr))(x), ptr, retval); \ + break; \ + default: \ + __put_user_bad(); \ + } \ +} while (0) + +#else + +#define __put_user_size(x, ptr, size, retval, errret) \ +do { \ + __typeof__(*(ptr))__pus_tmp = x; \ + retval = 0; \ + \ + if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \ + retval = errret; \ +} while (0) + +#endif + +#define __put_user_nocheck(x, ptr, size) \ +({ \ + long __pu_err; \ + __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ + __pu_err; \ +}) + + + +/* FIXME: this hack is definitely wrong -AK */ +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct __user *)(x)) + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ + asm volatile("1: mov"itype" %"rtype"1,%2\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: mov %3,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 3b) \ + : "=r"(err) \ + : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) + #ifdef CONFIG_X86_32 # include "uaccess_32.h" diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 4c47a5b..fab7557 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -145,83 +145,6 @@ extern void __put_user_8(void); #define __put_user(x, ptr) \ __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) -#define __put_user_nocheck(x, ptr, size) \ -({ \ - long __pu_err; \ - __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ - __pu_err; \ -}) - - -#define __put_user_u64(x, addr, err) \ - asm volatile("1: movl %%eax,0(%2)\n" \ - "2: movl %%edx,4(%2)\n" \ - "3:\n" \ - ".section .fixup,\"ax\"\n" \ - "4: movl %3,%0\n" \ - " jmp 3b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 4b) \ - _ASM_EXTABLE(2b, 4b) \ - : "=r" (err) \ - : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err)) - -#ifdef CONFIG_X86_WP_WORKS_OK - -#define __put_user_size(x, ptr, size, retval, errret) \ -do { \ - retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ - break; \ - case 2: \ - __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ - break; \ - case 4: \ - __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\ - break; \ - case 8: \ - __put_user_u64((__typeof__(*ptr))(x), ptr, retval); \ - break; \ - default: \ - __put_user_bad(); \ - } \ -} while (0) - -#else - -#define __put_user_size(x, ptr, size, retval, errret) \ -do { \ - __typeof__(*(ptr))__pus_tmp = x; \ - retval = 0; \ - \ - if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0)) \ - retval = errret; \ -} while (0) - -#endif -struct __large_struct { unsigned long buf[100]; }; -#define __m(x) (*(struct __large_struct __user *)(x)) - -/* - * Tell gcc we read from memory instead of writing: this is because - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ -#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ - asm volatile("1: mov"itype" %"rtype"1,%2\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl %3,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : "=r"(err) \ - : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err)) - - #define __get_user_nocheck(x, ptr, size) \ ({ \ long __gu_err; \ diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 6532d63..42c01aa 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -34,14 +34,6 @@ extern void __put_user_bad(void); #define __get_user_unaligned __get_user #define __put_user_unaligned __put_user -#define __put_user_nocheck(x, ptr, size) \ -({ \ - int __pu_err; \ - __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ - __pu_err; \ -}) - - #define __put_user_check(x, ptr, size) \ ({ \ int __pu_err; \ @@ -65,49 +57,6 @@ extern void __put_user_bad(void); __pu_err; \ }) -#define __put_user_size(x, ptr, size, retval, errret) \ -do { \ - retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __put_user_asm(x, ptr, retval, "b", "b", "iq", errret);\ - break; \ - case 2: \ - __put_user_asm(x, ptr, retval, "w", "w", "ir", errret);\ - break; \ - case 4: \ - __put_user_asm(x, ptr, retval, "l", "k", "ir", errret);\ - break; \ - case 8: \ - __put_user_asm(x, ptr, retval, "q", "", "Zr", errret); \ - break; \ - default: \ - __put_user_bad(); \ - } \ -} while (0) - -/* FIXME: this hack is definitely wrong -AK */ -struct __large_struct { unsigned long buf[100]; }; -#define __m(x) (*(struct __large_struct __user *)(x)) - -/* - * Tell gcc we read from memory instead of writing: this is because - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ -#define __put_user_asm(x, addr, err, itype, rtype, ltype, errno) \ - asm volatile("1: mov"itype" %"rtype"1,%2\n" \ - "2:\n" \ - ".section .fixup, \"ax\"\n" \ - "3: mov %3,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : "=r"(err) \ - : ltype (x), "m" (__m(addr)), "i" (errno), "0" (err)) - - #define __get_user_nocheck(x, ptr, size) \ ({ \ int __gu_err; \ -- cgit v0.10.2 From 6fd4725d75c5049641640ce23fa5896501dfbd42 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 11:57:33 -0300 Subject: x86: don't always use EFAULT on __get_user_size. Let the user of the macro specify the desired return. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 42c01aa..e0875d7 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -61,27 +61,27 @@ extern void __put_user_bad(void); ({ \ int __gu_err; \ unsigned long __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err); \ + __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);\ (x) = (__force typeof(*(ptr)))__gu_val; \ __gu_err; \ }) -#define __get_user_size(x, ptr, size, retval) \ +#define __get_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ - __get_user_asm(x, ptr, retval, "b", "b", "=q", -EFAULT);\ + __get_user_asm(x, ptr, retval, "b", "b", "=q", errret);\ break; \ case 2: \ - __get_user_asm(x, ptr, retval, "w", "w", "=r", -EFAULT);\ + __get_user_asm(x, ptr, retval, "w", "w", "=r", errret);\ break; \ case 4: \ - __get_user_asm(x, ptr, retval, "l", "k", "=r", -EFAULT);\ + __get_user_asm(x, ptr, retval, "l", "k", "=r", errret);\ break; \ case 8: \ - __get_user_asm(x, ptr, retval, "q", "", "=r", -EFAULT); \ + __get_user_asm(x, ptr, retval, "q", "", "=r", errret); \ break; \ default: \ (x) = __get_user_bad(); \ -- cgit v0.10.2 From 3f168221167ca7a844fde3bf58e1c7ca0bf9741e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 12:48:47 -0300 Subject: x86: merge __get_user_asm and its users. Move __get_user_asm and __get_user_size and __get_user_nocheck to uaccess.h. This requires us to define a macro at __get_user_size for the 64-bit access case. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index bcda5d0..4353b22 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -233,6 +233,47 @@ do { \ #endif +#ifdef CONFIG_X86_32 +#define __get_user_asm_u64(x, ptr, retval, errret) (x) = __get_user_bad() +#else +#define __get_user_asm_u64(x, ptr, retval, errret) \ + __get_user_asm(x, ptr, retval, "q", "", "=r", errret) +#endif + +#define __get_user_size(x, ptr, size, retval, errret) \ +do { \ + retval = 0; \ + __chk_user_ptr(ptr); \ + switch (size) { \ + case 1: \ + __get_user_asm(x, ptr, retval, "b", "b", "=q", errret); \ + break; \ + case 2: \ + __get_user_asm(x, ptr, retval, "w", "w", "=r", errret); \ + break; \ + case 4: \ + __get_user_asm(x, ptr, retval, "l", "k", "=r", errret); \ + break; \ + case 8: \ + __get_user_asm_u64(x, ptr, retval, errret); \ + break; \ + default: \ + (x) = __get_user_bad(); \ + } \ +} while (0) + +#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ + asm volatile("1: mov"itype" %2,%"rtype"1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: mov %3,%0\n" \ + " xor"itype" %"rtype"1,%"rtype"1\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 3b) \ + : "=r" (err), ltype(x) \ + : "m" (__m(addr)), "i" (errret), "0" (err)) + #define __put_user_nocheck(x, ptr, size) \ ({ \ long __pu_err; \ @@ -240,7 +281,14 @@ do { \ __pu_err; \ }) - +#define __get_user_nocheck(x, ptr, size) \ +({ \ + long __gu_err; \ + unsigned long __gu_val; \ + __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \ + (x) = (__force __typeof__(*(ptr)))__gu_val; \ + __gu_err; \ +}) /* FIXME: this hack is definitely wrong -AK */ struct __large_struct { unsigned long buf[100]; }; diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index fab7557..ebfe6b2 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -145,47 +145,6 @@ extern void __put_user_8(void); #define __put_user(x, ptr) \ __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) -#define __get_user_nocheck(x, ptr, size) \ -({ \ - long __gu_err; \ - unsigned long __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_size(x, ptr, size, retval, errret) \ -do { \ - retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __get_user_asm(x, ptr, retval, "b", "b", "=q", errret); \ - break; \ - case 2: \ - __get_user_asm(x, ptr, retval, "w", "w", "=r", errret); \ - break; \ - case 4: \ - __get_user_asm(x, ptr, retval, "l", "", "=r", errret); \ - break; \ - default: \ - (x) = __get_user_bad(); \ - } \ -} while (0) - -#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ - asm volatile("1: mov"itype" %2,%"rtype"1\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl %3,%0\n" \ - " xor"itype" %"rtype"1,%"rtype"1\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : "=r" (err), ltype (x) \ - : "m" (__m(addr)), "i" (errret), "0" (err)) - - unsigned long __must_check __copy_to_user_ll (void __user *to, const void *from, unsigned long n); unsigned long __must_check __copy_from_user_ll diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index e0875d7..42a9769 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -57,49 +57,6 @@ extern void __put_user_bad(void); __pu_err; \ }) -#define __get_user_nocheck(x, ptr, size) \ -({ \ - int __gu_err; \ - unsigned long __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);\ - (x) = (__force typeof(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_size(x, ptr, size, retval, errret) \ -do { \ - retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ - __get_user_asm(x, ptr, retval, "b", "b", "=q", errret);\ - break; \ - case 2: \ - __get_user_asm(x, ptr, retval, "w", "w", "=r", errret);\ - break; \ - case 4: \ - __get_user_asm(x, ptr, retval, "l", "k", "=r", errret);\ - break; \ - case 8: \ - __get_user_asm(x, ptr, retval, "q", "", "=r", errret); \ - break; \ - default: \ - (x) = __get_user_bad(); \ - } \ -} while (0) - -#define __get_user_asm(x, addr, err, itype, rtype, ltype, errno) \ - asm volatile("1: mov"itype" %2,%"rtype"1\n" \ - "2:\n" \ - ".section .fixup, \"ax\"\n" \ - "3: mov %3,%0\n" \ - " xor"itype" %"rtype"1,%"rtype"1\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : "=r" (err), ltype (x) \ - : "m" (__m(addr)), "i"(errno), "0"(err)) - /* * Copy To/From Userspace */ -- cgit v0.10.2 From 64a978c1e3b2c0e2b663caf54719319919c5c17f Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 12:59:37 -0300 Subject: x86: be more explicit in __put_user_x. For both __put_user_x and __put_user_8 macros, pass the error variable explicitly. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index ebfe6b2..2c90673 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -31,11 +31,11 @@ extern void __put_user_2(void); extern void __put_user_4(void); extern void __put_user_8(void); -#define __put_user_x(size, x, ptr) \ +#define __put_user_x(size, x, ptr, __ret_pu) \ asm volatile("call __put_user_" #size : "=a" (__ret_pu) \ :"0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") -#define __put_user_8(x, ptr) \ +#define __put_user_8(x, ptr, __ret_pu) \ asm volatile("call __put_user_8" : "=a" (__ret_pu) \ : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") @@ -66,19 +66,19 @@ extern void __put_user_8(void); __pu_val = x; \ switch (sizeof(*(ptr))) { \ case 1: \ - __put_user_x(1, __pu_val, ptr); \ + __put_user_x(1, __pu_val, ptr, __ret_pu); \ break; \ case 2: \ - __put_user_x(2, __pu_val, ptr); \ + __put_user_x(2, __pu_val, ptr, __ret_pu); \ break; \ case 4: \ - __put_user_x(4, __pu_val, ptr); \ + __put_user_x(4, __pu_val, ptr, __ret_pu); \ break; \ case 8: \ - __put_user_8(__pu_val, ptr); \ + __put_user_8(__pu_val, ptr, __ret_pu); \ break; \ default: \ - __put_user_x(X, __pu_val, ptr); \ + __put_user_x(X, __pu_val, ptr, __ret_pu); \ break; \ } \ __ret_pu; \ -- cgit v0.10.2 From ec840956d269e2beefe3a1c0fd7c1c70a199087f Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 13:00:48 -0300 Subject: x86: turn __put_user_check directly into put_user. We also check user pointer in x86_64 put_user, the way i386 does. In a separate patch for bisecting purposes. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 42a9769..9139854 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -23,9 +23,6 @@ extern void __put_user_bad(void); :"c" (ptr),"a" (x) \ :"ebx") -#define put_user(x, ptr) \ - __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) - #define __get_user(x, ptr) \ __get_user_nocheck((x), (ptr), sizeof(*(ptr))) #define __put_user(x, ptr) \ @@ -34,11 +31,12 @@ extern void __put_user_bad(void); #define __get_user_unaligned __get_user #define __put_user_unaligned __put_user -#define __put_user_check(x, ptr, size) \ +#define put_user(x, ptr) \ ({ \ int __pu_err; \ typeof(*(ptr)) __user *__pu_addr = (ptr); \ - switch (size) { \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ case 1: \ __put_user_x(1, __pu_err, x, __pu_addr); \ break; \ -- cgit v0.10.2 From e30a44fdbf11c7ca3a0096d71790f176a4a09e03 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 13:17:43 -0300 Subject: x86: merge put_user. Move both versions, which are highly similar, to uaccess.h. Note that, for x86_64, X86_WP_WORKS_OK is always defined. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 4353b22..3a9092a 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -178,6 +178,12 @@ extern int __get_user_bad(void); __ret_gu; \ }) +#define __put_user_x(size, x, ptr, __ret_pu) \ + asm volatile("call __put_user_" #size : "=a" (__ret_pu) \ + :"0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") + + + #ifdef CONFIG_X86_32 #define __put_user_u64(x, addr, err) \ asm volatile("1: movl %%eax,0(%2)\n" \ @@ -191,13 +197,71 @@ extern int __get_user_bad(void); _ASM_EXTABLE(2b, 4b) \ : "=r" (err) \ : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err)) + +#define __put_user_x8(x, ptr, __ret_pu) \ + asm volatile("call __put_user_8" : "=a" (__ret_pu) \ + : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #else #define __put_user_u64(x, ptr, retval) \ __put_user_asm(x, ptr, retval, "q", "", "Zr", -EFAULT) +#define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) #endif +extern void __put_user_bad(void); + +/* + * Strange magic calling convention: pointer in %ecx, + * value in %eax(:%edx), return value in %eax. clobbers %rbx + */ +extern void __put_user_1(void); +extern void __put_user_2(void); +extern void __put_user_4(void); +extern void __put_user_8(void); + #ifdef CONFIG_X86_WP_WORKS_OK +/** + * put_user: - Write a simple value into user space. + * @x: Value to copy to user space. + * @ptr: Destination address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple value from kernel space to user + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and @x must be assignable + * to the result of dereferencing @ptr. + * + * Returns zero on success, or -EFAULT on error. + */ +#define put_user(x, ptr) \ +({ \ + int __ret_pu; \ + __typeof__(*(ptr)) __pu_val; \ + __chk_user_ptr(ptr); \ + __pu_val = x; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __put_user_x(1, __pu_val, ptr, __ret_pu); \ + break; \ + case 2: \ + __put_user_x(2, __pu_val, ptr, __ret_pu); \ + break; \ + case 4: \ + __put_user_x(4, __pu_val, ptr, __ret_pu); \ + break; \ + case 8: \ + __put_user_x8(__pu_val, ptr, __ret_pu); \ + break; \ + default: \ + __put_user_x(X, __pu_val, ptr, __ret_pu); \ + break; \ + } \ + __ret_pu; \ +}) + #define __put_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ @@ -231,6 +295,16 @@ do { \ retval = errret; \ } while (0) +#define put_user(x, ptr) \ +({ \ + int __ret_pu; \ + __typeof__(*(ptr))__pus_tmp = x; \ + __ret_pu = 0; \ + if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, \ + sizeof(*(ptr))) != 0)) \ + __ret_pu = -EFAULT; \ + __ret_pu; \ +}) #endif #ifdef CONFIG_X86_32 diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 2c90673..e5c0437 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -20,85 +20,6 @@ extern struct movsl_mask { } ____cacheline_aligned_in_smp movsl_mask; #endif -extern void __put_user_bad(void); - -/* - * Strange magic calling convention: pointer in %ecx, - * value in %eax(:%edx), return value in %eax, no clobbers. - */ -extern void __put_user_1(void); -extern void __put_user_2(void); -extern void __put_user_4(void); -extern void __put_user_8(void); - -#define __put_user_x(size, x, ptr, __ret_pu) \ - asm volatile("call __put_user_" #size : "=a" (__ret_pu) \ - :"0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") - -#define __put_user_8(x, ptr, __ret_pu) \ - asm volatile("call __put_user_8" : "=a" (__ret_pu) \ - : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") - - -/** - * put_user: - Write a simple value into user space. - * @x: Value to copy to user space. - * @ptr: Destination address, in user space. - * - * Context: User context only. This function may sleep. - * - * This macro copies a single simple value from kernel space to user - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and @x must be assignable - * to the result of dereferencing @ptr. - * - * Returns zero on success, or -EFAULT on error. - */ -#ifdef CONFIG_X86_WP_WORKS_OK - -#define put_user(x, ptr) \ -({ \ - int __ret_pu; \ - __typeof__(*(ptr)) __pu_val; \ - __chk_user_ptr(ptr); \ - __pu_val = x; \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __put_user_x(1, __pu_val, ptr, __ret_pu); \ - break; \ - case 2: \ - __put_user_x(2, __pu_val, ptr, __ret_pu); \ - break; \ - case 4: \ - __put_user_x(4, __pu_val, ptr, __ret_pu); \ - break; \ - case 8: \ - __put_user_8(__pu_val, ptr, __ret_pu); \ - break; \ - default: \ - __put_user_x(X, __pu_val, ptr, __ret_pu); \ - break; \ - } \ - __ret_pu; \ -}) - -#else -#define put_user(x, ptr) \ -({ \ - int __ret_pu; \ - __typeof__(*(ptr))__pus_tmp = x; \ - __ret_pu = 0; \ - if (unlikely(__copy_to_user_ll(ptr, &__pus_tmp, \ - sizeof(*(ptr))) != 0)) \ - __ret_pu = -EFAULT; \ - __ret_pu; \ -}) - - -#endif - /** * __get_user: - Get a simple variable from user space, with less checking. * @x: Variable to store result. diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 9139854..2e75a5d 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -11,18 +11,6 @@ #define ARCH_HAS_SEARCH_EXTABLE -extern void __put_user_1(void); -extern void __put_user_2(void); -extern void __put_user_4(void); -extern void __put_user_8(void); -extern void __put_user_bad(void); - -#define __put_user_x(size, ret, x, ptr) \ - asm volatile("call __put_user_" #size \ - :"=a" (ret) \ - :"c" (ptr),"a" (x) \ - :"ebx") - #define __get_user(x, ptr) \ __get_user_nocheck((x), (ptr), sizeof(*(ptr))) #define __put_user(x, ptr) \ @@ -31,30 +19,6 @@ extern void __put_user_bad(void); #define __get_user_unaligned __get_user #define __put_user_unaligned __put_user -#define put_user(x, ptr) \ -({ \ - int __pu_err; \ - typeof(*(ptr)) __user *__pu_addr = (ptr); \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __put_user_x(1, __pu_err, x, __pu_addr); \ - break; \ - case 2: \ - __put_user_x(2, __pu_err, x, __pu_addr); \ - break; \ - case 4: \ - __put_user_x(4, __pu_err, x, __pu_addr); \ - break; \ - case 8: \ - __put_user_x(8, __pu_err, x, __pu_addr); \ - break; \ - default: \ - __put_user_bad(); \ - } \ - __pu_err; \ -}) - /* * Copy To/From Userspace */ -- cgit v0.10.2 From 8cb834e99f44bd56409b794504ae2b170675fc92 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 14:43:30 -0300 Subject: x86: move __get_user and __put_user into uaccess.h. We also carry the unaligned version with us. Only x86_64 uses it, but there's no problem in defining it. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 3a9092a..7c7b46a 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -383,7 +383,54 @@ struct __large_struct { unsigned long buf[100]; }; _ASM_EXTABLE(1b, 3b) \ : "=r"(err) \ : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) +/** + * __get_user: - Get a simple variable from user space, with less checking. + * @x: Variable to store result. + * @ptr: Source address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple variable from user space to kernel + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and the result of + * dereferencing @ptr must be assignable to @x without a cast. + * + * Caller must check the pointer with access_ok() before calling this + * function. + * + * Returns zero on success, or -EFAULT on error. + * On error, the variable @x is set to zero. + */ + +#define __get_user(x, ptr) \ + __get_user_nocheck((x), (ptr), sizeof(*(ptr))) +/** + * __put_user: - Write a simple value into user space, with less checking. + * @x: Value to copy to user space. + * @ptr: Destination address, in user space. + * + * Context: User context only. This function may sleep. + * + * This macro copies a single simple value from kernel space to user + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and @x must be assignable + * to the result of dereferencing @ptr. + * + * Caller must check the pointer with access_ok() before calling this + * function. + * + * Returns zero on success, or -EFAULT on error. + */ + +#define __put_user(x, ptr) \ + __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) +#define __get_user_unaligned __get_user +#define __put_user_unaligned __put_user #ifdef CONFIG_X86_32 # include "uaccess_32.h" diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index e5c0437..d3b5bf8 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -20,52 +20,6 @@ extern struct movsl_mask { } ____cacheline_aligned_in_smp movsl_mask; #endif -/** - * __get_user: - Get a simple variable from user space, with less checking. - * @x: Variable to store result. - * @ptr: Source address, in user space. - * - * Context: User context only. This function may sleep. - * - * This macro copies a single simple variable from user space to kernel - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and the result of - * dereferencing @ptr must be assignable to @x without a cast. - * - * Caller must check the pointer with access_ok() before calling this - * function. - * - * Returns zero on success, or -EFAULT on error. - * On error, the variable @x is set to zero. - */ -#define __get_user(x, ptr) \ - __get_user_nocheck((x), (ptr), sizeof(*(ptr))) - - -/** - * __put_user: - Write a simple value into user space, with less checking. - * @x: Value to copy to user space. - * @ptr: Destination address, in user space. - * - * Context: User context only. This function may sleep. - * - * This macro copies a single simple value from kernel space to user - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and @x must be assignable - * to the result of dereferencing @ptr. - * - * Caller must check the pointer with access_ok() before calling this - * function. - * - * Returns zero on success, or -EFAULT on error. - */ -#define __put_user(x, ptr) \ - __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) - unsigned long __must_check __copy_to_user_ll (void __user *to, const void *from, unsigned long n); unsigned long __must_check __copy_from_user_ll diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 2e75a5d..b5bacd6 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -11,14 +11,6 @@ #define ARCH_HAS_SEARCH_EXTABLE -#define __get_user(x, ptr) \ - __get_user_nocheck((x), (ptr), sizeof(*(ptr))) -#define __put_user(x, ptr) \ - __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) - -#define __get_user_unaligned __get_user -#define __put_user_unaligned __put_user - /* * Copy To/From Userspace */ -- cgit v0.10.2 From 8bc7de0c5dc0a5d3bcdc04bac6de0c799f91c5e4 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 14:53:41 -0300 Subject: x86: put movsl_mask into uaccess.h. x86_64 does not need it, but it won't have X86_INTEL_USERCOPY defined either. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 7c7b46a..0c4ab78 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -432,6 +432,15 @@ struct __large_struct { unsigned long buf[100]; }; #define __get_user_unaligned __get_user #define __put_user_unaligned __put_user +/* + * movsl can be slow when source and dest are not both 8-byte aligned + */ +#ifdef CONFIG_X86_INTEL_USERCOPY +extern struct movsl_mask { + int mask; +} ____cacheline_aligned_in_smp movsl_mask; +#endif + #ifdef CONFIG_X86_32 # include "uaccess_32.h" #else diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index d3b5bf8..3467749 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -11,15 +11,6 @@ #include #include -/* - * movsl can be slow when source and dest are not both 8-byte aligned - */ -#ifdef CONFIG_X86_INTEL_USERCOPY -extern struct movsl_mask { - int mask; -} ____cacheline_aligned_in_smp movsl_mask; -#endif - unsigned long __must_check __copy_to_user_ll (void __user *to, const void *from, unsigned long n); unsigned long __must_check __copy_from_user_ll -- cgit v0.10.2 From 22cac1670786108ccd4caa0656c39fa4ba69fa7d Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Wed, 25 Jun 2008 14:56:53 -0300 Subject: x86: define architectural characteristics in uaccess.h. Remove them from the arch-specific file. Signed-off-by: Glauber Costa Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 0c4ab78..f6fa4d8 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -441,9 +441,12 @@ extern struct movsl_mask { } ____cacheline_aligned_in_smp movsl_mask; #endif +#define ARCH_HAS_NOCACHE_UACCESS 1 + #ifdef CONFIG_X86_32 # include "uaccess_32.h" #else +# define ARCH_HAS_SEARCH_EXTABLE # include "uaccess_64.h" #endif diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 3467749..6fdef39 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -156,8 +156,6 @@ __copy_from_user(void *to, const void __user *from, unsigned long n) return __copy_from_user_ll(to, from, n); } -#define ARCH_HAS_NOCACHE_UACCESS - static __always_inline unsigned long __copy_from_user_nocache(void *to, const void __user *from, unsigned long n) { diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index b5bacd6..4e3ec00 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -9,8 +9,6 @@ #include #include -#define ARCH_HAS_SEARCH_EXTABLE - /* * Copy To/From Userspace */ @@ -180,7 +178,6 @@ __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size) return copy_user_generic((__force void *)dst, src, size); } -#define ARCH_HAS_NOCACHE_UACCESS 1 extern long __copy_user_nocache(void *dst, const void __user *src, unsigned size, int zerorest); -- cgit v0.10.2 From b50efd2a55fc1344654875369d458bb6838bd37a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 8 Jul 2008 01:41:05 -0700 Subject: x86: introduce page_size_mask for 64bit prepare for overmapped patch also printout last_map_addr together with end Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 57d5eff..7227a0a 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -340,7 +340,8 @@ phys_pte_update(pmd_t *pmd, unsigned long address, unsigned long end) } static unsigned long __meminit -phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) +phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, + unsigned long page_size_mask) { unsigned long pages = 0; @@ -365,7 +366,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) continue; } - if (cpu_has_pse) { + if (page_size_mask & (1<> PAGE_SHIFT, PAGE_KERNEL_LARGE)); @@ -383,20 +384,22 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) } static unsigned long __meminit -phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) +phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end, + unsigned long page_size_mask) { pmd_t *pmd = pmd_offset(pud, 0); unsigned long last_map_addr; spin_lock(&init_mm.page_table_lock); - last_map_addr = phys_pmd_init(pmd, address, end); + last_map_addr = phys_pmd_init(pmd, address, end, page_size_mask); spin_unlock(&init_mm.page_table_lock); __flush_tlb_all(); return last_map_addr; } static unsigned long __meminit -phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) +phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, + unsigned long page_size_mask) { unsigned long pages = 0; unsigned long last_map_addr = end; @@ -418,11 +421,12 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) if (pud_val(*pud)) { if (!pud_large(*pud)) - last_map_addr = phys_pmd_update(pud, addr, end); + last_map_addr = phys_pmd_update(pud, addr, end, + page_size_mask); continue; } - if (direct_gbpages) { + if (page_size_mask & (1<> PAGE_SHIFT, PAGE_KERNEL_LARGE)); @@ -433,7 +437,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) pmd = alloc_low_page(&pmd_phys); spin_lock(&init_mm.page_table_lock); - last_map_addr = phys_pmd_init(pmd, addr, end); + last_map_addr = phys_pmd_init(pmd, addr, end, page_size_mask); unmap_low_page(pmd); pud_populate(&init_mm, pud, __va(pmd_phys)); spin_unlock(&init_mm.page_table_lock); @@ -446,13 +450,14 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) } static unsigned long __meminit -phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end) +phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end, + unsigned long page_size_mask) { pud_t *pud; pud = (pud_t *)pgd_page_vaddr(*pgd); - return phys_pud_init(pud, addr, end); + return phys_pud_init(pud, addr, end, page_size_mask); } static void __init find_early_table_space(unsigned long end) @@ -608,29 +613,12 @@ static void __init early_memtest(unsigned long start, unsigned long end) } #endif -/* - * Setup the direct mapping of the physical memory at PAGE_OFFSET. - * This runs before bootmem is initialized and gets pages directly from - * the physical memory. To access them they are temporarily mapped. - */ -unsigned long __init_refok init_memory_mapping(unsigned long start, unsigned long end) +static unsigned long __init kernel_physical_mapping_init(unsigned long start, + unsigned long end, + unsigned long page_size_mask) { - unsigned long next, last_map_addr = end; - unsigned long start_phys = start, end_phys = end; - printk(KERN_INFO "init_memory_mapping\n"); - - /* - * Find space for the kernel direct mapping tables. - * - * Later we should allocate these tables in the local node of the - * memory mapped. Unfortunately this is done currently before the - * nodes are discovered. - */ - if (!after_bootmem) { - init_gbpages(); - find_early_table_space(end); - } + unsigned long next, last_map_addr = end; start = (unsigned long)__va(start); end = (unsigned long)__va(end); @@ -645,7 +633,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, unsigned lon next = end; if (pgd_val(*pgd)) { - last_map_addr = phys_pud_update(pgd, __pa(start), __pa(end)); + last_map_addr = phys_pud_update(pgd, __pa(start), + __pa(end), page_size_mask); continue; } @@ -654,22 +643,61 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, unsigned lon else pud = alloc_low_page(&pud_phys); - last_map_addr = phys_pud_init(pud, __pa(start), __pa(next)); + last_map_addr = phys_pud_init(pud, __pa(start), __pa(next), + page_size_mask); unmap_low_page(pud); pgd_populate(&init_mm, pgd_offset_k(start), __va(pud_phys)); } + return last_map_addr; +} +/* + * Setup the direct mapping of the physical memory at PAGE_OFFSET. + * This runs before bootmem is initialized and gets pages directly from + * the physical memory. To access them they are temporarily mapped. + */ +unsigned long __init_refok init_memory_mapping(unsigned long start, + unsigned long end) +{ + unsigned long last_map_addr; + unsigned long page_size_mask = 0; + + printk(KERN_INFO "init_memory_mapping\n"); + + /* + * Find space for the kernel direct mapping tables. + * + * Later we should allocate these tables in the local node of the + * memory mapped. Unfortunately this is done currently before the + * nodes are discovered. + */ + if (!after_bootmem) { + init_gbpages(); + find_early_table_space(end); + } + + if (direct_gbpages) + page_size_mask |= 1 << PG_LEVEL_1G; + if (cpu_has_pse) + page_size_mask |= 1 << PG_LEVEL_2M; + + last_map_addr = kernel_physical_mapping_init(start, end, + page_size_mask); + if (!after_bootmem) mmu_cr4_features = read_cr4(); __flush_tlb_all(); - if (!after_bootmem) + if (!after_bootmem && table_end > table_start) reserve_early(table_start << PAGE_SHIFT, table_end << PAGE_SHIFT, "PGTABLE"); + printk(KERN_INFO "last_map_addr: %lx end: %lx\n", + last_map_addr, end); + if (!after_bootmem) - early_memtest(start_phys, end_phys); + early_memtest(start, end); return last_map_addr >> PAGE_SHIFT; } -- cgit v0.10.2 From 49c980df552499e5e8595b52448f612fdab0484a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 3 Jul 2008 12:29:34 -0700 Subject: x86: fix vmemmap printout check Signed-off-by: Yinghai Lu Cc: "Nick Piggin" Cc: "Mark McLoughlin" Cc: xen-devel Cc: "Eduardo Habkost" Cc: "Vegard Nossum" Cc: "Stephen Tweedie" Cc: "Jeremy Fitzhardinge" Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 7227a0a..f7d8031 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -1104,9 +1104,6 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node) PAGE_KERNEL_LARGE); set_pmd(pmd, __pmd(pte_val(entry))); - addr_end = addr + PMD_SIZE; - p_end = p + PMD_SIZE; - /* check to see if we have contiguous blocks */ if (p_end != p || node_start != node) { if (p_start) @@ -1116,6 +1113,9 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node) node_start = node; p_start = p; } + + addr_end = addr + PMD_SIZE; + p_end = p + PMD_SIZE; } else vmemmap_verify((pte_t *)pmd, node, addr, next); } -- cgit v0.10.2 From 2dc807b37b7b8c7df445513ad2b415df4ebcaf6d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 8 Jul 2008 18:56:38 -0700 Subject: x86: make max_pfn cover acpi table below 4g When system have 4g less ram installed, and acpi table sit near end of ram, make max_pfn cover them too, so 64bit kernel don't need to mess up fixmap. Signed-off-by: Yinghai Lu Cc: "Suresh Siddha" Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index e07d401..2e08619 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1056,12 +1056,20 @@ unsigned long __initdata end_user_pfn = MAX_ARCH_PFN; /* * Find the highest page frame number we have available */ -unsigned long __init e820_end_of_ram(void) +unsigned long __init e820_end(void) { - unsigned long last_pfn; + int i; + unsigned long last_pfn = 0; unsigned long max_arch_pfn = MAX_ARCH_PFN; - last_pfn = find_max_pfn_with_active_regions(); + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + unsigned long end_pfn; + + end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; + if (end_pfn > last_pfn) + last_pfn = end_pfn; + } if (last_pfn > max_arch_pfn) last_pfn = max_arch_pfn; @@ -1192,9 +1200,7 @@ static int __init parse_memmap_opt(char *p) * the real mem size before original memory map is * reset. */ - e820_register_active_regions(0, 0, -1UL); - saved_max_pfn = e820_end_of_ram(); - remove_all_active_ranges(); + saved_max_pfn = e820_end(); #endif e820.nr_map = 0; userdef = 1; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index bea8ae7..a7c3471 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -709,22 +709,18 @@ void __init setup_arch(char **cmdline_p) early_gart_iommu_check(); #endif - e820_register_active_regions(0, 0, -1UL); /* * partially used pages are not usable - thus * we are rounding upwards: */ - max_pfn = e820_end_of_ram(); + max_pfn = e820_end(); /* preallocate 4k for mptable mpc */ early_reserve_e820_mpc_new(); /* update e820 for memory not covered by WB MTRRs */ mtrr_bp_init(); - if (mtrr_trim_uncached_memory(max_pfn)) { - remove_all_active_ranges(); - e820_register_active_regions(0, 0, -1UL); - max_pfn = e820_end_of_ram(); - } + if (mtrr_trim_uncached_memory(max_pfn)) + max_pfn = e820_end(); #ifdef CONFIG_X86_32 /* max_low_pfn get updated here */ @@ -767,9 +763,6 @@ void __init setup_arch(char **cmdline_p) */ acpi_boot_table_init(); - /* Remove active ranges so rediscovery with NUMA-awareness happens */ - remove_all_active_ranges(); - #ifdef CONFIG_ACPI_NUMA /* * Parse SRAT to discover nodes. diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index a20d0a7f..78c03d7 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -99,7 +99,7 @@ extern void free_early(u64 start, u64 end); extern void early_res_to_bootmem(u64 start, u64 end); extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); -extern unsigned long e820_end_of_ram(void); +extern unsigned long e820_end(void); extern int e820_find_active_region(const struct e820entry *ei, unsigned long start_pfn, unsigned long last_pfn, -- cgit v0.10.2 From c2e6d65bcea2672788f9bb58ce7606c41388387b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 8 Jul 2008 01:43:27 -0700 Subject: x86: not overmap more than the end of RAM in init_memory_mapping - 64bit handle head and tail that are not aligned to big pages (2MB/1GB boundary). with this patch, on system that support gbpages, change: last_map_addr: 1080000000 end: 1078000000 to: last_map_addr: 1078000000 end: 1078000000 Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index f7d8031..51f69b3 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -462,18 +462,25 @@ phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end, static void __init find_early_table_space(unsigned long end) { - unsigned long puds, tables, start; + unsigned long puds, pmds, ptes, tables, start; puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; tables = round_up(puds * sizeof(pud_t), PAGE_SIZE); - if (!direct_gbpages) { - unsigned long pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; - tables += round_up(pmds * sizeof(pmd_t), PAGE_SIZE); - } - if (!cpu_has_pse) { - unsigned long ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; - tables += round_up(ptes * sizeof(pte_t), PAGE_SIZE); - } + if (direct_gbpages) { + unsigned long extra; + extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); + pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; + } else + pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; + tables += round_up(pmds * sizeof(pmd_t), PAGE_SIZE); + + if (cpu_has_pse) { + unsigned long extra; + extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); + ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; + } else + ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; + tables += round_up(ptes * sizeof(pte_t), PAGE_SIZE); /* * RED-PEN putting page tables only on node 0 could @@ -660,8 +667,9 @@ static unsigned long __init kernel_physical_mapping_init(unsigned long start, unsigned long __init_refok init_memory_mapping(unsigned long start, unsigned long end) { - unsigned long last_map_addr; + unsigned long last_map_addr = end; unsigned long page_size_mask = 0; + unsigned long start_pfn, end_pfn; printk(KERN_INFO "init_memory_mapping\n"); @@ -682,8 +690,53 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, if (cpu_has_pse) page_size_mask |= 1 << PG_LEVEL_2M; - last_map_addr = kernel_physical_mapping_init(start, end, - page_size_mask); + /* head if not big page aligment ?*/ + start_pfn = start >> PAGE_SHIFT; + end_pfn = ((start + (PMD_SIZE - 1)) >> PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); + if (start_pfn < end_pfn) + last_map_addr = kernel_physical_mapping_init( + start_pfn<>PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); + end_pfn = ((start + (PUD_SIZE - 1))>>PUD_SHIFT) + << (PUD_SHIFT - PAGE_SHIFT); + if (end_pfn > ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT))) + end_pfn = ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT)); + if (start_pfn < end_pfn) + last_map_addr = kernel_physical_mapping_init( + start_pfn<>PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); + if (start_pfn < end_pfn) + last_map_addr = kernel_physical_mapping_init( + start_pfn<>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); + if (start_pfn < end_pfn) + last_map_addr = kernel_physical_mapping_init( + start_pfn<>PAGE_SHIFT; + if (start_pfn < end_pfn) + last_map_addr = kernel_physical_mapping_init( + start_pfn< Date: Wed, 9 Jul 2008 16:29:41 +0900 Subject: x86, iommu: replace CONFIG_IOMMU with CONFIG_GART_IOMMU in iommu.h Hmm, looks like it would be nice to have more cleanups of iommu.h and gart.h. Signed-off-by: FUJITA Tomonori Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h index 07862fd..cb7e989 100644 --- a/include/asm-x86/iommu.h +++ b/include/asm-x86/iommu.h @@ -5,7 +5,7 @@ extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); extern int force_iommu, no_iommu; extern int iommu_detected; -#ifdef CONFIG_IOMMU +#ifdef CONFIG_GART_IOMMU extern void gart_iommu_init(void); extern void gart_iommu_shutdown(void); extern void __init gart_parse_options(char *); -- cgit v0.10.2 From e2079c43861f71b2deb78ee20e247ad954fdd67e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 8 Jul 2008 16:12:26 +0200 Subject: x86: fix C1E && nx6325 stability problem The problems are that, with the ACPI vs timer overring issue _fixed_, after using the box for some time (between several seconds and 1 hour, at random) processes get very high CPU loads (once I've got X using 107% of the CPU, for example) and the system becomes unresponsive, as though there were interrupts lost or something similar. Andreas Herrman reproduced similar problems: > Ok, now I've reproduced the stability problem. > - Using tip/master, > - reverting e38502eb8aa82314d5ab0eba45f50e6790dadd88 and > - applying your patch from this posting > http://marc.info/?l=linux-kernel&m=121539354224562&w=4 > > Starting X, firefox, gimp, tuxpaint and doing some drawing in tuxpaint > results in a slow system. Drawing is almost not possible anymore -- > Selections of new colors, cursors etc. is performed with huge delay > if it's performed at all. > > BTW, the code sets up timer IRQ as Virtual Wire IRQ: > > Jul 8 14:57:58 kodscha IO-APIC (apicid-pin) 2-22, 2-23 not connected. > Jul 8 14:57:58 kodscha ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1 > Jul 8 14:57:58 kodscha ...trying to set up timer as Virtual Wire IRQ... works. > > and both INT0 and INT2 of IOAPIC are masked: > > Jul 8 14:57:58 kodscha NR Dst Mask Trig IRR Pol Stat Dmod Deli Vect: > Jul 8 14:57:58 kodscha 00 000 1 0 0 0 0 0 0 00 > Jul 8 14:57:58 kodscha 01 003 0 0 0 0 0 1 1 31 > Jul 8 14:57:58 kodscha 02 003 1 0 0 0 0 0 0 30 > > I've also seen strange CPU utilization -- with syslog-ng: > > top - 15:33:06 up 35 min, 4 users, load average: 1.70, 0.68, 0.37 > Tasks: 64 total, 4 running, 60 sleeping, 0 stopped, 0 zombie > Cpu0 : 0.0%us,100.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st > Cpu1 : 6.4%us, 87.2%sy, 0.0%ni, 5.8%id, 0.0%wa, 0.6%hi, 0.0%si, 0.0%st > Mem: 895384k total, 283568k used, 611816k free, 35492k buffers > Swap: 1959920k total, 0k used, 1959920k free, 163044k cached > > PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND > 4632 root 20 0 17216 800 580 S 104 0.1 0:34.22 syslog-ng > 28505 root 20 0 205m 11m 4024 S 6 1.3 0:21.16 X > 28518 root 20 0 56292 5652 4492 S 1 0.6 0:01.80 fluxbox > 1 root 20 0 3724 608 508 S 0 0.1 0:00.36 init > > So far I have no clue why C1E-idle in conjunction with virtual wire > mode causes this strange behaviour. > > ... and I start to think about the root cause of all this. > > I've performed similar tests under X with the IRQ0/INT0 configuration and > I did not see above symptoms. So lets fall back to the IRQ0/INT0 configuration on this box. This basically restores the dont-use-the-lapic-timer exception mechanism that was unconditional on this box prior commit 8750bf5 ("x86: add C1E aware idle function"). Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 5c01076..e1f0139 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1373,8 +1373,6 @@ static void __init acpi_process_madt(void) return; } -#ifdef __i386__ - static int __init disable_acpi_irq(const struct dmi_system_id *d) { if (!acpi_force) { @@ -1436,6 +1434,17 @@ dmi_disable_irq0_through_ioapic(const struct dmi_system_id *d) } /* + * Force ignoring BIOS IRQ0 pin2 override + */ +static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) +{ + pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident); + acpi_skip_timer_override = 1; + force_mask_ioapic_irq_2(); + return 0; +} + +/* * If your system is blacklisted here, but you find that acpi=force * works for you, please contact acpi-devel@sourceforge.net */ @@ -1628,11 +1637,35 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), }, }, + /* + * HP laptops which use a DSDT reporting as HP/SB400/10000, + * which includes some code which overrides all temperature + * trip points to 16C if the INTIN2 input of the I/O APIC + * is enabled. This input is incorrectly designated the + * ISA IRQ 0 via an interrupt source override even though + * it is wired to the output of the master 8259A and INTIN0 + * is not connected at all. Force ignoring BIOS IRQ0 pin2 + * override in that cases. + */ + { + .callback = dmi_ignore_irq0_timer_override, + .ident = "HP NX6125 laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"), + }, + }, + { + .callback = dmi_ignore_irq0_timer_override, + .ident = "HP NX6325 laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), + }, + }, {} }; -#endif /* __i386__ */ - /* * acpi_boot_table_init() and acpi_boot_init() * called from setup_arch(), always. @@ -1660,9 +1693,7 @@ int __init acpi_boot_table_init(void) { int error; -#ifdef __i386__ dmi_check_system(acpi_dmi_table); -#endif /* * If acpi_disabled, bail out diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 337ec34..6b220b9 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -59,6 +59,13 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); static DEFINE_SPINLOCK(vector_lock); +static bool mask_ioapic_irq_2 __initdata; + +void __init force_mask_ioapic_irq_2(void) +{ + mask_ioapic_irq_2 = true; +} + int timer_through_8259 __initdata; /* @@ -2172,6 +2179,9 @@ static inline void __init check_timer(void) printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", vector, apic1, pin1, apic2, pin2); + if (mask_ioapic_irq_2) + mask_IO_APIC_irq(2); + /* * Some BIOS writers are clueless and report the ExtINTA * I/O APIC input from the cascaded 8259A as the timer diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 2b4c40b..0494cdb 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -94,6 +94,13 @@ static int no_timer_check; static int disable_timer_pin_1 __initdata; +static bool mask_ioapic_irq_2 __initdata; + +void __init force_mask_ioapic_irq_2(void) +{ + mask_ioapic_irq_2 = true; +} + int timer_through_8259 __initdata; /* Where if anywhere is the i8259 connect in external int mode */ @@ -1698,6 +1705,9 @@ static inline void __init check_timer(void) apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", cfg->vector, apic1, pin1, apic2, pin2); + if (mask_ioapic_irq_2) + mask_IO_APIC_irq(2); + /* * Some BIOS writers are clueless and report the ExtINTA * I/O APIC input from the cascaded 8259A as the timer diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h index b02ea6e..8d4c8bd 100644 --- a/include/asm-x86/genapic_32.h +++ b/include/asm-x86/genapic_32.h @@ -119,5 +119,6 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; #define is_uv_system() 0 #define uv_wakeup_secondary(a, b) 1 +extern void force_mask_ioapic_irq_2(void); #endif diff --git a/include/asm-x86/genapic_64.h b/include/asm-x86/genapic_64.h index 0f85046..082ad02 100644 --- a/include/asm-x86/genapic_64.h +++ b/include/asm-x86/genapic_64.h @@ -46,4 +46,6 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); extern void setup_apic_routing(void); +extern void force_mask_ioapic_irq_2(void); + #endif -- cgit v0.10.2 From 183fe065652dbd64953afa9f389327e23e97967f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 9 Jul 2008 11:32:10 +0200 Subject: x86: build fix for "x86: fix C1E && nx6325 stability problem" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: arch/x86/kernel/acpi/boot.c: In function ‘dmi_ignore_irq0_timer_override’: arch/x86/kernel/acpi/boot.c:1443: error: implicit declaration of function ‘force_mask_ioapic_irq_2’ Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index e1f0139..bf7b4f7 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 6d8566ac131f3dc3e976de824dcb04feaea4b14c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:19 +0200 Subject: x86/pci: Makefile merge: Removing Makefile_* No functional nor ordering changes here. Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index c5c8e48..3a8fb73 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -1,5 +1,49 @@ ifeq ($(CONFIG_X86_32),y) -include ${srctree}/arch/x86/pci/Makefile_32 + +obj-y := i386.o init.o + +obj-$(CONFIG_PCI_BIOS) += pcbios.o +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_32.o direct.o mmconfig-shared.o +obj-$(CONFIG_PCI_DIRECT) += direct.o +obj-$(CONFIG_PCI_OLPC) += olpc.o + +pci-y := fixup.o + +# Do not change the ordering here. There is a nasty init function +# ordering dependency which breaks when you move acpi.o below +# legacy/irq.o +pci-$(CONFIG_ACPI) += acpi.o +pci-y += legacy.o irq.o + +# Careful: VISWS overrule the pci-y above. The colons are +# therefor correct. This needs a proper fix by distangling the code. +pci-$(CONFIG_X86_VISWS) := visws.o fixup.o + +pci-$(CONFIG_X86_NUMAQ) += numa.o + +# Necessary for NUMAQ as well +pci-$(CONFIG_NUMA) += mp_bus_to_node.o + +obj-y += $(pci-y) common.o early.o +obj-y += amd_bus.o + else -include ${srctree}/arch/x86/pci/Makefile_64 + +# +# Makefile for X86_64 specific PCI routines +# +# Reuse the i386 PCI subsystem +# +EXTRA_CFLAGS += -Iarch/x86/pci + +obj-y := i386.o +obj-$(CONFIG_PCI_DIRECT)+= direct.o +obj-y += fixup.o init.o +obj-$(CONFIG_ACPI) += acpi.o +obj-y += legacy.o irq.o common.o early.o +# mmconfig has a 64bit special +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o + +obj-y += amd_bus.o + endif diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32 deleted file mode 100644 index a34fbf5..0000000 --- a/arch/x86/pci/Makefile_32 +++ /dev/null @@ -1,26 +0,0 @@ -obj-y := i386.o init.o - -obj-$(CONFIG_PCI_BIOS) += pcbios.o -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_32.o direct.o mmconfig-shared.o -obj-$(CONFIG_PCI_DIRECT) += direct.o -obj-$(CONFIG_PCI_OLPC) += olpc.o - -pci-y := fixup.o - -# Do not change the ordering here. There is a nasty init function -# ordering dependency which breaks when you move acpi.o below -# legacy/irq.o -pci-$(CONFIG_ACPI) += acpi.o -pci-y += legacy.o irq.o - -# Careful: VISWS overrule the pci-y above. The colons are -# therefor correct. This needs a proper fix by distangling the code. -pci-$(CONFIG_X86_VISWS) := visws.o fixup.o - -pci-$(CONFIG_X86_NUMAQ) += numa.o - -# Necessary for NUMAQ as well -pci-$(CONFIG_NUMA) += mp_bus_to_node.o - -obj-y += $(pci-y) common.o early.o -obj-y += amd_bus.o diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64 deleted file mode 100644 index fd47068..0000000 --- a/arch/x86/pci/Makefile_64 +++ /dev/null @@ -1,17 +0,0 @@ -# -# Makefile for X86_64 specific PCI routines -# -# Reuse the i386 PCI subsystem -# -EXTRA_CFLAGS += -Iarch/x86/pci - -obj-y := i386.o -obj-$(CONFIG_PCI_DIRECT)+= direct.o -obj-y += fixup.o init.o -obj-$(CONFIG_ACPI) += acpi.o -obj-y += legacy.o irq.o common.o early.o -# mmconfig has a 64bit special -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o - -obj-y += amd_bus.o - -- cgit v0.10.2 From 7fa71c0e0e371b995fdf3a367542a014c1f37f29 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:20 +0200 Subject: x86/pci: Makefile merge: removing include dir flag Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 3a8fb73..8645094 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -32,9 +32,6 @@ else # # Makefile for X86_64 specific PCI routines # -# Reuse the i386 PCI subsystem -# -EXTRA_CFLAGS += -Iarch/x86/pci obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o -- cgit v0.10.2 From 0b40e84ab750b4ba5fc8d6712c892502dc93b212 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:21 +0200 Subject: x86/pci: Makefile merge: whitespace changes only Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 8645094..30944bc 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -33,14 +33,14 @@ else # Makefile for X86_64 specific PCI routines # -obj-y := i386.o -obj-$(CONFIG_PCI_DIRECT)+= direct.o -obj-y += fixup.o init.o -obj-$(CONFIG_ACPI) += acpi.o -obj-y += legacy.o irq.o common.o early.o +obj-y := i386.o +obj-$(CONFIG_PCI_DIRECT) += direct.o +obj-y += fixup.o init.o +obj-$(CONFIG_ACPI) += acpi.o +obj-y += legacy.o irq.o common.o early.o # mmconfig has a 64bit special -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o -obj-y += amd_bus.o +obj-y += amd_bus.o endif -- cgit v0.10.2 From a5d4fb94f750e439a0722c0a76c9aade3a9199be Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:22 +0200 Subject: x86/pci: Makefile merge: decoupling options for mp_bus_to_node.o Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 30944bc..044fa5b 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -14,6 +14,7 @@ pci-y := fixup.o # legacy/irq.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o +pci-$(CONFIG_NUMA) += mp_bus_to_node.o # Careful: VISWS overrule the pci-y above. The colons are # therefor correct. This needs a proper fix by distangling the code. @@ -21,9 +22,6 @@ pci-$(CONFIG_X86_VISWS) := visws.o fixup.o pci-$(CONFIG_X86_NUMAQ) += numa.o -# Necessary for NUMAQ as well -pci-$(CONFIG_NUMA) += mp_bus_to_node.o - obj-y += $(pci-y) common.o early.o obj-y += amd_bus.o -- cgit v0.10.2 From 8043c7be4b8dabaaeed8344dd0a4cbaa9a94fb71 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:23 +0200 Subject: x86/pci: Makefile merge: changing 64bit ordering This should be safe since mmconfig*.o and init.o do not contain *initcalls with the same level as in other files. Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 044fa5b..d5f15ef 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -31,14 +31,13 @@ else # Makefile for X86_64 specific PCI routines # -obj-y := i386.o +obj-y := i386.o init.o +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o obj-$(CONFIG_PCI_DIRECT) += direct.o -obj-y += fixup.o init.o +obj-y += fixup.o obj-$(CONFIG_ACPI) += acpi.o -obj-y += legacy.o irq.o common.o early.o -# mmconfig has a 64bit special -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o - +obj-y += legacy.o irq.o +obj-y += common.o early.o obj-y += amd_bus.o endif -- cgit v0.10.2 From 8eefc6640311bb56408fa0abe3f2930b3037f91a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:24 +0200 Subject: x86/pci: Makefile merge: creating pci-y for 64 bit Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index d5f15ef..ed130a2 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -34,10 +34,10 @@ else obj-y := i386.o init.o obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o obj-$(CONFIG_PCI_DIRECT) += direct.o -obj-y += fixup.o -obj-$(CONFIG_ACPI) += acpi.o -obj-y += legacy.o irq.o -obj-y += common.o early.o +pci-y := fixup.o +pci-$(CONFIG_ACPI) += acpi.o +pci-y += legacy.o irq.o +obj-y += $(pci-y) common.o early.o obj-y += amd_bus.o endif -- cgit v0.10.2 From 42a4b427a8d7bff95d9622ffa2365cb56da8e7d6 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:25 +0200 Subject: x86/pci: mp_bus_to_node merge: moving code in amd_bus.c Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index d02c598..465b3a6 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c @@ -14,27 +14,6 @@ * also get peer root bus resource for io,mmio */ - -/* - * sub bus (transparent) will use entres from 3 to store extra from root, - * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? - */ -#define RES_NUM 16 -struct pci_root_info { - char name[12]; - unsigned int res_num; - struct resource res[RES_NUM]; - int bus_min; - int bus_max; - int node; - int link; -}; - -/* 4 at this time, it may become to 32 */ -#define PCI_ROOT_NR 4 -static int pci_root_num; -static struct pci_root_info pci_root_info[PCI_ROOT_NR]; - #ifdef CONFIG_NUMA #define BUS_NR 256 @@ -65,8 +44,29 @@ int get_mp_bus_to_node(int busnum) return node; } + #endif +/* + * sub bus (transparent) will use entres from 3 to store extra from root, + * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? + */ +#define RES_NUM 16 +struct pci_root_info { + char name[12]; + unsigned int res_num; + struct resource res[RES_NUM]; + int bus_min; + int bus_max; + int node; + int link; +}; + +/* 4 at this time, it may become to 32 */ +#define PCI_ROOT_NR 4 +static int pci_root_num; +static struct pci_root_info pci_root_info[PCI_ROOT_NR]; + void set_pci_bus_resources_arch_default(struct pci_bus *b) { int i; -- cgit v0.10.2 From d199a0482791bdf2f052081aa212d8c83ccef88a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:26 +0200 Subject: x86/pci: merge: moving mp_bus_to_node.c to amd_bus.c Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index ed130a2..f3643a7 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -14,7 +14,6 @@ pci-y := fixup.o # legacy/irq.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o -pci-$(CONFIG_NUMA) += mp_bus_to_node.o # Careful: VISWS overrule the pci-y above. The colons are # therefor correct. This needs a proper fix by distangling the code. diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 465b3a6..a18141a 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c @@ -1,13 +1,13 @@ #include #include +#include #include "pci.h" #ifdef CONFIG_X86_64 - #include #include #include -#include +#endif /* * This discovers the pcibus <-> node mapping on AMD K8. @@ -18,6 +18,8 @@ #define BUS_NR 256 +#ifdef CONFIG_X86_64 + static int mp_bus_to_node[BUS_NR]; void set_mp_bus_to_node(int busnum, int node) @@ -45,7 +47,31 @@ int get_mp_bus_to_node(int busnum) return node; } -#endif +#else /* CONFIG_X86_32 */ + +static unsigned char mp_bus_to_node[BUS_NR]; + +void set_mp_bus_to_node(int busnum, int node) +{ + if (busnum >= 0 && busnum < BUS_NR) + mp_bus_to_node[busnum] = (unsigned char) node; +} + +int get_mp_bus_to_node(int busnum) +{ + int node; + + if (busnum < 0 || busnum > (BUS_NR - 1)) + return 0; + node = mp_bus_to_node[busnum]; + return node; +} + +#endif /* CONFIG_X86_32 */ + +#endif /* CONFIG_NUMA */ + +#ifdef CONFIG_X86_64 /* * sub bus (transparent) will use entres from 3 to store extra from root, diff --git a/arch/x86/pci/mp_bus_to_node.c b/arch/x86/pci/mp_bus_to_node.c deleted file mode 100644 index 0229439..0000000 --- a/arch/x86/pci/mp_bus_to_node.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -#define BUS_NR 256 - -static unsigned char mp_bus_to_node[BUS_NR]; - -void set_mp_bus_to_node(int busnum, int node) -{ - if (busnum >= 0 && busnum < BUS_NR) - mp_bus_to_node[busnum] = (unsigned char) node; -} - -int get_mp_bus_to_node(int busnum) -{ - int node; - - if (busnum < 0 || busnum > (BUS_NR - 1)) - return 0; - node = mp_bus_to_node[busnum]; - return node; -} -- cgit v0.10.2 From f4d994b541198446fc3d5d4ec5de232e171bf6dd Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:27 +0200 Subject: x86/pci: Makefile merge: coalescing 32 and 64 bit Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index f3643a7..1ba1236 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -1,9 +1,7 @@ -ifeq ($(CONFIG_X86_32),y) - obj-y := i386.o init.o obj-$(CONFIG_PCI_BIOS) += pcbios.o -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_32.o direct.o mmconfig-shared.o +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o obj-$(CONFIG_PCI_DIRECT) += direct.o obj-$(CONFIG_PCI_OLPC) += olpc.o @@ -23,20 +21,3 @@ pci-$(CONFIG_X86_NUMAQ) += numa.o obj-y += $(pci-y) common.o early.o obj-y += amd_bus.o - -else - -# -# Makefile for X86_64 specific PCI routines -# - -obj-y := i386.o init.o -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o -obj-$(CONFIG_PCI_DIRECT) += direct.o -pci-y := fixup.o -pci-$(CONFIG_ACPI) += acpi.o -pci-y += legacy.o irq.o -obj-y += $(pci-y) common.o early.o -obj-y += amd_bus.o - -endif -- cgit v0.10.2 From ae28d70529b874f657afd0f70ca148599345ba2a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:28 +0200 Subject: x86/pci: visws: renaming pcibios_init() Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index c2df4e9..c3dc9f2 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -85,7 +85,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -static int __init pcibios_init(void) +static int __init pci_visws_init(void) { /* The VISWS supports configuration access type 1 only */ pci_probe = (pci_probe | PCI_PROBE_CONF1) & @@ -105,4 +105,4 @@ static int __init pcibios_init(void) return 0; } -subsys_initcall(pcibios_init); +subsys_initcall(pci_visws_init); -- cgit v0.10.2 From 8dd779b19ce5972072ad2372a86c8acbae4da768 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 2 Jul 2008 22:50:29 +0200 Subject: x86/pci: removing subsys_initcall ordering dependencies So far subsys_initcalls has been executed in this order depending on the object order in the Makefile: arch/x86/pci/visws.c:subsys_initcall(pcibios_init); arch/x86/pci/numa.c:subsys_initcall(pci_numa_init); arch/x86/pci/acpi.c:subsys_initcall(pci_acpi_init); arch/x86/pci/legacy.c:subsys_initcall(pci_legacy_init); arch/x86/pci/irq.c:subsys_initcall(pcibios_irq_init); arch/x86/pci/common.c:subsys_initcall(pcibios_init); This patch removes the ordering dependency. There is now only one subsys_initcall function that contains subsystem initialization code with a defined order. Signed-off-by: Robert Richter Acked-by: Jesse Barnes Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 1ba1236..99d9f09 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -6,10 +6,6 @@ obj-$(CONFIG_PCI_DIRECT) += direct.o obj-$(CONFIG_PCI_OLPC) += olpc.o pci-y := fixup.o - -# Do not change the ordering here. There is a nasty init function -# ordering dependency which breaks when you move acpi.o below -# legacy/irq.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 4fa52d3..19af069 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -223,7 +223,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do return bus; } -static int __init pci_acpi_init(void) +int __init pci_acpi_init(void) { struct pci_dev *dev = NULL; @@ -257,4 +257,3 @@ static int __init pci_acpi_init(void) return 0; } -subsys_initcall(pci_acpi_init); diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 6e64aaf..20b9f59 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -384,7 +384,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) extern u8 pci_cache_line_size; -static int __init pcibios_init(void) +int __init pcibios_init(void) { struct cpuinfo_x86 *c = &boot_cpu_data; @@ -411,8 +411,6 @@ static int __init pcibios_init(void) return 0; } -subsys_initcall(pcibios_init); - char * __devinit pcibios_setup(char *str) { if (!strcmp(str, "off")) { diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c index b821f44..d6c950f 100644 --- a/arch/x86/pci/init.c +++ b/arch/x86/pci/init.c @@ -4,7 +4,7 @@ /* arch_initcall has too random ordering, so call the initializers in the right sequence from here. */ -static __init int pci_access_init(void) +static __init int pci_arch_init(void) { #ifdef CONFIG_PCI_DIRECT int type = 0; @@ -40,4 +40,4 @@ static __init int pci_access_init(void) return 0; } -arch_initcall(pci_access_init); +arch_initcall(pci_arch_init); diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index f0859de..dc568c6 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -1107,7 +1107,7 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = { { } }; -static int __init pcibios_irq_init(void) +int __init pcibios_irq_init(void) { DBG(KERN_DEBUG "PCI: IRQ init\n"); @@ -1142,9 +1142,6 @@ static int __init pcibios_irq_init(void) return 0; } -subsys_initcall(pcibios_irq_init); - - static void pirq_penalize_isa_irq(int irq, int active) { /* diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index a67921c..3c1d795 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c @@ -55,4 +55,13 @@ static int __init pci_legacy_init(void) return 0; } -subsys_initcall(pci_legacy_init); +int __init pci_subsys_init(void) +{ +#ifdef CONFIG_ACPI + pci_acpi_init(); +#endif + pci_legacy_init(); + pcibios_irq_init(); + pcibios_init(); +} +subsys_initcall(pci_subsys_init); diff --git a/arch/x86/pci/numa.c b/arch/x86/pci/numa.c index 99f1ecd..e1620dc 100644 --- a/arch/x86/pci/numa.c +++ b/arch/x86/pci/numa.c @@ -177,4 +177,10 @@ static int __init pci_numa_init(void) return 0; } -subsys_initcall(pci_numa_init); +static __init int pci_subsys_init(void) +{ + pci_numa_init(); + pcibios_irq_init(); + pcibios_init(); +} +subsys_initcall(pci_subsys_init); diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index ba263e6..5824174 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h @@ -39,9 +39,6 @@ enum pci_bf_sort_state { pci_dmi_bf, }; -extern void __init dmi_check_pciprobe(void); -extern void __init dmi_check_skip_isa_align(void); - /* pci-i386.c */ extern unsigned int pcibios_max_latency; @@ -99,10 +96,18 @@ extern struct pci_raw_ops *raw_pci_ext_ops; extern struct pci_raw_ops pci_direct_conf1; +/* arch_initcall level */ extern int pci_direct_probe(void); extern void pci_direct_init(int type); extern void pci_pcbios_init(void); extern int pci_olpc_init(void); +extern void __init dmi_check_pciprobe(void); +extern void __init dmi_check_skip_isa_align(void); + +/* some common used subsys_initcalls */ +extern int __init pci_acpi_init(void); +extern int __init pcibios_irq_init(void); +extern int __init pcibios_init(void); /* pci-mmconfig.c */ diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index c3dc9f2..16e5206 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -105,4 +105,9 @@ static int __init pci_visws_init(void) return 0; } -subsys_initcall(pci_visws_init); +static __init int pci_subsys_init(void) +{ + pci_visws_init(); + pcibios_init(); +} +subsys_initcall(pci_subsys_init); -- cgit v0.10.2 From c22d4c1885130db9c07f6441ab461208a1ba16b2 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 9 Jul 2008 03:01:14 -0700 Subject: x86: make e820_end return max ram type only for 32 bit to avoid warning from find_low_pfn_range for high pages size etc Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 2e08619..292ebc7 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1066,6 +1066,11 @@ unsigned long __init e820_end(void) struct e820entry *ei = &e820.map[i]; unsigned long end_pfn; +#ifdef CONFIG_X86_32 + if (ei->type != E820_RAM) + continue; +#endif + end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; if (end_pfn > last_pfn) last_pfn = end_pfn; -- cgit v0.10.2 From a737abd11ac4eb9f4226fa8c9f1d9b5be12a96c1 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 5 Jul 2008 15:53:39 +0400 Subject: x86: e820 memmap - add checking for NULL early param Signed-off-by: Cyrill Gorcunov Cc: Cyrill Gorcunov Cc: akpm@linux-foundation.org Cc: andi@firstfloor.org Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 292ebc7..66fd5bd 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1198,6 +1198,9 @@ static int __init parse_memmap_opt(char *p) char *oldp; u64 start_at, mem_size; + if (!p) + return -EINVAL; + if (!strcmp(p, "exactmap")) { #ifdef CONFIG_CRASH_DUMP /* -- cgit v0.10.2 From 1129585a08baf58582c0da91e572cb29e3179acf Mon Sep 17 00:00:00 2001 From: Vitaly Mayatskikh Date: Wed, 2 Jul 2008 15:48:21 +0200 Subject: x86: introduce copy_user_handle_tail() routine Introduce generic C routine for handling necessary tail operations after protection fault in copy_*_user on x86. Signed-off-by: Vitaly Mayatskikh Acked-by: Linus Torvalds Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 0c89d1b..f4df6e7 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -158,3 +158,26 @@ unsigned long copy_in_user(void __user *to, const void __user *from, unsigned le } EXPORT_SYMBOL(copy_in_user); +/* + * Try to copy last bytes and clear the rest if needed. + * Since protection fault in copy_from/to_user is not a normal situation, + * it is not necessary to optimize tail handling. + */ +unsigned long +copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest) +{ + char c; + unsigned zero_len; + + for (; len; --len) { + if (__get_user_nocheck(c, from++, sizeof(char))) + break; + if (__put_user_nocheck(c, to++, sizeof(char))) + break; + } + + for (c = 0, zero_len = len; zerorest && zero_len; --zero_len) + if (__put_user_nocheck(c, to++, sizeof(char))) + break; + return len; +} diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 4e3ec00..515d4dc 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -195,4 +195,7 @@ static inline int __copy_from_user_inatomic_nocache(void *dst, return __copy_user_nocache(dst, src, size, 0); } +unsigned long +copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest); + #endif /* __X86_64_UACCESS_H */ -- cgit v0.10.2 From ad2fc2cd925300b8127cf682f5a1c7511ae9dd27 Mon Sep 17 00:00:00 2001 From: Vitaly Mayatskikh Date: Wed, 2 Jul 2008 15:53:13 +0200 Subject: x86: fix copy_user on x86 Switch copy_user_generic_string(), copy_user_generic_unrolled() and __copy_user_nocache() from custom tail handlers to generic copy_user_tail_handle(). Signed-off-by: Vitaly Mayatskikh Acked-by: Linus Torvalds Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 7eaaf01..e5afb4a 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -1,8 +1,10 @@ -/* Copyright 2002 Andi Kleen, SuSE Labs. +/* + * Copyright 2008 Vitaly Mayatskikh + * Copyright 2002 Andi Kleen, SuSE Labs. * Subject to the GNU Public License v2. - * - * Functions to copy from and to user space. - */ + * + * Functions to copy from and to user space. + */ #include #include @@ -20,60 +22,88 @@ .long \orig-1f /* by default jump to orig */ 1: .section .altinstr_replacement,"ax" -2: .byte 0xe9 /* near jump with 32bit immediate */ +2: .byte 0xe9 /* near jump with 32bit immediate */ .long \alt-1b /* offset */ /* or alternatively to alt */ .previous .section .altinstructions,"a" .align 8 .quad 0b .quad 2b - .byte \feature /* when feature is set */ + .byte \feature /* when feature is set */ .byte 5 .byte 5 .previous .endm -/* Standard copy_to_user with segment limit checking */ + .macro ALIGN_DESTINATION +#ifdef FIX_ALIGNMENT + /* check for bad alignment of destination */ + movl %edi,%ecx + andl $7,%ecx + jz 102f /* already aligned */ + subl $8,%ecx + negl %ecx + subl %ecx,%edx +100: movb (%rsi),%al +101: movb %al,(%rdi) + incq %rsi + incq %rdi + decl %ecx + jnz 100b +102: + .section .fixup,"ax" +103: addl %r8d,%edx /* ecx is zerorest also */ + jmp copy_user_handle_tail + .previous + + .section __ex_table,"a" + .align 8 + .quad 100b,103b + .quad 101b,103b + .previous +#endif + .endm + +/* Standard copy_to_user with segment limit checking */ ENTRY(copy_to_user) CFI_STARTPROC GET_THREAD_INFO(%rax) movq %rdi,%rcx addq %rdx,%rcx - jc bad_to_user + jc bad_to_user cmpq TI_addr_limit(%rax),%rcx jae bad_to_user - xorl %eax,%eax /* clear zero flag */ ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string CFI_ENDPROC -ENTRY(copy_user_generic) +/* Standard copy_from_user with segment limit checking */ +ENTRY(copy_from_user) CFI_STARTPROC - movl $1,%ecx /* set zero flag */ + GET_THREAD_INFO(%rax) + movq %rsi,%rcx + addq %rdx,%rcx + jc bad_from_user + cmpq TI_addr_limit(%rax),%rcx + jae bad_from_user ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string CFI_ENDPROC +ENDPROC(copy_from_user) -ENTRY(__copy_from_user_inatomic) +ENTRY(copy_user_generic) CFI_STARTPROC - xorl %ecx,%ecx /* clear zero flag */ ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string CFI_ENDPROC +ENDPROC(copy_user_generic) -/* Standard copy_from_user with segment limit checking */ -ENTRY(copy_from_user) +ENTRY(__copy_from_user_inatomic) CFI_STARTPROC - GET_THREAD_INFO(%rax) - movq %rsi,%rcx - addq %rdx,%rcx - jc bad_from_user - cmpq TI_addr_limit(%rax),%rcx - jae bad_from_user - movl $1,%ecx /* set zero flag */ ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string CFI_ENDPROC -ENDPROC(copy_from_user) - +ENDPROC(__copy_from_user_inatomic) + .section .fixup,"ax" /* must zero dest */ +ENTRY(bad_from_user) bad_from_user: CFI_STARTPROC movl %edx,%ecx @@ -81,271 +111,158 @@ bad_from_user: rep stosb bad_to_user: - movl %edx,%eax + movl %edx,%eax ret CFI_ENDPROC -END(bad_from_user) +ENDPROC(bad_from_user) .previous - - + /* * copy_user_generic_unrolled - memory copy with exception handling. - * This version is for CPUs like P4 that don't have efficient micro code for rep movsq - * - * Input: + * This version is for CPUs like P4 that don't have efficient micro + * code for rep movsq + * + * Input: * rdi destination * rsi source * rdx count - * ecx zero flag -- if true zero destination on error * - * Output: - * eax uncopied bytes or 0 if successful. + * Output: + * eax uncopied bytes or 0 if successfull. */ ENTRY(copy_user_generic_unrolled) CFI_STARTPROC - pushq %rbx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbx, 0 - pushq %rcx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rcx, 0 - xorl %eax,%eax /*zero for the exception handler */ - -#ifdef FIX_ALIGNMENT - /* check for bad alignment of destination */ - movl %edi,%ecx - andl $7,%ecx - jnz .Lbad_alignment -.Lafter_bad_alignment: -#endif - - movq %rdx,%rcx - - movl $64,%ebx - shrq $6,%rdx - decq %rdx - js .Lhandle_tail - - .p2align 4 -.Lloop: -.Ls1: movq (%rsi),%r11 -.Ls2: movq 1*8(%rsi),%r8 -.Ls3: movq 2*8(%rsi),%r9 -.Ls4: movq 3*8(%rsi),%r10 -.Ld1: movq %r11,(%rdi) -.Ld2: movq %r8,1*8(%rdi) -.Ld3: movq %r9,2*8(%rdi) -.Ld4: movq %r10,3*8(%rdi) - -.Ls5: movq 4*8(%rsi),%r11 -.Ls6: movq 5*8(%rsi),%r8 -.Ls7: movq 6*8(%rsi),%r9 -.Ls8: movq 7*8(%rsi),%r10 -.Ld5: movq %r11,4*8(%rdi) -.Ld6: movq %r8,5*8(%rdi) -.Ld7: movq %r9,6*8(%rdi) -.Ld8: movq %r10,7*8(%rdi) - - decq %rdx - + cmpl $8,%edx + jb 20f /* less then 8 bytes, go to byte copy loop */ + ALIGN_DESTINATION + movl %edx,%ecx + andl $63,%edx + shrl $6,%ecx + jz 17f +1: movq (%rsi),%r8 +2: movq 1*8(%rsi),%r9 +3: movq 2*8(%rsi),%r10 +4: movq 3*8(%rsi),%r11 +5: movq %r8,(%rdi) +6: movq %r9,1*8(%rdi) +7: movq %r10,2*8(%rdi) +8: movq %r11,3*8(%rdi) +9: movq 4*8(%rsi),%r8 +10: movq 5*8(%rsi),%r9 +11: movq 6*8(%rsi),%r10 +12: movq 7*8(%rsi),%r11 +13: movq %r8,4*8(%rdi) +14: movq %r9,5*8(%rdi) +15: movq %r10,6*8(%rdi) +16: movq %r11,7*8(%rdi) leaq 64(%rsi),%rsi leaq 64(%rdi),%rdi - - jns .Lloop - - .p2align 4 -.Lhandle_tail: - movl %ecx,%edx - andl $63,%ecx - shrl $3,%ecx - jz .Lhandle_7 - movl $8,%ebx - .p2align 4 -.Lloop_8: -.Ls9: movq (%rsi),%r8 -.Ld9: movq %r8,(%rdi) decl %ecx - leaq 8(%rdi),%rdi + jnz 1b +17: movl %edx,%ecx + andl $7,%edx + shrl $3,%ecx + jz 20f +18: movq (%rsi),%r8 +19: movq %r8,(%rdi) leaq 8(%rsi),%rsi - jnz .Lloop_8 - -.Lhandle_7: + leaq 8(%rdi),%rdi + decl %ecx + jnz 18b +20: andl %edx,%edx + jz 23f movl %edx,%ecx - andl $7,%ecx - jz .Lende - .p2align 4 -.Lloop_1: -.Ls10: movb (%rsi),%bl -.Ld10: movb %bl,(%rdi) - incq %rdi +21: movb (%rsi),%al +22: movb %al,(%rdi) incq %rsi + incq %rdi decl %ecx - jnz .Lloop_1 - - CFI_REMEMBER_STATE -.Lende: - popq %rcx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rcx - popq %rbx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rbx + jnz 21b +23: xor %eax,%eax ret - CFI_RESTORE_STATE -#ifdef FIX_ALIGNMENT - /* align destination */ - .p2align 4 -.Lbad_alignment: - movl $8,%r9d - subl %ecx,%r9d - movl %r9d,%ecx - cmpq %r9,%rdx - jz .Lhandle_7 - js .Lhandle_7 -.Lalign_1: -.Ls11: movb (%rsi),%bl -.Ld11: movb %bl,(%rdi) - incq %rsi - incq %rdi - decl %ecx - jnz .Lalign_1 - subq %r9,%rdx - jmp .Lafter_bad_alignment -#endif + .section .fixup,"ax" +30: shll $6,%ecx + addl %ecx,%edx + jmp 60f +40: leal (%edx,%ecx,8),%edx + jmp 60f +50: movl %ecx,%edx +60: jmp copy_user_handle_tail /* ecx is zerorest also */ + .previous - /* table sorted by exception address */ .section __ex_table,"a" .align 8 - .quad .Ls1,.Ls1e /* Ls1-Ls4 have copied zero bytes */ - .quad .Ls2,.Ls1e - .quad .Ls3,.Ls1e - .quad .Ls4,.Ls1e - .quad .Ld1,.Ls1e /* Ld1-Ld4 have copied 0-24 bytes */ - .quad .Ld2,.Ls2e - .quad .Ld3,.Ls3e - .quad .Ld4,.Ls4e - .quad .Ls5,.Ls5e /* Ls5-Ls8 have copied 32 bytes */ - .quad .Ls6,.Ls5e - .quad .Ls7,.Ls5e - .quad .Ls8,.Ls5e - .quad .Ld5,.Ls5e /* Ld5-Ld8 have copied 32-56 bytes */ - .quad .Ld6,.Ls6e - .quad .Ld7,.Ls7e - .quad .Ld8,.Ls8e - .quad .Ls9,.Le_quad - .quad .Ld9,.Le_quad - .quad .Ls10,.Le_byte - .quad .Ld10,.Le_byte -#ifdef FIX_ALIGNMENT - .quad .Ls11,.Lzero_rest - .quad .Ld11,.Lzero_rest -#endif - .quad .Le5,.Le_zero + .quad 1b,30b + .quad 2b,30b + .quad 3b,30b + .quad 4b,30b + .quad 5b,30b + .quad 6b,30b + .quad 7b,30b + .quad 8b,30b + .quad 9b,30b + .quad 10b,30b + .quad 11b,30b + .quad 12b,30b + .quad 13b,30b + .quad 14b,30b + .quad 15b,30b + .quad 16b,30b + .quad 18b,40b + .quad 19b,40b + .quad 21b,50b + .quad 22b,50b .previous - - /* eax: zero, ebx: 64 */ -.Ls1e: addl $8,%eax /* eax is bytes left uncopied within the loop (Ls1e: 64 .. Ls8e: 8) */ -.Ls2e: addl $8,%eax -.Ls3e: addl $8,%eax -.Ls4e: addl $8,%eax -.Ls5e: addl $8,%eax -.Ls6e: addl $8,%eax -.Ls7e: addl $8,%eax -.Ls8e: addl $8,%eax - addq %rbx,%rdi /* +64 */ - subq %rax,%rdi /* correct destination with computed offset */ - - shlq $6,%rdx /* loop counter * 64 (stride length) */ - addq %rax,%rdx /* add offset to loopcnt */ - andl $63,%ecx /* remaining bytes */ - addq %rcx,%rdx /* add them */ - jmp .Lzero_rest - - /* exception on quad word loop in tail handling */ - /* ecx: loopcnt/8, %edx: length, rdi: correct */ -.Le_quad: - shll $3,%ecx - andl $7,%edx - addl %ecx,%edx - /* edx: bytes to zero, rdi: dest, eax:zero */ -.Lzero_rest: - cmpl $0,(%rsp) - jz .Le_zero - movq %rdx,%rcx -.Le_byte: - xorl %eax,%eax -.Le5: rep - stosb - /* when there is another exception while zeroing the rest just return */ -.Le_zero: - movq %rdx,%rax - jmp .Lende CFI_ENDPROC -ENDPROC(copy_user_generic) +ENDPROC(copy_user_generic_unrolled) - - /* Some CPUs run faster using the string copy instructions. - This is also a lot simpler. Use them when possible. - Patch in jmps to this code instead of copying it fully - to avoid unwanted aliasing in the exception tables. */ - - /* rdi destination - * rsi source - * rdx count - * ecx zero flag - * - * Output: - * eax uncopied bytes or 0 if successfull. - * - * Only 4GB of copy is supported. This shouldn't be a problem - * because the kernel normally only writes from/to page sized chunks - * even if user space passed a longer buffer. - * And more would be dangerous because both Intel and AMD have - * errata with rep movsq > 4GB. If someone feels the need to fix - * this please consider this. - */ +/* Some CPUs run faster using the string copy instructions. + * This is also a lot simpler. Use them when possible. + * + * Only 4GB of copy is supported. This shouldn't be a problem + * because the kernel normally only writes from/to page sized chunks + * even if user space passed a longer buffer. + * And more would be dangerous because both Intel and AMD have + * errata with rep movsq > 4GB. If someone feels the need to fix + * this please consider this. + * + * Input: + * rdi destination + * rsi source + * rdx count + * + * Output: + * eax uncopied bytes or 0 if successful. + */ ENTRY(copy_user_generic_string) CFI_STARTPROC - movl %ecx,%r8d /* save zero flag */ + andl %edx,%edx + jz 4f + cmpl $8,%edx + jb 2f /* less than 8 bytes, go to byte copy loop */ + ALIGN_DESTINATION movl %edx,%ecx shrl $3,%ecx - andl $7,%edx - jz 10f -1: rep - movsq - movl %edx,%ecx -2: rep - movsb -9: movl %ecx,%eax - ret - - /* multiple of 8 byte */ -10: rep + andl $7,%edx +1: rep movsq - xor %eax,%eax +2: movl %edx,%ecx +3: rep + movsb +4: xorl %eax,%eax ret - /* exception handling */ -3: lea (%rdx,%rcx,8),%rax /* exception on quad loop */ - jmp 6f -5: movl %ecx,%eax /* exception on byte loop */ - /* eax: left over bytes */ -6: testl %r8d,%r8d /* zero flag set? */ - jz 7f - movl %eax,%ecx /* initialize x86 loop counter */ - push %rax - xorl %eax,%eax -8: rep - stosb /* zero the rest */ -11: pop %rax -7: ret - CFI_ENDPROC -END(copy_user_generic_c) + .section .fixup,"ax" +11: leal (%edx,%ecx,8),%ecx +12: movl %ecx,%edx /* ecx is zerorest also */ + jmp copy_user_handle_tail + .previous .section __ex_table,"a" - .quad 1b,3b - .quad 2b,5b - .quad 8b,11b - .quad 10b,3b + .align 8 + .quad 1b,11b + .quad 3b,12b .previous + CFI_ENDPROC +ENDPROC(copy_user_generic_string) diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S index 9d3d1ab..93353d6 100644 --- a/arch/x86/lib/copy_user_nocache_64.S +++ b/arch/x86/lib/copy_user_nocache_64.S @@ -1,4 +1,6 @@ -/* Copyright 2002 Andi Kleen, SuSE Labs. +/* + * Copyright 2008 Vitaly Mayatskikh + * Copyright 2002 Andi Kleen, SuSE Labs. * Subject to the GNU Public License v2. * * Functions to copy from and to user space. @@ -12,204 +14,125 @@ #include #include #include -#include - -/* - * copy_user_nocache - Uncached memory copy with exception handling - * This will force destination/source out of cache for more performance. - * - * Input: - * rdi destination - * rsi source - * rdx count - * rcx zero flag when 1 zero on exception - * - * Output: - * eax uncopied bytes or 0 if successful. - */ -ENTRY(__copy_user_nocache) - CFI_STARTPROC - pushq %rbx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbx, 0 - pushq %rcx /* save zero flag */ - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rcx, 0 - - xorl %eax,%eax /* zero for the exception handler */ + .macro ALIGN_DESTINATION #ifdef FIX_ALIGNMENT /* check for bad alignment of destination */ movl %edi,%ecx andl $7,%ecx - jnz .Lbad_alignment -.Lafter_bad_alignment: -#endif - - movq %rdx,%rcx - - movl $64,%ebx - shrq $6,%rdx - decq %rdx - js .Lhandle_tail - - .p2align 4 -.Lloop: -.Ls1: movq (%rsi),%r11 -.Ls2: movq 1*8(%rsi),%r8 -.Ls3: movq 2*8(%rsi),%r9 -.Ls4: movq 3*8(%rsi),%r10 -.Ld1: movnti %r11,(%rdi) -.Ld2: movnti %r8,1*8(%rdi) -.Ld3: movnti %r9,2*8(%rdi) -.Ld4: movnti %r10,3*8(%rdi) - -.Ls5: movq 4*8(%rsi),%r11 -.Ls6: movq 5*8(%rsi),%r8 -.Ls7: movq 6*8(%rsi),%r9 -.Ls8: movq 7*8(%rsi),%r10 -.Ld5: movnti %r11,4*8(%rdi) -.Ld6: movnti %r8,5*8(%rdi) -.Ld7: movnti %r9,6*8(%rdi) -.Ld8: movnti %r10,7*8(%rdi) + jz 102f /* already aligned */ + subl $8,%ecx + negl %ecx + subl %ecx,%edx +100: movb (%rsi),%al +101: movb %al,(%rdi) + incq %rsi + incq %rdi + decl %ecx + jnz 100b +102: + .section .fixup,"ax" +103: addl %r8d,%edx /* ecx is zerorest also */ + jmp copy_user_handle_tail + .previous - dec %rdx + .section __ex_table,"a" + .align 8 + .quad 100b,103b + .quad 101b,103b + .previous +#endif + .endm +/* + * copy_user_nocache - Uncached memory copy with exception handling + * This will force destination/source out of cache for more performance. + */ +ENTRY(__copy_user_nocache) + CFI_STARTPROC + cmpl $8,%edx + jb 20f /* less then 8 bytes, go to byte copy loop */ + ALIGN_DESTINATION + movl %edx,%ecx + andl $63,%edx + shrl $6,%ecx + jz 17f +1: movq (%rsi),%r8 +2: movq 1*8(%rsi),%r9 +3: movq 2*8(%rsi),%r10 +4: movq 3*8(%rsi),%r11 +5: movnti %r8,(%rdi) +6: movnti %r9,1*8(%rdi) +7: movnti %r10,2*8(%rdi) +8: movnti %r11,3*8(%rdi) +9: movq 4*8(%rsi),%r8 +10: movq 5*8(%rsi),%r9 +11: movq 6*8(%rsi),%r10 +12: movq 7*8(%rsi),%r11 +13: movnti %r8,4*8(%rdi) +14: movnti %r9,5*8(%rdi) +15: movnti %r10,6*8(%rdi) +16: movnti %r11,7*8(%rdi) leaq 64(%rsi),%rsi leaq 64(%rdi),%rdi - - jns .Lloop - - .p2align 4 -.Lhandle_tail: - movl %ecx,%edx - andl $63,%ecx - shrl $3,%ecx - jz .Lhandle_7 - movl $8,%ebx - .p2align 4 -.Lloop_8: -.Ls9: movq (%rsi),%r8 -.Ld9: movnti %r8,(%rdi) decl %ecx - leaq 8(%rdi),%rdi + jnz 1b +17: movl %edx,%ecx + andl $7,%edx + shrl $3,%ecx + jz 20f +18: movq (%rsi),%r8 +19: movnti %r8,(%rdi) leaq 8(%rsi),%rsi - jnz .Lloop_8 - -.Lhandle_7: + leaq 8(%rdi),%rdi + decl %ecx + jnz 18b +20: andl %edx,%edx + jz 23f movl %edx,%ecx - andl $7,%ecx - jz .Lende - .p2align 4 -.Lloop_1: -.Ls10: movb (%rsi),%bl -.Ld10: movb %bl,(%rdi) - incq %rdi +21: movb (%rsi),%al +22: movb %al,(%rdi) incq %rsi + incq %rdi decl %ecx - jnz .Lloop_1 - - CFI_REMEMBER_STATE -.Lende: - popq %rcx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE %rcx - popq %rbx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rbx + jnz 21b +23: xorl %eax,%eax sfence ret - CFI_RESTORE_STATE -#ifdef FIX_ALIGNMENT - /* align destination */ - .p2align 4 -.Lbad_alignment: - movl $8,%r9d - subl %ecx,%r9d - movl %r9d,%ecx - cmpq %r9,%rdx - jz .Lhandle_7 - js .Lhandle_7 -.Lalign_1: -.Ls11: movb (%rsi),%bl -.Ld11: movb %bl,(%rdi) - incq %rsi - incq %rdi - decl %ecx - jnz .Lalign_1 - subq %r9,%rdx - jmp .Lafter_bad_alignment -#endif + .section .fixup,"ax" +30: shll $6,%ecx + addl %ecx,%edx + jmp 60f +40: leal (%edx,%ecx,8),%edx + jmp 60f +50: movl %ecx,%edx +60: sfence + movl %r8d,%ecx + jmp copy_user_handle_tail + .previous - /* table sorted by exception address */ .section __ex_table,"a" - .align 8 - .quad .Ls1,.Ls1e /* .Ls[1-4] - 0 bytes copied */ - .quad .Ls2,.Ls1e - .quad .Ls3,.Ls1e - .quad .Ls4,.Ls1e - .quad .Ld1,.Ls1e /* .Ld[1-4] - 0..24 bytes coped */ - .quad .Ld2,.Ls2e - .quad .Ld3,.Ls3e - .quad .Ld4,.Ls4e - .quad .Ls5,.Ls5e /* .Ls[5-8] - 32 bytes copied */ - .quad .Ls6,.Ls5e - .quad .Ls7,.Ls5e - .quad .Ls8,.Ls5e - .quad .Ld5,.Ls5e /* .Ld[5-8] - 32..56 bytes copied */ - .quad .Ld6,.Ls6e - .quad .Ld7,.Ls7e - .quad .Ld8,.Ls8e - .quad .Ls9,.Le_quad - .quad .Ld9,.Le_quad - .quad .Ls10,.Le_byte - .quad .Ld10,.Le_byte -#ifdef FIX_ALIGNMENT - .quad .Ls11,.Lzero_rest - .quad .Ld11,.Lzero_rest -#endif - .quad .Le5,.Le_zero + .quad 1b,30b + .quad 2b,30b + .quad 3b,30b + .quad 4b,30b + .quad 5b,30b + .quad 6b,30b + .quad 7b,30b + .quad 8b,30b + .quad 9b,30b + .quad 10b,30b + .quad 11b,30b + .quad 12b,30b + .quad 13b,30b + .quad 14b,30b + .quad 15b,30b + .quad 16b,30b + .quad 18b,40b + .quad 19b,40b + .quad 21b,50b + .quad 22b,50b .previous - - /* eax: zero, ebx: 64 */ -.Ls1e: addl $8,%eax /* eax: bytes left uncopied: Ls1e: 64 .. Ls8e: 8 */ -.Ls2e: addl $8,%eax -.Ls3e: addl $8,%eax -.Ls4e: addl $8,%eax -.Ls5e: addl $8,%eax -.Ls6e: addl $8,%eax -.Ls7e: addl $8,%eax -.Ls8e: addl $8,%eax - addq %rbx,%rdi /* +64 */ - subq %rax,%rdi /* correct destination with computed offset */ - - shlq $6,%rdx /* loop counter * 64 (stride length) */ - addq %rax,%rdx /* add offset to loopcnt */ - andl $63,%ecx /* remaining bytes */ - addq %rcx,%rdx /* add them */ - jmp .Lzero_rest - - /* exception on quad word loop in tail handling */ - /* ecx: loopcnt/8, %edx: length, rdi: correct */ -.Le_quad: - shll $3,%ecx - andl $7,%edx - addl %ecx,%edx - /* edx: bytes to zero, rdi: dest, eax:zero */ -.Lzero_rest: - cmpl $0,(%rsp) /* zero flag set? */ - jz .Le_zero - movq %rdx,%rcx -.Le_byte: - xorl %eax,%eax -.Le5: rep - stosb - /* when there is another exception while zeroing the rest just return */ -.Le_zero: - movq %rdx,%rax - jmp .Lende CFI_ENDPROC ENDPROC(__copy_user_nocache) - - -- cgit v0.10.2 From c356aa456e8677682aa3cdb4b81d08e814b1a379 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 9 Jul 2008 09:41:52 -0600 Subject: powerpc/bootwrapper: Allow user to specify additional default targets It is inconvenient to add additional default targets to the bootwrapper Makefile for each new board supported which just needs a different dts file. This change allows the defconfig to specify additional build targets. Signed-off-by: Grant Likely Acked-by: Josh Boyer diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f2a0f50..3216a3a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -458,6 +458,19 @@ config CMDLINE some command-line options at build time by entering them here. In most cases you will need to specify the root device here. +config EXTRA_TARGETS + string "Additional default image types" + help + List additional targets to be built by the bootwrapper here (separated + by spaces). This is useful for targets that depend of device tree + files in the .dts directory. + + Targets in this list will be build as part of the default build + target, or when the user does a 'make zImage' or a + 'make zImage.initrd'. + + If unsure, leave blank + if !44x || BROKEN config ARCH_WANTS_FREEZER_CONTROL def_bool y diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index df6e621..88d30db 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -276,6 +276,9 @@ ifeq ($(CONFIG_PPC32),y) image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot endif +# Allow extra targets to be added to the defconfig +image-y += $(subst ",,$(CONFIG_EXTRA_TARGETS)) + initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) initrd-y := $(patsubst zImage%, zImage.initrd%, \ $(patsubst dtbImage%, dtbImage.initrd%, \ -- cgit v0.10.2 From 57dc9a5747942f131a1a8b36d661fec6e6a5e9f6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 20 Jun 2008 15:35:32 -0400 Subject: NFS: Reduce the stack usage in NFSv4 create operations Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1293e0a..26fbeb3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2079,47 +2079,81 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n return err; } +struct nfs4_createdata { + struct rpc_message msg; + struct nfs4_create_arg arg; + struct nfs4_create_res res; + struct nfs_fh fh; + struct nfs_fattr fattr; + struct nfs_fattr dir_fattr; +}; + +static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, + struct qstr *name, struct iattr *sattr, u32 ftype) +{ + struct nfs4_createdata *data; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data != NULL) { + struct nfs_server *server = NFS_SERVER(dir); + + data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; + data->msg.rpc_argp = &data->arg; + data->msg.rpc_resp = &data->res; + data->arg.dir_fh = NFS_FH(dir); + data->arg.server = server; + data->arg.name = name; + data->arg.attrs = sattr; + data->arg.ftype = ftype; + data->arg.bitmask = server->attr_bitmask; + data->res.server = server; + data->res.fh = &data->fh; + data->res.fattr = &data->fattr; + data->res.dir_fattr = &data->dir_fattr; + nfs_fattr_init(data->res.fattr); + nfs_fattr_init(data->res.dir_fattr); + } + return data; +} + +static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) +{ + int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); + if (status == 0) { + update_changeattr(dir, &data->res.dir_cinfo); + nfs_post_op_update_inode(dir, data->res.dir_fattr); + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); + } + return status; +} + +static void nfs4_free_createdata(struct nfs4_createdata *data) +{ + kfree(data); +} + static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, unsigned int len, struct iattr *sattr) { - struct nfs_server *server = NFS_SERVER(dir); - struct nfs_fh fhandle; - struct nfs_fattr fattr, dir_fattr; - struct nfs4_create_arg arg = { - .dir_fh = NFS_FH(dir), - .server = server, - .name = &dentry->d_name, - .attrs = sattr, - .ftype = NF4LNK, - .bitmask = server->attr_bitmask, - }; - struct nfs4_create_res res = { - .server = server, - .fh = &fhandle, - .fattr = &fattr, - .dir_fattr = &dir_fattr, - }; - struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK], - .rpc_argp = &arg, - .rpc_resp = &res, - }; - int status; + struct nfs4_createdata *data; + int status = -ENAMETOOLONG; if (len > NFS4_MAXPATHLEN) - return -ENAMETOOLONG; + goto out; - arg.u.symlink.pages = &page; - arg.u.symlink.len = len; - nfs_fattr_init(&fattr); - nfs_fattr_init(&dir_fattr); + status = -ENOMEM; + data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4LNK); + if (data == NULL) + goto out; + + data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK]; + data->arg.u.symlink.pages = &page; + data->arg.u.symlink.len = len; - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - if (!status) { - update_changeattr(dir, &res.dir_cinfo); - nfs_post_op_update_inode(dir, res.dir_fattr); - status = nfs_instantiate(dentry, &fhandle, &fattr); - } + status = nfs4_do_create(dir, dentry, data); + + nfs4_free_createdata(data); +out: return status; } @@ -2140,39 +2174,17 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { - struct nfs_server *server = NFS_SERVER(dir); - struct nfs_fh fhandle; - struct nfs_fattr fattr, dir_fattr; - struct nfs4_create_arg arg = { - .dir_fh = NFS_FH(dir), - .server = server, - .name = &dentry->d_name, - .attrs = sattr, - .ftype = NF4DIR, - .bitmask = server->attr_bitmask, - }; - struct nfs4_create_res res = { - .server = server, - .fh = &fhandle, - .fattr = &fattr, - .dir_fattr = &dir_fattr, - }; - struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], - .rpc_argp = &arg, - .rpc_resp = &res, - }; - int status; + struct nfs4_createdata *data; + int status = -ENOMEM; - nfs_fattr_init(&fattr); - nfs_fattr_init(&dir_fattr); - - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - if (!status) { - update_changeattr(dir, &res.dir_cinfo); - nfs_post_op_update_inode(dir, res.dir_fattr); - status = nfs_instantiate(dentry, &fhandle, &fattr); - } + data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4DIR); + if (data == NULL) + goto out; + + status = nfs4_do_create(dir, dentry, data); + + nfs4_free_createdata(data); +out: return status; } @@ -2242,56 +2254,34 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { - struct nfs_server *server = NFS_SERVER(dir); - struct nfs_fh fh; - struct nfs_fattr fattr, dir_fattr; - struct nfs4_create_arg arg = { - .dir_fh = NFS_FH(dir), - .server = server, - .name = &dentry->d_name, - .attrs = sattr, - .bitmask = server->attr_bitmask, - }; - struct nfs4_create_res res = { - .server = server, - .fh = &fh, - .fattr = &fattr, - .dir_fattr = &dir_fattr, - }; - struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], - .rpc_argp = &arg, - .rpc_resp = &res, - }; - int status; - int mode = sattr->ia_mode; - - nfs_fattr_init(&fattr); - nfs_fattr_init(&dir_fattr); + struct nfs4_createdata *data; + int mode = sattr->ia_mode; + int status = -ENOMEM; BUG_ON(!(sattr->ia_valid & ATTR_MODE)); BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode)); + + data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4SOCK); + if (data == NULL) + goto out; + if (S_ISFIFO(mode)) - arg.ftype = NF4FIFO; + data->arg.ftype = NF4FIFO; else if (S_ISBLK(mode)) { - arg.ftype = NF4BLK; - arg.u.device.specdata1 = MAJOR(rdev); - arg.u.device.specdata2 = MINOR(rdev); + data->arg.ftype = NF4BLK; + data->arg.u.device.specdata1 = MAJOR(rdev); + data->arg.u.device.specdata2 = MINOR(rdev); } else if (S_ISCHR(mode)) { - arg.ftype = NF4CHR; - arg.u.device.specdata1 = MAJOR(rdev); - arg.u.device.specdata2 = MINOR(rdev); + data->arg.ftype = NF4CHR; + data->arg.u.device.specdata1 = MAJOR(rdev); + data->arg.u.device.specdata2 = MINOR(rdev); } - else - arg.ftype = NF4SOCK; - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - if (status == 0) { - update_changeattr(dir, &res.dir_cinfo); - nfs_post_op_update_inode(dir, res.dir_fattr); - status = nfs_instantiate(dentry, &fh, &fattr); - } + status = nfs4_do_create(dir, dentry, data); + + nfs4_free_createdata(data); +out: return status; } -- cgit v0.10.2 From 0b4aae7aad162ad175ba8a65708332f888066b26 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 20 Jun 2008 17:00:23 -0400 Subject: NFS: Reduce the stack usage in NFSv3 create operations Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index c3523ad..cf7d4e5 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -248,6 +248,53 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page, return status; } +struct nfs3_createdata { + struct rpc_message msg; + union { + struct nfs3_createargs create; + struct nfs3_mkdirargs mkdir; + struct nfs3_symlinkargs symlink; + struct nfs3_mknodargs mknod; + } arg; + struct nfs3_diropres res; + struct nfs_fh fh; + struct nfs_fattr fattr; + struct nfs_fattr dir_attr; +}; + +static struct nfs3_createdata *nfs3_alloc_createdata(void) +{ + struct nfs3_createdata *data; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data != NULL) { + data->msg.rpc_argp = &data->arg; + data->msg.rpc_resp = &data->res; + data->res.fh = &data->fh; + data->res.fattr = &data->fattr; + data->res.dir_attr = &data->dir_attr; + nfs_fattr_init(data->res.fattr); + nfs_fattr_init(data->res.dir_attr); + } + return data; +} + +static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data) +{ + int status; + + status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); + nfs_post_op_update_inode(dir, data->res.dir_attr); + if (status == 0) + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); + return status; +} + +static void nfs3_free_createdata(struct nfs3_createdata *data) +{ + kfree(data); +} + /* * Create a regular file. * For now, we don't implement O_EXCL. @@ -256,70 +303,60 @@ static int nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags, struct nameidata *nd) { - struct nfs_fh fhandle; - struct nfs_fattr fattr; - struct nfs_fattr dir_attr; - struct nfs3_createargs arg = { - .fh = NFS_FH(dir), - .name = dentry->d_name.name, - .len = dentry->d_name.len, - .sattr = sattr, - }; - struct nfs3_diropres res = { - .dir_attr = &dir_attr, - .fh = &fhandle, - .fattr = &fattr - }; - struct rpc_message msg = { - .rpc_proc = &nfs3_procedures[NFS3PROC_CREATE], - .rpc_argp = &arg, - .rpc_resp = &res, - }; + struct nfs3_createdata *data; mode_t mode = sattr->ia_mode; - int status; + int status = -ENOMEM; dprintk("NFS call create %s\n", dentry->d_name.name); - arg.createmode = NFS3_CREATE_UNCHECKED; + + data = nfs3_alloc_createdata(); + if (data == NULL) + goto out; + + data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_CREATE]; + data->arg.create.fh = NFS_FH(dir); + data->arg.create.name = dentry->d_name.name; + data->arg.create.len = dentry->d_name.len; + data->arg.create.sattr = sattr; + + data->arg.create.createmode = NFS3_CREATE_UNCHECKED; if (flags & O_EXCL) { - arg.createmode = NFS3_CREATE_EXCLUSIVE; - arg.verifier[0] = jiffies; - arg.verifier[1] = current->pid; + data->arg.create.createmode = NFS3_CREATE_EXCLUSIVE; + data->arg.create.verifier[0] = jiffies; + data->arg.create.verifier[1] = current->pid; } sattr->ia_mode &= ~current->fs->umask; -again: - nfs_fattr_init(&dir_attr); - nfs_fattr_init(&fattr); - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_refresh_inode(dir, &dir_attr); + for (;;) { + status = nfs3_do_create(dir, dentry, data); - /* If the server doesn't support the exclusive creation semantics, - * try again with simple 'guarded' mode. */ - if (status == -ENOTSUPP) { - switch (arg.createmode) { + if (status != -ENOTSUPP) + break; + /* If the server doesn't support the exclusive creation + * semantics, try again with simple 'guarded' mode. */ + switch (data->arg.create.createmode) { case NFS3_CREATE_EXCLUSIVE: - arg.createmode = NFS3_CREATE_GUARDED; + data->arg.create.createmode = NFS3_CREATE_GUARDED; break; case NFS3_CREATE_GUARDED: - arg.createmode = NFS3_CREATE_UNCHECKED; + data->arg.create.createmode = NFS3_CREATE_UNCHECKED; break; case NFS3_CREATE_UNCHECKED: goto out; } - goto again; + nfs_fattr_init(data->res.dir_attr); + nfs_fattr_init(data->res.fattr); } - if (status == 0) - status = nfs_instantiate(dentry, &fhandle, &fattr); if (status != 0) goto out; /* When we created the file with exclusive semantics, make * sure we set the attributes afterwards. */ - if (arg.createmode == NFS3_CREATE_EXCLUSIVE) { + if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) { dprintk("NFS call setattr (post-create)\n"); if (!(sattr->ia_valid & ATTR_ATIME_SET)) @@ -330,14 +367,15 @@ again: /* Note: we could use a guarded setattr here, but I'm * not sure this buys us anything (and I'd have * to revamp the NFSv3 XDR code) */ - status = nfs3_proc_setattr(dentry, &fattr, sattr); - nfs_post_op_update_inode(dentry->d_inode, &fattr); + status = nfs3_proc_setattr(dentry, data->res.fattr, sattr); + nfs_post_op_update_inode(dentry->d_inode, data->res.fattr); dprintk("NFS reply setattr (post-create): %d\n", status); + if (status != 0) + goto out; } - if (status != 0) - goto out; status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); out: + nfs3_free_createdata(data); dprintk("NFS reply create: %d\n", status); return status; } @@ -452,40 +490,28 @@ static int nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, unsigned int len, struct iattr *sattr) { - struct nfs_fh fhandle; - struct nfs_fattr fattr, dir_attr; - struct nfs3_symlinkargs arg = { - .fromfh = NFS_FH(dir), - .fromname = dentry->d_name.name, - .fromlen = dentry->d_name.len, - .pages = &page, - .pathlen = len, - .sattr = sattr - }; - struct nfs3_diropres res = { - .dir_attr = &dir_attr, - .fh = &fhandle, - .fattr = &fattr - }; - struct rpc_message msg = { - .rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK], - .rpc_argp = &arg, - .rpc_resp = &res, - }; - int status; + struct nfs3_createdata *data; + int status = -ENOMEM; if (len > NFS3_MAXPATHLEN) return -ENAMETOOLONG; dprintk("NFS call symlink %s\n", dentry->d_name.name); - nfs_fattr_init(&dir_attr); - nfs_fattr_init(&fattr); - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_post_op_update_inode(dir, &dir_attr); - if (status != 0) + data = nfs3_alloc_createdata(); + if (data == NULL) goto out; - status = nfs_instantiate(dentry, &fhandle, &fattr); + data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK]; + data->arg.symlink.fromfh = NFS_FH(dir); + data->arg.symlink.fromname = dentry->d_name.name; + data->arg.symlink.fromlen = dentry->d_name.len; + data->arg.symlink.pages = &page; + data->arg.symlink.pathlen = len; + data->arg.symlink.sattr = sattr; + + status = nfs3_do_create(dir, dentry, data); + + nfs3_free_createdata(data); out: dprintk("NFS reply symlink: %d\n", status); return status; @@ -494,42 +520,31 @@ out: static int nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { - struct nfs_fh fhandle; - struct nfs_fattr fattr, dir_attr; - struct nfs3_mkdirargs arg = { - .fh = NFS_FH(dir), - .name = dentry->d_name.name, - .len = dentry->d_name.len, - .sattr = sattr - }; - struct nfs3_diropres res = { - .dir_attr = &dir_attr, - .fh = &fhandle, - .fattr = &fattr - }; - struct rpc_message msg = { - .rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR], - .rpc_argp = &arg, - .rpc_resp = &res, - }; + struct nfs3_createdata *data; int mode = sattr->ia_mode; - int status; + int status = -ENOMEM; dprintk("NFS call mkdir %s\n", dentry->d_name.name); sattr->ia_mode &= ~current->fs->umask; - nfs_fattr_init(&dir_attr); - nfs_fattr_init(&fattr); - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_post_op_update_inode(dir, &dir_attr); - if (status != 0) + data = nfs3_alloc_createdata(); + if (data == NULL) goto out; - status = nfs_instantiate(dentry, &fhandle, &fattr); + + data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR]; + data->arg.mkdir.fh = NFS_FH(dir); + data->arg.mkdir.name = dentry->d_name.name; + data->arg.mkdir.len = dentry->d_name.len; + data->arg.mkdir.sattr = sattr; + + status = nfs3_do_create(dir, dentry, data); if (status != 0) goto out; + status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); out: + nfs3_free_createdata(data); dprintk("NFS reply mkdir: %d\n", status); return status; } @@ -615,52 +630,50 @@ static int nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { - struct nfs_fh fh; - struct nfs_fattr fattr, dir_attr; - struct nfs3_mknodargs arg = { - .fh = NFS_FH(dir), - .name = dentry->d_name.name, - .len = dentry->d_name.len, - .sattr = sattr, - .rdev = rdev - }; - struct nfs3_diropres res = { - .dir_attr = &dir_attr, - .fh = &fh, - .fattr = &fattr - }; - struct rpc_message msg = { - .rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD], - .rpc_argp = &arg, - .rpc_resp = &res, - }; + struct nfs3_createdata *data; mode_t mode = sattr->ia_mode; - int status; - - switch (sattr->ia_mode & S_IFMT) { - case S_IFBLK: arg.type = NF3BLK; break; - case S_IFCHR: arg.type = NF3CHR; break; - case S_IFIFO: arg.type = NF3FIFO; break; - case S_IFSOCK: arg.type = NF3SOCK; break; - default: return -EINVAL; - } + int status = -ENOMEM; dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name, MAJOR(rdev), MINOR(rdev)); sattr->ia_mode &= ~current->fs->umask; - nfs_fattr_init(&dir_attr); - nfs_fattr_init(&fattr); - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); - nfs_post_op_update_inode(dir, &dir_attr); - if (status != 0) + data = nfs3_alloc_createdata(); + if (data == NULL) goto out; - status = nfs_instantiate(dentry, &fh, &fattr); + + data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD]; + data->arg.mknod.fh = NFS_FH(dir); + data->arg.mknod.name = dentry->d_name.name; + data->arg.mknod.len = dentry->d_name.len; + data->arg.mknod.sattr = sattr; + data->arg.mknod.rdev = rdev; + + switch (sattr->ia_mode & S_IFMT) { + case S_IFBLK: + data->arg.mknod.type = NF3BLK; + break; + case S_IFCHR: + data->arg.mknod.type = NF3CHR; + break; + case S_IFIFO: + data->arg.mknod.type = NF3FIFO; + break; + case S_IFSOCK: + data->arg.mknod.type = NF3SOCK; + break; + default: + status = -EINVAL; + goto out; + } + + status = nfs3_do_create(dir, dentry, data); if (status != 0) goto out; status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); out: + nfs3_free_createdata(data); dprintk("NFS reply mknod: %d\n", status); return status; } -- cgit v0.10.2 From f3d47a3a6a1484a93c8cfe1e8c8d4399c95199c7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 5 Jun 2008 15:17:39 -0400 Subject: NFS: Fix a preemption count leak in nfs_update_request The commit 2785259631697ebb0749a3782cca206e2e542939 (nfs: use GFP_NOFS preloads for radix-tree insertion) appears to have introduced a bug: We only want to call radix_tree_preload() once after creating a request. Calling it every time we loop after we created the request, will cause preemption count leaks. Signed-off-by: Trond Myklebust Cc: Nick Piggin diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f333848..dc62bc5 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -584,13 +584,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, /* Loop over all inode entries and see if we find * A request for the page we wish to update */ - if (new) { - if (radix_tree_preload(GFP_NOFS)) { - nfs_release_request(new); - return ERR_PTR(-ENOMEM); - } - } - spin_lock(&inode->i_lock); req = nfs_page_find_request_locked(page); if (req) { @@ -630,6 +623,10 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, new = nfs_create_request(ctx, inode, page, offset, bytes); if (IS_ERR(new)) return new; + if (radix_tree_preload(GFP_NOFS)) { + nfs_release_request(new); + return ERR_PTR(-ENOMEM); + } } /* We have a request for our page. -- cgit v0.10.2 From 2116271a347d1181b5497602c2bfada1de8fd53b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 20 May 2008 19:34:39 -0400 Subject: NFS: Add correct bounds checking to NFSv2 locks NFSv2 file locking currently fails the Connectathon tests, because the calls to the VFS locking code do not return an EINVAL error if the struct file_lock overflows the 32-bit boundaries. The problem is due to the fact that we occasionally call helpers from fs/locks.c in order to avoid RPC calls to the server when we know that a local process holds the lock. These helpers are, of course, always 64-bit enabled, so EINVAL is not returned in cases when it would if the call had gone to the NLM code. For consistency, we therefore add support for a bounds-checking helper. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/file.c b/fs/nfs/file.c index d84a3d8..7c73f06 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -593,6 +593,7 @@ out: static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) { struct inode * inode = filp->f_mapping->host; + int ret = -ENOLCK; dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n", inode->i_sb->s_id, inode->i_ino, @@ -602,13 +603,22 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) /* No mandatory locks over NFS */ if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) - return -ENOLCK; + goto out_err; + + if (NFS_PROTO(inode)->lock_check_bounds != NULL) { + ret = NFS_PROTO(inode)->lock_check_bounds(fl); + if (ret < 0) + goto out_err; + } if (IS_GETLK(cmd)) - return do_getlk(filp, cmd, fl); - if (fl->fl_type == F_UNLCK) - return do_unlk(filp, cmd, fl); - return do_setlk(filp, cmd, fl); + ret = do_getlk(filp, cmd, fl); + else if (fl->fl_type == F_UNLCK) + ret = do_unlk(filp, cmd, fl); + else + ret = do_setlk(filp, cmd, fl); +out_err: + return ret; } /* diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 03599bf..5c35b02 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -598,6 +598,29 @@ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl); } +/* Helper functions for NFS lock bounds checking */ +#define NFS_LOCK32_OFFSET_MAX ((__s32)0x7fffffffUL) +static int nfs_lock_check_bounds(const struct file_lock *fl) +{ + __s32 start, end; + + start = (__s32)fl->fl_start; + if ((loff_t)start != fl->fl_start) + goto out_einval; + + if (fl->fl_end != OFFSET_MAX) { + end = (__s32)fl->fl_end; + if ((loff_t)end != fl->fl_end) + goto out_einval; + } else + end = NFS_LOCK32_OFFSET_MAX; + + if (start < 0 || start > end) + goto out_einval; + return 0; +out_einval: + return -EINVAL; +} const struct nfs_rpc_ops nfs_v2_clientops = { .version = 2, /* protocol version */ @@ -633,4 +656,5 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .file_open = nfs_open, .file_release = nfs_release, .lock = nfs_proc_lock, + .lock_check_bounds = nfs_lock_check_bounds, }; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 24263bb..8d780de 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -832,6 +832,7 @@ struct nfs_rpc_ops { int (*file_open) (struct inode *, struct file *); int (*file_release) (struct inode *, struct file *); int (*lock)(struct file *, int, struct file_lock *); + int (*lock_check_bounds)(const struct file_lock *); void (*clear_acl_cache)(struct inode *); }; -- cgit v0.10.2 From 8b39f2b41033754e7ba669503d27268beb1b524a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 14 May 2008 19:48:25 -0700 Subject: SUNRPC: Ensure we exit early in case of an encode error All errors from call_encode(), with exception of EAGAIN are fatal, so we should immediately return instead of proceeding to xprt_transmit(). Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8945307..9503b4c 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -890,7 +890,6 @@ call_encode(struct rpc_task *task) task->tk_msg.rpc_argp); if (task->tk_status == -ENOMEM) { /* XXX: Is this sane? */ - rpc_delay(task, 3*HZ); task->tk_status = -EAGAIN; } } @@ -1048,8 +1047,14 @@ call_transmit(struct rpc_task *task) BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); call_encode(task); /* Did the encode result in an error condition? */ - if (task->tk_status != 0) + if (task->tk_status != 0) { + /* Was the error nonfatal? */ + if (task->tk_status == -EAGAIN) + rpc_delay(task, HZ >> 4); + else + rpc_exit(task, task->tk_status); return; + } } xprt_transmit(task); if (task->tk_status < 0) -- cgit v0.10.2 From b390c2b55c830eb3b64633fa8d8b8837e073e458 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:30:11 -0400 Subject: SUNRPC: An ENOMEM error from call_encode is always fatal The special 'ENOMEM' case that was previously flagged as non-fatal is bogus: auth_gss always returns EAGAIN for non-fatal errors, and may in fact return ENOMEM in the special case where xdr_buf_read_netobj runs out of preallocated buffer space (invariably a _fatal_ error, since there is no provision for preallocating larger buffers). Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 9503b4c..1af4f16 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -888,10 +888,6 @@ call_encode(struct rpc_task *task) task->tk_status = rpcauth_wrap_req(task, encode, req, p, task->tk_msg.rpc_argp); - if (task->tk_status == -ENOMEM) { - /* XXX: Is this sane? */ - task->tk_status = -EAGAIN; - } } /* -- cgit v0.10.2 From efc91ed0191e3fc62bb1c556ac93fc4e661214d2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:31:00 -0400 Subject: NFS: Optimise append writes with holes If a file is being extended, and we're creating a hole, we might as well declare the entire page to be up to date. This patch significantly improves the write performance for sparse files in the case where lseek(SEEK_END) is used to append several non-contiguous writes at intervals of < PAGE_SIZE. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7c73f06..7ac89a8 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -344,6 +344,26 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, unsigned offset = pos & (PAGE_CACHE_SIZE - 1); int status; + /* + * Zero any uninitialised parts of the page, and then mark the page + * as up to date if it turns out that we're extending the file. + */ + if (!PageUptodate(page)) { + unsigned pglen = nfs_page_length(page); + unsigned end = offset + len; + + if (pglen == 0) { + zero_user_segments(page, 0, offset, + end, PAGE_CACHE_SIZE); + SetPageUptodate(page); + } else if (end >= pglen) { + zero_user_segment(page, end, PAGE_CACHE_SIZE); + if (offset == 0) + SetPageUptodate(page); + } else + zero_user_segment(page, pglen, PAGE_CACHE_SIZE); + } + lock_kernel(); status = nfs_updatepage(file, page, offset, copied); unlock_kernel(); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index dc62bc5..eea2d2b 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -616,7 +616,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, spin_unlock(&inode->i_lock); radix_tree_preload_end(); req = new; - goto zero_page; + goto out; } spin_unlock(&inode->i_lock); @@ -649,19 +649,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, req->wb_offset = offset; req->wb_pgbase = offset; req->wb_bytes = max(end, rqend) - req->wb_offset; - goto zero_page; + goto out; } if (end > rqend) req->wb_bytes = end - req->wb_offset; - return req; -zero_page: - /* If this page might potentially be marked as up to date, - * then we need to zero any uninitalised data. */ - if (req->wb_pgbase == 0 && req->wb_bytes != PAGE_CACHE_SIZE - && !PageUptodate(req->wb_page)) - zero_user_segment(req->wb_page, req->wb_bytes, PAGE_CACHE_SIZE); +out: return req; } -- cgit v0.10.2 From 7e5f6146609eb9134fac7d1b6bfee43df1732188 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 25 May 2008 12:59:19 -0400 Subject: NFS: Revert commit 44dd151d Revert commit 44dd151d "NFS: Don't mark a written page as uptodate until it is on disk". While it is true that the write may fail, that is always the case. There is no reason why we should treat data on pages that are not already marked as PG_uptodate as being special. The only thing we gain is a noticeable slowdown when re-reading these pages. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/write.c b/fs/nfs/write.c index eea2d2b..ee6fcde 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -188,6 +188,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, } /* Update file length */ nfs_grow_file(page, offset, count); + nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); nfs_clear_page_tag_locked(req); return 0; } @@ -743,12 +744,7 @@ int nfs_updatepage(struct file *file, struct page *page, static void nfs_writepage_release(struct nfs_page *req) { - if (PageError(req->wb_page)) { - nfs_end_page_writeback(req->wb_page); - nfs_inode_remove_request(req); - } else if (!nfs_reschedule_unstable_write(req)) { - /* Set the PG_uptodate flag */ - nfs_mark_uptodate(req->wb_page, req->wb_pgbase, req->wb_bytes); + if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) { nfs_end_page_writeback(req->wb_page); nfs_inode_remove_request(req); } else @@ -1069,8 +1065,6 @@ static void nfs_writeback_release_full(void *calldata) dprintk(" marked for commit\n"); goto next; } - /* Set the PG_uptodate flag? */ - nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); dprintk(" OK\n"); remove_request: nfs_end_page_writeback(page); @@ -1309,9 +1303,6 @@ static void nfs_commit_release(void *calldata) * returned by the server against all stored verfs. */ if (!memcmp(req->wb_verf.verifier, data->verf.verifier, sizeof(data->verf.verifier))) { /* We have a match */ - /* Set the PG_uptodate flag */ - nfs_mark_uptodate(req->wb_page, req->wb_pgbase, - req->wb_bytes); nfs_inode_remove_request(req); dprintk(" OK\n"); goto next; -- cgit v0.10.2 From 0f38b873aeaae698c3693748438547c8493165fb Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:31:01 -0400 Subject: SUNRPC: Use GFP_NOFS when allocating credentials Since the credentials may be allocated during the call to rpc_new_task(), which again may be called by a memory allocator... Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index cc12d5f..bf7585b 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -146,7 +146,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - dest->data = kmemdup(p, len, GFP_KERNEL); + dest->data = kmemdup(p, len, GFP_NOFS); if (unlikely(dest->data == NULL)) return ERR_PTR(-ENOMEM); dest->len = len; @@ -171,7 +171,7 @@ gss_alloc_context(void) { struct gss_cl_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(*ctx), GFP_NOFS); if (ctx != NULL) { ctx->gc_proc = RPC_GSS_PROC_DATA; ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ @@ -341,7 +341,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) { struct gss_upcall_msg *gss_msg; - gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL); + gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); if (gss_msg != NULL) { INIT_LIST_HEAD(&gss_msg->list); rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); @@ -503,7 +503,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) if (mlen > MSG_BUF_MAXSIZE) goto out; err = -ENOMEM; - buf = kmalloc(mlen, GFP_KERNEL); + buf = kmalloc(mlen, GFP_NOFS); if (!buf) goto out; @@ -806,7 +806,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", acred->uid, auth->au_flavor); - if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) + if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) goto out_err; rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 60c3dba..ef45eba 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -70,7 +70,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - res->data = kmemdup(p, len, GFP_KERNEL); + res->data = kmemdup(p, len, GFP_NOFS); if (unlikely(res->data == NULL)) return ERR_PTR(-ENOMEM); res->len = len; @@ -131,7 +131,7 @@ gss_import_sec_context_kerberos(const void *p, struct krb5_ctx *ctx; int tmp; - if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) + if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) goto out_err; p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index 5deb4b6..035e1dd 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -76,7 +76,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len); if (unlikely(q > end || q < p)) return ERR_PTR(-EFAULT); - res->data = kmemdup(p, len, GFP_KERNEL); + res->data = kmemdup(p, len, GFP_NOFS); if (unlikely(res->data == NULL)) return ERR_PTR(-ENOMEM); return q; @@ -90,7 +90,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len, struct spkm3_ctx *ctx; int version; - if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) + if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) goto out_err; p = simple_get_bytes(p, end, &version, sizeof(version)); diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c index 6cdd241a..3308157 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_token.c +++ b/net/sunrpc/auth_gss/gss_spkm3_token.c @@ -90,7 +90,7 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits) int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen) { - if (!(out->data = kzalloc(explen,GFP_KERNEL))) + if (!(out->data = kzalloc(explen,GFP_NOFS))) return 0; out->len = explen; memcpy(out->data, in, enclen); diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 44920b9..46b2647 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -66,7 +66,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", acred->uid, acred->gid); - if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL))) + if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS))) return ERR_PTR(-ENOMEM); rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); -- cgit v0.10.2 From b5418383ef13f70528281546d02c15edc03d8567 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 18:31:02 -0400 Subject: NFS: do_setlk(): don't flush caches when we have a delegation Signed-off-by: Trond Myklebust diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7ac89a8..0213c21 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -602,7 +602,8 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) * This makes locking act as a cache coherency point. */ nfs_sync_mapping(filp->f_mapping); - nfs_zap_caches(inode); + if (!nfs_have_delegation(inode, FMODE_READ)) + nfs_zap_caches(inode); out: return status; } -- cgit v0.10.2 From 6fb1bc10303c0d88f635d014324432ab6ee49d1b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:04 -0400 Subject: NFS: Update help text for CONFIG_NFS_FS Clean up: refresh the help text for Kconfig items related to the NFS client. Remove obsolete URLs, and make the language consistent among the options. Also move the ROOT_NFS config option next to the options related to the NFS client. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/Kconfig b/fs/Kconfig index 2694648..1c16de9 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1544,10 +1544,6 @@ config UFS_FS The recently released UFS2 variant (used in FreeBSD 5.x) is READ-ONLY supported. - If you only intend to mount files from some other Unix over the - network using NFS, you don't need the UFS file system support (but - you need NFS file system support obviously). - Note that this option is generally not needed for floppies, since a good portable way to transport files and directories between unixes (and even other operating systems) is given by the tar program ("man @@ -1587,6 +1583,7 @@ menuconfig NETWORK_FILESYSTEMS Say Y here to get to see options for network filesystems and filesystem-related networking code, such as NFS daemon and RPCSEC security modules. + This option alone does not add any kernel code. If you say N, all options in this submenu will be skipped and @@ -1595,76 +1592,92 @@ menuconfig NETWORK_FILESYSTEMS if NETWORK_FILESYSTEMS config NFS_FS - tristate "NFS file system support" + tristate "NFS client support" depends on INET select LOCKD select SUNRPC select NFS_ACL_SUPPORT if NFS_V3_ACL help - If you are connected to some other (usually local) Unix computer - (using SLIP, PLIP, PPP or Ethernet) and want to mount files residing - on that computer (the NFS server) using the Network File Sharing - protocol, say Y. "Mounting files" means that the client can access - the files with usual UNIX commands as if they were sitting on the - client's hard disk. For this to work, the server must run the - programs nfsd and mountd (but does not need to have NFS file system - support enabled in its kernel). NFS is explained in the Network - Administrator's Guide, available from - , on its man page: "man - nfs", and in the NFS-HOWTO. - - A superior but less widely used alternative to NFS is provided by - the Coda file system; see "Coda file system support" below. + Choose Y here if you want to access files residing on other + computers using Sun's Network File System protocol. To compile + this file system support as a module, choose M here: the module + will be called nfs. - If you say Y here, you should have said Y to TCP/IP networking also. - This option would enlarge your kernel by about 27 KB. + To mount file systems exported by NFS servers, you also need to + install the user space mount.nfs command which can be found in + the Linux nfs-utils package, available from http://linux-nfs.org/. + Information about using the mount command is available in the + mount(8) man page. More detail about the Linux NFS client + implementation is available via the nfs(5) man page. - To compile this file system support as a module, choose M here: the - module will be called nfs. + Below you can choose which versions of the NFS protocol are + available in the kernel to mount NFS servers. Support for NFS + version 2 (RFC 1094) is always available when NFS_FS is selected. - If you are configuring a diskless machine which will mount its root - file system over NFS at boot time, say Y here and to "Kernel - level IP autoconfiguration" above and to "Root file system on NFS" - below. You cannot compile this driver as a module in this case. - There are two packages designed for booting diskless machines over - the net: netboot, available from - , and Etherboot, - available from . + To configure a system which mounts its root file system via NFS + at boot time, say Y here, select "Kernel level IP + autoconfiguration" in the NETWORK menu, and select "Root file + system on NFS" below. You cannot compile this file system as a + module in this case. - If you don't know what all this is about, say N. + If unsure, say N. config NFS_V3 - bool "Provide NFSv3 client support" + bool "NFS client support for NFS version 3" depends on NFS_FS help - Say Y here if you want your NFS client to be able to speak version - 3 of the NFS protocol. + This option enables support for version 3 of the NFS protocol + (RFC 1813) in the kernel's NFS client. If unsure, say Y. config NFS_V3_ACL - bool "Provide client support for the NFSv3 ACL protocol extension" + bool "NFS client support for the NFSv3 ACL protocol extension" depends on NFS_V3 help - Implement the NFSv3 ACL protocol extension for manipulating POSIX - Access Control Lists. The server should also be compiled with - the NFSv3 ACL protocol extension; see the CONFIG_NFSD_V3_ACL option. + Some NFS servers support an auxiliary NFSv3 ACL protocol that + Sun added to Solaris but never became an official part of the + NFS version 3 protocol. This protocol extension allows + applications on NFS clients to manipulate POSIX Access Control + Lists on files residing on NFS servers. NFS servers enforce + ACLs on local files whether this protocol is available or not. + + Choose Y here if your NFS server supports the Solaris NFSv3 ACL + protocol extension and you want your NFS client to allow + applications to access and modify ACLs on files on the server. + + Most NFS servers don't support the Solaris NFSv3 ACL protocol + extension. You can choose N here or specify the "noacl" mount + option to prevent your NFS client from trying to use the NFSv3 + ACL protocol. If unsure, say N. config NFS_V4 - bool "Provide NFSv4 client support (EXPERIMENTAL)" + bool "NFS client support for NFS version 4 (EXPERIMENTAL)" depends on NFS_FS && EXPERIMENTAL select RPCSEC_GSS_KRB5 help - Say Y here if you want your NFS client to be able to speak the newer - version 4 of the NFS protocol. + This option enables support for version 4 of the NFS protocol + (RFC 3530) in the kernel's NFS client. - Note: Requires auxiliary userspace daemons which may be found on - http://www.citi.umich.edu/projects/nfsv4/ + To mount NFS servers using NFSv4, you also need to install user + space programs which can be found in the Linux nfs-utils package, + available from http://linux-nfs.org/. If unsure, say N. +config ROOT_NFS + bool "Root file system on NFS" + depends on NFS_FS=y && IP_PNP + help + If you want your system to mount its root file system via NFS, + choose Y here. This is common practice for managing systems + without local permanent storage. For details, read + . + + Most people say N here. + config NFSD tristate "NFS server support" depends on INET @@ -1746,20 +1759,6 @@ config NFSD_V4 If unsure, say N. -config ROOT_NFS - bool "Root file system on NFS" - depends on NFS_FS=y && IP_PNP - help - If you want your Linux box to mount its whole root file system (the - one containing the directory /) from some other computer over the - net via NFS (presumably because your box doesn't have a hard disk), - say Y. Read for - details. It is likely that in this case, you also want to say Y to - "Kernel level IP autoconfiguration" so that your box can discover - its network address at boot time. - - Most people say N here. - config LOCKD tristate -- cgit v0.10.2 From 3748f1e447ac1dbf45f33ee7491a008a8bb5cdf0 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:12 -0400 Subject: SUNRPC: Add a function to display the name of an RPC procedure Improve debugging messages in call_start() and call_verify() by having them show the RPC procedure name instead of the procedure number. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 1af4f16..68ea6dd 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -690,6 +690,21 @@ rpc_restart_call(struct rpc_task *task) } EXPORT_SYMBOL_GPL(rpc_restart_call); +#ifdef RPC_DEBUG +static const char *rpc_proc_name(const struct rpc_task *task) +{ + const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; + + if (proc) { + if (proc->p_name) + return proc->p_name; + else + return "NULL"; + } else + return "no proc"; +} +#endif + /* * 0. Initial state * @@ -701,9 +716,9 @@ call_start(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; - dprintk("RPC: %5u call_start %s%d proc %d (%s)\n", task->tk_pid, + dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid, clnt->cl_protname, clnt->cl_vers, - task->tk_msg.rpc_proc->p_proc, + rpc_proc_name(task), (RPC_IS_ASYNC(task) ? "async" : "sync")); /* Increment call count */ @@ -1432,10 +1447,10 @@ call_verify(struct rpc_task *task) error = -EPROTONOSUPPORT; goto out_err; case RPC_PROC_UNAVAIL: - dprintk("RPC: %5u %s: proc %p unsupported by program %u, " + dprintk("RPC: %5u %s: proc %s unsupported by program %u, " "version %u on server %s\n", task->tk_pid, __func__, - task->tk_msg.rpc_proc, + rpc_proc_name(task), task->tk_client->cl_prog, task->tk_client->cl_vers, task->tk_client->cl_server); -- cgit v0.10.2 From b0e1c57ea00302c3ac541ffd37e7db07d13cd674 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:19 -0400 Subject: SUNRPC: Rename "call_" functions that are no longer FSM states The RPC client uses a finite state machine to move RPC tasks through each step of an RPC request. Each state is contained in a function in net/sunrpc/clnt.c, and named call_foo. Some of the functions named call_foo have changed over the past few years and are no longer states in the FSM. These include: call_encode, call_header, and call_verify. As a clean up, rename the functions that have changed. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 68ea6dd..ab8038d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -58,7 +58,6 @@ static void call_start(struct rpc_task *task); static void call_reserve(struct rpc_task *task); static void call_reserveresult(struct rpc_task *task); static void call_allocate(struct rpc_task *task); -static void call_encode(struct rpc_task *task); static void call_decode(struct rpc_task *task); static void call_bind(struct rpc_task *task); static void call_bind_status(struct rpc_task *task); @@ -70,9 +69,9 @@ static void call_refreshresult(struct rpc_task *task); static void call_timeout(struct rpc_task *task); static void call_connect(struct rpc_task *task); static void call_connect_status(struct rpc_task *task); -static __be32 * call_header(struct rpc_task *task); -static __be32 * call_verify(struct rpc_task *task); +static __be32 *rpc_encode_header(struct rpc_task *task); +static __be32 *rpc_verify_header(struct rpc_task *task); static int rpc_ping(struct rpc_clnt *clnt, int flags); static void rpc_register_client(struct rpc_clnt *clnt) @@ -876,7 +875,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) * 3. Encode arguments of an RPC call */ static void -call_encode(struct rpc_task *task) +rpc_xdr_encode(struct rpc_task *task) { struct rpc_rqst *req = task->tk_rqstp; kxdrproc_t encode; @@ -891,13 +890,14 @@ call_encode(struct rpc_task *task) (char *)req->rq_buffer + req->rq_callsize, req->rq_rcvsize); - /* Encode header and provided arguments */ - encode = task->tk_msg.rpc_proc->p_encode; - if (!(p = call_header(task))) { - printk(KERN_INFO "RPC: call_header failed, exit EIO\n"); + p = rpc_encode_header(task); + if (p == NULL) { + printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n"); rpc_exit(task, -EIO); return; } + + encode = task->tk_msg.rpc_proc->p_encode; if (encode == NULL) return; @@ -1056,7 +1056,7 @@ call_transmit(struct rpc_task *task) /* Encode here so that rpcsec_gss can use correct sequence number. */ if (rpc_task_need_encode(task)) { BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); - call_encode(task); + rpc_xdr_encode(task); /* Did the encode result in an error condition? */ if (task->tk_status != 0) { /* Was the error nonfatal? */ @@ -1240,8 +1240,7 @@ call_decode(struct rpc_task *task) goto out_retry; } - /* Verify the RPC header */ - p = call_verify(task); + p = rpc_verify_header(task); if (IS_ERR(p)) { if (p == ERR_PTR(-EAGAIN)) goto out_retry; @@ -1259,7 +1258,7 @@ call_decode(struct rpc_task *task) return; out_retry: task->tk_status = 0; - /* Note: call_verify() may have freed the RPC slot */ + /* Note: rpc_verify_header() may have freed the RPC slot */ if (task->tk_rqstp == req) { req->rq_received = req->rq_rcv_buf.len = 0; if (task->tk_client->cl_discrtry) @@ -1306,11 +1305,8 @@ call_refreshresult(struct rpc_task *task) return; } -/* - * Call header serialization - */ static __be32 * -call_header(struct rpc_task *task) +rpc_encode_header(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; struct rpc_rqst *req = task->tk_rqstp; @@ -1330,11 +1326,8 @@ call_header(struct rpc_task *task) return p; } -/* - * Reply header verification - */ static __be32 * -call_verify(struct rpc_task *task) +rpc_verify_header(struct rpc_task *task) { struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; int len = task->tk_rqstp->rq_rcv_buf.len >> 2; @@ -1408,7 +1401,7 @@ call_verify(struct rpc_task *task) task->tk_action = call_bind; goto out_retry; case RPC_AUTH_TOOWEAK: - printk(KERN_NOTICE "call_verify: server %s requires stronger " + printk(KERN_NOTICE "RPC: server %s requires stronger " "authentication.\n", task->tk_client->cl_server); break; default: -- cgit v0.10.2 From 68a23ee94e3a06819f5a39d64f2e1f3131bab12d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:26 -0400 Subject: SUNRPC: Don't display the rpc_show_tasks header if there are no tasks Clean up: don't display the rpc_show_tasks column header unless there is at least one task to display. As far as I can tell, it is safe to let the list_for_each_entry macro decide that each list is empty. scripts/checkpatch.pl also wants a KERN_FOO at the start of any newly added printk() calls, so this and subsequent patches will also add KERN_INFO. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index ab8038d..7dda328 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1526,24 +1526,30 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int EXPORT_SYMBOL_GPL(rpc_call_null); #ifdef RPC_DEBUG +static void rpc_show_header(void) +{ + printk(KERN_INFO "-pid- proc flgs status -client- -prog- --rqstp- " + "-timeout -rpcwait -action- ---ops--\n"); +} + void rpc_show_tasks(void) { struct rpc_clnt *clnt; struct rpc_task *t; + int header = 0; spin_lock(&rpc_client_lock); - if (list_empty(&all_clients)) - goto out; - printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " - "-rpcwait -action- ---ops--\n"); list_for_each_entry(clnt, &all_clients, cl_clients) { - if (list_empty(&clnt->cl_tasks)) - continue; spin_lock(&clnt->cl_lock); list_for_each_entry(t, &clnt->cl_tasks, tk_task) { const char *rpc_waitq = "none"; int proc; + if (!header) { + rpc_show_header(); + header++; + } + if (t->tk_msg.rpc_proc) proc = t->tk_msg.rpc_proc->p_proc; else @@ -1563,7 +1569,6 @@ void rpc_show_tasks(void) } spin_unlock(&clnt->cl_lock); } -out: spin_unlock(&rpc_client_lock); } #endif -- cgit v0.10.2 From 38e886e0c18975543938519254fc9bf0829c75a3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:33 -0400 Subject: SUNRPC: Refactor rpc_show_tasks Clean up: move the logic that displays each task to its own function. This removes indentation and makes future changes easier. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 7dda328..7964a98 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1532,40 +1532,42 @@ static void rpc_show_header(void) "-timeout -rpcwait -action- ---ops--\n"); } +static void rpc_show_task(const struct rpc_clnt *clnt, + const struct rpc_task *task) +{ + const char *rpc_waitq = "none"; + int proc = -1; + + if (task->tk_msg.rpc_proc) + proc = task->tk_msg.rpc_proc->p_proc; + + if (RPC_IS_QUEUED(task)) + rpc_waitq = rpc_qname(task->tk_waitqueue); + + printk(KERN_INFO "%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", + task->tk_pid, proc, + task->tk_flags, task->tk_status, + clnt, clnt->cl_prog, + task->tk_rqstp, task->tk_timeout, + rpc_waitq, + task->tk_action, task->tk_ops); +} + void rpc_show_tasks(void) { struct rpc_clnt *clnt; - struct rpc_task *t; + struct rpc_task *task; int header = 0; spin_lock(&rpc_client_lock); list_for_each_entry(clnt, &all_clients, cl_clients) { spin_lock(&clnt->cl_lock); - list_for_each_entry(t, &clnt->cl_tasks, tk_task) { - const char *rpc_waitq = "none"; - int proc; - + list_for_each_entry(task, &clnt->cl_tasks, tk_task) { if (!header) { rpc_show_header(); header++; } - - if (t->tk_msg.rpc_proc) - proc = t->tk_msg.rpc_proc->p_proc; - else - proc = -1; - - if (RPC_IS_QUEUED(t)) - rpc_waitq = rpc_qname(t->tk_waitqueue); - - printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", - t->tk_pid, proc, - t->tk_flags, t->tk_status, - t->tk_client, - (t->tk_client ? t->tk_client->cl_prog : 0), - t->tk_rqstp, t->tk_timeout, - rpc_waitq, - t->tk_action, t->tk_ops); + rpc_show_task(clnt, task); } spin_unlock(&clnt->cl_lock); } -- cgit v0.10.2 From cb3997b5a0b21864368bd1bd1d0929f9304fb6d9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 21 May 2008 17:09:41 -0400 Subject: SUNRPC: Display some debugging information as text rather than numbers In rpc_show_tasks(), display the program name, version number, procedure name and tk_action as human-readable variable-length text fields rather than columnar numbers. Doing the symbol lookup here helps in cases where we have actual debugging output from a kernel log, but don't have access to the kernel image or RPC module that generated the output. Sample output: -pid- flgs status -client- --rqstp- -timeout ---ops-- 5608 0001 -11 eeb42690 f6d93710 0 f8fa1764 nfsv3 WRITE a:call_transmit_status q:none 5609 0001 -11 eeb42690 f6d937e0 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5610 0001 -11 eeb42690 f6d93230 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5611 0001 -11 eeb42690 f6d93300 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5612 0001 -11 eeb42690 f6d93090 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5613 0001 -11 eeb42690 f6d933d0 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5614 0001 -11 eeb42690 f6d93cc0 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5615 0001 -11 eeb42690 f6d93a50 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5616 0001 -11 eeb42690 f6d93640 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5617 0001 -11 eeb42690 f6d93b20 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5618 0001 -11 eeb42690 f6d93160 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 7964a98..0530eea 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -1528,29 +1529,31 @@ EXPORT_SYMBOL_GPL(rpc_call_null); #ifdef RPC_DEBUG static void rpc_show_header(void) { - printk(KERN_INFO "-pid- proc flgs status -client- -prog- --rqstp- " - "-timeout -rpcwait -action- ---ops--\n"); + printk(KERN_INFO "-pid- flgs status -client- --rqstp- " + "-timeout ---ops--\n"); } static void rpc_show_task(const struct rpc_clnt *clnt, const struct rpc_task *task) { const char *rpc_waitq = "none"; - int proc = -1; - - if (task->tk_msg.rpc_proc) - proc = task->tk_msg.rpc_proc->p_proc; + char *p, action[KSYM_SYMBOL_LEN]; if (RPC_IS_QUEUED(task)) rpc_waitq = rpc_qname(task->tk_waitqueue); - printk(KERN_INFO "%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", - task->tk_pid, proc, - task->tk_flags, task->tk_status, - clnt, clnt->cl_prog, - task->tk_rqstp, task->tk_timeout, - rpc_waitq, - task->tk_action, task->tk_ops); + /* map tk_action pointer to a function name; then trim off + * the "+0x0 [sunrpc]" */ + sprint_symbol(action, (unsigned long)task->tk_action); + p = strchr(action, '+'); + if (p) + *p = '\0'; + + printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", + task->tk_pid, task->tk_flags, task->tk_status, + clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, + clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), + action, rpc_waitq); } void rpc_show_tasks(void) -- cgit v0.10.2 From 549177863bac22f23663ee9f70c4e3b9fb269f2c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 27 May 2008 16:29:07 -0400 Subject: NFS: Make nfs_fsync methods consistent Clean up: Report the same debugging info, count function calls the same, and use similar function naming in nfs_fsync_dir() and nfs_fsync(). Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 982a206..5d73fbd 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -629,10 +629,11 @@ out: */ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) { - dfprintk(VFS, "NFS: fsync_dir(%s/%s) datasync %d\n", + dfprintk(VFS, "NFS: fsync dir(%s/%s) datasync %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, datasync); + nfs_inc_stats(dentry->d_inode, NFSIOS_VFSFSYNC); return 0; } diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 0213c21..1789de2 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -50,7 +50,7 @@ static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, unsigned long nr_segs, loff_t pos); static int nfs_file_flush(struct file *, fl_owner_t id); -static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); +static int nfs_file_fsync(struct file *, struct dentry *dentry, int datasync); static int nfs_check_flags(int flags); static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); @@ -72,7 +72,7 @@ const struct file_operations nfs_file_operations = { .open = nfs_file_open, .flush = nfs_file_flush, .release = nfs_file_release, - .fsync = nfs_fsync, + .fsync = nfs_file_fsync, .lock = nfs_lock, .flock = nfs_flock, .splice_read = nfs_file_splice_read, @@ -181,7 +181,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) } /* - * Helper for nfs_file_flush() and nfs_fsync() + * Helper for nfs_file_flush() and nfs_file_fsync() * * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to * disk, but it retrieves and clears ctx->error after synching, despite @@ -296,12 +296,14 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) * whether any write errors occurred for this process. */ static int -nfs_fsync(struct file *file, struct dentry *dentry, int datasync) +nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) { struct nfs_open_context *ctx = nfs_file_open_context(file); struct inode *inode = dentry->d_inode; - dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); + dfprintk(VFS, "NFS: fsync file(%s/%s) datasync %d\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + datasync); nfs_inc_stats(inode, NFSIOS_VFSFSYNC); return nfs_do_fsync(ctx, inode); -- cgit v0.10.2 From b84e06c58fdefdc42931f771dc295e63f4b27365 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:34 -0400 Subject: NFS: Make nfs_llseek methods consistent Clean up: Report the same debugging info in nfs_llseek_dir() and nfs_llseek_file(). Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5d73fbd..2457106 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -603,7 +603,15 @@ out: static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) { - mutex_lock(&filp->f_path.dentry->d_inode->i_mutex); + struct dentry *dentry = filp->f_path.dentry; + struct inode *inode = dentry->d_inode; + + dfprintk(VFS, "NFS: llseek dir(%s/%s, %lld, %d)\n", + dentry->d_parent->d_name.name, + dentry->d_name.name, + offset, origin); + + mutex_lock(&inode->i_mutex); switch (origin) { case 1: offset += filp->f_pos; @@ -619,7 +627,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) nfs_file_open_context(filp)->dir_cookie = 0; } out: - mutex_unlock(&filp->f_path.dentry->d_inode->i_mutex); + mutex_unlock(&inode->i_mutex); return offset; } diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 1789de2..cef3636 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -170,6 +170,11 @@ force_reval: static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) { + dfprintk(VFS, "NFS: llseek file(%s/%s, %lld, %d)\n", + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name, + offset, origin); + /* origin == SEEK_END => we must revalidate the cached file length */ if (origin == SEEK_END) { struct inode *inode = filp->f_mapping->host; -- cgit v0.10.2 From cc0dd2d1052aede2946ad1338a8f6f5d5c604740 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:42 -0400 Subject: NFS: Make nfs_open methods consistent Clean up: Report the same debugging info and count function calls the same for files and directories in nfs_opendir() and nfs_file_open(). Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 2457106..c962233 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -133,8 +133,11 @@ nfs_opendir(struct inode *inode, struct file *filp) { int res; - dfprintk(VFS, "NFS: opendir(%s/%ld)\n", - inode->i_sb->s_id, inode->i_ino); + dfprintk(VFS, "NFS: open dir(%s/%s)\n", + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name); + + nfs_inc_stats(inode, NFSIOS_VFSOPEN); lock_kernel(); /* Call generic open code in order to cache credentials */ diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cef3636..202408d 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -119,6 +119,10 @@ nfs_file_open(struct inode *inode, struct file *filp) { int res; + dfprintk(VFS, "NFS: open file(%s/%s)\n", + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name); + res = nfs_check_flags(filp->f_flags); if (res) return res; -- cgit v0.10.2 From b7eaefaa8722fd98e5c2632640d1abd2b0c83e84 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:50 -0400 Subject: NFS: Add debugging facility for NFS aops Recent work in fs/nfs/file.c neglected to add appropriate trace debugging for the NFS client's address space operations. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 202408d..6c447a3 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -335,6 +335,11 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping, struct page *page; index = pos >> PAGE_CACHE_SHIFT; + dfprintk(PAGECACHE, "NFS: write_begin(%s/%s(%ld), %u@%lld)\n", + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, + mapping->host->i_ino, len, (long long) pos); + page = __grab_cache_page(mapping, index); if (!page) return -ENOMEM; @@ -355,6 +360,11 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, unsigned offset = pos & (PAGE_CACHE_SIZE - 1); int status; + dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n", + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, + mapping->host->i_ino, len, (long long) pos); + /* * Zero any uninitialised parts of the page, and then mark the page * as up to date if it turns out that we're extending the file. @@ -389,6 +399,8 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, static void nfs_invalidate_page(struct page *page, unsigned long offset) { + dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %lu)\n", page, offset); + if (offset != 0) return; /* Cancel any unstarted writes on this page */ @@ -397,13 +409,20 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset) static int nfs_release_page(struct page *page, gfp_t gfp) { + dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); + /* If PagePrivate() is set, then the page is not freeable */ return 0; } static int nfs_launder_page(struct page *page) { - return nfs_wb_page(page->mapping->host, page); + struct inode *inode = page->mapping->host; + + dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n", + inode->i_ino, (long long)page_offset(page)); + + return nfs_wb_page(inode, page); } const struct address_space_operations nfs_file_aops = { @@ -423,13 +442,19 @@ const struct address_space_operations nfs_file_aops = { static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) { struct file *filp = vma->vm_file; + struct dentry *dentry = filp->f_path.dentry; unsigned pagelen; int ret = -EINVAL; struct address_space *mapping; + dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + filp->f_mapping->host->i_ino, + (long long)page_offset(page)); + lock_page(page); mapping = page->mapping; - if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) + if (mapping != dentry->d_inode->i_mapping) goto out_unlock; ret = 0; -- cgit v0.10.2 From 6da24bc9cfc645c619992e39aab09747164c9f14 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:55:58 -0400 Subject: NFS: Use NFSDBG_FILE for all fops Clean up: some fops use NFSDBG_FILE, some use NFSDBG_VFS. Let's use NFSDBG_FILE for all fops, and consistently report file names instead of inode numbers. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c962233..b194066 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -133,7 +133,7 @@ nfs_opendir(struct inode *inode, struct file *filp) { int res; - dfprintk(VFS, "NFS: open dir(%s/%s)\n", + dfprintk(FILE, "NFS: open dir(%s/%s)\n", filp->f_path.dentry->d_parent->d_name.name, filp->f_path.dentry->d_name.name); @@ -531,7 +531,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) struct nfs_fattr fattr; long res; - dfprintk(VFS, "NFS: readdir(%s/%s) starting at cookie %Lu\n", + dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", dentry->d_parent->d_name.name, dentry->d_name.name, (long long)filp->f_pos); nfs_inc_stats(inode, NFSIOS_VFSGETDENTS); @@ -598,7 +598,7 @@ out: unlock_kernel(); if (res > 0) res = 0; - dfprintk(VFS, "NFS: readdir(%s/%s) returns %ld\n", + dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n", dentry->d_parent->d_name.name, dentry->d_name.name, res); return res; @@ -609,7 +609,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; - dfprintk(VFS, "NFS: llseek dir(%s/%s, %lld, %d)\n", + dfprintk(FILE, "NFS: llseek dir(%s/%s, %lld, %d)\n", dentry->d_parent->d_name.name, dentry->d_name.name, offset, origin); @@ -640,7 +640,7 @@ out: */ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) { - dfprintk(VFS, "NFS: fsync dir(%s/%s) datasync %d\n", + dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, datasync); diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 4757a2b..08f6b04 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -890,7 +890,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, count = iov_length(iov, nr_segs); nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); - dprintk("nfs: direct read(%s/%s, %zd@%Ld)\n", + dfprintk(FILE, "NFS: direct read(%s/%s, %zd@%Ld)\n", file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, count, (long long) pos); @@ -947,7 +947,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, count = iov_length(iov, nr_segs); nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count); - dfprintk(VFS, "nfs: direct write(%s/%s, %zd@%Ld)\n", + dfprintk(FILE, "NFS: direct write(%s/%s, %zd@%Ld)\n", file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, count, (long long) pos); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 6c447a3..78b26f8 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -119,7 +119,7 @@ nfs_file_open(struct inode *inode, struct file *filp) { int res; - dfprintk(VFS, "NFS: open file(%s/%s)\n", + dprintk("NFS: open file(%s/%s)\n", filp->f_path.dentry->d_parent->d_name.name, filp->f_path.dentry->d_name.name); @@ -137,9 +137,15 @@ nfs_file_open(struct inode *inode, struct file *filp) static int nfs_file_release(struct inode *inode, struct file *filp) { + struct dentry *dentry = filp->f_path.dentry; + + dprintk("NFS: release(%s/%s)\n", + dentry->d_parent->d_name.name, + dentry->d_name.name); + /* Ensure that dirty pages are flushed out with the right creds */ if (filp->f_mode & FMODE_WRITE) - nfs_wb_all(filp->f_path.dentry->d_inode); + nfs_wb_all(dentry->d_inode); nfs_inc_stats(inode, NFSIOS_VFSRELEASE); return NFS_PROTO(inode)->file_release(inode, filp); } @@ -174,7 +180,7 @@ force_reval: static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) { - dfprintk(VFS, "NFS: llseek file(%s/%s, %lld, %d)\n", + dprintk("NFS: llseek file(%s/%s, %lld, %d)\n", filp->f_path.dentry->d_parent->d_name.name, filp->f_path.dentry->d_name.name, offset, origin); @@ -216,16 +222,18 @@ static int nfs_do_fsync(struct nfs_open_context *ctx, struct inode *inode) /* * Flush all dirty pages, and check for write errors. - * */ static int nfs_file_flush(struct file *file, fl_owner_t id) { struct nfs_open_context *ctx = nfs_file_open_context(file); - struct inode *inode = file->f_path.dentry->d_inode; + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = dentry->d_inode; int status; - dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); + dprintk("NFS: flush(%s/%s)\n", + dentry->d_parent->d_name.name, + dentry->d_name.name); if ((file->f_mode & FMODE_WRITE) == 0) return 0; @@ -250,7 +258,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov, if (iocb->ki_filp->f_flags & O_DIRECT) return nfs_file_direct_read(iocb, iov, nr_segs, pos); - dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", + dprintk("NFS: read(%s/%s, %lu@%lu)\n", dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long) pos); @@ -270,7 +278,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos, struct inode *inode = dentry->d_inode; ssize_t res; - dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n", + dprintk("NFS: splice_read(%s/%s, %lu@%Lu)\n", dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long long) *ppos); @@ -287,7 +295,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) struct inode *inode = dentry->d_inode; int status; - dfprintk(VFS, "nfs: mmap(%s/%s)\n", + dprintk("NFS: mmap(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); status = nfs_revalidate_mapping(inode, file->f_mapping); @@ -310,7 +318,7 @@ nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) struct nfs_open_context *ctx = nfs_file_open_context(file); struct inode *inode = dentry->d_inode; - dfprintk(VFS, "NFS: fsync file(%s/%s) datasync %d\n", + dprintk("NFS: fsync file(%s/%s) datasync %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, datasync); @@ -502,9 +510,9 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, if (iocb->ki_filp->f_flags & O_DIRECT) return nfs_file_direct_write(iocb, iov, nr_segs, pos); - dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n", + dprintk("NFS: write(%s/%s, %lu@%Ld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino, (unsigned long) count, (long long) pos); + (unsigned long) count, (long long) pos); result = -EBUSY; if (IS_SWAPFILE(inode)) @@ -649,13 +657,15 @@ out: */ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) { - struct inode * inode = filp->f_mapping->host; + struct inode *inode = filp->f_mapping->host; int ret = -ENOLCK; - dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n", - inode->i_sb->s_id, inode->i_ino, + dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n", + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name, fl->fl_type, fl->fl_flags, (long long)fl->fl_start, (long long)fl->fl_end); + nfs_inc_stats(inode, NFSIOS_VFSLOCK); /* No mandatory locks over NFS */ @@ -683,9 +693,9 @@ out_err: */ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) { - dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", - filp->f_path.dentry->d_inode->i_sb->s_id, - filp->f_path.dentry->d_inode->i_ino, + dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n", + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name, fl->fl_type, fl->fl_flags); /* @@ -708,12 +718,15 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) return do_setlk(filp, cmd, fl); } +/* + * There is no protocol support for leases, so we have no way to implement + * them correctly in the face of opens by other clients. + */ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) { - /* - * There is no protocol support for leases, so we have no way - * to implement them correctly in the face of opens by other - * clients. - */ + dprintk("NFS: setlease(%s/%s, arg=%ld)\n", + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, arg); + return -EINVAL; } -- cgit v0.10.2 From 48186c7d5734a6b137f9186b37f6dc98097d0429 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:56:05 -0400 Subject: NFS: Fix trace debugging nits in write.c Clean up: fix a few dprintk messages that still need to show the RPC task ID correctly, and be sure we use the preferred %lld or %llu instead of %Ld or %Lu. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ee6fcde..21d8a48 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -713,10 +713,10 @@ int nfs_updatepage(struct file *file, struct page *page, nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); - dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", + dprintk("NFS: nfs_updatepage(%s/%s %d@%lld)\n", file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, count, - (long long)(page_offset(page) +offset)); + (long long)(page_offset(page) + offset)); /* If we're not using byte range locks, and we know the page * is up to date, it may be more efficient to extend the write @@ -736,7 +736,7 @@ int nfs_updatepage(struct file *file, struct page *page, else __set_page_dirty_nobuffers(page); - dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", + dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", status, (long long)i_size_read(inode)); return status; } @@ -821,7 +821,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req, NFS_PROTO(inode)->write_setup(data, &msg); dprintk("NFS: %5u initiated write call " - "(req %s/%Ld, %u bytes @ offset %Lu)\n", + "(req %s/%lld, %u bytes @ offset %llu)\n", data->task.tk_pid, inode->i_sb->s_id, (long long)NFS_FILEID(inode), @@ -965,13 +965,13 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) { struct nfs_write_data *data = calldata; - struct nfs_page *req = data->req; - dprintk("NFS: write (%s/%Ld %d@%Ld)", - req->wb_context->path.dentry->d_inode->i_sb->s_id, - (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), - req->wb_bytes, - (long long)req_offset(req)); + dprintk("NFS: %5u write(%s/%lld %d@%lld)", + task->tk_pid, + data->req->wb_context->path.dentry->d_inode->i_sb->s_id, + (long long) + NFS_FILEID(data->req->wb_context->path.dentry->d_inode), + data->req->wb_bytes, (long long)req_offset(data->req)); nfs_writeback_done(task, data); } @@ -1045,7 +1045,8 @@ static void nfs_writeback_release_full(void *calldata) nfs_list_remove_request(req); - dprintk("NFS: write (%s/%Ld %d@%Ld)", + dprintk("NFS: %5u write (%s/%lld %d@%lld)", + data->task.tk_pid, req->wb_context->path.dentry->d_inode->i_sb->s_id, (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), req->wb_bytes, @@ -1118,7 +1119,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) static unsigned long complain; if (time_before(complain, jiffies)) { - dprintk("NFS: faulty NFS server %s:" + dprintk("NFS: faulty NFS server %s:" " (committed = %d) != (stable = %d)\n", NFS_SERVER(data->inode)->nfs_client->cl_hostname, resp->verf->committed, argp->stable); @@ -1287,7 +1288,7 @@ static void nfs_commit_release(void *calldata) dec_bdi_stat(req->wb_page->mapping->backing_dev_info, BDI_RECLAIMABLE); - dprintk("NFS: commit (%s/%Ld %d@%Ld)", + dprintk("NFS: commit (%s/%lld %d@%lld)", req->wb_context->path.dentry->d_inode->i_sb->s_id, (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), req->wb_bytes, -- cgit v0.10.2 From cd983ef81b9d79573848dabf81277c7314220257 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 11 Jun 2008 17:56:13 -0400 Subject: SUNRPC: Remove obsolete messages during transport connect Recent changes to the RPC client's transport connect logic make connect status values ECONNREFUSED and ECONNRESET impossible. Clean up xprt_connect_status() to account for these changes. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e1770f7..67996bd 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -690,7 +690,7 @@ static void xprt_connect_status(struct rpc_task *task) { struct rpc_xprt *xprt = task->tk_xprt; - if (task->tk_status >= 0) { + if (task->tk_status == 0) { xprt->stat.connect_count++; xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start; dprintk("RPC: %5u xprt_connect_status: connection established\n", @@ -699,12 +699,6 @@ static void xprt_connect_status(struct rpc_task *task) } switch (task->tk_status) { - case -ECONNREFUSED: - case -ECONNRESET: - dprintk("RPC: %5u xprt_connect_status: server %s refused " - "connection\n", task->tk_pid, - task->tk_client->cl_server); - break; case -ENOTCONN: dprintk("RPC: %5u xprt_connect_status: connection broken\n", task->tk_pid); -- cgit v0.10.2 From c2d946e55e1be20a7443918e3b7497b905e6b3f7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 01:08:00 +0300 Subject: fs/nfs/nfsroot.c: remove CVS keyword This patch removes a CVS keyword that wasn't updated for a long time from a comment. Signed-off-by: Adrian Bunk Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 531379d..15afe3a 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -1,6 +1,4 @@ /* - * $Id: nfsroot.c,v 1.45 1998/03/07 10:44:46 mj Exp $ - * * Copyright (C) 1995, 1996 Gero Kuhlmann * * Allow an NFS filesystem to be mounted as root. The way this works is: -- cgit v0.10.2 From 48b605f83c920d8daa50e43fc2c7f718e04c7bfa Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 10 Jun 2008 15:38:39 -0400 Subject: NFS: implement option checking when remounting NFS filesystems (resend) When remounting an NFS or NFS4 filesystem, the new NFS options are not respected, yet the remount will still return success. This patch adds a remount_fs sb op for NFS that checks any new nfs mount options against the existing ones and fails the mount if any have changed. This is only implemented for string-based mount options since doing this with binary options isn't really feasible. This is essentially the same as the original patch I sent out, but adds a check to see if the addr= option has changed. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 614efee..b550e92 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -207,6 +207,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); static void nfs_kill_super(struct super_block *); static void nfs_put_super(struct super_block *); +static int nfs_remount(struct super_block *sb, int *flags, char *raw_data); static struct file_system_type nfs_fs_type = { .owner = THIS_MODULE, @@ -234,6 +235,7 @@ static const struct super_operations nfs_sops = { .umount_begin = nfs_umount_begin, .show_options = nfs_show_options, .show_stats = nfs_show_stats, + .remount_fs = nfs_remount, }; #ifdef CONFIG_NFS_V4 @@ -278,6 +280,7 @@ static const struct super_operations nfs4_sops = { .umount_begin = nfs_umount_begin, .show_options = nfs_show_options, .show_stats = nfs_show_stats, + .remount_fs = nfs_remount, }; #endif @@ -1396,6 +1399,79 @@ out_invalid_fh: return -EINVAL; } +static int +nfs_compare_remount_data(struct nfs_server *nfss, + struct nfs_parsed_mount_data *data) +{ + if (data->flags != nfss->flags || + data->rsize != nfss->rsize || + data->wsize != nfss->wsize || + data->retrans != nfss->client->cl_timeout->to_retries || + data->auth_flavors[0] != nfss->client->cl_auth->au_flavor || + data->acregmin != nfss->acregmin / HZ || + data->acregmax != nfss->acregmax / HZ || + data->acdirmin != nfss->acdirmin / HZ || + data->acdirmax != nfss->acdirmax / HZ || + data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || + data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || + memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr, + data->nfs_server.addrlen) != 0) + return -EINVAL; + + return 0; +} + +static int +nfs_remount(struct super_block *sb, int *flags, char *raw_data) +{ + int error; + struct nfs_server *nfss = sb->s_fs_info; + struct nfs_parsed_mount_data *data; + struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data; + struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data; + + /* + * Userspace mount programs that send binary options generally send + * them populated with default values. We have no way to know which + * ones were explicitly specified. Fall back to legacy behavior and + * just return success. + */ + if ((sb->s_type == &nfs4_fs_type && options4->version == 1) || + (sb->s_type == &nfs_fs_type && options->version >= 1 && + options->version <= 6)) + return 0; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + /* fill out struct with values from existing mount */ + data->flags = nfss->flags; + data->rsize = nfss->rsize; + data->wsize = nfss->wsize; + data->retrans = nfss->client->cl_timeout->to_retries; + data->auth_flavors[0] = nfss->client->cl_auth->au_flavor; + data->acregmin = nfss->acregmin / HZ; + data->acregmax = nfss->acregmax / HZ; + data->acdirmin = nfss->acdirmin / HZ; + data->acdirmax = nfss->acdirmax / HZ; + data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; + data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; + memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, + data->nfs_server.addrlen); + + /* overwrite those values with any that were specified */ + error = nfs_parse_mount_options((char *)options, data); + if (error < 0) + goto out; + + /* compare new mount options with old ones */ + error = nfs_compare_remount_data(nfss, data); +out: + kfree(data); + return error; +} + /* * Initialise the common bits of the superblock */ -- cgit v0.10.2 From b6b6152c46861dd914d0e6cea9c27df057d6e235 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Mon, 9 Jun 2008 16:51:31 -0400 Subject: rpc: bring back cl_chatty The cl_chatty flag alows us to control whether a given rpc client leaves "server X not responding, timed out" messages in the syslog. Such messages make sense for ordinary nfs clients (where an unresponsive server means applications on the mountpoint are probably hanging), but not for the callback client (which can fail more commonly, with the only result just of disabling some optimizations). Previously cl_chatty was removed, do to lack of users; reinstate it, and use it for the nfsd's callback client. Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 4d4760e..702fa57 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -381,7 +381,7 @@ static int do_probe_callback(void *data) .program = &cb_program, .version = nfs_cb_version[1]->number, .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ - .flags = (RPC_CLNT_CREATE_NOPING), + .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), }; struct rpc_message msg = { .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 6fff7f8..764fd4c 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -42,7 +42,8 @@ struct rpc_clnt { unsigned int cl_softrtry : 1,/* soft timeouts */ cl_discrtry : 1,/* disconnect before retry */ - cl_autobind : 1;/* use getport() */ + cl_autobind : 1,/* use getport() */ + cl_chatty : 1;/* be verbose */ struct rpc_rtt * cl_rtt; /* RTO estimator data */ const struct rpc_timeout *cl_timeout; /* Timeout strategy */ @@ -114,6 +115,7 @@ struct rpc_create_args { #define RPC_CLNT_CREATE_NONPRIVPORT (1UL << 3) #define RPC_CLNT_CREATE_NOPING (1UL << 4) #define RPC_CLNT_CREATE_DISCRTRY (1UL << 5) +#define RPC_CLNT_CREATE_QUIET (1UL << 6) struct rpc_clnt *rpc_create(struct rpc_create_args *args); struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 0530eea..09631f6 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -324,6 +324,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) clnt->cl_autobind = 1; if (args->flags & RPC_CLNT_CREATE_DISCRTRY) clnt->cl_discrtry = 1; + if (!(args->flags & RPC_CLNT_CREATE_QUIET)) + clnt->cl_chatty = 1; return clnt; } @@ -1149,7 +1151,8 @@ call_status(struct rpc_task *task) rpc_exit(task, status); break; default: - printk("%s: RPC call returned error %d\n", + if (clnt->cl_chatty) + printk("%s: RPC call returned error %d\n", clnt->cl_protname, -status); rpc_exit(task, status); } @@ -1174,7 +1177,8 @@ call_timeout(struct rpc_task *task) task->tk_timeouts++; if (RPC_IS_SOFT(task)) { - printk(KERN_NOTICE "%s: server %s not responding, timed out\n", + if (clnt->cl_chatty) + printk(KERN_NOTICE "%s: server %s not responding, timed out\n", clnt->cl_protname, clnt->cl_server); rpc_exit(task, -EIO); return; @@ -1182,7 +1186,8 @@ call_timeout(struct rpc_task *task) if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { task->tk_flags |= RPC_CALL_MAJORSEEN; - printk(KERN_NOTICE "%s: server %s not responding, still trying\n", + if (clnt->cl_chatty) + printk(KERN_NOTICE "%s: server %s not responding, still trying\n", clnt->cl_protname, clnt->cl_server); } rpc_force_rebind(clnt); @@ -1213,8 +1218,9 @@ call_decode(struct rpc_task *task) task->tk_pid, task->tk_status); if (task->tk_flags & RPC_CALL_MAJORSEEN) { - printk(KERN_NOTICE "%s: server %s OK\n", - clnt->cl_protname, clnt->cl_server); + if (clnt->cl_chatty) + printk(KERN_NOTICE "%s: server %s OK\n", + clnt->cl_protname, clnt->cl_server); task->tk_flags &= ~RPC_CALL_MAJORSEEN; } -- cgit v0.10.2 From 720b8f2d6f7de9e16f1217448cc7396e1604e175 Mon Sep 17 00:00:00 2001 From: "\\\\\\\"J. Bruce Fields\\\\\\" Date: Mon, 9 Jun 2008 16:51:33 -0400 Subject: rpc: eliminate unused variable in auth_gss upcall code Also, a minor comment grammar fix in the same file. Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index bf7585b..ebfd630 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -272,7 +272,7 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) return NULL; } -/* Try to add a upcall to the pipefs queue. +/* Try to add an upcall to the pipefs queue. * If an upcall owned by our uid already exists, then we return a reference * to that upcall instead of adding the new upcall. */ @@ -493,7 +493,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) { const void *p, *end; void *buf; - struct rpc_clnt *clnt; struct gss_upcall_msg *gss_msg; struct inode *inode = filp->f_path.dentry->d_inode; struct gss_cl_ctx *ctx; @@ -507,7 +506,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) if (!buf) goto out; - clnt = RPC_I(inode)->private; err = -EFAULT; if (copy_from_user(buf, src, mlen)) goto err; -- cgit v0.10.2 From d25a03cf966f2cf9990dc0bf2a921a554919ea34 Mon Sep 17 00:00:00 2001 From: "\\\\\\\"J. Bruce Fields\\\\\\" Date: Mon, 9 Jun 2008 16:51:34 -0400 Subject: rpc: remove some unused macros There used to be a print_hexl() function that used isprint(), now gone. I don't know why NFS_NGROUPS and CA_RUN_AS_MACHINE were here. I also don't know why another #define that's actually used was marked "unused". Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index ebfd630..834a831 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -63,22 +63,11 @@ static const struct rpc_credops gss_nullops; # define RPCDBG_FACILITY RPCDBG_AUTH #endif -#define NFS_NGROUPS 16 - -#define GSS_CRED_SLACK 1024 /* XXX: unused */ +#define GSS_CRED_SLACK 1024 /* length of a krb5 verifier (48), plus data added before arguments when * using integrity (two 4-byte integers): */ #define GSS_VERF_SLACK 100 -/* XXX this define must match the gssd define -* as it is passed to gssd to signal the use of -* machine creds should be part of the shared rpc interface */ - -#define CA_RUN_AS_MACHINE 0x00000200 - -/* dump the buffer in `emacs-hexl' style */ -#define isprint(c) ((c > 0x1f) && (c < 0x7f)) - struct gss_auth { struct kref kref; struct rpc_auth rpc_auth; -- cgit v0.10.2 From a486aeda9b2b0d944aecce7871b3186379b898de Mon Sep 17 00:00:00 2001 From: "\\\\\\\"J. Bruce Fields\\\\\\" Date: Mon, 9 Jun 2008 16:51:35 -0400 Subject: rpc: minor cleanup of scheduler callback code Try to make the comment here a little more clear and concise. Also, this macro definition seems unnecessary. Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index d1a5c8c..64981a2 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -135,7 +135,6 @@ struct rpc_task_setup { #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) -#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL) #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) #define RPC_TASK_RUNNING 0 diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 6eab9bf..6288af0 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -626,19 +626,15 @@ static void __rpc_execute(struct rpc_task *task) /* * Execute any pending callback. */ - if (RPC_DO_CALLBACK(task)) { - /* Define a callback save pointer */ + if (task->tk_callback) { void (*save_callback)(struct rpc_task *); /* - * If a callback exists, save it, reset it, - * call it. - * The save is needed to stop from resetting - * another callback set within the callback handler - * - Dave + * We set tk_callback to NULL before calling it, + * in case it sets the tk_callback field itself: */ - save_callback=task->tk_callback; - task->tk_callback=NULL; + save_callback = task->tk_callback; + task->tk_callback = NULL; save_callback(task); } -- cgit v0.10.2 From 659bfcd6dd88919a5ad453f62afbeffcb3106847 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 10 Jun 2008 19:39:41 -0400 Subject: NFS: Fix the ftruncate() credential problem ftruncate() access checking is supposed to be performed at open() time, just like reads and writes. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 596c5d8..2e4ab4a 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -347,7 +347,7 @@ out_no_inode: goto out; } -#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET) +#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE) int nfs_setattr(struct dentry *dentry, struct iattr *attr) @@ -369,7 +369,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) /* Optimization: if the end result is no change, don't RPC */ attr->ia_valid &= NFS_VALID_ATTRS; - if (attr->ia_valid == 0) + if ((attr->ia_valid & ~ATTR_FILE) == 0) return 0; lock_kernel(); diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index cf7d4e5..b9c2d99 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -129,6 +129,8 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, int status; dprintk("NFS call setattr\n"); + if (sattr->ia_valid & ATTR_FILE) + msg.rpc_cred = nfs_file_cred(sattr->ia_file); nfs_fattr_init(fattr); status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); if (status == 0) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 26fbeb3..31a7e4c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1139,8 +1139,9 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int return res; } -static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr, - struct iattr *sattr, struct nfs4_state *state) +static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, + struct nfs_fattr *fattr, struct iattr *sattr, + struct nfs4_state *state) { struct nfs_server *server = NFS_SERVER(inode); struct nfs_setattrargs arg = { @@ -1154,9 +1155,10 @@ static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr, .server = server, }; struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR], - .rpc_argp = &arg, - .rpc_resp = &res, + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR], + .rpc_argp = &arg, + .rpc_resp = &res, + .rpc_cred = cred, }; unsigned long timestamp = jiffies; int status; @@ -1166,7 +1168,6 @@ static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr, if (nfs4_copy_delegation_stateid(&arg.stateid, inode)) { /* Use that stateid */ } else if (state != NULL) { - msg.rpc_cred = state->owner->so_cred; nfs4_copy_stateid(&arg.stateid, state, current->files); } else memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); @@ -1177,15 +1178,16 @@ static int _nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr, return status; } -static int nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr, - struct iattr *sattr, struct nfs4_state *state) +static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, + struct nfs_fattr *fattr, struct iattr *sattr, + struct nfs4_state *state) { struct nfs_server *server = NFS_SERVER(inode); struct nfs4_exception exception = { }; int err; do { err = nfs4_handle_exception(server, - _nfs4_do_setattr(inode, fattr, sattr, state), + _nfs4_do_setattr(inode, cred, fattr, sattr, state), &exception); } while (exception.retry); return err; @@ -1647,29 +1649,25 @@ static int nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, struct iattr *sattr) { - struct rpc_cred *cred; struct inode *inode = dentry->d_inode; - struct nfs_open_context *ctx; + struct rpc_cred *cred = NULL; struct nfs4_state *state = NULL; int status; nfs_fattr_init(fattr); - cred = rpc_lookup_cred(); - if (IS_ERR(cred)) - return PTR_ERR(cred); - /* Search for an existing open(O_WRITE) file */ - ctx = nfs_find_open_context(inode, cred, FMODE_WRITE); - if (ctx != NULL) + if (sattr->ia_valid & ATTR_FILE) { + struct nfs_open_context *ctx; + + ctx = nfs_file_open_context(sattr->ia_file); + cred = ctx->cred; state = ctx->state; + } - status = nfs4_do_setattr(inode, fattr, sattr, state); + status = nfs4_do_setattr(inode, cred, fattr, sattr, state); if (status == 0) nfs_setattr_update_inode(inode, sattr); - if (ctx != NULL) - put_nfs_open_context(ctx); - put_rpccred(cred); return status; } @@ -1897,17 +1895,16 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, goto out; } state = nfs4_do_open(dir, &path, flags, sattr, cred); - put_rpccred(cred); d_drop(dentry); if (IS_ERR(state)) { status = PTR_ERR(state); - goto out; + goto out_putcred; } d_add(dentry, igrab(state->inode)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); if (flags & O_EXCL) { struct nfs_fattr fattr; - status = nfs4_do_setattr(state->inode, &fattr, sattr, state); + status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state); if (status == 0) nfs_setattr_update_inode(state->inode, sattr); nfs_post_op_update_inode(state->inode, &fattr); @@ -1916,6 +1913,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, status = nfs4_intent_set_file(nd, &path, state); else nfs4_close_sync(&path, state, flags); +out_putcred: + put_rpccred(cred); out: return status; } diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 5c35b02..c760558 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -129,6 +129,8 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, sattr->ia_mode &= S_IALLUGO; dprintk("NFS call setattr\n"); + if (sattr->ia_valid & ATTR_FILE) + msg.rpc_cred = nfs_file_cred(sattr->ia_file); nfs_fattr_init(fattr); status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); if (status == 0) -- cgit v0.10.2 From b22602a673b1743bba4b62bb404ffd3b269d2f09 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 6 Jun 2008 13:22:25 -0400 Subject: SUNRPC: Ensure all transports set rq_xtime consistently The RPC client uses the rq_xtime field in each RPC request to determine the round-trip time of the request. Currently, the rq_xtime field is initialized by each transport just before it starts enqueing a request to be sent. However, transports do not handle initializing this value consistently; sometimes they don't initialize it at all. To make the measurement of request round-trip time consistent for all RPC client transport capabilities, pull rq_xtime initialization into the RPC client's generic transport logic. Now all transports will get a standardized RTT measure automatically, from: xprt_transmit() to xprt_complete_rqst() This makes round-trip time calculation more accurate for the TCP transport. The socket ->sendmsg() method can return "-EAGAIN" if the socket's output buffer is full, so the TCP transport's ->send_request() method may call the ->sendmsg() method repeatedly until it gets all of the request's bytes queued in the socket's buffer. Currently, the TCP transport sets the rq_xtime field every time through that loop so the final value is the timestamp just before the *last* call to the underlying socket's ->sendmsg() method. After this patch, the rq_xtime field contains a timestamp that reflects the time just before the *first* call to ->sendmsg(). This is consequential under heavy workloads because large requests often take multiple ->sendmsg() calls to get all the bytes of a request queued. The TCP transport causes the request to sleep until the remote end of the socket has received enough bytes to clear space in the socket's local output buffer. This delay can be quite significant. The method introduced by this patch is a more accurate measure of RTT for stream transports, since the server can cause enough back pressure to delay (ie increase the latency of) requests from the client. Additionally, this patch corrects the behavior of the RDMA transport, which entirely neglected to initialize the rq_xtime field. RPC performance metrics for RDMA transports now display correct RPC request round trip times. Signed-off-by: Chuck Lever Acked-by: Tom Talpey Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 67996bd..99a52aa 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -872,6 +872,7 @@ void xprt_transmit(struct rpc_task *task) return; req->rq_connect_cookie = xprt->connect_cookie; + req->rq_xtime = jiffies; status = xprt->ops->send_request(task); if (status == 0) { dprintk("RPC: %5u xmit complete\n", task->tk_pid); diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index ddbe981..4486c59 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -579,7 +579,6 @@ static int xs_udp_send_request(struct rpc_task *task) req->rq_svec->iov_base, req->rq_svec->iov_len); - req->rq_xtime = jiffies; status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, xdr, @@ -671,7 +670,6 @@ static int xs_tcp_send_request(struct rpc_task *task) * to cope with writespace callbacks arriving _after_ we have * called sendmsg(). */ while (1) { - req->rq_xtime = jiffies; status = xs_sendpages(transport->sock, NULL, 0, xdr, req->rq_bytes_sent); -- cgit v0.10.2 From 46cb650c224bb8e64a749090105d74b9e8eda669 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 16:32:46 -0400 Subject: NFS: Remove the redundant file_open entry from struct nfs_rpc_ops All instances are set to nfs_open(), so we should just remove the redundant indirection. Ditto for the file_release op Signed-off-by: Trond Myklebust diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 78b26f8..509dcb5 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -129,7 +129,7 @@ nfs_file_open(struct inode *inode, struct file *filp) nfs_inc_stats(inode, NFSIOS_VFSOPEN); lock_kernel(); - res = NFS_PROTO(inode)->file_open(inode, filp); + res = nfs_open(inode, filp); unlock_kernel(); return res; } @@ -147,7 +147,7 @@ nfs_file_release(struct inode *inode, struct file *filp) if (filp->f_mode & FMODE_WRITE) nfs_wb_all(dentry->d_inode); nfs_inc_stats(inode, NFSIOS_VFSRELEASE); - return NFS_PROTO(inode)->file_release(inode, filp); + return nfs_release(inode, filp); } /** diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index b9c2d99..1e750e45 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -816,8 +816,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .write_done = nfs3_write_done, .commit_setup = nfs3_proc_commit_setup, .commit_done = nfs3_commit_done, - .file_open = nfs_open, - .file_release = nfs_release, .lock = nfs3_proc_lock, .clear_acl_cache = nfs3_forget_cached_acls, }; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 31a7e4c..dfdd19a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3714,8 +3714,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .write_done = nfs4_write_done, .commit_setup = nfs4_proc_commit_setup, .commit_done = nfs4_commit_done, - .file_open = nfs_open, - .file_release = nfs_release, .lock = nfs4_proc_lock, .clear_acl_cache = nfs4_zap_acl_attr, }; diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index c760558..4dbb84d 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -655,8 +655,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .write_setup = nfs_proc_write_setup, .write_done = nfs_write_done, .commit_setup = nfs_proc_commit_setup, - .file_open = nfs_open, - .file_release = nfs_release, .lock = nfs_proc_lock, .lock_check_bounds = nfs_lock_check_bounds, }; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 8d780de..8c77c11 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -829,8 +829,6 @@ struct nfs_rpc_ops { int (*write_done) (struct rpc_task *, struct nfs_write_data *); void (*commit_setup) (struct nfs_write_data *, struct rpc_message *); int (*commit_done) (struct rpc_task *, struct nfs_write_data *); - int (*file_open) (struct inode *, struct file *); - int (*file_release) (struct inode *, struct file *); int (*lock)(struct file *, int, struct file_lock *); int (*lock_check_bounds)(const struct file_lock *); void (*clear_acl_cache)(struct inode *); -- cgit v0.10.2 From 34e8f92831cb5c40b3137e47a3daf4c09016ef02 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:32:25 -0400 Subject: NFS: Move fs/nfs/iostat.h to include/linux The fs/nfs/iostat.h header has definitions that were designed to be exposed to user space. Move these definitions under include/linux so user space can use the definitions in applications that read /proc/self/mountstats. Also address a handful of coding style issues called out by checkpatch.pl in fs/nfs/iostat.h. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h index 6350ecbd..2ec65e1 100644 --- a/fs/nfs/iostat.h +++ b/fs/nfs/iostat.h @@ -5,135 +5,41 @@ * * Copyright (C) 2005, 2006 Chuck Lever * - * NFS client per-mount statistics provide information about the health of - * the NFS client and the health of each NFS mount point. Generally these - * are not for detailed problem diagnosis, but simply to indicate that there - * is a problem. - * - * These counters are not meant to be human-readable, but are meant to be - * integrated into system monitoring tools such as "sar" and "iostat". As - * such, the counters are sampled by the tools over time, and are never - * zeroed after a file system is mounted. Moving averages can be computed - * by the tools by taking the difference between two instantaneous samples - * and dividing that by the time between the samples. */ #ifndef _NFS_IOSTAT #define _NFS_IOSTAT -#define NFS_IOSTAT_VERS "1.0" - -/* - * NFS byte counters - * - * 1. SERVER - the number of payload bytes read from or written to the - * server by the NFS client via an NFS READ or WRITE request. - * - * 2. NORMAL - the number of bytes read or written by applications via - * the read(2) and write(2) system call interfaces. - * - * 3. DIRECT - the number of bytes read or written from files opened - * with the O_DIRECT flag. - * - * These counters give a view of the data throughput into and out of the NFS - * client. Comparing the number of bytes requested by an application with the - * number of bytes the client requests from the server can provide an - * indication of client efficiency (per-op, cache hits, etc). - * - * These counters can also help characterize which access methods are in - * use. DIRECT by itself shows whether there is any O_DIRECT traffic. - * NORMAL + DIRECT shows how much data is going through the system call - * interface. A large amount of SERVER traffic without much NORMAL or - * DIRECT traffic shows that applications are using mapped files. - * - * NFS page counters - * - * These count the number of pages read or written via nfs_readpage(), - * nfs_readpages(), or their write equivalents. - */ -enum nfs_stat_bytecounters { - NFSIOS_NORMALREADBYTES = 0, - NFSIOS_NORMALWRITTENBYTES, - NFSIOS_DIRECTREADBYTES, - NFSIOS_DIRECTWRITTENBYTES, - NFSIOS_SERVERREADBYTES, - NFSIOS_SERVERWRITTENBYTES, - NFSIOS_READPAGES, - NFSIOS_WRITEPAGES, - __NFSIOS_BYTESMAX, -}; - -/* - * NFS event counters - * - * These counters provide a low-overhead way of monitoring client activity - * without enabling NFS trace debugging. The counters show the rate at - * which VFS requests are made, and how often the client invalidates its - * data and attribute caches. This allows system administrators to monitor - * such things as how close-to-open is working, and answer questions such - * as "why are there so many GETATTR requests on the wire?" - * - * They also count anamolous events such as short reads and writes, silly - * renames due to close-after-delete, and operations that change the size - * of a file (such operations can often be the source of data corruption - * if applications aren't using file locking properly). - */ -enum nfs_stat_eventcounters { - NFSIOS_INODEREVALIDATE = 0, - NFSIOS_DENTRYREVALIDATE, - NFSIOS_DATAINVALIDATE, - NFSIOS_ATTRINVALIDATE, - NFSIOS_VFSOPEN, - NFSIOS_VFSLOOKUP, - NFSIOS_VFSACCESS, - NFSIOS_VFSUPDATEPAGE, - NFSIOS_VFSREADPAGE, - NFSIOS_VFSREADPAGES, - NFSIOS_VFSWRITEPAGE, - NFSIOS_VFSWRITEPAGES, - NFSIOS_VFSGETDENTS, - NFSIOS_VFSSETATTR, - NFSIOS_VFSFLUSH, - NFSIOS_VFSFSYNC, - NFSIOS_VFSLOCK, - NFSIOS_VFSRELEASE, - NFSIOS_CONGESTIONWAIT, - NFSIOS_SETATTRTRUNC, - NFSIOS_EXTENDWRITE, - NFSIOS_SILLYRENAME, - NFSIOS_SHORTREAD, - NFSIOS_SHORTWRITE, - NFSIOS_DELAY, - __NFSIOS_COUNTSMAX, -}; - -#ifdef __KERNEL__ - #include #include +#include struct nfs_iostats { unsigned long long bytes[__NFSIOS_BYTESMAX]; unsigned long events[__NFSIOS_COUNTSMAX]; } ____cacheline_aligned; -static inline void nfs_inc_server_stats(struct nfs_server *server, enum nfs_stat_eventcounters stat) +static inline void nfs_inc_server_stats(struct nfs_server *server, + enum nfs_stat_eventcounters stat) { struct nfs_iostats *iostats; int cpu; cpu = get_cpu(); iostats = per_cpu_ptr(server->io_stats, cpu); - iostats->events[stat] ++; + iostats->events[stat]++; put_cpu_no_resched(); } -static inline void nfs_inc_stats(struct inode *inode, enum nfs_stat_eventcounters stat) +static inline void nfs_inc_stats(struct inode *inode, + enum nfs_stat_eventcounters stat) { nfs_inc_server_stats(NFS_SERVER(inode), stat); } -static inline void nfs_add_server_stats(struct nfs_server *server, enum nfs_stat_bytecounters stat, unsigned long addend) +static inline void nfs_add_server_stats(struct nfs_server *server, + enum nfs_stat_bytecounters stat, + unsigned long addend) { struct nfs_iostats *iostats; int cpu; @@ -144,7 +50,9 @@ static inline void nfs_add_server_stats(struct nfs_server *server, enum nfs_stat put_cpu_no_resched(); } -static inline void nfs_add_stats(struct inode *inode, enum nfs_stat_bytecounters stat, unsigned long addend) +static inline void nfs_add_stats(struct inode *inode, + enum nfs_stat_bytecounters stat, + unsigned long addend) { nfs_add_server_stats(NFS_SERVER(inode), stat, addend); } @@ -160,5 +68,4 @@ static inline void nfs_free_iostats(struct nfs_iostats *stats) free_percpu(stats); } -#endif -#endif +#endif /* _NFS_IOSTAT */ diff --git a/include/linux/nfs_iostat.h b/include/linux/nfs_iostat.h new file mode 100644 index 0000000..1cb9a3f --- /dev/null +++ b/include/linux/nfs_iostat.h @@ -0,0 +1,119 @@ +/* + * User-space visible declarations for NFS client per-mount + * point statistics + * + * Copyright (C) 2005, 2006 Chuck Lever + * + * NFS client per-mount statistics provide information about the + * health of the NFS client and the health of each NFS mount point. + * Generally these are not for detailed problem diagnosis, but + * simply to indicate that there is a problem. + * + * These counters are not meant to be human-readable, but are meant + * to be integrated into system monitoring tools such as "sar" and + * "iostat". As such, the counters are sampled by the tools over + * time, and are never zeroed after a file system is mounted. + * Moving averages can be computed by the tools by taking the + * difference between two instantaneous samples and dividing that + * by the time between the samples. + */ + +#ifndef _LINUX_NFS_IOSTAT +#define _LINUX_NFS_IOSTAT + +#define NFS_IOSTAT_VERS "1.0" + +/* + * NFS byte counters + * + * 1. SERVER - the number of payload bytes read from or written + * to the server by the NFS client via an NFS READ or WRITE + * request. + * + * 2. NORMAL - the number of bytes read or written by applications + * via the read(2) and write(2) system call interfaces. + * + * 3. DIRECT - the number of bytes read or written from files + * opened with the O_DIRECT flag. + * + * These counters give a view of the data throughput into and out + * of the NFS client. Comparing the number of bytes requested by + * an application with the number of bytes the client requests from + * the server can provide an indication of client efficiency + * (per-op, cache hits, etc). + * + * These counters can also help characterize which access methods + * are in use. DIRECT by itself shows whether there is any O_DIRECT + * traffic. NORMAL + DIRECT shows how much data is going through + * the system call interface. A large amount of SERVER traffic + * without much NORMAL or DIRECT traffic shows that applications + * are using mapped files. + * + * NFS page counters + * + * These count the number of pages read or written via nfs_readpage(), + * nfs_readpages(), or their write equivalents. + * + * NB: When adding new byte counters, please include the measured + * units in the name of each byte counter to help users of this + * interface determine what exactly is being counted. + */ +enum nfs_stat_bytecounters { + NFSIOS_NORMALREADBYTES = 0, + NFSIOS_NORMALWRITTENBYTES, + NFSIOS_DIRECTREADBYTES, + NFSIOS_DIRECTWRITTENBYTES, + NFSIOS_SERVERREADBYTES, + NFSIOS_SERVERWRITTENBYTES, + NFSIOS_READPAGES, + NFSIOS_WRITEPAGES, + __NFSIOS_BYTESMAX, +}; + +/* + * NFS event counters + * + * These counters provide a low-overhead way of monitoring client + * activity without enabling NFS trace debugging. The counters + * show the rate at which VFS requests are made, and how often the + * client invalidates its data and attribute caches. This allows + * system administrators to monitor such things as how close-to-open + * is working, and answer questions such as "why are there so many + * GETATTR requests on the wire?" + * + * They also count anamolous events such as short reads and writes, + * silly renames due to close-after-delete, and operations that + * change the size of a file (such operations can often be the + * source of data corruption if applications aren't using file + * locking properly). + */ +enum nfs_stat_eventcounters { + NFSIOS_INODEREVALIDATE = 0, + NFSIOS_DENTRYREVALIDATE, + NFSIOS_DATAINVALIDATE, + NFSIOS_ATTRINVALIDATE, + NFSIOS_VFSOPEN, + NFSIOS_VFSLOOKUP, + NFSIOS_VFSACCESS, + NFSIOS_VFSUPDATEPAGE, + NFSIOS_VFSREADPAGE, + NFSIOS_VFSREADPAGES, + NFSIOS_VFSWRITEPAGE, + NFSIOS_VFSWRITEPAGES, + NFSIOS_VFSGETDENTS, + NFSIOS_VFSSETATTR, + NFSIOS_VFSFLUSH, + NFSIOS_VFSFSYNC, + NFSIOS_VFSLOCK, + NFSIOS_VFSRELEASE, + NFSIOS_CONGESTIONWAIT, + NFSIOS_SETATTRTRUNC, + NFSIOS_EXTENDWRITE, + NFSIOS_SILLYRENAME, + NFSIOS_SHORTREAD, + NFSIOS_SHORTWRITE, + NFSIOS_DELAY, + __NFSIOS_COUNTSMAX, +}; + +#endif /* _LINUX_NFS_IOSTAT */ -- cgit v0.10.2 From 2e96d2867245668dbdb973729288cf69b9fafa66 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 16:42:05 -0400 Subject: NFS: Fix a warning in nfs4_async_handle_error We're not modifying the nfs_server when we call nfs_inc_server_stats and friends, so allow the compiler to pass 'const' pointers too. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h index 2ec65e1..a369528 100644 --- a/fs/nfs/iostat.h +++ b/fs/nfs/iostat.h @@ -19,7 +19,7 @@ struct nfs_iostats { unsigned long events[__NFSIOS_COUNTSMAX]; } ____cacheline_aligned; -static inline void nfs_inc_server_stats(struct nfs_server *server, +static inline void nfs_inc_server_stats(const struct nfs_server *server, enum nfs_stat_eventcounters stat) { struct nfs_iostats *iostats; @@ -31,13 +31,13 @@ static inline void nfs_inc_server_stats(struct nfs_server *server, put_cpu_no_resched(); } -static inline void nfs_inc_stats(struct inode *inode, +static inline void nfs_inc_stats(const struct inode *inode, enum nfs_stat_eventcounters stat) { nfs_inc_server_stats(NFS_SERVER(inode), stat); } -static inline void nfs_add_server_stats(struct nfs_server *server, +static inline void nfs_add_server_stats(const struct nfs_server *server, enum nfs_stat_bytecounters stat, unsigned long addend) { @@ -50,7 +50,7 @@ static inline void nfs_add_server_stats(struct nfs_server *server, put_cpu_no_resched(); } -static inline void nfs_add_stats(struct inode *inode, +static inline void nfs_add_stats(const struct inode *inode, enum nfs_stat_bytecounters stat, unsigned long addend) { diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index dfdd19a..058723d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2756,8 +2756,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) task->tk_status = 0; return -EAGAIN; case -NFS4ERR_DELAY: - nfs_inc_server_stats((struct nfs_server *) server, - NFSIOS_DELAY); + nfs_inc_server_stats(server, NFSIOS_DELAY); case -NFS4ERR_GRACE: rpc_delay(task, NFS4_POLL_RETRY_MAX); task->tk_status = 0; -- cgit v0.10.2 From f41f741838480aeaa3a189cff6e210503cf9c42d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 17:39:04 -0400 Subject: NFS: Ensure we zap only the access and acl caches when setting new acls ...and ensure that we obey the NFS_INO_INVALID_ACL flag when retrieving the acls. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2e4ab4a..2c23d06 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -57,8 +57,6 @@ static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED; static void nfs_invalidate_inode(struct inode *); static int nfs_update_inode(struct inode *, struct nfs_fattr *); -static void nfs_zap_acl_cache(struct inode *); - static struct kmem_cache * nfs_inode_cachep; static inline unsigned long @@ -167,7 +165,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) } } -static void nfs_zap_acl_cache(struct inode *inode) +void nfs_zap_acl_cache(struct inode *inode) { void (*clear_acl_cache)(struct inode *); diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 04ae867..24241fc 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -150,6 +150,7 @@ extern void nfs_clear_inode(struct inode *); #ifdef CONFIG_NFS_V4 extern void nfs4_clear_inode(struct inode *); #endif +void nfs_zap_acl_cache(struct inode *inode); /* super.c */ extern struct file_system_type nfs_xdev_fs_type; diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index 9b73625..423842f 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -5,6 +5,8 @@ #include #include +#include "internal.h" + #define NFSDBG_FACILITY NFSDBG_PROC ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size) @@ -205,6 +207,8 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) status = nfs_revalidate_inode(server, inode); if (status < 0) return ERR_PTR(status); + if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) + nfs_zap_acl_cache(inode); acl = nfs3_get_cached_acl(inode, type); if (acl != ERR_PTR(-EAGAIN)) return acl; @@ -319,9 +323,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, dprintk("NFS call setacl\n"); msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL]; status = rpc_call_sync(server->client_acl, &msg, 0); - spin_lock(&inode->i_lock); - NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS; - spin_unlock(&inode->i_lock); + nfs_access_zap_cache(inode); + nfs_zap_acl_cache(inode); dprintk("NFS reply setacl: %d\n", status); /* pages may have been allocated at the xdr layer. */ diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 058723d..10f01c0 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2695,6 +2695,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) ret = nfs_revalidate_inode(server, inode); if (ret < 0) return ret; + if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) + nfs_zap_acl_cache(inode); ret = nfs4_read_cached_acl(inode, buf, buflen); if (ret != -ENOENT) return ret; @@ -2722,7 +2724,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl nfs_inode_return_delegation(inode); buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - nfs_zap_caches(inode); + nfs_access_zap_cache(inode); + nfs_zap_acl_cache(inode); return ret; } -- cgit v0.10.2 From ecbb3845dd678364148c1faad32adbc9dd833ef9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:37:33 -0400 Subject: NFS: Allow any value for the "retry" option The kernel NFS mount option parser should ignore the retry= mount option since it is meaningful only in user space. Today it expects a number rather than arbitrary text, so it ignores the option if the value is numeric, but chokes if there are other characters in the value. Change it to allow any text (except ",") as its value. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b550e92..5278eef 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -101,6 +101,8 @@ enum { static match_table_t nfs_mount_option_tokens = { { Opt_userspace, "bg" }, { Opt_userspace, "fg" }, + { Opt_userspace, "retry=%s" }, + { Opt_soft, "soft" }, { Opt_hard, "hard" }, { Opt_intr, "intr" }, @@ -136,7 +138,6 @@ static match_table_t nfs_mount_option_tokens = { { Opt_acdirmin, "acdirmin=%u" }, { Opt_acdirmax, "acdirmax=%u" }, { Opt_actimeo, "actimeo=%u" }, - { Opt_userspace, "retry=%u" }, { Opt_namelen, "namlen=%u" }, { Opt_mountport, "mountport=%u" }, { Opt_mountvers, "mountvers=%u" }, -- cgit v0.10.2 From d33e4dfeab5eb0c3c1359cc1a399f2f8b49e18de Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:37:41 -0400 Subject: NFS: Treat "intr" and "nointr" options as deprecated Clean up: the "intr" and "nointr" mount options were recently retired. Document this in the NFS mount option parser. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 5278eef..f824c41 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -65,7 +65,6 @@ enum { /* Mount options that take no arguments */ Opt_soft, Opt_hard, - Opt_intr, Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, Opt_noac, @@ -105,8 +104,8 @@ static match_table_t nfs_mount_option_tokens = { { Opt_soft, "soft" }, { Opt_hard, "hard" }, - { Opt_intr, "intr" }, - { Opt_nointr, "nointr" }, + { Opt_deprecated, "intr" }, + { Opt_deprecated, "nointr" }, { Opt_posix, "posix" }, { Opt_noposix, "noposix" }, { Opt_cto, "cto" }, @@ -787,9 +786,6 @@ static int nfs_parse_mount_options(char *raw, case Opt_hard: mnt->flags &= ~NFS_MOUNT_SOFT; break; - case Opt_intr: - case Opt_nointr: - break; case Opt_posix: mnt->flags |= NFS_MOUNT_POSIX; break; @@ -1105,6 +1101,8 @@ static int nfs_parse_mount_options(char *raw, case Opt_userspace: case Opt_deprecated: + dfprintk(MOUNT, "NFS: ignoring mount option " + "'%s'\n", p); break; default: -- cgit v0.10.2 From 396cee977f79590673ad51b04f1853e58bc30e7b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Jun 2008 12:37:49 -0400 Subject: NFS: missing newline in NFS mount debugging message Clean up. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f824c41..a1065c1 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1190,7 +1190,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, if (status == 0) return 0; - dfprintk(MOUNT, "NFS: unable to mount server %s, error %d", + dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", hostname, status); return status; } -- cgit v0.10.2 From e7d39069e387a12d4c57f4067d9f48c1d29ea900 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 13 Jun 2008 12:12:32 -0400 Subject: NFS: Clean up nfs_update_request() Simplify the loop in nfs_update_request by moving into a separate function the code that attempts to update an existing cached NFS write. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 21d8a48..04f51e5 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -34,9 +34,6 @@ /* * Local function declarations */ -static struct nfs_page * nfs_update_request(struct nfs_open_context*, - struct page *, - unsigned int, unsigned int); static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, struct inode *inode, int ioflags); static void nfs_redirty_request(struct nfs_page *req); @@ -169,30 +166,6 @@ static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int SetPageUptodate(page); } -static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, - unsigned int offset, unsigned int count) -{ - struct nfs_page *req; - int ret; - - for (;;) { - req = nfs_update_request(ctx, page, offset, count); - if (!IS_ERR(req)) - break; - ret = PTR_ERR(req); - if (ret != -EBUSY) - return ret; - ret = nfs_wb_page(page->mapping->host, page); - if (ret != 0) - return ret; - } - /* Update file length */ - nfs_grow_file(page, offset, count); - nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); - nfs_clear_page_tag_locked(req); - return 0; -} - static int wb_priority(struct writeback_control *wbc) { if (wbc->for_reclaim) @@ -356,11 +329,19 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) /* * Insert a write request into an inode */ -static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) +static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) { struct nfs_inode *nfsi = NFS_I(inode); int error; + error = radix_tree_preload(GFP_NOFS); + if (error != 0) + goto out; + + /* Lock the request! */ + nfs_lock_request_dontget(req); + + spin_lock(&inode->i_lock); error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); BUG_ON(error); if (!nfsi->npages) { @@ -374,6 +355,10 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) kref_get(&req->wb_kref); radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); + spin_unlock(&inode->i_lock); + radix_tree_preload_end(); +out: + return error; } /* @@ -565,101 +550,121 @@ static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pg #endif /* - * Try to update any existing write request, or create one if there is none. - * In order to match, the request's credentials must match those of - * the calling process. + * Search for an existing write request, and attempt to update + * it to reflect a new dirty region on a given page. * - * Note: Should always be called with the Page Lock held! + * If the attempt fails, then the existing request is flushed out + * to disk. */ -static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, - struct page *page, unsigned int offset, unsigned int bytes) +static struct nfs_page *nfs_try_to_update_request(struct inode *inode, + struct page *page, + unsigned int offset, + unsigned int bytes) { - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - struct nfs_page *req, *new = NULL; - pgoff_t rqend, end; + struct nfs_page *req; + unsigned int rqend; + unsigned int end; + int error; + + if (!PagePrivate(page)) + return NULL; end = offset + bytes; + spin_lock(&inode->i_lock); for (;;) { - /* Loop over all inode entries and see if we find - * A request for the page we wish to update - */ - spin_lock(&inode->i_lock); req = nfs_page_find_request_locked(page); - if (req) { - if (!nfs_set_page_tag_locked(req)) { - int error; - - spin_unlock(&inode->i_lock); - error = nfs_wait_on_request(req); - nfs_release_request(req); - if (error < 0) { - if (new) { - radix_tree_preload_end(); - nfs_release_request(new); - } - return ERR_PTR(error); - } - continue; - } - spin_unlock(&inode->i_lock); - if (new) { - radix_tree_preload_end(); - nfs_release_request(new); - } + if (req == NULL) + goto out_unlock; + + rqend = req->wb_offset + req->wb_bytes; + /* + * Tell the caller to flush out the request if + * the offsets are non-contiguous. + * Note: nfs_flush_incompatible() will already + * have flushed out requests having wrong owners. + */ + if (!nfs_dirty_request(req) + || offset > rqend + || end < req->wb_offset) + goto out_flushme; + + if (nfs_set_page_tag_locked(req)) break; - } - if (new) { - nfs_lock_request_dontget(new); - nfs_inode_add_request(inode, new); - spin_unlock(&inode->i_lock); - radix_tree_preload_end(); - req = new; - goto out; - } + /* The request is locked, so wait and then retry */ spin_unlock(&inode->i_lock); - - new = nfs_create_request(ctx, inode, page, offset, bytes); - if (IS_ERR(new)) - return new; - if (radix_tree_preload(GFP_NOFS)) { - nfs_release_request(new); - return ERR_PTR(-ENOMEM); - } - } - - /* We have a request for our page. - * If the creds don't match, or the - * page addresses don't match, - * tell the caller to wait on the conflicting - * request. - */ - rqend = req->wb_offset + req->wb_bytes; - if (req->wb_context != ctx - || req->wb_page != page - || !nfs_dirty_request(req) - || offset > rqend || end < req->wb_offset) { - nfs_clear_page_tag_locked(req); - return ERR_PTR(-EBUSY); + error = nfs_wait_on_request(req); + nfs_release_request(req); + if (error != 0) + goto out_err; + spin_lock(&inode->i_lock); } /* Okay, the request matches. Update the region */ if (offset < req->wb_offset) { req->wb_offset = offset; req->wb_pgbase = offset; - req->wb_bytes = max(end, rqend) - req->wb_offset; - goto out; } - if (end > rqend) req->wb_bytes = end - req->wb_offset; + else + req->wb_bytes = rqend - req->wb_offset; +out_unlock: + spin_unlock(&inode->i_lock); + return req; +out_flushme: + spin_unlock(&inode->i_lock); + nfs_release_request(req); + error = nfs_wb_page(inode, page); +out_err: + return ERR_PTR(error); +} +/* + * Try to update an existing write request, or create one if there is none. + * + * Note: Should always be called with the Page Lock held to prevent races + * if we have to add a new request. Also assumes that the caller has + * already called nfs_flush_incompatible() if necessary. + */ +static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx, + struct page *page, unsigned int offset, unsigned int bytes) +{ + struct inode *inode = page->mapping->host; + struct nfs_page *req; + int error; + + req = nfs_try_to_update_request(inode, page, offset, bytes); + if (req != NULL) + goto out; + req = nfs_create_request(ctx, inode, page, offset, bytes); + if (IS_ERR(req)) + goto out; + error = nfs_inode_add_request(inode, req); + if (error != 0) { + nfs_release_request(req); + req = ERR_PTR(error); + } out: return req; } +static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, + unsigned int offset, unsigned int count) +{ + struct nfs_page *req; + + req = nfs_setup_write_request(ctx, page, offset, count); + if (IS_ERR(req)) + return PTR_ERR(req); + /* Update file length */ + nfs_grow_file(page, offset, count); + nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); + nfs_clear_page_tag_locked(req); + return 0; +} + int nfs_flush_incompatible(struct file *file, struct page *page) { struct nfs_open_context *ctx = nfs_file_open_context(file); -- cgit v0.10.2 From e468bae97d243fe0e1515abaa1f7d0edf1476ad0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 13 Jun 2008 13:25:22 -0400 Subject: NFS: Allow redirtying of a completed unstable write. Currently, if an unstable write completes, we cannot redirty the page in order to reflect a new change in the page data until after we've sent a COMMIT request. This patch allows a page rewrite to proceed without the unnecessary COMMIT step, putting it immediately back onto the dirty page list, undoing the VM unstable write accounting, and removing the NFS_PAGE_TAG_COMMIT tag from the NFS radix tree. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 04f51e5..feca8c6 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -242,12 +242,9 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, return ret; spin_lock(&inode->i_lock); } - if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { - /* This request is marked for commit */ + if (test_bit(PG_CLEAN, &req->wb_flags)) { spin_unlock(&inode->i_lock); - nfs_clear_page_tag_locked(req); - nfs_pageio_complete(pgio); - return 0; + BUG(); } if (nfs_set_page_writeback(page) != 0) { spin_unlock(&inode->i_lock); @@ -391,19 +388,6 @@ nfs_mark_request_dirty(struct nfs_page *req) __set_page_dirty_nobuffers(req->wb_page); } -/* - * Check if a request is dirty - */ -static inline int -nfs_dirty_request(struct nfs_page *req) -{ - struct page *page = req->wb_page; - - if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags)) - return 0; - return !PageWriteback(page); -} - #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) /* * Add a request to the inode's commit list. @@ -416,7 +400,7 @@ nfs_mark_request_commit(struct nfs_page *req) spin_lock(&inode->i_lock); nfsi->ncommit++; - set_bit(PG_NEED_COMMIT, &(req)->wb_flags); + set_bit(PG_CLEAN, &(req)->wb_flags); radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_COMMIT); @@ -426,6 +410,19 @@ nfs_mark_request_commit(struct nfs_page *req) __mark_inode_dirty(inode, I_DIRTY_DATASYNC); } +static int +nfs_clear_request_commit(struct nfs_page *req) +{ + struct page *page = req->wb_page; + + if (test_and_clear_bit(PG_CLEAN, &(req)->wb_flags)) { + dec_zone_page_state(page, NR_UNSTABLE_NFS); + dec_bdi_stat(page->mapping->backing_dev_info, BDI_RECLAIMABLE); + return 1; + } + return 0; +} + static inline int nfs_write_need_commit(struct nfs_write_data *data) { @@ -435,7 +432,7 @@ int nfs_write_need_commit(struct nfs_write_data *data) static inline int nfs_reschedule_unstable_write(struct nfs_page *req) { - if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { + if (test_and_clear_bit(PG_NEED_COMMIT, &req->wb_flags)) { nfs_mark_request_commit(req); return 1; } @@ -451,6 +448,12 @@ nfs_mark_request_commit(struct nfs_page *req) { } +static inline int +nfs_clear_request_commit(struct nfs_page *req) +{ + return 0; +} + static inline int nfs_write_need_commit(struct nfs_write_data *data) { @@ -508,11 +511,8 @@ static void nfs_cancel_commit_list(struct list_head *head) while(!list_empty(head)) { req = nfs_list_entry(head->next); - dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); - dec_bdi_stat(req->wb_page->mapping->backing_dev_info, - BDI_RECLAIMABLE); nfs_list_remove_request(req); - clear_bit(PG_NEED_COMMIT, &(req)->wb_flags); + nfs_clear_request_commit(req); nfs_inode_remove_request(req); nfs_unlock_request(req); } @@ -584,8 +584,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, * Note: nfs_flush_incompatible() will already * have flushed out requests having wrong owners. */ - if (!nfs_dirty_request(req) - || offset > rqend + if (offset > rqend || end < req->wb_offset) goto out_flushme; @@ -601,6 +600,10 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, spin_lock(&inode->i_lock); } + if (nfs_clear_request_commit(req)) + radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree, + req->wb_index, NFS_PAGE_TAG_COMMIT); + /* Okay, the request matches. Update the region */ if (offset < req->wb_offset) { req->wb_offset = offset; @@ -682,8 +685,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page) req = nfs_page_find_request(page); if (req == NULL) return 0; - do_flush = req->wb_page != page || req->wb_context != ctx - || !nfs_dirty_request(req); + do_flush = req->wb_page != page || req->wb_context != ctx; nfs_release_request(req); if (!do_flush) return 0; @@ -1288,10 +1290,7 @@ static void nfs_commit_release(void *calldata) while (!list_empty(&data->pages)) { req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); - clear_bit(PG_NEED_COMMIT, &(req)->wb_flags); - dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); - dec_bdi_stat(req->wb_page->mapping->backing_dev_info, - BDI_RECLAIMABLE); + nfs_clear_request_commit(req); dprintk("NFS: commit (%s/%lld %d@%lld)", req->wb_context->path.dentry->d_inode->i_sb->s_id, @@ -1467,7 +1466,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) req = nfs_page_find_request(page); if (req == NULL) goto out; - if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { + if (test_bit(PG_CLEAN, &req->wb_flags)) { nfs_release_request(req); break; } diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index a1676e1..3c60685 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -27,9 +27,12 @@ /* * Valid flags for a dirty buffer */ -#define PG_BUSY 0 -#define PG_NEED_COMMIT 1 -#define PG_NEED_RESCHED 2 +enum { + PG_BUSY = 0, + PG_CLEAN, + PG_NEED_COMMIT, + PG_NEED_RESCHED, +}; struct nfs_inode; struct nfs_page { -- cgit v0.10.2 From cd100725620a8063fbc81bcf16d7c9e71a9583e0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 17 Jun 2008 16:12:00 -0400 Subject: NFS: Fix a dependency on CONFIG_NFS_V4 in nfs_remount Fix the 'nfs4_fs_type' undeclared error in nfs_remount when compiling sans NFSv4... Signed-off-by: Trond Myklebust Cc: Jeff Layton diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a1065c1..b880db1 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1428,6 +1428,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) struct nfs_parsed_mount_data *data; struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data; struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data; + u32 nfsvers = nfss->nfs_client->rpc_ops->version; /* * Userspace mount programs that send binary options generally send @@ -1435,8 +1436,8 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) * ones were explicitly specified. Fall back to legacy behavior and * just return success. */ - if ((sb->s_type == &nfs4_fs_type && options4->version == 1) || - (sb->s_type == &nfs_fs_type && options->version >= 1 && + if ((nfsvers == 4 && options4->version == 1) || + (nfsvers <= 3 && options->version >= 1 && options->version <= 6)) return 0; -- cgit v0.10.2 From dc04589827f7e1af12714af8bb00e3f3c4c48c62 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:36:37 -0400 Subject: NFS: Use common device name parsing logic for NFSv4 and NFSv2/v3 To support passing a raw IPv6 address as a server hostname, we need to expand the logic that handles splitting the passed-in device name into a server hostname and export path Start by pulling device name parsing out of the mount option validation functions and into separate helper functions. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b880db1..c4ee8b3 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1196,6 +1196,67 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, } /* + * Split "dev_name" into "hostname:export_path". + * + * Note: caller frees hostname and export path, even on error. + */ +static int nfs_parse_devname(const char *dev_name, + char **hostname, size_t maxnamlen, + char **export_path, size_t maxpathlen) +{ + size_t len; + char *colon, *comma; + + colon = strchr(dev_name, ':'); + if (colon == NULL) + goto out_bad_devname; + + len = colon - dev_name; + if (len > maxnamlen) + goto out_hostname; + + /* N.B. caller will free nfs_server.hostname in all cases */ + *hostname = kstrndup(dev_name, len, GFP_KERNEL); + if (!*hostname) + goto out_nomem; + + /* kill possible hostname list: not supported */ + comma = strchr(*hostname, ','); + if (comma != NULL) { + if (comma == *hostname) + goto out_bad_devname; + *comma = '\0'; + } + + colon++; + len = strlen(colon); + if (len > maxpathlen) + goto out_path; + *export_path = kstrndup(colon, len, GFP_KERNEL); + if (!*export_path) + goto out_nomem; + + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path); + return 0; + +out_bad_devname: + dfprintk(MOUNT, "NFS: device name not in host:path format\n"); + return -EINVAL; + +out_nomem: + dfprintk(MOUNT, "NFS: not enough memory to parse device name\n"); + return -ENOMEM; + +out_hostname: + dfprintk(MOUNT, "NFS: server hostname too long\n"); + return -ENAMETOOLONG; + +out_path: + dfprintk(MOUNT, "NFS: export pathname too long\n"); + return -ENAMETOOLONG; +} + +/* * Validate the NFS2/NFS3 mount data * - fills in the mount root filehandle * @@ -1323,8 +1384,6 @@ static int nfs_validate_mount_data(void *options, break; default: { - unsigned int len; - char *c; int status; if (nfs_parse_mount_options((char *)options, args) == 0) @@ -1334,21 +1393,17 @@ static int nfs_validate_mount_data(void *options, &args->nfs_server.address)) goto out_no_address; - c = strchr(dev_name, ':'); - if (c == NULL) - return -EINVAL; - len = c - dev_name; - /* N.B. caller will free nfs_server.hostname in all cases */ - args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); - if (!args->nfs_server.hostname) - goto out_nomem; + status = nfs_parse_devname(dev_name, + &args->nfs_server.hostname, + PAGE_SIZE, + &args->nfs_server.export_path, + NFS_MAXPATHLEN); + if (!status) + status = nfs_try_mount(args, mntfh); - c++; - if (strlen(c) > NFS_MAXPATHLEN) - return -ENAMETOOLONG; - args->nfs_server.export_path = c; + kfree(args->nfs_server.export_path); + args->nfs_server.export_path = NULL; - status = nfs_try_mount(args, mntfh); if (status) return status; @@ -1958,7 +2013,7 @@ static int nfs4_validate_mount_data(void *options, break; default: { - unsigned int len; + int status; if (nfs_parse_mount_options((char *)options, args) == 0) return -EINVAL; @@ -1977,34 +2032,17 @@ static int nfs4_validate_mount_data(void *options, goto out_inval_auth; } - /* - * Split "dev_name" into "hostname:mntpath". - */ - c = strchr(dev_name, ':'); - if (c == NULL) - return -EINVAL; - /* while calculating len, pretend ':' is '\0' */ - len = c - dev_name; - if (len > NFS4_MAXNAMLEN) - return -ENAMETOOLONG; - /* N.B. caller will free nfs_server.hostname in all cases */ - args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); - if (!args->nfs_server.hostname) - goto out_nomem; - - c++; /* step over the ':' */ - len = strlen(c); - if (len > NFS4_MAXPATHLEN) - return -ENAMETOOLONG; - args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL); - if (!args->nfs_server.export_path) - goto out_nomem; - - dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path); - if (args->client_address == NULL) goto out_no_client_address; + status = nfs_parse_devname(dev_name, + &args->nfs_server.hostname, + NFS4_MAXNAMLEN, + &args->nfs_server.export_path, + NFS4_MAXPATHLEN); + if (status < 0) + return status; + break; } } @@ -2020,10 +2058,6 @@ out_inval_auth: data->auth_flavourlen); return -EINVAL; -out_nomem: - dfprintk(MOUNT, "NFS4: not enough memory to handle mount options\n"); - return -ENOMEM; - out_no_address: dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); return -EINVAL; -- cgit v0.10.2 From d1aa08257312f1439c1ab7c8a18e3856f9530f46 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:36:45 -0400 Subject: NFS: Support raw IPv6 address hostnames during NFS mount operation Traditionally the mount command has looked for a ":" to separate the server's hostname from the export path in the mounted on device name, like this: mount server:/export /mounted/on/dir The server's hostname is "server" and the export path is "/export". You can also substitute a specific IPv4 network address for the server hostname, like this: mount 192.168.0.55:/export /mounted/on/dir Raw IPv6 addresses present a problem, however, because they look something like this: fe80::200:5aff:fe00:30b Note the use of colons. To get around the presence of colons, copy the Solaris convention used for mounting IPv6 servers by address: wrap a raw IPv6 address with square brackets. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c4ee8b3..ea4abd2 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1195,14 +1195,9 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, return status; } -/* - * Split "dev_name" into "hostname:export_path". - * - * Note: caller frees hostname and export path, even on error. - */ -static int nfs_parse_devname(const char *dev_name, - char **hostname, size_t maxnamlen, - char **export_path, size_t maxpathlen) +static int nfs_parse_simple_hostname(const char *dev_name, + char **hostname, size_t maxnamlen, + char **export_path, size_t maxpathlen) { size_t len; char *colon, *comma; @@ -1257,6 +1252,85 @@ out_path: } /* + * Hostname has square brackets around it because it contains one or + * more colons. We look for the first closing square bracket, and a + * colon must follow it. + */ +static int nfs_parse_protected_hostname(const char *dev_name, + char **hostname, size_t maxnamlen, + char **export_path, size_t maxpathlen) +{ + size_t len; + char *start, *end; + + start = (char *)(dev_name + 1); + + end = strchr(start, ']'); + if (end == NULL) + goto out_bad_devname; + if (*(end + 1) != ':') + goto out_bad_devname; + + len = end - start; + if (len > maxnamlen) + goto out_hostname; + + /* N.B. caller will free nfs_server.hostname in all cases */ + *hostname = kstrndup(start, len, GFP_KERNEL); + if (*hostname == NULL) + goto out_nomem; + + end += 2; + len = strlen(end); + if (len > maxpathlen) + goto out_path; + *export_path = kstrndup(end, len, GFP_KERNEL); + if (!*export_path) + goto out_nomem; + + return 0; + +out_bad_devname: + dfprintk(MOUNT, "NFS: device name not in host:path format\n"); + return -EINVAL; + +out_nomem: + dfprintk(MOUNT, "NFS: not enough memory to parse device name\n"); + return -ENOMEM; + +out_hostname: + dfprintk(MOUNT, "NFS: server hostname too long\n"); + return -ENAMETOOLONG; + +out_path: + dfprintk(MOUNT, "NFS: export pathname too long\n"); + return -ENAMETOOLONG; +} + +/* + * Split "dev_name" into "hostname:export_path". + * + * The leftmost colon demarks the split between the server's hostname + * and the export path. If the hostname starts with a left square + * bracket, then it may contain colons. + * + * Note: caller frees hostname and export path, even on error. + */ +static int nfs_parse_devname(const char *dev_name, + char **hostname, size_t maxnamlen, + char **export_path, size_t maxpathlen) +{ + if (*dev_name == '[') + return nfs_parse_protected_hostname(dev_name, + hostname, maxnamlen, + export_path, maxpathlen); + + return nfs_parse_simple_hostname(dev_name, + hostname, maxnamlen, + export_path, maxpathlen); +} + +/* * Validate the NFS2/NFS3 mount data * - fills in the mount root filehandle * -- cgit v0.10.2 From ce3b7e1906ebbe96753fe090b36de6ffb8e0e0e7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:36:53 -0400 Subject: NFS: Add string length argument to nfs_parse_server_address To make nfs_parse_server_address() more generally useful, allow it to accept input strings that are not terminated with '\0'. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ea4abd2..d27aa1d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -705,38 +705,76 @@ static int nfs_verify_server_address(struct sockaddr *addr) return 0; } -/* - * Parse string addresses passed in via a mount option, - * and construct a sockaddr based on the result. - * - * If address parsing fails, set the sockaddr's address - * family to AF_UNSPEC to force nfs_verify_server_address() - * to punt the mount. - */ -static void nfs_parse_server_address(char *value, - struct sockaddr *sap, - size_t *len) +static void nfs_parse_ipv4_address(char *string, size_t str_len, + struct sockaddr *sap, size_t *addr_len) { - if (strchr(value, ':')) { - struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap; - u8 *addr = (u8 *)&ap->sin6_addr.in6_u; + struct sockaddr_in *sin = (struct sockaddr_in *)sap; + u8 *addr = (u8 *)&sin->sin_addr.s_addr; - ap->sin6_family = AF_INET6; - *len = sizeof(*ap); - if (in6_pton(value, -1, addr, '\0', NULL)) + if (str_len <= INET_ADDRSTRLEN) { + dfprintk(MOUNT, "NFS: parsing IPv4 address %*s\n", + (int)str_len, string); + + sin->sin_family = AF_INET; + *addr_len = sizeof(*sin); + if (in4_pton(string, str_len, addr, '\0', NULL)) return; - } else { - struct sockaddr_in *ap = (struct sockaddr_in *)sap; - u8 *addr = (u8 *)&ap->sin_addr.s_addr; + } + + sap->sa_family = AF_UNSPEC; + *addr_len = 0; +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static void nfs_parse_ipv6_address(char *string, size_t str_len, + struct sockaddr *sap, size_t *addr_len) +{ + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; + u8 *addr = (u8 *)&sin6->sin6_addr.in6_u; + + if (str_len <= INET6_ADDRSTRLEN) { + dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n", + (int)str_len, string); - ap->sin_family = AF_INET; - *len = sizeof(*ap); - if (in4_pton(value, -1, addr, '\0', NULL)) + sin6->sin6_family = AF_INET6; + *addr_len = sizeof(*sin6); + if (in6_pton(string, str_len, addr, '\0', NULL)) return; } sap->sa_family = AF_UNSPEC; - *len = 0; + *addr_len = 0; +} +#else +static void nfs_parse_ipv6_address(char *string, size_t str_len, + struct sockaddr *sap, size_t *addr_len) +{ + sap->sa_family = AF_UNSPEC; + *addr_len = 0; +} +#endif + +/* + * Construct a sockaddr based on the contents of a string that contains + * an IP address in presentation format. + * + * If there is a problem constructing the new sockaddr, set the address + * family to AF_UNSPEC. + */ +static void nfs_parse_ip_address(char *string, size_t str_len, + struct sockaddr *sap, size_t *addr_len) +{ + unsigned int i, colons; + + colons = 0; + for (i = 0; i < str_len; i++) + if (string[i] == ':') + colons++; + + if (colons >= 2) + nfs_parse_ipv6_address(string, str_len, sap, addr_len); + else + nfs_parse_ipv4_address(string, str_len, sap, addr_len); } /* @@ -1070,9 +1108,10 @@ static int nfs_parse_mount_options(char *raw, string = match_strdup(args); if (string == NULL) goto out_nomem; - nfs_parse_server_address(string, (struct sockaddr *) - &mnt->nfs_server.address, - &mnt->nfs_server.addrlen); + nfs_parse_ip_address(string, strlen(string), + (struct sockaddr *) + &mnt->nfs_server.address, + &mnt->nfs_server.addrlen); kfree(string); break; case Opt_clientaddr: @@ -1093,9 +1132,10 @@ static int nfs_parse_mount_options(char *raw, string = match_strdup(args); if (string == NULL) goto out_nomem; - nfs_parse_server_address(string, (struct sockaddr *) - &mnt->mount_server.address, - &mnt->mount_server.addrlen); + nfs_parse_ip_address(string, strlen(string), + (struct sockaddr *) + &mnt->mount_server.address, + &mnt->mount_server.addrlen); kfree(string); break; diff --git a/include/linux/inet.h b/include/linux/inet.h index 1354080..4cca05c 100644 --- a/include/linux/inet.h +++ b/include/linux/inet.h @@ -44,6 +44,13 @@ #include +/* + * These mimic similar macros defined in user-space for inet_ntop(3). + * See /usr/include/netinet/in.h . + */ +#define INET_ADDRSTRLEN (16) +#define INET6_ADDRSTRLEN (48) + extern __be32 in_aton(const char *str); extern int in4_pton(const char *src, int srclen, u8 *dst, int delim, const char **end); extern int in6_pton(const char *src, int srclen, u8 *dst, int delim, const char **end); -- cgit v0.10.2 From d8e7748ab8322171ebfd78f6155ff35e7d57ac32 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 23 Jun 2008 12:37:01 -0400 Subject: NFS: handle interface identifiers in incoming IPv6 addresses Add support in the kernel NFS client's address parser for interface identifiers. IPv6 link-local addresses require an additional "interface identifier", which is a network device name or an integer that indexes the array of local network interfaces. They are suffixed to the address with a '%'. For example: fe80::215:c5ff:fe3b:e1b2%2 indicates an interface index of 2. Or fe80::215:c5ff:fe3b:e1b2%eth0 indicates that requests should be routed through the eth0 device. Without the interface ID, link-local addresses are not usable for NFS. Both the kernel NFS client mount option parser and the mount.nfs command can take either form. The mount.nfs command always passes the address through getnameinfo(3), which usually re-writes interface indices as device names. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index d27aa1d..73a8e59 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -725,12 +726,48 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len, *addr_len = 0; } +#define IPV6_SCOPE_DELIMITER '%' + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len, + const char *delim, + struct sockaddr_in6 *sin6) +{ + char *p; + size_t len; + + if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) + return ; + if (*delim != IPV6_SCOPE_DELIMITER) + return; + + len = (string + str_len) - delim - 1; + p = kstrndup(delim + 1, len, GFP_KERNEL); + if (p) { + unsigned long scope_id = 0; + struct net_device *dev; + + dev = dev_get_by_name(&init_net, p); + if (dev != NULL) { + scope_id = dev->ifindex; + dev_put(dev); + } else { + /* scope_id is set to zero on error */ + strict_strtoul(p, 10, &scope_id); + } + + kfree(p); + sin6->sin6_scope_id = scope_id; + dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id); + } +} + static void nfs_parse_ipv6_address(char *string, size_t str_len, struct sockaddr *sap, size_t *addr_len) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; u8 *addr = (u8 *)&sin6->sin6_addr.in6_u; + const char *delim; if (str_len <= INET6_ADDRSTRLEN) { dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n", @@ -738,8 +775,10 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len, sin6->sin6_family = AF_INET6; *addr_len = sizeof(*sin6); - if (in6_pton(string, str_len, addr, '\0', NULL)) + if (in6_pton(string, str_len, addr, IPV6_SCOPE_DELIMITER, &delim)) { + nfs_parse_ipv6_scope_id(string, str_len, delim, sin6); return; + } } sap->sa_family = AF_UNSPEC; -- cgit v0.10.2 From 77e03677ac76d413fbb6d6caaffa1d64877a0c2a Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Tue, 24 Jun 2008 20:25:57 +0300 Subject: nfs: initialize timeout variable in nfs4_proc_setclientid_confirm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc (4.3.0) rightfully warns about this: /usr0/export/dev/bhalevy/git/linux-pnfs-bh-nfs41/fs/nfs/nfs4proc.c: In function nfs4_proc_setclientid_confirm: /usr0/export/dev/bhalevy/git/linux-pnfs-bh-nfs41/fs/nfs/nfs4proc.c:2936: warning: timeout may be used uninitialized in this function nfs4_delay that's passed a pointer to 'timeout' is looking at its value and sets it up to some value in the range: NFS4_POLL_RETRY_MIN..NFS4_POLL_RETRY_MAX if (*timeout <= 0) *timeout = NFS4_POLL_RETRY_MIN; if (*timeout > NFS4_POLL_RETRY_MAX) *timeout = NFS4_POLL_RETRY_MAX; Therefore it will end up set to some sane, though rather indeterministic, value. Signed-off-by: Benny Halevy Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 10f01c0..4451287 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2924,7 +2924,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred) { - long timeout; + long timeout = 0; int err; do { err = _nfs4_proc_setclientid_confirm(clp, cred); -- cgit v0.10.2 From ee84dfc45467fd8e5ce04fa2813d98e0aebe465c Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 11 Jun 2008 10:03:10 -0400 Subject: nfs4: remove BKL from nfs_callback_up and nfs_callback_down The nfs_callback_mutex is sufficient protection. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index c1e7c83..9e713d2 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -105,7 +105,6 @@ int nfs_callback_up(void) struct svc_rqst *rqstp; int ret = 0; - lock_kernel(); mutex_lock(&nfs_callback_mutex); if (nfs_callback_info.users++ || nfs_callback_info.task != NULL) goto out; @@ -149,7 +148,6 @@ out: if (serv) svc_destroy(serv); mutex_unlock(&nfs_callback_mutex); - unlock_kernel(); return ret; out_err: dprintk("Couldn't create callback socket or server thread; err = %d\n", @@ -163,13 +161,11 @@ out_err: */ void nfs_callback_down(void) { - lock_kernel(); mutex_lock(&nfs_callback_mutex); nfs_callback_info.users--; if (nfs_callback_info.users == 0 && nfs_callback_info.task != NULL) kthread_stop(nfs_callback_info.task); mutex_unlock(&nfs_callback_mutex); - unlock_kernel(); } static int nfs_callback_authenticate(struct svc_rqst *rqstp) -- cgit v0.10.2 From 5afc597c5f0bd184457e49b9a330fcb37b69db11 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 11 Jun 2008 10:03:11 -0400 Subject: nfs4: fix potential race with rapid nfs_callback_up/down cycle If the nfsv4 callback thread is rapidly brought up and down, it's possible that nfs_callback_svc might never get a chance to run. If this happens, the cleanup at thread exit might never occur, throwing the refcounting off and nfs_callback_info in an incorrect state. Move the clean functions into nfs_callback_down. Also change the nfs_callback_info struct to track the svc_rqst rather than svc_serv since we need to know that to call svc_exit_thread. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 9e713d2..f447f4b 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -27,7 +27,7 @@ struct nfs_callback_data { unsigned int users; - struct svc_serv *serv; + struct svc_rqst *rqst; struct task_struct *task; }; @@ -91,18 +91,15 @@ nfs_callback_svc(void *vrqstp) svc_process(rqstp); } unlock_kernel(); - nfs_callback_info.task = NULL; - svc_exit_thread(rqstp); return 0; } /* - * Bring up the server process if it is not already up. + * Bring up the callback thread if it is not already up. */ int nfs_callback_up(void) { struct svc_serv *serv = NULL; - struct svc_rqst *rqstp; int ret = 0; mutex_lock(&nfs_callback_mutex); @@ -120,22 +117,23 @@ int nfs_callback_up(void) nfs_callback_tcpport = ret; dprintk("Callback port = 0x%x\n", nfs_callback_tcpport); - rqstp = svc_prepare_thread(serv, &serv->sv_pools[0]); - if (IS_ERR(rqstp)) { - ret = PTR_ERR(rqstp); + nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); + if (IS_ERR(nfs_callback_info.rqst)) { + ret = PTR_ERR(nfs_callback_info.rqst); + nfs_callback_info.rqst = NULL; goto out_err; } svc_sock_update_bufs(serv); - nfs_callback_info.serv = serv; - nfs_callback_info.task = kthread_run(nfs_callback_svc, rqstp, + nfs_callback_info.task = kthread_run(nfs_callback_svc, + nfs_callback_info.rqst, "nfsv4-svc"); if (IS_ERR(nfs_callback_info.task)) { ret = PTR_ERR(nfs_callback_info.task); - nfs_callback_info.serv = NULL; + svc_exit_thread(nfs_callback_info.rqst); + nfs_callback_info.rqst = NULL; nfs_callback_info.task = NULL; - svc_exit_thread(rqstp); goto out_err; } out: @@ -157,14 +155,18 @@ out_err: } /* - * Kill the server process if it is not already down. + * Kill the callback thread if it's no longer being used. */ void nfs_callback_down(void) { mutex_lock(&nfs_callback_mutex); nfs_callback_info.users--; - if (nfs_callback_info.users == 0 && nfs_callback_info.task != NULL) + if (nfs_callback_info.users == 0 && nfs_callback_info.task != NULL) { kthread_stop(nfs_callback_info.task); + svc_exit_thread(nfs_callback_info.rqst); + nfs_callback_info.rqst = NULL; + nfs_callback_info.task = NULL; + } mutex_unlock(&nfs_callback_mutex); } -- cgit v0.10.2 From 877fcf103982e52a59a1035378b4c0b8c63fe004 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:23 -0400 Subject: SUNRPC: More useful debugging output for rpcb client Clean up dprintk's in rpcb client's XDR decoder functions. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index e6fb21b..cf2b916 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -438,7 +438,7 @@ static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p, unsigned short *portp) { *portp = (unsigned short) ntohl(*p++); - dprintk("RPC: rpcb_decode_getport result %u\n", + dprintk("RPC: rpcb_decode_getport result %u\n", *portp); return 0; } @@ -447,8 +447,8 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p, unsigned int *boolp) { *boolp = (unsigned int) ntohl(*p++); - dprintk("RPC: rpcb_decode_set result %u\n", - *boolp); + dprintk("RPC: rpcb_decode_set: call %s\n", + (*boolp ? "succeeded" : "failed")); return 0; } -- cgit v0.10.2 From fc200e794d723bc88c39859e8f096b717532f9c9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:31 -0400 Subject: SUNRPC: Document some naked integers in rpcbind client Clean up: Replace naked integers that represent rpcbind protocol versions. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index cf2b916..b23a719 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -32,6 +32,10 @@ #define RPCBIND_PROGRAM (100000u) #define RPCBIND_PORT (111u) +#define RPCBVERS_2 (2u) +#define RPCBVERS_3 (3u) +#define RPCBVERS_4 (4u) + enum { RPCBPROC_NULL, RPCBPROC_SET, @@ -82,7 +86,7 @@ static struct rpc_procinfo rpcb_procedures2[]; static struct rpc_procinfo rpcb_procedures3[]; struct rpcb_info { - int rpc_vers; + u32 rpc_vers; struct rpc_procinfo * rpc_proc; }; @@ -177,7 +181,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) prog, vers, prot, port); rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin, - sizeof(sin), XPRT_TRANSPORT_UDP, 2, 1); + sizeof(sin), XPRT_TRANSPORT_UDP, RPCBVERS_2, 1); if (IS_ERR(rpcb_clnt)) return PTR_ERR(rpcb_clnt); @@ -227,7 +231,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, - sizeof(*sin), prot, 2, 0); + sizeof(*sin), prot, RPCBVERS_2, 0); if (IS_ERR(rpcb_clnt)) return PTR_ERR(rpcb_clnt); @@ -588,35 +592,54 @@ static struct rpc_procinfo rpcb_procedures4[] = { static struct rpcb_info rpcb_next_version[] = { #ifdef CONFIG_SUNRPC_BIND34 - { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] }, - { 3, &rpcb_procedures3[RPCBPROC_GETADDR] }, + { + .rpc_vers = RPCBVERS_4, + .rpc_proc = &rpcb_procedures4[RPCBPROC_GETVERSADDR], + }, + { + .rpc_vers = RPCBVERS_3, + .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR], + }, #endif - { 2, &rpcb_procedures2[RPCBPROC_GETPORT] }, - { 0, NULL }, + { + .rpc_vers = RPCBVERS_2, + .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT], + }, + { + .rpc_proc = NULL, + }, }; static struct rpcb_info rpcb_next_version6[] = { #ifdef CONFIG_SUNRPC_BIND34 - { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] }, - { 3, &rpcb_procedures3[RPCBPROC_GETADDR] }, + { + .rpc_vers = RPCBVERS_4, + .rpc_proc = &rpcb_procedures4[RPCBPROC_GETVERSADDR], + }, + { + .rpc_vers = RPCBVERS_3, + .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR], + }, #endif - { 0, NULL }, + { + .rpc_proc = NULL, + }, }; static struct rpc_version rpcb_version2 = { - .number = 2, + .number = RPCBVERS_2, .nrprocs = RPCB_HIGHPROC_2, .procs = rpcb_procedures2 }; static struct rpc_version rpcb_version3 = { - .number = 3, + .number = RPCBVERS_3, .nrprocs = RPCB_HIGHPROC_3, .procs = rpcb_procedures3 }; static struct rpc_version rpcb_version4 = { - .number = 4, + .number = RPCBVERS_4, .nrprocs = RPCB_HIGHPROC_4, .procs = rpcb_procedures4 }; -- cgit v0.10.2 From 6a774051573042cdeb57e81f77b36c25e5856739 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:39 -0400 Subject: SUNRPC: Use rpcbind version 2 GETPORT Clean up: Change the version 2 procedure name to GETPORT. It's the same procedure number as GETADDR, but version 2 implementations usually refer to it as GETPORT. This also now matches the procedure name used in the version 2 procedure entry in the rpcb_next_version[] array, making it slightly less confusing. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index b23a719..a70cc1e 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -575,7 +575,7 @@ out_err: static struct rpc_procinfo rpcb_procedures2[] = { PROC(SET, mapping, set), PROC(UNSET, mapping, set), - PROC(GETADDR, mapping, getport), + PROC(GETPORT, mapping, getport), }; static struct rpc_procinfo rpcb_procedures3[] = { -- cgit v0.10.2 From 8842413aa4c3220ce9313791f99808fc149ca16d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:47 -0400 Subject: SUNRPC: Use GETADDR for rpcbind version 4 queries Some rpcbind servers that do support rpcbind version 4 do not support the GETVERSADDR procedure. Use GETADDR for querying rpcbind servers via rpcbind version 4 instead of GETVERSADDR. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index a70cc1e..625ba72 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -587,6 +587,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { static struct rpc_procinfo rpcb_procedures4[] = { PROC(SET, mapping, set), PROC(UNSET, mapping, set), + PROC(GETADDR, getaddr, getaddr), PROC(GETVERSADDR, getaddr, getaddr), }; @@ -594,7 +595,7 @@ static struct rpcb_info rpcb_next_version[] = { #ifdef CONFIG_SUNRPC_BIND34 { .rpc_vers = RPCBVERS_4, - .rpc_proc = &rpcb_procedures4[RPCBPROC_GETVERSADDR], + .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR], }, { .rpc_vers = RPCBVERS_3, @@ -614,7 +615,7 @@ static struct rpcb_info rpcb_next_version6[] = { #ifdef CONFIG_SUNRPC_BIND34 { .rpc_vers = RPCBVERS_4, - .rpc_proc = &rpcb_procedures4[RPCBPROC_GETVERSADDR], + .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR], }, { .rpc_vers = RPCBVERS_3, -- cgit v0.10.2 From 40fef8a649e5344bfb6a67a7cc3def3e0dad6448 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Jun 2008 17:24:54 -0400 Subject: SUNRPC: Use only rpcbind v2 for AF_INET requests Some server vendors support the higher versions of rpcbind only for AF_INET6. The kernel doesn't need to use v3 or v4 for AF_INET anyway, so change the kernel's rpcbind client to query AF_INET servers over rpcbind v2 only. This has a few interesting benefits: 1. If the rpcbind request is going over TCP, and the server doesn't support rpcbind versions 3 or 4, the client reduces by two the number of ephemeral ports left in TIME_WAIT for each rpcbind request. This will help during NFS mount storms. 2. The rpcbind interaction with servers that don't support rpcbind versions 3 or 4 will use less network traffic. Also helpful during mount storms. 3. We can eliminate the kernel build option that controls whether the kernel's rpcbind client uses rpcbind version 3 and 4 for AF_INET servers. Less complicated kernel configuration... Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/Kconfig b/fs/Kconfig index 1c16de9..0ce72dc 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1799,27 +1799,6 @@ config SUNRPC_XPRT_RDMA If unsure, say N. -config SUNRPC_BIND34 - bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)" - depends on SUNRPC && EXPERIMENTAL - default n - help - RPC requests over IPv6 networks require support for larger - addresses when performing an RPC bind. Sun added support for - IPv6 addressing by creating two new versions of the rpcbind - protocol (RFC 1833). - - This option enables support in the kernel RPC client for - querying rpcbind servers via versions 3 and 4 of the rpcbind - protocol. The kernel automatically falls back to version 2 - if a remote rpcbind service does not support versions 3 or 4. - By themselves, these new versions do not provide support for - RPC over IPv6, but the new protocol versions are necessary to - support it. - - If unsure, say N to get traditional behavior (version 2 rpcbind - requests only). - config RPCSEC_GSS_KRB5 tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" depends on SUNRPC && EXPERIMENTAL diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 625ba72..c62e446 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -592,16 +592,6 @@ static struct rpc_procinfo rpcb_procedures4[] = { }; static struct rpcb_info rpcb_next_version[] = { -#ifdef CONFIG_SUNRPC_BIND34 - { - .rpc_vers = RPCBVERS_4, - .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR], - }, - { - .rpc_vers = RPCBVERS_3, - .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR], - }, -#endif { .rpc_vers = RPCBVERS_2, .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT], @@ -612,7 +602,6 @@ static struct rpcb_info rpcb_next_version[] = { }; static struct rpcb_info rpcb_next_version6[] = { -#ifdef CONFIG_SUNRPC_BIND34 { .rpc_vers = RPCBVERS_4, .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR], @@ -621,7 +610,6 @@ static struct rpcb_info rpcb_next_version6[] = { .rpc_vers = RPCBVERS_3, .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR], }, -#endif { .rpc_proc = NULL, }, -- cgit v0.10.2 From 259875efed06d6936f54c9a264e868937f1bc217 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 2 Jul 2008 14:43:47 -0400 Subject: NFS: set transport defaults after mount option parsing is finished Move the UDP/TCP default timeo/retrans settings for text mounts to nfs_init_timeout_values(), which was were they were always being initialised (and sanity checked) for binary mounts. Document the default timeout values using appropriate #defines. Ensure that we initialise and sanity check the transport protocols that may have been specified by the user. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/client.c b/fs/nfs/client.c index f2a092c..5ee23e7 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -431,14 +431,14 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, { to->to_initval = timeo * HZ / 10; to->to_retries = retrans; - if (!to->to_retries) - to->to_retries = 2; switch (proto) { case XPRT_TRANSPORT_TCP: case XPRT_TRANSPORT_RDMA: + if (to->to_retries == 0) + to->to_retries = NFS_DEF_TCP_RETRANS; if (to->to_initval == 0) - to->to_initval = 60 * HZ; + to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10; if (to->to_initval > NFS_MAX_TCP_TIMEOUT) to->to_initval = NFS_MAX_TCP_TIMEOUT; to->to_increment = to->to_initval; @@ -450,14 +450,17 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, to->to_exponential = 0; break; case XPRT_TRANSPORT_UDP: - default: + if (to->to_retries == 0) + to->to_retries = NFS_DEF_UDP_RETRANS; if (!to->to_initval) - to->to_initval = 11 * HZ / 10; + to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10; if (to->to_initval > NFS_MAX_UDP_TIMEOUT) to->to_initval = NFS_MAX_UDP_TIMEOUT; to->to_maxval = NFS_MAX_UDP_TIMEOUT; to->to_exponential = 1; break; + default: + BUG(); } } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 73a8e59..9c1a960 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -817,6 +817,43 @@ static void nfs_parse_ip_address(char *string, size_t str_len, } /* + * Sanity check the NFS transport protocol. + * + */ +static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt) +{ + switch (mnt->nfs_server.protocol) { + case XPRT_TRANSPORT_UDP: + case XPRT_TRANSPORT_TCP: + case XPRT_TRANSPORT_RDMA: + break; + default: + mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; + } +} + +/* + * For text based NFSv2/v3 mounts, the mount protocol transport default + * settings should depend upon the specified NFS transport. + */ +static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) +{ + nfs_validate_transport_protocol(mnt); + + if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP || + mnt->mount_server.protocol == XPRT_TRANSPORT_TCP) + return; + switch (mnt->nfs_server.protocol) { + case XPRT_TRANSPORT_UDP: + mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; + break; + case XPRT_TRANSPORT_TCP: + case XPRT_TRANSPORT_RDMA: + mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; + } +} + +/* * Error-check and convert a string of mount options from user space into * a data structure */ @@ -896,20 +933,14 @@ static int nfs_parse_mount_options(char *raw, case Opt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; - mnt->timeo = 7; - mnt->retrans = 5; break; case Opt_tcp: mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; - mnt->timeo = 600; - mnt->retrans = 2; break; case Opt_rdma: mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; - mnt->timeo = 600; - mnt->retrans = 2; break; case Opt_acl: mnt->flags &= ~NFS_MOUNT_NOACL; @@ -1103,21 +1134,15 @@ static int nfs_parse_mount_options(char *raw, case Opt_xprt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; - mnt->timeo = 7; - mnt->retrans = 5; break; case Opt_xprt_tcp: mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; - mnt->timeo = 600; - mnt->retrans = 2; break; case Opt_xprt_rdma: /* vector side protocols to TCP */ mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; - mnt->timeo = 600; - mnt->retrans = 2; break; default: goto out_unrec_xprt; @@ -1438,14 +1463,11 @@ static int nfs_validate_mount_data(void *options, args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); args->rsize = NFS_MAX_FILE_IO_SIZE; args->wsize = NFS_MAX_FILE_IO_SIZE; - args->timeo = 600; - args->retrans = 2; args->acregmin = 3; args->acregmax = 60; args->acdirmin = 30; args->acdirmax = 60; args->mount_server.port = 0; /* autobind unless user sets port */ - args->mount_server.protocol = XPRT_TRANSPORT_UDP; args->nfs_server.port = 0; /* autobind unless user sets port */ args->nfs_server.protocol = XPRT_TRANSPORT_TCP; @@ -1546,6 +1568,8 @@ static int nfs_validate_mount_data(void *options, &args->nfs_server.address)) goto out_no_address; + nfs_set_mount_transport_protocol(args); + status = nfs_parse_devname(dev_name, &args->nfs_server.hostname, PAGE_SIZE, @@ -2095,14 +2119,11 @@ static int nfs4_validate_mount_data(void *options, args->rsize = NFS_MAX_FILE_IO_SIZE; args->wsize = NFS_MAX_FILE_IO_SIZE; - args->timeo = 600; - args->retrans = 2; args->acregmin = 3; args->acregmax = 60; args->acdirmin = 30; args->acdirmax = 60; args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ - args->nfs_server.protocol = XPRT_TRANSPORT_TCP; switch (data->version) { case 1: @@ -2163,6 +2184,7 @@ static int nfs4_validate_mount_data(void *options, args->acdirmin = data->acdirmin; args->acdirmax = data->acdirmax; args->nfs_server.protocol = data->proto; + nfs_validate_transport_protocol(args); break; default: { @@ -2175,6 +2197,8 @@ static int nfs4_validate_mount_data(void *options, &args->nfs_server.address)) return -EINVAL; + nfs_validate_transport_protocol(args); + switch (args->auth_flavor_len) { case 0: args->auth_flavors[0] = RPC_AUTH_UNIX; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 27d6a8d..830d9cc 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -12,6 +12,11 @@ #include /* Default timeout values */ +#define NFS_DEF_UDP_TIMEO (11) +#define NFS_DEF_UDP_RETRANS (3) +#define NFS_DEF_TCP_TIMEO (600) +#define NFS_DEF_TCP_RETRANS (2) + #define NFS_MAX_UDP_TIMEOUT (60*HZ) #define NFS_MAX_TCP_TIMEOUT (600*HZ) -- cgit v0.10.2 From ed596a8adb7964cf9d2f7682f9cf2c37322a775d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 26 Jun 2008 17:47:05 -0400 Subject: NFS: Move the nfs_set_port() call out of nfs_parse_mount_options() The remount path does not need to set the port in the server address. Since it's not really a part of option parsing, move the nfs_set_port() call to nfs_parse_mount_options()'s callers. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 9c1a960..de424d2 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1214,9 +1214,6 @@ static int nfs_parse_mount_options(char *raw, } } - nfs_set_port((struct sockaddr *)&mnt->nfs_server.address, - mnt->nfs_server.port); - return 1; out_nomem: @@ -1568,6 +1565,9 @@ static int nfs_validate_mount_data(void *options, &args->nfs_server.address)) goto out_no_address; + nfs_set_port((struct sockaddr *)&args->nfs_server.address, + args->nfs_server.port); + nfs_set_mount_transport_protocol(args); status = nfs_parse_devname(dev_name, @@ -2197,6 +2197,9 @@ static int nfs4_validate_mount_data(void *options, &args->nfs_server.address)) return -EINVAL; + nfs_set_port((struct sockaddr *)&args->nfs_server.address, + args->nfs_server.port); + nfs_validate_transport_protocol(args); switch (args->auth_flavor_len) { -- cgit v0.10.2 From 0e0cab744b17a70ef0f08d818d66935feade7cad Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 26 Jun 2008 17:47:12 -0400 Subject: NFS: use documenting macro constants for initializing ac{reg, dir}{min, max} Clean up. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 15afe3a..46763d1c 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -295,10 +295,10 @@ static int __init root_nfs_name(char *name) nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */ nfs_data.rsize = NFS_DEF_FILE_IO_SIZE; nfs_data.wsize = NFS_DEF_FILE_IO_SIZE; - nfs_data.acregmin = 3; - nfs_data.acregmax = 60; - nfs_data.acdirmin = 30; - nfs_data.acdirmax = 60; + nfs_data.acregmin = NFS_DEF_ACREGMIN; + nfs_data.acregmax = NFS_DEF_ACREGMAX; + nfs_data.acdirmin = NFS_DEF_ACDIRMIN; + nfs_data.acdirmax = NFS_DEF_ACDIRMAX; strcpy(buf, NFS_ROOT); /* Process options received from the remote server */ diff --git a/fs/nfs/super.c b/fs/nfs/super.c index de424d2..ebed63e 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -518,13 +518,13 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, if (nfss->bsize != 0) seq_printf(m, ",bsize=%u", nfss->bsize); seq_printf(m, ",namlen=%u", nfss->namelen); - if (nfss->acregmin != 3*HZ || showdefaults) + if (nfss->acregmin != NFS_DEF_ACREGMIN*HZ || showdefaults) seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ); - if (nfss->acregmax != 60*HZ || showdefaults) + if (nfss->acregmax != NFS_DEF_ACREGMAX*HZ || showdefaults) seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ); - if (nfss->acdirmin != 30*HZ || showdefaults) + if (nfss->acdirmin != NFS_DEF_ACDIRMIN*HZ || showdefaults) seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ); - if (nfss->acdirmax != 60*HZ || showdefaults) + if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults) seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ); for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { if (nfss->flags & nfs_infop->flag) @@ -1460,10 +1460,10 @@ static int nfs_validate_mount_data(void *options, args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); args->rsize = NFS_MAX_FILE_IO_SIZE; args->wsize = NFS_MAX_FILE_IO_SIZE; - args->acregmin = 3; - args->acregmax = 60; - args->acdirmin = 30; - args->acdirmax = 60; + args->acregmin = NFS_DEF_ACREGMIN; + args->acregmax = NFS_DEF_ACREGMAX; + args->acdirmin = NFS_DEF_ACDIRMIN; + args->acdirmax = NFS_DEF_ACDIRMAX; args->mount_server.port = 0; /* autobind unless user sets port */ args->nfs_server.port = 0; /* autobind unless user sets port */ args->nfs_server.protocol = XPRT_TRANSPORT_TCP; @@ -2119,10 +2119,10 @@ static int nfs4_validate_mount_data(void *options, args->rsize = NFS_MAX_FILE_IO_SIZE; args->wsize = NFS_MAX_FILE_IO_SIZE; - args->acregmin = 3; - args->acregmax = 60; - args->acdirmin = 30; - args->acdirmax = 60; + args->acregmin = NFS_DEF_ACREGMIN; + args->acregmax = NFS_DEF_ACREGMAX; + args->acdirmin = NFS_DEF_ACDIRMIN; + args->acdirmax = NFS_DEF_ACDIRMAX; args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ switch (data->version) { diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 830d9cc..29d2619 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -20,6 +20,11 @@ #define NFS_MAX_UDP_TIMEOUT (60*HZ) #define NFS_MAX_TCP_TIMEOUT (600*HZ) +#define NFS_DEF_ACREGMIN (3) +#define NFS_DEF_ACREGMAX (60) +#define NFS_DEF_ACDIRMIN (30) +#define NFS_DEF_ACDIRMAX (60) + /* * When flushing a cluster of dirty pages, there can be different * strategies: -- cgit v0.10.2 From 01060c896e3e1ef53dcb914301c186932cd31b81 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 16:33:38 -0400 Subject: NFS: Refactor logic for parsing NFS security flavor mount options Clean up: Refactor the NFS mount option parsing function to extract the security flavor parsing logic into a separate function. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ebed63e..6eb145e 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -854,6 +854,82 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) } /* + * Parse the value of the 'sec=' option. + * + * The flags setting is for v2/v3. The flavor_len setting is for v4. + * v2/v3 also need to know the difference between NULL and UNIX. + */ +static int nfs_parse_security_flavors(char *value, + struct nfs_parsed_mount_data *mnt) +{ + substring_t args[MAX_OPT_ARGS]; + + dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); + + switch (match_token(value, nfs_secflavor_tokens, args)) { + case Opt_sec_none: + mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 0; + mnt->auth_flavors[0] = RPC_AUTH_NULL; + break; + case Opt_sec_sys: + mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 0; + mnt->auth_flavors[0] = RPC_AUTH_UNIX; + break; + case Opt_sec_krb5: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; + break; + case Opt_sec_krb5i: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; + break; + case Opt_sec_krb5p: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; + break; + case Opt_sec_lkey: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; + break; + case Opt_sec_lkeyi: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; + break; + case Opt_sec_lkeyp: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; + break; + case Opt_sec_spkm: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; + break; + case Opt_sec_spkmi: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; + break; + case Opt_sec_spkmp: + mnt->flags |= NFS_MOUNT_SECFLAVOUR; + mnt->auth_flavor_len = 1; + mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; + break; + default: + return 0; + } + + return 1; +} + +/* * Error-check and convert a string of mount options from user space into * a data structure */ @@ -1054,73 +1130,10 @@ static int nfs_parse_mount_options(char *raw, string = match_strdup(args); if (string == NULL) goto out_nomem; - token = match_token(string, nfs_secflavor_tokens, args); + rc = nfs_parse_security_flavors(string, mnt); kfree(string); - - /* - * The flags setting is for v2/v3. The flavor_len - * setting is for v4. v2/v3 also need to know the - * difference between NULL and UNIX. - */ - switch (token) { - case Opt_sec_none: - mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 0; - mnt->auth_flavors[0] = RPC_AUTH_NULL; - break; - case Opt_sec_sys: - mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 0; - mnt->auth_flavors[0] = RPC_AUTH_UNIX; - break; - case Opt_sec_krb5: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; - break; - case Opt_sec_krb5i: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; - break; - case Opt_sec_krb5p: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; - break; - case Opt_sec_lkey: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; - break; - case Opt_sec_lkeyi: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; - break; - case Opt_sec_lkeyp: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; - break; - case Opt_sec_spkm: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; - break; - case Opt_sec_spkmi: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; - break; - case Opt_sec_spkmp: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; - mnt->auth_flavor_len = 1; - mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; - break; - default: + if (!rc) goto out_unrec_sec; - } break; case Opt_proto: string = match_strdup(args); -- cgit v0.10.2 From dd07c94750cb1ee4449fb0db06623e1865b3e26e Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 16:33:46 -0400 Subject: NFS: Set security flavor default for NFSv2/3 mounts like other defaults Set the default security flavor when we set the other mount option default values. After this change, only the legacy user-space mount path needs to set the NFS_MOUNT_SECFLAVOUR flag. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 6eb145e..2f7e7f2 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -856,8 +856,7 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt) /* * Parse the value of the 'sec=' option. * - * The flags setting is for v2/v3. The flavor_len setting is for v4. - * v2/v3 also need to know the difference between NULL and UNIX. + * The flavor_len setting is for v4 mounts. */ static int nfs_parse_security_flavors(char *value, struct nfs_parsed_mount_data *mnt) @@ -868,57 +867,46 @@ static int nfs_parse_security_flavors(char *value, switch (match_token(value, nfs_secflavor_tokens, args)) { case Opt_sec_none: - mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 0; mnt->auth_flavors[0] = RPC_AUTH_NULL; break; case Opt_sec_sys: - mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 0; mnt->auth_flavors[0] = RPC_AUTH_UNIX; break; case Opt_sec_krb5: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; break; case Opt_sec_krb5i: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; break; case Opt_sec_krb5p: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; break; case Opt_sec_lkey: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; break; case Opt_sec_lkeyi: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; break; case Opt_sec_lkeyp: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; break; case Opt_sec_spkm: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; break; case Opt_sec_spkmi: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; break; case Opt_sec_spkmp: - mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; break; @@ -1480,6 +1468,7 @@ static int nfs_validate_mount_data(void *options, args->mount_server.port = 0; /* autobind unless user sets port */ args->nfs_server.port = 0; /* autobind unless user sets port */ args->nfs_server.protocol = XPRT_TRANSPORT_TCP; + args->auth_flavors[0] = RPC_AUTH_UNIX; switch (data->version) { case 1: @@ -1537,7 +1526,9 @@ static int nfs_validate_mount_data(void *options, args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); args->namlen = data->namlen; args->bsize = data->bsize; - args->auth_flavors[0] = data->pseudoflavor; + + if (data->flags & NFS_MOUNT_SECFLAVOUR) + args->auth_flavors[0] = data->pseudoflavor; if (!args->nfs_server.hostname) goto out_nomem; @@ -1601,9 +1592,6 @@ static int nfs_validate_mount_data(void *options, } } - if (!(args->flags & NFS_MOUNT_SECFLAVOUR)) - args->auth_flavors[0] = RPC_AUTH_UNIX; - #ifndef CONFIG_NFS_V3 if (args->flags & NFS_MOUNT_VER3) goto out_v3_not_compiled; -- cgit v0.10.2 From 6738b2512bdf93ffbefe108b38a9165d5a718c3f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 16:33:54 -0400 Subject: NFS4: Set security flavor default for NFSv4 mounts like other defaults Set the default security flavor when we set the other mount option default values for NFSv4. This cleans up the NFSv4 mount option parsing path to look like the NFSv2/v3 one. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f7e7f2..4bbdbf6 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2125,6 +2125,8 @@ static int nfs4_validate_mount_data(void *options, args->acdirmin = NFS_DEF_ACDIRMIN; args->acdirmax = NFS_DEF_ACDIRMAX; args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ + args->auth_flavors[0] = RPC_AUTH_UNIX; + args->auth_flavor_len = 0; switch (data->version) { case 1: @@ -2140,18 +2142,13 @@ static int nfs4_validate_mount_data(void *options, &args->nfs_server.address)) goto out_no_address; - switch (data->auth_flavourlen) { - case 0: - args->auth_flavors[0] = RPC_AUTH_UNIX; - break; - case 1: + if (data->auth_flavourlen) { + if (data->auth_flavourlen > 1) + goto out_inval_auth; if (copy_from_user(&args->auth_flavors[0], data->auth_flavours, sizeof(args->auth_flavors[0]))) return -EFAULT; - break; - default: - goto out_inval_auth; } c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); @@ -2203,15 +2200,8 @@ static int nfs4_validate_mount_data(void *options, nfs_validate_transport_protocol(args); - switch (args->auth_flavor_len) { - case 0: - args->auth_flavors[0] = RPC_AUTH_UNIX; - break; - case 1: - break; - default: + if (args->auth_flavor_len > 1) goto out_inval_auth; - } if (args->client_address == NULL) goto out_no_client_address; -- cgit v0.10.2 From f45663ce5fb30f76a3414ab3ac69f4dd320e760a Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Jun 2008 19:28:02 -0400 Subject: NFS: Allow either strict or sloppy mount option parsing The kernel's NFS client mount option parser currently doesn't allow unrecognized or incorrect mount options. This prevents misspellings or incorrectly specified mount options from possibly causing silent data corruption. However, NFS mount options are not standardized, so different operating systems can use differently spelled mount options to support similar features, or can support mount options which no other operating system supports. "Sloppy" mount option parsing, which allows the parser to ignore any option it doesn't recognize, is needed to support automounters that often use maps that are shared between heterogenous operating systems. The legacy mount command ignores the validity of the values of mount options entirely, except for the "sec=" and "proto=" options. If an incorrect value is specified, the out-of-range value is passed to the kernel; if a value is specified that contains non-numeric characters, it appears as though the legacy mount command sets that option to zero (probably incorrect behavior in general). In any case, this sets a precedent which we will partially follow for the kernel mount option parser: + if "sloppy" is not set, the parser will be strict about both unrecognized options (same as legacy) and invalid option values (stricter than legacy) + if "sloppy" is set, the parser will ignore unrecognized options and invalid option values (same as legacy) An "invalid" option value in this case means that either the type (integer, short, or string) or sign (for integer values) of the specified value is incorrect. This patch does two things: it changes the NFS client's mount option parsing loop so that it parses the whole string instead of failing at the first unrecognized option or invalid option value. An unrecognized option or an invalid option value cause the option to be skipped. Then, the patch adds a "sloppy" mount option that allows the parsing to succeed anyway if there were any problems during parsing. When parsing a set of options is complete, if there are errors and "sloppy" was specified, return success anyway. Otherwise, only return success if there are no errors. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 4bbdbf6..47cf83e 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -92,8 +92,8 @@ enum { Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, Opt_addr, Opt_mountaddr, Opt_clientaddr, - /* Mount options that are ignored */ - Opt_userspace, Opt_deprecated, + /* Special mount options */ + Opt_userspace, Opt_deprecated, Opt_sloppy, Opt_err }; @@ -103,6 +103,8 @@ static match_table_t nfs_mount_option_tokens = { { Opt_userspace, "fg" }, { Opt_userspace, "retry=%s" }, + { Opt_sloppy, "sloppy" }, + { Opt_soft, "soft" }, { Opt_hard, "hard" }, { Opt_deprecated, "intr" }, @@ -917,15 +919,22 @@ static int nfs_parse_security_flavors(char *value, return 1; } +static void nfs_parse_invalid_value(const char *option) +{ + dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option); +} + /* * Error-check and convert a string of mount options from user space into - * a data structure + * a data structure. The whole mount string is processed; bad options are + * skipped as they are encountered. If there were no errors, return 1; + * otherwise return 0 (zero). */ static int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) { char *p, *string, *secdata; - int rc; + int rc, sloppy = 0, errors = 0; if (!raw) { dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); @@ -958,6 +967,10 @@ static int nfs_parse_mount_options(char *raw, token = match_token(p, nfs_mount_option_tokens, args); switch (token) { + + /* + * boolean options: foo/nofoo + */ case Opt_soft: mnt->flags |= NFS_MOUNT_SOFT; break; @@ -1025,103 +1038,145 @@ static int nfs_parse_mount_options(char *raw, mnt->flags |= NFS_MOUNT_UNSHARED; break; + /* + * options that take numeric values + */ case Opt_port: - if (match_int(args, &option)) - return 0; - if (option < 0 || option > 65535) - return 0; - mnt->nfs_server.port = option; + if (match_int(args, &option) || + option < 0 || option > USHORT_MAX) { + errors++; + nfs_parse_invalid_value("port"); + } else + mnt->nfs_server.port = option; break; case Opt_rsize: - if (match_int(args, &mnt->rsize)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("rsize"); + } else + mnt->rsize = option; break; case Opt_wsize: - if (match_int(args, &mnt->wsize)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("wsize"); + } else + mnt->wsize = option; break; case Opt_bsize: - if (match_int(args, &option)) - return 0; - if (option < 0) - return 0; - mnt->bsize = option; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("bsize"); + } else + mnt->bsize = option; break; case Opt_timeo: - if (match_int(args, &mnt->timeo)) - return 0; + if (match_int(args, &option) || option <= 0) { + errors++; + nfs_parse_invalid_value("timeo"); + } else + mnt->timeo = option; break; case Opt_retrans: - if (match_int(args, &mnt->retrans)) - return 0; + if (match_int(args, &option) || option <= 0) { + errors++; + nfs_parse_invalid_value("retrans"); + } else + mnt->retrans = option; break; case Opt_acregmin: - if (match_int(args, &mnt->acregmin)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("acregmin"); + } else + mnt->acregmin = option; break; case Opt_acregmax: - if (match_int(args, &mnt->acregmax)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("acregmax"); + } else + mnt->acregmax = option; break; case Opt_acdirmin: - if (match_int(args, &mnt->acdirmin)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("acdirmin"); + } else + mnt->acdirmin = option; break; case Opt_acdirmax: - if (match_int(args, &mnt->acdirmax)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("acdirmax"); + } else + mnt->acdirmax = option; break; case Opt_actimeo: - if (match_int(args, &option)) - return 0; - if (option < 0) - return 0; - mnt->acregmin = - mnt->acregmax = - mnt->acdirmin = - mnt->acdirmax = option; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("actimeo"); + } else + mnt->acregmin = mnt->acregmax = + mnt->acdirmin = mnt->acdirmax = option; break; case Opt_namelen: - if (match_int(args, &mnt->namlen)) - return 0; + if (match_int(args, &option) || option < 0) { + errors++; + nfs_parse_invalid_value("namlen"); + } else + mnt->namlen = option; break; case Opt_mountport: - if (match_int(args, &option)) - return 0; - if (option < 0 || option > 65535) - return 0; - mnt->mount_server.port = option; + if (match_int(args, &option) || + option < 0 || option > USHORT_MAX) { + errors++; + nfs_parse_invalid_value("mountport"); + } else + mnt->mount_server.port = option; break; case Opt_mountvers: - if (match_int(args, &option)) - return 0; - if (option < 0) - return 0; - mnt->mount_server.version = option; + if (match_int(args, &option) || + option < NFS_MNT_VERSION || + option > NFS_MNT3_VERSION) { + errors++; + nfs_parse_invalid_value("mountvers"); + } else + mnt->mount_server.version = option; break; case Opt_nfsvers: - if (match_int(args, &option)) - return 0; + if (match_int(args, &option)) { + errors++; + nfs_parse_invalid_value("nfsvers"); + break; + } switch (option) { - case 2: + case NFS2_VERSION: mnt->flags &= ~NFS_MOUNT_VER3; break; - case 3: + case NFS3_VERSION: mnt->flags |= NFS_MOUNT_VER3; break; default: - goto out_unrec_vers; + errors++; + nfs_parse_invalid_value("nfsvers"); } break; + /* + * options that take text values + */ case Opt_sec: string = match_strdup(args); if (string == NULL) goto out_nomem; rc = nfs_parse_security_flavors(string, mnt); kfree(string); - if (!rc) - goto out_unrec_sec; + if (!rc) { + errors++; + dfprintk(MOUNT, "NFS: unrecognized " + "security flavor\n"); + } break; case Opt_proto: string = match_strdup(args); @@ -1146,7 +1201,9 @@ static int nfs_parse_mount_options(char *raw, mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; break; default: - goto out_unrec_xprt; + errors++; + dfprintk(MOUNT, "NFS: unrecognized " + "transport protocol\n"); } break; case Opt_mountproto: @@ -1166,7 +1223,9 @@ static int nfs_parse_mount_options(char *raw, break; case Opt_xprt_rdma: /* not used for side protocols */ default: - goto out_unrec_xprt; + errors++; + dfprintk(MOUNT, "NFS: unrecognized " + "transport protocol\n"); } break; case Opt_addr: @@ -1204,6 +1263,13 @@ static int nfs_parse_mount_options(char *raw, kfree(string); break; + /* + * Special options + */ + case Opt_sloppy: + sloppy = 1; + dfprintk(MOUNT, "NFS: relaxing parsing rules\n"); + break; case Opt_userspace: case Opt_deprecated: dfprintk(MOUNT, "NFS: ignoring mount option " @@ -1211,7 +1277,9 @@ static int nfs_parse_mount_options(char *raw, break; default: - goto out_unknown; + errors++; + dfprintk(MOUNT, "NFS: unrecognized mount option " + "'%s'\n", p); } } @@ -1224,21 +1292,6 @@ out_security_failure: free_secdata(secdata); printk(KERN_INFO "NFS: security options invalid: %d\n", rc); return 0; -out_unrec_vers: - printk(KERN_INFO "NFS: unrecognized NFS version number\n"); - return 0; - -out_unrec_xprt: - printk(KERN_INFO "NFS: unrecognized transport protocol\n"); - return 0; - -out_unrec_sec: - printk(KERN_INFO "NFS: unrecognized security flavor\n"); - return 0; - -out_unknown: - printk(KERN_INFO "NFS: unknown mount option: %s\n", p); - return 0; } /* -- cgit v0.10.2 From 381ba74af55e58bca4c01553835a360a9f6fbb07 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 7 Jul 2008 12:18:53 -0400 Subject: SUNRPC: Ensure our task is notified when an rpcbind call is done If another task is busy in rpcb_getport_async number, it is more efficient to have it wake us up when it has finished instead of arbitrarily sleeping for 5 seconds. Also ensure that rpcb_wake_rpcbind_waiters() is called regardless of whether or not rpcb_getport_done() gets called. Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 09631f6..76739e9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -942,11 +942,9 @@ call_bind_status(struct rpc_task *task) } switch (task->tk_status) { - case -EAGAIN: - dprintk("RPC: %5u rpcbind waiting for another request " - "to finish\n", task->tk_pid); - /* avoid busy-waiting here -- could be a network outage. */ - rpc_delay(task, 5*HZ); + case -ENOMEM: + dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); + rpc_delay(task, HZ >> 2); goto retry_timeout; case -EACCES: dprintk("RPC: %5u remote rpcbind: RPC program/version " diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index c62e446..24e93e0 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -68,6 +68,7 @@ enum { #define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING) static void rpcb_getport_done(struct rpc_task *, void *); +static void rpcb_map_release(void *data); static struct rpc_program rpcb_program; struct rpcbind_args { @@ -80,6 +81,8 @@ struct rpcbind_args { const char * r_netid; const char * r_addr; const char * r_owner; + + int r_status; }; static struct rpc_procinfo rpcb_procedures2[]; @@ -93,14 +96,6 @@ struct rpcb_info { static struct rpcb_info rpcb_next_version[]; static struct rpcb_info rpcb_next_version6[]; -static void rpcb_map_release(void *data) -{ - struct rpcbind_args *map = data; - - xprt_put(map->r_xprt); - kfree(map); -} - static const struct rpc_call_ops rpcb_getport_ops = { .rpc_call_done = rpcb_getport_done, .rpc_release = rpcb_map_release, @@ -112,6 +107,15 @@ static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status) rpc_wake_up_status(&xprt->binding, status); } +static void rpcb_map_release(void *data) +{ + struct rpcbind_args *map = data; + + rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status); + xprt_put(map->r_xprt); + kfree(map); +} + static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, size_t salen, int proto, u32 version, int privileged) @@ -293,17 +297,16 @@ void rpcb_getport_async(struct rpc_task *task) /* Autobind on cloned rpc clients is discouraged */ BUG_ON(clnt->cl_parent != clnt); + /* Put self on the wait queue to ensure we get notified if + * some other task is already attempting to bind the port */ + rpc_sleep_on(&xprt->binding, task, NULL); + if (xprt_test_and_set_binding(xprt)) { - status = -EAGAIN; /* tell caller to check again */ dprintk("RPC: %5u %s: waiting for another binder\n", task->tk_pid, __func__); - goto bailout_nowake; + return; } - /* Put self on queue before sending rpcbind request, in case - * rpcb_getport_done completes before we return from rpc_run_task */ - rpc_sleep_on(&xprt->binding, task, NULL); - /* Someone else may have bound if we slept */ if (xprt_bound(xprt)) { status = 0; @@ -365,15 +368,15 @@ void rpcb_getport_async(struct rpc_task *task) map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ + map->r_status = -EIO; child = rpcb_call_async(rpcb_clnt, map, proc); rpc_release_client(rpcb_clnt); if (IS_ERR(child)) { - status = -EIO; /* rpcb_map_release() has freed the arguments */ dprintk("RPC: %5u %s: rpc_run_task failed\n", task->tk_pid, __func__); - goto bailout_nofree; + return; } rpc_put_task(child); @@ -382,7 +385,6 @@ void rpcb_getport_async(struct rpc_task *task) bailout_nofree: rpcb_wake_rpcbind_waiters(xprt, status); -bailout_nowake: task->tk_status = status; } EXPORT_SYMBOL_GPL(rpcb_getport_async); @@ -421,7 +423,7 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n", child->tk_pid, status, map->r_port); - rpcb_wake_rpcbind_waiters(xprt, status); + map->r_status = status; } static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p, -- cgit v0.10.2 From 9fde9bdd3023854f7b03cc425ff4a0ed51bd1eb3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 9 Jul 2008 10:56:11 -0600 Subject: powerpc/440: Convert Virtex ML507 device tree to dts-v1 Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/dts/virtex440-ml507.dts b/arch/powerpc/boot/dts/virtex440-ml507.dts index f1b3344..dc8e78e 100644 --- a/arch/powerpc/boot/dts/virtex440-ml507.dts +++ b/arch/powerpc/boot/dts/virtex440-ml507.dts @@ -9,36 +9,42 @@ * kind, whether express or implied. */ +/dts-v1/; + / { #address-cells = <1>; #size-cells = <1>; compatible = "xlnx,virtex440"; - dcr-parent = <&ppc440_virtex5_0>; + dcr-parent = <&ppc440_0>; model = "testing"; + DDR2_SDRAM: memory@0 { + device_type = "memory"; + reg = < 0 0x10000000 >; + } ; chosen { bootargs = "console=ttyS0 ip=on root=/dev/ram"; - linux,stdout-path = "/plb@0/serial@d0000000"; + linux,stdout-path = "/plb@0/serial@83e00000"; } ; cpus { #address-cells = <1>; #cpus = <1>; #size-cells = <0>; - ppc440_virtex5_0: cpu@0 { - clock-frequency = <17d78400>; + ppc440_0: cpu@0 { + clock-frequency = <400000000>; compatible = "PowerPC,440", "ibm,ppc440"; - d-cache-line-size = <20>; - d-cache-size = <8000>; + d-cache-line-size = <0x20>; + d-cache-size = <0x8000>; dcr-access-method = "native"; dcr-controller ; device_type = "cpu"; - i-cache-line-size = <20>; - i-cache-size = <8000>; + i-cache-line-size = <0x20>; + i-cache-size = <0x8000>; model = "PowerPC,440"; reg = <0>; - timebase-frequency = <17d78400>; + timebase-frequency = <400000000>; xlnx,apu-control = <1>; - xlnx,apu-udi-0 = ; - xlnx,apu-udi-1 = ; + xlnx,apu-udi-0 = <0>; + xlnx,apu-udi-1 = <0>; xlnx,apu-udi-10 = <0>; xlnx,apu-udi-11 = <0>; xlnx,apu-udi-12 = <0>; @@ -63,41 +69,41 @@ xlnx,dcu-wr-urgent-plb-prio = <0>; xlnx,dma0-control = <0>; xlnx,dma0-plb-prio = <0>; - xlnx,dma0-rxchannelctrl = <1010000>; - xlnx,dma0-rxirqtimer = <3ff>; - xlnx,dma0-txchannelctrl = <1010000>; - xlnx,dma0-txirqtimer = <3ff>; + xlnx,dma0-rxchannelctrl = <0x1010000>; + xlnx,dma0-rxirqtimer = <0x3ff>; + xlnx,dma0-txchannelctrl = <0x1010000>; + xlnx,dma0-txirqtimer = <0x3ff>; xlnx,dma1-control = <0>; xlnx,dma1-plb-prio = <0>; - xlnx,dma1-rxchannelctrl = <1010000>; - xlnx,dma1-rxirqtimer = <3ff>; - xlnx,dma1-txchannelctrl = <1010000>; - xlnx,dma1-txirqtimer = <3ff>; + xlnx,dma1-rxchannelctrl = <0x1010000>; + xlnx,dma1-rxirqtimer = <0x3ff>; + xlnx,dma1-txchannelctrl = <0x1010000>; + xlnx,dma1-txirqtimer = <0x3ff>; xlnx,dma2-control = <0>; xlnx,dma2-plb-prio = <0>; - xlnx,dma2-rxchannelctrl = <1010000>; - xlnx,dma2-rxirqtimer = <3ff>; - xlnx,dma2-txchannelctrl = <1010000>; - xlnx,dma2-txirqtimer = <3ff>; + xlnx,dma2-rxchannelctrl = <0x1010000>; + xlnx,dma2-rxirqtimer = <0x3ff>; + xlnx,dma2-txchannelctrl = <0x1010000>; + xlnx,dma2-txirqtimer = <0x3ff>; xlnx,dma3-control = <0>; xlnx,dma3-plb-prio = <0>; - xlnx,dma3-rxchannelctrl = <1010000>; - xlnx,dma3-rxirqtimer = <3ff>; - xlnx,dma3-txchannelctrl = <1010000>; - xlnx,dma3-txirqtimer = <3ff>; + xlnx,dma3-rxchannelctrl = <0x1010000>; + xlnx,dma3-rxirqtimer = <0x3ff>; + xlnx,dma3-txchannelctrl = <0x1010000>; + xlnx,dma3-txirqtimer = <0x3ff>; xlnx,endian-reset = <0>; xlnx,generate-plb-timespecs = <1>; xlnx,icu-rd-fetch-plb-prio = <0>; xlnx,icu-rd-spec-plb-prio = <0>; xlnx,icu-rd-touch-plb-prio = <0>; - xlnx,interconnect-imask = ; + xlnx,interconnect-imask = <0xffffffff>; xlnx,mplb-allow-lock-xfer = <1>; xlnx,mplb-arb-mode = <0>; - xlnx,mplb-awidth = <20>; - xlnx,mplb-counter = <500>; - xlnx,mplb-dwidth = <80>; + xlnx,mplb-awidth = <0x20>; + xlnx,mplb-counter = <0x500>; + xlnx,mplb-dwidth = <0x80>; xlnx,mplb-max-burst = <8>; - xlnx,mplb-native-dwidth = <80>; + xlnx,mplb-native-dwidth = <0x80>; xlnx,mplb-p2p = <0>; xlnx,mplb-prio-dcur = <2>; xlnx,mplb-prio-dcuw = <3>; @@ -110,54 +116,41 @@ xlnx,mplb-write-pipe-enable = <1>; xlnx,mplb-write-post-enable = <1>; xlnx,num-dma = <1>; - xlnx,pir = ; + xlnx,pir = <0xf>; xlnx,ppc440mc-addr-base = <0>; - xlnx,ppc440mc-addr-high = <1fffffff>; + xlnx,ppc440mc-addr-high = <0xfffffff>; xlnx,ppc440mc-arb-mode = <0>; - xlnx,ppc440mc-bank-conflict-mask = ; - xlnx,ppc440mc-control = ; + xlnx,ppc440mc-bank-conflict-mask = <0xc00000>; + xlnx,ppc440mc-control = <0xf810008f>; xlnx,ppc440mc-max-burst = <8>; xlnx,ppc440mc-prio-dcur = <2>; xlnx,ppc440mc-prio-dcuw = <3>; xlnx,ppc440mc-prio-icu = <4>; xlnx,ppc440mc-prio-splb0 = <1>; xlnx,ppc440mc-prio-splb1 = <0>; - xlnx,ppc440mc-row-conflict-mask = <3ffe00>; + xlnx,ppc440mc-row-conflict-mask = <0x3ffe00>; xlnx,ppcdm-asyncmode = <0>; xlnx,ppcds-asyncmode = <0>; xlnx,user-reset = <0>; DMA0: sdma@80 { compatible = "xlnx,ll-dma-1.00.a"; - dcr-reg = < 80 11 >; - interrupt-parent = <&opb_intc_0>; - interrupts = < 5 2 6 2 >; + dcr-reg = < 0x80 0x11 >; + interrupt-parent = <&xps_intc_0>; + interrupts = < 9 2 0xa 2 >; } ; } ; } ; - plb_v46_cfb_0: plb@0 { + plb_v46_0: plb@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "xlnx,plb-v46-1.02.a"; + compatible = "xlnx,plb-v46-1.02.a", "simple-bus"; ranges ; - iic_bus: i2c@d0020000 { - compatible = "xlnx,xps-iic-2.00.a"; - interrupt-parent = <&opb_intc_0>; - interrupts = < 7 2 >; - reg = < d0020000 200 >; - xlnx,clk-freq = <5f5e100>; - xlnx,family = "virtex5"; - xlnx,gpo-width = <1>; - xlnx,iic-freq = <186a0>; - xlnx,scl-inertial-delay = <0>; - xlnx,sda-inertial-delay = <0>; - xlnx,ten-bit-adr = <0>; - } ; - leds_8bit: gpio@d0010200 { + DIP_Switches_8Bit: gpio@81460000 { compatible = "xlnx,xps-gpio-1.00.a"; - interrupt-parent = <&opb_intc_0>; - interrupts = < 1 2 >; - reg = < d0010200 200 >; - xlnx,all-inputs = <0>; + interrupt-parent = <&xps_intc_0>; + interrupts = < 6 2 >; + reg = < 0x81460000 0x10000 >; + xlnx,all-inputs = <1>; xlnx,all-inputs-2 = <0>; xlnx,dout-default = <0>; xlnx,dout-default-2 = <0>; @@ -167,72 +160,137 @@ xlnx,is-bidir = <1>; xlnx,is-bidir-2 = <1>; xlnx,is-dual = <0>; - xlnx,tri-default = ; - xlnx,tri-default-2 = ; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; } ; - ll_temac_0: xps-ll-temac@91200000 { + Hard_Ethernet_MAC: xps-ll-temac@81c00000 { #address-cells = <1>; #size-cells = <1>; compatible = "xlnx,compound"; - ethernet@91200000 { - compatible = "xlnx,xps-ll-temac-1.01.a"; + ethernet@81c00000 { + compatible = "xlnx,xps-ll-temac-1.01.b"; device_type = "network"; - interrupt-parent = <&opb_intc_0>; - interrupts = < 4 2 >; + interrupt-parent = <&xps_intc_0>; + interrupts = < 5 2 >; llink-connected = <&DMA0>; local-mac-address = [ 02 00 00 00 00 00 ]; - reg = < 91200000 40 >; + reg = < 0x81c00000 0x40 >; xlnx,bus2core-clk-ratio = <1>; xlnx,phy-type = <1>; xlnx,phyaddr = <1>; - xlnx,rxcsum = <0>; - xlnx,rxfifo = <4000>; + xlnx,rxcsum = <1>; + xlnx,rxfifo = <0x1000>; xlnx,temac-type = <0>; - xlnx,txcsum = <0>; - xlnx,txfifo = <4000>; + xlnx,txcsum = <1>; + xlnx,txfifo = <0x1000>; } ; } ; - opb_intc_0: interrupt-controller@d0020200 { - #interrupt-cells = <2>; - compatible = "xlnx,xps-intc-1.00.a"; - interrupt-controller ; - reg = < d0020200 20 >; - xlnx,num-intr-inputs = <8>; + LEDs_8Bit: gpio@81400000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = < 0x81400000 0x10000 >; + xlnx,all-inputs = <0>; + xlnx,all-inputs-2 = <0>; + xlnx,dout-default = <0>; + xlnx,dout-default-2 = <0>; + xlnx,family = "virtex5"; + xlnx,gpio-width = <8>; + xlnx,interrupt-present = <0>; + xlnx,is-bidir = <1>; + xlnx,is-bidir-2 = <1>; + xlnx,is-dual = <0>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; } ; - plb_bram_if_cntlr_0: xps-bram-if-cntlr@ffff0000 { - compatible = "xlnx,xps-bram-if-cntlr-1.00.a"; - reg = < ffff0000 10000 >; + LEDs_Positions: gpio@81420000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = < 0x81420000 0x10000 >; + xlnx,all-inputs = <0>; + xlnx,all-inputs-2 = <0>; + xlnx,dout-default = <0>; + xlnx,dout-default-2 = <0>; xlnx,family = "virtex5"; + xlnx,gpio-width = <5>; + xlnx,interrupt-present = <0>; + xlnx,is-bidir = <1>; + xlnx,is-bidir-2 = <1>; + xlnx,is-dual = <0>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; } ; - plb_bram_if_cntlr_1: xps-bram-if-cntlr@eee00000 { - compatible = "xlnx,xps-bram-if-cntlr-1.00.a"; - reg = < eee00000 2000 >; + Push_Buttons_5Bit: gpio@81440000 { + compatible = "xlnx,xps-gpio-1.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 7 2 >; + reg = < 0x81440000 0x10000 >; + xlnx,all-inputs = <1>; + xlnx,all-inputs-2 = <0>; + xlnx,dout-default = <0>; + xlnx,dout-default-2 = <0>; xlnx,family = "virtex5"; + xlnx,gpio-width = <5>; + xlnx,interrupt-present = <1>; + xlnx,is-bidir = <1>; + xlnx,is-bidir-2 = <1>; + xlnx,is-dual = <0>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; } ; - rs232_uart_0: serial@d0000000 { - clock-frequency = <1312d00>; + RS232_Uart_1: serial@83e00000 { + clock-frequency = <100000000>; compatible = "xlnx,xps-uart16550-2.00.a", "ns16550"; - current-speed = <2580>; + current-speed = <0x2580>; device_type = "serial"; - interrupt-parent = <&opb_intc_0>; - interrupts = < 0 2 >; - reg = < d0000000 2000 >; - reg-offset = <1003>; + interrupt-parent = <&xps_intc_0>; + interrupts = < 8 2 >; + reg = < 0x83e00000 0x10000 >; + reg-offset = <3>; reg-shift = <2>; xlnx,family = "virtex5"; xlnx,has-external-rclk = <0>; - xlnx,has-external-xin = <1>; + xlnx,has-external-xin = <0>; xlnx,is-a-16550 = <1>; } ; - sysace_compactflash: sysace@d0030100 { + SysACE_CompactFlash: sysace@83600000 { compatible = "xlnx,xps-sysace-1.00.a"; - reg = < d0030100 80 >; + interrupt-parent = <&xps_intc_0>; + interrupts = < 4 2 >; + reg = < 0x83600000 0x10000 >; xlnx,family = "virtex5"; - xlnx,mem-width = <10>; + xlnx,mem-width = <0x10>; + } ; + xps_bram_if_cntlr_1: xps-bram-if-cntlr@ffff0000 { + compatible = "xlnx,xps-bram-if-cntlr-1.00.a"; + reg = < 0xffff0000 0x10000 >; + xlnx,family = "virtex5"; + } ; + xps_intc_0: interrupt-controller@81800000 { + #interrupt-cells = <2>; + compatible = "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x81800000 0x10000 >; + xlnx,num-intr-inputs = <0xb>; + } ; + xps_timebase_wdt_1: xps-timebase-wdt@83a00000 { + compatible = "xlnx,xps-timebase-wdt-1.00.b"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 2 0 1 2 >; + reg = < 0x83a00000 0x10000 >; + xlnx,family = "virtex5"; + xlnx,wdt-enable-once = <0>; + xlnx,wdt-interval = <0x1e>; + } ; + xps_timer_1: timer@83c00000 { + compatible = "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 3 2 >; + reg = < 0x83c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "virtex5"; + xlnx,gen0-assert = <1>; + xlnx,gen1-assert = <1>; + xlnx,one-timer-only = <1>; + xlnx,trig0-assert = <1>; + xlnx,trig1-assert = <1>; } ; - } ; - ppc440mc_ddr2_0: memory@0 { - device_type = "memory"; - reg = < 0 20000000 >; } ; } ; -- cgit v0.10.2 From 1bc54c03117b90716e0dedd7abb2a20405de65df Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 8 Jul 2008 15:54:40 +1000 Subject: powerpc: rework 4xx PTE access and TLB miss This is some preliminary work to improve TLB management on SW loaded TLB powerpc platforms. This introduce support for non-atomic PTE operations in pgtable-ppc32.h and removes write back to the PTE from the TLB miss handlers. In addition, the DSI interrupt code no longer tries to fixup write permission, this is left to generic code, and _PAGE_HWWRITE is gone. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Josh Boyer diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 2944529..f3a1ea9 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -293,119 +293,9 @@ interrupt_base: MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception) /* Data Storage Interrupt */ - START_EXCEPTION(DataStorage) - mtspr SPRN_SPRG0, r10 /* Save some working registers */ - mtspr SPRN_SPRG1, r11 - mtspr SPRN_SPRG4W, r12 - mtspr SPRN_SPRG5W, r13 - mfcr r11 - mtspr SPRN_SPRG7W, r11 - - /* - * Check if it was a store fault, if not then bail - * because a user tried to access a kernel or - * read-protected page. Otherwise, get the - * offending address and handle it. - */ - mfspr r10, SPRN_ESR - andis. r10, r10, ESR_ST@h - beq 2f - - mfspr r10, SPRN_DEAR /* Get faulting address */ - - /* If we are faulting a kernel address, we have to use the - * kernel page tables. - */ - lis r11, PAGE_OFFSET@h - cmplw r10, r11 - blt+ 3f - lis r11, swapper_pg_dir@h - ori r11, r11, swapper_pg_dir@l - - mfspr r12,SPRN_MMUCR - rlwinm r12,r12,0,0,23 /* Clear TID */ - - b 4f - - /* Get the PGD for the current thread */ -3: - mfspr r11,SPRN_SPRG3 - lwz r11,PGDIR(r11) - - /* Load PID into MMUCR TID */ - mfspr r12,SPRN_MMUCR /* Get MMUCR */ - mfspr r13,SPRN_PID /* Get PID */ - rlwimi r12,r13,0,24,31 /* Set TID */ - -4: - mtspr SPRN_MMUCR,r12 - - rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ - lwzx r11, r12, r11 /* Get pgd/pmd entry */ - rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ - beq 2f /* Bail if no table */ - - rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ - lwz r11, 4(r12) /* Get pte entry */ - - andi. r13, r11, _PAGE_RW /* Is it writeable? */ - beq 2f /* Bail if not */ - - /* Update 'changed'. - */ - ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE - stw r11, 4(r12) /* Update Linux page table */ - - li r13, PPC44x_TLB_SR@l /* Set SR */ - rlwimi r13, r11, 29, 29, 29 /* SX = _PAGE_HWEXEC */ - rlwimi r13, r11, 0, 30, 30 /* SW = _PAGE_RW */ - rlwimi r13, r11, 29, 28, 28 /* UR = _PAGE_USER */ - rlwimi r12, r11, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */ - rlwimi r12, r11, 29, 30, 30 /* (_PAGE_USER>>3)->r12 */ - and r12, r12, r11 /* HWEXEC/RW & USER */ - rlwimi r13, r12, 0, 26, 26 /* UX = HWEXEC & USER */ - rlwimi r13, r12, 3, 27, 27 /* UW = RW & USER */ - - rlwimi r11,r13,0,26,31 /* Insert static perms */ - - /* - * Clear U0-U3 and WL1 IL1I IL1D IL2I IL2D bits which are added - * on newer 440 cores like the 440x6 used on AMCC 460EX/460GT (see - * include/asm-powerpc/pgtable-ppc32.h for details). - */ - rlwinm r11,r11,0,20,10 - - /* find the TLB index that caused the fault. It has to be here. */ - tlbsx r10, 0, r10 - - tlbwe r11, r10, PPC44x_TLB_ATTRIB /* Write ATTRIB */ - - /* Done...restore registers and get out of here. - */ - mfspr r11, SPRN_SPRG7R - mtcr r11 - mfspr r13, SPRN_SPRG5R - mfspr r12, SPRN_SPRG4R + DATA_STORAGE_EXCEPTION - mfspr r11, SPRN_SPRG1 - mfspr r10, SPRN_SPRG0 - rfi /* Force context change */ - -2: - /* - * The bailout. Restore registers to pre-exception conditions - * and call the heavyweights to help us out. - */ - mfspr r11, SPRN_SPRG7R - mtcr r11 - mfspr r13, SPRN_SPRG5R - mfspr r12, SPRN_SPRG4R - - mfspr r11, SPRN_SPRG1 - mfspr r10, SPRN_SPRG0 - b data_access - - /* Instruction Storage Interrupt */ + /* Instruction Storage Interrupt */ INSTRUCTION_STORAGE_EXCEPTION /* External Input Interrupt */ @@ -423,7 +313,6 @@ interrupt_base: #else EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) #endif - /* System Call Interrupt */ START_EXCEPTION(SystemCall) NORMAL_EXCEPTION_PROLOG @@ -484,18 +373,57 @@ interrupt_base: 4: mtspr SPRN_MMUCR,r12 + /* Mask of required permission bits. Note that while we + * do copy ESR:ST to _PAGE_RW position as trying to write + * to an RO page is pretty common, we don't do it with + * _PAGE_DIRTY. We could do it, but it's a fairly rare + * event so I'd rather take the overhead when it happens + * rather than adding an instruction here. We should measure + * whether the whole thing is worth it in the first place + * as we could avoid loading SPRN_ESR completely in the first + * place... + * + * TODO: Is it worth doing that mfspr & rlwimi in the first + * place or can we save a couple of instructions here ? + */ + mfspr r12,SPRN_ESR + li r13,_PAGE_PRESENT|_PAGE_ACCESSED + rlwimi r13,r12,10,30,30 + + /* Load the PTE */ rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ - lwz r11, 4(r12) /* Get pte entry */ - andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ - beq 2f /* Bail if not present */ + lwz r11, 0(r12) /* Get high word of pte entry */ + lwz r12, 4(r12) /* Get low word of pte entry */ - ori r11, r11, _PAGE_ACCESSED - stw r11, 4(r12) + lis r10,tlb_44x_index@ha + + andc. r13,r13,r12 /* Check permission */ + + /* Load the next available TLB index */ + lwz r13,tlb_44x_index@l(r10) + + bne 2f /* Bail if permission mismach */ + + /* Increment, rollover, and store TLB index */ + addi r13,r13,1 + + /* Compare with watermark (instruction gets patched) */ + .globl tlb_44x_patch_hwater_D +tlb_44x_patch_hwater_D: + cmpwi 0,r13,1 /* reserve entries */ + ble 5f + li r13,0 +5: + /* Store the next available TLB index */ + stw r13,tlb_44x_index@l(r10) + + /* Re-load the faulting address */ + mfspr r10,SPRN_DEAR /* Jump to common tlb load */ b finish_tlb_load @@ -510,7 +438,7 @@ interrupt_base: mfspr r12, SPRN_SPRG4R mfspr r11, SPRN_SPRG1 mfspr r10, SPRN_SPRG0 - b data_access + b DataStorage /* Instruction TLB Error Interrupt */ /* @@ -554,18 +482,42 @@ interrupt_base: 4: mtspr SPRN_MMUCR,r12 + /* Make up the required permissions */ + li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ lwzx r11, r12, r11 /* Get pgd/pmd entry */ rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ beq 2f /* Bail if no table */ rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ - lwz r11, 4(r12) /* Get pte entry */ - andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ - beq 2f /* Bail if not present */ + lwz r11, 0(r12) /* Get high word of pte entry */ + lwz r12, 4(r12) /* Get low word of pte entry */ - ori r11, r11, _PAGE_ACCESSED - stw r11, 4(r12) + lis r10,tlb_44x_index@ha + + andc. r13,r13,r12 /* Check permission */ + + /* Load the next available TLB index */ + lwz r13,tlb_44x_index@l(r10) + + bne 2f /* Bail if permission mismach */ + + /* Increment, rollover, and store TLB index */ + addi r13,r13,1 + + /* Compare with watermark (instruction gets patched) */ + .globl tlb_44x_patch_hwater_I +tlb_44x_patch_hwater_I: + cmpwi 0,r13,1 /* reserve entries */ + ble 5f + li r13,0 +5: + /* Store the next available TLB index */ + stw r13,tlb_44x_index@l(r10) + + /* Re-load the faulting address */ + mfspr r10,SPRN_SRR0 /* Jump to common TLB load point */ b finish_tlb_load @@ -587,86 +539,40 @@ interrupt_base: /* * Local functions - */ - /* - * Data TLB exceptions will bail out to this point - * if they can't resolve the lightweight TLB fault. - */ -data_access: - NORMAL_EXCEPTION_PROLOG - mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ - stw r5,_ESR(r11) - mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ - EXC_XFER_EE_LITE(0x0300, handle_page_fault) + */ /* * Both the instruction and data TLB miss get to this * point to load the TLB. * r10 - EA of fault - * r11 - available to use - * r12 - Pointer to the 64-bit PTE - * r13 - available to use + * r11 - PTE high word value + * r12 - PTE low word value + * r13 - TLB index * MMUCR - loaded with proper value when we get here * Upon exit, we reload everything and RFI. */ finish_tlb_load: - /* - * We set execute, because we don't have the granularity to - * properly set this at the page level (Linux problem). - * If shared is set, we cause a zero PID->TID load. - * Many of these bits are software only. Bits we don't set - * here we (properly should) assume have the appropriate value. - */ - - /* Load the next available TLB index */ - lis r13, tlb_44x_index@ha - lwz r13, tlb_44x_index@l(r13) - /* Load the TLB high watermark */ - lis r11, tlb_44x_hwater@ha - lwz r11, tlb_44x_hwater@l(r11) - - /* Increment, rollover, and store TLB index */ - addi r13, r13, 1 - cmpw 0, r13, r11 /* reserve entries */ - ble 7f - li r13, 0 -7: - /* Store the next available TLB index */ - lis r11, tlb_44x_index@ha - stw r13, tlb_44x_index@l(r11) - - lwz r11, 0(r12) /* Get MS word of PTE */ - lwz r12, 4(r12) /* Get LS word of PTE */ - rlwimi r11, r12, 0, 0 , 19 /* Insert RPN */ - tlbwe r11, r13, PPC44x_TLB_XLAT /* Write XLAT */ + /* Combine RPN & ERPN an write WS 0 */ + rlwimi r11,r12,0,0,19 + tlbwe r11,r13,PPC44x_TLB_XLAT /* - * Create PAGEID. This is the faulting address, + * Create WS1. This is the faulting address (EPN), * page size, and valid flag. */ - li r11, PPC44x_TLB_VALID | PPC44x_TLB_4K - rlwimi r10, r11, 0, 20, 31 /* Insert valid and page size */ - tlbwe r10, r13, PPC44x_TLB_PAGEID /* Write PAGEID */ - - li r10, PPC44x_TLB_SR@l /* Set SR */ - rlwimi r10, r12, 0, 30, 30 /* Set SW = _PAGE_RW */ - rlwimi r10, r12, 29, 29, 29 /* SX = _PAGE_HWEXEC */ - rlwimi r10, r12, 29, 28, 28 /* UR = _PAGE_USER */ - rlwimi r11, r12, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */ - and r11, r12, r11 /* HWEXEC & USER */ - rlwimi r10, r11, 0, 26, 26 /* UX = HWEXEC & USER */ - - rlwimi r12, r10, 0, 26, 31 /* Insert static perms */ - - /* - * Clear U0-U3 and WL1 IL1I IL1D IL2I IL2D bits which are added - * on newer 440 cores like the 440x6 used on AMCC 460EX/460GT (see - * include/asm-powerpc/pgtable-ppc32.h for details). - */ - rlwinm r12, r12, 0, 20, 10 - - tlbwe r12, r13, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K + rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ + tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ + + /* And WS 2 */ + li r10,0xf85 /* Mask to apply from PTE */ + rlwimi r10,r12,29,30,30 /* DIRTY -> SW position */ + and r11,r12,r10 /* Mask PTE bits to keep */ + andi. r10,r12,_PAGE_USER /* User page ? */ + beq 1f /* nope, leave U bits empty */ + rlwimi r11,r11,3,26,28 /* yes, copy S bits to U */ +1: tlbwe r11,r13,PPC44x_TLB_ATTRIB /* Write ATTRIB */ /* Done...restore registers and get out of here. */ diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index b0461be..fce2df9 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -340,6 +340,14 @@ label: addi r3,r1,STACK_FRAME_OVERHEAD; \ EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) +#define DATA_STORAGE_EXCEPTION \ + START_EXCEPTION(DataStorage) \ + NORMAL_EXCEPTION_PROLOG; \ + mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ + stw r5,_ESR(r11); \ + mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ + EXC_XFER_EE_LITE(0x0300, handle_page_fault) + #define INSTRUCTION_STORAGE_EXCEPTION \ START_EXCEPTION(InstructionStorage) \ NORMAL_EXCEPTION_PROLOG; \ diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c index 953fb91..98052ac 100644 --- a/arch/powerpc/mm/44x_mmu.c +++ b/arch/powerpc/mm/44x_mmu.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "mmu_decl.h" @@ -37,11 +38,35 @@ unsigned int tlb_44x_index; /* = 0 */ unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS; int icache_44x_need_flush; +static void __init ppc44x_update_tlb_hwater(void) +{ + extern unsigned int tlb_44x_patch_hwater_D[]; + extern unsigned int tlb_44x_patch_hwater_I[]; + + /* The TLB miss handlers hard codes the watermark in a cmpli + * instruction to improve performances rather than loading it + * from the global variable. Thus, we patch the instructions + * in the 2 TLB miss handlers when updating the value + */ + tlb_44x_patch_hwater_D[0] = (tlb_44x_patch_hwater_D[0] & 0xffff0000) | + tlb_44x_hwater; + flush_icache_range((unsigned long)&tlb_44x_patch_hwater_D[0], + (unsigned long)&tlb_44x_patch_hwater_D[1]); + tlb_44x_patch_hwater_I[0] = (tlb_44x_patch_hwater_I[0] & 0xffff0000) | + tlb_44x_hwater; + flush_icache_range((unsigned long)&tlb_44x_patch_hwater_I[0], + (unsigned long)&tlb_44x_patch_hwater_I[1]); +} + /* * "Pins" a 256MB TLB entry in AS0 for kernel lowmem */ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) { + unsigned int entry = tlb_44x_hwater--; + + ppc44x_update_tlb_hwater(); + __asm__ __volatile__( "tlbwe %2,%3,%4\n" "tlbwe %1,%3,%5\n" @@ -50,7 +75,7 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), "r" (phys), "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M), - "r" (tlb_44x_hwater--), /* slot for this TLB entry */ + "r" (entry), "i" (PPC44x_TLB_PAGEID), "i" (PPC44x_TLB_XLAT), "i" (PPC44x_TLB_ATTRIB)); @@ -58,6 +83,8 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) void __init MMU_init_hw(void) { + ppc44x_update_tlb_hwater(); + flush_instruction_cache(); } diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 7b25107..1707d00 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -306,7 +306,8 @@ good_area: flush_dcache_icache_page(page); set_bit(PG_arch_1, &page->flags); } - pte_update(ptep, 0, _PAGE_HWEXEC); + pte_update(ptep, 0, _PAGE_HWEXEC | + _PAGE_ACCESSED); _tlbie(address, mm->context.id); pte_unmap_unlock(ptep, ptl); up_read(&mm->mmap_sem); diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h index e1d2bb5..11eede4 100644 --- a/include/asm-powerpc/pgtable-ppc32.h +++ b/include/asm-powerpc/pgtable-ppc32.h @@ -182,6 +182,9 @@ extern int icache_44x_need_flush; #define _PMD_SIZE_16M 0x0e0 #define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4)) +/* Until my rework is finished, 40x still needs atomic PTE updates */ +#define PTE_ATOMIC_UPDATES 1 + #elif defined(CONFIG_44x) /* * Definitions for PPC440 @@ -253,17 +256,17 @@ extern int icache_44x_need_flush; */ #define _PAGE_PRESENT 0x00000001 /* S: PTE valid */ -#define _PAGE_RW 0x00000002 /* S: Write permission */ +#define _PAGE_RW 0x00000002 /* S: Write permission */ #define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */ +#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */ #define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ -#define _PAGE_HWWRITE 0x00000010 /* H: Dirty & RW */ -#define _PAGE_HWEXEC 0x00000020 /* H: Execute permission */ -#define _PAGE_USER 0x00000040 /* S: User page */ -#define _PAGE_ENDIAN 0x00000080 /* H: E bit */ -#define _PAGE_GUARDED 0x00000100 /* H: G bit */ -#define _PAGE_DIRTY 0x00000200 /* S: Page dirty */ -#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */ -#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */ +#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */ +#define _PAGE_USER 0x00000040 /* S: User page */ +#define _PAGE_ENDIAN 0x00000080 /* H: E bit */ +#define _PAGE_GUARDED 0x00000100 /* H: G bit */ +#define _PAGE_COHERENT 0x00000200 /* H: M bit */ +#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */ +#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */ /* TODO: Add large page lowmem mapping support */ #define _PMD_PRESENT 0 @@ -273,6 +276,7 @@ extern int icache_44x_need_flush; /* ERPN in a PTE never gets cleared, ignore it */ #define _PTE_NONE_MASK 0xffffffff00000000ULL + #elif defined(CONFIG_FSL_BOOKE) /* MMU Assist Register 3: @@ -315,6 +319,9 @@ extern int icache_44x_need_flush; #define _PMD_PRESENT_MASK (PAGE_MASK) #define _PMD_BAD (~PAGE_MASK) +/* Until my rework is finished, FSL BookE still needs atomic PTE updates */ +#define PTE_ATOMIC_UPDATES 1 + #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ #define _PAGE_PRESENT 0x0001 /* Page is valid */ @@ -345,6 +352,9 @@ extern int icache_44x_need_flush; #define _PTE_NONE_MASK _PAGE_ACCESSED +/* Until my rework is finished, 8xx still needs atomic PTE updates */ +#define PTE_ATOMIC_UPDATES 1 + #else /* CONFIG_6xx */ /* Definitions for 60x, 740/750, etc. */ #define _PAGE_PRESENT 0x001 /* software: pte contains a translation */ @@ -365,6 +375,10 @@ extern int icache_44x_need_flush; #define _PMD_PRESENT 0 #define _PMD_PRESENT_MASK (PAGE_MASK) #define _PMD_BAD (~PAGE_MASK) + +/* Hash table based platforms need atomic updates of the linux PTE */ +#define PTE_ATOMIC_UPDATES 1 + #endif /* @@ -557,9 +571,11 @@ extern void add_hash_page(unsigned context, unsigned long va, * low PTE word since we expect ALL flag bits to be there */ #ifndef CONFIG_PTE_64BIT -static inline unsigned long pte_update(pte_t *p, unsigned long clr, +static inline unsigned long pte_update(pte_t *p, + unsigned long clr, unsigned long set) { +#ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; __asm__ __volatile__("\ @@ -572,16 +588,26 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" (clr), "r" (set), "m" (*p) : "cc" ); +#else /* PTE_ATOMIC_UPDATES */ + unsigned long old = pte_val(*p); + *p = __pte((old & ~clr) | set); +#endif /* !PTE_ATOMIC_UPDATES */ + #ifdef CONFIG_44x if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC)) icache_44x_need_flush = 1; #endif return old; } -#else -static inline unsigned long long pte_update(pte_t *p, unsigned long clr, - unsigned long set) +#else /* CONFIG_PTE_64BIT */ +/* TODO: Change that to only modify the low word and move set_pte_at() + * out of line + */ +static inline unsigned long long pte_update(pte_t *p, + unsigned long clr, + unsigned long set) { +#ifdef PTE_ATOMIC_UPDATES unsigned long long old; unsigned long tmp; @@ -596,13 +622,18 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr, : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p) : "cc" ); +#else /* PTE_ATOMIC_UPDATES */ + unsigned long long old = pte_val(*p); + *p = __pte((old & ~clr) | set); +#endif /* !PTE_ATOMIC_UPDATES */ + #ifdef CONFIG_44x if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC)) icache_44x_need_flush = 1; #endif return old; } -#endif +#endif /* CONFIG_PTE_64BIT */ /* * set_pte stores a linux PTE into the linux page table. @@ -671,7 +702,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty) ({ \ int __changed = !pte_same(*(__ptep), __entry); \ if (__changed) { \ - __ptep_set_access_flags(__ptep, __entry, __dirty); \ + __ptep_set_access_flags(__ptep, __entry, __dirty); \ flush_tlb_page_nohash(__vma, __address); \ } \ __changed; \ -- cgit v0.10.2 From 4248652d4f3ce6be1a94c77ddbfeb937af1df800 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Wed, 9 Jul 2008 05:00:10 +1000 Subject: powerpc/44x: Support NAND boot for Rev A Warp boards Allow the Rev A Warp boards to boot from NAND. Signed-off-by: Sean MacLennan Signed-off-by: Josh Boyer diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c index 7bec281..e55746b 100644 --- a/arch/powerpc/platforms/44x/warp-nand.c +++ b/arch/powerpc/platforms/44x/warp-nand.c @@ -113,9 +113,14 @@ static int warp_setup_nand_flash(void) pp = of_find_property(np, "reg", NULL); if (pp && (pp->length == 12)) { u32 *v = pp->value; - if (v[2] == 0x4000000) + if (v[2] == 0x4000000) { /* Rev A = 64M NAND */ - warp_nand_chip0.nr_partitions = 2; + warp_nand_chip0.nr_partitions = 3; + + nand_parts[1].size = 0x3000000; + nand_parts[2].offset = 0x3200000; + nand_parts[2].size = 0x0e00000; + } } of_node_put(np); } -- cgit v0.10.2 From 3fa69dd57759cb45fa48bb70a055025d25a7e4e8 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 9 Jul 2008 14:05:15 -0400 Subject: powerpc/44x: Update ppc44x_defconfig Add the virtex and sam440ep platforms to the multiboard defconfig Signed-off-by: Josh Boyer diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 12f9b5a..f9d279b 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc6 -# Sat Apr 5 09:35:48 2008 +# Linux kernel version: 2.6.26-rc8 +# Wed Jul 9 13:50:48 2008 # # CONFIG_PPC64 is not set @@ -32,6 +32,8 @@ CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_GENERIC_HWEIGHT=y @@ -88,6 +90,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_EXTRA_PASS=y @@ -115,12 +118,14 @@ CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y +# 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=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set @@ -157,6 +162,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y # CONFIG_PQ2ADS is not set CONFIG_BAMBOO=y CONFIG_EBONY=y +CONFIG_SAM440EP=y CONFIG_SEQUOIA=y CONFIG_TAISHAN=y CONFIG_KATMAI=y @@ -164,6 +170,7 @@ CONFIG_RAINIER=y CONFIG_WARP=y CONFIG_CANYONLANDS=y CONFIG_YOSEMITE=y +CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y CONFIG_440EP=y CONFIG_440EPX=y CONFIG_440GRX=y @@ -172,6 +179,8 @@ CONFIG_440GX=y CONFIG_440SPe=y CONFIG_460EX=y CONFIG_IBM440EP_ERR42=y +CONFIG_XILINX_VIRTEX=y +CONFIG_XILINX_VIRTEX_5_FXT=y # CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set @@ -220,13 +229,16 @@ 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_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y +CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set +CONFIG_EXTRA_TARGETS="" CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y @@ -246,6 +258,7 @@ CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set # # Advanced setup @@ -255,13 +268,13 @@ CONFIG_PCI_LEGACY=y # # Default settings for advanced configuration options are used # -CONFIG_HIGHMEM_START=0xfe000000 CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 CONFIG_TASK_SIZE=0xc0000000 CONFIG_CONSISTENT_START=0xff100000 CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_BOOT_LOAD=0x01000000 # # Networking @@ -303,8 +316,6 @@ CONFIG_TCP_CONG_CUBIC=y 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_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set @@ -366,6 +377,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -478,6 +490,10 @@ CONFIG_HAVE_IDE=y # # 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 @@ -528,7 +544,6 @@ CONFIG_NETDEV_1000=y # 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 @@ -546,6 +561,7 @@ CONFIG_NETDEV_10000=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_SFC is not set # CONFIG_TR is not set # @@ -553,6 +569,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -579,6 +596,7 @@ CONFIG_NETDEV_10000=y # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -611,22 +629,19 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set # CONFIG_GEN_RTC is not set +CONFIG_XILINX_HWICAP=m # CONFIG_R3964 is not set # CONFIG_APPLICOM 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 # @@ -639,12 +654,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 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 # @@ -671,6 +696,8 @@ 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 # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -679,14 +706,11 @@ CONFIG_USB_ARCH_HAS_EHCI=y # 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_EDAC is not set # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -701,7 +725,6 @@ CONFIG_EXT2_FS=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y @@ -770,7 +793,6 @@ CONFIG_NFS_FS=y 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_ROOT_NFS=y CONFIG_LOCKD=y @@ -798,6 +820,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set @@ -818,6 +841,7 @@ CONFIG_HAVE_LMB=y # 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 @@ -828,6 +852,7 @@ CONFIG_DETECT_SOFTLOCKUP=y 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 @@ -840,6 +865,7 @@ CONFIG_SCHED_DEBUG=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_BOOT_PRINTK_DELAY is not set @@ -851,6 +877,9 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_IRQSTACKS is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -861,50 +890,80 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y -# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=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=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL 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_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 is not set -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT 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_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED 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_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_LZO is not set # CONFIG_CRYPTO_HW is not set # CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set -- cgit v0.10.2 From 2bf3016f89344d4cd8b2c96bbec2b642a2bde413 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 10 Jul 2008 01:09:23 +1000 Subject: powerpc: Fix problems with 32bit PPC's running with >= 4GB of RAM This patch enables 32bit PPC's (with 36bit physical address space, e.g. IBM/AMCC PPC44x) to run with >= 4GB of RAM. Mostly its just replacing types (unsigned long -> phys_addr_t). Tested on an AMCC Katmai with 4GB of DDR2. Signed-off-by: Stefan Roese Signed-off-by: Josh Boyer diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 4541859..388ceda 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -57,8 +57,8 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -unsigned long total_memory; -unsigned long total_lowmem; +phys_addr_t total_memory; +phys_addr_t total_lowmem; phys_addr_t memstart_addr = (phys_addr_t)~0ull; EXPORT_SYMBOL(memstart_addr); diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 776ba6a..1ca2235 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -330,7 +330,7 @@ static int __init mark_nonram_nosave(void) void __init paging_init(void) { unsigned long total_ram = lmb_phys_mem_size(); - unsigned long top_of_ram = lmb_end_of_DRAM(); + phys_addr_t top_of_ram = lmb_end_of_DRAM(); unsigned long max_zone_pfns[MAX_NR_ZONES]; #ifdef CONFIG_PPC32 @@ -349,10 +349,10 @@ void __init paging_init(void) kmap_prot = PAGE_KERNEL; #endif /* CONFIG_HIGHMEM */ - printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", - top_of_ram, total_ram); + printk(KERN_DEBUG "Top of RAM: 0x%llx, Total RAM: 0x%lx\n", + (u64)top_of_ram, total_ram); printk(KERN_DEBUG "Memory hole size: %ldMB\n", - (top_of_ram - total_ram) >> 20); + (long int)((top_of_ram - total_ram) >> 20)); memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); #ifdef CONFIG_HIGHMEM max_zone_pfns[ZONE_DMA] = lowmem_end_addr >> PAGE_SHIFT; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 46585b7..fab3cfa 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -49,8 +49,8 @@ extern unsigned int num_tlbcam_entries; extern unsigned long ioremap_bot; extern unsigned long __max_low_memory; extern phys_addr_t __initial_memory_limit_addr; -extern unsigned long total_memory; -extern unsigned long total_lowmem; +extern phys_addr_t total_memory; +extern phys_addr_t total_lowmem; extern phys_addr_t memstart_addr; extern phys_addr_t lowmem_end_addr; -- cgit v0.10.2 From bdb08cb2d3491d441dd403dfb88d90ba90fb7232 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 30 Jun 2008 19:47:59 +0100 Subject: [ARM] pxa: allow clk aliases We need to support more than one name+device for a struct clk for a small number of peripherals. We do this by re-using struct clk alias to another struct clk - IOW, if we find that the entry we're using is an alias, we return the aliased entry not the one we found. Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index e97dc59..68afc39 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -47,6 +47,9 @@ struct clk *clk_get(struct device *dev, const char *id) clk = p; mutex_unlock(&clocks_mutex); + if (!IS_ERR(clk) && clk->ops == NULL) + clk = clk->other; + return clk; } EXPORT_SYMBOL(clk_get); diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h index bc6b77e..83cbfab 100644 --- a/arch/arm/mach-pxa/clock.h +++ b/arch/arm/mach-pxa/clock.h @@ -15,6 +15,7 @@ struct clk { unsigned int cken; unsigned int delay; unsigned int enabled; + struct clk *other; }; #define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ @@ -35,6 +36,17 @@ struct clk { .cken = CKEN_##_cken, \ } +/* + * This is a placeholder to alias one clock device+name pair + * to another struct clk. + */ +#define INIT_CKOTHER(_name, _other, _dev) \ + { \ + .name = _name, \ + .dev = _dev, \ + .other = _other, \ + } + extern const struct clkops clk_cken_ops; void clk_cken_enable(struct clk *clk); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e5b417d..09ee131 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -117,6 +117,10 @@ static struct clk pxa25x_hwuart_clk = INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) ; +/* + * PXA 2xx clock declarations. Order is important (see aliases below) + * Please be careful not to disrupt the ordering. + */ static struct clk pxa25x_clks[] = { INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), @@ -140,6 +144,8 @@ static struct clk pxa25x_clks[] = { INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), }; +static struct clk gpio7_clk = INIT_CKOTHER("GPIO7_CK", &pxa25x_clks[4], NULL); + #ifdef CONFIG_PM #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x @@ -311,6 +317,8 @@ static int __init pxa25x_init(void) if (cpu_is_pxa25x()) ret = platform_device_register(&pxa_device_hwuart); + clks_register(&gpio7_clk, 1); + return ret; } -- cgit v0.10.2 From 66a7f72d9892013e9ea663260f407758989ff510 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 2 Jun 2008 16:10:20 +0100 Subject: [ARM] pxa: remove pxa_set_cken() pxa_set_cken() is now unused, remove it. Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index c2f1023..ca05322 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -26,7 +26,6 @@ #include #include -#include /* for __pxa_set_cken */ #include "generic.h" @@ -61,23 +60,6 @@ unsigned int get_memclk_frequency_10khz(void) EXPORT_SYMBOL(get_memclk_frequency_10khz); /* - * Routine to safely enable or disable a clock in the CKEN - */ -void __pxa_set_cken(int clock, int enable) -{ - unsigned long flags; - local_irq_save(flags); - - if (enable) - CKEN |= (1 << clock); - else - CKEN &= ~(1 << clock); - - local_irq_restore(flags); -} -EXPORT_SYMBOL(__pxa_set_cken); - -/* * Intel PXA2xx internal register mapping. * * Note 1: not all PXA2xx variants implement all those addresses. diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index e25558f..d9af6da 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -192,15 +192,6 @@ extern int pxa_gpio_get_value(unsigned gpio); extern void pxa_gpio_set_value(unsigned gpio, int value); /* - * Routine to enable or disable CKEN - */ -static inline void __deprecated pxa_set_cken(int clock, int enable) -{ - extern void __pxa_set_cken(int clock, int enable); - __pxa_set_cken(clock, enable); -} - -/* * return current memory and LCD clock frequency in units of 10kHz */ extern unsigned int get_memclk_frequency_10khz(void); -- cgit v0.10.2 From 330ff197fcdc83ba151960d78294fb37777ebe12 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:52:27 +0100 Subject: [ARM] 5144/1: pxaficp_ir: cleanup includes Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index d5c2d27..a19c00a 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -13,16 +13,8 @@ * */ #include -#include -#include -#include #include -#include -#include -#include -#include #include -#include #include #include @@ -30,18 +22,11 @@ #include #include -#include #include -#include -#include #include #include #include -#ifdef CONFIG_MACH_MAINSTONE -#include -#endif - #define IrSR_RXPL_NEG_IS_ZERO (1<<4) #define IrSR_RXPL_POS_IS_ZERO 0x0 #define IrSR_TXPL_NEG_IS_ZERO (1<<3) -- cgit v0.10.2 From 918dbcba4ee3f0ad7d617b3969d5016481b9ceff Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:53:45 +0100 Subject: [ARM] 5145/1: PXA2xx: provide api to control IrDA pins state Provide a set of functions to control state of pins dedicated to IrDA. Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 02cbc3c..c4dfbe8 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -13,8 +13,8 @@ obj-$(CONFIG_PXA_SSP) += ssp.o obj-$(CONFIG_PXA_PWM) += pwm.o # SoC-specific code -obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o -obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa27x.o +obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o +obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o obj-$(CONFIG_CPU_PXA300) += pxa300.o obj-$(CONFIG_CPU_PXA320) += pxa320.o diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c new file mode 100644 index 0000000..d4f6415 --- /dev/null +++ b/arch/arm/mach-pxa/pxa2xx.c @@ -0,0 +1,46 @@ +/* + * linux/arch/arm/mach-pxa/pxa2xx.c + * + * code specific to pxa2xx + * + * Copyright (C) 2008 Dmitry Baryshkov + * + * 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 +#include +#include + +#include +#include +#include + +static unsigned long pxa2xx_mfp_fir[] = { + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, +}; + +static unsigned long pxa2xx_mfp_sir[] = { + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, +}; + +static unsigned long pxa2xx_mfp_off[] = { + GPIO46_GPIO | MFP_LPM_DRIVE_LOW, + GPIO47_GPIO | MFP_LPM_DRIVE_LOW, +}; + +void pxa2xx_transceiver_mode(struct device *dev, int mode) +{ + if (mode & IR_OFF) { + pxa2xx_mfp_config(pxa2xx_mfp_off, ARRAY_SIZE(pxa2xx_mfp_off)); + } else if (mode & IR_SIRMODE) { + pxa2xx_mfp_config(pxa2xx_mfp_sir, ARRAY_SIZE(pxa2xx_mfp_sir)); + } else if (mode & IR_FIRMODE) { + pxa2xx_mfp_config(pxa2xx_mfp_fir, ARRAY_SIZE(pxa2xx_mfp_fir)); + } else + BUG(); +} diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h index 99f4f42..0a50c3c 100644 --- a/include/asm-arm/arch-pxa/irda.h +++ b/include/asm-arm/arch-pxa/irda.h @@ -16,4 +16,8 @@ struct pxaficp_platform_data { extern void pxa_set_ficp_info(struct pxaficp_platform_data *info); +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) +void pxa2xx_transceiver_mode(struct device *dev, int mode); +#endif + #endif -- cgit v0.10.2 From 73d1a2c467ba4fb7420b499b6a7c66edf9626679 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:55:28 +0100 Subject: [ARM] 5147/1: pxaficp_ir: drop pxa_gpio_mode calls, as pin setting is handled in board code Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index a19c00a..f76b0b6 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -25,7 +25,6 @@ #include #include #include -#include #define IrSR_RXPL_NEG_IS_ZERO (1<<4) #define IrSR_RXPL_POS_IS_ZERO 0x0 @@ -148,10 +147,6 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) /* set board transceiver to SIR mode */ si->pdata->transceiver_mode(si->dev, IR_SIRMODE); - /* configure GPIO46/47 */ - pxa_gpio_mode(GPIO46_STRXD_MD); - pxa_gpio_mode(GPIO47_STTXD_MD); - /* enable the STUART clock */ pxa_irda_enable_sirclk(si); } @@ -186,10 +181,6 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) /* set board transceiver to FIR mode */ si->pdata->transceiver_mode(si->dev, IR_FIRMODE); - /* configure GPIO46/47 */ - pxa_gpio_mode(GPIO46_ICPRXD_MD); - pxa_gpio_mode(GPIO47_ICPTXD_MD); - /* enable the FICP clock */ pxa_irda_enable_firclk(si); -- cgit v0.10.2 From 7a8576204333d133d58cbcc59dacf49a5546e3e4 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 22 Jun 2008 23:36:39 +0100 Subject: [ARM] 5120/1: pxa: correct platform driver names for PXA25x and PXA27x UDC drivers The pxa2xx_udc.c driver is renamed to pxa25x_udc.c (the platform driver name changes from pxa2xx-udc to pxa25x-udc) and the platform driver name of pxa27x_udc.c is fixed to pxa27x-udc. pxa_device_udc in devices.c is split into pxa25x and pxa27x flavors and the pxa27x_device_udc is enabled in pxa27x.c. Signed-off-by: Philipp Zabel Acked-by: Nicolas Pitre Acked-by: Eric Miao Signed-off-by: Russell King Including from Ian Molton: Fixes for mistakes left over from the PXA2{5,7}X UDC split. Signed-off-by: Ian Molton Signed-off-by: Russell King diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index f6d66dc..3781b3d 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -326,11 +326,11 @@ static struct resource ixp4xx_udc_resources[] = { }; /* - * USB device controller. The IXP4xx uses the same controller as PXA2XX, + * USB device controller. The IXP4xx uses the same controller as PXA25X, * so we just use the same device. */ static struct platform_device ixp4xx_udc_device = { - .name = "pxa2xx-udc", + .name = "pxa25x-udc", .id = -1, .num_resources = 2, .resource = ixp4xx_udc_resources, diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 4a1eebb..123ee19 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -93,8 +93,19 @@ static struct resource pxa2xx_udc_resources[] = { static u64 udc_dma_mask = ~(u32)0; -struct platform_device pxa_device_udc = { - .name = "pxa2xx-udc", +struct platform_device pxa25x_device_udc = { + .name = "pxa25x-udc", + .id = -1, + .resource = pxa2xx_udc_resources, + .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), + .dev = { + .platform_data = &pxa_udc_info, + .dma_mask = &udc_dma_mask, + } +}; + +struct platform_device pxa27x_device_udc = { + .name = "pxa27x-udc", .id = -1, .resource = pxa2xx_udc_resources, .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index e620a33..881d1a7 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -1,7 +1,8 @@ extern struct platform_device pxa_device_mci; extern struct platform_device pxa3xx_device_mci2; extern struct platform_device pxa3xx_device_mci3; -extern struct platform_device pxa_device_udc; +extern struct platform_device pxa25x_device_udc; +extern struct platform_device pxa27x_device_udc; extern struct platform_device pxa_device_fb; extern struct platform_device pxa_device_ffuart; extern struct platform_device pxa_device_btuart; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index a1a7dd2..4cd50e3 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -127,7 +127,7 @@ static struct clk pxa25x_clks[] = { INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), - INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), + INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa25x_device_udc.dev), INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), @@ -267,7 +267,7 @@ void __init pxa25x_init_irq(void) } static struct platform_device *pxa25x_devices[] __initdata = { - &pxa_device_udc, + &pxa25x_device_udc, &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 4d7afae..d5d14ea 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -146,7 +146,7 @@ static struct clk pxa27x_clks[] = { INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev), + INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa27x_device_udc.dev), INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), @@ -357,7 +357,7 @@ void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { -/* &pxa_device_udc, The UDC driver is PXA25x only */ + &pxa27x_device_udc, &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index d26a9b0..15685d2 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -231,7 +231,7 @@ static struct clk pxa3xx_clks[] = { PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL), PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), - PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev), + PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa27x_device_udc.dev), PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev), PXA3xx_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev), diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 6e784d2..13dcec3 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -172,7 +172,7 @@ config USB_NET2280 default USB_GADGET select USB_GADGET_SELECTED -config USB_GADGET_PXA2XX +config USB_GADGET_PXA25X boolean "PXA 25x or IXP 4xx" depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX help @@ -184,19 +184,19 @@ config USB_GADGET_PXA2XX zero (for control transfers). Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "pxa2xx_udc" and force all + dynamically linked module called "pxa25x_udc" and force all gadget drivers to also be dynamically linked. -config USB_PXA2XX +config USB_PXA25X tristate - depends on USB_GADGET_PXA2XX + depends on USB_GADGET_PXA25X default USB_GADGET select USB_GADGET_SELECTED # if there's only one gadget driver, using only two bulk endpoints, # don't waste memory for the other endpoints -config USB_PXA2XX_SMALL - depends on USB_GADGET_PXA2XX +config USB_PXA25X_SMALL + depends on USB_GADGET_PXA25X bool default n if USB_ETH_RNDIS default y if USB_ZERO diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 1235725..e258afd 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -8,7 +8,7 @@ endif obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2280) += net2280.o obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o -obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o +obj-$(CONFIG_USB_PXA25X) += pxa25x_udc.o obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 8d61ea6..4ce3950 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -262,7 +262,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); /* For CDC-incapable hardware, choose the simple cdc subset. * Anything that talks bulk (without notable bugs) can do this. */ -#ifdef CONFIG_USB_GADGET_PXA2XX +#ifdef CONFIG_USB_GADGET_PXA25X #define DEV_CONFIG_SUBSET #endif diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index f7f159c..ca5149e 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -29,8 +29,8 @@ #define gadget_is_dummy(g) 0 #endif -#ifdef CONFIG_USB_GADGET_PXA2XX -#define gadget_is_pxa(g) !strcmp("pxa2xx_udc", (g)->name) +#ifdef CONFIG_USB_GADGET_PXA25X +#define gadget_is_pxa(g) !strcmp("pxa25x_udc", (g)->name) #else #define gadget_is_pxa(g) 0 #endif diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 69b0a27..f132a92 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1501,7 +1501,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } break; -#ifndef CONFIG_USB_GADGET_PXA2XX +#ifndef CONFIG_USB_GADGET_PXA25X /* PXA automagically handles this request too */ case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != 0x80) diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c new file mode 100644 index 0000000..031dceb --- /dev/null +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -0,0 +1,2388 @@ +/* + * Intel PXA25x and IXP4xx on-chip full speed USB device controllers + * + * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) + * Copyright (C) 2003 Robert Schwebel, Pengutronix + * Copyright (C) 2003 Benedikt Spranger, Pengutronix + * Copyright (C) 2003 David Brownell + * Copyright (C) 2003 Joshua Wise + * + * 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 + * + */ + +/* #define VERBOSE_DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * This driver is PXA25x only. Grab the right register definitions. + */ +#ifdef CONFIG_ARCH_PXA +#include +#endif + +#include + + +/* + * This driver handles the USB Device Controller (UDC) in Intel's PXA 25x + * series processors. The UDC for the IXP 4xx series is very similar. + * There are fifteen endpoints, in addition to ep0. + * + * Such controller drivers work with a gadget driver. The gadget driver + * returns descriptors, implements configuration and data protocols used + * by the host to interact with this device, and allocates endpoints to + * the different protocol interfaces. The controller driver virtualizes + * usb hardware so that the gadget drivers will be more portable. + * + * This UDC hardware wants to implement a bit too much USB protocol, so + * it constrains the sorts of USB configuration change events that work. + * The errata for these chips are misleading; some "fixed" bugs from + * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. + * + * Note that the UDC hardware supports DMA (except on IXP) but that's + * not used here. IN-DMA (to host) is simple enough, when the data is + * suitably aligned (16 bytes) ... the network stack doesn't do that, + * other software can. OUT-DMA is buggy in most chip versions, as well + * as poorly designed (data toggle not automatic). So this driver won't + * bother using DMA. (Mostly-working IN-DMA support was available in + * kernels before 2.6.23, but was never enabled or well tested.) + */ + +#define DRIVER_VERSION "30-June-2007" +#define DRIVER_DESC "PXA 25x USB Device Controller driver" + + +static const char driver_name [] = "pxa25x_udc"; + +static const char ep0name [] = "ep0"; + + +#ifdef CONFIG_ARCH_IXP4XX + +/* cpu-specific register addresses are compiled in to this code */ +#ifdef CONFIG_ARCH_PXA +#error "Can't configure both IXP and PXA" +#endif + +/* IXP doesn't yet support */ +#define clk_get(dev,name) NULL +#define clk_enable(clk) do { } while (0) +#define clk_disable(clk) do { } while (0) +#define clk_put(clk) do { } while (0) + +#endif + +#include "pxa25x_udc.h" + + +#ifdef CONFIG_USB_PXA25X_SMALL +#define SIZE_STR " (small)" +#else +#define SIZE_STR "" +#endif + +/* --------------------------------------------------------------------------- + * endpoint related parts of the api to the usb controller hardware, + * used by gadget driver; and the inner talker-to-hardware core. + * --------------------------------------------------------------------------- + */ + +static void pxa25x_ep_fifo_flush (struct usb_ep *ep); +static void nuke (struct pxa25x_ep *, int status); + +/* one GPIO should be used to detect VBUS from the host */ +static int is_vbus_present(void) +{ + struct pxa2xx_udc_mach_info *mach = the_controller->mach; + + if (mach->gpio_vbus) { + int value = gpio_get_value(mach->gpio_vbus); + return mach->gpio_vbus_inverted ? !value : value; + } + if (mach->udc_is_connected) + return mach->udc_is_connected(); + return 1; +} + +/* one GPIO should control a D+ pullup, so host sees this device (or not) */ +static void pullup_off(void) +{ + struct pxa2xx_udc_mach_info *mach = the_controller->mach; + + if (mach->gpio_pullup) + gpio_set_value(mach->gpio_pullup, 0); + else if (mach->udc_command) + mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); +} + +static void pullup_on(void) +{ + struct pxa2xx_udc_mach_info *mach = the_controller->mach; + + if (mach->gpio_pullup) + gpio_set_value(mach->gpio_pullup, 1); + else if (mach->udc_command) + mach->udc_command(PXA2XX_UDC_CMD_CONNECT); +} + +static void pio_irq_enable(int bEndpointAddress) +{ + bEndpointAddress &= 0xf; + if (bEndpointAddress < 8) + UICR0 &= ~(1 << bEndpointAddress); + else { + bEndpointAddress -= 8; + UICR1 &= ~(1 << bEndpointAddress); + } +} + +static void pio_irq_disable(int bEndpointAddress) +{ + bEndpointAddress &= 0xf; + if (bEndpointAddress < 8) + UICR0 |= 1 << bEndpointAddress; + else { + bEndpointAddress -= 8; + UICR1 |= 1 << bEndpointAddress; + } +} + +/* The UDCCR reg contains mask and interrupt status bits, + * so using '|=' isn't safe as it may ack an interrupt. + */ +#define UDCCR_MASK_BITS (UDCCR_REM | UDCCR_SRM | UDCCR_UDE) + +static inline void udc_set_mask_UDCCR(int mask) +{ + UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS); +} + +static inline void udc_clear_mask_UDCCR(int mask) +{ + UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS); +} + +static inline void udc_ack_int_UDCCR(int mask) +{ + /* udccr contains the bits we dont want to change */ + __u32 udccr = UDCCR & UDCCR_MASK_BITS; + + UDCCR = udccr | (mask & ~UDCCR_MASK_BITS); +} + +/* + * endpoint enable/disable + * + * we need to verify the descriptors used to enable endpoints. since pxa25x + * endpoint configurations are fixed, and are pretty much always enabled, + * there's not a lot to manage here. + * + * because pxa25x can't selectively initialize bulk (or interrupt) endpoints, + * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except + * for a single interface (with only the default altsetting) and for gadget + * drivers that don't halt endpoints (not reset by set_interface). that also + * means that if you use ISO, you must violate the USB spec rule that all + * iso endpoints must be in non-default altsettings. + */ +static int pxa25x_ep_enable (struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct pxa25x_ep *ep; + struct pxa25x_udc *dev; + + ep = container_of (_ep, struct pxa25x_ep, ep); + if (!_ep || !desc || ep->desc || _ep->name == ep0name + || desc->bDescriptorType != USB_DT_ENDPOINT + || ep->bEndpointAddress != desc->bEndpointAddress + || ep->fifo_size < le16_to_cpu + (desc->wMaxPacketSize)) { + DMSG("%s, bad ep or descriptor\n", __func__); + 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) { + DMSG("%s, %s type mismatch\n", __func__, _ep->name); + return -EINVAL; + } + + /* hardware _could_ do smaller, but driver doesn't */ + if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK + && le16_to_cpu (desc->wMaxPacketSize) + != BULK_FIFO_SIZE) + || !desc->wMaxPacketSize) { + DMSG("%s, bad %s maxpacket\n", __func__, _ep->name); + return -ERANGE; + } + + dev = ep->dev; + if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { + DMSG("%s, bogus device state\n", __func__); + return -ESHUTDOWN; + } + + ep->desc = desc; + ep->stopped = 0; + ep->pio_irqs = 0; + ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize); + + /* flush fifo (mostly for OUT buffers) */ + pxa25x_ep_fifo_flush (_ep); + + /* ... reset halt state too, if we could ... */ + + DBG(DBG_VERBOSE, "enabled %s\n", _ep->name); + return 0; +} + +static int pxa25x_ep_disable (struct usb_ep *_ep) +{ + struct pxa25x_ep *ep; + unsigned long flags; + + ep = container_of (_ep, struct pxa25x_ep, ep); + if (!_ep || !ep->desc) { + DMSG("%s, %s not enabled\n", __func__, + _ep ? ep->ep.name : NULL); + return -EINVAL; + } + local_irq_save(flags); + + nuke (ep, -ESHUTDOWN); + + /* flush fifo (mostly for IN buffers) */ + pxa25x_ep_fifo_flush (_ep); + + ep->desc = NULL; + ep->stopped = 1; + + local_irq_restore(flags); + DBG(DBG_VERBOSE, "%s disabled\n", _ep->name); + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* for the pxa25x, these can just wrap kmalloc/kfree. gadget drivers + * must still pass correctly initialized endpoints, since other controller + * drivers may care about how it's currently set up (dma issues etc). + */ + +/* + * pxa25x_ep_alloc_request - allocate a request data structure + */ +static struct usb_request * +pxa25x_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) +{ + struct pxa25x_request *req; + + req = kzalloc(sizeof(*req), gfp_flags); + if (!req) + return NULL; + + INIT_LIST_HEAD (&req->queue); + return &req->req; +} + + +/* + * pxa25x_ep_free_request - deallocate a request data structure + */ +static void +pxa25x_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) +{ + struct pxa25x_request *req; + + req = container_of (_req, struct pxa25x_request, req); + WARN_ON (!list_empty (&req->queue)); + kfree(req); +} + +/*-------------------------------------------------------------------------*/ + +/* + * done - retire a request; caller blocked irqs + */ +static void done(struct pxa25x_ep *ep, struct pxa25x_request *req, int status) +{ + unsigned stopped = ep->stopped; + + list_del_init(&req->queue); + + if (likely (req->req.status == -EINPROGRESS)) + req->req.status = status; + else + status = req->req.status; + + if (status && status != -ESHUTDOWN) + DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n", + ep->ep.name, &req->req, status, + req->req.actual, req->req.length); + + /* don't modify queue heads during completion callback */ + ep->stopped = 1; + req->req.complete(&ep->ep, &req->req); + ep->stopped = stopped; +} + + +static inline void ep0_idle (struct pxa25x_udc *dev) +{ + dev->ep0state = EP0_IDLE; +} + +static int +write_packet(volatile u32 *uddr, struct pxa25x_request *req, unsigned max) +{ + u8 *buf; + unsigned length, count; + + buf = req->req.buf + req->req.actual; + prefetch(buf); + + /* how big will this packet be? */ + length = min(req->req.length - req->req.actual, max); + req->req.actual += length; + + count = length; + while (likely(count--)) + *uddr = *buf++; + + return length; +} + +/* + * write to an IN endpoint fifo, as many packets as possible. + * irqs will use this to write the rest later. + * caller guarantees at least one packet buffer is ready (or a zlp). + */ +static int +write_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) +{ + unsigned max; + + max = le16_to_cpu(ep->desc->wMaxPacketSize); + do { + unsigned count; + int is_last, is_short; + + count = write_packet(ep->reg_uddr, req, max); + + /* last packet is usually short (or a zlp) */ + if (unlikely (count != max)) + is_last = is_short = 1; + else { + if (likely(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 = unlikely (max < ep->fifo_size); + } + + DBG(DBG_VERY_NOISY, "wrote %s %d bytes%s%s %d left %p\n", + ep->ep.name, count, + is_last ? "/L" : "", is_short ? "/S" : "", + req->req.length - req->req.actual, req); + + /* let loose that packet. maybe try writing another one, + * double buffering might work. TSP, TPC, and TFS + * bit values are the same for all normal IN endpoints. + */ + *ep->reg_udccs = UDCCS_BI_TPC; + if (is_short) + *ep->reg_udccs = UDCCS_BI_TSP; + + /* requests complete when all IN data is in the FIFO */ + if (is_last) { + done (ep, req, 0); + if (list_empty(&ep->queue)) + pio_irq_disable (ep->bEndpointAddress); + return 1; + } + + // TODO experiment: how robust can fifo mode tweaking be? + // double buffering is off in the default fifo mode, which + // prevents TFS from being set here. + + } while (*ep->reg_udccs & UDCCS_BI_TFS); + return 0; +} + +/* caller asserts req->pending (ep0 irq status nyet cleared); starts + * ep0 data stage. these chips want very simple state transitions. + */ +static inline +void ep0start(struct pxa25x_udc *dev, u32 flags, const char *tag) +{ + UDCCS0 = flags|UDCCS0_SA|UDCCS0_OPR; + USIR0 = USIR0_IR0; + dev->req_pending = 0; + DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n", + __func__, tag, UDCCS0, flags); +} + +static int +write_ep0_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) +{ + unsigned count; + int is_short; + + count = write_packet(&UDDR0, req, EP0_FIFO_SIZE); + ep->dev->stats.write.bytes += count; + + /* last packet "must be" short (or a zlp) */ + is_short = (count != EP0_FIFO_SIZE); + + DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count, + req->req.length - req->req.actual, req); + + if (unlikely (is_short)) { + if (ep->dev->req_pending) + ep0start(ep->dev, UDCCS0_IPR, "short IN"); + else + UDCCS0 = UDCCS0_IPR; + + count = req->req.length; + done (ep, req, 0); + ep0_idle(ep->dev); +#ifndef CONFIG_ARCH_IXP4XX +#if 1 + /* This seems to get rid of lost status irqs in some cases: + * host responds quickly, or next request involves config + * change automagic, or should have been hidden, or ... + * + * FIXME get rid of all udelays possible... + */ + if (count >= EP0_FIFO_SIZE) { + count = 100; + do { + if ((UDCCS0 & UDCCS0_OPR) != 0) { + /* clear OPR, generate ack */ + UDCCS0 = UDCCS0_OPR; + break; + } + count--; + udelay(1); + } while (count); + } +#endif +#endif + } else if (ep->dev->req_pending) + ep0start(ep->dev, 0, "IN"); + return is_short; +} + + +/* + * read_fifo - unload packet(s) from the fifo we use for usb OUT + * transfers and put them into the request. caller should have made + * sure there's at least one packet ready. + * + * returns true if the request completed because of short packet or the + * request buffer having filled (and maybe overran till end-of-packet). + */ +static int +read_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) +{ + for (;;) { + u32 udccs; + u8 *buf; + unsigned bufferspace, count, is_short; + + /* make sure there's a packet in the FIFO. + * UDCCS_{BO,IO}_RPC are all the same bit value. + * UDCCS_{BO,IO}_RNE are all the same bit value. + */ + udccs = *ep->reg_udccs; + if (unlikely ((udccs & UDCCS_BO_RPC) == 0)) + break; + buf = req->req.buf + req->req.actual; + prefetchw(buf); + bufferspace = req->req.length - req->req.actual; + + /* read all bytes from this packet */ + if (likely (udccs & UDCCS_BO_RNE)) { + count = 1 + (0x0ff & *ep->reg_ubcr); + req->req.actual += min (count, bufferspace); + } else /* zlp */ + count = 0; + is_short = (count < ep->ep.maxpacket); + DBG(DBG_VERY_NOISY, "read %s %02x, %d bytes%s req %p %d/%d\n", + ep->ep.name, udccs, count, + is_short ? "/S" : "", + req, req->req.actual, req->req.length); + while (likely (count-- != 0)) { + u8 byte = (u8) *ep->reg_uddr; + + 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) + DMSG("%s overflow %d\n", + ep->ep.name, count); + req->req.status = -EOVERFLOW; + } else { + *buf++ = byte; + bufferspace--; + } + } + *ep->reg_udccs = UDCCS_BO_RPC; + /* RPC/RSP/RNE could now reflect the other packet buffer */ + + /* iso is one request per packet */ + if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + if (udccs & UDCCS_IO_ROF) + req->req.status = -EHOSTUNREACH; + /* more like "is_done" */ + is_short = 1; + } + + /* completion */ + if (is_short || req->req.actual == req->req.length) { + done (ep, req, 0); + if (list_empty(&ep->queue)) + pio_irq_disable (ep->bEndpointAddress); + return 1; + } + + /* finished that packet. the next one may be waiting... */ + } + return 0; +} + +/* + * special ep0 version of the above. no UBCR0 or double buffering; status + * handshaking is magic. most device protocols don't need control-OUT. + * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other + * protocols do use them. + */ +static int +read_ep0_fifo (struct pxa25x_ep *ep, struct pxa25x_request *req) +{ + u8 *buf, byte; + unsigned bufferspace; + + buf = req->req.buf + req->req.actual; + bufferspace = req->req.length - req->req.actual; + + while (UDCCS0 & UDCCS0_RNE) { + byte = (u8) UDDR0; + + 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) + DMSG("%s overflow\n", ep->ep.name); + req->req.status = -EOVERFLOW; + } else { + *buf++ = byte; + req->req.actual++; + bufferspace--; + } + } + + UDCCS0 = UDCCS0_OPR | UDCCS0_IPR; + + /* completion */ + if (req->req.actual >= req->req.length) + return 1; + + /* finished that packet. the next one may be waiting... */ + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static int +pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) +{ + struct pxa25x_request *req; + struct pxa25x_ep *ep; + struct pxa25x_udc *dev; + unsigned long flags; + + req = container_of(_req, struct pxa25x_request, req); + if (unlikely (!_req || !_req->complete || !_req->buf + || !list_empty(&req->queue))) { + DMSG("%s, bad params\n", __func__); + return -EINVAL; + } + + ep = container_of(_ep, struct pxa25x_ep, ep); + if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { + DMSG("%s, bad ep\n", __func__); + return -EINVAL; + } + + dev = ep->dev; + if (unlikely (!dev->driver + || dev->gadget.speed == USB_SPEED_UNKNOWN)) { + DMSG("%s, bogus device state\n", __func__); + return -ESHUTDOWN; + } + + /* iso is always one packet per request, that's the only way + * we can report per-packet status. that also helps with dma. + */ + if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC + && req->req.length > le16_to_cpu + (ep->desc->wMaxPacketSize))) + return -EMSGSIZE; + + DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", + _ep->name, _req, _req->length, _req->buf); + + local_irq_save(flags); + + _req->status = -EINPROGRESS; + _req->actual = 0; + + /* kickstart this i/o queue? */ + if (list_empty(&ep->queue) && !ep->stopped) { + if (ep->desc == NULL/* ep0 */) { + unsigned length = _req->length; + + switch (dev->ep0state) { + case EP0_IN_DATA_PHASE: + dev->stats.write.ops++; + if (write_ep0_fifo(ep, req)) + req = NULL; + break; + + case EP0_OUT_DATA_PHASE: + dev->stats.read.ops++; + /* messy ... */ + if (dev->req_config) { + DBG(DBG_VERBOSE, "ep0 config ack%s\n", + dev->has_cfr ? "" : " raced"); + if (dev->has_cfr) + UDCCFR = UDCCFR_AREN|UDCCFR_ACM + |UDCCFR_MB1; + done(ep, req, 0); + dev->ep0state = EP0_END_XFER; + local_irq_restore (flags); + return 0; + } + if (dev->req_pending) + ep0start(dev, UDCCS0_IPR, "OUT"); + if (length == 0 || ((UDCCS0 & UDCCS0_RNE) != 0 + && read_ep0_fifo(ep, req))) { + ep0_idle(dev); + done(ep, req, 0); + req = NULL; + } + break; + + default: + DMSG("ep0 i/o, odd state %d\n", dev->ep0state); + local_irq_restore (flags); + return -EL2HLT; + } + /* can the FIFO can satisfy the request immediately? */ + } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) { + if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0 + && write_fifo(ep, req)) + req = NULL; + } else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0 + && read_fifo(ep, req)) { + req = NULL; + } + + if (likely (req && ep->desc)) + pio_irq_enable(ep->bEndpointAddress); + } + + /* pio or dma irq handler advances the queue. */ + if (likely(req != NULL)) + list_add_tail(&req->queue, &ep->queue); + local_irq_restore(flags); + + return 0; +} + + +/* + * nuke - dequeue ALL requests + */ +static void nuke(struct pxa25x_ep *ep, int status) +{ + struct pxa25x_request *req; + + /* called with irqs blocked */ + while (!list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, + struct pxa25x_request, + queue); + done(ep, req, status); + } + if (ep->desc) + pio_irq_disable (ep->bEndpointAddress); +} + + +/* dequeue JUST ONE request */ +static int pxa25x_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct pxa25x_ep *ep; + struct pxa25x_request *req; + unsigned long flags; + + ep = container_of(_ep, struct pxa25x_ep, ep); + if (!_ep || ep->ep.name == ep0name) + return -EINVAL; + + local_irq_save(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) { + local_irq_restore(flags); + return -EINVAL; + } + + done(ep, req, -ECONNRESET); + + local_irq_restore(flags); + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static int pxa25x_ep_set_halt(struct usb_ep *_ep, int value) +{ + struct pxa25x_ep *ep; + unsigned long flags; + + ep = container_of(_ep, struct pxa25x_ep, ep); + if (unlikely (!_ep + || (!ep->desc && ep->ep.name != ep0name)) + || ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + DMSG("%s, bad ep\n", __func__); + return -EINVAL; + } + if (value == 0) { + /* this path (reset toggle+halt) is needed to implement + * SET_INTERFACE on normal hardware. but it can't be + * done from software on the PXA UDC, and the hardware + * forgets to do it as part of SET_INTERFACE automagic. + */ + DMSG("only host can clear %s halt\n", _ep->name); + return -EROFS; + } + + local_irq_save(flags); + + if ((ep->bEndpointAddress & USB_DIR_IN) != 0 + && ((*ep->reg_udccs & UDCCS_BI_TFS) == 0 + || !list_empty(&ep->queue))) { + local_irq_restore(flags); + return -EAGAIN; + } + + /* FST bit is the same for control, bulk in, bulk out, interrupt in */ + *ep->reg_udccs = UDCCS_BI_FST|UDCCS_BI_FTF; + + /* ep0 needs special care */ + if (!ep->desc) { + start_watchdog(ep->dev); + ep->dev->req_pending = 0; + ep->dev->ep0state = EP0_STALL; + + /* and bulk/intr endpoints like dropping stalls too */ + } else { + unsigned i; + for (i = 0; i < 1000; i += 20) { + if (*ep->reg_udccs & UDCCS_BI_SST) + break; + udelay(20); + } + } + local_irq_restore(flags); + + DBG(DBG_VERBOSE, "%s halt\n", _ep->name); + return 0; +} + +static int pxa25x_ep_fifo_status(struct usb_ep *_ep) +{ + struct pxa25x_ep *ep; + + ep = container_of(_ep, struct pxa25x_ep, ep); + if (!_ep) { + DMSG("%s, bad ep\n", __func__); + return -ENODEV; + } + /* pxa can't report unclaimed bytes from IN fifos */ + if ((ep->bEndpointAddress & USB_DIR_IN) != 0) + return -EOPNOTSUPP; + if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN + || (*ep->reg_udccs & UDCCS_BO_RFS) == 0) + return 0; + else + return (*ep->reg_ubcr & 0xfff) + 1; +} + +static void pxa25x_ep_fifo_flush(struct usb_ep *_ep) +{ + struct pxa25x_ep *ep; + + ep = container_of(_ep, struct pxa25x_ep, ep); + if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) { + DMSG("%s, bad ep\n", __func__); + return; + } + + /* toggle and halt bits stay unchanged */ + + /* for OUT, just read and discard the FIFO contents. */ + if ((ep->bEndpointAddress & USB_DIR_IN) == 0) { + while (((*ep->reg_udccs) & UDCCS_BO_RNE) != 0) + (void) *ep->reg_uddr; + return; + } + + /* 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; +} + + +static struct usb_ep_ops pxa25x_ep_ops = { + .enable = pxa25x_ep_enable, + .disable = pxa25x_ep_disable, + + .alloc_request = pxa25x_ep_alloc_request, + .free_request = pxa25x_ep_free_request, + + .queue = pxa25x_ep_queue, + .dequeue = pxa25x_ep_dequeue, + + .set_halt = pxa25x_ep_set_halt, + .fifo_status = pxa25x_ep_fifo_status, + .fifo_flush = pxa25x_ep_fifo_flush, +}; + + +/* --------------------------------------------------------------------------- + * device-scoped parts of the api to the usb controller hardware + * --------------------------------------------------------------------------- + */ + +static int pxa25x_udc_get_frame(struct usb_gadget *_gadget) +{ + return ((UFNRH & 0x07) << 8) | (UFNRL & 0xff); +} + +static int pxa25x_udc_wakeup(struct usb_gadget *_gadget) +{ + /* host may not have enabled remote wakeup */ + if ((UDCCS0 & UDCCS0_DRWF) == 0) + return -EHOSTUNREACH; + udc_set_mask_UDCCR(UDCCR_RSM); + return 0; +} + +static void stop_activity(struct pxa25x_udc *, struct usb_gadget_driver *); +static void udc_enable (struct pxa25x_udc *); +static void udc_disable(struct pxa25x_udc *); + +/* We disable the UDC -- and its 48 MHz clock -- whenever it's not + * in active use. + */ +static int pullup(struct pxa25x_udc *udc) +{ + int is_active = udc->vbus && udc->pullup && !udc->suspended; + DMSG("%s\n", is_active ? "active" : "inactive"); + if (is_active) { + if (!udc->active) { + udc->active = 1; + /* Enable clock for USB device */ + clk_enable(udc->clk); + udc_enable(udc); + } + } else { + if (udc->active) { + if (udc->gadget.speed != USB_SPEED_UNKNOWN) { + DMSG("disconnect %s\n", udc->driver + ? udc->driver->driver.name + : "(no driver)"); + stop_activity(udc, udc->driver); + } + udc_disable(udc); + /* Disable clock for USB device */ + clk_disable(udc->clk); + udc->active = 0; + } + + } + return 0; +} + +/* VBUS reporting logically comes from a transceiver */ +static int pxa25x_udc_vbus_session(struct usb_gadget *_gadget, int is_active) +{ + struct pxa25x_udc *udc; + + udc = container_of(_gadget, struct pxa25x_udc, gadget); + udc->vbus = (is_active != 0); + DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); + pullup(udc); + return 0; +} + +/* drivers may have software control over D+ pullup */ +static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) +{ + struct pxa25x_udc *udc; + + udc = container_of(_gadget, struct pxa25x_udc, gadget); + + /* not all boards support pullup control */ + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) + return -EOPNOTSUPP; + + udc->pullup = (is_active != 0); + pullup(udc); + return 0; +} + +static const struct usb_gadget_ops pxa25x_udc_ops = { + .get_frame = pxa25x_udc_get_frame, + .wakeup = pxa25x_udc_wakeup, + .vbus_session = pxa25x_udc_vbus_session, + .pullup = pxa25x_udc_pullup, + + // .vbus_draw ... boards may consume current from VBUS, up to + // 100-500mA based on config. the 500uA suspend ceiling means + // that exclusively vbus-powered PXA designs violate USB specs. +}; + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_USB_GADGET_DEBUG_FS + +static int +udc_seq_show(struct seq_file *m, void *_d) +{ + struct pxa25x_udc *dev = m->private; + unsigned long flags; + int i; + u32 tmp; + + local_irq_save(flags); + + /* basic device status */ + seq_printf(m, DRIVER_DESC "\n" + "%s version: %s\nGadget driver: %s\nHost %s\n\n", + driver_name, DRIVER_VERSION SIZE_STR "(pio)", + dev->driver ? dev->driver->driver.name : "(none)", + is_vbus_present() ? "full speed" : "disconnected"); + + /* registers for device and ep0 */ + seq_printf(m, + "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", + UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); + + tmp = UDCCR; + seq_printf(m, + "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, + (tmp & UDCCR_REM) ? " rem" : "", + (tmp & UDCCR_RSTIR) ? " rstir" : "", + (tmp & UDCCR_SRM) ? " srm" : "", + (tmp & UDCCR_SUSIR) ? " susir" : "", + (tmp & UDCCR_RESIR) ? " resir" : "", + (tmp & UDCCR_RSM) ? " rsm" : "", + (tmp & UDCCR_UDA) ? " uda" : "", + (tmp & UDCCR_UDE) ? " ude" : ""); + + tmp = UDCCS0; + seq_printf(m, + "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, + (tmp & UDCCS0_SA) ? " sa" : "", + (tmp & UDCCS0_RNE) ? " rne" : "", + (tmp & UDCCS0_FST) ? " fst" : "", + (tmp & UDCCS0_SST) ? " sst" : "", + (tmp & UDCCS0_DRWF) ? " dwrf" : "", + (tmp & UDCCS0_FTF) ? " ftf" : "", + (tmp & UDCCS0_IPR) ? " ipr" : "", + (tmp & UDCCS0_OPR) ? " opr" : ""); + + if (dev->has_cfr) { + tmp = UDCCFR; + seq_printf(m, + "udccfr %02X =%s%s\n", tmp, + (tmp & UDCCFR_AREN) ? " aren" : "", + (tmp & UDCCFR_ACM) ? " acm" : ""); + } + + if (!is_vbus_present() || !dev->driver) + goto done; + + seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", + dev->stats.write.bytes, dev->stats.write.ops, + dev->stats.read.bytes, dev->stats.read.ops, + dev->stats.irqs); + + /* dump endpoint queues */ + for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { + struct pxa25x_ep *ep = &dev->ep [i]; + struct pxa25x_request *req; + + if (i != 0) { + const struct usb_endpoint_descriptor *desc; + + desc = ep->desc; + if (!desc) + continue; + tmp = *dev->ep [i].reg_udccs; + seq_printf(m, + "%s max %d %s udccs %02x irqs %lu\n", + ep->ep.name, le16_to_cpu(desc->wMaxPacketSize), + "pio", tmp, ep->pio_irqs); + /* TODO translate all five groups of udccs bits! */ + + } else /* ep0 should only have one transfer queued */ + seq_printf(m, "ep0 max 16 pio irqs %lu\n", + ep->pio_irqs); + + if (list_empty(&ep->queue)) { + seq_printf(m, "\t(nothing queued)\n"); + continue; + } + list_for_each_entry(req, &ep->queue, queue) { + seq_printf(m, + "\treq %p len %d/%d buf %p\n", + &req->req, req->req.actual, + req->req.length, req->req.buf); + } + } + +done: + local_irq_restore(flags); + return 0; +} + +static int +udc_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, udc_seq_show, inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = udc_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +#define create_debug_files(dev) \ + do { \ + dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ + S_IRUGO, NULL, dev, &debug_fops); \ + } while (0) +#define remove_debug_files(dev) \ + do { \ + if (dev->debugfs_udc) \ + debugfs_remove(dev->debugfs_udc); \ + } while (0) + +#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ + +#define create_debug_files(dev) do {} while (0) +#define remove_debug_files(dev) do {} while (0) + +#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ + +/*-------------------------------------------------------------------------*/ + +/* + * udc_disable - disable USB device controller + */ +static void udc_disable(struct pxa25x_udc *dev) +{ + /* block all irqs */ + udc_set_mask_UDCCR(UDCCR_SRM|UDCCR_REM); + UICR0 = UICR1 = 0xff; + UFNRH = UFNRH_SIM; + + /* if hardware supports it, disconnect from usb */ + pullup_off(); + + udc_clear_mask_UDCCR(UDCCR_UDE); + + ep0_idle (dev); + dev->gadget.speed = USB_SPEED_UNKNOWN; +} + + +/* + * udc_reinit - initialize software state + */ +static void udc_reinit(struct pxa25x_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 = EP0_IDLE; + + /* basic endpoint records init */ + for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { + struct pxa25x_ep *ep = &dev->ep[i]; + + if (i != 0) + list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); + + ep->desc = NULL; + ep->stopped = 0; + INIT_LIST_HEAD (&ep->queue); + ep->pio_irqs = 0; + } + + /* the rest was statically initialized, and is read-only */ +} + +/* until it's enabled, this UDC should be completely invisible + * to any USB host. + */ +static void udc_enable (struct pxa25x_udc *dev) +{ + udc_clear_mask_UDCCR(UDCCR_UDE); + + /* try to clear these bits before we enable the udc */ + udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); + + ep0_idle(dev); + dev->gadget.speed = USB_SPEED_UNKNOWN; + dev->stats.irqs = 0; + + /* + * sequence taken from chapter 12.5.10, PXA250 AppProcDevManual: + * - enable UDC + * - if RESET is already in progress, ack interrupt + * - unmask reset interrupt + */ + udc_set_mask_UDCCR(UDCCR_UDE); + if (!(UDCCR & UDCCR_UDA)) + udc_ack_int_UDCCR(UDCCR_RSTIR); + + if (dev->has_cfr /* UDC_RES2 is defined */) { + /* pxa255 (a0+) can avoid a set_config race that could + * prevent gadget drivers from configuring correctly + */ + UDCCFR = UDCCFR_ACM | UDCCFR_MB1; + } else { + /* "USB test mode" for pxa250 errata 40-42 (stepping a0, a1) + * which could result in missing packets and interrupts. + * supposedly one bit per endpoint, controlling whether it + * double buffers or not; ACM/AREN bits fit into the holes. + * zero bits (like USIR0_IRx) disable double buffering. + */ + UDC_RES1 = 0x00; + UDC_RES2 = 0x00; + } + + /* enable suspend/resume and reset irqs */ + udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); + + /* enable ep0 irqs */ + UICR0 &= ~UICR0_IM0; + + /* if hardware supports it, pullup D+ and wait for reset */ + pullup_on(); +} + + +/* when a driver is successfully registered, it will receive + * control requests including set_configuration(), which enables + * non-control requests. then usb traffic follows until a + * disconnect is reported. then a host may connect again, or + * the driver might get unbound. + */ +int usb_gadget_register_driver(struct usb_gadget_driver *driver) +{ + struct pxa25x_udc *dev = the_controller; + int retval; + + if (!driver + || driver->speed < USB_SPEED_FULL + || !driver->bind + || !driver->disconnect + || !driver->setup) + return -EINVAL; + if (!dev) + return -ENODEV; + if (dev->driver) + return -EBUSY; + + /* first hook up the driver ... */ + dev->driver = driver; + dev->gadget.dev.driver = &driver->driver; + dev->pullup = 1; + + retval = device_add (&dev->gadget.dev); + if (retval) { +fail: + dev->driver = NULL; + dev->gadget.dev.driver = NULL; + return retval; + } + retval = driver->bind(&dev->gadget); + if (retval) { + DMSG("bind to driver %s --> error %d\n", + driver->driver.name, retval); + device_del (&dev->gadget.dev); + goto fail; + } + + /* ... then enable host detection and ep0; and we're ready + * for set_configuration as well as eventual disconnect. + */ + DMSG("registered gadget driver '%s'\n", driver->driver.name); + pullup(dev); + dump_state(dev); + return 0; +} +EXPORT_SYMBOL(usb_gadget_register_driver); + +static void +stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) +{ + int i; + + /* don't disconnect drivers more than once */ + if (dev->gadget.speed == USB_SPEED_UNKNOWN) + driver = NULL; + dev->gadget.speed = USB_SPEED_UNKNOWN; + + /* prevent new request submissions, kill any outstanding requests */ + for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { + struct pxa25x_ep *ep = &dev->ep[i]; + + ep->stopped = 1; + nuke(ep, -ESHUTDOWN); + } + del_timer_sync(&dev->timer); + + /* report disconnect; the driver is already quiesced */ + if (driver) + driver->disconnect(&dev->gadget); + + /* re-init driver-visible data structures */ + udc_reinit(dev); +} + +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + struct pxa25x_udc *dev = the_controller; + + if (!dev) + return -ENODEV; + if (!driver || driver != dev->driver || !driver->unbind) + return -EINVAL; + + local_irq_disable(); + dev->pullup = 0; + pullup(dev); + stop_activity(dev, driver); + local_irq_enable(); + + driver->unbind(&dev->gadget); + dev->gadget.dev.driver = NULL; + dev->driver = NULL; + + device_del (&dev->gadget.dev); + + DMSG("unregistered gadget driver '%s'\n", driver->driver.name); + dump_state(dev); + return 0; +} +EXPORT_SYMBOL(usb_gadget_unregister_driver); + + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_LUBBOCK + +/* Lubbock has separate connect and disconnect irqs. More typical designs + * use one GPIO as the VBUS IRQ, and another to control the D+ pullup. + */ + +static irqreturn_t +lubbock_vbus_irq(int irq, void *_dev) +{ + struct pxa25x_udc *dev = _dev; + int vbus; + + dev->stats.irqs++; + switch (irq) { + case LUBBOCK_USB_IRQ: + vbus = 1; + disable_irq(LUBBOCK_USB_IRQ); + enable_irq(LUBBOCK_USB_DISC_IRQ); + break; + case LUBBOCK_USB_DISC_IRQ: + vbus = 0; + disable_irq(LUBBOCK_USB_DISC_IRQ); + enable_irq(LUBBOCK_USB_IRQ); + break; + default: + return IRQ_NONE; + } + + pxa25x_udc_vbus_session(&dev->gadget, vbus); + return IRQ_HANDLED; +} + +#endif + +static irqreturn_t udc_vbus_irq(int irq, void *_dev) +{ + struct pxa25x_udc *dev = _dev; + int vbus = gpio_get_value(dev->mach->gpio_vbus); + + if (dev->mach->gpio_vbus_inverted) + vbus = !vbus; + + pxa25x_udc_vbus_session(&dev->gadget, vbus); + return IRQ_HANDLED; +} + + +/*-------------------------------------------------------------------------*/ + +static inline void clear_ep_state (struct pxa25x_udc *dev) +{ + unsigned i; + + /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint + * fifos, and pending transactions mustn't be continued in any case. + */ + for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) + nuke(&dev->ep[i], -ECONNABORTED); +} + +static void udc_watchdog(unsigned long _dev) +{ + struct pxa25x_udc *dev = (void *)_dev; + + local_irq_disable(); + if (dev->ep0state == EP0_STALL + && (UDCCS0 & UDCCS0_FST) == 0 + && (UDCCS0 & UDCCS0_SST) == 0) { + UDCCS0 = UDCCS0_FST|UDCCS0_FTF; + DBG(DBG_VERBOSE, "ep0 re-stall\n"); + start_watchdog(dev); + } + local_irq_enable(); +} + +static void handle_ep0 (struct pxa25x_udc *dev) +{ + u32 udccs0 = UDCCS0; + struct pxa25x_ep *ep = &dev->ep [0]; + struct pxa25x_request *req; + union { + struct usb_ctrlrequest r; + u8 raw [8]; + u32 word [2]; + } u; + + if (list_empty(&ep->queue)) + req = NULL; + else + req = list_entry(ep->queue.next, struct pxa25x_request, queue); + + /* clear stall status */ + if (udccs0 & UDCCS0_SST) { + nuke(ep, -EPIPE); + UDCCS0 = UDCCS0_SST; + del_timer(&dev->timer); + ep0_idle(dev); + } + + /* previous request unfinished? non-error iff back-to-back ... */ + if ((udccs0 & UDCCS0_SA) != 0 && dev->ep0state != EP0_IDLE) { + nuke(ep, 0); + del_timer(&dev->timer); + ep0_idle(dev); + } + + switch (dev->ep0state) { + case EP0_IDLE: + /* late-breaking status? */ + udccs0 = UDCCS0; + + /* start control request? */ + if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE)) + == (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE))) { + int i; + + nuke (ep, -EPROTO); + + /* read SETUP packet */ + for (i = 0; i < 8; i++) { + if (unlikely(!(UDCCS0 & UDCCS0_RNE))) { +bad_setup: + DMSG("SETUP %d!\n", i); + goto stall; + } + u.raw [i] = (u8) UDDR0; + } + if (unlikely((UDCCS0 & UDCCS0_RNE) != 0)) + goto bad_setup; + +got_setup: + DBG(DBG_VERBOSE, "SETUP %02x.%02x v%04x i%04x l%04x\n", + u.r.bRequestType, u.r.bRequest, + le16_to_cpu(u.r.wValue), + le16_to_cpu(u.r.wIndex), + le16_to_cpu(u.r.wLength)); + + /* cope with automagic for some standard requests. */ + dev->req_std = (u.r.bRequestType & USB_TYPE_MASK) + == USB_TYPE_STANDARD; + dev->req_config = 0; + dev->req_pending = 1; + switch (u.r.bRequest) { + /* hardware restricts gadget drivers here! */ + case USB_REQ_SET_CONFIGURATION: + if (u.r.bRequestType == USB_RECIP_DEVICE) { + /* reflect hardware's automagic + * up to the gadget driver. + */ +config_change: + dev->req_config = 1; + clear_ep_state(dev); + /* if !has_cfr, there's no synch + * else use AREN (later) not SA|OPR + * USIR0_IR0 acts edge sensitive + */ + } + break; + /* ... and here, even more ... */ + case USB_REQ_SET_INTERFACE: + if (u.r.bRequestType == USB_RECIP_INTERFACE) { + /* udc hardware is broken by design: + * - altsetting may only be zero; + * - hw resets all interfaces' eps; + * - ep reset doesn't include halt(?). + */ + DMSG("broken set_interface (%d/%d)\n", + le16_to_cpu(u.r.wIndex), + le16_to_cpu(u.r.wValue)); + goto config_change; + } + break; + /* hardware was supposed to hide this */ + case USB_REQ_SET_ADDRESS: + if (u.r.bRequestType == USB_RECIP_DEVICE) { + ep0start(dev, 0, "address"); + return; + } + break; + } + + if (u.r.bRequestType & USB_DIR_IN) + dev->ep0state = EP0_IN_DATA_PHASE; + else + dev->ep0state = EP0_OUT_DATA_PHASE; + + i = dev->driver->setup(&dev->gadget, &u.r); + if (i < 0) { + /* hardware automagic preventing STALL... */ + if (dev->req_config) { + /* hardware sometimes neglects to tell + * tell us about config change events, + * so later ones may fail... + */ + WARN("config change %02x fail %d?\n", + u.r.bRequest, i); + return; + /* TODO experiment: if has_cfr, + * hardware didn't ACK; maybe we + * could actually STALL! + */ + } + DBG(DBG_VERBOSE, "protocol STALL, " + "%02x err %d\n", UDCCS0, i); +stall: + /* the watchdog timer helps deal with cases + * where udc seems to clear FST wrongly, and + * then NAKs instead of STALLing. + */ + ep0start(dev, UDCCS0_FST|UDCCS0_FTF, "stall"); + start_watchdog(dev); + dev->ep0state = EP0_STALL; + + /* deferred i/o == no response yet */ + } else if (dev->req_pending) { + if (likely(dev->ep0state == EP0_IN_DATA_PHASE + || dev->req_std || u.r.wLength)) + ep0start(dev, 0, "defer"); + else + ep0start(dev, UDCCS0_IPR, "defer/IPR"); + } + + /* expect at least one data or status stage irq */ + return; + + } else if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA)) + == (UDCCS0_OPR|UDCCS0_SA))) { + unsigned i; + + /* pxa210/250 erratum 131 for B0/B1 says RNE lies. + * still observed on a pxa255 a0. + */ + DBG(DBG_VERBOSE, "e131\n"); + nuke(ep, -EPROTO); + + /* read SETUP data, but don't trust it too much */ + for (i = 0; i < 8; i++) + u.raw [i] = (u8) UDDR0; + if ((u.r.bRequestType & USB_RECIP_MASK) + > USB_RECIP_OTHER) + goto stall; + if (u.word [0] == 0 && u.word [1] == 0) + goto stall; + goto got_setup; + } else { + /* some random early IRQ: + * - we acked FST + * - IPR cleared + * - OPR got set, without SA (likely status stage) + */ + UDCCS0 = udccs0 & (UDCCS0_SA|UDCCS0_OPR); + } + break; + case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */ + if (udccs0 & UDCCS0_OPR) { + UDCCS0 = UDCCS0_OPR|UDCCS0_FTF; + DBG(DBG_VERBOSE, "ep0in premature status\n"); + if (req) + done(ep, req, 0); + ep0_idle(dev); + } else /* irq was IPR clearing */ { + if (req) { + /* this IN packet might finish the request */ + (void) write_ep0_fifo(ep, req); + } /* else IN token before response was written */ + } + break; + case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */ + if (udccs0 & UDCCS0_OPR) { + if (req) { + /* this OUT packet might finish the request */ + if (read_ep0_fifo(ep, req)) + done(ep, req, 0); + /* else more OUT packets expected */ + } /* else OUT token before read was issued */ + } else /* irq was IPR clearing */ { + DBG(DBG_VERBOSE, "ep0out premature status\n"); + if (req) + done(ep, req, 0); + ep0_idle(dev); + } + break; + case EP0_END_XFER: + if (req) + done(ep, req, 0); + /* ack control-IN status (maybe in-zlp was skipped) + * also appears after some config change events. + */ + if (udccs0 & UDCCS0_OPR) + UDCCS0 = UDCCS0_OPR; + ep0_idle(dev); + break; + case EP0_STALL: + UDCCS0 = UDCCS0_FST; + break; + } + USIR0 = USIR0_IR0; +} + +static void handle_ep(struct pxa25x_ep *ep) +{ + struct pxa25x_request *req; + int is_in = ep->bEndpointAddress & USB_DIR_IN; + int completed; + u32 udccs, tmp; + + do { + completed = 0; + if (likely (!list_empty(&ep->queue))) + req = list_entry(ep->queue.next, + struct pxa25x_request, queue); + else + req = NULL; + + // TODO check FST handling + + udccs = *ep->reg_udccs; + if (unlikely(is_in)) { /* irq from TPC, SST, or (ISO) TUR */ + tmp = UDCCS_BI_TUR; + if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK)) + tmp |= UDCCS_BI_SST; + tmp &= udccs; + if (likely (tmp)) + *ep->reg_udccs = tmp; + if (req && likely ((udccs & UDCCS_BI_TFS) != 0)) + completed = write_fifo(ep, req); + + } else { /* irq from RPC (or for ISO, ROF) */ + if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK)) + tmp = UDCCS_BO_SST | UDCCS_BO_DME; + else + tmp = UDCCS_IO_ROF | UDCCS_IO_DME; + tmp &= udccs; + if (likely(tmp)) + *ep->reg_udccs = tmp; + + /* fifos can hold packets, ready for reading... */ + if (likely(req)) { + completed = read_fifo(ep, req); + } else + pio_irq_disable (ep->bEndpointAddress); + } + ep->pio_irqs++; + } while (completed); +} + +/* + * pxa25x_udc_irq - interrupt handler + * + * avoid delays in ep0 processing. the control handshaking isn't always + * under software control (pxa250c0 and the pxa255 are better), and delays + * could cause usb protocol errors. + */ +static irqreturn_t +pxa25x_udc_irq(int irq, void *_dev) +{ + struct pxa25x_udc *dev = _dev; + int handled; + + dev->stats.irqs++; + do { + u32 udccr = UDCCR; + + handled = 0; + + /* SUSpend Interrupt Request */ + if (unlikely(udccr & UDCCR_SUSIR)) { + udc_ack_int_UDCCR(UDCCR_SUSIR); + handled = 1; + DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() + ? "" : "+disconnect"); + + if (!is_vbus_present()) + stop_activity(dev, dev->driver); + else if (dev->gadget.speed != USB_SPEED_UNKNOWN + && dev->driver + && dev->driver->suspend) + dev->driver->suspend(&dev->gadget); + ep0_idle (dev); + } + + /* RESume Interrupt Request */ + if (unlikely(udccr & UDCCR_RESIR)) { + udc_ack_int_UDCCR(UDCCR_RESIR); + handled = 1; + DBG(DBG_VERBOSE, "USB resume\n"); + + if (dev->gadget.speed != USB_SPEED_UNKNOWN + && dev->driver + && dev->driver->resume + && is_vbus_present()) + dev->driver->resume(&dev->gadget); + } + + /* ReSeT Interrupt Request - USB reset */ + if (unlikely(udccr & UDCCR_RSTIR)) { + udc_ack_int_UDCCR(UDCCR_RSTIR); + handled = 1; + + if ((UDCCR & UDCCR_UDA) == 0) { + DBG(DBG_VERBOSE, "USB reset start\n"); + + /* reset driver and endpoints, + * in case that's not yet done + */ + stop_activity (dev, dev->driver); + + } else { + DBG(DBG_VERBOSE, "USB reset end\n"); + dev->gadget.speed = USB_SPEED_FULL; + memset(&dev->stats, 0, sizeof dev->stats); + /* driver and endpoints are still reset */ + } + + } else { + u32 usir0 = USIR0 & ~UICR0; + u32 usir1 = USIR1 & ~UICR1; + int i; + + if (unlikely (!usir0 && !usir1)) + continue; + + DBG(DBG_VERY_NOISY, "irq %02x.%02x\n", usir1, usir0); + + /* control traffic */ + if (usir0 & USIR0_IR0) { + dev->ep[0].pio_irqs++; + handle_ep0(dev); + handled = 1; + } + + /* endpoint data transfers */ + for (i = 0; i < 8; i++) { + u32 tmp = 1 << i; + + if (i && (usir0 & tmp)) { + handle_ep(&dev->ep[i]); + USIR0 |= tmp; + handled = 1; + } + if (usir1 & tmp) { + handle_ep(&dev->ep[i+8]); + USIR1 |= tmp; + handled = 1; + } + } + } + + /* we could also ask for 1 msec SOF (SIR) interrupts */ + + } while (handled); + return IRQ_HANDLED; +} + +/*-------------------------------------------------------------------------*/ + +static void nop_release (struct device *dev) +{ + DMSG("%s %s\n", __func__, dev->bus_id); +} + +/* this uses load-time allocation and initialization (instead of + * doing it at run-time) to save code, eliminate fault paths, and + * be more obviously correct. + */ +static struct pxa25x_udc memory = { + .gadget = { + .ops = &pxa25x_udc_ops, + .ep0 = &memory.ep[0].ep, + .name = driver_name, + .dev = { + .bus_id = "gadget", + .release = nop_release, + }, + }, + + /* control endpoint */ + .ep[0] = { + .ep = { + .name = ep0name, + .ops = &pxa25x_ep_ops, + .maxpacket = EP0_FIFO_SIZE, + }, + .dev = &memory, + .reg_udccs = &UDCCS0, + .reg_uddr = &UDDR0, + }, + + /* first group of endpoints */ + .ep[1] = { + .ep = { + .name = "ep1in-bulk", + .ops = &pxa25x_ep_ops, + .maxpacket = BULK_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = BULK_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 1, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .reg_udccs = &UDCCS1, + .reg_uddr = &UDDR1, + }, + .ep[2] = { + .ep = { + .name = "ep2out-bulk", + .ops = &pxa25x_ep_ops, + .maxpacket = BULK_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = BULK_FIFO_SIZE, + .bEndpointAddress = 2, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .reg_udccs = &UDCCS2, + .reg_ubcr = &UBCR2, + .reg_uddr = &UDDR2, + }, +#ifndef CONFIG_USB_PXA25X_SMALL + .ep[3] = { + .ep = { + .name = "ep3in-iso", + .ops = &pxa25x_ep_ops, + .maxpacket = ISO_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = ISO_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 3, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .reg_udccs = &UDCCS3, + .reg_uddr = &UDDR3, + }, + .ep[4] = { + .ep = { + .name = "ep4out-iso", + .ops = &pxa25x_ep_ops, + .maxpacket = ISO_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = ISO_FIFO_SIZE, + .bEndpointAddress = 4, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .reg_udccs = &UDCCS4, + .reg_ubcr = &UBCR4, + .reg_uddr = &UDDR4, + }, + .ep[5] = { + .ep = { + .name = "ep5in-int", + .ops = &pxa25x_ep_ops, + .maxpacket = INT_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = INT_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 5, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .reg_udccs = &UDCCS5, + .reg_uddr = &UDDR5, + }, + + /* second group of endpoints */ + .ep[6] = { + .ep = { + .name = "ep6in-bulk", + .ops = &pxa25x_ep_ops, + .maxpacket = BULK_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = BULK_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 6, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .reg_udccs = &UDCCS6, + .reg_uddr = &UDDR6, + }, + .ep[7] = { + .ep = { + .name = "ep7out-bulk", + .ops = &pxa25x_ep_ops, + .maxpacket = BULK_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = BULK_FIFO_SIZE, + .bEndpointAddress = 7, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .reg_udccs = &UDCCS7, + .reg_ubcr = &UBCR7, + .reg_uddr = &UDDR7, + }, + .ep[8] = { + .ep = { + .name = "ep8in-iso", + .ops = &pxa25x_ep_ops, + .maxpacket = ISO_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = ISO_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 8, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .reg_udccs = &UDCCS8, + .reg_uddr = &UDDR8, + }, + .ep[9] = { + .ep = { + .name = "ep9out-iso", + .ops = &pxa25x_ep_ops, + .maxpacket = ISO_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = ISO_FIFO_SIZE, + .bEndpointAddress = 9, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .reg_udccs = &UDCCS9, + .reg_ubcr = &UBCR9, + .reg_uddr = &UDDR9, + }, + .ep[10] = { + .ep = { + .name = "ep10in-int", + .ops = &pxa25x_ep_ops, + .maxpacket = INT_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = INT_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 10, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .reg_udccs = &UDCCS10, + .reg_uddr = &UDDR10, + }, + + /* third group of endpoints */ + .ep[11] = { + .ep = { + .name = "ep11in-bulk", + .ops = &pxa25x_ep_ops, + .maxpacket = BULK_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = BULK_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 11, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .reg_udccs = &UDCCS11, + .reg_uddr = &UDDR11, + }, + .ep[12] = { + .ep = { + .name = "ep12out-bulk", + .ops = &pxa25x_ep_ops, + .maxpacket = BULK_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = BULK_FIFO_SIZE, + .bEndpointAddress = 12, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .reg_udccs = &UDCCS12, + .reg_ubcr = &UBCR12, + .reg_uddr = &UDDR12, + }, + .ep[13] = { + .ep = { + .name = "ep13in-iso", + .ops = &pxa25x_ep_ops, + .maxpacket = ISO_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = ISO_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 13, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .reg_udccs = &UDCCS13, + .reg_uddr = &UDDR13, + }, + .ep[14] = { + .ep = { + .name = "ep14out-iso", + .ops = &pxa25x_ep_ops, + .maxpacket = ISO_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = ISO_FIFO_SIZE, + .bEndpointAddress = 14, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, + .reg_udccs = &UDCCS14, + .reg_ubcr = &UBCR14, + .reg_uddr = &UDDR14, + }, + .ep[15] = { + .ep = { + .name = "ep15in-int", + .ops = &pxa25x_ep_ops, + .maxpacket = INT_FIFO_SIZE, + }, + .dev = &memory, + .fifo_size = INT_FIFO_SIZE, + .bEndpointAddress = USB_DIR_IN | 15, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .reg_udccs = &UDCCS15, + .reg_uddr = &UDDR15, + }, +#endif /* !CONFIG_USB_PXA25X_SMALL */ +}; + +#define CP15R0_VENDOR_MASK 0xffffe000 + +#if defined(CONFIG_ARCH_PXA) +#define CP15R0_XSCALE_VALUE 0x69052000 /* intel/arm/xscale */ + +#elif defined(CONFIG_ARCH_IXP4XX) +#define CP15R0_XSCALE_VALUE 0x69054000 /* intel/arm/ixp4xx */ + +#endif + +#define CP15R0_PROD_MASK 0x000003f0 +#define PXA25x 0x00000100 /* and PXA26x */ +#define PXA210 0x00000120 + +#define CP15R0_REV_MASK 0x0000000f + +#define CP15R0_PRODREV_MASK (CP15R0_PROD_MASK | CP15R0_REV_MASK) + +#define PXA255_A0 0x00000106 /* or PXA260_B1 */ +#define PXA250_C0 0x00000105 /* or PXA26x_B0 */ +#define PXA250_B2 0x00000104 +#define PXA250_B1 0x00000103 /* or PXA260_A0 */ +#define PXA250_B0 0x00000102 +#define PXA250_A1 0x00000101 +#define PXA250_A0 0x00000100 + +#define PXA210_C0 0x00000125 +#define PXA210_B2 0x00000124 +#define PXA210_B1 0x00000123 +#define PXA210_B0 0x00000122 +#define IXP425_A0 0x000001c1 +#define IXP425_B0 0x000001f1 +#define IXP465_AD 0x00000200 + +/* + * probe - binds to the platform device + */ +static int __init pxa25x_udc_probe(struct platform_device *pdev) +{ + struct pxa25x_udc *dev = &memory; + int retval, vbus_irq, irq; + u32 chiprev; + + /* insist on Intel/ARM/XScale */ + asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev)); + if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) { + pr_err("%s: not XScale!\n", driver_name); + return -ENODEV; + } + + /* trigger chiprev-specific logic */ + switch (chiprev & CP15R0_PRODREV_MASK) { +#if defined(CONFIG_ARCH_PXA) + case PXA255_A0: + dev->has_cfr = 1; + break; + case PXA250_A0: + case PXA250_A1: + /* A0/A1 "not released"; ep 13, 15 unusable */ + /* fall through */ + case PXA250_B2: case PXA210_B2: + case PXA250_B1: case PXA210_B1: + case PXA250_B0: case PXA210_B0: + /* OUT-DMA is broken ... */ + /* fall through */ + case PXA250_C0: case PXA210_C0: + break; +#elif defined(CONFIG_ARCH_IXP4XX) + case IXP425_A0: + case IXP425_B0: + case IXP465_AD: + dev->has_cfr = 1; + break; +#endif + default: + pr_err("%s: unrecognized processor: %08x\n", + driver_name, chiprev); + /* iop3xx, ixp4xx, ... */ + return -ENODEV; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENODEV; + + dev->clk = clk_get(&pdev->dev, "UDCCLK"); + if (IS_ERR(dev->clk)) { + retval = PTR_ERR(dev->clk); + goto err_clk; + } + + pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, + dev->has_cfr ? "" : " (!cfr)", + SIZE_STR "(pio)" + ); + + /* other non-static parts of init */ + dev->dev = &pdev->dev; + dev->mach = pdev->dev.platform_data; + + if (dev->mach->gpio_vbus) { + if ((retval = gpio_request(dev->mach->gpio_vbus, + "pxa25x_udc GPIO VBUS"))) { + dev_dbg(&pdev->dev, + "can't get vbus gpio %d, err: %d\n", + dev->mach->gpio_vbus, retval); + goto err_gpio_vbus; + } + gpio_direction_input(dev->mach->gpio_vbus); + vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); + } else + vbus_irq = 0; + + if (dev->mach->gpio_pullup) { + if ((retval = gpio_request(dev->mach->gpio_pullup, + "pca25x_udc GPIO PULLUP"))) { + dev_dbg(&pdev->dev, + "can't get pullup gpio %d, err: %d\n", + dev->mach->gpio_pullup, retval); + goto err_gpio_pullup; + } + gpio_direction_output(dev->mach->gpio_pullup, 0); + } + + init_timer(&dev->timer); + dev->timer.function = udc_watchdog; + dev->timer.data = (unsigned long) dev; + + device_initialize(&dev->gadget.dev); + dev->gadget.dev.parent = &pdev->dev; + dev->gadget.dev.dma_mask = pdev->dev.dma_mask; + + the_controller = dev; + platform_set_drvdata(pdev, dev); + + udc_disable(dev); + udc_reinit(dev); + + dev->vbus = is_vbus_present(); + + /* irq setup after old hardware state is cleaned up */ + retval = request_irq(irq, pxa25x_udc_irq, + IRQF_DISABLED, driver_name, dev); + if (retval != 0) { + pr_err("%s: can't get irq %d, err %d\n", + driver_name, irq, retval); + goto err_irq1; + } + dev->got_irq = 1; + +#ifdef CONFIG_ARCH_LUBBOCK + if (machine_is_lubbock()) { + retval = request_irq(LUBBOCK_USB_DISC_IRQ, + lubbock_vbus_irq, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + driver_name, dev); + if (retval != 0) { + pr_err("%s: can't get irq %i, err %d\n", + driver_name, LUBBOCK_USB_DISC_IRQ, retval); +lubbock_fail0: + goto err_irq_lub; + } + retval = request_irq(LUBBOCK_USB_IRQ, + lubbock_vbus_irq, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + driver_name, dev); + if (retval != 0) { + pr_err("%s: can't get irq %i, err %d\n", + driver_name, LUBBOCK_USB_IRQ, retval); + free_irq(LUBBOCK_USB_DISC_IRQ, dev); + goto lubbock_fail0; + } + } else +#endif + if (vbus_irq) { + retval = request_irq(vbus_irq, udc_vbus_irq, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM | + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + driver_name, dev); + if (retval != 0) { + pr_err("%s: can't get irq %i, err %d\n", + driver_name, vbus_irq, retval); + goto err_vbus_irq; + } + } + create_debug_files(dev); + + return 0; + + err_vbus_irq: +#ifdef CONFIG_ARCH_LUBBOCK + free_irq(LUBBOCK_USB_DISC_IRQ, dev); + err_irq_lub: +#endif + free_irq(irq, dev); + err_irq1: + if (dev->mach->gpio_pullup) + gpio_free(dev->mach->gpio_pullup); + err_gpio_pullup: + if (dev->mach->gpio_vbus) + gpio_free(dev->mach->gpio_vbus); + err_gpio_vbus: + clk_put(dev->clk); + err_clk: + return retval; +} + +static void pxa25x_udc_shutdown(struct platform_device *_dev) +{ + pullup_off(); +} + +static int __exit pxa25x_udc_remove(struct platform_device *pdev) +{ + struct pxa25x_udc *dev = platform_get_drvdata(pdev); + + if (dev->driver) + return -EBUSY; + + dev->pullup = 0; + pullup(dev); + + remove_debug_files(dev); + + if (dev->got_irq) { + free_irq(platform_get_irq(pdev, 0), dev); + dev->got_irq = 0; + } +#ifdef CONFIG_ARCH_LUBBOCK + if (machine_is_lubbock()) { + free_irq(LUBBOCK_USB_DISC_IRQ, dev); + free_irq(LUBBOCK_USB_IRQ, dev); + } +#endif + if (dev->mach->gpio_vbus) { + free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); + gpio_free(dev->mach->gpio_vbus); + } + if (dev->mach->gpio_pullup) + gpio_free(dev->mach->gpio_pullup); + + clk_put(dev->clk); + + platform_set_drvdata(pdev, NULL); + the_controller = NULL; + return 0; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_PM + +/* USB suspend (controlled by the host) and system suspend (controlled + * by the PXA) don't necessarily work well together. If USB is active, + * the 48 MHz clock is required; so the system can't enter 33 MHz idle + * mode, or any deeper PM saving state. + * + * For now, we punt and forcibly disconnect from the USB host when PXA + * enters any suspend state. While we're disconnected, we always disable + * the 48MHz USB clock ... allowing PXA sleep and/or 33 MHz idle states. + * Boards without software pullup control shouldn't use those states. + * VBUS IRQs should probably be ignored so that the PXA device just acts + * "dead" to USB hosts until system resume. + */ +static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state) +{ + struct pxa25x_udc *udc = platform_get_drvdata(dev); + unsigned long flags; + + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) + WARN("USB host won't detect disconnect!\n"); + udc->suspended = 1; + + local_irq_save(flags); + pullup(udc); + local_irq_restore(flags); + + return 0; +} + +static int pxa25x_udc_resume(struct platform_device *dev) +{ + struct pxa25x_udc *udc = platform_get_drvdata(dev); + unsigned long flags; + + udc->suspended = 0; + local_irq_save(flags); + pullup(udc); + local_irq_restore(flags); + + return 0; +} + +#else +#define pxa25x_udc_suspend NULL +#define pxa25x_udc_resume NULL +#endif + +/*-------------------------------------------------------------------------*/ + +static struct platform_driver udc_driver = { + .shutdown = pxa25x_udc_shutdown, + .remove = __exit_p(pxa25x_udc_remove), + .suspend = pxa25x_udc_suspend, + .resume = pxa25x_udc_resume, + .driver = { + .owner = THIS_MODULE, + .name = "pxa25x-udc", + }, +}; + +static int __init udc_init(void) +{ + pr_info("%s: version %s\n", driver_name, DRIVER_VERSION); + return platform_driver_probe(&udc_driver, pxa25x_udc_probe); +} +module_init(udc_init); + +static void __exit udc_exit(void) +{ + platform_driver_unregister(&udc_driver); +} +module_exit(udc_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa25x-udc"); diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h new file mode 100644 index 0000000..4d11ece --- /dev/null +++ b/drivers/usb/gadget/pxa25x_udc.h @@ -0,0 +1,266 @@ +/* + * Intel PXA25x on-chip full speed USB device controller + * + * Copyright (C) 2003 Robert Schwebel , Pengutronix + * Copyright (C) 2003 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. + * + * 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 __LINUX_USB_GADGET_PXA25X_H +#define __LINUX_USB_GADGET_PXA25X_H + +#include + +/*-------------------------------------------------------------------------*/ + +/* pxa25x has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */ +#define UFNRH_SIR (1 << 7) /* SOF interrupt request */ +#define UFNRH_SIM (1 << 6) /* SOF interrupt mask */ +#define UFNRH_IPE14 (1 << 5) /* ISO packet error, ep14 */ +#define UFNRH_IPE9 (1 << 4) /* ISO packet error, ep9 */ +#define UFNRH_IPE4 (1 << 3) /* ISO packet error, ep4 */ + +/* pxa255 has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */ +#define UDCCFR UDC_RES2 /* UDC Control Function Register */ +#define UDCCFR_AREN (1 << 7) /* ACK response enable (now) */ +#define UDCCFR_ACM (1 << 2) /* ACK control mode (wait for AREN) */ + +/* latest pxa255 errata define new "must be one" bits in UDCCFR */ +#define UDCCFR_MB1 (0xff & ~(UDCCFR_AREN|UDCCFR_ACM)) + +/*-------------------------------------------------------------------------*/ + +struct pxa25x_udc; + +struct pxa25x_ep { + struct usb_ep ep; + struct pxa25x_udc *dev; + + const struct usb_endpoint_descriptor *desc; + struct list_head queue; + unsigned long pio_irqs; + + unsigned short fifo_size; + u8 bEndpointAddress; + u8 bmAttributes; + + unsigned stopped : 1; + unsigned dma_fixup : 1; + + /* UDCCS = UDC Control/Status for this EP + * UBCR = UDC Byte Count Remaining (contents of OUT fifo) + * UDDR = UDC Endpoint Data Register (the fifo) + * DRCM = DMA Request Channel Map + */ + volatile u32 *reg_udccs; + volatile u32 *reg_ubcr; + volatile u32 *reg_uddr; +}; + +struct pxa25x_request { + struct usb_request req; + struct list_head queue; +}; + +enum ep0_state { + EP0_IDLE, + EP0_IN_DATA_PHASE, + EP0_OUT_DATA_PHASE, + EP0_END_XFER, + EP0_STALL, +}; + +#define EP0_FIFO_SIZE ((unsigned)16) +#define BULK_FIFO_SIZE ((unsigned)64) +#define ISO_FIFO_SIZE ((unsigned)256) +#define INT_FIFO_SIZE ((unsigned)8) + +struct udc_stats { + struct ep0stats { + unsigned long ops; + unsigned long bytes; + } read, write; + unsigned long irqs; +}; + +#ifdef CONFIG_USB_PXA25X_SMALL +/* when memory's tight, SMALL config saves code+data. */ +#define PXA_UDC_NUM_ENDPOINTS 3 +#endif + +#ifndef PXA_UDC_NUM_ENDPOINTS +#define PXA_UDC_NUM_ENDPOINTS 16 +#endif + +struct pxa25x_udc { + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + + enum ep0_state ep0state; + struct udc_stats stats; + unsigned got_irq : 1, + vbus : 1, + pullup : 1, + has_cfr : 1, + req_pending : 1, + req_std : 1, + req_config : 1, + suspended : 1, + active : 1; + +#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) + struct timer_list timer; + + struct device *dev; + struct clk *clk; + struct pxa2xx_udc_mach_info *mach; + u64 dma_mask; + struct pxa25x_ep ep [PXA_UDC_NUM_ENDPOINTS]; + +#ifdef CONFIG_USB_GADGET_DEBUG_FS + struct dentry *debugfs_udc; +#endif +}; + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_LUBBOCK +#include +/* lubbock can also report usb connect/disconnect irqs */ +#endif + +static struct pxa25x_udc *the_controller; + +/*-------------------------------------------------------------------------*/ + +/* + * Debugging support vanishes in non-debug builds. DBG_NORMAL should be + * mostly silent during normal use/testing, with no timing side-effects. + */ +#define DBG_NORMAL 1 /* error paths, device state transitions */ +#define DBG_VERBOSE 2 /* add some success path trace info */ +#define DBG_NOISY 3 /* ... even more: request level */ +#define DBG_VERY_NOISY 4 /* ... even more: packet level */ + +#define DMSG(stuff...) pr_debug("udc: " stuff) + +#ifdef DEBUG + +static int is_vbus_present(void); + +static const char *state_name[] = { + "EP0_IDLE", + "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", + "EP0_END_XFER", "EP0_STALL" +}; + +#ifdef VERBOSE_DEBUG +# define UDC_DEBUG DBG_VERBOSE +#else +# define UDC_DEBUG DBG_NORMAL +#endif + +static void __maybe_unused +dump_udccr(const char *label) +{ + u32 udccr = UDCCR; + DMSG("%s %02X =%s%s%s%s%s%s%s%s\n", + label, udccr, + (udccr & UDCCR_REM) ? " rem" : "", + (udccr & UDCCR_RSTIR) ? " rstir" : "", + (udccr & UDCCR_SRM) ? " srm" : "", + (udccr & UDCCR_SUSIR) ? " susir" : "", + (udccr & UDCCR_RESIR) ? " resir" : "", + (udccr & UDCCR_RSM) ? " rsm" : "", + (udccr & UDCCR_UDA) ? " uda" : "", + (udccr & UDCCR_UDE) ? " ude" : ""); +} + +static void __maybe_unused +dump_udccs0(const char *label) +{ + u32 udccs0 = UDCCS0; + + DMSG("%s %s %02X =%s%s%s%s%s%s%s%s\n", + label, state_name[the_controller->ep0state], udccs0, + (udccs0 & UDCCS0_SA) ? " sa" : "", + (udccs0 & UDCCS0_RNE) ? " rne" : "", + (udccs0 & UDCCS0_FST) ? " fst" : "", + (udccs0 & UDCCS0_SST) ? " sst" : "", + (udccs0 & UDCCS0_DRWF) ? " dwrf" : "", + (udccs0 & UDCCS0_FTF) ? " ftf" : "", + (udccs0 & UDCCS0_IPR) ? " ipr" : "", + (udccs0 & UDCCS0_OPR) ? " opr" : ""); +} + +static void __maybe_unused +dump_state(struct pxa25x_udc *dev) +{ + u32 tmp; + unsigned i; + + DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", + is_vbus_present() ? "host " : "disconnected", + state_name[dev->ep0state], + UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); + dump_udccr("udccr"); + if (dev->has_cfr) { + tmp = UDCCFR; + DMSG("udccfr %02X =%s%s\n", tmp, + (tmp & UDCCFR_AREN) ? " aren" : "", + (tmp & UDCCFR_ACM) ? " acm" : ""); + } + + if (!dev->driver) { + DMSG("no gadget driver bound\n"); + return; + } else + DMSG("ep0 driver '%s'\n", dev->driver->driver.name); + + if (!is_vbus_present()) + return; + + dump_udccs0 ("udccs0"); + DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n", + dev->stats.write.bytes, dev->stats.write.ops, + dev->stats.read.bytes, dev->stats.read.ops); + + for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { + if (dev->ep [i].desc == NULL) + continue; + DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); + } +} + +#else + +#define dump_udccr(x) do{}while(0) +#define dump_udccs0(x) do{}while(0) +#define dump_state(x) do{}while(0) + +#define UDC_DEBUG ((unsigned)0) + +#endif + +#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) + +#define ERR(stuff...) pr_err("udc: " stuff) +#define WARN(stuff...) pr_warning("udc: " stuff) +#define INFO(stuff...) pr_info("udc: " stuff) + + +#endif /* __LINUX_USB_GADGET_PXA25X_H */ diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 40d6b58..4771b13 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2367,11 +2367,11 @@ static int pxa_udc_resume(struct platform_device *_dev) #endif /* work with hotplug and coldplug */ -MODULE_ALIAS("platform:pxa2xx-udc"); +MODULE_ALIAS("platform:pxa27x-udc"); static struct platform_driver udc_driver = { .driver = { - .name = "pxa2xx-udc", + .name = "pxa27x-udc", .owner = THIS_MODULE, }, .remove = __exit_p(pxa_udc_remove), diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c deleted file mode 100644 index 63db96a..0000000 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ /dev/null @@ -1,2389 +0,0 @@ -/* - * linux/drivers/usb/gadget/pxa2xx_udc.c - * Intel PXA25x and IXP4xx on-chip full speed USB device controllers - * - * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker) - * Copyright (C) 2003 Robert Schwebel, Pengutronix - * Copyright (C) 2003 Benedikt Spranger, Pengutronix - * Copyright (C) 2003 David Brownell - * Copyright (C) 2003 Joshua Wise - * - * 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 - * - */ - -/* #define VERBOSE_DEBUG */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * This driver is PXA25x only. Grab the right register definitions. - */ -#ifdef CONFIG_ARCH_PXA -#include -#endif - -#include - - -/* - * This driver handles the USB Device Controller (UDC) in Intel's PXA 25x - * series processors. The UDC for the IXP 4xx series is very similar. - * There are fifteen endpoints, in addition to ep0. - * - * Such controller drivers work with a gadget driver. The gadget driver - * returns descriptors, implements configuration and data protocols used - * by the host to interact with this device, and allocates endpoints to - * the different protocol interfaces. The controller driver virtualizes - * usb hardware so that the gadget drivers will be more portable. - * - * This UDC hardware wants to implement a bit too much USB protocol, so - * it constrains the sorts of USB configuration change events that work. - * The errata for these chips are misleading; some "fixed" bugs from - * pxa250 a0/a1 b0/b1/b2 sure act like they're still there. - * - * Note that the UDC hardware supports DMA (except on IXP) but that's - * not used here. IN-DMA (to host) is simple enough, when the data is - * suitably aligned (16 bytes) ... the network stack doesn't do that, - * other software can. OUT-DMA is buggy in most chip versions, as well - * as poorly designed (data toggle not automatic). So this driver won't - * bother using DMA. (Mostly-working IN-DMA support was available in - * kernels before 2.6.23, but was never enabled or well tested.) - */ - -#define DRIVER_VERSION "30-June-2007" -#define DRIVER_DESC "PXA 25x USB Device Controller driver" - - -static const char driver_name [] = "pxa2xx_udc"; - -static const char ep0name [] = "ep0"; - - -#ifdef CONFIG_ARCH_IXP4XX - -/* cpu-specific register addresses are compiled in to this code */ -#ifdef CONFIG_ARCH_PXA -#error "Can't configure both IXP and PXA" -#endif - -/* IXP doesn't yet support */ -#define clk_get(dev,name) NULL -#define clk_enable(clk) do { } while (0) -#define clk_disable(clk) do { } while (0) -#define clk_put(clk) do { } while (0) - -#endif - -#include "pxa2xx_udc.h" - - -#ifdef CONFIG_USB_PXA2XX_SMALL -#define SIZE_STR " (small)" -#else -#define SIZE_STR "" -#endif - -/* --------------------------------------------------------------------------- - * endpoint related parts of the api to the usb controller hardware, - * used by gadget driver; and the inner talker-to-hardware core. - * --------------------------------------------------------------------------- - */ - -static void pxa2xx_ep_fifo_flush (struct usb_ep *ep); -static void nuke (struct pxa2xx_ep *, int status); - -/* one GPIO should be used to detect VBUS from the host */ -static int is_vbus_present(void) -{ - struct pxa2xx_udc_mach_info *mach = the_controller->mach; - - if (mach->gpio_vbus) { - int value = gpio_get_value(mach->gpio_vbus); - return mach->gpio_vbus_inverted ? !value : value; - } - if (mach->udc_is_connected) - return mach->udc_is_connected(); - return 1; -} - -/* one GPIO should control a D+ pullup, so host sees this device (or not) */ -static void pullup_off(void) -{ - struct pxa2xx_udc_mach_info *mach = the_controller->mach; - - if (mach->gpio_pullup) - gpio_set_value(mach->gpio_pullup, 0); - else if (mach->udc_command) - mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); -} - -static void pullup_on(void) -{ - struct pxa2xx_udc_mach_info *mach = the_controller->mach; - - if (mach->gpio_pullup) - gpio_set_value(mach->gpio_pullup, 1); - else if (mach->udc_command) - mach->udc_command(PXA2XX_UDC_CMD_CONNECT); -} - -static void pio_irq_enable(int bEndpointAddress) -{ - bEndpointAddress &= 0xf; - if (bEndpointAddress < 8) - UICR0 &= ~(1 << bEndpointAddress); - else { - bEndpointAddress -= 8; - UICR1 &= ~(1 << bEndpointAddress); - } -} - -static void pio_irq_disable(int bEndpointAddress) -{ - bEndpointAddress &= 0xf; - if (bEndpointAddress < 8) - UICR0 |= 1 << bEndpointAddress; - else { - bEndpointAddress -= 8; - UICR1 |= 1 << bEndpointAddress; - } -} - -/* The UDCCR reg contains mask and interrupt status bits, - * so using '|=' isn't safe as it may ack an interrupt. - */ -#define UDCCR_MASK_BITS (UDCCR_REM | UDCCR_SRM | UDCCR_UDE) - -static inline void udc_set_mask_UDCCR(int mask) -{ - UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS); -} - -static inline void udc_clear_mask_UDCCR(int mask) -{ - UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS); -} - -static inline void udc_ack_int_UDCCR(int mask) -{ - /* udccr contains the bits we dont want to change */ - __u32 udccr = UDCCR & UDCCR_MASK_BITS; - - UDCCR = udccr | (mask & ~UDCCR_MASK_BITS); -} - -/* - * endpoint enable/disable - * - * we need to verify the descriptors used to enable endpoints. since pxa2xx - * endpoint configurations are fixed, and are pretty much always enabled, - * there's not a lot to manage here. - * - * because pxa2xx can't selectively initialize bulk (or interrupt) endpoints, - * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except - * for a single interface (with only the default altsetting) and for gadget - * drivers that don't halt endpoints (not reset by set_interface). that also - * means that if you use ISO, you must violate the USB spec rule that all - * iso endpoints must be in non-default altsettings. - */ -static int pxa2xx_ep_enable (struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) -{ - struct pxa2xx_ep *ep; - struct pxa2xx_udc *dev; - - ep = container_of (_ep, struct pxa2xx_ep, ep); - if (!_ep || !desc || ep->desc || _ep->name == ep0name - || desc->bDescriptorType != USB_DT_ENDPOINT - || ep->bEndpointAddress != desc->bEndpointAddress - || ep->fifo_size < le16_to_cpu - (desc->wMaxPacketSize)) { - DMSG("%s, bad ep or descriptor\n", __func__); - 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) { - DMSG("%s, %s type mismatch\n", __func__, _ep->name); - return -EINVAL; - } - - /* hardware _could_ do smaller, but driver doesn't */ - if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK - && le16_to_cpu (desc->wMaxPacketSize) - != BULK_FIFO_SIZE) - || !desc->wMaxPacketSize) { - DMSG("%s, bad %s maxpacket\n", __func__, _ep->name); - return -ERANGE; - } - - dev = ep->dev; - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DMSG("%s, bogus device state\n", __func__); - return -ESHUTDOWN; - } - - ep->desc = desc; - ep->stopped = 0; - ep->pio_irqs = 0; - ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize); - - /* flush fifo (mostly for OUT buffers) */ - pxa2xx_ep_fifo_flush (_ep); - - /* ... reset halt state too, if we could ... */ - - DBG(DBG_VERBOSE, "enabled %s\n", _ep->name); - return 0; -} - -static int pxa2xx_ep_disable (struct usb_ep *_ep) -{ - struct pxa2xx_ep *ep; - unsigned long flags; - - ep = container_of (_ep, struct pxa2xx_ep, ep); - if (!_ep || !ep->desc) { - DMSG("%s, %s not enabled\n", __func__, - _ep ? ep->ep.name : NULL); - return -EINVAL; - } - local_irq_save(flags); - - nuke (ep, -ESHUTDOWN); - - /* flush fifo (mostly for IN buffers) */ - pxa2xx_ep_fifo_flush (_ep); - - ep->desc = NULL; - ep->stopped = 1; - - local_irq_restore(flags); - DBG(DBG_VERBOSE, "%s disabled\n", _ep->name); - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* for the pxa2xx, these can just wrap kmalloc/kfree. gadget drivers - * must still pass correctly initialized endpoints, since other controller - * drivers may care about how it's currently set up (dma issues etc). - */ - -/* - * pxa2xx_ep_alloc_request - allocate a request data structure - */ -static struct usb_request * -pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) -{ - struct pxa2xx_request *req; - - req = kzalloc(sizeof(*req), gfp_flags); - if (!req) - return NULL; - - INIT_LIST_HEAD (&req->queue); - return &req->req; -} - - -/* - * pxa2xx_ep_free_request - deallocate a request data structure - */ -static void -pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) -{ - struct pxa2xx_request *req; - - req = container_of (_req, struct pxa2xx_request, req); - WARN_ON (!list_empty (&req->queue)); - kfree(req); -} - -/*-------------------------------------------------------------------------*/ - -/* - * done - retire a request; caller blocked irqs - */ -static void done(struct pxa2xx_ep *ep, struct pxa2xx_request *req, int status) -{ - unsigned stopped = ep->stopped; - - list_del_init(&req->queue); - - if (likely (req->req.status == -EINPROGRESS)) - req->req.status = status; - else - status = req->req.status; - - if (status && status != -ESHUTDOWN) - DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n", - ep->ep.name, &req->req, status, - req->req.actual, req->req.length); - - /* don't modify queue heads during completion callback */ - ep->stopped = 1; - req->req.complete(&ep->ep, &req->req); - ep->stopped = stopped; -} - - -static inline void ep0_idle (struct pxa2xx_udc *dev) -{ - dev->ep0state = EP0_IDLE; -} - -static int -write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max) -{ - u8 *buf; - unsigned length, count; - - buf = req->req.buf + req->req.actual; - prefetch(buf); - - /* how big will this packet be? */ - length = min(req->req.length - req->req.actual, max); - req->req.actual += length; - - count = length; - while (likely(count--)) - *uddr = *buf++; - - return length; -} - -/* - * write to an IN endpoint fifo, as many packets as possible. - * irqs will use this to write the rest later. - * caller guarantees at least one packet buffer is ready (or a zlp). - */ -static int -write_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) -{ - unsigned max; - - max = le16_to_cpu(ep->desc->wMaxPacketSize); - do { - unsigned count; - int is_last, is_short; - - count = write_packet(ep->reg_uddr, req, max); - - /* last packet is usually short (or a zlp) */ - if (unlikely (count != max)) - is_last = is_short = 1; - else { - if (likely(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 = unlikely (max < ep->fifo_size); - } - - DBG(DBG_VERY_NOISY, "wrote %s %d bytes%s%s %d left %p\n", - ep->ep.name, count, - is_last ? "/L" : "", is_short ? "/S" : "", - req->req.length - req->req.actual, req); - - /* let loose that packet. maybe try writing another one, - * double buffering might work. TSP, TPC, and TFS - * bit values are the same for all normal IN endpoints. - */ - *ep->reg_udccs = UDCCS_BI_TPC; - if (is_short) - *ep->reg_udccs = UDCCS_BI_TSP; - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - done (ep, req, 0); - if (list_empty(&ep->queue)) - pio_irq_disable (ep->bEndpointAddress); - return 1; - } - - // TODO experiment: how robust can fifo mode tweaking be? - // double buffering is off in the default fifo mode, which - // prevents TFS from being set here. - - } while (*ep->reg_udccs & UDCCS_BI_TFS); - return 0; -} - -/* caller asserts req->pending (ep0 irq status nyet cleared); starts - * ep0 data stage. these chips want very simple state transitions. - */ -static inline -void ep0start(struct pxa2xx_udc *dev, u32 flags, const char *tag) -{ - UDCCS0 = flags|UDCCS0_SA|UDCCS0_OPR; - USIR0 = USIR0_IR0; - dev->req_pending = 0; - DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n", - __func__, tag, UDCCS0, flags); -} - -static int -write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) -{ - unsigned count; - int is_short; - - count = write_packet(&UDDR0, req, EP0_FIFO_SIZE); - ep->dev->stats.write.bytes += count; - - /* last packet "must be" short (or a zlp) */ - is_short = (count != EP0_FIFO_SIZE); - - DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count, - req->req.length - req->req.actual, req); - - if (unlikely (is_short)) { - if (ep->dev->req_pending) - ep0start(ep->dev, UDCCS0_IPR, "short IN"); - else - UDCCS0 = UDCCS0_IPR; - - count = req->req.length; - done (ep, req, 0); - ep0_idle(ep->dev); -#ifndef CONFIG_ARCH_IXP4XX -#if 1 - /* This seems to get rid of lost status irqs in some cases: - * host responds quickly, or next request involves config - * change automagic, or should have been hidden, or ... - * - * FIXME get rid of all udelays possible... - */ - if (count >= EP0_FIFO_SIZE) { - count = 100; - do { - if ((UDCCS0 & UDCCS0_OPR) != 0) { - /* clear OPR, generate ack */ - UDCCS0 = UDCCS0_OPR; - break; - } - count--; - udelay(1); - } while (count); - } -#endif -#endif - } else if (ep->dev->req_pending) - ep0start(ep->dev, 0, "IN"); - return is_short; -} - - -/* - * read_fifo - unload packet(s) from the fifo we use for usb OUT - * transfers and put them into the request. caller should have made - * sure there's at least one packet ready. - * - * returns true if the request completed because of short packet or the - * request buffer having filled (and maybe overran till end-of-packet). - */ -static int -read_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) -{ - for (;;) { - u32 udccs; - u8 *buf; - unsigned bufferspace, count, is_short; - - /* make sure there's a packet in the FIFO. - * UDCCS_{BO,IO}_RPC are all the same bit value. - * UDCCS_{BO,IO}_RNE are all the same bit value. - */ - udccs = *ep->reg_udccs; - if (unlikely ((udccs & UDCCS_BO_RPC) == 0)) - break; - buf = req->req.buf + req->req.actual; - prefetchw(buf); - bufferspace = req->req.length - req->req.actual; - - /* read all bytes from this packet */ - if (likely (udccs & UDCCS_BO_RNE)) { - count = 1 + (0x0ff & *ep->reg_ubcr); - req->req.actual += min (count, bufferspace); - } else /* zlp */ - count = 0; - is_short = (count < ep->ep.maxpacket); - DBG(DBG_VERY_NOISY, "read %s %02x, %d bytes%s req %p %d/%d\n", - ep->ep.name, udccs, count, - is_short ? "/S" : "", - req, req->req.actual, req->req.length); - while (likely (count-- != 0)) { - u8 byte = (u8) *ep->reg_uddr; - - 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) - DMSG("%s overflow %d\n", - ep->ep.name, count); - req->req.status = -EOVERFLOW; - } else { - *buf++ = byte; - bufferspace--; - } - } - *ep->reg_udccs = UDCCS_BO_RPC; - /* RPC/RSP/RNE could now reflect the other packet buffer */ - - /* iso is one request per packet */ - if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { - if (udccs & UDCCS_IO_ROF) - req->req.status = -EHOSTUNREACH; - /* more like "is_done" */ - is_short = 1; - } - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - done (ep, req, 0); - if (list_empty(&ep->queue)) - pio_irq_disable (ep->bEndpointAddress); - return 1; - } - - /* finished that packet. the next one may be waiting... */ - } - return 0; -} - -/* - * special ep0 version of the above. no UBCR0 or double buffering; status - * handshaking is magic. most device protocols don't need control-OUT. - * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other - * protocols do use them. - */ -static int -read_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req) -{ - u8 *buf, byte; - unsigned bufferspace; - - buf = req->req.buf + req->req.actual; - bufferspace = req->req.length - req->req.actual; - - while (UDCCS0 & UDCCS0_RNE) { - byte = (u8) UDDR0; - - 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) - DMSG("%s overflow\n", ep->ep.name); - req->req.status = -EOVERFLOW; - } else { - *buf++ = byte; - req->req.actual++; - bufferspace--; - } - } - - UDCCS0 = UDCCS0_OPR | UDCCS0_IPR; - - /* completion */ - if (req->req.actual >= req->req.length) - return 1; - - /* finished that packet. the next one may be waiting... */ - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int -pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) -{ - struct pxa2xx_request *req; - struct pxa2xx_ep *ep; - struct pxa2xx_udc *dev; - unsigned long flags; - - req = container_of(_req, struct pxa2xx_request, req); - if (unlikely (!_req || !_req->complete || !_req->buf - || !list_empty(&req->queue))) { - DMSG("%s, bad params\n", __func__); - return -EINVAL; - } - - ep = container_of(_ep, struct pxa2xx_ep, ep); - if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DMSG("%s, bad ep\n", __func__); - return -EINVAL; - } - - dev = ep->dev; - if (unlikely (!dev->driver - || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - DMSG("%s, bogus device state\n", __func__); - return -ESHUTDOWN; - } - - /* iso is always one packet per request, that's the only way - * we can report per-packet status. that also helps with dma. - */ - if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC - && req->req.length > le16_to_cpu - (ep->desc->wMaxPacketSize))) - return -EMSGSIZE; - - DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n", - _ep->name, _req, _req->length, _req->buf); - - local_irq_save(flags); - - _req->status = -EINPROGRESS; - _req->actual = 0; - - /* kickstart this i/o queue? */ - if (list_empty(&ep->queue) && !ep->stopped) { - if (ep->desc == NULL/* ep0 */) { - unsigned length = _req->length; - - switch (dev->ep0state) { - case EP0_IN_DATA_PHASE: - dev->stats.write.ops++; - if (write_ep0_fifo(ep, req)) - req = NULL; - break; - - case EP0_OUT_DATA_PHASE: - dev->stats.read.ops++; - /* messy ... */ - if (dev->req_config) { - DBG(DBG_VERBOSE, "ep0 config ack%s\n", - dev->has_cfr ? "" : " raced"); - if (dev->has_cfr) - UDCCFR = UDCCFR_AREN|UDCCFR_ACM - |UDCCFR_MB1; - done(ep, req, 0); - dev->ep0state = EP0_END_XFER; - local_irq_restore (flags); - return 0; - } - if (dev->req_pending) - ep0start(dev, UDCCS0_IPR, "OUT"); - if (length == 0 || ((UDCCS0 & UDCCS0_RNE) != 0 - && read_ep0_fifo(ep, req))) { - ep0_idle(dev); - done(ep, req, 0); - req = NULL; - } - break; - - default: - DMSG("ep0 i/o, odd state %d\n", dev->ep0state); - local_irq_restore (flags); - return -EL2HLT; - } - /* can the FIFO can satisfy the request immediately? */ - } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) { - if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0 - && write_fifo(ep, req)) - req = NULL; - } else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0 - && read_fifo(ep, req)) { - req = NULL; - } - - if (likely (req && ep->desc)) - pio_irq_enable(ep->bEndpointAddress); - } - - /* pio or dma irq handler advances the queue. */ - if (likely(req != NULL)) - list_add_tail(&req->queue, &ep->queue); - local_irq_restore(flags); - - return 0; -} - - -/* - * nuke - dequeue ALL requests - */ -static void nuke(struct pxa2xx_ep *ep, int status) -{ - struct pxa2xx_request *req; - - /* called with irqs blocked */ - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, - struct pxa2xx_request, - queue); - done(ep, req, status); - } - if (ep->desc) - pio_irq_disable (ep->bEndpointAddress); -} - - -/* dequeue JUST ONE request */ -static int pxa2xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct pxa2xx_ep *ep; - struct pxa2xx_request *req; - unsigned long flags; - - ep = container_of(_ep, struct pxa2xx_ep, ep); - if (!_ep || ep->ep.name == ep0name) - return -EINVAL; - - local_irq_save(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) { - local_irq_restore(flags); - return -EINVAL; - } - - done(ep, req, -ECONNRESET); - - local_irq_restore(flags); - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int pxa2xx_ep_set_halt(struct usb_ep *_ep, int value) -{ - struct pxa2xx_ep *ep; - unsigned long flags; - - ep = container_of(_ep, struct pxa2xx_ep, ep); - if (unlikely (!_ep - || (!ep->desc && ep->ep.name != ep0name)) - || ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) { - DMSG("%s, bad ep\n", __func__); - return -EINVAL; - } - if (value == 0) { - /* this path (reset toggle+halt) is needed to implement - * SET_INTERFACE on normal hardware. but it can't be - * done from software on the PXA UDC, and the hardware - * forgets to do it as part of SET_INTERFACE automagic. - */ - DMSG("only host can clear %s halt\n", _ep->name); - return -EROFS; - } - - local_irq_save(flags); - - if ((ep->bEndpointAddress & USB_DIR_IN) != 0 - && ((*ep->reg_udccs & UDCCS_BI_TFS) == 0 - || !list_empty(&ep->queue))) { - local_irq_restore(flags); - return -EAGAIN; - } - - /* FST bit is the same for control, bulk in, bulk out, interrupt in */ - *ep->reg_udccs = UDCCS_BI_FST|UDCCS_BI_FTF; - - /* ep0 needs special care */ - if (!ep->desc) { - start_watchdog(ep->dev); - ep->dev->req_pending = 0; - ep->dev->ep0state = EP0_STALL; - - /* and bulk/intr endpoints like dropping stalls too */ - } else { - unsigned i; - for (i = 0; i < 1000; i += 20) { - if (*ep->reg_udccs & UDCCS_BI_SST) - break; - udelay(20); - } - } - local_irq_restore(flags); - - DBG(DBG_VERBOSE, "%s halt\n", _ep->name); - return 0; -} - -static int pxa2xx_ep_fifo_status(struct usb_ep *_ep) -{ - struct pxa2xx_ep *ep; - - ep = container_of(_ep, struct pxa2xx_ep, ep); - if (!_ep) { - DMSG("%s, bad ep\n", __func__); - return -ENODEV; - } - /* pxa can't report unclaimed bytes from IN fifos */ - if ((ep->bEndpointAddress & USB_DIR_IN) != 0) - return -EOPNOTSUPP; - if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN - || (*ep->reg_udccs & UDCCS_BO_RFS) == 0) - return 0; - else - return (*ep->reg_ubcr & 0xfff) + 1; -} - -static void pxa2xx_ep_fifo_flush(struct usb_ep *_ep) -{ - struct pxa2xx_ep *ep; - - ep = container_of(_ep, struct pxa2xx_ep, ep); - if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) { - DMSG("%s, bad ep\n", __func__); - return; - } - - /* toggle and halt bits stay unchanged */ - - /* for OUT, just read and discard the FIFO contents. */ - if ((ep->bEndpointAddress & USB_DIR_IN) == 0) { - while (((*ep->reg_udccs) & UDCCS_BO_RNE) != 0) - (void) *ep->reg_uddr; - return; - } - - /* 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; -} - - -static struct usb_ep_ops pxa2xx_ep_ops = { - .enable = pxa2xx_ep_enable, - .disable = pxa2xx_ep_disable, - - .alloc_request = pxa2xx_ep_alloc_request, - .free_request = pxa2xx_ep_free_request, - - .queue = pxa2xx_ep_queue, - .dequeue = pxa2xx_ep_dequeue, - - .set_halt = pxa2xx_ep_set_halt, - .fifo_status = pxa2xx_ep_fifo_status, - .fifo_flush = pxa2xx_ep_fifo_flush, -}; - - -/* --------------------------------------------------------------------------- - * device-scoped parts of the api to the usb controller hardware - * --------------------------------------------------------------------------- - */ - -static int pxa2xx_udc_get_frame(struct usb_gadget *_gadget) -{ - return ((UFNRH & 0x07) << 8) | (UFNRL & 0xff); -} - -static int pxa2xx_udc_wakeup(struct usb_gadget *_gadget) -{ - /* host may not have enabled remote wakeup */ - if ((UDCCS0 & UDCCS0_DRWF) == 0) - return -EHOSTUNREACH; - udc_set_mask_UDCCR(UDCCR_RSM); - return 0; -} - -static void stop_activity(struct pxa2xx_udc *, struct usb_gadget_driver *); -static void udc_enable (struct pxa2xx_udc *); -static void udc_disable(struct pxa2xx_udc *); - -/* We disable the UDC -- and its 48 MHz clock -- whenever it's not - * in active use. - */ -static int pullup(struct pxa2xx_udc *udc) -{ - int is_active = udc->vbus && udc->pullup && !udc->suspended; - DMSG("%s\n", is_active ? "active" : "inactive"); - if (is_active) { - if (!udc->active) { - udc->active = 1; - /* Enable clock for USB device */ - clk_enable(udc->clk); - udc_enable(udc); - } - } else { - if (udc->active) { - if (udc->gadget.speed != USB_SPEED_UNKNOWN) { - DMSG("disconnect %s\n", udc->driver - ? udc->driver->driver.name - : "(no driver)"); - stop_activity(udc, udc->driver); - } - udc_disable(udc); - /* Disable clock for USB device */ - clk_disable(udc->clk); - udc->active = 0; - } - - } - return 0; -} - -/* VBUS reporting logically comes from a transceiver */ -static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) -{ - struct pxa2xx_udc *udc; - - udc = container_of(_gadget, struct pxa2xx_udc, gadget); - udc->vbus = (is_active != 0); - DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); - pullup(udc); - return 0; -} - -/* drivers may have software control over D+ pullup */ -static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) -{ - struct pxa2xx_udc *udc; - - udc = container_of(_gadget, struct pxa2xx_udc, gadget); - - /* not all boards support pullup control */ - if (!udc->mach->gpio_pullup && !udc->mach->udc_command) - return -EOPNOTSUPP; - - udc->pullup = (is_active != 0); - pullup(udc); - return 0; -} - -static const struct usb_gadget_ops pxa2xx_udc_ops = { - .get_frame = pxa2xx_udc_get_frame, - .wakeup = pxa2xx_udc_wakeup, - .vbus_session = pxa2xx_udc_vbus_session, - .pullup = pxa2xx_udc_pullup, - - // .vbus_draw ... boards may consume current from VBUS, up to - // 100-500mA based on config. the 500uA suspend ceiling means - // that exclusively vbus-powered PXA designs violate USB specs. -}; - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_USB_GADGET_DEBUG_FS - -static int -udc_seq_show(struct seq_file *m, void *_d) -{ - struct pxa2xx_udc *dev = m->private; - unsigned long flags; - int i; - u32 tmp; - - local_irq_save(flags); - - /* basic device status */ - seq_printf(m, DRIVER_DESC "\n" - "%s version: %s\nGadget driver: %s\nHost %s\n\n", - driver_name, DRIVER_VERSION SIZE_STR "(pio)", - dev->driver ? dev->driver->driver.name : "(none)", - is_vbus_present() ? "full speed" : "disconnected"); - - /* registers for device and ep0 */ - seq_printf(m, - "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", - UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); - - tmp = UDCCR; - seq_printf(m, - "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, - (tmp & UDCCR_REM) ? " rem" : "", - (tmp & UDCCR_RSTIR) ? " rstir" : "", - (tmp & UDCCR_SRM) ? " srm" : "", - (tmp & UDCCR_SUSIR) ? " susir" : "", - (tmp & UDCCR_RESIR) ? " resir" : "", - (tmp & UDCCR_RSM) ? " rsm" : "", - (tmp & UDCCR_UDA) ? " uda" : "", - (tmp & UDCCR_UDE) ? " ude" : ""); - - tmp = UDCCS0; - seq_printf(m, - "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, - (tmp & UDCCS0_SA) ? " sa" : "", - (tmp & UDCCS0_RNE) ? " rne" : "", - (tmp & UDCCS0_FST) ? " fst" : "", - (tmp & UDCCS0_SST) ? " sst" : "", - (tmp & UDCCS0_DRWF) ? " dwrf" : "", - (tmp & UDCCS0_FTF) ? " ftf" : "", - (tmp & UDCCS0_IPR) ? " ipr" : "", - (tmp & UDCCS0_OPR) ? " opr" : ""); - - if (dev->has_cfr) { - tmp = UDCCFR; - seq_printf(m, - "udccfr %02X =%s%s\n", tmp, - (tmp & UDCCFR_AREN) ? " aren" : "", - (tmp & UDCCFR_ACM) ? " acm" : ""); - } - - if (!is_vbus_present() || !dev->driver) - goto done; - - seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", - dev->stats.write.bytes, dev->stats.write.ops, - dev->stats.read.bytes, dev->stats.read.ops, - dev->stats.irqs); - - /* dump endpoint queues */ - for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { - struct pxa2xx_ep *ep = &dev->ep [i]; - struct pxa2xx_request *req; - - if (i != 0) { - const struct usb_endpoint_descriptor *desc; - - desc = ep->desc; - if (!desc) - continue; - tmp = *dev->ep [i].reg_udccs; - seq_printf(m, - "%s max %d %s udccs %02x irqs %lu\n", - ep->ep.name, le16_to_cpu(desc->wMaxPacketSize), - "pio", tmp, ep->pio_irqs); - /* TODO translate all five groups of udccs bits! */ - - } else /* ep0 should only have one transfer queued */ - seq_printf(m, "ep0 max 16 pio irqs %lu\n", - ep->pio_irqs); - - if (list_empty(&ep->queue)) { - seq_printf(m, "\t(nothing queued)\n"); - continue; - } - list_for_each_entry(req, &ep->queue, queue) { - seq_printf(m, - "\treq %p len %d/%d buf %p\n", - &req->req, req->req.actual, - req->req.length, req->req.buf); - } - } - -done: - local_irq_restore(flags); - return 0; -} - -static int -udc_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, udc_seq_show, inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = udc_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -#define create_debug_files(dev) \ - do { \ - dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ - S_IRUGO, NULL, dev, &debug_fops); \ - } while (0) -#define remove_debug_files(dev) \ - do { \ - if (dev->debugfs_udc) \ - debugfs_remove(dev->debugfs_udc); \ - } while (0) - -#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ - -#define create_debug_files(dev) do {} while (0) -#define remove_debug_files(dev) do {} while (0) - -#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ - -/*-------------------------------------------------------------------------*/ - -/* - * udc_disable - disable USB device controller - */ -static void udc_disable(struct pxa2xx_udc *dev) -{ - /* block all irqs */ - udc_set_mask_UDCCR(UDCCR_SRM|UDCCR_REM); - UICR0 = UICR1 = 0xff; - UFNRH = UFNRH_SIM; - - /* if hardware supports it, disconnect from usb */ - pullup_off(); - - udc_clear_mask_UDCCR(UDCCR_UDE); - - ep0_idle (dev); - dev->gadget.speed = USB_SPEED_UNKNOWN; -} - - -/* - * udc_reinit - initialize software state - */ -static void udc_reinit(struct pxa2xx_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 = EP0_IDLE; - - /* basic endpoint records init */ - for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { - struct pxa2xx_ep *ep = &dev->ep[i]; - - if (i != 0) - list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); - - ep->desc = NULL; - ep->stopped = 0; - INIT_LIST_HEAD (&ep->queue); - ep->pio_irqs = 0; - } - - /* the rest was statically initialized, and is read-only */ -} - -/* until it's enabled, this UDC should be completely invisible - * to any USB host. - */ -static void udc_enable (struct pxa2xx_udc *dev) -{ - udc_clear_mask_UDCCR(UDCCR_UDE); - - /* try to clear these bits before we enable the udc */ - udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); - - ep0_idle(dev); - dev->gadget.speed = USB_SPEED_UNKNOWN; - dev->stats.irqs = 0; - - /* - * sequence taken from chapter 12.5.10, PXA250 AppProcDevManual: - * - enable UDC - * - if RESET is already in progress, ack interrupt - * - unmask reset interrupt - */ - udc_set_mask_UDCCR(UDCCR_UDE); - if (!(UDCCR & UDCCR_UDA)) - udc_ack_int_UDCCR(UDCCR_RSTIR); - - if (dev->has_cfr /* UDC_RES2 is defined */) { - /* pxa255 (a0+) can avoid a set_config race that could - * prevent gadget drivers from configuring correctly - */ - UDCCFR = UDCCFR_ACM | UDCCFR_MB1; - } else { - /* "USB test mode" for pxa250 errata 40-42 (stepping a0, a1) - * which could result in missing packets and interrupts. - * supposedly one bit per endpoint, controlling whether it - * double buffers or not; ACM/AREN bits fit into the holes. - * zero bits (like USIR0_IRx) disable double buffering. - */ - UDC_RES1 = 0x00; - UDC_RES2 = 0x00; - } - - /* enable suspend/resume and reset irqs */ - udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); - - /* enable ep0 irqs */ - UICR0 &= ~UICR0_IM0; - - /* if hardware supports it, pullup D+ and wait for reset */ - pullup_on(); -} - - -/* when a driver is successfully registered, it will receive - * control requests including set_configuration(), which enables - * non-control requests. then usb traffic follows until a - * disconnect is reported. then a host may connect again, or - * the driver might get unbound. - */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct pxa2xx_udc *dev = the_controller; - int retval; - - if (!driver - || driver->speed < USB_SPEED_FULL - || !driver->bind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - - /* first hook up the driver ... */ - dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; - dev->pullup = 1; - - retval = device_add (&dev->gadget.dev); - if (retval) { -fail: - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - retval = driver->bind(&dev->gadget); - if (retval) { - DMSG("bind to driver %s --> error %d\n", - driver->driver.name, retval); - device_del (&dev->gadget.dev); - goto fail; - } - - /* ... then enable host detection and ep0; and we're ready - * for set_configuration as well as eventual disconnect. - */ - DMSG("registered gadget driver '%s'\n", driver->driver.name); - pullup(dev); - dump_state(dev); - return 0; -} -EXPORT_SYMBOL(usb_gadget_register_driver); - -static void -stop_activity(struct pxa2xx_udc *dev, struct usb_gadget_driver *driver) -{ - int i; - - /* don't disconnect drivers more than once */ - if (dev->gadget.speed == USB_SPEED_UNKNOWN) - driver = NULL; - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* prevent new request submissions, kill any outstanding requests */ - for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { - struct pxa2xx_ep *ep = &dev->ep[i]; - - ep->stopped = 1; - nuke(ep, -ESHUTDOWN); - } - del_timer_sync(&dev->timer); - - /* report disconnect; the driver is already quiesced */ - if (driver) - driver->disconnect(&dev->gadget); - - /* re-init driver-visible data structures */ - udc_reinit(dev); -} - -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct pxa2xx_udc *dev = the_controller; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - - local_irq_disable(); - dev->pullup = 0; - pullup(dev); - stop_activity(dev, driver); - local_irq_enable(); - - driver->unbind(&dev->gadget); - dev->gadget.dev.driver = NULL; - dev->driver = NULL; - - device_del (&dev->gadget.dev); - - DMSG("unregistered gadget driver '%s'\n", driver->driver.name); - dump_state(dev); - return 0; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); - - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_ARCH_LUBBOCK - -/* Lubbock has separate connect and disconnect irqs. More typical designs - * use one GPIO as the VBUS IRQ, and another to control the D+ pullup. - */ - -static irqreturn_t -lubbock_vbus_irq(int irq, void *_dev) -{ - struct pxa2xx_udc *dev = _dev; - int vbus; - - dev->stats.irqs++; - switch (irq) { - case LUBBOCK_USB_IRQ: - vbus = 1; - disable_irq(LUBBOCK_USB_IRQ); - enable_irq(LUBBOCK_USB_DISC_IRQ); - break; - case LUBBOCK_USB_DISC_IRQ: - vbus = 0; - disable_irq(LUBBOCK_USB_DISC_IRQ); - enable_irq(LUBBOCK_USB_IRQ); - break; - default: - return IRQ_NONE; - } - - pxa2xx_udc_vbus_session(&dev->gadget, vbus); - return IRQ_HANDLED; -} - -#endif - -static irqreturn_t udc_vbus_irq(int irq, void *_dev) -{ - struct pxa2xx_udc *dev = _dev; - int vbus = gpio_get_value(dev->mach->gpio_vbus); - - if (dev->mach->gpio_vbus_inverted) - vbus = !vbus; - - pxa2xx_udc_vbus_session(&dev->gadget, vbus); - return IRQ_HANDLED; -} - - -/*-------------------------------------------------------------------------*/ - -static inline void clear_ep_state (struct pxa2xx_udc *dev) -{ - unsigned i; - - /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint - * fifos, and pending transactions mustn't be continued in any case. - */ - for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) - nuke(&dev->ep[i], -ECONNABORTED); -} - -static void udc_watchdog(unsigned long _dev) -{ - struct pxa2xx_udc *dev = (void *)_dev; - - local_irq_disable(); - if (dev->ep0state == EP0_STALL - && (UDCCS0 & UDCCS0_FST) == 0 - && (UDCCS0 & UDCCS0_SST) == 0) { - UDCCS0 = UDCCS0_FST|UDCCS0_FTF; - DBG(DBG_VERBOSE, "ep0 re-stall\n"); - start_watchdog(dev); - } - local_irq_enable(); -} - -static void handle_ep0 (struct pxa2xx_udc *dev) -{ - u32 udccs0 = UDCCS0; - struct pxa2xx_ep *ep = &dev->ep [0]; - struct pxa2xx_request *req; - union { - struct usb_ctrlrequest r; - u8 raw [8]; - u32 word [2]; - } u; - - if (list_empty(&ep->queue)) - req = NULL; - else - req = list_entry(ep->queue.next, struct pxa2xx_request, queue); - - /* clear stall status */ - if (udccs0 & UDCCS0_SST) { - nuke(ep, -EPIPE); - UDCCS0 = UDCCS0_SST; - del_timer(&dev->timer); - ep0_idle(dev); - } - - /* previous request unfinished? non-error iff back-to-back ... */ - if ((udccs0 & UDCCS0_SA) != 0 && dev->ep0state != EP0_IDLE) { - nuke(ep, 0); - del_timer(&dev->timer); - ep0_idle(dev); - } - - switch (dev->ep0state) { - case EP0_IDLE: - /* late-breaking status? */ - udccs0 = UDCCS0; - - /* start control request? */ - if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE)) - == (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE))) { - int i; - - nuke (ep, -EPROTO); - - /* read SETUP packet */ - for (i = 0; i < 8; i++) { - if (unlikely(!(UDCCS0 & UDCCS0_RNE))) { -bad_setup: - DMSG("SETUP %d!\n", i); - goto stall; - } - u.raw [i] = (u8) UDDR0; - } - if (unlikely((UDCCS0 & UDCCS0_RNE) != 0)) - goto bad_setup; - -got_setup: - DBG(DBG_VERBOSE, "SETUP %02x.%02x v%04x i%04x l%04x\n", - u.r.bRequestType, u.r.bRequest, - le16_to_cpu(u.r.wValue), - le16_to_cpu(u.r.wIndex), - le16_to_cpu(u.r.wLength)); - - /* cope with automagic for some standard requests. */ - dev->req_std = (u.r.bRequestType & USB_TYPE_MASK) - == USB_TYPE_STANDARD; - dev->req_config = 0; - dev->req_pending = 1; - switch (u.r.bRequest) { - /* hardware restricts gadget drivers here! */ - case USB_REQ_SET_CONFIGURATION: - if (u.r.bRequestType == USB_RECIP_DEVICE) { - /* reflect hardware's automagic - * up to the gadget driver. - */ -config_change: - dev->req_config = 1; - clear_ep_state(dev); - /* if !has_cfr, there's no synch - * else use AREN (later) not SA|OPR - * USIR0_IR0 acts edge sensitive - */ - } - break; - /* ... and here, even more ... */ - case USB_REQ_SET_INTERFACE: - if (u.r.bRequestType == USB_RECIP_INTERFACE) { - /* udc hardware is broken by design: - * - altsetting may only be zero; - * - hw resets all interfaces' eps; - * - ep reset doesn't include halt(?). - */ - DMSG("broken set_interface (%d/%d)\n", - le16_to_cpu(u.r.wIndex), - le16_to_cpu(u.r.wValue)); - goto config_change; - } - break; - /* hardware was supposed to hide this */ - case USB_REQ_SET_ADDRESS: - if (u.r.bRequestType == USB_RECIP_DEVICE) { - ep0start(dev, 0, "address"); - return; - } - break; - } - - if (u.r.bRequestType & USB_DIR_IN) - dev->ep0state = EP0_IN_DATA_PHASE; - else - dev->ep0state = EP0_OUT_DATA_PHASE; - - i = dev->driver->setup(&dev->gadget, &u.r); - if (i < 0) { - /* hardware automagic preventing STALL... */ - if (dev->req_config) { - /* hardware sometimes neglects to tell - * tell us about config change events, - * so later ones may fail... - */ - WARN("config change %02x fail %d?\n", - u.r.bRequest, i); - return; - /* TODO experiment: if has_cfr, - * hardware didn't ACK; maybe we - * could actually STALL! - */ - } - DBG(DBG_VERBOSE, "protocol STALL, " - "%02x err %d\n", UDCCS0, i); -stall: - /* the watchdog timer helps deal with cases - * where udc seems to clear FST wrongly, and - * then NAKs instead of STALLing. - */ - ep0start(dev, UDCCS0_FST|UDCCS0_FTF, "stall"); - start_watchdog(dev); - dev->ep0state = EP0_STALL; - - /* deferred i/o == no response yet */ - } else if (dev->req_pending) { - if (likely(dev->ep0state == EP0_IN_DATA_PHASE - || dev->req_std || u.r.wLength)) - ep0start(dev, 0, "defer"); - else - ep0start(dev, UDCCS0_IPR, "defer/IPR"); - } - - /* expect at least one data or status stage irq */ - return; - - } else if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA)) - == (UDCCS0_OPR|UDCCS0_SA))) { - unsigned i; - - /* pxa210/250 erratum 131 for B0/B1 says RNE lies. - * still observed on a pxa255 a0. - */ - DBG(DBG_VERBOSE, "e131\n"); - nuke(ep, -EPROTO); - - /* read SETUP data, but don't trust it too much */ - for (i = 0; i < 8; i++) - u.raw [i] = (u8) UDDR0; - if ((u.r.bRequestType & USB_RECIP_MASK) - > USB_RECIP_OTHER) - goto stall; - if (u.word [0] == 0 && u.word [1] == 0) - goto stall; - goto got_setup; - } else { - /* some random early IRQ: - * - we acked FST - * - IPR cleared - * - OPR got set, without SA (likely status stage) - */ - UDCCS0 = udccs0 & (UDCCS0_SA|UDCCS0_OPR); - } - break; - case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */ - if (udccs0 & UDCCS0_OPR) { - UDCCS0 = UDCCS0_OPR|UDCCS0_FTF; - DBG(DBG_VERBOSE, "ep0in premature status\n"); - if (req) - done(ep, req, 0); - ep0_idle(dev); - } else /* irq was IPR clearing */ { - if (req) { - /* this IN packet might finish the request */ - (void) write_ep0_fifo(ep, req); - } /* else IN token before response was written */ - } - break; - case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */ - if (udccs0 & UDCCS0_OPR) { - if (req) { - /* this OUT packet might finish the request */ - if (read_ep0_fifo(ep, req)) - done(ep, req, 0); - /* else more OUT packets expected */ - } /* else OUT token before read was issued */ - } else /* irq was IPR clearing */ { - DBG(DBG_VERBOSE, "ep0out premature status\n"); - if (req) - done(ep, req, 0); - ep0_idle(dev); - } - break; - case EP0_END_XFER: - if (req) - done(ep, req, 0); - /* ack control-IN status (maybe in-zlp was skipped) - * also appears after some config change events. - */ - if (udccs0 & UDCCS0_OPR) - UDCCS0 = UDCCS0_OPR; - ep0_idle(dev); - break; - case EP0_STALL: - UDCCS0 = UDCCS0_FST; - break; - } - USIR0 = USIR0_IR0; -} - -static void handle_ep(struct pxa2xx_ep *ep) -{ - struct pxa2xx_request *req; - int is_in = ep->bEndpointAddress & USB_DIR_IN; - int completed; - u32 udccs, tmp; - - do { - completed = 0; - if (likely (!list_empty(&ep->queue))) - req = list_entry(ep->queue.next, - struct pxa2xx_request, queue); - else - req = NULL; - - // TODO check FST handling - - udccs = *ep->reg_udccs; - if (unlikely(is_in)) { /* irq from TPC, SST, or (ISO) TUR */ - tmp = UDCCS_BI_TUR; - if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK)) - tmp |= UDCCS_BI_SST; - tmp &= udccs; - if (likely (tmp)) - *ep->reg_udccs = tmp; - if (req && likely ((udccs & UDCCS_BI_TFS) != 0)) - completed = write_fifo(ep, req); - - } else { /* irq from RPC (or for ISO, ROF) */ - if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK)) - tmp = UDCCS_BO_SST | UDCCS_BO_DME; - else - tmp = UDCCS_IO_ROF | UDCCS_IO_DME; - tmp &= udccs; - if (likely(tmp)) - *ep->reg_udccs = tmp; - - /* fifos can hold packets, ready for reading... */ - if (likely(req)) { - completed = read_fifo(ep, req); - } else - pio_irq_disable (ep->bEndpointAddress); - } - ep->pio_irqs++; - } while (completed); -} - -/* - * pxa2xx_udc_irq - interrupt handler - * - * avoid delays in ep0 processing. the control handshaking isn't always - * under software control (pxa250c0 and the pxa255 are better), and delays - * could cause usb protocol errors. - */ -static irqreturn_t -pxa2xx_udc_irq(int irq, void *_dev) -{ - struct pxa2xx_udc *dev = _dev; - int handled; - - dev->stats.irqs++; - do { - u32 udccr = UDCCR; - - handled = 0; - - /* SUSpend Interrupt Request */ - if (unlikely(udccr & UDCCR_SUSIR)) { - udc_ack_int_UDCCR(UDCCR_SUSIR); - handled = 1; - DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() - ? "" : "+disconnect"); - - if (!is_vbus_present()) - stop_activity(dev, dev->driver); - else if (dev->gadget.speed != USB_SPEED_UNKNOWN - && dev->driver - && dev->driver->suspend) - dev->driver->suspend(&dev->gadget); - ep0_idle (dev); - } - - /* RESume Interrupt Request */ - if (unlikely(udccr & UDCCR_RESIR)) { - udc_ack_int_UDCCR(UDCCR_RESIR); - handled = 1; - DBG(DBG_VERBOSE, "USB resume\n"); - - if (dev->gadget.speed != USB_SPEED_UNKNOWN - && dev->driver - && dev->driver->resume - && is_vbus_present()) - dev->driver->resume(&dev->gadget); - } - - /* ReSeT Interrupt Request - USB reset */ - if (unlikely(udccr & UDCCR_RSTIR)) { - udc_ack_int_UDCCR(UDCCR_RSTIR); - handled = 1; - - if ((UDCCR & UDCCR_UDA) == 0) { - DBG(DBG_VERBOSE, "USB reset start\n"); - - /* reset driver and endpoints, - * in case that's not yet done - */ - stop_activity (dev, dev->driver); - - } else { - DBG(DBG_VERBOSE, "USB reset end\n"); - dev->gadget.speed = USB_SPEED_FULL; - memset(&dev->stats, 0, sizeof dev->stats); - /* driver and endpoints are still reset */ - } - - } else { - u32 usir0 = USIR0 & ~UICR0; - u32 usir1 = USIR1 & ~UICR1; - int i; - - if (unlikely (!usir0 && !usir1)) - continue; - - DBG(DBG_VERY_NOISY, "irq %02x.%02x\n", usir1, usir0); - - /* control traffic */ - if (usir0 & USIR0_IR0) { - dev->ep[0].pio_irqs++; - handle_ep0(dev); - handled = 1; - } - - /* endpoint data transfers */ - for (i = 0; i < 8; i++) { - u32 tmp = 1 << i; - - if (i && (usir0 & tmp)) { - handle_ep(&dev->ep[i]); - USIR0 |= tmp; - handled = 1; - } - if (usir1 & tmp) { - handle_ep(&dev->ep[i+8]); - USIR1 |= tmp; - handled = 1; - } - } - } - - /* we could also ask for 1 msec SOF (SIR) interrupts */ - - } while (handled); - return IRQ_HANDLED; -} - -/*-------------------------------------------------------------------------*/ - -static void nop_release (struct device *dev) -{ - DMSG("%s %s\n", __func__, dev->bus_id); -} - -/* this uses load-time allocation and initialization (instead of - * doing it at run-time) to save code, eliminate fault paths, and - * be more obviously correct. - */ -static struct pxa2xx_udc memory = { - .gadget = { - .ops = &pxa2xx_udc_ops, - .ep0 = &memory.ep[0].ep, - .name = driver_name, - .dev = { - .bus_id = "gadget", - .release = nop_release, - }, - }, - - /* control endpoint */ - .ep[0] = { - .ep = { - .name = ep0name, - .ops = &pxa2xx_ep_ops, - .maxpacket = EP0_FIFO_SIZE, - }, - .dev = &memory, - .reg_udccs = &UDCCS0, - .reg_uddr = &UDDR0, - }, - - /* first group of endpoints */ - .ep[1] = { - .ep = { - .name = "ep1in-bulk", - .ops = &pxa2xx_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 1, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .reg_udccs = &UDCCS1, - .reg_uddr = &UDDR1, - }, - .ep[2] = { - .ep = { - .name = "ep2out-bulk", - .ops = &pxa2xx_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = 2, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .reg_udccs = &UDCCS2, - .reg_ubcr = &UBCR2, - .reg_uddr = &UDDR2, - }, -#ifndef CONFIG_USB_PXA2XX_SMALL - .ep[3] = { - .ep = { - .name = "ep3in-iso", - .ops = &pxa2xx_ep_ops, - .maxpacket = ISO_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = ISO_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 3, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .reg_udccs = &UDCCS3, - .reg_uddr = &UDDR3, - }, - .ep[4] = { - .ep = { - .name = "ep4out-iso", - .ops = &pxa2xx_ep_ops, - .maxpacket = ISO_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = ISO_FIFO_SIZE, - .bEndpointAddress = 4, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .reg_udccs = &UDCCS4, - .reg_ubcr = &UBCR4, - .reg_uddr = &UDDR4, - }, - .ep[5] = { - .ep = { - .name = "ep5in-int", - .ops = &pxa2xx_ep_ops, - .maxpacket = INT_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = INT_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 5, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .reg_udccs = &UDCCS5, - .reg_uddr = &UDDR5, - }, - - /* second group of endpoints */ - .ep[6] = { - .ep = { - .name = "ep6in-bulk", - .ops = &pxa2xx_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 6, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .reg_udccs = &UDCCS6, - .reg_uddr = &UDDR6, - }, - .ep[7] = { - .ep = { - .name = "ep7out-bulk", - .ops = &pxa2xx_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = 7, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .reg_udccs = &UDCCS7, - .reg_ubcr = &UBCR7, - .reg_uddr = &UDDR7, - }, - .ep[8] = { - .ep = { - .name = "ep8in-iso", - .ops = &pxa2xx_ep_ops, - .maxpacket = ISO_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = ISO_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 8, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .reg_udccs = &UDCCS8, - .reg_uddr = &UDDR8, - }, - .ep[9] = { - .ep = { - .name = "ep9out-iso", - .ops = &pxa2xx_ep_ops, - .maxpacket = ISO_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = ISO_FIFO_SIZE, - .bEndpointAddress = 9, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .reg_udccs = &UDCCS9, - .reg_ubcr = &UBCR9, - .reg_uddr = &UDDR9, - }, - .ep[10] = { - .ep = { - .name = "ep10in-int", - .ops = &pxa2xx_ep_ops, - .maxpacket = INT_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = INT_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 10, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .reg_udccs = &UDCCS10, - .reg_uddr = &UDDR10, - }, - - /* third group of endpoints */ - .ep[11] = { - .ep = { - .name = "ep11in-bulk", - .ops = &pxa2xx_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 11, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .reg_udccs = &UDCCS11, - .reg_uddr = &UDDR11, - }, - .ep[12] = { - .ep = { - .name = "ep12out-bulk", - .ops = &pxa2xx_ep_ops, - .maxpacket = BULK_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = BULK_FIFO_SIZE, - .bEndpointAddress = 12, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .reg_udccs = &UDCCS12, - .reg_ubcr = &UBCR12, - .reg_uddr = &UDDR12, - }, - .ep[13] = { - .ep = { - .name = "ep13in-iso", - .ops = &pxa2xx_ep_ops, - .maxpacket = ISO_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = ISO_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 13, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .reg_udccs = &UDCCS13, - .reg_uddr = &UDDR13, - }, - .ep[14] = { - .ep = { - .name = "ep14out-iso", - .ops = &pxa2xx_ep_ops, - .maxpacket = ISO_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = ISO_FIFO_SIZE, - .bEndpointAddress = 14, - .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .reg_udccs = &UDCCS14, - .reg_ubcr = &UBCR14, - .reg_uddr = &UDDR14, - }, - .ep[15] = { - .ep = { - .name = "ep15in-int", - .ops = &pxa2xx_ep_ops, - .maxpacket = INT_FIFO_SIZE, - }, - .dev = &memory, - .fifo_size = INT_FIFO_SIZE, - .bEndpointAddress = USB_DIR_IN | 15, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .reg_udccs = &UDCCS15, - .reg_uddr = &UDDR15, - }, -#endif /* !CONFIG_USB_PXA2XX_SMALL */ -}; - -#define CP15R0_VENDOR_MASK 0xffffe000 - -#if defined(CONFIG_ARCH_PXA) -#define CP15R0_XSCALE_VALUE 0x69052000 /* intel/arm/xscale */ - -#elif defined(CONFIG_ARCH_IXP4XX) -#define CP15R0_XSCALE_VALUE 0x69054000 /* intel/arm/ixp4xx */ - -#endif - -#define CP15R0_PROD_MASK 0x000003f0 -#define PXA25x 0x00000100 /* and PXA26x */ -#define PXA210 0x00000120 - -#define CP15R0_REV_MASK 0x0000000f - -#define CP15R0_PRODREV_MASK (CP15R0_PROD_MASK | CP15R0_REV_MASK) - -#define PXA255_A0 0x00000106 /* or PXA260_B1 */ -#define PXA250_C0 0x00000105 /* or PXA26x_B0 */ -#define PXA250_B2 0x00000104 -#define PXA250_B1 0x00000103 /* or PXA260_A0 */ -#define PXA250_B0 0x00000102 -#define PXA250_A1 0x00000101 -#define PXA250_A0 0x00000100 - -#define PXA210_C0 0x00000125 -#define PXA210_B2 0x00000124 -#define PXA210_B1 0x00000123 -#define PXA210_B0 0x00000122 -#define IXP425_A0 0x000001c1 -#define IXP425_B0 0x000001f1 -#define IXP465_AD 0x00000200 - -/* - * probe - binds to the platform device - */ -static int __init pxa2xx_udc_probe(struct platform_device *pdev) -{ - struct pxa2xx_udc *dev = &memory; - int retval, vbus_irq, irq; - u32 chiprev; - - /* insist on Intel/ARM/XScale */ - asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev)); - if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) { - pr_err("%s: not XScale!\n", driver_name); - return -ENODEV; - } - - /* trigger chiprev-specific logic */ - switch (chiprev & CP15R0_PRODREV_MASK) { -#if defined(CONFIG_ARCH_PXA) - case PXA255_A0: - dev->has_cfr = 1; - break; - case PXA250_A0: - case PXA250_A1: - /* A0/A1 "not released"; ep 13, 15 unusable */ - /* fall through */ - case PXA250_B2: case PXA210_B2: - case PXA250_B1: case PXA210_B1: - case PXA250_B0: case PXA210_B0: - /* OUT-DMA is broken ... */ - /* fall through */ - case PXA250_C0: case PXA210_C0: - break; -#elif defined(CONFIG_ARCH_IXP4XX) - case IXP425_A0: - case IXP425_B0: - case IXP465_AD: - dev->has_cfr = 1; - break; -#endif - default: - pr_err("%s: unrecognized processor: %08x\n", - driver_name, chiprev); - /* iop3xx, ixp4xx, ... */ - return -ENODEV; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENODEV; - - dev->clk = clk_get(&pdev->dev, "UDCCLK"); - if (IS_ERR(dev->clk)) { - retval = PTR_ERR(dev->clk); - goto err_clk; - } - - pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, - dev->has_cfr ? "" : " (!cfr)", - SIZE_STR "(pio)" - ); - - /* other non-static parts of init */ - dev->dev = &pdev->dev; - dev->mach = pdev->dev.platform_data; - - if (dev->mach->gpio_vbus) { - if ((retval = gpio_request(dev->mach->gpio_vbus, - "pxa2xx_udc GPIO VBUS"))) { - dev_dbg(&pdev->dev, - "can't get vbus gpio %d, err: %d\n", - dev->mach->gpio_vbus, retval); - goto err_gpio_vbus; - } - gpio_direction_input(dev->mach->gpio_vbus); - vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); - } else - vbus_irq = 0; - - if (dev->mach->gpio_pullup) { - if ((retval = gpio_request(dev->mach->gpio_pullup, - "pca2xx_udc GPIO PULLUP"))) { - dev_dbg(&pdev->dev, - "can't get pullup gpio %d, err: %d\n", - dev->mach->gpio_pullup, retval); - goto err_gpio_pullup; - } - gpio_direction_output(dev->mach->gpio_pullup, 0); - } - - init_timer(&dev->timer); - dev->timer.function = udc_watchdog; - dev->timer.data = (unsigned long) dev; - - device_initialize(&dev->gadget.dev); - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - - the_controller = dev; - platform_set_drvdata(pdev, dev); - - udc_disable(dev); - udc_reinit(dev); - - dev->vbus = is_vbus_present(); - - /* irq setup after old hardware state is cleaned up */ - retval = request_irq(irq, pxa2xx_udc_irq, - IRQF_DISABLED, driver_name, dev); - if (retval != 0) { - pr_err("%s: can't get irq %d, err %d\n", - driver_name, irq, retval); - goto err_irq1; - } - dev->got_irq = 1; - -#ifdef CONFIG_ARCH_LUBBOCK - if (machine_is_lubbock()) { - retval = request_irq(LUBBOCK_USB_DISC_IRQ, - lubbock_vbus_irq, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - driver_name, dev); - if (retval != 0) { - pr_err("%s: can't get irq %i, err %d\n", - driver_name, LUBBOCK_USB_DISC_IRQ, retval); -lubbock_fail0: - goto err_irq_lub; - } - retval = request_irq(LUBBOCK_USB_IRQ, - lubbock_vbus_irq, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM, - driver_name, dev); - if (retval != 0) { - pr_err("%s: can't get irq %i, err %d\n", - driver_name, LUBBOCK_USB_IRQ, retval); - free_irq(LUBBOCK_USB_DISC_IRQ, dev); - goto lubbock_fail0; - } - } else -#endif - if (vbus_irq) { - retval = request_irq(vbus_irq, udc_vbus_irq, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM | - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - driver_name, dev); - if (retval != 0) { - pr_err("%s: can't get irq %i, err %d\n", - driver_name, vbus_irq, retval); - goto err_vbus_irq; - } - } - create_debug_files(dev); - - return 0; - - err_vbus_irq: -#ifdef CONFIG_ARCH_LUBBOCK - free_irq(LUBBOCK_USB_DISC_IRQ, dev); - err_irq_lub: -#endif - free_irq(irq, dev); - err_irq1: - if (dev->mach->gpio_pullup) - gpio_free(dev->mach->gpio_pullup); - err_gpio_pullup: - if (dev->mach->gpio_vbus) - gpio_free(dev->mach->gpio_vbus); - err_gpio_vbus: - clk_put(dev->clk); - err_clk: - return retval; -} - -static void pxa2xx_udc_shutdown(struct platform_device *_dev) -{ - pullup_off(); -} - -static int __exit pxa2xx_udc_remove(struct platform_device *pdev) -{ - struct pxa2xx_udc *dev = platform_get_drvdata(pdev); - - if (dev->driver) - return -EBUSY; - - dev->pullup = 0; - pullup(dev); - - remove_debug_files(dev); - - if (dev->got_irq) { - free_irq(platform_get_irq(pdev, 0), dev); - dev->got_irq = 0; - } -#ifdef CONFIG_ARCH_LUBBOCK - if (machine_is_lubbock()) { - free_irq(LUBBOCK_USB_DISC_IRQ, dev); - free_irq(LUBBOCK_USB_IRQ, dev); - } -#endif - if (dev->mach->gpio_vbus) { - free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); - gpio_free(dev->mach->gpio_vbus); - } - if (dev->mach->gpio_pullup) - gpio_free(dev->mach->gpio_pullup); - - clk_put(dev->clk); - - platform_set_drvdata(pdev, NULL); - the_controller = NULL; - return 0; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_PM - -/* USB suspend (controlled by the host) and system suspend (controlled - * by the PXA) don't necessarily work well together. If USB is active, - * the 48 MHz clock is required; so the system can't enter 33 MHz idle - * mode, or any deeper PM saving state. - * - * For now, we punt and forcibly disconnect from the USB host when PXA - * enters any suspend state. While we're disconnected, we always disable - * the 48MHz USB clock ... allowing PXA sleep and/or 33 MHz idle states. - * Boards without software pullup control shouldn't use those states. - * VBUS IRQs should probably be ignored so that the PXA device just acts - * "dead" to USB hosts until system resume. - */ -static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) -{ - struct pxa2xx_udc *udc = platform_get_drvdata(dev); - unsigned long flags; - - if (!udc->mach->gpio_pullup && !udc->mach->udc_command) - WARN("USB host won't detect disconnect!\n"); - udc->suspended = 1; - - local_irq_save(flags); - pullup(udc); - local_irq_restore(flags); - - return 0; -} - -static int pxa2xx_udc_resume(struct platform_device *dev) -{ - struct pxa2xx_udc *udc = platform_get_drvdata(dev); - unsigned long flags; - - udc->suspended = 0; - local_irq_save(flags); - pullup(udc); - local_irq_restore(flags); - - return 0; -} - -#else -#define pxa2xx_udc_suspend NULL -#define pxa2xx_udc_resume NULL -#endif - -/*-------------------------------------------------------------------------*/ - -static struct platform_driver udc_driver = { - .shutdown = pxa2xx_udc_shutdown, - .remove = __exit_p(pxa2xx_udc_remove), - .suspend = pxa2xx_udc_suspend, - .resume = pxa2xx_udc_resume, - .driver = { - .owner = THIS_MODULE, - .name = "pxa2xx-udc", - }, -}; - -static int __init udc_init(void) -{ - pr_info("%s: version %s\n", driver_name, DRIVER_VERSION); - return platform_driver_probe(&udc_driver, pxa2xx_udc_probe); -} -module_init(udc_init); - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:pxa2xx-udc"); diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h deleted file mode 100644 index e2c19e8..0000000 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * linux/drivers/usb/gadget/pxa2xx_udc.h - * Intel PXA2xx on-chip full speed USB device controller - * - * Copyright (C) 2003 Robert Schwebel , Pengutronix - * Copyright (C) 2003 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. - * - * 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 __LINUX_USB_GADGET_PXA2XX_H -#define __LINUX_USB_GADGET_PXA2XX_H - -#include - -/*-------------------------------------------------------------------------*/ - -/* pxa2xx has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */ -#define UFNRH_SIR (1 << 7) /* SOF interrupt request */ -#define UFNRH_SIM (1 << 6) /* SOF interrupt mask */ -#define UFNRH_IPE14 (1 << 5) /* ISO packet error, ep14 */ -#define UFNRH_IPE9 (1 << 4) /* ISO packet error, ep9 */ -#define UFNRH_IPE4 (1 << 3) /* ISO packet error, ep4 */ - -/* pxa255 has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */ -#define UDCCFR UDC_RES2 /* UDC Control Function Register */ -#define UDCCFR_AREN (1 << 7) /* ACK response enable (now) */ -#define UDCCFR_ACM (1 << 2) /* ACK control mode (wait for AREN) */ - -/* latest pxa255 errata define new "must be one" bits in UDCCFR */ -#define UDCCFR_MB1 (0xff & ~(UDCCFR_AREN|UDCCFR_ACM)) - -/*-------------------------------------------------------------------------*/ - -struct pxa2xx_udc; - -struct pxa2xx_ep { - struct usb_ep ep; - struct pxa2xx_udc *dev; - - const struct usb_endpoint_descriptor *desc; - struct list_head queue; - unsigned long pio_irqs; - - unsigned short fifo_size; - u8 bEndpointAddress; - u8 bmAttributes; - - unsigned stopped : 1; - unsigned dma_fixup : 1; - - /* UDCCS = UDC Control/Status for this EP - * UBCR = UDC Byte Count Remaining (contents of OUT fifo) - * UDDR = UDC Endpoint Data Register (the fifo) - * DRCM = DMA Request Channel Map - */ - volatile u32 *reg_udccs; - volatile u32 *reg_ubcr; - volatile u32 *reg_uddr; -}; - -struct pxa2xx_request { - struct usb_request req; - struct list_head queue; -}; - -enum ep0_state { - EP0_IDLE, - EP0_IN_DATA_PHASE, - EP0_OUT_DATA_PHASE, - EP0_END_XFER, - EP0_STALL, -}; - -#define EP0_FIFO_SIZE ((unsigned)16) -#define BULK_FIFO_SIZE ((unsigned)64) -#define ISO_FIFO_SIZE ((unsigned)256) -#define INT_FIFO_SIZE ((unsigned)8) - -struct udc_stats { - struct ep0stats { - unsigned long ops; - unsigned long bytes; - } read, write; - unsigned long irqs; -}; - -#ifdef CONFIG_USB_PXA2XX_SMALL -/* when memory's tight, SMALL config saves code+data. */ -#define PXA_UDC_NUM_ENDPOINTS 3 -#endif - -#ifndef PXA_UDC_NUM_ENDPOINTS -#define PXA_UDC_NUM_ENDPOINTS 16 -#endif - -struct pxa2xx_udc { - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - - enum ep0_state ep0state; - struct udc_stats stats; - unsigned got_irq : 1, - vbus : 1, - pullup : 1, - has_cfr : 1, - req_pending : 1, - req_std : 1, - req_config : 1, - suspended : 1, - active : 1; - -#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) - struct timer_list timer; - - struct device *dev; - struct clk *clk; - struct pxa2xx_udc_mach_info *mach; - u64 dma_mask; - struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; - -#ifdef CONFIG_USB_GADGET_DEBUG_FS - struct dentry *debugfs_udc; -#endif -}; - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_ARCH_LUBBOCK -#include -/* lubbock can also report usb connect/disconnect irqs */ -#endif - -static struct pxa2xx_udc *the_controller; - -/*-------------------------------------------------------------------------*/ - -/* - * Debugging support vanishes in non-debug builds. DBG_NORMAL should be - * mostly silent during normal use/testing, with no timing side-effects. - */ -#define DBG_NORMAL 1 /* error paths, device state transitions */ -#define DBG_VERBOSE 2 /* add some success path trace info */ -#define DBG_NOISY 3 /* ... even more: request level */ -#define DBG_VERY_NOISY 4 /* ... even more: packet level */ - -#define DMSG(stuff...) pr_debug("udc: " stuff) - -#ifdef DEBUG - -static int is_vbus_present(void); - -static const char *state_name[] = { - "EP0_IDLE", - "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", - "EP0_END_XFER", "EP0_STALL" -}; - -#ifdef VERBOSE_DEBUG -# define UDC_DEBUG DBG_VERBOSE -#else -# define UDC_DEBUG DBG_NORMAL -#endif - -static void __maybe_unused -dump_udccr(const char *label) -{ - u32 udccr = UDCCR; - DMSG("%s %02X =%s%s%s%s%s%s%s%s\n", - label, udccr, - (udccr & UDCCR_REM) ? " rem" : "", - (udccr & UDCCR_RSTIR) ? " rstir" : "", - (udccr & UDCCR_SRM) ? " srm" : "", - (udccr & UDCCR_SUSIR) ? " susir" : "", - (udccr & UDCCR_RESIR) ? " resir" : "", - (udccr & UDCCR_RSM) ? " rsm" : "", - (udccr & UDCCR_UDA) ? " uda" : "", - (udccr & UDCCR_UDE) ? " ude" : ""); -} - -static void __maybe_unused -dump_udccs0(const char *label) -{ - u32 udccs0 = UDCCS0; - - DMSG("%s %s %02X =%s%s%s%s%s%s%s%s\n", - label, state_name[the_controller->ep0state], udccs0, - (udccs0 & UDCCS0_SA) ? " sa" : "", - (udccs0 & UDCCS0_RNE) ? " rne" : "", - (udccs0 & UDCCS0_FST) ? " fst" : "", - (udccs0 & UDCCS0_SST) ? " sst" : "", - (udccs0 & UDCCS0_DRWF) ? " dwrf" : "", - (udccs0 & UDCCS0_FTF) ? " ftf" : "", - (udccs0 & UDCCS0_IPR) ? " ipr" : "", - (udccs0 & UDCCS0_OPR) ? " opr" : ""); -} - -static void __maybe_unused -dump_state(struct pxa2xx_udc *dev) -{ - u32 tmp; - unsigned i; - - DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", - is_vbus_present() ? "host " : "disconnected", - state_name[dev->ep0state], - UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); - dump_udccr("udccr"); - if (dev->has_cfr) { - tmp = UDCCFR; - DMSG("udccfr %02X =%s%s\n", tmp, - (tmp & UDCCFR_AREN) ? " aren" : "", - (tmp & UDCCFR_ACM) ? " acm" : ""); - } - - if (!dev->driver) { - DMSG("no gadget driver bound\n"); - return; - } else - DMSG("ep0 driver '%s'\n", dev->driver->driver.name); - - if (!is_vbus_present()) - return; - - dump_udccs0 ("udccs0"); - DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n", - dev->stats.write.bytes, dev->stats.write.ops, - dev->stats.read.bytes, dev->stats.read.ops); - - for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { - if (dev->ep [i].desc == NULL) - continue; - DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); - } -} - -#else - -#define dump_udccr(x) do{}while(0) -#define dump_udccs0(x) do{}while(0) -#define dump_state(x) do{}while(0) - -#define UDC_DEBUG ((unsigned)0) - -#endif - -#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0) - -#define ERR(stuff...) pr_err("udc: " stuff) -#define WARN(stuff...) pr_warning("udc: " stuff) -#define INFO(stuff...) pr_info("udc: " stuff) - - -#endif /* __LINUX_USB_GADGET_PXA2XX_H */ -- cgit v0.10.2 From 9f19d6382854d6b2d58cc364253779479e14facc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 10 Jun 2008 12:30:05 +0100 Subject: [ARM] 5085/2: PXA: Move AC97 over to the new central device declaration model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As well as moving all the device declarations to a single one in devices.c this causes all platforms to register the I/O and interrupt resources for the AC97 controller. Cc: eric miao Cc: Mike Rapoport Cc: Lennert Buytenhek Cc: Jürgen Schindele Cc: Juergen Beisert Signed-off-by: Mark Brown Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 6d4416a..b3c3fd7 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -81,12 +82,6 @@ static struct platform_device cmx270_device_dm9k = { } }; -/* audio device */ -static struct platform_device cmx270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - /* touchscreen controller */ static struct platform_device cmx270_ts_device = { .name = "ucb1400_ts", @@ -219,7 +214,6 @@ static struct platform_device cmx270_ata = { /* platform devices */ static struct platform_device *platform_devices[] __initdata = { &cmx270_device_dm9k, - &cmx270_audio_device, &cmx270_rtc_device, &cmx270_2700G, &cmx270_led_device, @@ -594,6 +588,7 @@ static void __init cmx270_init(void) /* register CM-X270 platform devices */ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); /* set MCI and OHCI platform parameters */ pxa_set_mci_info(&cmx270_mci_platform_data); diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 123ee19..a6f2390 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "devices.h" #include "generic.h" @@ -298,6 +299,37 @@ struct platform_device pxa_device_rtc = { .id = -1, }; +static struct resource pxa_ac97_resources[] = { + [0] = { + .start = 0x40500000, + .end = 0x40500000 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa_ac97_dmamask = 0xffffffffUL; + +struct platform_device pxa_device_ac97 = { + .name = "pxa2xx-ac97", + .id = -1, + .dev = { + .dma_mask = &pxa_ac97_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa_ac97_resources), + .resource = pxa_ac97_resources, +}; + +void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops) +{ + pxa_register_device(&pxa_device_ac97, ops); +} + #ifdef CONFIG_PXA25x static struct resource pxa25x_resource_pwm0[] = { diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 881d1a7..b852eb1 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -12,6 +12,7 @@ extern struct platform_device pxa_device_i2c; extern struct platform_device pxa_device_i2s; extern struct platform_device pxa_device_ficp; extern struct platform_device pxa_device_rtc; +extern struct platform_device pxa_device_ac97; extern struct platform_device pxa27x_device_i2c_power; extern struct platform_device pxa27x_device_ohci; diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 1269ac9..e23865a 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -73,12 +74,6 @@ static struct platform_device em_x270_dm9k = { } }; -/* audio device */ -static struct platform_device em_x270_audio = { - .name = "pxa2xx-ac97", - .id = -1, -}; - /* WM9712 touchscreen controller. Hopefully the driver will make it to * the mainstream sometime */ static struct platform_device em_x270_ts = { @@ -218,7 +213,6 @@ static struct platform_device em_x270_nand = { /* platform devices */ static struct platform_device *platform_devices[] __initdata = { &em_x270_dm9k, - &em_x270_audio, &em_x270_ts, &em_x270_rtc, &em_x270_nand, @@ -326,6 +320,7 @@ static void __init em_x270_init(void) /* register EM-X270 platform devices */ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); /* set MCI and OHCI platform parameters */ pxa_set_mci_info(&em_x270_mci_platform_data); diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 183b587..cc1c4fa 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -168,11 +168,6 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -static struct platform_device lpd270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct resource lpd270_flash_resources[] = { [0] = { .start = PXA_CS0_PHYS, @@ -412,7 +407,6 @@ __setup("lcd=", lpd270_set_lcd); static struct platform_device *platform_devices[] __initdata = { &smc91x_device, &lpd270_backlight_device, - &lpd270_audio_device, &lpd270_flash_device[0], &lpd270_flash_device[1], }; @@ -456,6 +450,8 @@ static void __init lpd270_init(void) platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); + if (lpd270_lcd_to_use != NULL) set_pxa_fb_info(lpd270_lcd_to_use); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 7b9bdd0..a3fae41 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -196,11 +197,6 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { // no D+ pullup; lubbock can't connect/disconnect in software }; -static struct platform_device lub_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct resource sa1111_resources[] = { [0] = { .start = 0x10000000, @@ -368,7 +364,6 @@ static struct platform_device lubbock_flash_device[2] = { static struct platform_device *devices[] __initdata = { &sa1111_device, - &lub_audio_device, &smc91x_device, &lubbock_flash_device[0], &lubbock_flash_device[1], @@ -494,6 +489,7 @@ static void __init lubbock_init(void) set_pxa_fb_info(&sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data); + pxa_set_ac97_info(NULL); lubbock_flash_data[0].width = lubbock_flash_data[1].width = (BOOT_DEF & 1) ? 2 : 4; diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 2665944..f2e9e7c 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -280,12 +280,6 @@ static pxa2xx_audio_ops_t mst_audio_ops = { .resume = mst_audio_resume, }; -static struct platform_device mst_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, - .dev = { .platform_data = &mst_audio_ops }, -}; - static struct resource flash_resources[] = { [0] = { .start = PXA_CS0_PHYS, @@ -499,7 +493,6 @@ static struct platform_device mst_gpio_keys_device = { static struct platform_device *platform_devices[] __initdata = { &smc91x_device, - &mst_audio_device, &mst_flash_device[0], &mst_flash_device[1], &mst_gpio_keys_device, @@ -609,6 +602,7 @@ static void __init mainstone_init(void) pxa_set_ficp_info(&mainstone_ficp_platform_data); pxa_set_ohci_info(&mainstone_ohci_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(&mst_audio_ops); mainstone_init_keypad(); } diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 2564e16..5d87c7c 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -424,36 +425,6 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = { #endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ /* - * AC97 support - * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ - */ -static struct resource pxa27x_ac97_resources[] = { - [0] = { - .start = 0x40500000, - .end = 0x40500000 + 0xfff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_AC97, - .end = IRQ_AC97, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 pxa_ac97_dmamask = 0xffffffffUL; - -static struct platform_device pxa27x_device_ac97 = { - .name = "pxa2xx-ac97", - .id = -1, - .dev = { - .dma_mask = &pxa_ac97_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(pxa27x_ac97_resources), - .resource = pxa27x_ac97_resources, -}; - -/* * enable generic access to the base board control CPLDs U6 and U7 */ static struct map_desc pcm990_io_desc[] __initdata = { @@ -490,8 +461,6 @@ void __init pcm990_baseboard_init(void) pxa_gpio_mode(GPIO16_PWM0_MD); platform_device_register(&pcm990_backlight_device); - platform_device_register(&pxa27x_device_ac97); - /* MMC */ pxa_set_mci_info(&pcm990_mci_platform_data); @@ -499,6 +468,7 @@ void __init pcm990_baseboard_init(void) pxa_set_ohci_info(&pcm990_ohci_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(NULL); #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) pxa_set_camera_info(&pcm990_pxacamera_platform_data); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index bc7c465..61e2440 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -176,19 +176,10 @@ static struct platform_device uart_devices = { .resource = NULL, }; -/******************************************************************************************** - * PXA270 ac97 sound codec - ********************************************************************************************/ -static struct platform_device ac97_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct platform_device * trizeps4_devices[] __initdata = { &flash_device, &uart_devices, &dm9000_device, - &ac97_audio_device, }; #ifdef CONFIG_MACH_TRIZEPS4_CONXS @@ -439,6 +430,7 @@ static void __init trizeps4_init(void) pxa_set_mci_info(&trizeps4_mci_platform_data); pxa_set_ficp_info(&trizeps4_ficp_platform_data); pxa_set_ohci_info(&trizeps4_ohci_platform_data); + pxa_set_ac97_info(NULL); } static void __init trizeps4_map_io(void) diff --git a/include/asm-arm/arch-pxa/audio.h b/include/asm-arm/arch-pxa/audio.h index 52bbe3b..f82f96d 100644 --- a/include/asm-arm/arch-pxa/audio.h +++ b/include/asm-arm/arch-pxa/audio.h @@ -12,4 +12,6 @@ typedef struct { void *priv; } pxa2xx_audio_ops_t; +extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); + #endif -- cgit v0.10.2 From cabb352a6455c3550f157909196845f533b0f374 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 10 Jun 2008 10:48:25 +0100 Subject: [ARM] 5084/1: zylonite: Register AC97 device The Zylonite has an AC97 subsystem on it so register the AC97 controller device. Signed-off-by: Mark Brown Acked-by: Eric Miao Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index b13bb93..66b446c 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -337,6 +338,7 @@ static void __init zylonite_init(void) smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); platform_device_register(&smc91x_device); + pxa_set_ac97_info(NULL); zylonite_init_lcd(); zylonite_init_mmc(); zylonite_init_keypad(); -- cgit v0.10.2 From 16074b669ea97e2bef494ec7cceb475566f763e3 Mon Sep 17 00:00:00 2001 From: Patrice Vilchez Date: Wed, 9 Jul 2008 22:16:00 +0100 Subject: [ARM] at91: Fix NAND FLASH timings for at91sam9x evaluation kits. New timings are based on application note "NAND Flash Support on AT91SAM9 Microcontrollers" available at http://atmel.com/dyn/resources/prod_documents/doc6255.pdf). Signed-off-by: Patrice Vilchez Acked-by: Andrew Victor Signed-off-by: Andrew Morton Signed-off-by: Russell King diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 393a32a..26f5cac 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -321,8 +321,8 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) - | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 0babb64..ec18913 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -232,19 +232,19 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) - | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); - at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) - | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) + | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); - at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); if (data->bus_width_16) mode = AT91_SMC_DBW_16; else mode = AT91_SMC_DBW_8; - at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); /* enable pin */ if (data->enable_pin) diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 719667e..8a81f76 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -391,8 +391,8 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) - | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 8507dd0..ae28101 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -233,15 +233,15 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) - | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); - at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) - | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) + | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); - at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); - at91_sys_write(AT91_SMC_MODE(3), AT91_SMC_DBW_8 | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); + at91_sys_write(AT91_SMC_MODE(3), AT91_SMC_DBW_8 | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); /* enable pin */ if (data->enable_pin) -- cgit v0.10.2 From 63f385cd1f649b3f4f2d59fc609e051981215fd7 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Tue, 8 Jul 2008 23:07:48 +0100 Subject: [ARM] 5160/1: IOP3XX: gpio/gpiolib support This patch brings support for gpio/gpiolib framework to Intel IOP3xx platforms. Signed-off-by: Arnaud Patard Acked-by: Dan Williams Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68..63ef7cf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -299,6 +299,8 @@ config ARCH_IOP32X depends on MMU select PLAT_IOP select PCI + select GENERIC_GPIO + select HAVE_GPIO_LIB help Support for Intel's 80219 and IOP32X (XScale) family of processors. @@ -308,6 +310,8 @@ config ARCH_IOP33X depends on MMU select PLAT_IOP select PCI + select GENERIC_GPIO + select HAVE_GPIO_LIB help Support for Intel's IOP33X (XScale) family of processors. diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c index eda4360..640e498 100644 --- a/arch/arm/plat-iop/gpio.c +++ b/arch/arm/plat-iop/gpio.c @@ -11,6 +11,10 @@ */ #include +#include +#include +#include +#include #include void gpio_line_config(int line, int direction) @@ -46,3 +50,42 @@ void gpio_line_set(int line, int value) local_irq_restore(flags); } EXPORT_SYMBOL(gpio_line_set); + +static int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + gpio_line_config(gpio, GPIO_IN); + return 0; +} + +static int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, GPIO_OUT); + return 0; +} + +static int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + return gpio_line_get(gpio); +} + +static void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + gpio_line_set(gpio, value); +} + +static struct gpio_chip iop3xx_chip = { + .label = "iop3xx", + .direction_input = iop3xx_gpio_direction_input, + .get = iop3xx_gpio_get_value, + .direction_output = iop3xx_gpio_direction_output, + .set = iop3xx_gpio_set_value, + .base = 0, + .ngpio = IOP3XX_N_GPIOS, +}; + +static int __init iop3xx_gpio_setup(void) +{ + return gpiochip_add(&iop3xx_chip); +} +arch_initcall(iop3xx_gpio_setup); diff --git a/include/asm-arm/arch-iop32x/gpio.h b/include/asm-arm/arch-iop32x/gpio.h new file mode 100644 index 0000000..708f4ec --- /dev/null +++ b/include/asm-arm/arch-iop32x/gpio.h @@ -0,0 +1,6 @@ +#ifndef __ASM_ARCH_IOP32X_GPIO_H +#define __ASM_ARCH_IOP32X_GPIO_H + +#include + +#endif diff --git a/include/asm-arm/arch-iop33x/gpio.h b/include/asm-arm/arch-iop33x/gpio.h new file mode 100644 index 0000000..ddd55bb --- /dev/null +++ b/include/asm-arm/arch-iop33x/gpio.h @@ -0,0 +1,6 @@ +#ifndef __ASM_ARCH_IOP33X_GPIO_H +#define __ASM_ARCH_IOP33X_GPIO_H + +#include + +#endif diff --git a/include/asm-arm/hardware/iop3xx-gpio.h b/include/asm-arm/hardware/iop3xx-gpio.h new file mode 100644 index 0000000..0c9331f --- /dev/null +++ b/include/asm-arm/hardware/iop3xx-gpio.h @@ -0,0 +1,73 @@ +/* + * linux/include/asm-arm/hardware/iop3xx-gpio.h + * + * IOP3xx GPIO wrappers + * + * Copyright (c) 2008 Arnaud Patard + * Based on IXP4XX gpio.h file + * + * 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_ARM_HARDWARE_IOP3XX_GPIO_H +#define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H + +#include +#include + +#define IOP3XX_N_GPIOS 8 + +static inline int gpio_get_value(unsigned gpio) +{ + if (gpio > IOP3XX_N_GPIOS) + return __gpio_get_value(gpio); + + return gpio_line_get(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (gpio > IOP3XX_N_GPIOS) { + __gpio_set_value(gpio, value); + return; + } + gpio_line_set(gpio, value); +} + +static inline int gpio_cansleep(unsigned gpio) +{ + if (gpio < IOP3XX_N_GPIOS) + return 0; + else + return __gpio_cansleep(gpio); +} + +/* + * The GPIOs are not generating any interrupt + * Note : manuals are not clear about this + */ +static inline int gpio_to_irq(int gpio) +{ + return -EINVAL; +} + +static inline int irq_to_gpio(int gpio) +{ + return -EINVAL; +} + +#endif + -- cgit v0.10.2 From 48627d8d23c34106c1365563604739a50343edaf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Jul 2008 07:01:13 +0200 Subject: genirq: remove extraneous checks in manage.c In http://bugzilla.kernel.org/show_bug.cgi?id=9580 it was pointed out that the desc->chip checks are extraneous. In fact these are left overs from early development and can be removed safely. Signed-off-by: Thomas Gleixner diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 469814e..77a51be 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -377,7 +377,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) /* Setup the type (level, edge polarity) if configured: */ if (new->flags & IRQF_TRIGGER_MASK) { - if (desc->chip && desc->chip->set_type) + if (desc->chip->set_type) desc->chip->set_type(irq, new->flags & IRQF_TRIGGER_MASK); else @@ -387,8 +387,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) */ printk(KERN_WARNING "No IRQF_TRIGGER set_type " "function for IRQ %d (%s)\n", irq, - desc->chip ? desc->chip->name : - "unknown"); + desc->chip->name); } else compat_irq_chip_set_default_handler(desc); -- cgit v0.10.2 From 6b148507d3d042a3c11f4c3f6c0f649c6a89220d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 21 May 2008 21:14:58 +0200 Subject: pmtmr: allow command line override of ioport Stupid BIOSes do not tell us about the PMTimer, but we might know where it is. Signed-off-by: Thomas Gleixner diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 7b46faf..3baee02 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -215,3 +215,22 @@ pm_good: * but we still need to load before device_initcall */ fs_initcall(init_acpi_pm_clocksource); + +/* + * Allow an override of the IOPort. Stupid BIOSes do not tell us about + * the PMTimer, but we might know where it is. + */ +static int __init parse_pmtmr(char *arg) +{ + unsigned long base; + + if (strict_strtoul(arg, 16, &base)) + return -EINVAL; + + printk(KERN_INFO "PMTMR IOPort override: 0x%04lx -> 0x%04lx\n", + pmtmr_ioport, base); + pmtmr_ioport = base; + + return 1; +} +__setup("pmtmr=", parse_pmtmr); -- cgit v0.10.2 From 4fb3dc2729c22ed1b023475fe28b720460251de1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 9 Jul 2008 13:07:23 +0200 Subject: x86: build fix for "x86: fix C1E && nx6325 stability problem" fix: arch/x86/kernel/built-in.o: In function `dmi_ignore_irq0_timer_override': boot.c:(.init.text+0x3ea4): undefined reference to `force_mask_ioapic_irq_2' Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h index 8d4c8bd..33a73f5 100644 --- a/include/asm-x86/genapic_32.h +++ b/include/asm-x86/genapic_32.h @@ -119,6 +119,10 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; #define is_uv_system() 0 #define uv_wakeup_secondary(a, b) 1 +#ifdef CONFIG_X86_IO_APIC extern void force_mask_ioapic_irq_2(void); +#else +static inline void force_mask_ioapic_irq_2(void) { } +#endif #endif diff --git a/include/asm-x86/genapic_64.h b/include/asm-x86/genapic_64.h index 082ad02..647e4e5 100644 --- a/include/asm-x86/genapic_64.h +++ b/include/asm-x86/genapic_64.h @@ -46,6 +46,10 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); extern void setup_apic_routing(void); +#ifdef CONFIG_X86_IO_APIC extern void force_mask_ioapic_irq_2(void); +#else +static inline void force_mask_ioapic_irq_2(void) { } +#endif #endif -- cgit v0.10.2 From 7b16eb8930d1e2a7ce5c7f35c87d62252ecc91f2 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 9 Jul 2008 20:15:02 -0700 Subject: x86: overmapped fix when 4K pages on tail, 64-bit fix phys_pmd_init to make sure not to return bigger value than end. also print out range split:1G/2M/4K in init_memory_mapping(). Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 51f69b3..48548ef 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -302,11 +302,13 @@ static __meminit void unmap_low_page(void *adr) early_iounmap(adr, PAGE_SIZE); } -static void __meminit +static unsigned long __meminit phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end) { unsigned pages = 0; + unsigned long last_map_addr = end; int i; + pte_t *pte = pte_page + pte_index(addr); for(i = pte_index(addr); i < PTRS_PER_PTE; i++, addr += PAGE_SIZE, pte++) { @@ -326,17 +328,20 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end) printk(" pte=%p addr=%lx pte=%016lx\n", pte, addr, pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL).pte); set_pte(pte, pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL)); + last_map_addr = (addr & PAGE_MASK) + PAGE_SIZE; pages++; } update_page_count(PG_LEVEL_4K, pages); + + return last_map_addr; } -static void __meminit +static unsigned long __meminit phys_pte_update(pmd_t *pmd, unsigned long address, unsigned long end) { pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd); - phys_pte_init(pte, address, end); + return phys_pte_init(pte, address, end); } static unsigned long __meminit @@ -344,6 +349,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, unsigned long page_size_mask) { unsigned long pages = 0; + unsigned long last_map_addr = end; int i = pmd_index(address); @@ -362,7 +368,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, if (pmd_val(*pmd)) { if (!pmd_large(*pmd)) - phys_pte_update(pmd, address, end); + last_map_addr = phys_pte_update(pmd, address, + end); continue; } @@ -370,17 +377,18 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, pages++; set_pte((pte_t *)pmd, pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); + last_map_addr = (address & PMD_MASK) + PMD_SIZE; continue; } pte = alloc_low_page(&pte_phys); - phys_pte_init(pte, address, end); + last_map_addr = phys_pte_init(pte, address, end); unmap_low_page(pte); pmd_populate_kernel(&init_mm, pmd, __va(pte_phys)); } update_page_count(PG_LEVEL_2M, pages); - return address; + return last_map_addr; } static unsigned long __meminit @@ -659,6 +667,32 @@ static unsigned long __init kernel_physical_mapping_init(unsigned long start, return last_map_addr; } + +struct map_range { + unsigned long start; + unsigned long end; + unsigned page_size_mask; +}; + +#define NR_RANGE_MR 5 + +static int save_mr(struct map_range *mr, int nr_range, + unsigned long start_pfn, unsigned long end_pfn, + unsigned long page_size_mask) +{ + + if (start_pfn < end_pfn) { + if (nr_range >= NR_RANGE_MR) + panic("run out of range for init_memory_mapping\n"); + mr[nr_range].start = start_pfn<> PAGE_SHIFT; end_pfn = ((start + (PMD_SIZE - 1)) >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); - if (start_pfn < end_pfn) - last_map_addr = kernel_physical_mapping_init( - start_pfn<>PMD_SHIFT) @@ -706,37 +741,40 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, << (PUD_SHIFT - PAGE_SHIFT); if (end_pfn > ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT))) end_pfn = ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT)); - if (start_pfn < end_pfn) - last_map_addr = kernel_physical_mapping_init( - start_pfn<>PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); - if (start_pfn < end_pfn) - last_map_addr = kernel_physical_mapping_init( - start_pfn<>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); - if (start_pfn < end_pfn) - last_map_addr = kernel_physical_mapping_init( - start_pfn<>PAGE_SHIFT; - if (start_pfn < end_pfn) + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); + + for (i = 0; i < nr_range; i++) + printk(KERN_DEBUG " %010lx - %010lx page %s\n", + mr[i].start, mr[i].end, + (mr[i].page_size_mask & (1< Date: Wed, 9 Jul 2008 20:16:36 -0700 Subject: x86, acpi: merge __acpi_map_table and let 64-bit to fall back to use fixmap too. Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index bf7b4f7..a31a579 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -109,21 +109,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; */ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; -#ifdef CONFIG_X86_64 - -/* rely on all ACPI tables being in the direct mapping */ -char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size) -{ - if (!phys_addr || !size) - return NULL; - - if (phys_addr+size <= (max_pfn_mapped << PAGE_SHIFT) + PAGE_SIZE) - return __va(phys_addr); - - return NULL; -} - -#else /* * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, @@ -142,11 +127,15 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) unsigned long base, offset, mapped_size; int idx; - if (phys + size < 8 * 1024 * 1024) + if (!phys || !size) + return NULL; + + if (phys+size <= (max_pfn_mapped << PAGE_SHIFT)) return __va(phys); offset = phys & (PAGE_SIZE - 1); mapped_size = PAGE_SIZE - offset; + clear_fixmap(FIX_ACPI_END); set_fixmap(FIX_ACPI_END, phys); base = fix_to_virt(FIX_ACPI_END); @@ -158,13 +147,13 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) if (--idx < FIX_ACPI_BEGIN) return NULL; /* cannot handle this */ phys += PAGE_SIZE; + clear_fixmap(idx); set_fixmap(idx, phys); mapped_size += PAGE_SIZE; } return ((unsigned char *)base + offset); } -#endif #ifdef CONFIG_PCI_MMCONFIG /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index 1a0b61e..6a4789d 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h @@ -12,6 +12,7 @@ #define _ASM_FIXMAP_64_H #include +#include #include #include #include @@ -49,6 +50,10 @@ enum fixed_addresses { #ifdef CONFIG_PARAVIRT FIX_PARAVIRT_BOOTMAP, #endif +#ifdef CONFIG_ACPI + FIX_ACPI_BEGIN, + FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, +#endif #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT FIX_OHCI1394_BASE, #endif -- cgit v0.10.2 From 3d43ecd286e442792f2e899e6e06eb23ab3d99f6 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 9 Jul 2008 20:17:50 -0700 Subject: x86: make e820_end return end_of_ram again for 64bit even on 64bit systems with less than 4G RAM, we can now use fixmap to handle acpi SIT near end of ram. change e820_end to e820_end_of_ram again? or e820_ram_pfn? Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 66fd5bd..9836a07 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1066,10 +1066,8 @@ unsigned long __init e820_end(void) struct e820entry *ei = &e820.map[i]; unsigned long end_pfn; -#ifdef CONFIG_X86_32 if (ei->type != E820_RAM) continue; -#endif end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; if (end_pfn > last_pfn) -- cgit v0.10.2 From 942fd1ebf6072fdaa07ae6d77a4f58b39c1bfdf9 Mon Sep 17 00:00:00 2001 From: Walter Sheets Date: Fri, 27 Jun 2008 11:53:31 +0200 Subject: ALSA: via82xx - Add VIA audio device #1841 to ac97_quirk list Signed-off-by: Walter Sheets Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index b585cc3..6781be9 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1757,6 +1757,12 @@ static struct ac97_quirk ac97_quirks[] = { .type = AC97_TUNE_HP_ONLY }, { + .subvendor = 0x1019, + .subdevice = 0x1841, + .name = "ECS K7VTA3", + .type = AC97_TUNE_HP_ONLY + }, + { .subvendor = 0x1849, .subdevice = 0x3059, .name = "ASRock K7VM2", -- cgit v0.10.2 From 6cabf6b0694951288520512e0b68c78523acc9fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jun 2008 11:55:20 +0200 Subject: ALSA: Fix AC97 power down Some laptops don't like PR3 powerdown. Do PR3 powerdown only for the real power-saving. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 2d2f16e..07364c0 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2295,9 +2295,11 @@ static void snd_ac97_powerdown(struct snd_ac97 *ac97) power |= AC97_PD_PR0 | AC97_PD_PR1; /* ADC & DAC powerdown */ snd_ac97_write(ac97, AC97_POWERDOWN, power); udelay(100); - power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */ + power |= AC97_PD_PR2; /* Analog Mixer powerdown (Vref on) */ snd_ac97_write(ac97, AC97_POWERDOWN, power); if (ac97_is_power_save_mode(ac97)) { + power |= AC97_PD_PR3; /* Analog Mixer powerdown */ + snd_ac97_write(ac97, AC97_POWERDOWN, power); udelay(100); /* AC-link powerdown, internal Clk disable */ /* FIXME: this may cause click noises on some boards */ -- cgit v0.10.2 From 4d20f70a787e03530786152ea27a6ed157205cdc Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 27 Jun 2008 14:07:57 +0300 Subject: ALSA: ASoC: TLV320AIC3X: Add mixer control for ADC highpass filter Signed-off-by: Jarkko Nikula Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 4f0bf26..d138306 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -223,6 +223,8 @@ static const char *aic3x_right_hpcom_mux[] = { "differential of HPROUT", "constant VCM", "single-ended", "differential of HPLCOM", "external feedback" }; static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" }; +static const char *aic3x_adc_hpf[] = + { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" }; #define LDAC_ENUM 0 #define RDAC_ENUM 1 @@ -232,6 +234,7 @@ static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" }; #define LINE1R_ENUM 5 #define LINE2L_ENUM 6 #define LINE2R_ENUM 7 +#define ADC_HPF_ENUM 8 static const struct soc_enum aic3x_enum[] = { SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux), @@ -242,6 +245,7 @@ static const struct soc_enum aic3x_enum[] = { SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), + SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), }; static const struct snd_kcontrol_new aic3x_snd_controls[] = { @@ -292,6 +296,8 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { /* Input */ SOC_DOUBLE_R("PGA Capture Volume", LADC_VOL, RADC_VOL, 0, 0x7f, 0), SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), + + SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), }; /* add non dapm controls */ diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index c1dd1ac..e600946 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -37,6 +37,8 @@ #define AIC3X_ASD_INTF_CTRLB 9 /* Audio overflow status and PLL R value programming register */ #define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 +/* Audio codec digital filter control register */ +#define AIC3X_CODEC_DFILT_CTRL 12 /* ADC PGA Gain control registers */ #define LADC_VOL 15 -- cgit v0.10.2 From 0701e0640f4a1de2b509cfee508216275f81d812 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jun 2008 16:30:57 +0200 Subject: ALSA: ALSA: hda - Fix ALC883 medion model ALC883 medion model doesn't unmute the proper amps so no output can be heard. Replaced the mute switches to behave just like other models. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7d4bbb..081d1a5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7050,13 +7050,13 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { static struct snd_kcontrol_new alc883_fivestack_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), -- cgit v0.10.2 From 470eaf6be78424fc499a5039e5d5fe58bace2bc3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jun 2008 16:40:10 +0200 Subject: ALSA: hda - Add missing Thinkpad Z60m support Added the missing SSID of Thinkpad Z60m for model=thinkpad with AD1981HD. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 05ca027..e8003d9 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1616,6 +1616,7 @@ static const char *ad1981_models[AD1981_MODELS] = { static struct snd_pci_quirk ad1981_cfg_tbl[] = { SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), + SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), /* All HP models */ SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), -- cgit v0.10.2 From 6a9dccd61253f361760802d8d19c28fa83ea83f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Jul 2008 14:52:05 +0200 Subject: ALSA: ALSA: hda - Fix speaker output on Toshiba P105 Toshiba Satellite P105 with cx5045 has no HP pin but only a speaker pin and does the speaker-muting on hardware. Thus the matching model is laptop-micsense. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 64df810..95e3367 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -906,6 +906,7 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE), SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE), + SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), -- cgit v0.10.2 From 25552e87aa4102f048f1a8a8ddc87c96593c304e Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 2 Jul 2008 13:19:23 +0300 Subject: ALSA: ac97 - fix patch_ucb1400 for proper resume Replace 'snd_ac97_write' with snd_ac97_write_cache' in pacth_ucb1400 to allow proper codec wakeup. Signed-off-by: Mike Rapoport Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index abe88ad..0746e9c 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3710,7 +3710,7 @@ static int patch_ucb1400(struct snd_ac97 * ac97) { ac97->build_ops = &patch_ucb1400_ops; /* enable headphone driver and smart low power mode by default */ - snd_ac97_write(ac97, 0x6a, 0x0050); - snd_ac97_write(ac97, 0x6c, 0x0030); + snd_ac97_write_cache(ac97, 0x6a, 0x0050); + snd_ac97_write_cache(ac97, 0x6c, 0x0030); return 0; } -- cgit v0.10.2 From 5415552d21150dbfbff012de2b59e685ea232b1e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Jul 2008 11:51:19 +0100 Subject: ALSA: ASoC: Advertise 16000Hz rate for WM9713 PCM interface Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 0db9637..a480618 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1001,9 +1001,18 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream) return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); } -#define WM9713_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ - SNDRV_PCM_RATE_48000) +#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \ + SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000) + +#define WM9713_PCM_RATES (SNDRV_PCM_RATE_8000 | \ + SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000) #define WM9713_PCM_FORMATS \ (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ @@ -1051,13 +1060,13 @@ struct snd_soc_codec_dai wm9713_dai[] = { .stream_name = "Voice Playback", .channels_min = 1, .channels_max = 1, - .rates = WM9713_RATES, + .rates = WM9713_PCM_RATES, .formats = WM9713_PCM_FORMATS,}, .capture = { .stream_name = "Voice Capture", .channels_min = 1, .channels_max = 2, - .rates = WM9713_RATES, + .rates = WM9713_PCM_RATES, .formats = WM9713_PCM_FORMATS,}, .ops = { .hw_params = wm9713_pcm_hw_params, -- cgit v0.10.2 From 15e4c72f520d1db9adc38ba157547a7c1fca45b2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Jul 2008 11:51:20 +0100 Subject: ALSA: ASoC: Make pop/click debug wait times dynamically configurable DAPM supports adding a compile time configurable delay to the widget power sequences, aiding diagnosis of problems with pops and clicks being generated during them. This patch converts this to be configurable at run time via a sysfs file. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 2536382..7c2dd4e 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -54,16 +54,6 @@ #define dbg(format, arg...) #endif -#define POP_DEBUG 0 -#if POP_DEBUG -#define POP_TIME 500 /* 500 msecs - change if pop debug is too fast */ -#define pop_wait(time) schedule_timeout_uninterruptible(msecs_to_jiffies(time)) -#define pop_dbg(format, arg...) printk(format, ## arg); pop_wait(POP_TIME) -#else -#define pop_dbg(format, arg...) -#define pop_wait(time) -#endif - /* dapm power sequences - make this per codec in the future */ static int dapm_up_seq[] = { snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, @@ -80,6 +70,28 @@ static int dapm_status = 1; module_param(dapm_status, int, 0); MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); +static unsigned int pop_time; + +static void pop_wait(void) +{ + if (pop_time) + schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); +} + +static void pop_dbg(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + + if (pop_time) { + vprintk(fmt, args); + pop_wait(); + } + + va_end(args); +} + /* create a new dapm widget */ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( const struct snd_soc_dapm_widget *_widget) @@ -217,9 +229,9 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) change = old != new; if (change) { pop_dbg("pop test %s : %s in %d ms\n", widget->name, - widget->power ? "on" : "off", POP_TIME); + widget->power ? "on" : "off", pop_time); snd_soc_write(codec, widget->reg, new); - pop_wait(POP_TIME); + pop_wait(); } dbg("reg %x old %x new %x change %d\n", widget->reg, old, new, change); return change; @@ -803,20 +815,47 @@ static ssize_t dapm_widget_show(struct device *dev, static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); +/* pop/click delay times */ +static ssize_t dapm_pop_time_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", pop_time); +} + +static ssize_t dapm_pop_time_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) + +{ + if (strict_strtoul(buf, 10, &pop_time) < 0) + printk(KERN_ERR "Unable to parse pop_time setting\n"); + + return count; +} + +static DEVICE_ATTR(dapm_pop_time, 0744, dapm_pop_time_show, + dapm_pop_time_store); + int snd_soc_dapm_sys_add(struct device *dev) { int ret = 0; - if (dapm_status) + if (dapm_status) { ret = device_create_file(dev, &dev_attr_dapm_widget); + if (ret == 0) + ret = device_create_file(dev, &dev_attr_dapm_pop_time); + } + return ret; } static void snd_soc_dapm_sys_remove(struct device *dev) { - if (dapm_status) + if (dapm_status) { + device_remove_file(dev, &dev_attr_dapm_pop_time); device_remove_file(dev, &dev_attr_dapm_widget); + } } /* free all dapm widgets and resources */ -- cgit v0.10.2 From 3f775987030cf7ff922765c18ddd0d311b4b46ef Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 3 Jul 2008 09:33:10 +0200 Subject: ALSA: ASoC: AC97 codec PM Simple suspend/resume for AC97 ASoC codec. Signed-off-by: Manuel Lauss Acked-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 300d007..e4516f3 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -144,9 +144,34 @@ static int ac97_soc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_ac97_suspend(socdev->codec->ac97); + + return 0; +} + +static int ac97_soc_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_ac97_resume(socdev->codec->ac97); + + return 0; +} +#else +#define ac97_soc_suspend NULL +#define ac97_soc_resume NULL +#endif + struct snd_soc_codec_device soc_codec_dev_ac97 = { .probe = ac97_soc_probe, .remove = ac97_soc_remove, + .suspend = ac97_soc_suspend, + .resume = ac97_soc_resume, }; EXPORT_SYMBOL_GPL(soc_codec_dev_ac97); -- cgit v0.10.2 From 73ead4855d98e330f2840523e1648575b9f2aae9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Jul 2008 16:01:14 +0100 Subject: ALSA: ASoC: Fix warning from strict_strtoul() Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7c2dd4e..91cbbef 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -827,7 +827,11 @@ static ssize_t dapm_pop_time_store(struct device *dev, const char *buf, size_t count) { - if (strict_strtoul(buf, 10, &pop_time) < 0) + unsigned long val; + + if (strict_strtoul(buf, 10, &val) >= 0) + pop_time = val; + else printk(KERN_ERR "Unable to parse pop_time setting\n"); return count; -- cgit v0.10.2 From be321a890c25272965129ffe4b3b59a519fcf583 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 7 Jul 2008 16:04:04 +0200 Subject: ALSA: hda - Add support for Lenovo 3000 N200 Added the model entry (model=lenovo) for Lenovo N3000 N200 laptop with ALC861-VD. Reference below: https://bugzilla.novell.com/show_bug.cgi?id=406425 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 081d1a5..92a709b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -13004,6 +13004,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), {} }; -- cgit v0.10.2 From a5302181e5321664047f75715242aac4e0bbd17c Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 13:35:17 +0100 Subject: ALSA: asoc: core - refactored DAPM pin control API. Refactored snd_soc_dapm_set_endpoint() to snd_soc_dapm_enable_pin() and snd_soc_dapm_disable_pin(). Renamed snd_soc_dapm_sync_endpoints() to snd_soc_dapm_sync(). Renamed snd_soc_dapm_get_endpoint_status() to snd_soc_dapm_get_pin_status(). Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index b284953..3030fdc 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -234,16 +234,11 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); -/* event handler for register modifier widget - used by the soc-dapm */ -int dapm_reg_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event); - -/* 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_status(struct snd_soc_codec *codec, - char *pin); -int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec); +/* 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_get_pin_status(struct snd_soc_codec *codec, char *pin); +int snd_soc_dapm_sync(struct snd_soc_codec *codec); /* dapm widget types */ enum snd_soc_dapm_type { diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index 4a383a4..ad971e7 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -216,14 +216,14 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec) snd_soc_dapm_add_route(codec, intercon, ARRAY_SIZE(intercon)); /* not connected */ - snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); + snd_soc_dapm_disable_pin(codec, "RLINEIN"); + snd_soc_dapm_disable_pin(codec, "LLINEIN"); /* always connected */ - snd_soc_dapm_set_endpoint(codec, "Int Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); + snd_soc_dapm_enable_pin(codec, "Int Mic"); + snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index d138306..954d39b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -29,7 +29,7 @@ * --------------------------------------- * * Hence the machine layer should disable unsupported inputs/outputs by - * snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0), etc. + * snd_soc_dapm_disable_pin(codec, "MONO_LOUT"), etc. */ #include @@ -206,7 +206,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, } if (found) - snd_soc_dapm_sync_endpoints(widget->codec); + snd_soc_dapm_sync(widget->codec); } ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 4c70a0e..091eae3 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -103,17 +103,17 @@ static int evm_aic3x_init(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); /* not connected */ - snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0); - snd_soc_dapm_set_endpoint(codec, "HPLCOM", 0); - snd_soc_dapm_set_endpoint(codec, "HPRCOM", 0); + snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); + snd_soc_dapm_disable_pin(codec, "HPLCOM"); + snd_soc_dapm_disable_pin(codec, "HPRCOM"); /* always connected */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); - snd_soc_dapm_set_endpoint(codec, "Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); - snd_soc_dapm_set_endpoint(codec, "Line In", 1); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Line Out"); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 767b39f..74f4599 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -50,11 +50,22 @@ static int n810_dmic_func; static void n810_ext_control(struct snd_soc_codec *codec) { - snd_soc_dapm_set_endpoint(codec, "Ext Spk", n810_spk_func); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", n810_jack_func); - snd_soc_dapm_set_endpoint(codec, "DMic", n810_dmic_func); + if (n810_spk_func) + snd_soc_dapm_enable_pin(codec, "Ext Spk"); + else + snd_soc_dapm_disable_pin(codec, "Ext Spk"); + + if (n810_jack_func) + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + else + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + + if (n810_dmic_func) + snd_soc_dapm_enable_pin(codec, "DMic"); + else + snd_soc_dapm_disable_pin(codec, "DMic); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); } static int n810_startup(struct snd_pcm_substream *substream) @@ -236,9 +247,9 @@ static int n810_aic33_init(struct snd_soc_codec *codec) int i, err; /* Not connected */ - snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0); - snd_soc_dapm_set_endpoint(codec, "HPLCOM", 0); - snd_soc_dapm_set_endpoint(codec, "HPRCOM", 0); + snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); + snd_soc_dapm_disable_pin(codec, "HPLCOM"); + snd_soc_dapm_disable_pin(codec, "HPRCOM"); /* Add N810 specific controls */ for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { @@ -255,7 +266,7 @@ static int n810_aic33_init(struct snd_soc_codec *codec) /* Set up N810 specific audio path audio_map */ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index edeea63..db18ef6 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -50,47 +50,51 @@ static int corgi_spk_func; static void corgi_ext_control(struct snd_soc_codec *codec) { - int spk = 0, mic = 0, line = 0, hp = 0, hs = 0; - /* set up jack connection */ switch (corgi_jack_func) { case CORGI_HP: - hp = 1; /* set = unmute headphone */ set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + snd_soc_dapm_disable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case CORGI_MIC: - mic = 1; /* reset = mute headphone */ reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case CORGI_LINE: - line = 1; reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + snd_soc_dapm_disable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case CORGI_HEADSET: - hs = 1; - mic = 1; reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Headset Jack"); break; } if (corgi_spk_func == CORGI_SPK_ON) - spk = 1; - - /* set the enpoints to their new connetion states */ - snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", mic); - snd_soc_dapm_set_endpoint(codec, "Line Jack", line); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs); + snd_soc_dapm_enable_pin(codec, "Ext Spk"); + else + snd_soc_dapm_disable_pin(codec, "Ext Spk"); /* signal a DAPM event */ - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); } static int corgi_startup(struct snd_pcm_substream *substream) @@ -285,8 +289,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec) { int i, err; - snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); + snd_soc_dapm_disable_pin(codec, "LLINEIN"); + snd_soc_dapm_disable_pin(codec, "RLINEIN"); /* Add corgi specific controls */ for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { @@ -303,7 +307,7 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec) /* Set up corgi specific audio path audio_map */ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 810f1fe..36cbf69 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -48,8 +48,6 @@ static int poodle_spk_func; static void poodle_ext_control(struct snd_soc_codec *codec) { - int spk = 0; - /* set up jack connection */ if (poodle_jack_func == POODLE_HP) { /* set = unmute headphone */ @@ -57,23 +55,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec) POODLE_LOCOMO_GPIO_MUTE_L, 1); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 1); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); } else { locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_L, 0); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 0); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); } - if (poodle_spk_func == POODLE_SPK_ON) - spk = 1; - /* set the enpoints to their new connetion states */ - snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk); + if (poodle_spk_func == POODLE_SPK_ON) + snd_soc_dapm_enable_pin(codec, "Ext Spk"); + else + snd_soc_dapm_disable_pin(codec, "Ext Spk"); /* signal a DAPM event */ - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); } static int poodle_startup(struct snd_pcm_substream *substream) @@ -248,9 +246,9 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec) { int i, err; - snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "MICIN", 1); + snd_soc_dapm_disable_pin(codec, "LLINEIN"); + snd_soc_dapm_disable_pin(codec, "RLINEIN"); + snd_soc_dapm_enable_pin(codec, "MICIN"); /* Add poodle specific controls */ for (i = 0; i < ARRAY_SIZE(wm8731_poodle_controls); i++) { @@ -267,7 +265,7 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec) /* Set up poodle specific audio path audio_map */ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 092b5c7..ec18163 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -51,60 +51,60 @@ static int spitz_spk_func; static void spitz_ext_control(struct snd_soc_codec *codec) { if (spitz_spk_func == SPITZ_SPK_ON) - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); + snd_soc_dapm_enable_pin(codec, "Ext Spk"); else - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 0); + snd_soc_dapm_disable_pin(codec, "Ext Spk"); /* set up jack connection */ switch (spitz_jack_func) { case SPITZ_HP: /* enable and unmute hp jack, disable mic bias */ - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); break; case SPITZ_MIC: /* enable mic jack and bias, mute hp */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); break; case SPITZ_LINE: /* enable line jack, disable mic bias and mute hp */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 1); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(codec, "Line Jack"); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); break; case SPITZ_HEADSET: /* enable and unmute headset jack enable mic bias, mute L hp */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 1); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_enable_pin(codec, "Headset Jack"); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); break; case SPITZ_HP_OFF: /* jack removed, everything off */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); break; } - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); } static int spitz_startup(struct snd_pcm_substream *substream) @@ -291,13 +291,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) int i, err; /* NC codec pins */ - snd_soc_dapm_set_endpoint(codec, "RINPUT1", 0); - snd_soc_dapm_set_endpoint(codec, "LINPUT2", 0); - snd_soc_dapm_set_endpoint(codec, "RINPUT2", 0); - snd_soc_dapm_set_endpoint(codec, "LINPUT3", 0); - snd_soc_dapm_set_endpoint(codec, "RINPUT3", 0); - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "MONO", 0); + snd_soc_dapm_disable_pin(codec, "RINPUT1"); + 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 spitz specific controls */ for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { @@ -314,7 +314,7 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) /* Set up spitz specific audio paths */ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 465ff0f..dba7689 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -52,29 +52,31 @@ static int tosa_spk_func; static void tosa_ext_control(struct snd_soc_codec *codec) { - int spk = 0, mic_int = 0, hp = 0, hs = 0; - /* set up jack connection */ switch (tosa_jack_func) { case TOSA_HP: - hp = 1; + snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case TOSA_MIC_INT: - mic_int = 1; + snd_soc_dapm_enable_pin(codec, "Mic (Internal)"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case TOSA_HEADSET: - hs = 1; + snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Headset Jack"); break; } if (tosa_spk_func == TOSA_SPK_ON) - spk = 1; + snd_soc_dapm_enable_pin(codec, "Speaker"); + else + snd_soc_dapm_disable_pin(codec, "Speaker"); - snd_soc_dapm_set_endpoint(codec, "Speaker", spk); - snd_soc_dapm_set_endpoint(codec, "Mic (Internal)", mic_int); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); } static int tosa_startup(struct snd_pcm_substream *substream) @@ -191,8 +193,8 @@ static int tosa_ac97_init(struct snd_soc_codec *codec) { int i, err; - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "MONOOUT", 0); + snd_soc_dapm_disable_pin(codec, "OUT3"); + snd_soc_dapm_disable_pin(codec, "MONOOUT"); /* add tosa specific controls */ for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { @@ -209,7 +211,7 @@ static int tosa_ac97_init(struct snd_soc_codec *codec) /* set up tosa specific audio path audio_map */ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 3485123..f053e85 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -250,77 +250,77 @@ static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) switch (neo1973_scenario) { case NEO_AUDIO_OFF: - snd_soc_dapm_set_endpoint(codec, "Audio 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, "Call Mic", 0); + snd_soc_dapm_disable_pin(codec, "Audio 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, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_HANDSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); + snd_soc_dapm_enable_pin(codec, "Audio Out"); + snd_soc_dapm_enable_pin(codec, "GSM Line Out"); + snd_soc_dapm_enable_pin(codec, "GSM Line In"); + snd_soc_dapm_disable_pin(codec, "Headset Mic"); + snd_soc_dapm_enable_pin(codec, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_HEADSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); + snd_soc_dapm_enable_pin(codec, "Audio Out"); + snd_soc_dapm_enable_pin(codec, "GSM Line Out"); + snd_soc_dapm_enable_pin(codec, "GSM Line In"); + snd_soc_dapm_enable_pin(codec, "Headset Mic"); + snd_soc_dapm_disable_pin(codec, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_BLUETOOTH: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); + snd_soc_dapm_disable_pin(codec, "Audio Out"); + snd_soc_dapm_enable_pin(codec, "GSM Line Out"); + snd_soc_dapm_enable_pin(codec, "GSM Line In"); + snd_soc_dapm_disable_pin(codec, "Headset Mic"); + snd_soc_dapm_disable_pin(codec, "Call Mic"); break; case NEO_STEREO_TO_SPEAKERS: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - 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, "Call Mic", 0); + snd_soc_dapm_enable_pin(codec, "Audio 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, "Call Mic"); break; case NEO_STEREO_TO_HEADPHONES: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - 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, "Call Mic", 0); + snd_soc_dapm_enable_pin(codec, "Audio 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, "Call Mic"); break; case NEO_CAPTURE_HANDSET: - snd_soc_dapm_set_endpoint(codec, "Audio 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, "Call Mic", 1); + snd_soc_dapm_disable_pin(codec, "Audio 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_enable_pin(codec, "Call Mic"); break; case NEO_CAPTURE_HEADSET: - snd_soc_dapm_set_endpoint(codec, "Audio 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", 1); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); + snd_soc_dapm_disable_pin(codec, "Audio Out"); + snd_soc_dapm_disable_pin(codec, "GSM Line Out"); + snd_soc_dapm_disable_pin(codec, "GSM Line In"); + snd_soc_dapm_enable_pin(codec, "Headset Mic"); + snd_soc_dapm_disable_pin(codec, "Call Mic"); break; case NEO_CAPTURE_BLUETOOTH: - snd_soc_dapm_set_endpoint(codec, "Audio 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, "Call Mic", 0); + snd_soc_dapm_disable_pin(codec, "Audio 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, "Call Mic"); break; default: - snd_soc_dapm_set_endpoint(codec, "Audio 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, "Call Mic", 0); + snd_soc_dapm_disable_pin(codec, "Audio 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, "Call Mic"); } - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } @@ -511,12 +511,12 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) DBG("Entered %s\n", __func__); /* set up NC codec pins */ - snd_soc_dapm_set_endpoint(codec, "LOUT2", 0); - snd_soc_dapm_set_endpoint(codec, "ROUT2", 0); - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "OUT4", 0); - snd_soc_dapm_set_endpoint(codec, "LINE1", 0); - snd_soc_dapm_set_endpoint(codec, "LINE2", 0); + snd_soc_dapm_disable_pin(codec, "LOUT2"); + snd_soc_dapm_disable_pin(codec, "ROUT2"); + snd_soc_dapm_disable_pin(codec, "OUT3"); + snd_soc_dapm_disable_pin(codec, "OUT4"); + snd_soc_dapm_disable_pin(codec, "LINE1"); + snd_soc_dapm_disable_pin(codec, "LINE2"); /* set endpoints to default mode */ @@ -539,7 +539,7 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) err = snd_soc_dapm_add_routes(codec, dapm_routes, ARRAY_SIZE(dapm_routes)); - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index 2f91de8..846d1b3 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c @@ -25,7 +25,7 @@ extern struct snd_soc_platform sh7760_soc_platform; static int machine_init(struct snd_soc_codec *codec) { - snd_soc_dapm_sync_endpoints(codec); + snd_soc_dapm_sync(codec); return 0; } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 91cbbef..94296b5 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -880,8 +880,25 @@ static void dapm_free_widgets(struct snd_soc_codec *codec) } } +static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, + char *pin, int status) +{ + struct snd_soc_dapm_widget *w; + + list_for_each_entry(w, &codec->dapm_widgets, list) { + if (!strcmp(w->name, pin)) { + dbg("dapm: %s: pin %s\n", codec->name, pin); + w->connected = status; + return 0; + } + } + + dbg("dapm: %s: configuring unknown pin %s\n", codec->name, pin); + return -EINVAL; +} + /** - * snd_soc_dapm_sync_endpoints - scan and power dapm paths + * snd_soc_dapm_sync - scan and power dapm paths * @codec: audio codec * * Walks all dapm audio paths and powers widgets according to their @@ -889,11 +906,11 @@ static void dapm_free_widgets(struct snd_soc_codec *codec) * * Returns 0 for success. */ -int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec) +int snd_soc_dapm_sync(struct snd_soc_codec *codec) { return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); } -EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_endpoints); +EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, const char *sink, const char *control, const char *source) @@ -1441,53 +1458,57 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, } /** - * 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. + * snd_soc_dapm_enable_pin - enable pin. + * @snd_soc_codec: SoC codec + * @pin: pin name * - * Returns 0 for success else error. + * Enables input/output pin and it's parents or children widgets iff there is + * a valid audio route and active audio stream. + * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to + * do any widget power switching. */ -int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, - char *endpoint, int status) +int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin) { - 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 snd_soc_dapm_set_pin(codec, pin, 1); +} +EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); - return -ENODEV; +/** + * snd_soc_dapm_disable_pin - disable pin. + * @codec: SoC codec + * @pin: pin name + * + * Disables input/output pin and it's parents or children widgets. + * 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) +{ + return snd_soc_dapm_set_pin(codec, pin, 0); } -EXPORT_SYMBOL_GPL(snd_soc_dapm_set_endpoint); +EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); /** - * snd_soc_dapm_get_endpoint_status - get audio endpoint status + * snd_soc_dapm_get_pin_status - get audio pin status * @codec: audio codec - * @endpoint: audio signal endpoint (or start point) + * @pin: audio signal pin endpoint (or start point) * - * Get audio endpoint status - connected or disconnected. + * Get audio pin status - connected or disconnected. * - * Returns status + * Returns 1 for connected otherwise 0. */ -int snd_soc_dapm_get_endpoint_status(struct snd_soc_codec *codec, - char *endpoint) +int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin) { struct snd_soc_dapm_widget *w; list_for_each_entry(w, &codec->dapm_widgets, list) { - if (!strcmp(w->name, endpoint)) + if (!strcmp(w->name, pin)) return w->connected; } return 0; } -EXPORT_SYMBOL_GPL(snd_soc_dapm_get_endpoint_status); +EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); /** * snd_soc_dapm_free - free dapm resources -- cgit v0.10.2 From 3c4b266fe642bcaebe2b95edb56c3f8802924ff9 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:17 +0100 Subject: ALSA: asoc: core - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch series merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai in preparation for further ASoC v2 patches. This merger removes duplication in both DAI structures and simplifies the API for other users. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc.h b/include/sound/soc.h index 340223a..778e57e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -221,8 +221,7 @@ struct snd_soc_pcm_stream; struct snd_soc_ops; struct snd_soc_dai_mode; struct snd_soc_pcm_runtime; -struct snd_soc_codec_dai; -struct snd_soc_cpu_dai; +struct snd_soc_dai; struct snd_soc_codec; struct snd_soc_machine_config; struct soc_enum; @@ -317,50 +316,24 @@ struct snd_soc_ops { /* ASoC DAI ops */ struct snd_soc_dai_ops { /* DAI clocking configuration */ - int (*set_sysclk)(struct snd_soc_codec_dai *codec_dai, + int (*set_sysclk)(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir); - int (*set_pll)(struct snd_soc_codec_dai *codec_dai, + int (*set_pll)(struct snd_soc_dai *dai, int pll_id, unsigned int freq_in, unsigned int freq_out); - int (*set_clkdiv)(struct snd_soc_codec_dai *codec_dai, - int div_id, int div); + int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div); /* DAI format configuration */ - int (*set_fmt)(struct snd_soc_codec_dai *codec_dai, - unsigned int fmt); - int (*set_tdm_slot)(struct snd_soc_codec_dai *codec_dai, + int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); + int (*set_tdm_slot)(struct snd_soc_dai *dai, unsigned int mask, int slots); - int (*set_tristate)(struct snd_soc_codec_dai *, int tristate); + int (*set_tristate)(struct snd_soc_dai *dai, int tristate); /* digital mute */ - int (*digital_mute)(struct snd_soc_codec_dai *, int mute); + int (*digital_mute)(struct snd_soc_dai *dai, int mute); }; -/* SoC Codec DAI */ -struct snd_soc_codec_dai { - char *name; - int id; - unsigned char type; - - /* DAI capabilities */ - struct snd_soc_pcm_stream playback; - struct snd_soc_pcm_stream capture; - - /* DAI runtime info */ - struct snd_soc_codec *codec; - unsigned int active; - unsigned char pop_wait:1; - - /* ops */ - struct snd_soc_ops ops; - struct snd_soc_dai_ops dai_ops; - - /* DAI private data */ - void *private_data; -}; - -/* SoC CPU DAI */ -struct snd_soc_cpu_dai { - +/* SoC DAI (Digital Audio Interface) */ +struct snd_soc_dai { /* DAI description */ char *name; unsigned int id; @@ -368,13 +341,13 @@ struct snd_soc_cpu_dai { /* DAI callbacks */ int (*probe)(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai); + struct snd_soc_dai *dai); void (*remove)(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai); + struct snd_soc_dai *dai); int (*suspend)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); + struct snd_soc_dai *dai); int (*resume)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); + struct snd_soc_dai *dai); /* ops */ struct snd_soc_ops ops; @@ -386,7 +359,9 @@ struct snd_soc_cpu_dai { /* DAI runtime info */ struct snd_pcm_runtime *runtime; - unsigned char active:1; + struct snd_soc_codec *codec; + unsigned int active; + unsigned char pop_wait:1; void *dma_data; /* DAI private data */ @@ -428,7 +403,7 @@ struct snd_soc_codec { struct delayed_work delayed_work; /* codec DAI's */ - struct snd_soc_codec_dai *dai; + struct snd_soc_dai *dai; unsigned int num_dai; }; @@ -447,12 +422,12 @@ struct snd_soc_platform { int (*probe)(struct platform_device *pdev); int (*remove)(struct platform_device *pdev); int (*suspend)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); + struct snd_soc_dai *dai); int (*resume)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); + struct snd_soc_dai *dai); /* pcm creation and destruction */ - int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, + int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, struct snd_pcm *); void (*pcm_free)(struct snd_pcm *); @@ -466,8 +441,8 @@ struct snd_soc_dai_link { char *stream_name; /* Stream name */ /* DAI */ - struct snd_soc_codec_dai *codec_dai; - struct snd_soc_cpu_dai *cpu_dai; + struct snd_soc_dai *codec_dai; + struct snd_soc_dai *cpu_dai; /* machine stream operations */ struct snd_soc_ops *ops; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bdbbc6a..4d626b4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -134,8 +134,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_dai_link *machine = rtd->dai; struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; int ret = 0; mutex_lock(&pcm_mutex); @@ -272,7 +272,7 @@ static void close_delayed_work(struct work_struct *work) struct snd_soc_device *socdev = container_of(work, struct snd_soc_device, delayed_work.work); struct snd_soc_codec *codec = socdev->codec; - struct snd_soc_codec_dai *codec_dai; + struct snd_soc_dai *codec_dai; int i; mutex_lock(&pcm_mutex); @@ -323,8 +323,8 @@ static int soc_codec_close(struct snd_pcm_substream *substream) struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_dai_link *machine = rtd->dai; struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; struct snd_soc_codec *codec = socdev->codec; mutex_lock(&pcm_mutex); @@ -384,8 +384,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_dai_link *machine = rtd->dai; struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; struct snd_soc_codec *codec = socdev->codec; int ret = 0; @@ -489,8 +489,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_dai_link *machine = rtd->dai; struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; int ret = 0; mutex_lock(&pcm_mutex); @@ -559,8 +559,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_dai_link *machine = rtd->dai; struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; struct snd_soc_codec *codec = socdev->codec; mutex_lock(&pcm_mutex); @@ -594,8 +594,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_dai_link *machine = rtd->dai; struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; int ret; if (codec_dai->ops.trigger) { @@ -651,7 +651,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) /* mute any active DAC's */ for (i = 0; i < machine->num_links; i++) { - struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; + struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; if (dai->dai_ops.digital_mute && dai->playback.active) dai->dai_ops.digital_mute(dai, 1); } @@ -664,7 +664,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) machine->suspend_pre(pdev, state); for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) cpu_dai->suspend(pdev, cpu_dai); if (platform->suspend) @@ -690,7 +690,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) codec_dev->suspend(pdev, state); for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) cpu_dai->suspend(pdev, cpu_dai); } @@ -726,7 +726,7 @@ static void soc_resume_deferred(struct work_struct *work) machine->resume_pre(pdev); for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) cpu_dai->resume(pdev, cpu_dai); } @@ -747,13 +747,13 @@ static void soc_resume_deferred(struct work_struct *work) /* unmute any active DACs */ for (i = 0; i < machine->num_links; i++) { - struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; + struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; if (dai->dai_ops.digital_mute && dai->playback.active) dai->dai_ops.digital_mute(dai, 0); } for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) cpu_dai->resume(pdev, cpu_dai); if (platform->resume) @@ -803,7 +803,7 @@ static int soc_probe(struct platform_device *pdev) } for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->probe) { ret = cpu_dai->probe(pdev, cpu_dai); if (ret < 0) @@ -838,7 +838,7 @@ platform_err: cpu_dai_err: for (i--; i >= 0; i--) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->remove) cpu_dai->remove(pdev, cpu_dai); } @@ -867,7 +867,7 @@ static int soc_remove(struct platform_device *pdev) codec_dev->remove(pdev); for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; if (cpu_dai->remove) cpu_dai->remove(pdev, cpu_dai); } @@ -895,8 +895,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev, struct snd_soc_dai_link *dai_link, int num) { struct snd_soc_codec *codec = socdev->codec; - struct snd_soc_codec_dai *codec_dai = dai_link->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = dai_link->cpu_dai; + struct snd_soc_dai *codec_dai = dai_link->codec_dai; + struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; struct snd_soc_pcm_runtime *rtd; struct snd_pcm *pcm; char new_name[64]; @@ -1211,7 +1211,7 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev) { struct snd_soc_codec *codec = socdev->codec; #ifdef CONFIG_SND_SOC_AC97_BUS - struct snd_soc_codec_dai *codec_dai; + struct snd_soc_dai *codec_dai; int i; #endif -- cgit v0.10.2 From 453ba20b2800bc07a3eaf220010dc0127cc552fd Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:29 +0100 Subject: ALSA: asoc: at32 - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch series merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for AT32 platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c index cf76e89..435f1da 100644 --- a/sound/soc/at32/at32-pcm.c +++ b/sound/soc/at32/at32-pcm.c @@ -366,7 +366,7 @@ static struct snd_pcm_ops at32_pcm_ops = { static u64 at32_pcm_dmamask = 0xffffffff; static int at32_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, + struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; @@ -422,7 +422,7 @@ static void at32_pcm_free_dma_buffers(struct snd_pcm *pcm) #ifdef CONFIG_PM static int at32_pcm_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = dai->runtime; struct at32_runtime_data *prtd; @@ -447,7 +447,7 @@ static int at32_pcm_suspend(struct platform_device *pdev, static int at32_pcm_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = dai->runtime; struct at32_runtime_data *prtd; diff --git a/sound/soc/at32/at32-ssc.c b/sound/soc/at32/at32-ssc.c index 0ca4410..4ef6492 100644 --- a/sound/soc/at32/at32-ssc.c +++ b/sound/soc/at32/at32-ssc.c @@ -336,7 +336,7 @@ static void at32_ssc_shutdown(struct snd_pcm_substream *substream) /* * Set the SSC system clock rate */ -static int at32_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int at32_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { /* TODO: What the heck do I do here? */ @@ -348,7 +348,7 @@ static int at32_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, /* * Record DAI format for use by hw_params() */ -static int at32_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int at32_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; @@ -362,7 +362,7 @@ static int at32_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, /* * Record SSC clock dividers for use in hw_params() */ -static int at32_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, +static int at32_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; @@ -670,7 +670,7 @@ static int at32_ssc_prepare(struct snd_pcm_substream *substream) #ifdef CONFIG_PM static int at32_ssc_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { struct at32_ssc_info *ssc_p; @@ -699,7 +699,7 @@ static int at32_ssc_suspend(struct platform_device *pdev, static int at32_ssc_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { struct at32_ssc_info *ssc_p; u32 cr; @@ -746,7 +746,7 @@ static int at32_ssc_resume(struct platform_device *pdev, SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_S32) -struct snd_soc_cpu_dai at32_ssc_dai[NUM_SSC_DEVICES] = { +struct snd_soc_dai at32_ssc_dai[NUM_SSC_DEVICES] = { { .name = "at32-ssc0", .id = 0, diff --git a/sound/soc/at32/at32-ssc.h b/sound/soc/at32/at32-ssc.h index 3c6901a..3c052db 100644 --- a/sound/soc/at32/at32-ssc.h +++ b/sound/soc/at32/at32-ssc.h @@ -52,7 +52,7 @@ struct at32_ssc_info { #define AT32_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ -extern struct snd_soc_cpu_dai at32_ssc_dai[]; +extern struct snd_soc_dai at32_ssc_dai[]; diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index d6b9fd5..18ac7d7 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c @@ -82,7 +82,7 @@ static struct clk *_pll0; #if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock( struct snd_pcm_hw_params *params, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { struct at32_ssc_info *ssc_p = cpu_dai->private_data; struct ssc_device *ssc = ssc_p->ssc; @@ -132,8 +132,8 @@ static int playpaq_wm8510_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct at32_ssc_info *ssc_p = cpu_dai->private_data; struct ssc_device *ssc = ssc_p->ssc; unsigned int pll_out = 0, bclk = 0, mclk_div = 0; -- cgit v0.10.2 From d37ae539a1d76da8fe5a939ce8b6d818501c8716 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:37 +0100 Subject: ALSA: asoc: at91 - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the AT91 platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c index ccac6bd..d47492b 100644 --- a/sound/soc/at91/at91-pcm.c +++ b/sound/soc/at91/at91-pcm.c @@ -318,7 +318,7 @@ static int at91_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, static u64 at91_pcm_dmamask = 0xffffffff; static int at91_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) + struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; @@ -367,7 +367,7 @@ static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm) #ifdef CONFIG_PM static int at91_pcm_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = dai->runtime; struct at91_runtime_data *prtd; @@ -392,7 +392,7 @@ static int at91_pcm_suspend(struct platform_device *pdev, } static int at91_pcm_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = dai->runtime; struct at91_runtime_data *prtd; diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index bc35d00..c3625b6 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -281,7 +281,7 @@ static void at91_ssc_shutdown(struct snd_pcm_substream *substream) /* * Record the SSC system clock rate. */ -static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int at91_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { /* @@ -303,7 +303,7 @@ static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, /* * Record the DAI format for use in hw_params(). */ -static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int at91_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; @@ -315,7 +315,7 @@ static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, /* * Record SSC clock dividers for use in hw_params(). */ -static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, +static int at91_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; @@ -634,7 +634,7 @@ static int at91_ssc_prepare(struct snd_pcm_substream *substream) #ifdef CONFIG_PM static int at91_ssc_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { struct at91_ssc_info *ssc_p; @@ -662,7 +662,7 @@ static int at91_ssc_suspend(struct platform_device *pdev, } static int at91_ssc_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { struct at91_ssc_info *ssc_p; @@ -700,7 +700,7 @@ static int at91_ssc_resume(struct platform_device *pdev, #define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = { +struct snd_soc_dai at91_ssc_dai[NUM_SSC_DEVICES] = { { .name = "at91-ssc0", .id = 0, .type = SND_SOC_DAI_PCM, diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h index b188f97..6b7bf38 100644 --- a/sound/soc/at91/at91-ssc.h +++ b/sound/soc/at91/at91-ssc.h @@ -21,7 +21,7 @@ #define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ #define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ -extern struct snd_soc_cpu_dai at91_ssc_dai[]; +extern struct snd_soc_dai at91_ssc_dai[]; #endif /* _AT91_SSC_H */ diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index ad971e7..9d42139 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -53,8 +53,8 @@ static struct clk *pllb_clk; static int eti_b1_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int ret; /* cpu clock is the AT91 master clock sent to the SSC */ @@ -87,8 +87,8 @@ static int eti_b1_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int ret; #ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE -- cgit v0.10.2 From 9cb132d743cf39b3bbe4288e9035217e7237a0bb Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:42 +0100 Subject: ALSA: asoc: davinci - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the DaVinci platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 091eae3..4249e6a 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -33,8 +33,8 @@ static int evm_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int ret = 0; /* set codec DAI configuration */ diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index c3b545c..5ebf1ff 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -147,7 +147,7 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream) static int davinci_i2s_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; cpu_dai->dma_data = dev->dma_params[substream->stream]; @@ -155,7 +155,7 @@ static int davinci_i2s_startup(struct snd_pcm_substream *substream) return 0; } -static int davinci_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct davinci_mcbsp_dev *dev = cpu_dai->private_data; @@ -296,11 +296,11 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd) } static int davinci_i2s_probe(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; struct davinci_mcbsp_dev *dev; struct resource *mem, *ioarea; struct evm_snd_platform_data *pdata; @@ -358,11 +358,11 @@ err_release_region: } static void davinci_i2s_remove(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; + struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; struct davinci_mcbsp_dev *dev = cpu_dai->private_data; struct resource *mem; @@ -378,7 +378,7 @@ static void davinci_i2s_remove(struct platform_device *pdev, #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 -struct snd_soc_cpu_dai davinci_i2s_dai = { +struct snd_soc_dai davinci_i2s_dai = { .name = "davinci-i2s", .id = 0, .type = SND_SOC_DAI_I2S, diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/davinci/davinci-i2s.h index 9592d17..c5b0918 100644 --- a/sound/soc/davinci/davinci-i2s.h +++ b/sound/soc/davinci/davinci-i2s.h @@ -12,6 +12,6 @@ #ifndef _DAVINCI_I2S_H #define _DAVINCI_I2S_H -extern struct snd_soc_cpu_dai davinci_i2s_dai; +extern struct snd_soc_dai davinci_i2s_dai; #endif diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 6a76927..6a5e56a 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -350,7 +350,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm) static u64 davinci_pcm_dmamask = 0xffffffff; static int davinci_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) + struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret; -- cgit v0.10.2 From e550e17ffeb8cf8db27724eaf2ad05f77388afb9 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:07:52 +0100 Subject: ALSA: asoc: codecs - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the codec drivers. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index e4516f3..61fd96c 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -41,7 +41,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream) SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000) -struct snd_soc_codec_dai ac97_dai = { +struct snd_soc_dai ac97_dai = { .name = "AC97 HiFi", .type = SND_SOC_DAI_AC97, .playback = { diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h index 2bf6d69..281aa42 100644 --- a/sound/soc/codecs/ac97.h +++ b/sound/soc/codecs/ac97.h @@ -14,6 +14,6 @@ #define __LINUX_SND_SOC_AC97_H extern struct snd_soc_codec_device soc_codec_dev_ac97; -extern struct snd_soc_codec_dai ac97_dai; +extern struct snd_soc_dai ac97_dai; #endif diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 469266e..b26003c 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -329,7 +329,7 @@ static int ak4535_add_widgets(struct snd_soc_codec *codec) return 0; } -static int ak4535_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -369,7 +369,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, return 0; } -static int ak4535_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -394,7 +394,7 @@ static int ak4535_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return 0; } -static int ak4535_mute(struct snd_soc_codec_dai *dai, int mute) +static int ak4535_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; @@ -436,7 +436,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -struct snd_soc_codec_dai ak4535_dai = { +struct snd_soc_dai ak4535_dai = { .name = "AK4535", .playback = { .stream_name = "Playback", diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h index fc686dd..e9fe30e 100644 --- a/sound/soc/codecs/ak4535.h +++ b/sound/soc/codecs/ak4535.h @@ -40,7 +40,7 @@ struct ak4535_setup_data { unsigned short i2c_address; }; -extern struct snd_soc_codec_dai ak4535_dai; +extern struct snd_soc_dai ak4535_dai; extern struct snd_soc_codec_device soc_codec_dev_ak4535; #endif diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index e73fcfd..9deb8c7 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -201,7 +201,7 @@ static struct { * driver what the input settings can be. This would need to be implemented * for stand-alone mode to work. */ -static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -251,7 +251,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, * data for playback only, but ASoC currently does not support different * formats for playback vs. record. */ -static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; @@ -471,7 +471,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, * board does not have the MUTEA or MUTEB pins connected to such circuitry, * then this function will do nothing. */ -static int cs4270_mute(struct snd_soc_codec_dai *dai, int mute) +static int cs4270_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; int reg6; @@ -667,7 +667,7 @@ error: #endif /* USE_I2C*/ -struct snd_soc_codec_dai cs4270_dai = { +struct snd_soc_dai cs4270_dai = { .name = "CS4270", .playback = { .stream_name = "Playback", diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h index 0ced49b..adc6cd9 100644 --- a/sound/soc/codecs/cs4270.h +++ b/sound/soc/codecs/cs4270.h @@ -16,7 +16,7 @@ * The ASoC codec DAI structure for the CS4270. Assign this structure to * the .codec_dai field of your machine driver's snd_soc_dai_link structure. */ -extern struct snd_soc_codec_dai cs4270_dai; +extern struct snd_soc_dai cs4270_dai; /* * The ASoC codec device structure for the CS4270. Assign this structure diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 954d39b..b1dce5f 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -814,7 +814,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, return 0; } -static int aic3x_mute(struct snd_soc_codec_dai *dai, int mute) +static int aic3x_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u8 ldac_reg = aic3x_read_reg_cache(codec, LDAC_VOL) & ~MUTE_ON; @@ -831,7 +831,7 @@ static int aic3x_mute(struct snd_soc_codec_dai *dai, int mute) return 0; } -static int aic3x_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -841,7 +841,7 @@ static int aic3x_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, return 0; } -static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -990,7 +990,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected); #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) -struct snd_soc_codec_dai aic3x_dai = { +struct snd_soc_dai aic3x_dai = { .name = "aic3x", .playback = { .stream_name = "Playback", diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index e600946..d76c079 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -228,7 +228,7 @@ struct aic3x_setup_data { unsigned int gpio_func[2]; }; -extern struct snd_soc_codec_dai aic3x_dai; +extern struct snd_soc_dai aic3x_dai; extern struct snd_soc_codec_device soc_codec_dev_aic3x; #endif /* _AIC3X_H */ diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 6d5335b..a52d6d9 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -372,7 +372,7 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec) return 0; } -static int uda1380_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -499,7 +499,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream) uda1380_write(codec, UDA1380_CLK, clk); } -static int uda1380_mute(struct snd_soc_codec_dai *codec_dai, int mute) +static int uda1380_mute(struct snd_soc_dai *codec_dai, int mute) { struct snd_soc_codec *codec = codec_dai->codec; u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM; @@ -542,7 +542,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -struct snd_soc_codec_dai uda1380_dai[] = { +struct snd_soc_dai uda1380_dai[] = { { .name = "UDA1380", .playback = { diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h index f9d885c8..50c603e 100644 --- a/sound/soc/codecs/uda1380.h +++ b/sound/soc/codecs/uda1380.h @@ -83,7 +83,7 @@ struct uda1380_setup_data { #define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ #define UDA1380_DAI_CAPTURE 2 /* capture DAI */ -extern struct snd_soc_codec_dai uda1380_dai[3]; +extern struct snd_soc_dai uda1380_dai[3]; extern struct snd_soc_codec_device soc_codec_dev_uda1380; #endif /* _UDA1380_H */ diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index b549f67..67325fd 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -332,7 +332,7 @@ static void pll_factors(unsigned int target, unsigned int source) pll_div.k = K; } -static int wm8510_set_dai_pll(struct snd_soc_codec_dai *codec_dai, +static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, unsigned int freq_in, unsigned int freq_out) { struct snd_soc_codec *codec = codec_dai->codec; @@ -368,7 +368,7 @@ static int wm8510_set_dai_pll(struct snd_soc_codec_dai *codec_dai, /* * Configure WM8510 clock dividers. */ -static int wm8510_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, +static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div) { struct snd_soc_codec *codec = codec_dai->codec; @@ -402,7 +402,7 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, return 0; } -static int wm8510_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -510,7 +510,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } -static int wm8510_mute(struct snd_soc_codec_dai *dai, int mute) +static int wm8510_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 mute_reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0xffbf; @@ -554,7 +554,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, #define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -struct snd_soc_codec_dai wm8510_dai = { +struct snd_soc_dai wm8510_dai = { .name = "WM8510 HiFi", .playback = { .stream_name = "Playback", diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h index c862e7b..f5d2e42 100644 --- a/sound/soc/codecs/wm8510.h +++ b/sound/soc/codecs/wm8510.h @@ -97,7 +97,7 @@ struct wm8510_setup_data { unsigned short i2c_address; }; -extern struct snd_soc_codec_dai wm8510_dai; +extern struct snd_soc_dai wm8510_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8510; #endif diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 3ff42ad..369d39c 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -318,7 +318,7 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream) } } -static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute) +static int wm8731_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; @@ -330,7 +330,7 @@ static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute) return 0; } -static int wm8731_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -349,7 +349,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, } -static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -443,7 +443,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -struct snd_soc_codec_dai wm8731_dai = { +struct snd_soc_dai wm8731_dai = { .name = "WM8731", .playback = { .stream_name = "Playback", diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h index 5bcab6a..99f2e3c 100644 --- a/sound/soc/codecs/wm8731.h +++ b/sound/soc/codecs/wm8731.h @@ -38,7 +38,7 @@ struct wm8731_setup_data { unsigned short i2c_address; }; -extern struct snd_soc_codec_dai wm8731_dai; +extern struct snd_soc_dai wm8731_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8731; #endif diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index eb460c9..e23cb09 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -536,7 +536,7 @@ static inline int get_coeff(int mclk, int rate) return -EINVAL; } -static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -554,7 +554,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, return -EINVAL; } -static int wm8750_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -647,7 +647,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } -static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute) +static int wm8750_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; @@ -692,7 +692,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, #define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -struct snd_soc_codec_dai wm8750_dai = { +struct snd_soc_dai wm8750_dai = { .name = "WM8750", .playback = { .stream_name = "Playback", diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h index a97a54a..8ef30e6 100644 --- a/sound/soc/codecs/wm8750.h +++ b/sound/soc/codecs/wm8750.h @@ -61,7 +61,7 @@ struct wm8750_setup_data { unsigned short i2c_address; }; -extern struct snd_soc_codec_dai wm8750_dai; +extern struct snd_soc_dai wm8750_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8750; #endif diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index be01a73..8604809 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -740,7 +740,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, pll_div->k = K; } -static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai, +static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, unsigned int freq_in, unsigned int freq_out) { u16 reg, enable; @@ -863,7 +863,7 @@ static int get_coeff(int mclk, int rate) /* * Clock after PLL and dividers */ -static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -890,7 +890,7 @@ static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, /* * Set's ADC and Voice DAC format. */ -static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -960,7 +960,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, /* * Set's PCM dai fmt and BCLK. */ -static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1026,7 +1026,7 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return 0; } -static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, +static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1054,7 +1054,7 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, /* * Set's HiFi DAC format. */ -static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1087,7 +1087,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, /* * Set's I2S DAI format. */ -static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1195,7 +1195,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, return 0; } -static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1210,7 +1210,7 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return wm8753_pcm_set_dai_fmt(codec_dai, fmt); } -static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) @@ -1218,7 +1218,7 @@ static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return wm8753_i2s_set_dai_fmt(codec_dai, fmt); } -static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1233,7 +1233,7 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return wm8753_i2s_set_dai_fmt(codec_dai, fmt); } -static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1250,7 +1250,7 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return wm8753_i2s_set_dai_fmt(codec_dai, fmt); } -static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute) +static int wm8753_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; @@ -1316,7 +1316,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, * 3. Voice disabled - HIFI over HIFI * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture */ -static const struct snd_soc_codec_dai wm8753_all_dai[] = { +static const struct snd_soc_dai wm8753_all_dai[] = { /* DAI HiFi mode 1 */ { .name = "WM8753 HiFi", .id = 1, @@ -1456,7 +1456,7 @@ static const struct snd_soc_codec_dai wm8753_all_dai[] = { }, }; -struct snd_soc_codec_dai wm8753_dai[2]; +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 --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h index 95e2a1f..44f5f1f 100644 --- a/sound/soc/codecs/wm8753.h +++ b/sound/soc/codecs/wm8753.h @@ -120,7 +120,7 @@ struct wm8753_setup_data { #define WM8753_DAI_HIFI 0 #define WM8753_DAI_VOICE 1 -extern struct snd_soc_codec_dai wm8753_dai[2]; +extern struct snd_soc_dai wm8753_dai[2]; extern struct snd_soc_codec_device soc_codec_dev_wm8753; #endif diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index a1371b7..3ecce51 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1029,7 +1029,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, pll_div->k = K; } -static int wm8990_set_dai_pll(struct snd_soc_codec_dai *codec_dai, +static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, unsigned int freq_in, unsigned int freq_out) { u16 reg; @@ -1065,7 +1065,7 @@ static int wm8990_set_dai_pll(struct snd_soc_codec_dai *codec_dai, /* * Clock after PLL and dividers */ -static int wm8990_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, +static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1078,7 +1078,7 @@ static int wm8990_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, /* * Set's ADC and Voice DAC format. */ -static int wm8990_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1131,7 +1131,7 @@ static int wm8990_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, return 0; } -static int wm8990_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, +static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1196,7 +1196,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream, return 0; } -static int wm8990_mute(struct snd_soc_codec_dai *dai, int mute) +static int wm8990_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; u16 val; @@ -1329,7 +1329,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, * 1. ADC/DAC on Primary Interface * 2. ADC on Primary Interface/DAC on secondary */ -struct snd_soc_codec_dai wm8990_dai = { +struct snd_soc_dai wm8990_dai = { /* ADC/DAC on primary */ .name = "WM8990 ADC/DAC Primary", .id = 1, diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h index bf9f882..6bea574 100644 --- a/sound/soc/codecs/wm8990.h +++ b/sound/soc/codecs/wm8990.h @@ -825,7 +825,7 @@ struct wm8990_setup_data { #define WM8990_ADCCLK_DIV 2 #define WM8990_BCLK_DIV 3 -extern struct snd_soc_codec_dai wm8990_dai; +extern struct snd_soc_dai wm8990_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8990; #endif /* __WM8990REGISTERDEFS_H__ */ diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 4739011..9fc8edd 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -532,7 +532,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream) SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000) -struct snd_soc_codec_dai wm9712_dai[] = { +struct snd_soc_dai wm9712_dai[] = { { .name = "AC97 HiFi", .type = SND_SOC_DAI_AC97_BUS, diff --git a/sound/soc/codecs/wm9712.h b/sound/soc/codecs/wm9712.h index 719105d..d29e8a1 100644 --- a/sound/soc/codecs/wm9712.h +++ b/sound/soc/codecs/wm9712.h @@ -8,7 +8,7 @@ #define WM9712_DAI_AC97_HIFI 0 #define WM9712_DAI_AC97_AUX 1 -extern struct snd_soc_codec_dai wm9712_dai[2]; +extern struct snd_soc_dai wm9712_dai[2]; extern struct snd_soc_codec_device soc_codec_dev_wm9712; #endif diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index a480618..38d1fe0 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -789,7 +789,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, return 0; } -static int wm9713_set_dai_pll(struct snd_soc_codec_dai *codec_dai, +static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, unsigned int freq_in, unsigned int freq_out) { struct snd_soc_codec *codec = codec_dai->codec; @@ -800,7 +800,7 @@ static int wm9713_set_dai_pll(struct snd_soc_codec_dai *codec_dai, * Tristate the PCM DAI lines, tristate can be disabled by calling * wm9713_set_dai_fmt() */ -static int wm9713_set_dai_tristate(struct snd_soc_codec_dai *codec_dai, +static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai, int tristate) { struct snd_soc_codec *codec = codec_dai->codec; @@ -816,7 +816,7 @@ static int wm9713_set_dai_tristate(struct snd_soc_codec_dai *codec_dai, * Configure WM9713 clock dividers. * Voice DAC needs 256 FS */ -static int wm9713_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, +static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div) { struct snd_soc_codec *codec = codec_dai->codec; @@ -858,7 +858,7 @@ static int wm9713_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, return 0; } -static int wm9713_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, +static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1018,7 +1018,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream) (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ SNDRV_PCM_FORMAT_S24_LE) -struct snd_soc_codec_dai wm9713_dai[] = { +struct snd_soc_dai wm9713_dai[] = { { .name = "AC97 HiFi", .type = SND_SOC_DAI_AC97_BUS, diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h index d357b6c..63b8d81 100644 --- a/sound/soc/codecs/wm9713.h +++ b/sound/soc/codecs/wm9713.h @@ -46,7 +46,7 @@ #define WM9713_DAI_PCM_VOICE 2 extern struct snd_soc_codec_device soc_codec_dev_wm9713; -extern struct snd_soc_codec_dai wm9713_dai[3]; +extern struct snd_soc_dai wm9713_dai[3]; int wm9713_reset(struct snd_soc_codec *codec, int try_warm); -- cgit v0.10.2 From 8cf7b2b393b26b9ba1ccbeeb271a88e51d58f3e3 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:00 +0100 Subject: ALSA: asoc: fsl - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the Freescale PPC platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 78de716..da2bc59 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -282,7 +282,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id) * once for each .dai_link in the machine driver's snd_soc_machine * structure. */ -static int fsl_dma_new(struct snd_card *card, struct snd_soc_codec_dai *dai, +static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { static u64 fsl_dma_dmamask = DMA_BIT_MASK(32); diff --git a/sound/soc/fsl/fsl_dma.h b/sound/soc/fsl/fsl_dma.h index 430a6ce..385d4a4 100644 --- a/sound/soc/fsl/fsl_dma.h +++ b/sound/soc/fsl/fsl_dma.h @@ -126,7 +126,7 @@ struct fsl_dma_link_descriptor { u8 res[4]; /* Reserved */ } __attribute__ ((aligned(32), packed)); -/* DMA information needed to create a snd_soc_cpu_dai object +/* DMA information needed to create a snd_soc_dai object * * ssi_stx_phys: bus address of SSI STX register to use * ssi_srx_phys: bus address of SSI SRX register to use diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index f588545..71bff33 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -82,7 +82,7 @@ struct fsl_ssi_private { struct device *dev; unsigned int playback; unsigned int capture; - struct snd_soc_cpu_dai cpu_dai; + struct snd_soc_dai cpu_dai; struct device_attribute dev_attr; struct { @@ -479,7 +479,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) * @freq: the frequency of the given clock ID, currently ignored * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master) */ -static int fsl_ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int fsl_ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { @@ -497,7 +497,7 @@ static int fsl_ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, * * @format: one of SND_SOC_DAIFMT_xxx */ -static int fsl_ssi_set_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int format) +static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format) { return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL; } @@ -505,7 +505,7 @@ static int fsl_ssi_set_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int format) /** * fsl_ssi_dai_template: template CPU DAI for the SSI */ -static struct snd_soc_cpu_dai fsl_ssi_dai_template = { +static struct snd_soc_dai fsl_ssi_dai_template = { .playback = { /* The SSI does not support monaural audio. */ .channels_min = 2, @@ -569,15 +569,15 @@ static ssize_t fsl_sysfs_ssi_show(struct device *dev, } /** - * fsl_ssi_create_dai: create a snd_soc_cpu_dai structure + * fsl_ssi_create_dai: create a snd_soc_dai structure * - * This function is called by the machine driver to create a snd_soc_cpu_dai + * This function is called by the machine driver to create a snd_soc_dai * structure. The function creates an ssi_private object, which contains - * the snd_soc_cpu_dai. It also creates the sysfs statistics device. + * the snd_soc_dai. It also creates the sysfs statistics device. */ -struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) +struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) { - struct snd_soc_cpu_dai *fsl_ssi_dai; + struct snd_soc_dai *fsl_ssi_dai; struct fsl_ssi_private *ssi_private; int ret = 0; struct device_attribute *dev_attr; @@ -588,7 +588,7 @@ struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) return NULL; } memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template, - sizeof(struct snd_soc_cpu_dai)); + sizeof(struct snd_soc_dai)); fsl_ssi_dai = &ssi_private->cpu_dai; dev_attr = &ssi_private->dev_attr; @@ -623,11 +623,11 @@ struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) EXPORT_SYMBOL_GPL(fsl_ssi_create_dai); /** - * fsl_ssi_destroy_dai: destroy the snd_soc_cpu_dai object + * fsl_ssi_destroy_dai: destroy the snd_soc_dai object * * This function undoes the operations of fsl_ssi_create_dai() */ -void fsl_ssi_destroy_dai(struct snd_soc_cpu_dai *fsl_ssi_dai) +void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai) { struct fsl_ssi_private *ssi_private = container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai); diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index c5ce88e..83b44d7 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h @@ -217,8 +217,8 @@ struct fsl_ssi_info { struct device *dev; }; -struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info); -void fsl_ssi_destroy_dai(struct snd_soc_cpu_dai *fsl_ssi_dai); +struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info); +void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai); #endif diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 8820c3f..59d7e49 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -96,8 +96,8 @@ static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device) static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct mpc8610_hpcd_data *machine_data = rtd->socdev->dev->platform_data; int ret = 0; -- cgit v0.10.2 From 8687eb8bded8c3c5842a85bd0c30e43fc5a3e0e0 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:07 +0100 Subject: ALSA: asoc: omap - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the Omap platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 74f4599..d1233c0 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -86,8 +86,8 @@ static int n810_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int err; /* Set codec DAI configuration */ diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 40d87e6..00b0c9d 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -103,7 +103,7 @@ static const unsigned long omap2420_mcbsp_port[][2] = {}; static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); int err = 0; @@ -116,7 +116,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); if (!cpu_dai->active) { @@ -128,7 +128,7 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); int err = 0; @@ -157,7 +157,7 @@ static int omap_mcbsp_dai_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_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; @@ -223,7 +223,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, * This must be called before _set_clkdiv and _set_sysclk since McBSP register * cache is initialized here */ -static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); @@ -292,7 +292,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, return 0; } -static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, +static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); @@ -347,7 +347,7 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data, return 0; } -static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { @@ -376,7 +376,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, return err; } -struct snd_soc_cpu_dai omap_mcbsp_dai[NUM_LINKS] = { +struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS] = { { .name = "omap-mcbsp-dai", .id = 0, diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index 9965fd4..ed8afb5 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h @@ -44,6 +44,6 @@ enum omap_mcbsp_div { */ #define NUM_LINKS 1 -extern struct snd_soc_cpu_dai omap_mcbsp_dai[NUM_LINKS]; +extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS]; #endif diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 6237020..e092f3d 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -316,7 +316,7 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm) } } -int omap_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, +int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; -- cgit v0.10.2 From 917f93ac80a1c007d4a3ce269a3712f93a75728f Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:11 +0100 Subject: ALSA: asoc: pxa - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the PXA platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index db18ef6..782afbf 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -123,8 +123,8 @@ static int corgi_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int clk = 0; int ret = 0; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 36cbf69..ce25b6b 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -102,8 +102,8 @@ static int poodle_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int clk = 0; int ret = 0; diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index cb94795..b458667 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -283,7 +283,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { #ifdef CONFIG_PM static int pxa2xx_ac97_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { GCR |= GCR_ACLINK_OFF; clk_disable(ac97_clk); @@ -291,7 +291,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, } static int pxa2xx_ac97_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { pxa_gpio_mode(GPIO31_SYNC_AC97_MD); pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); @@ -311,7 +311,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, #endif static int pxa2xx_ac97_probe(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { int ret; @@ -373,7 +373,7 @@ static int pxa2xx_ac97_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_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; @@ -387,7 +387,7 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; @@ -401,7 +401,7 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; @@ -419,7 +419,7 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, * There is only 1 physical AC97 interface for pxa2xx, but it * has extra fifo's that can be used for aux DACs and ADCs. */ -struct snd_soc_cpu_dai pxa_ac97_dai[] = { +struct snd_soc_dai pxa_ac97_dai[] = { { .name = "pxa2xx-ac97", .id = 0, diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h index b8ccfee..e390de8 100644 --- a/sound/soc/pxa/pxa2xx-ac97.h +++ b/sound/soc/pxa/pxa2xx-ac97.h @@ -14,7 +14,7 @@ #define PXA2XX_DAI_AC97_AUX 1 #define PXA2XX_DAI_AC97_MIC 2 -extern struct snd_soc_cpu_dai pxa_ac97_dai[3]; +extern struct snd_soc_dai pxa_ac97_dai[3]; /* platform data */ extern struct snd_ac97_bus_ops pxa2xx_ac97_ops; diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 35090c2..9c06553 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -77,7 +77,7 @@ static struct pxa2xx_gpio gpio_bus[] = { static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; if (!cpu_dai->active) { SACR0 |= SACR0_RST; @@ -98,7 +98,7 @@ static int pxa_i2s_wait(void) return 0; } -static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { /* interface format */ @@ -124,7 +124,7 @@ static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, return 0; } -static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { if (clk_id != PXA2XX_I2S_SYSCLK) @@ -140,7 +140,7 @@ static int pxa2xx_i2s_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_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; pxa_gpio_mode(gpio_bus[pxa_i2s.master].rx); pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); @@ -237,7 +237,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) #ifdef CONFIG_PM static int pxa2xx_i2s_suspend(struct platform_device *dev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { if (!dai->active) return 0; @@ -255,7 +255,7 @@ static int pxa2xx_i2s_suspend(struct platform_device *dev, } static int pxa2xx_i2s_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { if (!dai->active) return 0; @@ -280,7 +280,7 @@ static int pxa2xx_i2s_resume(struct platform_device *pdev, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) -struct snd_soc_cpu_dai pxa_i2s_dai = { +struct snd_soc_dai pxa_i2s_dai = { .name = "pxa2xx-i2s", .id = 0, .type = SND_SOC_DAI_I2S, diff --git a/sound/soc/pxa/pxa2xx-i2s.h b/sound/soc/pxa/pxa2xx-i2s.h index 4435bd9..e2def44 100644 --- a/sound/soc/pxa/pxa2xx-i2s.h +++ b/sound/soc/pxa/pxa2xx-i2s.h @@ -15,6 +15,6 @@ /* I2S clock */ #define PXA2XX_I2S_SYSCLK 0 -extern struct snd_soc_cpu_dai pxa_i2s_dai; +extern struct snd_soc_dai pxa_i2s_dai; #endif diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index 01ad7bf..2df03ee 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -330,7 +330,7 @@ static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm) static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; -int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, +int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index ec18163..fd1abc7 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -121,8 +121,8 @@ static int spitz_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int clk = 0; int ret = 0; -- cgit v0.10.2 From 1992a6fbd929196aebe95e0e7b04c4da66c3bfec Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:24 +0100 Subject: ALSA: asoc: s3c24xx - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the S3C24xx platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index f053e85..51a4ce3 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -66,8 +66,8 @@ static int neo1973_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + 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; @@ -156,7 +156,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; DBG("Entered %s\n", __func__); @@ -176,7 +176,7 @@ static int neo1973_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_codec_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; unsigned int pcmdiv = 0; int ret = 0; unsigned long iis_clkrate; @@ -222,7 +222,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; DBG("Entered %s\n", __func__); @@ -546,7 +546,7 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec) /* * BT Codec DAI */ -static struct snd_soc_cpu_dai bt_dai = { +static struct snd_soc_dai bt_dai = { .name = "Bluetooth", .id = 0, .type = SND_SOC_DAI_PCM, diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index c463a82..ee4676e 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -295,7 +295,7 @@ static inline int s3c2412_snd_is_clkmaster(void) /* * Set S3C2412 I2S DAI format */ -static int s3c2412_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { u32 iismod; @@ -500,7 +500,7 @@ EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate); /* * Set S3C2412 Clock source */ -static int s3c2412_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); @@ -528,7 +528,7 @@ static int s3c2412_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, /* * Set S3C2412 Clock dividers */ -static int s3c2412_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, +static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { struct s3c2412_i2s_info *i2s = &s3c2412_i2s; @@ -602,7 +602,7 @@ EXPORT_SYMBOL_GPL(s3c2412_get_iisclk); static int s3c2412_i2s_probe(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { DBG("Entered %s\n", __func__); @@ -648,7 +648,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev, #ifdef CONFIG_PM static int s3c2412_i2s_suspend(struct platform_device *dev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct s3c2412_i2s_info *i2s = &s3c2412_i2s; u32 iismod; @@ -676,7 +676,7 @@ static int s3c2412_i2s_suspend(struct platform_device *dev, } static int s3c2412_i2s_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { struct s3c2412_i2s_info *i2s = &s3c2412_i2s; @@ -708,7 +708,7 @@ static int s3c2412_i2s_resume(struct platform_device *pdev, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -struct snd_soc_cpu_dai s3c2412_i2s_dai = { +struct snd_soc_dai s3c2412_i2s_dai = { .name = "s3c2412-i2s", .id = 0, .type = SND_SOC_DAI_I2S, diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h index 27f48e1..aac08a2 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.h +++ b/sound/soc/s3c24xx/s3c2412-i2s.h @@ -24,7 +24,7 @@ extern struct clk *s3c2412_get_iisclk(void); -extern struct snd_soc_cpu_dai s3c2412_i2s_dai; +extern struct snd_soc_dai s3c2412_i2s_dai; struct s3c2412_rate_calc { unsigned int clk_div; /* for prescaler */ diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c index 533565b..783349b 100644 --- a/sound/soc/s3c24xx/s3c2443-ac97.c +++ b/sound/soc/s3c24xx/s3c2443-ac97.c @@ -210,7 +210,7 @@ static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = { }; static int s3c2443_ac97_probe(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { int ret; u32 ac_glbctrl; @@ -262,7 +262,7 @@ static int s3c2443_ac97_probe(struct platform_device *pdev, } static void s3c2443_ac97_remove(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { free_irq(IRQ_S3C244x_AC97, NULL); clk_disable(s3c24xx_ac97.ac97_clk); @@ -274,7 +274,7 @@ static int s3c2443_ac97_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_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out; @@ -316,7 +316,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; @@ -352,7 +352,7 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -struct snd_soc_cpu_dai s3c2443_ac97_dai[] = { +struct snd_soc_dai s3c2443_ac97_dai[] = { { .name = "s3c2443-ac97", .id = 0, diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h index bf03e8e..a96dcad 100644 --- a/sound/soc/s3c24xx/s3c24xx-ac97.h +++ b/sound/soc/s3c24xx/s3c24xx-ac97.h @@ -26,6 +26,6 @@ #define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97 #endif -extern struct snd_soc_cpu_dai s3c2443_ac97_dai[]; +extern struct snd_soc_dai s3c2443_ac97_dai[]; #endif /*S3C24XXAC97_H_*/ diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 42e96b5..3975242 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -205,7 +205,7 @@ static inline int s3c24xx_snd_is_clkmaster(void) /* * Set S3C24xx I2S DAI format */ -static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { u32 iismod; @@ -313,7 +313,7 @@ exit_err: /* * Set S3C24xx Clock source */ -static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); @@ -339,7 +339,7 @@ static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, /* * Set S3C24xx Clock dividers */ -static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, +static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { u32 reg; @@ -378,7 +378,7 @@ u32 s3c24xx_i2s_get_clockrate(void) EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); static int s3c24xx_i2s_probe(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) + struct snd_soc_dai *dai) { DBG("Entered %s\n", __func__); @@ -411,7 +411,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev, #ifdef CONFIG_PM static int s3c24xx_i2s_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { DBG("Entered %s\n", __func__); @@ -426,7 +426,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev, } static int s3c24xx_i2s_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) + struct snd_soc_dai *cpu_dai) { DBG("Entered %s\n", __func__); clk_enable(s3c24xx_i2s.iis_clk); @@ -449,7 +449,7 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -struct snd_soc_cpu_dai s3c24xx_i2s_dai = { +struct snd_soc_dai s3c24xx_i2s_dai = { .name = "s3c24xx-i2s", .id = 0, .type = SND_SOC_DAI_I2S, diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h index 537b4ec..726d91c 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.h +++ b/sound/soc/s3c24xx/s3c24xx-i2s.h @@ -32,6 +32,6 @@ u32 s3c24xx_i2s_get_clockrate(void); -extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; +extern struct snd_soc_dai s3c24xx_i2s_dai; #endif /*S3C24XXI2S_H_*/ diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c index ef59974..cef79b3 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -429,7 +429,7 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK; static int s3c24xx_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) + struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; -- cgit v0.10.2 From 53640650ffe07f6201ecae0b0dca078b97327247 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 7 Jul 2008 16:08:29 +0100 Subject: ALSA: asoc: sh - merge structs snd_soc_codec_dai and snd_soc_cpu_dai. This patch merges struct snd_soc_codec_dai and struct snd_soc_cpu_dai into struct snd_soc_dai for the SuperH platform. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 7a3ce80..9faa126 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -326,7 +326,7 @@ static void camelot_pcm_free(struct snd_pcm *pcm) } static int camelot_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, + struct snd_soc_dai *dai, struct snd_pcm *pcm) { /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index b7b676b..df7bc34 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -266,7 +266,7 @@ static int hac_hw_params(struct snd_pcm_substream *substream, #define AC97_FMTS \ SNDRV_PCM_FMTBIT_S16_LE -struct snd_soc_cpu_dai sh4_hac_dai[] = { +struct snd_soc_dai sh4_hac_dai[] = { { .name = "HAC0", .id = 0, diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index 846d1b3..92bfaf4 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c @@ -20,7 +20,7 @@ #define IPSEL 0xFE400034 /* platform specific structs can be declared here */ -extern struct snd_soc_cpu_dai sh4_hac_dai[2]; +extern struct snd_soc_dai sh4_hac_dai[2]; extern struct snd_soc_platform sh7760_soc_platform; static int machine_init(struct snd_soc_codec *codec) diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index 3388bc3..55c3464 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -208,7 +208,7 @@ static int ssi_hw_params(struct snd_pcm_substream *substream, return 0; } -static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, +static int ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; @@ -222,7 +222,7 @@ static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, * This divider is used to generate the SSI_SCK (I2S bitclock) from the * clock at the HAC_BIT_CLK ("oversampling clock") pin. */ -static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div) +static int ssi_set_clkdiv(struct snd_soc_dai *dai, int did, int div) { struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; unsigned long ssicr; @@ -245,7 +245,7 @@ static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div) return 0; } -static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt) +static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; unsigned long ssicr = SSIREG(SSICR); @@ -332,7 +332,7 @@ static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt) SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) -struct snd_soc_cpu_dai sh4_ssi_dai[] = { +struct snd_soc_dai sh4_ssi_dai[] = { { .name = "SSI0", .id = 0, -- cgit v0.10.2 From c1286b8671135006eeb66b0267fa2895561b78e4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 Jul 2008 19:26:03 +0100 Subject: ALSA: ASoC: Switch DAPM to use of standard DEBUG macro DAPM contains debug output controlled by a DAPM_DEBUG macro. Change this to be controlled by the standard DEBUG, dropping the custom dbg() macro as we go. Also fix the error printed when configuring an unknown pin to be an unconditionally displayed error rather than debug output. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 94296b5..d18ebc6 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -45,13 +45,10 @@ #include /* debug */ -#define DAPM_DEBUG 0 -#if DAPM_DEBUG +#ifdef DEBUG #define dump_dapm(codec, action) dbg_dump_dapm(codec, action) -#define dbg(format, arg...) printk(format, ## arg) #else #define dump_dapm(codec, action) -#define dbg(format, arg...) #endif /* dapm power sequences - make this per codec in the future */ @@ -233,7 +230,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) snd_soc_write(codec, widget->reg, new); pop_wait(); } - dbg("reg %x old %x new %x change %d\n", widget->reg, old, new, change); + pr_debug("reg %x old %x new %x change %d\n", widget->reg, + old, new, change); return change; } @@ -591,8 +589,8 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) /* call any power change event handlers */ if (power_change) { if (w->event) { - dbg("power %s event for %s flags %x\n", - w->power ? "on" : "off", w->name, w->event_flags); + pr_debug("power %s event for %s flags %x\n", + w->power ? "on" : "off", w->name, w->event_flags); if (power) { /* power up event */ if (w->event_flags & SND_SOC_DAPM_PRE_PMU) { @@ -634,7 +632,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) return ret; } -#if DAPM_DEBUG +#ifdef DEBUG static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) { struct snd_soc_dapm_widget *w; @@ -887,13 +885,13 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, list_for_each_entry(w, &codec->dapm_widgets, list) { if (!strcmp(w->name, pin)) { - dbg("dapm: %s: pin %s\n", codec->name, pin); + pr_debug("dapm: %s: pin %s\n", codec->name, pin); w->connected = status; return 0; } } - dbg("dapm: %s: configuring unknown pin %s\n", codec->name, pin); + pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); return -EINVAL; } @@ -1397,8 +1395,8 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, { if (!w->sname) continue; - dbg("widget %s\n %s stream %s event %d\n", w->name, w->sname, - stream, event); + pr_debug("widget %s\n %s stream %s event %d\n", + w->name, w->sname, stream, event); if (strstr(w->sname, stream)) { switch(event) { case SND_SOC_DAPM_STREAM_START: -- cgit v0.10.2 From 3fccd8b1bf716f1314c76689a3554ea37ad282b6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 7 Jul 2008 19:26:04 +0100 Subject: ALSA: ASoC: Dump DAPM state for non-stream changes Explicit DAPM syncs are likely to cause DAPM state updates, as are mixer and mux configuration changes, so display the DAPM status after them too. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d18ebc6..2c87061 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -717,8 +717,10 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, path->connect = 0; /* old connection must be powered down */ } - if (found) + if (found) { dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); + dump_dapm(widget->codec, "mux power update"); + } return 0; } @@ -754,8 +756,10 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, break; } - if (found) + if (found) { dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); + dump_dapm(widget->codec, "mixer power update"); + } return 0; } @@ -906,7 +910,9 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, */ int snd_soc_dapm_sync(struct snd_soc_codec *codec) { - return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); + int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); + dump_dapm(codec, "sync"); + return ret; } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); -- cgit v0.10.2 From 7e2574050e6af203f0c94915c98c53ce1fc48044 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 8 Jul 2008 11:50:09 +0200 Subject: ALSA: hda - removed redundant gpio_mask An gpio_mask value was defined twice needlessly. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c4f3489..a6d1388 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3669,7 +3669,6 @@ again: /* GPIO0 High = EAPD */ spec->gpio_mask = 0x01; spec->gpio_dir = 0x01; - spec->gpio_mask = 0x01; spec->gpio_data = 0x01; spec->mux_nids = stac92hd71bxx_mux_nids; -- cgit v0.10.2 From 8c6529dbf881303920a415c2d14a500218661949 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:19:13 +0100 Subject: ALSA: asoc: core - add Digital Audio Interface (DAI) control functions. This patch adds several functions for DAI control and config and replaces the current method of calling function pointers within the DAI struct. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/soc.h b/include/sound/soc.h index 778e57e..1890d87 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -256,6 +256,27 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, struct snd_ac97_bus_ops *ops, int num); void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); +/* Digital Audio Interface clocking API.*/ +int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir); + +int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, + int div_id, int div); + +int snd_soc_dai_set_pll(struct snd_soc_dai *dai, + int pll_id, unsigned int freq_in, unsigned int freq_out); + +/* Digital Audio interface formatting */ +int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt); + +int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int mask, int slots); + +int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); + +/* Digital Audio Interface mute */ +int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute); + /* *Controls */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4d626b4..83f1190 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -434,8 +434,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) else { codec_dai->pop_wait = 0; cancel_delayed_work(&socdev->delayed_work); - if (codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 0); + snd_soc_dai_digital_mute(codec_dai, 0); } } else { /* no delayed work - do we need to power up codec */ @@ -454,8 +453,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) SND_SOC_DAPM_STREAM_START); snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); - if (codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 0); + snd_soc_dai_digital_mute(codec_dai, 0); } else { /* codec already powered - power on widgets */ @@ -467,8 +465,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) snd_soc_dapm_stream_event(codec, codec_dai->capture.stream_name, SND_SOC_DAPM_STREAM_START); - if (codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 0); + + snd_soc_dai_digital_mute(codec_dai, 0); } } @@ -566,8 +564,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) mutex_lock(&pcm_mutex); /* apply codec digital mute */ - if (!codec->active && codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 1); + if (!codec->active) + snd_soc_dai_digital_mute(codec_dai, 1); /* free any machine hw params */ if (machine->ops && machine->ops->hw_free) @@ -1703,6 +1701,132 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); +/** + * snd_soc_dai_set_sysclk - configure DAI system or master clock. + * @dai: DAI + * @clk_id: DAI specific clock ID + * @freq: new clock frequency in Hz + * @dir: new clock direction - input/output. + * + * Configures the DAI master (MCLK) or system (SYSCLK) clocking. + */ +int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + if (dai->dai_ops.set_sysclk) + return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); + +/** + * snd_soc_dai_set_clkdiv - configure DAI clock dividers. + * @dai: DAI + * @clk_id: DAI specific clock divider ID + * @div: new clock divisor. + * + * Configures the clock dividers. This is used to derive the best DAI bit and + * frame clocks from the system or master clock. It's best to set the DAI bit + * and frame clocks as low as possible to save system power. + */ +int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, + int div_id, int div) +{ + if (dai->dai_ops.set_clkdiv) + return dai->dai_ops.set_clkdiv(dai, div_id, div); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv); + +/** + * snd_soc_dai_set_pll - configure DAI PLL. + * @dai: DAI + * @pll_id: DAI specific PLL ID + * @freq_in: PLL input clock frequency in Hz + * @freq_out: requested PLL output clock frequency in Hz + * + * Configures and enables PLL to generate output clock based on input clock. + */ +int snd_soc_dai_set_pll(struct snd_soc_dai *dai, + int pll_id, unsigned int freq_in, unsigned int freq_out) +{ + if (dai->dai_ops.set_pll) + return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); + +/** + * snd_soc_dai_set_fmt - configure DAI hardware audio format. + * @dai: DAI + * @clk_id: DAI specific clock ID + * @fmt: SND_SOC_DAIFMT_ format value. + * + * Configures the DAI hardware format and clocking. + */ +int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + if (dai->dai_ops.set_fmt) + return dai->dai_ops.set_fmt(dai, fmt); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); + +/** + * snd_soc_dai_set_tdm_slot - configure DAI TDM. + * @dai: DAI + * @mask: DAI specific mask representing used slots. + * @slots: Number of slots in use. + * + * Configures a DAI for TDM operation. Both mask and slots are codec and DAI + * specific. + */ +int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int mask, int slots) +{ + if (dai->dai_ops.set_sysclk) + return dai->dai_ops.set_tdm_slot(dai, mask, slots); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); + +/** + * snd_soc_dai_set_tristate - configure DAI system or master clock. + * @dai: DAI + * @tristate: tristate enable + * + * Tristates the DAI so that others can use it. + */ +int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) +{ + if (dai->dai_ops.set_sysclk) + return dai->dai_ops.set_tristate(dai, tristate); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate); + +/** + * snd_soc_dai_digital_mute - configure DAI system or master clock. + * @dai: DAI + * @mute: mute enable + * + * Mutes the DAI DAC. + */ +int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) +{ + if (dai->dai_ops.digital_mute) + return dai->dai_ops.digital_mute(dai, mute); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); + static int __devinit snd_soc_init(void) { printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); -- cgit v0.10.2 From 64105cfd65df74fdf82c1d053b2c9953304a94ea Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:19:18 +0100 Subject: ALSA: asoc: machines - add Digital Audio Interface (DAI) control functions. This patch adds several functions for DAI control and config and replaces the current method of calling function pointers within the DAI struct within the machine drivers. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index 18ac7d7..fd62f25 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c @@ -210,14 +210,14 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, /* * set CPU and CODEC DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, fmt); + ret = snd_soc_dai_set_fmt(codec_dai, fmt); if (ret < 0) { pr_warning("playpaq_wm8510: " "Failed to set CODEC DAI format (%d)\n", ret); return ret; } - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, fmt); + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { pr_warning("playpaq_wm8510: " "Failed to set CPU DAI format (%d)\n", @@ -233,14 +233,13 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai); pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n", cd.cmr_div, cd.period); - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, - AT32_SSC_CMR_DIV, cd.cmr_div); + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div); if (ret < 0) { pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n", ret); return ret; } - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD, + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD, cd.period); if (ret < 0) { pr_warning("playpaq_wm8510: " @@ -260,7 +259,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, #if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE - ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk); + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk); if (ret < 0) { pr_warning ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n", @@ -270,7 +269,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ - ret = codec_dai->dai_ops.set_pll(codec_dai, 0, + ret = snd_soc_dai_set_pll(codec_dai, 0, clk_get_rate(CODEC_CLK), pll_out); if (ret < 0) { pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", @@ -279,8 +278,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, } - ret = codec_dai->dai_ops.set_clkdiv(codec_dai, - WM8510_MCLKDIV, mclk_div); + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div); if (ret < 0) { pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n", ret); diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index 9d42139..d532de9 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -58,13 +58,13 @@ static int eti_b1_startup(struct snd_pcm_substream *substream) int ret; /* cpu clock is the AT91 master clock sent to the SSC */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, AT91_SYSCLK_MCK, + ret = snd_soc_dai_set_sysclk(cpu_dai, AT91_SYSCLK_MCK, 60000000, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* codec system clock is supplied by PCK1, set to 12MHz */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, + ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, 12000000, SND_SOC_CLOCK_IN); if (ret < 0) return ret; @@ -96,13 +96,13 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream, int cmr_div, period; /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + 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 = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + 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; @@ -141,17 +141,17 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream, } /* set the MCK divider for BCLK */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div); + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div); if (ret < 0) return ret; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* set the BCLK divider for DACLRC */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_TCMR_PERIOD, period); } else { /* set the BCLK divider for ADCLRC */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_RCMR_PERIOD, period); } if (ret < 0) @@ -163,13 +163,13 @@ static int eti_b1_hw_params(struct snd_pcm_substream *substream, */ /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + 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 = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + 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; diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 4249e6a..5e2c306 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -38,19 +38,19 @@ static int evm_hw_params(struct snd_pcm_substream *substream, int ret = 0; /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM); if (ret < 0) return ret; /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF); if (ret < 0) return ret; /* set the codec system clock */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK, + ret = snd_soc_dai_set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK, SND_SOC_CLOCK_OUT); if (ret < 0) return ret; diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 59d7e49..4bdc9d8 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -103,55 +103,45 @@ static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream) int ret = 0; /* Tell the CPU driver what the serial protocol is. */ - if (cpu_dai->dai_ops.set_fmt) { - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, - machine_data->dai_format); - if (ret < 0) { - dev_err(substream->pcm->card->dev, - "could not set CPU driver audio format\n"); - return ret; - } + ret = snd_soc_dai_set_fmt(cpu_dai, machine_data->dai_format); + if (ret < 0) { + dev_err(substream->pcm->card->dev, + "could not set CPU driver audio format\n"); + return ret; } /* Tell the codec driver what the serial protocol is. */ - if (codec_dai->dai_ops.set_fmt) { - ret = codec_dai->dai_ops.set_fmt(codec_dai, - machine_data->dai_format); - if (ret < 0) { - dev_err(substream->pcm->card->dev, - "could not set codec driver audio format\n"); - return ret; - } + ret = snd_soc_dai_set_fmt(codec_dai, machine_data->dai_format); + if (ret < 0) { + dev_err(substream->pcm->card->dev, + "could not set codec driver audio format\n"); + return ret; } /* * Tell the CPU driver what the clock frequency is, and whether it's a * slave or master. */ - if (cpu_dai->dai_ops.set_sysclk) { - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, 0, - machine_data->clk_frequency, - machine_data->cpu_clk_direction); - if (ret < 0) { - dev_err(substream->pcm->card->dev, - "could not set CPU driver clock parameters\n"); - return ret; - } + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, + machine_data->clk_frequency, + machine_data->cpu_clk_direction); + if (ret < 0) { + dev_err(substream->pcm->card->dev, + "could not set CPU driver clock parameters\n"); + return ret; } /* * Tell the codec driver what the MCLK frequency is, and whether it's * a slave or master. */ - if (codec_dai->dai_ops.set_sysclk) { - ret = codec_dai->dai_ops.set_sysclk(codec_dai, 0, - machine_data->clk_frequency, - machine_data->codec_clk_direction); - if (ret < 0) { - dev_err(substream->pcm->card->dev, - "could not set codec driver clock params\n"); - return ret; - } + ret = snd_soc_dai_set_sysclk(codec_dai, 0, + machine_data->clk_frequency, + machine_data->codec_clk_direction); + if (ret < 0) { + dev_err(substream->pcm->card->dev, + "could not set codec driver clock params\n"); + return ret; } return 0; diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index d1233c0..e53c055 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -91,7 +91,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream, int err; /* Set codec DAI configuration */ - err = codec_dai->dai_ops.set_fmt(codec_dai, + err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); @@ -99,7 +99,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream, return err; /* Set cpu DAI configuration */ - err = cpu_dai->dai_ops.set_fmt(cpu_dai, + err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); @@ -107,7 +107,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream, return err; /* Set the codec system clock for DAC and ADC */ - err = codec_dai->dai_ops.set_sysclk(codec_dai, 0, 12000000, + err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000, SND_SOC_CLOCK_IN); return err; diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 782afbf..c029446 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -143,25 +143,25 @@ static int corgi_hw_params(struct snd_pcm_substream *substream, } /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + 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 = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + 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 = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, + ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* set the I2S system clock as input (unused) */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, + ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index ce25b6b..65a4e9a 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -122,25 +122,25 @@ static int poodle_hw_params(struct snd_pcm_substream *substream, } /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + 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 = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + 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 = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, + ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* set the I2S system clock as input (unused) */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, + ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index fd1abc7..6438579 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -141,25 +141,25 @@ static int spitz_hw_params(struct snd_pcm_substream *substream, } /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + 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 = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + 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 = codec_dai->dai_ops.set_sysclk(codec_dai, WM8750_SYSCLK, clk, + ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* set the I2S system clock as input (unused) */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, + ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 51a4ce3..4d7a9aa 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -108,44 +108,44 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, } /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, + 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 = cpu_dai->dai_ops.set_fmt(cpu_dai, + 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 = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out, + 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 = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, + 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 = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); if (ret < 0) return ret; /* set prescaler division for sample rate */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + 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 = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, + ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, iis_clkrate / 4, pll_out); if (ret < 0) return ret; @@ -161,7 +161,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) DBG("Entered %s\n", __func__); /* disable the PLL */ - return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0); + return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); } /* @@ -194,24 +194,24 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, /* todo: gg check mode (DSP_B) against CSR datasheet */ /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | + 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 = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, + 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 = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); + 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 = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, + ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, iis_clkrate / 4, 12288000); if (ret < 0) return ret; @@ -227,7 +227,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) DBG("Entered %s\n", __func__); /* disable the PLL */ - return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0); + return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); } static struct snd_soc_ops neo1973_voice_ops = { -- cgit v0.10.2 From ac8615baf279f9bcb90c8ae017321d63a94e1762 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:20:39 +0100 Subject: ALSA: asoc: n810 - fix build error. This patch adds a missing " that was recently introduced (removed) in the DAI struct merge patch series. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index e53c055..02cec968 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -63,7 +63,7 @@ static void n810_ext_control(struct snd_soc_codec *codec) if (n810_dmic_func) snd_soc_dapm_enable_pin(codec, "DMic"); else - snd_soc_dapm_disable_pin(codec, "DMic); + snd_soc_dapm_disable_pin(codec, "DMic"); snd_soc_dapm_sync(codec); } -- cgit v0.10.2 From 6f48413dd0f28d81a20fba2e264dd1b9f205893e Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 8 Jul 2008 13:21:52 +0100 Subject: ALSA: asoc: at32 - DAI struct merge and enable_pin() change. This adds support for the recent DAI struct merge and new DAPM pin API. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index fd62f25..fee5f8e 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c @@ -341,15 +341,15 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec) } - /* always connected endpoints */ - snd_soc_dapm_set_endpoint(codec, "Int Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); - snd_soc_dapm_sync_endpoints(codec); + /* always connected pins */ + snd_soc_dapm_enable_pin(codec, "Int Mic"); + snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_sync(codec); /* Make CSB show PLL rate */ - codec->dai->dai_ops.set_clkdiv(codec->dai, WM8510_OPCLKDIV, + snd_soc_dai_set_clkdiv(codec->dai, WM8510_OPCLKDIV, WM8510_OPCLKDIV_1 | 4); return 0; -- cgit v0.10.2 From bd5d06eb8f0b9e0eb117b9c45c254d577ec2e273 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:30:30 +0100 Subject: ALSA: Fix a const pointer usage warning in the Digigram VX soundcard driver Fix a const pointer usage warning in the Digigram VX soundcard driver. A const pointer is being passed to copy_from_user() to load the firmware into. This is okay in this case because the function has allocated the firmware struct itself, but the const qualifier is part of the firmware struct - so the patch casts the const away. Signed-off-by: David Howells Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index 1dfe694..efd22e9 100644 --- a/sound/drivers/vx/vx_hwdep.c +++ b/sound/drivers/vx/vx_hwdep.c @@ -183,7 +183,7 @@ static int vx_hwdep_dsp_load(struct snd_hwdep *hw, kfree(fw); return -ENOMEM; } - if (copy_from_user(fw->data, dsp->image, dsp->length)) { + if (copy_from_user((void *)fw->data, dsp->image, dsp->length)) { free_fw(fw); return -EFAULT; } -- cgit v0.10.2 From 7fc077fba5f8896c6fed3b35c5a10e7fdae82bbe Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:52:10 +0100 Subject: ALSA: Fix a const to non-const assignment in the Digigram VXpocket sound driver Fix a const to non-const pointer assignment warning in the Digigram VXpocket sound driver. This may be due to patch 0aa4937648b91e9e6d3879b2cbeaa5f0c9863ac0. Signed-off-by: David Howells Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c index 157b0b5..99bf2a6 100644 --- a/sound/pcmcia/vx/vxp_ops.c +++ b/sound/pcmcia/vx/vxp_ops.c @@ -151,7 +151,7 @@ static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware * unsigned int i; int c; int regCSUER, regRUER; - unsigned char *image; + const unsigned char *image; unsigned char data; /* Switch to programmation mode */ -- cgit v0.10.2 From ee2da99782d717b264d5c309a2084ca85e9a64ff Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 9 Jul 2008 10:28:41 +0200 Subject: ALSA: remove CONFIG_KMOD from sound A bunch of things in alsa depend on CONFIG_KMOD, use CONFIG_MODULES instead where the dependency is needed at all. Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h index f023c1b..3d9afb6 100644 --- a/include/sound/seq_kernel.h +++ b/include/sound/seq_kernel.h @@ -105,7 +105,7 @@ int snd_seq_event_port_attach(int client, struct snd_seq_port_callback *pcbp, int cap, int type, int midi_channels, int midi_voices, char *portname); int snd_seq_event_port_detach(int client, int port); -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES void snd_seq_autoload_lock(void); void snd_seq_autoload_unlock(void); #else diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 47cfa51..7a1545d 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -148,7 +148,7 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid) return NULL; } spin_unlock_irqrestore(&clients_lock, flags); -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES if (!in_interrupt()) { static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS]; static char card_requested[SNDRV_CARDS]; diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 2f00ad2..05410e5 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -124,7 +124,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, * load all registered drivers (called from seq_clientmgr.c) */ -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES /* avoid auto-loading during module_init() */ static int snd_seq_in_init; void snd_seq_autoload_lock(void) @@ -140,7 +140,7 @@ void snd_seq_autoload_unlock(void) void snd_seq_device_load_drivers(void) { -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES struct ops_list *ops; /* Calling request_module during module_init() @@ -566,7 +566,5 @@ EXPORT_SYMBOL(snd_seq_device_load_drivers); EXPORT_SYMBOL(snd_seq_device_new); EXPORT_SYMBOL(snd_seq_device_register_driver); EXPORT_SYMBOL(snd_seq_device_unregister_driver); -#ifdef CONFIG_KMOD EXPORT_SYMBOL(snd_seq_autoload_lock); EXPORT_SYMBOL(snd_seq_autoload_unlock); -#endif diff --git a/sound/core/sound.c b/sound/core/sound.c index 6c8ab48..09a9495 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -60,14 +60,14 @@ EXPORT_SYMBOL(snd_ecards_limit); static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; static DEFINE_MUTEX(sound_mutex); -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES /** * snd_request_card - try to load the card module * @card: the card number * * Tries to load the module "snd-card-X" for the given card number - * via KMOD. Returns immediately if already loaded. + * via request_module. Returns immediately if already loaded. */ void snd_request_card(int card) { @@ -92,7 +92,7 @@ static void snd_request_other(int minor) request_module(str); } -#endif /* request_module support */ +#endif /* modular kernel */ /** * snd_lookup_minor_data - get user data of a registered device @@ -132,7 +132,7 @@ static int snd_open(struct inode *inode, struct file *file) return -ENODEV; mptr = snd_minors[minor]; if (mptr == NULL) { -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES int dev = SNDRV_MINOR_DEVICE(minor); if (dev == SNDRV_MINOR_CONTROL) { /* /dev/aloadC? */ diff --git a/sound/core/timer.c b/sound/core/timer.c index 9d8184a..0af337e 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -146,7 +146,7 @@ static struct snd_timer *snd_timer_find(struct snd_timer_id *tid) return NULL; } -#ifdef CONFIG_KMOD +#ifdef CONFIG_MODULES static void snd_timer_request(struct snd_timer_id *tid) { @@ -259,8 +259,8 @@ int snd_timer_open(struct snd_timer_instance **ti, /* open a master instance */ mutex_lock(®ister_mutex); timer = snd_timer_find(tid); -#ifdef CONFIG_KMOD - if (timer == NULL) { +#ifdef CONFIG_MODULES + if (!timer) { mutex_unlock(®ister_mutex); snd_timer_request(tid); mutex_lock(®ister_mutex); diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c index ca94529..8a5b290 100644 --- a/sound/ppc/daca.c +++ b/sound/ppc/daca.c @@ -249,9 +249,7 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip) int i, err; struct pmac_daca *mix; -#ifdef CONFIG_KMOD request_module("i2c-powermac"); -#endif /* CONFIG_KMOD */ mix = kzalloc(sizeof(*mix), GFP_KERNEL); if (! mix) diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 3f8d716..009df8d 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -1350,9 +1350,7 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip) struct device_node *tas_node, *np; char *chipname; -#ifdef CONFIG_KMOD request_module("i2c-powermac"); -#endif /* CONFIG_KMOD */ mix = kzalloc(sizeof(*mix), GFP_KERNEL); if (! mix) -- cgit v0.10.2 From af13452820d075cb7153fe155ca796e64038d7e5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 9 Jul 2008 19:13:30 +0200 Subject: ALSA: wavefront - add const Fix const to non-const pointer cast warning in wavefront_synth.c. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 95eeca1..0bb9b92 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -1939,7 +1939,7 @@ static int __devinit wavefront_download_firmware (snd_wavefront_t *dev, char *path) { - unsigned char *buf; + const unsigned char *buf; int len, err; int section_cnt_downloaded = 0; const struct firmware *firmware; -- cgit v0.10.2 From 76d39d0a1947fee4c29976e507fb93188eaa2b38 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 8 Jul 2008 19:45:20 +0400 Subject: ALSA: tosa: fix compilation with new DAPM API Signed-off-by: Dmitry Baryshkov Acked-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index dba7689..b6edb61 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -153,7 +153,7 @@ SND_SOC_DAPM_SPK("Speaker", NULL), }; /* tosa audio map */ -static const snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route audio_map[] = { /* headphone connected to HPOUTL, HPOUTR */ {"Headphone Jack", NULL, "HPOUTL"}, @@ -205,7 +205,7 @@ static int tosa_ac97_init(struct snd_soc_codec *codec) } /* add tosa specific widgets */ - snd_soc_dapm_new_controls(codec, &tosa_dapm_widgets, + snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, ARRAY_SIZE(tosa_dapm_widgets)); /* set up tosa specific audio path audio_map */ -- cgit v0.10.2 From a84534dc179d3e9f501e5a12598cc5271cd28f5b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 8 Jul 2008 19:45:42 +0400 Subject: ALSA: ASoC: pxa2xx-ac97: fix warning due to missing argument in fuction declaration Signed-off-by: Dmitry Baryshkov Acked-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index b458667..059af81 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -356,7 +356,8 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev, return ret; } -static void pxa2xx_ac97_remove(struct platform_device *pdev) +static void pxa2xx_ac97_remove(struct platform_device *pdev, + struct snd_soc_dai *dai) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); -- cgit v0.10.2 From bf41534506a0572c06c8f34d12aa489be4c8780e Mon Sep 17 00:00:00 2001 From: Richard Chan Date: Wed, 9 Jul 2008 19:39:07 +0200 Subject: ALSA: Add Yamaha KX49 (USB MIDI controller) to usbquirks.h This patch is for the Yamaha USB MIDI controller KX49. http://www.yamahasynth.com/products/kx/index.html It has a 3-port MIDI interface and an HID interface (it has a tiny keyboard subset). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index b7ab3ee..d675050 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -210,6 +210,7 @@ YAMAHA_DEVICE(0x1042, NULL), YAMAHA_DEVICE(0x1043, NULL), YAMAHA_DEVICE(0x1044, NULL), YAMAHA_DEVICE(0x1045, NULL), +YAMAHA_DEVICE(0x104e, "KX49"), YAMAHA_DEVICE(0x2000, "DGP-7"), YAMAHA_DEVICE(0x2001, "DGP-5"), YAMAHA_DEVICE(0x2002, NULL), -- cgit v0.10.2 From 4a161d235b68eb7234f40106560c488a1bdb3851 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 9 Jul 2008 16:27:56 +0200 Subject: ALSA: ASoC: Au12x0/Au1550 PSC Audio support Audio for Au12x0/Au1550 PSCs in AC97 and I2S mode, for ASoC v1 framework. - DBDMA, AC97 and I2S drivers - sample AC97 machine code (Db1200) Signed-off-by: Manuel Lauss Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/asm-mips/mach-au1x00/au1xxx_psc.h b/include/asm-mips/mach-au1x00/au1xxx_psc.h index dae4eca..892b7f1 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_psc.h +++ b/include/asm-mips/mach-au1x00/au1xxx_psc.h @@ -204,6 +204,14 @@ typedef struct psc_i2s { u32 psc_i2sudf; } psc_i2s_t; +#define PSC_I2SCFG_OFFSET 0x08 +#define PSC_I2SMASK_OFFSET 0x0C +#define PSC_I2SPCR_OFFSET 0x10 +#define PSC_I2SSTAT_OFFSET 0x14 +#define PSC_I2SEVENT_OFFSET 0x18 +#define PSC_I2SRXTX_OFFSET 0x1C +#define PSC_I2SUDF_OFFSET 0x20 + /* I2S Config Register. */ #define PSC_I2SCFG_RT_MASK (3 << 30) #define PSC_I2SCFG_RT_FIFO1 (0 << 30) diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index b939e22..f743530 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -24,6 +24,7 @@ config SND_SOC_AC97_BUS # All the supported Soc's source "sound/soc/at32/Kconfig" source "sound/soc/at91/Kconfig" +source "sound/soc/au1x/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" source "sound/soc/sh/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 3645f95..933a66d 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -2,4 +2,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ -obj-$(CONFIG_SND_SOC) += omap/ +obj-$(CONFIG_SND_SOC) += omap/ au1x/ diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig new file mode 100644 index 0000000..410a893 --- /dev/null +++ b/sound/soc/au1x/Kconfig @@ -0,0 +1,32 @@ +## +## Au1200/Au1550 PSC + DBDMA +## +config SND_SOC_AU1XPSC + tristate "SoC Audio for Au1200/Au1250/Au1550" + depends on SOC_AU1200 || SOC_AU1550 + help + This option enables support for the Programmable Serial + Controllers in AC97 and I2S mode, and the Descriptor-Based DMA + Controller (DBDMA) as found on the Au1200/Au1250/Au1550 SoC. + +config SND_SOC_AU1XPSC_I2S + tristate + +config SND_SOC_AU1XPSC_AC97 + tristate + select AC97_BUS + select SND_AC97_CODEC + select SND_SOC_AC97_BUS + + +## +## Boards +## +config SND_SOC_SAMPLE_PSC_AC97 + tristate "Sample Au12x0/Au1550 PSC AC97 sound machine" + depends on SND_SOC_AU1XPSC + select SND_SOC_AU1XPSC_AC97 + select SND_SOC_AC97_CODEC + help + This is a sample AC97 sound machine for use in Au12x0/Au1550 + based systems which have audio on PSC1 (e.g. Db1200 demoboard). diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile new file mode 100644 index 0000000..6c6950b --- /dev/null +++ b/sound/soc/au1x/Makefile @@ -0,0 +1,13 @@ +# Au1200/Au1550 PSC audio +snd-soc-au1xpsc-dbdma-objs := dbdma2.o +snd-soc-au1xpsc-i2s-objs := psc-i2s.o +snd-soc-au1xpsc-ac97-objs := psc-ac97.o + +obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o +obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o +obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o + +# Boards +snd-soc-sample-ac97-objs := sample-ac97.o + +obj-$(CONFIG_SND_SOC_SAMPLE_PSC_AC97) += snd-soc-sample-ac97.o diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c new file mode 100644 index 0000000..1466d93 --- /dev/null +++ b/sound/soc/au1x/dbdma2.c @@ -0,0 +1,421 @@ +/* + * Au12x0/Au1550 PSC ALSA ASoC audio support. + * + * (c) 2007-2008 MSC Vertriebsges.m.b.H., + * Manuel Lauss + * + * 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 glue for Au1x-PSC audio. + * + * NOTE: all of these drivers can only work with a SINGLE instance + * of a PSC. Multiple independent audio devices are impossible + * with ASoC v1. + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "psc.h" + +/*#define PCM_DEBUG*/ + +#define MSG(x...) printk(KERN_INFO "au1xpsc_pcm: " x) +#ifdef PCM_DEBUG +#define DBG MSG +#else +#define DBG(x...) do {} while (0) +#endif + +struct au1xpsc_audio_dmadata { + /* DDMA control data */ + unsigned int ddma_id; /* DDMA direction ID for this PSC */ + u32 ddma_chan; /* DDMA context */ + + /* PCM context (for irq handlers) */ + struct snd_pcm_substream *substream; + unsigned long curr_period; /* current segment DDMA is working on */ + unsigned long q_period; /* queue period(s) */ + unsigned long dma_area; /* address of queued DMA area */ + unsigned long dma_area_s; /* start address of DMA area */ + unsigned long pos; /* current byte position being played */ + unsigned long periods; /* number of SG segments in total */ + unsigned long period_bytes; /* size in bytes of one SG segment */ + + /* runtime data */ + int msbits; +}; + +/* instance data. There can be only one, MacLeod!!!! */ +static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2]; + +/* + * These settings are somewhat okay, at least on my machine audio plays + * almost skip-free. Especially the 64kB buffer seems to help a LOT. + */ +#define AU1XPSC_PERIOD_MIN_BYTES 1024 +#define AU1XPSC_BUFFER_MIN_BYTES 65536 + +#define AU1XPSC_PCM_FMTS \ + (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ + SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ + SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \ + SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \ + 0) + +/* PCM hardware DMA capabilities - platform specific */ +static const struct snd_pcm_hardware au1xpsc_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED, + .formats = AU1XPSC_PCM_FMTS, + .period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES, + .period_bytes_max = 4096 * 1024 - 1, + .periods_min = 2, + .periods_max = 4096, /* 2 to as-much-as-you-like */ + .buffer_bytes_max = 4096 * 1024 - 1, + .fifo_size = 16, /* fifo entries of AC97/I2S PSC */ +}; + +static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) +{ + au1xxx_dbdma_put_source_flags(cd->ddma_chan, + (void *)phys_to_virt(cd->dma_area), + cd->period_bytes, DDMA_FLAGS_IE); + + /* update next-to-queue period */ + ++cd->q_period; + cd->dma_area += cd->period_bytes; + if (cd->q_period >= cd->periods) { + cd->q_period = 0; + cd->dma_area = cd->dma_area_s; + } +} + +static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd) +{ + au1xxx_dbdma_put_dest_flags(cd->ddma_chan, + (void *)phys_to_virt(cd->dma_area), + cd->period_bytes, DDMA_FLAGS_IE); + + /* update next-to-queue period */ + ++cd->q_period; + cd->dma_area += cd->period_bytes; + if (cd->q_period >= cd->periods) { + cd->q_period = 0; + cd->dma_area = cd->dma_area_s; + } +} + +static void au1x_pcm_dmatx_cb(int irq, void *dev_id) +{ + struct au1xpsc_audio_dmadata *cd = dev_id; + + cd->pos += cd->period_bytes; + if (++cd->curr_period >= cd->periods) { + cd->pos = 0; + cd->curr_period = 0; + } + snd_pcm_period_elapsed(cd->substream); + au1x_pcm_queue_tx(cd); +} + +static void au1x_pcm_dmarx_cb(int irq, void *dev_id) +{ + struct au1xpsc_audio_dmadata *cd = dev_id; + + cd->pos += cd->period_bytes; + if (++cd->curr_period >= cd->periods) { + cd->pos = 0; + cd->curr_period = 0; + } + snd_pcm_period_elapsed(cd->substream); + au1x_pcm_queue_rx(cd); +} + +static void au1x_pcm_dbdma_free(struct au1xpsc_audio_dmadata *pcd) +{ + if (pcd->ddma_chan) { + au1xxx_dbdma_stop(pcd->ddma_chan); + au1xxx_dbdma_reset(pcd->ddma_chan); + au1xxx_dbdma_chan_free(pcd->ddma_chan); + pcd->ddma_chan = 0; + pcd->msbits = 0; + } +} + +/* in case of missing DMA ring or changed TX-source / RX-dest bit widths, + * allocate (or reallocate) a 2-descriptor DMA ring with bit depth according + * to ALSA-supplied sample depth. This is due to limitations in the dbdma api + * (cannot adjust source/dest widths of already allocated descriptor ring). + */ +static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd, + int stype, int msbits) +{ + /* DMA only in 8/16/32 bit widths */ + if (msbits == 24) + msbits = 32; + + /* check current config: correct bits and descriptors allocated? */ + if ((pcd->ddma_chan) && (msbits == pcd->msbits)) + goto out; /* all ok! */ + + au1x_pcm_dbdma_free(pcd); + + if (stype == PCM_RX) + pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id, + DSCR_CMD0_ALWAYS, + au1x_pcm_dmarx_cb, (void *)pcd); + else + pcd->ddma_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS, + pcd->ddma_id, + au1x_pcm_dmatx_cb, (void *)pcd); + + if (!pcd->ddma_chan) + return -ENOMEM;; + + au1xxx_dbdma_set_devwidth(pcd->ddma_chan, msbits); + au1xxx_dbdma_ring_alloc(pcd->ddma_chan, 2); + + pcd->msbits = msbits; + + au1xxx_dbdma_stop(pcd->ddma_chan); + au1xxx_dbdma_reset(pcd->ddma_chan); + +out: + return 0; +} + +static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct au1xpsc_audio_dmadata *pcd; + int stype, ret; + + ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); + if (ret < 0) + goto out; + + stype = SUBSTREAM_TYPE(substream); + pcd = au1xpsc_audio_pcmdma[stype]; + + DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " + "runtime->min_align %d\n", + (unsigned long)runtime->dma_area, + (unsigned long)runtime->dma_addr, runtime->dma_bytes, + runtime->min_align); + + DBG("bits %d frags %d frag_bytes %d is_rx %d\n", params->msbits, + params_periods(params), params_period_bytes(params), stype); + + ret = au1x_pcm_dbdma_realloc(pcd, stype, params->msbits); + if (ret) { + MSG("DDMA channel (re)alloc failed!\n"); + goto out; + } + + pcd->substream = substream; + pcd->period_bytes = params_period_bytes(params); + pcd->periods = params_periods(params); + pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr; + pcd->q_period = 0; + pcd->curr_period = 0; + pcd->pos = 0; + + ret = 0; +out: + return ret; +} + +static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream) +{ + snd_pcm_lib_free_pages(substream); + return 0; +} + +static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct au1xpsc_audio_dmadata *pcd = + au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]; + + au1xxx_dbdma_reset(pcd->ddma_chan); + + if (SUBSTREAM_TYPE(substream) == PCM_RX) { + au1x_pcm_queue_rx(pcd); + au1x_pcm_queue_rx(pcd); + } else { + au1x_pcm_queue_tx(pcd); + au1x_pcm_queue_tx(pcd); + } + + return 0; +} + +static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + u32 c = au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->ddma_chan; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + au1xxx_dbdma_start(c); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + au1xxx_dbdma_stop(c); + break; + default: + return -EINVAL; + } + return 0; +} + +static snd_pcm_uframes_t +au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) +{ + return bytes_to_frames(substream->runtime, + au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->pos); +} + +static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) +{ + snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); + return 0; +} + +static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) +{ + au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]); + return 0; +} + +struct snd_pcm_ops au1xpsc_pcm_ops = { + .open = au1xpsc_pcm_open, + .close = au1xpsc_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = au1xpsc_pcm_hw_params, + .hw_free = au1xpsc_pcm_hw_free, + .prepare = au1xpsc_pcm_prepare, + .trigger = au1xpsc_pcm_trigger, + .pointer = au1xpsc_pcm_pointer, +}; + +static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm) +{ + snd_pcm_lib_preallocate_free_for_all(pcm); +} + +static int au1xpsc_pcm_new(struct snd_card *card, + struct snd_soc_dai *dai, + struct snd_pcm *pcm) +{ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + card->dev, AU1XPSC_BUFFER_MIN_BYTES, (4096 * 1024) - 1); + + return 0; +} + +static int au1xpsc_pcm_probe(struct platform_device *pdev) +{ + struct resource *r; + int ret; + + if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX]) + return -EBUSY; + + /* TX DMA */ + au1xpsc_audio_pcmdma[PCM_TX] + = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); + if (!au1xpsc_audio_pcmdma[PCM_TX]) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!r) { + ret = -ENODEV; + goto out1; + } + (au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start; + + /* RX DMA */ + au1xpsc_audio_pcmdma[PCM_RX] + = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); + if (!au1xpsc_audio_pcmdma[PCM_RX]) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!r) { + ret = -ENODEV; + goto out2; + } + (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; + + return 0; + +out2: + kfree(au1xpsc_audio_pcmdma[PCM_RX]); + au1xpsc_audio_pcmdma[PCM_RX] = NULL; +out1: + kfree(au1xpsc_audio_pcmdma[PCM_TX]); + au1xpsc_audio_pcmdma[PCM_TX] = NULL; + return ret; +} + +static int au1xpsc_pcm_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < 2; i++) { + if (au1xpsc_audio_pcmdma[i]) { + au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); + kfree(au1xpsc_audio_pcmdma[i]); + au1xpsc_audio_pcmdma[i] = NULL; + } + } + + return 0; +} + +/* au1xpsc audio platform */ +struct snd_soc_platform au1xpsc_soc_platform = { + .name = "au1xpsc-pcm-dbdma", + .probe = au1xpsc_pcm_probe, + .remove = au1xpsc_pcm_remove, + .pcm_ops = &au1xpsc_pcm_ops, + .pcm_new = au1xpsc_pcm_new, + .pcm_free = au1xpsc_pcm_free_dma_buffers, +}; +EXPORT_SYMBOL_GPL(au1xpsc_soc_platform); + +static int __init au1xpsc_audio_dbdma_init(void) +{ + au1xpsc_audio_pcmdma[PCM_TX] = NULL; + au1xpsc_audio_pcmdma[PCM_RX] = NULL; + return 0; +} + +static void __exit au1xpsc_audio_dbdma_exit(void) +{ +} + +module_init(au1xpsc_audio_dbdma_init); +module_exit(au1xpsc_audio_dbdma_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); +MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c new file mode 100644 index 0000000..57facba --- /dev/null +++ b/sound/soc/au1x/psc-ac97.c @@ -0,0 +1,387 @@ +/* + * Au12x0/Au1550 PSC ALSA ASoC audio support. + * + * (c) 2007-2008 MSC Vertriebsges.m.b.H., + * Manuel Lauss + * + * 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. + * + * Au1xxx-PSC AC97 glue. + * + * NOTE: all of these drivers can only work with a SINGLE instance + * of a PSC. Multiple independent audio devices are impossible + * with ASoC v1. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "psc.h" + +#define AC97_DIR \ + (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) + +#define AC97_RATES \ + SNDRV_PCM_RATE_8000_48000 + +#define AC97_FMTS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE) + +#define AC97PCR_START(stype) \ + ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS) +#define AC97PCR_STOP(stype) \ + ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP) +#define AC97PCR_CLRFIFO(stype) \ + ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) + +/* instance data. There can be only one, MacLeod!!!! */ +static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; + +/* AC97 controller reads codec register */ +static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, + unsigned short reg) +{ + /* FIXME */ + struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + unsigned short data, tmo; + + au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), AC97_CDC(pscdata)); + au_sync(); + + tmo = 1000; + while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo) + udelay(2); + + if (!tmo) + data = 0xffff; + else + data = au_readl(AC97_CDC(pscdata)) & 0xffff; + + au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); + au_sync(); + + return data; +} + +/* AC97 controller writes to codec register */ +static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, + unsigned short val) +{ + /* FIXME */ + struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + unsigned int tmo; + + au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), AC97_CDC(pscdata)); + au_sync(); + tmo = 1000; + while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo) + au_sync(); + + au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); + au_sync(); +} + +/* AC97 controller asserts a warm reset */ +static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) +{ + /* FIXME */ + struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + + au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); + au_sync(); + msleep(10); + au_writel(0, AC97_RST(pscdata)); + au_sync(); +} + +static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) +{ + /* FIXME */ + struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + int i; + + /* disable PSC during cold reset */ + au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); + au_sync(); + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata)); + au_sync(); + + /* issue cold reset */ + au_writel(PSC_AC97RST_RST, AC97_RST(pscdata)); + au_sync(); + msleep(500); + au_writel(0, AC97_RST(pscdata)); + au_sync(); + + /* enable PSC */ + au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); + au_sync(); + + /* wait for PSC to indicate it's ready */ + i = 100000; + while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) + au_sync(); + + if (i == 0) { + printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n"); + return; + } + + /* enable the ac97 function */ + au_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); + au_sync(); + + /* wait for AC97 core to become ready */ + i = 100000; + while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) + au_sync(); + if (i == 0) + printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); +} + +/* AC97 controller operations */ +struct snd_ac97_bus_ops soc_ac97_ops = { + .read = au1xpsc_ac97_read, + .write = au1xpsc_ac97_write, + .reset = au1xpsc_ac97_cold_reset, + .warm_reset = au1xpsc_ac97_warm_reset, +}; +EXPORT_SYMBOL_GPL(soc_ac97_ops); + +static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + /* FIXME */ + struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + unsigned long r, stat; + int chans, stype = SUBSTREAM_TYPE(substream); + + chans = params_channels(params); + + r = au_readl(AC97_CFG(pscdata)); + stat = au_readl(AC97_STAT(pscdata)); + + /* already active? */ + if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) { + /* reject parameters not currently set up */ + if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) || + (pscdata->rate != params_rate(params))) + return -EINVAL; + } else { + /* disable AC97 device controller first */ + au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); + au_sync(); + + /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */ + r &= ~PSC_AC97CFG_LEN_MASK; + r |= PSC_AC97CFG_SET_LEN(params->msbits); + + /* channels: enable slots for front L/R channel */ + if (stype == PCM_TX) { + r &= ~PSC_AC97CFG_TXSLOT_MASK; + r |= PSC_AC97CFG_TXSLOT_ENA(3); + r |= PSC_AC97CFG_TXSLOT_ENA(4); + } else { + r &= ~PSC_AC97CFG_RXSLOT_MASK; + r |= PSC_AC97CFG_RXSLOT_ENA(3); + r |= PSC_AC97CFG_RXSLOT_ENA(4); + } + + /* finally enable the AC97 controller again */ + au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); + au_sync(); + + pscdata->cfg = r; + pscdata->rate = params_rate(params); + } + + return 0; +} + +static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + /* FIXME */ + struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + int ret, stype = SUBSTREAM_TYPE(substream); + + ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + au_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); + au_sync(); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); + au_sync(); + break; + default: + ret = -EINVAL; + } + return ret; +} + +static int au1xpsc_ac97_probe(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + int ret; + struct resource *r; + unsigned long sel; + + if (au1xpsc_ac97_workdata) + return -EBUSY; + + au1xpsc_ac97_workdata = + kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); + if (!au1xpsc_ac97_workdata) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + ret = -ENODEV; + goto out0; + } + + ret = -EBUSY; + au1xpsc_ac97_workdata->ioarea = + request_mem_region(r->start, r->end - r->start + 1, + "au1xpsc_ac97"); + if (!au1xpsc_ac97_workdata->ioarea) + goto out0; + + au1xpsc_ac97_workdata->mmio = ioremap(r->start, 0xffff); + if (!au1xpsc_ac97_workdata->mmio) + goto out1; + + /* configuration: max dma trigger threshold, enable ac97 */ + au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | + PSC_AC97CFG_TT_FIFO8 | + PSC_AC97CFG_DE_ENABLE; + + /* preserve PSC clock source set up by platform (dev.platform_data + * is already occupied by soc layer) + */ + sel = au_readl(PSC_SEL(au1xpsc_ac97_workdata)) & PSC_SEL_CLK_MASK; + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); + au_sync(); + au_writel(0, PSC_SEL(au1xpsc_ac97_workdata)); + au_sync(); + au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(au1xpsc_ac97_workdata)); + au_sync(); + /* next up: cold reset. Dont check for PSC-ready now since + * there may not be any codec clock yet. + */ + + return 0; + +out1: + release_resource(au1xpsc_ac97_workdata->ioarea); + kfree(au1xpsc_ac97_workdata->ioarea); +out0: + kfree(au1xpsc_ac97_workdata); + au1xpsc_ac97_workdata = NULL; + return ret; +} + +static void au1xpsc_ac97_remove(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + /* disable PSC completely */ + au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); + au_sync(); + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); + au_sync(); + + iounmap(au1xpsc_ac97_workdata->mmio); + release_resource(au1xpsc_ac97_workdata->ioarea); + kfree(au1xpsc_ac97_workdata->ioarea); + kfree(au1xpsc_ac97_workdata); + au1xpsc_ac97_workdata = NULL; +} + +static int au1xpsc_ac97_suspend(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + /* save interesting registers and disable PSC */ + au1xpsc_ac97_workdata->pm[0] = + au_readl(PSC_SEL(au1xpsc_ac97_workdata)); + + au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); + au_sync(); + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); + au_sync(); + + return 0; +} + +static int au1xpsc_ac97_resume(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + /* restore PSC clock config */ + au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, + PSC_SEL(au1xpsc_ac97_workdata)); + au_sync(); + + /* after this point the ac97 core will cold-reset the codec. + * During cold-reset the PSC is reinitialized and the last + * configuration set up in hw_params() is restored. + */ + return 0; +} + +struct snd_soc_dai au1xpsc_ac97_dai = { + .name = "au1xpsc_ac97", + .type = SND_SOC_DAI_AC97, + .probe = au1xpsc_ac97_probe, + .remove = au1xpsc_ac97_remove, + .suspend = au1xpsc_ac97_suspend, + .resume = au1xpsc_ac97_resume, + .playback = { + .rates = AC97_RATES, + .formats = AC97_FMTS, + .channels_min = 2, + .channels_max = 2, + }, + .capture = { + .rates = AC97_RATES, + .formats = AC97_FMTS, + .channels_min = 2, + .channels_max = 2, + }, + .ops = { + .trigger = au1xpsc_ac97_trigger, + .hw_params = au1xpsc_ac97_hw_params, + }, +}; +EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai); + +static int __init au1xpsc_ac97_init(void) +{ + au1xpsc_ac97_workdata = NULL; + return 0; +} + +static void __exit au1xpsc_ac97_exit(void) +{ +} + +module_init(au1xpsc_ac97_init); +module_exit(au1xpsc_ac97_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); +MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c new file mode 100644 index 0000000..ba4b5c1 --- /dev/null +++ b/sound/soc/au1x/psc-i2s.c @@ -0,0 +1,414 @@ +/* + * Au12x0/Au1550 PSC ALSA ASoC audio support. + * + * (c) 2007-2008 MSC Vertriebsges.m.b.H., + * Manuel Lauss + * + * 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. + * + * Au1xxx-PSC I2S glue. + * + * NOTE: all of these drivers can only work with a SINGLE instance + * of a PSC. Multiple independent audio devices are impossible + * with ASoC v1. + * NOTE: so far only PSC slave mode (bit- and frameclock) is supported. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "psc.h" + +/* supported I2S DAI hardware formats */ +#define AU1XPSC_I2S_DAIFMT \ + (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | \ + SND_SOC_DAIFMT_NB_NF) + +/* supported I2S direction */ +#define AU1XPSC_I2S_DIR \ + (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) + +#define AU1XPSC_I2S_RATES \ + SNDRV_PCM_RATE_8000_192000 + +#define AU1XPSC_I2S_FMTS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +#define I2SSTAT_BUSY(stype) \ + ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB) +#define I2SPCR_START(stype) \ + ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS) +#define I2SPCR_STOP(stype) \ + ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP) +#define I2SPCR_CLRFIFO(stype) \ + ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) + + +/* instance data. There can be only one, MacLeod!!!! */ +static struct au1xpsc_audio_data *au1xpsc_i2s_workdata; + +static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; + unsigned long ct; + int ret; + + ret = -EINVAL; + + ct = pscdata->cfg; + + ct &= ~(PSC_I2SCFG_XM | PSC_I2SCFG_MLJ); /* left-justified */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + ct |= PSC_I2SCFG_XM; /* enable I2S mode */ + break; + case SND_SOC_DAIFMT_MSB: + break; + case SND_SOC_DAIFMT_LSB: + ct |= PSC_I2SCFG_MLJ; /* LSB (right-) justified */ + break; + default: + goto out; + } + + ct &= ~(PSC_I2SCFG_BI | PSC_I2SCFG_WI); /* IB-IF */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + ct |= PSC_I2SCFG_BI | PSC_I2SCFG_WI; + break; + case SND_SOC_DAIFMT_NB_IF: + ct |= PSC_I2SCFG_BI; + break; + case SND_SOC_DAIFMT_IB_NF: + ct |= PSC_I2SCFG_WI; + break; + case SND_SOC_DAIFMT_IB_IF: + break; + default: + goto out; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: /* CODEC master */ + ct |= PSC_I2SCFG_MS; /* PSC I2S slave mode */ + break; + case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */ + ct &= ~PSC_I2SCFG_MS; /* PSC I2S Master mode */ + break; + default: + goto out; + } + + pscdata->cfg = ct; + ret = 0; +out: + return ret; +} + +static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; + + int cfgbits; + unsigned long stat; + + /* check if the PSC is already streaming data */ + stat = au_readl(I2S_STAT(pscdata)); + if (stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB)) { + /* reject parameters not currently set up in hardware */ + cfgbits = au_readl(I2S_CFG(pscdata)); + if ((PSC_I2SCFG_GET_LEN(cfgbits) != params->msbits) || + (params_rate(params) != pscdata->rate)) + return -EINVAL; + } else { + /* set sample bitdepth */ + pscdata->cfg &= ~(0x1f << 4); + pscdata->cfg |= PSC_I2SCFG_SET_LEN(params->msbits); + /* remember current rate for other stream */ + pscdata->rate = params_rate(params); + } + return 0; +} + +/* Configure PSC late: on my devel systems the codec is I2S master and + * supplies the i2sbitclock __AND__ i2sMclk (!) to the PSC unit. ASoC + * uses aggressive PM and switches the codec off when it is not in use + * which also means the PSC unit doesn't get any clocks and is therefore + * dead. That's why this chunk here gets called from the trigger callback + * because I can be reasonably certain the codec is driving the clocks. + */ +static int au1xpsc_i2s_configure(struct au1xpsc_audio_data *pscdata) +{ + unsigned long tmo; + + /* bring PSC out of sleep, and configure I2S unit */ + au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); + au_sync(); + + tmo = 1000000; + while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo) + tmo--; + + if (!tmo) + goto psc_err; + + au_writel(0, I2S_CFG(pscdata)); + au_sync(); + au_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata)); + au_sync(); + + /* wait for I2S controller to become ready */ + tmo = 1000000; + while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo) + tmo--; + + if (tmo) + return 0; + +psc_err: + au_writel(0, I2S_CFG(pscdata)); + au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); + au_sync(); + return -ETIMEDOUT; +} + +static int au1xpsc_i2s_start(struct au1xpsc_audio_data *pscdata, int stype) +{ + unsigned long tmo, stat; + int ret; + + ret = 0; + + /* if both TX and RX are idle, configure the PSC */ + stat = au_readl(I2S_STAT(pscdata)); + if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { + ret = au1xpsc_i2s_configure(pscdata); + if (ret) + goto out; + } + + au_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata)); + au_sync(); + au_writel(I2SPCR_START(stype), I2S_PCR(pscdata)); + au_sync(); + + /* wait for start confirmation */ + tmo = 1000000; + while (!(au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) + tmo--; + + if (!tmo) { + au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); + au_sync(); + ret = -ETIMEDOUT; + } +out: + return ret; +} + +static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype) +{ + unsigned long tmo, stat; + + au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); + au_sync(); + + /* wait for stop confirmation */ + tmo = 1000000; + while ((au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) + tmo--; + + /* if both TX and RX are idle, disable PSC */ + stat = au_readl(I2S_STAT(pscdata)); + if (!(stat & (PSC_I2SSTAT_RB | PSC_I2SSTAT_RB))) { + au_writel(0, I2S_CFG(pscdata)); + au_sync(); + au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); + au_sync(); + } + return 0; +} + +static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; + int ret, stype = SUBSTREAM_TYPE(substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + ret = au1xpsc_i2s_start(pscdata, stype); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + ret = au1xpsc_i2s_stop(pscdata, stype); + break; + default: + ret = -EINVAL; + } + return ret; +} + +static int au1xpsc_i2s_probe(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + struct resource *r; + unsigned long sel; + int ret; + + if (au1xpsc_i2s_workdata) + return -EBUSY; + + au1xpsc_i2s_workdata = + kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); + if (!au1xpsc_i2s_workdata) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + ret = -ENODEV; + goto out0; + } + + ret = -EBUSY; + au1xpsc_i2s_workdata->ioarea = + request_mem_region(r->start, r->end - r->start + 1, + "au1xpsc_i2s"); + if (!au1xpsc_i2s_workdata->ioarea) + goto out0; + + au1xpsc_i2s_workdata->mmio = ioremap(r->start, 0xffff); + if (!au1xpsc_i2s_workdata->mmio) + goto out1; + + /* preserve PSC clock source set up by platform (dev.platform_data + * is already occupied by soc layer) + */ + sel = au_readl(PSC_SEL(au1xpsc_i2s_workdata)) & PSC_SEL_CLK_MASK; + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); + au_sync(); + au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(au1xpsc_i2s_workdata)); + au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); + au_sync(); + + /* preconfigure: set max rx/tx fifo depths */ + au1xpsc_i2s_workdata->cfg |= + PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8; + + /* don't wait for I2S core to become ready now; clocks may not + * be running yet; depending on clock input for PSC a wait might + * time out. + */ + + return 0; + +out1: + release_resource(au1xpsc_i2s_workdata->ioarea); + kfree(au1xpsc_i2s_workdata->ioarea); +out0: + kfree(au1xpsc_i2s_workdata); + au1xpsc_i2s_workdata = NULL; + return ret; +} + +static void au1xpsc_i2s_remove(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); + au_sync(); + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); + au_sync(); + + iounmap(au1xpsc_i2s_workdata->mmio); + release_resource(au1xpsc_i2s_workdata->ioarea); + kfree(au1xpsc_i2s_workdata->ioarea); + kfree(au1xpsc_i2s_workdata); + au1xpsc_i2s_workdata = NULL; +} + +static int au1xpsc_i2s_suspend(struct platform_device *pdev, + struct snd_soc_dai *cpu_dai) +{ + /* save interesting register and disable PSC */ + au1xpsc_i2s_workdata->pm[0] = + au_readl(PSC_SEL(au1xpsc_i2s_workdata)); + + au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); + au_sync(); + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); + au_sync(); + + return 0; +} + +static int au1xpsc_i2s_resume(struct platform_device *pdev, + struct snd_soc_dai *cpu_dai) +{ + /* select I2S mode and PSC clock */ + au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); + au_sync(); + au_writel(0, PSC_SEL(au1xpsc_i2s_workdata)); + au_sync(); + au_writel(au1xpsc_i2s_workdata->pm[0], + PSC_SEL(au1xpsc_i2s_workdata)); + au_sync(); + + return 0; +} + +struct snd_soc_dai au1xpsc_i2s_dai = { + .name = "au1xpsc_i2s", + .type = SND_SOC_DAI_I2S, + .probe = au1xpsc_i2s_probe, + .remove = au1xpsc_i2s_remove, + .suspend = au1xpsc_i2s_suspend, + .resume = au1xpsc_i2s_resume, + .playback = { + .rates = AU1XPSC_I2S_RATES, + .formats = AU1XPSC_I2S_FMTS, + .channels_min = 2, + .channels_max = 8, /* 2 without external help */ + }, + .capture = { + .rates = AU1XPSC_I2S_RATES, + .formats = AU1XPSC_I2S_FMTS, + .channels_min = 2, + .channels_max = 8, /* 2 without external help */ + }, + .ops = { + .trigger = au1xpsc_i2s_trigger, + .hw_params = au1xpsc_i2s_hw_params, + }, + .dai_ops = { + .set_fmt = au1xpsc_i2s_set_fmt, + }, +}; +EXPORT_SYMBOL(au1xpsc_i2s_dai); + +static int __init au1xpsc_i2s_init(void) +{ + au1xpsc_i2s_workdata = NULL; + return 0; +} + +static void __exit au1xpsc_i2s_exit(void) +{ +} + +module_init(au1xpsc_i2s_init); +module_exit(au1xpsc_i2s_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver"); +MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h new file mode 100644 index 0000000..8fdb1a0 --- /dev/null +++ b/sound/soc/au1x/psc.h @@ -0,0 +1,53 @@ +/* + * Au12x0/Au1550 PSC ALSA ASoC audio support. + * + * (c) 2007-2008 MSC Vertriebsges.m.b.H., + * Manuel Lauss + * + * 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: all of these drivers can only work with a SINGLE instance + * of a PSC. Multiple independent audio devices are impossible + * with ASoC v1. + */ + +#ifndef _AU1X_PCM_H +#define _AU1X_PCM_H + +extern struct snd_soc_dai au1xpsc_ac97_dai; +extern struct snd_soc_dai au1xpsc_i2s_dai; +extern struct snd_soc_platform au1xpsc_soc_platform; +extern struct snd_ac97_bus_ops soc_ac97_ops; + +struct au1xpsc_audio_data { + void __iomem *mmio; + + unsigned long cfg; + unsigned long rate; + + unsigned long pm[2]; + struct resource *ioarea; +}; + +#define PCM_TX 0 +#define PCM_RX 1 + +#define SUBSTREAM_TYPE(substream) \ + ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX) + +/* easy access macros */ +#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) +#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) +#define I2S_STAT(x) ((unsigned long)((x)->mmio) + PSC_I2SSTAT_OFFSET) +#define I2S_CFG(x) ((unsigned long)((x)->mmio) + PSC_I2SCFG_OFFSET) +#define I2S_PCR(x) ((unsigned long)((x)->mmio) + PSC_I2SPCR_OFFSET) +#define AC97_CFG(x) ((unsigned long)((x)->mmio) + PSC_AC97CFG_OFFSET) +#define AC97_CDC(x) ((unsigned long)((x)->mmio) + PSC_AC97CDC_OFFSET) +#define AC97_EVNT(x) ((unsigned long)((x)->mmio) + PSC_AC97EVNT_OFFSET) +#define AC97_PCR(x) ((unsigned long)((x)->mmio) + PSC_AC97PCR_OFFSET) +#define AC97_RST(x) ((unsigned long)((x)->mmio) + PSC_AC97RST_OFFSET) +#define AC97_STAT(x) ((unsigned long)((x)->mmio) + PSC_AC97STAT_OFFSET) + +#endif diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c new file mode 100644 index 0000000..f75ae7f --- /dev/null +++ b/sound/soc/au1x/sample-ac97.c @@ -0,0 +1,144 @@ +/* + * Sample Au12x0/Au1550 PSC AC97 sound machine. + * + * Copyright (c) 2007-2008 Manuel Lauss + * + * This program is free software; you can redistribute it and/or modify + * it under the terms outlined in the file COPYING at the root of this + * source archive. + * + * This is a very generic AC97 sound machine driver for boards which + * have (AC97) audio at PSC1 (e.g. DB1200 demoboards). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../codecs/ac97.h" +#include "psc.h" + +static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec) +{ + snd_soc_dapm_sync(codec); + return 0; +} + +static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = { + .name = "AC97", + .stream_name = "AC97 HiFi", + .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */ + .codec_dai = &ac97_dai, /* see codecs/ac97.c */ + .init = au1xpsc_sample_ac97_init, + .ops = NULL, +}; + +static struct snd_soc_machine au1xpsc_sample_ac97_machine = { + .name = "Au1xxx PSC AC97 Audio", + .dai_link = &au1xpsc_sample_ac97_dai, + .num_links = 1, +}; + +static struct snd_soc_device au1xpsc_sample_ac97_devdata = { + .machine = &au1xpsc_sample_ac97_machine, + .platform = &au1xpsc_soc_platform, /* see dbdma2.c */ + .codec_dev = &soc_codec_dev_ac97, +}; + +static struct resource au1xpsc_psc1_res[] = { + [0] = { + .start = CPHYSADDR(PSC1_BASE_ADDR), + .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { +#ifdef CONFIG_SOC_AU1200 + .start = AU1200_PSC1_INT, + .end = AU1200_PSC1_INT, +#elif defined(CONFIG_SOC_AU1550) + .start = AU1550_PSC1_INT, + .end = AU1550_PSC1_INT, +#endif + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = DSCR_CMD0_PSC1_TX, + .end = DSCR_CMD0_PSC1_TX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DSCR_CMD0_PSC1_RX, + .end = DSCR_CMD0_PSC1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device *au1xpsc_sample_ac97_dev; + +static int __init au1xpsc_sample_ac97_load(void) +{ + int ret; + +#ifdef CONFIG_SOC_AU1200 + unsigned long io; + + /* modify sys_pinfunc for AC97 on PSC1 */ + io = au_readl(SYS_PINFUNC); + io |= SYS_PINFUNC_P1C; + io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B); + au_writel(io, SYS_PINFUNC); + au_sync(); +#endif + + ret = -ENOMEM; + + /* setup PSC clock source for AC97 part: external clock provided + * by codec. The psc-ac97.c driver depends on this setting! + */ + au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET); + au_sync(); + + au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1); + if (!au1xpsc_sample_ac97_dev) + goto out; + + au1xpsc_sample_ac97_dev->resource = + kmemdup(au1xpsc_psc1_res, sizeof(struct resource) * + ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL); + au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res); + au1xpsc_sample_ac97_dev->id = 1; + + platform_set_drvdata(au1xpsc_sample_ac97_dev, + &au1xpsc_sample_ac97_devdata); + au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev; + ret = platform_device_add(au1xpsc_sample_ac97_dev); + + if (ret) { + platform_device_put(au1xpsc_sample_ac97_dev); + au1xpsc_sample_ac97_dev = NULL; + } + +out: + return ret; +} + +static void __exit au1xpsc_sample_ac97_exit(void) +{ + platform_device_unregister(au1xpsc_sample_ac97_dev); +} + +module_init(au1xpsc_sample_ac97_load); +module_exit(au1xpsc_sample_ac97_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine"); +MODULE_AUTHOR("Manuel Lauss "); -- cgit v0.10.2 From e93be88d7ec9d183c1cca51eabe040c051cdb687 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 10 Jul 2008 08:27:49 +0900 Subject: x86: clean up iommu.h and gart.h This remove lots of duplications in iommu.h and gart.h. The end result of this patch is: - iommu.h is a header file for everyone related with IOMMUs. - gart.h is the private header file. Only pci-gart_64.c and its friends include it. Signed-off-by: FUJITA Tomonori Cc: fujita.tomonori@lab.ntt.co.jp Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/gart.h b/include/asm-x86/gart.h index 417f76e..33b9aee 100644 --- a/include/asm-x86/gart.h +++ b/include/asm-x86/gart.h @@ -1,40 +1,14 @@ -#ifndef _ASM_X8664_IOMMU_H -#define _ASM_X8664_IOMMU_H 1 +#ifndef _ASM_X8664_GART_H +#define _ASM_X8664_GART_H 1 #include +#include -extern void pci_iommu_shutdown(void); -extern void no_iommu_init(void); -extern int force_iommu, no_iommu; -extern int iommu_detected; -extern int agp_amd64_init(void); -#ifdef CONFIG_GART_IOMMU -extern void gart_iommu_init(void); -extern void gart_iommu_shutdown(void); -extern void __init gart_parse_options(char *); -extern void early_gart_iommu_check(void); -extern void gart_iommu_hole_init(void); extern void set_up_gart_resume(u32, u32); + extern int fallback_aper_order; extern int fallback_aper_force; -extern int gart_iommu_aperture; -extern int gart_iommu_aperture_allowed; -extern int gart_iommu_aperture_disabled; extern int fix_aperture; -#else -#define gart_iommu_aperture 0 -#define gart_iommu_aperture_allowed 0 -#define gart_iommu_aperture_disabled 1 - -static inline void early_gart_iommu_check(void) -{ -} - -static inline void gart_iommu_shutdown(void) -{ -} - -#endif /* PTE bits. */ #define GPTE_VALID 1 diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h index cb7e989..068c9a4 100644 --- a/include/asm-x86/iommu.h +++ b/include/asm-x86/iommu.h @@ -1,29 +1,34 @@ -#ifndef _ASM_X8664_GART_H -#define _ASM_X8664_GART_H 1 +#ifndef _ASM_X8664_IOMMU_H +#define _ASM_X8664_IOMMU_H 1 extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); extern int force_iommu, no_iommu; extern int iommu_detected; + #ifdef CONFIG_GART_IOMMU +extern int gart_iommu_aperture; +extern int gart_iommu_aperture_allowed; +extern int gart_iommu_aperture_disabled; + +extern void early_gart_iommu_check(void); extern void gart_iommu_init(void); extern void gart_iommu_shutdown(void); extern void __init gart_parse_options(char *); -extern void iommu_hole_init(void); -extern int fallback_aper_order; -extern int fallback_aper_force; -extern int iommu_aperture; -extern int iommu_aperture_allowed; -extern int iommu_aperture_disabled; -extern int fix_aperture; +extern void gart_iommu_hole_init(void); + #else -#define iommu_aperture 0 -#define iommu_aperture_allowed 0 +#define gart_iommu_aperture 0 +#define gart_iommu_aperture_allowed 0 +#define gart_iommu_aperture_disabled 1 -static inline void gart_iommu_shutdown(void) +static inline void early_gart_iommu_check(void) { } +static inline void gart_iommu_shutdown(void) +{ +} #endif #endif -- cgit v0.10.2 From 18b743dc948aaddc46258b73f17bdec2ee4019ee Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 10 Jul 2008 09:50:50 +0900 Subject: x86, AMD IOMMU: clean up Kconfig entry AMD_IOMMU should depend on IOMMU_HELPER since they are the IOMMU helper functions. SWIOTLB requires IOMMU_HELPER so declaring that AMD_IOMMU depends on SWIOTLB properly fixes the problems. Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index bb0c0d0..c70d886 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -575,7 +575,7 @@ config SWIOTLB 3 GB of memory. If unsure, say Y. config IOMMU_HELPER - def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB) + def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU) config MAXSMP bool "Configure Maximum number of SMP Processors and NUMA Nodes" depends on X86_64 && SMP -- cgit v0.10.2 From 2179bab7d431ab8ed539e19e029b1f6a231f4ed3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 10:59:59 +0200 Subject: Revert "x86: fix IO APIC breakage on HP nx6325, v2" This reverts commit a74a1cc3df0be89658bc735c8aed80c8392e2c15. This was just temporary diagnostics commit - not needed now that we've got the final fix. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 0494cdb..83c953a 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -373,26 +373,6 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) entry->pin = pin; } -/* - * Reroute an IRQ to a different pin. - */ -static void __init replace_pin_at_irq(unsigned int irq, - int oldapic, int oldpin, - int newapic, int newpin) -{ - struct irq_pin_list *entry = irq_2_pin + irq; - - while (1) { - if (entry->apic == oldapic && entry->pin == oldpin) { - entry->apic = newapic; - entry->pin = newpin; - } - if (!entry->next) - break; - entry = irq_2_pin + entry->next; - } -} - #define DO_ACTION(name,R,ACTION, FINAL) \ \ @@ -1724,11 +1704,6 @@ static inline void __init check_timer(void) apic2 = apic1; } - replace_pin_at_irq(0, 0, 0, apic1, pin1); - apic1 = 0; - pin1 = 0; - setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); - if (pin1 != -1) { /* * Ok, does IRQ0 through the IOAPIC work? @@ -1760,9 +1735,10 @@ static inline void __init check_timer(void) /* * legacy devices should be connected to IO APIC #0 */ - replace_pin_at_irq(0, apic1, pin1, apic2, pin2); + /* replace_pin_at_irq(0, apic1, pin1, apic2, pin2); */ setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); unmask_IO_APIC_irq(0); + clear_IO_APIC_pin(apic2, pin2); enable_8259A_irq(0); if (timer_irq_works()) { apic_printk(APIC_VERBOSE," works.\n"); -- cgit v0.10.2 From c9076b63191ec799ba6848ce5603fff109da57d2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 11:00:50 +0200 Subject: Revert "x86: fix IO APIC breakage on HP nx6325" This reverts commit 90221a61a71b7ad659d8741cf1e404506b174982. This too was just temporary diagnostics - not needed now that we've got the final fix via: | commit e2079c43861f71b2deb78ee20e247ad954fdd67e | Author: Rafael J. Wysocki | Date: Tue Jul 8 16:12:26 2008 +0200 | | x86: fix C1E && nx6325 stability problem Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 83c953a..f930885 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -1738,7 +1738,6 @@ static inline void __init check_timer(void) /* replace_pin_at_irq(0, apic1, pin1, apic2, pin2); */ setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); unmask_IO_APIC_irq(0); - clear_IO_APIC_pin(apic2, pin2); enable_8259A_irq(0); if (timer_irq_works()) { apic_printk(APIC_VERBOSE," works.\n"); -- cgit v0.10.2 From c85ceac97487580e39daaf57858513246e425647 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 10 Jul 2008 11:01:06 +0200 Subject: ALSA: usb-audio: fix Yamaha KX quirk We have to restrict the quirk to interface 0 because the second interface is not MIDI but HID. Additionally, this product ID is used by all four KX models, so it is better to read the product name from the device. Signed-off-by: Clemens Ladisch diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index d675050..3eb12fe 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -210,7 +210,7 @@ YAMAHA_DEVICE(0x1042, NULL), YAMAHA_DEVICE(0x1043, NULL), YAMAHA_DEVICE(0x1044, NULL), YAMAHA_DEVICE(0x1045, NULL), -YAMAHA_DEVICE(0x104e, "KX49"), +YAMAHA_INTERFACE(0x104e, 0, NULL), YAMAHA_DEVICE(0x2000, "DGP-7"), YAMAHA_DEVICE(0x2001, "DGP-5"), YAMAHA_DEVICE(0x2002, NULL), -- cgit v0.10.2 From 0b9f4f49e2abe787673de8f1f56f053fb30fec24 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 1 Jul 2008 01:19:31 +0100 Subject: x86: I/O APIC: Add a 64-bit variation of replace_pin_at_irq() When an interrupt is rerouted to a different I/O APIC pin the relevant entry of the irq_2_pin list should get updated accordingly so that operations are performed on the correct redirection entry. This is already done by the 32-bit variation of the code and here is a complementing 64-bit implementation. Should make someone's decision less tough when merging the two. ;) Signed-off-by: Maciej W. Rozycki Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index f930885..8484117 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -373,6 +373,26 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) entry->pin = pin; } +/* + * Reroute an IRQ to a different pin. + */ +static void __init replace_pin_at_irq(unsigned int irq, + int oldapic, int oldpin, + int newapic, int newpin) +{ + struct irq_pin_list *entry = irq_2_pin + irq; + + while (1) { + if (entry->apic == oldapic && entry->pin == oldpin) { + entry->apic = newapic; + entry->pin = newpin; + } + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } +} + #define DO_ACTION(name,R,ACTION, FINAL) \ \ @@ -1735,7 +1755,7 @@ static inline void __init check_timer(void) /* * legacy devices should be connected to IO APIC #0 */ - /* replace_pin_at_irq(0, apic1, pin1, apic2, pin2); */ + replace_pin_at_irq(0, apic1, pin1, apic2, pin2); setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); unmask_IO_APIC_irq(0); enable_8259A_irq(0); -- cgit v0.10.2 From 83a1a3974f33d45d6631363738db737624a32e82 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 10 Jul 2008 11:05:42 +0200 Subject: ALSA: usb-audio: add some Yamaha USB MIDI quirks Add quirk entries for four Yamaha USB MIDI devices. Signed-off-by: Clemens Ladisch diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 3eb12fe..9ea726c 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -211,6 +211,10 @@ YAMAHA_DEVICE(0x1043, NULL), YAMAHA_DEVICE(0x1044, NULL), YAMAHA_DEVICE(0x1045, NULL), YAMAHA_INTERFACE(0x104e, 0, NULL), +YAMAHA_DEVICE(0x104f, NULL), +YAMAHA_DEVICE(0x1050, NULL), +YAMAHA_DEVICE(0x1051, NULL), +YAMAHA_DEVICE(0x1052, NULL), YAMAHA_DEVICE(0x2000, "DGP-7"), YAMAHA_DEVICE(0x2001, "DGP-5"), YAMAHA_DEVICE(0x2002, NULL), -- cgit v0.10.2 From a6784ad7eafa74a085c8458909eda0699a8fcf57 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 12:21:58 +0200 Subject: x86: fix visws and vsmp build these two sub-architectures want PCI to be default-on, not default-off. Reported-by: Robert Richter Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c70d886..3b1b1da 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -283,7 +283,7 @@ config X86_VOYAGER config X86_VISWS bool "SGI 320/540 (Visual Workstation)" - depends on X86_32 && !PCI + depends on X86_32 && PCI help The SGI Visual Workstation series is an IA32-based workstation based on SGI systems chips with some legacy PC hardware attached. @@ -355,7 +355,7 @@ config X86_RDC321X config X86_VSMP bool "Support for ScaleMP vSMP" select PARAVIRT - depends on X86_64 && !PCI + depends on X86_64 && PCI help Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is supposed to run on these EM64T-based machines. Only choose this option -- cgit v0.10.2 From ca201c8230de336c3684aa3f3422d0c3f02bcef9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 12:33:20 +0200 Subject: x86, visws: fix generic-ipi build fix: arch/x86/kernel/built-in.o: In function `smp_intr_init': (.init.text+0x49e2): undefined reference to `call_function_single_interrupt' Caused by include/asm-x86/mach-visws/entry_arch.h getting out of sync with the include/asm-x86/mach-default/entry_arch.h file it derives from. Copy the default file over - next step will be to simply include the default file. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/entry_arch.h b/include/asm-x86/mach-visws/entry_arch.h index b183fa6..9283b60 100644 --- a/include/asm-x86/mach-visws/entry_arch.h +++ b/include/asm-x86/mach-visws/entry_arch.h @@ -1,4 +1,10 @@ /* + * This file is designed to contain the BUILD_INTERRUPT specifications for + * all of the extra named interrupt vectors used by the architecture. + * Usually this is the Inter Process Interrupts (IPIs) + */ + +/* * The following vectors are part of the Linux architecture, there * is no hardware IRQ pin equivalent for them, they are triggered * through the ICC by us (IPIs) @@ -7,6 +13,7 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) +BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) #endif /* @@ -20,4 +27,9 @@ BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) + +#ifdef CONFIG_X86_MCE_P4THERMAL +BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR) +#endif + #endif -- cgit v0.10.2 From 42a2f217a5e324ed5f2373ab1b7a0a15187c4d6c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 12:35:46 +0200 Subject: x86, visws: use mach-default/entry_arch.h mach-default/entry_arch.h is exactly the same file as mach-visws/entry_arch.h, so include the first from the second, so that updates to the generic one get picked up by VISWS as well. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/entry_arch.h b/include/asm-x86/mach-visws/entry_arch.h index 9283b60..86be554 100644 --- a/include/asm-x86/mach-visws/entry_arch.h +++ b/include/asm-x86/mach-visws/entry_arch.h @@ -1,35 +1,5 @@ /* - * This file is designed to contain the BUILD_INTERRUPT specifications for - * all of the extra named interrupt vectors used by the architecture. - * Usually this is the Inter Process Interrupts (IPIs) + * VISWS uses the standard Linux entry points: */ -/* - * The following vectors are part of the Linux architecture, there - * is no hardware IRQ pin equivalent for them, they are triggered - * through the ICC by us (IPIs) - */ -#ifdef CONFIG_X86_SMP -BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) -BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) -BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) -BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) -#endif - -/* - * every pentium local APIC has two 'local interrupts', with a - * soft-definable vector attached to both interrupts, one of - * which is a timer interrupt, the other one is error counter - * overflow. Linux uses the local APIC timer interrupt to get - * a much simpler SMP time architecture: - */ -#ifdef CONFIG_X86_LOCAL_APIC -BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) -BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) -BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) - -#ifdef CONFIG_X86_MCE_P4THERMAL -BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR) -#endif - -#endif +#include "../mach-default/entry_arch.h" -- cgit v0.10.2 From 613526677a74c2b3d1b1696ea7334b2cf35155b3 Mon Sep 17 00:00:00 2001 From: sedji gaouaou Date: Thu, 10 Jul 2008 10:15:35 +0100 Subject: [ARM] 5130/4: Support for the at91sam9g20 Support for the at91sam9g20 : Atmel 400Mhz ARM 926ej-s SOC. AT91sam9g20 is an evolution of the at91sam9260 with a faster clock speed. We created a new board for this device but based the chip support directly on 9260 files with little updates. Here is the chip page on Atmel wabsite: http://atmel.com/dyn/products/product_card.asp?part_id=4337 Signed-off-by: Sedji Gaouaou Signed-off-by: Justin Waters Acked-by: Andrew Victor Signed-off-by: Russell King diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index cae5c67..5bad6b9 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -30,6 +30,11 @@ config ARCH_AT91SAM9RL select GENERIC_TIME select GENERIC_CLOCKEVENTS +config ARCH_AT91SAM9G20 + bool "AT91SAM9G20" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + config ARCH_AT91CAP9 bool "AT91CAP9" select GENERIC_TIME @@ -239,6 +244,20 @@ endif # ---------------------------------------------------------- +if ARCH_AT91SAM9G20 + +comment "AT91SAM9G20 Board Type" + +config MACH_AT91SAM9G20EK + bool "Atmel AT91SAM9G20-EK Evaluation Kit" + depends on ARCH_AT91SAM9G20 + help + Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. + +endif + +# ---------------------------------------------------------- + if ARCH_AT91CAP9 comment "AT91CAP9 Board Type" @@ -274,13 +293,13 @@ comment "AT91 Board Options" config MTD_AT91_DATAFLASH_CARD bool "Enable DataFlash Card support" - depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK || MACH_SAM9_L9260 || MACH_ECBAT91) + depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK) help Enable support for the DataFlash card. config MTD_NAND_AT91_BUSWIDTH_16 bool "Enable 16-bit data bus interface to NAND flash" - depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK) + depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK) help On AT91SAM926x boards both types of NAND flash can be present (8 and 16 bit data bus width). @@ -329,15 +348,15 @@ config AT91_EARLY_USART2 config AT91_EARLY_USART3 bool "USART3" - depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260) + depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20) config AT91_EARLY_USART4 bool "USART4" - depends on ARCH_AT91SAM9260 + depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 config AT91_EARLY_USART5 bool "USART5" - depends on ARCH_AT91SAM9260 + depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 endchoice diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 932d171..7d641f9 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o @@ -49,6 +50,9 @@ obj-$(CONFIG_MACH_USB_A9263) += board-usb-a9263.o # AT91SAM9RL board-specific support obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o +# AT91SAM9G20 board-specific support +obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o + # AT91CAP9 board-specific support obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index ee26550..380f12a 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -47,6 +47,20 @@ static struct map_desc at91sam9260_sram_desc[] __initdata = { } }; +static struct map_desc at91sam9g20_sram_desc[] __initdata = { + { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE), + .length = AT91SAM9G20_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE), + .length = AT91SAM9G20_SRAM1_SIZE, + .type = MT_DEVICE, + } +}; + static struct map_desc at91sam9xe_sram_desc[] __initdata = { { .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), @@ -307,6 +321,8 @@ void __init at91sam9260_initialize(unsigned long main_clock) if (cpu_is_at91sam9xe()) at91sam9xe_initialize(); + else if (cpu_is_at91sam9g20()) + iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); else iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 26f5cac..86cba4a 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -320,20 +321,41 @@ void __init at91_add_device_nand(struct at91_nand_data *data) csa = at91_sys_read(AT91_MATRIX_EBICSA); at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); - /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) - | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); + if (cpu_is_at91sam9260()) { + /* Timing for sam9260 */ + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); - at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) - | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) + | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); - at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); - if (data->bus_width_16) - mode = AT91_SMC_DBW_16; - else - mode = AT91_SMC_DBW_8; - at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); + } + + if (cpu_is_at91sam9g20()) { + /* Timing for sam9g20 */ + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0)); + + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(4) + | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(4)); + + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(3)); + } /* enable pin */ if (data->enable_pin) diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c new file mode 100644 index 0000000..45617c2 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootstrap", + .offset = 0, + .size = 4 * 1024 * 1024, + }, + { + .name = "Partition 1", + .offset = 4 * 1024 * 1024, + .size = 60 * 1024 * 1024, + }, + { + .name = "Partition 2", + .offset = 64 * 1024 * 1024, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, + .wire4 = 1, +}; + + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PA6, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PA9, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); +} + +MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index e8ce8f0..464bdbb 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -515,14 +515,19 @@ static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) /* * PLL input between 1MHz and 32MHz per spec, but lower * frequences seem necessary in some cases so allow 100K. + * Warning: some newer products need 2MHz min. */ input = main_freq / i; + if (cpu_is_at91sam9g20() && input < 2000000) + continue; if (input < 100000) continue; if (input > 32000000) continue; mul1 = out_freq / input; + if (cpu_is_at91sam9g20() && mul > 63) + continue; if (mul1 > 2048) continue; if (mul1 < 2) @@ -582,7 +587,8 @@ int __init at91_clock_init(unsigned long main_clock) /* report if PLLA is more than mildly overclocked */ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); - if (plla.rate_hz > 209000000) + if ((!cpu_is_at91sam9g20() && plla.rate_hz > 209000000) + || (cpu_is_at91sam9g20() && plla.rate_hz > 800000000)) pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); /* @@ -597,7 +603,7 @@ int __init at91_clock_init(unsigned long main_clock) uhpck.pmc_mask = AT91RM9200_PMC_UHP; udpck.pmc_mask = AT91RM9200_PMC_UDP; at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { uhpck.pmc_mask = AT91SAM926x_PMC_UHP; udpck.pmc_mask = AT91SAM926x_PMC_UDP; } else if (cpu_is_at91cap9()) { @@ -629,8 +635,13 @@ int __init at91_clock_init(unsigned long main_clock) freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ if (cpu_is_at91rm9200()) mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ - else - mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + else if (cpu_is_at91sam9g20()) { + mck.rate_hz = (mckr & AT91_PMC_MDIV) ? + freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ + if (mckr & AT91_PMC_PDIV) + freq /= 2; /* processor clock division */ + } else + mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ /* Register the PMC's standard clocks */ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index aa863c1..8ab4feb 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -202,7 +202,7 @@ static int at91_pm_verify_clocks(void) pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 33ed048..750d895 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -180,8 +180,8 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI - default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_PABRT_NOIFAR diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9f6cc8a..be3b13c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -217,7 +217,7 @@ config MII config MACB tristate "Atmel MACB support" - depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9 + depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 select PHYLIB help The Atmel MACB ethernet interface is found on many AT32 and AT91 diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 274c60a..b6b2a0a 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -888,7 +888,7 @@ static void pullup(struct at91_udc *udc, int is_on) at91_udp_write(udc, AT91_UDP_TXVC, 0); if (cpu_is_at91rm9200()) gpio_set_value(udc->board.pullup_pin, active); - else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { + else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); txvc |= AT91_UDP_TXVC_PUON; @@ -906,7 +906,7 @@ static void pullup(struct at91_udc *udc, int is_on) at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); if (cpu_is_at91rm9200()) gpio_set_value(udc->board.pullup_pin, !active); - else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { + else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); txvc &= ~AT91_UDP_TXVC_PUON; diff --git a/include/asm-arm/arch-at91/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h index c8934fe..889872a 100644 --- a/include/asm-arm/arch-at91/at91sam9260.h +++ b/include/asm-arm/arch-at91/at91sam9260.h @@ -6,6 +6,8 @@ * Common definitions. * Based on AT91SAM9260 datasheet revision A (Preliminary). * + * Includes also definitions for AT91SAM9XE and AT91SAM9G families + * * 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 @@ -123,5 +125,14 @@ #define AT91SAM9XE_FLASH_BASE 0x00200000 /* Internal FLASH base address */ #define AT91SAM9XE_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9G20_ROM_BASE 0x00100000 /* Internal ROM base address */ +#define AT91SAM9G20_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ + +#define AT91SAM9G20_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */ +#define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */ +#define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ +#define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */ + +#define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */ #endif diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index 1f24702..94de788 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h @@ -77,7 +77,7 @@ struct at91_eth_data { }; extern void __init at91_add_device_eth(struct at91_eth_data *data); -#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) +#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) #define eth_platform_data at91_eth_data #endif diff --git a/include/asm-arm/arch-at91/cpu.h b/include/asm-arm/arch-at91/cpu.h index 7145166..52df794 100644 --- a/include/asm-arm/arch-at91/cpu.h +++ b/include/asm-arm/arch-at91/cpu.h @@ -21,6 +21,7 @@ #define ARCH_ID_AT91SAM9260 0x019803a0 #define ARCH_ID_AT91SAM9261 0x019703a0 #define ARCH_ID_AT91SAM9263 0x019607a0 +#define ARCH_ID_AT91SAM9G20 0x019905a0 #define ARCH_ID_AT91SAM9RL64 0x019b03a0 #define ARCH_ID_AT91CAP9 0x039A03A0 @@ -63,6 +64,12 @@ static inline unsigned long at91_arch_identify(void) #define cpu_is_at91sam9260() (0) #endif +#ifdef CONFIG_ARCH_AT91SAM9G20 +#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20) +#else +#define cpu_is_at91sam9g20() (0) +#endif + #ifdef CONFIG_ARCH_AT91SAM9261 #define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261) #else diff --git a/include/asm-arm/arch-at91/hardware.h b/include/asm-arm/arch-at91/hardware.h index 2c826d82..016a3a3 100644 --- a/include/asm-arm/arch-at91/hardware.h +++ b/include/asm-arm/arch-at91/hardware.h @@ -18,7 +18,7 @@ #if defined(CONFIG_ARCH_AT91RM9200) #include -#elif defined(CONFIG_ARCH_AT91SAM9260) +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) #include #elif defined(CONFIG_ARCH_AT91SAM9261) #include diff --git a/include/asm-arm/arch-at91/timex.h b/include/asm-arm/arch-at91/timex.h index 6e084eb..298d831 100644 --- a/include/asm-arm/arch-at91/timex.h +++ b/include/asm-arm/arch-at91/timex.h @@ -57,6 +57,11 @@ #define AT91SAM9_MASTER_CLOCK 100000000 #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) +#elif defined(CONFIG_ARCH_AT91SAM9G20) + +#define AT91SAM9_MASTER_CLOCK 132096000 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + #elif defined(CONFIG_ARCH_AT91CAP9) #define AT91CAP9_MASTER_CLOCK 100000000 diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index bc35d00..1a42609 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -41,7 +41,7 @@ #define DBG(x...) #endif -#if defined(CONFIG_ARCH_AT91SAM9260) +#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) #define NUM_SSC_DEVICES 1 #else #define NUM_SSC_DEVICES 3 -- cgit v0.10.2 From 3ef8191f43cfd936ea00b7483ea0acf2f0303a23 Mon Sep 17 00:00:00 2001 From: sedji gaouaou Date: Thu, 10 Jul 2008 10:12:14 +0100 Subject: [ARM] 5133/2: at91sam9g20 defconfig file at91sam9g20 defconfig file Signed-off-by: Sedji Gaouaou Signed-off-by: Justin Waters Acked-by: Andrew Victor Signed-off-by: Russell King diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig new file mode 100644 index 0000000..c068638 --- /dev/null +++ b/arch/arm/configs/at91sam9g20ek_defconfig @@ -0,0 +1,1168 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24 +# Tue Jun 10 15:51:52 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# 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 is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_FAIR_GROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY 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_UID16=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_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB 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_UNLOAD=y +# 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 + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +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" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +CONFIG_ARCH_AT91SAM9G20=y +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_AT91_PMC_UNIT=y + +# +# AT91SAM9G20 Board Type +# +CONFIG_MACH_AT91SAM9G20EK=y + +# +# AT91 Board Options +# +# CONFIG_MTD_AT91_DATAFLASH_CARD is not set +# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set + +# +# AT91 Feature Selections +# +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +# CONFIG_AT91_SLOW_CLOCK is not set +CONFIG_AT91_TIMER_HZ=100 +CONFIG_AT91_EARLY_DBGU=y +# CONFIG_AT91_EARLY_USART0 is not set +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_AT91_EARLY_USART3 is not set +# CONFIG_AT91_EARLY_USART4 is not set +# CONFIG_AT91_EARLY_USART5 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y +# CONFIG_APM_EMULATION is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=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_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# 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_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL 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_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 + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC 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 +# 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 is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# 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 +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE 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_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_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_M25P80 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=y +# 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_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_AT91_ECC_SOFT=y +# CONFIG_MTD_NAND_AT91_ECC_HW is not set +# CONFIG_MTD_NAND_AT91_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD 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=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +CONFIG_ATMEL_PWM=y +# CONFIG_EEPROM_93CX6 is not set +CONFIG_ATMEL_SSC=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 is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# 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 is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# 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 is not set +# 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 is not set +# 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 +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH 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_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACB=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 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_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# 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_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 +# CONFIG_ISDN 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 is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# 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_KEYBOARD_GPIO=y +# 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 +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# 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 is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# 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 + +# +# ALSA ARM devices +# +# CONFIG_SND_AT91_AC97 is not set + +# +# SPI devices +# +CONFIG_SND_AT73C213=y +CONFIG_SND_AT73C213_TARGET_BITRATE=48000 + +# +# 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_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_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_PERSIST is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_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 +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# 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 +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# 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_AUERSWALD 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_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_ETH is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_AT91=y +# CONFIG_MMC_SPI is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_ATMEL_PWM=y +CONFIG_LEDS_GPIO=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1553 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_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_RTC_DRV_AT91SAM9_RTT=0 +CONFIG_RTC_DRV_AT91SAM9_GPBR=0 + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_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_XFS_FS 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=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# 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 is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=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 + +# +# 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_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN 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 +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +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_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# 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 +# CONFIG_CIFS 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 is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# 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 is not set +CONFIG_NLS_ISO8859_1=y +# 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=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set +# CONFIG_INSTRUMENTATION is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED 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_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y -- cgit v0.10.2 From 93aa7f8a12d1b229bcee12a1100a6df4945f5432 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 7 May 2008 21:10:13 +0800 Subject: [CRYPTO] cryptd: Fix EINPROGRESS notification context The EINPROGRESS notifications should be done just like the final call-backs, i.e., with BH off. This patch fixes the call in cryptd since previously it was called with BH on. Signed-off-by: Herbert Xu diff --git a/crypto/cryptd.c b/crypto/cryptd.c index b150de5..f38e147 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -82,10 +82,8 @@ static void cryptd_blkcipher_crypt(struct ablkcipher_request *req, rctx = ablkcipher_request_ctx(req); - if (unlikely(err == -EINPROGRESS)) { - rctx->complete(&req->base, err); - return; - } + if (unlikely(err == -EINPROGRESS)) + goto out; desc.tfm = child; desc.info = req->info; @@ -95,8 +93,9 @@ static void cryptd_blkcipher_crypt(struct ablkcipher_request *req, req->base.complete = rctx->complete; +out: local_bh_disable(); - req->base.complete(&req->base, err); + rctx->complete(&req->base, err); local_bh_enable(); } -- cgit v0.10.2 From c6580eb8b17d64f0d6ad25c86a034adbda5ab4e1 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Wed, 7 May 2008 22:14:10 +0800 Subject: [CRYPTO] ripemd: Add support for RIPEMD hash algorithms This patch adds support for RIPEMD-128 and RIPEMD-160 hash algorithms. Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/Makefile b/crypto/Makefile index ca02441..1efb556 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -27,6 +27,8 @@ obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o obj-$(CONFIG_CRYPTO_MD4) += md4.o obj-$(CONFIG_CRYPTO_MD5) += md5.o +obj-$(CONFIG_CRYPTO_RMD128) += rmd128.o +obj-$(CONFIG_CRYPTO_RMD160) += rmd160.o obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o diff --git a/crypto/ripemd.h b/crypto/ripemd.h new file mode 100644 index 0000000..2858e22 --- /dev/null +++ b/crypto/ripemd.h @@ -0,0 +1,26 @@ +/* + * Common values for RIPEMD algorithms + */ + +#ifndef _CRYPTO_RMD_H +#define _CRYPTO_RMD_H + +#define RMD128_DIGEST_SIZE 16 +#define RMD128_BLOCK_SIZE 64 + +#define RMD160_DIGEST_SIZE 20 +#define RMD160_BLOCK_SIZE 64 + +#define RMD256_DIGEST_SIZE 32 +#define RMD256_BLOCK_SIZE 64 + +#define RMD320_DIGEST_SIZE 40 +#define RMD320_BLOCK_SIZE 64 + +#define RMD_H0 0x67452301UL +#define RMD_H1 0xefcdab89UL +#define RMD_H2 0x98badcfeUL +#define RMD_H3 0x10325476UL +#define RMD_H4 0xc3d2e1f0UL + +#endif diff --git a/crypto/rmd128.c b/crypto/rmd128.c new file mode 100644 index 0000000..22cc13b --- /dev/null +++ b/crypto/rmd128.c @@ -0,0 +1,344 @@ +/* + * Cryptographic API. + * + * RIPEMD-128 - RACE Integrity Primitives Evaluation Message Digest. + * + * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC + * + * Copyright (c) 2008 Adrian-Ken Rueegsegger + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "ripemd.h" + +struct rmd128_ctx { + u64 byte_count; + u32 state[4]; + u32 buffer[16]; +}; + +#define K1 0x00000000UL +#define K2 0x5a827999UL +#define K3 0x6ed9eba1UL +#define K4 0x8f1bbcdcUL +#define KK1 0x50a28be6UL +#define KK2 0x5c4dd124UL +#define KK3 0x6d703ef3UL +#define KK4 0x00000000UL + +#define F1(x, y, z) (x ^ y ^ z) /* XOR */ +#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define F3(x, y, z) ((x | ~y) ^ z) +#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ + +#define ROUND(a, b, c, d, f, k, x, s) { \ + (a) += f((b), (c), (d)) + (x) + (k); \ + (a) = rol32((a), (s)); \ +} + +static void rmd128_transform(u32 *state, u32 const *in) +{ + u32 aa, bb, cc, dd, aaa, bbb, ccc, ddd; + + /* Initialize left lane */ + aa = state[0]; + bb = state[1]; + cc = state[2]; + dd = state[3]; + + /* Initialize right lane */ + aaa = state[0]; + bbb = state[1]; + ccc = state[2]; + ddd = state[3]; + + /* round 1: left lane */ + ROUND(aa, bb, cc, dd, F1, K1, in[0], 11); + ROUND(dd, aa, bb, cc, F1, K1, in[1], 14); + ROUND(cc, dd, aa, bb, F1, K1, in[2], 15); + ROUND(bb, cc, dd, aa, F1, K1, in[3], 12); + ROUND(aa, bb, cc, dd, F1, K1, in[4], 5); + ROUND(dd, aa, bb, cc, F1, K1, in[5], 8); + ROUND(cc, dd, aa, bb, F1, K1, in[6], 7); + ROUND(bb, cc, dd, aa, F1, K1, in[7], 9); + ROUND(aa, bb, cc, dd, F1, K1, in[8], 11); + ROUND(dd, aa, bb, cc, F1, K1, in[9], 13); + ROUND(cc, dd, aa, bb, F1, K1, in[10], 14); + ROUND(bb, cc, dd, aa, F1, K1, in[11], 15); + ROUND(aa, bb, cc, dd, F1, K1, in[12], 6); + ROUND(dd, aa, bb, cc, F1, K1, in[13], 7); + ROUND(cc, dd, aa, bb, F1, K1, in[14], 9); + ROUND(bb, cc, dd, aa, F1, K1, in[15], 8); + + /* round 2: left lane */ + ROUND(aa, bb, cc, dd, F2, K2, in[7], 7); + ROUND(dd, aa, bb, cc, F2, K2, in[4], 6); + ROUND(cc, dd, aa, bb, F2, K2, in[13], 8); + ROUND(bb, cc, dd, aa, F2, K2, in[1], 13); + ROUND(aa, bb, cc, dd, F2, K2, in[10], 11); + ROUND(dd, aa, bb, cc, F2, K2, in[6], 9); + ROUND(cc, dd, aa, bb, F2, K2, in[15], 7); + ROUND(bb, cc, dd, aa, F2, K2, in[3], 15); + ROUND(aa, bb, cc, dd, F2, K2, in[12], 7); + ROUND(dd, aa, bb, cc, F2, K2, in[0], 12); + ROUND(cc, dd, aa, bb, F2, K2, in[9], 15); + ROUND(bb, cc, dd, aa, F2, K2, in[5], 9); + ROUND(aa, bb, cc, dd, F2, K2, in[2], 11); + ROUND(dd, aa, bb, cc, F2, K2, in[14], 7); + ROUND(cc, dd, aa, bb, F2, K2, in[11], 13); + ROUND(bb, cc, dd, aa, F2, K2, in[8], 12); + + /* round 3: left lane */ + ROUND(aa, bb, cc, dd, F3, K3, in[3], 11); + ROUND(dd, aa, bb, cc, F3, K3, in[10], 13); + ROUND(cc, dd, aa, bb, F3, K3, in[14], 6); + ROUND(bb, cc, dd, aa, F3, K3, in[4], 7); + ROUND(aa, bb, cc, dd, F3, K3, in[9], 14); + ROUND(dd, aa, bb, cc, F3, K3, in[15], 9); + ROUND(cc, dd, aa, bb, F3, K3, in[8], 13); + ROUND(bb, cc, dd, aa, F3, K3, in[1], 15); + ROUND(aa, bb, cc, dd, F3, K3, in[2], 14); + ROUND(dd, aa, bb, cc, F3, K3, in[7], 8); + ROUND(cc, dd, aa, bb, F3, K3, in[0], 13); + ROUND(bb, cc, dd, aa, F3, K3, in[6], 6); + ROUND(aa, bb, cc, dd, F3, K3, in[13], 5); + ROUND(dd, aa, bb, cc, F3, K3, in[11], 12); + ROUND(cc, dd, aa, bb, F3, K3, in[5], 7); + ROUND(bb, cc, dd, aa, F3, K3, in[12], 5); + + /* round 4: left lane */ + ROUND(aa, bb, cc, dd, F4, K4, in[1], 11); + ROUND(dd, aa, bb, cc, F4, K4, in[9], 12); + ROUND(cc, dd, aa, bb, F4, K4, in[11], 14); + ROUND(bb, cc, dd, aa, F4, K4, in[10], 15); + ROUND(aa, bb, cc, dd, F4, K4, in[0], 14); + ROUND(dd, aa, bb, cc, F4, K4, in[8], 15); + ROUND(cc, dd, aa, bb, F4, K4, in[12], 9); + ROUND(bb, cc, dd, aa, F4, K4, in[4], 8); + ROUND(aa, bb, cc, dd, F4, K4, in[13], 9); + ROUND(dd, aa, bb, cc, F4, K4, in[3], 14); + ROUND(cc, dd, aa, bb, F4, K4, in[7], 5); + ROUND(bb, cc, dd, aa, F4, K4, in[15], 6); + ROUND(aa, bb, cc, dd, F4, K4, in[14], 8); + ROUND(dd, aa, bb, cc, F4, K4, in[5], 6); + ROUND(cc, dd, aa, bb, F4, K4, in[6], 5); + ROUND(bb, cc, dd, aa, F4, K4, in[2], 12); + + /* round 1: right lane */ + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[5], 8); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[14], 9); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[7], 9); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[0], 11); + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[9], 13); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[2], 15); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[11], 15); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[4], 5); + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[13], 7); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[6], 7); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[15], 8); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[8], 11); + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[1], 14); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[10], 14); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[3], 12); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[12], 6); + + /* round 2: right lane */ + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[6], 9); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[11], 13); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[3], 15); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[7], 7); + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[0], 12); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[13], 8); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[5], 9); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[10], 11); + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[14], 7); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[15], 7); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[8], 12); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[12], 7); + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[4], 6); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[9], 15); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[1], 13); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[2], 11); + + /* round 3: right lane */ + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[15], 9); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[5], 7); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[1], 15); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[3], 11); + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[7], 8); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[14], 6); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[6], 6); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[9], 14); + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[11], 12); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[8], 13); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[12], 5); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[2], 14); + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[10], 13); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[0], 13); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[4], 7); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[13], 5); + + /* round 4: right lane */ + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[8], 15); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[6], 5); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[4], 8); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[1], 11); + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[3], 14); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[11], 14); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[15], 6); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[0], 14); + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[5], 6); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[12], 9); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[2], 12); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[13], 9); + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[9], 12); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[7], 5); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[10], 15); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[14], 8); + + /* combine results */ + ddd += cc + state[1]; /* final result for state[0] */ + state[1] = state[2] + dd + aaa; + state[2] = state[3] + aa + bbb; + state[3] = state[0] + bb + ccc; + state[0] = ddd; + + return; +} + +static inline void le32_to_cpu_array(u32 *buf, unsigned int words) +{ + while (words--) { + le32_to_cpus(buf); + buf++; + } +} + +static inline void cpu_to_le32_array(u32 *buf, unsigned int words) +{ + while (words--) { + cpu_to_le32s(buf); + buf++; + } +} + +static inline void rmd128_transform_helper(struct rmd128_ctx *ctx) +{ + le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); + rmd128_transform(ctx->state, ctx->buffer); +} + +static void rmd128_init(struct crypto_tfm *tfm) +{ + struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); + + rctx->byte_count = 0; + + rctx->state[0] = RMD_H0; + rctx->state[1] = RMD_H1; + rctx->state[2] = RMD_H2; + rctx->state[3] = RMD_H3; + + memset(rctx->buffer, 0, sizeof(rctx->buffer)); +} + +static void rmd128_update(struct crypto_tfm *tfm, const u8 *data, + unsigned int len) +{ + struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); + const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); + + rctx->byte_count += len; + + /* Enough space in buffer? If so copy and we're done */ + if (avail > len) { + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, len); + return; + } + + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, avail); + + rmd128_transform_helper(rctx); + data += avail; + len -= avail; + + while (len >= sizeof(rctx->buffer)) { + memcpy(rctx->buffer, data, sizeof(rctx->buffer)); + rmd128_transform_helper(rctx); + data += sizeof(rctx->buffer); + len -= sizeof(rctx->buffer); + } + + memcpy(rctx->buffer, data, len); +} + +/* Add padding and return the message digest. */ +static void rmd128_final(struct crypto_tfm *tfm, u8 *out) +{ + struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); + u32 index, padlen; + u64 bits; + static const u8 padding[64] = { 0x80, }; + bits = rctx->byte_count << 3; + + /* Pad out to 56 mod 64 */ + index = rctx->byte_count & 0x3f; + padlen = (index < 56) ? (56 - index) : ((64+56) - index); + rmd128_update(tfm, padding, padlen); + + /* Append length */ + rmd128_update(tfm, (const u8 *)&bits, sizeof(bits)); + + /* Store state in digest */ + memcpy(out, rctx->state, sizeof(rctx->state)); + + /* Wipe context */ + memset(rctx, 0, sizeof(*rctx)); +} + +static struct crypto_alg alg = { + .cra_name = "rmd128", + .cra_driver_name = "rmd128", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = RMD128_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct rmd128_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = RMD128_DIGEST_SIZE, + .dia_init = rmd128_init, + .dia_update = rmd128_update, + .dia_final = rmd128_final } } +}; + +static int __init rmd128_mod_init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit rmd128_mod_fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(rmd128_mod_init); +module_exit(rmd128_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RIPEMD-128 Message Digest"); + +MODULE_ALIAS("rmd128"); diff --git a/crypto/rmd160.c b/crypto/rmd160.c new file mode 100644 index 0000000..a8a9d3d --- /dev/null +++ b/crypto/rmd160.c @@ -0,0 +1,388 @@ +/* + * Cryptographic API. + * + * RIPEMD-160 - RACE Integrity Primitives Evaluation Message Digest. + * + * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC + * + * Copyright (c) 2008 Adrian-Ken Rueegsegger + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "ripemd.h" + +struct rmd160_ctx { + u64 byte_count; + u32 state[5]; + u32 buffer[16]; +}; + +#define K1 0x00000000UL +#define K2 0x5a827999UL +#define K3 0x6ed9eba1UL +#define K4 0x8f1bbcdcUL +#define K5 0xa953fd4eUL +#define KK1 0x50a28be6UL +#define KK2 0x5c4dd124UL +#define KK3 0x6d703ef3UL +#define KK4 0x7a6d76e9UL +#define KK5 0x00000000UL + +#define F1(x, y, z) (x ^ y ^ z) /* XOR */ +#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define F3(x, y, z) ((x | ~y) ^ z) +#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ +#define F5(x, y, z) (x ^ (y | ~z)) + +#define ROUND(a, b, c, d, e, f, k, x, s) { \ + (a) += f((b), (c), (d)) + (x) + (k); \ + (a) = rol32((a), (s)) + (e); \ + (c) = rol32((c), 10); \ +} + +static void rmd160_transform(u32 *state, u32 const *in) +{ + u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee; + + /* Initialize left lane */ + aa = state[0]; + bb = state[1]; + cc = state[2]; + dd = state[3]; + ee = state[4]; + + /* Initialize right lane */ + aaa = state[0]; + bbb = state[1]; + ccc = state[2]; + ddd = state[3]; + eee = state[4]; + + /* round 1: left lane */ + ROUND(aa, bb, cc, dd, ee, F1, K1, in[0], 11); + ROUND(ee, aa, bb, cc, dd, F1, K1, in[1], 14); + ROUND(dd, ee, aa, bb, cc, F1, K1, in[2], 15); + ROUND(cc, dd, ee, aa, bb, F1, K1, in[3], 12); + ROUND(bb, cc, dd, ee, aa, F1, K1, in[4], 5); + ROUND(aa, bb, cc, dd, ee, F1, K1, in[5], 8); + ROUND(ee, aa, bb, cc, dd, F1, K1, in[6], 7); + ROUND(dd, ee, aa, bb, cc, F1, K1, in[7], 9); + ROUND(cc, dd, ee, aa, bb, F1, K1, in[8], 11); + ROUND(bb, cc, dd, ee, aa, F1, K1, in[9], 13); + ROUND(aa, bb, cc, dd, ee, F1, K1, in[10], 14); + ROUND(ee, aa, bb, cc, dd, F1, K1, in[11], 15); + ROUND(dd, ee, aa, bb, cc, F1, K1, in[12], 6); + ROUND(cc, dd, ee, aa, bb, F1, K1, in[13], 7); + ROUND(bb, cc, dd, ee, aa, F1, K1, in[14], 9); + ROUND(aa, bb, cc, dd, ee, F1, K1, in[15], 8); + + /* round 2: left lane" */ + ROUND(ee, aa, bb, cc, dd, F2, K2, in[7], 7); + ROUND(dd, ee, aa, bb, cc, F2, K2, in[4], 6); + ROUND(cc, dd, ee, aa, bb, F2, K2, in[13], 8); + ROUND(bb, cc, dd, ee, aa, F2, K2, in[1], 13); + ROUND(aa, bb, cc, dd, ee, F2, K2, in[10], 11); + ROUND(ee, aa, bb, cc, dd, F2, K2, in[6], 9); + ROUND(dd, ee, aa, bb, cc, F2, K2, in[15], 7); + ROUND(cc, dd, ee, aa, bb, F2, K2, in[3], 15); + ROUND(bb, cc, dd, ee, aa, F2, K2, in[12], 7); + ROUND(aa, bb, cc, dd, ee, F2, K2, in[0], 12); + ROUND(ee, aa, bb, cc, dd, F2, K2, in[9], 15); + ROUND(dd, ee, aa, bb, cc, F2, K2, in[5], 9); + ROUND(cc, dd, ee, aa, bb, F2, K2, in[2], 11); + ROUND(bb, cc, dd, ee, aa, F2, K2, in[14], 7); + ROUND(aa, bb, cc, dd, ee, F2, K2, in[11], 13); + ROUND(ee, aa, bb, cc, dd, F2, K2, in[8], 12); + + /* round 3: left lane" */ + ROUND(dd, ee, aa, bb, cc, F3, K3, in[3], 11); + ROUND(cc, dd, ee, aa, bb, F3, K3, in[10], 13); + ROUND(bb, cc, dd, ee, aa, F3, K3, in[14], 6); + ROUND(aa, bb, cc, dd, ee, F3, K3, in[4], 7); + ROUND(ee, aa, bb, cc, dd, F3, K3, in[9], 14); + ROUND(dd, ee, aa, bb, cc, F3, K3, in[15], 9); + ROUND(cc, dd, ee, aa, bb, F3, K3, in[8], 13); + ROUND(bb, cc, dd, ee, aa, F3, K3, in[1], 15); + ROUND(aa, bb, cc, dd, ee, F3, K3, in[2], 14); + ROUND(ee, aa, bb, cc, dd, F3, K3, in[7], 8); + ROUND(dd, ee, aa, bb, cc, F3, K3, in[0], 13); + ROUND(cc, dd, ee, aa, bb, F3, K3, in[6], 6); + ROUND(bb, cc, dd, ee, aa, F3, K3, in[13], 5); + ROUND(aa, bb, cc, dd, ee, F3, K3, in[11], 12); + ROUND(ee, aa, bb, cc, dd, F3, K3, in[5], 7); + ROUND(dd, ee, aa, bb, cc, F3, K3, in[12], 5); + + /* round 4: left lane" */ + ROUND(cc, dd, ee, aa, bb, F4, K4, in[1], 11); + ROUND(bb, cc, dd, ee, aa, F4, K4, in[9], 12); + ROUND(aa, bb, cc, dd, ee, F4, K4, in[11], 14); + ROUND(ee, aa, bb, cc, dd, F4, K4, in[10], 15); + ROUND(dd, ee, aa, bb, cc, F4, K4, in[0], 14); + ROUND(cc, dd, ee, aa, bb, F4, K4, in[8], 15); + ROUND(bb, cc, dd, ee, aa, F4, K4, in[12], 9); + ROUND(aa, bb, cc, dd, ee, F4, K4, in[4], 8); + ROUND(ee, aa, bb, cc, dd, F4, K4, in[13], 9); + ROUND(dd, ee, aa, bb, cc, F4, K4, in[3], 14); + ROUND(cc, dd, ee, aa, bb, F4, K4, in[7], 5); + ROUND(bb, cc, dd, ee, aa, F4, K4, in[15], 6); + ROUND(aa, bb, cc, dd, ee, F4, K4, in[14], 8); + ROUND(ee, aa, bb, cc, dd, F4, K4, in[5], 6); + ROUND(dd, ee, aa, bb, cc, F4, K4, in[6], 5); + ROUND(cc, dd, ee, aa, bb, F4, K4, in[2], 12); + + /* round 5: left lane" */ + ROUND(bb, cc, dd, ee, aa, F5, K5, in[4], 9); + ROUND(aa, bb, cc, dd, ee, F5, K5, in[0], 15); + ROUND(ee, aa, bb, cc, dd, F5, K5, in[5], 5); + ROUND(dd, ee, aa, bb, cc, F5, K5, in[9], 11); + ROUND(cc, dd, ee, aa, bb, F5, K5, in[7], 6); + ROUND(bb, cc, dd, ee, aa, F5, K5, in[12], 8); + ROUND(aa, bb, cc, dd, ee, F5, K5, in[2], 13); + ROUND(ee, aa, bb, cc, dd, F5, K5, in[10], 12); + ROUND(dd, ee, aa, bb, cc, F5, K5, in[14], 5); + ROUND(cc, dd, ee, aa, bb, F5, K5, in[1], 12); + ROUND(bb, cc, dd, ee, aa, F5, K5, in[3], 13); + ROUND(aa, bb, cc, dd, ee, F5, K5, in[8], 14); + ROUND(ee, aa, bb, cc, dd, F5, K5, in[11], 11); + ROUND(dd, ee, aa, bb, cc, F5, K5, in[6], 8); + ROUND(cc, dd, ee, aa, bb, F5, K5, in[15], 5); + ROUND(bb, cc, dd, ee, aa, F5, K5, in[13], 6); + + /* round 1: right lane */ + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[5], 8); + ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[14], 9); + ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[7], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[0], 11); + ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[9], 13); + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[2], 15); + ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[11], 15); + ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[4], 5); + ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[13], 7); + ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[6], 7); + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[15], 8); + ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[8], 11); + ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[1], 14); + ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[10], 14); + ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[3], 12); + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[12], 6); + + /* round 2: right lane */ + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[6], 9); + ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[11], 13); + ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[3], 15); + ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[7], 7); + ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[0], 12); + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[13], 8); + ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[5], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[10], 11); + ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[14], 7); + ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[15], 7); + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[8], 12); + ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[12], 7); + ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[4], 6); + ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[9], 15); + ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[1], 13); + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[2], 11); + + /* round 3: right lane */ + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[15], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[5], 7); + ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[1], 15); + ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[3], 11); + ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[7], 8); + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[14], 6); + ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[6], 6); + ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[9], 14); + ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[11], 12); + ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[8], 13); + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[12], 5); + ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[2], 14); + ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[10], 13); + ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[0], 13); + ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[4], 7); + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[13], 5); + + /* round 4: right lane */ + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[8], 15); + ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[6], 5); + ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[4], 8); + ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[1], 11); + ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[3], 14); + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[11], 14); + ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[15], 6); + ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[0], 14); + ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[5], 6); + ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[12], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[2], 12); + ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[13], 9); + ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[9], 12); + ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[7], 5); + ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[10], 15); + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[14], 8); + + /* round 5: right lane */ + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[12], 8); + ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[15], 5); + ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[10], 12); + ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[4], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[1], 12); + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[5], 5); + ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[8], 14); + ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[7], 6); + ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[6], 8); + ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[2], 13); + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[13], 6); + ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[14], 5); + ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[0], 15); + ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[3], 13); + ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[9], 11); + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[11], 11); + + /* combine results */ + ddd += cc + state[1]; /* final result for state[0] */ + state[1] = state[2] + dd + eee; + state[2] = state[3] + ee + aaa; + state[3] = state[4] + aa + bbb; + state[4] = state[0] + bb + ccc; + state[0] = ddd; + + return; +} + +static inline void le32_to_cpu_array(u32 *buf, unsigned int words) +{ + while (words--) { + le32_to_cpus(buf); + buf++; + } +} + +static inline void cpu_to_le32_array(u32 *buf, unsigned int words) +{ + while (words--) { + cpu_to_le32s(buf); + buf++; + } +} + +static inline void rmd160_transform_helper(struct rmd160_ctx *ctx) +{ + le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); + rmd160_transform(ctx->state, ctx->buffer); +} + +static void rmd160_init(struct crypto_tfm *tfm) +{ + struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); + + rctx->byte_count = 0; + + rctx->state[0] = RMD_H0; + rctx->state[1] = RMD_H1; + rctx->state[2] = RMD_H2; + rctx->state[3] = RMD_H3; + rctx->state[4] = RMD_H4; + + memset(rctx->buffer, 0, sizeof(rctx->buffer)); +} + +static void rmd160_update(struct crypto_tfm *tfm, const u8 *data, + unsigned int len) +{ + struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); + const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); + + rctx->byte_count += len; + + /* Enough space in buffer? If so copy and we're done */ + if (avail > len) { + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, len); + return; + } + + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, avail); + + rmd160_transform_helper(rctx); + data += avail; + len -= avail; + + while (len >= sizeof(rctx->buffer)) { + memcpy(rctx->buffer, data, sizeof(rctx->buffer)); + rmd160_transform_helper(rctx); + data += sizeof(rctx->buffer); + len -= sizeof(rctx->buffer); + } + + memcpy(rctx->buffer, data, len); +} + +/* Add padding and return the message digest. */ +static void rmd160_final(struct crypto_tfm *tfm, u8 *out) +{ + struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); + u32 index, padlen; + u64 bits; + static const u8 padding[64] = { 0x80, }; + bits = rctx->byte_count << 3; + + /* Pad out to 56 mod 64 */ + index = rctx->byte_count & 0x3f; + padlen = (index < 56) ? (56 - index) : ((64+56) - index); + rmd160_update(tfm, padding, padlen); + + /* Append length */ + rmd160_update(tfm, (const u8 *)&bits, sizeof(bits)); + + /* Store state in digest */ + memcpy(out, rctx->state, sizeof(rctx->state)); + + /* Wipe context */ + memset(rctx, 0, sizeof(*rctx)); +} + +static struct crypto_alg alg = { + .cra_name = "rmd160", + .cra_driver_name = "rmd160", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = RMD160_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct rmd160_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = RMD160_DIGEST_SIZE, + .dia_init = rmd160_init, + .dia_update = rmd160_update, + .dia_final = rmd160_final } } +}; + +static int __init rmd160_mod_init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit rmd160_mod_fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(rmd160_mod_init); +module_exit(rmd160_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RIPEMD-160 Message Digest"); + +MODULE_ALIAS("rmd160"); -- cgit v0.10.2 From fd4adf1a0b1923f6126835e1097b2997eb0d27e2 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Wed, 7 May 2008 22:16:36 +0800 Subject: [CRYPTO] tcrypt: Add test vectors for RIPEMD-128 and RIPEMD-160 This patch adds test vectors for RIPEMD-128 and RIPEMD-160 hash algorithms and digests (HMAC). The test vectors are taken from ISO:IEC 10118-3 (2004) and RFC2286. Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e47f6e0..f6220b3 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -13,6 +13,7 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * + * 2008-04-27 Added RIPEMD tests * 2007-11-13 Added GCM tests * 2007-11-13 Added AEAD support * 2007-11-06 Added SHA-224 and SHA-224-HMAC tests @@ -83,7 +84,7 @@ static char *check[] = { "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", "seed", "salsa20", "lzo", "cts", NULL + "camellia", "seed", "salsa20", "rmd128", "rmd160", "lzo", "cts", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -1615,6 +1616,14 @@ static void do_test(void) CTS_MODE_DEC_TEST_VECTORS); break; + case 39: + test_hash("rmd128", rmd128_tv_template, RMD128_TEST_VECTORS); + break; + + case 40: + test_hash("rmd160", rmd160_tv_template, RMD160_TEST_VECTORS); + break; + case 100: test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); @@ -1650,6 +1659,16 @@ static void do_test(void) XCBC_AES_TEST_VECTORS); break; + case 107: + test_hash("hmac(rmd128)", hmac_rmd128_tv_template, + HMAC_RMD128_TEST_VECTORS); + break; + + case 108: + test_hash("hmac(rmd160)", hmac_rmd160_tv_template, + HMAC_RMD160_TEST_VECTORS); + break; + case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, speed_template_16_24_32); @@ -1788,6 +1807,14 @@ static void do_test(void) test_hash_speed("sha224", sec, generic_hash_speed_template); if (mode > 300 && mode < 400) break; + case 314: + test_hash_speed("rmd128", sec, generic_hash_speed_template); + if (mode > 300 && mode < 400) break; + + case 315: + test_hash_speed("rmd160", sec, generic_hash_speed_template); + if (mode > 300 && mode < 400) break; + case 399: break; diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index 47bc0ec..8906823 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -13,6 +13,7 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * + * 2008-04-27 Added RIPEMD tests * 2007-11-13 Added GCM tests * 2007-11-13 Added AEAD support * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests @@ -168,6 +169,135 @@ static struct hash_testvec md5_tv_template[] = { .digest = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55" "\xac\x49\xda\x2e\x21\x07\xb6\x7a", } + +}; + +/* + * RIPEMD-128 test vectors from ISO/IEC 10118-3:2004(E) + */ +#define RMD128_TEST_VECTORS 10 + +static struct hash_testvec rmd128_tv_template[] = { + { + .digest = "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e" + "\xcb\x61\x0f\x18\xf6\xb3\x8b\x46", + }, { + .plaintext = "a", + .psize = 1, + .digest = "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7" + "\xcf\xc7\x85\xe7\x2f\x57\x8d\x33", + }, { + .plaintext = "abc", + .psize = 3, + .digest = "\xc1\x4a\x12\x19\x9c\x66\xe4\xba" + "\x84\x63\x6b\x0f\x69\x14\x4c\x77", + }, { + .plaintext = "message digest", + .psize = 14, + .digest = "\x9e\x32\x7b\x3d\x6e\x52\x30\x62" + "\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8", + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyz", + .psize = 26, + .digest = "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5" + "\x10\x71\x49\x22\xb3\x71\x83\x4e", + }, { + .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" + "fghijklmnopqrstuvwxyz0123456789", + .psize = 62, + .digest = "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f" + "\xae\xa4\x62\x4c\x60\xc5\xc7\x02", + }, { + .plaintext = "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + .psize = 80, + .digest = "\x3f\x45\xef\x19\x47\x32\xc2\xdb" + "\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3", + }, { + .plaintext = "abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d" + "\xdc\x22\xe8\x8b\x49\x13\x3a\x06", + .np = 2, + .tap = { 28, 28 }, + }, { + .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi" + "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr" + "lmnopqrsmnopqrstnopqrstu", + .psize = 112, + .digest = "\xd4\xec\xc9\x13\xe1\xdf\x77\x6b" + "\xf4\x8d\xe9\xd5\x5b\x1f\x25\x46", + }, { + .plaintext = "abcdbcdecdefdefgefghfghighijhijk", + .psize = 32, + .digest = "\x13\xfc\x13\xe8\xef\xff\x34\x7d" + "\xe1\x93\xff\x46\xdb\xac\xcf\xd4", + } +}; + +/* + * RIPEMD-160 test vectors from ISO/IEC 10118-3:2004(E) + */ +#define RMD160_TEST_VECTORS 10 + +static struct hash_testvec rmd160_tv_template[] = { + { + .digest = "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" + "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31", + }, { + .plaintext = "a", + .psize = 1, + .digest = "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae" + "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe", + }, { + .plaintext = "abc", + .psize = 3, + .digest = "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04" + "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc", + }, { + .plaintext = "message digest", + .psize = 14, + .digest = "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" + "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36", + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyz", + .psize = 26, + .digest = "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb" + "\xdc\xeb\x5b\x9d\x28\x65\xb3\x70\x8d\xbc", + }, { + .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" + "fghijklmnopqrstuvwxyz0123456789", + .psize = 62, + .digest = "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed" + "\x3a\x87\xa5\x71\x30\x79\xb2\x1f\x51\x89", + }, { + .plaintext = "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + .psize = 80, + .digest = "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb" + "\xd3\x32\x3c\xab\x82\xbf\x63\x32\x6b\xfb", + }, { + .plaintext = "abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05" + "\xa0\x6c\x27\xdc\xf4\x9a\xda\x62\xeb\x2b", + .np = 2, + .tap = { 28, 28 }, + }, { + .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi" + "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr" + "lmnopqrsmnopqrstnopqrstu", + .psize = 112, + .digest = "\x6f\x3f\xa3\x9b\x6b\x50\x3c\x38\x4f\x91" + "\x9a\x49\xa7\xaa\x5c\x2c\x08\xbd\xfb\x45", + }, { + .plaintext = "abcdbcdecdefdefgefghfghighijhijk", + .psize = 32, + .digest = "\x94\xc2\x64\x11\x54\x04\xe6\x33\x79\x0d" + "\xfc\xc8\x7b\x58\x7d\x36\x77\x06\x7d\x9f", + } }; /* @@ -817,6 +947,168 @@ static struct hash_testvec hmac_md5_tv_template[] = }; /* + * HMAC-RIPEMD128 test vectors from RFC2286 + */ +#define HMAC_RMD128_TEST_VECTORS 7 + +static struct hash_testvec hmac_rmd128_tv_template[] = { + { + .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + .ksize = 16, + .plaintext = "Hi There", + .psize = 8, + .digest = "\xfb\xf6\x1f\x94\x92\xaa\x4b\xbf" + "\x81\xc1\x72\xe8\x4e\x07\x34\xdb", + }, { + .key = "Jefe", + .ksize = 4, + .plaintext = "what do ya want for nothing?", + .psize = 28, + .digest = "\x87\x5f\x82\x88\x62\xb6\xb3\x34" + "\xb4\x27\xc5\x5f\x9f\x7f\xf0\x9b", + .np = 2, + .tap = { 14, 14 }, + }, { + .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", + .ksize = 16, + .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", + .psize = 50, + .digest = "\x09\xf0\xb2\x84\x6d\x2f\x54\x3d" + "\xa3\x63\xcb\xec\x8d\x62\xa3\x8d", + }, { + .key = "\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19", + .ksize = 25, + .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", + .psize = 50, + .digest = "\xbd\xbb\xd7\xcf\x03\xe4\x4b\x5a" + "\xa6\x0a\xf8\x15\xbe\x4d\x22\x94", + }, { + .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", + .ksize = 16, + .plaintext = "Test With Truncation", + .psize = 20, + .digest = "\xe7\x98\x08\xf2\x4b\x25\xfd\x03" + "\x1c\x15\x5f\x0d\x55\x1d\x9a\x3a", + }, { + .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa", + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First", + .psize = 54, + .digest = "\xdc\x73\x29\x28\xde\x98\x10\x4a" + "\x1f\x59\xd3\x73\xc1\x50\xac\xbb", + }, { + .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa", + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", + .psize = 73, + .digest = "\x5c\x6b\xec\x96\x79\x3e\x16\xd4" + "\x06\x90\xc2\x37\x63\x5f\x30\xc5", + }, +}; + +/* + * HMAC-RIPEMD160 test vectors from RFC2286 + */ +#define HMAC_RMD160_TEST_VECTORS 7 + +static struct hash_testvec hmac_rmd160_tv_template[] = { + { + .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + .ksize = 20, + .plaintext = "Hi There", + .psize = 8, + .digest = "\x24\xcb\x4b\xd6\x7d\x20\xfc\x1a\x5d\x2e" + "\xd7\x73\x2d\xcc\x39\x37\x7f\x0a\x56\x68", + }, { + .key = "Jefe", + .ksize = 4, + .plaintext = "what do ya want for nothing?", + .psize = 28, + .digest = "\xdd\xa6\xc0\x21\x3a\x48\x5a\x9e\x24\xf4" + "\x74\x20\x64\xa7\xf0\x33\xb4\x3c\x40\x69", + .np = 2, + .tap = { 14, 14 }, + }, { + .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", + .ksize = 20, + .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", + .psize = 50, + .digest = "\xb0\xb1\x05\x36\x0d\xe7\x59\x96\x0a\xb4" + "\xf3\x52\x98\xe1\x16\xe2\x95\xd8\xe7\xc1", + }, { + .key = "\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19", + .ksize = 25, + .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", + .psize = 50, + .digest = "\xd5\xca\x86\x2f\x4d\x21\xd5\xe6\x10\xe1" + "\x8b\x4c\xf1\xbe\xb9\x7a\x43\x65\xec\xf4", + }, { + .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", + .ksize = 20, + .plaintext = "Test With Truncation", + .psize = 20, + .digest = "\x76\x19\x69\x39\x78\xf9\x1d\x90\x53\x9a" + "\xe7\x86\x50\x0f\xf3\xd8\xe0\x51\x8e\x39", + }, { + .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa", + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First", + .psize = 54, + .digest = "\x64\x66\xca\x07\xac\x5e\xac\x29\xe1\xbd" + "\x52\x3e\x5a\xda\x76\x05\xb7\x91\xfd\x8b", + }, { + .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa", + .ksize = 80, + .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One " + "Block-Size Data", + .psize = 73, + .digest = "\x69\xea\x60\x79\x8d\x71\x61\x6c\xce\x5f" + "\xd0\x87\x1e\x23\x75\x4c\xd7\x5d\x5a\x0a", + }, +}; + +/* * HMAC-SHA1 test vectors from RFC2202 */ #define HMAC_SHA1_TEST_VECTORS 7 -- cgit v0.10.2 From 82798f90fb13fd934a15ed56fee227fe808dcbe8 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Wed, 7 May 2008 22:17:37 +0800 Subject: [CRYPTO] ripemd: Add Kconfig entries for RIPEMD hash algorithms This patch adds Kconfig entries for RIPEMD-128 and RIPEMD-160. Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/Kconfig b/crypto/Kconfig index 864456c..cfc521a 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -241,6 +241,32 @@ config CRYPTO_MICHAEL_MIC should not be used for other purposes because of the weakness of the algorithm. +config CRYPTO_RMD128 + tristate "RIPEMD-128 digest algorithm" + select CRYPTO_ALGAPI + help + RIPEMD-128 (ISO/IEC 10118-3:2004). + + RIPEMD-128 is a 128-bit cryptographic hash function. It should only + to be used as a secure replacement for RIPEMD. For other use cases + RIPEMD-160 should be used. + + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. + See + +config CRYPTO_RMD160 + tristate "RIPEMD-160 digest algorithm" + select CRYPTO_ALGAPI + help + RIPEMD-160 (ISO/IEC 10118-3:2004). + + RIPEMD-160 is a 160-bit cryptographic hash function. It is intended + to be used as a secure replacement for the 128-bit hash functions + MD4, MD5 and it's predecessor RIPEMD (not to be confused with RIPEMD-128). + + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. + See + config CRYPTO_SHA1 tristate "SHA1 digest algorithm" select CRYPTO_ALGAPI -- cgit v0.10.2 From b10c170638c1f75bf582a75442fcdf27057ff537 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 7 May 2008 22:19:38 +0800 Subject: [CRYPTO] tcrpyt: Get rid of change log in source Change logs should be kept in source control systems, not the source. This patch removes the change log from tcrpyt to stop people from extending it any more. Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index f6220b3..285c093 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -13,14 +13,6 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 2008-04-27 Added RIPEMD tests - * 2007-11-13 Added GCM tests - * 2007-11-13 Added AEAD support - * 2007-11-06 Added SHA-224 and SHA-224-HMAC tests - * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests - * 2004-08-09 Added cipher speed tests (Reyk Floeter ) - * 2003-09-14 Rewritten by Kartikey Mahendra Bhatt - * */ #include diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index 8906823..af91f0c 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -13,13 +13,6 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 2008-04-27 Added RIPEMD tests - * 2007-11-13 Added GCM tests - * 2007-11-13 Added AEAD support - * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests - * 2004-08-09 Cipher speed tests by Reyk Floeter - * 2003-09-14 Changes by Kartikey Mahendra Bhatt - * */ #ifndef _CRYPTO_TCRYPT_H #define _CRYPTO_TCRYPT_H -- cgit v0.10.2 From 3c42cbc2e01238778db92e16873a6e6f015a00af Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:28:27 +0800 Subject: [HIFN]: Endianess fixes HIFN uses little-endian by default, move cpu_to_le32 conversion to hifn_write_0/ hifn_write_1, add sparse annotations and fix an invalid endian conversion in hifn_setup_src_desc. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 81f3f95..d7a51ee 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -535,10 +535,10 @@ struct hifn_crypt_command */ struct hifn_mac_command { - volatile u16 masks; - volatile u16 header_skip; - volatile u16 source_count; - volatile u16 reserved; + volatile __le16 masks; + volatile __le16 header_skip; + volatile __le16 source_count; + volatile __le16 reserved; }; #define HIFN_MAC_CMD_ALG_MASK 0x0001 @@ -564,10 +564,10 @@ struct hifn_mac_command struct hifn_comp_command { - volatile u16 masks; - volatile u16 header_skip; - volatile u16 source_count; - volatile u16 reserved; + volatile __le16 masks; + volatile __le16 header_skip; + volatile __le16 source_count; + volatile __le16 reserved; }; #define HIFN_COMP_CMD_SRCLEN_M 0xc000 @@ -583,10 +583,10 @@ struct hifn_comp_command struct hifn_base_result { - volatile u16 flags; - volatile u16 session; - volatile u16 src_cnt; /* 15:0 of source count */ - volatile u16 dst_cnt; /* 15:0 of dest count */ + volatile __le16 flags; + volatile __le16 session; + volatile __le16 src_cnt; /* 15:0 of source count */ + volatile __le16 dst_cnt; /* 15:0 of dest count */ }; #define HIFN_BASE_RES_DSTOVERRUN 0x0200 /* destination overrun */ @@ -597,8 +597,8 @@ struct hifn_base_result struct hifn_comp_result { - volatile u16 flags; - volatile u16 crc; + volatile __le16 flags; + volatile __le16 crc; }; #define HIFN_COMP_RES_LCB_M 0xff00 /* longitudinal check byte */ @@ -609,8 +609,8 @@ struct hifn_comp_result struct hifn_mac_result { - volatile u16 flags; - volatile u16 reserved; + volatile __le16 flags; + volatile __le16 reserved; /* followed by 0, 6, 8, or 10 u16's of the MAC, then crypt */ }; @@ -619,8 +619,8 @@ struct hifn_mac_result struct hifn_crypt_result { - volatile u16 flags; - volatile u16 reserved; + volatile __le16 flags; + volatile __le16 reserved; }; #define HIFN_CRYPT_RES_SRC_NOTZERO 0x0001 /* source expired */ @@ -686,12 +686,12 @@ static inline u32 hifn_read_1(struct hifn_device *dev, u32 reg) static inline void hifn_write_0(struct hifn_device *dev, u32 reg, u32 val) { - writel(val, dev->bar[0] + reg); + writel((__force u32)cpu_to_le32(val), dev->bar[0] + reg); } static inline void hifn_write_1(struct hifn_device *dev, u32 reg, u32 val) { - writel(val, dev->bar[1] + reg); + writel((__force u32)cpu_to_le32(val), dev->bar[1] + reg); } static void hifn_wait_puc(struct hifn_device *dev) @@ -1037,14 +1037,14 @@ static void hifn_init_registers(struct hifn_device *dev) hifn_write_0(dev, HIFN_0_PUIER, HIFN_PUIER_DSTOVER); /* write all 4 ring address registers */ - hifn_write_1(dev, HIFN_1_DMA_CRAR, __cpu_to_le32(dptr + - offsetof(struct hifn_dma, cmdr[0]))); - hifn_write_1(dev, HIFN_1_DMA_SRAR, __cpu_to_le32(dptr + - offsetof(struct hifn_dma, srcr[0]))); - hifn_write_1(dev, HIFN_1_DMA_DRAR, __cpu_to_le32(dptr + - offsetof(struct hifn_dma, dstr[0]))); - hifn_write_1(dev, HIFN_1_DMA_RRAR, __cpu_to_le32(dptr + - offsetof(struct hifn_dma, resr[0]))); + hifn_write_1(dev, HIFN_1_DMA_CRAR, dptr + + offsetof(struct hifn_dma, cmdr[0])); + hifn_write_1(dev, HIFN_1_DMA_SRAR, dptr + + offsetof(struct hifn_dma, srcr[0])); + hifn_write_1(dev, HIFN_1_DMA_DRAR, dptr + + offsetof(struct hifn_dma, dstr[0])); + hifn_write_1(dev, HIFN_1_DMA_RRAR, dptr + + offsetof(struct hifn_dma, resr[0])); mdelay(2); #if 0 @@ -1178,8 +1178,8 @@ static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page, idx = dma->srci; dma->srcr[idx].p = __cpu_to_le32(addr); - dma->srcr[idx].l = __cpu_to_le32(size) | HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST; + dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | + HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); if (++idx == HIFN_D_SRC_RSIZE) { dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID | -- cgit v0.10.2 From 7808f0738f9ac5cff05bd89ee457334b9a029b5c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:29:42 +0800 Subject: [HIFN]: Remove printk_ratelimit() for debugging printk Without debugging this spams the log with "printk: N messages surpressed" without any actual messages on error. With debugging its more useful to always see the message. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d7a51ee..e5c3bc4 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -1651,7 +1651,7 @@ static int hifn_setup_session(struct ablkcipher_request *req) err_out: spin_unlock_irqrestore(&dev->lock, flags); err_out_exit: - if (err && printk_ratelimit()) + if (err) dprintk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, " "type: %u, err: %d.\n", dev->name, ctx->iv, ctx->ivsize, -- cgit v0.10.2 From 9e70a408ad66846bc98dc026efe0384ef68373fc Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:31:35 +0800 Subject: [HIFN]: Indicate asynchronous processing to crypto API hifn_setup_crypto() needs to return -EINPROGRESS on success to indicate asynchronous processing to the crypto API. This also means it must not return the errno code returned by hifn_process_queue(), if any. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index e5c3bc4..cce6e6f 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -2202,9 +2202,9 @@ static int hifn_setup_crypto(struct ablkcipher_request *req, u8 op, return err; if (dev->started < HIFN_QUEUE_LENGTH && dev->queue.qlen) - err = hifn_process_queue(dev); + hifn_process_queue(dev); - return err; + return -EINPROGRESS; } /* -- cgit v0.10.2 From 94eaa1bd7ca67e8f57919da96cbb41c215ef20cb Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:32:28 +0800 Subject: [HIFN]: Handle ablkcipher_walk errors ablkcipher_walk may return a negative error value, handle this properly instead of treating it as a huge number of scatter-gather elements. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index cce6e6f..4e89cd8 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -1602,7 +1602,10 @@ static int hifn_setup_session(struct ablkcipher_request *req) idx = 0; sg_num = ablkcipher_walk(req, &ctx->walk); - + if (sg_num < 0) { + err = sg_num; + goto err_out_exit; + } atomic_set(&ctx->sg_num, sg_num); spin_lock_irqsave(&dev->lock, flags); -- cgit v0.10.2 From d069033b42b392662320f71e319296a14d57ff3a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:33:37 +0800 Subject: [HIFN]: Fix data alignment checks The check for misalignment of the scatterlist data has two bugs: - the source buffer doesn't need to be aligned at all - the destination buffer and its size needs to be aligned to a multiple of 4, not to the crypto alg blocksize Introduce symbolic constant for destination buffer alignment requirements, use it instead of the crypto alg blocksize and remove the unnecessary checks for source buffer alignment and change cra_alignmask to zero. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 4e89cd8..4428e8e 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -369,6 +369,8 @@ static atomic_t hifn_dev_number; #define HIFN_D_DST_RSIZE 80*4 #define HIFN_D_RES_RSIZE 24*4 +#define HIFN_D_DST_DALIGN 4 + #define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-5 #define AES_MIN_KEY_SIZE 16 @@ -1458,10 +1460,6 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist static int ablkcipher_walk(struct ablkcipher_request *req, struct ablkcipher_walk *w) { - unsigned blocksize = - crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req)); - unsigned alignmask = - crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req)); struct scatterlist *src, *dst, *t; void *daddr; unsigned int nbytes = req->nbytes, offset, copy, diff; @@ -1477,15 +1475,13 @@ static int ablkcipher_walk(struct ablkcipher_request *req, dst = &req->dst[idx]; dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, " - "blocksize: %u, nbytes: %u.\n", + "nbytes: %u.\n", __func__, src->length, dst->length, src->offset, - dst->offset, offset, blocksize, nbytes); + dst->offset, offset, nbytes); - if (src->length & (blocksize - 1) || - src->offset & (alignmask - 1) || - dst->length & (blocksize - 1) || - dst->offset & (alignmask - 1) || - offset) { + if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || + !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) || + offset) { unsigned slen = src->length - offset; unsigned dlen = PAGE_SIZE; @@ -1498,8 +1494,8 @@ static int ablkcipher_walk(struct ablkcipher_request *req, idx += err; - copy = slen & ~(blocksize - 1); - diff = slen & (blocksize - 1); + copy = slen & ~(HIFN_D_DST_DALIGN - 1); + diff = slen & (HIFN_D_DST_DALIGN - 1); if (dlen < nbytes) { /* @@ -1507,7 +1503,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req, * to put there additional blocksized chunk, * so we mark that page as containing only * blocksize aligned chunks: - * t->length = (slen & ~(blocksize - 1)); + * t->length = (slen & ~(HIFN_D_DST_DALIGN - 1)); * and increase number of bytes to be processed * in next chunk: * nbytes += diff; @@ -1567,10 +1563,6 @@ static int hifn_setup_session(struct ablkcipher_request *req) unsigned int nbytes = req->nbytes, idx = 0, len; int err = -EINVAL, sg_num; struct scatterlist *src, *dst, *t; - unsigned blocksize = - crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm(req)); - unsigned alignmask = - crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req)); if (ctx->iv && !ctx->ivsize && ctx->mode != ACRYPTO_MODE_ECB) goto err_out_exit; @@ -1578,17 +1570,13 @@ static int hifn_setup_session(struct ablkcipher_request *req) ctx->walk.flags = 0; while (nbytes) { - src = &req->src[idx]; dst = &req->dst[idx]; - if (src->length & (blocksize - 1) || - src->offset & (alignmask - 1) || - dst->length & (blocksize - 1) || - dst->offset & (alignmask - 1)) { + if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || + !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN)) ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; - } - nbytes -= src->length; + nbytes -= dst->length; idx++; } @@ -2523,9 +2511,7 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t) alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; alg->alg.cra_blocksize = t->bsize; alg->alg.cra_ctxsize = sizeof(struct hifn_context); - alg->alg.cra_alignmask = 15; - if (t->bsize == 8) - alg->alg.cra_alignmask = 3; + alg->alg.cra_alignmask = 0; alg->alg.cra_type = &crypto_ablkcipher_type; alg->alg.cra_module = THIS_MODULE; alg->alg.cra_u.ablkcipher = t->ablkcipher; -- cgit v0.10.2 From 136f702f51a4bfa38003660768e7153823fff8a1 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:34:27 +0800 Subject: [HIFN]: Properly handle requests for less than the full scatterlist The scatterlist may contain more data than the crypto request, causing an underflow of the remaining byte count while walking the list. Use the minimum of the scatterlist element size and the remaining byte count specified in the crypto request to avoid this. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 4428e8e..366e974 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -1433,7 +1433,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist return -EINVAL; while (size) { - copy = min(drest, src->length); + copy = min(drest, min(size, src->length)); saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1); memcpy(daddr, saddr + src->offset, copy); @@ -1482,7 +1482,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req, if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) || offset) { - unsigned slen = src->length - offset; + unsigned slen = min(src->length - offset, nbytes); unsigned dlen = PAGE_SIZE; t = &w->cache[idx]; @@ -1540,7 +1540,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req, kunmap_atomic(daddr, KM_SOFTIRQ0); } else { - nbytes -= src->length; + nbytes -= min(src->length, nbytes); idx++; } @@ -1559,7 +1559,7 @@ static int hifn_setup_session(struct ablkcipher_request *req) struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); struct hifn_device *dev = ctx->dev; struct page *spage, *dpage; - unsigned long soff, doff, flags; + unsigned long soff, doff, dlen, flags; unsigned int nbytes = req->nbytes, idx = 0, len; int err = -EINVAL, sg_num; struct scatterlist *src, *dst, *t; @@ -1571,12 +1571,13 @@ static int hifn_setup_session(struct ablkcipher_request *req) while (nbytes) { dst = &req->dst[idx]; + dlen = min(dst->length, nbytes); if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || - !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN)) + !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN)) ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; - nbytes -= dst->length; + nbytes -= dlen; idx++; } @@ -1631,7 +1632,7 @@ static int hifn_setup_session(struct ablkcipher_request *req) if (err) goto err_out; - nbytes -= len; + nbytes -= min(len, nbytes); } dev->active = HIFN_DEFAULT_ACTIVE_NUM; @@ -1736,8 +1737,7 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset return -EINVAL; while (size) { - - copy = min(dst->length, srest); + copy = min(srest, min(dst->length, size)); daddr = kmap_atomic(sg_page(dst), KM_IRQ0); memcpy(daddr + dst->offset + offset, saddr, copy); @@ -1794,7 +1794,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error) sg_page(dst), dst->length, nbytes); if (!t->length) { - nbytes -= dst->length; + nbytes -= min(dst->length, nbytes); idx++; continue; } -- cgit v0.10.2 From 281d6bd45385c689e7c03c9ff2434c143971682d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:35:07 +0800 Subject: [HIFN]: Use unique driver names for different algos When the CryptoAPI instantiates a new algorithm, it performs a lookup by driver name. Since hifn uses the same name for all modes of one algorithm, the lookup may return an incorrect algorithm. Change the name to use -- to provide unique names for the different combinations and devices. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 366e974..d09338f 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -2355,7 +2355,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { * 3DES ECB, CBC, CFB and OFB modes. */ { - .name = "cfb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8, + .name = "cfb(des3_ede)", .drv_name = "cfb-3des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_3DES_KEY_LENGTH, .max_keysize = HIFN_3DES_KEY_LENGTH, @@ -2365,7 +2365,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "ofb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8, + .name = "ofb(des3_ede)", .drv_name = "ofb-3des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_3DES_KEY_LENGTH, .max_keysize = HIFN_3DES_KEY_LENGTH, @@ -2375,7 +2375,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "cbc(des3_ede)", .drv_name = "hifn-3des", .bsize = 8, + .name = "cbc(des3_ede)", .drv_name = "cbc-3des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_3DES_KEY_LENGTH, .max_keysize = HIFN_3DES_KEY_LENGTH, @@ -2385,7 +2385,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "ecb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8, + .name = "ecb(des3_ede)", .drv_name = "ecb-3des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_3DES_KEY_LENGTH, .max_keysize = HIFN_3DES_KEY_LENGTH, @@ -2399,7 +2399,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { * DES ECB, CBC, CFB and OFB modes. */ { - .name = "cfb(des)", .drv_name = "hifn-des", .bsize = 8, + .name = "cfb(des)", .drv_name = "cfb-des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_DES_KEY_LENGTH, .max_keysize = HIFN_DES_KEY_LENGTH, @@ -2409,7 +2409,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "ofb(des)", .drv_name = "hifn-des", .bsize = 8, + .name = "ofb(des)", .drv_name = "ofb-des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_DES_KEY_LENGTH, .max_keysize = HIFN_DES_KEY_LENGTH, @@ -2419,7 +2419,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "cbc(des)", .drv_name = "hifn-des", .bsize = 8, + .name = "cbc(des)", .drv_name = "cbc-des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_DES_KEY_LENGTH, .max_keysize = HIFN_DES_KEY_LENGTH, @@ -2429,7 +2429,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "ecb(des)", .drv_name = "hifn-des", .bsize = 8, + .name = "ecb(des)", .drv_name = "ecb-des", .bsize = 8, .ablkcipher = { .min_keysize = HIFN_DES_KEY_LENGTH, .max_keysize = HIFN_DES_KEY_LENGTH, @@ -2443,7 +2443,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { * AES ECB, CBC, CFB and OFB modes. */ { - .name = "ecb(aes)", .drv_name = "hifn-aes", .bsize = 16, + .name = "ecb(aes)", .drv_name = "ecb-aes", .bsize = 16, .ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, @@ -2453,7 +2453,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "cbc(aes)", .drv_name = "hifn-aes", .bsize = 16, + .name = "cbc(aes)", .drv_name = "cbc-aes", .bsize = 16, .ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, @@ -2463,7 +2463,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "cfb(aes)", .drv_name = "hifn-aes", .bsize = 16, + .name = "cfb(aes)", .drv_name = "cfb-aes", .bsize = 16, .ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, @@ -2473,7 +2473,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { }, }, { - .name = "ofb(aes)", .drv_name = "hifn-aes", .bsize = 16, + .name = "ofb(aes)", .drv_name = "ofb-aes", .bsize = 16, .ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, @@ -2505,7 +2505,8 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t) return -ENOMEM; snprintf(alg->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s", t->name); - snprintf(alg->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", t->drv_name); + snprintf(alg->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-%s", + t->drv_name, dev->name); alg->alg.cra_priority = 300; alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; -- cgit v0.10.2 From 4b804b53ef5a3c1a49c11bfff2754e0334cc932e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:35:47 +0800 Subject: [HIFN]: Properly initialize ivsize for CBC modes For combined modes like cbc(aes) the driver is responsible for initializing ivsize. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d09338f..a4b1cea 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -2377,6 +2377,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { { .name = "cbc(des3_ede)", .drv_name = "cbc-3des", .bsize = 8, .ablkcipher = { + .ivsize = HIFN_IV_LENGTH, .min_keysize = HIFN_3DES_KEY_LENGTH, .max_keysize = HIFN_3DES_KEY_LENGTH, .setkey = hifn_setkey, @@ -2421,6 +2422,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { { .name = "cbc(des)", .drv_name = "cbc-des", .bsize = 8, .ablkcipher = { + .ivsize = HIFN_IV_LENGTH, .min_keysize = HIFN_DES_KEY_LENGTH, .max_keysize = HIFN_DES_KEY_LENGTH, .setkey = hifn_setkey, @@ -2455,6 +2457,7 @@ static struct hifn_alg_template hifn_alg_templates[] = { { .name = "cbc(aes)", .drv_name = "cbc-aes", .bsize = 16, .ablkcipher = { + .ivsize = HIFN_AES_IV_LENGTH, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .setkey = hifn_setkey, -- cgit v0.10.2 From 6cd3d674ddd1706226d4c395440ef1997fd72381 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:36:17 +0800 Subject: [HIFN]: Fix max queue length value All but the last element of the command and result descriptor rings can be used for crypto requests, fix HIFN_QUEUE_LENGTH. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index a4b1cea..d6f0423 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -371,7 +371,7 @@ static atomic_t hifn_dev_number; #define HIFN_D_DST_DALIGN 4 -#define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-5 +#define HIFN_QUEUE_LENGTH HIFN_D_CMD_RSIZE-1 #define AES_MIN_KEY_SIZE 16 #define AES_MAX_KEY_SIZE 32 -- cgit v0.10.2 From 85e7e60b856141cc9831e11cdfc8e9265886abac Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:36:54 +0800 Subject: [HIFN]: Move command descriptor setup to seperate function Move command descriptor setup to seperate function as preparation for the following DMA setup fixes. Note 1: also fix a harmless typo while moving it: sa_idx is initialized to dma->resi instead of dma->cmdi. Note 2: errors from command descriptor setup are not propagated back, anymore, they can't be handled anyway and all conditions leading to errors should be checked earlier. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d6f0423..c9fe18d 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -1168,109 +1168,15 @@ static int hifn_setup_crypto_command(struct hifn_device *dev, return cmd_len; } -static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page, - unsigned int offset, unsigned int size) -{ - struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; - int idx; - dma_addr_t addr; - - addr = pci_map_page(dev->pdev, page, offset, size, PCI_DMA_TODEVICE); - - idx = dma->srci; - - dma->srcr[idx].p = __cpu_to_le32(addr); - dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); - - if (++idx == HIFN_D_SRC_RSIZE) { - dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID | - HIFN_D_JUMP | - HIFN_D_MASKDONEIRQ | HIFN_D_LAST); - idx = 0; - } - - dma->srci = idx; - dma->srcu++; - - if (!(dev->flags & HIFN_FLAG_SRC_BUSY)) { - hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); - dev->flags |= HIFN_FLAG_SRC_BUSY; - } - - return size; -} - -static void hifn_setup_res_desc(struct hifn_device *dev) -{ - struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; - - dma->resr[dma->resi].l = __cpu_to_le32(HIFN_USED_RESULT | - HIFN_D_VALID | HIFN_D_LAST); - /* - * dma->resr[dma->resi].l = __cpu_to_le32(HIFN_MAX_RESULT | HIFN_D_VALID | - * HIFN_D_LAST | HIFN_D_NOINVALID); - */ - - if (++dma->resi == HIFN_D_RES_RSIZE) { - dma->resr[HIFN_D_RES_RSIZE].l = __cpu_to_le32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | HIFN_D_LAST); - dma->resi = 0; - } - - dma->resu++; - - if (!(dev->flags & HIFN_FLAG_RES_BUSY)) { - hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA); - dev->flags |= HIFN_FLAG_RES_BUSY; - } -} - -static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page, - unsigned offset, unsigned size) -{ - struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; - int idx; - dma_addr_t addr; - - addr = pci_map_page(dev->pdev, page, offset, size, PCI_DMA_FROMDEVICE); - - idx = dma->dsti; - dma->dstr[idx].p = __cpu_to_le32(addr); - dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); - - if (++idx == HIFN_D_DST_RSIZE) { - dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID | - HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | - HIFN_D_LAST | HIFN_D_NOINVALID); - idx = 0; - } - dma->dsti = idx; - dma->dstu++; - - if (!(dev->flags & HIFN_FLAG_DST_BUSY)) { - hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); - dev->flags |= HIFN_FLAG_DST_BUSY; - } -} - -static int hifn_setup_dma(struct hifn_device *dev, struct page *spage, unsigned int soff, - struct page *dpage, unsigned int doff, unsigned int nbytes, void *priv, - struct hifn_context *ctx) +static int hifn_setup_cmd_desc(struct hifn_device *dev, + struct hifn_context *ctx, void *priv, unsigned int nbytes) { struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; int cmd_len, sa_idx; u8 *buf, *buf_pos; u16 mask; - dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, nbytes: %u, priv: %p, ctx: %p.\n", - dev->name, spage, soff, dpage, doff, nbytes, priv, ctx); - - sa_idx = dma->resi; - - hifn_setup_src_desc(dev, spage, soff, nbytes); - + sa_idx = dma->cmdi; buf_pos = buf = dma->command_bufs[dma->cmdi]; mask = 0; @@ -1372,16 +1278,113 @@ static int hifn_setup_dma(struct hifn_device *dev, struct page *spage, unsigned hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA); dev->flags |= HIFN_FLAG_CMD_BUSY; } - - hifn_setup_dst_desc(dev, dpage, doff, nbytes); - hifn_setup_res_desc(dev); - return 0; err_out: return -EINVAL; } +static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page, + unsigned int offset, unsigned int size) +{ + struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; + int idx; + dma_addr_t addr; + + addr = pci_map_page(dev->pdev, page, offset, size, PCI_DMA_TODEVICE); + + idx = dma->srci; + + dma->srcr[idx].p = __cpu_to_le32(addr); + dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | + HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); + + if (++idx == HIFN_D_SRC_RSIZE) { + dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID | + HIFN_D_JUMP | + HIFN_D_MASKDONEIRQ | HIFN_D_LAST); + idx = 0; + } + + dma->srci = idx; + dma->srcu++; + + if (!(dev->flags & HIFN_FLAG_SRC_BUSY)) { + hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA); + dev->flags |= HIFN_FLAG_SRC_BUSY; + } + + return size; +} + +static void hifn_setup_res_desc(struct hifn_device *dev) +{ + struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; + + dma->resr[dma->resi].l = __cpu_to_le32(HIFN_USED_RESULT | + HIFN_D_VALID | HIFN_D_LAST); + /* + * dma->resr[dma->resi].l = __cpu_to_le32(HIFN_MAX_RESULT | HIFN_D_VALID | + * HIFN_D_LAST | HIFN_D_NOINVALID); + */ + + if (++dma->resi == HIFN_D_RES_RSIZE) { + dma->resr[HIFN_D_RES_RSIZE].l = __cpu_to_le32(HIFN_D_VALID | + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | HIFN_D_LAST); + dma->resi = 0; + } + + dma->resu++; + + if (!(dev->flags & HIFN_FLAG_RES_BUSY)) { + hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA); + dev->flags |= HIFN_FLAG_RES_BUSY; + } +} + +static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page, + unsigned offset, unsigned size) +{ + struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt; + int idx; + dma_addr_t addr; + + addr = pci_map_page(dev->pdev, page, offset, size, PCI_DMA_FROMDEVICE); + + idx = dma->dsti; + dma->dstr[idx].p = __cpu_to_le32(addr); + dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | + HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); + + if (++idx == HIFN_D_DST_RSIZE) { + dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID | + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | + HIFN_D_LAST | HIFN_D_NOINVALID); + idx = 0; + } + dma->dsti = idx; + dma->dstu++; + + if (!(dev->flags & HIFN_FLAG_DST_BUSY)) { + hifn_write_1(dev, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); + dev->flags |= HIFN_FLAG_DST_BUSY; + } +} + +static int hifn_setup_dma(struct hifn_device *dev, struct page *spage, unsigned int soff, + struct page *dpage, unsigned int doff, unsigned int nbytes, void *priv, + struct hifn_context *ctx) +{ + dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, nbytes: %u, priv: %p, ctx: %p.\n", + dev->name, spage, soff, dpage, doff, nbytes, priv, ctx); + + hifn_setup_src_desc(dev, spage, soff, nbytes); + hifn_setup_cmd_desc(dev, ctx, priv, nbytes); + hifn_setup_dst_desc(dev, dpage, doff, nbytes); + hifn_setup_res_desc(dev); + return 0; +} + static int ablkcipher_walk_init(struct ablkcipher_walk *w, int num, gfp_t gfp_flags) { -- cgit v0.10.2 From 692af5da779e018fc6a3b480b67adb33e3c6e1f0 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 7 May 2008 22:37:29 +0800 Subject: [HIFN]: Have HW invalidate src and dest descriptors after processing The descriptors need to be invalidated after processing for ring cleanup to work properly and to avoid using an old destination descriptor when the src and cmd descriptors are already set up and the dst descriptor isn't. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index c9fe18d..459d283 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -1297,7 +1297,7 @@ static int hifn_setup_src_desc(struct hifn_device *dev, struct page *page, dma->srcr[idx].p = __cpu_to_le32(addr); dma->srcr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); + HIFN_D_MASKDONEIRQ | HIFN_D_LAST); if (++idx == HIFN_D_SRC_RSIZE) { dma->srcr[idx].l = __cpu_to_le32(HIFN_D_VALID | @@ -1325,7 +1325,7 @@ static void hifn_setup_res_desc(struct hifn_device *dev) HIFN_D_VALID | HIFN_D_LAST); /* * dma->resr[dma->resi].l = __cpu_to_le32(HIFN_MAX_RESULT | HIFN_D_VALID | - * HIFN_D_LAST | HIFN_D_NOINVALID); + * HIFN_D_LAST); */ if (++dma->resi == HIFN_D_RES_RSIZE) { @@ -1354,12 +1354,12 @@ static void hifn_setup_dst_desc(struct hifn_device *dev, struct page *page, idx = dma->dsti; dma->dstr[idx].p = __cpu_to_le32(addr); dma->dstr[idx].l = __cpu_to_le32(size | HIFN_D_VALID | - HIFN_D_MASKDONEIRQ | HIFN_D_NOINVALID | HIFN_D_LAST); + HIFN_D_MASKDONEIRQ | HIFN_D_LAST); if (++idx == HIFN_D_DST_RSIZE) { dma->dstr[idx].l = __cpu_to_le32(HIFN_D_VALID | HIFN_D_JUMP | HIFN_D_MASKDONEIRQ | - HIFN_D_LAST | HIFN_D_NOINVALID); + HIFN_D_LAST); idx = 0; } dma->dsti = idx; -- cgit v0.10.2 From a558f1d4f8730f055b004b4c8ca1605aeb957daa Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 8 May 2008 19:27:47 +0800 Subject: [CRYPTO] tcrypt: Catch cipher destination memory corruption Check whether the destination buffer is written to beyond the last byte contained in the scatterlist. Also change IDX1 of the cross-page access offsets to a multiple of 4. This triggers a corruption in the HIFN driver and doesn't seem to negatively impact other testcases. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 285c093..69eb29e 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -39,7 +39,7 @@ /* * Indexes into the xbuf to simulate cross-page access. */ -#define IDX1 37 +#define IDX1 32 #define IDX2 32400 #define IDX3 1 #define IDX4 8193 @@ -211,7 +211,7 @@ out: static void test_aead(char *algo, int enc, struct aead_testvec *template, unsigned int tcount) { - unsigned int ret, i, j, k, temp; + unsigned int ret, i, j, k, n, temp; char *q; struct crypto_aead *tfm; char *key; @@ -353,7 +353,6 @@ next_one: } printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e); - memset(xbuf, 0, XBUFSIZE); memset(axbuf, 0, XBUFSIZE); for (i = 0, j = 0; i < tcount; i++) { @@ -381,6 +380,7 @@ next_one: goto out; } + memset(xbuf, 0, XBUFSIZE); sg_init_table(sg, template[i].np); for (k = 0, temp = 0; k < template[i].np; k++) { memcpy(&xbuf[IDX[k]], @@ -452,6 +452,14 @@ next_one: 0 : authsize)) ? "fail" : "pass"); + for (n = 0; q[template[i].tap[k] + n]; n++) + ; + if (n) { + printk("Result buffer corruption %u " + "bytes:\n", n); + hexdump(&q[template[i].tap[k]], n); + } + temp += template[i].tap[k]; kunmap(sg_page(&sg[k])); } @@ -466,7 +474,7 @@ out: static void test_cipher(char *algo, int enc, struct cipher_testvec *template, unsigned int tcount) { - unsigned int ret, i, j, k, temp; + unsigned int ret, i, j, k, n, temp; char *q; struct crypto_ablkcipher *tfm; struct ablkcipher_request *req; @@ -574,7 +582,6 @@ static void test_cipher(char *algo, int enc, } printk("\ntesting %s %s across pages (chunking)\n", algo, e); - memset(xbuf, 0, XBUFSIZE); j = 0; for (i = 0; i < tcount; i++) { @@ -589,6 +596,7 @@ static void test_cipher(char *algo, int enc, printk("test %u (%d bit key):\n", j, template[i].klen * 8); + memset(xbuf, 0, XBUFSIZE); crypto_ablkcipher_clear_flags(tfm, ~0); if (template[i].wk) crypto_ablkcipher_set_flags( @@ -648,6 +656,14 @@ static void test_cipher(char *algo, int enc, memcmp(q, template[i].result + temp, template[i].tap[k]) ? "fail" : "pass"); + + for (n = 0; q[template[i].tap[k] + n]; n++) + ; + if (n) { + printk("Result buffer corruption %u " + "bytes:\n", n); + hexdump(&q[template[i].tap[k]], n); + } temp += template[i].tap[k]; kunmap(sg_page(&sg[k])); } -- cgit v0.10.2 From ba6b0398721524ec817f74ea3492b48fa79de52f Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:25:42 +0800 Subject: [CRYPTO] ripemd: Put all common RIPEMD values in header file This patch puts all common RIPEMD values in the appropriate header file. Initial values and constants are the same for all variants of RIPEMD. Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/ripemd.h b/crypto/ripemd.h index 2858e22..c57a2d4 100644 --- a/crypto/ripemd.h +++ b/crypto/ripemd.h @@ -17,10 +17,27 @@ #define RMD320_DIGEST_SIZE 40 #define RMD320_BLOCK_SIZE 64 +/* initial values */ #define RMD_H0 0x67452301UL #define RMD_H1 0xefcdab89UL #define RMD_H2 0x98badcfeUL #define RMD_H3 0x10325476UL #define RMD_H4 0xc3d2e1f0UL +#define RMD_H5 0x76543210UL +#define RMD_H6 0xfedcba98UL +#define RMD_H7 0x89abcdefUL +#define RMD_H8 0x01234567UL +#define RMD_H9 0x3c2d1e0fUL + +/* constants */ +#define RMD_K1 0x00000000UL +#define RMD_K2 0x5a827999UL +#define RMD_K3 0x6ed9eba1UL +#define RMD_K4 0x8f1bbcdcUL +#define RMD_K5 0xa953fd4eUL +#define RMD_K6 0x50a28be6UL +#define RMD_K7 0x5c4dd124UL +#define RMD_K8 0x6d703ef3UL +#define RMD_K9 0x7a6d76e9UL #endif diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 22cc13b..f72d2ce8 100644 --- a/crypto/rmd128.c +++ b/crypto/rmd128.c @@ -29,14 +29,14 @@ struct rmd128_ctx { u32 buffer[16]; }; -#define K1 0x00000000UL -#define K2 0x5a827999UL -#define K3 0x6ed9eba1UL -#define K4 0x8f1bbcdcUL -#define KK1 0x50a28be6UL -#define KK2 0x5c4dd124UL -#define KK3 0x6d703ef3UL -#define KK4 0x00000000UL +#define K1 RMD_K1 +#define K2 RMD_K2 +#define K3 RMD_K3 +#define K4 RMD_K4 +#define KK1 RMD_K6 +#define KK2 RMD_K7 +#define KK3 RMD_K8 +#define KK4 RMD_K1 #define F1(x, y, z) (x ^ y ^ z) /* XOR */ #define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ diff --git a/crypto/rmd160.c b/crypto/rmd160.c index a8a9d3d..80d647a 100644 --- a/crypto/rmd160.c +++ b/crypto/rmd160.c @@ -29,16 +29,16 @@ struct rmd160_ctx { u32 buffer[16]; }; -#define K1 0x00000000UL -#define K2 0x5a827999UL -#define K3 0x6ed9eba1UL -#define K4 0x8f1bbcdcUL -#define K5 0xa953fd4eUL -#define KK1 0x50a28be6UL -#define KK2 0x5c4dd124UL -#define KK3 0x6d703ef3UL -#define KK4 0x7a6d76e9UL -#define KK5 0x00000000UL +#define K1 RMD_K1 +#define K2 RMD_K2 +#define K3 RMD_K3 +#define K4 RMD_K4 +#define K5 RMD_K5 +#define KK1 RMD_K6 +#define KK2 RMD_K7 +#define KK3 RMD_K8 +#define KK4 RMD_K9 +#define KK5 RMD_K1 #define F1(x, y, z) (x ^ y ^ z) /* XOR */ #define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ -- cgit v0.10.2 From c555c28d9da517579085a00fc80e725b0b5d9fce Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:27:02 +0800 Subject: [CRYPTO] ripemd: Add support for RIPEMD-256 and RIPEMD-320 This patch adds support for the extended RIPEMD hash algorithms RIPEMD-256 and RIPEMD-320. Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/Makefile b/crypto/Makefile index 1efb556..807656b 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -29,6 +29,8 @@ obj-$(CONFIG_CRYPTO_MD4) += md4.o obj-$(CONFIG_CRYPTO_MD5) += md5.o obj-$(CONFIG_CRYPTO_RMD128) += rmd128.o obj-$(CONFIG_CRYPTO_RMD160) += rmd160.o +obj-$(CONFIG_CRYPTO_RMD256) += rmd256.o +obj-$(CONFIG_CRYPTO_RMD320) += rmd320.o obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o diff --git a/crypto/rmd256.c b/crypto/rmd256.c new file mode 100644 index 0000000..060ee81 --- /dev/null +++ b/crypto/rmd256.c @@ -0,0 +1,363 @@ +/* + * Cryptographic API. + * + * RIPEMD-256 - RACE Integrity Primitives Evaluation Message Digest. + * + * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC + * + * Copyright (c) 2008 Adrian-Ken Rueegsegger + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "ripemd.h" + +struct rmd256_ctx { + u64 byte_count; + u32 state[8]; + u32 buffer[16]; +}; + +#define K1 RMD_K1 +#define K2 RMD_K2 +#define K3 RMD_K3 +#define K4 RMD_K4 +#define KK1 RMD_K6 +#define KK2 RMD_K7 +#define KK3 RMD_K8 +#define KK4 RMD_K1 + +#define F1(x, y, z) (x ^ y ^ z) /* XOR */ +#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define F3(x, y, z) ((x | ~y) ^ z) +#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ + +#define ROUND(a, b, c, d, f, k, x, s) { \ + (a) += f((b), (c), (d)) + (x) + (k); \ + (a) = rol32((a), (s)); \ +} + +static void rmd256_transform(u32 *state, u32 const *in) +{ + u32 aa, bb, cc, dd, aaa, bbb, ccc, ddd, tmp; + + /* Initialize left lane */ + aa = state[0]; + bb = state[1]; + cc = state[2]; + dd = state[3]; + + /* Initialize right lane */ + aaa = state[4]; + bbb = state[5]; + ccc = state[6]; + ddd = state[7]; + + /* round 1: left lane */ + ROUND(aa, bb, cc, dd, F1, K1, in[0], 11); + ROUND(dd, aa, bb, cc, F1, K1, in[1], 14); + ROUND(cc, dd, aa, bb, F1, K1, in[2], 15); + ROUND(bb, cc, dd, aa, F1, K1, in[3], 12); + ROUND(aa, bb, cc, dd, F1, K1, in[4], 5); + ROUND(dd, aa, bb, cc, F1, K1, in[5], 8); + ROUND(cc, dd, aa, bb, F1, K1, in[6], 7); + ROUND(bb, cc, dd, aa, F1, K1, in[7], 9); + ROUND(aa, bb, cc, dd, F1, K1, in[8], 11); + ROUND(dd, aa, bb, cc, F1, K1, in[9], 13); + ROUND(cc, dd, aa, bb, F1, K1, in[10], 14); + ROUND(bb, cc, dd, aa, F1, K1, in[11], 15); + ROUND(aa, bb, cc, dd, F1, K1, in[12], 6); + ROUND(dd, aa, bb, cc, F1, K1, in[13], 7); + ROUND(cc, dd, aa, bb, F1, K1, in[14], 9); + ROUND(bb, cc, dd, aa, F1, K1, in[15], 8); + + /* round 1: right lane */ + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[5], 8); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[14], 9); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[7], 9); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[0], 11); + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[9], 13); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[2], 15); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[11], 15); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[4], 5); + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[13], 7); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[6], 7); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[15], 8); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[8], 11); + ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[1], 14); + ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[10], 14); + ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[3], 12); + ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[12], 6); + + /* Swap contents of "a" registers */ + tmp = aa; aa = aaa; aaa = tmp; + + /* round 2: left lane */ + ROUND(aa, bb, cc, dd, F2, K2, in[7], 7); + ROUND(dd, aa, bb, cc, F2, K2, in[4], 6); + ROUND(cc, dd, aa, bb, F2, K2, in[13], 8); + ROUND(bb, cc, dd, aa, F2, K2, in[1], 13); + ROUND(aa, bb, cc, dd, F2, K2, in[10], 11); + ROUND(dd, aa, bb, cc, F2, K2, in[6], 9); + ROUND(cc, dd, aa, bb, F2, K2, in[15], 7); + ROUND(bb, cc, dd, aa, F2, K2, in[3], 15); + ROUND(aa, bb, cc, dd, F2, K2, in[12], 7); + ROUND(dd, aa, bb, cc, F2, K2, in[0], 12); + ROUND(cc, dd, aa, bb, F2, K2, in[9], 15); + ROUND(bb, cc, dd, aa, F2, K2, in[5], 9); + ROUND(aa, bb, cc, dd, F2, K2, in[2], 11); + ROUND(dd, aa, bb, cc, F2, K2, in[14], 7); + ROUND(cc, dd, aa, bb, F2, K2, in[11], 13); + ROUND(bb, cc, dd, aa, F2, K2, in[8], 12); + + /* round 2: right lane */ + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[6], 9); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[11], 13); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[3], 15); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[7], 7); + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[0], 12); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[13], 8); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[5], 9); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[10], 11); + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[14], 7); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[15], 7); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[8], 12); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[12], 7); + ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[4], 6); + ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[9], 15); + ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[1], 13); + ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[2], 11); + + /* Swap contents of "b" registers */ + tmp = bb; bb = bbb; bbb = tmp; + + /* round 3: left lane */ + ROUND(aa, bb, cc, dd, F3, K3, in[3], 11); + ROUND(dd, aa, bb, cc, F3, K3, in[10], 13); + ROUND(cc, dd, aa, bb, F3, K3, in[14], 6); + ROUND(bb, cc, dd, aa, F3, K3, in[4], 7); + ROUND(aa, bb, cc, dd, F3, K3, in[9], 14); + ROUND(dd, aa, bb, cc, F3, K3, in[15], 9); + ROUND(cc, dd, aa, bb, F3, K3, in[8], 13); + ROUND(bb, cc, dd, aa, F3, K3, in[1], 15); + ROUND(aa, bb, cc, dd, F3, K3, in[2], 14); + ROUND(dd, aa, bb, cc, F3, K3, in[7], 8); + ROUND(cc, dd, aa, bb, F3, K3, in[0], 13); + ROUND(bb, cc, dd, aa, F3, K3, in[6], 6); + ROUND(aa, bb, cc, dd, F3, K3, in[13], 5); + ROUND(dd, aa, bb, cc, F3, K3, in[11], 12); + ROUND(cc, dd, aa, bb, F3, K3, in[5], 7); + ROUND(bb, cc, dd, aa, F3, K3, in[12], 5); + + /* round 3: right lane */ + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[15], 9); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[5], 7); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[1], 15); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[3], 11); + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[7], 8); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[14], 6); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[6], 6); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[9], 14); + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[11], 12); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[8], 13); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[12], 5); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[2], 14); + ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[10], 13); + ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[0], 13); + ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[4], 7); + ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[13], 5); + + /* Swap contents of "c" registers */ + tmp = cc; cc = ccc; ccc = tmp; + + /* round 4: left lane */ + ROUND(aa, bb, cc, dd, F4, K4, in[1], 11); + ROUND(dd, aa, bb, cc, F4, K4, in[9], 12); + ROUND(cc, dd, aa, bb, F4, K4, in[11], 14); + ROUND(bb, cc, dd, aa, F4, K4, in[10], 15); + ROUND(aa, bb, cc, dd, F4, K4, in[0], 14); + ROUND(dd, aa, bb, cc, F4, K4, in[8], 15); + ROUND(cc, dd, aa, bb, F4, K4, in[12], 9); + ROUND(bb, cc, dd, aa, F4, K4, in[4], 8); + ROUND(aa, bb, cc, dd, F4, K4, in[13], 9); + ROUND(dd, aa, bb, cc, F4, K4, in[3], 14); + ROUND(cc, dd, aa, bb, F4, K4, in[7], 5); + ROUND(bb, cc, dd, aa, F4, K4, in[15], 6); + ROUND(aa, bb, cc, dd, F4, K4, in[14], 8); + ROUND(dd, aa, bb, cc, F4, K4, in[5], 6); + ROUND(cc, dd, aa, bb, F4, K4, in[6], 5); + ROUND(bb, cc, dd, aa, F4, K4, in[2], 12); + + /* round 4: right lane */ + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[8], 15); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[6], 5); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[4], 8); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[1], 11); + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[3], 14); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[11], 14); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[15], 6); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[0], 14); + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[5], 6); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[12], 9); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[2], 12); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[13], 9); + ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[9], 12); + ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[7], 5); + ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[10], 15); + ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[14], 8); + + /* Swap contents of "d" registers */ + tmp = dd; dd = ddd; ddd = tmp; + + /* combine results */ + state[0] += aa; + state[1] += bb; + state[2] += cc; + state[3] += dd; + state[4] += aaa; + state[5] += bbb; + state[6] += ccc; + state[7] += ddd; + + return; +} + +static inline void le32_to_cpu_array(u32 *buf, unsigned int words) +{ + while (words--) { + le32_to_cpus(buf); + buf++; + } +} + +static inline void cpu_to_le32_array(u32 *buf, unsigned int words) +{ + while (words--) { + cpu_to_le32s(buf); + buf++; + } +} + +static inline void rmd256_transform_helper(struct rmd256_ctx *ctx) +{ + le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); + rmd256_transform(ctx->state, ctx->buffer); +} + +static void rmd256_init(struct crypto_tfm *tfm) +{ + struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); + + rctx->byte_count = 0; + + rctx->state[0] = RMD_H0; + rctx->state[1] = RMD_H1; + rctx->state[2] = RMD_H2; + rctx->state[3] = RMD_H3; + rctx->state[4] = RMD_H5; + rctx->state[5] = RMD_H6; + rctx->state[6] = RMD_H7; + rctx->state[7] = RMD_H8; + + memset(rctx->buffer, 0, sizeof(rctx->buffer)); +} + +static void rmd256_update(struct crypto_tfm *tfm, const u8 *data, + unsigned int len) +{ + struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); + const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); + + rctx->byte_count += len; + + /* Enough space in buffer? If so copy and we're done */ + if (avail > len) { + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, len); + return; + } + + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, avail); + + rmd256_transform_helper(rctx); + data += avail; + len -= avail; + + while (len >= sizeof(rctx->buffer)) { + memcpy(rctx->buffer, data, sizeof(rctx->buffer)); + rmd256_transform_helper(rctx); + data += sizeof(rctx->buffer); + len -= sizeof(rctx->buffer); + } + + memcpy(rctx->buffer, data, len); +} + +/* Add padding and return the message digest. */ +static void rmd256_final(struct crypto_tfm *tfm, u8 *out) +{ + struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); + u32 index, padlen; + u64 bits; + static const u8 padding[64] = { 0x80, }; + bits = rctx->byte_count << 3; + + /* Pad out to 56 mod 64 */ + index = rctx->byte_count & 0x3f; + padlen = (index < 56) ? (56 - index) : ((64+56) - index); + rmd256_update(tfm, padding, padlen); + + /* Append length */ + rmd256_update(tfm, (const u8 *)&bits, sizeof(bits)); + + /* Store state in digest */ + memcpy(out, rctx->state, sizeof(rctx->state)); + + /* Wipe context */ + memset(rctx, 0, sizeof(*rctx)); +} + +static struct crypto_alg alg = { + .cra_name = "rmd256", + .cra_driver_name = "rmd256", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = RMD256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct rmd256_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = RMD256_DIGEST_SIZE, + .dia_init = rmd256_init, + .dia_update = rmd256_update, + .dia_final = rmd256_final } } +}; + +static int __init rmd256_mod_init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit rmd256_mod_fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(rmd256_mod_init); +module_exit(rmd256_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RIPEMD-256 Message Digest"); + +MODULE_ALIAS("rmd256"); diff --git a/crypto/rmd320.c b/crypto/rmd320.c new file mode 100644 index 0000000..b39c054 --- /dev/null +++ b/crypto/rmd320.c @@ -0,0 +1,412 @@ +/* + * Cryptographic API. + * + * RIPEMD-320 - RACE Integrity Primitives Evaluation Message Digest. + * + * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC + * + * Copyright (c) 2008 Adrian-Ken Rueegsegger + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "ripemd.h" + +struct rmd320_ctx { + u64 byte_count; + u32 state[10]; + u32 buffer[16]; +}; + +#define K1 RMD_K1 +#define K2 RMD_K2 +#define K3 RMD_K3 +#define K4 RMD_K4 +#define K5 RMD_K5 +#define KK1 RMD_K6 +#define KK2 RMD_K7 +#define KK3 RMD_K8 +#define KK4 RMD_K9 +#define KK5 RMD_K1 + +#define F1(x, y, z) (x ^ y ^ z) /* XOR */ +#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define F3(x, y, z) ((x | ~y) ^ z) +#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ +#define F5(x, y, z) (x ^ (y | ~z)) + +#define ROUND(a, b, c, d, e, f, k, x, s) { \ + (a) += f((b), (c), (d)) + (x) + (k); \ + (a) = rol32((a), (s)) + (e); \ + (c) = rol32((c), 10); \ +} + +static void rmd320_transform(u32 *state, u32 const *in) +{ + u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee, tmp; + + /* Initialize left lane */ + aa = state[0]; + bb = state[1]; + cc = state[2]; + dd = state[3]; + ee = state[4]; + + /* Initialize right lane */ + aaa = state[5]; + bbb = state[6]; + ccc = state[7]; + ddd = state[8]; + eee = state[9]; + + /* round 1: left lane */ + ROUND(aa, bb, cc, dd, ee, F1, K1, in[0], 11); + ROUND(ee, aa, bb, cc, dd, F1, K1, in[1], 14); + ROUND(dd, ee, aa, bb, cc, F1, K1, in[2], 15); + ROUND(cc, dd, ee, aa, bb, F1, K1, in[3], 12); + ROUND(bb, cc, dd, ee, aa, F1, K1, in[4], 5); + ROUND(aa, bb, cc, dd, ee, F1, K1, in[5], 8); + ROUND(ee, aa, bb, cc, dd, F1, K1, in[6], 7); + ROUND(dd, ee, aa, bb, cc, F1, K1, in[7], 9); + ROUND(cc, dd, ee, aa, bb, F1, K1, in[8], 11); + ROUND(bb, cc, dd, ee, aa, F1, K1, in[9], 13); + ROUND(aa, bb, cc, dd, ee, F1, K1, in[10], 14); + ROUND(ee, aa, bb, cc, dd, F1, K1, in[11], 15); + ROUND(dd, ee, aa, bb, cc, F1, K1, in[12], 6); + ROUND(cc, dd, ee, aa, bb, F1, K1, in[13], 7); + ROUND(bb, cc, dd, ee, aa, F1, K1, in[14], 9); + ROUND(aa, bb, cc, dd, ee, F1, K1, in[15], 8); + + /* round 1: right lane */ + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[5], 8); + ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[14], 9); + ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[7], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[0], 11); + ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[9], 13); + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[2], 15); + ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[11], 15); + ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[4], 5); + ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[13], 7); + ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[6], 7); + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[15], 8); + ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[8], 11); + ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[1], 14); + ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[10], 14); + ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[3], 12); + ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[12], 6); + + /* Swap contents of "a" registers */ + tmp = aa; aa = aaa; aaa = tmp; + + /* round 2: left lane" */ + ROUND(ee, aa, bb, cc, dd, F2, K2, in[7], 7); + ROUND(dd, ee, aa, bb, cc, F2, K2, in[4], 6); + ROUND(cc, dd, ee, aa, bb, F2, K2, in[13], 8); + ROUND(bb, cc, dd, ee, aa, F2, K2, in[1], 13); + ROUND(aa, bb, cc, dd, ee, F2, K2, in[10], 11); + ROUND(ee, aa, bb, cc, dd, F2, K2, in[6], 9); + ROUND(dd, ee, aa, bb, cc, F2, K2, in[15], 7); + ROUND(cc, dd, ee, aa, bb, F2, K2, in[3], 15); + ROUND(bb, cc, dd, ee, aa, F2, K2, in[12], 7); + ROUND(aa, bb, cc, dd, ee, F2, K2, in[0], 12); + ROUND(ee, aa, bb, cc, dd, F2, K2, in[9], 15); + ROUND(dd, ee, aa, bb, cc, F2, K2, in[5], 9); + ROUND(cc, dd, ee, aa, bb, F2, K2, in[2], 11); + ROUND(bb, cc, dd, ee, aa, F2, K2, in[14], 7); + ROUND(aa, bb, cc, dd, ee, F2, K2, in[11], 13); + ROUND(ee, aa, bb, cc, dd, F2, K2, in[8], 12); + + /* round 2: right lane */ + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[6], 9); + ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[11], 13); + ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[3], 15); + ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[7], 7); + ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[0], 12); + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[13], 8); + ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[5], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[10], 11); + ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[14], 7); + ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[15], 7); + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[8], 12); + ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[12], 7); + ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[4], 6); + ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[9], 15); + ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[1], 13); + ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[2], 11); + + /* Swap contents of "b" registers */ + tmp = bb; bb = bbb; bbb = tmp; + + /* round 3: left lane" */ + ROUND(dd, ee, aa, bb, cc, F3, K3, in[3], 11); + ROUND(cc, dd, ee, aa, bb, F3, K3, in[10], 13); + ROUND(bb, cc, dd, ee, aa, F3, K3, in[14], 6); + ROUND(aa, bb, cc, dd, ee, F3, K3, in[4], 7); + ROUND(ee, aa, bb, cc, dd, F3, K3, in[9], 14); + ROUND(dd, ee, aa, bb, cc, F3, K3, in[15], 9); + ROUND(cc, dd, ee, aa, bb, F3, K3, in[8], 13); + ROUND(bb, cc, dd, ee, aa, F3, K3, in[1], 15); + ROUND(aa, bb, cc, dd, ee, F3, K3, in[2], 14); + ROUND(ee, aa, bb, cc, dd, F3, K3, in[7], 8); + ROUND(dd, ee, aa, bb, cc, F3, K3, in[0], 13); + ROUND(cc, dd, ee, aa, bb, F3, K3, in[6], 6); + ROUND(bb, cc, dd, ee, aa, F3, K3, in[13], 5); + ROUND(aa, bb, cc, dd, ee, F3, K3, in[11], 12); + ROUND(ee, aa, bb, cc, dd, F3, K3, in[5], 7); + ROUND(dd, ee, aa, bb, cc, F3, K3, in[12], 5); + + /* round 3: right lane */ + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[15], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[5], 7); + ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[1], 15); + ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[3], 11); + ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[7], 8); + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[14], 6); + ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[6], 6); + ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[9], 14); + ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[11], 12); + ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[8], 13); + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[12], 5); + ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[2], 14); + ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[10], 13); + ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[0], 13); + ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[4], 7); + ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[13], 5); + + /* Swap contents of "c" registers */ + tmp = cc; cc = ccc; ccc = tmp; + + /* round 4: left lane" */ + ROUND(cc, dd, ee, aa, bb, F4, K4, in[1], 11); + ROUND(bb, cc, dd, ee, aa, F4, K4, in[9], 12); + ROUND(aa, bb, cc, dd, ee, F4, K4, in[11], 14); + ROUND(ee, aa, bb, cc, dd, F4, K4, in[10], 15); + ROUND(dd, ee, aa, bb, cc, F4, K4, in[0], 14); + ROUND(cc, dd, ee, aa, bb, F4, K4, in[8], 15); + ROUND(bb, cc, dd, ee, aa, F4, K4, in[12], 9); + ROUND(aa, bb, cc, dd, ee, F4, K4, in[4], 8); + ROUND(ee, aa, bb, cc, dd, F4, K4, in[13], 9); + ROUND(dd, ee, aa, bb, cc, F4, K4, in[3], 14); + ROUND(cc, dd, ee, aa, bb, F4, K4, in[7], 5); + ROUND(bb, cc, dd, ee, aa, F4, K4, in[15], 6); + ROUND(aa, bb, cc, dd, ee, F4, K4, in[14], 8); + ROUND(ee, aa, bb, cc, dd, F4, K4, in[5], 6); + ROUND(dd, ee, aa, bb, cc, F4, K4, in[6], 5); + ROUND(cc, dd, ee, aa, bb, F4, K4, in[2], 12); + + /* round 4: right lane */ + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[8], 15); + ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[6], 5); + ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[4], 8); + ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[1], 11); + ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[3], 14); + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[11], 14); + ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[15], 6); + ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[0], 14); + ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[5], 6); + ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[12], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[2], 12); + ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[13], 9); + ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[9], 12); + ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[7], 5); + ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[10], 15); + ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[14], 8); + + /* Swap contents of "d" registers */ + tmp = dd; dd = ddd; ddd = tmp; + + /* round 5: left lane" */ + ROUND(bb, cc, dd, ee, aa, F5, K5, in[4], 9); + ROUND(aa, bb, cc, dd, ee, F5, K5, in[0], 15); + ROUND(ee, aa, bb, cc, dd, F5, K5, in[5], 5); + ROUND(dd, ee, aa, bb, cc, F5, K5, in[9], 11); + ROUND(cc, dd, ee, aa, bb, F5, K5, in[7], 6); + ROUND(bb, cc, dd, ee, aa, F5, K5, in[12], 8); + ROUND(aa, bb, cc, dd, ee, F5, K5, in[2], 13); + ROUND(ee, aa, bb, cc, dd, F5, K5, in[10], 12); + ROUND(dd, ee, aa, bb, cc, F5, K5, in[14], 5); + ROUND(cc, dd, ee, aa, bb, F5, K5, in[1], 12); + ROUND(bb, cc, dd, ee, aa, F5, K5, in[3], 13); + ROUND(aa, bb, cc, dd, ee, F5, K5, in[8], 14); + ROUND(ee, aa, bb, cc, dd, F5, K5, in[11], 11); + ROUND(dd, ee, aa, bb, cc, F5, K5, in[6], 8); + ROUND(cc, dd, ee, aa, bb, F5, K5, in[15], 5); + ROUND(bb, cc, dd, ee, aa, F5, K5, in[13], 6); + + /* round 5: right lane */ + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[12], 8); + ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[15], 5); + ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[10], 12); + ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[4], 9); + ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[1], 12); + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[5], 5); + ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[8], 14); + ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[7], 6); + ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[6], 8); + ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[2], 13); + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[13], 6); + ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[14], 5); + ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[0], 15); + ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[3], 13); + ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[9], 11); + ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[11], 11); + + /* Swap contents of "e" registers */ + tmp = ee; ee = eee; eee = tmp; + + /* combine results */ + state[0] += aa; + state[1] += bb; + state[2] += cc; + state[3] += dd; + state[4] += ee; + state[5] += aaa; + state[6] += bbb; + state[7] += ccc; + state[8] += ddd; + state[9] += eee; + + return; +} + +static inline void le32_to_cpu_array(u32 *buf, unsigned int words) +{ + while (words--) { + le32_to_cpus(buf); + buf++; + } +} + +static inline void cpu_to_le32_array(u32 *buf, unsigned int words) +{ + while (words--) { + cpu_to_le32s(buf); + buf++; + } +} + +static inline void rmd320_transform_helper(struct rmd320_ctx *ctx) +{ + le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); + rmd320_transform(ctx->state, ctx->buffer); +} + +static void rmd320_init(struct crypto_tfm *tfm) +{ + struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); + + rctx->byte_count = 0; + + rctx->state[0] = RMD_H0; + rctx->state[1] = RMD_H1; + rctx->state[2] = RMD_H2; + rctx->state[3] = RMD_H3; + rctx->state[4] = RMD_H4; + rctx->state[5] = RMD_H5; + rctx->state[6] = RMD_H6; + rctx->state[7] = RMD_H7; + rctx->state[8] = RMD_H8; + rctx->state[9] = RMD_H9; + + memset(rctx->buffer, 0, sizeof(rctx->buffer)); +} + +static void rmd320_update(struct crypto_tfm *tfm, const u8 *data, + unsigned int len) +{ + struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); + const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f); + + rctx->byte_count += len; + + /* Enough space in buffer? If so copy and we're done */ + if (avail > len) { + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, len); + return; + } + + memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), + data, avail); + + rmd320_transform_helper(rctx); + data += avail; + len -= avail; + + while (len >= sizeof(rctx->buffer)) { + memcpy(rctx->buffer, data, sizeof(rctx->buffer)); + rmd320_transform_helper(rctx); + data += sizeof(rctx->buffer); + len -= sizeof(rctx->buffer); + } + + memcpy(rctx->buffer, data, len); +} + +/* Add padding and return the message digest. */ +static void rmd320_final(struct crypto_tfm *tfm, u8 *out) +{ + struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); + u32 index, padlen; + u64 bits; + static const u8 padding[64] = { 0x80, }; + bits = rctx->byte_count << 3; + + /* Pad out to 56 mod 64 */ + index = rctx->byte_count & 0x3f; + padlen = (index < 56) ? (56 - index) : ((64+56) - index); + rmd320_update(tfm, padding, padlen); + + /* Append length */ + rmd320_update(tfm, (const u8 *)&bits, sizeof(bits)); + + /* Store state in digest */ + memcpy(out, rctx->state, sizeof(rctx->state)); + + /* Wipe context */ + memset(rctx, 0, sizeof(*rctx)); +} + +static struct crypto_alg alg = { + .cra_name = "rmd320", + .cra_driver_name = "rmd320", + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, + .cra_blocksize = RMD320_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct rmd320_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_u = { .digest = { + .dia_digestsize = RMD320_DIGEST_SIZE, + .dia_init = rmd320_init, + .dia_update = rmd320_update, + .dia_final = rmd320_final } } +}; + +static int __init rmd320_mod_init(void) +{ + return crypto_register_alg(&alg); +} + +static void __exit rmd320_mod_fini(void) +{ + crypto_unregister_alg(&alg); +} + +module_init(rmd320_mod_init); +module_exit(rmd320_mod_fini); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RIPEMD-320 Message Digest"); + +MODULE_ALIAS("rmd320"); -- cgit v0.10.2 From 2998db37b5c62890ff1a0d48abd76ada13ebc554 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:29:35 +0800 Subject: [CRYPTO] tcrypt: Add test vectors for RIPEMD-256 and RIPEMD-320 This patch adds test vectors for RIPEMD-256 and RIPEMD-320 hash algorithms. The test vectors are taken from Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 69eb29e..e0ea4d5 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -76,7 +76,8 @@ static char *check[] = { "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", "seed", "salsa20", "rmd128", "rmd160", "lzo", "cts", NULL + "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", + "lzo", "cts", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -1559,7 +1560,7 @@ static void do_test(void) case 29: test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS); break; - + case 30: test_cipher("ecb(xeta)", ENCRYPT, xeta_enc_tv_template, XETA_ENC_TEST_VECTORS); @@ -1632,6 +1633,14 @@ static void do_test(void) test_hash("rmd160", rmd160_tv_template, RMD160_TEST_VECTORS); break; + case 41: + test_hash("rmd256", rmd256_tv_template, RMD256_TEST_VECTORS); + break; + + case 42: + test_hash("rmd320", rmd320_tv_template, RMD320_TEST_VECTORS); + break; + case 100: test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); @@ -1823,6 +1832,14 @@ static void do_test(void) test_hash_speed("rmd160", sec, generic_hash_speed_template); if (mode > 300 && mode < 400) break; + case 316: + test_hash_speed("rmd256", sec, generic_hash_speed_template); + if (mode > 300 && mode < 400) break; + + case 317: + test_hash_speed("rmd320", sec, generic_hash_speed_template); + if (mode > 300 && mode < 400) break; + case 399: break; diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index af91f0c..20bd5fe 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -294,6 +294,142 @@ static struct hash_testvec rmd160_tv_template[] = { }; /* + * RIPEMD-256 test vectors + */ +#define RMD256_TEST_VECTORS 8 + +static struct hash_testvec rmd256_tv_template[] = { + { + .digest = "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18" + "\x77\xfc\x52\xd6\x4d\x30\xe3\x7a" + "\x2d\x97\x74\xfb\x1e\x5d\x02\x63" + "\x80\xae\x01\x68\xe3\xc5\x52\x2d", + }, { + .plaintext = "a", + .psize = 1, + .digest = "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9" + "\x0a\x91\xba\xb7\x0a\x1e\xba\x0c" + "\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf" + "\xcd\x88\x3a\x91\x34\x69\x29\x25", + }, { + .plaintext = "abc", + .psize = 3, + .digest = "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb" + "\xce\xf5\xca\x2d\x03\xe6\xdb\xa1" + "\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e" + "\x1e\x42\xd2\xe9\x75\x45\x9b\x65", + }, { + .plaintext = "message digest", + .psize = 14, + .digest = "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a" + "\x51\x4d\x5c\x91\x4c\x39\x2c\x90" + "\x18\xc7\xc4\x6b\xc1\x44\x65\x55" + "\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e", + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyz", + .psize = 26, + .digest = "\x64\x9d\x30\x34\x75\x1e\xa2\x16" + "\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc" + "\x78\x96\x11\x8a\x51\x97\x96\x87" + "\x82\xdd\x1f\xd9\x7d\x8d\x51\x33", + }, { + .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" + "fghijklmnopqrstuvwxyz0123456789", + .psize = 62, + .digest = "\x57\x40\xa4\x08\xac\x16\xb7\x20" + "\xb8\x44\x24\xae\x93\x1c\xbb\x1f" + "\xe3\x63\xd1\xd0\xbf\x40\x17\xf1" + "\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8", + }, { + .plaintext = "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + .psize = 80, + .digest = "\x06\xfd\xcc\x7a\x40\x95\x48\xaa" + "\xf9\x13\x68\xc0\x6a\x62\x75\xb5" + "\x53\xe3\xf0\x99\xbf\x0e\xa4\xed" + "\xfd\x67\x78\xdf\x89\xa8\x90\xdd", + }, { + .plaintext = "abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = "\x38\x43\x04\x55\x83\xaa\xc6\xc8" + "\xc8\xd9\x12\x85\x73\xe7\xa9\x80" + "\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e" + "\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f", + .np = 2, + .tap = { 28, 28 }, + } +}; + +/* + * RIPEMD-320 test vectors + */ +#define RMD320_TEST_VECTORS 8 + +static struct hash_testvec rmd320_tv_template[] = { + { + .digest = "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1" + "\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25" + "\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e" + "\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8", + }, { + .plaintext = "a", + .psize = 1, + .digest = "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5" + "\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57" + "\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54" + "\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d", + }, { + .plaintext = "abc", + .psize = 3, + .digest = "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d" + "\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08" + "\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74" + "\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d", + }, { + .plaintext = "message digest", + .psize = 14, + .digest = "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68" + "\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa" + "\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d" + "\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97", + }, { + .plaintext = "abcdefghijklmnopqrstuvwxyz", + .psize = 26, + .digest = "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93" + "\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4" + "\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed" + "\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09", + }, { + .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" + "fghijklmnopqrstuvwxyz0123456789", + .psize = 62, + .digest = "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2" + "\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c" + "\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9" + "\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4", + }, { + .plaintext = "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", + .psize = 80, + .digest = "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6" + "\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41" + "\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f" + "\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42", + }, { + .plaintext = "abcdbcdecdefdefgefghfghighij" + "hijkijkljklmklmnlmnomnopnopq", + .psize = 56, + .digest = "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4" + "\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59" + "\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b" + "\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac", + .np = 2, + .tap = { 28, 28 }, + } +}; + +/* * SHA1 test vectors from from FIPS PUB 180-1 */ #define SHA1_TEST_VECTORS 2 -- cgit v0.10.2 From 534fe2c1c3ffbbc3db66dba0783c82d3b345fd33 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Fri, 9 May 2008 21:30:27 +0800 Subject: [CRYPTO] ripemd: Add Kconfig entries for extended RIPEMD hash algorithms This patch adds Kconfig entries for RIPEMD-256 and RIPEMD-320. Signed-off-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/Kconfig b/crypto/Kconfig index cfc521a..5963a95 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -264,6 +264,31 @@ config CRYPTO_RMD160 to be used as a secure replacement for the 128-bit hash functions MD4, MD5 and it's predecessor RIPEMD (not to be confused with RIPEMD-128). + It's speed is comparable to SHA1 and there are no known attacks against + RIPEMD-160. + + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. + See + +config CRYPTO_RMD256 + tristate "RIPEMD-256 digest algorithm" + select CRYPTO_ALGAPI + help + RIPEMD-256 is an optional extension of RIPEMD-128 with a 256 bit hash. + It is intended for applications that require longer hash-results, without + needing a larger security level (than RIPEMD-128). + + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. + See + +config CRYPTO_RMD320 + tristate "RIPEMD-320 digest algorithm" + select CRYPTO_ALGAPI + help + RIPEMD-320 is an optional extension of RIPEMD-160 with a 320 bit hash. + It is intended for applications that require longer hash-results, without + needing a larger security level (than RIPEMD-160). + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. See -- cgit v0.10.2 From 004a403c2e954734090a69aedc7f4f822bdcc142 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Wed, 14 May 2008 20:41:47 +0800 Subject: [CRYPTO] hash: Add asynchronous hash support This patch adds asynchronous hash and digest support. Signed-off-by: Loc Ho Signed-off-by: Herbert Xu diff --git a/crypto/Makefile b/crypto/Makefile index 807656b..d4f3ed8 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CRYPTO_BLKCIPHER) += crypto_blkcipher.o obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o crypto_hash-objs := hash.o +crypto_hash-objs += ahash.o obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o diff --git a/crypto/ahash.c b/crypto/ahash.c new file mode 100644 index 0000000..a83e035 --- /dev/null +++ b/crypto/ahash.c @@ -0,0 +1,106 @@ +/* + * Asynchronous Cryptographic Hash operations. + * + * This is the asynchronous version of hash.c with notification of + * completion via a callback. + * + * Copyright (c) 2008 Loc Ho + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen) +{ + struct ahash_alg *ahash = crypto_ahash_alg(tfm); + unsigned long alignmask = crypto_ahash_alignmask(tfm); + int ret; + u8 *buffer, *alignbuffer; + unsigned long absize; + + absize = keylen + alignmask; + buffer = kmalloc(absize, GFP_ATOMIC); + if (!buffer) + return -ENOMEM; + + alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + memcpy(alignbuffer, key, keylen); + ret = ahash->setkey(tfm, alignbuffer, keylen); + memset(alignbuffer, 0, keylen); + kfree(buffer); + return ret; +} + +static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen) +{ + struct ahash_alg *ahash = crypto_ahash_alg(tfm); + unsigned long alignmask = crypto_ahash_alignmask(tfm); + + if ((unsigned long)key & alignmask) + return ahash_setkey_unaligned(tfm, key, keylen); + + return ahash->setkey(tfm, key, keylen); +} + +static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type, + u32 mask) +{ + return alg->cra_ctxsize; +} + +static int crypto_init_ahash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +{ + struct ahash_alg *alg = &tfm->__crt_alg->cra_ahash; + struct ahash_tfm *crt = &tfm->crt_ahash; + + if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) + return -EINVAL; + + crt->init = alg->init; + crt->update = alg->update; + crt->final = alg->final; + crt->digest = alg->digest; + crt->setkey = ahash_setkey; + crt->base = __crypto_ahash_cast(tfm); + crt->digestsize = alg->digestsize; + + return 0; +} + +static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) + __attribute__ ((unused)); +static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) +{ + seq_printf(m, "type : ahash\n"); + 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_hash.digestsize); +} + +const struct crypto_type crypto_ahash_type = { + .ctxsize = crypto_ahash_ctxsize, + .init = crypto_init_ahash_ops, +#ifdef CONFIG_PROC_FS + .show = crypto_ahash_show, +#endif +}; +EXPORT_SYMBOL_GPL(crypto_ahash_type); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Asynchronous cryptographic hash type"); diff --git a/crypto/api.c b/crypto/api.c index 0a0f41e..d06e332 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -235,8 +235,12 @@ static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) return crypto_init_cipher_ops(tfm); case CRYPTO_ALG_TYPE_DIGEST: - return crypto_init_digest_ops(tfm); - + if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != + CRYPTO_ALG_TYPE_HASH_MASK) + return crypto_init_digest_ops_async(tfm); + else + return crypto_init_digest_ops(tfm); + case CRYPTO_ALG_TYPE_COMPRESS: return crypto_init_compress_ops(tfm); diff --git a/crypto/digest.c b/crypto/digest.c index b526cc3..025c9ae 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -157,3 +157,84 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm) void crypto_exit_digest_ops(struct crypto_tfm *tfm) { } + +static int digest_async_nosetkey(struct crypto_ahash *tfm_async, const u8 *key, + unsigned int keylen) +{ + crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK); + return -ENOSYS; +} + +static int digest_async_setkey(struct crypto_ahash *tfm_async, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async); + struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; + + crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK); + return dalg->dia_setkey(tfm, key, keylen); +} + +static int digest_async_init(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; + + dalg->dia_init(tfm); + return 0; +} + +static int digest_async_update(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + update(&desc, req->src, req->nbytes); + return 0; +} + +static int digest_async_final(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + final(&desc, req->result); + return 0; +} + +static int digest_async_digest(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + return digest(&desc, req->src, req->nbytes, req->result); +} + +int crypto_init_digest_ops_async(struct crypto_tfm *tfm) +{ + struct ahash_tfm *crt = &tfm->crt_ahash; + struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; + + if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm)) + return -EINVAL; + + crt->init = digest_async_init; + crt->update = digest_async_update; + crt->final = digest_async_final; + crt->digest = digest_async_digest; + crt->setkey = dalg->dia_setkey ? digest_async_setkey : + digest_async_nosetkey; + crt->digestsize = dalg->dia_digestsize; + crt->base = __crypto_ahash_cast(tfm); + + return 0; +} diff --git a/crypto/hash.c b/crypto/hash.c index 7dcff67..f9400a0 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -59,24 +59,108 @@ static int hash_setkey(struct crypto_hash *crt, const u8 *key, return alg->setkey(crt, key, keylen); } -static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async); + struct crypto_hash *tfm_hash = __crypto_hash_cast(tfm); + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + + return alg->setkey(tfm_hash, key, keylen); +} + +static int hash_async_init(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + return alg->init(&desc); +} + +static int hash_async_update(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + return alg->update(&desc, req->src, req->nbytes); +} + +static int hash_async_final(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + return alg->final(&desc, req->result); +} + +static int hash_async_digest(struct ahash_request *req) +{ + struct crypto_tfm *tfm = req->base.tfm; + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + struct hash_desc desc = { + .tfm = __crypto_hash_cast(tfm), + .flags = req->base.flags, + }; + + return alg->digest(&desc, req->src, req->nbytes, req->result); +} + +static int crypto_init_hash_ops_async(struct crypto_tfm *tfm) +{ + struct ahash_tfm *crt = &tfm->crt_ahash; + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + + crt->init = hash_async_init; + crt->update = hash_async_update; + crt->final = hash_async_final; + crt->digest = hash_async_digest; + crt->setkey = hash_async_setkey; + crt->digestsize = alg->digestsize; + crt->base = __crypto_ahash_cast(tfm); + + return 0; +} + +static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm) { struct hash_tfm *crt = &tfm->crt_hash; struct hash_alg *alg = &tfm->__crt_alg->cra_hash; - if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) - return -EINVAL; - - crt->init = alg->init; - crt->update = alg->update; - crt->final = alg->final; - crt->digest = alg->digest; - crt->setkey = hash_setkey; + crt->init = alg->init; + crt->update = alg->update; + crt->final = alg->final; + crt->digest = alg->digest; + crt->setkey = hash_setkey; crt->digestsize = alg->digestsize; return 0; } +static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +{ + struct hash_alg *alg = &tfm->__crt_alg->cra_hash; + + if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) + return -EINVAL; + + if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK) + return crypto_init_hash_ops_async(tfm); + else + return crypto_init_hash_ops_sync(tfm); +} + static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) __attribute__ ((unused)); static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) diff --git a/crypto/internal.h b/crypto/internal.h index 32f4c21..683fcb2 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -86,6 +86,7 @@ struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask); struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); int crypto_init_digest_ops(struct crypto_tfm *tfm); +int crypto_init_digest_ops_async(struct crypto_tfm *tfm); int crypto_init_cipher_ops(struct crypto_tfm *tfm); int crypto_init_compress_ops(struct crypto_tfm *tfm); diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 60d06e7..fef272a 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -98,6 +98,7 @@ extern const struct crypto_type crypto_ablkcipher_type; extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; extern const struct crypto_type crypto_hash_type; +extern const struct crypto_type crypto_ahash_type; void crypto_mod_put(struct crypto_alg *alg); @@ -314,5 +315,40 @@ static inline int crypto_requires_sync(u32 type, u32 mask) return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC; } +static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + +static inline struct ahash_alg *crypto_ahash_alg( + struct crypto_ahash *tfm) +{ + return &crypto_ahash_tfm(tfm)->__crt_alg->cra_ahash; +} + +static inline int ahash_enqueue_request(struct crypto_queue *queue, + struct ahash_request *request) +{ + return crypto_enqueue_request(queue, &request->base); +} + +static inline struct ahash_request *ahash_dequeue_request( + struct crypto_queue *queue) +{ + return ahash_request_cast(crypto_dequeue_request(queue)); +} + +static inline void *ahash_request_ctx(struct ahash_request *req) +{ + return req->__ctx; +} + +static inline int ahash_tfm_in_queue(struct crypto_queue *queue, + struct crypto_ahash *tfm) +{ + return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm)); +} + + #endif /* _CRYPTO_ALGAPI_H */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 425824b..b6efe56 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -30,15 +30,17 @@ */ #define CRYPTO_ALG_TYPE_MASK 0x0000000f #define CRYPTO_ALG_TYPE_CIPHER 0x00000001 -#define CRYPTO_ALG_TYPE_DIGEST 0x00000002 -#define CRYPTO_ALG_TYPE_HASH 0x00000003 +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000002 +#define CRYPTO_ALG_TYPE_AEAD 0x00000003 #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 #define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005 #define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006 -#define CRYPTO_ALG_TYPE_COMPRESS 0x00000008 -#define CRYPTO_ALG_TYPE_AEAD 0x00000009 +#define CRYPTO_ALG_TYPE_DIGEST 0x00000008 +#define CRYPTO_ALG_TYPE_HASH 0x00000009 +#define CRYPTO_ALG_TYPE_AHASH 0x0000000a #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e +#define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000c #define CRYPTO_ALG_TYPE_BLKCIPHER_MASK 0x0000000c #define CRYPTO_ALG_LARVAL 0x00000010 @@ -102,6 +104,7 @@ struct crypto_async_request; struct crypto_aead; struct crypto_blkcipher; struct crypto_hash; +struct crypto_ahash; struct crypto_tfm; struct crypto_type; struct aead_givcrypt_request; @@ -131,6 +134,18 @@ struct ablkcipher_request { void *__ctx[] CRYPTO_MINALIGN_ATTR; }; +struct ahash_request { + struct crypto_async_request base; + + void *info; + + unsigned int nbytes; + struct scatterlist *src; + u8 *result; + + void *__ctx[] CRYPTO_MINALIGN_ATTR; +}; + /** * struct aead_request - AEAD request * @base: Common attributes for async crypto requests @@ -195,6 +210,17 @@ struct ablkcipher_alg { unsigned int ivsize; }; +struct ahash_alg { + int (*init)(struct ahash_request *req); + int (*update)(struct ahash_request *req); + int (*final)(struct ahash_request *req); + int (*digest)(struct ahash_request *req); + int (*setkey)(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen); + + unsigned int digestsize; +}; + struct aead_alg { int (*setkey)(struct crypto_aead *tfm, const u8 *key, unsigned int keylen); @@ -272,6 +298,7 @@ struct compress_alg { #define cra_cipher cra_u.cipher #define cra_digest cra_u.digest #define cra_hash cra_u.hash +#define cra_ahash cra_u.ahash #define cra_compress cra_u.compress struct crypto_alg { @@ -298,6 +325,7 @@ struct crypto_alg { struct cipher_alg cipher; struct digest_alg digest; struct hash_alg hash; + struct ahash_alg ahash; struct compress_alg compress; } cra_u; @@ -383,6 +411,19 @@ struct hash_tfm { unsigned int digestsize; }; +struct ahash_tfm { + int (*init)(struct ahash_request *req); + int (*update)(struct ahash_request *req); + int (*final)(struct ahash_request *req); + int (*digest)(struct ahash_request *req); + int (*setkey)(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen); + + unsigned int digestsize; + struct crypto_ahash *base; + unsigned int reqsize; +}; + struct compress_tfm { int (*cot_compress)(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, @@ -397,6 +438,7 @@ struct compress_tfm { #define crt_blkcipher crt_u.blkcipher #define crt_cipher crt_u.cipher #define crt_hash crt_u.hash +#define crt_ahash crt_u.ahash #define crt_compress crt_u.compress struct crypto_tfm { @@ -409,6 +451,7 @@ struct crypto_tfm { struct blkcipher_tfm blkcipher; struct cipher_tfm cipher; struct hash_tfm hash; + struct ahash_tfm ahash; struct compress_tfm compress; } crt_u; @@ -441,6 +484,10 @@ struct crypto_hash { struct crypto_tfm base; }; +struct crypto_ahash { + struct crypto_tfm base; +}; + enum { CRYPTOA_UNSPEC, CRYPTOA_ALG, @@ -1264,5 +1311,137 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm, src, slen, dst, dlen); } +static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) +{ + return (struct crypto_ahash *)tfm; +} + +static inline struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, + u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + mask &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_AHASH; + mask |= CRYPTO_ALG_TYPE_AHASH_MASK; + + return __crypto_ahash_cast(crypto_alloc_base(alg_name, type, mask)); +} + +static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) +{ + return &tfm->base; +} + +static inline void crypto_free_ahash(struct crypto_ahash *tfm) +{ + crypto_free_tfm(crypto_ahash_tfm(tfm)); +} + +static inline unsigned int crypto_ahash_alignmask( + struct crypto_ahash *tfm) +{ + return crypto_tfm_alg_alignmask(crypto_ahash_tfm(tfm)); +} + +static inline struct ahash_tfm *crypto_ahash_crt(struct crypto_ahash *tfm) +{ + return &crypto_ahash_tfm(tfm)->crt_ahash; +} + +static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm) +{ + return crypto_ahash_crt(tfm)->digestsize; +} + +static inline u32 crypto_ahash_get_flags(struct crypto_ahash *tfm) +{ + return crypto_tfm_get_flags(crypto_ahash_tfm(tfm)); +} + +static inline void crypto_ahash_set_flags(struct crypto_ahash *tfm, u32 flags) +{ + crypto_tfm_set_flags(crypto_ahash_tfm(tfm), flags); +} + +static inline void crypto_ahash_clear_flags(struct crypto_ahash *tfm, u32 flags) +{ + crypto_tfm_clear_flags(crypto_ahash_tfm(tfm), flags); +} + +static inline struct crypto_ahash *crypto_ahash_reqtfm( + struct ahash_request *req) +{ + return __crypto_ahash_cast(req->base.tfm); +} + +static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) +{ + return crypto_ahash_crt(tfm)->reqsize; +} + +static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, + const u8 *key, unsigned int keylen) +{ + struct ahash_tfm *crt = crypto_ahash_crt(tfm); + + return crt->setkey(crt->base, key, keylen); +} + +static inline int crypto_ahash_digest(struct ahash_request *req) +{ + struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); + return crt->digest(req); +} + +static inline void ahash_request_set_tfm(struct ahash_request *req, + struct crypto_ahash *tfm) +{ + req->base.tfm = crypto_ahash_tfm(crypto_ahash_crt(tfm)->base); +} + +static inline struct ahash_request *ahash_request_alloc( + struct crypto_ahash *tfm, gfp_t gfp) +{ + struct ahash_request *req; + + req = kmalloc(sizeof(struct ahash_request) + + crypto_ahash_reqsize(tfm), gfp); + + if (likely(req)) + ahash_request_set_tfm(req, tfm); + + return req; +} + +static inline void ahash_request_free(struct ahash_request *req) +{ + kfree(req); +} + +static inline struct ahash_request *ahash_request_cast( + struct crypto_async_request *req) +{ + return container_of(req, struct ahash_request, base); +} + +static inline void ahash_request_set_callback(struct ahash_request *req, + u32 flags, + crypto_completion_t complete, + void *data) +{ + req->base.complete = complete; + req->base.data = data; + req->base.flags = flags; +} + +static inline void ahash_request_set_crypt(struct ahash_request *req, + struct scatterlist *src, u8 *result, + unsigned int nbytes) +{ + req->src = src; + req->nbytes = nbytes; + req->result = result; +} + #endif /* _LINUX_CRYPTO_H */ -- cgit v0.10.2 From b8a28251c2066a2ac6481fc49ced5eb7f078e49b Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Wed, 14 May 2008 21:23:00 +0800 Subject: [CRYPTO] cryptd: Add asynchronous hash support This patch adds asynchronous hash support to crypto daemon. Signed-off-by: Loc Ho Signed-off-by: Herbert Xu diff --git a/crypto/Kconfig b/crypto/Kconfig index 5963a95..795e31c 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -65,6 +65,7 @@ config CRYPTO_NULL config CRYPTO_CRYPTD tristate "Software async crypto daemon" select CRYPTO_BLKCIPHER + select CRYPTO_HASH select CRYPTO_MANAGER help This is a generic software asynchronous crypto daemon that diff --git a/crypto/cryptd.c b/crypto/cryptd.c index f38e147..d3ecd7e 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -45,6 +45,13 @@ struct cryptd_blkcipher_request_ctx { crypto_completion_t complete; }; +struct cryptd_hash_ctx { + struct crypto_hash *child; +}; + +struct cryptd_hash_request_ctx { + crypto_completion_t complete; +}; static inline struct cryptd_state *cryptd_get_state(struct crypto_tfm *tfm) { @@ -260,6 +267,240 @@ out_put_alg: return inst; } +static int cryptd_hash_init_tfm(struct crypto_tfm *tfm) +{ + struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); + struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst); + struct crypto_spawn *spawn = &ictx->spawn; + struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_hash *cipher; + + cipher = crypto_spawn_hash(spawn); + if (IS_ERR(cipher)) + return PTR_ERR(cipher); + + ctx->child = cipher; + tfm->crt_ahash.reqsize = + sizeof(struct cryptd_hash_request_ctx); + return 0; +} + +static void cryptd_hash_exit_tfm(struct crypto_tfm *tfm) +{ + struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); + struct cryptd_state *state = cryptd_get_state(tfm); + int active; + + mutex_lock(&state->mutex); + active = ahash_tfm_in_queue(&state->queue, + __crypto_ahash_cast(tfm)); + mutex_unlock(&state->mutex); + + BUG_ON(active); + + crypto_free_hash(ctx->child); +} + +static int cryptd_hash_setkey(struct crypto_ahash *parent, + const u8 *key, unsigned int keylen) +{ + struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(parent); + struct crypto_hash *child = ctx->child; + int err; + + crypto_hash_clear_flags(child, CRYPTO_TFM_REQ_MASK); + crypto_hash_set_flags(child, crypto_ahash_get_flags(parent) & + CRYPTO_TFM_REQ_MASK); + err = crypto_hash_setkey(child, key, keylen); + crypto_ahash_set_flags(parent, crypto_hash_get_flags(child) & + CRYPTO_TFM_RES_MASK); + return err; +} + +static int cryptd_hash_enqueue(struct ahash_request *req, + crypto_completion_t complete) +{ + struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cryptd_state *state = + cryptd_get_state(crypto_ahash_tfm(tfm)); + int err; + + rctx->complete = req->base.complete; + req->base.complete = complete; + + spin_lock_bh(&state->lock); + err = ahash_enqueue_request(&state->queue, req); + spin_unlock_bh(&state->lock); + + wake_up_process(state->task); + return err; +} + +static void cryptd_hash_init(struct crypto_async_request *req_async, int err) +{ + struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); + struct crypto_hash *child = ctx->child; + struct ahash_request *req = ahash_request_cast(req_async); + struct cryptd_hash_request_ctx *rctx; + struct hash_desc desc; + + rctx = ahash_request_ctx(req); + + if (unlikely(err == -EINPROGRESS)) + goto out; + + desc.tfm = child; + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + err = crypto_hash_crt(child)->init(&desc); + + req->base.complete = rctx->complete; + +out: + local_bh_disable(); + rctx->complete(&req->base, err); + local_bh_enable(); +} + +static int cryptd_hash_init_enqueue(struct ahash_request *req) +{ + return cryptd_hash_enqueue(req, cryptd_hash_init); +} + +static void cryptd_hash_update(struct crypto_async_request *req_async, int err) +{ + struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); + struct crypto_hash *child = ctx->child; + struct ahash_request *req = ahash_request_cast(req_async); + struct cryptd_hash_request_ctx *rctx; + struct hash_desc desc; + + rctx = ahash_request_ctx(req); + + if (unlikely(err == -EINPROGRESS)) + goto out; + + desc.tfm = child; + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + err = crypto_hash_crt(child)->update(&desc, + req->src, + req->nbytes); + + req->base.complete = rctx->complete; + +out: + local_bh_disable(); + rctx->complete(&req->base, err); + local_bh_enable(); +} + +static int cryptd_hash_update_enqueue(struct ahash_request *req) +{ + return cryptd_hash_enqueue(req, cryptd_hash_update); +} + +static void cryptd_hash_final(struct crypto_async_request *req_async, int err) +{ + struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); + struct crypto_hash *child = ctx->child; + struct ahash_request *req = ahash_request_cast(req_async); + struct cryptd_hash_request_ctx *rctx; + struct hash_desc desc; + + rctx = ahash_request_ctx(req); + + if (unlikely(err == -EINPROGRESS)) + goto out; + + desc.tfm = child; + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + err = crypto_hash_crt(child)->final(&desc, req->result); + + req->base.complete = rctx->complete; + +out: + local_bh_disable(); + rctx->complete(&req->base, err); + local_bh_enable(); +} + +static int cryptd_hash_final_enqueue(struct ahash_request *req) +{ + return cryptd_hash_enqueue(req, cryptd_hash_final); +} + +static void cryptd_hash_digest(struct crypto_async_request *req_async, int err) +{ + struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(req_async->tfm); + struct crypto_hash *child = ctx->child; + struct ahash_request *req = ahash_request_cast(req_async); + struct cryptd_hash_request_ctx *rctx; + struct hash_desc desc; + + rctx = ahash_request_ctx(req); + + if (unlikely(err == -EINPROGRESS)) + goto out; + + desc.tfm = child; + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + err = crypto_hash_crt(child)->digest(&desc, + req->src, + req->nbytes, + req->result); + + req->base.complete = rctx->complete; + +out: + local_bh_disable(); + rctx->complete(&req->base, err); + local_bh_enable(); +} + +static int cryptd_hash_digest_enqueue(struct ahash_request *req) +{ + return cryptd_hash_enqueue(req, cryptd_hash_digest); +} + +static struct crypto_instance *cryptd_alloc_hash( + struct rtattr **tb, struct cryptd_state *state) +{ + struct crypto_instance *inst; + struct crypto_alg *alg; + + alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_HASH, + CRYPTO_ALG_TYPE_HASH_MASK); + if (IS_ERR(alg)) + return ERR_PTR(PTR_ERR(alg)); + + inst = cryptd_alloc_instance(alg, state); + if (IS_ERR(inst)) + goto out_put_alg; + + inst->alg.cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC; + inst->alg.cra_type = &crypto_ahash_type; + + inst->alg.cra_ahash.digestsize = alg->cra_hash.digestsize; + inst->alg.cra_ctxsize = sizeof(struct cryptd_hash_ctx); + + inst->alg.cra_init = cryptd_hash_init_tfm; + inst->alg.cra_exit = cryptd_hash_exit_tfm; + + inst->alg.cra_ahash.init = cryptd_hash_init_enqueue; + inst->alg.cra_ahash.update = cryptd_hash_update_enqueue; + inst->alg.cra_ahash.final = cryptd_hash_final_enqueue; + inst->alg.cra_ahash.setkey = cryptd_hash_setkey; + inst->alg.cra_ahash.digest = cryptd_hash_digest_enqueue; + +out_put_alg: + crypto_mod_put(alg); + return inst; +} + static struct cryptd_state state; static struct crypto_instance *cryptd_alloc(struct rtattr **tb) @@ -273,6 +514,8 @@ static struct crypto_instance *cryptd_alloc(struct rtattr **tb) switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) { case CRYPTO_ALG_TYPE_BLKCIPHER: return cryptd_alloc_blkcipher(tb, &state); + case CRYPTO_ALG_TYPE_DIGEST: + return cryptd_alloc_hash(tb, &state); } return ERR_PTR(-EINVAL); -- cgit v0.10.2 From cde0e2c819aad91ed1e1c2e8aa64c16e7774c769 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Wed, 14 May 2008 21:24:51 +0800 Subject: [CRYPTO] tcrypt: Use asynchronous hash interface This patch changes tcrypt to use the new asynchronous hash interface for testing hash algorithm correctness. The speed tests will continue to use the existing interface for now. Signed-off-by: Loc Ho Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e0ea4d5..e99cb4b 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -104,22 +104,30 @@ static void test_hash(char *algo, struct hash_testvec *template, unsigned int i, j, k, temp; struct scatterlist sg[8]; char result[64]; - struct crypto_hash *tfm; - struct hash_desc desc; + struct crypto_ahash *tfm; + struct ahash_request *req; + struct tcrypt_result tresult; int ret; void *hash_buff; printk("\ntesting %s\n", algo); - tfm = crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC); + init_completion(&tresult.completion); + + tfm = crypto_alloc_ahash(algo, 0, 0); if (IS_ERR(tfm)) { printk("failed to load transform for %s: %ld\n", algo, PTR_ERR(tfm)); return; } - desc.tfm = tfm; - desc.flags = 0; + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + printk(KERN_ERR "failed to allocate request for %s\n", algo); + goto out_noreq; + } + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &tresult); for (i = 0; i < tcount; i++) { printk("test %u:\n", i + 1); @@ -133,8 +141,9 @@ static void test_hash(char *algo, struct hash_testvec *template, sg_init_one(&sg[0], hash_buff, template[i].psize); if (template[i].ksize) { - ret = crypto_hash_setkey(tfm, template[i].key, - template[i].ksize); + crypto_ahash_clear_flags(tfm, ~0); + ret = crypto_ahash_setkey(tfm, template[i].key, + template[i].ksize); if (ret) { printk("setkey() failed ret=%d\n", ret); kfree(hash_buff); @@ -142,17 +151,30 @@ static void test_hash(char *algo, struct hash_testvec *template, } } - ret = crypto_hash_digest(&desc, sg, template[i].psize, result); - if (ret) { + ahash_request_set_crypt(req, sg, result, template[i].psize); + ret = crypto_ahash_digest(req); + switch (ret) { + case 0: + break; + case -EINPROGRESS: + case -EBUSY: + ret = wait_for_completion_interruptible( + &tresult.completion); + if (!ret && !(ret = tresult.err)) { + INIT_COMPLETION(tresult.completion); + break; + } + /* fall through */ + default: printk("digest () failed ret=%d\n", ret); kfree(hash_buff); goto out; } - hexdump(result, crypto_hash_digestsize(tfm)); + hexdump(result, crypto_ahash_digestsize(tfm)); printk("%s\n", memcmp(result, template[i].digest, - crypto_hash_digestsize(tfm)) ? + crypto_ahash_digestsize(tfm)) ? "fail" : "pass"); kfree(hash_buff); } @@ -181,8 +203,9 @@ static void test_hash(char *algo, struct hash_testvec *template, } if (template[i].ksize) { - ret = crypto_hash_setkey(tfm, template[i].key, - template[i].ksize); + crypto_ahash_clear_flags(tfm, ~0); + ret = crypto_ahash_setkey(tfm, template[i].key, + template[i].ksize); if (ret) { printk("setkey() failed ret=%d\n", ret); @@ -190,23 +213,38 @@ static void test_hash(char *algo, struct hash_testvec *template, } } - ret = crypto_hash_digest(&desc, sg, template[i].psize, - result); - if (ret) { + ahash_request_set_crypt(req, sg, result, + template[i].psize); + ret = crypto_ahash_digest(req); + switch (ret) { + case 0: + break; + case -EINPROGRESS: + case -EBUSY: + ret = wait_for_completion_interruptible( + &tresult.completion); + if (!ret && !(ret = tresult.err)) { + INIT_COMPLETION(tresult.completion); + break; + } + /* fall through */ + default: printk("digest () failed ret=%d\n", ret); goto out; } - hexdump(result, crypto_hash_digestsize(tfm)); + hexdump(result, crypto_ahash_digestsize(tfm)); printk("%s\n", memcmp(result, template[i].digest, - crypto_hash_digestsize(tfm)) ? + crypto_ahash_digestsize(tfm)) ? "fail" : "pass"); } } out: - crypto_free_hash(tfm); + ahash_request_free(req); +out_noreq: + crypto_free_ahash(tfm); } static void test_aead(char *algo, int enc, struct aead_testvec *template, -- cgit v0.10.2 From 0bea3dc1e2d85deb9e0bc523949d5c812f65b556 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 15 May 2008 14:29:46 +0800 Subject: [CRYPTO] hifn: Remove duplicated include Removed duplicated include file . Signed-off-by: Huang Weiyi Signed-off-by: Evgeniy Polyakov Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 459d283..d0f71a1 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 0f923a2aab7baa94c5fef498384151af1cd72cba Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Tue, 20 May 2008 11:41:48 +0800 Subject: [CRYPTO] rmd128: Fix endian problems This patch is based on Sebastian Siewior's patch and fixes endian issues making rmd128 work properly on big-endian machines. Signed-off-by: Adrian-Ken Rueegsegger Acked-by: Sebastian Siewior Signed-off-by: Herbert Xu diff --git a/crypto/rmd128.c b/crypto/rmd128.c index f72d2ce8..89a535a 100644 --- a/crypto/rmd128.c +++ b/crypto/rmd128.c @@ -44,7 +44,7 @@ struct rmd128_ctx { #define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ #define ROUND(a, b, c, d, f, k, x, s) { \ - (a) += f((b), (c), (d)) + (x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ (a) = rol32((a), (s)); \ } @@ -218,28 +218,6 @@ static void rmd128_transform(u32 *state, u32 const *in) return; } -static inline void le32_to_cpu_array(u32 *buf, unsigned int words) -{ - while (words--) { - le32_to_cpus(buf); - buf++; - } -} - -static inline void cpu_to_le32_array(u32 *buf, unsigned int words) -{ - while (words--) { - cpu_to_le32s(buf); - buf++; - } -} - -static inline void rmd128_transform_helper(struct rmd128_ctx *ctx) -{ - le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); - rmd128_transform(ctx->state, ctx->buffer); -} - static void rmd128_init(struct crypto_tfm *tfm) { struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); @@ -272,13 +250,13 @@ static void rmd128_update(struct crypto_tfm *tfm, const u8 *data, memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), data, avail); - rmd128_transform_helper(rctx); + rmd128_transform(rctx->state, rctx->buffer); data += avail; len -= avail; while (len >= sizeof(rctx->buffer)) { memcpy(rctx->buffer, data, sizeof(rctx->buffer)); - rmd128_transform_helper(rctx); + rmd128_transform(rctx->state, rctx->buffer); data += sizeof(rctx->buffer); len -= sizeof(rctx->buffer); } @@ -290,10 +268,12 @@ static void rmd128_update(struct crypto_tfm *tfm, const u8 *data, static void rmd128_final(struct crypto_tfm *tfm, u8 *out) { struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); - u32 index, padlen; + u32 i, index, padlen; u64 bits; + u32 *dst = (u32 *)out; static const u8 padding[64] = { 0x80, }; - bits = rctx->byte_count << 3; + + bits = cpu_to_le64(rctx->byte_count << 3); /* Pad out to 56 mod 64 */ index = rctx->byte_count & 0x3f; @@ -304,7 +284,8 @@ static void rmd128_final(struct crypto_tfm *tfm, u8 *out) rmd128_update(tfm, (const u8 *)&bits, sizeof(bits)); /* Store state in digest */ - memcpy(out, rctx->state, sizeof(rctx->state)); + for (i = 0; i < 4; i++) + dst[i] = cpu_to_le32(rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); -- cgit v0.10.2 From c928a0cddd070720268013fd012508059aa3de5a Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Mon, 26 May 2008 20:32:52 +1000 Subject: [CRYPTO] rmd160: Fix endian issues This patch fixes endian issues making rmd160 work properly on big-endian machines. Signed-off-by: Adrian-Ken Rueegsegger Acked-by: Sebastian Siewior Signed-off-by: Herbert Xu diff --git a/crypto/rmd160.c b/crypto/rmd160.c index 80d647a..136e31f 100644 --- a/crypto/rmd160.c +++ b/crypto/rmd160.c @@ -47,7 +47,7 @@ struct rmd160_ctx { #define F5(x, y, z) (x ^ (y | ~z)) #define ROUND(a, b, c, d, e, f, k, x, s) { \ - (a) += f((b), (c), (d)) + (x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ (a) = rol32((a), (s)) + (e); \ (c) = rol32((c), 10); \ } @@ -261,28 +261,6 @@ static void rmd160_transform(u32 *state, u32 const *in) return; } -static inline void le32_to_cpu_array(u32 *buf, unsigned int words) -{ - while (words--) { - le32_to_cpus(buf); - buf++; - } -} - -static inline void cpu_to_le32_array(u32 *buf, unsigned int words) -{ - while (words--) { - cpu_to_le32s(buf); - buf++; - } -} - -static inline void rmd160_transform_helper(struct rmd160_ctx *ctx) -{ - le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); - rmd160_transform(ctx->state, ctx->buffer); -} - static void rmd160_init(struct crypto_tfm *tfm) { struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); @@ -316,13 +294,13 @@ static void rmd160_update(struct crypto_tfm *tfm, const u8 *data, memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), data, avail); - rmd160_transform_helper(rctx); + rmd160_transform(rctx->state, rctx->buffer); data += avail; len -= avail; while (len >= sizeof(rctx->buffer)) { memcpy(rctx->buffer, data, sizeof(rctx->buffer)); - rmd160_transform_helper(rctx); + rmd160_transform(rctx->state, rctx->buffer); data += sizeof(rctx->buffer); len -= sizeof(rctx->buffer); } @@ -334,10 +312,12 @@ static void rmd160_update(struct crypto_tfm *tfm, const u8 *data, static void rmd160_final(struct crypto_tfm *tfm, u8 *out) { struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); - u32 index, padlen; + u32 i, index, padlen; u64 bits; + u32 *dst = (u32 *)out; static const u8 padding[64] = { 0x80, }; - bits = rctx->byte_count << 3; + + bits = cpu_to_le64(rctx->byte_count << 3); /* Pad out to 56 mod 64 */ index = rctx->byte_count & 0x3f; @@ -348,7 +328,8 @@ static void rmd160_final(struct crypto_tfm *tfm, u8 *out) rmd160_update(tfm, (const u8 *)&bits, sizeof(bits)); /* Store state in digest */ - memcpy(out, rctx->state, sizeof(rctx->state)); + for (i = 0; i < 5; i++) + dst[i] = cpu_to_le32(rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); -- cgit v0.10.2 From 2952ff1a598ce300c911d00d82872d00ca8b61ca Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Mon, 26 May 2008 20:33:44 +1000 Subject: [CRYPTO] rmd256: Fix endian issues This patch fixes endian issues making rmd256 work properly on big-endian machines. Signed-off-by: Adrian-Ken Rueegsegger Acked-by: Sebastian Siewior Signed-off-by: Herbert Xu diff --git a/crypto/rmd256.c b/crypto/rmd256.c index 060ee81..88f2203 100644 --- a/crypto/rmd256.c +++ b/crypto/rmd256.c @@ -44,7 +44,7 @@ struct rmd256_ctx { #define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ #define ROUND(a, b, c, d, f, k, x, s) { \ - (a) += f((b), (c), (d)) + (x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ (a) = rol32((a), (s)); \ } @@ -233,28 +233,6 @@ static void rmd256_transform(u32 *state, u32 const *in) return; } -static inline void le32_to_cpu_array(u32 *buf, unsigned int words) -{ - while (words--) { - le32_to_cpus(buf); - buf++; - } -} - -static inline void cpu_to_le32_array(u32 *buf, unsigned int words) -{ - while (words--) { - cpu_to_le32s(buf); - buf++; - } -} - -static inline void rmd256_transform_helper(struct rmd256_ctx *ctx) -{ - le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); - rmd256_transform(ctx->state, ctx->buffer); -} - static void rmd256_init(struct crypto_tfm *tfm) { struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); @@ -291,13 +269,13 @@ static void rmd256_update(struct crypto_tfm *tfm, const u8 *data, memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), data, avail); - rmd256_transform_helper(rctx); + rmd256_transform(rctx->state, rctx->buffer); data += avail; len -= avail; while (len >= sizeof(rctx->buffer)) { memcpy(rctx->buffer, data, sizeof(rctx->buffer)); - rmd256_transform_helper(rctx); + rmd256_transform(rctx->state, rctx->buffer); data += sizeof(rctx->buffer); len -= sizeof(rctx->buffer); } @@ -309,10 +287,12 @@ static void rmd256_update(struct crypto_tfm *tfm, const u8 *data, static void rmd256_final(struct crypto_tfm *tfm, u8 *out) { struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); - u32 index, padlen; + u32 i, index, padlen; u64 bits; + u32 *dst = (u32 *)out; static const u8 padding[64] = { 0x80, }; - bits = rctx->byte_count << 3; + + bits = cpu_to_le64(rctx->byte_count << 3); /* Pad out to 56 mod 64 */ index = rctx->byte_count & 0x3f; @@ -323,7 +303,8 @@ static void rmd256_final(struct crypto_tfm *tfm, u8 *out) rmd256_update(tfm, (const u8 *)&bits, sizeof(bits)); /* Store state in digest */ - memcpy(out, rctx->state, sizeof(rctx->state)); + for (i = 0; i < 8; i++) + dst[i] = cpu_to_le32(rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); -- cgit v0.10.2 From feedfdaa7bc02694c122d2d5246184248fb04513 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Mon, 26 May 2008 20:54:34 +1000 Subject: [CRYPTO] rmd320: Fix endian issues This patch fixes endian issues making rmd320 work properly on big-endian machines. Signed-off-by: Adrian-Ken Rueegsegger Acked-by: Sebastian Siewior Signed-off-by: Herbert Xu diff --git a/crypto/rmd320.c b/crypto/rmd320.c index b39c054..5b172f8 100644 --- a/crypto/rmd320.c +++ b/crypto/rmd320.c @@ -47,7 +47,7 @@ struct rmd320_ctx { #define F5(x, y, z) (x ^ (y | ~z)) #define ROUND(a, b, c, d, e, f, k, x, s) { \ - (a) += f((b), (c), (d)) + (x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ (a) = rol32((a), (s)) + (e); \ (c) = rol32((c), 10); \ } @@ -280,28 +280,6 @@ static void rmd320_transform(u32 *state, u32 const *in) return; } -static inline void le32_to_cpu_array(u32 *buf, unsigned int words) -{ - while (words--) { - le32_to_cpus(buf); - buf++; - } -} - -static inline void cpu_to_le32_array(u32 *buf, unsigned int words) -{ - while (words--) { - cpu_to_le32s(buf); - buf++; - } -} - -static inline void rmd320_transform_helper(struct rmd320_ctx *ctx) -{ - le32_to_cpu_array(ctx->buffer, sizeof(ctx->buffer) / sizeof(u32)); - rmd320_transform(ctx->state, ctx->buffer); -} - static void rmd320_init(struct crypto_tfm *tfm) { struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); @@ -340,13 +318,13 @@ static void rmd320_update(struct crypto_tfm *tfm, const u8 *data, memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail), data, avail); - rmd320_transform_helper(rctx); + rmd320_transform(rctx->state, rctx->buffer); data += avail; len -= avail; while (len >= sizeof(rctx->buffer)) { memcpy(rctx->buffer, data, sizeof(rctx->buffer)); - rmd320_transform_helper(rctx); + rmd320_transform(rctx->state, rctx->buffer); data += sizeof(rctx->buffer); len -= sizeof(rctx->buffer); } @@ -358,10 +336,12 @@ static void rmd320_update(struct crypto_tfm *tfm, const u8 *data, static void rmd320_final(struct crypto_tfm *tfm, u8 *out) { struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); - u32 index, padlen; + u32 i, index, padlen; u64 bits; + u32 *dst = (u32 *)out; static const u8 padding[64] = { 0x80, }; - bits = rctx->byte_count << 3; + + bits = cpu_to_le64(rctx->byte_count << 3); /* Pad out to 56 mod 64 */ index = rctx->byte_count & 0x3f; @@ -372,7 +352,8 @@ static void rmd320_final(struct crypto_tfm *tfm, u8 *out) rmd320_update(tfm, (const u8 *)&bits, sizeof(bits)); /* Store state in digest */ - memcpy(out, rctx->state, sizeof(rctx->state)); + for (i = 0; i < 10; i++) + dst[i] = cpu_to_le32(rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); -- cgit v0.10.2 From 0936a944068ef68f8b19f437e03f4654c29f2423 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 26 May 2008 21:21:07 +1000 Subject: [CRYPTO] hifn: Simplify code using ARRAY_SIZE() macro Signed-off-by: Robert P. J. Day Signed-off-by: Herbert Xu diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index d0f71a1..4d22b21 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -895,7 +895,7 @@ static int hifn_enable_crypto(struct hifn_device *dev) char *offtbl = NULL; int i; - for (i = 0; i < sizeof(pci2id)/sizeof(pci2id[0]); i++) { + for (i = 0; i < ARRAY_SIZE(pci2id); i++) { if (pci2id[i].pci_vendor == dev->pdev->vendor && pci2id[i].pci_prod == dev->pdev->device) { offtbl = pci2id[i].card_id; -- cgit v0.10.2 From 5cdcc22f25b0766fe16d5dd8e3b2efc91fa4da6e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 2 Jun 2008 21:30:38 +1000 Subject: [CRYPTO] rmd: Use pointer form of endian swapping operations This patch converts the relevant code in the rmd implementations to use the pointer form of the endian swapping operations. This allows certain architectures to generate more optimised code. For example, on sparc64 this more than halves the CPU cycles on a typical hashing operation. Based on a patch by David Miller. Signed-off-by: Herbert Xu diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 89a535a..1a481df 100644 --- a/crypto/rmd128.c +++ b/crypto/rmd128.c @@ -44,7 +44,7 @@ struct rmd128_ctx { #define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ #define ROUND(a, b, c, d, f, k, x, s) { \ - (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \ (a) = rol32((a), (s)); \ } @@ -285,7 +285,7 @@ static void rmd128_final(struct crypto_tfm *tfm, u8 *out) /* Store state in digest */ for (i = 0; i < 4; i++) - dst[i] = cpu_to_le32(rctx->state[i]); + dst[i] = cpu_to_le32p(&rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); diff --git a/crypto/rmd160.c b/crypto/rmd160.c index 136e31f..e9fd5f6 100644 --- a/crypto/rmd160.c +++ b/crypto/rmd160.c @@ -47,7 +47,7 @@ struct rmd160_ctx { #define F5(x, y, z) (x ^ (y | ~z)) #define ROUND(a, b, c, d, e, f, k, x, s) { \ - (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \ (a) = rol32((a), (s)) + (e); \ (c) = rol32((c), 10); \ } @@ -329,7 +329,7 @@ static void rmd160_final(struct crypto_tfm *tfm, u8 *out) /* Store state in digest */ for (i = 0; i < 5; i++) - dst[i] = cpu_to_le32(rctx->state[i]); + dst[i] = cpu_to_le32p(&rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); diff --git a/crypto/rmd256.c b/crypto/rmd256.c index 88f2203..b088526 100644 --- a/crypto/rmd256.c +++ b/crypto/rmd256.c @@ -44,7 +44,7 @@ struct rmd256_ctx { #define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */ #define ROUND(a, b, c, d, f, k, x, s) { \ - (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \ (a) = rol32((a), (s)); \ } @@ -304,7 +304,7 @@ static void rmd256_final(struct crypto_tfm *tfm, u8 *out) /* Store state in digest */ for (i = 0; i < 8; i++) - dst[i] = cpu_to_le32(rctx->state[i]); + dst[i] = cpu_to_le32p(&rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); diff --git a/crypto/rmd320.c b/crypto/rmd320.c index 5b172f8..dba03ec 100644 --- a/crypto/rmd320.c +++ b/crypto/rmd320.c @@ -47,7 +47,7 @@ struct rmd320_ctx { #define F5(x, y, z) (x ^ (y | ~z)) #define ROUND(a, b, c, d, e, f, k, x, s) { \ - (a) += f((b), (c), (d)) + le32_to_cpu(x) + (k); \ + (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \ (a) = rol32((a), (s)) + (e); \ (c) = rol32((c), 10); \ } @@ -353,7 +353,7 @@ static void rmd320_final(struct crypto_tfm *tfm, u8 *out) /* Store state in digest */ for (i = 0; i < 10; i++) - dst[i] = cpu_to_le32(rctx->state[i]); + dst[i] = cpu_to_le32p(&rctx->state[i]); /* Wipe context */ memset(rctx, 0, sizeof(*rctx)); -- cgit v0.10.2 From d729de23e86bbbb28adf6c3ded3651ea4ad8c539 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 3 Jun 2008 20:00:16 +1000 Subject: [CRYPTO] tcrypt: Add self test for des3_ebe cipher operating in cbc mode Patch to add checking of DES3 test vectors using CBC mode. FIPS-140-2 compliance mandates that any supported mode of operation must include a self test. This satisfies that requirement for cbc(des3_ede). The included test vector was generated by me using openssl. Key/IV was generated with the following command: openssl enc -des_ede_cbc -P input and output values were generated by repeating the string "Too many secrets" a few times over, truncating it to 128 bytes, and encrypting it with openssl using the aformentioned key. Tested successfully by myself Signed-off-by: Neil Horman Acked-by: Adrian-Ken Rueegsegger Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e99cb4b..ffc1ec6 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1220,6 +1220,14 @@ static void do_test(void) test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); + test_cipher("cbc(des3_ede)", ENCRYPT, + des3_ede_cbc_enc_tv_template, + DES3_EDE_CBC_ENC_TEST_VECTORS); + + test_cipher("cbc(des3_ede)", DECRYPT, + des3_ede_cbc_dec_tv_template, + DES3_EDE_CBC_DEC_TEST_VECTORS); + test_hash("md4", md4_tv_template, MD4_TEST_VECTORS); test_hash("sha224", sha224_tv_template, SHA224_TEST_VECTORS); @@ -1430,6 +1438,14 @@ static void do_test(void) DES3_EDE_ENC_TEST_VECTORS); test_cipher("ecb(des3_ede)", DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS); + + test_cipher("cbc(des3_ede)", ENCRYPT, + des3_ede_cbc_enc_tv_template, + DES3_EDE_CBC_ENC_TEST_VECTORS); + + test_cipher("cbc(des3_ede)", DECRYPT, + des3_ede_cbc_dec_tv_template, + DES3_EDE_CBC_DEC_TEST_VECTORS); break; case 5: diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h index 20bd5fe..801e0c2 100644 --- a/crypto/tcrypt.h +++ b/crypto/tcrypt.h @@ -1863,6 +1863,8 @@ static struct hash_testvec hmac_sha512_tv_template[] = { #define DES_CBC_DEC_TEST_VECTORS 4 #define DES3_EDE_ENC_TEST_VECTORS 3 #define DES3_EDE_DEC_TEST_VECTORS 3 +#define DES3_EDE_CBC_ENC_TEST_VECTORS 1 +#define DES3_EDE_CBC_DEC_TEST_VECTORS 1 static struct cipher_testvec des_enc_tv_template[] = { { /* From Applied Cryptography */ @@ -2101,9 +2103,6 @@ static struct cipher_testvec des_cbc_dec_tv_template[] = { }, }; -/* - * We really need some more test vectors, especially for DES3 CBC. - */ static struct cipher_testvec des3_ede_enc_tv_template[] = { { /* These are from openssl */ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef" @@ -2166,6 +2165,94 @@ static struct cipher_testvec des3_ede_dec_tv_template[] = { }, }; +static struct cipher_testvec des3_ede_cbc_enc_tv_template[] = { + { /* Generated from openssl */ + .key = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24" + "\x44\x4D\x99\x5A\x12\xD6\x40\xC0" + "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8", + .klen = 24, + .iv = "\x7D\x33\x88\x93\x0F\x93\xB2\x42", + .input = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e" + "\x53\x20\x63\x65\x65\x72\x73\x74" + "\x54\x20\x6f\x6f\x4d\x20\x6e\x61" + "\x20\x79\x65\x53\x72\x63\x74\x65" + "\x20\x73\x6f\x54\x20\x6f\x61\x4d" + "\x79\x6e\x53\x20\x63\x65\x65\x72" + "\x73\x74\x54\x20\x6f\x6f\x4d\x20" + "\x6e\x61\x20\x79\x65\x53\x72\x63" + "\x74\x65\x20\x73\x6f\x54\x20\x6f" + "\x61\x4d\x79\x6e\x53\x20\x63\x65" + "\x65\x72\x73\x74\x54\x20\x6f\x6f" + "\x4d\x20\x6e\x61\x20\x79\x65\x53" + "\x72\x63\x74\x65\x20\x73\x6f\x54" + "\x20\x6f\x61\x4d\x79\x6e\x53\x20" + "\x63\x65\x65\x72\x73\x74\x54\x20" + "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79", + .ilen = 128, + .result = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4" + "\x67\x17\x21\xc7\x6e\x8a\xd5\x49" + "\x74\xb3\x49\x05\xc5\x1c\xd0\xed" + "\x12\x56\x5c\x53\x96\xb6\x00\x7d" + "\x90\x48\xfc\xf5\x8d\x29\x39\xcc" + "\x8a\xd5\x35\x18\x36\x23\x4e\xd7" + "\x76\xd1\xda\x0c\x94\x67\xbb\x04" + "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea" + "\x22\x64\x47\xaa\x8f\x75\x13\xbf" + "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a" + "\x71\x63\x2e\x89\x7b\x1e\x12\xca" + "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a" + "\xd6\xf9\x21\x31\x62\x44\x45\xa6" + "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc" + "\x9d\xde\xa5\x70\xe9\x42\x45\x8a" + "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19", + .rlen = 128, + }, +}; + +static struct cipher_testvec des3_ede_cbc_dec_tv_template[] = { + { /* Generated from openssl */ + .key = "\xE9\xC0\xFF\x2E\x76\x0B\x64\x24" + "\x44\x4D\x99\x5A\x12\xD6\x40\xC0" + "\xEA\xC2\x84\xE8\x14\x95\xDB\xE8", + .klen = 24, + .iv = "\x7D\x33\x88\x93\x0F\x93\xB2\x42", + .input = "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4" + "\x67\x17\x21\xc7\x6e\x8a\xd5\x49" + "\x74\xb3\x49\x05\xc5\x1c\xd0\xed" + "\x12\x56\x5c\x53\x96\xb6\x00\x7d" + "\x90\x48\xfc\xf5\x8d\x29\x39\xcc" + "\x8a\xd5\x35\x18\x36\x23\x4e\xd7" + "\x76\xd1\xda\x0c\x94\x67\xbb\x04" + "\x8b\xf2\x03\x6c\xa8\xcf\xb6\xea" + "\x22\x64\x47\xaa\x8f\x75\x13\xbf" + "\x9f\xc2\xc3\xf0\xc9\x56\xc5\x7a" + "\x71\x63\x2e\x89\x7b\x1e\x12\xca" + "\xe2\x5f\xaf\xd8\xa4\xf8\xc9\x7a" + "\xd6\xf9\x21\x31\x62\x44\x45\xa6" + "\xd6\xbc\x5a\xd3\x2d\x54\x43\xcc" + "\x9d\xde\xa5\x70\xe9\x42\x45\x8a" + "\x6b\xfa\xb1\x91\x13\xb0\xd9\x19", + .ilen = 128, + .result = "\x6f\x54\x20\x6f\x61\x4d\x79\x6e" + "\x53\x20\x63\x65\x65\x72\x73\x74" + "\x54\x20\x6f\x6f\x4d\x20\x6e\x61" + "\x20\x79\x65\x53\x72\x63\x74\x65" + "\x20\x73\x6f\x54\x20\x6f\x61\x4d" + "\x79\x6e\x53\x20\x63\x65\x65\x72" + "\x73\x74\x54\x20\x6f\x6f\x4d\x20" + "\x6e\x61\x20\x79\x65\x53\x72\x63" + "\x74\x65\x20\x73\x6f\x54\x20\x6f" + "\x61\x4d\x79\x6e\x53\x20\x63\x65" + "\x65\x72\x73\x74\x54\x20\x6f\x6f" + "\x4d\x20\x6e\x61\x20\x79\x65\x53" + "\x72\x63\x74\x65\x20\x73\x6f\x54" + "\x20\x6f\x61\x4d\x79\x6e\x53\x20" + "\x63\x65\x65\x72\x73\x74\x54\x20" + "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79", + .rlen = 128, + }, +}; + /* * Blowfish test vectors. */ -- cgit v0.10.2 From 9c4a79653b35efc9d6790c295e22f79f4b361125 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Mon, 23 Jun 2008 19:50:15 +0800 Subject: crypto: talitos - Freescale integrated security engine (SEC) driver Add support for the SEC available on a wide range of PowerQUICC devices, e.g. MPC8349E, MPC8548E. This initial version supports authenc(hmac(sha1),cbc(aes)) for use with IPsec. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 43b71b6..249c135 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -174,4 +174,20 @@ config CRYPTO_DEV_HIFN_795X_RNG Select this option if you want to enable the random number generator on the HIFN 795x crypto adapters. +config CRYPTO_DEV_TALITOS + tristate "Talitos Freescale Security Engine (SEC)" + select CRYPTO_ALGAPI + select CRYPTO_AUTHENC + select HW_RANDOM + depends on FSL_SOC + help + Say 'Y' here to use the Freescale Security Engine (SEC) + to offload cryptographic algorithm computation. + + The Freescale SEC is present on PowerQUICC 'E' processors, such + as the MPC8349E and MPC8548E. + + To compile this driver as a module, choose M here: the module + will be called talitos. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c0327f0..d29d2cd 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o +obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c new file mode 100644 index 0000000..e123312 --- /dev/null +++ b/drivers/crypto/talitos.c @@ -0,0 +1,1467 @@ +/* + * talitos - Freescale Integrated Security Engine (SEC) device driver + * + * Copyright (c) 2008 Freescale Semiconductor, Inc. + * + * Scatterlist Crypto API glue code copied from files with the following: + * Copyright (c) 2006-2007 Herbert Xu + * + * Crypto algorithm registration code copied from hifn driver: + * 2007+ Copyright (c) Evgeniy Polyakov + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "talitos.h" + +#define TALITOS_TIMEOUT 100000 +#define TALITOS_MAX_DATA_LEN 65535 + +#define DESC_TYPE(desc_hdr) ((be32_to_cpu(desc_hdr) >> 3) & 0x1f) +#define PRIMARY_EU(desc_hdr) ((be32_to_cpu(desc_hdr) >> 28) & 0xf) +#define SECONDARY_EU(desc_hdr) ((be32_to_cpu(desc_hdr) >> 16) & 0xf) + +/* descriptor pointer entry */ +struct talitos_ptr { + __be16 len; /* length */ + u8 j_extent; /* jump to sg link table and/or extent */ + u8 eptr; /* extended address */ + __be32 ptr; /* address */ +}; + +/* descriptor */ +struct talitos_desc { + __be32 hdr; /* header high bits */ + __be32 hdr_lo; /* header low bits */ + struct talitos_ptr ptr[7]; /* ptr/len pair array */ +}; + +/** + * talitos_request - descriptor submission request + * @desc: descriptor pointer (kernel virtual) + * @dma_desc: descriptor's physical bus address + * @callback: whom to call when descriptor processing is done + * @context: caller context (optional) + */ +struct talitos_request { + struct talitos_desc *desc; + dma_addr_t dma_desc; + void (*callback) (struct device *dev, struct talitos_desc *desc, + void *context, int error); + void *context; +}; + +struct talitos_private { + struct device *dev; + struct of_device *ofdev; + void __iomem *reg; + int irq; + + /* SEC version geometry (from device tree node) */ + unsigned int num_channels; + unsigned int chfifo_len; + unsigned int exec_units; + unsigned int desc_types; + + /* next channel to be assigned next incoming descriptor */ + atomic_t last_chan; + + /* per-channel request fifo */ + struct talitos_request **fifo; + + /* + * length of the request fifo + * fifo_len is chfifo_len rounded up to next power of 2 + * so we can use bitwise ops to wrap + */ + unsigned int fifo_len; + + /* per-channel index to next free descriptor request */ + int *head; + + /* per-channel index to next in-progress/done descriptor request */ + int *tail; + + /* per-channel request submission (head) and release (tail) locks */ + spinlock_t *head_lock; + spinlock_t *tail_lock; + + /* request callback tasklet */ + struct tasklet_struct done_task; + struct tasklet_struct error_task; + + /* list of registered algorithms */ + struct list_head alg_list; + + /* hwrng device */ + struct hwrng rng; +}; + +/* + * map virtual single (contiguous) pointer to h/w descriptor pointer + */ +static void map_single_talitos_ptr(struct device *dev, + struct talitos_ptr *talitos_ptr, + unsigned short len, void *data, + unsigned char extent, + enum dma_data_direction dir) +{ + talitos_ptr->len = cpu_to_be16(len); + talitos_ptr->ptr = cpu_to_be32(dma_map_single(dev, data, len, dir)); + talitos_ptr->j_extent = extent; +} + +/* + * unmap bus single (contiguous) h/w descriptor pointer + */ +static void unmap_single_talitos_ptr(struct device *dev, + struct talitos_ptr *talitos_ptr, + enum dma_data_direction dir) +{ + dma_unmap_single(dev, be32_to_cpu(talitos_ptr->ptr), + be16_to_cpu(talitos_ptr->len), dir); +} + +static int reset_channel(struct device *dev, int ch) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + unsigned int timeout = TALITOS_TIMEOUT; + + setbits32(priv->reg + TALITOS_CCCR(ch), TALITOS_CCCR_RESET); + + while ((in_be32(priv->reg + TALITOS_CCCR(ch)) & TALITOS_CCCR_RESET) + && --timeout) + cpu_relax(); + + if (timeout == 0) { + dev_err(dev, "failed to reset channel %d\n", ch); + return -EIO; + } + + /* set done writeback and IRQ */ + setbits32(priv->reg + TALITOS_CCCR_LO(ch), TALITOS_CCCR_LO_CDWE | + TALITOS_CCCR_LO_CDIE); + + return 0; +} + +static int reset_device(struct device *dev) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + unsigned int timeout = TALITOS_TIMEOUT; + + setbits32(priv->reg + TALITOS_MCR, TALITOS_MCR_SWR); + + while ((in_be32(priv->reg + TALITOS_MCR) & TALITOS_MCR_SWR) + && --timeout) + cpu_relax(); + + if (timeout == 0) { + dev_err(dev, "failed to reset device\n"); + return -EIO; + } + + return 0; +} + +/* + * Reset and initialize the device + */ +static int init_device(struct device *dev) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + int ch, err; + + /* + * Master reset + * errata documentation: warning: certain SEC interrupts + * are not fully cleared by writing the MCR:SWR bit, + * set bit twice to completely reset + */ + err = reset_device(dev); + if (err) + return err; + + err = reset_device(dev); + if (err) + return err; + + /* reset channels */ + for (ch = 0; ch < priv->num_channels; ch++) { + err = reset_channel(dev, ch); + if (err) + return err; + } + + /* enable channel done and error interrupts */ + setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT); + setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); + + return 0; +} + +/** + * talitos_submit - submits a descriptor to the device for processing + * @dev: the SEC device to be used + * @desc: the descriptor to be processed by the device + * @callback: whom to call when processing is complete + * @context: a handle for use by caller (optional) + * + * desc must contain valid dma-mapped (bus physical) address pointers. + * callback must check err and feedback in descriptor header + * for device processing status. + */ +static int talitos_submit(struct device *dev, struct talitos_desc *desc, + void (*callback)(struct device *dev, + struct talitos_desc *desc, + void *context, int error), + void *context) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + struct talitos_request *request; + unsigned long flags, ch; + int head; + + /* select done notification */ + desc->hdr |= DESC_HDR_DONE_NOTIFY; + + /* emulate SEC's round-robin channel fifo polling scheme */ + ch = atomic_inc_return(&priv->last_chan) & (priv->num_channels - 1); + + spin_lock_irqsave(&priv->head_lock[ch], flags); + + head = priv->head[ch]; + request = &priv->fifo[ch][head]; + + if (request->desc) { + /* request queue is full */ + spin_unlock_irqrestore(&priv->head_lock[ch], flags); + return -EAGAIN; + } + + /* map descriptor and save caller data */ + request->dma_desc = dma_map_single(dev, desc, sizeof(*desc), + DMA_BIDIRECTIONAL); + request->callback = callback; + request->context = context; + + /* increment fifo head */ + priv->head[ch] = (priv->head[ch] + 1) & (priv->fifo_len - 1); + + smp_wmb(); + request->desc = desc; + + /* GO! */ + wmb(); + out_be32(priv->reg + TALITOS_FF_LO(ch), request->dma_desc); + + spin_unlock_irqrestore(&priv->head_lock[ch], flags); + + return -EINPROGRESS; +} + +/* + * process what was done, notify callback of error if not + */ +static void flush_channel(struct device *dev, int ch, int error, int reset_ch) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + struct talitos_request *request, saved_req; + unsigned long flags; + int tail, status; + + spin_lock_irqsave(&priv->tail_lock[ch], flags); + + tail = priv->tail[ch]; + while (priv->fifo[ch][tail].desc) { + request = &priv->fifo[ch][tail]; + + /* descriptors with their done bits set don't get the error */ + rmb(); + if ((request->desc->hdr & DESC_HDR_DONE) == DESC_HDR_DONE) + status = 0; + else + if (!error) + break; + else + status = error; + + dma_unmap_single(dev, request->dma_desc, + sizeof(struct talitos_desc), DMA_BIDIRECTIONAL); + + /* copy entries so we can call callback outside lock */ + saved_req.desc = request->desc; + saved_req.callback = request->callback; + saved_req.context = request->context; + + /* release request entry in fifo */ + smp_wmb(); + request->desc = NULL; + + /* increment fifo tail */ + priv->tail[ch] = (tail + 1) & (priv->fifo_len - 1); + + spin_unlock_irqrestore(&priv->tail_lock[ch], flags); + saved_req.callback(dev, saved_req.desc, saved_req.context, + status); + /* channel may resume processing in single desc error case */ + if (error && !reset_ch && status == error) + return; + spin_lock_irqsave(&priv->tail_lock[ch], flags); + tail = priv->tail[ch]; + } + + spin_unlock_irqrestore(&priv->tail_lock[ch], flags); +} + +/* + * process completed requests for channels that have done status + */ +static void talitos_done(unsigned long data) +{ + struct device *dev = (struct device *)data; + struct talitos_private *priv = dev_get_drvdata(dev); + int ch; + + for (ch = 0; ch < priv->num_channels; ch++) + flush_channel(dev, ch, 0, 0); +} + +/* + * locate current (offending) descriptor + */ +static struct talitos_desc *current_desc(struct device *dev, int ch) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + int tail = priv->tail[ch]; + dma_addr_t cur_desc; + + cur_desc = in_be32(priv->reg + TALITOS_CDPR_LO(ch)); + + while (priv->fifo[ch][tail].dma_desc != cur_desc) { + tail = (tail + 1) & (priv->fifo_len - 1); + if (tail == priv->tail[ch]) { + dev_err(dev, "couldn't locate current descriptor\n"); + return NULL; + } + } + + return priv->fifo[ch][tail].desc; +} + +/* + * user diagnostics; report root cause of error based on execution unit status + */ +static void report_eu_error(struct device *dev, int ch, struct talitos_desc *desc) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + int i; + + switch (desc->hdr & DESC_HDR_SEL0_MASK) { + case DESC_HDR_SEL0_AFEU: + dev_err(dev, "AFEUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_AFEUISR), + in_be32(priv->reg + TALITOS_AFEUISR_LO)); + break; + case DESC_HDR_SEL0_DEU: + dev_err(dev, "DEUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_DEUISR), + in_be32(priv->reg + TALITOS_DEUISR_LO)); + break; + case DESC_HDR_SEL0_MDEUA: + case DESC_HDR_SEL0_MDEUB: + dev_err(dev, "MDEUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_MDEUISR), + in_be32(priv->reg + TALITOS_MDEUISR_LO)); + break; + case DESC_HDR_SEL0_RNG: + dev_err(dev, "RNGUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_RNGUISR), + in_be32(priv->reg + TALITOS_RNGUISR_LO)); + break; + case DESC_HDR_SEL0_PKEU: + dev_err(dev, "PKEUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_PKEUISR), + in_be32(priv->reg + TALITOS_PKEUISR_LO)); + break; + case DESC_HDR_SEL0_AESU: + dev_err(dev, "AESUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_AESUISR), + in_be32(priv->reg + TALITOS_AESUISR_LO)); + break; + case DESC_HDR_SEL0_CRCU: + dev_err(dev, "CRCUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_CRCUISR), + in_be32(priv->reg + TALITOS_CRCUISR_LO)); + break; + case DESC_HDR_SEL0_KEU: + dev_err(dev, "KEUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_KEUISR), + in_be32(priv->reg + TALITOS_KEUISR_LO)); + break; + } + + switch (desc->hdr & DESC_HDR_SEL1_MASK) { + case DESC_HDR_SEL1_MDEUA: + case DESC_HDR_SEL1_MDEUB: + dev_err(dev, "MDEUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_MDEUISR), + in_be32(priv->reg + TALITOS_MDEUISR_LO)); + break; + case DESC_HDR_SEL1_CRCU: + dev_err(dev, "CRCUISR 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_CRCUISR), + in_be32(priv->reg + TALITOS_CRCUISR_LO)); + break; + } + + for (i = 0; i < 8; i++) + dev_err(dev, "DESCBUF 0x%08x_%08x\n", + in_be32(priv->reg + TALITOS_DESCBUF(ch) + 8*i), + in_be32(priv->reg + TALITOS_DESCBUF_LO(ch) + 8*i)); +} + +/* + * recover from error interrupts + */ +static void talitos_error(unsigned long data) +{ + struct device *dev = (struct device *)data; + struct talitos_private *priv = dev_get_drvdata(dev); + unsigned int timeout = TALITOS_TIMEOUT; + int ch, error, reset_dev = 0, reset_ch = 0; + u32 isr, isr_lo, v, v_lo; + + isr = in_be32(priv->reg + TALITOS_ISR); + isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); + + for (ch = 0; ch < priv->num_channels; ch++) { + /* skip channels without errors */ + if (!(isr & (1 << (ch * 2 + 1)))) + continue; + + error = -EINVAL; + + v = in_be32(priv->reg + TALITOS_CCPSR(ch)); + v_lo = in_be32(priv->reg + TALITOS_CCPSR_LO(ch)); + + if (v_lo & TALITOS_CCPSR_LO_DOF) { + dev_err(dev, "double fetch fifo overflow error\n"); + error = -EAGAIN; + reset_ch = 1; + } + if (v_lo & TALITOS_CCPSR_LO_SOF) { + /* h/w dropped descriptor */ + dev_err(dev, "single fetch fifo overflow error\n"); + error = -EAGAIN; + } + if (v_lo & TALITOS_CCPSR_LO_MDTE) + dev_err(dev, "master data transfer error\n"); + if (v_lo & TALITOS_CCPSR_LO_SGDLZ) + dev_err(dev, "s/g data length zero error\n"); + if (v_lo & TALITOS_CCPSR_LO_FPZ) + dev_err(dev, "fetch pointer zero error\n"); + if (v_lo & TALITOS_CCPSR_LO_IDH) + dev_err(dev, "illegal descriptor header error\n"); + if (v_lo & TALITOS_CCPSR_LO_IEU) + dev_err(dev, "invalid execution unit error\n"); + if (v_lo & TALITOS_CCPSR_LO_EU) + report_eu_error(dev, ch, current_desc(dev, ch)); + if (v_lo & TALITOS_CCPSR_LO_GB) + dev_err(dev, "gather boundary error\n"); + if (v_lo & TALITOS_CCPSR_LO_GRL) + dev_err(dev, "gather return/length error\n"); + if (v_lo & TALITOS_CCPSR_LO_SB) + dev_err(dev, "scatter boundary error\n"); + if (v_lo & TALITOS_CCPSR_LO_SRL) + dev_err(dev, "scatter return/length error\n"); + + flush_channel(dev, ch, error, reset_ch); + + if (reset_ch) { + reset_channel(dev, ch); + } else { + setbits32(priv->reg + TALITOS_CCCR(ch), + TALITOS_CCCR_CONT); + setbits32(priv->reg + TALITOS_CCCR_LO(ch), 0); + while ((in_be32(priv->reg + TALITOS_CCCR(ch)) & + TALITOS_CCCR_CONT) && --timeout) + cpu_relax(); + if (timeout == 0) { + dev_err(dev, "failed to restart channel %d\n", + ch); + reset_dev = 1; + } + } + } + if (reset_dev || isr & ~TALITOS_ISR_CHERR || isr_lo) { + dev_err(dev, "done overflow, internal time out, or rngu error: " + "ISR 0x%08x_%08x\n", isr, isr_lo); + + /* purge request queues */ + for (ch = 0; ch < priv->num_channels; ch++) + flush_channel(dev, ch, -EIO, 1); + + /* reset and reinitialize the device */ + init_device(dev); + } +} + +static irqreturn_t talitos_interrupt(int irq, void *data) +{ + struct device *dev = data; + struct talitos_private *priv = dev_get_drvdata(dev); + u32 isr, isr_lo; + + isr = in_be32(priv->reg + TALITOS_ISR); + isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); + + /* ack */ + out_be32(priv->reg + TALITOS_ICR, isr); + out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); + + if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo)) + talitos_error((unsigned long)data); + else + if (likely(isr & TALITOS_ISR_CHDONE)) + tasklet_schedule(&priv->done_task); + + return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE; +} + +/* + * hwrng + */ +static int talitos_rng_data_present(struct hwrng *rng, int wait) +{ + struct device *dev = (struct device *)rng->priv; + struct talitos_private *priv = dev_get_drvdata(dev); + u32 ofl; + int i; + + for (i = 0; i < 20; i++) { + ofl = in_be32(priv->reg + TALITOS_RNGUSR_LO) & + TALITOS_RNGUSR_LO_OFL; + if (ofl || !wait) + break; + udelay(10); + } + + return !!ofl; +} + +static int talitos_rng_data_read(struct hwrng *rng, u32 *data) +{ + struct device *dev = (struct device *)rng->priv; + struct talitos_private *priv = dev_get_drvdata(dev); + + /* rng fifo requires 64-bit accesses */ + *data = in_be32(priv->reg + TALITOS_RNGU_FIFO); + *data = in_be32(priv->reg + TALITOS_RNGU_FIFO_LO); + + return sizeof(u32); +} + +static int talitos_rng_init(struct hwrng *rng) +{ + struct device *dev = (struct device *)rng->priv; + struct talitos_private *priv = dev_get_drvdata(dev); + unsigned int timeout = TALITOS_TIMEOUT; + + setbits32(priv->reg + TALITOS_RNGURCR_LO, TALITOS_RNGURCR_LO_SR); + while (!(in_be32(priv->reg + TALITOS_RNGUSR_LO) & TALITOS_RNGUSR_LO_RD) + && --timeout) + cpu_relax(); + if (timeout == 0) { + dev_err(dev, "failed to reset rng hw\n"); + return -ENODEV; + } + + /* start generating */ + setbits32(priv->reg + TALITOS_RNGUDSR_LO, 0); + + return 0; +} + +static int talitos_register_rng(struct device *dev) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + + priv->rng.name = dev_driver_string(dev), + priv->rng.init = talitos_rng_init, + priv->rng.data_present = talitos_rng_data_present, + priv->rng.data_read = talitos_rng_data_read, + priv->rng.priv = (unsigned long)dev; + + return hwrng_register(&priv->rng); +} + +static void talitos_unregister_rng(struct device *dev) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + + hwrng_unregister(&priv->rng); +} + +/* + * crypto alg + */ +#define TALITOS_CRA_PRIORITY 3000 +#define TALITOS_MAX_KEY_SIZE 64 +#define TALITOS_MAX_AUTH_SIZE 20 +#define TALITOS_AES_MIN_BLOCK_SIZE 16 +#define TALITOS_AES_IV_LENGTH 16 + +struct talitos_ctx { + struct device *dev; + __be32 desc_hdr_template; + u8 key[TALITOS_MAX_KEY_SIZE]; + u8 iv[TALITOS_AES_IV_LENGTH]; + unsigned int keylen; + unsigned int enckeylen; + unsigned int authkeylen; + unsigned int authsize; +}; + +static int aes_cbc_sha1_hmac_authenc_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) +{ + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + + ctx->authsize = authsize; + + return 0; +} + +static int aes_cbc_sha1_hmac_authenc_setkey(struct crypto_aead *authenc, + const u8 *key, unsigned int keylen) +{ + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + struct rtattr *rta = (void *)key; + struct crypto_authenc_key_param *param; + unsigned int authkeylen; + unsigned int enckeylen; + + if (!RTA_OK(rta, keylen)) + goto badkey; + + if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) + goto badkey; + + if (RTA_PAYLOAD(rta) < sizeof(*param)) + goto badkey; + + param = RTA_DATA(rta); + enckeylen = be32_to_cpu(param->enckeylen); + + key += RTA_ALIGN(rta->rta_len); + keylen -= RTA_ALIGN(rta->rta_len); + + if (keylen < enckeylen) + goto badkey; + + authkeylen = keylen - enckeylen; + + if (keylen > TALITOS_MAX_KEY_SIZE) + goto badkey; + + memcpy(&ctx->key, key, keylen); + + ctx->keylen = keylen; + ctx->enckeylen = enckeylen; + ctx->authkeylen = authkeylen; + + return 0; + +badkey: + crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; +} + +/* + * ipsec_esp_edesc - s/w-extended ipsec_esp descriptor + * @src_nents: number of segments in input scatterlist + * @dst_nents: number of segments in output scatterlist + * @dma_len: length of dma mapped link_tbl space + * @dma_link_tbl: bus physical address of link_tbl + * @desc: h/w descriptor + * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) + * + * if decrypting (with authcheck), or either one of src_nents or dst_nents + * is greater than 1, an integrity check value is concatenated to the end + * of link_tbl data + */ +struct ipsec_esp_edesc { + int src_nents; + int dst_nents; + int dma_len; + dma_addr_t dma_link_tbl; + struct talitos_desc desc; + struct talitos_ptr link_tbl[0]; +}; + +static void ipsec_esp_unmap(struct device *dev, + struct ipsec_esp_edesc *edesc, + struct aead_request *areq) +{ + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[6], DMA_FROM_DEVICE); + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[3], DMA_TO_DEVICE); + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE); + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[0], DMA_TO_DEVICE); + + dma_unmap_sg(dev, areq->assoc, 1, DMA_TO_DEVICE); + + if (areq->src != areq->dst) { + dma_unmap_sg(dev, areq->src, edesc->src_nents ? : 1, + DMA_TO_DEVICE); + dma_unmap_sg(dev, areq->dst, edesc->dst_nents ? : 1, + DMA_FROM_DEVICE); + } else { + dma_unmap_sg(dev, areq->src, edesc->src_nents ? : 1, + DMA_BIDIRECTIONAL); + } + + if (edesc->dma_len) + dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len, + DMA_BIDIRECTIONAL); +} + +/* + * ipsec_esp descriptor callbacks + */ +static void ipsec_esp_encrypt_done(struct device *dev, + struct talitos_desc *desc, void *context, + int err) +{ + struct aead_request *areq = context; + struct ipsec_esp_edesc *edesc = + container_of(desc, struct ipsec_esp_edesc, desc); + struct crypto_aead *authenc = crypto_aead_reqtfm(areq); + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + struct scatterlist *sg; + void *icvdata; + + ipsec_esp_unmap(dev, edesc, areq); + + /* copy the generated ICV to dst */ + if (edesc->dma_len) { + icvdata = &edesc->link_tbl[edesc->src_nents + + edesc->dst_nents + 1]; + sg = sg_last(areq->dst, edesc->dst_nents); + memcpy((char *)sg_virt(sg) + sg->length - ctx->authsize, + icvdata, ctx->authsize); + } + + kfree(edesc); + + aead_request_complete(areq, err); +} + +static void ipsec_esp_decrypt_done(struct device *dev, + struct talitos_desc *desc, void *context, + int err) +{ + struct aead_request *req = context; + struct ipsec_esp_edesc *edesc = + container_of(desc, struct ipsec_esp_edesc, desc); + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + struct scatterlist *sg; + void *icvdata; + + ipsec_esp_unmap(dev, edesc, req); + + if (!err) { + /* auth check */ + if (edesc->dma_len) + icvdata = &edesc->link_tbl[edesc->src_nents + + edesc->dst_nents + 1]; + else + icvdata = &edesc->link_tbl[0]; + + sg = sg_last(req->dst, edesc->dst_nents ? : 1); + err = memcmp(icvdata, (char *)sg_virt(sg) + sg->length - + ctx->authsize, ctx->authsize) ? -EBADMSG : 0; + } + + kfree(edesc); + + aead_request_complete(req, err); +} + +/* + * convert scatterlist to SEC h/w link table format + * stop at cryptlen bytes + */ +static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, + int cryptlen, struct talitos_ptr *link_tbl_ptr) +{ + while (cryptlen > 0) { + link_tbl_ptr->ptr = cpu_to_be32(sg_dma_address(sg)); + link_tbl_ptr->len = cpu_to_be16(sg_dma_len(sg)); + link_tbl_ptr->j_extent = 0; + link_tbl_ptr++; + cryptlen -= sg_dma_len(sg); + sg = sg_next(sg); + } + + /* adjust (decrease) last entry's len to cryptlen */ + link_tbl_ptr--; + link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len) + + cryptlen); + + /* tag end of link table */ + link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; +} + +/* + * fill in and submit ipsec_esp descriptor + */ +static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, + u8 *giv, u64 seq, + void (*callback) (struct device *dev, + struct talitos_desc *desc, + void *context, int error)) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + struct talitos_ctx *ctx = crypto_aead_ctx(aead); + struct device *dev = ctx->dev; + struct talitos_desc *desc = &edesc->desc; + unsigned int cryptlen = areq->cryptlen; + unsigned int authsize = ctx->authsize; + unsigned int ivsize; + int sg_count; + + /* hmac key */ + map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key, + 0, DMA_TO_DEVICE); + /* hmac data */ + map_single_talitos_ptr(dev, &desc->ptr[1], sg_virt(areq->src) - + sg_virt(areq->assoc), sg_virt(areq->assoc), 0, + DMA_TO_DEVICE); + /* cipher iv */ + ivsize = crypto_aead_ivsize(aead); + map_single_talitos_ptr(dev, &desc->ptr[2], ivsize, giv ?: areq->iv, 0, + DMA_TO_DEVICE); + + /* cipher key */ + map_single_talitos_ptr(dev, &desc->ptr[3], ctx->enckeylen, + (char *)&ctx->key + ctx->authkeylen, 0, + DMA_TO_DEVICE); + + /* + * cipher in + * map and adjust cipher len to aead request cryptlen. + * extent is bytes of HMAC postpended to ciphertext, + * typically 12 for ipsec + */ + desc->ptr[4].len = cpu_to_be16(cryptlen); + desc->ptr[4].j_extent = authsize; + + if (areq->src == areq->dst) + sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ? : 1, + DMA_BIDIRECTIONAL); + else + sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ? : 1, + DMA_TO_DEVICE); + + if (sg_count == 1) { + desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); + } else { + sg_to_link_tbl(areq->src, sg_count, cryptlen, + &edesc->link_tbl[0]); + desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; + desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); + dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, + edesc->dma_len, DMA_BIDIRECTIONAL); + } + + /* cipher out */ + desc->ptr[5].len = cpu_to_be16(cryptlen); + desc->ptr[5].j_extent = authsize; + + if (areq->src != areq->dst) { + sg_count = dma_map_sg(dev, areq->dst, edesc->dst_nents ? : 1, + DMA_FROM_DEVICE); + } + + if (sg_count == 1) { + desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst)); + } else { + struct talitos_ptr *link_tbl_ptr = + &edesc->link_tbl[edesc->src_nents]; + struct scatterlist *sg; + + desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *) + edesc->dma_link_tbl + + edesc->src_nents); + if (areq->src == areq->dst) { + memcpy(link_tbl_ptr, &edesc->link_tbl[0], + edesc->src_nents * sizeof(struct talitos_ptr)); + } else { + sg_to_link_tbl(areq->dst, sg_count, cryptlen, + link_tbl_ptr); + } + link_tbl_ptr += sg_count - 1; + + /* handle case where sg_last contains the ICV exclusively */ + sg = sg_last(areq->dst, edesc->dst_nents); + if (sg->length == ctx->authsize) + link_tbl_ptr--; + + link_tbl_ptr->j_extent = 0; + link_tbl_ptr++; + link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; + link_tbl_ptr->len = cpu_to_be16(authsize); + + /* icv data follows link tables */ + link_tbl_ptr->ptr = cpu_to_be32((struct talitos_ptr *) + edesc->dma_link_tbl + + edesc->src_nents + + edesc->dst_nents + 1); + + desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP; + dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, + edesc->dma_len, DMA_BIDIRECTIONAL); + } + + /* iv out */ + map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0, + DMA_FROM_DEVICE); + + return talitos_submit(dev, desc, callback, areq); +} + + +/* + * derive number of elements in scatterlist + */ +static int sg_count(struct scatterlist *sg_list, int nbytes) +{ + struct scatterlist *sg = sg_list; + int sg_nents = 0; + + while (nbytes) { + sg_nents++; + nbytes -= sg->length; + sg = sg_next(sg); + } + + return sg_nents; +} + +/* + * allocate and map the ipsec_esp extended descriptor + */ +static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, + int icv_stashing) +{ + struct crypto_aead *authenc = crypto_aead_reqtfm(areq); + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + struct ipsec_esp_edesc *edesc; + int src_nents, dst_nents, alloc_len, dma_len; + + if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) { + dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n"); + return ERR_PTR(-EINVAL); + } + + src_nents = sg_count(areq->src, areq->cryptlen + ctx->authsize); + src_nents = (src_nents == 1) ? 0 : src_nents; + + if (areq->dst == areq->src) { + dst_nents = src_nents; + } else { + dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize); + dst_nents = (dst_nents == 1) ? 0 : src_nents; + } + + /* + * allocate space for base edesc plus the link tables, + * allowing for a separate entry for the generated ICV (+ 1), + * and the ICV data itself + */ + alloc_len = sizeof(struct ipsec_esp_edesc); + if (src_nents || dst_nents) { + dma_len = (src_nents + dst_nents + 1) * + sizeof(struct talitos_ptr) + ctx->authsize; + alloc_len += dma_len; + } else { + dma_len = 0; + alloc_len += icv_stashing ? ctx->authsize : 0; + } + + edesc = kmalloc(alloc_len, GFP_DMA); + if (!edesc) { + dev_err(ctx->dev, "could not allocate edescriptor\n"); + return ERR_PTR(-ENOMEM); + } + + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; + edesc->dma_len = dma_len; + edesc->dma_link_tbl = dma_map_single(ctx->dev, &edesc->link_tbl[0], + edesc->dma_len, DMA_BIDIRECTIONAL); + + return edesc; +} + +static int aes_cbc_sha1_hmac_authenc_encrypt(struct aead_request *req) +{ + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + struct ipsec_esp_edesc *edesc; + + /* allocate extended descriptor */ + edesc = ipsec_esp_edesc_alloc(req, 0); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + /* set encrypt */ + edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_AESU_ENC; + + return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); +} + +static int aes_cbc_sha1_hmac_authenc_decrypt(struct aead_request *req) +{ + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + unsigned int authsize = ctx->authsize; + struct ipsec_esp_edesc *edesc; + struct scatterlist *sg; + void *icvdata; + + req->cryptlen -= authsize; + + /* allocate extended descriptor */ + edesc = ipsec_esp_edesc_alloc(req, 1); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + /* stash incoming ICV for later cmp with ICV generated by the h/w */ + if (edesc->dma_len) + icvdata = &edesc->link_tbl[edesc->src_nents + + edesc->dst_nents + 1]; + else + icvdata = &edesc->link_tbl[0]; + + sg = sg_last(req->src, edesc->src_nents ? : 1); + + memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize, + ctx->authsize); + + /* decrypt */ + edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; + + return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_done); +} + +static int aes_cbc_sha1_hmac_authenc_givencrypt( + struct aead_givcrypt_request *req) +{ + struct aead_request *areq = &req->areq; + struct crypto_aead *authenc = crypto_aead_reqtfm(areq); + struct talitos_ctx *ctx = crypto_aead_ctx(authenc); + struct ipsec_esp_edesc *edesc; + + /* allocate extended descriptor */ + edesc = ipsec_esp_edesc_alloc(areq, 0); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + /* set encrypt */ + edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_AESU_ENC; + + memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); + + return ipsec_esp(edesc, areq, req->giv, req->seq, + ipsec_esp_encrypt_done); +} + +struct talitos_alg_template { + char name[CRYPTO_MAX_ALG_NAME]; + char driver_name[CRYPTO_MAX_ALG_NAME]; + unsigned int blocksize; + struct aead_alg aead; + struct device *dev; + __be32 desc_hdr_template; +}; + +static struct talitos_alg_template driver_algs[] = { + /* single-pass ipsec_esp descriptor */ + { + .name = "authenc(hmac(sha1),cbc(aes))", + .driver_name = "authenc(hmac(sha1-talitos),cbc(aes-talitos))", + .blocksize = TALITOS_AES_MIN_BLOCK_SIZE, + .aead = { + .setkey = aes_cbc_sha1_hmac_authenc_setkey, + .setauthsize = aes_cbc_sha1_hmac_authenc_setauthsize, + .encrypt = aes_cbc_sha1_hmac_authenc_encrypt, + .decrypt = aes_cbc_sha1_hmac_authenc_decrypt, + .givencrypt = aes_cbc_sha1_hmac_authenc_givencrypt, + .geniv = "", + .ivsize = TALITOS_AES_IV_LENGTH, + .maxauthsize = TALITOS_MAX_AUTH_SIZE, + }, + .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | + DESC_HDR_SEL0_AESU | + DESC_HDR_MODE0_AESU_CBC | + DESC_HDR_SEL1_MDEUA | + DESC_HDR_MODE1_MDEU_INIT | + DESC_HDR_MODE1_MDEU_PAD | + DESC_HDR_MODE1_MDEU_SHA1_HMAC, + } +}; + +struct talitos_crypto_alg { + struct list_head entry; + struct device *dev; + __be32 desc_hdr_template; + struct crypto_alg crypto_alg; +}; + +static int talitos_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + struct talitos_crypto_alg *talitos_alg = + container_of(alg, struct talitos_crypto_alg, crypto_alg); + struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); + + /* update context with ptr to dev */ + ctx->dev = talitos_alg->dev; + /* copy descriptor header template value */ + ctx->desc_hdr_template = talitos_alg->desc_hdr_template; + + /* random first IV */ + get_random_bytes(ctx->iv, TALITOS_AES_IV_LENGTH); + + return 0; +} + +/* + * given the alg's descriptor header template, determine whether descriptor + * type and primary/secondary execution units required match the hw + * capabilities description provided in the device tree node. + */ +static int hw_supports(struct device *dev, __be32 desc_hdr_template) +{ + struct talitos_private *priv = dev_get_drvdata(dev); + int ret; + + ret = (1 << DESC_TYPE(desc_hdr_template) & priv->desc_types) && + (1 << PRIMARY_EU(desc_hdr_template) & priv->exec_units); + + if (SECONDARY_EU(desc_hdr_template)) + ret = ret && (1 << SECONDARY_EU(desc_hdr_template) + & priv->exec_units); + + return ret; +} + +static int __devexit talitos_remove(struct of_device *ofdev) +{ + struct device *dev = &ofdev->dev; + struct talitos_private *priv = dev_get_drvdata(dev); + struct talitos_crypto_alg *t_alg, *n; + int i; + + list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) { + crypto_unregister_alg(&t_alg->crypto_alg); + list_del(&t_alg->entry); + kfree(t_alg); + } + + if (hw_supports(dev, DESC_HDR_SEL0_RNG)) + talitos_unregister_rng(dev); + + kfree(priv->tail); + kfree(priv->head); + + if (priv->fifo) + for (i = 0; i < priv->num_channels; i++) + kfree(priv->fifo[i]); + + kfree(priv->fifo); + kfree(priv->head_lock); + kfree(priv->tail_lock); + + if (priv->irq != NO_IRQ) { + free_irq(priv->irq, dev); + irq_dispose_mapping(priv->irq); + } + + tasklet_kill(&priv->done_task); + tasklet_kill(&priv->error_task); + + iounmap(priv->reg); + + dev_set_drvdata(dev, NULL); + + kfree(priv); + + return 0; +} + +static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, + struct talitos_alg_template + *template) +{ + struct talitos_crypto_alg *t_alg; + struct crypto_alg *alg; + + t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL); + if (!t_alg) + return ERR_PTR(-ENOMEM); + + alg = &t_alg->crypto_alg; + + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + alg->cra_module = THIS_MODULE; + alg->cra_init = talitos_cra_init; + alg->cra_priority = TALITOS_CRA_PRIORITY; + alg->cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC; + alg->cra_blocksize = template->blocksize; + alg->cra_alignmask = 0; + alg->cra_type = &crypto_aead_type; + alg->cra_ctxsize = sizeof(struct talitos_ctx); + alg->cra_u.aead = template->aead; + + t_alg->desc_hdr_template = template->desc_hdr_template; + t_alg->dev = dev; + + return t_alg; +} + +static int talitos_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device *dev = &ofdev->dev; + struct device_node *np = ofdev->node; + struct talitos_private *priv; + const unsigned int *prop; + int i, err; + + priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + + priv->ofdev = ofdev; + + tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev); + tasklet_init(&priv->error_task, talitos_error, (unsigned long)dev); + + priv->irq = irq_of_parse_and_map(np, 0); + + if (priv->irq == NO_IRQ) { + dev_err(dev, "failed to map irq\n"); + err = -EINVAL; + goto err_out; + } + + /* get the irq line */ + err = request_irq(priv->irq, talitos_interrupt, 0, + dev_driver_string(dev), dev); + if (err) { + dev_err(dev, "failed to request irq %d\n", priv->irq); + irq_dispose_mapping(priv->irq); + priv->irq = NO_IRQ; + goto err_out; + } + + priv->reg = of_iomap(np, 0); + if (!priv->reg) { + dev_err(dev, "failed to of_iomap\n"); + err = -ENOMEM; + goto err_out; + } + + /* get SEC version capabilities from device tree */ + prop = of_get_property(np, "fsl,num-channels", NULL); + if (prop) + priv->num_channels = *prop; + + prop = of_get_property(np, "fsl,channel-fifo-len", NULL); + if (prop) + priv->chfifo_len = *prop; + + prop = of_get_property(np, "fsl,exec-units-mask", NULL); + if (prop) + priv->exec_units = *prop; + + prop = of_get_property(np, "fsl,descriptor-types-mask", NULL); + if (prop) + priv->desc_types = *prop; + + if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len || + !priv->exec_units || !priv->desc_types) { + dev_err(dev, "invalid property data in device tree node\n"); + err = -EINVAL; + goto err_out; + } + + of_node_put(np); + np = NULL; + + priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, + GFP_KERNEL); + priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, + GFP_KERNEL); + if (!priv->head_lock || !priv->tail_lock) { + dev_err(dev, "failed to allocate fifo locks\n"); + err = -ENOMEM; + goto err_out; + } + + for (i = 0; i < priv->num_channels; i++) { + spin_lock_init(&priv->head_lock[i]); + spin_lock_init(&priv->tail_lock[i]); + } + + priv->fifo = kmalloc(sizeof(struct talitos_request *) * + priv->num_channels, GFP_KERNEL); + if (!priv->fifo) { + dev_err(dev, "failed to allocate request fifo\n"); + err = -ENOMEM; + goto err_out; + } + + priv->fifo_len = roundup_pow_of_two(priv->chfifo_len); + + for (i = 0; i < priv->num_channels; i++) { + priv->fifo[i] = kzalloc(sizeof(struct talitos_request) * + priv->fifo_len, GFP_KERNEL); + if (!priv->fifo[i]) { + dev_err(dev, "failed to allocate request fifo %d\n", i); + err = -ENOMEM; + goto err_out; + } + } + + priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); + priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); + if (!priv->head || !priv->tail) { + dev_err(dev, "failed to allocate request index space\n"); + err = -ENOMEM; + goto err_out; + } + + /* reset and initialize the h/w */ + err = init_device(dev); + if (err) { + dev_err(dev, "failed to initialize device\n"); + goto err_out; + } + + /* register the RNG, if available */ + if (hw_supports(dev, DESC_HDR_SEL0_RNG)) { + err = talitos_register_rng(dev); + if (err) { + dev_err(dev, "failed to register hwrng: %d\n", err); + goto err_out; + } else + dev_info(dev, "hwrng\n"); + } + + /* register crypto algorithms the device supports */ + INIT_LIST_HEAD(&priv->alg_list); + + for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { + if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { + struct talitos_crypto_alg *t_alg; + + t_alg = talitos_alg_alloc(dev, &driver_algs[i]); + if (IS_ERR(t_alg)) { + err = PTR_ERR(t_alg); + goto err_out; + } + + err = crypto_register_alg(&t_alg->crypto_alg); + if (err) { + dev_err(dev, "%s alg registration failed\n", + t_alg->crypto_alg.cra_driver_name); + kfree(t_alg); + } else { + list_add_tail(&t_alg->entry, &priv->alg_list); + dev_info(dev, "%s\n", + t_alg->crypto_alg.cra_driver_name); + } + } + } + + return 0; + +err_out: + talitos_remove(ofdev); + if (np) + of_node_put(np); + + return err; +} + +static struct of_device_id talitos_match[] = { + { + .compatible = "fsl,sec2.0", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, talitos_match); + +static struct of_platform_driver talitos_driver = { + .name = "talitos", + .match_table = talitos_match, + .probe = talitos_probe, + .remove = __devexit_p(talitos_remove), +}; + +static int __init talitos_init(void) +{ + return of_register_platform_driver(&talitos_driver); +} +module_init(talitos_init); + +static void __exit talitos_exit(void) +{ + of_unregister_platform_driver(&talitos_driver); +} +module_exit(talitos_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kim Phillips "); +MODULE_DESCRIPTION("Freescale integrated security engine (SEC) driver"); diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h new file mode 100644 index 0000000..de0e377 --- /dev/null +++ b/drivers/crypto/talitos.h @@ -0,0 +1,200 @@ +/* + * Freescale SEC (talitos) device register and descriptor header defines + * + * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. + * + * 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. + * + * 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. + * + */ + +/* + * TALITOS_xxx_LO addresses point to the low data bits (32-63) of the register + */ + +/* global register offset addresses */ +#define TALITOS_MCR 0x1030 /* master control register */ +#define TALITOS_MCR_LO 0x1038 +#define TALITOS_MCR_SWR 0x1 /* s/w reset */ +#define TALITOS_IMR 0x1008 /* interrupt mask register */ +#define TALITOS_IMR_INIT 0x10fff /* enable channel IRQs */ +#define TALITOS_IMR_LO 0x100C +#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */ +#define TALITOS_ISR 0x1010 /* interrupt status register */ +#define TALITOS_ISR_CHERR 0xaa /* channel errors mask */ +#define TALITOS_ISR_CHDONE 0x55 /* channel done mask */ +#define TALITOS_ISR_LO 0x1014 +#define TALITOS_ICR 0x1018 /* interrupt clear register */ +#define TALITOS_ICR_LO 0x101C + +/* channel register address stride */ +#define TALITOS_CH_STRIDE 0x100 + +/* channel configuration register */ +#define TALITOS_CCCR(ch) (ch * TALITOS_CH_STRIDE + 0x1108) +#define TALITOS_CCCR_CONT 0x2 /* channel continue */ +#define TALITOS_CCCR_RESET 0x1 /* channel reset */ +#define TALITOS_CCCR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x110c) +#define TALITOS_CCCR_LO_CDWE 0x10 /* chan. done writeback enab. */ +#define TALITOS_CCCR_LO_NT 0x4 /* notification type */ +#define TALITOS_CCCR_LO_CDIE 0x2 /* channel done IRQ enable */ + +/* CCPSR: channel pointer status register */ +#define TALITOS_CCPSR(ch) (ch * TALITOS_CH_STRIDE + 0x1110) +#define TALITOS_CCPSR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x1114) +#define TALITOS_CCPSR_LO_DOF 0x8000 /* double FF write oflow error */ +#define TALITOS_CCPSR_LO_SOF 0x4000 /* single FF write oflow error */ +#define TALITOS_CCPSR_LO_MDTE 0x2000 /* master data transfer error */ +#define TALITOS_CCPSR_LO_SGDLZ 0x1000 /* s/g data len zero error */ +#define TALITOS_CCPSR_LO_FPZ 0x0800 /* fetch ptr zero error */ +#define TALITOS_CCPSR_LO_IDH 0x0400 /* illegal desc hdr error */ +#define TALITOS_CCPSR_LO_IEU 0x0200 /* invalid EU error */ +#define TALITOS_CCPSR_LO_EU 0x0100 /* EU error detected */ +#define TALITOS_CCPSR_LO_GB 0x0080 /* gather boundary error */ +#define TALITOS_CCPSR_LO_GRL 0x0040 /* gather return/length error */ +#define TALITOS_CCPSR_LO_SB 0x0020 /* scatter boundary error */ +#define TALITOS_CCPSR_LO_SRL 0x0010 /* scatter return/length error */ + +/* channel fetch fifo register */ +#define TALITOS_FF(ch) (ch * TALITOS_CH_STRIDE + 0x1148) +#define TALITOS_FF_LO(ch) (ch * TALITOS_CH_STRIDE + 0x114c) + +/* current descriptor pointer register */ +#define TALITOS_CDPR(ch) (ch * TALITOS_CH_STRIDE + 0x1140) +#define TALITOS_CDPR_LO(ch) (ch * TALITOS_CH_STRIDE + 0x1144) + +/* descriptor buffer register */ +#define TALITOS_DESCBUF(ch) (ch * TALITOS_CH_STRIDE + 0x1180) +#define TALITOS_DESCBUF_LO(ch) (ch * TALITOS_CH_STRIDE + 0x1184) + +/* gather link table */ +#define TALITOS_GATHER(ch) (ch * TALITOS_CH_STRIDE + 0x11c0) +#define TALITOS_GATHER_LO(ch) (ch * TALITOS_CH_STRIDE + 0x11c4) + +/* scatter link table */ +#define TALITOS_SCATTER(ch) (ch * TALITOS_CH_STRIDE + 0x11e0) +#define TALITOS_SCATTER_LO(ch) (ch * TALITOS_CH_STRIDE + 0x11e4) + +/* execution unit interrupt status registers */ +#define TALITOS_DEUISR 0x2030 /* DES unit */ +#define TALITOS_DEUISR_LO 0x2034 +#define TALITOS_AESUISR 0x4030 /* AES unit */ +#define TALITOS_AESUISR_LO 0x4034 +#define TALITOS_MDEUISR 0x6030 /* message digest unit */ +#define TALITOS_MDEUISR_LO 0x6034 +#define TALITOS_AFEUISR 0x8030 /* arc4 unit */ +#define TALITOS_AFEUISR_LO 0x8034 +#define TALITOS_RNGUISR 0xa030 /* random number unit */ +#define TALITOS_RNGUISR_LO 0xa034 +#define TALITOS_RNGUSR 0xa028 /* rng status */ +#define TALITOS_RNGUSR_LO 0xa02c +#define TALITOS_RNGUSR_LO_RD 0x1 /* reset done */ +#define TALITOS_RNGUSR_LO_OFL 0xff0000/* output FIFO length */ +#define TALITOS_RNGUDSR 0xa010 /* data size */ +#define TALITOS_RNGUDSR_LO 0xa014 +#define TALITOS_RNGU_FIFO 0xa800 /* output FIFO */ +#define TALITOS_RNGU_FIFO_LO 0xa804 /* output FIFO */ +#define TALITOS_RNGURCR 0xa018 /* reset control */ +#define TALITOS_RNGURCR_LO 0xa01c +#define TALITOS_RNGURCR_LO_SR 0x1 /* software reset */ +#define TALITOS_PKEUISR 0xc030 /* public key unit */ +#define TALITOS_PKEUISR_LO 0xc034 +#define TALITOS_KEUISR 0xe030 /* kasumi unit */ +#define TALITOS_KEUISR_LO 0xe034 +#define TALITOS_CRCUISR 0xf030 /* cyclic redundancy check unit*/ +#define TALITOS_CRCUISR_LO 0xf034 + +/* + * talitos descriptor header (hdr) bits + */ + +/* written back when done */ +#define DESC_HDR_DONE __constant_cpu_to_be32(0xff000000) + +/* primary execution unit select */ +#define DESC_HDR_SEL0_MASK __constant_cpu_to_be32(0xf0000000) +#define DESC_HDR_SEL0_AFEU __constant_cpu_to_be32(0x10000000) +#define DESC_HDR_SEL0_DEU __constant_cpu_to_be32(0x20000000) +#define DESC_HDR_SEL0_MDEUA __constant_cpu_to_be32(0x30000000) +#define DESC_HDR_SEL0_MDEUB __constant_cpu_to_be32(0xb0000000) +#define DESC_HDR_SEL0_RNG __constant_cpu_to_be32(0x40000000) +#define DESC_HDR_SEL0_PKEU __constant_cpu_to_be32(0x50000000) +#define DESC_HDR_SEL0_AESU __constant_cpu_to_be32(0x60000000) +#define DESC_HDR_SEL0_KEU __constant_cpu_to_be32(0x70000000) +#define DESC_HDR_SEL0_CRCU __constant_cpu_to_be32(0x80000000) + +/* primary execution unit mode (MODE0) and derivatives */ +#define DESC_HDR_MODE0_AESU_CBC __constant_cpu_to_be32(0x00200000) +#define DESC_HDR_MODE0_AESU_ENC __constant_cpu_to_be32(0x00100000) +#define DESC_HDR_MODE0_DEU_CBC __constant_cpu_to_be32(0x00400000) +#define DESC_HDR_MODE0_DEU_3DES __constant_cpu_to_be32(0x00200000) +#define DESC_HDR_MODE0_DEU_ENC __constant_cpu_to_be32(0x00100000) +#define DESC_HDR_MODE0_MDEU_INIT __constant_cpu_to_be32(0x01000000) +#define DESC_HDR_MODE0_MDEU_HMAC __constant_cpu_to_be32(0x00800000) +#define DESC_HDR_MODE0_MDEU_PAD __constant_cpu_to_be32(0x00400000) +#define DESC_HDR_MODE0_MDEU_MD5 __constant_cpu_to_be32(0x00200000) +#define DESC_HDR_MODE0_MDEU_SHA256 __constant_cpu_to_be32(0x00100000) +#define DESC_HDR_MODE0_MDEU_SHA1 __constant_cpu_to_be32(0x00000000) +#define DESC_HDR_MODE0_MDEU_MD5_HMAC (DESC_HDR_MODE0_MDEU_MD5 | \ + DESC_HDR_MODE0_MDEU_HMAC) +#define DESC_HDR_MODE0_MDEU_SHA256_HMAC (DESC_HDR_MODE0_MDEU_SHA256 | \ + DESC_HDR_MODE0_MDEU_HMAC) +#define DESC_HDR_MODE0_MDEU_SHA1_HMAC (DESC_HDR_MODE0_MDEU_SHA1 | \ + DESC_HDR_MODE0_MDEU_HMAC) + +/* secondary execution unit select (SEL1) */ +#define DESC_HDR_SEL1_MASK __constant_cpu_to_be32(0x000f0000) +#define DESC_HDR_SEL1_MDEUA __constant_cpu_to_be32(0x00030000) +#define DESC_HDR_SEL1_MDEUB __constant_cpu_to_be32(0x000b0000) +#define DESC_HDR_SEL1_CRCU __constant_cpu_to_be32(0x00080000) + +/* secondary execution unit mode (MODE1) and derivatives */ +#define DESC_HDR_MODE1_MDEU_INIT __constant_cpu_to_be32(0x00001000) +#define DESC_HDR_MODE1_MDEU_HMAC __constant_cpu_to_be32(0x00000800) +#define DESC_HDR_MODE1_MDEU_PAD __constant_cpu_to_be32(0x00000400) +#define DESC_HDR_MODE1_MDEU_MD5 __constant_cpu_to_be32(0x00000200) +#define DESC_HDR_MODE1_MDEU_SHA256 __constant_cpu_to_be32(0x00000100) +#define DESC_HDR_MODE1_MDEU_SHA1 __constant_cpu_to_be32(0x00000000) +#define DESC_HDR_MODE1_MDEU_MD5_HMAC (DESC_HDR_MODE1_MDEU_MD5 | \ + DESC_HDR_MODE1_MDEU_HMAC) +#define DESC_HDR_MODE1_MDEU_SHA256_HMAC (DESC_HDR_MODE1_MDEU_SHA256 | \ + DESC_HDR_MODE1_MDEU_HMAC) +#define DESC_HDR_MODE1_MDEU_SHA1_HMAC (DESC_HDR_MODE1_MDEU_SHA1 | \ + DESC_HDR_MODE1_MDEU_HMAC) + +/* direction of overall data flow (DIR) */ +#define DESC_HDR_DIR_INBOUND __constant_cpu_to_be32(0x00000002) + +/* request done notification (DN) */ +#define DESC_HDR_DONE_NOTIFY __constant_cpu_to_be32(0x00000001) + +/* descriptor types */ +#define DESC_HDR_TYPE_AESU_CTR_NONSNOOP __constant_cpu_to_be32(0 << 3) +#define DESC_HDR_TYPE_IPSEC_ESP __constant_cpu_to_be32(1 << 3) +#define DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU __constant_cpu_to_be32(2 << 3) +#define DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU __constant_cpu_to_be32(4 << 3) + +/* link table extent field bits */ +#define DESC_PTR_LNKTBL_JUMP 0x80 +#define DESC_PTR_LNKTBL_RETURN 0x02 +#define DESC_PTR_LNKTBL_NEXT 0x01 -- cgit v0.10.2 From 81bef0150074d677d8cbd4e971a8ce6c9746a1fc Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Wed, 25 Jun 2008 14:38:47 +0800 Subject: crypto: ixp4xx - Hardware crypto support for IXP4xx CPUs Add support for the hardware crypto engine provided by the NPE C of the Intel IXP4xx networking processor series. Supported ciphers: des, des3, aes and a combination of them with md5 and sha1 hmac Signed-off-by: Christian Hohnstaedt Signed-off-by: Herbert Xu diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 249c135..eb2ec2e 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -190,4 +190,13 @@ config CRYPTO_DEV_TALITOS To compile this driver as a module, choose M here: the module will be called talitos. +config CRYPTO_DEV_IXP4XX + tristate "Driver for IXP4xx crypto hardware acceleration" + depends on ARCH_IXP4XX + select CRYPTO_DES + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + help + Driver for the IXP4xx NPE crypto engine. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index d29d2cd..73557b2 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o +obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c new file mode 100644 index 0000000..42a107f --- /dev/null +++ b/drivers/crypto/ixp4xx_crypto.c @@ -0,0 +1,1506 @@ +/* + * Intel IXP4xx NPE-C crypto driver + * + * Copyright (C) 2008 Christian Hohnstaedt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MAX_KEYLEN 32 + +/* hash: cfgword + 2 * digestlen; crypt: keylen + cfgword */ +#define NPE_CTX_LEN 80 +#define AES_BLOCK128 16 + +#define NPE_OP_HASH_VERIFY 0x01 +#define NPE_OP_CCM_ENABLE 0x04 +#define NPE_OP_CRYPT_ENABLE 0x08 +#define NPE_OP_HASH_ENABLE 0x10 +#define NPE_OP_NOT_IN_PLACE 0x20 +#define NPE_OP_HMAC_DISABLE 0x40 +#define NPE_OP_CRYPT_ENCRYPT 0x80 + +#define NPE_OP_CCM_GEN_MIC 0xcc +#define NPE_OP_HASH_GEN_ICV 0x50 +#define NPE_OP_ENC_GEN_KEY 0xc9 + +#define MOD_ECB 0x0000 +#define MOD_CTR 0x1000 +#define MOD_CBC_ENC 0x2000 +#define MOD_CBC_DEC 0x3000 +#define MOD_CCM_ENC 0x4000 +#define MOD_CCM_DEC 0x5000 + +#define KEYLEN_128 4 +#define KEYLEN_192 6 +#define KEYLEN_256 8 + +#define CIPH_DECR 0x0000 +#define CIPH_ENCR 0x0400 + +#define MOD_DES 0x0000 +#define MOD_TDEA2 0x0100 +#define MOD_3DES 0x0200 +#define MOD_AES 0x0800 +#define MOD_AES128 (0x0800 | KEYLEN_128) +#define MOD_AES192 (0x0900 | KEYLEN_192) +#define MOD_AES256 (0x0a00 | KEYLEN_256) + +#define MAX_IVLEN 16 +#define NPE_ID 2 /* NPE C */ +#define NPE_QLEN 16 +/* Space for registering when the first + * NPE_QLEN crypt_ctl are busy */ +#define NPE_QLEN_TOTAL 64 + +#define SEND_QID 29 +#define RECV_QID 30 + +#define CTL_FLAG_UNUSED 0x0000 +#define CTL_FLAG_USED 0x1000 +#define CTL_FLAG_PERFORM_ABLK 0x0001 +#define CTL_FLAG_GEN_ICV 0x0002 +#define CTL_FLAG_GEN_REVAES 0x0004 +#define CTL_FLAG_PERFORM_AEAD 0x0008 +#define CTL_FLAG_MASK 0x000f + +#define HMAC_IPAD_VALUE 0x36 +#define HMAC_OPAD_VALUE 0x5C +#define HMAC_PAD_BLOCKLEN SHA1_BLOCK_SIZE + +#define MD5_DIGEST_SIZE 16 + +struct buffer_desc { + u32 phys_next; + u16 buf_len; + u16 pkt_len; + u32 phys_addr; + u32 __reserved[4]; + struct buffer_desc *next; +}; + +struct crypt_ctl { + u8 mode; /* NPE_OP_* operation mode */ + u8 init_len; + u16 reserved; + u8 iv[MAX_IVLEN]; /* IV for CBC mode or CTR IV for CTR mode */ + u32 icv_rev_aes; /* icv or rev aes */ + u32 src_buf; + u32 dst_buf; + u16 auth_offs; /* Authentication start offset */ + u16 auth_len; /* Authentication data length */ + u16 crypt_offs; /* Cryption start offset */ + u16 crypt_len; /* Cryption data length */ + u32 aadAddr; /* Additional Auth Data Addr for CCM mode */ + u32 crypto_ctx; /* NPE Crypto Param structure address */ + + /* Used by Host: 4*4 bytes*/ + unsigned ctl_flags; + union { + struct ablkcipher_request *ablk_req; + struct aead_request *aead_req; + struct crypto_tfm *tfm; + } data; + struct buffer_desc *regist_buf; + u8 *regist_ptr; +}; + +struct ablk_ctx { + struct buffer_desc *src; + struct buffer_desc *dst; + unsigned src_nents; + unsigned dst_nents; +}; + +struct aead_ctx { + struct buffer_desc *buffer; + unsigned short assoc_nents; + unsigned short src_nents; + struct scatterlist ivlist; + /* used when the hmac is not on one sg entry */ + u8 *hmac_virt; + int encrypt; +}; + +struct ix_hash_algo { + u32 cfgword; + unsigned char *icv; +}; + +struct ix_sa_dir { + unsigned char *npe_ctx; + dma_addr_t npe_ctx_phys; + int npe_ctx_idx; + u8 npe_mode; +}; + +struct ixp_ctx { + struct ix_sa_dir encrypt; + struct ix_sa_dir decrypt; + int authkey_len; + u8 authkey[MAX_KEYLEN]; + int enckey_len; + u8 enckey[MAX_KEYLEN]; + u8 salt[MAX_IVLEN]; + u8 nonce[CTR_RFC3686_NONCE_SIZE]; + unsigned salted; + atomic_t configuring; + struct completion completion; +}; + +struct ixp_alg { + struct crypto_alg crypto; + const struct ix_hash_algo *hash; + u32 cfg_enc; + u32 cfg_dec; + + int registered; +}; + +static const struct ix_hash_algo hash_alg_md5 = { + .cfgword = 0xAA010004, + .icv = "\x01\x23\x45\x67\x89\xAB\xCD\xEF" + "\xFE\xDC\xBA\x98\x76\x54\x32\x10", +}; +static const struct ix_hash_algo hash_alg_sha1 = { + .cfgword = 0x00000005, + .icv = "\x67\x45\x23\x01\xEF\xCD\xAB\x89\x98\xBA" + "\xDC\xFE\x10\x32\x54\x76\xC3\xD2\xE1\xF0", +}; + +static struct npe *npe_c; +static struct dma_pool *buffer_pool = NULL; +static struct dma_pool *ctx_pool = NULL; + +static struct crypt_ctl *crypt_virt = NULL; +static dma_addr_t crypt_phys; + +static int support_aes = 1; + +static void dev_release(struct device *dev) +{ + return; +} + +#define DRIVER_NAME "ixp4xx_crypto" +static struct platform_device pseudo_dev = { + .name = DRIVER_NAME, + .id = 0, + .num_resources = 0, + .dev = { + .coherent_dma_mask = DMA_32BIT_MASK, + .release = dev_release, + } +}; + +static struct device *dev = &pseudo_dev.dev; + +static inline dma_addr_t crypt_virt2phys(struct crypt_ctl *virt) +{ + return crypt_phys + (virt - crypt_virt) * sizeof(struct crypt_ctl); +} + +static inline struct crypt_ctl *crypt_phys2virt(dma_addr_t phys) +{ + return crypt_virt + (phys - crypt_phys) / sizeof(struct crypt_ctl); +} + +static inline u32 cipher_cfg_enc(struct crypto_tfm *tfm) +{ + return container_of(tfm->__crt_alg, struct ixp_alg,crypto)->cfg_enc; +} + +static inline u32 cipher_cfg_dec(struct crypto_tfm *tfm) +{ + return container_of(tfm->__crt_alg, struct ixp_alg,crypto)->cfg_dec; +} + +static inline const struct ix_hash_algo *ix_hash(struct crypto_tfm *tfm) +{ + return container_of(tfm->__crt_alg, struct ixp_alg, crypto)->hash; +} + +static int setup_crypt_desc(void) +{ + BUILD_BUG_ON(sizeof(struct crypt_ctl) != 64); + crypt_virt = dma_alloc_coherent(dev, + NPE_QLEN * sizeof(struct crypt_ctl), + &crypt_phys, GFP_KERNEL); + if (!crypt_virt) + return -ENOMEM; + memset(crypt_virt, 0, NPE_QLEN * sizeof(struct crypt_ctl)); + return 0; +} + +static spinlock_t desc_lock; +static struct crypt_ctl *get_crypt_desc(void) +{ + int i; + static int idx = 0; + unsigned long flags; + + spin_lock_irqsave(&desc_lock, flags); + + if (unlikely(!crypt_virt)) + setup_crypt_desc(); + if (unlikely(!crypt_virt)) { + spin_unlock_irqrestore(&desc_lock, flags); + return NULL; + } + i = idx; + if (crypt_virt[i].ctl_flags == CTL_FLAG_UNUSED) { + if (++idx >= NPE_QLEN) + idx = 0; + crypt_virt[i].ctl_flags = CTL_FLAG_USED; + spin_unlock_irqrestore(&desc_lock, flags); + return crypt_virt +i; + } else { + spin_unlock_irqrestore(&desc_lock, flags); + return NULL; + } +} + +static spinlock_t emerg_lock; +static struct crypt_ctl *get_crypt_desc_emerg(void) +{ + int i; + static int idx = NPE_QLEN; + struct crypt_ctl *desc; + unsigned long flags; + + desc = get_crypt_desc(); + if (desc) + return desc; + if (unlikely(!crypt_virt)) + return NULL; + + spin_lock_irqsave(&emerg_lock, flags); + i = idx; + if (crypt_virt[i].ctl_flags == CTL_FLAG_UNUSED) { + if (++idx >= NPE_QLEN_TOTAL) + idx = NPE_QLEN; + crypt_virt[i].ctl_flags = CTL_FLAG_USED; + spin_unlock_irqrestore(&emerg_lock, flags); + return crypt_virt +i; + } else { + spin_unlock_irqrestore(&emerg_lock, flags); + return NULL; + } +} + +static void free_buf_chain(struct buffer_desc *buf, u32 phys) +{ + while (buf) { + struct buffer_desc *buf1; + u32 phys1; + + buf1 = buf->next; + phys1 = buf->phys_next; + dma_pool_free(buffer_pool, buf, phys); + buf = buf1; + phys = phys1; + } +} + +static struct tasklet_struct crypto_done_tasklet; + +static void finish_scattered_hmac(struct crypt_ctl *crypt) +{ + struct aead_request *req = crypt->data.aead_req; + struct aead_ctx *req_ctx = aead_request_ctx(req); + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + int authsize = crypto_aead_authsize(tfm); + int decryptlen = req->cryptlen - authsize; + + if (req_ctx->encrypt) { + scatterwalk_map_and_copy(req_ctx->hmac_virt, + req->src, decryptlen, authsize, 1); + } + dma_pool_free(buffer_pool, req_ctx->hmac_virt, crypt->icv_rev_aes); +} + +static void one_packet(dma_addr_t phys) +{ + struct crypt_ctl *crypt; + struct ixp_ctx *ctx; + int failed; + enum dma_data_direction src_direction = DMA_BIDIRECTIONAL; + + failed = phys & 0x1 ? -EBADMSG : 0; + phys &= ~0x3; + crypt = crypt_phys2virt(phys); + + switch (crypt->ctl_flags & CTL_FLAG_MASK) { + case CTL_FLAG_PERFORM_AEAD: { + struct aead_request *req = crypt->data.aead_req; + struct aead_ctx *req_ctx = aead_request_ctx(req); + dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, + DMA_TO_DEVICE); + dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL); + dma_unmap_sg(dev, req->src, req_ctx->src_nents, + DMA_BIDIRECTIONAL); + + free_buf_chain(req_ctx->buffer, crypt->src_buf); + if (req_ctx->hmac_virt) { + finish_scattered_hmac(crypt); + } + req->base.complete(&req->base, failed); + break; + } + case CTL_FLAG_PERFORM_ABLK: { + struct ablkcipher_request *req = crypt->data.ablk_req; + struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req); + int nents; + if (req_ctx->dst) { + nents = req_ctx->dst_nents; + dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE); + free_buf_chain(req_ctx->dst, crypt->dst_buf); + src_direction = DMA_TO_DEVICE; + } + nents = req_ctx->src_nents; + dma_unmap_sg(dev, req->src, nents, src_direction); + free_buf_chain(req_ctx->src, crypt->src_buf); + req->base.complete(&req->base, failed); + break; + } + case CTL_FLAG_GEN_ICV: + ctx = crypto_tfm_ctx(crypt->data.tfm); + dma_pool_free(ctx_pool, crypt->regist_ptr, + crypt->regist_buf->phys_addr); + dma_pool_free(buffer_pool, crypt->regist_buf, crypt->src_buf); + if (atomic_dec_and_test(&ctx->configuring)) + complete(&ctx->completion); + break; + case CTL_FLAG_GEN_REVAES: + ctx = crypto_tfm_ctx(crypt->data.tfm); + *(u32*)ctx->decrypt.npe_ctx &= cpu_to_be32(~CIPH_ENCR); + if (atomic_dec_and_test(&ctx->configuring)) + complete(&ctx->completion); + break; + default: + BUG(); + } + crypt->ctl_flags = CTL_FLAG_UNUSED; +} + +static void irqhandler(void *_unused) +{ + tasklet_schedule(&crypto_done_tasklet); +} + +static void crypto_done_action(unsigned long arg) +{ + int i; + + for(i=0; i<4; i++) { + dma_addr_t phys = qmgr_get_entry(RECV_QID); + if (!phys) + return; + one_packet(phys); + } + tasklet_schedule(&crypto_done_tasklet); +} + +static int init_ixp_crypto(void) +{ + int ret = -ENODEV; + + if (! ( ~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH | + IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) { + printk(KERN_ERR "ixp_crypto: No HW crypto available\n"); + return ret; + } + npe_c = npe_request(NPE_ID); + if (!npe_c) + return ret; + + if (!npe_running(npe_c)) { + npe_load_firmware(npe_c, npe_name(npe_c), dev); + } + + /* buffer_pool will also be used to sometimes store the hmac, + * so assure it is large enough + */ + BUILD_BUG_ON(SHA1_DIGEST_SIZE > sizeof(struct buffer_desc)); + buffer_pool = dma_pool_create("buffer", dev, + sizeof(struct buffer_desc), 32, 0); + ret = -ENOMEM; + if (!buffer_pool) { + goto err; + } + ctx_pool = dma_pool_create("context", dev, + NPE_CTX_LEN, 16, 0); + if (!ctx_pool) { + goto err; + } + 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); + if (ret) { + qmgr_release_queue(SEND_QID); + goto err; + } + qmgr_set_irq(RECV_QID, QUEUE_IRQ_SRC_NOT_EMPTY, irqhandler, NULL); + tasklet_init(&crypto_done_tasklet, crypto_done_action, 0); + + qmgr_enable_irq(RECV_QID); + return 0; +err: + if (ctx_pool) + dma_pool_destroy(ctx_pool); + if (buffer_pool) + dma_pool_destroy(buffer_pool); + npe_release(npe_c); + return ret; +} + +static void release_ixp_crypto(void) +{ + qmgr_disable_irq(RECV_QID); + tasklet_kill(&crypto_done_tasklet); + + qmgr_release_queue(SEND_QID); + qmgr_release_queue(RECV_QID); + + dma_pool_destroy(ctx_pool); + dma_pool_destroy(buffer_pool); + + npe_release(npe_c); + + if (crypt_virt) { + dma_free_coherent(dev, + NPE_QLEN_TOTAL * sizeof( struct crypt_ctl), + crypt_virt, crypt_phys); + } + return; +} + +static void reset_sa_dir(struct ix_sa_dir *dir) +{ + memset(dir->npe_ctx, 0, NPE_CTX_LEN); + dir->npe_ctx_idx = 0; + dir->npe_mode = 0; +} + +static int init_sa_dir(struct ix_sa_dir *dir) +{ + dir->npe_ctx = dma_pool_alloc(ctx_pool, GFP_KERNEL, &dir->npe_ctx_phys); + if (!dir->npe_ctx) { + return -ENOMEM; + } + reset_sa_dir(dir); + return 0; +} + +static void free_sa_dir(struct ix_sa_dir *dir) +{ + memset(dir->npe_ctx, 0, NPE_CTX_LEN); + dma_pool_free(ctx_pool, dir->npe_ctx, dir->npe_ctx_phys); +} + +static int init_tfm(struct crypto_tfm *tfm) +{ + struct ixp_ctx *ctx = crypto_tfm_ctx(tfm); + int ret; + + atomic_set(&ctx->configuring, 0); + ret = init_sa_dir(&ctx->encrypt); + if (ret) + return ret; + ret = init_sa_dir(&ctx->decrypt); + if (ret) { + free_sa_dir(&ctx->encrypt); + } + return ret; +} + +static int init_tfm_ablk(struct crypto_tfm *tfm) +{ + tfm->crt_ablkcipher.reqsize = sizeof(struct ablk_ctx); + return init_tfm(tfm); +} + +static int init_tfm_aead(struct crypto_tfm *tfm) +{ + tfm->crt_aead.reqsize = sizeof(struct aead_ctx); + return init_tfm(tfm); +} + +static void exit_tfm(struct crypto_tfm *tfm) +{ + struct ixp_ctx *ctx = crypto_tfm_ctx(tfm); + free_sa_dir(&ctx->encrypt); + free_sa_dir(&ctx->decrypt); +} + +static int register_chain_var(struct crypto_tfm *tfm, u8 xpad, u32 target, + int init_len, u32 ctx_addr, const u8 *key, int key_len) +{ + struct ixp_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypt_ctl *crypt; + struct buffer_desc *buf; + int i; + u8 *pad; + u32 pad_phys, buf_phys; + + BUILD_BUG_ON(NPE_CTX_LEN < HMAC_PAD_BLOCKLEN); + pad = dma_pool_alloc(ctx_pool, GFP_KERNEL, &pad_phys); + if (!pad) + return -ENOMEM; + buf = dma_pool_alloc(buffer_pool, GFP_KERNEL, &buf_phys); + if (!buf) { + dma_pool_free(ctx_pool, pad, pad_phys); + return -ENOMEM; + } + crypt = get_crypt_desc_emerg(); + if (!crypt) { + dma_pool_free(ctx_pool, pad, pad_phys); + dma_pool_free(buffer_pool, buf, buf_phys); + return -EAGAIN; + } + + memcpy(pad, key, key_len); + memset(pad + key_len, 0, HMAC_PAD_BLOCKLEN - key_len); + for (i = 0; i < HMAC_PAD_BLOCKLEN; i++) { + pad[i] ^= xpad; + } + + crypt->data.tfm = tfm; + crypt->regist_ptr = pad; + crypt->regist_buf = buf; + + crypt->auth_offs = 0; + crypt->auth_len = HMAC_PAD_BLOCKLEN; + crypt->crypto_ctx = ctx_addr; + crypt->src_buf = buf_phys; + crypt->icv_rev_aes = target; + crypt->mode = NPE_OP_HASH_GEN_ICV; + crypt->init_len = init_len; + crypt->ctl_flags |= CTL_FLAG_GEN_ICV; + + buf->next = 0; + buf->buf_len = HMAC_PAD_BLOCKLEN; + buf->pkt_len = 0; + buf->phys_addr = pad_phys; + + atomic_inc(&ctx->configuring); + qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt)); + BUG_ON(qmgr_stat_overflow(SEND_QID)); + return 0; +} + +static int setup_auth(struct crypto_tfm *tfm, int encrypt, unsigned authsize, + const u8 *key, int key_len, unsigned digest_len) +{ + u32 itarget, otarget, npe_ctx_addr; + unsigned char *cinfo; + int init_len, ret = 0; + u32 cfgword; + struct ix_sa_dir *dir; + struct ixp_ctx *ctx = crypto_tfm_ctx(tfm); + const struct ix_hash_algo *algo; + + dir = encrypt ? &ctx->encrypt : &ctx->decrypt; + cinfo = dir->npe_ctx + dir->npe_ctx_idx; + algo = ix_hash(tfm); + + /* write cfg word to cryptinfo */ + cfgword = algo->cfgword | ( authsize << 6); /* (authsize/4) << 8 */ + *(u32*)cinfo = cpu_to_be32(cfgword); + cinfo += sizeof(cfgword); + + /* write ICV to cryptinfo */ + memcpy(cinfo, algo->icv, digest_len); + cinfo += digest_len; + + itarget = dir->npe_ctx_phys + dir->npe_ctx_idx + + sizeof(algo->cfgword); + otarget = itarget + digest_len; + init_len = cinfo - (dir->npe_ctx + dir->npe_ctx_idx); + npe_ctx_addr = dir->npe_ctx_phys + dir->npe_ctx_idx; + + dir->npe_ctx_idx += init_len; + dir->npe_mode |= NPE_OP_HASH_ENABLE; + + if (!encrypt) + dir->npe_mode |= NPE_OP_HASH_VERIFY; + + ret = register_chain_var(tfm, HMAC_OPAD_VALUE, otarget, + init_len, npe_ctx_addr, key, key_len); + if (ret) + return ret; + return register_chain_var(tfm, HMAC_IPAD_VALUE, itarget, + init_len, npe_ctx_addr, key, key_len); +} + +static int gen_rev_aes_key(struct crypto_tfm *tfm) +{ + struct crypt_ctl *crypt; + struct ixp_ctx *ctx = crypto_tfm_ctx(tfm); + struct ix_sa_dir *dir = &ctx->decrypt; + + crypt = get_crypt_desc_emerg(); + if (!crypt) { + return -EAGAIN; + } + *(u32*)dir->npe_ctx |= cpu_to_be32(CIPH_ENCR); + + crypt->data.tfm = tfm; + crypt->crypt_offs = 0; + crypt->crypt_len = AES_BLOCK128; + crypt->src_buf = 0; + crypt->crypto_ctx = dir->npe_ctx_phys; + crypt->icv_rev_aes = dir->npe_ctx_phys + sizeof(u32); + crypt->mode = NPE_OP_ENC_GEN_KEY; + crypt->init_len = dir->npe_ctx_idx; + crypt->ctl_flags |= CTL_FLAG_GEN_REVAES; + + atomic_inc(&ctx->configuring); + qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt)); + BUG_ON(qmgr_stat_overflow(SEND_QID)); + return 0; +} + +static int setup_cipher(struct crypto_tfm *tfm, int encrypt, + const u8 *key, int key_len) +{ + u8 *cinfo; + u32 cipher_cfg; + u32 keylen_cfg = 0; + struct ix_sa_dir *dir; + struct ixp_ctx *ctx = crypto_tfm_ctx(tfm); + u32 *flags = &tfm->crt_flags; + + dir = encrypt ? &ctx->encrypt : &ctx->decrypt; + cinfo = dir->npe_ctx; + + if (encrypt) { + cipher_cfg = cipher_cfg_enc(tfm); + dir->npe_mode |= NPE_OP_CRYPT_ENCRYPT; + } else { + cipher_cfg = cipher_cfg_dec(tfm); + } + if (cipher_cfg & MOD_AES) { + switch (key_len) { + case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break; + case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break; + case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break; + default: + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + cipher_cfg |= keylen_cfg; + } else if (cipher_cfg & MOD_3DES) { + const u32 *K = (const u32 *)key; + if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || + !((K[2] ^ K[4]) | (K[3] ^ K[5])))) + { + *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; + return -EINVAL; + } + } else { + u32 tmp[DES_EXPKEY_WORDS]; + if (des_ekey(tmp, key) == 0) { + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + } + } + /* write cfg word to cryptinfo */ + *(u32*)cinfo = cpu_to_be32(cipher_cfg); + cinfo += sizeof(cipher_cfg); + + /* write cipher key to cryptinfo */ + memcpy(cinfo, key, key_len); + /* NPE wants keylen set to DES3_EDE_KEY_SIZE even for single DES */ + if (key_len < DES3_EDE_KEY_SIZE && !(cipher_cfg & MOD_AES)) { + memset(cinfo + key_len, 0, DES3_EDE_KEY_SIZE -key_len); + key_len = DES3_EDE_KEY_SIZE; + } + dir->npe_ctx_idx = sizeof(cipher_cfg) + key_len; + dir->npe_mode |= NPE_OP_CRYPT_ENABLE; + if ((cipher_cfg & MOD_AES) && !encrypt) { + return gen_rev_aes_key(tfm); + } + return 0; +} + +static int count_sg(struct scatterlist *sg, int nbytes) +{ + int i; + for (i = 0; nbytes > 0; i++, sg = sg_next(sg)) + nbytes -= sg->length; + return i; +} + +static struct buffer_desc *chainup_buffers(struct scatterlist *sg, + unsigned nbytes, struct buffer_desc *buf, gfp_t flags) +{ + int nents = 0; + + while (nbytes > 0) { + struct buffer_desc *next_buf; + u32 next_buf_phys; + unsigned len = min(nbytes, sg_dma_len(sg)); + + nents++; + nbytes -= len; + if (!buf->phys_addr) { + buf->phys_addr = sg_dma_address(sg); + buf->buf_len = len; + buf->next = NULL; + buf->phys_next = 0; + goto next; + } + /* Two consecutive chunks on one page may be handled by the old + * buffer descriptor, increased by the length of the new one + */ + if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) { + buf->buf_len += len; + goto next; + } + next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys); + if (!next_buf) + return NULL; + buf->next = next_buf; + buf->phys_next = next_buf_phys; + + buf = next_buf; + buf->next = NULL; + buf->phys_next = 0; + buf->phys_addr = sg_dma_address(sg); + buf->buf_len = len; +next: + if (nbytes > 0) { + sg = sg_next(sg); + } + } + return buf; +} + +static int ablk_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len) +{ + struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm); + u32 *flags = &tfm->base.crt_flags; + int ret; + + init_completion(&ctx->completion); + atomic_inc(&ctx->configuring); + + reset_sa_dir(&ctx->encrypt); + reset_sa_dir(&ctx->decrypt); + + ctx->encrypt.npe_mode = NPE_OP_HMAC_DISABLE; + ctx->decrypt.npe_mode = NPE_OP_HMAC_DISABLE; + + ret = setup_cipher(&tfm->base, 0, key, key_len); + if (ret) + goto out; + ret = setup_cipher(&tfm->base, 1, key, key_len); + if (ret) + goto out; + + if (*flags & CRYPTO_TFM_RES_WEAK_KEY) { + if (*flags & CRYPTO_TFM_REQ_WEAK_KEY) { + ret = -EINVAL; + } else { + *flags &= ~CRYPTO_TFM_RES_WEAK_KEY; + } + } +out: + if (!atomic_dec_and_test(&ctx->configuring)) + wait_for_completion(&ctx->completion); + return ret; +} + +static int ablk_rfc3686_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len) +{ + struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm); + + /* the nonce is stored in bytes at end of key */ + if (key_len < CTR_RFC3686_NONCE_SIZE) + return -EINVAL; + + memcpy(ctx->nonce, key + (key_len - CTR_RFC3686_NONCE_SIZE), + CTR_RFC3686_NONCE_SIZE); + + key_len -= CTR_RFC3686_NONCE_SIZE; + return ablk_setkey(tfm, key, key_len); +} + +static int ablk_perform(struct ablkcipher_request *req, int encrypt) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm); + unsigned ivsize = crypto_ablkcipher_ivsize(tfm); + int ret = -ENOMEM; + struct ix_sa_dir *dir; + struct crypt_ctl *crypt; + unsigned int nbytes = req->nbytes, nents; + enum dma_data_direction src_direction = DMA_BIDIRECTIONAL; + struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req); + gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? + GFP_KERNEL : GFP_ATOMIC; + + if (qmgr_stat_full(SEND_QID)) + return -EAGAIN; + if (atomic_read(&ctx->configuring)) + return -EAGAIN; + + dir = encrypt ? &ctx->encrypt : &ctx->decrypt; + + crypt = get_crypt_desc(); + if (!crypt) + return ret; + + crypt->data.ablk_req = req; + crypt->crypto_ctx = dir->npe_ctx_phys; + crypt->mode = dir->npe_mode; + crypt->init_len = dir->npe_ctx_idx; + + crypt->crypt_offs = 0; + crypt->crypt_len = nbytes; + + BUG_ON(ivsize && !req->info); + memcpy(crypt->iv, req->info, ivsize); + if (req->src != req->dst) { + crypt->mode |= NPE_OP_NOT_IN_PLACE; + nents = count_sg(req->dst, nbytes); + /* This was never tested by Intel + * for more than one dst buffer, I think. */ + BUG_ON(nents != 1); + req_ctx->dst_nents = nents; + dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE); + req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf); + if (!req_ctx->dst) + goto unmap_sg_dest; + req_ctx->dst->phys_addr = 0; + if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags)) + goto free_buf_dest; + src_direction = DMA_TO_DEVICE; + } else { + req_ctx->dst = NULL; + req_ctx->dst_nents = 0; + } + nents = count_sg(req->src, nbytes); + req_ctx->src_nents = nents; + dma_map_sg(dev, req->src, nents, src_direction); + + req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf); + if (!req_ctx->src) + goto unmap_sg_src; + req_ctx->src->phys_addr = 0; + if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags)) + goto free_buf_src; + + crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK; + qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt)); + BUG_ON(qmgr_stat_overflow(SEND_QID)); + return -EINPROGRESS; + +free_buf_src: + free_buf_chain(req_ctx->src, crypt->src_buf); +unmap_sg_src: + dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction); +free_buf_dest: + if (req->src != req->dst) { + free_buf_chain(req_ctx->dst, crypt->dst_buf); +unmap_sg_dest: + dma_unmap_sg(dev, req->src, req_ctx->dst_nents, + DMA_FROM_DEVICE); + } + crypt->ctl_flags = CTL_FLAG_UNUSED; + return ret; +} + +static int ablk_encrypt(struct ablkcipher_request *req) +{ + return ablk_perform(req, 1); +} + +static int ablk_decrypt(struct ablkcipher_request *req) +{ + return ablk_perform(req, 0); +} + +static int ablk_rfc3686_crypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm); + u8 iv[CTR_RFC3686_BLOCK_SIZE]; + u8 *info = req->info; + int ret; + + /* set up counter block */ + memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); + memcpy(iv + CTR_RFC3686_NONCE_SIZE, info, CTR_RFC3686_IV_SIZE); + + /* initialize counter portion of counter block */ + *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = + cpu_to_be32(1); + + req->info = iv; + ret = ablk_perform(req, 1); + req->info = info; + return ret; +} + +static int hmac_inconsistent(struct scatterlist *sg, unsigned start, + unsigned int nbytes) +{ + int offset = 0; + + if (!nbytes) + return 0; + + for (;;) { + if (start < offset + sg->length) + break; + + offset += sg->length; + sg = sg_next(sg); + } + return (start + nbytes > offset + sg->length); +} + +static int aead_perform(struct aead_request *req, int encrypt, + int cryptoffset, int eff_cryptlen, u8 *iv) +{ + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct ixp_ctx *ctx = crypto_aead_ctx(tfm); + unsigned ivsize = crypto_aead_ivsize(tfm); + unsigned authsize = crypto_aead_authsize(tfm); + int ret = -ENOMEM; + struct ix_sa_dir *dir; + struct crypt_ctl *crypt; + unsigned int cryptlen, nents; + struct buffer_desc *buf; + struct aead_ctx *req_ctx = aead_request_ctx(req); + gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? + GFP_KERNEL : GFP_ATOMIC; + + if (qmgr_stat_full(SEND_QID)) + return -EAGAIN; + if (atomic_read(&ctx->configuring)) + return -EAGAIN; + + if (encrypt) { + dir = &ctx->encrypt; + cryptlen = req->cryptlen; + } else { + dir = &ctx->decrypt; + /* req->cryptlen includes the authsize when decrypting */ + cryptlen = req->cryptlen -authsize; + eff_cryptlen -= authsize; + } + crypt = get_crypt_desc(); + if (!crypt) + return ret; + + crypt->data.aead_req = req; + crypt->crypto_ctx = dir->npe_ctx_phys; + crypt->mode = dir->npe_mode; + crypt->init_len = dir->npe_ctx_idx; + + crypt->crypt_offs = cryptoffset; + crypt->crypt_len = eff_cryptlen; + + crypt->auth_offs = 0; + crypt->auth_len = req->assoclen + ivsize + cryptlen; + BUG_ON(ivsize && !req->iv); + memcpy(crypt->iv, req->iv, ivsize); + + if (req->src != req->dst) { + BUG(); /* -ENOTSUP because of my lazyness */ + } + + req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf); + if (!req_ctx->buffer) + goto out; + req_ctx->buffer->phys_addr = 0; + /* ASSOC data */ + nents = count_sg(req->assoc, req->assoclen); + req_ctx->assoc_nents = nents; + dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE); + buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags); + if (!buf) + goto unmap_sg_assoc; + /* IV */ + sg_init_table(&req_ctx->ivlist, 1); + sg_set_buf(&req_ctx->ivlist, iv, ivsize); + dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL); + buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags); + if (!buf) + goto unmap_sg_iv; + if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) { + /* The 12 hmac bytes are scattered, + * we need to copy them into a safe buffer */ + req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags, + &crypt->icv_rev_aes); + if (unlikely(!req_ctx->hmac_virt)) + goto unmap_sg_iv; + if (!encrypt) { + scatterwalk_map_and_copy(req_ctx->hmac_virt, + req->src, cryptlen, authsize, 0); + } + req_ctx->encrypt = encrypt; + } else { + req_ctx->hmac_virt = NULL; + } + /* Crypt */ + nents = count_sg(req->src, cryptlen + authsize); + req_ctx->src_nents = nents; + dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL); + buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags); + if (!buf) + goto unmap_sg_src; + if (!req_ctx->hmac_virt) { + crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize; + } + crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD; + qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt)); + BUG_ON(qmgr_stat_overflow(SEND_QID)); + return -EINPROGRESS; +unmap_sg_src: + dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL); + if (req_ctx->hmac_virt) { + dma_pool_free(buffer_pool, req_ctx->hmac_virt, + crypt->icv_rev_aes); + } +unmap_sg_iv: + dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL); +unmap_sg_assoc: + dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE); + free_buf_chain(req_ctx->buffer, crypt->src_buf); +out: + crypt->ctl_flags = CTL_FLAG_UNUSED; + return ret; +} + +static int aead_setup(struct crypto_aead *tfm, unsigned int authsize) +{ + struct ixp_ctx *ctx = crypto_aead_ctx(tfm); + u32 *flags = &tfm->base.crt_flags; + unsigned digest_len = crypto_aead_alg(tfm)->maxauthsize; + int ret; + + if (!ctx->enckey_len && !ctx->authkey_len) + return 0; + init_completion(&ctx->completion); + atomic_inc(&ctx->configuring); + + reset_sa_dir(&ctx->encrypt); + reset_sa_dir(&ctx->decrypt); + + ret = setup_cipher(&tfm->base, 0, ctx->enckey, ctx->enckey_len); + if (ret) + goto out; + ret = setup_cipher(&tfm->base, 1, ctx->enckey, ctx->enckey_len); + if (ret) + goto out; + ret = setup_auth(&tfm->base, 0, authsize, ctx->authkey, + ctx->authkey_len, digest_len); + if (ret) + goto out; + ret = setup_auth(&tfm->base, 1, authsize, ctx->authkey, + ctx->authkey_len, digest_len); + if (ret) + goto out; + + if (*flags & CRYPTO_TFM_RES_WEAK_KEY) { + if (*flags & CRYPTO_TFM_REQ_WEAK_KEY) { + ret = -EINVAL; + goto out; + } else { + *flags &= ~CRYPTO_TFM_RES_WEAK_KEY; + } + } +out: + if (!atomic_dec_and_test(&ctx->configuring)) + wait_for_completion(&ctx->completion); + return ret; +} + +static int aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + int max = crypto_aead_alg(tfm)->maxauthsize >> 2; + + if ((authsize>>2) < 1 || (authsize>>2) > max || (authsize & 3)) + return -EINVAL; + return aead_setup(tfm, authsize); +} + +static int aead_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) +{ + struct ixp_ctx *ctx = crypto_aead_ctx(tfm); + struct rtattr *rta = (struct rtattr *)key; + struct crypto_authenc_key_param *param; + + if (!RTA_OK(rta, keylen)) + goto badkey; + if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) + goto badkey; + if (RTA_PAYLOAD(rta) < sizeof(*param)) + goto badkey; + + param = RTA_DATA(rta); + ctx->enckey_len = be32_to_cpu(param->enckeylen); + + key += RTA_ALIGN(rta->rta_len); + keylen -= RTA_ALIGN(rta->rta_len); + + if (keylen < ctx->enckey_len) + goto badkey; + + ctx->authkey_len = keylen - ctx->enckey_len; + memcpy(ctx->enckey, key + ctx->authkey_len, ctx->enckey_len); + memcpy(ctx->authkey, key, ctx->authkey_len); + + return aead_setup(tfm, crypto_aead_authsize(tfm)); +badkey: + ctx->enckey_len = 0; + crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; +} + +static int aead_encrypt(struct aead_request *req) +{ + unsigned ivsize = crypto_aead_ivsize(crypto_aead_reqtfm(req)); + return aead_perform(req, 1, req->assoclen + ivsize, + req->cryptlen, req->iv); +} + +static int aead_decrypt(struct aead_request *req) +{ + unsigned ivsize = crypto_aead_ivsize(crypto_aead_reqtfm(req)); + return aead_perform(req, 0, req->assoclen + ivsize, + req->cryptlen, req->iv); +} + +static int aead_givencrypt(struct aead_givcrypt_request *req) +{ + struct crypto_aead *tfm = aead_givcrypt_reqtfm(req); + struct ixp_ctx *ctx = crypto_aead_ctx(tfm); + unsigned len, ivsize = crypto_aead_ivsize(tfm); + __be64 seq; + + /* copied from eseqiv.c */ + if (!ctx->salted) { + get_random_bytes(ctx->salt, ivsize); + ctx->salted = 1; + } + memcpy(req->areq.iv, ctx->salt, ivsize); + len = ivsize; + if (ivsize > sizeof(u64)) { + memset(req->giv, 0, ivsize - sizeof(u64)); + len = sizeof(u64); + } + seq = cpu_to_be64(req->seq); + memcpy(req->giv + ivsize - len, &seq, len); + return aead_perform(&req->areq, 1, req->areq.assoclen, + req->areq.cryptlen +ivsize, req->giv); +} + +static struct ixp_alg ixp4xx_algos[] = { +{ + .crypto = { + .cra_name = "cbc(des)", + .cra_blocksize = DES_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .ivsize = DES_BLOCK_SIZE, + .geniv = "eseqiv", + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_DES | MOD_CBC_ENC | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_DES | MOD_CBC_DEC | KEYLEN_192, + +}, { + .crypto = { + .cra_name = "ecb(des)", + .cra_blocksize = DES_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_DES | MOD_ECB | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_DES | MOD_ECB | KEYLEN_192, +}, { + .crypto = { + .cra_name = "cbc(des3_ede)", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .ivsize = DES3_EDE_BLOCK_SIZE, + .geniv = "eseqiv", + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_3DES | MOD_CBC_ENC | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_3DES | MOD_CBC_DEC | KEYLEN_192, +}, { + .crypto = { + .cra_name = "ecb(des3_ede)", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_3DES | MOD_ECB | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_3DES | MOD_ECB | KEYLEN_192, +}, { + .crypto = { + .cra_name = "cbc(aes)", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .geniv = "eseqiv", + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_AES | MOD_CBC_ENC, + .cfg_dec = CIPH_DECR | MOD_AES | MOD_CBC_DEC, +}, { + .crypto = { + .cra_name = "ecb(aes)", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_AES | MOD_ECB, + .cfg_dec = CIPH_DECR | MOD_AES | MOD_ECB, +}, { + .crypto = { + .cra_name = "ctr(aes)", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .geniv = "eseqiv", + } + } + }, + .cfg_enc = CIPH_ENCR | MOD_AES | MOD_CTR, + .cfg_dec = CIPH_ENCR | MOD_AES | MOD_CTR, +}, { + .crypto = { + .cra_name = "rfc3686(ctr(aes))", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_u = { .ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .geniv = "eseqiv", + .setkey = ablk_rfc3686_setkey, + .encrypt = ablk_rfc3686_crypt, + .decrypt = ablk_rfc3686_crypt } + } + }, + .cfg_enc = CIPH_ENCR | MOD_AES | MOD_CTR, + .cfg_dec = CIPH_ENCR | MOD_AES | MOD_CTR, +}, { + .crypto = { + .cra_name = "authenc(hmac(md5),cbc(des))", + .cra_blocksize = DES_BLOCK_SIZE, + .cra_u = { .aead = { + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + } + } + }, + .hash = &hash_alg_md5, + .cfg_enc = CIPH_ENCR | MOD_DES | MOD_CBC_ENC | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_DES | MOD_CBC_DEC | KEYLEN_192, +}, { + .crypto = { + .cra_name = "authenc(hmac(md5),cbc(des3_ede))", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_u = { .aead = { + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + } + } + }, + .hash = &hash_alg_md5, + .cfg_enc = CIPH_ENCR | MOD_3DES | MOD_CBC_ENC | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_3DES | MOD_CBC_DEC | KEYLEN_192, +}, { + .crypto = { + .cra_name = "authenc(hmac(sha1),cbc(des))", + .cra_blocksize = DES_BLOCK_SIZE, + .cra_u = { .aead = { + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + } + } + }, + .hash = &hash_alg_sha1, + .cfg_enc = CIPH_ENCR | MOD_DES | MOD_CBC_ENC | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_DES | MOD_CBC_DEC | KEYLEN_192, +}, { + .crypto = { + .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_u = { .aead = { + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + } + } + }, + .hash = &hash_alg_sha1, + .cfg_enc = CIPH_ENCR | MOD_3DES | MOD_CBC_ENC | KEYLEN_192, + .cfg_dec = CIPH_DECR | MOD_3DES | MOD_CBC_DEC | KEYLEN_192, +}, { + .crypto = { + .cra_name = "authenc(hmac(md5),cbc(aes))", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_u = { .aead = { + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + } + } + }, + .hash = &hash_alg_md5, + .cfg_enc = CIPH_ENCR | MOD_AES | MOD_CBC_ENC, + .cfg_dec = CIPH_DECR | MOD_AES | MOD_CBC_DEC, +}, { + .crypto = { + .cra_name = "authenc(hmac(sha1),cbc(aes))", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_u = { .aead = { + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + } + } + }, + .hash = &hash_alg_sha1, + .cfg_enc = CIPH_ENCR | MOD_AES | MOD_CBC_ENC, + .cfg_dec = CIPH_DECR | MOD_AES | MOD_CBC_DEC, +} }; + +#define IXP_POSTFIX "-ixp4xx" +static int __init ixp_module_init(void) +{ + int num = ARRAY_SIZE(ixp4xx_algos); + int i,err ; + + if (platform_device_register(&pseudo_dev)) + return -ENODEV; + + spin_lock_init(&desc_lock); + spin_lock_init(&emerg_lock); + + err = init_ixp_crypto(); + if (err) { + platform_device_unregister(&pseudo_dev); + return err; + } + for (i=0; i< num; i++) { + struct crypto_alg *cra = &ixp4xx_algos[i].crypto; + + if (snprintf(cra->cra_driver_name, CRYPTO_MAX_ALG_NAME, + "%s"IXP_POSTFIX, cra->cra_name) >= + CRYPTO_MAX_ALG_NAME) + { + continue; + } + if (!support_aes && (ixp4xx_algos[i].cfg_enc & MOD_AES)) { + continue; + } + if (!ixp4xx_algos[i].hash) { + /* block ciphers */ + cra->cra_type = &crypto_ablkcipher_type; + cra->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC; + if (!cra->cra_ablkcipher.setkey) + cra->cra_ablkcipher.setkey = ablk_setkey; + if (!cra->cra_ablkcipher.encrypt) + cra->cra_ablkcipher.encrypt = ablk_encrypt; + if (!cra->cra_ablkcipher.decrypt) + cra->cra_ablkcipher.decrypt = ablk_decrypt; + cra->cra_init = init_tfm_ablk; + } else { + /* authenc */ + cra->cra_type = &crypto_aead_type; + cra->cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC; + cra->cra_aead.setkey = aead_setkey; + cra->cra_aead.setauthsize = aead_setauthsize; + cra->cra_aead.encrypt = aead_encrypt; + cra->cra_aead.decrypt = aead_decrypt; + cra->cra_aead.givencrypt = aead_givencrypt; + cra->cra_init = init_tfm_aead; + } + cra->cra_ctxsize = sizeof(struct ixp_ctx); + cra->cra_module = THIS_MODULE; + cra->cra_alignmask = 3; + cra->cra_priority = 300; + cra->cra_exit = exit_tfm; + if (crypto_register_alg(cra)) + printk(KERN_ERR "Failed to register '%s'\n", + cra->cra_name); + else + ixp4xx_algos[i].registered = 1; + } + return 0; +} + +static void __exit ixp_module_exit(void) +{ + int num = ARRAY_SIZE(ixp4xx_algos); + int i; + + for (i=0; i< num; i++) { + if (ixp4xx_algos[i].registered) + crypto_unregister_alg(&ixp4xx_algos[i].crypto); + } + release_ixp_crypto(); + platform_device_unregister(&pseudo_dev); +} + +module_init(ixp_module_init); +module_exit(ixp_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Christian Hohnstaedt "); +MODULE_DESCRIPTION("IXP4xx hardware crypto"); + -- cgit v0.10.2 From 4b22f0ddb6564210c9ded7ba25b2a1007733e784 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 3 Jul 2008 14:57:30 +0800 Subject: crypto: tcrpyt - Remove unnecessary kmap/kunmap calls Noticed by Neil Horman: we are doing unnecessary kmap/kunmap calls on kmalloced memory. This patch removes them. For the purposes of testing SG construction, the underlying crypto code already does plenty of kmap/kunmap calls anyway. Signed-off-by: Herbert Xu diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index ffc1ec6..87f08f9 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -31,7 +30,7 @@ #include "tcrypt.h" /* - * Need to kmalloc() memory for testing kmap(). + * Need to kmalloc() memory for testing. */ #define TVMEMSIZE 16384 #define XBUFSIZE 32768 @@ -376,13 +375,12 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template, goto next_one; } - q = kmap(sg_page(&sg[0])) + sg[0].offset; + q = input; hexdump(q, template[i].rlen); printk(KERN_INFO "enc/dec: %s\n", memcmp(q, template[i].result, template[i].rlen) ? "fail" : "pass"); - kunmap(sg_page(&sg[0])); next_one: if (!template[i].key) kfree(key); @@ -482,7 +480,7 @@ next_one: for (k = 0, temp = 0; k < template[i].np; k++) { printk(KERN_INFO "page %u\n", k); - q = kmap(sg_page(&sg[k])) + sg[k].offset; + q = &axbuf[IDX[k]]; hexdump(q, template[i].tap[k]); printk(KERN_INFO "%s\n", memcmp(q, template[i].result + temp, @@ -500,7 +498,6 @@ next_one: } temp += template[i].tap[k]; - kunmap(sg_page(&sg[k])); } } } @@ -609,13 +606,12 @@ static void test_cipher(char *algo, int enc, goto out; } - q = kmap(sg_page(&sg[0])) + sg[0].offset; + q = data; hexdump(q, template[i].rlen); printk("%s\n", memcmp(q, template[i].result, template[i].rlen) ? "fail" : "pass"); - kunmap(sg_page(&sg[0])); } kfree(data); } @@ -689,7 +685,7 @@ static void test_cipher(char *algo, int enc, temp = 0; for (k = 0; k < template[i].np; k++) { printk("page %u\n", k); - q = kmap(sg_page(&sg[k])) + sg[k].offset; + q = &xbuf[IDX[k]]; hexdump(q, template[i].tap[k]); printk("%s\n", memcmp(q, template[i].result + temp, @@ -704,7 +700,6 @@ static void test_cipher(char *algo, int enc, hexdump(&q[template[i].tap[k]], n); } temp += template[i].tap[k]; - kunmap(sg_page(&sg[k])); } } } -- cgit v0.10.2 From b43e726b32b85713c7c56b6545cf71c2b02b5e1a Mon Sep 17 00:00:00 2001 From: Jeremy Katz Date: Thu, 3 Jul 2008 19:03:31 +0800 Subject: crypto: padlock - Make module loading quieter when hardware isn't available When loading aes or sha256 via the module aliases, the padlock modules also try to get loaded. Make the error message for them not being present only be a NOTICE rather than an ERROR so that use of 'quiet' will suppress the messages Signed-off-by: Jeremy Katz Signed-off-by: Herbert Xu diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index bb30eb9..54a2a16 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -385,12 +385,12 @@ static int __init padlock_init(void) int ret; if (!cpu_has_xcrypt) { - printk(KERN_ERR PFX "VIA PadLock not detected.\n"); + printk(KERN_NOTICE PFX "VIA PadLock not detected.\n"); return -ENODEV; } if (!cpu_has_xcrypt_enabled) { - printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); return -ENODEV; } diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index c666b4e..40d5680 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -254,12 +254,12 @@ static int __init padlock_init(void) int rc = -ENODEV; if (!cpu_has_phe) { - printk(KERN_ERR PFX "VIA PadLock Hash Engine not detected.\n"); + printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); return -ENODEV; } if (!cpu_has_phe_enabled) { - printk(KERN_ERR PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); return -ENODEV; } -- cgit v0.10.2 From 70bcaca75389a6c011ddc866eb1743b070a838b0 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Thu, 3 Jul 2008 19:08:46 +0800 Subject: crypto: talitos - Add support for 3des This patch adds support for authenc(hmac(sha1),cbc(des3_ede)) to the talitos crypto driver for the Freescale Security Engine. Some adjustments were made to the scatterlist to link table conversion to make 3des work for ping -s 1439..1446. Signed-off-by: Lee Nipper Signed-off-by: Herbert Xu diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index e123312..e8459e0 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -642,20 +642,24 @@ static void talitos_unregister_rng(struct device *dev) #define TALITOS_MAX_KEY_SIZE 64 #define TALITOS_MAX_AUTH_SIZE 20 #define TALITOS_AES_MIN_BLOCK_SIZE 16 +#define TALITOS_3DES_MIN_BLOCK_SIZE 24 + #define TALITOS_AES_IV_LENGTH 16 +#define TALITOS_3DES_IV_LENGTH 8 +#define TALITOS_MAX_IV_LENGTH 16 struct talitos_ctx { struct device *dev; __be32 desc_hdr_template; u8 key[TALITOS_MAX_KEY_SIZE]; - u8 iv[TALITOS_AES_IV_LENGTH]; + u8 iv[TALITOS_MAX_IV_LENGTH]; unsigned int keylen; unsigned int enckeylen; unsigned int authkeylen; unsigned int authsize; }; -static int aes_cbc_sha1_hmac_authenc_setauthsize(struct crypto_aead *authenc, +static int aead_authenc_setauthsize(struct crypto_aead *authenc, unsigned int authsize) { struct talitos_ctx *ctx = crypto_aead_ctx(authenc); @@ -665,7 +669,7 @@ static int aes_cbc_sha1_hmac_authenc_setauthsize(struct crypto_aead *authenc, return 0; } -static int aes_cbc_sha1_hmac_authenc_setkey(struct crypto_aead *authenc, +static int aead_authenc_setkey(struct crypto_aead *authenc, const u8 *key, unsigned int keylen) { struct talitos_ctx *ctx = crypto_aead_ctx(authenc); @@ -825,10 +829,12 @@ static void ipsec_esp_decrypt_done(struct device *dev, * convert scatterlist to SEC h/w link table format * stop at cryptlen bytes */ -static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, +static int sg_to_link_tbl(struct scatterlist *sg, int sg_count, int cryptlen, struct talitos_ptr *link_tbl_ptr) { - while (cryptlen > 0) { + int n_sg = sg_count; + + while (n_sg--) { link_tbl_ptr->ptr = cpu_to_be32(sg_dma_address(sg)); link_tbl_ptr->len = cpu_to_be16(sg_dma_len(sg)); link_tbl_ptr->j_extent = 0; @@ -837,13 +843,22 @@ static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, sg = sg_next(sg); } - /* adjust (decrease) last entry's len to cryptlen */ + /* adjust (decrease) last one (or two) entry's len to cryptlen */ link_tbl_ptr--; + while (link_tbl_ptr->len <= (-cryptlen)) { + /* Empty this entry, and move to previous one */ + cryptlen += be16_to_cpu(link_tbl_ptr->len); + link_tbl_ptr->len = 0; + sg_count--; + link_tbl_ptr--; + } link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len) + cryptlen); /* tag end of link table */ link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; + + return sg_count; } /* @@ -900,12 +915,17 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, if (sg_count == 1) { desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); } else { - sg_to_link_tbl(areq->src, sg_count, cryptlen, - &edesc->link_tbl[0]); - desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; - desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); - dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, - edesc->dma_len, DMA_BIDIRECTIONAL); + sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen, + &edesc->link_tbl[0]); + if (sg_count > 1) { + desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; + desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); + dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, + edesc->dma_len, DMA_BIDIRECTIONAL); + } else { + /* Only one segment now, so no link tbl needed */ + desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); + } } /* cipher out */ @@ -931,8 +951,8 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, memcpy(link_tbl_ptr, &edesc->link_tbl[0], edesc->src_nents * sizeof(struct talitos_ptr)); } else { - sg_to_link_tbl(areq->dst, sg_count, cryptlen, - link_tbl_ptr); + sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen, + link_tbl_ptr); } link_tbl_ptr += sg_count - 1; @@ -1038,7 +1058,7 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, return edesc; } -static int aes_cbc_sha1_hmac_authenc_encrypt(struct aead_request *req) +static int aead_authenc_encrypt(struct aead_request *req) { struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct talitos_ctx *ctx = crypto_aead_ctx(authenc); @@ -1050,12 +1070,12 @@ static int aes_cbc_sha1_hmac_authenc_encrypt(struct aead_request *req) return PTR_ERR(edesc); /* set encrypt */ - edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_AESU_ENC; + edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done); } -static int aes_cbc_sha1_hmac_authenc_decrypt(struct aead_request *req) +static int aead_authenc_decrypt(struct aead_request *req) { struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct talitos_ctx *ctx = crypto_aead_ctx(authenc); @@ -1089,7 +1109,7 @@ static int aes_cbc_sha1_hmac_authenc_decrypt(struct aead_request *req) return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_done); } -static int aes_cbc_sha1_hmac_authenc_givencrypt( +static int aead_authenc_givencrypt( struct aead_givcrypt_request *req) { struct aead_request *areq = &req->areq; @@ -1103,7 +1123,7 @@ static int aes_cbc_sha1_hmac_authenc_givencrypt( return PTR_ERR(edesc); /* set encrypt */ - edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_AESU_ENC; + edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); @@ -1127,11 +1147,11 @@ static struct talitos_alg_template driver_algs[] = { .driver_name = "authenc(hmac(sha1-talitos),cbc(aes-talitos))", .blocksize = TALITOS_AES_MIN_BLOCK_SIZE, .aead = { - .setkey = aes_cbc_sha1_hmac_authenc_setkey, - .setauthsize = aes_cbc_sha1_hmac_authenc_setauthsize, - .encrypt = aes_cbc_sha1_hmac_authenc_encrypt, - .decrypt = aes_cbc_sha1_hmac_authenc_decrypt, - .givencrypt = aes_cbc_sha1_hmac_authenc_givencrypt, + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, .geniv = "", .ivsize = TALITOS_AES_IV_LENGTH, .maxauthsize = TALITOS_MAX_AUTH_SIZE, @@ -1143,6 +1163,29 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_INIT | DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_SHA1_HMAC, + }, + { + .name = "authenc(hmac(sha1),cbc(des3_ede))", + .driver_name = "authenc(hmac(sha1-talitos),cbc(3des-talitos))", + .blocksize = TALITOS_3DES_MIN_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = TALITOS_3DES_IV_LENGTH, + .maxauthsize = TALITOS_MAX_AUTH_SIZE, + }, + .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | + DESC_HDR_SEL0_DEU | + DESC_HDR_MODE0_DEU_CBC | + DESC_HDR_MODE0_DEU_3DES | + DESC_HDR_SEL1_MDEUA | + DESC_HDR_MODE1_MDEU_INIT | + DESC_HDR_MODE1_MDEU_PAD | + DESC_HDR_MODE1_MDEU_SHA1_HMAC, } }; @@ -1166,7 +1209,7 @@ static int talitos_cra_init(struct crypto_tfm *tfm) ctx->desc_hdr_template = talitos_alg->desc_hdr_template; /* random first IV */ - get_random_bytes(ctx->iv, TALITOS_AES_IV_LENGTH); + get_random_bytes(ctx->iv, TALITOS_MAX_IV_LENGTH); return 0; } diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index de0e377..c48a405 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -144,11 +144,10 @@ #define DESC_HDR_SEL0_CRCU __constant_cpu_to_be32(0x80000000) /* primary execution unit mode (MODE0) and derivatives */ +#define DESC_HDR_MODE0_ENCRYPT __constant_cpu_to_be32(0x00100000) #define DESC_HDR_MODE0_AESU_CBC __constant_cpu_to_be32(0x00200000) -#define DESC_HDR_MODE0_AESU_ENC __constant_cpu_to_be32(0x00100000) #define DESC_HDR_MODE0_DEU_CBC __constant_cpu_to_be32(0x00400000) #define DESC_HDR_MODE0_DEU_3DES __constant_cpu_to_be32(0x00200000) -#define DESC_HDR_MODE0_DEU_ENC __constant_cpu_to_be32(0x00100000) #define DESC_HDR_MODE0_MDEU_INIT __constant_cpu_to_be32(0x01000000) #define DESC_HDR_MODE0_MDEU_HMAC __constant_cpu_to_be32(0x00800000) #define DESC_HDR_MODE0_MDEU_PAD __constant_cpu_to_be32(0x00400000) -- cgit v0.10.2 From ebbcf3369224ae7d23bfee06d8c5ea87a9541db5 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 3 Jul 2008 19:14:02 +0800 Subject: crypto: talitos - Use proper form for algorithm driver names The name authenc(hmac(sha1-talitos),cbc(aes-talitos)) is potentially ambiguous since it could also mean using the generic authenc template on hmac(sha1-talitos) and cbc(aes-talitos). In general, parentheses should be reserved for templates that spawn algorithms. This patches changes it to the form authenc-hmac-sha1-cbc-aes-talitos. Signed-off-by: Herbert Xu diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index e8459e0..8c270cd 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1144,7 +1144,7 @@ static struct talitos_alg_template driver_algs[] = { /* single-pass ipsec_esp descriptor */ { .name = "authenc(hmac(sha1),cbc(aes))", - .driver_name = "authenc(hmac(sha1-talitos),cbc(aes-talitos))", + .driver_name = "authenc-hmac-sha1-cbc-aes-talitos", .blocksize = TALITOS_AES_MIN_BLOCK_SIZE, .aead = { .setkey = aead_authenc_setkey, @@ -1166,7 +1166,7 @@ static struct talitos_alg_template driver_algs[] = { }, { .name = "authenc(hmac(sha1),cbc(des3_ede))", - .driver_name = "authenc(hmac(sha1-talitos),cbc(3des-talitos))", + .driver_name = "authenc-hmac-sha1-cbc-3des-talitos", .blocksize = TALITOS_3DES_MIN_BLOCK_SIZE, .aead = { .setkey = aead_authenc_setkey, -- cgit v0.10.2 From bd699f2df6dbc2f4cba528fe598bd63a4d3702c5 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 19:42:24 +0800 Subject: crypto: camellia - Use kernel-provided bitops, unaligned access helpers Remove the private implementation of 32-bit rotation and unaligned access with byteswapping. As a bonus, fixes sparse warnings: crypto/camellia.c:602:2: warning: cast to restricted __be32 crypto/camellia.c:603:2: warning: cast to restricted __be32 crypto/camellia.c:604:2: warning: cast to restricted __be32 crypto/camellia.c:605:2: warning: cast to restricted __be32 crypto/camellia.c:710:2: warning: cast to restricted __be32 crypto/camellia.c:711:2: warning: cast to restricted __be32 crypto/camellia.c:712:2: warning: cast to restricted __be32 crypto/camellia.c:713:2: warning: cast to restricted __be32 crypto/camellia.c:714:2: warning: cast to restricted __be32 crypto/camellia.c:715:2: warning: cast to restricted __be32 crypto/camellia.c:716:2: warning: cast to restricted __be32 crypto/camellia.c:717:2: warning: cast to restricted __be32 Signed-off-by: Harvey Harrison Signed-off-by: Herbert Xu diff --git a/crypto/camellia.c b/crypto/camellia.c index 493fee7..b1cc4de 100644 --- a/crypto/camellia.c +++ b/crypto/camellia.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include static const u32 camellia_sp1110[256] = { 0x70707000,0x82828200,0x2c2c2c00,0xececec00, @@ -335,20 +337,6 @@ static const u32 camellia_sp4404[256] = { /* * macros */ -#define GETU32(v, pt) \ - do { \ - /* latest breed of gcc is clever enough to use move */ \ - memcpy(&(v), (pt), 4); \ - (v) = be32_to_cpu(v); \ - } while(0) - -/* rotation right shift 1byte */ -#define ROR8(x) (((x) >> 8) + ((x) << 24)) -/* rotation left shift 1bit */ -#define ROL1(x) (((x) << 1) + ((x) >> 31)) -/* rotation left shift 1byte */ -#define ROL8(x) (((x) << 8) + ((x) >> 24)) - #define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ do { \ w0 = ll; \ @@ -383,7 +371,7 @@ static const u32 camellia_sp4404[256] = { ^ camellia_sp3033[(u8)(il >> 8)] \ ^ camellia_sp4404[(u8)(il )]; \ yl ^= yr; \ - yr = ROR8(yr); \ + yr = ror32(yr, 8); \ yr ^= yl; \ } while(0) @@ -405,7 +393,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) subL[7] ^= subL[1]; subR[7] ^= subR[1]; subL[1] ^= subR[1] & ~subR[9]; dw = subL[1] & subL[9], - subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */ + subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */ /* round 8 */ subL[11] ^= subL[1]; subR[11] ^= subR[1]; /* round 10 */ @@ -414,7 +402,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) subL[15] ^= subL[1]; subR[15] ^= subR[1]; subL[1] ^= subR[1] & ~subR[17]; dw = subL[1] & subL[17], - subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */ + subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */ /* round 14 */ subL[19] ^= subL[1]; subR[19] ^= subR[1]; /* round 16 */ @@ -430,7 +418,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) } else { subL[1] ^= subR[1] & ~subR[25]; dw = subL[1] & subL[25], - subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */ + subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */ /* round 20 */ subL[27] ^= subL[1]; subR[27] ^= subR[1]; /* round 22 */ @@ -450,7 +438,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) subL[26] ^= kw4l; subR[26] ^= kw4r; kw4l ^= kw4r & ~subR[24]; dw = kw4l & subL[24], - kw4r ^= ROL1(dw); /* modified for FL(kl5) */ + kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */ } /* round 17 */ subL[22] ^= kw4l; subR[22] ^= kw4r; @@ -460,7 +448,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) subL[18] ^= kw4l; subR[18] ^= kw4r; kw4l ^= kw4r & ~subR[16]; dw = kw4l & subL[16], - kw4r ^= ROL1(dw); /* modified for FL(kl3) */ + kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */ /* round 11 */ subL[14] ^= kw4l; subR[14] ^= kw4r; /* round 9 */ @@ -469,7 +457,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) subL[10] ^= kw4l; subR[10] ^= kw4r; kw4l ^= kw4r & ~subR[8]; dw = kw4l & subL[8], - kw4r ^= ROL1(dw); /* modified for FL(kl1) */ + kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */ /* round 5 */ subL[6] ^= kw4l; subR[6] ^= kw4r; /* round 3 */ @@ -494,7 +482,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) SUBKEY_R(6) = subR[5] ^ subR[7]; tl = subL[10] ^ (subR[10] & ~subR[8]); dw = tl & subL[8], /* FL(kl1) */ - tr = subR[10] ^ ROL1(dw); + tr = subR[10] ^ rol32(dw, 1); SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */ SUBKEY_R(7) = subR[6] ^ tr; SUBKEY_L(8) = subL[8]; /* FL(kl1) */ @@ -503,7 +491,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) SUBKEY_R(9) = subR[9]; tl = subL[7] ^ (subR[7] & ~subR[9]); dw = tl & subL[9], /* FLinv(kl2) */ - tr = subR[7] ^ ROL1(dw); + tr = subR[7] ^ rol32(dw, 1); SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */ SUBKEY_R(10) = tr ^ subR[11]; SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */ @@ -516,7 +504,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) SUBKEY_R(14) = subR[13] ^ subR[15]; tl = subL[18] ^ (subR[18] & ~subR[16]); dw = tl & subL[16], /* FL(kl3) */ - tr = subR[18] ^ ROL1(dw); + tr = subR[18] ^ rol32(dw, 1); SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */ SUBKEY_R(15) = subR[14] ^ tr; SUBKEY_L(16) = subL[16]; /* FL(kl3) */ @@ -525,7 +513,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) SUBKEY_R(17) = subR[17]; tl = subL[15] ^ (subR[15] & ~subR[17]); dw = tl & subL[17], /* FLinv(kl4) */ - tr = subR[15] ^ ROL1(dw); + tr = subR[15] ^ rol32(dw, 1); SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */ SUBKEY_R(18) = tr ^ subR[19]; SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */ @@ -544,7 +532,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) } else { tl = subL[26] ^ (subR[26] & ~subR[24]); dw = tl & subL[24], /* FL(kl5) */ - tr = subR[26] ^ ROL1(dw); + tr = subR[26] ^ rol32(dw, 1); SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */ SUBKEY_R(23) = subR[22] ^ tr; SUBKEY_L(24) = subL[24]; /* FL(kl5) */ @@ -553,7 +541,7 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) SUBKEY_R(25) = subR[25]; tl = subL[23] ^ (subR[23] & ~subR[25]); dw = tl & subL[25], /* FLinv(kl6) */ - tr = subR[23] ^ ROL1(dw); + tr = subR[23] ^ rol32(dw, 1); SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */ SUBKEY_R(26) = tr ^ subR[27]; SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */ @@ -573,17 +561,17 @@ static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max) /* apply the inverse of the last half of P-function */ i = 2; do { - dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */ + dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = rol32(dw, 8);/* round 1 */ SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw; - dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */ + dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = rol32(dw, 8);/* round 2 */ SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw; - dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */ + dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = rol32(dw, 8);/* round 3 */ SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw; - dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */ + dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = rol32(dw, 8);/* round 4 */ SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw; - dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */ + dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = rol32(dw, 9);/* round 5 */ SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw; - dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */ + dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = rol32(dw, 8);/* round 6 */ SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw; i += 8; } while (i < max); @@ -599,10 +587,10 @@ static void camellia_setup128(const unsigned char *key, u32 *subkey) /** * k == kll || klr || krl || krr (|| is concatenation) */ - GETU32(kll, key ); - GETU32(klr, key + 4); - GETU32(krl, key + 8); - GETU32(krr, key + 12); + kll = get_unaligned_be32(key); + klr = get_unaligned_be32(key + 4); + krl = get_unaligned_be32(key + 8); + krr = get_unaligned_be32(key + 12); /* generate KL dependent subkeys */ /* kw1 */ @@ -707,14 +695,14 @@ static void camellia_setup256(const unsigned char *key, u32 *subkey) * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) * (|| is concatenation) */ - GETU32(kll, key ); - GETU32(klr, key + 4); - GETU32(krl, key + 8); - GETU32(krr, key + 12); - GETU32(krll, key + 16); - GETU32(krlr, key + 20); - GETU32(krrl, key + 24); - GETU32(krrr, key + 28); + kll = get_unaligned_be32(key); + klr = get_unaligned_be32(key + 4); + krl = get_unaligned_be32(key + 8); + krr = get_unaligned_be32(key + 12); + krll = get_unaligned_be32(key + 16); + krlr = get_unaligned_be32(key + 20); + krrl = get_unaligned_be32(key + 24); + krrr = get_unaligned_be32(key + 28); /* generate KL dependent subkeys */ /* kw1 */ @@ -870,13 +858,13 @@ static void camellia_setup192(const unsigned char *key, u32 *subkey) t0 &= ll; \ t2 |= rr; \ rl ^= t2; \ - lr ^= ROL1(t0); \ + lr ^= rol32(t0, 1); \ t3 = krl; \ t1 = klr; \ t3 &= rl; \ t1 |= lr; \ ll ^= t1; \ - rr ^= ROL1(t3); \ + rr ^= rol32(t3, 1); \ } while(0) #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \ @@ -892,7 +880,7 @@ static void camellia_setup192(const unsigned char *key, u32 *subkey) il ^= kl; \ ir ^= il ^ kr; \ yl ^= ir; \ - yr ^= ROR8(il) ^ ir; \ + yr ^= ror32(il, 8) ^ ir; \ } while(0) /* max = 24: 128bit encrypt, max = 32: 256bit encrypt */ -- cgit v0.10.2 From b2b6a1720db65c97885ab9fc51fa23be47573bf4 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 19:45:57 +0800 Subject: crypto: rmd128 - sparse annotations Signed-off-by: Harvey Harrison Signed-off-by: Herbert Xu diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 1a481df..5de6fa2 100644 --- a/crypto/rmd128.c +++ b/crypto/rmd128.c @@ -26,7 +26,7 @@ struct rmd128_ctx { u64 byte_count; u32 state[4]; - u32 buffer[16]; + __le32 buffer[16]; }; #define K1 RMD_K1 @@ -48,7 +48,7 @@ struct rmd128_ctx { (a) = rol32((a), (s)); \ } -static void rmd128_transform(u32 *state, u32 const *in) +static void rmd128_transform(u32 *state, const __le32 *in) { u32 aa, bb, cc, dd, aaa, bbb, ccc, ddd; @@ -269,8 +269,8 @@ static void rmd128_final(struct crypto_tfm *tfm, u8 *out) { struct rmd128_ctx *rctx = crypto_tfm_ctx(tfm); u32 i, index, padlen; - u64 bits; - u32 *dst = (u32 *)out; + __le64 bits; + __le32 *dst = (__le32 *)out; static const u8 padding[64] = { 0x80, }; bits = cpu_to_le64(rctx->byte_count << 3); -- cgit v0.10.2 From caee16883a235b1b042282276859e7d5901fad21 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 4 Jul 2008 19:48:58 +0800 Subject: crypto: rmd - sparse annotations Similar to the rmd128.c annotations, significantly cuts down on the noise. Signed-off-by: Harvey Harrison Signed-off-by: Herbert Xu diff --git a/crypto/rmd160.c b/crypto/rmd160.c index e9fd5f6..f001ec7 100644 --- a/crypto/rmd160.c +++ b/crypto/rmd160.c @@ -26,7 +26,7 @@ struct rmd160_ctx { u64 byte_count; u32 state[5]; - u32 buffer[16]; + __le32 buffer[16]; }; #define K1 RMD_K1 @@ -52,7 +52,7 @@ struct rmd160_ctx { (c) = rol32((c), 10); \ } -static void rmd160_transform(u32 *state, u32 const *in) +static void rmd160_transform(u32 *state, const __le32 *in) { u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee; @@ -313,8 +313,8 @@ static void rmd160_final(struct crypto_tfm *tfm, u8 *out) { struct rmd160_ctx *rctx = crypto_tfm_ctx(tfm); u32 i, index, padlen; - u64 bits; - u32 *dst = (u32 *)out; + __le64 bits; + __le32 *dst = (__le32 *)out; static const u8 padding[64] = { 0x80, }; bits = cpu_to_le64(rctx->byte_count << 3); diff --git a/crypto/rmd256.c b/crypto/rmd256.c index b088526..e3de5b4 100644 --- a/crypto/rmd256.c +++ b/crypto/rmd256.c @@ -26,7 +26,7 @@ struct rmd256_ctx { u64 byte_count; u32 state[8]; - u32 buffer[16]; + __le32 buffer[16]; }; #define K1 RMD_K1 @@ -48,7 +48,7 @@ struct rmd256_ctx { (a) = rol32((a), (s)); \ } -static void rmd256_transform(u32 *state, u32 const *in) +static void rmd256_transform(u32 *state, const __le32 *in) { u32 aa, bb, cc, dd, aaa, bbb, ccc, ddd, tmp; @@ -288,8 +288,8 @@ static void rmd256_final(struct crypto_tfm *tfm, u8 *out) { struct rmd256_ctx *rctx = crypto_tfm_ctx(tfm); u32 i, index, padlen; - u64 bits; - u32 *dst = (u32 *)out; + __le64 bits; + __le32 *dst = (__le32 *)out; static const u8 padding[64] = { 0x80, }; bits = cpu_to_le64(rctx->byte_count << 3); diff --git a/crypto/rmd320.c b/crypto/rmd320.c index dba03ec..b143d66 100644 --- a/crypto/rmd320.c +++ b/crypto/rmd320.c @@ -26,7 +26,7 @@ struct rmd320_ctx { u64 byte_count; u32 state[10]; - u32 buffer[16]; + __le32 buffer[16]; }; #define K1 RMD_K1 @@ -52,7 +52,7 @@ struct rmd320_ctx { (c) = rol32((c), 10); \ } -static void rmd320_transform(u32 *state, u32 const *in) +static void rmd320_transform(u32 *state, const __le32 *in) { u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee, tmp; @@ -337,8 +337,8 @@ static void rmd320_final(struct crypto_tfm *tfm, u8 *out) { struct rmd320_ctx *rctx = crypto_tfm_ctx(tfm); u32 i, index, padlen; - u64 bits; - u32 *dst = (u32 *)out; + __le64 bits; + __le32 *dst = (__le32 *)out; static const u8 padding[64] = { 0x80, }; bits = cpu_to_le64(rctx->byte_count << 3); -- cgit v0.10.2 From ca786dc738f4f583b57b1bba7a335b5e8233f4b0 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 7 Jul 2008 20:23:56 +0800 Subject: crypto: hash - Fixed digest size check The digest size check on hash algorithms is incorrect. It's perfectly valid for hash algorithms to have a digest length longer than their block size. For example crc32c has a block size of 1 and a digest size of 4. Rather than having it lie about its block size, this patch fixes the checks to do what they really should which is to bound the digest size so that code placing the digest on the stack continue to work. HMAC however still needs to check this as it's only defined for such algorithms. Signed-off-by: Herbert Xu diff --git a/crypto/ahash.c b/crypto/ahash.c index a83e035..8c1f918 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -68,7 +68,7 @@ static int crypto_init_ahash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) struct ahash_alg *alg = &tfm->__crt_alg->cra_ahash; struct ahash_tfm *crt = &tfm->crt_ahash; - if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) + if (alg->digestsize > PAGE_SIZE / 8) return -EINVAL; crt->init = alg->init; diff --git a/crypto/digest.c b/crypto/digest.c index 025c9ae..d63d5d9 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -141,7 +141,7 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm) struct hash_tfm *ops = &tfm->crt_hash; struct digest_alg *dalg = &tfm->__crt_alg->cra_digest; - if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm)) + if (dalg->dia_digestsize > PAGE_SIZE / 8) return -EINVAL; ops->init = init; diff --git a/crypto/hash.c b/crypto/hash.c index f9400a0..0d7caa9 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -152,7 +152,7 @@ static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) { struct hash_alg *alg = &tfm->__crt_alg->cra_hash; - if (alg->digestsize > crypto_tfm_alg_blocksize(tfm)) + if (alg->digestsize > PAGE_SIZE / 8) return -EINVAL; if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK) diff --git a/crypto/hmac.c b/crypto/hmac.c index 14c6351..7ff2d6a 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -226,6 +226,7 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) struct crypto_instance *inst; struct crypto_alg *alg; int err; + int ds; err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH); if (err) @@ -236,6 +237,13 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) if (IS_ERR(alg)) return ERR_CAST(alg); + inst = ERR_PTR(-EINVAL); + ds = (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == + CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize : + alg->cra_digest.dia_digestsize; + if (ds > alg->cra_blocksize) + goto out_put_alg; + inst = crypto_alloc_instance("hmac", alg); if (IS_ERR(inst)) goto out_put_alg; @@ -246,14 +254,10 @@ static struct crypto_instance *hmac_alloc(struct rtattr **tb) inst->alg.cra_alignmask = alg->cra_alignmask; inst->alg.cra_type = &crypto_hash_type; - inst->alg.cra_hash.digestsize = - (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == - CRYPTO_ALG_TYPE_HASH ? alg->cra_hash.digestsize : - alg->cra_digest.dia_digestsize; + inst->alg.cra_hash.digestsize = ds; inst->alg.cra_ctxsize = sizeof(struct hmac_ctx) + - ALIGN(inst->alg.cra_blocksize * 2 + - inst->alg.cra_hash.digestsize, + ALIGN(inst->alg.cra_blocksize * 2 + ds, sizeof(void *)); inst->alg.cra_init = hmac_init_tfm; -- cgit v0.10.2 From 166247f46a9c866e6f7f7d2212be875fb82212a1 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 7 Jul 2008 20:54:35 +0800 Subject: crypto: hash - Removed vestigial ahash fields The base field in ahash_tfm appears to have been cut-n-pasted from ablkcipher. It isn't needed here at all. Similarly, the info field in ahash_request also appears to have originated from its cipher counter-part and is vestigial. Signed-off-by: Herbert Xu diff --git a/crypto/ahash.c b/crypto/ahash.c index 8c1f918..e6e5906 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -76,7 +76,6 @@ static int crypto_init_ahash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) crt->final = alg->final; crt->digest = alg->digest; crt->setkey = ahash_setkey; - crt->base = __crypto_ahash_cast(tfm); crt->digestsize = alg->digestsize; return 0; diff --git a/crypto/digest.c b/crypto/digest.c index d63d5d9..bf33298 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -234,7 +234,6 @@ int crypto_init_digest_ops_async(struct crypto_tfm *tfm) crt->setkey = dalg->dia_setkey ? digest_async_setkey : digest_async_nosetkey; crt->digestsize = dalg->dia_digestsize; - crt->base = __crypto_ahash_cast(tfm); return 0; } diff --git a/crypto/hash.c b/crypto/hash.c index 0d7caa9..140a755 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -128,7 +128,6 @@ static int crypto_init_hash_ops_async(struct crypto_tfm *tfm) crt->digest = hash_async_digest; crt->setkey = hash_async_setkey; crt->digestsize = alg->digestsize; - crt->base = __crypto_ahash_cast(tfm); return 0; } diff --git a/include/linux/crypto.h b/include/linux/crypto.h index b6efe56..68ef293 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -137,8 +137,6 @@ struct ablkcipher_request { struct ahash_request { struct crypto_async_request base; - void *info; - unsigned int nbytes; struct scatterlist *src; u8 *result; @@ -420,7 +418,6 @@ struct ahash_tfm { unsigned int keylen); unsigned int digestsize; - struct crypto_ahash *base; unsigned int reqsize; }; @@ -1384,7 +1381,7 @@ static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, { struct ahash_tfm *crt = crypto_ahash_crt(tfm); - return crt->setkey(crt->base, key, keylen); + return crt->setkey(tfm, key, keylen); } static inline int crypto_ahash_digest(struct ahash_request *req) @@ -1396,7 +1393,7 @@ static inline int crypto_ahash_digest(struct ahash_request *req) static inline void ahash_request_set_tfm(struct ahash_request *req, struct crypto_ahash *tfm) { - req->base.tfm = crypto_ahash_tfm(crypto_ahash_crt(tfm)->base); + req->base.tfm = crypto_ahash_tfm(tfm); } static inline struct ahash_request *ahash_request_alloc( -- cgit v0.10.2 From b8454eebe380677789735fd6bad368af2e6b2d1e Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 7 Jul 2008 22:41:31 +0800 Subject: crypto: prng - Deterministic CPRNG This patch adds a cryptographic pseudo-random number generator based on CTR(AES-128). It is meant to be used in cases where a deterministic CPRNG is required. One of the first applications will be as an input in the IPsec IV generation process. Signed-off-by: Neil Horman Signed-off-by: Herbert Xu diff --git a/crypto/Kconfig b/crypto/Kconfig index 795e31c..43b7473 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -666,6 +666,15 @@ config CRYPTO_LZO help This is the LZO algorithm. +comment "Random Number Generation" + +config CRYPTO_PRNG + tristate "Pseudo Random Number Generation for Cryptographic modules" + help + This option enables the generic pseudo random number generator + for cryptographic modules. Uses the Algorithm specified in + ANSI X9.31 A.2.4 + source "drivers/crypto/Kconfig" endif # if CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index d4f3ed8..ef61b3b 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -69,7 +69,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o obj-$(CONFIG_CRYPTO_LZO) += lzo.o - +obj-$(CONFIG_CRYPTO_PRNG) += prng.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o # diff --git a/crypto/prng.c b/crypto/prng.c new file mode 100644 index 0000000..24e4f32 --- /dev/null +++ b/crypto/prng.c @@ -0,0 +1,410 @@ +/* + * PRNG: Pseudo Random Number Generator + * Based on NIST Recommended PRNG From ANSI X9.31 Appendix A.2.4 using + * AES 128 cipher in RFC3686 ctr mode + * + * (C) Neil Horman + * + * 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 + * any later version. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "prng.h" + +#define TEST_PRNG_ON_START 0 + +#define DEFAULT_PRNG_KEY "0123456789abcdef1011" +#define DEFAULT_PRNG_KSZ 20 +#define DEFAULT_PRNG_IV "defaultv" +#define DEFAULT_PRNG_IVSZ 8 +#define DEFAULT_BLK_SZ 16 +#define DEFAULT_V_SEED "zaybxcwdveuftgsh" + +/* + * Flags for the prng_context flags field + */ + +#define PRNG_FIXED_SIZE 0x1 +#define PRNG_NEED_RESET 0x2 + +/* + * Note: DT is our counter value + * I is our intermediate value + * V is our seed vector + * See http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf + * for implementation details + */ + + +struct prng_context { + char *prng_key; + char *prng_iv; + spinlock_t prng_lock; + unsigned char rand_data[DEFAULT_BLK_SZ]; + unsigned char last_rand_data[DEFAULT_BLK_SZ]; + unsigned char DT[DEFAULT_BLK_SZ]; + unsigned char I[DEFAULT_BLK_SZ]; + unsigned char V[DEFAULT_BLK_SZ]; + u32 rand_data_valid; + struct crypto_blkcipher *tfm; + u32 flags; +}; + +static int dbg; + +static void hexdump(char *note, unsigned char *buf, unsigned int len) +{ + if (dbg) { + printk(KERN_CRIT "%s", note); + print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, + 16, 1, + buf, len, false); + } +} + +#define dbgprint(format, args...) do {if(dbg) printk(format, ##args);} while(0) + +static void xor_vectors(unsigned char *in1, unsigned char *in2, + unsigned char *out, unsigned int size) +{ + int i; + + for (i=0;itfm; + desc.flags = 0; + + + dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",ctx); + + hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ); + hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ); + hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ); + + /* + * This algorithm is a 3 stage state machine + */ + for (i=0;i<3;i++) { + + desc.tfm = ctx->tfm; + desc.flags = 0; + switch (i) { + case 0: + /* + * Start by encrypting the counter value + * This gives us an intermediate value I + */ + memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ); + sg_init_one(&sg_out, &ctx->I[0], DEFAULT_BLK_SZ); + hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ); + break; + case 1: + + /* + * Next xor I with our secret vector V + * encrypt that result to obtain our + * pseudo random data which we output + */ + xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ); + sg_init_one(&sg_out, &ctx->rand_data[0], DEFAULT_BLK_SZ); + hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ); + break; + case 2: + /* + * First check that we didn't produce the same random data + * that we did last time around through this + */ + if (!memcmp(ctx->rand_data, ctx->last_rand_data, DEFAULT_BLK_SZ)) { + printk(KERN_ERR "ctx %p Failed repetition check!\n", + ctx); + ctx->flags |= PRNG_NEED_RESET; + return -1; + } + memcpy(ctx->last_rand_data, ctx->rand_data, DEFAULT_BLK_SZ); + + /* + * Lastly xor the random data with I + * and encrypt that to obtain a new secret vector V + */ + xor_vectors(ctx->rand_data, ctx->I, tmp, DEFAULT_BLK_SZ); + sg_init_one(&sg_out, &ctx->V[0], DEFAULT_BLK_SZ); + hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ); + break; + } + + /* Initialize our input buffer */ + sg_init_one(&sg_in, &tmp[0], DEFAULT_BLK_SZ); + + /* do the encryption */ + ret = crypto_blkcipher_encrypt(&desc, &sg_out, &sg_in, DEFAULT_BLK_SZ); + + /* And check the result */ + if (ret) { + dbgprint(KERN_CRIT "Encryption of new block failed for context %p\n",ctx); + ctx->rand_data_valid = DEFAULT_BLK_SZ; + return -1; + } + + } + + /* + * Now update our DT value + */ + for (i=DEFAULT_BLK_SZ-1;i>0;i--) { + ctx->DT[i] = ctx->DT[i-1]; + } + ctx->DT[0] += 1; + + dbgprint("Returning new block for context %p\n",ctx); + ctx->rand_data_valid = 0; + + hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ); + hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ); + hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ); + hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ); + + return 0; +} + +/* Our exported functions */ +int get_prng_bytes(char *buf, int nbytes, struct prng_context *ctx) +{ + unsigned long flags; + unsigned char *ptr = buf; + unsigned int byte_count = (unsigned int)nbytes; + int err; + + + if (nbytes < 0) + return -EINVAL; + + spin_lock_irqsave(&ctx->prng_lock, flags); + + err = -EFAULT; + if (ctx->flags & PRNG_NEED_RESET) + goto done; + + /* + * If the FIXED_SIZE flag is on, only return whole blocks of + * pseudo random data + */ + err = -EINVAL; + if (ctx->flags & PRNG_FIXED_SIZE) { + if (nbytes < DEFAULT_BLK_SZ) + goto done; + byte_count = DEFAULT_BLK_SZ; + } + + err = byte_count; + + dbgprint(KERN_CRIT "getting %d random bytes for context %p\n",byte_count, ctx); + + +remainder: + if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { + if (_get_more_prng_bytes(ctx) < 0) { + memset(buf, 0, nbytes); + err = -EFAULT; + goto done; + } + } + + /* + * Copy up to the next whole block size + */ + if (byte_count < DEFAULT_BLK_SZ) { + for (;ctx->rand_data_valid < DEFAULT_BLK_SZ; ctx->rand_data_valid++) { + *ptr = ctx->rand_data[ctx->rand_data_valid]; + ptr++; + byte_count--; + if (byte_count == 0) + goto done; + } + } + + /* + * Now copy whole blocks + */ + for(;byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { + if (_get_more_prng_bytes(ctx) < 0) { + memset(buf, 0, nbytes); + err = -1; + goto done; + } + memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ); + ctx->rand_data_valid += DEFAULT_BLK_SZ; + ptr += DEFAULT_BLK_SZ; + } + + /* + * Now copy any extra partial data + */ + if (byte_count) + goto remainder; + +done: + spin_unlock_irqrestore(&ctx->prng_lock, flags); + dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",err, ctx); + return err; +} +EXPORT_SYMBOL_GPL(get_prng_bytes); + +struct prng_context *alloc_prng_context(void) +{ + struct prng_context *ctx=kzalloc(sizeof(struct prng_context), GFP_KERNEL); + + spin_lock_init(&ctx->prng_lock); + + if (reset_prng_context(ctx, NULL, NULL, NULL, NULL)) { + kfree(ctx); + ctx = NULL; + } + + dbgprint(KERN_CRIT "returning context %p\n",ctx); + return ctx; +} + +EXPORT_SYMBOL_GPL(alloc_prng_context); + +void free_prng_context(struct prng_context *ctx) +{ + crypto_free_blkcipher(ctx->tfm); + kfree(ctx); +} +EXPORT_SYMBOL_GPL(free_prng_context); + +int reset_prng_context(struct prng_context *ctx, + unsigned char *key, unsigned char *iv, + unsigned char *V, unsigned char *DT) +{ + int ret; + int iv_len; + int rc = -EFAULT; + + spin_lock(&ctx->prng_lock); + ctx->flags |= PRNG_NEED_RESET; + + if (key) + memcpy(ctx->prng_key,key,strlen(ctx->prng_key)); + else + ctx->prng_key = DEFAULT_PRNG_KEY; + + if (iv) + memcpy(ctx->prng_iv,iv, strlen(ctx->prng_iv)); + else + ctx->prng_iv = DEFAULT_PRNG_IV; + + if (V) + memcpy(ctx->V,V,DEFAULT_BLK_SZ); + else + memcpy(ctx->V,DEFAULT_V_SEED,DEFAULT_BLK_SZ); + + if (DT) + memcpy(ctx->DT, DT, DEFAULT_BLK_SZ); + else + memset(ctx->DT, 0, DEFAULT_BLK_SZ); + + memset(ctx->rand_data,0,DEFAULT_BLK_SZ); + memset(ctx->last_rand_data,0,DEFAULT_BLK_SZ); + + if (ctx->tfm) + crypto_free_blkcipher(ctx->tfm); + + ctx->tfm = crypto_alloc_blkcipher("rfc3686(ctr(aes))",0,0); + if (!ctx->tfm) { + dbgprint(KERN_CRIT "Failed to alloc crypto tfm for context %p\n",ctx->tfm); + goto out; + } + + ctx->rand_data_valid = DEFAULT_BLK_SZ; + + ret = crypto_blkcipher_setkey(ctx->tfm, ctx->prng_key, strlen(ctx->prng_key)); + if (ret) { + dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n", + crypto_blkcipher_get_flags(ctx->tfm)); + crypto_free_blkcipher(ctx->tfm); + goto out; + } + + iv_len = crypto_blkcipher_ivsize(ctx->tfm); + if (iv_len) { + crypto_blkcipher_set_iv(ctx->tfm, ctx->prng_iv, iv_len); + } + rc = 0; + ctx->flags &= ~PRNG_NEED_RESET; +out: + spin_unlock(&ctx->prng_lock); + + return rc; + +} +EXPORT_SYMBOL_GPL(reset_prng_context); + +/* Module initalization */ +static int __init prng_mod_init(void) +{ + +#ifdef TEST_PRNG_ON_START + int i; + unsigned char tmpbuf[DEFAULT_BLK_SZ]; + + struct prng_context *ctx = alloc_prng_context(); + if (ctx == NULL) + return -EFAULT; + for (i=0;i<16;i++) { + if (get_prng_bytes(tmpbuf, DEFAULT_BLK_SZ, ctx) < 0) { + free_prng_context(ctx); + return -EFAULT; + } + } + free_prng_context(ctx); +#endif + + return 0; +} + +static void __exit prng_mod_fini(void) +{ + return; +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Software Pseudo Random Number Generator"); +MODULE_AUTHOR("Neil Horman "); +module_param(dbg, int, 0); +MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)"); +module_init(prng_mod_init); +module_exit(prng_mod_fini); diff --git a/crypto/prng.h b/crypto/prng.h new file mode 100644 index 0000000..1ac9be5 --- /dev/null +++ b/crypto/prng.h @@ -0,0 +1,27 @@ +/* + * PRNG: Pseudo Random Number Generator + * + * (C) Neil Horman + * + * 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 + * any later version. + * + * + */ + +#ifndef _PRNG_H_ +#define _PRNG_H_ +struct prng_context; + +int get_prng_bytes(char *buf, int nbytes, struct prng_context *ctx); +struct prng_context *alloc_prng_context(void); +int reset_prng_context(struct prng_context *ctx, + unsigned char *key, unsigned char *iv, + unsigned char *V, + unsigned char *DT); +void free_prng_context(struct prng_context *ctx); + +#endif + -- cgit v0.10.2 From 20036252fc61c624a49770fb89684ea5cfdfa05e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 7 Jul 2008 22:19:53 +0800 Subject: crypto: hash - Added scatter list walking helper This patch adds the walking helpers for hash algorithms akin to those of block ciphers. This is a necessary step before we can reimplement existing hash algorithms using the new ahash interface. Signed-off-by: Herbert Xu diff --git a/crypto/ahash.c b/crypto/ahash.c index e6e5906..27128f2 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -13,7 +13,8 @@ * */ -#include +#include +#include #include #include #include @@ -23,6 +24,94 @@ #include "internal.h" +static int hash_walk_next(struct crypto_hash_walk *walk) +{ + unsigned int alignmask = walk->alignmask; + unsigned int offset = walk->offset; + unsigned int nbytes = min(walk->entrylen, + ((unsigned int)(PAGE_SIZE)) - offset); + + walk->data = crypto_kmap(walk->pg, 0); + walk->data += offset; + + if (offset & alignmask) + nbytes = alignmask + 1 - (offset & alignmask); + + walk->entrylen -= nbytes; + return nbytes; +} + +static int hash_walk_new_entry(struct crypto_hash_walk *walk) +{ + struct scatterlist *sg; + + sg = walk->sg; + walk->pg = sg_page(sg); + walk->offset = sg->offset; + walk->entrylen = sg->length; + + if (walk->entrylen > walk->total) + walk->entrylen = walk->total; + walk->total -= walk->entrylen; + + return hash_walk_next(walk); +} + +int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) +{ + unsigned int alignmask = walk->alignmask; + unsigned int nbytes = walk->entrylen; + + walk->data -= walk->offset; + + if (nbytes && walk->offset & alignmask && !err) { + walk->offset += alignmask - 1; + walk->offset = ALIGN(walk->offset, alignmask + 1); + walk->data += walk->offset; + + nbytes = min(nbytes, + ((unsigned int)(PAGE_SIZE)) - walk->offset); + walk->entrylen -= nbytes; + + return nbytes; + } + + crypto_kunmap(walk->data, 0); + crypto_yield(walk->flags); + + if (err) + return err; + + walk->offset = 0; + + if (nbytes) + return hash_walk_next(walk); + + if (!walk->total) + return 0; + + walk->sg = scatterwalk_sg_next(walk->sg); + + return hash_walk_new_entry(walk); +} +EXPORT_SYMBOL_GPL(crypto_hash_walk_done); + +int crypto_hash_walk_first(struct ahash_request *req, + struct crypto_hash_walk *walk) +{ + walk->total = req->nbytes; + + if (!walk->total) + return 0; + + walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req)); + walk->sg = req->src; + walk->flags = req->base.flags; + + return hash_walk_new_entry(walk); +} +EXPORT_SYMBOL_GPL(crypto_hash_walk_first); + static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) { diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h new file mode 100644 index 0000000..93ac422 --- /dev/null +++ b/include/crypto/internal/hash.h @@ -0,0 +1,41 @@ +/* + * Hash algorithms. + * + * Copyright (c) 2008 Herbert Xu + * + * 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 _CRYPTO_INTERNAL_HASH_H +#define _CRYPTO_INTERNAL_HASH_H + +#include + +struct ahash_request; +struct scatterlist; + +struct crypto_hash_walk { + char *data; + + unsigned int offset; + unsigned int alignmask; + + struct page *pg; + unsigned int entrylen; + + unsigned int total; + struct scatterlist *sg; + + unsigned int flags; +}; + +int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); +int crypto_hash_walk_first(struct ahash_request *req, + struct crypto_hash_walk *walk); + +#endif /* _CRYPTO_INTERNAL_HASH_H */ + -- cgit v0.10.2 From 5773a3e6e396d5fd9de58372abe6a86b7e258e3e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 8 Jul 2008 20:54:28 +0800 Subject: crypto: crc32c - Add ahash implementation This patch reimplements crc32c using the ahash interface. This allows one tfm to be used by an unlimited number of users provided that they all use the same key (which all current crc32c users do). Signed-off-by: Herbert Xu diff --git a/crypto/Kconfig b/crypto/Kconfig index 43b7473..ea50357 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -213,7 +213,7 @@ comment "Digest" config CRYPTO_CRC32C tristate "CRC32c CRC algorithm" - select CRYPTO_ALGAPI + select CRYPTO_HASH select LIBCRC32C help Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used diff --git a/crypto/crc32c.c b/crypto/crc32c.c index 0dcf64a..a882d9e 100644 --- a/crypto/crc32c.c +++ b/crypto/crc32c.c @@ -5,20 +5,23 @@ * * This module file is a wrapper to invoke the lib/crc32c routines. * + * Copyright (c) 2008 Herbert Xu + * * 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 #include #include #include -#include #include #include -#define CHKSUM_BLOCK_SIZE 32 +#define CHKSUM_BLOCK_SIZE 1 #define CHKSUM_DIGEST_SIZE 4 struct chksum_ctx { @@ -71,7 +74,7 @@ static void chksum_final(struct crypto_tfm *tfm, u8 *out) *(__le32 *)out = ~cpu_to_le32(mctx->crc); } -static int crc32c_cra_init(struct crypto_tfm *tfm) +static int crc32c_cra_init_old(struct crypto_tfm *tfm) { struct chksum_ctx *mctx = crypto_tfm_ctx(tfm); @@ -79,14 +82,14 @@ static int crc32c_cra_init(struct crypto_tfm *tfm) return 0; } -static struct crypto_alg alg = { +static struct crypto_alg old_alg = { .cra_name = "crc32c", .cra_flags = CRYPTO_ALG_TYPE_DIGEST, .cra_blocksize = CHKSUM_BLOCK_SIZE, .cra_ctxsize = sizeof(struct chksum_ctx), .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(alg.cra_list), - .cra_init = crc32c_cra_init, + .cra_list = LIST_HEAD_INIT(old_alg.cra_list), + .cra_init = crc32c_cra_init_old, .cra_u = { .digest = { .dia_digestsize= CHKSUM_DIGEST_SIZE, @@ -98,14 +101,125 @@ static struct crypto_alg alg = { } }; +/* + * Setting the seed allows arbitrary accumulators and flexible XOR policy + * If your algorithm starts with ~0, then XOR with ~0 before you set + * the seed. + */ +static int crc32c_setkey(struct crypto_ahash *hash, const u8 *key, + unsigned int keylen) +{ + u32 *mctx = crypto_ahash_ctx(hash); + + if (keylen != sizeof(u32)) { + crypto_ahash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + *mctx = le32_to_cpup((__le32 *)key); + return 0; +} + +static int crc32c_init(struct ahash_request *req) +{ + u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); + u32 *crcp = ahash_request_ctx(req); + + *crcp = *mctx; + return 0; +} + +static int crc32c_update(struct ahash_request *req) +{ + struct crypto_hash_walk walk; + u32 *crcp = ahash_request_ctx(req); + u32 crc = *crcp; + int nbytes; + + for (nbytes = crypto_hash_walk_first(req, &walk); nbytes; + nbytes = crypto_hash_walk_done(&walk, 0)) + crc = crc32c(crc, walk.data, nbytes); + + *crcp = crc; + return 0; +} + +static int crc32c_final(struct ahash_request *req) +{ + u32 *crcp = ahash_request_ctx(req); + + *(__le32 *)req->result = ~cpu_to_le32p(crcp); + return 0; +} + +static int crc32c_digest(struct ahash_request *req) +{ + struct crypto_hash_walk walk; + u32 *mctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); + u32 crc = *mctx; + int nbytes; + + for (nbytes = crypto_hash_walk_first(req, &walk); nbytes; + nbytes = crypto_hash_walk_done(&walk, 0)) + crc = crc32c(crc, walk.data, nbytes); + + *(__le32 *)req->result = ~cpu_to_le32(crc); + return 0; +} + +static int crc32c_cra_init(struct crypto_tfm *tfm) +{ + u32 *key = crypto_tfm_ctx(tfm); + + *key = ~0; + + tfm->crt_ahash.reqsize = sizeof(u32); + + return 0; +} + +static struct crypto_alg alg = { + .cra_name = "crc32c", + .cra_driver_name = "crc32c-generic", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_blocksize = CHKSUM_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_ctxsize = sizeof(u32), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg.cra_list), + .cra_init = crc32c_cra_init, + .cra_type = &crypto_ahash_type, + .cra_u = { + .ahash = { + .digestsize = CHKSUM_DIGEST_SIZE, + .setkey = crc32c_setkey, + .init = crc32c_init, + .update = crc32c_update, + .final = crc32c_final, + .digest = crc32c_digest, + } + } +}; + static int __init crc32c_mod_init(void) { - return crypto_register_alg(&alg); + int err; + + err = crypto_register_alg(&old_alg); + if (err) + return err; + + err = crypto_register_alg(&alg); + if (err) + crypto_unregister_alg(&old_alg); + + return err; } static void __exit crc32c_mod_fini(void) { crypto_unregister_alg(&alg); + crypto_unregister_alg(&old_alg); } module_init(crc32c_mod_init); -- cgit v0.10.2 From 18e33e6d5cc0495826f5245777cd267732815e01 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 10 Jul 2008 16:01:22 +0800 Subject: crypto: hash - Move ahash functions into crypto/hash.h All new crypto interfaces should go into individual files as much as possible in order to ensure that crypto.h does not collapse under its own weight. This patch moves the ahash code into crypto/hash.h and crypto/internal/hash.h respectively. Signed-off-by: Herbert Xu diff --git a/crypto/cryptd.c b/crypto/cryptd.c index d3ecd7e..d29e06b 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/crypto/digest.c b/crypto/digest.c index bf33298..ac09194 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -12,6 +12,7 @@ * */ +#include #include #include #include diff --git a/crypto/hash.c b/crypto/hash.c index 140a755..cb86b19 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -9,6 +9,7 @@ * any later version. */ +#include #include #include #include diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 87f08f9..59821a2 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -15,6 +15,7 @@ * */ +#include #include #include #include diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index fef272a..60d06e7 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -98,7 +98,6 @@ extern const struct crypto_type crypto_ablkcipher_type; extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; extern const struct crypto_type crypto_hash_type; -extern const struct crypto_type crypto_ahash_type; void crypto_mod_put(struct crypto_alg *alg); @@ -315,40 +314,5 @@ static inline int crypto_requires_sync(u32 type, u32 mask) return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC; } -static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm) -{ - return crypto_tfm_ctx(&tfm->base); -} - -static inline struct ahash_alg *crypto_ahash_alg( - struct crypto_ahash *tfm) -{ - return &crypto_ahash_tfm(tfm)->__crt_alg->cra_ahash; -} - -static inline int ahash_enqueue_request(struct crypto_queue *queue, - struct ahash_request *request) -{ - return crypto_enqueue_request(queue, &request->base); -} - -static inline struct ahash_request *ahash_dequeue_request( - struct crypto_queue *queue) -{ - return ahash_request_cast(crypto_dequeue_request(queue)); -} - -static inline void *ahash_request_ctx(struct ahash_request *req) -{ - return req->__ctx; -} - -static inline int ahash_tfm_in_queue(struct crypto_queue *queue, - struct crypto_ahash *tfm) -{ - return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm)); -} - - #endif /* _CRYPTO_ALGAPI_H */ diff --git a/include/crypto/hash.h b/include/crypto/hash.h new file mode 100644 index 0000000..d12498e --- /dev/null +++ b/include/crypto/hash.h @@ -0,0 +1,154 @@ +/* + * Hash: Hash algorithms under the crypto API + * + * Copyright (c) 2008 Herbert Xu + * + * 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 _CRYPTO_HASH_H +#define _CRYPTO_HASH_H + +#include + +struct crypto_ahash { + struct crypto_tfm base; +}; + +static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) +{ + return (struct crypto_ahash *)tfm; +} + +static inline struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, + u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + mask &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_AHASH; + mask |= CRYPTO_ALG_TYPE_AHASH_MASK; + + return __crypto_ahash_cast(crypto_alloc_base(alg_name, type, mask)); +} + +static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) +{ + return &tfm->base; +} + +static inline void crypto_free_ahash(struct crypto_ahash *tfm) +{ + crypto_free_tfm(crypto_ahash_tfm(tfm)); +} + +static inline unsigned int crypto_ahash_alignmask( + struct crypto_ahash *tfm) +{ + return crypto_tfm_alg_alignmask(crypto_ahash_tfm(tfm)); +} + +static inline struct ahash_tfm *crypto_ahash_crt(struct crypto_ahash *tfm) +{ + return &crypto_ahash_tfm(tfm)->crt_ahash; +} + +static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm) +{ + return crypto_ahash_crt(tfm)->digestsize; +} + +static inline u32 crypto_ahash_get_flags(struct crypto_ahash *tfm) +{ + return crypto_tfm_get_flags(crypto_ahash_tfm(tfm)); +} + +static inline void crypto_ahash_set_flags(struct crypto_ahash *tfm, u32 flags) +{ + crypto_tfm_set_flags(crypto_ahash_tfm(tfm), flags); +} + +static inline void crypto_ahash_clear_flags(struct crypto_ahash *tfm, u32 flags) +{ + crypto_tfm_clear_flags(crypto_ahash_tfm(tfm), flags); +} + +static inline struct crypto_ahash *crypto_ahash_reqtfm( + struct ahash_request *req) +{ + return __crypto_ahash_cast(req->base.tfm); +} + +static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) +{ + return crypto_ahash_crt(tfm)->reqsize; +} + +static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, + const u8 *key, unsigned int keylen) +{ + struct ahash_tfm *crt = crypto_ahash_crt(tfm); + + return crt->setkey(tfm, key, keylen); +} + +static inline int crypto_ahash_digest(struct ahash_request *req) +{ + struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); + return crt->digest(req); +} + +static inline void ahash_request_set_tfm(struct ahash_request *req, + struct crypto_ahash *tfm) +{ + req->base.tfm = crypto_ahash_tfm(tfm); +} + +static inline struct ahash_request *ahash_request_alloc( + struct crypto_ahash *tfm, gfp_t gfp) +{ + struct ahash_request *req; + + req = kmalloc(sizeof(struct ahash_request) + + crypto_ahash_reqsize(tfm), gfp); + + if (likely(req)) + ahash_request_set_tfm(req, tfm); + + return req; +} + +static inline void ahash_request_free(struct ahash_request *req) +{ + kfree(req); +} + +static inline struct ahash_request *ahash_request_cast( + struct crypto_async_request *req) +{ + return container_of(req, struct ahash_request, base); +} + +static inline void ahash_request_set_callback(struct ahash_request *req, + u32 flags, + crypto_completion_t complete, + void *data) +{ + req->base.complete = complete; + req->base.data = data; + req->base.flags = flags; +} + +static inline void ahash_request_set_crypt(struct ahash_request *req, + struct scatterlist *src, u8 *result, + unsigned int nbytes) +{ + req->src = src; + req->nbytes = nbytes; + req->result = result; +} + +#endif /* _CRYPTO_HASH_H */ diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 93ac422..917ae57 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -14,6 +14,7 @@ #define _CRYPTO_INTERNAL_HASH_H #include +#include struct ahash_request; struct scatterlist; @@ -33,9 +34,45 @@ struct crypto_hash_walk { unsigned int flags; }; +extern const struct crypto_type crypto_ahash_type; + int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err); int crypto_hash_walk_first(struct ahash_request *req, struct crypto_hash_walk *walk); +static inline void *crypto_ahash_ctx(struct crypto_ahash *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} + +static inline struct ahash_alg *crypto_ahash_alg( + struct crypto_ahash *tfm) +{ + return &crypto_ahash_tfm(tfm)->__crt_alg->cra_ahash; +} + +static inline int ahash_enqueue_request(struct crypto_queue *queue, + struct ahash_request *request) +{ + return crypto_enqueue_request(queue, &request->base); +} + +static inline struct ahash_request *ahash_dequeue_request( + struct crypto_queue *queue) +{ + return ahash_request_cast(crypto_dequeue_request(queue)); +} + +static inline void *ahash_request_ctx(struct ahash_request *req) +{ + return req->__ctx; +} + +static inline int ahash_tfm_in_queue(struct crypto_queue *queue, + struct crypto_ahash *tfm) +{ + return crypto_tfm_in_queue(queue, crypto_ahash_tfm(tfm)); +} + #endif /* _CRYPTO_INTERNAL_HASH_H */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 68ef293..c43dc47 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -481,10 +481,6 @@ struct crypto_hash { struct crypto_tfm base; }; -struct crypto_ahash { - struct crypto_tfm base; -}; - enum { CRYPTOA_UNSPEC, CRYPTOA_ALG, @@ -1308,137 +1304,5 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm, src, slen, dst, dlen); } -static inline struct crypto_ahash *__crypto_ahash_cast(struct crypto_tfm *tfm) -{ - return (struct crypto_ahash *)tfm; -} - -static inline struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, - u32 type, u32 mask) -{ - type &= ~CRYPTO_ALG_TYPE_MASK; - mask &= ~CRYPTO_ALG_TYPE_MASK; - type |= CRYPTO_ALG_TYPE_AHASH; - mask |= CRYPTO_ALG_TYPE_AHASH_MASK; - - return __crypto_ahash_cast(crypto_alloc_base(alg_name, type, mask)); -} - -static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) -{ - return &tfm->base; -} - -static inline void crypto_free_ahash(struct crypto_ahash *tfm) -{ - crypto_free_tfm(crypto_ahash_tfm(tfm)); -} - -static inline unsigned int crypto_ahash_alignmask( - struct crypto_ahash *tfm) -{ - return crypto_tfm_alg_alignmask(crypto_ahash_tfm(tfm)); -} - -static inline struct ahash_tfm *crypto_ahash_crt(struct crypto_ahash *tfm) -{ - return &crypto_ahash_tfm(tfm)->crt_ahash; -} - -static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm) -{ - return crypto_ahash_crt(tfm)->digestsize; -} - -static inline u32 crypto_ahash_get_flags(struct crypto_ahash *tfm) -{ - return crypto_tfm_get_flags(crypto_ahash_tfm(tfm)); -} - -static inline void crypto_ahash_set_flags(struct crypto_ahash *tfm, u32 flags) -{ - crypto_tfm_set_flags(crypto_ahash_tfm(tfm), flags); -} - -static inline void crypto_ahash_clear_flags(struct crypto_ahash *tfm, u32 flags) -{ - crypto_tfm_clear_flags(crypto_ahash_tfm(tfm), flags); -} - -static inline struct crypto_ahash *crypto_ahash_reqtfm( - struct ahash_request *req) -{ - return __crypto_ahash_cast(req->base.tfm); -} - -static inline unsigned int crypto_ahash_reqsize(struct crypto_ahash *tfm) -{ - return crypto_ahash_crt(tfm)->reqsize; -} - -static inline int crypto_ahash_setkey(struct crypto_ahash *tfm, - const u8 *key, unsigned int keylen) -{ - struct ahash_tfm *crt = crypto_ahash_crt(tfm); - - return crt->setkey(tfm, key, keylen); -} - -static inline int crypto_ahash_digest(struct ahash_request *req) -{ - struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req)); - return crt->digest(req); -} - -static inline void ahash_request_set_tfm(struct ahash_request *req, - struct crypto_ahash *tfm) -{ - req->base.tfm = crypto_ahash_tfm(tfm); -} - -static inline struct ahash_request *ahash_request_alloc( - struct crypto_ahash *tfm, gfp_t gfp) -{ - struct ahash_request *req; - - req = kmalloc(sizeof(struct ahash_request) + - crypto_ahash_reqsize(tfm), gfp); - - if (likely(req)) - ahash_request_set_tfm(req, tfm); - - return req; -} - -static inline void ahash_request_free(struct ahash_request *req) -{ - kfree(req); -} - -static inline struct ahash_request *ahash_request_cast( - struct crypto_async_request *req) -{ - return container_of(req, struct ahash_request, base); -} - -static inline void ahash_request_set_callback(struct ahash_request *req, - u32 flags, - crypto_completion_t complete, - void *data) -{ - req->base.complete = complete; - req->base.data = data; - req->base.flags = flags; -} - -static inline void ahash_request_set_crypt(struct ahash_request *req, - struct scatterlist *src, u8 *result, - unsigned int nbytes) -{ - req->src = src; - req->nbytes = nbytes; - req->result = result; -} - #endif /* _LINUX_CRYPTO_H */ -- cgit v0.10.2 From 3952f17ed63434cc2154c3765ff97e1d4adab042 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Thu, 10 Jul 2008 18:29:18 +0800 Subject: crypto: talitos - Add support for sha256 and md5 variants This patch adds support for: authenc(hmac(sha256),cbc(aes)), authenc(hmac(sha256),cbc(des3_ede)), authenc(hmac(md5),cbc(aes)), authenc(hmac(md5),cbc(des3_ede)). Some constant usage was changed to use aes, des, and sha include files. Signed-off-by: Lee Nipper Signed-off-by: Herbert Xu diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 8c270cd..b11943d 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -640,13 +641,9 @@ static void talitos_unregister_rng(struct device *dev) */ #define TALITOS_CRA_PRIORITY 3000 #define TALITOS_MAX_KEY_SIZE 64 -#define TALITOS_MAX_AUTH_SIZE 20 -#define TALITOS_AES_MIN_BLOCK_SIZE 16 -#define TALITOS_3DES_MIN_BLOCK_SIZE 24 +#define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ -#define TALITOS_AES_IV_LENGTH 16 -#define TALITOS_3DES_IV_LENGTH 8 -#define TALITOS_MAX_IV_LENGTH 16 +#define MD5_DIGEST_SIZE 16 struct talitos_ctx { struct device *dev; @@ -1145,7 +1142,7 @@ static struct talitos_alg_template driver_algs[] = { { .name = "authenc(hmac(sha1),cbc(aes))", .driver_name = "authenc-hmac-sha1-cbc-aes-talitos", - .blocksize = TALITOS_AES_MIN_BLOCK_SIZE, + .blocksize = AES_BLOCK_SIZE, .aead = { .setkey = aead_authenc_setkey, .setauthsize = aead_authenc_setauthsize, @@ -1153,8 +1150,8 @@ static struct talitos_alg_template driver_algs[] = { .decrypt = aead_authenc_decrypt, .givencrypt = aead_authenc_givencrypt, .geniv = "", - .ivsize = TALITOS_AES_IV_LENGTH, - .maxauthsize = TALITOS_MAX_AUTH_SIZE, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, }, .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | DESC_HDR_SEL0_AESU | @@ -1167,7 +1164,7 @@ static struct talitos_alg_template driver_algs[] = { { .name = "authenc(hmac(sha1),cbc(des3_ede))", .driver_name = "authenc-hmac-sha1-cbc-3des-talitos", - .blocksize = TALITOS_3DES_MIN_BLOCK_SIZE, + .blocksize = DES3_EDE_BLOCK_SIZE, .aead = { .setkey = aead_authenc_setkey, .setauthsize = aead_authenc_setauthsize, @@ -1175,8 +1172,8 @@ static struct talitos_alg_template driver_algs[] = { .decrypt = aead_authenc_decrypt, .givencrypt = aead_authenc_givencrypt, .geniv = "", - .ivsize = TALITOS_3DES_IV_LENGTH, - .maxauthsize = TALITOS_MAX_AUTH_SIZE, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, }, .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | DESC_HDR_SEL0_DEU | @@ -1186,6 +1183,96 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_INIT | DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_SHA1_HMAC, + }, + { + .name = "authenc(hmac(sha256),cbc(aes))", + .driver_name = "authenc-hmac-sha256-cbc-aes-talitos", + .blocksize = AES_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | + DESC_HDR_SEL0_AESU | + DESC_HDR_MODE0_AESU_CBC | + DESC_HDR_SEL1_MDEUA | + DESC_HDR_MODE1_MDEU_INIT | + DESC_HDR_MODE1_MDEU_PAD | + DESC_HDR_MODE1_MDEU_SHA256_HMAC, + }, + { + .name = "authenc(hmac(sha256),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha256-cbc-3des-talitos", + .blocksize = DES3_EDE_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | + DESC_HDR_SEL0_DEU | + DESC_HDR_MODE0_DEU_CBC | + DESC_HDR_MODE0_DEU_3DES | + DESC_HDR_SEL1_MDEUA | + DESC_HDR_MODE1_MDEU_INIT | + DESC_HDR_MODE1_MDEU_PAD | + DESC_HDR_MODE1_MDEU_SHA256_HMAC, + }, + { + .name = "authenc(hmac(md5),cbc(aes))", + .driver_name = "authenc-hmac-md5-cbc-aes-talitos", + .blocksize = AES_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, + .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | + DESC_HDR_SEL0_AESU | + DESC_HDR_MODE0_AESU_CBC | + DESC_HDR_SEL1_MDEUA | + DESC_HDR_MODE1_MDEU_INIT | + DESC_HDR_MODE1_MDEU_PAD | + DESC_HDR_MODE1_MDEU_MD5_HMAC, + }, + { + .name = "authenc(hmac(md5),cbc(des3_ede))", + .driver_name = "authenc-hmac-md5-cbc-3des-talitos", + .blocksize = DES3_EDE_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, + .desc_hdr_template = DESC_HDR_TYPE_IPSEC_ESP | + DESC_HDR_SEL0_DEU | + DESC_HDR_MODE0_DEU_CBC | + DESC_HDR_MODE0_DEU_3DES | + DESC_HDR_SEL1_MDEUA | + DESC_HDR_MODE1_MDEU_INIT | + DESC_HDR_MODE1_MDEU_PAD | + DESC_HDR_MODE1_MDEU_MD5_HMAC, } }; -- cgit v0.10.2 From 34ec8a0ae138c2787a550b930d29a9cce4900cee Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 10 Jul 2008 14:49:19 +0200 Subject: ALSA: HDA - HP dc7600 with pci sub IDs 0x103c/0x3011 belongs to hp-3013 model As reported and tested by an RedHat customer, HP dc7600 with pci sub IDs 0x103c/0x3011 works with the hp-3013 model and not with the hp only model. Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 92a709b..2807bc8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5167,7 +5167,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), + SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), -- cgit v0.10.2 From 6dfff895fa33b8576f82a38cee8abe5f73561e24 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 18:37:51 +0100 Subject: libertas: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 54280e2..d075b44 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -122,7 +122,7 @@ static inline void if_cs_write16(struct if_cs_card *card, uint reg, u16 val) static inline void if_cs_write16_rep( struct if_cs_card *card, uint reg, - void *buf, + const void *buf, unsigned long count) { if (debug_output) diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 51f664b..3dd537b 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -392,7 +392,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) unsigned long timeout; u8 *chunk_buffer; u32 chunk_size; - u8 *firmware; + const u8 *firmware; size_t size; lbs_deb_enter(LBS_DEB_SDIO); @@ -508,7 +508,7 @@ static int if_sdio_prog_real(struct if_sdio_card *card) unsigned long timeout; u8 *chunk_buffer; u32 chunk_size; - u8 *firmware; + const u8 *firmware; size_t size, req_size; lbs_deb_enter(LBS_DEB_SDIO); diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 36288b2..4dcd409 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -293,7 +293,7 @@ static void if_usb_disconnect(struct usb_interface *intf) static int if_usb_send_fw_pkt(struct if_usb_card *cardp) { struct fwdata *fwdata = cardp->ep_out_buf; - uint8_t *firmware = cardp->fw->data; + const uint8_t *firmware = cardp->fw->data; /* If we got a CRC failure on the last block, back up and retry it */ @@ -746,7 +746,7 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) * len image length * @return 0 or -1 */ -static int check_fwfile_format(uint8_t *data, uint32_t totlen) +static int check_fwfile_format(const uint8_t *data, uint32_t totlen) { uint32_t bincmd, exit; uint32_t blksize, offset, len; -- cgit v0.10.2 From 8187b4fb9c17ea8e2a71c0563434f3ee08aad0d7 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 23:56:51 +0100 Subject: bluetooth: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index b990805..0c211ad 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c @@ -566,7 +566,8 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg return -ENOIOCTLCMD; } -static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count) +static int bfusb_load_firmware(struct bfusb_data *data, + const unsigned char *firmware, int count) { unsigned char *buf; int err, pipe, len, size, sent = 0; diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 7703d6e..593b7c5 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -470,7 +470,8 @@ static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long /* ======================== Card services HCI interaction ======================== */ -static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count) +static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware, + int count) { char *ptr = (char *) firmware; char b[9]; -- cgit v0.10.2 From f61e761e2128c7ca0d044651b18928991ab03be2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 23:57:19 +0100 Subject: cyclades: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index ef73e72..6bff9d8 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -4668,7 +4668,7 @@ static inline int __devinit cyc_isfwstr(const char *str, unsigned int size) return 0; } -static inline void __devinit cyz_fpga_copy(void __iomem *fpga, u8 *data, +static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data, unsigned int size) { for (; size > 0; size--) { @@ -4701,10 +4701,10 @@ static int __devinit __cyz_load_fw(const struct firmware *fw, const char *name, const u32 mailbox, void __iomem *base, void __iomem *fpga) { - void *ptr = fw->data; - struct zfile_header *h = ptr; - struct zfile_config *c, *cs; - struct zfile_block *b, *bs; + const void *ptr = fw->data; + const struct zfile_header *h = ptr; + const struct zfile_config *c, *cs; + const struct zfile_block *b, *bs; unsigned int a, tmp, len = fw->size; #define BAD_FW KERN_ERR "Bad firmware: " if (len < sizeof(*h)) { -- cgit v0.10.2 From 9ad46a6ac5422882d9f9a7f0d77ca0766f56bb6e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 23:58:24 +0100 Subject: cx25840: treat firmware data as const Signed-off-by: David Woodhouse Acked-by: Hans Verkuil Acked-by: Tyler Trafford Acked-by: Mike Isely diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index 620d295..8d489a4 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c @@ -79,7 +79,7 @@ static int check_fw_load(struct i2c_client *client, int size) return 0; } -static int fw_write(struct i2c_client *client, u8 *data, int size) +static int fw_write(struct i2c_client *client, const u8 *data, int size) { if (i2c_master_send(client, data, size) < size) { v4l_err(client, "firmware load i2c failure\n"); @@ -93,7 +93,8 @@ int cx25840_loadfw(struct i2c_client *client) { struct cx25840_state *state = i2c_get_clientdata(client); const struct firmware *fw = NULL; - u8 buffer[4], *ptr; + u8 buffer[FWSEND]; + const u8 *ptr; int size, retval; if (state->is_cx23885) @@ -108,29 +109,23 @@ int cx25840_loadfw(struct i2c_client *client) buffer[0] = 0x08; buffer[1] = 0x02; - buffer[2] = fw->data[0]; - buffer[3] = fw->data[1]; - retval = fw_write(client, buffer, 4); - if (retval < 0) { - release_firmware(fw); - return retval; - } - - size = fw->size - 2; + size = fw->size; ptr = fw->data; while (size > 0) { - ptr[0] = 0x08; - ptr[1] = 0x02; - retval = fw_write(client, ptr, min(FWSEND, size + 2)); + int len = min(FWSEND - 2, size); + + memcpy(buffer + 2, ptr, len); + + retval = fw_write(client, buffer, len + 2); if (retval < 0) { release_firmware(fw); return retval; } - size -= FWSEND - 2; - ptr += FWSEND - 2; + size -= len; + ptr += len; } end_fw_load(client); -- cgit v0.10.2 From b0d31d6b28c7ca2ed78ce16ec649c0aac383a3fe Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:00:07 +0100 Subject: myri10ge: treat firmware data as const ... which means allocating our own buffer for reading it back. Signed-off-by: David Woodhouse diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index e0d76c7..823bb6d 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -529,6 +529,7 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) unsigned crc, reread_crc; const struct firmware *fw; struct device *dev = &mgp->pdev->dev; + unsigned char *fw_readback; struct mcp_gen_header *hdr; size_t hdr_offset; int status; @@ -571,9 +572,15 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) mb(); readb(mgp->sram); } + fw_readback = vmalloc(fw->size); + if (!fw_readback) { + status = -ENOMEM; + goto abort_with_fw; + } /* corruption checking is good for parity recovery and buggy chipset */ - memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); - reread_crc = crc32(~0, fw->data, fw->size); + memcpy_fromio(fw_readback, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); + reread_crc = crc32(~0, fw_readback, fw->size); + vfree(fw_readback); if (crc != reread_crc) { dev_err(dev, "CRC failed(fw-len=%u), got 0x%x (expect 0x%x)\n", (unsigned)fw->size, reread_crc, crc); -- cgit v0.10.2 From c2ba47d776bf9a45e15f28fc73ad44877437bef9 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:01:40 +0100 Subject: vx222: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index b4bfc1a..631f3a6 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c @@ -359,7 +359,7 @@ static int vx2_load_xilinx_binary(struct vx_core *chip, const struct firmware *x { unsigned int i; unsigned int port; - unsigned char *image; + const unsigned char *image; /* XILINX reset (wait at least 1 milisecond between reset on and off). */ vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK); -- cgit v0.10.2 From 93a9c901c88ba2b1bae9dd55e6243896b8a580f1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:02:03 +0100 Subject: riptide: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 979f7da..6a35962 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -682,7 +682,7 @@ static union firmware_version firmware_versions[] = { }, }; -static u32 atoh(unsigned char *in, unsigned int len) +static u32 atoh(const unsigned char *in, unsigned int len) { u32 sum = 0; unsigned int mult = 1; @@ -702,12 +702,12 @@ static u32 atoh(unsigned char *in, unsigned int len) return sum; } -static int senddata(struct cmdif *cif, unsigned char *in, u32 offset) +static int senddata(struct cmdif *cif, const unsigned char *in, u32 offset) { u32 addr; u32 data; u32 i; - unsigned char *p; + const unsigned char *p; i = atoh(&in[1], 2); addr = offset + atoh(&in[3], 4); @@ -726,10 +726,10 @@ static int senddata(struct cmdif *cif, unsigned char *in, u32 offset) return 0; } -static int loadfirmware(struct cmdif *cif, unsigned char *img, +static int loadfirmware(struct cmdif *cif, const unsigned char *img, unsigned int size) { - unsigned char *in; + const unsigned char *in; u32 laddr, saddr, t, val; int err = 0; -- cgit v0.10.2 From b8d21807a1a479e0214a03069a88e3e93492b72d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:02:28 +0100 Subject: pcxhr: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 78aa81f..957e6af 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -269,7 +269,7 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin unsigned int chipsc; unsigned char data; unsigned char mask; - unsigned char *image; + const unsigned char *image; /* test first xilinx */ chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); @@ -316,7 +316,7 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp) int err; unsigned int i; unsigned int len; - unsigned char *data; + const unsigned char *data; unsigned char dummy; /* check the length of boot image */ snd_assert(dsp->size > 0, return -EINVAL); -- cgit v0.10.2 From 2f0600b639777cbc1c0ae3f7bbbc982b0838e706 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:02:49 +0100 Subject: vx: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index 9953886..585af2e 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -453,7 +453,7 @@ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot) vx_outb(chip, TXM, 0); vx_outb(chip, TXL, 0); } else { - unsigned char *image = boot->data + i; + const unsigned char *image = boot->data + i; if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) { snd_printk(KERN_ERR "dsp boot failed at %d\n", i); return -EIO; @@ -671,7 +671,7 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp) unsigned int i; int err; unsigned int csum = 0; - unsigned char *image, *cptr; + const unsigned char *image, *cptr; snd_assert(dsp->size % 3 == 0, return -EINVAL); -- cgit v0.10.2 From aafcd2f7d6790490bd921f04390bc210b386ecfa Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:05:10 +0100 Subject: ueagle-atm: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 5f71ff3..cb01b51 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -579,7 +579,7 @@ MODULE_PARM_DESC(annex, * uea_send_modem_cmd - Send a command for pre-firmware devices. */ static int uea_send_modem_cmd(struct usb_device *usb, - u16 addr, u16 size, u8 * buff) + u16 addr, u16 size, const u8 *buff) { int ret = -ENOMEM; u8 *xfer_buff; @@ -604,7 +604,8 @@ static int uea_send_modem_cmd(struct usb_device *usb, static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context) { struct usb_device *usb = context; - u8 *pfw, value; + const u8 *pfw; + u8 value; u32 crc = 0; int ret, size; @@ -720,7 +721,7 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) /* * Make sure that the DSP code provided is safe to use. */ -static int check_dsp_e1(u8 *dsp, unsigned int len) +static int check_dsp_e1(const u8 *dsp, unsigned int len) { u8 pagecount, blockcount; u16 blocksize; @@ -771,7 +772,7 @@ static int check_dsp_e1(u8 *dsp, unsigned int len) return 0; } -static int check_dsp_e4(u8 *dsp, int len) +static int check_dsp_e4(const u8 *dsp, int len) { int i; struct l1_code *p = (struct l1_code *) dsp; @@ -819,7 +820,7 @@ static int check_dsp_e4(u8 *dsp, int len) /* * send data to the idma pipe * */ -static int uea_idma_write(struct uea_softc *sc, void *data, u32 size) +static int uea_idma_write(struct uea_softc *sc, const void *data, u32 size) { int ret = -ENOMEM; u8 *xfer_buff; @@ -903,7 +904,7 @@ static void uea_load_page_e1(struct work_struct *work) u16 ovl = sc->ovl; struct block_info_e1 bi; - u8 *p; + const u8 *p; u8 pagecount, blockcount; u16 blockaddr, blocksize; u32 pageoffset; @@ -986,7 +987,7 @@ static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot) bi.wReserved = cpu_to_be16(UEA_RESERVED); do { - u8 *blockoffset; + const u8 *blockoffset; unsigned int blocksize; blockidx = &p->page_header[blockno]; @@ -1095,7 +1096,7 @@ static inline int wait_cmv_ack(struct uea_softc *sc) #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 static int uea_request(struct uea_softc *sc, - u16 value, u16 index, u16 size, void *data) + u16 value, u16 index, u16 size, const void *data) { u8 *xfer_buff; int ret = -ENOMEM; @@ -1891,7 +1892,8 @@ static int load_XILINX_firmware(struct uea_softc *sc) { const struct firmware *fw_entry; int ret, size, u, ln; - u8 *pfw, value; + const u8 *pfw; + u8 value; char *fw_name = FW_DIR "930-fpga.bin"; uea_enters(INS_TO_USBDEV(sc)); -- cgit v0.10.2 From 3b216d186c6df2642b397dbb67fbb7884ead0d88 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:05:28 +0100 Subject: cxacru: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 5ea3093..90583d6 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -820,7 +820,7 @@ reschedule: } static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, - u8 code1, u8 code2, u32 addr, u8 *data, int size) + u8 code1, u8 code2, u32 addr, const u8 *data, int size) { int ret; u8 *buf; -- cgit v0.10.2 From 0bc202e0fd84b8c8d042bdf9f0995e1e47bdbf59 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:05:45 +0100 Subject: aic94xx: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 4446e3d..8630a75 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c @@ -1093,9 +1093,9 @@ out: * @bytes_to_verify: total bytes to verify */ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha, - void *src, u32 dest_offset, u32 bytes_to_verify) + const void *src, u32 dest_offset, u32 bytes_to_verify) { - u8 *src_buf; + const u8 *src_buf; u8 flash_char; int err; u32 nv_offset, reg, i; @@ -1105,7 +1105,7 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha, err = FLASH_OK; nv_offset = dest_offset; - src_buf = (u8 *)src; + src_buf = (const u8 *)src; for (i = 0; i < bytes_to_verify; i++) { flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i); if (flash_char != src_buf[i]) { @@ -1124,9 +1124,9 @@ int asd_verify_flash_seg(struct asd_ha_struct *asd_ha, * @bytes_to_write: total bytes to write */ int asd_write_flash_seg(struct asd_ha_struct *asd_ha, - void *src, u32 dest_offset, u32 bytes_to_write) + const void *src, u32 dest_offset, u32 bytes_to_write) { - u8 *src_buf; + const u8 *src_buf; u32 nv_offset, reg, i; int err; @@ -1153,7 +1153,7 @@ int asd_write_flash_seg(struct asd_ha_struct *asd_ha, return err; } - src_buf = (u8 *)src; + src_buf = (const u8 *)src; for (i = 0; i < bytes_to_write; i++) { /* Setup program command sequence */ switch (asd_ha->hw_prof.flash.method) { diff --git a/drivers/scsi/aic94xx/aic94xx_sds.h b/drivers/scsi/aic94xx/aic94xx_sds.h index bb9795a..a06dc01 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.h +++ b/drivers/scsi/aic94xx/aic94xx_sds.h @@ -110,9 +110,9 @@ struct bios_file_header { }; int asd_verify_flash_seg(struct asd_ha_struct *asd_ha, - void *src, u32 dest_offset, u32 bytes_to_verify); + const void *src, u32 dest_offset, u32 bytes_to_verify); int asd_write_flash_seg(struct asd_ha_struct *asd_ha, - void *src, u32 dest_offset, u32 bytes_to_write); + const void *src, u32 dest_offset, u32 bytes_to_write); int asd_chk_write_status(struct asd_ha_struct *asd_ha, u32 sector_addr, u8 erase_flag); int asd_check_flash_type(struct asd_ha_struct *asd_ha); diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index f4272ac..8f98e33 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c @@ -46,7 +46,7 @@ static const struct firmware *sequencer_fw; static u16 cseq_vecs[CSEQ_NUM_VECS], lseq_vecs[LSEQ_NUM_VECS], mode2_task, cseq_idle_loop, lseq_idle_loop; -static u8 *cseq_code, *lseq_code; +static const u8 *cseq_code, *lseq_code; static u32 cseq_code_size, lseq_code_size; static u16 first_scb_site_no = 0xFFFF; @@ -1235,7 +1235,8 @@ int asd_release_firmware(void) static int asd_request_firmware(struct asd_ha_struct *asd_ha) { int err, i; - struct sequencer_file_header header, *hdr_ptr; + struct sequencer_file_header header; + const struct sequencer_file_header *hdr_ptr; u32 csum = 0; u16 *ptr_cseq_vecs, *ptr_lseq_vecs; @@ -1249,7 +1250,7 @@ static int asd_request_firmware(struct asd_ha_struct *asd_ha) if (err) return err; - hdr_ptr = (struct sequencer_file_header *)sequencer_fw->data; + hdr_ptr = (const struct sequencer_file_header *)sequencer_fw->data; header.csum = le32_to_cpu(hdr_ptr->csum); header.major = le32_to_cpu(hdr_ptr->major); -- cgit v0.10.2 From 45ef0bdb18a37bcf102e2a18c757227f8b192a36 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:08:19 +0100 Subject: zd1201: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index d5c0c66..78baa0f 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -49,7 +49,7 @@ MODULE_DEVICE_TABLE(usb, zd1201_table); static int zd1201_fw_upload(struct usb_device *dev, int apfw) { const struct firmware *fw_entry; - char *data; + const char *data; unsigned long len; int err; unsigned char ret; -- cgit v0.10.2 From f160ebcbeb6c9b79a770f22e14398158dac3de00 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:08:39 +0100 Subject: rt2x00: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b4bf1e0..a74e1a5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -511,8 +511,8 @@ struct rt2x00lib_ops { */ int (*probe_hw) (struct rt2x00_dev *rt2x00dev); char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); - u16 (*get_firmware_crc) (void *data, const size_t len); - int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data, + u16 (*get_firmware_crc) (const void *data, const size_t len); + int (*load_firmware) (struct rt2x00_dev *rt2x00dev, const void *data, const size_t len); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 9d1cdb9..b41967e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -82,7 +82,7 @@ static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, const unsigned long offset, - void *value, const u16 length) + const void *value, const u16 length) { memcpy_toio(rt2x00dev->csr.base + offset, value, length); } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 14bc7b2..bb78de5 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -915,7 +915,7 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) return fw_name; } -static u16 rt61pci_get_firmware_crc(void *data, const size_t len) +static u16 rt61pci_get_firmware_crc(const void *data, const size_t len) { u16 crc; @@ -932,7 +932,7 @@ static u16 rt61pci_get_firmware_crc(void *data, const size_t len) return crc; } -static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, +static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, const size_t len) { int i; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 83cc014..d5a6c21 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -856,7 +856,7 @@ static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) return FIRMWARE_RT2571; } -static u16 rt73usb_get_firmware_crc(void *data, const size_t len) +static u16 rt73usb_get_firmware_crc(const void *data, const size_t len) { u16 crc; @@ -873,13 +873,13 @@ static u16 rt73usb_get_firmware_crc(void *data, const size_t len) return crc; } -static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, +static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, const size_t len) { unsigned int i; int status; u32 reg; - char *ptr = data; + const char *ptr = data; char *cache; int buflen; int timeout; -- cgit v0.10.2 From 8b72eb4333aba692a16339acf8a74d84b10d3568 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:08:55 +0100 Subject: p54: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 1610a73..815c095 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -376,7 +376,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) const struct firmware *fw_entry = NULL; int err, alen; u8 carry = 0; - u8 *buf, *tmp, *data; + u8 *buf, *tmp; + const u8 *data; unsigned int left, remains, block_size; struct x2_header *hdr; unsigned long timeout; @@ -523,7 +524,7 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) void *buf; __le32 reg; unsigned int remains, offset; - u8 *data; + const u8 *data; buf = kmalloc(512, GFP_KERNEL); if (!buf) { -- cgit v0.10.2 From 2f26e8afb22d79f655def146894595a39aeea1f8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:09:29 +0100 Subject: atmel: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 438e63e..d1acef7 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -560,7 +560,7 @@ static const struct { static void build_wpa_mib(struct atmel_private *priv); static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void atmel_copy_to_card(struct net_device *dev, u16 dest, - unsigned char *src, u16 len); + const unsigned char *src, u16 len); static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len); static void atmel_set_gcr(struct net_device *dev, u16 mask); @@ -3853,7 +3853,7 @@ static int reset_atmel_card(struct net_device *dev) if (priv->card_type == CARD_TYPE_EEPROM) { /* copy in firmware if needed */ const struct firmware *fw_entry = NULL; - unsigned char *fw; + const unsigned char *fw; int len = priv->firmware_length; if (!(fw = priv->firmware)) { if (priv->firmware_type == ATMEL_FW_TYPE_NONE) { @@ -4120,7 +4120,7 @@ static void atmel_writeAR(struct net_device *dev, u16 data) } static void atmel_copy_to_card(struct net_device *dev, u16 dest, - unsigned char *src, u16 len) + const unsigned char *src, u16 len) { int i; atmel_writeAR(dev, dest); -- cgit v0.10.2 From afd636e94d3cd99697f7291dbf957f0ca8a7544e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:10:26 +0100 Subject: irda-usb: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 6f50ed7..18b471c 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1024,7 +1024,7 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) * Upload firmware code to SigmaTel 421X IRDA-USB dongle */ static int stir421x_fw_upload(struct irda_usb_cb *self, - unsigned char *patch, + const unsigned char *patch, const unsigned int patch_len) { int ret = -ENOMEM; @@ -1073,11 +1073,11 @@ static int stir421x_fw_upload(struct irda_usb_cb *self, */ static int stir421x_patch_device(struct irda_usb_cb *self) { - unsigned int i; - int ret; - char stir421x_fw_name[11]; - const struct firmware *fw; - unsigned char *fw_version_ptr; /* pointer to version string */ + unsigned int i; + int ret; + char stir421x_fw_name[11]; + const struct firmware *fw; + const unsigned char *fw_version_ptr; /* pointer to version string */ unsigned long fw_version = 0; /* -- cgit v0.10.2 From 2c733a16784021c7c6a0c10e800937f0645d0a36 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:10:55 +0100 Subject: cxgb3: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 579bee4..8e8ebd7 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -686,8 +686,9 @@ int t3_seeprom_write(struct adapter *adapter, u32 addr, __le32 data); int t3_seeprom_wp(struct adapter *adapter, int enable); int t3_get_tp_version(struct adapter *adapter, u32 *vers); int t3_check_tpsram_version(struct adapter *adapter, int *must_load); -int t3_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size); -int t3_set_proto_sram(struct adapter *adap, u8 *data); +int t3_check_tpsram(struct adapter *adapter, const u8 *tp_ram, + unsigned int size); +int t3_set_proto_sram(struct adapter *adap, const u8 *data); int t3_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented); int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size); diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index d405a93..47d5178 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -923,7 +923,8 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load) * Checks if an adapter's tp sram is compatible with the driver. * Returns 0 if the versions are compatible, a negative error otherwise. */ -int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size) +int t3_check_tpsram(struct adapter *adapter, const u8 *tp_sram, + unsigned int size) { u32 csum; unsigned int i; @@ -2875,10 +2876,10 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p) * * Write the contents of the protocol SRAM. */ -int t3_set_proto_sram(struct adapter *adap, u8 *data) +int t3_set_proto_sram(struct adapter *adap, const u8 *data) { int i; - __be32 *buf = (__be32 *)data; + const __be32 *buf = (const __be32 *)data; for (i = 0; i < PROTO_SRAM_LINES; i++) { t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, be32_to_cpu(*buf++)); -- cgit v0.10.2 From 4f2a0c3cdbead635f8aae729f550fcabcb73d1a5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:11:44 +0100 Subject: bt8xx: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 8ef0424..1c56ae9 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -3768,7 +3768,8 @@ static int terratec_active_radio_upgrade(struct bttv *btv) #define BTTV_ALT_DCLK 0x100000 #define BTTV_ALT_NCONFIG 0x800000 -static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) +static int __devinit pvr_altera_load(struct bttv *btv, const u8 *micro, + u32 microlen) { u32 n; u8 bits; -- cgit v0.10.2 From 99b6e4f511e38ea7beae35ee1b46b440151ce727 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:12:00 +0100 Subject: ttusb-dec: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index fefdc05..de5829b 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1275,7 +1275,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) u8 b1[] = { 0x61 }; u8 *b; char idstring[21]; - u8 *firmware = NULL; + const u8 *firmware = NULL; size_t firmware_size = 0; u16 firmware_csum = 0; __be16 firmware_csum_ns; -- cgit v0.10.2 From bc179153ae2334efe28cf4f3300e024da7d83753 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:12:23 +0100 Subject: dvb frontends: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index d268e65..cf5e576 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c @@ -590,7 +590,8 @@ static void bcm3510_release(struct dvb_frontend* fe) */ #define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw" -static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len) +static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b, + u16 len) { int ret = 0,i; bcm3510_register_value vH, vL,vD; @@ -614,7 +615,7 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe) struct bcm3510_state* st = fe->demodulator_priv; const struct firmware *fw; u16 addr,len; - u8 *b; + const u8 *b; int ret,i; deb_info("requesting firmware\n"); diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index 23d0228..af29835 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c @@ -93,7 +93,8 @@ static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) return 0; } -static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len) +static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, + const u8 *buf, u8 len) { u8 buf2 [len+1]; int err; diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 7eaa476..6afe12a 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c @@ -69,7 +69,7 @@ struct or51211_state { u32 current_frequency; }; -static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf, +static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, int len) { int err; @@ -77,7 +77,7 @@ static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf, msg.addr = reg; msg.flags = 0; msg.len = len; - msg.buf = buf; + msg.buf = (u8 *)buf; if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { printk(KERN_WARNING "or51211: i2c_writebytes error " diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index aa78aa1..1c9a9b4 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c @@ -98,7 +98,7 @@ static int sp8870_readreg (struct sp8870_state* state, u16 reg) static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw) { struct i2c_msg msg; - char *fw_buf = fw->data; + const char *fw_buf = fw->data; int fw_pos; u8 tx_buf[255]; int tx_len; diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index 49f5587..4543609 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c @@ -140,7 +140,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware u8 buf [BLOCKSIZE+2]; int i; int fw_size = fw->size; - unsigned char *mem = fw->data; + const unsigned char *mem = fw->data; dprintk("%s\n", __func__); diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 090fb7d..0ab8d86b 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -233,7 +233,7 @@ static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) } static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, - u8 *data, u16 len) + const u8 *data, u16 len) { int ret = -EREMOTEIO; struct i2c_msg msg; diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index a0d6386..1465ff7 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -317,7 +317,7 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state, } static int tda1004x_do_upload(struct tda1004x_state *state, - unsigned char *mem, unsigned int len, + const unsigned char *mem, unsigned int len, u8 dspCodeCounterReg, u8 dspCodeInReg) { u8 buf[65]; -- cgit v0.10.2 From e62f89f2aebd57f48687f139c20cf6375693b622 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:12:42 +0100 Subject: cxusb: treat firmware data as const ...which means allocating our own copy when we want to modify it. (stupid thinko fixed by mkrufky) Signed-off-by: David Woodhouse Signed-off-by: Michael Krufky diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 720fcd1..0286156 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -24,6 +24,7 @@ * see Documentation/dvb/README.dvb-usb for more information */ #include +#include #include "cxusb.h" @@ -700,12 +701,26 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, if (fw->data[idoff] == (USB_VID_DVICO & 0xff) && fw->data[idoff + 1] == USB_VID_DVICO >> 8) { - fw->data[idoff + 2] = + struct firmware new_fw; + u8 *new_fw_data = vmalloc(fw->size); + int ret; + + if (!new_fw_data) + return -ENOMEM; + + memcpy(new_fw_data, fw->data, fw->size); + new_fw.size = fw->size; + new_fw.data = new_fw_data; + + new_fw_data[idoff + 2] = le16_to_cpu(udev->descriptor.idProduct) + 1; - fw->data[idoff + 3] = + new_fw_data[idoff + 3] = le16_to_cpu(udev->descriptor.idProduct) >> 8; - return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2); + ret = usb_cypress_load_firmware(udev, &new_fw, + CYPRESS_FX2); + vfree(new_fw_data); + return ret; } } -- cgit v0.10.2 From 3a9282cacdb13466b9c745518237938434dbde0b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:13:08 +0100 Subject: gp8psk: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 2653120..d965a92 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c @@ -86,7 +86,8 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) { int ret; const struct firmware *fw = NULL; - u8 *ptr, *buf; + const u8 *ptr; + u8 *buf; if ((ret = request_firmware(&fw, bcm4500_firmware, &d->udev->dev)) != 0) { err("did not find the bcm4500 firmware file. (%s) " -- cgit v0.10.2 From c63e87e90abb5d3ecd05d6c6eba94163bf8c1760 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 24 May 2008 00:13:34 +0100 Subject: tuners: treat firmware data as const Signed-off-by: David Woodhouse diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 0cbde17..30eb07b 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c @@ -254,7 +254,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) { struct xc2028_data *priv = fe->tuner_priv; const struct firmware *fw = NULL; - unsigned char *p, *endp; + const unsigned char *p, *endp; int rc = 0; int n, n_array; char name[33]; diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 7cf4f5b..4878d64 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -278,7 +278,7 @@ static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData) return result; } -static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[]) +static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) { struct xc5000_priv *priv = fe->tuner_priv; -- cgit v0.10.2 From fa6e1cb66e2f9d2d4703e7bd7dd50839bb10e4c3 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 11:58:27 +0300 Subject: maestro3: treat firmware data as const The maestro3 driver is byte-swapping its firmware to be host-endian in advance, when it doesn't seem to be necessary -- we could just use le16_to_cpu() as we load it. Doing that means that we need to switch the in-tree firmware to be little-endian too. Take the least intrusive way of doing this, which is to switch the existing snd_m3_convert_from_le() function to convert _to_ little-endian instead, and use it on the in-tree firmware instead of the loaded firmware. It's a bit suboptimal but doesn't matter much right now because we're about to remove the special cases for the in-tree version anyway. Signed-off-by: David Woodhouse diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index a536c59..9dfba6e 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2240,18 +2240,16 @@ static const struct firmware assp_minisrc = { .size = sizeof assp_minisrc_image }; -#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ - #ifdef __LITTLE_ENDIAN -static inline void snd_m3_convert_from_le(const struct firmware *fw) { } +static inline void snd_m3_convert_to_le(const struct firmware *fw) { } #else -static void snd_m3_convert_from_le(const struct firmware *fw) +static void snd_m3_convert_to_le(const struct firmware *fw) { int i; u16 *data = (u16 *)fw->data; for (i = 0; i < fw->size / 2; ++i) - le16_to_cpus(&data[i]); + cpu_to_le16s(&data[i]); } #endif @@ -2271,7 +2269,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = { static void snd_m3_assp_init(struct snd_m3 *chip) { unsigned int i; - u16 *data; + const u16 *data; /* zero kernel data */ for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) @@ -2289,10 +2287,11 @@ static void snd_m3_assp_init(struct snd_m3 *chip) KDATA_DMA_XFER0); /* write kernel into code memory.. */ - data = (u16 *)chip->assp_kernel_image->data; + data = (const u16 *)chip->assp_kernel_image->data; for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, - REV_B_CODE_MEMORY_BEGIN + i, data[i]); + REV_B_CODE_MEMORY_BEGIN + i, + le16_to_cpu(data[i])); } /* @@ -2301,10 +2300,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip) * drop it there. It seems that the minisrc doesn't * need vectors, so we won't bother with them.. */ - data = (u16 *)chip->assp_minisrc_image->data; + data = (const u16 *)chip->assp_minisrc_image->data; for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, - 0x400 + i, data[i]); + 0x400 + i, le16_to_cpu(data[i])); } /* @@ -2749,8 +2748,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, if (err < 0) { snd_m3_free(chip); return err; - } else - snd_m3_convert_from_le(chip->assp_kernel_image); + } #endif #ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL @@ -2761,8 +2759,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, if (err < 0) { snd_m3_free(chip); return err; - } else - snd_m3_convert_from_le(chip->assp_minisrc_image); + } #endif if ((err = pci_request_regions(pci, card->driver)) < 0) { @@ -2915,6 +2912,10 @@ static struct pci_driver driver = { static int __init alsa_card_m3_init(void) { +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + snd_m3_convert_to_le(&assp_kernel); + snd_m3_convert_to_le(&assp_minisrc); +#endif return pci_register_driver(&driver); } -- cgit v0.10.2 From b82a82d0a90af74847ae3e873a241dedf3786fd5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 14:40:00 +0300 Subject: ymfpci: treat firmware data as const Standardise both in-kernel and loaded firmware to be stored as little-endian instead of host-endian. Signed-off-by: David Woodhouse diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 29b3056..6298b29 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -2009,11 +2010,34 @@ static struct firmware snd_ymfpci_controller_1e_microcode = { .size = YDSXG_CTRLLENGTH, .data = (u8 *)CntrlInst1E, }; + +#ifdef __BIG_ENDIAN +static int microcode_swapped; +static DEFINE_MUTEX(microcode_swap); + +static void snd_ymfpci_convert_to_le(const struct firmware *fw) +{ + int i; + u32 *data = (u32 *)fw->data; + + for (i = 0; i < fw->size / 4; ++i) + cpu_to_le32s(&data[i]); +} #endif -#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) { +#ifdef __BIG_ENDIAN + mutex_lock(µcode_swap); + if (!microcode_swapped) { + snd_ymfpci_convert_to_le(&snd_ymfpci_dsp_microcode); + snd_ymfpci_convert_to_le(&snd_ymfpci_controller_1e_microcode); + snd_ymfpci_convert_to_le(&snd_ymfpci_controller_microcode); + microcode_swapped = 1; + } + mutex_unlock(µcode_swap); +#endif + chip->dsp_microcode = &snd_ymfpci_dsp_microcode; if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || @@ -2029,19 +2053,6 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) #else /* use fw_loader */ -#ifdef __LITTLE_ENDIAN -static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } -#else -static void snd_ymfpci_convert_from_le(const struct firmware *fw) -{ - int i; - u32 *data = (u32 *)fw->data; - - for (i = 0; i < fw->size / 4; ++i) - le32_to_cpus(&data[i]); -} -#endif - static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) { int err, is_1e; @@ -2050,9 +2061,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw", &chip->pci->dev); if (err >= 0) { - if (chip->dsp_microcode->size == YDSXG_DSPLENGTH) - snd_ymfpci_convert_from_le(chip->dsp_microcode); - else { + if (chip->dsp_microcode->size != YDSXG_DSPLENGTH) { snd_printk(KERN_ERR "DSP microcode has wrong size\n"); err = -EINVAL; } @@ -2067,9 +2076,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = request_firmware(&chip->controller_microcode, name, &chip->pci->dev); if (err >= 0) { - if (chip->controller_microcode->size == YDSXG_CTRLLENGTH) - snd_ymfpci_convert_from_le(chip->controller_microcode); - else { + if (chip->controller_microcode->size != YDSXG_CTRLLENGTH) { snd_printk(KERN_ERR "controller microcode" " has wrong size\n"); err = -EINVAL; @@ -2090,7 +2097,7 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip) { int i; u16 ctrl; - u32 *inst; + const __le32 *inst; snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000); snd_ymfpci_disable_dsp(chip); @@ -2105,14 +2112,16 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip) snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); /* setup DSP instruction code */ - inst = (u32 *)chip->dsp_microcode->data; + inst = (const __le32 *)chip->dsp_microcode->data; for (i = 0; i < YDSXG_DSPLENGTH / 4; i++) - snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), inst[i]); + snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), + le32_to_cpu(inst[i])); /* setup control instruction code */ - inst = (u32 *)chip->controller_microcode->data; + inst = (const __le32 *)chip->controller_microcode->data; for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++) - snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]); + snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), + le32_to_cpu(inst[i])); snd_ymfpci_enable_dsp(chip); } -- cgit v0.10.2 From c6c1c94e8225c833d4c175622f8c2e70c7347a7d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 May 2008 10:05:08 -0700 Subject: dell_rbu: firmware data is const Signed-off-by: Greg Kroah-Hartman Signed-off-by: David Woodhouse diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 6a8b1e0..7430e21 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -220,7 +220,7 @@ out_noalloc: return retval; } -static int packetize_data(void *data, size_t length) +static int packetize_data(const u8 *data, size_t length) { int rc = 0; int done = 0; -- cgit v0.10.2 From a13b04af713bfa60d44cbac956ab00d3a5793de7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 May 2008 10:05:08 -0700 Subject: x86 microcode: firmware data is const Signed-off-by: Greg Kroah-Hartman Signed-off-by: David Woodhouse diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c index 69729e3..649dfd7 100644 --- a/arch/x86/kernel/microcode.c +++ b/arch/x86/kernel/microcode.c @@ -488,7 +488,7 @@ MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); #define microcode_dev_exit() do { } while(0) #endif -static long get_next_ucode_from_buffer(void **mc, void *buf, +static long get_next_ucode_from_buffer(void **mc, const u8 *buf, unsigned long size, long offset) { microcode_header_t *mc_header; @@ -522,7 +522,7 @@ static int cpu_request_microcode(int cpu) char name[30]; struct cpuinfo_x86 *c = &cpu_data(cpu); const struct firmware *firmware; - void *buf; + const u8 *buf; unsigned long size; long offset = 0; int error; -- cgit v0.10.2 From ed5a2825feb79c424882c9d0f483172a91c93b54 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Thu, 29 May 2008 10:17:38 -0700 Subject: isight: treat firmware data as const Signed-off-by: Greg Kroah-Hartman Signed-off-by: David Woodhouse diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index 9f30aa1..d94aa73 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c @@ -41,7 +41,7 @@ static int isight_firmware_load(struct usb_interface *intf, const struct firmware *firmware; unsigned char *buf = kmalloc(50, GFP_KERNEL); unsigned char data[4]; - u8 *ptr; + const u8 *ptr; if (!buf) return -ENOMEM; -- cgit v0.10.2 From b561c74ae2832d32cc189ecd82863d31151cdcb5 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:36:45 +0100 Subject: Fix a const pointer usage warning in the Digigram VX soundcard driver Fix a const pointer usage warning in the Digigram VX soundcard driver. A const pointer is being passed to copy_from_user() to load the firmware into. This is okay in this case because the function has allocated the firmware struct itself, but the const qualifier will be part of the firmware struct - so the patch casts the const away. Signed-off-by: David Howells Signed-off-by: David Woodhouse diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index 1dfe694..efd22e9 100644 --- a/sound/drivers/vx/vx_hwdep.c +++ b/sound/drivers/vx/vx_hwdep.c @@ -183,7 +183,7 @@ static int vx_hwdep_dsp_load(struct snd_hwdep *hw, kfree(fw); return -ENOMEM; } - if (copy_from_user(fw->data, dsp->image, dsp->length)) { + if (copy_from_user((void *)fw->data, dsp->image, dsp->length)) { free_fw(fw); return -EFAULT; } -- cgit v0.10.2 From 2bca76e89bc43f86136080536858048ebffab3e3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:37:15 +0100 Subject: Fix a const assignment in moxa_load_fw() Fix an assignment of a const pointer to a non-const pointer in moxa_load_fw(). Signed-off-by: David Howells Signed-off-by: David Woodhouse diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index d57d3a6..e21346d 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -721,7 +721,7 @@ static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr, static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw) { - void *ptr = fw->data; + const void *ptr = fw->data; char rsn[64]; u16 lens[5]; size_t len; @@ -734,7 +734,7 @@ static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw) u8 model; /* C218T=1, C320T=2, CP204=3 */ u8 reserved2[8]; __le16 len[5]; - } *hdr = ptr; + } const *hdr = ptr; BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens)); -- cgit v0.10.2 From 9b8a3e4cb1361cf4b4a50916876e72f07a9037e9 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:38:56 +0100 Subject: Fix a const pointer error in the Conexant cx23418 MPEG encoder driver Fix a const pointer to non-const pointer assignment error in the Conexant cx23418 MPEG encoder driver. Signed-off-by: David Howells Signed-off-by: David Woodhouse diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index 526e142..a1a6af6 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c @@ -29,7 +29,7 @@ int cx18_av_loadfw(struct cx18 *cx) const struct firmware *fw = NULL; u32 size; u32 v; - u8 *ptr; + const u8 *ptr; int i; if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { -- cgit v0.10.2 From 67852dc08c0782735d48ce1e2a6eb44cd02a6ff7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:45:58 +0100 Subject: Fix a const pointer usage warning in the Digigram pcxhr soundcard driver Fix a const pointer usage warning in the Digigram pcxhr compatible soundcard driver. A const pointer is being passed to copy_from_user() to load the firmware into. This is okay in this case because the function has allocated the firmware struct itself, but the const qualifier is part of the firmware struct - so the patch casts the const away. Signed-off-by: David Howells Signed-off-by: David Woodhouse diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index e6a4bfb..d2f0432 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c @@ -394,7 +394,7 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw, (unsigned long)fw.size); return -ENOMEM; } - if (copy_from_user(fw.data, dsp->image, dsp->length)) { + if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) { vfree(fw.data); return -EFAULT; } -- cgit v0.10.2 From fd4f80de4612cc5255c108a8c13df88f89c46654 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 17:43:01 +0100 Subject: Fix a const pointer usage warning in the Digigram miXart soundcard driver Fix a const pointer usage warning in the Digigram miXart soundcard driver. A const pointer is being passed to copy_from_user() to load the firmware into. This is okay in this case because the function has allocated the firmware struct itself, but the const qualifier is part of the firmware struct - so the patch casts the const away. Signed-off-by: David Howells Signed-off-by: David Woodhouse diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 122c28e..f986031 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -613,7 +613,7 @@ static int mixart_hwdep_dsp_load(struct snd_hwdep *hw, (int)dsp->length); return -ENOMEM; } - if (copy_from_user(fw.data, dsp->image, dsp->length)) { + if (copy_from_user((void *) fw.data, dsp->image, dsp->length)) { vfree(fw.data); return -EFAULT; } -- cgit v0.10.2 From b7a39bd0afc4021e8ad2b1189e884551e147427f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 18:38:49 +0100 Subject: firmware: make fw->data const In preparation for supporting firmware files linked into the static kernel, make fw->data const to ensure that users aren't modifying it (so that we can pass a pointer to the original in-kernel copy, rather than having to copy it). Signed-off-by: David Woodhouse diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 9fd4a85..264b3a2 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -257,7 +257,7 @@ firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr, if (retval) goto out; - memcpy(fw->data + offset, buffer, count); + memcpy((u8 *)fw->data + offset, buffer, count); fw->size = max_t(size_t, offset + count, fw->size); retval = count; diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 6c7eff2..88718d6 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -8,7 +8,7 @@ struct firmware { size_t size; - u8 *data; + const u8 *data; }; struct device; -- cgit v0.10.2 From 5658c769443d543728b6c5c673dffc2df8676317 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 13:52:42 +0100 Subject: firmware: allow firmware files to be built into kernel image Some drivers have their own hacks to bypass the kernel's firmware loader and build their firmware into the kernel; this renders those unnecessary. Other drivers don't use the firmware loader at all, because they always want the firmware to be available. This allows them to start using the firmware loader. A third set of drivers already use the firmware loader, but can't be used without help from userspace, which sometimes requires an initrd. This allows them to work in a static kernel. Signed-off-by: David Woodhouse diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 264b3a2..b0be1d1 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -49,6 +49,14 @@ struct firmware_priv { struct timer_list timeout; }; +#ifdef CONFIG_FW_LOADER +extern struct builtin_fw __start_builtin_fw[]; +extern struct builtin_fw __end_builtin_fw[]; +#else /* Module case. Avoid ifdefs later; it'll all optimise out */ +static struct builtin_fw *__start_builtin_fw; +static struct builtin_fw *__end_builtin_fw; +#endif + static void fw_load_abort(struct firmware_priv *fw_priv) { @@ -391,13 +399,12 @@ _request_firmware(const struct firmware **firmware_p, const char *name, struct device *f_dev; struct firmware_priv *fw_priv; struct firmware *firmware; + struct builtin_fw *builtin; int retval; if (!firmware_p) return -EINVAL; - printk(KERN_INFO "firmware: requesting %s\n", name); - *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); if (!firmware) { printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n", @@ -406,6 +413,20 @@ _request_firmware(const struct firmware **firmware_p, const char *name, goto out; } + for (builtin = __start_builtin_fw; builtin != __end_builtin_fw; + builtin++) { + if (strcmp(name, builtin->name)) + continue; + printk(KERN_INFO "firmware: using built-in firmware %s\n", + name); + firmware->size = builtin->size; + firmware->data = builtin->data; + return 0; + } + + if (uevent) + printk(KERN_INFO "firmware: requesting %s\n", name); + retval = fw_setup_device(firmware, &f_dev, name, device, uevent); if (retval) goto error_kfree_fw; @@ -473,8 +494,16 @@ request_firmware(const struct firmware **firmware_p, const char *name, void release_firmware(const struct firmware *fw) { + struct builtin_fw *builtin; + if (fw) { + for (builtin = __start_builtin_fw; builtin != __end_builtin_fw; + builtin++) { + if (fw->data == builtin->data) + goto free_fw; + } vfree(fw->data); + free_fw: kfree(fw); } } diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f054778..8d71a40 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -86,6 +86,13 @@ VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \ } \ \ + /* Built-in firmware blobs */ \ + .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_builtin_fw) = .; \ + *(.builtin_fw) \ + VMLINUX_SYMBOL(__end_builtin_fw) = .; \ + } \ + \ /* RapidIO route ops */ \ .rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_rio_route_ops) = .; \ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 88718d6..c8ecf5b 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -1,7 +1,10 @@ #ifndef _LINUX_FIRMWARE_H #define _LINUX_FIRMWARE_H + #include #include +#include + #define FIRMWARE_NAME_MAX 30 #define FW_ACTION_NOHOTPLUG 0 #define FW_ACTION_HOTPLUG 1 @@ -13,6 +16,24 @@ struct firmware { struct device; +struct builtin_fw { + char *name; + void *data; + unsigned long size; +}; + +/* We have to play tricks here much like stringify() to get the + __COUNTER__ macro to be expanded as we want it */ +#define __fw_concat1(x, y) x##y +#define __fw_concat(x, y) __fw_concat1(x, y) + +#define DECLARE_BUILTIN_FIRMWARE(name, blob) \ + DECLARE_BUILTIN_FIRMWARE_SIZE(name, &(blob), sizeof(blob)) + +#define DECLARE_BUILTIN_FIRMWARE_SIZE(name, blob, size) \ + static const struct builtin_fw __fw_concat(__builtin_fw,__COUNTER__) \ + __used __section(.builtin_fw) = { name, blob, size } + #if defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE)) int request_firmware(const struct firmware **fw, const char *name, struct device *device); -- cgit v0.10.2 From 4d2acfbfdf68257e846aaa355edd10fc35ba0feb Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 23 May 2008 13:58:12 +0100 Subject: firmware: Add CONFIG_EXTRA_FIRMWARE option This allows arbitrary firmware files to be included in the static kernel where the firmware loader can find them without requiring userspace to be alive. (Updated and CONFIG_EXTRA_FIRMWARE_DIR added with lots of help from Johannes Berg). Signed-off-by: David Woodhouse Signed-off-by: Johannes Berg diff --git a/Makefile b/Makefile index 6315424..f398cff 100644 --- a/Makefile +++ b/Makefile @@ -450,7 +450,7 @@ scripts: scripts_basic include/config/auto.conf # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ -drivers-y := drivers/ sound/ +drivers-y := drivers/ sound/ firmware/ net-y := net/ libs-y := lib/ core-y := usr/ diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index d7da109..13cfcb4 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -34,6 +34,45 @@ config FW_LOADER require userspace firmware loading support, but a module built outside the kernel tree does. +config EXTRA_FIRMWARE + string "External firmware blobs to build into the kernel binary" + depends on FW_LOADER + help + This option allows firmware to be built into the kernel, for the + cases where the user either cannot or doesn't want to provide it from + userspace at runtime (for example, when the firmware in question is + required for accessing the boot device, and the user doesn't want to + use an initrd). + + This option is a string, and takes the (space-separated) names of the + firmware files -- the same names which appear in MODULE_FIRMWARE() + and request_firmware() in the source. These files should exist under + the directory specified by the EXTRA_FIRMWARE_DIR option, which is + by default the firmware/ subdirectory of the kernel source tree. + + So, for example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin", + copy the usb8388.bin file into the firmware/ directory, and build the + kernel. Then any request_firmware("usb8388.bin") will be + satisfied internally without needing to call out to userspace. + + WARNING: If you include additional firmware files into your binary + kernel image which are not available under the terms of the GPL, + then it may be a violation of the GPL to distribute the resulting + image -- since it combines both GPL and non-GPL work. You should + consult a lawyer of your own before distributing such an image. + +config EXTRA_FIRMWARE_DIR + string "Firmware blobs root directory" + depends on EXTRA_FIRMWARE != "" + default "firmware" + help + This option controls the directory in which the kernel build system + looks for the firmware files listed in the EXTRA_FIRMWARE option. + The default is the firmware/ directory in the kernel source tree, + but by changing this option you can point it elsewhere, such as + the /lib/firmware/ directory or another separate directory + containing firmware files. + config DEBUG_DRIVER bool "Driver Core verbose debug messages" depends on DEBUG_KERNEL diff --git a/firmware/Makefile b/firmware/Makefile new file mode 100644 index 0000000..e69461f --- /dev/null +++ b/firmware/Makefile @@ -0,0 +1,88 @@ +# +# kbuild file for firmware/ +# + +# Create $(fwabs) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a +# leading /, it's relative to $(srctree). +fwdir := $(subst ",,$(CONFIG_EXTRA_FIRMWARE_DIR)) +fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) + +fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) + +firmware-y := $(fw-external-y) $(fw-shipped-y) +firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y) $(fw-shipped-)))) + +quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) + cmd_mkdir = mkdir -p $@ + +quiet_cmd_ihex = IHEX $@ + cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@ + +quiet_cmd_fwbin = MK_FW $@ + cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ + FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ + firmware/%.gen.S,%,$@))))"; \ + ASM_WORD=$(if $(CONFIG_64BIT),.quad,.long); \ + ASM_ALIGN=$(if $(CONFIG_64BIT),3,2); \ + PROGBITS=$(if $(CONFIG_ARM),%,@)progbits; \ + echo "/* Generated by firmware/Makefile */" > $@;\ + echo " .section .rodata" >>$@;\ + echo " .p2align $${ASM_ALIGN}" >>$@;\ + echo "_fw_$${FWSTR}_bin:" >>$@;\ + echo " .incbin \"$(2)\"" >>$@;\ + echo "_fw_end:" >>$@;\ + echo " .section .rodata.str,\"aMS\",$${PROGBITS},1" >>$@;\ + echo " .p2align $${ASM_ALIGN}" >>$@;\ + echo "_fw_$${FWSTR}_name:" >>$@;\ + echo " .string \"$$FWNAME\"" >>$@;\ + echo " .section .builtin_fw,\"a\",$${PROGBITS}" >>$@;\ + echo " .p2align $${ASM_ALIGN}" >>$@;\ + echo " $${ASM_WORD} _fw_$${FWSTR}_name" >>$@;\ + echo " $${ASM_WORD} _fw_$${FWSTR}_bin" >>$@;\ + echo " $${ASM_WORD} _fw_end - _fw_$${FWSTR}_bin" >>$@; + +# One of these files will change, or come into existence, whenever +# the configuration changes between 32-bit and 64-bit. The .S files +# need to change when that happens. +wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \ + include/config/ppc32.h include/config/ppc64.h \ + include/config/superh32.h include/config/superh64.h \ + include/config/x86_32.h include/config/x86_64.h) + +# Workaround for make < 3.81, where .SECONDEXPANSION doesn't work. +# It'll end up depending on these targets, so make them a PHONY rule which +# depends on _all_ the directories in $(firmware-dirs), and it'll work out OK. +PHONY += $(objtree)/$$(%) $(objtree)/$(obj)/$$(%) +$(objtree)/$$(%) $(objtree)/$(obj)/$$(%): $(firmware-dirs) + @true + +# For the $$(dir %) trick, where we need % to be expanded first. +.SECONDEXPANSION: + +$(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) \ + | $(objtree)/$$(dir %) + $(call cmd,fwbin,$(patsubst %.gen.S,%,$@)) +$(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \ + include/config/builtin/firmware/dir.h | $(objtree)/$$(dir %) + $(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@)) + +# The .o files depend on the binaries directly; the .S files don't. +$(patsubst %,$(obj)/%.gen.o, $(fw-shipped-y)): %.gen.o: % +$(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/% + +$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) + $(call cmd,ihex) + +$(firmware-dirs): + $(call cmd,mkdir) + +obj-y := $(patsubst %,%.gen.o, $(firmware-y)) + +# Remove .S files and binaries created from ihex +# (during 'make clean' .config isn't included so they're all in $(fw-shipped-)) +targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \ + $(shell find $(obj) -name \*.gen.S 2>/dev/null)) + +# Without this, built-in.o won't be created when it's empty, and the +# final vmlinux link will fail. +obj-n := dummy -- cgit v0.10.2 From d172e7f5c67f2d41f453c7aa83d3bdb405ef8ba5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 25 Jun 2008 13:56:07 +0100 Subject: firmware: Add CONFIG_FIRMWARE_IN_KERNEL option. This will control whether we build firmware into the kernel image for _every_ driver which we convert to request_firmware(), to avoid a proliferation of 'CONFIG_XXX_FIRMWARE' options for each one. Default to 'y' for now, which is the wrong thing to do but people seem to be insisting on it and refusing to even review patches until it's done. And it does preserve the existing behaviour for built-in drivers. Signed-off-by: David Woodhouse diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 13cfcb4..d47482f 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -34,6 +34,31 @@ config FW_LOADER require userspace firmware loading support, but a module built outside the kernel tree does. +config FIRMWARE_IN_KERNEL + bool "Include in-kernel firmware blobs in kernel binary" + depends on FW_LOADER + default y + help + The kernel source tree includes a number of firmware 'blobs' + which are used by various drivers. The recommended way to + use these is to run "make firmware_install" and to copy the + resulting binary files created in usr/lib/firmware directory + of the kernel tree to the /lib/firmware on your system so + that they can be loaded by userspace helpers on request. + + Enabling this option will build each required firmware blob + into the kernel directly, where request_firmware() will find + them without having to call out to userspace. This may be + useful if your root file system requires a device which uses + such firmware, and do not wish to use an initrd. + + This single option controls the inclusion of firmware for + every driver which usees request_firmare() and ships its + firmware in the kernel source tree, to avoid a proliferation + of 'Include firmware for xxx device' options. + + Say 'N' and let firmware be loaded from userspace. + config EXTRA_FIRMWARE string "External firmware blobs to build into the kernel binary" depends on FW_LOADER diff --git a/firmware/Makefile b/firmware/Makefile index e69461f..cc25f56 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -9,6 +9,11 @@ fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) +# If CONFIG_FIRMWARE_IN_KERNEL is not set, then don't include any firmware +ifneq ($(CONFIG_FIRMWARE_IN_KERNEL),y) +fw-shipped-y := +endif + firmware-y := $(fw-external-y) $(fw-shipped-y) firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y) $(fw-shipped-)))) -- cgit v0.10.2 From 88ecf814c47f577248751ddbe9626d98aeef5783 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 11:01:51 +0300 Subject: firmware: Add firmware installation to modules_install, add firmware_install For 'make modules_install', install any firmware required by the modules which are being installed. Also add a 'make firmware_install' target which doesn't depend on the configuration, but installs _all_ available in-kernel-tree firmware into $(INSTALL_FW_PATH), which defaults to /lib/firmware. This is intended for distributors to make arch-independent (and config-independent) packages containing firmware. Signed-off-by: David Woodhouse diff --git a/Makefile b/Makefile index f398cff..bd2aa14 100644 --- a/Makefile +++ b/Makefile @@ -995,6 +995,16 @@ depend dep: @echo '*** Warning: make $@ is unnecessary now.' # --------------------------------------------------------------------------- +# Firmware install +INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware +export INSTALL_FW_PATH + +PHONY += firmware_install +firmware_install: FORCE + @mkdir -p $(objtree)/firmware + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install + +# --------------------------------------------------------------------------- # Kernel headers INSTALL_HDR_PATH=$(objtree)/usr export INSTALL_HDR_PATH @@ -1080,6 +1090,7 @@ _modinst_: # boot script depmod is the master version. PHONY += _modinst_post _modinst_post: _modinst_ + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst $(call cmd,depmod) else # CONFIG_MODULES @@ -1197,6 +1208,8 @@ help: @echo '* vmlinux - Build the bare kernel' @echo '* modules - Build all modules' @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)' + @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH' + @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)' @echo ' dir/ - Build all files in dir and below' @echo ' dir/file.[ois] - Build specified target only' @echo ' dir/file.ko - Build module including final link' diff --git a/firmware/Makefile b/firmware/Makefile index cc25f56..3742fee 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -9,13 +9,22 @@ fwabs := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) -# If CONFIG_FIRMWARE_IN_KERNEL is not set, then don't include any firmware -ifneq ($(CONFIG_FIRMWARE_IN_KERNEL),y) -fw-shipped-y := -endif +# There are three cases to care about: +# 1. Building kernel with CONFIG_FIRMWARE_IN_KERNEL=y -- $(fw-shipped-y) should +# include the firmware files to include, according to .config +# 2. 'make modules_install', which will install firmware for modules, and +# _also_ for the in-kernel drivers when CONFIG_FIRMWARE_IN_KERNEL=n +# 3. 'make firmware_install', which installs all firmware, unconditionally. -firmware-y := $(fw-external-y) $(fw-shipped-y) -firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(firmware-y) $(fw-shipped-)))) +# For the former two cases we want $(fw-shipped-y) and $(fw-shipped-m) to be +# accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). +# But be aware that the config file might not be included at all. + + +fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) + +# Directories which we _might_ need to create, so we have a rule for them. +firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(fw-external-y) $(fw-shipped-all)))) quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) cmd_mkdir = mkdir -p $@ @@ -81,7 +90,8 @@ $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) $(firmware-dirs): $(call cmd,mkdir) -obj-y := $(patsubst %,%.gen.o, $(firmware-y)) +obj-y += $(patsubst %,%.gen.o, $(fw-external-y)) +obj-$(CONFIG_FIRMWARE_IN_KERNEL) += $(patsubst %,%.gen.o, $(fw-shipped-y)) # Remove .S files and binaries created from ihex # (during 'make clean' .config isn't included so they're all in $(fw-shipped-)) diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst new file mode 100644 index 0000000..1c03008 --- /dev/null +++ b/scripts/Makefile.fwinst @@ -0,0 +1,45 @@ +# ========================================================================== +# Installing firmware +# +# We don't include the .config, so all firmware files are in $(fw-shipped-) +# rather than in $(fw-shipped-y) or $(fw-shipped-n). +# ========================================================================== + +INSTALL := install + +# For modules_install installing firmware, we want to see .config +# But for firmware_install, we don't care, but don't want to require it. +-include $(objtree)/.config + +include scripts/Kbuild.include +include $(srctree)/$(obj)/Makefile + +include scripts/Makefile.host + +mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-m)) + +# If CONFIG_FIRMWARE_IN_KERNEL isn't set, then install the +# firmware for in-kernel drivers too. +ifndef CONFIG_FIRMWARE_IN_KERNEL +mod-fw += $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-y)) +endif + +installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all)) +installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/. + +quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@) + cmd_install = $(INSTALL) -m0644 $< $@ + +$(installed-fw-dirs): + $(call cmd,mkdir) + +$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)/ + $(call cmd,install) + +.PHONY: __fw_install __fw_modinst FORCE + +__fw_install: $(installed-fw) +__fw_modinst: $(mod-fw) + + +FORCE: -- cgit v0.10.2 From bacfe09dd7545467965e8d8f1eab20bc62dce00d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 13:57:27 +0300 Subject: ihex.h: binary representation of ihex records Some devices need their firmware as a set of {address, len, data...} records in some specific order rather than a simple blob. The normal way of doing this kind of thing is 'ihex', which is a text format and not entirely suitable for use in the kernel. This provides a binary representation which is very similar, but much more compact -- and a helper routine to skip to the next record, because the alignment constraints mean that everybody will screw it up for themselves otherwise. Also a helper function which can verify that a 'struct firmware' contains a valid set of ihex records, and that following them won't run off the end of the loaded data. Signed-off-by: David Woodhouse diff --git a/include/linux/ihex.h b/include/linux/ihex.h new file mode 100644 index 0000000..df89edd --- /dev/null +++ b/include/linux/ihex.h @@ -0,0 +1,50 @@ +/* + * Compact binary representation of ihex records. Some devices need their + * firmware loaded in strange orders rather than a single big blob, but + * actually parsing ihex-as-text within the kernel seems silly. Thus,... + */ + +#ifndef __LINUX_IHEX_H__ +#define __LINUX_IHEX_H__ + +#include +#include + +/* Intel HEX files actually limit the length to 256 bytes, but we have + drivers which would benefit from using separate records which are + longer than that, so we extend to 16 bits of length */ +struct ihex_binrec { + __be32 addr; + __be16 len; + uint8_t data[0]; +} __attribute__((aligned(4))); + +/* Find the next record, taking into account the 4-byte alignment */ +static inline const struct ihex_binrec * +ihex_next_binrec(const struct ihex_binrec *rec) +{ + int next = ((be16_to_cpu(rec->len) + 5) & ~3) - 2; + rec = (void *)&rec->data[next]; + + return be16_to_cpu(rec->len) ? rec : NULL; +} + +/* Check that ihex_next_binrec() won't take us off the end of the image... */ +static inline int ihex_validate_fw(const struct firmware *fw) +{ + const struct ihex_binrec *rec; + size_t ofs = 0; + + while (ofs <= fw->size - sizeof(*rec)) { + rec = (void *)&fw->data[ofs]; + + /* Zero length marks end of records */ + if (!be16_to_cpu(rec->len)) + return 0; + + /* Point to next record... */ + ofs += (sizeof(*rec) + be16_to_cpu(rec->len) + 3) & ~3; + } + return -EINVAL; +} +#endif /* __LINUX_IHEX_H__ */ -- cgit v0.10.2 From f1485f3deb89e6ae10c4d34662ec9e692855ab5d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 31 May 2008 15:20:37 +0300 Subject: ihex: request_ihex_firmware() function to load and validate firmware Provide a helper to load the file and validate it in one call, to simplify error handling in the drivers which are going to use it. Signed-off-by: David Woodhouse diff --git a/include/linux/ihex.h b/include/linux/ihex.h index df89edd..2baace2 100644 --- a/include/linux/ihex.h +++ b/include/linux/ihex.h @@ -9,6 +9,7 @@ #include #include +#include /* Intel HEX files actually limit the length to 256 bytes, but we have drivers which would benefit from using separate records which are @@ -47,4 +48,27 @@ static inline int ihex_validate_fw(const struct firmware *fw) } return -EINVAL; } + +/* Request firmware and validate it so that we can trust we won't + * run off the end while reading records... */ +static inline int request_ihex_firmware(const struct firmware **fw, + const char *fw_name, + struct device *dev) +{ + const struct firmware *lfw; + int ret; + + ret = request_firmware(&lfw, fw_name, dev); + if (ret) + return ret; + ret = ihex_validate_fw(lfw); + if (ret) { + dev_err(dev, "Firmware \"%s\" not valid IHEX records\n", + fw_name); + release_firmware(lfw); + return ret; + } + *fw = lfw; + return 0; +} #endif /* __LINUX_IHEX_H__ */ -- cgit v0.10.2 From 8bd6b2229bf98761465020467ec33547d05bff46 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 31 May 2008 15:07:18 +0300 Subject: ihex: add ihex2fw tool for converting HEX files into firmware images Not the straight conversion to binary which objcopy can do for us, but actually representing each record with its original {addr, length}, because some drivers need that information preserved. Fix up 'firmware_install' to be able to build $(hostprogs-y) too. Signed-off-by: David Woodhouse diff --git a/firmware/Makefile b/firmware/Makefile index 3742fee..9e780a3 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,6 +32,9 @@ quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) quiet_cmd_ihex = IHEX $@ cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@ +quiet_cmd_ihex2fw = IHEX2FW $@ + cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ + quiet_cmd_fwbin = MK_FW $@ cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ @@ -84,9 +87,18 @@ $(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \ $(patsubst %,$(obj)/%.gen.o, $(fw-shipped-y)): %.gen.o: % $(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/% +# .ihex is used just as a simple way to hold binary files in a source tree +# where binaries are frowned upon. They are directly converted with objcopy. $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) $(call cmd,ihex) +# .HEX is also Intel HEX, but where the offset and length in each record +# is actually meaningful, because the firmware has to be loaded in a certain +# order rather than as a single binary blob. Thus, we convert them into our +# more compact binary representation of ihex records () +$(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) + $(call cmd,ihex2fw) + $(firmware-dirs): $(call cmd,mkdir) @@ -101,3 +113,5 @@ targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \ # Without this, built-in.o won't be created when it's empty, and the # final vmlinux link will fail. obj-n := dummy + +hostprogs-y := ihex2fw diff --git a/firmware/ihex2fw.c b/firmware/ihex2fw.c new file mode 100644 index 0000000..9e77cd2 --- /dev/null +++ b/firmware/ihex2fw.c @@ -0,0 +1,247 @@ +/* + * Parser/loader for IHEX formatted data. + * + * Copyright © 2008 David Woodhouse + * Copyright © 2005 Jan Harkes + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ihex_binrec { + struct ihex_binrec *next; /* not part of the real data structure */ + uint32_t addr; + uint16_t len; + uint8_t data[]; +}; + +/** + * nybble/hex are little helpers to parse hexadecimal numbers to a byte value + **/ +static uint8_t nybble(const uint8_t n) +{ + if (n >= '0' && n <= '9') return n - '0'; + else if (n >= 'A' && n <= 'F') return n - ('A' - 10); + else if (n >= 'a' && n <= 'f') return n - ('a' - 10); + return 0; +} + +static uint8_t hex(const uint8_t *data, uint8_t *crc) +{ + uint8_t val = (nybble(data[0]) << 4) | nybble(data[1]); + *crc += val; + return val; +} + +static int process_ihex(uint8_t *data, ssize_t size); +static void file_record(struct ihex_binrec *record); +static int output_records(int outfd); + +static int sort_records = 0; + +int main(int argc, char **argv) +{ + int infd, outfd; + struct stat st; + uint8_t *data; + + if (argc == 4 && !strcmp(argv[1], "-s")) { + sort_records = 1; + argc--; + argv++; + } + if (argc != 3) { + usage: + fprintf(stderr, "ihex2fw: Convert ihex files into binary " + "representation for use by Linux kernel\n"); + fprintf(stderr, "usage: ihex2fw [-s] \n"); + fprintf(stderr, " -s: sort records by address\n"); + return 1; + } + if (!strcmp(argv[1], "-")) + infd = 0; + else + infd = open(argv[1], O_RDONLY); + if (infd == -1) { + fprintf(stderr, "Failed to open source file: %s", + strerror(errno)); + goto usage; + } + if (fstat(infd, &st)) { + perror("stat"); + return 1; + } + data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, infd, 0); + if (data == MAP_FAILED) { + perror("mmap"); + return 1; + } + + if (!strcmp(argv[2], "-")) + outfd = 1; + else + outfd = open(argv[2], O_TRUNC|O_CREAT|O_WRONLY, 0644); + if (outfd == -1) { + fprintf(stderr, "Failed to open destination file: %s", + strerror(errno)); + goto usage; + } + if (process_ihex(data, st.st_size)) + return 1; + + output_records(outfd); + return 0; +} + +static int process_ihex(uint8_t *data, ssize_t size) +{ + struct ihex_binrec *record; + uint32_t offset = 0; + uint8_t type, crc = 0, crcbyte = 0; + int i, j; + int line = 1; + int len; + + i = 0; +next_record: + /* search for the start of record character */ + while (i < size) { + if (data[i] == '\n') line++; + if (data[i++] == ':') break; + } + + /* Minimum record length would be about 10 characters */ + if (i + 10 > size) { + fprintf(stderr, "Can't find valid record at line %d\n", line); + return -EINVAL; + } + + len = hex(data + i, &crc); i += 2; + + record = malloc((sizeof (*record) + len + 3) & ~3); + if (!record) { + fprintf(stderr, "out of memory for records\n"); + return -ENOMEM; + } + memset(record, 0, (sizeof(*record) + len + 3) & ~3); + record->len = len; + + /* now check if we have enough data to read everything */ + if (i + 8 + (record->len * 2) > size) { + fprintf(stderr, "Not enough data to read complete record at line %d\n", + line); + return -EINVAL; + } + + record->addr = hex(data + i, &crc) << 8; i += 2; + record->addr |= hex(data + i, &crc); i += 2; + type = hex(data + i, &crc); i += 2; + + for (j = 0; j < record->len; j++, i += 2) + record->data[j] = hex(data + i, &crc); + + /* check CRC */ + crcbyte = hex(data + i, &crc); i += 2; + if (crc != 0) { + fprintf(stderr, "CRC failure at line %d: got 0x%X, expected 0x%X\n", + line, crcbyte, (unsigned char)(crcbyte-crc)); + return -EINVAL; + } + + /* Done reading the record */ + switch (type) { + case 0: + /* old style EOF record? */ + if (!record->len) + break; + + record->addr += offset; + file_record(record); + goto next_record; + + case 1: /* End-Of-File Record */ + if (record->addr || record->len) { + fprintf(stderr, "Bad EOF record (type 01) format at line %d", + line); + return -EINVAL; + } + break; + + case 2: /* Extended Segment Address Record (HEX86) */ + case 4: /* Extended Linear Address Record (HEX386) */ + if (record->addr || record->len != 2) { + fprintf(stderr, "Bad HEX86/HEX386 record (type %02X) at line %d\n", + type, line); + return -EINVAL; + } + + /* We shouldn't really be using the offset for HEX86 because + * the wraparound case is specified quite differently. */ + offset = record->data[0] << 8 | record->data[1]; + offset <<= (type == 2 ? 4 : 16); + goto next_record; + + case 3: /* Start Segment Address Record */ + case 5: /* Start Linear Address Record */ + if (record->addr || record->len != 4) { + fprintf(stderr, "Bad Start Address record (type %02X) at line %d\n", + type, line); + return -EINVAL; + } + + /* These records contain the CS/IP or EIP where execution + * starts. Don't really know what to do with them. */ + goto next_record; + + default: + fprintf(stderr, "Unknown record (type %02X)\n", type); + return -EINVAL; + } + + return 0; +} + +static struct ihex_binrec *records; + +static void file_record(struct ihex_binrec *record) +{ + struct ihex_binrec **p = &records; + + while ((*p) && (!sort_records || (*p)->addr < record->addr)) + p = &((*p)->next); + + record->next = *p; + *p = record; +} + +static int output_records(int outfd) +{ + unsigned char zeroes[5] = {0, 0, 0, 0, 0}; + struct ihex_binrec *p = records; + + while (p) { + uint16_t writelen = (p->len + 9) & ~3; + + p->addr = htonl(p->addr); + p->len = htonl(p->len); + write(outfd, &p->addr, writelen); + p = p->next; + } + /* EOF record is zero length, since we don't bother to represent + the type field in the binary version */ + write(outfd, zeroes, 5); + return 0; +} diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index 1c03008..3d2f460 100644 --- a/scripts/Makefile.fwinst +++ b/scripts/Makefile.fwinst @@ -6,6 +6,7 @@ # ========================================================================== INSTALL := install +src := $(obj) # For modules_install installing firmware, we want to see .config # But for firmware_install, we don't care, but don't want to require it. @@ -41,5 +42,4 @@ $(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)/ __fw_install: $(installed-fw) __fw_modinst: $(mod-fw) - FORCE: -- cgit v0.10.2 From 59890f74e51abffd0dd017785d89f8a8475d489d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 26 Jun 2008 13:55:30 +0100 Subject: ihex: Add support for long records to ihex2fw.c Some drivers could do with using records like Intel HEX, but with each record being larger than 256 bytes. This has been possible in the binary representation (struct ihex_binrec) in the kernel since the beginning -- at least of the the current version of history. But we haven't been able to represent that in the .HEX files which get converted to .fw files. This adds a '-w' option to ihex2fw to make it interpret the first _two_ bytes of each line as the record length, instead of only one byte. And adds makefile rules for %.H16->%.fw which use that. Signed-off-by: David Woodhouse diff --git a/firmware/Makefile b/firmware/Makefile index 9e780a3..40881a9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -35,6 +35,9 @@ quiet_cmd_ihex = IHEX $@ quiet_cmd_ihex2fw = IHEX2FW $@ cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ +quiet_cmd_h16tofw = H16TOFW $@ + cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@ + quiet_cmd_fwbin = MK_FW $@ cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ @@ -99,6 +102,10 @@ $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) $(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) $(call cmd,ihex2fw) +# .H16 is our own modified form of Intel HEX, with 16-bit length for records. +$(obj)/%.fw: $(obj)/%.H16 $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) + $(call cmd,h16tofw) + $(firmware-dirs): $(call cmd,mkdir) diff --git a/firmware/ihex2fw.c b/firmware/ihex2fw.c index 9e77cd2..660b191 100644 --- a/firmware/ihex2fw.c +++ b/firmware/ihex2fw.c @@ -20,6 +20,9 @@ #include #include #include +#define _GNU_SOURCE +#include + struct ihex_binrec { struct ihex_binrec *next; /* not part of the real data structure */ @@ -51,34 +54,49 @@ static void file_record(struct ihex_binrec *record); static int output_records(int outfd); static int sort_records = 0; +static int wide_records = 0; + +int usage(void) +{ + fprintf(stderr, "ihex2fw: Convert ihex files into binary " + "representation for use by Linux kernel\n"); + fprintf(stderr, "usage: ihex2fw [] \n"); + fprintf(stderr, " -w: wide records (16-bit length)\n"); + fprintf(stderr, " -s: sort records by address\n"); + return 1; +} int main(int argc, char **argv) { int infd, outfd; struct stat st; uint8_t *data; + int opt; - if (argc == 4 && !strcmp(argv[1], "-s")) { - sort_records = 1; - argc--; - argv++; - } - if (argc != 3) { - usage: - fprintf(stderr, "ihex2fw: Convert ihex files into binary " - "representation for use by Linux kernel\n"); - fprintf(stderr, "usage: ihex2fw [-s] \n"); - fprintf(stderr, " -s: sort records by address\n"); - return 1; + while ((opt = getopt(argc, argv, "ws")) != -1) { + switch (opt) { + case 'w': + wide_records = 1; + break; + case 's': + sort_records = 1; + break; + default: + return usage(); + } } - if (!strcmp(argv[1], "-")) + + if (optind + 2 != argc) + return usage(); + + if (!strcmp(argv[optind], "-")) infd = 0; else - infd = open(argv[1], O_RDONLY); + infd = open(argv[optind], O_RDONLY); if (infd == -1) { fprintf(stderr, "Failed to open source file: %s", strerror(errno)); - goto usage; + return usage(); } if (fstat(infd, &st)) { perror("stat"); @@ -90,14 +108,14 @@ int main(int argc, char **argv) return 1; } - if (!strcmp(argv[2], "-")) + if (!strcmp(argv[optind+1], "-")) outfd = 1; else - outfd = open(argv[2], O_TRUNC|O_CREAT|O_WRONLY, 0644); + outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644); if (outfd == -1) { fprintf(stderr, "Failed to open destination file: %s", strerror(errno)); - goto usage; + return usage(); } if (process_ihex(data, st.st_size)) return 1; @@ -130,7 +148,10 @@ next_record: } len = hex(data + i, &crc); i += 2; - + if (wide_records) { + len <<= 8; + len += hex(data + i, &crc); i += 2; + } record = malloc((sizeof (*record) + len + 3) & ~3); if (!record) { fprintf(stderr, "out of memory for records\n"); -- cgit v0.10.2 From 76770664dcbc008300c2ac8747671efcc4f78c2d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 26 May 2008 23:01:27 +0100 Subject: firmware: convert korg1212 driver to use firmware loader exclusively Signed-off-by: David Woodhouse diff --git a/firmware/Makefile b/firmware/Makefile index 40881a9..ea4a883 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -20,6 +20,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). # But be aware that the config file might not be included at all. +fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE new file mode 100644 index 0000000..89ca95b --- /dev/null +++ b/firmware/WHENCE @@ -0,0 +1,19 @@ + ********** + * WHENCE * + ********** + +This file attempts to document the origin and licensing information, +if known, for each piece of firmware distributed for use with the Linux +kernel. + +-------------------------------------------------------------------------- + +Driver: korg1212 -- Korg 1212 IO audio device + +File: korg/k1212.dsp + +Licence: Unknown + +Found in alsa-firmware package in hex form; no licensing information. + +-------------------------------------------------------------------------- diff --git a/firmware/korg/k1212.dsp.ihex b/firmware/korg/k1212.dsp.ihex new file mode 100644 index 0000000..b151997 --- /dev/null +++ b/firmware/korg/k1212.dsp.ihex @@ -0,0 +1,987 @@ +:1000000001FF18FFF5FFCFFF00FF00FFFFFF00FF1C +:1000100000FF00FFFFFF00FF00FF00FFFFFF00FFEA +:1000200026FF18FFFFFF0FFF00FF00FFFFFF00FF8D +:1000300000FF00FFFFFF00FF00FF00FFFFFF00FFCA +:1000400000FF0AFFFFFF1FFF00FF00FFFFFF00FF91 +:1000500000FF00FFFFFF00FF00FF00FFFFFF00FFAA +:1000600000FF0AFFFFFF1FFF00FF00FFFFFF00FF71 +:1000700000FF00FFFFFF00FF00FF00FFFFFF00FF8A +:1000800000FF0AFFFFFF1FFF00FF00FFFFFF00FF51 +:1000900000FF00FFFFFF00FF00FF00FFFFFF00FF6A +:1000A00038FF18FFFFFFDFFF00FF00FFFFFF00FF2B +:1000B00000FF00FFFFFF00FF00FF00FFFFFF00FF4A +:1000C00000FF0AFFFFFF1FFF00FF00FFFFFF00FF11 +:1000D00000FF00FFFFFF00FF00FF00FFFFFF00FF2A +:1000E00003FF3CFFFFFFFCFF67FF40FFFFFFC0FF78 +:1000F000FFFF93FFFFFFE0FF00FF0CFFFFFF0CFF80 +:100100000CFF0CFFFFFF00FF30FF0CFFFFFF00FFA5 +:100110000FFF40FFFFFFF4FF47FF80FFFFFF0AFFD5 +:1001200082FF23FFFFFF0FFF8DFF93FFFFFF7AFF8B +:100130008DFF83FFFFFF70FF47FF90FFFFFF00FF72 +:1001400000FF48FFFFFF04FFA0FF23FFFFFF0FFF9B +:1001500046FF90FFFFFF6AFF00FF0CFFFFFF20FF3D +:1001600000FF04FFFFFF1CFF00FF04FFFFFF1CFF59 +:1001700000FF04FFFFFF1CFF00FF04FFFFFF1CFF49 +:1001800000FF04FFFFFF10FF00FF04FFFFFF10FF51 +:1001900000FF04FFFFFF10FF00FF04FFFFFF10FF41 +:1001A00000FF04FFFFFF10FF00FF04FFFFFF10FF31 +:1001B00000FF04FFFFFF10FF00FF04FFFFFF10FF21 +:1001C00000FF04FFFFFF10FF00FF04FFFFFF10FF11 +:1001D00000FF04FFFFFF10FF00FF04FFFFFF10FF01 +:1001E00072FF1CFFFFFF5FFF02FF40FFFFFF40FFAA +:1001F00011FF90FFFFFF20FF00FF48FFFFFF00FF00 +:100200008BFF93FFFFFF20FF00FF40FFFFFF00FF7A +:1002100086FF93FFFFFF70FF8BFF93FFFFFF30FF11 +:100220008DFF93FFFFFF40FF02FF91FFFFFF80FF65 +:1002300002FF91FFFFFF90FF8DFF93FFFFFFC0FFC5 +:1002400046FF90FFFFFF20FF8DFF93FFFFFFD0FFD2 +:1002500000FF48FFFFFF00FF8BFF93FFFFFF40FF02 +:10026000FFFF47FFFFFFF0FF8DFF93FFFFFFE0FF62 +:1002700000FF34FFFFFF17FF00FF38FFFFFF17FFEE +:1002800080FF37FFFFFF02FF84FF3BFFFFFF02FFFE +:1002900002FF34FFFFFF4AFF02FF38FFFFFF4AFF64 +:1002A00001FF34FFFFFF2BFF01FF38FFFFFF2BFF94 +:1002B00080FF43FFFFFF00FF82FF93FFFFFF50FF20 +:1002C00081FF43FFFFFF20FF82FF93FFFFFF60FFDF +:1002D00084FF43FFFFFF00FF82FF93FFFFFF70FFDC +:1002E00085FF43FFFFFF20FF83FF93FFFFFFC0FF5A +:1002F00082FF37FFFFFF81FF00FF34FFFFFF89FF11 +:1003000088FF43FFFFFF00FF00FF68FFFFFF07FFBD +:1003100082FF83FFFFFF60FF00FF68FFFFFF07FF13 +:100320008CFF43FFFFFF00FF00FF68FFFFFF07FF99 +:1003300083FF83FFFFFFC0FF00FF68FFFFFF07FF92 +:100340008AFF43FFFFFF00FF00FF68FFFFFF07FF7B +:1003500082FF83FFFFFF50FF00FF68FFFFFF07FFE3 +:100360008EFF43FFFFFF00FF00FF68FFFFFF07FF57 +:1003700082FF83FFFFFF70FF00FF68FFFFFF07FFA3 +:1003800083FF37FFFFFF01FF00FF34FFFFFF89FFFF +:1003900000FF34FFFFFF26FF30FF0CFFFFFF00FFD1 +:1003A00000FF40FFFFFF26FF20FF40FFFFFF04FF8D +:1003B00080FF41FFFFFF02FFE0FF20FFFFFF0FFF75 +:1003C00000FF68FFFFFFB6FF63FF22FFFFFF0FFF85 +:1003D00062FF6AFFFFFFA6FF62FF6AFFFFFFA6FF43 +:1003E00000FF68FFFFFFA6FF00FF09FFFFFF07FFF9 +:1003F00040FF41FFFFFF02FFE0FF20FFFFFF0FFF75 +:1004000000FF68FFFFFFB6FF63FF22FFFFFF0FFF44 +:1004100062FF6AFFFFFFA6FF62FF6AFFFFFFA6FF02 +:1004200000FF68FFFFFFA6FF05FF41FFFFFF02FF80 +:10043000E0FF20FFFFFF0FFF8BFF93FFFFFFBBFFDE +:1004400002FF41FFFFFF82FFE0FF20FFFFFF0FFFE2 +:100450008BFF93FFFFFFCBFF05FF41FFFFFFE2FF95 +:10046000E0FF20FFFFFF0FFF8BFF93FFFFFFDBFF8E +:1004700020FF0CFFFFFF00FF30FF0CFFFFFF00FF1E +:1004800000FF40FFFFFF26FF00FF41FFFFFF02FFCD +:10049000E0FF20FFFFFF0FFF83FF93FFFFFF82FFBF +:1004A00083FF93FFFFFF9BFF03FF41FFFFFF02FF5F +:1004B000E0FF20FFFFFF0FFF83FF93FFFFFFA2FF7F +:1004C00083FF93FFFFFFBBFF20FF0CFFFFFF00FF39 +:1004D00000FF40FFFFFF00FF44FF90FFFFFF60FFB2 +:1004E00000FF00FFFFFF00FF00FF00FFFFFF00FF16 +:1004F00000FF00FFFFFF00FF00FF00FFFFFF00FF06 +:1005000000FF00FFFFFF00FF00FF00FFFFFF00FFF5 +:1005100000FF00FFFFFF00FF00FF00FFFFFF00FFE5 +:1005200021FF40FFFFFF60FF40FF90FFFFFF20FF24 +:1005300002FF35FFFFFF00FF00FF34FFFFFF08FF52 +:1005400000FF3CFFFFFF85FF0AFF14FFFFFFAEFF28 +:1005500000FFA0FFFFFF03FF00FF35FFFFFF00FFCD +:1005600000FF34FFFFFF08FF02FF3CFFFFFF05FF16 +:100570000AFF14FFFFFFFEFF00FFA0FFFFFF03FFC6 +:1005800003FF35FFFFFF00FF00FF34FFFFFF08FF01 +:1005900002FF3CFFFFFF05FF0BFF14FFFFFF4EFFB5 +:1005A00000FFA0FFFFFF03FF00FF35FFFFFF01FF7C +:1005B00078FF1CFFFFFF5FFF03FF35FFFFFF01FF19 +:1005C00078FF1CFFFFFF5FFF5BFF40FFFFFFF0FFB7 +:1005D000FFFF93FFFFFF30FF80FF42FFFFFF70FF31 +:1005E000FFFF93FFFFFF60FFDFFF40FFFFFFF0FF14 +:1005F000FEFF93FFFFFFF0FF80FF42FFFFFF70FF52 +:10060000FFFF93FFFFFF20FFC1FF41FFFFFF80FFC0 +:10061000FFFF93FFFFFFF0FF03FF3CFFFFFFFCFF27 +:1006200000FF3CFFFFFF04FF02FF3CFFFFFF23FF33 +:1006300000FF48FFFFFF00FF8BFF93FFFFFF20FF3E +:1006400059FF18FFFFFFDFFF00FF48FFFFFF00FF1C +:100650008BFF93FFFFFF20FF18FF23FFFFFF0FFF1C +:100660000CFF14FFFFFFE4FF8BFF83FFFFFF24FF5E +:1006700000FF22FFFFFF0FFF0DFF18FFFFFF0FFF1F +:100680008BFF83FFFFFF20FF00FF40FFFFFF14FFF2 +:10069000E0FF22FFFFFF0FFF10FF18FFFFFFD0FF5B +:1006A0008BFF83FFFFFF20FF00FF40FFFFFF24FFC2 +:1006B000E0FF22FFFFFF0FFF10FF18FFFFFF30FFDB +:1006C0008BFF83FFFFFF20FF00FF40FFFFFF44FF82 +:1006D000E0FF22FFFFFF0FFF22FF18FFFFFF90FF49 +:1006E0008BFF83FFFFFF20FF00FF40FFFFFF84FF22 +:1006F000E0FF22FFFFFF0FFF22FF18FFFFFF90FF29 +:100700000CFF18FFFFFF6FFF00FF40FFFFFF00FF20 +:1007100086FF93FFFFFF70FF76FF1CFFFFFF9FFF29 +:1007200086FF83FFFFFF50FF86FF83FFFFFF64FF0D +:1007300060FF22FFFFFF0FFF74FF18FFFFFF81FF25 +:1007400000FF35FFFFFF00FF60FF1CFFFFFF7FFF83 +:1007500061FF1CFFFFFFAFFF77FF1CFFFFFFAFFF35 +:1007600063FF1CFFFFFF4FFF05FF35FFFFFF00FF8B +:1007700092FF3BFFFFFF00FF00FF34FFFFFF08FF7A +:1007800000FF38FFFFFF08FF00FF3CFFFFFF65FF92 +:100790000FFF14FFFFFF6EFF00FF60FFFFFF03FF6F +:1007A00000FF60FFFFFF13FF00FF78FFFFFF13FF55 +:1007B00000FF78FFFFFF03FF05FF35FFFFFFE0FFAE +:1007C0007FFF38FFFFFF00FF00FF34FFFFFF08FF40 +:1007D00000FF38FFFFFF08FF00FF3CFFFFFF65FF42 +:1007E00010FF14FFFFFF0EFF00FF60FFFFFF03FF7E +:1007F00000FF60FFFFFF13FF00FF58FFFFFF13FF25 +:1008000000FF58FFFFFF03FF79FF1CFFFFFFFFFF03 +:1008100000FF0AFFFFFF0FFF0EFF1CFFFFFF1FFF80 +:100820008DFF83FFFFFFE0FF78FF22FFFFFF0FFF39 +:1008300015FF1CFFFFFF85FF75FF1CFFFFFF8FFFEC +:1008400000FF40FFFFFF40FF8BFF93FFFFFF80FF94 +:1008500002FF40FFFFFF60FF11FF90FFFFFF20FF3F +:1008600016FF18FFFFFF1FFF0EFF1CFFFFFF1FFFFC +:1008700075FF1CFFFFFF8FFF80FF35FFFFFF00FFAD +:1008800000FF34FFFFFF08FF00FF40FFFFFF00FFF6 +:1008900040FF3CFFFFFF05FF11FF14FFFFFF4EFF6E +:1008A00000FF68FFFFFF03FF87FF83FFFFFFF0FFED +:1008B00086FF93FFFFFF80FF90FF37FFFFFF00FFE2 +:1008C00002FF34FFFFFF08FF00FF60FFFFFF03FF91 +:1008D00089FF93FFFFFF20FF00FF60FFFFFF03FF83 +:1008E00089FF93FFFFFF30FF00FF60FFFFFF03FF63 +:1008F00089FF93FFFFFF40FF00FF60FFFFFF03FF43 +:1009000089FF93FFFFFF50FF86FF97FFFFFF90FFD8 +:1009100003FF35FFFFFF00FF60FF1CFFFFFF7FFFAE +:1009200063FF1CFFFFFF7FFF00FF40FFFFFF00FF93 +:100930008DFF93FFFFFF60FF82FF93FFFFFF40FFEC +:1009400086FF93FFFFFFA0FF83FF37FFFFFF80FFBE +:1009500075FF1CFFFFFF1FFF83FF43FFFFFF00FF2B +:1009600087FF93FFFFFFE0FF6AFF1CFFFFFF0FFF02 +:1009700040FF41FFFFFF00FF8BFF93FFFFFF90FF52 +:1009800080FF41FFFFFF00FF8BFF93FFFFFFA0FFF2 +:100990008BFF87FFFFFF90FF7EFF38FFFFFF00FF09 +:1009A00040FF34FFFFFF08FF00FF38FFFFFF08FF95 +:1009B00000FF3CFFFFFF55FF13FF14FFFFFFBEFFCB +:1009C00000FF60FFFFFF03FF00FF60FFFFFF13FF5B +:1009D00000FF58FFFFFF13FF00FF58FFFFFF03FF5B +:1009E00000FF60FFFFFF03FF00FF60FFFFFF13FF3B +:1009F00000FF58FFFFFF13FF00FF58FFFFFF03FF3B +:100A000000FF60FFFFFF03FF00FF60FFFFFF13FF1A +:100A100000FF58FFFFFF13FF00FF58FFFFFF03FF1A +:100A200000FF60FFFFFF03FF00FF60FFFFFF03FF0A +:100A30008BFF97FFFFFF90FF05FF41FFFFFF00FFC8 +:100A400092FF43FFFFFF01FF86FF93FFFFFFF0FFD1 +:100A500086FF93FFFFFFE1FF8DFF83FFFFFFE0FFB6 +:100A600078FF22FFFFFF0FFF15FF1CFFFFFF85FF31 +:100A700075FF1CFFFFFF8FFF8DFF83FFFFFF40FF10 +:100A800078FF22FFFFFF0FFF53FF18FFFFFFB4FFA8 +:100A900072FF1CFFFFFF0FFF00FF40FFFFFF00FF83 +:100AA0008BFF93FFFFFF30FF02FF40FFFFFF60FF60 +:100AB00011FF90FFFFFF20FF16FF18FFFFFF4FFF02 +:100AC00038FF42FFFFFF50FF48FF90FFFFFFA0FFEE +:100AD00000FF00FFFFFF00FF00FF00FFFFFF00FF20 +:100AE00000FF00FFFFFF00FF00FF00FFFFFF00FF10 +:100AF00030FF40FFFFFF00FF47FF90FFFFFF50FF69 +:100B000000FF0AFFFFFF0FFF1EFF1CFFFFFF0FFF8D +:100B100020FF1CFFFFFFCFFF16FF18FFFFFF1FFF87 +:100B200000FF40FFFFFF00FF46FF90FFFFFF70FF49 +:100B300018FF1CFFFFFFEFFF6AFF1CFFFFFFBFFF57 +:100B40005CFF1CFFFFFF7FFF18FF1CFFFFFFEFFF95 +:100B500067FF1CFFFFFF3FFF5CFF1CFFFFFF7FFFE6 +:100B600008FF40FFFFFF00FF46FF90FFFFFF70FF01 +:100B700018FF1CFFFFFFEFFF69FF1CFFFFFF0FFFC8 +:100B80005DFF1CFFFFFF2FFF18FF1CFFFFFFEFFFA4 +:100B900079FF1CFFFFFF1FFF5CFF1CFFFFFF7FFFB4 +:100BA00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFF35 +:100BB00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFF25 +:100BC00018FF1CFFFFFFEFFF5DFF1CFFFFFF2FFF64 +:100BD00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFF05 +:100BE00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFF5 +:100BF00018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFE5 +:100C000018FF1CFFFFFFEFFF5DFF1CFFFFFF2FFF23 +:100C100018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFC4 +:100C200018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFB4 +:100C300018FF1CFFFFFFEFFF5CFF1CFFFFFF7FFFA4 +:100C400018FF1CFFFFFFEFFF5DFF1CFFFFFF2FFFE3 +:100C500018FF1CFFFFFFEFFF66FF1CFFFFFF1FFFDA +:100C60005CFF1CFFFFFF7FFF16FF18FFFFFF4FFF1A +:100C70008BFF87FFFFFF61FF00FF34FFFFFF89FF4E +:100C800000FF34FFFFFF26FF00FF60FFFFFF06FFAE +:100C900083FF93FFFFFFD0FF00FF60FFFFFF06FF12 +:100CA00083FF93FFFFFFE0FF38FF22FFFFFF0FFFEF +:100CB00019FF14FFFFFF85FF8BFF83FFFFFF50FF2E +:100CC00078FF22FFFFFF0FFF00FF60FFFFFF07FF1E +:100CD00004FF0DFFFFFF30FF00FF60FFFFFF07FF76 +:100CE00083FF93FFFFFFF0FF00FF60FFFFFF07FFA1 +:100CF00008FF0DFFFFFF30FF00FF60FFFFFF07FF52 +:100D000086FF93FFFFFF40FF00FF40FFFFFF01FF53 +:100D10008BFF93FFFFFF51FF00FF34FFFFFF46FFF4 +:100D200000FF09FFFFFF06FF8BFF97FFFFFF61FF3B +:100D300083FF8BFFFFFFD0FF83FF8BFFFFFFE1FFF0 +:100D400087FF37FFFFFF01FF6EFF1CFFFFFFBFFFA5 +:100D500087FF37FFFFFF00FF92FF37FFFFFF01FF15 +:100D60007FFF38FFFFFF00FF7EFF38FFFFFF01FF1F +:100D700023FF1CFFFFFFFFFF7EFF38FFFFFF00FF89 +:100D800083FF87FFFFFFF1FF86FF8BFFFFFF41FF20 +:100D90006CFF1CFFFFFF2FFF87FF37FFFFFF00FFE8 +:100DA0008BFF8BFFFFFFA0FF00FF34FFFFFF08FF5B +:100DB00040FF38FFFFFF08FF00FF3CFFFFFF55FF2C +:100DC0001BFF14FFFFFFCEFF00FF60FFFFFF03FFCD +:100DD00000FF60FFFFFF13FF00FF78FFFFFF13FF1F +:100DE00000FF78FFFFFF03FF00FF60FFFFFF03FF2F +:100DF00000FF60FFFFFF13FF00FF78FFFFFF13FFFF +:100E000000FF78FFFFFF03FF00FF60FFFFFF03FF0E +:100E100000FF60FFFFFF13FF00FF78FFFFFF13FFDE +:100E200000FF78FFFFFF03FF8BFF83FFFFFFE1FF62 +:100E30008BFF83FFFFFFF0FF00FF78FFFFFF13FF33 +:100E400000FF78FFFFFF03FF8BFF9BFFFFFFA0FF6B +:100E50008BFF87FFFFFF90FF7EFF38FFFFFF00FF44 +:100E600040FF34FFFFFF08FF00FF38FFFFFF08FFD0 +:100E700000FF3CFFFFFF55FF1DFF14FFFFFF3EFF7C +:100E800000FF60FFFFFF03FF00FF60FFFFFF13FF96 +:100E900000FF58FFFFFF13FF00FF58FFFFFF03FF96 +:100EA00000FF60FFFFFF03FF00FF60FFFFFF13FF76 +:100EB00000FF58FFFFFF13FF00FF58FFFFFF03FF76 +:100EC00000FF60FFFFFF03FF00FF60FFFFFF13FF56 +:100ED00000FF58FFFFFF13FF00FF58FFFFFF03FF56 +:100EE00000FF60FFFFFF03FF00FF60FFFFFF03FF46 +:100EF0008BFF97FFFFFF90FF00FF0AFFFFFF0FFF31 +:100F00008BFF87FFFFFF61FF00FF34FFFFFF89FFBB +:100F100000FF34FFFFFF26FF00FF60FFFFFF06FF1B +:100F200083FF93FFFFFFD0FF00FF60FFFFFF06FF7F +:100F300083FF93FFFFFFE0FF8BFF83FFFFFF51FF66 +:100F400079FF22FFFFFF0FFF74FF18FFFFFFB4FFC1 +:100F500038FF22FFFFFF0FFF1EFF14FFFFFFD5FF2B +:100F60008BFF83FFFFFF50FF78FF22FFFFFF0FFF84 +:100F700000FF60FFFFFF07FF04FF0DFFFFFF30FFD3 +:100F800000FF60FFFFFF07FF83FF93FFFFFFF0FFFE +:100F900000FF60FFFFFF07FF08FF0DFFFFFF30FFAF +:100FA00000FF60FFFFFF07FF86FF93FFFFFF40FF8B +:100FB00000FF40FFFFFF01FF8BFF93FFFFFF51FF8B +:100FC00000FF34FFFFFF46FF00FF09FFFFFF06FFA2 +:100FD0008BFF97FFFFFF61FF83FF8BFFFFFFD0FFBA +:100FE00083FF8BFFFFFFE1FF87FF37FFFFFF01FF5D +:100FF0006EFF1CFFFFFFBFFF87FF37FFFFFF00FFF4 +:1010000092FF37FFFFFF01FF7FFF38FFFFFF00FF69 +:1010100023FF1CFFFFFFFFFF7EFF38FFFFFF00FFE6 +:1010200083FF87FFFFFFF1FF86FF8BFFFFFF41FF7D +:101030006CFF1CFFFFFF2FFF00FF0AFFFFFF0FFFEA +:101040008DFF8FFFFFFFC5FF20FF14FFFFFFAEFFE7 +:1010500000FF00FFFFFF00FF00FF0AFFFFFF0FFF81 +:101060008BFF83FFFFFF84FF00FF23FFFFFF0FFFC6 +:101070008BFF93FFFFFF8AFF64FF1CFFFFFFE0FF72 +:101080007EFF38FFFFFF00FF00FF38FFFFFF08FF74 +:1010900000FF3CFFFFFFE5FF21FF14FFFFFF5EFFA6 +:1010A00000FF40FFFFFF00FF00FF58FFFFFF03FFAF +:1010B00000FF0AFFFFFF0FFF08FF40FFFFFF10FFC9 +:1010C00047FF90FFFFFF20FF00FF04FFFFFF1CFF13 +:1010D00000FF04FFFFFF1CFF00FF04FFFFFF1CFFDA +:1010E00000FF04FFFFFF1CFF00FF04FFFFFF10FFD6 +:1010F00000FF04FFFFFF10FF00FF04FFFFFF10FFD2 +:1011000000FF04FFFFFF10FF00FF04FFFFFF10FFC1 +:1011100000FF04FFFFFF10FF00FF04FFFFFF10FFB1 +:1011200000FF04FFFFFF10FF00FF04FFFFFF10FFA1 +:1011300000FF04FFFFFF10FF00FF04FFFFFF10FF91 +:1011400000FF04FFFFFF10FF02FF40FFFFFF40FF13 +:1011500011FF90FFFFFF20FF78FF42FFFFFF50FFCE +:1011600048FF90FFFFFFA0FF00FF00FFFFFF00FF11 +:1011700000FF00FFFFFF00FF00FF00FFFFFF00FF79 +:1011800000FF00FFFFFF00FF00FF00FFFFFF00FF69 +:10119000B0FF40FFFFFF00FF47FF90FFFFFF50FF42 +:1011A00000FF40FFFFFF00FF8DFF93FFFFFF40FFA9 +:1011B0008DFF93FFFFFF50FF00FF40FFFFFF01FF88 +:1011C0008BFF93FFFFFF51FF00FF40FFFFFF00FF7A +:1011D00046FF90FFFFFF70FF8DFF83FFFFFFD0FFF3 +:1011E00078FF22FFFFFF0FFF0CFF18FFFFFF90FFAC +:1011F0000CFF18FFFFFF6FFF20FF0CFFFFFF00FF3A +:1012000000FF34FFFFFF09FF00FF34FFFFFF08FF6F +:1012100000FF38FFFFFF08FF00FF38FFFFFF09FF57 +:1012200000FF38FFFFFF06FF00FF34FFFFFF26FF30 +:1012300098FFCCFFFFFF37FF00FF3CFFFFFFA5FF3C +:1012400024FF14FFFFFFFEFF00FF60FFFFFF73FF9F +:1012500008FF0DFFFFFF14FF98FF20FFFFFF0FFFA8 +:1012600000FF50FFFFFFC6FF69FFCCFFFFFF37FF06 +:1012700000FF05FFFFFF00FF00FF58FFFFFFC6FF55 +:1012800098FF20FFFFFF0FFF00FF60FFFFFF72FFCF +:1012900008FF0DFFFFFF14FF00FF50FFFFFFC6FF19 +:1012A00069FFCCFFFFFF37FF00FF05FFFFFF00FFD7 +:1012B00000FF58FFFFFFC6FF98FF20FFFFFF0FFF53 +:1012C00000FF60FFFFFF73FF08FF0DFFFFFF14FF2C +:1012D00000FF50FFFFFFC6FF69FF20FFFFFF0FFF6A +:1012E00000FF05FFFFFF00FF00FF58FFFFFFC6FFE5 +:1012F00030FF0CFFFFFF00FF00FF0AFFFFFF0FFFA3 +:1013000000FF0CFFFFFF30FF47FF80FFFFFF58FF8C +:1013100010FF0FFFFFFF01FF66FF23FFFFFF0FFF1F +:1013200026FF18FFFFFF94FF00FF48FFFFFF00FFAD +:101330008BFF93FFFFFF40FF80FF40FFFFFF00FF99 +:1013400049FF90FFFFFF40FF16FF0FFFFFFF02FF67 +:1013500066FF23FFFFFF0FFF38FF18FFFFFFB4FFFB +:101360000FFF40FFFFFFF4FF47FF80FFFFFF0AFF73 +:1013700082FF23FFFFFF0FFF8DFF93FFFFFF7AFF29 +:101380007AFF26FFFFFF0FFF10FF27FFFFFF0FFF72 +:1013900038FF18FFFFFFB4FF27FF18FFFFFFD2FF42 +:1013A00000FF48FFFFFF00FF8BFF93FFFFFF30FFB1 +:1013B0008DFF83FFFFFF70FF47FF90FFFFFF00FFE0 +:1013C00000FF48FFFFFF04FFA0FF23FFFFFF0FFF09 +:1013D00046FF90FFFFFF6AFF00FF0CFFFFFF20FFAB +:1013E00000FF0AFFFFFF1FFF10FF27FFFFFF0FFF98 +:1013F00029FF18FFFFFF92FF46FF80FFFFFF00FF5E +:101400008BFF93FFFFFF20FF8DFF83FFFFFF70FF28 +:1014100047FF90FFFFFF00FF00FF48FFFFFF04FFB3 +:10142000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFB4 +:1014300000FF0CFFFFFF20FF00FF04FFFFFF1CFF6A +:1014400000FF04FFFFFF1CFF00FF04FFFFFF1CFF66 +:1014500000FF04FFFFFF1CFF00FF04FFFFFF10FF62 +:1014600000FF04FFFFFF10FF00FF04FFFFFF10FF5E +:1014700000FF04FFFFFF10FF00FF04FFFFFF10FF4E +:1014800000FF04FFFFFF10FF00FF04FFFFFF10FF3E +:1014900000FF04FFFFFF10FF00FF04FFFFFF10FF2E +:1014A00000FF04FFFFFF10FF00FF04FFFFFF10FF1E +:1014B00000FF04FFFFFF10FF00FF04FFFFFF03FF1B +:1014C0000DFF18FFFFFF0FFF10FF27FFFFFF0FFFAC +:1014D00031FF18FFFFFF12FF30FF0CFFFFFF00FF7F +:1014E00008FF0CFFFFFF00FFFFFF4FFFFFFF89FF1B +:1014F00090FF37FFFFFF00FF02FF34FFFFFF08FFF1 +:1015000000FF34FFFFFF34FF00FF34FFFFFF55FFF4 +:1015100046FF80FFFFFF08FF00FF0EFFFFFF0FFFEA +:1015200000FF0DFFFFFF4EFFA7FF23FFFFFF0FFF91 +:1015300000FF68FFFFFFA3FF00FF0DFFFFFF4AFF53 +:1015400046FF80FFFFFF18FF00FF0EFFFFFF0FFFAA +:1015500000FF0DFFFFFF5EFFAFFF23FFFFFF0FFF49 +:1015600000FF68FFFFFFA0FF00FF0DFFFFFF5AFF16 +:1015700046FF80FFFFFF48FF10FF0FFFFFFFFEFF4A +:1015800087FF93FFFFFFFEFF00FF0DFFFFFF2EFF12 +:1015900002FF40FFFFFF06FFE0FF20FFFFFF0FFFFE +:1015A00000FF40FFFFFF01FF63FF22FFFFFF0FFF70 +:1015B00000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF88 +:1015C00000FF0DFFFFFF5AFF00FF68FFFFFFA0FFB6 +:1015D00000FF0DFFFFFF5AFF63FF22FFFFFF0FFF1A +:1015E00000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF58 +:1015F00000FF0DFFFFFF5AFF00FF68FFFFFFA0FF86 +:1016000063FF22FFFFFF0FFF00FF0DFFFFFF4AFFF9 +:1016100049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF17 +:1016200000FF68FFFFFFA0FF63FF22FFFFFF0FFF28 +:1016300000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF07 +:1016400000FF0DFFFFFF5AFF00FF68FFFFFFA0FF35 +:1016500063FF22FFFFFF0FFF00FF0DFFFFFF4AFFA9 +:1016600049FF6AFFFFFFA3FF00FF0DFFFFFF5AFFC7 +:1016700000FF68FFFFFFA0FF63FF22FFFFFF0FFFD8 +:1016800000FF0DFFFFFF4AFF49FF6AFFFFFFA3FFB7 +:1016900000FF0DFFFFFF5AFF00FF68FFFFFFA0FFE5 +:1016A00063FF22FFFFFF0FFF00FF0DFFFFFF4AFF59 +:1016B00049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF77 +:1016C00000FF68FFFFFFA1FF46FF80FFFFFF28FF2D +:1016D00000FF0EFFFFFF0FFF00FF0DFFFFFF4EFF9C +:1016E000A7FF23FFFFFF0FFF00FF68FFFFFFA3FF20 +:1016F00000FF0DFFFFFF4AFF46FF80FFFFFF38FF9F +:1017000000FF0EFFFFFF0FFF00FF0DFFFFFF5EFF5B +:10171000AFFF23FFFFFF0FFF00FF68FFFFFFA0FFEA +:1017200000FF0DFFFFFF5AFF63FF22FFFFFF0FFFC8 +:1017300000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF06 +:1017400000FF0DFFFFFF5AFF00FF68FFFFFFA0FF34 +:1017500063FF22FFFFFF0FFF00FF0DFFFFFF4AFFA8 +:1017600049FF6AFFFFFFA3FF00FF0DFFFFFF5AFFC6 +:1017700000FF68FFFFFFA0FF63FF22FFFFFF0FFFD7 +:1017800000FF0DFFFFFF4AFF49FF6AFFFFFFA3FFB6 +:1017900000FF0DFFFFFF5AFF00FF68FFFFFFA0FFE4 +:1017A00063FF22FFFFFF0FFF00FF0DFFFFFF4AFF58 +:1017B00049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF76 +:1017C00000FF68FFFFFFA0FF63FF22FFFFFF0FFF87 +:1017D00000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF66 +:1017E00000FF0DFFFFFF5AFF00FF68FFFFFFA0FF94 +:1017F00063FF22FFFFFF0FFF00FF0DFFFFFF4AFF08 +:1018000049FF6AFFFFFFA3FF00FF0DFFFFFF5AFF25 +:1018100000FF68FFFFFFA0FF63FF22FFFFFF0FFF36 +:1018200000FF0DFFFFFF4AFF49FF6AFFFFFFA3FF15 +:1018300000FF0DFFFFFF5AFF00FF68FFFFFFA3FF40 +:10184000FFFF4FFFFFFFF0FF86FF93FFFFFF50FFFB +:101850008DFF83FFFFFF70FF47FF90FFFFFF00FF3B +:1018600000FF48FFFFFF04FFA0FF23FFFFFF0FFF64 +:1018700046FF90FFFFFF6AFF00FF0CFFFFFF20FF06 +:1018800000FF0AFFFFFF1FFF10FF27FFFFFF0FFFF3 +:1018900032FF18FFFFFF42FF8BFF83FFFFFFE4FFD4 +:1018A0008BFF83FFFFFFF5FF46FF90FFFFFF44FF25 +:1018B00008FF22FFFFFF0FFFFFFF4FFFFFFF89FF22 +:1018C00000FF0DFFFFFF8AFF00FF0EFFFFFF0FFF6E +:1018D00000FF0DFFFFFF4EFFA7FF23FFFFFF0FFFDE +:1018E00046FF90FFFFFF5AFF8DFF83FFFFFF70FF52 +:1018F00047FF90FFFFFF00FF00FF48FFFFFF04FFCF +:10190000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFCF +:1019100000FF0CFFFFFF20FF00FF0AFFFFFF1FFF7C +:1019200010FF27FFFFFF0FFF35FF18FFFFFFD2FF5C +:1019300000FF4CFFFFFF00FF00FF93FFFFFF00FFD2 +:101940000BFF40FFFFFF80FF11FF90FFFFFFF0FF45 +:1019500000FF40FFFFFF10FF11FF90FFFFFFE0FFC0 +:1019600046FF80FFFFFF0AFF7AFF26FFFFFF0FFF02 +:1019700035FF1CFFFFFF24FF10FF27FFFFFF0FFFB6 +:1019800033FF18FFFFFFC5FF00FF40FFFFFFC0FF51 +:1019900011FF90FFFFFF60FF8DFF93FFFFFFD0FF60 +:1019A00000FF48FFFFFF00FF8DFF83FFFFFF70FF79 +:1019B00047FF90FFFFFF00FF00FF48FFFFFF04FF0E +:1019C000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF0F +:1019D00000FF0CFFFFFF20FF00FF0AFFFFFF1FFFBC +:1019E00010FF27FFFFFF0FFF34FF18FFFFFF85FFEA +:1019F00000FF40FFFFFF40FF11FF90FFFFFF60FF70 +:101A00008DFF93FFFFFFD0FF8DFF83FFFFFF70FF70 +:101A100047FF90FFFFFF00FF00FF48FFFFFF04FFAD +:101A2000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFAE +:101A300000FF0CFFFFFF20FF00FF0AFFFFFF1FFF5B +:101A400000FF40FFFFFF00FF11FF90FFFFFF60FF5F +:101A50008DFF93FFFFFFD0FF8DFF83FFFFFF70FF20 +:101A600047FF90FFFFFF00FF00FF48FFFFFF04FF5D +:101A7000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF5E +:101A800000FF0CFFFFFF20FF00FF0AFFFFFF1FFF0B +:101A900000FF48FFFFFF00FF8DFF93FFFFFF80FF68 +:101AA00000FF48FFFFFF00FF00FF93FFFFFF00FF65 +:101AB0000DFF40FFFFFFF0FF11FF90FFFFFFF0FF62 +:101AC00000FF40FFFFFF10FF11FF90FFFFFFE0FF4F +:101AD000FFFF40FFFFFFF0FF90FF27FFFFFF0FFF1B +:101AE00000FF0AFFFFFF0FFF10FF27FFFFFF0FFFA1 +:101AF00037FF18FFFFFF42FF46FF80FFFFFF00FF99 +:101B000089FF93FFFFFFA0FF46FF80FFFFFF10FF4D +:101B100089FF93FFFFFFB0FF46FF80FFFFFF20FF1D +:101B200089FF93FFFFFFC0FF46FF80FFFFFF30FFED +:101B300089FF93FFFFFFD0FF46FF80FFFFFF40FFBD +:101B400089FF93FFFFFFE0FF46FF80FFFFFF50FF8D +:101B500089FF93FFFFFFF0FF00FF40FFFFFF10FF33 +:101B600086FF93FFFFFF60FF8DFF83FFFFFF70FF86 +:101B700047FF90FFFFFF00FF00FF48FFFFFF04FF4C +:101B8000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF4D +:101B900000FF0CFFFFFF20FF00FF0AFFFFFF1FFFFA +:101BA00010FF27FFFFFF0FFF39FF18FFFFFF22FF86 +:101BB00046FF80FFFFFF00FF8DFF93FFFFFF20FF29 +:101BC00046FF80FFFFFF10FF8DFF93FFFFFF30FFF9 +:101BD00046FF80FFFFFF20FF78FF22FFFFFF0FFF80 +:101BE00038FF1CFFFFFF84FF00FF40FFFFFF00FFE7 +:101BF00046FF90FFFFFF20FF00FF48FFFFFF00FFB1 +:101C00008DFF93FFFFFF40FF8DFF83FFFFFF70FFFE +:101C100047FF90FFFFFF00FF00FF48FFFFFF04FFAB +:101C2000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFAC +:101C300000FF0CFFFFFF20FF00FF0AFFFFFF1FFF59 +:101C400000FF48FFFFFF00FF8DFF93FFFFFF50FFE6 +:101C500000FF0AFFFFFF0FFF00FF0CFFFFFF20FF49 +:101C600000FF0AFFFFFF1FFF00FF0CFFFFFF30FF19 +:101C700000FF48FFFFFF00FF8BFF93FFFFFF50FFB8 +:101C800000FF0CFFFFFF20FF00FF0AFFFFFF1FFF09 +:101C90008DFF83FFFFFF70FF0FFF40FFFFFFF4FF8B +:101CA000E0FF22FFFFFF0FFF41FF18FFFFFF30FFA4 +:101CB0008DFF83FFFFFF70FF0FFF40FFFFFFE4FF7B +:101CC000E0FF22FFFFFF0FFF42FF18FFFFFF40FF73 +:101CD0008DFF83FFFFFF70FF0FFF40FFFFFFD4FF6B +:101CE000E0FF22FFFFFF0FFF47FF18FFFFFFA0FFEE +:101CF0008DFF83FFFFFF70FF0FFF40FFFFFFC4FF5B +:101D0000E0FF22FFFFFF0FFF46FF18FFFFFFD0FF9E +:101D10008DFF83FFFFFF70FF0FFF40FFFFFFB4FF4A +:101D2000E0FF22FFFFFF0FFF48FF18FFFFFFE0FF6C +:101D30008DFF83FFFFFF70FF0FFF40FFFFFFA4FF3A +:101D4000E0FF22FFFFFF0FFF4AFF18FFFFFF60FFCA +:101D50008DFF83FFFFFF70FF0FFF40FFFFFF94FF2A +:101D6000E0FF22FFFFFF0FFF4CFF18FFFFFF00FF08 +:101D70008DFF83FFFFFF70FF0FFF40FFFFFF84FF1A +:101D8000E0FF22FFFFFF0FFF4DFF18FFFFFFE0FF07 +:101D90008DFF83FFFFFF70FF0FFF40FFFFFF74FF0A +:101DA000E0FF22FFFFFF0FFF4FFF18FFFFFF20FFA5 +:101DB0008DFF83FFFFFF70FF0FFF40FFFFFF64FFFA +:101DC000E0FF22FFFFFF0FFF4FFF18FFFFFFF0FFB5 +:101DD0008DFF83FFFFFF70FF0EFF40FFFFFFF4FF4B +:101DE000E0FF22FFFFFF0FFF44FF18FFFFFF40FF50 +:101DF0008DFF83FFFFFF70FF0EFF40FFFFFFE4FF3B +:101E0000E0FF22FFFFFF0FFF45FF18FFFFFF50FF1E +:101E10008DFF83FFFFFF70FF0AFF40FFFFFF04FFFE +:101E2000E0FF22FFFFFF0FFF3DFF18FFFFFFD0FF86 +:101E30008DFF83FFFFFF70FF0AFF40FFFFFF14FFCE +:101E4000E0FF22FFFFFF0FFF3FFF18FFFFFF10FF24 +:101E50008DFF83FFFFFF70FF0AFF40FFFFFF24FF9E +:101E6000E0FF22FFFFFF0FFF3FFF18FFFFFF80FF94 +:101E70008DFF83FFFFFF70FF0AFF40FFFFFF34FF6E +:101E8000E0FF22FFFFFF0FFF3FFF18FFFFFFF0FF04 +:101E90008DFF83FFFFFF70FF0AFF40FFFFFF44FF3E +:101EA000E0FF22FFFFFF0FFF40FF18FFFFFF60FF73 +:101EB0008DFF83FFFFFF70FF47FF90FFFFFF00FFD5 +:101EC00000FF48FFFFFF04FFA0FF23FFFFFF0FFFFE +:101ED00046FF90FFFFFF6AFF00FF0CFFFFFF20FFA0 +:101EE00000FF0AFFFFFF1FFF8DFF83FFFFFF70FF53 +:101EF00047FF90FFFFFF00FF00FF48FFFFFF04FFC9 +:101F0000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFC9 +:101F100000FF0CFFFFFF08FF00FF40FFFFFF00FF77 +:101F2000FFFF93FFFFFFF0FF00FF40FFFFFF00FFF9 +:101F300044FF90FFFFFF60FF00FF00FFFFFF00FF77 +:101F400000FF00FFFFFF00FF00FF00FFFFFF00FF9B +:101F500000FF00FFFFFF00FF00FF00FFFFFF00FF8B +:101F600000FF00FFFFFF00FF00FF00FFFFFF00FF7B +:101F700000FF00FFFFFF00FF21FF40FFFFFF80FF8A +:101F8000FFFF93FFFFFFF0FF8DFF83FFFFFF70FF59 +:101F900047FF90FFFFFF00FF00FF48FFFFFF04FF28 +:101FA000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF29 +:101FB00025FF40FFFFFF80FFFFFF93FFFFFFF0FFC4 +:101FC0008DFF83FFFFFF70FF47FF90FFFFFF00FFC4 +:101FD00000FF48FFFFFF04FFA0FF23FFFFFF0FFFED +:101FE00046FF90FFFFFF6AFFE9FF41FFFFFF80FF11 +:101FF000FFFF93FFFFFFF0FF8DFF83FFFFFF70FFE9 +:1020000047FF90FFFFFF00FF00FF48FFFFFF04FFB7 +:10201000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFB8 +:10202000EDFF41FFFFFF80FFFFFF93FFFFFFF0FF8A +:102030008DFF83FFFFFF70FF47FF90FFFFFF00FF53 +:1020400000FF48FFFFFF04FFA0FF23FFFFFF0FFF7C +:1020500046FF90FFFFFF6AFF00FF40FFFFFF00FF0A +:1020600044FF90FFFFFF60FF00FF00FFFFFF00FF46 +:1020700000FF00FFFFFF00FF00FF00FFFFFF00FF6A +:1020800000FF00FFFFFF00FFF1FF41FFFFFF80FFA8 +:10209000FFFF93FFFFFFF0FF46FF84FFFFFF00FFFE +:1020A00000FF34FFFFFF08FF00FF60FFFFFF03FF9B +:1020B00000FF00FFFFFF00FF00FF00FFFFFF00FF2A +:1020C00000FF00FFFFFF00FF00FF00FFFFFF00FF1A +:1020D00046FF90FFFFFF60FFF7FF4FFFFFFFF4FF9A +:1020E00046FF90FFFFFF74FF8DFF83FFFFFF70FF30 +:1020F00047FF90FFFFFF00FF00FF48FFFFFF04FFC7 +:10210000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFC7 +:1021100000FF0CFFFFFF20FF00FF0AFFFFFF1FFF74 +:1021200046FF84FFFFFF00FF00FF34FFFFFF08FFB3 +:1021300000FF34FFFFFF06FF00FF00FFFFFF00FF6F +:1021400000FF00FFFFFF00FF00FF00FFFFFF00FF99 +:1021500000FF00FFFFFF00FF46FF80FFFFFF10FFB3 +:1021600000FF00FFFFFF00FF00FF00FFFFFF00FF79 +:1021700000FF00FFFFFF00FF00FF00FFFFFF00FF69 +:1021800000FF68FFFFFF02FF00FF00FFFFFF00FFEF +:1021900000FF00FFFFFF00FF00FF00FFFFFF00FF49 +:1021A00000FF00FFFFFF00FF00FF60FFFFFF22FFB7 +:1021B00000FF00FFFFFF00FF00FF00FFFFFF00FF29 +:1021C00000FF00FFFFFF00FF00FF00FFFFFF00FF19 +:1021D00046FF90FFFFFF62FFF7FF4FFFFFFFF4FF97 +:1021E00046FF90FFFFFF74FF8DFF83FFFFFF70FF2F +:1021F00047FF90FFFFFF00FF00FF48FFFFFF04FFC6 +:10220000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFC6 +:1022100000FF0CFFFFFF20FF00FF0AFFFFFF1FFF73 +:1022200046FF88FFFFFF00FF00FF38FFFFFF08FFAA +:1022300000FF50FFFFFF03FF00FF00FFFFFF00FF55 +:1022400000FF00FFFFFF00FF00FF00FFFFFF00FF98 +:1022500000FF00FFFFFF00FF46FF90FFFFFF60FF52 +:10226000F7FF4FFFFFFFF4FF46FF90FFFFFF74FFF4 +:102270008DFF83FFFFFF70FF47FF90FFFFFF00FF11 +:1022800000FF48FFFFFF04FFA0FF23FFFFFF0FFF3A +:1022900046FF90FFFFFF6AFF00FF0CFFFFFF20FFDC +:1022A00000FF0AFFFFFF1FFF46FF88FFFFFF00FF41 +:1022B00000FF38FFFFFF08FF00FF38FFFFFF04FFAC +:1022C00000FF00FFFFFF00FF00FF00FFFFFF00FF18 +:1022D00000FF00FFFFFF00FF00FF00FFFFFF00FF08 +:1022E00046FF80FFFFFF10FF00FF58FFFFFF03FFC7 +:1022F00000FF50FFFFFF23FF00FF00FFFFFF00FF75 +:1023000000FF00FFFFFF00FF00FF00FFFFFF00FFD7 +:1023100000FF00FFFFFF00FF46FF90FFFFFF62FF8F +:10232000F7FF4FFFFFFFF4FF46FF90FFFFFF74FF33 +:102330008DFF83FFFFFF70FF47FF90FFFFFF00FF50 +:1023400000FF48FFFFFF04FFA0FF23FFFFFF0FFF79 +:1023500046FF90FFFFFF6AFF00FF0CFFFFFF20FF1B +:1023600000FF0AFFFFFF1FFF46FF80FFFFFF00FF88 +:10237000FFFF93FFFFFFE0FFFFFF83FFFFFFE2FF91 +:1023800046FF90FFFFFF62FFF7FF4FFFFFFFF4FFE5 +:1023900046FF90FFFFFF74FF8DFF83FFFFFF70FF7D +:1023A00047FF90FFFFFF00FF00FF48FFFFFF04FF14 +:1023B000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF15 +:1023C00000FF0CFFFFFF20FF00FF0AFFFFFF1FFFC2 +:1023D00003FF0DFFFFFF0FFF00FF00FFFFFF00FFE8 +:1023E00000FF00FFFFFF00FF00FF00FFFFFF00FFF7 +:1023F00000FF00FFFFFF00FF46FF90FFFFFF60FFB1 +:102400000CFF0DFFFFFFF0FF00FF00FFFFFF00FFCD +:1024100000FF00FFFFFF00FF00FF00FFFFFF00FFC6 +:1024200000FF00FFFFFF00FFF7FF4FFFFFFFF4FF7C +:1024300046FF90FFFFFF74FF8DFF83FFFFFF70FFDC +:1024400047FF90FFFFFF00FF00FF48FFFFFF04FF73 +:10245000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF74 +:1024600000FF0CFFFFFF20FF00FF0AFFFFFF1FFF21 +:1024700046FF80FFFFFF02FF00FF00FFFFFF00FF9E +:1024800000FF00FFFFFF00FF00FF00FFFFFF00FF56 +:1024900000FF00FFFFFF00FF00FF00FFFFFF00FF46 +:1024A00000FF00FFFFFF00FF00FF00FFFFFF00FF36 +:1024B00000FF00FFFFFF00FF46FF80FFFFFF13FF4D +:1024C00000FF40FFFFFF00FF11FF90FFFFFF60FFD5 +:1024D0008DFF93FFFFFFD0FF11FF90FFFFFFF2FF83 +:1024E00011FF90FFFFFFE3FFF7FF4FFFFFFFF4FF38 +:1024F00046FF90FFFFFF74FF8DFF83FFFFFF70FF1C +:1025000047FF90FFFFFF00FF00FF48FFFFFF04FFB2 +:10251000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFB3 +:1025200000FF0CFFFFFF20FF00FF0AFFFFFF1FFF60 +:1025300046FF84FFFFFF00FF00FF34FFFFFF08FF9F +:1025400000FF34FFFFFF06FF00FF00FFFFFF00FF5B +:1025500000FF00FFFFFF00FF00FF00FFFFFF00FF85 +:1025600000FF00FFFFFF00FF46FF80FFFFFF10FF9F +:10257000FFFF93FFFFFFE0FF00FF60FFFFFF22FF71 +:1025800067FF40FFFFFF40FFFFFF93FFFFFFE0FFFC +:1025900000FF00FFFFFF00FF00FF00FFFFFF00FF45 +:1025A00000FF00FFFFFF00FF00FF00FFFFFF00FF35 +:1025B00046FF90FFFFFF62FFF7FF4FFFFFFFF4FFB3 +:1025C00046FF90FFFFFF74FF8DFF83FFFFFF70FF4B +:1025D00047FF90FFFFFF00FF00FF48FFFFFF04FFE2 +:1025E000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFE3 +:1025F00000FF0CFFFFFF20FF00FF0AFFFFFF1FFF90 +:1026000046FF84FFFFFF00FF00FF34FFFFFF08FFCE +:1026100000FF34FFFFFF06FF00FF00FFFFFF00FF8A +:1026200000FF00FFFFFF00FF46FF80FFFFFF10FFDE +:1026300000FF00FFFFFF00FF00FF00FFFFFF00FFA4 +:1026400000FF00FFFFFF00FF00FF00FFFFFF00FF94 +:1026500046FF80FFFFFF23FFFFFF93FFFFFFE0FF29 +:1026600000FF68FFFFFF32FF00FF60FFFFFF72FF08 +:1026700067FF40FFFFFF40FFFFFF93FFFFFFE0FF0B +:1026800000FF00FFFFFF00FF00FF00FFFFFF00FF54 +:1026900000FF00FFFFFF00FF00FF00FFFFFF00FF44 +:1026A00046FF90FFFFFF67FFF7FF4FFFFFFFF4FFBD +:1026B00046FF90FFFFFF74FF8DFF83FFFFFF70FF5A +:1026C00047FF90FFFFFF00FF00FF48FFFFFF04FFF1 +:1026D000A0FF23FFFFFF0FFF46FF90FFFFFF6AFFF2 +:1026E00000FF0CFFFFFF20FF00FF0AFFFFFF1FFF9F +:1026F00046FF80FFFFFF05FF03FF0DFFFFFF0FFFFA +:1027000000FF00FFFFFF00FF00FF00FFFFFF00FFD3 +:1027100000FF00FFFFFF00FF00FF00FFFFFF00FFC3 +:102720000CFF0DFFFFFFF5FF00FF00FFFFFF00FFA5 +:1027300000FF00FFFFFF00FF00FF00FFFFFF00FFA3 +:1027400000FF00FFFFFF00FFF7FF4FFFFFFFF4FF59 +:1027500046FF90FFFFFF74FF8DFF83FFFFFF70FFB9 +:1027600047FF90FFFFFF00FF00FF48FFFFFF04FF50 +:10277000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF51 +:1027800000FF0CFFFFFF20FF00FF0AFFFFFF1FFFFE +:1027900046FF80FFFFFF00FF8DFF93FFFFFFC0FF9D +:1027A0008DFF83FFFFFFC7FF46FF90FFFFFF67FF1F +:1027B000F7FF4FFFFFFFF4FF46FF90FFFFFF74FF9F +:1027C0008DFF83FFFFFF70FF47FF90FFFFFF00FFBC +:1027D00000FF48FFFFFF04FFA0FF23FFFFFF0FFFE5 +:1027E00046FF90FFFFFF6AFF00FF0CFFFFFF20FF87 +:1027F00000FF0AFFFFFF1FFF46FF80FFFFFF00FFF4 +:102800008DFF93FFFFFFE0FF8DFF83FFFFFFE7FFDB +:1028100000FF00FFFFFF00FF00FF00FFFFFF00FFC2 +:1028200000FF00FFFFFF00FF00FF00FFFFFF00FFB2 +:1028300046FF90FFFFFF67FFF7FF4FFFFFFFF4FF2B +:1028400046FF90FFFFFF74FF8DFF83FFFFFF70FFC8 +:1028500047FF90FFFFFF00FF00FF48FFFFFF04FF5F +:10286000A0FF23FFFFFF0FFF46FF90FFFFFF6AFF60 +:1028700000FF0CFFFFFF20FF00FF0AFFFFFF1FFF0D +:102880008DFF83FFFFFFD0FF00FF40FFFFFF24FF0E +:10289000A0FF23FFFFFF0FFF11FF90FFFFFF6AFF65 +:1028A00000FF40FFFFFF14FF18FF23FFFFFF0FFF94 +:1028B00051FF14FFFFFF81FF90FF80FFFFFF60FFCC +:1028C00080FF23FFFFFF0FFF8DFF83FFFFFFD0FF80 +:1028D00000FF40FFFFFF14FFA0FF23FFFFFF0FFFDC +:1028E00011FF90FFFFFF6AFF30FF0CFFFFFF00FFAB +:1028F00000FF40FFFFFF16FF10FF40FFFFFF07FF35 +:1029000090FF34FFFFFF71FF00FF34FFFFFF09FF5F +:102910000FFF40FFFFFFF5FF00FF60FFFFFF07FF16 +:1029200088FF63FFFFFF27FFE8FF60FFFFFF07FF50 +:1029300062FF61FFFFFF27FF88FF2BFFFFFF8BFF79 +:10294000E8FF60FFFFFF07FF62FF61FFFFFF17FF68 +:1029500088FF2FFFFFFFFBFF89FF23FFFFFF0FFF14 +:1029600098FF20FFFFFF0FFFEAFF20FFFFFF0FFF91 +:1029700000FF0DFFFFFFABFF00FF0DFFFFFFB8FFE4 +:1029800000FF0DFFFFFFCFFF62FF21FFFFFF0FFFE3 +:1029900010FF22FFFFFF0FFF62FF21FFFFFF0FFF6E +:1029A00000FF40FFFFFF24FF90FF80FFFFFF60FF5D +:1029B00080FF23FFFFFF0FFF51FF18FFFFFF00FF06 +:1029C0008BFF93FFFFFFEBFF8BFF93FFFFFFFCFFEE +:1029D00000FF0AFFFFFF0FFF51FF1CFFFFFF0FFF6C +:1029E0008DFF93FFFFFFACFF82FF3CFFFFFF45FF22 +:1029F00054FF14FFFFFF2EFFFFFF3FFFFFFFF5FF18 +:102A000054FF14FFFFFF1EFF00FF00FFFFFF00FF4A +:102A100000FF00FFFFFF00FF51FF1CFFFFFF0FFF44 +:102A200000FF0DFFFFFF0CFF8DFF83FFFFFFA4FFE3 +:102A3000E0FF22FFFFFF0FFF53FF18FFFFFFB3FF71 +:102A40008DFF83FFFFFFD0FF00FF40FFFFFF24FF4C +:102A5000A0FF23FFFFFF0FFF00FF0DFFFFFFBAFFE7 +:102A60008BFF83FFFFFFF5FF11FF90FFFFFF6BFF61 +:102A700000FF40FFFFFF14FF18FF23FFFFFF0FFFC2 +:102A800055FF14FFFFFF21FF90FF80FFFFFF60FF56 +:102A900080FF23FFFFFF0FFF00FF40FFFFFF20FF2E +:102AA00000FF40FFFFFF01FF8BFF83FFFFFFE4FFFD +:102AB0008BFF83FFFFFFF5FF08FF0CFFFFFF00FF09 +:102AC00060FF22FFFFFF0FFF49FF2AFFFFFFEAFF22 +:102AD00000FF0DFFFFFF4EFF8BFF93FFFFFFEEFF99 +:102AE00000FF0DFFFFFF5AFF8BFF93FFFFFFFAFF71 +:102AF0008DFF83FFFFFF20FF8DFF83FFFFFF31FF6F +:102B0000E0FF22FFFFFF0FFFC9FF2AFFFFFFEAFFE1 +:102B100054FF18FFFFFFD5FF00FF0DFFFFFF4EFF23 +:102B200000FF0DFFFFFF5AFF82FF4FFFFFFFF0FF87 +:102B3000FFFF4FFFFFFFF1FFE0FF22FFFFFF0FFF4F +:102B4000C9FF2AFFFFFFEAFF56FF18FFFFFFB4FF90 +:102B500054FF18FFFFFFDFFF00FF40FFFFFF20FFD4 +:102B600047FF90FFFFFF20FF0CFF0CFFFFFF00FF60 +:102B700002FF40FFFFFF60FF11FF90FFFFFF20FFFC +:102B800016FF18FFFFFF4FFF8DFF83FFFFFFD0FFF2 +:102B900000FF40FFFFFF24FFA0FF23FFFFFF0FFF09 +:102BA00011FF90FFFFFF6AFF00FF40FFFFFF14FFD0 +:102BB00018FF23FFFFFF0FFF57FF14FFFFFF91FFD9 +:102BC00090FF80FFFFFF60FF80FF23FFFFFF0FFFED +:102BD0008DFF83FFFFFFD0FF00FF40FFFFFF14FFCB +:102BE000A0FF23FFFFFF0FFF11FF90FFFFFF6AFF12 +:102BF00030FF0CFFFFFF00FF00FF40FFFFFF16FF4D +:102C000010FF40FFFFFF07FF90FF34FFFFFF71FF42 +:102C100000FF34FFFFFF09FF0FFF40FFFFFFF5FF3D +:102C200000FF60FFFFFF07FF88FF63FFFFFF27FF35 +:102C3000E8FF60FFFFFF07FF62FF61FFFFFF27FF65 +:102C400088FF2BFFFFFF8BFFE8FF60FFFFFF07FF01 +:102C500062FF61FFFFFF17FF88FF2FFFFFFFFBFFF2 +:102C600089FF23FFFFFF0FFF98FF20FFFFFF0FFFEC +:102C7000EAFF20FFFFFF0FFF00FF0DFFFFFFABFF8D +:102C800000FF0DFFFFFFB8FF00FF0DFFFFFFCFFFAD +:102C900062FF21FFFFFF0FFF10FF22FFFFFF0FFF6B +:102CA00062FF21FFFFFF0FFF00FF40FFFFFF24FF38 +:102CB00090FF80FFFFFF60FF80FF23FFFFFF0FFFFC +:102CC00057FF18FFFFFF10FF8BFF93FFFFFFEBFF86 +:102CD0008BFF93FFFFFFFCFF5CFF1CFFFFFF3FFF2D +:102CE00000FF0AFFFFFF0FFF57FF1CFFFFFF1FFF43 +:102CF0008DFF93FFFFFFACFF82FF3CFFFFFF45FF0F +:102D00005AFF14FFFFFF4EFFFFFF3FFFFFFFF5FFDE +:102D10005AFF14FFFFFF3EFF00FF00FFFFFF00FF11 +:102D200000FF00FFFFFF00FF57FF1CFFFFFF1FFF1B +:102D300000FF0DFFFFFF0CFF8DFF83FFFFFFA4FFD0 +:102D4000E0FF22FFFFFF0FFF59FF18FFFFFFD3FF38 +:102D50005CFF1CFFFFFF3FFF8DFF83FFFFFFD0FFE6 +:102D600000FF40FFFFFF24FFA0FF23FFFFFF0FFF37 +:102D700000FF0DFFFFFFBAFF8BFF83FFFFFFF5FF93 +:102D80005CFF1CFFFFFF3FFF11FF90FFFFFF6BFF8A +:102D900000FF40FFFFFF14FF18FF23FFFFFF0FFF9F +:102DA0005BFF14FFFFFF61FF90FF80FFFFFF60FFED +:102DB00080FF23FFFFFF0FFF00FF40FFFFFF20FF0B +:102DC00000FF40FFFFFF01FF8BFF83FFFFFFE4FFDA +:102DD0008BFF83FFFFFFF5FF08FF0CFFFFFF00FFE6 +:102DE00060FF22FFFFFF0FFF49FF2AFFFFFFEAFFFF +:102DF00000FF0DFFFFFF4EFF8BFF93FFFFFFEEFF76 +:102E00008BFF93FFFFFFFAFF5EFF1CFFFFFF0FFF2B +:102E10005BFF18FFFFFF0FFF8BFF83FFFFFF20FF0C +:102E200078FF22FFFFFF0FFF0DFF18FFFFFF05FFD9 +:102E300000FF0AFFFFFF0FFF08FF0CFFFFFF00FF6F +:102E400000FF40FFFFFF14FF00FF40FFFFFF05FFF3 +:102E50008BFF83FFFFFFE0FF8BFF83FFFFFFF1FF8F +:102E600060FF22FFFFFF0FFF49FF2AFFFFFFEAFF7E +:102E70008BFF93FFFFFFFAFF8BFF93FFFFFFEEFF38 +:102E80000CFF0CFFFFFF00FF00FF0AFFFFFF0FFF1B +:102E900008FF0CFFFFFF00FF00FF40FFFFFF14FFD4 +:102EA00000FF40FFFFFF05FF8BFF83FFFFFFE0FFF9 +:102EB0008BFF83FFFFFFF1FF60FF22FFFFFF0FFF8C +:102EC00049FF2AFFFFFFEAFF8BFF93FFFFFFFAFF97 +:102ED0008BFF93FFFFFFEEFF0CFF0CFFFFFF00FFD8 +:102EE0008DFF83FFFFFF40FF78FF22FFFFFF0FFFF3 +:102EF0005EFF1CFFFFFF04FF00FF0AFFFFFF0FFF45 +:102F000008FF0CFFFFFF00FF8DFF83FFFFFF50FF57 +:102F100078FF22FFFFFF0FFF5FFF1CFFFFFF54FF43 +:102F20000FFF40FFFFFFF5FF90FF80FFFFFFA8FFAF +:102F300010FF0FFFFFFF08FF90FF80FFFFFF90FFD4 +:102F400088FF27FFFFFF0FFFB6FF27FFFFFF0FFFE1 +:102F50008BFF83FFFFFFFAFFF2FF22FFFFFF0FFF50 +:102F600000FF0DFFFFFF0AFF00FF40FFFFFF14FF00 +:102F7000E2FF22FFFFFF0FFF74FF18FFFFFFE2FFDA +:102F800038FF23FFFFFF0FFF00FF40FFFFFF24FF7D +:102F9000E2FF22FFFFFF0FFF74FF18FFFFFFE2FFBA +:102FA00000FF0AFFFFFF0FFF0FFF40FFFFFFF5FFCE +:102FB00090FF80FFFFFF80FF8BFF83FFFFFFE2FF9B +:102FC00088FF27FFFFFF0FFF98FF20FFFFFF0FFF86 +:102FD00010FF40FFFFFF07FFE8FF20FFFFFF0FFF8D +:102FE00000FF0DFFFFFFACFFF2FF22FFFFFF0FFF0F +:102FF00000FF0DFFFFFF0AFF01FF40FFFFFF04FF7F +:10300000E2FF22FFFFFF0FFF74FF18FFFFFFE2FF49 +:1030100038FF23FFFFFF0FFF02FF40FFFFFF04FF0A +:10302000E2FF22FFFFFF0FFF74FF18FFFFFFE2FF29 +:1030300000FF0AFFFFFF0FFF00FF34FFFFFF08FF45 +:1030400000FF34FFFFFFD4FF00FF34FFFFFF85FFC9 +:10305000FFFF4FFFFFFF89FF00FF09FFFFFF01FF99 +:1030600089FF83FFFFFFB8FF00FF0EFFFFFF0FFF89 +:1030700000FF0DFFFFFF4EFFA7FF23FFFFFF0FFF26 +:1030800000FF68FFFFFFA3FF89FF83FFFFFFA8FF8B +:1030900000FF0EFFFFFF0FFF00FF0DFFFFFF4EFFC2 +:1030A000A7FF23FFFFFF0FFF00FF68FFFFFFA3FF46 +:1030B00000FF09FFFFFF03FF8BFF83FFFFFFB0FF50 +:1030C00000FF68FFFFFF00FF00FF0AFFFFFF0FFF89 +:1030D00002FF35FFFFFF00FF00FF34FFFFFF08FF87 +:1030E00000FF34FFFFFF26FF89FF83FFFFFFD8FFAC +:1030F00000FF0EFFFFFF0FFF00FF0DFFFFFF4EFF62 +:10310000A7FF23FFFFFF0FFF00FF68FFFFFFA3FFE5 +:1031100089FF83FFFFFFC8FF00FF0EFFFFFF0FFFC8 +:1031200000FF0DFFFFFF4EFFA7FF23FFFFFF0FFF75 +:1031300000FF68FFFFFFA3FF00FF09FFFFFF03FF82 +:103140008BFF83FFFFFFD0FF00FF68FFFFFF02FF41 +:1031500001FF40FFFFFF80FF00FF68FFFFFF02FF4E +:1031600000FF40FFFFFF20FF00FF68FFFFFF03FF9E +:1031700000FF0AFFFFFF0FFF00FF40FFFFFF10FFF0 +:103180008BFF93FFFFFF40FF30FF40FFFFFF00FF7B +:1031900049FF90FFFFFF40FF00FF0AFFFFFF0FFF07 +:1031A00000FF40FFFFFF60FF00FF91FFFFFFF0FF08 +:1031B00000FF0AFFFFFF0FFF01FF42FFFFFF80FF3D +:1031C00000FF91FFFFFF70FF07FF42FFFFFF80FF3F +:1031D00003FF91FFFFFF70FF02FF42FFFFFF00FFB1 +:1031E00000FF91FFFFFFF0FF08FF42FFFFFF00FF1E +:1031F00003FF91FFFFFFF0FF00FF40FFFFFF20FFF5 +:1032000001FF91FFFFFF70FF00FF40FFFFFF20FF66 +:1032100004FF91FFFFFF70FF00FF0AFFFFFF0FFF9A +:1032200004FF42FFFFFF00FF49FF90FFFFFF20FF69 +:1032300062FF1CFFFFFFFFFF00FF0AFFFFFF0FFF02 +:1032400000FF40FFFFFF20FF00FF91FFFFFFF0FFA7 +:1032500001FF42FFFFFF00FF49FF90FFFFFF20FF3C +:1032600062FF1CFFFFFFFFFF00FF0AFFFFFF0FFFD2 +:1032700000FF40FFFFFF40FF8BFF93FFFFFF80FF3A +:1032800005FF35FFFFFF00FF92FF3BFFFFFF00FF41 +:1032900000FF34FFFFFF08FF00FF38FFFFFF08FFBC +:1032A00000FF3CFFFFFF65FF65FF14FFFFFF9EFF70 +:1032B00000FF60FFFFFF03FF00FF60FFFFFF13FF42 +:1032C00000FF78FFFFFF13FF00FF78FFFFFF03FF02 +:1032D00001FF42FFFFFF00FF49FF90FFFFFF20FFBC +:1032E00062FF1CFFFFFFFFFF05FF81FFFFFFC0FF25 +:1032F00078FF22FFFFFF0FFF21FF18FFFFFF71FF85 +:1033000000FF0AFFFFFF0FFF49FF80FFFFFF48FF9D +:1033100010FF0FFFFFFF03FF66FF23FFFFFF0FFFFD +:1033200074FF18FFFFFF54FF86FF83FFFFFFC0FFFE +:1033300049FF90FFFFFF20FF62FF1CFFFFFFFFFF21 +:1033400086FF83FFFFFF80FF01FF40FFFFFF04FFB9 +:10335000E0FF22FFFFFF0FFF86FF93FFFFFF8AFFC3 +:1033600067FF1CFFFFFF00FF86FF87FFFFFFD0FF07 +:1033700075FF1CFFFFFF1FFF00FF0AFFFFFF0FFF8E +:1033800000FF48FFFFFF00FF82FF93FFFFFF40FFAA +:1033900000FF0AFFFFFF0FFF08FF0CFFFFFF00FF0A +:1033A00086FF8BFFFFFFB0FF00FF38FFFFFF08FF26 +:1033B00000FF38FFFFFFF4FFFFFF4FFFFFFF89FF14 +:1033C0008DFF83FFFFFF60FF89FF83FFFFFF44FF47 +:1033D00000FF40FFFFFF01FF89FF83FFFFFF55FF55 +:1033E00060FF26FFFFFF0FFF49FF22FFFFFF0FFFD8 +:1033F00000FF78FFFFFFA3FF10FF22FFFFFF0FFF7B +:1034000000FF78FFFFFFA0FF8DFF83FFFFFF60FF3E +:1034100089FF83FFFFFF24FF00FF40FFFFFF01FF45 +:1034200089FF83FFFFFF35FF60FF26FFFFFF0FFFD0 +:1034300049FF22FFFFFF0FFF00FF78FFFFFFA3FF01 +:1034400010FF22FFFFFF0FFF00FF78FFFFFFA3FF2A +:103450008DFF83FFFFFF60FF20FF40FFFFFF04FFA2 +:1034600060FF22FFFFFF0FFF8DFF93FFFFFF6AFF4B +:103470000CFF0CFFFFFF00FF00FF0AFFFFFF0FFF25 +:1034800008FF0CFFFFFF00FF86FF87FFFFFFB0FF75 +:1034900000FF34FFFFFF08FF01FF34FFFFFF04FFC1 +:1034A00000FF34FFFFFF35FFFFFF4FFFFFFF89FFE6 +:1034B00000FF09FFFFFF01FF87FF8BFFFFFFE0FF1A +:1034C00000FF38FFFFFF88FF00FF70FFFFFF03FFD3 +:1034D00000FF68FFFFFF00FF00FF70FFFFFF03FF1B +:1034E00000FF68FFFFFF03FF87FF9BFFFFFFE0FF79 +:1034F0000CFF0CFFFFFF00FF00FF0AFFFFFF0FFFA5 +:1035000001FF3CFFFFFF05FF6AFF14FFFFFF9EFF67 +:1035100067FF1CFFFFFF3FFF69FF1CFFFFFF0FFF5F +:1035200066FF1CFFFFFF1FFF38FF22FFFFFF0FFF9B +:103530006AFF14FFFFFF85FF8BFF83FFFFFF40FF44 +:1035400078FF22FFFFFF0FFF00FF00FFFFFF00FFDC +:1035500000FF0AFFFFFF0FFF82FF83FFFFFF40FF17 +:1035600078FF22FFFFFF0FFF6AFF1CFFFFFFF4FF42 +:1035700000FF0AFFFFFF0FFF00FF40FFFFFF10FFEC +:1035800047FF90FFFFFF20FF87FF83FFFFFFF0FF54 +:1035900086FF93FFFFFF80FF00FF40FFFFFF00FF5C +:1035A0008DFF93FFFFFF60FF82FF93FFFFFF40FF50 +:1035B00086FF87FFFFFF90FF02FF34FFFFFF08FF3A +:1035C00000FF60FFFFFF03FF89FF93FFFFFF20FF66 +:1035D00000FF60FFFFFF03FF89FF93FFFFFF30FF46 +:1035E00000FF60FFFFFF03FF89FF93FFFFFF40FF26 +:1035F00000FF60FFFFFF03FF89FF93FFFFFF50FF06 +:1036000086FF97FFFFFF90FF00FF0AFFFFFF0FFFFE +:1036100000FF34FFFFFF64FF00FF34FFFFFF35FFB3 +:1036200001FF34FFFFFF96FF00FF38FFFFFF34FF6D +:1036300000FF38FFFFFF65FF01FF38FFFFFF96FF28 +:1036400000FF38FFFFFF08FF02FF34FFFFFF49FFC5 +:1036500002FF38FFFFFF49FF10FF40FFFFFF06FF9B +:1036600010FF40FFFFFF02FF30FF0CFFFFFF00FFD6 +:1036700000FF3CFFFFFF25FF6DFF14FFFFFFBEFFB4 +:1036800098FF50FFFFFF73FF88FF50FFFFFF73FF9E +:1036900083FF68FFFFFFC5FF88FF68FFFFFFC4FFD0 +:1036A00083FF68FFFFFFC5FF00FF68FFFFFFC6FF46 +:1036B00098FF50FFFFFF73FF88FF50FFFFFF73FF6E +:1036C00083FF78FFFFFFC4FF88FF78FFFFFFC5FF80 +:1036D00083FF78FFFFFFC4FF00FF78FFFFFFC6FFF7 +:1036E00098FF50FFFFFF73FF88FF50FFFFFF73FF3E +:1036F00083FF68FFFFFFC5FF88FF68FFFFFFC4FF70 +:1037000083FF68FFFFFFC5FF00FF68FFFFFFC6FFE5 +:1037100000FF3CFFFFFF25FF6EFF14FFFFFF8EFF42 +:1037200098FF50FFFFFF73FF88FF50FFFFFF73FFFD +:1037300083FF78FFFFFFC4FF88FF78FFFFFFC4FF10 +:1037400000FF78FFFFFFC4FF20FF0CFFFFFF00FF1B +:1037500000FF0AFFFFFF0FFF00FF34FFFFFFE9FF3D +:1037600001FF38FFFFFF28FF01FF38FFFFFF29FFA0 +:1037700000FF38FFFFFF66FF00FF38FFFFFF34FF49 +:1037800000FF38FFFFFF75FF10FF40FFFFFF06FF40 +:1037900000FF41FFFFFF07FF30FF0CFFFFFF00FFAF +:1037A00098FF70FFFFFF20FF00FF3CFFFFFF25FF9A +:1037B00070FF14FFFFFF2EFF80FF70FFFFFF42FF2F +:1037C00063FF72FFFFFF20FF80FF68FFFFFFA7FF7F +:1037D00000FF70FFFFFF41FF63FF72FFFFFF24FF49 +:1037E00080FF68FFFFFFA7FF00FF70FFFFFF46FF9E +:1037F00063FF72FFFFFF24FF80FF68FFFFFFA7FF4B +:1038000000FF70FFFFFF45FF63FF72FFFFFF20FF18 +:1038100000FF68FFFFFFA7FF80FF70FFFFFF42FF71 +:1038200063FF72FFFFFF20FF80FF70FFFFFF41FF7C +:1038300063FF6AFFFFFFA7FF00FF70FFFFFF24FF8A +:1038400080FF68FFFFFFA7FF00FF70FFFFFF44FF3F +:1038500063FF72FFFFFF24FF80FF68FFFFFFA7FFEA +:10386000F0FF40FFFFFF05FF00FF4FFFFFFF04FFDA +:1038700000FF0DFFFFFF0BFF80FF27FFFFFF0FFF84 +:1038800088FF23FFFFFF0FFFEAFF20FFFFFF0FFF6F +:1038900074FF22FFFFFF0FFF00FF68FFFFFFA7FF7E +:1038A00000FF70FFFFFF24FF80FF70FFFFFF44FF5A +:1038B00063FF72FFFFFF24FF80FF68FFFFFFA7FF8A +:1038C00000FF4FFFFFFF04FF00FF0DFFFFFF0BFF97 +:1038D00080FF27FFFFFF0FFF88FF23FFFFFF0FFF82 +:1038E000EAFF20FFFFFF0FFF74FF22FFFFFF0FFF24 +:1038F00000FF68FFFFFFA7FF00FF0AFFFFFF0FFFAA +:1039000038FF22FFFFFF0FFF72FF14FFFFFF35FF9D +:103910008BFF83FFFFFF30FF78FF22FFFFFF0FFFCA +:1039200000FF0AFFFFFF0FFF0EFF40FFFFFF00FF3A +:1039300010FF90FFFFFF10FF08FF40FFFFFF00FF99 +:1039400010FF90FFFFFF90FF02FF40FFFFFF40FFCF +:1039500011FF90FFFFFF20FF00FF40FFFFFF00FF70 +:1039600010FF90FFFFFFB0FFB0FF40FFFFFF00FF21 +:1039700047FF90FFFFFF50FF30FF40FFFFFF00FFBA +:1039800047FF90FFFFFF40FF78FF42FFFFFF50FF20 +:1039900048FF90FFFFFFA0FF40FF40FFFFFF00FF39 +:1039A00049FF90FFFFFF70FF18FF40FFFFFF00FF80 +:1039B00047FF90FFFFFF70FF18FF40FFFFFF10FF62 +:1039C00047FF90FFFFFF70FF18FF40FFFFFF00FF62 +:1039D00047FF90FFFFFF70FF00FF40FFFFFF00FF6A +:1039E00011FF90FFFFFF60FF8DFF93FFFFFFD0FFF0 +:1039F0000BFF40FFFFFF80FF11FF90FFFFFFF0FF75 +:103A000000FF40FFFFFF10FF11FF90FFFFFFE0FFEF +:103A100000FF48FFFFFF00FF00FF93FFFFFF00FFD5 +:103A200000FF0AFFFFFF0FFF08FF40FFFFFF00FF3F +:103A300047FF90FFFFFF20FF22FF18FFFFFF9FFFC0 +:103A400000FF48FFFFFF10FF86FF93FFFFFF70FF9F +:103A500022FF18FFFFFF9FFF00FF48FFFFFF00FF4F +:103A600086FF93FFFFFF70FF22FF18FFFFFF9FFFFE +:103A700000FF48FFFFFF20FF86FF93FFFFFF70FF5F +:103A800022FF18FFFFFF9FFF00FF34FFFFFF48FFEB +:103A900000FF60FFFFFF03FF86FF93FFFFFFB0FF04 +:103AA00000FF60FFFFFF03FF86FF93FFFFFFC0FFE4 +:103AB00086FF97FFFFFFD0FF00FF0AFFFFFF0FFF0A +:103AC00080FF37FFFFFF02FF84FF3BFFFFFF02FF86 +:103AD00000FF60FFFFFF0BFF0CFF0DFFFFFF90FFDC +:103AE00000FF70FFFFFF0BFF0CFF0DFFFFFFB0FF9C +:103AF00088FF37FFFFFF03FF8CFF3BFFFFFF03FF44 +:103B000000FF40FFFFFF01FF8BFF93FFFFFF51FF0F +:103B100082FF43FFFFFF80FF8BFF93FFFFFF60FFEC +:103B200000FF34FFFFFF89FF00FF40FFFFFF00FFA2 +:103B30000CFF0DFFFFFF80FF0CFF0DFFFFFFA0FF3D +:103B400000FF0AFFFFFF0FFF80FF37FFFFFF00FFAF +:103B500000FF34FFFFFF08FF02FF3CFFFFFF45FFB0 +:103B600076FF14FFFFFFDEFF00FFA0FFFFFF03FF54 +:103B700084FF37FFFFFF00FF00FF34FFFFFF08FF58 +:103B800002FF3CFFFFFF45FF77FF14FFFFFF2EFF03 +:103B900000FFA0FFFFFF03FF7EFF38FFFFFF00FFD6 +:103BA00000FF38FFFFFF08FF00FF3CFFFFFFE5FFBE +:103BB00077FF14FFFFFF8EFF00FF40FFFFFF00FFB6 +:103BC00000FF58FFFFFF03FF00FF0AFFFFFF0FFF8B +:103BD00064FF1CFFFFFF4FFF38FF22FFFFFF0FFFB7 +:103BE00077FF14FFFFFFE5FF8BFF83FFFFFF40FF21 +:103BF00078FF22FFFFFF0FFF64FF1CFFFFFF8FFF17 +:103C000038FF22FFFFFF0FFF78FF14FFFFFF35FF94 +:103C10008BFF83FFFFFF40FF78FF22FFFFFF0FFFB7 +:103C200000FF0AFFFFFF0FFF00FF34FFFFFF09FF48 +:103C300000FF34FFFFFF85FF00FF34FFFFFF56FF4B +:103C400000FF09FFFFFF06FF20FF40FFFFFF00FF0F +:103C500001FF40FFFFFFC1FF00FF40FFFFFF44FFE8 +:103C600000FF68FFFFFF05FF00FF68FFFFFF15FF74 +:103C700000FF68FFFFFF05FF00FF68FFFFFF45FF34 +:103C800000FF0AFFFFFF0FFF86FF87FFFFFFF0FF28 +:103C900086FF8BFFFFFFE0FF00FF34FFFFFFC8FF41 +:103CA00000FF38FFFFFFC8FF00FF60FFFFFF03FFBB +:103CB00000FF60FFFFFF13FF00FF78FFFFFF13FF10 +:103CC00000FF78FFFFFF03FF86FF97FFFFFFF0FF76 +:103CD00086FF9BFFFFFFE0FF05FF81FFFFFFC0FFA7 +:103CE00078FF22FFFFFF0FFF21FF18FFFFFF71FF8B +:103CF00000FF0AFFFFFF0FFF7FFF38FFFFFF01FFFD +:103D000000FF38FFFFFF09FF00FF38FFFFFF06FF3E +:103D10007EFF40FFFFFF00FF00FF40FFFFFFB1FFFE +:103D200008FF0CFFFFFF00FF00FF3CFFFFFFC5FF88 +:103D30007AFF14FFFFFFBEFF00FF50FFFFFF46FFAB +:103D4000E1FF22FFFFFF0FFF7AFF1CFFFFFFE0FFF5 +:103D500060FF22FFFFFF0FFF00FF58FFFFFFA7FFDD +:103D60000CFF0CFFFFFF00FF00FF0AFFFFFF0FFF2C +:103D700000FF40FFFFFFC4FF00FF0AFFFFFF0FFF30 +:103D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 +:043D9000FFFFFFFF33 +:00000001FF diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 7e47421..1abbf87 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -734,7 +734,6 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND - select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -742,15 +741,6 @@ config SND_KORG1212 To compile this driver as a module, choose M here: the module will be called snd-korg1212. -config SND_KORG1212_FIRMWARE_IN_KERNEL - bool "In-kernel firmware for Korg1212 driver" - depends on SND_KORG1212 - default y - help - Say Y here to include the static firmware built in the kernel - for the Korg1212 driver. If you choose N here, you need to - install the firmware files from the alsa-firmware package. - config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND diff --git a/sound/pci/korg1212/korg1212-firmware.h b/sound/pci/korg1212/korg1212-firmware.h deleted file mode 100644 index f6f5b91..0000000 --- a/sound/pci/korg1212/korg1212-firmware.h +++ /dev/null @@ -1,987 +0,0 @@ -static char dspCode [] = { -0x01,0xff,0x18,0xff,0xf5,0xff,0xcf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x26,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x38,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x03,0xff,0x3c,0xff,0xff,0xff,0xfc,0xff,0x67,0xff,0x40,0xff,0xff,0xff,0xc0,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x0c,0xff, -0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x0a,0xff, -0x82,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x7a,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x72,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x02,0xff,0x91,0xff,0xff,0xff,0x80,0xff, -0x02,0xff,0x91,0xff,0xff,0xff,0x90,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xc0,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0xff,0xff,0x47,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xe0,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x17,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x17,0xff, -0x80,0xff,0x37,0xff,0xff,0xff,0x02,0xff,0x84,0xff,0x3b,0xff,0xff,0xff,0x02,0xff, -0x02,0xff,0x34,0xff,0xff,0xff,0x4a,0xff,0x02,0xff,0x38,0xff,0xff,0xff,0x4a,0xff, -0x01,0xff,0x34,0xff,0xff,0xff,0x2b,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x2b,0xff, -0x80,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x50,0xff, -0x81,0xff,0x43,0xff,0xff,0xff,0x20,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x60,0xff, -0x84,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x70,0xff, -0x85,0xff,0x43,0xff,0xff,0xff,0x20,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xc0,0xff, -0x82,0xff,0x37,0xff,0xff,0xff,0x81,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff, -0x88,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x82,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x8c,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x83,0xff,0x83,0xff,0xff,0xff,0xc0,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x8a,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x82,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x8e,0xff,0x43,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x82,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x07,0xff, -0x83,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x26,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x04,0xff, -0x80,0xff,0x41,0xff,0xff,0xff,0x02,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xb6,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa6,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x07,0xff, -0x40,0xff,0x41,0xff,0xff,0xff,0x02,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xb6,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff,0x62,0xff,0x6a,0xff,0xff,0xff,0xa6,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa6,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0x02,0xff, -0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xbb,0xff, -0x02,0xff,0x41,0xff,0xff,0xff,0x82,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0xcb,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0xe2,0xff, -0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xdb,0xff, -0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x41,0xff,0xff,0xff,0x02,0xff, -0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0x82,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0x9b,0xff,0x03,0xff,0x41,0xff,0xff,0xff,0x02,0xff, -0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xa2,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0xbb,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x21,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x40,0xff,0x90,0xff,0xff,0xff,0x20,0xff, -0x02,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x85,0xff,0x0a,0xff,0x14,0xff,0xff,0xff,0xae,0xff, -0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x35,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x05,0xff, -0x0a,0xff,0x14,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff, -0x03,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x02,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x0b,0xff,0x14,0xff,0xff,0xff,0x4e,0xff, -0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x35,0xff,0xff,0xff,0x01,0xff, -0x78,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x03,0xff,0x35,0xff,0xff,0xff,0x01,0xff, -0x78,0xff,0x1c,0xff,0xff,0xff,0x5f,0xff,0x5b,0xff,0x40,0xff,0xff,0xff,0xf0,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x80,0xff,0x42,0xff,0xff,0xff,0x70,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0xdf,0xff,0x40,0xff,0xff,0xff,0xf0,0xff, -0xfe,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x80,0xff,0x42,0xff,0xff,0xff,0x70,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0xc1,0xff,0x41,0xff,0xff,0xff,0x80,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x03,0xff,0x3c,0xff,0xff,0xff,0xfc,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x04,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x23,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff, -0x59,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x0c,0xff,0x14,0xff,0xff,0xff,0xe4,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x24,0xff, -0x00,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0d,0xff,0x18,0xff,0xff,0xff,0x0f,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x18,0xff,0xff,0xff,0xd0,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x18,0xff,0xff,0xff,0x30,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x44,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x90,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x84,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x90,0xff, -0x0c,0xff,0x18,0xff,0xff,0xff,0x6f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x76,0xff,0x1c,0xff,0xff,0xff,0x9f,0xff, -0x86,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x86,0xff,0x83,0xff,0xff,0xff,0x64,0xff, -0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0x81,0xff, -0x00,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x60,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x61,0xff,0x1c,0xff,0xff,0xff,0xaf,0xff,0x77,0xff,0x1c,0xff,0xff,0xff,0xaf,0xff, -0x63,0xff,0x1c,0xff,0xff,0xff,0x4f,0xff,0x05,0xff,0x35,0xff,0xff,0xff,0x00,0xff, -0x92,0xff,0x3b,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff, -0x0f,0xff,0x14,0xff,0xff,0xff,0x6e,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x05,0xff,0x35,0xff,0xff,0xff,0xe0,0xff, -0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff, -0x10,0xff,0x14,0xff,0xff,0xff,0x0e,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,0x79,0xff,0x1c,0xff,0xff,0xff,0xff,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0e,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x15,0xff,0x1c,0xff,0xff,0xff,0x85,0xff,0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x80,0xff, -0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff, -0x16,0xff,0x18,0xff,0xff,0xff,0x1f,0xff,0x0e,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff, -0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,0x80,0xff,0x35,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x40,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x11,0xff,0x14,0xff,0xff,0xff,0x4e,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,0x87,0xff,0x83,0xff,0xff,0xff,0xf0,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x80,0xff,0x90,0xff,0x37,0xff,0xff,0xff,0x00,0xff, -0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0x50,0xff,0x86,0xff,0x97,0xff,0xff,0xff,0x90,0xff, -0x03,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x60,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x63,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,0x83,0xff,0x37,0xff,0xff,0xff,0x80,0xff, -0x75,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x83,0xff,0x43,0xff,0xff,0xff,0x00,0xff, -0x87,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x40,0xff,0x41,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x90,0xff, -0x80,0xff,0x41,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xa0,0xff, -0x8b,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff, -0x40,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,0x13,0xff,0x14,0xff,0xff,0xff,0xbe,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x8b,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x05,0xff,0x41,0xff,0xff,0xff,0x00,0xff, -0x92,0xff,0x43,0xff,0xff,0xff,0x01,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xf0,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0xe1,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xe0,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x15,0xff,0x1c,0xff,0xff,0xff,0x85,0xff, -0x75,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x40,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x53,0xff,0x18,0xff,0xff,0xff,0xb4,0xff, -0x72,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff, -0x38,0xff,0x42,0xff,0xff,0xff,0x50,0xff,0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x1e,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x20,0xff,0x1c,0xff,0xff,0xff,0xcf,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x1f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff, -0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff, -0x67,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x69,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff, -0x79,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x5d,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff, -0x18,0xff,0x1c,0xff,0xff,0xff,0xef,0xff,0x66,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff, -0x5c,0xff,0x1c,0xff,0xff,0xff,0x7f,0xff,0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff, -0x8b,0xff,0x87,0xff,0xff,0xff,0x61,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x19,0xff,0x14,0xff,0xff,0xff,0x85,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x50,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x04,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x08,0xff,0x0d,0xff,0xff,0xff,0x30,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x46,0xff, -0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,0x8b,0xff,0x97,0xff,0xff,0xff,0x61,0xff, -0x83,0xff,0x8b,0xff,0xff,0xff,0xd0,0xff,0x83,0xff,0x8b,0xff,0xff,0xff,0xe1,0xff, -0x87,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x6e,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff, -0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x92,0xff,0x37,0xff,0xff,0xff,0x01,0xff, -0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x01,0xff, -0x23,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff, -0x83,0xff,0x87,0xff,0xff,0xff,0xf1,0xff,0x86,0xff,0x8b,0xff,0xff,0xff,0x41,0xff, -0x6c,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x8b,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x40,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff, -0x1b,0xff,0x14,0xff,0xff,0xff,0xce,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe1,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x9b,0xff,0xff,0xff,0xa0,0xff, -0x8b,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff, -0x40,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x55,0xff,0x1d,0xff,0x14,0xff,0xff,0xff,0x3e,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x8b,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x8b,0xff,0x87,0xff,0xff,0xff,0x61,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x06,0xff, -0x83,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x51,0xff, -0x79,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xb4,0xff, -0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x1e,0xff,0x14,0xff,0xff,0xff,0xd5,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x50,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x04,0xff,0x0d,0xff,0xff,0xff,0x30,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x83,0xff,0x93,0xff,0xff,0xff,0xf0,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x08,0xff,0x0d,0xff,0xff,0xff,0x30,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x46,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff, -0x8b,0xff,0x97,0xff,0xff,0xff,0x61,0xff,0x83,0xff,0x8b,0xff,0xff,0xff,0xd0,0xff, -0x83,0xff,0x8b,0xff,0xff,0xff,0xe1,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x01,0xff, -0x6e,0xff,0x1c,0xff,0xff,0xff,0xbf,0xff,0x87,0xff,0x37,0xff,0xff,0xff,0x00,0xff, -0x92,0xff,0x37,0xff,0xff,0xff,0x01,0xff,0x7f,0xff,0x38,0xff,0xff,0xff,0x00,0xff, -0x23,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff, -0x83,0xff,0x87,0xff,0xff,0xff,0xf1,0xff,0x86,0xff,0x8b,0xff,0xff,0xff,0x41,0xff, -0x6c,0xff,0x1c,0xff,0xff,0xff,0x2f,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x8d,0xff,0x8f,0xff,0xff,0xff,0xc5,0xff,0x20,0xff,0x14,0xff,0xff,0xff,0xae,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x84,0xff,0x00,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x8a,0xff,0x64,0xff,0x1c,0xff,0xff,0xff,0xe0,0xff, -0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0xe5,0xff,0x21,0xff,0x14,0xff,0xff,0xff,0x5e,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x10,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x78,0xff,0x42,0xff,0xff,0xff,0x50,0xff, -0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0xb0,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0x50,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0c,0xff,0x18,0xff,0xff,0xff,0x90,0xff, -0x0c,0xff,0x18,0xff,0xff,0xff,0x6f,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x09,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff, -0x98,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xa5,0xff, -0x24,0xff,0x14,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x73,0xff, -0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,0x69,0xff,0xcc,0xff,0xff,0xff,0x37,0xff, -0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff, -0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x72,0xff, -0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff,0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff, -0x69,0xff,0xcc,0xff,0xff,0xff,0x37,0xff,0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x73,0xff,0x08,0xff,0x0d,0xff,0xff,0xff,0x14,0xff, -0x00,0xff,0x50,0xff,0xff,0xff,0xc6,0xff,0x69,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x05,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xc6,0xff, -0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x30,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x58,0xff, -0x10,0xff,0x0f,0xff,0xff,0xff,0x01,0xff,0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x26,0xff,0x18,0xff,0xff,0xff,0x94,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x80,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x49,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x16,0xff,0x0f,0xff,0xff,0xff,0x02,0xff, -0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x38,0xff,0x18,0xff,0xff,0xff,0xb4,0xff, -0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff,0x47,0xff,0x80,0xff,0xff,0xff,0x0a,0xff, -0x82,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x7a,0xff, -0x7a,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x38,0xff,0x18,0xff,0xff,0xff,0xb4,0xff,0x27,0xff,0x18,0xff,0xff,0xff,0xd2,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x30,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x29,0xff,0x18,0xff,0xff,0xff,0x92,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x1c,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x04,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x04,0xff,0xff,0xff,0x03,0xff, -0x0d,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x31,0xff,0x18,0xff,0xff,0xff,0x12,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff, -0x90,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x34,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x55,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x18,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5e,0xff,0xaf,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x48,0xff,0x10,0xff,0x0f,0xff,0xff,0xff,0xfe,0xff, -0x87,0xff,0x93,0xff,0xff,0xff,0xfe,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x2e,0xff, -0x02,0xff,0x40,0xff,0xff,0xff,0x06,0xff,0xe0,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa1,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x28,0xff, -0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff, -0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x38,0xff, -0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5e,0xff, -0xaf,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff, -0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff, -0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa0,0xff,0x63,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4a,0xff,0x49,0xff,0x6a,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff, -0xff,0xff,0x4f,0xff,0xff,0xff,0xf0,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x50,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x32,0xff,0x18,0xff,0xff,0xff,0x42,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x44,0xff, -0x08,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x8a,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x5a,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x35,0xff,0x18,0xff,0xff,0xff,0xd2,0xff, -0x00,0xff,0x4c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff, -0x0b,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x0a,0xff,0x7a,0xff,0x26,0xff,0xff,0xff,0x0f,0xff, -0x35,0xff,0x1c,0xff,0xff,0xff,0x24,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x33,0xff,0x18,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0xc0,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x34,0xff,0x18,0xff,0xff,0xff,0x85,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x80,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff, -0x0d,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff, -0xff,0xff,0x40,0xff,0xff,0xff,0xf0,0xff,0x90,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x37,0xff,0x18,0xff,0xff,0xff,0x42,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0xa0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0xb0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x20,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0xc0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x30,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x40,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x50,0xff, -0x89,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x10,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x39,0xff,0x18,0xff,0xff,0xff,0x22,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x20,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x30,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x20,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x38,0xff,0x1c,0xff,0xff,0xff,0x84,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x50,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x30,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x50,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x41,0xff,0x18,0xff,0xff,0xff,0x30,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xe4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x42,0xff,0x18,0xff,0xff,0xff,0x40,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xd4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x47,0xff,0x18,0xff,0xff,0xff,0xa0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xc4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x18,0xff,0xff,0xff,0xd0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xb4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x48,0xff,0x18,0xff,0xff,0xff,0xe0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xa4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4a,0xff,0x18,0xff,0xff,0xff,0x60,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x94,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4c,0xff,0x18,0xff,0xff,0xff,0x00,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x84,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4d,0xff,0x18,0xff,0xff,0xff,0xe0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x74,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4f,0xff,0x18,0xff,0xff,0xff,0x20,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0x64,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x4f,0xff,0x18,0xff,0xff,0xff,0xf0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0xf4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x44,0xff,0x18,0xff,0xff,0xff,0x40,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0xe4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x45,0xff,0x18,0xff,0xff,0xff,0x50,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x04,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3d,0xff,0x18,0xff,0xff,0xff,0xd0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x14,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0x10,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x24,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0x80,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x34,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x3f,0xff,0x18,0xff,0xff,0xff,0xf0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x0a,0xff,0x40,0xff,0xff,0xff,0x44,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x40,0xff,0x18,0xff,0xff,0xff,0x60,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x21,0xff,0x40,0xff,0xff,0xff,0x80,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x25,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0xe9,0xff,0x41,0xff,0xff,0xff,0x80,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0xed,0xff,0x41,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x44,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf1,0xff,0x41,0xff,0xff,0xff,0x80,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xf0,0xff,0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x22,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x88,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x50,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff, -0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x88,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x04,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x50,0xff,0xff,0xff,0x23,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff, -0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0xff,0xff,0x83,0xff,0xff,0xff,0xe2,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x03,0xff,0x0d,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x60,0xff, -0x0c,0xff,0x0d,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x02,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf2,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0xe3,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff, -0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x22,0xff, -0x67,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x62,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x84,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x06,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x10,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x23,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x32,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x72,0xff, -0x67,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe0,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x05,0xff,0x03,0xff,0x0d,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x0c,0xff,0x0d,0xff,0xff,0xff,0xf5,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xc0,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0xc7,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff, -0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff,0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff,0x46,0xff,0x80,0xff,0xff,0xff,0x00,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0xe0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xe7,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x67,0xff,0xf7,0xff,0x4f,0xff,0xff,0xff,0xf4,0xff, -0x46,0xff,0x90,0xff,0xff,0xff,0x74,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x70,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x04,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x46,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x0c,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x1f,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x51,0xff,0x14,0xff,0xff,0xff,0x81,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff, -0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x16,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff, -0x90,0xff,0x34,0xff,0xff,0xff,0x71,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff, -0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x88,0xff,0x63,0xff,0xff,0xff,0x27,0xff,0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x62,0xff,0x61,0xff,0xff,0xff,0x27,0xff,0x88,0xff,0x2b,0xff,0xff,0xff,0x8b,0xff, -0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x62,0xff,0x61,0xff,0xff,0xff,0x17,0xff, -0x88,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff,0x89,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0xab,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xb8,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0xcf,0xff,0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff, -0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff, -0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x51,0xff,0x18,0xff,0xff,0xff,0x00,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0xeb,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfc,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x51,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0xac,0xff,0x82,0xff,0x3c,0xff,0xff,0xff,0x45,0xff, -0x54,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf5,0xff, -0x54,0xff,0x14,0xff,0xff,0xff,0x1e,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x51,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x0c,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xa4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x53,0xff,0x18,0xff,0xff,0xff,0xb3,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xba,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6b,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x55,0xff,0x14,0xff,0xff,0xff,0x21,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff, -0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x20,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x31,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0xc9,0xff,0x2a,0xff,0xff,0xff,0xea,0xff, -0x54,0xff,0x18,0xff,0xff,0xff,0xd5,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x5a,0xff,0x82,0xff,0x4f,0xff,0xff,0xff,0xf0,0xff, -0xff,0xff,0x4f,0xff,0xff,0xff,0xf1,0xff,0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0xc9,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,0x56,0xff,0x18,0xff,0xff,0xff,0xb4,0xff, -0x54,0xff,0x18,0xff,0xff,0xff,0xdf,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x02,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff, -0x16,0xff,0x18,0xff,0xff,0xff,0x4f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff, -0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x57,0xff,0x14,0xff,0xff,0xff,0x91,0xff, -0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff, -0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6a,0xff, -0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x16,0xff, -0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,0x90,0xff,0x34,0xff,0xff,0xff,0x71,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x88,0xff,0x63,0xff,0xff,0xff,0x27,0xff, -0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff,0x62,0xff,0x61,0xff,0xff,0xff,0x27,0xff, -0x88,0xff,0x2b,0xff,0xff,0xff,0x8b,0xff,0xe8,0xff,0x60,0xff,0xff,0xff,0x07,0xff, -0x62,0xff,0x61,0xff,0xff,0xff,0x17,0xff,0x88,0xff,0x2f,0xff,0xff,0xff,0xfb,0xff, -0x89,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xab,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0xb8,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0xcf,0xff, -0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x62,0xff,0x21,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff, -0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff,0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x57,0xff,0x18,0xff,0xff,0xff,0x10,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xeb,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0xfc,0xff,0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x57,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0xac,0xff,0x82,0xff,0x3c,0xff,0xff,0xff,0x45,0xff, -0x5a,0xff,0x14,0xff,0xff,0xff,0x4e,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf5,0xff, -0x5a,0xff,0x14,0xff,0xff,0xff,0x3e,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x57,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x0c,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xa4,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x59,0xff,0x18,0xff,0xff,0xff,0xd3,0xff, -0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0xd0,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff,0xa0,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0xba,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff, -0x5c,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0x6b,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x18,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x5b,0xff,0x14,0xff,0xff,0xff,0x61,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x60,0xff, -0x80,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe4,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xf5,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,0x5e,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x5b,0xff,0x18,0xff,0xff,0xff,0x0f,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x20,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x0d,0xff,0x18,0xff,0xff,0xff,0x05,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x05,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xe0,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xf1,0xff, -0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff, -0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x05,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe0,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xf1,0xff,0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x49,0xff,0x2a,0xff,0xff,0xff,0xea,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0xfa,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0xee,0xff,0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x5e,0xff,0x1c,0xff,0xff,0xff,0x04,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x50,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x5f,0xff,0x1c,0xff,0xff,0xff,0x54,0xff, -0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0xa8,0xff, -0x10,0xff,0x0f,0xff,0xff,0xff,0x08,0xff,0x90,0xff,0x80,0xff,0xff,0xff,0x90,0xff, -0x88,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0xb6,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xfa,0xff,0xf2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x0a,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x14,0xff, -0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff, -0x38,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x24,0xff, -0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0f,0xff,0x40,0xff,0xff,0xff,0xf5,0xff, -0x90,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xe2,0xff, -0x88,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x98,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x10,0xff,0x40,0xff,0xff,0xff,0x07,0xff,0xe8,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0xac,0xff,0xf2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x0a,0xff,0x01,0xff,0x40,0xff,0xff,0xff,0x04,0xff, -0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff, -0x38,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x04,0xff, -0xe2,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x18,0xff,0xff,0xff,0xe2,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0xd4,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x85,0xff, -0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x01,0xff, -0x89,0xff,0x83,0xff,0xff,0xff,0xb8,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0xa8,0xff, -0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff, -0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff, -0x00,0xff,0x09,0xff,0xff,0xff,0x03,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0xb0,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x02,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x26,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0xd8,0xff, -0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff, -0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff, -0x89,0xff,0x83,0xff,0xff,0xff,0xc8,0xff,0x00,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x4e,0xff,0xa7,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa3,0xff,0x00,0xff,0x09,0xff,0xff,0xff,0x03,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff, -0x01,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x02,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff, -0x8b,0xff,0x93,0xff,0xff,0xff,0x40,0xff,0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x49,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x60,0xff,0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x01,0xff,0x42,0xff,0xff,0xff,0x80,0xff, -0x00,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x07,0xff,0x42,0xff,0xff,0xff,0x80,0xff, -0x03,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x02,0xff,0x42,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,0x08,0xff,0x42,0xff,0xff,0xff,0x00,0xff, -0x03,0xff,0x91,0xff,0xff,0xff,0xf0,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff, -0x01,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff, -0x04,0xff,0x91,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x04,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff, -0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x91,0xff,0xff,0xff,0xf0,0xff, -0x01,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff, -0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x40,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x80,0xff, -0x05,0xff,0x35,0xff,0xff,0xff,0x00,0xff,0x92,0xff,0x3b,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x65,0xff,0x65,0xff,0x14,0xff,0xff,0xff,0x9e,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff, -0x01,0xff,0x42,0xff,0xff,0xff,0x00,0xff,0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff, -0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0x05,0xff,0x81,0xff,0xff,0xff,0xc0,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x21,0xff,0x18,0xff,0xff,0xff,0x71,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x80,0xff,0xff,0xff,0x48,0xff, -0x10,0xff,0x0f,0xff,0xff,0xff,0x03,0xff,0x66,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0x74,0xff,0x18,0xff,0xff,0xff,0x54,0xff,0x86,0xff,0x83,0xff,0xff,0xff,0xc0,0xff, -0x49,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x62,0xff,0x1c,0xff,0xff,0xff,0xff,0xff, -0x86,0xff,0x83,0xff,0xff,0xff,0x80,0xff,0x01,0xff,0x40,0xff,0xff,0xff,0x04,0xff, -0xe0,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x8a,0xff, -0x67,0xff,0x1c,0xff,0xff,0xff,0x00,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xd0,0xff, -0x75,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x86,0xff,0x8b,0xff,0xff,0xff,0xb0,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0x44,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x89,0xff,0x83,0xff,0xff,0xff,0x55,0xff, -0x60,0xff,0x26,0xff,0xff,0xff,0x0f,0xff,0x49,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff,0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0xa0,0xff,0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff, -0x89,0xff,0x83,0xff,0xff,0xff,0x24,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff, -0x89,0xff,0x83,0xff,0xff,0xff,0x35,0xff,0x60,0xff,0x26,0xff,0xff,0xff,0x0f,0xff, -0x49,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff, -0x10,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xa3,0xff, -0x8d,0xff,0x83,0xff,0xff,0xff,0x60,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x04,0xff, -0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0x6a,0xff, -0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xb0,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x01,0xff,0x34,0xff,0xff,0xff,0x04,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x35,0xff,0xff,0xff,0x4f,0xff,0xff,0xff,0x89,0xff, -0x00,0xff,0x09,0xff,0xff,0xff,0x01,0xff,0x87,0xff,0x8b,0xff,0xff,0xff,0xe0,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x88,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x03,0xff,0x87,0xff,0x9b,0xff,0xff,0xff,0xe0,0xff, -0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x01,0xff,0x3c,0xff,0xff,0xff,0x05,0xff,0x6a,0xff,0x14,0xff,0xff,0xff,0x9e,0xff, -0x67,0xff,0x1c,0xff,0xff,0xff,0x3f,0xff,0x69,0xff,0x1c,0xff,0xff,0xff,0x0f,0xff, -0x66,0xff,0x1c,0xff,0xff,0xff,0x1f,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x6a,0xff,0x14,0xff,0xff,0xff,0x85,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x82,0xff,0x83,0xff,0xff,0xff,0x40,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x6a,0xff,0x1c,0xff,0xff,0xff,0xf4,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x87,0xff,0x83,0xff,0xff,0xff,0xf0,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x80,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x8d,0xff,0x93,0xff,0xff,0xff,0x60,0xff,0x82,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0x86,0xff,0x87,0xff,0xff,0xff,0x90,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x30,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x40,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x89,0xff,0x93,0xff,0xff,0xff,0x50,0xff, -0x86,0xff,0x97,0xff,0xff,0xff,0x90,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x64,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x35,0xff, -0x01,0xff,0x34,0xff,0xff,0xff,0x96,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x34,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x65,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x96,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x34,0xff,0xff,0xff,0x49,0xff, -0x02,0xff,0x38,0xff,0xff,0xff,0x49,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x06,0xff, -0x10,0xff,0x40,0xff,0xff,0xff,0x02,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,0x6d,0xff,0x14,0xff,0xff,0xff,0xbe,0xff, -0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff, -0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x88,0xff,0x68,0xff,0xff,0xff,0xc4,0xff, -0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xc6,0xff, -0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff, -0x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x88,0xff,0x78,0xff,0xff,0xff,0xc5,0xff, -0x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0xc6,0xff, -0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff, -0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x88,0xff,0x68,0xff,0xff,0xff,0xc4,0xff, -0x83,0xff,0x68,0xff,0xff,0xff,0xc5,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xc6,0xff, -0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff,0x6e,0xff,0x14,0xff,0xff,0xff,0x8e,0xff, -0x98,0xff,0x50,0xff,0xff,0xff,0x73,0xff,0x88,0xff,0x50,0xff,0xff,0xff,0x73,0xff, -0x83,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x88,0xff,0x78,0xff,0xff,0xff,0xc4,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0xc4,0xff,0x20,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0xe9,0xff, -0x01,0xff,0x38,0xff,0xff,0xff,0x28,0xff,0x01,0xff,0x38,0xff,0xff,0xff,0x29,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x66,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x34,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x75,0xff,0x10,0xff,0x40,0xff,0xff,0xff,0x06,0xff, -0x00,0xff,0x41,0xff,0xff,0xff,0x07,0xff,0x30,0xff,0x0c,0xff,0xff,0xff,0x00,0xff, -0x98,0xff,0x70,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0x25,0xff, -0x70,0xff,0x14,0xff,0xff,0xff,0x2e,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x42,0xff, -0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff, -0x00,0xff,0x70,0xff,0xff,0xff,0x41,0xff,0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff, -0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x46,0xff, -0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff, -0x00,0xff,0x70,0xff,0xff,0xff,0x45,0xff,0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x42,0xff, -0x63,0xff,0x72,0xff,0xff,0xff,0x20,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x41,0xff, -0x63,0xff,0x6a,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x24,0xff, -0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x70,0xff,0xff,0xff,0x44,0xff, -0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff, -0xf0,0xff,0x40,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x4f,0xff,0xff,0xff,0x04,0xff, -0x00,0xff,0x0d,0xff,0xff,0xff,0x0b,0xff,0x80,0xff,0x27,0xff,0xff,0xff,0x0f,0xff, -0x88,0xff,0x23,0xff,0xff,0xff,0x0f,0xff,0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff, -0x74,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff, -0x00,0xff,0x70,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x70,0xff,0xff,0xff,0x44,0xff, -0x63,0xff,0x72,0xff,0xff,0xff,0x24,0xff,0x80,0xff,0x68,0xff,0xff,0xff,0xa7,0xff, -0x00,0xff,0x4f,0xff,0xff,0xff,0x04,0xff,0x00,0xff,0x0d,0xff,0xff,0xff,0x0b,0xff, -0x80,0xff,0x27,0xff,0xff,0xff,0x0f,0xff,0x88,0xff,0x23,0xff,0xff,0xff,0x0f,0xff, -0xea,0xff,0x20,0xff,0xff,0xff,0x0f,0xff,0x74,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0xa7,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x72,0xff,0x14,0xff,0xff,0xff,0x35,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x30,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x0e,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x10,0xff,0x90,0xff,0xff,0xff,0x10,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x10,0xff,0x90,0xff,0xff,0xff,0x90,0xff,0x02,0xff,0x40,0xff,0xff,0xff,0x40,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x10,0xff,0x90,0xff,0xff,0xff,0xb0,0xff,0xb0,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x50,0xff,0x30,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x42,0xff,0xff,0xff,0x50,0xff, -0x48,0xff,0x90,0xff,0xff,0xff,0xa0,0xff,0x40,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x49,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x10,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x18,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x70,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x11,0xff,0x90,0xff,0xff,0xff,0x60,0xff,0x8d,0xff,0x93,0xff,0xff,0xff,0xd0,0xff, -0x0b,0xff,0x40,0xff,0xff,0xff,0x80,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xf0,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x10,0xff,0x11,0xff,0x90,0xff,0xff,0xff,0xe0,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x93,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x08,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x47,0xff,0x90,0xff,0xff,0xff,0x20,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x10,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff, -0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,0x00,0xff,0x48,0xff,0xff,0xff,0x00,0xff, -0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff,0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff, -0x00,0xff,0x48,0xff,0xff,0xff,0x20,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0x70,0xff, -0x22,0xff,0x18,0xff,0xff,0xff,0x9f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x48,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xb0,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x93,0xff,0xff,0xff,0xc0,0xff, -0x86,0xff,0x97,0xff,0xff,0xff,0xd0,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x80,0xff,0x37,0xff,0xff,0xff,0x02,0xff,0x84,0xff,0x3b,0xff,0xff,0xff,0x02,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x0b,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0x90,0xff, -0x00,0xff,0x70,0xff,0xff,0xff,0x0b,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0xb0,0xff, -0x88,0xff,0x37,0xff,0xff,0xff,0x03,0xff,0x8c,0xff,0x3b,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0x01,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x51,0xff, -0x82,0xff,0x43,0xff,0xff,0xff,0x80,0xff,0x8b,0xff,0x93,0xff,0xff,0xff,0x60,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x89,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x0c,0xff,0x0d,0xff,0xff,0xff,0x80,0xff,0x0c,0xff,0x0d,0xff,0xff,0xff,0xa0,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x80,0xff,0x37,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff,0x02,0xff,0x3c,0xff,0xff,0xff,0x45,0xff, -0x76,0xff,0x14,0xff,0xff,0xff,0xde,0xff,0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff, -0x84,0xff,0x37,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x08,0xff, -0x02,0xff,0x3c,0xff,0xff,0xff,0x45,0xff,0x77,0xff,0x14,0xff,0xff,0xff,0x2e,0xff, -0x00,0xff,0xa0,0xff,0xff,0xff,0x03,0xff,0x7e,0xff,0x38,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x08,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xe5,0xff, -0x77,0xff,0x14,0xff,0xff,0xff,0x8e,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x00,0xff,0x58,0xff,0xff,0xff,0x03,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x64,0xff,0x1c,0xff,0xff,0xff,0x4f,0xff,0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x77,0xff,0x14,0xff,0xff,0xff,0xe5,0xff,0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x64,0xff,0x1c,0xff,0xff,0xff,0x8f,0xff, -0x38,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x78,0xff,0x14,0xff,0xff,0xff,0x35,0xff, -0x8b,0xff,0x83,0xff,0xff,0xff,0x40,0xff,0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x09,0xff, -0x00,0xff,0x34,0xff,0xff,0xff,0x85,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0x56,0xff, -0x00,0xff,0x09,0xff,0xff,0xff,0x06,0xff,0x20,0xff,0x40,0xff,0xff,0xff,0x00,0xff, -0x01,0xff,0x40,0xff,0xff,0xff,0xc1,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0x44,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x15,0xff, -0x00,0xff,0x68,0xff,0xff,0xff,0x05,0xff,0x00,0xff,0x68,0xff,0xff,0xff,0x45,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x86,0xff,0x87,0xff,0xff,0xff,0xf0,0xff, -0x86,0xff,0x8b,0xff,0xff,0xff,0xe0,0xff,0x00,0xff,0x34,0xff,0xff,0xff,0xc8,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0xc8,0xff,0x00,0xff,0x60,0xff,0xff,0xff,0x03,0xff, -0x00,0xff,0x60,0xff,0xff,0xff,0x13,0xff,0x00,0xff,0x78,0xff,0xff,0xff,0x13,0xff, -0x00,0xff,0x78,0xff,0xff,0xff,0x03,0xff,0x86,0xff,0x97,0xff,0xff,0xff,0xf0,0xff, -0x86,0xff,0x9b,0xff,0xff,0xff,0xe0,0xff,0x05,0xff,0x81,0xff,0xff,0xff,0xc0,0xff, -0x78,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x21,0xff,0x18,0xff,0xff,0xff,0x71,0xff, -0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff,0x7f,0xff,0x38,0xff,0xff,0xff,0x01,0xff, -0x00,0xff,0x38,0xff,0xff,0xff,0x09,0xff,0x00,0xff,0x38,0xff,0xff,0xff,0x06,0xff, -0x7e,0xff,0x40,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x40,0xff,0xff,0xff,0xb1,0xff, -0x08,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x3c,0xff,0xff,0xff,0xc5,0xff, -0x7a,0xff,0x14,0xff,0xff,0xff,0xbe,0xff,0x00,0xff,0x50,0xff,0xff,0xff,0x46,0xff, -0xe1,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x7a,0xff,0x1c,0xff,0xff,0xff,0xe0,0xff, -0x60,0xff,0x22,0xff,0xff,0xff,0x0f,0xff,0x00,0xff,0x58,0xff,0xff,0xff,0xa7,0xff, -0x0c,0xff,0x0c,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0x00,0xff,0x40,0xff,0xff,0xff,0xc4,0xff,0x00,0xff,0x0a,0xff,0xff,0xff,0x0f,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff }; diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index f4c85b5..4a44c0f 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -260,14 +260,6 @@ enum MonitorModeSelector { #define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement // from the card after sending a command. -#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL -#include "korg1212-firmware.h" -static const struct firmware static_dsp_code = { - .data = (u8 *)dspCode, - .size = sizeof dspCode -}; -#endif - enum ClockSourceIndex { K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz K1212_CLKIDX_AdatAt48K, // selects source as ADAT at 48 kHz @@ -412,9 +404,7 @@ struct snd_korg1212 { MODULE_DESCRIPTION("korg1212"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}"); -#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL MODULE_FIRMWARE("korg/k1212.dsp"); -#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -2348,9 +2338,6 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + offsetof(struct KorgSharedBuffer, AdatTimeCode); -#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL - dsp_code = &static_dsp_code; -#else err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { release_firmware(dsp_code); @@ -2358,15 +2345,12 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * snd_korg1212_free(korg1212); return err; } -#endif if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), dsp_code->size, &korg1212->dma_dsp) < 0) { snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); snd_korg1212_free(korg1212); -#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL release_firmware(dsp_code); -#endif return -ENOMEM; } @@ -2376,9 +2360,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); -#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL release_firmware(dsp_code); -#endif rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); -- cgit v0.10.2 From a292f404fabb342716a9d96e8155b7fb7b651dc1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 14:48:34 +0300 Subject: firmware: convert maestro3 driver to use firmware loader exclusively Signed-off-by: David Woodhouse diff --git a/firmware/Makefile b/firmware/Makefile index ea4a883..f312ac0 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -21,6 +21,8 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # But be aware that the config file might not be included at all. fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp +fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ + ess/maestro3_assp_minisrc.fw fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index 89ca95b..c08dbc8 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -17,3 +17,17 @@ Licence: Unknown Found in alsa-firmware package in hex form; no licensing information. -------------------------------------------------------------------------- + +Driver: maestro3 -- ESS Allegro Maestro3 audio device + +File: ess/maestro3_assp_kernel.fw +File: ess/maestro3_assp_minisrc.fw + +Licence: Unknown + +Found in alsa-firmware package in hex form with a comment claiming to +be GPLv2+, but without source -- and with another comment saying "ESS +drops binary dsp code images on our heads, but we don't get to see +specs on the dsp." + +-------------------------------------------------------------------------- diff --git a/firmware/ess/maestro3_assp_kernel.fw.ihex b/firmware/ess/maestro3_assp_kernel.fw.ihex new file mode 100644 index 0000000..933c4c3 --- /dev/null +++ b/firmware/ess/maestro3_assp_kernel.fw.ihex @@ -0,0 +1,120 @@ +:10000000807930008079B4038079B4038079FB0073 +:100010008079DD008079B4038079320380798702AA +:100020008079B4038079B4038079B4038079B40310 +:1000300080791A038079B40380792F028079B40320 +:100040008079B4038079B4038079B4038079B403F0 +:100050008079630080796B008079B4038079B40380 +:1000600080BF7C2C0688048840BE20BC09AE0010EE +:100070000AAE0100386908EB53005A6908EBD60054 +:100080000900888B806988E3360030BE20BC09698E +:1000900001B8099041BE41BE286988EB780041BE95 +:1000A00040BE8079380041BE41BE3A90386908E3CD +:1000B00056003A9041BE40BE00EF3A90396908E3DD +:1000C0005E003A9000EF0B690C668CEF0A690C66D3 +:1000D0000B62096600EF10690F6604EF88E3750094 +:1000E0000E690F6610620D6600EF0E690D6600EF77 +:1000F00070AE010020BC27AE0100396908EB5D003D +:10010000266901B826902600888B806988E3CB0099 +:100110002890280D114200E17A00114700E1A0006B +:10012000807A630011B80A66096204E37A000B0C56 +:1001300005400A1001BA1290120C02408079AF00FB +:10014000807A6B0002BE0E620D6610BA44E37A003C +:10015000100C05400E1001BA1290120C0240031050 +:1001600002BA1290120C0040031088E3BA00041087 +:100170008079BC00041001BA1290120C0140050CE9 +:100180000340060C04401110B0BFFF011290120C86 +:10019000064020BC00EF26AE28107069D0BF0100D9 +:1001A000709088E37A0028AE000000EF70AE000384 +:1001B000700C0CB05AAE000000EF807A8A037F69A1 +:1001C00001B87F905600888BA00C08B071AF00B0CA +:1001D000714E00E2F30056AE57105600A00C08B066 +:1001E00056808079A1031008A0BF591004E3A10331 +:1001F00056808079A103807A8A0301BF43BE59BE2D +:100200007C90376988E30D0101BA08E30C0171AEF7 +:100210000400710C0050366937900ABF9E108A8B1B +:1002200080AF1480804C0ABF600500F50ABF20052E +:1002300000B917BBA090176988E34801170D00E1CA +:1002400027010CBF78050DBF7C0580792B010CBF01 +:1002500038050DBF3C05006908E335018C8B59BE9C +:1002600007BBA09020BC807957010C038B8B03B98E +:100270000988C6BE3E01AC69AB90AD69AB9013086E +:100280000A6644E3440109030C8320BC80795701CA +:10029000556988E35701387C0BBF780500F50BBF23 +:1002A000380507B90988C6BE5601AB10AA90746913 +:1002B00088E3630172AE400500F572AE000561AEE1 +:1002C0003B10807AF602786988E382018C8B0CBF40 +:1002D000600500E5407C140820BA12883D73807ADE +:1002E00080033E73807A80038C8B0CBF6C0500E525 +:1002F000407C14082CBA12883F73807A80034073C4 +:10030000807A8003756988E38E0172AE480500F536 +:1003100072AE080561AE4110807AF602796988E311 +:10032000AD018C8B0CBF600500E5407C140818BA49 +:1003300012884373807A80034473807A80038C8BA5 +:100340000CBF6C0500E5407C140824BA1288457384 +:10035000807A80034673807A8003766988E3B901E6 +:1003600072AE580500F572AE180561AE4710807A7E +:10037000F6027A6988E3D8018C8B0CBF600500E532 +:10038000407C140808BA12884973807A80034A7343 +:10039000807A80038C8B0CBF6C0500E5407C1408D0 +:1003A00014BA12884B73807A80034C73807A80036E +:1003B00021BC1CAE90108A8B0ABF600500E5407C12 +:1003C000120804B813888D8B0DBF6C0500E5407CC6 +:1003D000150804B81188807A4A038A8B0ABF600521 +:1003E00000E5407C1F7303B90988C6BEF9018A5431 +:1003F00003BEA098207303B90988C6BE01028A54BF +:1004000003BEA098201F1F2F269820BC356988E3C3 +:10041000A103336901B83390A0BFEE0208E3A10342 +:10042000339000BF516988E31F02347380BE605768 +:1004300003BE7E9F59BE34907E69510D139020BC3F +:100440005C6988E3A1035E7380BE605703BE7E9F34 +:1004500059BE5E907E695C0D13908079A103807A0D +:100460008A0301BF43BE776988E34E0261AE4D1037 +:100470006100888B806988E34E027190710D0B00DA +:10048000A0AF1080A0AF108010080A6608E34902F0 +:10049000090010080C6688E34E020B8020BC7B69C3 +:1004A00088E3A1030ABF9E108A8B80AF1480804C22 +:1004B00000E166027C6990BF6005729072037C69FE +:1004C00090BF640573907304807970027C6990BF5B +:1004D0002005729072037C6990BF240573907304A9 +:1004E0007C6901B87C900ABFFD108A8B80AF1080B8 +:1004F0004F738A5403BE809821BC26738B5403BE6D +:100500008B618C9803BE806180988079A103807A8A +:100510008A03280D114700E1BE0212AF064012699E +:10052000B0BF000C88E3B602A0BF000888E3B202A7 +:100530001269B0BF000CA0BF000488E3A3020969E0 +:100540000B908079A5020BAF054001690590026907 +:100550000690114300E1ED021169C0BF0020119027 +:100560008079ED0209690B908079B8020BAF0540E4 +:1005700005AF034006AF04408079ED0212AF06409C +:100580001269B0BF000C88E3E702A0BF000888E34F +:10059000E3021269B0BF000CA0BF000488E3D402DC +:1005A0000D6910908079D60210AF05400169059061 +:1005B00002690690114300E1ED021169C0BF0020FD +:1005C00011908079ED020D6910908079E90210AFE9 +:1005D000054005AF034006AF044020BC7069719030 +:1005E000807A7800716970908079A10320BC6103E2 +:1005F0008B8B806988EF7202720304787190710DA1 +:100600008A8B0B0003B90988C6BE0903A869AB90A1 +:10061000A869AA9010080A6644E30F0309001008AD +:100620000C6688E314030B8020BC616901B86190FB +:100630008079F702807A8A03355D0100346901B858 +:1006400034900ABF9E108A8B80AF1480804872AEAF +:10065000500500F572AE100561AE5110807AF602B9 +:100660008079A103807A8A03355D02005E6901B852 +:100670005E900ABF9E108A8B80AF1480804772AE56 +:10068000580500F572AE180561AE5C10807AF6026E +:100690008079A1031C00888B806988EF1D901D0D57 +:1006A0000F1010668CE358030E6910660F620D661A +:1006B0000FBA01E37A0310048A8B03B90988C6BE16 +:1006C0006C038C6AAA61AB988C6AAB61AD988C6A3A +:1006D000AD61A9988C6AA961AA98047C8B8B047C73 +:1006E0008D8B047C898B047C14080E6608E37903E7 +:1006F0000D04108421BC1C6901B81C9080794A0348 +:1007000003B909888A8BC6BE8803AC5403BE8C61CA +:10071000AA9800EF20BC46BE09086B900A086C90AE +:100720000B086D901A0862901B0863901E08649075 +:1007300059BE1E88658066816782688369846A8580 +:1007400000EF20BC6B6909886C690A886D690B88A9 +:1007500062691A8863691B8864691E88650066017E +:0A0760006702680369046A053ABEE7 +:00000001FF diff --git a/firmware/ess/maestro3_assp_minisrc.fw.ihex b/firmware/ess/maestro3_assp_minisrc.fw.ihex new file mode 100644 index 0000000..d2c0031 --- /dev/null +++ b/firmware/ess/maestro3_assp_minisrc.fw.ihex @@ -0,0 +1,51 @@ +:1000000080BF1E106E906E00888B806988EF6F90A5 +:100010006F0D006908EB120420BC6E6901B86E9088 +:10002000807903040EB9078843BE01BF47BE41BEB5 +:10003000807A2A0040BE2930CCEF41BE807A280069 +:1000400040BE2830CCEF076908E32A0409692C90E8 +:1000500080792C040D692C9009101A880A1001BAB5 +:100060001B880D101C880E1001BA1D8880BFED0082 +:100070001E880C05240104B92790186908E3B3040D +:100080002D901369A0BF987504F72DAEFF008D8BDE +:10009000196908E363041A6908E3560407B9098873 +:1000A000C6BE5304A910AD9080797C0403B90988B9 +:1000B000C6BE60048918226CAD90A910236E226C14 +:1000C000AD9080797C041A1008E36F0403B90988A5 +:1000D000C6BE6C04A910A090AD9080797C0401B9D3 +:1000E0000988C6BE7B048918226CA090AD90A91027 +:1000F000236E226CA090AD902D6908E39C0424012E +:1001000003B702B91888898B2C028A10047CA0904E +:100110002B691F88807E5B052A690988898BA099D5 +:100120008A10A0902B691F88807E5B052A69098848 +:10013000898BAF99997B840424010F061B1013202F +:100140001B90A0BFFF7F44E3AC041B90898B807A97 +:100150001A05276901BA2790807A2305276908E3E1 +:100160009E0480790F052406261013202690A0BF38 +:10017000FF7F04E3C0048D8B807A1A058079B40474 +:100180002690131026301B908D8B807A1A05807A6A +:100190002305271001BA279008E3B40424010F06B1 +:1001A000898B1A6908E3EA04196988E3E00403B952 +:1001B0000988C6BEDD04A01FAE2FA99880790F055F +:1001C00001B9188807B90988C6BEE704EE10A990DE +:1001D00080790F05196908E3FE0403B9098846BE52 +:1001E000C6BEFA04A0171EBEAE1FBFBF00FF13BEDF +:1001F000DFBF8080A99947BE80790F0501B90988C2 +:10020000C6BE0E05A016A026B7BF00FF1EBEA01ECC +:10021000AE2EBFBF00FF13BEDFBF8080A9990C8543 +:100220000F86076988E31605070D108559BE1E88DD +:100230004ABE00EF1E101C901F101D90A0101E90B3 +:10024000A0101F9000EF1E101C3020901B73205434 +:1002500003BE259825101C2025902573145403BE39 +:100260008E8B80982F6988E3390559BE07BB806162 +:100270008098A08B1F101D3021901B73215403BE4A +:100280002E982E101D202E902E73155403BE80988C +:100290002F6988E34F0559BE07BB80618098A08B0A +:1002A000186908EF2573165403BEA0982E731754CF +:1002B00003BEA09800EFA08BC6BE6B0559BE04BB61 +:1002C00090AA04BE1EBEE099E08BA069D090A06900 +:1002D000D0901F0805B81F88908BA069D090A069A6 +:1002E0009090D08BD88B1FBE00EF00000000000064 +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:020310000000EB +:00000001FF diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 1abbf87..32836ea 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -744,7 +744,6 @@ config SND_KORG1212 config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND - select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL select SND_AC97_CODEC help Say Y here to include support for soundcards based on ESS Maestro 3 @@ -753,15 +752,6 @@ config SND_MAESTRO3 To compile this driver as a module, choose M here: the module will be called snd-maestro3. -config SND_MAESTRO3_FIRMWARE_IN_KERNEL - bool "In-kernel firmware for Maestro3 driver" - depends on SND_MAESTRO3 - default y - help - Say Y here to include the static firmware built in the kernel - for the Maestro3 driver. If you choose N here, you need to - install the firmware files from the alsa-firmware package. - config SND_MIXART tristate "Digigram miXart" depends on SND diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 9dfba6e..b258297 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -58,10 +58,8 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," "{ESS,Allegro PCI}," "{ESS,Allegro-1 PCI}," "{ESS,Canyon3D-2/LE PCI}}"); -#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw"); MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw"); -#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -2101,161 +2099,6 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) } -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - -/* - * DSP Code images - */ - -static const u16 assp_kernel_image[] = { - 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, - 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, - 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, - 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, - 0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, - 0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, - 0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, - 0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, - 0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, - 0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, - 0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, - 0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, - 0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, - 0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, - 0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, - 0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, - 0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, - 0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, - 0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, - 0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, - 0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, - 0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, - 0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, - 0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, - 0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, - 0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, - 0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, - 0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, - 0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, - 0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, - 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, - 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, - 0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, - 0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, - 0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, - 0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, - 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, - 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, - 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, - 0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, - 0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, - 0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, - 0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, - 0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, - 0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, - 0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, - 0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, - 0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, - 0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, - 0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, - 0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, - 0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, - 0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, - 0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, - 0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, - 0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, - 0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, - 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, - 0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, - 0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, - 0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, - 0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, - 0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, - 0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, - 0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, - 0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, - 0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, - 0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, - 0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, - 0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, - 0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, - 0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, - 0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, - 0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, - 0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, - 0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, - 0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, - 0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, - 0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, - 0xBE3A, -}; - -/* - * Mini sample rate converter code image - * that is to be loaded at 0x400 on the DSP. - */ -static const u16 assp_minisrc_image[] = { - - 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, - 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, - 0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, - 0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, - 0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, - 0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, - 0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, - 0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, - 0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, - 0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, - 0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, - 0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, - 0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, - 0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, - 0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, - 0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, - 0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, - 0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, - 0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, - 0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, - 0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, - 0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, - 0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, - 0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, - 0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, - 0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, - 0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, - 0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, - 0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, - 0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, - 0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, - 0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; - -static const struct firmware assp_kernel = { - .data = (u8 *)assp_kernel_image, - .size = sizeof assp_kernel_image -}; -static const struct firmware assp_minisrc = { - .data = (u8 *)assp_minisrc_image, - .size = sizeof assp_minisrc_image -}; - -#ifdef __LITTLE_ENDIAN -static inline void snd_m3_convert_to_le(const struct firmware *fw) { } -#else -static void snd_m3_convert_to_le(const struct firmware *fw) -{ - int i; - u16 *data = (u16 *)fw->data; - - for (i = 0; i < fw->size / 2; ++i) - cpu_to_le16s(&data[i]); -} -#endif - -#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ - - /* * initialize ASSP */ @@ -2547,10 +2390,8 @@ static int snd_m3_free(struct snd_m3 *chip) if (chip->iobase) pci_release_regions(chip->pci); -#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL release_firmware(chip->assp_kernel_image); release_firmware(chip->assp_minisrc_image); -#endif pci_disable_device(chip->pci); kfree(chip); @@ -2740,27 +2581,19 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, return -ENOMEM; } -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - chip->assp_kernel_image = &assp_kernel; -#else err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); if (err < 0) { snd_m3_free(chip); return err; } -#endif -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - chip->assp_minisrc_image = &assp_minisrc; -#else err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); if (err < 0) { snd_m3_free(chip); return err; } -#endif if ((err = pci_request_regions(pci, card->driver)) < 0) { snd_m3_free(chip); @@ -2912,10 +2745,6 @@ static struct pci_driver driver = { static int __init alsa_card_m3_init(void) { -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - snd_m3_convert_to_le(&assp_kernel); - snd_m3_convert_to_le(&assp_minisrc); -#endif return pci_register_driver(&driver); } -- cgit v0.10.2 From 18ee6dfae89d9c131e3c9952939633ba8fa86247 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 15:07:34 +0300 Subject: firmware: convert ymfpci driver to use firmware loader exclusively Signed-off-by: David Woodhouse diff --git a/firmware/Makefile b/firmware/Makefile index f312ac0..a962fe9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -23,6 +23,8 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw +fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ + yamaha/ds1e_ctrl.fw fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index c08dbc8..ae40fb1 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -31,3 +31,16 @@ drops binary dsp code images on our heads, but we don't get to see specs on the dsp." -------------------------------------------------------------------------- + +Driver: ymfpci -- Yamaha YMF724/740/744/754 audio devices + +File: yamaha/ds1_ctrl.fw +File: yamaha/ds1_dsp.fw +File: yamaha/ds1e_ctrl.fw + +Licence: Unknown + +Found alsa-firmware package in hex form, with the following comment: + Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved. + +-------------------------------------------------------------------------- diff --git a/firmware/yamaha/ds1_ctrl.fw.ihex b/firmware/yamaha/ds1_ctrl.fw.ihex new file mode 100644 index 0000000..aa9b1d7 --- /dev/null +++ b/firmware/yamaha/ds1_ctrl.fw.ihex @@ -0,0 +1,769 @@ +:10000000070000000700240007000C0007001C0088 +:1000100007000600020070002000000040000300FE +:100020000471000086420000400003000D0F000034 +:10003000100800003A042000820200000D020000B7 +:10004000100800003A04200082120000820E2000F6 +:10005000821A00000D2D0300100800003A04100061 +:100060008DD30200100800003A0418000D010000B2 +:1000700015000200FD000000200000006088030061 +:100080006090030060800300408003004080030014 +:1000900040800300408001007D0A00004080030092 +:1000A000408003004080010002042000820800001C +:1000B0001A0008000409000086590100070000002A +:1000C000070026000700000007000000068A010064 +:1000D000070000008D0C0300100800003A0418000F +:1000E000070026007D080000428001000A1600007B +:1000F00006A20400070000008D2100001008000087 +:100100003A04080006C2210007000000FD070000B5 +:10011000428001000A0008000409000086930200E2 +:1001200095010000040D09000700000020080000F0 +:10013000F50000007D0B000060F00100FD000000F4 +:1001400006220300408001007D0A00004280030077 +:100150004A8013000A001800201800006090050073 +:100160006088050040800100FD0000004280010021 +:100170000A007000150100004411070086230300E7 +:100180000000030020700000064A030040800100C8 +:100190008D340000100800003A04080006EA21002F +:1001A000070000008DD30200100800003A04180078 +:1001B0000682010007000000070024008D0F0000E8 +:1001C000100800003A16000002240000025C000043 +:1001D000FD28000020000000408001000D00080004 +:1001E0001508000084095100070000004D000000C0 +:1001F0005D0E0000020E00008D410000100800009E +:100200003A040800068A2C00070000008D00000058 +:1002100024090000020F00008D45000010080000B6 +:100220003A040800068A2C00070000007D38000010 +:10023000428001000A000800151000008409010036 +:10024000868301000700000006AA010007000000E5 +:10025000FD080000428001000A0018000419000097 +:100260008680210007002800101800003A042800AA +:10027000020C28000D000000100800003A142800AD +:100280008D80080020080000FD0200004080010071 +:10029000070020000D02000004991800070000006C +:1002A0002D400000BD000000FD0200004280010062 +:1002B0000A00080004090000865A05000700000033 +:1002C00000010000200A00007D04000040800100C1 +:1002D000428001000A002000153000004421010086 +:1002E000864903000700000004210000864903003E +:1002F000070000008D0F0000100800003A0C2800D5 +:100300004439020086C906000700000010180000EA +:100310003A0428000D81080020080000FD020000BA +:100320004080010007002000102800003A007800FB +:100330008D680000100800003A040800068A2800B2 +:10034000070000000D40000015100000049918007F +:1003500004292900043939000700000006020600BC +:1003600007000000F50400007D00000020000000F0 +:100370008D00000060080100408001007D04000045 +:10038000428003004A8021000A001800441902003C +:1003900086582100070000007540000004F171003C +:1003A00007000000420001000A00280004290000A4 +:1003B00086202100070000000D3C000004A9300049 +:1003C000070000007D070000428001000A000800CD +:1003D0000409000086DA07007D05000020280000DF +:1003E00060B0030006F207004080010020300000EA +:1003F00060A8030040800100FD020000428001006F +:100400000A0008000409000086FA0700070000003F +:100410007D050000428001000A0428008D0E0000C6 +:10042000100800003A0C28000D0000001008000021 +:100430003A1428000D00090020080000FD02000009 +:100440004080010007002000FD3D0000200000006A +:10045000408001007D1000008D8D0000100800001C +:100460003A040800068A280007000000150800006A +:100470001A00080084090100865109007D1300005C +:1004800000052000200F2800608F3300608F3B00A4 +:10049000608F4300608F4B00608F5300608F5B0064 +:1004A000608A030040800100BD7F0000C43D380029 +:1004B000070000007D1A0000751300004280010053 +:1004C0004A0009000A001000048D0B000495130077 +:1004D00007000000200800006090010004110000E7 +:1004E0008620210040000100FD170000428001002D +:1004F0000A0008000409000086222100070000000D +:100500007D190000428003004A8009000A001000A3 +:100510002409000064160000FD1100004280030061 +:100520004A802B004A8019008D0000004489210078 +:10053000070000004422000086E10A0007000000D6 +:10054000641A0000242A00007D190000020108003E +:10055000220110002008000060900300408001008C +:10056000FD3D00008D0000002008000040800100DB +:10057000751300007D1A0000420001004A80090046 +:100580000A0010001D020000E4890100E492290025 +:1005900044913000070000000D060000150A00001D +:1005A0001D0C000025100000E4A90000E42B010050 +:1005B00064040000E4B30100E432020064040000BB +:1005C0006404000064040000640400000D040000E2 +:1005D000C4B108000700000020080000F50B00006F +:1005E000400003007D190000428003004A8009009A +:1005F000240A00000A000800640E0800070000003A +:1006000022011000200800006010030040000100DB +:10061000AC6400007D02000020000000408001006A +:100620007D10000042800100FD1100004A803B0067 +:100630004A8009000A0020009500000044111A00B9 +:1006400044A1000086200D000D04000084B90000C4 +:1006500086210D00FD18000042800100FD10000001 +:100660004A8009000A0028009500000024090100C2 +:10067000642A000086110D00070000000429000014 +:1006800086220D0007000000062A0D000200080067 +:100690008D0000007D38000020080000408001002F +:1006A0007D120000428001000A00100004390000A1 +:1006B00086D10D000D080000B5FF7F0084B9000051 +:1006C00086A10D0025000000067A0E002D00000016 +:1006D000150000002D0800008DC702002008000052 +:1006E00006C20E000D00000035807F0084B90000B6 +:1006F00086710E00250040008D00000044091100A5 +:10070000070000008D0100000495100007000000A4 +:10071000649100002404000024040000240400006C +:1007200002011000020028008DC60200200800000F +:1007300006C20E008D0100002D0400008D00000097 +:1007400004951000070000000D02000084911000C5 +:10075000070000000DC70200200800008D00000007 +:10076000FD38000040800100FD3B0000201000002B +:1007700060A80300150800008431310084212100A5 +:100780000700000060B0030060A00300408001008B +:10079000FD2200009500000024090100240400004F +:1007A0002404000064120000020110002008000070 +:1007B0006090030040800100241900008DFB0000C0 +:1007C0007D390000200800004080050042800300C1 +:1007D0004A840900060600000A04080024040000F8 +:1007E000240400007D110000428001000A0008007E +:1007F000240A000002052800020C28000D800900D0 +:1008000020080000FD0200004080010007002000D9 +:10081000FD220000428001000A000800950000004F +:10082000C40D2800241901007D1900004280010038 +:10083000FD1100004A8009000A001000B500000008 +:1008400044311100048D0A0007000000440A08002A +:100850000495120007000000FD2300002010000096 +:100860004080030044121000070000002008000030 +:100870006090030040800100FD0200004280010002 +:100880000A0008000409000086FA100007000000B2 +:10089000FD3B000000010000100A00007A800B0000 +:1008A0004A80130084090900070000009500000039 +:1008B000043D0100868011000A00100002001000B3 +:1008C0008409090007000000428003004A801100EB +:1008D000040D0900070000000A001000840D090043 +:1008E000070000007D250000200800004080010076 +:1008F0000D010000100800003A1428007D120000CD +:10090000428001000A0020007D19000042800100A1 +:100910007D1100004A8031000A00100024310000DF +:100920000D2801007D3900002008000040800500EE +:10093000428003004A840900060600000A040800F9 +:1009400002013000243100002404000024040000CF +:1009500024120000020528004C1A00008601130032 +:10096000020070002D000000000003007D38000030 +:10097000428001000A001000062A13002421000012 +:10098000AD000000020010000D010000240900006D +:10099000246B00008D3601007D3900002008000026 +:1009A00040800500428003004A84090006060000DA +:1009B0000A040800643200008D000000240A0000D0 +:1009C000201000007D220000408001000D3C01004D +:1009D000100800003A04080006D2290007000000B1 +:1009E000202800007D200000408001007D110000D3 +:1009F000428003004A8013000A8033007D380000E3 +:100A0000428001000A00080004090000863A16002E +:100A1000070000008D000000640903008D470100FD +:100A20007D3900002008000040800500428003005E +:100A30004A840900060600000A0408000201380082 +:100A4000240400002404000024120000FD02000021 +:100A5000428001000A0008000409000086A2140078 +:100A600007000000020528004C1A00008639160015 +:100A700007000000642103002C630000FD3D00001E +:100A8000428001000A0008009500000004090900E6 +:100A900007000000200800004C1A000086611500C5 +:100AA0004080010000000300067A150024210000A8 +:100AB0000D01000024090000246B00008D5B010083 +:100AC0007D390000200800004080050042800300BE +:100AD0004A840900060600000A040800643A00007F +:100AE0009500000024120000FD0200004280010079 +:100AF0000A0008000409000086DA1500070000005B +:100B00008D620100100800003A04080006D2290096 +:100B10000700000006D2140007000000207000004B +:100B20000A0108002A011000FD200000608803006F +:100B300060900300408001007D220000428001009F +:100B4000FD3D00000A0008004A843100040900004D +:100B500086D816008B0018008D000000049918003C +:100B60002C31000006AA1700070000004C320000DC +:100B700086331700070000000419000086301700B4 +:100B80000700000095000000449119002C2200008D +:100B9000243100006C6300003D0E0000751300005E +:100BA000FD0B0000420001004A8009000A0010000D +:100BB000EC8A0300EC9303004C22000086A9170086 +:100BC000070000008D000000049918006C2200004E +:100BD0002C3200000A053000AB1D300083200000DD +:100BE000FD180000428001000A000800248901006D +:100BF000020530008310000075180000420001005B +:100C00000A0010008D000000240901007513000087 +:100C100042053300CB0C3300CB2C3300CB343300F4 +:100C2000CB3C3300CB443300CB4C3300CB543300AC +:100C30008B5C300083600000F50200004200010080 +:100C40000A00080004090000867A18000700000066 +:100C50002D1E0000FD050000428001000A00080072 +:100C600024890200020528000D060000100800007B +:100C70003A0C28008D000000100800003A142800EB +:100C80008D800A0020080000F502000040000100ED +:100C90000700220075120000420003004A002100F4 +:100CA0008D00000044091A00070000000D980100A3 +:100CB000100800003A04080006222B00070000007C +:100CC000F5010000420003004A000D000A00100078 +:100CD00044910800070000002008000040000100C7 +:100CE000F525000044310A0007000000200800003C +:100CF00060280300400003007D21000042800300C3 +:100D00004A800B000A001000200800006010030059 +:100D1000400003008D000000240100002C010000B1 +:100D2000640E0000641A00006C6300000A010800F1 +:100D30002A0110002008000060100300400003009A +:100D4000FD200000428001000A0008007D22000012 +:100D5000428001000A00100020080000601003001B +:100D6000400003007D190000428001000A000800D5 +:100D7000FD220000428003000A001000200800004D +:100D80006010030040000300040D0900070000008C +:100D90002008000040000300428003004A800B004E +:100DA0000A0010002008000060100300400003004B +:100DB000428003004A8013004A801900040D11008C +:100DC000048D1900070000000A0008002010000030 +:100DD0006018030060080300400003008D0000005D +:100DE00044090B000700000020080000400001003B +:100DF000F5050000420003000A000800200800007A +:100E000040000100F5000000420001000A00080057 +:100E10000409000086601C00751E000042000300EB +:100E20004A0401000A0C000006721C0007000000C2 +:100E300002040000020C00007D170000F51A0000FB +:100E4000428001004A1403004A1C03004A240300A4 +:100E50004A2C03004A3403004A3C03004A4403007E +:100E60000A4C00003D040000F5130000FD1A0000CC +:100E7000420003004A000B004A801B004A80130016 +:100E80000A0020004491080044A11900E4890300ED +:100E9000EC990300025500000A5D000042000300C7 +:100EA0004A000B004A801B004A8013000A00200001 +:100EB0004491080044A11900E4890300EC9903005F +:100EC000026500000A6D0000420003004A000B00AA +:100ED0004A0019004A802B004A8013004A802100F2 +:100EE0000A0030004491080044A1190044B12A00CE +:100EF000E4890300EC990300027500000A7D0000FC +:100F0000E4A90300020700007D10000015040000A2 +:100F1000428001000A000800E4090100020F0000FD +:100F2000F52A0000FD190000420001004A80090076 +:100F30000A0010003409000074160000F5290000B2 +:100F4000420001000A0010007C91000075200000A2 +:100F5000420001000A0008000409000086D21E00B9 +:100F6000F5260000F5270000420003004A000900B2 +:100F70000A0010003C0A00007C160000751A0000F0 +:100F8000FD0B0000420001004A8051000A004800A9 +:100F90000700160075100000420001000A2C28000E +:100FA000121D280012252800321F000007001E0015 +:100FB00007000E007519000042000100F52D000029 +:100FC0004A000D000A0010004491000086B21F0084 +:100FD000420001000A3428005D0E00008D00000070 +:100FE000750300002008000040000100F4D2050055 +:100FF00004D154005C7300008653200007000000F9 +:1010000007000C000700080007000A000D0402009A +:10101000100800003A040800062233000700000010 +:10102000065A200007000000070008007522000093 +:10103000420001000A002000042100008620210057 +:101040002D1E0000F5020000420001000A00080009 +:101050000409000086922000070000001020000014 +:101060003A0430007D050000C38001000A0008003A +:101070002489020002052800020C28000D810A00C4 +:1010800020080000F50200004000010007002200D7 +:10109000FD040000428001000A007000000003000F +:1010A0002070000006FA0600408001000D180200C2 +:1010B000100800003A04080006222B000700000078 +:1010C000FD020000428001000A000800040900003F +:1010D000868A21000700000006F2010007000000D8 +:1010E00075080000FD0900000D010000060A22003D +:1010F00095020000750B00007D0900000D00000046 +:1011000015050000420001000A0018000419000043 +:1011100086782800F506000020100000400001003D +:10112000F5040000200800004000010075070000E1 +:10113000420001004A8009000A001000241100004A +:101140000409000086BA2200150800000201080008 +:101150000412100006DA22007505000004120800CF +:1011600007000000020110007505000025040000C2 +:10117000241102000201100020080000601003008A +:101180004000010024190000867828008D0000002E +:1011900064040000049D00008688270002011800F6 +:1011A00075050000420001000A0428008D010000BE +:1011B00024090000020D28000D0000002409000091 +:1011C000021528000D00100020080000F5020000A4 +:1011D000400001000700200075110000FD02000022 +:1011E000428001000A0008000409000086C22300B2 +:1011F0000700000000010000200B0800600B130036 +:10120000600B1B00600A0300400001004200050063 +:101210004A003D004A0035004A002D000A00200027 +:10122000F5060000420001000A142800F504000041 +:10123000420001000A00080015030000040D01002F +:1012400086CA24001540000095000000040D01002E +:1012500086B82400220010002A00100006E22400B4 +:10126000070000000431330004A92A000700000031 +:10127000242103000205280024110000240400009A +:1012800024040000243200002C2900006C630000BC +:1012900086F325000700000064B10200640400002A +:1012A000640400008D000000640A0000020D2800A4 +:1012B0008D00100020080000F50200004000010031 +:1012C000070022008D00000004B93800070000006C +:1012D0006C2903000A013000F50200004200010001 +:1012E0000A0008000409000086BA25000700000073 +:1012F0002C3102000A0528008D0000006C09010055 +:101300000A0D28000D01100020080000F502000061 +:101310004000010007002200241100002404000006 +:10132000240400002432000002013000442903009C +:10133000867A26000700000002003000F504000055 +:10134000420001000A00080015030000040D01001E +:1013500086C0260024310000640400000201300031 +:10136000F5020000420001000A0008000409000024 +:1013700086CA260007000000243100000205300064 +:10138000243900008305300083080000F5050000C3 +:10139000420001000A0428008D00000024810000A2 +:1013A000020D28008D000000248100000215280095 +:1013B0008D01100020080000F5020000400001002F +:1013C0000700220025100000750500004200030000 +:1013D0004A0009000A00100004090A000411120062 +:1013E0000700000020100000600805004000050014 +:1013F000FD060000428001004A0009000A001000BA +:10140000A500000004090A000411120007000000F2 +:10141000200800006090010040000100F50200007B +:10142000420001000A00080004090000864228006A +:1014300007000000060A230007000000060600005F +:1014400007000000F5020000420001000A00080049 +:101450000409000086922800070000000001000037 +:10146000200B0800608B1300608B1B00608B230037 +:10147000608B2B00608B3300608B3B00608B4300E4 +:10148000608B4B00608B5300608B5B00608B630054 +:10149000608B6B00608B7300608B7B00608F030040 +:1014A000608F0B00608F1300608F1B00608F230024 +:1014B000608F2B00608F3300608F3B00608F430094 +:1014C000608F4B00608F5300608F5B00608F630004 +:1014D000608F6B00608F7300608F7B00608A0300F9 +:1014E00006060000408001008D000000640A000034 +:1014F000020D2800240A00007D0200004280010045 +:101500000A00100024120000FD03000042800100C8 +:101510000A0008000409000086822A000700000073 +:101520008D010000240A000064040000640400002F +:101530000201080024090000240400002404000023 +:10154000020110000D0002004491000086D92A001B +:1015500007000000FD010000428001000A000800B1 +:10156000440A000086BB2A00428001000D000A00E8 +:1015700020080000FD02000040800100070020005C +:101580007D020000201000000606000040800100DF +:10159000F5020000420001000A00080004090000F2 +:1015A000862A2B00070000007D0300004280010016 +:1015B0000A00080004090000865A2B0007000000FA +:1015C000750000007D2E0000420001004A800B00E3 +:1015D0002000000004090000860600004000010011 +:1015E0004A8431008B043000830800008D00000025 +:1015F000100800003A1428008D00000010080000B8 +:101600003A0C280075060000420001000A0008009C +:101610001538000024090100020528000D000B0008 +:1016200020080000F502000040000100060600004E +:1016300007002200640400006404000006060000A5 +:1016400007000000340100008D7F00003C0900000D +:10165000121D280012252800321F000007000E006E +:101660000D0100007D030000200800004080010003 +:10167000F4D2050007000000070008007D03000009 +:10168000428001000A0008000409000086022D00C3 +:101690000700000006060000070000000700000029 +:1016A0001200000007001000070032000700600071 +:1016B000800010001A0048000449000086612D00D7 +:1016C00007000000101200003A0058004501000019 +:1016D000045D5C0007000000800000001A00480064 +:1016E0000449000086B12D00070000001012000020 +:1016F0003A0050000459000086082E004500000002 +:10170000C5000000F5FF7F007DFF7F0024D50700A6 +:101710002442000002015000020520008200000067 +:101720001A0040000441000086392E000700000026 +:10173000653800001A004000204000004D100000F5 +:1017400084C10400861B3000400000000700040034 +:10175000650100004501000020400000400000003D +:1017600065070000800008001A00400004410000E6 +:1017700086C92E0007000000101200003A00400049 +:101780000441000086222F004D000000CD00000023 +:10179000104800003A042000820800001A004000AF +:1017A0000441000086312F0007000000204800009F +:1017B000045900008608300040000000E5070000E2 +:1017C00080042000A0162800E0163200E0163A003F +:1017D000E0164200601202004000000032000000EB +:1017E000750040007D00000074D507001205200040 +:1017F000820000001A0040000441000086E12F0032 +:1018000007000000067203000700640007000600DE +:10181000E50000002000000040000000650A000014 +:1018200020000000400002004000020040000000D4 +:1018300065010000420000000A0070000471000011 +:1018400086A2300007000000068201000700640045 +:101850000000050020700000400000000672030038 +:1018600007006400070000006D300000608802007F +:10187000609002000A0008006088020040800000BA +:10188000120010000D10000084910000864131000C +:101890000D0E000084910000865132000700000008 +:1018A00007003000201000006D3B00004080000069 +:1018B000800000001A000800040900008661310061 +:1018C0000700000020120000ED0D00004080000025 +:1018D000428000000A0010000D00400044951000F6 +:1018E0000700000020100000ED0D00004080000007 +:1018F000428000000A042000820000001A00080054 +:101900000409000086F13100070000006D3B000073 +:10191000428000000A000800150E00008409010042 +:10192000869B3200070060001A000800150C0000BA +:1019300084090100868332002000000007001A009D +:10194000ED02000040800000070062006D300000E2 +:10195000428002004A800A00200800004A800A00F3 +:10196000060600004A80100007000000122528002B +:10197000321F0000F4D2050004D154005C73000053 +:10198000860700000700000007000C0007000A009F +:1019900007001C00653400004000020020480000E1 +:1019A000605002000A004000604002004000000059 +:1019B000444945000700000020400000E53A0000CF +:1019C00040000000E5280000420000000A00480036 +:1019D0000449000086683800652C000042000000C1 +:1019E0000A004000D5000000044145000700000047 +:1019F000550600000445050086F23400D5010000BC +:101A00000445050086F03400652B0000420000000C +:101A1000E53A00004A0050000A004000D4C34500E7 +:101A2000070000000445450007000000CD0000004D +:101A30004449440007000000044545000700000039 +:101A40004D010000444955000700000044510400C6 +:101A500086E93400652C0000420000000A004800BE +:101A600004D14C000700000044C1040086F3340098 +:101A70000700000007001600E52C000042000400EB +:101A80000A004000204000004000000065290000DE +:101A9000420000000A00400004410000866035005A +:101AA000070000000224000006A23600025C0000CD +:101AB000E5250000420000000A00400074420000DA +:101AC000E52A0000420000000A00400074420000C5 +:101AD00012015000E5290000420000000A00400009 +:101AE000344200000441450007000000204000008F +:101AF00040000000E53E0000200000004000000023 +:101B0000E52D0000520140000A005000445104003D +:101B1000864A3600C5000000E53E00002040000077 +:101B200040000000E52B0000420000000A004000D9 +:101B30005442400007000000E52A00002040000059 +:101B400040000000320150003401040074560000CF +:101B5000E5290000420002000A00420042000000A5 +:101B60000A0050007C410500E5280000420000000A +:101B70000A004800C500000044C14C008610370030 +:101B8000E5260000E5270000420002004A00400070 +:101B90000A0050003C4200007C560000E52800008E +:101BA0002048000040000000121D280012252800D7 +:101BB000721F000065290000420000000A0040007A +:101BC0000441000086AA370007000E000700160037 +:101BD00007001E00E53E0000420000000A00400031 +:101BE0000441000086E83700652D00004200000037 +:101BF0000A34280065340000420002004A00420016 +:101C0000204000004A004A004A005000F4D205007B +:101C100004D154005C7300008651380007000000B6 +:101C2000060600000700080007000C000700080077 +:101C300007000A00E5010000450002002040000006 +:101C4000600000006503000040000000652E0000F9 +:101C5000201A0000601A0A004000000065340000ED +:101C6000420002004A004200204000004A004A00B0 +:101C7000060600004A0050000000000000000000BE +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:1020000000000000000000000000000000000000D0 +:1020100000000000000000000000000000000000C0 +:1020200000000000000000000000000000000000B0 +:1020300000000000000000000000000000000000A0 +:102040000000000000000000000000000000000090 +:102050000000000000000000000000000000000080 +:102060000000000000000000000000000000000070 +:102070000000000000000000000000000000000060 +:102080000000000000000000000000000000000050 +:102090000000000000000000000000000000000040 +:1020A0000000000000000000000000000000000030 +:1020B0000000000000000000000000000000000020 +:1020C0000000000000000000000000000000000010 +:1020D0000000000000000000000000000000000000 +:1020E00000000000000000000000000000000000F0 +:1020F00000000000000000000000000000000000E0 +:1021000000000000000000000000000000000000CF +:1021100000000000000000000000000000000000BF +:1021200000000000000000000000000000000000AF +:10213000000000000000000000000000000000009F +:10214000000000000000000000000000000000008F +:10215000000000000000000000000000000000007F +:10216000000000000000000000000000000000006F +:10217000000000000000000000000000000000005F +:10218000000000000000000000000000000000004F +:10219000000000000000000000000000000000003F +:1021A000000000000000000000000000000000002F +:1021B000000000000000000000000000000000001F +:1021C000000000000000000000000000000000000F +:1021D00000000000000000000000000000000000FF +:1021E00000000000000000000000000000000000EF +:1021F00000000000000000000000000000000000DF +:1022000000000000000000000000000000000000CE +:1022100000000000000000000000000000000000BE +:1022200000000000000000000000000000000000AE +:10223000000000000000000000000000000000009E +:10224000000000000000000000000000000000008E +:10225000000000000000000000000000000000007E +:10226000000000000000000000000000000000006E +:10227000000000000000000000000000000000005E +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000000000000000DE +:1023000000000000000000000000000000000000CD +:1023100000000000000000000000000000000000BD +:1023200000000000000000000000000000000000AD +:10233000000000000000000000000000000000009D +:10234000000000000000000000000000000000008D +:10235000000000000000000000000000000000007D +:10236000000000000000000000000000000000006D +:10237000000000000000000000000000000000005D +:10238000000000000000000000000000000000004D +:10239000000000000000000000000000000000003D +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D00000000000000000000000000000000000FD +:1023E00000000000000000000000000000000000ED +:1023F00000000000000000000000000000000000DD +:1024000000000000000000000000000000000000CC +:1024100000000000000000000000000000000000BC +:1024200000000000000000000000000000000000AC +:10243000000000000000000000000000000000009C +:10244000000000000000000000000000000000008C +:10245000000000000000000000000000000000007C +:10246000000000000000000000000000000000006C +:10247000000000000000000000000000000000005C +:10248000000000000000000000000000000000004C +:10249000000000000000000000000000000000003C +:1024A000000000000000000000000000000000002C +:1024B000000000000000000000000000000000001C +:1024C000000000000000000000000000000000000C +:1024D00000000000000000000000000000000000FC +:1024E00000000000000000000000000000000000EC +:1024F00000000000000000000000000000000000DC +:1025000000000000000000000000000000000000CB +:1025100000000000000000000000000000000000BB +:1025200000000000000000000000000000000000AB +:10253000000000000000000000000000000000009B +:10254000000000000000000000000000000000008B +:10255000000000000000000000000000000000007B +:10256000000000000000000000000000000000006B +:10257000000000000000000000000000000000005B +:10258000000000000000000000000000000000004B +:10259000000000000000000000000000000000003B +:1025A000000000000000000000000000000000002B +:1025B000000000000000000000000000000000001B +:1025C000000000000000000000000000000000000B +:1025D00000000000000000000000000000000000FB +:1025E00000000000000000000000000000000000EB +:1025F00000000000000000000000000000000000DB +:1026000000000000000000000000000000000000CA +:1026100000000000000000000000000000000000BA +:1026200000000000000000000000000000000000AA +:10263000000000000000000000000000000000009A +:10264000000000000000000000000000000000008A +:10265000000000000000000000000000000000007A +:10266000000000000000000000000000000000006A +:10267000000000000000000000000000000000005A +:10268000000000000000000000000000000000004A +:10269000000000000000000000000000000000003A +:1026A000000000000000000000000000000000002A +:1026B000000000000000000000000000000000001A +:1026C000000000000000000000000000000000000A +:1026D00000000000000000000000000000000000FA +:1026E00000000000000000000000000000000000EA +:1026F00000000000000000000000000000000000DA +:1027000000000000000000000000000000000000C9 +:1027100000000000000000000000000000000000B9 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:102860000000000000000000000000000000000068 +:102870000000000000000000000000000000000058 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A000000000000000000000000000000000000C6 +:102A100000000000000000000000000000000000B6 +:102A200000000000000000000000000000000000A6 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50000000000000000000000000000000000076 +:102A60000000000000000000000000000000000066 +:102A70000000000000000000000000000000000056 +:102A80000000000000000000000000000000000046 +:102A90000000000000000000000000000000000036 +:102AA0000000000000000000000000000000000026 +:102AB0000000000000000000000000000000000016 +:102AC0000000000000000000000000000000000006 +:102AD00000000000000000000000000000000000F6 +:102AE00000000000000000000000000000000000E6 +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B200000000000000000000000000000000000A5 +:102B30000000000000000000000000000000000095 +:102B40000000000000000000000000000000000085 +:102B50000000000000000000000000000000000075 +:102B60000000000000000000000000000000000065 +:102B70000000000000000000000000000000000055 +:102B80000000000000000000000000000000000045 +:102B90000000000000000000000000000000000035 +:102BA0000000000000000000000000000000000025 +:102BB0000000000000000000000000000000000015 +:102BC0000000000000000000000000000000000005 +:102BD00000000000000000000000000000000000F5 +:102BE00000000000000000000000000000000000E5 +:102BF00000000000000000000000000000000000D5 +:102C000000000000000000000000000000000000C4 +:102C100000000000000000000000000000000000B4 +:102C200000000000000000000000000000000000A4 +:102C30000000000000000000000000000000000094 +:102C40000000000000000000000000000000000084 +:102C50000000000000000000000000000000000074 +:102C60000000000000000000000000000000000064 +:102C70000000000000000000000000000000000054 +:102C80000000000000000000000000000000000044 +:102C90000000000000000000000000000000000034 +:102CA0000000000000000000000000000000000024 +:102CB0000000000000000000000000000000000014 +:102CC0000000000000000000000000000000000004 +:102CD00000000000000000000000000000000000F4 +:102CE00000000000000000000000000000000000E4 +:102CF00000000000000000000000000000000000D4 +:102D000000000000000000000000000000000000C3 +:102D100000000000000000000000000000000000B3 +:102D200000000000000000000000000000000000A3 +:102D30000000000000000000000000000000000093 +:102D40000000000000000000000000000000000083 +:102D50000000000000000000000000000000000073 +:102D60000000000000000000000000000000000063 +:102D70000000000000000000000000000000000053 +:102D80000000000000000000000000000000000043 +:102D90000000000000000000000000000000000033 +:102DA0000000000000000000000000000000000023 +:102DB0000000000000000000000000000000000013 +:102DC0000000000000000000000000000000000003 +:102DD00000000000000000000000000000000000F3 +:102DE00000000000000000000000000000000000E3 +:102DF00000000000000000000000000000000000D3 +:102E000000000000000000000000000000000000C2 +:102E100000000000000000000000000000000000B2 +:102E200000000000000000000000000000000000A2 +:102E30000000000000000000000000000000000092 +:102E40000000000000000000000000000000000082 +:102E50000000000000000000000000000000000072 +:102E60000000000000000000000000000000000062 +:102E70000000000000000000000000000000000052 +:102E80000000000000000000000000000000000042 +:102E90000000000000000000000000000000000032 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000000000000000000000000000000F2 +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F000000000000000000000000000000000000C1 +:102F100000000000000000000000000000000000B1 +:102F200000000000000000000000000000000000A1 +:102F30000000000000000000000000000000000091 +:102F40000000000000000000000000000000000081 +:102F50000000000000000000000000000000000071 +:102F60000000000000000000000000000000000061 +:102F70000000000000000000000000000000000051 +:102F80000000000000000000000000000000000041 +:102F90000000000000000000000000000000000031 +:102FA0000000000000000000000000000000000021 +:102FB0000000000000000000000000000000000011 +:102FC0000000000000000000000000000000000001 +:102FD00000000000000000000000000000000000F1 +:102FE00000000000000000000000000000000000E1 +:102FF00000000000000000000000000000000000D1 +:00000001FF diff --git a/firmware/yamaha/ds1_dsp.fw.ihex b/firmware/yamaha/ds1_dsp.fw.ihex new file mode 100644 index 0000000..acb0ba4 --- /dev/null +++ b/firmware/yamaha/ds1_dsp.fw.ihex @@ -0,0 +1,9 @@ +:1000000081000000A40100000A0000002F00000091 +:1000100053020800170380017B4000003F8400006A +:100020003C4801003C9401003CD805003C1C000009 +:100030007BC000003F0C05003C5021010000000087 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:00000001FF diff --git a/firmware/yamaha/ds1e_ctrl.fw.ihex b/firmware/yamaha/ds1e_ctrl.fw.ihex new file mode 100644 index 0000000..597f429 --- /dev/null +++ b/firmware/yamaha/ds1e_ctrl.fw.ihex @@ -0,0 +1,769 @@ +:10000000070000000700240007000C0007001C0088 +:1000100007000600020070002000000040000300FE +:100020000471000086420000400003000D0F000034 +:10003000100800003A042000820200000D020000B7 +:10004000100800003A04200082120000820E2000F6 +:100050000D800000100800003A042000821A000001 +:100060000D460300100800003A0410000DEC0200D9 +:10007000100800003A0418000D01000015000200ED +:10008000FD00000020000000608803006090030075 +:100090006080030040800300408003004080030034 +:1000A000408001007D0A0000408003004080030082 +:1000B0004080010002042000820800001A000800AD +:1000C00004090000867101000700000007002600F7 +:1000D00007004000070000008D2503001008000005 +:1000E0003A04180007002600024428007D0800009A +:1000F000428001000A16000006A205000700000069 +:10010000070044000D230000100800003A04080016 +:1001100006FA220007000000FD07000042800100EF +:100120000A0008000409000086AB020095010000E7 +:10013000040D09000700000020080000F500000081 +:100140007D0B000060F00100FD000000063A030096 +:10015000408001007D0A0000428003004A801300B5 +:100160000A00180020180000609005006088050053 +:1001700040800100FD000000428001000A00700084 +:100180001501000044110700863B03000000030036 +:100190002070000006620300408001000D36000060 +:1001A000100800003A04080006222300070000009F +:1001B0000DEC0200100800003A041800069A010035 +:1001C00007000000070024008D0F00001008000049 +:1001D0003A16000002240000025C0000FD28000026 +:1001E00020000000408001000D00080015080000FC +:1001F00084095100070000004D0000005D0E000062 +:10020000020E00000D430000100800003A04080030 +:1002100006122E00070000008D00000024090000D7 +:10022000020F00000D470000100800003A0408000B +:1002300006122E0007000000800448001012000083 +:100240003A0428008D770000100800003A0C2800BE +:100250008D060000100800003A142800024428000F +:100260008D250300100800003A0418008DFF0700D8 +:1002700020080000FD020000408001000700260069 +:1002800007002000FD020000428001000A00080073 +:100290000409000086120500070000000700240082 +:1002A0000DEC0200100800003A0418007D38000030 +:1002B000428001000A0008001510000084090100B6 +:1002C000869B01000700000006B201000700000045 +:1002D000FD080000428001000A0018000419000017 +:1002E00086B8220007002800101800003A042800F1 +:1002F000020C28000D000000100800003A1428002D +:100300008D80080020080000FD02000040800100F0 +:10031000070020000D0200000499180007000000EB +:100320002D400000BD000000FD02000042800100E1 +:100330000A00080004090000865A060007000000B1 +:1003400000010000200A00007D0400004080010040 +:10035000428001000A002000153000004421010005 +:10036000866103000700000004210000866103008D +:10037000070000008D0F0000100800003A0C280054 +:100380004439020086C90700070000001018000069 +:100390003A0428000D81080020080000FD0200003A +:1003A0004080010007002000102800003A0078007B +:1003B0008D780000100800003A04080006122A0098 +:1003C000070000000D4000001510000004991800FF +:1003D000042929000439390007000000060207003B +:1003E00007000000F50400007D0000002000000070 +:1003F0008D00000060080100408001007D040000C5 +:10040000428003004A8021000A00180044190200BB +:1004100086902200070000007540000004F1710082 +:1004200007000000420001000A0028000429000023 +:1004300086582200070000000D3C000004A930008F +:10044000070000007D070000428001000A0008004C +:100450000409000086DA08007D050000202800005D +:1004600060B0030006F20800408001002030000068 +:1004700060A8030040800100FD02000042800100EE +:100480000A0008000409000086FA080007000000BE +:100490007D050000428001000A0428008D0E000046 +:1004A000100800003A0C28000D00000010080000A1 +:1004B0003A1428000D00090020080000FD02000089 +:1004C0004080010007002000FD3D000020000000EA +:1004D000408001007D1000008D9D0000100800008C +:1004E0003A04080006122A00070000001508000060 +:1004F0001A0008008409010086510A007D130000DB +:1005000000052000200F2800608F3300608F3B0023 +:10051000608F4300608F4B00608F5300608F5B00E3 +:10052000608A0300408001007D10000042800100CD +:100530000A000800150200008409010086813A00C3 +:1005400007000000BD7F0000C43D38000700000028 +:100550007D1A000075130000428001004A00090066 +:100560000A001000048D0B00049513000700000022 +:10057000200800006090010004110000865822004D +:1005800040000100FD170000428001000A00080041 +:1005900004090000865A2200070000007D190000AF +:1005A000428003004A8009000A001000240900006C +:1005B00064160000FD110000428003004A802B00F9 +:1005C0004A8019008D0000004489210007000000C6 +:1005D0004422000086190C0007000000641A000085 +:1005E000242A00007D1900000201080022011000E9 +:1005F000200800006090030040800100FD3D0000E5 +:100600008D000000200800004080010075130000EC +:100610007D1A0000420001004A8009000A00100013 +:100620001D020000E4890100E49229004491300099 +:10063000070000000D060000150A00001D0C000058 +:1006400025100000E4A90000E42B01006404000070 +:10065000E4B30100E432020064040000640400001A +:1006600064040000640400000D040000C4B108002C +:100670000700000020080000F50B00004000030008 +:100680007D190000428003004A800900240A00000E +:100690000A000800640E0800070000002201100094 +:1006A000200800006010030040000100AC6400005E +:1006B0007D02000020000000408001007D1000004D +:1006C00042800100FD1100004A803B004A80090081 +:1006D0000A0020009500000044111A0044A1000007 +:1006E00086580E000D04000084B9000086590E00E3 +:1006F000FD18000042800100FD1000004A80090042 +:100700000A0028009500000024090100642A000066 +:1007100086490E000700000004290000865A0E00DA +:100720000700000006620E00020008008D000000B5 +:100730007D38000020080000408001007D1200008C +:10074000428001000A0010000439000086090F00F1 +:100750000D080000B5FF7F0084B9000086D90E00A7 +:100760002500000006B20F002D000000150000005B +:100770002D0800000DE002002008000006FA0F001E +:100780000D00000035807F0084B9000086A90F00AD +:10079000250040008D000000440911000700000002 +:1007A0008D01000004951000070000006491000016 +:1007B00024040000240400002404000002011000AE +:1007C000020028000DDF02002008000006FA0F00DA +:1007D0008D0100002D0400008D0000000495100024 +:1007E000070000000D0200008491100007000000C7 +:1007F0008DDF0200200800008D000000FD380000A1 +:1008000040800100FD3B00002010000060A80300B4 +:100810001508000084313100842121000700000008 +:1008200060B0030060A0030040800100FD220000D2 +:1008300095000000240901002404000024040000A5 +:100840006412000002011000200800006090030004 +:1008500040800100241900000D0F01007D390000C7 +:100860002008000040800500428003004A840900FF +:10087000060600000A040800240400002404000006 +:100880007D110000428001000A000800240A0000D7 +:1008900002052800020C28000D8009002008000035 +:1008A000FD0200004080010007002000FD22000042 +:1008B000428001000A00080095000000C40D2800D5 +:1008C000241901007D19000042800100FD11000083 +:1008D0004A8009000A001000B500000044311100F0 +:1008E000048D0A0007000000440A08000495120065 +:1008F00007000000FD2300002010000040800300DE +:10090000441210000700000020080000609003005F +:1009100040800100FD020000428001000A00080042 +:10092000040900008632120007000000FD3B0000B1 +:1009300000010000100A00007A800B004A801300BA +:10094000840909000700000095000000043D010033 +:1009500086B812000A001000020010008409090085 +:1009600007000000428003004A801100040D0900C6 +:10097000070000000A001000840D090007000000B5 +:100980007D25000020080000408001000D010000CE +:10099000100800003A1428007D1200004280010077 +:1009A0000A0020007D190000428001007D11000036 +:1009B0004A8031000A001000243100008D3B010004 +:1009C0007D390000200800004080050042800300BF +:1009D0004A840900060600000A04080002013000EB +:1009E000243100002404000024040000241200002C +:1009F000020528004C1A000086391400020070001D +:100A00002D000000000003007D380000428001003E +:100A10000A0010000662140024210000AD0000004E +:100A2000020010000D01000024090000246B0000EA +:100A30000D4A01007D3900002008000040800500BB +:100A4000428003004A840900060600000A040800E8 +:100A5000643200008D000000240A00002010000015 +:100A60007D220000408001008D4F01001008000031 +:100A70003A040800065A2B00070000002028000056 +:100A80007D200000408001007D11000042800300B5 +:100A90004A8013000A8033007D3800004280010044 +:100AA0000A00080004090000867217000700000011 +:100AB0008D000000640903000D5B01007D3900001A +:100AC0002008000040800500428003004A8409009D +:100AD000060600000A040800020138002404000091 +:100AE0002404000024120000FD02000042800100E6 +:100AF0000A0008000409000086DA1500070000005B +:100B0000020528004C1A000086711700070000003B +:100B1000642103002C630000FD3D000042800100C1 +:100B20000A00080095000000040909000700000001 +:100B3000200800004C1A0000869916004080010031 +:100B40000000030006B21600242100000D01000081 +:100B500024090000246B00000D6F01007D390000A6 +:100B60002008000040800500428003004A840900FC +:100B7000060600000A040800643A00009500000020 +:100B800024120000FD020000428001000A0008005B +:100B90000409000086121700070000000D7601000E +:100BA000100800003A040800065A2B000700000055 +:100BB000060A160007000000207000000A01080065 +:100BC0002A011000FD2000006088030060900300EF +:100BD000408001007D22000042800100FD3D0000B8 +:100BE0000A0008004A843100040900008610180039 +:100BF0008B0018008D000000049918002C310000B3 +:100C000006E21800070000004C320000866B180056 +:100C100007000000041900008668180007000000A3 +:100C200095000000449119002C220000243100009E +:100C30006C6300003D0E000075130000FD0B00000A +:100C4000420001004A8009000A001000EC8A0300FB +:100C5000EC9303004C22000086E11800070000001E +:100C60008D000000049918006C2200002C32000056 +:100C70000A053000AB1D300083200000FD18000085 +:100C8000428001000A0008002489010002053000AA +:100C90008310000075180000420001000A001000D7 +:100CA0008D00000024090100751300004205330087 +:100CB000CB0C3300CB2C3300CB343300CB3C330094 +:100CC000CB443300CB4C3300CB5433008B5C30002F +:100CD00083600000F5020000420001000A000800E5 +:100CE0000409000086B21900070000002D1E000054 +:100CF000FD050000428001000A000800248902006E +:100D0000020528000D060000100800003A0C28001B +:100D10008D000000100800003A1428008D800A00A1 +:100D200020080000F502000040000100070022003A +:100D300075120000420003004A0021008D000000EF +:100D400044091A00070000008DAB010010080000E4 +:100D50003A04080006AA2C0007000000F501000074 +:100D6000420003004A000D000A00100044910800F0 +:100D7000070000002008000040000100F5250000E9 +:100D800044310A000700000020080000602803002A +:100D9000400003007D210000428003004A800B00D8 +:100DA0000A0010002008000060100300400003004B +:100DB0008D000000240100002C010000640E0000E2 +:100DC000641A00006C6300000A0108002A01100088 +:100DD000200800006010030040000300FD20000018 +:100DE000428001000A0008007D22000042800100CC +:100DF0000A001000200800006010030040000300FB +:100E00007D190000428001000A000800FD22000058 +:100E1000428003000A001000200800006010030058 +:100E200040000300040D0900070000002008000036 +:100E300040000300428003004A800B000A001000BB +:100E400020080000601003004000030042800300FF +:100E50004A8013004A801900040D1100048D190006 +:100E6000070000000A0008002010000060180300BE +:100E700060080300400003008D00000044090B00DF +:100E8000070000002008000040000100F5050000F8 +:100E9000420003000A000800200800004000010092 +:100EA000F5000000420001000A00080004090000EB +:100EB00086981D00751E0000420003004A040100D0 +:100EC0000A0C000006AA1D00070000000204000032 +:100ED000020C00007D170000F51A0000428001009E +:100EE0004A1403004A1C03004A2403004A2C03004E +:100EF0004A3403004A3C03004A4403000A4C000001 +:100F00003D040000F5130000FD1A0000420003003C +:100F10004A000B004A801B004A8013000A00200090 +:100F20004491080044A11900E4890300EC990300EE +:100F3000025500000A5D0000420003004A000B0059 +:100F40004A801B004A8013000A00200044910800D8 +:100F500044A11900E4890300EC9903000265000034 +:100F60000A6D0000420003004A000B004A0019000D +:100F70004A802B004A8013004A8021000A0030007A +:100F80004491080044A1190044B12A00E4890300F7 +:100F9000EC990300027500000A7D0000E4A903003B +:100FA000020700007D1000001504000042800100CF +:100FB0000A000800E4090100020F0000F52A000001 +:100FC000FD190000420001004A8009000A001000DB +:100FD0003409000074160000F529000042000100E9 +:100FE0000A0010007C910000752000004200010002 +:100FF0000A00080004090000860A2000F526000007 +:10100000F5270000420003004A0009000A00100012 +:101010003C0A00007C160000751A0000FD0B000061 +:10102000420001004A8051000A00480007001600F3 +:1010300075100000420001000A2C2800121D280033 +:1010400012252800321F000007001E0007000E00B6 +:101050007519000042000100F52D00004A000D0046 +:101060000A0010004491000086EA200042000100BE +:101070000A3428005D0E00008D000000750300009A +:101080002008000040000100F4D2050004D1540003 +:101090005C730000868B21000700000007000C0035 +:1010A0000700080007000A008D1702001008000062 +:1010B0003A04080006B2340007000000069221003E +:1010C0000700000007000800752200004200010030 +:1010D0000A00200004210000865822002D1E000076 +:1010E000F5020000420001000A00080004090000A7 +:1010F00086CA210007000000102000003A043000DA +:101100007D050000C38001000A0008002489020058 +:1011100002052800020C28000D810A0020080000AA +:10112000F50200004000010007002200FD0400005D +:10113000428001000A0070000000030020700000DF +:1011400006FA0700408001008D2B02001008000005 +:101150003A04080006AA2C0007000000FD02000067 +:10116000428001000A0008000409000086C2220033 +:1011700007000000060202000700000075080000DA +:10118000FD0900000D010000064223009502000049 +:10119000750B00007D0900000D0000001505000022 +:1011A000420001000A0018000419000086002A000D +:1011B000F50600002010000040000100F5040000CA +:1011C00020080000400001007507000042000100F7 +:1011D0004A8009000A0010002411000004090000E0 +:1011E00086F2230015080000020108000412100016 +:1011F0000612240075050000041208000700000014 +:1012000002011000750500002504000024110200F1 +:1012100002011000200800006010030040000100DF +:101220002419000086002A008D00000064040000DC +:10123000049D0000861029000201180075050000B9 +:10124000420001000A0428008D010000240900006A +:10125000020D28000D0000002409000002152800DE +:101260000D00100020080000F50200004000010001 +:101270000700200075110000FD02000042800100FF +:101280000A0008000409000086FA24000700000094 +:1012900000010000200B0800600B1300600B1B0016 +:1012A000600A030040000100420005004A003D00C2 +:1012B0004A0035004A002D000A002000F506000013 +:1012C000420001000A142800F50400004200010059 +:1012D0000A00080015030000040D01008602260024 +:1012E0001540000095000000040D010086F0250067 +:1012F000220010002A001000061A26000700000035 +:101300000431330004A92A0007000000242103004F +:1013100002052800024428002411000002014000B8 +:101320002404000024040000243200002C290000C2 +:101330006C630000867327000700000064B10200A0 +:1013400064040000640400008D000000640A0000D2 +:10135000020D28008D00100020080000F50200009A +:1013600040000100070022008D00000004B9380091 +:10137000070000006C2903000A013000F50200009C +:10138000420001000A00080004090000860227004C +:10139000070000002C2100000A0528006C31000025 +:1013A0006C0400006C0400000A45280024110000B1 +:1013B000646B0000020110008D0000006C09010048 +:1013C0000A0D28000D01100020080000F5020000A1 +:1013D0004000010007002200244100002404000016 +:1013E00024040000243200000201300044290300DC +:1013F00086FA27000700000002003000F504000014 +:10140000420001000A00080015030000040D01005D +:1014100086402800243100006404000002013000EE +:10142000F5020000420001000A0008000409000063 +:10143000864A2800070000000244280024310000EA +:1014400002053000243900008305300083080000C5 +:10145000F5050000420001000A0428008D0000008C +:1014600024810000020D28008D000000248100006E +:10147000021528008D01100020080000F502000070 +:101480004000010007002200251000007505000043 +:10149000420003004A0009000A00100004090A0083 +:1014A0000411120007000000201000006008050071 +:1014B00040000500FD060000428001004A000900CE +:1014C0000A001000A500000004090A00041112001F +:1014D00007000000200800006090010040000100AB +:1014E000F5020000420001000A00080004090000A3 +:1014F00086CA2900070000000642240007000000F9 +:101500000606000007000000F5020000420001008E +:101510000A00080004090000861A2A0007000000DB +:1015200000010000200B0800608B1300608B1B0083 +:10153000608B2300608B2B00608B3300608B3B0043 +:10154000608B4300608B4B00608B5300608B5B00B3 +:10155000608B6300608B6B00608B7300608B7B0023 +:10156000608F0300608F0B00608F1300608F1B0083 +:10157000608F2300608F2B00608F3300608F3B00F3 +:10158000608F4300608F4B00608F5300608F5B0063 +:10159000608F6300608F6B00608F7300608F7B00D3 +:1015A000608A030006060000408001008D000000F4 +:1015B000640A0000020D2800240A00007D020000D9 +:1015C000428001000A00100024120000FD03000008 +:1015D000428001000A00080004090000860A2C006D +:1015E000070000008D010000240A000064040000D0 +:1015F0006404000002010800240900002404000023 +:1016000024040000020110000D00020044910000BB +:1016100086612C0007000000FD01000042800100EF +:101620000A000800440A000086432C0042800100A2 +:101630000D000A0020080000FD02000040800100AB +:10164000070020007D0200002010000006060000B8 +:1016500040800100F5020000420001000A0008007D +:101660000409000086B22C00070000007D03000082 +:10167000428001000A0008000409000086E22C00F4 +:1016800007000000750000007D2E000042000100F0 +:101690004A800B00200000000409000086060000BC +:1016A000400001004A8431008B04300083080000B0 +:1016B0008D000000100800003A1428008D00000082 +:1016C000100800003A0C28007506000042000100D6 +:1016D0000A0008001538000024090100020528004E +:1016E0000D000B0020080000F50200004000010082 +:1016F00006060000070022006404000064040000E5 +:101700000606000007000000340100008D7F000085 +:101710003C090000121D280012252800321F00007D +:1017200007000E000D0100007D03000020080000EE +:1017300040800100F4D20500070000000700080007 +:101740007D030000428001000A0008000409000037 +:10175000868A2E0007000000060600000700000031 +:101760000700000012000000070010000700320010 +:101770000700600007004600800010001A004800C3 +:101780000449000086F12E0007000000101200003E +:101790003A00580045010000045D5C0007000000AD +:1017A000800000001A0048000449000086412F0014 +:1017B00007000000101200003A0050000459000019 +:1017C00086982F0045000000C5000000F5FF7F004F +:1017D0007DFF7F0024D50700244200000201500055 +:1017E00002052000820000001A00400004410000B1 +:1017F00086C92F0007000000653800001A0040006D +:10180000204000004D10000084C1040086AB310070 +:1018100040000000070004006501000045010000D1 +:101820002040000040000000650700008000080024 +:101830001A004000044100008659300007000000F3 +:10184000101200003A0040000441000086B230004F +:101850004D000000CD000000104800003A042000B8 +:10186000820800001A0040000441000086C13000D8 +:10187000070000002048000004590000869831004D +:1018800040000000E507000080042000A0162800AA +:10189000E0163200E0163A00E01642006012020044 +:1018A0004000000032000000750040007D00000094 +:1018B00074D5070012052000820000001A004000C5 +:1018C000044100008671310007000000068A030011 +:1018D00007006400E5000000200000004000000058 +:1018E000650A0000200000004000020040000200E5 +:1018F0004000000065010000420000000A00700086 +:101900000471000086323200070000000700060064 +:10191000069A010007006400000005002070000026 +:1019200040000000068A0300070064000700000072 +:101930006D30000060880200609002000A0008001C +:101940006088020040800000120010000D100000AE +:101950008491000086D132000D0E000084910000B9 +:1019600086E133000700000007003000201000006F +:101970006D3B000040800000800000001A0008005D +:101980000409000086F13200070000002012000068 +:10199000ED0D000040800000428000000A001000B1 +:1019A0000D004000449510000700000020100000CA +:1019B000ED0D000040800000428000000A0420007D +:1019C000820000001A00080004090000868133002C +:1019D000070000006D3B0000428000000A00080084 +:1019E000150E000084090100862B340007006000FA +:1019F0001A000800150C0000840901008613340049 +:101A00002000000007001A00ED02000040800000E6 +:101A1000070062006D300000428002004A800A0028 +:101A2000200800004A800A00060600004A801000D4 +:101A30000700000012252800321F0000F4D2050024 +:101A400004D154005C73000086070000070000000A +:101A500007000C0007000A0007001C0065340000A6 +:101A60004000020020480000605002000A004000D0 +:101A700060400200400000004449450007000000AB +:101A800020400000E53A000040000000E52800008A +:101A9000420000000A0048000449000086F83900AE +:101AA000652C0000420000000A004000D500000044 +:101AB00004414500070000005506000004450500EC +:101AC00086823600D5010000044505008680360078 +:101AD000652B000042000000E53A00004A0050007B +:101AE0000A004000D4C3450007000000044545003B +:101AF00007000000CD00000044494400070000003A +:101B000004454500070000004D0100004449550010 +:101B1000070000004451040086793600652C00005F +:101B2000420000000A00480004D14C0007000000F9 +:101B300044C1040086833600070000000700160039 +:101B4000E52C0000420004000A0040002040000094 +:101B50004000000065290000420000000A0040002B +:101B60000441000086F03600070000000224000057 +:101B700006323800025C0000E5250000420000004B +:101B80000A00400074420000E52A00004200000004 +:101B90000A0040007442000012015000E5290000D4 +:101BA000420000000A0040003442000004414500A9 +:101BB000070000002040000040000000E53E00005B +:101BC0002000000040000000E52D00005201400010 +:101BD0000A0050004451040086DA3700C5000000B6 +:101BE000E53E00002040000040000000E52B000022 +:101BF000420000000A00400054424000070000007C +:101C0000E52A0000204000004000000032015000A2 +:101C10003401040074560000E5290000420002006F +:101C20000A004200420000000A0050007C4105000A +:101C3000E5280000420000000A004800C50000003E +:101C400044C14C0086A03800E5260000E5270000CE +:101C5000420002004A0040000A0050003C420000DE +:101C60007C560000E52800002048000040000000ED +:101C7000121D280012252800721F0000652900008F +:101C8000420000000A00400004410000863A39008A +:101C900007000E000700160007001E00E53E0000CA +:101CA000420000000A00400004410000867839002C +:101CB000652D0000420000000A3428006534000051 +:101CC000420002004A004200204000004A004A0050 +:101CD0004A005000F4D2050004D154005C730000A7 +:101CE00086E1390007000000060600000700080032 +:101CF00007000C000700080007000A00E5010000CB +:101D00004500020020400000600000006503000064 +:101D100040000000652E0000201A0000601A0A0032 +:101D20004000000065340000420002004A0042000A +:101D3000204000004A004A00060600004A00500009 +:101D4000FD170000428001000A000800040900009D +:101D5000865A2200070000007D100000428001002A +:101D6000FD1100004A8033004A8019000A0020005B +:101D70009500000044112A0044A1010086903B0018 +:101D80000D04000084B1000086913B00FD180000A6 +:101D900042800100FD1000004A8009000A0038005E +:101DA0009500000024090100643A000086813B0090 +:101DB000070000000439000086923B000700000085 +:101DC000069A3B000D0000008D0000002008000076 +:101DD0007D38000040800100020070007D1100008D +:101DE000428001007D1900004A8029000A0030006D +:101DF0000200380024310000240400002404000004 +:101E0000242A0000020528008D06000010080000AA +:101E10003A1428000D75000024B10000642200006F +:101E200086033D0002442800100800003A0C2800F8 +:101E30000D800B0020080000FD0200004080010022 +:101E4000070020008D75000024B100000201100081 +:101E50004421010086493E00101800003A0010009D +:101E60007D380000428001000A00080004090000DB +:101E700086483E0000000300064A3E00BD00000008 +:101E80008D00000064310200640A0000020D280089 +:101E90008D800B0020080000FD0200004080010042 +:101EA000070020007D380000428001000A00080081 +:101EB0000409000086323E0000000300FD0200001D +:101EC000428001000A0008000409000086823D00EB +:101ED00007000000102800003A0428000D750000DB +:101EE0002409030064220000020D28006C31020066 +:101EF0000A4528000D810B0020080000FD020000AB +:101F000040800100070020008D000000240A00002E +:101F1000064A3E0002011000101800003A001000AE +:101F2000BD000000103800003A0430007D180000A9 +:101F300042800100FD1800004A8009000A002000CC +:101F4000AD000000248902002C21070010100000C1 +:101F5000830530008B0D3000BB143000831C300033 +:101F6000832000007D130000428003004A84330078 +:101F7000CBAC3300CBB43300CBBC3300CBC4330089 +:101F8000CBCC3300CBD433008B5C300083600000BB +:101F90000D1E0000FD050000428001000A00200027 +:101FA000240902008D0600006CA900009D000000BD +:101FB000FD020000428001000A0008000409000040 +:101FC000866A3F0007000000020528000A0D28006D +:101FD00002442800101800003A1428008D000C005C +:101FE00020080000FD0200004080010007002200E0 +:101FF00004390000865822000D1E00007D050000F7 +:10200000428001000A00200024090200A50000000F +:10201000FD020000428001000A00080004090000DF +:10202000862A40000700000002052800020C280054 +:10203000102000003A1428000D010C0020080000B8 +:10204000FD02000040800100065A22000700220025 +:102050000000000000000000000000000000000080 +:102060000000000000000000000000000000000070 +:102070000000000000000000000000000000000060 +:102080000000000000000000000000000000000050 +:102090000000000000000000000000000000000040 +:1020A0000000000000000000000000000000000030 +:1020B0000000000000000000000000000000000020 +:1020C0000000000000000000000000000000000010 +:1020D0000000000000000000000000000000000000 +:1020E00000000000000000000000000000000000F0 +:1020F00000000000000000000000000000000000E0 +:1021000000000000000000000000000000000000CF +:1021100000000000000000000000000000000000BF +:1021200000000000000000000000000000000000AF +:10213000000000000000000000000000000000009F +:10214000000000000000000000000000000000008F +:10215000000000000000000000000000000000007F +:10216000000000000000000000000000000000006F +:10217000000000000000000000000000000000005F +:10218000000000000000000000000000000000004F +:10219000000000000000000000000000000000003F +:1021A000000000000000000000000000000000002F +:1021B000000000000000000000000000000000001F +:1021C000000000000000000000000000000000000F +:1021D00000000000000000000000000000000000FF +:1021E00000000000000000000000000000000000EF +:1021F00000000000000000000000000000000000DF +:1022000000000000000000000000000000000000CE +:1022100000000000000000000000000000000000BE +:1022200000000000000000000000000000000000AE +:10223000000000000000000000000000000000009E +:10224000000000000000000000000000000000008E +:10225000000000000000000000000000000000007E +:10226000000000000000000000000000000000006E +:10227000000000000000000000000000000000005E +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000000000000000DE +:1023000000000000000000000000000000000000CD +:1023100000000000000000000000000000000000BD +:1023200000000000000000000000000000000000AD +:10233000000000000000000000000000000000009D +:10234000000000000000000000000000000000008D +:10235000000000000000000000000000000000007D +:10236000000000000000000000000000000000006D +:10237000000000000000000000000000000000005D +:10238000000000000000000000000000000000004D +:10239000000000000000000000000000000000003D +:1023A000000000000000000000000000000000002D +:1023B000000000000000000000000000000000001D +:1023C000000000000000000000000000000000000D +:1023D00000000000000000000000000000000000FD +:1023E00000000000000000000000000000000000ED +:1023F00000000000000000000000000000000000DD +:1024000000000000000000000000000000000000CC +:1024100000000000000000000000000000000000BC +:1024200000000000000000000000000000000000AC +:10243000000000000000000000000000000000009C +:10244000000000000000000000000000000000008C +:10245000000000000000000000000000000000007C +:10246000000000000000000000000000000000006C +:10247000000000000000000000000000000000005C +:10248000000000000000000000000000000000004C +:10249000000000000000000000000000000000003C +:1024A000000000000000000000000000000000002C +:1024B000000000000000000000000000000000001C +:1024C000000000000000000000000000000000000C +:1024D00000000000000000000000000000000000FC +:1024E00000000000000000000000000000000000EC +:1024F00000000000000000000000000000000000DC +:1025000000000000000000000000000000000000CB +:1025100000000000000000000000000000000000BB +:1025200000000000000000000000000000000000AB +:10253000000000000000000000000000000000009B +:10254000000000000000000000000000000000008B +:10255000000000000000000000000000000000007B +:10256000000000000000000000000000000000006B +:10257000000000000000000000000000000000005B +:10258000000000000000000000000000000000004B +:10259000000000000000000000000000000000003B +:1025A000000000000000000000000000000000002B +:1025B000000000000000000000000000000000001B +:1025C000000000000000000000000000000000000B +:1025D00000000000000000000000000000000000FB +:1025E00000000000000000000000000000000000EB +:1025F00000000000000000000000000000000000DB +:1026000000000000000000000000000000000000CA +:1026100000000000000000000000000000000000BA +:1026200000000000000000000000000000000000AA +:10263000000000000000000000000000000000009A +:10264000000000000000000000000000000000008A +:10265000000000000000000000000000000000007A +:10266000000000000000000000000000000000006A +:10267000000000000000000000000000000000005A +:10268000000000000000000000000000000000004A +:10269000000000000000000000000000000000003A +:1026A000000000000000000000000000000000002A +:1026B000000000000000000000000000000000001A +:1026C000000000000000000000000000000000000A +:1026D00000000000000000000000000000000000FA +:1026E00000000000000000000000000000000000EA +:1026F00000000000000000000000000000000000DA +:1027000000000000000000000000000000000000C9 +:1027100000000000000000000000000000000000B9 +:1027200000000000000000000000000000000000A9 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000000000000000000000000000000000079 +:102760000000000000000000000000000000000069 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:102860000000000000000000000000000000000068 +:102870000000000000000000000000000000000058 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000000000000000037 +:1029A0000000000000000000000000000000000027 +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A000000000000000000000000000000000000C6 +:102A100000000000000000000000000000000000B6 +:102A200000000000000000000000000000000000A6 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50000000000000000000000000000000000076 +:102A60000000000000000000000000000000000066 +:102A70000000000000000000000000000000000056 +:102A80000000000000000000000000000000000046 +:102A90000000000000000000000000000000000036 +:102AA0000000000000000000000000000000000026 +:102AB0000000000000000000000000000000000016 +:102AC0000000000000000000000000000000000006 +:102AD00000000000000000000000000000000000F6 +:102AE00000000000000000000000000000000000E6 +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B200000000000000000000000000000000000A5 +:102B30000000000000000000000000000000000095 +:102B40000000000000000000000000000000000085 +:102B50000000000000000000000000000000000075 +:102B60000000000000000000000000000000000065 +:102B70000000000000000000000000000000000055 +:102B80000000000000000000000000000000000045 +:102B90000000000000000000000000000000000035 +:102BA0000000000000000000000000000000000025 +:102BB0000000000000000000000000000000000015 +:102BC0000000000000000000000000000000000005 +:102BD00000000000000000000000000000000000F5 +:102BE00000000000000000000000000000000000E5 +:102BF00000000000000000000000000000000000D5 +:102C000000000000000000000000000000000000C4 +:102C100000000000000000000000000000000000B4 +:102C200000000000000000000000000000000000A4 +:102C30000000000000000000000000000000000094 +:102C40000000000000000000000000000000000084 +:102C50000000000000000000000000000000000074 +:102C60000000000000000000000000000000000064 +:102C70000000000000000000000000000000000054 +:102C80000000000000000000000000000000000044 +:102C90000000000000000000000000000000000034 +:102CA0000000000000000000000000000000000024 +:102CB0000000000000000000000000000000000014 +:102CC0000000000000000000000000000000000004 +:102CD00000000000000000000000000000000000F4 +:102CE00000000000000000000000000000000000E4 +:102CF00000000000000000000000000000000000D4 +:102D000000000000000000000000000000000000C3 +:102D100000000000000000000000000000000000B3 +:102D200000000000000000000000000000000000A3 +:102D30000000000000000000000000000000000093 +:102D40000000000000000000000000000000000083 +:102D50000000000000000000000000000000000073 +:102D60000000000000000000000000000000000063 +:102D70000000000000000000000000000000000053 +:102D80000000000000000000000000000000000043 +:102D90000000000000000000000000000000000033 +:102DA0000000000000000000000000000000000023 +:102DB0000000000000000000000000000000000013 +:102DC0000000000000000000000000000000000003 +:102DD00000000000000000000000000000000000F3 +:102DE00000000000000000000000000000000000E3 +:102DF00000000000000000000000000000000000D3 +:102E000000000000000000000000000000000000C2 +:102E100000000000000000000000000000000000B2 +:102E200000000000000000000000000000000000A2 +:102E30000000000000000000000000000000000092 +:102E40000000000000000000000000000000000082 +:102E50000000000000000000000000000000000072 +:102E60000000000000000000000000000000000062 +:102E70000000000000000000000000000000000052 +:102E80000000000000000000000000000000000042 +:102E90000000000000000000000000000000000032 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000000000000000000000000000000F2 +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F000000000000000000000000000000000000C1 +:102F100000000000000000000000000000000000B1 +:102F200000000000000000000000000000000000A1 +:102F30000000000000000000000000000000000091 +:102F40000000000000000000000000000000000081 +:102F50000000000000000000000000000000000071 +:102F60000000000000000000000000000000000061 +:102F70000000000000000000000000000000000051 +:102F80000000000000000000000000000000000041 +:102F90000000000000000000000000000000000031 +:102FA0000000000000000000000000000000000021 +:102FB0000000000000000000000000000000000011 +:102FC0000000000000000000000000000000000001 +:102FD00000000000000000000000000000000000F1 +:102FE00000000000000000000000000000000000E1 +:102FF00000000000000000000000000000000000D1 +:00000001FF diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 32836ea..e4a0045 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -914,7 +914,6 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND - select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -925,15 +924,6 @@ config SND_YMFPCI To compile this driver as a module, choose M here: the module will be called snd-ymfpci. -config SND_YMFPCI_FIRMWARE_IN_KERNEL - bool "In-kernel firmware for YMFPCI driver" - depends on SND_YMFPCI - default y - help - Say Y here to include the static firmware built in the kernel - for the YMFPCI driver. If you choose N here, you need to - install the firmware files from the alsa-firmware package. - config SND_AC97_POWER_SAVE bool "AC97 Power-Saving Mode" depends on SND_AC97_CODEC && EXPERIMENTAL diff --git a/sound/pci/ymfpci/ymfpci_image.h b/sound/pci/ymfpci/ymfpci_image.h deleted file mode 100644 index 112f2ff..0000000 --- a/sound/pci/ymfpci/ymfpci_image.h +++ /dev/null @@ -1,1565 +0,0 @@ -#ifndef _HWMCODE_ -#define _HWMCODE_ - -static u32 DspInst[YDSXG_DSPLENGTH / 4] = { - 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, - 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, - 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, - 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; - -static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = { - 0x000007, 0x240007, 0x0C0007, 0x1C0007, - 0x060007, 0x700002, 0x000020, 0x030040, - 0x007104, 0x004286, 0x030040, 0x000F0D, - 0x000810, 0x20043A, 0x000282, 0x00020D, - 0x000810, 0x20043A, 0x001282, 0x200E82, - 0x001A82, 0x032D0D, 0x000810, 0x10043A, - 0x02D38D, 0x000810, 0x18043A, 0x00010D, - 0x020015, 0x0000FD, 0x000020, 0x038860, - 0x039060, 0x038060, 0x038040, 0x038040, - 0x038040, 0x018040, 0x000A7D, 0x038040, - 0x038040, 0x018040, 0x200402, 0x000882, - 0x08001A, 0x000904, 0x015986, 0x000007, - 0x260007, 0x000007, 0x000007, 0x018A06, - 0x000007, 0x030C8D, 0x000810, 0x18043A, - 0x260007, 0x00087D, 0x018042, 0x00160A, - 0x04A206, 0x000007, 0x00218D, 0x000810, - 0x08043A, 0x21C206, 0x000007, 0x0007FD, - 0x018042, 0x08000A, 0x000904, 0x029386, - 0x000195, 0x090D04, 0x000007, 0x000820, - 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD, - 0x032206, 0x018040, 0x000A7D, 0x038042, - 0x13804A, 0x18000A, 0x001820, 0x059060, - 0x058860, 0x018040, 0x0000FD, 0x018042, - 0x70000A, 0x000115, 0x071144, 0x032386, - 0x030000, 0x007020, 0x034A06, 0x018040, - 0x00348D, 0x000810, 0x08043A, 0x21EA06, - 0x000007, 0x02D38D, 0x000810, 0x18043A, - 0x018206, 0x000007, 0x240007, 0x000F8D, - 0x000810, 0x00163A, 0x002402, 0x005C02, - 0x0028FD, 0x000020, 0x018040, 0x08000D, - 0x000815, 0x510984, 0x000007, 0x00004D, - 0x000E5D, 0x000E02, 0x00418D, 0x000810, - 0x08043A, 0x2C8A06, 0x000007, 0x00008D, - 0x000924, 0x000F02, 0x00458D, 0x000810, - 0x08043A, 0x2C8A06, 0x000007, 0x00387D, - 0x018042, 0x08000A, 0x001015, 0x010984, - 0x018386, 0x000007, 0x01AA06, 0x000007, - 0x0008FD, 0x018042, 0x18000A, 0x001904, - 0x218086, 0x280007, 0x001810, 0x28043A, - 0x280C02, 0x00000D, 0x000810, 0x28143A, - 0x08808D, 0x000820, 0x0002FD, 0x018040, - 0x200007, 0x00020D, 0x189904, 0x000007, - 0x00402D, 0x0000BD, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x055A86, 0x000007, - 0x000100, 0x000A20, 0x00047D, 0x018040, - 0x018042, 0x20000A, 0x003015, 0x012144, - 0x034986, 0x000007, 0x002104, 0x034986, - 0x000007, 0x000F8D, 0x000810, 0x280C3A, - 0x023944, 0x06C986, 0x000007, 0x001810, - 0x28043A, 0x08810D, 0x000820, 0x0002FD, - 0x018040, 0x200007, 0x002810, 0x78003A, - 0x00688D, 0x000810, 0x08043A, 0x288A06, - 0x000007, 0x00400D, 0x001015, 0x189904, - 0x292904, 0x393904, 0x000007, 0x060206, - 0x000007, 0x0004F5, 0x00007D, 0x000020, - 0x00008D, 0x010860, 0x018040, 0x00047D, - 0x038042, 0x21804A, 0x18000A, 0x021944, - 0x215886, 0x000007, 0x004075, 0x71F104, - 0x000007, 0x010042, 0x28000A, 0x002904, - 0x212086, 0x000007, 0x003C0D, 0x30A904, - 0x000007, 0x00077D, 0x018042, 0x08000A, - 0x000904, 0x07DA86, 0x00057D, 0x002820, - 0x03B060, 0x07F206, 0x018040, 0x003020, - 0x03A860, 0x018040, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x07FA86, 0x000007, - 0x00057D, 0x018042, 0x28040A, 0x000E8D, - 0x000810, 0x280C3A, 0x00000D, 0x000810, - 0x28143A, 0x09000D, 0x000820, 0x0002FD, - 0x018040, 0x200007, 0x003DFD, 0x000020, - 0x018040, 0x00107D, 0x008D8D, 0x000810, - 0x08043A, 0x288A06, 0x000007, 0x000815, - 0x08001A, 0x010984, 0x095186, 0x00137D, - 0x200500, 0x280F20, 0x338F60, 0x3B8F60, - 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, - 0x038A60, 0x018040, 0x007FBD, 0x383DC4, - 0x000007, 0x001A7D, 0x001375, 0x018042, - 0x09004A, 0x10000A, 0x0B8D04, 0x139504, - 0x000007, 0x000820, 0x019060, 0x001104, - 0x212086, 0x010040, 0x0017FD, 0x018042, - 0x08000A, 0x000904, 0x212286, 0x000007, - 0x00197D, 0x038042, 0x09804A, 0x10000A, - 0x000924, 0x001664, 0x0011FD, 0x038042, - 0x2B804A, 0x19804A, 0x00008D, 0x218944, - 0x000007, 0x002244, 0x0AE186, 0x000007, - 0x001A64, 0x002A24, 0x00197D, 0x080102, - 0x100122, 0x000820, 0x039060, 0x018040, - 0x003DFD, 0x00008D, 0x000820, 0x018040, - 0x001375, 0x001A7D, 0x010042, 0x09804A, - 0x10000A, 0x00021D, 0x0189E4, 0x2992E4, - 0x309144, 0x000007, 0x00060D, 0x000A15, - 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4, - 0x000464, 0x01B3E4, 0x0232E4, 0x000464, - 0x000464, 0x000464, 0x000464, 0x00040D, - 0x08B1C4, 0x000007, 0x000820, 0x000BF5, - 0x030040, 0x00197D, 0x038042, 0x09804A, - 0x000A24, 0x08000A, 0x080E64, 0x000007, - 0x100122, 0x000820, 0x031060, 0x010040, - 0x0064AC, 0x00027D, 0x000020, 0x018040, - 0x00107D, 0x018042, 0x0011FD, 0x3B804A, - 0x09804A, 0x20000A, 0x000095, 0x1A1144, - 0x00A144, 0x0D2086, 0x00040D, 0x00B984, - 0x0D2186, 0x0018FD, 0x018042, 0x0010FD, - 0x09804A, 0x28000A, 0x000095, 0x010924, - 0x002A64, 0x0D1186, 0x000007, 0x002904, - 0x0D2286, 0x000007, 0x0D2A06, 0x080002, - 0x00008D, 0x00387D, 0x000820, 0x018040, - 0x00127D, 0x018042, 0x10000A, 0x003904, - 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984, - 0x0DA186, 0x000025, 0x0E7A06, 0x00002D, - 0x000015, 0x00082D, 0x02C78D, 0x000820, - 0x0EC206, 0x00000D, 0x7F8035, 0x00B984, - 0x0E7186, 0x400025, 0x00008D, 0x110944, - 0x000007, 0x00018D, 0x109504, 0x000007, - 0x009164, 0x000424, 0x000424, 0x000424, - 0x100102, 0x280002, 0x02C68D, 0x000820, - 0x0EC206, 0x00018D, 0x00042D, 0x00008D, - 0x109504, 0x000007, 0x00020D, 0x109184, - 0x000007, 0x02C70D, 0x000820, 0x00008D, - 0x0038FD, 0x018040, 0x003BFD, 0x001020, - 0x03A860, 0x000815, 0x313184, 0x212184, - 0x000007, 0x03B060, 0x03A060, 0x018040, - 0x0022FD, 0x000095, 0x010924, 0x000424, - 0x000424, 0x001264, 0x100102, 0x000820, - 0x039060, 0x018040, 0x001924, 0x00FB8D, - 0x00397D, 0x000820, 0x058040, 0x038042, - 0x09844A, 0x000606, 0x08040A, 0x000424, - 0x000424, 0x00117D, 0x018042, 0x08000A, - 0x000A24, 0x280502, 0x280C02, 0x09800D, - 0x000820, 0x0002FD, 0x018040, 0x200007, - 0x0022FD, 0x018042, 0x08000A, 0x000095, - 0x280DC4, 0x011924, 0x00197D, 0x018042, - 0x0011FD, 0x09804A, 0x10000A, 0x0000B5, - 0x113144, 0x0A8D04, 0x000007, 0x080A44, - 0x129504, 0x000007, 0x0023FD, 0x001020, - 0x038040, 0x101244, 0x000007, 0x000820, - 0x039060, 0x018040, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x10FA86, 0x000007, - 0x003BFD, 0x000100, 0x000A10, 0x0B807A, - 0x13804A, 0x090984, 0x000007, 0x000095, - 0x013D04, 0x118086, 0x10000A, 0x100002, - 0x090984, 0x000007, 0x038042, 0x11804A, - 0x090D04, 0x000007, 0x10000A, 0x090D84, - 0x000007, 0x00257D, 0x000820, 0x018040, - 0x00010D, 0x000810, 0x28143A, 0x00127D, - 0x018042, 0x20000A, 0x00197D, 0x018042, - 0x00117D, 0x31804A, 0x10000A, 0x003124, - 0x01280D, 0x00397D, 0x000820, 0x058040, - 0x038042, 0x09844A, 0x000606, 0x08040A, - 0x300102, 0x003124, 0x000424, 0x000424, - 0x001224, 0x280502, 0x001A4C, 0x130186, - 0x700002, 0x00002D, 0x030000, 0x00387D, - 0x018042, 0x10000A, 0x132A06, 0x002124, - 0x0000AD, 0x100002, 0x00010D, 0x000924, - 0x006B24, 0x01368D, 0x00397D, 0x000820, - 0x058040, 0x038042, 0x09844A, 0x000606, - 0x08040A, 0x003264, 0x00008D, 0x000A24, - 0x001020, 0x00227D, 0x018040, 0x013C0D, - 0x000810, 0x08043A, 0x29D206, 0x000007, - 0x002820, 0x00207D, 0x018040, 0x00117D, - 0x038042, 0x13804A, 0x33800A, 0x00387D, - 0x018042, 0x08000A, 0x000904, 0x163A86, - 0x000007, 0x00008D, 0x030964, 0x01478D, - 0x00397D, 0x000820, 0x058040, 0x038042, - 0x09844A, 0x000606, 0x08040A, 0x380102, - 0x000424, 0x000424, 0x001224, 0x0002FD, - 0x018042, 0x08000A, 0x000904, 0x14A286, - 0x000007, 0x280502, 0x001A4C, 0x163986, - 0x000007, 0x032164, 0x00632C, 0x003DFD, - 0x018042, 0x08000A, 0x000095, 0x090904, - 0x000007, 0x000820, 0x001A4C, 0x156186, - 0x018040, 0x030000, 0x157A06, 0x002124, - 0x00010D, 0x000924, 0x006B24, 0x015B8D, - 0x00397D, 0x000820, 0x058040, 0x038042, - 0x09844A, 0x000606, 0x08040A, 0x003A64, - 0x000095, 0x001224, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x15DA86, 0x000007, - 0x01628D, 0x000810, 0x08043A, 0x29D206, - 0x000007, 0x14D206, 0x000007, 0x007020, - 0x08010A, 0x10012A, 0x0020FD, 0x038860, - 0x039060, 0x018040, 0x00227D, 0x018042, - 0x003DFD, 0x08000A, 0x31844A, 0x000904, - 0x16D886, 0x18008B, 0x00008D, 0x189904, - 0x00312C, 0x17AA06, 0x000007, 0x00324C, - 0x173386, 0x000007, 0x001904, 0x173086, - 0x000007, 0x000095, 0x199144, 0x00222C, - 0x003124, 0x00636C, 0x000E3D, 0x001375, - 0x000BFD, 0x010042, 0x09804A, 0x10000A, - 0x038AEC, 0x0393EC, 0x00224C, 0x17A986, - 0x000007, 0x00008D, 0x189904, 0x00226C, - 0x00322C, 0x30050A, 0x301DAB, 0x002083, - 0x0018FD, 0x018042, 0x08000A, 0x018924, - 0x300502, 0x001083, 0x001875, 0x010042, - 0x10000A, 0x00008D, 0x010924, 0x001375, - 0x330542, 0x330CCB, 0x332CCB, 0x3334CB, - 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB, - 0x305C8B, 0x006083, 0x0002F5, 0x010042, - 0x08000A, 0x000904, 0x187A86, 0x000007, - 0x001E2D, 0x0005FD, 0x018042, 0x08000A, - 0x028924, 0x280502, 0x00060D, 0x000810, - 0x280C3A, 0x00008D, 0x000810, 0x28143A, - 0x0A808D, 0x000820, 0x0002F5, 0x010040, - 0x220007, 0x001275, 0x030042, 0x21004A, - 0x00008D, 0x1A0944, 0x000007, 0x01980D, - 0x000810, 0x08043A, 0x2B2206, 0x000007, - 0x0001F5, 0x030042, 0x0D004A, 0x10000A, - 0x089144, 0x000007, 0x000820, 0x010040, - 0x0025F5, 0x0A3144, 0x000007, 0x000820, - 0x032860, 0x030040, 0x00217D, 0x038042, - 0x0B804A, 0x10000A, 0x000820, 0x031060, - 0x030040, 0x00008D, 0x000124, 0x00012C, - 0x000E64, 0x001A64, 0x00636C, 0x08010A, - 0x10012A, 0x000820, 0x031060, 0x030040, - 0x0020FD, 0x018042, 0x08000A, 0x00227D, - 0x018042, 0x10000A, 0x000820, 0x031060, - 0x030040, 0x00197D, 0x018042, 0x08000A, - 0x0022FD, 0x038042, 0x10000A, 0x000820, - 0x031060, 0x030040, 0x090D04, 0x000007, - 0x000820, 0x030040, 0x038042, 0x0B804A, - 0x10000A, 0x000820, 0x031060, 0x030040, - 0x038042, 0x13804A, 0x19804A, 0x110D04, - 0x198D04, 0x000007, 0x08000A, 0x001020, - 0x031860, 0x030860, 0x030040, 0x00008D, - 0x0B0944, 0x000007, 0x000820, 0x010040, - 0x0005F5, 0x030042, 0x08000A, 0x000820, - 0x010040, 0x0000F5, 0x010042, 0x08000A, - 0x000904, 0x1C6086, 0x001E75, 0x030042, - 0x01044A, 0x000C0A, 0x1C7206, 0x000007, - 0x000402, 0x000C02, 0x00177D, 0x001AF5, - 0x018042, 0x03144A, 0x031C4A, 0x03244A, - 0x032C4A, 0x03344A, 0x033C4A, 0x03444A, - 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD, - 0x030042, 0x0B004A, 0x1B804A, 0x13804A, - 0x20000A, 0x089144, 0x19A144, 0x0389E4, - 0x0399EC, 0x005502, 0x005D0A, 0x030042, - 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, - 0x089144, 0x19A144, 0x0389E4, 0x0399EC, - 0x006502, 0x006D0A, 0x030042, 0x0B004A, - 0x19004A, 0x2B804A, 0x13804A, 0x21804A, - 0x30000A, 0x089144, 0x19A144, 0x2AB144, - 0x0389E4, 0x0399EC, 0x007502, 0x007D0A, - 0x03A9E4, 0x000702, 0x00107D, 0x000415, - 0x018042, 0x08000A, 0x0109E4, 0x000F02, - 0x002AF5, 0x0019FD, 0x010042, 0x09804A, - 0x10000A, 0x000934, 0x001674, 0x0029F5, - 0x010042, 0x10000A, 0x00917C, 0x002075, - 0x010042, 0x08000A, 0x000904, 0x1ED286, - 0x0026F5, 0x0027F5, 0x030042, 0x09004A, - 0x10000A, 0x000A3C, 0x00167C, 0x001A75, - 0x000BFD, 0x010042, 0x51804A, 0x48000A, - 0x160007, 0x001075, 0x010042, 0x282C0A, - 0x281D12, 0x282512, 0x001F32, 0x1E0007, - 0x0E0007, 0x001975, 0x010042, 0x002DF5, - 0x0D004A, 0x10000A, 0x009144, 0x1FB286, - 0x010042, 0x28340A, 0x000E5D, 0x00008D, - 0x000375, 0x000820, 0x010040, 0x05D2F4, - 0x54D104, 0x00735C, 0x205386, 0x000007, - 0x0C0007, 0x080007, 0x0A0007, 0x02040D, - 0x000810, 0x08043A, 0x332206, 0x000007, - 0x205A06, 0x000007, 0x080007, 0x002275, - 0x010042, 0x20000A, 0x002104, 0x212086, - 0x001E2D, 0x0002F5, 0x010042, 0x08000A, - 0x000904, 0x209286, 0x000007, 0x002010, - 0x30043A, 0x00057D, 0x0180C3, 0x08000A, - 0x028924, 0x280502, 0x280C02, 0x0A810D, - 0x000820, 0x0002F5, 0x010040, 0x220007, - 0x0004FD, 0x018042, 0x70000A, 0x030000, - 0x007020, 0x06FA06, 0x018040, 0x02180D, - 0x000810, 0x08043A, 0x2B2206, 0x000007, - 0x0002FD, 0x018042, 0x08000A, 0x000904, - 0x218A86, 0x000007, 0x01F206, 0x000007, - 0x000875, 0x0009FD, 0x00010D, 0x220A06, - 0x000295, 0x000B75, 0x00097D, 0x00000D, - 0x000515, 0x010042, 0x18000A, 0x001904, - 0x287886, 0x0006F5, 0x001020, 0x010040, - 0x0004F5, 0x000820, 0x010040, 0x000775, - 0x010042, 0x09804A, 0x10000A, 0x001124, - 0x000904, 0x22BA86, 0x000815, 0x080102, - 0x101204, 0x22DA06, 0x000575, 0x081204, - 0x000007, 0x100102, 0x000575, 0x000425, - 0x021124, 0x100102, 0x000820, 0x031060, - 0x010040, 0x001924, 0x287886, 0x00008D, - 0x000464, 0x009D04, 0x278886, 0x180102, - 0x000575, 0x010042, 0x28040A, 0x00018D, - 0x000924, 0x280D02, 0x00000D, 0x000924, - 0x281502, 0x10000D, 0x000820, 0x0002F5, - 0x010040, 0x200007, 0x001175, 0x0002FD, - 0x018042, 0x08000A, 0x000904, 0x23C286, - 0x000007, 0x000100, 0x080B20, 0x130B60, - 0x1B0B60, 0x030A60, 0x010040, 0x050042, - 0x3D004A, 0x35004A, 0x2D004A, 0x20000A, - 0x0006F5, 0x010042, 0x28140A, 0x0004F5, - 0x010042, 0x08000A, 0x000315, 0x010D04, - 0x24CA86, 0x004015, 0x000095, 0x010D04, - 0x24B886, 0x100022, 0x10002A, 0x24E206, - 0x000007, 0x333104, 0x2AA904, 0x000007, - 0x032124, 0x280502, 0x001124, 0x000424, - 0x000424, 0x003224, 0x00292C, 0x00636C, - 0x25F386, 0x000007, 0x02B164, 0x000464, - 0x000464, 0x00008D, 0x000A64, 0x280D02, - 0x10008D, 0x000820, 0x0002F5, 0x010040, - 0x220007, 0x00008D, 0x38B904, 0x000007, - 0x03296C, 0x30010A, 0x0002F5, 0x010042, - 0x08000A, 0x000904, 0x25BA86, 0x000007, - 0x02312C, 0x28050A, 0x00008D, 0x01096C, - 0x280D0A, 0x10010D, 0x000820, 0x0002F5, - 0x010040, 0x220007, 0x001124, 0x000424, - 0x000424, 0x003224, 0x300102, 0x032944, - 0x267A86, 0x000007, 0x300002, 0x0004F5, - 0x010042, 0x08000A, 0x000315, 0x010D04, - 0x26C086, 0x003124, 0x000464, 0x300102, - 0x0002F5, 0x010042, 0x08000A, 0x000904, - 0x26CA86, 0x000007, 0x003124, 0x300502, - 0x003924, 0x300583, 0x000883, 0x0005F5, - 0x010042, 0x28040A, 0x00008D, 0x008124, - 0x280D02, 0x00008D, 0x008124, 0x281502, - 0x10018D, 0x000820, 0x0002F5, 0x010040, - 0x220007, 0x001025, 0x000575, 0x030042, - 0x09004A, 0x10000A, 0x0A0904, 0x121104, - 0x000007, 0x001020, 0x050860, 0x050040, - 0x0006FD, 0x018042, 0x09004A, 0x10000A, - 0x0000A5, 0x0A0904, 0x121104, 0x000007, - 0x000820, 0x019060, 0x010040, 0x0002F5, - 0x010042, 0x08000A, 0x000904, 0x284286, - 0x000007, 0x230A06, 0x000007, 0x000606, - 0x000007, 0x0002F5, 0x010042, 0x08000A, - 0x000904, 0x289286, 0x000007, 0x000100, - 0x080B20, 0x138B60, 0x1B8B60, 0x238B60, - 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60, - 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60, - 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60, - 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60, - 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60, - 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60, - 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60, - 0x000606, 0x018040, 0x00008D, 0x000A64, - 0x280D02, 0x000A24, 0x00027D, 0x018042, - 0x10000A, 0x001224, 0x0003FD, 0x018042, - 0x08000A, 0x000904, 0x2A8286, 0x000007, - 0x00018D, 0x000A24, 0x000464, 0x000464, - 0x080102, 0x000924, 0x000424, 0x000424, - 0x100102, 0x02000D, 0x009144, 0x2AD986, - 0x000007, 0x0001FD, 0x018042, 0x08000A, - 0x000A44, 0x2ABB86, 0x018042, 0x0A000D, - 0x000820, 0x0002FD, 0x018040, 0x200007, - 0x00027D, 0x001020, 0x000606, 0x018040, - 0x0002F5, 0x010042, 0x08000A, 0x000904, - 0x2B2A86, 0x000007, 0x00037D, 0x018042, - 0x08000A, 0x000904, 0x2B5A86, 0x000007, - 0x000075, 0x002E7D, 0x010042, 0x0B804A, - 0x000020, 0x000904, 0x000686, 0x010040, - 0x31844A, 0x30048B, 0x000883, 0x00008D, - 0x000810, 0x28143A, 0x00008D, 0x000810, - 0x280C3A, 0x000675, 0x010042, 0x08000A, - 0x003815, 0x010924, 0x280502, 0x0B000D, - 0x000820, 0x0002F5, 0x010040, 0x000606, - 0x220007, 0x000464, 0x000464, 0x000606, - 0x000007, 0x000134, 0x007F8D, 0x00093C, - 0x281D12, 0x282512, 0x001F32, 0x0E0007, - 0x00010D, 0x00037D, 0x000820, 0x018040, - 0x05D2F4, 0x000007, 0x080007, 0x00037D, - 0x018042, 0x08000A, 0x000904, 0x2D0286, - 0x000007, 0x000606, 0x000007, 0x000007, - 0x000012, 0x100007, 0x320007, 0x600007, - 0x100080, 0x48001A, 0x004904, 0x2D6186, - 0x000007, 0x001210, 0x58003A, 0x000145, - 0x5C5D04, 0x000007, 0x000080, 0x48001A, - 0x004904, 0x2DB186, 0x000007, 0x001210, - 0x50003A, 0x005904, 0x2E0886, 0x000045, - 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524, - 0x004224, 0x500102, 0x200502, 0x000082, - 0x40001A, 0x004104, 0x2E3986, 0x000007, - 0x003865, 0x40001A, 0x004020, 0x00104D, - 0x04C184, 0x301B86, 0x000040, 0x040007, - 0x000165, 0x000145, 0x004020, 0x000040, - 0x000765, 0x080080, 0x40001A, 0x004104, - 0x2EC986, 0x000007, 0x001210, 0x40003A, - 0x004104, 0x2F2286, 0x00004D, 0x0000CD, - 0x004810, 0x20043A, 0x000882, 0x40001A, - 0x004104, 0x2F3186, 0x000007, 0x004820, - 0x005904, 0x300886, 0x000040, 0x0007E5, - 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0, - 0x4216E0, 0x021260, 0x000040, 0x000032, - 0x400075, 0x00007D, 0x07D574, 0x200512, - 0x000082, 0x40001A, 0x004104, 0x2FE186, - 0x000007, 0x037206, 0x640007, 0x060007, - 0x0000E5, 0x000020, 0x000040, 0x000A65, - 0x000020, 0x020040, 0x020040, 0x000040, - 0x000165, 0x000042, 0x70000A, 0x007104, - 0x30A286, 0x000007, 0x018206, 0x640007, - 0x050000, 0x007020, 0x000040, 0x037206, - 0x640007, 0x000007, 0x00306D, 0x028860, - 0x029060, 0x08000A, 0x028860, 0x008040, - 0x100012, 0x00100D, 0x009184, 0x314186, - 0x000E0D, 0x009184, 0x325186, 0x000007, - 0x300007, 0x001020, 0x003B6D, 0x008040, - 0x000080, 0x08001A, 0x000904, 0x316186, - 0x000007, 0x001220, 0x000DED, 0x008040, - 0x008042, 0x10000A, 0x40000D, 0x109544, - 0x000007, 0x001020, 0x000DED, 0x008040, - 0x008042, 0x20040A, 0x000082, 0x08001A, - 0x000904, 0x31F186, 0x000007, 0x003B6D, - 0x008042, 0x08000A, 0x000E15, 0x010984, - 0x329B86, 0x600007, 0x08001A, 0x000C15, - 0x010984, 0x328386, 0x000020, 0x1A0007, - 0x0002ED, 0x008040, 0x620007, 0x00306D, - 0x028042, 0x0A804A, 0x000820, 0x0A804A, - 0x000606, 0x10804A, 0x000007, 0x282512, - 0x001F32, 0x05D2F4, 0x54D104, 0x00735C, - 0x000786, 0x000007, 0x0C0007, 0x0A0007, - 0x1C0007, 0x003465, 0x020040, 0x004820, - 0x025060, 0x40000A, 0x024060, 0x000040, - 0x454944, 0x000007, 0x004020, 0x003AE5, - 0x000040, 0x0028E5, 0x000042, 0x48000A, - 0x004904, 0x386886, 0x002C65, 0x000042, - 0x40000A, 0x0000D5, 0x454104, 0x000007, - 0x000655, 0x054504, 0x34F286, 0x0001D5, - 0x054504, 0x34F086, 0x002B65, 0x000042, - 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4, - 0x000007, 0x454504, 0x000007, 0x0000CD, - 0x444944, 0x000007, 0x454504, 0x000007, - 0x00014D, 0x554944, 0x000007, 0x045144, - 0x34E986, 0x002C65, 0x000042, 0x48000A, - 0x4CD104, 0x000007, 0x04C144, 0x34F386, - 0x000007, 0x160007, 0x002CE5, 0x040042, - 0x40000A, 0x004020, 0x000040, 0x002965, - 0x000042, 0x40000A, 0x004104, 0x356086, - 0x000007, 0x002402, 0x36A206, 0x005C02, - 0x0025E5, 0x000042, 0x40000A, 0x004274, - 0x002AE5, 0x000042, 0x40000A, 0x004274, - 0x500112, 0x0029E5, 0x000042, 0x40000A, - 0x004234, 0x454104, 0x000007, 0x004020, - 0x000040, 0x003EE5, 0x000020, 0x000040, - 0x002DE5, 0x400152, 0x50000A, 0x045144, - 0x364A86, 0x0000C5, 0x003EE5, 0x004020, - 0x000040, 0x002BE5, 0x000042, 0x40000A, - 0x404254, 0x000007, 0x002AE5, 0x004020, - 0x000040, 0x500132, 0x040134, 0x005674, - 0x0029E5, 0x020042, 0x42000A, 0x000042, - 0x50000A, 0x05417C, 0x0028E5, 0x000042, - 0x48000A, 0x0000C5, 0x4CC144, 0x371086, - 0x0026E5, 0x0027E5, 0x020042, 0x40004A, - 0x50000A, 0x00423C, 0x00567C, 0x0028E5, - 0x004820, 0x000040, 0x281D12, 0x282512, - 0x001F72, 0x002965, 0x000042, 0x40000A, - 0x004104, 0x37AA86, 0x0E0007, 0x160007, - 0x1E0007, 0x003EE5, 0x000042, 0x40000A, - 0x004104, 0x37E886, 0x002D65, 0x000042, - 0x28340A, 0x003465, 0x020042, 0x42004A, - 0x004020, 0x4A004A, 0x50004A, 0x05D2F4, - 0x54D104, 0x00735C, 0x385186, 0x000007, - 0x000606, 0x080007, 0x0C0007, 0x080007, - 0x0A0007, 0x0001E5, 0x020045, 0x004020, - 0x000060, 0x000365, 0x000040, 0x002E65, - 0x001A20, 0x0A1A60, 0x000040, 0x003465, - 0x020042, 0x42004A, 0x004020, 0x4A004A, - 0x000606, 0x50004A, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000 -}; - -// -------------------------------------------- -// DS-1E Controller InstructionRAM Code -// 1999/06/21 -// Buf441 slot is Enabled. -// -------------------------------------------- -// 04/09 creat -// 04/12 stop nise fix -// 06/21 WorkingOff timming -static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = { - 0x000007, 0x240007, 0x0C0007, 0x1C0007, - 0x060007, 0x700002, 0x000020, 0x030040, - 0x007104, 0x004286, 0x030040, 0x000F0D, - 0x000810, 0x20043A, 0x000282, 0x00020D, - 0x000810, 0x20043A, 0x001282, 0x200E82, - 0x00800D, 0x000810, 0x20043A, 0x001A82, - 0x03460D, 0x000810, 0x10043A, 0x02EC0D, - 0x000810, 0x18043A, 0x00010D, 0x020015, - 0x0000FD, 0x000020, 0x038860, 0x039060, - 0x038060, 0x038040, 0x038040, 0x038040, - 0x018040, 0x000A7D, 0x038040, 0x038040, - 0x018040, 0x200402, 0x000882, 0x08001A, - 0x000904, 0x017186, 0x000007, 0x260007, - 0x400007, 0x000007, 0x03258D, 0x000810, - 0x18043A, 0x260007, 0x284402, 0x00087D, - 0x018042, 0x00160A, 0x05A206, 0x000007, - 0x440007, 0x00230D, 0x000810, 0x08043A, - 0x22FA06, 0x000007, 0x0007FD, 0x018042, - 0x08000A, 0x000904, 0x02AB86, 0x000195, - 0x090D04, 0x000007, 0x000820, 0x0000F5, - 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, - 0x018040, 0x000A7D, 0x038042, 0x13804A, - 0x18000A, 0x001820, 0x059060, 0x058860, - 0x018040, 0x0000FD, 0x018042, 0x70000A, - 0x000115, 0x071144, 0x033B86, 0x030000, - 0x007020, 0x036206, 0x018040, 0x00360D, - 0x000810, 0x08043A, 0x232206, 0x000007, - 0x02EC0D, 0x000810, 0x18043A, 0x019A06, - 0x000007, 0x240007, 0x000F8D, 0x000810, - 0x00163A, 0x002402, 0x005C02, 0x0028FD, - 0x000020, 0x018040, 0x08000D, 0x000815, - 0x510984, 0x000007, 0x00004D, 0x000E5D, - 0x000E02, 0x00430D, 0x000810, 0x08043A, - 0x2E1206, 0x000007, 0x00008D, 0x000924, - 0x000F02, 0x00470D, 0x000810, 0x08043A, - 0x2E1206, 0x000007, 0x480480, 0x001210, - 0x28043A, 0x00778D, 0x000810, 0x280C3A, - 0x00068D, 0x000810, 0x28143A, 0x284402, - 0x03258D, 0x000810, 0x18043A, 0x07FF8D, - 0x000820, 0x0002FD, 0x018040, 0x260007, - 0x200007, 0x0002FD, 0x018042, 0x08000A, - 0x000904, 0x051286, 0x000007, 0x240007, - 0x02EC0D, 0x000810, 0x18043A, 0x00387D, - 0x018042, 0x08000A, 0x001015, 0x010984, - 0x019B86, 0x000007, 0x01B206, 0x000007, - 0x0008FD, 0x018042, 0x18000A, 0x001904, - 0x22B886, 0x280007, 0x001810, 0x28043A, - 0x280C02, 0x00000D, 0x000810, 0x28143A, - 0x08808D, 0x000820, 0x0002FD, 0x018040, - 0x200007, 0x00020D, 0x189904, 0x000007, - 0x00402D, 0x0000BD, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x065A86, 0x000007, - 0x000100, 0x000A20, 0x00047D, 0x018040, - 0x018042, 0x20000A, 0x003015, 0x012144, - 0x036186, 0x000007, 0x002104, 0x036186, - 0x000007, 0x000F8D, 0x000810, 0x280C3A, - 0x023944, 0x07C986, 0x000007, 0x001810, - 0x28043A, 0x08810D, 0x000820, 0x0002FD, - 0x018040, 0x200007, 0x002810, 0x78003A, - 0x00788D, 0x000810, 0x08043A, 0x2A1206, - 0x000007, 0x00400D, 0x001015, 0x189904, - 0x292904, 0x393904, 0x000007, 0x070206, - 0x000007, 0x0004F5, 0x00007D, 0x000020, - 0x00008D, 0x010860, 0x018040, 0x00047D, - 0x038042, 0x21804A, 0x18000A, 0x021944, - 0x229086, 0x000007, 0x004075, 0x71F104, - 0x000007, 0x010042, 0x28000A, 0x002904, - 0x225886, 0x000007, 0x003C0D, 0x30A904, - 0x000007, 0x00077D, 0x018042, 0x08000A, - 0x000904, 0x08DA86, 0x00057D, 0x002820, - 0x03B060, 0x08F206, 0x018040, 0x003020, - 0x03A860, 0x018040, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x08FA86, 0x000007, - 0x00057D, 0x018042, 0x28040A, 0x000E8D, - 0x000810, 0x280C3A, 0x00000D, 0x000810, - 0x28143A, 0x09000D, 0x000820, 0x0002FD, - 0x018040, 0x200007, 0x003DFD, 0x000020, - 0x018040, 0x00107D, 0x009D8D, 0x000810, - 0x08043A, 0x2A1206, 0x000007, 0x000815, - 0x08001A, 0x010984, 0x0A5186, 0x00137D, - 0x200500, 0x280F20, 0x338F60, 0x3B8F60, - 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, - 0x038A60, 0x018040, 0x00107D, 0x018042, - 0x08000A, 0x000215, 0x010984, 0x3A8186, - 0x000007, 0x007FBD, 0x383DC4, 0x000007, - 0x001A7D, 0x001375, 0x018042, 0x09004A, - 0x10000A, 0x0B8D04, 0x139504, 0x000007, - 0x000820, 0x019060, 0x001104, 0x225886, - 0x010040, 0x0017FD, 0x018042, 0x08000A, - 0x000904, 0x225A86, 0x000007, 0x00197D, - 0x038042, 0x09804A, 0x10000A, 0x000924, - 0x001664, 0x0011FD, 0x038042, 0x2B804A, - 0x19804A, 0x00008D, 0x218944, 0x000007, - 0x002244, 0x0C1986, 0x000007, 0x001A64, - 0x002A24, 0x00197D, 0x080102, 0x100122, - 0x000820, 0x039060, 0x018040, 0x003DFD, - 0x00008D, 0x000820, 0x018040, 0x001375, - 0x001A7D, 0x010042, 0x09804A, 0x10000A, - 0x00021D, 0x0189E4, 0x2992E4, 0x309144, - 0x000007, 0x00060D, 0x000A15, 0x000C1D, - 0x001025, 0x00A9E4, 0x012BE4, 0x000464, - 0x01B3E4, 0x0232E4, 0x000464, 0x000464, - 0x000464, 0x000464, 0x00040D, 0x08B1C4, - 0x000007, 0x000820, 0x000BF5, 0x030040, - 0x00197D, 0x038042, 0x09804A, 0x000A24, - 0x08000A, 0x080E64, 0x000007, 0x100122, - 0x000820, 0x031060, 0x010040, 0x0064AC, - 0x00027D, 0x000020, 0x018040, 0x00107D, - 0x018042, 0x0011FD, 0x3B804A, 0x09804A, - 0x20000A, 0x000095, 0x1A1144, 0x00A144, - 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, - 0x0018FD, 0x018042, 0x0010FD, 0x09804A, - 0x28000A, 0x000095, 0x010924, 0x002A64, - 0x0E4986, 0x000007, 0x002904, 0x0E5A86, - 0x000007, 0x0E6206, 0x080002, 0x00008D, - 0x00387D, 0x000820, 0x018040, 0x00127D, - 0x018042, 0x10000A, 0x003904, 0x0F0986, - 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, - 0x000025, 0x0FB206, 0x00002D, 0x000015, - 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, - 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, - 0x400025, 0x00008D, 0x110944, 0x000007, - 0x00018D, 0x109504, 0x000007, 0x009164, - 0x000424, 0x000424, 0x000424, 0x100102, - 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, - 0x00018D, 0x00042D, 0x00008D, 0x109504, - 0x000007, 0x00020D, 0x109184, 0x000007, - 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, - 0x018040, 0x003BFD, 0x001020, 0x03A860, - 0x000815, 0x313184, 0x212184, 0x000007, - 0x03B060, 0x03A060, 0x018040, 0x0022FD, - 0x000095, 0x010924, 0x000424, 0x000424, - 0x001264, 0x100102, 0x000820, 0x039060, - 0x018040, 0x001924, 0x010F0D, 0x00397D, - 0x000820, 0x058040, 0x038042, 0x09844A, - 0x000606, 0x08040A, 0x000424, 0x000424, - 0x00117D, 0x018042, 0x08000A, 0x000A24, - 0x280502, 0x280C02, 0x09800D, 0x000820, - 0x0002FD, 0x018040, 0x200007, 0x0022FD, - 0x018042, 0x08000A, 0x000095, 0x280DC4, - 0x011924, 0x00197D, 0x018042, 0x0011FD, - 0x09804A, 0x10000A, 0x0000B5, 0x113144, - 0x0A8D04, 0x000007, 0x080A44, 0x129504, - 0x000007, 0x0023FD, 0x001020, 0x038040, - 0x101244, 0x000007, 0x000820, 0x039060, - 0x018040, 0x0002FD, 0x018042, 0x08000A, - 0x000904, 0x123286, 0x000007, 0x003BFD, - 0x000100, 0x000A10, 0x0B807A, 0x13804A, - 0x090984, 0x000007, 0x000095, 0x013D04, - 0x12B886, 0x10000A, 0x100002, 0x090984, - 0x000007, 0x038042, 0x11804A, 0x090D04, - 0x000007, 0x10000A, 0x090D84, 0x000007, - 0x00257D, 0x000820, 0x018040, 0x00010D, - 0x000810, 0x28143A, 0x00127D, 0x018042, - 0x20000A, 0x00197D, 0x018042, 0x00117D, - 0x31804A, 0x10000A, 0x003124, 0x013B8D, - 0x00397D, 0x000820, 0x058040, 0x038042, - 0x09844A, 0x000606, 0x08040A, 0x300102, - 0x003124, 0x000424, 0x000424, 0x001224, - 0x280502, 0x001A4C, 0x143986, 0x700002, - 0x00002D, 0x030000, 0x00387D, 0x018042, - 0x10000A, 0x146206, 0x002124, 0x0000AD, - 0x100002, 0x00010D, 0x000924, 0x006B24, - 0x014A0D, 0x00397D, 0x000820, 0x058040, - 0x038042, 0x09844A, 0x000606, 0x08040A, - 0x003264, 0x00008D, 0x000A24, 0x001020, - 0x00227D, 0x018040, 0x014F8D, 0x000810, - 0x08043A, 0x2B5A06, 0x000007, 0x002820, - 0x00207D, 0x018040, 0x00117D, 0x038042, - 0x13804A, 0x33800A, 0x00387D, 0x018042, - 0x08000A, 0x000904, 0x177286, 0x000007, - 0x00008D, 0x030964, 0x015B0D, 0x00397D, - 0x000820, 0x058040, 0x038042, 0x09844A, - 0x000606, 0x08040A, 0x380102, 0x000424, - 0x000424, 0x001224, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x15DA86, 0x000007, - 0x280502, 0x001A4C, 0x177186, 0x000007, - 0x032164, 0x00632C, 0x003DFD, 0x018042, - 0x08000A, 0x000095, 0x090904, 0x000007, - 0x000820, 0x001A4C, 0x169986, 0x018040, - 0x030000, 0x16B206, 0x002124, 0x00010D, - 0x000924, 0x006B24, 0x016F0D, 0x00397D, - 0x000820, 0x058040, 0x038042, 0x09844A, - 0x000606, 0x08040A, 0x003A64, 0x000095, - 0x001224, 0x0002FD, 0x018042, 0x08000A, - 0x000904, 0x171286, 0x000007, 0x01760D, - 0x000810, 0x08043A, 0x2B5A06, 0x000007, - 0x160A06, 0x000007, 0x007020, 0x08010A, - 0x10012A, 0x0020FD, 0x038860, 0x039060, - 0x018040, 0x00227D, 0x018042, 0x003DFD, - 0x08000A, 0x31844A, 0x000904, 0x181086, - 0x18008B, 0x00008D, 0x189904, 0x00312C, - 0x18E206, 0x000007, 0x00324C, 0x186B86, - 0x000007, 0x001904, 0x186886, 0x000007, - 0x000095, 0x199144, 0x00222C, 0x003124, - 0x00636C, 0x000E3D, 0x001375, 0x000BFD, - 0x010042, 0x09804A, 0x10000A, 0x038AEC, - 0x0393EC, 0x00224C, 0x18E186, 0x000007, - 0x00008D, 0x189904, 0x00226C, 0x00322C, - 0x30050A, 0x301DAB, 0x002083, 0x0018FD, - 0x018042, 0x08000A, 0x018924, 0x300502, - 0x001083, 0x001875, 0x010042, 0x10000A, - 0x00008D, 0x010924, 0x001375, 0x330542, - 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, - 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, - 0x006083, 0x0002F5, 0x010042, 0x08000A, - 0x000904, 0x19B286, 0x000007, 0x001E2D, - 0x0005FD, 0x018042, 0x08000A, 0x028924, - 0x280502, 0x00060D, 0x000810, 0x280C3A, - 0x00008D, 0x000810, 0x28143A, 0x0A808D, - 0x000820, 0x0002F5, 0x010040, 0x220007, - 0x001275, 0x030042, 0x21004A, 0x00008D, - 0x1A0944, 0x000007, 0x01AB8D, 0x000810, - 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, - 0x030042, 0x0D004A, 0x10000A, 0x089144, - 0x000007, 0x000820, 0x010040, 0x0025F5, - 0x0A3144, 0x000007, 0x000820, 0x032860, - 0x030040, 0x00217D, 0x038042, 0x0B804A, - 0x10000A, 0x000820, 0x031060, 0x030040, - 0x00008D, 0x000124, 0x00012C, 0x000E64, - 0x001A64, 0x00636C, 0x08010A, 0x10012A, - 0x000820, 0x031060, 0x030040, 0x0020FD, - 0x018042, 0x08000A, 0x00227D, 0x018042, - 0x10000A, 0x000820, 0x031060, 0x030040, - 0x00197D, 0x018042, 0x08000A, 0x0022FD, - 0x038042, 0x10000A, 0x000820, 0x031060, - 0x030040, 0x090D04, 0x000007, 0x000820, - 0x030040, 0x038042, 0x0B804A, 0x10000A, - 0x000820, 0x031060, 0x030040, 0x038042, - 0x13804A, 0x19804A, 0x110D04, 0x198D04, - 0x000007, 0x08000A, 0x001020, 0x031860, - 0x030860, 0x030040, 0x00008D, 0x0B0944, - 0x000007, 0x000820, 0x010040, 0x0005F5, - 0x030042, 0x08000A, 0x000820, 0x010040, - 0x0000F5, 0x010042, 0x08000A, 0x000904, - 0x1D9886, 0x001E75, 0x030042, 0x01044A, - 0x000C0A, 0x1DAA06, 0x000007, 0x000402, - 0x000C02, 0x00177D, 0x001AF5, 0x018042, - 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, - 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, - 0x00043D, 0x0013F5, 0x001AFD, 0x030042, - 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, - 0x089144, 0x19A144, 0x0389E4, 0x0399EC, - 0x005502, 0x005D0A, 0x030042, 0x0B004A, - 0x1B804A, 0x13804A, 0x20000A, 0x089144, - 0x19A144, 0x0389E4, 0x0399EC, 0x006502, - 0x006D0A, 0x030042, 0x0B004A, 0x19004A, - 0x2B804A, 0x13804A, 0x21804A, 0x30000A, - 0x089144, 0x19A144, 0x2AB144, 0x0389E4, - 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, - 0x000702, 0x00107D, 0x000415, 0x018042, - 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, - 0x0019FD, 0x010042, 0x09804A, 0x10000A, - 0x000934, 0x001674, 0x0029F5, 0x010042, - 0x10000A, 0x00917C, 0x002075, 0x010042, - 0x08000A, 0x000904, 0x200A86, 0x0026F5, - 0x0027F5, 0x030042, 0x09004A, 0x10000A, - 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, - 0x010042, 0x51804A, 0x48000A, 0x160007, - 0x001075, 0x010042, 0x282C0A, 0x281D12, - 0x282512, 0x001F32, 0x1E0007, 0x0E0007, - 0x001975, 0x010042, 0x002DF5, 0x0D004A, - 0x10000A, 0x009144, 0x20EA86, 0x010042, - 0x28340A, 0x000E5D, 0x00008D, 0x000375, - 0x000820, 0x010040, 0x05D2F4, 0x54D104, - 0x00735C, 0x218B86, 0x000007, 0x0C0007, - 0x080007, 0x0A0007, 0x02178D, 0x000810, - 0x08043A, 0x34B206, 0x000007, 0x219206, - 0x000007, 0x080007, 0x002275, 0x010042, - 0x20000A, 0x002104, 0x225886, 0x001E2D, - 0x0002F5, 0x010042, 0x08000A, 0x000904, - 0x21CA86, 0x000007, 0x002010, 0x30043A, - 0x00057D, 0x0180C3, 0x08000A, 0x028924, - 0x280502, 0x280C02, 0x0A810D, 0x000820, - 0x0002F5, 0x010040, 0x220007, 0x0004FD, - 0x018042, 0x70000A, 0x030000, 0x007020, - 0x07FA06, 0x018040, 0x022B8D, 0x000810, - 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, - 0x018042, 0x08000A, 0x000904, 0x22C286, - 0x000007, 0x020206, 0x000007, 0x000875, - 0x0009FD, 0x00010D, 0x234206, 0x000295, - 0x000B75, 0x00097D, 0x00000D, 0x000515, - 0x010042, 0x18000A, 0x001904, 0x2A0086, - 0x0006F5, 0x001020, 0x010040, 0x0004F5, - 0x000820, 0x010040, 0x000775, 0x010042, - 0x09804A, 0x10000A, 0x001124, 0x000904, - 0x23F286, 0x000815, 0x080102, 0x101204, - 0x241206, 0x000575, 0x081204, 0x000007, - 0x100102, 0x000575, 0x000425, 0x021124, - 0x100102, 0x000820, 0x031060, 0x010040, - 0x001924, 0x2A0086, 0x00008D, 0x000464, - 0x009D04, 0x291086, 0x180102, 0x000575, - 0x010042, 0x28040A, 0x00018D, 0x000924, - 0x280D02, 0x00000D, 0x000924, 0x281502, - 0x10000D, 0x000820, 0x0002F5, 0x010040, - 0x200007, 0x001175, 0x0002FD, 0x018042, - 0x08000A, 0x000904, 0x24FA86, 0x000007, - 0x000100, 0x080B20, 0x130B60, 0x1B0B60, - 0x030A60, 0x010040, 0x050042, 0x3D004A, - 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, - 0x010042, 0x28140A, 0x0004F5, 0x010042, - 0x08000A, 0x000315, 0x010D04, 0x260286, - 0x004015, 0x000095, 0x010D04, 0x25F086, - 0x100022, 0x10002A, 0x261A06, 0x000007, - 0x333104, 0x2AA904, 0x000007, 0x032124, - 0x280502, 0x284402, 0x001124, 0x400102, - 0x000424, 0x000424, 0x003224, 0x00292C, - 0x00636C, 0x277386, 0x000007, 0x02B164, - 0x000464, 0x000464, 0x00008D, 0x000A64, - 0x280D02, 0x10008D, 0x000820, 0x0002F5, - 0x010040, 0x220007, 0x00008D, 0x38B904, - 0x000007, 0x03296C, 0x30010A, 0x0002F5, - 0x010042, 0x08000A, 0x000904, 0x270286, - 0x000007, 0x00212C, 0x28050A, 0x00316C, - 0x00046C, 0x00046C, 0x28450A, 0x001124, - 0x006B64, 0x100102, 0x00008D, 0x01096C, - 0x280D0A, 0x10010D, 0x000820, 0x0002F5, - 0x010040, 0x220007, 0x004124, 0x000424, - 0x000424, 0x003224, 0x300102, 0x032944, - 0x27FA86, 0x000007, 0x300002, 0x0004F5, - 0x010042, 0x08000A, 0x000315, 0x010D04, - 0x284086, 0x003124, 0x000464, 0x300102, - 0x0002F5, 0x010042, 0x08000A, 0x000904, - 0x284A86, 0x000007, 0x284402, 0x003124, - 0x300502, 0x003924, 0x300583, 0x000883, - 0x0005F5, 0x010042, 0x28040A, 0x00008D, - 0x008124, 0x280D02, 0x00008D, 0x008124, - 0x281502, 0x10018D, 0x000820, 0x0002F5, - 0x010040, 0x220007, 0x001025, 0x000575, - 0x030042, 0x09004A, 0x10000A, 0x0A0904, - 0x121104, 0x000007, 0x001020, 0x050860, - 0x050040, 0x0006FD, 0x018042, 0x09004A, - 0x10000A, 0x0000A5, 0x0A0904, 0x121104, - 0x000007, 0x000820, 0x019060, 0x010040, - 0x0002F5, 0x010042, 0x08000A, 0x000904, - 0x29CA86, 0x000007, 0x244206, 0x000007, - 0x000606, 0x000007, 0x0002F5, 0x010042, - 0x08000A, 0x000904, 0x2A1A86, 0x000007, - 0x000100, 0x080B20, 0x138B60, 0x1B8B60, - 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, - 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, - 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, - 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, - 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, - 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, - 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, - 0x038A60, 0x000606, 0x018040, 0x00008D, - 0x000A64, 0x280D02, 0x000A24, 0x00027D, - 0x018042, 0x10000A, 0x001224, 0x0003FD, - 0x018042, 0x08000A, 0x000904, 0x2C0A86, - 0x000007, 0x00018D, 0x000A24, 0x000464, - 0x000464, 0x080102, 0x000924, 0x000424, - 0x000424, 0x100102, 0x02000D, 0x009144, - 0x2C6186, 0x000007, 0x0001FD, 0x018042, - 0x08000A, 0x000A44, 0x2C4386, 0x018042, - 0x0A000D, 0x000820, 0x0002FD, 0x018040, - 0x200007, 0x00027D, 0x001020, 0x000606, - 0x018040, 0x0002F5, 0x010042, 0x08000A, - 0x000904, 0x2CB286, 0x000007, 0x00037D, - 0x018042, 0x08000A, 0x000904, 0x2CE286, - 0x000007, 0x000075, 0x002E7D, 0x010042, - 0x0B804A, 0x000020, 0x000904, 0x000686, - 0x010040, 0x31844A, 0x30048B, 0x000883, - 0x00008D, 0x000810, 0x28143A, 0x00008D, - 0x000810, 0x280C3A, 0x000675, 0x010042, - 0x08000A, 0x003815, 0x010924, 0x280502, - 0x0B000D, 0x000820, 0x0002F5, 0x010040, - 0x000606, 0x220007, 0x000464, 0x000464, - 0x000606, 0x000007, 0x000134, 0x007F8D, - 0x00093C, 0x281D12, 0x282512, 0x001F32, - 0x0E0007, 0x00010D, 0x00037D, 0x000820, - 0x018040, 0x05D2F4, 0x000007, 0x080007, - 0x00037D, 0x018042, 0x08000A, 0x000904, - 0x2E8A86, 0x000007, 0x000606, 0x000007, - 0x000007, 0x000012, 0x100007, 0x320007, - 0x600007, 0x460007, 0x100080, 0x48001A, - 0x004904, 0x2EF186, 0x000007, 0x001210, - 0x58003A, 0x000145, 0x5C5D04, 0x000007, - 0x000080, 0x48001A, 0x004904, 0x2F4186, - 0x000007, 0x001210, 0x50003A, 0x005904, - 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, - 0x7FFF7D, 0x07D524, 0x004224, 0x500102, - 0x200502, 0x000082, 0x40001A, 0x004104, - 0x2FC986, 0x000007, 0x003865, 0x40001A, - 0x004020, 0x00104D, 0x04C184, 0x31AB86, - 0x000040, 0x040007, 0x000165, 0x000145, - 0x004020, 0x000040, 0x000765, 0x080080, - 0x40001A, 0x004104, 0x305986, 0x000007, - 0x001210, 0x40003A, 0x004104, 0x30B286, - 0x00004D, 0x0000CD, 0x004810, 0x20043A, - 0x000882, 0x40001A, 0x004104, 0x30C186, - 0x000007, 0x004820, 0x005904, 0x319886, - 0x000040, 0x0007E5, 0x200480, 0x2816A0, - 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, - 0x000040, 0x000032, 0x400075, 0x00007D, - 0x07D574, 0x200512, 0x000082, 0x40001A, - 0x004104, 0x317186, 0x000007, 0x038A06, - 0x640007, 0x0000E5, 0x000020, 0x000040, - 0x000A65, 0x000020, 0x020040, 0x020040, - 0x000040, 0x000165, 0x000042, 0x70000A, - 0x007104, 0x323286, 0x000007, 0x060007, - 0x019A06, 0x640007, 0x050000, 0x007020, - 0x000040, 0x038A06, 0x640007, 0x000007, - 0x00306D, 0x028860, 0x029060, 0x08000A, - 0x028860, 0x008040, 0x100012, 0x00100D, - 0x009184, 0x32D186, 0x000E0D, 0x009184, - 0x33E186, 0x000007, 0x300007, 0x001020, - 0x003B6D, 0x008040, 0x000080, 0x08001A, - 0x000904, 0x32F186, 0x000007, 0x001220, - 0x000DED, 0x008040, 0x008042, 0x10000A, - 0x40000D, 0x109544, 0x000007, 0x001020, - 0x000DED, 0x008040, 0x008042, 0x20040A, - 0x000082, 0x08001A, 0x000904, 0x338186, - 0x000007, 0x003B6D, 0x008042, 0x08000A, - 0x000E15, 0x010984, 0x342B86, 0x600007, - 0x08001A, 0x000C15, 0x010984, 0x341386, - 0x000020, 0x1A0007, 0x0002ED, 0x008040, - 0x620007, 0x00306D, 0x028042, 0x0A804A, - 0x000820, 0x0A804A, 0x000606, 0x10804A, - 0x000007, 0x282512, 0x001F32, 0x05D2F4, - 0x54D104, 0x00735C, 0x000786, 0x000007, - 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, - 0x020040, 0x004820, 0x025060, 0x40000A, - 0x024060, 0x000040, 0x454944, 0x000007, - 0x004020, 0x003AE5, 0x000040, 0x0028E5, - 0x000042, 0x48000A, 0x004904, 0x39F886, - 0x002C65, 0x000042, 0x40000A, 0x0000D5, - 0x454104, 0x000007, 0x000655, 0x054504, - 0x368286, 0x0001D5, 0x054504, 0x368086, - 0x002B65, 0x000042, 0x003AE5, 0x50004A, - 0x40000A, 0x45C3D4, 0x000007, 0x454504, - 0x000007, 0x0000CD, 0x444944, 0x000007, - 0x454504, 0x000007, 0x00014D, 0x554944, - 0x000007, 0x045144, 0x367986, 0x002C65, - 0x000042, 0x48000A, 0x4CD104, 0x000007, - 0x04C144, 0x368386, 0x000007, 0x160007, - 0x002CE5, 0x040042, 0x40000A, 0x004020, - 0x000040, 0x002965, 0x000042, 0x40000A, - 0x004104, 0x36F086, 0x000007, 0x002402, - 0x383206, 0x005C02, 0x0025E5, 0x000042, - 0x40000A, 0x004274, 0x002AE5, 0x000042, - 0x40000A, 0x004274, 0x500112, 0x0029E5, - 0x000042, 0x40000A, 0x004234, 0x454104, - 0x000007, 0x004020, 0x000040, 0x003EE5, - 0x000020, 0x000040, 0x002DE5, 0x400152, - 0x50000A, 0x045144, 0x37DA86, 0x0000C5, - 0x003EE5, 0x004020, 0x000040, 0x002BE5, - 0x000042, 0x40000A, 0x404254, 0x000007, - 0x002AE5, 0x004020, 0x000040, 0x500132, - 0x040134, 0x005674, 0x0029E5, 0x020042, - 0x42000A, 0x000042, 0x50000A, 0x05417C, - 0x0028E5, 0x000042, 0x48000A, 0x0000C5, - 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, - 0x020042, 0x40004A, 0x50000A, 0x00423C, - 0x00567C, 0x0028E5, 0x004820, 0x000040, - 0x281D12, 0x282512, 0x001F72, 0x002965, - 0x000042, 0x40000A, 0x004104, 0x393A86, - 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, - 0x000042, 0x40000A, 0x004104, 0x397886, - 0x002D65, 0x000042, 0x28340A, 0x003465, - 0x020042, 0x42004A, 0x004020, 0x4A004A, - 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, - 0x39E186, 0x000007, 0x000606, 0x080007, - 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, - 0x020045, 0x004020, 0x000060, 0x000365, - 0x000040, 0x002E65, 0x001A20, 0x0A1A60, - 0x000040, 0x003465, 0x020042, 0x42004A, - 0x004020, 0x4A004A, 0x000606, 0x50004A, - 0x0017FD, 0x018042, 0x08000A, 0x000904, - 0x225A86, 0x000007, 0x00107D, 0x018042, - 0x0011FD, 0x33804A, 0x19804A, 0x20000A, - 0x000095, 0x2A1144, 0x01A144, 0x3B9086, - 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, - 0x018042, 0x0010FD, 0x09804A, 0x38000A, - 0x000095, 0x010924, 0x003A64, 0x3B8186, - 0x000007, 0x003904, 0x3B9286, 0x000007, - 0x3B9A06, 0x00000D, 0x00008D, 0x000820, - 0x00387D, 0x018040, 0x700002, 0x00117D, - 0x018042, 0x00197D, 0x29804A, 0x30000A, - 0x380002, 0x003124, 0x000424, 0x000424, - 0x002A24, 0x280502, 0x00068D, 0x000810, - 0x28143A, 0x00750D, 0x00B124, 0x002264, - 0x3D0386, 0x284402, 0x000810, 0x280C3A, - 0x0B800D, 0x000820, 0x0002FD, 0x018040, - 0x200007, 0x00758D, 0x00B124, 0x100102, - 0x012144, 0x3E4986, 0x001810, 0x10003A, - 0x00387D, 0x018042, 0x08000A, 0x000904, - 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, - 0x00008D, 0x023164, 0x000A64, 0x280D02, - 0x0B808D, 0x000820, 0x0002FD, 0x018040, - 0x200007, 0x00387D, 0x018042, 0x08000A, - 0x000904, 0x3E3286, 0x030000, 0x0002FD, - 0x018042, 0x08000A, 0x000904, 0x3D8286, - 0x000007, 0x002810, 0x28043A, 0x00750D, - 0x030924, 0x002264, 0x280D02, 0x02316C, - 0x28450A, 0x0B810D, 0x000820, 0x0002FD, - 0x018040, 0x200007, 0x00008D, 0x000A24, - 0x3E4A06, 0x100102, 0x001810, 0x10003A, - 0x0000BD, 0x003810, 0x30043A, 0x00187D, - 0x018042, 0x0018FD, 0x09804A, 0x20000A, - 0x0000AD, 0x028924, 0x07212C, 0x001010, - 0x300583, 0x300D8B, 0x3014BB, 0x301C83, - 0x002083, 0x00137D, 0x038042, 0x33844A, - 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, - 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, - 0x001E0D, 0x0005FD, 0x018042, 0x20000A, - 0x020924, 0x00068D, 0x00A96C, 0x00009D, - 0x0002FD, 0x018042, 0x08000A, 0x000904, - 0x3F6A86, 0x000007, 0x280502, 0x280D0A, - 0x284402, 0x001810, 0x28143A, 0x0C008D, - 0x000820, 0x0002FD, 0x018040, 0x220007, - 0x003904, 0x225886, 0x001E0D, 0x00057D, - 0x018042, 0x20000A, 0x020924, 0x0000A5, - 0x0002FD, 0x018042, 0x08000A, 0x000904, - 0x402A86, 0x000007, 0x280502, 0x280C02, - 0x002010, 0x28143A, 0x0C010D, 0x000820, - 0x0002FD, 0x018040, 0x225A06, 0x220007, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000 -}; - -#endif //_HWMCODE_ diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 6298b29..2164e34 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1994,65 +1994,6 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip) } } -#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL - -#include "ymfpci_image.h" - -static struct firmware snd_ymfpci_dsp_microcode = { - .size = YDSXG_DSPLENGTH, - .data = (u8 *)DspInst, -}; -static struct firmware snd_ymfpci_controller_microcode = { - .size = YDSXG_CTRLLENGTH, - .data = (u8 *)CntrlInst, -}; -static struct firmware snd_ymfpci_controller_1e_microcode = { - .size = YDSXG_CTRLLENGTH, - .data = (u8 *)CntrlInst1E, -}; - -#ifdef __BIG_ENDIAN -static int microcode_swapped; -static DEFINE_MUTEX(microcode_swap); - -static void snd_ymfpci_convert_to_le(const struct firmware *fw) -{ - int i; - u32 *data = (u32 *)fw->data; - - for (i = 0; i < fw->size / 4; ++i) - cpu_to_le32s(&data[i]); -} -#endif - -static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) -{ -#ifdef __BIG_ENDIAN - mutex_lock(µcode_swap); - if (!microcode_swapped) { - snd_ymfpci_convert_to_le(&snd_ymfpci_dsp_microcode); - snd_ymfpci_convert_to_le(&snd_ymfpci_controller_1e_microcode); - snd_ymfpci_convert_to_le(&snd_ymfpci_controller_microcode); - microcode_swapped = 1; - } - mutex_unlock(µcode_swap); -#endif - - chip->dsp_microcode = &snd_ymfpci_dsp_microcode; - if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || - chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || - chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || - chip->device_id == PCI_DEVICE_ID_YAMAHA_754) - chip->controller_microcode = - &snd_ymfpci_controller_1e_microcode; - else - chip->controller_microcode = - &snd_ymfpci_controller_microcode; - return 0; -} - -#else /* use fw_loader */ - static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) { int err, is_1e; @@ -2091,8 +2032,6 @@ MODULE_FIRMWARE("yamaha/ds1_dsp.fw"); MODULE_FIRMWARE("yamaha/ds1_ctrl.fw"); MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw"); -#endif - static void snd_ymfpci_download_image(struct snd_ymfpci *chip) { int i; @@ -2273,10 +2212,8 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); pci_disable_device(chip->pci); -#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL release_firmware(chip->dsp_microcode); release_firmware(chip->controller_microcode); -#endif kfree(chip); return 0; } -- cgit v0.10.2 From 0f805b86c9492c294c710de8539a8be68b521a86 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 16:39:16 +0300 Subject: smctr: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 5f1c507..fa73e6e 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -59,7 +60,6 @@ #endif #include "smctr.h" /* Our Stuff */ -#include "smctr_firmware.h" /* SMC adapter firmware */ static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n"; static const char cardname[] = "smctr"; @@ -103,7 +103,8 @@ static int smctr_clear_trc_reset(int ioaddr); static int smctr_close(struct net_device *dev); /* D */ -static int smctr_decode_firmware(struct net_device *dev); +static int smctr_decode_firmware(struct net_device *dev, + const struct firmware *fw); static int smctr_disable_16bit(struct net_device *dev); static int smctr_disable_adapter_ctrl_store(struct net_device *dev); static int smctr_disable_bic_int(struct net_device *dev); @@ -748,7 +749,8 @@ static int smctr_close(struct net_device *dev) return (0); } -static int smctr_decode_firmware(struct net_device *dev) +static int smctr_decode_firmware(struct net_device *dev, + const struct firmware *fw) { struct net_local *tp = netdev_priv(dev); short bit = 0x80, shift = 12; @@ -762,10 +764,10 @@ static int smctr_decode_firmware(struct net_device *dev) if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name); - weight = *(long *)(tp->ptr_ucode + WEIGHT_OFFSET); - tsize = *(__u8 *)(tp->ptr_ucode + TREE_SIZE_OFFSET); - tree = (DECODE_TREE_NODE *)(tp->ptr_ucode + TREE_OFFSET); - ucode = (__u8 *)(tp->ptr_ucode + TREE_OFFSET + weight = *(long *)(fw->data + WEIGHT_OFFSET); + tsize = *(__u8 *)(fw->data + TREE_SIZE_OFFSET); + tree = (DECODE_TREE_NODE *)(fw->data + TREE_OFFSET); + ucode = (__u8 *)(fw->data + TREE_OFFSET + (tsize * sizeof(DECODE_TREE_NODE))); mem = (__u16 *)(tp->ram_access); @@ -2963,34 +2965,44 @@ static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) static int smctr_load_firmware(struct net_device *dev) { struct net_local *tp = netdev_priv(dev); + const struct firmware *fw; __u16 i, checksum = 0; int err = 0; if(smctr_debug > 10) printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name); - tp->ptr_ucode = smctr_code; + if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) { + printk(KERN_ERR "%s: firmware not found\n", dev->name); + return (UCODE_NOT_PRESENT); + } + tp->num_of_tx_buffs = 4; tp->mode_bits |= UMAC; tp->receive_mask = 0; tp->max_packet_size = 4177; /* Can only upload the firmware once per adapter reset. */ - if(tp->microcode_version != 0) - return (UCODE_PRESENT); + if (tp->microcode_version != 0) { + err = (UCODE_PRESENT); + goto out; + } /* Verify the firmware exists and is there in the right amount. */ - if (!tp->ptr_ucode - || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET) < UCODE_VERSION)) + if (!fw->data + || (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION)) { - return (UCODE_NOT_PRESENT); + err = (UCODE_NOT_PRESENT); + goto out; } /* UCODE_SIZE is not included in Checksum. */ - for(i = 0; i < *((__u16 *)(tp->ptr_ucode + UCODE_SIZE_OFFSET)); i += 2) - checksum += *((__u16 *)(tp->ptr_ucode + 2 + i)); - if(checksum) - return (UCODE_NOT_PRESENT); + for(i = 0; i < *((__u16 *)(fw->data + UCODE_SIZE_OFFSET)); i += 2) + checksum += *((__u16 *)(fw->data + 2 + i)); + if (checksum) { + err = (UCODE_NOT_PRESENT); + goto out; + } /* At this point we have a valid firmware image, lets kick it on up. */ smctr_enable_adapter_ram(dev); @@ -2998,7 +3010,7 @@ static int smctr_load_firmware(struct net_device *dev) smctr_set_page(dev, (__u8 *)tp->ram_access); if((smctr_checksum_firmware(dev)) - || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET) + || (*(fw->data + UCODE_VERSION_OFFSET) > tp->microcode_version)) { smctr_enable_adapter_ctrl_store(dev); @@ -3007,9 +3019,9 @@ static int smctr_load_firmware(struct net_device *dev) for(i = 0; i < CS_RAM_SIZE; i += 2) *((__u16 *)(tp->ram_access + i)) = 0; - smctr_decode_firmware(dev); + smctr_decode_firmware(dev, fw); - tp->microcode_version = *(tp->ptr_ucode + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET)) + tp->microcode_version = *(fw->data + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET)) = (tp->microcode_version << 8); *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET)) = ~(tp->microcode_version << 8) + 1; @@ -3023,7 +3035,8 @@ static int smctr_load_firmware(struct net_device *dev) err = UCODE_PRESENT; smctr_disable_16bit(dev); - + out: + release_firmware(fw); return (err); } @@ -5651,6 +5664,7 @@ static int io[SMCTR_MAX_ADAPTERS]; static int irq[SMCTR_MAX_ADAPTERS]; MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("tr_smctr.bin"); module_param_array(io, int, NULL, 0); module_param_array(irq, int, NULL, 0); diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h index 88dfa2e..52df7dd 100644 --- a/drivers/net/tokenring/smctr.h +++ b/drivers/net/tokenring/smctr.h @@ -1042,8 +1042,6 @@ typedef struct net_local { __u16 functional_address[2]; __u16 bitwise_group_address[2]; - const __u8 *ptr_ucode; - __u8 cleanup; struct sk_buff_head SendSkbQueue; diff --git a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h deleted file mode 100644 index 292e50ddf..0000000 --- a/drivers/net/tokenring/smctr_firmware.h +++ /dev/null @@ -1,978 +0,0 @@ -/* - * The firmware this driver downloads into the tokenring card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * This firmware is licensed to you strictly for use in conjunction - * with the use of SMC TokenRing adapters. There is no waranty - * expressed or implied about its fitness for any purpose. - */ - -/* smctr_firmware.h: SMC TokenRing driver firmware dump for Linux. - * - * Notes: - * - This is an 8K binary image. (MCT.BIN v6.3C1 03/01/95) - * - * Authors: - * - Jay Schulist - */ - - -#if defined(CONFIG_SMCTR) || defined(CONFIG_SMCTR_MODULE) - -static const unsigned char smctr_code[] = { - 0x0BC, 0x01D, 0x012, 0x03B, 0x063, 0x0B4, 0x0E9, 0x000, - 0x000, 0x01F, 0x000, 0x001, 0x001, 0x000, 0x002, 0x005, - 0x001, 0x000, 0x006, 0x003, 0x001, 0x000, 0x004, 0x009, - 0x001, 0x000, 0x00A, 0x007, 0x001, 0x000, 0x008, 0x00B, - 0x001, 0x000, 0x00C, 0x000, 0x000, 0x000, 0x000, 0x00F, - 0x001, 0x000, 0x010, 0x00D, 0x001, 0x000, 0x00E, 0x013, - 0x001, 0x000, 0x014, 0x011, 0x001, 0x000, 0x012, 0x000, - 0x000, 0x005, 0x000, 0x015, 0x001, 0x000, 0x016, 0x019, - 0x001, 0x000, 0x01A, 0x017, 0x001, 0x000, 0x018, 0x000, - 0x000, 0x00E, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000, - 0x000, 0x004, 0x000, 0x01B, 0x001, 0x000, 0x01C, 0x000, - 0x000, 0x007, 0x000, 0x000, 0x000, 0x00F, 0x000, 0x000, - 0x000, 0x00B, 0x000, 0x01D, 0x001, 0x000, 0x01E, 0x000, - 0x000, 0x008, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, - 0x000, 0x00C, 0x000, 0x000, 0x000, 0x006, 0x000, 0x000, - 0x000, 0x00D, 0x000, 0x000, 0x000, 0x003, 0x000, 0x000, - 0x000, 0x00A, 0x000, 0x000, 0x000, 0x009, 0x000, 0x004, - 0x078, 0x0C6, 0x0BC, 0x001, 0x094, 0x004, 0x093, 0x080, - 0x0C8, 0x040, 0x062, 0x0E9, 0x0DA, 0x01C, 0x02C, 0x015, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x058, - 0x00B, 0x0E9, 0x0E5, 0x0D5, 0x095, 0x0C1, 0x09D, 0x077, - 0x0CE, 0x0BB, 0x0A0, 0x06E, 0x01C, 0x005, 0x0F6, 0x077, - 0x0C6, 0x002, 0x0FA, 0x096, 0x070, 0x0E8, 0x01D, 0x0C0, - 0x017, 0x00E, 0x002, 0x0FA, 0x058, 0x07D, 0x0C0, 0x05F, - 0x072, 0x0CE, 0x0EC, 0x0A4, 0x0C3, 0x084, 0x090, 0x07A, - 0x030, 0x0CD, 0x08D, 0x079, 0x019, 0x0E7, 0x06C, 0x024, - 0x027, 0x09C, 0x008, 0x039, 0x007, 0x038, 0x0A8, 0x04A, - 0x04C, 0x0EA, 0x04D, 0x098, 0x09B, 0x024, 0x04C, 0x0C0, - 0x026, 0x0D3, 0x0E7, 0x054, 0x05A, 0x04D, 0x0F2, 0x04C, - 0x00C, 0x013, 0x023, 0x049, 0x090, 0x032, 0x06E, 0x0A4, - 0x0DF, 0x093, 0x071, 0x013, 0x077, 0x026, 0x0E1, 0x026, - 0x0F8, 0x026, 0x00C, 0x04C, 0x012, 0x026, 0x008, 0x009, - 0x082, 0x082, 0x060, 0x0A9, 0x030, 0x079, 0x036, 0x0B0, - 0x0B2, 0x0A8, 0x0A7, 0x072, 0x064, 0x08F, 0x09B, 0x033, - 0x033, 0x0F9, 0x0B8, 0x039, 0x0D5, 0x011, 0x073, 0x0AA, - 0x075, 0x026, 0x05D, 0x026, 0x051, 0x093, 0x02A, 0x049, - 0x094, 0x0C9, 0x095, 0x089, 0x0BC, 0x04D, 0x0C8, 0x09B, - 0x080, 0x09B, 0x0A0, 0x099, 0x006, 0x04C, 0x086, 0x026, - 0x058, 0x09B, 0x0A4, 0x09B, 0x099, 0x037, 0x062, 0x06C, - 0x067, 0x09B, 0x033, 0x030, 0x0BF, 0x036, 0x066, 0x061, - 0x0BF, 0x036, 0x0EC, 0x0C5, 0x0BD, 0x066, 0x082, 0x05A, - 0x050, 0x031, 0x0D5, 0x09D, 0x098, 0x018, 0x029, 0x03C, - 0x098, 0x086, 0x04C, 0x017, 0x026, 0x03E, 0x02C, 0x0B8, - 0x069, 0x03B, 0x049, 0x02E, 0x0B4, 0x008, 0x043, 0x01A, - 0x0A4, 0x0F9, 0x0B3, 0x051, 0x0F1, 0x010, 0x0F3, 0x043, - 0x0CD, 0x008, 0x06F, 0x063, 0x079, 0x0B3, 0x033, 0x00E, - 0x013, 0x098, 0x049, 0x098, 0x004, 0x0DA, 0x07C, 0x0E0, - 0x052, 0x079, 0x031, 0x00C, 0x098, 0x02E, 0x04D, 0x0AC, - 0x02C, 0x084, 0x014, 0x0EE, 0x04C, 0x0FE, 0x067, 0x05E, - 0x0E4, 0x09A, 0x075, 0x029, 0x0D7, 0x0A9, 0x035, 0x03A, - 0x094, 0x05B, 0x0D5, 0x09B, 0x058, 0x0B4, 0x0AF, 0x075, - 0x066, 0x0AF, 0x014, 0x0A9, 0x0EF, 0x040, 0x095, 0x025, - 0x008, 0x0B9, 0x0AD, 0x042, 0x0FC, 0x0D8, 0x0D9, 0x08C, - 0x033, 0x00E, 0x013, 0x098, 0x066, 0x01E, 0x045, 0x0AC, - 0x0B0, 0x00C, 0x042, 0x0D3, 0x0CC, 0x0A6, 0x012, 0x062, - 0x0DE, 0x0B4, 0x0B1, 0x080, 0x049, 0x07D, 0x0A2, 0x0DE, - 0x0B4, 0x018, 0x0C0, 0x024, 0x084, 0x0E6, 0x054, 0x0F5, - 0x083, 0x046, 0x001, 0x068, 0x01A, 0x063, 0x00C, 0x0C6, - 0x012, 0x064, 0x0FA, 0x04C, 0x035, 0x01C, 0x02C, 0x00E, - 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, - 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AD, 0x0D7, 0x002, - 0x070, 0x0E0, 0x04C, 0x0F3, 0x0A1, 0x0C1, 0x0D5, 0x0C0, - 0x03C, 0x0B9, 0x069, 0x039, 0x060, 0x04E, 0x058, 0x077, - 0x002, 0x067, 0x093, 0x03C, 0x099, 0x0E4, 0x0CF, 0x038, - 0x01C, 0x097, 0x02E, 0x040, 0x01B, 0x090, 0x031, 0x046, - 0x0A3, 0x05E, 0x00E, 0x088, 0x034, 0x06A, 0x035, 0x0E0, - 0x0E8, 0x0AA, 0x035, 0x01A, 0x0A9, 0x0F5, 0x015, 0x046, - 0x0A3, 0x0EA, 0x07D, 0x04A, 0x0A3, 0x051, 0x0AA, 0x09F, - 0x070, 0x054, 0x0A6, 0x057, 0x02E, 0x0B4, 0x0CD, 0x0C8, - 0x0A3, 0x00C, 0x0C1, 0x0DA, 0x0C6, 0x0E1, 0x0CB, 0x07A, - 0x0D4, 0x01C, 0x068, 0x0FF, 0x0CF, 0x055, 0x0A8, 0x0C0, - 0x02D, 0x085, 0x011, 0x017, 0x044, 0x02A, 0x030, 0x00B, - 0x04A, 0x088, 0x0C2, 0x04D, 0x0B5, 0x020, 0x0D5, 0x026, - 0x001, 0x069, 0x051, 0x069, 0x052, 0x019, 0x052, 0x060, - 0x016, 0x095, 0x016, 0x082, 0x096, 0x054, 0x098, 0x005, - 0x0A5, 0x045, 0x0F3, 0x0DD, 0x06A, 0x0F9, 0x028, 0x018, - 0x0EF, 0x000, 0x030, 0x030, 0x051, 0x04E, 0x044, 0x05D, - 0x012, 0x0D1, 0x043, 0x0E6, 0x012, 0x06F, 0x09E, 0x0BA, - 0x0CC, 0x0DF, 0x025, 0x003, 0x01D, 0x0E0, 0x006, 0x006, - 0x00A, 0x030, 0x0CC, 0x0A9, 0x0EB, 0x02D, 0x000, 0x086, - 0x0A6, 0x012, 0x065, 0x04F, 0x056, 0x0D6, 0x065, 0x049, - 0x05F, 0x03D, 0x0E8, 0x037, 0x0C9, 0x040, 0x0C7, 0x078, - 0x001, 0x081, 0x082, 0x08C, 0x033, 0x018, 0x049, 0x080, - 0x0AE, 0x040, 0x0C5, 0x018, 0x005, 0x09C, 0x06D, 0x018, - 0x066, 0x00E, 0x0F3, 0x0A0, 0x0C6, 0x012, 0x062, 0x0DE, - 0x0F5, 0x004, 0x0B4, 0x0AC, 0x06B, 0x0C6, 0x019, 0x091, - 0x073, 0x005, 0x048, 0x02E, 0x072, 0x094, 0x080, 0x073, - 0x0A1, 0x0C8, 0x047, 0x036, 0x066, 0x064, 0x02F, 0x036, - 0x066, 0x064, 0x007, 0x099, 0x002, 0x091, 0x08E, 0x072, - 0x0D1, 0x00F, 0x09D, 0x006, 0x031, 0x073, 0x0A0, 0x0C3, - 0x051, 0x06A, 0x01A, 0x020, 0x0BF, 0x03A, 0x00C, 0x02C, - 0x073, 0x087, 0x043, 0x05E, 0x060, 0x002, 0x023, 0x0FC, - 0x0E0, 0x0D6, 0x035, 0x0EF, 0x09E, 0x0F5, 0x0EF, 0x092, - 0x081, 0x08E, 0x0F0, 0x003, 0x003, 0x005, 0x018, 0x066, - 0x045, 0x0CC, 0x00B, 0x048, 0x02E, 0x070, 0x00A, 0x040, - 0x039, 0x0D0, 0x0E4, 0x023, 0x09B, 0x033, 0x032, 0x017, - 0x09B, 0x033, 0x032, 0x003, 0x0CC, 0x085, 0x048, 0x0C7, - 0x038, 0x014, 0x0A5, 0x0CE, 0x029, 0x07E, 0x0D2, 0x080, - 0x0A1, 0x0A8, 0x0B4, 0x048, 0x088, 0x02F, 0x0CE, 0x083, - 0x00B, 0x01C, 0x0E1, 0x0D0, 0x0D7, 0x098, 0x004, 0x088, - 0x087, 0x0CE, 0x096, 0x031, 0x073, 0x0A5, 0x08F, 0x0F3, - 0x083, 0x058, 0x0D7, 0x0BE, 0x07B, 0x082, 0x0AF, 0x092, - 0x081, 0x08E, 0x0F0, 0x003, 0x003, 0x005, 0x018, 0x066, - 0x045, 0x0CC, 0x015, 0x020, 0x0B9, 0x0C8, 0x029, 0x000, - 0x0E7, 0x043, 0x090, 0x08E, 0x06C, 0x0CC, 0x0C8, 0x05E, - 0x06C, 0x0CC, 0x0C8, 0x00F, 0x032, 0x005, 0x023, 0x01C, - 0x0E4, 0x050, 0x0D4, 0x05A, 0x017, 0x088, 0x02F, 0x0CE, - 0x083, 0x010, 0x0F9, 0x0D0, 0x023, 0x017, 0x03A, 0x004, - 0x035, 0x0E6, 0x000, 0x022, 0x016, 0x039, 0x0C3, 0x0A3, - 0x0FC, 0x0E0, 0x0D6, 0x035, 0x0E0, 0x0BF, 0x0F4, 0x018, - 0x0F2, 0x02D, 0x04D, 0x043, 0x051, 0x06E, 0x05A, 0x022, - 0x01F, 0x030, 0x0D4, 0x017, 0x0E7, 0x041, 0x091, 0x073, - 0x005, 0x048, 0x02E, 0x077, 0x069, 0x000, 0x0E7, 0x043, - 0x090, 0x08E, 0x06C, 0x0CC, 0x0C8, 0x05E, 0x06C, 0x0CC, - 0x0C8, 0x00F, 0x032, 0x005, 0x023, 0x01C, 0x0EF, 0x04C, - 0x04E, 0x006, 0x004, 0x0C9, 0x09E, 0x00B, 0x0FF, 0x041, - 0x08F, 0x022, 0x0D4, 0x0D4, 0x035, 0x016, 0x0E5, 0x0A2, - 0x021, 0x0F3, 0x05A, 0x082, 0x0FC, 0x0E8, 0x032, 0x02E, - 0x060, 0x0A9, 0x005, 0x0CE, 0x013, 0x048, 0x007, 0x03A, - 0x01C, 0x084, 0x073, 0x066, 0x066, 0x042, 0x0F3, 0x066, - 0x066, 0x040, 0x079, 0x090, 0x029, 0x018, 0x0E7, 0x00A, - 0x098, 0x09C, 0x00A, 0x09E, 0x0B5, 0x012, 0x05C, 0x07C, - 0x0C3, 0x031, 0x08B, 0x098, 0x02A, 0x07C, 0x0D3, 0x0ED, - 0x038, 0x0E9, 0x0D3, 0x04E, 0x074, 0x0ED, 0x049, 0x09E, - 0x00B, 0x0FF, 0x041, 0x08F, 0x022, 0x0D4, 0x0D4, 0x035, - 0x016, 0x0E5, 0x0A2, 0x02D, 0x0EB, 0x045, 0x033, 0x08F, - 0x0FC, 0x0F7, 0x0A0, 0x05F, 0x025, 0x003, 0x01D, 0x0E4, - 0x00E, 0x006, 0x00A, 0x030, 0x0CC, 0x00C, 0x0F3, 0x0EB, - 0x040, 0x0DE, 0x061, 0x0A8, 0x070, 0x092, 0x00A, 0x000, - 0x0E1, 0x024, 0x01E, 0x000, 0x0E1, 0x024, 0x01E, 0x000, - 0x0E1, 0x024, 0x01E, 0x000, 0x0E1, 0x024, 0x01E, 0x000, - 0x0E1, 0x024, 0x01E, 0x001, 0x00F, 0x098, 0x02A, 0x00B, - 0x0F3, 0x0A0, 0x0C8, 0x0B9, 0x0A2, 0x0A4, 0x017, 0x03A, - 0x069, 0x000, 0x0E7, 0x043, 0x090, 0x08E, 0x075, 0x048, - 0x05E, 0x070, 0x069, 0x001, 0x0E6, 0x000, 0x052, 0x031, - 0x0CC, 0x018, 0x014, 0x0A5, 0x0CC, 0x009, 0x082, 0x094, - 0x073, 0x00C, 0x0A0, 0x091, 0x0F5, 0x025, 0x0CC, 0x007, - 0x006, 0x084, 0x084, 0x09F, 0x030, 0x0A2, 0x0A4, 0x07D, - 0x050, 0x075, 0x0A6, 0x065, 0x001, 0x04A, 0x08E, 0x0B4, - 0x0CC, 0x0C4, 0x035, 0x054, 0x075, 0x066, 0x0A4, 0x097, - 0x07A, 0x089, 0x050, 0x053, 0x013, 0x080, 0x019, 0x0E3, - 0x049, 0x05C, 0x06D, 0x0CE, 0x0A9, 0x040, 0x035, 0x006, - 0x078, 0x0D2, 0x057, 0x006, 0x0F1, 0x0B3, 0x02A, 0x08D, - 0x097, 0x023, 0x062, 0x092, 0x05D, 0x069, 0x099, 0x01C, - 0x06A, 0x036, 0x0E6, 0x0CD, 0x046, 0x012, 0x06F, 0x09E, - 0x0E1, 0x0AB, 0x0E4, 0x0A3, 0x00C, 0x0C0, 0x0DE, 0x0AC, - 0x0D4, 0x00D, 0x028, 0x01B, 0x0D0, 0x012, 0x0A5, 0x000, - 0x0F8, 0x04B, 0x0AD, 0x033, 0x028, 0x006, 0x0A0, 0x0DE, - 0x014, 0x097, 0x03A, 0x089, 0x05D, 0x0C0, 0x00D, 0x0E3, - 0x006, 0x090, 0x092, 0x05D, 0x069, 0x098, 0x066, 0x0B9, - 0x019, 0x095, 0x0E4, 0x0A8, 0x0CF, 0x09D, 0x033, 0x018, - 0x049, 0x0BE, 0x07B, 0x086, 0x0AF, 0x092, 0x08C, 0x033, - 0x024, 0x014, 0x00C, 0x0F4, 0x083, 0x024, 0x021, 0x0C2, - 0x070, 0x0BF, 0x0F4, 0x018, 0x0F2, 0x02D, 0x04D, 0x043, - 0x051, 0x06E, 0x05A, 0x022, 0x01F, 0x032, 0x0A8, 0x02F, - 0x0CE, 0x083, 0x022, 0x0E6, 0x005, 0x0A4, 0x017, 0x03A, - 0x069, 0x000, 0x0E7, 0x043, 0x090, 0x08E, 0x075, 0x048, - 0x05E, 0x070, 0x069, 0x001, 0x0E6, 0x042, 0x0A4, 0x063, - 0x098, 0x002, 0x029, 0x04B, 0x09A, 0x029, 0x078, 0x0E9, - 0x040, 0x053, 0x013, 0x081, 0x081, 0x032, 0x067, 0x082, - 0x0FF, 0x0D0, 0x063, 0x0C8, 0x0B5, 0x035, 0x00D, 0x045, - 0x0AE, 0x050, 0x008, 0x07C, 0x0E0, 0x0D0, 0x05F, 0x09D, - 0x006, 0x045, 0x0CC, 0x001, 0x0A4, 0x017, 0x03A, 0x069, - 0x000, 0x0E7, 0x043, 0x090, 0x08E, 0x075, 0x048, 0x05E, - 0x070, 0x069, 0x001, 0x0E6, 0x059, 0x0A4, 0x063, 0x098, - 0x01C, 0x052, 0x097, 0x03B, 0x030, 0x052, 0x08E, 0x07D, - 0x02A, 0x009, 0x01F, 0x051, 0x0EB, 0x0A4, 0x0A4, 0x00A, - 0x0B9, 0x094, 0x087, 0x0AE, 0x0C5, 0x031, 0x038, 0x002, - 0x0FF, 0x0D0, 0x063, 0x0C8, 0x0B5, 0x035, 0x00D, 0x045, - 0x0AE, 0x050, 0x008, 0x07C, 0x0EA, 0x020, 0x0BF, 0x03A, - 0x00C, 0x08B, 0x09A, 0x016, 0x090, 0x05C, 0x0E9, 0x0A4, - 0x003, 0x09D, 0x00E, 0x042, 0x039, 0x0D5, 0x021, 0x079, - 0x095, 0x048, 0x00F, 0x030, 0x00A, 0x091, 0x08E, 0x060, - 0x0EB, 0x029, 0x073, 0x000, 0x009, 0x054, 0x004, 0x0CA, - 0x082, 0x065, 0x052, 0x065, 0x0E4, 0x0CA, 0x022, 0x065, - 0x072, 0x065, 0x009, 0x032, 0x0E0, 0x099, 0x072, 0x04C, - 0x0C4, 0x0E0, 0x00B, 0x0FF, 0x041, 0x08F, 0x022, 0x0D4, - 0x0D4, 0x035, 0x016, 0x0B9, 0x040, 0x021, 0x0F3, 0x08A, - 0x082, 0x0FC, 0x0E8, 0x032, 0x02E, 0x060, 0x0A9, 0x005, - 0x0CE, 0x09A, 0x040, 0x039, 0x0D0, 0x0E4, 0x023, 0x09D, - 0x052, 0x017, 0x099, 0x054, 0x061, 0x099, 0x001, 0x0E6, - 0x040, 0x0A4, 0x063, 0x098, 0x004, 0x0B1, 0x084, 0x098, - 0x018, 0x0EF, 0x02D, 0x003, 0x005, 0x031, 0x038, 0x002, - 0x0FF, 0x0D0, 0x063, 0x0C8, 0x0B5, 0x035, 0x00D, 0x045, - 0x0B9, 0x068, 0x088, 0x07C, 0x0E0, 0x050, 0x05F, 0x09D, - 0x006, 0x045, 0x0CC, 0x081, 0x048, 0x02E, 0x071, 0x034, - 0x08F, 0x048, 0x001, 0x048, 0x015, 0x021, 0x005, 0x021, - 0x0E9, 0x00A, 0x052, 0x003, 0x0CE, 0x05A, 0x046, 0x039, - 0x0CF, 0x047, 0x08E, 0x060, 0x0AB, 0x01A, 0x0F3, 0x053, - 0x043, 0x0EB, 0x035, 0x024, 0x0B8, 0x01B, 0x030, 0x007, - 0x009, 0x08A, 0x074, 0x02F, 0x07E, 0x041, 0x074, 0x01E, - 0x01D, 0x00D, 0x087, 0x046, 0x049, 0x0D5, 0x095, 0x0D1, - 0x0D5, 0x0D5, 0x0BB, 0x0A9, 0x04E, 0x082, 0x09D, 0x005, - 0x03A, 0x00A, 0x074, 0x014, 0x0E8, 0x029, 0x0D0, 0x042, - 0x074, 0x05B, 0x0CE, 0x050, 0x0C4, 0x007, 0x045, 0x0BC, - 0x0E2, 0x00C, 0x040, 0x074, 0x05B, 0x0CE, 0x083, 0x004, - 0x0F9, 0x095, 0x04D, 0x013, 0x063, 0x05E, 0x06F, 0x031, - 0x03B, 0x0A0, 0x08B, 0x0A2, 0x0C5, 0x039, 0x08D, 0x078, - 0x03A, 0x022, 0x0A0, 0x000, 0x06B, 0x0C1, 0x0D1, 0x054, - 0x060, 0x016, 0x0D9, 0x091, 0x0A2, 0x0E7, 0x043, 0x08C, - 0x024, 0x0DC, 0x01C, 0x0E0, 0x051, 0x017, 0x039, 0x06B, - 0x03B, 0x0CC, 0x04B, 0x042, 0x02E, 0x06B, 0x050, 0x0BF, - 0x036, 0x036, 0x065, 0x04F, 0x07A, 0x018, 0x055, 0x025, - 0x078, 0x098, 0x023, 0x0E7, 0x050, 0x03E, 0x0F3, 0x081, - 0x04C, 0x002, 0x06D, 0x03E, 0x071, 0x053, 0x0AF, 0x078, - 0x0A9, 0x0D4, 0x0A6, 0x029, 0x0B1, 0x0BC, 0x0D9, 0x099, - 0x0B2, 0x08E, 0x062, 0x08F, 0x022, 0x02E, 0x075, 0x016, - 0x0B0, 0x0B2, 0x0AB, 0x023, 0x028, 0x016, 0x054, 0x052, - 0x031, 0x0BC, 0x0D9, 0x099, 0x0B2, 0x08E, 0x066, 0x019, - 0x002, 0x02E, 0x075, 0x016, 0x050, 0x02C, 0x0A9, 0x0C8, - 0x0C6, 0x0F5, 0x020, 0x0D3, 0x0E4, 0x07F, 0x04F, 0x09C, - 0x00A, 0x0D6, 0x016, 0x07F, 0x090, 0x0EE, 0x04C, 0x0EB, - 0x0CF, 0x0E2, 0x088, 0x0BA, 0x02F, 0x042, 0x086, 0x0AE, - 0x0BD, 0x0E5, 0x0A7, 0x052, 0x09F, 0x093, 0x063, 0x079, - 0x0EB, 0x033, 0x008, 0x0F9, 0x094, 0x052, 0x047, 0x0CD, - 0x099, 0x025, 0x06F, 0x03A, 0x00C, 0x013, 0x0E6, 0x055, - 0x034, 0x04C, 0x05A, 0x04D, 0x0B5, 0x023, 0x095, 0x0A5, - 0x048, 0x011, 0x05A, 0x00A, 0x043, 0x095, 0x0AC, 0x02C, - 0x0BA, 0x024, 0x005, 0x049, 0x0B1, 0x0BC, 0x0CA, 0x0A7, - 0x072, 0x06C, 0x06B, 0x0C5, 0x0BD, 0x0E8, 0x031, 0x069, - 0x052, 0x05D, 0x006, 0x012, 0x065, 0x03E, 0x0B1, 0x050, - 0x04C, 0x07D, 0x04F, 0x0AC, 0x00A, 0x030, 0x00B, 0x036, - 0x064, 0x011, 0x073, 0x08A, 0x083, 0x08E, 0x075, 0x012, - 0x09F, 0x07B, 0x0D2, 0x099, 0x058, 0x0EE, 0x082, 0x02E, - 0x077, 0x0A0, 0x0E3, 0x09D, 0x05D, 0x04F, 0x0BC, 0x02A, - 0x053, 0x029, 0x053, 0x0DE, 0x093, 0x024, 0x0BA, 0x0B3, - 0x036, 0x0AA, 0x04A, 0x0C6, 0x079, 0x0D4, 0x0B9, 0x0DE, - 0x062, 0x05A, 0x011, 0x073, 0x050, 0x050, 0x0BF, 0x037, - 0x036, 0x06F, 0x013, 0x023, 0x0BA, 0x00C, 0x024, 0x0CE, - 0x0BD, 0x0E2, 0x0A7, 0x052, 0x0B2, 0x08E, 0x06B, 0x060, - 0x062, 0x02E, 0x075, 0x013, 0x030, 0x0AC, 0x0A0, 0x059, - 0x0CA, 0x064, 0x063, 0x079, 0x0B3, 0x033, 0x065, 0x01C, - 0x0CC, 0x032, 0x004, 0x05C, 0x0EA, 0x02C, 0x0A0, 0x059, - 0x0DF, 0x023, 0x01B, 0x0D4, 0x083, 0x052, 0x047, 0x0DD, - 0x079, 0x096, 0x0D4, 0x09E, 0x0B3, 0x052, 0x04B, 0x0A2, - 0x05A, 0x01A, 0x08D, 0x05D, 0x07B, 0x082, 0x0A7, 0x052, - 0x0B2, 0x08E, 0x066, 0x019, 0x002, 0x02E, 0x075, 0x016, - 0x050, 0x02C, 0x08C, 0x032, 0x01D, 0x07B, 0x08E, 0x0A7, - 0x052, 0x0B1, 0x0BC, 0x0D9, 0x099, 0x098, 0x004, 0x0DA, - 0x07C, 0x0E2, 0x0AC, 0x0FE, 0x066, 0x019, 0x002, 0x02E, - 0x065, 0x050, 0x0BF, 0x033, 0x066, 0x064, 0x0FE, 0x074, - 0x018, 0x086, 0x04C, 0x017, 0x026, 0x0D6, 0x016, 0x052, - 0x039, 0x018, 0x0DE, 0x07A, 0x0CC, 0x0C2, 0x03E, 0x065, - 0x014, 0x091, 0x0F3, 0x066, 0x049, 0x008, 0x06E, 0x083, - 0x009, 0x033, 0x0AF, 0x031, 0x0ED, 0x00D, 0x09D, 0x006, - 0x012, 0x062, 0x02A, 0x031, 0x08D, 0x06D, 0x0E7, 0x041, - 0x082, 0x07C, 0x0CA, 0x0A6, 0x089, 0x087, 0x009, 0x02E, - 0x029, 0x0B1, 0x0AF, 0x010, 0x039, 0x0D6, 0x064, 0x097, - 0x030, 0x01D, 0x042, 0x075, 0x093, 0x044, 0x002, 0x08C, - 0x024, 0x0D2, 0x07A, 0x0B3, 0x050, 0x0F6, 0x089, 0x005, - 0x043, 0x05E, 0x061, 0x098, 0x0C0, 0x02C, 0x092, 0x025, - 0x03C, 0x08B, 0x024, 0x089, 0x049, 0x005, 0x049, 0x0E7, - 0x00C, 0x0B9, 0x084, 0x098, 0x0B7, 0x0AD, 0x033, 0x044, - 0x0AE, 0x05A, 0x051, 0x086, 0x060, 0x09F, 0x038, 0x0A9, - 0x0A2, 0x06C, 0x06B, 0x0C4, 0x08E, 0x0F4, 0x05E, 0x049, - 0x046, 0x012, 0x062, 0x0DE, 0x0B4, 0x0CD, 0x021, 0x05C, - 0x0B4, 0x0A3, 0x00C, 0x0C1, 0x03E, 0x072, 0x029, 0x0A2, - 0x06C, 0x06B, 0x0C6, 0x012, 0x062, 0x047, 0x0F0, 0x0E8, - 0x0C3, 0x032, 0x004, 0x035, 0x040, 0x092, 0x0A4, 0x082, - 0x088, 0x010, 0x092, 0x07C, 0x0CB, 0x0D4, 0x02F, 0x0A4, - 0x002, 0x011, 0x084, 0x098, 0x0B7, 0x0AD, 0x033, 0x044, - 0x0AE, 0x05A, 0x051, 0x086, 0x060, 0x09F, 0x038, 0x0A9, - 0x0A2, 0x06C, 0x06B, 0x0C4, 0x08E, 0x0F4, 0x05E, 0x049, - 0x044, 0x008, 0x049, 0x03E, 0x065, 0x0EA, 0x017, 0x0D2, - 0x001, 0x008, 0x0C2, 0x04C, 0x05B, 0x0D6, 0x099, 0x0A4, - 0x02B, 0x096, 0x094, 0x061, 0x098, 0x027, 0x0CE, 0x045, - 0x034, 0x04D, 0x08D, 0x078, 0x081, 0x009, 0x027, 0x0CC, - 0x0BD, 0x012, 0x028, 0x06C, 0x058, 0x0AF, 0x0B6, 0x0F3, - 0x0A0, 0x0C1, 0x03E, 0x065, 0x053, 0x044, 0x0D8, 0x0D7, - 0x092, 0x08E, 0x07D, 0x04B, 0x0C2, 0x0FA, 0x061, 0x026, - 0x006, 0x03A, 0x0B3, 0x06B, 0x003, 0x005, 0x049, 0x0E7, - 0x00C, 0x0B9, 0x06F, 0x05A, 0x066, 0x095, 0x05C, 0x0B4, - 0x0A3, 0x00C, 0x0C1, 0x03E, 0x070, 0x029, 0x0A2, 0x06E, - 0x0A4, 0x0DF, 0x093, 0x071, 0x013, 0x077, 0x026, 0x0E1, - 0x026, 0x0F8, 0x026, 0x0C6, 0x0BC, 0x094, 0x073, 0x0F9, - 0x02F, 0x00B, 0x0E9, 0x084, 0x098, 0x018, 0x0EA, 0x0CC, - 0x0EC, 0x00C, 0x015, 0x027, 0x09C, 0x032, 0x0FF, 0x03D, - 0x056, 0x0AF, 0x092, 0x08B, 0x07A, 0x0D3, 0x035, 0x0D5, - 0x0CB, 0x04A, 0x030, 0x0CC, 0x013, 0x0E7, 0x002, 0x09A, - 0x026, 0x0C6, 0x0BC, 0x094, 0x073, 0x041, 0x097, 0x091, - 0x0F4, 0x083, 0x0CE, 0x004, 0x020, 0x062, 0x08B, 0x005, - 0x016, 0x049, 0x08C, 0x024, 0x0C0, 0x0C7, 0x056, 0x090, - 0x0C0, 0x0C1, 0x052, 0x079, 0x0C3, 0x02E, 0x05B, 0x0D5, - 0x0A6, 0x072, 0x0D2, 0x094, 0x0FA, 0x0AD, 0x058, 0x0C8, - 0x0FA, 0x09F, 0x054, 0x0B3, 0x032, 0x04B, 0x0B9, 0x054, - 0x0A6, 0x051, 0x086, 0x06B, 0x079, 0x0D0, 0x060, 0x09F, - 0x032, 0x005, 0x034, 0x04D, 0x08D, 0x07A, 0x04D, 0x01E, - 0x07A, 0x0B3, 0x051, 0x000, 0x0A9, 0x03D, 0x059, 0x0A8, - 0x07B, 0x044, 0x082, 0x0A1, 0x0AF, 0x04A, 0x08D, 0x052, - 0x0A9, 0x052, 0x041, 0x049, 0x04F, 0x03A, 0x02E, 0x040, - 0x0A4, 0x099, 0x050, 0x0BE, 0x090, 0x008, 0x052, 0x079, - 0x0C3, 0x02E, 0x061, 0x026, 0x02D, 0x0EB, 0x04C, 0x0D0, - 0x015, 0x0CB, 0x04A, 0x030, 0x0CC, 0x013, 0x0E7, 0x002, - 0x09A, 0x026, 0x0C6, 0x0BC, 0x048, 0x0FE, 0x01D, 0x025, - 0x046, 0x0A9, 0x054, 0x0A9, 0x020, 0x0A4, 0x0A7, 0x09D, - 0x017, 0x020, 0x052, 0x04C, 0x0A8, 0x05F, 0x048, 0x004, - 0x023, 0x009, 0x031, 0x06F, 0x05A, 0x066, 0x080, 0x0AE, - 0x05A, 0x051, 0x086, 0x060, 0x09F, 0x038, 0x014, 0x0D1, - 0x036, 0x035, 0x0E4, 0x0A7, 0x09D, 0x017, 0x020, 0x052, - 0x04C, 0x0A2, 0x045, 0x00D, 0x08B, 0x015, 0x0F4, 0x091, - 0x0DE, 0x08B, 0x0C9, 0x028, 0x0C2, 0x04C, 0x05B, 0x0D6, - 0x099, 0x0A9, 0x05C, 0x0B4, 0x0A3, 0x00C, 0x0D6, 0x0F3, - 0x0A0, 0x0C1, 0x03E, 0x064, 0x00A, 0x068, 0x09B, 0x01A, - 0x0F1, 0x06D, 0x04C, 0x0AA, 0x092, 0x0E0, 0x036, 0x094, - 0x070, 0x09B, 0x029, 0x078, 0x013, 0x0AE, 0x0B3, 0x0AA, - 0x085, 0x0D4, 0x043, 0x075, 0x009, 0x03A, 0x0C9, 0x0EB, - 0x035, 0x024, 0x0B8, 0x01B, 0x032, 0x08E, 0x013, 0x048, - 0x07E, 0x04E, 0x0FD, 0x040, 0x0FD, 0x040, 0x0FD, 0x040, - 0x0FD, 0x040, 0x0FD, 0x040, 0x0FC, 0x013, 0x0F4, 0x021, - 0x0F9, 0x017, 0x045, 0x08A, 0x030, 0x00B, 0x033, 0x05F, - 0x083, 0x0A2, 0x02A, 0x030, 0x00B, 0x033, 0x05F, 0x083, - 0x0A2, 0x0A8, 0x0C0, 0x02D, 0x0B3, 0x020, 0x070, 0x092, - 0x013, 0x09A, 0x0DE, 0x074, 0x018, 0x027, 0x0CC, 0x0AA, - 0x068, 0x09B, 0x01A, 0x0F7, 0x007, 0x045, 0x051, 0x080, - 0x05B, 0x066, 0x047, 0x007, 0x038, 0x0A8, 0x023, 0x0E7, - 0x051, 0x011, 0x03F, 0x0E0, 0x0E8, 0x085, 0x046, 0x001, - 0x06D, 0x099, 0x006, 0x012, 0x065, 0x04F, 0x07A, 0x020, - 0x024, 0x0BA, 0x0B3, 0x032, 0x015, 0x025, 0x07B, 0x0AD, - 0x033, 0x078, 0x0AE, 0x00E, 0x073, 0x0D0, 0x047, 0x0CE, - 0x0A7, 0x030, 0x0CC, 0x044, 0x0FF, 0x083, 0x0A2, 0x0A8, - 0x0C0, 0x02C, 0x0D9, 0x091, 0x0C1, 0x0D1, 0x015, 0x018, - 0x005, 0x09B, 0x032, 0x008, 0x0BA, 0x02C, 0x051, 0x080, - 0x059, 0x0B3, 0x020, 0x070, 0x092, 0x0E2, 0x098, 0x089, - 0x0FD, 0x0BC, 0x0EE, 0x018, 0x090, 0x0FC, 0x08B, 0x0A2, - 0x0C5, 0x02B, 0x00D, 0x078, 0x03A, 0x022, 0x0A5, 0x061, - 0x0AF, 0x007, 0x045, 0x051, 0x080, 0x05B, 0x066, 0x044, - 0x09E, 0x0B3, 0x052, 0x04B, 0x083, 0x0AD, 0x0C7, 0x009, - 0x0BE, 0x01F, 0x09F, 0x074, 0x065, 0x05D, 0x00A, 0x017, - 0x07C, 0x0AB, 0x0A0, 0x0C2, 0x04C, 0x038, 0x049, 0x012, - 0x02E, 0x038, 0x049, 0x007, 0x0A3, 0x00C, 0x0C1, 0x03E, - 0x065, 0x053, 0x044, 0x0D8, 0x0D7, 0x0AD, 0x0E7, 0x000, - 0x032, 0x04B, 0x09B, 0x033, 0x034, 0x04A, 0x003, 0x000, - 0x09D, 0x025, 0x0CE, 0x083, 0x024, 0x0B8, 0x019, 0x099, - 0x08C, 0x002, 0x012, 0x04B, 0x0A1, 0x099, 0x0D8, 0x0C0, - 0x027, 0x049, 0x073, 0x0CF, 0x0F9, 0x03C, 0x0F4, 0x07C, - 0x0E7, 0x098, 0x004, 0x0E9, 0x02E, 0x07F, 0x039, 0x0E3, - 0x04F, 0x046, 0x053, 0x0C0, 0x060, 0x013, 0x0A4, 0x0B9, - 0x0E5, 0x03C, 0x003, 0x0DE, 0x08F, 0x09C, 0x0F3, 0x000, - 0x09C, 0x06F, 0x0CF, 0x03E, 0x085, 0x0F9, 0x0A3, 0x036, - 0x002, 0x01E, 0x060, 0x038, 0x092, 0x03E, 0x063, 0x01A, - 0x010, 0x09F, 0x0CF, 0x018, 0x010, 0x092, 0x0BC, 0x0D0, - 0x0A4, 0x00C, 0x0DC, 0x0C0, 0x00F, 0x09C, 0x097, 0x034, - 0x062, 0x0B6, 0x0E7, 0x0F3, 0x0F3, 0x0A5, 0x0CF, 0x018, - 0x042, 0x034, 0x01C, 0x0C2, 0x0CA, 0x0FA, 0x08E, 0x068, - 0x052, 0x006, 0x0AF, 0x03C, 0x0A3, 0x00D, 0x0BF, 0x09E, - 0x050, 0x0E1, 0x0D1, 0x073, 0x0CA, 0x0E0, 0x03A, 0x0FC, - 0x0C1, 0x009, 0x01A, 0x01E, 0x06A, 0x05C, 0x05B, 0x08E, - 0x063, 0x04E, 0x077, 0x073, 0x0CC, 0x061, 0x067, 0x0DD, - 0x0E6, 0x06C, 0x048, 0x0D1, 0x0F3, 0x01B, 0x024, 0x069, - 0x051, 0x008, 0x0D4, 0x042, 0x01B, 0x0F4, 0x067, 0x0D1, - 0x080, 0x04E, 0x02F, 0x0D0, 0x08C, 0x0D8, 0x030, 0x009, - 0x0C2, 0x01E, 0x080, 0x01C, 0x046, 0x001, 0x03A, 0x047, - 0x0D0, 0x031, 0x0A1, 0x006, 0x001, 0x03A, 0x07F, 0x046, - 0x030, 0x021, 0x018, 0x004, 0x0E9, 0x05E, 0x084, 0x029, - 0x000, 0x0C0, 0x027, 0x0CD, 0x0D0, 0x000, 0x07C, 0x098, - 0x004, 0x0F9, 0x02E, 0x084, 0x062, 0x08C, 0x002, 0x07D, - 0x0BA, 0x03E, 0x07E, 0x04C, 0x002, 0x07D, 0x02E, 0x08C, - 0x061, 0x008, 0x030, 0x009, 0x0F4, 0x01D, 0x001, 0x065, - 0x073, 0x000, 0x09F, 0x051, 0x0D0, 0x085, 0x020, 0x018, - 0x004, 0x0FA, 0x0BD, 0x019, 0x046, 0x018, 0x0C0, 0x027, - 0x0DF, 0x0D1, 0x094, 0x038, 0x04C, 0x002, 0x07D, 0x017, - 0x046, 0x057, 0x001, 0x030, 0x009, 0x0F5, 0x0FA, 0x001, - 0x009, 0x006, 0x001, 0x03E, 0x087, 0x0A1, 0x04B, 0x088, - 0x0C0, 0x027, 0x0DC, 0x074, 0x00D, 0x039, 0x0D3, 0x000, - 0x09F, 0x073, 0x0D0, 0x030, 0x0B3, 0x098, 0x004, 0x0FB, - 0x0BD, 0x006, 0x0C4, 0x083, 0x000, 0x09F, 0x047, 0x0D0, - 0x036, 0x048, 0x0CC, 0x002, 0x071, 0x0BF, 0x03F, 0x09A, - 0x017, 0x0E6, 0x03F, 0x008, 0x021, 0x0E6, 0x092, 0x0A4, - 0x08F, 0x09A, 0x010, 0x031, 0x0A7, 0x0F3, 0x010, 0x0B1, - 0x084, 0x0AF, 0x03A, 0x0AC, 0x0DC, 0x0F7, 0x073, 0x0F2, - 0x05C, 0x0C6, 0x02A, 0x0DB, 0x09E, 0x07E, 0x07E, 0x097, - 0x031, 0x008, 0x063, 0x0D0, 0x073, 0x07B, 0x043, 0x0A8, - 0x0E6, 0x03D, 0x034, 0x0EA, 0x0F3, 0x0E3, 0x015, 0x0BF, - 0x09F, 0x018, 0x05F, 0x045, 0x0CF, 0x0E8, 0x09F, 0x05F, - 0x09A, 0x05B, 0x003, 0x0D0, 0x0F3, 0x0D3, 0x0CE, 0x037, - 0x01C, 0x0D0, 0x00F, 0x0BB, 0x09E, 0x068, 0x078, 0x03B, - 0x0BC, 0x0CA, 0x031, 0x0E8, 0x0F9, 0x0A2, 0x002, 0x012, - 0x0A2, 0x073, 0x051, 0x008, 0x06F, 0x0D1, 0x0F3, 0x046, - 0x001, 0x038, 0x0BF, 0x040, 0x0FC, 0x023, 0x000, 0x09C, - 0x021, 0x0E8, 0x049, 0x051, 0x080, 0x04E, 0x091, 0x0F4, - 0x021, 0x003, 0x019, 0x080, 0x04E, 0x09F, 0x0D0, 0x021, - 0x063, 0x006, 0x001, 0x03A, 0x056, 0x08C, 0x002, 0x074, - 0x0FE, 0x075, 0x049, 0x05E, 0x063, 0x0D3, 0x04A, 0x054, - 0x042, 0x035, 0x013, 0x0A7, 0x0D1, 0x080, 0x04E, 0x095, - 0x0E8, 0x01E, 0x09A, 0x04C, 0x002, 0x07C, 0x0DD, 0x01B, - 0x0B9, 0x0E6, 0x001, 0x03E, 0x04B, 0x0A0, 0x062, 0x0A3, - 0x000, 0x09F, 0x06E, 0x08C, 0x0FC, 0x0F3, 0x000, 0x09F, - 0x04B, 0x0A0, 0x042, 0x018, 0x0CC, 0x002, 0x07D, 0x007, - 0x043, 0x0DA, 0x013, 0x000, 0x09F, 0x051, 0x0D0, 0x03D, - 0x034, 0x098, 0x004, 0x0FA, 0x0BD, 0x01C, 0x062, 0x08C, - 0x002, 0x07D, 0x0FD, 0x01C, 0x061, 0x073, 0x000, 0x09F, - 0x045, 0x0D1, 0x0F4, 0x04E, 0x060, 0x013, 0x0EB, 0x0F4, - 0x025, 0x0B0, 0x033, 0x000, 0x09F, 0x043, 0x0D1, 0x0A7, - 0x09C, 0x018, 0x004, 0x0FB, 0x08E, 0x084, 0x003, 0x0E9, - 0x080, 0x04F, 0x0B9, 0x0E8, 0x043, 0x0C1, 0x030, 0x009, - 0x0F7, 0x07A, 0x00A, 0x031, 0x098, 0x004, 0x0FA, 0x03E, - 0x084, 0x040, 0x041, 0x080, 0x04E, 0x082, 0x0E7, 0x041, - 0x087, 0x009, 0x023, 0x004, 0x023, 0x000, 0x09D, 0x005, - 0x0CE, 0x096, 0x01C, 0x024, 0x08C, 0x010, 0x08C, 0x002, - 0x074, 0x017, 0x03A, 0x004, 0x038, 0x049, 0x018, 0x021, - 0x018, 0x004, 0x0E8, 0x02E, 0x074, 0x050, 0x0E1, 0x024, - 0x060, 0x084, 0x060, 0x013, 0x0A0, 0x0B9, 0x0D4, 0x011, - 0x0C2, 0x048, 0x0C1, 0x008, 0x0C0, 0x027, 0x041, 0x073, - 0x0A8, 0x023, 0x084, 0x091, 0x082, 0x011, 0x080, 0x04E, - 0x082, 0x0E7, 0x052, 0x08E, 0x012, 0x046, 0x008, 0x046, - 0x001, 0x03A, 0x00B, 0x09D, 0x040, 0x01C, 0x024, 0x08C, - 0x010, 0x08C, 0x002, 0x074, 0x017, 0x03A, 0x009, 0x00E, - 0x012, 0x046, 0x008, 0x046, 0x001, 0x03A, 0x00B, 0x098, - 0x06A, 0x01C, 0x024, 0x0B0, 0x0E1, 0x018, 0x004, 0x0E8, - 0x02E, 0x06B, 0x050, 0x0E1, 0x025, 0x087, 0x008, 0x0C0, - 0x027, 0x041, 0x073, 0x005, 0x043, 0x084, 0x096, 0x01C, - 0x023, 0x000, 0x09D, 0x005, 0x0CC, 0x0AA, 0x01C, 0x024, - 0x0B0, 0x0E1, 0x018, 0x004, 0x0E8, 0x02E, 0x070, 0x068, - 0x070, 0x092, 0x0C3, 0x084, 0x060, 0x013, 0x0E5, 0x044, - 0x0F9, 0x040, 0x09D, 0x005, 0x0CE, 0x05A, 0x01C, 0x024, - 0x0B0, 0x0E1, 0x018, 0x004, 0x0F9, 0x0D1, 0x03E, 0x070, - 0x027, 0x0CF, 0x013, 0x0E5, 0x044, 0x02C, 0x0A0, 0x042, - 0x0CB, 0x089, 0x0F2, 0x021, 0x03A, 0x00B, 0x09C, 0x00A, - 0x01C, 0x024, 0x0B0, 0x0E1, 0x018, 0x004, 0x0F9, 0x0D1, - 0x00B, 0x038, 0x010, 0x0B3, 0x0C4, 0x021, 0x039, 0x036, - 0x05C, 0x042, 0x0C8, 0x084, 0x02B, 0x079, 0x0D0, 0x061, - 0x0C2, 0x074, 0x015, 0x024, 0x0BA, 0x0D3, 0x031, 0x0E5, - 0x059, 0x008, 0x029, 0x008, 0x0E0, 0x066, 0x063, 0x042, - 0x095, 0x012, 0x081, 0x000, 0x029, 0x00B, 0x0C1, 0x051, - 0x024, 0x0B8, 0x019, 0x099, 0x090, 0x022, 0x090, 0x0B4, - 0x018, 0x0A0, 0x091, 0x041, 0x001, 0x041, 0x041, 0x041, - 0x052, 0x083, 0x0CA, 0x040, 0x028, 0x068, 0x029, 0x008, - 0x0BA, 0x016, 0x010, 0x09C, 0x099, 0x00B, 0x056, 0x094, - 0x090, 0x052, 0x015, 0x074, 0x0C0, 0x027, 0x01A, 0x02A, - 0x0D2, 0x090, 0x025, 0x0D3, 0x000, 0x09D, 0x028, 0x0AB, - 0x04A, 0x042, 0x017, 0x04C, 0x002, 0x070, 0x0D4, 0x084, - 0x02E, 0x098, 0x004, 0x0E1, 0x02A, 0x042, 0x017, 0x04C, - 0x002, 0x070, 0x082, 0x090, 0x04B, 0x0A6, 0x001, 0x038, - 0x051, 0x048, 0x042, 0x0E9, 0x080, 0x04E, 0x015, 0x0A4, - 0x021, 0x074, 0x0C0, 0x027, 0x00F, 0x0A4, 0x012, 0x0E9, - 0x080, 0x04E, 0x082, 0x0AC, 0x080, 0x0AC, 0x0A0, 0x0AC, - 0x0A9, 0x059, 0x0E5, 0x064, 0x045, 0x065, 0x0CA, 0x0C8, - 0x04A, 0x0CE, 0x00A, 0x0CE, 0x04A, 0x0CE, 0x095, 0x091, - 0x095, 0x094, 0x095, 0x093, 0x029, 0x025, 0x0C0, 0x0CC, - 0x0CC, 0x088, 0x0A4, 0x097, 0x056, 0x036, 0x064, 0x072, - 0x090, 0x054, 0x08A, 0x09C, 0x045, 0x008, 0x0B9, 0x0B7, - 0x066, 0x012, 0x093, 0x009, 0x0C9, 0x0B2, 0x074, 0x08E, - 0x0BA, 0x060, 0x013, 0x0E5, 0x034, 0x08E, 0x0BA, 0x060, - 0x013, 0x0E4, 0x074, 0x08E, 0x0BA, 0x060, 0x013, 0x0E5, - 0x069, 0x01D, 0x074, 0x0C0, 0x027, 0x0CA, 0x029, 0x01D, - 0x074, 0x0C0, 0x027, 0x0CE, 0x0D2, 0x025, 0x0D3, 0x000, - 0x09F, 0x038, 0x0A4, 0x04B, 0x0A6, 0x001, 0x03E, 0x05E, - 0x091, 0x02E, 0x098, 0x004, 0x0F9, 0x015, 0x022, 0x05D, - 0x030, 0x009, 0x0F3, 0x0E9, 0x012, 0x0E9, 0x080, 0x04F, - 0x090, 0x052, 0x025, 0x0D3, 0x000, 0x09D, 0x0C5, 0x048, - 0x025, 0x0D3, 0x000, 0x09C, 0x045, 0x0CE, 0x0CD, 0x009, - 0x0C9, 0x0B2, 0x01A, 0x044, 0x0BA, 0x060, 0x013, 0x0E7, - 0x034, 0x089, 0x074, 0x0C0, 0x027, 0x01C, 0x027, 0x0B7, - 0x09C, 0x080, 0x0C2, 0x0D7, 0x076, 0x059, 0x09B, 0x093, - 0x00C, 0x064, 0x0C3, 0x01D, 0x01B, 0x0F4, 0x045, 0x04B, - 0x0C7, 0x0C6, 0x03A, 0x037, 0x0E8, 0x081, 0x04B, 0x0C7, - 0x0C6, 0x03A, 0x037, 0x0E8, 0x091, 0x04B, 0x0C7, 0x0C6, - 0x032, 0x061, 0x08E, 0x0B3, 0x0BC, 0x0C3, 0x04A, 0x022, - 0x0E6, 0x0B5, 0x024, 0x097, 0x071, 0x0C9, 0x087, 0x0B4, - 0x031, 0x0AE, 0x073, 0x0A2, 0x0CF, 0x039, 0x0D2, 0x05D, - 0x004, 0x044, 0x042, 0x0C0, 0x0D6, 0x0DE, 0x071, 0x006, - 0x016, 0x0BB, 0x0DB, 0x0CE, 0x083, 0x00C, 0x064, 0x0C3, - 0x01D, 0x031, 0x013, 0x004, 0x0F9, 0x095, 0x04D, 0x013, - 0x032, 0x093, 0x063, 0x05E, 0x066, 0x014, 0x0CC, 0x029, - 0x02A, 0x053, 0x030, 0x0A6, 0x061, 0x04C, 0x0C2, 0x099, - 0x085, 0x03A, 0x072, 0x0CC, 0x0C2, 0x099, 0x085, 0x006, - 0x01B, 0x0B3, 0x00A, 0x066, 0x014, 0x014, 0x024, 0x099, - 0x085, 0x033, 0x00A, 0x008, 0x0B1, 0x086, 0x061, 0x04C, - 0x0C2, 0x084, 0x021, 0x068, 0x073, 0x03B, 0x030, 0x0A6, - 0x061, 0x041, 0x04E, 0x0A5, 0x098, 0x053, 0x030, 0x0AC, - 0x059, 0x076, 0x061, 0x04C, 0x0C2, 0x0B0, 0x08D, 0x0D6, - 0x061, 0x04C, 0x0C2, 0x0B0, 0x02C, 0x0F6, 0x061, 0x04C, - 0x0C2, 0x0B1, 0x08C, 0x0A5, 0x098, 0x053, 0x030, 0x0AC, - 0x00F, 0x024, 0x0CC, 0x029, 0x098, 0x056, 0x00F, 0x028, - 0x066, 0x015, 0x092, 0x01A, 0x019, 0x085, 0x033, 0x00A, - 0x0CA, 0x085, 0x00C, 0x0C2, 0x099, 0x085, 0x065, 0x0C3, - 0x0D9, 0x085, 0x033, 0x00A, 0x0CE, 0x070, 0x086, 0x061, - 0x04C, 0x0C2, 0x0B3, 0x097, 0x071, 0x00C, 0x099, 0x03B, - 0x0CC, 0x083, 0x058, 0x00B, 0x0EA, 0x077, 0x09D, 0x006, - 0x04A, 0x0BE, 0x004, 0x074, 0x060, 0x0E0, 0x0D1, 0x04E, - 0x038, 0x04C, 0x03E, 0x0EE, 0x03E, 0x0EE, 0x03E, 0x0EE, - 0x03E, 0x0EE, 0x030, 0x0BB, 0x0CA, 0x0E1, 0x01F, 0x077, - 0x01F, 0x077, 0x01F, 0x077, 0x01F, 0x077, 0x027, 0x070, - 0x08F, 0x0BB, 0x080, 0x00E, 0x011, 0x0F7, 0x071, 0x0F7, - 0x07C, 0x06F, 0x03C, 0x0B3, 0x036, 0x002, 0x0FB, 0x08D, - 0x0E6, 0x055, 0x070, 0x07F, 0x02D, 0x024, 0x069, 0x055, - 0x04F, 0x058, 0x0A9, 0x023, 0x01F, 0x054, 0x0F7, 0x08A, - 0x095, 0x025, 0x02B, 0x075, 0x00C, 0x0CC, 0x0AC, 0x056, - 0x051, 0x0CC, 0x051, 0x0E4, 0x045, 0x0CE, 0x0A2, 0x012, - 0x039, 0x0C0, 0x0A0, 0x0AF, 0x056, 0x06A, 0x049, 0x07F, - 0x002, 0x08C, 0x009, 0x0F8, 0x00B, 0x0EB, 0x0AF, 0x056, - 0x076, 0x067, 0x052, 0x0B2, 0x08E, 0x069, 0x0A7, 0x011, - 0x073, 0x0A8, 0x0B1, 0x0BC, 0x0CA, 0x0A0, 0x0A9, 0x036, - 0x050, 0x02C, 0x098, 0x0E7, 0x00A, 0x0F5, 0x066, 0x0A4, - 0x097, 0x0E2, 0x05A, 0x030, 0x027, 0x0BA, 0x0F7, 0x083, - 0x04E, 0x0A5, 0x033, 0x00A, 0x066, 0x015, 0x08D, 0x0E6, - 0x055, 0x039, 0x0D2, 0x0A7, 0x0AC, 0x054, 0x060, 0x016, - 0x070, 0x01B, 0x072, 0x08E, 0x062, 0x08F, 0x022, 0x02E, - 0x075, 0x016, 0x002, 0x0FB, 0x08D, 0x0E6, 0x00A, 0x095, - 0x03D, 0x062, 0x0A3, 0x000, 0x0B7, 0x001, 0x0B5, 0x053, - 0x0DE, 0x02A, 0x054, 0x094, 0x0AD, 0x0D4, 0x033, 0x032, - 0x0B1, 0x059, 0x047, 0x031, 0x047, 0x091, 0x017, 0x03A, - 0x088, 0x048, 0x0E7, 0x002, 0x0B0, 0x017, 0x0DC, 0x067, - 0x09D, 0x04B, 0x08D, 0x0E7, 0x052, 0x0AA, 0x07B, 0x0D4, - 0x0AA, 0x092, 0x0BD, 0x0D6, 0x099, 0x0BC, 0x056, 0x002, - 0x0FB, 0x08C, 0x0F3, 0x066, 0x066, 0x0C6, 0x0F3, 0x066, - 0x066, 0x062, 0x099, 0x02A, 0x0F8, 0x018, 0x068, 0x070, - 0x0B0, 0x08A, 0x00D, 0x055, 0x055, 0x055, 0x055, 0x052, - 0x032, 0x0E1, 0x040, 0x05C, 0x038, 0x00B, 0x0EA, 0x09B, - 0x087, 0x001, 0x07D, 0x0C0, 0x05F, 0x070, 0x017, 0x0DC, - 0x005, 0x0F5, 0x0DC, 0x09B, 0x001, 0x07D, 0x061, 0x04D, - 0x080, 0x0BE, 0x0A7, 0x079, 0x082, 0x0A2, 0x01F, 0x050, - 0x015, 0x02A, 0x08F, 0x08B, 0x01C, 0x0E5, 0x0A5, 0x013, - 0x084, 0x058, 0x0E7, 0x002, 0x091, 0x054, 0x005, 0x002, - 0x04B, 0x0BD, 0x022, 0x01A, 0x094, 0x07F, 0x09C, 0x01A, - 0x0C0, 0x05F, 0x042, 0x01A, 0x021, 0x0D1, 0x080, 0x059, - 0x0C0, 0x06D, 0x01C, 0x02C, 0x00A, 0x083, 0x055, 0x055, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, - 0x055, 0x054, 0x01C, 0x0B8, 0x05C, 0x06E, 0x017, 0x09C, - 0x02F, 0x038, 0x05E, 0x070, 0x0E7, 0x0B8, 0x05E, 0x070, - 0x0BC, 0x0E1, 0x079, 0x0C2, 0x0F3, 0x085, 0x0E7, 0x00B, - 0x0CE, 0x017, 0x09C, 0x029, 0x09C, 0x029, 0x09C, 0x029, - 0x09C, 0x023, 0x00F, 0x058, 0x014, 0x0EE, 0x035, 0x077, - 0x026, 0x021, 0x093, 0x005, 0x0C9, 0x0B0, 0x017, 0x0D2, - 0x01D, 0x018, 0x08A, 0x021, 0x093, 0x005, 0x0C9, 0x0B0, - 0x017, 0x0D1, 0x087, 0x0AC, 0x00A, 0x074, 0x00F, 0x0AE, - 0x0F5, 0x05A, 0x082, 0x0A3, 0x0E4, 0x03A, 0x031, 0x014, - 0x0BB, 0x0D7, 0x059, 0x099, 0x074, 0x0A2, 0x019, 0x030, - 0x05C, 0x09B, 0x001, 0x07D, 0x018, 0x07A, 0x0C0, 0x0A7, - 0x040, 0x0F8, 0x043, 0x0D4, 0x063, 0x089, 0x025, 0x0D0, - 0x010, 0x0D6, 0x01C, 0x06A, 0x010, 0x0F5, 0x055, 0x089, - 0x025, 0x0D1, 0x051, 0x066, 0x01F, 0x051, 0x0F5, 0x091, - 0x049, 0x02E, 0x089, 0x015, 0x098, 0x06A, 0x0A3, 0x0E0, - 0x08A, 0x094, 0x065, 0x064, 0x00E, 0x013, 0x017, 0x038, - 0x0A8, 0x086, 0x04C, 0x017, 0x026, 0x0C0, 0x05F, 0x046, - 0x01E, 0x0B0, 0x028, 0x063, 0x01F, 0x008, 0x07A, 0x08C, - 0x071, 0x024, 0x0BA, 0x002, 0x01A, 0x0D0, 0x00D, 0x042, - 0x01E, 0x0AA, 0x0B1, 0x024, 0x0BA, 0x02A, 0x02D, 0x031, - 0x0F5, 0x01F, 0x058, 0x074, 0x092, 0x0E8, 0x087, 0x05A, - 0x063, 0x052, 0x0DE, 0x0F4, 0x051, 0x069, 0x04A, 0x03E, - 0x009, 0x069, 0x046, 0x050, 0x0F0, 0x0E1, 0x031, 0x073, - 0x005, 0x045, 0x0BD, 0x059, 0x08D, 0x08B, 0x04A, 0x07C, - 0x0D3, 0x0ED, 0x038, 0x0E9, 0x0D3, 0x04E, 0x074, 0x0ED, - 0x044, 0x032, 0x060, 0x0B9, 0x036, 0x002, 0x0FA, 0x05B, - 0x0DE, 0x08A, 0x02D, 0x029, 0x0D0, 0x0E1, 0x021, 0x0F5, - 0x0A3, 0x092, 0x021, 0x0F2, 0x019, 0x030, 0x05C, 0x09B, - 0x001, 0x07D, 0x021, 0x0F5, 0x0A0, 0x0C6, 0x001, 0x067, - 0x001, 0x0B4, 0x045, 0x0CE, 0x0A5, 0x012, 0x039, 0x0D4, - 0x01C, 0x005, 0x0F4, 0x040, 0x0A1, 0x0C2, 0x0C3, 0x050, - 0x06A, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, - 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x081, 0x0AF, - 0x086, 0x09F, 0x019, 0x01B, 0x0E7, 0x081, 0x0F3, 0x065, - 0x0F2, 0x080, 0x0BE, 0x070, 0x017, 0x0DF, 0x0DF, 0x038, - 0x00B, 0x0EB, 0x00D, 0x0C3, 0x080, 0x0BE, 0x0A7, 0x00F, - 0x095, 0x04F, 0x05A, 0x094, 0x0C0, 0x02C, 0x0D8, 0x0B1, - 0x0A7, 0x0CE, 0x05A, 0x011, 0x073, 0x0A8, 0x03A, 0x0C2, - 0x0CC, 0x0B6, 0x030, 0x017, 0x0DC, 0x06F, 0x035, 0x0A9, - 0x080, 0x04D, 0x0A7, 0x0CE, 0x02A, 0x018, 0x079, 0x0C5, - 0x049, 0x0DE, 0x061, 0x0A8, 0x022, 0x0E7, 0x050, 0x033, - 0x0F9, 0x098, 0x064, 0x008, 0x0B9, 0x095, 0x042, 0x0FC, - 0x0CC, 0x0D9, 0x095, 0x03D, 0x062, 0x0A2, 0x048, 0x0D4, - 0x048, 0x0E7, 0x002, 0x088, 0x0B9, 0x0C1, 0x0A0, 0x0E3, - 0x09D, 0x04E, 0x062, 0x0E6, 0x0CC, 0x0C6, 0x06B, 0x0CE, - 0x083, 0x010, 0x0C9, 0x082, 0x0E4, 0x0DA, 0x0C2, 0x0C8, - 0x01E, 0x0C3, 0x0B9, 0x036, 0x002, 0x0FA, 0x0A9, 0x0EB, - 0x04E, 0x030, 0x030, 0x0FA, 0x00D, 0x0F0, 0x0A9, 0x0EB, - 0x040, 0x0B9, 0x00F, 0x0AA, 0x07A, 0x0D2, 0x0C2, 0x0C8, - 0x0FA, 0x0A7, 0x0AD, 0x041, 0x00A, 0x047, 0x0D5, 0x03D, - 0x068, 0x0AC, 0x0F1, 0x0F5, 0x04F, 0x05A, 0x097, 0x054, - 0x07D, 0x04F, 0x0A8, 0x0AA, 0x055, 0x01F, 0x011, 0x073, - 0x05A, 0x0B0, 0x017, 0x0DE, 0x05D, 0x059, 0x0A9, 0x025, - 0x0D0, 0x055, 0x02A, 0x046, 0x0BC, 0x0B8, 0x022, 0x0AE, - 0x045, 0x029, 0x03E, 0x014, 0x0FA, 0x0E1, 0x099, 0x094, - 0x0CA, 0x04A, 0x0BE, 0x03D, 0x0D6, 0x099, 0x092, 0x05D, - 0x015, 0x017, 0x0C8, 0x0D7, 0x0DC, 0x015, 0x017, 0x08A, - 0x040, 0x01F, 0x00A, 0x09E, 0x0AC, 0x0C9, 0x065, 0x049, - 0x05C, 0x01D, 0x010, 0x068, 0x04A, 0x03E, 0x05B, 0x0DE, - 0x083, 0x016, 0x095, 0x080, 0x0BE, 0x091, 0x074, 0x058, - 0x0A4, 0x000, 0x07C, 0x038, 0x0E7, 0x056, 0x030, 0x017, - 0x0DF, 0x075, 0x0A6, 0x064, 0x097, 0x045, 0x020, 0x09D, - 0x003, 0x05F, 0x070, 0x054, 0x05E, 0x029, 0x01D, 0x0F0, - 0x0A9, 0x0EA, 0x0CC, 0x086, 0x054, 0x095, 0x0C1, 0x0D1, - 0x006, 0x083, 0x00F, 0x0AA, 0x07B, 0x0D0, 0x065, 0x049, - 0x045, 0x0BD, 0x0E9, 0x062, 0x0D2, 0x091, 0x0DF, 0x004, - 0x05D, 0x016, 0x029, 0x01C, 0x07D, 0x04F, 0x0AC, 0x01A, - 0x047, 0x01A, 0x0A9, 0x0F5, 0x067, 0x066, 0x053, 0x028, - 0x0B7, 0x0BD, 0x02C, 0x05A, 0x052, 0x03B, 0x0E3, 0x0DD, - 0x059, 0x0A9, 0x025, 0x0D1, 0x0A8, 0x0AC, 0x008, 0x06B, - 0x0EE, 0x008, 0x0AB, 0x0C5, 0x020, 0x02F, 0x085, 0x04F, - 0x056, 0x066, 0x075, 0x049, 0x05C, 0x01C, 0x018, 0x01D, - 0x081, 0x0C2, 0x064, 0x005, 0x0F0, 0x080, 0x0BE, 0x035, - 0x05C, 0x0D0, 0x017, 0x0C2, 0x055, 0x0F0, 0x095, 0x07C, - 0x025, 0x05F, 0x008, 0x00B, 0x0E1, 0x001, 0x07C, 0x07B, - 0x0AB, 0x035, 0x024, 0x0BA, 0x010, 0x055, 0x093, 0x01A, - 0x0FB, 0x082, 0x02A, 0x0F1, 0x048, 0x0D7, 0x0C2, 0x0A7, - 0x0AB, 0x031, 0x0B2, 0x0A4, 0x0AC, 0x063, 0x09D, 0x04A, - 0x08D, 0x07C, 0x07B, 0x0AB, 0x035, 0x024, 0x0BA, 0x010, - 0x054, 0x030, 0x08D, 0x07D, 0x0C1, 0x015, 0x078, 0x0AC, - 0x06F, 0x05A, 0x094, 0x060, 0x01A, 0x0E3, 0x079, 0x0D4, - 0x0AA, 0x04F, 0x085, 0x04F, 0x056, 0x066, 0x0D5, 0x049, - 0x058, 0x0C7, 0x03A, 0x095, 0x049, 0x0F0, 0x045, 0x0D1, - 0x062, 0x094, 0x086, 0x0BC, 0x01D, 0x013, 0x0D2, 0x090, - 0x0FF, 0x0CF, 0x07A, 0x083, 0x0F2, 0x050, 0x031, 0x0DE, - 0x000, 0x060, 0x060, 0x0A1, 0x017, 0x035, 0x0A8, 0x05F, - 0x09B, 0x01B, 0x037, 0x007, 0x044, 0x01A, 0x030, 0x00B, - 0x038, 0x00D, 0x0BC, 0x01C, 0x0E0, 0x0D0, 0x047, 0x0CE, - 0x0A0, 0x0AA, 0x07A, 0x0A1, 0x098, 0x06A, 0x092, 0x095, - 0x03D, 0x068, 0x031, 0x080, 0x05B, 0x080, 0x0DA, 0x0A9, - 0x0EF, 0x041, 0x095, 0x025, 0x016, 0x0F7, 0x0A5, 0x08B, - 0x04A, 0x0C6, 0x079, 0x0B3, 0x033, 0x060, 0x02F, 0x0AA, - 0x09E, 0x0B1, 0x051, 0x080, 0x059, 0x09E, 0x0CA, 0x0A7, - 0x0AC, 0x00A, 0x030, 0x00B, 0x067, 0x0B2, 0x0AD, 0x0D5, - 0x0DA, 0x092, 0x05D, 0x017, 0x0A3, 0x000, 0x0B3, 0x02D, - 0x095, 0x06E, 0x008, 0x0A9, 0x058, 0x0A1, 0x017, 0x03A, - 0x08B, 0x001, 0x07D, 0x054, 0x0F7, 0x08E, 0x095, 0x025, - 0x008, 0x01C, 0x0E0, 0x056, 0x002, 0x0FB, 0x0C1, 0x0D1, - 0x015, 0x018, 0x005, 0x092, 0x06B, 0x03C, 0x01D, 0x012, - 0x028, 0x0C0, 0x02C, 0x0A5, 0x06C, 0x011, 0x070, 0x017, - 0x0B2, 0x038, 0x04D, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0B4, - 0x0EC, 0x04A, 0x0ED, 0x0B3, 0x09E, 0x002, 0x0FB, 0x080, - 0x0BE, 0x0E0, 0x02F, 0x0B1, 0x039, 0x093, 0x03E, 0x06D, - 0x0E7, 0x010, 0x060, 0x09F, 0x032, 0x0A9, 0x0A2, 0x06C, - 0x005, 0x0F4, 0x040, 0x0E6, 0x00A, 0x095, 0x03D, 0x06A, - 0x023, 0x000, 0x0B3, 0x080, 0x0DA, 0x0A7, 0x0D6, 0x02A, - 0x003, 0x00D, 0x070, 0x017, 0x0D2, 0x02E, 0x076, 0x029, - 0x04F, 0x0BC, 0x054, 0x0A6, 0x051, 0x06F, 0x07A, 0x058, - 0x0B4, 0x0AC, 0x005, 0x0F4, 0x08B, 0x0A2, 0x0F4, 0x00E, - 0x035, 0x00D, 0x049, 0x02E, 0x0B4, 0x0CC, 0x018, 0x0A5, - 0x0C8, 0x0F8, 0x04A, 0x097, 0x023, 0x0E1, 0x005, 0x02E, - 0x047, 0x0C2, 0x08A, 0x05C, 0x08F, 0x085, 0x069, 0x072, - 0x03E, 0x01F, 0x04A, 0x0C3, 0x055, 0x01F, 0x056, 0x043, - 0x032, 0x08C, 0x0A3, 0x05E, 0x060, 0x0A8, 0x045, 0x0CE, - 0x00D, 0x060, 0x02F, 0x0A3, 0x084, 0x09D, 0x0D8, 0x0F0, - 0x017, 0x0D2, 0x02E, 0x00E, 0x01B, 0x023, 0x084, 0x0D8, - 0x00B, 0x0EB, 0x089, 0x0F3, 0x080, 0x0BE, 0x0E0, 0x02F, - 0x0BB, 0x039, 0x085, 0x0DF, 0x022, 0x003, 0x0E7, 0x001, - 0x07D, 0x0C0, 0x05F, 0x070, 0x017, 0x0D1, 0x017, 0x038, - 0x014, 0x05B, 0x0D6, 0x0A2, 0x074, 0x00D, 0x04B, 0x07A, - 0x0B3, 0x031, 0x096, 0x094, 0x06B, 0x0CC, 0x035, 0x023, - 0x0D7, 0x049, 0x048, 0x015, 0x073, 0x029, 0x00F, 0x05D, - 0x08A, 0x0C0, 0x05F, 0x04D, 0x079, 0x084, 0x035, 0x080, - 0x0BE, 0x088, 0x01C, 0x0C3, 0x052, 0x09F, 0x059, 0x068, - 0x0C0, 0x02C, 0x0E0, 0x036, 0x0AA, 0x07B, 0x0CD, 0x04A, - 0x092, 0x0BE, 0x0F3, 0x081, 0x04A, 0x07D, 0x05B, 0x059, - 0x094, 0x0CA, 0x01C, 0x024, 0x0EE, 0x0C7, 0x080, 0x0BE, - 0x088, 0x01C, 0x0C3, 0x052, 0x09F, 0x059, 0x068, 0x0C0, - 0x02C, 0x0E0, 0x036, 0x0AA, 0x07B, 0x0CD, 0x04A, 0x092, - 0x0BE, 0x0F3, 0x081, 0x043, 0x084, 0x09C, 0x07B, 0x038, - 0x00B, 0x0EB, 0x0AF, 0x070, 0x0D4, 0x0EA, 0x053, 0x000, - 0x09B, 0x04F, 0x09C, 0x054, 0x030, 0x0F3, 0x08A, 0x094, - 0x0FA, 0x0B6, 0x0B3, 0x029, 0x094, 0x022, 0x0E6, 0x01A, - 0x085, 0x0F9, 0x0B0, 0x059, 0x093, 0x0F9, 0x0D2, 0x0C4, - 0x032, 0x060, 0x0B9, 0x036, 0x0B0, 0x0B3, 0x090, 0x0D9, - 0x077, 0x026, 0x01C, 0x027, 0x022, 0x0E8, 0x096, 0x0B4, - 0x023, 0x0EA, 0x09E, 0x0B5, 0x011, 0x080, 0x059, 0x065, - 0x086, 0x020, 0x073, 0x096, 0x08D, 0x079, 0x0AD, 0x058, - 0x00B, 0x0E9, 0x017, 0x044, 0x08A, 0x04A, 0x007, 0x0D7, - 0x07A, 0x082, 0x0A1, 0x090, 0x0FA, 0x0EF, 0x001, 0x054, - 0x0BA, 0x050, 0x0D4, 0x059, 0x01E, 0x02C, 0x0E9, 0x0F3, - 0x08A, 0x099, 0x085, 0x06B, 0x00B, 0x023, 0x015, 0x097, - 0x072, 0x061, 0x017, 0x030, 0x0D4, 0x02C, 0x073, 0x087, - 0x048, 0x0AA, 0x002, 0x081, 0x025, 0x0DE, 0x091, 0x00D, - 0x04A, 0x0C0, 0x05F, 0x07E, 0x0D2, 0x080, 0x0A5, 0x03E, - 0x0B2, 0x0D0, 0x0C8, 0x06B, 0x080, 0x0BE, 0x088, 0x01C, - 0x0EA, 0x009, 0x017, 0x044, 0x01A, 0x037, 0x01A, 0x091, - 0x074, 0x058, 0x0A3, 0x071, 0x0AF, 0x007, 0x044, 0x054, - 0x06E, 0x035, 0x0E0, 0x0E8, 0x0AA, 0x064, 0x00F, 0x090, - 0x0FA, 0x0D0, 0x063, 0x000, 0x0B3, 0x080, 0x0DA, 0x02C, - 0x073, 0x087, 0x048, 0x0AA, 0x002, 0x081, 0x025, 0x0DE, - 0x091, 0x00D, 0x04A, 0x0C0, 0x05F, 0x048, 0x0BA, 0x027, - 0x0A3, 0x000, 0x0B7, 0x001, 0x0B7, 0x04F, 0x09C, 0x0B4, - 0x06B, 0x0CC, 0x035, 0x016, 0x0F5, 0x066, 0x063, 0x02D, - 0x029, 0x01E, 0x0BA, 0x04A, 0x040, 0x0AB, 0x099, 0x048, - 0x07A, 0x0EC, 0x050, 0x08B, 0x09C, 0x008, 0x022, 0x0FC, - 0x0F9, 0x0B2, 0x055, 0x03D, 0x062, 0x0A9, 0x023, 0x051, - 0x023, 0x09C, 0x00A, 0x03C, 0x073, 0x00D, 0x044, 0x05C, - 0x0E1, 0x050, 0x071, 0x0CE, 0x0A1, 0x01F, 0x0E7, 0x015, - 0x06B, 0x00B, 0x025, 0x0ED, 0x00B, 0x093, 0x060, 0x02F, - 0x0AA, 0x09E, 0x0AC, 0x036, 0x065, 0x049, 0x05F, 0x07A, - 0x020, 0x050, 0x008, 0x07F, 0x0EF, 0x039, 0x014, 0x049, - 0x001, 0x011, 0x081, 0x004, 0x060, 0x040, 0x0CC, 0x059, - 0x0C0, 0x0AD, 0x023, 0x0EB, 0x041, 0x0B0, 0x081, 0x0F2, - 0x03A, 0x041, 0x0AA, 0x050, 0x043, 0x0E4, 0x0D4, 0x086, - 0x054, 0x0A0, 0x087, 0x0C1, 0x052, 0x0CA, 0x093, 0x001, - 0x032, 0x054, 0x09D, 0x024, 0x002, 0x000, 0x000, 0x052, - 0x0AF, 0x016, 0x046, 0x0A7, 0x091, 0x067, 0x008, 0x0B4, - 0x004, 0x051, 0x0F1, 0x065, 0x019, 0x0B4, 0x06E, 0x02D, - 0x0C0, 0x0AD, 0x049, 0x000, 0x092, 0x057, 0x01B, 0x074, - 0x045, 0x05F, 0x023, 0x051, 0x0B7, 0x044, 0x00A, 0x010, - 0x006, 0x0A3, 0x06E, 0x08B, 0x06B, 0x008, 0x01F, 0x019, - 0x0D1, 0x0E6, 0x080, 0x082, 0x080, 0x054, 0x004, 0x02A, - 0x045, 0x091, 0x0A9, 0x0E4, 0x059, 0x0C2, 0x02D, 0x001, - 0x014, 0x004, 0x050, 0x0D3, 0x0FC, 0x055, 0x084, 0x061, - 0x0D9, 0x080, 0x051, 0x02F, 0x0E2, 0x01F, 0x046, 0x05F, - 0x040, 0x0E0, 0x020, 0x015, 0x04A, 0x0BC, 0x059, 0x01A, - 0x09E, 0x045, 0x09C, 0x022, 0x0D0, 0x011, 0x048, 0x0CB, - 0x0E8, 0x014, 0x008, 0x001, 0x054, 0x015, 0x0E2, 0x0C8, - 0x0D4, 0x0F2, 0x02C, 0x0E1, 0x016, 0x080, 0x08A, 0x046, - 0x05F, 0x052, 0x07C, 0x0D9, 0x0A8, 0x0F8, 0x088, 0x0D0, - 0x05A, 0x03C, 0x0D2, 0x05C, 0x05B, 0x080, 0x0DA, 0x0A7, - 0x0D6, 0x05A, 0x008, 0x086, 0x0A4, 0x05D, 0x017, 0x0A0, - 0x0C3, 0x052, 0x02E, 0x088, 0x0A8, 0x022, 0x01F, 0x053, - 0x0EA, 0x0DA, 0x0CC, 0x0A6, 0x050, 0x0E1, 0x027, 0x076, - 0x03C, 0x005, 0x0F5, 0x04F, 0x0AB, 0x06B, 0x032, 0x099, - 0x043, 0x084, 0x09C, 0x07B, 0x038, 0x00B, 0x0E9, 0x027, - 0x0AC, 0x0D4, 0x092, 0x0E0, 0x00E, 0x0DA, 0x038, 0x04D, - 0x080, 0x0BE, 0x0E6, 0x07D, 0x050, 0x0BA, 0x051, 0x0AE, - 0x066, 0x0EF, 0x0BC, 0x0DC, 0x07B, 0x087, 0x01E, 0x002, - 0x0FA, 0x093, 0x0E6, 0x0CD, 0x047, 0x0C4, 0x043, 0x0CD, - 0x00F, 0x034, 0x09D, 0x0A3, 0x000, 0x0B0, 0x055, 0x001, - 0x0AE, 0x003, 0x084, 0x004, 0x0CE, 0x001, 0x0D0, 0x0E1, - 0x070, 0x002, 0x080, 0x00E, 0x089, 0x0E9, 0x022, 0x01F, - 0x0E0, 0x0E8, 0x096, 0x0B0, 0x011, 0x0F4, 0x0C2, 0x0CE, - 0x003, 0x06A, 0x044, 0x02D, 0x0C0, 0x06D, 0x048, 0x005, - 0x0B8, 0x00D, 0x0A3, 0x000, 0x0B7, 0x076, 0x0D5, 0x0DE, - 0x0B1, 0x050, 0x0DC, 0x07D, 0x077, 0x0BC, 0x054, 0x0BA, - 0x052, 0x07F, 0x058, 0x014, 0x034, 0x00F, 0x09A, 0x0F3, - 0x081, 0x058, 0x00B, 0x0EA, 0x0EF, 0x058, 0x014, 0x060, - 0x016, 0x0A5, 0x06C, 0x02E, 0x0F7, 0x081, 0x04B, 0x0A5, - 0x06F, 0x07D, 0x05D, 0x0EE, 0x0B5, 0x02E, 0x095, 0x080, - 0x0BE, 0x0F0, 0x073, 0x0BD, 0x004, 0x07C, 0x0EA, 0x0FE, - 0x0EB, 0x04C, 0x0DE, 0x029, 0x053, 0x0DD, 0x06A, 0x054, - 0x094, 0x0A9, 0x0EA, 0x00A, 0x08C, 0x002, 0x0D6, 0x04C, - 0x03C, 0x005, 0x0F4, 0x000, 0x0EA, 0x0CD, 0x056, 0x0AF, - 0x0C0, 0x047, 0x0D2, 0x09C, 0x08D, 0x029, 0x0CA, 0x0E0, - 0x02F, 0x0AE, 0x0BD, 0x075, 0x099, 0x09D, 0x04A, 0x0F9, - 0x0EF, 0x051, 0x07C, 0x094, 0x00C, 0x077, 0x080, 0x018, - 0x018, 0x029, 0x02A, 0x0F8, 0x0E0, 0x0E8, 0x0AA, 0x030, - 0x00B, 0x02A, 0x098, 0x07C, 0x01D, 0x011, 0x051, 0x080, - 0x059, 0x054, 0x0C3, 0x051, 0x0F5, 0x01B, 0x033, 0x024, - 0x0BB, 0x082, 0x0A5, 0x019, 0x05C, 0x01D, 0x010, 0x028, - 0x0C0, 0x02C, 0x09A, 0x0C7, 0x0C1, 0x0D1, 0x022, 0x08C, - 0x002, 0x0C9, 0x094, 0x064, 0x05C, 0x00C, 0x0D6, 0x08E, - 0x013, 0x060, 0x02F, 0x0B8, 0x00B, 0x0EA, 0x030, 0x0E3, - 0x0C0, 0x05F, 0x048, 0x0DC, 0x078, 0x00B, 0x0E8, 0x000, - 0x0E3, 0x0C0, 0x05F, 0x06C, 0x038, 0x0D5, 0x02E, 0x035, - 0x04F, 0x05A, 0x08A, 0x061, 0x0AA, 0x09F, 0x056, 0x01B, - 0x032, 0x099, 0x046, 0x042, 0x0C8, 0x001, 0x00C, 0x045, - 0x0CE, 0x0A5, 0x017, 0x0E6, 0x0C6, 0x0CE, 0x0A9, 0x0EB, - 0x015, 0x016, 0x046, 0x0A2, 0x047, 0x038, 0x014, 0x043, - 0x026, 0x022, 0x0E7, 0x03D, 0x060, 0x02F, 0x0AA, 0x09E, - 0x0B5, 0x012, 0x0E0, 0x07F, 0x001, 0x07D, 0x0E3, 0x0E7, - 0x002, 0x093, 0x0F9, 0x095, 0x044, 0x05C, 0x0E5, 0x0A0, - 0x0E3, 0x09D, 0x04A, 0x07F, 0x09C, 0x054, 0x0A9, 0x0EB, - 0x051, 0x005, 0x046, 0x0B9, 0x0FC, 0x0C0, 0x01B, 0x022, - 0x02E, 0x064, 0x054, 0x02F, 0x0CD, 0x046, 0x0CC, 0x0A7, - 0x0D5, 0x086, 0x0CC, 0x0A6, 0x050, 0x055, 0x0C6, 0x045, - 0x0CE, 0x05A, 0x00E, 0x039, 0x0D4, 0x0A7, 0x0F9, 0x0C5, - 0x04A, 0x09E, 0x0B5, 0x011, 0x080, 0x059, 0x0C0, 0x06D, - 0x0CF, 0x0E6, 0x000, 0x0D9, 0x011, 0x073, 0x022, 0x0A1, - 0x07E, 0x06A, 0x036, 0x065, 0x03E, 0x0AC, 0x036, 0x065, - 0x032, 0x0B0, 0x017, 0x0DD, 0x03E, 0x072, 0x0D2, 0x079, - 0x031, 0x00C, 0x098, 0x02E, 0x04C, 0x020, 0x073, 0x02A, - 0x08F, 0x0F3, 0x08A, 0x0AD, 0x0E7, 0x041, 0x082, 0x07C, - 0x0CA, 0x0A6, 0x089, 0x0B5, 0x085, 0x09F, 0x0B0, 0x0F0, - 0x017, 0x0D5, 0x01F, 0x054, 0x054, 0x025, 0x01A, 0x0A8, - 0x0FF, 0x02A, 0x094, 0x065, 0x011, 0x0D7, 0x049, 0x044, - 0x0D5, 0x0CC, 0x0A0, 0x055, 0x0D8, 0x0AE, 0x00E, 0x088, - 0x014, 0x060, 0x016, 0x04D, 0x063, 0x022, 0x0E0, 0x072, - 0x086, 0x038, 0x04D, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0B8, - 0x00B, 0x0EE, 0x002, 0x0FB, 0x081, 0x038, 0x0F0, 0x017, - 0x0D7, 0x0D7, 0x01E, 0x002, 0x0FA, 0x0FA, 0x0E3, 0x0C0, - 0x05F, 0x04C, 0x085, 0x090, 0x002, 0x018, 0x0C8, 0x05B, - 0x080, 0x0DA, 0x030, 0x00B, 0x070, 0x01B, 0x04C, 0x022, - 0x0D3, 0x04C, 0x033, 0x003, 0x08C, 0x02E, 0x04C, 0x043, - 0x026, 0x0D0, 0x0F5, 0x063, 0x066, 0x0D0, 0x095, 0x0A7, - 0x0CE, 0x045, 0x033, 0x00A, 0x0D6, 0x016, 0x042, 0x038, - 0x06E, 0x0E4, 0x0CE, 0x0BD, 0x059, 0x02C, 0x0D2, 0x0AB, - 0x0BA, 0x094, 0x09D, 0x0E6, 0x01A, 0x0B0, 0x017, 0x0D5, - 0x04F, 0x05A, 0x08B, 0x009, 0x01A, 0x088, 0x0B9, 0x0C5, - 0x042, 0x047, 0x030, 0x0D4, 0x032, 0x016, 0x072, 0x088, - 0x065, 0x0BD, 0x059, 0x099, 0x025, 0x0A5, 0x060, 0x02F, - 0x0B8, 0x060, 0x0F3, 0x008, 0x0B7, 0x04A, 0x01A, 0x08F, - 0x0AB, 0x00D, 0x099, 0x046, 0x051, 0x0AF, 0x038, 0x0A8, - 0x08E, 0x090, 0x065, 0x013, 0x052, 0x018, 0x0A0, 0x054, - 0x0B1, 0x042, 0x02E, 0x061, 0x0A8, 0x048, 0x0E7, 0x02D, - 0x016, 0x0F7, 0x0A8, 0x005, 0x0A5, 0x060, 0x02F, 0x0A4, - 0x075, 0x0D2, 0x051, 0x035, 0x073, 0x028, 0x015, 0x076, - 0x02B, 0x083, 0x0A2, 0x005, 0x018, 0x005, 0x093, 0x058, - 0x0C8, 0x0B8, 0x006, 0x028, 0x063, 0x084, 0x0D8, 0x00B, - 0x0EE, 0x002, 0x0FB, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0A0, - 0x043, 0x0A7, 0x001, 0x07D, 0x04C, 0x0E3, 0x0C0, 0x05F, - 0x070, 0x017, 0x0DC, 0x005, 0x0F4, 0x064, 0x02D, 0x0C0, - 0x06D, 0x018, 0x005, 0x0B8, 0x00D, 0x0A5, 0x0BD, 0x06A, - 0x023, 0x086, 0x0AA, 0x09E, 0x0B5, 0x011, 0x0A4, 0x06A, - 0x0A3, 0x0EA, 0x08A, 0x08D, 0x023, 0x0E1, 0x017, 0x038, - 0x034, 0x069, 0x071, 0x098, 0x045, 0x0A6, 0x098, 0x06A, - 0x03E, 0x0AC, 0x036, 0x065, 0x019, 0x046, 0x0BC, 0x0E2, - 0x0A2, 0x03A, 0x041, 0x094, 0x04D, 0x048, 0x062, 0x081, - 0x052, 0x0C5, 0x016, 0x0F7, 0x0A8, 0x08B, 0x04A, 0x054, - 0x0F5, 0x0A8, 0x08C, 0x002, 0x0DC, 0x006, 0x0D1, 0x003, - 0x09C, 0x0B4, 0x0A9, 0x0EE, 0x00A, 0x095, 0x025, 0x02A, - 0x07A, 0x0AD, 0x046, 0x001, 0x067, 0x001, 0x0B5, 0x0D7, - 0x0AC, 0x00A, 0x030, 0x00B, 0x06C, 0x049, 0x035, 0x0E6, - 0x0B5, 0x067, 0x0F3, 0x000, 0x06C, 0x088, 0x0B9, 0x091, - 0x050, 0x0BF, 0x031, 0x01B, 0x032, 0x0A7, 0x0B8, 0x068, - 0x095, 0x025, 0x07B, 0x0AD, 0x033, 0x078, 0x0A7, 0x0CD, - 0x03E, 0x0D3, 0x08E, 0x09D, 0x034, 0x0E7, 0x04E, 0x0D4, - 0x022, 0x0E7, 0x006, 0x084, 0x08E, 0x060, 0x0A8, 0x0FF, - 0x038, 0x0AB, 0x083, 0x09C, 0x02A, 0x008, 0x0F9, 0x0D4, - 0x020, 0x063, 0x0BC, 0x01A, 0x006, 0x00A, 0x0C0, 0x05F, - 0x046, 0x042, 0x0DC, 0x006, 0x0D1, 0x080, 0x05B, 0x080, - 0x0DA, 0x022, 0x0E6, 0x01A, 0x084, 0x08E, 0x072, 0x0D1, - 0x06F, 0x05A, 0x080, 0x087, 0x01A, 0x0AA, 0x07A, 0x0D4, - 0x048, 0x0C8, 0x0D5, 0x047, 0x0D5, 0x015, 0x023, 0x023, - 0x0E1, 0x017, 0x038, 0x034, 0x08C, 0x0BA, 0x04B, 0x07B, - 0x0D4, 0x002, 0x0D2, 0x08C, 0x022, 0x0DC, 0x006, 0x0D5, - 0x01F, 0x056, 0x01B, 0x032, 0x08C, 0x0A3, 0x05E, 0x071, - 0x051, 0x01D, 0x020, 0x0CA, 0x026, 0x0A4, 0x031, 0x040, - 0x0A9, 0x062, 0x0B0, 0x017, 0x0DF, 0x09E, 0x0F4, 0x0B7, - 0x0C9, 0x040, 0x0C7, 0x078, 0x001, 0x081, 0x082, 0x0B8, - 0x038, 0x039, 0x049, 0x01C, 0x026, 0x0C0, 0x05F, 0x070, - 0x017, 0x0D4, 0x0AB, 0x0E1, 0x02A, 0x0F8, 0x04A, 0x0BE, - 0x012, 0x0AF, 0x08F, 0x097, 0x04F, 0x0CB, 0x0A7, 0x001, - 0x07D, 0x0DA, 0x080, 0x0AA, 0x091, 0x064, 0x07F, 0x04A, - 0x081, 0x0D5, 0x022, 0x0C8, 0x0FE, 0x082, 0x080, 0x025, - 0x048, 0x0B2, 0x03E, 0x0BB, 0x0DC, 0x035, 0x02E, 0x094, - 0x007, 0x0E8, 0x08A, 0x09C, 0x003, 0x0E2, 0x04B, 0x0A5, - 0x077, 0x0AB, 0x0B3, 0x032, 0x0E9, 0x04B, 0x0BD, 0x059, - 0x086, 0x084, 0x097, 0x07A, 0x004, 0x0BA, 0x053, 0x0E1, - 0x032, 0x0EF, 0x050, 0x0D4, 0x0E6, 0x035, 0x053, 0x0EB, - 0x002, 0x09C, 0x0C7, 0x0D7, 0x07A, 0x0B3, 0x030, 0x0D2, - 0x05D, 0x0EA, 0x002, 0x0E9, 0x044, 0x05D, 0x016, 0x028, - 0x0C0, 0x02C, 0x0E0, 0x036, 0x091, 0x074, 0x045, 0x059, - 0x018, 0x0D5, 0x04F, 0x0AC, 0x00A, 0x0C4, 0x035, 0x030, - 0x08B, 0x038, 0x069, 0x02B, 0x0BD, 0x059, 0x098, 0x069, - 0x02E, 0x0F5, 0x012, 0x0E9, 0x058, 0x067, 0x04A, 0x0EF, - 0x050, 0x0D5, 0x08E, 0x03E, 0x01C, 0x0A4, 0x0B0, 0x0CE, - 0x093, 0x021, 0x06E, 0x01A, 0x048, 0x01F, 0x0A2, 0x02A, - 0x0C3, 0x00D, 0x057, 0x07A, 0x0B3, 0x00D, 0x009, 0x02E, - 0x0F4, 0x043, 0x05D, 0x028, 0x08B, 0x083, 0x020, 0x092, - 0x038, 0x04D, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0AC, 0x017, - 0x049, 0x0B3, 0x0A5, 0x082, 0x0E9, 0x03E, 0x0E9, 0x036, - 0x074, 0x0E0, 0x02F, 0x0A6, 0x0CE, 0x09C, 0x005, 0x0F4, - 0x0C2, 0x02C, 0x08C, 0x052, 0x057, 0x07A, 0x0D4, 0x08D, - 0x048, 0x0FA, 0x0EF, 0x050, 0x0D5, 0x0AE, 0x035, 0x053, - 0x0EB, 0x002, 0x086, 0x021, 0x0AA, 0x0EF, 0x056, 0x066, - 0x01A, 0x04B, 0x0BD, 0x044, 0x0BA, 0x050, 0x0C4, 0x0E9, - 0x053, 0x0EB, 0x002, 0x086, 0x081, 0x0F5, 0x0DE, 0x0A1, - 0x0A8, 0x062, 0x01F, 0x05D, 0x0FE, 0x0A2, 0x05D, 0x029, - 0x077, 0x0A8, 0x06A, 0x061, 0x08D, 0x040, 0x0FD, 0x011, - 0x053, 0x00C, 0x06A, 0x0A7, 0x0D6, 0x005, 0x030, 0x0C7, - 0x0D7, 0x07F, 0x0A9, 0x057, 0x04A, 0x05D, 0x0EB, 0x048, - 0x01B, 0x00C, 0x07C, 0x08B, 0x09D, 0x08A, 0x053, 0x0EF, - 0x066, 0x094, 0x0CA, 0x054, 0x0F5, 0x0A0, 0x0C6, 0x001, - 0x06E, 0x003, 0x06A, 0x09F, 0x056, 0x076, 0x065, 0x032, - 0x08B, 0x07B, 0x0D2, 0x0C5, 0x0A5, 0x060, 0x02F, 0x0AA, - 0x07D, 0x065, 0x0A3, 0x000, 0x0B7, 0x001, 0x0B4, 0x0C8, - 0x05A, 0x007, 0x08F, 0x0ED, 0x001, 0x0D5, 0x027, 0x091, - 0x067, 0x001, 0x0B4, 0x08B, 0x09C, 0x054, 0x01C, 0x073, - 0x0A8, 0x084, 0x05C, 0x0C1, 0x050, 0x0BF, 0x036, 0x056, - 0x060, 0x0AB, 0x08C, 0x08B, 0x09C, 0x054, 0x01C, 0x073, - 0x0A8, 0x084, 0x05C, 0x0C1, 0x050, 0x0BF, 0x036, 0x056, - 0x06C, 0x005, 0x0F5, 0x053, 0x0D6, 0x0A2, 0x030, 0x00B, - 0x029, 0x05B, 0x019, 0x0FC, 0x0F6, 0x094, 0x045, 0x0CF, - 0x015, 0x00B, 0x0F3, 0x03C, 0x0B3, 0x02A, 0x07A, 0x0C5, - 0x046, 0x001, 0x064, 0x08A, 0x031, 0x023, 0x09C, 0x00A, - 0x05D, 0x0EA, 0x034, 0x033, 0x02E, 0x095, 0x0C7, 0x0CE, - 0x02A, 0x04F, 0x0E6, 0x050, 0x020, 0x0B9, 0x031, 0x00C, - 0x09B, 0x0EF, 0x039, 0x014, 0x045, 0x0CE, 0x045, 0x007, - 0x01C, 0x0EA, 0x046, 0x087, 0x0AB, 0x01B, 0x036, 0x084, - 0x0A7, 0x05E, 0x0AC, 0x096, 0x067, 0x052, 0x0B0, 0x017, - 0x0DC, 0x0FE, 0x07B, 0x04A, 0x022, 0x0E7, 0x08A, 0x085, - 0x0F9, 0x09E, 0x059, 0x097, 0x07A, 0x08D, 0x00C, 0x0CB, - 0x0A5, 0x027, 0x0F3, 0x0A0, 0x044, 0x032, 0x060, 0x0B9, - 0x037, 0x0DE, 0x072, 0x028, 0x08B, 0x09C, 0x08A, 0x00E, - 0x039, 0x0D4, 0x08C, 0x005, 0x0F7, 0x0E7, 0x0B8, 0x02A, - 0x0F9, 0x028, 0x018, 0x0EF, 0x000, 0x030, 0x030, 0x057, - 0x007, 0x044, 0x00A, 0x050, 0x08F, 0x0F0, 0x073, 0x091, - 0x041, 0x01F, 0x03A, 0x090, 0x045, 0x0C0, 0x0BB, 0x018, - 0x0E1, 0x036, 0x002, 0x0FB, 0x0FB, 0x09E, 0x002, 0x0FA, - 0x0EE, 0x0E7, 0x0F5, 0x0CF, 0x001, 0x07D, 0x010, 0x05C, - 0x0F0, 0x017, 0x0D1, 0x005, 0x0CF, 0x001, 0x07D, 0x053, - 0x0EB, 0x02D, 0x018, 0x005, 0x0B8, 0x00D, 0x0A6, 0x042, - 0x0DC, 0x006, 0x0D3, 0x017, 0x035, 0x0A8, 0x08B, 0x09C, - 0x00A, 0x00E, 0x039, 0x0D4, 0x00C, 0x0FE, 0x07B, 0x04A, - 0x022, 0x0E6, 0x055, 0x00B, 0x0F3, 0x031, 0x0B3, 0x060, - 0x02F, 0x0BC, 0x07C, 0x0E2, 0x0A4, 0x0FE, 0x065, 0x051, - 0x017, 0x038, 0x014, 0x01C, 0x073, 0x0A8, 0x019, 0x0FC, - 0x0F6, 0x094, 0x045, 0x0CC, 0x0AA, 0x017, 0x0E6, 0x063, - 0x066, 0x00A, 0x0B8, 0x0CC, 0x085, 0x0A1, 0x058, 0x0F6, - 0x0A2, 0x035, 0x048, 0x048, 0x07F, 0x04A, 0x089, 0x095, - 0x021, 0x021, 0x0FD, 0x005, 0x002, 0x054, 0x09E, 0x045, - 0x091, 0x00E, 0x03C, 0x005, 0x0F5, 0x007, 0x040, 0x055, - 0x048, 0x052, 0x03E, 0x086, 0x0A0, 0x075, 0x048, 0x052, - 0x03E, 0x0B5, 0x000, 0x04A, 0x09C, 0x000, 0x06B, 0x0C7, - 0x0CE, 0x045, 0x027, 0x0F3, 0x02A, 0x084, 0x037, 0x035, - 0x0DE, 0x0A0, 0x0AB, 0x023, 0x01A, 0x0AE, 0x0F5, 0x083, - 0x059, 0x018, 0x0D7, 0x043, 0x0DE, 0x02A, 0x0D0, 0x094, - 0x0EB, 0x0DE, 0x005, 0x03A, 0x095, 0x09F, 0x0CC, 0x0C3, - 0x020, 0x045, 0x0CC, 0x0AA, 0x017, 0x0E6, 0x066, 0x0CC, - 0x043, 0x026, 0x04F, 0x0E7, 0x041, 0x022, 0x02E, 0x070, - 0x068, 0x038, 0x0E7, 0x053, 0x0E0, 0x02F, 0x0AB, 0x0BC, - 0x012, 0x0D2, 0x0E9, 0x058, 0x00B, 0x0EA, 0x0A7, 0x0AD, - 0x045, 0x0A1, 0x01F, 0x0C0, 0x05F, 0x078, 0x039, 0x0C8, - 0x0A0, 0x08F, 0x09D, 0x048, 0x01C, 0x024, 0x0EE, 0x0C7, - 0x080, 0x0BE, 0x0BA, 0x0F5, 0x06D, 0x066, 0x049, 0x077, - 0x00D, 0x04E, 0x0A5, 0x030, 0x009, 0x0B4, 0x0F9, 0x0C5, - 0x043, 0x00F, 0x038, 0x0A9, 0x03F, 0x09D, 0x002, 0x0FB, - 0x0CE, 0x045, 0x011, 0x073, 0x091, 0x041, 0x0C7, 0x03A, - 0x091, 0x09F, 0x0CF, 0x069, 0x044, 0x05C, 0x0F1, 0x050, - 0x0BF, 0x033, 0x0CB, 0x032, 0x0A7, 0x0AC, 0x054, 0x090, - 0x08D, 0x044, 0x08E, 0x070, 0x029, 0x077, 0x0A8, 0x0D0, - 0x0CC, 0x0BA, 0x056, 0x0B0, 0x0B2, 0x09D, 0x08C, 0x086, - 0x04C, 0x017, 0x026, 0x077, 0x026, 0x01C, 0x027, 0x01C, - 0x024, 0x09E, 0x023, 0x061, 0x0BE, 0x08E, 0x012, 0x04F, - 0x011, 0x087, 0x01C, 0x0EA, 0x05C, 0x005, 0x0F5, 0x0D7, - 0x0B8, 0x06A, 0x075, 0x029, 0x077, 0x0AB, 0x00D, 0x099, - 0x074, 0x0A5, 0x04F, 0x072, 0x0A0, 0x0AA, 0x04A, 0x0C6, - 0x0F3, 0x066, 0x066, 0x0C6, 0x039, 0x082, 0x0AF, 0x075, - 0x0A6, 0x06F, 0x014, 0x06B, 0x0CE, 0x005, 0x070, 0x073, - 0x096, 0x082, 0x03E, 0x075, 0x028, 0x0E1, 0x03A, 0x0A7, - 0x0AD, 0x044, 0x060, 0x016, 0x052, 0x0B6, 0x01D, 0x07A, - 0x0B6, 0x0B3, 0x024, 0x0BB, 0x086, 0x0A7, 0x052, 0x098, - 0x004, 0x0DA, 0x07C, 0x0E2, 0x0A1, 0x087, 0x09C, 0x055, - 0x0F7, 0x09C, 0x0B5, 0x0AC, 0x02C, 0x095, 0x033, 0x0B9, - 0x031, 0x005, 0x0D9, 0x053, 0x0D6, 0x0A2, 0x030, 0x00B, - 0x029, 0x05B, 0x002, 0x02E, 0x061, 0x05A, 0x017, 0x0E6, - 0x09C, 0x0B3, 0x02A, 0x07A, 0x0C5, 0x040, 0x021, 0x0A8, - 0x091, 0x0CE, 0x005, 0x027, 0x0F3, 0x0A5, 0x088, 0x064, - 0x0C1, 0x072, 0x065, 0x04F, 0x058, 0x014, 0x00C, 0x08D, - 0x07E, 0x0F3, 0x081, 0x044, 0x05C, 0x0EF, 0x041, 0x0C7, - 0x03A, 0x0BE, 0x002, 0x0FA, 0x0A9, 0x0EA, 0x0CE, 0x0CC, - 0x0A9, 0x029, 0x053, 0x0D6, 0x0A2, 0x046, 0x047, 0x0DD, - 0x07A, 0x0C0, 0x0A3, 0x000, 0x086, 0x0E2, 0x09B, 0x029, - 0x078, 0x08B, 0x081, 0x009, 0x098, 0x070, 0x09B, 0x029, - 0x079, 0x05D, 0x0D9, 0x072, 0x0ED, 0x094, 0x0BC, 0x0B9, - 0x076, 0x013, 0x03B, 0x02A, 0x05D, 0x0B2, 0x097, 0x095, - 0x02E, 0x0D9, 0x04B, 0x0CA, 0x07D, 0x05B, 0x059, 0x094, - 0x0CA, 0x01C, 0x024, 0x0EE, 0x0C7, 0x094, 0x0BC, 0x0C0, - 0x026, 0x0D3, 0x0E7, 0x015, 0x00C, 0x03C, 0x0E2, 0x0AC, - 0x0FE, 0x07B, 0x04A, 0x022, 0x0E7, 0x08A, 0x085, 0x0F9, - 0x09E, 0x059, 0x097, 0x07A, 0x08D, 0x00C, 0x0CB, 0x0A5, - 0x027, 0x0F3, 0x0A0, 0x041, 0x072, 0x062, 0x019, 0x037, - 0x0DE, 0x070, 0x028, 0x08B, 0x09C, 0x08A, 0x00E, 0x039, - 0x0D4, 0x08D, 0x00F, 0x056, 0x036, 0x06D, 0x009, 0x04E, - 0x0BD, 0x059, 0x02C, 0x0CE, 0x0A5, 0x06B, 0x00B, 0x022, - 0x0D9, 0x09D, 0x0C9, 0x0B2, 0x097, 0x0BE, 0x0F3, 0x081, - 0x04A, 0x07D, 0x065, 0x0A3, 0x000, 0x093, 0x08F, 0x067, - 0x029, 0x078, 0x0C2, 0x04D, 0x0C1, 0x0D1, 0x006, 0x082, - 0x031, 0x0AF, 0x007, 0x038, 0x034, 0x011, 0x0F3, 0x0A8, - 0x02A, 0x09E, 0x0A8, 0x066, 0x01A, 0x0A4, 0x0A5, 0x04F, - 0x05A, 0x00C, 0x011, 0x08F, 0x0AA, 0x07B, 0x0D0, 0x065, - 0x049, 0x045, 0x0BD, 0x0E9, 0x062, 0x0D2, 0x0B1, 0x09E, - 0x06C, 0x0CC, 0x0C6, 0x019, 0x087, 0x009, 0x0C3, 0x08E, - 0x075, 0x041, 0x01F, 0x03A, 0x0A5, 0x013, 0x0D5, 0x055, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, - 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, - 0x055, 0x055, 0x055, 0x05A, 0x0CC, 0x090 - }; - -#endif /* defined(CONFIG_SMCTR) || defined(CONFIG_SMCTR_MODULE) */ diff --git a/firmware/Makefile b/firmware/Makefile index a962fe9..7a8fa9e 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -20,6 +20,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). # But be aware that the config file might not be included at all. +fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw diff --git a/firmware/WHENCE b/firmware/WHENCE index ae40fb1..a8fc4b6 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -44,3 +44,16 @@ Found alsa-firmware package in hex form, with the following comment: Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved. -------------------------------------------------------------------------- + +Driver: smctr -- SMC ISA/MCA Token Ring adapter + +File: tr_smctr.bin +Info: MCT.BIN v6.3C1 03/01/95 + +Original licence info: + + * This firmware is licensed to you strictly for use in conjunction + * with the use of SMC TokenRing adapters. There is no waranty + * expressed or implied about its fitness for any purpose. + +-------------------------------------------------------------------------- diff --git a/firmware/tr_smctr.bin.ihex b/firmware/tr_smctr.bin.ihex new file mode 100644 index 0000000..6797451 --- /dev/null +++ b/firmware/tr_smctr.bin.ihex @@ -0,0 +1,477 @@ +:10000000BC1D123B63B4E900001F000101000205A2 +:10001000010006030100040901000A070100080BA2 +:1000200001000C000000000F0100100D01000E1374 +:10003000010014110100120000050015010016193D +:1000400001001A1701001800000E00000001000056 +:100050000004001B01001C0000070000000F00004E +:10006000000B001D01001E0000080000000200003F +:10007000000C000000060000000D0000000300005E +:10008000000A00000009000478C6BC0194049380B3 +:10009000C84062E9DA1C2C1555555555555555582B +:1000A0000BE9E5D595C19D77CEBBA06E1C05F67713 +:1000B000C602FA9670E81DC0170E02FA587DC05F9E +:1000C00072CEECA4C384907A30CD8D7919E76C247C +:1000D000279C08390738A84A4CEA4D989B244CC005 +:1000E00026D3E7545A4DF24C0C13234990326EA498 +:1000F000DF9371137726E126F8260C4C12260809A7 +:10010000828260A9307936B0B2A8A772648F9B331F +:1001100033F9B839D51173AA75265D2651932A494A +:1001200094C99589BC4DC89B809BA099064C862696 +:10013000589BA49B9937626C679B3330BF366661CE +:10014000BF36ECC5BD66825A5031D59D9818293C02 +:1001500098864C17263E2CB8693B492EB408431AA2 +:10016000A4F9B351F110F343CD086F6379B3330EA3 +:100170001398499804DA7CE05279310C982E4DACF2 +:100180002C8414EE4CFE675EE49A7529D7A9353AA3 +:10019000945BD59B58B4AF7566AF14A9EF40952515 +:1001A00008B9AD42FCD8D98C330E1398661E45AC05 +:1001B000B00C42D3CCA61262DEB4B180497DA2DE7F +:1001C000B418C02484E654F5834601681A630CC64B +:1001D0001264FA4C351C2C0EAAAAAAAAAAAAAAAA88 +:1001E000AAAAAAAAAAADD70270E04CF3A1C1D5C0B1 +:1001F0003CB96939604E58770267933C99E4CF382F +:100200001C972E401B903146A35E0E88346A35E061 +:10021000E8AA351AA9F51546A3EA7D4AA351AA9F73 +:100220007054A6572EB4CDC8A30CC1DAC6E1CB7A60 +:10023000D41C68FFCF55A8C02D851117442A300B58 +:100240004A88C24DB520D5260169516952195260BC +:100250001695168296549805A545F3DD6AF9281877 +:10026000EF003030514E445D12D143E6126F9EBA1A +:10027000CCDF25031DE006060A30CCA9EB2D008655 +:10028000A612654F56D665495F3DE837C940C77825 +:100290000181828C33184980AE40C518059C6D18C9 +:1002A000660EF3A0C61262DEF504B4AC6BC61991FB +:1002B0007305482E72948073A1C8473666642F3642 +:1002C0006664079902918E72D10F9D063173A0C3A7 +:1002D000516A1A20BF3A0C2C7387435E600223FCDC +:1002E000E0D635EF9EF5EF92818EF0030305186698 +:1002F00045CC0B482E700A4039D0E4239B3332178B +:100300009B333203CC8548C73814A5CE297ED280D2 +:10031000A1A8B448882FCE830B1CE1D0D7980488BD +:1003200087CE963173A58FF38358D7BE7B82AF9269 +:10033000818EF0030305186645CC1520B9C8290045 +:10034000E743908E6CCCC85E6CCCC80F3205231C82 +:10035000E450D45A17882FCE8310F9D023173A04CB +:1003600035E600221639C3A3FCE0D635E0BFF41809 +:10037000F22D4D43516E5A221F30D417E74191732D +:1003800005482E776900E743908E6CCCC85E6CCC34 +:10039000C80F3205231CEF4C4E0604C99E0BFF41CB +:1003A0008F22D4D43516E5A221F35A82FCE8322EEE +:1003B00060A905CE1348073A1C8473666642F3664B +:1003C000664079902918E70A989C0A9EB5125C7CD1 +:1003D000C3318B982A7CD3ED38E9D34E74ED499E16 +:1003E0000BFF418F22D4D43516E5A22DEB45338F78 +:1003F000FCF7A05F25031DE40E060A30CC0CF3EBDE +:1004000040DE61A870920A00E1241E00E1241E0073 +:10041000E1241E00E1241E00E1241E010F982A0B96 +:10042000F3A0C8B9A2A4173A6900E743908E7548B3 +:100430005E706901E6005231CC1814A5CC09829493 +:10044000730CA091F525CC070684849F30A2A47D6F +:100450005075A665014A8EB4CCC435547566A49710 +:100460007A895053138019E3495C6DCEA940350653 +:1004700078D25706F1B32A8D972362925D69991C51 +:100480006A36E6CD46126F9EE1ABE4A30CC0DEAC4B +:10049000D40D281BD012A500F84BAD332806A0DEE2 +:1004A00014973A895DC00DE30690925D699866B92C +:1004B0001995E4A8CF9D331849BE7B86AF928C3343 +:1004C00024140CF4832421C270BFF418F22D4D4380 +:1004D000516E5A221F32A82FCE8322E605A4173A66 +:1004E0006900E743908E75485E706901E642A46337 +:1004F0009802294B9A2978E9405313818132678207 +:10050000FFD063C8B5350D45AE50087CE0D05F9D87 +:100510000645CC01A4173A6900E743908E75485E02 +:10052000706901E659A463981C52973B30528E7D46 +:100530002A091F51EBA4A40AB99487AEC531380229 +:10054000FFD063C8B5350D45AE50087CEA20BF3AF0 +:100550000C8B9A16905CE9A4039D0E4239D5217943 +:1005600095480F300A918E60EB297300095404CA34 +:1005700082655265E4CA226572650932E099724C5F +:10058000C4E00BFF418F22D4D43516B94021F38A41 +:1005900082FCE8322E60A905CE9A4039D0E4239D32 +:1005A00052179954619901E640A4639804B1849864 +:1005B00018EF2D0305313802FFD063C8B5350D455E +:1005C000B968887CE0505F9D0645CC81482E713427 +:1005D0008F48014815210521E90A5203CE5A4639B0 +:1005E000CF478E60AB1AF35343EB3524B81B30076B +:1005F000098A742F7E41741E1D0D874649D595D1F9 +:10060000D5D5BBA94E829D053A0A7414E829D0427B +:10061000745BCE50C40745BCE20C40745BCE8304CF +:10062000F9954D13635E6F313BA08BA2C5398D7870 +:100630003A22A0006BC1D1546016D991A2E7438C35 +:1006400024DC1CE05117396B3BCC4B422E6B50BF66 +:100650003636654F7A185525789823E7503EF38152 +:100660004C026D3E7153AF78A9D4A629B1BCD9997B +:10067000B28E628F222E7516B0B2AB23281654525A +:1006800031BCD999B28E6619022E7516502CA9C8A4 +:10069000C6F520D3E47F4F9C0AD6167F90EE4CEB34 +:1006A000CFE288BA2F4286AEBDE5A7529F93637909 +:1006B000EB3308F9945247CD99256F3A0C13E65560 +:1006C000344C5A4DB52395A548115A0A4395AC2C84 +:1006D000BA240549B1BCCAA7726C6BC5BDE83169C3 +:1006E000525D0612653EB1504C7D4FAC0A300B3660 +:1006F0006411738A838E75129F7BD29958EE822E75 +:1007000077A0E39D5D4FBC2A532953DE9324BAB3EF +:1007100036AA4AC679D4B9DE625A11735050BF372F +:10072000366F1323BA0C24CEBDE2A752B28E6B6093 +:10073000622E751330ACA059CA646379B333651C5B +:10074000CC32045CEA2CA059DF231BD4835247DD52 +:100750007996D49EB3524BA25A1A8D5D7B82A752D2 +:10076000B28E6619022E7516502C8C321D7B8EA708 +:1007700052B1BCD9999804DA7CE2ACFE6619022E1B +:100780006550BF336664FE7418864C1726D6165221 +:100790003918DE7ACCC23E651491F36649086E833F +:1007A0000933AF31ED0D9D0612622A318D6DE7419F +:1007B000827CCAA68987092E29B1AF1039D66497E1 +:1007C000301D42759344028C24D27AB350F68905C9 +:1007D000435E6198C02C92253C8B2489490549E7EA +:1007E0000CB98498B7AD3344AE5A5186609F38A98E +:1007F000A26C6BC48EF45E49461262DEB4CD215CFD +:10080000B4A30CC13E7229A26C6BC6126247F0E819 +:10081000C33204354092A4828810927CCBD42FA49A +:1008200002118498B7AD3344AE5A5186609F38A9FF +:10083000A26C6BC48EF45E494408493E65EA17D247 +:100840000108C24C5BD699A42B9694619827CE459B +:10085000344D8D78810927CCBD12286C58AFB6F382 +:10086000A0C13E655344D8D7928E7D4BC2FA612613 +:10087000063AB36B030549E70CB96F5A66955CB449 +:10088000A30CC13E7029A26EA4DF9371137726E1F9 +:1008900026F826C6BC9473F92F0BE9849818EACC85 +:1008A000EC0C15279C32FF3D56AF928B7AD335D591 +:1008B000CB4A30CC13E7029A26C6BC947341979179 +:1008C000F483CE0420628B0516498C24C0C7569051 +:1008D000C0C15279C32E5BD5A672D294FAAD58C866 +:1008E000FA9F54B3324BB954A651866B79D0609FAE +:1008F0003205344D8D7A4D1E7AB35100A93D59A869 +:100900007B4482A1AF4A8D52A95241494F3A2E40B1 +:10091000A49950BE90085279C32E61262DEB4CD07D +:1009200015CB4A30CC13E7029A26C6BC48FE1D25DB +:1009300046A954A920A4A79D1720524CA85F48049B +:100940002309316F5A6680AE5A5186609F3814D1A0 +:100950003635E4A79D1720524CA2450D8B15F49116 +:10096000DE8BC928C24C5BD699A95CB4A30CD6F324 +:10097000A0C13E640A689B1AF16D4CAA92E03694BD +:10098000709B297813AEB3AA85D44375093AC9EB95 +:100990003524B81B328E13487E4EFD40FD40FD408D +:1009A000FD40FD40FC13F421F917458A300B335FFD +:1009B00083A22A300B335F83A2A8C02DB32070928C +:1009C000139ADE741827CCAA689B1AF70745518042 +:1009D0005B66470738A823E751113FE0E8854601E9 +:1009E0006D990612654F7A2024BAB33215257BAD76 +:1009F0003378AE0E73D047CEA730CC44FF83A2A885 +:100A0000C02CD991C1D11518059B3208BA2C518040 +:100A100059B3207092E29889FDBCEE1890FC8BA22D +:100A2000C52B0D783A22A561AF074551805B66441E +:100A30009EB3524B83ADC709BE1F9F74655D0A17F5 +:100A40007CABA0C24C3849122E384907A30CC13EDA +:100A5000655344D8D7ADE700324B9B33344A03008B +:100A60009D25CE8324B819998C02124BA199D8C028 +:100A7000274973CFF93CF47CE79804E92E7F39E3EA +:100A80004F4653C06013A4B9E53C03DE8F9CF300CE +:100A90009C6FCF3E85F9A336021E6038923E631AE2 +:100AA000109FCF181092BCD0A40CDCC00F9C9734C0 +:100AB00062B6E7F3F3A5CF1842341CC2CAFA8E68B7 +:100AC0005206AF3CA30DBF9E50E1D173CAE03AFC81 +:100AD000C1091A1E6A5C5B8E634E7773CC6167DD59 +:100AE000E66C48D1F31B24695108D4421BF467D14A +:100AF000804E2FD08CD83009C21E801C46013A4748 +:100B0000D031A106013A7F4630211804E95E8429DC +:100B100000C027CDD0007C9804F92E84628C027D21 +:100B2000BA3E7E4C027D2E8C61083009F41D0165B1 +:100B300073009F51D085201804FABD194618C027AC +:100B4000DFD194384C027D174657013009F5FA0180 +:100B50000906013E87A14B88C027DC740D39D300FC +:100B60009F73D030B39804FBBD06C483009F47D069 +:100B70003648CC0271BF3F9A17E63F0821E692A49F +:100B80008F9A1031A7F310B184AF3AACDCF773F24F +:100B90005CC62ADB9E7E7E97310863D0737B43A8B8 +:100BA000E63D34EAF3E315BF9F185F45CFE89F5F4A +:100BB0009A5B03D0F3D3CE371CD00FBB9E68783B33 +:100BC000BCCA31E8F9A20212A27351086FD1F346F0 +:100BD0000138BF40FC23009C21E84951804E91F42C +:100BE000210319804E9FD0216306013A568C02746E +:100BF000FE75495E63D34A54423513A7D1804E95A2 +:100C0000E81E9A4C027CDD1BB9E6013E4BA062A3B4 +:100C1000009F6E8CFCF3009F4BA04218CC027D0716 +:100C200043DA13009F51D03D349804FABD1C628C06 +:100C3000027DFD1C6173009F45D1F44E6013EBF4FF +:100C400025B033009F43D1A79C1804FB8E8403E991 +:100C5000804FB9E843C13009F77A0A319804FA3E67 +:100C6000844041804E82E7418709230423009D058B +:100C7000CE961C248C108C0274173A043849182123 +:100C80001804E82E7450E12460846013A0B9D411D4 +:100C9000C248C108C0274173A82384918211804EA5 +:100CA00082E7528E12460846013A0B9D401C248C66 +:100CB000108C0274173A090E12460846013A0B9836 +:100CC0006A1C24B0E11804E82E6B50E1258708C0A7 +:100CD000274173054384961C23009D05CCAA1C2440 +:100CE000B0E11804E82E70687092C3846013E54484 +:100CF000F9409D05CE5A1C24B0E11804F9D13E708C +:100D000027CF13E5442CA042CB89F2213A0B9C0A51 +:100D10001C24B0E11804F9D10B3810B3C4213936C2 +:100D20005C42C8842B79D061C2741524BAD331E5F2 +:100D300059082908E066634295128100290BC151C8 +:100D400024B81999902290B418A0914101414141D1 +:100D50005283CA4028682908BA16109C990B5694E9 +:100D600090521574C0271A2AD29025D3009D28AB23 +:100D70004A42174C0270D4842E9804E12A42174C40 +:100D8000027082904BA60138514842E9804E15A46A +:100D90002174C0270FA412E9804E82AC80ACA0ACB5 +:100DA000A959E5644565CAC84ACE0ACE4ACE95918E +:100DB000959495932925C0CCCC88A4975636647217 +:100DC00090548A9C4508B9B766129309C9B2748ECB +:100DD000BA6013E5348EBA6013E4748EBA6013E51A +:100DE000691D74C027CA291D74C027CED225D3001F +:100DF0009F38A44BA6013E5E912E9804F915225D02 +:100E00003009F3E912E9804F905225D3009DC5487F +:100E100025D3009C45CECD09C9B21A44BA6013E768 +:100E2000348974C0271C27B79C80C2D776599B93FE +:100E30000C64C31D1BF4454BC7C63A37E8814BC74A +:100E4000C63A37E8914BC7C632618EB3BCC34A225B +:100E5000E6B5249771C987B431AE73A2CF39D25D9C +:100E6000044442C0D6DE710616BBDBCE830C64C3DD +:100E70001D311304F9954D133293635E6614CC292A +:100E80002A5330A6614CC299853A72CCC299850624 +:100E90001BB30A661414249985330A08B186614C81 +:100EA000C2842168733B30A661414EA5985330AC93 +:100EB0005976614CC2B08DD6614CC2B02CF6614CF3 +:100EC000C2B18CA5985330AC0F24CC2998560F286A +:100ED0006615921A1985330ACA850CC2998565C3AD +:100EE000D985330ACE7086614CC2B397710C993B99 +:100EF000CC83580BEA779D064ABE047460E0D14E5D +:100F0000384C3EEE3EEE3EEE3EEE30BBCAE11F7781 +:100F10001F771F771F7727708FBB800E11F771F730 +:100F20007C6F3CB33602FB8DE655707F2D246955EE +:100F30004F58A9231F54F78A95252B750CCCAC5616 +:100F400051CC51E445CEA21239C0A0AF566A497FB8 +:100F5000028C09F80BEBAF56766752B28E69A71177 +:100F600073A8B1BCCAA0A936502C98E70AF566A4AC +:100F700097E25A3027BAF7834EA5330A66158DE6F5 +:100F80005539D2A7AC546016701B728E628F222E18 +:100F9000751602FB8DE60A953D62A300B701B553B5 +:100FA000DE2A5494ADD43332B15947314791173AC0 +:100FB0008848E702B017DC679D4B8DE752AA7BD4C7 +:100FC000AA92BDD699BC5602FB8CF36666C6F36640 +:100FD0006662992AF8186870B08A0D5555555552B1 +:100FE00032E1405C380BEA9B87017DC05F7017DC03 +:100FF00005F5DC9B017D614D80BEA77982A21F5063 +:10100000152A8F8B1CE5A5138458E702915405021D +:101010004BBD221A947F9C1AC05F421A21D180597D +:10102000C06D1C2C0A83555555555555555555556C +:1010300055541CB85C6E179C2F385E70E7B85E7014 +:10104000BCE179C2F385E70BCE179C299C299C292A +:101050009C230F5814EE357726219305C9B017D27B +:101060001D188A219305C9B017D187AC0A740FAE39 +:10107000F55A82A3E43A3114BBD7599974A21930B6 +:101080005C9B017D187AC0A740F843D4638925D0C2 +:1010900010D61C6A10F5558925D151661F51F5915E +:1010A000492E8915986AA3E08A9465640E1317384F +:1010B000A8864C1726C05F461EB028631F087A8C8E +:1010C0007124BA021AD00D421EAAB124BA2A2D31B7 +:1010D000F51F587492E8875A6352DEF451694A3E0C +:1010E00009694650F0E131730545BD598D8B4A7C45 +:1010F000D3ED38E9D34E74ED443260B93602FA5B71 +:10110000DE8A2D29D0E121F5A39221F219305C9BD2 +:10111000017D21F5A0C6016701B445CEA51239D4E1 +:101120001C05F440A1C2C3506AAAAAAAAAAAAAAAE4 +:10113000AAAAAAAAAAAA81AF869F191BE781F3656A +:10114000F280BE7017DFDF380BEB0DC380BEA70F38 +:10115000954F5A94C02CD8B1A7CE5A1173A83AC251 +:10116000CCB63017DC6F35A9804DA7CE2A1879C5CB +:1011700049DE61A822E75033F9986408B99542FC2A +:10118000CCD9953D62A248D448E70288B9C1A0E312 +:101190009D4E62E6CCC66BCE8310C982E4DAC2C82B +:1011A0001EC3B93602FAA9EB4E3030FA0DF0A9EBA6 +:1011B00040B90FAA7AD2C2C8FAA7AD410A47D53DB5 +:1011C00068ACF1F54F5A97547D4FA8AA551F11737B +:1011D0005AB017DE5D59A925D0552A46BCB822AEB3 +:1011E00045293E14FAE19994CA4ABE3DD699925DCA +:1011F0001517C8D7DC15178A401F0A9EACC9654968 +:101200005C1D10684A3E5BDE83169580BE91745863 +:10121000A4007C38E7563017DF75A6649745209DFB +:10122000035F70545E291DF0A9EACC865495C1D1A4 +:1012300006830FAA7BD0654945BDE962D291DF04E0 +:101240005D16291C7D4FAC1A471AA9F5676653280D +:10125000B7BD2C5A523BE3DD59A925D1A8AC086B88 +:10126000EE08ABC5202F854F566675495C1C181DCE +:1012700081C26405F080BE355CD017C255F0957C04 +:10128000255F080BE1017C7BAB3524BA1055931A1E +:10129000FB822AF148D7C2A7AB31B2A4AC639D4A06 +:1012A0008D7C7BAB3524BA1054308D7DC11578AC64 +:1012B0006F5A94601AE379D4AA4F854F5666D54980 +:1012C00058C73A9549F045D1629486BC1D13D29017 +:1012D000FFCF7A83F25031DE006060A11735A85F3E +:1012E0009B1B3707441A300B380DBC1CE0D047CE8F +:1012F000A0AA7AA1986A92953D6831805B80DAA9AC +:10130000EF41952516F7A58B4AC679B333602FAA0E +:101310009EB15180599ECAA7AC0A300B67B2ADD5B9 +:10132000DA925D17A300B32D956E08A958A1173A5C +:101330008B017D54F78E9525081CE05602FBC1D128 +:10134000151805926B3C1D1228C02CA56C11701746 +:10135000B2384D80BEE02FB4EC4AEDB39E02FB8064 +:10136000BEE02FB139933E6DE710609F32A9A26CA9 +:1013700005F440E60A953D6A2300B380DAA7D62A31 +:10138000030D7017D22E76294FBC54A6516F7A5890 +:10139000B4AC05F48BA2F40E350D492EB4CC18A5CF +:1013A000C8F84A9723E1052E47C28A5C8F85697287 +:1013B0003E1F4AC3551F5643328CA35E60A845CEDC +:1013C0000D602FA3849DD8F017D22E0E1B2384D836 +:1013D0000BEB89F380BEE02FBB3985DF2203E701E9 +:1013E0007DC05F7017D11738145BD6A2740D4B7A8D +:1013F000B33196946BCC3523D749481573290F5DCB +:101400008AC05F4D79843580BE881CC3529F59685D +:10141000C02CE036AA7BCD4A92BEF3814A7D5B594F +:1014200094CA1C24EEC780BE881CC3529F5968C052 +:101430002CE036AA7BCD4A92BEF38143849C7B3854 +:101440000BEBAF70D4EA53009B4F9C5430F38A945B +:10145000FAB6B3299422E61A85F9B05993F9D2C4A1 +:101460003260B936B0B390D977261C2722E896B4FB +:1014700023EA9EB511805965862073968D79AD5803 +:101480000BE917448A4A07D77A82A190FAEF0154F0 +:10149000BA50D4591E2CE9F38A99856B0B23159702 +:1014A00072611730D42C738748AA028125DE910D12 +:1014B0004AC05F7ED280A53EB2D0C86B80BE881C79 +:1014C000EA0917441A371A917458A371AF074454A4 +:1014D0006E35E0E8AA640F90FAD06300B380DA2C8E +:1014E000738748AA028125DE910D4AC05F48BA275A +:1014F000A300B701B74F9CB46BCC3516F566632DCE +:10150000291EBA4A40AB99487AEC508B9C0822FCC1 +:10151000F9B2553D62A92351239C0A3C730D445CEA +:10152000E15071CEA11FE7156B0B25ED0B93602FDA +:10153000AA9EAC3665495F7A2050087FEF3914497E +:10154000011181046040CC59C0AD23EB41B081F260 +:101550003A41AA5043E4D48654A087C152CA9301A9 +:1015600032549D2402000052AF1646A7916708B47A +:101570000451F16519B46E2DC0AD490092571B742A +:10158000455F2351B7440A1006A36E8B6B081F19E1 +:10159000D1E680828054042A4591A9E459C22D01E4 +:1015A000140450D3FC558461D980512FE21F465F4B +:1015B00040E020154ABC591A9E459C22D01148CBC8 +:1015C000E81408015415E2C8D4F22CE116808A46CA +:1015D0005F527CD9A8F888D05A3CD25C5B80DAA7ED +:1015E000D65A0886A45D17A0C3522E88A8221F537E +:1015F000EADACCA650E127763C05F54FAB6B329981 +:1016000043849C7B380BE927ACD492E00EDA384D4A +:1016100080BEE67D50BA51AE66EFBCDC7B871E0211 +:10162000FA93E6CD47C443CD0F349DA300B05501D6 +:10163000AE038404CE01D0E17002800E89E9221F3E +:10164000E0E896B011F4C2CE036A442DC06D48059F +:10165000B80DA300B776D5DEB150DC7D77BC54BAA7 +:10166000527F5814340F9AF381580BEAEF581460E4 +:1016700016A56C2EF7814BA56F7D5DEEB52E95807E +:10168000BEF073BD047CEAFEEB4CDE2953DD6A54E8 +:1016900094A9EA0A8C02D64C3C05F400EACD56AF78 +:1016A000C047D29C8D29CAE02FAEBD75999D4AF9DD +:1016B000EF517C940C77801818292AF8E0E8AA30BA +:1016C0000B2A987C1D1151805954C351F51B3324AA +:1016D000BB82A5195C1D1028C02C9AC7C1D1228CD1 +:1016E00002C994645C0CD68E13602FB80BEA30E309 +:1016F000C05F48DC780BE800E3C05F6C38D52E355E +:101700004F5A8A61AA9F561B32994642C8010C451E +:10171000CEA517E6C6CEA9EB151646A24738144348 +:101720002622E73D602FAA9EB512E07F017DE3E708 +:101730000293F995445CE5A0E39D4A7F9C54A9EB94 +:10174000510546B9FCC01B222E64542FCD46CCA7B0 +:10175000D586CCA65055C645CE5A0E39D4A7F9C564 +:101760004A9EB5118059C06DCFE600D9117322A1F0 +:101770007E6A36653EAC366532B017DD3E72D27990 +:10178000310C982E4C20732A8FF38AADE741827C6E +:10179000CAA689B5859FB0F017D51F5454251AA83D +:1017A000FF2A946511D74944D5CCA055D8AE0E88F0 +:1017B0001460164D6322E07286384D80BEE02FB86B +:1017C0000BEE02FB8138F017D7D71E02FAFAE3C0FE +:1017D0005F4C85900218C85B80DA300B701B4C227E +:1017E000D34C33038C2E4C4326D0F56366D095A79B +:1017F000CE45330AD61642386EE4CEBD592CD2AB54 +:10180000BA949DE61AB017D54F5A8B091A88B9C5F4 +:10181000424730D43216728865BD599925A5602F8C +:10182000B860F308B74A1A8FAB0D994651AF38A884 +:101830008E9065135218A054B1422E61A848E72D2E +:1018400016F7A805A5602FA475D251357328157613 +:101850002B83A20518059358C8B806286384D80BB3 +:10186000EE02FB80BEE02FA043A7017D4CE3C05FEA +:101870007017DC05F4642DC06D1805B80DA5BD6AA0 +:101880002386AA9EB511A46AA3EA8A8D23E117389C +:101890003469719845A6986A3EAC36651946BCE233 +:1018A000A23A41944D48628152C516F7A88B4A541A +:1018B000F5A88C02DC06D1039CB4A9EE0A95252A72 +:1018C0007AAD46016701B5D7AC0A300B6C4935E6F5 +:1018D000B567F3006C88B99150BF311B32A7B86867 +:1018E00095257BAD3378A7CD3ED38E9D34E74ED47E +:1018F00022E706848E60A8FF38AB839C2A08F9D4BF +:101900002063BC1A060AC05F4642DC06D1805B80B9 +:10191000DA22E61A848E72D16F5A80871AAA7AD494 +:1019200048C8D547D5152323E11738348CBA4B7BEB +:10193000D402D28C22DC06D51F561B328CA35E71DA +:10194000511D20CA26A43140A962B017DF9EF4B70A +:10195000C940C778018182B83839491C26C05F70F8 +:1019600017D4ABE12AF84ABE12AF8F974FCBA7012D +:101970007DDA80AA91647F4A81D522C8FE828025C3 +:1019800048B23EBBDC352E9407E88A9C03E24BA5A7 +:1019900077ABB332E94BBD598684977A04BA53E1E9 +:1019A00032EF50D4E63553EB029CC7D77AB330D22E +:1019B0005DEA02E9445D1628C02CE0369174455971 +:1019C00018D54FAC0AC435308B38692BBD5998698E +:1019D0002EF512E958674AEF50D58E3E1CA4B0CEC2 +:1019E00093216E1A481FA22AC30D577AB30D092EF0 +:1019F000F4435D288B832092384D80BEE02FAC17D6 +:101A000049B3A582E93EE93674E02FA6CE9C05F4E1 +:101A1000C22C8C52577AD48D48FAEF50D5AE35533C +:101A2000EB028621AAEF56661A4BBD44BA50C4E9B0 +:101A300053EB028681F5DEA1A8621F5DFEA25D293F +:101A400077A86A618D40FD11530C6AA7D60530C78F +:101A5000D77FA9574A5DEB481B0C7C8B9D8A53EFBF +:101A60006694CA54F5A0C6016E036A9F5676653225 +:101A70008B7BD2C5A5602FAA7D65A300B701B4C832 +:101A80005A078FED01D527916701B48B9C541C73C5 +:101A9000A8845CC150BF365660AB8C8B9C541C73C1 +:101AA000A8845CC150BF36566C05F553D6A2300BE6 +:101AB000295B19FCF69445CF150BF33CB32A7AC584 +:101AC0004601648A31239C0A5DEA34332E95C7CEE1 +:101AD0002A4FE65020B9310C9BEF391445CE45070B +:101AE0001CEA4687AB1B3684A75EAC966752B017DC +:101AF000DCFE7B4A22E78A85F99E59977A8D0CCBCA +:101B0000A527F3A0443260B937DE72288B9C8A0E79 +:101B100039D48C05F7E7B82AF92818EF0030305788 +:101B200007440A508FF07391411F3A9045C0BB188B +:101B3000E13602FBFB9E02FAEEE7F5CF017D105C79 +:101B4000F017D105CF017D53EB2D1805B80DA64236 +:101B5000DC06D31735A88B9C0A0E39D40CFE7B4AC1 +:101B600022E6550BF331B3602FBC7CE2A4FE655135 +:101B70001738141C73A819FCF69445CCAA17E66311 +:101B8000660AB8CC85A158F6A23548487F4A89959F +:101B90002121FD0502549E45910E3C05F507405557 +:101BA00048523E86A07548523EB5004A9C006BC71D +:101BB000CE4527F32A843735DEA0AB231AAEF58352 +:101BC0005918D743DE2AD094EBDE053A959FCCC353 +:101BD0002045CCAA17E666CC43264FE741222E705B +:101BE0006838E753E02FABBC12D2E9580BEAA7AD37 +:101BF00045A11FC05F7839C8A08F9D481C24EEC73F +:101C000080BEBAF56D6649770D4EA53009B4F9C5A9 +:101C1000430F38A93F9D02FBCE4511739141C73A4E +:101C2000919FCF69445CF150BF33CB32A7AC549045 +:101C30008D448E702977A8D0CCBA56B0B29D8C86D0 +:101C40004C172677261C271C249E2361BE8E124F1C +:101C500011871CEA5C05F5D7B86A752977AB0D9931 +:101C600074A54F72A0AA4AC6F36666C63982AF75DC +:101C7000A66F146BCE05707396823E7528E13AA765 +:101C8000AD44601652B61D7AB6B324BB86A75298EF +:101C900004DA7CE2A1879C55F79CB5AC2C9533B94E +:101CA0003105D953D6A2300B295B022E615A17E6B3 +:101CB0009CB32A7AC54021A891CE0527F3A5886454 +:101CC000C172654F58140C8D7EF381445CEF41C79F +:101CD0003ABE02FAA9EACECCA92953D6A24647DDDC +:101CE0007AC0A30086E29B29788B810998709B2992 +:101CF000795DD972ED94BCB976133B2A5DB29795A4 +:101D00002ED94BCA7D5B5994CA1C24EEC794BCC023 +:101D100026D3E7150C3CE2ACFE7B4A22E78A85F924 +:101D20009E59977A8D0CCBA527F3A0417262193783 +:101D3000DE70288B9C8A0E39D48D0F56366D094E75 +:101D4000BD592CCEA56B0B22D99DC9B297BEF3818C +:101D50004A7D65A300938F672978C24DC1D1068261 +:101D600031AF07383411F3A82A9EA8661AA4A54FEC +:101D70005A0C118FAA7BD0654945BDE962D2B19E4C +:101D80006CCCC6198709C38E75411F3AA513D5556A +:101D900055555555555555555555555555555555F3 +:101DA00055555555555555555555555555555555E3 +:0E1DB00055555555555555555555555ACC90C8 +:00000001FF -- cgit v0.10.2 From 79682499d9f3eaea4e6a970d8aa0b9bc1ac2a97f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 17:17:17 +0300 Subject: kaweth: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 7c66b05..d6829db 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -57,13 +57,12 @@ #include #include #include +#include #include #include #undef DEBUG -#include "kawethfw.h" - #define KAWETH_MTU 1514 #define KAWETH_BUF_SIZE 1664 #define KAWETH_TX_TIMEOUT (5 * HZ) @@ -108,6 +107,10 @@ MODULE_AUTHOR("Michael Zappe , Stephane Alnet , Brad Hards and Oliver Neukum "); MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("kaweth/new_code.bin"); +MODULE_FIRMWARE("kaweth/new_code_fix.bin"); +MODULE_FIRMWARE("kaweth/trigger_code.bin"); +MODULE_FIRMWARE("kaweth/trigger_code_fix.bin"); static const char driver_name[] = "kaweth"; @@ -385,17 +388,28 @@ static int kaweth_set_receive_filter(struct kaweth_device *kaweth, * kaweth_download_firmware ****************************************************************/ static int kaweth_download_firmware(struct kaweth_device *kaweth, - __u8 *data, - __u16 data_len, + const char *fwname, __u8 interrupt, __u8 type) { - if(data_len > KAWETH_FIRMWARE_BUF_SIZE) { - err("Firmware too big: %d", data_len); + const struct firmware *fw; + int data_len; + int ret; + + ret = request_firmware(&fw, fwname, &kaweth->dev->dev); + if (ret) { + err("Firmware request failed\n"); + return ret; + } + + if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { + err("Firmware too big: %zu", fw->size); return -ENOSPC; } + data_len = fw->size; + memcpy(kaweth->firmware_buf, fw->data, fw->size); - memcpy(kaweth->firmware_buf, data, data_len); + release_firmware(fw); kaweth->firmware_buf[2] = (data_len & 0xFF) - 7; kaweth->firmware_buf[3] = data_len >> 8; @@ -406,8 +420,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, kaweth->firmware_buf[2]); dbg("Downloading firmware at %p to kaweth device at %p", - data, - kaweth); + fw->data, kaweth); dbg("Firmware length: %d", data_len); return kaweth_control(kaweth, @@ -1009,8 +1022,7 @@ static int kaweth_probe( info("Downloading firmware..."); kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); if ((result = kaweth_download_firmware(kaweth, - kaweth_new_code, - len_kaweth_new_code, + "kaweth/new_code.bin", 100, 2)) < 0) { err("Error downloading firmware (%d)", result); @@ -1018,8 +1030,7 @@ static int kaweth_probe( } if ((result = kaweth_download_firmware(kaweth, - kaweth_new_code_fix, - len_kaweth_new_code_fix, + "kaweth/new_code_fix.bin", 100, 3)) < 0) { err("Error downloading firmware fix (%d)", result); @@ -1027,8 +1038,7 @@ static int kaweth_probe( } if ((result = kaweth_download_firmware(kaweth, - kaweth_trigger_code, - len_kaweth_trigger_code, + "kaweth/trigger_code.bin", 126, 2)) < 0) { err("Error downloading trigger code (%d)", result); @@ -1037,8 +1047,7 @@ static int kaweth_probe( } if ((result = kaweth_download_firmware(kaweth, - kaweth_trigger_code_fix, - len_kaweth_trigger_code_fix, + "kaweth/trigger_code_fix.bin", 126, 3)) < 0) { err("Error downloading trigger code fix (%d)", result); diff --git a/drivers/net/usb/kawethfw.h b/drivers/net/usb/kawethfw.h deleted file mode 100644 index cf85fcb..0000000 --- a/drivers/net/usb/kawethfw.h +++ /dev/null @@ -1,557 +0,0 @@ -/******************************************/ -/* NOTE: B6/C3 is data header signature */ -/* 0xAA/0xBB is data length = total */ -/* bytes - 7, 0xCC is type, 0xDD is */ -/* interrupt to use. */ -/******************************************/ - -/**************************************************************** - * kaweth_trigger_code - ****************************************************************/ -static __u8 kaweth_trigger_code[] = -{ - 0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD, - 0xc8, 0x07, 0xa0, 0x00, 0xf0, 0x07, 0x5e, 0x00, - 0x06, 0x00, 0xf0, 0x07, 0x0a, 0x00, 0x08, 0x00, - 0xf0, 0x09, 0x00, 0x00, 0x02, 0x00, 0xe7, 0x07, - 0x36, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, - 0x04, 0x00, 0xe7, 0x07, 0x50, 0xc3, 0x10, 0xc0, - 0xf0, 0x09, 0x0e, 0xc0, 0x00, 0x00, 0xe7, 0x87, - 0x01, 0x00, 0x0e, 0xc0, 0x97, 0xcf, 0xd7, 0x09, - 0x00, 0xc0, 0x17, 0x02, 0xc8, 0x07, 0xa0, 0x00, - 0xe7, 0x17, 0x50, 0xc3, 0x10, 0xc0, 0x30, 0xd8, - 0x04, 0x00, 0x30, 0x5c, 0x08, 0x00, 0x04, 0x00, - 0xb0, 0xc0, 0x06, 0x00, 0xc8, 0x05, 0xe7, 0x05, - 0x00, 0xc0, 0xc0, 0xdf, 0x97, 0xcf, 0x49, 0xaf, - 0xc0, 0x07, 0x00, 0x00, 0x60, 0xaf, 0x4a, 0xaf, - 0x00, 0x0c, 0x0c, 0x00, 0x40, 0xd2, 0x00, 0x1c, - 0x0c, 0x00, 0x40, 0xd2, 0x30, 0x00, 0x08, 0x00, - 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00, 0xf0, 0x07, - 0x86, 0x00, 0x06, 0x00, 0x67, 0xcf, 0x27, 0x0c, - 0x02, 0x00, 0x00, 0x00, 0x27, 0x0c, 0x00, 0x00, - 0x0e, 0xc0, 0x49, 0xaf, 0x64, 0xaf, 0xc0, 0x07, - 0x00, 0x00, 0x4b, 0xaf, 0x4a, 0xaf, 0x5a, 0xcf, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x94, 0x00, 0x05, 0x00, - 0x00, 0x00 -}; -/**************************************************************** - * kaweth_trigger_code_fix - ****************************************************************/ -static __u8 kaweth_trigger_code_fix[] = -{ - 0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD, - 0x02, 0x00, 0x06, 0x00, 0x18, 0x00, 0x3e, 0x00, - 0x80, 0x00, 0x98, 0x00, 0xaa, 0x00, - 0x00, 0x00 -}; - -/**************************************************************** - * kaweth_new_code - ****************************************************************/ -static __u8 kaweth_new_code[] = -{ - 0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD, - 0x9f, 0xcf, 0xde, 0x06, 0xe7, 0x57, 0x00, 0x00, - 0xc4, 0x06, 0x97, 0xc1, 0xe7, 0x67, 0xff, 0x1f, - 0x28, 0xc0, 0xe7, 0x87, 0x00, 0x04, 0x24, 0xc0, - 0xe7, 0x67, 0xff, 0xf9, 0x22, 0xc0, 0x97, 0xcf, - 0xd7, 0x09, 0x00, 0xc0, 0xe7, 0x09, 0xa2, 0xc0, - 0xbe, 0x06, 0x9f, 0xaf, 0x36, 0x00, 0xe7, 0x05, - 0x00, 0xc0, 0xa7, 0xcf, 0xbc, 0x06, 0x97, 0xcf, - 0xe7, 0x57, 0x00, 0x00, 0xb8, 0x06, 0xa7, 0xa1, - 0xb8, 0x06, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00, - 0x14, 0x08, 0x0a, 0xc0, 0xe7, 0x57, 0x00, 0x00, - 0xa4, 0xc0, 0xa7, 0xc0, 0x7a, 0x06, 0x9f, 0xaf, - 0x92, 0x07, 0xe7, 0x07, 0x00, 0x00, 0x14, 0x08, - 0xe7, 0x57, 0xff, 0xff, 0xba, 0x06, 0x9f, 0xa0, - 0x38, 0x00, 0xe7, 0x59, 0xba, 0x06, 0xbe, 0x06, - 0x9f, 0xa0, 0x38, 0x00, 0xc8, 0x09, 0xca, 0x06, - 0x08, 0x62, 0x9f, 0xa1, 0x36, 0x08, 0xc0, 0x09, - 0x76, 0x06, 0x00, 0x60, 0xa7, 0xc0, 0x7a, 0x06, - 0x9f, 0xaf, 0xcc, 0x02, 0xe7, 0x57, 0x00, 0x00, - 0xb8, 0x06, 0xa7, 0xc1, 0x7a, 0x06, 0x9f, 0xaf, - 0x04, 0x00, 0xe7, 0x57, 0x00, 0x00, 0x8e, 0x06, - 0x0a, 0xc1, 0xe7, 0x09, 0x20, 0xc0, 0x10, 0x08, - 0xe7, 0xd0, 0x10, 0x08, 0xe7, 0x67, 0x40, 0x00, - 0x10, 0x08, 0x9f, 0xaf, 0x92, 0x0c, 0xc0, 0x09, - 0xd0, 0x06, 0x00, 0x60, 0x05, 0xc4, 0xc0, 0x59, - 0xbe, 0x06, 0x02, 0xc0, 0x9f, 0xaf, 0xec, 0x00, - 0x9f, 0xaf, 0x34, 0x02, 0xe7, 0x57, 0x00, 0x00, - 0xa6, 0x06, 0x9f, 0xa0, 0x7a, 0x02, 0xa7, 0xcf, - 0x7a, 0x06, 0x48, 0x02, 0xe7, 0x09, 0xbe, 0x06, - 0xd0, 0x06, 0xc8, 0x37, 0x04, 0x00, 0x9f, 0xaf, - 0x08, 0x03, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00, - 0xce, 0x06, 0x97, 0xc0, 0xd7, 0x09, 0x00, 0xc0, - 0xc1, 0xdf, 0xc8, 0x09, 0xc6, 0x06, 0x08, 0x62, - 0x14, 0xc0, 0x27, 0x04, 0xc6, 0x06, 0x10, 0x94, - 0xf0, 0x07, 0x10, 0x08, 0x02, 0x00, 0xc1, 0x07, - 0x01, 0x00, 0x70, 0x00, 0x04, 0x00, 0xf0, 0x07, - 0x30, 0x01, 0x06, 0x00, 0x50, 0xaf, 0xe7, 0x07, - 0xff, 0xff, 0xd0, 0x06, 0xe7, 0x07, 0x00, 0x00, - 0xce, 0x06, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, - 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x48, 0x02, - 0xd0, 0x09, 0xc6, 0x06, 0x27, 0x02, 0xc6, 0x06, - 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0x48, 0x02, - 0xc8, 0x37, 0x04, 0x00, 0x00, 0x0c, 0x0c, 0x00, - 0x00, 0x60, 0x21, 0xc0, 0xc0, 0x37, 0x3e, 0x00, - 0x23, 0xc9, 0xc0, 0x57, 0xb4, 0x05, 0x1b, 0xc8, - 0xc0, 0x17, 0x3f, 0x00, 0xc0, 0x67, 0xc0, 0xff, - 0x30, 0x00, 0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x02, 0xc0, 0x17, 0x4c, 0x00, - 0x30, 0x00, 0x06, 0x00, 0xf0, 0x07, 0xa0, 0x01, - 0x0a, 0x00, 0x48, 0x02, 0xc1, 0x07, 0x02, 0x00, - 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x51, 0xaf, - 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0x9f, 0xaf, - 0x08, 0x03, 0x9f, 0xaf, 0x7a, 0x02, 0x97, 0xcf, - 0x9f, 0xaf, 0x7a, 0x02, 0xc9, 0x37, 0x04, 0x00, - 0xc1, 0xdf, 0xc8, 0x09, 0xa2, 0x06, 0x50, 0x02, - 0x67, 0x02, 0xa2, 0x06, 0xd1, 0x07, 0x00, 0x00, - 0x27, 0xd8, 0xaa, 0x06, 0xc0, 0xdf, 0x9f, 0xaf, - 0xc4, 0x01, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00, - 0xd2, 0x06, 0x97, 0xc1, 0xe7, 0x57, 0x01, 0x00, - 0xa8, 0x06, 0x97, 0xc0, 0xc8, 0x09, 0xa0, 0x06, - 0x08, 0x62, 0x97, 0xc0, 0x00, 0x02, 0xc0, 0x17, - 0x0e, 0x00, 0x27, 0x00, 0x34, 0x01, 0x27, 0x0c, - 0x0c, 0x00, 0x36, 0x01, 0xe7, 0x07, 0x50, 0xc3, - 0x12, 0xc0, 0xe7, 0x07, 0xcc, 0x0b, 0x02, 0x00, - 0xe7, 0x07, 0x01, 0x00, 0xa8, 0x06, 0xe7, 0x07, - 0x05, 0x00, 0x90, 0xc0, 0x97, 0xcf, 0xc8, 0x09, - 0xa4, 0x06, 0x08, 0x62, 0x02, 0xc0, 0x10, 0x64, - 0x07, 0xc1, 0xe7, 0x07, 0x00, 0x00, 0x9e, 0x06, - 0xe7, 0x07, 0x72, 0x04, 0x24, 0x00, 0x97, 0xcf, - 0x27, 0x04, 0xa4, 0x06, 0xc8, 0x17, 0x0e, 0x00, - 0x27, 0x02, 0x9e, 0x06, 0xe7, 0x07, 0x80, 0x04, - 0x24, 0x00, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, - 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00, 0x90, 0x06, - 0x13, 0xc1, 0x9f, 0xaf, 0x06, 0x02, 0xe7, 0x57, - 0x00, 0x00, 0x9e, 0x06, 0x13, 0xc0, 0xe7, 0x09, - 0x9e, 0x06, 0x30, 0x01, 0xe7, 0x07, 0xf2, 0x05, - 0x32, 0x01, 0xe7, 0x07, 0x10, 0x00, 0x96, 0xc0, - 0xe7, 0x09, 0x9e, 0x06, 0x90, 0x06, 0x04, 0xcf, - 0xe7, 0x57, 0x00, 0x00, 0x9e, 0x06, 0x02, 0xc1, - 0x9f, 0xaf, 0x06, 0x02, 0xe7, 0x05, 0x00, 0xc0, - 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, - 0x08, 0x92, 0xe7, 0x57, 0x02, 0x00, 0xaa, 0x06, - 0x02, 0xc3, 0xc8, 0x09, 0xa4, 0x06, 0x27, 0x02, - 0xa6, 0x06, 0x08, 0x62, 0x03, 0xc1, 0xe7, 0x05, - 0x00, 0xc0, 0x97, 0xcf, 0x27, 0x04, 0xa4, 0x06, - 0xe7, 0x05, 0x00, 0xc0, 0xf0, 0x07, 0x40, 0x00, - 0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x02, 0xc0, 0x17, 0x0c, 0x00, 0x30, 0x00, - 0x06, 0x00, 0xf0, 0x07, 0x46, 0x01, 0x0a, 0x00, - 0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x02, 0x00, - 0x51, 0xaf, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00, - 0x96, 0x06, 0x97, 0xc0, 0xc1, 0xdf, 0xc8, 0x09, - 0x96, 0x06, 0x27, 0x04, 0x96, 0x06, 0x27, 0x52, - 0x98, 0x06, 0x03, 0xc1, 0xe7, 0x07, 0x96, 0x06, - 0x98, 0x06, 0xc0, 0xdf, 0x17, 0x02, 0xc8, 0x17, - 0x0e, 0x00, 0x9f, 0xaf, 0xba, 0x03, 0xc8, 0x05, - 0x00, 0x60, 0x03, 0xc0, 0x9f, 0xaf, 0x24, 0x03, - 0x97, 0xcf, 0x9f, 0xaf, 0x08, 0x03, 0x97, 0xcf, - 0x57, 0x02, 0xc9, 0x07, 0xa4, 0x06, 0xd7, 0x09, - 0x00, 0xc0, 0xc1, 0xdf, 0x08, 0x62, 0x1b, 0xc0, - 0x50, 0x04, 0x11, 0x02, 0xe7, 0x05, 0x00, 0xc0, - 0xc9, 0x05, 0x97, 0xcf, 0x97, 0x02, 0xca, 0x09, - 0xd6, 0x06, 0xf2, 0x17, 0x01, 0x00, 0x04, 0x00, - 0xf2, 0x27, 0x00, 0x00, 0x06, 0x00, 0xca, 0x17, - 0x2c, 0x00, 0xf8, 0x77, 0x01, 0x00, 0x0e, 0x00, - 0x06, 0xc0, 0xca, 0xd9, 0xf8, 0x57, 0xff, 0x00, - 0x0e, 0x00, 0x01, 0xc1, 0xca, 0xd9, 0x22, 0x1c, - 0x0c, 0x00, 0xe2, 0x27, 0x00, 0x00, 0xe2, 0x17, - 0x01, 0x00, 0xe2, 0x27, 0x00, 0x00, 0xca, 0x05, - 0x00, 0x0c, 0x0c, 0x00, 0xc0, 0x17, 0x41, 0x00, - 0xc0, 0x67, 0xc0, 0xff, 0x30, 0x00, 0x08, 0x00, - 0x00, 0x02, 0xc0, 0x17, 0x0c, 0x00, 0x30, 0x00, - 0x06, 0x00, 0xf0, 0x07, 0xda, 0x00, 0x0a, 0x00, - 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0c, - 0x08, 0x00, 0x40, 0xd1, 0x01, 0x00, 0xc0, 0x19, - 0xce, 0x06, 0xc0, 0x59, 0xc2, 0x06, 0x04, 0xc9, - 0x49, 0xaf, 0x9f, 0xaf, 0xec, 0x00, 0x4a, 0xaf, - 0x67, 0x10, 0xce, 0x06, 0xc8, 0x17, 0x04, 0x00, - 0xc1, 0x07, 0x01, 0x00, 0xd7, 0x09, 0x00, 0xc0, - 0xc1, 0xdf, 0x50, 0xaf, 0xe7, 0x05, 0x00, 0xc0, - 0x97, 0xcf, 0xc0, 0x07, 0x01, 0x00, 0xc1, 0x09, - 0xac, 0x06, 0xc1, 0x77, 0x01, 0x00, 0x97, 0xc1, - 0xd8, 0x77, 0x01, 0x00, 0x12, 0xc0, 0xc9, 0x07, - 0x6a, 0x06, 0x9f, 0xaf, 0x08, 0x04, 0x04, 0xc1, - 0xc1, 0x77, 0x08, 0x00, 0x13, 0xc0, 0x97, 0xcf, - 0xc1, 0x77, 0x02, 0x00, 0x97, 0xc1, 0xc1, 0x77, - 0x10, 0x00, 0x0c, 0xc0, 0x9f, 0xaf, 0x2c, 0x04, - 0x97, 0xcf, 0xc1, 0x77, 0x04, 0x00, 0x06, 0xc0, - 0xc9, 0x07, 0x70, 0x06, 0x9f, 0xaf, 0x08, 0x04, - 0x97, 0xc0, 0x00, 0xcf, 0x00, 0x90, 0x97, 0xcf, - 0x50, 0x54, 0x97, 0xc1, 0x70, 0x5c, 0x02, 0x00, - 0x02, 0x00, 0x97, 0xc1, 0x70, 0x5c, 0x04, 0x00, - 0x04, 0x00, 0x97, 0xcf, 0x80, 0x01, 0xc0, 0x00, - 0x60, 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, - 0x06, 0x00, 0x00, 0x00, 0xcb, 0x09, 0xb2, 0x06, - 0xcc, 0x09, 0xb4, 0x06, 0x0b, 0x53, 0x11, 0xc0, - 0xc9, 0x02, 0xca, 0x07, 0x1c, 0x04, 0x9f, 0xaf, - 0x08, 0x04, 0x97, 0xc0, 0x0a, 0xc8, 0x82, 0x08, - 0x0a, 0xcf, 0x82, 0x08, 0x9f, 0xaf, 0x08, 0x04, - 0x97, 0xc0, 0x05, 0xc2, 0x89, 0x30, 0x82, 0x60, - 0x78, 0xc1, 0x00, 0x90, 0x97, 0xcf, 0x89, 0x10, - 0x09, 0x53, 0x79, 0xc2, 0x89, 0x30, 0x82, 0x08, - 0x7a, 0xcf, 0xc0, 0xdf, 0x97, 0xcf, 0xc0, 0xdf, - 0x97, 0xcf, 0xe7, 0x09, 0x96, 0xc0, 0x92, 0x06, - 0xe7, 0x09, 0x98, 0xc0, 0x94, 0x06, 0x0f, 0xcf, - 0xe7, 0x09, 0x96, 0xc0, 0x92, 0x06, 0xe7, 0x09, - 0x98, 0xc0, 0x94, 0x06, 0xe7, 0x09, 0x9e, 0x06, - 0x30, 0x01, 0xe7, 0x07, 0xf2, 0x05, 0x32, 0x01, - 0xe7, 0x07, 0x10, 0x00, 0x96, 0xc0, 0xd7, 0x09, - 0x00, 0xc0, 0x17, 0x02, 0xc8, 0x09, 0x90, 0x06, - 0xc8, 0x37, 0x0e, 0x00, 0xe7, 0x77, 0x2a, 0x00, - 0x92, 0x06, 0x30, 0xc0, 0x97, 0x02, 0xca, 0x09, - 0xd6, 0x06, 0xe7, 0x77, 0x20, 0x00, 0x92, 0x06, - 0x0e, 0xc0, 0xf2, 0x17, 0x01, 0x00, 0x10, 0x00, - 0xf2, 0x27, 0x00, 0x00, 0x12, 0x00, 0xe7, 0x77, - 0x0a, 0x00, 0x92, 0x06, 0xca, 0x05, 0x1e, 0xc0, - 0x97, 0x02, 0xca, 0x09, 0xd6, 0x06, 0xf2, 0x17, - 0x01, 0x00, 0x0c, 0x00, 0xf2, 0x27, 0x00, 0x00, - 0x0e, 0x00, 0xe7, 0x77, 0x02, 0x00, 0x92, 0x06, - 0x07, 0xc0, 0xf2, 0x17, 0x01, 0x00, 0x44, 0x00, - 0xf2, 0x27, 0x00, 0x00, 0x46, 0x00, 0x06, 0xcf, - 0xf2, 0x17, 0x01, 0x00, 0x60, 0x00, 0xf2, 0x27, - 0x00, 0x00, 0x62, 0x00, 0xca, 0x05, 0x9f, 0xaf, - 0x08, 0x03, 0x0f, 0xcf, 0x57, 0x02, 0x09, 0x02, - 0xf1, 0x09, 0x94, 0x06, 0x0c, 0x00, 0xf1, 0xda, - 0x0c, 0x00, 0xc8, 0x09, 0x98, 0x06, 0x50, 0x02, - 0x67, 0x02, 0x98, 0x06, 0xd1, 0x07, 0x00, 0x00, - 0xc9, 0x05, 0xe7, 0x09, 0x9e, 0x06, 0x90, 0x06, - 0xe7, 0x57, 0x00, 0x00, 0x90, 0x06, 0x02, 0xc0, - 0x9f, 0xaf, 0x06, 0x02, 0xc8, 0x05, 0xe7, 0x05, - 0x00, 0xc0, 0xc0, 0xdf, 0x97, 0xcf, 0xd7, 0x09, - 0x00, 0xc0, 0x17, 0x00, 0x17, 0x02, 0x97, 0x02, - 0xc0, 0x09, 0x92, 0xc0, 0xe7, 0x07, 0x04, 0x00, - 0x90, 0xc0, 0xca, 0x09, 0xd6, 0x06, 0xe7, 0x07, - 0x00, 0x00, 0xa8, 0x06, 0xe7, 0x07, 0x6a, 0x04, - 0x02, 0x00, 0xc0, 0x77, 0x02, 0x00, 0x08, 0xc0, - 0xf2, 0x17, 0x01, 0x00, 0x50, 0x00, 0xf2, 0x27, - 0x00, 0x00, 0x52, 0x00, 0x9f, 0xcf, 0x24, 0x06, - 0xc0, 0x77, 0x10, 0x00, 0x06, 0xc0, 0xf2, 0x17, - 0x01, 0x00, 0x58, 0x00, 0xf2, 0x27, 0x00, 0x00, - 0x5a, 0x00, 0xc0, 0x77, 0x80, 0x00, 0x06, 0xc0, - 0xf2, 0x17, 0x01, 0x00, 0x70, 0x00, 0xf2, 0x27, - 0x00, 0x00, 0x72, 0x00, 0xc0, 0x77, 0x08, 0x00, - 0x1d, 0xc1, 0xf2, 0x17, 0x01, 0x00, 0x08, 0x00, - 0xf2, 0x27, 0x00, 0x00, 0x0a, 0x00, 0xc0, 0x77, - 0x00, 0x02, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00, - 0x64, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x66, 0x00, - 0xc0, 0x77, 0x40, 0x00, 0x06, 0xc0, 0xf2, 0x17, - 0x01, 0x00, 0x5c, 0x00, 0xf2, 0x27, 0x00, 0x00, - 0x5e, 0x00, 0xc0, 0x77, 0x01, 0x00, 0x01, 0xc0, - 0x1b, 0xcf, 0x1a, 0xcf, 0xf2, 0x17, 0x01, 0x00, - 0x00, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x02, 0x00, - 0xc8, 0x09, 0x34, 0x01, 0xca, 0x17, 0x14, 0x00, - 0xd8, 0x77, 0x01, 0x00, 0x05, 0xc0, 0xca, 0xd9, - 0xd8, 0x57, 0xff, 0x00, 0x01, 0xc0, 0xca, 0xd9, - 0xe2, 0x19, 0x94, 0xc0, 0xe2, 0x27, 0x00, 0x00, - 0xe2, 0x17, 0x01, 0x00, 0xe2, 0x27, 0x00, 0x00, - 0x9f, 0xaf, 0x40, 0x06, 0x9f, 0xaf, 0xc4, 0x01, - 0xe7, 0x57, 0x00, 0x00, 0xd2, 0x06, 0x9f, 0xa1, - 0x0e, 0x0a, 0xca, 0x05, 0xc8, 0x05, 0xc0, 0x05, - 0xe7, 0x05, 0x00, 0xc0, 0xc0, 0xdf, 0x97, 0xcf, - 0xc8, 0x09, 0xa0, 0x06, 0x08, 0x62, 0x97, 0xc0, - 0x27, 0x04, 0xa0, 0x06, 0x27, 0x52, 0xa2, 0x06, - 0x03, 0xc1, 0xe7, 0x07, 0xa0, 0x06, 0xa2, 0x06, - 0x9f, 0xaf, 0x08, 0x03, 0xe7, 0x57, 0x00, 0x00, - 0xaa, 0x06, 0x02, 0xc0, 0x27, 0xda, 0xaa, 0x06, - 0x97, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xfb, 0x13, 0xe7, 0x57, - 0x00, 0x80, 0xb2, 0x00, 0x06, 0xc2, 0xe7, 0x07, - 0xee, 0x0b, 0x12, 0x00, 0xe7, 0x07, 0x34, 0x0c, - 0xb2, 0x00, 0xe7, 0x07, 0xc6, 0x07, 0xf2, 0x02, - 0xc8, 0x09, 0xb4, 0x00, 0xf8, 0x07, 0x02, 0x00, - 0x0d, 0x00, 0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07, - 0x00, 0x00, 0x0e, 0xc0, 0xc8, 0x09, 0xde, 0x00, - 0xc8, 0x17, 0x09, 0x00, 0xc9, 0x07, 0xda, 0x06, - 0xc0, 0x07, 0x04, 0x00, 0x68, 0x0a, 0x00, 0xda, - 0x7d, 0xc1, 0xe7, 0x09, 0xc0, 0x00, 0x7c, 0x06, - 0xe7, 0x09, 0xbe, 0x00, 0x78, 0x06, 0xe7, 0x09, - 0x10, 0x00, 0xbc, 0x06, 0xc8, 0x07, 0xd6, 0x07, - 0x9f, 0xaf, 0xae, 0x07, 0x9f, 0xaf, 0x00, 0x0a, - 0xc8, 0x09, 0xde, 0x00, 0x00, 0x0e, 0x0f, 0x00, - 0x41, 0x90, 0x9f, 0xde, 0x06, 0x00, 0x44, 0xaf, - 0x27, 0x00, 0xb2, 0x06, 0x27, 0x00, 0xb4, 0x06, - 0x27, 0x00, 0xb6, 0x06, 0xc0, 0x07, 0x74, 0x00, - 0x44, 0xaf, 0x27, 0x00, 0xd6, 0x06, 0x08, 0x00, - 0x00, 0x90, 0xc1, 0x07, 0x3a, 0x00, 0x20, 0x00, - 0x01, 0xda, 0x7d, 0xc1, 0x9f, 0xaf, 0xba, 0x09, - 0xc0, 0x07, 0x44, 0x00, 0x48, 0xaf, 0x27, 0x00, - 0x7a, 0x06, 0x9f, 0xaf, 0x96, 0x0a, 0xe7, 0x07, - 0x01, 0x00, 0xc0, 0x06, 0xe7, 0x05, 0x0e, 0xc0, - 0x97, 0xcf, 0x49, 0xaf, 0xe7, 0x87, 0x43, 0x00, - 0x0e, 0xc0, 0xe7, 0x07, 0xff, 0xff, 0xbe, 0x06, - 0x9f, 0xaf, 0xae, 0x0a, 0xc0, 0x07, 0x01, 0x00, - 0x60, 0xaf, 0x4a, 0xaf, 0x97, 0xcf, 0x00, 0x08, - 0x09, 0x08, 0x11, 0x08, 0x00, 0xda, 0x7c, 0xc1, - 0x97, 0xcf, 0x67, 0x04, 0xcc, 0x02, 0xc0, 0xdf, - 0x51, 0x94, 0xb1, 0xaf, 0x06, 0x00, 0xc1, 0xdf, - 0xc9, 0x09, 0xcc, 0x02, 0x49, 0x62, 0x75, 0xc1, - 0xc0, 0xdf, 0xa7, 0xcf, 0xd6, 0x02, 0x0e, 0x00, - 0x24, 0x00, 0x80, 0x04, 0x22, 0x00, 0x4e, 0x05, - 0xd0, 0x00, 0x0e, 0x0a, 0xaa, 0x00, 0x30, 0x08, - 0xbe, 0x00, 0x4a, 0x0a, 0x10, 0x00, 0x20, 0x00, - 0x04, 0x00, 0x6e, 0x04, 0x02, 0x00, 0x6a, 0x04, - 0x06, 0x00, 0x00, 0x00, 0x24, 0xc0, 0x04, 0x04, - 0x28, 0xc0, 0xfe, 0xfb, 0x1e, 0xc0, 0x00, 0x04, - 0x22, 0xc0, 0xff, 0xf4, 0xc0, 0x00, 0x90, 0x09, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56, 0x08, - 0x60, 0x08, 0xd0, 0x08, 0xda, 0x08, 0x00, 0x09, - 0x04, 0x09, 0x08, 0x09, 0x32, 0x09, 0x42, 0x09, - 0x50, 0x09, 0x52, 0x09, 0x5a, 0x09, 0x5a, 0x09, - 0x27, 0x02, 0xca, 0x06, 0x97, 0xcf, 0xe7, 0x07, - 0x00, 0x00, 0xca, 0x06, 0x0a, 0x0e, 0x01, 0x00, - 0xca, 0x57, 0x0e, 0x00, 0x9f, 0xc3, 0x5a, 0x09, - 0xca, 0x37, 0x00, 0x00, 0x9f, 0xc2, 0x5a, 0x09, - 0x0a, 0xd2, 0xb2, 0xcf, 0x16, 0x08, 0xc8, 0x09, - 0xde, 0x00, 0x07, 0x06, 0x9f, 0xcf, 0x6c, 0x09, - 0x17, 0x02, 0xc8, 0x09, 0xde, 0x00, 0x00, 0x0e, - 0x0f, 0x00, 0x41, 0x90, 0x9f, 0xde, 0x06, 0x00, - 0xc8, 0x05, 0x30, 0x50, 0x06, 0x00, 0x9f, 0xc8, - 0x5a, 0x09, 0x27, 0x0c, 0x02, 0x00, 0xb0, 0x06, - 0xc0, 0x09, 0xb2, 0x06, 0x27, 0x00, 0xb4, 0x06, - 0xe7, 0x07, 0x00, 0x00, 0xae, 0x06, 0x27, 0x00, - 0x80, 0x06, 0x00, 0x1c, 0x06, 0x00, 0x27, 0x00, - 0xb6, 0x06, 0x41, 0x90, 0x67, 0x50, 0xb0, 0x06, - 0x0d, 0xc0, 0x67, 0x00, 0x7e, 0x06, 0x27, 0x0c, - 0x06, 0x00, 0x82, 0x06, 0xe7, 0x07, 0xbc, 0x08, - 0x84, 0x06, 0xc8, 0x07, 0x7e, 0x06, 0x41, 0x90, - 0x51, 0xaf, 0x97, 0xcf, 0x9f, 0xaf, 0x48, 0x0c, - 0xe7, 0x09, 0xb6, 0x06, 0xb4, 0x06, 0xe7, 0x09, - 0xb0, 0x06, 0xae, 0x06, 0x59, 0xaf, 0x97, 0xcf, - 0x27, 0x0c, 0x02, 0x00, 0xac, 0x06, 0x59, 0xaf, - 0x97, 0xcf, 0x09, 0x0c, 0x02, 0x00, 0x09, 0xda, - 0x49, 0xd2, 0xc9, 0x19, 0xd6, 0x06, 0xc8, 0x07, - 0x7e, 0x06, 0xe0, 0x07, 0x00, 0x00, 0x60, 0x02, - 0xe0, 0x07, 0x04, 0x00, 0xd0, 0x07, 0xcc, 0x08, - 0x48, 0xdb, 0x41, 0x90, 0x50, 0xaf, 0x97, 0xcf, - 0x59, 0xaf, 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf, - 0xf0, 0x57, 0x06, 0x00, 0x06, 0x00, 0x25, 0xc1, - 0xe7, 0x07, 0x70, 0x06, 0x80, 0x06, 0x41, 0x90, - 0x67, 0x00, 0x7e, 0x06, 0x27, 0x0c, 0x06, 0x00, - 0x82, 0x06, 0xe7, 0x07, 0x8c, 0x09, 0x84, 0x06, - 0xc8, 0x07, 0x7e, 0x06, 0x41, 0x90, 0x51, 0xaf, - 0x97, 0xcf, 0x07, 0x0c, 0x06, 0x00, 0xc7, 0x57, - 0x06, 0x00, 0x0f, 0xc1, 0xc8, 0x07, 0x70, 0x06, - 0x15, 0xcf, 0x00, 0x0c, 0x02, 0x00, 0x00, 0xda, - 0x40, 0xd1, 0x27, 0x00, 0xc2, 0x06, 0x1e, 0xcf, - 0x1d, 0xcf, 0x27, 0x0c, 0x02, 0x00, 0xcc, 0x06, - 0x19, 0xcf, 0x27, 0x02, 0x20, 0x01, 0xe7, 0x07, - 0x08, 0x00, 0x22, 0x01, 0xe7, 0x07, 0x13, 0x00, - 0xb0, 0xc0, 0x97, 0xcf, 0x41, 0x90, 0x67, 0x00, - 0x7e, 0x06, 0xe7, 0x01, 0x82, 0x06, 0x27, 0x02, - 0x80, 0x06, 0xe7, 0x07, 0x8c, 0x09, 0x84, 0x06, - 0xc8, 0x07, 0x7e, 0x06, 0xc1, 0x07, 0x00, 0x80, - 0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf, - 0x00, 0x60, 0x05, 0xc0, 0xe7, 0x07, 0x00, 0x00, - 0xc4, 0x06, 0xa7, 0xcf, 0x7c, 0x06, 0x9f, 0xaf, - 0x00, 0x0a, 0xe7, 0x07, 0x01, 0x00, 0xc4, 0x06, - 0x49, 0xaf, 0xd7, 0x09, 0x00, 0xc0, 0x07, 0xaf, - 0xe7, 0x05, 0x00, 0xc0, 0x4a, 0xaf, 0xa7, 0xcf, - 0x7c, 0x06, 0xc0, 0x07, 0xfe, 0x7f, 0x44, 0xaf, - 0x40, 0x00, 0xc0, 0x37, 0x00, 0x01, 0x41, 0x90, - 0xc0, 0x37, 0x08, 0x00, 0xdf, 0xde, 0x50, 0x06, - 0xc0, 0x57, 0x10, 0x00, 0x02, 0xc2, 0xc0, 0x07, - 0x10, 0x00, 0x27, 0x00, 0x9a, 0x06, 0x41, 0x90, - 0x9f, 0xde, 0x40, 0x06, 0x44, 0xaf, 0x27, 0x00, - 0x9c, 0x06, 0xc0, 0x09, 0x9a, 0x06, 0x41, 0x90, - 0x00, 0xd2, 0x00, 0xd8, 0x9f, 0xde, 0x08, 0x00, - 0x44, 0xaf, 0x27, 0x00, 0xc8, 0x06, 0x97, 0xcf, - 0xe7, 0x87, 0x00, 0x84, 0x28, 0xc0, 0xe7, 0x67, - 0xff, 0xfb, 0x24, 0xc0, 0x97, 0xcf, 0xe7, 0x87, - 0x01, 0x00, 0xd2, 0x06, 0xe7, 0x57, 0x00, 0x00, - 0xa8, 0x06, 0x97, 0xc1, 0x9f, 0xaf, 0x00, 0x0a, - 0xe7, 0x87, 0x00, 0x06, 0x22, 0xc0, 0xe7, 0x07, - 0x00, 0x00, 0x90, 0xc0, 0xe7, 0x67, 0xfe, 0xff, - 0x3e, 0xc0, 0xe7, 0x07, 0x26, 0x00, 0x0a, 0xc0, - 0xe7, 0x87, 0x01, 0x00, 0x3e, 0xc0, 0xe7, 0x07, - 0xff, 0xff, 0xbe, 0x06, 0x9f, 0xaf, 0x10, 0x0b, - 0x97, 0xcf, 0x17, 0x00, 0xa7, 0xaf, 0x78, 0x06, - 0xc0, 0x05, 0x27, 0x00, 0x76, 0x06, 0xe7, 0x87, - 0x01, 0x00, 0xd2, 0x06, 0x9f, 0xaf, 0x00, 0x0a, - 0xe7, 0x07, 0x0c, 0x00, 0x40, 0xc0, 0x9f, 0xaf, - 0x10, 0x0b, 0x00, 0x90, 0x27, 0x00, 0xa6, 0x06, - 0x27, 0x00, 0xaa, 0x06, 0xe7, 0x09, 0xb2, 0x06, - 0xb4, 0x06, 0x27, 0x00, 0xae, 0x06, 0x27, 0x00, - 0xac, 0x06, 0x9f, 0xaf, 0xae, 0x0a, 0xc0, 0x07, - 0x00, 0x00, 0x27, 0x00, 0xb2, 0x02, 0x27, 0x00, - 0xb4, 0x02, 0x27, 0x00, 0x8e, 0x06, 0xc0, 0x07, - 0x06, 0x00, 0xc8, 0x09, 0xde, 0x00, 0xc8, 0x17, - 0x03, 0x00, 0xc9, 0x07, 0x70, 0x06, 0x29, 0x0a, - 0x00, 0xda, 0x7d, 0xc1, 0x97, 0xcf, 0xd7, 0x09, - 0x00, 0xc0, 0xc1, 0xdf, 0x00, 0x90, 0x27, 0x00, - 0x96, 0x06, 0xe7, 0x07, 0x96, 0x06, 0x98, 0x06, - 0x27, 0x00, 0xa0, 0x06, 0xe7, 0x07, 0xa0, 0x06, - 0xa2, 0x06, 0x27, 0x00, 0xa6, 0x06, 0x27, 0x00, - 0x90, 0x06, 0x27, 0x00, 0x9e, 0x06, 0xc8, 0x09, - 0x9c, 0x06, 0xc1, 0x09, 0x9a, 0x06, 0xc9, 0x07, - 0xa4, 0x06, 0x11, 0x02, 0x09, 0x02, 0xc8, 0x17, - 0x40, 0x06, 0x01, 0xda, 0x7a, 0xc1, 0x51, 0x94, - 0xc8, 0x09, 0xc8, 0x06, 0xc9, 0x07, 0xc6, 0x06, - 0xc1, 0x09, 0x9a, 0x06, 0x11, 0x02, 0x09, 0x02, - 0xc8, 0x17, 0x08, 0x00, 0x01, 0xda, 0x7a, 0xc1, - 0x51, 0x94, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, - 0xe7, 0x57, 0x00, 0x00, 0x76, 0x06, 0x97, 0xc0, - 0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x09, 0xbe, 0x06, - 0xba, 0x06, 0xe7, 0x57, 0xff, 0xff, 0xba, 0x06, - 0x04, 0xc1, 0xe7, 0x07, 0x10, 0x0b, 0xb8, 0x06, - 0x97, 0xcf, 0xe7, 0x17, 0x32, 0x00, 0xba, 0x06, - 0xe7, 0x67, 0xff, 0x07, 0xba, 0x06, 0xe7, 0x07, - 0x46, 0x0b, 0xb8, 0x06, 0x97, 0xcf, 0xe7, 0x57, - 0x00, 0x00, 0xc0, 0x06, 0x23, 0xc0, 0xe7, 0x07, - 0x04, 0x00, 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x80, - 0x80, 0xc0, 0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, - 0xe7, 0x07, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x07, - 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, - 0x00, 0x00, 0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, - 0xe7, 0x07, 0x00, 0x80, 0x80, 0xc0, 0xe7, 0x07, - 0x00, 0x80, 0x40, 0xc0, 0xc0, 0x07, 0x00, 0x00, - 0xe7, 0x07, 0x00, 0x00, 0x40, 0xc0, 0xe7, 0x07, - 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07, 0x04, 0x00, - 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x02, 0x40, 0xc0, - 0xe7, 0x07, 0x0c, 0x02, 0x40, 0xc0, 0xe7, 0x07, - 0x00, 0x00, 0xc0, 0x06, 0xe7, 0x07, 0x00, 0x00, - 0xb8, 0x06, 0xe7, 0x07, 0x00, 0x00, 0xd2, 0x06, - 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x9f, 0xaf, - 0x34, 0x02, 0xe7, 0x05, 0x00, 0xc0, 0x9f, 0xaf, - 0xc4, 0x01, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, - 0x17, 0x00, 0x17, 0x02, 0x97, 0x02, 0xe7, 0x57, - 0x00, 0x00, 0xa8, 0x06, 0x06, 0xc0, 0xc0, 0x09, - 0x92, 0xc0, 0xc0, 0x77, 0x09, 0x02, 0x9f, 0xc1, - 0x5c, 0x05, 0x9f, 0xcf, 0x32, 0x06, 0xd7, 0x09, - 0x0e, 0xc0, 0xe7, 0x07, 0x00, 0x00, 0x0e, 0xc0, - 0x9f, 0xaf, 0x02, 0x0c, 0xe7, 0x05, 0x0e, 0xc0, - 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, 0x17, 0x02, - 0xc8, 0x09, 0xb0, 0xc0, 0xe7, 0x67, 0xfe, 0x7f, - 0xb0, 0xc0, 0xc8, 0x77, 0x00, 0x20, 0x9f, 0xc1, - 0x64, 0xeb, 0xe7, 0x57, 0x00, 0x00, 0xc8, 0x02, - 0x9f, 0xc1, 0x80, 0xeb, 0xc8, 0x99, 0xca, 0x02, - 0xc8, 0x67, 0x04, 0x00, 0x9f, 0xc1, 0x96, 0xeb, - 0x9f, 0xcf, 0x4c, 0xeb, 0xe7, 0x07, 0x00, 0x00, - 0xa6, 0xc0, 0xe7, 0x09, 0xb0, 0xc0, 0xc8, 0x02, - 0xe7, 0x07, 0x03, 0x00, 0xb0, 0xc0, 0x97, 0xcf, - 0xc0, 0x09, 0xb0, 0x06, 0xc0, 0x37, 0x01, 0x00, - 0x97, 0xc9, 0xc9, 0x09, 0xb2, 0x06, 0x02, 0x00, - 0x41, 0x90, 0x48, 0x02, 0xc9, 0x17, 0x06, 0x00, - 0x9f, 0xaf, 0x08, 0x04, 0x9f, 0xa2, 0x72, 0x0c, - 0x02, 0xda, 0x77, 0xc1, 0x41, 0x60, 0x71, 0xc1, - 0x97, 0xcf, 0x17, 0x02, 0x57, 0x02, 0x43, 0x04, - 0x21, 0x04, 0xe0, 0x00, 0x43, 0x04, 0x21, 0x04, - 0xe0, 0x00, 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00, - 0xc1, 0x07, 0x01, 0x00, 0xc9, 0x05, 0xc8, 0x05, - 0x97, 0xcf, 0xe7, 0x07, 0x01, 0x00, 0x8e, 0x06, - 0xc8, 0x07, 0x86, 0x06, 0xe7, 0x07, 0x00, 0x00, - 0x86, 0x06, 0xe7, 0x07, 0x10, 0x08, 0x88, 0x06, - 0xe7, 0x07, 0x04, 0x00, 0x8a, 0x06, 0xe7, 0x07, - 0xbc, 0x0c, 0x8c, 0x06, 0xc1, 0x07, 0x03, 0x80, - 0x50, 0xaf, 0x97, 0xcf, 0xe7, 0x07, 0x00, 0x00, - 0x8e, 0x06, 0x97, 0xcf, - 0x00, 0x00 -}; - -/**************************************************************** - * kaweth_new_code_fix - ****************************************************************/ -static __u8 kaweth_new_code_fix[] = -{ - 0xB6, 0xC3, 0xAA, 0xBB, 0xCC, 0xDD, - 0x02, 0x00, 0x08, 0x00, 0x28, 0x00, 0x2c, 0x00, - 0x34, 0x00, 0x3c, 0x00, 0x40, 0x00, 0x48, 0x00, - 0x54, 0x00, 0x58, 0x00, 0x5e, 0x00, 0x64, 0x00, - 0x68, 0x00, 0x6e, 0x00, 0x6c, 0x00, 0x72, 0x00, - 0x76, 0x00, 0x7c, 0x00, 0x80, 0x00, 0x86, 0x00, - 0x8a, 0x00, 0x90, 0x00, 0x94, 0x00, 0x98, 0x00, - 0x9e, 0x00, 0xa6, 0x00, 0xaa, 0x00, 0xb0, 0x00, - 0xb4, 0x00, 0xb8, 0x00, 0xc0, 0x00, 0xc6, 0x00, - 0xca, 0x00, 0xd0, 0x00, 0xd4, 0x00, 0xd8, 0x00, - 0xe0, 0x00, 0xde, 0x00, 0xe8, 0x00, 0xf0, 0x00, - 0xfc, 0x00, 0x04, 0x01, 0x0a, 0x01, 0x18, 0x01, - 0x22, 0x01, 0x28, 0x01, 0x3a, 0x01, 0x3e, 0x01, - 0x7e, 0x01, 0x98, 0x01, 0x9c, 0x01, 0xa2, 0x01, - 0xac, 0x01, 0xb2, 0x01, 0xba, 0x01, 0xc0, 0x01, - 0xc8, 0x01, 0xd0, 0x01, 0xd6, 0x01, 0xf4, 0x01, - 0xfc, 0x01, 0x08, 0x02, 0x16, 0x02, 0x1a, 0x02, - 0x22, 0x02, 0x2a, 0x02, 0x2e, 0x02, 0x3e, 0x02, - 0x44, 0x02, 0x4a, 0x02, 0x50, 0x02, 0x64, 0x02, - 0x62, 0x02, 0x6c, 0x02, 0x72, 0x02, 0x86, 0x02, - 0x8c, 0x02, 0x90, 0x02, 0x9e, 0x02, 0xbc, 0x02, - 0xd0, 0x02, 0xd8, 0x02, 0xdc, 0x02, 0xe0, 0x02, - 0xe8, 0x02, 0xe6, 0x02, 0xf4, 0x02, 0xfe, 0x02, - 0x04, 0x03, 0x0c, 0x03, 0x28, 0x03, 0x7c, 0x03, - 0x90, 0x03, 0x94, 0x03, 0x9c, 0x03, 0xa2, 0x03, - 0xc0, 0x03, 0xd0, 0x03, 0xd4, 0x03, 0xee, 0x03, - 0xfa, 0x03, 0xfe, 0x03, 0x2e, 0x04, 0x32, 0x04, - 0x3c, 0x04, 0x40, 0x04, 0x4e, 0x04, 0x76, 0x04, - 0x7c, 0x04, 0x84, 0x04, 0x8a, 0x04, 0x8e, 0x04, - 0xa6, 0x04, 0xb0, 0x04, 0xb8, 0x04, 0xbe, 0x04, - 0xd2, 0x04, 0xdc, 0x04, 0xee, 0x04, 0x10, 0x05, - 0x1a, 0x05, 0x24, 0x05, 0x2a, 0x05, 0x36, 0x05, - 0x34, 0x05, 0x3c, 0x05, 0x42, 0x05, 0x64, 0x05, - 0x6a, 0x05, 0x6e, 0x05, 0x86, 0x05, 0x22, 0x06, - 0x26, 0x06, 0x2c, 0x06, 0x30, 0x06, 0x42, 0x06, - 0x4a, 0x06, 0x4e, 0x06, 0x56, 0x06, 0x54, 0x06, - 0x5a, 0x06, 0x60, 0x06, 0x66, 0x06, 0xe8, 0x06, - 0xee, 0x06, 0xf4, 0x06, 0x16, 0x07, 0x26, 0x07, - 0x2c, 0x07, 0x32, 0x07, 0x36, 0x07, 0x3a, 0x07, - 0x3e, 0x07, 0x52, 0x07, 0x56, 0x07, 0x5a, 0x07, - 0x64, 0x07, 0x76, 0x07, 0x7a, 0x07, 0x80, 0x07, - 0x84, 0x07, 0x8a, 0x07, 0x9e, 0x07, 0xa2, 0x07, - 0xda, 0x07, 0xde, 0x07, 0xe2, 0x07, 0xe6, 0x07, - 0xea, 0x07, 0xee, 0x07, 0xf2, 0x07, 0xf6, 0x07, - 0x0e, 0x08, 0x16, 0x08, 0x18, 0x08, 0x1a, 0x08, - 0x1c, 0x08, 0x1e, 0x08, 0x20, 0x08, 0x22, 0x08, - 0x24, 0x08, 0x26, 0x08, 0x28, 0x08, 0x2a, 0x08, - 0x2c, 0x08, 0x2e, 0x08, 0x32, 0x08, 0x3a, 0x08, - 0x46, 0x08, 0x4e, 0x08, 0x54, 0x08, 0x5e, 0x08, - 0x78, 0x08, 0x7e, 0x08, 0x82, 0x08, 0x86, 0x08, - 0x8c, 0x08, 0x90, 0x08, 0x98, 0x08, 0x9e, 0x08, - 0xa4, 0x08, 0xaa, 0x08, 0xb0, 0x08, 0xae, 0x08, - 0xb4, 0x08, 0xbe, 0x08, 0xc4, 0x08, 0xc2, 0x08, - 0xca, 0x08, 0xc8, 0x08, 0xd4, 0x08, 0xe4, 0x08, - 0xe8, 0x08, 0xf6, 0x08, 0x14, 0x09, 0x12, 0x09, - 0x1a, 0x09, 0x20, 0x09, 0x26, 0x09, 0x24, 0x09, - 0x2a, 0x09, 0x3e, 0x09, 0x4c, 0x09, 0x56, 0x09, - 0x70, 0x09, 0x74, 0x09, 0x78, 0x09, 0x7e, 0x09, - 0x7c, 0x09, 0x82, 0x09, 0x98, 0x09, 0x9c, 0x09, - 0xa0, 0x09, 0xa6, 0x09, 0xb8, 0x09, 0xdc, 0x09, - 0xe8, 0x09, 0xec, 0x09, 0xfc, 0x09, 0x12, 0x0a, - 0x18, 0x0a, 0x1e, 0x0a, 0x42, 0x0a, 0x46, 0x0a, - 0x4e, 0x0a, 0x54, 0x0a, 0x5a, 0x0a, 0x5e, 0x0a, - 0x68, 0x0a, 0x6e, 0x0a, 0x72, 0x0a, 0x78, 0x0a, - 0x76, 0x0a, 0x7c, 0x0a, 0x80, 0x0a, 0x84, 0x0a, - 0x94, 0x0a, 0xa4, 0x0a, 0xb8, 0x0a, 0xbe, 0x0a, - 0xbc, 0x0a, 0xc2, 0x0a, 0xc8, 0x0a, 0xc6, 0x0a, - 0xcc, 0x0a, 0xd0, 0x0a, 0xd4, 0x0a, 0xd8, 0x0a, - 0xdc, 0x0a, 0xe0, 0x0a, 0xf2, 0x0a, 0xf6, 0x0a, - 0xfa, 0x0a, 0x14, 0x0b, 0x1a, 0x0b, 0x20, 0x0b, - 0x1e, 0x0b, 0x26, 0x0b, 0x2e, 0x0b, 0x2c, 0x0b, - 0x36, 0x0b, 0x3c, 0x0b, 0x42, 0x0b, 0x40, 0x0b, - 0x4a, 0x0b, 0xaa, 0x0b, 0xb0, 0x0b, 0xb6, 0x0b, - 0xc0, 0x0b, 0xc8, 0x0b, 0xda, 0x0b, 0xe8, 0x0b, - 0xec, 0x0b, 0xfa, 0x0b, 0x4a, 0x0c, 0x54, 0x0c, - 0x62, 0x0c, 0x66, 0x0c, 0x96, 0x0c, 0x9a, 0x0c, - 0xa0, 0x0c, 0xa6, 0x0c, 0xa4, 0x0c, 0xac, 0x0c, - 0xb2, 0x0c, 0xb0, 0x0c, 0xc0, 0x0c, - 0x00, 0x00 -}; - - -static const int len_kaweth_trigger_code = sizeof(kaweth_trigger_code); -static const int len_kaweth_trigger_code_fix = sizeof(kaweth_trigger_code_fix); -static const int len_kaweth_new_code = sizeof(kaweth_new_code); -static const int len_kaweth_new_code_fix = sizeof(kaweth_new_code_fix); diff --git a/firmware/Makefile b/firmware/Makefile index 7a8fa9e..40939e9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -26,6 +26,9 @@ fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ yamaha/ds1e_ctrl.fw +fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ + kaweth/new_code_fix.bin \ + kaweth/trigger_code_fix.bin fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index a8fc4b6..1373f529 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -57,3 +57,16 @@ Original licence info: * expressed or implied about its fitness for any purpose. -------------------------------------------------------------------------- + +Driver: kaweth -- USB KLSI KL5USB101-based Ethernet device + +File: kaweth/new_code.bin +File: kaweth/new_code_fix.bin +File: kaweth/trigger_code.bin +File: kaweth/trigger_code_fix.bin + +Licence: Unknown + +Found in hex form in the kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/kaweth/new_code.bin.ihex b/firmware/kaweth/new_code.bin.ihex new file mode 100644 index 0000000..292d40f --- /dev/null +++ b/firmware/kaweth/new_code.bin.ihex @@ -0,0 +1,206 @@ +:10000000B6C3AABBCCDD9FCFDE06E7570000C4060F +:1000100097C1E767FF1F28C0E787000424C0E76790 +:10002000FFF922C097CFD70900C0E709A2C0BE06DA +:100030009FAF3600E70500C0A7CFBC0697CFE757B4 +:100040000000B806A7A1B80697CFE757000014082C +:100050000AC0E7570000A4C0A7C07A069FAF920766 +:10006000E70700001408E757FFFFBA069FA0380013 +:10007000E759BA06BE069FA03800C809CA0608623A +:100080009FA13608C00976060060A7C07A069FAF18 +:10009000CC02E7570000B806A7C17A069FAF04005C +:1000A000E75700008E060AC1E70920C01008E7D014 +:1000B0001008E767400010089FAF920CC009D006F7 +:1000C000006005C4C059BE0602C09FAFEC009FAFE0 +:1000D0003402E7570000A6069FA07A02A7CF7A064F +:1000E0004802E709BE06D006C83704009FAF0803E0 +:1000F00097CFE7570000CE0697C0D70900C0C1DFF1 +:10010000C809C606086214C02704C6061094F00782 +:1001100010080200C107010070000400F007300160 +:10012000060050AFE707FFFFD006E7070000CE0646 +:10013000E70500C097CFD70900C0C1DF4802D0094A +:10014000C6062702C606E70500C097CF4802C83793 +:100150000400000C0C00006021C0C0373E0023C921 +:10016000C057B4051BC8C0173F00C067C0FF3000B0 +:100170000800F007000004000002C0174C00300027 +:100180000600F007A0010A004802C1070200D709D3 +:1001900000C0C1DF51AFE70500C097CF9FAF080394 +:1001A0009FAF7A0297CF9FAF7A02C9370400C1DFB1 +:1001B000C809A20650026702A206D107000027D88C +:1001C000AA06C0DF9FAFC40197CFE7570000D20651 +:1001D00097C1E7570100A80697C0C809A0060862A2 +:1001E00097C00002C0170E0027003401270C0C0036 +:1001F0003601E70750C312C0E707CC0B0200E70740 +:100200000100A806E707050090C097CFC809A4061B +:10021000086202C0106407C1E70700009E06E707F6 +:100220007204240097CF2704A406C8170E002702E3 +:100230009E06E7078004240097CFD70900C0C1DFDE +:10024000E7570000900613C19FAF0602E757000072 +:100250009E0613C0E7099E063001E707F20532014A +:10026000E707100096C0E7099E06900604CFE757FF +:1002700000009E0602C19FAF0602E70500C097CFAF +:10028000D70900C0C1DF0892E7570200AA0602C3DF +:10029000C809A4062702A606086203C1E70500C034 +:1002A00097CF2704A406E70500C0F0074000080028 +:1002B000F007000004000002C0170C003000060028 +:1002C000F00746010A00C8170400C107020051AF39 +:1002D00097CFE7570000960697C0C1DFC80996067A +:1002E000270496062752980603C1E7079606980644 +:1002F000C0DF1702C8170E009FAFBA03C805006021 +:1003000003C09FAF240397CF9FAF080397CF570237 +:10031000C907A406D70900C0C1DF08621BC050048A +:100320001102E70500C0C90597CF9702CA09D60692 +:10033000F21701000400F22700000600CA172C0083 +:10034000F87701000E0006C0CAD9F857FF000E006A +:1003500001C1CAD9221C0C00E2270000E2170100EB +:10036000E2270000CA05000C0C00C0174100C0675E +:10037000C0FF300008000002C0170C00300006006B +:10038000F007DA000A00F00700000400000C080083 +:1003900040D10100C019CE06C059C20604C949AFF8 +:1003A0009FAFEC004AAF6710CE06C8170400C10724 +:1003B0000100D70900C0C1DF50AFE70500C097CFEB +:1003C000C0070100C109AC06C177010097C1D87709 +:1003D000010012C0C9076A069FAF080404C1C177B3 +:1003E000080013C097CFC177020097C1C1771000F2 +:1003F0000CC09FAF2C0497CFC177040006C0C9077B +:1004000070069FAF080497C000CF009097CF50545C +:1004100097C1705C0200020097C1705C0400040088 +:1004200097CF8001C0006000300018000C0006006B +:100430000000CB09B206CC09B4060B5311C0C902A7 +:10044000CA071C049FAF080497C00AC882080ACFD5 +:1004500082089FAF080497C005C28930826078C1C6 +:10046000009097CF8910095379C2893082087ACFDA +:10047000C0DF97CFC0DF97CFE70996C09206E709A4 +:1004800098C094060FCFE70996C09206E70998C076 +:100490009406E7099E063001E707F2053201E707F7 +:1004A000100096C0D70900C01702C8099006C837C7 +:1004B0000E00E7772A00920630C09702CA09D606D6 +:1004C000E777200092060EC0F21701001000F22715 +:1004D00000001200E7770A009206CA051EC09702C4 +:1004E000CA09D606F21701000C00F22700000E0020 +:1004F000E7770200920607C0F21701004400F227D6 +:100500000000460006CFF21701006000F22700004D +:100510006200CA059FAF08030FCF57020902F10915 +:1005200094060C00F1DA0C00C80998065002670224 +:100530009806D1070000C905E7099E069006E7570F +:100540000000900602C09FAF0602C805E70500C084 +:10055000C0DF97CFD70900C0170017029702C00964 +:1005600092C0E707040090C0CA09D606E70700005A +:10057000A806E7076A040200C077020008C0F21765 +:1005800001005000F227000052009FCF2406C077E0 +:10059000100006C0F21701005800F22700005A00B0 +:1005A000C077800006C0F21701007000F22700003B +:1005B0007200C07708001DC1F21701000800F22781 +:1005C00000000A00C077000206C0F21701006400B4 +:1005D000F22700006600C077400006C0F217010055 +:1005E0005C00F22700005E00C077010001C01BCF55 +:1005F0001ACFF21701000000F22700000200C8091C +:100600003401CA171400D877010005C0CAD9D857D9 +:10061000FF0001C0CAD9E21994C0E2270000E21726 +:100620000100E22700009FAF40069FAFC401E757DB +:100630000000D2069FA10E0ACA05C805C005E7053D +:1006400000C0C0DF97CFC809A006086297C0270482 +:10065000A0062752A20603C1E707A006A2069FAF85 +:100660000803E7570000AA0602C027DAAA0697CFB8 +:10067000FFFFFFFFFFFF0000000000000000000080 +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C00000000000000000003F00000000000000EB +:1006D000000000000000FFFF01000000000000001B +:1006E000FFFFFB13E7570080B20006C2E707EE0BDF +:1006F0001200E707340CB200E707C607F202C80988 +:10070000B400F80702000D00D7090EC0E70700008B +:100710000EC0C809DE00C8170900C907DA06C007FD +:100720000400680A00DA7DC1E709C0007C06E70919 +:10073000BE007806E7091000BC06C807D6079FAFC1 +:10074000AE079FAF000AC809DE00000E0F004190FF +:100750009FDE060044AF2700B2062700B40627003C +:10076000B606C007740044AF2700D6060800009004 +:10077000C1073A00200001DA7DC19FAFBA09C00766 +:10078000440048AF27007A069FAF960AE7070100AA +:10079000C006E7050EC097CF49AFE78743000EC0FC +:1007A000E707FFFFBE069FAFAE0AC007010060AFBC +:1007B0004AAF97CF00080908110800DA7CC197CF2B +:1007C0006704CC02C0DF5194B1AF0600C1DFC90994 +:1007D000CC02496275C1C0DFA7CFD6020E0024004B +:1007E000800422004E05D0000E0AAA003008BE0088 +:1007F0004A0A1000200004006E0402006A04060089 +:10080000000024C0040428C0FEFB1EC0000422C057 +:10081000FFF4C000900900000000FFFF56086008C8 +:10082000D008DA0800090409080932094209500908 +:1008300052095A095A092702CA0697CFE70700004A +:10084000CA060A0E0100CA570E009FC35A09CA37CA +:1008500000009FC25A090AD2B2CF1608C809DE00AA +:1008600007069FCF6C091702C809DE00000E0F00B3 +:1008700041909FDE0600C805305006009FC85A0907 +:10088000270C0200B006C009B2062700B406E7072D +:100890000000AE0627008006001C06002700B606F2 +:1008A00041906750B0060DC067007E06270C060019 +:1008B0008206E707BC088406C8077E06419051AF50 +:1008C00097CF9FAF480CE709B606B406E709B00614 +:1008D000AE0659AF97CF270C0200AC0659AF97CFA1 +:1008E000090C020009DA49D2C919D606C8077E06E2 +:1008F000E00700006002E0070400D007CC0848DBF6 +:10090000419050AF97CF59AF97CF59AF97CFF0578E +:100910000600060025C1E7077006800641906700C3 +:100920007E06270C06008206E7078C098406C807A6 +:100930007E06419051AF97CF070C0600C7570600BF +:100940000FC1C807700615CF000C020000DA40D1B5 +:100950002700C2061ECF1DCF270C0200CC0619CFE0 +:1009600027022001E70708002201E7071300B0C0B3 +:1009700097CF419067007E06E70182062702800636 +:10098000E7078C098406C8077E06C107008050AFC0 +:1009900097CF59AF97CF006005C0E7070000C406A6 +:1009A000A7CF7C069FAF000AE7070100C40649AF46 +:1009B000D70900C007AFE70500C04AAFA7CF7C0644 +:1009C000C007FE7F44AF4000C03700014190C037F0 +:1009D0000800DFDE5006C057100002C2C00710003A +:1009E00027009A0641909FDE400644AF27009C06F0 +:1009F000C0099A06419000D200D89FDE080044AF9B +:100A00002700C80697CFE787008428C0E767FFFB69 +:100A100024C097CFE7870100D206E7570000A80659 +:100A200097C19FAF000AE787000622C0E7070000D2 +:100A300090C0E767FEFF3EC0E70726000AC0E787D1 +:100A400001003EC0E707FFFFBE069FAF100B97CF28 +:100A50001700A7AF7806C00527007606E7870100D4 +:100A6000D2069FAF000AE7070C0040C09FAF100BF3 +:100A700000902700A6062700AA06E709B206B406DA +:100A80002700AE062700AC069FAFAE0AC0070000E5 +:100A90002700B2022700B40227008E06C007060016 +:100AA000C809DE00C8170300C9077006290A00DA62 +:100AB0007DC197CFD70900C0C1DF009027009606FF +:100AC000E707960698062700A006E707A006A206F5 +:100AD0002700A6062700900627009E06C8099C0648 +:100AE000C1099A06C907A40611020902C8174006DF +:100AF00001DA7AC15194C809C806C907C606C109F6 +:100B00009A0611020902C817080001DA7AC1519445 +:100B1000E70500C097CFE7570000760697C09FAF64 +:100B20000400E709BE06BA06E757FFFFBA0604C18C +:100B3000E707100BB80697CFE7173200BA06E7674A +:100B4000FF07BA06E707460BB80697CFE75700003E +:100B5000C00623C0E707040090C0E707008080C0FC +:100B6000E707000080C0E707008080C0C0070000E2 +:100B7000C0070000C0070000E707000080C0E707CB +:100B8000008080C0E707008040C0C0070000E70782 +:100B9000000040C0E707000080C0E707040090C0E5 +:100BA000E707000240C0E7070C0240C0E70700006B +:100BB000C006E7070000B806E7070000D206D7091D +:100BC00000C0C1DF9FAF3402E70500C09FAFC40182 +:100BD00097CFD70900C0170017029702E757000008 +:100BE000A80606C0C00992C0C07709029FC15C0573 +:100BF0009FCF3206D7090EC0E70700000EC09FAF97 +:100C0000020CE7050EC097CFD70900C01702C8092C +:100C1000B0C0E767FE7FB0C0C87700209FC164EB1B +:100C2000E7570000C8029FC180EBC899CA02C86795 +:100C300004009FC196EB9FCF4CEBE7070000A6C0D6 +:100C4000E709B0C0C802E7070300B0C097CFC009EA +:100C5000B006C037010097C9C909B2060200419029 +:100C60004802C91706009FAF08049FA2720C02DA5F +:100C700077C1416071C197CF170257024304210425 +:100C8000E00043042104E00043042104E000C10724 +:100C90000100C905C80597CFE70701008E06C80700 +:100CA0008606E70700008606E70710088806E707BC +:100CB00004008A06E707BC0C8C06C107038050AF0E +:0C0CC00097CFE70700008E0697CF0000DA +:00000001FF diff --git a/firmware/kaweth/new_code_fix.bin.ihex b/firmware/kaweth/new_code_fix.bin.ihex new file mode 100644 index 0000000..fb35d3d --- /dev/null +++ b/firmware/kaweth/new_code_fix.bin.ihex @@ -0,0 +1,40 @@ +:10000000B6C3AABBCCDD0200080028002C003400D7 +:100010003C0040004800540058005E006400680046 +:100020006E006C00720076007C00800086008A0002 +:100030009000940098009E00A600AA00B000B400B2 +:10004000B800C000C600CA00D000D400D800E0004C +:10005000DE00E800F000FC0004010A0118012201A2 +:1000600028013A013E017E0198019C01A201AC01E8 +:10007000B201BA01C001C801D001D601F401FC01EE +:10008000080216021A0222022A022E023E0244022C +:100090004A025002640262026C02720286028C0200 +:1000A00090029E02BC02D002D802DC02E002E8020A +:1000B000E602F402FE0204030C0328037C0390030F +:1000C00094039C03A203C003D003D403EE03FA03FA +:1000D000FE032E0432043C0440044E0476047C04E7 +:1000E00084048A048E04A604B004B804BE04D204B6 +:1000F000DC04EE0410051A0524052A05360534052E +:100100003C05420564056A056E058605220626063D +:100110002C06300642064A064E06560654065A0675 +:1001200060066606E806EE06F406160726072C07A4 +:10013000320736073A073E07520756075A07640741 +:1001400076077A07800784078A079E07A207DA07DF +:10015000DE07E207E607EA07EE07F207F6070E08F2 +:10016000160818081A081C081E0820082208240867 +:10017000260828082A082C082E0832083A084608BB +:100180004E0854085E0878087E08820886088C08A5 +:10019000900898089E08A408AA08B008AE08B408F9 +:1001A000BE08C408C208CA08C808D408E408E80899 +:1001B000F608140912091A092009260924092A092E +:1001C0003E094C0956097009740978097E097C09B1 +:1001D000820998099C09A009A609B809DC09E8095F +:1001E000EC09FC09120A180A1E0A420A460A4E0ABB +:1001F000540A5A0A5E0A680A6E0A720A780A760A6D +:100200007C0A800A840A940AA40AB80ABE0ABC0AB4 +:10021000C20AC80AC60ACC0AD00AD40AD80ADC0A1A +:10022000E00AF20AF60AFA0A140B1A0B200B1E0B4C +:10023000260B2E0B2C0B360B3C0B420B400B4A0BA8 +:10024000AA0BB00BB60BC00BC80BDA0BE80BEC0B10 +:10025000FA0B4A0C540C620C660C960C9A0CA00C0F +:0E026000A60CA40CAC0CB20CB00CC00C000030 +:00000001FF diff --git a/firmware/kaweth/trigger_code.bin.ihex b/firmware/kaweth/trigger_code.bin.ihex new file mode 100644 index 0000000..c3e1658 --- /dev/null +++ b/firmware/kaweth/trigger_code.bin.ihex @@ -0,0 +1,13 @@ +:10000000B6C3AABBCCDDC807A000F0075E0006009F +:10001000F0070A000800F00900000200E7073600B8 +:100020000000F00700000400E70750C310C0F0090B +:100030000EC00000E78701000EC097CFD70900C0AF +:100040001702C807A000E71750C310C030D804003B +:10005000305C08000400B0C00600C805E70500C019 +:10006000C0DF97CF49AFC007000060AF4AAF000CB8 +:100070000C0040D2001C0C0040D230000800F007F9 +:1000800000000400F0078600060067CF270C02007E +:100090000000270C00000EC049AF64AFC00700008D +:1000A0004BAF4AAF5ACF0000000000000000000034 +:0600B000940005000000B1 +:00000001FF diff --git a/firmware/kaweth/trigger_code_fix.bin.ihex b/firmware/kaweth/trigger_code_fix.bin.ihex new file mode 100644 index 0000000..7712f73 --- /dev/null +++ b/firmware/kaweth/trigger_code_fix.bin.ihex @@ -0,0 +1,3 @@ +:10000000B6C3AABBCCDD0200060018003E0080008B +:060010009800AA000000A8 +:00000001FF -- cgit v0.10.2 From 0a2a736afa91e8a0402c9dbdaf2ee28481a50bd3 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 29 May 2008 19:50:06 +0300 Subject: ttusb-budget: use request_firmware() Signed-off-by: David Woodhouse Acked-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 5d2d81a..bc2043e 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "dmxdev.h" @@ -285,13 +286,19 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num return i; } -#include "dvb-ttusb-dspbootcode.h" - static int ttusb_boot_dsp(struct ttusb *ttusb) { + const struct firmware *fw; int i, err; u8 b[40]; + err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin", + &ttusb->dev->dev); + if (err) { + printk(KERN_ERR "ttusb-budget: failed to request firmware\n"); + return err; + } + /* BootBlock */ b[0] = 0xaa; b[2] = 0x13; @@ -299,8 +306,8 @@ static int ttusb_boot_dsp(struct ttusb *ttusb) /* upload dsp code in 32 byte steps (36 didn't work for me ...) */ /* 32 is max packet size, no messages should be splitted. */ - for (i = 0; i < sizeof(dsp_bootcode); i += 28) { - memcpy(&b[4], &dsp_bootcode[i], 28); + for (i = 0; i < fw->size; i += 28) { + memcpy(&b[4], &fw->data[i], 28); b[1] = ++ttusb->c; @@ -1820,3 +1827,4 @@ module_exit(ttusb_exit); MODULE_AUTHOR("Holger Waechtler "); MODULE_DESCRIPTION("TTUSB DVB Driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin"); diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h deleted file mode 100644 index 8c3cd54..0000000 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h +++ /dev/null @@ -1,1644 +0,0 @@ - -#include - -static u8 dsp_bootcode [] = { - 0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f, - 0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb, - 0x6b, 0xf8, 0x00, 0x18, 0x03, 0xff, 0x68, 0xf8, - 0x00, 0x18, 0xff, 0xfe, 0xf7, 0xb8, 0xf7, 0xbe, - 0xf6, 0xb9, 0xf4, 0xa0, 0xf6, 0xb7, 0xf6, 0xb5, - 0xf6, 0xb6, 0xf0, 0x20, 0x19, 0xdf, 0xf1, 0x00, - 0x00, 0x01, 0xf8, 0x4d, 0x01, 0xab, 0xf6, 0xb8, - 0xf0, 0x20, 0x19, 0xdf, 0xf0, 0x73, 0x01, 0xa5, - 0x7e, 0xf8, 0x00, 0x12, 0xf0, 0x00, 0x00, 0x01, - 0x47, 0xf8, 0x00, 0x11, 0x7e, 0x92, 0x00, 0xf8, - 0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x7e, 0xf8, - 0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x6c, 0x89, - 0x01, 0x9a, 0xf7, 0xb8, 0xee, 0xfc, 0xf0, 0x20, - 0xff, 0xff, 0xf1, 0x00, 0x00, 0x01, 0xf8, 0x4d, - 0x01, 0xbf, 0xf2, 0x73, 0x01, 0xb9, 0x4e, 0x02, - 0xf4, 0x95, 0xf5, 0xe3, 0x56, 0x02, 0x7e, 0x00, - 0x11, 0x00, 0xfa, 0x4c, 0x01, 0xb7, 0x6b, 0x03, - 0x00, 0x01, 0xf6, 0xb8, 0xee, 0x04, 0xf0, 0x74, - 0x0d, 0xa7, 0xf0, 0x74, 0x01, 0xc5, 0x4a, 0x11, - 0x4a, 0x16, 0x72, 0x11, 0x2a, 0xe6, 0x10, 0xf8, - 0x00, 0x11, 0xfa, 0x45, 0x01, 0xdb, 0xf4, 0x95, - 0xee, 0xff, 0x48, 0x11, 0xf0, 0x00, 0x2a, 0xc6, - 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0xee, - 0xff, 0xff, 0xf4, 0xe3, 0x6c, 0xe9, 0xff, 0xff, - 0x01, 0xd5, 0x10, 0xf8, 0x2a, 0xe7, 0xf8, 0x45, - 0x01, 0xe2, 0x10, 0xf8, 0x2a, 0xe7, 0xf4, 0xe3, - 0xf0, 0x74, 0x01, 0xff, 0xee, 0x01, 0x8a, 0x16, - 0x8a, 0x11, 0xfc, 0x00, 0xf7, 0xb8, 0xe9, 0x20, - 0x4a, 0x11, 0x09, 0xf8, 0x2a, 0xe6, 0xf8, 0x4e, - 0x01, 0xf3, 0xf2, 0x73, 0x01, 0xfd, 0xf4, 0x95, - 0xe8, 0x01, 0x72, 0x11, 0x2a, 0xe6, 0x49, 0x11, - 0x80, 0xe1, 0x2a, 0xc6, 0xf3, 0x00, 0x00, 0x01, - 0xe8, 0x00, 0x81, 0xf8, 0x2a, 0xe6, 0x8a, 0x11, - 0xfc, 0x00, 0xf4, 0x95, 0xf0, 0x73, 0x02, 0x00, - 0x10, 0xf8, 0x2a, 0x0f, 0xfc, 0x00, 0x4a, 0x11, - 0xf0, 0x74, 0x02, 0x02, 0x80, 0xf8, 0x2a, 0x10, - 0x73, 0x08, 0x00, 0x09, 0x40, 0xf8, 0x2a, 0x15, - 0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10, - 0x03, 0xe8, 0xf5, 0xa9, 0xf8, 0x30, 0x02, 0x21, - 0x71, 0xf8, 0x2a, 0x10, 0x2a, 0x15, 0x56, 0xf8, - 0x2a, 0x0c, 0xf0, 0xe3, 0x4e, 0xf8, 0x2a, 0x16, - 0xe8, 0x00, 0x4e, 0xf8, 0x2a, 0x0c, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, - 0x68, 0xf8, 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, - 0x00, 0x07, 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, - 0xff, 0xfc, 0x6b, 0xf8, 0x2a, 0x0f, 0x00, 0x01, - 0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x06, 0xf4, 0xeb, - 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x0f, 0x00, 0x00, - 0x76, 0x00, 0x00, 0x00, 0xfb, 0x80, 0x19, 0x4c, - 0xf4, 0x95, 0xe8, 0x00, 0x80, 0xf8, 0x2a, 0x11, - 0xf9, 0x80, 0x19, 0x07, 0x80, 0xf8, 0x2a, 0x0e, - 0xf9, 0x80, 0x16, 0x66, 0x76, 0x00, 0x2a, 0x12, - 0x10, 0xf8, 0x2a, 0x11, 0xf9, 0x80, 0x18, 0xe3, - 0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x66, - 0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x87, - 0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf6, 0xb8, - 0xf4, 0x95, 0xf0, 0x20, 0x80, 0x00, 0x11, 0xf8, - 0x2a, 0x5a, 0xf8, 0x4d, 0x02, 0x93, 0x11, 0xf8, - 0x2a, 0x9f, 0xf8, 0x4c, 0x02, 0x7c, 0x77, 0x12, - 0x2a, 0x39, 0x49, 0x12, 0x01, 0xf8, 0x2a, 0x9f, - 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81, - 0x00, 0x11, 0x6c, 0xe1, 0xff, 0xab, 0x02, 0x93, - 0x6b, 0xf8, 0x2a, 0x9f, 0x00, 0x01, 0xe9, 0x05, - 0x01, 0xe2, 0x00, 0x03, 0x81, 0xf8, 0x2a, 0xa0, - 0xf0, 0x73, 0x02, 0x95, 0x72, 0x11, 0x2a, 0x9f, - 0xf4, 0x95, 0x10, 0xe1, 0x2a, 0x39, 0x6b, 0xf8, - 0x2a, 0x9f, 0x00, 0x01, 0x11, 0xf8, 0x2a, 0x9f, - 0x09, 0xf8, 0x2a, 0xa0, 0xf8, 0x4c, 0x02, 0x93, - 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 0x76, 0xf8, - 0x2a, 0x9f, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa0, - 0x00, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x48, 0x11, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, - 0x10, 0xf8, 0x2a, 0x5a, 0xf8, 0x44, 0x02, 0xb2, - 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x01, 0xf0, 0x74, - 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, - 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 0x02, 0xb2, - 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 0x80, 0x00, - 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0xd6, - 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95, - 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b, - 0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11, - 0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15, - 0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19, - 0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a, - 0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8, - 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, - 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, - 0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe, - 0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xfd, - 0xf0, 0x74, 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, - 0x77, 0x10, 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, - 0x02, 0xef, 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, - 0x80, 0x00, 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, - 0x18, 0xd6, 0xee, 0x03, 0x8a, 0x18, 0xf4, 0x95, - 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 0x8a, 0x1a, - 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 0x8a, 0x19, - 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x15, - 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 0x8a, 0x11, - 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, - 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 0xf4, 0xeb, - 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, - 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, - 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, - 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, - 0x00, 0x03, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, - 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95, - 0xf4, 0x95, 0x10, 0x81, 0x6f, 0xf8, 0x2a, 0x9e, - 0x0c, 0x88, 0xe8, 0xff, 0x18, 0xe1, 0x00, 0x01, - 0x1a, 0xf8, 0x2a, 0x9e, 0xf0, 0x30, 0x1f, 0xff, - 0x80, 0xf8, 0x2a, 0x9e, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, - 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x11, 0xe2, - 0x00, 0x01, 0x81, 0xe1, 0x00, 0x01, 0x11, 0xe2, - 0x00, 0x02, 0x81, 0xe1, 0x00, 0x02, 0x76, 0xe1, - 0x00, 0x03, 0x00, 0x02, 0x48, 0x08, 0x6f, 0xe1, - 0x00, 0x04, 0x0c, 0x98, 0xf0, 0x30, 0x00, 0xff, - 0x80, 0xe1, 0x00, 0x05, 0x76, 0xe1, 0x00, 0x06, - 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, - 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, - 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, - 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, - 0x76, 0xe1, 0x00, 0x03, 0x00, 0x04, 0x48, 0x11, - 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 0xf4, 0x95, - 0x77, 0x13, 0x2a, 0x76, 0xe9, 0x00, 0xe5, 0x98, - 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 0x48, 0x0b, - 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x03, 0x71, - 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xf0, - 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81, - 0x00, 0x14, 0x71, 0xe1, 0x00, 0x01, 0x00, 0x15, - 0x49, 0x11, 0xf3, 0x00, 0x00, 0x02, 0x89, 0x11, - 0xe7, 0x82, 0x6d, 0xea, 0x00, 0x04, 0xe7, 0x83, - 0x6d, 0xeb, 0x00, 0x0a, 0x77, 0x1a, 0x00, 0x05, - 0xf0, 0x72, 0x03, 0xaa, 0x11, 0x81, 0xf2, 0xe8, - 0x80, 0x82, 0xe9, 0xff, 0x19, 0xe1, 0x00, 0x01, - 0xf1, 0xa0, 0x81, 0x92, 0x11, 0xe1, 0x00, 0x0c, - 0xf2, 0xe8, 0x80, 0x83, 0xe9, 0xff, 0x19, 0xe1, - 0x00, 0x0d, 0xf1, 0xa0, 0x81, 0x93, 0x6d, 0xe9, - 0x00, 0x02, 0x48, 0x18, 0x49, 0x18, 0x70, 0x00, - 0x00, 0x15, 0xf0, 0x00, 0x00, 0x04, 0xf3, 0x00, - 0x00, 0x0a, 0x80, 0x01, 0x81, 0x02, 0xf2, 0x74, - 0x0e, 0x54, 0xf4, 0x95, 0x48, 0x14, 0xee, 0x10, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf0, 0x74, - 0x0c, 0x5e, 0x80, 0xf8, 0x2a, 0x5c, 0x77, 0x12, - 0x2a, 0x39, 0x76, 0x82, 0x00, 0x55, 0x77, 0x11, - 0x2a, 0x18, 0x10, 0xe1, 0x00, 0x01, 0x80, 0xe2, - 0x00, 0x01, 0x10, 0xe1, 0x00, 0x02, 0x80, 0xe2, - 0x00, 0x02, 0x76, 0xe2, 0x00, 0x03, 0x00, 0x1c, - 0xf6, 0xb8, 0x56, 0xf8, 0x2a, 0x16, 0xf0, 0xf0, - 0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x07, 0x56, 0xf8, - 0x2a, 0x16, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80, - 0x80, 0xe2, 0x00, 0x06, 0x56, 0xf8, 0x2a, 0x16, - 0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, - 0x00, 0x05, 0x57, 0xf8, 0x2a, 0x16, 0xe8, 0xff, - 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x04, 0x56, 0xf8, - 0x27, 0x6c, 0xf0, 0xf0, 0xf0, 0xf8, 0x80, 0xe2, - 0x00, 0x0b, 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf0, - 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0a, - 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf8, 0xe8, 0xff, - 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x09, 0xe8, 0xff, - 0x57, 0xf8, 0x27, 0x6c, 0xf2, 0x80, 0x80, 0xe2, - 0x00, 0x08, 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0xf0, - 0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x0f, 0x56, 0xf8, - 0x27, 0x6a, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80, - 0x80, 0xe2, 0x00, 0x0e, 0x56, 0xf8, 0x27, 0x6a, - 0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, - 0x00, 0x0d, 0x57, 0xf8, 0x27, 0x6a, 0xe8, 0xff, - 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0c, 0x76, 0xe2, - 0x00, 0x13, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x12, - 0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x5c, 0x0c, 0x58, - 0x80, 0xe2, 0x00, 0x11, 0xe8, 0xff, 0x18, 0xf8, - 0x2a, 0x5c, 0x80, 0xe2, 0x00, 0x10, 0x76, 0xe2, - 0x00, 0x17, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x16, - 0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x9e, 0x0c, 0x58, - 0x80, 0xe2, 0x00, 0x15, 0xe8, 0xff, 0x18, 0xf8, - 0x2a, 0x9e, 0x80, 0xe2, 0x00, 0x14, 0x76, 0xe2, - 0x00, 0x1b, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1a, - 0x00, 0x00, 0x76, 0xe2, 0x00, 0x19, 0x00, 0x00, - 0x70, 0xe2, 0x00, 0x18, 0x27, 0x6e, 0x76, 0xe2, - 0x00, 0x1f, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1e, - 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1d, 0x00, 0x00, - 0x76, 0xe2, 0x00, 0x1c, 0x00, 0x00, 0x76, 0xe2, - 0x00, 0x20, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, - 0x10, 0xf8, 0x2a, 0x38, 0xf8, 0x45, 0x04, 0xed, - 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x02, - 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x08, - 0x6d, 0xe9, 0xff, 0xdf, 0xf6, 0xa9, 0xf8, 0x20, - 0x04, 0x75, 0xf0, 0x73, 0x04, 0x7d, 0xf0, 0x10, - 0x00, 0x21, 0xf0, 0x00, 0x1a, 0x83, 0x48, 0x08, - 0x7e, 0xf8, 0x00, 0x08, 0xf4, 0xe2, 0xf0, 0x74, - 0x03, 0x0a, 0xf0, 0x73, 0x04, 0xea, 0x48, 0x12, - 0xf2, 0x74, 0x03, 0x23, 0xf0, 0x00, 0x00, 0x04, - 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, - 0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, - 0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48, - 0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x69, - 0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36, - 0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, - 0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48, - 0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x41, - 0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36, - 0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0x57, - 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 0x2a, 0x1c, - 0xf0, 0x74, 0x12, 0xa4, 0xf2, 0x74, 0x03, 0x36, - 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, - 0x48, 0x12, 0xf2, 0x74, 0x03, 0x80, 0xf0, 0x00, - 0x00, 0x04, 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, - 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, - 0x2a, 0x1c, 0xf0, 0x74, 0x12, 0xc5, 0xf2, 0x74, - 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, - 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 0xe8, 0xff, - 0x6f, 0xe1, 0x00, 0x06, 0x0d, 0x48, 0x18, 0xe1, - 0x00, 0x07, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0xf2, 0xa0, 0x70, 0x00, 0x00, 0x12, 0x80, 0x01, - 0x10, 0xe1, 0x00, 0x04, 0xf0, 0x74, 0x0e, 0x7a, - 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, - 0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0xbc, - 0x76, 0xf8, 0x2a, 0x38, 0x00, 0x00, 0xee, 0x02, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, - 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, - 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, - 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, - 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x09, - 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, - 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x86, 0xe9, 0x00, - 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, - 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, - 0x05, 0x0a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, - 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, - 0x77, 0x13, 0x2a, 0x18, 0x10, 0xe3, 0x00, 0x01, - 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe3, 0x00, 0x02, - 0x80, 0xe1, 0x00, 0x02, 0x13, 0xe3, 0x00, 0x03, - 0x81, 0xe1, 0x00, 0x03, 0x48, 0x11, 0x77, 0x11, - 0x00, 0x00, 0xf8, 0x4d, 0x05, 0x44, 0xf0, 0x00, - 0x00, 0x04, 0x88, 0x12, 0x48, 0x13, 0xf0, 0x00, - 0x00, 0x04, 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, - 0xe5, 0x98, 0x6d, 0x91, 0xf6, 0xb8, 0x48, 0x11, - 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x05, 0x3a, - 0xf0, 0x20, 0x2a, 0x39, 0x49, 0x11, 0xf5, 0x00, - 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x76, 0xe1, - 0x00, 0x04, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, - 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, - 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, - 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, - 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x0c, - 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, - 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x7a, 0xe9, 0x00, - 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, - 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, - 0x05, 0x6a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, - 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, - 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, - 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, - 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, - 0x00, 0x19, 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, - 0x88, 0x12, 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x5d, - 0xe9, 0x00, 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, - 0xf6, 0xb8, 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, - 0xf8, 0x43, 0x05, 0x93, 0x76, 0x82, 0x00, 0xaa, - 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0x88, 0x11, 0x10, 0xf8, 0x2a, 0x38, - 0xf8, 0x44, 0x05, 0xe3, 0x10, 0xf8, 0x2a, 0xa1, - 0xf8, 0x44, 0x05, 0xba, 0x6c, 0xe1, 0xff, 0x56, - 0x05, 0xe3, 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, - 0x70, 0xe2, 0x2a, 0x18, 0x00, 0x11, 0x6b, 0xf8, - 0x2a, 0xa1, 0x00, 0x01, 0xf0, 0x73, 0x05, 0xe3, - 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 0x70, 0xe2, - 0x2a, 0x18, 0x00, 0x11, 0x10, 0xf8, 0x2a, 0xa1, - 0xf0, 0x00, 0x00, 0x01, 0x88, 0x12, 0xf4, 0x95, - 0xf4, 0x95, 0x6e, 0xe2, 0xff, 0xfc, 0x05, 0xd1, - 0x73, 0x12, 0x2a, 0xa1, 0x48, 0x11, 0xf0, 0x00, - 0x00, 0x05, 0x80, 0xf8, 0x2a, 0xa2, 0x10, 0xf8, - 0x2a, 0xa1, 0x08, 0xf8, 0x2a, 0xa2, 0xf8, 0x44, - 0x05, 0xe3, 0x6c, 0xe1, 0xff, 0xab, 0x05, 0xdd, - 0x76, 0xf8, 0x2a, 0x38, 0x00, 0x01, 0x76, 0xf8, - 0x2a, 0xa1, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa2, - 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95, - 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b, - 0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11, - 0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15, - 0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19, - 0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a, - 0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8, - 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, - 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, - 0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe, - 0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xff, - 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0x04, - 0xf0, 0x74, 0x05, 0xa2, 0xee, 0x01, 0x8a, 0x18, - 0xf4, 0x95, 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, - 0x8a, 0x1a, 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, - 0x8a, 0x19, 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, - 0x8a, 0x15, 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, - 0x8a, 0x11, 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, - 0x8a, 0x0b, 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, - 0xf4, 0xeb, 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x38, - 0x00, 0x00, 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, - 0xe8, 0x01, 0x4e, 0x00, 0xfb, 0x80, 0x17, 0xd6, - 0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x2a, 0x5b, - 0x76, 0x00, 0x2a, 0x8f, 0xf9, 0x80, 0x16, 0xaa, - 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x5c, - 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x6f, - 0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1a, - 0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1a, - 0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1b, - 0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1b, - 0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, - 0x13, 0x02, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d, - 0x06, 0x6a, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, - 0xf4, 0x95, 0xf0, 0x72, 0x06, 0x69, 0x1c, 0x91, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, - 0x12, 0x03, 0x11, 0x02, 0xf8, 0x45, 0x06, 0x79, - 0xf0, 0x10, 0x00, 0x01, 0x88, 0x1a, 0xf4, 0x95, - 0xf0, 0x72, 0x06, 0x78, 0x81, 0x91, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, - 0x00, 0x11, 0x11, 0x03, 0x61, 0xf8, 0x00, 0x11, - 0x00, 0x01, 0xf8, 0x30, 0x06, 0x91, 0xf6, 0xb8, - 0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11, - 0xf3, 0xe8, 0xe8, 0xff, 0x18, 0x81, 0xf1, 0xa0, - 0x81, 0x81, 0xf0, 0x73, 0x06, 0x9d, 0xf6, 0xb8, - 0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11, - 0xf3, 0x30, 0x00, 0xff, 0xf0, 0x20, 0xff, 0x00, - 0x18, 0x81, 0xf1, 0xa0, 0x81, 0x81, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x11, 0x02, - 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, - 0x06, 0xb1, 0x49, 0x0b, 0xf6, 0x1f, 0x88, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf2, 0x73, - 0x06, 0xb8, 0xf0, 0x30, 0x00, 0xff, 0x49, 0x0b, - 0xf6, 0x1f, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, - 0x12, 0x81, 0xf4, 0x78, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x12, - 0x13, 0x03, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d, - 0x06, 0xcc, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, - 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xcb, 0x11, 0x92, - 0xf2, 0xc0, 0x81, 0x91, 0x8a, 0x11, 0xfc, 0x00, - 0x88, 0x12, 0x12, 0x02, 0x71, 0x01, 0x00, 0x13, - 0xf8, 0x45, 0x06, 0xdb, 0xf0, 0x10, 0x00, 0x01, - 0x88, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xda, - 0xe5, 0x98, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, - 0x88, 0x11, 0x11, 0x04, 0x10, 0x06, 0x71, 0x05, - 0x00, 0x12, 0x61, 0xf8, 0x00, 0x12, 0x00, 0x01, - 0xf8, 0x20, 0x06, 0xea, 0xf0, 0x00, 0x00, 0x01, - 0xf6, 0xb8, 0xf0, 0x00, 0x00, 0x01, 0x6f, 0xf8, - 0x00, 0x12, 0x0f, 0x1f, 0x48, 0x08, 0x81, 0x00, - 0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xba, - 0xf4, 0x95, 0x48, 0x11, 0xee, 0x02, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x88, 0x12, - 0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 0x00, 0x13, - 0x61, 0xf8, 0x00, 0x13, 0x00, 0x01, 0xf8, 0x20, - 0x07, 0x09, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, - 0x00, 0x01, 0x88, 0x11, 0xf6, 0xb8, 0x6f, 0xf8, - 0x00, 0x13, 0x0f, 0x1f, 0x81, 0x00, 0x48, 0x11, - 0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xce, - 0xf4, 0x95, 0x48, 0x12, 0x48, 0x11, 0xf0, 0x30, - 0xff, 0xfe, 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xfc, - 0xf4, 0x95, 0x80, 0x02, 0x71, 0x08, 0x00, 0x16, - 0x10, 0x09, 0x71, 0x0b, 0x00, 0x17, 0x80, 0x03, - 0x71, 0x0a, 0x00, 0x11, 0x48, 0x17, 0xf8, 0x45, - 0x07, 0x3f, 0x70, 0x00, 0x00, 0x11, 0x10, 0x03, - 0xf0, 0x74, 0x06, 0x9f, 0x80, 0x01, 0x70, 0x00, - 0x00, 0x16, 0x10, 0x02, 0xf0, 0x74, 0x06, 0x7b, - 0x6d, 0x91, 0x6d, 0x96, 0x6c, 0xef, 0xff, 0xff, - 0x07, 0x2f, 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, - 0x10, 0xf8, 0x2a, 0xe8, 0x08, 0xf8, 0x2a, 0xe9, - 0xf8, 0x45, 0x07, 0x64, 0x76, 0x00, 0x00, 0x01, - 0x62, 0xf8, 0x2a, 0xe9, 0x00, 0x5e, 0xf2, 0x74, - 0x12, 0x0b, 0xf0, 0x00, 0x30, 0x40, 0x72, 0x11, - 0x2a, 0xe9, 0x77, 0x10, 0x00, 0x0f, 0xf5, 0xa9, - 0xf8, 0x20, 0x07, 0x61, 0x6b, 0xf8, 0x2a, 0xe9, - 0x00, 0x01, 0xf0, 0x73, 0x07, 0x64, 0x76, 0xf8, - 0x2a, 0xe9, 0x00, 0x00, 0xee, 0x02, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xe8, 0x00, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x08, 0xe8, 0x00, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x09, 0xf6, 0xb8, - 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 0x75, 0xf8, - 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 0x0c, 0x30, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 0x76, 0xf8, - 0x2a, 0xe8, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xe9, - 0x00, 0x00, 0x6c, 0x81, 0x07, 0x92, 0x76, 0xf8, - 0x2a, 0xea, 0x00, 0x00, 0xfb, 0x80, 0x16, 0x76, - 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 0x75, 0xf8, - 0x00, 0x08, 0x00, 0x00, 0xf0, 0x73, 0x07, 0xa8, - 0x76, 0xf8, 0x2a, 0xea, 0x00, 0x01, 0xfb, 0x80, - 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x10, 0xfb, 0x80, - 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0xf6, 0xb8, - 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 0x75, 0xf8, - 0x00, 0x08, 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, - 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, - 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, - 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, - 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, - 0x10, 0xf8, 0x2a, 0xea, 0xf8, 0x45, 0x07, 0xe1, - 0x10, 0xf8, 0x2a, 0xe8, 0xf0, 0x00, 0x00, 0x01, - 0xf0, 0x30, 0x00, 0x0f, 0x80, 0xf8, 0x2a, 0xe8, - 0x10, 0xf8, 0x2a, 0xe8, 0xf8, 0x44, 0x07, 0xd6, - 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, - 0x0c, 0x30, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, - 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, - 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x8a, 0x1d, - 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0a, 0x8a, 0x09, - 0x8a, 0x08, 0xf4, 0xeb, 0xee, 0xff, 0xf2, 0x74, - 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x01, 0xee, 0x01, - 0xfc, 0x00, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, - 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, - 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, - 0x8a, 0x1d, 0x8a, 0x07, 0xf4, 0xeb, 0x4a, 0x11, - 0x77, 0x11, 0x00, 0x28, 0x76, 0x81, 0x24, 0x00, - 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, - 0xf2, 0x74, 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x00, - 0x77, 0x11, 0x00, 0x1d, 0x68, 0x81, 0x00, 0x7f, - 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0x80, - 0x77, 0x11, 0x00, 0x1d, 0xf0, 0x30, 0x01, 0x00, - 0x1a, 0x81, 0x80, 0x81, 0xf0, 0x74, 0x0a, 0x33, - 0xf0, 0x74, 0x11, 0xac, 0xf9, 0x80, 0x13, 0x25, - 0xf9, 0x80, 0x16, 0x53, 0xf9, 0x80, 0x17, 0x82, - 0xf0, 0x74, 0x06, 0x2f, 0xf9, 0x80, 0x14, 0xb2, - 0xf9, 0x80, 0x19, 0x10, 0xf0, 0x74, 0x0d, 0xe3, - 0xf0, 0x74, 0x07, 0xe8, 0xf0, 0x74, 0x02, 0x36, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x60, 0xf8, - 0x27, 0x7b, 0xff, 0xff, 0xf8, 0x30, 0x08, 0x39, - 0x71, 0xf8, 0x27, 0x7b, 0x27, 0x79, 0x60, 0xf8, - 0x27, 0x79, 0xff, 0xff, 0xf8, 0x30, 0x08, 0xb2, - 0x10, 0xf8, 0x29, 0x86, 0x08, 0xf8, 0x27, 0x79, - 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 0xf4, 0x95, - 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x30, - 0x08, 0x58, 0x10, 0xf8, 0x27, 0x79, 0x08, 0xf8, - 0x27, 0x7a, 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, - 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, - 0xf8, 0x20, 0x08, 0x63, 0x76, 0xf8, 0x27, 0x79, - 0xff, 0xff, 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, - 0xf7, 0xb8, 0xf2, 0x73, 0x08, 0xd9, 0xf0, 0x20, - 0xff, 0xff, 0xf6, 0xb8, 0x56, 0xf8, 0x27, 0x74, - 0xf0, 0xf9, 0x88, 0x11, 0x56, 0xf8, 0x27, 0x72, - 0xf0, 0xf9, 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, - 0xe7, 0x20, 0xf4, 0xa9, 0xf8, 0x30, 0x08, 0x8f, - 0xf1, 0x20, 0x27, 0x7c, 0x48, 0x11, 0xf6, 0x00, - 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x83, - 0x08, 0xf8, 0x27, 0x79, 0xf0, 0x30, 0x7f, 0xff, - 0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, - 0xf5, 0xab, 0xf8, 0x30, 0x08, 0x8f, 0x6d, 0x91, - 0x48, 0x11, 0xf0, 0x30, 0x01, 0xff, 0x88, 0x11, - 0xf4, 0x95, 0xe7, 0x20, 0xf7, 0xa9, 0xf8, 0x30, - 0x08, 0x74, 0x6d, 0x89, 0x48, 0x11, 0xf0, 0x30, - 0x01, 0xff, 0xf0, 0xe7, 0xf4, 0x95, 0x48, 0x08, - 0x4e, 0xf8, 0x27, 0x74, 0x48, 0x08, 0xf1, 0xf9, - 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, - 0x27, 0x7c, 0x27, 0x7a, 0x60, 0xf8, 0x27, 0x7b, - 0xff, 0xff, 0xf8, 0x30, 0x08, 0xab, 0x48, 0x08, - 0x4e, 0xf8, 0x27, 0x72, 0x76, 0xf8, 0x27, 0x7b, - 0xff, 0xff, 0x76, 0xf8, 0x27, 0x79, 0xff, 0xff, - 0xf2, 0x73, 0x08, 0xd9, 0xf4, 0x95, 0xe8, 0x00, - 0x44, 0xf8, 0x27, 0x73, 0x40, 0xf8, 0x27, 0x75, - 0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10, - 0x80, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xd8, - 0xf6, 0xb8, 0x10, 0xf8, 0x27, 0x73, 0xf0, 0x00, - 0x80, 0x00, 0x48, 0x08, 0x4e, 0xf8, 0x27, 0x74, - 0x48, 0x08, 0xf0, 0xf9, 0x88, 0x11, 0xf4, 0x95, - 0xf4, 0x95, 0x71, 0xe1, 0x27, 0x7c, 0x27, 0x7a, - 0xf7, 0xb8, 0x57, 0xf8, 0x27, 0x74, 0xf0, 0x62, - 0xff, 0xff, 0xf0, 0x40, 0xff, 0x80, 0xf2, 0x80, - 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfb, - 0x11, 0xf8, 0x27, 0x71, 0x09, 0xf8, 0x27, 0x73, - 0x89, 0x11, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, - 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xed, 0xf2, 0x73, - 0x09, 0x0e, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0x20, - 0x76, 0x00, 0x00, 0x41, 0xf0, 0x74, 0x12, 0xee, - 0x88, 0x16, 0xf4, 0x95, 0xf7, 0xb8, 0x6d, 0x96, - 0x10, 0xf8, 0x00, 0x16, 0xf8, 0x47, 0x09, 0x0a, - 0xe7, 0x61, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, - 0x00, 0x80, 0x76, 0x02, 0x00, 0xff, 0x76, 0x03, - 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, - 0xe8, 0x00, 0x6c, 0xe9, 0xff, 0xff, 0x08, 0xfb, - 0x73, 0x16, 0x00, 0x0e, 0xf0, 0x66, 0x00, 0x41, - 0xee, 0x05, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x13, - 0xf6, 0xb8, 0x77, 0x11, 0x7f, 0xff, 0x57, 0xf8, - 0x27, 0x72, 0x48, 0x11, 0xf2, 0x80, 0xf0, 0x00, - 0x80, 0x00, 0x88, 0x11, 0xf6, 0x40, 0xf0, 0xe0, - 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 0x80, 0xf8, - 0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x57, 0xf8, - 0x27, 0x72, 0x48, 0x12, 0xf2, 0x80, 0x88, 0x12, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x09, 0x38, - 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, - 0xf0, 0x73, 0x09, 0x3d, 0xf0, 0x20, 0x80, 0x01, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x70, 0x81, - 0x00, 0x13, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0xf0, 0x30, 0x7f, 0xff, 0x11, 0xf8, 0x29, 0x86, - 0xf5, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11, - 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, - 0xf8, 0x20, 0x09, 0x54, 0xf2, 0x73, 0x09, 0x67, - 0xf4, 0x95, 0xe8, 0x02, 0x6f, 0xf8, 0x27, 0x7a, - 0x0d, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11, - 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, - 0xf8, 0x20, 0x09, 0x64, 0xf2, 0x73, 0x09, 0x67, - 0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x27, 0x7b, - 0xe8, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0x11, 0xf8, 0x29, 0x86, 0xf5, 0x20, 0xf3, 0x30, - 0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, - 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x7a, - 0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x02, - 0x6f, 0xf8, 0x27, 0x7a, 0x0d, 0x20, 0xf3, 0x30, - 0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, - 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x8a, - 0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x01, - 0x80, 0xf8, 0x27, 0x79, 0xe8, 0x00, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, - 0x00, 0x12, 0x88, 0x11, 0xf6, 0xb8, 0x57, 0xf8, - 0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80, - 0xf0, 0x00, 0x80, 0x00, 0x80, 0x81, 0x57, 0xf8, - 0x27, 0x72, 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, - 0x80, 0xf8, 0x27, 0x78, 0x77, 0x11, 0x80, 0x00, - 0x48, 0x11, 0x57, 0xf8, 0x27, 0x72, 0xf2, 0x80, - 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, - 0x09, 0xb5, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, - 0x00, 0x01, 0xf0, 0x73, 0x09, 0xba, 0xf0, 0x20, - 0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, - 0x45, 0xf8, 0x27, 0x71, 0x43, 0xf8, 0x27, 0x73, - 0x83, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0xe7, 0x20, - 0xf6, 0xa9, 0xf8, 0x30, 0x09, 0xc9, 0xf2, 0x73, - 0x09, 0xe4, 0x77, 0x12, 0x00, 0x00, 0x57, 0xf8, - 0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80, - 0x49, 0x12, 0xf5, 0x00, 0xf3, 0x00, 0x80, 0x00, - 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 0xf8, 0x30, - 0x09, 0xdc, 0xf1, 0x20, 0x80, 0x00, 0xf5, 0x20, - 0x89, 0x12, 0xf4, 0x95, 0x48, 0x12, 0x6f, 0xf8, - 0x27, 0x73, 0x0d, 0x00, 0xf4, 0x95, 0x49, 0x0b, - 0x4f, 0xf8, 0x27, 0x72, 0x8a, 0x11, 0xfe, 0x00, - 0x48, 0x12, 0xf4, 0x95, 0x4a, 0x11, 0x4a, 0x16, - 0x4a, 0x17, 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x08, - 0x00, 0x16, 0x88, 0x17, 0xf0, 0x74, 0x08, 0x30, - 0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74, - 0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0a, 0x0a, - 0xf2, 0x74, 0x08, 0xdb, 0xf4, 0x95, 0x48, 0x16, - 0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74, - 0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, - 0x10, 0x02, 0x70, 0x01, 0x00, 0x11, 0x80, 0x00, - 0xf2, 0x74, 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, - 0x49, 0x11, 0x48, 0x17, 0xf6, 0x00, 0x88, 0x17, - 0xe7, 0x60, 0xf5, 0xa9, 0xf8, 0x20, 0x0a, 0x2d, - 0x48, 0x16, 0xf6, 0x20, 0x88, 0x11, 0x48, 0x18, - 0x70, 0x00, 0x00, 0x11, 0xf2, 0x74, 0x09, 0x8f, - 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 0x70, 0x01, - 0x00, 0x11, 0x10, 0x02, 0x80, 0x00, 0xf2, 0x74, - 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 0xee, 0x04, - 0x48, 0x16, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, - 0xfc, 0x00, 0xee, 0xfd, 0xe8, 0x00, 0x4e, 0xf8, - 0x27, 0x70, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x72, - 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, - 0x4e, 0xf8, 0x27, 0x76, 0x76, 0xf8, 0x27, 0x79, - 0xff, 0xff, 0x76, 0xf8, 0x27, 0x7a, 0x00, 0x00, - 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 0x76, 0xf8, - 0x27, 0x78, 0x00, 0x00, 0xe8, 0x00, 0x75, 0xf8, - 0x00, 0x08, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, - 0x76, 0x01, 0x02, 0x00, 0xf2, 0x74, 0x12, 0xdc, - 0xf0, 0x20, 0x27, 0x7c, 0xee, 0x03, 0xfc, 0x00, - 0x4a, 0x11, 0xee, 0xfc, 0xf4, 0x95, 0x4e, 0x00, - 0x77, 0x12, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x12, - 0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x12, - 0xf0, 0xe0, 0xf1, 0xf1, 0x4f, 0x02, 0xe9, 0x01, - 0xf4, 0x95, 0x48, 0x0b, 0xf5, 0x40, 0x56, 0x02, - 0xf1, 0x80, 0x81, 0xf8, 0x27, 0x78, 0x77, 0x11, - 0x80, 0x00, 0x56, 0x00, 0x49, 0x11, 0xf1, 0x80, - 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, - 0x0a, 0x81, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, - 0x00, 0x01, 0xf0, 0x73, 0x0a, 0x86, 0xf0, 0x20, - 0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, - 0x10, 0x82, 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0xee, 0xfe, 0xf4, 0x95, 0x4e, 0x00, - 0x77, 0x11, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x11, - 0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x11, - 0xf0, 0xe0, 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, - 0x80, 0xf8, 0x27, 0x78, 0x56, 0x00, 0xf1, 0x20, - 0x80, 0x00, 0xf1, 0x80, 0xf4, 0x95, 0x49, 0x0b, - 0xf8, 0x4d, 0x0a, 0xab, 0xf0, 0x20, 0x80, 0x01, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf0, 0x73, - 0x0a, 0xaf, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, - 0x00, 0x01, 0xee, 0x02, 0x48, 0x11, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x12, 0x13, 0x02, - 0x77, 0x11, 0x00, 0x00, 0xf8, 0x4d, 0x0a, 0xcb, - 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 0xf4, 0x95, - 0xf0, 0x72, 0x0a, 0xca, 0x48, 0x11, 0x1c, 0xf8, - 0x29, 0x7e, 0x88, 0x11, 0x11, 0xf8, 0x29, 0x7e, - 0xf2, 0x00, 0x00, 0x01, 0x80, 0xf8, 0x29, 0x7e, - 0x81, 0x92, 0x48, 0x11, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x11, - 0x88, 0x12, 0xf6, 0xb8, 0xf0, 0x20, 0x7f, 0xff, - 0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0xf0, 0x00, - 0x80, 0x00, 0x80, 0x82, 0x57, 0xf8, 0x27, 0x70, - 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 0x80, 0xf8, - 0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x48, 0x12, - 0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0x88, 0x12, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x0a, 0xf4, - 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, - 0xf0, 0x73, 0x0a, 0xf9, 0xf0, 0x20, 0x80, 0x01, - 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x45, 0xf8, - 0x27, 0x75, 0xe7, 0x10, 0x43, 0xf8, 0x27, 0x71, - 0x83, 0xf8, 0x00, 0x12, 0x6d, 0xe8, 0x00, 0x04, - 0x6d, 0x8a, 0xf6, 0xaa, 0xf8, 0x30, 0x0b, 0x0a, - 0xf2, 0x73, 0x0b, 0x25, 0x77, 0x11, 0x00, 0x00, - 0x57, 0xf8, 0x27, 0x70, 0xf0, 0x20, 0x7f, 0xff, - 0xf2, 0x80, 0x49, 0x11, 0xf5, 0x00, 0xf3, 0x00, - 0x80, 0x00, 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, - 0xf8, 0x30, 0x0b, 0x1d, 0xf1, 0x20, 0x80, 0x00, - 0xf5, 0x20, 0x89, 0x11, 0xf4, 0x95, 0x48, 0x11, - 0x6f, 0xf8, 0x27, 0x71, 0x0d, 0x00, 0xf4, 0x95, - 0x49, 0x0b, 0x4f, 0xf8, 0x27, 0x70, 0x48, 0x11, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, - 0x4a, 0x17, 0xee, 0xf0, 0x88, 0x17, 0x10, 0x17, - 0x80, 0x05, 0x10, 0x16, 0x80, 0x06, 0x10, 0x15, - 0x80, 0x07, 0x71, 0x14, 0x00, 0x11, 0x10, 0x05, - 0xf0, 0x30, 0x00, 0x01, 0x88, 0x10, 0x10, 0x06, - 0xf0, 0x30, 0x00, 0x01, 0x80, 0x08, 0x49, 0x11, - 0x10, 0x05, 0xf6, 0x01, 0x80, 0x09, 0x10, 0x06, - 0x61, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf8, 0x20, - 0x0b, 0x4b, 0x10, 0x09, 0xf0, 0x00, 0x00, 0x01, - 0x80, 0x09, 0x71, 0x08, 0x00, 0x12, 0xf4, 0xaa, - 0xf8, 0x30, 0x0b, 0x54, 0x10, 0x09, 0xf0, 0x00, - 0x00, 0x01, 0x80, 0x09, 0x12, 0x09, 0x49, 0x11, - 0xf4, 0x7f, 0x80, 0x09, 0xf6, 0x20, 0x80, 0x0a, - 0x56, 0xf8, 0x27, 0x70, 0x4e, 0x0c, 0x10, 0x09, - 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, - 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 0xf4, 0x95, - 0xf4, 0x95, 0x6c, 0x86, 0x0b, 0x6d, 0xf2, 0x73, - 0x0c, 0x59, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0xb8, - 0xf4, 0x95, 0x56, 0x0c, 0xf0, 0xf9, 0x88, 0x12, - 0xf4, 0x95, 0xf4, 0x95, 0x70, 0xe2, 0x27, 0x7c, - 0x29, 0x86, 0xe8, 0x00, 0x80, 0x0e, 0x48, 0x11, - 0xf8, 0x45, 0x0b, 0xcc, 0x77, 0x10, 0x00, 0x01, - 0xf4, 0xa9, 0xf8, 0x30, 0x0b, 0x89, 0x6c, 0xe1, - 0xff, 0xfd, 0x0b, 0x8b, 0x10, 0xe7, 0x00, 0x02, - 0x80, 0x0e, 0xf0, 0x73, 0x0b, 0x8b, 0x10, 0x87, - 0x80, 0x0e, 0xe7, 0x10, 0xf5, 0xae, 0xf8, 0x20, - 0x0b, 0xb2, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, - 0x00, 0x16, 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, - 0x48, 0x17, 0x49, 0x16, 0xf6, 0x00, 0x88, 0x17, - 0x48, 0x11, 0xf6, 0x20, 0x88, 0x11, 0x10, 0x09, - 0xf6, 0x20, 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, - 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, - 0x10, 0x04, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, - 0x00, 0x11, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11, - 0x00, 0x04, 0x80, 0x04, 0xf0, 0x73, 0x0b, 0xbc, - 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 0x00, 0x11, - 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11, - 0x00, 0x04, 0x80, 0x04, 0x49, 0x11, 0x48, 0x16, - 0xf6, 0x20, 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, - 0x6c, 0x86, 0x0b, 0xcc, 0x10, 0x0a, 0x80, 0x00, - 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, - 0x00, 0x04, 0x88, 0x16, 0x12, 0x0a, 0xf8, 0x45, - 0x0c, 0x33, 0x71, 0x0a, 0x00, 0x10, 0xf4, 0xae, - 0xf8, 0x30, 0x0c, 0x1c, 0x48, 0x16, 0xf0, 0xe1, - 0x88, 0x11, 0x12, 0x08, 0xf8, 0x45, 0x0b, 0xdb, - 0x6d, 0x89, 0x12, 0x07, 0xf8, 0x45, 0x0b, 0xe9, - 0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11, - 0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74, - 0x06, 0xdc, 0xf0, 0x73, 0x0b, 0xef, 0x48, 0x11, - 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74, - 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e, - 0x10, 0x06, 0x49, 0x11, 0xf6, 0x00, 0x80, 0x06, - 0x10, 0x05, 0xf6, 0x20, 0x88, 0x11, 0xf0, 0x00, - 0x00, 0x01, 0x48, 0x08, 0x6f, 0x00, 0x0c, 0x9f, - 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, - 0x00, 0x04, 0x12, 0x07, 0xf8, 0x45, 0x0c, 0x11, - 0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11, - 0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74, - 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x17, 0x48, 0x11, - 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74, - 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e, - 0xf0, 0x73, 0x0c, 0x33, 0x12, 0x07, 0xf8, 0x45, - 0x0c, 0x2a, 0x10, 0x07, 0x80, 0x00, 0x10, 0x06, - 0x80, 0x01, 0x10, 0x05, 0x80, 0x02, 0x10, 0x04, - 0xf0, 0x74, 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x30, - 0x12, 0x05, 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, - 0xf0, 0x74, 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, - 0x81, 0x0e, 0x76, 0x00, 0x00, 0x01, 0x48, 0x18, - 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, - 0x71, 0x04, 0x00, 0x11, 0x70, 0x81, 0x29, 0x86, - 0x10, 0x0e, 0x1c, 0xf8, 0x29, 0x86, 0x80, 0x0e, - 0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 0xf2, 0x74, - 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x10, 0x0e, - 0x71, 0x04, 0x00, 0x11, 0x80, 0x81, 0x10, 0xf8, - 0x29, 0x86, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x30, - 0x7f, 0xff, 0x80, 0xf8, 0x29, 0x86, 0x10, 0x09, - 0xf0, 0x00, 0x00, 0x02, 0x80, 0x09, 0xee, 0x10, - 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, - 0x10, 0xf8, 0x27, 0x75, 0x08, 0xf8, 0x27, 0x71, - 0xf0, 0x10, 0x00, 0x01, 0x48, 0x08, 0xfc, 0x00, - 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xff, 0xf4, 0x95, - 0x71, 0x04, 0x00, 0x16, 0xf0, 0x00, 0x00, 0x01, - 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 0x6d, 0xee, - 0xff, 0xfd, 0x48, 0x16, 0xf8, 0x45, 0x0c, 0x99, - 0x56, 0xf8, 0x29, 0x7c, 0xf0, 0x74, 0x0a, 0x5a, - 0x88, 0x11, 0x10, 0xf8, 0x29, 0x7d, 0xf0, 0x00, - 0x00, 0x01, 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, - 0x10, 0xf8, 0x29, 0x82, 0xf0, 0x00, 0x00, 0x01, - 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xa9, - 0xfa, 0x30, 0x0c, 0x96, 0x80, 0xf8, 0x29, 0x82, - 0x56, 0xf8, 0x29, 0x80, 0xf0, 0x00, 0x00, 0x01, - 0x4e, 0xf8, 0x29, 0x80, 0x73, 0x11, 0x29, 0x82, - 0x6c, 0xee, 0xff, 0xff, 0x0c, 0x76, 0xee, 0x01, - 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0x76, 0xf8, 0x29, 0x84, 0x00, 0x00, 0x76, 0xf8, - 0x29, 0x85, 0x00, 0x01, 0xe8, 0x00, 0x4e, 0xf8, - 0x2a, 0x0c, 0x76, 0xf8, 0x29, 0x86, 0x00, 0x00, - 0x76, 0xf8, 0x29, 0x87, 0x00, 0x00, 0x77, 0x11, - 0x29, 0x88, 0x76, 0x81, 0xaa, 0xaa, 0x76, 0xe1, - 0x00, 0x01, 0xaa, 0xaa, 0x76, 0xe1, 0x00, 0x02, - 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x06, 0x00, 0x14, - 0x71, 0x07, 0x00, 0x13, 0x71, 0x08, 0x00, 0x12, - 0x71, 0x09, 0x00, 0x15, 0x77, 0x10, 0x00, 0xff, - 0xf4, 0xaa, 0xf8, 0x30, 0x0d, 0x44, 0x49, 0x13, - 0x53, 0xf8, 0x2a, 0x0c, 0x4f, 0xf8, 0x2a, 0x0c, - 0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d, - 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x01, - 0x71, 0xe1, 0x24, 0x00, 0x00, 0x11, 0xf4, 0xa9, - 0xf8, 0x30, 0x0d, 0x17, 0x77, 0x10, 0x00, 0x02, - 0xf4, 0xa9, 0xf8, 0x30, 0x0c, 0xec, 0x77, 0x11, - 0x29, 0x8a, 0x76, 0x81, 0x00, 0x00, 0xe8, 0x00, - 0x77, 0x14, 0x00, 0x00, 0x77, 0x13, 0x00, 0x00, - 0xf0, 0x73, 0x0d, 0x48, 0x6c, 0x83, 0x0c, 0xfa, - 0x77, 0x11, 0x29, 0x8a, 0x48, 0x12, 0xf0, 0xe8, - 0xf0, 0x40, 0x80, 0x00, 0x80, 0x81, 0xe8, 0x00, - 0x77, 0x14, 0x00, 0x00, 0xf0, 0x73, 0x0d, 0x48, - 0x49, 0x13, 0xf3, 0x40, 0x80, 0x00, 0x81, 0xf8, - 0x29, 0x8a, 0x61, 0xf8, 0x00, 0x15, 0x00, 0x01, - 0xf8, 0x20, 0x0d, 0x07, 0x69, 0xf8, 0x29, 0x8a, - 0x40, 0x00, 0x61, 0xf8, 0x00, 0x14, 0x00, 0x01, - 0xf8, 0x20, 0x0d, 0x0f, 0x69, 0xf8, 0x29, 0x8a, - 0x20, 0x00, 0x77, 0x11, 0x29, 0x8a, 0x49, 0x12, - 0xf3, 0xe8, 0x1b, 0x81, 0x81, 0x81, 0xf0, 0x73, - 0x0d, 0x48, 0x11, 0xf8, 0x29, 0x84, 0xf8, 0x4c, - 0x0d, 0x37, 0x77, 0x11, 0x29, 0x88, 0x76, 0x81, - 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 0xf3, 0x10, - 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 0x81, 0xe1, - 0x00, 0x01, 0x76, 0x00, 0x00, 0x02, 0x80, 0x01, - 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 0x00, 0x13, - 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0x48, 0x11, - 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 0xf0, 0x73, - 0x0d, 0x73, 0x76, 0x00, 0x00, 0x00, 0x80, 0x01, - 0x76, 0x02, 0x00, 0x00, 0x70, 0x03, 0x00, 0x13, - 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0xe8, 0x00, - 0xf0, 0x73, 0x0d, 0x73, 0x77, 0x11, 0x29, 0x8a, - 0x70, 0x81, 0x00, 0x13, 0x11, 0xf8, 0x29, 0x84, - 0xf8, 0x4c, 0x0d, 0x68, 0x77, 0x11, 0x29, 0x88, - 0x76, 0x81, 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, - 0xf3, 0x10, 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, - 0x81, 0xe1, 0x00, 0x01, 0x76, 0x00, 0x00, 0x03, - 0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, - 0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, - 0x48, 0x11, 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, - 0xf0, 0x73, 0x0d, 0x73, 0x76, 0x00, 0x00, 0x01, - 0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, - 0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, - 0x48, 0x11, 0x6b, 0xf8, 0x29, 0x84, 0xff, 0xff, - 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0xf5, 0x40, 0xf4, 0x95, 0x48, 0x0b, 0xf4, 0x78, - 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe1, - 0xff, 0xb9, 0x0d, 0x88, 0xf2, 0x73, 0x0d, 0xa5, - 0xf4, 0x95, 0xe8, 0x60, 0xf2, 0x00, 0x00, 0x06, - 0x61, 0xf8, 0x00, 0x11, 0x00, 0x20, 0xf8, 0x30, - 0x0d, 0x98, 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, - 0xf8, 0x20, 0x0d, 0xa3, 0xf2, 0x00, 0x00, 0x07, - 0xf0, 0x73, 0x0d, 0xa3, 0x61, 0xf8, 0x00, 0x0b, - 0x00, 0x01, 0xf8, 0x20, 0x0d, 0xa1, 0xf2, 0x73, - 0x0d, 0xa3, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, - 0x00, 0x02, 0x48, 0x08, 0xf4, 0x7f, 0x8a, 0x11, - 0xfc, 0x00, 0xee, 0xff, 0xf0, 0x74, 0x07, 0xfd, - 0xf0, 0x74, 0x07, 0x44, 0xf0, 0x74, 0x0d, 0xb4, - 0xf0, 0x74, 0x02, 0x05, 0xf0, 0x74, 0x04, 0x60, - 0xf0, 0x73, 0x0d, 0xaa, 0xee, 0xfd, 0x10, 0xf8, - 0x2a, 0xa3, 0xf8, 0x44, 0x0d, 0xcb, 0x10, 0xf8, - 0x2a, 0xa4, 0xf8, 0x45, 0x0d, 0xd7, 0x76, 0x00, - 0x02, 0x00, 0xf2, 0x74, 0x09, 0xe8, 0xf0, 0x20, - 0x22, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00, - 0x76, 0xf8, 0x2a, 0xa7, 0x00, 0x00, 0xf0, 0x73, - 0x0d, 0xd7, 0x76, 0x00, 0x02, 0x00, 0xf2, 0x74, - 0x09, 0xe8, 0xf0, 0x20, 0x20, 0x00, 0x76, 0xf8, - 0x2a, 0xa3, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa7, - 0x00, 0x01, 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, - 0xf0, 0x10, 0x3a, 0x98, 0xf8, 0x47, 0x0d, 0xe1, - 0x76, 0xf8, 0x27, 0x6e, 0x00, 0x00, 0xee, 0x03, - 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x77, 0x11, - 0x20, 0x00, 0x76, 0x00, 0xaa, 0xaa, 0x76, 0x01, - 0x02, 0x00, 0xf2, 0x74, 0x06, 0x6c, 0xf4, 0x95, - 0x48, 0x11, 0x76, 0x00, 0x55, 0x55, 0x76, 0x01, - 0x02, 0x00, 0x48, 0x11, 0xf2, 0x74, 0x06, 0x6c, - 0xf0, 0x00, 0x02, 0x00, 0x76, 0xf8, 0x2a, 0xa3, - 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00, - 0xe8, 0x00, 0x4e, 0x00, 0xfb, 0x80, 0x15, 0x3e, - 0xf4, 0x95, 0xe8, 0x04, 0x80, 0xf8, 0x2a, 0xa5, - 0x76, 0x00, 0x2a, 0xa8, 0xf9, 0x80, 0x14, 0x87, - 0x76, 0x00, 0x2a, 0xad, 0xfb, 0x80, 0x13, 0x62, - 0xf4, 0x95, 0xe8, 0x02, 0x10, 0xf8, 0x2a, 0xa5, - 0xf9, 0x80, 0x14, 0x63, 0xfb, 0x80, 0x16, 0x66, - 0xf4, 0x95, 0xe8, 0x1c, 0xfb, 0x80, 0x16, 0x87, - 0xf4, 0x95, 0xe8, 0x1c, 0xe8, 0x01, 0x4e, 0x00, - 0xfb, 0x80, 0x17, 0xd6, 0xf4, 0x95, 0xe8, 0x00, - 0x80, 0xf8, 0x2a, 0xa6, 0x76, 0x00, 0x2a, 0xb7, - 0xf9, 0x80, 0x16, 0xaa, 0x10, 0xf8, 0x2a, 0xa6, - 0xf9, 0x80, 0x17, 0x5c, 0x10, 0xf8, 0x2a, 0xa6, - 0xf9, 0x80, 0x17, 0x6f, 0xee, 0x02, 0x8a, 0x11, - 0xfc, 0x00, 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, - 0x4a, 0x0a, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, - 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, - 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, - 0x10, 0xf8, 0x2a, 0xa7, 0xf8, 0x44, 0x0e, 0x4b, - 0x76, 0xf8, 0x2a, 0xa3, 0x00, 0x01, 0xf0, 0x73, - 0x0e, 0x4e, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x01, - 0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x0a, 0x8a, 0x09, - 0x8a, 0x08, 0xf4, 0xeb, 0x4a, 0x11, 0x4a, 0x16, - 0x4a, 0x17, 0xee, 0xfe, 0x88, 0x0e, 0x71, 0x08, - 0x00, 0x16, 0x71, 0x06, 0x00, 0x17, 0x11, 0x07, - 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 0x25, 0xa0, - 0x88, 0x11, 0x76, 0x01, 0x00, 0x06, 0x81, 0x00, - 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 0x00, 0x01, - 0x76, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x16, - 0x48, 0x11, 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, - 0x00, 0x07, 0x70, 0x81, 0x00, 0x17, 0xee, 0x02, - 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, - 0x4a, 0x11, 0x88, 0x0e, 0x71, 0x02, 0x00, 0x12, - 0x11, 0x03, 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, - 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x70, 0x81, - 0x00, 0x12, 0x6e, 0xe2, 0xff, 0xfe, 0x0e, 0x8d, - 0xf4, 0x95, 0xe8, 0x00, 0xe8, 0x01, 0x80, 0xe1, - 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, - 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0c, - 0x00, 0x00, 0x81, 0xe1, 0x00, 0x01, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 0x88, 0x0e, - 0xf4, 0x95, 0xf1, 0x66, 0x00, 0x0d, 0xf3, 0x00, - 0x24, 0x00, 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, - 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, - 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, - 0x00, 0x00, 0x80, 0x02, 0x76, 0x03, 0x00, 0x00, - 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0xe8, 0x00, - 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0x88, 0x19, 0xf4, 0x95, 0x73, 0x19, 0x00, 0x0e, - 0xf1, 0x66, 0x00, 0x0d, 0xf2, 0x00, 0x24, 0x00, - 0x77, 0x15, 0x25, 0xa0, 0x77, 0x14, 0x00, 0x00, - 0x77, 0x1a, 0x00, 0x1f, 0xf0, 0x72, 0x0f, 0x14, - 0xf6, 0xb8, 0x49, 0x19, 0x09, 0x85, 0xf8, 0x4c, - 0x0f, 0x13, 0xf1, 0x00, 0x00, 0x05, 0x89, 0x11, - 0x49, 0x15, 0xf3, 0x00, 0x00, 0x01, 0x89, 0x13, - 0x49, 0x15, 0xf3, 0x00, 0x00, 0x07, 0x89, 0x12, - 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, - 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, - 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, - 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, - 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, - 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0f, 0x13, - 0x6d, 0x94, 0x6d, 0xed, 0x00, 0x0d, 0x48, 0x14, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, - 0x4a, 0x17, 0xee, 0xf8, 0x88, 0x17, 0x10, 0x0d, - 0x80, 0x04, 0x10, 0x0c, 0x80, 0x05, 0x71, 0x0e, - 0x00, 0x16, 0x73, 0x17, 0x00, 0x0e, 0xf0, 0x66, - 0x00, 0x0d, 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, - 0x10, 0xf8, 0x27, 0x63, 0xf8, 0x45, 0x0f, 0x32, - 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, - 0x10, 0xf8, 0x27, 0x60, 0xf8, 0x44, 0x0f, 0x3d, - 0x60, 0xe1, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x20, - 0x0f, 0x6d, 0xf0, 0x73, 0x11, 0x33, 0x10, 0x04, - 0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f, - 0x11, 0x04, 0xf3, 0x00, 0x00, 0x01, 0x81, 0x04, - 0x6d, 0x8e, 0x77, 0x10, 0x00, 0x01, 0x71, 0xe1, - 0x00, 0x02, 0x00, 0x12, 0xf4, 0xaa, 0xf8, 0x30, - 0x0f, 0x62, 0x77, 0x10, 0x00, 0x02, 0xf4, 0xaa, - 0xf8, 0x30, 0x0f, 0x6d, 0x45, 0xe1, 0x00, 0x0b, - 0x88, 0x10, 0x43, 0xe1, 0x00, 0x0c, 0x83, 0xf8, - 0x00, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xaa, - 0xf8, 0x30, 0x0f, 0x6d, 0xf0, 0x73, 0x0f, 0x96, - 0xf5, 0x00, 0x81, 0x04, 0x49, 0x16, 0xf5, 0x20, - 0x89, 0x16, 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x48, 0x16, - 0xf8, 0x45, 0x11, 0x33, 0xf7, 0xb8, 0x71, 0xe1, - 0x00, 0x02, 0x00, 0x12, 0x10, 0xf8, 0x00, 0x12, - 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x46, 0x0f, 0x8c, - 0x10, 0xf8, 0x00, 0x12, 0xf0, 0x10, 0x00, 0x03, - 0xf8, 0x45, 0x10, 0x16, 0x77, 0x10, 0x00, 0x01, - 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0x9c, 0x77, 0x10, - 0x00, 0x02, 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0xa8, - 0xf0, 0x73, 0x0f, 0x96, 0x77, 0x10, 0x00, 0x04, - 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xb7, 0x77, 0x10, - 0x00, 0x05, 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xbc, - 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, - 0xf0, 0x73, 0x11, 0x31, 0x76, 0xe1, 0x00, 0x0c, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0x02, 0x00, 0x02, 0x11, 0xe1, 0x00, 0x0c, - 0xe8, 0x03, 0xf6, 0x20, 0x89, 0x12, 0xf4, 0x95, - 0x77, 0x10, 0x00, 0x03, 0xf5, 0xaa, 0xf8, 0x30, - 0x0f, 0xb6, 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, - 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf5, 0xae, - 0xf8, 0x20, 0x0f, 0xbd, 0x48, 0x16, 0x80, 0x06, - 0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x03, - 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xc8, 0x6b, 0xf8, - 0x27, 0x6f, 0x00, 0x01, 0x12, 0x06, 0xf8, 0x45, - 0x10, 0x00, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00, - 0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02, - 0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74, - 0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06, - 0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04, - 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, - 0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04, - 0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, - 0x88, 0x16, 0x89, 0x13, 0xf4, 0x95, 0x77, 0x10, - 0x00, 0x03, 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xf5, - 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 0x77, 0x10, - 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, - 0xf6, 0xab, 0xf8, 0x20, 0x10, 0x00, 0x6b, 0xf8, - 0x27, 0x6f, 0x00, 0x01, 0x6c, 0xe2, 0xff, 0xfd, - 0x11, 0x31, 0xf6, 0xb8, 0x6f, 0xe1, 0x00, 0x05, - 0x0c, 0x48, 0x6f, 0xe1, 0x00, 0x06, 0x0c, 0x18, - 0xf0, 0x30, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x03, - 0x80, 0xe1, 0x00, 0x0b, 0x76, 0xe1, 0x00, 0x02, - 0x00, 0x03, 0x48, 0x16, 0xf8, 0x45, 0x11, 0x33, - 0x71, 0xe1, 0x00, 0x0c, 0x00, 0x12, 0x10, 0xe1, - 0x00, 0x0b, 0x49, 0x12, 0xf6, 0x20, 0x88, 0x13, - 0xe8, 0x0c, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95, - 0xf4, 0x95, 0xf5, 0xab, 0xf8, 0x20, 0x10, 0x27, - 0x48, 0x13, 0x80, 0x06, 0x88, 0x10, 0xf4, 0x95, - 0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0x30, - 0x70, 0x06, 0x00, 0x16, 0x12, 0x06, 0xf8, 0x45, - 0x10, 0x5f, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00, - 0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02, - 0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74, - 0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06, - 0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04, - 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, - 0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04, - 0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, - 0x88, 0x16, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x0c, - 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 0xf6, 0xab, - 0xf8, 0x20, 0x10, 0x5f, 0x6b, 0xf8, 0x27, 0x6f, - 0x00, 0x01, 0x77, 0x10, 0x00, 0x0c, 0xf6, 0xaa, - 0xf8, 0x20, 0x10, 0x6b, 0xf2, 0x74, 0x0e, 0x9f, - 0xf4, 0x95, 0x48, 0x17, 0x71, 0xe1, 0x00, 0x0c, - 0x00, 0x12, 0x77, 0x10, 0x00, 0x0c, 0xf4, 0xaa, - 0xf8, 0x30, 0x10, 0x7c, 0x77, 0x10, 0x00, 0x0c, - 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x13, 0xf6, 0xab, - 0xf8, 0x30, 0x10, 0xb4, 0xe7, 0x30, 0xf7, 0xaa, - 0xf8, 0x30, 0x10, 0xb4, 0xf2, 0x74, 0x0e, 0xc1, - 0xf4, 0x95, 0x48, 0x17, 0x88, 0x12, 0xf4, 0x95, - 0xf4, 0x95, 0x6c, 0x82, 0x10, 0x8d, 0x76, 0xe1, - 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, - 0x00, 0x05, 0xf0, 0x73, 0x10, 0xb4, 0x76, 0xe1, - 0x00, 0x02, 0x00, 0x04, 0x77, 0x10, 0x00, 0x0c, - 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf5, 0xaa, - 0xf8, 0x20, 0x10, 0x9a, 0xf0, 0x73, 0x10, 0x9c, - 0x77, 0x12, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x00, - 0x70, 0x01, 0x00, 0x12, 0x70, 0x02, 0x00, 0x17, - 0x76, 0x03, 0x00, 0x01, 0x48, 0x11, 0xf2, 0x74, - 0x0c, 0xb9, 0xf0, 0x00, 0x00, 0x05, 0x76, 0xe1, - 0x00, 0x04, 0x00, 0x00, 0x77, 0x10, 0x00, 0x0c, - 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf6, 0xaa, - 0xf8, 0x20, 0x11, 0x1c, 0x48, 0x16, 0xf8, 0x45, - 0x11, 0x33, 0x60, 0xe1, 0x00, 0x02, 0x00, 0x05, - 0xf8, 0x20, 0x10, 0xdf, 0x10, 0xe1, 0x00, 0x0b, - 0x08, 0xe1, 0x00, 0x0c, 0x11, 0xe1, 0x00, 0x04, - 0xf8, 0x4d, 0x10, 0xc7, 0x6b, 0xf8, 0x27, 0x6f, - 0x00, 0x01, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, - 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xcf, 0x48, 0x16, - 0xf4, 0x95, 0x48, 0x08, 0xf8, 0x45, 0x11, 0x16, - 0x6f, 0xe1, 0x00, 0x0c, 0x0d, 0x00, 0x81, 0xe1, - 0x00, 0x0c, 0x11, 0x04, 0xf5, 0x00, 0x81, 0x04, - 0x49, 0x16, 0xf5, 0x20, 0x89, 0x16, 0xf0, 0x73, - 0x11, 0x0e, 0x10, 0xe1, 0x00, 0x0b, 0x71, 0xe1, - 0x00, 0x0c, 0x00, 0x12, 0x88, 0x10, 0xf4, 0x95, - 0xf4, 0x95, 0xf6, 0xaa, 0xf8, 0x30, 0x11, 0x16, - 0x49, 0x12, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95, - 0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xf3, - 0x48, 0x16, 0x80, 0x06, 0x48, 0x08, 0xf8, 0x45, - 0x11, 0x16, 0x10, 0x04, 0x70, 0x02, 0x00, 0x17, - 0x80, 0x00, 0x76, 0x03, 0x00, 0x00, 0x10, 0x06, - 0x80, 0x01, 0x10, 0x05, 0xf0, 0x74, 0x0c, 0xb9, - 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, - 0x00, 0x0c, 0x11, 0x06, 0x10, 0x04, 0xf6, 0x00, - 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 0x88, 0x16, - 0x10, 0xe1, 0x00, 0x0c, 0x08, 0xe1, 0x00, 0x0b, - 0xf8, 0x45, 0x11, 0x1c, 0xf0, 0x73, 0x11, 0x31, - 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, - 0xf0, 0x73, 0x11, 0x33, 0x76, 0xe1, 0x00, 0x0c, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x02, 0x00, 0x01, 0x10, 0x04, - 0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f, - 0x88, 0x12, 0xf4, 0x95, 0x77, 0x10, 0x00, 0xff, - 0xf4, 0xaa, 0xf8, 0x30, 0x11, 0x33, 0x6c, 0x86, - 0x0f, 0x70, 0xee, 0x08, 0x8a, 0x17, 0x8a, 0x16, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, - 0xf4, 0x95, 0x71, 0x06, 0x00, 0x12, 0x88, 0x11, - 0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d, - 0xf3, 0x00, 0x24, 0x00, 0x89, 0x14, 0x13, 0x81, - 0xf7, 0x7a, 0xf3, 0x30, 0x00, 0x01, 0x81, 0xf8, - 0x27, 0x60, 0x13, 0xe1, 0x00, 0x01, 0xf7, 0x7c, - 0xf3, 0x30, 0x00, 0x03, 0x81, 0xf8, 0x27, 0x61, - 0xe9, 0x0f, 0x19, 0xe1, 0x00, 0x01, 0x81, 0xf8, - 0x27, 0x62, 0x71, 0xe4, 0x00, 0x03, 0x00, 0x13, - 0xf6, 0xb8, 0x49, 0x13, 0xf3, 0x00, 0x00, 0x01, - 0xf3, 0x30, 0x00, 0x0f, 0x49, 0x0b, 0x09, 0xf8, - 0x27, 0x62, 0xf8, 0x4d, 0x11, 0x75, 0x77, 0x10, - 0x00, 0xff, 0xf4, 0xab, 0xf8, 0x30, 0x11, 0x75, - 0x57, 0xf8, 0x27, 0x6c, 0xf3, 0x00, 0x00, 0x01, - 0x4f, 0xf8, 0x27, 0x6c, 0x76, 0xf8, 0x27, 0x63, - 0x00, 0x01, 0xf0, 0x73, 0x11, 0x78, 0x76, 0xf8, - 0x27, 0x63, 0x00, 0x00, 0x70, 0xe4, 0x00, 0x03, - 0x27, 0x62, 0x76, 0xf8, 0x27, 0x64, 0x00, 0x00, - 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 0x00, 0x0b, - 0x00, 0x02, 0xf8, 0x20, 0x11, 0x8d, 0xe9, 0x01, - 0x6f, 0xe1, 0x00, 0x02, 0x0f, 0x18, 0x81, 0xf8, - 0x27, 0x64, 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, - 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 0x11, 0xa9, - 0x10, 0xf8, 0x27, 0x64, 0xf1, 0x00, 0x00, 0x04, - 0x89, 0x13, 0xe9, 0xb8, 0xf5, 0x20, 0x81, 0xf8, - 0x27, 0x65, 0x60, 0x84, 0x00, 0x02, 0xf8, 0x20, - 0x11, 0xa9, 0x70, 0x00, 0x00, 0x11, 0x70, 0x01, - 0x00, 0x13, 0x70, 0x02, 0x27, 0x65, 0xf2, 0x74, - 0x0f, 0x18, 0xf4, 0x95, 0x48, 0x12, 0xee, 0x04, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, - 0x4a, 0x17, 0xee, 0xfc, 0xe8, 0x00, 0x4e, 0xf8, - 0x27, 0x66, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x68, - 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x6c, 0xe8, 0x00, - 0x4e, 0xf8, 0x27, 0x6a, 0x77, 0x12, 0x27, 0x40, - 0x77, 0x11, 0x24, 0x00, 0x77, 0x1a, 0x00, 0x1f, - 0xf0, 0x72, 0x11, 0xdb, 0x70, 0x92, 0x00, 0x11, - 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 0x76, 0x81, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 0x76, 0xe1, - 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, - 0x6d, 0xe9, 0x00, 0x0d, 0xf0, 0x20, 0x25, 0xa0, - 0xf1, 0x00, 0x00, 0x07, 0x89, 0x11, 0xf1, 0x00, - 0x00, 0x01, 0x81, 0x02, 0x88, 0x16, 0xf4, 0x95, - 0x77, 0x17, 0x00, 0x20, 0x76, 0x86, 0x00, 0xff, - 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, - 0x10, 0x02, 0xf0, 0x74, 0x06, 0x6c, 0x76, 0x00, - 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74, - 0x06, 0x6c, 0xf4, 0x95, 0x48, 0x11, 0x10, 0x02, - 0xf0, 0x00, 0x00, 0x0d, 0x80, 0x02, 0x6d, 0xe9, - 0x00, 0x0d, 0x6d, 0xee, 0x00, 0x0d, 0x6c, 0xef, - 0xff, 0xff, 0x11, 0xe8, 0xf0, 0x74, 0x0c, 0x9d, - 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, - 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, - 0xee, 0xfa, 0x88, 0x11, 0x10, 0x0a, 0x49, 0x11, - 0xf8, 0x4d, 0x12, 0x9f, 0x48, 0x08, 0xf8, 0x45, - 0x12, 0x9f, 0x80, 0x04, 0x12, 0x81, 0xf5, 0x78, - 0x89, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe2, - 0xff, 0xb9, 0x12, 0x8a, 0x61, 0xf8, 0x00, 0x08, - 0x00, 0x80, 0xf8, 0x30, 0x12, 0x8a, 0x13, 0xe1, - 0x00, 0x01, 0xf0, 0xe8, 0xf7, 0x78, 0xf1, 0xa0, - 0xf2, 0x30, 0x1f, 0xff, 0x88, 0x17, 0xf4, 0x95, - 0x77, 0x12, 0x24, 0x00, 0x77, 0x16, 0x00, 0x00, - 0x77, 0x13, 0x00, 0x20, 0xf6, 0xb8, 0x48, 0x17, - 0x08, 0xe2, 0x00, 0x01, 0xf8, 0x45, 0x12, 0x42, - 0x6d, 0xea, 0x00, 0x0d, 0x6d, 0x96, 0x6c, 0xeb, - 0xff, 0xff, 0x12, 0x34, 0xf0, 0x73, 0x12, 0x90, - 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0x00, 0x00, 0x01, - 0x4e, 0xf8, 0x27, 0x6a, 0x60, 0x82, 0x00, 0x01, - 0xf8, 0x30, 0x12, 0x54, 0x70, 0x00, 0x00, 0x16, - 0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11, - 0xf0, 0x73, 0x12, 0x90, 0x70, 0x00, 0x00, 0x16, - 0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11, - 0x72, 0x10, 0x2a, 0x9e, 0xf4, 0x95, 0xf4, 0xaf, - 0xf8, 0x30, 0x12, 0x6e, 0x76, 0x00, 0x00, 0x00, - 0x76, 0x01, 0x00, 0xbc, 0x70, 0x02, 0x00, 0x16, - 0x76, 0x03, 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, - 0xf4, 0x95, 0x48, 0x11, 0xf0, 0x73, 0x12, 0x90, - 0x10, 0xf8, 0x27, 0x6e, 0xf8, 0x44, 0x12, 0x90, - 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0xbc, - 0x70, 0x02, 0x00, 0x16, 0x76, 0x03, 0x00, 0x00, - 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0x48, 0x11, - 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 0xf0, 0x10, - 0x13, 0x88, 0xf8, 0x42, 0x12, 0x90, 0x76, 0xf8, - 0x27, 0x6e, 0x00, 0x01, 0xf0, 0x73, 0x12, 0x90, - 0x56, 0xf8, 0x27, 0x66, 0xf0, 0x00, 0x00, 0x01, - 0x4e, 0xf8, 0x27, 0x66, 0x6d, 0xe9, 0x00, 0x5e, - 0x56, 0xf8, 0x27, 0x68, 0xf0, 0x00, 0x00, 0x01, - 0x4e, 0xf8, 0x27, 0x68, 0x71, 0x04, 0x00, 0x12, - 0x6e, 0xea, 0xff, 0xff, 0x12, 0x18, 0x70, 0x04, - 0x00, 0x12, 0xee, 0x06, 0x8a, 0x17, 0x8a, 0x16, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, - 0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d, - 0xf0, 0x00, 0x25, 0xa0, 0x88, 0x11, 0xf4, 0x95, - 0xf4, 0x95, 0x76, 0x81, 0x00, 0xff, 0x76, 0x00, - 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74, - 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x01, 0x76, 0x00, - 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0x48, 0x11, - 0xf2, 0x74, 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x07, - 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, - 0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d, - 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, - 0xf4, 0x95, 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, - 0x76, 0x81, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, - 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, - 0x13, 0x03, 0x88, 0x11, 0xfa, 0x4d, 0x12, 0xec, - 0x71, 0x02, 0x00, 0x12, 0xf3, 0x10, 0x00, 0x01, - 0x89, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x12, 0xeb, - 0x70, 0x91, 0x00, 0x12, 0x8a, 0x11, 0xfc, 0x00, - 0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d, - 0xf7, 0xb8, 0xee, 0xfe, 0x10, 0xf8, 0x00, 0x08, - 0x11, 0x06, 0xf1, 0xc0, 0x83, 0x00, 0xf4, 0x85, - 0x11, 0x06, 0xf7, 0x85, 0x81, 0x06, 0xf6, 0xb8, - 0xec, 0x0f, 0x1e, 0x06, 0x61, 0x00, 0x80, 0x00, - 0xf8, 0x20, 0x13, 0x05, 0xf4, 0x84, 0xee, 0x02, - 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, - 0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d, - 0xee, 0xfe, 0xf7, 0xb8, 0x80, 0x00, 0x10, 0xf8, - 0x00, 0x08, 0xf4, 0x85, 0x11, 0x06, 0xf7, 0x85, - 0x81, 0x06, 0xf6, 0xb8, 0xec, 0x0f, 0x1e, 0x06, - 0xf0, 0xf0, 0x61, 0x00, 0x80, 0x00, 0xf8, 0x20, - 0x13, 0x20, 0xf4, 0x84, 0xee, 0x02, 0x8a, 0x0d, - 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 0x4a, 0x11, - 0x77, 0x11, 0x00, 0x7b, 0x76, 0x81, 0x2e, 0xec, - 0x77, 0x11, 0x00, 0x7b, 0xee, 0xff, 0x71, 0x81, - 0x00, 0x11, 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0x62, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x76, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x92, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x94, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0xb0, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xb3, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0xbe, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0xbf, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0xc1, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc3, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc5, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0xc7, 0x00, 0x00, 0x76, 0x81, - 0x00, 0x00, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, - 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xff, - 0xf4, 0x95, 0x71, 0x06, 0x00, 0x16, 0xfb, 0x80, - 0x16, 0xa2, 0x88, 0x17, 0xf4, 0x95, 0xf7, 0xb8, - 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02, - 0xfa, 0x46, 0x13, 0x88, 0x77, 0x11, 0x00, 0x00, - 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02, - 0xf8, 0x45, 0x13, 0xf9, 0x10, 0xf8, 0x00, 0x17, - 0xf8, 0x45, 0x14, 0x39, 0x10, 0xf8, 0x00, 0x17, - 0xf0, 0x10, 0x00, 0x01, 0xf8, 0x45, 0x14, 0x1f, - 0xf0, 0x73, 0x14, 0x52, 0x10, 0xf8, 0x00, 0x17, - 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x45, 0x13, 0xd3, - 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x06, - 0xf8, 0x44, 0x14, 0x52, 0x77, 0x12, 0x00, 0x7b, - 0x71, 0x82, 0x00, 0x14, 0x61, 0xe4, 0x00, 0x07, - 0x00, 0x40, 0xf8, 0x30, 0x14, 0x52, 0x49, 0x14, - 0x48, 0x17, 0xf6, 0x00, 0x88, 0x12, 0xf4, 0x95, - 0x77, 0x13, 0x00, 0x55, 0x77, 0x11, 0x00, 0x57, - 0x6d, 0xea, 0x00, 0x3b, 0xe5, 0x01, 0x10, 0xe6, - 0x00, 0x06, 0x80, 0x81, 0x48, 0x14, 0x00, 0xf8, - 0x00, 0x17, 0x88, 0x12, 0xf4, 0x95, 0x77, 0x11, - 0x00, 0x55, 0x10, 0xe2, 0x00, 0x40, 0x80, 0x81, - 0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x07, - 0x80, 0x81, 0x77, 0x11, 0x00, 0x55, 0x10, 0xe2, - 0x00, 0x45, 0x80, 0x81, 0x10, 0xe6, 0x00, 0x08, - 0x77, 0x11, 0x00, 0x57, 0x80, 0x81, 0x77, 0x11, - 0x00, 0x55, 0x10, 0xe2, 0x00, 0x4a, 0x80, 0x81, - 0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x09, - 0x80, 0x81, 0xf2, 0x73, 0x14, 0x52, 0x77, 0x11, - 0x03, 0xc0, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82, - 0xf0, 0x00, 0x00, 0x07, 0x88, 0x13, 0xf4, 0x95, - 0xf4, 0x95, 0x96, 0x1b, 0xf8, 0x30, 0x14, 0x52, - 0x10, 0xe3, 0x00, 0x35, 0x77, 0x12, 0x00, 0x55, - 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, - 0x00, 0x04, 0x80, 0x82, 0x77, 0x12, 0x00, 0x55, - 0x10, 0xe3, 0x00, 0x37, 0x80, 0x82, 0x77, 0x12, - 0x00, 0x57, 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, - 0x48, 0x11, 0xf0, 0x40, 0x00, 0x10, 0xf2, 0x73, - 0x14, 0x50, 0xf0, 0x40, 0x00, 0x20, 0x77, 0x12, - 0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07, - 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0d, - 0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x34, - 0x77, 0x13, 0x00, 0x55, 0x80, 0x83, 0x77, 0x13, - 0x00, 0x57, 0x10, 0xe6, 0x00, 0x02, 0x80, 0x83, - 0x10, 0xe2, 0x00, 0x36, 0x77, 0x12, 0x00, 0x55, - 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, - 0x00, 0x03, 0x80, 0x82, 0x48, 0x11, 0xf0, 0x40, - 0x00, 0x04, 0xf2, 0x73, 0x14, 0x50, 0xf0, 0x40, - 0x00, 0x08, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82, - 0xf0, 0x00, 0x00, 0x07, 0x88, 0x12, 0xf4, 0x95, - 0xf4, 0x95, 0x96, 0x0e, 0xf8, 0x30, 0x14, 0x52, - 0x10, 0xe2, 0x00, 0x33, 0x77, 0x12, 0x00, 0x55, - 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, - 0x00, 0x01, 0x80, 0x82, 0x48, 0x11, 0xf2, 0x73, - 0x14, 0x50, 0xf0, 0x40, 0x00, 0x02, 0x77, 0x12, - 0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07, - 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0f, - 0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x32, - 0x77, 0x12, 0x00, 0x55, 0x77, 0x13, 0x00, 0x57, - 0x80, 0x82, 0x48, 0x11, 0xe7, 0x62, 0xf0, 0x40, - 0x00, 0x01, 0xe5, 0x01, 0x88, 0x11, 0xf4, 0x95, - 0x77, 0x12, 0x00, 0x7b, 0x48, 0x11, 0x71, 0x82, - 0x00, 0x12, 0x1a, 0xe2, 0x00, 0x07, 0x80, 0xe2, - 0x00, 0x07, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, - 0x8a, 0x17, 0x48, 0x11, 0x8a, 0x16, 0x8a, 0x11, - 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0x77, 0x0e, - 0x00, 0x05, 0x77, 0x12, 0x00, 0x55, 0xe8, 0x04, - 0xf6, 0xb8, 0x28, 0xe1, 0x00, 0x02, 0xee, 0xff, - 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0xf0, 0x20, - 0x80, 0x00, 0xee, 0x01, 0x1a, 0x82, 0x77, 0x12, - 0x00, 0x57, 0x80, 0x82, 0xe8, 0x01, 0x32, 0xe1, - 0x00, 0x02, 0xf5, 0x82, 0x77, 0x11, 0x00, 0x54, - 0xf6, 0x93, 0x18, 0x81, 0x77, 0x11, 0x00, 0x54, - 0xf2, 0xa0, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, - 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, - 0x71, 0x04, 0x00, 0x11, 0xfb, 0x80, 0x16, 0xa2, - 0x88, 0x16, 0xf4, 0x95, 0x77, 0x12, 0x00, 0x55, - 0x10, 0xe6, 0x00, 0x03, 0x80, 0x82, 0x77, 0x12, - 0x00, 0x56, 0x10, 0xe1, 0x00, 0x02, 0x77, 0x13, - 0x00, 0x56, 0x80, 0x82, 0x77, 0x12, 0x00, 0x56, - 0x10, 0xe1, 0x00, 0x03, 0x80, 0x82, 0x10, 0xe1, - 0x00, 0x04, 0x77, 0x12, 0x00, 0x56, 0x80, 0x82, - 0x77, 0x12, 0x00, 0x56, 0x10, 0xe1, 0x00, 0x01, - 0x80, 0x82, 0xe7, 0x12, 0xe5, 0x01, 0xf9, 0x80, - 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, - 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xf9, - 0x77, 0x11, 0x00, 0x7b, 0x76, 0x00, 0x00, 0x16, - 0x76, 0x01, 0x00, 0x17, 0x76, 0x02, 0x00, 0x1a, - 0x76, 0x03, 0x00, 0x1b, 0x76, 0x04, 0x00, 0x1c, - 0x76, 0x05, 0x00, 0x1d, 0x71, 0x81, 0x00, 0x17, - 0x71, 0xe7, 0x00, 0x06, 0x00, 0x11, 0x10, 0x81, - 0xf8, 0x44, 0x14, 0xdf, 0xf9, 0x80, 0x16, 0x53, - 0xf6, 0xb8, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x20, - 0xff, 0xff, 0xf6, 0xb8, 0xfb, 0x80, 0x16, 0x08, - 0xf0, 0x20, 0xff, 0xff, 0x77, 0x11, 0x00, 0x7b, - 0x71, 0x81, 0x00, 0x17, 0x76, 0xe7, 0x00, 0x06, - 0x00, 0x01, 0x48, 0x17, 0x77, 0x16, 0x00, 0x00, - 0x77, 0x10, 0x00, 0x04, 0x77, 0x15, 0x00, 0x03, - 0x77, 0x14, 0x00, 0x02, 0x77, 0x13, 0x00, 0x01, - 0xf0, 0x00, 0x00, 0x39, 0x76, 0xe7, 0x00, 0x08, - 0x00, 0x1f, 0x76, 0xe7, 0x00, 0x07, 0x00, 0x00, - 0x88, 0x0e, 0x77, 0x1a, 0x00, 0x05, 0x48, 0x17, - 0xf0, 0x00, 0x00, 0x09, 0x88, 0x12, 0x48, 0x18, - 0x88, 0x19, 0xe8, 0x00, 0xf0, 0x72, 0x15, 0x2c, - 0x73, 0x19, 0x00, 0x11, 0x76, 0x82, 0x00, 0x00, - 0x11, 0x91, 0x73, 0x11, 0x00, 0x19, 0x70, 0xe2, - 0x00, 0x03, 0x00, 0x16, 0x70, 0xe2, 0x00, 0x04, - 0x00, 0x13, 0x70, 0xe2, 0x00, 0x05, 0x00, 0x14, - 0x81, 0xe2, 0x00, 0x01, 0x70, 0xe2, 0x00, 0x06, - 0x00, 0x15, 0x70, 0xe2, 0x00, 0x07, 0x00, 0x10, - 0x80, 0xe2, 0x00, 0x02, 0x73, 0x0e, 0x00, 0x11, - 0xf1, 0x00, 0x00, 0x1e, 0x6d, 0xee, 0x00, 0x05, - 0x6d, 0xeb, 0x00, 0x05, 0x6d, 0xec, 0x00, 0x05, - 0x6d, 0xed, 0x00, 0x05, 0x6d, 0xe8, 0x00, 0x05, - 0xf0, 0x00, 0x00, 0x01, 0x81, 0x91, 0x6d, 0xea, - 0x00, 0x08, 0x73, 0x11, 0x00, 0x0e, 0xee, 0x07, - 0x76, 0xe7, 0x00, 0x41, 0x00, 0x24, 0x76, 0xe7, - 0x00, 0x46, 0x00, 0x25, 0x76, 0xe7, 0x00, 0x4b, - 0x00, 0x26, 0x76, 0xe7, 0x00, 0x50, 0x00, 0x27, - 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, - 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfe, 0x88, 0x11, - 0x56, 0x06, 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, - 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 0xf0, 0x10, - 0xff, 0xff, 0xfa, 0x45, 0x15, 0x60, 0x77, 0x16, - 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 0x49, 0x11, - 0x10, 0x82, 0xf6, 0x03, 0xf0, 0x00, 0x00, 0x09, - 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, - 0xf8, 0x44, 0x15, 0x71, 0xf2, 0x73, 0x15, 0x71, - 0xf4, 0x95, 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, - 0x10, 0x81, 0xf0, 0x00, 0x00, 0x09, 0x88, 0x11, - 0xf4, 0x95, 0x77, 0x12, 0x00, 0x06, 0x10, 0x81, - 0xf8, 0x45, 0x15, 0x5c, 0x6e, 0xea, 0xff, 0xff, - 0x15, 0x69, 0x6d, 0xe9, 0x00, 0x08, 0x76, 0x86, - 0x00, 0x01, 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, - 0x10, 0xf8, 0x00, 0x0b, 0xf8, 0x45, 0x15, 0x7e, - 0xfb, 0x80, 0x15, 0x85, 0xf4, 0x95, 0x48, 0x16, - 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x02, 0x48, 0x16, - 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, - 0xee, 0xff, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, - 0xf4, 0x95, 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, - 0xf8, 0x30, 0x15, 0xc4, 0x10, 0xe1, 0x00, 0x03, - 0x77, 0x12, 0x00, 0x55, 0x80, 0x82, 0x77, 0x12, - 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, - 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, - 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, - 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, - 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, - 0x00, 0x02, 0xf0, 0x00, 0x00, 0x08, 0x32, 0xf8, - 0x00, 0x08, 0x77, 0x12, 0x00, 0x54, 0xe8, 0x01, - 0xf4, 0x82, 0xf4, 0x93, 0x18, 0x82, 0x77, 0x12, - 0x00, 0x54, 0xf0, 0x40, 0x00, 0x00, 0x80, 0x82, - 0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x76, - 0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x66, - 0xf0, 0x73, 0x16, 0x03, 0x77, 0x11, 0x00, 0x7b, - 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 0x00, 0x07, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, - 0x00, 0x09, 0xf9, 0x80, 0x15, 0x85, 0x77, 0x11, - 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, - 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, - 0x00, 0x08, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81, - 0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80, - 0x15, 0x85, 0xf0, 0x00, 0x00, 0x10, 0x77, 0x11, - 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, - 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, - 0x00, 0x18, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81, - 0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80, - 0x15, 0x85, 0xf0, 0x00, 0x00, 0x20, 0x77, 0x11, - 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, - 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, - 0x00, 0x28, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, - 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, - 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, - 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, - 0x16, 0x41, 0x77, 0x11, 0x00, 0x55, 0x76, 0x81, - 0x00, 0x1e, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, - 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0xf2, 0x73, - 0x16, 0x4e, 0x76, 0x81, 0x00, 0x00, 0x77, 0x11, - 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, - 0x00, 0x07, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, - 0x10, 0xe1, 0x00, 0x39, 0xf9, 0x80, 0x16, 0x08, - 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, - 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, - 0x10, 0x81, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, - 0x16, 0x63, 0xf4, 0x95, 0xee, 0xff, 0x76, 0x81, - 0x00, 0x01, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4, - 0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8, - 0x00, 0x08, 0xee, 0xff, 0x77, 0x11, 0x00, 0x01, - 0xe8, 0x01, 0xee, 0x01, 0xf4, 0x82, 0x1a, 0x81, - 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, - 0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8, - 0x00, 0x08, 0xee, 0xff, 0xe8, 0x01, 0x77, 0x11, - 0x00, 0x00, 0xf4, 0x82, 0xee, 0x01, 0xf4, 0x93, - 0x18, 0x81, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, - 0xf4, 0xe4, 0x4a, 0x11, 0xf0, 0x10, 0x00, 0x10, - 0x77, 0x11, 0x00, 0x00, 0x32, 0xf8, 0x00, 0x08, - 0xee, 0xff, 0x11, 0x81, 0xe8, 0x01, 0xee, 0x01, - 0x77, 0x11, 0x00, 0x00, 0xf4, 0x82, 0xf2, 0xa0, - 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, - 0xf2, 0x73, 0x16, 0x9e, 0xf6, 0xbb, 0xf4, 0x95, - 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4, - 0xf2, 0x73, 0x16, 0xa6, 0xf7, 0xbb, 0xf4, 0x95, - 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4, - 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 0x71, 0x04, - 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, - 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x0e, 0x10, 0xe6, 0x00, 0x0e, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, - 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x0d, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, - 0x10, 0xe6, 0x00, 0x0d, 0x80, 0x82, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0c, - 0x10, 0xe6, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 0x10, 0xe6, - 0x00, 0x0b, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, - 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x10, 0xe6, 0x00, 0x0a, 0x80, 0x82, - 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x09, 0x10, 0xe6, 0x00, 0x09, 0x71, 0xe1, - 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x08, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, - 0x00, 0x08, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 0x10, 0xe6, - 0x00, 0x07, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, - 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x10, 0xe6, 0x00, 0x06, 0x80, 0x82, - 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x05, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, - 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x04, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, - 0x00, 0x04, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 0x71, 0xe1, - 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 0x00, 0x03, - 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x02, 0x10, 0xe6, 0x00, 0x02, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, - 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x01, 0x10, 0xe6, 0x00, 0x01, 0x71, 0xe1, - 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x13, 0xe7, 0x62, - 0xe5, 0x01, 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, - 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, - 0x00, 0x12, 0xee, 0xff, 0x76, 0x82, 0x00, 0x00, - 0xee, 0x01, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, - 0x69, 0x81, 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, - 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95, - 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0xee, 0xff, 0x76, 0x82, 0x00, 0x01, 0xee, 0x01, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 0x69, 0x81, - 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, - 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, - 0xf0, 0x00, 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, - 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 0x17, 0x9c, - 0xf4, 0x95, 0xee, 0xff, 0xf9, 0x80, 0x16, 0x53, - 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, - 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, - 0x76, 0x81, 0x00, 0x01, 0xee, 0x01, 0x76, 0xe1, - 0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, - 0x00, 0x21, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x20, - 0x76, 0xe1, 0x00, 0x04, 0x00, 0x23, 0x76, 0xe1, - 0x00, 0x05, 0x00, 0x22, 0x76, 0xe1, 0x00, 0x06, - 0x00, 0x38, 0x76, 0xe1, 0x00, 0x07, 0x00, 0x39, - 0x76, 0xe1, 0x00, 0x08, 0x00, 0x15, 0x76, 0xe1, - 0x00, 0x09, 0x00, 0x14, 0x76, 0xe1, 0x00, 0x0a, - 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x41, - 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x40, 0x76, 0xe1, - 0x00, 0x0d, 0x00, 0x43, 0x76, 0xe1, 0x00, 0x0e, - 0x00, 0x42, 0x76, 0xe1, 0x00, 0x0f, 0x00, 0x48, - 0x76, 0xe1, 0x00, 0x10, 0x00, 0x49, 0x76, 0xe1, - 0x00, 0x11, 0x00, 0x1b, 0x76, 0xe1, 0x00, 0x12, - 0x00, 0x1a, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, - 0x4a, 0x11, 0xee, 0xfd, 0x88, 0x11, 0x56, 0x06, - 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 0x77, 0x12, - 0x00, 0x7b, 0x77, 0x0e, 0x00, 0x09, 0x10, 0x82, - 0x28, 0xf8, 0x00, 0x11, 0xf0, 0x00, 0x00, 0x95, - 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, - 0xf8, 0x45, 0x17, 0xf0, 0xf2, 0x73, 0x17, 0xfd, - 0x77, 0x11, 0xff, 0xff, 0x76, 0x81, 0x00, 0x01, - 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 0x10, 0xf8, - 0x00, 0x0b, 0xf8, 0x45, 0x17, 0xfd, 0xfb, 0x80, - 0x18, 0x10, 0xf4, 0x95, 0x48, 0x11, 0xf9, 0x80, - 0x16, 0x9a, 0xee, 0x03, 0x48, 0x11, 0x8a, 0x11, - 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, - 0xf4, 0x95, 0xee, 0xff, 0x71, 0xe1, 0x00, 0x01, - 0x00, 0x11, 0xee, 0x01, 0x10, 0x81, 0x8a, 0x11, - 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, - 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, - 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, - 0x18, 0xc3, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x01, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x02, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x03, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x04, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x05, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x07, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x20, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x08, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x09, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, - 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0d, - 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, - 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, - 0x76, 0x82, 0x00, 0x0e, 0x71, 0xe1, 0x00, 0x06, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, - 0x00, 0x07, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1, - 0x00, 0x08, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1, - 0x00, 0x07, 0xf9, 0x80, 0x16, 0x66, 0x10, 0xe1, - 0x00, 0x08, 0xf9, 0x80, 0x16, 0x66, 0xf0, 0x73, - 0x18, 0xd1, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, - 0xfb, 0x80, 0x18, 0x10, 0xf0, 0x00, 0x00, 0x95, - 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xfb, 0x80, - 0x18, 0x10, 0xf0, 0x00, 0x00, 0x9e, 0xf9, 0x80, - 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4, - 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 0xf4, 0x95, - 0x10, 0x04, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x11, - 0xee, 0x01, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, - 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, - 0x71, 0x04, 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, - 0x88, 0x11, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x02, - 0x00, 0x12, 0x76, 0x82, 0x00, 0x10, 0x10, 0xe6, - 0x00, 0x01, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, - 0x80, 0x82, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12, - 0x10, 0xe6, 0x00, 0x02, 0x80, 0x82, 0xe7, 0x62, - 0x71, 0xe1, 0x00, 0x02, 0x00, 0x13, 0xe5, 0x01, - 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, - 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, - 0xee, 0x01, 0x10, 0xe1, 0x00, 0x01, 0x8a, 0x11, - 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, - 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, - 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, - 0xfa, 0x44, 0x19, 0x2a, 0xf4, 0x95, 0xee, 0xff, - 0xf9, 0x80, 0x16, 0x53, 0x77, 0x11, 0x00, 0x7b, - 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 0x88, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x76, 0x81, 0x00, 0x01, - 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 0x00, 0x00, - 0x76, 0xe1, 0x00, 0x02, 0x00, 0x13, 0x76, 0xe1, - 0x00, 0x03, 0x00, 0x26, 0x76, 0xe1, 0x00, 0x04, - 0x00, 0x25, 0x76, 0xe1, 0x00, 0x05, 0x00, 0x24, - 0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1, - 0x00, 0x07, 0x00, 0x17, 0x76, 0xe1, 0x00, 0x08, - 0x00, 0x32, 0x76, 0xe1, 0x00, 0x09, 0x00, 0x31, - 0x76, 0xe1, 0x00, 0x0a, 0x00, 0x30, 0x8a, 0x11, - 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, - 0x4a, 0x17, 0xee, 0xff, 0xf4, 0x95, 0x71, 0x06, - 0x00, 0x17, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, - 0xf4, 0x95, 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, - 0xf0, 0x10, 0xff, 0xff, 0xfa, 0x45, 0x19, 0x73, - 0x77, 0x16, 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, - 0x77, 0x0e, 0x00, 0x05, 0x10, 0x82, 0x28, 0xf8, - 0x00, 0x11, 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, - 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf8, 0x44, - 0x19, 0x84, 0xf2, 0x73, 0x19, 0x84, 0xf4, 0x95, - 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, - 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 0xf4, 0x95, - 0x77, 0x12, 0x00, 0x02, 0x10, 0x81, 0xf8, 0x45, - 0x19, 0x6f, 0x6e, 0xea, 0xff, 0xff, 0x19, 0x7c, - 0x6d, 0xe9, 0x00, 0x05, 0x61, 0xf8, 0x00, 0x17, - 0x00, 0x01, 0xfa, 0x20, 0x19, 0x8f, 0x76, 0x86, - 0x00, 0x01, 0xfb, 0x80, 0x19, 0x97, 0xf4, 0x95, - 0x48, 0x16, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, - 0x8a, 0x17, 0x48, 0x16, 0x8a, 0x16, 0x8a, 0x11, - 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 0xfb, 0x80, - 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, - 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 0x19, 0xcc, - 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 0x69, 0x82, - 0x00, 0x10, 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, - 0x68, 0x82, 0xf7, 0xff, 0x71, 0xe1, 0x00, 0x02, - 0x00, 0x12, 0x68, 0x82, 0xfb, 0xff, 0x71, 0xe1, - 0x00, 0x02, 0x00, 0x12, 0x68, 0x82, 0xff, 0xf0, - 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 0x76, 0x82, - 0xff, 0xff, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12, - 0x76, 0x82, 0xff, 0xff, 0x71, 0xe1, 0x00, 0x02, - 0x00, 0x12, 0x69, 0x82, 0x00, 0x20, 0x71, 0xe1, - 0x00, 0x02, 0x00, 0x11, 0xf2, 0x73, 0x19, 0xda, - 0x68, 0x81, 0xff, 0xef, 0x77, 0x11, 0x00, 0x7b, - 0x10, 0x81, 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, - 0x00, 0xb4, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, - 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 0x00, 0xb9, - 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, - 0xf4, 0xe4, 0x00, 0xa4, 0x00, 0x00, 0x19, 0xdf, - 0x00, 0x01, 0x2a, 0xe6, 0x00, 0x00, 0x00, 0x01, - 0x2a, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x2a, 0x12, - 0x0c, 0x01, 0xc3, 0x4f, 0x00, 0x00, 0x00, 0x01, - 0x2a, 0x15, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x16, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2a, 0x5d, - 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, - 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, - 0x00, 0x63, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x6f, - 0x00, 0x54, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, - 0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x47, - 0x00, 0x00, 0x00, 0x04, 0x2a, 0x76, 0x00, 0x30, - 0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, - 0x2a, 0x7a, 0x00, 0x46, 0x00, 0x65, 0x00, 0x62, - 0x00, 0x20, 0x00, 0x32, 0x00, 0x37, 0x00, 0x20, - 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x09, 0x2a, 0x86, 0x00, 0x31, - 0x00, 0x34, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x35, - 0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x00, - 0x00, 0x0f, 0x2a, 0x8f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x2a, 0x9e, 0x00, 0x00, - 0x00, 0x01, 0x2a, 0x9f, 0x00, 0x00, 0x00, 0x01, - 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa1, - 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa2, 0x00, 0x00, - 0x00, 0x01, 0x29, 0x7e, 0x00, 0x00, 0x00, 0x02, - 0x29, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x29, 0x82, 0xff, 0xff, 0x00, 0x01, 0x2a, 0xa7, - 0x00, 0x00, 0x00, 0x05, 0x2a, 0xa8, 0x71, 0x41, - 0x20, 0x00, 0x20, 0x00, 0x00, 0x23, 0x04, 0x00, - 0x00, 0x0a, 0x2a, 0xad, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x2a, 0xb7, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0xa0, 0x82, 0x40, - 0x00, 0x08, 0x30, 0x7f, 0x00, 0x80, 0x01, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x27, 0x6e, 0x00, 0x00, - 0x00, 0x01, 0x27, 0x6f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x09, 0x00, 0x00, 0x1a, 0x83, 0x04, 0xe8, - 0x04, 0xcf, 0x04, 0xc5, 0x04, 0xba, 0x04, 0xb0, - 0x04, 0xac, 0x04, 0x9c, 0x04, 0x8c, 0x04, 0x81, - 0x00, 0x78, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xaa, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x02, 0x23, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x05, 0xe5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x02, 0xb5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x0e, 0x33, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, - 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0x00, 0x00, -}; - diff --git a/firmware/Makefile b/firmware/Makefile index 40939e9..be7e015 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -20,6 +20,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). # But be aware that the config file might not be included at all. +fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 1373f529..9c2a1eb 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -70,3 +70,13 @@ Licence: Unknown Found in hex form in the kernel source. -------------------------------------------------------------------------- + +Driver: ttusb-budget -- Technotrend/Hauppauge Nova-USB devices + +File: ttusb-budget/dspbootcode.bin + +Licence: Unknown + +Found in hex form in the kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/ttusb-budget/dspbootcode.bin.ihex b/firmware/ttusb-budget/dspbootcode.bin.ihex new file mode 100644 index 0000000..b4b2247 --- /dev/null +++ b/firmware/ttusb-budget/dspbootcode.bin.ihex @@ -0,0 +1,820 @@ +:1000000008AA001800030800001000000180185F13 +:100010000000018077182AEB6BF8001803FF68F8DE +:100020000018FFFEF7B8F7BEF6B9F4A0F6B7F6B5BC +:10003000F6B6F02019DFF1000001F84D01ABF6B87B +:10004000F02019DFF07301A57EF80012F000000126 +:1000500047F800117E9200F80011F00000017EF8D0 +:100060000011F00000016C89019AF7B8EEFCF02055 +:10007000FFFFF1000001F84D01BFF27301B94E021C +:10008000F495F5E356027E001100FA4C01B76B03BC +:100090000001F6B8EE04F0740DA7F07401C54A1122 +:1000A0004A1672112AE610F80011FA4501DBF495A0 +:1000B000EEFF4811F0002AC68816F495F49510EE6C +:1000C000FFFFF4E36CE9FFFF01D510F82AE7F845DC +:1000D00001E210F82AE7F4E3F07401FFEE018A165A +:1000E0008A11FC00F7B8E9204A1109F82AE6F84E0F +:1000F00001F3F27301FDF495E80172112AE649114A +:1001000080E12AC6F3000001E80081F82AE68A119E +:10011000FC00F495F073020010F82A0FFC004A115D +:10012000F074020280F82A107308000940F82A15BA +:1001300082F80011F495771003E8F5A9F830022150 +:1001400071F82A102A1556F82A0CF0E34EF82A16F0 +:10015000E8004EF82A0C8A11FC004A064A074A1D9C +:1001600068F800077D3F69F80007400068F8001D47 +:10017000FFFC6BF82A0F00018A1D8A078A06F4EB40 +:10018000EEFD76F82A0F000076000000FB80194C87 +:10019000F495E80080F82A11F980190780F82A0EF2 +:1001A000F980166676002A1210F82A11F98018E3F1 +:1001B00010F82A0EF980166610F82A0EF9801687B4 +:1001C000EE03FC004A11F6B8F495F020800011F817 +:1001D0002A5AF84D029311F82A9FF84C027C7712A4 +:1001E0002A39491201F82A9F8911F495F4957181F1 +:1001F00000116CE1FFAB02936BF82A9F0001E90547 +:1002000001E2000381F82AA0F073029572112A9F7F +:10021000F49510E12A396BF82A9F000111F82A9F02 +:1002200009F82AA0F84C029376F82A5A000076F8CA +:100230002A9F000076F82AA000008811F495481142 +:100240008A11FC004A11EEFE10F82A5AF84402B254 +:1002500076F82A5A0001F07402588811F495771044 +:100260008000F4A9F83002B24811F03000FF80009D +:1002700010F82A5BF98018D6EE028A11FC00F4957A +:100280004A084A094A0A4A0B4A0C4A0D4A104A11BE +:100290004A124A134A144A154A164A174A174A1963 +:1002A0004A0E4A064A074A1A4A1D4A1B4A1C68F85F +:1002B00000077D3F69F80007400068F8001DFFFC5B +:1002C000481868F80018FFFEF495F4954A08EEFD0A +:1002D000F07402588811F49577108000F4A9F83072 +:1002E00002EF4811F03000FF800010F82A5BF9801F +:1002F00018D6EE038A18F4958A1C8A1B8A1D8A1A5E +:100300008A078A068A0E8A198A178A178A168A1510 +:100310008A148A138A128A118A108A0D8A0C8A0B0F +:100320008A0A8A098A08F4EB4A1177112A397681F8 +:10033000005577122A1810E2000180E1000110E256 +:10034000000280E1000276E10003000076E1000493 +:1003500000AAF07402988A11FC004A118811F495E1 +:10036000F49510816FF82A9E0C88E8FF18E10001CF +:100370001AF82A9EF0301FFF80F82A9E8A11FC008E +:100380004A1177112A397681005577122A1811E21D +:10039000000181E1000111E2000281E1000276E149 +:1003A0000003000248086FE100040C98F03000FFE1 +:1003B00080E1000576E1000600AAF07402988A1137 +:1003C000FC004A1177112A397681005577122A18D4 +:1003D00010E2000180E1000110E2000280E1000271 +:1003E00076E1000300044811F00000048812F4953F +:1003F00077132A76E900E598F3000001F6B8480B78 +:1004000008F82A3CF8430371768200AAF074029837 +:100410008A11FC004A11EEF08811F495F49571816F +:10042000001471E1000100154911F3000002891167 +:10043000E7826DEA0004E7836DEB000A771A000596 +:10044000F07203AA1181F2E88082E9FF19E100014C +:10045000F1A0819211E1000CF2E88083E9FF19E13B +:10046000000DF1A081936DE9000248184918700051 +:100470000015F0000004F300000A80018102F2740C +:100480000E54F4954814EE108A11FC004A11F074D1 +:100490000C5E80F82A5C77122A3976820055771133 +:1004A0002A1810E1000180E2000110E1000280E260 +:1004B000000276E20003001CF6B856F82A16F0F0A7 +:1004C000F0F880E2000756F82A16F1F0E8FFF28013 +:1004D00080E2000656F82A16F1F8E8FFF28080E282 +:1004E000000557F82A16E8FFF28080E2000456F86B +:1004F000276CF0F0F0F880E2000B56F8276CF1F072 +:10050000E8FFF28080E2000A56F8276CF1F8E8FF75 +:10051000F28080E20009E8FF57F8276CF28080E261 +:10052000000856F8276AF0F0F0F880E2000F56F85D +:10053000276AF1F0E8FFF28080E2000E56F8276AA1 +:10054000F1F8E8FFF28080E2000D57F8276AE8FF33 +:10055000F28080E2000C76E20013000076E20012E6 +:1005600000006FF82A5C0C5880E20011E8FF18F8D0 +:100570002A5C80E2001076E20017000076E20016A6 +:1005800000006FF82A9E0C5880E20015E8FF18F86A +:100590002A9E80E2001476E2001B000076E2001A38 +:1005A000000076E20019000070E20018276E76E283 +:1005B000001F000076E2001E000076E2001D000031 +:1005C00076E2001C000076E2002000AAF074029897 +:1005D0008A11FC004A11EEFE10F82A38F84504EDA5 +:1005E00077122A1810E200028811F495771000089B +:1005F0006DE9FFDFF6A9F8200475F073047DF010B3 +:100600000021F0001A8348087EF80008F4E2F07434 +:10061000030AF07304EA4812F2740323F0000004A2 +:10062000F2740336F495E800F07304EA77112A189F +:10063000E8FF6FE100040D4818E10005F274096954 +:10064000F495F2A0F0740336F07304EA77112A18D7 +:10065000E8FF6FE100040D4818E10005F27409415C +:10066000F495F2A0F0740336F07304EAF0740357C3 +:10067000F07304EA10F82A1CF07412A4F274033622 +:10068000F495E800F07304EA4812F2740380F00075 +:100690000004F2740336F495E800F07304EA10F8ED +:1006A0002A1CF07412C5F2740336F495E800F07356 +:1006B00004EA77112A18E8FF6FE100060D4818E1F7 +:1006C000000771E100050012F2A070000012800125 +:1006D00010E10004F0740E7AF2740336F495E80029 +:1006E000F07304EAF07403BC76F82A380000EE02D6 +:1006F0008A11FC004A1177112A3976810055771248 +:100700002A1810E2000180E1000110E2000280E1FD +:10071000000276E1000300094811F000000488128D +:10072000F49577132A86E900E598F3000001F6B8FE +:10073000480B08F82A3CF843050A768200AAF074B0 +:1007400002988A11FC004A1177112A3976810055E6 +:1007500077132A1810E3000180E1000110E3000282 +:1007600080E1000213E3000381E1000348117711E7 +:100770000000F84D0544F000000488124813F00012 +:1007800000048813F495F495E5986D91F6B8481136 +:1007900008F82A3CF843053AF0202A394911F500B7 +:1007A0008911F495F49576E1000400AAF07402989A +:1007B0008A11FC004A1177112A3976810055771287 +:1007C0002A1810E2000180E1000110E2000280E13D +:1007D000000276E10003000C4811F00000048812CA +:1007E000F49577132A7AE900E598F3000001F6B84A +:1007F000480B08F82A3CF843056A768200AAF07490 +:1008000002988A11FC004A1177112A397681005525 +:1008100077122A1810E2000180E1000110E20002C4 +:1008200080E1000276E1000300194811F0000004A5 +:100830008812F49577132A5DE900E598F30000012A +:10084000F6B8480B08F82A3CF8430593768200AACC +:10085000F07402988A11FC004A11881110F82A38A5 +:10086000F84405E310F82AA1F84405BA6CE1FF56F4 +:1008700005E372122AA1F49570E22A1800116BF8B0 +:100880002AA10001F07305E372122AA1F49570E227 +:100890002A18001110F82AA1F00000018812F4951E +:1008A000F4956EE2FFFC05D173122AA14811F00005 +:1008B000000580F82AA210F82AA108F82AA2F84414 +:1008C00005E36CE1FFAB05DD76F82A38000176F828 +:1008D0002AA1000076F82AA200008A11FC00F495F3 +:1008E0004A084A094A0A4A0B4A0C4A0D4A104A1158 +:1008F0004A124A134A144A154A164A174A174A19FD +:100900004A0E4A064A074A1A4A1D4A1B4A1C68F8F8 +:1009100000077D3F69F80007400068F8001DFFFCF4 +:10092000481868F80018FFFEF495F4954A08EEFFA1 +:1009300010F82A5BF9801804F07405A2EE018A18F9 +:10094000F4958A1C8A1B8A1D8A1A8A078A068A0ECF +:100950008A198A178A178A168A158A148A138A129C +:100960008A118A108A0D8A0C8A0B8A0A8A098A08D7 +:10097000F4EBEEFD76F82A38000076F82A5A0000EB +:10098000E8014E00FB8017D6F495E80180F82A5B59 +:1009900076002A8FF98016AA10F82A5BF980175C76 +:1009A00010F82A5BF980176FFB801666F495E81A39 +:1009B000FB801687F495E81AFB801666F495E81B11 +:1009C000FB801687F495E81BEE03FC004A11F495B2 +:1009D00013028811E800F84D066AF3100001891A25 +:1009E000F495F07206691C918A11FC004A11881175 +:1009F00012031102F8450679F0100001881AF495E7 +:100A0000F072067881918A11FC004A11F495710206 +:100A10000011110361F800110001F8300691F6B8D9 +:100A20006FF800110C1F8811F3E8E8FF1881F1A09E +:100A30008181F073069DF6B86FF800110C1F8811C4 +:100A4000F33000FFF020FF001881F1A081818A11AE +:100A5000FC004A11F495110261F8000B0001F82026 +:100A600006B1490BF61F8811F495F4951081F273C5 +:100A700006B8F03000FF490BF61F8811F495F49585 +:100A80001281F4788A11FC004A11F4957102001267 +:100A900013038811E800F84D06CCF3100001891A01 +:100AA000F495F07206CB1192F2C081918A11FC008C +:100AB0008812120271010013F84506DBF0100001E4 +:100AC000881AF495F07206DAE598FC004A11EEFEF9 +:100AD0008811110410067105001261F8001200015E +:100AE000F82006EAF0000001F6B8F00000016FF807 +:100AF00000120F1F48088100F47F8001F27406BACB +:100B0000F4954811EE028A11FC004A11EEFE88129B +:100B1000110410067105001361F800130001F8209C +:100B20000709F0000001F00000018811F6B86FF825 +:100B300000130F1F81004811F47F8001F27406CE6C +:100B4000F49548124811F030FFFEEE028A11FC00C5 +:100B50004A114A164A17EEFCF495800271080016F5 +:100B60001009710B00178003710A00114817F8452E +:100B7000073F700000111003F074069F80017000A1 +:100B800000161002F074067B6D916D966CEFFFFFFE +:100B9000072FEE048A178A168A11FC004A11EEFE0E +:100BA00010F82AE808F82AE9F845076476000001F9 +:100BB00062F82AE9005EF274120BF0003040721104 +:100BC0002AE97710000FF5A9F82007616BF82AE9E8 +:100BD0000001F073076476F82AE90000EE028A113A +:100BE000FC004A118811E80075F800080008E800C8 +:100BF00075F800080009F6B8F495F020FC3F75F888 +:100C00000008000DF0200C3075F80008000C76F894 +:100C10002AE8000076F82AE900006C81079276F84D +:100C20002AEA0000FB801676F495E810E80075F8D3 +:100C300000080000F07307A876F82AEA0001FB809C +:100C40001666F495E810FB801687F495E810E80026 +:100C500075F800080000F6B8F495F020FFFF75F86D +:100C6000000800008A11FC00F4954A084A094A0A63 +:100C70004A064A074A1D68F800077D3F69F80007E1 +:100C8000400068F8001DFFFC10F82AEAF84507E16B +:100C900010F82AE8F0000001F030000F80F82AE890 +:100CA00010F82AE8F84407D6F6B8F495F020FC3F8F +:100CB00075F80008000DF0200C3075F80008000CE5 +:100CC000E80075F800080000F6B8F495F020FFFF82 +:100CD00075F8000800008A1D8A078A068A0A8A09B0 +:100CE0008A08F4EBEEFFF2740767F495E801EE0171 +:100CF000FC004A074A1D68F800077D3F69F80007B5 +:100D0000400068F8001DFFFC8A1D8A07F4EB4A11B9 +:100D10007711002876812400E80075F800080001AA +:100D2000F2740767F495E8007711001D6881007F71 +:100D3000F6B8F495F020FF807711001DF030010027 +:100D40001A818081F0740A33F07411ACF980132594 +:100D5000F9801653F9801782F074062FF98014B2C7 +:100D6000F9801910F0740DE3F07407E8F07402369E +:100D70008A11FC004A1160F8277BFFFFF830083920 +:100D800071F8277B277960F82779FFFFF83008B2E0 +:100D900010F8298608F82779F0307FFF8811F4953C +:100DA00077104000F6A9F830085810F8277908F8AD +:100DB000277AF0307FFF8811F49577104000F6A96C +:100DC000F820086376F82779FFFF76F8277BFFFF86 +:100DD000F7B8F27308D9F020FFFFF6B856F8277479 +:100DE000F0F9881156F82772F0F98812F495F49505 +:100DF000E720F4A9F830088FF120277C4811F6008D +:100E00008813F495F495108308F82779F0307FFF64 +:100E10008813F49577104000F5ABF830088F6D918A +:100E20004811F03001FF8811F495E720F7A9F83058 +:100E300008746D894811F03001FFF0E7F495480817 +:100E40004EF827744808F1F98911F495F49571E189 +:100E5000277C277A60F8277BFFFFF83008AB48082B +:100E60004EF8277276F8277BFFFF76F82779FFFF89 +:100E7000F27308D9F495E80044F8277340F8277511 +:100E800082F80011F49577108000F6A9F82008D8B0 +:100E9000F6B810F82773F000800048084EF8277461 +:100EA0004808F0F98811F495F49571E1277C277AC8 +:100EB000F7B857F82774F062FFFFF040FF80F28028 +:100EC0004EF82774E8008A11FC004A114A16EEFB1E +:100ED00011F8277109F8277389118810F495F49592 +:100EE000F6A9F82008EDF273090EF495E800F62053 +:100EF00076000041F07412EE8816F495F7B86D96FE +:100F000010F80016F847090AE7617600000076013C +:100F10000080760200FF76030000F2740CB9F495AD +:100F2000E8006CE9FFFF08FB7316000EF066004155 +:100F3000EE058A168A11FC004A11F495710200131D +:100F4000F6B877117FFF57F827724811F280F0004A +:100F500080008811F640F0E0F1F1E801F28080F8BD +:100F600027787712800057F827724812F28088128B +:100F7000F495F4956C820938E80075F800080001D2 +:100F8000F073093DF020800175F8000800017081C0 +:100F900000138A11FC004A11F0307FFF11F82986F6 +:100FA000F520F3307FFF8911F49577104000F6A902 +:100FB000F8200954F2730967F495E8026FF8277A6C +:100FC0000D20F3307FFF8911F49577104000F6A9CA +:100FD000F8200964F2730967F495E80180F8277B2B +:100FE000E8008A11FC004A1111F82986F520F33037 +:100FF0007FFF8911F49577104000F6A9F820097A4F +:10100000F273098DF495E8026FF8277A0D20F3301A +:101010007FFF8911F49577104000F6A9F820098A1E +:10102000F273098DF495E80180F82779E8008A11B8 +:10103000FC004A11F495710200128811F6B857F8B5 +:101040002772F0207FFFF280F0008000808157F847 +:101050002772E801F3F1F28080F827787711800099 +:10106000481157F82772F2808811F495F4956C8135 +:1010700009B5E80075F800080001F07309BAF0201E +:10108000800175F80008000145F8277143F82773BF +:1010900083F80011F495E720F6A9F83009C9F27336 +:1010A00009E47712000057F82772F0207FFFF280E2 +:1010B0004912F500F300800061F8000B8000F83061 +:1010C00009DCF1208000F5208912F49548126FF8B0 +:1010D00027730D00F495490B4FF827728A11FE0013 +:1010E0004812F4954A114A164A17EEFCF495710815 +:1010F00000168817F0740830481870000016F27453 +:10110000098FF00000028811F495F4956C810A0AA9 +:10111000F27408DBF4954816481870000016F27453 +:10112000098FF00000028811100270010011800088 +:10113000F27406CEF495481749114817F60088173F +:10114000E760F5A9F8200A2D4816F62088114818FE +:1011500070000011F274098FF00000028811700114 +:10116000001110028000F27406CEF4954817EE04C8 +:1011700048168A178A168A11FC00EEFDE8004EF820 +:101180002770E8004EF82772E8004EF82774E80050 +:101190004EF8277676F82779FFFF76F8277A000051 +:1011A00076F8277BFFFF76F827780000E80075F8CF +:1011B000000800017600000076010200F27412DCE3 +:1011C000F020277CEE03FC004A11EEFCF4954E0063 +:1011D00077127FFFF6B84912F180F3008000891280 +:1011E000F0E0F1F14F02E901F495480BF5405602A9 +:1011F000F18081F827787711800056004911F1803D +:101200008911F495F4956C810A81E80075F800085D +:101210000001F0730A86F020800175F800080001D3 +:101220001082EE048A11FC004A11EEFEF4954E0085 +:1012300077117FFFF6B84911F180F3008000891122 +:10124000F0E0F1F1E801F28080F827785600F12013 +:101250008000F180F495490BF84D0AABF020800135 +:1012600075F800080001F0730AAFE80075F800088F +:101270000001EE0248118A11FC004A118812130283 +:1012800077110000F84D0ACBF3100001891AF4958C +:10129000F0720ACA48111CF8297E881111F8297EBB +:1012A000F200000180F8297E819248118A11FC0029 +:1012B0004A11F495710200118812F6B8F0207FFFF0 +:1012C00057F82770F280F0008000808257F827706E +:1012D000E801F3F1F28080F8277877128000481255 +:1012E00057F82770F2808812F495F4956C820AF40E +:1012F000E80075F800080001F0730AF9F020800199 +:1013000075F80008000145F82775E71043F82771C4 +:1013100083F800126DE800046D8AF6AAF8300B0A13 +:10132000F2730B257711000057F82770F0207FFF2C +:10133000F2804911F500F300800061F8000B800095 +:10134000F8300B1DF1208000F5208911F49548112B +:101350006FF827710D00F495490B4FF8277048116D +:101360008A11FC004A114A164A17EEF08817101726 +:1013700080051016800610158007711400111005E5 +:10138000F030000188101006F0300001800849118B +:101390001005F6018009100661F800080001F82028 +:1013A0000B4B1009F0000001800971080012F4AA2B +:1013B000F8300B541009F00000018009120949119E +:1013C000F47F8009F620800A56F827704E0C100929 +:1013D00080004818F2740ACEF00000048816F495D4 +:1013E000F4956C860B6DF2730C59F495E800F6B821 +:1013F000F495560CF0F98812F495F49570E2277C78 +:101400002986E800800E4811F8450BCC77100001C2 +:10141000F4A9F8300B896CE1FFFD0B8B10E700029B +:10142000800EF0730B8B1087800EE710F5AEF8205E +:101430000BB270000017700100161004F07406CE95 +:1014400048174916F60088174811F6208811100928 +:10145000F62080004818F2740ACEF00000048816C6 +:1014600010047000001770010011F07406CE4811CE +:1014700000048004F0730BBC7000001770010011B1 +:101480001004F07406CE4811000480044911481677 +:10149000F6208816F495F4956C860BCC100A800023 +:1014A0004818F2740ACEF00000048816120AF845B3 +:1014B0000C33710A0010F4AEF8300C1C4816F0E141 +:1014C00088111208F8450BDB6D891207F8450BE906 +:1014D0001007800070020011100680011004F074E3 +:1014E00006DCF0730BEF48116F000C9F1004F074D2 +:1014F0000AB3110EF1C0810E10064911F6008006E4 +:101500001005F6208811F000000148086F000C9FBC +:101510004818F2740ACEF00000041207F8450C11C6 +:101520001007800070020011100680011004F07492 +:1015300006DCF0730C1748116F000C9F1004F07458 +:101540000AB3110EF1C0810EF0730C331207F84587 +:101550000C2A10078000100680011005800210047C +:10156000F07406DCF0730C3012056F000C9F100451 +:10157000F0740AB3110EF1C0810E76000001481814 +:10158000F2740ACEF0000004710400117081298603 +:10159000100E1CF82986800E760000014818F2749F +:1015A0000ACEF0000004100E71040011808110F8C2 +:1015B0002986F0000001F0307FFF80F829861009AD +:1015C000F00000028009EE108A178A168A11FC00CA +:1015D00010F8277508F82771F01000014808FC0082 +:1015E0004A114A16EEFFF49571040016F00000014E +:1015F00048084EF8297C6DEEFFFD4816F8450C9919 +:1016000056F8297CF0740A5A881110F8297DF000E8 +:10161000000148084EF8297C10F82982F0000001EA +:101620008810F495F495F4A9FA300C9680F8298284 +:1016300056F82980F00000014EF8298073112982A4 +:101640006CEEFFFF0C76EE018A168A11FC004A113F +:1016500076F82984000076F829850001E8004EF824 +:101660002A0C76F82986000076F829870000771181 +:1016700029887681AAAA76E10001AAAA76E1000269 +:1016800000008A11FC004A11EEFCF495710600146A +:10169000710700137108001271090015771000FF1F +:1016A000F4AAF8300D44491353F82A0C4FF82A0CC9 +:1016B0007312000EF166000D8911F4957710000188 +:1016C00071E124000011F4A9F8300D177710000221 +:1016D000F4A9F8300CEC7711298A76810000E80033 +:1016E0007714000077130000F0730D486C830CFA38 +:1016F0007711298A4812F0E8F04080008081E800E4 +:1017000077140000F0730D484913F340800081F80E +:10171000298A61F800150001F8200D0769F8298A67 +:10172000400061F800140001F8200D0F69F8298AC3 +:1017300020007711298A4912F3E81B818181F07317 +:101740000D4811F82984F84C0D37771129887681D6 +:10175000AAAA11F82985F3100001F340AA0081E13B +:101760000001760000028001700200147003001373 +:10177000F2740B28F495481171F829852984F073C7 +:101780000D737600000080017602000070030013E4 +:10179000F2740B28F495E800F0730D737711298A21 +:1017A0007081001311F82984F84C0D68771129888D +:1017B0007681AAAA11F82985F3100001F340AA0046 +:1017C00081E10001760000038001700200147003C3 +:1017D0000013F2740B28F495481171F829852984B7 +:1017E000F0730D7376000001800170020014700325 +:1017F0000013F2740B28F49548116BF82984FFFF4D +:10180000EE048A11FC004A11F540F495480BF47877 +:101810008811F495F4956CE1FFB90D88F2730DA56C +:10182000F495E860F200000661F800110020F8303D +:101830000D9861F8000B0001F8200DA3F2000007DD +:10184000F0730DA361F8000B0001F8200DA1F273F5 +:101850000DA3F0000001F00000024808F47F8A1197 +:10186000FC00EEFFF07407FDF0740744F0740DB453 +:10187000F0740205F0740460F0730DAAEEFD10F828 +:101880002AA3F8440DCB10F82AA4F8450DD776000A +:101890000200F27409E8F020220076F82AA4000081 +:1018A00076F82AA70000F0730DD776000200F274D4 +:1018B00009E8F020200076F82AA3000076F82AA78D +:1018C0000001F0740C5EF0E0F0103A98F8470DE17A +:1018D00076F8276E0000EE03FC004A11EEFE771149 +:1018E00020007600AAAA76010200F274066CF49534 +:1018F000481176005555760102004811F274066CC5 +:10190000F000020076F82AA3000076F82AA400006E +:10191000E8004E00FB80153EF495E80480F82AA507 +:1019200076002AA8F980148776002AADFB8013621E +:10193000F495E80210F82AA5F9801463FB80166676 +:10194000F495E81CFB801687F495E81CE8014E002E +:10195000FB8017D6F495E80080F82AA676002AB70F +:10196000F98016AA10F82AA6F980175C10F82AA6A2 +:10197000F980176FEE028A11FC00F4954A084A09B3 +:101980004A0A4A074A1D68F800077D3F69F80007C0 +:10199000400068F8001DFFFC10F82AA7F8440E4B21 +:1019A00076F82AA30001F0730E4E76F82AA40001FF +:1019B0008A1D8A078A0A8A098A08F4EB4A114A169C +:1019C0004A17EEFE880E71080016710600171107FF +:1019D000F066000DF00025A0881176010006810058 +:1019E000F27406CEF00000017601000670000016C9 +:1019F0004811F27406CEF000000770810017EE0265 +:101A00008A178A168A11FC004A11880E7102001288 +:101A10001103F066000DF00024008811F495708128 +:101A200000126EE2FFFE0E8DF495E800E80180E101 +:101A3000000276E1000300FF76E10004000076E199 +:101A4000000B000076E1000C000081E100018A112A +:101A5000FC004A11EEFC880EF495F166000DF300CF +:101A600024008911F495F49576E1000C000076E1EC +:101A7000000B000076E10002000176000000760114 +:101A80000000800276030000F2740CB9F495E800BF +:101A9000EE048A11FC004A118819F4957319000E9E +:101AA000F166000DF2002400771525A077140000E0 +:101AB000771A001FF0720F14F6B849190985F84C0F +:101AC0000F13F100000589114915F3000001891376 +:101AD0004915F3000007891211931D91199289107D +:101AE000F495F4956C800F1311931D911992891040 +:101AF000F495F4956C800F1311931D911992891030 +:101B0000F495F4956C800F1311931D91199289101F +:101B1000F495F4956C800F1311931D91199289100F +:101B2000F495F4956C800F1311931D9119928911FE +:101B3000F495F4956C810F136D946DED000D4814C0 +:101B40008A11FC004A114A164A17EEF88817100D40 +:101B50008004100C8005710E00167317000EF066DD +:101B6000000DF0002400881110F82763F8450F32AB +:101B7000F2740E9FF495481710F82760F8440F3D53 +:101B800060E100020001F8200F6DF07311331004C2 +:101B900080001005F074069F1104F3000001810419 +:101BA0006D8E7710000171E100020012F4AAF83086 +:101BB0000F6277100002F4AAF8300F6D45E1000BB8 +:101BC000881043E1000C83F80012F495F495F4AA10 +:101BD000F8300F6DF0730F96F50081044916F5206B +:101BE000891676E1000C000076E10004000048163A +:101BF000F8451133F7B871E10002001210F8001235 +:101C0000F0100003F8460F8C10F80012F0100003DB +:101C1000F845101677100001F4AAF8300F9C7710E1 +:101C20000002F4AAF8300FA8F0730F9677100004A2 +:101C3000F4AAF83010B777100005F4AAF83010BCF9 +:101C4000F2740E9FF4954817F073113176E1000C91 +:101C5000000076E1000B000076E10004000076E170 +:101C60000002000211E1000CE803F6208912F4954D +:101C700077100003F5AAF8300FB66BF8276F000154 +:101C80008810F495F495F5AEF8200FBD481680063F +:101C90008813F49577100003F6ABF8200FC86BF8A3 +:101CA000276F00011206F845100010E100048000C3 +:101CB0001005800110048002100680034811F274A0 +:101CC000071EF0000005100600E1000480E100049A +:101CD000100600E1000C80E1000C881211061004CF +:101CE000F60080044816F62088168913F4957710BC +:101CF0000003F6ABF8200FF56BF8276F00017710A3 +:101D0000000C71E100040013F6ABF82010006BF832 +:101D1000276F00016CE2FFFD1131F6B86FE100059D +:101D20000C486FE100060C18F0300FFFF0000003C4 +:101D300080E1000B76E1000200034816F8451133FC +:101D400071E1000C001210E1000B4912F62088131B +:101D5000E80CF6208810F495F495F5ABF8201027E0 +:101D6000481380068810F495F495F5AEF8201030ED +:101D7000700600161206F845105F10E1000480009E +:101D80001005800110048002100680034811F274CF +:101D9000071EF0000005100600E1000480E10004C9 +:101DA000100600E1000C80E1000C881211061004FE +:101DB000F60080044816F6208816F4957710000C7B +:101DC00071E100040013F6ABF820105F6BF8276F89 +:101DD00000017710000CF6AAF820106BF2740E9F29 +:101DE000F495481771E1000C00127710000CF4AA6A +:101DF000F830107C7710000C71E1000B0013F6AB8B +:101E0000F83010B4E730F7AAF83010B4F2740EC10D +:101E1000F49548178812F495F4956C82108D76E14C +:101E20000004000076E100020005F07310B476E1D2 +:101E3000000200047710000C71E1000B0012F5AAFB +:101E4000F820109AF073109C7712000C76000000B6 +:101E50007001001270020017760300014811F2743D +:101E60000CB9F000000576E1000400007710000CCA +:101E700071E1000B0012F6AAF820111C4816F84573 +:101E8000113360E100020005F82010DF10E1000BC3 +:101E900008E1000C11E10004F84D10C76BF8276F42 +:101EA00000018810F495F495F5AEF82010CF48168F +:101EB000F4954808F84511166FE1000C0D0081E11A +:101EC000000C1104F50081044916F5208916F07301 +:101ED000110E10E1000B71E1000C00128810F49556 +:101EE000F495F6AAF83011164912F6208810F495E8 +:101EF000F495F5AEF82010F3481680064808F8452A +:101F000011161004700200178000760300001006FE +:101F100080011005F0740CB9100600E1000C80E19E +:101F2000000C11061004F60080044816F6208816EE +:101F300010E1000C08E1000BF845111CF0731131A1 +:101F4000F2740E9FF4954817F073113376E1000C8C +:101F5000000076E1000B000076E1000200011004B1 +:101F600080001005F074069F8812F495771000FF2A +:101F7000F4AAF83011336C860F70EE088A178A16AF +:101F80008A11FC004A11EEFCF495710600128811CA +:101F90007312000EF166000DF30024008914138102 +:101FA000F77AF330000181F8276013E10001F77C34 +:101FB000F330000381F82761E90F19E1000181F88E +:101FC000276271E400030013F6B84913F30000011F +:101FD000F330000F490B09F82762F84D117577109F +:101FE00000FFF4ABF830117557F8276CF3000001CF +:101FF0004FF8276C76F827630001F073117876F8B4 +:102000002763000070E40003276276F8276400006D +:1020100011F8276161F8000B0002F820118DE90129 +:102020006FE100020F1881F8276411F8276161F849 +:10203000000B0001F82011A910F82764F10000043A +:102040008913E9B8F52081F8276560840002F8203B +:1020500011A9700000117001001370022765F2745D +:102060000F18F4954812EE048A11FC004A114A1622 +:102070004A17EEFCE8004EF82766E8004EF827689D +:10208000E8004EF8276CE8004EF8276A77122740E0 +:1020900077112400771A001FF07211DB7092001183 +:1020A00076E10001FFFF7681000076E1000200008A +:1020B00076E1000300FF76E1000C000076E1000B02 +:1020C000000076E1000400006DE9000DF02025A07D +:1020D000F10000078911F100000181028816F495D2 +:1020E00077170020768600FF760000007601000654 +:1020F0001002F074066C7600000076010006F2749F +:10210000066CF49548111002F000000D80026DE994 +:10211000000D6DEE000D6CEFFFFF11E8F0740C9DEB +:10212000EE048A178A168A11FC004A114A164A17C9 +:10213000EEFA8811100A4911F84D129F4808F84527 +:10214000129F80041281F5788912F495F4956CE25F +:10215000FFB9128A61F800080080F830128A13E192 +:102160000001F0E8F778F1A0F2301FFF8817F4952E +:10217000771224007716000077130020F6B848176E +:1021800008E20001F84512426DEA000D6D966CEB15 +:10219000FFFF1234F073129056F8276AF000000126 +:1021A0004EF8276A60820001F83012547000001661 +:1021B000F2741138F4954811F07312907000001603 +:1021C000F2741138F495481172102A9EF495F4AF08 +:1021D000F830126E76000000760100BC7002001626 +:1021E00076030000F2740CB9F4954811F073129064 +:1021F00010F8276EF844129076000000760100BCBB +:102200007002001676030000F2740CB9F4954811C0 +:10221000F0740C5EF0E0F0101388F842129076F83B +:10222000276E0001F073129056F82766F000000147 +:102230004EF827666DE9005E56F82768F000000149 +:102240004EF82768710400126EEAFFFF121870043E +:102250000012EE068A178A168A11FC004A11EEFE59 +:10226000880EF495F066000DF00025A08811F49515 +:10227000F495768100FF7600000076010006F27486 +:10228000066CF0000001760000007601000648119F +:10229000F274066CF0000007EE028A11FC004A118D +:1022A000880EF495F066000DF00024008811F49576 +:1022B000F49576E10001FFFF7681000076E10002EF +:1022C000000076E1000300FF8A11FC004A11F4953A +:1022D00013038811FA4D12EC71020012F310000181 +:1022E000891AF495F07212EB709100128A11FC00B9 +:1022F000F4954A0B4A0C4A0DF7B8EEFE10F80008A8 +:102300001106F1C08300F4851106F7858106F6B841 +:10231000EC0F1E0661008000F8201305F484EE0225 +:102320008A0D8A0C8A0BFC00F4954A0B4A0C4A0D64 +:10233000EEFEF7B8800010F80008F4851106F78566 +:102340008106F6B8EC0F1E06F0F061008000F82060 +:102350001320F484EE028A0D8A0C8A0BFC004A11C9 +:102360007711007B76812EEC7711007BEEFF718177 +:102370000011EE0176E10001000076E100040000AA +:1023800076E10006000076E10062000076E100766A +:10239000000076E10092000076E10094000076E112 +:1023A00000B0000076E100B3000076E100BE00005E +:1023B00076E100BF000076E100C1000076E100C3D5 +:1023C000000076E100C5000076E100C700007681DC +:1023D00000008A11F495F4E44A114A164A17EEFFF8 +:1023E000F49571060016FB8016A28817F495F7B8CD +:1023F00010F80017F0100002FA4613887711000059 +:1024000010F80017F0100002F84513F910F8001743 +:10241000F845143910F80017F0100001F845141FA2 +:10242000F073145210F80017F0100003F84513D39E +:1024300010F80017F0100006F84414527712007BD1 +:102440007182001461E400070040F830145249140E +:102450004817F6008812F495771300557711005746 +:102460006DEA003BE50110E600068081481400F8A3 +:1024700000178812F4957711005510E20040808112 +:102480007711005710E6000780817711005510E2A0 +:102490000045808110E60008771100578081771190 +:1024A000005510E2004A80817711005710E60009BC +:1024B0008081F2731452771103C07712007B10826F +:1024C000F00000078813F495F495961BF830145229 +:1024D00010E300357712005580827712005710E61E +:1024E000000480827712005510E300378082771253 +:1024F000005710E6000580824811F0400010F2738A +:102500001450F04000207712007B1082F00000078A +:102510008812F495F495960DF830145210E20034B8 +:102520007713005580837713005710E600028083ED +:1025300010E200367712005580827712005710E6BD +:10254000000380824811F0400004F2731450F04000 +:1025500000087712007B1082F00000078812F495C3 +:10256000F495960EF830145210E2003377120055AD +:1025700080827712005710E6000180824811F273C2 +:102580001450F04000027712007B1082F000000728 +:102590008812F495F495960FF830145210E2003238 +:1025A000771200557713005780824811E762F04098 +:1025B0000001E5018811F4957712007B48117182C2 +:1025C00000121AE2000780E20007F980169AEE0175 +:1025D0008A1748118A168A11F4E44A118811770E75 +:1025E000000577120055E804F6B828E10002EEFF76 +:1025F000808277120057F0208000EE011A82771255 +:1026000000578082E80132E10002F5827711005420 +:10261000F693188177110054F2A080818A11F49505 +:10262000F4E44A114A16F49571040011FB8016A2D5 +:102630008816F4957712005510E600038082771211 +:10264000005610E100027713005680827712005680 +:1026500010E10003808210E10004771200568082AE +:102660007712005610E100018082E712E501F9803F +:10267000169A8A168A11F4E44A114A164A17EEF994 +:102680007711007B76000016760100177602001A9B +:102690007603001B7604001C7605001D718100176F +:1026A00071E7000600111081F84414DFF980165319 +:1026B000F6B8FB801585F020FFFFF6B8FB80160802 +:1026C000F020FFFF7711007B7181001776E700068D +:1026D00000014817771600007710000477150003F3 +:1026E0007714000277130001F000003976E7000844 +:1026F000001F76E700070000880E771A00054817CC +:10270000F0000009881248188819E800F072152CAA +:10271000731900117682000011917311001970E293 +:102720000003001670E20004001370E200050014BC +:1027300081E2000170E20006001570E2000700105F +:1027400080E20002730E0011F100001E6DEE000524 +:102750006DEB00056DEC00056DED00056DE8000505 +:10276000F000000181916DEA00087311000EEE0780 +:1027700076E70041002476E70046002576E7004B27 +:10278000002676E7005000278A178A168A11F4E49B +:102790004A114A16EEFE881156064E00F98016A21E +:1027A000F7B810F80011F010FFFFFA451560771622 +:1027B000FFFF7712007B49111082F603F000000939 +:1027C0008811F495F4951081F8441571F273157120 +:1027D000F495E7167711007B1081F000000988114D +:1027E000F495771200061081F845155C6EEAFFFF3C +:1027F00015696DE9000876860001E9015600F1804F +:1028000010F8000BF845157EFB801585F4954816E9 +:10281000F980169AEE0248168A168A11F4E44A11D3 +:10282000EEFFFB8016A28811F4957710FFFFF4A944 +:10283000F83015C410E1000377120055808277123A +:1028400000567682000077120056768200007712DA +:1028500000567682000077120056768200007712CA +:1028600000567682000010E10002F000000832F805 +:10287000000877120054E801F482F493188277126A +:102880000054F0400000808210E10001F9801676CB +:1028900010E10001F9801666F07316037711007BD2 +:1028A0007181001171E1000700127682000010E1D1 +:1028B0000009F98015857711007B7181001110E105 +:1028C0000009FB801585F00000087711007B7181FD +:1028D000001110E10009FB801585F0000010771150 +:1028E000007B7181001110E10009FB801585F0006B +:1028F00000187711007B7181001110E10009FB8045 +:102900001585F00000207711007B7181001110E126 +:102910000009FB801585F0000028F980169AEE0169 +:102920008A11F4E44A11EEFFFB8016A28811F49597 +:102930007710FFFFF4A9F830164177110055768122 +:10294000001E7711005676810000771100567681BF +:1029500000007711005676810000771100567681CD +:1029600000007711005676810000771100567681BD +:1029700000007711005676810000771100567681AD +:102980000000771100567681000077110056F2732F +:10299000164E768100007711007B7181001171E184 +:1029A000000700127682000010E10039F980160855 +:1029B000F980169AEE018A11F4E44A117711007B2E +:1029C0001081F00000048811F495F4951081FA4408 +:1029D0001663F495EEFF76810001EE018A11F4E4AE +:1029E000F01000104A1132F80008EEFF77110001D4 +:1029F000E801EE01F4821A8180818A11F495F4E4F1 +:102A0000F01000104A1132F80008EEFFE8017711CB +:102A10000000F482EE01F493188180818A11F4950C +:102A2000F4E44A11F01000107711000032F80008A9 +:102A3000EEFF1181E801EE0177110000F482F2A0AF +:102A400080818A11F495F4E4F273169EF6BBF49536 +:102A5000F495F495F495F4E4F27316A6F7BBF495A7 +:102A6000F495F495F495F4E44A114A16F49571043A +:102A70000016FB8016A28811F49571E10005001282 +:102A80007682000E10E6000E71E1000600128082D0 +:102A900071E1000500127682000D71E1000600125E +:102AA00010E6000D808271E1000500127682000CB4 +:102AB00010E6000C71E100060012808271E1000551 +:102AC00000127682000B10E6000B71E10006001286 +:102AD000808271E1000500127682000A71E1000631 +:102AE000001210E6000A808271E100050012768271 +:102AF000000910E6000971E100060012808271E110 +:102B0000000500127682000871E10006001210E64E +:102B10000008808271E1000500127682000710E64D +:102B2000000771E100060012808271E100050012C9 +:102B30007682000671E10006001210E6000680822F +:102B400071E1000500127682000571E100060012B5 +:102B500010E60005808271E1000500127682000413 +:102B600071E10006001210E60004808271E10005A8 +:102B700000127682000371E10006001210E60003E5 +:102B8000808271E1000500127682000210E60002E8 +:102B900071E100060012808271E100050012768268 +:102BA000000110E6000171E100060012808271E16F +:102BB000000500127682000071E100060013E76252 +:102BC000E501F980169A8A168A11F4E44A118811EF +:102BD000F495F49571E100050012EEFF7682000095 +:102BE000EE0171E100060011698100018A11F4957E +:102BF000F4E44A118811F495F49571E1000500128E +:102C0000EEFF76820001EE0171E10006001169819C +:102C100000018A11F495F4E44A117711007B1081C8 +:102C2000F00000948811F495F4951081FA44179CF3 +:102C3000F495EEFFF98016537711007B1081F000B8 +:102C400000948811F495F49576810001EE0176E107 +:102C50000001000076E10002002176E1000300207F +:102C600076E10004002376E10005002276E100060B +:102C7000003876E10007003976E10008001576E1BA +:102C80000009001476E1000A000076E1000B004123 +:102C900076E1000C004076E1000D004376E1000E85 +:102CA000004276E1000F004876E10010004976E12D +:102CB0000011001B76E10012001A8A11F495F4E469 +:102CC0004A11EEFD881156064E00F98016A27712C1 +:102CD000007B770E0009108228F80011F0000095A3 +:102CE0008811F495F4951081F84517F0F27317FDEB +:102CF0007711FFFF76810001E9015600F18010F89D +:102D0000000BF84517FDFB801810F4954811F98069 +:102D1000169AEE0348118A11F495F4E44A118811C9 +:102D2000F495EEFF71E100010011EE0110818A11AE +:102D3000F495F4E44A11EEFFFB8016A28811F49595 +:102D40007710FFFFF4A9F83018C371E100050012F5 +:102D50007682000071E1000600127682000071E1C7 +:102D6000000500127682000171E1000600127682F1 +:102D7000000071E1000500127682000271E1000698 +:102D800000127682000071E10005001276820003D5 +:102D900071E1000600127682000071E10005001268 +:102DA0007682000471E1000600127682000071E173 +:102DB000000500127682000571E10006001276829D +:102DC000000071E1000500127682000671E1000644 +:102DD00000127682000171E1000500127682000780 +:102DE00071E1000600127682200071E100050012F8 +:102DF0007682000871E1000600127682000071E11F +:102E0000000500127682000971E100060012768248 +:102E1000000071E1000500127682000A71E10006EF +:102E200000127682000071E1000500127682000B2C +:102E300071E1000600127682000071E100050012C7 +:102E40007682000C71E1000600127682000071E1CA +:102E5000000500127682000D71E1000600127682F4 +:102E6000000071E1000500127682000E71E100069B +:102E700000127682000010E10007F980167610E15A +:102E80000008F980167610E10007F980166610E157 +:102E90000008F9801666F07318D17711007B108155 +:102EA000FB801810F00000957711007B1081FB80EB +:102EB0001810F000009EF980169AEE018A11F4E4D1 +:102EC0004A118811EEFFF495100471E1000300111E +:102ED000EE0180818A11F495F4E44A114A16F495C2 +:102EE00071040016FB8016A28811F49571E10002AE +:102EF00000127682001010E6000171E1000300125A +:102F0000808271E10004001210E600028082E76214 +:102F100071E100020013E501F980169A8A168A1100 +:102F2000F4E44A118811EEFFEE0110E100018A116C +:102F3000F495F4E44A117711007B1081F00000B39E +:102F40008811F495F4951081FA44192AF495EEFF4E +:102F5000F98016537711007B1081F00000B38811BF +:102F6000F495F49576810001EE0176E10001000010 +:102F700076E10002001376E10003002676E100040A +:102F8000002576E10005002476E10006000076E1E8 +:102F90000007001776E10008003276E100090031F1 +:102FA00076E1000A00308A11F495F4E44A114A16D9 +:102FB0004A17EEFFF49571060017FB8016A28811E0 +:102FC000F495F7B810F80011F010FFFFFA451973E7 +:102FD0007716FFFF7712007B770E0005108228F826 +:102FE0000011F00000B48811F495F4951081F844B4 +:102FF0001984F2731984F495E7167711007B108118 +:10300000F00000B48811F495771200021081F845A1 +:10301000196F6EEAFFFF197C6DE9000561F8001772 +:103020000001FA20198F76860001FB801997F4952C +:103030004816F980169AEE018A1748168A168A11E0 +:10304000F4E44A11EEFFFB8016A28811F495771084 +:10305000FFFFF4A9F83019CC71E100020012698277 +:10306000001071E1000200126882F7FF71E10002B6 +:1030700000126882FBFF71E1000200126882FFF01B +:1030800071E1000300127682FFFF71E1000400127B +:103090007682FFFF71E1000200126982002071E177 +:1030A00000020011F27319DA6881FFEF7711007BDB +:1030B0001081FB801997F00000B47711007B10811C +:1030C000FB801997F00000B9F980169AEE018A1179 +:1030D000F4E400A4000019DF00012AE6000000016A +:1030E0002AE7000000032A120C01C34F0000000170 +:1030F0002A15000000022A160000000000192A5DAF +:103100000043006F0070007900720069006700687A +:10311000007400200054006500630068006E006FBA +:10312000005400720065006E0064002000410047FA +:10313000000000042A760030002E00300000000C51 +:103140002A7A004600650062002000320037002025 +:103150000032003000300031000000092A860031C2 +:103160000034003A00330035003A003300330000E9 +:10317000000F2A8F00000000000000010000000185 +:10318000000000000000000000000000000000003F +:10319000000000012A9E000000012A9F000000019B +:1031A0002AA0000000012AA1000000012AA20000BC +:1031B0000001297E000000022980000000000001BB +:1031C0002982FFFF00012AA7000000052AA87141FB +:1031D0002000200000230400000A2AAD00000000A7 +:1031E00000000000000000000000000000000000DF +:1031F000000F2AB7000000000000004000A082403D +:103200000008307F00800180000000000000000006 +:1032100000000001276E00000001276F0000000081 +:10322000000900001A8304E804CF04C504BA04B0FE +:1032300004AC049C048C0481007800000100F2734B +:1032400007EFF495F495F27307EFF495F495F273A4 +:1032500007EFF495F495F27307EFF495F495F27394 +:1032600007EFF495F495F27307EFF495F495F27384 +:1032700007EFF495F495F27307EFF495F495F27374 +:1032800007EFF495F495F27307EFF495F495F27364 +:1032900007EFF495F495F27307EFF495F495F27354 +:1032A00007EFF495F495F27307EFF495F495F27344 +:1032B00007EFF495F495F27307EFF495F495F27334 +:1032C00007AAF495F495F27307EFF495F495F27369 +:1032D00007EFF495F495F2730223F495F495F273E5 +:1032E00007EFF495F495F27307EFF495F495F27304 +:1032F00007EFF495F495F27307EFF495F495F273F4 +:1033000007EFF495F495F27307EFF495F495F273E3 +:1033100005E5F495F495F27302B5F495F495F2731E +:103320000E33F495F495F27307EFF495F4950000DD +:00000001FF -- cgit v0.10.2 From 2971c579f93bcff26744672ea98c13bef71ded97 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 14:04:03 +0300 Subject: keyspan: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 9ba64cc..9a7681b 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -304,19 +304,19 @@ config USB_SERIAL_KEYSPAN config USB_SERIAL_KEYSPAN_MPR bool "USB Keyspan MPR Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the Keyspan MPR converter. config USB_SERIAL_KEYSPAN_USA28 bool "USB Keyspan USA-28 Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-28 converter. config USB_SERIAL_KEYSPAN_USA28X bool "USB Keyspan USA-28X Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-28X converter. Be sure you have a USA-28X, there are also 28XA and 28XB @@ -324,7 +324,7 @@ config USB_SERIAL_KEYSPAN_USA28X config USB_SERIAL_KEYSPAN_USA28XA bool "USB Keyspan USA-28XA Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-28XA converter. Be sure you have a USA-28XA, there are also 28X and 28XB @@ -332,7 +332,7 @@ config USB_SERIAL_KEYSPAN_USA28XA config USB_SERIAL_KEYSPAN_USA28XB bool "USB Keyspan USA-28XB Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-28XB converter. Be sure you have a USA-28XB, there are also 28X and 28XA @@ -340,43 +340,43 @@ config USB_SERIAL_KEYSPAN_USA28XB config USB_SERIAL_KEYSPAN_USA19 bool "USB Keyspan USA-19 Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-19 converter. config USB_SERIAL_KEYSPAN_USA18X bool "USB Keyspan USA-18X Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-18X converter. config USB_SERIAL_KEYSPAN_USA19W bool "USB Keyspan USA-19W Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-19W converter. config USB_SERIAL_KEYSPAN_USA19QW bool "USB Keyspan USA-19QW Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-19QW converter. config USB_SERIAL_KEYSPAN_USA19QI bool "USB Keyspan USA-19QI Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-19QI converter. config USB_SERIAL_KEYSPAN_USA49W bool "USB Keyspan USA-49W Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-49W converter. config USB_SERIAL_KEYSPAN_USA49WLC bool "USB Keyspan USA-49WLC Firmware" - depends on USB_SERIAL_KEYSPAN + depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL help Say Y here to include firmware for the USA-49WLC converter. diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 3df8a66..11e439b 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -105,6 +105,8 @@ #include #include #include +#include +#include #include #include #include @@ -1339,13 +1341,13 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp) port->tty = NULL; } - /* download the firmware to a pre-renumeration device */ static int keyspan_fake_startup (struct usb_serial *serial) { int response; - const struct ezusb_hex_record *record; + const struct ihex_binrec *record; char *fw_name; + const struct firmware *fw; dbg("Keyspan startup version %04x product %04x", le16_to_cpu(serial->dev->descriptor.bcdDevice), @@ -1359,72 +1361,60 @@ static int keyspan_fake_startup (struct usb_serial *serial) /* Select firmware image on the basis of idProduct */ switch (le16_to_cpu(serial->dev->descriptor.idProduct)) { case keyspan_usa28_pre_product_id: - record = &keyspan_usa28_firmware[0]; - fw_name = "USA28"; + fw_name = "keyspan/usa28.fw"; break; case keyspan_usa28x_pre_product_id: - record = &keyspan_usa28x_firmware[0]; - fw_name = "USA28X"; + fw_name = "keyspan/usa28x.fw"; break; case keyspan_usa28xa_pre_product_id: - record = &keyspan_usa28xa_firmware[0]; - fw_name = "USA28XA"; + fw_name = "keyspan/usa28xa.fw"; break; case keyspan_usa28xb_pre_product_id: - record = &keyspan_usa28xb_firmware[0]; - fw_name = "USA28XB"; + fw_name = "keyspan/usa28xb.fw"; break; case keyspan_usa19_pre_product_id: - record = &keyspan_usa19_firmware[0]; - fw_name = "USA19"; + fw_name = "keyspan/usa19.fw"; break; case keyspan_usa19qi_pre_product_id: - record = &keyspan_usa19qi_firmware[0]; - fw_name = "USA19QI"; + fw_name = "keyspan/usa19qi.fw"; break; case keyspan_mpr_pre_product_id: - record = &keyspan_mpr_firmware[0]; - fw_name = "MPR"; + fw_name = "keyspan/mpr.fw"; break; case keyspan_usa19qw_pre_product_id: - record = &keyspan_usa19qw_firmware[0]; - fw_name = "USA19QI"; + fw_name = "keyspan/usa19qw.fw"; break; case keyspan_usa18x_pre_product_id: - record = &keyspan_usa18x_firmware[0]; - fw_name = "USA18X"; + fw_name = "keyspan/usa18x.fw"; break; case keyspan_usa19w_pre_product_id: - record = &keyspan_usa19w_firmware[0]; - fw_name = "USA19W"; + fw_name = "keyspan/usa19w.fw"; break; case keyspan_usa49w_pre_product_id: - record = &keyspan_usa49w_firmware[0]; - fw_name = "USA49W"; + fw_name = "keyspan/usa49w.fw"; break; case keyspan_usa49wlc_pre_product_id: - record = &keyspan_usa49wlc_firmware[0]; - fw_name = "USA49WLC"; + fw_name = "keyspan/usa49wlc.fw"; break; default: - record = NULL; - fw_name = "Unknown"; - break; + dev_err(&serial->dev->dev, "Unknown product ID (%04x)\n", + le16_to_cpu(serial->dev->descriptor.idProduct)); + return 1; } - if (record == NULL) { + if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name); return(1); } @@ -1434,19 +1424,22 @@ static int keyspan_fake_startup (struct usb_serial *serial) /* download the firmware image */ response = ezusb_set_reset(serial, 1); - while(record->address != 0xffff) { - response = ezusb_writememory(serial, record->address, + record = (const struct ihex_binrec *)fw->data; + + while (record) { + response = ezusb_writememory(serial, be32_to_cpu(record->addr), (unsigned char *)record->data, - record->data_size, 0xa0); + be16_to_cpu(record->len), 0xa0); if (response < 0) { dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan" "firmware (%d %04X %p %d)\n", - response, - record->address, record->data, record->data_size); + response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } - record++; + record = ihex_next_binrec(record); } + release_firmware(fw); /* bring device out of reset. Renumeration will occur in a moment and the new device will bind to the real driver */ response = ezusb_set_reset(serial, 0); @@ -2756,6 +2749,19 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("keyspan/usa28.fw"); +MODULE_FIRMWARE("keyspan/usa28x.fw"); +MODULE_FIRMWARE("keyspan/usa28xa.fw"); +MODULE_FIRMWARE("keyspan/usa28xb.fw"); +MODULE_FIRMWARE("keyspan/usa19.fw"); +MODULE_FIRMWARE("keyspan/usa19qi.fw"); +MODULE_FIRMWARE("keyspan/mpr.fw"); +MODULE_FIRMWARE("keyspan/usa19qw.fw"); +MODULE_FIRMWARE("keyspan/usa18x.fw"); +MODULE_FIRMWARE("keyspan/usa19w.fw"); +MODULE_FIRMWARE("keyspan/usa49w.fw"); +MODULE_FIRMWARE("keyspan/usa49wlc.fw"); + module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 8d6ed02..b52fb65 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -103,90 +103,6 @@ static int keyspan_usa67_send_setup (struct usb_serial *serial, struct usb_serial_port *port, int reset_port); -/* Struct used for firmware - increased size of data section - to allow Keyspan's 'C' firmware struct to be used unmodified */ -struct ezusb_hex_record { - __u16 address; - __u8 data_size; - __u8 data[64]; -}; - -/* Conditionally include firmware images, if they aren't - included create a null pointer instead. Current - firmware images aren't optimised to remove duplicate - addresses in the image itself. */ -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28 - #include "keyspan_usa28_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa28_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28X - #include "keyspan_usa28x_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa28x_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28XA - #include "keyspan_usa28xa_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa28xa_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28XB - #include "keyspan_usa28xb_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa28xb_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19 - #include "keyspan_usa19_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa19_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19QI - #include "keyspan_usa19qi_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa19qi_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_MPR - #include "keyspan_mpr_fw.h" -#else - static const struct ezusb_hex_record *keyspan_mpr_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19QW - #include "keyspan_usa19qw_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa19qw_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA18X - #include "keyspan_usa18x_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa18x_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19W - #include "keyspan_usa19w_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa19w_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49W - #include "keyspan_usa49w_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa49w_firmware = NULL; -#endif - -#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49WLC - #include "keyspan_usa49wlc_fw.h" -#else - static const struct ezusb_hex_record *keyspan_usa49wlc_firmware = NULL; -#endif - /* Values used for baud rate calculation - device specific */ #define KEYSPAN_INVALID_BAUD_RATE (-1) #define KEYSPAN_BAUD_RATE_OK (0) diff --git a/drivers/usb/serial/keyspan_mpr_fw.h b/drivers/usb/serial/keyspan_mpr_fw.h deleted file mode 100644 index 238805e..0000000 --- a/drivers/usb/serial/keyspan_mpr_fw.h +++ /dev/null @@ -1,286 +0,0 @@ -/* keyspan_mpr_fw.h - - The firmware contained herein as keyspan_mpr_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -static char theFirmwareDate53[] = - "04/26/2002 02:47p 11,570 USA53"; -*/ - -static const struct ezusb_hex_record keyspan_mpr_firmware[] = { - {0x0033, 3, { 0x02, 0x00, 0x1a}}, - {0x001a, 4, { 0x53, 0xd8, 0xef, 0x32}}, - {0x0003, 16, { 0x8e, 0x56, 0x8f, 0x57, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60}}, - {0x0013, 7, { 0x05, 0x12, 0x0f, 0xa2, 0x80, 0xee, 0x22}}, - {0x0023, 3, { 0x02, 0x00, 0x46}}, - {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}}, - {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x0b, 0x07, 0xa2, 0x0e, 0x92, 0x9b, 0x85, 0x36, 0x99, 0xc2, 0x99, 0xd2}}, - {0x0066, 16, { 0x12, 0x20, 0x12, 0x03, 0x02, 0x02, 0xf9, 0xc2, 0x12, 0x30, 0x03, 0x19, 0x7e, 0x7e, 0x7f, 0x40}}, - {0x0076, 16, { 0x75, 0x1a, 0x7e, 0x75, 0x1b, 0x40, 0x75, 0x17, 0x00, 0x7e, 0x7d, 0x7f, 0xc0, 0x75, 0x18, 0x7d}}, - {0x0086, 16, { 0x75, 0x19, 0xc0, 0x80, 0x17, 0x7e, 0x7d, 0x7f, 0xc0, 0x75, 0x1a, 0x7d, 0x75, 0x1b, 0xc0, 0x75}}, - {0x0096, 16, { 0x17, 0x01, 0x7e, 0x7e, 0x7f, 0x40, 0x75, 0x18, 0x7e, 0x75, 0x19, 0x40, 0x20, 0x0b, 0x03, 0x02}}, - {0x00a6, 16, { 0x01, 0x84, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x3c, 0x20, 0x0c, 0x34, 0x20, 0x09, 0x31, 0x90}}, - {0x00b6, 16, { 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x29, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b}}, - {0x00c6, 16, { 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a}}, - {0x00d6, 16, { 0xe5, 0x1b, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0x02, 0x02, 0xf7}}, - {0x00e6, 16, { 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0x30, 0x03, 0x11, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xa3, 0xe0, 0x54}}, - {0x00f6, 16, { 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0x80, 0x11, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0x90, 0x7f}}, - {0x0043, 3, { 0x02, 0x0f, 0x00}}, - {0x0000, 3, { 0x02, 0x00, 0x26}}, - {0x0026, 12, { 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5a, 0x02, 0x0a, 0x33}}, - {0x0106, 64, { 0xc6, 0xe0, 0x54, 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0xe5, 0x17, 0x24, 0xff, 0x92, 0x03, 0x30, - 0x0d, 0x0d, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0xe5, - 0x1d, 0x60, 0x05, 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0x85, 0x1c, 0x53, 0x85, 0x19, 0x82, 0x85, 0x18, - 0x83, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x12, 0xff, 0x20, 0x0c, 0x3a, 0x20, 0x09, 0x37, 0x90}}, - {0x0146, 64, { 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x2f, 0x30, 0x10, 0x1c, 0x85, 0x19, 0x82, 0x85, 0x18, 0x83, 0xa3, - 0xe0, 0x13, 0x92, 0x0e, 0x85, 0x19, 0x82, 0x85, 0x18, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x36, 0x75, - 0x3a, 0x03, 0x02, 0x02, 0xf7, 0x75, 0x3a, 0x02, 0x85, 0x19, 0x82, 0x85, 0x18, 0x83, 0xa3, 0xe0, - 0xf5, 0x36, 0x02, 0x02, 0xf7, 0x75, 0x3a, 0x01, 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0x30, 0x03}}, - {0x0186, 64, { 0x0e, 0x90, 0x7f, 0xc6, 0xe0, 0x54, 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0x80, 0x0c, 0x90, 0x7f, - 0xc8, 0xe0, 0x54, 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, - 0x03, 0x02, 0x02, 0x68, 0xe5, 0x1d, 0x60, 0x07, 0xc2, 0x14, 0xc2, 0x05, 0x02, 0x02, 0xf7, 0x85, - 0x1c, 0x53, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x12, 0xff}}, - {0x01c6, 64, { 0x30, 0x0c, 0x03, 0x02, 0x02, 0x60, 0x30, 0x09, 0x03, 0x02, 0x02, 0x60, 0x90, 0x7f, 0x9b, 0xe0, 0x55, - 0x38, 0x60, 0x03, 0x02, 0x02, 0x60, 0x30, 0x10, 0x1b, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xa3, - 0xe0, 0x13, 0x92, 0x9b, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x99, 0x75, - 0x3a, 0x03, 0x80, 0x0d, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xa3, 0xe0, 0xf5, 0x99, 0x75}}, - {0x0206, 64, { 0x3a, 0x02, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x40, 0x26, 0x30, 0x03, 0x07, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, - 0x80, 0x05, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xe5, 0x17, 0x24, 0xff, 0x92, 0x03, 0x20, 0x0d, 0x03, - 0x02, 0x02, 0xf7, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0x02, 0x02, 0xf7, 0x30, 0x10, - 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83}}, - {0x0246, 64, { 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, - 0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b, 0x02, 0x02, 0xf7, 0x75, 0x3a, 0x01, 0xc2, 0x14, 0x02, 0x02, - 0xf7, 0x30, 0x0c, 0x03, 0x02, 0x02, 0xf5, 0x30, 0x09, 0x03, 0x02, 0x02, 0xf5, 0x90, 0x7f, 0x9b, - 0xe0, 0x55, 0x38, 0x70, 0x79, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f}}, - {0x0286, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, - 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x3a, 0xc3, 0x95, 0x53, - 0x40, 0x22, 0x30, 0x03, 0x07, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xc9, 0xe4, - 0xf0, 0xe5, 0x17, 0x24, 0xff, 0x92, 0x03, 0x30, 0x0d, 0x36, 0xc2, 0x0d, 0x90, 0x7f, 0xbb}}, - {0x02c6, 64, { 0x74, 0x01, 0xf0, 0x80, 0x2c, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, 0xf5, 0x82, - 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, - 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b, 0x80, 0x02, 0xc2, 0x14, - 0xd2, 0x01, 0x20, 0x98, 0x03, 0x02, 0x04, 0x35, 0xc2, 0x98, 0x20, 0x02, 0x03, 0x02, 0x03}}, - {0x0306, 64, { 0xa2, 0x20, 0x15, 0x27, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, - 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x10, 0x4d, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, - 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99, 0x55, 0xe5, 0x55, 0xb5, - 0x47, 0x04, 0xd2, 0x09, 0x80, 0x2e, 0xe5, 0x55, 0xb5, 0x46, 0x04, 0xc2, 0x09, 0x80, 0x25}}, - {0x0346, 64, { 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x55, 0xf0, - 0x30, 0x10, 0x11, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, - 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0f, 0xe5, 0x39, 0xc3, 0x95, 0x43, 0x50, 0x03, 0x02, 0x04, 0x33, - 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x16, 0xe5, 0x39, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02}}, - {0x0386, 64, { 0x04, 0x33, 0x15, 0x39, 0x15, 0x39, 0x05, 0x2b, 0x43, 0x34, 0x01, 0x02, 0x04, 0x33, 0x90, 0x7f, 0xb7, - 0xe5, 0x39, 0xf0, 0x75, 0x39, 0x00, 0xc2, 0x02, 0x02, 0x04, 0x33, 0x20, 0x15, 0x27, 0xaf, 0x39, - 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, - 0x10, 0x4d, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5}}, - {0x03c6, 64, { 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99, 0x55, 0xe5, 0x55, 0xb5, 0x47, 0x04, 0xd2, 0x09, 0x80, - 0x2e, 0xe5, 0x55, 0xb5, 0x46, 0x04, 0xc2, 0x09, 0x80, 0x25, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, - 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x55, 0xf0, 0x30, 0x10, 0x11, 0xaf, 0x39, - 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0}}, - {0x0406, 64, { 0xd2, 0x0f, 0xe5, 0x39, 0xc3, 0x95, 0x43, 0x40, 0x24, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x12, 0xe5, - 0x39, 0xc3, 0x94, 0x40, 0x40, 0x16, 0x15, 0x39, 0x15, 0x39, 0x05, 0x2b, 0x43, 0x34, 0x01, 0x80, - 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x39, 0xf0, 0x75, 0x39, 0x00, 0xd2, 0x02, 0xd2, 0x01, 0x30, 0x01, - 0x05, 0xc2, 0x01, 0x02, 0x00, 0x56, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0}}, - {0x0446, 64, { 0xe0, 0x32, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x54, 0xe5, 0x34, 0x60, 0x50, 0xe5, 0x31, 0x70, 0x4c, - 0xe5, 0x34, 0x30, 0xe1, 0x0b, 0xe4, 0xf5, 0x2f, 0x75, 0x34, 0x01, 0x75, 0x31, 0x02, 0x80, 0x0e, - 0xa2, 0x08, 0xe4, 0x33, 0xf5, 0x2f, 0xc2, 0x08, 0xe4, 0xf5, 0x34, 0x75, 0x31, 0x10, 0xe4, 0xf5, - 0x56, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x56, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12}}, - {0x0486, 64, { 0x0c, 0x79, 0xff, 0x74, 0x00, 0x25, 0x56, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x05, - 0x56, 0xe5, 0x56, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xbd, 0x74, 0x0c, 0xf0, 0x90, 0x7f, 0xca, 0xe0, - 0x30, 0xe1, 0x03, 0x02, 0x05, 0xd1, 0xe4, 0xf5, 0x56, 0x74, 0x40, 0x25, 0x56, 0xf5, 0x82, 0xe4, - 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x56, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x3b, 0xf9}}, - {0x04c6, 64, { 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x0c, 0x92, 0x05, 0x56, 0xe5, 0x56, 0xb4, 0x18, 0xdb, 0xe5, 0x3b, - 0x60, 0x11, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x36, 0x85, 0x3c, 0xca, 0x85, 0x3d, 0xcb, 0xe4, 0x90, - 0x7f, 0x9f, 0xf0, 0xe5, 0x3e, 0x13, 0x92, 0x10, 0x92, 0x9f, 0x85, 0x3f, 0x38, 0xe5, 0x40, 0x13, - 0x92, 0x15, 0xe5, 0x41, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07}}, - {0x0506, 64, { 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x42, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f, - 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x48, 0x60, 0x0b, 0xc2, 0x0c, - 0xc2, 0x09, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x49, 0x60, 0x0c, 0xd2, 0x09, 0x43, - 0x34, 0x01, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x4a, 0x60, 0x0d, 0xc2, 0xaf}}, - {0x0546, 64, { 0xc2, 0x0b, 0xd2, 0x00, 0xe4, 0xf5, 0x53, 0xf5, 0x3a, 0xd2, 0xaf, 0xe5, 0x4b, 0x60, 0x05, 0x30, 0x15, - 0x02, 0xd2, 0x09, 0xe5, 0x4c, 0x60, 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, - 0x9e, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x4d, 0x60, 0x0a, - 0xd2, 0x9c, 0xc2, 0x98, 0x75, 0x2c, 0x01, 0x75, 0x31, 0x1e, 0xe5, 0x4e, 0x60, 0x07, 0xc2}}, - {0x0586, 64, { 0x9c, 0xe4, 0xf5, 0x39, 0xf5, 0x2c, 0xe5, 0x4f, 0x60, 0x03, 0xe4, 0xf5, 0x39, 0xe5, 0x50, 0x60, 0x02, - 0xd2, 0x07, 0xe5, 0x51, 0x60, 0x0a, 0xe5, 0x4d, 0x70, 0x02, 0xf5, 0x31, 0xe5, 0x51, 0x42, 0x34, - 0xe5, 0x52, 0x60, 0x1f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, - 0x74, 0x32, 0xf0, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0}}, - {0x05c6, 64, { 0xd2, 0x03, 0xd2, 0x02, 0xd2, 0x08, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0xa2, 0x0c, 0xe4, 0x33, 0xff, 0x65, - 0x29, 0x60, 0x05, 0x8f, 0x29, 0x43, 0x34, 0x01, 0xa2, 0x09, 0xe4, 0x33, 0xff, 0x65, 0x2a, 0x60, - 0x05, 0x8f, 0x2a, 0x43, 0x34, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0xff, 0x54, 0x08, 0x64, 0x08, 0xf5, - 0x57, 0x65, 0x25, 0x60, 0x06, 0x85, 0x57, 0x25, 0x43, 0x34, 0x01, 0xef, 0x54, 0x10, 0x64}}, - {0x0606, 64, { 0x10, 0xf5, 0x57, 0x65, 0x26, 0x60, 0x06, 0x85, 0x57, 0x26, 0x43, 0x34, 0x01, 0xef, 0x54, 0x40, 0x64, - 0x40, 0xf5, 0x57, 0x65, 0x27, 0x60, 0x06, 0x85, 0x57, 0x27, 0x43, 0x34, 0x01, 0xef, 0x54, 0x20, - 0x64, 0x20, 0xf5, 0x57, 0x65, 0x28, 0x60, 0x06, 0x85, 0x57, 0x28, 0x43, 0x34, 0x01, 0x90, 0x7f, - 0x9a, 0xe0, 0x54, 0x40, 0x64, 0x40, 0xf5, 0x57, 0x65, 0x2e, 0x60, 0x06, 0x85, 0x57, 0x2e}}, - {0x0646, 64, { 0x43, 0x34, 0x01, 0x30, 0x07, 0x35, 0xc2, 0xaf, 0x30, 0x02, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, - 0x27, 0xe5, 0x39, 0x60, 0x09, 0x90, 0x7f, 0xb7, 0xf0, 0xe4, 0xf5, 0x39, 0xc2, 0x02, 0xc2, 0x07, - 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x39, 0x60, 0x09, 0x90, 0x7f, 0xb9, - 0xf0, 0xe4, 0xf5, 0x39, 0xd2, 0x02, 0xc2, 0x07, 0xd2, 0xaf, 0x20, 0x05, 0x3d, 0x30, 0x03}}, - {0x0686, 64, { 0x1e, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x33, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x3a, - 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x53, 0xd2, 0x05, 0x75, 0x12, 0xff, 0x80, 0x1c, 0x90, 0x7f, - 0xc8, 0xe0, 0x20, 0xe1, 0x15, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x3a, 0x01, 0x90, - 0x7f, 0xc9, 0xe0, 0xf5, 0x53, 0xd2, 0x05, 0x75, 0x12, 0xff, 0x20, 0x14, 0x33, 0x20, 0x00}}, - {0x06c6, 64, { 0x06, 0xe5, 0x3a, 0x65, 0x53, 0x70, 0x2a, 0x30, 0x05, 0x1a, 0x30, 0x03, 0x09, 0xe4, 0x90, 0x7f, 0xc7, - 0xf0, 0xc2, 0x03, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0xc2, 0x05, 0xe4, 0xf5, - 0x53, 0xf5, 0x3a, 0x30, 0x0d, 0x0a, 0xc2, 0x0d, 0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, - 0x30, 0x14, 0x03, 0x02, 0x07, 0xbf, 0x20, 0x05, 0x03, 0x02, 0x07, 0xbf, 0x30, 0x0c, 0x03}}, - {0x0706, 64, { 0x02, 0x07, 0xbf, 0x30, 0x09, 0x03, 0x02, 0x07, 0xbf, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x60, 0x03, - 0x02, 0x07, 0xbf, 0x30, 0x03, 0x0c, 0x7e, 0x7e, 0x7f, 0x40, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x40, - 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0xc0, 0x75, 0x58, 0x7d, 0x75, 0x59, 0xc0, 0x30, 0x10, 0x12, 0xaf, - 0x3a, 0x05, 0x3a, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0x13}}, - {0x0746, 64, { 0x92, 0x1a, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, - 0xf5, 0x57, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x2a, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, - 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, - 0x05, 0x3a, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0xf5, 0x36}}, - {0x0786, 64, { 0xd2, 0x0b, 0x80, 0x15, 0xc2, 0x0b, 0x30, 0x03, 0x09, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80, - 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0x30, 0x10, 0x04, 0xa2, 0x1a, 0x92, 0x9b, 0xd2, - 0x14, 0xc2, 0xaf, 0x85, 0x57, 0x99, 0x20, 0x0b, 0x0d, 0x30, 0x0d, 0x0a, 0xc2, 0x0d, 0xc2, 0x00, - 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0c}}, - {0x07c6, 64, { 0xa4, 0x09, 0x1c, 0x00, 0x09, 0x89, 0x01, 0x09, 0xe6, 0x03, 0x07, 0xe3, 0x06, 0x09, 0x0d, 0x08, 0x09, - 0x01, 0x09, 0x08, 0xe9, 0x0a, 0x08, 0xf8, 0x0b, 0x00, 0x00, 0x0a, 0x24, 0x90, 0x7f, 0xeb, 0xe0, - 0x24, 0xfe, 0x60, 0x1c, 0x14, 0x70, 0x03, 0x02, 0x08, 0x79, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0a, - 0x24, 0x74, 0x0d, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x87, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0a}}, - {0x0806, 64, { 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0xd8, - 0x75, 0x83, 0x0d, 0xef, 0xf0, 0x75, 0x82, 0xd1, 0x75, 0x83, 0x0d, 0xf0, 0x75, 0x82, 0xca, 0x75, - 0x83, 0x0d, 0xf0, 0x75, 0x82, 0xc3, 0x75, 0x83, 0x0d, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, - 0x82, 0x9e, 0x75, 0x83, 0x0d, 0xf0, 0x90, 0x7f, 0xef, 0xe0, 0xfe, 0x90, 0x7f, 0xee, 0xe0}}, - {0x0846, 64, { 0x7c, 0x00, 0x24, 0x00, 0xf5, 0x5a, 0xec, 0x3e, 0xf5, 0x59, 0x75, 0x15, 0x0d, 0x75, 0x16, 0x99, 0x75, - 0x82, 0x9b, 0x75, 0x83, 0x0d, 0xe0, 0x75, 0x13, 0x00, 0xf5, 0x14, 0xd3, 0xe5, 0x14, 0x95, 0x5a, - 0xe5, 0x13, 0x95, 0x59, 0x40, 0x06, 0x85, 0x59, 0x13, 0x85, 0x5a, 0x14, 0x12, 0x0b, 0xba, 0x02, - 0x0a, 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x0b, 0x75, 0x56, 0xff, 0x75, 0x57, 0x0d, 0x75}}, - {0x0886, 64, { 0x58, 0xdc, 0x80, 0x2d, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x0b, 0x75, 0x56, 0xff, 0x75, 0x57, 0x0d, - 0x75, 0x58, 0xe0, 0x80, 0x1b, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x02, 0x0b, 0x75, 0x56, 0xff, 0x75, - 0x57, 0x0d, 0x75, 0x58, 0xf0, 0x80, 0x09, 0x75, 0x56, 0xff, 0x75, 0x57, 0x0e, 0x75, 0x58, 0x1e, - 0x90, 0x7f, 0xee, 0xe0, 0x75, 0x59, 0x00, 0xf5, 0x5a, 0xae, 0x57, 0xaf, 0x58, 0x8e, 0x15}}, - {0x08c6, 64, { 0x8f, 0x16, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x13, 0xf5, 0x14, 0xd3, 0x95, 0x5a, - 0xe5, 0x13, 0x95, 0x59, 0x40, 0x06, 0x85, 0x59, 0x13, 0x85, 0x5a, 0x14, 0x12, 0x0b, 0xba, 0x02, - 0x0a, 0x2b, 0x90, 0x7f, 0x00, 0xe5, 0x11, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0a, - 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x11, 0x02, 0x0a, 0x2b, 0x12, 0x0c, 0x24, 0x90, 0x7f}}, - {0x0906, 64, { 0xea, 0xe0, 0xf5, 0x10, 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0x00, 0xe5, 0x10, 0xf0, 0x90, 0x7f, 0xb5, 0x74, - 0x01, 0xf0, 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x27, 0x14, 0x60, 0x34, - 0x24, 0x02, 0x60, 0x03, 0x02, 0x0a, 0x24, 0xa2, 0x16, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, - 0x18, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74}}, - {0x0946, 64, { 0x02, 0xf0, 0x02, 0x0a, 0x2b, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, - 0xf0, 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, - 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, - 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0}}, - {0x0986, 64, { 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x17, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0a, - 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0a, 0x24, 0xc2, 0x16, 0x02, 0x0a, - 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x76, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, - 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34}}, - {0x09c6, 64, { 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, - 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x45, 0x90, - 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x10, 0x24, 0x02, 0x70, 0x39, 0x90, 0x7f, 0xea, 0xe0, 0x64, - 0x01, 0x70, 0x2a, 0xd2, 0x16, 0x80, 0x2d, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f}}, - {0x0a06, 64, { 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, - 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, - 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xc2, 0x10, 0xe4, 0xf5, - 0x10, 0xf5, 0x34, 0xc2, 0x09, 0xc2, 0x0c, 0xc2, 0x0b, 0xc2, 0x14, 0xc2, 0x0d, 0xc2, 0x15}}, - {0x0a46, 64, { 0xc2, 0x11, 0xc2, 0x07, 0xc2, 0x12, 0xc2, 0x0f, 0xc2, 0x08, 0xf5, 0x35, 0xf5, 0x39, 0xf5, 0x53, 0xf5, - 0x3a, 0xf5, 0x33, 0xf5, 0x30, 0xf5, 0x2f, 0xf5, 0x2e, 0xf5, 0x2d, 0xf5, 0x2c, 0xf5, 0x2b, 0xf5, - 0x2a, 0xf5, 0x29, 0xf5, 0x28, 0xf5, 0x27, 0xf5, 0x26, 0xf5, 0x25, 0xf5, 0x24, 0xc2, 0x05, 0xc2, - 0x17, 0xc2, 0x19, 0xc2, 0x16, 0xc2, 0x18, 0xc2, 0x04, 0xd2, 0x13, 0xc2, 0x06, 0xc2, 0x01}}, - {0x0a86, 64, { 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, - 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, - 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, - 0xe0, 0x44, 0x0f, 0xf0, 0x90, 0x7f, 0xac, 0x74, 0x0e, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2}}, - {0x0ac6, 64, { 0x1a, 0x12, 0x0f, 0x7d, 0xc2, 0x17, 0x30, 0x04, 0x03, 0x12, 0x04, 0x48, 0x30, 0x04, 0x2a, 0x30, 0x06, - 0x27, 0xc2, 0x06, 0xe5, 0x12, 0x60, 0x16, 0x15, 0x12, 0x90, 0x7f, 0xd8, 0xe0, 0x30, 0xe6, 0x04, - 0x7f, 0x00, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x80, 0x06, 0x90, 0x7f, 0x96, - 0x74, 0x20, 0xf0, 0x12, 0x0b, 0x14, 0x80, 0xcd, 0x30, 0x17, 0x07, 0xc2, 0x17, 0x12, 0x07}}, - {0x0b06, 64, { 0xc0, 0x80, 0xc3, 0x30, 0x19, 0xc0, 0xc2, 0x19, 0x12, 0x0e, 0xdc, 0x80, 0xb9, 0x22, 0xe5, 0x31, 0x60, - 0x02, 0x15, 0x31, 0xe5, 0x39, 0x60, 0x55, 0x65, 0x35, 0x70, 0x4b, 0xe5, 0x33, 0xf4, 0x60, 0x02, - 0x05, 0x33, 0xe5, 0x33, 0xc3, 0x95, 0x44, 0x40, 0x43, 0xc2, 0xaf, 0x30, 0x02, 0x1b, 0x90, 0x7f, - 0xb8, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7f, 0xb7, 0xe5, 0x39, 0xf0, 0xc2, 0x02, 0xe4, 0xf5}}, - {0x0b46, 64, { 0x39, 0xf5, 0x33, 0xf5, 0x35, 0x75, 0x12, 0xff, 0x80, 0x19, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x12, - 0x90, 0x7f, 0xb9, 0xe5, 0x39, 0xf0, 0xd2, 0x02, 0xe4, 0xf5, 0x39, 0xf5, 0x33, 0xf5, 0x35, 0x75, - 0x12, 0xff, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x39, 0x35, 0xe4, 0xf5, 0x33, 0xe5, 0x2c, 0x60, 0x30, - 0x20, 0x0f, 0x07, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, 0x0f, 0xe5, 0x2d, 0x60, 0x06, 0xe4}}, - {0x0b86, 64, { 0xf5, 0x2d, 0x43, 0x34, 0x01, 0xe4, 0xf5, 0x30, 0x80, 0x14, 0xe5, 0x30, 0xd3, 0x95, 0x45, 0x50, 0x0d, - 0xe5, 0x30, 0xb5, 0x45, 0x06, 0x75, 0x2d, 0x01, 0x43, 0x34, 0x01, 0x05, 0x30, 0xc2, 0x0f, 0x22, - 0x90, 0x7f, 0xd9, 0xe0, 0x30, 0xe2, 0x04, 0x7f, 0x00, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96, - 0xef, 0xf0, 0x22, 0xe5, 0x14, 0x45, 0x13, 0x60, 0x57, 0xae, 0x13, 0xaf, 0x14, 0xd3, 0xef}}, - {0x0bc6, 64, { 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x04, 0x7e, 0x00, 0x7f, 0x40, 0xc3, 0xe5, 0x14, 0x9f, 0xf5, 0x14, - 0xe5, 0x13, 0x9e, 0xf5, 0x13, 0xe4, 0xfd, 0xed, 0xc3, 0x9f, 0xe4, 0x9e, 0x50, 0x1f, 0x85, 0x16, - 0x82, 0x85, 0x15, 0x83, 0xe0, 0xfc, 0x74, 0x00, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, - 0xec, 0xf0, 0x0d, 0x05, 0x16, 0xe5, 0x16, 0x70, 0x02, 0x05, 0x15, 0x80, 0xda, 0x90, 0x7f}}, - {0x0c06, 64, { 0xa9, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xef, 0xf0, 0x22, - 0x90, 0x7f, 0xac, 0xe0, 0x54, 0xfe, 0xf0, 0xe4, 0x90, 0x7f, 0xb5, 0xf0, 0x22, 0xe4, 0x90, 0x7f, - 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x20, 0xf0, 0x90, 0x7f, - 0x94, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0x97, 0x74, 0x86}}, - {0x0c46, 64, { 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84, 0xf0, 0x90, 0x7f, 0x98, 0xf0, - 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x75, 0x98, 0x40, - 0x43, 0xa8, 0x10, 0x90, 0x7f, 0xde, 0x74, 0x1f, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x0f, 0xf0, 0xd2, - 0x04, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22}}, - {0x0c86, 64, { 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, - 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, - 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, - 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3}}, - {0x0cc6, 64, { 0xa3, 0xa3, 0x80, 0xdf, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x93, 0xf0, - 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x42, 0xf0, 0x90, 0x7f, - 0x9c, 0x74, 0x10, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xbe, 0xf0, 0x30, - 0x16, 0x04, 0x7f, 0x80, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x7f, 0x97, 0xef, 0xf0, 0xe4, 0x90}}, - {0x0d06, 64, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0xf0, 0x90, 0x7f, 0x98, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, - 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, - 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, 0x12, 0x0b, 0xba, 0xd0, 0xd0, 0xd0, - 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0}}, - {0x0d46, 64, { 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, - 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, - 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0d86, 64, { 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0xff, 0xff, 0x40, 0xcd, 0x06, 0x1c, 0x01, 0x01, 0x00, 0x01, 0x02, - 0x00, 0x02, 0x09, 0x02, 0x43, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x07, - 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00}}, - {0x0dc6, 64, { 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, - 0x84, 0x02, 0x40, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, - 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2e, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, - 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x50, 0x00}}, - {0x0e06, 64, { 0x53, 0x00, 0x48, 0x00, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x22, 0x03, 0x55, 0x00, 0x53, 0x00, 0x41, 0x00, 0x2d, - 0x00, 0x35, 0x00, 0x33, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, 0x00, 0x61, - 0x00, 0x70, 0x00, 0x72, 0x00, 0x32, 0x00, 0x36, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xc0, 0x83}}, - {0x0e46, 64, { 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, - 0x74, 0x02, 0xf0, 0xd2, 0x06, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, - 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, - 0x00, 0xd2, 0x17, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0}}, - {0x0e86, 64, { 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, - 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x19, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, - 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, - 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00}}, - {0x0ec6, 64, { 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, - 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x12, 0x0c, 0xca, 0x12, 0x0f, 0xb3, 0x90, 0x7f, 0xd6, 0xe0, 0x30, - 0xe7, 0x12, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, - 0xe0, 0x54, 0xfe, 0xf0, 0x12, 0x0c, 0x24, 0x22, 0x00, 0x02, 0x0e, 0x69, 0x00, 0x02, 0x0e}}, - {0x0f06, 64, { 0x42, 0x00, 0x02, 0x0d, 0x45, 0x00, 0x02, 0x0e, 0x90, 0x00, 0x02, 0x0f, 0x10, 0x00, 0x02, 0x0f, 0x14, - 0x00, 0x02, 0x0d, 0x12, 0x00, 0x02, 0x0f, 0x1c, 0x00, 0x02, 0x0e, 0xb7, 0x00, 0x02, 0x0f, 0x24, - 0x00, 0x02, 0x0f, 0x33, 0x00, 0x02, 0x0f, 0x2c, 0x00, 0x02, 0x0f, 0x58, 0xc0, 0xe0, 0xc0, 0x83, - 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90}}, - {0x0f46, 64, { 0x7f, 0xa9, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, - 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, - 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, - 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44}}, - {0x0f86, 61, { 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x03, 0x90, - 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, - 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, - 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22}}, - {0xffff, 0, {0x00}} -}; - diff --git a/drivers/usb/serial/keyspan_usa18x_fw.h b/drivers/usb/serial/keyspan_usa18x_fw.h deleted file mode 100644 index e7b3bc0..0000000 --- a/drivers/usb/serial/keyspan_usa18x_fw.h +++ /dev/null @@ -1,447 +0,0 @@ -/* keyspan_usa18x_fw.h - - The firmware contained herein as keyspan_usa18x_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." -*/ - -static const struct ezusb_hex_record keyspan_usa18x_firmware[] = { - {0x0033, 3, { 0x02, 0x12, 0xf7}}, - {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}}, - {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}}, - {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}}, - {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x1b, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}}, - {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}}, - {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x1b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}}, - {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}}, - {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xba}}, - {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}}, - {0x00a6, 16, { 0x12, 0x13, 0x1b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}}, - {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}}, - {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xba, 0xd2, 0x03, 0xe4, 0x90, 0x7f}}, - {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x60, 0x12, 0x11, 0xd6, 0x8f}}, - {0x00e6, 16, { 0x19, 0x12, 0x13, 0x27, 0x8f, 0x36, 0xe5, 0x19, 0xc3, 0x95, 0x3a, 0x50, 0x0f, 0x12, 0x12, 0xeb}}, - {0x00f6, 16, { 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x5e, 0xc2, 0x0b, 0xe5, 0x19}}, - {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0043, 3, { 0x02, 0x13, 0x00}}, - {0x0000, 3, { 0x02, 0x0e, 0x00}}, - {0x0106, 64, { 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x36, 0x02, 0xe5, 0x36, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, - 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, - 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x4b, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, - 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08}}, - {0x0146, 64, { 0x90, 0x7e, 0x80, 0xe5, 0x36, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, - 0x0c, 0xdf, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, - 0x20, 0x05, 0x03, 0x02, 0x03, 0xc1, 0xc2, 0x05, 0xe4, 0xf5, 0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, - 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a}}, - {0x0186, 64, { 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, - 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, - 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xb1, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x11, 0xb1, 0x43, 0x46, - 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90}}, - {0x01c6, 64, { 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0x35, 0x90, 0x7e, 0x02, 0xe0, - 0xff, 0x12, 0x10, 0x5b, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x11, 0xb1, 0x7f, 0x03, - 0x7d, 0x07, 0x12, 0x11, 0xb1, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, - 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90}}, - {0x0206, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, - 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, - 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, - 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80, 0x80, 0x03, 0x53, 0x42}}, - {0x0246, 64, { 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, - 0x10, 0xa7, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xcd, 0xaf, 0x42, 0x12, 0x10, 0x81, 0x90, - 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10, 0x81, 0x90, 0x7e, 0x0c, - 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd}}, - {0x0286, 64, { 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, - 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, - 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, - 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10}}, - {0x02c6, 64, { 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, - 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, - 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x12, 0x12, 0xdf, - 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12}}, - {0x0306, 64, { 0x11, 0xb1, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, - 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xb1, 0x75, 0x29, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, - 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, - 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98}}, - {0x0346, 64, { 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, - 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xb1, 0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, - 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xb1, 0xe4, - 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12}}, - {0x0386, 64, { 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, - 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, - 0x1f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, - 0x74, 0x35, 0xf0, 0xd2, 0x03, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x1a, 0x52, 0xe5, 0x38}}, - {0x03c6, 64, { 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, - 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x12, 0xdf, 0xef, 0x54, 0x01, 0xf5, - 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13, 0x33, 0xef, 0x54, 0x80, - 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07, 0x30, 0x0d, 0x11, 0x12}}, - {0x0406, 64, { 0x13, 0x33, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19, 0x25, 0xd2, 0x07, 0x20, - 0x1b, 0x03, 0x02, 0x07, 0xec, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x6f, 0xef, 0xc3, 0x95, 0x3d, 0x40, - 0x03, 0x02, 0x04, 0xae, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a, 0xc2, 0x00, 0x80, 0x77, - 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x6f, 0xef, 0xc3}}, - {0x0446, 64, { 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0x14, 0xf5, - 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41, 0x75, 0x0c, 0x7d, 0x75, - 0x0d, 0x41, 0x12, 0x0d, 0x04, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x39, 0x90, 0x7f, - 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x6f, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90}}, - {0x0486, 64, { 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, - 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x04, - 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, - 0x36, 0x12, 0x12, 0x20, 0x8f, 0x19, 0x12, 0x13, 0x7b, 0x8f, 0x37, 0xe5, 0x19, 0xc3, 0x95}}, - {0x04c6, 64, { 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x57, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, - 0x5e, 0xc2, 0x0c, 0xe5, 0x19, 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x37, 0x02, 0xe5, 0x37, 0x30, - 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, - 0x7d, 0x7f, 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0x84, 0xe5}}, - {0x0506, 64, { 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb, 0xf0, 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, - 0x19, 0x3f, 0x85, 0x19, 0x08, 0x90, 0x7d, 0x80, 0xe5, 0x37, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, - 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0x29, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, - 0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x97, 0xc2, 0x06, 0xe4}}, - {0x0546, 64, { 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, - 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, - 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, - 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xfb, 0x7f, 0x03}}, - {0x0586, 64, { 0x7d, 0xcd, 0x12, 0x11, 0xfb, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, - 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, - 0x11, 0x19, 0x90, 0x7e, 0x22, 0xe0, 0xff, 0x12, 0x11, 0x3f, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, - 0xfd, 0x12, 0x11, 0xfb, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xfb, 0x43, 0x47, 0x80, 0x90}}, - {0x05c6, 64, { 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, - 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, - 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, - 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90}}, - {0x0606, 64, { 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e, 0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, - 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f, 0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, - 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x11, 0x65, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0x8b, - 0xaf, 0x43, 0x12, 0x10, 0xf3, 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf}}, - {0x0646, 64, { 0x43, 0x12, 0x10, 0xf3, 0x90, 0x7e, 0x2c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, - 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, - 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, - 0x53, 0x47, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0}}, - {0x0686, 64, { 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3, 0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, - 0x60, 0x05, 0x43, 0x47, 0x10, 0x80, 0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, - 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f}}, - {0x06c6, 64, { 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x4b, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, - 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, - 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, 0x75, 0x32, - 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0}}, - {0x0706, 64, { 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, - 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f, 0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, - 0x75, 0x34, 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4}}, - {0x0746, 64, { 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, 0xe4, 0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, - 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, - 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c, 0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, - 0xf5, 0x39, 0xd2, 0x08, 0x90, 0x7e, 0x3f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x13}}, - {0x0786, 64, { 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0, 0x74, 0x36, 0xf0, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, - 0x30, 0x1a, 0x52, 0xe5, 0x39, 0x60, 0x02, 0x15, 0x39, 0x30, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, - 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, - 0x13, 0x4b, 0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2}}, - {0x07c6, 64, { 0x08, 0x12, 0x13, 0x87, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, - 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x87, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, - 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, - 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90}}, - {0x0806, 64, { 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, - 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x09, 0x20, 0xe5, 0x0a, 0x70, 0x40, - 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, - 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25}}, - {0x0846, 64, { 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, - 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38, 0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, - 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08, 0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, - 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12}}, - {0x0886, 64, { 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, - 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, - 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a, 0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, - 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}}, - {0x08c6, 64, { 0xfa, 0x12, 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, - 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, - 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15, 0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, - 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25}}, - {0x0906, 64, { 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, - 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0e, - 0xe4, 0x0a, 0x08, 0x00, 0x0a, 0x7c, 0x01, 0x0a, 0xe8, 0x03, 0x09, 0x44, 0x06, 0x09, 0xfb, 0x08, - 0x09, 0xf5, 0x09, 0x09, 0xdd, 0x0a, 0x09, 0xec, 0x0b, 0x00, 0x00, 0x0b, 0x37, 0x90, 0x7f}}, - {0x0946, 64, { 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61, 0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xd3, 0x74, - 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, - 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, - 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19}}, - {0x0986, 64, { 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, - 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, - 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, - 0x0a, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0}}, - {0x09c6, 64, { 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, - 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, - 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x3e, 0x12, 0x0b, - 0x46, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02}}, - {0x0a06, 64, { 0x0b, 0x3e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, - 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, - 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0xe4, 0x90, 0x7f, - 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f}}, - {0x0a46, 64, { 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, - 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, - 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02}}, - {0x0a86, 64, { 0x60, 0x03, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x3e, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, - 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, - 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f}}, - {0x0ac6, 64, { 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, - 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, - 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, - 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}}, - {0x0b06, 64, { 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, - 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, - 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22}}, - {0x0b46, 64, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, - 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, - 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, - 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa}}, - {0x0b86, 64, { 0xe4, 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, - 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b, 0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, - 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xb1, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0x81, 0x90, 0x7f}}, - {0x0bc6, 64, { 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, - 0x12, 0x11, 0xb1, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xb1, 0x90, 0x7f, - 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11}}, - {0x0c06, 64, { 0xb1, 0x7f, 0x01, 0x12, 0x12, 0x6a, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xb1, 0x20, 0x1b, 0x03, 0x02, - 0x0c, 0xb7, 0x75, 0x2d, 0x01, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, - 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, - 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2}}, - {0x0c46, 64, { 0x00, 0xc2, 0x0a, 0xc2, 0x13, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00, - 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xfb, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x10, - 0xf3, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90, 0xc0, - 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74}}, - {0x0c86, 64, { 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x11, 0xfb, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12, - 0x11, 0xfb, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, - 0x7f, 0x12, 0x11, 0xfb, 0x7f, 0x01, 0x12, 0x12, 0x8b, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xfb, - 0xd2, 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82}}, - {0x0cc6, 64, { 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, - 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, - 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, - 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f}}, - {0x0d06, 64, { 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, - 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, - 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, - 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05}}, - {0x0d46, 64, { 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, - 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, - 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, - 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0}}, - {0x0d86, 64, { 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, - 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, - 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, - 0x1a, 0x12, 0x12, 0x45, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, 0x12}}, - {0x0dc6, 64, { 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, 0x05, 0xd2, - 0x1a, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, 0x05, 0xc2, - 0x1a, 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x21, 0x80, 0xd6, 0x30, 0x18, - 0xd3, 0xc2, 0x18, 0x12, 0x13, 0x93, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd}}, - {0x0e06, 64, { 0x75, 0x81, 0x47, 0x02, 0x0e, 0x47, 0x02, 0x0d, 0x6f, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, - 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, - 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, - 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40}}, - {0x0e46, 64, { 0x80, 0x90, 0x12, 0xac, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, - 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, - 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, - 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca}}, - {0x0e86, 64, { 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, - 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, - 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, - 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5}}, - {0x0ec6, 64, { 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, - 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, - 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, - 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3}}, - {0x0f06, 64, { 0xa3, 0xa3, 0x80, 0xdf, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, 0x75, 0x1c, - 0x86, 0xab, 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xa5, 0xb4, 0x03, 0x1d, - 0xaf, 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0x8c, 0x7e, 0x00, 0x29, 0xff, - 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, 0x00}}, - {0x0f46, 64, { 0x7a, 0x00, 0x79, 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, - 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac, - 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, - 0x60, 0x0a, 0x12, 0x13, 0x27, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, 0x1a}}, - {0x0f86, 64, { 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, - 0xf0, 0x12, 0x13, 0x3f, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, - 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x7b, 0x8f, 0x1a, - 0xef, 0x42, 0x37, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0}}, - {0x0fc6, 64, { 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, - 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, - 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, - 0x11, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0}}, - {0x1006, 64, { 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, - 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, - 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, - 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10}}, - {0x1046, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, - 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13}}, - {0x1086, 64, { 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, - 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44}}, - {0x10c6, 64, { 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, - 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, - 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90}}, - {0x1106, 64, { 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, - 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, - 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90}}, - {0x1146, 64, { 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, - 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, - 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f}}, - {0x1186, 64, { 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, - 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, - 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90}}, - {0x11c6, 64, { 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, - 0x13, 0x0f, 0x8f, 0x1a, 0x12, 0x13, 0x0f, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, - 0x13, 0x0f, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x0f, 0x8f, 0x1b, 0x80, - 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90}}, - {0x1206, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, - 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x63, 0x8f, 0x1a, 0x12, 0x13, - 0x63, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x63, 0x8f, 0x1a, 0xe5, 0x1a, - 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x63, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90}}, - {0x1246, 64, { 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, - 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xc8, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, - 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xb1, 0x90, - 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80}}, - {0x1286, 64, { 0xfd, 0x12, 0x11, 0xb1, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xfb, - 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, - 0xfd, 0x12, 0x11, 0xfb, 0x22, 0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, - 0x00, 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10, 0xc1, 0x16, 0x01, 0x0a, 0x00, 0xc1}}, - {0x12c6, 64, { 0x1b, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, - 0x60, 0x05, 0x12, 0x0d, 0x4e, 0x80, 0xee, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0xe7, 0x00, 0x02, 0x13}}, - {0x1306, 64, { 0x04, 0x00, 0x02, 0x0f, 0xbd, 0x00, 0x02, 0x10, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90}}, - {0x1346, 64, { 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff}}, - {0x1386, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x12, 0x00, 0x03, 0x12, - 0x0d, 0x5f, 0x12, 0x0b, 0x46, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x12, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 20, { 0x72, 0x00, 0x10, 0x03, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, - 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00} } -}; diff --git a/drivers/usb/serial/keyspan_usa19_fw.h b/drivers/usb/serial/keyspan_usa19_fw.h deleted file mode 100644 index b023c52..0000000 --- a/drivers/usb/serial/keyspan_usa19_fw.h +++ /dev/null @@ -1,285 +0,0 @@ -/* keyspan_usa19_fw.h - - The firmware contained herein as keyspan_usa19_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." -*/ - - -static const struct ezusb_hex_record keyspan_usa19_firmware[] = { - {0x0026, 10, { 0x12, 0x0d, 0xbf, 0x12, 0x0f, 0x47, 0x12, 0x0d, 0x6b, 0x22}}, - {0x0033, 3, { 0x02, 0x00, 0x1a}}, - {0x001a, 4, { 0x53, 0xd8, 0xef, 0x32}}, - {0x0003, 16, { 0x8e, 0x13, 0x8f, 0x14, 0xe5, 0x14, 0x15, 0x14, 0xae, 0x13, 0x70, 0x02, 0x15, 0x13, 0x4e, 0x60}}, - {0x0013, 7, { 0x05, 0x12, 0x0f, 0x36, 0x80, 0xee, 0x22}}, - {0x0023, 3, { 0x02, 0x00, 0x46}}, - {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}}, - {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x08, 0x07, 0xa2, 0x0b, 0x92, 0x9b, 0x85, 0x35, 0x99, 0xc2, 0x99, 0xd2}}, - {0x0066, 16, { 0x0f, 0x20, 0x0f, 0x03, 0x02, 0x04, 0x31, 0xc2, 0x0f, 0x20, 0x02, 0x03, 0x02, 0x02, 0x56, 0x20}}, - {0x0076, 16, { 0x08, 0x03, 0x02, 0x01, 0x27, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x3e, 0x20, 0x09, 0x36, 0x20}}, - {0x0086, 16, { 0x06, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x29, 0x30, 0x0d, 0x12, 0xaf}}, - {0x0096, 16, { 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92}}, - {0x00a6, 16, { 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0}}, - {0x00b6, 16, { 0xf5, 0x35, 0x02, 0x04, 0x2f, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2}}, - {0x00c6, 16, { 0x02, 0x30, 0x0a, 0x0c, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x08, 0x02, 0x04, 0x2f}}, - {0x00d6, 16, { 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc9, 0xe0}}, - {0x00e6, 16, { 0xf5, 0x50, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x20, 0x09, 0x2d, 0x20, 0x06, 0x2a, 0x90}}, - {0x00f6, 16, { 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x20, 0x30, 0x0d, 0x11, 0x90, 0x7d, 0xc1, 0xe0}}, - {0x0043, 3, { 0x02, 0x0f, 0x00}}, - {0x0000, 3, { 0x02, 0x0c, 0x61}}, - {0x0106, 64, { 0x13, 0x92, 0x0b, 0xa3, 0xe0, 0xf5, 0x35, 0x75, 0x37, 0x03, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x02, 0x90, - 0x7d, 0xc1, 0xe0, 0xf5, 0x35, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x08, 0x02, 0x04, 0x2f, - 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x03, 0x02, 0x01, 0xcf, 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, - 0x07, 0xc2, 0x10, 0xc2, 0x03, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x50, 0x90}}, - {0x0146, 64, { 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x30, 0x09, 0x03, 0x02, 0x01, 0xc7, 0x20, 0x06, 0x72, 0x20, 0x00, - 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x65, 0x30, 0x0d, 0x10, 0x90, 0x7e, - 0x41, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x03, 0x80, 0x09, 0x90, 0x7e, - 0x41, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x02, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90}}, - {0x0186, 64, { 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x02, 0x20, 0x0a, 0x03, 0x02, 0x04, 0x2f, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, - 0x04, 0xf0, 0x02, 0x04, 0x2f, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, - 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, - 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x02, 0x04}}, - {0x01c6, 64, { 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x10, 0x02, 0x04, 0x2f, 0x30, 0x09, 0x03, 0x02, 0x02, 0x51, 0x20, 0x06, - 0x79, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x6f, 0x30, 0x0d, 0x12, 0xaf, 0x37, - 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, - 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0}}, - {0x0206, 64, { 0xf5, 0x99, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x02, 0x20, - 0x0a, 0x03, 0x02, 0x04, 0x2f, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x2f, 0x30, - 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, - 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34}}, - {0x0246, 64, { 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x02, 0x04, 0x2f, 0xc2, 0x10, 0x02, 0x04, 0x2f, 0x20, - 0x08, 0x03, 0x02, 0x03, 0x08, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x3e, 0x20, 0x09, 0x36, 0x20, - 0x06, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x29, 0x30, 0x0d, 0x12, 0xaf, - 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13}}, - {0x0286, 64, { 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, - 0xf5, 0x35, 0x02, 0x04, 0x2f, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, - 0x02, 0x30, 0x0a, 0x0c, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x08, 0x02, 0x04, 0x2f, - 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc7}}, - {0x02c6, 64, { 0xe0, 0xf5, 0x50, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x20, 0x09, 0x2d, 0x20, 0x06, 0x2a, 0x90, - 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x20, 0x30, 0x0d, 0x11, 0x90, 0x7e, 0x41, 0xe0, - 0x13, 0x92, 0x0b, 0xa3, 0xe0, 0xf5, 0x35, 0x75, 0x37, 0x03, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x02, - 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x35, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x08, 0x02}}, - {0x0306, 64, { 0x04, 0x2f, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x03, 0x02, 0x03, 0xb0, 0x90, 0x7f, 0xc8, 0xe0, 0x30, - 0xe1, 0x07, 0xc2, 0x10, 0xc2, 0x03, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x50, 0x90, - 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x30, 0x09, 0x03, 0x02, 0x03, 0xa8, 0x20, 0x06, 0x72, 0x20, - 0x00, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x65, 0x30, 0x0d, 0x10}}, - {0x0346, 64, { 0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x03, 0x80, 0x09, 0x90, - 0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x02, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90, - 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02, 0x20, 0x0a, 0x03, 0x02, 0x04, 0x2f, 0xc2, 0x0a, 0x90, 0x7f, - 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x2f, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0}}, - {0x0386, 64, { 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, - 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x02, 0x04, - 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x10, 0x02, 0x04, 0x2f, 0x30, 0x09, 0x03, 0x02, 0x04, 0x2d, 0x20, - 0x06, 0x74, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x6a, 0x30, 0x0d, 0x12}}, - {0x03c6, 64, { 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, - 0x9b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, - 0xf5, 0x99, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x13, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02, - 0x30, 0x0a, 0x35, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x0d, 0x12}}, - {0x0406, 64, { 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, - 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, - 0xf5, 0x35, 0xd2, 0x08, 0x80, 0x02, 0xc2, 0x10, 0xd2, 0x12, 0x20, 0x98, 0x03, 0x02, 0x05, 0x6d, - 0xc2, 0x98, 0x20, 0x01, 0x03, 0x02, 0x04, 0xda, 0x20, 0x11, 0x27, 0xaf, 0x36, 0x05, 0x36}}, - {0x0446, 64, { 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x0d, 0x4d, 0xaf, - 0x36, 0x05, 0x36, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, - 0x80, 0x3a, 0x85, 0x99, 0x10, 0xe5, 0x10, 0xb5, 0x44, 0x04, 0xd2, 0x06, 0x80, 0x2e, 0xe5, 0x10, - 0xb5, 0x43, 0x04, 0xc2, 0x06, 0x80, 0x25, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x80, 0x2f, 0xf5}}, - {0x0486, 64, { 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x10, 0xf0, 0x30, 0x0d, 0x11, 0xaf, 0x36, 0x05, 0x36, 0x74, - 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0c, 0xe5, 0x36, - 0xc3, 0x95, 0x40, 0x50, 0x03, 0x02, 0x05, 0x6b, 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x16, 0xe5, - 0x36, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02, 0x05, 0x6b, 0x15, 0x36, 0x15, 0x36, 0x05, 0x2b}}, - {0x04c6, 64, { 0x43, 0x33, 0x01, 0x02, 0x05, 0x6b, 0x90, 0x7f, 0xb7, 0xe5, 0x36, 0xf0, 0x75, 0x36, 0x00, 0xc2, 0x01, - 0x02, 0x05, 0x6b, 0x20, 0x11, 0x27, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, - 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x0d, 0x4d, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, - 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99}}, - {0x0506, 64, { 0x10, 0xe5, 0x10, 0xb5, 0x44, 0x04, 0xd2, 0x06, 0x80, 0x2e, 0xe5, 0x10, 0xb5, 0x43, 0x04, 0xc2, 0x06, - 0x80, 0x25, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, - 0xe5, 0x10, 0xf0, 0x30, 0x0d, 0x11, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, - 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0c, 0xe5, 0x36, 0xc3, 0x95, 0x40, 0x40}}, - {0x0546, 64, { 0x24, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x12, 0xe5, 0x36, 0xc3, 0x94, 0x40, 0x40, 0x16, 0x15, 0x36, - 0x15, 0x36, 0x05, 0x2b, 0x43, 0x33, 0x01, 0x80, 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x36, 0xf0, 0x75, - 0x36, 0x00, 0xd2, 0x01, 0xd2, 0x12, 0x30, 0x12, 0x05, 0xc2, 0x12, 0x02, 0x00, 0x56, 0xd0, 0xd0, - 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1}}, - {0x0586, 64, { 0x03, 0x02, 0x06, 0xab, 0xe4, 0xf5, 0x13, 0x74, 0x40, 0x25, 0x13, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, - 0x83, 0xe0, 0xff, 0xe5, 0x13, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x38, 0xf9, 0xec, 0x34, 0x00, 0xfa, - 0xef, 0x12, 0x0d, 0x33, 0x05, 0x13, 0xe5, 0x13, 0xb4, 0x18, 0xdb, 0xe5, 0x38, 0x60, 0x0c, 0x75, - 0xc9, 0x20, 0x75, 0xc8, 0x34, 0x85, 0x39, 0xca, 0x85, 0x3a, 0xcb, 0xe5, 0x3b, 0x13, 0x92}}, - {0x05c6, 64, { 0x0d, 0x92, 0x9f, 0xe5, 0x3c, 0x13, 0x92, 0x0e, 0xe5, 0x3d, 0x13, 0x92, 0x11, 0xe5, 0x3e, 0x60, 0x09, - 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0, - 0xe5, 0x3f, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, - 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x45, 0x60, 0x0b, 0xc2, 0x09, 0xc2, 0x06, 0x90, 0x7f, 0x95}}, - {0x0606, 64, { 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x46, 0x60, 0x0c, 0xd2, 0x06, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x95, 0xe0, - 0x44, 0x02, 0xf0, 0xe5, 0x47, 0x60, 0x0d, 0xc2, 0xaf, 0xc2, 0x08, 0xd2, 0x00, 0xe4, 0xf5, 0x50, - 0xf5, 0x37, 0xd2, 0xaf, 0xe5, 0x48, 0x60, 0x05, 0x30, 0x11, 0x02, 0xd2, 0x06, 0xe5, 0x49, 0x60, - 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44, 0x02, 0xf0}}, - {0x0646, 64, { 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x4a, 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98, 0x75, 0x2c, - 0x01, 0x75, 0x31, 0x1e, 0xe5, 0x4b, 0x60, 0x07, 0xc2, 0x9c, 0xe4, 0xf5, 0x36, 0xf5, 0x2c, 0xe5, - 0x4c, 0x60, 0x03, 0xe4, 0xf5, 0x36, 0xe5, 0x4d, 0x60, 0x02, 0xd2, 0x04, 0xe5, 0x4e, 0x60, 0x0a, - 0xe5, 0x4a, 0x70, 0x02, 0xf5, 0x31, 0xe5, 0x4e, 0x42, 0x33, 0xe5, 0x4f, 0x60, 0x1f, 0x90}}, - {0x0686, 64, { 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x13, 0xf0, - 0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0, 0xd2, 0x02, 0xd2, 0x01, 0xd2, 0x05, 0xe4, - 0x90, 0x7f, 0xcb, 0xf0, 0xa2, 0x09, 0xe4, 0x33, 0xff, 0x65, 0x29, 0x60, 0x05, 0x8f, 0x29, 0x43, - 0x33, 0x01, 0xa2, 0x06, 0xe4, 0x33, 0xff, 0x65, 0x2a, 0x60, 0x05, 0x8f, 0x2a, 0x43, 0x33}}, - {0x06c6, 64, { 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x08, 0xb5, 0x25, 0x0a, 0xe0, 0x54, 0x08, 0x64, 0x08, 0xf5, 0x25, - 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x10, 0xb5, 0x26, 0x0a, 0xe0, 0x54, 0x10, 0x64, - 0x10, 0xf5, 0x26, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x40, 0xb5, 0x27, 0x0a, 0xe0, - 0x54, 0x40, 0x64, 0x40, 0xf5, 0x27, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x20}}, - {0x0706, 64, { 0xb5, 0x28, 0x0a, 0xe0, 0x54, 0x20, 0x64, 0x20, 0xf5, 0x28, 0x43, 0x33, 0x01, 0x30, 0x04, 0x35, 0xc2, - 0xaf, 0x30, 0x01, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x36, 0x60, 0x09, 0x90, - 0x7f, 0xb7, 0xf0, 0xe4, 0xf5, 0x36, 0xc2, 0x01, 0xc2, 0x04, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, - 0x20, 0xe1, 0x0f, 0xe5, 0x36, 0x60, 0x09, 0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x36, 0xd2}}, - {0x0746, 64, { 0x01, 0xc2, 0x04, 0xd2, 0xaf, 0x20, 0x03, 0x37, 0x30, 0x02, 0x1b, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, - 0x2d, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x75, 0x37, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, - 0x50, 0xd2, 0x03, 0x80, 0x19, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7d, 0xc0, 0xe0, - 0x13, 0x92, 0x0a, 0x75, 0x37, 0x01, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x50, 0xd2, 0x03, 0x20}}, - {0x0786, 64, { 0x10, 0x33, 0x20, 0x00, 0x06, 0xe5, 0x37, 0x65, 0x50, 0x70, 0x2a, 0x30, 0x03, 0x1a, 0x30, 0x02, 0x09, - 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x02, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x02, - 0xc2, 0x03, 0xe4, 0xf5, 0x50, 0xf5, 0x37, 0x30, 0x0a, 0x0a, 0xc2, 0x0a, 0xc2, 0x00, 0x90, 0x7f, - 0xbb, 0x74, 0x01, 0xf0, 0x30, 0x10, 0x03, 0x02, 0x08, 0xc5, 0x20, 0x03, 0x03, 0x02, 0x08}}, - {0x07c6, 64, { 0xc5, 0x30, 0x0e, 0x0a, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x02, 0x08, 0xc5, 0x30, 0x06, 0x03, - 0x02, 0x08, 0xc5, 0x30, 0x09, 0x03, 0x02, 0x08, 0xc5, 0x30, 0x02, 0x62, 0x30, 0x0d, 0x12, 0xaf, - 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, - 0x19, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83}}, - {0x0806, 64, { 0xe0, 0xf5, 0x14, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x2a, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, - 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, - 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, - 0x08, 0x80, 0x6b, 0xc2, 0x08, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x02, 0x80, 0x60, 0x30}}, - {0x0846, 64, { 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, - 0x13, 0x92, 0x19, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, - 0x83, 0xe0, 0xf5, 0x14, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x2a, 0x30, 0x0d, 0x12, 0xaf, 0x37, - 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92}}, - {0x0886, 64, { 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, - 0x35, 0xd2, 0x08, 0x80, 0x09, 0xc2, 0x08, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x02, 0x30, 0x0d, - 0x04, 0xa2, 0x19, 0x92, 0x9b, 0xd2, 0x10, 0xc2, 0xaf, 0x85, 0x14, 0x99, 0x20, 0x08, 0x0d, 0x30, - 0x0a, 0x0a, 0xc2, 0x0a, 0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90}}, - {0x08c6, 64, { 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x51, 0xe5, 0x33, 0x60, 0x4d, 0xe5, 0x31, 0x70, 0x49, 0xe5, 0x33, 0x30, - 0xe1, 0x08, 0xe4, 0xf5, 0x2f, 0x75, 0x33, 0x01, 0x80, 0x0b, 0xa2, 0x05, 0xe4, 0x33, 0xf5, 0x2f, - 0xc2, 0x05, 0xe4, 0xf5, 0x33, 0xe4, 0xf5, 0x13, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x13, - 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0c, 0xed, 0xff, 0x74, 0x00, 0x25, 0x13, 0xf5, 0x82}}, - {0x0906, 64, { 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x13, 0xe5, 0x13, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xbd, - 0x74, 0x0c, 0xf0, 0x75, 0x31, 0x10, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0d, 0x45, 0x0a, 0x03, - 0x00, 0x0a, 0x77, 0x01, 0x0a, 0xe3, 0x03, 0x09, 0x41, 0x06, 0x09, 0xf4, 0x08, 0x09, 0xe8, 0x09, - 0x09, 0xd0, 0x0a, 0x09, 0xdf, 0x0b, 0x00, 0x00, 0x0b, 0x32, 0x90, 0x7f, 0xeb, 0xe0, 0x24}}, - {0x0946, 64, { 0xfe, 0x60, 0x16, 0x14, 0x60, 0x57, 0x24, 0x02, 0x70, 0x76, 0x74, 0x0f, 0x90, 0x7f, 0xd4, 0xf0, 0x74, - 0x64, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, - 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0xb5, 0x75, 0x83, 0x0f, 0xef, 0xf0, 0x75, 0x82, 0xae, 0x75, - 0x83, 0x0f, 0xf0, 0x75, 0x82, 0xa7, 0x75, 0x83, 0x0f, 0xf0, 0x75, 0x82, 0xa0, 0x75, 0x83}}, - {0x0986, 64, { 0x0f, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x7b, 0x75, 0x83, 0x0f, 0xf0, 0x74, 0x0f, 0x90, - 0x7f, 0xd4, 0xf0, 0x74, 0x76, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xea, 0xe0, - 0xff, 0x12, 0x0e, 0x48, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, - 0xd5, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x39}}, - {0x09c6, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0x00, 0xe5, 0x19, 0xf0, 0x90, - 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x19, 0x02, 0x0b, - 0x39, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x18, 0x12, 0x0d, 0x6b, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0x00, - 0xe5, 0x18, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xe8}}, - {0x0a06, 64, { 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x13, 0xe4, 0x33, 0xff, - 0x25, 0xe0, 0xff, 0xa2, 0x17, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, - 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x39, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, - 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80}}, - {0x0a46, 64, { 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, - 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, - 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x39, - 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x39}}, - {0x0a86, 64, { 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x13, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x0b, 0x39, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, - 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, - 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff}}, - {0x0ac6, 64, { 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, - 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, - 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, - 0x13, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea}}, - {0x0b06, 64, { 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, - 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, - 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x20, 0x15, 0x03, 0x02, 0x0b}}, - {0x0b46, 64, { 0xd3, 0xe5, 0x31, 0x60, 0x02, 0x15, 0x31, 0xe5, 0x36, 0x60, 0x4f, 0x65, 0x34, 0x70, 0x45, 0xe5, 0x32, - 0xf4, 0x60, 0x02, 0x05, 0x32, 0xe5, 0x32, 0xc3, 0x95, 0x41, 0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x01, - 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f, 0xb7, 0xe5, 0x36, 0xf0, 0xc2, 0x01, - 0xe4, 0xf5, 0x36, 0xf5, 0x32, 0xf5, 0x34, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1}}, - {0x0b86, 64, { 0x0f, 0x90, 0x7f, 0xb9, 0xe5, 0x36, 0xf0, 0xd2, 0x01, 0xe4, 0xf5, 0x36, 0xf5, 0x32, 0xf5, 0x34, 0xd2, - 0xaf, 0x80, 0x06, 0x85, 0x36, 0x34, 0xe4, 0xf5, 0x32, 0xe5, 0x2c, 0x60, 0x2f, 0x20, 0x0c, 0x07, - 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, 0x0f, 0xe5, 0x2d, 0x60, 0x06, 0xe4, 0xf5, 0x2d, 0x43, 0x33, - 0x01, 0xe4, 0xf5, 0x30, 0x80, 0x14, 0xe5, 0x30, 0xd3, 0x95, 0x42, 0x50, 0x0d, 0xe5, 0x30}}, - {0x0bc6, 64, { 0xb5, 0x42, 0x06, 0x75, 0x2d, 0x01, 0x43, 0x33, 0x01, 0x05, 0x30, 0xc2, 0x0c, 0x22, 0x75, 0x12, 0x01, - 0xc2, 0x14, 0xc2, 0x18, 0xc2, 0x13, 0xc2, 0x17, 0xc2, 0x15, 0xc2, 0x12, 0xd2, 0x16, 0xe4, 0xf5, - 0x18, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x13, - 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74}}, - {0x0c06, 64, { 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, - 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, - 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0x19, 0x12, 0x0e, 0xda, 0xc2, 0x14, 0x30, - 0x15, 0x03, 0x12, 0x05, 0x80, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x11, 0x60, 0x08, 0xe0, 0xf5}}, - {0x0c46, 64, { 0x11, 0x12, 0x0b, 0x41, 0x80, 0xea, 0x30, 0x14, 0x07, 0xc2, 0x14, 0x12, 0x09, 0x1e, 0x80, 0xe0, 0x30, - 0x18, 0xdd, 0xc2, 0x18, 0x12, 0x00, 0x26, 0x80, 0xd6, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, - 0x75, 0x81, 0x50, 0x02, 0x0c, 0xa8, 0x02, 0x0b, 0xd4, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, - 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8}}, - {0x0c86, 64, { 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, - 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, - 0x80, 0x90, 0x0e, 0x04, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, - 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0}}, - {0x0cc6, 64, { 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, - 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, - 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, - 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22}}, - {0x0d06, 64, { 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, - 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, - 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, - 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0}}, - {0x0d46, 64, { 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, - 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, - 0xa3, 0xa3, 0x80, 0xdf, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, - 0x7f, 0x96, 0x74, 0x10, 0xf0, 0x90, 0x7f, 0x94, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0x9d, 0x04}}, - {0x0d86, 64, { 0xf0, 0x90, 0x7f, 0x97, 0x74, 0x20, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f, 0x9e, 0x74, - 0x84, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, - 0x7f, 0xcb, 0xf0, 0x75, 0x98, 0x40, 0x43, 0xa8, 0x10, 0x90, 0x7f, 0xde, 0x74, 0x1f, 0xf0, 0x90, - 0x7f, 0xdf, 0x74, 0x0f, 0xf0, 0xd2, 0x15, 0x22, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f}}, - {0x0dc6, 64, { 0x94, 0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xe0, - 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x20, 0xf0, - 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0xfd, 0xf0, 0xe4, 0x90, 0x7f, 0x97, - 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22, 0x0c, 0x24}}, - {0x0e06, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x01, 0x33, - 0x01, 0x01, 0x32, 0x00, 0x01, 0x37, 0x00, 0x01, 0x50, 0x00, 0x01, 0x36, 0x00, 0x01, 0x34, 0x00, - 0xc1, 0x05, 0xc1, 0x0c, 0xc1, 0x03, 0xc1, 0x0f, 0xc1, 0x04, 0xc1, 0x0e, 0xc1, 0x11, 0xc1, 0x0a, - 0xc1, 0x10, 0xc1, 0x08, 0xc1, 0x09, 0xc1, 0x06, 0xc1, 0x00, 0xc1, 0x0d, 0xc1, 0x81, 0xc1}}, - {0x0e46, 64, { 0x82, 0x00, 0x8f, 0x13, 0xe4, 0xf5, 0x14, 0x75, 0x15, 0xff, 0x75, 0x16, 0x0f, 0x75, 0x17, 0xb9, 0xab, - 0x15, 0xaa, 0x16, 0xa9, 0x17, 0x90, 0x00, 0x01, 0x12, 0x0d, 0x06, 0xb4, 0x03, 0x1d, 0xaf, 0x14, - 0x05, 0x14, 0xef, 0xb5, 0x13, 0x01, 0x22, 0x12, 0x0c, 0xed, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, - 0xa9, 0x07, 0x75, 0x15, 0xff, 0xf5, 0x16, 0x89, 0x17, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00}}, - {0x0e86, 64, { 0x79, 0x00, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, - 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, - 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, - 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x14, 0x53, 0x91}}, - {0x0ec6, 64, { 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, - 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x19, - 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, 0xe0, - 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x00, 0x02, 0x0e, 0xb3, 0x00, 0x02, 0x0f}}, - {0x0f06, 64, { 0x04, 0x00, 0x02, 0x0e, 0x89, 0x00, 0x02, 0x0f, 0x0f, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, - 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, - 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x74, - 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9}}, - {0x0f46, 64, { 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, - 0x01, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x07, 0x01, 0x01, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, - 0x02, 0x43, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x07, 0xff, 0x00}}, - {0x0f86, 64, { 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, - 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, - 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, - 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73}}, - {0x0fc6, 23, { 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x0e, 0x03, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, - 0x61, 0x00, 0x6c, 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00} } -}; diff --git a/drivers/usb/serial/keyspan_usa19qi_fw.h b/drivers/usb/serial/keyspan_usa19qi_fw.h deleted file mode 100644 index 1a26472..0000000 --- a/drivers/usb/serial/keyspan_usa19qi_fw.h +++ /dev/null @@ -1,284 +0,0 @@ -/* keyspan_usa19qi_fw.h - - The firmware contained herein as keyspn_usa19qi_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -*/ - -static const struct ezusb_hex_record keyspan_usa19qi_firmware[] = { - {0x0033, 3, { 0x02, 0x00, 0x1a}}, - {0x001a, 4, { 0x53, 0xd8, 0xef, 0x32}}, - {0x0003, 16, { 0x8e, 0x11, 0x8f, 0x12, 0xe5, 0x12, 0x15, 0x12, 0xae, 0x11, 0x70, 0x02, 0x15, 0x11, 0x4e, 0x60}}, - {0x0013, 7, { 0x05, 0x12, 0x0f, 0x84, 0x80, 0xee, 0x22}}, - {0x0023, 3, { 0x02, 0x00, 0x46}}, - {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}}, - {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x0b, 0x07, 0xa2, 0x0e, 0x92, 0x9b, 0x85, 0x36, 0x99, 0xc2, 0x99, 0xd2}}, - {0x0066, 16, { 0x12, 0x20, 0x12, 0x03, 0x02, 0x04, 0x1e, 0xc2, 0x12, 0x20, 0x03, 0x03, 0x02, 0x02, 0x4e, 0x20}}, - {0x0076, 16, { 0x0b, 0x03, 0x02, 0x01, 0x26, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x3c, 0x20, 0x0c, 0x34, 0x20}}, - {0x0086, 16, { 0x09, 0x31, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x29, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05}}, - {0x0096, 16, { 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf}}, - {0x00a6, 16, { 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x36}}, - {0x00b6, 16, { 0x02, 0x04, 0x1c, 0xc2, 0x0b, 0x02, 0x04, 0x1c, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03, 0x30}}, - {0x00c6, 16, { 0x0d, 0x0c, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x0b, 0x02, 0x04, 0x1c, 0x90, 0x7f}}, - {0x00d6, 16, { 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x0b, 0x02, 0x04, 0x1c, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x53}}, - {0x00e6, 16, { 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x16, 0xff, 0x20, 0x0c, 0x2b, 0x20, 0x09, 0x28}}, - {0x00f6, 16, { 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x20, 0x30, 0x10, 0x11, 0x90, 0x7d, 0xc1, 0xe0, 0x13}}, - {0x0043, 3, { 0x02, 0x0e, 0x00}}, - {0x0000, 3, { 0x02, 0x00, 0x26}}, - {0x0026, 12, { 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x54, 0x02, 0x0b, 0x28}}, - {0x0106, 64, { 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x36, 0x75, 0x3a, 0x03, 0x02, 0x04, 0x1c, 0x75, 0x3a, 0x02, 0x90, 0x7d, - 0xc1, 0xe0, 0xf5, 0x36, 0x02, 0x04, 0x1c, 0x75, 0x3a, 0x01, 0xc2, 0x0b, 0x02, 0x04, 0x1c, 0xe5, - 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x03, 0x02, 0x01, 0xc9, 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, 0x07, - 0xc2, 0x14, 0xc2, 0x05, 0x02, 0x04, 0x1c, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x53, 0x90, 0x7e}}, - {0x0146, 64, { 0x40, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x16, 0xff, 0x20, 0x0c, 0x70, 0x20, 0x09, 0x6d, 0x90, 0x7f, 0x9b, - 0xe0, 0x55, 0x38, 0x70, 0x65, 0x30, 0x10, 0x10, 0x90, 0x7e, 0x41, 0xe0, 0x13, 0x92, 0x9b, 0xa3, - 0xe0, 0xf5, 0x99, 0x75, 0x3a, 0x03, 0x80, 0x09, 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x99, 0x75, 0x3a, - 0x02, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03}}, - {0x0186, 64, { 0x20, 0x0d, 0x03, 0x02, 0x04, 0x1c, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x1c, 0x30, - 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, - 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, - 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b, 0x02, 0x04, 0x1c, 0x75, 0x3a, 0x01, 0xc2, 0x14}}, - {0x01c6, 64, { 0x02, 0x04, 0x1c, 0x30, 0x0c, 0x03, 0x02, 0x02, 0x49, 0x20, 0x09, 0x77, 0x90, 0x7f, 0x9b, 0xe0, 0x55, - 0x38, 0x70, 0x6f, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, - 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, - 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x40}}, - {0x0206, 64, { 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03, 0x20, 0x0d, 0x03, 0x02, 0x04, 0x1c, 0xc2, 0x0d, 0x90, - 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x1c, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, - 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, - 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b}}, - {0x0246, 64, { 0x02, 0x04, 0x1c, 0xc2, 0x14, 0x02, 0x04, 0x1c, 0x20, 0x0b, 0x03, 0x02, 0x02, 0xff, 0xe5, 0x3a, 0xc3, - 0x95, 0x53, 0x50, 0x3c, 0x20, 0x0c, 0x34, 0x20, 0x09, 0x31, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, - 0x70, 0x29, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, - 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5}}, - {0x0286, 64, { 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0x02, 0x04, 0x1c, 0xc2, 0x0b, 0x02, 0x04, 0x1c, - 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x03, 0x30, 0x0d, 0x0c, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x04, - 0xf0, 0xc2, 0x0b, 0x02, 0x04, 0x1c, 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x0b, 0x02, - 0x04, 0x1c, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x53, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0d}}, - {0x02c6, 64, { 0x75, 0x16, 0xff, 0x20, 0x0c, 0x2b, 0x20, 0x09, 0x28, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x20, - 0x30, 0x10, 0x11, 0x90, 0x7e, 0x41, 0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x36, 0x75, 0x3a, - 0x03, 0x02, 0x04, 0x1c, 0x75, 0x3a, 0x02, 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x36, 0x02, 0x04, 0x1c, - 0x75, 0x3a, 0x01, 0xc2, 0x0b, 0x02, 0x04, 0x1c, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x03}}, - {0x0306, 64, { 0x02, 0x03, 0xa2, 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x14, 0xc2, 0x05, 0x02, 0x04, 0x1c, - 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x53, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x16, 0xff, - 0x20, 0x0c, 0x70, 0x20, 0x09, 0x6d, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x65, 0x30, 0x10, - 0x10, 0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x3a, 0x03}}, - {0x0346, 64, { 0x80, 0x09, 0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x3a, 0x02, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x40, - 0x17, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x03, 0x20, 0x0d, 0x03, 0x02, 0x04, 0x1c, 0xc2, 0x0d, - 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x1c, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, - 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a}}, - {0x0386, 64, { 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b, - 0x02, 0x04, 0x1c, 0x75, 0x3a, 0x01, 0xc2, 0x14, 0x02, 0x04, 0x1c, 0x20, 0x0c, 0x75, 0x20, 0x09, - 0x72, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x6a, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, - 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xaf}}, - {0x03c6, 64, { 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, - 0x3a, 0xc3, 0x95, 0x53, 0x40, 0x13, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x03, 0x30, 0x0d, 0x35, - 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, - 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf}}, - {0x0406, 64, { 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0xd2, - 0x0b, 0x80, 0x02, 0xc2, 0x14, 0xd2, 0x01, 0x20, 0x98, 0x03, 0x02, 0x05, 0x5a, 0xc2, 0x98, 0x20, - 0x02, 0x03, 0x02, 0x04, 0xc7, 0x20, 0x16, 0x27, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, - 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x10, 0x4d, 0xaf, 0x39, 0x05}}, - {0x0446, 64, { 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, - 0x99, 0x10, 0xe5, 0x10, 0xb5, 0x47, 0x04, 0xd2, 0x09, 0x80, 0x2e, 0xe5, 0x10, 0xb5, 0x46, 0x04, - 0xc2, 0x09, 0x80, 0x25, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, - 0xf5, 0x83, 0xe5, 0x10, 0xf0, 0x30, 0x10, 0x11, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f}}, - {0x0486, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0f, 0xe5, 0x39, 0xc3, 0x95, 0x43, - 0x50, 0x03, 0x02, 0x05, 0x58, 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x16, 0xe5, 0x39, 0xc3, 0x94, - 0x40, 0x50, 0x03, 0x02, 0x05, 0x58, 0x15, 0x39, 0x15, 0x39, 0x05, 0x2b, 0x43, 0x34, 0x01, 0x02, - 0x05, 0x58, 0x90, 0x7f, 0xb7, 0xe5, 0x39, 0xf0, 0x75, 0x39, 0x00, 0xc2, 0x02, 0x02, 0x05}}, - {0x04c6, 64, { 0x58, 0x20, 0x16, 0x27, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, - 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x10, 0x4d, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, - 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99, 0x10, 0xe5, 0x10, 0xb5, - 0x47, 0x04, 0xd2, 0x09, 0x80, 0x2e, 0xe5, 0x10, 0xb5, 0x46, 0x04, 0xc2, 0x09, 0x80, 0x25}}, - {0x0506, 64, { 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x10, 0xf0, - 0x30, 0x10, 0x11, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, - 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0f, 0xe5, 0x39, 0xc3, 0x95, 0x43, 0x40, 0x24, 0x90, 0x7f, 0xb6, - 0xe0, 0x30, 0xe1, 0x12, 0xe5, 0x39, 0xc3, 0x94, 0x40, 0x40, 0x16, 0x15, 0x39, 0x15, 0x39}}, - {0x0546, 64, { 0x05, 0x2b, 0x43, 0x34, 0x01, 0x80, 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x39, 0xf0, 0x75, 0x39, 0x00, 0xd2, - 0x02, 0xd2, 0x01, 0x30, 0x01, 0x05, 0xc2, 0x01, 0x02, 0x00, 0x56, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, - 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x51, 0xe5, 0x34, 0x60, - 0x4d, 0xe5, 0x31, 0x70, 0x49, 0xe5, 0x34, 0x30, 0xe1, 0x08, 0xe4, 0xf5, 0x2f, 0x75, 0x34}}, - {0x0586, 64, { 0x01, 0x80, 0x0b, 0xa2, 0x08, 0xe4, 0x33, 0xf5, 0x2f, 0xc2, 0x08, 0xe4, 0xf5, 0x34, 0xe4, 0xf5, 0x11, - 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x11, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0d, 0x06, - 0xff, 0x74, 0x00, 0x25, 0x11, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x11, - 0xe5, 0x11, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xbd, 0x74, 0x0c, 0xf0, 0x75, 0x31, 0x10, 0x90}}, - {0x05c6, 64, { 0x7f, 0xca, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x06, 0xf3, 0xe4, 0xf5, 0x11, 0x74, 0x40, 0x25, 0x11, 0xf5, - 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x11, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x3b, - 0xf9, 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x0d, 0x1f, 0x05, 0x11, 0xe5, 0x11, 0xb4, 0x18, 0xdb, - 0xe5, 0x3b, 0x60, 0x11, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x36, 0x85, 0x3c, 0xca, 0x85, 0x3d}}, - {0x0606, 64, { 0xcb, 0xe4, 0x90, 0x7f, 0x9f, 0xf0, 0xe5, 0x3e, 0x13, 0x92, 0x10, 0x92, 0x9f, 0x85, 0x3f, 0x38, 0xe5, - 0x40, 0x13, 0x92, 0x16, 0xe5, 0x41, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, - 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x42, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, - 0x54, 0x7f, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x48, 0x60}}, - {0x0646, 64, { 0x0b, 0xc2, 0x0c, 0xc2, 0x09, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x49, 0x60, 0x0c, 0xd2, - 0x09, 0x43, 0x34, 0x01, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x4a, 0x60, 0x0d, 0xc2, - 0xaf, 0xc2, 0x0b, 0xd2, 0x00, 0xe4, 0xf5, 0x53, 0xf5, 0x3a, 0xd2, 0xaf, 0xe5, 0x4b, 0x60, 0x05, - 0x30, 0x16, 0x02, 0xd2, 0x09, 0xe5, 0x4c, 0x60, 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd}}, - {0x0686, 64, { 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x4d, - 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98, 0x75, 0x2c, 0x01, 0x75, 0x31, 0x1e, 0xe5, 0x4e, 0x60, 0x07, - 0xc2, 0x9c, 0xe4, 0xf5, 0x39, 0xf5, 0x2c, 0xe5, 0x4f, 0x60, 0x03, 0xe4, 0xf5, 0x39, 0xe5, 0x50, - 0x60, 0x02, 0xd2, 0x07, 0xe5, 0x51, 0x60, 0x0a, 0xe5, 0x4d, 0x70, 0x02, 0xf5, 0x31, 0xe5}}, - {0x06c6, 64, { 0x51, 0x42, 0x34, 0xe5, 0x52, 0x60, 0x1f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, - 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, - 0xf0, 0xd2, 0x03, 0xd2, 0x02, 0xd2, 0x08, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0xa2, 0x0c, 0xe4, 0x33, - 0xff, 0x65, 0x29, 0x60, 0x05, 0x8f, 0x29, 0x43, 0x34, 0x01, 0xa2, 0x09, 0xe4, 0x33, 0xff}}, - {0x0706, 64, { 0x65, 0x2a, 0x60, 0x05, 0x8f, 0x2a, 0x43, 0x34, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0xff, 0x54, 0x08, 0x64, - 0x08, 0xfe, 0x65, 0x25, 0x60, 0x05, 0x8e, 0x25, 0x43, 0x34, 0x01, 0xef, 0x54, 0x10, 0x64, 0x10, - 0xfe, 0x65, 0x26, 0x60, 0x05, 0x8e, 0x26, 0x43, 0x34, 0x01, 0xef, 0x54, 0x40, 0x64, 0x40, 0xfe, - 0x65, 0x27, 0x60, 0x05, 0x8e, 0x27, 0x43, 0x34, 0x01, 0xef, 0x54, 0x20, 0x64, 0x20, 0xfe}}, - {0x0746, 64, { 0x65, 0x28, 0x60, 0x05, 0x8e, 0x28, 0x43, 0x34, 0x01, 0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x40, 0x64, 0x40, - 0xfe, 0x65, 0x2e, 0x60, 0x05, 0x8e, 0x2e, 0x43, 0x34, 0x01, 0x30, 0x07, 0x35, 0xc2, 0xaf, 0x30, - 0x02, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x39, 0x60, 0x09, 0x90, 0x7f, 0xb7, - 0xf0, 0xe4, 0xf5, 0x39, 0xc2, 0x02, 0xc2, 0x07, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20}}, - {0x0786, 64, { 0xe1, 0x0f, 0xe5, 0x39, 0x60, 0x09, 0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x39, 0xd2, 0x02, 0xc2, 0x07, - 0xd2, 0xaf, 0x20, 0x05, 0x3d, 0x30, 0x03, 0x1e, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x33, 0x90, - 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x3a, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x53, 0xd2, - 0x05, 0x75, 0x16, 0xff, 0x80, 0x1c, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x15, 0x90, 0x7d}}, - {0x07c6, 64, { 0xc0, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x3a, 0x01, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x53, 0xd2, 0x05, 0x75, - 0x16, 0xff, 0x20, 0x14, 0x33, 0x20, 0x00, 0x06, 0xe5, 0x3a, 0x65, 0x53, 0x70, 0x2a, 0x30, 0x05, - 0x1a, 0x30, 0x03, 0x09, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80, 0x07, 0xe4, 0x90, 0x7f, - 0xc9, 0xf0, 0xd2, 0x03, 0xc2, 0x05, 0xe4, 0xf5, 0x53, 0xf5, 0x3a, 0x30, 0x0d, 0x0a, 0xc2}}, - {0x0806, 64, { 0x0d, 0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0x30, 0x14, 0x03, 0x02, 0x09, 0x14, 0x20, 0x05, - 0x03, 0x02, 0x09, 0x14, 0x30, 0x0c, 0x03, 0x02, 0x09, 0x14, 0x30, 0x09, 0x03, 0x02, 0x09, 0x14, - 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x60, 0x03, 0x02, 0x09, 0x14, 0x30, 0x03, 0x61, 0x30, 0x10, - 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83}}, - {0x0846, 64, { 0xe0, 0x13, 0x92, 0x1b, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, - 0x83, 0xe0, 0xfe, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x2a, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, - 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, - 0x3a, 0x05, 0x3a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5}}, - {0x0886, 64, { 0x36, 0xd2, 0x0b, 0x80, 0x6a, 0xc2, 0x0b, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80, 0x5f, 0x30, - 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, - 0xe0, 0x13, 0x92, 0x1b, 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, - 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x2a, 0x30, 0x10, 0x12, 0xaf}}, - {0x08c6, 64, { 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, - 0xaf, 0x3a, 0x05, 0x3a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, - 0x36, 0xd2, 0x0b, 0x80, 0x09, 0xc2, 0x0b, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0x30, 0x10, - 0x04, 0xa2, 0x1b, 0x92, 0x9b, 0xd2, 0x14, 0xc2, 0xaf, 0x8e, 0x99, 0x20, 0x0b, 0x0d, 0x30}}, - {0x0906, 64, { 0x0d, 0x0a, 0xc2, 0x0d, 0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x22, 0x90, 0x7f, - 0xe9, 0xe0, 0x12, 0x0d, 0x31, 0x0a, 0x11, 0x00, 0x0a, 0x7e, 0x01, 0x0a, 0xdb, 0x03, 0x09, 0x38, - 0x06, 0x0a, 0x02, 0x08, 0x09, 0xf6, 0x09, 0x09, 0xde, 0x0a, 0x09, 0xed, 0x0b, 0x00, 0x00, 0x0b, - 0x19, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x5a, 0x24, 0x02, 0x60}}, - {0x0946, 64, { 0x03, 0x02, 0x0b, 0x19, 0x74, 0x0d, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x87, 0x90, 0x7f, 0xd5, 0xf0, 0x02, - 0x0b, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, - 0xd8, 0x75, 0x83, 0x0d, 0xef, 0xf0, 0x75, 0x82, 0xd1, 0x75, 0x83, 0x0d, 0xf0, 0x75, 0x82, 0xca, - 0x75, 0x83, 0x0d, 0xf0, 0x75, 0x82, 0xc3, 0x75, 0x83, 0x0d, 0xf0, 0x90, 0x7f, 0xea, 0xe0}}, - {0x0986, 64, { 0x04, 0x75, 0x82, 0x9e, 0x75, 0x83, 0x0d, 0xf0, 0x74, 0x0d, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x99, 0x90, - 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x0b, 0x75, 0x11, 0xff, 0x75, - 0x12, 0x0d, 0x75, 0x13, 0xdc, 0x80, 0x1b, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x0b, 0x75, 0x11, - 0xff, 0x75, 0x12, 0x0d, 0x75, 0x13, 0xe0, 0x80, 0x09, 0x75, 0x11, 0xff, 0x75, 0x12, 0x0d}}, - {0x09c6, 64, { 0x75, 0x13, 0xf0, 0xaa, 0x12, 0xa9, 0x13, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, - 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0x00, 0xe5, 0x15, 0xf0, 0x90, 0x7f, 0xb5, - 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x15, 0x02, 0x0b, 0x20, 0x12, - 0x0c, 0xb1, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x14, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0x00, 0xe5}}, - {0x0a06, 64, { 0x14, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, - 0x60, 0x27, 0x14, 0x60, 0x34, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x19, 0xa2, 0x17, 0xe4, 0x33, - 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x19, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, - 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x20, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3}}, - {0x0a46, 64, { 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, - 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, - 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, - 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x17}}, - {0x0a86, 64, { 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0b, - 0x19, 0xc2, 0x17, 0x02, 0x0b, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x76, 0x90, 0x7f, 0xec, 0xe0, - 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, - 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80}}, - {0x0ac6, 64, { 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, - 0x20, 0xf0, 0x80, 0x45, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x10, 0x24, 0x02, 0x70, 0x39, - 0x90, 0x7f, 0xea, 0xe0, 0x64, 0x01, 0x70, 0x2a, 0xd2, 0x17, 0x80, 0x2d, 0x90, 0x7f, 0xea, 0xe0, - 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0}}, - {0x0b06, 64, { 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, - 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, - 0x22, 0xc2, 0x10, 0xe4, 0xf5, 0x14, 0xf5, 0x34, 0xc2, 0x09, 0xc2, 0x0c, 0xc2, 0x0b, 0xc2, 0x14, - 0xc2, 0x0d, 0xc2, 0x16, 0xc2, 0x11, 0xc2, 0x07, 0xc2, 0x12, 0xc2, 0x0f, 0xc2, 0x08, 0xf5}}, - {0x0b46, 64, { 0x35, 0xf5, 0x39, 0xf5, 0x53, 0xf5, 0x3a, 0xf5, 0x33, 0xf5, 0x30, 0xf5, 0x2f, 0xf5, 0x2e, 0xf5, 0x2d, - 0xf5, 0x2c, 0xf5, 0x2b, 0xf5, 0x2a, 0xf5, 0x29, 0xf5, 0x28, 0xf5, 0x27, 0xf5, 0x26, 0xf5, 0x25, - 0xf5, 0x24, 0xc2, 0x05, 0xc2, 0x18, 0xc2, 0x1a, 0xc2, 0x17, 0xc2, 0x19, 0xc2, 0x15, 0xc2, 0x04, - 0xd2, 0x13, 0xc2, 0x06, 0xc2, 0x01, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0xd2, 0xe8}}, - {0x0b86, 64, { 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, - 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, - 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0f, 0xf0, 0x90, 0x7f, 0xac, 0x74, 0x0e, - 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0x1b, 0x12, 0x0f, 0x5f, 0xc2, 0x18, 0x30, 0x04, 0x03}}, - {0x0bc6, 64, { 0x12, 0x05, 0x6d, 0x30, 0x04, 0x2a, 0x30, 0x06, 0x27, 0xc2, 0x06, 0xe5, 0x16, 0x60, 0x16, 0x15, 0x16, - 0x90, 0x7f, 0xd8, 0xe0, 0x30, 0xe6, 0x04, 0x7f, 0x00, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96, - 0xef, 0xf0, 0x80, 0x06, 0x90, 0x7f, 0x96, 0x74, 0x20, 0xf0, 0x12, 0x0c, 0x0b, 0x80, 0xcd, 0x30, - 0x18, 0x07, 0xc2, 0x18, 0x12, 0x09, 0x15, 0x80, 0xc3, 0x30, 0x1a, 0xc0, 0xc2, 0x1a, 0x12}}, - {0x0c06, 64, { 0x0f, 0xbb, 0x80, 0xb9, 0x22, 0xe5, 0x31, 0x60, 0x02, 0x15, 0x31, 0xe5, 0x39, 0x60, 0x55, 0x65, 0x35, - 0x70, 0x4b, 0xe5, 0x33, 0xf4, 0x60, 0x02, 0x05, 0x33, 0xe5, 0x33, 0xc3, 0x95, 0x44, 0x40, 0x43, - 0xc2, 0xaf, 0x30, 0x02, 0x1b, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7f, 0xb7, 0xe5, - 0x39, 0xf0, 0xc2, 0x02, 0xe4, 0xf5, 0x39, 0xf5, 0x33, 0xf5, 0x35, 0x75, 0x16, 0xff, 0x80}}, - {0x0c46, 64, { 0x19, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7f, 0xb9, 0xe5, 0x39, 0xf0, 0xd2, 0x02, 0xe4, - 0xf5, 0x39, 0xf5, 0x33, 0xf5, 0x35, 0x75, 0x16, 0xff, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x39, 0x35, - 0xe4, 0xf5, 0x33, 0xe5, 0x2c, 0x60, 0x30, 0x20, 0x0f, 0x07, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, - 0x0f, 0xe5, 0x2d, 0x60, 0x06, 0xe4, 0xf5, 0x2d, 0x43, 0x34, 0x01, 0xe4, 0xf5, 0x30, 0x80}}, - {0x0c86, 64, { 0x14, 0xe5, 0x30, 0xd3, 0x95, 0x45, 0x50, 0x0d, 0xe5, 0x30, 0xb5, 0x45, 0x06, 0x75, 0x2d, 0x01, 0x43, - 0x34, 0x01, 0x05, 0x30, 0xc2, 0x0f, 0x22, 0x90, 0x7f, 0xd9, 0xe0, 0x30, 0xe2, 0x04, 0x7f, 0x00, - 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, - 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x20, 0xf0, 0x90, 0x7f, 0x94, 0x74}}, - {0x0cc6, 64, { 0x01, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x97, 0x74, 0x86, 0xf0, 0x90, 0x7f, 0x95, - 0x74, 0x03, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84, 0xf0, 0x90, 0x7f, 0x98, 0xf0, 0xe4, 0x90, 0x7f, - 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x75, 0x98, 0x40, 0x43, 0xa8, 0x10, - 0x90, 0x7f, 0xde, 0x74, 0x1f, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x0f, 0xf0, 0xd2, 0x04, 0x22}}, - {0x0d06, 64, { 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, - 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, - 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, - 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93}}, - {0x0d46, 64, { 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, - 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, - 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, - 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0d86, 64, { 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x0c, 0x01, 0x01, 0x00, 0x01, 0x02, - 0x00, 0x02, 0x09, 0x02, 0x43, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x07, - 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00}}, - {0x0dc6, 64, { 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, - 0x84, 0x02, 0x40, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, - 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x0e, 0x03, 0x53, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x02, 0x0e, 0xa2, 0x00, 0x02, 0x0e}}, - {0x0e06, 64, { 0x7b, 0x00, 0x02, 0x0d, 0x57, 0x00, 0x02, 0x0e, 0xc9, 0x00, 0x02, 0x0e, 0x10, 0x00, 0x02, 0x0e, 0x14, - 0x00, 0x02, 0x0e, 0x18, 0x00, 0x02, 0x0e, 0x1c, 0x00, 0x02, 0x0e, 0xf0, 0x00, 0x02, 0x0e, 0x24, - 0x00, 0x02, 0x0f, 0x15, 0x00, 0x02, 0x0e, 0x2c, 0x00, 0x02, 0x0f, 0x3a, 0xe4, 0x90, 0x7f, 0x95, - 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x02}}, - {0x0e46, 64, { 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x10, 0xf0, 0xe4, 0x90, 0x7f, - 0x96, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xfe, 0xf0, 0x30, 0x17, 0x04, 0x7f, 0x80, 0x80, 0x02, 0x7f, - 0x00, 0x90, 0x7f, 0x97, 0xef, 0xf0, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0xf0, 0x90, - 0x7f, 0x98, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0}}, - {0x0e86, 64, { 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd2, 0x06, 0xd0, 0x86, - 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, - 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, - 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83}}, - {0x0ec6, 64, { 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, - 0x00, 0xd2, 0x1a, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, - 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, - 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74}}, - {0x0f06, 64, { 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, - 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, - 0x90, 0x7f, 0xa9, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, - 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86}}, - {0x0f46, 64, { 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, - 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, - 0x44, 0x08, 0xf0, 0x30, 0x1b, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, - 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x74, 0x00}}, - {0x0f86, 64, { 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, - 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x90, 0x7f, - 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, 0xe0, - 0x54, 0xfe, 0xf0, 0x22, 0x12, 0x0e, 0x33, 0x12, 0x0f, 0x95, 0x90, 0x7f, 0xd6, 0xe0, 0x30}}, - {0x0fc6, 9, { 0xe7, 0x03, 0x12, 0x0f, 0xa5, 0x12, 0x0c, 0xb1, 0x22}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa19qw_fw.h b/drivers/usb/serial/keyspan_usa19qw_fw.h deleted file mode 100644 index 0803f8b..0000000 --- a/drivers/usb/serial/keyspan_usa19qw_fw.h +++ /dev/null @@ -1,448 +0,0 @@ -/* keyspan_usa19qw_fw.h - - The firmware contained herein as keyspan_usa19wq_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -*/ - -static const struct ezusb_hex_record keyspan_usa19qw_firmware[] = { - {0x0033, 3, { 0x02, 0x00, 0x2d}}, - {0x002d, 4, { 0x53, 0xd8, 0xef, 0x32}}, - {0x0046, 16, { 0x30, 0x10, 0x19, 0x12, 0x0e, 0x0f, 0xef, 0xc3, 0x95, 0x14, 0x40, 0x03, 0x02, 0x00, 0xdf, 0x90}}, - {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x10, 0xc2, 0x0b, 0x02, 0x00, 0xdf, 0x30, 0x0d, 0x3e, 0x90}}, - {0x0066, 16, { 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x73, 0x12, 0x0e, 0x0f, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x6a, 0x90}}, - {0x0076, 16, { 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x10, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x36, 0x20, 0x0b, 0x11}}, - {0x0086, 16, { 0x60, 0x0f, 0xf5, 0x24, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x29, 0x7e, 0x75, 0x2a, 0x41, 0x12, 0x09}}, - {0x0096, 16, { 0x10, 0xc2, 0x0d, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x75, 0x26, 0xff, 0x80, 0x3c, 0x90, 0x7f, 0xc8}}, - {0x00a6, 16, { 0xe0, 0x20, 0xe1, 0x35, 0x12, 0x0e, 0x0f, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x2c, 0x90, 0x7d, 0xc0}}, - {0x00b6, 16, { 0xe0, 0x13, 0x92, 0x10, 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x36, 0x20, 0x0b, 0x11, 0x60, 0x0f}}, - {0x00c6, 16, { 0xf5, 0x24, 0x7e, 0x7d, 0x7f, 0xc1, 0x75, 0x29, 0x7d, 0x75, 0x2a, 0xc1, 0x12, 0x09, 0x10, 0xd2}}, - {0x00d6, 16, { 0x0d, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0x75, 0x26, 0xff, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03}}, - {0x00e6, 16, { 0x02, 0x01, 0x68, 0x12, 0x0c, 0xff, 0x8f, 0x36, 0x12, 0x0e, 0x1b, 0x8f, 0x11, 0xe5, 0x36, 0xc3}}, - {0x00f6, 16, { 0x95, 0x13, 0x50, 0x0f, 0x12, 0x0d, 0xde, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x11, 0x20, 0xe7, 0x03}}, - {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0043, 3, { 0x02, 0x0e, 0x00}}, - {0x0003, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90}}, - {0x0013, 16, { 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0}}, - {0x0023, 10, { 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32}}, - {0x0000, 3, { 0x02, 0x09, 0xc5}}, - {0x0106, 64, { 0x30, 0x13, 0x5f, 0xc2, 0x13, 0xe5, 0x36, 0x60, 0x59, 0xb4, 0x80, 0x03, 0x43, 0x11, 0x02, 0xe5, 0x11, - 0x30, 0xe7, 0x24, 0xe5, 0x36, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x36, 0x20, 0x85, 0x36, 0x24, - 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x29, 0x7e, 0x75, 0x2a, 0x80, 0x12, 0x0b, 0x9a, 0xe5, 0x36, 0x25, - 0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x2a, 0xe5, 0x36, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75}}, - {0x0146, 64, { 0x36, 0x3f, 0x85, 0x36, 0x24, 0x90, 0x7e, 0x80, 0xe5, 0x11, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x29, - 0x7e, 0x75, 0x2a, 0x81, 0x12, 0x09, 0x35, 0xe5, 0x36, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x75, 0x26, - 0xff, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x0e, 0x03, 0x02, 0x03, 0xc4, 0xe4, 0xf5, - 0x35, 0x74, 0x40, 0x25, 0x35, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5}}, - {0x0186, 64, { 0x35, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, - 0x12, 0x0a, 0x97, 0x05, 0x35, 0xe5, 0x35, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x6e, - 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x0c, 0xda, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, - 0x0c, 0x1c, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x0c, 0x42, 0xd2, 0x11, 0xd2, 0x12, 0x75}}, - {0x01c6, 64, { 0x36, 0x04, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x05, 0xc2, 0x12, 0x43, 0x36, 0xc0, 0x90, 0x7e, 0x04, 0xe0, - 0xb4, 0x01, 0x07, 0xc2, 0x12, 0x43, 0x36, 0x0b, 0x80, 0x10, 0x90, 0x7e, 0x04, 0xe0, 0x60, 0x07, - 0xc2, 0x11, 0x43, 0x36, 0x09, 0x80, 0x03, 0x43, 0x36, 0x02, 0x7f, 0x03, 0xad, 0x36, 0x12, 0x0c, - 0xda, 0x43, 0x1a, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x1a}}, - {0x0206, 64, { 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x17, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, - 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x19, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, - 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x42, 0x90, 0x7e, 0x13, 0xe0, - 0x60, 0x05, 0x43, 0x16, 0x04, 0x80, 0x03, 0x53, 0x16, 0xfb, 0xe4, 0xff, 0xad, 0x16, 0x12}}, - {0x0246, 64, { 0x0c, 0xda, 0x90, 0x7e, 0x08, 0xe0, 0x60, 0x05, 0x43, 0x18, 0x80, 0x80, 0x03, 0x53, 0x18, 0x7f, 0x53, - 0x18, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x18, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x0c, - 0x8e, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x0c, 0xb4, 0xaf, 0x18, 0x12, 0x0c, 0x68, 0x90, 0x7e, - 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x1a, 0x01, 0x80, 0x03, 0x53, 0x1a}}, - {0x0286, 64, { 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x1a, 0xf0, 0x90, 0x7e, 0x0c, 0xe0, - 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x1a, 0x02, 0x80, 0x03, 0x53, 0x1a, 0xfd, 0x90, 0x7f, - 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x1a, 0xf0, 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x13, - 0xa3, 0xe0, 0x13, 0x92, 0x14, 0xa3, 0xe0, 0xf5, 0x14, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x1a}}, - {0x02c6, 64, { 0x10, 0x80, 0x03, 0x53, 0x1a, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x1a, - 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x19, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, - 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x12, 0x0d, - 0xd2, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x16, 0xfd, 0xe4, 0xff, 0xad, 0x16}}, - {0x0306, 64, { 0x12, 0x0c, 0xda, 0xe4, 0xf5, 0x0e, 0xf5, 0x0d, 0xd2, 0x0f, 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, - 0x16, 0x02, 0xe4, 0xff, 0xad, 0x16, 0x12, 0x0c, 0xda, 0x75, 0x0d, 0x01, 0xd2, 0x0f, 0x90, 0x7e, - 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x17, 0x44, 0x04, 0x90, 0xc0, - 0x00, 0xf0, 0xd2, 0x0b, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x19, 0x40, 0x90, 0x7f}}, - {0x0346, 64, { 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, - 0x0f, 0x53, 0x16, 0xfe, 0xe4, 0xff, 0xad, 0x16, 0x12, 0x0c, 0xda, 0x75, 0x0f, 0x01, 0xd2, 0x0f, - 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x16, 0x01, 0xe4, 0xff, 0xad, 0x16, 0x12, 0x0c, 0xda, - 0xe4, 0xf5, 0x0f, 0xd2, 0x0f, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74}}, - {0x0386, 64, { 0x12, 0xf0, 0xe5, 0x17, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, - 0x13, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x10, 0x01, 0xe4, 0xf5, 0x12, 0xd2, 0x0f, 0x90, - 0x7e, 0x1f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, - 0xf0, 0x74, 0x35, 0xf0, 0xd2, 0x0d, 0xc2, 0x0e, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x16}}, - {0x03c6, 64, { 0x71, 0xe5, 0x12, 0x60, 0x02, 0x15, 0x12, 0xe5, 0x30, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x30, 0x80, - 0x60, 0x75, 0x30, 0x0a, 0x12, 0x0d, 0xd2, 0xef, 0x54, 0x01, 0xf5, 0x36, 0x65, 0x0e, 0x60, 0x07, - 0x85, 0x36, 0x0e, 0xd2, 0x0f, 0x80, 0x11, 0x12, 0x0e, 0x27, 0xef, 0x54, 0x10, 0xf5, 0x36, 0x65, - 0x09, 0x60, 0x05, 0x85, 0x36, 0x09, 0xd2, 0x0f, 0x12, 0x0e, 0x27, 0xef, 0x54, 0x80, 0xf5}}, - {0x0406, 64, { 0x36, 0x65, 0x0a, 0x60, 0x05, 0x85, 0x36, 0x0a, 0xd2, 0x0f, 0x12, 0x0e, 0x27, 0xef, 0x54, 0x20, 0xf5, - 0x36, 0x65, 0x0b, 0x60, 0x08, 0x85, 0x36, 0x0b, 0x30, 0x11, 0x02, 0xd2, 0x0f, 0x12, 0x0e, 0x27, - 0xef, 0x54, 0x40, 0xf5, 0x36, 0x65, 0x0c, 0x60, 0x08, 0x85, 0x36, 0x0c, 0x30, 0x12, 0x02, 0xd2, - 0x0f, 0x30, 0x16, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0}}, - {0x0446, 64, { 0x60, 0x09, 0xe0, 0xf5, 0x32, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x33, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, - 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, - 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x29, 0xe5, 0x27, 0x70, 0x40, 0x30, 0x0f, 0x39, 0xe5, - 0x12, 0x70, 0x35, 0xc2, 0x0f, 0xf5, 0x35, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x08, 0x25, 0x35}}, - {0x0486, 64, { 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0a, 0x51, 0xff, 0x74, 0x80, 0x25, 0x35, 0xf5, 0x82, 0xe4, 0x34, - 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x35, 0xe5, 0x35, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, - 0x09, 0xf0, 0x75, 0x12, 0x10, 0xe4, 0xf5, 0x10, 0x75, 0x27, 0x02, 0x22, 0xe5, 0x27, 0x64, 0x02, - 0x70, 0x36, 0x30, 0x05, 0x2f, 0xc2, 0x05, 0xf5, 0x35, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2b}}, - {0x04c6, 64, { 0x25, 0x35, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0a, 0x51, 0xff, 0x74, 0x80, 0x25, 0x35, 0xf5, 0x82, - 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x35, 0xe5, 0x35, 0xb4, 0x05, 0xdb, 0x90, 0x7f, - 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x27, 0x03, 0x22, 0xe5, 0x32, 0x60, 0x33, 0x75, 0x31, 0x03, 0x15, - 0x32, 0xe4, 0xf5, 0x35, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x31, 0x25, 0x35, 0xf9, 0xee, 0x34}}, - {0x0506, 64, { 0x00, 0xfa, 0x12, 0x0a, 0x51, 0xff, 0x74, 0x80, 0x25, 0x35, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, - 0xef, 0xf0, 0x05, 0x35, 0xe5, 0x35, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, - 0xf5, 0x27, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0a, 0xa9, 0x06, 0x08, 0x00, 0x06, 0x7c, 0x01, - 0x06, 0xe9, 0x03, 0x05, 0x4d, 0x06, 0x05, 0xf9, 0x08, 0x05, 0xed, 0x09, 0x05, 0xd5, 0x0a}}, - {0x0546, 64, { 0x05, 0xe4, 0x0b, 0x00, 0x00, 0x07, 0x39, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, - 0x50, 0x24, 0x02, 0x70, 0x6f, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, - 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, - 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19, 0xf0}}, - {0x0586, 64, { 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, - 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, - 0x40, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0b, 0x1c, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, - 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xb4, 0xe0, 0x44}}, - {0x05c6, 64, { 0x01, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, - 0x00, 0xe5, 0x25, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xea, - 0xe0, 0xf5, 0x25, 0x02, 0x07, 0x40, 0x12, 0x07, 0x48, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x23, 0x02, - 0x07, 0x40, 0x90, 0x7f, 0x00, 0xe5, 0x23, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02}}, - {0x0606, 64, { 0x07, 0x40, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, - 0xa2, 0x01, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x07, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, - 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x40, 0xe4, 0x90, 0x7f, - 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f}}, - {0x0646, 64, { 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, - 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, - 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1e, 0x24, 0x02}}, - {0x0686, 64, { 0x60, 0x03, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x06, 0x12, 0x0d, 0xf9, 0x02, 0x07, - 0x40, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x40, 0x90, 0x7f, 0xea, 0xe0, 0x70, - 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, - 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90}}, - {0x06c6, 64, { 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, - 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x60, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, - 0x80, 0x57, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x24, 0x02, 0x70, 0x4b, 0x90, 0x7f, - 0xea, 0xe0, 0xb4, 0x01, 0x05, 0x12, 0x0d, 0xf6, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44}}, - {0x0706, 64, { 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, - 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, - 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, - 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02}}, - {0x0746, 64, { 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0x74, - 0x20, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, - 0xf0, 0xe4, 0xf5, 0x08, 0x7f, 0x01, 0x7b, 0x00, 0x74, 0x08, 0x2f, 0xf9, 0xe4, 0x34, 0x00}}, - {0x0786, 64, { 0xfa, 0xe4, 0x12, 0x0a, 0x97, 0x0f, 0xbf, 0x09, 0xee, 0x75, 0x13, 0x01, 0xe4, 0xf5, 0x12, 0xf5, 0x30, - 0xf5, 0x11, 0xc2, 0x0f, 0xc2, 0x13, 0xc2, 0x0e, 0xc2, 0x0b, 0xc2, 0x10, 0xc2, 0x04, 0x90, 0x7f, - 0x98, 0x74, 0x13, 0xf0, 0x75, 0x19, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, - 0xfd, 0x12, 0x0c, 0xda, 0x7f, 0x10, 0x8f, 0x18, 0x12, 0x0c, 0x68, 0x90, 0x7f, 0x98, 0x74}}, - {0x07c6, 64, { 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x17, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, - 0x0c, 0xda, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x16, 0x12, 0x0c, 0xda, 0x90, 0x7f, 0x98, - 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x0c, 0xda, 0x7f, - 0x01, 0x12, 0x0d, 0x6a, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x0c, 0xda, 0xe4, 0xff, 0xe5, 0x16}}, - {0x0806, 64, { 0x54, 0x7f, 0xfd, 0x12, 0x0c, 0xda, 0x12, 0x0e, 0x0f, 0x8f, 0x15, 0xe4, 0xff, 0xe5, 0x16, 0x44, 0x80, - 0xfd, 0x12, 0x0c, 0xda, 0xe5, 0x15, 0x30, 0xe7, 0x04, 0xc2, 0x08, 0x80, 0x02, 0xd2, 0x08, 0x90, - 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x75, 0x1a, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0x03, - 0x22, 0xd2, 0x15, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x0d, 0xf9, 0xd2, 0xe8}}, - {0x0846, 64, { 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, - 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, - 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x16, 0x12, 0x0d, - 0x24, 0xc2, 0x02, 0xe4, 0xf5, 0x28, 0xf5, 0x30, 0xc2, 0x09, 0xf5, 0x23, 0xc2, 0x03, 0x90}}, - {0x0886, 64, { 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x34, 0x60, 0x48, 0x30, 0x03, 0x05, 0xd2, 0x16, - 0x12, 0x00, 0x46, 0xe5, 0x0f, 0x60, 0x22, 0xe5, 0x26, 0x60, 0x16, 0x15, 0x26, 0x90, 0x7f, 0xd8, - 0xe0, 0x30, 0xe6, 0x04, 0x7f, 0x20, 0x80, 0x02, 0x7f, 0x30, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x80, - 0x1a, 0x90, 0x7f, 0x96, 0x74, 0x30, 0xf0, 0x80, 0x12, 0x90, 0x7f, 0xd9, 0xe0, 0x30, 0xe2}}, - {0x08c6, 64, { 0x04, 0x7f, 0x30, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, - 0x34, 0x80, 0x20, 0x30, 0x03, 0x07, 0xc2, 0x16, 0x12, 0x00, 0x46, 0x80, 0x16, 0xe5, 0x0f, 0x70, - 0x12, 0x90, 0x7f, 0xd9, 0xe0, 0x30, 0xe2, 0x04, 0x7f, 0x30, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, - 0x96, 0xef, 0xf0, 0x30, 0x02, 0x07, 0xc2, 0x02, 0x12, 0x05, 0x2a, 0x80, 0x86, 0x30, 0x0a}}, - {0x0906, 64, { 0x83, 0xc2, 0x0a, 0x12, 0x0b, 0x5d, 0x02, 0x08, 0x8a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, - 0x24, 0xe5, 0x2a, 0xf5, 0x82, 0xe5, 0x29, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, - 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, - 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x24, 0xe5, 0x2a, 0xf5, 0x82, 0xe5, 0x29, 0xf5, 0x83, 0xc2}}, - {0x0946, 64, { 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, - 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x24, 0xe5, 0x2a, 0xf5, 0x82, 0xe5, - 0x29, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, - 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf}}, - {0x0986, 64, { 0x24, 0xe5, 0x2a, 0xf5, 0x82, 0xe5, 0x29, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, - 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, - 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, - 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x78}}, - {0x09c6, 64, { 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x39, 0x02, 0x0a, 0x0c, 0x02, 0x08, 0x38, 0xe4, 0x93, 0xa3, - 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, - 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, - 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02}}, - {0x0a06, 64, { 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x0d, 0x8b, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, - 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, - 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, - 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82}}, - {0x0a46, 64, { 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, - 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, - 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, - 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25}}, - {0x0a86, 64, { 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, - 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, - 0xf3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, - 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02}}, - {0x0ac6, 64, { 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, - 0x74, 0x20, 0xf0, 0x30, 0x01, 0x03, 0xff, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x7f, 0x96, 0xef, 0xf0, - 0xe4, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, - 0x30, 0x08, 0x11, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0x90, 0x7f}}, - {0x0b06, 64, { 0x98, 0x74, 0x20, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xdf, 0xf0, 0xe4, - 0x90, 0x7f, 0x98, 0xf0, 0x22, 0x8f, 0x35, 0xe4, 0xf5, 0x36, 0x75, 0x37, 0xff, 0x75, 0x38, 0x19, - 0x75, 0x39, 0x86, 0xab, 0x37, 0xaa, 0x38, 0xa9, 0x39, 0x90, 0x00, 0x01, 0x12, 0x0a, 0x6a, 0xb4, - 0x03, 0x1d, 0xaf, 0x36, 0x05, 0x36, 0xef, 0xb5, 0x35, 0x01, 0x22, 0x12, 0x0a, 0x51, 0x7e}}, - {0x0b46, 64, { 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x37, 0xff, 0xf5, 0x38, 0x89, 0x39, 0x80, 0xd4, 0x7b, - 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x35, 0x12, 0x0a, 0xcf, 0x20, - 0x08, 0x07, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, - 0x12, 0x09, 0xb5, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0e, 0x30, 0x01, 0x05, 0x12, 0x0d}}, - {0x0b86, 64, { 0xbc, 0x80, 0x06, 0x12, 0x0d, 0x49, 0xef, 0x60, 0xe1, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x12, - 0x07, 0x48, 0x22, 0x05, 0x2a, 0xe5, 0x2a, 0xae, 0x29, 0x70, 0x02, 0x05, 0x29, 0x14, 0xf5, 0x82, - 0x8e, 0x83, 0xe5, 0x11, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x2a, 0xe5, 0x2a, 0xac, 0x29, 0x70, 0x02, - 0x05, 0x29, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x24, 0xe5, 0x24, 0x60, 0x07}}, - {0x0bc6, 64, { 0x12, 0x0e, 0x1b, 0x8f, 0x11, 0x80, 0xcd, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, - 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x02, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, - 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, - 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x0a}}, - {0x0c06, 64, { 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, - 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, - 0x13, 0xf0, 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74}}, - {0x0c46, 64, { 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, - 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, - 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5}}, - {0x0c86, 64, { 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, - 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, - 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0}}, - {0x0cc6, 64, { 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, - 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x19, 0x54, 0x7f, 0x90, 0xc0, 0x00, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, - 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x0d, 0xea, 0x8f, 0x37, 0x12, 0x0d}}, - {0x0d06, 64, { 0xea, 0x8f, 0x38, 0xe5, 0x37, 0x65, 0x38, 0x60, 0x12, 0x12, 0x0d, 0xea, 0x8f, 0x37, 0xe5, 0x37, 0x65, - 0x38, 0x60, 0x07, 0x12, 0x0d, 0xea, 0x8f, 0x38, 0x80, 0xe8, 0xaf, 0x37, 0x22, 0x90, 0x7f, 0xd6, - 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x16, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, - 0xf4, 0x7e, 0x01, 0x12, 0x0d, 0xa5, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44}}, - {0x0d46, 64, { 0x04, 0xf0, 0x22, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x36, 0x12, 0x07, 0x48, 0x12, 0x0e, 0x27, 0xef, 0x30, - 0xe6, 0x0b, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x36, 0x60, 0xf1, 0x7f, 0x01, 0x22, 0x12, 0x0a, 0xcf, - 0x7f, 0x00, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x16, 0x54, 0x7f, 0xfd, 0x12, 0x0c, 0xda, 0x90, - 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x16, 0x44, 0x80}}, - {0x0d86, 64, { 0xfd, 0x12, 0x0c, 0xda, 0x22, 0x05, 0x2b, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x31, 0x03, 0x00, 0x00, - 0xc1, 0x86, 0xc1, 0x02, 0xc1, 0x0a, 0xc1, 0x01, 0xc1, 0x07, 0x01, 0x27, 0x00, 0x00, 0x8e, 0x36, - 0x8f, 0x37, 0xe5, 0x37, 0x15, 0x37, 0xae, 0x36, 0x70, 0x02, 0x15, 0x36, 0x4e, 0x60, 0x05, 0x12, - 0x09, 0xa4, 0x80, 0xee, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e}}, - {0x0dc6, 64, { 0x00, 0x12, 0x0d, 0xa5, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x11, - 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, - 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xd2, - 0x01, 0x22, 0xc2, 0x01, 0x22, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0b, 0xce, 0x00, 0x02, 0x0e}}, - {0x0e06, 64, { 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x0b, 0xf5, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0e46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0e86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0ec6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0f06, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0f46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0f86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0fc6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1006, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1046, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1086, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x10c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1106, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1146, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1186, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x11c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1206, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1246, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1286, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x12c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1306, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1346, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1386, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x19, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 4, { 0x72, 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa19w_fw.h b/drivers/usb/serial/keyspan_usa19w_fw.h deleted file mode 100644 index 75d6191..0000000 --- a/drivers/usb/serial/keyspan_usa19w_fw.h +++ /dev/null @@ -1,446 +0,0 @@ -/* keyspan_usa19w_fw.h - - The firmware contained herein as keyspan_usa19w_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." -*/ - -static const struct ezusb_hex_record keyspan_usa19w_firmware[] = { - {0x0033, 3, { 0x02, 0x0d, 0x5c}}, - {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}}, - {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}}, - {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x17, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}}, - {0x0046, 16, { 0x30, 0x0f, 0x18, 0x12, 0x0d, 0x38, 0xef, 0xc3, 0x95, 0x14, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}}, - {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x0f, 0xc2, 0x0a, 0x80, 0x77, 0x30, 0x0c, 0x3b, 0x90, 0x7f}}, - {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x0d, 0x38, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}}, - {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x0f, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x1c, 0x20, 0x0a, 0x11, 0x60}}, - {0x0086, 16, { 0x0f, 0xf5, 0x23, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x27, 0x7e, 0x75, 0x28, 0x41, 0x12, 0x08, 0x01}}, - {0x0096, 16, { 0xc2, 0x0c, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}}, - {0x00a6, 16, { 0x12, 0x0d, 0x38, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0f}}, - {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x1c, 0x20, 0x0a, 0x11, 0x60, 0x0f, 0xf5, 0x23, 0x7e, 0x7d}}, - {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x27, 0x7d, 0x75, 0x28, 0xc1, 0x12, 0x08, 0x01, 0xd2, 0x0c, 0xe4, 0x90, 0x7f}}, - {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x5e, 0x12, 0x0c, 0x41, 0x8f}}, - {0x00e6, 16, { 0x1c, 0x12, 0x0d, 0x44, 0x8f, 0x11, 0xe5, 0x1c, 0xc3, 0x95, 0x13, 0x50, 0x0f, 0x12, 0x0d, 0x20}}, - {0x00f6, 16, { 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x11, 0x20, 0xe7, 0x03, 0x30, 0x12, 0x5c, 0xc2, 0x12, 0xe5, 0x1c}}, - {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0043, 3, { 0x02, 0x0e, 0x00}}, - {0x0000, 3, { 0x02, 0x08, 0xb6}}, - {0x0106, 64, { 0x60, 0x56, 0xb4, 0x80, 0x03, 0x43, 0x11, 0x02, 0xe5, 0x11, 0x30, 0xe7, 0x24, 0xe5, 0x1c, 0xd3, 0x94, - 0x20, 0x40, 0x03, 0x75, 0x1c, 0x20, 0x85, 0x1c, 0x23, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x27, 0x7e, - 0x75, 0x28, 0x80, 0x12, 0x0a, 0x86, 0xe5, 0x1c, 0x25, 0x1c, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x27, - 0xe5, 0x1c, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x1c, 0x3f, 0x85, 0x1c, 0x23, 0x90, 0x7e}}, - {0x0146, 64, { 0x80, 0xe5, 0x11, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x27, 0x7e, 0x75, 0x28, 0x81, 0x12, 0x08, 0x26, - 0xe5, 0x1c, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x0d, - 0x03, 0x02, 0x03, 0xba, 0xe4, 0xf5, 0x1b, 0x74, 0x40, 0x25, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0x7c, - 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1b, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24}}, - {0x0186, 64, { 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0a, 0x0d, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x20, 0xd7, - 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x6e, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x0c, 0x1c, - 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x0b, 0x5e, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x0b, 0x84, - 0xd2, 0x10, 0xd2, 0x11, 0x75, 0x1c, 0x04, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x05, 0xc2, 0x11}}, - {0x01c6, 64, { 0x43, 0x1c, 0xc0, 0x90, 0x7e, 0x04, 0xe0, 0xb4, 0x01, 0x07, 0xc2, 0x11, 0x43, 0x1c, 0x0b, 0x80, 0x10, - 0x90, 0x7e, 0x04, 0xe0, 0x60, 0x07, 0xc2, 0x10, 0x43, 0x1c, 0x09, 0x80, 0x03, 0x43, 0x1c, 0x02, - 0x7f, 0x03, 0xad, 0x1c, 0x12, 0x0c, 0x1c, 0x43, 0x19, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, - 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x16, 0x44}}, - {0x0206, 64, { 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x18, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x18, 0xf0, 0x90, 0x7e, 0x07, 0xe0, - 0x60, 0x42, 0x90, 0x7e, 0x13, 0xe0, 0x60, 0x05, 0x43, 0x15, 0x04, 0x80, 0x03, 0x53, 0x15, 0xfb, - 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0x1c, 0x90, 0x7e, 0x08, 0xe0, 0x60, 0x05, 0x43, 0x17}}, - {0x0246, 64, { 0x80, 0x80, 0x03, 0x53, 0x17, 0x7f, 0x53, 0x17, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x17, - 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x0b, 0xd0, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x0b, 0xf6, 0xaf, - 0x17, 0x12, 0x0b, 0xaa, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x19, - 0x01, 0x80, 0x03, 0x53, 0x19, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00}}, - {0x0286, 64, { 0xe5, 0x19, 0xf0, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x19, 0x02, 0x80, - 0x03, 0x53, 0x19, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, - 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x13, 0xa3, 0xe0, 0x13, 0x92, 0x13, 0xa3, 0xe0, 0xf5, 0x14, 0xa3, - 0xe0, 0x60, 0x05, 0x43, 0x19, 0x10, 0x80, 0x03, 0x53, 0x19, 0xef, 0x90, 0x7f, 0x98, 0x74}}, - {0x02c6, 64, { 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x18, 0xbf, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x11, 0xf0, 0x12, 0x0d, 0x14, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x15, - 0xfd, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0x1c, 0xe4, 0xf5, 0x0e, 0xf5, 0x0d, 0xd2, 0x0e}}, - {0x0306, 64, { 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x15, 0x02, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0x1c, 0x75, - 0x0d, 0x01, 0xd2, 0x0e, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, - 0xe5, 0x16, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x0a, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, - 0x43, 0x18, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0}}, - {0x0346, 64, { 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x15, 0xfe, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, - 0x1c, 0x75, 0x0f, 0x01, 0xd2, 0x0e, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x15, 0x01, 0xe4, - 0xff, 0xad, 0x15, 0x12, 0x0c, 0x1c, 0xe4, 0xf5, 0x0f, 0xd2, 0x0e, 0x90, 0x7e, 0x1c, 0xe0, 0x60, - 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x16, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0}}, - {0x0386, 64, { 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x12, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x10, 0x01, - 0xe4, 0xf5, 0x12, 0xd2, 0x0e, 0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x11, - 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, 0xf0, 0xd2, 0x0c, 0xc2, 0x0d, 0xe4, 0x90, - 0x7f, 0xcf, 0xf0, 0x30, 0x15, 0x71, 0xe5, 0x12, 0x60, 0x02, 0x15, 0x12, 0xe5, 0x2e, 0xd3}}, - {0x03c6, 64, { 0x94, 0x00, 0x40, 0x04, 0x15, 0x2e, 0x80, 0x60, 0x75, 0x2e, 0x0a, 0x12, 0x0d, 0x14, 0xef, 0x54, 0x01, - 0xf5, 0x1c, 0x65, 0x0e, 0x60, 0x07, 0x85, 0x1c, 0x0e, 0xd2, 0x0e, 0x80, 0x11, 0x12, 0x0d, 0x50, - 0xef, 0x54, 0x10, 0xf5, 0x1c, 0x65, 0x09, 0x60, 0x05, 0x85, 0x1c, 0x09, 0xd2, 0x0e, 0x12, 0x0d, - 0x50, 0xef, 0x54, 0x80, 0xf5, 0x1c, 0x65, 0x0a, 0x60, 0x05, 0x85, 0x1c, 0x0a, 0xd2, 0x0e}}, - {0x0406, 64, { 0x12, 0x0d, 0x50, 0xef, 0x54, 0x20, 0xf5, 0x1c, 0x65, 0x0b, 0x60, 0x08, 0x85, 0x1c, 0x0b, 0x30, 0x10, - 0x02, 0xd2, 0x0e, 0x12, 0x0d, 0x50, 0xef, 0x54, 0x40, 0xf5, 0x1c, 0x65, 0x0c, 0x60, 0x08, 0x85, - 0x1c, 0x0c, 0x30, 0x11, 0x02, 0xd2, 0x0e, 0x30, 0x15, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, - 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x30, 0x90, 0x7b, 0x42, 0xe0, 0xf5}}, - {0x0446, 64, { 0x31, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, - 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x1f, 0xe5, 0x25, - 0x70, 0x40, 0x30, 0x0e, 0x39, 0xe5, 0x12, 0x70, 0x35, 0xc2, 0x0e, 0xf5, 0x1b, 0x7e, 0x00, 0x7b, - 0x00, 0x74, 0x08, 0x25, 0x1b, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x09, 0xc7, 0xff, 0x74}}, - {0x0486, 64, { 0x80, 0x25, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, - 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x12, 0x10, 0xe4, 0xf5, 0x10, 0x75, 0x25, - 0x02, 0x22, 0xe5, 0x25, 0x64, 0x02, 0x70, 0x36, 0x30, 0x05, 0x2f, 0xc2, 0x05, 0xf5, 0x1b, 0x7e, - 0x00, 0x7b, 0x00, 0x74, 0x29, 0x25, 0x1b, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x09, 0xc7}}, - {0x04c6, 64, { 0xff, 0x74, 0x80, 0x25, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1b, 0xe5, - 0x1b, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x25, 0x03, 0x22, 0xe5, 0x30, - 0x60, 0x33, 0x75, 0x2f, 0x03, 0x15, 0x30, 0xe4, 0xf5, 0x1b, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2f, - 0x25, 0x1b, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x09, 0xc7, 0xff, 0x74, 0x80, 0x25, 0x1b}}, - {0x0506, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x03, 0xdb, 0x90, - 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x25, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0a, 0x1f, - 0x05, 0xf6, 0x00, 0x06, 0x6a, 0x01, 0x06, 0xd7, 0x03, 0x05, 0x43, 0x06, 0x05, 0xe9, 0x08, 0x05, - 0xe3, 0x09, 0x05, 0xcb, 0x0a, 0x05, 0xda, 0x0b, 0x00, 0x00, 0x07, 0x27, 0x90, 0x7f, 0xeb}}, - {0x0546, 64, { 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x50, 0x24, 0x02, 0x70, 0x6f, 0x74, 0x19, 0x90, 0x7f, 0xd4, - 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, - 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, - 0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea}}, - {0x0586, 64, { 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, - 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x45, 0xea, - 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x2e, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xb4, 0xe0, 0x44}}, - {0x05c6, 64, { 0x01, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0x00, 0xe5, 0x24, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, - 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x24, 0x02, 0x07, 0x2e, 0x12, 0x07, 0x36, 0x02, - 0x07, 0x2e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x07, 0x2e, 0x90, - 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2}}, - {0x0606, 64, { 0x01, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x07, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, - 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x2e, 0xe4, 0x90, 0x7f, 0x00, 0xf0, - 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xec, 0xe0, 0xf4, - 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4}}, - {0x0646, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, - 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, - 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1e, 0x24, 0x02, 0x60, 0x03, 0x02, - 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x06, 0x12, 0x0d, 0x63, 0x02, 0x07, 0x2e}}, - {0x0686, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, - 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, - 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, - 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f}}, - {0x06c6, 64, { 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x60, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x57, - 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x24, 0x02, 0x70, 0x4b, 0x90, 0x7f, 0xea, 0xe0, - 0xb4, 0x01, 0x05, 0x12, 0x0d, 0x60, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, - 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff}}, - {0x0706, 64, { 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, - 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, - 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}}, - {0x0746, 64, { 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, - 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, - 0x08, 0x7f, 0x01, 0x7b, 0x00, 0x74, 0x08, 0x2f, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0a, - 0x0d, 0x0f, 0xbf, 0x09, 0xee, 0x75, 0x13, 0x01, 0xe4, 0xf5, 0x12, 0xf5, 0x2e, 0xf5, 0x11}}, - {0x0786, 64, { 0xc2, 0x0e, 0xc2, 0x12, 0xc2, 0x0d, 0xc2, 0x0a, 0xc2, 0x0f, 0xc2, 0x04, 0x90, 0x7f, 0x98, 0x74, 0x13, - 0xf0, 0x75, 0x18, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x0c, - 0x1c, 0x7f, 0x10, 0x8f, 0x17, 0x12, 0x0b, 0xaa, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, - 0x8f, 0x16, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x0c, 0x1c}}, - {0x07c6, 64, { 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x15, 0x12, 0x0c, 0x1c, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, - 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x0c, 0x1c, 0x7f, 0x01, 0x12, 0x0c, - 0xac, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x0c, 0x1c, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x75, 0x19, - 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0x03, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10}}, - {0x0806, 64, { 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, - 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, - 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, - 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7}}, - {0x0846, 64, { 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, - 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, - 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, - 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0}}, - {0x0886, 64, { 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, - 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, - 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x78, - 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x31, 0x02, 0x08, 0xfd, 0x02, 0x09, 0x42, 0xe4}}, - {0x08c6, 64, { 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, - 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, - 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, - 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x0c, 0xcd, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc}}, - {0x0906, 64, { 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, - 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, - 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, - 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xd2, 0x14, 0x90, 0x7f}}, - {0x0946, 64, { 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x0d, 0x63, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, - 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, - 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, - 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x15, 0x12, 0x0c, 0x66, 0xc2, 0x02, 0xe4, 0xf5}}, - {0x0986, 64, { 0x26, 0xf5, 0x2e, 0xc2, 0x08, 0xc2, 0x03, 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, - 0x1a, 0x60, 0x10, 0x30, 0x03, 0x05, 0xd2, 0x15, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, - 0x1a, 0x80, 0x08, 0x30, 0x03, 0x05, 0xc2, 0x15, 0x12, 0x00, 0x46, 0x30, 0x02, 0x07, 0xc2, 0x02, - 0x12, 0x05, 0x20, 0x80, 0xd6, 0x30, 0x09, 0xd3, 0xc2, 0x09, 0x12, 0x0a, 0xba, 0x80, 0xcc}}, - {0x09c6, 64, { 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, - 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, - 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, - 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5}}, - {0x0a06, 64, { 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, - 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, - 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, - 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x8f}}, - {0x0a46, 64, { 0x1b, 0xe4, 0xf5, 0x1c, 0x75, 0x1d, 0xff, 0x75, 0x1e, 0x19, 0x75, 0x1f, 0x86, 0xab, 0x1d, 0xaa, 0x1e, - 0xa9, 0x1f, 0x90, 0x00, 0x01, 0x12, 0x09, 0xe0, 0xb4, 0x03, 0x1d, 0xaf, 0x1c, 0x05, 0x1c, 0xef, - 0xb5, 0x1b, 0x01, 0x22, 0x12, 0x09, 0xc7, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, - 0x1d, 0xff, 0xf5, 0x1e, 0x89, 0x1f, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22}}, - {0x0a86, 64, { 0x05, 0x28, 0xe5, 0x28, 0xae, 0x27, 0x70, 0x02, 0x05, 0x27, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x11, - 0xf0, 0x12, 0x00, 0x36, 0x05, 0x28, 0xe5, 0x28, 0xac, 0x27, 0x70, 0x02, 0x05, 0x27, 0x14, 0xf5, - 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x23, 0xe5, 0x23, 0x60, 0x07, 0x12, 0x0d, 0x44, 0x8f, 0x11, - 0x80, 0xcd, 0x22, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x1b, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6}}, - {0x0ac6, 64, { 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x08, 0xa6, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0e, 0x30, 0x01, 0x05, - 0x12, 0x0c, 0xfe, 0x80, 0x06, 0x12, 0x0c, 0x8b, 0xef, 0x60, 0xe1, 0x12, 0x07, 0x36, 0x22, 0xc0, - 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, - 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0}}, - {0x0b06, 64, { 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, - 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x02, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, - 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, - 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00}}, - {0x0b46, 64, { 0xd2, 0x09, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, - 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, - 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f}}, - {0x0b86, 64, { 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, - 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, - 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, - 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13}}, - {0x0bc6, 64, { 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, - 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, - 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74}}, - {0x0c06, 64, { 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, - 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x0d, 0x2c, 0x8f, 0x1d}}, - {0x0c46, 64, { 0x12, 0x0d, 0x2c, 0x8f, 0x1e, 0xe5, 0x1d, 0x65, 0x1e, 0x60, 0x12, 0x12, 0x0d, 0x2c, 0x8f, 0x1d, 0xe5, - 0x1d, 0x65, 0x1e, 0x60, 0x07, 0x12, 0x0d, 0x2c, 0x8f, 0x1e, 0x80, 0xe8, 0xaf, 0x1d, 0x22, 0x90, - 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x15, 0x04, 0xe0, 0x44, 0x02, - 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x0c, 0xe7, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0}}, - {0x0c86, 64, { 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x1c, 0x12, 0x07, 0x36, 0x12, 0x0d, 0x50, - 0xef, 0x30, 0xe6, 0x0b, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x1c, 0x60, 0xf1, 0x7f, 0x01, 0x22, 0x12, - 0x00, 0x03, 0x7f, 0x00, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x15, 0x54, 0x7f, 0xfd, 0x12, 0x0c, - 0x1c, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x15}}, - {0x0cc6, 64, { 0x44, 0x80, 0xfd, 0x12, 0x0c, 0x1c, 0x22, 0x05, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x2f, 0x03, - 0x00, 0x00, 0xc1, 0x86, 0xc1, 0x02, 0xc1, 0x09, 0xc1, 0x01, 0xc1, 0x07, 0x01, 0x25, 0x00, 0x00, - 0x8e, 0x1c, 0x8f, 0x1d, 0xe5, 0x1d, 0x15, 0x1d, 0xae, 0x1c, 0x70, 0x02, 0x15, 0x1c, 0x4e, 0x60, - 0x05, 0x12, 0x08, 0x95, 0x80, 0xee, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f}}, - {0x0d06, 64, { 0x0d, 0x7e, 0x00, 0x12, 0x0c, 0xe7, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x7f, 0x98, - 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, - 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, - 0x22, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f}}, - {0x0d46, 64, { 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, - 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0xd2, 0x01, 0x22, 0xc2, 0x01, 0x22, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0d86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0dc6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0b, 0x10, 0x00, 0x02, 0x0e}}, - {0x0e06, 64, { 0x04, 0x00, 0x02, 0x0a, 0xe6, 0x00, 0x02, 0x0b, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0e46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0e86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0ec6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0f06, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0f46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0f86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x0fc6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1006, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1046, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1086, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x10c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1106, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1146, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1186, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x11c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1206, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1246, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1286, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x12c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1306, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1346, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1386, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x08, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 4, { 0x72, 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00} } -}; diff --git a/drivers/usb/serial/keyspan_usa28_fw.h b/drivers/usb/serial/keyspan_usa28_fw.h deleted file mode 100644 index 848b0a2..0000000 --- a/drivers/usb/serial/keyspan_usa28_fw.h +++ /dev/null @@ -1,466 +0,0 @@ -/* keyspan_usa28_fw.h - - The firmware contained herein as keyspan_usa28_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -*/ - -static const struct ezusb_hex_record keyspan_usa28_firmware[] = { - {0x0026, 10, { 0x12, 0x17, 0xdb, 0x12, 0x18, 0xb5, 0x12, 0x14, 0xc3, 0x22}}, - {0x0033, 3, { 0x02, 0x00, 0x1d}}, - {0x001d, 4, { 0x53, 0xd8, 0xef, 0x32}}, - {0x0006, 16, { 0x8e, 0x12, 0x8f, 0x13, 0xe5, 0x13, 0x15, 0x13, 0xae, 0x12, 0x70, 0x02, 0x15, 0x12, 0x4e, 0x60}}, - {0x0016, 7, { 0x05, 0x12, 0x18, 0xa4, 0x80, 0xee, 0x22}}, - {0x0003, 3, { 0x02, 0x00, 0x46}}, - {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}}, - {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x11, 0x07, 0xa2, 0x17, 0x92, 0x9b, 0x85, 0x46, 0x99, 0xc2, 0x99, 0xd2}}, - {0x0066, 16, { 0x1f, 0x30, 0xc1, 0x0e, 0x30, 0x12, 0x07, 0xa2, 0x18, 0x92, 0xc3, 0x85, 0x47, 0xc1, 0xc2, 0xc1}}, - {0x0076, 16, { 0xd2, 0x20, 0x20, 0x1f, 0x03, 0x02, 0x04, 0x42, 0xc2, 0x1f, 0x20, 0x03, 0x03, 0x02, 0x02, 0x67}}, - {0x0086, 16, { 0x20, 0x11, 0x03, 0x02, 0x01, 0x38, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x3e, 0x20, 0x13, 0x36}}, - {0x0096, 16, { 0x20, 0x0b, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x29, 0x30, 0x1b, 0x12}}, - {0x00a6, 16, { 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13}}, - {0x00b6, 16, { 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83}}, - {0x00c6, 16, { 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc7, 0xe4, 0xf0}}, - {0x00d6, 16, { 0xc2, 0x03, 0x30, 0x15, 0x0c, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0xc2, 0x11, 0x02, 0x04}}, - {0x00e6, 16, { 0x40, 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc9}}, - {0x00f6, 16, { 0xe0, 0xf5, 0x7c, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x15, 0x20, 0x13, 0x2d, 0x20, 0x0b, 0x2a}}, - {0x0043, 3, { 0x02, 0x1b, 0x00}}, - {0x0023, 3, { 0x02, 0x00, 0x46}}, - {0x003b, 3, { 0x02, 0x00, 0x46}}, - {0x0000, 3, { 0x02, 0x16, 0x3d}}, - {0x0106, 64, { 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x20, 0x30, 0x1b, 0x11, 0x90, 0x7d, 0xc1, 0xe0, - 0x13, 0x92, 0x17, 0xa3, 0xe0, 0xf5, 0x46, 0x75, 0x4a, 0x03, 0x02, 0x04, 0x40, 0x75, 0x4a, 0x02, - 0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x11, 0x02, 0x04, - 0x40, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x03, 0x02, 0x01, 0xe0, 0x90, 0x7f, 0xc6, 0xe0}}, - {0x0146, 64, { 0x30, 0xe1, 0x07, 0xc2, 0x21, 0xc2, 0x05, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c, 0x90, - 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x15, 0x30, 0x13, 0x03, 0x02, 0x01, 0xd8, 0x20, 0x0b, 0x72, 0x20, - 0x00, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x65, 0x30, 0x1b, 0x10, 0x90, - 0x7e, 0x41, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x03, 0x80, 0x09}}, - {0x0186, 64, { 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x02, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17, 0x90, - 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03, 0x20, 0x15, 0x03, 0x02, 0x04, 0x40, 0xc2, 0x15, 0x90, 0x7f, - 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x40, 0x30, 0x1b, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, - 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a}}, - {0x01c6, 64, { 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x02, 0x04, - 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x21, 0x02, 0x04, 0x40, 0x30, 0x13, 0x03, 0x02, 0x02, 0x62, 0x20, - 0x0b, 0x79, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x6f, 0x30, 0x1b, 0x12, 0xae, - 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13}}, - {0x0206, 64, { 0x92, 0x9b, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, - 0xf5, 0x99, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03, - 0x20, 0x15, 0x03, 0x02, 0x04, 0x40, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x40, - 0x30, 0x1b, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e}}, - {0x0246, 64, { 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, - 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x02, 0x04, 0x40, 0xc2, 0x21, 0x02, 0x04, 0x40, - 0x20, 0x11, 0x03, 0x02, 0x03, 0x19, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x3e, 0x20, 0x13, 0x36, - 0x20, 0x0b, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x29, 0x30, 0x1b}}, - {0x0286, 64, { 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, - 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, - 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, - 0xd2, 0x03, 0x30, 0x15, 0x0c, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0xc2, 0x11, 0x02}}, - {0x02c6, 64, { 0x04, 0x40, 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc7, - 0xe0, 0xf5, 0x7c, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x15, 0x20, 0x13, 0x2d, 0x20, 0x0b, 0x2a, - 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x20, 0x30, 0x1b, 0x11, 0x90, 0x7e, 0x41, - 0xe0, 0x13, 0x92, 0x17, 0xa3, 0xe0, 0xf5, 0x46, 0x75, 0x4a, 0x03, 0x02, 0x04, 0x40, 0x75}}, - {0x0306, 64, { 0x4a, 0x02, 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x11, 0x02, - 0x04, 0x40, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x03, 0x02, 0x03, 0xc1, 0x90, 0x7f, 0xc8, 0xe0, - 0x30, 0xe1, 0x07, 0xc2, 0x21, 0xc2, 0x05, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x7c, - 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x15, 0x30, 0x13, 0x03, 0x02, 0x03, 0xb9, 0x20, 0x0b}}, - {0x0346, 64, { 0x72, 0x20, 0x00, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x65, 0x30, 0x1b, 0x10, - 0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x03, 0x80, 0x09, - 0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x02, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17, - 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x03, 0x20, 0x15, 0x03, 0x02, 0x04, 0x40, 0xc2, 0x15}}, - {0x0386, 64, { 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x40, 0x30, 0x1b, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, - 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x02, - 0x04, 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x21, 0x02, 0x04, 0x40, 0x30, 0x13, 0x03, 0x02, 0x04}}, - {0x03c6, 64, { 0x3e, 0x20, 0x0b, 0x74, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x6a, 0x30, 0x1b, 0x12, - 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, - 0x92, 0x9b, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, - 0xe0, 0xf5, 0x99, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x13, 0x90, 0x7f, 0xc9, 0xe4, 0xf0}}, - {0x0406, 64, { 0xd2, 0x03, 0x30, 0x15, 0x35, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x1b, 0x12, - 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, - 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, - 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x80, 0x02, 0xc2, 0x21, 0xd2, 0x25, 0x20, 0x20, 0x03, 0x02}}, - {0x0446, 64, { 0x08, 0x0c, 0xc2, 0x20, 0x20, 0x04, 0x03, 0x02, 0x06, 0x31, 0x20, 0x12, 0x03, 0x02, 0x05, 0x02, 0xe5, - 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x3e, 0x20, 0x14, 0x36, 0x20, 0x0d, 0x33, 0x90, 0x7f, 0x9a, 0xe0, - 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x29, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, - 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b}}, - {0x0486, 64, { 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0x02, 0x08, 0x0a, 0xc2, - 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x04, 0x30, 0x16, 0x0c, 0xc2, 0x16, - 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcc, 0xe0, 0x30, 0xe1, - 0x05, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xf5, 0x7d, 0x90, 0x7c, 0xc0}}, - {0x04c6, 64, { 0xe0, 0x13, 0x92, 0x16, 0x20, 0x14, 0x2d, 0x20, 0x0d, 0x2a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03, - 0x20, 0x1e, 0x20, 0x30, 0x1d, 0x11, 0x90, 0x7c, 0xc1, 0xe0, 0x13, 0x92, 0x18, 0xa3, 0xe0, 0xf5, - 0x47, 0x75, 0x4b, 0x03, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x02, 0x90, 0x7c, 0xc1, 0xe0, 0xf5, 0x47, - 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0xe5, 0x4b, 0xc3, 0x95}}, - {0x0506, 64, { 0x7d, 0x50, 0x03, 0x02, 0x05, 0xaa, 0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x22, 0xc2, 0x06, - 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x16, - 0x30, 0x14, 0x03, 0x02, 0x05, 0xa2, 0x20, 0x0d, 0x72, 0x20, 0x00, 0x6f, 0x90, 0x7f, 0x9a, 0xe0, - 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x65, 0x30, 0x1d, 0x10, 0x90, 0x7d, 0x41, 0xe0, 0x13, 0x92}}, - {0x0546, 64, { 0xc3, 0xa3, 0xe0, 0xf5, 0xc1, 0x75, 0x4b, 0x03, 0x80, 0x09, 0x90, 0x7d, 0x41, 0xe0, 0xf5, 0xc1, 0x75, - 0x4b, 0x02, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x04, - 0x20, 0x16, 0x03, 0x02, 0x08, 0x0a, 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x08, 0x0a, - 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d}}, - {0x0586, 64, { 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, - 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01, 0xc2, 0x22, - 0x02, 0x08, 0x0a, 0x30, 0x14, 0x03, 0x02, 0x06, 0x2c, 0x20, 0x0d, 0x79, 0x90, 0x7f, 0x9a, 0xe0, - 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x6f, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40}}, - {0x05c6, 64, { 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0xc3, 0xae, 0x4b, 0x05, 0x4b, 0x74, - 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0xc1, 0xe5, 0x4b, 0xc3, 0x95, - 0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x04, 0x20, 0x16, 0x03, 0x02, 0x08, 0x0a, - 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x08, 0x0a, 0x30, 0x1d, 0x12, 0xae, 0x4b}}, - {0x0606, 64, { 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, - 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, - 0xd2, 0x12, 0x02, 0x08, 0x0a, 0xc2, 0x22, 0x02, 0x08, 0x0a, 0x20, 0x12, 0x03, 0x02, 0x06, 0xe3, - 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x3e, 0x20, 0x14, 0x36, 0x20, 0x0d, 0x33, 0x90, 0x7f}}, - {0x0646, 64, { 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x29, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b, - 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0x02, 0x08, 0x0a, - 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcd, 0xe4, 0xf0, 0xd2, 0x04, 0x30, 0x16, 0x0c}}, - {0x0686, 64, { 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xca, 0xe0, 0x30, - 0xe1, 0x05, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0x90, 0x7d, 0x40, - 0xe0, 0x13, 0x92, 0x16, 0x20, 0x14, 0x2d, 0x20, 0x0d, 0x2a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, - 0x03, 0x20, 0x1e, 0x20, 0x30, 0x1d, 0x11, 0x90, 0x7d, 0x41, 0xe0, 0x13, 0x92, 0x18, 0xa3}}, - {0x06c6, 64, { 0xe0, 0xf5, 0x47, 0x75, 0x4b, 0x03, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x02, 0x90, 0x7d, 0x41, 0xe0, 0xf5, - 0x47, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0xe5, 0x4b, 0xc3, 0x95, - 0x7d, 0x50, 0x03, 0x02, 0x07, 0x8b, 0x90, 0x7f, 0xcc, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x22, 0xc2, - 0x06, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xf5, 0x7d, 0x90, 0x7c, 0xc0, 0xe0, 0x13}}, - {0x0706, 64, { 0x92, 0x16, 0x30, 0x14, 0x03, 0x02, 0x07, 0x83, 0x20, 0x0d, 0x72, 0x20, 0x00, 0x6f, 0x90, 0x7f, 0x9a, - 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x65, 0x30, 0x1d, 0x10, 0x90, 0x7c, 0xc1, 0xe0, 0x13, 0x92, - 0xc3, 0xa3, 0xe0, 0xf5, 0xc1, 0x75, 0x4b, 0x03, 0x80, 0x09, 0x90, 0x7c, 0xc1, 0xe0, 0xf5, 0xc1, - 0x75, 0x4b, 0x02, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcd, 0xe4, 0xf0}}, - {0x0746, 64, { 0xd2, 0x04, 0x20, 0x16, 0x03, 0x02, 0x08, 0x0a, 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x08, - 0x0a, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, - 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, - 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01}}, - {0x0786, 64, { 0xc2, 0x22, 0x02, 0x08, 0x0a, 0x30, 0x14, 0x03, 0x02, 0x08, 0x08, 0x20, 0x0d, 0x74, 0x90, 0x7f, 0x9a, - 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x6a, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0xc3, 0xae, 0x4b, 0x05, 0x4b, - 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0xc1, 0xe5, 0x4b}}, - {0x07c6, 64, { 0xc3, 0x95, 0x7d, 0x40, 0x13, 0x90, 0x7f, 0xcd, 0xe4, 0xf0, 0xd2, 0x04, 0x30, 0x16, 0x35, 0xc2, 0x16, - 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b, - 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12}}, - {0x0806, 64, { 0x80, 0x02, 0xc2, 0x22, 0xd2, 0x25, 0x20, 0x98, 0x03, 0x02, 0x09, 0x3e, 0xc2, 0x98, 0x20, 0x01, 0x03, - 0x02, 0x08, 0xb0, 0x20, 0x23, 0x27, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, - 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x1b, 0x49, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x36, 0xaf, 0x99}}, - {0x0846, 64, { 0xef, 0xb5, 0x58, 0x04, 0xd2, 0x0b, 0x80, 0x2c, 0xef, 0xb5, 0x57, 0x04, 0xc2, 0x0b, 0x80, 0x24, 0xae, - 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xef, 0xf0, 0x30, - 0x1b, 0x11, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, - 0xe5, 0x98, 0xf0, 0xd2, 0x19, 0xe5, 0x48, 0xc3, 0x95, 0x54, 0x50, 0x03, 0x02, 0x09, 0x3c}}, - {0x0886, 64, { 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x15, 0xe5, 0x48, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02, 0x09, 0x3c, - 0x15, 0x48, 0x15, 0x48, 0x05, 0x2d, 0xd2, 0x0c, 0x02, 0x09, 0x3c, 0x90, 0x7f, 0xb7, 0xe5, 0x48, - 0xf0, 0x75, 0x48, 0x00, 0xc2, 0x01, 0x02, 0x09, 0x3c, 0x20, 0x23, 0x27, 0xae, 0x48, 0x05, 0x48, - 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x1b}}, - {0x08c6, 64, { 0x49, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, - 0xf0, 0x80, 0x36, 0xaf, 0x99, 0xef, 0xb5, 0x58, 0x04, 0xd2, 0x0b, 0x80, 0x2c, 0xef, 0xb5, 0x57, - 0x04, 0xc2, 0x0b, 0x80, 0x24, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, - 0x7e, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x1b, 0x11, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e}}, - {0x0906, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x19, 0xe5, 0x48, 0xc3, 0x95, 0x54, - 0x40, 0x23, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x11, 0xe5, 0x48, 0xc3, 0x94, 0x40, 0x40, 0x15, - 0x15, 0x48, 0x15, 0x48, 0x05, 0x2d, 0xd2, 0x0c, 0x80, 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x48, 0xf0, - 0x75, 0x48, 0x00, 0xd2, 0x01, 0xd2, 0x25, 0x20, 0xc0, 0x03, 0x02, 0x0a, 0x70, 0xc2, 0xc0}}, - {0x0946, 64, { 0x20, 0x02, 0x03, 0x02, 0x09, 0xe2, 0x20, 0x24, 0x27, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, - 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc1, 0xf0, 0x30, 0x1d, 0x49, 0xae, 0x49, 0x05, 0x49, - 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0x80, 0x36, 0xaf, - 0xc1, 0xef, 0xb5, 0x70, 0x04, 0xd2, 0x0d, 0x80, 0x2c, 0xef, 0xb5, 0x6f, 0x04, 0xc2, 0x0d}}, - {0x0986, 64, { 0x80, 0x24, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, - 0xf0, 0x30, 0x1d, 0x11, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, - 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0xd2, 0x1a, 0xe5, 0x49, 0xc3, 0x95, 0x6c, 0x50, 0x03, 0x02, 0x0a, - 0x6e, 0x90, 0x7f, 0xbc, 0xe0, 0x30, 0xe1, 0x15, 0xe5, 0x49, 0xc3, 0x94, 0x40, 0x50, 0x03}}, - {0x09c6, 64, { 0x02, 0x0a, 0x6e, 0x15, 0x49, 0x15, 0x49, 0x05, 0x39, 0xd2, 0x0e, 0x02, 0x0a, 0x6e, 0x90, 0x7f, 0xbb, - 0xe5, 0x49, 0xf0, 0x75, 0x49, 0x00, 0xc2, 0x02, 0x02, 0x0a, 0x6e, 0x20, 0x24, 0x27, 0xae, 0x49, - 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc1, 0xf0, 0x30, - 0x1d, 0x49, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5}}, - {0x0a06, 64, { 0x83, 0xe5, 0xc0, 0xf0, 0x80, 0x36, 0xaf, 0xc1, 0xef, 0xb5, 0x70, 0x04, 0xd2, 0x0d, 0x80, 0x2c, 0xef, - 0xb5, 0x6f, 0x04, 0xc2, 0x0d, 0x80, 0x24, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, - 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x1d, 0x11, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0xd2, 0x1a, 0xe5, 0x49}}, - {0x0a46, 64, { 0xc3, 0x95, 0x6c, 0x40, 0x23, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x11, 0xe5, 0x49, 0xc3, 0x94, 0x40, - 0x40, 0x15, 0x15, 0x49, 0x15, 0x49, 0x05, 0x39, 0xd2, 0x0e, 0x80, 0x0b, 0x90, 0x7f, 0xbd, 0xe5, - 0x49, 0xf0, 0x75, 0x49, 0x00, 0xd2, 0x02, 0xd2, 0x25, 0x30, 0x25, 0x05, 0xc2, 0x25, 0x02, 0x00, - 0x56, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xce}}, - {0x0a86, 64, { 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x0b, 0xa5, 0xe4, 0xf5, 0x12, 0x74, 0x40, 0x25, 0x12, 0xf5, 0x82, 0xe4, - 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x12, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x4c, 0xf9, 0xec, - 0x34, 0x00, 0xfa, 0xef, 0x12, 0x15, 0xcd, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x18, 0xdb, 0xe5, 0x4c, - 0x60, 0x0c, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x36, 0x85, 0x4d, 0xca, 0x85, 0x4e, 0xcb, 0xe5}}, - {0x0ac6, 64, { 0x4f, 0x13, 0x92, 0x1b, 0x92, 0x9f, 0xe5, 0x50, 0x13, 0x92, 0x1c, 0xe5, 0x51, 0x13, 0x92, 0x23, 0xe5, - 0x52, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, - 0x44, 0x04, 0xf0, 0xe5, 0x53, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x07, - 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x59, 0x60, 0x0b, 0xc2, 0x13, 0xc2, 0x0b}}, - {0x0b06, 64, { 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x5a, 0x60, 0x0b, 0xd2, 0x0b, 0xd2, 0x0c, 0x90, 0x7f, - 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x5b, 0x60, 0x0d, 0xc2, 0xaf, 0xc2, 0x11, 0xd2, 0x00, 0xe4, - 0xf5, 0x7c, 0xf5, 0x4a, 0xd2, 0xaf, 0xe5, 0x5c, 0x60, 0x05, 0x30, 0x23, 0x02, 0xd2, 0x0b, 0xe5, - 0x5d, 0x60, 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44}}, - {0x0b46, 64, { 0x02, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x5e, 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98, - 0x75, 0x2e, 0x01, 0x75, 0x40, 0x28, 0xe5, 0x5f, 0x60, 0x07, 0xc2, 0x9c, 0xe4, 0xf5, 0x48, 0xf5, - 0x2e, 0xe5, 0x60, 0x60, 0x03, 0xe4, 0xf5, 0x48, 0xe5, 0x61, 0x60, 0x02, 0xd2, 0x07, 0xe5, 0x62, - 0x60, 0x08, 0xe5, 0x5e, 0x70, 0x02, 0xf5, 0x40, 0xd2, 0x0c, 0xe5, 0x63, 0x60, 0x19, 0x90}}, - {0x0b86, 64, { 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x15, 0xf0, - 0x74, 0x35, 0xf0, 0xd2, 0x03, 0xd2, 0x01, 0xd2, 0x09, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0xa2, 0x13, - 0xe4, 0x33, 0xff, 0x65, 0x2b, 0x60, 0x04, 0x8f, 0x2b, 0xd2, 0x0c, 0xa2, 0x0b, 0xe4, 0x33, 0xff, - 0x65, 0x2c, 0x60, 0x04, 0x8f, 0x2c, 0xd2, 0x0c, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x08, 0x65}}, - {0x0bc6, 64, { 0x27, 0x60, 0x07, 0xe0, 0x54, 0x08, 0xf5, 0x27, 0xd2, 0x0c, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x40, 0xb5, - 0x29, 0x09, 0xe0, 0x54, 0x40, 0x64, 0x40, 0xf5, 0x29, 0xd2, 0x0c, 0x30, 0x07, 0x35, 0xc2, 0xaf, - 0x30, 0x01, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x48, 0x60, 0x09, 0x90, 0x7f, - 0xb7, 0xf0, 0xe4, 0xf5, 0x48, 0xc2, 0x01, 0xc2, 0x07, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0}}, - {0x0c06, 64, { 0x20, 0xe1, 0x0f, 0xe5, 0x48, 0x60, 0x09, 0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x48, 0xd2, 0x01, 0xc2, - 0x07, 0xd2, 0xaf, 0x20, 0x05, 0x37, 0x30, 0x03, 0x1b, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x2d, - 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x15, 0x75, 0x4a, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c, - 0xd2, 0x05, 0x80, 0x19, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7d, 0xc0, 0xe0}}, - {0x0c46, 64, { 0x13, 0x92, 0x15, 0x75, 0x4a, 0x01, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x7c, 0xd2, 0x05, 0x20, 0x21, 0x33, - 0x20, 0x00, 0x06, 0xe5, 0x4a, 0x65, 0x7c, 0x70, 0x2a, 0x30, 0x05, 0x1a, 0x30, 0x03, 0x09, 0xe4, - 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0xc2, - 0x05, 0xe4, 0xf5, 0x7c, 0xf5, 0x4a, 0x30, 0x15, 0x0a, 0xc2, 0x15, 0xc2, 0x00, 0x90, 0x7f}}, - {0x0c86, 64, { 0xbf, 0x74, 0x01, 0xf0, 0x30, 0x21, 0x03, 0x02, 0x0d, 0x94, 0x20, 0x05, 0x03, 0x02, 0x0d, 0x94, 0x30, - 0x1c, 0x0a, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x0d, 0x94, 0x30, 0x0b, 0x03, 0x02, - 0x0d, 0x94, 0x30, 0x13, 0x03, 0x02, 0x0d, 0x94, 0x30, 0x03, 0x62, 0x30, 0x1b, 0x12, 0xaf, 0x4a, - 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92}}, - {0x0cc6, 64, { 0x2d, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, - 0x13, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x2a, 0x30, 0x1b, 0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, - 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xaf, 0x4a, 0x05, - 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2}}, - {0x0d06, 64, { 0x11, 0x80, 0x6b, 0xc2, 0x11, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80, 0x60, 0x30, 0x1b, 0x12, - 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, - 0x92, 0x2d, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, - 0xe0, 0xf5, 0x13, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x2a, 0x30, 0x1b, 0x12, 0xaf, 0x4a}}, - {0x0d46, 64, { 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xaf, - 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x46, - 0xd2, 0x11, 0x80, 0x09, 0xc2, 0x11, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0x30, 0x1b, 0x04, - 0xa2, 0x2d, 0x92, 0x9b, 0xd2, 0x21, 0xc2, 0xaf, 0x85, 0x13, 0x99, 0x20, 0x11, 0x0d, 0x30}}, - {0x0d86, 64, { 0x15, 0x0a, 0xc2, 0x15, 0xc2, 0x00, 0x90, 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xd0, - 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x0e, 0xb5, 0xe4, 0xf5, 0x12, 0x74, 0xc0, 0x25, 0x12, 0xf5, 0x82, - 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x12, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x64, 0xf9, - 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x15, 0xcd, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x18, 0xdb}}, - {0x0dc6, 64, { 0xe5, 0x64, 0x60, 0x0b, 0x75, 0x89, 0x60, 0x75, 0x88, 0x40, 0xd2, 0xdf, 0x85, 0x65, 0x8d, 0xe5, 0x67, - 0x13, 0x92, 0x1d, 0x92, 0xc7, 0xe5, 0x68, 0x13, 0x92, 0x1e, 0xe5, 0x69, 0x13, 0x92, 0x24, 0xe5, - 0x6a, 0x60, 0x09, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x97, 0xe0, - 0x44, 0x10, 0xf0, 0xe5, 0x6b, 0x60, 0x09, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0x7f, 0xf0, 0x80}}, - {0x0e06, 64, { 0x07, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x71, 0x60, 0x0b, 0xc2, 0x14, 0xc2, 0x0d, 0x90, - 0x7f, 0x94, 0xe0, 0x44, 0x08, 0xf0, 0xe5, 0x72, 0x60, 0x0b, 0xd2, 0x0d, 0xd2, 0x0e, 0x90, 0x7f, - 0x94, 0xe0, 0x44, 0x08, 0xf0, 0xe5, 0x73, 0x60, 0x0d, 0xc2, 0xaf, 0xc2, 0x12, 0xd2, 0x00, 0xe4, - 0xf5, 0x7d, 0xf5, 0x4b, 0xd2, 0xaf, 0xe5, 0x74, 0x60, 0x05, 0x30, 0x24, 0x02, 0xd2, 0x0d}}, - {0x0e46, 64, { 0xe5, 0x75, 0x60, 0x15, 0x90, 0x7f, 0x94, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x08, - 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0xf7, 0xf0, 0xe5, 0x76, 0x60, 0x0a, 0xd2, 0xc4, 0xc2, 0xc0, - 0x75, 0x3a, 0x01, 0x75, 0x41, 0x28, 0xe5, 0x77, 0x60, 0x07, 0xc2, 0xc4, 0xe4, 0xf5, 0x49, 0xf5, - 0x3a, 0xe5, 0x78, 0x60, 0x03, 0xe4, 0xf5, 0x49, 0xe5, 0x79, 0x60, 0x02, 0xd2, 0x08, 0xe5}}, - {0x0e86, 64, { 0x7a, 0x60, 0x08, 0xe5, 0x76, 0x70, 0x02, 0xf5, 0x41, 0xd2, 0x0e, 0xe5, 0x7b, 0x60, 0x19, 0x90, 0x7f, - 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0, 0x74, 0x16, 0xf0, - 0x74, 0x36, 0xf0, 0xd2, 0x04, 0xd2, 0x02, 0xd2, 0x0a, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0xa2, 0x14, - 0xe4, 0x33, 0xff, 0x65, 0x37, 0x60, 0x04, 0x8f, 0x37, 0xd2, 0x0e, 0xa2, 0x0d, 0xe4, 0x33}}, - {0x0ec6, 64, { 0xff, 0x65, 0x38, 0x60, 0x04, 0x8f, 0x38, 0xd2, 0x0e, 0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x20, 0x65, 0x33, - 0x60, 0x07, 0xe0, 0x54, 0x20, 0xf5, 0x33, 0xd2, 0x0e, 0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x40, 0xb5, - 0x35, 0x09, 0xe0, 0x54, 0x40, 0x64, 0x40, 0xf5, 0x35, 0xd2, 0x0e, 0x30, 0x08, 0x35, 0xc2, 0xaf, - 0x30, 0x02, 0x18, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x49, 0x60, 0x09, 0x90}}, - {0x0f06, 64, { 0x7f, 0xbb, 0xf0, 0xe4, 0xf5, 0x49, 0xc2, 0x02, 0xc2, 0x08, 0x80, 0x16, 0x90, 0x7f, 0xba, 0xe0, 0x20, - 0xe1, 0x0f, 0xe5, 0x49, 0x60, 0x09, 0x90, 0x7f, 0xbd, 0xf0, 0xe4, 0xf5, 0x49, 0xd2, 0x02, 0xc2, - 0x08, 0xd2, 0xaf, 0x20, 0x06, 0x37, 0x30, 0x04, 0x1b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x2d, - 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x16, 0x75, 0x4b, 0x01, 0x90, 0x7f, 0xcb, 0xe0, 0xf5}}, - {0x0f46, 64, { 0x7d, 0xd2, 0x06, 0x80, 0x19, 0x90, 0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7c, 0xc0, 0xe0, 0x13, - 0x92, 0x16, 0x75, 0x4b, 0x01, 0x90, 0x7f, 0xcd, 0xe0, 0xf5, 0x7d, 0xd2, 0x06, 0x20, 0x22, 0x33, - 0x20, 0x00, 0x06, 0xe5, 0x4b, 0x65, 0x7d, 0x70, 0x2a, 0x30, 0x06, 0x1a, 0x30, 0x04, 0x09, 0xe4, - 0x90, 0x7f, 0xcb, 0xf0, 0xc2, 0x04, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0xd2, 0x04}}, - {0x0f86, 64, { 0xc2, 0x06, 0xe4, 0xf5, 0x7d, 0xf5, 0x4b, 0x30, 0x16, 0x0a, 0xc2, 0x16, 0xc2, 0x00, 0x90, 0x7f, 0xc1, - 0x74, 0x01, 0xf0, 0x30, 0x22, 0x03, 0x02, 0x10, 0xa4, 0x20, 0x06, 0x03, 0x02, 0x10, 0xa4, 0x30, - 0x1e, 0x0a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x02, 0x10, 0xa4, 0x30, 0x0d, 0x03, 0x02, - 0x10, 0xa4, 0x30, 0x14, 0x03, 0x02, 0x10, 0xa4, 0x30, 0x04, 0x62, 0x30, 0x1d, 0x12, 0xaf}}, - {0x0fc6, 64, { 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x2d, - 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, - 0x13, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x2a, 0x30, 0x1d, 0x12, 0xaf, 0x4b, 0x05, 0x4b, 0x74, - 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xaf, 0x4b}}, - {0x1006, 64, { 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, - 0x80, 0x6b, 0xc2, 0x12, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0xc2, 0x04, 0x80, 0x60, 0x30, 0x1d, 0x12, - 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, - 0x92, 0x2d, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5}}, - {0x1046, 64, { 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x2a, 0x30, 0x1d, 0x12, 0xaf, 0x4b, 0x05, - 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xaf, - 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, - 0xd2, 0x12, 0x80, 0x09, 0xc2, 0x12, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0xd2, 0x04, 0x30, 0x1d}}, - {0x1086, 64, { 0x04, 0xa2, 0x2d, 0x92, 0xc3, 0xd2, 0x22, 0xc2, 0xaf, 0x85, 0x13, 0xc1, 0x20, 0x12, 0x0d, 0x30, 0x16, - 0x0a, 0xc2, 0x16, 0xc2, 0x00, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xc2, - 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0x7a, 0xe5, 0x1a, 0x70, 0x46, 0x30, 0x0c, 0x3f, 0xe5, 0x40, - 0x70, 0x3b, 0xa2, 0x09, 0x33, 0xf5, 0x31, 0xc2, 0x09, 0xc2, 0x0c, 0xe4, 0xf5, 0x12, 0x7e}}, - {0x10c6, 64, { 0x00, 0x7b, 0x00, 0x74, 0x26, 0x25, 0x12, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x15, 0x87, 0xff, 0x74, - 0x80, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, - 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x0c, 0xf0, 0x75, 0x40, 0x10, 0x22, 0x75, 0x1a, 0x01, - 0x22, 0xe5, 0x1a, 0x64, 0x01, 0x70, 0x45, 0x30, 0x0e, 0x3e, 0xe5, 0x41, 0x70, 0x3a, 0xa2}}, - {0x1106, 64, { 0x0a, 0x33, 0xf5, 0x3d, 0xc2, 0x0a, 0xc2, 0x0e, 0xe4, 0xf5, 0x12, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x32, - 0x25, 0x12, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x15, 0x87, 0xff, 0x74, 0x80, 0x25, 0x12, 0xf5, - 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x0c, 0xdb, 0x90, - 0x7f, 0xc3, 0x74, 0x0c, 0xf0, 0x75, 0x41, 0x10, 0x75, 0x1a, 0x02, 0x22, 0xe5, 0x1c, 0x60}}, - {0x1146, 64, { 0x30, 0x15, 0x1c, 0xe4, 0xf5, 0x12, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x1b, 0x25, 0x12, 0xf9, 0xee, 0x34, - 0x00, 0xfa, 0x12, 0x15, 0x87, 0xff, 0x74, 0x80, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, - 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, - 0xe4, 0xf5, 0x1a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x16, 0x17, 0x12, 0x40, 0x00, 0x12}}, - {0x1186, 64, { 0xb4, 0x01, 0x13, 0x20, 0x03, 0x11, 0x9e, 0x06, 0x12, 0x33, 0x08, 0x12, 0x2d, 0x09, 0x12, 0x20, 0x0a, - 0x13, 0x76, 0x0b, 0x00, 0x00, 0x13, 0x6f, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, - 0x60, 0x40, 0x24, 0x02, 0x70, 0x69, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, - 0xd5, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x17, 0x4b, 0x8b, 0x12}}, - {0x11c6, 64, { 0x8a, 0x13, 0x89, 0x14, 0xea, 0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, - 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, - 0x13, 0x76, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x17, 0x9a, 0x8b, 0x12, 0x8a, 0x13, 0x89, 0x14, - 0xea, 0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90}}, - {0x1206, 64, { 0x7f, 0xd5, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13, 0x76, 0x90, - 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, - 0x7f, 0xb5, 0xf0, 0x02, 0x13, 0x76, 0x12, 0x14, 0xc3, 0x02, 0x13, 0x76, 0x90, 0x7f, 0x00, 0x74, - 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f}}, - {0x1246, 64, { 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x26, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, - 0xa2, 0x2b, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, - 0x02, 0xf0, 0x02, 0x13, 0x76, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, - 0x02, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54}}, - {0x1286, 64, { 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, - 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, - 0x02, 0x13, 0x76, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xe8, - 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xea}}, - {0x12c6, 64, { 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x26, 0x02, 0x13, 0x76, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, - 0x13, 0x76, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, - 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, - 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13}}, - {0x1306, 64, { 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, - 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x26, 0x80, 0x3f, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20}}, - {0x1346, 64, { 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, - 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, - 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, - 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x20, 0x28, 0x03, 0x02, 0x14, 0xc2, 0xe5, 0x40}}, - {0x1386, 64, { 0x60, 0x02, 0x15, 0x40, 0xe5, 0x48, 0x60, 0x4f, 0x65, 0x44, 0x70, 0x45, 0xe5, 0x42, 0xf4, 0x60, 0x02, - 0x05, 0x42, 0xe5, 0x42, 0xc3, 0x95, 0x55, 0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x01, 0x18, 0x90, 0x7f, - 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f, 0xb7, 0xe5, 0x48, 0xf0, 0xc2, 0x01, 0xe4, 0xf5, 0x48, - 0xf5, 0x42, 0xf5, 0x44, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0x90, 0x7f}}, - {0x13c6, 64, { 0xb9, 0xe5, 0x48, 0xf0, 0xd2, 0x01, 0xe4, 0xf5, 0x48, 0xf5, 0x42, 0xf5, 0x44, 0xd2, 0xaf, 0x80, 0x06, - 0x85, 0x48, 0x44, 0xe4, 0xf5, 0x42, 0xe5, 0x2e, 0x60, 0x2d, 0x20, 0x19, 0x07, 0x90, 0x7f, 0x9b, - 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x2f, 0x60, 0x05, 0xe4, 0xf5, 0x2f, 0xd2, 0x0c, 0xe4, 0xf5, 0x3e, - 0x80, 0x13, 0xe5, 0x3e, 0xd3, 0x95, 0x56, 0x50, 0x0c, 0xe5, 0x3e, 0xb5, 0x56, 0x05, 0x75}}, - {0x1406, 64, { 0x2f, 0x01, 0xd2, 0x0c, 0x05, 0x3e, 0xc2, 0x19, 0xe5, 0x41, 0x60, 0x02, 0x15, 0x41, 0xe5, 0x49, 0x60, - 0x4f, 0x65, 0x45, 0x70, 0x45, 0xe5, 0x43, 0xf4, 0x60, 0x02, 0x05, 0x43, 0xe5, 0x43, 0xc3, 0x95, - 0x6d, 0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x02, 0x18, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x27, 0x90, - 0x7f, 0xbb, 0xe5, 0x49, 0xf0, 0xc2, 0x02, 0xe4, 0xf5, 0x49, 0xf5, 0x43, 0xf5, 0x45, 0x80}}, - {0x1446, 64, { 0x16, 0x90, 0x7f, 0xba, 0xe0, 0x20, 0xe1, 0x0f, 0x90, 0x7f, 0xbd, 0xe5, 0x49, 0xf0, 0xd2, 0x02, 0xe4, - 0xf5, 0x49, 0xf5, 0x43, 0xf5, 0x45, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x49, 0x45, 0xe4, 0xf5, 0x43, - 0xe5, 0x3a, 0x60, 0x2d, 0x20, 0x1a, 0x07, 0x90, 0x7f, 0x9a, 0xe0, 0x30, 0xe2, 0x0e, 0xe5, 0x3b, - 0x60, 0x05, 0xe4, 0xf5, 0x3b, 0xd2, 0x0e, 0xe4, 0xf5, 0x3f, 0x80, 0x13, 0xe5, 0x3f, 0xd3}}, - {0x1486, 64, { 0x95, 0x6e, 0x50, 0x0c, 0xe5, 0x3f, 0xb5, 0x6e, 0x05, 0x75, 0x3b, 0x01, 0xd2, 0x0e, 0x05, 0x3f, 0xc2, - 0x1a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, - 0x1c, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x1d, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, - 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22, 0xe4, 0x90, 0x7f}}, - {0x14c6, 64, { 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x10, 0xf0, 0x90, 0x7f, - 0x94, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x9a, 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0xfd, - 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x23, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84, 0xf0, 0xe4, 0x90, 0x7f, - 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcf, 0xf0, 0x75, 0x98, 0x40, 0x43, 0xa8}}, - {0x1506, 64, { 0x10, 0xc2, 0x1b, 0xc2, 0x05, 0xc2, 0x21, 0xc2, 0x0b, 0xc2, 0x13, 0xf5, 0x7c, 0xf5, 0x4a, 0xc2, 0x11, - 0xc2, 0x15, 0xf5, 0x42, 0xc2, 0x19, 0xf5, 0x44, 0xf5, 0x48, 0xc2, 0x23, 0xc2, 0x1c, 0xf5, 0x2d, - 0xf5, 0x2f, 0xc2, 0x07, 0xc2, 0x00, 0xc2, 0x1f, 0xf5, 0x3e, 0xc2, 0x09, 0xd2, 0x0c, 0xf5, 0x26, - 0x90, 0x7f, 0xcb, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xd1, 0xf0, 0x75, 0xc0, 0x40}}, - {0x1546, 64, { 0x43, 0xa8, 0x40, 0xc2, 0x1d, 0xc2, 0x06, 0xc2, 0x22, 0xc2, 0x0d, 0xc2, 0x14, 0xf5, 0x7d, 0xf5, 0x4b, - 0xc2, 0x12, 0xc2, 0x16, 0xf5, 0x43, 0xc2, 0x1a, 0xf5, 0x45, 0xf5, 0x49, 0xc2, 0x24, 0xc2, 0x1e, - 0xf5, 0x39, 0xf5, 0x3b, 0xc2, 0x08, 0xc2, 0x00, 0xc2, 0x20, 0xf5, 0x3f, 0xc2, 0x0a, 0xd2, 0x0e, - 0x75, 0x32, 0x01, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xd2, 0x28}}, - {0x1586, 64, { 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, - 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, - 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, - 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5}}, - {0x15c6, 64, { 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, - 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, - 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0, 0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, - 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe, 0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5}}, - {0x1606, 64, { 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83, 0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22, - 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, - 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, - 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x7d}}, - {0x1646, 64, { 0x02, 0x16, 0x84, 0x02, 0x16, 0xc9, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, - 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, - 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, - 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x18}}, - {0x1686, 64, { 0xc5, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, - 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, - 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, - 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde}}, - {0x16c6, 64, { 0xe7, 0x80, 0xbe, 0x75, 0x11, 0x01, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xae, 0xe0, - 0xff, 0xd3, 0x92, 0x26, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, - 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, - 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44}}, - {0x1706, 64, { 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0xbe, 0xd2, 0x2d, - 0x12, 0x18, 0x7f, 0xc2, 0x27, 0xc2, 0x25, 0xc2, 0x28, 0x30, 0x28, 0x03, 0x12, 0x0a, 0x83, 0x90, - 0x7f, 0xd8, 0xe0, 0x65, 0x10, 0x60, 0x08, 0xe0, 0xf5, 0x10, 0x12, 0x13, 0x7e, 0x80, 0xea, 0x30, - 0x27, 0x07, 0xc2, 0x27, 0x12, 0x11, 0x7b, 0x80, 0xe0, 0x30, 0x2c, 0xdd, 0xc2, 0x2c, 0x12}}, - {0x1746, 64, { 0x00, 0x26, 0x80, 0xd6, 0x22, 0xe4, 0xfe, 0x75, 0x17, 0xff, 0x75, 0x18, 0x19, 0x75, 0x19, 0x12, 0xab, - 0x17, 0xaa, 0x18, 0xa9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x15, 0xa0, 0x64, 0x02, 0x70, 0x2d, 0xad, - 0x06, 0x0e, 0xed, 0xb5, 0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x15, 0xdf, 0x85, 0xf0, 0x15, - 0xf5, 0x16, 0x62, 0x15, 0xe5, 0x15, 0x62, 0x16, 0xe5, 0x16, 0x62, 0x15, 0x29, 0xfd, 0xe5}}, - {0x1786, 64, { 0x15, 0x3a, 0xa9, 0x05, 0x75, 0x17, 0xff, 0xf5, 0x18, 0x89, 0x19, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, - 0x79, 0x00, 0x22, 0x8f, 0x15, 0xe4, 0xf5, 0x16, 0x75, 0x17, 0xff, 0x75, 0x18, 0x19, 0x75, 0x19, - 0x86, 0xab, 0x17, 0xaa, 0x18, 0xa9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x15, 0xa0, 0xb4, 0x03, 0x1d, - 0xaf, 0x16, 0x05, 0x16, 0xef, 0xb5, 0x15, 0x01, 0x22, 0x12, 0x15, 0x87, 0x7e, 0x00, 0x29}}, - {0x17c6, 64, { 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x17, 0xff, 0xf5, 0x18, 0x89, 0x19, 0x80, 0xd4, 0x7b, 0x00, 0x7a, - 0x00, 0x79, 0x00, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x94, - 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xf0, 0xe4, 0x90, 0x7f, 0x95, 0xf0, - 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9d, 0xf0}}, - {0x1806, 64, { 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, - 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, - 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, - 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x27, 0x53, 0x91, 0xef, 0x90}}, - {0x1846, 64, { 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, - 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, - 0xd2, 0x2c, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, - 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0}}, - {0x1886, 64, { 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x2d, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, - 0x06, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x74, 0x00, 0xf5, - 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, - 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xc1}}, - {0x18c6, 64, { 0xaa, 0x01, 0x1a, 0x00, 0x03, 0x1b, 0x03, 0x00, 0x00, 0xc1, 0x27, 0xc1, 0x2c, 0xc1, 0x26, 0xc1, 0x2b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x0f, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 64, { 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1a46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1a86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1ac6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x18, 0x31, 0x00, 0x02, 0x1b}}, - {0x1b06, 9, { 0x04, 0x00, 0x02, 0x18, 0x07, 0x00, 0x02, 0x18, 0x58}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa28x_fw.h b/drivers/usb/serial/keyspan_usa28x_fw.h deleted file mode 100644 index 3387ed9..0000000 --- a/drivers/usb/serial/keyspan_usa28x_fw.h +++ /dev/null @@ -1,447 +0,0 @@ -/* keyspan_usa28x_fw.h - - The firmware contained herein as keyspan_usa28x_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -*/ - -static const struct ezusb_hex_record keyspan_usa28x_firmware[] = { - {0x0033, 3, { 0x02, 0x12, 0xf7}}, - {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}}, - {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}}, - {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}}, - {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x1b, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}}, - {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}}, - {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x1b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}}, - {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}}, - {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xba}}, - {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}}, - {0x00a6, 16, { 0x12, 0x13, 0x1b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}}, - {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}}, - {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xba, 0xd2, 0x03, 0xe4, 0x90, 0x7f}}, - {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x60, 0x12, 0x11, 0xd6, 0x8f}}, - {0x00e6, 16, { 0x19, 0x12, 0x13, 0x27, 0x8f, 0x36, 0xe5, 0x19, 0xc3, 0x95, 0x3a, 0x50, 0x0f, 0x12, 0x12, 0xeb}}, - {0x00f6, 16, { 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x5e, 0xc2, 0x0b, 0xe5, 0x19}}, - {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0043, 3, { 0x02, 0x13, 0x00}}, - {0x0000, 3, { 0x02, 0x0e, 0x00}}, - {0x0106, 64, { 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x36, 0x02, 0xe5, 0x36, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, - 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, - 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x4b, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, - 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08}}, - {0x0146, 64, { 0x90, 0x7e, 0x80, 0xe5, 0x36, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, - 0x0c, 0xdf, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, - 0x20, 0x05, 0x03, 0x02, 0x03, 0xc1, 0xc2, 0x05, 0xe4, 0xf5, 0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, - 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a}}, - {0x0186, 64, { 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, - 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, - 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xb1, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x11, 0xb1, 0x43, 0x46, - 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90}}, - {0x01c6, 64, { 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0x35, 0x90, 0x7e, 0x02, 0xe0, - 0xff, 0x12, 0x10, 0x5b, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x11, 0xb1, 0x7f, 0x03, - 0x7d, 0x07, 0x12, 0x11, 0xb1, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, - 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90}}, - {0x0206, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, - 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, - 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, - 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80, 0x80, 0x03, 0x53, 0x42}}, - {0x0246, 64, { 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, - 0x10, 0xa7, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xcd, 0xaf, 0x42, 0x12, 0x10, 0x81, 0x90, - 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10, 0x81, 0x90, 0x7e, 0x0c, - 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd}}, - {0x0286, 64, { 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, - 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, - 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, - 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10}}, - {0x02c6, 64, { 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, - 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, - 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x12, 0x12, 0xdf, - 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12}}, - {0x0306, 64, { 0x11, 0xb1, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, - 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xb1, 0x75, 0x29, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, - 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, - 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98}}, - {0x0346, 64, { 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, - 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xb1, 0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, - 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xb1, 0xe4, - 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12}}, - {0x0386, 64, { 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, - 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, - 0x1f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, - 0x74, 0x35, 0xf0, 0xd2, 0x03, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x1a, 0x52, 0xe5, 0x38}}, - {0x03c6, 64, { 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, - 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x12, 0xdf, 0xef, 0x54, 0x01, 0xf5, - 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13, 0x33, 0xef, 0x54, 0x80, - 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07, 0x30, 0x0d, 0x11, 0x12}}, - {0x0406, 64, { 0x13, 0x33, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19, 0x25, 0xd2, 0x07, 0x20, - 0x1b, 0x03, 0x02, 0x07, 0xec, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x6f, 0xef, 0xc3, 0x95, 0x3d, 0x40, - 0x03, 0x02, 0x04, 0xae, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a, 0xc2, 0x00, 0x80, 0x77, - 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x6f, 0xef, 0xc3}}, - {0x0446, 64, { 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0x14, 0xf5, - 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41, 0x75, 0x0c, 0x7d, 0x75, - 0x0d, 0x41, 0x12, 0x0d, 0x04, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x39, 0x90, 0x7f, - 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x6f, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90}}, - {0x0486, 64, { 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, - 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x04, - 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, - 0x36, 0x12, 0x12, 0x20, 0x8f, 0x19, 0x12, 0x13, 0x7b, 0x8f, 0x37, 0xe5, 0x19, 0xc3, 0x95}}, - {0x04c6, 64, { 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x57, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, - 0x5e, 0xc2, 0x0c, 0xe5, 0x19, 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x37, 0x02, 0xe5, 0x37, 0x30, - 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, - 0x7d, 0x7f, 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0x84, 0xe5}}, - {0x0506, 64, { 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb, 0xf0, 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, - 0x19, 0x3f, 0x85, 0x19, 0x08, 0x90, 0x7d, 0x80, 0xe5, 0x37, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, - 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0x29, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, - 0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x97, 0xc2, 0x06, 0xe4}}, - {0x0546, 64, { 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, - 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, - 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, - 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xfb, 0x7f, 0x03}}, - {0x0586, 64, { 0x7d, 0xcd, 0x12, 0x11, 0xfb, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, - 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, - 0x11, 0x19, 0x90, 0x7e, 0x22, 0xe0, 0xff, 0x12, 0x11, 0x3f, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, - 0xfd, 0x12, 0x11, 0xfb, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xfb, 0x43, 0x47, 0x80, 0x90}}, - {0x05c6, 64, { 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, - 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, - 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, - 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90}}, - {0x0606, 64, { 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e, 0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, - 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f, 0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, - 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x11, 0x65, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0x8b, - 0xaf, 0x43, 0x12, 0x10, 0xf3, 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf}}, - {0x0646, 64, { 0x43, 0x12, 0x10, 0xf3, 0x90, 0x7e, 0x2c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, - 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, - 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, - 0x53, 0x47, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0}}, - {0x0686, 64, { 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3, 0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, - 0x60, 0x05, 0x43, 0x47, 0x10, 0x80, 0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, - 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f}}, - {0x06c6, 64, { 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x4b, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, - 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, - 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, 0x75, 0x32, - 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0}}, - {0x0706, 64, { 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, - 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f, 0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, - 0x75, 0x34, 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4}}, - {0x0746, 64, { 0xff, 0xad, 0x3f, 0x12, 0x11, 0xfb, 0xe4, 0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, - 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, - 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c, 0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, - 0xf5, 0x39, 0xd2, 0x08, 0x90, 0x7e, 0x3f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x13}}, - {0x0786, 64, { 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0, 0x74, 0x36, 0xf0, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, - 0x30, 0x1a, 0x52, 0xe5, 0x39, 0x60, 0x02, 0x15, 0x39, 0x30, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, - 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, - 0x13, 0x4b, 0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2}}, - {0x07c6, 64, { 0x08, 0x12, 0x13, 0x87, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, - 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x87, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, - 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, - 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90}}, - {0x0806, 64, { 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, - 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x09, 0x20, 0xe5, 0x0a, 0x70, 0x40, - 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, - 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25}}, - {0x0846, 64, { 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, - 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38, 0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, - 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08, 0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, - 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12}}, - {0x0886, 64, { 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, - 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, - 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a, 0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, - 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}}, - {0x08c6, 64, { 0xfa, 0x12, 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, - 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, - 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15, 0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, - 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x8c, 0xff, 0x74, 0x80, 0x25}}, - {0x0906, 64, { 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, - 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0e, - 0xe4, 0x0a, 0x08, 0x00, 0x0a, 0x7c, 0x01, 0x0a, 0xe8, 0x03, 0x09, 0x44, 0x06, 0x09, 0xfb, 0x08, - 0x09, 0xf5, 0x09, 0x09, 0xdd, 0x0a, 0x09, 0xec, 0x0b, 0x00, 0x00, 0x0b, 0x37, 0x90, 0x7f}}, - {0x0946, 64, { 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61, 0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xd3, 0x74, - 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, - 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, - 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19}}, - {0x0986, 64, { 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, - 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, - 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, - 0x0a, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0}}, - {0x09c6, 64, { 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, - 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, - 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x3e, 0x12, 0x0b, - 0x46, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02}}, - {0x0a06, 64, { 0x0b, 0x3e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, - 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, - 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0xe4, 0x90, 0x7f, - 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f}}, - {0x0a46, 64, { 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, - 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, - 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02}}, - {0x0a86, 64, { 0x60, 0x03, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x3e, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, - 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, - 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f}}, - {0x0ac6, 64, { 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, - 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, - 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, - 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}}, - {0x0b06, 64, { 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, - 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, - 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22}}, - {0x0b46, 64, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, - 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, - 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, - 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa}}, - {0x0b86, 64, { 0xe4, 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, - 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b, 0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, - 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xb1, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0x81, 0x90, 0x7f}}, - {0x0bc6, 64, { 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, - 0x12, 0x11, 0xb1, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xb1, 0x90, 0x7f, - 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11}}, - {0x0c06, 64, { 0xb1, 0x7f, 0x01, 0x12, 0x12, 0x6a, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xb1, 0x20, 0x1b, 0x03, 0x02, - 0x0c, 0xb7, 0x75, 0x2d, 0x01, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, - 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xd2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, - 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2}}, - {0x0c46, 64, { 0x00, 0xc2, 0x0a, 0xc2, 0x13, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00, - 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xfb, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x10, - 0xf3, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90, 0xc0, - 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74}}, - {0x0c86, 64, { 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x11, 0xfb, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12, - 0x11, 0xfb, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, - 0x7f, 0x12, 0x11, 0xfb, 0x7f, 0x01, 0x12, 0x12, 0x8b, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xfb, - 0xd2, 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82}}, - {0x0cc6, 64, { 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, - 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, - 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, - 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f}}, - {0x0d06, 64, { 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, - 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, - 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, - 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05}}, - {0x0d46, 64, { 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, - 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, - 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, - 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0}}, - {0x0d86, 64, { 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, - 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, - 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, - 0x1a, 0x12, 0x12, 0x45, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, 0x12}}, - {0x0dc6, 64, { 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, 0x05, 0xd2, - 0x1a, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, 0x05, 0xc2, - 0x1a, 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x21, 0x80, 0xd6, 0x30, 0x18, - 0xd3, 0xc2, 0x18, 0x12, 0x13, 0x93, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd}}, - {0x0e06, 64, { 0x75, 0x81, 0x47, 0x02, 0x0e, 0x47, 0x02, 0x0d, 0x6f, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, - 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, - 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, - 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40}}, - {0x0e46, 64, { 0x80, 0x90, 0x12, 0xac, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, - 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, - 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, - 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca}}, - {0x0e86, 64, { 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, - 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, - 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, - 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5}}, - {0x0ec6, 64, { 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, - 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, - 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, - 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3}}, - {0x0f06, 64, { 0xa3, 0xa3, 0x80, 0xdf, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, 0x75, 0x1c, - 0x86, 0xab, 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xa5, 0xb4, 0x03, 0x1d, - 0xaf, 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0x8c, 0x7e, 0x00, 0x29, 0xff, - 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, 0x00}}, - {0x0f46, 64, { 0x7a, 0x00, 0x79, 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, - 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac, - 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, - 0x60, 0x0a, 0x12, 0x13, 0x27, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, 0x1a}}, - {0x0f86, 64, { 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, - 0xf0, 0x12, 0x13, 0x3f, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, - 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x7b, 0x8f, 0x1a, - 0xef, 0x42, 0x37, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0}}, - {0x0fc6, 64, { 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, - 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, - 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, - 0x11, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0}}, - {0x1006, 64, { 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, - 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, - 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, - 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10}}, - {0x1046, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, - 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13}}, - {0x1086, 64, { 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, - 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44}}, - {0x10c6, 64, { 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, - 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, - 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90}}, - {0x1106, 64, { 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, - 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, - 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90}}, - {0x1146, 64, { 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, - 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, - 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f}}, - {0x1186, 64, { 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, - 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, - 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90}}, - {0x11c6, 64, { 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, - 0x13, 0x0f, 0x8f, 0x1a, 0x12, 0x13, 0x0f, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, - 0x13, 0x0f, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x0f, 0x8f, 0x1b, 0x80, - 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90}}, - {0x1206, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, - 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x63, 0x8f, 0x1a, 0x12, 0x13, - 0x63, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x63, 0x8f, 0x1a, 0xe5, 0x1a, - 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x63, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90}}, - {0x1246, 64, { 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, - 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xc8, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, - 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xb1, 0x90, - 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80}}, - {0x1286, 64, { 0xfd, 0x12, 0x11, 0xb1, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xfb, - 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, - 0xfd, 0x12, 0x11, 0xfb, 0x22, 0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, - 0x00, 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10, 0xc1, 0x16, 0x01, 0x0a, 0x00, 0xc1}}, - {0x12c6, 64, { 0x9b, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, - 0x60, 0x05, 0x12, 0x0d, 0x4e, 0x80, 0xee, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0xe7, 0x00, 0x02, 0x13}}, - {0x1306, 64, { 0x04, 0x00, 0x02, 0x0f, 0xbd, 0x00, 0x02, 0x10, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90}}, - {0x1346, 64, { 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff}}, - {0x1386, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x12, 0x00, 0x03, 0x12, - 0x0d, 0x5f, 0x12, 0x0b, 0x46, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x10, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 4, { 0x72, 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa28xa_fw.h b/drivers/usb/serial/keyspan_usa28xa_fw.h deleted file mode 100644 index 7b56678..0000000 --- a/drivers/usb/serial/keyspan_usa28xa_fw.h +++ /dev/null @@ -1,449 +0,0 @@ -/* keyspan_usa28xa_fw.h - - The firmware contained herein as keyspan_usa28xa.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - - - -*/ - -static const struct ezusb_hex_record keyspan_usa28xa_firmware[] = { - {0x0033, 3, { 0x02, 0x12, 0xf9}}, - {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}}, - {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}}, - {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}}, - {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x27, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}}, - {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}}, - {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x27, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}}, - {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}}, - {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xc8}}, - {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}}, - {0x00a6, 16, { 0x12, 0x13, 0x27, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}}, - {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}}, - {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xc8, 0xd2, 0x03, 0xe4, 0x90, 0x7f}}, - {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x60, 0x12, 0x11, 0xe4, 0x8f}}, - {0x00e6, 16, { 0x19, 0x12, 0x13, 0x33, 0x8f, 0x36, 0xe5, 0x19, 0xc3, 0x95, 0x3a, 0x50, 0x0f, 0x12, 0x13, 0x0f}}, - {0x00f6, 16, { 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x5e, 0xc2, 0x0b, 0xe5, 0x19}}, - {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0043, 3, { 0x02, 0x13, 0x00}}, - {0x0000, 3, { 0x02, 0x0e, 0x0e}}, - {0x0106, 64, { 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x36, 0x02, 0xe5, 0x36, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, - 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, - 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x59, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, - 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08}}, - {0x0146, 64, { 0x90, 0x7e, 0x80, 0xe5, 0x36, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, - 0x0c, 0xed, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, - 0x20, 0x05, 0x03, 0x02, 0x03, 0xc1, 0xc2, 0x05, 0xe4, 0xf5, 0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, - 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a}}, - {0x0186, 64, { 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xe0, 0x05, 0x18, 0xe5, - 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, - 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xbf, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x11, 0xbf, 0x43, 0x46, - 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90}}, - {0x01c6, 64, { 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0x43, 0x90, 0x7e, 0x02, 0xe0, - 0xff, 0x12, 0x10, 0x69, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x11, 0xbf, 0x7f, 0x03, - 0x7d, 0x07, 0x12, 0x11, 0xbf, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, - 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90}}, - {0x0206, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, - 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, - 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, - 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80, 0x80, 0x03, 0x53, 0x42}}, - {0x0246, 64, { 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, - 0x10, 0xb5, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xdb, 0xaf, 0x42, 0x12, 0x10, 0x8f, 0x90, - 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10, 0x8f, 0x90, 0x7e, 0x0c, - 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd}}, - {0x0286, 64, { 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, - 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, - 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, - 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10}}, - {0x02c6, 64, { 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, - 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, - 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x12, 0x12, 0xed, - 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12}}, - {0x0306, 64, { 0x11, 0xbf, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, - 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xbf, 0x75, 0x29, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, - 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, - 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98}}, - {0x0346, 64, { 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, - 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xbf, 0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, - 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xbf, 0xe4, - 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12}}, - {0x0386, 64, { 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, - 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, - 0x1f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, - 0x74, 0x35, 0xf0, 0xd2, 0x03, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x1a, 0x52, 0xe5, 0x38}}, - {0x03c6, 64, { 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, - 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x12, 0xed, 0xef, 0x54, 0x01, 0xf5, - 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13, 0x3f, 0xef, 0x54, 0x80, - 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07, 0x30, 0x0d, 0x11, 0x12}}, - {0x0406, 64, { 0x13, 0x3f, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19, 0x25, 0xd2, 0x07, 0x20, - 0x1b, 0x03, 0x02, 0x07, 0xec, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x7b, 0xef, 0xc3, 0x95, 0x3d, 0x40, - 0x03, 0x02, 0x04, 0xae, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a, 0xc2, 0x00, 0x80, 0x77, - 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x7b, 0xef, 0xc3}}, - {0x0446, 64, { 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0x14, 0xf5, - 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41, 0x75, 0x0c, 0x7d, 0x75, - 0x0d, 0x41, 0x12, 0x0d, 0x12, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x39, 0x90, 0x7f, - 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x7b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90}}, - {0x0486, 64, { 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, - 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x12, - 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, - 0x36, 0x12, 0x12, 0x2e, 0x8f, 0x19, 0x12, 0x13, 0x87, 0x8f, 0x37, 0xe5, 0x19, 0xc3, 0x95}}, - {0x04c6, 64, { 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x63, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, - 0x5e, 0xc2, 0x0c, 0xe5, 0x19, 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x37, 0x02, 0xe5, 0x37, 0x30, - 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, - 0x7d, 0x7f, 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0x92, 0xe5}}, - {0x0506, 64, { 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb, 0xf0, 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, - 0x19, 0x3f, 0x85, 0x19, 0x08, 0x90, 0x7d, 0x80, 0xe5, 0x37, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, - 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0x37, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, - 0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x97, 0xc2, 0x06, 0xe4}}, - {0x0546, 64, { 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, - 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, - 0x12, 0x0e, 0xe0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, - 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x09, 0x7f, 0x03}}, - {0x0586, 64, { 0x7d, 0xcd, 0x12, 0x12, 0x09, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, - 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, - 0x11, 0x27, 0x90, 0x7e, 0x22, 0xe0, 0xff, 0x12, 0x11, 0x4d, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, - 0xfd, 0x12, 0x12, 0x09, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x09, 0x43, 0x47, 0x80, 0x90}}, - {0x05c6, 64, { 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, - 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, - 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, - 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90}}, - {0x0606, 64, { 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e, 0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, - 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f, 0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, - 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x11, 0x73, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0x99, - 0xaf, 0x43, 0x12, 0x11, 0x01, 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf}}, - {0x0646, 64, { 0x43, 0x12, 0x11, 0x01, 0x90, 0x7e, 0x2c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, - 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, - 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, - 0x53, 0x47, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0}}, - {0x0686, 64, { 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3, 0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, - 0x60, 0x05, 0x43, 0x47, 0x10, 0x80, 0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, - 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f}}, - {0x06c6, 64, { 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x57, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, - 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x09, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, - 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x09, 0x75, 0x32, - 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0}}, - {0x0706, 64, { 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, - 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f, 0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x09, - 0x75, 0x34, 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4}}, - {0x0746, 64, { 0xff, 0xad, 0x3f, 0x12, 0x12, 0x09, 0xe4, 0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, - 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, - 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c, 0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, - 0xf5, 0x39, 0xd2, 0x08, 0x90, 0x7e, 0x3f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x13}}, - {0x0786, 64, { 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0, 0x74, 0x36, 0xf0, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, - 0x30, 0x1a, 0x52, 0xe5, 0x39, 0x60, 0x02, 0x15, 0x39, 0x30, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, - 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, - 0x13, 0x57, 0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2}}, - {0x07c6, 64, { 0x08, 0x12, 0x13, 0x93, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, - 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x93, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, - 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, - 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90}}, - {0x0806, 64, { 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, - 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x09, 0x20, 0xe5, 0x0a, 0x70, 0x40, - 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, - 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9a, 0xff, 0x74, 0x80, 0x25}}, - {0x0846, 64, { 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, - 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38, 0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, - 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08, 0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, - 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12}}, - {0x0886, 64, { 0x0e, 0x9a, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, - 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, - 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a, 0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, - 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}}, - {0x08c6, 64, { 0xfa, 0x12, 0x0e, 0x9a, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, - 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, - 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15, 0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, - 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9a, 0xff, 0x74, 0x80, 0x25}}, - {0x0906, 64, { 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, - 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0e, - 0xf2, 0x0a, 0x08, 0x00, 0x0a, 0x7c, 0x01, 0x0a, 0xe8, 0x03, 0x09, 0x44, 0x06, 0x09, 0xfb, 0x08, - 0x09, 0xf5, 0x09, 0x09, 0xdd, 0x0a, 0x09, 0xec, 0x0b, 0x00, 0x00, 0x0b, 0x37, 0x90, 0x7f}}, - {0x0946, 64, { 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61, 0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xd3, 0x74, - 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, - 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, - 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19}}, - {0x0986, 64, { 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, - 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, - 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, - 0x18, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0}}, - {0x09c6, 64, { 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, - 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, - 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x3e, 0x12, 0x0b, - 0x46, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02}}, - {0x0a06, 64, { 0x0b, 0x3e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, - 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, - 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0xe4, 0x90, 0x7f, - 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f}}, - {0x0a46, 64, { 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, - 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, - 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02}}, - {0x0a86, 64, { 0x60, 0x03, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x3e, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x3e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, - 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, - 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f}}, - {0x0ac6, 64, { 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, - 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, - 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, - 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}}, - {0x0b06, 64, { 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, - 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, - 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22}}, - {0x0b46, 64, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, - 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, - 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, - 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa}}, - {0x0b86, 64, { 0xe4, 0x12, 0x0e, 0xe0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, - 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b, 0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, - 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xbf, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0x8f, 0x90, 0x7f}}, - {0x0bc6, 64, { 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, - 0x12, 0x11, 0xbf, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xbf, 0x90, 0x7f, - 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11}}, - {0x0c06, 64, { 0xbf, 0x7f, 0x01, 0x12, 0x12, 0x78, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xbf, 0x7f, 0x13, 0x7d, 0x01, - 0x12, 0x11, 0xbf, 0x20, 0x1b, 0x03, 0x02, 0x0c, 0xc5, 0x75, 0x2d, 0x01, 0x75, 0x18, 0x01, 0x7b, - 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xe0, 0x05, 0x18, - 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37}}, - {0x0c46, 64, { 0xc2, 0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2, 0x00, 0xc2, 0x0a, 0xc2, 0x13, 0x90, 0x7f, 0x98, 0x74, 0x0b, - 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, - 0x09, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x11, 0x01, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, - 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0}}, - {0x0c86, 64, { 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x09, 0xe4, 0xff, - 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12, 0x12, 0x09, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, - 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x12, 0x09, 0x7f, 0x01, 0x12, 0x12, 0x99, - 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x09, 0x7f, 0x13, 0x7d, 0x01, 0x12, 0x12, 0x09, 0xd2}}, - {0x0cc6, 64, { 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, - 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, - 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, - 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05}}, - {0x0d06, 64, { 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, - 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, - 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5}}, - {0x0d46, 64, { 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, - 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, - 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0}}, - {0x0d86, 64, { 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, - 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, - 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, - 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x1a}}, - {0x0dc6, 64, { 0x12, 0x12, 0x53, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, 0x12, 0x90, 0x7f, 0xa1, - 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, 0x05, 0xd2, 0x1a, 0x12, - 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, 0x05, 0xc2, 0x1a, 0x12, - 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x21, 0x80, 0xd6, 0x30, 0x18, 0xd3}}, - {0x0e06, 64, { 0xc2, 0x18, 0x12, 0x13, 0x9f, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x47, - 0x02, 0x0e, 0x55, 0x02, 0x0d, 0x7d, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, - 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, - 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80}}, - {0x0e46, 64, { 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x12, - 0xba, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, - 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, - 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8}}, - {0x0e86, 64, { 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, - 0xe7, 0x80, 0xbe, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, - 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, - 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25}}, - {0x0ec6, 64, { 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, - 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, - 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, - 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01}}, - {0x0f06, 64, { 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, - 0xdf, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, 0x75, 0x1c, 0x86, 0xab, - 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xb3, 0xb4, 0x03, 0x1d, 0xaf, 0x19, - 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0x9a, 0x7e, 0x00, 0x29, 0xff, 0xee}}, - {0x0f46, 64, { 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, - 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, - 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, - 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60}}, - {0x0f86, 64, { 0x0a, 0x12, 0x13, 0x33, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, - 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, - 0x13, 0x4b, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, - 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x87, 0x8f, 0x1a, 0xef}}, - {0x0fc6, 64, { 0x42, 0x37, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, - 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, - 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, - 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x11}}, - {0x1006, 64, { 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, - 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, - 0x86, 0x75, 0x86, 0x00, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, - 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98}}, - {0x1046, 64, { 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, - 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, - 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0}}, - {0x1086, 64, { 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, - 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, - 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, - 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14}}, - {0x10c6, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, - 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b}}, - {0x1106, 64, { 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xef, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, - 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45}}, - {0x1146, 64, { 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, - 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, - 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90}}, - {0x1186, 64, { 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, - 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, - 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5}}, - {0x11c6, 64, { 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x1b, - 0x8f, 0x1a, 0x12, 0x13, 0x1b, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x1b, - 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x1b, 0x8f, 0x1b, 0x80, 0xe8}}, - {0x1206, 64, { 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0d, - 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x6f, 0x8f, 0x1a, 0x12, 0x13, 0x6f, 0x8f, - 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x6f, 0x8f, 0x1a, 0xe5, 0x1a, 0x65}}, - {0x1246, 64, { 0x1b, 0x60, 0x07, 0x12, 0x13, 0x6f, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0xd6, 0xe0, - 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, - 0x7e, 0x01, 0x12, 0x12, 0xd6, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, - 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xbf, 0x90, 0x7f}}, - {0x1286, 64, { 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, 0x11, - 0xbf, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x09, 0x90, 0x7f, - 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, 0xfd, 0x12, - 0x12, 0x09, 0x22, 0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, 0x00}}, - {0x12c6, 64, { 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10, 0xc1, 0x16, 0x01, 0x0a, 0x00, 0xc1, 0x9b, 0x00, 0x8e, - 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, 0x60, 0x05, - 0x12, 0x0d, 0x5c, 0x80, 0xee, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, - 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x02, 0x0f, 0xf5, 0x00, 0x02, 0x13}}, - {0x1306, 64, { 0x04, 0x00, 0x02, 0x0f, 0xcb, 0x00, 0x02, 0x10, 0x1c, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90}}, - {0x1346, 64, { 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff}}, - {0x1386, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x12, 0x00, 0x03, 0x12, 0x0d, 0x6d, 0x12, 0x0b, - 0x46, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x15, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 4, { 0x72, 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa28xb_fw.h b/drivers/usb/serial/keyspan_usa28xb_fw.h deleted file mode 100644 index f5fcad4..0000000 --- a/drivers/usb/serial/keyspan_usa28xb_fw.h +++ /dev/null @@ -1,448 +0,0 @@ -/* keyspan_usa28xb_fw.h - - The firmware contained herein as keyspan_usa29xb_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -*/ - -static const struct ezusb_hex_record keyspan_usa28xb_firmware[] = { - {0x0033, 3, { 0x02, 0x00, 0x2d}}, - {0x002d, 4, { 0x53, 0xd8, 0xef, 0x32}}, - {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x33, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}}, - {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}}, - {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x33, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}}, - {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}}, - {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xcc}}, - {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}}, - {0x00a6, 16, { 0x12, 0x13, 0x33, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}}, - {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}}, - {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xcc, 0xd2, 0x03, 0xe4, 0x90, 0x7f}}, - {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x60, 0x12, 0x11, 0xf5, 0x8f}}, - {0x00e6, 16, { 0x19, 0x12, 0x13, 0x3f, 0x8f, 0x36, 0xe5, 0x19, 0xc3, 0x95, 0x3a, 0x50, 0x0f, 0x12, 0x13, 0x1b}}, - {0x00f6, 16, { 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x5e, 0xc2, 0x0b, 0xe5, 0x19}}, - {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0043, 3, { 0x02, 0x13, 0x00}}, - {0x0003, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90}}, - {0x0013, 16, { 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0}}, - {0x0023, 10, { 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32}}, - {0x0000, 3, { 0x02, 0x0e, 0x12}}, - {0x0106, 64, { 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x36, 0x02, 0xe5, 0x36, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, - 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, - 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x5d, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, - 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08}}, - {0x0146, 64, { 0x90, 0x7e, 0x80, 0xe5, 0x36, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, - 0x0c, 0xf1, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, - 0x20, 0x05, 0x03, 0x02, 0x03, 0xc1, 0xe4, 0xf5, 0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, - 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79}}, - {0x0186, 64, { 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xe4, 0x05, 0x18, 0xe5, 0x18, 0xb4, - 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, - 0xe4, 0xfd, 0x12, 0x11, 0xd0, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x11, 0xd0, 0x43, 0x46, 0x80, 0x90, - 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90, 0x7e, 0x13}}, - {0x01c6, 64, { 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0x54, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, - 0x10, 0x7a, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x11, 0xd0, 0x7f, 0x03, 0x7d, 0x07, - 0x12, 0x11, 0xd0, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, - 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90, 0xc0, 0x00}}, - {0x0206, 64, { 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, - 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, - 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80, 0x80, 0x03, 0x53, 0x42, 0x7f, 0x53}}, - {0x0246, 64, { 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x10, 0xc6, - 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xec, 0xaf, 0x42, 0x12, 0x10, 0xa0, 0x90, 0x7e, 0x03, - 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10, 0xa0, 0x90, 0x7e, 0x0c, 0xe0, 0x60, - 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd, 0x90, 0x7f}}, - {0x0286, 64, { 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, - 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, - 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, - 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10, 0x80, 0x03}}, - {0x02c6, 64, { 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, - 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, - 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x12, 0x13, 0x0f, 0xef, 0x54, - 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd0}}, - {0x0306, 64, { 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, - 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd0, 0x75, 0x29, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, 0xe0, 0x60, - 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, - 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13}}, - {0x0346, 64, { 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x3e, - 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd0, 0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x1b, - 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd0, 0xe4, 0xf5, 0x2b, - 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5}}, - {0x0386, 64, { 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, 0x90, 0x7e, - 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, 0x1f, 0xe0, - 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, - 0xf0, 0xd2, 0x03, 0xc2, 0x05, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x1a, 0x54, 0xe5, 0x38}}, - {0x03c6, 64, { 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x4b, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, - 0x40, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x13, 0x0f, 0xef, 0x54, 0x01, 0xf5, - 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13, 0x4b, 0xef, 0x54, 0x80, - 0x64, 0x80, 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07, 0x30, 0x0d}}, - {0x0406, 64, { 0x11, 0x12, 0x13, 0x4b, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19, 0x25, 0xd2, - 0x07, 0x20, 0x1b, 0x03, 0x02, 0x07, 0xf0, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x87, 0xef, 0xc3, 0x95, - 0x3d, 0x40, 0x03, 0x02, 0x04, 0xb0, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a, 0xc2, 0x00, - 0x80, 0x77, 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x87}}, - {0x0446, 64, { 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, - 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41, 0x75, 0x0c, - 0x7d, 0x75, 0x0d, 0x41, 0x12, 0x0d, 0x16, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x39, - 0x90, 0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x87, 0xef, 0xc3, 0x94, 0x40, 0x50}}, - {0x0486, 64, { 0x29, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, - 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d, 0xc1, 0x12, - 0x0d, 0x16, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x03, - 0x02, 0x05, 0x38, 0x12, 0x12, 0x3f, 0x8f, 0x19, 0x12, 0x13, 0x93, 0x8f, 0x37, 0xe5, 0x19}}, - {0x04c6, 64, { 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x6f, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, - 0x30, 0x0c, 0x5e, 0xc2, 0x0c, 0xe5, 0x19, 0x60, 0x58, 0xb4, 0x80, 0x03, 0x43, 0x37, 0x02, 0xe5, - 0x37, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, - 0x08, 0x7e, 0x7d, 0x7f, 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f}}, - {0x0506, 64, { 0x96, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb, 0xf0, 0x80, 0x27, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, - 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0x90, 0x7d, 0x80, 0xe5, 0x37, 0xf0, 0x7e, 0x7d, 0x7f, - 0x81, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0x3b, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, - 0xf0, 0x90, 0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x99, 0xe4}}, - {0x0546, 64, { 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, - 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, - 0x12, 0x0e, 0xe4, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, - 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x1a, 0x7f, 0x03}}, - {0x0586, 64, { 0x7d, 0xcd, 0x12, 0x12, 0x1a, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, - 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, - 0x11, 0x38, 0x90, 0x7e, 0x22, 0xe0, 0xff, 0x12, 0x11, 0x5e, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, - 0xfd, 0x12, 0x12, 0x1a, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x1a, 0x43, 0x47, 0x80, 0x90}}, - {0x05c6, 64, { 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, - 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, - 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, - 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90}}, - {0x0606, 64, { 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e, 0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, - 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f, 0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, - 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x11, 0x84, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xaa, - 0xaf, 0x43, 0x12, 0x11, 0x12, 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf}}, - {0x0646, 64, { 0x43, 0x12, 0x11, 0x12, 0x90, 0x7e, 0x2c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, - 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, - 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, - 0x53, 0x47, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0}}, - {0x0686, 64, { 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3, 0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, - 0x60, 0x05, 0x43, 0x47, 0x10, 0x80, 0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, - 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f}}, - {0x06c6, 64, { 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x63, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, - 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x1a, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, - 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x1a, 0x75, 0x32, - 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0}}, - {0x0706, 64, { 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, - 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f, 0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x1a, - 0x75, 0x34, 0x01, 0xd2, 0x08, 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4}}, - {0x0746, 64, { 0xff, 0xad, 0x3f, 0x12, 0x12, 0x1a, 0xe4, 0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, - 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, - 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c, 0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, - 0xf5, 0x39, 0xd2, 0x08, 0x90, 0x7e, 0x3f, 0xe0, 0x60, 0x11, 0x90, 0x7f, 0xd7, 0x74, 0x13}}, - {0x0786, 64, { 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0, 0x74, 0x36, 0xf0, 0xd2, 0x04, 0xc2, 0x06, 0xe4, 0x90, 0x7f, - 0xd1, 0xf0, 0x30, 0x1a, 0x54, 0xe5, 0x39, 0x60, 0x02, 0x15, 0x39, 0x30, 0x13, 0x4b, 0xe5, 0x13, - 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x40, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, - 0x13, 0x12, 0x13, 0x63, 0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x33, 0x60, 0x05, 0x85, 0x19}}, - {0x07c6, 64, { 0x33, 0xd2, 0x08, 0x12, 0x13, 0x9f, 0xef, 0x54, 0x80, 0x64, 0x80, 0xf5, 0x19, 0x65, 0x2f, 0x60, 0x05, - 0x85, 0x19, 0x2f, 0xd2, 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x9f, 0xef, 0x54, 0x10, 0xf5, 0x19, - 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, - 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x15, 0x90, 0x7b, 0x42}}, - {0x0806, 64, { 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, - 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x09, 0x24, - 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, - 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9e}}, - {0x0846, 64, { 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, - 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38, 0x10, 0xe4, 0xf5, 0x2c, - 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08, 0x39, 0xe5, 0x39, 0x70, - 0x35, 0xc2, 0x08, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xee}}, - {0x0886, 64, { 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9e, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, - 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, - 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a, 0x64, 0x02, 0x70, 0x36, - 0x30, 0x14, 0x2f, 0xc2, 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x0e, 0x25, 0x18}}, - {0x08c6, 64, { 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9e, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, - 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, - 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15, 0xe4, 0xf5, 0x18, 0x7e, - 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9e}}, - {0x0906, 64, { 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, - 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x0a, 0x22, 0x90, 0x7f, - 0xe9, 0xe0, 0x12, 0x0e, 0xf6, 0x0a, 0x0c, 0x00, 0x0a, 0x80, 0x01, 0x0a, 0xec, 0x03, 0x09, 0x48, - 0x06, 0x09, 0xff, 0x08, 0x09, 0xf9, 0x09, 0x09, 0xe1, 0x0a, 0x09, 0xf0, 0x0b, 0x00, 0x00}}, - {0x0946, 64, { 0x0b, 0x3b, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61, 0x24, 0x02, 0x60, 0x03, - 0x02, 0x09, 0xd7, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, - 0x0b, 0x42, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, - 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82}}, - {0x0986, 64, { 0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, - 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, - 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xea, - 0xe0, 0xff, 0x12, 0x0f, 0x1c, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9}}, - {0x09c6, 64, { 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x42, - 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, - 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, - 0x0b, 0x42, 0x12, 0x0b, 0x4a, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90}}, - {0x0a06, 64, { 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, - 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x16, 0xe4, 0x33, - 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, - 0x42, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02}}, - {0x0a46, 64, { 0x0b, 0x42, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, - 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, - 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x42, 0x90, - 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe}}, - {0x0a86, 64, { 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, - 0x10, 0x02, 0x0b, 0x42, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x42, 0x90, 0x7f, - 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, - 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83}}, - {0x0ac6, 64, { 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, - 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, - 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, - 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80, 0x3f, 0x90, 0x7f, 0xb4}}, - {0x0b06, 64, { 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, - 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, - 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0}}, - {0x0b46, 64, { 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, - 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, - 0x7f, 0x98, 0x74, 0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, - 0xde, 0xf0, 0xe4, 0xf5, 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9}}, - {0x0b86, 64, { 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xe4, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3a, - 0x01, 0xe4, 0xf5, 0x38, 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b, 0xc2, 0x05, 0xc2, 0x00, - 0xc2, 0x09, 0xc2, 0x13, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, - 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xd0, 0x7f, 0x10, 0x8f, 0x42, 0x12}}, - {0x0bc6, 64, { 0x10, 0xa0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, - 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, - 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x11, 0xd0, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, - 0x11, 0xd0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05}}, - {0x0c06, 64, { 0x7d, 0x7f, 0x12, 0x11, 0xd0, 0x7f, 0x01, 0x12, 0x12, 0x89, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xd0, - 0x7f, 0x13, 0x7d, 0x09, 0x12, 0x11, 0xd0, 0x20, 0x1b, 0x03, 0x02, 0x0c, 0xc9, 0x75, 0x2d, 0x01, - 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, - 0x0e, 0xe4, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5, 0x39}}, - {0x0c46, 64, { 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2, 0x00, 0xc2, 0x0a, 0xc2, 0x13, 0x90, - 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, - 0xe4, 0xfd, 0x12, 0x12, 0x1a, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x11, 0x12, 0x90, 0x7f, 0x98, 0x74, - 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f}}, - {0x0c86, 64, { 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, - 0x12, 0x1a, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12, 0x12, 0x1a, 0x90, 0x7f, 0x98, - 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x12, 0x1a, 0x7f, - 0x01, 0x12, 0x12, 0xaa, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x1a, 0x7f, 0x13, 0x7d, 0x09}}, - {0x0cc6, 64, { 0x12, 0x12, 0x1a, 0xd2, 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, - 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, - 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, - 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90}}, - {0x0d06, 64, { 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, - 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, - 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, - 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5}}, - {0x0d46, 64, { 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, - 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, - 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, - 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92}}, - {0x0d86, 64, { 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, - 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, - 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, - 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0}}, - {0x0dc6, 64, { 0xd2, 0xaf, 0xd2, 0x1a, 0x12, 0x12, 0x64, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, - 0x12, 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, - 0x05, 0xd2, 0x1a, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, - 0x05, 0xc2, 0x1a, 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x25, 0x80}}, - {0x0e06, 64, { 0xd6, 0x30, 0x18, 0xd3, 0xc2, 0x18, 0x12, 0x13, 0xab, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, - 0xfd, 0x75, 0x81, 0x47, 0x02, 0x0e, 0x59, 0x02, 0x0d, 0x81, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, - 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, - 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40}}, - {0x0e46, 64, { 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, - 0x40, 0x80, 0x90, 0x12, 0xcb, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, - 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, - 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3}}, - {0x0e86, 64, { 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, - 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, - 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, - 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22}}, - {0x0ec6, 64, { 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, - 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, - 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, - 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3}}, - {0x0f06, 64, { 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, - 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, - 0x75, 0x1c, 0x86, 0xab, 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xb7, 0xb4, - 0x03, 0x1d, 0xaf, 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0x9e, 0x7e}}, - {0x0f46, 64, { 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, - 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, - 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, - 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15}}, - {0x0f86, 64, { 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x3f, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, - 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, - 0xe5, 0x1a, 0xf0, 0x12, 0x13, 0x57, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, - 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13}}, - {0x0fc6, 64, { 0x93, 0x8f, 0x1a, 0xef, 0x42, 0x37, 0x80, 0xca, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, - 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, - 0x27, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x20, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, - 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x22}}, - {0x1006, 64, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x11, - 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, - 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, - 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08}}, - {0x1046, 64, { 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, - 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, - 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, - 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0}}, - {0x1086, 64, { 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, - 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, - 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22}}, - {0x10c6, 64, { 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, - 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, - 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98}}, - {0x1106, 64, { 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, - 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, - 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, - 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f}}, - {0x1146, 64, { 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, - 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, - 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f}}, - {0x1186, 64, { 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, - 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, - 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, - 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b}}, - {0x11c6, 64, { 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, - 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, - 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, - 0x27, 0x8f, 0x1a, 0x12, 0x13, 0x27, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12}}, - {0x1206, 64, { 0x13, 0x27, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x27, 0x8f, 0x1b, 0x80, 0xe8, - 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, - 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, - 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x7b, 0x8f, 0x1a, 0x12, 0x13}}, - {0x1246, 64, { 0x7b, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x7b, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, - 0x1b, 0x60, 0x07, 0x12, 0x13, 0x7b, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0xd6, - 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, - 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xe7, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44}}, - {0x1286, 64, { 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xd0, 0x90, 0x7f, - 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, - 0x11, 0xd0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x1a, 0x90, - 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80}}, - {0x12c6, 64, { 0xfd, 0x12, 0x12, 0x1a, 0x22, 0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, 0x00, - 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10, 0xc1, 0x16, 0x01, 0x0a, 0x00, 0xc1, 0x9b, 0x00, - 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, 0x60, - 0x05, 0x12, 0x0d, 0x60, 0x80, 0xee, 0x22, 0x00, 0x00, 0x02, 0x10, 0x06, 0x00, 0x02, 0x13}}, - {0x1306, 64, { 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x10, 0x2d, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90}}, - {0x1346, 64, { 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff}}, - {0x1386, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, - 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x12, 0x0f, 0xcf, 0x12, 0x0d, 0x71, 0x12, 0x0b, 0x4a, 0x22, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x10, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}}, - {0x1a06, 4, { 0x72, 0x00, 0x00, 0x00}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa49w_fw.h b/drivers/usb/serial/keyspan_usa49w_fw.h deleted file mode 100644 index dc24dac..0000000 --- a/drivers/usb/serial/keyspan_usa49w_fw.h +++ /dev/null @@ -1,464 +0,0 @@ -/* keyspan_usa49w_fw.h - - The firmware contained herein as keyspan_usa49w_fw.h is - - Copyright (C) 1999-2001 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -*/ - -static const struct ezusb_hex_record keyspan_usa49w_firmware[] = { - {0x0033, 3, { 0x02, 0x18, 0xfb}}, - {0x0036, 12, { 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0046, 16, { 0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x15}}, - {0x0056, 16, { 0x24, 0x04, 0xfd, 0xe4, 0x35, 0x14, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9}}, - {0x0066, 16, { 0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0xf1, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x15, 0x24, 0x05, 0xf5}}, - {0x0076, 16, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x34, 0xe5, 0x15, 0x24, 0x09}}, - {0x0086, 16, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x0a, 0xf5, 0x82}}, - {0x0096, 16, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x16, 0x47, 0xe5}}, - {0x00a6, 16, { 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xcf, 0xf0, 0x80, 0x41}}, - {0x00b6, 16, { 0xe5, 0x15, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x76}}, - {0x00c6, 16, { 0xe5, 0x15, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03}}, - {0x00d6, 16, { 0x7f, 0x01, 0xe5, 0x15, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12}}, - {0x00e6, 16, { 0x16, 0x47, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x30}}, - {0x00f6, 16, { 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0}}, - {0x0003, 16, { 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74}}, - {0x0013, 16, { 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24}}, - {0x0023, 16, { 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22}}, - {0x0043, 3, { 0x02, 0x1b, 0x00}}, - {0x0000, 3, { 0x02, 0x10, 0x95}}, - {0x0106, 64, { 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, - 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x15, 0x24, 0x0c}}, - {0x0146, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, - 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, - 0x0d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x4f, 0xe5}}, - {0x0186, 64, { 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x32, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, - 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x15, - 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x16, 0x47, 0xe5}}, - {0x01c6, 64, { 0x15, 0x24, 0x0e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x33, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, - 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x15, 0x24, 0x33, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x15, 0x24, 0x0f}}, - {0x0206, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xe7, 0xe5, 0x15, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x17, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4}}, - {0x0246, 64, { 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xb7, 0xe5, 0x15, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, - 0x44, 0x01, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}}, - {0x0286, 64, { 0x83, 0xe0, 0x54, 0xfe, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x12, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14}}, - {0x02c6, 64, { 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x16, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82}}, - {0x0306, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x54, 0xbf, 0xf0, 0xe5, 0x15, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}}, - {0x0346, 64, { 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, - 0x15, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, - 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x15, - 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78}}, - {0x0386, 64, { 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, - 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x6b, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0, - 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14}}, - {0x03c6, 64, { 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x12, 0x00, - 0x36, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x47, 0xe5, 0x15, - 0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2b}}, - {0x0406, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1b, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x47, 0xe5}}, - {0x0446, 64, { 0x15, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x16, 0x42, 0x13, - 0xe5, 0x15, 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x70, 0x0e, 0xe5, - 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2a, 0x90, 0x78, 0x41, - 0x74, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}}, - {0x0486, 64, { 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xef, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5}}, - {0x04c6, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1e, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x47, - 0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5}}, - {0x0506, 64, { 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, - 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15, - 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4, - 0xff, 0x12, 0x16, 0x47, 0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}}, - {0x0546, 64, { 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x18, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x21, 0xf5, 0x82}}, - {0x0586, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, - 0x01, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0}}, - {0x05c6, 64, { 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x03, 0x12, 0x18, 0x85, 0xe5, 0x15, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, - 0x60, 0x1b, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x08, - 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0xff, 0xe5, 0x16, 0xf4, 0xfe, 0xef, 0x5e, 0xf0, 0xe5, 0x15}}, - {0x0606, 64, { 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x16, 0xe5, 0x15, 0x24, 0x31, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x16, - 0xf0, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x12, 0x03, 0x07, 0x83, 0x00, 0x07, 0xf7, 0x01, 0x08, - 0x63, 0x03, 0x06, 0x4c, 0x06, 0x07, 0x74, 0x08, 0x07, 0x68, 0x09, 0x07, 0x50, 0x0a, 0x07}}, - {0x0646, 64, { 0x5f, 0x0b, 0x00, 0x00, 0x08, 0xb2, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x1c, 0x14, 0x70, 0x03, - 0x02, 0x06, 0xfe, 0x24, 0x02, 0x60, 0x03, 0x02, 0x07, 0x46, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, - 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, - 0x17, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe0, 0x04, 0x7f, 0x03, 0x80}}, - {0x0686, 64, { 0x02, 0x7f, 0x02, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x6d, 0x75, 0x83, 0x19, - 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75, - 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80, - 0x02, 0x7f, 0x32, 0x75, 0x82, 0x1a, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x90, 0x7f, 0xef, 0xe0}}, - {0x06c6, 64, { 0xfe, 0x90, 0x7f, 0xee, 0xe0, 0x7c, 0x00, 0x24, 0x00, 0xf5, 0x19, 0xec, 0x3e, 0xf5, 0x18, 0x75, 0x33, - 0x19, 0x75, 0x34, 0x12, 0x75, 0x82, 0x14, 0x75, 0x83, 0x19, 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, - 0xd3, 0xe5, 0x28, 0x95, 0x19, 0xe5, 0x27, 0x95, 0x18, 0x40, 0x06, 0x85, 0x18, 0x27, 0x85, 0x19, - 0x28, 0x12, 0x13, 0x12, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x14, 0x2b}}, - {0x0706, 64, { 0xea, 0x49, 0x60, 0x32, 0x90, 0x7f, 0xee, 0xe0, 0x75, 0x18, 0x00, 0xf5, 0x19, 0xae, 0x02, 0xaf, 0x01, - 0x8e, 0x33, 0x8f, 0x34, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x27, 0xf5, 0x28, - 0xd3, 0x95, 0x19, 0xe5, 0x27, 0x95, 0x18, 0x40, 0x06, 0x85, 0x18, 0x27, 0x85, 0x19, 0x28, 0x12, - 0x13, 0x12, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xb9}}, - {0x0746, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0x00, 0xe5, 0x25, 0xf0, 0x90, - 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x25, 0x02, 0x08, - 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x22, 0x12, 0x0a, 0xb8, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0x00, - 0xe5, 0x22, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xe8}}, - {0x0786, 64, { 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, - 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, - 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xb9, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, - 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80}}, - {0x07c6, 64, { 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, - 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, - 0x74, 0x02, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xb9, - 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x08, 0xb9}}, - {0x0806, 64, { 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, - 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, - 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff}}, - {0x0846, 64, { 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, - 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, - 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, - 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea}}, - {0x0886, 64, { 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, - 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, - 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe5, 0x11, 0x54, 0x0f, 0x70}}, - {0x08c6, 64, { 0x03, 0x02, 0x09, 0xb2, 0x12, 0x16, 0xa5, 0xef, 0x20, 0xe1, 0x75, 0x12, 0x17, 0x03, 0xef, 0x14, 0xf5, - 0x19, 0x12, 0x18, 0xcc, 0xef, 0x25, 0x19, 0xff, 0xe4, 0x33, 0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee, - 0x64, 0x80, 0x94, 0x80, 0x50, 0x59, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, - 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82}}, - {0x0906, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe2, 0x12, 0xe5, 0x19, 0x60, 0x0e, 0xf5, 0x23, 0xef, 0x24, - 0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0xad, 0xe4, 0xff, 0x12, 0x14, 0xe3}}, - {0x0946, 64, { 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe7, 0x5d, 0x12, 0x18, - 0xcc, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3, - 0x9e, 0x50, 0x48, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, - 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7b}}, - {0x0986, 64, { 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, - 0x13, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0xf5, 0x24, 0x80, 0x03, 0x12, 0x12, 0xa1, 0x12, 0x16, 0xd4, 0xef, 0x30, - 0xe1, 0x03, 0x02, 0x0a, 0xb7, 0x12, 0x17, 0xd2, 0x8f, 0x19, 0x12, 0x18, 0xd8, 0xe5, 0x15}}, - {0x09c6, 64, { 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x19, 0xc3, 0x9f, 0x50, 0x28, 0x12, 0x18, 0xb4, - 0xef, 0x30, 0xe0, 0x21, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, - 0x20, 0xe7, 0x12, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}}, - {0x0a06, 64, { 0x20, 0xe1, 0x03, 0x02, 0x0a, 0xb7, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x19, 0x70, 0x03, 0x02, 0x0a, 0xb7, 0xb4, 0x80, 0x0f, 0xe5, 0x15, - 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, - 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe7, 0x29, 0xe5, 0x19}}, - {0x0a46, 64, { 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x23, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, - 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x2c, 0xf5, 0x2d, 0x12, 0x13, 0xdd, 0xe5, 0x19, 0x25, - 0xe0, 0xff, 0x12, 0x15, 0x19, 0x22, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, - 0x85, 0x19, 0x23, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}}, - {0x0a86, 64, { 0xff, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83, - 0xef, 0xf0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x24, 0x01, - 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0x6c, 0xe5, 0x19, 0x04, 0xff, 0x12, 0x15, 0x19, - 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96}}, - {0x0ac6, 64, { 0xf0, 0xe4, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0, 0xf5, 0x8e, 0x90, 0x7f, 0x95, 0x74, - 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x1f, 0xf0, 0x90, 0x78, - 0x43, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x9f, 0xf0, 0x90, - 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x7e, 0x7b, 0x7f, 0xc0, 0x75}}, - {0x0b06, 64, { 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x0f, 0x12, - 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, - 0x75, 0x16, 0x01, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, - 0x7e, 0x7e, 0x7f, 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7e, 0xf0, 0xa3, 0x74}}, - {0x0b46, 64, { 0x40, 0xf0, 0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, - 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, - 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x0f, 0x12, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, - 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0xe5, 0x15}}, - {0x0b86, 64, { 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x7e, 0x7d, 0x7f, 0xc0, 0x85, - 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7e, 0x7f, 0x00, - 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0x7e, - 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0}}, - {0x0bc6, 64, { 0x75, 0x16, 0x04, 0x12, 0x0f, 0x12, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, - 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f, 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, - 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f, 0x80, 0x85, 0x15, 0x82, 0x85}}, - {0x0c06, 64, { 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, - 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x0f, 0x12, - 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, - 0x75, 0x16, 0x08, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74}}, - {0x0c46, 64, { 0x03, 0xf0, 0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7c, 0xf0, 0xa3, 0x74, - 0xc0, 0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, - 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0xc2, 0x0a, 0xc2, 0x09, 0xd2, 0x02, 0x22, 0xe5, 0x10, 0x04, 0x54, - 0x03, 0xf5, 0x10, 0x14, 0x60, 0x1f, 0x14, 0x60, 0x31, 0x14, 0x60, 0x43, 0x24, 0x03, 0x70}}, - {0x0c86, 64, { 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, - 0x75, 0x16, 0x01, 0x80, 0x3d, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, - 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x80, 0x28, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, - 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0x80, 0x13}}, - {0x0cc6, 64, { 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, - 0x16, 0x08, 0xe5, 0x32, 0x55, 0x16, 0x70, 0x03, 0x02, 0x0e, 0x11, 0xe5, 0x16, 0xf4, 0xff, 0x52, - 0x32, 0xe5, 0x26, 0x54, 0x7f, 0xfe, 0x70, 0x0f, 0xe5, 0x2a, 0x55, 0x16, 0x60, 0x24, 0x90, 0x7f, - 0x98, 0xe0, 0x45, 0x16, 0xf0, 0x80, 0x1b, 0xbe, 0x20, 0x18, 0xe5, 0x15, 0x24, 0x31, 0xf5}}, - {0x0d06, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x09, 0xe4, 0xf5, 0x2a, 0x90, 0x7f, 0x98, 0xe0, - 0x5f, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x03, - 0xe0, 0x14, 0xf0, 0xe5, 0x15, 0x24, 0x34, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0x11, 0x74, 0x0a, 0xf0, 0x12, 0x00}}, - {0x0d46, 64, { 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x19, 0xe5, 0x15, 0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x19, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x12, 0x18, 0xe4, 0x8f, - 0x19, 0xe5, 0x15, 0x24, 0x27, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x19, - 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24}}, - {0x0d86, 64, { 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x19, 0x54, 0x80, 0xfe, 0x6f, 0x60, - 0x06, 0xee, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x29, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x19, 0x54, 0x20, 0xfe, 0x6f, 0x60, 0x15, 0xee, 0xf0, 0xe5, 0x15, - 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe4, 0x04, 0xe5, 0x16}}, - {0x0dc6, 64, { 0x42, 0x13, 0xe5, 0x12, 0x55, 0x16, 0xff, 0xf5, 0x19, 0xe5, 0x15, 0x24, 0x2a, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x16, 0xe5, 0x19, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x17, 0x55, - 0x16, 0xff, 0xf5, 0x19, 0xe5, 0x15, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}}, - {0x0e06, 64, { 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x19, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x22, 0x30, 0x09, 0x03, 0x02, 0x0f, - 0x11, 0xe5, 0x24, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14, 0x60, 0x58, 0x14, 0x60, 0x6f, 0x24, - 0x04, 0x60, 0x03, 0x02, 0x0e, 0xcf, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, - 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x12, 0xa1, 0x75, 0x24, 0x01}}, - {0x0e46, 64, { 0x22, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, - 0x75, 0x16, 0x02, 0x12, 0x12, 0xa1, 0x75, 0x24, 0x02, 0x22, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, - 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x12, 0xa1, - 0x75, 0x24, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90}}, - {0x0e86, 64, { 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x12, 0xa1, 0x75, 0x24, 0x04, 0x22, 0x30, 0x04, - 0x33, 0xc2, 0x04, 0x53, 0x13, 0xdf, 0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2e, 0x25, - 0x19, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0xab, 0xff, 0x74, 0x80, 0x25, 0x19, 0xf5, 0x82, - 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x03, 0xdb, 0x90}}, - {0x0ec6, 64, { 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0x75, 0x24, 0x05, 0x22, 0xe5, 0x36, 0x60, 0x3b, 0xd5, 0x36, 0x0a, 0x53, - 0x13, 0xef, 0x30, 0x0a, 0x04, 0xd2, 0x09, 0xc2, 0x0a, 0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x00, - 0x74, 0x35, 0x25, 0x19, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0xab, 0xff, 0x74, 0x80, 0x25, - 0x19, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x19, 0xe5, 0x19, 0xb4}}, - {0x0f06, 64, { 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x24, 0x22, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, - 0x7b, 0x01, 0xe5, 0x15, 0x25, 0x1a, 0xf9, 0xee, 0x35, 0x14, 0xfa, 0xe4, 0x12, 0x11, 0xf1, 0x05, - 0x1a, 0xe5, 0x1a, 0xb4, 0x3c, 0xe8, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5}}, - {0x0f46, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, - 0x12, 0x16, 0x47, 0x7f, 0x10, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xef, 0xf0, 0x12, 0x15, 0xb7, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0xe5, 0x15, 0x24, - 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x44, 0x06, 0x90, 0xc0, 0x00}}, - {0x0f86, 64, { 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x16, 0x47, 0xe4, 0xff, - 0x7e, 0xa3, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xee, 0xf0, 0xfd, - 0x12, 0x16, 0x47, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f}}, - {0x0fc6, 64, { 0x05, 0x7d, 0x7f, 0x12, 0x16, 0x47, 0x7f, 0x01, 0x12, 0x15, 0x4f, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x16, - 0x47, 0x22, 0x53, 0x13, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7b, 0x7f, 0xc0, - 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0x12, - 0x08, 0xc1, 0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14}}, - {0x1006, 64, { 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x08, 0xc1, 0x90, - 0x7c, 0x71, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, - 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x08, 0xc1, 0x90, 0x7c, 0xb1, 0xe0, - 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f}}, - {0x1046, 64, { 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x08, 0xc1, 0x05, 0x11, 0xe5, 0x11, 0x54, 0x0f, 0xf5, - 0x18, 0x70, 0x1f, 0x90, 0x78, 0x41, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf5, 0x17, - 0x90, 0x78, 0x41, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf4, 0xf5, 0x12, 0x12, 0x11, - 0x21, 0x22, 0xe5, 0x18, 0xb4, 0x01, 0x04, 0x12, 0x0c, 0x73, 0x22, 0x90, 0x7f, 0xc2, 0xe0}}, - {0x1086, 64, { 0x20, 0xe1, 0x08, 0xe5, 0x13, 0x60, 0x04, 0x12, 0x0e, 0x12, 0x22, 0x12, 0x0c, 0x73, 0x22, 0x78, 0x7f, - 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x37, 0x02, 0x10, 0xdc, 0x02, 0x12, 0x29, 0xe4, 0x93, 0xa3, - 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, - 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20}}, - {0x10c6, 64, { 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, - 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x18, 0x50, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, - 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, - 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8}}, - {0x1106, 64, { 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, - 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x90, 0x7f, 0xd2, 0xe0, 0x30, 0xe1, - 0x03, 0x02, 0x11, 0xaa, 0xc2, 0x09, 0x90, 0x7b, 0x40, 0xe0, 0x14, 0x60, 0x26, 0x14, 0x60, 0x3b, - 0x14, 0x60, 0x50, 0x24, 0x83, 0x60, 0x64, 0x24, 0x80, 0x70, 0x63, 0x7e, 0x7b, 0x7f, 0xc0}}, - {0x1146, 64, { 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x00, - 0x46, 0x80, 0x4b, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, - 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x00, 0x46, 0x80, 0x33, 0x7e, 0x7c, 0x7f, 0x40, 0x75, - 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0x12}}, - {0x1186, 64, { 0x00, 0x46, 0x80, 0x1b, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, - 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x00, 0x46, 0x80, 0x03, 0x12, 0x17, 0x5c, 0xe4, 0x90, - 0x7f, 0xd3, 0xf0, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, - 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01}}, - {0x11c6, 64, { 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, - 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, - 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, - 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0}}, - {0x1206, 64, { 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, - 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, - 0x80, 0xdf, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, - 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0}}, - {0x1246, 64, { 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, - 0x90, 0x7f, 0xaf, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x0b, - 0x12, 0x18, 0x14, 0xc2, 0x01, 0xe4, 0xf5, 0x2b, 0xf5, 0x31, 0xc2, 0x07, 0xc2, 0x02, 0x75, 0x29, - 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x26, 0x60, 0x06, 0x75, 0x32, 0x0f, 0xe0, 0xf5, 0x26}}, - {0x1286, 64, { 0x30, 0x02, 0x03, 0x12, 0x0f, 0xd9, 0x30, 0x01, 0x07, 0xc2, 0x01, 0x12, 0x06, 0x29, 0x80, 0xe2, 0x30, - 0x08, 0xdf, 0xc2, 0x08, 0x12, 0x18, 0x35, 0x80, 0xd8, 0x22, 0xe5, 0x13, 0x55, 0x16, 0x60, 0x6a, - 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x5c, 0xe5, 0x16, - 0xf4, 0x52, 0x13, 0xe5, 0x15, 0x24, 0x26, 0xff, 0xe4, 0x35, 0x14, 0xfe, 0xe4, 0xfd, 0x0f}}, - {0x12c6, 64, { 0xef, 0xaa, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0xfc, 0x74, 0x80, 0x2d, 0xf5, - 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0xbd, 0x0b, 0xe2, 0x90, 0x7f, 0xc3, 0x74, - 0x0b, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x10, 0xf0, - 0xe5, 0x15, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15}}, - {0x1306, 64, { 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x22, 0xe5, 0x28, 0x45, 0x27, 0x60, - 0x57, 0xae, 0x27, 0xaf, 0x28, 0xd3, 0xef, 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x04, 0x7e, 0x00, - 0x7f, 0x40, 0xc3, 0xe5, 0x28, 0x9f, 0xf5, 0x28, 0xe5, 0x27, 0x9e, 0xf5, 0x27, 0xe4, 0xfd, 0xed, - 0xc3, 0x9f, 0xe4, 0x9e, 0x50, 0x1f, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0x74}}, - {0x1346, 64, { 0x00, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0x05, 0x34, 0xe5, 0x34, 0x70, - 0x02, 0x05, 0x33, 0x80, 0xda, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x44, - 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xef, 0xf0, 0x22, 0x90, 0x7f, 0xac, 0xe0, 0x54, 0xfe, 0xf0, 0xe4, - 0x90, 0x7f, 0xb5, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0}}, - {0x1386, 64, { 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4, 0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, - 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x30, 0x00, 0x07, 0xe5, 0x29, 0x54, 0xf0, 0xff, - 0x80, 0x02, 0x7f, 0x00, 0xef, 0x44, 0x08, 0x90, 0x78, 0x41, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, - 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0}}, - {0x13c6, 64, { 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, - 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x8f, 0x1a, 0x05, 0x2d, 0xe5, 0x2d, 0xae, 0x2c, 0x70, 0x02, - 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x18, 0xf0, 0x05, 0x2d, 0xe5, - 0x2d, 0xac, 0x2c, 0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15}}, - {0x1406, 64, { 0x23, 0xe5, 0x23, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xc0, - 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x18, 0xd8, 0x8f, 0x1a, 0xee, 0x4f, 0xd0, 0x82, 0xd0, 0x83, - 0xf0, 0x80, 0xb5, 0x22, 0x8f, 0x1a, 0xe4, 0xf5, 0x1b, 0x75, 0x1c, 0xff, 0x75, 0x1d, 0x19, 0x75, - 0x1e, 0x86, 0xab, 0x1c, 0xaa, 0x1d, 0xa9, 0x1e, 0x90, 0x00, 0x01, 0x12, 0x11, 0xc4, 0xb4}}, - {0x1446, 64, { 0x03, 0x1d, 0xaf, 0x1b, 0x05, 0x1b, 0xef, 0xb5, 0x1a, 0x01, 0x22, 0x12, 0x11, 0xab, 0x7e, 0x00, 0x29, - 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1c, 0xff, 0xf5, 0x1d, 0x89, 0x1e, 0x80, 0xd4, 0x7b, 0x00, - 0x7a, 0x00, 0x79, 0x00, 0x22, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x78, 0x4f, 0x74, 0xc0, 0xf0, - 0xe4, 0x90, 0x78, 0x50, 0xf0, 0xe5, 0x2c, 0x90, 0x78, 0x51, 0xf0, 0xae, 0x2c, 0xe5, 0x2d}}, - {0x1486, 64, { 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0x90, - 0x7f, 0xe2, 0xe0, 0x44, 0x10, 0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, - 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0xe5, 0x2c, 0x90, 0x78, 0x4f, - 0xf0, 0xae, 0x2c, 0xe5, 0x2d, 0x90, 0x78, 0x50, 0xf0, 0x90, 0x78, 0x51, 0x74, 0xc0, 0xf0}}, - {0x14c6, 64, { 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, - 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22, 0xe5, 0x15, 0x24, 0x04, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x13, 0x14, 0x60, - 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f, 0xc9, 0xef, 0xf0}}, - {0x1506, 64, { 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd, 0xef, 0xf0, 0xe5, 0x16, 0x42, - 0x2a, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, - 0x0f, 0x14, 0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xb7, 0xef, 0xf0, 0x80, 0x13, - 0x90, 0x7f, 0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb, 0xef, 0xf0, 0x80, 0x05, 0x90}}, - {0x1546, 64, { 0x7f, 0xbd, 0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x15, 0x24, 0x32, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xfd, 0x12, 0x16, 0x47, 0x90, 0x78, - 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xfd, 0x12, 0x16, 0x47, 0x22, 0xc0, 0xe0}}, - {0x1586, 64, { 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, - 0x75, 0xd0, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, 0x12, 0x13, 0x12, 0xd0, - 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, - 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41}}, - {0x15c6, 64, { 0x74, 0x02, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, - 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, - 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74, - 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15}}, - {0x1606, 64, { 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, - 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74, - 0x06, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, - 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0}}, - {0x1646, 64, { 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x07, 0xf0, 0x90, 0xc0, - 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x90, - 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0xe4, 0x90, 0x78, 0x41}}, - {0x1686, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0xe5, 0x15, - 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14, 0x60, 0x11, - 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc8, 0xe0}}, - {0x16c6, 64, { 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc, 0xe0, 0xff, 0x22, 0xe5, 0x15, 0x24, - 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14, 0x60, 0x11, 0x14, - 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xb8, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0, 0xff, 0x22, 0xe5, 0x15, 0x24}}, - {0x1706, 64, { 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, - 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc9, 0xe0, 0xff, 0x22, 0x90, - 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, - 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0}}, - {0x1746, 64, { 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, - 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x36, 0x43, 0x13, 0x10, 0xa3, 0xe0, - 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0x90, 0x7b, 0x43, 0xe0, 0xf5, - 0x37, 0xa3, 0xe0, 0x54, 0xf0, 0xf5, 0x29, 0xe0, 0x60, 0x02, 0xd2, 0x0a, 0x22, 0xc0, 0xe0}}, - {0x1786, 64, { 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x01, 0x53, 0x91, - 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, - 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, - 0x75, 0x86, 0x00, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0}}, - {0x17c6, 64, { 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x12, 0x18, 0xc0, 0xae, 0x07, - 0x12, 0x18, 0xc0, 0xad, 0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x18, 0xc0, 0xae, 0x07, 0xee, 0x6d, - 0x60, 0x07, 0x12, 0x18, 0xc0, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06, 0x22, 0x74, 0x00, 0xf5, 0x86, - 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f}}, - {0x1806, 64, { 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x90, 0x7f, 0xd6, - 0xe0, 0x44, 0x04, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x0b, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, - 0xf4, 0x7e, 0x01, 0x12, 0x18, 0x6b, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0x12, 0x13, - 0x7c, 0x12, 0x18, 0x04, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0a, 0x7f, 0x05, 0x7e, 0x00}}, - {0x1846, 64, { 0x12, 0x18, 0x6b, 0x12, 0x18, 0x9e, 0x12, 0x0a, 0xb8, 0x22, 0x03, 0x35, 0x80, 0x00, 0x00, 0x03, 0x2e, - 0x81, 0x00, 0x00, 0xc1, 0x85, 0xc1, 0x81, 0xc1, 0x08, 0xc1, 0x00, 0xc1, 0x06, 0x01, 0x22, 0x00, - 0x01, 0x24, 0x00, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, - 0x15, 0x18, 0x4e, 0x60, 0x08, 0x12, 0x17, 0xf3, 0x12, 0x17, 0xf3, 0x80, 0xeb, 0x22, 0xe5}}, - {0x1886, 64, { 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x04, 0xff, 0x44, 0x10, 0x90, 0x7f, - 0xd7, 0xf0, 0xef, 0x44, 0x30, 0xf0, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, - 0x7e, 0x00, 0x12, 0x18, 0x6b, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x78, 0x41, - 0x74, 0x02, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0}}, - {0x18c6, 64, { 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, - 0x22, 0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, - 0x74, 0x06, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0x00}}, - {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x0a, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x55, 0x00, 0x53, - 0x00, 0x42, 0x00, 0x20, 0x00, 0x34, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, - 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00}}, - {0x1a06, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1a46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1a86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1ac6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x17, 0x84, 0x00, 0x02, 0x1b}}, - {0x1b06, 21, { 0x04, 0x00, 0x02, 0x17, 0x32, 0x00, 0x02, 0x17, 0xab, 0x00, 0x02, 0x1b, 0x10, 0x00, 0x02, 0x1b, 0x14, - 0x00, 0x02, 0x15, 0x84}}, - {0xffff, 0, {0x00}} -}; diff --git a/drivers/usb/serial/keyspan_usa49wlc_fw.h b/drivers/usb/serial/keyspan_usa49wlc_fw.h deleted file mode 100644 index bef06a3..0000000 --- a/drivers/usb/serial/keyspan_usa49wlc_fw.h +++ /dev/null @@ -1,476 +0,0 @@ -/* keyspan_usa49w_fw.h - - The firmware contained herein as keyspan_usa49w_fw.h is - - Copyright (C) 1999-2003 - Keyspan, A division of InnoSys Incorporated ("Keyspan") - - as an unpublished work. This notice does not imply unrestricted or - public access to the source code from which this firmware image is - derived. Except as noted below this firmware image may not be - reproduced, used, sold or transferred to any third party without - Keyspan's prior written consent. All Rights Reserved. - - Permission is hereby granted for the distribution of this firmware - image as part of a Linux or other Open Source operating system kernel - in text or binary form as required. - - This firmware may not be modified and may only be used with - Keyspan hardware. Distribution and/or Modification of the - keyspan.c driver which includes this firmware, in whole or in - part, requires the inclusion of this statement." - -static char theFirmwareDate49[] = - "02/14/2002 02:37p 19,347 USA49"; - - - -static char theFirmwareDate65[] = - "01/31/2003 09:34a 19,331 USA65"; - - -*/ - -static const struct ezusb_hex_record keyspan_usa49wlc_firmware[] = { - {0x7f92, 1, { 0x01}}, - {0x0033, 3, { 0x02, 0x18, 0xfb}}, - {0x0036, 13, { 0xe5, 0x11, 0x04, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}}, - {0x0046, 16, { 0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x15}}, - {0x0056, 16, { 0x24, 0x04, 0xfd, 0xe4, 0x35, 0x14, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9}}, - {0x0066, 16, { 0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0xec, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x15, 0x24, 0x05, 0xf5}}, - {0x0076, 16, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x34, 0xe5, 0x15, 0x24, 0x09}}, - {0x0086, 16, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x0a, 0xf5, 0x82}}, - {0x0096, 16, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x16, 0x6b, 0xe5}}, - {0x00a6, 16, { 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xcf, 0xf0, 0x80, 0x41}}, - {0x00b6, 16, { 0xe5, 0x15, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03}}, - {0x00c6, 16, { 0xe5, 0x15, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xab}}, - {0x00d6, 16, { 0x7f, 0x01, 0xe5, 0x15, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12}}, - {0x00e6, 16, { 0x16, 0x6b, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x30}}, - {0x00f6, 16, { 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0}}, - {0x0003, 16, { 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74}}, - {0x0013, 16, { 0xf0, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24}}, - {0x0023, 16, { 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22}}, - {0x0043, 3, { 0x02, 0x1b, 0x00}}, - {0x0000, 3, { 0x02, 0x10, 0x90}}, - {0x0106, 64, { 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf2, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, - 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x15, 0x24, 0x0c}}, - {0x0146, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, - 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, - 0x0d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x4f, 0xe5}}, - {0x0186, 64, { 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x32, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, - 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x15, - 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x16, 0x6b, 0xe5}}, - {0x01c6, 64, { 0x15, 0x24, 0x0e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x33, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, - 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x15, 0x24, 0x33, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x15, 0x24, 0x0f}}, - {0x0206, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x0b, 0xe5, 0x15, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x3b, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4}}, - {0x0246, 64, { 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xdb, 0xe5, 0x15, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, - 0x44, 0x01, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}}, - {0x0286, 64, { 0x83, 0xe0, 0x54, 0xfe, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x12, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14}}, - {0x02c6, 64, { 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x16, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82}}, - {0x0306, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x54, 0xbf, 0xf0, 0xe5, 0x15, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}}, - {0x0346, 64, { 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, - 0x15, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, - 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x15, - 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78}}, - {0x0386, 64, { 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, - 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x6b, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0, - 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14}}, - {0x03c6, 64, { 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x12, 0x00, - 0x36, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x6b, 0xe5, 0x15, - 0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2b}}, - {0x0406, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1b, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x6b, 0xe5}}, - {0x0446, 64, { 0x15, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x16, 0x42, 0x13, - 0xe5, 0x15, 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x70, 0x0e, 0xe5, - 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2a, 0x90, 0x78, 0x41, - 0x74, 0xf2, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}}, - {0x0486, 64, { 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xef, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, - 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5}}, - {0x04c6, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1e, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x6b, - 0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5}}, - {0x0506, 64, { 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, - 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15, - 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4, - 0xff, 0x12, 0x16, 0x6b, 0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}}, - {0x0546, 64, { 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x18, 0x90, 0x78, 0x41, 0x74, 0xf2, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x21, 0xf5, 0x82}}, - {0x0586, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, - 0x01, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0}}, - {0x05c6, 64, { 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, - 0x03, 0x12, 0x18, 0x7a, 0xe5, 0x15, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, - 0x60, 0x23, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x08, - 0xf0, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0xff, 0x42, 0x11, 0x90, 0x7f, 0x96, 0xe0, 0x4f, 0xf0}}, - {0x0606, 64, { 0x90, 0x78, 0x41, 0xe0, 0x4f, 0xf0, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x60, 0x24, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, - 0xf7, 0xf0, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0xf4, 0xff, 0x52, 0x11, 0x90, 0x7f, 0x96, 0xe0, 0x5f, - 0xf0, 0x90, 0x78, 0x41, 0xe0, 0x5f, 0xf0, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x11, 0xfe}}, - {0x0646, 64, { 0x07, 0x99, 0x00, 0x08, 0x0d, 0x01, 0x08, 0x79, 0x03, 0x06, 0x62, 0x06, 0x07, 0x8a, 0x08, 0x07, 0x7e, - 0x09, 0x07, 0x66, 0x0a, 0x07, 0x75, 0x0b, 0x00, 0x00, 0x08, 0xc8, 0x90, 0x7f, 0xeb, 0xe0, 0x24, - 0xfe, 0x60, 0x1c, 0x14, 0x70, 0x03, 0x02, 0x07, 0x14, 0x24, 0x02, 0x60, 0x03, 0x02, 0x07, 0x5c, - 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0xcf}}, - {0x0686, 64, { 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, - 0xe0, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, - 0x75, 0x82, 0x6d, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, - 0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea}}, - {0x06c6, 64, { 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80, 0x02, 0x7f, 0x32, 0x75, 0x82, 0x1a, 0x75, 0x83, 0x19, 0xef, - 0xf0, 0x90, 0x7f, 0xef, 0xe0, 0xfe, 0x90, 0x7f, 0xee, 0xe0, 0x7c, 0x00, 0x24, 0x00, 0xf5, 0x18, - 0xec, 0x3e, 0xf5, 0x17, 0x75, 0x33, 0x19, 0x75, 0x34, 0x12, 0x75, 0x82, 0x14, 0x75, 0x83, 0x19, - 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xd3, 0xe5, 0x28, 0x95, 0x18, 0xe5, 0x27, 0x95, 0x17}}, - {0x0706, 64, { 0x40, 0x06, 0x85, 0x17, 0x27, 0x85, 0x18, 0x28, 0x12, 0x13, 0x0d, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, - 0xe0, 0xff, 0x12, 0x14, 0x5f, 0xea, 0x49, 0x60, 0x32, 0x90, 0x7f, 0xee, 0xe0, 0x75, 0x17, 0x00, - 0xf5, 0x18, 0xae, 0x02, 0xaf, 0x01, 0x8e, 0x33, 0x8f, 0x34, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, - 0xa3, 0xe0, 0x8e, 0x27, 0xf5, 0x28, 0xd3, 0x95, 0x18, 0xe5, 0x27, 0x95, 0x17, 0x40, 0x06}}, - {0x0746, 64, { 0x85, 0x17, 0x27, 0x85, 0x18, 0x28, 0x12, 0x13, 0x0d, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xb4, 0xe0, 0x44, - 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, - 0x7f, 0x00, 0xe5, 0x25, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, - 0xea, 0xe0, 0xf5, 0x25, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x22, 0x12, 0x0a}}, - {0x0786, 64, { 0xce, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0x00, 0xe5, 0x22, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, - 0x08, 0xcf, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, - 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, - 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xcf, 0xe4}}, - {0x07c6, 64, { 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, - 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, - 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, - 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xb4}}, - {0x0806, 64, { 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, - 0x60, 0x03, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08, - 0xcf, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, 0xe0, 0x70, - 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54}}, - {0x0846, 64, { 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, - 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, - 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, - 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90}}, - {0x0886, 64, { 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, - 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, - 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, - 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}}, - {0x08c6, 64, { 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, - 0xe5, 0x12, 0x54, 0x0f, 0x70, 0x03, 0x02, 0x09, 0xc8, 0x12, 0x16, 0x9a, 0xef, 0x20, 0xe1, 0x75, - 0x12, 0x16, 0xf8, 0xef, 0x14, 0xf5, 0x18, 0x12, 0x18, 0xc5, 0xef, 0x25, 0x18, 0xff, 0xe4, 0x33, - 0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x59, 0x85, 0x15, 0x82}}, - {0x0906, 64, { 0x85, 0x14, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, - 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, - 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, - 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe2, 0x12, 0xe5}}, - {0x0946, 64, { 0x18, 0x60, 0x0e, 0xf5, 0x23, 0xef, 0x24, 0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0xa0, - 0xe4, 0xff, 0x12, 0x14, 0xd7, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, - 0xe0, 0x30, 0xe7, 0x5d, 0x12, 0x18, 0xc5, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x48, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82}}, - {0x0986, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, - 0xf5, 0x83, 0xe0, 0x54, 0x7b, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x15, - 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xf5, 0x24, 0x80, 0x03, 0x12}}, - {0x09c6, 64, { 0x12, 0x9c, 0x12, 0x16, 0xc9, 0xef, 0x30, 0xe1, 0x03, 0x02, 0x0a, 0xcd, 0x12, 0x17, 0xc7, 0x8f, 0x18, - 0x12, 0x18, 0xd3, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, - 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0xc3, - 0x9f, 0x50, 0x28, 0x12, 0x18, 0xa9, 0xef, 0x30, 0xe0, 0x21, 0xe5, 0x15, 0x24, 0x38, 0xf5}}, - {0x0a06, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe7, 0x12, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x03, 0x02, 0x0a, 0xcd, 0xe5, 0x15, 0x24, 0x31, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x18, 0x70, 0x03, 0x02, 0x0a, - 0xcd, 0xb4, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}}, - {0x0a46, 64, { 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, - 0x30, 0xe7, 0x29, 0xe5, 0x18, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x18, 0x20, 0x85, 0x18, 0x23, - 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x2c, 0xf5, 0x2d, - 0x12, 0x13, 0xcf, 0xe5, 0x18, 0x25, 0xe0, 0xff, 0x12, 0x15, 0x0d, 0x22, 0xe5, 0x18, 0xd3}}, - {0x0a86, 64, { 0x94, 0x3f, 0x40, 0x03, 0x75, 0x18, 0x3f, 0x85, 0x18, 0x23, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, - 0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, - 0xe0, 0xfe, 0xa3, 0xe0, 0x24, 0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0x1d}}, - {0x0ac6, 64, { 0xe5, 0x18, 0x04, 0xff, 0x12, 0x15, 0x0d, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, - 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0, - 0xf5, 0x8e, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, - 0x98, 0x74, 0x2f, 0xf0, 0x90, 0x78, 0x43, 0x74, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0}}, - {0x0b06, 64, { 0x90, 0x7f, 0xdf, 0x74, 0x9f, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, - 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, - 0x75, 0x16, 0x01, 0x12, 0x0f, 0x28, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, - 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82}}, - {0x0b46, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x7e, 0x7e, 0x7f, 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, - 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x15, 0x82, 0x85, 0x14, - 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, - 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x0f}}, - {0x0b86, 64, { 0x28, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, - 0x75, 0x16, 0x02, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, - 0xf0, 0x7e, 0x7d, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, - 0xc0, 0xf0, 0x7e, 0x7e, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74}}, - {0x0bc6, 64, { 0x7e, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, - 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x0f, 0x28, 0x7e, 0x7c, 0x7f, 0x40, 0x75, - 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0xe5, 0x15, - 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f}}, - {0x0c06, 64, { 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f, - 0x80, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0, - 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, - 0x75, 0x16, 0x08, 0x12, 0x0f, 0x28, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15}}, - {0x0c46, 64, { 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14, - 0x83, 0x74, 0x7c, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85, - 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0xc2, 0x0a, 0xc2, 0x09}}, - {0x0c86, 64, { 0xe4, 0xf5, 0x11, 0xd2, 0x02, 0x22, 0xe5, 0x10, 0x04, 0x54, 0x03, 0xf5, 0x10, 0x14, 0x60, 0x1f, 0x14, - 0x60, 0x31, 0x14, 0x60, 0x43, 0x24, 0x03, 0x70, 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, - 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x80, 0x3d, 0x7e, 0x7c, - 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75}}, - {0x0cc6, 64, { 0x16, 0x02, 0x80, 0x28, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, - 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0x80, 0x13, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, - 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0xe5, 0x32, 0x55, 0x16, 0x70, - 0x03, 0x02, 0x0e, 0x27, 0xe5, 0x16, 0xf4, 0x52, 0x32, 0xe5, 0x26, 0x54, 0x7f, 0xff, 0x70}}, - {0x0d06, 64, { 0x17, 0xe5, 0x2a, 0x55, 0x16, 0x60, 0x34, 0x90, 0x7f, 0x96, 0xe0, 0xfe, 0xe5, 0x16, 0xc4, 0x54, 0xf0, - 0xf4, 0xfd, 0xee, 0x5d, 0xf0, 0x80, 0x23, 0xbf, 0x20, 0x20, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x11, 0xe4, 0xf5, 0x2a, 0x90, 0x7f, 0x96, 0xe0, - 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0xfe, 0xef, 0x4e, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5}}, - {0x0d46, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe5, 0x15, 0x24, 0x34, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02, - 0x0e, 0x27, 0x74, 0x0a, 0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x18, 0xe5, 0x15, - 0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x18}}, - {0x0d86, 64, { 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x12, 0x18, 0xe1, 0x8f, 0x18, 0xe5, 0x15, 0x24, 0x27, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, - 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, - 0xff, 0xe5, 0x18, 0x54, 0x80, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x16, 0x42, 0x13}}, - {0x0dc6, 64, { 0xe5, 0x15, 0x24, 0x29, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x54, 0x20, - 0xfe, 0x6f, 0x60, 0x15, 0xee, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x30, 0xe4, 0x04, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x2a, 0xf5, 0x82, 0xe4, - 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x54, 0x40, 0xfe, 0x6f, 0x60, 0x15, 0xee}}, - {0x0e06, 64, { 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5, - 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, - 0x22, 0x30, 0x09, 0x03, 0x02, 0x0f, 0x27, 0xe5, 0x24, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14, - 0x60, 0x58, 0x14, 0x60, 0x6f, 0x24, 0x04, 0x60, 0x03, 0x02, 0x0e, 0xe5, 0x7e, 0x7b, 0x7f}}, - {0x0e46, 64, { 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x12, - 0x12, 0x9c, 0x75, 0x24, 0x01, 0x22, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, - 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x12, 0x9c, 0x75, 0x24, 0x02, 0x22, - 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x2b}}, - {0x0e86, 64, { 0xf0, 0x75, 0x16, 0x04, 0x12, 0x12, 0x9c, 0x75, 0x24, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, - 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x12, 0x9c, - 0x75, 0x24, 0x04, 0x22, 0x30, 0x04, 0x33, 0xc2, 0x04, 0x53, 0x13, 0xdf, 0xe4, 0xf5, 0x18, 0x7e, - 0x00, 0x7b, 0x00, 0x74, 0x2e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0xa6}}, - {0x0ec6, 64, { 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, - 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0x75, 0x24, 0x05, 0x22, 0xe5, 0x36, - 0x60, 0x3b, 0xd5, 0x36, 0x0a, 0x53, 0x13, 0xef, 0x30, 0x0a, 0x04, 0xd2, 0x09, 0xc2, 0x0a, 0xe4, - 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x35, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa}}, - {0x0f06, 64, { 0x12, 0x11, 0xa6, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, - 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x24, - 0x22, 0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x01, 0xe5, 0x15, 0x25, 0x19, 0xf9, 0xee, 0x35, 0x14, - 0xfa, 0xe4, 0x12, 0x11, 0xec, 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x3c, 0xe8, 0xe5, 0x15, 0x24}}, - {0x0f46, 64, { 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, - 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0, - 0x00, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x16, 0x6b, 0x7f, 0x10, 0xe5, 0x15, 0x24, 0x33, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x15, 0xdb, 0x90, 0x78, 0x41, 0x74}}, - {0x0f86, 64, { 0xf2, 0xf0, 0x7f, 0x01, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, - 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, - 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, - 0xfd, 0x12, 0x16, 0x6b, 0xe4, 0xff, 0x7e, 0xa3, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4}}, - {0x0fc6, 64, { 0x35, 0x14, 0xf5, 0x83, 0xee, 0xf0, 0xfd, 0x12, 0x16, 0x6b, 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x90, - 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x16, 0x6b, 0x7f, 0x01, 0x12, 0x15, 0x43, - 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x16, 0x6b, 0x22, 0x53, 0x13, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30, - 0xe3, 0x16, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98}}, - {0x1006, 64, { 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x08, 0xd7, 0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e, - 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, - 0x16, 0x02, 0x12, 0x08, 0xd7, 0x90, 0x7c, 0x71, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40, - 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04}}, - {0x1046, 64, { 0x12, 0x08, 0xd7, 0x90, 0x7c, 0xb1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, - 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x08, 0xd7, 0x05, - 0x12, 0xe5, 0x12, 0x54, 0x0f, 0xf5, 0x17, 0x70, 0x04, 0x12, 0x11, 0x1c, 0x22, 0xe5, 0x17, 0xb4, - 0x01, 0x04, 0x12, 0x0c, 0x8c, 0x22, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x08, 0xe5, 0x13}}, - {0x1086, 64, { 0x60, 0x04, 0x12, 0x0e, 0x28, 0x22, 0x12, 0x0c, 0x8c, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, - 0x81, 0x37, 0x02, 0x10, 0xd7, 0x02, 0x12, 0x24, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, - 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, - 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4}}, - {0x10c6, 64, { 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x90, 0x18, 0x45, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, - 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, - 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5}}, - {0x1106, 64, { 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, - 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x90, 0x7f, 0xd2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0xa5, 0xc2, - 0x09, 0x90, 0x7b, 0x40, 0xe0, 0x14, 0x60, 0x26, 0x14, 0x60, 0x3b, 0x14, 0x60, 0x50, 0x24, 0x83, - 0x60, 0x64, 0x24, 0x80, 0x70, 0x63, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15}}, - {0x1146, 64, { 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x00, 0x46, 0x80, 0x4b, 0x7e, 0x7c, - 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, 0x16, - 0x02, 0x12, 0x00, 0x46, 0x80, 0x33, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, - 0x90, 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x00, 0x46, 0x80, 0x1b, 0x7e}}, - {0x1186, 64, { 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, - 0x08, 0x12, 0x00, 0x46, 0x80, 0x03, 0x12, 0x17, 0x51, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22, 0xbb, - 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, - 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5}}, - {0x11c6, 64, { 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, - 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, - 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, - 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70}}, - {0x1206, 64, { 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, - 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x90, 0x7f, 0xae, - 0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, - 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff}}, - {0x1246, 64, { 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0x74, 0x01, - 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x0b, 0x12, 0x18, 0x09, 0xc2, 0x01, - 0xe4, 0xf5, 0x2b, 0xf5, 0x31, 0xc2, 0x07, 0xc2, 0x02, 0x75, 0x29, 0x0f, 0x90, 0x7f, 0xd8, 0xe0, - 0x65, 0x26, 0x60, 0x06, 0x75, 0x32, 0x0f, 0xe0, 0xf5, 0x26, 0x30, 0x02, 0x03, 0x12, 0x0f}}, - {0x1286, 64, { 0xef, 0x30, 0x01, 0x07, 0xc2, 0x01, 0x12, 0x06, 0x3f, 0x80, 0xe2, 0x30, 0x08, 0xdf, 0xc2, 0x08, 0x12, - 0x18, 0x2a, 0x80, 0xd8, 0x22, 0xe5, 0x13, 0x55, 0x16, 0x60, 0x6a, 0xe5, 0x15, 0x24, 0x3a, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x5c, 0xe5, 0x16, 0xf4, 0x52, 0x13, 0xe5, 0x15, - 0x24, 0x26, 0xff, 0xe4, 0x35, 0x14, 0xfe, 0xe4, 0xfd, 0x0f, 0xef, 0xaa, 0x06, 0x70, 0x01}}, - {0x12c6, 64, { 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0xfc, 0x74, 0x80, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, - 0x83, 0xec, 0xf0, 0x0d, 0xbd, 0x0b, 0xe2, 0x90, 0x7f, 0xc3, 0x74, 0x0b, 0xf0, 0xe5, 0x15, 0x24, - 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xe5, 0x15, 0x24, 0x2e, 0xf5, - 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82, 0xe4}}, - {0x1306, 64, { 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x22, 0xe5, 0x28, 0x45, 0x27, 0x60, 0x57, 0xae, 0x27, 0xaf, 0x28, - 0xd3, 0xef, 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x04, 0x7e, 0x00, 0x7f, 0x40, 0xc3, 0xe5, 0x28, - 0x9f, 0xf5, 0x28, 0xe5, 0x27, 0x9e, 0xf5, 0x27, 0xe4, 0xfd, 0xed, 0xc3, 0x9f, 0xe4, 0x9e, 0x50, - 0x1f, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0x74, 0x00, 0x2d, 0xf5, 0x82, 0xe4}}, - {0x1346, 64, { 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0x05, 0x34, 0xe5, 0x34, 0x70, 0x02, 0x05, 0x33, 0x80, 0xda, - 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb5, - 0xef, 0xf0, 0x22, 0x90, 0x7f, 0xac, 0xe0, 0x54, 0xfe, 0xf0, 0xe4, 0x90, 0x7f, 0xb5, 0xf0, 0x22, - 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0xe4, 0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f, 0x94, 0xf0}}, - {0x1386, 64, { 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f, - 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xff, 0xf0, 0x30, 0x00, 0x07, 0xe5, 0x29, 0x54, 0x0f, 0xff, - 0x80, 0x02, 0x7f, 0x00, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x1f, 0xf0, 0xe4, - 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0xdf}}, - {0x13c6, 64, { 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x8f, 0x19, 0x05, 0x2d, 0xe5, 0x2d, 0xae, 0x2c, - 0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x19, 0xf0, 0x12, 0x18, 0xef, 0x05, - 0x2d, 0xe5, 0x2d, 0xac, 0x2c, 0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, - 0x15, 0x23, 0xe5, 0x23, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14}}, - {0x1406, 64, { 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x18, 0xd3, 0x8f, 0x19, 0xee, 0x4f, 0xd0, 0x82, - 0xd0, 0x83, 0xf0, 0x80, 0xb5, 0x22, 0x90, 0x78, 0x41, 0xe5, 0x11, 0xf0, 0x90, 0x78, 0x4f, 0x74, - 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x50, 0xf0, 0xe5, 0x2c, 0x90, 0x78, 0x51, 0xf0, 0xae, 0x2c, 0xe5, - 0x2d, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90, 0x78, 0x57, 0x74}}, - {0x1446, 64, { 0x04, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x10, 0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x55, - 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22, 0x8f, 0x19, 0xe4, 0xf5, 0x1a, 0x75, 0x1b, 0xff, - 0x75, 0x1c, 0x19, 0x75, 0x1d, 0x86, 0xab, 0x1b, 0xaa, 0x1c, 0xa9, 0x1d, 0x90, 0x00, 0x01, 0x12, - 0x11, 0xbf, 0xb4, 0x03, 0x1d, 0xaf, 0x1a, 0x05, 0x1a, 0xef, 0xb5, 0x19, 0x01, 0x22, 0x12}}, - {0x1486, 64, { 0x11, 0xa6, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1b, 0xff, 0xf5, 0x1c, 0x89, 0x1d, - 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0x90, 0x78, 0x41, 0xe5, 0x11, 0xf0, 0xe5, - 0x2c, 0x90, 0x78, 0x4f, 0xf0, 0xae, 0x2c, 0xe5, 0x2d, 0x90, 0x78, 0x50, 0xf0, 0x90, 0x78, 0x51, - 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90}}, - {0x14c6, 64, { 0x78, 0x57, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22, - 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14, - 0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f, - 0xc9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd}}, - {0x1506, 64, { 0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, - 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xb7, - 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f, 0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb, 0xef, 0xf0, - 0x80, 0x05, 0x90, 0x7f, 0xbd, 0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xae, 0x07, 0xe4}}, - {0x1546, 64, { 0xff, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xfd, 0x12, - 0x16, 0x6b, 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x15, - 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xfd, 0x12, 0x16, 0x6b, - 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86}}, - {0x1586, 64, { 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, - 0x12, 0x13, 0x0d, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, - 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74}}, - {0x15c6, 64, { 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x78, 0x41, 0x74, 0xf2, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, - 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f}}, - {0x1606, 64, { 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, - 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, - 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf}}, - {0x1646, 64, { 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf6, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, - 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, - 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, - 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41}}, - {0x1686, 64, { 0x74, 0xf7, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf5, 0xf0, 0x90, 0xc0, 0x00, - 0xed, 0xf0, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, - 0x60, 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff, 0x22, - 0x90, 0x7f, 0xc8, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc}}, - {0x16c6, 64, { 0xe0, 0xff, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, - 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90, - 0x7f, 0xb8, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0, 0xff, - 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60}}, - {0x1706, 64, { 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f, - 0xc9, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22, - 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, - 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86}}, - {0x1746, 64, { 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x36, - 0x43, 0x13, 0x10, 0xa3, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, - 0x90, 0x7b, 0x43, 0xe0, 0xf5, 0x37, 0xa3, 0xe0, 0x54, 0xf0, 0xf5, 0x29, 0xe0, 0x60, 0x02, 0xd2, - 0x0a, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75}}, - {0x1786, 64, { 0x86, 0x00, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, - 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, - 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, - 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0}}, - {0x17c6, 64, { 0x32, 0x12, 0x18, 0xb7, 0xae, 0x07, 0x12, 0x18, 0xb7, 0xad, 0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x18, - 0xb7, 0xae, 0x07, 0xee, 0x6d, 0x60, 0x07, 0x12, 0x18, 0xb7, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06, - 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, - 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00}}, - {0x1806, 64, { 0x00, 0x00, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x04, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x0b, 0x04, - 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x18, 0x60, 0x90, 0x7f, 0xd6, 0xe0, 0x54, - 0xf7, 0xf0, 0x22, 0x12, 0x13, 0x77, 0x12, 0x17, 0xf9, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0a, - 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x18, 0x60, 0x12, 0x18, 0x93, 0x12, 0x0a, 0xce, 0x22, 0x03}}, - {0x1846, 64, { 0x35, 0x80, 0x00, 0x00, 0x03, 0x2e, 0x81, 0x00, 0x00, 0xc1, 0x85, 0xc1, 0x81, 0xc1, 0x08, 0xc1, 0x00, - 0xc1, 0x06, 0x01, 0x22, 0x00, 0x01, 0x24, 0x00, 0x00, 0x8e, 0x17, 0x8f, 0x18, 0xe5, 0x18, 0x15, - 0x18, 0xae, 0x17, 0x70, 0x02, 0x15, 0x17, 0x4e, 0x60, 0x08, 0x12, 0x17, 0xe8, 0x12, 0x17, 0xe8, - 0x80, 0xeb, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}}, - {0x1886, 64, { 0x04, 0xff, 0x44, 0x10, 0x90, 0x7f, 0xd7, 0xf0, 0xef, 0x44, 0x30, 0xf0, 0x22, 0x90, 0x7f, 0xd6, 0xe0, - 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x18, 0x60, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, - 0xf0, 0x22, 0xe5, 0x11, 0x24, 0x02, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, - 0xe5, 0x11, 0x24, 0x03, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe5}}, - {0x18c6, 64, { 0x11, 0x24, 0x04, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe5, 0x11, 0x24, 0x05, - 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe5, 0x11, 0x24, 0x06, 0x90, 0x78, - 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, 0xe5, 0x11, 0xf0, 0x90, 0xc0, - 0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0xff}}, - {0x1906, 64, { 0xff, 0x40, 0xcd, 0x06, 0x2a, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01, - 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, - 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, - 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}}, - {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, - 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, - 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}}, - {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}}, - {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x24, 0x03, 0x4b, 0x00, 0x65, - 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, - 0x00, 0x41, 0x00, 0x2d, 0x00, 0x34, 0x00, 0x39, 0x00, 0x57, 0x00, 0x4c, 0x00, 0x43, 0x00, 0x22, - 0x03, 0x55, 0x00, 0x53, 0x00, 0x41, 0x00, 0x2d, 0x00, 0x36, 0x00, 0x35, 0x00, 0x20, 0x00}}, - {0x1a06, 64, { 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x6a, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x33, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1a46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1a86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {0x1ac6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x17, 0x79, 0x00, 0x02, 0x1b}}, - {0x1b06, 21, { 0x04, 0x00, 0x02, 0x17, 0x27, 0x00, 0x02, 0x17, 0xa0, 0x00, 0x02, 0x1b, 0x10, 0x00, 0x02, 0x1b, 0x14, - 0x00, 0x02, 0x15, 0x78}}, - {0xffff, 0, { 0x00}}, -}; - - diff --git a/firmware/Makefile b/firmware/Makefile index be7e015..db1b01a 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -30,6 +30,25 @@ fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ kaweth/new_code_fix.bin \ kaweth/trigger_code_fix.bin +ifdef CONFIG_FIRMWARE_IN_KERNEL +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19) += keyspan/usa19.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QI) += keyspan/usa19qi.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19QW) += keyspan/usa19qw.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA19W) += keyspan/usa19w.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28) += keyspan/usa28.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XA) += keyspan/usa28xa.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28XB) += keyspan/usa28xb.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw +else +fw-shipped- := keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ + keyspan/usa19qi.fw keyspan/usa19qw.fw keyspan/usa19w.fw \ + keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ + keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw +endif fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index 9c2a1eb..d66291a 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -80,3 +80,42 @@ Licence: Unknown Found in hex form in the kernel source. -------------------------------------------------------------------------- + +Driver: keyspan -- USB Keyspan USA-xxx serial device + +File: keyspan/mpr.fw +File: keyspan/usa18x.fw +File: keyspan/usa19.fw +File: keyspan/usa19qi.fw +File: keyspan/usa19qw.fw +File: keyspan/usa19w.fw +File: keyspan/usa28.fw +File: keyspan/usa28xa.fw +File: keyspan/usa28xb.fw +File: keyspan/usa28x.fw +File: keyspan/usa49w.fw +File: keyspan/usa49wlc.fw + +Converted from Intel HEX files, used in our binary representation of ihex. + +Original licence information: + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." + +-------------------------------------------------------------------------- diff --git a/firmware/keyspan/mpr.HEX b/firmware/keyspan/mpr.HEX new file mode 100644 index 0000000..a53ba10 --- /dev/null +++ b/firmware/keyspan/mpr.HEX @@ -0,0 +1,104 @@ +:0300330002001AAE +:04001A0053D8EF3296 +:100003008E568F57E5571557AE56700215564E60EC +:0700130005120FA280EE228E +:0300230002004692 +:10004600C0E0C083C082C086758600C0D075D00867 +:1000560030990E300B07A20E929B853699C299D223 +:10006600122012030202F9C2123003197E7E7F406B +:10007600751A7E751B407517007E7D7FC075187DCD +:100086007519C080177E7D7FC0751A7D751BC0757A +:1000960017017E7E7F4075187E751940200B03027E +:1000A6000184E53AC39553503C200C342009319025 +:1000B6007F9BE055387029301012AF3A053AE51BA0 +:1000C6002FF582E4351AF583E013920EAF3A053A1E +:1000D600E51B2FF582E4351AF583E0F5360202F7C3 +:1000E600C20B0202F7300311907FC7E4F0A3E0547D +:1000F60002F51DA3E0F51C8011907FC9E4F0907F06 +:03004300020F00A9 +:03000000020026D5 +:0C002600787FE4F6D8FD75815A020A3399 +:40010600C6E05402F51DA3E0F51CE51724FF9203300D0DC20D907FBB7401F0C20B0202F7E51D6005C20B0202F7851C53851982851883E013920D7512FF200C3A2009379082 +:400146007F9BE05538702F30101C851982851883A3E013920E851982851883A3A3E0F536753A030202F7753A02851982851883A3E0F5360202F7753A01C20B0202F73003FE +:400186000E907FC6E05402F51DA3E0F51C800C907FC8E05402F51DA3E0F51CE53AC395535003020268E51D6007C214C2050202F7851C53851B82851A83E013920D7512FF61 +:4001C600300C03020260300903020260907F9BE05538600302026030101B851B82851A83A3E013929B851B82851A83A3A3E0F599753A03800D851B82851A83A3E0F5997575 +:400206003A02E53AC395534026300307907FC7E4F08005907FC9E4F0E51724FF9203200D030202F7C20D907FBB7401F00202F7301012AF3A053AE51B2FF582E4351AF58394 +:40024600E013920EAF3A053AE51B2FF582E4351AF583E0F536D20B0202F7753A01C2140202F7300C030202F53009030202F5907F9BE055387079301012AF3A053AE51B2FF2 +:40028600F582E4351AF583E013929BAF3A053AE51B2FF582E4351AF583E0F599E53AC395534022300307907FC7E4F08005907FC9E4F0E51724FF9203300D36C20D907FBB0E +:4002C6007401F0802C301012AF3A053AE51B2FF582E4351AF583E013920EAF3A053AE51B2FF582E4351AF583E0F536D20B8002C214D201209803020435C298200203020383 +:40030600A2201527AF39053974802FF582E4347EF583E599F030104DAF39053974802FF582E4347EF583E598F0803A859955E555B54704D209802EE555B54604C20980251C +:40034600AF39053974802FF582E4347EF583E555F0301011AF39053974802FF582E4347EF583E598F0D20FE539C395435003020433907FB8E030E116E539C39440500302F5 +:40038600043315391539052B433401020433907FB7E539F0753900C202020433201527AF39053974002FF582E4347EF583E599F030104DAF39053974002FF582E4347EF594 +:4003C60083E598F0803A859955E555B54704D209802EE555B54604C2098025AF39053974002FF582E4347EF583E555F0301011AF39053974002FF582E4347EF583E598F0EA +:40040600D20FE539C395434024907FB6E030E112E539C39440401615391539052B433401800B907FB9E539F0753900D202D201300105C201020056D0D0D086D082D083D02F +:40044600E032907FBCE020E154E5346050E531704CE53430E10BE4F52F753401753102800EA208E433F52FC208E4F534753110E4F5567E007B0074242556F9EE3400FA12D8 +:400486000C79FF74002556F582E4347DF583EFF00556E556B40CDB907FBD740CF0907FCAE030E1030205D1E4F55674402556F582E4347DF583E0FFE5567C007B00243BF903 +:4004C600EC3400FAEF120C920556E556B418DBE53B601175C92075C836853CCA853DCBE4907F9FF0E53E139210929F853F38E540139215E5416009907F98E054FBF0800744 +:40050600907F98E04404F0E5426009907F98E0547FF08007907F98E04480F0E548600BC20CC209907F95E04402F0E549600CD209433401907F95E04402F0E54A600DC2AFBB +:40054600C20BD200E4F553F53AD2AFE54B6005301502D209E54C6015907F95E054FDF0907F9EE04402F0907F98E054FDF0E54D600AD29CC298752C0175311EE54E6007C227 +:400586009CE4F539F52CE54F6003E4F539E5506002D207E551600AE54D7002F531E5514234E552601F907FD77411F07431F07412F07432F07413F07433F07414F07434F067 +:4005C600D203D202D208E4907FCBF0A20CE433FF652960058F29433401A209E433FF652A60058F2A433401907F9BE0FF54086408F55765256006855725433401EF5410643A +:4006060010F55765266006855726433401EF54406440F55765276006855727433401EF54206420F55765286006855728433401907F9AE054406440F557652E600685572E5B +:40064600433401300735C2AF300218907FB8E020E127E5396009907FB7F0E4F539C202C2078016907FB6E020E10FE5396009907FB9F0E4F539D202C207D2AF20053D3003DB +:400686001E907FC6E020E133907E40E013920D753A01907FC7E0F553D2057512FF801C907FC8E020E115907DC0E013920D753A01907FC9E0F553D2057512FF2014332000E6 +:4006C60006E53A6553702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F553F53A300D0AC20DC200907FBB7401F03014030207BF2005030207BF300C0314 +:400706000207BF3009030207BF907F9BE0553860030207BF30030C7E7E7F4075587E755940800A7E7D7FC075587D7559C0301012AF3A053AE5592FF582E43558F583E0137C +:40074600921AAF3A053AE5592FF582E43558F583E0F557E53AC39553502A301012AF3A053AE5592FF582E43558F583E013920EAF3A053AE5592FF582E43558F583E0F53688 +:40078600D20B8015C20B300309E4907FC7F0C2038007E4907FC9F0D203301004A21A929BD214C2AF855799200B0D300D0AC20DC200907FBB7401F0D2AF22907FE9E0120C70 +:4007C600A4091C0009890109E60307E306090D0809010908E90A08F80B00000A24907FEBE024FE601C14700302087924026003020A24740D907FD4F07487907FD5F0020AE6 +:400806002B907FEAE0B401047F0280027F037582D875830DEFF07582D175830DF07582CA75830DF07582C375830DF0907FEAE00475829E75830DF0907FEFE0FE907FEEE07B +:400846007C002400F55AEC3EF55975150D75169975829B75830DE0751300F514D3E514955AE51395594006855913855A14120BBA020A2B907FEAE0700B7556FF75570D7503 +:4008860058DC802D907FEAE0B4010B7556FF75570D7558E0801B907FEAE0B4020B7556FF75570D7558F080097556FF75570E75581E907FEEE0755900F55AAE57AF588E1512 +:4008C6008F168F828E83E0FEA3E08E13F514D3955AE51395594006855913855A14120BBA020A2B907F00E511F0907FB57401F0020A2B907FEAE0F511020A2B120C24907F84 +:40090600EAE0F510020A2B907F00E510F0907FB57401F0020A2B907FE8E0247F602714603424026003020A24A216E433FF25E0FFA218E4334F907F00F0E4A3F0907FB57455 +:4009460002F0020A2BE4907F00F0A3F0907FB57402F0020A2B907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00B +:40098600020A2B907FE8E024FE601724026003020A2B907FEAE064016003020A24C216020A2B907FEAE07076907FECE0F45480FFC4540FFFE054072F25E024B4F582E4348D +:4009C6007FF583E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F08045907FE8E024FE601024027039907FEAE06401702AD216802D907FEAE07020907F77 +:400A0600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08007907FB4E04401F0907FB4E04402F022C210E4F510F534C209C20CC20BC214C20DC215A5 +:400A4600C211C207C212C20FC208F535F539F553F53AF533F530F52FF52EF52DF52CF52BF52AF529F528F527F526F525F524C205C217C219C216C218C204D213C206C20178 +:400A8600907F92E054FDF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440FF0907FAC740EF0D2AFD2BCD247 +:400AC6001A120F7DC21730040312044830042A300627C206E51260161512907FD8E030E6047F0080027F20907F96EFF08006907F967420F0120B1480CD301707C217120741 +:400B0600C080C33019C0C219120EDC80B922E53160021531E53960556535704BE533F460020533E533C395444043C2AF30021B907FB8E020E12D907FB7E539F0C202E4F5AA +:400B460039F533F5357512FF8019907FB6E020E112907FB9E539F0D202E4F539F533F5357512FFD2AF8006853935E4F533E52C6030200F07907F9BE030E00FE52D6006E497 +:400B8600F52D433401E4F5308014E530D39545500DE530B54506752D014334010530C20F22907FD9E030E2047F0080027F20907F96EFF022E51445136057AE13AF14D3EF0F +:400BC6009440EE940040047E007F40C3E5149FF514E5139EF513E4FDEDC39FE49E501F851682851583E0FC74002DF582E4347FF583ECF00D0516E5167002051580DA907FC4 +:400C0600A97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022E4907F93F0907F9C7430F0907F967420F0907F947401F0907F9D74FFF0907F977486DF +:400C4600F0907F957403F0907F9E7484F0907F98F0E4907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D20422BB010689828A83E0225002E722C3 +:400C8600BBFE02E32289828A83E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA367 +:400CC600A3A380DFE4907F95F0907F94F0907F93F0907F9DE04402F0907F97E04442F0907F9C7410F0E4907F96F0907F9D74BEF03016047F8080027F00907F97EFF0E49045 +:400D06007F95F0907F9EF0907F98F022C0E0C0F0C083C082C085C084C086758600C0D075D0085391EF907FA97401F0120BBAD0D0D086D084D085D082D083D0F0D0E032C06A +:400D4600E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E03200000000000000000000000000000000000000000000001C +:400D86000012011001FFFFFF40CD061C010100010200020902430001010080320904000007FF00000007050102400000070502024000000705030240000007058102400002 +:400DC600010705820240000107058302400001070584024000010403090410034B00650079007300700061006E002E034B00650079007300700061006E00200055005000A3 +:400E0600530048003100310032002D00530065007200690061006C0022035500530041002D003500330020003200300030003200610070007200320036000000C0E0C083DB +:400E4600C082C085C084C0867586005391EF907FAB7402F0D206D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2175391EF907FAB7401F0D086D01F +:400E860084D085D082D083D0E032C0E0C083C082C085C084C086758600D2195391EF907FAB7408F0D086D084D085D082D083D0E032C0E0C083C082C085C084C08675860084 +:400EC6005391EF907FA97402F0D086D084D085D082D083D0E032120CCA120FB3907FD6E030E712E04401F07F0D7E00120003907FD6E054FEF0120C242200020E6900020EA3 +:400F06004200020D4500020E9000020F1000020F1400020D1200020F1C00020EB700020F2400020F3300020F2C00020F58C0E0C083C082C085C084C0867586005391EF90A9 +:400F46007FA97404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA97408F0D086D084D085D082D083D0E032907FD6E054FBF0E044C1 +:3D0F860008F0301A04E04402F07FF47E01120003907FD6E054F7F0E04404F0227400F58690FDA57C05A3E582458370F922907FD6E04480F04387010000000000222C +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." + +static char theFirmwareDate53[] = + "04/26/2002 02:47p 11,570 USA53"; + diff --git a/firmware/keyspan/usa18x.HEX b/firmware/keyspan/usa18x.HEX new file mode 100644 index 0000000..a9ff70e --- /dev/null +++ b/firmware/keyspan/usa18x.HEX @@ -0,0 +1,141 @@ +:030033000212F7BF +:10000300E4907F93F0907F9C7430F0E4907F96F0BF +:10001300907F94F0907F9D74FFF0E4907F97F09031 +:0F0023007F95F0907F9E7407F0E4907F98F02215 +:1000460030091812131BEFC3953C40030200D890E9 +:100056007FBF7401F0C209C200807730033B907FF6 +:10006600C6E020E16D12131BEFC394405064907EEE +:1000760040E0139209907FC7E014F5192000116043 +:100086000FF5087E7E7F41750C7E750D41120CBA08 +:10009600C203E4907FC7F08039907FC8E020E13248 +:1000A60012131BEFC394405029907DC0E0139209B0 +:1000B600907FC9E014F519200011600FF5087E7DC8 +:1000C6007FC1750C7D750DC1120CBAD203E4907F09 +:1000D600C9F0907FB6E030E1030201601211D68FBD +:1000E600191213278F36E519C3953A500F1212EBE2 +:1000F600EF30E008E53620E703300B5EC20BE5196A +:0C003600907F987410F090C000E0FF2252 +:03004300021300A5 +:03000000020E00ED +:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F4BE51925E0907FB7F08027E519D3943F400375193F851908D4 +:40014600907E80E536F07E7E7F81750C7E750D81120CDFE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AF1 +:400186007E79002400F9EC347EFAEF120ED20518E518B420D7907E00E06068907E03E060247F01E4FD1211B17F037DCD1211B1434680907F987414F090C000E546F0E490E0 +:4001C6007E13F08030907E01E0FF121035907E02E0FF12105B7F01907E11E0FD1211B17F037D071211B1434680907F987414F090C000E546F0907F987412F0E5404406903E +:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA +:400246007F5342FC907E09E06011434202A3E0FF1210A7907E0BE0FF1210CDAF42121081907E03E0600853427FAF42121081907E0CE06018A3E0600543460280035346FDB4 +:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B +:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212DFEF54FE90C000F0533EFDE4FFAD3E120F +:4003060011B1E4F52AF529D207907E17E0600F433E02E4FFAD3E1211B1752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98F2 +:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211B1752B01D207907E1BE0600F433E01E4FFAD3E1211B1E4F52BD207907E1CE0600E907F98741284 +:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892 +:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212DFEF5401F519652A600585192AD207121333EF5480F51965266005851926D207300D11127F +:400406001333EF5410F51965256005851925D207201B030207EC300A1812136FEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12136FEFC35A +:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D04C204E4907FCBF08039907FCCE020E13212136FEFC39440502990BC +:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D04D204E4907FCDF0907FBAE030E1030205361212208F1912137B8F37E519C3952B +:4004C6003B500F121357EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F84E503 +:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D29E51904907FBBF0907FD0E030E106200603020797C206E4F8 +:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120ED20518E518B420D7907E20E06068907E23E060247F01E4FD1211FB7F0329 +:400586007DCD1211FB434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121119907E22E0FF12113F7F01907E31E0FD1211FB7F037D071211FB4347809048 +:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB +:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121165907E2BE0FF12118BAF431210F3907E23E0600853437FAFFE +:40064600431210F3907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0D4 +:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 +:4006C600987409F012134BEF54FE90C000F0533FFDE4FFAD3F1211FBE4F533F532D208907E37E0600F433F02E4FFAD3F1211FB753201D208907E38E06010907F98740AF043 +:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F1211FB753401D208907E3BE0600F433F01E4E9 +:40074600FFAD3F1211FBE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741389 +:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C21312134BEF5401F51965336005851933D279 +:4007C60008121387EF5480F519652F600585192FD208300E11121387EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F5169035 +:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E8CFF748025BD +:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297 +:400886000E8CFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340083 +:4008C600FA120E8CFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E8CFF748025F2 +:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EE40A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F3D +:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2 +:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F0AEA49600DEA907FD4F0E9907FD5F085 +:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205 +:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04 +:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F +:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6 +:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049 +:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4 +:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B +:400B8600E4120ED20518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211B17F108F42121081907F02 +:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211B1E4FF7EA3AD068D3E1211B1907F987411F090C000E4F07F057D7F12118E +:400C0600B17F0112126A7F037D071211B1201B03020CB7752D017518017B00742D2518F9E43400FAE4120ED20518E518B409EA753B01E4F539F513F537C208C20CC206C2CD +:400C460000C20AC213907F98740BF075450390C0007403F07F0CE4FD1211FB7F108F431210F3907F98740AF07F018F41EF440690C000F0907F98740CF075478090C000744E +:400C860080F00FE4FD1211FBE4FF7EA3AD068D3F1211FB907F987409F090C000E4F07F057D7F1211FB7F0112128B7F037D071211FBD21222907F987410F0AF08E50DF582A5 +:400CC600E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF22907F20 +:400D0600987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C000E00586F0A3055C +:400D460086DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F0907FAEE0FFD39210E433FEEF4EF089 +:400D8600D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A121245C211E4F50BF513C217C212D4 +:400DC600907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D3C21812139380CC22787FE4F6D8FDC7 +:400E0600758147020E47020D6FE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B01020408102040F5 +:400E4600809012ACE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CA1E +:400E8600DFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E5B8 +:400EC6008229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3C1 +:400F0600A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EA5B4031DAF190519EFB5180122120E8C7E0029FFEE3AA907751AFFF51B891C80D47B00A5 +:400F46007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213278F1AEF423680CA228F1AFC +:400F8600050DE50DAE0C7002050C14F5828E83E51AF012133F050DE50DAC0C7002050C14F5828C83EFF01508E508600A12137B8F1AEF423780CA22C0E0C083C082C085C088 +:400FC60084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D0C6 +:4010060085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F9874108A +:40104600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E544547F90C000F022907F98741349 +:40108600F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544D9 +:4010C600547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF0902A +:40110600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090AF +:40114600C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547FEC +:4011860090C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F09075 +:4011C600C000EFF0907F987415F090C000EDF02212130F8F1A12130F8F1BE51A651B601212130F8F1AE51A651B600712130F8F1B80E8AF1A22907F98740BF0E545547F9098 +:40120600C000F0907F98740FF090C000EFF0907F98740DF090C000EDF0221213638F1A1213638F1BE51A651B60121213638F1AE51A651B60071213638F1B80E8AF1A2290C8 +:401246007FD6E054FBF0E04408F0301A04E04402F07FF47E011212C8907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211B1907F987411F090C000EEF0E4E53E4480E8 +:40128600FD1211B122AE07E4FFE53F547FFD1211FB907F987409F090C000EEF0E4E53F4480FD1211FB22050E02000000000314030000C111C118C195C110C116010A00C19C +:4012C6001B008E188F19E5191519AE18700215184E6005120D4E80EE22907F987411F090C000E0FF22907F987412F090C000E0FF2253D8EF320000000000020FE70002130A +:401306000400020FBD0002100E907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22907F987408F09050 +:40134600C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FF22907F98740DF090C000E0FFC5 +:4013860022907F98740EF090C000E0FF22120003120D5F120B4622000000000000000000000000000000000000000000000000000000000000000000000000000000000083 +:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 +:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 +:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 +:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 +:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 +:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 +:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 +:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 +:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 +:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 +:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 +:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 +:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 +:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 +:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 +:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 +:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 +:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 +:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF +:401906000040CD06120100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400074 +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:141A06007200100330003000300030003000300030000000F7 +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19.HEX b/firmware/keyspan/usa19.HEX new file mode 100644 index 0000000..c5d1496 --- /dev/null +++ b/firmware/keyspan/usa19.HEX @@ -0,0 +1,101 @@ +:0A002600120DBF120F47120D6B22DE +:0300330002001AAE +:04001A0053D8EF3296 +:100003008E138F14E5141514AE13700215134E607E +:0700130005120F3680EE22FA +:0300230002004692 +:10004600C0E0C083C082C086758600C0D075D00867 +:1000560030990E300807A20B929B853599C299D22A +:100066000F200F03020431C20F20020302025620A2 +:100076000803020127E537C39550503E2009362074 +:100086000633907F9BE030E303200E29300D12AF3C +:1000960037053774402FF582E4347EF583E01392FA +:1000A6000BAF37053774402FF582E4347EF583E0D5 +:1000B600F53502042FC20802042F907FC7E4F0C270 +:1000C60002300A0CC20A907FBB04F0C20802042F59 +:1000D600907FC8E030E105C20802042F907FC9E096 +:1000E600F550907DC0E013920A20092D20062A9033 +:1000F6007F9BE030E303200E20300D11907DC1E0A0 +:03004300020F00A9 +:03000000020C618E +:4001060013920BA3E0F53575370302042F753702907DC1E0F53502042F753701C20802042FE537C3955050030201CF907FC6E030E107C210C20302042F907FC7E0F5509004 +:400146007E40E013920A3009030201C720067220006F907F9BE030E303200E65300D10907E41E013929BA3E0F5997537038009907E41E0F599753702E537C39550401790B1 +:400186007FC7E4F0C202200A0302042FC20A907FBB04F002042F300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E4347EF583E0F535D20802045D +:4001C6002F753701C21002042F300903020251200679907F9BE030E303200E6F300D12AF37053774402FF582E4347EF583E013929BAF37053774402FF582E4347EF583E046 +:40020600F599E537C395504017907FC7E4F0C202200A0302042FC20A907FBB04F002042F300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E43483 +:400246007EF583E0F535D20802042FC21002042F200803020308E537C39550503E200936200633907F9BE030E303200E29300D12AF37053774C02FF582E4347DF583E013DE +:40028600920BAF37053774C02FF582E4347DF583E0F53502042FC20802042F907FC9E4F0D202300A0CC20A907FBB04F0C20802042F907FC6E030E105C20802042F907FC765 +:4002C600E0F550907E40E013920A20092D20062A907F9BE030E303200E20300D11907E41E013920BA3E0F53575370302042F753702907E41E0F53502042F753701C20802EF +:40030600042FE537C3955050030203B0907FC8E030E107C210C20302042F907FC9E0F550907DC0E013920A3009030203A820067220006F907F9BE030E303200E65300D1034 +:40034600907DC1E013929BA3E0F5997537038009907DC1E0F599753702E537C395504017907FC9E4F0D202200A0302042FC20A907FBB04F002042F300D12AF37053774C0F5 +:400386002FF582E4347DF583E013920BAF37053774C02FF582E4347DF583E0F535D20802042F753701C21002042F30090302042D200674907F9BE030E303200E6A300D128E +:4003C600AF37053774C02FF582E4347DF583E013929BAF37053774C02FF582E4347DF583E0F599E537C395504013907FC9E4F0D202300A35C20A907FBB04F0802C300D12CC +:40040600AF37053774C02FF582E4347DF583E013920BAF37053774C02FF582E4347DF583E0F535D2088002C210D21220980302056DC2982001030204DA201127AF360536F3 +:4004460074802FF582E4347EF583E599F0300D4DAF36053674802FF582E4347EF583E598F0803A859910E510B54404D206802EE510B54304C2068025AF36053674802FF5AB +:4004860082E4347EF583E510F0300D11AF36053674802FF582E4347EF583E598F0D20CE536C39540500302056B907FB8E030E116E536C39440500302056B15361536052BDD +:4004C60043330102056B907FB7E536F0753600C20102056B201127AF36053674002FF582E4347EF583E599F0300D4DAF36053674002FF582E4347EF583E598F0803A859937 +:4005060010E510B54404D206802EE510B54304C2068025AF36053674002FF582E4347EF583E510F0300D11AF36053674002FF582E4347EF583E598F0D20CE536C3954040CE +:4005460024907FB6E030E112E536C39440401615361536052B433301800B907FB9E536F0753600D201D212301205C212020056D0D0D086D082D083D0E032907FCAE030E1CA +:40058600030206ABE4F51374402513F582E4347DF583E0FFE5137C007B002438F9EC3400FAEF120D330513E513B418DBE538600C75C92075C8348539CA853ACBE53B1392BF +:4005C6000D929FE53C13920EE53D139211E53E6009907F98E054FBF08007907F98E04404F0E53F6009907F98E0547FF08007907F98E04480F0E545600BC209C206907F950E +:40060600E04402F0E546600CD206433301907F95E04402F0E547600DC2AFC208D200E4F550F537D2AFE5486005301102D206E5496015907F95E054FDF0907F9EE04402F0AA +:40064600907F98E054FDF0E54A600AD29CC298752C0175311EE54B6007C29CE4F536F52CE54C6003E4F536E54D6002D204E54E600AE54A7002F531E54E4233E54F601F9064 +:400686007FD77411F07431F07412F07432F07413F07433F07414F07434F0D202D201D205E4907FCBF0A209E433FF652960058F29433301A206E433FF652A60058F2A4333BA +:4006C60001907F9BE05408B5250AE054086408F525433301907F9BE05410B5260AE054106410F526433301907F9BE05440B5270AE054406440F527433301907F9BE0542026 +:40070600B5280AE054206420F528433301300435C2AF300118907FB8E020E127E5366009907FB7F0E4F536C201C2048016907FB6E020E10FE5366009907FB9F0E4F536D234 +:4007460001C204D2AF20033730021B907FC6E020E12D907E40E013920A753701907FC7E0F550D2038019907FC8E020E112907DC0E013920A753701907FC9E0F550D20320E9 +:400786001033200006E5376550702A30031A300209E4907FC7F0C2028007E4907FC9F0D202C203E4F550F537300A0AC20AC200907FBB7401F03010030208C5200303020805 +:4007C600C5300E0A907F9BE030E3030208C53006030208C53009030208C5300262300D12AF37053774402FF582E4347EF583E0139219AF37053774402FF582E4347EF583CF +:40080600E0F514E537C39550502A300D12AF37053774402FF582E4347EF583E013920BAF37053774402FF582E4347EF583E0F535D208806BC208E4907FC7F0C20280603081 +:400846000D12AF37053774C02FF582E4347DF583E0139219AF37053774C02FF582E4347DF583E0F514E537C39550502A300D12AF37053774C02FF582E4347DF583E013929F +:400886000BAF37053774C02FF582E4347DF583E0F535D2088009C208E4907FC9F0D202300D04A219929BD210C2AF85149920080D300A0AC20AC200907FBB7401F0D2AF9072 +:4008C6007FBCE020E151E533604DE5317049E53330E108E4F52F753301800BA205E433F52FC205E4F533E4F5137E007B0074242513F9EE3400FA120CEDFF74002513F582D8 +:40090600E4347DF583EFF00513E513B40CDB907FBD740CF075311022907FE9E0120D450A03000A77010AE30309410609F40809E80909D00A09DF0B00000B32907FEBE024EB +:40094600FE601614605724027076740F907FD4F07464907FD5F0020B39907FEAE070047F0280027F037582B575830FEFF07582AE75830FF07582A775830FF07582A07583BA +:400986000FF0907FEAE00475827B75830FF0740F907FD4F07476907FD5F0020B39907FEAE0FF120E48EA49600DEA907FD4F0E9907FD5F0020B39907FB4E04401F0020B39D4 +:4009C600907FB4E04401F0020B39907F00E519F0907FB57401F0020B39907FEAE0F519020B39907FEAE0F518120D6B020B39907F00E518F0907FB57401F0020B39907FE822 +:400A0600E0247F60241460312402705BA213E433FF25E0FFA217E4334F907F00F0E4A3F0907FB57402F0020B39E4907F00F0A3F0907FB57402F0020B39907FECE0F45480B6 +:400A4600FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B39907FB4E04401F0020B39907FE8E024FE601D24026003020B3904 +:400A8600907FEAE0B40105C213020B39907FB4E04401F0020B39907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FFCC +:400AC600131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D213803F907FB4E04401F08036907FEA36 +:400B0600E07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022201503020B3E +:400B4600D3E53160021531E536604F65347045E532F460020532E532C39541403DC2AF300118907FB8E020E127907FB7E536F0C201E4F536F532F5348016907FB6E020E13D +:400B86000F907FB9E536F0D201E4F536F532F534D2AF8006853634E4F532E52C602F200C07907F9BE030E00FE52D6006E4F52D433301E4F5308014E530D39542500DE530DB +:400BC600B54206752D014333010530C20C22751201C214C218C213C217C215C212D216E4F518907F92E054FDF0907FAEE0FFD39213E433FEEF4EF0D2E843D820907FDE74DB +:400C060001F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD2BCD219120EDAC214301503120580907FD8E065116008E0F5CA +:400C460011120B4180EA301407C21412091E80E03018DDC21812002680D622787FE4F6D8FD758150020CA8020BD4E493A3F8E493A34003F68001F208DFF48029E493A3F83B +:400C86005407240CC8C333C4540F4420C8834004F456800146F6DFE4800B0102040810204080900E04E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E08E +:400CC60060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E4932242 +:400D0600BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D0E1 +:400D460083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DFE4907F93F0907F9C7430F0907F967410F0907F947401F0907F9D04E2 +:400D8600F0907F977420F0907F957403F0907F9E7484F0E4907F98F0907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D21522E4907F95F0907FF7 +:400DC60094F0907F93F0907F9DE04402F0907F97E04402F0907F9DE054FDF0907F9C7420F0E4907F96F0907F9DE044FDF0E4907F97F0907F9E74FFF0E4907F98F0220C24D0 +:400E0600000000000000000000000000013000013301013200013700015000013600013400C105C10CC103C10FC104C10EC111C10AC110C108C109C106C100C10DC181C109 +:400E460082008F13E4F5147515FF75160F7517B9AB15AA16A917900001120D06B4031DAF140514EFB5130122120CED7E0029FFEE3AA9077515FFF516891780D47B007A006D +:400E8600790022C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2145391C7 +:400EC600EF907FAB7401F0D086D084D085D082D083D0E032907FD6E054FBF0E04408F0301904E04402F07FF47E01120003907FD6E054F7F0E04404F02200020EB300020FC0 +:400F06000400020E8900020F0FC0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E0327400F58690FDA57C05A3E582458370F9B9 +:400F460022907FD6E04480F04387010000000000220000000000000000000000000012011001FF000040CD0607010100010200020902430001010080320904000007FF008A +:400F86000000070501024000000705020240000007050302400000070581024000010705820240000107058302400001070584024000010403090410034B00650079007332 +:170FC60000700061006E000E03530065007200690061006C00000064 +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19qi.HEX b/firmware/keyspan/usa19qi.HEX new file mode 100644 index 0000000..353bfcf --- /dev/null +++ b/firmware/keyspan/usa19qi.HEX @@ -0,0 +1,101 @@ +:0300330002001AAE +:04001A0053D8EF3296 +:100003008E118F12E5121512AE11700215114E608A +:0700130005120F8480EE22AC +:0300230002004692 +:10004600C0E0C083C082C086758600C0D075D00867 +:1000560030990E300B07A20E929B853699C299D223 +:100066001220120302041EC21220030302024E20B3 +:100076000B03020126E53AC39553503C200C34206D +:100086000931907F9BE055387029301012AF3A0540 +:100096003A74402FF582E4347EF583E013920EAF76 +:1000A6003A053A74402FF582E4347EF583E0F5365E +:1000B60002041CC20B02041C907FC7E4F0C203308A +:1000C6000D0CC20D907FBB04F0C20B02041C907F86 +:1000D600C8E030E105C20B02041C907FC9E0F5536D +:1000E600907DC0E013920D7516FF200C2B20092879 +:1000F600907F9BE055387020301011907DC1E01341 +:03004300020E00AA +:03000000020026D5 +:0C002600787FE4F6D8FD758154020B28A9 +:40010600920EA3E0F536753A0302041C753A02907DC1E0F53602041C753A01C20B02041CE53AC3955350030201C9907FC6E030E107C214C20502041C907FC7E0F553907ECB +:4001460040E013920D7516FF200C7020096D907F9BE055387065301010907E41E013929BA3E0F599753A038009907E41E0F599753A02E53AC395534017907FC7E4F0C203F6 +:40018600200D0302041CC20D907FBB04F002041C301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F536D20B02041C753A01C214A3 +:4001C60002041C300C03020249200977907F9BE05538706F301012AF3A053A74402FF582E4347EF583E013929BAF3A053A74402FF582E4347EF583E0F599E53AC3955340AB +:4002060017907FC7E4F0C203200D0302041CC20D907FBB04F002041C301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F536D20B44 +:4002460002041CC21402041C200B030202FFE53AC39553503C200C34200931907F9BE055387029301012AF3A053A74C02FF582E4347DF583E013920EAF3A053A74C02FF5F9 +:4002860082E4347DF583E0F53602041CC20B02041C907FC9E4F0D203300D0CC20D907FBB04F0C20B02041C907FC6E030E105C20B02041C907FC7E0F553907E40E013920DAF +:4002C6007516FF200C2B200928907F9BE055387020301011907E41E013920EA3E0F536753A0302041C753A02907E41E0F53602041C753A01C20B02041CE53AC39553500381 +:400306000203A2907FC8E030E107C214C20502041C907FC9E0F553907DC0E013920D7516FF200C7020096D907F9BE055387065301010907DC1E013929BA3E0F599753A037A +:400346008009907DC1E0F599753A02E53AC395534017907FC9E4F0D203200D0302041CC20D907FBB04F002041C301012AF3A053A74C02FF582E4347DF583E013920EAF3A81 +:40038600053A74C02FF582E4347DF583E0F536D20B02041C753A01C21402041C200C75200972907F9BE05538706A301012AF3A053A74C02FF582E4347DF583E013929BAF02 +:4003C6003A053A74C02FF582E4347DF583E0F599E53AC395534013907FC9E4F0D203300D35C20D907FBB04F0802C301012AF3A053A74C02FF582E4347DF583E013920EAF3D +:400406003A053A74C02FF582E4347DF583E0F536D20B8002C214D20120980302055AC2982002030204C7201627AF39053974802FF582E4347EF583E599F030104DAF3905C8 +:400446003974802FF582E4347EF583E598F0803A859910E510B54704D209802EE510B54604C2098025AF39053974802FF582E4347EF583E510F0301011AF39053974802F11 +:40048600F582E4347EF583E598F0D20FE539C395435003020558907FB8E030E116E539C39440500302055815391539052B433401020558907FB7E539F0753900C2020205D3 +:4004C60058201627AF39053974002FF582E4347EF583E599F030104DAF39053974002FF582E4347EF583E598F0803A859910E510B54704D209802EE510B54604C209802573 +:40050600AF39053974002FF582E4347EF583E510F0301011AF39053974002FF582E4347EF583E598F0D20FE539C395434024907FB6E030E112E539C3944040161539153909 +:40054600052B433401800B907FB9E539F0753900D202D201300105C201020056D0D0D086D082D083D0E032907FBCE020E151E534604DE5317049E53430E108E4F52F7534D4 +:4005860001800BA208E433F52FC208E4F534E4F5117E007B0074242511F9EE3400FA120D06FF74002511F582E4347DF583EFF00511E511B40CDB907FBD740CF075311090CD +:4005C6007FCAE030E1030206F3E4F51174402511F582E4347DF583E0FFE5117C007B00243BF9EC3400FAEF120D1F0511E511B418DBE53B601175C92075C836853CCA853D98 +:40060600CBE4907F9FF0E53E139210929F853F38E540139216E5416009907F98E054FBF08007907F98E04404F0E5426009907F98E0547FF08007907F98E04480F0E54860BE +:400646000BC20CC209907F95E04402F0E549600CD209433401907F95E04402F0E54A600DC2AFC20BD200E4F553F53AD2AFE54B6005301602D209E54C6015907F95E054FDB4 +:40068600F0907F9EE04402F0907F98E054FDF0E54D600AD29CC298752C0175311EE54E6007C29CE4F539F52CE54F6003E4F539E5506002D207E551600AE54D7002F531E55C +:4006C600514234E552601F907FD77411F07431F07412F07432F07413F07433F07414F07434F0D203D202D208E4907FCBF0A20CE433FF652960058F29433401A209E433FF84 +:40070600652A60058F2A433401907F9BE0FF54086408FE652560058E25433401EF54106410FE652660058E26433401EF54406440FE652760058E27433401EF54206420FE1C +:40074600652860058E28433401907F9AE054406440FE652E60058E2E433401300735C2AF300218907FB8E020E127E5396009907FB7F0E4F539C202C2078016907FB6E0203B +:40078600E10FE5396009907FB9F0E4F539D202C207D2AF20053D30031E907FC6E020E133907E40E013920D753A01907FC7E0F553D2057516FF801C907FC8E020E115907DD3 +:4007C600C0E013920D753A01907FC9E0F553D2057516FF201433200006E53A6553702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F553F53A300D0AC265 +:400806000DC200907FBB7401F0301403020914200503020914300C03020914300903020914907F9BE055386003020914300361301012AF3A053A74402FF582E4347EF5833F +:40084600E013921BAF3A053A74402FF582E4347EF583E0FEE53AC39553502A301012AF3A053A74402FF582E4347EF583E013920EAF3A053A74402FF582E4347EF583E0F546 +:4008860036D20B806AC20BE4907FC7F0C203805F301012AF3A053A74C02FF582E4347DF583E013921BAF3A053A74C02FF582E4347DF583E0FEE53AC39553502A301012AFE7 +:4008C6003A053A74C02FF582E4347DF583E013920EAF3A053A74C02FF582E4347DF583E0F536D20B8009C20BE4907FC9F0D203301004A21B929BD214C2AF8E99200B0D301D +:400906000D0AC20DC200907FBB7401F0D2AF22907FE9E0120D310A11000A7E010ADB030938060A020809F60909DE0A09ED0B00000B19907FEBE024FE601914605A24026041 +:4009460003020B19740D907FD4F07487907FD5F0020B20907FEAE070047F0280027F037582D875830DEFF07582D175830DF07582CA75830DF07582C375830DF0907FEAE078 +:400986000475829E75830DF0740D907FD4F07499907FD5F0020B20907FEAE0700B7511FF75120D7513DC801B907FEAE0B4010B7511FF75120D7513E080097511FF75120D19 +:4009C6007513F0AA12A913AE02EE907FD4F0AF01EF907FD5F0020B20907F00E515F0907FB57401F0020B20907FEAE0F515020B20120CB1907FEAE0F514020B20907F00E5BF +:400A060014F0907FB57401F0020B20907FE8E0247F602714603424026003020B19A217E433FF25E0FFA219E4334F907F00F0E4A3F0907FB57402F0020B20E4907F00F0A3B7 +:400A4600F0907FB57402F0020B20907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B20907FE8E024FE601726 +:400A860024026003020B20907FEAE064016003020B19C217020B20907FEAE07076907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480D6 +:400AC600FF131313541FFFE054072F907FD7F0E04420F08045907FE8E024FE601024027039907FEAE06401702AD217802D907FEAE07020907FECE0F45480FFC4540FFFE056 +:400B060054072F25E024B4F582E4347FF5837401F08007907FB4E04401F0907FB4E04402F022C210E4F514F534C209C20CC20BC214C20DC216C211C207C212C20FC208F538 +:400B460035F539F553F53AF533F530F52FF52EF52DF52CF52BF52AF529F528F527F526F525F524C205C218C21AC217C219C215C204D213C206C201907F92E054FDF0D2E820 +:400B860043D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440FF0907FAC740EF0D2AFD2BCD21B120F5FC21830040316 +:400BC60012056D30042A300627C206E51660161516907FD8E030E6047F0080027F20907F96EFF08006907F967420F0120C0B80CD301807C21812091580C3301AC0C21A128E +:400C06000FBB80B922E53160021531E53960556535704BE533F460020533E533C395444043C2AF30021B907FB8E020E12D907FB7E539F0C202E4F539F533F5357516FF802D +:400C460019907FB6E020E112907FB9E539F0D202E4F539F533F5357516FFD2AF8006853935E4F533E52C6030200F07907F9BE030E00FE52D6006E4F52D433401E4F5308000 +:400C860014E530D39545500DE530B54506752D014334010530C20F22907FD9E030E2047F0080027F20907F96EFF022E4907F93F0907F9C7430F0907F967420F0907F94748A +:400CC60001F0907F9D74BFF0907F977486F0907F957403F0907F9E7484F0907F98F0E4907FC7F0907FC9F0907FCBF075984043A810907FDE741FF0907FDF740FF0D204221A +:400D0600BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193EB +:400D4600F5828883E4737402936860EFA3A3A380DFC0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E03200000000007B +:400D86000012011001FF000040CD060C010100010200020902430001010080320904000007FF00000007050102400000070502024000000705030240000007058102400010 +:400DC600010705820240000107058302400001070584024000010403090410034B00650079007300700061006E000E03530065007200690061006C000000020EA200020E41 +:400E06007B00020D5700020EC900020E1000020E1400020E1800020E1C00020EF000020E2400020F1500020E2C00020F3AE4907F95F0907F94F0907F93F0907F9DE044020A +:400E4600F0907F97E04402F0907F9C7410F0E4907F96F0907F9D74FEF03017047F8080027F00907F97EFF0E4907F95F0907F9EF0907F98F022C0E0C083C082C085C084C00E +:400E8600867586005391EF907FAB7402F0D206D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7401F0D086D084D085D082D083EB +:400EC600D0E032C0E0C083C082C085C084C086758600D21A5391EF907FAB7408F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA974C2 +:400F060002F0D086D084D085D082D083D0E032C0E0C083C082C085C084C0867586005391EF907FA97404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086D7 +:400F46007586005391EF907FA97408F0D086D084D085D082D083D0E032907FD6E054FBF0E04408F0301B04E04402F07FF47E01120003907FD6E054F7F0E04404F0227400B9 +:400F8600F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022907FD6E04401F07F0D7E00120003907FD6E054FEF022120E33120F95907FD6E030FA +:090FC600E703120FA5120CB12281 +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19qw.HEX b/firmware/keyspan/usa19qw.HEX new file mode 100644 index 0000000..8a89102 --- /dev/null +++ b/firmware/keyspan/usa19qw.HEX @@ -0,0 +1,142 @@ +:0300330002002D9B +:04002D0053D8EF3283 +:10004600301019120E0FEFC3951440030200DF9013 +:100056007FBF7401F0C210C20B0200DF300D3E906C +:100066007FC6E020E173120E0FEFC39440506A90F2 +:100076007E40E0139210907FC7E014F536200B11F6 +:10008600600FF5247E7E7F4175297E752A4112090F +:1000960010C20DE4907FC7F07526FF803C907FC8A4 +:1000A600E020E135120E0FEFC39440502C907DC036 +:1000B600E0139210907FC9E014F536200B11600F03 +:1000C600F5247E7D7FC175297D752AC1120910D25E +:1000D6000DE4907FC9F07526FF907FB6E030E1030E +:1000E600020168120CFF8F36120E1B8F11E536C304 +:1000F6009513500F120DDEEF30E008E51120E703EF +:0C003600907F987410F090C000E0FF2252 +:03004300020E00AA +:10000300C0E0C083C082C085C084C086758600906E +:100013007FC4E4F05391EF907FAB7404F0D086D0AB +:0A00230084D085D082D083D0E03273 +:030000000209C52D +:4001060030135FC213E5366059B48003431102E51130E724E536D3942040037536208536247E7E7F8075297E752A80120B9AE53625E0907FB7F0802AE536D3943F4003753B +:40014600363F853624907E80E511F07E7E7F8175297E752A81120935E53604907FB7F07526FF907FCEE030E106200E030203C4E4F53574402535F582E4347CF583E0FFE589 +:40018600357C007B017A7E79002400F9EC347EFAEF120A970535E535B420D7907E00E0606E7F01907E11E0FD120CDA907E01E0FF120C1C907E02E0FF120C42D211D2127562 +:4001C6003604907E03E06005C2124336C0907E04E0B40107C21243360B8010907E04E06007C21143360980034336027F03AD36120CDA431A80907F987414F090C000E51A72 +:40020600F0907F987412F0E517440690C000F0907E05E06012A3E0543FF519907F987413F090C000E519F0907E07E06042907E13E0600543160480035316FBE4FFAD161247 +:400246000CDA907E08E06005431880800353187F5318FC907E09E06011431802A3E0FF120C8E907E0BE0FF120CB4AF18120C68907E0EE06018A3E06005431A018003531AD4 +:40028600FE907F987414F090C000E51AF0907E0CE06018A3E06005431A028003531AFD907F987414F090C000E51AF0907E12E0F513A3E0139214A3E0F514A3E06005431AC3 +:4002C600108003531AEF907F987414F090C000E51AF0907E16E060325319BF907F987413F0E519547F90C000F0907F987411F0120DD2EF54FE90C000F05316FDE4FFAD1621 +:40030600120CDAE4F50EF50DD20F907E17E0600F431602E4FFAD16120CDA750D01D20F907E18E06010907F987412F0E517440490C000F0D20B907E19E06011431940907F0D +:40034600987413F0E519547F90C000F0907E1AE0600F5316FEE4FFAD16120CDA750F01D20F907E1BE0600F431601E4FFAD16120CDAE4F50FD20F907E1CE0600E907F9874A9 +:4003860012F0E517440290C000F0907E1DE06002D213907E1EE06008751001E4F512D20F907E1FE06011907FD77411F07431F07415F07435F0D20DC20EE4907FCFF0301674 +:4003C60071E51260021512E530D3940040041530806075300A120DD2EF5401F536650E600785360ED20F8011120E27EF5410F53665096005853609D20F120E27EF5480F5C1 +:4004060036650A600585360AD20F120E27EF5420F536650B600885360B301102D20F120E27EF5440F536650C600885360C301202D20F30162A907FD2E020E123907B40E035 +:400446006009E0F532907B42E0F533907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020529E5277040300F39E5127035C20FF5357E007B0074082535DB +:40048600F9EE3400FA120A51FF74802535F582E4347BF583EFF00535E535B409DB907FC37409F0751210E4F51075270222E5276402703630052FC205F5357E007B00742B96 +:4004C6002535F9EE3400FA120A51FF74802535F582E4347BF583EFF00535E535B405DB907FC37405F075270322E53260337531031532E4F5357E007B0074312535F9EE34CD +:4005060000FA120A51FF74802535F582E4347BF583EFF00535E535B403DB907FC37403F0E4F52722907FE9E0120AA9060800067C0106E903054D0605F90805ED0905D50A02 +:4005460005E40B00000739907FEBE024FE60161460502402706F7419907FD4F07400907FD5F0020740907FEAE070047F0280027F03758282758319EFF0758274758319F06E +:40058600758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020740907FEAE0FF120B1CEA49600DEA907FD4F0E9907FD5F0020740907FB4E0449B +:4005C60001F0020740907FB4E04401F0020740907F00E525F0907FB57401F0020740907FEAE0F525020740120748907FEAE0F523020740907F00E523F0907FB57401F00216 +:400606000740907FE8E0247F60241460312402705BA201E433FF25E0FFA207E4334F907F00F0E4A3F0907FB57402F0020740E4907F00F0A3F0907FB57402F0020740907F2C +:40064600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020740907FB4E04401F0020740907FE8E024FE601E240216 +:400686006003020740907FEAE0B40106120DF9020740907FB4E04401F0020740907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F090F8 +:4006C6007FECE05480FF131313541FFFE054072F907FD7F0E04420F08060907FB4E04401F08057907FE8E024FE60192402704B907FEAE0B40105120DF6803F907FB4E04487 +:4007060001F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F9 +:40074600F022E4907F93F0907F9C7430F0907F967420F0907F9574C0F0907F9E743FF0907F987410F0E4F58E907FDF74FFF0907FDEF0E4F5087F017B0074082FF9E4340023 +:40078600FAE4120A970FBF09EE751301E4F512F530F511C20FC213C20EC20BC210C204907F987413F075190390C0007403F07F0CE4FD120CDA7F108F18120C68907F9874C2 +:4007C60012F07F018F17EF440690C000F00FE4FD120CDAE4FF7EA3AD068D16120CDA907F987411F090C000E4F07F057D7F120CDA7F01120D6A7F037D07120CDAE4FFE5167B +:40080600547FFD120CDA120E0F8F15E4FFE5164480FD120CDAE51530E704C2088002D208907F987414F0751A8090C0007480F0D20322D215907F92E04402F0120DF9D2E87C +:4008460043D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAE740DF0D2AFD216120D24C202E4F528F530C209F523C20390F7 +:400886007FA104F0907FD8E065346048300305D216120046E50F6022E52660161526907FD8E030E6047F2080027F30907F96EFF0801A907F967430F08012907FD9E030E2F8 +:4008C600047F3080027F20907F96EFF0907FD8E0F5348020300307C2161200468016E50F7012907FD9E030E2047F3080027F20907F96EFF0300207C20212052A8086300AE4 +:4009060083C20A120B5D02088A22907F987410F0AF24E52AF582E529F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF24E52AF582E529F583C2A3 +:40094600AF058690C000E00586F0A30586DFF70586D2AF22907F987408F0AF24E52AF582E529F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AFCD +:4009860024E52AF582E529F583C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022784B +:4009C6007FE4F6D8FD758139020A0C020838E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B010211 +:400A0600040810204080900D8BE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582B0 +:400A4600C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E925BB +:400A860082F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E47374028F +:400AC600936860EFA3A3A380DFE4907F93F0907F9C7420F0300103FF80027F00907F96EFF0E4907F94F0907F9D74FFF0E4907F97F0300811907F95F0907F9E74FFF0907F05 +:400B0600987420F022E4907F95F0907F9E74DFF0E4907F98F0228F35E4F5367537FF753819753986AB37AA38A939900001120A6AB4031DAF360536EFB5350122120A517E5C +:400B46000029FFEE3AA9077537FFF538893980D47B007A00790022907FD8E0F535120ACF200807907F92E054FDF0907FD6E04480F01209B5907FD6E030E70E300105120D9C +:400B8600BC8006120D49EF60E1907F92E04402F012074822052AE52AAE297002052914F5828E83E511F0120036052AE52AAC297002052914F5828C83EFF01524E5246007C7 +:400BC600120E1B8F1180CD22C0E0C083C082C085C084C086758600D2025391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D20A9F +:400C06005391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E519547F90C000F022907F9874E8 +:400C460013F090C00074BFF0907F987411F090C000EFF0907F987413F0E519547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E57C +:400C860019547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E519547F90C000F022907F987413F090C00074BFF0907F987416F0FE +:400CC60090C000EFF0907F987413F0E519547F90C000F022907F987413F0E519547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF022120DEA8F37120D91 +:400D0600EA8F38E53765386012120DEA8F37E53765386007120DEA8F3880E8AF3722907FD6E054FBF0E04408F0301604E04402F07FF47E01120DA5907FD6E054F7F0E04448 +:400D460004F022907FD8E0F536120748120E27EF30E60B907FD8E0653660F17F0122120ACF7F0022AE07E4FFE516547FFD120CDA907F987411F090C000EEF0E4E516448084 +:400D8600FD120CDA22052B02000000000331030000C186C102C10AC101C107012700008E368F37E5371537AE36700215364E60051209A480EE22907FD6E04401F07F0D7E8D +:400DC60000120DA5907FD6E054FEF022907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22D20122C2012200000000020BCE00020EF1 +:400E0600040002000300020BF5907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22000000000000000000000000000000000000004E +:400E4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C +:400E8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C +:400EC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC +:400F060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB +:400F4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B +:400F8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B +:400FC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB +:4010060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA +:40104600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A +:40108600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A +:4010C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA +:4011060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9 +:401146000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069 +:401186000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029 +:4011C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9 +:4012060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8 +:401246000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068 +:401286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028 +:4012C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8 +:4013060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7 +:401346000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067 +:401386000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027 +:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 +:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 +:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 +:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 +:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 +:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 +:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 +:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 +:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 +:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 +:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 +:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 +:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 +:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 +:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 +:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 +:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 +:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 +:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF +:401906000040CD06190100000102000209027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240006D +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:041A0600720000006A +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa19w.HEX b/firmware/keyspan/usa19w.HEX new file mode 100644 index 0000000..a3b8431 --- /dev/null +++ b/firmware/keyspan/usa19w.HEX @@ -0,0 +1,141 @@ +:03003300020D5C5F +:10000300E4907F93F0907F9C7430F0E4907F96F0BF +:10001300907F94F0907F9D74FFF0E4907F97F09031 +:0F0023007F95F0907F9E7417F0E4907F98F02205 +:10004600300F18120D38EFC3951440030200D890F4 +:100056007FBF7401F0C20FC20A8077300C3B907FDD +:10006600C6E020E16D120D38EFC394405064907ED7 +:1000760040E013920F907FC7E014F51C200A116030 +:100086000FF5237E7E7F4175277E75284112080174 +:10009600C20CE4907FC7F08039907FC8E020E1323F +:1000A600120D38EFC394405029907DC0E013920F93 +:1000B600907FC9E014F51C200A11600FF5237E7DA0 +:1000C6007FC175277D7528C1120801D20CE4907F87 +:1000D600C9F0907FB6E030E10302015E120C418F59 +:1000E6001C120D448F11E51CC39513500F120D20E1 +:1000F600EF30E008E51120E70330125CC212E51C80 +:0C003600907F987410F090C000E0FF2252 +:03004300020E00AA +:030000000208B63D +:400106006056B48003431102E51130E724E51CD394204003751C20851C237E7E7F8075277E752880120A86E51C251C907FB7F08027E51CD3943F4003751C3F851C23907E06 +:4001460080E511F07E7E7F8175277E752881120826E51C04907FB7F0907FCEE030E106200D030203BAE4F51B7440251BF582E4347CF583E0FFE51B7C007B017A7E7900244A +:4001860000F9EC347EFAEF120A0D051BE51BB420D7907E00E0606E7F01907E11E0FD120C1C907E01E0FF120B5E907E02E0FF120B84D210D211751C04907E03E06005C211D7 +:4001C600431CC0907E04E0B40107C211431C0B8010907E04E06007C210431C098003431C027F03AD1C120C1C431980907F987414F090C000E519F0907F987412F0E51644CE +:400206000690C000F0907E05E06012A3E0543FF518907F987413F090C000E518F0907E07E06042907E13E0600543150480035315FBE4FFAD15120C1C907E08E060054317BC +:4002460080800353177F5317FC907E09E06011431702A3E0FF120BD0907E0BE0FF120BF6AF17120BAA907E0EE06018A3E0600543190180035319FE907F987414F090C00046 +:40028600E519F0907E0CE06018A3E0600543190280035319FD907F987414F090C000E519F0907E12E0F513A3E0139213A3E0F514A3E0600543191080035319EF907F98742D +:4002C60014F090C000E519F0907E16E060325318BF907F987413F0E518547F90C000F0907F987411F0120D14EF54FE90C000F05315FDE4FFAD15120C1CE4F50EF50DD20EEB +:40030600907E17E0600F431502E4FFAD15120C1C750D01D20E907E18E06010907F987412F0E516440490C000F0D20A907E19E06011431840907F987413F0E518547F90C064 +:4003460000F0907E1AE0600F5315FEE4FFAD15120C1C750F01D20E907E1BE0600F431501E4FFAD15120C1CE4F50FD20E907E1CE0600E907F987412F0E516440290C000F0D8 +:40038600907E1DE06002D212907E1EE06008751001E4F512D20E907E1FE06011907FD77411F07431F07415F07435F0D20CC20DE4907FCFF0301571E51260021512E52ED326 +:4003C60094004004152E8060752E0A120D14EF5401F51C650E6007851C0ED20E8011120D50EF5410F51C65096005851C09D20E120D50EF5480F51C650A6005851C0AD20EFB +:40040600120D50EF5420F51C650B6008851C0B301002D20E120D50EF5440F51C650C6008851C0C301102D20E30152A907FD2E020E123907B40E06009E0F530907B42E0F572 +:4004460031907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E10302051FE5257040300E39E5127035C20EF51B7E007B007408251BF9EE3400FA1209C7FF7447 +:4004860080251BF582E4347BF583EFF0051BE51BB409DB907FC37409F0751210E4F51075250222E5256402703630052FC205F51B7E007B007429251BF9EE3400FA1209C7C2 +:4004C600FF7480251BF582E4347BF583EFF0051BE51BB405DB907FC37405F075250322E5306033752F031530E4F51B7E007B00742F251BF9EE3400FA1209C7FF7480251B26 +:40050600F582E4347BF583EFF0051BE51BB403DB907FC37403F0E4F52522907FE9E0120A1F05F600066A0106D70305430605E90805E30905CB0A05DA0B00000727907FEBC9 +:40054600E024FE60161460502402706F7419907FD4F07400907FD5F002072E907FEAE070047F0280027F03758282758319EFF0758274758319F0758258758319F0907FEA65 +:40058600E004758217758319F07419907FD4F07412907FD5F002072E907FEAE0FF120A45EA49600DEA907FD4F0E9907FD5F002072E907FB4E04401F002072E907FB4E044D1 +:4005C60001F002072E907F00E524F0907FB57401F002072E907FEAE0F52402072E12073602072E907F007401F0907FB5F002072E907FE8E0247F60241460312402705BA221 +:4006060001E433FF25E0FFA207E4334F907F00F0E4A3F0907FB57402F002072EE4907F00F0A3F0907FB57402F002072E907FECE0F45480FFC4540FFFE054072F25E024B4CD +:40064600F582E4347FF583E054FD907F00F0E4A3F0907FB57402F002072E907FB4E04401F002072E907FE8E024FE601E2402600302072E907FEAE0B40106120D6302072E53 +:40068600907FB4E04401F002072E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF131313541FFFE054072F907F69 +:4006C600D7F0E04420F08060907FB4E04401F08057907FE8E024FE60192402704B907FEAE0B40105120D60803F907FB4E04401F08036907FEAE07020907FECE0F45480FFAD +:40070600C4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022E4907F93F0907F9C7430F0E4907F96F06B +:40074600907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5087F017B0074082FF9E43400FAE4120A0D0FBF09EE751301E4F512F52EF511A2 +:40078600C20EC212C20DC20AC20FC204907F987413F075180390C0007403F07F0CE4FD120C1C7F108F17120BAA907F987412F07F018F16EF440690C000F00FE4FD120C1C71 +:4007C600E4FF7EA3AD068D15120C1C907F987411F090C000E4F07F057D7F120C1C7F01120CAC7F037D07120C1C907F987414F075198090C0007480F0D20322907F98741059 +:40080600F0AF23E528F582E527F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF23E528F582E527F583C2AF058690C000E00586F0A30586DFF76F +:400846000586D2AF22907F987408F0AF23E528F582E527F583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF23E528F582E527F583C2AF058690C045 +:4008860000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022787FE4F6D8FD7581310208FD020942E43B +:4008C60093A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B0102040810204080900CCDE47E019360BC36 +:40090600A3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BED214907F83 +:4009460092E04402F0120D63D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAE740DF0D2AFD215120C66C202E4F557 +:4009860026F52EC208C203907FA104F0907FD8E0651A6010300305D215120046907FD8E0F51A8008300305C215120046300207C20212052080D63009D3C209120ABA80CC40 +:4009C60022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E51F +:400A0600833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF8F58 +:400A46001BE4F51C751DFF751E19751F86AB1DAA1EA91F9000011209E0B4031DAF1C051CEFB51B01221209C77E0029FFEE3AA907751DFFF51E891F80D47B007A00790022F3 +:400A86000528E528AE277002052714F5828E83E511F01200360528E528AC277002052714F5828C83EFF01523E5236007120D448F1180CD22907FD8E0F51B120003907FD6AB +:400AC600E04480F01208A6907FD6E030E70E300105120CFE8006120C8BEF60E112073622C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D0DF +:400B060084D085D082D083D0E032C0E0C083C082C085C084C086758600D2025391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C08675860025 +:400B4600D2095391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E518547F90C000F022907FDB +:400B8600987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E518547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F98741307 +:400BC600F0E518547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E518547F90C000F022907F987413F090C00074BFF0907F9874F2 +:400C060016F090C000EFF0907F987413F0E518547F90C000F022907F987413F0E518547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF022120D2C8F1D44 +:400C4600120D2C8F1EE51D651E6012120D2C8F1DE51D651E6007120D2C8F1E80E8AF1D22907FD6E054FBF0E04408F0301504E04402F07FF47E01120CE7907FD6E054F7F0D8 +:400C8600E04404F022907FD8E0F51C120736120D50EF30E60B907FD8E0651C60F17F01221200037F0022AE07E4FFE515547FFD120C1C907F987411F090C000EEF0E4E51599 +:400CC6004480FD120C1C2205290200000000032F030000C186C102C109C101C107012500008E1C8F1DE51D151DAE1C7002151C4E600512089580EE22907FD6E04401F07F86 +:400D06000D7E00120CE7907FD6E054FEF022907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F2B +:400D4600987415F090C000E0FF22907F987416F090C000E0FF2253D8EF32D20122C20122000000000000000000000000000000000000000000000000000000000000000073 +:400D8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D +:400DC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020B1000020EC0 +:400E06000400020AE600020B370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072 +:400E4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C +:400E8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002C +:400EC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC +:400F060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AB +:400F4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006B +:400F8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002B +:400FC60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EB +:4010060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA +:40104600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006A +:40108600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002A +:4010C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EA +:4011060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A9 +:401146000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069 +:401186000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029 +:4011C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E9 +:4012060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A8 +:401246000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068 +:401286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028 +:4012C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E8 +:4013060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A7 +:401346000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067 +:401386000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027 +:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 +:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 +:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 +:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 +:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 +:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 +:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 +:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 +:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 +:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 +:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 +:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 +:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 +:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 +:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 +:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 +:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 +:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 +:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF +:401906000040CD06080100000102000209027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240007E +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:041A0600720000006A +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28.HEX b/firmware/keyspan/usa28.HEX new file mode 100644 index 0000000..000c978 --- /dev/null +++ b/firmware/keyspan/usa28.HEX @@ -0,0 +1,148 @@ +:0A0026001217DB1218B51214C322E2 +:0300330002001DAB +:04001D0053D8EF3293 +:100006008E128F13E5131513AE12700215124E6081 +:07001600051218A480EE2280 +:03000300020046B2 +:10004600C0E0C083C082C086758600C0D075D00867 +:1000560030990E301107A217929B854699C299D204 +:100066001F30C10E301207A21892C38547C1C2C104 +:10007600D220201F03020442C21F2003030202678C +:10008600201103020138E54AC3957C503E20133601 +:10009600200B33907F9BE020E303201C29301B12AA +:1000A600AE4A054A74402EF582E4347EF583E013A9 +:1000B6009217AE4A054A74402EF582E4347EF583E3 +:1000C600E0F546020440C211020440907FC7E4F006 +:1000D600C20330150CC215907FBF04F0C211020492 +:1000E60040907FC8E030E105C211020440907FC90C +:1000F600E0F57C907DC0E013921520132D200B2A8D +:03004300021B009D +:0300230002004692 +:03003B000200467A +:0300000002163DA8 +:40010600907F9BE020E303201C20301B11907DC1E0139217A3E0F546754A03020440754A02907DC1E0F546020440754A01C211020440E54AC3957C50030201E0907FC6E08A +:4001460030E107C221C205020440907FC7E0F57C907E40E01392153013030201D8200B7220006F907F9BE020E303201C65301B10907E41E013929BA3E0F599754A038009BE +:40018600907E41E0F599754A02E54AC3957C4017907FC7E4F0C203201503020440C215907FBF04F0020440301B12AE4A054A74402EF582E4347EF583E0139217AE4A054AA7 +:4001C60074402EF582E4347EF583E0F546D211020440754A01C221020440301303020262200B79907F9BE020E303201C6F301B12AE4A054A74402EF582E4347EF583E013DC +:40020600929BAE4A054A74402EF582E4347EF583E0F599E54AC3957C4017907FC7E4F0C203201503020440C215907FBF04F0020440301B12AE4A054A74402EF582E4347EB6 +:40024600F583E0139217AE4A054A74402EF582E4347EF583E0F546D211020440C221020440201103020319E54AC3957C503E201336200B33907F9BE020E303201C29301B5F +:4002860012AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546020440C211020440907FC9E4F0D20330150CC215907FBF04F0C2110276 +:4002C6000440907FC6E030E105C211020440907FC7E0F57C907E40E013921520132D200B2A907F9BE020E303201C20301B11907E41E0139217A3E0F546754A03020440759E +:400306004A02907E41E0F546020440754A01C211020440E54AC3957C50030203C1907FC8E030E107C221C205020440907FC9E0F57C907DC0E01392153013030203B9200B48 +:400346007220006F907F9BE020E303201C65301B10907DC1E013929BA3E0F599754A038009907DC1E0F599754A02E54AC3957C4017907FC9E4F0D203201503020440C21573 +:40038600907FBF04F0020440301B12AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546D211020440754A01C221020440301303020463 +:4003C6003E200B74907F9BE020E303201C6A301B12AE4A054A74C02EF582E4347DF583E013929BAE4A054A74C02EF582E4347DF583E0F599E54AC3957C4013907FC9E4F09D +:40040600D203301535C215907FBF04F0802C301B12AE4A054A74C02EF582E4347DF583E0139217AE4A054A74C02EF582E4347DF583E0F546D2118002C221D2252020030230 +:40044600080CC220200403020631201203020502E54BC3957D503E201436200D33907F9AE020E503201E29301D12AE4B054B74402EF582E4347DF583E0139218AE4B054B99 +:4004860074402EF582E4347DF583E0F54702080AC21202080A907FCBE4F0C20430160CC216907FC104F0C21202080A907FCCE030E105C21202080A907FCDE0F57D907CC0BB +:4004C600E013921620142D200D2A907F9AE020E503201E20301D11907CC1E0139218A3E0F547754B0302080A754B02907CC1E0F54702080A754B01C21202080AE54BC39566 +:400506007D50030205AA907FCAE030E107C222C20602080A907FCBE0F57D907D40E01392163014030205A2200D7220006F907F9AE020E503201E65301D10907D41E013920D +:40054600C3A3E0F5C1754B038009907D41E0F5C1754B02E54BC3957D4017907FCBE4F0C20420160302080AC216907FC104F002080A301D12AE4B054B74402EF582E4347D24 +:40058600F583E0139218AE4B054B74402EF582E4347DF583E0F547D21202080A754B01C22202080A30140302062C200D79907F9AE020E503201E6F301D12AE4B054B7440E9 +:4005C6002EF582E4347DF583E01392C3AE4B054B74402EF582E4347DF583E0F5C1E54BC3957D4017907FCBE4F0C20420160302080AC216907FC104F002080A301D12AE4B91 +:40060600054B74402EF582E4347DF583E0139218AE4B054B74402EF582E4347DF583E0F547D21202080AC22202080A2012030206E3E54BC3957D503E201436200D33907F1A +:400646009AE020E503201E29301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F54702080AC21202080A907FCDE4F0D20430160C43 +:40068600C216907FC104F0C21202080A907FCAE030E105C21202080A907FCBE0F57D907D40E013921620142D200D2A907F9AE020E503201E20301D11907D41E0139218A352 +:4006C600E0F547754B0302080A754B02907D41E0F54702080A754B01C21202080AE54BC3957D500302078B907FCCE030E107C222C20602080A907FCDE0F57D907CC0E013AC +:400706009216301403020783200D7220006F907F9AE020E503201E65301D10907CC1E01392C3A3E0F5C1754B038009907CC1E0F5C1754B02E54BC3957D4017907FCDE4F0AE +:40074600D20420160302080AC216907FC104F002080A301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F547D21202080A754B0173 +:40078600C22202080A301403020808200D74907F9AE020E503201E6A301D12AE4B054B74C02EF582E4347CF583E01392C3AE4B054B74C02EF582E4347CF583E0F5C1E54B3F +:4007C600C3957D4013907FCDE4F0D204301635C216907FC104F0802C301D12AE4B054B74C02EF582E4347CF583E0139218AE4B054B74C02EF582E4347CF583E0F547D2122A +:400806008002C222D22520980302093EC2982001030208B0202327AE48054874802EF582E4347EF583E599F0301B49AE48054874802EF582E4347EF583E598F08036AF996E +:40084600EFB55804D20B802CEFB55704C20B8024AE48054874802EF582E4347EF583EFF0301B11AE48054874802EF582E4347EF583E598F0D219E548C39554500302093C9F +:40088600907FB8E030E115E548C39440500302093C15481548052DD20C02093C907FB7E548F0754800C20102093C202327AE48054874002EF582E4347EF583E599F0301BBF +:4008C60049AE48054874002EF582E4347EF583E598F08036AF99EFB55804D20B802CEFB55704C20B8024AE48054874002EF582E4347EF583EFF0301B11AE48054874002E51 +:40090600F582E4347EF583E598F0D219E548C395544023907FB6E030E111E548C39440401515481548052DD20C800B907FB9E548F0754800D201D22520C003020A70C2C016 +:400946002002030209E2202427AE49054974802EF582E4347DF583E5C1F0301D49AE49054974802EF582E4347DF583E5C0F08036AFC1EFB57004D20D802CEFB56F04C20DAE +:400986008024AE49054974802EF582E4347DF583EFF0301D11AE49054974802EF582E4347DF583E5C0F0D21AE549C3956C5003020A6E907FBCE030E115E549C39440500351 +:4009C600020A6E154915490539D20E020A6E907FBBE549F0754900C202020A6E202427AE49054974002EF582E4347DF583E5C1F0301D49AE49054974002EF582E4347DF555 +:400A060083E5C0F08036AFC1EFB57004D20D802CEFB56F04C20D8024AE49054974002EF582E4347DF583EFF0301D11AE49054974002EF582E4347DF583E5C0F0D21AE54983 +:400A4600C3956C4023907FBAE030E111E549C394404015154915490539D20E800B907FBDE549F0754900D202D225302505C225020056D0D0D086D082D083D0E032907FCE99 +:400A8600E030E103020BA5E4F51274402512F582E4347CF583E0FFE5127C007B00244CF9EC3400FAEF1215CD0512E512B418DBE54C600C75C92075C836854DCA854ECBE5BC +:400AC6004F13921B929FE55013921CE551139223E5526009907F98E054FBF08007907F98E04404F0E5536009907F98E0547FF08007907F98E04480F0E559600BC213C20B18 +:400B0600907F95E04402F0E55A600BD20BD20C907F95E04402F0E55B600DC2AFC211D200E4F57CF54AD2AFE55C6005302302D20BE55D6015907F95E054FDF0907F9EE044D9 +:400B460002F0907F98E054FDF0E55E600AD29CC298752E01754028E55F6007C29CE4F548F52EE5606003E4F548E5616002D207E5626008E55E7002F540D20CE56360199060 +:400B86007FD77411F07431F07412F07432F07415F07435F0D203D201D209E4907FCFF0A213E433FF652B60048F2BD20CA20BE433FF652C60048F2CD20C907F9BE054086589 +:400BC600276007E05408F527D20C907F9BE05440B52909E054406440F529D20C300735C2AF300118907FB8E020E127E5486009907FB7F0E4F548C201C2078016907FB6E0E9 +:400C060020E10FE5486009907FB9F0E4F548D201C207D2AF20053730031B907FC6E020E12D907E40E0139215754A01907FC7E0F57CD2058019907FC8E020E112907DC0E0CF +:400C4600139215754A01907FC9E0F57CD205202133200006E54A657C702A30051A300309E4907FC7F0C2038007E4907FC9F0D203C205E4F57CF54A30150AC215C200907F5C +:400C8600BF7401F0302103020D94200503020D94301C0A907F9BE020E303020D94300B03020D94301303020D94300362301B12AF4A054A74402FF582E4347EF583E01392CE +:400CC6002DAF4A054A74402FF582E4347EF583E0F513E54AC3957C502A301B12AF4A054A74402FF582E4347EF583E0139217AF4A054A74402FF582E4347EF583E0F546D266 +:400D060011806BC211E4907FC7F0C2038060301B12AF4A054A74C02FF582E4347DF583E013922DAF4A054A74C02FF582E4347DF583E0F513E54AC3957C502A301B12AF4A67 +:400D4600054A74C02FF582E4347DF583E0139217AF4A054A74C02FF582E4347DF583E0F546D2118009C211E4907FC9F0D203301B04A22D929BD221C2AF85139920110D3043 +:400D8600150AC215C200907FBF7401F0D2AF907FD0E030E103020EB5E4F51274C02512F582E4347BF583E0FFE5127C007B002464F9EC3400FAEF1215CD0512E512B418DB51 +:400DC600E564600B758960758840D2DF85658DE56713921D92C7E56813921EE569139224E56A6009907F97E054EFF08007907F97E04410F0E56B6009907F97E0547FF080A4 +:400E060007907F97E04480F0E571600BC214C20D907F94E04408F0E572600BD20DD20E907F94E04408F0E573600DC2AFC212D200E4F57DF54BD2AFE5746005302402D20D20 +:400E4600E5756015907F94E054F7F0907F9DE04408F0907F97E054F7F0E576600AD2C4C2C0753A01754128E5776007C2C4E4F549F53AE5786003E4F549E5796002D208E5F0 +:400E86007A6008E5767002F541D20EE57B6019907FD77413F07433F07414F07434F07416F07436F0D204D202D20AE4907FD1F0A214E433FF653760048F37D20EA20DE43304 +:400EC600FF653860048F38D20E907F9AE0542065336007E05420F533D20E907F9AE05440B53509E054406440F535D20E300835C2AF300218907FBCE020E127E54960099099 +:400F06007FBBF0E4F549C202C2088016907FBAE020E10FE5496009907FBDF0E4F549D202C208D2AF20063730041B907FCAE020E12D907D40E0139216754B01907FCBE0F503 +:400F46007DD2068019907FCCE020E112907CC0E0139216754B01907FCDE0F57DD206202233200006E54B657D702A30061A300409E4907FCBF0C2048007E4907FCDF0D2042C +:400F8600C206E4F57DF54B30160AC216C200907FC17401F03022030210A42006030210A4301E0A907F9AE020E5030210A4300D030210A43014030210A4300462301D12AF8E +:400FC6004B054B74402FF582E4347DF583E013922DAF4B054B74402FF582E4347DF583E0F513E54BC3957D502A301D12AF4B054B74402FF582E4347DF583E0139218AF4B78 +:40100600054B74402FF582E4347DF583E0F547D212806BC212E4907FCBF0C2048060301D12AF4B054B74C02FF582E4347CF583E013922DAF4B054B74C02FF582E4347CF5F2 +:4010460083E0F513E54BC3957D502A301D12AF4B054B74C02FF582E4347CF583E0139218AF4B054B74C02FF582E4347CF583E0F547D2128009C212E4907FCDF0D204301DF4 +:4010860004A22D92C3D222C2AF8513C120120D30160AC216C200907FC17401F0D2AF907FC2E030E10302117AE51A7046300C3FE540703BA20933F531C209C20CE4F5127E0D +:4010C600007B0074262512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B40CDB907FC3740CF075401022751A0122E51A64017045300E3EE541703AA2C5 +:401106000A33F53DC20AC20EE4F5127E007B0074322512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B40CDB907FC3740CF0754110751A0222E51C60CA +:4011460030151CE4F5127E007B00741B2512F9EE3400FA121587FF74802512F582E4347BF583EFF00512E512B403DB907FC37403F0E4F51A22907FE9E012161712400012A7 +:40118600B401132003119E06123308122D0912200A13760B0000136F907FEBE024FE6016146040240270697419907FD4F07400907FD5F0021376907FEAE0FF12174B8B1261 +:4011C6008A138914EA496011AE02EE907FD4F0AF01EF907FD5F0021376907FB4E04401F0021376907FEAE0FF12179A8B128A138914EA496011AE02EE907FD4F0AF01EF9083 +:401206007FD5F0021376907FB4E04401F0021376907FB4E04401F0021376907F007401F0907FB5F00213761214C3021376907F007401F0907FB5F0021376907FE8E0247FBF +:4012460060241460312402705BA226E433FF25E0FFA22BE4334F907F00F0E4A3F0907FB57402F0021376E4907F00F0A3F0907FB57402F0021376907FECE0F45480FFC45429 +:401286000FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0021376907FB4E04401F0021376907FE8E024FE601D24026003021376907FEA0B +:4012C600E0B40105C226021376907FB4E04401F0021376907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF131313A7 +:40130600541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D226803F907FB4E04401F08036907FEAE07020A3 +:40134600907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F0222028030214C2E54063 +:4013860060021540E548604F65447045E542F460020542E542C39555403DC2AF300118907FB8E020E127907FB7E548F0C201E4F548F542F5448016907FB6E020E10F907F07 +:4013C600B9E548F0D201E4F548F542F544D2AF8006854844E4F542E52E602D201907907F9BE030E00EE52F6005E4F52FD20CE4F53E8013E53ED39556500CE53EB556057504 +:401406002F01D20C053EC219E54160021541E549604F65457045E543F460020543E543C3956D403DC2AF300218907FBCE020E127907FBBE549F0C202E4F549F543F54580E2 +:4014460016907FBAE020E10F907FBDE549F0D202E4F549F543F545D2AF8006854945E4F543E53A602D201A07907F9AE030E20EE53B6005E4F53BD20EE4F53F8013E53FD35E +:40148600956E500CE53FB56E05753B01D20E053FC21A907FD2E020E123907B40E06009E0F51C907B42E0F51D907B41E06009907FD77417F07437F0E4907FD3F022E4907FC5 +:4014C60093F0907F9C7430F0907F96E04410F0907F94740DF0907F9D749AF0907F97E054FDF0907F957423F0907F9E7484F0E4907FC7F0907FC9F0907FCFF075984043A89E +:4015060010C21BC205C221C20BC213F57CF54AC211C215F542C219F544F548C223C21CF52DF52FC207C200C21FF53EC209D20CF526907FCBF0907FCDF0907FD1F075C04043 +:4015460043A840C21DC206C222C20DC214F57DF54BC212C216F543C21AF545F549C224C21EF539F53BC208C200C220F53FC20AD20E753201907FDF74FFF0907FDEF0D228DE +:4015860022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E553 +:4015C600833AF583E49322BB010689828A83F0225002F722BBFE01F322BB0110E58229F582E5833AF583E0F5F0A3E0225009E92582F886F008E622BBFE0AE92582F8E2F511 +:40160600F008E222E5832AF583E993F5F0A3E99322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF787FE4F6D8FD75817D0E +:401646000216840216C9E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B010204081020408090181A +:40168600C5E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DE39 +:4016C600E780BE751101907F92E054FDF0907FAEE0FFD39226E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE044C5 +:4017060001F0907FAEE0440DF0D2AFD2BCD2BED22D12187FC227C225C228302803120A83907FD8E065106008E0F51012137E80EA302707C22712117B80E0302CDDC22C12C5 +:40174600002680D622E4FE7517FF751819751912AB17AA18A9199000011215A06402702DAD060EEDB50701229000021215DF85F015F5166215E5156216E516621529FDE551 +:40178600153AA9057517FFF518891980C37B007A007900228F15E4F5167517FF751819751986AB17AA18A9199000011215A0B4031DAF160516EFB51501221215877E0029BE +:4017C600FFEE3AA9077517FFF518891980D47B007A00790022E4907F93F0907F9CF0907F94F0907F9D7402F0907F97F0E4907F95F0907F9E74FFF0E4907F98F0907F9DF003 +:4018060022C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2275391EF9024 +:401846007FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D22C5391EF907FAB7408F0D086D084D085D082D083D0E032907FD6E054FBF0DD +:40188600E04408F0302D04E04402F07FF47E01120006907FD6E054F7F0E04404F0227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022C125 +:4018C600AA011A00031B030000C127C12CC126C12B000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF0031 +:401906000040CD060F0100000102000109027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400078 +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:401A0600720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E +:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060 +:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020 +:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002183100021B78 +:091B06000400021807000218583F +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28x.HEX b/firmware/keyspan/usa28x.HEX new file mode 100644 index 0000000..9f0f7fa --- /dev/null +++ b/firmware/keyspan/usa28x.HEX @@ -0,0 +1,141 @@ +:030033000212F7BF +:10000300E4907F93F0907F9C7430F0E4907F96F0BF +:10001300907F94F0907F9D74FFF0E4907F97F09031 +:0F0023007F95F0907F9E7407F0E4907F98F02215 +:1000460030091812131BEFC3953C40030200D890E9 +:100056007FBF7401F0C209C200807730033B907FF6 +:10006600C6E020E16D12131BEFC394405064907EEE +:1000760040E0139209907FC7E014F5192000116043 +:100086000FF5087E7E7F41750C7E750D41120CBA08 +:10009600C203E4907FC7F08039907FC8E020E13248 +:1000A60012131BEFC394405029907DC0E0139209B0 +:1000B600907FC9E014F519200011600FF5087E7DC8 +:1000C6007FC1750C7D750DC1120CBAD203E4907F09 +:1000D600C9F0907FB6E030E1030201601211D68FBD +:1000E600191213278F36E519C3953A500F1212EBE2 +:1000F600EF30E008E53620E703300B5EC20BE5196A +:0C003600907F987410F090C000E0FF2252 +:03004300021300A5 +:03000000020E00ED +:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F4BE51925E0907FB7F08027E519D3943F400375193F851908D4 +:40014600907E80E536F07E7E7F81750C7E750D81120CDFE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AF1 +:400186007E79002400F9EC347EFAEF120ED20518E518B420D7907E00E06068907E03E060247F01E4FD1211B17F037DCD1211B1434680907F987414F090C000E546F0E490E0 +:4001C6007E13F08030907E01E0FF121035907E02E0FF12105B7F01907E11E0FD1211B17F037D071211B1434680907F987414F090C000E546F0907F987412F0E5404406903E +:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA +:400246007F5342FC907E09E06011434202A3E0FF1210A7907E0BE0FF1210CDAF42121081907E03E0600853427FAF42121081907E0CE06018A3E0600543460280035346FDB4 +:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B +:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212DFEF54FE90C000F0533EFDE4FFAD3E120F +:4003060011B1E4F52AF529D207907E17E0600F433E02E4FFAD3E1211B1752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98F2 +:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211B1752B01D207907E1BE0600F433E01E4FFAD3E1211B1E4F52BD207907E1CE0600E907F98741284 +:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892 +:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212DFEF5401F519652A600585192AD207121333EF5480F51965266005851926D207300D11127F +:400406001333EF5410F51965256005851925D207201B030207EC300A1812136FEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12136FEFC35A +:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D04C204E4907FCBF08039907FCCE020E13212136FEFC39440502990BC +:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D04D204E4907FCDF0907FBAE030E1030205361212208F1912137B8F37E519C3952B +:4004C6003B500F121357EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F84E503 +:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D29E51904907FBBF0907FD0E030E106200603020797C206E4F8 +:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120ED20518E518B420D7907E20E06068907E23E060247F01E4FD1211FB7F0329 +:400586007DCD1211FB434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121119907E22E0FF12113F7F01907E31E0FD1211FB7F037D071211FB4347809048 +:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB +:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121165907E2BE0FF12118BAF431210F3907E23E0600853437FAFFE +:40064600431210F3907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0D4 +:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 +:4006C600987409F012134BEF54FE90C000F0533FFDE4FFAD3F1211FBE4F533F532D208907E37E0600F433F02E4FFAD3F1211FB753201D208907E38E06010907F98740AF043 +:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F1211FB753401D208907E3BE0600F433F01E4E9 +:40074600FFAD3F1211FBE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741389 +:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C21312134BEF5401F51965336005851933D279 +:4007C60008121387EF5480F519652F600585192FD208300E11121387EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F5169035 +:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E8CFF748025BD +:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297 +:400886000E8CFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340083 +:4008C600FA120E8CFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E8CFF748025F2 +:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EE40A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F3D +:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2 +:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F0AEA49600DEA907FD4F0E9907FD5F085 +:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205 +:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04 +:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F +:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6 +:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049 +:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4 +:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B +:400B8600E4120ED20518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211B17F108F42121081907F02 +:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211B1E4FF7EA3AD068D3E1211B1907F987411F090C000E4F07F057D7F12118E +:400C0600B17F0112126A7F037D071211B1201B03020CB7752D017518017B00742D2518F9E43400FAE4120ED20518E518B409EA753B01E4F539F513F537C208C20CC206C2CD +:400C460000C20AC213907F98740BF075450390C0007403F07F0CE4FD1211FB7F108F431210F3907F98740AF07F018F41EF440690C000F0907F98740CF075478090C000744E +:400C860080F00FE4FD1211FBE4FF7EA3AD068D3F1211FB907F987409F090C000E4F07F057D7F1211FB7F0112128B7F037D071211FBD21222907F987410F0AF08E50DF582A5 +:400CC600E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF22907F20 +:400D0600987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C000E00586F0A3055C +:400D460086DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F0907FAEE0FFD39210E433FEEF4EF089 +:400D8600D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A121245C211E4F50BF513C217C212D4 +:400DC600907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D3C21812139380CC22787FE4F6D8FDC7 +:400E0600758147020E47020D6FE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F456800146F6DFE4800B01020408102040F5 +:400E4600809012ACE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CA1E +:400E8600DFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E5B8 +:400EC6008229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3C1 +:400F0600A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EA5B4031DAF190519EFB5180122120E8C7E0029FFEE3AA907751AFFF51B891C80D47B00A5 +:400F46007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213278F1AEF423680CA228F1AFC +:400F8600050DE50DAE0C7002050C14F5828E83E51AF012133F050DE50DAC0C7002050C14F5828C83EFF01508E508600A12137B8F1AEF423780CA22C0E0C083C082C085C088 +:400FC60084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D0C6 +:4010060085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F9874108A +:40104600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0E544547F90C000F022907F98741349 +:40108600F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544D9 +:4010C600547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF0902A +:40110600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090AF +:40114600C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547FEC +:4011860090C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F09075 +:4011C600C000EFF0907F987415F090C000EDF02212130F8F1A12130F8F1BE51A651B601212130F8F1AE51A651B600712130F8F1B80E8AF1A22907F98740BF0E545547F9098 +:40120600C000F0907F98740FF090C000EFF0907F98740DF090C000EDF0221213638F1A1213638F1BE51A651B60121213638F1AE51A651B60071213638F1B80E8AF1A2290C8 +:401246007FD6E054FBF0E04408F0301A04E04402F07FF47E011212C8907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211B1907F987411F090C000EEF0E4E53E4480E8 +:40128600FD1211B122AE07E4FFE53F547FFD1211FB907F987409F090C000EEF0E4E53F4480FD1211FB22050E02000000000314030000C111C118C195C110C116010A00C19C +:4012C6009B008E188F19E5191519AE18700215184E6005120D4E80EE22907F987411F090C000E0FF22907F987412F090C000E0FF2253D8EF320000000000020FE70002138A +:401306000400020FBD0002100E907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F090C000E0FF22907F987408F09050 +:40134600C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FF22907F98740DF090C000E0FFC5 +:4013860022907F98740EF090C000E0FF22120003120D5F120B4622000000000000000000000000000000000000000000000000000000000000000000000000000000000083 +:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 +:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 +:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 +:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 +:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 +:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 +:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 +:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 +:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 +:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 +:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 +:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 +:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 +:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 +:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 +:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 +:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 +:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 +:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF +:401906000040CD06100100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400076 +:4019460000070506024000000705070240000007058102400001070582024000000705830240000107058402400001070585024000010705860240000107058702400001F4 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:041A0600720000006A +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28xa.HEX b/firmware/keyspan/usa28xa.HEX new file mode 100644 index 0000000..f14932e --- /dev/null +++ b/firmware/keyspan/usa28xa.HEX @@ -0,0 +1,141 @@ +:030033000212F9BD +:10000300E4907F93F0907F9C7430F0E4907F96F0BF +:10001300907F94F0907F9D74FFF0E4907F97F09031 +:0F0023007F95F0907F9E7407F0E4907F98F02215 +:10004600300918121327EFC3953C40030200D890DD +:100056007FBF7401F0C209C200807730033B907FF6 +:10006600C6E020E16D121327EFC394405064907EE2 +:1000760040E0139209907FC7E014F5192000116043 +:100086000FF5087E7E7F41750C7E750D41120CC8FA +:10009600C203E4907FC7F08039907FC8E020E13248 +:1000A600121327EFC394405029907DC0E0139209A4 +:1000B600907FC9E014F519200011600FF5087E7DC8 +:1000C6007FC1750C7D750DC1120CC8D203E4907FFB +:1000D600C9F0907FB6E030E1030201601211E48FAF +:1000E600191213338F36E519C3953A500F12130FB1 +:1000F600EF30E008E53620E703300B5EC20BE5196A +:0C003600907F987410F090C000E0FF2252 +:03004300021300A5 +:03000000020E0EDF +:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F59E51925E0907FB7F08027E519D3943F400375193F851908C6 +:40014600907E80E536F07E7E7F81750C7E750D81120CEDE51904907FB7F0907FCEE030E1062005030203C1C205E4F51874402518F582E4347CF583E0FFE5187C007B017AE3 +:400186007E79002400F9EC347EFAEF120EE00518E518B420D7907E00E06068907E03E060247F01E4FD1211BF7F037DCD1211BF434680907F987414F090C000E546F0E490B6 +:4001C6007E13F08030907E01E0FF121043907E02E0FF1210697F01907E11E0FD1211BF7F037D071211BF434680907F987414F090C000E546F0907F987412F0E54044069006 +:40020600C000F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E0600543428080035342DA +:400246007F5342FC907E09E06011434202A3E0FF1210B5907E0BE0FF1210DBAF4212108F907E03E0600853427FAF4212108F907E0CE06018A3E0600543460280035346FD7C +:40028600907F987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E060054346108B +:4002C60080035346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F01212EDEF54FE90C000F0533EFDE4FFAD3E1201 +:4003060011BFE4F52AF529D207907E17E0600F433E02E4FFAD3E1211BF752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F98D6 +:400346007413F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211BF752B01D207907E1BE0600F433E01E4FFAD3E1211BFE4F52BD207907E1CE0600E907F98741268 +:40038600F0E540440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203E4907FCFF0301A52E53892 +:4003C60060021538201349E513D3940040041513803E75130A301B02D2131212EDEF5401F519652A600585192AD20712133FEF5480F51965266005851926D207300D111265 +:40040600133FEF5410F51965256005851925D207201B030207EC300A1812137BEFC3953D40030204AE907FC17401F0C20AC200807730043B907FCAE020E16D12137BEFC336 +:4004460094405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D12C204E4907FCBF08039907FCCE020E13212137BEFC39440502990A2 +:400486007CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D12D204E4907FCDF0907FBAE030E10302053612122E8F191213878F37E519C39503 +:4004C6003B500F121363EF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120F92E5E9 +:400506001925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D37E51904907FBBF0907FD0E030E106200603020797C206E4EA +:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120EE00518E518B420D7907E20E06068907E23E060247F01E4FD1212097F030C +:400586007DCD121209434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121127907E22E0FF12114D7F01907E31E0FD1212097F037D0712120943478090FF +:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB +:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121173907E2BE0FF121199AF43121101907E23E0600853437FAFD3 +:4006460043121101907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0C5 +:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 +:4006C600987409F0121357EF54FE90C000F0533FFDE4FFAD3F121209E4F533F532D208907E37E0600F433F02E4FFAD3F121209753201D208907E38E06010907F98740AF019 +:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F121209753401D208907E3BE0600F433F01E4DA +:40074600FFAD3F121209E4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD774137A +:40078600F07433F07416F07436F0D204E4907FD1F0301A52E53960021539301349E513D3940040041513803E75130A301B02C213121357EF5401F51965336005851933D26D +:4007C60008121393EF5480F519652F600585192FD208300E11121393EF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B42E0F516901D +:400806007B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020920E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E9AFF748025AF +:4008460018F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EE3400FA1297 +:400886000E9AFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E2518F9EE340075 +:4008C600FA120E9AFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E9AFF748025D6 +:4009060018F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EF20A08000A7C010AE80309440609FB0809F50909DD0A09EC0B00000B37907F2F +:40094600EBE024FE6019146061240260030209D37419907FD4F07400907FD5F0020B3E907FEAE070047F0280027F03758282758319EFF075827B758319F0758274758319B2 +:40098600F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B3E907FEAE0FF120F18EA49600DEA907FD4F0E9907FD5F077 +:4009C600020B3E907FB4E04401F0020B3E907FB4E04401F0020B3E907F00E509F0907FB57401F0020B3E907FEAE0F509020B3E120B46020B3E907F007401F0907FB5F00205 +:400A06000B3E907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B3EE4907F00F0A3F0907FB57402F0020B3E907F04 +:400A4600ECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B3E907FB4E04401F0020B3E907FE8E024FE601D24020F +:400A86006003020B3E907FEAE0B40105C210020B3E907FB4E04401F0020B3E907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FB6 +:400AC600ECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB4E04401F049 +:400B06008036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022D4 +:400B4600E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F9E43400FA8B +:400B8600E4120EE00518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211BF7F108F4212108F907FD8 +:400BC600987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211BFE4FF7EA3AD068D3E1211BF907F987411F090C000E4F07F057D7F121172 +:400C0600BF7F011212787F037D071211BF7F137D011211BF201B03020CC5752D017518017B00742D2518F9E43400FAE4120EE00518E518B409EA753B01E4F539F513F537B7 +:400C4600C208C20CC206C200C20AC213907F98740BF075450390C0007403F07F0CE4FD1212097F108F43121101907F98740AF07F018F41EF440690C000F0907F98740CF00E +:400C860075478090C0007480F00FE4FD121209E4FF7EA3AD068D3F121209907F987409F090C000E4F07F057D7F1212097F011212997F037D071212097F137D01121209D28D +:400CC6001222907F987410F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690C000E00568 +:400D060086F0A30586DFF70586D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF582E50CF577 +:400D460083C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92E04402F00A +:400D8600907FAEE0FFD39210E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0D2AFD21A56 +:400DC600121253C211E4F50BF513C217C212907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092180D63018D38A +:400E0600C21812139F80CC22787FE4F6D8FD758147020E55020D7DE493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F4568031 +:400E46000146F6DFE4800B01020408102040809012BAE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C582C828 +:400E8600CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E0225006E92548 +:400EC60082F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A393F87401DE +:400F060093F5828883E4737402936860EFA3A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EB3B4031DAF190519EFB5180122120E9A7E0029FFEEB6 +:400F46003AA907751AFFF51B891C80D47B007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF01508E508607B +:400F86000A1213338F1AEF423680CA228F1A050DE50DAE0C7002050C14F5828E83E51AF012134B050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213878F1AEFF8 +:400FC600423780CA22C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D21123 +:401006005391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB7408F0D086D084D085D082D083D0E032907F9833 +:401046007413F090C00074BFF0907F987410F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987411F090C000EFF0907F987413F0C0 +:40108600E544547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987414B3 +:4010C600F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F987413F0E544547F90C000F022907F98740BCC +:40110600F090C00074BFF0907F98740AF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987408F090C000EFF0907F98740BF0E54582 +:40114600547F90C000F022907F98740BF090C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740CF090C3 +:40118600C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BF0E545547F90C000F022907F987413F0E5CC +:4011C60044547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF02212131B8F1A12131B8F1BE51A651B601212131B8F1AE51A651B600712131B8F1B80E8ED +:40120600AF1A22907F98740BF0E545547F90C000F0907F98740FF090C000EFF0907F98740DF090C000EDF02212136F8F1A12136F8F1BE51A651B601212136F8F1AE51A65AD +:401246001B600712136F8F1B80E8AF1A22907FD6E054FBF0E04408F0301A04E04402F07FF47E011212D6907FD6E054F7F0E04404F022AE07E4FFE53E547FFD1211BF907F2F +:40128600987411F090C000EEF0E4E53E4480FD1211BF22AE07E4FFE53F547FFD121209907F987409F090C000EEF0E4E53F4480FD12120922050E02000000000314030000DF +:4012C600C111C118C195C110C116010A00C19B008E188F19E5191519AE18700215184E6005120D5C80EE22907F987411F090C000E0FF2253D8EF32000000020FF500021367 +:401306000400020FCB0002101C907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090C000E0FF22907F987416F0902A +:40134600C000E0FF22907F987408F090C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FF22907F98740CF090C000E0FFCA +:4013860022907F98740DF090C000E0FF22907F98740EF090C000E0FF22120003120D6D120B462200000000000000000000000000000000000000000000000000000000000C +:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 +:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 +:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 +:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 +:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 +:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 +:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 +:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 +:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 +:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 +:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 +:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 +:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 +:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 +:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 +:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 +:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 +:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 +:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF +:401906000040CD06150100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400071 +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:041A0600720000006A +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa28xb.HEX b/firmware/keyspan/usa28xb.HEX new file mode 100644 index 0000000..07cb708 --- /dev/null +++ b/firmware/keyspan/usa28xb.HEX @@ -0,0 +1,142 @@ +:0300330002002D9B +:04002D0053D8EF3283 +:10004600300918121333EFC3953C40030200D890D1 +:100056007FBF7401F0C209C200807730033B907FF6 +:10006600C6E020E16D121333EFC394405064907ED6 +:1000760040E0139209907FC7E014F5192000116043 +:100086000FF5087E7E7F41750C7E750D41120CCCF6 +:10009600C203E4907FC7F08039907FC8E020E13248 +:1000A600121333EFC394405029907DC0E013920998 +:1000B600907FC9E014F519200011600FF5087E7DC8 +:1000C6007FC1750C7D750DC1120CCCD203E4907FF7 +:1000D600C9F0907FB6E030E1030201601211F58F9E +:1000E6001912133F8F36E519C3953A500F12131B99 +:1000F600EF30E008E53620E703300B5EC20BE5196A +:0C003600907F987410F090C000E0FF2252 +:03004300021300A5 +:10000300C0E0C083C082C085C084C086758600906E +:100013007FC4E4F05391EF907FAB7404F0D086D0AB +:0A00230084D085D082D083D0E03273 +:03000000020E12DB +:400106006058B48003433602E53630E726E519D3942040037519208519087E7E7F80750C7E750D80AF36120F5DE51925E0907FB7F08027E519D3943F400375193F851908C2 +:40014600907E80E536F07E7E7F81750C7E750D81120CF1E51904907FB7F0907FCEE030E1062005030203C1E4F51874402518F582E4347CF583E0FFE5187C007B017A7E79AF +:40018600002400F9EC347EFAEF120EE40518E518B420D7907E00E06068907E03E060247F01E4FD1211D07F037DCD1211D0434680907F987414F090C000E546F0E4907E13F6 +:4001C600F08030907E01E0FF121054907E02E0FF12107A7F01907E11E0FD1211D07F037D071211D0434680907F987414F090C000E546F0907F987412F0E540440690C00093 +:40020600F0907E03E07006907E13E07008E4907E13F07525FF907E05E06012A3E0543FF544907F987413F090C000E544F0907E07E0602BA3E06005434280800353427F53C8 +:4002460042FC907E09E06011434202A3E0FF1210C6907E0BE0FF1210ECAF421210A0907E03E0600853427FAF421210A0907E0CE06018A3E0600543460280035346FD907FFB +:40028600987414F090C000E546F0907E0EE06018A3E0600543460180035346FE907F987414F090C000E546F0907E12E0F53AA3E013920DA3E0F53CA3E06005434610800317 +:4002C6005346EF907F987414F090C000E546F0907E16E060325344BF907F987413F0E544547F90C000F0907F987411F012130FEF54FE90C000F0533EFDE4FFAD3E1211D080 +:40030600E4F52AF529D207907E17E0600F433E02E4FFAD3E1211D0752901D207907E18E06010907F987412F0E540440490C000F0D200907E19E06011434440907F9874130E +:40034600F0E544547F90C000F0907E1AE0600F533EFEE4FFAD3E1211D0752B01D207907E1BE0600F433E01E4FFAD3E1211D0E4F52BD207907E1CE0600E907F987412F0E5F8 +:4003860040440290C000F0907E1DE06002D20B907E1EE06008752C01E4F538D207907E1FE06011907FD77411F07431F07415F07435F0D203C205E4907FCFF0301A54E5389E +:4003C6006002153820134BE513D3940040041513804075130A301B02D21312130FEF5401F519652A600585192AD20712134BEF54806480F51965266005851926D207300D71 +:400406001112134BEF5410F51965256005851925D207201B030207F0300A18121387EFC3953D40030204B0907FC17401F0C20AC200807730043B907FCAE020E16D1213879B +:40044600EFC394405064907D40E013920A907FCBE014F519200011600FF5087E7D7F41750C7D750D41120D16C204E4907FCBF08039907FCCE020E132121387EFC394405099 +:4004860029907CC0E013920A907FCDE014F519200011600FF5087E7C7FC1750C7C750DC1120D16D204E4907FCDF0907FBAE030E10302053812123F8F191213938F37E5197F +:4004C600C3953B500F12136FEF30E008E53720E703300C5EC20CE5196058B48003433702E53730E726E519D3942040037519208519087E7D7F80750C7D750D80AF37120FFC +:4005060096E51925E0907FBBF08027E519D3943F400375193F851908907D80E537F07E7D7F81750C7D750D81120D3BE51904907FBBF0907FD0E030E106200603020799E431 +:40054600F51874C02518F582E4347BF583E0FFE5187C007B017A7E79202420F9EC347EFAEF120EE40518E518B420D7907E20E06068907E23E060247F01E4FD12121A7F03F7 +:400586007DCD12121A434780907F98740CF090C000E547F0E4907E33F08030907E21E0FF121138907E22E0FF12115E7F01907E31E0FD12121A7F037D0712121A43478090AA +:4005C6007F98740CF090C000E547F0907F98740AF0E541440690C000F0907E23E07006907E33E07008E4907E33F0752EFF907E25E06012A3E0543FF545907F98740BF090EB +:40060600C000E545F0907E27E0602BA3E06005434380800353437F5343FC907E29E06011434302A3E0FF121184907E2BE0FF1211AAAF43121112907E23E0600853437FAFA0 +:4006460043121112907E2CE06018A3E0600543470280035347FD907F98740CF090C000E547F0907E2EE06018A3E0600543470180035347FE907F98740CF090C000E547F0B4 +:40068600907E32E0F53BA3E013920EA3E0F53DA3E0600543471080035347EF907F98740CF090C000E547F0907E36E060325345BF907F98740BF0E545547F90C000F0907F79 +:4006C600987409F0121363EF54FE90C000F0533FFDE4FFAD3F12121AE4F533F532D208907E37E0600F433F02E4FFAD3F12121A753201D208907E38E06010907F98740AF0EB +:40070600E541440490C000F0D200907E39E06011434540907F98740BF0E545547F90C000F0907E3AE0600F533FFEE4FFAD3F12121A753401D208907E3BE0600F433F01E4C9 +:40074600FFAD3F12121AE4F534D208907E3CE0600E907F98740AF0E541440290C000F0907E3DE06002D20C907E3EE06008753501E4F539D208907E3FE06011907FD7741369 +:40078600F07433F07416F07436F0D204C206E4907FD1F0301A54E5396002153930134BE513D3940040041513804075130A301B02C213121363EF5401F51965336005851998 +:4007C60033D20812139FEF54806480F519652F600585192FD208300E1112139FEF5410F519652E600585192ED208301A2A907FD2E020E123907B40E06009E0F515907B4297 +:40080600E0F516907B41E06009907FD77417F07437F0E4907FD3F0907FC2E030E103020924E50A7040300739E5387035C207F5187E007B0074242518F9EE3400FA120E9E44 +:40084600FF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753810E4F52C750A0122E50A64017040300839E5397035C208F5187E007B00742D2518F9EEBF +:400886003400FA120E9EFF74802518F582E4347BF583EFF00518E518B409DB907FC37409F0753910E4F535750A0222E50A6402703630142FC214F5187E007B00740E25184C +:4008C600F9EE3400FA120E9EFF74802518F582E4347BF583EFF00518E518B405DB907FC37405F0750A0322E51560301515E4F5187E007B0074142518F9EE3400FA120E9ECB +:40090600FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F0E4F50A22907FE9E0120EF60A0C000A80010AEC0309480609FF0809F90909E10A09F00B000044 +:400946000B3B907FEBE024FE6019146061240260030209D77419907FD4F07400907FD5F0020B42907FEAE070047F0280027F03758282758319EFF075827B758319F07582DA +:4009860074758319F0758266758319F0758258758319F0907FEAE004758217758319F07419907FD4F07412907FD5F0020B42907FEAE0FF120F1CEA49600DEA907FD4F0E9BE +:4009C600907FD5F0020B42907FB4E04401F0020B42907FB4E04401F0020B42907F00E509F0907FB57401F0020B42907FEAE0F509020B42120B4A020B42907F007401F0903B +:400A06007FB5F0020B42907FE8E0247F60241460312402705BA210E433FF25E0FFA216E4334F907F00F0E4A3F0907FB57402F0020B42E4907F00F0A3F0907FB57402F0022E +:400A46000B42907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F0020B42907FB4E04401F0020B42907FE8E024FE4E +:400A8600601D24026003020B42907FEAE0B40105C210020B42907FB4E04401F0020B42907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583EA +:400AC600E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D210803F907FB47B +:400B0600E04401F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E017 +:400B46004402F022E4907F93F0907F9C7430F0E4907F96F0907F9574C0F0907F9E743FF0907F987418F0E4F58E907FDF74FFF0907FDEF0E4F5247518017B0074242518F945 +:400B8600E43400FAE4120EE40518E518B409EA753A01E4F538F513F536C207C20BC205C200C209C213907F987413F075440390C0007403F07F0CE4FD1211D07F108F42125F +:400BC60010A0907F987412F07F018F40EF440690C000F0907F987414F075468090C0007480F00FE4FD1211D0E4FF7EA3AD068D3E1211D0907F987411F090C000E4F07F05B0 +:400C06007D7F1211D07F011212897F037D071211D07F137D091211D0201B03020CC9752D017518017B00742D2518F9E43400FAE4120EE40518E518B409EA753B01E4F53978 +:400C4600F513F537C208C20CC206C200C20AC213907F98740BF075450390C0007403F07F0CE4FD12121A7F108F43121112907F98740AF07F018F41EF440690C000F0907FC0 +:400C860098740CF075478090C0007480F00FE4FD12121AE4FF7EA3AD068D3F12121A907F987409F090C000E4F07F057D7F12121A7F011212AA7F037D0712121A7F137D0927 +:400CC60012121AD21222907F987410F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987410F0AF08E50DF582E50CF583C2AF058690FD +:400D0600C000E00586F0A30586DFF70586D2AF22907F987408F0AF08E50DF582E50CF583C2AF058690C0000586E0A30586F00586DFF7D2AF22907F987408F0AF08E50DF53A +:400D460082E50CF583C2AF058690C000E00586F0A30586DFF70586D2AF227400F58690FDA57C05A3E582458370F922907FD6E04480F0438701000000000022D219907F92B8 +:400D8600E04402F0907FAEE0FFD39210E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFF0907FA9F0907FAAF05391EF907FAFE04401F0907FAEE0440DF0AD +:400DC600D2AFD21A121264C211E4F50BF513C217C212907FA104F0907FD8E065176010301205D21A120046907FD8E0F5178008301205C21A120046301107C21112092580F9 +:400E0600D63018D3C2181213AB80CC22787FE4F6D8FD758147020E59020D81E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C88340FA +:400E460004F456800146F6DFE4800B01020408102040809012CBE47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A320 +:400E8600C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BEBB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F582E5833AF583E022D5 +:400EC6005006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E4937012740193700DA3A37A +:400F060093F8740193F5828883E4737402936860EFA3A3A380DF8F18E4F519751AFF751B19751C86AB1AAA1BA91C900001120EB7B4031DAF190519EFB5180122120E9E7EC4 +:400F46000029FFEE3AA907751AFFF51B891C80D47B007A007900228F1A050DE50DAE0C7002050C14F5828E83E51AF0120036050DE50DAC0C7002050C14F5828C83EFF015BA +:400F860008E508600A12133F8F1AEF423680CA228F1A050DE50DAE0C7002050C14F5828E83E51AF0121357050DE50DAC0C7002050C14F5828C83EFF01508E508600A1213AA +:400FC600938F1AEF423780CA22E4907F93F0907F9C7430F0E4907F96F0907F95F0907F9E7427F0907F987420F0907F9E7407F0E4907F94F0907F9D74FFF0E4907F97F0227C +:40100600C0E0C083C082C085C084C086758600D2115391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2185391EF907FAB74087E +:40104600F0D086D084D085D082D083D0E032907F987413F090C00074BFF0907F987410F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF00C +:40108600907F987411F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987412F090C000EFF0907F987413F0E544547F90C000F0220A +:4010C600907F987413F090C00074BFF0907F987414F090C000EFF0907F987413F0E544547F90C000F022907F987413F090C00074BFF0907F987416F090C000EFF0907F9807 +:401106007413F0E544547F90C000F022907F98740BF090C00074BFF0907F98740AF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907FFA +:40114600987408F090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F987409F090C000EFF0907F98740BF0E545547F90C000F022907F71 +:4011860098740BF090C00074BFF0907F98740CF090C000EFF0907F98740BF0E545547F90C000F022907F98740BF090C00074BFF0907F98740EF090C000EFF0907F98740BFD +:4011C600F0E545547F90C000F022907F987413F0E544547F90C000F0907F987417F090C000EFF0907F987415F090C000EDF0221213278F1A1213278F1BE51A651B60121292 +:4012060013278F1AE51A651B60071213278F1B80E8AF1A22907F98740BF0E545547F90C000F0907F98740FF090C000EFF0907F98740DF090C000EDF02212137B8F1A121325 +:401246007B8F1BE51A651B601212137B8F1AE51A651B600712137B8F1B80E8AF1A22907FD6E054FBF0E04408F0301A04E04402F07FF47E011212E7907FD6E054F7F0E044E1 +:4012860004F022AE07E4FFE53E547FFD1211D0907F987411F090C000EEF0E4E53E4480FD1211D022AE07E4FFE53F547FFD12121A907F987409F090C000EEF0E4E53F448095 +:4012C600FD12121A22050E02000000000314030000C111C118C195C110C116010A00C19B008E188F19E5191519AE18700215184E6005120D6080EE2200000210060002137E +:4013060004000200030002102D907F987411F090C000E0FF22907F987412F090C000E0FF22907F987413F090C000E0FF22907F987414F090C000E0FF22907F987415F090F5 +:40134600C000E0FF22907F987416F090C000E0FF22907F987408F090C000E0FF22907F987409F090C000E0FF22907F98740AF090C000E0FF22907F98740BF090C000E0FFC0 +:4013860022907F98740CF090C000E0FF22907F98740DF090C000E0FF22907F98740EF090C000E0FF22120FCF120D71120B4A220000000000000000000000000000000000C1 +:4013C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E7 +:4014060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6 +:401446000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066 +:401486000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026 +:4014C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E6 +:4015060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A5 +:401546000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065 +:401586000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025 +:4015C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E5 +:4016060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A4 +:401646000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064 +:401686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024 +:4016C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4 +:4017060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A3 +:401746000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063 +:401786000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:4017C60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E3 +:4018060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2 +:401846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062 +:401886000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022 +:4018C6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012011001FF00BF +:401906000040CD06100100000102000209027400010100A032090400000EFF0000000705010240000007050202400000070503024000000705040240000007050502400076 +:4019460000070506024000000705070240000007058102400001070582024000000705830240000107058402400001070585024000010705860240000107058702400001F4 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0036034B00650079007300700061006E0020005500530042002000530065007200690061006C002000410064006100700074006500F9 +:041A0600720000006A +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa49w.HEX b/firmware/keyspan/usa49w.HEX new file mode 100644 index 0000000..5e5b3d1 --- /dev/null +++ b/firmware/keyspan/usa49w.HEX @@ -0,0 +1,145 @@ +:030033000218FBB5 +:0C0036009078417401F090C000E0FF22BF +:10004600E4FF74402FF582E4347BF583E0FEE5158A +:100056002404FDE43514FAA9057B01EF7C0029F997 +:10006600EC3AFAEE1211F10FBF22D7E5152405F589 +:1000760082E43514F583E07003020134E5152409A2 +:10008600F582E43514F583E0700EE515240AF58251 +:10009600E43514F583E060187F01E4FD121647E5A8 +:1000A600152431F582E43514F583E054CFF0804110 +:1000B600E5152406F582E43514F583E0FF1216767D +:1000C600E5152407F582E43514F583E0FF120003F5 +:1000D6007F01E5152408F582E43514F583E0FD1269 +:1000E6001647E5152431F582E43514F583E04430EE +:1000F600F0E5152439F582E43514F583E04480F003 +:100003009078417403F090C00074BFF0907841740D +:1000130001F090C000EFF09078417403F0E51524EF +:1000230037F582E43514F583E0547F90C000F02265 +:03004300021B009D +:0300000002109556 +:400106009078417404F0E5152439F582E43514F583E090C000F09078417402F0E5152436F582E43514F583E0440690C000F0E515240BF582E43514F583E06032E515240C0B +:40014600F582E43514F583E0543FFFE5152437F582E43514F583EFF09078417403F0E5152437F582E43514F583E090C000F0E515240DF582E43514F583E0700302024FE588 +:40018600152417F582E43514F583E06011E5152432F582E43514F583E04404F0800FE5152432F582E43514F583E054FBF0E4FFE5152432F582E43514F583E0FD121647E55E +:4001C60015240EF582E43514F583E06011E5152433F582E43514F583E04480F0800FE5152433F582E43514F583E0547FF0E5152433F582E43514F583E054FCF0E515240FEB +:40020600F582E43514F583E0602FE5152433F582E43514F583E04402F0E5152410F582E43514F583E0FF1215E7E5152411F582E43514F583E0FF121617E5152433F582E45E +:400246003514F583E0FF1215B7E5152414F582E43514F583E06044E5152415F582E43514F583E06011E5152439F582E43514F583E04401F0800FE5152439F582E43514F581 +:4002860083E054FEF09078417404F0E5152439F582E43514F583E090C000F0E5152412F582E43514F583E06044E5152413F582E43514F583E06011E5152439F582E43514E6 +:4002C600F583E04402F0800FE5152439F582E43514F583E054FDF09078417404F0E5152439F582E43514F583E090C000F0E5152416F582E43514F583E0FFE5152435F5820A +:40030600E43514F583EFF0E5152417F582E43514F583E030E011E5152431F582E43514F583E04440F0800FE5152431F582E43514F583E054BFF0E5152418F582E43514F576 +:4003460083E0FFE515243BF582E43514F583EFF0E5152419F582E43514F583E06011E5152439F582E43514F583E04410F0800FE5152439F582E43514F583E054EFF0907869 +:40038600417404F0E5152439F582E43514F583E090C000F0E515241AF582E43514F583E0606BE5152437F582E43514F583E054BFF09078417403F0E5152437F582E43514FF +:4003C600F583E0547F90C000F09078417401F0120036EF54FE90C000F0E5152432F582E43514F583E054FDFFF0FDE4FF121647E515242CF582E43514F583E4F0E515242BB7 +:40040600F582E43514F583E4F0E5164213E515241BF582E43514F583E0700EE5152425F582E43514F583E06028E5152432F582E43514F583E04402FFF0FDE4FF121647E547 +:4004460015242BF582E43514F5837401F0E5164213E515241CF582E43514F583E0FF700EE5152425F582E43514F583E0602A9078417402F0E5152436F582E43514F583E0C6 +:40048600440490C000F0EF600FE5152431F582E43514F583E04404F0E515241DF582E43514F583E06027E5152437F582E43514F583E04440F09078417403F0E5152437F550 +:4004C60082E43514F583E0547F90C000F0E515241EF582E43514F583E06028E5152432F582E43514F583E054FEFFF0FDE4FF121647E515242DF582E43514F5837401F0E58F +:40050600164213E515241FF582E43514F583E0700EE5152425F582E43514F583E06027E5152432F582E43514F583E04401FFF0FDE4FF121647E515242DF582E43514F58397 +:40054600E4F0E5164213E5152420F582E43514F583E0700EE5152425F582E43514F583E060189078417402F0E5152436F582E43514F583E0440290C000F0E5152421F582A7 +:40058600E43514F583E0600FE5152431F582E43514F583E04402F0E5152422F582E43514F583E0601FE515242EF582E43514F5837401F0E515243AF582E43514F583E4F0F0 +:4005C600E5164213E5152423F582E43514F583E06003121885E5152424F582E43514F583E0601BE5152431F582E43514F583E04408F0907F98E0FFE516F4FEEF5EF0E5156C +:400606002425F582E43514F583E06016E5152431F582E43514F583E054F7F0907F98E04516F022907FE9E012120307830007F701086303064C0607740807680907500A07CE +:400646005F0B000008B2907FEBE024FE601C1470030206FE240260030207467419907FD4F07400907FD5F00208B9907FEAE004758217758319F0907FEAE030E0047F03802D +:40068600027F02758282758319EFF075826D758319F0758266758319F075825F758319F0758258758319F0907FEAE030E1047F6480027F3275821A758319EFF0907FEFE0FB +:4006C600FE907FEEE07C002400F519EC3EF518753319753412758214758319E0752700F528D3E5289519E527951840068518278519281213120208B9907FEAE0FF12142BC9 +:40070600EA496032907FEEE0751800F519AE02AF018E338F348F828E83E0FEA3E08E27F528D39519E527951840068518278519281213120208B9907FB4E04401F00208B99E +:40074600907FB4E04401F00208B9907F00E525F0907FB57401F00208B9907FEAE0F5250208B9907FEAE0F522120AB80208B9907F00E522F0907FB57401F00208B9907FE8BD +:40078600E0247F60241460312402705BA200E433FF25E0FFA206E4334F907F00F0E4A3F0907FB57402F00208B9E4907F00F0A3F0907FB57402F00208B9907FECE0F4548063 +:4007C600FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00208B9907FB4E04401F00208B9907FE8E024FE601D240260030208B910 +:40080600907FEAE0B40105C2000208B9907FB4E04401F00208B9907FEAE07038907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E4F0907FECE05480FF67 +:40084600131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A907FEAE0B40104D200803F907FB4E04401F08036907FEACB +:40088600E07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F08007907FB4E04401F0907FB4E04402F022E511540F703D +:4008C600030209B21216A5EF20E175121703EF14F5191218CCEF2519FFE433FEC3EF9480EE648094805059851582851483E0FEA3E0FFF5828E83E030E011E5152431F58250 +:40090600E43514F583E04480F0800FE5152431F582E43514F583E0547FF0E5152431F582E43514F583E020E212E519600EF523EF2401F52DE43EF52C1214ADE4FF1214E3C0 +:40094600E5152431F582E43514F583E030E75D1218CCE515243BF582E43514F583E0FEEFC39E5048E515242FF582E43514F5837401F0E5152431F582E43514F583E0547B99 +:40098600F0E515243AF582E43514F583E4F0E5164213907FC2E030E110E5152426F582E43514F583E0F52480031212A11216D4EF30E103020AB71217D28F191218D8E515D5 +:4009C6002438F582E43514F583EFF0E5152435F582E43514F583E0FFE519C39F50281218B4EF30E021E5152438F582E43514F583E020E712E5152431F582E43514F583E0C0 +:400A060020E103020AB7E5152431F582E43514F583E054FDF0E5197003020AB7B4800FE5152438F582E43514F583E04402F0E5152438F582E43514F583E0FF30E729E519CF +:400A4600D394204003751920851923851582851483A3A3E0FCA3E08C2CF52D1213DDE51925E0FF12151922E519D3943F400375193F851923E5152438F582E43514F583E053 +:400A8600FF851582851483A3A3E0FCA3E0F5828C83EFF0851582851483A3A3E0FEA3E02401F52DE43EF52C12146CE51904FF12151922E4907F93F0907F9C74F0F0907F9677 +:400AC600F0E4907F94F090784A04F0F58E907F9574C0F0907F9E743FF0907F98741FF090784374FFF0E4907841F0907FDF749FF0907FDEF0907F92E04402F07E7B7FC07581 +:400B0600147B7515C0907F9674EFF0751601120F127E7B7FC075147B7515C0907F9674EFF0751601E5152426F582E43514F583E4F07E7E7F40851582851483747EF0A374F5 +:400B460040F07E7E7F80851582851483A3A3747EF0A37480F07E7C7F0075147C751500907F9674DFF0751602120F127E7C7F0075147C751500907F9674DFF0751602E51536 +:400B86002426F582E43514F5837401F07E7D7FC0851582851483747DF0A374C0F07E7E7F00851582851483A3A3747EF0A37400F07E7C7F4075147C751540907F9674BFF018 +:400BC600751604120F127E7C7F4075147C751540907F9674BFF0751604E5152426F582E43514F5837402F07E7D7F40851582851483747DF0A37440F07E7D7F8085158285D3 +:400C06001483A3A3747DF0A37480F07E7C7F8075147C751580907F96747FF0751608120F127E7C7F8075147C751580907F96747FF0751608E5152426F582E43514F583741C +:400C460003F07E7C7FC0851582851483747CF0A374C0F07E7D7F00851582851483A3A3747DF0A37400F0C20AC209D20222E510045403F51014601F1460311460432403701B +:400C8600527E7B7FC075147B7515C0907F9674EFF0751601803D7E7C7F0075147C751500907F9674DFF075160280287E7C7F4075147C751540907F9674BFF075160480137E +:400CC6007E7C7F8075147C751580907F96747FF0751608E53255167003020E11E516F4FF5232E526547FFE700FE52A55166024907F98E04516F0801BBE2018E5152431F543 +:400D060082E43514F583E030E309E4F52A907F98E05FF0E515243AF582E43514F583E06003E014F0E5152434F582E43514F583E06003E014F0E06003020E11740AF012009D +:400D460036EF5401FFF519E515242CF582E43514F583E06F6007E519F0E51642131218E48F19E5152427F582E43514F583E0FFE5195410FE6F6006EEF0E5164213E5152415 +:400D860028F582E43514F583E0FFE5195480FE6F6006EEF0E5164213E5152429F582E43514F583E0FFE5195420FE6F6015EEF0E5152431F582E43514F583E030E404E51665 +:400DC6004213E5125516FFF519E515242AF582E43514F583E06F6016E519F0E5152431F582E43514F583E030E504E5164213E5175516FFF519E5152430F582E43514F58380 +:400E0600E06F6007E519F0E516421322300903020F11E52414602A14604114605814606F24046003020ECF7E7B7FC075147B7515C0907F9674EFF07516011212A17524015A +:400E4600227E7C7F0075147C751500907F9674DFF07516021212A1752402227E7C7F4075147C751540907F9674BFF07516041212A1752403227E7C7F8075147C7515809051 +:400E86007F96747FF07516081212A175240422300433C2045313DFE4F5197E007B00742E2519F9EE3400FA1211ABFF74802519F582E4347BF583EFF00519E519B403DB902D +:400EC6007FC37403F075240522E536603BD5360A5313EF300A04D209C20AE4F5197E007B0074352519F9EE3400FA1211ABFF74802519F582E4347BF583EFF00519E519B467 +:400F060003DB907FC37403F0E4F52422E4F51A7E007B01E515251AF9EE3514FAE41211F1051AE51AB43CE8E5152435F582E43514F5837401F09078417403F0E5152437F569 +:400F460082E43514F5837403F090C000F07F0CE4FD1216477F10E5152433F582E43514F583EFF01215B79078417402F07F01E5152436F582E43514F583EFF0440690C000F1 +:400F8600F09078417404F0E5152439F582E43514F5837480F090C000F00FE4FD121647E4FF7EA3E5152432F582E43514F583EEF0FD1216479078417401F090C000E4F07F89 +:400FC600057D7F1216477F0112154F7F037D071216472253133F907BF1E030E3167E7B7FC075147B7515C0907F9674EFF07516011208C1907C31E030E3167E7C7F00751417 +:401006007C751500907F9674DFF07516021208C1907C71E030E3167E7C7F4075147C751540907F9674BFF07516041208C1907CB1E030E3167E7C7F8075147C751580907F37 +:4010460096747FF07516081208C10511E511540FF518701F907841E054F7F0907F99E0F517907841E04408F0907F99E0F4F51212112122E518B40104120C7322907FC2E018 +:4010860020E108E5136004120E1222120C7322787FE4F6D8FD7581370210DC021229E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F44207E +:4010C600C8834004F456800146F6DFE4800B0102040810204080901850E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8A2 +:40110600E493A3C8C582C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BE907FD2E030E1030211AAC209907B40E014602614603B14605024836064248070637E7B7FC01C +:4011460075147B7515C0907F9674EFF0751601120046804B7E7C7F0075147C751500907F9674DFF075160212004680337E7C7F4075147C751540907F9674BFF075160412FB +:401186000046801B7E7C7F8075147C751580907F96747FF0751608120046800312175CE4907FD3F022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB0189 +:4011C6000CE58229F582E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D086 +:4012060082F8E4937012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF907FAEE0FFD39200E433FEEF4EF0D2E843D820907FDE7401F0907FDFF08E +:40124600907FAB74FFF0907FA9F0907FAAF05391EF907FAF7401F0907FAE740DF0D2AFD20B121814C201E4F52BF531C207C2027529F0907FD8E06526600675320FE0F526C9 +:40128600300203120FD9300107C20112062980E23008DFC20812183580D822E5135516606AE515243AF582E43514F583E0705CE516F45213E5152426FFE43514FEE4FD0FA2 +:4012C600EFAA0670010E14F5828A83E0FC74802DF582E4347BF583ECF00DBD0BE2907FC3740BF0E515243AF582E43514F5837410F0E515242EF582E43514F583E4F0E515C1 +:40130600242FF582E43514F583E4F022E52845276057AE27AF28D3EF9440EE940040047E007F40C3E5289FF528E5279EF527E4FDEDC39FE49E501F853482853383E0FC7494 +:40134600002DF582E4347FF583ECF00D0534E5347002053380DA907FA97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022E4907F93F0907F9C74F0A7 +:40138600F0907F96F0E490784AF0907F94F0907F9D74FFF0E4907F97F0300007E52954F0FF80027F00EF4408907841F0E4907F98F0907F95F0907F9E74FFF0E4907F98F0C9 +:4013C600907F93F0907F9C74F0F0E4907F96F0907F92E054FDF0228F1A052DE52DAE2C7002052C14F5828E83E51AF01218F0052DE52DAC2C7002052C14F5828C83EFF0159D +:4014060023E523601FE5152438F582E43514F583C083C082E0FE1218D88F1AEE4FD082D083F080B5228F1AE4F51B751CFF751D19751E86AB1CAA1DA91E9000011211C4B4E1 +:40144600031DAF1B051BEFB51A01221211AB7E0029FFEE3AA907751CFFF51D891E80D47B007A00790022E4907841F090784F74C0F0E4907850F0E52C907851F0AE2CE52DF8 +:40148600907852F0907854E523F09078577404F0907FE2E04410F0E054F7F0E4907855F0907855E060FA22E4907841F0E52C90784FF0AE2CE52D907850F090785174C0F081 +:4014C600E4907852F0907854E523F09078577404F0E4907855F0907855E060FA22E5152404F582E43514F583E014600F1460131460178000907FC7EFF08013907FC9EFF081 +:40150600800C907FCBEFF08005907FCDEFF0E516422A22E5152404F582E43514F583E014600F1460131460178000907FB7EFF08013907FB9EFF0800C907FBBEFF08005903B +:401546007FBDEFF0E516422A22AE07E4FFE5152432F582E43514F583E0547FFD1216479078417401F090C000EEF0E4E5152432F582E43514F583E04480FD12164722C0E0A0 +:40158600C0F0C083C082C085C084C086758600C0D075D0085391EF907FA97401F0121312D0D0D086D084D085D082D083D0F0D0E0329078417403F090C00074BFF0907841D0 +:4015C6007402F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F0229078417403F090C00074BFF09078417404F090C000EFF09078417403F0E5156D +:401606002437F582E43514F583E0547F90C000F0229078417403F090C00074BFF09078417406F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F0FF +:40164600229078417403F0E5152437F582E43514F583E0547F90C000F09078417407F090C000EFF09078417405F090C000EDF0229078417403F090C00074BFF0E4907841FA +:40168600F090C000EFF09078417403F0E5152437F582E43514F583E0547F90C000F022E5152404F582E43514F583E014600E1460111460148000907FC6E0FF22907FC8E015 +:4016C600FF22907FCAE0FF22907FCCE0FF22E5152404F582E43514F583E014600E1460111460148000907FB6E0FF22907FB8E0FF22907FBAE0FF22907FBCE0FF22E515249E +:4017060004F582E43514F583E014600E1460111460148000907FC7E0FF22907FC9E0FF22907FCBE0FF22907FCDE0FF22C0E0C083C082C085C084C086758600907FC4E4F096 +:401746005391EF907FAB7404F0D086D084D085D082D083D0E032907B41E0F536431310A3E06009907FD77417F07437F0907B43E0F537A3E054F0F529E06002D20A22C0E024 +:40178600C083C082C085C084C086758600D2015391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2085391EF907FAB7408F0D0F7 +:4017C60086D084D085D082D083D0E0321218C0AE071218C0AD07EE6D60101218C0AE07EE6D60071218C0AD0780ECAF06227400F58690FDA57C05A3E582458370F922907FD5 +:40180600D6E04480F0438701000000000022907FD6E04404F0E04408F0300B04E04402F07FF47E0112186B907FD6E054F7F02212137C121804907FD6E030E70A7F057E007D +:4018460012186B12189E120AB8220335800000032E810000C185C181C108C100C106012200012400008E188F19E5191519AE18700215184E60081217F31217F380EB22E545 +:40188600152404F582E43514F583E004FF4410907FD7F0EF4430F022907FD6E04401F07F0D7E0012186B907FD6E054FEF0229078417402F090C000E0FF229078417403F0D5 +:4018C60090C000E0FF229078417404F090C000E0FF229078417405F090C000E0FF229078417406F090C000E0FF22E4907841F090C000E0FF2253D8EF320012011001FF00AB +:401906000040CD060A0100000102000409027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240007A +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E003603550053004200200034002D0070006F00720074002000530065007200690061006C00200041006400610070007400650072003C +:401A060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0 +:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060 +:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020 +:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002178400021B26 +:151B06000400021732000217AB00021B1000021B1400021584BE +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2001 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." diff --git a/firmware/keyspan/usa49wlc.HEX b/firmware/keyspan/usa49wlc.HEX new file mode 100644 index 0000000..8406eb1 --- /dev/null +++ b/firmware/keyspan/usa49wlc.HEX @@ -0,0 +1,153 @@ +:017F920001ED +:030033000218FBB5 +:0D003600E51104907841F090C000E0FF2239 +:10004600E4FF74402FF582E4347BF583E0FEE5158A +:100056002404FDE43514FAA9057B01EF7C0029F997 +:10006600EC3AFAEE1211EC0FBF22D7E5152405F58E +:1000760082E43514F583E07003020134E5152409A2 +:10008600F582E43514F583E0700EE515240AF58251 +:10009600E43514F583E060187F01E4FD12166BE584 +:1000A600152431F582E43514F583E054CFF0804110 +:1000B600E5152406F582E43514F583E0FF12000306 +:1000C600E5152407F582E43514F583E0FF1215AB38 +:1000D6007F01E5152408F582E43514F583E0FD1269 +:1000E600166BE5152431F582E43514F583E04430CA +:1000F600F0E5152439F582E43514F583E04480F003 +:1000030090784174F3F090C00074BFF0907841741D +:10001300F0F090C000EFF090784174F3F0E5152410 +:1000230037F582E43514F583E0547F90C000F02265 +:03004300021B009D +:030000000210905B +:4001060090784174F4F0E5152439F582E43514F583E090C000F090784174F2F0E5152436F582E43514F583E0440690C000F0E515240BF582E43514F583E06032E515240C2B +:40014600F582E43514F583E0543FFFE5152437F582E43514F583EFF090784174F3F0E5152437F582E43514F583E090C000F0E515240DF582E43514F583E0700302024FE598 +:40018600152417F582E43514F583E06011E5152432F582E43514F583E04404F0800FE5152432F582E43514F583E054FBF0E4FFE5152432F582E43514F583E0FD12166BE53A +:4001C60015240EF582E43514F583E06011E5152433F582E43514F583E04480F0800FE5152433F582E43514F583E0547FF0E5152433F582E43514F583E054FCF0E515240FEB +:40020600F582E43514F583E0602FE5152433F582E43514F583E04402F0E5152410F582E43514F583E0FF12160BE5152411F582E43514F583E0FF12163BE5152433F582E415 +:400246003514F583E0FF1215DBE5152414F582E43514F583E06044E5152415F582E43514F583E06011E5152439F582E43514F583E04401F0800FE5152439F582E43514F55D +:4002860083E054FEF090784174F4F0E5152439F582E43514F583E090C000F0E5152412F582E43514F583E06044E5152413F582E43514F583E06011E5152439F582E43514F6 +:4002C600F583E04402F0800FE5152439F582E43514F583E054FDF090784174F4F0E5152439F582E43514F583E090C000F0E5152416F582E43514F583E0FFE5152435F5821A +:40030600E43514F583EFF0E5152417F582E43514F583E030E011E5152431F582E43514F583E04440F0800FE5152431F582E43514F583E054BFF0E5152418F582E43514F576 +:4003460083E0FFE515243BF582E43514F583EFF0E5152419F582E43514F583E06011E5152439F582E43514F583E04410F0800FE5152439F582E43514F583E054EFF0907869 +:400386004174F4F0E5152439F582E43514F583E090C000F0E515241AF582E43514F583E0606BE5152437F582E43514F583E054BFF090784174F3F0E5152437F582E435141F +:4003C600F583E0547F90C000F090784174F1F0120036EF54FE90C000F0E5152432F582E43514F583E054FDFFF0FDE4FF12166BE515242CF582E43514F583E4F0E515242BA3 +:40040600F582E43514F583E4F0E5164213E515241BF582E43514F583E0700EE5152425F582E43514F583E06028E5152432F582E43514F583E04402FFF0FDE4FF12166BE523 +:4004460015242BF582E43514F5837401F0E5164213E515241CF582E43514F583E0FF700EE5152425F582E43514F583E0602A90784174F2F0E5152436F582E43514F583E0D6 +:40048600440490C000F0EF600FE5152431F582E43514F583E04404F0E515241DF582E43514F583E06027E5152437F582E43514F583E04440F090784174F3F0E5152437F560 +:4004C60082E43514F583E0547F90C000F0E515241EF582E43514F583E06028E5152432F582E43514F583E054FEFFF0FDE4FF12166BE515242DF582E43514F5837401F0E56B +:40050600164213E515241FF582E43514F583E0700EE5152425F582E43514F583E06027E5152432F582E43514F583E04401FFF0FDE4FF12166BE515242DF582E43514F58373 +:40054600E4F0E5164213E5152420F582E43514F583E0700EE5152425F582E43514F583E0601890784174F2F0E5152436F582E43514F583E0440290C000F0E5152421F582B7 +:40058600E43514F583E0600FE5152431F582E43514F583E04402F0E5152422F582E43514F583E0601FE515242EF582E43514F5837401F0E515243AF582E43514F583E4F0F0 +:4005C600E5164213E5152423F582E43514F583E0600312187AE5152424F582E43514F583E06023E5152431F582E43514F583E04408F0E516C454F0FF4211907F96E04FF000 +:40060600907841E04FF0E5152425F582E43514F583E06024E5152431F582E43514F583E054F7F0E516C454F0F4FF5211907F96E05FF0907841E05FF022907FE9E01211FE43 +:40064600079900080D01087903066206078A08077E0907660A07750B000008C8907FEBE024FE601C1470030207142402600302075C7419907FD4F07400907FD5F00208CF4C +:40068600907FEAE004758217758319F0907FEAE030E0047F0280027F03758282758319EFF075826D758319F0758266758319F075825F758319F0758258758319F0907FEA0A +:4006C600E030E1047F6480027F3275821A758319EFF0907FEFE0FE907FEEE07C002400F518EC3EF517753319753412758214758319E0752700F528D3E5289518E5279517D6 +:40070600400685172785182812130D0208CF907FEAE0FF12145FEA496032907FEEE0751700F518AE02AF018E338F348F828E83E0FEA3E08E27F528D39518E527951740068B +:4007460085172785182812130D0208CF907FB4E04401F00208CF907FB4E04401F00208CF907F00E525F0907FB57401F00208CF907FEAE0F5250208CF907FEAE0F522120A9B +:40078600CE0208CF907F00E522F0907FB57401F00208CF907FE8E0247F60241460312402705BA200E433FF25E0FFA206E4334F907F00F0E4A3F0907FB57402F00208CFE4C9 +:4007C600907F00F0A3F0907FB57402F00208CF907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF583E054FD907F00F0E4A3F0907FB57402F00208CF907FB45C +:40080600E04401F00208CF907FE8E024FE601D240260030208CF907FEAE0B40105C2000208CF907FB4E04401F00208CF907FEAE07038907FECE0F45480FFC4540FFFE05490 +:40084600072F25E024B4F582E4347FF583E4F0907FECE05480FF131313541FFFE054072F907FD7F0E04420F0805F907FB4E04401F08056907FE8E024FE60182402704A90CA +:400886007FEAE0B40104D200803F907FB4E04401F08036907FEAE07020907FECE0F45480FFC4540FFFE054072F25E024B4F582E4347FF5837401F08010907FB4E04401F046 +:4008C6008007907FB4E04401F0907FB4E04402F022E512540F70030209C812169AEF20E1751216F8EF14F5181218C5EF2518FFE433FEC3EF9480EE64809480505985158201 +:40090600851483E0FEA3E0FFF5828E83E030E011E5152431F582E43514F583E04480F0800FE5152431F582E43514F583E0547FF0E5152431F582E43514F583E020E212E5CC +:4009460018600EF523EF2401F52DE43EF52C1214A0E4FF1214D7E5152431F582E43514F583E030E75D1218C5E515243BF582E43514F583E0FEEFC39E5048E515242FF58207 +:40098600E43514F5837401F0E5152431F582E43514F583E0547BF0E515243AF582E43514F583E4F0E5164213907FC2E030E110E5152426F582E43514F583E0F524800312C5 +:4009C600129C1216C9EF30E103020ACD1217C78F181218D3E5152438F582E43514F583EFF0E5152435F582E43514F583E0FFE518C39F50281218A9EF30E021E5152438F52E +:400A060082E43514F583E020E712E5152431F582E43514F583E020E103020ACDE5152431F582E43514F583E054FDF0E5187003020ACDB4800FE5152438F582E43514F583DE +:400A4600E04402F0E5152438F582E43514F583E0FF30E729E518D394204003751820851823851582851483A3A3E0FCA3E08C2CF52D1213CFE51825E0FF12150D22E518D3C3 +:400A8600943F400375183F851823E5152438F582E43514F583E0FF851582851483A3A3E0FCA3E0F5828C83EFF0851582851483A3A3E0FEA3E02401F52DE43EF52C12141D4F +:400AC600E51804FF12150D22E4907F93F0907F9C74FFF0E4907F96F0907F94F090784A04F0F58E907F9574C0F0907F9E743FF0907F98742FF090784374F7F0E4907841F02C +:400B0600907FDF749FF0907FDEF0907F92E04402F07E7B7FC075147B7515C0907F98742EF0751601120F287E7B7FC075147B7515C0907F98742EF0751601E5152426F58290 +:400B4600E43514F583E4F07E7E7F40851582851483747EF0A37440F07E7E7F80851582851483A3A3747EF0A37480F07E7C7F0075147C751500907F98742DF0751602120F0A +:400B8600287E7C7F0075147C751500907F98742DF0751602E5152426F582E43514F5837401F07E7D7FC0851582851483747DF0A374C0F07E7E7F00851582851483A3A374EE +:400BC6007EF0A37400F07E7C7F4075147C751540907F98742BF0751604120F287E7C7F4075147C751540907F98742BF0751604E5152426F582E43514F5837402F07E7D7F57 +:400C060040851582851483747DF0A37440F07E7D7F80851582851483A3A3747DF0A37480F07E7C7F8075147C751580907F987427F0751608120F287E7C7F8075147C751590 +:400C460080907F987427F0751608E5152426F582E43514F5837403F07E7C7FC0851582851483747CF0A374C0F07E7D7F00851582851483A3A3747DF0A37400F0C20AC209D3 +:400C8600E4F511D20222E510045403F51014601F146031146043240370527E7B7FC075147B7515C0907F98742EF0751601803D7E7C7F0075147C751500907F98742DF07564 +:400CC600160280287E7C7F4075147C751540907F98742BF075160480137E7C7F8075147C751580907F987427F0751608E53255167003020E27E516F45232E526547FFF7095 +:400D060017E52A55166034907F96E0FEE516C454F0F4FDEE5DF08023BF2020E5152431F582E43514F583E030E311E4F52A907F96E0FFE516C454F0FEEF4EF0E515243AF5C3 +:400D460082E43514F583E06003E014F0E5152434F582E43514F583E06003E014F0E06003020E27740AF0120036EF5401FFF518E515242CF582E43514F583E06F6007E518F1 +:400D8600F0E51642131218E18F18E5152427F582E43514F583E0FFE5185410FE6F6006EEF0E5164213E5152428F582E43514F583E0FFE5185480FE6F6006EEF0E516421386 +:400DC600E5152429F582E43514F583E0FFE5185420FE6F6015EEF0E5152431F582E43514F583E030E404E5164213E515242AF582E43514F583E0FFE5185440FE6F6015EE23 +:400E0600F0E5152431F582E43514F583E030E504E5164213E5152430F582E43514F583E4F022300903020F27E52414602A14604114605814606F24046003020EE57E7B7F31 +:400E4600C075147B7515C0907F98742EF075160112129C752401227E7C7F0075147C751500907F98742DF075160212129C752402227E7C7F4075147C751540907F98742B05 +:400E8600F075160412129C752403227E7C7F8075147C751580907F987427F075160812129C75240422300433C2045313DFE4F5187E007B00742E2518F9EE3400FA1211A6CA +:400EC600FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F075240522E536603BD5360A5313EF300A04D209C20AE4F5187E007B0074352518F9EE3400FACC +:400F06001211A6FF74802518F582E4347BF583EFF00518E518B403DB907FC37403F0E4F52422E4F5197E007B01E5152519F9EE3514FAE41211EC0519E519B43CE8E51524FA +:400F460035F582E43514F5837401F090784174F3F0E5152437F582E43514F5837403F090C000F07F0CE4FD12166B7F10E5152433F582E43514F583EFF01215DB9078417464 +:400F8600F2F07F01E5152436F582E43514F583EFF0440690C000F090784174F4F0E5152439F582E43514F5837480F090C000F00FE4FD12166BE4FF7EA3E5152432F582E486 +:400FC6003514F583EEF0FD12166B90784174F1F090C000E4F07F057D7F12166B7F011215437F037D0712166B2253133F907BF1E030E3167E7B7FC075147B7515C0907F986B +:40100600742EF07516011208D7907C31E030E3167E7C7F0075147C751500907F98742DF07516021208D7907C71E030E3167E7C7F4075147C751540907F98742BF0751604C4 +:401046001208D7907CB1E030E3167E7C7F8075147C751580907F987427F07516081208D70512E512540FF517700412111C22E517B40104120C8C22907FC2E020E108E51370 +:401086006004120E2822120C8C22787FE4F6D8FD7581370210D7021224E493A3F8E493A34003F68001F208DFF48029E493A3F85407240CC8C333C4540F4420C8834004F4D7 +:4010C60056800146F6DFE4800B0102040810204080901845E47E019360BCA3FF543F30E509541FFEE493A360010ECF54C025E060A840B8E493A3FAE493A3F8E493A3C8C589 +:4011060082C8CAC583CAF0A3C8C582C8CAC583CADFE9DEE780BE907FD2E030E1030211A5C209907B40E014602614603B14605024836064248070637E7B7FC075147B75153A +:40114600C0907F98742EF0751601120046804B7E7C7F0075147C751500907F98742DF075160212004680337E7C7F4075147C751540907F98742BF0751604120046801B7E2B +:401186007C7F8075147C751580907F987427F07516081200468003121751E4907FD3F022BB010689828A83E0225002E722BBFE02E32289828A83E49322BB010CE58229F5B8 +:4011C60082E5833AF583E0225006E92582F8E622BBFE06E92582F8E222E58229F582E5833AF583E49322BB010689828A83F0225002F722BBFE01F322D083D082F8E49370B6 +:4012060012740193700DA3A393F8740193F5828883E4737402936860EFA3A3A380DF907FAEE0FFD39200E433FEEF4EF0D2E843D820907FDE7401F0907FDFF0907FAB74FFC2 +:40124600F0907FA9F0907FAAF05391EF907FAF7401F0907FAE740DF0D2AFD20B121809C201E4F52BF531C207C20275290F907FD8E06526600675320FE0F526300203120F8C +:40128600EF300107C20112063F80E23008DFC20812182A80D822E5135516606AE515243AF582E43514F583E0705CE516F45213E5152426FFE43514FEE4FD0FEFAA067001C7 +:4012C6000E14F5828A83E0FC74802DF582E4347BF583ECF00DBD0BE2907FC3740BF0E515243AF582E43514F5837410F0E515242EF582E43514F583E4F0E515242FF582E423 +:401306003514F583E4F022E52845276057AE27AF28D3EF9440EE940040047E007F40C3E5289FF528E5279EF527E4FDEDC39FE49E501F853482853383E0FC74002DF582E4BA +:40134600347FF583ECF00D0534E5347002053380DA907FA97401F0907FACE04401F0907FB5EFF022907FACE054FEF0E4907FB5F022907F98740FF0E490784AF0907F94F0E1 +:40138600907F9D74FFF0E4907F97F0907841F0907F93F0907F9C74FFF0300007E529540FFF80027F00907F96EFF0907F98741FF0E4907F95F0907F9E743FF0907F9874DFAD +:4013C600F0907F92E054FDF0228F19052DE52DAE2C7002052C14F5828E83E519F01218EF052DE52DAC2C7002052C14F5828C83EFF01523E523601FE5152438F582E4351416 +:40140600F583C083C082E0FE1218D38F19EE4FD082D083F080B522907841E511F090784F74C0F0E4907850F0E52C907851F0AE2CE52D907852F0907854E523F09078577470 +:4014460004F0907FE2E04410F0E054F7F0E4907855F0907855E060FA228F19E4F51A751BFF751C19751D86AB1BAA1CA91D9000011211BFB4031DAF1A051AEFB519012212F9 +:4014860011A67E0029FFEE3AA907751BFFF51C891D80D47B007A00790022907841E511F0E52C90784FF0AE2CE52D907850F090785174C0F0E4907852F0907854E523F0907D +:4014C60078577404F0E4907855F0907855E060FA22E5152404F582E43514F583E014600F1460131460178000907FC7EFF08013907FC9EFF0800C907FCBEFF08005907FCDED +:40150600EFF0E516422A22E5152404F582E43514F583E014600F1460131460178000907FB7EFF08013907FB9EFF0800C907FBBEFF08005907FBDEFF0E516422A22AE07E4A4 +:40154600FFE5152432F582E43514F583E0547FFD12166B90784174F1F090C000EEF0E4E5152432F582E43514F583E04480FD12166B22C0E0C0F0C083C082C085C084C086A1 +:40158600758600C0D075D0085391EF907FA97401F012130DD0D0D086D084D085D082D083D0F0D0E03290784174F3F090C00074BFF090784174F1F090C000EFF090784174A8 +:4015C600F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F090C00074BFF090784174F2F090C000EFF090784174F3F0E5152437F582E43514F583E0547FD7 +:4016060090C000F02290784174F3F090C00074BFF090784174F4F090C000EFF090784174F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F090C00074BF16 +:40164600F090784174F6F090C000EFF090784174F3F0E5152437F582E43514F583E0547F90C000F02290784174F3F0E5152437F582E43514F583E0547F90C000F09078412F +:4016860074F7F090C000EFF090784174F5F090C000EDF022E5152404F582E43514F583E014600E1460111460148000907FC6E0FF22907FC8E0FF22907FCAE0FF22907FCC19 +:4016C600E0FF22E5152404F582E43514F583E014600E1460111460148000907FB6E0FF22907FB8E0FF22907FBAE0FF22907FBCE0FF22E5152404F582E43514F583E0146000 +:401706000E1460111460148000907FC7E0FF22907FC9E0FF22907FCBE0FF22907FCDE0FF22C0E0C083C082C085C084C086758600907FC4E4F05391EF907FAB7404F0D086BF +:40174600D084D085D082D083D0E032907B41E0F536431310A3E06009907FD77417F07437F0907B43E0F537A3E054F0F529E06002D20A22C0E0C083C082C085C084C08675A6 +:401786008600D2015391EF907FAB7401F0D086D084D085D082D083D0E032C0E0C083C082C085C084C086758600D2085391EF907FAB7408F0D086D084D085D082D083D0E03C +:4017C600321218B7AE071218B7AD07EE6D60101218B7AE07EE6D60071218B7AD0780ECAF06227400F58690FDA57C05A3E582458370F922907FD6E04480F043870100000048 +:40180600000022907FD6E04404F0E04408F0300B04E04402F07FF47E01121860907FD6E054F7F0221213771217F9907FD6E030E70A7F057E00121860121893120ACE220378 +:4018460035800000032E810000C185C181C108C100C106012200012400008E178F18E5181518AE17700215174E60081217E81217E880EB22E5152404F582E43514F583E07E +:4018860004FF4410907FD7F0EF4430F022907FD6E04401F07F0D7E00121860907FD6E054FEF022E5112402907841F090C000E0FF22E5112403907841F090C000E0FF22E597 +:4018C600112404907841F090C000E0FF22E5112405907841F090C000E0FF22E5112406907841F090C000E0FF22907841E511F090C000E0FF2253D8EF320012011001FFFFDE +:40190600FF40CD062A0100000102000409027400010100A032090400000EFF000000070501024000000705020240000007050302400000070504024000000705050240005B +:4019460000070506024000000705070240000007058102400001070582024000010705830240000107058402400001070585024000010705860240000107058702400001F3 +:401986000403090448034B00650079007300700061006E002C002000610020006400690076006900730069006F006E0020006F006600200049006E006E006F005300790040 +:4019C6007300200049006E0063002E0024034B00650079007300700061006E0020005500530041002D003400390057004C00430022035500530041002D00360035002000B5 +:401A060032003000300033006A0061006E0033003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E +:401A46000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060 +:401A86000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020 +:401AC6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002177900021B31 +:151B06000400021727000217A000021B1000021B1400021578E0 +:00000001FF + + The firmware contained herein is + + Copyright (C) 1999-2003 + Keyspan, A division of InnoSys Incorporated ("Keyspan") + + as an unpublished work. This notice does not imply unrestricted or + public access to the source code from which this firmware image is + derived. Except as noted below this firmware image may not be + reproduced, used, sold or transferred to any third party without + Keyspan's prior written consent. All Rights Reserved. + + Permission is hereby granted for the distribution of this firmware + image as part of a Linux or other Open Source operating system kernel + in text or binary form as required. + + This firmware may not be modified and may only be used with + Keyspan hardware. Distribution and/or Modification of the + keyspan.c driver which includes this firmware, in whole or in + part, requires the inclusion of this statement." + +static char theFirmwareDate49[] = + "02/14/2002 02:37p 19,347 USA49"; + +static char theFirmwareDate65[] = + "01/31/2003 09:34a 19,331 USA65"; + -- cgit v0.10.2 From 3edbf98b863391bdd7ad2bf47b7db1689afac886 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 15:15:13 +0300 Subject: keyspan_pda: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/usb/serial/keyspan_pda.S b/drivers/usb/serial/keyspan_pda.S deleted file mode 100644 index 418fe69..0000000 --- a/drivers/usb/serial/keyspan_pda.S +++ /dev/null @@ -1,1124 +0,0 @@ -/* $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $ - * - * Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on - * the EzUSB microcontroller. - * - * (C) Copyright 2000 Brian Warner - * - * 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. - * - * "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the - * company. - * - * This serial adapter is basically an EzUSB chip and an RS-232 line driver - * in a little widget that has a DB-9 on one end and a USB plug on the other. - * It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2 - * as a baud-rate generator. The wiring is: - * PC0/RxD0 <- rxd (DB9 pin 2) PC4 <- dsr pin 6 - * PC1/TxD0 -> txd pin 3 PC5 <- ri pin 9 - * PC2 -> rts pin 7 PC6 <- dcd pin 1 - * PC3 <- cts pin 8 PC7 -> dtr pin 4 - * PB1 -> line driver standby - * - * The EzUSB register constants below come from their excellent documentation - * and sample code (which used to be available at www.anchorchips.com, but - * that has now been absorbed into Cypress' site and the CD-ROM contents - * don't appear to be available online anymore). If we get multiple - * EzUSB-based drivers into the kernel, it might be useful to pull them out - * into a separate .h file. - * - * THEORY OF OPERATION: - * - * There are two 256-byte ring buffers, one for tx, one for rx. - * - * EP2out is pure tx data. When it appears, the data is copied into the tx - * ring and serial transmission is started if it wasn't already running. The - * "tx buffer empty" interrupt may kick off another character if the ring - * still has data. If the host is tx-blocked because the ring filled up, - * it will request a "tx unthrottle" interrupt. If sending a serial character - * empties the ring below the desired threshold, we set a bit that will send - * up the tx unthrottle message as soon as the rx buffer becomes free. - * - * EP2in (interrupt) is used to send both rx chars and rx status messages - * (only "tx unthrottle" at this time) back up to the host. The first byte - * of the rx message indicates data (0) or status msg (1). Status messages - * are sent before any data. - * - * Incoming serial characters are put into the rx ring by the serial - * interrupt, and the EP2in buffer sent if it wasn't already in transit. - * When the EP2in buffer returns, the interrupt prompts us to send more - * rx chars (or status messages) if they are pending. - * - * Device control happens through "vendor specific" control messages on EP0. - * All messages are destined for the "Interface" (with the index always 0, - * so that if their two-port device might someday use similar firmware, we - * can use index=1 to refer to the second port). The messages defined are: - * - * bRequest = 0 : set baud/bits/parity - * 1 : unused - * 2 : reserved for setting HW flow control (CTSRTS) - * 3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc) - * 4 : set break (on/off) - * 5 : reserved for requesting interrupts on pin state change - * 6 : query buffer room or chars in tx buffer - * 7 : request tx unthrottle interrupt - * - * The host-side driver is set to recognize the device ID values stashed in - * serial EEPROM (0x06cd, 0x0103), program this firmware into place, then - * start it running. This firmware will use EzUSB's "renumeration" trick by - * simulating a bus disconnect, then reconnect with a different device ID - * (encoded in the desc_device descriptor below). The host driver then - * recognizes the new device ID and glues it to the real serial driver code. - * - * USEFUL DOCS: - * EzUSB Technical Reference Manual: - * 8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is - * basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports - * use totally different registers! - * USB 1.1 spec: www.usb.org - * - * HOW TO BUILD: - * gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s - * as31 -l keyspan_pda.asm - * mv keyspan_pda.obj keyspan_pda.hex - * perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h - * Get as31 from , and hack on it - * a bit to make it build. - * - * THANKS: - * Greg Kroah-Hartman, for coordinating the whole usb-serial thing. - * AnchorChips, for making such an incredibly useful little microcontroller. - * KeySpan, for making a handy, cheap ($40) widget that was so easy to take - * apart and trace with an ohmmeter. - * - * TODO: - * lots. grep for TODO. Interrupt safety needs stress-testing. Better flow - * control. Interrupting host upon change in DCD, etc, counting transitions. - * Need to find a safe device id to use (the one used by the Keyspan firmware - * under Windows would be ideal.. can anyone figure out what it is?). Parity. - * More baud rates. Oh, and the string-descriptor-length silicon bug - * workaround should be implemented, but I'm lazy, and the consequence is - * that the device name strings that show up in your kernel log will have - * lots of trailing binary garbage in them (appears as ????). Device strings - * should be made more accurate. - * - * Questions, bugs, patches to Brian. - * - * -Brian Warner - * - */ - -#define HIGH(x) (((x) & 0xff00) / 256) -#define LOW(x) ((x) & 0xff) - -#define dpl1 0x84 -#define dph1 0x85 -#define dps 0x86 - -;;; our bit assignments -#define TX_RUNNING 0 -#define DO_TX_UNTHROTTLE 1 - - ;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60 -#define STACK #0x60-1 - -#define EXIF 0x91 -#define EIE 0xe8 - .flag EUSB, EIE.0 - .flag ES0, IE.4 - -#define EP0CS #0x7fb4 -#define EP0STALLbit #0x01 -#define IN0BUF #0x7f00 -#define IN0BC #0x7fb5 -#define OUT0BUF #0x7ec0 -#define OUT0BC #0x7fc5 -#define IN2BUF #0x7e00 -#define IN2BC #0x7fb9 -#define IN2CS #0x7fb8 -#define OUT2BC #0x7fc9 -#define OUT2CS #0x7fc8 -#define OUT2BUF #0x7dc0 -#define IN4BUF #0x7d00 -#define IN4BC #0x7fbd -#define IN4CS #0x7fbc -#define OEB #0x7f9d -#define OUTB #0x7f97 -#define OEC #0x7f9e -#define OUTC #0x7f98 -#define PINSC #0x7f9b -#define PORTCCFG #0x7f95 -#define IN07IRQ #0x7fa9 -#define OUT07IRQ #0x7faa -#define IN07IEN #0x7fac -#define OUT07IEN #0x7fad -#define USBIRQ #0x7fab -#define USBIEN #0x7fae -#define USBBAV #0x7faf -#define USBCS #0x7fd6 -#define SUDPTRH #0x7fd4 -#define SUDPTRL #0x7fd5 -#define SETUPDAT #0x7fe8 - - ;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91) - - .org 0 - ljmp start - ;; interrupt vectors - .org 23H - ljmp serial_int - .byte 0 - - .org 43H - ljmp USB_Jump_Table - .byte 0 ; filled in by the USB core - -;;; local variables. These are not initialized properly: do it by hand. - .org 30H -rx_ring_in: .byte 0 -rx_ring_out: .byte 0 -tx_ring_in: .byte 0 -tx_ring_out: .byte 0 -tx_unthrottle_threshold: .byte 0 - - .org 0x100H ; wants to be on a page boundary -USB_Jump_Table: - ljmp ISR_Sudav ; Setup Data Available - .byte 0 - ljmp 0 ; Start of Frame - .byte 0 - ljmp 0 ; Setup Data Loading - .byte 0 - ljmp 0 ; Global Suspend - .byte 0 - ljmp 0 ; USB Reset - .byte 0 - ljmp 0 ; Reserved - .byte 0 - ljmp 0 ; End Point 0 In - .byte 0 - ljmp 0 ; End Point 0 Out - .byte 0 - ljmp 0 ; End Point 1 In - .byte 0 - ljmp 0 ; End Point 1 Out - .byte 0 - ljmp ISR_Ep2in - .byte 0 - ljmp ISR_Ep2out - .byte 0 - - - .org 0x200 - -start: mov SP,STACK-1 ; set stack - ;; clear local variables - clr a - mov tx_ring_in, a - mov tx_ring_out, a - mov rx_ring_in, a - mov rx_ring_out, a - mov tx_unthrottle_threshold, a - clr TX_RUNNING - clr DO_TX_UNTHROTTLE - - ;; clear fifo with "fe" - mov r1, 0 - mov a, #0xfe - mov dptr, #tx_ring -clear_tx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_tx_ring_loop - - mov a, #0xfd - mov dptr, #rx_ring -clear_rx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_rx_ring_loop - -;;; turn on the RS-232 driver chip (bring the STANDBY pin low) - ;; set OEB.1 - mov a, #02H - mov dptr,OEB - movx @dptr,a - ;; clear PB1 - mov a, #00H - mov dptr,OUTB - movx @dptr,a - ;; set OEC.[127] - mov a, #0x86 - mov dptr,OEC - movx @dptr,a - ;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port - mov dptr, PORTCCFG - mov a, #0x03 - movx @dptr, a - - ;; set up interrupts, autovectoring - mov dptr, USBBAV - movx a,@dptr - setb acc.0 ; AVEN bit to 0 - movx @dptr, a - - mov a,#0x01 ; enable SUDAV: setup data available (for ep0) - mov dptr, USBIRQ - movx @dptr, a ; clear SUDAVI - mov dptr, USBIEN - movx @dptr, a - - mov dptr, IN07IEN - mov a,#0x04 ; enable IN2 int - movx @dptr, a - - mov dptr, OUT07IEN - mov a,#0x04 ; enable OUT2 int - movx @dptr, a - mov dptr, OUT2BC - movx @dptr, a ; arm OUT2 - - mov a, #0x84 ; turn on RTS, DTR - mov dptr,OUTC - movx @dptr, a - ;; setup the serial port. 9600 8N1. - mov a,#01010011 ; mode 1, enable rx, clear int - mov SCON, a - ;; using timer2, in 16-bit baud-rate-generator mode - ;; (xtal 12MHz, internal fosc 24MHz) - ;; RCAP2H,RCAP2L = 65536 - fosc/(32*baud) - ;; 57600: 0xFFF2.F, say 0xFFF3 - ;; 9600: 0xFFB1.E, say 0xFFB2 - ;; 300: 0xF63C -#define BAUD 9600 -#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate)) -#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate)) -#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate)) - - mov T2CON, #030h ; rclk=1,tclk=1,cp=0,tr2=0(enable later) - mov r3, #5 - acall set_baud - setb TR2 - mov SCON, #050h - -#if 0 - mov r1, #0x40 - mov a, #0x41 -send: - mov SBUF, a - inc a - anl a, #0x3F - orl a, #0x40 -; xrl a, #0x02 -wait1: - jnb TI, wait1 - clr TI - djnz r1, send -;done: sjmp done - -#endif - - setb EUSB - setb EA - setb ES0 - ;acall dump_stat - - ;; hey, what say we RENUMERATE! (TRM p.62) - mov a, #0 - mov dps, a - mov dptr, USBCS - mov a, #0x02 ; DISCON=0, DISCOE=0, RENUM=1 - movx @dptr, a - ;; now presence pin is floating, simulating disconnect. wait 0.5s - mov r1, #46 -renum_wait1: - mov r2, #0 -renum_wait2: - mov r3, #0 -renum_wait3: - djnz r3, renum_wait3 - djnz r2, renum_wait2 - djnz r1, renum_wait1 ; wait about n*(256^2) 6MHz clocks - mov a, #0x06 ; DISCON=0, DISCOE=1, RENUM=1 - movx @dptr, a - ;; we are back online. the host device will now re-query us - - -main: sjmp main - - - -ISR_Sudav: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, USBIRQ ; clear USB int - mov a,#01h - movx @dptr,a - - ;; get request type - mov dptr, SETUPDAT - movx a, @dptr - mov r1, a ; r1 = bmRequestType - inc dptr - movx a, @dptr - mov r2, a ; r2 = bRequest - inc dptr - movx a, @dptr - mov r3, a ; r3 = wValueL - inc dptr - movx a, @dptr - mov r4, a ; r4 = wValueH - - ;; main switch on bmRequest.type: standard or vendor - mov a, r1 - anl a, #0x60 - cjne a, #0x00, setup_bmreq_type_not_standard - ;; standard request: now main switch is on bRequest - ljmp setup_bmreq_is_standard - -setup_bmreq_type_not_standard: - ;; a still has bmreq&0x60 - cjne a, #0x40, setup_bmreq_type_not_vendor - ;; Anchor reserves bRequest 0xa0-0xaf, we use small ones - ;; switch on bRequest. bmRequest will always be 0x41 or 0xc1 - cjne r2, #0x00, setup_ctrl_not_00 - ;; 00 is set baud, wValue[0] has baud rate index - lcall set_baud ; index in r3, carry set if error - jc setup_bmreq_type_not_standard__do_stall - ljmp setup_done_ack -setup_bmreq_type_not_standard__do_stall: - ljmp setup_stall -setup_ctrl_not_00: - cjne r2, #0x01, setup_ctrl_not_01 - ;; 01 is reserved for set bits (parity). TODO - ljmp setup_stall -setup_ctrl_not_01: - cjne r2, #0x02, setup_ctrl_not_02 - ;; 02 is set HW flow control. TODO - ljmp setup_stall -setup_ctrl_not_02: - cjne r2, #0x03, setup_ctrl_not_03 - ;; 03 is control pins (RTS, DTR). - ljmp control_pins ; will jump to setup_done_ack, - ; or setup_return_one_byte -setup_ctrl_not_03: - cjne r2, #0x04, setup_ctrl_not_04 - ;; 04 is send break (really "turn break on/off"). TODO - cjne r3, #0x00, setup_ctrl_do_break_on - ;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port - mov dptr, PORTCCFG - movx a, @dptr - orl a, #0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_do_break_on: - ;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low) - mov dptr, OUTC - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - mov dptr, PORTCCFG - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_not_04: - cjne r2, #0x05, setup_ctrl_not_05 - ;; 05 is set desired interrupt bitmap. TODO - ljmp setup_stall -setup_ctrl_not_05: - cjne r2, #0x06, setup_ctrl_not_06 - ;; 06 is query room - cjne r3, #0x00, setup_ctrl_06_not_00 - ;; 06, wValue[0]=0 is query write_room - mov a, tx_ring_out - setb c - subb a, tx_ring_in ; out-1-in = 255 - (in-out) - ljmp setup_return_one_byte -setup_ctrl_06_not_00: - cjne r3, #0x01, setup_ctrl_06_not_01 - ;; 06, wValue[0]=1 is query chars_in_buffer - mov a, tx_ring_in - clr c - subb a, tx_ring_out ; in-out - ljmp setup_return_one_byte -setup_ctrl_06_not_01: - ljmp setup_stall -setup_ctrl_not_06: - cjne r2, #0x07, setup_ctrl_not_07 - ;; 07 is request tx unthrottle interrupt - mov tx_unthrottle_threshold, r3; wValue[0] is threshold value - ljmp setup_done_ack -setup_ctrl_not_07: - ljmp setup_stall - -setup_bmreq_type_not_vendor: - ljmp setup_stall - - -setup_bmreq_is_standard: - cjne r2, #0x00, setup_breq_not_00 - ;; 00: Get_Status (sub-switch on bmRequestType: device, ep, int) - cjne r1, #0x80, setup_Get_Status_not_device - ;; Get_Status(device) - ;; are we self-powered? no. can we do remote wakeup? no - ;; so return two zero bytes. This is reusable -setup_return_two_zero_bytes: - mov dptr, IN0BUF - clr a - movx @dptr, a - inc dptr - movx @dptr, a - mov dptr, IN0BC - mov a, #2 - movx @dptr, a - ljmp setup_done_ack -setup_Get_Status_not_device: - cjne r1, #0x82, setup_Get_Status_not_endpoint - ;; Get_Status(endpoint) - ;; must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0 - ;; for now: cheat. TODO - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_endpoint: - cjne r1, #0x81, setup_Get_Status_not_interface - ;; Get_Status(interface): return two zeros - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_interface: - ljmp setup_stall - -setup_breq_not_00: - cjne r2, #0x01, setup_breq_not_01 - ;; 01: Clear_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Clear_Feature_not_stall - ;; Clear_Feature(stall). should clear a stall bit. TODO - ljmp setup_stall -setup_Clear_Feature_not_stall: - cjne r3, #0x01, setup_Clear_Feature_not_rwake - ;; Clear_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Clear_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_01: - cjne r2, #0x03, setup_breq_not_03 - ;; 03: Set_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Set_Feature_not_stall - ;; Set_Feature(stall). Should set a stall bit. TODO - ljmp setup_stall -setup_Set_Feature_not_stall: - cjne r3, #0x01, setup_Set_Feature_not_rwake - ;; Set_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Set_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_03: - cjne r2, #0x06, setup_breq_not_06 - ;; 06: Get_Descriptor (s-switch on wValueH: dev, config[n], string[n]) - cjne r4, #0x01, setup_Get_Descriptor_not_device - ;; Get_Descriptor(device) - mov dptr, SUDPTRH - mov a, #HIGH(desc_device) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_device) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_device: - cjne r4, #0x02, setup_Get_Descriptor_not_config - ;; Get_Descriptor(config[n]) - cjne r3, #0x00, setup_stall; only handle n==0 - ;; Get_Descriptor(config[0]) - mov dptr, SUDPTRH - mov a, #HIGH(desc_config1) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_config1) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_config: - cjne r4, #0x03, setup_Get_Descriptor_not_string - ;; Get_Descriptor(string[wValueL]) - ;; if (wValueL >= maxstrings) stall - mov a, #((desc_strings_end-desc_strings)/2) - clr c - subb a,r3 ; a=4, r3 = 0..3 . if a<=0 then stall - jc setup_stall - jz setup_stall - mov a, r3 - add a, r3 ; a = 2*wValueL - mov dptr, #desc_strings - add a, dpl - mov dpl, a - mov a, #0 - addc a, dph - mov dph, a ; dph = desc_strings[a]. big endian! (handy) - ;; it looks like my adapter uses a revision of the EZUSB that - ;; contains "rev D errata number 8", as hinted in the EzUSB example - ;; code. I cannot find an actual errata description on the Cypress - ;; web site, but from the example code it looks like this bug causes - ;; the length of string descriptors to be read incorrectly, possibly - ;; sending back more characters than the descriptor has. The workaround - ;; is to manually send out all of the data. The consequence of not - ;; using the workaround is that the strings gathered by the kernel - ;; driver are too long and are filled with trailing garbage (including - ;; leftover strings). Writing this out by hand is a nuisance, so for - ;; now I will just live with the bug. - movx a, @dptr - mov r1, a - inc dptr - movx a, @dptr - mov r2, a - mov dptr, SUDPTRH - mov a, r1 - movx @dptr, a - mov dptr, SUDPTRL - mov a, r2 - movx @dptr, a - ;; done - ljmp setup_done_ack - -setup_Get_Descriptor_not_string: - ljmp setup_stall - -setup_breq_not_06: - cjne r2, #0x08, setup_breq_not_08 - ;; Get_Configuration. always 1. return one byte. - ;; this is reusable - mov a, #1 -setup_return_one_byte: - mov dptr, IN0BUF - movx @dptr, a - mov a, #1 - mov dptr, IN0BC - movx @dptr, a - ljmp setup_done_ack -setup_breq_not_08: - cjne r2, #0x09, setup_breq_not_09 - ;; 09: Set_Configuration. ignored. - ljmp setup_done_ack -setup_breq_not_09: - cjne r2, #0x0a, setup_breq_not_0a - ;; 0a: Get_Interface. get the current altsetting for int[wIndexL] - ;; since we only have one interface, ignore wIndexL, return a 0 - mov a, #0 - ljmp setup_return_one_byte -setup_breq_not_0a: - cjne r2, #0x0b, setup_breq_not_0b - ;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored - ljmp setup_done_ack -setup_breq_not_0b: - ljmp setup_stall - - -setup_done_ack: - ;; now clear HSNAK - mov dptr, EP0CS - mov a, #0x02 - movx @dptr, a - sjmp setup_done -setup_stall: - ;; unhandled. STALL - ;EP0CS |= bmEPSTALL - mov dptr, EP0CS - movx a, @dptr - orl a, EP0STALLbit - movx @dptr, a - sjmp setup_done - -setup_done: - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -;;; ============================================================== - -set_baud: ; baud index in r3 - ;; verify a < 10 - mov a, r3 - jb ACC.7, set_baud__badbaud - clr c - subb a, #10 - jnc set_baud__badbaud - mov a, r3 - rl a ; a = index*2 - add a, #LOW(baud_table) - mov dpl, a - mov a, #HIGH(baud_table) - addc a, #0 - mov dph, a - ;; TODO: shut down xmit/receive - ;; TODO: wait for current xmit char to leave - ;; TODO: shut down timer to avoid partial-char glitch - movx a,@dptr ; BAUD_HIGH - mov RCAP2H, a - mov TH2, a - inc dptr - movx a,@dptr ; BAUD_LOW - mov RCAP2L, a - mov TL2, a - ;; TODO: restart xmit/receive - ;; TODO: reenable interrupts, resume tx if pending - clr c ; c=0: success - ret -set_baud__badbaud: - setb c ; c=1: failure - ret - -;;; ================================================== -control_pins: - cjne r1, #0x41, control_pins_in -control_pins_out: - mov a, r3 ; wValue[0] holds new bits: b7 is new DTR, b2 is new RTS - xrl a, #0xff ; 1 means active, 0V, +12V ? - anl a, #0x84 - mov r3, a - mov dptr, OUTC - movx a, @dptr ; only change bits 7 and 2 - anl a, #0x7b ; ~0x84 - orl a, r3 - movx @dptr, a ; other pins are inputs, bits ignored - ljmp setup_done_ack -control_pins_in: - mov dptr, PINSC - movx a, @dptr - xrl a, #0xff - ljmp setup_return_one_byte - -;;; ======================================== - -ISR_Ep2in: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, IN07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - ;; do stuff - lcall start_in - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -ISR_Ep2out: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, OUT07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - ;; do stuff - - ;; copy data into buffer. for now, assume we will have enough space - mov dptr, OUT2BC ; get byte count - movx a,@dptr - mov r1, a - clr a - mov dps, a - mov dptr, OUT2BUF ; load DPTR0 with source - mov dph1, #HIGH(tx_ring) ; load DPTR1 with target - mov dpl1, tx_ring_in -OUT_loop: - movx a,@dptr ; read - inc dps ; switch to DPTR1: target - inc dpl1 ; target = tx_ring_in+1 - movx @dptr,a ; store - mov a,dpl1 - cjne a, tx_ring_out, OUT_no_overflow - sjmp OUT_overflow -OUT_no_overflow: - inc tx_ring_in ; tx_ring_in++ - inc dps ; switch to DPTR0: source - inc dptr - djnz r1, OUT_loop - sjmp OUT_done -OUT_overflow: - ;; signal overflow - ;; fall through -OUT_done: - ;; ack - mov dptr,OUT2BC - movx @dptr,a - - ;; start tx - acall maybe_start_tx - ;acall dump_stat - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -dump_stat: - ;; fill in EP4in with a debugging message: - ;; tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out - ;; tx_active - ;; tx_ring[0..15] - ;; 0xfc - ;; rx_ring[0..15] - clr a - mov dps, a - - mov dptr, IN4CS - movx a, @dptr - jb acc.1, dump_stat__done; busy: cannot dump, old one still pending - mov dptr, IN4BUF - - mov a, tx_ring_in - movx @dptr, a - inc dptr - mov a, tx_ring_out - movx @dptr, a - inc dptr - - mov a, rx_ring_in - movx @dptr, a - inc dptr - mov a, rx_ring_out - movx @dptr, a - inc dptr - - clr a - jnb TX_RUNNING, dump_stat__no_tx_running - inc a -dump_stat__no_tx_running: - movx @dptr, a - inc dptr - ;; tx_ring[0..15] - inc dps - mov dptr, #tx_ring ; DPTR1: source - mov r1, #16 -dump_stat__tx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__tx_ring_loop - inc dps - - mov a, #0xfc - movx @dptr, a - inc dptr - - ;; rx_ring[0..15] - inc dps - mov dptr, #rx_ring ; DPTR1: source - mov r1, #16 -dump_stat__rx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__rx_ring_loop - - ;; now send it - clr a - mov dps, a - mov dptr, IN4BC - mov a, #38 - movx @dptr, a -dump_stat__done: - ret - -;;; ============================================================ - -maybe_start_tx: - ;; make sure the tx process is running. - jb TX_RUNNING, start_tx_done -start_tx: - ;; is there work to be done? - mov a, tx_ring_in - cjne a,tx_ring_out, start_tx__work - ret ; no work -start_tx__work: - ;; tx was not running. send the first character, setup the TI int - inc tx_ring_out ; [++tx_ring_out] - mov dph, #HIGH(tx_ring) - mov dpl, tx_ring_out - movx a, @dptr - mov sbuf, a - setb TX_RUNNING -start_tx_done: - ;; can we unthrottle the host tx process? - ;; step 1: do we care? - mov a, #0 - cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx - ;; nope -start_tx_really_done: - ret -start_tx__maybe_unthrottle_tx: - ;; step 2: is there now room? - mov a, tx_ring_out - setb c - subb a, tx_ring_in - ;; a is now write_room. If thresh >= a, we can unthrottle - clr c - subb a, tx_unthrottle_threshold - jc start_tx_really_done ; nope - ;; yes, we can unthrottle. remove the threshold and mark a request - mov tx_unthrottle_threshold, #0 - setb DO_TX_UNTHROTTLE - ;; prod rx, which will actually send the message when in2 becomes free - ljmp start_in - - -serial_int: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - jnb TI, serial_int__not_tx - ;; tx finished. send another character if we have one - clr TI ; clear int - clr TX_RUNNING - lcall start_tx -serial_int__not_tx: - jnb RI, serial_int__not_rx - lcall get_rx_char - clr RI ; clear int -serial_int__not_rx: - ;; return - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -get_rx_char: - mov dph, #HIGH(rx_ring) - mov dpl, rx_ring_in - inc dpl ; target = rx_ring_in+1 - mov a, sbuf - movx @dptr, a - ;; check for overflow before incrementing rx_ring_in - mov a, dpl - cjne a, rx_ring_out, get_rx_char__no_overflow - ;; signal overflow - ret -get_rx_char__no_overflow: - inc rx_ring_in - ;; kick off USB INpipe - acall start_in - ret - -start_in: - ;; check if the inpipe is already running. - mov dptr, IN2CS - movx a, @dptr - jb acc.1, start_in__done; int will handle it - jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle - ;; see if there is any work to do. a serial interrupt might occur - ;; during this sequence? - mov a, rx_ring_in - cjne a, rx_ring_out, start_in__have_work - ret ; nope -start_in__have_work: - ;; now copy as much data as possible into the pipe. 63 bytes max. - clr a - mov dps, a - mov dph, #HIGH(rx_ring) ; load DPTR0 with source - inc dps - mov dptr, IN2BUF ; load DPTR1 with target - movx @dptr, a ; in[0] signals that rest of IN is rx data - inc dptr - inc dps - ;; loop until we run out of data, or we have copied 64 bytes - mov r1, #1 ; INbuf size counter -start_in__loop: - mov a, rx_ring_in - cjne a, rx_ring_out, start_inlocal_irq_enablell_copying - sjmp start_in__kick -start_inlocal_irq_enablell_copying: - inc rx_ring_out - mov dpl, rx_ring_out - movx a, @dptr - inc dps - movx @dptr, a ; write into IN buffer - inc dptr - inc dps - inc r1 - cjne r1, #64, start_in__loop; loop -start_in__kick: - ;; either we ran out of data, or we copied 64 bytes. r1 has byte count - ;; kick off IN - mov dptr, IN2BC - mov a, r1 - jz start_in__done - movx @dptr, a - ;; done -start_in__done: - ;acall dump_stat - ret -start_in__do_tx_unthrottle: - ;; special sequence: send a tx unthrottle message - clr DO_TX_UNTHROTTLE - clr a - mov dps, a - mov dptr, IN2BUF - mov a, #1 - movx @dptr, a - inc dptr - mov a, #2 - movx @dptr, a - mov dptr, IN2BC - movx @dptr, a - ret - -putchar: - clr TI - mov SBUF, a -putchar_wait: - jnb TI, putchar_wait - clr TI - ret - - -baud_table: ; baud_high, then baud_low - ;; baud[0]: 110 - .byte BAUD_HIGH(110) - .byte BAUD_LOW(110) - ;; baud[1]: 300 - .byte BAUD_HIGH(300) - .byte BAUD_LOW(300) - ;; baud[2]: 1200 - .byte BAUD_HIGH(1200) - .byte BAUD_LOW(1200) - ;; baud[3]: 2400 - .byte BAUD_HIGH(2400) - .byte BAUD_LOW(2400) - ;; baud[4]: 4800 - .byte BAUD_HIGH(4800) - .byte BAUD_LOW(4800) - ;; baud[5]: 9600 - .byte BAUD_HIGH(9600) - .byte BAUD_LOW(9600) - ;; baud[6]: 19200 - .byte BAUD_HIGH(19200) - .byte BAUD_LOW(19200) - ;; baud[7]: 38400 - .byte BAUD_HIGH(38400) - .byte BAUD_LOW(38400) - ;; baud[8]: 57600 - .byte BAUD_HIGH(57600) - .byte BAUD_LOW(57600) - ;; baud[9]: 115200 - .byte BAUD_HIGH(115200) - .byte BAUD_LOW(115200) - -desc_device: - .byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40 - .byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01 -;;; The "real" device id, which must match the host driver, is that -;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104 - -desc_config1: - .byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32 - .byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00 - .byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01 - .byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 - -desc_strings: - .word string_langids, string_mfg, string_product, string_serial -desc_strings_end: - -string_langids: .byte string_langids_end-string_langids - .byte 3 - .word 0 -string_langids_end: - - ;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now - ;; *that* is a pain in the ass to encode. And they are little-endian - ;; too. Use this perl snippet to get the bytecodes: - /* while (<>) { - @c = split(//); - foreach $c (@c) { - printf("0x%02x, 0x00, ", ord($c)); - } - } - */ - -string_mfg: .byte string_mfg_end-string_mfg - .byte 3 -; .byte "ACME usb widgets" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00 -string_mfg_end: - -string_product: .byte string_product_end-string_product - .byte 3 -; .byte "ACME USB serial widget" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00 -string_product_end: - -string_serial: .byte string_serial_end-string_serial - .byte 3 -; .byte "47" - .byte 0x34, 0x00, 0x37, 0x00 -string_serial_end: - -;;; ring buffer memory - ;; tx_ring_in+1 is where the next input byte will go - ;; [tx_ring_out] has been sent - ;; if tx_ring_in == tx_ring_out, theres no work to do - ;; there are (tx_ring_in - tx_ring_out) chars to be written - ;; dont let _in lap _out - ;; cannot inc if tx_ring_in+1 == tx_ring_out - ;; write [tx_ring_in+1] then tx_ring_in++ - ;; if (tx_ring_in+1 == tx_ring_out), overflow - ;; else tx_ring_in++ - ;; read/send [tx_ring_out+1], then tx_ring_out++ - - ;; rx_ring_in works the same way - - .org 0x1000 -tx_ring: - .skip 0x100 ; 256 bytes -rx_ring: - .skip 0x100 ; 256 bytes - - - .END - diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index ff54203..644a1ea 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -76,18 +76,14 @@ #include #include #include +#include +#include #include #include #include static int debug; -struct ezusb_hex_record { - __u16 address; - __u8 data_size; - __u8 data[16]; -}; - /* make a simple define to handle if we are compiling keyspan_pda or xircom support */ #if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE) #define KEYSPAN @@ -100,14 +96,6 @@ struct ezusb_hex_record { #undef XIRCOM #endif -#ifdef KEYSPAN -#include "keyspan_pda_fw.h" -#endif - -#ifdef XIRCOM -#include "xircom_pgs_fw.h" -#endif - /* * Version Information */ @@ -722,38 +710,47 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp) static int keyspan_pda_fake_startup (struct usb_serial *serial) { int response; - const struct ezusb_hex_record *record = NULL; + const char *fw_name; + const struct ihex_binrec *record; + const struct firmware *fw; /* download the firmware here ... */ response = ezusb_set_reset(serial, 1); + if (0) { ; } #ifdef KEYSPAN - if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID) - record = &keyspan_pda_firmware[0]; + else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID) + fw_name = "keyspan_pda/keyspan_pda.fw"; #endif #ifdef XIRCOM - if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) || - (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID)) - record = &xircom_pgs_firmware[0]; + else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) || + (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID)) + fw_name = "keyspan_pda/xircom_pgs.fw"; #endif - if (record == NULL) { + else { err("%s: unknown vendor, aborting.", __func__); return -ENODEV; } + if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { + err("failed to load firmware \"%s\"\n", fw_name); + return -ENOENT; + } + record = (const struct ihex_binrec *)fw->data; - while(record->address != 0xffff) { - response = ezusb_writememory(serial, record->address, + while (record) { + response = ezusb_writememory(serial, be32_to_cpu(record->addr), (unsigned char *)record->data, - record->data_size, 0xa0); + be16_to_cpu(record->len), 0xa0); if (response < 0) { err("ezusb_writememory failed for Keyspan PDA " "firmware (%d %04X %p %d)", - response, - record->address, record->data, record->data_size); + response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } - record++; + record = ihex_next_binrec(record); } + release_firmware(fw); /* bring device out of reset. Renumeration will occur in a moment and the new device will bind to the real driver */ response = ezusb_set_reset(serial, 0); diff --git a/drivers/usb/serial/keyspan_pda_fw.h b/drivers/usb/serial/keyspan_pda_fw.h deleted file mode 100644 index f253acc..0000000 --- a/drivers/usb/serial/keyspan_pda_fw.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * USB Keyspan PDA Firmware - * - * Copyright (C) 1999, 2000 Brian Warner - * - * 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. - * - * Generated from keyspan_pda.s by ezusb_convert.pl - * - */ - -static const struct ezusb_hex_record keyspan_pda_firmware[] = { -{ 0x0000, 3, {0x02, 0x02, 0x00} }, -{ 0x0023, 4, {0x02, 0x05, 0x5f, 0x00} }, -{ 0x0043, 4, {0x02, 0x01, 0x00, 0x00} }, -{ 0x0030, 5, {0x00, 0x00, 0x00, 0x00, 0x00} }, -{ 0x0100, 16, {0x02, 0x02, 0x96, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} }, -{ 0x0110, 16, {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} }, -{ 0x0120, 16, {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x04, 0x61, 0x00, 0x02, 0x04, 0x89, 0x00} }, -{ 0x0200, 16, {0x75, 0x81, 0x5e, 0xe4, 0xf5, 0x32, 0xf5, 0x33, 0xf5, 0x30, 0xf5, 0x31, 0xf5, 0x34, 0xc2, 0x00} }, -{ 0x0210, 16, {0xc2, 0x01, 0xa9, 0x00, 0x74, 0xfe, 0x90, 0x10, 0x00, 0xf0, 0xa3, 0xd9, 0xfc, 0x74, 0xfd, 0x90} }, -{ 0x0220, 16, {0x11, 0x00, 0xf0, 0xa3, 0xd9, 0xfc, 0x74, 0x02, 0x90, 0x7f, 0x9d, 0xf0, 0x74, 0x00, 0x90, 0x7f} }, -{ 0x0230, 16, {0x97, 0xf0, 0x74, 0x86, 0x90, 0x7f, 0x9e, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f} }, -{ 0x0240, 16, {0xaf, 0xe0, 0xd2, 0xe0, 0xf0, 0x74, 0x01, 0x90, 0x7f, 0xab, 0xf0, 0x90, 0x7f, 0xae, 0xf0, 0x90} }, -{ 0x0250, 16, {0x7f, 0xac, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xad, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x74} }, -{ 0x0260, 16, {0x84, 0x90, 0x7f, 0x98, 0xf0, 0x74, 0x00, 0xf5, 0x98, 0x75, 0xc8, 0x30, 0x7b, 0x05, 0x91, 0x20} }, -{ 0x0270, 16, {0xd2, 0xca, 0x75, 0x98, 0x50, 0xd2, 0xe8, 0xd2, 0xaf, 0xd2, 0xac, 0x74, 0x00, 0xf5, 0x86, 0x90} }, -{ 0x0280, 16, {0x7f, 0xd6, 0x74, 0x02, 0xf0, 0x79, 0x2e, 0x7a, 0x00, 0x7b, 0x00, 0xdb, 0xfe, 0xda, 0xfa, 0xd9} }, -{ 0x0290, 16, {0xf6, 0x74, 0x06, 0xf0, 0x80, 0xfe, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85} }, -{ 0x02a0, 16, {0xc0, 0xe0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0x90, 0x7f} }, -{ 0x02b0, 16, {0xe8, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xa3, 0xe0, 0xfc, 0xe9, 0x54, 0x60, 0xb4} }, -{ 0x02c0, 16, {0x00, 0x03, 0x02, 0x03, 0x39, 0xb4, 0x40, 0x6e, 0xba, 0x00, 0x0b, 0x12, 0x04, 0x20, 0x40, 0x03} }, -{ 0x02d0, 16, {0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0xba, 0x01, 0x03, 0x02, 0x04, 0x0a, 0xba, 0x02, 0x03, 0x02} }, -{ 0x02e0, 16, {0x04, 0x0a, 0xba, 0x03, 0x03, 0x02, 0x04, 0x44, 0xba, 0x04, 0x1e, 0xbb, 0x00, 0x0a, 0x90, 0x7f} }, -{ 0x02f0, 16, {0x95, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x04, 0x02, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0x90} }, -{ 0x0300, 16, {0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x04, 0x02, 0xba, 0x05, 0x03, 0x02, 0x04, 0x0a, 0xba} }, -{ 0x0310, 16, {0x06, 0x19, 0xbb, 0x00, 0x08, 0xe5, 0x33, 0xd3, 0x95, 0x32, 0x02, 0x03, 0xde, 0xbb, 0x01, 0x08} }, -{ 0x0320, 16, {0xe5, 0x32, 0xc3, 0x95, 0x33, 0x02, 0x03, 0xde, 0x02, 0x04, 0x0a, 0xba, 0x07, 0x05, 0x8b, 0x34} }, -{ 0x0330, 16, {0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x04, 0x0a, 0xba, 0x00, 0x20, 0xb9, 0x80, 0x10, 0x90} }, -{ 0x0340, 16, {0x7f, 0x00, 0xe4, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x04, 0x02, 0xb9} }, -{ 0x0350, 16, {0x82, 0x02, 0x80, 0xeb, 0xb9, 0x81, 0x02, 0x80, 0xe6, 0x02, 0x04, 0x0a, 0xba, 0x01, 0x0f, 0xbb} }, -{ 0x0360, 16, {0x00, 0x03, 0x02, 0x04, 0x0a, 0xbb, 0x01, 0x03, 0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0xba, 0x03} }, -{ 0x0370, 16, {0x0f, 0xbb, 0x00, 0x03, 0x02, 0x04, 0x0a, 0xbb, 0x01, 0x03, 0x02, 0x04, 0x02, 0x02, 0x04, 0x0a} }, -{ 0x0380, 16, {0xba, 0x06, 0x56, 0xbc, 0x01, 0x0f, 0x90, 0x7f, 0xd4, 0x74, 0x06, 0xf0, 0x90, 0x7f, 0xd5, 0x74} }, -{ 0x0390, 16, {0x12, 0xf0, 0x02, 0x04, 0x02, 0xbc, 0x02, 0x12, 0xbb, 0x00, 0x6f, 0x90, 0x7f, 0xd4, 0x74, 0x06} }, -{ 0x03a0, 16, {0xf0, 0x90, 0x7f, 0xd5, 0x74, 0x24, 0xf0, 0x02, 0x04, 0x02, 0xbc, 0x03, 0x29, 0x74, 0x04, 0xc3} }, -{ 0x03b0, 16, {0x9b, 0x40, 0x57, 0x60, 0x55, 0xeb, 0x2b, 0x90, 0x06, 0x44, 0x25, 0x82, 0xf5, 0x82, 0x74, 0x00} }, -{ 0x03c0, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0x90, 0x7f, 0xd4, 0xe9, 0xf0, 0x90, 0x7f} }, -{ 0x03d0, 16, {0xd5, 0xea, 0xf0, 0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0xba, 0x08, 0x0f, 0x74, 0x01, 0x90, 0x7f} }, -{ 0x03e0, 16, {0x00, 0xf0, 0x74, 0x01, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x04, 0x02, 0xba, 0x09, 0x03, 0x02, 0x04} }, -{ 0x03f0, 16, {0x02, 0xba, 0x0a, 0x05, 0x74, 0x00, 0x02, 0x03, 0xde, 0xba, 0x0b, 0x03, 0x02, 0x04, 0x02, 0x02} }, -{ 0x0400, 16, {0x04, 0x0a, 0x90, 0x7f, 0xb4, 0x74, 0x02, 0xf0, 0x80, 0x09, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} }, -{ 0x0410, 16, {0xf0, 0x80, 0x00, 0xd0, 0xe0, 0xd0, 0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32} }, -{ 0x0420, 16, {0xeb, 0x20, 0xe7, 0x1e, 0xc3, 0x94, 0x0a, 0x50, 0x19, 0xeb, 0x23, 0x24, 0xfe, 0xf5, 0x82, 0x74} }, -{ 0x0430, 16, {0x05, 0x34, 0x00, 0xf5, 0x83, 0xe0, 0xf5, 0xcb, 0xf5, 0xcd, 0xa3, 0xe0, 0xf5, 0xca, 0xf5, 0xcc} }, -{ 0x0440, 16, {0xc3, 0x22, 0xd3, 0x22, 0xb9, 0x41, 0x11, 0xeb, 0x64, 0xff, 0x54, 0x84, 0xfb, 0x90, 0x7f, 0x98} }, -{ 0x0450, 16, {0xe0, 0x54, 0x7b, 0x4b, 0xf0, 0x02, 0x04, 0x02, 0x90, 0x7f, 0x9b, 0xe0, 0x64, 0xff, 0x02, 0x03} }, -{ 0x0460, 16, {0xde, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85, 0xc0, 0xe0, 0xe5, 0x91, 0xc2} }, -{ 0x0470, 16, {0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xa9, 0x74, 0x04, 0xf0, 0x12, 0x05, 0xa0, 0xd0, 0xe0, 0xd0, 0x85} }, -{ 0x0480, 16, {0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0} }, -{ 0x0490, 16, {0x84, 0xc0, 0x85, 0xc0, 0xe0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xaa, 0x74, 0x04} }, -{ 0x04a0, 16, {0xf0, 0x90, 0x7f, 0xc9, 0xe0, 0xf9, 0xe4, 0xf5, 0x86, 0x90, 0x7d, 0xc0, 0x75, 0x85, 0x10, 0x85} }, -{ 0x04b0, 16, {0x32, 0x84, 0xe0, 0x05, 0x86, 0x05, 0x84, 0xf0, 0xe5, 0x84, 0xb5, 0x33, 0x02, 0x80, 0x09, 0x05} }, -{ 0x04c0, 16, {0x32, 0x05, 0x86, 0xa3, 0xd9, 0xec, 0x80, 0x00, 0x90, 0x7f, 0xc9, 0xf0, 0xb1, 0x31, 0xd0, 0xe0} }, -{ 0x04d0, 16, {0xd0, 0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0xe4, 0xf5, 0x86, 0x90, 0x7f} }, -{ 0x04e0, 16, {0xbc, 0xe0, 0x20, 0xe1, 0x4b, 0x90, 0x7d, 0x00, 0xe5, 0x32, 0xf0, 0xa3, 0xe5, 0x33, 0xf0, 0xa3} }, -{ 0x04f0, 16, {0xe5, 0x30, 0xf0, 0xa3, 0xe5, 0x31, 0xf0, 0xa3, 0xe4, 0x30, 0x00, 0x01, 0x04, 0xf0, 0xa3, 0x05} }, -{ 0x0500, 16, {0x86, 0x90, 0x10, 0x00, 0x79, 0x10, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xd9, 0xf6} }, -{ 0x0510, 16, {0x05, 0x86, 0x74, 0xfc, 0xf0, 0xa3, 0x05, 0x86, 0x90, 0x11, 0x00, 0x79, 0x10, 0xe0, 0xa3, 0x05} }, -{ 0x0520, 16, {0x86, 0xf0, 0xa3, 0x05, 0x86, 0xd9, 0xf6, 0xe4, 0xf5, 0x86, 0x90, 0x7f, 0xbd, 0x74, 0x26, 0xf0} }, -{ 0x0530, 16, {0x22, 0x20, 0x00, 0x13, 0xe5, 0x32, 0xb5, 0x33, 0x01, 0x22, 0x05, 0x33, 0x75, 0x83, 0x10, 0x85} }, -{ 0x0540, 16, {0x33, 0x82, 0xe0, 0xf5, 0x99, 0xd2, 0x00, 0x74, 0x00, 0xb5, 0x34, 0x01, 0x22, 0xe5, 0x33, 0xd3} }, -{ 0x0550, 16, {0x95, 0x32, 0xc3, 0x95, 0x34, 0x40, 0xf5, 0x75, 0x34, 0x00, 0xd2, 0x01, 0x02, 0x05, 0xa0, 0xc0} }, -{ 0x0560, 16, {0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85, 0xc0, 0xe0, 0x30, 0x99, 0x07, 0xc2, 0x99} }, -{ 0x0570, 16, {0xc2, 0x00, 0x12, 0x05, 0x34, 0x30, 0x98, 0x05, 0x12, 0x05, 0x8a, 0xc2, 0x98, 0xd0, 0xe0, 0xd0} }, -{ 0x0580, 16, {0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0x75, 0x83, 0x11, 0x85, 0x30, 0x82} }, -{ 0x0590, 16, {0x05, 0x82, 0xe5, 0x99, 0xf0, 0xe5, 0x82, 0xb5, 0x31, 0x01, 0x22, 0x05, 0x30, 0xb1, 0xa0, 0x22} }, -{ 0x05a0, 16, {0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x38, 0x20, 0x01, 0x36, 0xe5, 0x30, 0xb5, 0x31, 0x01, 0x22} }, -{ 0x05b0, 16, {0xe4, 0xf5, 0x86, 0x75, 0x83, 0x11, 0x05, 0x86, 0x90, 0x7e, 0x00, 0xf0, 0xa3, 0x05, 0x86, 0x79} }, -{ 0x05c0, 16, {0x01, 0xe5, 0x30, 0xb5, 0x31, 0x02, 0x80, 0x10, 0x05, 0x31, 0x85, 0x31, 0x82, 0xe0, 0x05, 0x86} }, -{ 0x05d0, 16, {0xf0, 0xa3, 0x05, 0x86, 0x09, 0xb9, 0x40, 0xe9, 0x90, 0x7f, 0xb9, 0xe9, 0x60, 0x01, 0xf0, 0x22} }, -{ 0x05e0, 16, {0xc2, 0x01, 0xe4, 0xf5, 0x86, 0x90, 0x7e, 0x00, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x02, 0xf0, 0x90} }, -{ 0x05f0, 16, {0x7f, 0xb9, 0xf0, 0x22, 0xc2, 0x99, 0xf5, 0x99, 0x30, 0x99, 0xfd, 0xc2, 0x99, 0x22, 0xe5, 0x5e} }, -{ 0x0600, 16, {0xf6, 0x3c, 0xfd, 0x8f, 0xfe, 0xc8, 0xff, 0x64, 0xff, 0xb2, 0xff, 0xd9, 0xff, 0xed, 0xff, 0xf3} }, -{ 0x0610, 16, {0xff, 0xfa, 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab} }, -{ 0x0620, 16, {0x01, 0x02, 0x03, 0x01, 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00} }, -{ 0x0630, 16, {0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01, 0x07, 0x05, 0x02} }, -{ 0x0640, 16, {0x02, 0x40, 0x00, 0x00, 0x06, 0x4c, 0x06, 0x50, 0x06, 0x72, 0x06, 0xa0, 0x04, 0x03, 0x00, 0x00} }, -{ 0x0650, 16, {0x22, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00} }, -{ 0x0660, 16, {0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00} }, -{ 0x0670, 16, {0x73, 0x00, 0x2e, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00} }, -{ 0x0680, 16, {0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00} }, -{ 0x0690, 16, {0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00} }, -{ 0x06a0, 6, {0x06, 0x03, 0x34, 0x00, 0x37, 0x00} }, -{ 0xffff, 0, {0x00} } -}; diff --git a/drivers/usb/serial/xircom_pgs.S b/drivers/usb/serial/xircom_pgs.S deleted file mode 100644 index 05d99dd..0000000 --- a/drivers/usb/serial/xircom_pgs.S +++ /dev/null @@ -1,1192 +0,0 @@ -/* $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $ - * - * Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on - * the EzUSB microcontroller. - * - * (C) Copyright 2000 Brian Warner - * - * 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. - * - * "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the - * company. - * - * This serial adapter is basically an EzUSB chip and an RS-232 line driver - * in a little widget that has a DB-9 on one end and a USB plug on the other. - * It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2 - * as a baud-rate generator. The wiring is: - * PC0/RxD0 <- rxd (DB9 pin 2) PC4 <- dsr pin 6 - * PC1/TxD0 -> txd pin 3 PC5 <- ri pin 9 - * PC2 -> rts pin 7 PC6 <- dcd pin 1 - * PC3 <- cts pin 8 PC7 -> dtr pin 4 - * PB1 -> line driver standby - * - * The EzUSB register constants below come from their excellent documentation - * and sample code (which used to be available at www.anchorchips.com, but - * that has now been absorbed into Cypress' site and the CD-ROM contents - * don't appear to be available online anymore). If we get multiple - * EzUSB-based drivers into the kernel, it might be useful to pull them out - * into a separate .h file. - * - * THEORY OF OPERATION: - * - * There are two 256-byte ring buffers, one for tx, one for rx. - * - * EP2out is pure tx data. When it appears, the data is copied into the tx - * ring and serial transmission is started if it wasn't already running. The - * "tx buffer empty" interrupt may kick off another character if the ring - * still has data. If the host is tx-blocked because the ring filled up, - * it will request a "tx unthrottle" interrupt. If sending a serial character - * empties the ring below the desired threshold, we set a bit that will send - * up the tx unthrottle message as soon as the rx buffer becomes free. - * - * EP2in (interrupt) is used to send both rx chars and rx status messages - * (only "tx unthrottle" at this time) back up to the host. The first byte - * of the rx message indicates data (0) or status msg (1). Status messages - * are sent before any data. - * - * Incoming serial characters are put into the rx ring by the serial - * interrupt, and the EP2in buffer sent if it wasn't already in transit. - * When the EP2in buffer returns, the interrupt prompts us to send more - * rx chars (or status messages) if they are pending. - * - * Device control happens through "vendor specific" control messages on EP0. - * All messages are destined for the "Interface" (with the index always 0, - * so that if their two-port device might someday use similar firmware, we - * can use index=1 to refer to the second port). The messages defined are: - * - * bRequest = 0 : set baud/bits/parity - * 1 : unused - * 2 : reserved for setting HW flow control (CTSRTS) - * 3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc) - * 4 : set break (on/off) - * 5 : reserved for requesting interrupts on pin state change - * 6 : query buffer room or chars in tx buffer - * 7 : request tx unthrottle interrupt - * - * The host-side driver is set to recognize the device ID values stashed in - * serial EEPROM (0x06cd, 0x0103), program this firmware into place, then - * start it running. This firmware will use EzUSB's "renumeration" trick by - * simulating a bus disconnect, then reconnect with a different device ID - * (encoded in the desc_device descriptor below). The host driver then - * recognizes the new device ID and glues it to the real serial driver code. - * - * USEFUL DOCS: - * EzUSB Technical Reference Manual: - * 8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is - * basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports - * use totally different registers! - * USB 1.1 spec: www.usb.org - * - * HOW TO BUILD: - * gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s - * as31 -l keyspan_pda.asm - * mv keyspan_pda.obj keyspan_pda.hex - * perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h - * Get as31 from , and hack on it - * a bit to make it build. - * - * THANKS: - * Greg Kroah-Hartman, for coordinating the whole usb-serial thing. - * AnchorChips, for making such an incredibly useful little microcontroller. - * KeySpan, for making a handy, cheap ($40) widget that was so easy to take - * apart and trace with an ohmmeter. - * - * TODO: - * lots. grep for TODO. Interrupt safety needs stress-testing. Better flow - * control. Interrupting host upon change in DCD, etc, counting transitions. - * Need to find a safe device id to use (the one used by the Keyspan firmware - * under Windows would be ideal.. can anyone figure out what it is?). Parity. - * More baud rates. Oh, and the string-descriptor-length silicon bug - * workaround should be implemented, but I'm lazy, and the consequence is - * that the device name strings that show up in your kernel log will have - * lots of trailing binary garbage in them (appears as ????). Device strings - * should be made more accurate. - * - * Questions, bugs, patches to Brian. - * - * -Brian Warner - * - */ - -#define HIGH(x) (((x) & 0xff00) / 256) -#define LOW(x) ((x) & 0xff) - -#define dpl1 0x84 -#define dph1 0x85 -#define dps 0x86 - -;;; our bit assignments -#define TX_RUNNING 0 -#define DO_TX_UNTHROTTLE 1 - - ;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60 -#define STACK #0x60-1 - -#define EXIF 0x91 -#define EIE 0xe8 - .flag EUSB, EIE.0 - .flag ES0, IE.4 - -#define EP0CS #0x7fb4 -#define EP0STALLbit #0x01 -#define IN0BUF #0x7f00 -#define IN0BC #0x7fb5 -#define OUT0BUF #0x7ec0 -#define OUT0BC #0x7fc5 -#define IN2BUF #0x7e00 -#define IN2BC #0x7fb9 -#define IN2CS #0x7fb8 -#define OUT2BC #0x7fc9 -#define OUT2CS #0x7fc8 -#define OUT2BUF #0x7dc0 -#define IN4BUF #0x7d00 -#define IN4BC #0x7fbd -#define IN4CS #0x7fbc -#define OEB #0x7f9d -#define OUTB #0x7f97 -#define OEC #0x7f9e -#define OUTC #0x7f98 -#define PINSC #0x7f9b -#define PORTBCFG #0x7f94 -#define PORTCCFG #0x7f95 -#define OEA #0x7f9c -#define IN07IRQ #0x7fa9 -#define OUT07IRQ #0x7faa -#define IN07IEN #0x7fac -#define OUT07IEN #0x7fad -#define USBIRQ #0x7fab -#define USBIEN #0x7fae -#define USBBAV #0x7faf -#define USBCS #0x7fd6 -#define SUDPTRH #0x7fd4 -#define SUDPTRL #0x7fd5 -#define SETUPDAT #0x7fe8 - - ;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91) - - .org 0 - ljmp start - ;; interrupt vectors - .org 23H - ljmp serial_int - .byte 0 - - .org 43H - ljmp USB_Jump_Table - .byte 0 ; filled in by the USB core - -;;; local variables. These are not initialized properly: do it by hand. - .org 30H -rx_ring_in: .byte 0 -rx_ring_out: .byte 0 -tx_ring_in: .byte 0 -tx_ring_out: .byte 0 -tx_unthrottle_threshold: .byte 0 - - .org 0x100H ; wants to be on a page boundary -USB_Jump_Table: - ljmp ISR_Sudav ; Setup Data Available - .byte 0 - ljmp 0 ; Start of Frame - .byte 0 - ljmp 0 ; Setup Data Loading - .byte 0 - ljmp 0 ; Global Suspend - .byte 0 - ljmp 0 ; USB Reset - .byte 0 - ljmp 0 ; Reserved - .byte 0 - ljmp 0 ; End Point 0 In - .byte 0 - ljmp 0 ; End Point 0 Out - .byte 0 - ljmp 0 ; End Point 1 In - .byte 0 - ljmp 0 ; End Point 1 Out - .byte 0 - ljmp ISR_Ep2in - .byte 0 - ljmp ISR_Ep2out - .byte 0 - - - .org 0x200 - -start: mov SP,STACK-1 ; set stack - ;; clear local variables - clr a - mov tx_ring_in, a - mov tx_ring_out, a - mov rx_ring_in, a - mov rx_ring_out, a - mov tx_unthrottle_threshold, a - clr TX_RUNNING - clr DO_TX_UNTHROTTLE - - ;; clear fifo with "fe" - mov r1, 0 - mov a, #0xfe - mov dptr, #tx_ring -clear_tx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_tx_ring_loop - - mov a, #0xfd - mov dptr, #rx_ring -clear_rx_ring_loop: - movx @dptr, a - inc dptr - djnz r1, clear_rx_ring_loop - -;;; turn on the RS-232 driver chip (bring the STANDBY pin low) -;;; on Xircom the STANDBY is wired to PB6 and PC4 - mov dptr, PORTBCFG - mov a, #0xBf - movx @dptr, a - mov dptr, PORTCCFG - mov a, #0xef - movx @dptr, a - - ;; set OEC.4 - mov a, #0x10 - mov dptr,OEC - movx @dptr,a - - ;; clear PC4 - mov a, #0x00 - mov dptr,OUTC - movx @dptr,a - - ;; set OEB.6 - mov a, #0x40 - mov dptr,OEB - movx @dptr,a - - ;; clear PB6 - mov a, #0x00 - mov dptr,OUTB - movx @dptr,a - - ;; set OEC.[17] - mov a, #0x82 - mov dptr,OEC - movx @dptr,a - - - ;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port - mov dptr, PORTCCFG - mov a, #0x03 - movx @dptr, a - - ;; set up interrupts, autovectoring - ;; set BKPT - mov dptr, USBBAV - movx a,@dptr - setb acc.0 ; AVEN bit to 0 - movx @dptr, a - - mov a,#0x01 ; enable SUDAV: setup data available (for ep0) - mov dptr, USBIRQ - movx @dptr, a ; clear SUDAVI - mov dptr, USBIEN - movx @dptr, a - - mov dptr, IN07IEN - mov a,#0x04 ; enable IN2 int - movx @dptr, a - - mov dptr, OUT07IEN - mov a,#0x04 ; enable OUT2 int - movx @dptr, a - mov dptr, OUT2BC - movx @dptr, a ; arm OUT2 - -;; mov a, #0x84 ; turn on RTS, DTR -;; mov dptr,OUTC -;; movx @dptr, a - - mov a, #0x7 ; turn on DTR - mov dptr,USBBAV - movx @dptr, a - - mov a, #0x20 ; turn on the RED led - mov dptr,OEA - movx @dptr, a - - mov a, #0x80 ; turn on RTS - mov dptr,OUTC - movx @dptr, a - - ;; setup the serial port. 9600 8N1. - mov a,#0x53 ; mode 1, enable rx, clear int - mov SCON, a - ;; using timer2, in 16-bit baud-rate-generator mode - ;; (xtal 12MHz, internal fosc 24MHz) - ;; RCAP2H,RCAP2L = 65536 - fosc/(32*baud) - ;; 57600: 0xFFF2.F, say 0xFFF3 - ;; 9600: 0xFFB1.E, say 0xFFB2 - ;; 300: 0xF63C -#define BAUD 9600 -#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate)) -#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate)) -#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate)) - - mov T2CON, #030h ; rclk=1,tclk=1,cp=0,tr2=0(enable later) - mov r3, #5 - acall set_baud - setb TR2 - mov SCON, #050h - -#if 0 - mov r1, #0x40 - mov a, #0x41 -send: - mov SBUF, a - inc a - anl a, #0x3F - orl a, #0x40 -; xrl a, #0x02 -wait1: - jnb TI, wait1 - clr TI - djnz r1, send -;done: sjmp done - -#endif - - setb EUSB - setb EA - setb ES0 - ;acall dump_stat - - ;; hey, what say we RENUMERATE! (TRM p.62) - mov a, #0 - mov dps, a - mov dptr, USBCS - mov a, #0x02 ; DISCON=0, DISCOE=0, RENUM=1 - movx @dptr, a - ;; now presence pin is floating, simulating disconnect. wait 0.5s - mov r1, #46 -renum_wait1: - mov r2, #0 -renum_wait2: - mov r3, #0 -renum_wait3: - djnz r3, renum_wait3 - djnz r2, renum_wait2 - djnz r1, renum_wait1 ; wait about n*(256^2) 6MHz clocks - mov a, #0x06 ; DISCON=0, DISCOE=1, RENUM=1 - movx @dptr, a - ;; we are back online. the host device will now re-query us - - -main: sjmp main - - - -ISR_Sudav: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, USBIRQ ; clear USB int - mov a,#01h - movx @dptr,a - - ;; get request type - mov dptr, SETUPDAT - movx a, @dptr - mov r1, a ; r1 = bmRequestType - inc dptr - movx a, @dptr - mov r2, a ; r2 = bRequest - inc dptr - movx a, @dptr - mov r3, a ; r3 = wValueL - inc dptr - movx a, @dptr - mov r4, a ; r4 = wValueH - - ;; main switch on bmRequest.type: standard or vendor - mov a, r1 - anl a, #0x60 - cjne a, #0x00, setup_bmreq_type_not_standard - ;; standard request: now main switch is on bRequest - ljmp setup_bmreq_is_standard - -setup_bmreq_type_not_standard: - ;; a still has bmreq&0x60 - cjne a, #0x40, setup_bmreq_type_not_vendor - ;; Anchor reserves bRequest 0xa0-0xaf, we use small ones - ;; switch on bRequest. bmRequest will always be 0x41 or 0xc1 - cjne r2, #0x00, setup_ctrl_not_00 - ;; 00 is set baud, wValue[0] has baud rate index - lcall set_baud ; index in r3, carry set if error - jc setup_bmreq_type_not_standard__do_stall - ljmp setup_done_ack -setup_bmreq_type_not_standard__do_stall: - ljmp setup_stall -setup_ctrl_not_00: - cjne r2, #0x01, setup_ctrl_not_01 - ;; 01 is reserved for set bits (parity). TODO - ljmp setup_stall -setup_ctrl_not_01: - cjne r2, #0x02, setup_ctrl_not_02 - ;; 02 is set HW flow control. TODO - ljmp setup_stall -setup_ctrl_not_02: - cjne r2, #0x03, setup_ctrl_not_03 - ;; 03 is control pins (RTS, DTR). - ljmp control_pins ; will jump to setup_done_ack, - ; or setup_return_one_byte -setup_ctrl_not_03: - cjne r2, #0x04, setup_ctrl_not_04 - ;; 04 is send break (really "turn break on/off"). TODO - cjne r3, #0x00, setup_ctrl_do_break_on - ;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port - mov dptr, PORTCCFG - movx a, @dptr - orl a, #0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_do_break_on: - ;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low) - mov dptr, OUTC - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - mov dptr, PORTCCFG - movx a, @dptr - anl a, #0xfd ; ~0x02 - movx @dptr, a - ljmp setup_done_ack -setup_ctrl_not_04: - cjne r2, #0x05, setup_ctrl_not_05 - ;; 05 is set desired interrupt bitmap. TODO - ljmp setup_stall -setup_ctrl_not_05: - cjne r2, #0x06, setup_ctrl_not_06 - ;; 06 is query room - cjne r3, #0x00, setup_ctrl_06_not_00 - ;; 06, wValue[0]=0 is query write_room - mov a, tx_ring_out - setb c - subb a, tx_ring_in ; out-1-in = 255 - (in-out) - ljmp setup_return_one_byte -setup_ctrl_06_not_00: - cjne r3, #0x01, setup_ctrl_06_not_01 - ;; 06, wValue[0]=1 is query chars_in_buffer - mov a, tx_ring_in - clr c - subb a, tx_ring_out ; in-out - ljmp setup_return_one_byte -setup_ctrl_06_not_01: - ljmp setup_stall -setup_ctrl_not_06: - cjne r2, #0x07, setup_ctrl_not_07 - ;; 07 is request tx unthrottle interrupt - mov tx_unthrottle_threshold, r3; wValue[0] is threshold value - ljmp setup_done_ack -setup_ctrl_not_07: - ljmp setup_stall - -setup_bmreq_type_not_vendor: - ljmp setup_stall - - -setup_bmreq_is_standard: - cjne r2, #0x00, setup_breq_not_00 - ;; 00: Get_Status (sub-switch on bmRequestType: device, ep, int) - cjne r1, #0x80, setup_Get_Status_not_device - ;; Get_Status(device) - ;; are we self-powered? no. can we do remote wakeup? no - ;; so return two zero bytes. This is reusable -setup_return_two_zero_bytes: - mov dptr, IN0BUF - clr a - movx @dptr, a - inc dptr - movx @dptr, a - mov dptr, IN0BC - mov a, #2 - movx @dptr, a - ljmp setup_done_ack -setup_Get_Status_not_device: - cjne r1, #0x82, setup_Get_Status_not_endpoint - ;; Get_Status(endpoint) - ;; must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0 - ;; for now: cheat. TODO - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_endpoint: - cjne r1, #0x81, setup_Get_Status_not_interface - ;; Get_Status(interface): return two zeros - sjmp setup_return_two_zero_bytes -setup_Get_Status_not_interface: - ljmp setup_stall - -setup_breq_not_00: - cjne r2, #0x01, setup_breq_not_01 - ;; 01: Clear_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Clear_Feature_not_stall - ;; Clear_Feature(stall). should clear a stall bit. TODO - ljmp setup_stall -setup_Clear_Feature_not_stall: - cjne r3, #0x01, setup_Clear_Feature_not_rwake - ;; Clear_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Clear_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_01: - cjne r2, #0x03, setup_breq_not_03 - ;; 03: Set_Feature (sub-switch on wValueL: stall, remote wakeup) - cjne r3, #0x00, setup_Set_Feature_not_stall - ;; Set_Feature(stall). Should set a stall bit. TODO - ljmp setup_stall -setup_Set_Feature_not_stall: - cjne r3, #0x01, setup_Set_Feature_not_rwake - ;; Set_Feature(remote wakeup). ignored. - ljmp setup_done_ack -setup_Set_Feature_not_rwake: - ljmp setup_stall - -setup_breq_not_03: - cjne r2, #0x06, setup_breq_not_06 - ;; 06: Get_Descriptor (s-switch on wValueH: dev, config[n], string[n]) - cjne r4, #0x01, setup_Get_Descriptor_not_device - ;; Get_Descriptor(device) - mov dptr, SUDPTRH - mov a, #HIGH(desc_device) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_device) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_device: - cjne r4, #0x02, setup_Get_Descriptor_not_config - ;; Get_Descriptor(config[n]) - cjne r3, #0x00, setup_stall; only handle n==0 - ;; Get_Descriptor(config[0]) - mov dptr, SUDPTRH - mov a, #HIGH(desc_config1) - movx @dptr, a - mov dptr, SUDPTRL - mov a, #LOW(desc_config1) - movx @dptr, a - ljmp setup_done_ack -setup_Get_Descriptor_not_config: - cjne r4, #0x03, setup_Get_Descriptor_not_string - ;; Get_Descriptor(string[wValueL]) - ;; if (wValueL >= maxstrings) stall - mov a, #((desc_strings_end-desc_strings)/2) - clr c - subb a,r3 ; a=4, r3 = 0..3 . if a<=0 then stall - jc setup_stall - jz setup_stall - mov a, r3 - add a, r3 ; a = 2*wValueL - mov dptr, #desc_strings - add a, dpl - mov dpl, a - mov a, #0 - addc a, dph - mov dph, a ; dph = desc_strings[a]. big endian! (handy) - ;; it looks like my adapter uses a revision of the EZUSB that - ;; contains "rev D errata number 8", as hinted in the EzUSB example - ;; code. I cannot find an actual errata description on the Cypress - ;; web site, but from the example code it looks like this bug causes - ;; the length of string descriptors to be read incorrectly, possibly - ;; sending back more characters than the descriptor has. The workaround - ;; is to manually send out all of the data. The consequence of not - ;; using the workaround is that the strings gathered by the kernel - ;; driver are too long and are filled with trailing garbage (including - ;; leftover strings). Writing this out by hand is a nuisance, so for - ;; now I will just live with the bug. - movx a, @dptr - mov r1, a - inc dptr - movx a, @dptr - mov r2, a - mov dptr, SUDPTRH - mov a, r1 - movx @dptr, a - mov dptr, SUDPTRL - mov a, r2 - movx @dptr, a - ;; done - ljmp setup_done_ack - -setup_Get_Descriptor_not_string: - ljmp setup_stall - -setup_breq_not_06: - cjne r2, #0x08, setup_breq_not_08 - ;; Get_Configuration. always 1. return one byte. - ;; this is reusable - mov a, #1 -setup_return_one_byte: - mov dptr, IN0BUF - movx @dptr, a - mov a, #1 - mov dptr, IN0BC - movx @dptr, a - ljmp setup_done_ack -setup_breq_not_08: - cjne r2, #0x09, setup_breq_not_09 - ;; 09: Set_Configuration. ignored. - ljmp setup_done_ack -setup_breq_not_09: - cjne r2, #0x0a, setup_breq_not_0a - ;; 0a: Get_Interface. get the current altsetting for int[wIndexL] - ;; since we only have one interface, ignore wIndexL, return a 0 - mov a, #0 - ljmp setup_return_one_byte -setup_breq_not_0a: - cjne r2, #0x0b, setup_breq_not_0b - ;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored - ljmp setup_done_ack -setup_breq_not_0b: - ljmp setup_stall - - -setup_done_ack: - ;; now clear HSNAK - mov dptr, EP0CS - mov a, #0x02 - movx @dptr, a - sjmp setup_done -setup_stall: - ;; unhandled. STALL - ;EP0CS |= bmEPSTALL - mov dptr, EP0CS - movx a, @dptr - orl a, EP0STALLbit - movx @dptr, a - sjmp setup_done - -setup_done: - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -;;; ============================================================== - -set_baud: ; baud index in r3 - ;; verify a < 10 - mov a, r3 - jb ACC.7, set_baud__badbaud - clr c - subb a, #10 - jnc set_baud__badbaud - mov a, r3 - rl a ; a = index*2 - add a, #LOW(baud_table) - mov dpl, a - mov a, #HIGH(baud_table) - addc a, #0 - mov dph, a - ;; TODO: shut down xmit/receive - ;; TODO: wait for current xmit char to leave - ;; TODO: shut down timer to avoid partial-char glitch - movx a,@dptr ; BAUD_HIGH - mov RCAP2H, a - mov TH2, a - inc dptr - movx a,@dptr ; BAUD_LOW - mov RCAP2L, a - mov TL2, a - ;; TODO: restart xmit/receive - ;; TODO: reenable interrupts, resume tx if pending - clr c ; c=0: success - ret -set_baud__badbaud: - setb c ; c=1: failure - ret - -;;; ================================================== -control_pins: - cjne r1, #0x41, control_pins_in -control_pins_out: - ;TODO BKPT is DTR - mov a, r3 ; wValue[0] holds new bits: b7 is new RTS - xrl a, #0xff ; 1 means active, 0V, +12V ? - anl a, #0x80 - mov r3, a - mov dptr, OUTC - movx a, @dptr ; only change bit 7 - anl a, #0x7F ; ~0x84 - orl a, r3 - movx @dptr, a ; other pins are inputs, bits ignored - ljmp setup_done_ack -control_pins_in: - mov dptr, PINSC - movx a, @dptr - xrl a, #0xff - ljmp setup_return_one_byte - -;;; ======================================== - -ISR_Ep2in: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, IN07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - mov a, #0x20 ; Turn off the green LED - mov dptr,OEA - movx @dptr, a - - - ;; do stuff - lcall start_in - - mov a, #0x20 ; Turn off the green LED - mov dptr,OEA - movx @dptr, a - - - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -ISR_Ep2out: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - - mov a, #0x10 ; Turn the green LED - mov dptr,OEA - movx @dptr, a - - - - mov a,EXIF - clr acc.4 - mov EXIF,a ; clear INT2 first - mov dptr, OUT07IRQ ; clear USB int - mov a,#04h - movx @dptr,a - - ;; do stuff - - ;; copy data into buffer. for now, assume we will have enough space - mov dptr, OUT2BC ; get byte count - movx a,@dptr - mov r1, a - clr a - mov dps, a - mov dptr, OUT2BUF ; load DPTR0 with source - mov dph1, #HIGH(tx_ring) ; load DPTR1 with target - mov dpl1, tx_ring_in -OUT_loop: - movx a,@dptr ; read - inc dps ; switch to DPTR1: target - inc dpl1 ; target = tx_ring_in+1 - movx @dptr,a ; store - mov a,dpl1 - cjne a, tx_ring_out, OUT_no_overflow - sjmp OUT_overflow -OUT_no_overflow: - inc tx_ring_in ; tx_ring_in++ - inc dps ; switch to DPTR0: source - inc dptr - djnz r1, OUT_loop - sjmp OUT_done -OUT_overflow: - ;; signal overflow - ;; fall through -OUT_done: - ;; ack - mov dptr,OUT2BC - movx @dptr,a - - ;; start tx - acall maybe_start_tx - ;acall dump_stat - - mov a, #0x20 ; Turn off the green LED - mov dptr,OEA - movx @dptr, a - - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -dump_stat: - ;; fill in EP4in with a debugging message: - ;; tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out - ;; tx_active - ;; tx_ring[0..15] - ;; 0xfc - ;; rx_ring[0..15] - clr a - mov dps, a - - mov dptr, IN4CS - movx a, @dptr - jb acc.1, dump_stat__done; busy: cannot dump, old one still pending - mov dptr, IN4BUF - - mov a, tx_ring_in - movx @dptr, a - inc dptr - mov a, tx_ring_out - movx @dptr, a - inc dptr - - mov a, rx_ring_in - movx @dptr, a - inc dptr - mov a, rx_ring_out - movx @dptr, a - inc dptr - - clr a - jnb TX_RUNNING, dump_stat__no_tx_running - inc a -dump_stat__no_tx_running: - movx @dptr, a - inc dptr - ;; tx_ring[0..15] - inc dps - mov dptr, #tx_ring ; DPTR1: source - mov r1, #16 -dump_stat__tx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__tx_ring_loop - inc dps - - mov a, #0xfc - movx @dptr, a - inc dptr - - ;; rx_ring[0..15] - inc dps - mov dptr, #rx_ring ; DPTR1: source - mov r1, #16 -dump_stat__rx_ring_loop: - movx a, @dptr - inc dptr - inc dps - movx @dptr, a - inc dptr - inc dps - djnz r1, dump_stat__rx_ring_loop - - ;; now send it - clr a - mov dps, a - mov dptr, IN4BC - mov a, #38 - movx @dptr, a -dump_stat__done: - ret - -;;; ============================================================ - -maybe_start_tx: - ;; make sure the tx process is running. - jb TX_RUNNING, start_tx_done -start_tx: - ;; is there work to be done? - mov a, tx_ring_in - cjne a,tx_ring_out, start_tx__work - ret ; no work -start_tx__work: - ;; tx was not running. send the first character, setup the TI int - inc tx_ring_out ; [++tx_ring_out] - mov dph, #HIGH(tx_ring) - mov dpl, tx_ring_out - movx a, @dptr - mov sbuf, a - setb TX_RUNNING -start_tx_done: - ;; can we unthrottle the host tx process? - ;; step 1: do we care? - mov a, #0 - cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx - ;; nope -start_tx_really_done: - ret -start_tx__maybe_unthrottle_tx: - ;; step 2: is there now room? - mov a, tx_ring_out - setb c - subb a, tx_ring_in - ;; a is now write_room. If thresh >= a, we can unthrottle - clr c - subb a, tx_unthrottle_threshold - jc start_tx_really_done ; nope - ;; yes, we can unthrottle. remove the threshold and mark a request - mov tx_unthrottle_threshold, #0 - setb DO_TX_UNTHROTTLE - ;; prod rx, which will actually send the message when in2 becomes free - ljmp start_in - - -serial_int: - push dps - push dpl - push dph - push dpl1 - push dph1 - push acc - jnb TI, serial_int__not_tx - ;; tx finished. send another character if we have one - clr TI ; clear int - clr TX_RUNNING - lcall start_tx -serial_int__not_tx: - jnb RI, serial_int__not_rx - lcall get_rx_char - clr RI ; clear int -serial_int__not_rx: - ;; return - pop acc - pop dph1 - pop dpl1 - pop dph - pop dpl - pop dps - reti - -get_rx_char: - mov dph, #HIGH(rx_ring) - mov dpl, rx_ring_in - inc dpl ; target = rx_ring_in+1 - mov a, sbuf - movx @dptr, a - ;; check for overflow before incrementing rx_ring_in - mov a, dpl - cjne a, rx_ring_out, get_rx_char__no_overflow - ;; signal overflow - ret -get_rx_char__no_overflow: - inc rx_ring_in - ;; kick off USB INpipe - acall start_in - ret - -start_in: - ;; check if the inpipe is already running. - mov a,#0x10 - mov dptr, OEA - movx @dptr,a - - mov dptr, IN2CS - movx a, @dptr - jb acc.1, start_in__done; int will handle it - jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle - ;; see if there is any work to do. a serial interrupt might occur - ;; during this sequence? - mov a, rx_ring_in - cjne a, rx_ring_out, start_in__have_work - ret ; nope -start_in__have_work: - ;; now copy as much data as possible into the pipe. 63 bytes max. - clr a - mov dps, a - mov dph, #HIGH(rx_ring) ; load DPTR0 with source - inc dps - mov dptr, IN2BUF ; load DPTR1 with target - movx @dptr, a ; in[0] signals that rest of IN is rx data - inc dptr - inc dps - ;; loop until we run out of data, or we have copied 64 bytes - mov r1, #1 ; INbuf size counter -start_in__loop: - mov a, rx_ring_in - cjne a, rx_ring_out, start_inlocal_irq_enablell_copying - sjmp start_in__kick -start_inlocal_irq_enablell_copying: - inc rx_ring_out - mov dpl, rx_ring_out - movx a, @dptr - inc dps - movx @dptr, a ; write into IN buffer - inc dptr - inc dps - inc r1 - cjne r1, #64, start_in__loop; loop -start_in__kick: - ;; either we ran out of data, or we copied 64 bytes. r1 has byte count - ;; kick off IN - mov a, #0x10 ; Turn the green LED - mov dptr,OEA - movx @dptr, a - mov dptr, IN2BC - mov a, r1 - jz start_in__done - movx @dptr, a - ;; done -start_in__done: - ;acall dump_stat - ret -start_in__do_tx_unthrottle: - ;; special sequence: send a tx unthrottle message - clr DO_TX_UNTHROTTLE - clr a - mov dps, a - mov dptr, IN2BUF - mov a, #1 - movx @dptr, a - inc dptr - mov a, #2 - movx @dptr, a - mov dptr, IN2BC - movx @dptr, a - ret - -putchar: - clr TI - mov SBUF, a -putchar_wait: - jnb TI, putchar_wait - clr TI - ret - - -baud_table: ; baud_high, then baud_low - ;; baud[0]: 110 - .byte BAUD_HIGH(110) - .byte BAUD_LOW(110) - ;; baud[1]: 300 - .byte BAUD_HIGH(300) - .byte BAUD_LOW(300) - ;; baud[2]: 1200 - .byte BAUD_HIGH(1200) - .byte BAUD_LOW(1200) - ;; baud[3]: 2400 - .byte BAUD_HIGH(2400) - .byte BAUD_LOW(2400) - ;; baud[4]: 4800 - .byte BAUD_HIGH(4800) - .byte BAUD_LOW(4800) - ;; baud[5]: 9600 - .byte BAUD_HIGH(9600) - .byte BAUD_LOW(9600) - ;; baud[6]: 19200 - .byte BAUD_HIGH(19200) - .byte BAUD_LOW(19200) - ;; baud[7]: 38400 - .byte BAUD_HIGH(38400) - .byte BAUD_LOW(38400) - ;; baud[8]: 57600 - .byte BAUD_HIGH(57600) - .byte BAUD_LOW(57600) - ;; baud[9]: 115200 - .byte BAUD_HIGH(115200) - .byte BAUD_LOW(115200) - -desc_device: - .byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40 - .byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01 -;;; The "real" device id, which must match the host driver, is that -;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104 - -desc_config1: - .byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32 - .byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00 - .byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01 - .byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 - -desc_strings: - .word string_langids, string_mfg, string_product, string_serial -desc_strings_end: - -string_langids: .byte string_langids_end-string_langids - .byte 3 - .word 0 -string_langids_end: - - ;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now - ;; *that* is a pain in the ass to encode. And they are little-endian - ;; too. Use this perl snippet to get the bytecodes: - /* while (<>) { - @c = split(//); - foreach $c (@c) { - printf("0x%02x, 0x00, ", ord($c)); - } - } - */ - -string_mfg: .byte string_mfg_end-string_mfg - .byte 3 -; .byte "ACME usb widgets" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00 -string_mfg_end: - -string_product: .byte string_product_end-string_product - .byte 3 -; .byte "ACME USB serial widget" - .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00 -string_product_end: - -string_serial: .byte string_serial_end-string_serial - .byte 3 -; .byte "47" - .byte 0x34, 0x00, 0x37, 0x00 -string_serial_end: - -;;; ring buffer memory - ;; tx_ring_in+1 is where the next input byte will go - ;; [tx_ring_out] has been sent - ;; if tx_ring_in == tx_ring_out, theres no work to do - ;; there are (tx_ring_in - tx_ring_out) chars to be written - ;; dont let _in lap _out - ;; cannot inc if tx_ring_in+1 == tx_ring_out - ;; write [tx_ring_in+1] then tx_ring_in++ - ;; if (tx_ring_in+1 == tx_ring_out), overflow - ;; else tx_ring_in++ - ;; read/send [tx_ring_out+1], then tx_ring_out++ - - ;; rx_ring_in works the same way - - .org 0x1000 -tx_ring: - .skip 0x100 ; 256 bytes -rx_ring: - .skip 0x100 ; 256 bytes - - - .END - diff --git a/drivers/usb/serial/xircom_pgs_fw.h b/drivers/usb/serial/xircom_pgs_fw.h deleted file mode 100644 index 3ff74a6..0000000 --- a/drivers/usb/serial/xircom_pgs_fw.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * USB Xircom PGS Firmware - * - * Copyright (C) 1999, 2000 Brian Warner - * Copyright (C) 2001 Cristian M. Craciunescu - * - * 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. - * - * Generated from xircom_pgs.S by ezusb_convert_x.pl - */ - -static const struct ezusb_hex_record xircom_pgs_firmware[] = { -{ 0x0000, 3, {0x02, 0x02, 0x00} }, -{ 0x0023, 4, {0x02, 0x05, 0x9b, 0x00} }, -{ 0x0030, 5, {0x00, 0x00, 0x00, 0x00, 0x00} }, -{ 0x0043, 4, {0x02, 0x01, 0x00, 0x00} }, -{ 0x0100, 16, {0x02, 0x02, 0xba, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} }, -{ 0x0110, 16, {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} }, -{ 0x0120, 16, {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x04, 0x85, 0x00, 0x02, 0x04, 0xb9, 0x00} }, -{ 0x0200, 16, {0x75, 0x81, 0x5e, 0xe4, 0xf5, 0x32, 0xf5, 0x33, 0xf5, 0x30, 0xf5, 0x31, 0xf5, 0x34, 0xc2, 0x00} }, -{ 0x0210, 16, {0xc2, 0x01, 0xa9, 0x00, 0x74, 0xfe, 0x90, 0x10, 0x00, 0xf0, 0xa3, 0xd9, 0xfc, 0x74, 0xfd, 0x90} }, -{ 0x0220, 16, {0x11, 0x00, 0xf0, 0xa3, 0xd9, 0xfc, 0x90, 0x7f, 0x94, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x95, 0x74} }, -{ 0x0230, 16, {0xef, 0xf0, 0x74, 0x10, 0x90, 0x7f, 0x9e, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0x98, 0xf0, 0x74, 0x40} }, -{ 0x0240, 16, {0x90, 0x7f, 0x9d, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0x97, 0xf0, 0x74, 0x82, 0x90, 0x7f, 0x9e, 0xf0} }, -{ 0x0250, 16, {0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f, 0xaf, 0xe0, 0xd2, 0xe0, 0xf0, 0x74, 0x01, 0x90} }, -{ 0x0260, 16, {0x7f, 0xab, 0xf0, 0x90, 0x7f, 0xae, 0xf0, 0x90, 0x7f, 0xac, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xad} }, -{ 0x0270, 16, {0x74, 0x04, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x74, 0x07, 0x90, 0x7f, 0xaf, 0xf0, 0x74, 0x20, 0x90} }, -{ 0x0280, 16, {0x7f, 0x9c, 0xf0, 0x74, 0x80, 0x90, 0x7f, 0x98, 0xf0, 0x74, 0x53, 0xf5, 0x98, 0x75, 0xc8, 0x30} }, -{ 0x0290, 16, {0x7b, 0x05, 0x91, 0x44, 0xd2, 0xca, 0x75, 0x98, 0x50, 0xd2, 0xe8, 0xd2, 0xaf, 0xd2, 0xac, 0x74} }, -{ 0x02a0, 16, {0x00, 0xf5, 0x86, 0x90, 0x7f, 0xd6, 0x74, 0x02, 0xf0, 0x79, 0x2e, 0x7a, 0x00, 0x7b, 0x00, 0xdb} }, -{ 0x02b0, 16, {0xfe, 0xda, 0xfa, 0xd9, 0xf6, 0x74, 0x06, 0xf0, 0x80, 0xfe, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83} }, -{ 0x02c0, 16, {0xc0, 0x84, 0xc0, 0x85, 0xc0, 0xe0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xab, 0x74} }, -{ 0x02d0, 16, {0x01, 0xf0, 0x90, 0x7f, 0xe8, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xa3, 0xe0, 0xfc} }, -{ 0x02e0, 16, {0xe9, 0x54, 0x60, 0xb4, 0x00, 0x03, 0x02, 0x03, 0x5d, 0xb4, 0x40, 0x6e, 0xba, 0x00, 0x0b, 0x12} }, -{ 0x02f0, 16, {0x04, 0x44, 0x40, 0x03, 0x02, 0x04, 0x26, 0x02, 0x04, 0x2e, 0xba, 0x01, 0x03, 0x02, 0x04, 0x2e} }, -{ 0x0300, 16, {0xba, 0x02, 0x03, 0x02, 0x04, 0x2e, 0xba, 0x03, 0x03, 0x02, 0x04, 0x68, 0xba, 0x04, 0x1e, 0xbb} }, -{ 0x0310, 16, {0x00, 0x0a, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x04, 0x26, 0x90, 0x7f, 0x98, 0xe0} }, -{ 0x0320, 16, {0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x04, 0x26, 0xba, 0x05, 0x03} }, -{ 0x0330, 16, {0x02, 0x04, 0x2e, 0xba, 0x06, 0x19, 0xbb, 0x00, 0x08, 0xe5, 0x33, 0xd3, 0x95, 0x32, 0x02, 0x04} }, -{ 0x0340, 16, {0x02, 0xbb, 0x01, 0x08, 0xe5, 0x32, 0xc3, 0x95, 0x33, 0x02, 0x04, 0x02, 0x02, 0x04, 0x2e, 0xba} }, -{ 0x0350, 16, {0x07, 0x05, 0x8b, 0x34, 0x02, 0x04, 0x26, 0x02, 0x04, 0x2e, 0x02, 0x04, 0x2e, 0xba, 0x00, 0x20} }, -{ 0x0360, 16, {0xb9, 0x80, 0x10, 0x90, 0x7f, 0x00, 0xe4, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0} }, -{ 0x0370, 16, {0x02, 0x04, 0x26, 0xb9, 0x82, 0x02, 0x80, 0xeb, 0xb9, 0x81, 0x02, 0x80, 0xe6, 0x02, 0x04, 0x2e} }, -{ 0x0380, 16, {0xba, 0x01, 0x0f, 0xbb, 0x00, 0x03, 0x02, 0x04, 0x2e, 0xbb, 0x01, 0x03, 0x02, 0x04, 0x26, 0x02} }, -{ 0x0390, 16, {0x04, 0x2e, 0xba, 0x03, 0x0f, 0xbb, 0x00, 0x03, 0x02, 0x04, 0x2e, 0xbb, 0x01, 0x03, 0x02, 0x04} }, -{ 0x03a0, 16, {0x26, 0x02, 0x04, 0x2e, 0xba, 0x06, 0x56, 0xbc, 0x01, 0x0f, 0x90, 0x7f, 0xd4, 0x74, 0x06, 0xf0} }, -{ 0x03b0, 16, {0x90, 0x7f, 0xd5, 0x74, 0x5a, 0xf0, 0x02, 0x04, 0x26, 0xbc, 0x02, 0x12, 0xbb, 0x00, 0x6f, 0x90} }, -{ 0x03c0, 16, {0x7f, 0xd4, 0x74, 0x06, 0xf0, 0x90, 0x7f, 0xd5, 0x74, 0x6c, 0xf0, 0x02, 0x04, 0x26, 0xbc, 0x03} }, -{ 0x03d0, 16, {0x29, 0x74, 0x04, 0xc3, 0x9b, 0x40, 0x57, 0x60, 0x55, 0xeb, 0x2b, 0x90, 0x06, 0x8c, 0x25, 0x82} }, -{ 0x03e0, 16, {0xf5, 0x82, 0x74, 0x00, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0x90, 0x7f, 0xd4} }, -{ 0x03f0, 16, {0xe9, 0xf0, 0x90, 0x7f, 0xd5, 0xea, 0xf0, 0x02, 0x04, 0x26, 0x02, 0x04, 0x2e, 0xba, 0x08, 0x0f} }, -{ 0x0400, 16, {0x74, 0x01, 0x90, 0x7f, 0x00, 0xf0, 0x74, 0x01, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x04, 0x26, 0xba} }, -{ 0x0410, 16, {0x09, 0x03, 0x02, 0x04, 0x26, 0xba, 0x0a, 0x05, 0x74, 0x00, 0x02, 0x04, 0x02, 0xba, 0x0b, 0x03} }, -{ 0x0420, 16, {0x02, 0x04, 0x26, 0x02, 0x04, 0x2e, 0x90, 0x7f, 0xb4, 0x74, 0x02, 0xf0, 0x80, 0x09, 0x90, 0x7f} }, -{ 0x0430, 16, {0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x00, 0xd0, 0xe0, 0xd0, 0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0} }, -{ 0x0440, 16, {0x82, 0xd0, 0x86, 0x32, 0xeb, 0x20, 0xe7, 0x1e, 0xc3, 0x94, 0x0a, 0x50, 0x19, 0xeb, 0x23, 0x24} }, -{ 0x0450, 16, {0x46, 0xf5, 0x82, 0x74, 0x06, 0x34, 0x00, 0xf5, 0x83, 0xe0, 0xf5, 0xcb, 0xf5, 0xcd, 0xa3, 0xe0} }, -{ 0x0460, 16, {0xf5, 0xca, 0xf5, 0xcc, 0xc3, 0x22, 0xd3, 0x22, 0xb9, 0x41, 0x11, 0xeb, 0x64, 0xff, 0x54, 0x80} }, -{ 0x0470, 16, {0xfb, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f, 0x4b, 0xf0, 0x02, 0x04, 0x26, 0x90, 0x7f, 0x9b, 0xe0} }, -{ 0x0480, 16, {0x64, 0xff, 0x02, 0x04, 0x02, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85, 0xc0} }, -{ 0x0490, 16, {0xe0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xa9, 0x74, 0x04, 0xf0, 0x74, 0x20, 0x90} }, -{ 0x04a0, 16, {0x7f, 0x9c, 0xf0, 0x12, 0x05, 0xdc, 0x74, 0x20, 0x90, 0x7f, 0x9c, 0xf0, 0xd0, 0xe0, 0xd0, 0x85} }, -{ 0x04b0, 16, {0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0} }, -{ 0x04c0, 16, {0x84, 0xc0, 0x85, 0xc0, 0xe0, 0x74, 0x10, 0x90, 0x7f, 0x9c, 0xf0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5} }, -{ 0x04d0, 16, {0x91, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xc9, 0xe0, 0xf9, 0xe4, 0xf5, 0x86, 0x90} }, -{ 0x04e0, 16, {0x7d, 0xc0, 0x75, 0x85, 0x10, 0x85, 0x32, 0x84, 0xe0, 0x05, 0x86, 0x05, 0x84, 0xf0, 0xe5, 0x84} }, -{ 0x04f0, 16, {0xb5, 0x33, 0x02, 0x80, 0x09, 0x05, 0x32, 0x05, 0x86, 0xa3, 0xd9, 0xec, 0x80, 0x00, 0x90, 0x7f} }, -{ 0x0500, 16, {0xc9, 0xf0, 0xb1, 0x6d, 0x74, 0x20, 0x90, 0x7f, 0x9c, 0xf0, 0xd0, 0xe0, 0xd0, 0x85, 0xd0, 0x84} }, -{ 0x0510, 16, {0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0xe4, 0xf5, 0x86, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1} }, -{ 0x0520, 16, {0x4b, 0x90, 0x7d, 0x00, 0xe5, 0x32, 0xf0, 0xa3, 0xe5, 0x33, 0xf0, 0xa3, 0xe5, 0x30, 0xf0, 0xa3} }, -{ 0x0530, 16, {0xe5, 0x31, 0xf0, 0xa3, 0xe4, 0x30, 0x00, 0x01, 0x04, 0xf0, 0xa3, 0x05, 0x86, 0x90, 0x10, 0x00} }, -{ 0x0540, 16, {0x79, 0x10, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xd9, 0xf6, 0x05, 0x86, 0x74, 0xfc} }, -{ 0x0550, 16, {0xf0, 0xa3, 0x05, 0x86, 0x90, 0x11, 0x00, 0x79, 0x10, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0xa3, 0x05} }, -{ 0x0560, 16, {0x86, 0xd9, 0xf6, 0xe4, 0xf5, 0x86, 0x90, 0x7f, 0xbd, 0x74, 0x26, 0xf0, 0x22, 0x20, 0x00, 0x13} }, -{ 0x0570, 16, {0xe5, 0x32, 0xb5, 0x33, 0x01, 0x22, 0x05, 0x33, 0x75, 0x83, 0x10, 0x85, 0x33, 0x82, 0xe0, 0xf5} }, -{ 0x0580, 16, {0x99, 0xd2, 0x00, 0x74, 0x00, 0xb5, 0x34, 0x01, 0x22, 0xe5, 0x33, 0xd3, 0x95, 0x32, 0xc3, 0x95} }, -{ 0x0590, 16, {0x34, 0x40, 0xf5, 0x75, 0x34, 0x00, 0xd2, 0x01, 0x02, 0x05, 0xdc, 0xc0, 0x86, 0xc0, 0x82, 0xc0} }, -{ 0x05a0, 16, {0x83, 0xc0, 0x84, 0xc0, 0x85, 0xc0, 0xe0, 0x30, 0x99, 0x07, 0xc2, 0x99, 0xc2, 0x00, 0x12, 0x05} }, -{ 0x05b0, 16, {0x70, 0x30, 0x98, 0x05, 0x12, 0x05, 0xc6, 0xc2, 0x98, 0xd0, 0xe0, 0xd0, 0x85, 0xd0, 0x84, 0xd0} }, -{ 0x05c0, 16, {0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0x75, 0x83, 0x11, 0x85, 0x30, 0x82, 0x05, 0x82, 0xe5, 0x99} }, -{ 0x05d0, 16, {0xf0, 0xe5, 0x82, 0xb5, 0x31, 0x01, 0x22, 0x05, 0x30, 0xb1, 0xdc, 0x22, 0x74, 0x10, 0x90, 0x7f} }, -{ 0x05e0, 16, {0x9c, 0xf0, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x3e, 0x20, 0x01, 0x3c, 0xe5, 0x30, 0xb5, 0x31} }, -{ 0x05f0, 16, {0x01, 0x22, 0xe4, 0xf5, 0x86, 0x75, 0x83, 0x11, 0x05, 0x86, 0x90, 0x7e, 0x00, 0xf0, 0xa3, 0x05} }, -{ 0x0600, 16, {0x86, 0x79, 0x01, 0xe5, 0x30, 0xb5, 0x31, 0x02, 0x80, 0x10, 0x05, 0x31, 0x85, 0x31, 0x82, 0xe0} }, -{ 0x0610, 16, {0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0x09, 0xb9, 0x40, 0xe9, 0x74, 0x10, 0x90, 0x7f, 0x9c, 0xf0} }, -{ 0x0620, 16, {0x90, 0x7f, 0xb9, 0xe9, 0x60, 0x01, 0xf0, 0x22, 0xc2, 0x01, 0xe4, 0xf5, 0x86, 0x90, 0x7e, 0x00} }, -{ 0x0630, 16, {0x74, 0x01, 0xf0, 0xa3, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xb9, 0xf0, 0x22, 0xc2, 0x99, 0xf5, 0x99} }, -{ 0x0640, 16, {0x30, 0x99, 0xfd, 0xc2, 0x99, 0x22, 0xe5, 0x5e, 0xf6, 0x3c, 0xfd, 0x8f, 0xfe, 0xc8, 0xff, 0x64} }, -{ 0x0650, 16, {0xff, 0xb2, 0xff, 0xd9, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xfa, 0x12, 0x01, 0x00, 0x01, 0xff, 0xff} }, -{ 0x0660, 16, {0xff, 0x40, 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 0x01, 0x02, 0x03, 0x01, 0x09, 0x02, 0x20, 0x00} }, -{ 0x0670, 16, {0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05} }, -{ 0x0680, 16, {0x82, 0x03, 0x40, 0x00, 0x01, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x06, 0x94, 0x06, 0x98} }, -{ 0x0690, 16, {0x06, 0xba, 0x06, 0xe8, 0x04, 0x03, 0x00, 0x00, 0x22, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00} }, -{ 0x06a0, 16, {0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00} }, -{ 0x06b0, 16, {0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00, 0x2e, 0x03, 0x41, 0x00, 0x43, 0x00} }, -{ 0x06c0, 16, {0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00} }, -{ 0x06d0, 16, {0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00} }, -{ 0x06e0, 14, {0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x06, 0x03, 0x34, 0x00, 0x37, 0x00} }, -{ 0xffff, 0, {0x00} } -}; diff --git a/firmware/Makefile b/firmware/Makefile index db1b01a..dd76fa5 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -49,6 +49,8 @@ fw-shipped- := keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw endif +fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw +fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index d66291a..b5be4bc 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -119,3 +119,17 @@ Original licence information: part, requires the inclusion of this statement." -------------------------------------------------------------------------- + +Driver: keyspan_pda -- USB Keyspan PDA single-port serial device + +File: keyspan_pda/keyspan_pda.fw +Source: keyspan_pda/keyspan_pda.S + +File: keyspan_pda/xircom_pgs.fw +Source: keyspan_pda/xircom_pgs.S + +Licence: GPLv2+ + +Compiled from original 8051 source into Intel HEX, used in our binary ihex form. + +-------------------------------------------------------------------------- diff --git a/firmware/keyspan_pda/keyspan_pda.HEX b/firmware/keyspan_pda/keyspan_pda.HEX new file mode 100644 index 0000000..6fcf02b --- /dev/null +++ b/firmware/keyspan_pda/keyspan_pda.HEX @@ -0,0 +1,83 @@ +:03000000020200F9 +:0400230002055F0073 +:0400430002010000B6 +:050030000000000000CB +:10010000020296000200000002000000020000004F +:1001100002000000020000000200000002000000D7 +:1001200002000000020000000204610002048900D5 +:1002000075815EE4F532F533F530F531F534C20031 +:10021000C201A90074FE901000F0A3D9FC74FD90F7 +:100220001100F0A3D9FC7402907F9DF07400907FC0 +:1002300097F07486907F9EF0907F957403F0907F86 +:10024000AFE0D2E0F07401907FABF0907FAEF09021 +:100250007FAC7404F0907FAD7404F0907FC9F074AB +:1002600084907F98F07400F59875C8307B059120D4 +:10027000D2CA759850D2E8D2AFD2AC7400F586904D +:100280007FD67402F0792E7A007B00DBFEDAFAD991 +:10029000F67406F080FEC086C082C083C084C0852C +:1002A000C0E0E591C2E4F591907FAB7401F0907FDE +:1002B000E8E0F9A3E0FAA3E0FBA3E0FCE95460B4B2 +:1002C0000003020339B4406EBA000B12042040034D +:1002D00002040202040ABA010302040ABA02030277 +:1002E000040ABA0303020444BA041EBB000A907F46 +:1002F00095E04402F0020402907F98E054FDF090F3 +:100300007F95E054FDF0020402BA050302040ABA24 +:100310000619BB0008E533D395320203DEBB0108A2 +:10032000E532C395330203DE02040ABA07058B34B3 +:1003300002040202040A02040ABA0020B9801090E2 +:100340007F00E4F0A3F0907FB57402F0020402B9DC +:10035000820280EBB9810280E602040ABA010FBB77 +:10036000000302040ABB010302040202040ABA03E6 +:100370000FBB000302040ABB010302040202040AC9 +:10038000BA0656BC010F907FD47406F0907FD574E6 +:1003900012F0020402BC0212BB006F907FD47406FC +:1003A000F0907FD57424F0020402BC03297404C3C6 +:1003B0009B40576055EB2B9006442582F5827400D4 +:1003C0003583F583E0F9A3E0FA907FD4E9F0907FDC +:1003D000D5EAF002040202040ABA080F7401907F01 +:1003E00000F07401907FB5F0020402BA0903020420 +:1003F00002BA0A0574000203DEBA0B030204020209 +:10040000040A907FB47402F08009907FB4E0440144 +:10041000F08000D0E0D085D084D083D082D08632E6 +:10042000EB20E71EC3940A5019EB2324FEF58274D7 +:10043000053400F583E0F5CBF5CDA3E0F5CAF5CCA6 +:10044000C322D322B94111EB64FF5484FB907F98FF +:10045000E0547B4BF0020402907F9BE064FF0203B8 +:10046000DEC086C082C083C084C085C0E0E591C282 +:10047000E4F591907FA97404F01205A0D0E0D08536 +:10048000D084D083D082D08632C086C082C083C060 +:1004900084C085C0E0E591C2E4F591907FAA740420 +:1004A000F0907FC9E0F9E4F586907DC075851085F0 +:1004B0003284E005860584F0E584B53302800905C1 +:1004C000320586A3D9EC8000907FC9F0B131D0E02D +:1004D000D085D084D083D082D08632E4F586907FD8 +:1004E000BCE020E14B907D00E532F0A3E533F0A3C2 +:1004F000E530F0A3E531F0A3E430000104F0A305FA +:10050000869010007910E0A30586F0A30586D9F641 +:10051000058674FCF0A305869011007910E0A30510 +:1005200086F0A30586D9F6E4F586907FBD7426F0A3 +:1005300022200013E532B53301220533758310857F +:100540003382E0F599D2007400B5340122E533D34B +:100550009532C3953440F5753400D2010205A0C030 +:1005600086C082C083C084C085C0E0309907C2992C +:10057000C20012053430980512058AC298D0E0D026 +:1005800085D084D083D082D0863275831185308225 +:100590000582E599F0E582B53101220530B1A0224E +:1005A000907FB8E020E138200136E530B5310122F6 +:1005B000E4F5867583110586907E00F0A3058679A3 +:1005C00001E530B5310280100531853182E00586C4 +:1005D000F0A3058609B940E9907FB9E96001F022EE +:1005E000C201E4F586907E007401F0A37402F090DD +:1005F0007FB9F022C299F5993099FDC29922E55E42 +:10060000F63CFD8FFEC8FF64FFB2FFD9FFEDFFF39C +:10061000FFFA12010001FFFFFF40CD06040189AB84 +:1006200001020301090220000101008032090400D7 +:100630000002FFFFFF0007058203400001070502DB +:1006400002400000064C0650067206A0040300009B +:100650002203410043004D00450020007500730057 +:100660006200200077006900640067006500740084 +:1006700073002E03410043004D004500200055004B +:1006800053004200200073006500720069006100A1 +:100690006C0020007700690064006700650074004A +:0606A000060334003700E0 +:00000001FF diff --git a/firmware/keyspan_pda/keyspan_pda.S b/firmware/keyspan_pda/keyspan_pda.S new file mode 100644 index 0000000..418fe69 --- /dev/null +++ b/firmware/keyspan_pda/keyspan_pda.S @@ -0,0 +1,1124 @@ +/* $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $ + * + * Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on + * the EzUSB microcontroller. + * + * (C) Copyright 2000 Brian Warner + * + * 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. + * + * "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the + * company. + * + * This serial adapter is basically an EzUSB chip and an RS-232 line driver + * in a little widget that has a DB-9 on one end and a USB plug on the other. + * It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2 + * as a baud-rate generator. The wiring is: + * PC0/RxD0 <- rxd (DB9 pin 2) PC4 <- dsr pin 6 + * PC1/TxD0 -> txd pin 3 PC5 <- ri pin 9 + * PC2 -> rts pin 7 PC6 <- dcd pin 1 + * PC3 <- cts pin 8 PC7 -> dtr pin 4 + * PB1 -> line driver standby + * + * The EzUSB register constants below come from their excellent documentation + * and sample code (which used to be available at www.anchorchips.com, but + * that has now been absorbed into Cypress' site and the CD-ROM contents + * don't appear to be available online anymore). If we get multiple + * EzUSB-based drivers into the kernel, it might be useful to pull them out + * into a separate .h file. + * + * THEORY OF OPERATION: + * + * There are two 256-byte ring buffers, one for tx, one for rx. + * + * EP2out is pure tx data. When it appears, the data is copied into the tx + * ring and serial transmission is started if it wasn't already running. The + * "tx buffer empty" interrupt may kick off another character if the ring + * still has data. If the host is tx-blocked because the ring filled up, + * it will request a "tx unthrottle" interrupt. If sending a serial character + * empties the ring below the desired threshold, we set a bit that will send + * up the tx unthrottle message as soon as the rx buffer becomes free. + * + * EP2in (interrupt) is used to send both rx chars and rx status messages + * (only "tx unthrottle" at this time) back up to the host. The first byte + * of the rx message indicates data (0) or status msg (1). Status messages + * are sent before any data. + * + * Incoming serial characters are put into the rx ring by the serial + * interrupt, and the EP2in buffer sent if it wasn't already in transit. + * When the EP2in buffer returns, the interrupt prompts us to send more + * rx chars (or status messages) if they are pending. + * + * Device control happens through "vendor specific" control messages on EP0. + * All messages are destined for the "Interface" (with the index always 0, + * so that if their two-port device might someday use similar firmware, we + * can use index=1 to refer to the second port). The messages defined are: + * + * bRequest = 0 : set baud/bits/parity + * 1 : unused + * 2 : reserved for setting HW flow control (CTSRTS) + * 3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc) + * 4 : set break (on/off) + * 5 : reserved for requesting interrupts on pin state change + * 6 : query buffer room or chars in tx buffer + * 7 : request tx unthrottle interrupt + * + * The host-side driver is set to recognize the device ID values stashed in + * serial EEPROM (0x06cd, 0x0103), program this firmware into place, then + * start it running. This firmware will use EzUSB's "renumeration" trick by + * simulating a bus disconnect, then reconnect with a different device ID + * (encoded in the desc_device descriptor below). The host driver then + * recognizes the new device ID and glues it to the real serial driver code. + * + * USEFUL DOCS: + * EzUSB Technical Reference Manual: + * 8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is + * basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports + * use totally different registers! + * USB 1.1 spec: www.usb.org + * + * HOW TO BUILD: + * gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s + * as31 -l keyspan_pda.asm + * mv keyspan_pda.obj keyspan_pda.hex + * perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h + * Get as31 from , and hack on it + * a bit to make it build. + * + * THANKS: + * Greg Kroah-Hartman, for coordinating the whole usb-serial thing. + * AnchorChips, for making such an incredibly useful little microcontroller. + * KeySpan, for making a handy, cheap ($40) widget that was so easy to take + * apart and trace with an ohmmeter. + * + * TODO: + * lots. grep for TODO. Interrupt safety needs stress-testing. Better flow + * control. Interrupting host upon change in DCD, etc, counting transitions. + * Need to find a safe device id to use (the one used by the Keyspan firmware + * under Windows would be ideal.. can anyone figure out what it is?). Parity. + * More baud rates. Oh, and the string-descriptor-length silicon bug + * workaround should be implemented, but I'm lazy, and the consequence is + * that the device name strings that show up in your kernel log will have + * lots of trailing binary garbage in them (appears as ????). Device strings + * should be made more accurate. + * + * Questions, bugs, patches to Brian. + * + * -Brian Warner + * + */ + +#define HIGH(x) (((x) & 0xff00) / 256) +#define LOW(x) ((x) & 0xff) + +#define dpl1 0x84 +#define dph1 0x85 +#define dps 0x86 + +;;; our bit assignments +#define TX_RUNNING 0 +#define DO_TX_UNTHROTTLE 1 + + ;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60 +#define STACK #0x60-1 + +#define EXIF 0x91 +#define EIE 0xe8 + .flag EUSB, EIE.0 + .flag ES0, IE.4 + +#define EP0CS #0x7fb4 +#define EP0STALLbit #0x01 +#define IN0BUF #0x7f00 +#define IN0BC #0x7fb5 +#define OUT0BUF #0x7ec0 +#define OUT0BC #0x7fc5 +#define IN2BUF #0x7e00 +#define IN2BC #0x7fb9 +#define IN2CS #0x7fb8 +#define OUT2BC #0x7fc9 +#define OUT2CS #0x7fc8 +#define OUT2BUF #0x7dc0 +#define IN4BUF #0x7d00 +#define IN4BC #0x7fbd +#define IN4CS #0x7fbc +#define OEB #0x7f9d +#define OUTB #0x7f97 +#define OEC #0x7f9e +#define OUTC #0x7f98 +#define PINSC #0x7f9b +#define PORTCCFG #0x7f95 +#define IN07IRQ #0x7fa9 +#define OUT07IRQ #0x7faa +#define IN07IEN #0x7fac +#define OUT07IEN #0x7fad +#define USBIRQ #0x7fab +#define USBIEN #0x7fae +#define USBBAV #0x7faf +#define USBCS #0x7fd6 +#define SUDPTRH #0x7fd4 +#define SUDPTRL #0x7fd5 +#define SETUPDAT #0x7fe8 + + ;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91) + + .org 0 + ljmp start + ;; interrupt vectors + .org 23H + ljmp serial_int + .byte 0 + + .org 43H + ljmp USB_Jump_Table + .byte 0 ; filled in by the USB core + +;;; local variables. These are not initialized properly: do it by hand. + .org 30H +rx_ring_in: .byte 0 +rx_ring_out: .byte 0 +tx_ring_in: .byte 0 +tx_ring_out: .byte 0 +tx_unthrottle_threshold: .byte 0 + + .org 0x100H ; wants to be on a page boundary +USB_Jump_Table: + ljmp ISR_Sudav ; Setup Data Available + .byte 0 + ljmp 0 ; Start of Frame + .byte 0 + ljmp 0 ; Setup Data Loading + .byte 0 + ljmp 0 ; Global Suspend + .byte 0 + ljmp 0 ; USB Reset + .byte 0 + ljmp 0 ; Reserved + .byte 0 + ljmp 0 ; End Point 0 In + .byte 0 + ljmp 0 ; End Point 0 Out + .byte 0 + ljmp 0 ; End Point 1 In + .byte 0 + ljmp 0 ; End Point 1 Out + .byte 0 + ljmp ISR_Ep2in + .byte 0 + ljmp ISR_Ep2out + .byte 0 + + + .org 0x200 + +start: mov SP,STACK-1 ; set stack + ;; clear local variables + clr a + mov tx_ring_in, a + mov tx_ring_out, a + mov rx_ring_in, a + mov rx_ring_out, a + mov tx_unthrottle_threshold, a + clr TX_RUNNING + clr DO_TX_UNTHROTTLE + + ;; clear fifo with "fe" + mov r1, 0 + mov a, #0xfe + mov dptr, #tx_ring +clear_tx_ring_loop: + movx @dptr, a + inc dptr + djnz r1, clear_tx_ring_loop + + mov a, #0xfd + mov dptr, #rx_ring +clear_rx_ring_loop: + movx @dptr, a + inc dptr + djnz r1, clear_rx_ring_loop + +;;; turn on the RS-232 driver chip (bring the STANDBY pin low) + ;; set OEB.1 + mov a, #02H + mov dptr,OEB + movx @dptr,a + ;; clear PB1 + mov a, #00H + mov dptr,OUTB + movx @dptr,a + ;; set OEC.[127] + mov a, #0x86 + mov dptr,OEC + movx @dptr,a + ;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port + mov dptr, PORTCCFG + mov a, #0x03 + movx @dptr, a + + ;; set up interrupts, autovectoring + mov dptr, USBBAV + movx a,@dptr + setb acc.0 ; AVEN bit to 0 + movx @dptr, a + + mov a,#0x01 ; enable SUDAV: setup data available (for ep0) + mov dptr, USBIRQ + movx @dptr, a ; clear SUDAVI + mov dptr, USBIEN + movx @dptr, a + + mov dptr, IN07IEN + mov a,#0x04 ; enable IN2 int + movx @dptr, a + + mov dptr, OUT07IEN + mov a,#0x04 ; enable OUT2 int + movx @dptr, a + mov dptr, OUT2BC + movx @dptr, a ; arm OUT2 + + mov a, #0x84 ; turn on RTS, DTR + mov dptr,OUTC + movx @dptr, a + ;; setup the serial port. 9600 8N1. + mov a,#01010011 ; mode 1, enable rx, clear int + mov SCON, a + ;; using timer2, in 16-bit baud-rate-generator mode + ;; (xtal 12MHz, internal fosc 24MHz) + ;; RCAP2H,RCAP2L = 65536 - fosc/(32*baud) + ;; 57600: 0xFFF2.F, say 0xFFF3 + ;; 9600: 0xFFB1.E, say 0xFFB2 + ;; 300: 0xF63C +#define BAUD 9600 +#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate)) +#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate)) +#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate)) + + mov T2CON, #030h ; rclk=1,tclk=1,cp=0,tr2=0(enable later) + mov r3, #5 + acall set_baud + setb TR2 + mov SCON, #050h + +#if 0 + mov r1, #0x40 + mov a, #0x41 +send: + mov SBUF, a + inc a + anl a, #0x3F + orl a, #0x40 +; xrl a, #0x02 +wait1: + jnb TI, wait1 + clr TI + djnz r1, send +;done: sjmp done + +#endif + + setb EUSB + setb EA + setb ES0 + ;acall dump_stat + + ;; hey, what say we RENUMERATE! (TRM p.62) + mov a, #0 + mov dps, a + mov dptr, USBCS + mov a, #0x02 ; DISCON=0, DISCOE=0, RENUM=1 + movx @dptr, a + ;; now presence pin is floating, simulating disconnect. wait 0.5s + mov r1, #46 +renum_wait1: + mov r2, #0 +renum_wait2: + mov r3, #0 +renum_wait3: + djnz r3, renum_wait3 + djnz r2, renum_wait2 + djnz r1, renum_wait1 ; wait about n*(256^2) 6MHz clocks + mov a, #0x06 ; DISCON=0, DISCOE=1, RENUM=1 + movx @dptr, a + ;; we are back online. the host device will now re-query us + + +main: sjmp main + + + +ISR_Sudav: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + mov a,EXIF + clr acc.4 + mov EXIF,a ; clear INT2 first + mov dptr, USBIRQ ; clear USB int + mov a,#01h + movx @dptr,a + + ;; get request type + mov dptr, SETUPDAT + movx a, @dptr + mov r1, a ; r1 = bmRequestType + inc dptr + movx a, @dptr + mov r2, a ; r2 = bRequest + inc dptr + movx a, @dptr + mov r3, a ; r3 = wValueL + inc dptr + movx a, @dptr + mov r4, a ; r4 = wValueH + + ;; main switch on bmRequest.type: standard or vendor + mov a, r1 + anl a, #0x60 + cjne a, #0x00, setup_bmreq_type_not_standard + ;; standard request: now main switch is on bRequest + ljmp setup_bmreq_is_standard + +setup_bmreq_type_not_standard: + ;; a still has bmreq&0x60 + cjne a, #0x40, setup_bmreq_type_not_vendor + ;; Anchor reserves bRequest 0xa0-0xaf, we use small ones + ;; switch on bRequest. bmRequest will always be 0x41 or 0xc1 + cjne r2, #0x00, setup_ctrl_not_00 + ;; 00 is set baud, wValue[0] has baud rate index + lcall set_baud ; index in r3, carry set if error + jc setup_bmreq_type_not_standard__do_stall + ljmp setup_done_ack +setup_bmreq_type_not_standard__do_stall: + ljmp setup_stall +setup_ctrl_not_00: + cjne r2, #0x01, setup_ctrl_not_01 + ;; 01 is reserved for set bits (parity). TODO + ljmp setup_stall +setup_ctrl_not_01: + cjne r2, #0x02, setup_ctrl_not_02 + ;; 02 is set HW flow control. TODO + ljmp setup_stall +setup_ctrl_not_02: + cjne r2, #0x03, setup_ctrl_not_03 + ;; 03 is control pins (RTS, DTR). + ljmp control_pins ; will jump to setup_done_ack, + ; or setup_return_one_byte +setup_ctrl_not_03: + cjne r2, #0x04, setup_ctrl_not_04 + ;; 04 is send break (really "turn break on/off"). TODO + cjne r3, #0x00, setup_ctrl_do_break_on + ;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port + mov dptr, PORTCCFG + movx a, @dptr + orl a, #0x02 + movx @dptr, a + ljmp setup_done_ack +setup_ctrl_do_break_on: + ;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low) + mov dptr, OUTC + movx a, @dptr + anl a, #0xfd ; ~0x02 + movx @dptr, a + mov dptr, PORTCCFG + movx a, @dptr + anl a, #0xfd ; ~0x02 + movx @dptr, a + ljmp setup_done_ack +setup_ctrl_not_04: + cjne r2, #0x05, setup_ctrl_not_05 + ;; 05 is set desired interrupt bitmap. TODO + ljmp setup_stall +setup_ctrl_not_05: + cjne r2, #0x06, setup_ctrl_not_06 + ;; 06 is query room + cjne r3, #0x00, setup_ctrl_06_not_00 + ;; 06, wValue[0]=0 is query write_room + mov a, tx_ring_out + setb c + subb a, tx_ring_in ; out-1-in = 255 - (in-out) + ljmp setup_return_one_byte +setup_ctrl_06_not_00: + cjne r3, #0x01, setup_ctrl_06_not_01 + ;; 06, wValue[0]=1 is query chars_in_buffer + mov a, tx_ring_in + clr c + subb a, tx_ring_out ; in-out + ljmp setup_return_one_byte +setup_ctrl_06_not_01: + ljmp setup_stall +setup_ctrl_not_06: + cjne r2, #0x07, setup_ctrl_not_07 + ;; 07 is request tx unthrottle interrupt + mov tx_unthrottle_threshold, r3; wValue[0] is threshold value + ljmp setup_done_ack +setup_ctrl_not_07: + ljmp setup_stall + +setup_bmreq_type_not_vendor: + ljmp setup_stall + + +setup_bmreq_is_standard: + cjne r2, #0x00, setup_breq_not_00 + ;; 00: Get_Status (sub-switch on bmRequestType: device, ep, int) + cjne r1, #0x80, setup_Get_Status_not_device + ;; Get_Status(device) + ;; are we self-powered? no. can we do remote wakeup? no + ;; so return two zero bytes. This is reusable +setup_return_two_zero_bytes: + mov dptr, IN0BUF + clr a + movx @dptr, a + inc dptr + movx @dptr, a + mov dptr, IN0BC + mov a, #2 + movx @dptr, a + ljmp setup_done_ack +setup_Get_Status_not_device: + cjne r1, #0x82, setup_Get_Status_not_endpoint + ;; Get_Status(endpoint) + ;; must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0 + ;; for now: cheat. TODO + sjmp setup_return_two_zero_bytes +setup_Get_Status_not_endpoint: + cjne r1, #0x81, setup_Get_Status_not_interface + ;; Get_Status(interface): return two zeros + sjmp setup_return_two_zero_bytes +setup_Get_Status_not_interface: + ljmp setup_stall + +setup_breq_not_00: + cjne r2, #0x01, setup_breq_not_01 + ;; 01: Clear_Feature (sub-switch on wValueL: stall, remote wakeup) + cjne r3, #0x00, setup_Clear_Feature_not_stall + ;; Clear_Feature(stall). should clear a stall bit. TODO + ljmp setup_stall +setup_Clear_Feature_not_stall: + cjne r3, #0x01, setup_Clear_Feature_not_rwake + ;; Clear_Feature(remote wakeup). ignored. + ljmp setup_done_ack +setup_Clear_Feature_not_rwake: + ljmp setup_stall + +setup_breq_not_01: + cjne r2, #0x03, setup_breq_not_03 + ;; 03: Set_Feature (sub-switch on wValueL: stall, remote wakeup) + cjne r3, #0x00, setup_Set_Feature_not_stall + ;; Set_Feature(stall). Should set a stall bit. TODO + ljmp setup_stall +setup_Set_Feature_not_stall: + cjne r3, #0x01, setup_Set_Feature_not_rwake + ;; Set_Feature(remote wakeup). ignored. + ljmp setup_done_ack +setup_Set_Feature_not_rwake: + ljmp setup_stall + +setup_breq_not_03: + cjne r2, #0x06, setup_breq_not_06 + ;; 06: Get_Descriptor (s-switch on wValueH: dev, config[n], string[n]) + cjne r4, #0x01, setup_Get_Descriptor_not_device + ;; Get_Descriptor(device) + mov dptr, SUDPTRH + mov a, #HIGH(desc_device) + movx @dptr, a + mov dptr, SUDPTRL + mov a, #LOW(desc_device) + movx @dptr, a + ljmp setup_done_ack +setup_Get_Descriptor_not_device: + cjne r4, #0x02, setup_Get_Descriptor_not_config + ;; Get_Descriptor(config[n]) + cjne r3, #0x00, setup_stall; only handle n==0 + ;; Get_Descriptor(config[0]) + mov dptr, SUDPTRH + mov a, #HIGH(desc_config1) + movx @dptr, a + mov dptr, SUDPTRL + mov a, #LOW(desc_config1) + movx @dptr, a + ljmp setup_done_ack +setup_Get_Descriptor_not_config: + cjne r4, #0x03, setup_Get_Descriptor_not_string + ;; Get_Descriptor(string[wValueL]) + ;; if (wValueL >= maxstrings) stall + mov a, #((desc_strings_end-desc_strings)/2) + clr c + subb a,r3 ; a=4, r3 = 0..3 . if a<=0 then stall + jc setup_stall + jz setup_stall + mov a, r3 + add a, r3 ; a = 2*wValueL + mov dptr, #desc_strings + add a, dpl + mov dpl, a + mov a, #0 + addc a, dph + mov dph, a ; dph = desc_strings[a]. big endian! (handy) + ;; it looks like my adapter uses a revision of the EZUSB that + ;; contains "rev D errata number 8", as hinted in the EzUSB example + ;; code. I cannot find an actual errata description on the Cypress + ;; web site, but from the example code it looks like this bug causes + ;; the length of string descriptors to be read incorrectly, possibly + ;; sending back more characters than the descriptor has. The workaround + ;; is to manually send out all of the data. The consequence of not + ;; using the workaround is that the strings gathered by the kernel + ;; driver are too long and are filled with trailing garbage (including + ;; leftover strings). Writing this out by hand is a nuisance, so for + ;; now I will just live with the bug. + movx a, @dptr + mov r1, a + inc dptr + movx a, @dptr + mov r2, a + mov dptr, SUDPTRH + mov a, r1 + movx @dptr, a + mov dptr, SUDPTRL + mov a, r2 + movx @dptr, a + ;; done + ljmp setup_done_ack + +setup_Get_Descriptor_not_string: + ljmp setup_stall + +setup_breq_not_06: + cjne r2, #0x08, setup_breq_not_08 + ;; Get_Configuration. always 1. return one byte. + ;; this is reusable + mov a, #1 +setup_return_one_byte: + mov dptr, IN0BUF + movx @dptr, a + mov a, #1 + mov dptr, IN0BC + movx @dptr, a + ljmp setup_done_ack +setup_breq_not_08: + cjne r2, #0x09, setup_breq_not_09 + ;; 09: Set_Configuration. ignored. + ljmp setup_done_ack +setup_breq_not_09: + cjne r2, #0x0a, setup_breq_not_0a + ;; 0a: Get_Interface. get the current altsetting for int[wIndexL] + ;; since we only have one interface, ignore wIndexL, return a 0 + mov a, #0 + ljmp setup_return_one_byte +setup_breq_not_0a: + cjne r2, #0x0b, setup_breq_not_0b + ;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored + ljmp setup_done_ack +setup_breq_not_0b: + ljmp setup_stall + + +setup_done_ack: + ;; now clear HSNAK + mov dptr, EP0CS + mov a, #0x02 + movx @dptr, a + sjmp setup_done +setup_stall: + ;; unhandled. STALL + ;EP0CS |= bmEPSTALL + mov dptr, EP0CS + movx a, @dptr + orl a, EP0STALLbit + movx @dptr, a + sjmp setup_done + +setup_done: + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +;;; ============================================================== + +set_baud: ; baud index in r3 + ;; verify a < 10 + mov a, r3 + jb ACC.7, set_baud__badbaud + clr c + subb a, #10 + jnc set_baud__badbaud + mov a, r3 + rl a ; a = index*2 + add a, #LOW(baud_table) + mov dpl, a + mov a, #HIGH(baud_table) + addc a, #0 + mov dph, a + ;; TODO: shut down xmit/receive + ;; TODO: wait for current xmit char to leave + ;; TODO: shut down timer to avoid partial-char glitch + movx a,@dptr ; BAUD_HIGH + mov RCAP2H, a + mov TH2, a + inc dptr + movx a,@dptr ; BAUD_LOW + mov RCAP2L, a + mov TL2, a + ;; TODO: restart xmit/receive + ;; TODO: reenable interrupts, resume tx if pending + clr c ; c=0: success + ret +set_baud__badbaud: + setb c ; c=1: failure + ret + +;;; ================================================== +control_pins: + cjne r1, #0x41, control_pins_in +control_pins_out: + mov a, r3 ; wValue[0] holds new bits: b7 is new DTR, b2 is new RTS + xrl a, #0xff ; 1 means active, 0V, +12V ? + anl a, #0x84 + mov r3, a + mov dptr, OUTC + movx a, @dptr ; only change bits 7 and 2 + anl a, #0x7b ; ~0x84 + orl a, r3 + movx @dptr, a ; other pins are inputs, bits ignored + ljmp setup_done_ack +control_pins_in: + mov dptr, PINSC + movx a, @dptr + xrl a, #0xff + ljmp setup_return_one_byte + +;;; ======================================== + +ISR_Ep2in: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + mov a,EXIF + clr acc.4 + mov EXIF,a ; clear INT2 first + mov dptr, IN07IRQ ; clear USB int + mov a,#04h + movx @dptr,a + + ;; do stuff + lcall start_in + + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +ISR_Ep2out: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + mov a,EXIF + clr acc.4 + mov EXIF,a ; clear INT2 first + mov dptr, OUT07IRQ ; clear USB int + mov a,#04h + movx @dptr,a + + ;; do stuff + + ;; copy data into buffer. for now, assume we will have enough space + mov dptr, OUT2BC ; get byte count + movx a,@dptr + mov r1, a + clr a + mov dps, a + mov dptr, OUT2BUF ; load DPTR0 with source + mov dph1, #HIGH(tx_ring) ; load DPTR1 with target + mov dpl1, tx_ring_in +OUT_loop: + movx a,@dptr ; read + inc dps ; switch to DPTR1: target + inc dpl1 ; target = tx_ring_in+1 + movx @dptr,a ; store + mov a,dpl1 + cjne a, tx_ring_out, OUT_no_overflow + sjmp OUT_overflow +OUT_no_overflow: + inc tx_ring_in ; tx_ring_in++ + inc dps ; switch to DPTR0: source + inc dptr + djnz r1, OUT_loop + sjmp OUT_done +OUT_overflow: + ;; signal overflow + ;; fall through +OUT_done: + ;; ack + mov dptr,OUT2BC + movx @dptr,a + + ;; start tx + acall maybe_start_tx + ;acall dump_stat + + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +dump_stat: + ;; fill in EP4in with a debugging message: + ;; tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out + ;; tx_active + ;; tx_ring[0..15] + ;; 0xfc + ;; rx_ring[0..15] + clr a + mov dps, a + + mov dptr, IN4CS + movx a, @dptr + jb acc.1, dump_stat__done; busy: cannot dump, old one still pending + mov dptr, IN4BUF + + mov a, tx_ring_in + movx @dptr, a + inc dptr + mov a, tx_ring_out + movx @dptr, a + inc dptr + + mov a, rx_ring_in + movx @dptr, a + inc dptr + mov a, rx_ring_out + movx @dptr, a + inc dptr + + clr a + jnb TX_RUNNING, dump_stat__no_tx_running + inc a +dump_stat__no_tx_running: + movx @dptr, a + inc dptr + ;; tx_ring[0..15] + inc dps + mov dptr, #tx_ring ; DPTR1: source + mov r1, #16 +dump_stat__tx_ring_loop: + movx a, @dptr + inc dptr + inc dps + movx @dptr, a + inc dptr + inc dps + djnz r1, dump_stat__tx_ring_loop + inc dps + + mov a, #0xfc + movx @dptr, a + inc dptr + + ;; rx_ring[0..15] + inc dps + mov dptr, #rx_ring ; DPTR1: source + mov r1, #16 +dump_stat__rx_ring_loop: + movx a, @dptr + inc dptr + inc dps + movx @dptr, a + inc dptr + inc dps + djnz r1, dump_stat__rx_ring_loop + + ;; now send it + clr a + mov dps, a + mov dptr, IN4BC + mov a, #38 + movx @dptr, a +dump_stat__done: + ret + +;;; ============================================================ + +maybe_start_tx: + ;; make sure the tx process is running. + jb TX_RUNNING, start_tx_done +start_tx: + ;; is there work to be done? + mov a, tx_ring_in + cjne a,tx_ring_out, start_tx__work + ret ; no work +start_tx__work: + ;; tx was not running. send the first character, setup the TI int + inc tx_ring_out ; [++tx_ring_out] + mov dph, #HIGH(tx_ring) + mov dpl, tx_ring_out + movx a, @dptr + mov sbuf, a + setb TX_RUNNING +start_tx_done: + ;; can we unthrottle the host tx process? + ;; step 1: do we care? + mov a, #0 + cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx + ;; nope +start_tx_really_done: + ret +start_tx__maybe_unthrottle_tx: + ;; step 2: is there now room? + mov a, tx_ring_out + setb c + subb a, tx_ring_in + ;; a is now write_room. If thresh >= a, we can unthrottle + clr c + subb a, tx_unthrottle_threshold + jc start_tx_really_done ; nope + ;; yes, we can unthrottle. remove the threshold and mark a request + mov tx_unthrottle_threshold, #0 + setb DO_TX_UNTHROTTLE + ;; prod rx, which will actually send the message when in2 becomes free + ljmp start_in + + +serial_int: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + jnb TI, serial_int__not_tx + ;; tx finished. send another character if we have one + clr TI ; clear int + clr TX_RUNNING + lcall start_tx +serial_int__not_tx: + jnb RI, serial_int__not_rx + lcall get_rx_char + clr RI ; clear int +serial_int__not_rx: + ;; return + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +get_rx_char: + mov dph, #HIGH(rx_ring) + mov dpl, rx_ring_in + inc dpl ; target = rx_ring_in+1 + mov a, sbuf + movx @dptr, a + ;; check for overflow before incrementing rx_ring_in + mov a, dpl + cjne a, rx_ring_out, get_rx_char__no_overflow + ;; signal overflow + ret +get_rx_char__no_overflow: + inc rx_ring_in + ;; kick off USB INpipe + acall start_in + ret + +start_in: + ;; check if the inpipe is already running. + mov dptr, IN2CS + movx a, @dptr + jb acc.1, start_in__done; int will handle it + jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle + ;; see if there is any work to do. a serial interrupt might occur + ;; during this sequence? + mov a, rx_ring_in + cjne a, rx_ring_out, start_in__have_work + ret ; nope +start_in__have_work: + ;; now copy as much data as possible into the pipe. 63 bytes max. + clr a + mov dps, a + mov dph, #HIGH(rx_ring) ; load DPTR0 with source + inc dps + mov dptr, IN2BUF ; load DPTR1 with target + movx @dptr, a ; in[0] signals that rest of IN is rx data + inc dptr + inc dps + ;; loop until we run out of data, or we have copied 64 bytes + mov r1, #1 ; INbuf size counter +start_in__loop: + mov a, rx_ring_in + cjne a, rx_ring_out, start_inlocal_irq_enablell_copying + sjmp start_in__kick +start_inlocal_irq_enablell_copying: + inc rx_ring_out + mov dpl, rx_ring_out + movx a, @dptr + inc dps + movx @dptr, a ; write into IN buffer + inc dptr + inc dps + inc r1 + cjne r1, #64, start_in__loop; loop +start_in__kick: + ;; either we ran out of data, or we copied 64 bytes. r1 has byte count + ;; kick off IN + mov dptr, IN2BC + mov a, r1 + jz start_in__done + movx @dptr, a + ;; done +start_in__done: + ;acall dump_stat + ret +start_in__do_tx_unthrottle: + ;; special sequence: send a tx unthrottle message + clr DO_TX_UNTHROTTLE + clr a + mov dps, a + mov dptr, IN2BUF + mov a, #1 + movx @dptr, a + inc dptr + mov a, #2 + movx @dptr, a + mov dptr, IN2BC + movx @dptr, a + ret + +putchar: + clr TI + mov SBUF, a +putchar_wait: + jnb TI, putchar_wait + clr TI + ret + + +baud_table: ; baud_high, then baud_low + ;; baud[0]: 110 + .byte BAUD_HIGH(110) + .byte BAUD_LOW(110) + ;; baud[1]: 300 + .byte BAUD_HIGH(300) + .byte BAUD_LOW(300) + ;; baud[2]: 1200 + .byte BAUD_HIGH(1200) + .byte BAUD_LOW(1200) + ;; baud[3]: 2400 + .byte BAUD_HIGH(2400) + .byte BAUD_LOW(2400) + ;; baud[4]: 4800 + .byte BAUD_HIGH(4800) + .byte BAUD_LOW(4800) + ;; baud[5]: 9600 + .byte BAUD_HIGH(9600) + .byte BAUD_LOW(9600) + ;; baud[6]: 19200 + .byte BAUD_HIGH(19200) + .byte BAUD_LOW(19200) + ;; baud[7]: 38400 + .byte BAUD_HIGH(38400) + .byte BAUD_LOW(38400) + ;; baud[8]: 57600 + .byte BAUD_HIGH(57600) + .byte BAUD_LOW(57600) + ;; baud[9]: 115200 + .byte BAUD_HIGH(115200) + .byte BAUD_LOW(115200) + +desc_device: + .byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40 + .byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01 +;;; The "real" device id, which must match the host driver, is that +;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104 + +desc_config1: + .byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32 + .byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00 + .byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01 + .byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 + +desc_strings: + .word string_langids, string_mfg, string_product, string_serial +desc_strings_end: + +string_langids: .byte string_langids_end-string_langids + .byte 3 + .word 0 +string_langids_end: + + ;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now + ;; *that* is a pain in the ass to encode. And they are little-endian + ;; too. Use this perl snippet to get the bytecodes: + /* while (<>) { + @c = split(//); + foreach $c (@c) { + printf("0x%02x, 0x00, ", ord($c)); + } + } + */ + +string_mfg: .byte string_mfg_end-string_mfg + .byte 3 +; .byte "ACME usb widgets" + .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00 +string_mfg_end: + +string_product: .byte string_product_end-string_product + .byte 3 +; .byte "ACME USB serial widget" + .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00 +string_product_end: + +string_serial: .byte string_serial_end-string_serial + .byte 3 +; .byte "47" + .byte 0x34, 0x00, 0x37, 0x00 +string_serial_end: + +;;; ring buffer memory + ;; tx_ring_in+1 is where the next input byte will go + ;; [tx_ring_out] has been sent + ;; if tx_ring_in == tx_ring_out, theres no work to do + ;; there are (tx_ring_in - tx_ring_out) chars to be written + ;; dont let _in lap _out + ;; cannot inc if tx_ring_in+1 == tx_ring_out + ;; write [tx_ring_in+1] then tx_ring_in++ + ;; if (tx_ring_in+1 == tx_ring_out), overflow + ;; else tx_ring_in++ + ;; read/send [tx_ring_out+1], then tx_ring_out++ + + ;; rx_ring_in works the same way + + .org 0x1000 +tx_ring: + .skip 0x100 ; 256 bytes +rx_ring: + .skip 0x100 ; 256 bytes + + + .END + diff --git a/firmware/keyspan_pda/xircom_pgs.HEX b/firmware/keyspan_pda/xircom_pgs.HEX new file mode 100644 index 0000000..e9b00d7 --- /dev/null +++ b/firmware/keyspan_pda/xircom_pgs.HEX @@ -0,0 +1,87 @@ +:03000000020200F9 +:0400230002059B0037 +:050030000000000000CB +:0400430002010000B6 +:100100000202BA000200000002000000020000002B +:1001100002000000020000000200000002000000D7 +:100120000200000002000000020485000204B90081 +:1002000075815EE4F532F533F530F531F534C20031 +:10021000C201A90074FE901000F0A3D9FC74FD90F7 +:100220001100F0A3D9FC907F9474BFF0907F957477 +:10023000EFF07410907F9EF07400907F98F07440FF +:10024000907F9DF07400907F97F07482907F9EF075 +:10025000907F957403F0907FAFE0D2E0F07401904E +:100260007FABF0907FAEF0907FAC7404F0907FADE8 +:100270007404F0907FC9F07407907FAFF074209001 +:100280007F9CF07480907F98F07453F59875C83017 +:100290007B059144D2CA759850D2E8D2AFD2AC74E3 +:1002A00000F586907FD67402F0792E7A007B00DB11 +:1002B000FEDAFAD9F67406F080FEC086C082C083EA +:1002C000C084C085C0E0E591C2E4F591907FAB7435 +:1002D00001F0907FE8E0F9A3E0FAA3E0FBA3E0FCE3 +:1002E000E95460B4000302035DB4406EBA000B121F +:1002F0000444400302042602042EBA010302042E21 +:10030000BA020302042EBA0303020468BA041EBB35 +:10031000000A907F95E04402F0020426907F98E066 +:1003200054FDF0907F95E054FDF0020426BA0503D9 +:1003300002042EBA0619BB0008E533D39532020435 +:1003400002BB0108E532C3953302040202042EBA4F +:1003500007058B3402042602042E02042EBA002064 +:10036000B98010907F00E4F0A3F0907FB57402F0A4 +:10037000020426B9820280EBB9810280E602042ED3 +:10038000BA010FBB000302042EBB010302042602C4 +:10039000042EBA030FBB000302042EBB01030204A8 +:1003A0002602042EBA0656BC010F907FD47406F0C4 +:1003B000907FD5745AF0020426BC0212BB006F90E5 +:1003C0007FD47406F0907FD5746CF0020426BC03D1 +:1003D000297404C39B40576055EB2B90068C2582F3 +:1003E000F58274003583F583E0F9A3E0FA907FD4B9 +:1003F000E9F0907FD5EAF002042602042EBA080F35 +:100400007401907F00F07401907FB5F0020426BA69 +:100410000903020426BA0A057400020402BA0B0397 +:1004200002042602042E907FB47402F08009907FAB +:10043000B4E04401F08000D0E0D085D084D083D0F7 +:1004400082D08632EB20E71EC3940A5019EB232496 +:1004500046F58274063400F583E0F5CBF5CDA3E0D4 +:10046000F5CAF5CCC322D322B94111EB64FF548005 +:10047000FB907F98E0547F4BF0020426907F9BE036 +:1004800064FF020402C086C082C083C084C085C0ED +:10049000E0E591C2E4F591907FA97404F074209096 +:1004A0007F9CF01205DC7420907F9CF0D0E0D0851A +:1004B000D084D083D082D08632C086C082C083C030 +:1004C00084C085C0E07410907F9CF0E591C2E4F593 +:1004D00091907FAA7404F0907FC9E0F9E4F58690CA +:1004E0007DC0758510853284E005860584F0E5843D +:1004F000B53302800905320586A3D9EC8000907FD0 +:10050000C9F0B16D7420907F9CF0D0E0D085D0848C +:10051000D083D082D08632E4F586907FBCE020E1A3 +:100520004B907D00E532F0A3E533F0A3E530F0A376 +:10053000E531F0A3E430000104F0A305869010003B +:100540007910E0A30586F0A30586D9F6058674FC2C +:10055000F0A305869011007910E0A30586F0A305AD +:1005600086D9F6E4F586907FBD7426F0222000132C +:10057000E532B53301220533758310853382E0F50A +:1005800099D2007400B5340122E533D39532C39576 +:100590003440F5753400D2010205DCC086C082C04B +:1005A00083C084C085C0E0309907C299C20012059B +:1005B000703098051205C6C298D0E0D085D084D09E +:1005C00083D082D086327583118530820582E59989 +:1005D000F0E582B53101220530B1DC227410907F44 +:1005E0009CF0907FB8E020E13E20013CE530B53141 +:1005F0000122E4F5867583110586907E00F0A3053F +:10060000867901E530B5310280100531853182E00F +:100610000586F0A3058609B940E97410907F9CF027 +:10062000907FB9E96001F022C201E4F586907E0076 +:100630007401F0A37402F0907FB9F022C299F59989 +:100640003099FDC29922E55EF63CFD8FFEC8FF643D +:10065000FFB2FFD9FFEDFFF3FFFA12010001FFFF28 +:10066000FF40CD06040189AB01020301090220000D +:1006700001010080320904000002FFFFFF000705AE +:10068000820340000107050202400000069406981C +:1006900006BA06E8040300002203410043004D00AF +:1006A000450020007500730062002000770069009B +:1006B000640067006500740073002E03410043006E +:1006C0004D004500200055005300420020007300FB +:1006D00065007200690061006C002000770069000D +:0E06E0006400670065007400060334003700F4 +:00000001FF diff --git a/firmware/keyspan_pda/xircom_pgs.S b/firmware/keyspan_pda/xircom_pgs.S new file mode 100644 index 0000000..05d99dd --- /dev/null +++ b/firmware/keyspan_pda/xircom_pgs.S @@ -0,0 +1,1192 @@ +/* $Id: loop.s,v 1.23 2000/03/20 09:49:06 warner Exp $ + * + * Firmware for the Keyspan PDA Serial Adapter, a USB serial port based on + * the EzUSB microcontroller. + * + * (C) Copyright 2000 Brian Warner + * + * 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. + * + * "Keyspan PDA Serial Adapter" is probably a copyright of Keyspan, the + * company. + * + * This serial adapter is basically an EzUSB chip and an RS-232 line driver + * in a little widget that has a DB-9 on one end and a USB plug on the other. + * It uses the EzUSB's internal UART0 (using the pins from Port C) and timer2 + * as a baud-rate generator. The wiring is: + * PC0/RxD0 <- rxd (DB9 pin 2) PC4 <- dsr pin 6 + * PC1/TxD0 -> txd pin 3 PC5 <- ri pin 9 + * PC2 -> rts pin 7 PC6 <- dcd pin 1 + * PC3 <- cts pin 8 PC7 -> dtr pin 4 + * PB1 -> line driver standby + * + * The EzUSB register constants below come from their excellent documentation + * and sample code (which used to be available at www.anchorchips.com, but + * that has now been absorbed into Cypress' site and the CD-ROM contents + * don't appear to be available online anymore). If we get multiple + * EzUSB-based drivers into the kernel, it might be useful to pull them out + * into a separate .h file. + * + * THEORY OF OPERATION: + * + * There are two 256-byte ring buffers, one for tx, one for rx. + * + * EP2out is pure tx data. When it appears, the data is copied into the tx + * ring and serial transmission is started if it wasn't already running. The + * "tx buffer empty" interrupt may kick off another character if the ring + * still has data. If the host is tx-blocked because the ring filled up, + * it will request a "tx unthrottle" interrupt. If sending a serial character + * empties the ring below the desired threshold, we set a bit that will send + * up the tx unthrottle message as soon as the rx buffer becomes free. + * + * EP2in (interrupt) is used to send both rx chars and rx status messages + * (only "tx unthrottle" at this time) back up to the host. The first byte + * of the rx message indicates data (0) or status msg (1). Status messages + * are sent before any data. + * + * Incoming serial characters are put into the rx ring by the serial + * interrupt, and the EP2in buffer sent if it wasn't already in transit. + * When the EP2in buffer returns, the interrupt prompts us to send more + * rx chars (or status messages) if they are pending. + * + * Device control happens through "vendor specific" control messages on EP0. + * All messages are destined for the "Interface" (with the index always 0, + * so that if their two-port device might someday use similar firmware, we + * can use index=1 to refer to the second port). The messages defined are: + * + * bRequest = 0 : set baud/bits/parity + * 1 : unused + * 2 : reserved for setting HW flow control (CTSRTS) + * 3 : get/set "modem info" (pin states: DTR, RTS, DCD, RI, etc) + * 4 : set break (on/off) + * 5 : reserved for requesting interrupts on pin state change + * 6 : query buffer room or chars in tx buffer + * 7 : request tx unthrottle interrupt + * + * The host-side driver is set to recognize the device ID values stashed in + * serial EEPROM (0x06cd, 0x0103), program this firmware into place, then + * start it running. This firmware will use EzUSB's "renumeration" trick by + * simulating a bus disconnect, then reconnect with a different device ID + * (encoded in the desc_device descriptor below). The host driver then + * recognizes the new device ID and glues it to the real serial driver code. + * + * USEFUL DOCS: + * EzUSB Technical Reference Manual: + * 8051 manuals: everywhere, but try www.dalsemi.com because the EzUSB is + * basically the Dallas enhanced 8051 code. Remember that the EzUSB IO ports + * use totally different registers! + * USB 1.1 spec: www.usb.org + * + * HOW TO BUILD: + * gcc -x assembler-with-cpp -P -E -o keyspan_pda.asm keyspan_pda.s + * as31 -l keyspan_pda.asm + * mv keyspan_pda.obj keyspan_pda.hex + * perl ezusb_convert.pl keyspan_pda < keyspan_pda.hex > keyspan_pda_fw.h + * Get as31 from , and hack on it + * a bit to make it build. + * + * THANKS: + * Greg Kroah-Hartman, for coordinating the whole usb-serial thing. + * AnchorChips, for making such an incredibly useful little microcontroller. + * KeySpan, for making a handy, cheap ($40) widget that was so easy to take + * apart and trace with an ohmmeter. + * + * TODO: + * lots. grep for TODO. Interrupt safety needs stress-testing. Better flow + * control. Interrupting host upon change in DCD, etc, counting transitions. + * Need to find a safe device id to use (the one used by the Keyspan firmware + * under Windows would be ideal.. can anyone figure out what it is?). Parity. + * More baud rates. Oh, and the string-descriptor-length silicon bug + * workaround should be implemented, but I'm lazy, and the consequence is + * that the device name strings that show up in your kernel log will have + * lots of trailing binary garbage in them (appears as ????). Device strings + * should be made more accurate. + * + * Questions, bugs, patches to Brian. + * + * -Brian Warner + * + */ + +#define HIGH(x) (((x) & 0xff00) / 256) +#define LOW(x) ((x) & 0xff) + +#define dpl1 0x84 +#define dph1 0x85 +#define dps 0x86 + +;;; our bit assignments +#define TX_RUNNING 0 +#define DO_TX_UNTHROTTLE 1 + + ;; stack from 0x60 to 0x7f: should really set SP to 0x60-1, not 0x60 +#define STACK #0x60-1 + +#define EXIF 0x91 +#define EIE 0xe8 + .flag EUSB, EIE.0 + .flag ES0, IE.4 + +#define EP0CS #0x7fb4 +#define EP0STALLbit #0x01 +#define IN0BUF #0x7f00 +#define IN0BC #0x7fb5 +#define OUT0BUF #0x7ec0 +#define OUT0BC #0x7fc5 +#define IN2BUF #0x7e00 +#define IN2BC #0x7fb9 +#define IN2CS #0x7fb8 +#define OUT2BC #0x7fc9 +#define OUT2CS #0x7fc8 +#define OUT2BUF #0x7dc0 +#define IN4BUF #0x7d00 +#define IN4BC #0x7fbd +#define IN4CS #0x7fbc +#define OEB #0x7f9d +#define OUTB #0x7f97 +#define OEC #0x7f9e +#define OUTC #0x7f98 +#define PINSC #0x7f9b +#define PORTBCFG #0x7f94 +#define PORTCCFG #0x7f95 +#define OEA #0x7f9c +#define IN07IRQ #0x7fa9 +#define OUT07IRQ #0x7faa +#define IN07IEN #0x7fac +#define OUT07IEN #0x7fad +#define USBIRQ #0x7fab +#define USBIEN #0x7fae +#define USBBAV #0x7faf +#define USBCS #0x7fd6 +#define SUDPTRH #0x7fd4 +#define SUDPTRL #0x7fd5 +#define SETUPDAT #0x7fe8 + + ;; usb interrupt : enable is EIE.0 (0xe8), flag is EXIF.4 (0x91) + + .org 0 + ljmp start + ;; interrupt vectors + .org 23H + ljmp serial_int + .byte 0 + + .org 43H + ljmp USB_Jump_Table + .byte 0 ; filled in by the USB core + +;;; local variables. These are not initialized properly: do it by hand. + .org 30H +rx_ring_in: .byte 0 +rx_ring_out: .byte 0 +tx_ring_in: .byte 0 +tx_ring_out: .byte 0 +tx_unthrottle_threshold: .byte 0 + + .org 0x100H ; wants to be on a page boundary +USB_Jump_Table: + ljmp ISR_Sudav ; Setup Data Available + .byte 0 + ljmp 0 ; Start of Frame + .byte 0 + ljmp 0 ; Setup Data Loading + .byte 0 + ljmp 0 ; Global Suspend + .byte 0 + ljmp 0 ; USB Reset + .byte 0 + ljmp 0 ; Reserved + .byte 0 + ljmp 0 ; End Point 0 In + .byte 0 + ljmp 0 ; End Point 0 Out + .byte 0 + ljmp 0 ; End Point 1 In + .byte 0 + ljmp 0 ; End Point 1 Out + .byte 0 + ljmp ISR_Ep2in + .byte 0 + ljmp ISR_Ep2out + .byte 0 + + + .org 0x200 + +start: mov SP,STACK-1 ; set stack + ;; clear local variables + clr a + mov tx_ring_in, a + mov tx_ring_out, a + mov rx_ring_in, a + mov rx_ring_out, a + mov tx_unthrottle_threshold, a + clr TX_RUNNING + clr DO_TX_UNTHROTTLE + + ;; clear fifo with "fe" + mov r1, 0 + mov a, #0xfe + mov dptr, #tx_ring +clear_tx_ring_loop: + movx @dptr, a + inc dptr + djnz r1, clear_tx_ring_loop + + mov a, #0xfd + mov dptr, #rx_ring +clear_rx_ring_loop: + movx @dptr, a + inc dptr + djnz r1, clear_rx_ring_loop + +;;; turn on the RS-232 driver chip (bring the STANDBY pin low) +;;; on Xircom the STANDBY is wired to PB6 and PC4 + mov dptr, PORTBCFG + mov a, #0xBf + movx @dptr, a + mov dptr, PORTCCFG + mov a, #0xef + movx @dptr, a + + ;; set OEC.4 + mov a, #0x10 + mov dptr,OEC + movx @dptr,a + + ;; clear PC4 + mov a, #0x00 + mov dptr,OUTC + movx @dptr,a + + ;; set OEB.6 + mov a, #0x40 + mov dptr,OEB + movx @dptr,a + + ;; clear PB6 + mov a, #0x00 + mov dptr,OUTB + movx @dptr,a + + ;; set OEC.[17] + mov a, #0x82 + mov dptr,OEC + movx @dptr,a + + + ;; set PORTCCFG.[01] to route TxD0,RxD0 to serial port + mov dptr, PORTCCFG + mov a, #0x03 + movx @dptr, a + + ;; set up interrupts, autovectoring + ;; set BKPT + mov dptr, USBBAV + movx a,@dptr + setb acc.0 ; AVEN bit to 0 + movx @dptr, a + + mov a,#0x01 ; enable SUDAV: setup data available (for ep0) + mov dptr, USBIRQ + movx @dptr, a ; clear SUDAVI + mov dptr, USBIEN + movx @dptr, a + + mov dptr, IN07IEN + mov a,#0x04 ; enable IN2 int + movx @dptr, a + + mov dptr, OUT07IEN + mov a,#0x04 ; enable OUT2 int + movx @dptr, a + mov dptr, OUT2BC + movx @dptr, a ; arm OUT2 + +;; mov a, #0x84 ; turn on RTS, DTR +;; mov dptr,OUTC +;; movx @dptr, a + + mov a, #0x7 ; turn on DTR + mov dptr,USBBAV + movx @dptr, a + + mov a, #0x20 ; turn on the RED led + mov dptr,OEA + movx @dptr, a + + mov a, #0x80 ; turn on RTS + mov dptr,OUTC + movx @dptr, a + + ;; setup the serial port. 9600 8N1. + mov a,#0x53 ; mode 1, enable rx, clear int + mov SCON, a + ;; using timer2, in 16-bit baud-rate-generator mode + ;; (xtal 12MHz, internal fosc 24MHz) + ;; RCAP2H,RCAP2L = 65536 - fosc/(32*baud) + ;; 57600: 0xFFF2.F, say 0xFFF3 + ;; 9600: 0xFFB1.E, say 0xFFB2 + ;; 300: 0xF63C +#define BAUD 9600 +#define BAUD_TIMEOUT(rate) (65536 - (24 * 1000 * 1000) / (32 * rate)) +#define BAUD_HIGH(rate) HIGH(BAUD_TIMEOUT(rate)) +#define BAUD_LOW(rate) LOW(BAUD_TIMEOUT(rate)) + + mov T2CON, #030h ; rclk=1,tclk=1,cp=0,tr2=0(enable later) + mov r3, #5 + acall set_baud + setb TR2 + mov SCON, #050h + +#if 0 + mov r1, #0x40 + mov a, #0x41 +send: + mov SBUF, a + inc a + anl a, #0x3F + orl a, #0x40 +; xrl a, #0x02 +wait1: + jnb TI, wait1 + clr TI + djnz r1, send +;done: sjmp done + +#endif + + setb EUSB + setb EA + setb ES0 + ;acall dump_stat + + ;; hey, what say we RENUMERATE! (TRM p.62) + mov a, #0 + mov dps, a + mov dptr, USBCS + mov a, #0x02 ; DISCON=0, DISCOE=0, RENUM=1 + movx @dptr, a + ;; now presence pin is floating, simulating disconnect. wait 0.5s + mov r1, #46 +renum_wait1: + mov r2, #0 +renum_wait2: + mov r3, #0 +renum_wait3: + djnz r3, renum_wait3 + djnz r2, renum_wait2 + djnz r1, renum_wait1 ; wait about n*(256^2) 6MHz clocks + mov a, #0x06 ; DISCON=0, DISCOE=1, RENUM=1 + movx @dptr, a + ;; we are back online. the host device will now re-query us + + +main: sjmp main + + + +ISR_Sudav: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + mov a,EXIF + clr acc.4 + mov EXIF,a ; clear INT2 first + mov dptr, USBIRQ ; clear USB int + mov a,#01h + movx @dptr,a + + ;; get request type + mov dptr, SETUPDAT + movx a, @dptr + mov r1, a ; r1 = bmRequestType + inc dptr + movx a, @dptr + mov r2, a ; r2 = bRequest + inc dptr + movx a, @dptr + mov r3, a ; r3 = wValueL + inc dptr + movx a, @dptr + mov r4, a ; r4 = wValueH + + ;; main switch on bmRequest.type: standard or vendor + mov a, r1 + anl a, #0x60 + cjne a, #0x00, setup_bmreq_type_not_standard + ;; standard request: now main switch is on bRequest + ljmp setup_bmreq_is_standard + +setup_bmreq_type_not_standard: + ;; a still has bmreq&0x60 + cjne a, #0x40, setup_bmreq_type_not_vendor + ;; Anchor reserves bRequest 0xa0-0xaf, we use small ones + ;; switch on bRequest. bmRequest will always be 0x41 or 0xc1 + cjne r2, #0x00, setup_ctrl_not_00 + ;; 00 is set baud, wValue[0] has baud rate index + lcall set_baud ; index in r3, carry set if error + jc setup_bmreq_type_not_standard__do_stall + ljmp setup_done_ack +setup_bmreq_type_not_standard__do_stall: + ljmp setup_stall +setup_ctrl_not_00: + cjne r2, #0x01, setup_ctrl_not_01 + ;; 01 is reserved for set bits (parity). TODO + ljmp setup_stall +setup_ctrl_not_01: + cjne r2, #0x02, setup_ctrl_not_02 + ;; 02 is set HW flow control. TODO + ljmp setup_stall +setup_ctrl_not_02: + cjne r2, #0x03, setup_ctrl_not_03 + ;; 03 is control pins (RTS, DTR). + ljmp control_pins ; will jump to setup_done_ack, + ; or setup_return_one_byte +setup_ctrl_not_03: + cjne r2, #0x04, setup_ctrl_not_04 + ;; 04 is send break (really "turn break on/off"). TODO + cjne r3, #0x00, setup_ctrl_do_break_on + ;; do break off: restore PORTCCFG.1 to reconnect TxD0 to serial port + mov dptr, PORTCCFG + movx a, @dptr + orl a, #0x02 + movx @dptr, a + ljmp setup_done_ack +setup_ctrl_do_break_on: + ;; do break on: clear PORTCCFG.0, set TxD high(?) (b1 low) + mov dptr, OUTC + movx a, @dptr + anl a, #0xfd ; ~0x02 + movx @dptr, a + mov dptr, PORTCCFG + movx a, @dptr + anl a, #0xfd ; ~0x02 + movx @dptr, a + ljmp setup_done_ack +setup_ctrl_not_04: + cjne r2, #0x05, setup_ctrl_not_05 + ;; 05 is set desired interrupt bitmap. TODO + ljmp setup_stall +setup_ctrl_not_05: + cjne r2, #0x06, setup_ctrl_not_06 + ;; 06 is query room + cjne r3, #0x00, setup_ctrl_06_not_00 + ;; 06, wValue[0]=0 is query write_room + mov a, tx_ring_out + setb c + subb a, tx_ring_in ; out-1-in = 255 - (in-out) + ljmp setup_return_one_byte +setup_ctrl_06_not_00: + cjne r3, #0x01, setup_ctrl_06_not_01 + ;; 06, wValue[0]=1 is query chars_in_buffer + mov a, tx_ring_in + clr c + subb a, tx_ring_out ; in-out + ljmp setup_return_one_byte +setup_ctrl_06_not_01: + ljmp setup_stall +setup_ctrl_not_06: + cjne r2, #0x07, setup_ctrl_not_07 + ;; 07 is request tx unthrottle interrupt + mov tx_unthrottle_threshold, r3; wValue[0] is threshold value + ljmp setup_done_ack +setup_ctrl_not_07: + ljmp setup_stall + +setup_bmreq_type_not_vendor: + ljmp setup_stall + + +setup_bmreq_is_standard: + cjne r2, #0x00, setup_breq_not_00 + ;; 00: Get_Status (sub-switch on bmRequestType: device, ep, int) + cjne r1, #0x80, setup_Get_Status_not_device + ;; Get_Status(device) + ;; are we self-powered? no. can we do remote wakeup? no + ;; so return two zero bytes. This is reusable +setup_return_two_zero_bytes: + mov dptr, IN0BUF + clr a + movx @dptr, a + inc dptr + movx @dptr, a + mov dptr, IN0BC + mov a, #2 + movx @dptr, a + ljmp setup_done_ack +setup_Get_Status_not_device: + cjne r1, #0x82, setup_Get_Status_not_endpoint + ;; Get_Status(endpoint) + ;; must get stall bit for ep[wIndexL], return two bytes, bit in lsb 0 + ;; for now: cheat. TODO + sjmp setup_return_two_zero_bytes +setup_Get_Status_not_endpoint: + cjne r1, #0x81, setup_Get_Status_not_interface + ;; Get_Status(interface): return two zeros + sjmp setup_return_two_zero_bytes +setup_Get_Status_not_interface: + ljmp setup_stall + +setup_breq_not_00: + cjne r2, #0x01, setup_breq_not_01 + ;; 01: Clear_Feature (sub-switch on wValueL: stall, remote wakeup) + cjne r3, #0x00, setup_Clear_Feature_not_stall + ;; Clear_Feature(stall). should clear a stall bit. TODO + ljmp setup_stall +setup_Clear_Feature_not_stall: + cjne r3, #0x01, setup_Clear_Feature_not_rwake + ;; Clear_Feature(remote wakeup). ignored. + ljmp setup_done_ack +setup_Clear_Feature_not_rwake: + ljmp setup_stall + +setup_breq_not_01: + cjne r2, #0x03, setup_breq_not_03 + ;; 03: Set_Feature (sub-switch on wValueL: stall, remote wakeup) + cjne r3, #0x00, setup_Set_Feature_not_stall + ;; Set_Feature(stall). Should set a stall bit. TODO + ljmp setup_stall +setup_Set_Feature_not_stall: + cjne r3, #0x01, setup_Set_Feature_not_rwake + ;; Set_Feature(remote wakeup). ignored. + ljmp setup_done_ack +setup_Set_Feature_not_rwake: + ljmp setup_stall + +setup_breq_not_03: + cjne r2, #0x06, setup_breq_not_06 + ;; 06: Get_Descriptor (s-switch on wValueH: dev, config[n], string[n]) + cjne r4, #0x01, setup_Get_Descriptor_not_device + ;; Get_Descriptor(device) + mov dptr, SUDPTRH + mov a, #HIGH(desc_device) + movx @dptr, a + mov dptr, SUDPTRL + mov a, #LOW(desc_device) + movx @dptr, a + ljmp setup_done_ack +setup_Get_Descriptor_not_device: + cjne r4, #0x02, setup_Get_Descriptor_not_config + ;; Get_Descriptor(config[n]) + cjne r3, #0x00, setup_stall; only handle n==0 + ;; Get_Descriptor(config[0]) + mov dptr, SUDPTRH + mov a, #HIGH(desc_config1) + movx @dptr, a + mov dptr, SUDPTRL + mov a, #LOW(desc_config1) + movx @dptr, a + ljmp setup_done_ack +setup_Get_Descriptor_not_config: + cjne r4, #0x03, setup_Get_Descriptor_not_string + ;; Get_Descriptor(string[wValueL]) + ;; if (wValueL >= maxstrings) stall + mov a, #((desc_strings_end-desc_strings)/2) + clr c + subb a,r3 ; a=4, r3 = 0..3 . if a<=0 then stall + jc setup_stall + jz setup_stall + mov a, r3 + add a, r3 ; a = 2*wValueL + mov dptr, #desc_strings + add a, dpl + mov dpl, a + mov a, #0 + addc a, dph + mov dph, a ; dph = desc_strings[a]. big endian! (handy) + ;; it looks like my adapter uses a revision of the EZUSB that + ;; contains "rev D errata number 8", as hinted in the EzUSB example + ;; code. I cannot find an actual errata description on the Cypress + ;; web site, but from the example code it looks like this bug causes + ;; the length of string descriptors to be read incorrectly, possibly + ;; sending back more characters than the descriptor has. The workaround + ;; is to manually send out all of the data. The consequence of not + ;; using the workaround is that the strings gathered by the kernel + ;; driver are too long and are filled with trailing garbage (including + ;; leftover strings). Writing this out by hand is a nuisance, so for + ;; now I will just live with the bug. + movx a, @dptr + mov r1, a + inc dptr + movx a, @dptr + mov r2, a + mov dptr, SUDPTRH + mov a, r1 + movx @dptr, a + mov dptr, SUDPTRL + mov a, r2 + movx @dptr, a + ;; done + ljmp setup_done_ack + +setup_Get_Descriptor_not_string: + ljmp setup_stall + +setup_breq_not_06: + cjne r2, #0x08, setup_breq_not_08 + ;; Get_Configuration. always 1. return one byte. + ;; this is reusable + mov a, #1 +setup_return_one_byte: + mov dptr, IN0BUF + movx @dptr, a + mov a, #1 + mov dptr, IN0BC + movx @dptr, a + ljmp setup_done_ack +setup_breq_not_08: + cjne r2, #0x09, setup_breq_not_09 + ;; 09: Set_Configuration. ignored. + ljmp setup_done_ack +setup_breq_not_09: + cjne r2, #0x0a, setup_breq_not_0a + ;; 0a: Get_Interface. get the current altsetting for int[wIndexL] + ;; since we only have one interface, ignore wIndexL, return a 0 + mov a, #0 + ljmp setup_return_one_byte +setup_breq_not_0a: + cjne r2, #0x0b, setup_breq_not_0b + ;; 0b: Set_Interface. set altsetting for interface[wIndexL]. ignored + ljmp setup_done_ack +setup_breq_not_0b: + ljmp setup_stall + + +setup_done_ack: + ;; now clear HSNAK + mov dptr, EP0CS + mov a, #0x02 + movx @dptr, a + sjmp setup_done +setup_stall: + ;; unhandled. STALL + ;EP0CS |= bmEPSTALL + mov dptr, EP0CS + movx a, @dptr + orl a, EP0STALLbit + movx @dptr, a + sjmp setup_done + +setup_done: + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +;;; ============================================================== + +set_baud: ; baud index in r3 + ;; verify a < 10 + mov a, r3 + jb ACC.7, set_baud__badbaud + clr c + subb a, #10 + jnc set_baud__badbaud + mov a, r3 + rl a ; a = index*2 + add a, #LOW(baud_table) + mov dpl, a + mov a, #HIGH(baud_table) + addc a, #0 + mov dph, a + ;; TODO: shut down xmit/receive + ;; TODO: wait for current xmit char to leave + ;; TODO: shut down timer to avoid partial-char glitch + movx a,@dptr ; BAUD_HIGH + mov RCAP2H, a + mov TH2, a + inc dptr + movx a,@dptr ; BAUD_LOW + mov RCAP2L, a + mov TL2, a + ;; TODO: restart xmit/receive + ;; TODO: reenable interrupts, resume tx if pending + clr c ; c=0: success + ret +set_baud__badbaud: + setb c ; c=1: failure + ret + +;;; ================================================== +control_pins: + cjne r1, #0x41, control_pins_in +control_pins_out: + ;TODO BKPT is DTR + mov a, r3 ; wValue[0] holds new bits: b7 is new RTS + xrl a, #0xff ; 1 means active, 0V, +12V ? + anl a, #0x80 + mov r3, a + mov dptr, OUTC + movx a, @dptr ; only change bit 7 + anl a, #0x7F ; ~0x84 + orl a, r3 + movx @dptr, a ; other pins are inputs, bits ignored + ljmp setup_done_ack +control_pins_in: + mov dptr, PINSC + movx a, @dptr + xrl a, #0xff + ljmp setup_return_one_byte + +;;; ======================================== + +ISR_Ep2in: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + mov a,EXIF + clr acc.4 + mov EXIF,a ; clear INT2 first + mov dptr, IN07IRQ ; clear USB int + mov a,#04h + movx @dptr,a + + mov a, #0x20 ; Turn off the green LED + mov dptr,OEA + movx @dptr, a + + + ;; do stuff + lcall start_in + + mov a, #0x20 ; Turn off the green LED + mov dptr,OEA + movx @dptr, a + + + + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +ISR_Ep2out: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + + mov a, #0x10 ; Turn the green LED + mov dptr,OEA + movx @dptr, a + + + + mov a,EXIF + clr acc.4 + mov EXIF,a ; clear INT2 first + mov dptr, OUT07IRQ ; clear USB int + mov a,#04h + movx @dptr,a + + ;; do stuff + + ;; copy data into buffer. for now, assume we will have enough space + mov dptr, OUT2BC ; get byte count + movx a,@dptr + mov r1, a + clr a + mov dps, a + mov dptr, OUT2BUF ; load DPTR0 with source + mov dph1, #HIGH(tx_ring) ; load DPTR1 with target + mov dpl1, tx_ring_in +OUT_loop: + movx a,@dptr ; read + inc dps ; switch to DPTR1: target + inc dpl1 ; target = tx_ring_in+1 + movx @dptr,a ; store + mov a,dpl1 + cjne a, tx_ring_out, OUT_no_overflow + sjmp OUT_overflow +OUT_no_overflow: + inc tx_ring_in ; tx_ring_in++ + inc dps ; switch to DPTR0: source + inc dptr + djnz r1, OUT_loop + sjmp OUT_done +OUT_overflow: + ;; signal overflow + ;; fall through +OUT_done: + ;; ack + mov dptr,OUT2BC + movx @dptr,a + + ;; start tx + acall maybe_start_tx + ;acall dump_stat + + mov a, #0x20 ; Turn off the green LED + mov dptr,OEA + movx @dptr, a + + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +dump_stat: + ;; fill in EP4in with a debugging message: + ;; tx_ring_in, tx_ring_out, rx_ring_in, rx_ring_out + ;; tx_active + ;; tx_ring[0..15] + ;; 0xfc + ;; rx_ring[0..15] + clr a + mov dps, a + + mov dptr, IN4CS + movx a, @dptr + jb acc.1, dump_stat__done; busy: cannot dump, old one still pending + mov dptr, IN4BUF + + mov a, tx_ring_in + movx @dptr, a + inc dptr + mov a, tx_ring_out + movx @dptr, a + inc dptr + + mov a, rx_ring_in + movx @dptr, a + inc dptr + mov a, rx_ring_out + movx @dptr, a + inc dptr + + clr a + jnb TX_RUNNING, dump_stat__no_tx_running + inc a +dump_stat__no_tx_running: + movx @dptr, a + inc dptr + ;; tx_ring[0..15] + inc dps + mov dptr, #tx_ring ; DPTR1: source + mov r1, #16 +dump_stat__tx_ring_loop: + movx a, @dptr + inc dptr + inc dps + movx @dptr, a + inc dptr + inc dps + djnz r1, dump_stat__tx_ring_loop + inc dps + + mov a, #0xfc + movx @dptr, a + inc dptr + + ;; rx_ring[0..15] + inc dps + mov dptr, #rx_ring ; DPTR1: source + mov r1, #16 +dump_stat__rx_ring_loop: + movx a, @dptr + inc dptr + inc dps + movx @dptr, a + inc dptr + inc dps + djnz r1, dump_stat__rx_ring_loop + + ;; now send it + clr a + mov dps, a + mov dptr, IN4BC + mov a, #38 + movx @dptr, a +dump_stat__done: + ret + +;;; ============================================================ + +maybe_start_tx: + ;; make sure the tx process is running. + jb TX_RUNNING, start_tx_done +start_tx: + ;; is there work to be done? + mov a, tx_ring_in + cjne a,tx_ring_out, start_tx__work + ret ; no work +start_tx__work: + ;; tx was not running. send the first character, setup the TI int + inc tx_ring_out ; [++tx_ring_out] + mov dph, #HIGH(tx_ring) + mov dpl, tx_ring_out + movx a, @dptr + mov sbuf, a + setb TX_RUNNING +start_tx_done: + ;; can we unthrottle the host tx process? + ;; step 1: do we care? + mov a, #0 + cjne a, tx_unthrottle_threshold, start_tx__maybe_unthrottle_tx + ;; nope +start_tx_really_done: + ret +start_tx__maybe_unthrottle_tx: + ;; step 2: is there now room? + mov a, tx_ring_out + setb c + subb a, tx_ring_in + ;; a is now write_room. If thresh >= a, we can unthrottle + clr c + subb a, tx_unthrottle_threshold + jc start_tx_really_done ; nope + ;; yes, we can unthrottle. remove the threshold and mark a request + mov tx_unthrottle_threshold, #0 + setb DO_TX_UNTHROTTLE + ;; prod rx, which will actually send the message when in2 becomes free + ljmp start_in + + +serial_int: + push dps + push dpl + push dph + push dpl1 + push dph1 + push acc + jnb TI, serial_int__not_tx + ;; tx finished. send another character if we have one + clr TI ; clear int + clr TX_RUNNING + lcall start_tx +serial_int__not_tx: + jnb RI, serial_int__not_rx + lcall get_rx_char + clr RI ; clear int +serial_int__not_rx: + ;; return + pop acc + pop dph1 + pop dpl1 + pop dph + pop dpl + pop dps + reti + +get_rx_char: + mov dph, #HIGH(rx_ring) + mov dpl, rx_ring_in + inc dpl ; target = rx_ring_in+1 + mov a, sbuf + movx @dptr, a + ;; check for overflow before incrementing rx_ring_in + mov a, dpl + cjne a, rx_ring_out, get_rx_char__no_overflow + ;; signal overflow + ret +get_rx_char__no_overflow: + inc rx_ring_in + ;; kick off USB INpipe + acall start_in + ret + +start_in: + ;; check if the inpipe is already running. + mov a,#0x10 + mov dptr, OEA + movx @dptr,a + + mov dptr, IN2CS + movx a, @dptr + jb acc.1, start_in__done; int will handle it + jb DO_TX_UNTHROTTLE, start_in__do_tx_unthrottle + ;; see if there is any work to do. a serial interrupt might occur + ;; during this sequence? + mov a, rx_ring_in + cjne a, rx_ring_out, start_in__have_work + ret ; nope +start_in__have_work: + ;; now copy as much data as possible into the pipe. 63 bytes max. + clr a + mov dps, a + mov dph, #HIGH(rx_ring) ; load DPTR0 with source + inc dps + mov dptr, IN2BUF ; load DPTR1 with target + movx @dptr, a ; in[0] signals that rest of IN is rx data + inc dptr + inc dps + ;; loop until we run out of data, or we have copied 64 bytes + mov r1, #1 ; INbuf size counter +start_in__loop: + mov a, rx_ring_in + cjne a, rx_ring_out, start_inlocal_irq_enablell_copying + sjmp start_in__kick +start_inlocal_irq_enablell_copying: + inc rx_ring_out + mov dpl, rx_ring_out + movx a, @dptr + inc dps + movx @dptr, a ; write into IN buffer + inc dptr + inc dps + inc r1 + cjne r1, #64, start_in__loop; loop +start_in__kick: + ;; either we ran out of data, or we copied 64 bytes. r1 has byte count + ;; kick off IN + mov a, #0x10 ; Turn the green LED + mov dptr,OEA + movx @dptr, a + mov dptr, IN2BC + mov a, r1 + jz start_in__done + movx @dptr, a + ;; done +start_in__done: + ;acall dump_stat + ret +start_in__do_tx_unthrottle: + ;; special sequence: send a tx unthrottle message + clr DO_TX_UNTHROTTLE + clr a + mov dps, a + mov dptr, IN2BUF + mov a, #1 + movx @dptr, a + inc dptr + mov a, #2 + movx @dptr, a + mov dptr, IN2BC + movx @dptr, a + ret + +putchar: + clr TI + mov SBUF, a +putchar_wait: + jnb TI, putchar_wait + clr TI + ret + + +baud_table: ; baud_high, then baud_low + ;; baud[0]: 110 + .byte BAUD_HIGH(110) + .byte BAUD_LOW(110) + ;; baud[1]: 300 + .byte BAUD_HIGH(300) + .byte BAUD_LOW(300) + ;; baud[2]: 1200 + .byte BAUD_HIGH(1200) + .byte BAUD_LOW(1200) + ;; baud[3]: 2400 + .byte BAUD_HIGH(2400) + .byte BAUD_LOW(2400) + ;; baud[4]: 4800 + .byte BAUD_HIGH(4800) + .byte BAUD_LOW(4800) + ;; baud[5]: 9600 + .byte BAUD_HIGH(9600) + .byte BAUD_LOW(9600) + ;; baud[6]: 19200 + .byte BAUD_HIGH(19200) + .byte BAUD_LOW(19200) + ;; baud[7]: 38400 + .byte BAUD_HIGH(38400) + .byte BAUD_LOW(38400) + ;; baud[8]: 57600 + .byte BAUD_HIGH(57600) + .byte BAUD_LOW(57600) + ;; baud[9]: 115200 + .byte BAUD_HIGH(115200) + .byte BAUD_LOW(115200) + +desc_device: + .byte 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40 + .byte 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab, 1, 2, 3, 0x01 +;;; The "real" device id, which must match the host driver, is that +;;; "0xcd 0x06 0x04 0x01" sequence, which is 0x06cd, 0x0104 + +desc_config1: + .byte 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32 + .byte 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00 + .byte 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01 + .byte 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 + +desc_strings: + .word string_langids, string_mfg, string_product, string_serial +desc_strings_end: + +string_langids: .byte string_langids_end-string_langids + .byte 3 + .word 0 +string_langids_end: + + ;; sigh. These strings are Unicode, meaning UTF16? 2 bytes each. Now + ;; *that* is a pain in the ass to encode. And they are little-endian + ;; too. Use this perl snippet to get the bytecodes: + /* while (<>) { + @c = split(//); + foreach $c (@c) { + printf("0x%02x, 0x00, ", ord($c)); + } + } + */ + +string_mfg: .byte string_mfg_end-string_mfg + .byte 3 +; .byte "ACME usb widgets" + .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00, 0x73, 0x00 +string_mfg_end: + +string_product: .byte string_product_end-string_product + .byte 3 +; .byte "ACME USB serial widget" + .byte 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00 +string_product_end: + +string_serial: .byte string_serial_end-string_serial + .byte 3 +; .byte "47" + .byte 0x34, 0x00, 0x37, 0x00 +string_serial_end: + +;;; ring buffer memory + ;; tx_ring_in+1 is where the next input byte will go + ;; [tx_ring_out] has been sent + ;; if tx_ring_in == tx_ring_out, theres no work to do + ;; there are (tx_ring_in - tx_ring_out) chars to be written + ;; dont let _in lap _out + ;; cannot inc if tx_ring_in+1 == tx_ring_out + ;; write [tx_ring_in+1] then tx_ring_in++ + ;; if (tx_ring_in+1 == tx_ring_out), overflow + ;; else tx_ring_in++ + ;; read/send [tx_ring_out+1], then tx_ring_out++ + + ;; rx_ring_in works the same way + + .org 0x1000 +tx_ring: + .skip 0x100 ; 256 bytes +rx_ring: + .skip 0x100 ; 256 bytes + + + .END + -- cgit v0.10.2 From ae93a55bf948753de0bb8e43fa9c027f786abb05 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 16:19:39 +0300 Subject: emi26: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index 4b9dc81..4b994a0 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -16,18 +16,8 @@ #include #include #include - -#define MAX_INTEL_HEX_RECORD_LENGTH 16 -typedef struct _INTEL_HEX_RECORD -{ - __u32 length; - __u32 address; - __u32 type; - __u8 data[MAX_INTEL_HEX_RECORD_LENGTH]; -} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD; - -/* include firmware (variables) */ -#include "emi26_fw.h" +#include +#include #define EMI26_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */ #define EMI26_PRODUCT_ID 0x0100 /* EMI 2|6 without firmware */ @@ -40,7 +30,9 @@ typedef struct _INTEL_HEX_RECORD #define CPUCS_REG 0x7F92 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ #define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS) -static int emi26_writememory( struct usb_device *dev, int address, unsigned char *data, int length, __u8 bRequest); +static int emi26_writememory( struct usb_device *dev, int address, + const unsigned char *data, int length, + __u8 bRequest); static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi26_load_firmware (struct usb_device *dev); static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id); @@ -50,7 +42,9 @@ static void __exit emi26_exit (void); /* thanks to drivers/usb/serial/keyspan_pda.c code */ -static int emi26_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) +static int emi26_writememory (struct usb_device *dev, int address, + const unsigned char *data, int length, + __u8 request) { int result; unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); @@ -83,9 +77,12 @@ static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit) static int emi26_load_firmware (struct usb_device *dev) { + const struct firmware *loader_fw = NULL; + const struct firmware *bitstream_fw = NULL; + const struct firmware *firmware_fw = NULL; + const struct ihex_binrec *rec; int err; int i; - int pos = 0; /* Position in hex record */ __u32 addr; /* Address to write */ __u8 *buf; @@ -96,6 +93,23 @@ static int emi26_load_firmware (struct usb_device *dev) goto wraperr; } + err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); + if (err) + goto nofw; + + err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw", + &dev->dev); + if (err) + goto nofw; + + err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw", + &dev->dev); + if (err) { + nofw: + err( "%s - request_firmware() failed", __func__); + goto wraperr; + } + /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) { @@ -103,13 +117,17 @@ static int emi26_load_firmware (struct usb_device *dev) goto wraperr; } + rec = (const struct ihex_binrec *)loader_fw->data; /* 1. We need to put the loader for the FPGA into the EZ-USB */ - for (i=0; g_Loader[i].type == 0; i++) { - err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); + while (rec) { + err = emi26_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } + rec = ihex_next_binrec(rec); } /* De-assert reset (let the CPU run) */ @@ -123,15 +141,16 @@ static int emi26_load_firmware (struct usb_device *dev) /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with * a single request. This is _much_ faster! */ + rec = (const struct ihex_binrec *)bitstream_fw->data; do { i = 0; - addr = g_bitstream[pos].address; + addr = be32_to_cpu(rec->addr); /* intel hex records are terminated with type 0 element */ - while ((g_bitstream[pos].type == 0) && (i + g_bitstream[pos].length < FW_LOAD_SIZE)) { - memcpy(buf + i, g_bitstream[pos].data, g_bitstream[pos].length); - i += g_bitstream[pos].length; - pos++; + while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) { + memcpy(buf + i, rec->data, be16_to_cpu(rec->len)); + i += be16_to_cpu(rec->len); + rec = ihex_next_binrec(rec); } err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); if (err < 0) { @@ -148,8 +167,11 @@ static int emi26_load_firmware (struct usb_device *dev) } /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ - for (i=0; g_Loader[i].type == 0; i++) { - err = emi26_writememory(dev, g_Loader[i].address, g_Loader[i].data, g_Loader[i].length, ANCHOR_LOAD_INTERNAL); + for (rec = (const struct ihex_binrec *)loader_fw->data; + rec; rec = ihex_next_binrec(rec)) { + err = emi26_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; @@ -165,9 +187,13 @@ static int emi26_load_firmware (struct usb_device *dev) } /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ - for (i=0; g_Firmware[i].type == 0; i++) { - if (!INTERNAL_RAM(g_Firmware[i].address)) { - err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_EXTERNAL); + + for (rec = (const struct ihex_binrec *)firmware_fw->data; + rec; rec = ihex_next_binrec(rec)) { + if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) { + err = emi26_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_EXTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; @@ -182,9 +208,12 @@ static int emi26_load_firmware (struct usb_device *dev) goto wraperr; } - for (i=0; g_Firmware[i].type == 0; i++) { - if (INTERNAL_RAM(g_Firmware[i].address)) { - err = emi26_writememory(dev, g_Firmware[i].address, g_Firmware[i].data, g_Firmware[i].length, ANCHOR_LOAD_INTERNAL); + for (rec = (const struct ihex_binrec *)firmware_fw->data; + rec; rec = ihex_next_binrec(rec)) { + if (INTERNAL_RAM(be32_to_cpu(rec->addr))) { + err = emi26_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; @@ -205,6 +234,10 @@ static int emi26_load_firmware (struct usb_device *dev) err = 1; wraperr: + release_firmware(loader_fw); + release_firmware(bitstream_fw); + release_firmware(firmware_fw); + kfree(buf); return err; } @@ -257,5 +290,8 @@ MODULE_AUTHOR("Tapio Laxström"); MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader."); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("emi26/loader.fw"); +MODULE_FIRMWARE("emi26/bitstream.fw"); +MODULE_FIRMWARE("emi26/firmware.fw"); /* vi:ai:syntax=c:sw=8:ts=8:tw=80 */ diff --git a/drivers/usb/misc/emi26_fw.h b/drivers/usb/misc/emi26_fw.h deleted file mode 100644 index a47ff10..0000000 --- a/drivers/usb/misc/emi26_fw.h +++ /dev/null @@ -1,5779 +0,0 @@ -/* - * This file is generated from three different files, provided by Emagic. - */ -/* generated Fri Mar 8 15:11:35 EET 2002 */ - -/* - * This firmware is for the Emagic EMI 2|6 Audio Interface - * - * The firmware contained herein is Copyright (c) 1999-2002 Emagic - * as an unpublished work. This notice does not imply unrestricted - * or public access to this firmware which is a trade secret of Emagic, - * and which may not be reproduced, used, sold or transferred to - * any third party without Emagic's written consent. All Rights Reserved. - * - * Permission is hereby granted for the distribution of this firmware - * image as part of a Linux or other Open Source operating system kernel - * in text or binary form as required. - * - * This firmware may not be modified and may only be used with the - * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of - * any driver which includes this firmware, in whole or in part, - * requires the inclusion of this statement. - */ -static INTEL_HEX_RECORD g_bitstream[]={ -{ 16, 0x8010, 0, {0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x07 } }, -{ 16, 0x8020, 0, {0x30,0x01,0x60,0x01,0x00,0x00,0x00,0x0b,0x30,0x01,0x20,0x01,0x00,0x80,0x3f,0x2d } }, -{ 16, 0x8030, 0, {0x30,0x00,0xc0,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x09 } }, -{ 16, 0x8040, 0, {0x30,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x01 } }, -{ 16, 0x8050, 0, {0x30,0x00,0x40,0x00,0x50,0x00,0x3e,0x04,0x08,0x12,0x10,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04 } }, -{ 16, 0x8080, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x84 } }, -{ 16, 0x80b0, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00 } }, -{ 16, 0x80e0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8110, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04 } }, -{ 16, 0x8140, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x13,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8170, 0, {0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84 } }, -{ 16, 0x81a0, 0, {0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf7,0x10,0x01,0x14,0x00,0x25,0x00,0x05 } }, -{ 16, 0x81b0, 0, {0x40,0x01,0x50,0x00,0x94,0x00,0x15,0x00,0x07,0x40,0x01,0xd0,0x00,0x94,0x00,0x25 } }, -{ 16, 0x81c0, 0, {0x80,0x01,0x60,0x02,0xd8,0x00,0xf6,0x00,0x2f,0x80,0x02,0xe0,0x04,0xd8,0x37,0x44 } }, -{ 16, 0x81d0, 0, {0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf2,0x00,0xcc,0x90,0x39,0x20 } }, -{ 16, 0x81e0, 0, {0x0d,0x98,0x03,0xd2,0x00,0xe7,0x80,0x37,0x04,0x0e,0xf1,0x83,0x7e,0x00,0xdf,0x90 } }, -{ 16, 0x81f0, 0, {0x31,0xe4,0x8f,0x79,0x03,0x7c,0x20,0xdf,0x22,0x33,0xc0,0x0c,0xf0,0x22,0x30,0x00 } }, -{ 16, 0x8200, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0x62,0x00,0x80,0x24,0x22,0x20 } }, -{ 16, 0x8210, 0, {0x08,0x98,0x12,0xe2,0x00,0x8b,0x81,0x20,0x94,0x08,0x74,0x02,0x2e,0x00,0x8a,0x01 } }, -{ 16, 0x8220, 0, {0x22,0xc8,0x08,0x92,0x02,0x3d,0x80,0x8b,0x60,0x22,0x80,0x08,0xb0,0x02,0x20,0x04 } }, -{ 16, 0x8230, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x00,0xa0,0x00,0x20,0x00 } }, -{ 16, 0x8240, 0, {0x0b,0x10,0x02,0xc0,0x00,0xa1,0x00,0x24,0x09,0x4a,0x32,0x02,0x48,0x00,0xb1,0x00 } }, -{ 16, 0x8250, 0, {0x62,0xc0,0x09,0xa0,0x46,0xcc,0x24,0x93,0x49,0x2a,0x80,0x48,0x30,0x22,0x62,0x01 } }, -{ 16, 0x8260, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa8,0x12,0xa8,0x00,0x22,0x00 } }, -{ 16, 0x8270, 0, {0x08,0x90,0x02,0xe0,0x00,0x89,0x80,0x22,0x44,0x08,0xb0,0x12,0xa8,0x00,0xa9,0x40 } }, -{ 16, 0x8280, 0, {0x22,0xc0,0x08,0x90,0x82,0xac,0x00,0x9b,0x04,0x2a,0xc4,0x08,0xb0,0x02,0x70,0x04 } }, -{ 16, 0x8290, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x84,0x00,0xe9,0x80,0xb2,0x64 } }, -{ 16, 0x82a0, 0, {0x4d,0xa0,0x03,0xea,0x20,0xe9,0xc0,0x36,0x40,0x0e,0xb0,0x03,0x44,0x00,0xfb,0x90 } }, -{ 16, 0x82b0, 0, {0xb2,0x88,0x0d,0xbc,0x03,0xec,0x08,0x5b,0x00,0x38,0x60,0x2c,0xb0,0x63,0x40,0x04 } }, -{ 16, 0x82c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x26,0xdd,0x90,0x37,0x40 } }, -{ 16, 0x82d0, 0, {0x4f,0xe0,0x13,0xf2,0x80,0xfd,0x00,0x3d,0xa0,0x0d,0x70,0x03,0x75,0x00,0x5e,0x00 } }, -{ 16, 0x82e0, 0, {0x3f,0xa4,0x0d,0xf9,0x03,0x5c,0x10,0xeb,0x00,0x37,0x20,0x0f,0x30,0x03,0xb8,0x00 } }, -{ 16, 0x82f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xe9,0x80,0x32,0x40 } }, -{ 16, 0x8300, 0, {0x0c,0xa1,0x83,0xe8,0x00,0xe9,0x00,0x32,0x42,0x0e,0xb0,0x03,0xac,0x48,0xe9,0x00 } }, -{ 16, 0x8310, 0, {0x3a,0x80,0x0e,0xa4,0x03,0xec,0x00,0xeb,0x00,0xb2,0x03,0x0e,0xb0,0x0b,0x10,0x04 } }, -{ 16, 0x8320, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2e,0x80,0x89,0xd1,0x20,0x40 } }, -{ 16, 0x8330, 0, {0x08,0xa0,0x02,0xc0,0x00,0x81,0x80,0x22,0x58,0x08,0xf5,0x02,0x2f,0x40,0x8b,0x00 } }, -{ 16, 0x8340, 0, {0x20,0xc0,0x08,0x30,0x43,0x7c,0x00,0x87,0x00,0x22,0x40,0x08,0xf0,0x02,0x32,0x00 } }, -{ 16, 0x8350, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x42,0x01,0x9a,0x44,0x28,0xa2 } }, -{ 16, 0x8360, 0, {0x08,0x18,0x02,0xc0,0x80,0xa1,0x80,0xa0,0x00,0x08,0x30,0x02,0x8e,0x00,0xab,0x00 } }, -{ 16, 0x8370, 0, {0x2c,0x40,0x0a,0x30,0x02,0x0c,0x00,0xa3,0x00,0x20,0x44,0x0a,0x30,0x02,0x38,0x00 } }, -{ 16, 0x8380, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x32,0x00,0x96,0x82,0x2b,0xa2 } }, -{ 16, 0x8390, 0, {0x88,0x5a,0x02,0xf2,0x00,0x05,0x80,0x29,0xa0,0x08,0x78,0x42,0xbe,0x00,0x8e,0x84 } }, -{ 16, 0x83a0, 0, {0x2f,0x61,0x0a,0xd8,0x02,0x4e,0x10,0xa7,0x80,0x20,0x28,0x08,0x78,0x02,0x18,0x00 } }, -{ 16, 0x83b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xf2,0x24,0x38,0x80 } }, -{ 16, 0x83c0, 0, {0x2c,0x1a,0x03,0xc4,0x00,0xe0,0x58,0xa0,0x80,0x2e,0x30,0x03,0x88,0x41,0xe3,0x02 } }, -{ 16, 0x83d0, 0, {0x3c,0x40,0x06,0x20,0x03,0x8c,0x00,0xe3,0x00,0x10,0x00,0x0e,0x31,0x43,0x12,0x02 } }, -{ 16, 0x83e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x98,0x00,0xee,0x01,0x37,0x84 } }, -{ 16, 0x83f0, 0, {0x9f,0xd9,0x03,0xf0,0x48,0xfd,0x10,0x37,0xc0,0x07,0xb0,0x03,0x5c,0x00,0xf6,0x10 } }, -{ 16, 0x8400, 0, {0x33,0xc0,0x0d,0xe1,0x03,0xed,0x20,0xdf,0x10,0x3f,0x48,0x0f,0xf0,0x23,0xd0,0x06 } }, -{ 16, 0x8410, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x02,0xcb,0x80,0x30,0xc0 } }, -{ 16, 0x8420, 0, {0x0c,0xa0,0x03,0xe2,0x02,0xc9,0x00,0x3a,0x40,0x0d,0xb6,0x03,0x64,0x00,0xeb,0x00 } }, -{ 16, 0x8430, 0, {0x3e,0xc0,0x0f,0xb0,0x03,0xed,0x00,0xfb,0x01,0x3e,0xe0,0x0c,0xb0,0x02,0xea,0x00 } }, -{ 16, 0x8440, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x00,0x87,0x00,0x21,0xc0 } }, -{ 16, 0x8450, 0, {0x28,0x60,0x02,0xd0,0x00,0x85,0x00,0x2d,0x80,0x48,0xf0,0x82,0x1c,0x00,0xb7,0x00 } }, -{ 16, 0x8460, 0, {0x2d,0x00,0x0b,0x50,0x02,0xdc,0x00,0xb7,0xa0,0x2f,0x80,0x28,0x7a,0x02,0xd2,0x04 } }, -{ 16, 0x8470, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc1,0x00,0xbe,0x00,0x87,0x80,0x21,0xe0 } }, -{ 16, 0x8480, 0, {0x28,0x68,0x02,0xd7,0x00,0x84,0x80,0x2d,0xe0,0x49,0x79,0x06,0x53,0x09,0xb5,0x80 } }, -{ 16, 0x8490, 0, {0x2d,0xe2,0x0b,0x78,0x02,0xde,0x80,0xb7,0x90,0x2d,0xb0,0x08,0x79,0x02,0xf0,0x00 } }, -{ 16, 0x84a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x10,0x83,0x01,0x28,0xc8 } }, -{ 16, 0x84b0, 0, {0x08,0x20,0x02,0xc2,0x06,0x81,0x00,0x2c,0xc8,0x88,0x30,0x62,0x0e,0x21,0xb3,0xa0 } }, -{ 16, 0x84c0, 0, {0x2c,0xc1,0x0b,0xb6,0x02,0xcc,0x00,0xb3,0x00,0x2c,0xe0,0x08,0x30,0x02,0xd2,0x04 } }, -{ 16, 0x84d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xca,0x40,0xb0,0x80 } }, -{ 16, 0x84e0, 0, {0x0c,0x2c,0x02,0xf8,0x00,0xc6,0x20,0x3f,0x90,0x0d,0xa0,0x03,0x7b,0x01,0xee,0xe0 } }, -{ 16, 0x84f0, 0, {0x3f,0xb4,0x0f,0xec,0x03,0xe8,0x00,0xfa,0x00,0x3f,0xa0,0x0c,0xa0,0x03,0xfa,0x04 } }, -{ 16, 0x8500, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe3,0x00,0xf8,0x09,0x26,0x00 } }, -{ 16, 0x8510, 0, {0x0f,0xc1,0x83,0xe0,0x10,0xf8,0x40,0x3c,0x00,0x0f,0x80,0x03,0xe0,0x01,0xf8,0x00 } }, -{ 16, 0x8520, 0, {0x3e,0x00,0x0f,0x81,0x03,0xe0,0x04,0xf8,0x00,0x3e,0x10,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0x8530, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x00,0x3e,0x40 } }, -{ 16, 0x8540, 0, {0x4f,0x90,0x63,0x26,0x84,0x39,0x02,0xb2,0x40,0x0c,0x91,0x03,0x24,0x00,0xf9,0x00 } }, -{ 16, 0x8550, 0, {0x3e,0x40,0x0f,0x90,0x03,0x24,0x00,0xf1,0x00,0x3a,0x44,0x0f,0x90,0x03,0xc2,0x04 } }, -{ 16, 0x8560, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x45,0x00,0x89,0x40,0x2e,0x40 } }, -{ 16, 0x8570, 0, {0x08,0x92,0x0a,0x24,0x00,0xb9,0x31,0x22,0x60,0x88,0x94,0x8a,0x24,0x20,0xb9,0x00 } }, -{ 16, 0x8580, 0, {0x2e,0x40,0x0b,0x90,0x02,0x24,0x00,0xb9,0x00,0x22,0x68,0x0b,0x90,0x02,0xe0,0x00 } }, -{ 16, 0x8590, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0xa0,0x8d,0x84,0x2f,0x40 } }, -{ 16, 0x85a0, 0, {0x0b,0xd1,0x02,0x24,0x00,0xb9,0x00,0x22,0x4a,0x08,0x10,0x02,0x2c,0x40,0xb9,0x00 } }, -{ 16, 0x85b0, 0, {0x2e,0x40,0x0b,0x90,0x02,0x24,0x00,0xb9,0x00,0x2a,0x40,0x0b,0x90,0x02,0xc6,0x00 } }, -{ 16, 0x85c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x14,0x00,0x85,0x80,0x2d,0x40 } }, -{ 16, 0x85d0, 0, {0x08,0x50,0x02,0x04,0x0c,0xb9,0x00,0xa0,0x50,0x08,0x14,0x22,0x04,0x00,0xb1,0x00 } }, -{ 16, 0x85e0, 0, {0x2c,0x40,0x0b,0x10,0x02,0x04,0x00,0xb1,0x28,0x20,0x4a,0x0b,0x13,0x02,0xc2,0x01 } }, -{ 16, 0x85f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc0,0x50,0x3e,0x80 } }, -{ 16, 0x8600, 0, {0x0f,0xc0,0x43,0x20,0x00,0xf8,0x00,0x30,0x00,0x2c,0x80,0x23,0x20,0x00,0xf8,0x51 } }, -{ 16, 0x8610, 0, {0x3e,0x14,0x8f,0x85,0x0b,0x21,0x40,0xf8,0x70,0x3a,0x08,0x0f,0x84,0x83,0xee,0x03 } }, -{ 16, 0x8620, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xc4,0x00,0xf9,0x04,0x3e,0x40 } }, -{ 16, 0x8630, 0, {0x0f,0x90,0x23,0xd4,0x00,0xfd,0x00,0x3f,0x50,0x0f,0x94,0x03,0xf4,0x04,0xfd,0x00 } }, -{ 16, 0x8640, 0, {0x3f,0x41,0x8f,0xd0,0x43,0xe5,0x0c,0xf9,0x02,0x3f,0x4a,0x0f,0x92,0x03,0xe6,0x02 } }, -{ 16, 0x8650, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xd4,0x01,0xfd,0x00,0x3d,0x40 } }, -{ 16, 0x8660, 0, {0x0c,0xd0,0x13,0xf4,0x00,0xd5,0x00,0x33,0x6a,0x1c,0xdc,0x83,0x34,0x00,0xd1,0x04 } }, -{ 16, 0x8670, 0, {0x3e,0x50,0x0c,0x91,0x03,0xe6,0xc0,0xdd,0xb0,0x33,0x6a,0x2c,0x9c,0x83,0xe6,0x00 } }, -{ 16, 0x8680, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x09,0xf8,0x80,0x2e,0x00 } }, -{ 16, 0x8690, 0, {0x88,0x80,0x00,0xe8,0x00,0xba,0x00,0x22,0xb0,0x08,0x8e,0x02,0x28,0x00,0x88,0xa8 } }, -{ 16, 0x86a0, 0, {0x26,0x28,0x08,0x8a,0x22,0xe2,0x00,0x88,0xe4,0x22,0x30,0x08,0x8c,0x02,0xce,0x04 } }, -{ 16, 0x86b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x28,0x2e,0x40 } }, -{ 16, 0x86c0, 0, {0x08,0x10,0x02,0xc4,0x00,0x99,0x00,0x20,0x42,0x48,0x10,0x02,0x64,0x01,0x91,0x80 } }, -{ 16, 0x86d0, 0, {0x2c,0x48,0x08,0x10,0x02,0xc4,0xc0,0x81,0x40,0x20,0x4a,0x08,0x12,0x02,0xc2,0x01 } }, -{ 16, 0x86e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x94,0xa9,0x02,0x2e,0x40 } }, -{ 16, 0x86f0, 0, {0x0a,0x90,0x02,0x64,0x00,0xb9,0x00,0x82,0x60,0x08,0x90,0x02,0x66,0x00,0x89,0x10 } }, -{ 16, 0x8700, 0, {0x24,0x62,0x08,0x90,0x02,0xe4,0x00,0x89,0x02,0x22,0x40,0x18,0x90,0x02,0xc6,0x04 } }, -{ 16, 0x8710, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x00,0xb9,0x04,0x3e,0x40 } }, -{ 16, 0x8720, 0, {0x0c,0x90,0x13,0xe4,0x00,0xd1,0xc0,0x12,0x50,0x28,0x90,0x03,0x44,0x00,0xd9,0x00 } }, -{ 16, 0x8730, 0, {0x3e,0x40,0x28,0x92,0x03,0xe4,0x02,0xd9,0x00,0x32,0x42,0x8c,0x90,0x12,0xe8,0x04 } }, -{ 16, 0x8740, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa6,0x20,0xf9,0x00,0x3e,0x41 } }, -{ 16, 0x8750, 0, {0x2d,0x90,0x03,0xe4,0x00,0xf9,0x20,0x3e,0x40,0x4f,0x90,0x01,0xa4,0x00,0xf9,0x00 } }, -{ 16, 0x8760, 0, {0x36,0x40,0x8f,0x92,0x07,0xe4,0x00,0xf1,0x00,0xbe,0x40,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0x8770, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x3e,0x20 } }, -{ 16, 0x8780, 0, {0x0c,0x80,0x03,0xe0,0x40,0xf8,0x00,0x36,0x12,0x2c,0x00,0x03,0xe0,0xc0,0xf8,0x00 } }, -{ 16, 0x8790, 0, {0x32,0x10,0x0d,0x84,0x03,0xa0,0x00,0xf8,0x02,0x3e,0x08,0x0f,0x80,0x00,0xca,0x04 } }, -{ 16, 0x87a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x3a,0x90,0x8e,0x00,0x2d,0xa0 } }, -{ 16, 0x87b0, 0, {0x80,0xe8,0x02,0xfa,0x00,0xbe,0x40,0x23,0x80,0x08,0xe8,0x02,0xfa,0x00,0x8a,0x00 } }, -{ 16, 0x87c0, 0, {0x36,0x80,0x08,0xa0,0x02,0xe8,0x00,0xba,0x00,0x2f,0x80,0x0b,0xa0,0x03,0x8a,0x00 } }, -{ 16, 0x87d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x46,0x02,0x83,0x00,0x2c,0x80 } }, -{ 16, 0x87e0, 0, {0x08,0x22,0x42,0xc6,0x80,0xb1,0x60,0x2e,0xf4,0x08,0x38,0x22,0xce,0x00,0xa3,0x00 } }, -{ 16, 0x87f0, 0, {0x20,0xc0,0x08,0x30,0x02,0xac,0x00,0xb1,0x00,0x2e,0x40,0x0b,0x30,0x02,0xca,0x00 } }, -{ 16, 0x8800, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x02,0x85,0x01,0x2d,0xc2 } }, -{ 16, 0x8810, 0, {0xa8,0x44,0x02,0xd4,0x00,0xbd,0x01,0x29,0x40,0x18,0x68,0xd2,0xdc,0x00,0x8f,0x80 } }, -{ 16, 0x8820, 0, {0x25,0xcc,0x28,0x73,0x42,0xdc,0x80,0xb5,0x30,0x2d,0xc0,0x1b,0x72,0x02,0xe8,0x00 } }, -{ 16, 0x8830, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x04,0xc6,0x82,0x3d,0xe0 } }, -{ 16, 0x8840, 0, {0x0c,0x48,0x12,0xd6,0x10,0xf5,0x80,0x3c,0xa0,0x0c,0x70,0x03,0xde,0x00,0xe7,0x90 } }, -{ 16, 0x8850, 0, {0x23,0xea,0x04,0x7a,0x03,0x9e,0x00,0xf5,0x80,0x3d,0xe0,0x0f,0x7a,0x03,0xea,0x02 } }, -{ 16, 0x8860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0d,0xac,0x00,0x9c,0x00,0x3e,0xc0 } }, -{ 16, 0x8870, 0, {0x0f,0x80,0x03,0xe4,0x10,0xf9,0x00,0x36,0x01,0x0f,0xa0,0x03,0xc0,0x00,0xeb,0x00 } }, -{ 16, 0x8880, 0, {0x3e,0xd8,0x4e,0xb0,0x83,0xec,0x00,0xf9,0x00,0x3e,0xc0,0x0f,0xb4,0x43,0x82,0x06 } }, -{ 16, 0x8890, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xde,0x00,0xcf,0x84,0x31,0xe0 } }, -{ 16, 0x88a0, 0, {0x0e,0xc8,0x43,0xd6,0x00,0xcd,0x80,0x33,0xe0,0xcd,0xd9,0x03,0x3a,0x00,0xff,0x88 } }, -{ 16, 0x88b0, 0, {0x33,0xe0,0x0f,0xf9,0x13,0xfe,0x24,0xfd,0x80,0x3f,0x20,0x0c,0xf6,0x83,0x10,0x00 } }, -{ 16, 0x88c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0x85,0x00,0x21,0xc4 } }, -{ 16, 0x88d0, 0, {0x28,0x40,0x82,0xd0,0x00,0xd5,0x00,0x23,0x80,0x48,0xc9,0x02,0x1c,0x00,0xb7,0x00 } }, -{ 16, 0x88e0, 0, {0x21,0xc0,0x0b,0x71,0x02,0xde,0x80,0xb5,0x10,0x2d,0xc0,0x28,0xf0,0x02,0x2a,0x04 } }, -{ 16, 0x88f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9c,0x00,0x96,0x00,0x21,0xc0 } }, -{ 16, 0x8900, 0, {0x0a,0x41,0x02,0xf5,0x40,0x8d,0x00,0x21,0x40,0x09,0x52,0x02,0x98,0x20,0xb7,0x00 } }, -{ 16, 0x8910, 0, {0x21,0xc0,0x0b,0x70,0x06,0xdc,0x80,0xb5,0x00,0x2d,0xc0,0x08,0x70,0x02,0x04,0x00 } }, -{ 16, 0x8920, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xcc,0x10,0x98,0x00,0x00,0xc0 } }, -{ 16, 0x8930, 0, {0x88,0x04,0x82,0xc0,0x00,0x91,0x04,0x20,0x03,0x09,0x00,0x02,0x8a,0x00,0xb3,0x0a } }, -{ 16, 0x8940, 0, {0x20,0xc4,0x8b,0x34,0x02,0xcc,0x00,0xb9,0x00,0x2c,0xc0,0x00,0x30,0x02,0x18,0x04 } }, -{ 16, 0x8950, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x15,0xac,0x00,0xdb,0x00,0xb0,0xc0 } }, -{ 16, 0x8960, 0, {0x0e,0x9c,0x02,0xc5,0x00,0xc1,0x10,0xb2,0xc0,0x0d,0xb0,0x0b,0xa7,0x08,0xff,0x00 } }, -{ 16, 0x8970, 0, {0xb3,0xc0,0x0f,0xfa,0x03,0xfc,0x00,0xfd,0x00,0x3e,0xd4,0x0c,0xf0,0x0b,0x2e,0x04 } }, -{ 16, 0x8980, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x04,0xed,0x00,0x3e,0x40 } }, -{ 16, 0x8990, 0, {0x0f,0x84,0x03,0xe5,0x40,0xf9,0x40,0x3e,0x60,0xce,0xb4,0x43,0x64,0x00,0xfb,0x80 } }, -{ 16, 0x89a0, 0, {0x3e,0xc2,0x0f,0xb0,0x13,0xec,0x00,0xf9,0x02,0x3e,0xc0,0x4f,0xb0,0x03,0xe1,0x00 } }, -{ 16, 0x89b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x10,0xff,0x00,0xce,0x00,0x33,0xc0 } }, -{ 16, 0x89c0, 0, {0x0e,0xc0,0x07,0x74,0x04,0xec,0x00,0x11,0x80,0x0c,0xca,0x03,0xfe,0x60,0xff,0x00 } }, -{ 16, 0x89d0, 0, {0x3f,0xc0,0x0f,0xf0,0x83,0x3c,0x00,0xdd,0x00,0xb3,0x50,0x2c,0xf0,0x03,0x20,0x04 } }, -{ 16, 0x89e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x4c,0x04,0x8b,0x0b,0x22,0x70 } }, -{ 16, 0x89f0, 0, {0x08,0x08,0x03,0x67,0x20,0x8a,0x88,0xa2,0x00,0x28,0x84,0x02,0xe7,0x00,0xbb,0x00 } }, -{ 16, 0x8a00, 0, {0x3e,0xc0,0x0b,0xb0,0x02,0x2c,0x00,0xb9,0x00,0x22,0x61,0x08,0xb0,0x03,0x60,0x40 } }, -{ 16, 0x8a10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x20,0x22,0xe2 } }, -{ 16, 0x8a20, 0, {0x0a,0x8c,0x02,0x26,0x00,0xa9,0x80,0x2a,0xc0,0x08,0xb4,0x42,0xed,0x00,0xbb,0x00 } }, -{ 16, 0x8a30, 0, {0x2e,0xc0,0x0b,0x30,0x02,0x2c,0x00,0xb9,0x00,0x20,0x80,0x08,0x30,0x02,0x60,0x00 } }, -{ 16, 0x8a40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0e,0x01,0x81,0x00,0xa0,0xc0 } }, -{ 16, 0x8a50, 0, {0x08,0x81,0x02,0x44,0x00,0x81,0x00,0x28,0x81,0x08,0x32,0x02,0xcc,0x00,0xb3,0x00 } }, -{ 16, 0x8a60, 0, {0x28,0xc0,0x0b,0x30,0x02,0x0c,0x80,0xb1,0x00,0x20,0xc0,0x08,0x30,0x12,0x42,0x01 } }, -{ 16, 0x8a70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0d,0x6c,0x00,0xc2,0x01,0x32,0xc0 } }, -{ 16, 0x8a80, 0, {0x2e,0x80,0x16,0x2c,0x08,0xe9,0x00,0x3a,0x40,0x0c,0x80,0x03,0xec,0x00,0xf7,0x00 } }, -{ 16, 0x8a90, 0, {0x2f,0xc0,0x0f,0xf0,0x0b,0x2c,0x00,0xd9,0x00,0x30,0x40,0x0c,0xf0,0x03,0x60,0x03 } }, -{ 16, 0x8aa0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x0d,0xf8,0x08,0xff,0x00,0x3f,0xc0 } }, -{ 16, 0x8ab0, 0, {0x0f,0xc2,0x17,0xfc,0x00,0xf7,0x00,0x37,0x00,0x0f,0x84,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0x8ac0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xed,0x00,0xfd,0x00,0x3f,0x40,0x0f,0xf0,0x03,0xe8,0x06 } }, -{ 16, 0x8ad0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xcf,0x30,0x17,0x48 } }, -{ 16, 0x8ae0, 0, {0x0c,0x59,0x03,0xb9,0x00,0xdf,0x28,0x35,0x24,0x0d,0x82,0xa3,0x7c,0x80,0xff,0x00 } }, -{ 16, 0x8af0, 0, {0x3f,0xc8,0x0f,0xf2,0x03,0xe4,0xa0,0xef,0x80,0x3f,0xe1,0x8c,0xd8,0x43,0x30,0x00 } }, -{ 16, 0x8b00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xed,0x48,0x89,0x34,0xa3,0x70 } }, -{ 16, 0x8b10, 0, {0x28,0xb0,0x23,0x60,0x00,0x8b,0xc0,0x22,0x40,0x08,0xb4,0x82,0x2f,0x40,0xbf,0xd1 } }, -{ 16, 0x8b20, 0, {0x6f,0xf4,0x8e,0xbd,0x02,0xe7,0x00,0xbb,0x80,0x3a,0xe0,0x08,0x98,0x0a,0x28,0x04 } }, -{ 16, 0x8b30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0xb0,0x91,0x00,0xa8,0x50 } }, -{ 16, 0x8b40, 0, {0x08,0xb2,0x02,0xc8,0x84,0x93,0x00,0x24,0x49,0x0b,0x02,0x02,0x4c,0x00,0xb3,0x04 } }, -{ 16, 0x8b50, 0, {0x2c,0xc0,0x0b,0x30,0x42,0x84,0x00,0xb3,0x00,0x2e,0x00,0x0a,0xb0,0x12,0x22,0x01 } }, -{ 16, 0x8b60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xac,0x02,0x99,0x18,0x2a,0x44 } }, -{ 16, 0x8b70, 0, {0x08,0xb8,0x82,0xa2,0x01,0xbb,0x00,0x28,0x60,0x0a,0xa0,0x12,0x6c,0x00,0xbb,0x00 } }, -{ 16, 0x8b80, 0, {0x6e,0xc0,0x0a,0xb0,0x02,0xe4,0x00,0xbb,0x00,0x2a,0x00,0x2a,0xb0,0x02,0x38,0x04 } }, -{ 16, 0x8b90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xe4,0x08,0xda,0xc0,0x3a,0x60 } }, -{ 16, 0x8ba0, 0, {0x0c,0x18,0x0a,0xeb,0x04,0xdb,0x00,0x36,0xe0,0x07,0x85,0x83,0x6c,0x00,0xfb,0x00 } }, -{ 16, 0x8bb0, 0, {0x2e,0xc0,0x0f,0xb0,0x43,0xe4,0x00,0xeb,0x00,0x3e,0x88,0x0e,0x18,0x03,0x10,0x04 } }, -{ 16, 0x8bc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x41,0x9c,0x10,0xe9,0x00,0x37,0x60 } }, -{ 16, 0x8bd0, 0, {0x87,0xf0,0x17,0x70,0x00,0xcf,0x01,0x37,0xc0,0x4c,0x98,0x03,0xbc,0x00,0xfb,0x00 } }, -{ 16, 0x8be0, 0, {0x3f,0xc2,0x0f,0xf0,0x03,0xe4,0x00,0xff,0x40,0x3f,0xe4,0x0d,0xd9,0x03,0xf0,0x00 } }, -{ 16, 0x8bf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa4,0x00,0xf4,0x00,0x30,0x40 } }, -{ 16, 0x8c00, 0, {0x0f,0xb4,0x03,0x99,0x00,0xfb,0x00,0x3e,0xc0,0x0d,0x04,0x23,0x2c,0x08,0xfb,0x88 } }, -{ 16, 0x8c10, 0, {0x32,0xc0,0x0f,0xb0,0x03,0xe6,0x00,0xdb,0x10,0x3e,0x02,0x0f,0xb0,0x83,0xd0,0x04 } }, -{ 16, 0x8c20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xb9,0x50,0xa2,0x48 } }, -{ 16, 0x8c30, 0, {0x8b,0xb0,0x03,0x20,0x00,0xd7,0x80,0x2e,0xd8,0x00,0x80,0x02,0x3c,0x00,0xbf,0x80 } }, -{ 16, 0x8c40, 0, {0x23,0xe8,0x8b,0xf0,0x02,0xf4,0x40,0x8b,0x40,0x0c,0x42,0x03,0xb6,0x02,0xf2,0x00 } }, -{ 16, 0x8c50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb2,0x44,0x00,0xc8 } }, -{ 16, 0x8c60, 0, {0x0b,0x30,0x12,0x8c,0x00,0xa3,0x80,0x24,0xc8,0x0b,0x00,0x0a,0xcc,0x00,0xb3,0x44 } }, -{ 16, 0x8c70, 0, {0x04,0xc0,0x1b,0x36,0x02,0xc5,0x01,0x83,0x0c,0x2c,0xa0,0x0b,0x30,0x02,0xf8,0x00 } }, -{ 16, 0x8c80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x08,0xb7,0x90,0x21,0x64 } }, -{ 16, 0x8c90, 0, {0x0b,0xf8,0x02,0x4a,0x04,0x97,0x81,0x2f,0xe4,0x0a,0x78,0x02,0x9e,0x00,0xb7,0x80 } }, -{ 16, 0x8ca0, 0, {0x21,0xe0,0x8b,0x78,0x82,0xd6,0x86,0x87,0x84,0x2d,0xa0,0x0b,0x78,0x02,0xc0,0x00 } }, -{ 16, 0x8cb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x04,0x00,0xf2,0x00,0x30,0xc0 } }, -{ 16, 0x8cc0, 0, {0x0f,0x30,0x03,0x8c,0x00,0xe3,0x0a,0x3c,0xc0,0x0f,0x18,0x03,0x8c,0x00,0xf3,0x02 } }, -{ 16, 0x8cd0, 0, {0x30,0xc0,0x1f,0x30,0x01,0xc6,0x80,0xc3,0x00,0x3c,0xc0,0x0f,0x12,0x03,0xda,0x02 } }, -{ 16, 0x8ce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x0d,0xbc,0x00,0xff,0x00,0x3f,0x41 } }, -{ 16, 0x8cf0, 0, {0x0f,0xf0,0x03,0xb8,0x08,0xff,0x08,0x3f,0xc0,0x0d,0xf0,0x03,0x3c,0x20,0xff,0x08 } }, -{ 16, 0x8d00, 0, {0x3b,0xd2,0x0f,0xf0,0x03,0xf4,0x40,0xef,0x00,0x3f,0xc4,0x0f,0xd0,0x03,0xd0,0x06 } }, -{ 16, 0x8d10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xfe,0x00,0x32,0xc2 } }, -{ 16, 0x8d20, 0, {0x0c,0x30,0x0b,0x26,0x00,0xfb,0x80,0x36,0xc0,0x0d,0xa0,0x03,0xec,0x00,0xfb,0xe0 } }, -{ 16, 0x8d30, 0, {0x32,0xd0,0x0f,0xb8,0x43,0x64,0x44,0xdb,0x04,0x3e,0x80,0x0f,0xb0,0x03,0xe2,0x00 } }, -{ 16, 0x8d40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb7,0x00,0xa1,0xc0 } }, -{ 16, 0x8d50, 0, {0x88,0x70,0x03,0x10,0x00,0xb7,0x20,0x21,0xc0,0x08,0x70,0x02,0xdc,0x80,0xb3,0x30 } }, -{ 16, 0x8d60, 0, {0x31,0xc8,0x0b,0x74,0x02,0x14,0x00,0x87,0x40,0x2d,0xc0,0x4b,0x70,0x02,0xd2,0x00 } }, -{ 16, 0x8d70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x96,0x20,0xb6,0x80,0x20,0xe0 } }, -{ 16, 0x8d80, 0, {0x28,0xf8,0x02,0x94,0x10,0xb7,0x81,0x27,0xe2,0x09,0x78,0x02,0xde,0x00,0xb7,0xa0 } }, -{ 16, 0x8d90, 0, {0xa9,0xe8,0x0b,0x38,0x02,0x76,0x00,0x87,0x80,0x2d,0xa0,0x0b,0x58,0x02,0xf0,0x00 } }, -{ 16, 0x8da0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xce,0x10,0xb3,0x00,0x20,0xc4 } }, -{ 16, 0x8db0, 0, {0x08,0x20,0x02,0x80,0x10,0xb3,0x00,0x22,0xc8,0x08,0xb0,0x02,0xcc,0x11,0xb3,0x02 } }, -{ 16, 0x8dc0, 0, {0x28,0xc0,0x0b,0x30,0x02,0x04,0x00,0x93,0x80,0x2c,0xd2,0x0b,0x10,0x02,0xd2,0x04 } }, -{ 16, 0x8dd0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0x40,0x32,0xa0 } }, -{ 16, 0x8de0, 0, {0x0c,0xe4,0x03,0x98,0x80,0xfa,0x00,0x37,0xa0,0x0d,0xe0,0x83,0xe8,0x00,0xfe,0x00 } }, -{ 16, 0x8df0, 0, {0x3a,0x80,0x0b,0xa0,0x03,0x68,0x00,0xd8,0xa0,0x3f,0x90,0x0f,0xa0,0x03,0xfa,0x04 } }, -{ 16, 0x8e00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x08,0xf8,0x08,0x3e,0x00 } }, -{ 16, 0x8e10, 0, {0x0f,0x80,0x03,0x20,0x00,0xf8,0x40,0x3e,0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x04 } }, -{ 16, 0x8e20, 0, {0x30,0x10,0x0f,0x80,0x03,0xe0,0x02,0xe8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0x8e30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf1,0x00,0x32,0x40 } }, -{ 16, 0x8e40, 0, {0x0e,0x90,0x83,0xa4,0x00,0xc9,0x80,0x3e,0x40,0x0e,0x90,0x03,0xa4,0x00,0xf9,0x00 } }, -{ 16, 0x8e50, 0, {0x3e,0x40,0x0c,0x90,0x03,0xe4,0x00,0xc8,0x00,0x3e,0x40,0x8f,0x90,0x03,0x02,0x04 } }, -{ 16, 0x8e60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x40,0xa0,0x62 } }, -{ 16, 0x8e70, 0, {0x08,0x10,0x02,0x24,0x10,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0x8e80, 0, {0x2e,0x52,0x08,0x94,0x02,0xc4,0x00,0x89,0x40,0x2e,0x40,0x0b,0x10,0x03,0x60,0x10 } }, -{ 16, 0x8e90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x18,0x22,0x44 } }, -{ 16, 0x8ea0, 0, {0x0a,0x90,0x02,0xac,0x00,0x89,0x10,0x2e,0xc0,0x0a,0x90,0x02,0xa4,0x00,0xb9,0x80 } }, -{ 16, 0x8eb0, 0, {0x2e,0x60,0x08,0x98,0x02,0xe6,0x02,0x89,0x08,0x2e,0x40,0x0b,0x90,0x02,0x06,0x00 } }, -{ 16, 0x8ec0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0xb1,0x20,0xa0,0x48 } }, -{ 16, 0x8ed0, 0, {0x08,0x90,0x02,0x24,0x08,0x81,0x23,0x2c,0x50,0x08,0x10,0x02,0x04,0x80,0xb1,0x20 } }, -{ 16, 0x8ee0, 0, {0x2c,0x48,0x28,0x12,0x02,0xe4,0x80,0x81,0x20,0x2c,0x40,0x0b,0x98,0x02,0x42,0x05 } }, -{ 16, 0x8ef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x50,0x32,0x00 } }, -{ 16, 0x8f00, 0, {0x0e,0x85,0x03,0xa1,0xe0,0xca,0x00,0x3e,0x00,0x0e,0x85,0x03,0xa0,0x00,0xf8,0x00 } }, -{ 16, 0x8f10, 0, {0x2e,0x00,0x9c,0xa0,0x03,0xe0,0x00,0xc8,0x28,0x3e,0x00,0x0f,0x80,0x03,0x2e,0x01 } }, -{ 16, 0x8f20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xf5,0x10,0x3f,0x44 } }, -{ 16, 0x8f30, 0, {0x0f,0xd0,0x03,0xf4,0x00,0xf1,0x10,0x3d,0x40,0x8f,0xd4,0x03,0xe4,0x50,0xf9,0x10 } }, -{ 16, 0x8f40, 0, {0x3e,0x45,0x0f,0x91,0x03,0xd4,0x40,0xfc,0x00,0x3f,0xc0,0x8f,0xd0,0x23,0xe6,0x04 } }, -{ 16, 0x8f50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x20,0xcd,0xa8,0x33,0x40 } }, -{ 16, 0x8f60, 0, {0x8d,0xd0,0x03,0x26,0x80,0xcd,0x00,0x3d,0x50,0x0c,0x9a,0x03,0x64,0x00,0xf9,0xa0 } }, -{ 16, 0x8f70, 0, {0x7a,0x6a,0x0f,0x9a,0x63,0xe6,0x80,0xc9,0x80,0x3e,0x40,0x0f,0x90,0x03,0x06,0x00 } }, -{ 16, 0x8f80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x00,0x88,0xe0,0x36,0x00 } }, -{ 16, 0x8f90, 0, {0x08,0x80,0x0a,0x21,0x42,0xc8,0x00,0x2e,0x29,0x0c,0xa4,0x42,0x20,0x00,0xb8,0x40 } }, -{ 16, 0x8fa0, 0, {0x2e,0x00,0x0b,0x81,0x02,0xe1,0x00,0x88,0x02,0x3a,0x01,0x0b,0xc0,0x02,0x0e,0x04 } }, -{ 16, 0x8fb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x02,0x81,0x08,0x24,0x40 } }, -{ 16, 0x8fc0, 0, {0x09,0x10,0x02,0x04,0x00,0x91,0x00,0x2c,0x40,0x4b,0x14,0x02,0x44,0x00,0xb5,0x10 } }, -{ 16, 0x8fd0, 0, {0x29,0x40,0x0b,0x50,0x02,0xf5,0x00,0xb5,0x00,0x2d,0x40,0x0b,0xd0,0x02,0x02,0x01 } }, -{ 16, 0x8fe0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa6,0x01,0x89,0x00,0x26,0x40 } }, -{ 16, 0x8ff0, 0, {0x08,0x94,0x02,0x24,0x01,0x89,0x00,0x2e,0x40,0x1a,0x90,0x02,0x6c,0x00,0xbf,0x02 } }, -{ 16, 0x9000, 0, {0x2f,0x40,0x0b,0xd0,0x02,0xf4,0x02,0xbd,0x80,0x2b,0x40,0x8b,0xd8,0x3a,0x06,0x04 } }, -{ 16, 0x9010, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x05,0x36,0x41 } }, -{ 16, 0x9020, 0, {0x0d,0x1c,0x03,0x24,0x00,0xd9,0x00,0x3e,0x42,0x2f,0x94,0x03,0x64,0x00,0xf9,0x00 } }, -{ 16, 0x9030, 0, {0x3a,0x40,0x0f,0x90,0x03,0xc4,0x00,0xf9,0x00,0x3e,0x70,0x0f,0x10,0x03,0x28,0x04 } }, -{ 16, 0x9040, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x84,0x08,0xf9,0x24,0x3e,0x40 } }, -{ 16, 0x9050, 0, {0x0f,0x91,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x41,0x0d,0x10,0x03,0xa4,0x00,0xf9,0x00 } }, -{ 16, 0x9060, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xc9,0x00,0x3e,0x64,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0x9070, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x08,0xc8,0x80,0x32,0x02 } }, -{ 16, 0x9080, 0, {0x0f,0x80,0x03,0x00,0x00,0xc8,0x08,0x3a,0x10,0xce,0x84,0x03,0xe0,0x00,0xfc,0x00 } }, -{ 16, 0x9090, 0, {0x3f,0x00,0x8f,0xc0,0x03,0xf0,0x80,0xfc,0x00,0x3f,0x18,0x0f,0xc0,0x43,0xca,0x04 } }, -{ 16, 0x90a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8e,0x00,0xa1,0x80 } }, -{ 16, 0x90b0, 0, {0x0b,0xe0,0x02,0x28,0x00,0xde,0xc2,0x23,0x90,0x00,0xa0,0x02,0xe8,0x00,0xba,0x00 } }, -{ 16, 0x90c0, 0, {0x2e,0x80,0x0b,0xa0,0x02,0xe8,0x00,0xfa,0x00,0x2e,0x80,0x0b,0xa0,0x02,0xca,0x00 } }, -{ 16, 0x90d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x99,0x81,0x60,0xc0 } }, -{ 16, 0x90e0, 0, {0x0b,0x10,0x02,0x0c,0x00,0x90,0x10,0x2a,0xfc,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x00 } }, -{ 16, 0x90f0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xca,0x00 } }, -{ 16, 0x9100, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x82,0x95,0x40,0x21,0xc0 } }, -{ 16, 0x9110, 0, {0x0b,0x50,0x02,0x1c,0x80,0x90,0x80,0x23,0x01,0x09,0x72,0x12,0xdc,0x00,0xb6,0x00 } }, -{ 16, 0x9120, 0, {0x2d,0x00,0x0b,0x40,0x02,0xd0,0x00,0xb4,0x09,0x2d,0x00,0x4b,0x40,0x82,0xe8,0x00 } }, -{ 16, 0x9130, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x80,0xdd,0x80,0xb1,0xe0 } }, -{ 16, 0x9140, 0, {0x0f,0xda,0x03,0x0f,0x80,0xd4,0x80,0x39,0xe0,0x0b,0x7a,0x03,0xde,0x00,0xf5,0x80 } }, -{ 16, 0x9150, 0, {0x3d,0x20,0x0f,0x48,0x03,0xd6,0x10,0xf6,0x81,0x3d,0xe0,0x8f,0x68,0x03,0xea,0x02 } }, -{ 16, 0x9160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xed,0x00,0x3e,0x00 } }, -{ 16, 0x9170, 0, {0x0f,0x91,0x0b,0xec,0x10,0xf8,0x00,0x3e,0x00,0x0e,0xb0,0x03,0xec,0x00,0xf8,0x00 } }, -{ 16, 0x9180, 0, {0x3e,0xc0,0x4f,0xb0,0x03,0xe8,0x00,0xe9,0x01,0x3e,0x00,0x0f,0x90,0x03,0xc2,0x06 } }, -{ 16, 0x9190, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x20,0xbf,0x81,0x33,0xa4 } }, -{ 16, 0x91a0, 0, {0x8c,0x19,0x03,0x3e,0x00,0xcd,0x80,0x3f,0xe0,0x0f,0xf8,0x83,0x3e,0x00,0xef,0x80 } }, -{ 16, 0x91b0, 0, {0x3f,0xe0,0x0f,0xf9,0x13,0xfa,0x10,0xfd,0x80,0x3f,0xa4,0x0f,0xd8,0x03,0xc0,0x00 } }, -{ 16, 0x91c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xbf,0x20,0x31,0xc2 } }, -{ 16, 0x91d0, 0, {0x08,0x5a,0x02,0x3c,0x02,0x87,0x00,0x2d,0x94,0x0b,0x70,0x0a,0x1c,0x40,0x86,0x10 } }, -{ 16, 0x91e0, 0, {0x2d,0x00,0x0b,0x40,0x02,0xd4,0x00,0xf6,0x00,0x2d,0x40,0x4b,0x60,0x02,0xea,0x04 } }, -{ 16, 0x91f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x01,0x23,0x80 } }, -{ 16, 0x9200, 0, {0x28,0x50,0x02,0x1c,0x00,0x84,0x00,0x2d,0xc0,0x0b,0x30,0x02,0x1c,0x00,0xb5,0x00 } }, -{ 16, 0x9210, 0, {0x2d,0x00,0x0b,0x40,0x06,0xd0,0x40,0xb4,0x08,0x2d,0x80,0x0b,0x48,0x02,0xc0,0x00 } }, -{ 16, 0x9220, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0xb3,0x08,0xa0,0x20 } }, -{ 16, 0x9230, 0, {0x08,0x11,0x8a,0x0e,0x00,0x80,0x00,0x2c,0x90,0x0b,0x37,0x02,0x0c,0x00,0x90,0x00 } }, -{ 16, 0x9240, 0, {0x2c,0xc0,0x0b,0x30,0x42,0xcc,0x04,0xa3,0x80,0x2c,0x50,0x0b,0x30,0x02,0xc8,0x04 } }, -{ 16, 0x9250, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xf9,0x80,0x32,0x60 } }, -{ 16, 0x9260, 0, {0x0c,0xd4,0x03,0x3c,0x80,0x88,0x00,0x3e,0xd0,0x0f,0xf8,0x03,0x28,0x00,0xfa,0x00 } }, -{ 16, 0x9270, 0, {0x3e,0xc0,0x0f,0xb0,0x07,0xec,0x01,0xbb,0x80,0x3e,0x54,0x0f,0xb0,0x06,0xea,0x04 } }, -{ 16, 0x9280, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xee,0x08,0xf9,0x80,0x3a,0xc0 } }, -{ 16, 0x9290, 0, {0x0f,0x90,0x03,0xec,0x00,0xf8,0x40,0x3e,0x58,0x0f,0xb0,0x43,0xe9,0x00,0xeb,0x44 } }, -{ 16, 0x92a0, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x0d,0xf8,0x00,0x3e,0x80,0x0f,0x80,0x03,0xe0,0x00 } }, -{ 16, 0x92b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xcf,0x00,0x33,0x40 } }, -{ 16, 0x92c0, 0, {0x0c,0xd0,0x03,0x3c,0x30,0xcc,0x00,0x3b,0xc0,0x2d,0xf0,0x03,0xd8,0x02,0xcc,0x00 } }, -{ 16, 0x92d0, 0, {0x3d,0x00,0x0c,0xc0,0x03,0xf4,0x00,0xee,0x02,0x37,0x40,0x0c,0xe0,0x03,0xc0,0x44 } }, -{ 16, 0x92e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x18,0x83,0x84,0x20,0x00 } }, -{ 16, 0x92f0, 0, {0x4a,0x10,0x02,0x0c,0x00,0xa8,0x48,0x2e,0x60,0x08,0xb0,0x02,0xe9,0x00,0x89,0x40 } }, -{ 16, 0x9300, 0, {0x2e,0xc0,0x08,0xb0,0x02,0xe8,0x10,0xb1,0x01,0x20,0x80,0x0a,0x90,0x03,0xa0,0x40 } }, -{ 16, 0x9310, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x82,0x22,0x08 } }, -{ 16, 0x9320, 0, {0x08,0x90,0x02,0x2c,0x14,0x88,0x04,0x2c,0x08,0x08,0xb0,0x12,0xe8,0x00,0x8a,0x00 } }, -{ 16, 0x9330, 0, {0x2e,0xc0,0x0a,0xb0,0x02,0xe8,0x01,0xb9,0x00,0x26,0x04,0x08,0x90,0x02,0xe0,0x00 } }, -{ 16, 0x9340, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x80,0xa2,0xc0 } }, -{ 16, 0x9350, 0, {0x0a,0x92,0x02,0x2c,0x00,0xa2,0x00,0x2c,0x00,0x08,0x34,0x02,0xc8,0x00,0x83,0x00 } }, -{ 16, 0x9360, 0, {0x2c,0x00,0x28,0x00,0x02,0xc4,0x01,0xba,0x00,0x22,0xc0,0x02,0x20,0x06,0xc2,0x01 } }, -{ 16, 0x9370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xca,0x00,0xb2,0x00 } }, -{ 16, 0x9380, 0, {0x0c,0x92,0x0b,0x2c,0x04,0xc8,0x04,0x3a,0x00,0x0c,0xb4,0x03,0xe8,0x00,0xc8,0x00 } }, -{ 16, 0x9390, 0, {0x2e,0x00,0x0c,0x80,0x33,0xe1,0x40,0xe8,0x00,0x36,0x00,0x0c,0x80,0x03,0xc0,0x03 } }, -{ 16, 0x93a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3d,0x00 } }, -{ 16, 0x93b0, 0, {0x0f,0xd1,0x0b,0xfc,0x01,0xfc,0x00,0x3f,0x00,0x0f,0xf0,0x03,0xd8,0x00,0xfd,0x00 } }, -{ 16, 0x93c0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x80,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x07,0xa8,0x06 } }, -{ 16, 0x93d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xf3,0x00,0xcf,0x80,0x35,0x60 } }, -{ 16, 0x93e0, 0, {0x4e,0x68,0x43,0x5c,0x00,0xe7,0x80,0x39,0xc0,0x0c,0xc1,0x03,0x7e,0x00,0xcf,0x34 } }, -{ 16, 0x93f0, 0, {0x35,0xe1,0x4d,0xf2,0x03,0x7c,0x00,0xdf,0x38,0x3f,0xc8,0x0f,0xf8,0x03,0xf0,0x00 } }, -{ 16, 0x9400, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0xc8,0x00,0xdb,0x84,0x22,0x60 } }, -{ 16, 0x9410, 0, {0x08,0xac,0x0a,0x2c,0x00,0x8b,0x80,0x22,0x30,0x08,0x91,0x22,0x2c,0x90,0x27,0x61 } }, -{ 16, 0x9420, 0, {0x22,0xca,0x88,0xfc,0x22,0xbf,0x00,0x8b,0x62,0x2f,0xd0,0x09,0xb8,0x03,0xb0,0x04 } }, -{ 16, 0x9430, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xe2,0x80,0xa9,0x02,0x24,0x40 } }, -{ 16, 0x9440, 0, {0x82,0x34,0x42,0x04,0x00,0xa9,0x00,0x28,0xc5,0x48,0x32,0x02,0x4c,0x20,0x83,0x30 } }, -{ 16, 0x9450, 0, {0x20,0xc0,0x08,0x31,0x02,0x0d,0x00,0xb3,0x20,0x2c,0xc4,0x0b,0x30,0x02,0xf2,0x01 } }, -{ 16, 0x9460, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xaa,0x02,0xb9,0x04,0x22,0x60 } }, -{ 16, 0x9470, 0, {0x28,0xb2,0x02,0x26,0x00,0x89,0x88,0x02,0xc0,0x08,0x31,0x12,0xec,0x00,0x8b,0x00 } }, -{ 16, 0x9480, 0, {0x2a,0xd0,0x08,0xb0,0x02,0xac,0x00,0x2b,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0xb0,0x04 } }, -{ 16, 0x9490, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xe2,0x00,0xe3,0x00,0x36,0x20 } }, -{ 16, 0x94a0, 0, {0x0e,0xa4,0x63,0x6e,0x00,0xe1,0xc0,0x1a,0xc1,0x0c,0x80,0x03,0x68,0x70,0xcb,0x00 } }, -{ 16, 0x94b0, 0, {0x36,0x80,0x0d,0xb0,0x03,0x4c,0x00,0xfb,0x04,0x3e,0xc1,0x0f,0xb0,0x03,0xd0,0x04 } }, -{ 16, 0x94c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x04,0xdf,0x00,0x3f,0x00 } }, -{ 16, 0x94d0, 0, {0x0f,0xe8,0x03,0xfc,0x00,0xfd,0x00,0x3f,0x00,0x2b,0x98,0x03,0x3a,0x00,0x77,0x00 } }, -{ 16, 0x94e0, 0, {0x27,0xe4,0x0f,0xf0,0x03,0xfc,0x00,0xdf,0x00,0x3e,0xc0,0x0d,0xf0,0x43,0xf8,0x00 } }, -{ 16, 0x94f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0xa4,0x68,0xcb,0x20,0x3a,0x90 } }, -{ 16, 0x9500, 0, {0x0f,0x24,0xa3,0xac,0x00,0xe9,0x50,0x3a,0xc0,0x0e,0xb4,0x83,0x2c,0x08,0xeb,0x00 } }, -{ 16, 0x9510, 0, {0x3a,0x90,0x0e,0xb0,0x8b,0xec,0x80,0xfb,0x00,0x3e,0xc0,0x0e,0xb0,0x03,0x90,0x04 } }, -{ 16, 0x9520, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x01,0x0a,0x00,0x8b,0xa0,0x20,0x80 } }, -{ 16, 0x9530, 0, {0x0d,0xa8,0x02,0x2c,0x04,0x89,0x40,0x28,0xe8,0x08,0xb2,0x02,0x2c,0x00,0xaf,0x00 } }, -{ 16, 0x9540, 0, {0x02,0x80,0x08,0x7c,0x03,0x3d,0x80,0x3f,0x00,0x2f,0xc0,0x08,0xb0,0x02,0x36,0x00 } }, -{ 16, 0x9550, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x49,0x00,0x03,0x40,0x28,0xc0 } }, -{ 16, 0x9560, 0, {0x2b,0x28,0x4a,0x28,0x00,0xa1,0x00,0x68,0xd2,0x0a,0x20,0x42,0xa4,0x01,0xa3,0x00 } }, -{ 16, 0x9570, 0, {0x02,0x40,0x0a,0x34,0x02,0x0d,0x00,0x33,0x00,0x2c,0xc0,0x0a,0x30,0x00,0xb8,0x00 } }, -{ 16, 0x9580, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x01,0x1a,0x00,0x87,0x90,0x21,0xe4 } }, -{ 16, 0x9590, 0, {0x2b,0xc8,0x12,0x3a,0x00,0x85,0xc0,0x2b,0x21,0x28,0x68,0x02,0xb6,0x00,0xa7,0x84 } }, -{ 16, 0x95a0, 0, {0x23,0x60,0x08,0x38,0x80,0x1e,0x00,0xb7,0x80,0x2d,0xe0,0x08,0x78,0x02,0x2e,0x00 } }, -{ 16, 0x95b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xc1,0x00,0x38,0x54 } }, -{ 16, 0x95c0, 0, {0x0f,0x26,0x83,0x80,0x00,0xe0,0x34,0x28,0xc8,0x0e,0x2c,0x0b,0x8c,0x00,0xe3,0x00 } }, -{ 16, 0x95d0, 0, {0x78,0x45,0x0e,0x30,0x03,0x8e,0x80,0xf3,0x00,0x3c,0xc8,0x0e,0x30,0x03,0x92,0x02 } }, -{ 16, 0x95e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb8,0x00,0xf5,0x02,0x3f,0x44 } }, -{ 16, 0x95f0, 0, {0x0d,0x90,0x03,0xf8,0x00,0xbd,0x14,0x1f,0xc0,0x0f,0xe1,0x23,0x5c,0x44,0x9f,0x42 } }, -{ 16, 0x9600, 0, {0x3f,0xc0,0x0f,0xf4,0x82,0x7d,0x40,0xff,0x10,0x3f,0xc0,0x4f,0x70,0x07,0xd0,0x06 } }, -{ 16, 0x9610, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x02,0xcb,0x00,0x38,0xc0 } }, -{ 16, 0x9620, 0, {0x3c,0xa0,0x03,0xec,0x00,0xe9,0x00,0x3e,0xc0,0x0c,0xb0,0x03,0x20,0x04,0xfb,0x21 } }, -{ 16, 0x9630, 0, {0x3e,0x80,0x4f,0xb4,0x03,0xcf,0x00,0xcb,0x00,0x3e,0xcc,0x4f,0xb0,0x43,0xea,0x00 } }, -{ 16, 0x9640, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x91,0x98,0x00,0x87,0x00,0x21,0xc0 } }, -{ 16, 0x9650, 0, {0x08,0x40,0x02,0xdc,0x04,0xb5,0x00,0x2d,0x00,0x2d,0x70,0x02,0x1c,0x1c,0xb7,0x02 } }, -{ 16, 0x9660, 0, {0x2d,0xc0,0x0b,0x72,0x02,0xdc,0x00,0x87,0x40,0x2d,0xca,0x8b,0x70,0x02,0xf2,0x04 } }, -{ 16, 0x9670, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xba,0x00,0x87,0x88,0x2b,0xe0 } }, -{ 16, 0x9680, 0, {0x18,0x78,0x22,0xd6,0x11,0xa4,0x82,0x2f,0xe0,0x08,0x78,0x02,0x12,0x00,0xb7,0x94 } }, -{ 16, 0x9690, 0, {0x6d,0x60,0x4b,0x7a,0x02,0xde,0x40,0xb7,0xa0,0x2d,0xe0,0x0b,0x78,0x06,0xe0,0x00 } }, -{ 16, 0x96a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xc9,0x12,0x83,0x82,0x28,0xd4 } }, -{ 16, 0x96b0, 0, {0x98,0x00,0x06,0xef,0x05,0xb1,0x90,0x2c,0xc1,0x09,0xb4,0x02,0x0c,0x04,0xb3,0x01 } }, -{ 16, 0x96c0, 0, {0x6c,0xf0,0x0b,0x30,0x02,0xcc,0x00,0xbb,0x00,0x2e,0xc0,0x0b,0x30,0x02,0xd2,0x04 } }, -{ 16, 0x96d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x40,0xca,0x80,0x3b,0xa0 } }, -{ 16, 0x96e0, 0, {0x4c,0xe5,0x02,0xf8,0x80,0xee,0x00,0x3d,0x80,0x2c,0xe0,0x0f,0x38,0x80,0xfa,0x00 } }, -{ 16, 0x96f0, 0, {0x3f,0xa9,0x0f,0xa0,0x03,0xe8,0x00,0xba,0x02,0x3e,0x80,0x8b,0xa0,0x03,0xfa,0x04 } }, -{ 16, 0x9700, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x10,0xf8,0x00,0x26,0x02 } }, -{ 16, 0x9710, 0, {0x0f,0x84,0x03,0xe0,0x24,0xf8,0x00,0x3e,0x00,0x4f,0x80,0xa3,0xe0,0x30,0xf8,0x00 } }, -{ 16, 0x9720, 0, {0x36,0x02,0x0f,0x80,0x23,0xe0,0x04,0x08,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0x9730, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0xb6,0x41 } }, -{ 16, 0x9740, 0, {0x4e,0x99,0x0b,0xa4,0x00,0x69,0x10,0x3e,0x40,0x0c,0x90,0x03,0xa4,0x10,0xc9,0x00 } }, -{ 16, 0x9750, 0, {0x3e,0x40,0x0d,0x92,0x03,0xe6,0x00,0xf9,0x00,0x3a,0x40,0x0e,0x90,0x03,0xc2,0x04 } }, -{ 16, 0x9760, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x81,0x00,0x20,0x42 } }, -{ 16, 0x9770, 0, {0x08,0x14,0x9a,0x24,0x00,0x89,0x00,0x6e,0x50,0x00,0x90,0x02,0x24,0x10,0xd9,0x02 } }, -{ 16, 0x9780, 0, {0x6e,0x40,0x0b,0x94,0x03,0xa7,0x00,0xb9,0x00,0x22,0x40,0x08,0x90,0x03,0xe0,0x00 } }, -{ 16, 0x9790, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x06,0x00,0x99,0x00,0xa6,0x41 } }, -{ 16, 0x97a0, 0, {0x0a,0x90,0x06,0x2c,0x00,0xa9,0x09,0x6e,0x50,0x08,0x91,0x02,0x84,0x04,0x89,0x00 } }, -{ 16, 0x97b0, 0, {0x0e,0x40,0x0b,0x94,0x02,0xe5,0x49,0xb9,0x00,0x0a,0x40,0x0a,0x90,0x02,0xc6,0x00 } }, -{ 16, 0x97c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x06,0x00,0x81,0x00,0x22,0x40 } }, -{ 16, 0x97d0, 0, {0x08,0x12,0x22,0x04,0x81,0xa1,0x00,0x2c,0x40,0x08,0x16,0x02,0x04,0x00,0x91,0x20 } }, -{ 16, 0x97e0, 0, {0x2c,0x40,0x0b,0x12,0x42,0x84,0x89,0xb1,0x20,0x20,0x48,0x08,0x10,0x02,0xc2,0x01 } }, -{ 16, 0x97f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x00,0x36,0x00 } }, -{ 16, 0x9800, 0, {0x0a,0x80,0x03,0xa1,0x40,0xe8,0x00,0x2e,0x00,0x0c,0x00,0x23,0xa1,0x40,0xc8,0x50 } }, -{ 16, 0x9810, 0, {0x2e,0x14,0x0d,0x80,0x03,0xe0,0x00,0xf8,0x50,0x3a,0x00,0x0e,0x80,0x03,0xee,0x03 } }, -{ 16, 0x9820, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x1d,0xd4,0x00,0xf5,0x00,0xbf,0x40 } }, -{ 16, 0x9830, 0, {0x0f,0xd1,0x03,0xf4,0x44,0xdd,0x02,0x3d,0x50,0x2b,0xd1,0x23,0xf4,0x00,0xf9,0x10 } }, -{ 16, 0x9840, 0, {0x3f,0x40,0x0d,0x91,0x03,0xa4,0x48,0xf9,0x12,0x3e,0x4e,0x1f,0x90,0x03,0xa6,0x02 } }, -{ 16, 0x9850, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf4,0x00,0xc5,0x04,0x3b,0x40 } }, -{ 16, 0x9860, 0, {0x0f,0xd8,0x03,0xa7,0x80,0xfd,0x00,0xb3,0x68,0x0d,0xd8,0x43,0xa5,0x10,0xc9,0xa0 } }, -{ 16, 0x9870, 0, {0x32,0x51,0x4f,0x5a,0x43,0x36,0x00,0xc9,0xa0,0x7a,0x68,0x0b,0xd0,0x03,0xc6,0x01 } }, -{ 16, 0x9880, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x18,0xca,0x88,0x88,0x02,0x02,0x00 } }, -{ 16, 0x9890, 0, {0x8d,0x84,0x22,0x23,0x42,0xf8,0x00,0x22,0x04,0x28,0x8a,0xa2,0xaa,0x94,0x88,0xe9 } }, -{ 16, 0x98a0, 0, {0x20,0xa8,0x0a,0x80,0x0a,0x21,0x40,0x80,0xe2,0x2e,0x28,0x0b,0x80,0x02,0xce,0x04 } }, -{ 16, 0x98b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x20,0xa1,0x04,0xa8,0xc0 } }, -{ 16, 0x98c0, 0, {0x0b,0x1c,0x2a,0x24,0x00,0x39,0x04,0x20,0x40,0x2a,0x1e,0x02,0xe4,0x80,0xb1,0x10 } }, -{ 16, 0x98d0, 0, {0x2a,0x48,0x09,0x14,0x46,0x04,0x00,0x81,0x38,0x2c,0x5b,0x0b,0x10,0x02,0xd2,0x00 } }, -{ 16, 0x98e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa4,0x12,0xa9,0x24,0x22,0x40 } }, -{ 16, 0x98f0, 0, {0x29,0x90,0x02,0x24,0x00,0x39,0x00,0x02,0x58,0x08,0x18,0x10,0xe6,0x01,0xb9,0x00 } }, -{ 16, 0x9900, 0, {0xaa,0x44,0x08,0x90,0x02,0x24,0x00,0x89,0x00,0x0e,0x41,0x0b,0x90,0x02,0xc6,0x04 } }, -{ 16, 0x9910, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0xe1,0x01,0x2a,0x64 } }, -{ 16, 0x9920, 0, {0x2f,0x94,0x13,0x24,0x02,0x71,0x60,0x12,0x60,0x4d,0x90,0x00,0xc5,0x02,0xf9,0x00 } }, -{ 16, 0x9930, 0, {0x3a,0x40,0x0f,0x90,0x23,0x24,0x02,0xc9,0x02,0x3a,0x40,0x0f,0x90,0x02,0xe8,0x04 } }, -{ 16, 0x9940, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x01,0xa4,0x00,0xd9,0x00,0x3e,0x60 } }, -{ 16, 0x9950, 0, {0xaf,0x90,0x83,0x64,0x88,0xf9,0x20,0x3e,0x62,0x03,0x90,0x83,0xa4,0x00,0xc9,0x00 } }, -{ 16, 0x9960, 0, {0x36,0x60,0x0f,0x10,0x03,0xc4,0x00,0xf9,0x00,0x7e,0x40,0x0f,0x90,0x03,0xda,0x00 } }, -{ 16, 0x9970, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa1,0x00,0xc8,0x82,0x32,0x00 } }, -{ 16, 0x9980, 0, {0x6f,0x00,0x03,0xa0,0x00,0xd8,0x40,0x30,0x00,0x0e,0x80,0x03,0x60,0x04,0xf8,0x01 } }, -{ 16, 0x9990, 0, {0x3e,0x10,0x4f,0x80,0x8b,0x22,0x00,0xf8,0x00,0x32,0x01,0x0e,0x80,0x03,0xca,0x04 } }, -{ 16, 0x99a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x38,0x00,0x0e,0x00,0xa9,0x90 } }, -{ 16, 0x99b0, 0, {0x2f,0xe6,0x20,0x88,0x00,0x9e,0x80,0x23,0x80,0x0a,0xe8,0x03,0x28,0x00,0xba,0x00 } }, -{ 16, 0x99c0, 0, {0x18,0x80,0x0d,0xec,0x02,0x38,0x80,0xba,0x00,0xa2,0x80,0x08,0xa0,0x03,0x8a,0x00 } }, -{ 16, 0x99d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x02,0x83,0x80,0x20,0xc8 } }, -{ 16, 0x99e0, 0, {0x0b,0x20,0x02,0x0c,0x01,0x92,0x10,0x68,0xc0,0x3a,0x3c,0x02,0xcc,0x10,0x3b,0x02 } }, -{ 16, 0x99f0, 0, {0x0c,0xc0,0x28,0x3c,0x02,0x4e,0x00,0xb3,0x00,0x28,0xc0,0x28,0x30,0x02,0xca,0x00 } }, -{ 16, 0x9a00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x14,0x00,0x87,0x42,0x2b,0xc0 } }, -{ 16, 0x9a10, 0, {0x29,0x70,0x22,0x9c,0x00,0xb6,0x00,0x2b,0xc2,0x0a,0x60,0x86,0x1c,0x00,0xb7,0x21 } }, -{ 16, 0x9a20, 0, {0x29,0xc0,0x00,0x74,0x02,0x5c,0x00,0x37,0x91,0x01,0xe0,0x08,0x74,0x02,0xa8,0x00 } }, -{ 16, 0x9a30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x80,0x21,0xe0 } }, -{ 16, 0x9a40, 0, {0x2f,0x78,0x02,0x9e,0x00,0x96,0x80,0x39,0xe0,0x2e,0xf8,0x03,0xde,0x30,0xf7,0xd0 } }, -{ 16, 0x9a50, 0, {0x2d,0xf2,0x00,0x78,0x03,0x52,0x00,0xf7,0xa2,0x3b,0xe0,0x0e,0x78,0x07,0xea,0x02 } }, -{ 16, 0x9a60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xb4,0x00,0xfb,0x00,0x0c,0xc0 } }, -{ 16, 0x9a70, 0, {0x0f,0x30,0x03,0xec,0x10,0xd3,0x00,0xb4,0xc0,0x2f,0x80,0x03,0x6c,0x48,0xfb,0x00 } }, -{ 16, 0x9a80, 0, {0x3e,0xc8,0x4d,0x90,0x03,0xa4,0x00,0xfb,0x20,0x1e,0xc0,0x0f,0xb0,0x03,0xc2,0x06 } }, -{ 16, 0x9a90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xcc,0x80,0x2b,0x2c } }, -{ 16, 0x9aa0, 0, {0x2f,0xf8,0x03,0x7e,0x00,0x6e,0x80,0x3b,0xa1,0x0d,0xd8,0x43,0x3e,0x00,0xff,0x90 } }, -{ 16, 0x9ab0, 0, {0x33,0xe0,0x0f,0xe9,0x33,0xfe,0x00,0xcf,0xc0,0x3f,0xe2,0x0f,0xd8,0x03,0xc0,0x00 } }, -{ 16, 0x9ac0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xb4,0x40,0x87,0x00,0x21,0x04 } }, -{ 16, 0x9ad0, 0, {0x08,0x78,0x02,0x1c,0x00,0x86,0x00,0x21,0xc0,0x28,0x90,0x02,0xdc,0x00,0xb7,0x10 } }, -{ 16, 0x9ae0, 0, {0x21,0xc0,0x0f,0x73,0x02,0xcc,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x50,0x02,0xea,0x00 } }, -{ 16, 0x9af0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9d,0x00,0xa4,0x00,0x29,0x48 } }, -{ 16, 0x9b00, 0, {0x6a,0xf0,0x82,0x4c,0x00,0xae,0x00,0xa1,0xc4,0x29,0x74,0x02,0x5c,0x40,0xa3,0x10 } }, -{ 16, 0x9b10, 0, {0x61,0xc2,0x0b,0x60,0x06,0xc8,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x50,0x02,0xc0,0x04 } }, -{ 16, 0x9b20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xe6,0x01,0xa3,0x02,0x20,0x40 } }, -{ 16, 0x9b30, 0, {0x28,0x3c,0x02,0x0c,0x00,0x83,0x42,0x20,0xc8,0x08,0x10,0x02,0xcd,0x00,0xb3,0x00 } }, -{ 16, 0x9b40, 0, {0x28,0xf0,0x0b,0x30,0x02,0xcc,0x01,0x83,0x04,0x2c,0xc0,0x83,0x10,0x02,0xc8,0x04 } }, -{ 16, 0x9b50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xaa,0x80,0xeb,0x00,0x38,0xc0 } }, -{ 16, 0x9b60, 0, {0x0a,0x90,0x03,0x7c,0x22,0xa2,0x40,0x32,0x48,0x0d,0xb0,0x0b,0x3e,0x00,0xff,0x00 } }, -{ 16, 0x9b70, 0, {0x33,0xf4,0x0f,0x90,0x03,0xec,0x00,0x8f,0x02,0x3f,0xc0,0x0f,0x90,0x03,0xea,0x04 } }, -{ 16, 0x9b80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe0,0x00,0xd9,0x02,0x3e,0xc0 } }, -{ 16, 0x9b90, 0, {0x0e,0xb6,0x03,0xec,0x00,0xfa,0x20,0x3e,0xc0,0x4f,0x24,0x23,0xac,0x60,0xfb,0x00 } }, -{ 16, 0x9ba0, 0, {0xa6,0xc0,0x0e,0x90,0x03,0xe4,0x00,0xfb,0x00,0x3c,0xc1,0x0f,0x90,0x03,0xe0,0x00 } }, -{ 16, 0x9bb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf8,0x02,0xcf,0x00,0x33,0xe0 } }, -{ 16, 0x9bc0, 0, {0x2c,0xf0,0x13,0xbc,0x00,0x2e,0x10,0xb1,0x64,0x2e,0xf0,0x02,0x3c,0x00,0xff,0x02 } }, -{ 16, 0x9bd0, 0, {0x3f,0xc1,0x4d,0xec,0x63,0xfe,0x00,0xb7,0x00,0x3b,0xc0,0x0c,0xd8,0x03,0xc0,0x44 } }, -{ 16, 0x9be0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x6c,0x28,0x81,0x81,0x22,0xe0 } }, -{ 16, 0x9bf0, 0, {0x0a,0x38,0x02,0x3c,0x04,0xba,0xc9,0x32,0xe0,0x20,0x84,0x02,0x2c,0x00,0xbb,0x00 } }, -{ 16, 0x9c00, 0, {0x2e,0xc0,0x0b,0x9c,0x02,0xe7,0x81,0xbb,0x04,0x22,0xc0,0x0a,0x99,0x02,0xe0,0x00 } }, -{ 16, 0x9c10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x28,0x40,0x88,0x80,0x22,0x88 } }, -{ 16, 0x9c20, 0, {0x28,0xbc,0x42,0xac,0x00,0xba,0x00,0x2a,0x80,0x08,0x84,0x02,0xac,0x00,0xbb,0x00 } }, -{ 16, 0x9c30, 0, {0x2e,0xc0,0x0b,0xb0,0x82,0xe8,0x90,0xab,0x00,0x62,0xc0,0x08,0xb0,0x12,0xe0,0x00 } }, -{ 16, 0x9c40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x89,0x00,0x2a,0x80 } }, -{ 16, 0x9c50, 0, {0x28,0xb2,0x02,0x0c,0x00,0xba,0x00,0x20,0xc0,0x08,0x00,0x02,0x8c,0x00,0xb3,0x00 } }, -{ 16, 0x9c60, 0, {0x2c,0xc0,0x0b,0x30,0x20,0x4c,0x14,0xb3,0x00,0x20,0xc0,0x08,0x30,0x02,0xc2,0x01 } }, -{ 16, 0x9c70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x68,0x00,0xc8,0x00,0xb2,0xc0 } }, -{ 16, 0x9c80, 0, {0x2c,0xb2,0x03,0xac,0x00,0xfa,0x00,0x3a,0xc0,0x4e,0xa5,0x03,0xbc,0x00,0xff,0x00 } }, -{ 16, 0x9c90, 0, {0x3f,0xc0,0x09,0xa0,0x03,0xe9,0x04,0xef,0x00,0xba,0xc0,0x0c,0xb0,0x01,0xc0,0x01 } }, -{ 16, 0x9ca0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xf5,0x00,0x35,0xc0 } }, -{ 16, 0x9cb0, 0, {0xaf,0x34,0x03,0xfc,0x00,0xf4,0x00,0x39,0xc0,0x0f,0xc2,0x03,0x7c,0x00,0xff,0x01 } }, -{ 16, 0x9cc0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0xa0,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8,0x05 } }, -{ 16, 0x9cd0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xff,0x29,0x3d,0x20 } }, -{ 16, 0x9ce0, 0, {0x8e,0xc1,0x03,0x32,0x48,0xdc,0x80,0x23,0x25,0x0e,0xf2,0x03,0x3c,0xc0,0xdf,0x84 } }, -{ 16, 0x9cf0, 0, {0x33,0xc9,0x0f,0xf2,0x03,0xfc,0x00,0xcf,0x80,0x33,0x40,0x0c,0xf2,0x03,0x30,0x00 } }, -{ 16, 0x9d00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0xc0,0xbb,0x60,0x2e,0x08 } }, -{ 16, 0x9d10, 0, {0x08,0x81,0x02,0x20,0x04,0x88,0x20,0x20,0x48,0x08,0xf1,0x82,0x2d,0xc0,0x83,0x00 } }, -{ 16, 0x9d20, 0, {0x22,0xd4,0x09,0xf5,0x02,0xfc,0x08,0x8b,0x01,0x22,0x40,0x28,0xb4,0x02,0x20,0x04 } }, -{ 16, 0x9d30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x20,0xb3,0x09,0x2c,0x82 } }, -{ 16, 0x9d40, 0, {0x08,0x10,0x16,0xa0,0x10,0x90,0x08,0x28,0x48,0x0a,0x32,0x02,0x0c,0x00,0xbb,0x00 } }, -{ 16, 0x9d50, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x02,0x93,0x01,0x20,0x00,0x8a,0x31,0x22,0xe2,0x01 } }, -{ 16, 0x9d60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x04,0xbb,0x00,0x2c,0x80 } }, -{ 16, 0x9d70, 0, {0x08,0x86,0x02,0xa0,0x20,0xa0,0x00,0x2a,0x60,0x0a,0xb0,0x10,0x2c,0x00,0xab,0x0c } }, -{ 16, 0x9d80, 0, {0x6e,0xc0,0x09,0xb0,0x02,0xcc,0x00,0x9b,0x00,0x22,0x60,0x0a,0xb0,0x02,0xf0,0x04 } }, -{ 16, 0x9d90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xec,0x00,0xbb,0x00,0x3e,0x34 } }, -{ 16, 0x9da0, 0, {0x08,0xa0,0x0b,0x83,0x00,0xd9,0x02,0x3a,0xe0,0x2e,0xb0,0x0b,0x2c,0x00,0xf8,0x80 } }, -{ 16, 0x9db0, 0, {0x3e,0xc0,0x4f,0xb0,0x03,0xec,0x00,0xca,0x40,0xb2,0x72,0x0e,0xb0,0x0b,0xc0,0x04 } }, -{ 16, 0x9dc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x10,0xfb,0x00,0x3f,0x00 } }, -{ 16, 0x9dd0, 0, {0x0d,0xf8,0x13,0x70,0x48,0xdd,0x40,0x37,0xc2,0x8d,0xf0,0x03,0xdc,0x00,0xdd,0xc8 } }, -{ 16, 0x9de0, 0, {0x13,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xee,0x40,0x7f,0x40,0x0d,0x70,0x03,0x38,0x00 } }, -{ 16, 0x9df0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x01,0x32,0xc0 } }, -{ 16, 0x9e00, 0, {0x04,0x10,0x03,0x20,0x40,0xe8,0x10,0x3a,0xc0,0x0d,0xb0,0x03,0xac,0x08,0xf8,0x40 } }, -{ 16, 0x9e10, 0, {0xb2,0xc0,0x2c,0xb0,0x33,0xa4,0x82,0xda,0x40,0xba,0x40,0x0f,0xb0,0x03,0xd0,0x04 } }, -{ 16, 0x9e20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3c,0x08,0xbf,0x80,0x22,0xc8 } }, -{ 16, 0x9e30, 0, {0x08,0xb7,0x00,0x23,0x44,0x88,0xd0,0x22,0xd0,0x08,0x70,0x82,0xfc,0x00,0xb2,0xe0 } }, -{ 16, 0x9e40, 0, {0x03,0xf4,0x08,0xf5,0x02,0x37,0x04,0x8b,0xd1,0x22,0x60,0x4b,0xfd,0x02,0xf2,0x00 } }, -{ 16, 0x9e50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x10,0xa4,0x40 } }, -{ 16, 0x9e60, 0, {0x08,0x00,0x02,0x48,0x00,0xa0,0x42,0x2a,0xd0,0x01,0x30,0x02,0x8c,0x00,0xb3,0x80 } }, -{ 16, 0x9e70, 0, {0x2c,0xc0,0x09,0x31,0x02,0xcc,0x00,0x89,0x00,0x22,0xe8,0x03,0x38,0x02,0xf8,0x00 } }, -{ 16, 0x9e80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x1e,0x00,0xb7,0x80,0x27,0x64 } }, -{ 16, 0x9e90, 0, {0x68,0x4a,0x02,0x52,0x00,0x8c,0x80,0x21,0xe0,0x08,0x78,0x02,0xde,0x00,0xb7,0x80 } }, -{ 16, 0x9ea0, 0, {0x2d,0xe2,0x19,0x39,0x02,0x5e,0x30,0x85,0x98,0x21,0xe4,0x0b,0x79,0x02,0xd8,0x00 } }, -{ 16, 0x9eb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf3,0x20,0x34,0x00 } }, -{ 16, 0x9ec0, 0, {0x0c,0xb8,0x03,0x48,0x80,0xe2,0x22,0x38,0xc0,0x0d,0x30,0x03,0x8c,0x00,0xf3,0x00 } }, -{ 16, 0x9ed0, 0, {0x3e,0xc0,0x0d,0x31,0x03,0xec,0x00,0xcb,0x00,0x38,0x06,0x0f,0x30,0x83,0xd2,0x02 } }, -{ 16, 0x9ee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0xff,0x00,0x3b,0x01 } }, -{ 16, 0x9ef0, 0, {0x0f,0xd0,0x03,0x90,0x00,0xf6,0x00,0x3f,0xc0,0x0f,0xf4,0x01,0xfc,0x00,0xff,0x01 } }, -{ 16, 0x9f00, 0, {0x33,0xc2,0x0e,0xf5,0x13,0xbc,0x00,0xed,0x00,0x3f,0xc4,0x0f,0xf0,0x03,0xd0,0x06 } }, -{ 16, 0x9f10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x00,0x3c,0xc0 } }, -{ 16, 0x9f20, 0, {0x0e,0xa0,0x01,0x64,0x01,0xd8,0x00,0x32,0xe0,0x2c,0xb5,0x03,0x2c,0x00,0xf2,0x00 } }, -{ 16, 0x9f30, 0, {0x7a,0xc0,0x0d,0xb4,0x03,0x2d,0x80,0xc9,0x02,0x32,0xc0,0x0c,0xb0,0x03,0x2a,0x00 } }, -{ 16, 0x9f40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x80,0xb7,0x00,0x2d,0xc0 } }, -{ 16, 0x9f50, 0, {0x0d,0x60,0x02,0xd0,0x01,0x84,0x00,0x21,0xc0,0x08,0x30,0x02,0x1d,0x00,0xb7,0x00 } }, -{ 16, 0x9f60, 0, {0x21,0xc8,0x0b,0xf4,0x03,0x1e,0xc0,0x86,0x00,0x21,0xc0,0x08,0x7c,0x03,0x52,0x04 } }, -{ 16, 0x9f70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0xc0,0xb7,0x90,0x2d,0xe0 } }, -{ 16, 0x9f80, 0, {0x08,0x78,0x06,0xd6,0x01,0xb4,0x82,0x21,0xe0,0x08,0x78,0x0a,0x1e,0x00,0xb5,0xc0 } }, -{ 16, 0x9f90, 0, {0x29,0xe8,0x09,0x78,0x02,0x36,0xc1,0x97,0x80,0x28,0xb0,0x0a,0x7a,0x02,0x30,0x00 } }, -{ 16, 0x9fa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xbb,0x00,0x2c,0xe0 } }, -{ 16, 0x9fb0, 0, {0x09,0x35,0x82,0xc0,0xc1,0xa0,0x51,0x20,0xe4,0x08,0x30,0x02,0x8c,0x00,0xbb,0xc4 } }, -{ 16, 0x9fc0, 0, {0x20,0xc0,0x0b,0x30,0x02,0x06,0x00,0x93,0x18,0xaa,0xb0,0x2a,0x30,0x0a,0x52,0x04 } }, -{ 16, 0x9fd0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x01,0x3d,0xac } }, -{ 16, 0x9fe0, 0, {0x4c,0xec,0x13,0x78,0x10,0xf6,0x80,0xb3,0x90,0x0c,0xa0,0x03,0x28,0x00,0xfe,0x00 } }, -{ 16, 0x9ff0, 0, {0x3a,0x81,0x0d,0xa0,0x0f,0x2a,0x80,0xde,0x04,0x3b,0xa0,0x0e,0xa0,0x03,0x3a,0x04 } }, -{ 16, 0xa000, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00 } }, -{ 16, 0xa010, 0, {0x0d,0x80,0x02,0xe1,0x00,0xd8,0x48,0x3e,0x12,0x0f,0x80,0x13,0x60,0x00,0xf8,0x60 } }, -{ 16, 0xa020, 0, {0x3e,0x00,0x07,0x80,0x03,0xa0,0x02,0xe8,0x04,0x26,0x08,0x05,0x80,0x03,0x92,0x00 } }, -{ 16, 0xa030, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x04,0x3a,0x40 } }, -{ 16, 0xa040, 0, {0x0c,0x12,0x03,0x24,0x82,0xc9,0x00,0x36,0x44,0x0f,0x10,0x03,0x24,0x00,0xf9,0x00 } }, -{ 16, 0xa050, 0, {0x36,0x40,0x04,0x90,0x03,0x04,0x00,0xc9,0x00,0x12,0x40,0x0c,0x90,0x03,0x02,0x04 } }, -{ 16, 0xa060, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x81,0x22,0x40 } }, -{ 16, 0xa070, 0, {0x08,0x90,0x1a,0x24,0x00,0x89,0x00,0x22,0x68,0x0b,0x99,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xa080, 0, {0x22,0x40,0x68,0x90,0x0a,0x24,0x00,0x89,0x00,0xa2,0x40,0x08,0x90,0x0a,0x20,0x00 } }, -{ 16, 0xa090, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x10,0x22,0xe0 } }, -{ 16, 0xa0a0, 0, {0x08,0x94,0x00,0x04,0x04,0x8b,0x08,0x26,0xc0,0x0b,0x90,0x02,0x24,0x04,0xb9,0x0c } }, -{ 16, 0xa0b0, 0, {0x24,0x40,0x0a,0x10,0x02,0x24,0x00,0x23,0x02,0x2a,0x40,0xa8,0x10,0x02,0x06,0x00 } }, -{ 16, 0xa0c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x90,0xb1,0x20,0x22,0x40 } }, -{ 16, 0xa0d0, 0, {0x08,0x12,0x02,0x0c,0x10,0x81,0x02,0xa0,0x50,0x0b,0x12,0x02,0x04,0x80,0xb1,0x05 } }, -{ 16, 0xa0e0, 0, {0x00,0x48,0x0a,0x10,0x02,0x04,0xa0,0xa1,0x00,0x28,0x4a,0x08,0x12,0x00,0x02,0x01 } }, -{ 16, 0xa0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x50,0xba,0x14 } }, -{ 16, 0xa100, 0, {0x0c,0x85,0x03,0x01,0x42,0xc8,0x50,0x34,0x00,0x0f,0x85,0x03,0x21,0x40,0xf8,0x00 } }, -{ 16, 0xa110, 0, {0x36,0x00,0x0e,0x80,0x13,0x20,0x80,0xe0,0x00,0x1a,0x08,0x0c,0x00,0x03,0x2e,0x03 } }, -{ 16, 0xa120, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x44,0xf9,0x10,0x3f,0x40 } }, -{ 16, 0xa130, 0, {0x2f,0xd1,0x13,0xf4,0x04,0xf5,0x00,0x3f,0x40,0x0f,0x91,0x0b,0xe4,0x40,0xff,0x28 } }, -{ 16, 0xa140, 0, {0xbe,0x4e,0x0d,0x96,0x83,0xd4,0xa2,0xdd,0x28,0x37,0x4a,0x0f,0x93,0x83,0xe6,0x06 } }, -{ 16, 0xa150, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x05,0xe4,0x10,0xcd,0x00,0x3f,0x40 } }, -{ 16, 0xa160, 0, {0x0f,0xd0,0x03,0x35,0x02,0x5d,0x01,0x31,0x44,0x0f,0xd0,0x03,0x24,0x00,0xf9,0x00 } }, -{ 16, 0xa170, 0, {0x32,0x60,0x0c,0x98,0x83,0xe6,0x40,0xd9,0x00,0x36,0x6a,0x0c,0x9e,0x83,0x26,0x01 } }, -{ 16, 0xa180, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0x88,0x00,0x2e,0x00 } }, -{ 16, 0xa190, 0, {0x0b,0x80,0x42,0x02,0x80,0x8a,0x00,0x22,0x20,0x88,0x80,0x03,0x20,0x08,0xb8,0x82 } }, -{ 16, 0xa1a0, 0, {0x22,0x21,0x08,0x88,0x82,0xe2,0x42,0x88,0xa8,0x22,0x20,0x08,0xce,0x02,0x0e,0x04 } }, -{ 16, 0xa1b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x02,0x81,0x00,0x68,0x40 } }, -{ 16, 0xa1c0, 0, {0x0b,0x10,0x02,0x84,0x01,0xb9,0x00,0x20,0x40,0x49,0x10,0x0a,0x04,0x00,0xb5,0x08 } }, -{ 16, 0xa1d0, 0, {0x21,0x46,0x08,0x50,0x02,0xd4,0x00,0x8d,0x20,0x25,0x4a,0x0b,0x50,0x02,0x42,0x01 } }, -{ 16, 0xa1e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0x89,0x04,0x6e,0x54 } }, -{ 16, 0xa1f0, 0, {0x0b,0x10,0x12,0xa4,0x01,0xa9,0x00,0xa2,0x40,0x18,0x90,0x16,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xa200, 0, {0x23,0x40,0x18,0xd0,0x02,0xf4,0x00,0x8d,0x40,0x21,0x4a,0x0b,0xd0,0x02,0x46,0x04 } }, -{ 16, 0xa210, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x3a,0x50 } }, -{ 16, 0xa220, 0, {0x8f,0x96,0x0b,0x84,0x02,0xf1,0x01,0x30,0x48,0x8d,0x90,0x03,0x24,0x10,0xf9,0x00 } }, -{ 16, 0xa230, 0, {0xb2,0x40,0x2c,0x90,0x03,0xe6,0x40,0xd1,0xc0,0x36,0x50,0x2f,0x90,0x0b,0x68,0x04 } }, -{ 16, 0xa240, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x60 } }, -{ 16, 0xa250, 0, {0x0f,0x99,0xc3,0x64,0x00,0xd9,0x28,0x3e,0x40,0x0d,0x90,0x03,0xa4,0x00,0xf9,0x40 } }, -{ 16, 0xa260, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe4,0x20,0xf9,0x40,0x3e,0x40,0x0c,0x90,0x03,0x8a,0x00 } }, -{ 16, 0xa270, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x01,0x36,0x00 } }, -{ 16, 0xa280, 0, {0x8f,0x80,0x03,0xe0,0x02,0xf8,0x04,0x32,0x00,0x0d,0x80,0x43,0x20,0x02,0xcc,0x00 } }, -{ 16, 0xa290, 0, {0x3f,0x00,0x0f,0xc0,0x13,0x90,0x02,0xdc,0x40,0x3f,0x10,0x4c,0xc0,0x23,0x0a,0x04 } }, -{ 16, 0xa2a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xba,0x00,0x22,0x80 } }, -{ 16, 0xa2b0, 0, {0x0b,0xe8,0x20,0xf8,0x00,0x4e,0xc0,0x23,0xa0,0x08,0xa0,0x03,0x68,0x00,0x8a,0x00 } }, -{ 16, 0xa2c0, 0, {0x2e,0x80,0x1f,0xa0,0x02,0x2a,0x06,0x8a,0x00,0x2e,0xa0,0x02,0x60,0x03,0x0a,0x00 } }, -{ 16, 0xa2d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x00,0xb3,0x00,0x20,0xc0 } }, -{ 16, 0xa2e0, 0, {0x0b,0x3d,0x02,0xc0,0x03,0x23,0x00,0x20,0xe0,0x01,0xb0,0x06,0x4c,0x00,0x8b,0x00 } }, -{ 16, 0xa2f0, 0, {0x2e,0xc0,0x4b,0x30,0x02,0x8e,0x08,0x83,0x80,0x2c,0xc4,0x00,0x34,0x8e,0x4a,0x00 } }, -{ 16, 0xa300, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x80,0xb5,0x80,0x61,0xc0 } }, -{ 16, 0xa310, 0, {0x0b,0x40,0x02,0xd4,0x00,0x84,0x08,0x23,0xc2,0x08,0x50,0x02,0x5e,0xc0,0x84,0x01 } }, -{ 16, 0xa320, 0, {0x2d,0x00,0x8a,0x08,0x02,0x10,0x24,0x84,0x08,0x6d,0x00,0x0a,0x03,0x12,0x28,0x00 } }, -{ 16, 0xa330, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf5,0x82,0x21,0x60 } }, -{ 16, 0xa340, 0, {0x0f,0x78,0x03,0xd6,0x04,0xae,0x80,0x31,0xe0,0x0d,0x58,0x23,0x7e,0x00,0xc6,0x80 } }, -{ 16, 0xa350, 0, {0x2d,0xe0,0x0b,0x78,0x03,0x8e,0x00,0xd7,0x82,0x3d,0xf0,0x0c,0x7a,0x03,0x6a,0x02 } }, -{ 16, 0xa360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf1,0x00,0xba,0xd8 } }, -{ 16, 0xa370, 0, {0x0f,0x80,0x03,0xe4,0x12,0xf8,0x00,0xbe,0x80,0x0e,0x10,0x03,0xec,0x00,0xf9,0x00 } }, -{ 16, 0xa380, 0, {0x3e,0x00,0x5f,0x80,0x03,0xe0,0x08,0xf8,0x04,0x3c,0x00,0x0f,0x80,0x03,0xc2,0x06 } }, -{ 16, 0xa390, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x20,0xff,0x80,0x3f,0xf0 } }, -{ 16, 0xa3a0, 0, {0x0f,0xf8,0x03,0xd2,0x00,0xef,0x84,0xb3,0x61,0x0c,0xb9,0x03,0xfe,0x00,0xff,0x80 } }, -{ 16, 0xa3b0, 0, {0x33,0xe0,0x0c,0xf8,0x13,0x22,0x11,0xcd,0x90,0x3f,0x60,0x0c,0xe8,0x03,0x10,0x00 } }, -{ 16, 0xa3c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xf5,0x00,0x2d,0xc0 } }, -{ 16, 0xa3d0, 0, {0x0b,0x00,0x02,0xd4,0x04,0x84,0x20,0x23,0x40,0x08,0x5a,0x02,0xdc,0x00,0xb4,0x00 } }, -{ 16, 0xa3e0, 0, {0x21,0x00,0x28,0xc2,0x02,0x1e,0x04,0x86,0x04,0x2d,0x88,0x08,0xd0,0x02,0x2a,0x04 } }, -{ 16, 0xa3f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9c,0x00,0xb5,0x00,0x2d,0x40 } }, -{ 16, 0xa400, 0, {0x0b,0x70,0x02,0xf4,0x20,0xa7,0x04,0x21,0xc0,0x0a,0x50,0x02,0xdc,0x00,0xbe,0x00 } }, -{ 16, 0xa410, 0, {0x21,0xc0,0x08,0x70,0x12,0x00,0x00,0x85,0x00,0x2d,0x40,0x88,0x68,0x0a,0x04,0x00 } }, -{ 16, 0xa420, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xcc,0x00,0xa1,0x00,0x2e,0xc0 } }, -{ 16, 0xa430, 0, {0x1b,0x08,0x06,0xc4,0x20,0x80,0x00,0x20,0x98,0x1a,0x10,0x02,0xcc,0x00,0xb1,0x08 } }, -{ 16, 0xa440, 0, {0x20,0x00,0x08,0x00,0x02,0x0c,0x01,0x82,0xc0,0x2c,0xac,0x28,0x90,0x22,0x18,0x04 } }, -{ 16, 0xa450, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xb3,0x00,0x3e,0x40 } }, -{ 16, 0xa460, 0, {0x0f,0xba,0x03,0xe5,0x02,0xe9,0x04,0x32,0x90,0xae,0xb0,0x03,0xfc,0x10,0xfb,0x40 } }, -{ 16, 0xa470, 0, {0xb2,0x00,0x0c,0x80,0x0b,0x2c,0x02,0x82,0x18,0x3f,0xa0,0x0c,0xd0,0x03,0x2e,0x04 } }, -{ 16, 0xa480, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0xec,0x04,0xfb,0x01,0x3e,0x40 } }, -{ 16, 0xa490, 0, {0x0f,0xb6,0x43,0xe4,0x00,0xf8,0x00,0x3e,0x80,0x01,0x90,0x03,0xec,0x00,0xf8,0x81 } }, -{ 16, 0xa4a0, 0, {0x3e,0xd0,0x0d,0xb4,0x53,0xe0,0x00,0xf9,0x40,0x3e,0x40,0x0f,0xa0,0x03,0xe0,0x00 } }, -{ 16, 0xa4b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xdc,0x02,0xcd,0x80,0x33,0x60 } }, -{ 16, 0xa4c0, 0, {0x2c,0xda,0x03,0xfc,0x00,0xec,0x00,0x33,0x40,0x0f,0xf2,0x03,0x7c,0x04,0xfe,0x00 } }, -{ 16, 0xa4d0, 0, {0x32,0x00,0x0c,0xc8,0x03,0x3c,0x00,0xce,0x00,0x31,0x80,0x0c,0xd1,0x03,0x24,0x04 } }, -{ 16, 0xa4e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x91,0x04,0x6c,0x00,0x09,0x00,0x2a,0x64 } }, -{ 16, 0xa4f0, 0, {0x08,0x8e,0x02,0xc2,0x10,0xa0,0x10,0x3e,0x10,0x0b,0x98,0x02,0xec,0x00,0xb9,0x00 } }, -{ 16, 0xa500, 0, {0x02,0xd8,0x08,0xbe,0x22,0x20,0x00,0x89,0x00,0x22,0x50,0x08,0xa0,0x02,0x20,0x40 } }, -{ 16, 0xa510, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x0b,0x20,0x22,0x40 } }, -{ 16, 0xa520, 0, {0x08,0xa0,0x02,0xe5,0x42,0xab,0x04,0x22,0x18,0x0b,0xb0,0x02,0x6c,0x00,0xb3,0x00 } }, -{ 16, 0xa530, 0, {0x20,0x04,0x08,0x01,0x02,0x00,0x04,0xa8,0x40,0x22,0x10,0x08,0x80,0x02,0x20,0x00 } }, -{ 16, 0xa540, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x08,0x83,0x00,0x28,0x40 } }, -{ 16, 0xa550, 0, {0x08,0x04,0x02,0xc4,0x02,0xa8,0x00,0x2c,0x00,0x0b,0x12,0x02,0xcc,0x00,0xb0,0x00 } }, -{ 16, 0xa560, 0, {0x20,0xc0,0x40,0x30,0x02,0x0c,0x00,0x8b,0x00,0xa8,0xc0,0x08,0x30,0x02,0x02,0x11 } }, -{ 16, 0xa570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0d,0x6c,0x00,0xc9,0x00,0x33,0x40 } }, -{ 16, 0xa580, 0, {0x0c,0xb0,0x03,0xec,0x02,0xeb,0x00,0x32,0x40,0x0f,0xb0,0x03,0x6c,0x00,0xfa,0x00 } }, -{ 16, 0xa590, 0, {0x32,0x00,0x0c,0x80,0x03,0x20,0x80,0xc8,0x00,0x30,0x00,0x0c,0x80,0x03,0x20,0x03 } }, -{ 16, 0xa5a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xfd,0x00,0x3f,0x40 } }, -{ 16, 0xa5b0, 0, {0x0f,0xc2,0x13,0xf0,0x00,0xf4,0x00,0x3f,0x00,0x4f,0xd4,0x03,0xfc,0x00,0xf5,0x00 } }, -{ 16, 0xa5c0, 0, {0x3f,0xc0,0x8f,0xf0,0x03,0xfc,0x40,0xff,0x00,0x37,0xc0,0x2f,0xf0,0x03,0xe8,0x06 } }, -{ 16, 0xa5d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0x00,0xcc,0x00,0x33,0x00 } }, -{ 16, 0xa5e0, 0, {0x0e,0xd0,0x0b,0x33,0x00,0xcc,0x00,0x33,0xe0,0x0f,0xc0,0x83,0x7c,0x00,0xcf,0x20 } }, -{ 16, 0xa5f0, 0, {0x7b,0x09,0x8c,0xf8,0x03,0xfe,0x50,0xcf,0x38,0x3f,0xe1,0x0d,0xc2,0x03,0xf0,0x00 } }, -{ 16, 0xa600, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe2,0x00,0x98,0x08,0x20,0x80 } }, -{ 16, 0xa610, 0, {0x08,0x98,0x02,0x20,0x00,0x88,0xd0,0x22,0xe0,0x0e,0xb4,0x22,0x7d,0x19,0x9f,0x69 } }, -{ 16, 0xa620, 0, {0x2e,0x90,0x08,0x30,0x92,0x28,0x81,0xdb,0x64,0x2e,0xe1,0x88,0x16,0xa2,0xe0,0x04 } }, -{ 16, 0xa630, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x00,0x90,0x24,0x20,0x01 } }, -{ 16, 0xa640, 0, {0x08,0x10,0x16,0x00,0x82,0x83,0x01,0x28,0xc1,0x0b,0x02,0x82,0x0c,0xe0,0xa3,0x10 } }, -{ 16, 0xa650, 0, {0x28,0x0e,0x1b,0x92,0x02,0x84,0x84,0x93,0x20,0x2e,0xc0,0x08,0x31,0x02,0xe2,0x01 } }, -{ 16, 0xa660, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa8,0x10,0x98,0x00,0x22,0x80 } }, -{ 16, 0xa670, 0, {0x08,0x90,0x02,0x00,0x60,0x8a,0x10,0x2a,0xc0,0x0a,0x20,0x02,0x6c,0x18,0xbb,0x00 } }, -{ 16, 0xa680, 0, {0x6e,0x60,0x2b,0x90,0x02,0x46,0x20,0x8b,0x00,0x2e,0xc2,0x08,0xb1,0x82,0xf0,0x04 } }, -{ 16, 0xa690, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xe4,0x02,0xcb,0x00,0xb2,0x40 } }, -{ 16, 0xa6a0, 0, {0x2c,0x92,0x03,0x27,0x00,0x88,0x00,0xba,0xc0,0x0f,0x88,0x03,0x2c,0x00,0xeb,0x04 } }, -{ 16, 0xa6b0, 0, {0x3a,0xa0,0xcf,0x2c,0xa3,0xed,0x00,0x9b,0x00,0x3c,0xf0,0x2d,0x8c,0x33,0xd0,0x04 } }, -{ 16, 0xa6c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x04,0xef,0x00,0x3f,0xc0 } }, -{ 16, 0xa6d0, 0, {0x0d,0x51,0x03,0xf0,0x00,0xf1,0x81,0x37,0xc0,0x0e,0xf4,0x03,0x9c,0x10,0xcf,0x00 } }, -{ 16, 0xa6e0, 0, {0x3d,0x80,0x0c,0xec,0x07,0xb8,0x08,0xff,0x02,0x1f,0xc4,0x0f,0xc8,0x03,0xf8,0x00 } }, -{ 16, 0xa6f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x9e,0x00,0xc3,0x00,0x38,0x40 } }, -{ 16, 0xa700, 0, {0x0c,0x92,0x03,0xa4,0x80,0xfb,0x20,0x3a,0xc0,0x0d,0x94,0x03,0x2c,0x40,0xfb,0x00 } }, -{ 16, 0xa710, 0, {0x3e,0x01,0x0f,0x80,0x03,0xe5,0x00,0xeb,0x00,0x3a,0xc0,0x0d,0x84,0x0b,0x10,0x04 } }, -{ 16, 0xa720, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x08,0x8b,0x02,0x22,0xc0 } }, -{ 16, 0xa730, 0, {0x08,0x92,0x03,0x21,0x00,0x8b,0x48,0x22,0xc0,0x0b,0xb7,0x02,0x3d,0x40,0x3f,0x01 } }, -{ 16, 0xa740, 0, {0x22,0x74,0x0b,0x90,0x02,0x28,0x04,0xbf,0x00,0xb2,0xc0,0x0b,0x85,0x02,0x32,0x00 } }, -{ 16, 0xa750, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x40,0x01,0x80,0x00,0x28,0x00 } }, -{ 16, 0xa760, 0, {0x08,0x2c,0x12,0x88,0x40,0xb0,0x40,0x08,0xc0,0x0b,0x18,0x02,0x0e,0x00,0xb3,0x00 } }, -{ 16, 0xa770, 0, {0x28,0x20,0x11,0x30,0x02,0x0c,0x00,0xb3,0x00,0x24,0x00,0x09,0x00,0x06,0x38,0x00 } }, -{ 16, 0xa780, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x12,0x00,0x84,0x80,0x21,0xa0 } }, -{ 16, 0xa790, 0, {0x28,0x68,0x12,0x3a,0x00,0x84,0x80,0x25,0xe0,0x8b,0x58,0x02,0x1e,0x40,0xb7,0x82 } }, -{ 16, 0xa7a0, 0, {0x21,0xa6,0x0b,0x78,0x02,0x1a,0x00,0xb7,0x80,0x21,0x20,0x0b,0x58,0x02,0x08,0x00 } }, -{ 16, 0xa7b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xc8,0x21,0x38,0x09 } }, -{ 16, 0xa7c0, 0, {0x0c,0x28,0x03,0x80,0x01,0xf1,0x00,0x38,0xc0,0x0d,0x85,0x02,0x0c,0x00,0xfb,0x00 } }, -{ 16, 0xa7d0, 0, {0x38,0x85,0x0f,0x10,0x03,0x8c,0x00,0xeb,0x10,0x3c,0xc8,0x0d,0x30,0x03,0x12,0x02 } }, -{ 16, 0xa7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x98,0x00,0xfc,0x01,0x3f,0x80 } }, -{ 16, 0xa7f0, 0, {0x0f,0x68,0x03,0xd0,0x40,0xfc,0x00,0x3b,0xc0,0x0d,0xc0,0x03,0xfc,0x20,0xff,0x00 } }, -{ 16, 0xa800, 0, {0x3b,0xc5,0x0f,0xf0,0x0b,0xb4,0x40,0xff,0x18,0x3f,0x00,0x0f,0xf1,0x03,0xd0,0x06 } }, -{ 16, 0xa810, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xeb,0x00,0xb0,0x41 } }, -{ 16, 0xa820, 0, {0x0c,0xa0,0x03,0xe0,0x04,0xca,0x04,0xb0,0xe0,0x0e,0xb0,0x03,0xec,0x80,0xcb,0x20 } }, -{ 16, 0xa830, 0, {0x32,0x81,0x0c,0xa0,0x03,0xee,0x00,0xdb,0x00,0x3e,0x00,0x0e,0xb0,0x03,0x2a,0x00 } }, -{ 16, 0xa840, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x04,0x87,0x00,0x21,0xc0 } }, -{ 16, 0xa850, 0, {0x48,0x60,0x02,0xf0,0x00,0x87,0x00,0x21,0xc0,0x08,0x70,0x02,0xfc,0xa0,0x83,0x28 } }, -{ 16, 0xa860, 0, {0xa3,0x80,0x08,0x60,0x02,0xdc,0x00,0x87,0x20,0x2d,0xc0,0x0b,0x70,0x02,0x12,0x04 } }, -{ 16, 0xa870, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9c,0x02,0xa3,0x80,0x21,0x60 } }, -{ 16, 0xa880, 0, {0x08,0x68,0x02,0xd2,0x00,0x87,0x80,0x21,0xe0,0x29,0x78,0x02,0xde,0x80,0x87,0x90 } }, -{ 16, 0xa890, 0, {0x21,0xa0,0x19,0x48,0x02,0xfe,0x00,0x97,0x80,0x2d,0xe0,0x0a,0x38,0x82,0x30,0x00 } }, -{ 16, 0xa8a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x01,0x83,0x80,0x20,0xc0 } }, -{ 16, 0xa8b0, 0, {0x08,0x20,0x42,0xc0,0x30,0x83,0x70,0xa0,0xc0,0x89,0x34,0x02,0xcc,0x02,0x83,0x00 } }, -{ 16, 0xa8c0, 0, {0x60,0xc0,0x29,0x00,0x02,0xce,0x00,0x83,0x00,0x2c,0xc8,0x0b,0xbc,0x02,0x12,0x04 } }, -{ 16, 0xa8d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa9,0x00,0xea,0xe2,0x32,0x90 } }, -{ 16, 0xa8e0, 0, {0x2c,0xe0,0x03,0xfb,0x02,0xce,0xc0,0x32,0x80,0x0f,0xe4,0x03,0xe8,0x00,0x8a,0x00 } }, -{ 16, 0xa8f0, 0, {0x33,0x88,0x0d,0x64,0xc3,0xfa,0x00,0xda,0x00,0x3d,0x90,0x0e,0xe0,0x0b,0x3a,0x04 } }, -{ 16, 0xa900, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xc0,0x24,0xf8,0x08,0x3e,0x12 } }, -{ 16, 0xa910, 0, {0x0f,0xc0,0x03,0xe0,0x48,0xf0,0x00,0x3e,0x00,0x0e,0x80,0x93,0xc0,0x00,0xf8,0x00 } }, -{ 16, 0xa920, 0, {0x7e,0x01,0x0e,0x80,0xc2,0xe0,0x40,0xf8,0x00,0x7e,0x00,0x8f,0x84,0x03,0xd2,0x00 } }, -{ 16, 0xa930, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe5,0x00,0xc1,0x01,0x32,0x48 } }, -{ 16, 0xa940, 0, {0x0c,0x98,0x03,0xe6,0x40,0xc9,0x00,0x32,0x40,0x0f,0x90,0x03,0x66,0x00,0xc9,0x00 } }, -{ 16, 0xa950, 0, {0x18,0x61,0x0c,0x90,0x03,0x64,0x20,0xf9,0x05,0x3e,0x40,0x0c,0x90,0x83,0x02,0x04 } }, -{ 16, 0xa960, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x66,0x20,0x89,0x00,0x20,0x52 } }, -{ 16, 0xa970, 0, {0x28,0x10,0xc2,0x26,0x02,0xa9,0x00,0x22,0x40,0x0b,0x90,0x0a,0x27,0x00,0xa9,0x00 } }, -{ 16, 0xa980, 0, {0x22,0x70,0x08,0x90,0x02,0x24,0x08,0xb9,0x00,0x2e,0x40,0x0a,0x90,0x0a,0x20,0x00 } }, -{ 16, 0xa990, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x02,0x8d,0x00,0x23,0x40 } }, -{ 16, 0xa9a0, 0, {0x08,0xd1,0x02,0x84,0x20,0x89,0x00,0x22,0x60,0x0b,0x11,0xf2,0x24,0xb0,0x81,0x00 } }, -{ 16, 0xa9b0, 0, {0x2a,0x46,0x08,0x90,0x42,0x64,0x08,0xb9,0x00,0x2e,0x40,0x08,0x92,0x02,0x06,0x00 } }, -{ 16, 0xa9c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x14,0x80,0x85,0x20,0x23,0x48 } }, -{ 16, 0xa9d0, 0, {0x08,0x52,0x02,0x84,0x08,0x81,0x00,0x20,0x40,0x0b,0x12,0x02,0x04,0x80,0xa1,0x20 } }, -{ 16, 0xa9e0, 0, {0x28,0x49,0x28,0x90,0x02,0x04,0x00,0x31,0x20,0x2e,0x40,0x08,0x32,0x02,0x02,0x01 } }, -{ 16, 0xa9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x50,0xb2,0x14 } }, -{ 16, 0xaa00, 0, {0x0c,0xc0,0x03,0xa1,0x40,0xc8,0x00,0xb2,0x00,0x07,0x85,0x03,0x21,0x40,0xc8,0x50 } }, -{ 16, 0xaa10, 0, {0x3a,0x15,0x0c,0x85,0x03,0x61,0x40,0xf8,0x51,0x3e,0x00,0x2c,0x85,0x03,0x2e,0x03 } }, -{ 16, 0xaa20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xc4,0x48,0xf9,0x10,0x3e,0x44 } }, -{ 16, 0xaa30, 0, {0x4f,0x91,0x03,0x74,0x00,0xf5,0x44,0x3e,0x40,0x0f,0xd1,0x03,0xe4,0x40,0xf9,0x10 } }, -{ 16, 0xaa40, 0, {0x37,0x44,0x0f,0xd0,0x03,0xd4,0x00,0xf9,0x10,0x3f,0xc0,0x0f,0xd1,0x03,0xe6,0x06 } }, -{ 16, 0xaa50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf6,0xa0,0xdd,0x8c,0x33,0x78 } }, -{ 16, 0xaa60, 0, {0x0e,0xda,0x03,0x35,0x00,0xcd,0xa0,0x33,0x40,0x0d,0xf8,0x0b,0x36,0x81,0xe9,0x80 } }, -{ 16, 0xaa70, 0, {0x33,0x70,0x0c,0x91,0x03,0xe4,0x40,0xf9,0xc0,0x3e,0xc0,0x0f,0xdc,0x03,0xc6,0x00 } }, -{ 16, 0xaa80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x04,0xb8,0x40,0x20,0x3c } }, -{ 16, 0xaa90, 0, {0x0c,0x85,0x02,0x02,0x84,0x8a,0x40,0x22,0x00,0x08,0x8f,0x82,0x23,0x00,0xb8,0xe8 } }, -{ 16, 0xaaa0, 0, {0x22,0x20,0x08,0x88,0x02,0xe2,0x00,0xb8,0xd0,0x2e,0x00,0x0b,0x8c,0x02,0xce,0x04 } }, -{ 16, 0xaab0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x91,0x00,0x60,0x48 } }, -{ 16, 0xaac0, 0, {0x4b,0x10,0x02,0x04,0x8a,0x81,0x40,0x60,0x40,0x49,0x10,0x02,0x8d,0xa0,0xa1,0x41 } }, -{ 16, 0xaad0, 0, {0x20,0x50,0x09,0x12,0x22,0xc4,0x80,0xb1,0x20,0x2c,0x40,0x4b,0x3e,0x02,0xc2,0x01 } }, -{ 16, 0xaae0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x08,0xb9,0x04,0xa0,0x40 } }, -{ 16, 0xaaf0, 0, {0x48,0xb0,0x02,0x24,0x00,0x89,0x00,0x82,0x40,0x08,0x90,0xa6,0xa4,0x00,0xb9,0x04 } }, -{ 16, 0xab00, 0, {0x22,0x54,0x29,0x95,0x02,0xe5,0x40,0xb9,0x00,0x6e,0x40,0x0b,0x92,0x02,0xc6,0x04 } }, -{ 16, 0xab10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0x91,0x00,0x32,0x40 } }, -{ 16, 0xab20, 0, {0x0f,0x90,0x09,0x24,0x00,0x89,0x90,0x32,0x40,0x0d,0x94,0x03,0xa4,0x00,0xe9,0x02 } }, -{ 16, 0xab30, 0, {0x72,0x60,0x0d,0x94,0x03,0xe4,0x01,0xf9,0x01,0x3e,0x60,0x0f,0x90,0x03,0xe8,0x04 } }, -{ 16, 0xab40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x40,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0xab50, 0, {0x4f,0x90,0x03,0xe7,0x10,0xf9,0x80,0x3e,0x40,0x0f,0x10,0x13,0x64,0x00,0xf1,0x00 } }, -{ 16, 0xab60, 0, {0xbe,0x40,0x0e,0x90,0x03,0xe6,0x08,0xf9,0x01,0x3e,0x64,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0xab70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf8,0x00,0x32,0x08 } }, -{ 16, 0xab80, 0, {0x0c,0x01,0x0b,0x20,0x40,0xc8,0x40,0x32,0x00,0x0e,0x84,0x83,0x20,0x00,0xf8,0x04 } }, -{ 16, 0xab90, 0, {0x3e,0x04,0x0f,0x80,0x03,0x21,0x00,0xe8,0x00,0x3e,0x10,0x0f,0x88,0x03,0xca,0x04 } }, -{ 16, 0xaba0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x38,0x00,0x3e,0x04,0x23,0x80 } }, -{ 16, 0xabb0, 0, {0x08,0xec,0x12,0x39,0x44,0xa6,0x00,0x28,0x81,0x08,0xe0,0x00,0x38,0x08,0xba,0x00 } }, -{ 16, 0xabc0, 0, {0x3f,0x80,0x0b,0xa0,0x02,0xa8,0x00,0x8a,0x02,0x2e,0x80,0x0b,0xe0,0x02,0xca,0x00 } }, -{ 16, 0xabd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x48,0x00,0x31,0x00,0x24,0xd0 } }, -{ 16, 0xabe0, 0, {0x08,0x3e,0x12,0xae,0x08,0x81,0xa0,0x2c,0xc0,0x0a,0x38,0x00,0x4c,0x00,0xb3,0x00 } }, -{ 16, 0xabf0, 0, {0x6e,0xc0,0x0a,0x30,0x02,0x0c,0x00,0xa3,0x00,0x6c,0xc0,0x0b,0x30,0x02,0xca,0x00 } }, -{ 16, 0xac00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x18,0x00,0xb5,0x10,0x25,0xc0 } }, -{ 16, 0xac10, 0, {0x28,0x60,0x12,0x90,0x10,0xa5,0x08,0x2d,0xc2,0x08,0x64,0x22,0x58,0x18,0xb7,0x00 } }, -{ 16, 0xac20, 0, {0x2d,0x80,0x0b,0x79,0x02,0xbe,0xc0,0x87,0x01,0x6d,0xc0,0x0b,0x60,0x02,0xe8,0x00 } }, -{ 16, 0xac30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf5,0x84,0x35,0x20 } }, -{ 16, 0xac40, 0, {0x8c,0x18,0x02,0x92,0x10,0xc5,0x80,0x3d,0x60,0x0e,0xc8,0x0b,0x5a,0x08,0x77,0xf3 } }, -{ 16, 0xac50, 0, {0x3d,0xa0,0x0f,0xf8,0x03,0x1e,0xb0,0xe7,0x85,0x3d,0xe0,0x0f,0x78,0x03,0xea,0x02 } }, -{ 16, 0xac60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf1,0x04,0xba,0x01 } }, -{ 16, 0xac70, 0, {0x0f,0xa0,0x43,0x60,0x09,0xe1,0x00,0x38,0x40,0x0e,0xa0,0x03,0xa8,0x14,0xfb,0x20 } }, -{ 16, 0xac80, 0, {0x3a,0x80,0x0f,0xb4,0x1b,0x4c,0x80,0xfb,0x29,0x3e,0xc0,0x0f,0xb0,0x23,0xc2,0x06 } }, -{ 16, 0xac90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfa,0x00,0xcd,0x80,0x3b,0xe0 } }, -{ 16, 0xaca0, 0, {0x4e,0xf8,0x03,0xf2,0x02,0xd4,0x81,0x3b,0xe0,0x8e,0x98,0x07,0x3e,0x44,0xef,0x91 } }, -{ 16, 0xacb0, 0, {0x3f,0xe0,0x4f,0xfc,0x07,0xee,0xd0,0xcf,0x98,0x33,0xe4,0x0f,0xf8,0x03,0xc0,0x00 } }, -{ 16, 0xacc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x01,0x98,0x00,0x85,0x10,0x2d,0xc4 } }, -{ 16, 0xacd0, 0, {0x0d,0x11,0x02,0xf0,0x00,0x85,0x20,0x31,0xc4,0x0b,0x7b,0x00,0x38,0x40,0xd7,0x10 } }, -{ 16, 0xace0, 0, {0x2d,0x80,0x0b,0x70,0x62,0xfe,0xe1,0x87,0x14,0x39,0xc0,0x0b,0x60,0x02,0xea,0x04 } }, -{ 16, 0xacf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xbc,0x40,0xa5,0x00,0x29,0x40 } }, -{ 16, 0xad00, 0, {0x0b,0x50,0x82,0xdc,0x40,0x84,0x04,0x2d,0xc0,0x0b,0x10,0x06,0x58,0x44,0xa7,0x10 } }, -{ 16, 0xad10, 0, {0x2d,0x80,0x0b,0x71,0x02,0xdc,0x00,0x87,0x04,0x21,0xc2,0x0b,0x50,0x02,0xc0,0x10 } }, -{ 16, 0xad20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x0a,0xa1,0x01,0x2c,0x40 } }, -{ 16, 0xad30, 0, {0x89,0x18,0x02,0xc1,0x00,0xa1,0x08,0x20,0xc0,0x0b,0x34,0x06,0x40,0x00,0x93,0x05 } }, -{ 16, 0xad40, 0, {0x2c,0x14,0x0b,0x3c,0x86,0xce,0x10,0x83,0x01,0x28,0xf1,0x0b,0x14,0x02,0xc8,0x04 } }, -{ 16, 0xad50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xed,0x00,0x3a,0xc0 } }, -{ 16, 0xad60, 0, {0x07,0xbc,0x63,0xed,0x00,0x81,0x40,0x3e,0xc0,0x0e,0x88,0x03,0x64,0x00,0xef,0x00 } }, -{ 16, 0xad70, 0, {0x7e,0x50,0x0f,0xf0,0x02,0xfd,0x42,0xcf,0x00,0x72,0xc0,0x1f,0xb4,0x03,0xea,0x04 } }, -{ 16, 0xad80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe8,0x00,0x99,0x00,0x3e,0xe0 } }, -{ 16, 0xad90, 0, {0x4f,0xb4,0x83,0xed,0x90,0x09,0x40,0x3e,0xc0,0x0f,0xa1,0x83,0xa8,0x01,0xeb,0x01 } }, -{ 16, 0xada0, 0, {0x3e,0x00,0x0f,0xb1,0x13,0xec,0x0c,0xfb,0x00,0x3a,0xc0,0x5f,0x20,0x23,0xe0,0x00 } }, -{ 16, 0xadb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf8,0x00,0xfd,0x04,0x3f,0xb0 } }, -{ 16, 0xadc0, 0, {0x0d,0x60,0x03,0x3e,0x00,0xcd,0x00,0x33,0xf0,0x0f,0xf2,0x01,0xf0,0x00,0xff,0x03 } }, -{ 16, 0xadd0, 0, {0x3f,0x03,0x0f,0xf0,0x01,0xfc,0x00,0xfb,0x02,0x33,0xc2,0x0f,0xf0,0xe3,0x00,0x44 } }, -{ 16, 0xade0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6a,0x00,0xb9,0x02,0x2e,0xa0 } }, -{ 16, 0xadf0, 0, {0x4a,0xac,0x02,0x0e,0x80,0xf9,0xc0,0x36,0xe1,0x0b,0xa0,0x02,0x2a,0x08,0xbb,0x00 } }, -{ 16, 0xae00, 0, {0x2e,0x20,0x0e,0xb0,0x02,0xec,0x00,0xeb,0x00,0x22,0xc0,0x8b,0xb0,0x02,0x20,0x40 } }, -{ 16, 0xae10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x23,0x00,0xa9,0x00,0x28,0xc0 } }, -{ 16, 0xae20, 0, {0x09,0xb2,0x22,0x6c,0x40,0x89,0x89,0x2a,0xc0,0x0b,0x14,0x06,0x26,0x00,0xab,0x02 } }, -{ 16, 0xae30, 0, {0x6e,0xe0,0x09,0xb0,0x06,0x6c,0x00,0xb3,0x02,0x22,0xc0,0x0b,0xb0,0x02,0x20,0x00 } }, -{ 16, 0xae40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x08,0x00,0xb1,0x00,0x2c,0xc0 } }, -{ 16, 0xae50, 0, {0x0a,0x30,0x02,0x2c,0x00,0xbb,0x00,0x64,0xc0,0x0b,0x32,0x0a,0x08,0x00,0x33,0x00 } }, -{ 16, 0xae60, 0, {0x6c,0x80,0x02,0x30,0x46,0xcc,0x18,0xa3,0x00,0x20,0xc0,0x0b,0x28,0x02,0x02,0x11 } }, -{ 16, 0xae70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x68,0x00,0xe9,0x00,0x38,0xc1 } }, -{ 16, 0xae80, 0, {0x0d,0xb1,0x0b,0x2c,0x00,0x89,0x00,0x3a,0xc0,0x0b,0x90,0x03,0x60,0x00,0xff,0x02 } }, -{ 16, 0xae90, 0, {0x3e,0x80,0x0f,0xf0,0x03,0xfc,0x80,0xff,0x00,0x32,0xc0,0x8f,0x80,0x0b,0x00,0x03 } }, -{ 16, 0xaea0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xd8,0x00,0xfd,0x04,0x3f,0xc0 } }, -{ 16, 0xaeb0, 0, {0x2f,0xf2,0x03,0xfc,0x11,0xef,0x00,0x3f,0xc0,0x0f,0xf4,0x43,0x70,0x00,0xff,0x00 } }, -{ 16, 0xaec0, 0, {0x3f,0x00,0x46,0xf0,0x03,0xfd,0x00,0xef,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xe8,0x06 } }, -{ 16, 0xaed0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xff,0x80,0x3d,0xe0 } }, -{ 16, 0xaee0, 0, {0x0c,0xf9,0x13,0xde,0x00,0x7f,0x80,0xb3,0xe0,0x0f,0xfc,0x03,0xbe,0x40,0xcf,0x80 } }, -{ 16, 0xaef0, 0, {0x33,0xf0,0x0f,0xf8,0x03,0x7c,0x04,0xcc,0x80,0x33,0xa0,0x0c,0xf0,0x0b,0x30,0x01 } }, -{ 16, 0xaf00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe0,0x20,0x88,0x00,0x2e,0x20 } }, -{ 16, 0xaf10, 0, {0x08,0x82,0x12,0xe0,0x80,0xa8,0x81,0x22,0x02,0x0b,0x80,0x02,0x20,0x80,0xa8,0x80 } }, -{ 16, 0xaf20, 0, {0x22,0x08,0x0b,0x80,0x02,0x2c,0x02,0x88,0x04,0xaa,0x20,0x08,0xb0,0x02,0x20,0x04 } }, -{ 16, 0xaf30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xec,0x00,0xa3,0x08,0x2c,0x80 } }, -{ 16, 0xaf40, 0, {0x08,0x32,0x02,0xc4,0x20,0xa3,0x00,0x28,0x40,0x0b,0x92,0x02,0x84,0x00,0xa9,0x01 } }, -{ 16, 0xaf50, 0, {0x28,0xc8,0x1b,0x12,0x82,0xcc,0x40,0xa8,0x00,0x24,0xe0,0x0a,0x30,0x42,0x22,0x01 } }, -{ 16, 0xaf60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xa8,0x80,0xa8,0x02,0x2e,0x40 } }, -{ 16, 0xaf70, 0, {0x68,0x80,0x10,0xc8,0x00,0xb8,0x40,0x2a,0x90,0x0b,0xa0,0x00,0x28,0x00,0xaa,0x08 } }, -{ 16, 0xaf80, 0, {0x2a,0x02,0x03,0x20,0x02,0x8c,0x00,0xa8,0x88,0x2e,0x20,0x0a,0xb0,0x02,0x30,0x04 } }, -{ 16, 0xaf90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe8,0x04,0xfa,0x00,0x3c,0x40 } }, -{ 16, 0xafa0, 0, {0x0c,0xa0,0x03,0xe8,0x00,0xeb,0x00,0x3a,0xc0,0x0f,0x20,0x53,0xa8,0x00,0xe3,0x40 } }, -{ 16, 0xafb0, 0, {0x2a,0x40,0x0f,0xa0,0x03,0x6c,0x00,0xa8,0x80,0x34,0x20,0x1e,0xb0,0x03,0x10,0x04 } }, -{ 16, 0xafc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x00,0x9d,0x91,0x3f,0x80 } }, -{ 16, 0xafd0, 0, {0x0f,0xda,0x23,0xf4,0x00,0xcc,0x20,0x37,0x00,0x07,0xd0,0x13,0x74,0x00,0xbc,0x00 } }, -{ 16, 0xafe0, 0, {0xb7,0x80,0x0b,0xd0,0x43,0x7c,0x00,0xdc,0x04,0x3b,0x00,0x6d,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0xaff0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa8,0x00,0xfa,0x80,0x3a,0x00 } }, -{ 16, 0xb000, 0, {0x2c,0xa0,0x0b,0x20,0x02,0xcb,0x62,0x3e,0x50,0x0e,0x88,0x03,0x20,0x00,0xd9,0x10 } }, -{ 16, 0xb010, 0, {0x3e,0x70,0x8c,0x80,0x33,0xec,0x80,0xd8,0x40,0x3a,0x02,0x0d,0xb0,0x03,0x10,0x04 } }, -{ 16, 0xb020, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x01,0x0c,0x00,0x39,0x80,0x22,0xc0 } }, -{ 16, 0xb030, 0, {0x0c,0x9d,0x82,0x2c,0x10,0xd0,0x40,0x2e,0xa0,0x08,0xb8,0x03,0x4e,0x02,0x8a,0x40 } }, -{ 16, 0xb040, 0, {0x0e,0xa0,0x0d,0xb0,0x03,0x3d,0x00,0xd0,0x90,0x36,0x10,0x0b,0xf0,0x02,0xb2,0x00 } }, -{ 16, 0xb050, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb1,0x00,0x60,0xc0 } }, -{ 16, 0xb060, 0, {0x8a,0x18,0x02,0x8c,0x08,0x80,0x40,0x0c,0xa0,0x02,0x30,0x02,0xce,0x00,0x82,0x48 } }, -{ 16, 0xb070, 0, {0x2c,0x80,0x2b,0x30,0x06,0x8c,0x00,0x81,0x02,0x20,0x90,0x09,0xb0,0x02,0x38,0x00 } }, -{ 16, 0xb080, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x12,0x00,0xb6,0x90,0xa3,0x30 } }, -{ 16, 0xb090, 0, {0x08,0xe8,0x22,0xb2,0x14,0x87,0x80,0x2d,0x60,0x08,0x49,0x12,0x12,0x61,0x95,0x90 } }, -{ 16, 0xb0a0, 0, {0x2d,0x61,0x0a,0x48,0x16,0x1e,0x80,0x95,0x80,0x25,0x20,0x0b,0x78,0x02,0x88,0x00 } }, -{ 16, 0xb0b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf1,0x00,0x28,0x8c } }, -{ 16, 0xb0c0, 0, {0x8e,0x10,0x03,0x84,0x80,0x80,0x00,0x2c,0x02,0x0a,0x9a,0x02,0xe4,0x00,0xd0,0x00 } }, -{ 16, 0xb0d0, 0, {0x3e,0x80,0x0b,0x91,0x03,0x8e,0x80,0xc2,0x08,0x38,0x80,0x0d,0xb0,0x03,0x12,0x02 } }, -{ 16, 0xb0e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb0,0x00,0xf6,0x00,0x3f,0x44 } }, -{ 16, 0xb0f0, 0, {0x0f,0x21,0x13,0x78,0x00,0xff,0x00,0x3d,0xc0,0x0f,0xe0,0x03,0x78,0x00,0xef,0x04 } }, -{ 16, 0xb100, 0, {0x3f,0x40,0x8d,0xe8,0x03,0xdc,0x04,0xf6,0x00,0x3f,0x00,0x0f,0xf0,0x83,0xd0,0x06 } }, -{ 16, 0xb110, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x00,0xe8,0x80,0x32,0x40 } }, -{ 16, 0xb120, 0, {0x0f,0x88,0x0b,0x28,0x00,0x78,0x02,0x3e,0x80,0x0e,0x28,0x03,0x28,0x00,0xca,0x80 } }, -{ 16, 0xb130, 0, {0x32,0x00,0x0f,0xa0,0x03,0xec,0x00,0xc9,0x80,0x32,0x80,0x0f,0xb0,0x03,0x2a,0x00 } }, -{ 16, 0xb140, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x8c,0x00,0x8f,0x00,0xa1,0x80 } }, -{ 16, 0xb150, 0, {0x0b,0x70,0x42,0x14,0x00,0xb7,0x00,0x2d,0x41,0x0b,0x50,0x42,0x14,0x00,0xa5,0x00 } }, -{ 16, 0xb160, 0, {0xa1,0xc0,0x0b,0x50,0x02,0xfc,0x80,0xa5,0x00,0x21,0x00,0x0b,0xf2,0x02,0x12,0x04 } }, -{ 16, 0xb170, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xba,0x00,0xa4,0x80,0x29,0x30 } }, -{ 16, 0xb180, 0, {0x4b,0x48,0x06,0x52,0x08,0xb4,0x80,0x2d,0x20,0x0b,0x48,0x42,0x32,0x00,0x84,0x80 } }, -{ 16, 0xb190, 0, {0x21,0x20,0x0b,0x48,0x12,0xde,0x40,0x86,0x81,0x29,0xa0,0x0b,0x78,0x0a,0x30,0x00 } }, -{ 16, 0xb1a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0x83,0x05,0x20,0xe0 } }, -{ 16, 0xb1b0, 0, {0x0b,0x34,0x02,0x6c,0x10,0xb3,0x00,0x2c,0xc0,0x0b,0x36,0x4a,0x0d,0x0d,0xa3,0x00 } }, -{ 16, 0xb1c0, 0, {0x20,0xc0,0x0b,0x34,0x82,0xcc,0x02,0xa2,0x00,0x28,0x00,0x0b,0x30,0x02,0x12,0x04 } }, -{ 16, 0xb1d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa9,0x20,0xea,0x40,0x30,0xa0 } }, -{ 16, 0xb1e0, 0, {0x07,0xa0,0x43,0x69,0x40,0xfa,0x00,0x3c,0x80,0x0f,0xa0,0x03,0x08,0x40,0xca,0x00 } }, -{ 16, 0xb1f0, 0, {0x30,0xa0,0x0f,0xa4,0x03,0xe8,0x00,0xce,0x00,0x3b,0x98,0x0f,0xa0,0x03,0x3a,0x04 } }, -{ 16, 0xb200, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xd2,0x00,0xfc,0x08,0x3f,0x00 } }, -{ 16, 0xb210, 0, {0x0b,0xc2,0x03,0xb0,0x00,0xfc,0x00,0x3f,0x00,0x0f,0xc0,0x03,0xf0,0x00,0xfc,0x00 } }, -{ 16, 0xb220, 0, {0x3f,0x04,0x0f,0xc0,0x03,0xe0,0x00,0xf8,0x00,0xb6,0x02,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xb230, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0x3e,0x68 } }, -{ 16, 0xb240, 0, {0x4c,0x91,0x01,0xe4,0x08,0xc9,0x00,0x3e,0x40,0x2c,0x92,0x03,0xe4,0x02,0xc9,0xa0 } }, -{ 16, 0xb250, 0, {0x3e,0x70,0x0e,0x90,0x03,0xc6,0x42,0xc9,0x00,0x3e,0x40,0x0f,0x10,0x03,0x02,0x04 } }, -{ 16, 0xb260, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x86,0x0e,0x60 } }, -{ 16, 0xb270, 0, {0x08,0x98,0x02,0xe4,0x08,0x89,0x10,0x2e,0x60,0x08,0x90,0x02,0xe4,0x00,0x89,0x0c } }, -{ 16, 0xb280, 0, {0x2e,0x60,0x08,0x90,0x02,0xe6,0x88,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0xa0,0x00 } }, -{ 16, 0xb290, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x9d,0x10,0x2f,0x40 } }, -{ 16, 0xb2a0, 0, {0x28,0xd0,0x06,0xf4,0x02,0xad,0x00,0x2f,0x60,0x08,0xd0,0x02,0xf4,0x00,0x8d,0x00 } }, -{ 16, 0xb2b0, 0, {0x2f,0x40,0x0a,0xd0,0x02,0xe4,0x00,0x89,0x00,0x2e,0x60,0x0b,0x90,0x02,0x06,0x00 } }, -{ 16, 0xb2c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x34,0x00,0x85,0x00,0x2d,0x40 } }, -{ 16, 0xb2d0, 0, {0x08,0x58,0x02,0xd4,0x00,0xa5,0x02,0x2d,0x40,0x08,0x50,0x00,0xd4,0x00,0x85,0x00 } }, -{ 16, 0xb2e0, 0, {0x2d,0x40,0x08,0x54,0x02,0xc4,0x80,0x81,0x00,0x2c,0x60,0x0b,0x14,0x02,0x82,0x01 } }, -{ 16, 0xb2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x52,0x3e,0x00 } }, -{ 16, 0xb300, 0, {0x0c,0x05,0x03,0xe1,0x40,0xe8,0x04,0x3e,0x14,0x0c,0x85,0x03,0xe1,0x40,0xc8,0x00 } }, -{ 16, 0xb310, 0, {0x3e,0x14,0x0e,0xc0,0x03,0xe0,0x00,0xc0,0x02,0x3e,0x00,0x4f,0x80,0x23,0x2e,0x03 } }, -{ 16, 0xb320, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x00,0xf9,0x01,0x3e,0x40 } }, -{ 16, 0xb330, 0, {0x4f,0x90,0x13,0xe4,0x00,0xd9,0x00,0x1e,0x40,0x0f,0x90,0x03,0xc4,0x10,0xf1,0x00 } }, -{ 16, 0xb340, 0, {0x1e,0x40,0x0f,0x90,0x03,0xe4,0xe0,0xfd,0x28,0x3f,0x40,0x0f,0x94,0x03,0xe6,0x06 } }, -{ 16, 0xb350, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa4,0x00,0xfd,0x00,0x3f,0x40 } }, -{ 16, 0xb360, 0, {0x4d,0x50,0x02,0xe4,0x00,0x95,0x04,0x33,0x40,0x28,0xd0,0x03,0xf4,0x00,0xfd,0x00 } }, -{ 16, 0xb370, 0, {0x33,0x40,0x0f,0x91,0x03,0x34,0x00,0xcd,0x40,0x33,0x40,0x0f,0x98,0x81,0x06,0x00 } }, -{ 16, 0xb380, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x10,0xb8,0x00,0x2e,0x00 } }, -{ 16, 0xb390, 0, {0x0b,0x80,0x02,0xe0,0x10,0xb8,0x00,0x22,0x00,0x08,0x80,0x02,0xe0,0x00,0xb8,0x00 } }, -{ 16, 0xb3a0, 0, {0x22,0x00,0x0b,0x88,0x03,0xc2,0x80,0x88,0x80,0x22,0x00,0x0b,0x8c,0x02,0x0e,0x04 } }, -{ 16, 0xb3b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0xc4,0x00,0xb1,0x00,0x2c,0xc0 } }, -{ 16, 0xb3c0, 0, {0x0b,0x10,0x02,0xc4,0x00,0xbb,0x00,0x22,0x40,0x08,0x10,0x02,0xc4,0x01,0xb9,0x00 } }, -{ 16, 0xb3d0, 0, {0x20,0x40,0x1b,0x90,0x02,0x04,0x22,0x89,0x00,0x20,0x60,0x0b,0x12,0x82,0x02,0x01 } }, -{ 16, 0xb3e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x44,0xb9,0x00,0x2e,0xc0 } }, -{ 16, 0xb3f0, 0, {0x4b,0x90,0x02,0xe4,0x10,0xb9,0x02,0x02,0x40,0x08,0x91,0x42,0xe4,0x00,0xb9,0x80 } }, -{ 16, 0xb400, 0, {0x22,0x40,0x0b,0x92,0x02,0xc4,0x00,0x99,0x40,0x22,0x40,0x4b,0x90,0x12,0x06,0x04 } }, -{ 16, 0xb410, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x00,0xb9,0x01,0x3e,0x58 } }, -{ 16, 0xb420, 0, {0x0d,0x90,0x03,0xe6,0x00,0xd1,0x00,0x32,0x60,0x0c,0x98,0x02,0xe6,0x40,0xf9,0x00 } }, -{ 16, 0xb430, 0, {0xb2,0x40,0x0f,0x18,0x03,0x24,0x00,0xc9,0x80,0x32,0x50,0x0f,0x90,0x23,0x28,0x04 } }, -{ 16, 0xb440, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x42 } }, -{ 16, 0xb450, 0, {0x0b,0x90,0x03,0xe7,0x08,0xf9,0x00,0xbe,0x48,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0xb460, 0, {0x3e,0x40,0x0f,0x98,0x03,0xa4,0x00,0xe9,0xa0,0xbe,0x40,0x0f,0x10,0x0b,0x4a,0x00 } }, -{ 16, 0xb470, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x01,0x3e,0x00 } }, -{ 16, 0xb480, 0, {0x0f,0x80,0x8b,0x20,0x00,0xf8,0x20,0x3e,0x01,0x0f,0x81,0x03,0xe0,0x00,0xf8,0x08 } }, -{ 16, 0xb490, 0, {0x3a,0x00,0x0c,0x80,0x03,0xe0,0x00,0xd8,0x40,0x32,0x00,0x0f,0x80,0x13,0x0a,0x04 } }, -{ 16, 0xb4a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8a,0x80,0x2f,0x91 } }, -{ 16, 0xb4b0, 0, {0x0b,0xee,0x02,0x28,0x01,0xbe,0x00,0x20,0x80,0x0b,0xa0,0x02,0xea,0x80,0xb6,0x48 } }, -{ 16, 0xb4c0, 0, {0x22,0x80,0x0d,0xa0,0x02,0xfa,0x02,0x86,0x41,0xa3,0xa6,0x0b,0xa0,0x03,0x0a,0x00 } }, -{ 16, 0xb4d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x80,0x2c,0xc0 } }, -{ 16, 0xb4e0, 0, {0x0b,0x30,0x02,0x0c,0x10,0xb3,0x00,0x28,0xc0,0x0b,0x38,0x02,0xcc,0x00,0xb3,0x00 } }, -{ 16, 0xb4f0, 0, {0x28,0xc0,0x09,0x30,0x02,0xc6,0x01,0x83,0x60,0x20,0x70,0x0b,0x30,0x0a,0x4a,0x00 } }, -{ 16, 0xb500, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x2e,0x88,0x85,0x08,0x2d,0x80 } }, -{ 16, 0xb510, 0, {0x4b,0xf8,0x06,0x1c,0x80,0xb7,0x00,0x21,0xc0,0x0b,0x50,0x02,0xd4,0x00,0xb6,0x00 } }, -{ 16, 0xb520, 0, {0x29,0x60,0x09,0x70,0x02,0xd0,0xa0,0x8d,0x00,0x21,0x40,0x0b,0x32,0x02,0x28,0x00 } }, -{ 16, 0xb530, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xd5,0x80,0x3d,0xe0 } }, -{ 16, 0xb540, 0, {0x8f,0x78,0x03,0x1e,0x84,0xb7,0x82,0x3d,0x60,0x0f,0x59,0x03,0xde,0x00,0xf7,0x80 } }, -{ 16, 0xb550, 0, {0x29,0x60,0x15,0x78,0x03,0xde,0x00,0xc7,0x80,0x31,0x60,0x0f,0x7c,0x03,0x6a,0x02 } }, -{ 16, 0xb560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x40,0xe9,0x00,0x3e,0x80 } }, -{ 16, 0xb570, 0, {0x0f,0xa0,0x03,0xed,0x30,0xfb,0x00,0x36,0xc1,0x0f,0x96,0x03,0xe4,0x00,0xb3,0x00 } }, -{ 16, 0xb580, 0, {0x34,0x40,0x0f,0xb7,0x83,0xec,0x40,0x21,0x00,0x3e,0x40,0x0f,0xb0,0x03,0xc2,0x06 } }, -{ 16, 0xb590, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xff,0x81,0x33,0xe0 } }, -{ 16, 0xb5a0, 0, {0x0f,0xf9,0x03,0xde,0x20,0xcf,0x81,0x3f,0xe0,0x07,0x78,0x03,0x3e,0x00,0xff,0x80 } }, -{ 16, 0xb5b0, 0, {0x3f,0xe0,0x04,0xf8,0x13,0xfe,0x02,0xde,0x80,0x33,0x60,0x0f,0xf8,0x03,0x00,0x00 } }, -{ 16, 0xb5c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xb7,0x00,0x21,0xc4 } }, -{ 16, 0xb5d0, 0, {0x0b,0x5a,0x02,0xdc,0x48,0x86,0x50,0x2d,0xc0,0x0b,0x31,0x02,0x94,0x60,0xb4,0x18 } }, -{ 16, 0xb5e0, 0, {0x2d,0x40,0x48,0x70,0x02,0xe8,0x00,0xa5,0x10,0x21,0x40,0x0b,0x71,0x02,0x2a,0x04 } }, -{ 16, 0xb5f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xbd,0x00,0x21,0x42 } }, -{ 16, 0xb600, 0, {0x0b,0x70,0x02,0xfc,0x02,0x85,0x00,0x25,0x40,0x0b,0x50,0x02,0x9c,0x00,0xb7,0x00 } }, -{ 16, 0xb610, 0, {0x2f,0x40,0x28,0x71,0x02,0xdc,0x00,0xa6,0x00,0x21,0xc0,0x0b,0x70,0x02,0x00,0x00 } }, -{ 16, 0xb620, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0x6d,0x80,0xb1,0x20,0xa0,0x50 } }, -{ 16, 0xb630, 0, {0x0b,0xb2,0x06,0xce,0x00,0xa0,0x34,0x2e,0xf0,0x0b,0x18,0x02,0x85,0x20,0xb3,0x4a } }, -{ 16, 0xb640, 0, {0x2c,0x54,0x88,0x38,0x02,0xcc,0x10,0xa1,0x00,0x20,0xb0,0x0b,0x30,0x02,0x08,0x04 } }, -{ 16, 0xb650, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbe,0x80,0xf3,0x08,0x10,0x54 } }, -{ 16, 0xb660, 0, {0x0b,0x88,0x13,0xff,0x00,0xc0,0x80,0x3e,0x64,0x0f,0xb4,0x83,0x07,0x00,0xf9,0xc0 } }, -{ 16, 0xb670, 0, {0x3e,0xf0,0x0c,0xfc,0x13,0xf4,0x00,0xea,0x00,0x32,0x70,0x0f,0xf0,0x0b,0x2a,0x04 } }, -{ 16, 0xb680, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xf9,0x00,0x3e,0x10 } }, -{ 16, 0xb690, 0, {0x07,0x91,0x03,0xec,0xc0,0x58,0x00,0x3e,0x44,0x0f,0x92,0x03,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0xb6a0, 0, {0x3e,0xc0,0x8f,0xb3,0x03,0xe0,0x00,0xbb,0x00,0xbe,0x44,0x0f,0xb0,0x03,0xe0,0x00 } }, -{ 16, 0xb6b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x02,0xcd,0x04,0x33,0xe0 } }, -{ 16, 0xb6c0, 0, {0x0c,0xc0,0x03,0x3c,0x08,0xfe,0x00,0x33,0x60,0x2c,0xd0,0x02,0xb4,0x80,0xcf,0x00 } }, -{ 16, 0xb6d0, 0, {0x3f,0x52,0x07,0xf0,0x13,0xfc,0x00,0xce,0x10,0x33,0x42,0x0c,0xb0,0x03,0xc0,0x44 } }, -{ 16, 0xb6e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x00,0x89,0x00,0x2a,0xb0 } }, -{ 16, 0xb6f0, 0, {0x08,0x88,0x02,0x2c,0x00,0xba,0x00,0x36,0x44,0x08,0x90,0x00,0x26,0x00,0xdb,0xc0 } }, -{ 16, 0xb700, 0, {0x2e,0x40,0x0b,0xb0,0x02,0xec,0x00,0x83,0xc0,0x28,0x40,0x0a,0xb0,0x02,0xe0,0x40 } }, -{ 16, 0xb710, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x22,0x08 } }, -{ 16, 0xb720, 0, {0x1a,0xa2,0x02,0x2c,0x10,0xb9,0x20,0x22,0x40,0x08,0x30,0x02,0x2c,0x04,0xaa,0x54 } }, -{ 16, 0xb730, 0, {0x2e,0xc0,0x0b,0xb0,0x12,0xcc,0x00,0x8b,0x08,0x22,0x40,0x08,0xb0,0x02,0xe0,0x00 } }, -{ 16, 0xb740, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x04,0x2a,0x00 } }, -{ 16, 0xb750, 0, {0x0a,0x08,0x82,0x0c,0x00,0xb8,0x00,0x64,0x40,0x08,0x30,0x02,0xa4,0x00,0xb0,0x00 } }, -{ 16, 0xb760, 0, {0x2c,0xc0,0x8b,0x30,0x10,0xc8,0x02,0x8b,0x00,0x2a,0x40,0x0a,0x30,0x02,0xc2,0x01 } }, -{ 16, 0xb770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xc9,0x00,0x32,0x00 } }, -{ 16, 0xb780, 0, {0x1a,0x82,0x03,0x3c,0x00,0xf9,0x00,0x32,0x40,0x0c,0xd1,0x03,0xac,0x00,0xeb,0x00 } }, -{ 16, 0xb790, 0, {0x3e,0x40,0x0f,0xf0,0x03,0xed,0x00,0xc3,0x00,0x32,0xc0,0x8c,0xb0,0x03,0xc0,0x03 } }, -{ 16, 0xb7a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xf5,0x00,0x3f,0x00 } }, -{ 16, 0xb7b0, 0, {0x0d,0x80,0x4b,0xfc,0x00,0x7c,0x00,0x3f,0x40,0x0f,0xd2,0x0b,0x74,0x00,0xdf,0x00 } }, -{ 16, 0xb7c0, 0, {0x1d,0x40,0x8f,0xf0,0x03,0xfc,0xa0,0xff,0x00,0x3f,0x80,0x0f,0xf0,0x03,0xe8,0x06 } }, -{ 16, 0xb7d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xdf,0x84,0x3b,0xe0 } }, -{ 16, 0xb7e0, 0, {0x0f,0xf8,0x0b,0x3e,0x00,0xec,0x80,0x33,0xe1,0x0c,0x30,0x03,0x3c,0x80,0xcf,0x48 } }, -{ 16, 0xb7f0, 0, {0x37,0xc0,0x0e,0x40,0x03,0xe0,0xc0,0xc7,0x91,0xb3,0x04,0x0c,0xf0,0x03,0x30,0x00 } }, -{ 16, 0xb800, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xef,0x04,0x8b,0x80,0x22,0x41 } }, -{ 16, 0xb810, 0, {0x0b,0xb0,0x82,0x2e,0x00,0x88,0x80,0xa2,0xe0,0x0a,0xa2,0x92,0xad,0x80,0x87,0x42 } }, -{ 16, 0xb820, 0, {0x23,0xd8,0x8a,0xad,0x02,0xe0,0xc0,0x8b,0x00,0x20,0x4c,0x48,0xa4,0x02,0x20,0x04 } }, -{ 16, 0xb830, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x58,0xbb,0x00,0x28,0x80 } }, -{ 16, 0xb840, 0, {0x0b,0xb2,0x42,0x24,0x00,0xa8,0x00,0x2a,0xc0,0x0a,0x10,0x02,0x04,0x60,0xa3,0x20 } }, -{ 16, 0xb850, 0, {0x24,0xd2,0x08,0x00,0x42,0x8c,0x83,0x9b,0x01,0x20,0x49,0x08,0x33,0xc2,0x22,0x01 } }, -{ 16, 0xb860, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x00,0xab,0x88,0x22,0xa0 } }, -{ 16, 0xb870, 0, {0x0b,0xb8,0x02,0x26,0x0c,0xa8,0x00,0x2a,0xc0,0x0a,0x92,0x02,0xa4,0x00,0xab,0x06 } }, -{ 16, 0xb880, 0, {0x22,0xc0,0x0a,0xb0,0x02,0xe8,0x00,0x9b,0x00,0x02,0x40,0x08,0xa0,0x42,0x30,0x04 } }, -{ 16, 0xb890, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xd3,0x80,0x3a,0xe0 } }, -{ 16, 0xb8a0, 0, {0x0f,0x18,0x01,0x06,0x00,0xe8,0x30,0x38,0x66,0x0e,0xb8,0x03,0x2a,0x40,0xeb,0x00 } }, -{ 16, 0xb8b0, 0, {0x36,0xc1,0x0e,0x96,0x03,0xe2,0x80,0xda,0x08,0x32,0x80,0x2c,0xbb,0x03,0x10,0x04 } }, -{ 16, 0xb8c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x9c,0x00,0xdf,0x00,0x3f,0xc0 } }, -{ 16, 0xb8d0, 0, {0x0f,0xd0,0x03,0xf4,0x00,0xdc,0x80,0x37,0x60,0x0f,0xe8,0x03,0xfa,0x00,0xdf,0x01 } }, -{ 16, 0xb8e0, 0, {0x3f,0xc0,0x0f,0xc0,0x43,0xe6,0x4c,0xef,0xa0,0x3f,0x44,0x0f,0xa0,0x03,0xf8,0x00 } }, -{ 16, 0xb8f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x40,0xdb,0x00,0x36,0x80 } }, -{ 16, 0xb900, 0, {0x0c,0x98,0x03,0x26,0x00,0xf8,0x00,0x3e,0xc0,0x0e,0x18,0x03,0x84,0x02,0xe3,0x01 } }, -{ 16, 0xb910, 0, {0x38,0xc1,0x0e,0xb4,0x03,0xac,0x80,0xca,0x18,0x3a,0xd0,0x2c,0x30,0x03,0x10,0x04 } }, -{ 16, 0xb920, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3f,0x40,0xb9,0x88,0x2e,0x80 } }, -{ 16, 0xb930, 0, {0x08,0xbc,0x02,0xa3,0x00,0xb0,0x00,0x0e,0xc0,0x08,0xb0,0x06,0x20,0x00,0x8f,0x04 } }, -{ 16, 0xb940, 0, {0x23,0xc1,0x08,0xb9,0x12,0x2f,0x00,0x83,0x80,0x36,0x40,0x08,0xad,0x02,0x32,0x00 } }, -{ 16, 0xb950, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb2,0x00,0x2c,0xc0 } }, -{ 16, 0xb960, 0, {0x09,0x32,0x02,0x84,0x00,0x33,0x00,0x2c,0xb2,0x0a,0x36,0x12,0x8c,0x08,0x93,0x05 } }, -{ 16, 0xb970, 0, {0x20,0xc0,0x0b,0x18,0x02,0xed,0x00,0x91,0x80,0x6a,0x00,0x08,0x10,0x02,0x38,0x00 } }, -{ 16, 0xb980, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0xb7,0x80,0x2d,0xe0 } }, -{ 16, 0xb990, 0, {0x09,0x78,0x02,0x97,0x40,0xb4,0x80,0x2f,0xa0,0x08,0xe8,0x02,0x0e,0x40,0x97,0x82 } }, -{ 16, 0xb9a0, 0, {0x21,0xe0,0x98,0x68,0x82,0x1a,0x18,0x9d,0x90,0x2d,0xa1,0x18,0x58,0x02,0x08,0x00 } }, -{ 16, 0xb9b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0xc0,0xf3,0x00,0x3e,0xc0 } }, -{ 16, 0xb9c0, 0, {0x0d,0xb0,0x43,0x84,0x40,0xf0,0x00,0x3c,0x82,0x0e,0x38,0x12,0x8c,0x44,0xf3,0x30 } }, -{ 16, 0xb9d0, 0, {0xba,0xc1,0x1e,0x10,0x47,0x8e,0x22,0xd1,0x10,0x38,0x18,0x0c,0x30,0x83,0x12,0x02 } }, -{ 16, 0xb9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x40,0xff,0x00,0x3f,0xc0 } }, -{ 16, 0xb9f0, 0, {0x0e,0xe0,0x03,0xf4,0x40,0xfc,0x00,0x3d,0xc4,0x0f,0xd0,0x01,0xf4,0x41,0xef,0x18 } }, -{ 16, 0xba00, 0, {0x3f,0xc4,0x1f,0xf0,0x03,0xf8,0x48,0xef,0x14,0x33,0x80,0x0f,0xc1,0x03,0xd0,0x06 } }, -{ 16, 0xba10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xfc,0x40,0xfb,0x00,0x3e,0xc0 } }, -{ 16, 0xba20, 0, {0x0f,0x98,0x03,0x24,0x00,0xcb,0x00,0x3e,0x40,0x0f,0xb0,0x03,0xa8,0x00,0xdb,0x28 } }, -{ 16, 0xba30, 0, {0x3e,0xc4,0x1f,0x90,0x23,0xec,0x00,0xca,0x00,0x32,0xe0,0x0c,0x90,0x03,0xea,0x00 } }, -{ 16, 0xba40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x80,0xb7,0x00,0x2d,0xc0 } }, -{ 16, 0xba50, 0, {0x4b,0x50,0x52,0x14,0x00,0xd4,0x01,0x2d,0x80,0x0b,0x60,0x02,0xd8,0x00,0xa7,0x20 } }, -{ 16, 0xba60, 0, {0x2d,0xc5,0x0b,0x40,0x16,0xdc,0x00,0x84,0x00,0x23,0xc0,0x08,0x40,0x02,0xd2,0x04 } }, -{ 16, 0xba70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x80,0xb7,0x80,0x2d,0xe0 } }, -{ 16, 0xba80, 0, {0x0b,0x78,0x0a,0x96,0x00,0x94,0x80,0x2d,0x60,0x1b,0x78,0x06,0xd2,0x00,0xa7,0x80 } }, -{ 16, 0xba90, 0, {0x2d,0xe0,0x0b,0x78,0x22,0xde,0x00,0x87,0x82,0x21,0xe0,0x08,0x58,0x02,0xf0,0x00 } }, -{ 16, 0xbaa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0xe4,0x2c,0xc0 } }, -{ 16, 0xbab0, 0, {0x1b,0x21,0x02,0x81,0x00,0x90,0x00,0x2c,0xc8,0x0b,0x39,0x02,0xce,0x00,0xa3,0x00 } }, -{ 16, 0xbac0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcd,0x00,0x8b,0x20,0x20,0xf0,0x08,0xb2,0x02,0xd2,0x04 } }, -{ 16, 0xbad0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0xa0,0x3f,0x82 } }, -{ 16, 0xbae0, 0, {0x0f,0xe8,0x03,0x98,0x30,0xd6,0x00,0x3f,0xa0,0x0f,0xe0,0x03,0xba,0xc0,0xfa,0x00 } }, -{ 16, 0xbaf0, 0, {0x3e,0x80,0x0f,0xec,0x33,0xf8,0x02,0xce,0x00,0xb3,0xb8,0x2c,0xec,0x83,0xfa,0x04 } }, -{ 16, 0xbb00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x18,0xf8,0x40,0x3e,0x00 } }, -{ 16, 0xbb10, 0, {0x0f,0x80,0x02,0x60,0x84,0xf8,0x05,0x2e,0x04,0x8f,0x80,0x41,0xe0,0x00,0x78,0x02 } }, -{ 16, 0xbb20, 0, {0x3e,0x00,0x0f,0x81,0x83,0xe0,0x20,0xf8,0x00,0xbe,0x02,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xbb30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe6,0x18,0xf9,0x20,0x3e,0x40 } }, -{ 16, 0xbb40, 0, {0x0f,0x9c,0x03,0xe4,0x40,0xc9,0x00,0x32,0x61,0x0c,0x90,0x13,0xc4,0x08,0xc9,0x01 } }, -{ 16, 0xbb50, 0, {0x3e,0x41,0x0f,0x18,0x03,0x24,0x00,0xc9,0xa0,0x32,0x40,0x0f,0x98,0x43,0x02,0x04 } }, -{ 16, 0xbb60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x65,0x00,0xb1,0xc0,0x22,0x40 } }, -{ 16, 0xbb70, 0, {0x0b,0x9c,0x02,0xe7,0x10,0x89,0x00,0x28,0x44,0x08,0x94,0x22,0xe4,0x10,0x89,0x00 } }, -{ 16, 0xbb80, 0, {0x2e,0x40,0x0b,0x9f,0x22,0x26,0x60,0x89,0x80,0x22,0x40,0x0b,0x91,0x0a,0x20,0x00 } }, -{ 16, 0xbb90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x80,0xb9,0x00,0x2e,0xc0 } }, -{ 16, 0xbba0, 0, {0x4b,0xb4,0x02,0xe4,0x20,0x89,0x20,0x22,0x40,0x08,0x94,0x02,0xec,0x00,0x89,0x00 } }, -{ 16, 0xbbb0, 0, {0x2e,0x41,0x0b,0x90,0x02,0x04,0x00,0x89,0x40,0x22,0x40,0x0b,0x90,0x02,0x06,0x00 } }, -{ 16, 0xbbc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb1,0x04,0x20,0x40 } }, -{ 16, 0xbbd0, 0, {0x8b,0x10,0x02,0xe4,0x05,0x81,0x00,0x28,0x40,0x28,0x12,0x12,0xc4,0x82,0x81,0x20 } }, -{ 16, 0xbbe0, 0, {0x2c,0x48,0x0b,0x12,0x0a,0x04,0x82,0x81,0x00,0x20,0x48,0x0b,0x12,0x02,0x02,0x01 } }, -{ 16, 0xbbf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x68,0xa0,0xfa,0x02,0x3e,0x14 } }, -{ 16, 0xbc00, 0, {0x0f,0x85,0x03,0xe0,0x00,0xc8,0x00,0x32,0x00,0x0c,0x85,0x03,0xc1,0x40,0xc8,0x53 } }, -{ 16, 0xbc10, 0, {0x3e,0x14,0x0f,0x80,0x03,0x01,0x48,0xc0,0x50,0xb2,0x14,0x0f,0x85,0x03,0x2e,0x03 } }, -{ 16, 0xbc20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x00,0xfd,0x00,0xbf,0x40 } }, -{ 16, 0xbc30, 0, {0x0f,0x50,0x13,0xd4,0x02,0xfd,0x00,0x2f,0xc0,0x0f,0xd1,0x03,0xf4,0x40,0xf9,0x10 } }, -{ 16, 0xbc40, 0, {0x3e,0x44,0x0f,0xd1,0x03,0xf4,0x40,0xff,0x00,0xbf,0x44,0x0f,0xd1,0x03,0xe6,0x06 } }, -{ 16, 0xbc50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0xa0,0xfd,0x01,0x3e,0x44 } }, -{ 16, 0xbc60, 0, {0x0f,0xd1,0x03,0xd4,0x00,0xc5,0x00,0x33,0x41,0x0f,0xdb,0x03,0x27,0x20,0xd9,0xe0 } }, -{ 16, 0xbc70, 0, {0xb2,0x70,0x0d,0xda,0x83,0xf6,0x40,0xcf,0x10,0x32,0x78,0x2d,0xda,0x03,0x06,0x00 } }, -{ 16, 0xbc80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x00,0xb8,0x00,0x2e,0x28 } }, -{ 16, 0xbc90, 0, {0x0b,0x88,0x42,0xe0,0x10,0xd8,0x00,0x22,0x00,0x0b,0x8c,0x0a,0x23,0x00,0x88,0xc0 } }, -{ 16, 0xbca0, 0, {0x22,0x28,0x08,0x84,0x02,0xc2,0x80,0x80,0xa0,0x22,0x30,0x48,0xaa,0x82,0x0e,0x04 } }, -{ 16, 0xbcb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2c,0x40 } }, -{ 16, 0xbcc0, 0, {0x8b,0x12,0x02,0xc4,0x00,0x99,0x02,0x28,0x40,0x8b,0x16,0x02,0x84,0x81,0x91,0x30 } }, -{ 16, 0xbcd0, 0, {0x20,0x58,0x09,0x10,0x02,0xc5,0x00,0x81,0x00,0x64,0x4d,0x08,0x34,0x02,0x02,0x01 } }, -{ 16, 0xbce0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xac,0x0c,0xb9,0x04,0x2e,0x48 } }, -{ 16, 0xbcf0, 0, {0x0b,0x94,0x06,0xe4,0x00,0x99,0x40,0xaa,0x40,0x0b,0x92,0x22,0xa4,0x00,0x89,0x00 } }, -{ 16, 0xbd00, 0, {0x60,0x40,0x08,0x94,0x02,0xe4,0x00,0x89,0x80,0xa6,0x50,0x08,0x92,0x02,0x06,0x04 } }, -{ 16, 0xbd10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x98,0x3e,0x48 } }, -{ 16, 0xbd20, 0, {0x0f,0x98,0x03,0xe5,0x20,0xd9,0x00,0x3a,0x64,0x0f,0x94,0x83,0xa4,0xc0,0xd9,0x02 } }, -{ 16, 0xbd30, 0, {0x72,0x40,0x4d,0x90,0x42,0xe4,0x82,0xc9,0x40,0x36,0x40,0x0c,0x90,0x0b,0x28,0x04 } }, -{ 16, 0xbd40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xac,0x28,0xf9,0x88,0x3e,0x40 } }, -{ 16, 0xbd50, 0, {0x0f,0x99,0x13,0xe7,0x00,0xf9,0xc0,0x36,0x60,0x0f,0x90,0x03,0x66,0x00,0xf1,0x00 } }, -{ 16, 0xbd60, 0, {0x7e,0x40,0x0f,0x99,0x07,0xe4,0x60,0xf9,0x00,0x38,0x40,0x0f,0x98,0x03,0xca,0x00 } }, -{ 16, 0xbd70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x10,0x32,0x00 } }, -{ 16, 0xbd80, 0, {0x0f,0x82,0x0b,0x21,0x00,0xe8,0x00,0x36,0x04,0x0c,0x86,0x03,0xe1,0x00,0xd8,0x00 } }, -{ 16, 0xbd90, 0, {0x32,0x00,0x0f,0x80,0x03,0x61,0x00,0xc8,0x00,0x32,0x00,0x0f,0x00,0x03,0x0a,0x04 } }, -{ 16, 0xbda0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x20,0xbe,0x00,0x22,0x80 } }, -{ 16, 0xbdb0, 0, {0x28,0xec,0x02,0x19,0x04,0x82,0x00,0x03,0x80,0x0d,0xe4,0x82,0xe8,0x00,0x8a,0x01 } }, -{ 16, 0xbdc0, 0, {0xaa,0x80,0x8b,0xed,0x82,0x3b,0x80,0x8e,0x90,0x36,0x80,0x0b,0xe0,0x03,0x4a,0x00 } }, -{ 16, 0xbdd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x42,0x00,0xb3,0x80,0x20,0xc0 } }, -{ 16, 0xbde0, 0, {0x6b,0x34,0x16,0x40,0xc0,0x83,0x10,0x24,0x72,0x88,0xb0,0x02,0xec,0x00,0x83,0x00 } }, -{ 16, 0xbdf0, 0, {0x24,0xc0,0x0b,0x04,0x02,0x6f,0x09,0x9b,0x00,0x24,0xc0,0x0b,0x30,0x02,0x0a,0x00 } }, -{ 16, 0xbe00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x14,0x00,0xb7,0x80,0x23,0xe4 } }, -{ 16, 0xbe10, 0, {0x28,0x78,0x82,0x74,0x14,0x8f,0x00,0x61,0xe0,0x09,0x50,0x12,0xdc,0x04,0x87,0x22 } }, -{ 16, 0xbe20, 0, {0x25,0xc8,0x1b,0x78,0x02,0x14,0x00,0x94,0x40,0xa5,0xc0,0x0b,0x60,0x22,0x68,0x00 } }, -{ 16, 0xbe30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x20,0xb7,0x80,0xb1,0xe0 } }, -{ 16, 0xbe40, 0, {0x8f,0xf8,0x03,0x12,0x02,0xe7,0x80,0x35,0xe0,0x0c,0x68,0x06,0xcf,0xc2,0xcf,0xb0 } }, -{ 16, 0xbe50, 0, {0x25,0xf4,0x0f,0x58,0x03,0x5a,0x02,0xd5,0x80,0x75,0xfa,0x4f,0xf8,0x03,0x2a,0x02 } }, -{ 16, 0xbe60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xa5,0x90,0xf3,0x00,0x3d,0xc0 } }, -{ 16, 0xbe70, 0, {0x4f,0xb0,0x13,0xa8,0x04,0xfb,0x00,0x3c,0xc0,0x0f,0x80,0x43,0xec,0x80,0xeb,0x60 } }, -{ 16, 0xbe80, 0, {0x3a,0xc9,0x0f,0x30,0x03,0xec,0x00,0xe9,0x00,0x3e,0xc8,0x0f,0xa0,0x03,0xc2,0x06 } }, -{ 16, 0xbe90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xee,0x80,0x3f,0xe0 } }, -{ 16, 0xbea0, 0, {0x0d,0x89,0x03,0xd2,0x40,0xe5,0x81,0x39,0xe0,0x3c,0xf9,0x07,0xfe,0x00,0xcf,0x88 } }, -{ 16, 0xbeb0, 0, {0x3f,0xe0,0x0f,0xe8,0x03,0xf2,0x08,0xce,0x80,0x33,0xe0,0x0c,0xf8,0x03,0x00,0x00 } }, -{ 16, 0xbec0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x94,0x44,0xc6,0x00,0x2f,0xc0 } }, -{ 16, 0xbed0, 0, {0x08,0x58,0x02,0xd0,0xc4,0x85,0x24,0x21,0x90,0x08,0x54,0x12,0xdc,0x82,0x07,0x00 } }, -{ 16, 0xbee0, 0, {0x2d,0xc0,0x0b,0x70,0x06,0xd4,0x00,0x8e,0x48,0x21,0xc0,0x0a,0x60,0x02,0x2a,0x04 } }, -{ 16, 0xbef0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa7,0x40,0x2d,0xc0 } }, -{ 16, 0xbf00, 0, {0x08,0x42,0x02,0xd0,0x00,0xad,0x00,0x29,0xc0,0x08,0x70,0x22,0xdc,0x28,0x87,0x00 } }, -{ 16, 0xbf10, 0, {0x2d,0xc0,0x0b,0x40,0x02,0x98,0x00,0x97,0x00,0xa0,0xc4,0x08,0x70,0x02,0x00,0x00 } }, -{ 16, 0xbf20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x08,0x93,0x00,0x2c,0xe0 } }, -{ 16, 0xbf30, 0, {0x08,0x3c,0x22,0xc1,0x00,0x81,0x00,0x20,0x80,0x88,0x15,0x02,0xce,0x30,0x83,0x00 } }, -{ 16, 0xbf40, 0, {0x2c,0xc0,0x0b,0x3c,0x02,0xcc,0x04,0x93,0xc0,0x20,0xf4,0x4a,0x0c,0x82,0x08,0x04 } }, -{ 16, 0xbf50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xe3,0xc0,0x1f,0xe0 } }, -{ 16, 0xbf60, 0, {0x6c,0x10,0x83,0xe0,0x04,0xeb,0x00,0x3a,0x52,0x4c,0xb4,0x03,0xfe,0x02,0xcf,0x00 } }, -{ 16, 0xbf70, 0, {0x3f,0xc0,0x0f,0x84,0x43,0xe1,0x02,0xd8,0xc2,0x33,0xc0,0x0c,0x84,0x0b,0x2a,0x04 } }, -{ 16, 0xbf80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe9,0x00,0xeb,0x10,0x3e,0xc4 } }, -{ 16, 0xbf90, 0, {0x0e,0x94,0x03,0xe4,0x00,0xfb,0x18,0x3e,0xc2,0x0f,0xb6,0x03,0xec,0x00,0xfb,0x01 } }, -{ 16, 0xbfa0, 0, {0x3e,0xc0,0x0f,0x35,0x03,0xc4,0x28,0xea,0x42,0x3e,0xc0,0x0f,0x81,0x03,0xe0,0x00 } }, -{ 16, 0xbfb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x40,0xff,0x00,0x33,0xc0 } }, -{ 16, 0xbfc0, 0, {0x0c,0xc0,0xa3,0x30,0x28,0xcd,0xa0,0x33,0xc0,0x0c,0xe8,0x03,0x0c,0x00,0xef,0x05 } }, -{ 16, 0xbfd0, 0, {0x3d,0xc0,0x0c,0xca,0x83,0x3c,0x00,0xcd,0x08,0x3f,0xc2,0x0c,0xa0,0x03,0xc0,0x44 } }, -{ 16, 0xbfe0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x67,0x00,0xbb,0x80,0x20,0xc0 } }, -{ 16, 0xbff0, 0, {0x08,0xaa,0x02,0x08,0x00,0xa1,0x01,0x34,0xd1,0x08,0xa4,0x12,0x2c,0x00,0x8b,0x00 } }, -{ 16, 0xc000, 0, {0x6e,0xc0,0x88,0xb2,0x02,0x2c,0x08,0x89,0x80,0x2e,0xc0,0x0a,0xa8,0x03,0xa0,0x40 } }, -{ 16, 0xc010, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xba,0x80,0xa2,0xc0 } }, -{ 16, 0xc020, 0, {0x08,0xa8,0x0a,0xa0,0x00,0x8b,0x00,0xa2,0xc0,0x48,0x11,0x02,0xac,0x04,0x8b,0x00 } }, -{ 16, 0xc030, 0, {0x2e,0xc0,0x00,0x80,0x12,0x2a,0x08,0x8b,0x14,0x2c,0xc0,0x08,0x88,0x02,0xe0,0x00 } }, -{ 16, 0xc040, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xb2,0x00,0x22,0xc0 } }, -{ 16, 0xc050, 0, {0x08,0xb2,0x12,0x80,0x00,0xab,0x01,0x24,0xc0,0x08,0x00,0x02,0x0c,0x04,0x83,0x00 } }, -{ 16, 0xc060, 0, {0x2c,0xc0,0x08,0x30,0x02,0x07,0x00,0x82,0x00,0x24,0xc0,0x08,0x08,0x02,0x82,0x01 } }, -{ 16, 0xc070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xfb,0x00,0x32,0xc0 } }, -{ 16, 0xc080, 0, {0x0c,0xa2,0x03,0xa0,0x00,0xc9,0x00,0x32,0xc0,0x24,0x94,0x03,0x3c,0x02,0xcf,0x00 } }, -{ 16, 0xc090, 0, {0x2f,0xc0,0x04,0x80,0x0b,0x09,0x02,0xcb,0x01,0x3f,0xc0,0x2c,0xa0,0x03,0xc0,0x03 } }, -{ 16, 0xc0a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xdc,0x00,0xfd,0x02,0x3f,0xc0 } }, -{ 16, 0xc0b0, 0, {0x4f,0xe4,0x13,0x70,0x00,0xfd,0x00,0x3f,0xc0,0x0f,0xc2,0x83,0xfc,0x00,0xff,0x00 } }, -{ 16, 0xc0c0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xa8,0x06 } }, -{ 16, 0xc0d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x20,0xef,0x30,0x3f,0x04 } }, -{ 16, 0xc0e0, 0, {0x6c,0x88,0x03,0x3a,0x42,0xe4,0x91,0x3f,0x0d,0x0d,0x48,0x03,0x3c,0xc0,0xff,0x02 } }, -{ 16, 0xc0f0, 0, {0x33,0x44,0x0c,0xf4,0x03,0xfc,0x82,0xdf,0x30,0x33,0x60,0x0d,0xf1,0x03,0x30,0x00 } }, -{ 16, 0xc100, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xed,0x00,0x8b,0x70,0x2e,0x18 } }, -{ 16, 0xc110, 0, {0x88,0x22,0x4a,0x2c,0x82,0xea,0x26,0x2e,0x0c,0x0b,0xb8,0x42,0x3d,0x80,0xbf,0x90 } }, -{ 16, 0xc120, 0, {0x2a,0x54,0x28,0xb4,0x02,0xcd,0x00,0xdb,0x40,0x2a,0x4a,0x48,0x30,0x02,0xa0,0x04 } }, -{ 16, 0xc130, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0xb0,0xa3,0x00,0x6c,0x10 } }, -{ 16, 0xc140, 0, {0x09,0x00,0x82,0x20,0x82,0xa0,0x20,0x2c,0x88,0x4b,0x80,0x00,0x0c,0x40,0xb3,0x01 } }, -{ 16, 0xc150, 0, {0x20,0x48,0x0b,0x36,0x02,0x8c,0xe0,0x83,0x64,0x24,0x40,0x28,0x32,0x02,0x22,0x01 } }, -{ 16, 0xc160, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x11,0xac,0x00,0x8b,0x00,0x2e,0x00 } }, -{ 16, 0xc170, 0, {0x09,0x80,0x80,0xa6,0x00,0xba,0x11,0x2e,0x88,0x0b,0xb0,0x00,0x2c,0x00,0xbb,0x02 } }, -{ 16, 0xc180, 0, {0x02,0x40,0x09,0xb0,0x02,0xec,0x00,0x8b,0x00,0x2c,0xc8,0x08,0xb8,0x82,0xb0,0x04 } }, -{ 16, 0xc190, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xeb,0x00,0x3e,0x92 } }, -{ 16, 0xc1a0, 0, {0x0d,0x80,0x03,0x0a,0x20,0xe9,0x00,0x3e,0x50,0x45,0x80,0x01,0x2c,0x04,0xf3,0x00 } }, -{ 16, 0xc1b0, 0, {0x90,0x60,0x09,0xb0,0x03,0xec,0x00,0x8b,0x02,0x26,0x50,0x8d,0xbc,0x03,0x10,0x04 } }, -{ 16, 0xc1c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xbc,0x00,0xff,0x02,0x3f,0x80 } }, -{ 16, 0xc1d0, 0, {0x0e,0xf9,0x02,0x7c,0x22,0xaf,0x00,0x3f,0x60,0x03,0xc0,0x0b,0xfc,0x10,0xff,0x00 } }, -{ 16, 0xc1e0, 0, {0x3f,0x4a,0x4e,0xf0,0x03,0xfc,0x00,0xf7,0x00,0x2b,0x60,0x0f,0x70,0x03,0xf8,0x00 } }, -{ 16, 0xc1f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x00,0xb0,0x00 } }, -{ 16, 0xc200, 0, {0x0f,0x82,0x0b,0xa9,0x00,0xc9,0x00,0x32,0xd2,0x0f,0xa0,0x83,0xac,0x00,0xcb,0x10 } }, -{ 16, 0xc210, 0, {0x3e,0x40,0x0c,0xb0,0x03,0xec,0x00,0xdb,0x00,0x32,0x50,0x2c,0x95,0x03,0x10,0x04 } }, -{ 16, 0xc220, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3c,0x04,0xbf,0x02,0x22,0x80 } }, -{ 16, 0xc230, 0, {0x0b,0x98,0x00,0x29,0x00,0xcb,0x40,0x22,0xc0,0x0b,0x24,0x02,0x3c,0x08,0x8f,0x50 } }, -{ 16, 0xc240, 0, {0x2e,0x50,0x0d,0xf0,0x02,0xfd,0x42,0x8f,0x58,0x22,0xe0,0x48,0xb5,0x02,0x32,0x00 } }, -{ 16, 0xc250, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x6c,0x00,0xb3,0x00,0x24,0x40 } }, -{ 16, 0xc260, 0, {0x4b,0x94,0x00,0x49,0x00,0x90,0x80,0x04,0x30,0x09,0x00,0x0e,0x4c,0x00,0x83,0x80 } }, -{ 16, 0xc270, 0, {0x2c,0xc0,0x09,0x30,0x22,0x6e,0x42,0x83,0x80,0x20,0x48,0x08,0x38,0x02,0x38,0x00 } }, -{ 16, 0xc280, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0xb7,0x80,0x65,0x20 } }, -{ 16, 0xc290, 0, {0x0b,0x78,0x82,0x7a,0x08,0x8c,0xc0,0x25,0xa3,0x4b,0x78,0x02,0x5e,0x04,0x87,0x84 } }, -{ 16, 0xc2a0, 0, {0x2d,0x61,0x89,0x78,0x02,0xde,0x04,0x87,0x80,0xe9,0x62,0x08,0x78,0x02,0x08,0x00 } }, -{ 16, 0xc2b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xfb,0x00,0x34,0x48 } }, -{ 16, 0xc2c0, 0, {0x0f,0x3b,0x03,0x48,0x00,0x93,0x48,0x34,0x50,0x0d,0x00,0x03,0x6c,0x00,0xc3,0x10 } }, -{ 16, 0xc2d0, 0, {0x1c,0xc2,0x05,0x30,0x03,0xcc,0x40,0xcb,0x00,0x32,0x40,0x0c,0x20,0x03,0x12,0x02 } }, -{ 16, 0xc2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x20,0xff,0x01,0x03,0x40 } }, -{ 16, 0xc2f0, 0, {0x0f,0xf0,0x23,0x1c,0x00,0xff,0x00,0x3b,0x80,0x0f,0xb0,0x23,0x3c,0x02,0xff,0x50 } }, -{ 16, 0xc300, 0, {0x3d,0xc4,0x0f,0xf1,0x03,0xec,0x00,0xef,0x00,0xb7,0xc0,0x0f,0xe1,0x03,0xd0,0x06 } }, -{ 16, 0xc310, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xec,0x00,0xfb,0x02,0x3e,0xe0 } }, -{ 16, 0xc320, 0, {0x0c,0x80,0x03,0x48,0x02,0xc8,0x81,0x32,0x00,0x0f,0x90,0x42,0xec,0xa0,0xfb,0x10 } }, -{ 16, 0xc330, 0, {0x3e,0xe0,0x0c,0xb1,0x03,0xec,0x40,0xfb,0x10,0x32,0x40,0x1f,0xf0,0x03,0x2a,0x00 } }, -{ 16, 0xc340, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb7,0x24,0x2d,0x80 } }, -{ 16, 0xc350, 0, {0x08,0x70,0x42,0xd8,0x10,0x8c,0x02,0x21,0x40,0x0b,0x50,0x02,0xdd,0x00,0xe7,0x20 } }, -{ 16, 0xc360, 0, {0x2f,0x40,0x08,0x70,0x02,0xdc,0x05,0xb7,0x00,0x21,0xc0,0x0b,0xf0,0x02,0x12,0x04 } }, -{ 16, 0xc370, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x90,0x2f,0x40 } }, -{ 16, 0xc380, 0, {0x0a,0x68,0x02,0x7a,0x00,0x97,0x80,0x21,0xe0,0x0b,0x78,0x02,0xde,0x00,0xb7,0x80 } }, -{ 16, 0xc390, 0, {0x2d,0xe0,0x08,0x78,0x06,0xde,0x00,0xb7,0xa0,0x21,0x60,0x0b,0x78,0x42,0x30,0x00 } }, -{ 16, 0xc3a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0x00,0x2c,0xc0 } }, -{ 16, 0xc3b0, 0, {0x0a,0x34,0x02,0xc8,0x00,0x83,0x4a,0x20,0xf8,0x0b,0x31,0x02,0xcc,0x00,0xa3,0x00 } }, -{ 16, 0xc3c0, 0, {0x2c,0xc0,0x08,0x30,0x02,0xcc,0x00,0xb3,0x00,0x20,0xb2,0x0b,0x20,0x42,0x12,0x04 } }, -{ 16, 0xc3d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xba,0x00,0x3f,0x88 } }, -{ 16, 0xc3e0, 0, {0x2e,0xe0,0x43,0x59,0x88,0xde,0x00,0x33,0xb0,0x0f,0x6c,0x03,0xe8,0x00,0xfa,0x00 } }, -{ 16, 0xc3f0, 0, {0x3e,0x80,0x2c,0xa0,0x03,0xe8,0x04,0xfa,0x00,0x23,0xb8,0x0f,0xe0,0x8b,0x3a,0x04 } }, -{ 16, 0xc400, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x04,0xf8,0x01,0x3e,0x00 } }, -{ 16, 0xc410, 0, {0x09,0x82,0x21,0xe0,0x00,0xf8,0x40,0xbe,0x14,0x0f,0x84,0x81,0xe0,0x00,0xe8,0x00 } }, -{ 16, 0xc420, 0, {0x3e,0x00,0x1f,0x80,0x03,0xe0,0x00,0xf8,0x00,0xbe,0x00,0x0f,0x88,0x03,0xd2,0x00 } }, -{ 16, 0xc430, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xe1,0x00,0x32,0x40 } }, -{ 16, 0xc440, 0, {0x0c,0x90,0x43,0xe4,0x20,0xd9,0x00,0x3c,0x44,0x08,0x90,0x03,0x24,0x00,0xf9,0x01 } }, -{ 16, 0xc450, 0, {0x3e,0x48,0x0f,0x10,0x43,0x25,0x00,0xc9,0x00,0xb2,0x40,0x0c,0x90,0x03,0x02,0x04 } }, -{ 16, 0xc460, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x00,0xa0,0x40 } }, -{ 16, 0xc470, 0, {0x08,0x98,0x02,0xe6,0x08,0xa9,0x60,0x2e,0x49,0x08,0x94,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xc480, 0, {0x2e,0x70,0x0b,0x90,0x02,0x26,0x02,0x89,0x00,0xa0,0x40,0x0a,0x90,0x0a,0x20,0x00 } }, -{ 16, 0xc490, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x22,0x40 } }, -{ 16, 0xc4a0, 0, {0x08,0x98,0x04,0xe6,0x00,0x99,0x80,0x2e,0x40,0x0a,0xb1,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xc4b0, 0, {0x0e,0x40,0x0b,0x90,0x0a,0x04,0x00,0x81,0x01,0x22,0xc0,0x08,0x10,0x02,0x06,0x00 } }, -{ 16, 0xc4c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0xb1,0x20,0x22,0x48 } }, -{ 16, 0xc4d0, 0, {0x08,0x18,0x06,0xc4,0x00,0xa1,0x00,0x2c,0x48,0x2a,0x30,0x02,0x04,0x80,0xb1,0x22 } }, -{ 16, 0xc4e0, 0, {0x2c,0x48,0x0b,0x12,0x02,0x05,0x80,0x81,0x60,0x22,0x50,0x0a,0x14,0x02,0x02,0x01 } }, -{ 16, 0xc4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x50,0x32,0x14 } }, -{ 16, 0xc500, 0, {0x0c,0x85,0x03,0xe1,0x40,0xd8,0x50,0x3e,0x14,0x0e,0x80,0x0b,0x21,0x40,0xfa,0x00 } }, -{ 16, 0xc510, 0, {0x3e,0x94,0x0f,0x85,0x03,0x20,0x00,0xc0,0x00,0x32,0x00,0x0c,0x80,0x03,0x2e,0x03 } }, -{ 16, 0xc520, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x41,0xf9,0x10,0x3d,0x45 } }, -{ 16, 0xc530, 0, {0x0f,0xd0,0x03,0xf4,0x00,0xff,0x00,0x3f,0x45,0x0d,0xd0,0x03,0xe4,0x40,0xf9,0x10 } }, -{ 16, 0xc540, 0, {0x3f,0x44,0x0f,0x91,0x03,0xe4,0x42,0xf9,0x10,0x3f,0x40,0x0f,0xd4,0x03,0xe6,0x06 } }, -{ 16, 0xc550, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe4,0x00,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0xc560, 0, {0x0c,0xd0,0x03,0xf4,0x08,0x8d,0x02,0x3f,0x40,0x0f,0xd0,0x03,0xe4,0x00,0xcd,0x00 } }, -{ 16, 0xc570, 0, {0x33,0x40,0x0c,0x90,0x03,0x24,0x00,0xf9,0x00,0x32,0x40,0x4c,0x98,0x23,0x06,0x00 } }, -{ 16, 0xc580, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0xe8,0x00,0x2e,0x00 } }, -{ 16, 0xc590, 0, {0x48,0x80,0x02,0xe8,0x00,0xd0,0x00,0x2e,0x80,0x0b,0x80,0x12,0xe0,0x02,0x88,0x00 } }, -{ 16, 0xc5a0, 0, {0xa2,0x00,0x0a,0x80,0x12,0x22,0x00,0xb8,0x81,0x22,0x28,0x08,0xcf,0x02,0x0e,0x04 } }, -{ 16, 0xc5b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2c,0x40 } }, -{ 16, 0xc5c0, 0, {0x28,0x10,0x02,0xc4,0x00,0x81,0x00,0x2c,0x40,0x0b,0x10,0x02,0xc4,0x00,0x91,0x00 } }, -{ 16, 0xc5d0, 0, {0x26,0x40,0x09,0x10,0x02,0x54,0xa0,0xb5,0x2c,0xa5,0x42,0x08,0x50,0x82,0x02,0x01 } }, -{ 16, 0xc5e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0xa9,0x00,0x2e,0x50 } }, -{ 16, 0xc5f0, 0, {0x58,0x90,0x02,0xe4,0x80,0x9b,0x00,0x2e,0x45,0x8b,0x92,0x02,0xe4,0x00,0x99,0x00 } }, -{ 16, 0xc600, 0, {0x26,0x44,0x0b,0x90,0x02,0x64,0x08,0xb5,0x00,0x25,0x4a,0x08,0x51,0x02,0x06,0x04 } }, -{ 16, 0xc610, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x00,0x3e,0x54 } }, -{ 16, 0xc620, 0, {0x0c,0x90,0x43,0xc4,0x00,0xc9,0x90,0x3e,0x70,0x0f,0x98,0x03,0xe4,0x00,0xd9,0x00 } }, -{ 16, 0xc630, 0, {0x34,0x60,0x4d,0x90,0x0a,0x64,0x00,0xf9,0x00,0x36,0x40,0x2c,0x9e,0x03,0x28,0x04 } }, -{ 16, 0xc640, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x00,0x3c,0x40 } }, -{ 16, 0xc650, 0, {0x0f,0x9c,0x03,0xe6,0x30,0xf9,0x00,0x3e,0x62,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x00 } }, -{ 16, 0xc660, 0, {0x3a,0x40,0x4e,0x90,0x03,0xa4,0x00,0x79,0x0c,0x3a,0x40,0x0f,0x90,0x1b,0xca,0x00 } }, -{ 16, 0xc670, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x00,0x3e,0x00 } }, -{ 16, 0xc680, 0, {0x0c,0x81,0x13,0xe1,0x08,0xc8,0x48,0x32,0x00,0x3c,0x80,0x03,0xc0,0x00,0xf0,0x10 } }, -{ 16, 0xc690, 0, {0x3e,0x06,0x0c,0x80,0x03,0xf0,0x08,0xcc,0x00,0x33,0x04,0x0c,0xc0,0x03,0x0a,0x04 } }, -{ 16, 0xc6a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xba,0x00,0x2e,0x80 } }, -{ 16, 0xc6b0, 0, {0x08,0xec,0x42,0xfa,0x20,0x8e,0x00,0x23,0xa0,0x08,0xe8,0x42,0xe8,0x00,0xbe,0x80 } }, -{ 16, 0xc6c0, 0, {0x2f,0x80,0x08,0xa0,0x02,0xe8,0x00,0xda,0x00,0x22,0x80,0x48,0xe0,0x02,0x0a,0x00 } }, -{ 16, 0xc6d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x2c,0xc0 } }, -{ 16, 0xc6e0, 0, {0x09,0x34,0x82,0xc9,0x00,0x83,0x80,0x20,0xf0,0x08,0x30,0x82,0xcc,0x00,0xb3,0x80 } }, -{ 16, 0xc6f0, 0, {0x2c,0xf0,0x08,0xb0,0x02,0xc1,0x20,0x80,0x00,0xa0,0x32,0x08,0x00,0x02,0x0a,0x00 } }, -{ 16, 0xc700, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0xc0,0xb7,0x01,0x2f,0xc8 } }, -{ 16, 0xc710, 0, {0x89,0x50,0x02,0xd8,0x02,0x87,0xc4,0x21,0xe2,0x48,0x70,0x82,0xdc,0x00,0xb7,0x00 } }, -{ 16, 0xc720, 0, {0x2c,0x40,0x08,0x72,0x02,0xce,0x00,0x97,0x08,0x23,0xc0,0x08,0x70,0x02,0x28,0x00 } }, -{ 16, 0xc730, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf7,0xe1,0x3d,0xe8 } }, -{ 16, 0xc740, 0, {0x2d,0x68,0x03,0xf2,0x00,0xc7,0x80,0xb0,0xe0,0x08,0x68,0x03,0xdf,0x80,0xf6,0x80 } }, -{ 16, 0xc750, 0, {0x3d,0xe0,0x8c,0x7e,0x03,0xda,0x00,0xcc,0x80,0x31,0x20,0x0c,0xc8,0x0b,0x2a,0x02 } }, -{ 16, 0xc760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x08,0xfb,0x00,0x3c,0xc0 } }, -{ 16, 0xc770, 0, {0x0e,0x80,0x03,0xe0,0x08,0xf9,0x00,0x3e,0x40,0x0f,0xb0,0x02,0xec,0x00,0xfa,0x00 } }, -{ 16, 0xc780, 0, {0x3e,0x40,0x2f,0xb0,0x03,0xe4,0x00,0xfb,0x00,0x3c,0xc0,0x2f,0xb0,0x03,0xc2,0x06 } }, -{ 16, 0xc790, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xff,0x92,0x7f,0xea } }, -{ 16, 0xc7a0, 0, {0x0c,0xf8,0x03,0xfe,0x00,0xcc,0xa0,0x3f,0x20,0x0d,0xf9,0x03,0x3e,0x00,0xcf,0x80 } }, -{ 16, 0xc7b0, 0, {0x33,0x60,0x0f,0xf8,0x03,0xf6,0x00,0xef,0x84,0x33,0xe0,0x2c,0xc8,0x03,0x00,0x00 } }, -{ 16, 0xc7c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xb7,0x00,0x2f,0xc8 } }, -{ 16, 0xc7d0, 0, {0x08,0x54,0x02,0xd8,0x00,0xd6,0x04,0x2d,0x01,0x08,0x69,0x02,0x1c,0x00,0x85,0x00 } }, -{ 16, 0xc7e0, 0, {0x21,0x43,0x0b,0x70,0x03,0x9a,0xc0,0x8c,0x00,0xa3,0x02,0x08,0xf1,0x02,0x2a,0x04 } }, -{ 16, 0xc7f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x01,0x2d,0xcc } }, -{ 16, 0xc800, 0, {0x08,0x70,0x02,0xd4,0x00,0x94,0x28,0x2d,0xc2,0x08,0xc2,0x02,0x5c,0x00,0x86,0x00 } }, -{ 16, 0xc810, 0, {0x21,0x80,0x0b,0x71,0x02,0xdc,0x00,0xa7,0x10,0x21,0xc0,0x08,0x48,0x02,0x40,0x00 } }, -{ 16, 0xc820, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x08,0xb3,0x00,0x2c,0xf0 } }, -{ 16, 0xc830, 0, {0x08,0x05,0x02,0xc0,0x20,0x90,0x80,0x2e,0x00,0x08,0x00,0x82,0x4c,0x02,0x80,0x00 } }, -{ 16, 0xc840, 0, {0xa0,0x61,0x0b,0x30,0x02,0xa0,0x00,0x80,0x00,0xa0,0x30,0x88,0xb1,0x0a,0x48,0x04 } }, -{ 16, 0xc850, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xff,0x00,0x2d,0xc8 } }, -{ 16, 0xc860, 0, {0x0c,0x3d,0x03,0xe4,0x00,0xdb,0x02,0x3e,0xf0,0x2c,0x90,0x4b,0x7c,0x00,0xc1,0x00 } }, -{ 16, 0xc870, 0, {0x32,0x20,0x4f,0xf0,0x13,0xe0,0x00,0xe8,0x01,0x32,0x00,0x8c,0xac,0x03,0x6a,0x04 } }, -{ 16, 0xc880, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x04,0x3e,0xc2 } }, -{ 16, 0xc890, 0, {0x4f,0xb0,0x03,0xe0,0x04,0xfa,0x40,0x3e,0xc2,0x4e,0x98,0x23,0xac,0x10,0xf8,0x00 } }, -{ 16, 0xc8a0, 0, {0x3e,0x50,0x07,0xb0,0x13,0xac,0x00,0xfb,0x00,0x3e,0xc2,0x0f,0x92,0x03,0xa0,0x00 } }, -{ 16, 0xc8b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xcf,0x00,0x3f,0xc0 } }, -{ 16, 0xc8c0, 0, {0x0c,0xc8,0x23,0x36,0x82,0xcf,0x80,0x3f,0x80,0x0c,0xe0,0x03,0xec,0x00,0xf9,0x20 } }, -{ 16, 0xc8d0, 0, {0x33,0xc0,0x0e,0xf0,0x03,0xf8,0x10,0xdc,0x00,0x33,0x00,0x4c,0xe8,0x21,0x00,0x44 } }, -{ 16, 0xc8e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x00,0xab,0x00,0x2e,0xc0 } }, -{ 16, 0xc8f0, 0, {0x4a,0x8d,0x42,0x21,0x00,0x8b,0x42,0x2e,0xd2,0x08,0xb0,0x03,0xec,0x00,0xb8,0x88 } }, -{ 16, 0xc900, 0, {0x34,0x62,0x0d,0xb0,0x02,0xe4,0x00,0x8b,0x00,0x22,0xc0,0x08,0x90,0x0a,0x20,0x40 } }, -{ 16, 0xc910, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x2e,0xc0 } }, -{ 16, 0xc920, 0, {0x08,0xa0,0x02,0x0d,0x00,0x89,0x10,0x2e,0x08,0x28,0x92,0x02,0xec,0x04,0xbb,0x00 } }, -{ 16, 0xc930, 0, {0x22,0xa0,0x08,0xb0,0x02,0x64,0x02,0xb3,0x02,0x20,0xc0,0x08,0xa2,0x02,0xa0,0x00 } }, -{ 16, 0xc940, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xa3,0x00,0x2e,0xc0 } }, -{ 16, 0xc950, 0, {0x0a,0x90,0x22,0x0c,0x10,0x80,0x00,0x2c,0x00,0x18,0x02,0x82,0xcc,0x00,0xb0,0x00 } }, -{ 16, 0xc960, 0, {0x26,0x40,0x09,0x30,0x02,0xc8,0x20,0x80,0x00,0x20,0x00,0x08,0x10,0x06,0x82,0x01 } }, -{ 16, 0xc970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xcb,0x00,0x2e,0xc0 } }, -{ 16, 0xc980, 0, {0x0c,0xa1,0x02,0x24,0x00,0x88,0x00,0x3c,0x00,0x0c,0x80,0x03,0xec,0x00,0xfb,0x00 } }, -{ 16, 0xc990, 0, {0x32,0x80,0x0e,0xb0,0x03,0xcc,0x80,0xdb,0x00,0x32,0xc0,0x0c,0xa0,0x03,0x80,0x03 } }, -{ 16, 0xc9a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3f,0xc0 } }, -{ 16, 0xc9b0, 0, {0x4f,0xc2,0x13,0xd4,0x10,0xfc,0x00,0x3f,0x00,0x0f,0x00,0x03,0xbc,0x00,0xfc,0x00 } }, -{ 16, 0xc9c0, 0, {0x3f,0x40,0x0f,0xf0,0x23,0xe0,0x12,0xfc,0x01,0xbf,0x00,0x0f,0xd0,0x03,0x68,0x02 } }, -{ 16, 0xc9d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xc7,0x80,0x33,0xc0 } }, -{ 16, 0xc9e0, 0, {0x8b,0xb4,0x03,0xb0,0xc0,0xcf,0x2e,0x1f,0x0c,0x4f,0xc3,0x03,0x30,0x80,0xff,0x01 } }, -{ 16, 0xc9f0, 0, {0x3f,0x08,0x0f,0xf0,0x00,0x7c,0x00,0xff,0x21,0x33,0xe4,0x0c,0xe0,0x03,0x30,0x00 } }, -{ 16, 0xca00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xee,0x00,0x8b,0x82,0x23,0xf0 } }, -{ 16, 0xca10, 0, {0x0b,0xb5,0x12,0x0d,0x88,0x88,0xc0,0x0e,0x98,0x0b,0x86,0x02,0x21,0x00,0xbb,0xc0 } }, -{ 16, 0xca20, 0, {0x2e,0xe4,0x4b,0xf7,0x83,0x2f,0x44,0xbf,0x90,0x22,0xc8,0x48,0xa6,0x82,0x20,0x04 } }, -{ 16, 0xca30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x09,0x8a,0x00,0x20,0x50 } }, -{ 16, 0xca40, 0, {0x4b,0xb2,0x0a,0x80,0xcc,0x83,0x01,0x0c,0x8c,0x0b,0x23,0x0a,0x04,0x60,0xb3,0x14 } }, -{ 16, 0xca50, 0, {0x24,0x40,0x4b,0x30,0x02,0xcc,0x10,0xb3,0x00,0x20,0xc8,0xe9,0x11,0x06,0x62,0x01 } }, -{ 16, 0xca60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x01,0x8a,0x80,0xa2,0x44 } }, -{ 16, 0xca70, 0, {0x0b,0xb0,0x02,0xa1,0x04,0x88,0x40,0x2e,0xa0,0x0b,0x20,0x02,0x28,0x20,0xbb,0x40 } }, -{ 16, 0xca80, 0, {0x2e,0x40,0x0b,0xb0,0x02,0x2c,0x08,0xbb,0x00,0x22,0xc0,0x09,0xb0,0x02,0x70,0x04 } }, -{ 16, 0xca90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xc3,0x83,0x32,0xe0 } }, -{ 16, 0xcaa0, 0, {0x8f,0x00,0x03,0xa0,0x02,0xcb,0xc4,0x3e,0x28,0x07,0x8b,0x03,0x21,0x00,0xf9,0xc0 } }, -{ 16, 0xcab0, 0, {0x3e,0x10,0x0f,0xb0,0x03,0xec,0x00,0x7b,0x00,0x32,0xc0,0x0d,0xa0,0x03,0x50,0x04 } }, -{ 16, 0xcac0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x9c,0x02,0xff,0x00,0x3f,0xe0 } }, -{ 16, 0xcad0, 0, {0x0f,0xf4,0x43,0x5e,0x80,0xfc,0x94,0x3f,0x00,0x0f,0xc0,0x2b,0xf2,0x50,0xfd,0x21 } }, -{ 16, 0xcae0, 0, {0x7e,0x84,0x8f,0xf0,0x03,0x6c,0x0c,0xff,0x00,0x3f,0xc0,0x0e,0x62,0x03,0xb8,0x00 } }, -{ 16, 0xcaf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xeb,0x00,0x32,0x40 } }, -{ 16, 0xcb00, 0, {0x2c,0x80,0x03,0x69,0x00,0xcb,0x30,0xb2,0x00,0x4f,0xb3,0x43,0xe5,0x00,0xcb,0x40 } }, -{ 16, 0xcb10, 0, {0x72,0x18,0x2c,0xb0,0x03,0xec,0x28,0xc3,0x21,0x3a,0xc1,0x0f,0x94,0x03,0x10,0x04 } }, -{ 16, 0xcb20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3c,0x00,0x8b,0x20,0x22,0x50 } }, -{ 16, 0xcb30, 0, {0x08,0xb0,0x02,0x28,0x00,0x88,0xc0,0x2a,0x00,0x8b,0xb4,0x02,0xe8,0x00,0xdb,0x00 } }, -{ 16, 0xcb40, 0, {0x62,0x30,0x08,0xf0,0x02,0xfc,0x00,0x8f,0x80,0x22,0xc0,0x0b,0x95,0x47,0x32,0x00 } }, -{ 16, 0xcb50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb1,0x00,0x20,0xc2 } }, -{ 16, 0xcb60, 0, {0x48,0x30,0x02,0x49,0x80,0x83,0x42,0x60,0x12,0x0b,0x30,0x02,0xc8,0x00,0x82,0x02 } }, -{ 16, 0xcb70, 0, {0x2c,0x30,0x09,0xb0,0x02,0xcf,0x01,0x83,0x50,0x2a,0xc0,0x0b,0x20,0x02,0xb8,0x00 } }, -{ 16, 0xcb80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0x9d,0x80,0xa0,0xe0 } }, -{ 16, 0xcb90, 0, {0x08,0x79,0x22,0x5e,0x60,0x87,0x90,0x29,0xa0,0x0b,0x78,0x02,0xc6,0x00,0x92,0x81 } }, -{ 16, 0xcba0, 0, {0x05,0xe0,0x09,0x78,0x02,0xde,0x40,0x87,0x80,0x21,0xe0,0x0b,0x29,0x02,0x08,0x00 } }, -{ 16, 0xcbb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x40,0xf2,0x00,0x30,0xc0 } }, -{ 16, 0xcbc0, 0, {0x08,0x3a,0x03,0x44,0x04,0xc3,0x14,0x30,0xc0,0x0f,0x22,0x03,0xcc,0x80,0xc2,0x00 } }, -{ 16, 0xcbd0, 0, {0xa4,0xd2,0x0d,0x30,0x13,0xcc,0x20,0xc3,0x00,0x38,0xc4,0x4f,0x04,0x43,0x12,0x02 } }, -{ 16, 0xcbe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x9c,0x00,0xee,0x00,0x3f,0xe0 } }, -{ 16, 0xcbf0, 0, {0x0f,0x70,0x03,0xb4,0x02,0xf4,0x10,0x3f,0xc0,0x8f,0xa0,0x03,0xfc,0x00,0x7e,0x00 } }, -{ 16, 0xcc00, 0, {0x3b,0xc0,0x0e,0xf0,0x83,0xec,0x00,0xf7,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xd0,0x06 } }, -{ 16, 0xcc10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xfc,0x00,0xf9,0x00,0x3e,0xc0 } }, -{ 16, 0xcc20, 0, {0x0f,0xa0,0x03,0xaa,0x12,0xcb,0x01,0x32,0x80,0x0f,0xb0,0x13,0x28,0x14,0xf9,0x80 } }, -{ 16, 0xcc30, 0, {0x3a,0x40,0x03,0xb4,0x03,0xec,0x42,0xcb,0x18,0x3e,0xc0,0x0f,0xb0,0x03,0x2a,0x00 } }, -{ 16, 0xcc40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9d,0x00,0xb5,0x00,0x2d,0xc4 } }, -{ 16, 0xcc50, 0, {0x0b,0x70,0x4b,0x7c,0x00,0x84,0x00,0x21,0x80,0x0b,0x70,0x02,0x94,0x10,0xb2,0x00 } }, -{ 16, 0xcc60, 0, {0x29,0xc0,0x0b,0x72,0x82,0xdc,0x00,0x87,0x20,0x2d,0xc1,0x0e,0x70,0x02,0x12,0x04 } }, -{ 16, 0xcc70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x80,0x2d,0xe0 } }, -{ 16, 0xcc80, 0, {0x0b,0x68,0x02,0x9e,0x00,0x83,0x80,0x21,0xe0,0x5b,0x38,0x02,0x1e,0x00,0xb4,0xc0 } }, -{ 16, 0xcc90, 0, {0x25,0xe0,0x09,0x78,0x32,0xce,0x00,0x97,0x80,0x2d,0xe0,0x0b,0x5c,0x4e,0x30,0x00 } }, -{ 16, 0xcca0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0x44,0x2c,0xc0 } }, -{ 16, 0xccb0, 0, {0x0b,0x3c,0x02,0xcc,0x40,0x93,0x08,0x20,0xe0,0x0b,0x30,0x02,0x8c,0x10,0xb3,0xc0 } }, -{ 16, 0xccc0, 0, {0x28,0xd8,0x1b,0x30,0x02,0xcc,0x08,0x93,0x01,0x6c,0xc0,0x0a,0xb8,0x82,0x12,0x04 } }, -{ 16, 0xccd0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xf6,0x10,0x3e,0x80 } }, -{ 16, 0xcce0, 0, {0x4b,0xed,0x83,0xb8,0x00,0xce,0xe4,0xb3,0xa3,0x0f,0xe0,0x03,0x38,0x00,0xfe,0x00 } }, -{ 16, 0xccf0, 0, {0x3b,0x80,0x0d,0xa0,0x02,0xe8,0x00,0xda,0x00,0x3e,0x80,0x0f,0xe8,0x02,0x3a,0x04 } }, -{ 16, 0xcd00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x10,0xf8,0x40,0x3e,0x00 } }, -{ 16, 0xcd10, 0, {0x0f,0x80,0x13,0x60,0x00,0xe0,0x00,0x3e,0x00,0x43,0x08,0x03,0xe0,0x00,0xf8,0x08 } }, -{ 16, 0xcd20, 0, {0x3a,0x00,0x0f,0x80,0x03,0xe0,0x00,0xe8,0x40,0x3e,0x00,0x0e,0x80,0x23,0xd2,0x00 } }, -{ 16, 0xcd30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x00,0xd9,0xc0,0xbe,0x40 } }, -{ 16, 0xcd40, 0, {0x0f,0x90,0x03,0xe6,0x00,0xf9,0x00,0x32,0x40,0x01,0x9a,0x03,0x24,0x00,0xf9,0x00 } }, -{ 16, 0xcd50, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc4,0x40,0x09,0x10,0x0e,0x40,0x0f,0x9a,0x03,0x02,0x04 } }, -{ 16, 0xcd60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x04,0x89,0x04,0xa2,0x60 } }, -{ 16, 0xcd70, 0, {0x8b,0x9d,0x80,0xa6,0x00,0xb9,0x80,0x22,0x40,0x48,0x98,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xcd80, 0, {0x2e,0x40,0x8b,0x90,0x02,0xe4,0x94,0x89,0x60,0x2e,0x40,0x0b,0x94,0x0b,0x20,0x00 } }, -{ 16, 0xcd90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x99,0x08,0xae,0x48 } }, -{ 16, 0xcda0, 0, {0x4b,0x10,0x02,0xe5,0x81,0xb9,0x10,0x20,0x44,0x1b,0x94,0x02,0x24,0x10,0xb9,0x00 } }, -{ 16, 0xcdb0, 0, {0x6e,0x60,0x0b,0x90,0x02,0xe4,0x00,0x89,0x00,0x2e,0x40,0x0b,0x94,0x02,0x06,0x00 } }, -{ 16, 0xcdc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0x89,0x00,0xa0,0x68 } }, -{ 16, 0xcdd0, 0, {0x0b,0x12,0x02,0x84,0x89,0xb1,0x20,0x20,0x48,0x1a,0x12,0x12,0x04,0x80,0xb1,0x22 } }, -{ 16, 0xcde0, 0, {0x0c,0x48,0x0b,0x12,0x02,0xc4,0x81,0xa1,0x20,0x2c,0x40,0x0b,0x12,0x02,0x02,0x01 } }, -{ 16, 0xcdf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xd8,0x00,0xbe,0x00 } }, -{ 16, 0xce00, 0, {0x0f,0x05,0x0b,0xe1,0x40,0xf8,0x00,0x32,0x14,0x0f,0x85,0x03,0x21,0x40,0xf8,0x00 } }, -{ 16, 0xce10, 0, {0x2e,0x80,0x0f,0x85,0x13,0xe0,0x02,0xc8,0x00,0x3e,0x14,0x0f,0x05,0x01,0x2e,0x03 } }, -{ 16, 0xce20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x40,0xfd,0x00,0xbf,0x44 } }, -{ 16, 0xce30, 0, {0x0f,0xd1,0x03,0xf4,0x40,0x7d,0x10,0xbf,0x44,0x45,0xf1,0x2b,0xf4,0x40,0xfd,0x10 } }, -{ 16, 0xce40, 0, {0x3f,0x44,0x0f,0x91,0x03,0xe4,0x40,0xd9,0x10,0x3e,0x40,0x0f,0xd1,0x03,0xa6,0x06 } }, -{ 16, 0xce50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x00,0xfd,0x00,0x1f,0x62 } }, -{ 16, 0xce60, 0, {0x0f,0xd8,0x82,0x36,0x00,0xbd,0xa0,0x3b,0x68,0x0c,0xdc,0x83,0x26,0xc8,0xd9,0xa0 } }, -{ 16, 0xce70, 0, {0x33,0x60,0x0d,0x99,0x83,0x56,0x20,0xd5,0xa8,0x2e,0x44,0x0c,0xd8,0x83,0x86,0x04 } }, -{ 16, 0xce80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x48,0xb8,0x00,0x2e,0x00 } }, -{ 16, 0xce90, 0, {0x0b,0x0a,0x82,0x22,0x20,0xb8,0x50,0x22,0xba,0x08,0x8a,0x22,0x22,0x80,0x88,0x00 } }, -{ 16, 0xcea0, 0, {0x22,0x01,0x08,0x0c,0x02,0x20,0x00,0x88,0x00,0x2e,0x28,0x88,0x88,0x02,0xce,0x04 } }, -{ 16, 0xceb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2c,0x40 } }, -{ 16, 0xcec0, 0, {0x1b,0x10,0x0a,0x84,0x40,0xb1,0x00,0x28,0x58,0x0a,0x32,0x02,0x05,0x00,0x99,0x40 } }, -{ 16, 0xced0, 0, {0x20,0x65,0x09,0x10,0x42,0xc4,0x00,0x91,0x00,0x2c,0x40,0x0a,0x30,0x82,0xc2,0x01 } }, -{ 16, 0xcee0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0xb9,0x00,0x2e,0x40 } }, -{ 16, 0xcef0, 0, {0x1b,0x90,0x02,0xa5,0x80,0xb9,0x10,0x22,0x48,0x08,0x10,0x42,0x04,0x10,0x09,0x00 } }, -{ 16, 0xcf00, 0, {0x22,0x40,0x08,0x90,0x02,0xe4,0x00,0x9b,0x00,0x2c,0x40,0x0a,0x94,0x22,0xc6,0x04 } }, -{ 16, 0xcf10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x20,0x3e,0x40 } }, -{ 16, 0xcf20, 0, {0x0f,0x90,0x13,0xa7,0x10,0xf9,0x60,0xba,0x50,0x2e,0x9c,0x0a,0x25,0x84,0xd1,0xf0 } }, -{ 16, 0xcf30, 0, {0xb2,0x60,0x0d,0x90,0x03,0xe4,0x00,0xd9,0x00,0x3e,0x40,0x0e,0x90,0x03,0xa8,0x00 } }, -{ 16, 0xcf40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x0c,0xf9,0x90,0x3e,0x6a } }, -{ 16, 0xcf50, 0, {0x8f,0x90,0x23,0x66,0x00,0xf1,0x08,0x3c,0x40,0x0f,0x9c,0x43,0xe4,0x40,0xf9,0x80 } }, -{ 16, 0xcf60, 0, {0x3a,0x44,0x0f,0x90,0x03,0x24,0x04,0xe9,0x02,0x3e,0x40,0x2d,0x91,0x13,0xca,0x00 } }, -{ 16, 0xcf70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xe8,0x20,0x3e,0x01 } }, -{ 16, 0xcf80, 0, {0x0c,0x00,0x03,0xa1,0x20,0xe8,0x50,0x32,0x10,0x2c,0x8c,0x03,0x21,0x00,0xe8,0x00 } }, -{ 16, 0xcf90, 0, {0x32,0x02,0x0f,0x00,0x13,0x20,0x88,0xc8,0x08,0x32,0x00,0x0f,0x8c,0x03,0xca,0x00 } }, -{ 16, 0xcfa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x20,0x8e,0xe3,0x2f,0x90 } }, -{ 16, 0xcfb0, 0, {0x0a,0xe0,0x06,0x3b,0x00,0xee,0x04,0x23,0x90,0x08,0xe0,0x02,0x28,0x08,0x8a,0x02 } }, -{ 16, 0xcfc0, 0, {0x75,0x90,0x8b,0xa0,0x41,0x58,0x90,0x8e,0x80,0x2a,0x81,0x0b,0xe0,0x03,0x8a,0x10 } }, -{ 16, 0xcfd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4e,0x00,0xa3,0x00,0x6c,0x60 } }, -{ 16, 0xcfe0, 0, {0x08,0x38,0x1a,0x8e,0x40,0xa0,0x80,0x20,0xcc,0x09,0x30,0x02,0x0c,0x05,0xa3,0x04 } }, -{ 16, 0xcff0, 0, {0x28,0xc4,0x0b,0x30,0x02,0x0d,0x01,0x83,0xc0,0x20,0xc0,0x0b,0x30,0x02,0xca,0x00 } }, -{ 16, 0xd000, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x08,0x87,0x00,0x2d,0x62 } }, -{ 16, 0xd010, 0, {0x0b,0x70,0x92,0x1c,0x08,0xa0,0x00,0x61,0xc0,0x09,0x60,0x06,0x1c,0x80,0xa7,0x00 } }, -{ 16, 0xd020, 0, {0x21,0xc0,0x0b,0x72,0x02,0x58,0x01,0x87,0x88,0x29,0xc0,0x0b,0x60,0x12,0xa8,0x00 } }, -{ 16, 0xd030, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xe6,0x80,0x3d,0x60 } }, -{ 16, 0xd040, 0, {0x0c,0x78,0x42,0x96,0x00,0xe4,0x80,0xa3,0x60,0x0d,0x78,0x03,0x3f,0x00,0xe3,0x80 } }, -{ 16, 0xd050, 0, {0x21,0xe0,0x0f,0x7b,0x03,0x16,0x08,0xc7,0x80,0x31,0xe2,0x4f,0x78,0x43,0xea,0x02 } }, -{ 16, 0xd060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0x8c,0x01,0xf8,0x00,0x3c,0x40 } }, -{ 16, 0xd070, 0, {0x0e,0xb0,0x02,0xec,0x00,0xf8,0x01,0x3e,0x40,0x4e,0x30,0x33,0xed,0x20,0xdb,0x01 } }, -{ 16, 0xd080, 0, {0xbe,0xc0,0x0f,0xb4,0x03,0xec,0x00,0xfb,0x00,0x3e,0xd8,0x0f,0xa0,0x03,0xc2,0x06 } }, -{ 16, 0xd090, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xc7,0x84,0x23,0x60 } }, -{ 16, 0xd0a0, 0, {0x0c,0x78,0x0b,0xbe,0x00,0xfd,0x80,0x3f,0xe0,0x0f,0xeb,0x03,0x3e,0x00,0xcf,0x80 } }, -{ 16, 0xd0b0, 0, {0x3b,0x25,0x0c,0xf8,0x83,0x7e,0x40,0xcd,0x80,0x33,0xe2,0x0b,0xf9,0x03,0x00,0x00 } }, -{ 16, 0xd0c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x02,0x87,0x00,0x15,0x48 } }, -{ 16, 0xd0d0, 0, {0x08,0x70,0x02,0x14,0x20,0xb6,0x00,0x35,0x9a,0x49,0xc8,0x03,0x9c,0x84,0xa7,0x00 } }, -{ 16, 0xd0e0, 0, {0x39,0xd0,0x0a,0x70,0x02,0x1a,0x08,0xa4,0x00,0x21,0xc0,0x09,0x61,0x42,0x2a,0x04 } }, -{ 16, 0xd0f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x00,0x21,0x40 } }, -{ 16, 0xd100, 0, {0x08,0x71,0x02,0x94,0x00,0xb5,0x00,0x2d,0x40,0x0b,0xf1,0x22,0x5c,0x02,0x07,0x08 } }, -{ 16, 0xd110, 0, {0x2c,0x50,0x08,0x70,0x02,0x50,0x00,0x87,0x00,0x2d,0xc4,0x0b,0x50,0x42,0x00,0x00 } }, -{ 16, 0xd120, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0x83,0x02,0x24,0x40 } }, -{ 16, 0xd130, 0, {0x18,0x3d,0x0a,0x01,0x00,0xb0,0x58,0x24,0x20,0x09,0x30,0x02,0x8f,0x40,0x83,0xe0 } }, -{ 16, 0xd140, 0, {0x2c,0xc1,0x0a,0x30,0x42,0x08,0x00,0xb3,0x01,0x6c,0xc0,0x09,0x08,0x16,0x08,0x04 } }, -{ 16, 0xd150, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x8c,0x00,0x8b,0x00,0x32,0x40 } }, -{ 16, 0xd160, 0, {0x0c,0x25,0x03,0xa8,0x48,0xf8,0x81,0x3e,0x80,0x0f,0x80,0x63,0x7c,0x00,0xcb,0x80 } }, -{ 16, 0xd170, 0, {0x3a,0xc0,0x0c,0xf0,0x03,0x6c,0x00,0xca,0x02,0xbf,0xc0,0x0f,0x98,0x8b,0x2a,0x04 } }, -{ 16, 0xd180, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xf9,0x00,0x3e,0x50 } }, -{ 16, 0xd190, 0, {0x2f,0xa4,0x0b,0xc8,0x00,0xf0,0x40,0x3e,0xd0,0x0f,0xa0,0x33,0xec,0x20,0xfb,0x04 } }, -{ 16, 0xd1a0, 0, {0x7a,0xe0,0x0f,0xb0,0x03,0xed,0x08,0xe9,0x03,0x32,0xc0,0x0d,0x90,0x03,0xe0,0x00 } }, -{ 16, 0xd1b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xec,0x40,0xee,0x00,0x3e,0xc0 } }, -{ 16, 0xd1c0, 0, {0x0c,0xda,0x03,0x70,0x04,0xcc,0x02,0xb1,0xa0,0x0e,0xf0,0x23,0xec,0x00,0xff,0x00 } }, -{ 16, 0xd1d0, 0, {0x37,0x20,0xcd,0xb0,0x73,0xec,0x88,0xfb,0x80,0x3f,0xc0,0x0f,0x30,0x03,0x00,0x44 } }, -{ 16, 0xd1e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6e,0x00,0x88,0x80,0x2c,0xe1 } }, -{ 16, 0xd1f0, 0, {0x08,0x94,0x0a,0xa9,0x02,0x88,0x40,0x22,0xd0,0x08,0xb9,0x42,0xec,0x04,0xbb,0x00 } }, -{ 16, 0xd200, 0, {0x2c,0xd4,0x0d,0xb0,0x02,0xed,0x20,0xbb,0xd0,0x2e,0xc0,0x0b,0xb0,0x02,0xa0,0x40 } }, -{ 16, 0xd210, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x24,0x00,0xab,0x80,0x2e,0xf0 } }, -{ 16, 0xd220, 0, {0x29,0xa0,0x82,0x6d,0x00,0x88,0x08,0x22,0x04,0x08,0x90,0x42,0xec,0x00,0xbb,0x00 } }, -{ 16, 0xd230, 0, {0x2a,0x81,0x08,0xb0,0x02,0xe4,0x09,0xba,0x04,0x2e,0xc1,0x4b,0x98,0x82,0x20,0x00 } }, -{ 16, 0xd240, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x83,0x00,0x2c,0xc0 } }, -{ 16, 0xd250, 0, {0x0a,0x21,0x02,0x84,0x10,0x82,0x00,0xe0,0x00,0x18,0x0a,0x12,0xcc,0x00,0xb3,0x00 } }, -{ 16, 0xd260, 0, {0x0c,0xc0,0x09,0x30,0x02,0xcc,0x90,0xb0,0x00,0x2c,0xc0,0x0b,0x10,0x02,0x82,0x01 } }, -{ 16, 0xd270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xeb,0x00,0x3e,0x00 } }, -{ 16, 0xd280, 0, {0x2c,0xb4,0x03,0x64,0x08,0x88,0x00,0xb2,0x00,0x0c,0xb2,0x43,0xfc,0x00,0xfb,0x00 } }, -{ 16, 0xd290, 0, {0x56,0x00,0x0c,0xf0,0x01,0xe4,0x00,0xfb,0x00,0x3f,0xc0,0x0f,0x80,0x0b,0x00,0x03 } }, -{ 16, 0xd2a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf4,0x00,0xff,0x00,0x3f,0x40 } }, -{ 16, 0xd2b0, 0, {0x2d,0xf0,0x61,0xf0,0x00,0xf4,0x00,0x27,0x01,0x0d,0xb1,0x11,0xfc,0x00,0xff,0x02 } }, -{ 16, 0xd2c0, 0, {0x07,0xc0,0x0f,0xf0,0x03,0xec,0x40,0xff,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0x68,0x06 } }, -{ 16, 0xd2d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf6,0x00,0xef,0x90,0x3d,0x4c } }, -{ 16, 0xd2e0, 0, {0x2c,0xc0,0x13,0xf4,0x08,0xfd,0x20,0x37,0x4c,0x8e,0x82,0x83,0x74,0x84,0xdc,0xc2 } }, -{ 16, 0xd2f0, 0, {0x3f,0xd8,0x0d,0xf2,0x03,0xec,0xc0,0xff,0x81,0x3f,0x00,0x0c,0xf8,0x03,0xf0,0x00 } }, -{ 16, 0xd300, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe6,0x00,0x8b,0x24,0x2e,0x5c } }, -{ 16, 0xd310, 0, {0x08,0x8d,0x02,0xff,0x48,0xb9,0x90,0x2f,0x54,0x0b,0x84,0x82,0x3e,0x40,0xa0,0x80 } }, -{ 16, 0xd320, 0, {0x2e,0xc4,0x0a,0xfc,0x42,0xed,0x80,0xb9,0x80,0x2e,0x60,0x0a,0x98,0x12,0xe0,0x04 } }, -{ 16, 0xd330, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe4,0x01,0xa3,0x00,0x28,0x48 } }, -{ 16, 0xd340, 0, {0x0a,0x00,0x42,0xc4,0x00,0xb1,0x00,0x2c,0x49,0x0b,0x0a,0x42,0x04,0xa2,0x91,0x21 } }, -{ 16, 0xd350, 0, {0x2c,0xc9,0x08,0x31,0x02,0x8c,0xc1,0xa3,0x00,0x2c,0x40,0x08,0x18,0x02,0xa2,0x01 } }, -{ 16, 0xd360, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa0,0x20,0x8b,0x82,0x2e,0x44 } }, -{ 16, 0xd370, 0, {0x58,0x80,0x02,0xe4,0x00,0xbb,0x10,0x2e,0x40,0x0b,0xa1,0x12,0x0c,0x01,0x89,0x10 } }, -{ 16, 0xd380, 0, {0x2e,0xc0,0x0a,0xb0,0x02,0xec,0x01,0xb8,0x80,0x2e,0xe2,0x0a,0xa1,0x02,0xf0,0x04 } }, -{ 16, 0xd390, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xeb,0x40,0xeb,0x40,0x3e,0x60 } }, -{ 16, 0xd3a0, 0, {0x0e,0x87,0x33,0xe4,0x00,0xb9,0xa1,0x36,0xc0,0x0e,0xa8,0x0b,0x26,0x00,0xda,0xc0 } }, -{ 16, 0xd3b0, 0, {0x3e,0xc0,0x8d,0xb0,0x03,0xec,0x00,0xfb,0x85,0x3e,0xe1,0x08,0xb8,0x03,0x90,0x05 } }, -{ 16, 0xd3c0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x00,0xff,0x02,0x2f,0x60 } }, -{ 16, 0xd3d0, 0, {0x03,0xe8,0x83,0xfc,0x10,0xfd,0x80,0x1f,0x40,0x1f,0xd0,0x13,0xbe,0x40,0xee,0x04 } }, -{ 16, 0xd3e0, 0, {0x3f,0xc0,0x0f,0xf0,0x43,0xfc,0x08,0xfd,0x00,0x3c,0xc0,0x0f,0xd0,0x11,0xf8,0x00 } }, -{ 16, 0xd3f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa4,0x00,0xdb,0x00,0xb2,0x40 } }, -{ 16, 0xd400, 0, {0x0e,0x94,0x03,0x24,0x00,0xd9,0x00,0xba,0xc0,0x0c,0x20,0x03,0xe4,0x90,0xfb,0x00 } }, -{ 16, 0xd410, 0, {0x3a,0xc0,0x0c,0xb0,0x03,0xec,0x01,0xfa,0x00,0x3e,0xd0,0x2c,0x98,0x03,0x90,0x04 } }, -{ 16, 0xd420, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x03,0x00,0x8b,0x00,0x22,0x48 } }, -{ 16, 0xd430, 0, {0x08,0x84,0x22,0x2c,0x00,0xb9,0x00,0x22,0xc0,0x08,0xa0,0x02,0xed,0x00,0x8b,0xa0 } }, -{ 16, 0xd440, 0, {0x21,0xc0,0x08,0xf0,0x02,0xfc,0x00,0xb9,0x80,0x2e,0xc0,0x08,0xa0,0x02,0x32,0x00 } }, -{ 16, 0xd450, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x45,0x20,0x93,0x00,0x22,0xf8 } }, -{ 16, 0xd460, 0, {0x0b,0x30,0x0a,0x84,0x40,0xb2,0x00,0x20,0x40,0x08,0x10,0x02,0xc4,0x00,0x80,0x80 } }, -{ 16, 0xd470, 0, {0x28,0xc0,0x28,0x39,0x02,0x4c,0x00,0xb1,0x00,0x2c,0xc0,0x08,0x30,0x02,0xb8,0x00 } }, -{ 16, 0xd480, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x36,0x00,0x9f,0x80,0x21,0x60 } }, -{ 16, 0xd490, 0, {0x09,0x38,0x02,0x9e,0x00,0xb2,0xc0,0x20,0x60,0x48,0x48,0x12,0xd6,0xc6,0x86,0xd0 } }, -{ 16, 0xd4a0, 0, {0x21,0xe0,0x08,0x78,0x00,0xde,0x80,0xb7,0x82,0x2d,0xe0,0x08,0xf8,0x02,0x08,0x00 } }, -{ 16, 0xd4b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x20,0xd3,0x10,0x30,0xc8 } }, -{ 16, 0xd4c0, 0, {0x0f,0x30,0x03,0x84,0x00,0xf1,0x00,0x30,0x40,0x24,0x19,0x03,0xe4,0xc0,0xe0,0x40 } }, -{ 16, 0xd4d0, 0, {0x3a,0xc0,0x0c,0x32,0x03,0xce,0x80,0xb1,0x28,0x3c,0xc0,0x0c,0x30,0x13,0x92,0x02 } }, -{ 16, 0xd4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0x9c,0x00,0xe6,0x00,0x7f,0xc0 } }, -{ 16, 0xd4f0, 0, {0x0e,0xf0,0x23,0x74,0x40,0xff,0x10,0x3f,0x40,0x4f,0xd0,0x03,0xfc,0xd2,0xce,0x04 } }, -{ 16, 0xd500, 0, {0x3f,0xc0,0x0f,0xf4,0x03,0xfc,0x00,0xfe,0x00,0x3f,0xc0,0x0f,0x71,0x03,0xd0,0x12 } }, -{ 16, 0xd510, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xee,0x00,0xcb,0x00,0x16,0xc0 } }, -{ 16, 0xd520, 0, {0x0d,0x80,0x03,0x27,0x20,0xcb,0x00,0x3e,0xc2,0x0a,0xb0,0x53,0xe4,0x28,0xc1,0x81 } }, -{ 16, 0xd530, 0, {0x32,0xc1,0x0e,0xb9,0x03,0x2c,0x00,0xf1,0x80,0x35,0xe0,0x0c,0xb8,0x03,0x2a,0x04 } }, -{ 16, 0xd540, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x02,0x87,0x10,0x2d,0x40 } }, -{ 16, 0xd550, 0, {0x08,0x70,0x03,0x5c,0x00,0xa7,0x00,0x2d,0x40,0x28,0x70,0x02,0xd4,0x04,0x87,0x04 } }, -{ 16, 0xd560, 0, {0xa1,0xd0,0x0b,0x72,0x02,0x1d,0x00,0xf7,0x00,0x21,0xc0,0x0d,0x50,0x02,0x12,0x04 } }, -{ 16, 0xd570, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0x85,0x80,0x25,0xe0 } }, -{ 16, 0xd580, 0, {0x09,0x78,0x02,0x37,0x03,0x87,0x80,0x2f,0xe0,0x08,0x78,0x12,0xc6,0x10,0x8d,0x80 } }, -{ 16, 0xd590, 0, {0x25,0xe8,0x0b,0x38,0x02,0x1e,0x80,0xbc,0x84,0x25,0xe0,0x08,0x58,0x02,0x70,0x00 } }, -{ 16, 0xd5a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcd,0x80,0x83,0x88,0x2c,0xc0 } }, -{ 16, 0xd5b0, 0, {0x08,0x3c,0x02,0x4e,0x01,0xa3,0xd2,0x2e,0xc4,0x08,0xb1,0x02,0xcc,0x00,0x83,0x80 } }, -{ 16, 0xd5c0, 0, {0x24,0xc1,0x0b,0x30,0x02,0x0c,0x00,0xb3,0x40,0xa0,0xd2,0x09,0x30,0x12,0x52,0x00 } }, -{ 16, 0xd5d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x00,0xca,0xc0,0x36,0x80 } }, -{ 16, 0xd5e0, 0, {0x0d,0x67,0x13,0x28,0x00,0xce,0x00,0x3e,0xa0,0x0c,0xed,0x03,0xe8,0x00,0xce,0xe0 } }, -{ 16, 0xd5f0, 0, {0x36,0x80,0x1e,0xa0,0x0b,0x28,0x04,0xfe,0x00,0xb7,0xb2,0x0c,0xe0,0x0b,0x7a,0x00 } }, -{ 16, 0xd600, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x40,0xf8,0x10,0x2e,0x10 } }, -{ 16, 0xd610, 0, {0x0f,0x80,0x03,0xe0,0x01,0xd8,0x0a,0x3e,0x00,0x0f,0x80,0x03,0xc0,0x02,0xf8,0x08 } }, -{ 16, 0xd620, 0, {0x3a,0x00,0x0f,0x80,0x03,0xe0,0x10,0xe8,0x20,0xbe,0x00,0x0f,0x80,0x13,0x92,0x00 } }, -{ 16, 0xd630, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe5,0x00,0xfb,0x00,0x3e,0x40 } }, -{ 16, 0xd640, 0, {0x0c,0x91,0x03,0x26,0x00,0x61,0x80,0x32,0x40,0x0c,0x90,0x03,0x24,0x00,0xc9,0x00 } }, -{ 16, 0xd650, 0, {0x1e,0x40,0x0c,0x9c,0x03,0xe4,0x01,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xc2,0x00 } }, -{ 16, 0xd660, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x67,0x00,0xb9,0x00,0x2c,0x40 } }, -{ 16, 0xd670, 0, {0x00,0x9c,0x02,0xa6,0x00,0x79,0x00,0x22,0x40,0x28,0x90,0x02,0x24,0x00,0x89,0x00 } }, -{ 16, 0xd680, 0, {0x2c,0x44,0x08,0x98,0x02,0xe4,0x00,0xb9,0x80,0x2e,0x40,0x0b,0x90,0x02,0xe0,0x01 } }, -{ 16, 0xd690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xbb,0x00,0x26,0x50 } }, -{ 16, 0xd6a0, 0, {0x28,0x90,0x82,0x24,0x84,0x99,0x20,0x22,0x40,0x49,0x90,0x02,0x24,0x00,0x89,0x00 } }, -{ 16, 0xd6b0, 0, {0x2e,0x40,0x08,0x90,0x02,0xe4,0x00,0xb9,0x60,0x2e,0x40,0x0b,0x90,0x02,0xc6,0x04 } }, -{ 16, 0xd6c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x06,0x00,0xb1,0x00,0x2e,0x48 } }, -{ 16, 0xd6d0, 0, {0x08,0x12,0x02,0x84,0x80,0xb1,0x20,0xa0,0x48,0x09,0x12,0x0a,0x04,0x80,0x81,0x00 } }, -{ 16, 0xd6e0, 0, {0x2c,0x48,0x28,0x12,0x42,0xc4,0x88,0x31,0x00,0x2c,0x40,0x0b,0x18,0x02,0xc2,0x01 } }, -{ 16, 0xd6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x50,0x36,0x14 } }, -{ 16, 0xd700, 0, {0x0c,0x80,0x03,0x20,0x00,0xe8,0x00,0x32,0x14,0x0c,0x85,0x03,0x21,0x40,0xc8,0x50 } }, -{ 16, 0xd710, 0, {0x3e,0x14,0x0c,0x80,0x03,0xe1,0x40,0x38,0x00,0x3e,0x00,0x8f,0x80,0x03,0xee,0x03 } }, -{ 16, 0xd720, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xd4,0x00,0xfb,0x04,0x3d,0x44 } }, -{ 16, 0xd730, 0, {0x0f,0x51,0x23,0xd4,0x48,0xed,0x10,0x3d,0x44,0x4e,0xd1,0x23,0xf4,0x42,0xfd,0x00 } }, -{ 16, 0xd740, 0, {0x3e,0x44,0x8f,0x91,0x03,0xe4,0x58,0xfd,0x00,0x3f,0x50,0x0f,0x50,0x03,0xe6,0x06 } }, -{ 16, 0xd750, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf4,0x00,0xf9,0x00,0x3d,0x40 } }, -{ 16, 0xd760, 0, {0x0c,0xd0,0x03,0xf4,0x00,0xdd,0x02,0x3e,0x40,0x0c,0x90,0x03,0xe4,0x40,0xc9,0x10 } }, -{ 16, 0xd770, 0, {0x37,0x40,0x07,0xd0,0x07,0x24,0x00,0xe5,0x00,0x2f,0x6a,0x0f,0x70,0x03,0x06,0x00 } }, -{ 16, 0xd780, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0xb8,0x00,0x3a,0x00 } }, -{ 16, 0xd790, 0, {0x80,0x80,0x02,0xe0,0x00,0x88,0x00,0x2e,0x00,0x0a,0x80,0x53,0xa2,0x80,0x2c,0xa0 } }, -{ 16, 0xd7a0, 0, {0x22,0x00,0x0b,0x80,0x0a,0x20,0x00,0xb8,0x00,0x2e,0x10,0x09,0x80,0x03,0x0e,0x04 } }, -{ 16, 0xd7b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x6c,0x40 } }, -{ 16, 0xd7c0, 0, {0x2a,0x10,0x02,0x84,0x01,0x81,0x80,0x2e,0x40,0x09,0x10,0x02,0xf4,0x00,0x8d,0x04 } }, -{ 16, 0xd7d0, 0, {0x20,0x40,0x0b,0x10,0x02,0x84,0x00,0xb1,0x00,0x2c,0x40,0x0b,0x98,0x02,0x42,0x01 } }, -{ 16, 0xd7e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x20,0xb9,0x00,0x2a,0x40 } }, -{ 16, 0xd7f0, 0, {0x88,0xb4,0x02,0xe6,0x01,0xa9,0x20,0x2e,0x48,0x0a,0x90,0x00,0xa4,0x40,0xad,0x40 } }, -{ 16, 0xd800, 0, {0x22,0x40,0x0b,0x90,0x12,0xa4,0x04,0xb9,0x01,0x2e,0x41,0x0b,0x90,0x02,0x06,0x04 } }, -{ 16, 0xd810, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0xc0,0x3e,0x60 } }, -{ 16, 0xd820, 0, {0x0c,0x94,0x13,0xa6,0x02,0xd9,0x42,0x1c,0x60,0x0c,0x9e,0x01,0xc6,0x04,0xc1,0x00 } }, -{ 16, 0xd830, 0, {0xb2,0x40,0x1f,0x90,0x02,0xa4,0x00,0xe9,0x08,0x3e,0x68,0x4f,0x98,0x0b,0x68,0x04 } }, -{ 16, 0xd840, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa6,0x40,0xf9,0x20,0x38,0x70 } }, -{ 16, 0xd850, 0, {0x0f,0x91,0x03,0xe4,0x00,0xd9,0x80,0x3e,0x40,0x0f,0x9c,0x13,0xa4,0x00,0xf9,0x00 } }, -{ 16, 0xd860, 0, {0x3e,0x40,0x0f,0x10,0x03,0x64,0x10,0xf9,0x0a,0x3e,0x50,0x0d,0x9a,0x03,0xca,0x00 } }, -{ 16, 0xd870, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xd8,0x04,0x3e,0x00 } }, -{ 16, 0xd880, 0, {0x0c,0x81,0x13,0xc0,0x02,0xd8,0x20,0x3e,0x00,0x2d,0x84,0x03,0xe0,0x00,0xcc,0x08 } }, -{ 16, 0xd890, 0, {0x3a,0x00,0x0f,0x80,0x43,0xe0,0x00,0xf8,0x41,0x32,0x00,0x07,0x81,0x8b,0x0a,0x04 } }, -{ 16, 0xd8a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x3a,0x60,0x8a,0x00,0x2f,0xa8 } }, -{ 16, 0xd8b0, 0, {0x0a,0xe0,0x22,0xe8,0x02,0x7e,0x48,0x2e,0x80,0x08,0xa0,0x42,0xe8,0x04,0x8e,0x00 } }, -{ 16, 0xd8c0, 0, {0x23,0xa8,0x0b,0xa8,0x82,0xe8,0x00,0xee,0x00,0xa2,0x80,0x4b,0x60,0x02,0x0a,0x00 } }, -{ 16, 0xd8d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x00,0x6c,0xc0 } }, -{ 16, 0xd8e0, 0, {0x08,0x30,0x02,0xcc,0x00,0x13,0x81,0x2c,0xc0,0x08,0x30,0x02,0xce,0x40,0x82,0x40 } }, -{ 16, 0xd8f0, 0, {0x28,0xe0,0x0b,0x38,0x02,0xcc,0x00,0xb3,0x10,0x24,0xc0,0x8b,0x38,0x02,0x0a,0x00 } }, -{ 16, 0xd900, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x00,0x87,0x20,0x2f,0xc0 } }, -{ 16, 0xd910, 0, {0x0a,0x70,0x02,0xdc,0x0a,0xb6,0x00,0x2c,0xc8,0x88,0x72,0x06,0xd8,0x00,0x86,0x00 } }, -{ 16, 0xd920, 0, {0x21,0xc0,0x0b,0x70,0x02,0xdc,0x84,0xaf,0x80,0xa5,0xc0,0x0b,0xd0,0x02,0x28,0x00 } }, -{ 16, 0xd930, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xd7,0x80,0x3d,0xa0 } }, -{ 16, 0xd940, 0, {0x1c,0x78,0x13,0xd6,0x02,0xd7,0x80,0x3d,0xec,0x08,0x7e,0x23,0xfe,0x00,0xce,0x80 } }, -{ 16, 0xd950, 0, {0x39,0x60,0x0f,0x78,0x03,0xdf,0x00,0xf6,0x80,0x75,0xe0,0x0f,0x78,0x03,0x2a,0x02 } }, -{ 16, 0xd960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0x8c,0x00,0xfb,0x10,0x3e,0x80 } }, -{ 16, 0xd970, 0, {0x1f,0xa0,0x21,0xcc,0x00,0xfa,0x00,0x3e,0xc0,0x0e,0xb0,0x03,0xe8,0x02,0xfa,0x00 } }, -{ 16, 0xd980, 0, {0x3e,0x40,0x0f,0xb0,0x13,0xec,0x00,0xea,0x01,0x3a,0xc0,0x0f,0x90,0x03,0xc2,0x06 } }, -{ 16, 0xd990, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfc,0x00,0xff,0x80,0x3f,0x60 } }, -{ 16, 0xd9a0, 0, {0x08,0x99,0x07,0x7e,0x00,0xdd,0x80,0x3f,0xe2,0x0c,0xf8,0x03,0xf6,0x02,0xdf,0x80 } }, -{ 16, 0xd9b0, 0, {0xb3,0xe0,0x0c,0xf8,0x03,0x3e,0x41,0xcc,0x80,0x33,0xe4,0x0f,0xf8,0x03,0xc0,0x00 } }, -{ 16, 0xd9c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x40,0xb7,0x00,0x2d,0xc0 } }, -{ 16, 0xd9d0, 0, {0x0d,0x5a,0x22,0xdc,0x80,0x75,0x00,0x2d,0xc0,0x08,0x71,0x02,0xf0,0x20,0x87,0x00 } }, -{ 16, 0xd9e0, 0, {0x21,0xc0,0x0a,0x70,0x02,0x1c,0x00,0xd4,0x28,0x21,0xc0,0x0b,0x72,0x02,0xea,0x04 } }, -{ 16, 0xd9f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x40,0xb7,0x00,0x2d,0x00 } }, -{ 16, 0xda00, 0, {0x08,0x72,0x22,0xf4,0x00,0x87,0x00,0x2d,0xc2,0x08,0x70,0x02,0xd4,0x00,0x87,0x80 } }, -{ 16, 0xda10, 0, {0x25,0x40,0x09,0x30,0x02,0x5c,0x01,0xad,0x00,0x29,0xd0,0x4b,0x70,0x02,0xc0,0x00 } }, -{ 16, 0xda20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0xbb,0xc8,0x2c,0xa0 } }, -{ 16, 0xda30, 0, {0x09,0x20,0x02,0xce,0x00,0xa3,0x00,0x2c,0xe0,0xa8,0x3d,0x42,0xc2,0x00,0x8b,0x80 } }, -{ 16, 0xda40, 0, {0x24,0x40,0x0b,0x30,0x0a,0x6c,0x08,0xa3,0x40,0xa8,0xe0,0x0b,0x34,0x02,0xc8,0x04 } }, -{ 16, 0xda50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xad,0x00,0xff,0x48,0x3c,0x28 } }, -{ 16, 0xda60, 0, {0x0c,0xa9,0x23,0x6c,0x80,0x8b,0x00,0x3f,0xc0,0x0c,0xfc,0x03,0xec,0x00,0xd8,0x80 } }, -{ 16, 0xda70, 0, {0x34,0x40,0x0d,0x30,0x03,0x7c,0x02,0xa3,0x40,0x38,0x68,0x0f,0x24,0x03,0xea,0x04 } }, -{ 16, 0xda80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xed,0x88,0xfb,0x00,0x3e,0x50 } }, -{ 16, 0xda90, 0, {0x0f,0xa1,0x03,0xec,0x04,0x3a,0xc0,0x3e,0xc0,0x0f,0xb0,0x83,0xe8,0x02,0xf8,0x10 } }, -{ 16, 0xdaa0, 0, {0x3a,0x41,0x0e,0x90,0x03,0xac,0x00,0x9b,0x08,0xb6,0x40,0x0f,0x81,0x03,0xe0,0x00 } }, -{ 16, 0xdab0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0xb3,0x20 } }, -{ 16, 0xdac0, 0, {0x0c,0x50,0x13,0x1c,0x09,0xcd,0x83,0x33,0xc0,0x83,0x70,0x00,0x3c,0x00,0xdc,0x10 } }, -{ 16, 0xdad0, 0, {0x32,0x60,0x0e,0xf1,0x43,0x2c,0x00,0xce,0x04,0x3b,0x70,0x0c,0xf0,0x83,0x00,0x44 } }, -{ 16, 0xdae0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x67,0x80,0xbb,0x01,0x62,0x21 } }, -{ 16, 0xdaf0, 0, {0x8a,0x89,0x20,0x2c,0x00,0x80,0xe0,0x22,0xc0,0x0b,0xb0,0x03,0xd8,0x10,0x8c,0x04 } }, -{ 16, 0xdb00, 0, {0x22,0x40,0x05,0x90,0x02,0xac,0x00,0xd8,0x80,0x36,0x40,0x0a,0x90,0x02,0x20,0x40 } }, -{ 16, 0xdb10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x26,0x00,0xbb,0x00,0x22,0x06 } }, -{ 16, 0xdb20, 0, {0x08,0x80,0x02,0x2e,0x00,0x88,0x20,0x22,0xc0,0x09,0xb0,0x02,0xa4,0x00,0x99,0x00 } }, -{ 16, 0xdb30, 0, {0x62,0xc4,0x08,0xb0,0x06,0x2c,0x00,0x88,0x80,0x22,0x41,0x08,0xa0,0x02,0x20,0x00 } }, -{ 16, 0xdb40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xb3,0x00,0x20,0x40 } }, -{ 16, 0xdb50, 0, {0x0a,0x00,0x82,0x0c,0x00,0x80,0x00,0x20,0xc0,0x0b,0x30,0x22,0xa0,0x00,0x81,0x00 } }, -{ 16, 0xdb60, 0, {0xa0,0xc0,0x09,0x30,0x02,0x8c,0x00,0x90,0x00,0x24,0x40,0x0a,0x28,0x02,0x02,0x01 } }, -{ 16, 0xdb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xfb,0x02,0x20,0x00 } }, -{ 16, 0xdb80, 0, {0x2c,0x92,0x03,0x2c,0x02,0x88,0x00,0x31,0xc0,0x0b,0xb5,0x02,0xa4,0x00,0xd1,0x04 } }, -{ 16, 0xdb90, 0, {0x32,0x40,0x0e,0x90,0x03,0x2c,0x40,0xc9,0x00,0x3a,0x40,0x8c,0xa0,0x03,0x00,0x03 } }, -{ 16, 0xdba0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf4,0x00,0xff,0x00,0x2f,0x00 } }, -{ 16, 0xdbb0, 0, {0x0f,0xc0,0x03,0xdc,0x00,0xfc,0x00,0x3f,0xc1,0x0f,0xf0,0x43,0xf0,0x00,0xfd,0x00 } }, -{ 16, 0xdbc0, 0, {0x3f,0x40,0x4f,0xd0,0x03,0xfc,0x00,0xf5,0x00,0x3f,0x40,0x0f,0xe0,0x03,0xe8,0x06 } }, -{ 16, 0xdbd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd8,0x80,0xcc,0x00,0xb7,0x04 } }, -{ 16, 0xdbe0, 0, {0x4e,0xe1,0x03,0x3c,0x20,0xdf,0x10,0x31,0x80,0x06,0xf0,0x03,0x7f,0x00,0xff,0xc0 } }, -{ 16, 0xdbf0, 0, {0x3b,0xc0,0x0e,0xf2,0x03,0x5e,0x00,0xef,0x10,0x33,0xd0,0x2c,0xf2,0x03,0x30,0x00 } }, -{ 16, 0xdc00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0xe9,0x00,0x88,0xc6,0x20,0x5c } }, -{ 16, 0xdc10, 0, {0x08,0xa4,0x57,0x65,0x00,0x8f,0x52,0x2a,0xf0,0x09,0xfc,0x02,0x04,0x00,0xbb,0x00 } }, -{ 16, 0xdc20, 0, {0x2d,0xd9,0x09,0x74,0x83,0x64,0x28,0x83,0x44,0x22,0x84,0x88,0x06,0x82,0x30,0x04 } }, -{ 16, 0xdc30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xc9,0x00,0x80,0x10,0x20,0x08 } }, -{ 16, 0xdc40, 0, {0x08,0x31,0x12,0x04,0xb2,0xa3,0x00,0x20,0x84,0x1b,0x34,0x02,0x0c,0x80,0xb3,0x20 } }, -{ 16, 0xdc50, 0, {0x2c,0xc7,0x09,0x36,0x02,0x8c,0x80,0x93,0x40,0xac,0xc8,0x08,0x31,0x28,0x32,0x01 } }, -{ 16, 0xdc60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa9,0x00,0x88,0x00,0xa2,0x50 } }, -{ 16, 0xdc70, 0, {0x08,0x35,0x02,0x24,0x00,0x8b,0x04,0x2e,0xc1,0x09,0xb0,0x02,0x24,0x94,0xbb,0x00 } }, -{ 16, 0xdc80, 0, {0x2e,0xc0,0x0b,0xb0,0x02,0xcc,0x60,0x8b,0x00,0x2e,0x80,0x08,0x80,0x00,0x30,0x04 } }, -{ 16, 0xdc90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xe7,0x02,0xcb,0x18,0xb2,0x80 } }, -{ 16, 0xdca0, 0, {0x2c,0xac,0x0a,0x2e,0x08,0xeb,0x00,0x32,0x12,0x4e,0xb0,0x03,0x2b,0x80,0xfb,0x00 } }, -{ 16, 0xdcb0, 0, {0x3a,0xc0,0x0a,0xb0,0x03,0xab,0x08,0xeb,0x04,0x2e,0x48,0x0c,0xb8,0x83,0x00,0x04 } }, -{ 16, 0xdcc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb6,0x80,0xff,0x80,0x39,0xca } }, -{ 16, 0xdcd0, 0, {0x0d,0xe8,0x03,0xd6,0x40,0xe7,0x04,0x3b,0x66,0x4e,0x70,0x03,0xb8,0x00,0xff,0x01 } }, -{ 16, 0xdce0, 0, {0x3f,0xc0,0x6c,0xf0,0x03,0x70,0x06,0xe7,0x00,0x31,0x04,0x0f,0xc1,0x43,0xf8,0x00 } }, -{ 16, 0xdcf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x85,0x00,0xcb,0x40,0x32,0x90 } }, -{ 16, 0xdd00, 0, {0x2f,0xb0,0x0b,0x64,0x80,0xfb,0x08,0xba,0x10,0x0d,0xb0,0xa7,0x2d,0x00,0xfb,0x04 } }, -{ 16, 0xdd10, 0, {0x3e,0xc0,0x8e,0xb0,0x03,0x6d,0x00,0xdb,0x01,0x32,0x40,0x8c,0x33,0x03,0x90,0x04 } }, -{ 16, 0xdd20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0x24,0x00,0x83,0xe0,0xa2,0xd0 } }, -{ 16, 0xdd30, 0, {0x40,0xb0,0x02,0x25,0x04,0xbf,0x80,0xa0,0x50,0x08,0xf8,0x02,0x20,0x00,0x8b,0x02 } }, -{ 16, 0xdd40, 0, {0x2f,0xd0,0x08,0xf0,0x02,0x24,0x00,0x8f,0x80,0x36,0x01,0x08,0x84,0x42,0x36,0x00 } }, -{ 16, 0xdd50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x44,0x00,0x83,0x48,0x20,0xc4 } }, -{ 16, 0xdd60, 0, {0x09,0x00,0x02,0x46,0x00,0xb3,0x01,0xa8,0x90,0x19,0x30,0x12,0x8c,0x00,0xa3,0x04 } }, -{ 16, 0xdd70, 0, {0x2e,0xe2,0x0a,0xb0,0x02,0x0c,0x00,0x83,0x49,0x28,0xc0,0x09,0x3c,0x02,0x38,0x00 } }, -{ 16, 0xdd80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x01,0x36,0x04,0x83,0x80,0x21,0xe1 } }, -{ 16, 0xdd90, 0, {0x08,0x38,0x12,0x1e,0x28,0xb3,0x98,0x21,0xa0,0x19,0x38,0x82,0x96,0x00,0x87,0x83 } }, -{ 16, 0xdda0, 0, {0x2d,0xe2,0x08,0x78,0x22,0x36,0x8c,0x87,0x80,0x2d,0xe0,0x09,0x79,0x02,0x3e,0x00 } }, -{ 16, 0xddb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x04,0x00,0xc3,0x30,0x30,0xc8 } }, -{ 16, 0xddc0, 0, {0x4d,0x00,0x0b,0x4c,0x80,0xf3,0x12,0x38,0xc0,0x0d,0x3a,0x02,0x8c,0x80,0xf3,0x00 } }, -{ 16, 0xddd0, 0, {0x3c,0xc0,0x0e,0x30,0x0b,0x0e,0x00,0xc3,0x0c,0x3a,0xc0,0x0d,0x30,0x03,0x12,0x02 } }, -{ 16, 0xdde0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb4,0x06,0xff,0x10,0x3f,0xc0 } }, -{ 16, 0xddf0, 0, {0x0f,0xb0,0x13,0xbc,0x00,0xff,0x10,0x7f,0xc0,0x0e,0xf1,0xa3,0x7c,0x00,0xff,0x12 } }, -{ 16, 0xde00, 0, {0x3f,0xc2,0x0f,0xf5,0x23,0xbc,0x41,0xef,0x18,0x37,0x80,0xae,0xc0,0x03,0x50,0x06 } }, -{ 16, 0xde10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xdb,0x00,0x3e,0xda } }, -{ 16, 0xde20, 0, {0x0c,0x80,0x03,0x66,0x10,0x8b,0x00,0x32,0x80,0x8c,0xb6,0x03,0x4a,0x00,0x4b,0x80 } }, -{ 16, 0xde30, 0, {0x32,0xc8,0x0c,0xb4,0x03,0x0a,0x10,0xdb,0x00,0x3e,0xc1,0x0c,0xb0,0x43,0x2a,0x00 } }, -{ 16, 0xde40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x11,0xb4,0x00,0x87,0x04,0x2c,0xc0 } }, -{ 16, 0xde50, 0, {0x0d,0x70,0x03,0x1c,0x08,0x87,0x48,0x20,0x81,0x0d,0x72,0x82,0x5c,0x00,0xd7,0x00 } }, -{ 16, 0xde60, 0, {0x21,0xcc,0x28,0xf0,0x02,0x1c,0x10,0x87,0x20,0x2c,0x00,0x08,0x40,0x0a,0x32,0x04 } }, -{ 16, 0xde70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x96,0x00,0xb7,0x81,0x2d,0xe0 } }, -{ 16, 0xde80, 0, {0x08,0x48,0x02,0x0e,0x04,0x87,0x80,0x21,0xe0,0x08,0x78,0x02,0x3e,0x01,0x87,0x80 } }, -{ 16, 0xde90, 0, {0x21,0xe0,0x18,0x79,0x02,0x3a,0x01,0x97,0xa0,0x2d,0x60,0x08,0x38,0x02,0x20,0x00 } }, -{ 16, 0xdea0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xc6,0x00,0xa3,0xc6,0x2c,0xc0 } }, -{ 16, 0xdeb0, 0, {0x09,0x30,0x02,0x0c,0x01,0x83,0x00,0x20,0xe0,0x09,0x30,0x02,0x4e,0x00,0x93,0x00 } }, -{ 16, 0xdec0, 0, {0x20,0xc0,0x49,0x30,0x22,0x0f,0x64,0x83,0x02,0x6c,0xd4,0x28,0x30,0x02,0x12,0x04 } }, -{ 16, 0xded0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x11,0xab,0x80,0xfa,0xe0,0x3c,0x88 } }, -{ 16, 0xdee0, 0, {0x0c,0xe0,0x02,0x28,0x02,0xca,0x00,0xb3,0xa9,0x0c,0xa0,0x03,0x3b,0x10,0xca,0x00 } }, -{ 16, 0xdef0, 0, {0xa2,0x80,0x0c,0xa0,0x0b,0x38,0x00,0xda,0x00,0x3f,0xb0,0x0c,0xe6,0x03,0x3a,0x04 } }, -{ 16, 0xdf00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xc0,0x20,0x98,0x08,0x3e,0x00 } }, -{ 16, 0xdf10, 0, {0x0f,0x80,0x0b,0xe1,0x00,0xf8,0x01,0x3c,0x10,0x4f,0x00,0x03,0xa0,0x40,0xf8,0x00 } }, -{ 16, 0xdf20, 0, {0x3e,0x10,0x0e,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3c,0x02,0x2f,0x04,0x93,0xd2,0x00 } }, -{ 16, 0xdf30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc1,0xc1,0x32,0x40 } }, -{ 16, 0xdf40, 0, {0x0c,0x98,0x03,0x26,0x40,0xf9,0x00,0x32,0x40,0x0c,0x98,0x03,0x24,0x24,0xf9,0x00 } }, -{ 16, 0xdf50, 0, {0x3c,0x60,0x0c,0x10,0x03,0xa4,0x00,0xf9,0x82,0x32,0x40,0x0c,0x90,0x03,0x02,0x04 } }, -{ 16, 0xdf60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x50 } }, -{ 16, 0xdf70, 0, {0x0d,0x98,0x02,0x25,0x80,0xb9,0x00,0x22,0x52,0x0d,0x9c,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xdf80, 0, {0x2e,0x60,0x08,0x90,0x42,0x24,0x00,0xb9,0x40,0x36,0x40,0x08,0x90,0x0a,0x20,0x00 } }, -{ 16, 0xdf90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x8d,0x00,0x23,0x40 } }, -{ 16, 0xdfa0, 0, {0x08,0x12,0x02,0x24,0x00,0xa1,0x10,0xa2,0x60,0x08,0x92,0x8a,0x24,0x00,0xb9,0x01 } }, -{ 16, 0xdfb0, 0, {0x2e,0x46,0x08,0x90,0x02,0xa4,0x00,0xb1,0x50,0x22,0x40,0x28,0x90,0x82,0x06,0x00 } }, -{ 16, 0xdfc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x84,0x85,0x20,0xa1,0xd8 } }, -{ 16, 0xdfd0, 0, {0x09,0x10,0x02,0x04,0x80,0xb3,0x20,0x20,0x40,0x29,0x12,0x06,0x04,0x00,0xb1,0x01 } }, -{ 16, 0xdfe0, 0, {0x2c,0x48,0x28,0x12,0x02,0x04,0x00,0xb1,0x20,0x24,0x48,0x08,0x12,0x02,0x02,0x01 } }, -{ 16, 0xdff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x42,0x8a,0x00,0xb3,0x00 } }, -{ 16, 0xe000, 0, {0x0c,0x05,0x03,0x21,0x40,0xe0,0x50,0xb2,0x00,0x2c,0x80,0x02,0x21,0x40,0xf0,0x50 } }, -{ 16, 0xe010, 0, {0x3c,0x14,0x0c,0x85,0x13,0xa1,0x50,0xf8,0x50,0x32,0x14,0x0c,0x85,0x23,0x2e,0x03 } }, -{ 16, 0xe020, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xf9,0x10,0x3e,0x44 } }, -{ 16, 0xe030, 0, {0x0f,0xd4,0x0b,0xf4,0x44,0xf9,0x10,0x3f,0x50,0x4f,0x11,0x03,0xf4,0x00,0xf9,0x00 } }, -{ 16, 0xe040, 0, {0x3e,0x44,0x0f,0x91,0x53,0xf4,0x14,0xf9,0x10,0x3f,0x44,0x0f,0xd1,0x03,0xe6,0x02 } }, -{ 16, 0xe050, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x05,0xe6,0xa0,0xdd,0x88,0xb3,0x66 } }, -{ 16, 0xe060, 0, {0x0c,0xdc,0x83,0x36,0x88,0xbd,0xa0,0x37,0x6a,0x0c,0xda,0x0b,0x25,0x02,0xc9,0x40 } }, -{ 16, 0xe070, 0, {0x3f,0x78,0x4f,0x98,0xb3,0xe5,0x04,0xcd,0xa0,0x72,0x78,0x0c,0xd8,0x8b,0x26,0x14 } }, -{ 16, 0xe080, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe3,0x00,0x88,0x42,0x22,0x31 } }, -{ 16, 0xe090, 0, {0x08,0x0a,0x02,0x22,0xa0,0xb8,0xf9,0x22,0x10,0x0d,0x84,0x12,0x6a,0x80,0x88,0x80 } }, -{ 16, 0xe0a0, 0, {0x2e,0x20,0x0b,0x08,0x02,0xe2,0x80,0xa8,0xa8,0xa2,0x38,0x48,0xa8,0x02,0x0e,0x00 } }, -{ 16, 0xe0b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0xa2,0x81,0x00,0x20,0x48 } }, -{ 16, 0xe0c0, 0, {0x08,0x12,0x42,0x45,0x00,0xb1,0x00,0x24,0x40,0x09,0x14,0x02,0x24,0x00,0x81,0x20 } }, -{ 16, 0xe0d0, 0, {0x2c,0x58,0x0b,0x10,0x82,0xc4,0x04,0x91,0x40,0x64,0x6c,0x08,0x30,0x82,0x12,0x05 } }, -{ 16, 0xe0e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0x89,0x00,0x22,0x41 } }, -{ 16, 0xe0f0, 0, {0x08,0x90,0x8a,0x64,0x80,0xb9,0x00,0x22,0x50,0x09,0x90,0x06,0x64,0x08,0x99,0x00 } }, -{ 16, 0xe100, 0, {0x2e,0x40,0x0b,0x90,0x06,0xc4,0x01,0xb9,0x02,0x26,0x61,0x88,0x90,0x02,0x06,0x04 } }, -{ 16, 0xe110, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x22,0x40 } }, -{ 16, 0xe120, 0, {0x2c,0x94,0x23,0x64,0x00,0xb9,0x00,0x36,0x40,0x09,0x90,0x13,0x05,0x00,0xc9,0x00 } }, -{ 16, 0xe130, 0, {0x3e,0x40,0x4f,0x90,0x13,0xe5,0xc0,0xd9,0x00,0x26,0x40,0x2c,0x94,0x03,0x28,0x00 } }, -{ 16, 0xe140, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x01,0xa4,0x02,0xe9,0x08,0x3c,0x40 } }, -{ 16, 0xe150, 0, {0x0f,0x90,0x0b,0xa4,0x00,0xf1,0x00,0x3e,0x41,0x0f,0x90,0x43,0xa4,0x88,0xe9,0x04 } }, -{ 16, 0xe160, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe6,0x00,0xe1,0x00,0x3a,0x40,0x9f,0x92,0x63,0xda,0x00 } }, -{ 16, 0xe170, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x80,0x10,0xe0,0x01,0x32,0x00 } }, -{ 16, 0xe180, 0, {0x8f,0x80,0x03,0x20,0x00,0xd8,0x08,0x30,0x01,0x8c,0x00,0x03,0xe1,0x02,0xc8,0x04 } }, -{ 16, 0xe190, 0, {0x3e,0x00,0x0c,0x80,0x0b,0x21,0x00,0xc8,0x00,0x78,0x00,0x0f,0x86,0x03,0x0a,0x00 } }, -{ 16, 0xe1a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8e,0x40,0x2b,0x82 } }, -{ 16, 0xe1b0, 0, {0x0b,0xa0,0x02,0x3a,0x00,0x8e,0x80,0x23,0x82,0x08,0xe2,0x02,0x28,0x10,0x8a,0x00 } }, -{ 16, 0xe1c0, 0, {0x2f,0x98,0x28,0xa0,0x12,0x28,0x00,0x8e,0x20,0x2e,0x80,0x4b,0xe4,0x02,0x0a,0x00 } }, -{ 16, 0xe1d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x02,0xa2,0x40,0x20,0x80 } }, -{ 16, 0xe1e0, 0, {0x0b,0xb0,0x02,0x4e,0x40,0x93,0xc0,0xa0,0x20,0x08,0x36,0x02,0x8c,0x00,0x93,0x00 } }, -{ 16, 0xe1f0, 0, {0x2c,0xe2,0x08,0x30,0x06,0x4c,0x12,0x93,0x08,0x28,0xc0,0x0b,0xb0,0x02,0x0a,0x00 } }, -{ 16, 0xe200, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x08,0x82,0x40,0x29,0x40 } }, -{ 16, 0xe210, 0, {0x0b,0x70,0x02,0x5e,0x08,0x84,0x08,0x23,0x40,0x08,0x70,0x06,0x1c,0x80,0x87,0x00 } }, -{ 16, 0xe220, 0, {0x2d,0x20,0x08,0x79,0x12,0x5c,0x00,0x94,0x00,0x2d,0xc0,0x0b,0x30,0x42,0x28,0x00 } }, -{ 16, 0xe230, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x00,0xe4,0x80,0x31,0xa1 } }, -{ 16, 0xe240, 0, {0x0f,0x58,0x13,0x76,0x00,0xd0,0x80,0x31,0xc0,0x0c,0x38,0x03,0xbe,0x80,0xd7,0x81 } }, -{ 16, 0xe250, 0, {0x3f,0x20,0x8c,0x79,0x03,0x7f,0x01,0xd6,0x80,0x39,0xe8,0x4f,0x68,0x03,0x2a,0x00 } }, -{ 16, 0xe260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xbe,0x00,0xfa,0x00,0x3e,0x00 } }, -{ 16, 0xe270, 0, {0x8f,0x96,0x0b,0xa4,0x00,0xea,0x00,0x3c,0xc0,0x0f,0x90,0x03,0xac,0x20,0xfb,0x40 } }, -{ 16, 0xe280, 0, {0x2e,0x00,0x0f,0xb2,0x03,0xad,0xa0,0xea,0x00,0x3e,0xc0,0x0f,0xa0,0x1b,0xc2,0x04 } }, -{ 16, 0xe290, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x08,0xde,0x81,0x33,0xa4 } }, -{ 16, 0xe2a0, 0, {0x0e,0xfc,0x13,0x3e,0x00,0xfc,0x80,0x13,0x20,0x0c,0x68,0x03,0x3e,0x20,0xff,0xc8 } }, -{ 16, 0xe2b0, 0, {0x3f,0x60,0x1d,0xf8,0x03,0x7e,0x00,0xc7,0x80,0x33,0xe2,0x0c,0xd8,0x03,0x10,0x00 } }, -{ 16, 0xe2c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0x86,0x41,0x31,0xc4 } }, -{ 16, 0xe2d0, 0, {0x08,0x79,0x42,0x9c,0x00,0xbc,0x10,0x21,0x40,0x85,0x35,0x03,0x5c,0x00,0xb7,0x00 } }, -{ 16, 0xe2e0, 0, {0x2d,0xc0,0x08,0x72,0x02,0x2c,0x00,0xa7,0x01,0x37,0xc0,0x08,0x51,0x42,0x2a,0x00 } }, -{ 16, 0xe2f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x8c,0x40,0x82,0x00,0x24,0x81 } }, -{ 16, 0xe300, 0, {0x08,0xd8,0x02,0x14,0x20,0xb5,0x00,0x20,0x40,0x09,0x60,0x02,0x1c,0x40,0xb7,0x00 } }, -{ 16, 0xe310, 0, {0x2c,0x40,0x0b,0x30,0x22,0xdc,0x00,0x97,0x00,0x21,0xc4,0x08,0x40,0x02,0x44,0x00 } }, -{ 16, 0xe320, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xec,0x00,0x92,0x06,0x20,0x90 } }, -{ 16, 0xe330, 0, {0x38,0x15,0x02,0x86,0x00,0xb8,0x00,0x60,0x50,0x09,0x30,0x02,0x4e,0x01,0xbb,0x00 } }, -{ 16, 0xe340, 0, {0x2e,0x40,0x0b,0x30,0x02,0xce,0x20,0xb3,0x00,0x24,0xf0,0x48,0x02,0x0a,0x58,0x04 } }, -{ 16, 0xe350, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xca,0x00,0xa6,0x94 } }, -{ 16, 0xe360, 0, {0x2c,0x90,0x03,0x2e,0x00,0xfb,0x05,0xb2,0x85,0x0d,0x90,0x03,0x3f,0x90,0xff,0x00 } }, -{ 16, 0xe370, 0, {0x7e,0x80,0x1f,0xf0,0x43,0xfc,0x21,0x9a,0x00,0x33,0xc8,0x3c,0xb2,0x03,0x6a,0x04 } }, -{ 16, 0xe380, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0xec,0x02,0xea,0x40,0x3d,0x80 } }, -{ 16, 0xe390, 0, {0x0f,0x10,0x93,0xed,0x00,0xfb,0x40,0x3e,0x90,0x8f,0x30,0x03,0xec,0x80,0xfb,0x00 } }, -{ 16, 0xe3a0, 0, {0x3e,0x91,0x1c,0xb0,0x03,0x2c,0x10,0xe8,0x00,0x3e,0xc8,0x1f,0x90,0x03,0xa5,0x10 } }, -{ 16, 0xe3b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xfc,0x02,0xe4,0x00,0x73,0xa0 } }, -{ 16, 0xe3c0, 0, {0x0c,0xfc,0x03,0x7c,0x02,0xff,0x10,0x13,0xc4,0x1c,0xc0,0x03,0x3c,0x00,0xff,0x00 } }, -{ 16, 0xe3d0, 0, {0x37,0xe0,0x0d,0xf0,0x03,0xfc,0x00,0xed,0x80,0x31,0xc0,0x0c,0x32,0x63,0x20,0x04 } }, -{ 16, 0xe3e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x6c,0x00,0x8a,0xc0,0x22,0xb1 } }, -{ 16, 0xe3f0, 0, {0x8a,0xb8,0x43,0x4a,0x10,0xdb,0x20,0x20,0xf0,0x0a,0x94,0x03,0x6c,0x00,0xbb,0x07 } }, -{ 16, 0xe400, 0, {0x22,0xb8,0x08,0xb0,0x02,0xec,0x11,0xe8,0xc0,0xb2,0xc0,0x2a,0x92,0x1a,0x20,0x00 } }, -{ 16, 0xe410, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x2c,0x00,0xaa,0x80,0x22,0x98 } }, -{ 16, 0xe420, 0, {0x08,0x90,0x02,0x2f,0x03,0xbb,0x01,0x2a,0x83,0x08,0xb2,0x4e,0x2c,0x04,0xab,0x02 } }, -{ 16, 0xe430, 0, {0x22,0xc4,0x28,0xb0,0x22,0xec,0x09,0xb3,0x50,0x62,0xc0,0x08,0xb0,0x02,0x20,0x00 } }, -{ 16, 0xe440, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x01,0x83,0x00,0x60,0x80 } }, -{ 16, 0xe450, 0, {0x08,0x12,0x0a,0x44,0x00,0x93,0x00,0x2a,0x80,0x4a,0x30,0x02,0x0c,0x00,0xb3,0x00 } }, -{ 16, 0xe460, 0, {0x60,0xc0,0x08,0x30,0x02,0xcc,0x00,0xb3,0x02,0x60,0xc0,0x08,0x00,0x46,0x02,0x01 } }, -{ 16, 0xe470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0d,0x6c,0x00,0xe8,0x02,0x22,0x80 } }, -{ 16, 0xe480, 0, {0x2c,0xf2,0x43,0x2c,0x00,0xfb,0x00,0xba,0xc0,0x08,0xa5,0x02,0x3c,0x00,0xef,0x00 } }, -{ 16, 0xe490, 0, {0x36,0xc0,0x4d,0xf0,0x13,0xfd,0x51,0xfb,0x00,0x32,0xc0,0x0c,0xb0,0x03,0x20,0x01 } }, -{ 16, 0xe4a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0x7e,0x04,0x3f,0x80 } }, -{ 16, 0xe4b0, 0, {0x0f,0x31,0x43,0xf0,0x02,0xff,0x00,0x37,0xc0,0x0f,0xf0,0x03,0xfc,0x08,0xff,0x00 } }, -{ 16, 0xe4c0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xef,0x00,0x3b,0xc0,0x0f,0xc0,0x03,0xe8,0x16 } }, -{ 16, 0xe4d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf2,0x40,0xfc,0x80,0x3f,0x24 } }, -{ 16, 0xe4e0, 0, {0x0d,0xd8,0x53,0xd6,0x04,0xdf,0x32,0x3f,0xcc,0x4c,0xc0,0x43,0xfc,0x00,0xdf,0x60 } }, -{ 16, 0xe4f0, 0, {0x37,0xc0,0x0f,0xc4,0x03,0x7c,0xd0,0xdf,0x20,0x33,0xd8,0x0d,0xf8,0x43,0xf0,0x00 } }, -{ 16, 0xe500, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x18,0xe8,0x80,0xb0,0x01,0x2e,0x08 } }, -{ 16, 0xe510, 0, {0x88,0x90,0x02,0xec,0x20,0x8b,0x70,0x2f,0xcc,0x08,0xb3,0x82,0xfd,0xe0,0xbf,0x40 } }, -{ 16, 0xe520, 0, {0x22,0xd8,0x0b,0x93,0x02,0xfd,0xc0,0xaf,0x10,0x28,0xf0,0x08,0xbc,0x12,0xf0,0x04 } }, -{ 16, 0xe530, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x00,0xb0,0x00,0x2e,0x01 } }, -{ 16, 0xe540, 0, {0x0a,0x12,0x82,0xec,0x80,0xb3,0x00,0x2c,0xc8,0x0a,0x00,0x32,0x8c,0x00,0xa3,0x30 } }, -{ 16, 0xe550, 0, {0x20,0xd2,0x09,0x00,0x02,0x8c,0x80,0x83,0x00,0x28,0xd8,0x0b,0x34,0x12,0xf2,0x01 } }, -{ 16, 0xe560, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xac,0x01,0xb8,0x02,0x2e,0x00 } }, -{ 16, 0xe570, 0, {0x0a,0x90,0x12,0xec,0x10,0x8b,0x00,0x2e,0xc0,0x0a,0xb0,0x00,0xec,0x00,0xb3,0x00 } }, -{ 16, 0xe580, 0, {0x22,0xc1,0x0b,0x92,0x02,0xcc,0x01,0xab,0x00,0x2a,0xc0,0x02,0xb0,0x02,0xf0,0x04 } }, -{ 16, 0xe590, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe0,0x00,0xfa,0x0c,0x3e,0xc0 } }, -{ 16, 0xe5a0, 0, {0x0f,0xa0,0x13,0xee,0x20,0xdb,0x00,0x3e,0xc0,0x2e,0x88,0x53,0xec,0x00,0xfb,0x00 } }, -{ 16, 0xe5b0, 0, {0xb2,0xc0,0x8f,0xac,0x83,0xac,0x08,0xdb,0x00,0x1a,0xc0,0x4f,0xb0,0x03,0xc0,0x04 } }, -{ 16, 0xe5c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x00,0xfe,0x00,0x3f,0xc0 } }, -{ 16, 0xe5d0, 0, {0x2d,0xe0,0x03,0xfe,0x80,0x7f,0x00,0x3f,0xc0,0x0d,0xd2,0x03,0xfc,0x00,0xbf,0x01 } }, -{ 16, 0xe5e0, 0, {0x3e,0xc0,0x0d,0xc8,0x03,0xfc,0x0c,0xff,0x00,0x3f,0xc0,0x09,0xf0,0x23,0xf8,0x00 } }, -{ 16, 0xe5f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa4,0x00,0xfa,0x40,0x32,0xc1 } }, -{ 16, 0xe600, 0, {0x0f,0xa0,0x03,0x29,0x08,0xdb,0x00,0x3e,0xc0,0x0e,0x85,0x03,0xec,0x20,0xcb,0x00 } }, -{ 16, 0xe610, 0, {0x3a,0xc0,0x0e,0xa4,0x03,0xec,0x00,0xfb,0x00,0x3a,0xc2,0x0e,0xb0,0x03,0x10,0x04 } }, -{ 16, 0xe620, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xba,0x60,0x20,0xc0 } }, -{ 16, 0xe630, 0, {0x0b,0xa0,0x02,0x08,0x00,0xaf,0x00,0x2f,0xd0,0x0b,0xb5,0x02,0xfe,0x02,0x8f,0x00 } }, -{ 16, 0xe640, 0, {0x2f,0xc0,0x0d,0x80,0x0a,0x3c,0x00,0xb7,0x00,0x23,0xc2,0x05,0xf0,0x22,0x36,0x00 } }, -{ 16, 0xe650, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x04,0x40,0x00,0xb1,0x88,0x20,0x00 } }, -{ 16, 0xe660, 0, {0x0b,0x10,0x02,0x0c,0x00,0x83,0x00,0x2e,0xc8,0x0b,0x08,0x06,0x4d,0x40,0x83,0x00 } }, -{ 16, 0xe670, 0, {0x20,0xc0,0x08,0x30,0x06,0x0c,0x08,0x93,0x20,0x0a,0xe0,0x4a,0x30,0x02,0x38,0x00 } }, -{ 16, 0xe680, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x5a,0x00,0xb5,0x90,0x21,0x20 } }, -{ 16, 0xe690, 0, {0x0b,0x58,0x42,0x3e,0x00,0xa7,0x80,0x2d,0xe0,0x0b,0x69,0x02,0xde,0x40,0x87,0x92 } }, -{ 16, 0xe6a0, 0, {0x2d,0xe0,0x09,0x18,0x02,0x9e,0x01,0xb7,0x80,0x29,0xe0,0x03,0x70,0x02,0x3e,0x00 } }, -{ 16, 0xe6b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x44,0x00,0xf1,0x01,0x30,0x00 } }, -{ 16, 0xe6c0, 0, {0x5f,0x18,0x03,0x0c,0x10,0x83,0x00,0x3c,0xc4,0x0e,0x04,0x03,0xec,0x00,0x83,0x00 } }, -{ 16, 0xe6d0, 0, {0x30,0xc4,0x0c,0x31,0x03,0x8c,0x00,0xf3,0x00,0x38,0xc8,0x0e,0x31,0x03,0x12,0x02 } }, -{ 16, 0xe6e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xbc,0x00,0xfd,0x04,0xbf,0x04 } }, -{ 16, 0xe6f0, 0, {0x4f,0x58,0x03,0xf8,0x08,0xef,0x08,0x3f,0xc0,0x0f,0xf0,0x01,0xfc,0x00,0xff,0x4c } }, -{ 16, 0xe700, 0, {0x3f,0xc1,0x0f,0xd0,0x03,0x3c,0x00,0xf7,0x00,0x37,0xc2,0x0d,0x72,0x03,0xd0,0x06 } }, -{ 16, 0xe710, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xe2,0x00,0xdb,0x00,0x32,0xc0 } }, -{ 16, 0xe720, 0, {0x4d,0xa8,0x03,0x2c,0x08,0xfb,0x00,0x7e,0xc8,0x8f,0xb0,0x0b,0x6f,0x45,0xeb,0xc2 } }, -{ 16, 0xe730, 0, {0x36,0xc0,0x07,0xa0,0x03,0xef,0x20,0xcb,0x50,0xb2,0xc0,0x0c,0x79,0x03,0x2a,0x00 } }, -{ 16, 0xe740, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x19,0x98,0x00,0x8f,0x00,0x21,0xc0 } }, -{ 16, 0xe750, 0, {0x0b,0x60,0x03,0x5c,0x00,0x37,0x00,0x2d,0xd2,0x0b,0x30,0x02,0x0c,0xa8,0x87,0x24 } }, -{ 16, 0xe760, 0, {0x21,0xd0,0x09,0x70,0x02,0xdd,0x88,0x87,0x2a,0x23,0xe8,0x08,0x70,0x02,0x32,0x04 } }, -{ 16, 0xe770, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xb6,0x00,0x97,0x80,0x21,0xe0 } }, -{ 16, 0xe780, 0, {0x0b,0x68,0x02,0x1e,0x00,0xb7,0x80,0x2d,0xe8,0x8b,0x48,0x82,0x1e,0x80,0xa3,0x84 } }, -{ 16, 0xe790, 0, {0x25,0xe8,0x0b,0x68,0x02,0xce,0x02,0x87,0x80,0x21,0xe0,0x08,0x7a,0x02,0x20,0x00 } }, -{ 16, 0xe7a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x04,0xcc,0x08,0x83,0x82,0x20,0xe0 } }, -{ 16, 0xe7b0, 0, {0x8b,0x2a,0x02,0x48,0x40,0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x82,0x0c,0x00,0x83,0x00 } }, -{ 16, 0xe7c0, 0, {0x00,0xc1,0x09,0x31,0x02,0xcc,0x00,0x83,0x00,0x20,0xc0,0x08,0x30,0x0a,0x12,0x04 } }, -{ 16, 0xe7d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xe8,0x00,0xda,0xa0,0x32,0xa8 } }, -{ 16, 0xe7e0, 0, {0x8d,0xa8,0x03,0x3b,0x00,0xfa,0x00,0x3e,0x80,0x0f,0xe4,0x03,0x68,0x00,0xea,0x02 } }, -{ 16, 0xe7f0, 0, {0x36,0x80,0x0f,0xe4,0x03,0xe8,0x00,0xca,0x00,0x32,0x80,0x2c,0xa0,0x03,0x3a,0x04 } }, -{ 16, 0xe800, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x01,0xa0,0x10,0xf8,0x00,0xbe,0x20 } }, -{ 16, 0xe810, 0, {0x8f,0xc1,0x03,0xe0,0x24,0xf8,0x00,0x3e,0x10,0x0f,0x84,0x03,0xe0,0x00,0xf8,0x01 } }, -{ 16, 0xe820, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x01,0xbe,0x10,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xe830, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xf9,0x40,0x32,0x40 } }, -{ 16, 0xe840, 0, {0xcf,0x90,0x03,0xe4,0x00,0xc9,0x00,0x0e,0x50,0x0f,0x1a,0x03,0x26,0x00,0xf9,0x00 } }, -{ 16, 0xe850, 0, {0x3e,0x40,0x0f,0x90,0x81,0xe4,0x00,0xf9,0x80,0x32,0x40,0x0c,0x90,0x03,0xc2,0x04 } }, -{ 16, 0xe860, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x04,0xb1,0x04,0x22,0x40 } }, -{ 16, 0xe870, 0, {0x0b,0x90,0x02,0xe4,0x00,0xa9,0x00,0x2e,0x53,0x0b,0x92,0x0a,0x26,0x48,0xb9,0x04 } }, -{ 16, 0xe880, 0, {0x2e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x80,0x02,0x50,0x08,0x90,0x02,0xe0,0x00 } }, -{ 16, 0xe890, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x05,0x24,0x00,0xbd,0x00,0x23,0x40 } }, -{ 16, 0xe8a0, 0, {0x0b,0xd0,0x12,0xc4,0x00,0x89,0x02,0x2e,0x40,0x0b,0x90,0x22,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xe8b0, 0, {0x2e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb1,0x20,0x20,0x40,0x68,0x90,0x22,0xc6,0x00 } }, -{ 16, 0xe8c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x14,0x14,0x00,0xbf,0x12,0xa1,0x40 } }, -{ 16, 0xe8d0, 0, {0x0b,0x50,0x02,0xc4,0x00,0xa1,0x20,0x2c,0x48,0x0b,0x12,0x02,0x04,0x10,0xb1,0x11 } }, -{ 16, 0xe8e0, 0, {0x2c,0x48,0x0b,0x13,0x22,0xc4,0x00,0xb1,0x40,0x20,0x5a,0x08,0x10,0x02,0xc2,0x01 } }, -{ 16, 0xe8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x40,0x32,0x14 } }, -{ 16, 0xe900, 0, {0x0f,0x45,0x03,0xe1,0x40,0xc8,0x50,0x3e,0x15,0x8f,0x85,0x03,0x21,0xe8,0xf8,0x68 } }, -{ 16, 0xe910, 0, {0x3e,0x14,0x0f,0x84,0x03,0xe1,0xe0,0xf0,0x28,0x32,0xa8,0xcc,0x80,0x23,0xee,0x03 } }, -{ 16, 0xe920, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x15,0xc4,0x10,0xf9,0x20,0x3e,0x40 } }, -{ 16, 0xe930, 0, {0x0f,0x90,0x03,0xf4,0x00,0xf9,0x10,0x3e,0x44,0x0f,0xd1,0x03,0xe4,0x00,0xf9,0x20 } }, -{ 16, 0xe940, 0, {0x3e,0x44,0x0f,0xd3,0x03,0xe4,0x00,0xf9,0x00,0xbe,0x40,0x0f,0x94,0x03,0xe6,0x06 } }, -{ 16, 0xe950, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xe4,0x00,0xfd,0x10,0x33,0x40 } }, -{ 16, 0xe960, 0, {0x0c,0xd0,0x03,0x24,0x00,0xd9,0x00,0x3f,0x40,0x4c,0xd0,0x03,0xf6,0x00,0xfd,0x90 } }, -{ 16, 0xe970, 0, {0x3a,0x40,0x0c,0x90,0x03,0xe6,0xa0,0xfd,0xa8,0x37,0x68,0x0c,0xd8,0x83,0x26,0x00 } }, -{ 16, 0xe980, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x08,0xc8,0xa0,0x22,0x00 } }, -{ 16, 0xe990, 0, {0x08,0x80,0x02,0x20,0x00,0x88,0x00,0x2e,0x00,0x0c,0x80,0x12,0xe0,0x00,0xb8,0x80 } }, -{ 16, 0xe9a0, 0, {0x22,0x00,0x0d,0x0a,0x02,0xe3,0x80,0xb0,0xc0,0x20,0x34,0x08,0x84,0x03,0x4e,0x04 } }, -{ 16, 0xe9b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x09,0xa1,0x00,0x20,0x41 } }, -{ 16, 0xe9c0, 0, {0x08,0x90,0x02,0x24,0x00,0x91,0x00,0x2c,0x40,0x08,0x10,0x02,0xc5,0x00,0xb1,0x60 } }, -{ 16, 0xe9d0, 0, {0x20,0x40,0x08,0x10,0xa2,0xc4,0x20,0xb1,0x28,0x24,0x4a,0x08,0x10,0x02,0x52,0x01 } }, -{ 16, 0xe9e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x14,0xa4,0x01,0x81,0x00,0xa2,0x40 } }, -{ 16, 0xe9f0, 0, {0xa8,0x90,0x00,0x25,0x40,0x89,0x01,0x2c,0x40,0x08,0x94,0x02,0xe4,0x00,0xb9,0x00 } }, -{ 16, 0xea00, 0, {0x2a,0x40,0x09,0x90,0x02,0xe4,0x01,0xb9,0x04,0x22,0x41,0x48,0x90,0x02,0x46,0x04 } }, -{ 16, 0xea10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x14,0xa5,0x20,0xe9,0x00,0x32,0x40 } }, -{ 16, 0xea20, 0, {0x4c,0x10,0x0b,0x26,0x00,0xd9,0x00,0x3e,0x40,0x2c,0x98,0x03,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0xea30, 0, {0xb2,0x40,0x0c,0x90,0x03,0xe4,0x00,0xf9,0x00,0x36,0x40,0x2c,0x90,0x03,0x68,0x04 } }, -{ 16, 0xea40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x01,0xa4,0x00,0xe9,0x00,0x3e,0x40 } }, -{ 16, 0xea50, 0, {0x0f,0x90,0x03,0xe6,0x00,0xf9,0x00,0x3e,0x40,0x0e,0x9a,0x03,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0xea60, 0, {0x36,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3c,0x40,0x0f,0x90,0x03,0xda,0x00 } }, -{ 16, 0xea70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa1,0x00,0xf8,0x00,0x32,0x00 } }, -{ 16, 0xea80, 0, {0x0f,0x80,0x13,0xa0,0x00,0xc8,0x00,0x32,0x04,0x8c,0x80,0x03,0xa0,0xc0,0xf8,0x00 } }, -{ 16, 0xea90, 0, {0x3a,0x00,0x0f,0x80,0x03,0x20,0x00,0xc0,0x09,0x32,0x00,0x4c,0x80,0x01,0x0a,0x04 } }, -{ 16, 0xeaa0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xbe,0x00,0x20,0x80 } }, -{ 16, 0xeab0, 0, {0x0b,0xe0,0x02,0x88,0x00,0xaa,0x00,0x03,0xa0,0x0a,0xe6,0x02,0xfa,0x00,0x8a,0x00 } }, -{ 16, 0xeac0, 0, {0x32,0x80,0x0b,0xa0,0x02,0x28,0x00,0x8e,0x80,0xa3,0x80,0x28,0x20,0x02,0x8a,0x00 } }, -{ 16, 0xead0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x00,0xb3,0x48,0x20,0x40 } }, -{ 16, 0xeae0, 0, {0x0b,0x10,0x02,0x0c,0x00,0x83,0x00,0x20,0xc0,0x08,0x34,0x82,0x8e,0x04,0x99,0x00 } }, -{ 16, 0xeaf0, 0, {0x0a,0xc0,0x1b,0x30,0x02,0x0c,0x02,0x90,0x50,0x20,0x60,0x08,0x30,0x02,0x0a,0x00 } }, -{ 16, 0xeb00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x11,0x1c,0x80,0xbd,0x0a,0x21,0x48 } }, -{ 16, 0xeb10, 0, {0x0b,0x52,0x02,0x9c,0x40,0xa3,0xa0,0x20,0x80,0x0a,0x60,0x02,0xce,0x00,0x85,0x20 } }, -{ 16, 0xeb20, 0, {0x21,0xc4,0x0b,0x7a,0x06,0x1e,0x80,0x95,0x20,0x21,0x90,0x08,0x70,0x02,0x28,0x00 } }, -{ 16, 0xeb30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x08,0x1e,0x80,0xf7,0x80,0xb1,0x79 } }, -{ 16, 0xeb40, 0, {0x0f,0xdb,0x02,0x3e,0x20,0xc7,0xa0,0xb1,0x60,0xcc,0x78,0x13,0x96,0x00,0xf1,0xf0 } }, -{ 16, 0xeb50, 0, {0x39,0xe2,0x0f,0x7b,0x13,0x0f,0x00,0xd4,0xa0,0x31,0x60,0x2c,0x70,0x03,0x2a,0x02 } }, -{ 16, 0xeb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x15,0xac,0x00,0xf7,0x00,0x3e,0x40 } }, -{ 16, 0xeb70, 0, {0x0f,0x90,0x03,0xed,0x80,0xfb,0x10,0x3e,0x40,0x0b,0xb0,0x23,0xec,0x00,0xf9,0x20 } }, -{ 16, 0xeb80, 0, {0x3a,0xd8,0x0f,0xb0,0x0b,0xed,0x81,0xed,0x10,0x3e,0x80,0x0f,0x30,0x03,0xc2,0x06 } }, -{ 16, 0xeb90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xbe,0x20,0xee,0x80,0x33,0x60 } }, -{ 16, 0xeba0, 0, {0x0c,0xd8,0x83,0x1e,0x00,0x6f,0x80,0x33,0xe0,0x0f,0xb8,0x11,0x32,0x04,0xf5,0x80 } }, -{ 16, 0xebb0, 0, {0x33,0xe0,0x0f,0xf8,0x83,0x2f,0x40,0xfe,0x80,0xb3,0xe0,0x0c,0xf8,0x03,0x10,0x00 } }, -{ 16, 0xebc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x18,0x9c,0x00,0xbc,0x00,0xa1,0x44 } }, -{ 16, 0xebd0, 0, {0x08,0x10,0x03,0x5c,0x00,0x8f,0x00,0x21,0x80,0x0b,0xea,0x22,0x1c,0x80,0xb5,0x01 } }, -{ 16, 0xebe0, 0, {0x21,0xc0,0x0b,0xf0,0x02,0x1e,0x80,0xbe,0x00,0x23,0x80,0x2a,0x70,0x02,0x2a,0x04 } }, -{ 16, 0xebf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x20,0xa7,0x00,0x23,0x40 } }, -{ 16, 0xec00, 0, {0x0b,0x50,0x0a,0x3c,0x00,0xa7,0x00,0x25,0xc0,0x0a,0x43,0x02,0x10,0x00,0xb5,0x00 } }, -{ 16, 0xec10, 0, {0x21,0xc0,0x0b,0x70,0x82,0x1c,0x80,0xb4,0x00,0x21,0xc0,0x08,0x70,0x02,0x04,0x00 } }, -{ 16, 0xec20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x04,0x8e,0x04,0xb3,0x00,0x22,0x40 } }, -{ 16, 0xec30, 0, {0x09,0x14,0x02,0x4c,0x00,0x83,0x00,0x20,0xc0,0x0b,0x24,0x82,0x04,0x00,0xb1,0x00 } }, -{ 16, 0xec40, 0, {0x20,0xc0,0x8b,0x3a,0x02,0x2c,0x01,0xb0,0x00,0x20,0x80,0x0a,0x30,0x02,0x1a,0x04 } }, -{ 16, 0xec50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x9e,0x00,0xeb,0x04,0x33,0x40 } }, -{ 16, 0xec60, 0, {0x2d,0xdc,0x03,0x1d,0x60,0xef,0x00,0x32,0x00,0xcf,0x9a,0x03,0x28,0x00,0xfd,0x00 } }, -{ 16, 0xec70, 0, {0x33,0xc1,0x8b,0xfc,0x0b,0x3c,0x00,0xfc,0x00,0x32,0x80,0x0c,0x90,0x03,0x2a,0x04 } }, -{ 16, 0xec80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xac,0x10,0xf8,0x00,0x3e,0x40 } }, -{ 16, 0xec90, 0, {0x0e,0x98,0x23,0xac,0x04,0xfb,0x00,0x3c,0x00,0x0f,0x84,0x20,0xed,0x00,0xf9,0x00 } }, -{ 16, 0xeca0, 0, {0x3e,0xc0,0x4f,0xb0,0x03,0xec,0x00,0xfd,0x00,0x3e,0x80,0x0f,0x90,0x03,0xe4,0x00 } }, -{ 16, 0xecb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x10,0xfc,0x00,0xcf,0x80,0x33,0x40 } }, -{ 16, 0xecc0, 0, {0x0c,0xd0,0x83,0xfc,0x00,0xef,0x00,0x3f,0x40,0x0c,0xf1,0x41,0x30,0x10,0xcd,0x00 } }, -{ 16, 0xecd0, 0, {0x3f,0xc0,0x00,0x70,0x13,0x3c,0x00,0xe4,0x00,0xb1,0xd0,0x0c,0x10,0x03,0x20,0x04 } }, -{ 16, 0xece0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0x04,0x2c,0x00,0x8a,0xe4,0x2a,0x40 } }, -{ 16, 0xecf0, 0, {0x28,0x90,0x02,0xec,0x00,0x8b,0x00,0x3e,0x02,0x0a,0x80,0x02,0x2c,0x82,0x89,0x04 } }, -{ 16, 0xed00, 0, {0x2e,0xc1,0x0a,0xb0,0x0a,0x2c,0x00,0x89,0x02,0x22,0xf2,0x2a,0x98,0x02,0x20,0x00 } }, -{ 16, 0xed10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x02,0x80,0x14,0x2a,0x40 } }, -{ 16, 0xed20, 0, {0x08,0x90,0x02,0xec,0x08,0xab,0x04,0x2e,0x84,0x08,0x10,0x82,0x80,0x10,0x89,0x03 } }, -{ 16, 0xed30, 0, {0x2c,0xc0,0x4a,0xb0,0x22,0x2c,0x00,0xaa,0x00,0x22,0x80,0x08,0x91,0x02,0x20,0x00 } }, -{ 16, 0xed40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x2c,0x00,0x80,0x00,0x28,0x40 } }, -{ 16, 0xed50, 0, {0x08,0x11,0x02,0xec,0x00,0x83,0x00,0x2c,0x81,0x0a,0x00,0x5a,0x88,0x00,0x01,0x00 } }, -{ 16, 0xed60, 0, {0x2c,0xc0,0x0a,0x30,0x02,0x0c,0x00,0x82,0x00,0x20,0x80,0x0a,0x10,0x02,0x02,0x01 } }, -{ 16, 0xed70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xc9,0x00,0x3a,0x40 } }, -{ 16, 0xed80, 0, {0x0c,0xd4,0x03,0xfc,0x00,0xeb,0x00,0x3e,0x40,0x0c,0x92,0x03,0xa0,0x00,0x4d,0x00 } }, -{ 16, 0xed90, 0, {0x3f,0xc0,0x0e,0xf0,0x33,0x3c,0x80,0xe8,0x00,0x32,0xc0,0x0c,0x90,0x03,0x20,0x03 } }, -{ 16, 0xeda0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xfc,0x00,0xfc,0x00,0x3d,0x40 } }, -{ 16, 0xedb0, 0, {0x0f,0x50,0x03,0xfc,0x02,0x3f,0x04,0x3b,0x01,0x4f,0xc4,0x13,0x70,0x00,0xfd,0x00 } }, -{ 16, 0xedc0, 0, {0x3f,0xc0,0x1f,0xf0,0x01,0xfc,0x40,0xfc,0x00,0x3f,0xc0,0x0f,0xd0,0x13,0xe8,0x06 } }, -{ 16, 0xedd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf8,0xe0,0xff,0x80,0x3d,0xc0 } }, -{ 16, 0xede0, 0, {0x0d,0xf3,0x82,0xf0,0x80,0xff,0x40,0x31,0xcb,0x0c,0xf3,0x03,0xfd,0x04,0xef,0xc1 } }, -{ 16, 0xedf0, 0, {0x33,0xe0,0x0f,0x79,0x03,0xfe,0x00,0xcf,0x42,0x33,0xf0,0x4c,0xf8,0x03,0x30,0x00 } }, -{ 16, 0xee00, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0xe9,0x08,0xb9,0x81,0x2f,0xf0 } }, -{ 16, 0xee10, 0, {0x08,0xf4,0x52,0xe9,0x20,0xbf,0x40,0x23,0xf0,0x0a,0xf3,0x02,0xfd,0x08,0x8b,0x00 } }, -{ 16, 0xee20, 0, {0x36,0xe0,0x0b,0x80,0x22,0xe8,0x80,0x8f,0x40,0x22,0xc0,0x08,0xb0,0x82,0x30,0x04 } }, -{ 16, 0xee30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xcc,0x00,0xb1,0x80,0x2c,0xc5 } }, -{ 16, 0xee40, 0, {0x09,0x32,0x42,0xc8,0xc0,0xb3,0x31,0x20,0xc1,0x08,0x32,0x02,0xcc,0xd4,0xbb,0x20 } }, -{ 16, 0xee50, 0, {0x68,0xc0,0x0b,0x30,0x02,0xcc,0x20,0x93,0x60,0x20,0x88,0x08,0x32,0x02,0x32,0x01 } }, -{ 16, 0xee60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x15,0xa0,0x00,0xbb,0x80,0x2e,0xc0 } }, -{ 16, 0xee70, 0, {0x08,0xb0,0x02,0xea,0x00,0xbb,0x00,0x62,0xc1,0x0a,0xb0,0x02,0xcc,0x00,0xab,0x00 } }, -{ 16, 0xee80, 0, {0x2e,0xc0,0x0b,0xa0,0x00,0xe8,0x00,0x83,0x00,0x22,0xc1,0x08,0x30,0x02,0x30,0x04 } }, -{ 16, 0xee90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xe8,0x90,0xfb,0x80,0x3e,0xc0 } }, -{ 16, 0xeea0, 0, {0x0d,0xb0,0x03,0xe2,0x10,0xfb,0x00,0x32,0xc0,0x4c,0xb0,0x13,0xec,0x00,0xe9,0x54 } }, -{ 16, 0xeeb0, 0, {0x3a,0xc0,0x0f,0xb0,0x03,0xe6,0x00,0xcb,0x00,0xb2,0x40,0x0c,0xb0,0x03,0x04,0x04 } }, -{ 16, 0xeec0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb8,0x00,0xff,0x00,0x3f,0xc0 } }, -{ 16, 0xeed0, 0, {0x8f,0xf0,0x03,0xf0,0x00,0xf7,0x02,0xbf,0xc1,0x0f,0xf0,0x23,0xfc,0x00,0xdf,0x06 } }, -{ 16, 0xeee0, 0, {0x37,0xc0,0x8f,0xc9,0x07,0xfa,0x92,0xff,0x04,0x3f,0x50,0x2f,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0xeef0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x10,0xac,0x00,0xc9,0x00,0x3e,0xc2 } }, -{ 16, 0xef00, 0, {0x0e,0xb0,0x23,0xe4,0x00,0xeb,0x00,0x3a,0xc8,0x0e,0xb0,0x03,0xec,0x00,0xf9,0x00 } }, -{ 16, 0xef10, 0, {0x3e,0xc0,0x0f,0xb4,0x03,0xa4,0x00,0xfb,0x00,0x3e,0x80,0x0f,0xb0,0x83,0xd0,0x04 } }, -{ 16, 0xef20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x28,0x00,0x8b,0x74,0x2d,0xc0 } }, -{ 16, 0xef30, 0, {0x08,0xf0,0x02,0xe4,0x00,0x8f,0x00,0x21,0xf0,0x08,0xf0,0x02,0xfc,0x10,0xd3,0x00 } }, -{ 16, 0xef40, 0, {0x2e,0xc0,0x0b,0x90,0x12,0x2c,0x00,0xef,0x00,0x2e,0xc0,0x0b,0xb6,0x02,0xf6,0x00 } }, -{ 16, 0xef50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x48,0x00,0xa3,0x00,0x2c,0xc4 } }, -{ 16, 0xef60, 0, {0x0a,0x30,0x02,0xc0,0x00,0xa3,0x00,0x68,0xf0,0x0a,0x30,0x12,0xcc,0x04,0xa2,0x00 } }, -{ 16, 0xef70, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xec,0x00,0xb3,0x01,0x2e,0xc0,0x0b,0x34,0x02,0xf8,0x00 } }, -{ 16, 0xef80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x01,0x0c,0x00,0x87,0x80,0x2d,0xe8 } }, -{ 16, 0xef90, 0, {0x08,0x78,0x42,0xda,0x00,0x87,0x80,0x25,0xe0,0x08,0x79,0x02,0xce,0x00,0x96,0x80 } }, -{ 16, 0xefa0, 0, {0x2d,0xe0,0x0b,0xd9,0x02,0xde,0x00,0xa7,0x80,0x2d,0xe0,0x0b,0x78,0x02,0xfc,0x00 } }, -{ 16, 0xefb0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x40,0xe3,0x10,0x3c,0xc0 } }, -{ 16, 0xefc0, 0, {0x0a,0x38,0x03,0xe8,0x00,0xeb,0x00,0x38,0xc2,0x0a,0x30,0x03,0xcc,0x00,0xe3,0x40 } }, -{ 16, 0xefd0, 0, {0x3c,0xc0,0x0f,0x34,0x03,0xcd,0x00,0xf3,0x20,0x3c,0x88,0x0f,0x30,0x03,0xd2,0x02 } }, -{ 16, 0xefe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb4,0x80,0xff,0x04,0x3f,0xc8 } }, -{ 16, 0xeff0, 0, {0x0f,0xf0,0x83,0xf8,0x40,0xff,0x18,0x3b,0xc0,0x0f,0xf4,0x83,0xfc,0x00,0xee,0x02 } }, -{ 16, 0xf000, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0x3c,0x00,0xef,0x08,0x3f,0x80,0x0f,0xf0,0x13,0xd0,0x06 } }, -{ 16, 0xf010, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe8,0x00,0xcb,0x00,0x3e,0xf2 } }, -{ 16, 0xf020, 0, {0x4d,0xb2,0x13,0xe8,0x04,0xcb,0x01,0x32,0xf8,0x4d,0xb2,0x13,0x6d,0x20,0xf8,0x00 } }, -{ 16, 0xf030, 0, {0x3e,0xc0,0x0f,0x30,0x03,0x24,0x00,0xfb,0x00,0x3e,0x40,0x8f,0xb8,0x03,0x2a,0x00 } }, -{ 16, 0xf040, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x11,0x8c,0x00,0x86,0x00,0x2c,0xc0 } }, -{ 16, 0xf050, 0, {0x08,0x73,0x02,0xd8,0x12,0x87,0x30,0x20,0xcb,0x08,0xf2,0x02,0x1d,0x05,0xb5,0x00 } }, -{ 16, 0xf060, 0, {0x2d,0xc0,0x0b,0x60,0x03,0x50,0x10,0xb7,0x09,0x2d,0xc0,0x0b,0xf0,0x02,0x32,0x04 } }, -{ 16, 0xf070, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x00,0x87,0x80,0x2d,0xe4 } }, -{ 16, 0xf080, 0, {0x09,0x7a,0x02,0xce,0x01,0x87,0x80,0x21,0xec,0x09,0x78,0x02,0x5e,0x80,0xb7,0xc0 } }, -{ 16, 0xf090, 0, {0x2d,0xe0,0x0b,0xf8,0x02,0x1e,0x00,0xb7,0xa0,0x2d,0x60,0x0b,0x78,0x02,0x20,0x00 } }, -{ 16, 0xf0a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xee,0x00,0x82,0x80,0x2c,0xc0 } }, -{ 16, 0xf0b0, 0, {0x08,0x30,0x02,0xec,0x00,0x83,0x00,0xa0,0xc0,0x08,0x30,0x02,0x0c,0x00,0xb3,0x80 } }, -{ 16, 0xf0c0, 0, {0x2c,0xc1,0x0b,0x30,0x02,0x4e,0x00,0xb3,0x00,0x2c,0xf1,0x0b,0x30,0x0a,0x12,0x04 } }, -{ 16, 0xf0d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x80,0xc6,0x00,0x3e,0x80 } }, -{ 16, 0xf0e0, 0, {0x0d,0xa0,0x03,0xf8,0x40,0xca,0x00,0x32,0x80,0x0d,0xa0,0x13,0x68,0x00,0xfe,0x02 } }, -{ 16, 0xf0f0, 0, {0x7e,0x80,0x0f,0xed,0x83,0x39,0x10,0xfa,0x00,0x3f,0x8c,0x0f,0xa0,0x03,0x3a,0x04 } }, -{ 16, 0xf100, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x12,0xf8,0x90,0x3e,0x00 } }, -{ 16, 0xf110, 0, {0x0f,0x80,0x03,0xe0,0x00,0xf8,0x05,0x3e,0x00,0x0e,0x00,0x03,0xe0,0x00,0xf8,0x80 } }, -{ 16, 0xf120, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x60,0xf8,0x00,0x7e,0x00,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xf130, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc9,0x80,0x32,0x64 } }, -{ 16, 0xf140, 0, {0x0f,0x90,0x43,0xe4,0x06,0xc1,0x04,0x3a,0x40,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x00 } }, -{ 16, 0xf150, 0, {0x32,0x40,0x0f,0x90,0x03,0x24,0x00,0xc1,0x01,0x32,0x40,0x0c,0x90,0x03,0xc2,0x04 } }, -{ 16, 0xf160, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0xc0,0x22,0x40 } }, -{ 16, 0xf170, 0, {0x0b,0x90,0x02,0x24,0x00,0x89,0x00,0x22,0x50,0x1b,0x90,0x22,0x24,0x00,0x81,0x00 } }, -{ 16, 0xf180, 0, {0x22,0x40,0x0b,0x90,0x22,0x24,0x08,0xc9,0x00,0x20,0x40,0x08,0x94,0x02,0xe0,0x00 } }, -{ 16, 0xf190, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x99,0x20,0x22,0x40 } }, -{ 16, 0xf1a0, 0, {0x0b,0x10,0x02,0xa4,0x00,0x89,0x00,0x2a,0x58,0x0b,0x90,0x02,0x84,0x00,0xa9,0x00 } }, -{ 16, 0xf1b0, 0, {0x22,0x40,0x0b,0x10,0x0a,0x04,0x00,0x99,0x02,0x22,0xc1,0x08,0x90,0x82,0xc6,0x00 } }, -{ 16, 0xf1c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x91,0x02,0xa0,0xc8 } }, -{ 16, 0xf1d0, 0, {0x0b,0x12,0x02,0x04,0x80,0x81,0x22,0x20,0x48,0x9b,0x12,0x02,0x04,0x90,0x89,0x01 } }, -{ 16, 0xf1e0, 0, {0x20,0x40,0x0b,0x10,0x02,0x04,0x02,0x81,0x22,0x22,0x40,0x08,0x10,0x02,0xc2,0x01 } }, -{ 16, 0xf1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x42,0xda,0x01,0x32,0x01 } }, -{ 16, 0xf200, 0, {0x0f,0x85,0x03,0xa1,0x40,0xc0,0x50,0x3a,0x01,0x8b,0x85,0x23,0xa1,0x44,0xe8,0x50 } }, -{ 16, 0xf210, 0, {0xb2,0x00,0x0f,0x85,0x03,0x21,0x48,0xd8,0x51,0x32,0x14,0x2c,0x85,0x03,0xee,0x03 } }, -{ 16, 0xf220, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf5,0x00,0xed,0x02,0x3e,0x44 } }, -{ 16, 0xf230, 0, {0x0f,0x91,0x03,0xf4,0x40,0xf9,0x10,0x3e,0x44,0x0f,0x91,0x03,0xe4,0x40,0xfd,0x00 } }, -{ 16, 0xf240, 0, {0x3e,0x40,0x0f,0xd0,0x03,0xf4,0x00,0xe9,0x10,0xbf,0x40,0x0f,0x90,0x03,0x66,0x06 } }, -{ 16, 0xf250, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x21,0xc5,0x00,0x33,0x68 } }, -{ 16, 0xf260, 0, {0x0f,0x9a,0x03,0x6f,0x88,0xc9,0xc0,0x33,0x68,0x0c,0x9e,0x03,0x27,0x80,0xd9,0x40 } }, -{ 16, 0xf270, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc5,0x10,0xd9,0xe8,0x36,0x50,0x0c,0xd0,0x03,0xe6,0x00 } }, -{ 16, 0xf280, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x08,0x88,0x00,0x82,0x00 } }, -{ 16, 0xf290, 0, {0x0b,0x8e,0x82,0xeb,0xc8,0x88,0xe0,0x22,0x00,0x28,0x88,0x42,0xa2,0x80,0x8a,0x80 } }, -{ 16, 0xf2a0, 0, {0x22,0x00,0x0b,0xaa,0x02,0xe2,0x00,0x88,0xc0,0x22,0xa9,0x08,0x8a,0x03,0x8e,0x04 } }, -{ 16, 0xf2b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x00,0x81,0x00,0x20,0xd0 } }, -{ 16, 0xf2c0, 0, {0x0b,0x11,0x32,0x84,0x84,0x81,0x60,0x60,0x50,0x08,0x16,0x06,0x05,0x00,0x91,0x20 } }, -{ 16, 0xf2d0, 0, {0x20,0x40,0x0b,0x10,0x82,0xe4,0x09,0x91,0x20,0x24,0x40,0x08,0x10,0xc2,0xd2,0x01 } }, -{ 16, 0xf2e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x04,0x89,0x04,0x22,0x40 } }, -{ 16, 0xf2f0, 0, {0x0b,0x90,0x02,0xc4,0x00,0xa9,0x00,0x22,0x41,0x00,0x90,0x02,0xa4,0x00,0x81,0x00 } }, -{ 16, 0xf300, 0, {0x22,0x40,0x0b,0x92,0x22,0xe5,0x80,0x99,0x01,0x22,0x61,0x08,0x90,0x02,0x86,0x04 } }, -{ 16, 0xf310, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x14,0xa5,0x82,0x81,0x90,0x32,0x40 } }, -{ 16, 0xf320, 0, {0x0f,0x90,0x13,0x67,0x02,0xc9,0x00,0x32,0x40,0x0c,0x90,0x23,0x24,0x04,0xd9,0xc0 } }, -{ 16, 0xf330, 0, {0xb2,0x40,0x0f,0x9c,0x03,0xe6,0x00,0xd9,0x00,0x36,0x50,0x0c,0x90,0x03,0xe8,0x04 } }, -{ 16, 0xf340, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x00,0xa6,0x80,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0xf350, 0, {0x0f,0x90,0x03,0xe7,0x00,0xd9,0x00,0xbc,0x42,0x0f,0x90,0x53,0xe4,0x04,0xf9,0x10 } }, -{ 16, 0xf360, 0, {0x3e,0x40,0x0f,0x98,0x03,0xe6,0x04,0xe1,0x00,0x3e,0x40,0x2f,0x90,0x03,0xda,0x00 } }, -{ 16, 0xf370, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x81,0x10,0x48,0x10,0x32,0x08 } }, -{ 16, 0xf380, 0, {0x0c,0x80,0x0f,0x21,0x02,0xc8,0x00,0x3a,0x04,0x0f,0x80,0x07,0x60,0x00,0xf8,0x40 } }, -{ 16, 0xf390, 0, {0xb2,0x00,0x0f,0x84,0x0b,0x20,0x00,0xd8,0x00,0x36,0x10,0x0c,0x80,0x03,0xca,0x04 } }, -{ 16, 0xf3a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x04,0x28,0x04,0x8e,0x80,0x23,0x80 } }, -{ 16, 0xf3b0, 0, {0x08,0xa0,0x42,0x28,0x00,0x8a,0x00,0x23,0xa0,0x4b,0xa0,0x02,0xe8,0x00,0xba,0x00 } }, -{ 16, 0xf3c0, 0, {0x76,0x80,0x0b,0xa0,0x02,0x08,0x00,0x8a,0x00,0x32,0x80,0x08,0xe0,0x03,0xca,0x00 } }, -{ 16, 0xf3d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x82,0x00,0x20,0xd0 } }, -{ 16, 0xf3e0, 0, {0x08,0x30,0x02,0x0c,0x00,0x9b,0x00,0x28,0xc0,0x1a,0xb0,0x02,0x6c,0x00,0xb3,0x02 } }, -{ 16, 0xf3f0, 0, {0x20,0xc0,0x0b,0x30,0x02,0x0c,0x00,0xa3,0x00,0x22,0xc0,0x28,0x34,0x82,0xca,0x00 } }, -{ 16, 0xf400, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1c,0x00,0x87,0x00,0x20,0xe0 } }, -{ 16, 0xf410, 0, {0x08,0x78,0x02,0x0c,0x00,0x97,0x20,0x25,0xc0,0x0b,0x71,0x02,0xdc,0x81,0xb7,0x20 } }, -{ 16, 0xf420, 0, {0x21,0xc0,0x0b,0x7a,0x42,0x3c,0x80,0x87,0x20,0x21,0xc0,0x08,0x70,0x02,0xe8,0x00 } }, -{ 16, 0xf430, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x0e,0x82,0xc7,0x80,0xb1,0xe0 } }, -{ 16, 0xf440, 0, {0x2c,0xfa,0x06,0x1e,0x08,0xd3,0xb1,0x39,0x60,0x4e,0x78,0x12,0x5e,0xa0,0xff,0xf0 } }, -{ 16, 0xf450, 0, {0x21,0xe0,0x0f,0xf8,0x03,0x1f,0x08,0xe3,0xa0,0x33,0xe0,0x0c,0x68,0x03,0xea,0x02 } }, -{ 16, 0xf460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x40,0xfb,0x00,0x3e,0xc0 } }, -{ 16, 0xf470, 0, {0x0f,0xb2,0x03,0xed,0xa8,0xeb,0x10,0x3a,0x80,0x0f,0xb0,0xc3,0xec,0x40,0xfb,0x00 } }, -{ 16, 0xf480, 0, {0x3e,0xc0,0x0f,0xb0,0x83,0xec,0x80,0xeb,0x70,0xbe,0xc4,0x0f,0xb0,0x03,0x82,0x06 } }, -{ 16, 0xf490, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xce,0x80,0xb3,0x60 } }, -{ 16, 0xf4a0, 0, {0x0f,0xfc,0x83,0x7e,0x20,0xef,0xb0,0x3b,0xe0,0x0f,0xb8,0x03,0x3e,0x00,0xcf,0x81 } }, -{ 16, 0xf4b0, 0, {0x3f,0xe0,0x8f,0xf8,0x83,0xef,0x40,0xff,0xc2,0x33,0xe1,0x0c,0xf8,0x03,0xd0,0x00 } }, -{ 16, 0xf4c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x82,0x87,0x18,0x21,0x80 } }, -{ 16, 0xf4d0, 0, {0x0b,0x30,0x02,0x1c,0x60,0xd7,0x10,0x21,0xd0,0x0b,0x7b,0x02,0x3c,0x00,0xd7,0x00 } }, -{ 16, 0xf4e0, 0, {0x2d,0xc0,0x0b,0x70,0x02,0xde,0x00,0xbf,0x00,0xa3,0xc4,0x08,0x70,0x03,0xaa,0x04 } }, -{ 16, 0xf4f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0x11,0x87,0x00,0x21,0xc0 } }, -{ 16, 0xf500, 0, {0x0b,0x30,0x02,0x1c,0x00,0x93,0x20,0x69,0xc0,0x0b,0x70,0x02,0x1c,0x00,0x87,0x00 } }, -{ 16, 0xf510, 0, {0x2d,0xc0,0x0b,0x71,0x02,0xdc,0x20,0xb7,0x10,0x21,0xc0,0x08,0x60,0x02,0x84,0x00 } }, -{ 16, 0xf520, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xcd,0x00,0x83,0x40,0x20,0xc0 } }, -{ 16, 0xf530, 0, {0x4b,0x30,0x02,0x0c,0x01,0x83,0x00,0x20,0xc0,0x0b,0x30,0x02,0x0c,0x00,0x93,0x80 } }, -{ 16, 0xf540, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x01,0xb3,0x00,0x20,0xc0,0x08,0x30,0x22,0x98,0x04 } }, -{ 16, 0xf550, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbf,0x20,0xca,0xc0,0x32,0x80 } }, -{ 16, 0xf560, 0, {0x0f,0xf0,0x03,0x3e,0x00,0x9f,0x00,0x3a,0x80,0x0f,0xf0,0x0b,0x3c,0x00,0xcf,0x98 } }, -{ 16, 0xf570, 0, {0x3e,0xc0,0x0f,0xf6,0x03,0xff,0x00,0xff,0x00,0x31,0xe0,0x2c,0xb0,0x03,0xae,0x04 } }, -{ 16, 0xf580, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xcc,0x80,0xfb,0x00,0x3e,0x50 } }, -{ 16, 0xf590, 0, {0x0f,0xb0,0x03,0xac,0x02,0xfb,0x00,0x7e,0x50,0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00 } }, -{ 16, 0xf5a0, 0, {0x3e,0xc0,0x0f,0xb2,0x03,0xec,0x20,0xf3,0x00,0x3e,0xc6,0x0f,0x90,0x03,0xa0,0x00 } }, -{ 16, 0xf5b0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x02,0xcf,0x98,0x73,0xc8 } }, -{ 16, 0xf5c0, 0, {0x0f,0x70,0x03,0x3c,0x00,0xff,0x00,0x33,0x28,0x0f,0xb0,0x02,0x1c,0x00,0x4f,0x00 } }, -{ 16, 0xf5d0, 0, {0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x01,0x33,0xc0,0x0c,0xe4,0x03,0xe4,0x04 } }, -{ 16, 0xf5e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x6c,0x00,0x83,0x80,0xa2,0xf8 } }, -{ 16, 0xf5f0, 0, {0x0b,0xb0,0x42,0x2c,0x00,0xbb,0x00,0x32,0x10,0x0f,0xb0,0x03,0x6c,0x04,0xab,0x00 } }, -{ 16, 0xf600, 0, {0x2e,0xc0,0x0b,0xb0,0x12,0xec,0x04,0xeb,0x00,0x22,0xc0,0x4a,0x94,0x82,0xe0,0x00 } }, -{ 16, 0xf610, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x6c,0x00,0x8a,0x00,0x22,0x00 } }, -{ 16, 0xf620, 0, {0x0b,0xb0,0x02,0x2c,0x00,0xb3,0x00,0xa2,0xc0,0x0b,0x30,0x02,0xac,0x00,0xab,0x04 } }, -{ 16, 0xf630, 0, {0x2e,0xc0,0x0b,0xb0,0x42,0xec,0x00,0xbb,0x00,0x22,0xc0,0x08,0xb0,0x22,0xe0,0x00 } }, -{ 16, 0xf640, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0c,0x00,0x8b,0x01,0x20,0x00 } }, -{ 16, 0xf650, 0, {0x0b,0x30,0x06,0x0c,0x00,0xb3,0x00,0x20,0xc0,0x0a,0x32,0x0a,0xcc,0x00,0xa3,0x00 } }, -{ 16, 0xf660, 0, {0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x00,0xa3,0x00,0x22,0xc0,0x4a,0x00,0x12,0xc2,0x01 } }, -{ 16, 0xf670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x6c,0x00,0x8b,0x04,0x22,0xc0 } }, -{ 16, 0xf680, 0, {0x0f,0xf1,0x03,0x1c,0x00,0xff,0x04,0x32,0xc0,0x0b,0xf2,0x03,0xbc,0x00,0xef,0x00 } }, -{ 16, 0xf690, 0, {0x3e,0xc0,0x07,0xf0,0x03,0xfc,0x80,0xff,0x00,0xb2,0xc0,0x0c,0xa0,0x03,0xe0,0x03 } }, -{ 16, 0xf6a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xdc,0x00,0xf5,0x00,0x3f,0xc0 } }, -{ 16, 0xf6b0, 0, {0x0f,0xf0,0x03,0xfc,0x01,0xff,0x02,0x3b,0xc0,0x0f,0xf1,0x03,0x7c,0x00,0xff,0x00 } }, -{ 16, 0xf6c0, 0, {0x3f,0xc0,0x0f,0xf0,0x13,0xfc,0x40,0xef,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xe8,0x06 } }, -{ 16, 0xf6d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xf2,0x40,0xcc,0x80,0x37,0x20 } }, -{ 16, 0xf6e0, 0, {0x0c,0xd8,0x03,0xb0,0x44,0xfc,0x08,0x3f,0x0e,0x0f,0xc1,0x03,0xfc,0x00,0xcc,0x94 } }, -{ 16, 0xf6f0, 0, {0x3f,0x0a,0x2e,0xc4,0x03,0x7d,0x80,0xcf,0x10,0x3f,0xc0,0x0f,0xc0,0x83,0x30,0x00 } }, -{ 16, 0xf700, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0xe0,0x90,0x88,0x02,0x22,0x81 } }, -{ 16, 0xf710, 0, {0x08,0x92,0x13,0xa4,0x40,0x3b,0x60,0x22,0x18,0x0b,0x81,0x02,0xfc,0xd4,0x81,0x00 } }, -{ 16, 0xf720, 0, {0x3a,0xb0,0x0a,0x94,0x02,0x3d,0x40,0xaf,0x63,0x2f,0xdf,0x0b,0x98,0x00,0x20,0x04 } }, -{ 16, 0xf730, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe0,0x00,0x88,0x00,0x20,0x40 } }, -{ 16, 0xf740, 0, {0x88,0x30,0x82,0xc0,0x00,0xb0,0x08,0x28,0x80,0x0a,0x10,0x02,0xcc,0x20,0x80,0x01 } }, -{ 16, 0xf750, 0, {0x2c,0x40,0x1b,0x06,0x02,0x8c,0x90,0x93,0x60,0x68,0xc0,0x4a,0x00,0x42,0x22,0x01 } }, -{ 16, 0xf760, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xa0,0x02,0x88,0x00,0x22,0xc0 } }, -{ 16, 0xf770, 0, {0x08,0xb0,0x02,0xe4,0x20,0xbb,0x88,0x26,0x98,0x0b,0x80,0x42,0xcc,0x18,0x8a,0x00 } }, -{ 16, 0xf780, 0, {0x2e,0xc2,0x1b,0x98,0x02,0xac,0x00,0xab,0x00,0x2e,0xc0,0x0b,0x98,0x82,0x30,0x04 } }, -{ 16, 0xf790, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xe3,0xc0,0xcb,0x02,0x32,0x00 } }, -{ 16, 0xf7a0, 0, {0x2c,0x80,0x03,0xae,0x08,0xb9,0x00,0x3e,0x70,0x0f,0xb9,0x03,0xec,0x02,0x48,0x48 } }, -{ 16, 0xf7b0, 0, {0x3c,0xc0,0x0f,0x8c,0x93,0xec,0x00,0xdb,0x00,0x1a,0xc0,0x0e,0xac,0x03,0x10,0x04 } }, -{ 16, 0xf7c0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb2,0x00,0xff,0x00,0xbb,0x80 } }, -{ 16, 0xf7d0, 0, {0x0f,0xc0,0x43,0xb6,0x40,0xbd,0x00,0x3b,0x60,0x0f,0xe8,0x03,0xfc,0x00,0xff,0x94 } }, -{ 16, 0xf7e0, 0, {0x3b,0xe4,0x0e,0x60,0x0f,0x6c,0x08,0xef,0x01,0x3f,0xc0,0x0f,0x60,0x03,0xf8,0x00 } }, -{ 16, 0xf7f0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa1,0x00,0xfb,0x00,0x3e,0x60 } }, -{ 16, 0xf800, 0, {0x0f,0xa0,0x03,0xed,0x00,0xf9,0x40,0x3a,0x00,0x0f,0x90,0x03,0xec,0x02,0xc9,0x04 } }, -{ 16, 0xf810, 0, {0x32,0xd0,0x0f,0x90,0x03,0x2c,0x08,0xdb,0x00,0xb6,0xc0,0x0d,0xb4,0x03,0xd0,0x04 } }, -{ 16, 0xf820, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x00,0x00,0xb3,0x89,0x2e,0xe0 } }, -{ 16, 0xf830, 0, {0x0b,0xa4,0x03,0xa4,0x01,0xb9,0x00,0x2e,0x01,0x0b,0x90,0x42,0xfc,0x10,0x89,0x50 } }, -{ 16, 0xf840, 0, {0xa2,0xc0,0x8d,0xb4,0x02,0x3c,0x44,0x8f,0x00,0x23,0xc0,0x08,0xb0,0x02,0xf2,0x00 } }, -{ 16, 0xf850, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x04,0x0c,0x00,0xb0,0x80,0x2e,0x00 } }, -{ 16, 0xf860, 0, {0x0b,0x12,0x02,0xc8,0x00,0xba,0x00,0x2c,0xc0,0x0b,0x20,0x02,0xcc,0x00,0xa2,0x00 } }, -{ 16, 0xf870, 0, {0x20,0x00,0x2b,0x2d,0x9a,0x2e,0x42,0x83,0x00,0x28,0xc0,0x08,0x20,0x02,0xf8,0x00 } }, -{ 16, 0xf880, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x1e,0x04,0xb4,0x80,0x2d,0xa0 } }, -{ 16, 0xf890, 0, {0x0b,0x58,0x02,0x92,0x00,0xb6,0x80,0x2d,0xe0,0x0b,0x68,0x02,0xde,0x40,0xa6,0x80 } }, -{ 16, 0xf8a0, 0, {0x21,0x24,0x29,0x48,0x02,0x1e,0x80,0x87,0x80,0x69,0xe0,0x08,0x61,0x02,0xc8,0x00 } }, -{ 16, 0xf8b0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x18,0x0c,0x00,0xf0,0x30,0x3c,0x4c } }, -{ 16, 0xf8c0, 0, {0x0f,0x32,0x03,0xc8,0x80,0xb2,0x00,0x38,0x80,0x0f,0x1b,0x03,0xec,0x00,0xe0,0x30 } }, -{ 16, 0xf8d0, 0, {0x30,0x04,0x0f,0xb1,0x03,0x0e,0x85,0xcb,0x00,0x3a,0xc0,0x0c,0x31,0x03,0xd2,0x02 } }, -{ 16, 0xf8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1c,0xbc,0x00,0xfc,0x11,0x3f,0xc4 } }, -{ 16, 0xf8f0, 0, {0x0f,0xb8,0x13,0xb0,0x04,0xfe,0x02,0x3f,0x80,0x0f,0xc0,0x03,0xfd,0x00,0xdf,0x12 } }, -{ 16, 0xf900, 0, {0x1d,0x04,0x0f,0xd0,0x43,0xbc,0x01,0xef,0x10,0x33,0xc4,0x0e,0xf3,0x03,0xd0,0x06 } }, -{ 16, 0xf910, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xee,0x00,0xcb,0x00,0x3e,0x00 } }, -{ 16, 0xf920, 0, {0x0f,0x80,0x03,0x28,0x00,0xf8,0x00,0x3e,0x40,0x3d,0xb0,0x03,0xef,0x08,0xc9,0x00 } }, -{ 16, 0xf930, 0, {0x3a,0x00,0x0c,0xa0,0x03,0xec,0x98,0xfb,0x20,0x32,0xd2,0x0c,0xa8,0x03,0x2a,0x02 } }, -{ 16, 0xf940, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0x87,0x01,0x2d,0x80 } }, -{ 16, 0xf950, 0, {0x0b,0x40,0x42,0x1c,0x04,0x37,0x00,0xa1,0x40,0x08,0x60,0x02,0xcc,0x80,0x87,0x00 } }, -{ 16, 0xf960, 0, {0x2d,0x80,0x2e,0x70,0x02,0xdc,0xa9,0xb7,0x28,0x21,0xd0,0x08,0x70,0x02,0x12,0x00 } }, -{ 16, 0xf970, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xbe,0x02,0x87,0x80,0x2d,0x60 } }, -{ 16, 0xf980, 0, {0x4b,0xe8,0x02,0x5a,0x01,0xb4,0x88,0x28,0xe0,0x88,0x78,0xc2,0xde,0x52,0x86,0xc0 } }, -{ 16, 0xf990, 0, {0x29,0x60,0x08,0x68,0x02,0xde,0x40,0xb3,0x92,0xe1,0xe8,0x28,0x28,0x02,0x70,0x00 } }, -{ 16, 0xf9a0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x14,0xcc,0x00,0x8b,0x80,0x2e,0xc0 } }, -{ 16, 0xf9b0, 0, {0x0b,0x20,0x02,0x4d,0x80,0x9b,0x20,0x20,0xe0,0x08,0x38,0x02,0xcc,0x00,0x83,0x80 } }, -{ 16, 0xf9c0, 0, {0x2c,0xc0,0x0a,0xb0,0x02,0xcc,0x08,0xb3,0x00,0x20,0xc0,0x08,0x31,0x02,0x52,0x04 } }, -{ 16, 0xf9d0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xca,0xe0,0x3e,0x80 } }, -{ 16, 0xf9e0, 0, {0x1f,0xa4,0x0b,0x79,0x00,0xfe,0x00,0x3f,0x82,0x1d,0xe0,0x03,0xe8,0x00,0xce,0x40 } }, -{ 16, 0xf9f0, 0, {0x3b,0x88,0x2c,0xe4,0x03,0xe8,0x01,0xfa,0x00,0x32,0x80,0x0c,0xe8,0x03,0x7a,0x04 } }, -{ 16, 0xfa00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0xa0,0x00,0xf8,0x09,0x3e,0x00 } }, -{ 16, 0xfa10, 0, {0x8f,0xc0,0x83,0xa0,0x18,0xf8,0x00,0x3c,0x20,0x0f,0x88,0x03,0xe0,0x00,0xf8,0x08 } }, -{ 16, 0xfa20, 0, {0x3e,0x20,0x0e,0x80,0x83,0xe1,0x01,0xf0,0x00,0x3c,0x00,0x0f,0x80,0x0b,0x92,0x00 } }, -{ 16, 0xfa30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xf9,0x42,0x32,0x40 } }, -{ 16, 0xfa40, 0, {0x4c,0x98,0x03,0x04,0x00,0xc9,0x00,0x3a,0x40,0x0f,0x90,0x23,0x24,0x00,0xb9,0x81 } }, -{ 16, 0xfa50, 0, {0x3c,0x40,0x0c,0x92,0x03,0x24,0x00,0xf9,0x05,0x32,0x40,0x6c,0x90,0xc3,0xc2,0x04 } }, -{ 16, 0xfa60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x24,0x14,0xb9,0x00,0xa2,0x54 } }, -{ 16, 0xfa70, 0, {0x08,0x9b,0x1a,0x24,0x02,0x89,0x00,0x22,0x40,0x28,0x90,0x02,0xa4,0x00,0xb9,0x90 } }, -{ 16, 0xfa80, 0, {0x2e,0x40,0x28,0x9c,0x82,0x25,0x04,0xb9,0x00,0x22,0x40,0x08,0x98,0x12,0xe0,0x00 } }, -{ 16, 0xfa90, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xad,0x00,0x23,0x40 } }, -{ 16, 0xfaa0, 0, {0x08,0x50,0x02,0x64,0x00,0x89,0x00,0x2a,0x40,0x08,0x10,0x02,0x64,0x00,0xb9,0x00 } }, -{ 16, 0xfab0, 0, {0x6e,0x40,0x08,0x90,0x02,0x25,0x00,0xa9,0x00,0x22,0x40,0x08,0x91,0x06,0xc6,0x00 } }, -{ 16, 0xfac0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x14,0x00,0xb5,0x10,0xa1,0x44 } }, -{ 16, 0xfad0, 0, {0x28,0x50,0x02,0x44,0x80,0x81,0x30,0x20,0x48,0x08,0x12,0x02,0x84,0x40,0xb1,0x80 } }, -{ 16, 0xfae0, 0, {0x6c,0xc8,0x08,0x12,0x02,0x04,0x80,0xb1,0x34,0x20,0x48,0x08,0x12,0x02,0xc2,0x01 } }, -{ 16, 0xfaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xe8,0x40,0x32,0x90 } }, -{ 16, 0xfb00, 0, {0x0c,0xc5,0x03,0x61,0x40,0xc0,0x40,0x3a,0x14,0x0f,0x85,0x03,0x21,0xb0,0xf8,0x50 } }, -{ 16, 0xfb10, 0, {0x3e,0x00,0x0c,0x85,0x03,0x21,0x40,0xf8,0x40,0xb0,0x14,0x0c,0x80,0x03,0xee,0x01 } }, -{ 16, 0xfb20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x1d,0xc4,0x04,0xf9,0x22,0x0e,0x48 } }, -{ 16, 0xfb30, 0, {0x0f,0x10,0x13,0xb4,0x40,0xfd,0x30,0x3f,0x44,0x4f,0xd1,0x00,0xe4,0x84,0xff,0x01 } }, -{ 16, 0xfb40, 0, {0x3d,0x44,0x0f,0xd1,0x0b,0xe4,0x40,0xf9,0x30,0x3e,0x44,0x0f,0xd1,0x03,0xe6,0x04 } }, -{ 16, 0xfb50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x05,0xe4,0x00,0xdd,0x40,0x3f,0x50 } }, -{ 16, 0xfb60, 0, {0x0c,0xd0,0x03,0x2c,0x00,0xc9,0x00,0x36,0x40,0x0f,0x90,0x13,0x27,0x04,0xf5,0x01 } }, -{ 16, 0xfb70, 0, {0x37,0x40,0x0c,0xf0,0x03,0xf6,0x20,0xf9,0xa8,0x32,0x68,0x0c,0xd0,0x03,0xc6,0x00 } }, -{ 16, 0xfb80, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xe0,0x00,0x88,0xa0,0x2e,0x28 } }, -{ 16, 0xfb90, 0, {0x28,0x80,0x02,0x20,0x00,0x88,0xa0,0x22,0x00,0x0b,0x80,0x0a,0x62,0x80,0xb8,0x00 } }, -{ 16, 0xfba0, 0, {0x22,0x00,0x08,0x80,0x02,0xe1,0x00,0xb8,0xe0,0x22,0x3a,0x08,0xa0,0x02,0xce,0x04 } }, -{ 16, 0xfbb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x02,0x81,0x00,0x2e,0x40 } }, -{ 16, 0xfbc0, 0, {0x08,0x10,0x0a,0x44,0x02,0x81,0x08,0x24,0x40,0x0a,0x10,0x02,0x45,0x80,0xb9,0x00 } }, -{ 16, 0xfbd0, 0, {0x24,0x40,0x29,0x10,0x02,0xc4,0x00,0xb1,0x08,0x24,0x44,0x08,0x10,0x02,0xc2,0x01 } }, -{ 16, 0xfbe0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x14,0xa4,0x04,0x89,0x01,0x2e,0x50 } }, -{ 16, 0xfbf0, 0, {0x48,0xb2,0x02,0x64,0x00,0x91,0x00,0x22,0x46,0x0b,0x90,0x02,0x64,0x00,0xb9,0x01 } }, -{ 16, 0xfc00, 0, {0x26,0xc0,0x09,0xb0,0x12,0xe4,0x00,0xb1,0x00,0x26,0x40,0x08,0x90,0x02,0xc6,0x04 } }, -{ 16, 0xfc10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x04,0xe4,0x00,0xc9,0x00,0x3c,0x40 } }, -{ 16, 0xfc20, 0, {0x0c,0x90,0x03,0x64,0x00,0xc9,0x02,0x36,0x50,0x0e,0x93,0x03,0x24,0x00,0xf9,0x90 } }, -{ 16, 0xfc30, 0, {0x36,0x48,0x0d,0x94,0x83,0xe4,0x08,0xf9,0x00,0xb6,0x40,0x0c,0x94,0x03,0xe8,0x04 } }, -{ 16, 0xfc40, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0xa4,0x00,0xe9,0x00,0x3e,0x40 } }, -{ 16, 0xfc50, 0, {0x0f,0x90,0x13,0xa4,0x00,0xe9,0x02,0x2e,0x61,0x05,0x90,0x03,0xa4,0x00,0xf9,0x00 } }, -{ 16, 0xfc60, 0, {0x3a,0x40,0x0e,0x90,0x43,0xe4,0x10,0xf9,0x00,0x38,0x40,0x2f,0x90,0x03,0xca,0x00 } }, -{ 16, 0xfc70, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x01,0x32,0x04 } }, -{ 16, 0xfc80, 0, {0x0f,0x80,0x43,0xc0,0x01,0xc8,0x00,0xb2,0x01,0x0c,0x80,0x03,0x20,0x00,0xc8,0x40 } }, -{ 16, 0xfc90, 0, {0x30,0x00,0x8c,0x84,0x83,0xe0,0x00,0xc8,0x00,0x32,0x00,0x6c,0x84,0x03,0xca,0x04 } }, -{ 16, 0xfca0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x28,0x00,0xba,0x00,0x23,0x80 } }, -{ 16, 0xfcb0, 0, {0x0b,0xea,0x02,0xe8,0x00,0xaa,0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0x86,0x20 } }, -{ 16, 0xfcc0, 0, {0x37,0xa0,0x8d,0xe4,0x02,0xf8,0x00,0xda,0x00,0x22,0x80,0x08,0xa0,0x02,0xca,0x00 } }, -{ 16, 0xfcd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x6c,0x00,0xb3,0x00,0x20,0xc0 } }, -{ 16, 0xfce0, 0, {0x0b,0xb8,0x02,0x4c,0x04,0x83,0x00,0x20,0xc0,0x08,0xb0,0x02,0x0c,0x02,0x83,0x00 } }, -{ 16, 0xfcf0, 0, {0x20,0x40,0x28,0x34,0x02,0xce,0x90,0x83,0x00,0xa0,0xc0,0x08,0x30,0x02,0xca,0x00 } }, -{ 16, 0xfd00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1c,0xc0,0xb5,0x88,0x21,0x40 } }, -{ 16, 0xfd10, 0, {0x0b,0x70,0x02,0xdc,0x80,0xa3,0x20,0x21,0xe0,0x48,0x32,0x42,0x0e,0x90,0x8e,0x01 } }, -{ 16, 0xfd20, 0, {0x65,0x50,0x09,0x70,0x02,0xde,0x20,0x93,0x21,0x21,0xc0,0x08,0x70,0x02,0xe8,0x00 } }, -{ 16, 0xfd30, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x18,0x1e,0x00,0xff,0x80,0xb1,0xa0 } }, -{ 16, 0xfd40, 0, {0x0f,0x48,0x02,0x7e,0x00,0x87,0xa0,0x33,0xe0,0x28,0x7a,0x0b,0x1f,0x00,0xc4,0x80 } }, -{ 16, 0xfd50, 0, {0x31,0x60,0x8c,0x58,0x03,0xfe,0x00,0xc7,0xc8,0x33,0xe8,0x0c,0x58,0x03,0xea,0x02 } }, -{ 16, 0xfd60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xff,0x00,0x3e,0x00 } }, -{ 16, 0xfd70, 0, {0x0f,0x90,0x23,0xec,0xa0,0xfb,0x40,0x3e,0xc0,0x8f,0xb5,0x03,0xed,0x80,0xf8,0x00 } }, -{ 16, 0xfd80, 0, {0x3c,0x40,0x0f,0xb0,0x03,0xe8,0x00,0xfb,0x02,0x3e,0xd0,0x0f,0x90,0x03,0xc2,0x06 } }, -{ 16, 0xfd90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x04,0xbe,0x00,0xff,0x80,0x3f,0xe0 } }, -{ 16, 0xfda0, 0, {0x0f,0xd9,0x03,0xfe,0x20,0xcf,0xc8,0x33,0xea,0x8f,0xfc,0x03,0x3f,0x00,0xfd,0x80 } }, -{ 16, 0xfdb0, 0, {0x3f,0x60,0x0e,0xe8,0x03,0xf2,0x00,0xcf,0x80,0x2f,0xfe,0x0c,0x78,0x03,0x00,0x00 } }, -{ 16, 0xfdc0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x00,0x9c,0x00,0xb5,0x02,0x2d,0xc0 } }, -{ 16, 0xfdd0, 0, {0x0b,0x58,0x42,0xdc,0x80,0xcf,0x00,0x21,0xc1,0x0b,0x30,0x12,0x1c,0x40,0xb4,0x02 } }, -{ 16, 0xfde0, 0, {0x2d,0x46,0x08,0x71,0x12,0xc8,0x00,0xe7,0x00,0x2d,0xc4,0x08,0x70,0x03,0x6a,0x04 } }, -{ 16, 0xfdf0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x00,0x2d,0x02 } }, -{ 16, 0xfe00, 0, {0x0b,0x46,0x02,0xdc,0x08,0x97,0x00,0x21,0xc9,0x0a,0x30,0x22,0x1c,0x00,0xb4,0x00 } }, -{ 16, 0xfe10, 0, {0x2d,0x40,0x0a,0x50,0x82,0xc4,0x00,0xb7,0x00,0x2c,0xc8,0x28,0x50,0x02,0x40,0x10 } }, -{ 16, 0xfe20, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x14,0x8c,0x18,0xb3,0x00,0x2e,0x20 } }, -{ 16, 0xfe30, 0, {0x0b,0x18,0x02,0xcf,0x4a,0x83,0xc2,0x20,0xc1,0x0b,0x34,0x22,0x0c,0x04,0xb8,0x58 } }, -{ 16, 0xfe40, 0, {0x2c,0x40,0x0b,0x28,0x02,0xc8,0x00,0xa3,0x00,0x2c,0xc0,0x08,0x14,0x02,0x48,0x04 } }, -{ 16, 0xfe50, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xbc,0x00,0xfb,0x00,0x3e,0x80 } }, -{ 16, 0xfe60, 0, {0x0f,0xa0,0x02,0xfc,0x00,0xdf,0xa0,0xb3,0xc0,0x0e,0xf0,0x0b,0x3c,0x00,0xfb,0xc0 } }, -{ 16, 0xfe70, 0, {0x3c,0xa0,0x0e,0xbd,0x03,0xec,0x00,0xff,0x00,0x3f,0xc0,0x0c,0x30,0x03,0x6a,0x04 } }, -{ 16, 0xfe80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xec,0x00,0xf9,0x00,0x3e,0x01 } }, -{ 16, 0xfe90, 0, {0x8f,0xb1,0x43,0xec,0x00,0xf3,0x00,0x3e,0xc0,0x4f,0xb0,0x13,0xec,0x00,0xfb,0x00 } }, -{ 16, 0xfea0, 0, {0x3e,0x80,0x0c,0x84,0x03,0xe1,0x00,0x73,0x00,0x3e,0xc1,0x0f,0xb2,0x43,0xe0,0x00 } }, -{ 16, 0xfeb0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x50,0xfc,0x10,0xff,0x80,0x37,0xc0 } }, -{ 16, 0xfec0, 0, {0x0c,0xe0,0x03,0xfc,0x20,0xff,0x08,0x33,0xc0,0x0f,0xf0,0x83,0xbc,0x00,0xff,0x00 } }, -{ 16, 0xfed0, 0, {0x33,0xc0,0x2e,0x40,0x03,0x1c,0x01,0xcf,0x00,0x11,0xc0,0x4c,0xd0,0x03,0x00,0x44 } }, -{ 16, 0xfee0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x04,0xb3,0x02,0x22,0x72 } }, -{ 16, 0xfef0, 0, {0x08,0xa1,0x16,0xec,0x00,0xbb,0x04,0x22,0xc0,0x0b,0xb0,0x42,0xec,0x00,0xba,0x19 } }, -{ 16, 0xff00, 0, {0xb6,0xd0,0x08,0x9c,0x4a,0x26,0x80,0xdb,0x00,0x22,0xc0,0x08,0x90,0x03,0x60,0x40 } }, -{ 16, 0xff10, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xb9,0x10,0x62,0x20 } }, -{ 16, 0xff20, 0, {0x48,0xa0,0x02,0xec,0x00,0xbb,0x00,0x22,0xc0,0x0b,0xb0,0x02,0xec,0x10,0xbb,0x00 } }, -{ 16, 0xff30, 0, {0x66,0x08,0x0a,0xa8,0x12,0x26,0x10,0x9b,0x00,0x2a,0xc0,0x28,0xb0,0x26,0x20,0x00 } }, -{ 16, 0xff40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0c,0x00,0xb9,0x00,0x20,0x00 } }, -{ 16, 0xff50, 0, {0x08,0x32,0x02,0xcc,0x04,0xb3,0x00,0x20,0xc0,0x4b,0x30,0x02,0xcc,0x00,0xb3,0x00 } }, -{ 16, 0xff60, 0, {0x20,0x00,0x08,0x00,0x02,0x01,0x00,0x93,0x00,0x28,0xc0,0x08,0x30,0x06,0x42,0x11 } }, -{ 16, 0xff70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x6c,0x00,0xf9,0x00,0xb2,0x40 } }, -{ 16, 0xff80, 0, {0x0c,0x82,0x02,0xdc,0x01,0xff,0x00,0xb2,0xc0,0x0b,0xf1,0x03,0xbc,0x00,0xf9,0x00 } }, -{ 16, 0xff90, 0, {0x26,0x40,0x2e,0x80,0x03,0x21,0x04,0xcf,0x00,0xbb,0xc0,0x0c,0x90,0x03,0x00,0x03 } }, -{ 16, 0xffa0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xfd,0x00,0x3f,0x40 } }, -{ 16, 0xffb0, 0, {0x0f,0x81,0x03,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x23,0xfc,0x00,0xfc,0x00 } }, -{ 16, 0xffc0, 0, {0x2d,0x40,0x2f,0xc0,0x03,0xf0,0x88,0xff,0x00,0x37,0xc0,0x8f,0xd0,0x03,0xe8,0x02 } }, -{ 16, 0xffd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x40,0xff,0x80,0x33,0xc2 } }, -{ 16, 0xffe0, 0, {0x0c,0xf8,0x03,0x7c,0xa0,0xff,0x90,0x3f,0xc4,0x2c,0xb4,0x03,0xbc,0x80,0xcf,0x40 } }, -{ 16, 0xfff0, 0, {0x37,0xe0,0x0f,0xf1,0x93,0x6e,0x44,0xbf,0x30,0x3f,0x20,0x2c,0xf8,0x63,0xf0,0x04 } }, -{ 16, 0x8010, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0x00,0xeb,0x20,0x23,0xf0 } }, -{ 16, 0x8020, 0, {0x08,0xb8,0x52,0x3d,0x00,0xb3,0x00,0x2e,0xdc,0x08,0xf4,0x42,0x1c,0x42,0x8b,0x40 } }, -{ 16, 0x8030, 0, {0x22,0xc8,0x0b,0xf6,0x03,0x6c,0x88,0xbb,0x30,0x2e,0x00,0x08,0xb2,0x02,0xe0,0x04 } }, -{ 16, 0x8040, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xbb,0x08,0x20,0xc0 } }, -{ 16, 0x8050, 0, {0x08,0x30,0x02,0x4c,0xa0,0xb3,0x20,0x26,0x80,0x88,0x36,0x02,0xcc,0xa0,0x93,0x60 } }, -{ 16, 0x8060, 0, {0xa4,0xc2,0x0a,0x32,0x42,0x4c,0x90,0xb3,0x20,0x2c,0x0b,0x88,0x30,0x82,0xe2,0x01 } }, -{ 16, 0x8070, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x08,0xbb,0x22,0xa2,0xc0 } }, -{ 16, 0x8080, 0, {0x08,0xb0,0x02,0x2c,0x00,0xbb,0x00,0x2e,0x90,0x08,0xb0,0x02,0xec,0x00,0x9b,0x00 } }, -{ 16, 0x8090, 0, {0x22,0xc0,0x0b,0xb0,0x02,0x6c,0x00,0xbb,0x02,0x2e,0x20,0x08,0xb0,0x02,0xf0,0x00 } }, -{ 16, 0x80a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xb1,0x83,0x32,0xc0 } }, -{ 16, 0x80b0, 0, {0x0c,0x1a,0x03,0x6c,0x10,0xfb,0x00,0x34,0xc0,0x0c,0xb0,0x03,0xec,0x08,0xda,0x00 } }, -{ 16, 0x80c0, 0, {0x36,0xc0,0x0e,0xb0,0x0b,0x6c,0x00,0xfb,0x00,0x3e,0x28,0x0c,0xb0,0x02,0xd0,0x00 } }, -{ 16, 0x80d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x00,0xed,0x80,0x3f,0xc0 } }, -{ 16, 0x80e0, 0, {0x0f,0xd4,0x03,0xec,0x00,0xff,0x00,0x3f,0xc8,0x0f,0xb0,0x03,0x3c,0x00,0xee,0x40 } }, -{ 16, 0x80f0, 0, {0x3f,0xc0,0x0f,0x70,0x03,0xfc,0x00,0xff,0x00,0x3f,0x80,0x0f,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0x8100, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x20,0xb0,0xc0 } }, -{ 16, 0x8110, 0, {0x0f,0xb4,0x03,0xac,0x02,0xcb,0x00,0x32,0x90,0x0e,0xb0,0x03,0x6c,0x00,0xeb,0x00 } }, -{ 16, 0x8120, 0, {0x3a,0xc0,0x0c,0xb0,0x02,0xec,0x00,0xfb,0x00,0x3e,0x91,0x0f,0xb0,0x03,0x90,0x00 } }, -{ 16, 0x8130, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xbb,0x80,0x23,0xd7 } }, -{ 16, 0x8140, 0, {0x0b,0x90,0x02,0x3c,0x14,0x8b,0x00,0x6a,0x08,0x28,0xf0,0x00,0xbc,0x00,0x83,0x00 } }, -{ 16, 0x8150, 0, {0xbe,0xc0,0x88,0xf0,0x13,0x2c,0x00,0xef,0x00,0x2e,0x80,0x0b,0xb0,0x07,0xb2,0x00 } }, -{ 16, 0x8160, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x40,0x20,0xd0 } }, -{ 16, 0x8170, 0, {0x0b,0x28,0x02,0x8c,0x00,0x83,0x01,0x20,0xc0,0x1a,0xb8,0x00,0x6c,0x10,0xa1,0x00 } }, -{ 16, 0x8180, 0, {0x68,0xc0,0x2a,0x30,0x02,0x8c,0x00,0xb3,0x02,0x2e,0x00,0x4b,0x30,0x02,0xf8,0x04 } }, -{ 16, 0x8190, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x00,0xb7,0xa0,0x21,0xe0 } }, -{ 16, 0x81a0, 0, {0x0b,0xec,0xc2,0x1e,0x04,0x87,0x80,0x29,0xe4,0x08,0x79,0x82,0x9e,0x40,0xaf,0x90 } }, -{ 16, 0x81b0, 0, {0x29,0xe0,0x0a,0x38,0x00,0x1e,0x00,0xa7,0x90,0x2d,0x24,0x0b,0x78,0x02,0x88,0x00 } }, -{ 16, 0x81c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x50,0xfb,0x09,0x30,0xc0 } }, -{ 16, 0x81d0, 0, {0x0f,0x20,0x02,0x8c,0x40,0xc3,0x00,0x20,0xc0,0x0a,0x38,0x03,0x4c,0x44,0xe1,0x00 } }, -{ 16, 0x81e0, 0, {0xaa,0xc0,0x0e,0x31,0x43,0x8e,0x00,0xf3,0x00,0x3c,0x00,0x0f,0x30,0x03,0xd2,0x02 } }, -{ 16, 0x81f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x4d,0xbc,0x00,0xff,0x20,0x3f,0xd0 } }, -{ 16, 0x8200, 0, {0x4f,0x70,0x03,0xfc,0x00,0xff,0x00,0x3d,0xc0,0x0f,0xf3,0x43,0xfc,0x40,0xd7,0x00 } }, -{ 16, 0x8210, 0, {0xbf,0xc0,0x0d,0xf4,0xc3,0xfc,0x40,0xff,0x00,0x3f,0x40,0x0f,0xf0,0x03,0xd0,0x06 } }, -{ 16, 0x8220, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x00,0x32,0xd0 } }, -{ 16, 0x8230, 0, {0x0d,0x90,0x01,0xed,0xc0,0xfb,0x00,0x3e,0xc0,0x1f,0xba,0x03,0xac,0xc0,0xc8,0x00 } }, -{ 16, 0x8240, 0, {0x32,0xe0,0x8d,0xb4,0x43,0xec,0x00,0xfb,0x00,0x36,0xa0,0x0c,0xb0,0x03,0x6a,0x00 } }, -{ 16, 0x8250, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb7,0x00,0x21,0xc8 } }, -{ 16, 0x8260, 0, {0x08,0x60,0x02,0xdc,0x20,0xb7,0x00,0x2d,0xc0,0x0f,0x74,0xa2,0x1c,0x28,0xd6,0x00 } }, -{ 16, 0x8270, 0, {0x35,0xc0,0x08,0x72,0x02,0x5c,0x08,0xb7,0x44,0xa1,0x80,0x48,0x70,0x02,0x12,0x00 } }, -{ 16, 0x8280, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x80,0x20,0xe4 } }, -{ 16, 0x8290, 0, {0x09,0x78,0x26,0xde,0x00,0xb7,0x80,0x2d,0xe2,0x0a,0x70,0x12,0x8c,0x88,0x81,0x80 } }, -{ 16, 0x82a0, 0, {0x21,0xe0,0x09,0x78,0x02,0xde,0x00,0xb3,0xa0,0x25,0xa0,0x28,0x78,0x02,0x70,0x04 } }, -{ 16, 0x82b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x01,0xbb,0x80,0x20,0xc0 } }, -{ 16, 0x82c0, 0, {0x08,0x30,0x42,0xec,0x00,0xb3,0x00,0x2c,0xc0,0x0a,0x30,0x22,0x0c,0x00,0x93,0x00 } }, -{ 16, 0x82d0, 0, {0x24,0xc1,0x08,0x30,0x02,0xcc,0x00,0xb3,0x00,0x20,0xe0,0x08,0xb0,0x02,0x12,0x04 } }, -{ 16, 0x82e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x08,0xb2,0x80 } }, -{ 16, 0x82f0, 0, {0x0d,0xe2,0x03,0xe8,0x00,0xfa,0x00,0x3f,0x80,0x0a,0xa0,0x03,0xa8,0x00,0xce,0x50 } }, -{ 16, 0x8300, 0, {0x32,0x80,0x05,0xa0,0x03,0xe8,0x00,0xfa,0x00,0x37,0xa8,0x0c,0xa0,0x03,0x7a,0x04 } }, -{ 16, 0x8310, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x60,0x08,0xf8,0x00,0x3c,0x00 } }, -{ 16, 0x8320, 0, {0x0f,0x88,0x01,0xe0,0x00,0xf8,0x04,0x3c,0x00,0x4f,0x00,0x13,0xc0,0x00,0xf8,0x00 } }, -{ 16, 0x8330, 0, {0x3e,0x00,0x0f,0x80,0x03,0x60,0x00,0xf8,0x02,0x3e,0x01,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0x8340, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x90,0x12,0x40 } }, -{ 16, 0x8350, 0, {0x0c,0x90,0x03,0xa4,0x00,0xc9,0x00,0x3e,0x70,0x0e,0x94,0x33,0x24,0x08,0xc9,0x00 } }, -{ 16, 0x8360, 0, {0x2a,0x40,0x0b,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3a,0x40,0x0f,0x90,0x03,0x02,0x04 } }, -{ 16, 0x8370, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x42,0x22,0x60 } }, -{ 16, 0x8380, 0, {0x08,0x10,0x02,0x24,0x00,0x89,0x03,0x2e,0x40,0x08,0x90,0x02,0xa4,0x01,0x81,0x04 } }, -{ 16, 0x8390, 0, {0x3e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x02,0x22,0x40,0x0e,0x90,0x02,0x20,0x00 } }, -{ 16, 0x83a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x40,0x2a,0x4a } }, -{ 16, 0x83b0, 0, {0x08,0x91,0x02,0xa4,0x00,0x89,0x00,0x2e,0x40,0x1a,0x90,0x0a,0x24,0x04,0x89,0x00 } }, -{ 16, 0x83c0, 0, {0x2a,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb1,0x00,0x2a,0x40,0x0b,0x90,0x02,0x06,0x00 } }, -{ 16, 0x83d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb1,0x01,0xa8,0x48 } }, -{ 16, 0x83e0, 0, {0x88,0x90,0x02,0x04,0x80,0x81,0x40,0x2c,0x50,0x18,0x14,0x0a,0x84,0x10,0x89,0x40 } }, -{ 16, 0x83f0, 0, {0x2c,0x40,0x0b,0x10,0x02,0xc4,0x00,0x31,0x20,0x20,0x40,0x0a,0x10,0x0a,0x02,0x01 } }, -{ 16, 0x8400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf0,0x50,0x3a,0x00 } }, -{ 16, 0x8410, 0, {0x2c,0xa0,0x02,0xa1,0x42,0xc8,0x00,0x3e,0x00,0xde,0x00,0x23,0x21,0x42,0x88,0x00 } }, -{ 16, 0x8420, 0, {0x38,0x14,0x0f,0x85,0x03,0xe1,0x40,0xf8,0x50,0x38,0x14,0x0f,0x05,0x03,0x2e,0x01 } }, -{ 16, 0x8430, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xe4,0x08,0xfd,0x00,0x36,0x44 } }, -{ 16, 0x8440, 0, {0x0f,0xd0,0x03,0x64,0x40,0xf9,0x00,0x3d,0x50,0x0f,0x94,0x03,0xe5,0x00,0x7d,0x40 } }, -{ 16, 0x8450, 0, {0x3e,0x40,0x0f,0x94,0x03,0xe4,0x00,0xf9,0x10,0x3f,0x40,0x0e,0x90,0x03,0xe6,0x04 } }, -{ 16, 0x8460, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe4,0x00,0xfd,0x40,0x33,0x68 } }, -{ 16, 0x8470, 0, {0x0c,0xd0,0x03,0xe7,0x81,0xf9,0x00,0x33,0x78,0x0d,0xd8,0x13,0x26,0xa0,0xcd,0xa0 } }, -{ 16, 0x8480, 0, {0x32,0x40,0x0d,0x9b,0x03,0x24,0x00,0xf9,0xa0,0x3c,0x44,0x2c,0x90,0x07,0x86,0x00 } }, -{ 16, 0x8490, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe0,0x00,0xb8,0xa0,0xa2,0x10 } }, -{ 16, 0x84a0, 0, {0x18,0x80,0x03,0x82,0x84,0xb8,0x80,0x36,0x2c,0x2e,0x0f,0x02,0xa3,0xa0,0xd8,0xe0 } }, -{ 16, 0x84b0, 0, {0x36,0x22,0x8b,0x08,0x03,0x42,0xa0,0xf8,0xe0,0x2e,0x28,0x08,0x88,0x02,0xce,0x04 } }, -{ 16, 0x84c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0xa0,0x50 } }, -{ 16, 0x84d0, 0, {0x28,0x30,0x02,0xc5,0x80,0xb1,0x08,0x20,0x40,0x09,0x10,0xa2,0x44,0x08,0x81,0x48 } }, -{ 16, 0x84e0, 0, {0x20,0x40,0x0b,0x14,0x02,0x04,0x80,0xb1,0x38,0x2c,0x48,0x08,0x12,0x82,0x82,0x01 } }, -{ 16, 0x84f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0xb1,0x00,0x22,0x40 } }, -{ 16, 0x8500, 0, {0x08,0x92,0x02,0xe4,0x00,0xb9,0x02,0x26,0x58,0x4a,0x90,0x02,0xe4,0x08,0x99,0x40 } }, -{ 16, 0x8510, 0, {0x26,0x40,0x0b,0x90,0x02,0x64,0x08,0xb9,0x01,0x2c,0x48,0x08,0x90,0x12,0xc6,0x04 } }, -{ 16, 0x8520, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x80,0x32,0x40 } }, -{ 16, 0x8530, 0, {0x08,0x98,0x83,0xe4,0x04,0xb9,0x01,0x30,0x40,0x0d,0x90,0x0b,0x64,0x02,0xc9,0x00 } }, -{ 16, 0x8540, 0, {0x32,0x40,0x0f,0x90,0x03,0x24,0x00,0xf9,0x00,0x1e,0x58,0x0c,0x90,0x03,0xa8,0x04 } }, -{ 16, 0x8550, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x20,0x3c,0x40 } }, -{ 16, 0x8560, 0, {0x0f,0x98,0x03,0xa4,0x00,0xb9,0x00,0x3e,0x42,0x8e,0x10,0x4b,0x84,0x04,0xf9,0x00 } }, -{ 16, 0x8570, 0, {0x3e,0x40,0x8f,0x90,0x03,0xe4,0x00,0xe9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0x8580, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x00,0x32,0x08 } }, -{ 16, 0x8590, 0, {0x0f,0x84,0x83,0xa0,0x04,0xc8,0x04,0x3e,0x00,0x83,0x80,0x01,0x20,0x00,0xc0,0x00 } }, -{ 16, 0x85a0, 0, {0x32,0x00,0x0f,0x00,0x03,0xa0,0x00,0xc8,0x00,0x32,0x10,0x4e,0x80,0x13,0xca,0x04 } }, -{ 16, 0x85b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8e,0x90,0xa3,0x80 } }, -{ 16, 0x85c0, 0, {0x0b,0xe4,0x02,0x28,0x00,0xca,0x00,0x2f,0x80,0x4a,0xa0,0x13,0xa8,0x00,0xaa,0x00 } }, -{ 16, 0x85d0, 0, {0x36,0x81,0x0b,0xa0,0x02,0x28,0x00,0x8a,0x00,0x22,0x80,0x08,0xa0,0x03,0x8a,0x00 } }, -{ 16, 0x85e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0xc0,0x20,0xd0 } }, -{ 16, 0x85f0, 0, {0x0b,0x34,0x02,0x8c,0x00,0x8b,0x00,0x2c,0xf0,0x8b,0x18,0x02,0x4c,0x00,0x83,0x00 } }, -{ 16, 0x8600, 0, {0x60,0xc0,0x0b,0x30,0x02,0x8c,0x02,0x83,0x00,0x28,0xc1,0x0a,0x30,0x02,0xca,0x00 } }, -{ 16, 0x8610, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1e,0x00,0xb4,0x0b,0x69,0xc0 } }, -{ 16, 0x8620, 0, {0x09,0x58,0x06,0x1e,0x80,0x97,0x10,0x2f,0xc2,0x48,0x70,0x82,0x9c,0x80,0xa7,0x08 } }, -{ 16, 0x8630, 0, {0x25,0xcc,0x0b,0x70,0x02,0x1e,0x81,0x87,0xa2,0xab,0xc4,0x08,0x73,0x02,0xe8,0x00 } }, -{ 16, 0x8640, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x10,0xdc,0x84,0x21,0xe0 } }, -{ 16, 0x8650, 0, {0x0f,0x78,0x42,0x9f,0x02,0xc7,0x88,0x3d,0xe0,0x2f,0x71,0x03,0x4e,0x00,0xcf,0x80 } }, -{ 16, 0x8660, 0, {0x21,0xe2,0x0f,0x78,0x83,0x9e,0x49,0xcf,0xd0,0x39,0xe8,0x0e,0x78,0x03,0xea,0x02 } }, -{ 16, 0x8670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x4d,0xac,0x40,0xca,0x00,0x36,0x00 } }, -{ 16, 0x8680, 0, {0x8f,0x30,0x23,0xec,0xa8,0xeb,0x40,0x3c,0xc0,0x0f,0x96,0x43,0xed,0x80,0xfb,0x00 } }, -{ 16, 0x8690, 0, {0x3e,0xd8,0x8f,0xb1,0x43,0xed,0x80,0xfb,0x20,0x36,0xca,0x0f,0xb0,0xa3,0x82,0x06 } }, -{ 16, 0x86a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x80,0xfc,0x80,0x31,0xe0 } }, -{ 16, 0x86b0, 0, {0x05,0xaa,0x10,0xfe,0x44,0xff,0x90,0x3f,0xe1,0xcf,0xf9,0x17,0x3f,0x20,0xd7,0x80 } }, -{ 16, 0x86c0, 0, {0x8b,0xe4,0x0f,0xf8,0x03,0x3e,0x30,0xff,0x80,0x37,0xe0,0x0f,0xf8,0x00,0x40,0x00 } }, -{ 16, 0x86d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xbd,0x10,0x21,0xc0 } }, -{ 16, 0x86e0, 0, {0x08,0x4a,0x02,0xdc,0xc0,0xb7,0x00,0x2d,0xc2,0x0c,0xd3,0x02,0x1c,0x80,0x87,0x00 } }, -{ 16, 0x86f0, 0, {0x29,0xc0,0x4b,0x72,0x02,0x1c,0x00,0xb7,0x01,0x21,0xc0,0x0b,0xf0,0x12,0x2a,0x04 } }, -{ 16, 0x8700, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x90,0x34,0x00,0x21,0x80 } }, -{ 16, 0x8710, 0, {0x09,0x70,0x00,0x5c,0x0c,0xb7,0x00,0x2d,0xc4,0x08,0x50,0x1a,0x0c,0x00,0x97,0x00 } }, -{ 16, 0x8720, 0, {0x21,0xc0,0x4b,0x30,0x02,0x1c,0x00,0xb7,0x00,0x25,0xc0,0x0b,0x70,0x02,0x40,0x00 } }, -{ 16, 0x8730, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x00,0xb0,0x00,0x60,0x00 } }, -{ 16, 0x8740, 0, {0x08,0x3e,0x02,0xcc,0x00,0xb3,0x02,0x0c,0xe0,0x2b,0xb0,0x02,0x0c,0x00,0x93,0x00 } }, -{ 16, 0x8750, 0, {0x28,0xc0,0x0b,0xb0,0x02,0x2c,0x10,0xb3,0x00,0x20,0xd6,0x03,0x30,0x02,0x08,0x04 } }, -{ 16, 0x8760, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xfb,0x00,0xb2,0x00 } }, -{ 16, 0x8770, 0, {0x05,0xbe,0x03,0x7c,0x00,0xff,0x00,0x3e,0x20,0x0c,0xb0,0x03,0x3c,0x00,0xd9,0x80 } }, -{ 16, 0x8780, 0, {0x33,0xc0,0x8b,0xf0,0x03,0x3c,0x00,0xff,0x00,0x37,0xe0,0x0f,0xf0,0x03,0x6a,0x04 } }, -{ 16, 0x8790, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x04,0x3e,0x00 } }, -{ 16, 0x87a0, 0, {0x0f,0xa4,0x23,0xcc,0x00,0xfb,0x00,0x3e,0x81,0x08,0x90,0x03,0xec,0x00,0xe9,0x14 } }, -{ 16, 0x87b0, 0, {0x3e,0xc0,0x0f,0xb0,0x03,0xec,0x10,0xfb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xe0,0x00 } }, -{ 16, 0x87c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0x37,0x80 } }, -{ 16, 0x87d0, 0, {0x0f,0xfa,0x03,0xfc,0x00,0xcf,0x00,0x3f,0x90,0x06,0xdc,0x23,0x3c,0x00,0xfd,0x10 } }, -{ 16, 0x87e0, 0, {0x33,0xc0,0x0f,0xf0,0x0b,0x3c,0x00,0x43,0x00,0x33,0xc0,0x0f,0xf0,0x03,0xc0,0x44 } }, -{ 16, 0x87f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x6c,0x09,0xbb,0x19,0x22,0x32 } }, -{ 16, 0x8800, 0, {0x0b,0xbe,0x03,0x6c,0x00,0x8b,0x00,0x2c,0x90,0x0d,0xb8,0x02,0xac,0x00,0xb1,0x00 } }, -{ 16, 0x8810, 0, {0xf2,0xc0,0x0b,0xb0,0x12,0xac,0x00,0x8b,0x00,0x22,0xc0,0x0b,0xb0,0x03,0xa0,0x40 } }, -{ 16, 0x8820, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x10,0xb3,0x00,0x26,0x20 } }, -{ 16, 0x8830, 0, {0x0b,0x90,0x12,0xec,0x01,0x8b,0x00,0x2a,0xc2,0x0a,0x90,0x02,0x2c,0x00,0xbb,0x00 } }, -{ 16, 0x8840, 0, {0xa2,0xc0,0x0b,0xb0,0x02,0x2c,0x00,0xab,0x00,0x2a,0xc0,0x0b,0xb0,0x02,0xe0,0x00 } }, -{ 16, 0x8850, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x01,0xb3,0x00,0x20,0x00 } }, -{ 16, 0x8860, 0, {0x0b,0x00,0x02,0x8c,0x00,0x83,0x00,0x2e,0xc0,0x0b,0x34,0x02,0x8c,0x00,0xbb,0x00 } }, -{ 16, 0x8870, 0, {0x20,0xc0,0x0b,0x30,0x02,0x0d,0x00,0xa3,0x00,0xa0,0xc0,0x0b,0x30,0x02,0x82,0x01 } }, -{ 16, 0x8880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xbb,0x04,0x36,0x80 } }, -{ 16, 0x8890, 0, {0x0f,0xb2,0x02,0xfc,0x02,0xcf,0x02,0x38,0xc0,0x0e,0xf0,0x03,0x3c,0x00,0xfb,0x00 } }, -{ 16, 0x88a0, 0, {0x23,0xc0,0x0f,0xf0,0x03,0x3d,0x02,0xef,0x00,0x33,0xc0,0x0f,0xf0,0x43,0xc0,0x03 } }, -{ 16, 0x88b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3f,0x00 } }, -{ 16, 0x88c0, 0, {0x0f,0xf4,0x23,0x7c,0x00,0xff,0x00,0x3f,0xc0,0x0d,0xd0,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0x88d0, 0, {0x3b,0xc0,0x0f,0xf0,0x03,0xfc,0x88,0xdf,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xa8,0x06 } }, -{ 16, 0x88e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0x50,0xce,0x12,0x33,0xd0 } }, -{ 16, 0x88f0, 0, {0x4c,0x86,0x83,0x30,0x80,0x5f,0x68,0x33,0xc4,0x0f,0xf3,0x83,0x3c,0xc0,0xcc,0x38 } }, -{ 16, 0x8900, 0, {0xb3,0x08,0x0c,0xc6,0x03,0xf1,0xa0,0xff,0x00,0x33,0x24,0x0c,0xc2,0x03,0xf0,0x00 } }, -{ 16, 0x8910, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0x80,0xd2,0x20,0x23,0xd8 } }, -{ 16, 0x8920, 0, {0x0d,0x96,0x02,0x88,0x60,0xaf,0x40,0x23,0xdc,0x0b,0xf6,0x02,0x3c,0xc2,0x88,0x60 } }, -{ 16, 0x8930, 0, {0x22,0x52,0x08,0x91,0x22,0xe1,0x00,0xb7,0x24,0xa2,0x48,0x8a,0x84,0x82,0x60,0x04 } }, -{ 16, 0x8940, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x00,0x81,0x00,0xe0,0xc4 } }, -{ 16, 0x8950, 0, {0x0a,0x00,0x02,0x04,0x80,0xa3,0x20,0xa8,0xc0,0x1b,0x30,0x0a,0x0c,0x00,0xa0,0x00 } }, -{ 16, 0x8960, 0, {0x28,0x0c,0x09,0x02,0x02,0xc4,0x80,0xb3,0x1c,0x22,0x08,0x19,0x03,0x02,0xe2,0x11 } }, -{ 16, 0x8970, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa4,0x00,0x99,0x80,0x62,0xc0 } }, -{ 16, 0x8980, 0, {0x0b,0xa0,0x32,0xa4,0x51,0xab,0x00,0x2a,0xc0,0x8b,0xb0,0x00,0x0c,0x00,0xa9,0xc0 } }, -{ 16, 0x8990, 0, {0x2a,0x21,0x08,0xb8,0x22,0xe2,0x00,0xbb,0x00,0x22,0x84,0x1b,0xa8,0x42,0x70,0x04 } }, -{ 16, 0x89a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe2,0x00,0xcb,0xc9,0x32,0xc0 } }, -{ 16, 0x89b0, 0, {0x0e,0x8b,0x13,0x22,0x10,0xdb,0x01,0x32,0xc0,0x0f,0xb0,0x0b,0x2c,0x00,0x68,0x81 } }, -{ 16, 0x89c0, 0, {0x3a,0x22,0x2c,0x88,0x23,0xe3,0x00,0xfb,0x00,0x30,0x30,0x8d,0x9c,0x83,0xd0,0x04 } }, -{ 16, 0x89d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xba,0x40,0xf7,0x04,0x3e,0xc2 } }, -{ 16, 0x89e0, 0, {0x0d,0xd8,0x23,0xd8,0x00,0x7b,0x00,0x37,0xc0,0x0f,0x70,0x33,0xfc,0x10,0xd2,0x00 } }, -{ 16, 0x89f0, 0, {0x35,0xc0,0x8f,0xc0,0x03,0xf4,0x00,0xf7,0x02,0x3f,0xe0,0x0e,0x80,0x03,0xf8,0x00 } }, -{ 16, 0x8a00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x81,0x20,0xc8,0x08,0x30,0xc0 } }, -{ 16, 0x8a10, 0, {0x0c,0x00,0x83,0x24,0x40,0xc3,0x89,0x3a,0xc0,0x0e,0xb0,0x0b,0x2c,0x08,0xc9,0x48 } }, -{ 16, 0x8a20, 0, {0x72,0x54,0x0f,0x91,0x03,0xed,0x02,0xeb,0x8a,0x3a,0x62,0x8c,0x80,0x0b,0x10,0x04 } }, -{ 16, 0x8a30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2b,0x04,0x88,0x40,0xa3,0xc2 } }, -{ 16, 0x8a40, 0, {0x02,0xae,0x12,0x27,0x42,0x8f,0x44,0x23,0xc2,0x0b,0xf4,0x02,0x3d,0x00,0x0a,0x40 } }, -{ 16, 0x8a50, 0, {0x22,0xe0,0x0b,0xb5,0x02,0xec,0x20,0x8f,0x44,0xa2,0x40,0x8d,0xbd,0x23,0x32,0x00 } }, -{ 16, 0x8a60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x49,0x40,0x83,0x81,0x24,0xc1 } }, -{ 16, 0x8a70, 0, {0x08,0x28,0x02,0x01,0x00,0x93,0x00,0xa0,0xe8,0x0a,0x30,0x82,0x8f,0x60,0xb3,0x90 } }, -{ 16, 0x8a80, 0, {0x60,0xb8,0x0b,0x28,0x12,0x4a,0x00,0x93,0x00,0x20,0x90,0x09,0x20,0x02,0x78,0x00 } }, -{ 16, 0x8a90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x02,0x87,0xa8,0x25,0xe0 } }, -{ 16, 0x8aa0, 0, {0x0a,0x7b,0x02,0x1a,0x04,0x87,0x80,0x21,0xe4,0x0b,0x78,0x82,0x8e,0x02,0x96,0x91 } }, -{ 16, 0x8ab0, 0, {0x21,0x21,0x0b,0x69,0x40,0xdb,0x40,0x97,0x92,0x23,0xa0,0x89,0x58,0x82,0x08,0x00 } }, -{ 16, 0x8ac0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x25,0x82,0xc3,0x00,0x34,0xc0 } }, -{ 16, 0x8ad0, 0, {0x0c,0x9b,0x43,0x08,0xd0,0xd3,0x20,0x38,0xc0,0x0e,0xb0,0x03,0x8c,0x00,0xb3,0x00 } }, -{ 16, 0x8ae0, 0, {0x20,0x80,0x07,0x10,0x03,0xe0,0x00,0xd3,0x10,0x38,0x18,0x0d,0x30,0x03,0x52,0x02 } }, -{ 16, 0x8af0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xb4,0x00,0x7f,0x20,0x1b,0xd0 } }, -{ 16, 0x8b00, 0, {0x0f,0xf1,0x03,0xf8,0x40,0xef,0x00,0x3f,0xc0,0x0f,0xb4,0x03,0x7c,0x20,0xcf,0x04 } }, -{ 16, 0x8b10, 0, {0xbf,0x40,0x0f,0xf0,0x03,0xe4,0x10,0xef,0x18,0x3d,0xc0,0x0f,0xe0,0x03,0xd0,0x06 } }, -{ 16, 0x8b20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x00,0xe3,0x00,0xb2,0xc4 } }, -{ 16, 0x8b30, 0, {0x0c,0xa0,0x03,0x24,0x00,0xdb,0x68,0x32,0xc8,0x0c,0xb4,0x03,0xec,0x80,0xc8,0x80 } }, -{ 16, 0x8b40, 0, {0xb6,0xe0,0x0c,0xa0,0x03,0x2e,0x00,0xcb,0xe0,0xb2,0x60,0x0c,0xb8,0x0b,0x2a,0x00 } }, -{ 16, 0x8b50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x02,0x87,0x00,0xa1,0xc8 } }, -{ 16, 0x8b60, 0, {0x08,0x70,0x02,0x1c,0x08,0x97,0x02,0x21,0xd4,0x08,0x74,0x02,0xdc,0xc0,0x07,0x00 } }, -{ 16, 0x8b70, 0, {0x21,0xc0,0x88,0x70,0x02,0x18,0x00,0x83,0x08,0x21,0xc0,0x08,0x50,0x02,0x12,0x04 } }, -{ 16, 0x8b80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x20,0xad,0x80,0x29,0xe0 } }, -{ 16, 0x8b90, 0, {0x08,0x58,0x02,0x1e,0x00,0x97,0xb0,0x21,0xe8,0x08,0x78,0x02,0xde,0x10,0x15,0x80 } }, -{ 16, 0x8ba0, 0, {0x21,0xa1,0x08,0x48,0x02,0x5e,0x00,0x87,0xa4,0x65,0xa0,0x08,0x78,0x02,0x30,0x00 } }, -{ 16, 0x8bb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcf,0x10,0x81,0x70,0xa8,0xc0 } }, -{ 16, 0x8bc0, 0, {0x38,0x30,0x0a,0x0d,0x00,0x93,0x00,0xa0,0xc1,0x28,0x30,0x02,0xcc,0x02,0x83,0x88 } }, -{ 16, 0x8bd0, 0, {0x20,0xe0,0x38,0x34,0x0a,0x4d,0x72,0x83,0x00,0x24,0xe8,0x28,0x34,0x82,0x12,0x04 } }, -{ 16, 0x8be0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x40,0xee,0xc0,0xba,0x80 } }, -{ 16, 0x8bf0, 0, {0x0c,0xe0,0x03,0x39,0x10,0xda,0x00,0x32,0x80,0x0c,0xa0,0x03,0xe8,0x00,0xde,0xc8 } }, -{ 16, 0x8c00, 0, {0x33,0xa0,0x0c,0xe0,0x03,0x7b,0x00,0xca,0x00,0x37,0xb1,0x0c,0xe4,0x23,0x3a,0x04 } }, -{ 16, 0x8c10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xc1,0x00,0xf8,0x00,0x36,0x00 } }, -{ 16, 0x8c20, 0, {0x0f,0x80,0x03,0xc0,0x20,0x38,0x00,0x3e,0x00,0x0f,0x00,0x03,0xe0,0x00,0xf8,0x02 } }, -{ 16, 0x8c30, 0, {0x3a,0x24,0x0f,0x80,0x83,0xa0,0x01,0xf8,0x04,0x3a,0x04,0x0d,0x80,0x13,0xd2,0x00 } }, -{ 16, 0x8c40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x44,0xc1,0x00,0x32,0x40 } }, -{ 16, 0x8c50, 0, {0x0c,0x90,0x32,0x24,0x0c,0xc1,0x06,0x38,0x40,0x0d,0x90,0x09,0x04,0x00,0xd9,0x00 } }, -{ 16, 0x8c60, 0, {0x3e,0x40,0x0f,0x18,0x03,0x24,0x00,0xf9,0x01,0x3e,0x40,0x0f,0x90,0x03,0xc2,0x04 } }, -{ 16, 0x8c70, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x06,0x89,0x00,0x2a,0x50 } }, -{ 16, 0x8c80, 0, {0x08,0x94,0x0a,0x24,0x00,0x89,0x42,0x22,0x50,0x0a,0x90,0x12,0x25,0x00,0x89,0x00 } }, -{ 16, 0x8c90, 0, {0x2e,0x50,0x0b,0x9c,0x0a,0x25,0x10,0xb9,0x00,0x2e,0x50,0x0b,0x90,0x02,0xe0,0x00 } }, -{ 16, 0x8ca0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x20,0x89,0x00,0x20,0x42 } }, -{ 16, 0x8cb0, 0, {0x08,0x10,0xc2,0xac,0x10,0x89,0x08,0x2a,0x42,0x09,0x90,0x02,0x24,0x20,0x99,0x00 } }, -{ 16, 0x8cc0, 0, {0x2e,0x42,0x0a,0xb1,0x82,0x2c,0x20,0xb9,0x00,0x6e,0x42,0x0b,0x90,0x02,0xc6,0x00 } }, -{ 16, 0x8cd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x83,0x00,0x28,0x48 } }, -{ 16, 0x8ce0, 0, {0x08,0x12,0x62,0x8c,0x80,0x81,0x00,0x20,0x40,0x02,0x10,0x02,0x84,0x80,0x81,0x20 } }, -{ 16, 0x8cf0, 0, {0x2c,0x49,0x0b,0x12,0x06,0x04,0x84,0xb3,0x02,0x6c,0x40,0x0b,0x12,0x02,0xc2,0x01 } }, -{ 16, 0x8d00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x41,0xe0,0xc8,0x78,0x30,0x14 } }, -{ 16, 0x8d10, 0, {0x4c,0x05,0x13,0xa1,0x42,0xc0,0x78,0x38,0x1e,0x0d,0x87,0x83,0x01,0x40,0xd0,0x50 } }, -{ 16, 0x8d20, 0, {0x3c,0x14,0x0e,0x05,0x03,0x01,0x40,0xf8,0x78,0x3c,0x14,0x0f,0x05,0x03,0xee,0x03 } }, -{ 16, 0x8d30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xfc,0x00,0xff,0x00,0x0e,0x44 } }, -{ 16, 0x8d40, 0, {0x2f,0xf1,0x03,0x74,0x40,0xf9,0x00,0x3e,0x40,0x0d,0x90,0x03,0x64,0x40,0xfd,0x10 } }, -{ 16, 0x8d50, 0, {0x3f,0x44,0x0f,0xd1,0x01,0xf4,0x40,0xf9,0x01,0x3f,0xc0,0x0f,0xd1,0x03,0xe6,0x06 } }, -{ 16, 0x8d60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x22,0xe9,0x88,0xb2,0x40 } }, -{ 16, 0x8d70, 0, {0x0f,0x90,0x03,0x24,0x16,0xc9,0x8c,0x36,0x7b,0x8f,0x9c,0x83,0xa7,0x90,0xc9,0x00 } }, -{ 16, 0x8d80, 0, {0x3e,0x50,0x04,0x94,0x13,0x24,0x50,0xc9,0xe0,0x3e,0x50,0x0f,0x90,0x03,0x06,0x00 } }, -{ 16, 0x8d90, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe2,0x80,0x88,0xa0,0x22,0x28 } }, -{ 16, 0x8da0, 0, {0x0b,0x8a,0x02,0x2a,0x80,0x88,0xa4,0x22,0x30,0x08,0x8e,0x0a,0x22,0x02,0x88,0xa0 } }, -{ 16, 0x8db0, 0, {0x2e,0x28,0x88,0xaa,0x12,0x22,0x90,0x88,0xf4,0x2e,0x20,0x0b,0xc8,0x02,0x0e,0x04 } }, -{ 16, 0x8dc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xd4,0x20,0xa5,0x08,0x21,0x42 } }, -{ 16, 0x8dd0, 0, {0x0b,0x50,0x82,0x14,0x31,0x85,0x08,0x25,0x40,0x0a,0x50,0x22,0x94,0x40,0x85,0x08 } }, -{ 16, 0x8de0, 0, {0x6d,0x40,0x08,0x50,0x02,0x54,0x02,0x95,0x00,0x2d,0x48,0x0b,0x50,0x82,0x42,0x01 } }, -{ 16, 0x8df0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0x84,0x00,0x8d,0x10,0x23,0x40 } }, -{ 16, 0x8e00, 0, {0x0b,0xd0,0x00,0x34,0x01,0x8d,0x00,0x23,0x41,0x58,0xd0,0x02,0x34,0x00,0x8d,0x08 } }, -{ 16, 0x8e10, 0, {0x2f,0x50,0x08,0xd2,0x02,0x74,0x80,0x9d,0x00,0x2f,0x48,0x0b,0xdc,0x02,0x46,0x04 } }, -{ 16, 0x8e20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x40,0xe9,0xc0,0x32,0x40 } }, -{ 16, 0x8e30, 0, {0x0f,0x90,0x09,0x26,0x00,0xc9,0x04,0x36,0x40,0x1f,0x90,0x23,0xa4,0x08,0xc9,0x40 } }, -{ 16, 0x8e40, 0, {0x3e,0x40,0x0c,0x94,0x0b,0x64,0x20,0xd9,0x02,0x3e,0x41,0x0f,0x94,0x03,0x68,0x04 } }, -{ 16, 0x8e50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x80,0x3e,0x40 } }, -{ 16, 0x8e60, 0, {0x0f,0x14,0x03,0xc5,0x08,0xf9,0x00,0x3e,0x40,0x1f,0x90,0x23,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0x8e70, 0, {0x3c,0x40,0xaf,0x98,0x03,0x86,0x00,0xe9,0x00,0x3e,0x40,0x0f,0x10,0x0b,0x8a,0x00 } }, -{ 16, 0x8e80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xb0,0x00,0xdc,0x40,0xb3,0x00 } }, -{ 16, 0x8e90, 0, {0x0f,0xc0,0x03,0x31,0x02,0xc4,0x04,0xb1,0x00,0x3c,0x40,0x03,0x10,0x00,0xfc,0x40 } }, -{ 16, 0x8ea0, 0, {0x33,0x00,0x0c,0xc4,0x03,0xb1,0x00,0xcc,0x00,0xb3,0x00,0x0c,0xc4,0x03,0xca,0x04 } }, -{ 16, 0x8eb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x8a,0x80,0x22,0xa0 } }, -{ 16, 0x8ec0, 0, {0x0b,0xa0,0x02,0x2a,0x00,0x8a,0x84,0x22,0xa1,0x08,0xa0,0x02,0x28,0x08,0xba,0x01 } }, -{ 16, 0x8ed0, 0, {0x22,0x80,0x08,0xa0,0x2b,0x28,0x00,0x8a,0x80,0x2a,0x80,0x08,0xe0,0x02,0xca,0x00 } }, -{ 16, 0x8ee0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x02,0x9b,0x81,0x20,0xe0 } }, -{ 16, 0x8ef0, 0, {0x8b,0x38,0x06,0xce,0x00,0x93,0x80,0x20,0xc0,0x08,0x38,0x02,0x0c,0x00,0xb3,0x80 } }, -{ 16, 0x8f00, 0, {0x6c,0xe0,0x0a,0xb0,0x02,0x4c,0x00,0x93,0x00,0x20,0xe0,0x08,0x30,0x02,0xca,0x00 } }, -{ 16, 0x8f10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x10,0x04,0x80,0x08,0x21,0x02 } }, -{ 16, 0x8f20, 0, {0x4b,0x44,0x06,0xd0,0x20,0x90,0x08,0x21,0x02,0x80,0x44,0x02,0x10,0x00,0xb4,0xc0 } }, -{ 16, 0x8f30, 0, {0x2d,0x10,0x48,0x40,0x02,0x00,0x00,0x94,0x89,0x29,0x30,0x08,0x40,0x02,0xe8,0x00 } }, -{ 16, 0x8f40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x32,0x00,0xd6,0x80,0x31,0xa0 } }, -{ 16, 0x8f50, 0, {0x0f,0xe8,0x0b,0xca,0x00,0xd6,0x80,0x23,0xa0,0x04,0xf8,0x0b,0x1a,0x00,0xff,0x80 } }, -{ 16, 0x8f60, 0, {0xbf,0xa0,0x2e,0xc8,0x13,0xda,0x02,0x5e,0x80,0x73,0xa0,0x2c,0x78,0x03,0xea,0x02 } }, -{ 16, 0x8f70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0x8f80, 0, {0x0f,0x90,0x03,0x24,0x00,0xe9,0x00,0x3e,0x40,0x0e,0x80,0x03,0xe4,0x00,0xf8,0x00 } }, -{ 16, 0x8f90, 0, {0x32,0x40,0x0f,0xb0,0x03,0xe4,0x01,0xe9,0x04,0x36,0x40,0x0f,0x80,0x03,0xc2,0x06 } }, -{ 16, 0x8fa0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xcd,0x80,0x33,0x60 } }, -{ 16, 0x8fb0, 0, {0x0c,0xd8,0x43,0x36,0x00,0xcd,0x80,0x33,0x60,0x0c,0xd9,0x23,0xbe,0x00,0x4d,0x80 } }, -{ 16, 0x8fc0, 0, {0x33,0x60,0x08,0xf8,0x0b,0x3e,0x00,0xfd,0x84,0x3f,0x60,0x0f,0xf9,0x03,0xc0,0x00 } }, -{ 16, 0x8fd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x90,0x04,0xde,0x00,0x23,0x80 } }, -{ 16, 0x8fe0, 0, {0x08,0x60,0x02,0xb8,0x20,0x8e,0x04,0x23,0x80,0x08,0x68,0x02,0x10,0x00,0x8e,0x20 } }, -{ 16, 0x8ff0, 0, {0x23,0x82,0x08,0x40,0x02,0x12,0x00,0xf6,0x00,0x2d,0x80,0x0b,0x41,0xa0,0xea,0x04 } }, -{ 16, 0x9000, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x84,0x00,0x21,0x00 } }, -{ 16, 0x9010, 0, {0x08,0x41,0x02,0x50,0x40,0x94,0x00,0x21,0x00,0x0a,0x52,0x02,0xd8,0x00,0x85,0x02 } }, -{ 16, 0x9020, 0, {0x25,0x04,0x08,0x40,0x22,0x18,0x08,0xb4,0x00,0x2d,0x10,0x0b,0x78,0x40,0xc0,0x00 } }, -{ 16, 0x9030, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xee,0x22,0x93,0x00,0x20,0xc0 } }, -{ 16, 0x9040, 0, {0x08,0x38,0x02,0xec,0x00,0x93,0x00,0x20,0xc1,0x2a,0x20,0x02,0x64,0x02,0x82,0x10 } }, -{ 16, 0x9050, 0, {0x24,0xf0,0x0a,0x3c,0x42,0x24,0x28,0xb3,0x00,0x2c,0xe0,0x0b,0x88,0x82,0xc8,0x04 } }, -{ 16, 0x9060, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xad,0x00,0xcb,0x00,0xb2,0xc0 } }, -{ 16, 0x9070, 0, {0xac,0xbe,0x03,0x6e,0x02,0xdb,0x00,0xb2,0xc0,0x1e,0xa0,0x03,0xe4,0x00,0xca,0x11 } }, -{ 16, 0x9080, 0, {0xb6,0xd0,0xac,0xbc,0x03,0x24,0x00,0xfb,0x00,0x3e,0xc0,0xcf,0x84,0x03,0xea,0x04 } }, -{ 16, 0x9090, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe0,0x40,0xf8,0x00,0x3c,0x00 } }, -{ 16, 0x90a0, 0, {0x2f,0x82,0x03,0xa0,0x00,0xe8,0x00,0x3e,0x00,0x1d,0x90,0x13,0xa8,0x00,0xf9,0x00 } }, -{ 16, 0x90b0, 0, {0x3a,0x00,0x81,0x83,0x43,0xe8,0x00,0xe8,0x03,0x3e,0x04,0x0f,0xb0,0x03,0xe0,0x00 } }, -{ 16, 0x90c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xe0,0x00,0xd6,0x00,0x37,0x80 } }, -{ 16, 0x90d0, 0, {0x0c,0xa0,0x03,0xf8,0x00,0xce,0x00,0x33,0x80,0x0d,0xa0,0x13,0x20,0x08,0xce,0x00 } }, -{ 16, 0x90e0, 0, {0x33,0x82,0x0c,0x40,0x73,0x30,0x18,0xce,0x00,0x1f,0x80,0x4f,0xc1,0x43,0x00,0x44 } }, -{ 16, 0x90f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x7c,0x00,0x8d,0x00,0x23,0x40 } }, -{ 16, 0x9100, 0, {0x0a,0xd0,0x02,0xf4,0x00,0x8d,0x00,0x23,0x40,0x08,0xd4,0x80,0x3e,0x42,0x8d,0x40 } }, -{ 16, 0x9110, 0, {0x23,0x40,0x08,0xf0,0x02,0x3e,0x40,0x8d,0x00,0x0f,0x40,0x0b,0xf4,0x02,0x20,0x40 } }, -{ 16, 0x9120, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x99,0x00,0xa6,0x40 } }, -{ 16, 0x9130, 0, {0x08,0x90,0x06,0xe4,0x00,0x91,0x00,0x20,0x40,0x88,0x00,0x02,0x24,0x08,0x80,0x40 } }, -{ 16, 0x9140, 0, {0x20,0x40,0x0a,0xb0,0x02,0x24,0x00,0x89,0x00,0x0e,0x40,0x0b,0x84,0x02,0x20,0x00 } }, -{ 16, 0x9150, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x82,0x00,0x20,0x80 } }, -{ 16, 0x9160, 0, {0x0a,0x21,0x06,0xc8,0x01,0x82,0x00,0x20,0x80,0x08,0x32,0x82,0x08,0x08,0x83,0x00 } }, -{ 16, 0x9170, 0, {0x60,0x80,0x0a,0x00,0x12,0x08,0x80,0x82,0x00,0x2c,0x80,0x0b,0x30,0x0a,0x02,0x01 } }, -{ 16, 0x9180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xd8,0x00,0x36,0x00 } }, -{ 16, 0x9190, 0, {0x0c,0x84,0x23,0xe0,0x00,0xc8,0x00,0x32,0x00,0x0d,0x82,0x0b,0x20,0x02,0xc8,0x00 } }, -{ 16, 0x91a0, 0, {0x32,0x00,0x0e,0x00,0x03,0x20,0x02,0xc8,0x00,0x3e,0x00,0x0f,0x80,0x03,0x00,0x03 } }, -{ 16, 0x91b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xbf,0x00,0x3f,0xc0 } }, -{ 16, 0x91c0, 0, {0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00,0xbf,0xc0,0x8f,0xb0,0x03,0xfc,0x08,0xff,0x02 } }, -{ 16, 0x91d0, 0, {0x3f,0xc0,0x0d,0xf0,0x03,0xed,0x00,0xff,0x02,0x3f,0xc0,0x0f,0xf0,0x03,0xe8,0x06 } }, -{ 16, 0x91e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf0,0x8c,0xff,0x00,0x3d,0x60 } }, -{ 16, 0x91f0, 0, {0x2c,0xb2,0x83,0x7c,0x90,0xdf,0x38,0x31,0xe0,0x0f,0xf8,0x03,0x3c,0x00,0xff,0x20 } }, -{ 16, 0x9200, 0, {0x3f,0xc4,0x0e,0xf4,0x03,0x7c,0x00,0xf4,0x80,0x33,0x00,0x0d,0xf8,0x03,0xf0,0x00 } }, -{ 16, 0x9210, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe1,0x20,0xbb,0x62,0x2e,0x42 } }, -{ 16, 0x9220, 0, {0x28,0xf4,0x42,0x3e,0x40,0x8f,0x44,0x22,0xe0,0x0b,0xb0,0x83,0x7f,0x44,0xbf,0xc1 } }, -{ 16, 0x9230, 0, {0x2d,0xdc,0x2a,0xf6,0x02,0x3f,0x45,0xb8,0x80,0x22,0x61,0x88,0xb8,0x02,0xe0,0x04 } }, -{ 16, 0x9240, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc5,0x80,0xb2,0x18,0x2e,0xc8 } }, -{ 16, 0x9250, 0, {0x29,0x30,0x32,0x0c,0x08,0xb3,0x20,0x20,0xc0,0x4b,0x92,0x02,0x0c,0x00,0xb3,0x40 } }, -{ 16, 0x9260, 0, {0x2c,0xc0,0x89,0x34,0x12,0x4c,0x00,0xb0,0x00,0x24,0xc1,0x49,0x30,0x02,0xe2,0x01 } }, -{ 16, 0x9270, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xa4,0x00,0xba,0x0c,0x2e,0xe0 } }, -{ 16, 0x9280, 0, {0xa9,0xb0,0x06,0x2c,0x00,0x8b,0x00,0xa2,0xc0,0x0b,0x90,0x00,0x6c,0x00,0xbb,0x00 } }, -{ 16, 0x9290, 0, {0x2e,0xc0,0x0b,0x30,0x02,0x6c,0x00,0xba,0x80,0x26,0xf0,0x08,0xb0,0x02,0xf0,0x04 } }, -{ 16, 0x92a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xee,0x00,0xfb,0xc4,0x3e,0x78 } }, -{ 16, 0x92b0, 0, {0x2d,0xb0,0x03,0x6c,0x08,0xfb,0x00,0x32,0xc0,0x8b,0x24,0x83,0x2c,0x00,0xfb,0x00 } }, -{ 16, 0x92c0, 0, {0x3e,0xc0,0x8f,0xb0,0x0b,0x6c,0x08,0xb2,0xe0,0x16,0x60,0x8d,0xb0,0x23,0xd0,0x04 } }, -{ 16, 0x92d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbe,0x98,0xff,0x40,0x3f,0xc0 } }, -{ 16, 0x92e0, 0, {0x0e,0x70,0x03,0xdc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xe0,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0x92f0, 0, {0x3f,0xc0,0x0e,0xf0,0x03,0xac,0x00,0xfe,0x00,0xb9,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0x9300, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xad,0x00,0xfa,0x40,0x3e,0xd0 } }, -{ 16, 0x9310, 0, {0x0e,0xb2,0x03,0xec,0x00,0xc3,0x00,0x3e,0xc0,0x0c,0xa0,0x03,0x2c,0x01,0xfb,0x00 } }, -{ 16, 0x9320, 0, {0x3c,0xc0,0x0e,0xb8,0x03,0xec,0x00,0xda,0x00,0x3a,0xd0,0x4f,0xb0,0x23,0xd0,0x04 } }, -{ 16, 0x9330, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xba,0x00,0x2c,0xc0 } }, -{ 16, 0x9340, 0, {0x08,0xf4,0x07,0xbc,0x14,0xdf,0x00,0x3e,0xc0,0x1a,0xa0,0x52,0xbc,0x00,0xbf,0x04 } }, -{ 16, 0x9350, 0, {0x3f,0xc0,0x8a,0xf0,0x03,0xbc,0x00,0xfa,0x00,0x22,0xc8,0x0f,0xb0,0x03,0xf2,0x00 } }, -{ 16, 0x9360, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x48,0x01,0xb1,0x00,0x6c,0xc2 } }, -{ 16, 0x9370, 0, {0x0a,0x30,0x42,0xcc,0x00,0x83,0x05,0x2c,0xc0,0x08,0x30,0x02,0x8c,0x01,0xb3,0x04 } }, -{ 16, 0x9380, 0, {0x2c,0xc0,0x0a,0x30,0x22,0x8c,0x00,0x80,0x80,0x28,0xc0,0x0b,0x30,0x22,0xf8,0x00 } }, -{ 16, 0x9390, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x08,0xb7,0x80,0x6f,0xe0 } }, -{ 16, 0x93a0, 0, {0x18,0x78,0x02,0x8e,0x40,0xb7,0x80,0x2d,0xe0,0x0a,0x78,0x02,0x9e,0x00,0xb7,0x80 } }, -{ 16, 0x93b0, 0, {0x29,0xe1,0x0a,0x78,0x02,0x9e,0x01,0xbc,0x80,0x29,0xe4,0x0b,0x78,0x02,0xc8,0x00 } }, -{ 16, 0x93c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x09,0x40,0xf1,0x20,0x3c,0xc4 } }, -{ 16, 0x93d0, 0, {0x0e,0x39,0x02,0xcc,0x00,0xc3,0x00,0x2c,0xc4,0x08,0x92,0x03,0x8c,0x88,0xb3,0x10 } }, -{ 16, 0x93e0, 0, {0x2c,0xc4,0x0e,0xb0,0x07,0x8c,0x00,0xc2,0x08,0x38,0xc0,0x0f,0x30,0x43,0xd2,0x02 } }, -{ 16, 0x93f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x10,0xfc,0x00,0x7f,0xc0 } }, -{ 16, 0x9400, 0, {0x0f,0xf0,0x83,0xfc,0x21,0xdf,0x08,0x3b,0xc0,0x8f,0x90,0x01,0xfc,0x21,0xff,0x0c } }, -{ 16, 0x9410, 0, {0x3f,0xc2,0x0f,0xf1,0x03,0xec,0x00,0xef,0x00,0x77,0xc0,0x1e,0xf0,0x03,0x90,0x06 } }, -{ 16, 0x9420, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe8,0x01,0xf9,0x00,0x32,0xc0 } }, -{ 16, 0x9430, 0, {0x0f,0xb2,0x03,0xee,0x90,0xdb,0xe1,0x3a,0xc0,0x4d,0x38,0x13,0x2d,0x30,0xfb,0x00 } }, -{ 16, 0x9440, 0, {0x3e,0xe0,0x4f,0xba,0x43,0x2c,0x40,0xfa,0x00,0x3f,0xc0,0x8c,0xb0,0x03,0xea,0x00 } }, -{ 16, 0x9450, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0xb1,0x00,0x21,0xc0 } }, -{ 16, 0x9460, 0, {0x0b,0x71,0x02,0xcc,0x20,0xa7,0x28,0x21,0xc0,0x0b,0x70,0x13,0x5c,0x08,0xb7,0x10 } }, -{ 16, 0x9470, 0, {0x2d,0xc4,0x4b,0x34,0x83,0x1c,0xc1,0xb7,0x02,0x2d,0xc0,0x1a,0x70,0x02,0xd2,0x04 } }, -{ 16, 0x9480, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x20,0xb4,0xc4,0x25,0xa2 } }, -{ 16, 0x9490, 0, {0x0b,0x78,0x06,0xde,0x00,0x83,0x80,0x29,0xe0,0x1b,0xf8,0x02,0x5e,0x80,0xa7,0xa0 } }, -{ 16, 0x94a0, 0, {0x2d,0xc8,0x0a,0x72,0x02,0x1e,0x00,0xa6,0x80,0x28,0xe0,0x08,0x78,0x02,0xf0,0x00 } }, -{ 16, 0x94b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xed,0x00,0xb3,0x40,0x24,0xc3 } }, -{ 16, 0x94c0, 0, {0x0b,0x30,0x42,0xcc,0x00,0xa3,0x00,0x20,0xc0,0x1b,0x34,0x02,0x4c,0x00,0xb3,0x00 } }, -{ 16, 0x94d0, 0, {0x2c,0xc0,0x4b,0x30,0x02,0x0c,0x00,0xb3,0x88,0x2c,0xd4,0x0a,0x30,0x02,0xd2,0x04 } }, -{ 16, 0x94e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xfe,0x40,0xb7,0xa0 } }, -{ 16, 0x94f0, 0, {0x0f,0xa0,0x03,0xe8,0x00,0xda,0x00,0x3a,0x80,0x0f,0xe2,0x03,0x68,0x00,0xfa,0x00 } }, -{ 16, 0x9500, 0, {0x3e,0x80,0x0f,0xa0,0x0b,0x28,0x00,0xee,0xe0,0x3f,0xb0,0x04,0xa0,0x03,0xfa,0x04 } }, -{ 16, 0x9510, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x04,0xf0,0x08,0x3a,0x10 } }, -{ 16, 0x9520, 0, {0x0f,0x84,0x03,0xe0,0x10,0xf8,0x00,0x3e,0x00,0x4f,0x80,0x83,0xe0,0x00,0xf8,0x00 } }, -{ 16, 0x9530, 0, {0x3c,0x00,0x0f,0x80,0x03,0x80,0x00,0xf8,0x40,0x3e,0x09,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0x9540, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x20,0xe9,0x00,0x32,0x44 } }, -{ 16, 0x9550, 0, {0x0c,0x90,0x03,0x24,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x13,0xe4,0x00,0xb9,0x00 } }, -{ 16, 0x9560, 0, {0x1e,0x40,0x0c,0x10,0x03,0x24,0x00,0xc9,0xa0,0x3c,0x64,0x0c,0x90,0x03,0x82,0x04 } }, -{ 16, 0x9570, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x68 } }, -{ 16, 0x9580, 0, {0x08,0x13,0x02,0x24,0x08,0xf9,0x00,0x2e,0x48,0x1b,0x90,0x02,0xe4,0x00,0xb9,0x00 } }, -{ 16, 0x9590, 0, {0x3e,0x40,0x0c,0x90,0x02,0x24,0x08,0xf9,0x40,0x2e,0x60,0x0a,0x90,0x06,0xe0,0x00 } }, -{ 16, 0x95a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xa9,0x00,0x20,0x40 } }, -{ 16, 0x95b0, 0, {0x08,0x90,0x02,0x24,0x00,0xb9,0x01,0x2e,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x00 } }, -{ 16, 0x95c0, 0, {0x2e,0x40,0x08,0x92,0x22,0x24,0x00,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0xc6,0x00 } }, -{ 16, 0x95d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x80,0x81,0x21,0xe0,0x50 } }, -{ 16, 0x95e0, 0, {0x28,0x16,0x0a,0x04,0x80,0xa1,0x40,0x2c,0x40,0x4b,0x14,0x22,0xc4,0x00,0xb1,0x00 } }, -{ 16, 0x95f0, 0, {0x2c,0x50,0x09,0x14,0x02,0x04,0x04,0xb1,0x00,0x2c,0x40,0x0a,0x10,0x02,0xc2,0x01 } }, -{ 16, 0x9600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xe8,0x50,0x32,0x00 } }, -{ 16, 0x9610, 0, {0x8c,0x80,0x02,0x20,0x00,0xb8,0x00,0x3e,0x00,0x0b,0x80,0x33,0xe0,0x10,0xf8,0x00 } }, -{ 16, 0x9620, 0, {0x3e,0x00,0x0c,0x80,0x03,0x20,0x08,0xca,0x00,0x3e,0x00,0x0c,0x80,0x03,0xae,0x03 } }, -{ 16, 0x9630, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xfc,0x40,0xfd,0x10,0x2f,0x41 } }, -{ 16, 0x9640, 0, {0x4f,0x91,0x03,0xe4,0x40,0xf9,0x40,0x3e,0x40,0x4f,0xd0,0x63,0xe5,0x00,0xf9,0x40 } }, -{ 16, 0x9650, 0, {0x3a,0x50,0x2e,0x94,0x03,0x65,0x00,0xed,0x00,0x3f,0x50,0x0f,0x90,0x03,0xe6,0x06 } }, -{ 16, 0x9660, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xe6,0x00,0xf9,0xe0,0x33,0x50 } }, -{ 16, 0x9670, 0, {0x0c,0xda,0x03,0xa6,0x00,0xd9,0x80,0x3f,0x40,0x0f,0x91,0x03,0xa6,0x00,0xf9,0x88 } }, -{ 16, 0x9680, 0, {0x3e,0x68,0x0c,0xde,0x03,0x66,0x00,0xed,0x00,0x3b,0x69,0x0c,0x90,0x03,0xc6,0x00 } }, -{ 16, 0x9690, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe1,0x08,0xb8,0xe0,0x20,0x20 } }, -{ 16, 0x96a0, 0, {0x18,0x8e,0x26,0xe1,0x00,0x80,0xa0,0x2e,0x00,0x4b,0x88,0x42,0xe1,0x50,0xb8,0x40 } }, -{ 16, 0x96b0, 0, {0x2e,0x2a,0x0d,0x0a,0x02,0x20,0x08,0xb8,0x00,0x2e,0x14,0x0d,0x80,0x02,0xce,0x04 } }, -{ 16, 0x96c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x60,0x20,0x40 } }, -{ 16, 0x96d0, 0, {0x08,0x31,0xa2,0xc5,0x00,0x91,0x48,0x2c,0x40,0x1b,0x12,0x02,0x84,0x00,0xb1,0x00 } }, -{ 16, 0x96e0, 0, {0x2c,0x50,0x09,0x16,0x02,0x05,0x00,0xa3,0x04,0x28,0x40,0x08,0x10,0x02,0xc2,0x01 } }, -{ 16, 0x96f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa4,0x00,0xb9,0x08,0x20,0x70 } }, -{ 16, 0x9700, 0, {0x28,0x90,0x02,0xe4,0x00,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0xe4,0x08,0xb9,0x03 } }, -{ 16, 0x9710, 0, {0x2c,0x40,0x29,0x90,0x02,0x64,0x00,0xb9,0x00,0x2e,0x62,0x09,0x90,0x02,0xc6,0x04 } }, -{ 16, 0x9720, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe5,0x00,0xf9,0xd0,0xb2,0x70 } }, -{ 16, 0x9730, 0, {0x08,0x90,0x03,0xe4,0x00,0xd9,0x04,0x3e,0x40,0x0f,0x90,0x03,0xa4,0x10,0xf9,0x02 } }, -{ 16, 0x9740, 0, {0x3e,0x40,0x0d,0x90,0x2b,0x64,0x00,0xe9,0x8d,0x3a,0x60,0x0c,0x90,0x03,0xe8,0x04 } }, -{ 16, 0x9750, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x80,0x3e,0x42 } }, -{ 16, 0x9760, 0, {0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x9a,0x03,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0x9770, 0, {0x3e,0x40,0x2f,0x10,0x03,0xa4,0x00,0xf9,0x22,0x3c,0x40,0x4f,0x90,0x03,0xca,0x00 } }, -{ 16, 0x9780, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf0,0x40,0x32,0x00 } }, -{ 16, 0x9790, 0, {0x0c,0x80,0x03,0xc0,0x00,0xf8,0x00,0x32,0x20,0x1f,0x80,0x03,0xe0,0x00,0xc8,0x00 } }, -{ 16, 0x97a0, 0, {0x32,0x00,0x0c,0x80,0x02,0x20,0x00,0xc8,0xc0,0x3e,0x00,0x0c,0x80,0x03,0xca,0x04 } }, -{ 16, 0x97b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x15,0x28,0x10,0xba,0x00,0x23,0xa0 } }, -{ 16, 0x97c0, 0, {0x0a,0xe4,0x02,0xe8,0x00,0xba,0x00,0x2b,0xa1,0x0b,0xa0,0x02,0xe8,0x00,0xaa,0x00 } }, -{ 16, 0x97d0, 0, {0x2a,0x81,0x0a,0xa0,0x03,0xe8,0x08,0xde,0x00,0x2e,0x80,0x0a,0xa0,0x02,0xca,0x00 } }, -{ 16, 0x97e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x04,0xa0,0xb1 } }, -{ 16, 0x97f0, 0, {0x08,0x36,0x22,0xcc,0x00,0xb3,0x00,0x20,0xe4,0x0b,0x30,0x02,0xcc,0x00,0x83,0x00 } }, -{ 16, 0x9800, 0, {0x20,0xc0,0x08,0x18,0x02,0x0c,0x00,0x91,0x01,0x2c,0xc0,0x08,0x30,0x06,0xca,0x00 } }, -{ 16, 0x9810, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0xc8,0xb3,0x21,0x21,0xc2 } }, -{ 16, 0x9820, 0, {0x2a,0x70,0x02,0xdc,0x00,0xb7,0xa0,0x29,0xc0,0x0b,0x72,0x02,0xce,0x00,0xa7,0x81 } }, -{ 16, 0x9830, 0, {0x29,0xc0,0x4a,0x74,0x02,0xfe,0x00,0x97,0x01,0x2c,0xc0,0x0a,0x70,0x12,0xe8,0x00 } }, -{ 16, 0x9840, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x80,0xf7,0xc0,0x31,0xe0 } }, -{ 16, 0x9850, 0, {0x0c,0x48,0x03,0xde,0x11,0xf7,0x80,0x21,0xe0,0x0b,0x7a,0x03,0xde,0x00,0xc3,0x80 } }, -{ 16, 0x9860, 0, {0x33,0xd8,0x6c,0x78,0x03,0x3e,0x00,0xd6,0x80,0x3d,0xe0,0x0c,0x78,0x03,0xea,0x02 } }, -{ 16, 0x9870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0d,0xac,0x08,0xfb,0x80,0x3e,0xc0 } }, -{ 16, 0x9880, 0, {0x0f,0xd0,0x03,0xec,0x04,0xfb,0x3c,0x3e,0xc0,0x0f,0xb6,0x07,0x6c,0x01,0xfb,0x00 } }, -{ 16, 0x9890, 0, {0x3e,0xd0,0x0f,0x94,0x07,0xec,0x01,0xea,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xc2,0x06 } }, -{ 16, 0x98a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfe,0x00,0xcf,0xa4,0x3b,0x60 } }, -{ 16, 0x98b0, 0, {0x08,0xd9,0x03,0x7e,0x00,0xcf,0x80,0x3f,0x25,0x4f,0xfc,0x87,0xbe,0x00,0xcf,0x80 } }, -{ 16, 0x98c0, 0, {0x7f,0xfc,0x0c,0xfc,0x03,0x7c,0x00,0xf6,0x90,0x33,0xe0,0x0f,0xf8,0x03,0xc0,0x00 } }, -{ 16, 0x98d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x08,0x8f,0x28,0x21,0x40 } }, -{ 16, 0x98e0, 0, {0x08,0xd0,0x02,0x1c,0x40,0xa7,0x20,0x31,0x04,0x1b,0x78,0x02,0xdc,0x80,0xd7,0x00 } }, -{ 16, 0x98f0, 0, {0x2f,0xc4,0x1a,0xd0,0x02,0x1e,0x48,0xb6,0x00,0x61,0xc0,0x0b,0x70,0x06,0xea,0x04 } }, -{ 16, 0x9900, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x00,0x87,0x30,0x69,0x44 } }, -{ 16, 0x9910, 0, {0x08,0x50,0x22,0x0c,0x00,0x87,0x01,0x2d,0x44,0x8b,0x70,0x06,0x8c,0x10,0x87,0x00 } }, -{ 16, 0x9920, 0, {0x29,0xc9,0x08,0x50,0x02,0x1c,0x44,0xa6,0x00,0x61,0xc0,0x0b,0x70,0x02,0xc0,0x00 } }, -{ 16, 0x9930, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcd,0x00,0x83,0x88,0x60,0x40 } }, -{ 16, 0x9940, 0, {0x00,0x10,0x02,0x4c,0x00,0x2b,0x00,0x2c,0x41,0x1b,0x30,0x02,0xcc,0x00,0x93,0x00 } }, -{ 16, 0x9950, 0, {0x2c,0xc0,0x0a,0x30,0x42,0x0c,0x00,0xb2,0x40,0x20,0xf1,0x0b,0x30,0x02,0xc8,0x04 } }, -{ 16, 0x9960, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbd,0x41,0xcf,0xc0,0xba,0xf0 } }, -{ 16, 0x9970, 0, {0x28,0x90,0x1b,0x6c,0x08,0xcf,0x00,0x2c,0xc0,0x0f,0xf0,0x03,0xac,0x00,0x8b,0x00 } }, -{ 16, 0x9980, 0, {0x3f,0xc0,0x6c,0xb0,0x4b,0x2c,0x01,0xfb,0x40,0x22,0xc8,0x0f,0xb0,0x03,0xea,0x04 } }, -{ 16, 0x9990, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x04,0xfb,0x04,0x3f,0xd4 } }, -{ 16, 0x99a0, 0, {0x0f,0x10,0x03,0xac,0x00,0xfb,0x00,0x32,0xc0,0x5f,0xb0,0x03,0xec,0x00,0xfb,0x04 } }, -{ 16, 0x99b0, 0, {0x3e,0xc0,0x4f,0x10,0x13,0xec,0x00,0xfb,0x88,0x3e,0xc0,0x4f,0xb0,0x03,0xe0,0x00 } }, -{ 16, 0x99c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xc7,0x00,0x33,0x62 } }, -{ 16, 0x99d0, 0, {0x0c,0xc0,0x0b,0x3c,0x00,0xef,0x00,0x33,0xe0,0x1c,0xf0,0x13,0x3c,0x08,0xf7,0x00 } }, -{ 16, 0x99e0, 0, {0x31,0xc0,0x0e,0xd8,0x03,0xbc,0x00,0xfe,0x00,0x3d,0xc6,0x0c,0xf0,0x03,0xc0,0x44 } }, -{ 16, 0x99f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x00,0xcb,0x03,0x22,0x47 } }, -{ 16, 0x9a00, 0, {0x08,0x98,0x42,0x2c,0x00,0x9b,0x00,0x2a,0xc0,0x0a,0xb0,0x02,0x2c,0x00,0xbb,0x04 } }, -{ 16, 0x9a10, 0, {0x2a,0xc0,0x0a,0xb0,0x02,0xac,0x08,0xfa,0x00,0x2e,0x60,0x08,0xb0,0x02,0xe0,0x40 } }, -{ 16, 0x9a20, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x9b,0x00,0x20,0x40 } }, -{ 16, 0x9a30, 0, {0x08,0x98,0x02,0x2c,0x00,0xbb,0x00,0x22,0x88,0x08,0x30,0x02,0x2c,0x00,0xbb,0x00 } }, -{ 16, 0x9a40, 0, {0x22,0xc0,0x8a,0x92,0x02,0xac,0x00,0xaa,0x80,0x2e,0xc0,0x08,0xb0,0x06,0xe0,0x00 } }, -{ 16, 0x9a50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x00,0xa0,0x40 } }, -{ 16, 0x9a60, 0, {0x08,0x10,0x02,0x0c,0x00,0xb3,0x00,0x28,0x80,0x0a,0x32,0x12,0x0c,0x00,0xb3,0x04 } }, -{ 16, 0x9a70, 0, {0x28,0xc0,0x0a,0x30,0x22,0x8c,0x20,0xb2,0x00,0x2c,0xc0,0x08,0x30,0x02,0xc2,0x01 } }, -{ 16, 0x9a80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x02,0xcb,0x00,0x30,0x40 } }, -{ 16, 0x9a90, 0, {0x1c,0x94,0x03,0x2c,0x00,0xef,0x00,0x32,0xc0,0x88,0xf0,0x8b,0x2c,0x00,0xfb,0x00 } }, -{ 16, 0x9aa0, 0, {0x33,0xc0,0xae,0xf0,0x03,0xac,0x80,0xea,0x01,0x3e,0xc0,0x2c,0xb0,0x03,0xc0,0x03 } }, -{ 16, 0x9ab0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xff,0x00,0x2f,0x40 } }, -{ 16, 0x9ac0, 0, {0x07,0xd2,0x83,0xfc,0x00,0xdf,0x04,0x3f,0xc0,0x0f,0xb0,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0x9ad0, 0, {0x3f,0xc0,0x0f,0xd0,0x0b,0xec,0x00,0xee,0x00,0x3f,0x40,0x0f,0xf0,0x03,0xe8,0x06 } }, -{ 16, 0x9ae0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf5,0x00,0xcf,0x08,0x3f,0x48 } }, -{ 16, 0x9af0, 0, {0x0f,0xc3,0x93,0x70,0xd0,0xdc,0x30,0x3f,0xd8,0x0c,0xb2,0x03,0x3c,0xc0,0xff,0x40 } }, -{ 16, 0x9b00, 0, {0x33,0xc4,0x2c,0xf1,0x03,0x62,0x50,0xfc,0x34,0x33,0x00,0x0f,0x5c,0x03,0xf0,0x00 } }, -{ 16, 0x9b10, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xc4,0x80,0x8b,0x00,0x2f,0x5a } }, -{ 16, 0x9b20, 0, {0x0b,0xa6,0x12,0x21,0xc0,0x89,0x70,0x2f,0xdc,0x08,0xf2,0xc2,0x3d,0xd0,0xbf,0x40 } }, -{ 16, 0x9b30, 0, {0x37,0xdc,0x88,0xf5,0x0a,0x20,0x80,0xe8,0x10,0x2a,0x16,0x0b,0x90,0x02,0xe0,0x04 } }, -{ 16, 0x9b40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x00,0x83,0x08,0x2c,0x44 } }, -{ 16, 0x9b50, 0, {0x0b,0x02,0x02,0x0c,0x00,0x80,0x00,0x2c,0xc8,0x08,0x33,0x42,0x8c,0x90,0xb3,0x30 } }, -{ 16, 0x9b60, 0, {0x28,0xc8,0x4a,0x32,0x12,0x80,0x0c,0xb0,0xa0,0x28,0x28,0x0b,0x12,0x02,0xe2,0x01 } }, -{ 16, 0x9b70, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa2,0x00,0x8b,0x00,0x2e,0x48 } }, -{ 16, 0x9b80, 0, {0x0b,0xa0,0x22,0x20,0x20,0x88,0x80,0x2e,0xc0,0x28,0xb0,0x0a,0xac,0x00,0xbb,0x00 } }, -{ 16, 0x9b90, 0, {0x2e,0xc0,0x0a,0xb0,0x02,0xa0,0x00,0xab,0x82,0x2a,0xa0,0x0b,0xb2,0x02,0xf0,0x04 } }, -{ 16, 0x9ba0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe7,0x00,0xcb,0x00,0x3e,0xc0 } }, -{ 16, 0x9bb0, 0, {0xcf,0x9c,0x0b,0x21,0x00,0xd8,0x88,0x3e,0xc0,0x0c,0xb0,0x03,0xac,0x00,0xfb,0x00 } }, -{ 16, 0x9bc0, 0, {0x3a,0xc0,0x0e,0xb0,0x43,0xe8,0x40,0xf8,0x80,0x3a,0x60,0x0f,0x98,0x03,0xd0,0x04 } }, -{ 16, 0x9bd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb4,0x00,0xff,0x00,0x0f,0xe0 } }, -{ 16, 0x9be0, 0, {0x07,0xa1,0x03,0xe8,0x02,0xfb,0x00,0x3f,0xc0,0x0f,0x70,0x23,0x7c,0x00,0xff,0x02 } }, -{ 16, 0x9bf0, 0, {0x35,0xc0,0x4d,0xb0,0x03,0x74,0x20,0xfc,0x01,0x3f,0x00,0x0f,0xf8,0x03,0xf8,0x00 } }, -{ 16, 0x9c00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa5,0x00,0xcb,0x00,0xba,0x40 } }, -{ 16, 0x9c10, 0, {0x0c,0x14,0x0b,0x2f,0x22,0xc9,0x40,0x32,0xc0,0x8e,0xb0,0x03,0xac,0x00,0xfb,0x00 } }, -{ 16, 0x9c20, 0, {0x3e,0xc0,0x0e,0xb0,0x03,0xe4,0x00,0xc9,0x00,0x32,0x00,0x2c,0x90,0x03,0x10,0x04 } }, -{ 16, 0x9c30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x01,0x24,0x00,0x8f,0x00,0x22,0x40 } }, -{ 16, 0x9c40, 0, {0x2c,0xa5,0x42,0x29,0x00,0x8b,0x04,0xa3,0xc1,0x0d,0xf0,0x0a,0x3c,0x00,0xbf,0x00 } }, -{ 16, 0x9c50, 0, {0x3f,0xc0,0x08,0xf0,0x01,0x69,0x00,0xda,0x05,0x22,0xd0,0x08,0x94,0x03,0x72,0x00 } }, -{ 16, 0x9c60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x60,0x40,0x83,0x01,0x20,0xc0 } }, -{ 16, 0x9c70, 0, {0x09,0x00,0x02,0x20,0x00,0x82,0x60,0x22,0xc0,0x08,0x30,0x42,0x4c,0x10,0xbb,0x02 } }, -{ 16, 0x9c80, 0, {0x2c,0xc0,0x08,0xb0,0x12,0x05,0x00,0x9b,0x00,0x20,0x82,0x09,0x32,0x02,0x38,0x00 } }, -{ 16, 0x9c90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x90,0x87,0x80,0x20,0xe0 } }, -{ 16, 0x9ca0, 0, {0x08,0x58,0x02,0x16,0x14,0x84,0x81,0x21,0xe0,0x29,0x39,0x02,0x5e,0x00,0xb7,0x80 } }, -{ 16, 0x9cb0, 0, {0x28,0xe0,0x08,0x78,0x02,0x7a,0x80,0x96,0x81,0x21,0xe0,0x09,0xf8,0x02,0x48,0x00 } }, -{ 16, 0x9cc0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x09,0x8b,0x10,0x38,0x44 } }, -{ 16, 0x9cd0, 0, {0x4d,0x25,0x12,0x0c,0x00,0xc2,0x10,0x22,0xc8,0x0a,0x38,0x03,0xcc,0x00,0xf3,0x10 } }, -{ 16, 0x9ce0, 0, {0x2c,0xc0,0x0c,0x30,0x03,0x8a,0xc0,0xd9,0x10,0x32,0x40,0x2d,0x10,0x03,0x12,0x02 } }, -{ 16, 0x9cf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x80,0xff,0x00,0x3f,0x40 } }, -{ 16, 0x9d00, 0, {0x0f,0xf0,0x03,0xf4,0x40,0xed,0x00,0x3f,0xc0,0x0e,0xf3,0x03,0xbc,0x04,0xff,0x00 } }, -{ 16, 0x9d10, 0, {0x3f,0xc2,0x0f,0xf0,0x0b,0xd4,0x00,0xff,0x10,0xbf,0x80,0x0e,0xf0,0x03,0xd0,0x06 } }, -{ 16, 0x9d20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xfa,0x00,0xcb,0x02,0x3e,0xc0 } }, -{ 16, 0x9d30, 0, {0x0f,0x90,0x03,0xa0,0x00,0xcb,0x00,0x3a,0xca,0x0c,0xb3,0x13,0xaf,0x24,0xcb,0x48 } }, -{ 16, 0x9d40, 0, {0x1e,0xc8,0x0f,0xb6,0x03,0x2c,0x00,0xfa,0x00,0x3e,0xc0,0x0f,0x90,0x03,0xea,0x00 } }, -{ 16, 0x9d50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x08,0x87,0x20,0x2d,0xc4 } }, -{ 16, 0x9d60, 0, {0x0b,0x50,0x12,0xdc,0x04,0x87,0x00,0x2c,0xc0,0x08,0x70,0xa2,0x1d,0x00,0xa7,0x40 } }, -{ 16, 0x9d70, 0, {0x25,0xcb,0x8b,0x74,0x82,0x1c,0x00,0xb7,0x00,0x2d,0xc1,0x0b,0x70,0x02,0xd2,0x04 } }, -{ 16, 0x9d80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x01,0x87,0x90,0x2d,0xe0 } }, -{ 16, 0x9d90, 0, {0x0b,0x78,0x02,0xce,0x00,0x86,0x80,0x2d,0xe4,0x29,0x7a,0x02,0x9e,0x80,0x87,0xa0 } }, -{ 16, 0x9da0, 0, {0x6d,0xe8,0x0b,0x78,0x02,0x1e,0x00,0xb5,0x80,0x2d,0x60,0x0b,0x78,0x02,0xf0,0x00 } }, -{ 16, 0x9db0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcd,0x00,0x83,0x02,0x2c,0xe0 } }, -{ 16, 0x9dc0, 0, {0x0b,0x30,0x02,0xcc,0x00,0x83,0xe0,0x2c,0xc0,0x08,0x30,0x02,0x0c,0x00,0xa3,0x00 } }, -{ 16, 0x9dd0, 0, {0x24,0xc0,0x0b,0xb0,0x02,0x0e,0x20,0xb3,0x08,0x2c,0xc0,0x0b,0x30,0x02,0xd2,0x04 } }, -{ 16, 0x9de0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x82,0xca,0x00,0x3e,0xa8 } }, -{ 16, 0x9df0, 0, {0x0f,0xe0,0x03,0xf8,0x02,0x8e,0x80,0x3e,0x80,0x0d,0xa0,0x5b,0xa8,0x00,0xca,0x00 } }, -{ 16, 0x9e00, 0, {0x3e,0x80,0x0f,0xa0,0x03,0x3b,0x80,0xfe,0x42,0x2f,0x80,0x0f,0xa8,0x03,0xfa,0x04 } }, -{ 16, 0x9e10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x20,0xf8,0x00,0x3e,0x00 } }, -{ 16, 0x9e20, 0, {0x0f,0x06,0x03,0xc0,0x00,0xf8,0x11,0x3e,0x00,0x0f,0x00,0x03,0xe0,0x00,0xf8,0x00 } }, -{ 16, 0x9e30, 0, {0x36,0x00,0x0f,0x80,0x0b,0xe0,0x00,0xf8,0x04,0x3e,0x20,0x0f,0x81,0x03,0xd2,0x00 } }, -{ 16, 0x9e40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0x9e50, 0, {0x0c,0x9a,0x03,0x24,0x40,0xc9,0xc0,0x3e,0x40,0x4c,0x90,0x03,0x24,0x00,0xf9,0x00 } }, -{ 16, 0x9e60, 0, {0x36,0x40,0x07,0x90,0x03,0x24,0x00,0xc9,0x04,0x32,0x60,0x0f,0x90,0x03,0xc2,0x04 } }, -{ 16, 0x9e70, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x02,0x2e,0x40 } }, -{ 16, 0x9e80, 0, {0x0a,0x92,0x02,0x25,0x02,0x89,0xe0,0x2e,0x40,0x98,0x90,0x02,0x24,0x00,0xb9,0x00 } }, -{ 16, 0x9e90, 0, {0x22,0x40,0x09,0x90,0x02,0x04,0x00,0xd9,0x00,0x22,0x44,0x0b,0x9c,0x02,0xe0,0x00 } }, -{ 16, 0x9ea0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x2c,0x00,0xb9,0x00,0x2c,0x40 } }, -{ 16, 0x9eb0, 0, {0x08,0x90,0x02,0x24,0x28,0x89,0x00,0x2c,0x40,0x68,0x90,0x42,0x24,0x0c,0xb1,0x04 } }, -{ 16, 0x9ec0, 0, {0x26,0x40,0x0b,0x90,0x0a,0x2c,0x80,0x81,0x00,0x22,0x40,0xcb,0x92,0x82,0xc6,0x00 } }, -{ 16, 0x9ed0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb1,0x20,0x2c,0x48 } }, -{ 16, 0x9ee0, 0, {0x0a,0x12,0x02,0x04,0x80,0x81,0x21,0x2c,0x4c,0x08,0x11,0x02,0x04,0x08,0xb1,0x10 } }, -{ 16, 0x9ef0, 0, {0x20,0x4c,0x09,0x12,0x02,0x24,0x01,0x91,0x20,0xa0,0x48,0x0b,0x10,0x02,0xc2,0x01 } }, -{ 16, 0x9f00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x41,0xe0,0xf8,0x50,0x3e,0x14 } }, -{ 16, 0x9f10, 0, {0x0c,0x85,0x03,0x21,0x40,0xc8,0x50,0x3e,0x10,0x08,0x06,0x83,0x01,0xf0,0xf8,0x68 } }, -{ 16, 0x9f20, 0, {0x36,0x10,0x0f,0x05,0x03,0x29,0x40,0xc8,0x50,0x32,0x94,0x0f,0x85,0x03,0xee,0x03 } }, -{ 16, 0x9f30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x00,0xf9,0x10,0x3f,0x44 } }, -{ 16, 0x9f40, 0, {0x0f,0xd1,0x0b,0xf4,0x40,0xfd,0x12,0x2e,0x4c,0x03,0x92,0x0b,0xe4,0x00,0xf9,0x20 } }, -{ 16, 0x9f50, 0, {0x3e,0x4c,0x0f,0x91,0x03,0xfc,0x00,0xfd,0x10,0x3f,0x44,0x0f,0xd0,0x03,0xe6,0x06 } }, -{ 16, 0x9f60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x20,0xc9,0x01,0x3e,0x40 } }, -{ 16, 0x9f70, 0, {0x0f,0xd0,0x03,0x3c,0x00,0xbd,0x00,0x32,0x63,0x0c,0x9e,0x43,0x27,0x00,0xe9,0xc0 } }, -{ 16, 0x9f80, 0, {0x3e,0x68,0x0c,0x98,0x03,0x34,0x00,0xf9,0x10,0x3f,0x40,0x0f,0xd0,0x03,0xc6,0x00 } }, -{ 16, 0x9f90, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xc2,0x20,0xd8,0x00,0x2e,0x00 } }, -{ 16, 0x9fa0, 0, {0x0b,0x80,0x52,0x28,0x04,0xb8,0x00,0x22,0x38,0x08,0x88,0x03,0x62,0x00,0x88,0xf0 } }, -{ 16, 0x9fb0, 0, {0x2e,0x3a,0x48,0x8f,0x0a,0x20,0x00,0xb0,0x80,0x2e,0x00,0x0b,0x80,0x02,0xce,0x04 } }, -{ 16, 0x9fc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0x81,0x00,0x2c,0x40 } }, -{ 16, 0x9fd0, 0, {0x0b,0x10,0x02,0x04,0x00,0xb1,0x00,0x20,0x42,0x48,0x14,0x42,0x05,0x80,0xa1,0x20 } }, -{ 16, 0x9fe0, 0, {0x2c,0x44,0x08,0x10,0x82,0x04,0x00,0xb1,0x20,0x2c,0x40,0x0b,0x10,0x02,0xc2,0x01 } }, -{ 16, 0x9ff0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa5,0x01,0x99,0x00,0x2e,0x40 } }, -{ 16, 0xa000, 0, {0x0b,0x90,0x02,0x24,0x40,0xbb,0x01,0x22,0x41,0x08,0x90,0x12,0x24,0x00,0xa9,0x00 } }, -{ 16, 0xa010, 0, {0x2c,0x40,0x08,0x10,0x40,0x24,0x08,0xb9,0x40,0x6e,0x50,0x0b,0x92,0x02,0xc6,0x04 } }, -{ 16, 0xa020, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x14,0xc9,0x05,0x3e,0x41 } }, -{ 16, 0xa030, 0, {0x0f,0x90,0x0b,0x24,0x04,0xf9,0x08,0xb2,0x40,0x2c,0x90,0x0a,0x24,0x00,0xe9,0x00 } }, -{ 16, 0xa040, 0, {0x3e,0x40,0x2c,0x90,0x03,0x27,0x00,0xf9,0x80,0x3e,0x60,0x0f,0x90,0x03,0xe8,0x04 } }, -{ 16, 0xa050, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x84,0x88,0xf9,0x00,0x3e,0x48 } }, -{ 16, 0xa060, 0, {0x0f,0x99,0x03,0xe6,0x00,0xf9,0x02,0x3c,0x40,0xaf,0x10,0x03,0xe4,0x12,0xd9,0x04 } }, -{ 16, 0xa070, 0, {0x3e,0x40,0x0f,0x90,0x03,0xe5,0x00,0xf9,0xc0,0x3e,0x64,0x0f,0x90,0x83,0xca,0x00 } }, -{ 16, 0xa080, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xc8,0x00,0x3e,0x00 } }, -{ 16, 0xa090, 0, {0x0f,0x80,0x03,0x21,0x00,0xc8,0x40,0xb2,0x00,0x0c,0x80,0x03,0x20,0x10,0xc8,0x00 } }, -{ 16, 0xa0a0, 0, {0x32,0x00,0x0c,0x80,0x03,0xe0,0x80,0xf8,0x04,0x32,0x00,0x2c,0x80,0x0b,0x0a,0x04 } }, -{ 16, 0xa0b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0xca,0x00,0x2e,0x80 } }, -{ 16, 0xa0c0, 0, {0x0b,0xe8,0x0a,0x38,0x10,0x8e,0xc0,0x22,0x80,0x0d,0xa0,0x02,0x28,0x00,0x0a,0x04 } }, -{ 16, 0xa0d0, 0, {0x02,0x80,0x28,0xa0,0x02,0xfb,0x00,0xba,0x00,0x37,0xb0,0x48,0xea,0x02,0x0a,0x00 } }, -{ 16, 0xa0e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x01,0x2c,0xc0 } }, -{ 16, 0xa0f0, 0, {0x8b,0xb0,0x42,0x0c,0x90,0x9b,0x20,0x20,0xc0,0x48,0x30,0x42,0x2c,0x00,0x83,0x00 } }, -{ 16, 0xa100, 0, {0x20,0xc0,0x08,0x30,0x02,0xcd,0x40,0xb3,0x00,0x24,0xc8,0x08,0x38,0x02,0x0a,0x00 } }, -{ 16, 0xa110, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x14,0x00,0x87,0x00,0x2d,0xc0 } }, -{ 16, 0xa120, 0, {0x0b,0x24,0x06,0x16,0x00,0x93,0x08,0x21,0xc8,0x09,0x31,0x02,0x0c,0x80,0x87,0xa0 } }, -{ 16, 0xa130, 0, {0x21,0xc0,0x18,0x72,0x02,0xdc,0x00,0xb7,0xb4,0x24,0xe3,0x08,0x78,0x02,0x28,0x00 } }, -{ 16, 0xa140, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x02,0x97,0xa0,0x3d,0xf0 } }, -{ 16, 0xa150, 0, {0x0f,0x48,0x03,0x3e,0x00,0xd6,0x80,0x30,0xe0,0x2c,0x7a,0x02,0x1e,0x82,0xc3,0xf0 } }, -{ 16, 0xa160, 0, {0x33,0xec,0x0c,0x7c,0x03,0xd6,0x00,0xf7,0x80,0x35,0xe0,0x0c,0xd8,0x03,0x2a,0x02 } }, -{ 16, 0xa170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x19,0xa5,0xa0,0xfb,0x00,0x3e,0xca } }, -{ 16, 0xa180, 0, {0x0f,0x80,0x03,0xec,0x02,0xea,0x00,0x3e,0xc6,0x0f,0xb4,0x0b,0xed,0x40,0xfb,0x00 } }, -{ 16, 0xa190, 0, {0xbe,0xc0,0x0f,0xb6,0x43,0xe0,0x00,0xfb,0x02,0x3e,0x80,0x0f,0x90,0x03,0xc2,0x06 } }, -{ 16, 0xa1a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x02,0xcf,0x88,0x3f,0xe0 } }, -{ 16, 0xa1b0, 0, {0x0c,0xb9,0x03,0xfe,0x00,0xdd,0x81,0x33,0xe0,0x8c,0xfc,0x03,0x3f,0x04,0xcf,0x80 } }, -{ 16, 0xa1c0, 0, {0x33,0xe2,0x4f,0xfc,0x03,0x3e,0x00,0xcf,0xc0,0x33,0x64,0x0c,0xf8,0x03,0xc0,0x00 } }, -{ 16, 0xa1d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x94,0x40,0x87,0x00,0x2f,0xc1 } }, -{ 16, 0xa1e0, 0, {0x0d,0x69,0xa2,0xd0,0x40,0xbc,0x00,0x23,0xc0,0x08,0xf0,0x02,0x9c,0x00,0x87,0x00 } }, -{ 16, 0xa1f0, 0, {0x21,0xc0,0x0b,0x70,0x0a,0x3c,0x04,0x87,0x10,0x21,0x4c,0x08,0x60,0x02,0xea,0x04 } }, -{ 16, 0xa200, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9e,0x00,0x87,0x00,0x2d,0xc0 } }, -{ 16, 0xa210, 0, {0x09,0x62,0x02,0xd8,0x00,0x97,0x00,0x21,0xc4,0x08,0x70,0x02,0x0c,0x40,0x97,0x00 } }, -{ 16, 0xa220, 0, {0x21,0xc4,0x0b,0x30,0x02,0x58,0x00,0xa7,0x08,0x21,0x80,0x08,0x60,0x82,0xc0,0x00 } }, -{ 16, 0xa230, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xe4,0x25,0x83,0x00,0x2c,0xc0 } }, -{ 16, 0xa240, 0, {0x09,0x22,0x02,0xcc,0x20,0xb2,0x00,0x20,0xc0,0x28,0xb0,0x02,0x8c,0x00,0x93,0x00 } }, -{ 16, 0xa250, 0, {0x20,0xc0,0x0b,0x30,0x42,0x6c,0x20,0x83,0x08,0x20,0xe2,0x08,0xb8,0x02,0xc8,0x04 } }, -{ 16, 0xa260, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa4,0x00,0xcf,0x00,0x3f,0xc0 } }, -{ 16, 0xa270, 0, {0x0d,0x9c,0x03,0xe8,0x00,0xdb,0x80,0x33,0xc0,0x0c,0xf0,0x0b,0x3c,0x06,0xdf,0x00 } }, -{ 16, 0xa280, 0, {0xb3,0xc0,0x0b,0xf0,0x07,0x68,0x00,0xef,0x40,0x32,0xa8,0x0c,0xa8,0x03,0xea,0x04 } }, -{ 16, 0xa290, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x00,0x2e,0xc0 } }, -{ 16, 0xa2a0, 0, {0x0f,0x94,0x03,0xc5,0x40,0xfa,0x30,0x3e,0xc0,0x0f,0xb0,0x03,0x6c,0x00,0xeb,0x00 } }, -{ 16, 0xa2b0, 0, {0x3e,0xc0,0x0f,0x30,0x13,0xad,0x40,0xfb,0x02,0x3e,0xd0,0x0f,0xb4,0x03,0xe0,0x00 } }, -{ 16, 0xa2c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xe4,0x00,0xc7,0x00,0x31,0xc1 } }, -{ 16, 0xa2d0, 0, {0x8c,0xd0,0x03,0x34,0x00,0xcd,0x00,0x3d,0xc0,0x0c,0xf0,0x01,0x7c,0x00,0xdb,0x01 } }, -{ 16, 0xa2e0, 0, {0x3d,0xc0,0x4c,0xf0,0x0b,0x30,0x02,0xc3,0x00,0x32,0x00,0x0f,0xd0,0x03,0x00,0x44 } }, -{ 16, 0xa2f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6e,0x40,0x8b,0x00,0x2a,0xc0 } }, -{ 16, 0xa300, 0, {0x28,0x84,0x42,0x22,0x80,0x88,0x80,0x3a,0xc0,0x0d,0xb0,0x02,0xac,0x08,0x8b,0x00 } }, -{ 16, 0xa310, 0, {0x2e,0xc0,0x08,0xb0,0x02,0x23,0x20,0x8b,0x00,0x22,0x30,0x8b,0x8c,0x02,0x20,0x40 } }, -{ 16, 0xa320, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x24,0x00,0x8b,0x00,0x22,0xc0 } }, -{ 16, 0xa330, 0, {0x08,0x38,0x86,0x2a,0x00,0x89,0x80,0x2a,0xc0,0x08,0xb0,0x02,0xcc,0x00,0x9b,0x00 } }, -{ 16, 0xa340, 0, {0x2e,0xc0,0x08,0xb0,0x42,0x26,0x00,0x8b,0x00,0x22,0x71,0x0b,0x8c,0x02,0x20,0x00 } }, -{ 16, 0xa350, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0x83,0x00,0x28,0xc0 } }, -{ 16, 0xa360, 0, {0x08,0x32,0x42,0x00,0x00,0x81,0x00,0x28,0xc0,0x09,0x30,0x52,0x8c,0x08,0x83,0x00 } }, -{ 16, 0xa370, 0, {0x2c,0xc0,0x18,0x30,0x06,0x00,0x00,0x83,0x00,0xa0,0x00,0x0b,0x00,0x02,0x02,0x01 } }, -{ 16, 0xa380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x74,0x02,0x8b,0x00,0x33,0xc0 } }, -{ 16, 0xa390, 0, {0x0c,0x92,0x0b,0x20,0x02,0xc8,0x00,0x3b,0xc0,0x0c,0xf5,0x03,0xfc,0x00,0xdf,0x01 } }, -{ 16, 0xa3a0, 0, {0x3f,0xc1,0x04,0xf0,0x33,0x21,0x40,0xcf,0x00,0x32,0x00,0x0f,0x80,0x0b,0x00,0x03 } }, -{ 16, 0xa3b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x19,0xfc,0x00,0xff,0x00,0x3f,0xc0 } }, -{ 16, 0xa3c0, 0, {0x0f,0xc4,0x03,0xf0,0x00,0x9c,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0xa3d0, 0, {0x2f,0xc0,0x0f,0xf0,0x03,0xf0,0x80,0xff,0x00,0x3f,0x00,0x0f,0xc0,0x03,0xe8,0x06 } }, -{ 16, 0xa3e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0xc0,0xff,0xa0,0x31,0x24 } }, -{ 16, 0xa3f0, 0, {0x0e,0xf0,0x63,0x10,0x04,0xef,0x64,0x3f,0xc0,0x4c,0xf3,0x03,0x1c,0x80,0xdf,0x08 } }, -{ 16, 0xa400, 0, {0x37,0xc0,0x0f,0xf0,0x03,0xf0,0xa0,0xfc,0x00,0x31,0x08,0x2c,0xd2,0x03,0xf0,0x00 } }, -{ 16, 0xa410, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe1,0x00,0xbb,0xc1,0x22,0x48 } }, -{ 16, 0xa420, 0, {0x08,0xfd,0x02,0x2e,0x00,0x97,0x00,0x2f,0xc2,0x48,0x71,0x23,0x7e,0x40,0xbf,0x00 } }, -{ 16, 0xa430, 0, {0x21,0xc5,0x4b,0xf5,0x02,0xef,0x00,0xbb,0x40,0x36,0xe0,0x08,0xa8,0x02,0xe0,0x04 } }, -{ 16, 0xa440, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc5,0x84,0xb3,0x11,0xa2,0xc9 } }, -{ 16, 0xa450, 0, {0x0a,0x30,0x02,0x00,0x01,0xb3,0x30,0x28,0xc4,0x08,0x32,0x42,0x0c,0x00,0xa3,0x08 } }, -{ 16, 0xa460, 0, {0xa0,0xca,0x0a,0x32,0x82,0x80,0x10,0xb0,0x41,0x24,0x11,0x08,0x31,0x02,0xe2,0x01 } }, -{ 16, 0xa470, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa5,0x00,0xbb,0x00,0x22,0xe1 } }, -{ 16, 0xa480, 0, {0x28,0xb0,0x02,0x2c,0x80,0x9b,0x00,0x2e,0xc0,0x08,0xb0,0x02,0x6c,0x00,0xb3,0x00 } }, -{ 16, 0xa490, 0, {0x22,0xc0,0x0b,0xb0,0x00,0xec,0x20,0xbb,0x00,0x26,0xc0,0x08,0x80,0x02,0xf0,0x04 } }, -{ 16, 0xa4a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe3,0x40,0xf7,0x04,0x32,0xc0 } }, -{ 16, 0xa4b0, 0, {0x4e,0xb0,0x23,0x2e,0x20,0xeb,0x00,0x1e,0xc0,0x0c,0xb0,0x01,0x2c,0x00,0xfb,0x00 } }, -{ 16, 0xa4c0, 0, {0x36,0xc0,0x1f,0xb0,0x03,0xe1,0x40,0xfb,0x00,0x36,0x98,0x0c,0x90,0x03,0xd0,0x04 } }, -{ 16, 0xa4d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb6,0x04,0xff,0x02,0x3f,0xc0 } }, -{ 16, 0xa4e0, 0, {0x0f,0xf0,0x03,0xfe,0x00,0xef,0x02,0x3d,0xc0,0x0f,0xf0,0x23,0xfc,0x00,0xff,0x00 } }, -{ 16, 0xa4f0, 0, {0x3f,0xc0,0x4f,0xf0,0x03,0xfc,0x00,0xf4,0x00,0x3b,0x40,0x0f,0xa0,0x13,0xf8,0x00 } }, -{ 16, 0xa500, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xaa,0x20,0xeb,0x10,0x36,0xc0 } }, -{ 16, 0xa510, 0, {0x0d,0xb0,0x07,0xec,0x20,0xdb,0x00,0x32,0xc0,0x0c,0xb0,0x02,0x6c,0x20,0xeb,0x00 } }, -{ 16, 0xa520, 0, {0x3e,0xc1,0x0d,0xb0,0x03,0xe0,0x20,0xdb,0xa0,0x32,0x90,0x4c,0xb0,0x0b,0x10,0x04 } }, -{ 16, 0xa530, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2d,0x00,0x8f,0x80,0x20,0xc1 } }, -{ 16, 0xa540, 0, {0x08,0x70,0x12,0xcf,0x00,0x8f,0x00,0xa3,0xc0,0x0d,0xf0,0x02,0x3c,0x00,0x8f,0x00 } }, -{ 16, 0xa550, 0, {0x37,0xc0,0x88,0xf0,0x02,0xec,0x00,0x88,0x00,0x20,0x40,0x08,0x80,0x02,0x32,0x00 } }, -{ 16, 0xa560, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xa3,0x80,0x24,0x81 } }, -{ 16, 0xa570, 0, {0x09,0x30,0x06,0xcc,0x40,0x93,0x00,0x28,0xc1,0x08,0xb0,0x02,0xcf,0x40,0xa3,0x00 } }, -{ 16, 0xa580, 0, {0x2c,0xc0,0x09,0x30,0x02,0xcd,0x00,0x90,0x40,0x60,0x40,0x28,0x10,0x02,0x38,0x00 } }, -{ 16, 0xa590, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x0e,0x00,0x87,0x80,0x23,0xe0 } }, -{ 16, 0xa5a0, 0, {0x48,0x79,0x02,0xde,0x41,0x97,0x80,0x29,0xe0,0x19,0x78,0x06,0x9e,0x00,0x87,0x80 } }, -{ 16, 0xa5b0, 0, {0x25,0xe0,0x08,0x78,0x02,0xd2,0x03,0x83,0x80,0x21,0xa0,0x08,0x68,0x02,0x08,0x00 } }, -{ 16, 0xa5c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xa3,0x00,0x34,0xc0 } }, -{ 16, 0xa5d0, 0, {0x0d,0x30,0x42,0xcc,0x01,0xd3,0x10,0x3a,0xc5,0x0c,0x39,0x03,0xcc,0x00,0xe3,0x04 } }, -{ 16, 0xa5e0, 0, {0x3c,0xc4,0x0d,0x30,0x03,0xce,0x00,0xd0,0x00,0x30,0x40,0x0c,0x30,0x03,0x12,0x02 } }, -{ 16, 0xa5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0xf7,0x00,0x3f,0xc0 } }, -{ 16, 0xa600, 0, {0x1f,0xf0,0x53,0xfc,0x00,0xef,0x08,0x37,0xd1,0x0f,0xf0,0x83,0x7c,0x00,0xf7,0x40 } }, -{ 16, 0xa610, 0, {0x3f,0xc1,0x0f,0xf1,0x03,0xd0,0x00,0xff,0x00,0xbf,0x84,0x0f,0xc8,0x03,0xd0,0x06 } }, -{ 16, 0xa620, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe0,0x00,0xfb,0x00,0x3e,0xe0 } }, -{ 16, 0xa630, 0, {0x2c,0xbe,0x83,0xec,0x00,0xeb,0x40,0x3e,0xc0,0x0f,0xb4,0x03,0xed,0x20,0xfb,0x10 } }, -{ 16, 0xa640, 0, {0xb6,0xd2,0x0f,0xb4,0x83,0xec,0x00,0xdb,0x80,0x36,0xc1,0x0c,0x90,0x21,0x2a,0x00 } }, -{ 16, 0xa650, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x00,0xb7,0x00,0x2f,0xc0 } }, -{ 16, 0xa660, 0, {0x08,0x36,0x02,0x0c,0x08,0x87,0x30,0x2d,0xd9,0x8b,0x72,0x86,0xdd,0x00,0xb3,0x20 } }, -{ 16, 0xa670, 0, {0x21,0xc8,0x0b,0x74,0x02,0xd0,0x02,0x84,0x00,0xa0,0x00,0x28,0x20,0x02,0x12,0x04 } }, -{ 16, 0xa680, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x00,0xb7,0x80,0x2d,0xe0 } }, -{ 16, 0xa690, 0, {0x08,0x7a,0x02,0x9d,0x00,0xa7,0xa0,0x2d,0xe0,0x0b,0x78,0x02,0x9e,0x80,0xa7,0x80 } }, -{ 16, 0xa6a0, 0, {0x21,0xe4,0x08,0x7a,0x26,0x9e,0x18,0x83,0x04,0x21,0xe0,0x08,0x78,0x0a,0x70,0x00 } }, -{ 16, 0xa6b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0xb3,0x00,0x2c,0xe0 } }, -{ 16, 0xa6c0, 0, {0x58,0x30,0x12,0x0e,0x82,0x83,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x01,0xb3,0x00 } }, -{ 16, 0xa6d0, 0, {0x20,0xc1,0x0b,0x30,0x02,0xc0,0x08,0x88,0xd2,0x20,0x20,0x08,0x00,0x02,0x52,0x04 } }, -{ 16, 0xa6e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x60,0xfa,0x00,0x3f,0x82 } }, -{ 16, 0xa6f0, 0, {0x0c,0xa0,0x03,0xfa,0x00,0xaa,0x00,0x1e,0x80,0x8f,0xa0,0x03,0xe8,0x00,0xf2,0x00 } }, -{ 16, 0xa700, 0, {0x32,0x80,0x1f,0xa0,0x03,0xe8,0x00,0xda,0x00,0x36,0x88,0xac,0xe0,0x03,0x7a,0x04 } }, -{ 16, 0xa710, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe1,0x00,0xf8,0x00,0x3e,0x20 } }, -{ 16, 0xa720, 0, {0x4f,0x80,0x03,0xe1,0x00,0xf0,0x00,0x3c,0x00,0x0b,0x80,0x03,0xe0,0x00,0xf8,0x02 } }, -{ 16, 0xa730, 0, {0x3a,0x00,0x0f,0x80,0x43,0xf1,0x00,0xfc,0x0a,0x3d,0x00,0x0f,0xc0,0x03,0x92,0x00 } }, -{ 16, 0xa740, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe6,0x00,0xc9,0x90,0x3e,0x40 } }, -{ 16, 0xa750, 0, {0x0f,0x92,0x03,0xe4,0x00,0xd9,0x00,0x32,0x40,0x04,0x90,0x07,0xe7,0x00,0xf9,0x10 } }, -{ 16, 0xa760, 0, {0x30,0x40,0x0c,0x90,0x43,0xe4,0x09,0xd9,0x80,0x22,0x40,0x2c,0x10,0x0b,0x02,0x04 } }, -{ 16, 0xa770, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x60,0x89,0xc0,0x2e,0x40 } }, -{ 16, 0xa780, 0, {0x0b,0x98,0x26,0xc5,0x80,0x89,0x00,0x22,0x40,0x28,0x90,0x12,0xe7,0x10,0xb9,0x00 } }, -{ 16, 0xa790, 0, {0x36,0x40,0x28,0x90,0x12,0xc5,0x83,0xc9,0x80,0xb6,0x40,0x08,0x90,0x02,0x20,0x00 } }, -{ 16, 0xa7a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x89,0x40,0x2e,0x41 } }, -{ 16, 0xa7b0, 0, {0x4b,0x90,0x02,0xe4,0x00,0x99,0x00,0xa2,0x40,0x0a,0x90,0x02,0xe5,0x00,0xb9,0x00 } }, -{ 16, 0xa7c0, 0, {0xe2,0x41,0x08,0x90,0x42,0xe4,0x00,0x9d,0x50,0xab,0x4a,0x08,0xd0,0x26,0x06,0x00 } }, -{ 16, 0xa7d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x82,0x81,0x20,0x2c,0x50 } }, -{ 16, 0xa7e0, 0, {0x0b,0x10,0x02,0xe4,0x00,0x81,0x40,0x20,0x50,0x4a,0x14,0x32,0xc4,0x00,0xb1,0x40 } }, -{ 16, 0xa7f0, 0, {0x24,0x51,0x18,0x14,0x12,0xd4,0x00,0x85,0x40,0x2d,0x40,0x08,0x50,0x06,0x02,0x01 } }, -{ 16, 0xa800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc8,0x00,0x3e,0x00 } }, -{ 16, 0xa810, 0, {0x0f,0x80,0x02,0xe0,0x00,0xd8,0x00,0x32,0x00,0x0a,0x80,0x02,0xe0,0x10,0xf8,0x00 } }, -{ 16, 0xa820, 0, {0x32,0x00,0x04,0x80,0x03,0xe0,0x00,0xd8,0x00,0x3a,0x00,0x0c,0xc0,0x03,0x2e,0x03 } }, -{ 16, 0xa830, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xf9,0x10,0x3f,0x41 } }, -{ 16, 0xa840, 0, {0x0f,0x94,0x03,0xf5,0x00,0xf9,0x40,0x3e,0x50,0x0d,0x94,0x03,0xe5,0x10,0xf9,0x40 } }, -{ 16, 0xa850, 0, {0x3e,0x50,0x4f,0x94,0x03,0xc5,0x00,0xe9,0x41,0x36,0x50,0x0f,0x94,0x03,0xe6,0x06 } }, -{ 16, 0xa860, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x00,0xfd,0xa8,0x3a,0x40 } }, -{ 16, 0xa870, 0, {0x0c,0xd8,0x23,0x36,0x00,0xe9,0xa0,0x3e,0x78,0x0f,0x9e,0x03,0xb6,0x80,0xcd,0xe2 } }, -{ 16, 0xa880, 0, {0x32,0x68,0x0c,0x9b,0x03,0x36,0x82,0x4d,0xa0,0x37,0x68,0x8c,0x98,0x03,0x06,0x00 } }, -{ 16, 0xa890, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xeb,0xa0,0xb8,0x40,0x20,0x20 } }, -{ 16, 0xa8a0, 0, {0x08,0x85,0x02,0x21,0x51,0x88,0xc0,0x2e,0x29,0x0b,0x8e,0x02,0xe1,0x00,0xd8,0xe0 } }, -{ 16, 0xa8b0, 0, {0x22,0x32,0x0d,0x8d,0x23,0x61,0x48,0x98,0xd4,0xa2,0x10,0x28,0x84,0x02,0x0e,0x04 } }, -{ 16, 0xa8c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb3,0x00,0x2a,0x4a } }, -{ 16, 0xa8d0, 0, {0x28,0x10,0x4e,0xa4,0x08,0xa1,0x68,0x28,0x44,0x0b,0x14,0x02,0xc5,0x00,0x81,0x40 } }, -{ 16, 0xa8e0, 0, {0xa0,0x50,0x08,0x10,0x02,0x04,0x02,0x91,0x2a,0x20,0x44,0x28,0x14,0x4a,0x02,0x01 } }, -{ 16, 0xa8f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xac,0x80,0xb9,0x00,0x22,0x40 } }, -{ 16, 0xa900, 0, {0x48,0x90,0x06,0xa4,0x00,0xa9,0x00,0x2e,0x40,0x0b,0x90,0x22,0xe4,0x00,0x99,0x00 } }, -{ 16, 0xa910, 0, {0x22,0x40,0x09,0x10,0x02,0x64,0x02,0x99,0x00,0x22,0x40,0x08,0x90,0x02,0x06,0x04 } }, -{ 16, 0xa920, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x00,0x38,0x58 } }, -{ 16, 0xa930, 0, {0x0c,0x90,0x53,0x84,0x14,0xa9,0x04,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xc9,0x00 } }, -{ 16, 0xa940, 0, {0x32,0x40,0x0c,0x90,0x03,0x24,0x04,0xd9,0x00,0xb6,0x40,0x4c,0x90,0x0b,0x28,0x04 } }, -{ 16, 0xa950, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x00,0xf9,0x02,0x3e,0x49 } }, -{ 16, 0xa960, 0, {0x0f,0x10,0x43,0x64,0x00,0xd9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xc4,0x00,0xf1,0x02 } }, -{ 16, 0xa970, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc4,0x02,0xe9,0x04,0x3c,0x40,0x0f,0x1c,0x03,0xca,0x00 } }, -{ 16, 0xa980, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x80,0xc8,0x20,0x3e,0x00 } }, -{ 16, 0xa990, 0, {0x8c,0x80,0x0b,0x20,0x00,0xe8,0x02,0x3e,0x00,0x0f,0x80,0x03,0xa0,0x82,0xc8,0x00 } }, -{ 16, 0xa9a0, 0, {0x6c,0x00,0x0f,0x80,0x03,0x20,0x10,0xc8,0x00,0x32,0x02,0x0c,0x80,0x03,0x0a,0x04 } }, -{ 16, 0xa9b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x38,0x00,0x86,0x00,0x2e,0x80 } }, -{ 16, 0xa9c0, 0, {0x68,0xa8,0x80,0x3a,0x00,0x8a,0x00,0x2e,0x80,0x0b,0xa0,0x02,0xf8,0x00,0x8a,0x00 } }, -{ 16, 0xa9d0, 0, {0x2e,0x80,0x0b,0xa0,0x0a,0x3a,0x00,0x8e,0x10,0x23,0x80,0x08,0xa0,0x03,0x0a,0x00 } }, -{ 16, 0xa9e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4d,0x00,0x83,0x00,0x2c,0xc0 } }, -{ 16, 0xa9f0, 0, {0x08,0x38,0x00,0x0c,0x60,0x23,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xcc,0x40,0x83,0x00 } }, -{ 16, 0xaa00, 0, {0x2c,0xc0,0x0b,0x30,0x02,0x0c,0x02,0x8a,0x80,0xa0,0xe0,0x28,0x30,0x0a,0x4a,0x00 } }, -{ 16, 0xaa10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x16,0x20,0x87,0x02,0x2d,0xc1 } }, -{ 16, 0xaa20, 0, {0x48,0x70,0x12,0x7c,0x00,0xa7,0x20,0x2d,0xc9,0x0b,0x72,0x00,0xdc,0x00,0x87,0x08 } }, -{ 16, 0xaa30, 0, {0x2d,0xc4,0x1b,0x32,0x02,0x1d,0x01,0x87,0x42,0x21,0xc2,0x08,0x70,0x02,0x28,0x00 } }, -{ 16, 0xaa40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x02,0xc7,0x80,0x3d,0xec } }, -{ 16, 0xaa50, 0, {0x0c,0x58,0x03,0x1e,0x00,0xe7,0x80,0x3d,0xec,0x0f,0x7f,0x03,0x96,0x00,0xc7,0x80 } }, -{ 16, 0xaa60, 0, {0x2d,0xe2,0x07,0x79,0x03,0x0a,0x06,0xc3,0x80,0x30,0x20,0x8c,0x38,0x03,0x6a,0x02 } }, -{ 16, 0xaa70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xfb,0x00,0x3e,0xc0 } }, -{ 16, 0xaa80, 0, {0x0f,0x10,0x43,0x8c,0x00,0xdb,0x38,0x3e,0xd8,0x0f,0xb0,0x03,0xcc,0x04,0xfb,0x44 } }, -{ 16, 0xaa90, 0, {0x3e,0xc0,0x8f,0xb6,0x13,0xec,0x02,0xff,0x02,0x3e,0x00,0x0f,0xb0,0x03,0xc2,0x06 } }, -{ 16, 0xaaa0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfa,0x00,0xff,0x80,0x31,0xe3 } }, -{ 16, 0xaab0, 0, {0x0e,0xf8,0x23,0xfe,0x02,0xdf,0x80,0xb7,0xe2,0x0e,0xf8,0x03,0x7e,0x00,0x6d,0xd0 } }, -{ 16, 0xaac0, 0, {0x33,0xe0,0x0c,0xf8,0x9b,0x76,0xc0,0xdf,0x84,0xb3,0xe0,0x04,0xf8,0x03,0xc0,0x00 } }, -{ 16, 0xaad0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x90,0x40,0xb7,0x02,0x21,0xc4 } }, -{ 16, 0xaae0, 0, {0x08,0x7b,0x42,0xdc,0x00,0x87,0x00,0x21,0xc4,0x0b,0x30,0x00,0x10,0x80,0x8d,0x00 } }, -{ 16, 0xaaf0, 0, {0x23,0xc0,0x0d,0xf2,0x02,0x04,0x42,0x8f,0x00,0x29,0xc8,0x28,0x70,0x02,0xea,0x04 } }, -{ 16, 0xab00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x00,0xb6,0x00,0x23,0xc0 } }, -{ 16, 0xab10, 0, {0x0a,0x72,0x02,0x8c,0x00,0x87,0x00,0x21,0xc0,0x0a,0x30,0x02,0x04,0x01,0xa7,0x02 } }, -{ 16, 0xab20, 0, {0x21,0xc0,0x08,0x70,0x42,0x00,0x8a,0x87,0x00,0x21,0xc0,0x28,0x70,0x02,0xc0,0x00 } }, -{ 16, 0xab30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xc5,0x00,0xb0,0x00,0xa0,0xd0 } }, -{ 16, 0xab40, 0, {0x08,0xb0,0x02,0xc9,0x42,0x8b,0x00,0x20,0xc0,0x0b,0x30,0x22,0x04,0x00,0x83,0x00 } }, -{ 16, 0xab50, 0, {0xa0,0xc0,0x49,0x30,0x02,0x45,0x40,0x93,0xc0,0xa8,0xd4,0x00,0x35,0x02,0xc8,0x04 } }, -{ 16, 0xab60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xbb,0x00,0x31,0xc0 } }, -{ 16, 0xab70, 0, {0x0e,0xb0,0x23,0xcd,0x00,0xdf,0x00,0x37,0xc0,0x0e,0xf0,0x01,0x68,0x00,0xe3,0x00 } }, -{ 16, 0xab80, 0, {0x33,0xc0,0x1c,0xf0,0x03,0x45,0x00,0xda,0xc8,0x92,0xd4,0x2c,0xb4,0x03,0xea,0x04 } }, -{ 16, 0xab90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe5,0x20,0xfb,0x00,0x3e,0xc0 } }, -{ 16, 0xaba0, 0, {0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00,0x3e,0xc0,0x4f,0xb0,0x03,0xad,0x00,0xfb,0x00 } }, -{ 16, 0xabb0, 0, {0x7e,0xc0,0x1f,0x30,0x03,0xa4,0x80,0xe9,0x20,0x3c,0xc0,0x0f,0x32,0x03,0xe0,0x00 } }, -{ 16, 0xabc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xc7,0x00,0x33,0xc2 } }, -{ 16, 0xabd0, 0, {0x2c,0xf0,0x03,0x3e,0x20,0xdb,0x00,0x13,0xc0,0x0c,0x70,0x03,0x3c,0x80,0xef,0x04 } }, -{ 16, 0xabe0, 0, {0x73,0xc1,0x0f,0xf0,0x22,0x30,0x00,0xc6,0x00,0xb2,0xc0,0x0c,0xf0,0x03,0x00,0x44 } }, -{ 16, 0xabf0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x69,0x00,0x8b,0x44,0xa2,0xc1 } }, -{ 16, 0xac00, 0, {0x88,0xb0,0x03,0x6c,0x00,0x8b,0x00,0x22,0xc0,0x28,0xb0,0x0a,0x2d,0x00,0xbb,0x00 } }, -{ 16, 0xac10, 0, {0x62,0xc0,0x0b,0xb0,0x02,0x26,0x02,0x8b,0x80,0x22,0xc0,0x08,0xb0,0x03,0x20,0x40 } }, -{ 16, 0xac20, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x28,0x01,0x8a,0x08,0x22,0xc0 } }, -{ 16, 0xac30, 0, {0x08,0xb2,0x02,0x6c,0x40,0x9b,0x00,0x28,0xc0,0x48,0xb0,0x16,0x29,0x04,0xb9,0x01 } }, -{ 16, 0xac40, 0, {0x22,0xc0,0x49,0xb0,0x06,0xae,0x09,0x8b,0x80,0x22,0xe0,0x48,0xb0,0x02,0x20,0x00 } }, -{ 16, 0xac50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x02,0x82,0x00,0x22,0xc0 } }, -{ 16, 0xac60, 0, {0x88,0xb0,0x02,0x44,0x00,0x83,0x00,0x28,0xc0,0x08,0x30,0x02,0x08,0x00,0xb1,0x00 } }, -{ 16, 0xac70, 0, {0x20,0xc0,0x0b,0x30,0x02,0x8c,0x00,0x83,0x80,0x20,0xe0,0x08,0x30,0x0a,0x02,0x01 } }, -{ 16, 0xac80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xca,0x00,0x33,0xc0 } }, -{ 16, 0xac90, 0, {0x0c,0xb2,0x03,0x2c,0x00,0xdf,0x00,0x3b,0xc0,0x4c,0xf5,0x13,0x2c,0x04,0xef,0x00 } }, -{ 16, 0xaca0, 0, {0xa3,0xc0,0x0d,0xf0,0x03,0xa8,0x40,0xcb,0x00,0xb2,0x00,0x2c,0xb0,0x03,0x00,0x03 } }, -{ 16, 0xacb0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf0,0x00,0xf4,0x00,0x3f,0xc0 } }, -{ 16, 0xacc0, 0, {0x0f,0xb1,0x03,0xf0,0x00,0xff,0x00,0x37,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0xacd0, 0, {0x3f,0xc0,0x07,0xf0,0x0b,0x7c,0x08,0xff,0x01,0x3f,0x00,0x0f,0xf0,0x03,0xa8,0x06 } }, -{ 16, 0xace0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0xc5,0xed,0x33,0x3b,0xcc } }, -{ 16, 0xacf0, 0, {0x0c,0xf0,0x03,0x30,0x40,0xff,0x25,0x3f,0xcc,0x0c,0xf3,0x83,0x3c,0xd0,0xdf,0x48 } }, -{ 16, 0xad00, 0, {0x37,0x30,0x4c,0xf3,0x03,0xfd,0x80,0xcf,0x28,0x33,0xd8,0x0c,0xf1,0x03,0x30,0x00 } }, -{ 16, 0xad10, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0xd0,0xbb,0x31,0x20,0xcc } }, -{ 16, 0xad20, 0, {0x88,0xf3,0x42,0x20,0x50,0xbf,0x90,0x2f,0xc4,0x0a,0xf6,0x02,0x7d,0xc0,0x8f,0x40 } }, -{ 16, 0xad30, 0, {0x26,0x40,0x8f,0xf6,0x02,0xfd,0x00,0xff,0x08,0x39,0xc8,0x08,0xf6,0x02,0xa0,0x04 } }, -{ 16, 0xad40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x80,0xa1,0x20,0x28,0xc9 } }, -{ 16, 0xad50, 0, {0x08,0x30,0x9a,0x00,0x09,0xb3,0x00,0x2c,0xc0,0x20,0x30,0x02,0x4c,0x90,0x83,0x20 } }, -{ 16, 0xad60, 0, {0x02,0x08,0x0b,0x33,0x12,0xcd,0x80,0x93,0x20,0x24,0xd8,0x08,0x34,0x22,0x22,0x01 } }, -{ 16, 0xad70, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xae,0x00,0xbb,0x10,0x22,0xc0 } }, -{ 16, 0xad80, 0, {0x08,0xb0,0x02,0x26,0x01,0x3b,0x01,0x6e,0xc0,0x08,0xb0,0x02,0x4c,0x08,0x8b,0x00 } }, -{ 16, 0xad90, 0, {0xa2,0x89,0x0b,0xb0,0x02,0xec,0x00,0xab,0x00,0x6a,0xc1,0x28,0xb0,0x02,0xb0,0x04 } }, -{ 16, 0xada0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0x6e,0x00,0xe8,0xc1,0x3a,0xc0 } }, -{ 16, 0xadb0, 0, {0x2c,0xb0,0x43,0x26,0x00,0xfb,0x06,0x3e,0xc1,0x0c,0xb0,0x0b,0x2c,0x02,0xcb,0x00 } }, -{ 16, 0xadc0, 0, {0x34,0x22,0x9f,0xb0,0x43,0xec,0x00,0x9b,0x02,0x36,0xc1,0x8c,0xb0,0x03,0x10,0x04 } }, -{ 16, 0xadd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x00,0xfc,0x80,0x3d,0xd0 } }, -{ 16, 0xade0, 0, {0x2f,0xf0,0x03,0xfc,0x00,0xfb,0x00,0x3d,0xc0,0x07,0x30,0x03,0xbc,0x00,0xef,0x04 } }, -{ 16, 0xadf0, 0, {0x3f,0xe0,0x5e,0xb0,0x01,0xfc,0x00,0xff,0x00,0x1b,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0xae00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xcb,0x01,0x3e,0xc9 } }, -{ 16, 0xae10, 0, {0x0c,0xb0,0x17,0x20,0x84,0xeb,0x00,0xb2,0xc1,0x0d,0xb0,0x03,0x6c,0x00,0xc3,0x00 } }, -{ 16, 0xae20, 0, {0x32,0x50,0x0f,0xb0,0x03,0x0c,0x40,0xc3,0x00,0x7e,0xc0,0x0c,0x30,0x03,0x10,0x04 } }, -{ 16, 0xae30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0x8a,0x58,0x2e,0xe0 } }, -{ 16, 0xae40, 0, {0x48,0xf0,0x02,0x2d,0x00,0xef,0x01,0x23,0xc0,0x08,0xf0,0x22,0x3c,0x04,0x8f,0x60 } }, -{ 16, 0xae50, 0, {0x36,0x54,0x0b,0xf0,0x0a,0x3d,0x40,0x8f,0x00,0x2f,0xc0,0x08,0xf0,0x03,0x72,0x00 } }, -{ 16, 0xae60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x40,0x00,0x89,0x80,0x2c,0x10 } }, -{ 16, 0xae70, 0, {0x08,0xb0,0x02,0x49,0x00,0xa3,0xa0,0x24,0xc0,0x09,0x30,0x02,0x4c,0x00,0x83,0xc9 } }, -{ 16, 0xae80, 0, {0x20,0x90,0x42,0x30,0x12,0x4d,0x00,0x83,0x00,0x6a,0xc0,0x09,0x30,0x02,0x38,0x00 } }, -{ 16, 0xae90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x00,0x85,0x80,0x6d,0x62 } }, -{ 16, 0xaea0, 0, {0x08,0x7e,0x02,0x56,0x40,0x27,0x80,0x25,0xe0,0x19,0x78,0x06,0x0e,0x00,0x83,0x80 } }, -{ 16, 0xaeb0, 0, {0x61,0xa0,0x0b,0x78,0x02,0x4e,0x00,0x87,0x82,0x6d,0xe0,0x09,0x79,0x02,0x48,0x00 } }, -{ 16, 0xaec0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x2c,0x02,0xc3,0x61,0x3c,0x88 } }, -{ 16, 0xaed0, 0, {0x2c,0xba,0x12,0x49,0x10,0xe3,0x2c,0x36,0xc0,0x0d,0x30,0x53,0x4c,0x44,0xc3,0x00 } }, -{ 16, 0xaee0, 0, {0x20,0x01,0x0f,0x31,0x03,0x4c,0x00,0xc3,0x01,0x3c,0xc0,0x2d,0xb1,0x03,0x12,0x02 } }, -{ 16, 0xaef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0xff,0x00,0x3f,0x00 } }, -{ 16, 0xaf00, 0, {0x4f,0xf1,0x09,0xb0,0x00,0xff,0x00,0x3b,0xc0,0x0e,0xf4,0x01,0xfd,0x24,0xff,0x40 } }, -{ 16, 0xaf10, 0, {0xbf,0xc0,0x07,0xf0,0x03,0xbc,0x00,0x6f,0x10,0x3f,0xc4,0x1e,0xf1,0x83,0xd0,0x06 } }, -{ 16, 0xaf20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xc4,0x00,0xe8,0x04,0x32,0x00 } }, -{ 16, 0xaf30, 0, {0x0c,0xb6,0x03,0xe8,0x02,0xcb,0x00,0x36,0xca,0x0f,0xb5,0x03,0xad,0x00,0xfb,0x20 } }, -{ 16, 0xaf40, 0, {0x3e,0x40,0x0f,0xb3,0x03,0xec,0x80,0xfb,0xa8,0x32,0xc6,0x8c,0xb6,0x03,0x2a,0x00 } }, -{ 16, 0xaf50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x02,0xe6,0x00,0x20,0x00 } }, -{ 16, 0xaf60, 0, {0x08,0x73,0x02,0xdc,0x00,0x87,0x70,0x2d,0xd0,0x0b,0xf0,0x02,0x1c,0x84,0xb7,0x20 } }, -{ 16, 0xaf70, 0, {0x2d,0xc0,0x0b,0x70,0x82,0xdd,0x24,0xb7,0x40,0x34,0xc9,0x28,0x72,0x82,0x92,0x04 } }, -{ 16, 0xaf80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xbe,0x02,0xac,0x80,0xa1,0x20 } }, -{ 16, 0xaf90, 0, {0x08,0x79,0x00,0xce,0x04,0x87,0x80,0x65,0xe0,0x0b,0x7a,0x02,0x9e,0x00,0xb7,0x90 } }, -{ 16, 0xafa0, 0, {0x6d,0xa0,0x0b,0x78,0x02,0xde,0x00,0xb7,0x80,0x21,0xe0,0x08,0x78,0x02,0x30,0x00 } }, -{ 16, 0xafb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xed,0x82,0xab,0xe0,0x20,0xe4 } }, -{ 16, 0xafc0, 0, {0x08,0x30,0x02,0xee,0x04,0x83,0x00,0x2c,0xc1,0x1b,0x30,0x02,0x0c,0x08,0xb3,0x00 } }, -{ 16, 0xafd0, 0, {0x64,0xf6,0x0b,0xb0,0x02,0xcc,0x04,0xb3,0x00,0x26,0xc0,0x08,0x30,0x02,0x92,0x04 } }, -{ 16, 0xafe0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xbb,0x80,0xee,0x49,0x31,0xa0 } }, -{ 16, 0xaff0, 0, {0x2c,0xa0,0x03,0xfa,0x00,0xca,0x02,0x36,0x80,0x0f,0xa0,0x03,0xa8,0x00,0xfa,0x02 } }, -{ 16, 0xb000, 0, {0x3f,0x90,0x0f,0xa0,0x63,0xe8,0x00,0xfa,0x00,0x32,0x80,0x0c,0xa0,0x23,0x3a,0x04 } }, -{ 16, 0xb010, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x0a,0xe8,0x00,0x3e,0x08 } }, -{ 16, 0xb020, 0, {0x0f,0x80,0x03,0xe3,0x50,0xf0,0x00,0x3e,0x00,0x0f,0x80,0x13,0xe0,0x00,0xf8,0x00 } }, -{ 16, 0xb030, 0, {0x3e,0x00,0x0f,0x80,0x03,0xe0,0x01,0xf8,0x01,0x7e,0x00,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xb040, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x40,0xc9,0xa1,0x32,0x40 } }, -{ 16, 0xb050, 0, {0x20,0x11,0x01,0xa6,0x40,0xc9,0x84,0x36,0x40,0x0d,0x90,0x03,0x44,0x00,0x41,0x00 } }, -{ 16, 0xb060, 0, {0x32,0x40,0x0f,0x90,0x0b,0x24,0x00,0xf9,0x00,0x3e,0x40,0x4c,0x10,0x03,0x02,0x04 } }, -{ 16, 0xb070, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0x89,0x82,0xa2,0x40 } }, -{ 16, 0xb080, 0, {0x08,0x9c,0x02,0x25,0x00,0x89,0xc8,0x22,0x40,0x08,0x90,0x42,0x24,0x00,0x89,0x20 } }, -{ 16, 0xb090, 0, {0x22,0x60,0x0b,0x90,0x02,0x24,0x10,0xb9,0x00,0x2e,0x40,0x08,0x90,0x03,0x60,0x00 } }, -{ 16, 0xb0a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x04,0x22,0xca } }, -{ 16, 0xb0b0, 0, {0x0a,0x90,0x0a,0x25,0x02,0x89,0x20,0x20,0x40,0x28,0x10,0x02,0x64,0x01,0xa9,0x00 } }, -{ 16, 0xb0c0, 0, {0x22,0x4b,0x0b,0x90,0x02,0x24,0x01,0xb9,0x00,0x2e,0x41,0x28,0x90,0x02,0x06,0x00 } }, -{ 16, 0xb0d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x90,0x81,0xa0,0x20,0x48 } }, -{ 16, 0xb0e0, 0, {0x0a,0x32,0x02,0x04,0x80,0x81,0x00,0x20,0x44,0x08,0x11,0x02,0x04,0xd0,0xa1,0x20 } }, -{ 16, 0xb0f0, 0, {0x20,0x40,0x0b,0x11,0x02,0x06,0x00,0xb1,0x31,0x2c,0x48,0x08,0x14,0x02,0x42,0x01 } }, -{ 16, 0xb100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x42,0xc8,0x54,0x32,0x14 } }, -{ 16, 0xb110, 0, {0x0e,0x85,0x03,0x21,0x44,0xc8,0x28,0xb2,0x1a,0x4c,0x86,0x93,0x61,0x14,0xe8,0x50 } }, -{ 16, 0xb120, 0, {0x22,0x14,0x0f,0x86,0x83,0x21,0x40,0xf0,0x40,0x1e,0x14,0x0c,0x00,0x03,0x2e,0x03 } }, -{ 16, 0xb130, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0x74,0x44,0xf5,0x10,0x3f,0x44 } }, -{ 16, 0xb140, 0, {0x0d,0x91,0x03,0x74,0x40,0xf9,0x00,0x3e,0x48,0x0b,0x92,0x03,0xe4,0xc2,0xd9,0x10 } }, -{ 16, 0xb150, 0, {0xbf,0x40,0x0f,0x92,0x03,0xe5,0x04,0xf9,0x30,0x3e,0x44,0x0f,0x94,0x43,0xe6,0x06 } }, -{ 16, 0xb160, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x22,0xcd,0xa1,0x33,0x61 } }, -{ 16, 0xb170, 0, {0x0c,0xd8,0xd3,0x34,0x10,0xcd,0xa8,0x3e,0x60,0x8e,0x9c,0x93,0xa7,0x08,0xcd,0x80 } }, -{ 16, 0xb180, 0, {0x33,0x40,0x0e,0x9a,0xd3,0x36,0xa0,0xc9,0x80,0x32,0x60,0x0c,0x99,0x03,0x06,0x00 } }, -{ 16, 0xb190, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe3,0x88,0x8a,0xa0,0x20,0x28 } }, -{ 16, 0xb1a0, 0, {0x08,0x80,0x22,0x20,0x12,0x88,0x40,0x2c,0x28,0x08,0x8a,0x02,0x22,0x00,0x88,0x00 } }, -{ 16, 0xb1b0, 0, {0x22,0x00,0x0b,0x8c,0x03,0x21,0x00,0x88,0xd0,0xa2,0x3e,0x28,0x8d,0x02,0x0e,0x04 } }, -{ 16, 0xb1c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xce,0x20,0xa1,0x48,0x20,0x52 } }, -{ 16, 0xb1d0, 0, {0x29,0x10,0x02,0x24,0x03,0x81,0x00,0x2c,0x52,0x0a,0x10,0x12,0x85,0x10,0x91,0x40 } }, -{ 16, 0xb1e0, 0, {0xa4,0x40,0x0a,0x12,0x82,0x44,0x00,0x91,0x28,0x24,0x40,0x28,0x12,0x02,0x02,0x01 } }, -{ 16, 0xb1f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0xa9,0x14,0x22,0x40 } }, -{ 16, 0xb200, 0, {0x09,0x90,0x02,0xa4,0x01,0x89,0x04,0x2c,0x40,0x08,0x90,0x02,0x24,0x00,0x99,0x00 } }, -{ 16, 0xb210, 0, {0x22,0x44,0x4b,0x10,0x42,0x24,0x14,0x99,0x00,0x26,0x40,0x08,0x10,0x02,0x06,0x04 } }, -{ 16, 0xb220, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x40,0xe9,0x40,0xb2,0x78 } }, -{ 16, 0xb230, 0, {0x0d,0x90,0x0b,0x24,0x22,0xc9,0x03,0x3e,0x41,0x0e,0x90,0x03,0xa4,0x02,0xd9,0x00 } }, -{ 16, 0xb240, 0, {0x16,0x58,0x06,0x90,0x0b,0x64,0x02,0xd9,0x00,0x36,0x40,0x0c,0x90,0x0b,0x28,0x04 } }, -{ 16, 0xb250, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x84,0x00,0xd9,0x80,0x3e,0x4a } }, -{ 16, 0xb260, 0, {0x0e,0x90,0x03,0x64,0x20,0xf9,0x08,0x3e,0x41,0x0f,0x90,0x03,0xe4,0x00,0xe1,0x08 } }, -{ 16, 0xb270, 0, {0x3e,0x40,0x0f,0x90,0x03,0xc4,0x00,0xe1,0x00,0x38,0x40,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0xb280, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x09,0xf0,0x40,0xb0,0x10 } }, -{ 16, 0xb290, 0, {0x4c,0x00,0x0b,0x20,0x00,0xf8,0x00,0x3a,0x00,0x1c,0x00,0x03,0xe0,0x00,0xc8,0x00 } }, -{ 16, 0xb2a0, 0, {0x36,0x00,0x0c,0x80,0x03,0x20,0x00,0xc8,0x00,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04 } }, -{ 16, 0xb2b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x28,0x00,0x3e,0x88,0x23,0xa2 } }, -{ 16, 0xb2c0, 0, {0x48,0xe0,0x00,0x19,0x80,0xbe,0x88,0x2e,0x80,0x0d,0xa0,0x42,0xe8,0x00,0x8e,0x00 } }, -{ 16, 0xb2d0, 0, {0x23,0x90,0x08,0xa0,0x0a,0x3a,0x00,0xda,0x00,0x36,0x80,0x0b,0xa0,0x0a,0x0a,0x00 } }, -{ 16, 0xb2e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x80,0x20,0xe0 } }, -{ 16, 0xb2f0, 0, {0x28,0x30,0xc2,0x0f,0x10,0xb3,0x40,0x28,0xc0,0x0b,0x30,0x02,0xec,0x11,0x83,0x40 } }, -{ 16, 0xb300, 0, {0x28,0xd2,0x0a,0x30,0x02,0x0c,0xc0,0x83,0x00,0x20,0xc0,0x0b,0x30,0x02,0x0a,0x00 } }, -{ 16, 0xb310, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x00,0xb6,0x00,0x21,0xc0 } }, -{ 16, 0xb320, 0, {0x08,0x20,0xc2,0x1c,0x10,0xb5,0x00,0x2d,0xc8,0x0a,0x72,0x02,0xdc,0x40,0x85,0x08 } }, -{ 16, 0xb330, 0, {0x29,0xa2,0x1a,0x72,0x22,0x0c,0x00,0x93,0x30,0x05,0xc4,0x0b,0x32,0x22,0x28,0x00 } }, -{ 16, 0xb340, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x16,0x00,0xb2,0x80,0x31,0x20 } }, -{ 16, 0xb350, 0, {0x0c,0x58,0x03,0x1e,0x00,0xf7,0x80,0x39,0xf8,0x0b,0x7c,0x22,0xce,0x40,0xcf,0x80 } }, -{ 16, 0xb360, 0, {0x9b,0x60,0x2e,0x3b,0x03,0x1a,0x00,0xc7,0xa8,0x11,0xe0,0x0f,0x78,0x03,0x2a,0x02 } }, -{ 16, 0xb370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xa4,0x00,0xfa,0x00,0x3e,0xc0 } }, -{ 16, 0xb380, 0, {0x0f,0x90,0x23,0xe8,0x00,0xfb,0x00,0x3e,0xd0,0x2d,0xb6,0x03,0xed,0x02,0xf9,0x00 } }, -{ 16, 0xb390, 0, {0x32,0x40,0x0d,0xb0,0x07,0xec,0x00,0xfb,0x60,0x3e,0xc8,0x0f,0xb5,0x03,0xc2,0x06 } }, -{ 16, 0xb3a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xff,0x80,0x33,0xa0 } }, -{ 16, 0xb3b0, 0, {0x0c,0xf8,0x0b,0x32,0x40,0xce,0x81,0x37,0xf0,0x0c,0xbc,0x03,0xfe,0x00,0xff,0x84 } }, -{ 16, 0xb3c0, 0, {0x33,0xe0,0x2c,0xf8,0x83,0xe6,0x02,0xcf,0x85,0x33,0xf0,0x0c,0xfc,0x03,0x00,0x14 } }, -{ 16, 0xb3d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0xbe,0x00,0x35,0xc6 } }, -{ 16, 0xb3e0, 0, {0x28,0x30,0x02,0x30,0x40,0x87,0x00,0x23,0xc0,0x08,0x7a,0x02,0xdc,0x00,0xbe,0x00 } }, -{ 16, 0xb3f0, 0, {0x23,0xc0,0x08,0x70,0x12,0xfe,0x00,0x87,0x00,0x21,0xc0,0x08,0xf0,0x02,0x2a,0x04 } }, -{ 16, 0xb400, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x20,0xb6,0x00,0x20,0x80 } }, -{ 16, 0xb410, 0, {0x08,0x31,0x02,0x5c,0x01,0x87,0x00,0x25,0xc0,0x08,0x72,0x02,0xdc,0x00,0xb6,0x00 } }, -{ 16, 0xb420, 0, {0x21,0xd0,0x09,0x70,0x02,0xd4,0x08,0x93,0x00,0x20,0xc0,0x08,0x70,0x02,0x00,0x00 } }, -{ 16, 0xb430, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xc4,0x00,0xb0,0xe0,0x24,0x60 } }, -{ 16, 0xb440, 0, {0x08,0x20,0x06,0x48,0x01,0x80,0x00,0x20,0xc0,0x08,0x30,0x02,0xcc,0x04,0xb3,0x00 } }, -{ 16, 0xb450, 0, {0x20,0x84,0x0b,0x30,0x02,0xe8,0x00,0x9b,0x00,0x20,0xc0,0x08,0x30,0x02,0x08,0x04 } }, -{ 16, 0xb460, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xb9,0xe0,0x32,0x80 } }, -{ 16, 0xb470, 0, {0x6c,0xb0,0x23,0x6f,0x00,0xc3,0x00,0x37,0xc1,0x3c,0xf0,0x03,0xfc,0x00,0xfa,0x00 } }, -{ 16, 0xb480, 0, {0xb0,0xc0,0x09,0xf0,0x03,0xec,0x10,0xdf,0x00,0x73,0xc0,0x0c,0xf0,0x0b,0x2a,0x00 } }, -{ 16, 0xb490, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x10,0xf8,0x00,0x3e,0x42 } }, -{ 16, 0xb4a0, 0, {0x0f,0x24,0x03,0xa8,0x60,0xf8,0x00,0x3c,0xc1,0x0f,0xb0,0x03,0xec,0x00,0xf9,0x40 } }, -{ 16, 0xb4b0, 0, {0x3e,0x80,0x04,0xb0,0x23,0xe1,0x00,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xe0,0x00 } }, -{ 16, 0xb4c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf4,0x00,0xee,0x00,0x3d,0x30 } }, -{ 16, 0xb4d0, 0, {0x0c,0xc0,0x03,0x14,0x00,0xcc,0xa0,0xb3,0xc0,0x4c,0x70,0x03,0x5c,0x10,0xdf,0x00 } }, -{ 16, 0xb4e0, 0, {0x3f,0x00,0x0c,0xf0,0x03,0xf8,0x00,0xcf,0x00,0x23,0xc0,0x0c,0xf0,0x03,0x00,0x40 } }, -{ 16, 0xb4f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x64,0x00,0xba,0x81,0x2e,0x58 } }, -{ 16, 0xb500, 0, {0x08,0x88,0x02,0x27,0x80,0x89,0x20,0x22,0xc0,0x28,0xb0,0x02,0x2c,0x00,0x88,0x83 } }, -{ 16, 0xb510, 0, {0x2e,0x20,0x05,0xb0,0x62,0xe3,0x00,0x8b,0x00,0x2a,0xc0,0x08,0xb0,0x03,0x60,0x40 } }, -{ 16, 0xb520, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x26,0x00,0xb9,0x81,0x2e,0x40 } }, -{ 16, 0xb530, 0, {0x08,0x8c,0x06,0x26,0x00,0x88,0x00,0x22,0xc0,0x08,0xb0,0x16,0x6c,0x00,0x98,0x88 } }, -{ 16, 0xb540, 0, {0x2e,0x20,0x08,0xb0,0x04,0xe3,0x01,0x0b,0x00,0x28,0xc0,0x08,0x30,0x02,0x20,0x00 } }, -{ 16, 0xb550, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0xb0,0x00,0x2c,0xc0 } }, -{ 16, 0xb560, 0, {0x28,0x00,0x0e,0x00,0x10,0x80,0x00,0x20,0xc0,0x08,0x32,0x02,0x0c,0x00,0x80,0x04 } }, -{ 16, 0xb570, 0, {0x2e,0x20,0x09,0x30,0x02,0xc4,0x12,0x83,0x00,0x28,0xc0,0x08,0x30,0x02,0x42,0x01 } }, -{ 16, 0xb580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xfa,0x00,0x3e,0x00 } }, -{ 16, 0xb590, 0, {0x2c,0x91,0x03,0x20,0x00,0x8a,0x00,0x33,0xc0,0x0c,0xf0,0x03,0x7c,0x00,0xd8,0x00 } }, -{ 16, 0xb5a0, 0, {0x2e,0x40,0x0c,0xf0,0x03,0xe0,0x80,0xcf,0x00,0x3b,0xc0,0x0c,0xf0,0x03,0x00,0x03 } }, -{ 16, 0xb5b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xfc,0x00,0xfc,0x01,0x3f,0x40 } }, -{ 16, 0xb5c0, 0, {0x0f,0xc0,0x13,0xf0,0x00,0xf4,0x00,0x3f,0xc1,0x0f,0xf4,0x23,0xfc,0x08,0xfc,0x00 } }, -{ 16, 0xb5d0, 0, {0x3f,0x00,0x0f,0xf0,0x03,0xf0,0x40,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8,0x06 } }, -{ 16, 0xb5e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x20,0xcd,0x10,0x39,0xc8 } }, -{ 16, 0xb5f0, 0, {0x0d,0xc1,0x03,0x3c,0x80,0xef,0x90,0x23,0xd8,0x0f,0xf8,0x00,0xfe,0x00,0xcf,0x80 } }, -{ 16, 0xb600, 0, {0x1f,0xd0,0x0f,0xf9,0x03,0xff,0x00,0xe7,0xc0,0x33,0xc4,0x0f,0xf0,0x03,0xb0,0x00 } }, -{ 16, 0xb610, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0xfe,0x02,0x89,0x40,0x23,0xf0 } }, -{ 16, 0xb620, 0, {0x08,0x85,0x10,0x3c,0x00,0x8b,0x00,0xa3,0xdc,0x4b,0xb2,0x82,0xec,0x20,0x8b,0x00 } }, -{ 16, 0xb630, 0, {0x26,0xc0,0x4b,0xb0,0x02,0xec,0x10,0xb9,0x04,0x2a,0xc9,0x0b,0xb5,0x80,0xf0,0x04 } }, -{ 16, 0xb640, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0xcc,0x00,0x81,0x64,0x28,0xc4 } }, -{ 16, 0xb650, 0, {0x09,0xb2,0x0a,0x0c,0xf0,0xa3,0x20,0x20,0xc8,0x0b,0x32,0x02,0xec,0x02,0x83,0x08 } }, -{ 16, 0xb660, 0, {0x2c,0xc8,0x09,0x32,0x02,0xcc,0x80,0xab,0xa0,0x20,0xc8,0x0b,0x32,0x00,0xb2,0x01 } }, -{ 16, 0xb670, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x10,0x89,0x00,0x22,0xc0 } }, -{ 16, 0xb680, 0, {0x08,0xb2,0x12,0x2c,0x02,0x0b,0x00,0x22,0xc0,0x0b,0xb8,0x02,0xec,0x00,0x8b,0x00 } }, -{ 16, 0xb690, 0, {0x26,0xc0,0x4b,0xb0,0x46,0xec,0x00,0xb9,0x00,0x0a,0xc0,0x0b,0xb0,0x02,0xf0,0x04 } }, -{ 16, 0xb6a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x15,0xec,0x10,0xc9,0xe0,0x3a,0xc0 } }, -{ 16, 0xb6b0, 0, {0x0d,0x28,0x03,0x2c,0x00,0xeb,0x10,0x32,0xc0,0x0f,0x82,0x03,0xc4,0x00,0xcb,0x00 } }, -{ 16, 0xb6c0, 0, {0x3e,0xc1,0x0f,0xb0,0x06,0xec,0x08,0xe9,0x00,0xb2,0xc0,0x0f,0xb0,0x13,0x90,0x04 } }, -{ 16, 0xb6d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x9c,0x00,0xf5,0xa0,0x3f,0xc0 } }, -{ 16, 0xb6e0, 0, {0x0f,0xe8,0x03,0xfc,0x08,0xff,0x00,0x3f,0xc0,0x8f,0xc0,0x03,0xfc,0x00,0xff,0x00 } }, -{ 16, 0xb6f0, 0, {0x37,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x04,0x3e,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0xb700, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x10,0xac,0x00,0xf9,0x40,0x34,0xc0 } }, -{ 16, 0xb710, 0, {0x0d,0xb4,0x03,0x2c,0x00,0xdb,0x40,0x3e,0xc0,0x2c,0x80,0x03,0x64,0x08,0xfb,0x10 } }, -{ 16, 0xb720, 0, {0x3e,0xc6,0x8f,0xb0,0x03,0xec,0x00,0xf9,0x80,0x32,0xc0,0x0c,0xb0,0x0b,0x14,0x04 } }, -{ 16, 0xb730, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x3e,0x20,0xe9,0xc8,0x37,0xd4 } }, -{ 16, 0xb740, 0, {0x48,0xaa,0x22,0x1c,0x00,0x8b,0x00,0x6f,0xe0,0x08,0x85,0x82,0xed,0x40,0xbb,0x84 } }, -{ 16, 0xb750, 0, {0x2f,0xc0,0x4b,0xb8,0x03,0xad,0x40,0xb3,0x00,0x23,0xd4,0x08,0xf7,0x02,0x32,0x00 } }, -{ 16, 0xb760, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x4c,0x00,0xb1,0x64,0xa4,0xc0 } }, -{ 16, 0xb770, 0, {0x09,0x20,0x0a,0x0c,0x04,0xb8,0x00,0x6c,0xc0,0x08,0x38,0x02,0xc8,0x40,0xb3,0x80 } }, -{ 16, 0xb780, 0, {0x2c,0xd1,0x0b,0x30,0x02,0xcc,0x04,0xb3,0x00,0x28,0xc0,0x08,0x30,0x02,0x3a,0x00 } }, -{ 16, 0xb790, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x01,0x1e,0x00,0xa5,0x80,0x25,0xe0 } }, -{ 16, 0xb7a0, 0, {0x88,0x3a,0x12,0x1e,0x00,0xa6,0x90,0x2d,0xe2,0x08,0x79,0x02,0xda,0x00,0xb7,0x82 } }, -{ 16, 0xb7b0, 0, {0x2d,0xe0,0x03,0x78,0x82,0x9e,0x00,0xbc,0xc1,0x29,0xe0,0x08,0x78,0x02,0x2c,0x10 } }, -{ 16, 0xb7c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x08,0x0c,0x00,0xf3,0x00,0x34,0xc0 } }, -{ 16, 0xb7d0, 0, {0x0d,0x3e,0x03,0x0c,0x00,0xf0,0x40,0x2e,0xc0,0x0c,0x30,0x43,0xc8,0x00,0xf3,0x00 } }, -{ 16, 0xb7e0, 0, {0x3c,0xc0,0x07,0x30,0x03,0xcc,0x80,0xf2,0x00,0x38,0xc0,0x0c,0x30,0x03,0x12,0x02 } }, -{ 16, 0xb7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x19,0xbd,0x20,0xf7,0x00,0x3f,0xc2 } }, -{ 16, 0xb800, 0, {0x0f,0xf1,0x0b,0xdc,0x20,0xde,0x04,0x3f,0xd2,0x07,0xf0,0x13,0xf8,0x40,0xff,0x00 } }, -{ 16, 0xb810, 0, {0x3f,0xc0,0x07,0xf0,0x03,0xfc,0x00,0xfd,0x00,0x37,0xc0,0x0f,0x70,0x03,0xd0,0x06 } }, -{ 16, 0xb820, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x05,0xcf,0x00,0xdc,0x00,0x3e,0xca } }, -{ 16, 0xb830, 0, {0x0f,0xa0,0x00,0xac,0x92,0xc9,0x00,0x32,0xc0,0x0f,0xb0,0x11,0xa4,0x08,0xfb,0x00 } }, -{ 16, 0xb840, 0, {0x2e,0xc0,0x4f,0xb0,0x23,0xec,0x00,0xf9,0x00,0x3e,0xc4,0x0f,0xb0,0x03,0xea,0x00 } }, -{ 16, 0xb850, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x91,0x9c,0x00,0x84,0x00,0x01,0xc0 } }, -{ 16, 0xb860, 0, {0x4b,0x70,0x22,0x1c,0xc0,0x87,0x00,0x21,0xc0,0x4b,0x70,0x02,0x1c,0x00,0xb7,0x01 } }, -{ 16, 0xb870, 0, {0x25,0xd8,0x0b,0x70,0x22,0xdc,0x00,0xb6,0x00,0x2d,0xc0,0x0b,0x72,0x22,0xf2,0x04 } }, -{ 16, 0xb880, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x80,0x97,0x80,0xa9,0xe0 } }, -{ 16, 0xb890, 0, {0x0b,0xf8,0x02,0xce,0x08,0x85,0x80,0x29,0xe8,0x0b,0xfc,0x02,0x17,0x00,0xb7,0x80 } }, -{ 16, 0xb8a0, 0, {0x2d,0xe0,0x8b,0x78,0x02,0xde,0x00,0xb4,0xc0,0x2d,0xe8,0x0b,0x79,0x02,0xe0,0x00 } }, -{ 16, 0xb8b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0x83,0x08,0xa0,0xc0 } }, -{ 16, 0xb8c0, 0, {0x8b,0x3c,0x02,0x4c,0x00,0x83,0x00,0xa0,0xc0,0x1b,0x3c,0x0a,0x0f,0x29,0xb3,0x00 } }, -{ 16, 0xb8d0, 0, {0x24,0xc0,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x80,0x2c,0xc0,0x0b,0x30,0x02,0xd2,0x04 } }, -{ 16, 0xb8e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xde,0x00,0x3a,0x80 } }, -{ 16, 0xb8f0, 0, {0x0f,0xea,0x02,0xe8,0x00,0xce,0x00,0x3a,0x80,0x0f,0xe0,0x03,0x38,0x00,0xfa,0x00 } }, -{ 16, 0xb900, 0, {0x3e,0x80,0x0f,0xa0,0x03,0xe8,0x00,0xfe,0x00,0x3e,0x80,0x0b,0xa0,0x03,0xfa,0x04 } }, -{ 16, 0xb910, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x00,0xf8,0x04,0xba,0x01 } }, -{ 16, 0xb920, 0, {0x0f,0x82,0x0b,0x80,0x04,0xf8,0x80,0x3e,0x00,0x0f,0x86,0x03,0x60,0x00,0xf8,0x00 } }, -{ 16, 0xb930, 0, {0x36,0x00,0x0f,0x80,0x23,0xe1,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xb940, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x01,0xf9,0x00,0x32,0x40 } }, -{ 16, 0xb950, 0, {0x0f,0x90,0x03,0xe4,0x00,0x49,0x00,0x32,0x40,0x0b,0x90,0x03,0x24,0x00,0x49,0x00 } }, -{ 16, 0xb960, 0, {0x3c,0x40,0x0d,0x90,0x03,0xe4,0x08,0xc9,0x00,0x3e,0x60,0x0c,0x90,0x03,0x02,0x04 } }, -{ 16, 0xb970, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x00,0xb9,0x40,0xa2,0x64 } }, -{ 16, 0xb980, 0, {0x0b,0x18,0x02,0x25,0x00,0xd1,0x50,0x36,0x50,0x4e,0x90,0x0a,0x24,0x02,0x89,0x40 } }, -{ 16, 0xb990, 0, {0x3a,0x51,0x08,0x94,0x02,0xe5,0x22,0x89,0x44,0x2e,0x60,0x28,0x90,0x0a,0x20,0x00 } }, -{ 16, 0xb9a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xb1,0x08,0x22,0x40 } }, -{ 16, 0xb9b0, 0, {0x4b,0x92,0x82,0xa5,0x00,0xa9,0x08,0x22,0x50,0x0a,0x10,0x02,0x0c,0x00,0xa9,0x40 } }, -{ 16, 0xb9c0, 0, {0x6e,0x50,0x0b,0x94,0x02,0xc4,0x04,0x89,0x44,0x6c,0x48,0x88,0x10,0x02,0x46,0x00 } }, -{ 16, 0xb9d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x00,0xb1,0x40,0xe0,0x40 } }, -{ 16, 0xb9e0, 0, {0x1b,0x14,0x0a,0x04,0x00,0xb9,0x00,0x24,0x40,0x1a,0x10,0x22,0x04,0x00,0xa1,0x00 } }, -{ 16, 0xb9f0, 0, {0x28,0x40,0x0a,0x10,0x12,0xc4,0x00,0x81,0x02,0x6c,0x40,0x08,0x12,0x02,0x42,0x01 } }, -{ 16, 0xba00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x08,0xb0,0x00,0x32,0x00 } }, -{ 16, 0xba10, 0, {0x4f,0x80,0x02,0xa1,0x50,0xe0,0x50,0x32,0x14,0x0e,0xa5,0x23,0x21,0x40,0xe8,0x50 } }, -{ 16, 0xba20, 0, {0x3e,0x14,0x0f,0x85,0x03,0xe1,0x40,0xc8,0x50,0x1e,0x14,0x0c,0x85,0x43,0x6e,0x03 } }, -{ 16, 0xba30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd8,0x19,0xe5,0x00,0xfd,0x40,0x3e,0x50 } }, -{ 16, 0xba40, 0, {0x0f,0x74,0x03,0xa5,0x00,0x5d,0x00,0x3e,0x50,0x0a,0x50,0x13,0xf4,0x00,0xd9,0x00 } }, -{ 16, 0xba50, 0, {0x3a,0x50,0x0d,0x90,0x13,0xe4,0x00,0xff,0x00,0x3e,0x50,0x0f,0x91,0x03,0xa6,0x06 } }, -{ 16, 0xba60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x90,0xbd,0xe8,0x23,0x6b } }, -{ 16, 0xba70, 0, {0x0b,0xda,0x0b,0x36,0x80,0xc9,0x00,0x32,0x68,0x46,0x90,0x43,0xe4,0x00,0x49,0x00 } }, -{ 16, 0xba80, 0, {0x32,0x68,0x0c,0x90,0x03,0x24,0x40,0xf9,0x00,0x32,0x60,0x0c,0x9c,0x03,0xc6,0x01 } }, -{ 16, 0xba90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x10,0xe1,0x00,0xb8,0xe0,0xa2,0x11 } }, -{ 16, 0xbaa0, 0, {0x0b,0x8e,0x0a,0x23,0x22,0x88,0x80,0x2a,0x31,0x28,0x88,0x02,0x62,0x00,0x88,0x80 } }, -{ 16, 0xbab0, 0, {0xa2,0x30,0x28,0x88,0x8a,0x22,0x00,0xb8,0xa8,0xa2,0x39,0x08,0xca,0x02,0xce,0x04 } }, -{ 16, 0xbac0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc5,0x08,0x21,0x00,0x00,0x40 } }, -{ 16, 0xbad0, 0, {0x03,0x14,0x82,0x85,0x80,0xad,0x08,0x21,0x52,0x98,0x50,0x82,0x34,0x23,0x85,0x08 } }, -{ 16, 0xbae0, 0, {0x21,0x52,0x08,0x50,0x06,0x54,0x00,0xb5,0x20,0x21,0x5a,0x09,0x54,0x02,0xd2,0x01 } }, -{ 16, 0xbaf0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xa4,0x00,0xb9,0x61,0x22,0x40 } }, -{ 16, 0xbb00, 0, {0x0b,0x90,0x06,0x04,0x00,0xad,0x00,0x69,0x40,0x08,0xd0,0x02,0x74,0x00,0x85,0x00 } }, -{ 16, 0xbb10, 0, {0x01,0x40,0x00,0x70,0x06,0x74,0x04,0xb5,0x00,0x23,0x40,0x09,0xd0,0x02,0xc6,0x04 } }, -{ 16, 0xbb20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x14,0xa4,0x00,0xe9,0x00,0x32,0x40 } }, -{ 16, 0xbb30, 0, {0x4f,0x95,0x0b,0xa4,0x00,0xe9,0x00,0x32,0x40,0x8c,0x90,0x03,0x24,0x00,0xc9,0x00 } }, -{ 16, 0xbb40, 0, {0x32,0x40,0x0c,0x90,0x03,0x64,0x08,0xf9,0x00,0x32,0x40,0x3d,0x90,0x03,0xe8,0x04 } }, -{ 16, 0xbb50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x01,0xa4,0x08,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0xbb60, 0, {0x4f,0x90,0x8b,0xe4,0x04,0xd9,0x01,0x3e,0x40,0x0d,0x90,0x03,0x64,0x00,0xd9,0x01 } }, -{ 16, 0xbb70, 0, {0x3e,0x40,0x0f,0x90,0x03,0xa4,0x00,0xf9,0x00,0x3c,0x40,0x0e,0x90,0x03,0xda,0x00 } }, -{ 16, 0xbb80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x40,0x36,0x20 } }, -{ 16, 0xbb90, 0, {0x17,0x84,0x03,0x20,0x21,0xc8,0x00,0x7e,0x02,0x2c,0x80,0x43,0x20,0x00,0xe8,0x02 } }, -{ 16, 0xbba0, 0, {0x3e,0x01,0x0f,0x80,0x03,0xe0,0x00,0xc8,0x40,0x1e,0x00,0x0f,0x80,0x03,0xca,0x04 } }, -{ 16, 0xbbb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x2a,0x88,0xb6,0x02,0x23,0xa0 } }, -{ 16, 0xbbc0, 0, {0x0b,0xec,0x42,0x2b,0x00,0xd2,0x80,0x6e,0xb1,0x08,0xa0,0x22,0x08,0x00,0xea,0x04 } }, -{ 16, 0xbbd0, 0, {0x3a,0x80,0x9f,0xa0,0x03,0xa8,0x00,0x8a,0x04,0x2e,0x80,0x0b,0xa8,0x02,0xca,0x00 } }, -{ 16, 0xbbe0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb2,0x00,0xa4,0xe1 } }, -{ 16, 0xbbf0, 0, {0x8b,0xb4,0x32,0x47,0x45,0x83,0x90,0x2c,0xf4,0x4b,0x38,0x12,0x0e,0x44,0xa3,0x01 } }, -{ 16, 0xbc00, 0, {0x2c,0xc0,0x4b,0x30,0x02,0xce,0x00,0x93,0x00,0x6c,0xc0,0x0b,0x38,0x02,0xca,0x00 } }, -{ 16, 0xbc10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x00,0xb7,0x44,0x21,0xc2 } }, -{ 16, 0xbc20, 0, {0x0b,0x54,0x02,0x54,0x05,0x87,0x00,0x2c,0x40,0x9b,0x6c,0x02,0x18,0x10,0xa7,0x04 } }, -{ 16, 0xbc30, 0, {0x29,0xc0,0x0a,0x70,0x02,0x9b,0x00,0x97,0x04,0x0d,0x80,0x0b,0x60,0x82,0xe8,0x00 } }, -{ 16, 0xbc40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf3,0x80,0x35,0xe0 } }, -{ 16, 0xbc50, 0, {0x0b,0x38,0x02,0x52,0x10,0x84,0x80,0x2d,0xa0,0x0f,0xf8,0x0b,0x1e,0x00,0xe6,0x80 } }, -{ 16, 0xbc60, 0, {0x1d,0xa0,0x0b,0x68,0x03,0xfe,0x02,0xd6,0x80,0x3d,0xe0,0x0f,0x78,0x03,0xea,0x02 } }, -{ 16, 0xbc70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x1d,0xac,0x00,0xfb,0x00,0x3e,0xc1 } }, -{ 16, 0xbc80, 0, {0x8b,0x90,0x0b,0x80,0x0a,0xb8,0x01,0x2e,0x00,0x0c,0xb0,0x03,0xe8,0x00,0xfa,0x00 } }, -{ 16, 0xbc90, 0, {0x3e,0xc0,0x0f,0xa0,0x43,0xec,0x00,0xeb,0x00,0x3e,0x80,0x0f,0xa6,0x23,0xc2,0x02 } }, -{ 16, 0xbca0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xfe,0x80,0x33,0x20 } }, -{ 16, 0xbcb0, 0, {0x4e,0xc9,0x12,0xf6,0x50,0xef,0x90,0x3f,0xe0,0x0c,0x19,0x00,0xb6,0x42,0xcf,0x21 } }, -{ 16, 0xbcc0, 0, {0x3f,0xe0,0x0e,0xf9,0x02,0xe6,0xc0,0xff,0x80,0x3f,0xe0,0x4c,0xdc,0x03,0x40,0x00 } }, -{ 16, 0xbcd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x11,0x94,0x00,0xb7,0x00,0x81,0x40 } }, -{ 16, 0xbce0, 0, {0x08,0x03,0x02,0x14,0xc4,0x87,0x01,0x2d,0xc8,0x08,0x6a,0x12,0x38,0x40,0x87,0x02 } }, -{ 16, 0xbcf0, 0, {0x2d,0xc0,0x08,0x71,0x12,0xd2,0x80,0xb7,0x00,0x2d,0x80,0x08,0x60,0x02,0x2a,0x04 } }, -{ 16, 0xbd00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x10,0x21,0x80 } }, -{ 16, 0xbd10, 0, {0x08,0xf4,0x12,0x94,0x04,0xa6,0x00,0x2c,0xc0,0x18,0xd2,0x02,0x14,0x48,0x86,0x10 } }, -{ 16, 0xbd20, 0, {0x2d,0x80,0x0a,0x61,0x32,0xd4,0x00,0xb6,0x18,0x2d,0xc4,0x08,0x58,0x02,0x00,0x10 } }, -{ 16, 0xbd30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xc4,0x00,0xb3,0x00,0x20,0xc0 } }, -{ 16, 0xbd40, 0, {0x40,0xb0,0x22,0x04,0x00,0x82,0x81,0x0c,0xc0,0x08,0x30,0x0a,0x0a,0x00,0x8a,0x00 } }, -{ 16, 0xbd50, 0, {0x2e,0xc0,0x08,0xa0,0x02,0xc4,0x00,0xbb,0x00,0x2e,0x80,0x08,0x20,0x02,0x08,0x04 } }, -{ 16, 0xbd60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xfb,0x00,0xa0,0xc0 } }, -{ 16, 0xbd70, 0, {0x24,0x94,0x23,0xac,0x10,0xeb,0xa0,0x0e,0xc0,0x0c,0xb0,0x02,0x2e,0x20,0xc9,0x00 } }, -{ 16, 0xbd80, 0, {0x2e,0x40,0x0e,0x90,0x03,0xec,0x00,0xf9,0x80,0x3e,0x40,0x6c,0xa0,0x0b,0x2a,0x04 } }, -{ 16, 0xbd90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xcc,0x00,0xfb,0x00,0x3e,0xc0 } }, -{ 16, 0xbda0, 0, {0x89,0x90,0x03,0x2c,0x00,0xfb,0x02,0x3e,0x40,0x4f,0xa0,0x03,0x6d,0x01,0xfb,0x41 } }, -{ 16, 0xbdb0, 0, {0x3e,0xc0,0x8f,0xb4,0x03,0xe8,0x00,0xfb,0x20,0x3e,0x50,0x0f,0xa4,0x03,0xe0,0x00 } }, -{ 16, 0xbdc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xc3,0x20,0xb2,0xc0 } }, -{ 16, 0xbdd0, 0, {0x0d,0xd0,0x03,0x38,0x00,0xcd,0x00,0x3f,0x80,0x0d,0xf0,0x03,0xfc,0x00,0xfd,0x02 } }, -{ 16, 0xbde0, 0, {0x36,0x00,0x0c,0xd0,0x03,0x3f,0x08,0xfc,0x04,0x12,0xc0,0x0c,0xa0,0x03,0xc0,0x44 } }, -{ 16, 0xbdf0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x6c,0x02,0x8b,0xc8,0x22,0xc0 } }, -{ 16, 0xbe00, 0, {0x08,0x98,0x0a,0x2a,0x40,0x89,0x20,0x2e,0x01,0x8e,0xb0,0x12,0xec,0x80,0xbb,0xf0 } }, -{ 16, 0xbe10, 0, {0x22,0xe5,0x08,0xbd,0x02,0x2e,0x00,0xbb,0x90,0x22,0xed,0x08,0xa2,0x02,0xe0,0x00 } }, -{ 16, 0xbe20, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x01,0x22,0x00 } }, -{ 16, 0xbe30, 0, {0x49,0xa8,0x1e,0x04,0x00,0x8b,0x01,0x2e,0xc0,0x49,0x90,0x02,0xe4,0x00,0xb9,0x00 } }, -{ 16, 0xbe40, 0, {0x22,0x40,0x0a,0x90,0x02,0x2c,0x00,0xb9,0x00,0x2a,0x40,0x08,0x80,0x02,0xe0,0x00 } }, -{ 16, 0xbe50, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x00,0x81,0x00,0x20,0x40 } }, -{ 16, 0xbe60, 0, {0x08,0x20,0x02,0x04,0x00,0x83,0x00,0x2c,0xc0,0x0a,0x20,0x42,0xcc,0x00,0xb3,0x00 } }, -{ 16, 0xbe70, 0, {0x20,0xc0,0x02,0x30,0x02,0x08,0x84,0xb3,0x04,0x08,0x40,0x08,0x20,0x02,0xc2,0x11 } }, -{ 16, 0xbe80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0x8b,0x00,0xb2,0x80 } }, -{ 16, 0xbe90, 0, {0x0d,0xb1,0x03,0x24,0x02,0xcb,0x01,0x3e,0xc0,0x4d,0x90,0x43,0xe4,0x00,0xf9,0x00 } }, -{ 16, 0xbea0, 0, {0xb2,0x00,0x2e,0x90,0x0b,0x2c,0x80,0xf8,0x00,0xba,0xc0,0x2c,0x80,0x03,0xc0,0x03 } }, -{ 16, 0xbeb0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf4,0x00,0x7d,0x00,0x3f,0xc0 } }, -{ 16, 0xbec0, 0, {0x0f,0x72,0x03,0xd4,0x00,0xff,0x00,0x3f,0xc0,0x0e,0xf1,0x47,0xfc,0x00,0xff,0x00 } }, -{ 16, 0xbed0, 0, {0x3b,0xc0,0x0d,0xf0,0x13,0xfc,0x50,0xff,0x00,0x37,0xc0,0x0f,0xe0,0x03,0xe8,0x06 } }, -{ 16, 0xbee0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0xc4,0xcc,0x33,0x3f,0x04 } }, -{ 16, 0xbef0, 0, {0x2c,0xf6,0x03,0x38,0x60,0xcc,0x90,0xb3,0x20,0x0f,0xf1,0x23,0xf0,0x60,0xff,0x01 } }, -{ 16, 0xbf00, 0, {0x23,0xc8,0x0c,0xf2,0x8a,0x3c,0x81,0xdf,0x30,0x3f,0x64,0x0c,0xd8,0x03,0x30,0x04 } }, -{ 16, 0xbf10, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe0,0xc2,0x8a,0x30,0x2e,0x18 } }, -{ 16, 0xbf20, 0, {0x08,0xf5,0x30,0xa5,0x94,0x58,0x22,0x22,0x21,0x4b,0xf3,0x02,0xe1,0x00,0x9f,0x70 } }, -{ 16, 0xbf30, 0, {0x2b,0xe4,0x0a,0xf4,0x12,0x1d,0x40,0xaf,0x72,0x2c,0x49,0x2f,0x30,0x82,0xa0,0x06 } }, -{ 16, 0xbf40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x80,0x80,0xa0,0x2c,0x98 } }, -{ 16, 0xbf50, 0, {0x08,0x32,0x22,0x08,0x00,0x82,0x00,0x28,0x00,0x03,0x32,0x02,0xc0,0x84,0xb3,0x0c } }, -{ 16, 0xbf60, 0, {0x20,0xc0,0x58,0x32,0x92,0x8c,0x30,0xa3,0x20,0x2e,0xc0,0x48,0x12,0x42,0x62,0x01 } }, -{ 16, 0xbf70, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xa8,0x00,0x8b,0x00,0x2e,0x20 } }, -{ 16, 0xbf80, 0, {0x08,0xb0,0x0a,0x20,0x01,0x98,0x00,0x2a,0x22,0x0b,0xb0,0x02,0xe6,0x00,0x9b,0x00 } }, -{ 16, 0xbf90, 0, {0x22,0xc0,0x0a,0xb0,0x12,0xac,0x04,0xab,0x00,0x2e,0xc0,0x03,0xb0,0x02,0xf0,0x00 } }, -{ 16, 0xbfa0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xe5,0x00,0xc8,0x00,0x3e,0xb0 } }, -{ 16, 0xbfb0, 0, {0x0c,0xb0,0x03,0x29,0x00,0xc8,0x00,0x3a,0x20,0x4f,0xb0,0x03,0xe2,0x20,0xfb,0x01 } }, -{ 16, 0xbfc0, 0, {0xb0,0xc0,0x0c,0xb0,0x03,0x2c,0x00,0xfb,0x02,0x3c,0x41,0x0c,0x90,0x43,0x48,0x04 } }, -{ 16, 0xbfd0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xa2,0x80,0xfe,0x40,0x3e,0x00 } }, -{ 16, 0xbfe0, 0, {0x0f,0xf0,0x63,0xec,0x00,0xbf,0xc4,0x17,0x42,0x0f,0xf0,0x03,0xec,0x00,0xff,0x00 } }, -{ 16, 0xbff0, 0, {0x1f,0xc1,0x0f,0xb0,0x03,0x5c,0x00,0xfb,0x00,0x3f,0x40,0x4f,0xf0,0x00,0xb8,0x00 } }, -{ 16, 0xc000, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa5,0x02,0xc8,0x00,0x3e,0x90 } }, -{ 16, 0xc010, 0, {0x2c,0xb0,0x0b,0x01,0x06,0xcb,0x01,0x3e,0x50,0x5f,0xb0,0x13,0x21,0x10,0xcb,0x00 } }, -{ 16, 0xc020, 0, {0x7e,0xc0,0x0c,0xb0,0x0b,0x2c,0x00,0xcb,0x00,0x32,0xc0,0x0c,0x90,0x03,0x10,0x04 } }, -{ 16, 0xc030, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x28,0x01,0x8b,0xd0,0x2c,0x34 } }, -{ 16, 0xc040, 0, {0x48,0xff,0x02,0x30,0x00,0xaa,0x04,0x2e,0x69,0x0f,0xf0,0x03,0x68,0x10,0xdf,0x00 } }, -{ 16, 0xc050, 0, {0x2f,0xd4,0x0d,0xf0,0x02,0x3e,0x00,0x5f,0x04,0xb6,0xc0,0x08,0xb0,0x03,0x72,0x00 } }, -{ 16, 0xc060, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x69,0x90,0x81,0x80,0x2c,0x00 } }, -{ 16, 0xc070, 0, {0x48,0xb8,0x02,0x08,0x09,0x99,0x00,0x4c,0xb0,0x0b,0x30,0x02,0x0c,0x00,0x8b,0x00 } }, -{ 16, 0xc080, 0, {0x2c,0xc0,0x09,0xb0,0x40,0x0c,0x40,0x83,0x00,0x00,0x40,0x0a,0x90,0x02,0x30,0x00 } }, -{ 16, 0xc090, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x00,0x84,0x88,0x2d,0xe4 } }, -{ 16, 0xc0a0, 0, {0x48,0x39,0x02,0x16,0x00,0xb4,0x80,0x2d,0xe0,0x0a,0x7b,0x06,0x5e,0x00,0x97,0x80 } }, -{ 16, 0xc0b0, 0, {0x2d,0xe2,0x09,0x78,0x02,0x1e,0x90,0x97,0x80,0x25,0x64,0x8a,0x78,0x02,0x48,0x00 } }, -{ 16, 0xc0c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0d,0x00,0x81,0x10,0x2c,0x96 } }, -{ 16, 0xc0d0, 0, {0x08,0x31,0x23,0x0c,0x00,0x90,0x20,0x3c,0xc4,0x1b,0xb8,0x02,0x08,0x40,0xc3,0x00 } }, -{ 16, 0xc0e0, 0, {0x2c,0xc4,0x0d,0x30,0x03,0x0e,0x40,0xc3,0x10,0x30,0xc0,0x4e,0x10,0x07,0x1a,0x12 } }, -{ 16, 0xc0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xbc,0x00,0x7d,0x05,0x3f,0xc5 } }, -{ 16, 0xc100, 0, {0x0f,0xb1,0x0b,0xf4,0x00,0xef,0x00,0x1f,0x45,0x0f,0xf0,0x43,0xfc,0x01,0xff,0x40 } }, -{ 16, 0xc110, 0, {0x3d,0xc4,0x1f,0xf0,0x06,0xfc,0x10,0xff,0x00,0x3b,0xc1,0x2d,0xf1,0x03,0xd0,0x06 } }, -{ 16, 0xc120, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x04,0xcb,0x04,0x3e,0xa0 } }, -{ 16, 0xc130, 0, {0x44,0xb6,0x03,0x28,0x04,0xcb,0x80,0x32,0x80,0x0f,0xb3,0x93,0x60,0x08,0xfb,0x20 } }, -{ 16, 0xc140, 0, {0x3e,0xd2,0x1f,0xb3,0x03,0x2d,0x80,0xfb,0x61,0x7e,0x40,0x8c,0x98,0x03,0x2a,0x00 } }, -{ 16, 0xc150, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x84,0x0c,0x86,0x05,0x2d,0xc0 } }, -{ 16, 0xc160, 0, {0x08,0xf4,0x82,0x8c,0x90,0x85,0x00,0xa1,0xc0,0x0b,0xf0,0x02,0x5c,0x00,0x37,0x00 } }, -{ 16, 0xc170, 0, {0x2d,0xd0,0x0b,0x71,0x02,0x1c,0xc8,0xb7,0x48,0x2d,0x40,0x0a,0x70,0x02,0x12,0x04 } }, -{ 16, 0xc180, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0x87,0x80,0x2d,0xa1 } }, -{ 16, 0xc190, 0, {0x60,0x78,0x4a,0x16,0xd0,0xa7,0x80,0x29,0xe0,0x0b,0x78,0x52,0x96,0x01,0xb7,0x90 } }, -{ 16, 0xc1a0, 0, {0x2d,0xe8,0x0b,0x7a,0x22,0x5e,0x40,0xb7,0xa0,0x2f,0xe1,0x48,0x50,0x22,0x30,0x00 } }, -{ 16, 0xc1b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x10,0x83,0x84,0x2c,0xc0 } }, -{ 16, 0xc1c0, 0, {0x08,0x30,0x02,0xa4,0x10,0x83,0xcb,0x28,0xe0,0x0b,0x30,0x2a,0x4f,0x40,0x93,0x00 } }, -{ 16, 0xc1d0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0x4c,0x10,0xb3,0x02,0x2c,0xc0,0xaa,0x30,0x02,0x12,0x04 } }, -{ 16, 0xc1e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xce,0xa0,0x3f,0x80 } }, -{ 16, 0xc1f0, 0, {0x4c,0xa0,0x2b,0x3a,0x00,0xce,0x40,0x3b,0xb8,0x0f,0xa0,0x03,0xb9,0x00,0xba,0x00 } }, -{ 16, 0xc200, 0, {0x3e,0x80,0x0f,0xa0,0x03,0x68,0x00,0xfa,0x00,0x7e,0x80,0x1c,0xa0,0x0b,0x3a,0x04 } }, -{ 16, 0xc210, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x02,0xf8,0x00,0x3e,0x04 } }, -{ 16, 0xc220, 0, {0x8f,0x00,0x03,0xe0,0x4a,0xf8,0x10,0x26,0x18,0x0f,0x80,0x03,0xa0,0x80,0xf8,0x02 } }, -{ 16, 0xc230, 0, {0x3e,0x00,0x8f,0x00,0x0b,0xa0,0x00,0xf8,0x02,0x3e,0x00,0x0f,0x80,0x13,0xd2,0x00 } }, -{ 16, 0xc240, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x20,0xc9,0x00,0x32,0x40 } }, -{ 16, 0xc250, 0, {0x4d,0x99,0x03,0x24,0x00,0xc9,0x02,0x3e,0x68,0x0f,0x90,0x02,0x24,0x00,0xe9,0x00 } }, -{ 16, 0xc260, 0, {0x30,0x40,0x8c,0x90,0x03,0x04,0x40,0xc9,0x00,0x3e,0x40,0x0c,0x90,0x03,0x02,0x04 } }, -{ 16, 0xc270, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x20,0x89,0x06,0x22,0x50 } }, -{ 16, 0xc280, 0, {0x8b,0x9c,0xc2,0x24,0x00,0xd9,0x01,0x2e,0x40,0x0b,0x90,0x42,0x24,0x08,0xb9,0x01 } }, -{ 16, 0xc290, 0, {0x22,0x46,0x0d,0x90,0x0a,0x26,0x02,0x89,0x00,0x2c,0x40,0x0a,0x10,0x02,0x20,0x00 } }, -{ 16, 0xc2a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x06,0x00,0x91,0x40,0x42,0x70 } }, -{ 16, 0xc2b0, 0, {0x0b,0x90,0x12,0x2c,0x02,0x8b,0x00,0x2e,0x40,0x0b,0x10,0x22,0xe4,0x10,0xb1,0x00 } }, -{ 16, 0xc2c0, 0, {0xa2,0x40,0x48,0x90,0x12,0x24,0x08,0x99,0x02,0x2e,0x40,0x08,0x90,0x02,0x06,0x00 } }, -{ 16, 0xc2d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x92,0x91,0x20,0xe0,0x48 } }, -{ 16, 0xc2e0, 0, {0x0b,0x12,0x02,0x04,0x02,0x91,0x10,0x2c,0xc0,0x0b,0x10,0x06,0x84,0xc0,0xb1,0x10 } }, -{ 16, 0xc2f0, 0, {0x20,0x48,0x89,0x11,0x02,0x05,0x80,0x91,0x40,0x2e,0x44,0x2a,0x94,0x02,0x02,0x01 } }, -{ 16, 0xc300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x30,0x14 } }, -{ 16, 0xc310, 0, {0x0f,0x85,0x0b,0x21,0xe0,0x80,0x40,0x3e,0x00,0x0f,0x87,0x8b,0xe1,0x0c,0xf8,0x6c } }, -{ 16, 0xc320, 0, {0x32,0x00,0x84,0x06,0x83,0x20,0x04,0xd8,0x28,0x3e,0x10,0x0c,0x00,0x03,0x2e,0x03 } }, -{ 16, 0xc330, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x40,0xad,0x10,0x3f,0x45 } }, -{ 16, 0xc340, 0, {0x0f,0x91,0x03,0xfc,0x18,0x7d,0x20,0x1f,0x41,0x0f,0x90,0x03,0x74,0xc0,0xf9,0x21 } }, -{ 16, 0xc350, 0, {0x3e,0x44,0x0f,0x92,0x01,0xe4,0x40,0xe9,0x00,0x3d,0x48,0x4f,0xd0,0x03,0xe6,0x06 } }, -{ 16, 0xc360, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf7,0x80,0xfd,0xe0,0x33,0x70 } }, -{ 16, 0xc370, 0, {0x0c,0xda,0x03,0x26,0x20,0xc9,0x40,0x31,0x40,0x0e,0x9a,0x03,0x24,0x00,0xf9,0x80 } }, -{ 16, 0xc380, 0, {0x3b,0x60,0x0f,0x9c,0x83,0x36,0xa0,0xf9,0xa1,0xb0,0x40,0x0f,0x91,0x03,0xc6,0x00 } }, -{ 16, 0xc390, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe2,0x90,0xb8,0xa0,0x22,0x28 } }, -{ 16, 0xc3a0, 0, {0x28,0x88,0x0a,0x22,0x02,0x88,0xa0,0x22,0x00,0x08,0x88,0x02,0xc2,0x80,0xb8,0x88 } }, -{ 16, 0xc3b0, 0, {0x22,0x04,0x0b,0x8e,0x03,0x22,0x80,0xb8,0xd0,0x2a,0x20,0x0b,0x88,0x02,0xce,0x04 } }, -{ 16, 0xc3c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x80,0xb1,0x61,0x00,0x58 } }, -{ 16, 0xc3d0, 0, {0x48,0x16,0x8a,0x04,0xa0,0x89,0x01,0x22,0x40,0x1a,0x14,0x88,0x04,0x20,0xb1,0x40 } }, -{ 16, 0xc3e0, 0, {0x28,0x40,0x0b,0x10,0x0a,0x04,0x20,0xb1,0x2c,0x20,0x4a,0x0b,0x12,0x02,0xc2,0x01 } }, -{ 16, 0xc3f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa5,0x90,0xbb,0x40,0x20,0x40 } }, -{ 16, 0xc400, 0, {0x08,0x90,0x02,0x24,0x40,0x89,0x42,0x62,0x58,0x08,0x10,0x02,0xe5,0x00,0xb9,0x03 } }, -{ 16, 0xc410, 0, {0x22,0xc0,0x0b,0x90,0x02,0xa4,0x14,0x31,0x00,0x2a,0x44,0x0b,0x90,0x02,0xc6,0x04 } }, -{ 16, 0xc420, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xa5,0x00,0xf9,0x01,0x32,0x40 } }, -{ 16, 0xc430, 0, {0x8c,0x90,0x03,0x27,0x00,0xc1,0x94,0x30,0x40,0x0e,0x90,0x03,0x24,0x00,0xf9,0x00 } }, -{ 16, 0xc440, 0, {0x3a,0x40,0x0f,0x90,0x03,0x24,0x00,0xf9,0x00,0x32,0x60,0x07,0x90,0x27,0xe8,0x05 } }, -{ 16, 0xc450, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa4,0x18,0xf9,0x00,0xbe,0x44 } }, -{ 16, 0xc460, 0, {0x0f,0x90,0x03,0xc4,0x00,0xf9,0x00,0xbe,0x61,0x8f,0x90,0x03,0xa4,0x00,0xf1,0x00 } }, -{ 16, 0xc470, 0, {0x1e,0x40,0x0f,0x10,0x03,0x24,0x08,0xf9,0x00,0x7e,0x40,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0xc480, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x81,0xf8,0x00,0x32,0x04 } }, -{ 16, 0xc490, 0, {0x0c,0x00,0xd3,0x21,0x00,0xd8,0x04,0x3a,0x14,0x9c,0x80,0x03,0x21,0x01,0xc8,0x00 } }, -{ 16, 0xc4a0, 0, {0x36,0x00,0x0c,0x80,0x13,0x20,0x10,0xc8,0x00,0x32,0x00,0x2c,0x80,0x03,0xca,0x04 } }, -{ 16, 0xc4b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x04,0x3a,0x00,0xbe,0x84,0x23,0x85 } }, -{ 16, 0xc4c0, 0, {0x08,0xec,0x83,0x68,0x04,0x8a,0x00,0x2f,0x90,0x4d,0xa0,0x02,0x28,0x01,0xda,0x00 } }, -{ 16, 0xc4d0, 0, {0x23,0xb0,0x0a,0xa0,0x02,0x2a,0x08,0xda,0x01,0x22,0x80,0x0f,0xa0,0x02,0xca,0x00 } }, -{ 16, 0xc4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xbb,0xf0,0x20,0xc0 } }, -{ 16, 0xc4f0, 0, {0x08,0x3c,0x0a,0x0c,0x00,0x93,0x01,0x28,0xc8,0x89,0x30,0x06,0x4c,0x00,0x83,0x02 } }, -{ 16, 0xc500, 0, {0x2c,0xf6,0x08,0x30,0x02,0x04,0x00,0xa3,0x00,0x20,0xc0,0x0a,0x30,0x02,0xca,0x00 } }, -{ 16, 0xc510, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1d,0x11,0xb3,0x00,0xa0,0xc0 } }, -{ 16, 0xc520, 0, {0x08,0x50,0x02,0x5c,0x10,0x87,0x01,0x6d,0x81,0x49,0x32,0x52,0x1e,0xc3,0x87,0x00 } }, -{ 16, 0xc530, 0, {0x28,0xe0,0x0a,0x32,0x26,0x1f,0x00,0x37,0x00,0x23,0xe0,0x0b,0x72,0x02,0xc8,0x00 } }, -{ 16, 0xc540, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x12,0x00,0xb7,0x82,0x31,0x20 } }, -{ 16, 0xc550, 0, {0x08,0x08,0x37,0x0f,0x08,0xd7,0xe0,0x39,0x60,0x19,0x7a,0x0b,0x5e,0x0c,0x83,0xb2 } }, -{ 16, 0xc560, 0, {0x7d,0xe0,0x0c,0x7a,0x0b,0x3e,0x02,0xaf,0xa0,0xb1,0xe0,0x0e,0x7a,0x03,0xca,0x02 } }, -{ 16, 0xc570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xa0,0x10,0xfb,0x00,0x3e,0xc0 } }, -{ 16, 0xc580, 0, {0x6f,0xb0,0x43,0xec,0x11,0xfb,0x00,0x3e,0x40,0x0f,0xb5,0x03,0xec,0x20,0xfb,0x50 } }, -{ 16, 0xc590, 0, {0x36,0x00,0x0f,0xb5,0x43,0xe5,0xa1,0xdb,0x78,0x3e,0xc0,0x0f,0xb4,0x03,0xc2,0x06 } }, -{ 16, 0xc5a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xff,0xa0,0x3f,0xa0 } }, -{ 16, 0xc5b0, 0, {0x0d,0xc9,0x13,0x3e,0x00,0xcf,0xd0,0x3d,0xe8,0x02,0xff,0x13,0x3e,0x00,0xcf,0x82 } }, -{ 16, 0xc5c0, 0, {0x3f,0x60,0x0c,0xfc,0x23,0x3e,0x10,0xef,0x80,0x33,0xf2,0x0c,0xfc,0x83,0x10,0x00 } }, -{ 16, 0xc5d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x40,0xb5,0x01,0x2d,0xd0 } }, -{ 16, 0xc5e0, 0, {0x08,0x58,0x02,0x1c,0x40,0x57,0x10,0x2d,0x5a,0x28,0x31,0x02,0xbc,0x01,0x97,0x10 } }, -{ 16, 0xc5f0, 0, {0x2d,0x00,0x0a,0x70,0x02,0x84,0x04,0xcf,0x00,0x29,0xc0,0x0a,0xf0,0x02,0x2a,0x04 } }, -{ 16, 0xc600, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0xb7,0x2a,0x2d,0x82 } }, -{ 16, 0xc610, 0, {0x08,0x42,0x22,0x3c,0x00,0x87,0x11,0x0d,0xcc,0x88,0x32,0x02,0x1d,0x00,0x97,0x00 } }, -{ 16, 0xc620, 0, {0x2c,0xc4,0x08,0x30,0x02,0x14,0x00,0xa7,0x00,0x23,0xc0,0x09,0x70,0x82,0x00,0x00 } }, -{ 16, 0xc630, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x14,0xc0,0x20,0xb0,0x20,0x2c,0x50 } }, -{ 16, 0xc640, 0, {0x08,0x10,0x02,0x2d,0xc0,0x93,0xe2,0x2c,0x21,0x08,0x30,0x02,0x0e,0x08,0x93,0x00 } }, -{ 16, 0xc650, 0, {0x2c,0x40,0x0a,0x30,0x02,0x8c,0x00,0x93,0x00,0x2a,0xc0,0x0b,0x30,0x02,0x18,0x04 } }, -{ 16, 0xc660, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xf8,0xc0,0x3e,0x80 } }, -{ 16, 0xc670, 0, {0x2c,0xa0,0x0b,0x3f,0x00,0xc7,0x60,0x3e,0xd0,0x0c,0xf0,0x0b,0x3c,0x00,0xcf,0x00 } }, -{ 16, 0xc680, 0, {0x3e,0x80,0x0c,0xf0,0x0b,0x2c,0x00,0xef,0x00,0x33,0xc1,0x0d,0xf0,0x0b,0x2a,0x04 } }, -{ 16, 0xc690, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x40,0xf3,0x40,0x3e,0x50 } }, -{ 16, 0xc6a0, 0, {0x8e,0xb4,0x03,0xec,0x10,0xfb,0x00,0x3e,0x09,0x0f,0xb0,0x13,0xec,0x42,0xeb,0x00 } }, -{ 16, 0xc6b0, 0, {0x3c,0x00,0x8f,0xb0,0x13,0xc4,0x11,0xe3,0x00,0x3e,0xc0,0x0e,0xb0,0x03,0xe0,0x00 } }, -{ 16, 0xc6c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xfc,0x80,0x31,0x22 } }, -{ 16, 0xc6d0, 0, {0x0c,0xa8,0x03,0x3c,0x00,0xcf,0x00,0x33,0xa0,0x0e,0xf0,0x03,0xdc,0x00,0xcf,0x00 } }, -{ 16, 0xc6e0, 0, {0x1f,0xf0,0x0c,0xf0,0x03,0xf4,0x00,0xcf,0x02,0x33,0xc0,0x0c,0xf0,0x02,0x00,0x54 } }, -{ 16, 0xc6f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6f,0x00,0xbb,0xc0,0x22,0x70 } }, -{ 16, 0xc700, 0, {0x0a,0xb9,0x42,0x2c,0x10,0x8b,0x00,0x76,0x11,0x83,0xb0,0x02,0xec,0x10,0xab,0x00 } }, -{ 16, 0xc710, 0, {0x2e,0xb0,0x0a,0xb0,0x03,0xec,0x04,0x8b,0x00,0xa2,0xc0,0x28,0xb0,0x02,0x20,0x40 } }, -{ 16, 0xc720, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x65,0x40,0xb8,0x20,0x22,0x44 } }, -{ 16, 0xc730, 0, {0x58,0x34,0x0a,0x2c,0x00,0x8b,0x00,0x22,0x84,0x4b,0xb0,0x02,0xec,0x00,0x8b,0x00 } }, -{ 16, 0xc740, 0, {0x6e,0xc0,0x08,0xb0,0x42,0xe6,0x04,0x8b,0x00,0x02,0xc0,0x08,0x30,0x02,0xa0,0x01 } }, -{ 16, 0xc750, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0xb1,0x00,0x20,0xc0 } }, -{ 16, 0xc760, 0, {0x0a,0x30,0x0a,0x0c,0x00,0x8b,0x03,0x24,0x80,0x0b,0x30,0x02,0xcc,0x00,0xa3,0x00 } }, -{ 16, 0xc770, 0, {0x6c,0x00,0x0a,0x30,0x02,0x8d,0x00,0x83,0x00,0x20,0xc0,0x18,0x30,0x02,0x82,0x00 } }, -{ 16, 0xc780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x64,0x00,0xf8,0x00,0x30,0x00 } }, -{ 16, 0xc790, 0, {0x4c,0xa0,0x0b,0x2c,0x02,0xcf,0x00,0x22,0x40,0x0e,0xf5,0x03,0xfc,0x00,0xcf,0x01 } }, -{ 16, 0xc7a0, 0, {0x3e,0x00,0x0c,0xf0,0x12,0xdd,0x02,0xcf,0x02,0x33,0xc0,0x4c,0xf0,0x0b,0x80,0x03 } }, -{ 16, 0xc7b0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0x19,0xf0,0x00,0xfc,0x00,0x3f,0x40 } }, -{ 16, 0xc7c0, 0, {0x0f,0xb1,0x03,0xdc,0x00,0xbf,0x01,0x3f,0x00,0x0f,0xf2,0x23,0xfc,0x10,0xff,0x00 } }, -{ 16, 0xc7d0, 0, {0x3f,0x00,0x0f,0xf0,0x01,0xf4,0x84,0xff,0x00,0x3d,0xc0,0x4f,0xf0,0x13,0x68,0x06 } }, -{ 16, 0xc7e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x40,0xdf,0x80,0x33,0xc8 } }, -{ 16, 0xc7f0, 0, {0x0c,0xf8,0x03,0x3c,0x0a,0x9f,0xc0,0x3f,0xf0,0x08,0xb8,0x02,0x3e,0x00,0xff,0x80 } }, -{ 16, 0xc800, 0, {0x3f,0xd8,0x0c,0xf9,0x61,0x2e,0x40,0x6f,0x90,0x3f,0xe4,0x8f,0xf1,0x83,0x30,0x00 } }, -{ 16, 0xc810, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xec,0x04,0x8b,0x80,0x23,0xf0 } }, -{ 16, 0xc820, 0, {0x08,0xb8,0x02,0x3d,0x40,0xab,0x00,0x0e,0x08,0x48,0x22,0x82,0x6c,0x20,0xbb,0x00 } }, -{ 16, 0xc830, 0, {0x2f,0xd0,0x48,0xb0,0x02,0x2c,0x00,0xbb,0x00,0x2e,0xc1,0x0b,0xb0,0x02,0x30,0x04 } }, -{ 16, 0xc840, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x02,0x83,0x01,0xa0,0xc5 } }, -{ 16, 0xc850, 0, {0x08,0xb0,0x4a,0x4c,0xa0,0x80,0x24,0x28,0xc8,0x09,0x32,0x02,0x4c,0x00,0xb3,0x08 } }, -{ 16, 0xc860, 0, {0x2e,0xd1,0x29,0xb2,0x3a,0x0c,0x84,0xa3,0x21,0x2c,0xc8,0x4b,0xb2,0x0a,0x32,0x01 } }, -{ 16, 0xc870, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x08,0x8b,0x00,0x22,0xc0 } }, -{ 16, 0xc880, 0, {0x08,0xb0,0x02,0x4c,0x00,0x88,0x21,0x24,0x21,0x09,0xb0,0x46,0x6c,0x00,0xbb,0x06 } }, -{ 16, 0xc890, 0, {0x2e,0xc0,0x09,0xb0,0x02,0x2c,0x10,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0x30,0x04 } }, -{ 16, 0xc8a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xcb,0x00,0x32,0xc0 } }, -{ 16, 0xc8b0, 0, {0x0c,0xb9,0x02,0x6c,0x00,0xcb,0xc8,0x3a,0xc0,0x2d,0x90,0x0b,0x2c,0x08,0xfb,0x00 } }, -{ 16, 0xc8c0, 0, {0x3e,0xc0,0x0d,0x30,0x42,0x2c,0x00,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x13,0x00,0x04 } }, -{ 16, 0xc8d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xbc,0x00,0xef,0x00,0x3d,0xc0 } }, -{ 16, 0xc8e0, 0, {0x0f,0xf0,0x03,0xbc,0x06,0xef,0x82,0x3f,0x40,0x4e,0xc9,0x83,0xbc,0x00,0xff,0x00 } }, -{ 16, 0xc8f0, 0, {0x7f,0xc0,0x1c,0xf0,0x13,0x7c,0x00,0xff,0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xf8,0x00 } }, -{ 16, 0xc900, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x02,0x3e,0xc0 } }, -{ 16, 0xc910, 0, {0x0e,0xb0,0x03,0xac,0x20,0xd8,0x40,0x3e,0xc0,0x8c,0x90,0x0b,0x2c,0x00,0xfb,0x00 } }, -{ 16, 0xc920, 0, {0x3e,0xc9,0x0d,0xb0,0x33,0xec,0x08,0xfb,0x02,0x3e,0xc0,0x0f,0xb0,0x0b,0x54,0x04 } }, -{ 16, 0xc930, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2c,0x00,0xb3,0x00,0x2f,0xc0 } }, -{ 16, 0xc940, 0, {0x0b,0x30,0x12,0xfc,0x00,0x88,0xa0,0x2e,0x40,0x28,0x94,0x02,0x2c,0x10,0xbb,0x04 } }, -{ 16, 0xc950, 0, {0x2d,0xc0,0x28,0xb0,0x02,0xec,0x00,0xbb,0x00,0x2e,0xc0,0x0b,0x72,0x06,0x32,0x00 } }, -{ 16, 0xc960, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x6c,0x00,0xb3,0x00,0x2c,0xe0 } }, -{ 16, 0xc970, 0, {0x0a,0x10,0x02,0xcd,0x00,0x93,0x00,0x2c,0xc0,0x08,0xb0,0x02,0x4c,0x00,0xb3,0x00 } }, -{ 16, 0xc980, 0, {0x28,0xc0,0x08,0x30,0x02,0xcc,0x00,0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x02,0x3a,0x00 } }, -{ 16, 0xc990, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x1e,0x40,0xb7,0x80,0x2d,0xe2 } }, -{ 16, 0xc9a0, 0, {0x0b,0x58,0x02,0xde,0x02,0x97,0x81,0x2f,0xa0,0x08,0x68,0x02,0x5e,0x00,0xb7,0x81 } }, -{ 16, 0xc9b0, 0, {0x2f,0xe0,0x08,0x79,0x02,0xde,0x00,0xb7,0x81,0x2d,0xe0,0x0b,0x78,0x02,0x3c,0x00 } }, -{ 16, 0xc9c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf3,0x00,0x3c,0xc0 } }, -{ 16, 0xc9d0, 0, {0x0e,0x32,0x03,0xcc,0x80,0xd3,0x00,0x3c,0xc4,0x0c,0x39,0x03,0x4c,0x08,0xf3,0x1a } }, -{ 16, 0xc9e0, 0, {0x3c,0xc6,0x0d,0x30,0x03,0xce,0x20,0xf3,0x08,0x3c,0xc0,0x0f,0x30,0x03,0x52,0x02 } }, -{ 16, 0xc9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1d,0xac,0x00,0xfb,0x00,0x2e,0xc0 } }, -{ 16, 0xca00, 0, {0x0b,0xb0,0x03,0xcc,0x20,0xeb,0x00,0x3c,0x80,0x0f,0xb0,0x41,0xac,0x00,0xfb,0x00 } }, -{ 16, 0xca10, 0, {0x3c,0xc2,0x0f,0xb0,0x03,0xec,0x40,0xfb,0x00,0x3e,0xc0,0x0f,0x30,0x03,0xd0,0x06 } }, -{ 16, 0xca20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xee,0x02,0xc3,0x80,0x30,0xce } }, -{ 16, 0xca30, 0, {0x0d,0x98,0x03,0xac,0xa0,0xc3,0x80,0xb2,0xc0,0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00 } }, -{ 16, 0xca40, 0, {0x3e,0xd2,0x4f,0xb0,0x09,0x2e,0x08,0x4b,0x01,0x3e,0xc0,0x24,0xb0,0x03,0xea,0x00 } }, -{ 16, 0xca50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x9c,0x00,0x87,0x01,0x21,0xc0 } }, -{ 16, 0xca60, 0, {0x48,0x50,0x12,0x4c,0x00,0x87,0x00,0x35,0xc0,0x4b,0x60,0x02,0xdc,0x04,0xb7,0x01 } }, -{ 16, 0xca70, 0, {0x2d,0xc0,0x0b,0x70,0x02,0x1c,0x00,0x87,0x00,0x2d,0xc1,0x0c,0x72,0x02,0xf2,0x04 } }, -{ 16, 0xca80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0x87,0x80,0x23,0xe0 } }, -{ 16, 0xca90, 0, {0x08,0xf8,0x02,0xde,0x80,0x8f,0x81,0x21,0xe0,0x4b,0x78,0x12,0xde,0x04,0x37,0x80 } }, -{ 16, 0xcaa0, 0, {0x2d,0xe8,0x0b,0xf8,0x02,0x3e,0x18,0x87,0x80,0x2f,0xe0,0x09,0x79,0x02,0xe0,0x00 } }, -{ 16, 0xcab0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x00,0x83,0x00,0xa0,0xc0 } }, -{ 16, 0xcac0, 0, {0x28,0x30,0x42,0x4c,0x00,0x83,0x00,0x24,0xc0,0x0b,0x38,0x06,0xcc,0x04,0xb3,0x00 } }, -{ 16, 0xcad0, 0, {0x2c,0xc0,0x0b,0x30,0x02,0x0c,0x02,0x83,0x00,0x2c,0xc0,0x08,0x30,0x02,0xd2,0x04 } }, -{ 16, 0xcae0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xca,0x00,0x31,0x80 } }, -{ 16, 0xcaf0, 0, {0x08,0xe0,0x02,0x98,0x02,0xce,0x00,0x33,0x84,0x0b,0xea,0x03,0xe8,0x00,0xba,0x00 } }, -{ 16, 0xcb00, 0, {0x3f,0x81,0x0f,0xa0,0x03,0x28,0x00,0xca,0x00,0x3e,0x80,0x0d,0xe0,0x03,0xfa,0x04 } }, -{ 16, 0xcb10, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00 } }, -{ 16, 0xcb20, 0, {0x0e,0x84,0x23,0xa0,0x00,0xf8,0x00,0x3a,0x10,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x00 } }, -{ 16, 0xcb30, 0, {0x3e,0x10,0x0f,0x80,0x13,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0d,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xcb40, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x01,0xf9,0x00,0x3e,0x40 } }, -{ 16, 0xcb50, 0, {0x0c,0x9a,0x13,0xe4,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x98,0x23,0xe4,0x80,0xf9,0x00 } }, -{ 16, 0xcb60, 0, {0x3e,0x40,0x2c,0x98,0x03,0x64,0x00,0xf9,0x00,0x3e,0x40,0x0c,0x90,0x03,0xc2,0x04 } }, -{ 16, 0xcb70, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x04,0xb9,0x00,0x2e,0x40 } }, -{ 16, 0xcb80, 0, {0x68,0x9c,0x22,0xe4,0x02,0x89,0x01,0x7c,0x50,0x8d,0x98,0x22,0xe4,0x80,0xb9,0x20 } }, -{ 16, 0xcb90, 0, {0x2e,0x50,0x48,0x10,0x0b,0x25,0x00,0xb9,0x44,0x2c,0x40,0x28,0x90,0x00,0xe0,0x00 } }, -{ 16, 0xcba0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x2e,0x50 } }, -{ 16, 0xcbb0, 0, {0x08,0x90,0x02,0xe4,0x04,0x89,0x00,0x2e,0x50,0x0a,0x92,0x02,0xe4,0x00,0xb9,0x00 } }, -{ 16, 0xcbc0, 0, {0x2c,0x40,0x08,0x91,0x02,0x24,0x00,0xb9,0x00,0x2e,0x40,0x08,0x90,0x02,0xc6,0x00 } }, -{ 16, 0xcbd0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x05,0x00,0xb1,0x01,0x2c,0x40 } }, -{ 16, 0xcbe0, 0, {0x48,0x30,0x02,0xe4,0x00,0x81,0x00,0x2a,0x40,0x4b,0x10,0x02,0xc4,0x00,0xb1,0x00 } }, -{ 16, 0xcbf0, 0, {0x0c,0xc0,0x08,0x90,0x02,0x0c,0x00,0xb3,0x00,0x2e,0x40,0x48,0x12,0x02,0xc2,0x01 } }, -{ 16, 0xcc00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xb8,0x01,0x3e,0x00 } }, -{ 16, 0xcc10, 0, {0x1c,0x80,0x07,0xe1,0x50,0xc8,0x50,0x2e,0x14,0x1e,0x85,0x03,0xe1,0x41,0xf8,0x50 } }, -{ 16, 0xcc20, 0, {0x3e,0x14,0x0c,0x85,0x13,0x21,0x48,0xf8,0x50,0x3e,0x14,0x0c,0x85,0x43,0xee,0x03 } }, -{ 16, 0xcc30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x19,0xc4,0x00,0xf9,0x00,0x3e,0x51 } }, -{ 16, 0xcc40, 0, {0x0f,0x50,0x03,0xe5,0x00,0xfd,0x00,0x3f,0x40,0x1d,0xd0,0x03,0xf4,0x10,0xf9,0x00 } }, -{ 16, 0xcc50, 0, {0x3e,0x50,0x0f,0x50,0x00,0x94,0x00,0xf9,0x00,0x3d,0x40,0x0f,0x91,0x03,0xe6,0x06 } }, -{ 16, 0xcc60, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xe4,0x50,0xcd,0x00,0x31,0x60 } }, -{ 16, 0xcc70, 0, {0x04,0xd0,0x03,0x36,0x80,0xc1,0x42,0x2e,0x50,0x1f,0x94,0x03,0xe5,0x00,0xe9,0x02 } }, -{ 16, 0xcc80, 0, {0x2e,0x72,0x0a,0x90,0x22,0x05,0x08,0xe9,0x40,0x3e,0x50,0x40,0x9c,0x03,0x26,0x00 } }, -{ 16, 0xcc90, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xc2,0x82,0x88,0x00,0x22,0x15 } }, -{ 16, 0xcca0, 0, {0x08,0x80,0x02,0x23,0x58,0x88,0xa0,0x2e,0x28,0x0b,0xaa,0x42,0xe2,0x82,0x88,0x80 } }, -{ 16, 0xccb0, 0, {0x2e,0x38,0x28,0x88,0x02,0x22,0x80,0xb8,0xa0,0x3a,0x28,0x08,0xcd,0x02,0x0e,0x04 } }, -{ 16, 0xccc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x81,0x00,0xa6,0x40 } }, -{ 16, 0xccd0, 0, {0x28,0x10,0x0a,0x24,0x26,0x95,0x00,0x0d,0x40,0x0b,0x50,0x02,0x74,0x00,0x85,0x08 } }, -{ 16, 0xcce0, 0, {0x2f,0x40,0x79,0xd2,0xaa,0x14,0x00,0xa5,0x01,0x2f,0x40,0x38,0x50,0x02,0x12,0x01 } }, -{ 16, 0xccf0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x04,0x89,0x00,0x26,0x40 } }, -{ 16, 0xcd00, 0, {0x08,0x91,0x02,0x24,0x10,0x9d,0x08,0x2f,0x40,0x0b,0xd0,0x02,0xf4,0x00,0x8d,0x02 } }, -{ 16, 0xcd10, 0, {0x2f,0x40,0x09,0xd0,0x00,0x34,0x00,0xbd,0x00,0x0b,0x40,0x18,0x70,0x02,0x06,0x04 } }, -{ 16, 0xcd20, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xc4,0x00,0xc9,0x05,0x36,0x41 } }, -{ 16, 0xcd30, 0, {0x4c,0x90,0x63,0x24,0x00,0xd9,0x00,0x3e,0x40,0x0b,0x90,0x03,0x44,0x08,0xc9,0x00 } }, -{ 16, 0xcd40, 0, {0x3e,0x40,0x15,0x10,0x03,0x24,0x00,0xe9,0x00,0x3c,0x40,0x0c,0x90,0x03,0x28,0x04 } }, -{ 16, 0xcd50, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0xa4,0x04,0xf9,0x00,0x3a,0x40 } }, -{ 16, 0xcd60, 0, {0x4f,0x98,0x03,0xe4,0x00,0xe9,0x99,0x3e,0x40,0x4f,0x90,0x03,0xe4,0x20,0xf9,0x0a } }, -{ 16, 0xcd70, 0, {0x3e,0x40,0x0e,0x90,0x43,0x64,0x24,0xf9,0x08,0x3a,0x42,0x0f,0x90,0x8b,0xda,0x00 } }, -{ 16, 0xcd80, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x12,0x00 } }, -{ 16, 0xcd90, 0, {0x0c,0x80,0x43,0xe0,0x00,0xc8,0x40,0x32,0x00,0x0f,0x84,0x53,0xe0,0x10,0xf8,0x00 } }, -{ 16, 0xcda0, 0, {0x3e,0x00,0x0d,0x80,0x23,0x20,0x00,0xd8,0x00,0x3e,0x00,0x0f,0x80,0x03,0x0a,0x04 } }, -{ 16, 0xcdb0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x38,0x02,0x82,0x00,0xa1,0x88 } }, -{ 16, 0xcdc0, 0, {0x08,0x60,0x22,0xc8,0x00,0x8a,0x40,0x36,0xa1,0x0b,0xa0,0x02,0xe9,0x10,0xba,0x44 } }, -{ 16, 0xcdd0, 0, {0x2c,0x80,0x0c,0xa4,0x12,0x29,0x02,0x8a,0x44,0x2e,0x98,0x0b,0xa4,0x02,0x0a,0x00 } }, -{ 16, 0xcde0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x10,0x83,0x00,0x20,0xe0 } }, -{ 16, 0xcdf0, 0, {0x18,0x30,0x92,0xc4,0x08,0x93,0x40,0x20,0xe0,0x0b,0x30,0x02,0xcd,0x00,0xb3,0x40 } }, -{ 16, 0xce00, 0, {0x2c,0xc0,0x0b,0x3a,0x42,0xcd,0x00,0x83,0x40,0x2c,0xd0,0x0b,0x38,0x02,0x4a,0x00 } }, -{ 16, 0xce10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x41,0x1c,0x00,0x87,0x00,0x21,0xc0 } }, -{ 16, 0xce20, 0, {0x28,0x70,0x02,0xd1,0x00,0x9d,0x80,0x25,0xc2,0x4b,0x60,0x02,0xdc,0x08,0xb7,0x02 } }, -{ 16, 0xce30, 0, {0x2c,0xc0,0x0a,0x74,0x02,0xfe,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x34,0x02,0x68,0x00 } }, -{ 16, 0xce40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x84,0x31,0xe0 } }, -{ 16, 0xce50, 0, {0x0c,0x68,0x03,0xd6,0x00,0x97,0x80,0x31,0xa0,0x0f,0x58,0x13,0xde,0x08,0xf7,0x82 } }, -{ 16, 0xce60, 0, {0x3d,0xa0,0x0f,0xf8,0x0b,0xde,0x00,0xc7,0x80,0x3d,0xe0,0x0f,0x78,0x8b,0x6a,0x02 } }, -{ 16, 0xce70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xad,0x80,0xf3,0x00,0x3e,0xc1 } }, -{ 16, 0xce80, 0, {0x0f,0xa0,0x23,0xc0,0x02,0xe9,0x00,0x3e,0x81,0x0f,0x80,0x03,0xec,0x00,0xfb,0x00 } }, -{ 16, 0xce90, 0, {0x3e,0xc0,0x0d,0xb0,0x13,0x2c,0x00,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x82,0x02 } }, -{ 16, 0xcea0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x32,0xc7,0x80,0x33,0x60 } }, -{ 16, 0xceb0, 0, {0x0f,0x78,0x03,0x3e,0xc8,0x4e,0x80,0x23,0x64,0x0c,0xf8,0x03,0x3a,0x00,0xce,0x80 } }, -{ 16, 0xcec0, 0, {0x13,0xec,0x06,0xd8,0x03,0x3a,0x00,0xde,0x80,0x33,0xa4,0x0c,0xc8,0x03,0xd0,0x00 } }, -{ 16, 0xced0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0x9c,0x00,0x87,0x10,0x01,0xc0 } }, -{ 16, 0xcee0, 0, {0x0b,0x70,0x02,0x18,0x50,0x84,0x00,0x2b,0x44,0x08,0x60,0x12,0x98,0x00,0x86,0x13 } }, -{ 16, 0xcef0, 0, {0x21,0xc4,0x88,0x50,0x02,0x18,0x80,0x86,0x00,0x21,0x80,0x08,0x61,0x02,0xea,0x04 } }, -{ 16, 0xcf00, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x00,0x21,0x40 } }, -{ 16, 0xcf10, 0, {0x0b,0xf1,0x02,0x5c,0x80,0x06,0x00,0x21,0x00,0x88,0xd0,0x02,0x5c,0x00,0x87,0x00 } }, -{ 16, 0xcf20, 0, {0x20,0x89,0x8a,0xf1,0x02,0x1c,0x08,0x87,0x10,0x21,0x81,0x88,0x48,0x02,0xc6,0x00 } }, -{ 16, 0xcf30, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x10,0x83,0x04,0xa0,0xc1 } }, -{ 16, 0xcf40, 0, {0x0b,0x30,0x0a,0x48,0x0c,0x88,0x06,0x60,0x38,0x08,0x04,0x42,0xec,0x01,0x8b,0x04 } }, -{ 16, 0xcf50, 0, {0x22,0xc1,0x08,0x30,0x0a,0x2c,0x00,0x8b,0x00,0x22,0x80,0x00,0x20,0x02,0xd8,0x04 } }, -{ 16, 0xcf60, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xc3,0x00,0x22,0x80 } }, -{ 16, 0xcf70, 0, {0x8f,0x90,0x03,0x64,0x0a,0xcb,0x02,0xb2,0xf2,0x20,0x35,0x12,0x64,0x0a,0xc9,0x00 } }, -{ 16, 0xcf80, 0, {0xb2,0x40,0x0e,0xa0,0x03,0x24,0x0a,0xc9,0x00,0xa2,0x40,0x2c,0xa0,0x03,0xee,0x04 } }, -{ 16, 0xcf90, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xec,0x00,0xfb,0x00,0x3c,0x80 } }, -{ 16, 0xcfa0, 0, {0x0f,0x90,0x03,0xa5,0x00,0xdb,0x40,0x3e,0xd0,0x4d,0xb4,0x13,0xa4,0x08,0xfb,0x01 } }, -{ 16, 0xcfb0, 0, {0x3e,0xc0,0x1c,0xa0,0x03,0x6c,0x00,0xfb,0x04,0x3e,0x50,0x4f,0xa4,0x03,0xe0,0x00 } }, -{ 16, 0xcfc0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0x33,0xc0 } }, -{ 16, 0xcfd0, 0, {0x0c,0xe8,0x43,0x26,0x00,0xdf,0x80,0xb3,0xe0,0x0f,0xf8,0x03,0x7c,0x00,0xcd,0x00 } }, -{ 16, 0xcfe0, 0, {0x33,0x04,0x0c,0xe0,0x23,0x34,0x40,0xcd,0x00,0x23,0x40,0x0c,0xe0,0x03,0xe0,0x04 } }, -{ 16, 0xcff0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x6c,0x10,0xbb,0x00,0xa2,0xd2 } }, -{ 16, 0xd000, 0, {0x08,0x28,0x02,0x04,0x60,0x8b,0x19,0x22,0xc6,0x0e,0xb1,0x8a,0x2e,0x40,0x8b,0x90 } }, -{ 16, 0xd010, 0, {0x22,0xc1,0x08,0xa4,0x82,0x2c,0x00,0x8b,0x90,0x22,0x64,0x48,0xa4,0x02,0xe0,0x00 } }, -{ 16, 0xd020, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xbb,0x00,0x22,0x00 } }, -{ 16, 0xd030, 0, {0x08,0x91,0x2e,0x24,0x00,0x9b,0x00,0x22,0xc0,0x8b,0xb0,0x12,0x20,0x04,0x88,0x00 } }, -{ 16, 0xd040, 0, {0x22,0x40,0x08,0x10,0x22,0x20,0x00,0x88,0x01,0x2a,0xd0,0x08,0x80,0x42,0xe0,0x00 } }, -{ 16, 0xd050, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0c,0x00,0xb3,0x04,0x20,0x80 } }, -{ 16, 0xd060, 0, {0x08,0x10,0x06,0x04,0x10,0x83,0x00,0x20,0xc0,0x8b,0xb0,0x12,0x00,0x00,0x82,0x00 } }, -{ 16, 0xd070, 0, {0x20,0xc0,0x28,0x10,0x42,0x09,0x06,0x82,0x00,0x28,0xc0,0x08,0x20,0x02,0xc2,0x01 } }, -{ 16, 0xd080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xbb,0x00,0x32,0x40 } }, -{ 16, 0xd090, 0, {0x2c,0xb0,0x03,0x24,0x00,0xd3,0x00,0x32,0xc0,0x5f,0xb5,0x03,0x0c,0x02,0xc1,0x00 } }, -{ 16, 0xd0a0, 0, {0xb2,0x00,0x0c,0xb0,0x0b,0x05,0x00,0xc1,0x00,0xb8,0xc0,0x2c,0x80,0x13,0xe0,0x03 } }, -{ 16, 0xd0b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xdc,0x00,0xff,0x00,0x1f,0xc0 } }, -{ 16, 0xd0c0, 0, {0x87,0xf0,0x01,0xf4,0x00,0xff,0x00,0x3f,0xc0,0x0e,0x70,0x43,0xfc,0x10,0x7f,0x00 } }, -{ 16, 0xd0d0, 0, {0x3f,0xc0,0x0f,0x70,0x03,0xfc,0x00,0xff,0x00,0x37,0xc0,0x0f,0xe0,0x03,0xe8,0x06 } }, -{ 16, 0xd0e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf1,0x84,0xfe,0x61,0x31,0xd8 } }, -{ 16, 0xd0f0, 0, {0x0c,0xb2,0xc3,0xfc,0xe0,0xcc,0x80,0x7b,0xc0,0x0e,0xf1,0x03,0x7c,0xe0,0xcc,0x83 } }, -{ 16, 0xd100, 0, {0x3f,0x20,0x0f,0xf0,0xcb,0x32,0x44,0xdc,0x84,0x3f,0x25,0x4c,0xf2,0x43,0x30,0x00 } }, -{ 16, 0xd110, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0xe4,0x48,0xb0,0x10,0x22,0xdc } }, -{ 16, 0xd120, 0, {0x08,0xb6,0x02,0xfd,0x92,0x88,0x85,0x23,0xf4,0x40,0xf1,0x02,0xed,0x00,0x88,0x2d } }, -{ 16, 0xd130, 0, {0x0e,0x60,0x0b,0xbc,0x12,0x2c,0x10,0xa8,0x82,0x2e,0x00,0x0a,0xfc,0x22,0xa0,0x04 } }, -{ 16, 0xd140, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x80,0xb3,0x22,0x28,0xc0 } }, -{ 16, 0xd150, 0, {0x08,0x30,0x82,0xcc,0x01,0x88,0x00,0x2c,0xc0,0x4a,0x32,0x02,0xcc,0x00,0x01,0x01 } }, -{ 16, 0xd160, 0, {0x28,0x00,0x4b,0xb0,0x02,0xa0,0x00,0x80,0x00,0x2c,0x09,0x08,0x34,0x02,0x62,0x01 } }, -{ 16, 0xd170, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xac,0x04,0xb2,0x10,0x2a,0xc1 } }, -{ 16, 0xd180, 0, {0x08,0xb0,0x02,0xec,0x10,0x89,0x80,0x22,0xc0,0x08,0xb0,0x02,0xec,0x08,0x88,0x00 } }, -{ 16, 0xd190, 0, {0x2e,0x40,0x83,0xb0,0x02,0xa0,0x40,0xb9,0x80,0x2c,0x21,0x0a,0xb0,0x02,0xf0,0x04 } }, -{ 16, 0xd1a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xfa,0x00,0xba,0xc0 } }, -{ 16, 0xd1b0, 0, {0x2c,0xb0,0x43,0xec,0x00,0xc0,0x80,0x3e,0xc0,0x8e,0xb0,0x03,0x4c,0x0c,0xc8,0x10 } }, -{ 16, 0xd1c0, 0, {0x3e,0x80,0x8f,0xb0,0x03,0x82,0x10,0xd8,0x82,0x3e,0x28,0x0c,0xb0,0x0b,0x50,0x04 } }, -{ 16, 0xd1d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0xb6,0x80,0xfd,0x02,0x37,0xc1 } }, -{ 16, 0xd1e0, 0, {0x0f,0xb0,0x03,0xfc,0x00,0xfd,0x00,0x3e,0xc0,0x0f,0xb0,0x53,0xfc,0x02,0xff,0x01 } }, -{ 16, 0xd1f0, 0, {0x2f,0xa4,0x8b,0xf0,0x83,0x7c,0x00,0xad,0x02,0x2f,0x40,0x03,0x70,0x03,0xb8,0x00 } }, -{ 16, 0xd200, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x04,0x32,0xc0 } }, -{ 16, 0xd210, 0, {0x4c,0xb0,0x23,0x2c,0x00,0xf8,0x40,0x3e,0xc2,0x0c,0xb0,0x03,0x2c,0x00,0xfb,0x41 } }, -{ 16, 0xd220, 0, {0x32,0xc2,0x0f,0xb0,0x43,0x2d,0x00,0xc8,0x50,0x3e,0x40,0x0c,0xb0,0x0b,0x10,0x04 } }, -{ 16, 0xd230, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x05,0x2f,0x90,0xb9,0x50,0x03,0xc0 } }, -{ 16, 0xd240, 0, {0x18,0xf0,0x1a,0x3c,0x00,0xb9,0x32,0x2d,0xe0,0x38,0xf0,0x60,0x3c,0x04,0xf9,0x00 } }, -{ 16, 0xd250, 0, {0x3e,0xf0,0x0b,0x7c,0x80,0x2c,0x00,0xd9,0xc0,0x2e,0x40,0x0d,0xf0,0x02,0x32,0x00 } }, -{ 16, 0xd260, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4b,0x24,0xb2,0x10,0x02,0xc1 } }, -{ 16, 0xd270, 0, {0x28,0x30,0x02,0x6c,0x04,0xb2,0xc1,0x2c,0xc0,0x08,0x30,0x00,0x0c,0x00,0xb2,0x00 } }, -{ 16, 0xd280, 0, {0x28,0x24,0x03,0x3c,0x0a,0x00,0x00,0x82,0xc8,0x2c,0xa0,0x08,0x30,0x02,0x38,0x00 } }, -{ 16, 0xd290, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x16,0x00,0xb4,0x80,0x21,0xe4 } }, -{ 16, 0xd2a0, 0, {0x48,0x7b,0x02,0x5e,0x00,0xb6,0x80,0x6d,0xe2,0x48,0x79,0x22,0x1e,0x40,0xac,0x84 } }, -{ 16, 0xd2b0, 0, {0x2d,0xe0,0x0b,0xfa,0x00,0x52,0x40,0x96,0x80,0x2d,0xe8,0x19,0x38,0x02,0x08,0x00 } }, -{ 16, 0xd2c0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x40,0xf3,0x10,0xb0,0xc4 } }, -{ 16, 0xd2d0, 0, {0x08,0x3a,0x02,0x4c,0x90,0xf3,0x10,0x3c,0xcc,0x08,0x31,0x03,0x0c,0x49,0xb0,0x40 } }, -{ 16, 0xd2e0, 0, {0x30,0x05,0x0f,0x30,0x07,0x21,0x40,0x43,0x01,0x3e,0xc2,0x1c,0x30,0x43,0x12,0x02 } }, -{ 16, 0xd2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x0d,0xbc,0x10,0xfc,0x10,0x3f,0xc5 } }, -{ 16, 0xd300, 0, {0x0f,0xf1,0x01,0xbc,0x04,0xff,0x04,0x3f,0xc4,0x0f,0xb1,0x4b,0xfc,0x64,0xf7,0x00 } }, -{ 16, 0xd310, 0, {0x37,0xc0,0x0f,0x72,0x53,0xac,0x44,0xff,0x01,0x3f,0xc9,0x0f,0xf4,0x03,0xd0,0x06 } }, -{ 16, 0xd320, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x08,0xfa,0x00,0x3e,0xe0 } }, -{ 16, 0xd330, 0, {0x0c,0xb0,0x03,0x2c,0x00,0xcb,0x02,0x3e,0xca,0x0f,0xb2,0x07,0x2e,0x00,0xdb,0x02 } }, -{ 16, 0xd340, 0, {0x32,0x08,0x0f,0x31,0x03,0x2c,0x00,0xcb,0x04,0x3e,0x80,0x0c,0x35,0x03,0x2a,0x00 } }, -{ 16, 0xd350, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x11,0x94,0x00,0xb5,0x00,0x2d,0xc8 } }, -{ 16, 0xd360, 0, {0x08,0x70,0x0a,0x1c,0x22,0x87,0x00,0x2d,0xc9,0x0b,0xf2,0x82,0x9c,0x80,0xa6,0x00 } }, -{ 16, 0xd370, 0, {0x09,0x8b,0x0b,0x70,0x0a,0x1c,0x02,0x85,0x00,0x2d,0x40,0x08,0x70,0x02,0x92,0x04 } }, -{ 16, 0xd380, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0x80,0x2c,0xec } }, -{ 16, 0xd390, 0, {0x08,0x7b,0x02,0x5e,0x40,0x85,0x89,0x2d,0xec,0x8b,0x7b,0x02,0x4e,0x84,0x8f,0x80 } }, -{ 16, 0xd3a0, 0, {0x25,0x64,0x0b,0xfa,0x02,0x12,0x08,0x97,0x80,0x6f,0xe1,0x08,0x7a,0x02,0x30,0x00 } }, -{ 16, 0xd3b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x14,0xcc,0x20,0xb3,0x64,0x2c,0xc0 } }, -{ 16, 0xd3c0, 0, {0x08,0x30,0x06,0x0c,0x10,0x83,0x8a,0x6c,0xc0,0x5b,0x30,0x42,0xcc,0x00,0xab,0x10 } }, -{ 16, 0xd3d0, 0, {0x2c,0xf2,0x0b,0x30,0x02,0x0d,0x00,0x93,0x04,0x2c,0xd5,0x08,0x30,0x0a,0x92,0x04 } }, -{ 16, 0xd3e0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xbb,0x00,0xfe,0xc0,0x3e,0x80 } }, -{ 16, 0xd3f0, 0, {0x2c,0xa0,0x03,0x68,0x00,0xc6,0x40,0x3f,0x80,0x0f,0xa0,0x02,0x68,0x00,0xce,0x44 } }, -{ 16, 0xd400, 0, {0x36,0x90,0x4f,0x60,0x03,0x1b,0x70,0xde,0xd8,0x3f,0xa0,0x0c,0x20,0x03,0x3a,0x04 } }, -{ 16, 0xd410, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0xe0,0x40,0xf8,0x10,0x3e,0x00 } }, -{ 16, 0xd420, 0, {0x0f,0x80,0x03,0xa0,0x10,0xf8,0x42,0x3e,0x10,0x1f,0x80,0x03,0xa0,0x00,0xe8,0x0c } }, -{ 16, 0xd430, 0, {0x3a,0x04,0x1f,0x80,0x03,0xe0,0x00,0xe8,0x45,0x7e,0x02,0x2f,0x80,0x03,0xd2,0x00 } }, -{ 16, 0xd440, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x64,0x00,0xe9,0x80,0x32,0x40 } }, -{ 16, 0xd450, 0, {0x0f,0x90,0x0b,0x04,0x08,0xd9,0x80,0x36,0x40,0x0f,0x10,0x13,0x24,0x08,0xf9,0x00 } }, -{ 16, 0xd460, 0, {0x72,0x70,0x0f,0x91,0x13,0x24,0x10,0xc9,0x10,0x3e,0x69,0x0c,0x90,0x03,0x02,0x04 } }, -{ 16, 0xd470, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x64,0x08,0xb9,0x80,0x22,0x40 } }, -{ 16, 0xd480, 0, {0x0b,0x10,0x02,0x24,0x00,0x89,0xc4,0x22,0x52,0x0b,0x90,0x42,0x24,0x00,0xb9,0x00 } }, -{ 16, 0xd490, 0, {0x22,0xe0,0x0b,0x90,0x12,0x24,0x04,0xd9,0x4a,0x2e,0x60,0x08,0x90,0x03,0x60,0x00 } }, -{ 16, 0xd4a0, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb1,0x18,0x22,0x40 } }, -{ 16, 0xd4b0, 0, {0x0b,0x90,0x02,0x24,0x00,0x8b,0x20,0x26,0x49,0x0b,0x90,0x02,0x64,0x00,0xb9,0x00 } }, -{ 16, 0xd4c0, 0, {0xa2,0x40,0x0b,0x90,0x8a,0x24,0x00,0x8b,0x00,0x2c,0x40,0xa8,0x90,0x02,0x06,0x00 } }, -{ 16, 0xd4d0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x04,0x84,0xb1,0x20,0xa0,0x48 } }, -{ 16, 0xd4e0, 0, {0x0b,0x11,0x06,0x04,0x00,0x83,0x00,0x00,0x40,0x4b,0x11,0x02,0x04,0x49,0xb1,0x10 } }, -{ 16, 0xd4f0, 0, {0x28,0x40,0x0b,0x10,0x02,0x24,0x41,0x91,0x00,0x2c,0x50,0x08,0x10,0x02,0x42,0x01 } }, -{ 16, 0xd500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x69,0x40,0xe8,0x50,0x32,0x14 } }, -{ 16, 0xd510, 0, {0x0f,0x86,0x93,0x21,0xe2,0xc8,0x00,0x36,0x0a,0x0b,0x86,0x8b,0x61,0xa8,0xf8,0x40 } }, -{ 16, 0xd520, 0, {0x22,0x80,0x0f,0x82,0xa3,0x21,0x08,0xc8,0x02,0x3e,0x00,0x0c,0x80,0x43,0x2e,0x03 } }, -{ 16, 0xd530, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x1d,0xf4,0x48,0xfd,0x12,0x3e,0x44 } }, -{ 16, 0xd540, 0, {0x0f,0x12,0x03,0xc4,0x00,0x7d,0x01,0x1e,0x40,0x0b,0x92,0x03,0xe4,0x80,0xf5,0x20 } }, -{ 16, 0xd550, 0, {0x36,0x40,0x0f,0x90,0x03,0xd4,0x90,0x7d,0x00,0x3d,0x40,0x0f,0x94,0x03,0xe6,0x06 } }, -{ 16, 0xd560, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xf6,0xc1,0xdd,0x88,0x32,0x72 } }, -{ 16, 0xd570, 0, {0x0c,0x98,0x03,0x26,0x22,0xdd,0x00,0x3f,0x62,0x2c,0x99,0x83,0x46,0xa0,0xc9,0x40 } }, -{ 16, 0xd580, 0, {0xb2,0x40,0x0f,0xd8,0x03,0x24,0x00,0xfd,0x00,0x33,0x51,0x2c,0xd8,0x83,0x06,0x00 } }, -{ 16, 0xd590, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0xe3,0xc2,0x88,0xc0,0x22,0x30 } }, -{ 16, 0xd5a0, 0, {0x08,0x8c,0x42,0x22,0x11,0x8a,0x01,0x2e,0x00,0x08,0x88,0x52,0x23,0x00,0x80,0xa3 } }, -{ 16, 0xd5b0, 0, {0x2a,0x00,0x4b,0x80,0x42,0x22,0xa0,0xb8,0x00,0x22,0x28,0x08,0x84,0x02,0x8e,0x04 } }, -{ 16, 0xd5c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x81,0x2d,0x20,0x48 } }, -{ 16, 0xd5d0, 0, {0x68,0x14,0x80,0x04,0x20,0x81,0x00,0x2e,0x40,0x0b,0x12,0x12,0x04,0x24,0x81,0x20 } }, -{ 16, 0xd5e0, 0, {0x20,0x40,0x0b,0x94,0x32,0x04,0x90,0xb9,0x00,0x20,0x40,0x48,0x10,0x4a,0x02,0x01 } }, -{ 16, 0xd5f0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xa4,0x00,0x89,0x20,0x22,0x40 } }, -{ 16, 0xd600, 0, {0x08,0x90,0x12,0x24,0x00,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0x24,0x08,0x89,0x40 } }, -{ 16, 0xd610, 0, {0x22,0x50,0x0b,0xb0,0x02,0x24,0x20,0xb9,0x09,0xa2,0x44,0x08,0x90,0x02,0x86,0x04 } }, -{ 16, 0xd620, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xd9,0x08,0xb2,0x40 } }, -{ 16, 0xd630, 0, {0x4c,0x10,0x23,0x04,0x04,0xd9,0xc1,0x3e,0x40,0x8f,0x90,0x0b,0x04,0x08,0xc1,0x40 } }, -{ 16, 0xd640, 0, {0x12,0x40,0x0f,0x90,0x43,0x24,0x04,0xf1,0x41,0x30,0x78,0x0c,0x90,0x03,0x28,0x04 } }, -{ 16, 0xd650, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x86,0x64,0xf9,0x80,0x3e,0x40 } }, -{ 16, 0xd660, 0, {0x0f,0x90,0x0b,0xe4,0x00,0xf9,0x98,0x3e,0x40,0x2f,0x10,0x03,0xa4,0x02,0xf9,0x10 } }, -{ 16, 0xd670, 0, {0x3e,0x40,0x0f,0x90,0x0b,0xe6,0x40,0xf9,0x90,0x3e,0x60,0x0f,0x90,0x03,0xca,0x00 } }, -{ 16, 0xd680, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x41,0x32,0x00 } }, -{ 16, 0xd690, 0, {0x0c,0x80,0x07,0x20,0x10,0xc8,0x10,0x3e,0x0c,0x0e,0x80,0x03,0xe0,0x04,0xc8,0x00 } }, -{ 16, 0xd6a0, 0, {0xba,0x00,0x0f,0x81,0x43,0x20,0x00,0xf8,0x70,0x3e,0x00,0x0f,0x00,0x0b,0x0a,0x04 } }, -{ 16, 0xd6b0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x39,0x02,0x8e,0x20,0xa3,0x80 } }, -{ 16, 0xd6c0, 0, {0x28,0xe0,0x0a,0x38,0x10,0xae,0x04,0x3d,0xa1,0x8e,0xe0,0x02,0xf8,0x00,0x8e,0x00 } }, -{ 16, 0xd6d0, 0, {0x76,0x80,0x0b,0x60,0x03,0x78,0x00,0xbe,0x40,0x2f,0x82,0x0b,0xa0,0x03,0xca,0x00 } }, -{ 16, 0xd6e0, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4d,0x00,0x8b,0x88,0x22,0xc0 } }, -{ 16, 0xd6f0, 0, {0x18,0x30,0x02,0x0c,0x00,0x83,0x44,0x2c,0xd0,0x1b,0x30,0x12,0xcc,0x06,0x83,0x00 } }, -{ 16, 0xd700, 0, {0x20,0xc1,0x0b,0x30,0x82,0x0c,0x01,0xb3,0x00,0x2c,0x40,0x0b,0x30,0x02,0x0a,0x00 } }, -{ 16, 0xd710, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x01,0x1c,0x00,0x85,0x00,0x20,0xcc } }, -{ 16, 0xd720, 0, {0x08,0x70,0x06,0x1c,0x84,0xa7,0x01,0x29,0xc0,0x0b,0x72,0x22,0xdc,0x80,0x87,0x34 } }, -{ 16, 0xd730, 0, {0x61,0x80,0x0b,0x10,0x02,0x5c,0x00,0xb7,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xe8,0x00 } }, -{ 16, 0xd740, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x0e,0x00,0x8c,0x80,0x31,0xe0 } }, -{ 16, 0xd750, 0, {0x0c,0xfe,0x02,0x3f,0x00,0xc5,0x80,0x2d,0xe0,0x0e,0x78,0x03,0xdf,0xa0,0xc7,0xa0 } }, -{ 16, 0xd760, 0, {0x21,0x60,0x0f,0x78,0x03,0x1e,0x80,0xf7,0x80,0x3d,0xe0,0x0f,0x78,0x03,0x2a,0x02 } }, -{ 16, 0xd770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1d,0xac,0x00,0xf9,0x00,0x3e,0xc0 } }, -{ 16, 0xd780, 0, {0x0f,0xb0,0x03,0xec,0x00,0xfa,0x00,0x3e,0xc0,0x06,0xb0,0x03,0xec,0x80,0xfb,0x28 } }, -{ 16, 0xd790, 0, {0x36,0xd8,0x4f,0xa0,0x03,0xec,0x10,0xfa,0x00,0x3e,0x50,0x0f,0x30,0x03,0xc2,0x06 } }, -{ 16, 0xd7a0, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfa,0x00,0xcc,0x80,0xb3,0xe0 } }, -{ 16, 0xd7b0, 0, {0x0f,0xf8,0x03,0x3e,0x00,0xcf,0x90,0x3f,0x60,0x4f,0xf8,0xc3,0x3e,0x00,0xef,0x80 } }, -{ 16, 0xd7c0, 0, {0x33,0xf0,0x0c,0x7a,0x03,0x3e,0x70,0xc5,0x90,0x33,0xf1,0x0c,0x78,0x03,0x00,0x00 } }, -{ 16, 0xd7d0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xb8,0x00,0x87,0x00,0x21,0xc0 } }, -{ 16, 0xd7e0, 0, {0x0b,0x70,0x4a,0x1c,0x00,0x87,0x10,0x2d,0xc0,0x4b,0x71,0x0a,0x3c,0x44,0x8f,0x12 } }, -{ 16, 0xd7f0, 0, {0x21,0x86,0x0d,0x72,0x02,0x1e,0x00,0x87,0x00,0x23,0x40,0x08,0x70,0x0a,0x2a,0x04 } }, -{ 16, 0xd800, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x84,0x00,0x25,0xc0 } }, -{ 16, 0xd810, 0, {0x0b,0x71,0x0a,0x0c,0x00,0xa7,0x12,0x2d,0x84,0x0b,0x70,0x0a,0x1c,0x00,0xb7,0x08 } }, -{ 16, 0xd820, 0, {0x23,0x40,0x09,0xf3,0x1a,0x5c,0x86,0x97,0x08,0x25,0x40,0x08,0x70,0x02,0x00,0x00 } }, -{ 16, 0xd830, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x14,0xcc,0x20,0x81,0x20,0x26,0xc0 } }, -{ 16, 0xd840, 0, {0x0b,0x30,0x02,0x2c,0x00,0x82,0x42,0x2c,0x80,0x0b,0x30,0x22,0x0c,0x08,0x9b,0x80 } }, -{ 16, 0xd850, 0, {0x20,0xe0,0x09,0x20,0x02,0x4d,0x08,0x92,0x00,0x24,0xe5,0x08,0x30,0x0a,0x08,0x04 } }, -{ 16, 0xd860, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xae,0x82,0xca,0xe0,0xb7,0xc0 } }, -{ 16, 0xd870, 0, {0x0f,0xf0,0x13,0x3c,0x0a,0xc9,0xc8,0x3e,0x40,0x0f,0xf0,0x03,0x3c,0x04,0xff,0x84 } }, -{ 16, 0xd880, 0, {0x32,0xc0,0x0d,0x90,0x13,0x7c,0x00,0xd9,0x00,0xf6,0xc0,0x2c,0x10,0x03,0x2a,0x04 } }, -{ 16, 0xd890, 0, {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xe4,0x00,0xf3,0x00,0x3a,0xc1 } }, -{ 16, 0xd8a0, 0, {0x4f,0xb0,0x03,0xec,0x00,0xf9,0x08,0x3c,0x00,0x0f,0x30,0x13,0xec,0x00,0xeb,0x04 } }, -{ 16, 0xd8b0, 0, {0xbe,0x18,0x0f,0x90,0x23,0xac,0x60,0xe9,0x02,0x3a,0x40,0x4f,0x90,0x03,0xe0,0x00 } }, -{ 16, 0xd8c0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xca,0x00,0x33,0xc0 } }, -{ 16, 0xd8d0, 0, {0x0c,0xf0,0x03,0xfc,0x00,0xcd,0x02,0x7f,0x40,0x0c,0xf0,0x42,0x3c,0x00,0xcf,0x08 } }, -{ 16, 0xd8e0, 0, {0x37,0x10,0x0f,0xd0,0x03,0xfc,0x10,0xcd,0x08,0x3f,0x66,0x2c,0xd9,0x03,0x00,0x44 } }, -{ 16, 0xd8f0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x04,0x63,0x80,0x8b,0xe0,0x22,0xc0 } }, -{ 16, 0xd900, 0, {0x08,0xb0,0x22,0xec,0x00,0xd8,0x80,0x6e,0x20,0x68,0xb0,0x1a,0x2c,0x01,0xfb,0x00 } }, -{ 16, 0xd910, 0, {0x22,0x18,0x0b,0x88,0x43,0x4c,0x00,0x88,0xa0,0x2c,0xc0,0x1d,0x90,0x02,0x20,0x40 } }, -{ 16, 0xd920, 0, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x08,0x80,0x8b,0x20,0x22,0xc0 } }, -{ 16, 0xd930, 0, {0x08,0xb0,0x22,0xec,0x00,0x88,0x88,0x2e,0x62,0x48,0xb0,0x1a,0xcc,0x00,0x8b,0x00 } }, -{ 16, 0xd940, 0, {0x26,0xc0,0x4a,0x88,0x02,0xec,0x00,0x08,0x84,0x2e,0x40,0x09,0x90,0x02,0x20,0x00 } }, -{ 16, 0xd950, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x83,0x00,0x60,0xc0 } }, -{ 16, 0xd960, 0, {0x08,0x30,0x02,0xcc,0x00,0x90,0x06,0x6c,0x00,0x08,0x30,0x02,0x8c,0x00,0xa3,0x04 } }, -{ 16, 0xd970, 0, {0x20,0x00,0x8b,0x00,0x06,0x4c,0x21,0x80,0x00,0x6c,0xc0,0x49,0x10,0x0a,0x02,0x01 } }, -{ 16, 0xd980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xca,0x00,0xb2,0xc1 } }, -{ 16, 0xd990, 0, {0x88,0xb4,0x03,0xec,0x10,0xc8,0x00,0x2e,0x00,0x0c,0xb0,0x0b,0xbc,0x08,0x8f,0x00 } }, -{ 16, 0xd9a0, 0, {0x36,0x00,0x06,0x80,0x03,0xec,0x80,0xc8,0x02,0x3f,0xc1,0x0c,0x90,0x03,0x00,0x03 } }, -{ 16, 0xd9b0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x1d,0xf0,0x00,0xff,0x00,0x3f,0xc0 } }, -{ 16, 0xd9c0, 0, {0x0f,0x72,0x83,0xfc,0x18,0xfc,0x03,0x3f,0x00,0x8f,0x70,0x03,0x7c,0x00,0xff,0x00 } }, -{ 16, 0xd9d0, 0, {0x3d,0x00,0x0f,0xc0,0x23,0x8c,0x06,0xfc,0x00,0x3f,0x40,0x0e,0xd0,0x03,0xe8,0x06 } }, -{ 16, 0xd9e0, 0, {0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x41,0x03,0x70,0x40,0xdc,0x10 } }, -{ 16, 0xd9f0, 0, {0x37,0x04,0x0d,0xc1,0x03,0x70,0x40,0xdc,0x10,0x37,0x04,0x0d,0xc1,0x01,0x70,0x40 } }, -{ 16, 0xda00, 0, {0x9c,0x10,0x17,0x14,0x05,0xc1,0x03,0x70,0x40,0xdc,0x10,0x17,0x04,0x0d,0xc0,0x31 } }, -{ 16, 0xda10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x44,0x05,0x71,0x01,0x5c,0x40 } }, -{ 16, 0xda20, 0, {0x57,0x10,0x15,0xc4,0x05,0x21,0x01,0x5c,0x40,0x57,0x10,0x15,0xc4,0x01,0x71,0x01 } }, -{ 16, 0xda30, 0, {0x5c,0x40,0x17,0x10,0x05,0xc4,0x05,0x71,0x05,0x5c,0x41,0x57,0x10,0x15,0xc0,0x11 } }, -{ 16, 0xda40, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x01,0x20,0x80,0x48,0x20 } }, -{ 16, 0xda50, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 } }, -{ 16, 0xda60, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x20 } }, -{ 16, 0xda70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x60,0x00,0x58,0x00 } }, -{ 16, 0xda80, 0, {0x16,0x00,0x05,0x80,0x01,0x60,0x00,0x58,0x00,0x16,0x00,0x05,0x80,0x05,0x60,0x00 } }, -{ 16, 0xda90, 0, {0x58,0x00,0x16,0x18,0x01,0x80,0x01,0x60,0x00,0x58,0x00,0x56,0x00,0x05,0x80,0x20 } }, -{ 16, 0xdaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x05,0x22,0x01,0x1c,0x80 } }, -{ 16, 0xdab0, 0, {0x47,0x20,0x11,0xc8,0x04,0x72,0x01,0x5c,0x80,0x57,0x20,0x11,0xc8,0x04,0x72,0x41 } }, -{ 16, 0xdac0, 0, {0x5c,0x80,0x57,0x20,0x11,0xc8,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x15,0xc0,0x31 } }, -{ 16, 0xdad0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x00,0x60,0x00,0x18,0x00 } }, -{ 16, 0xdae0, 0, {0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00 } }, -{ 16, 0xdaf0, 0, {0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x31 } }, -{ 16, 0xdb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x04,0x22,0x01,0x08,0x80 } }, -{ 16, 0xdb10, 0, {0x42,0x20,0x10,0x88,0x04,0x22,0x01,0x08,0x80,0x42,0x20,0x10,0x80,0x04,0x23,0x01 } }, -{ 16, 0xdb20, 0, {0x08,0x80,0x42,0x20,0x10,0x88,0x04,0x22,0x01,0x08,0x00,0x42,0x20,0x10,0x80,0x21 } }, -{ 16, 0xdb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x4a,0x05,0x42,0x81,0x50,0xa0 } }, -{ 16, 0xdb40, 0, {0x44,0x2c,0x11,0x0b,0x04,0x42,0x81,0x10,0xe0,0x54,0x28,0x11,0x02,0x00,0x42,0x81 } }, -{ 16, 0xdb50, 0, {0x10,0xa0,0x44,0x38,0x11,0x0b,0x05,0x42,0x81,0x10,0x21,0x14,0x28,0x15,0x00,0x31 } }, -{ 16, 0xdb60, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0c,0x01,0x57,0x00,0x54,0xc0 } }, -{ 16, 0xdb70, 0, {0x15,0x30,0x04,0x4c,0x01,0x13,0x00,0x54,0xc0,0x15,0x70,0x05,0x4c,0x01,0x53,0x00 } }, -{ 16, 0xdb80, 0, {0x54,0xc0,0x15,0x30,0x85,0x4c,0x01,0x13,0x00,0x54,0xc0,0x15,0x30,0x05,0x40,0x21 } }, -{ 16, 0xdb90, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x10,0x00 } }, -{ 16, 0xdba0, 0, {0x04,0x00,0x00,0x40,0x00,0x10,0x00,0x10,0x62,0x04,0x00,0x01,0x08,0x04,0x41,0x00 } }, -{ 16, 0xdbb0, 0, {0x10,0x00,0x44,0x18,0x11,0x00,0x00,0x10,0x00,0x10,0x80,0x04,0x00,0x01,0x01,0x20 } }, -{ 16, 0xdbc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x60,0x02,0x08,0x00,0x82,0x00 } }, -{ 16, 0xdbd0, 0, {0x20,0x80,0x08,0x60,0x02,0x18,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x00,0x08,0x20 } }, -{ 16, 0xdbe0, 0, {0x82,0x00,0x00,0x80,0x80,0x20,0x02,0x18,0x00,0x82,0x00,0x20,0x80,0x08,0x01,0x31 } }, -{ 16, 0xdbf0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x05,0x64,0x01,0x58,0x00 } }, -{ 16, 0xdc00, 0, {0x56,0x00,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x56,0x40,0x15,0x80,0x05,0x60,0x01 } }, -{ 16, 0xdc10, 0, {0x58,0x00,0x56,0x00,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x76,0x00,0x15,0x80,0x31 } }, -{ 16, 0xdc20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x03,0x60,0x00,0xd8,0x00 } }, -{ 16, 0xdc30, 0, {0x36,0x00,0x0d,0x80,0x03,0x60,0x00,0x98,0x00,0x36,0x00,0x1d,0x88,0x05,0x60,0x00 } }, -{ 16, 0xdc40, 0, {0xd8,0x00,0x16,0x00,0x0d,0x80,0x03,0x60,0x00,0xd8,0x80,0x46,0x00,0x0d,0x80,0x31 } }, -{ 16, 0xdc50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x04,0x30,0x81,0x0c,0x20 } }, -{ 16, 0xdc60, 0, {0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x22,0x41,0x08,0x18,0xc2,0x04,0x30,0x89 } }, -{ 16, 0xdc70, 0, {0x0c,0x20,0x03,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x10,0xc0,0x10 } }, -{ 16, 0xdc80, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x30,0x00,0x0c,0x00 } }, -{ 16, 0xdc90, 0, {0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00 } }, -{ 16, 0xdca0, 0, {0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x01 } }, -{ 16, 0xdcb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x01,0x30,0x80,0x4c,0x20 } }, -{ 16, 0xdcc0, 0, {0x13,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c,0x20,0x13,0x08,0x04,0xc3,0x01,0x30,0x80 } }, -{ 16, 0xdcd0, 0, {0x4c,0x20,0x13,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c,0x30,0x13,0x08,0x04,0xc0,0x21 } }, -{ 16, 0xdce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x05,0x60,0x81,0x58,0x20 } }, -{ 16, 0xdcf0, 0, {0x56,0x08,0x11,0x82,0x05,0x60,0x81,0x58,0x20,0x56,0x08,0x11,0x83,0x00,0x60,0x81 } }, -{ 16, 0xdd00, 0, {0x58,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x81,0x18,0x30,0x56,0x08,0x15,0x80,0x30 } }, -{ 16, 0xdd10, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x00,0x20,0x80,0x08,0x20 } }, -{ 16, 0xdd20, 0, {0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x30,0x80 } }, -{ 16, 0xdd30, 0, {0x08,0x20,0x02,0x00,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x03,0x08,0x00,0x80,0x31 } }, -{ 16, 0xdd40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x04,0x60,0x81,0x18,0x20 } }, -{ 16, 0xdd50, 0, {0x46,0x48,0x11,0x92,0x04,0x60,0x81,0x19,0x20,0x46,0x28,0x11,0x82,0x00,0x34,0x81 } }, -{ 16, 0xdd60, 0, {0x18,0x20,0x46,0x48,0x11,0x92,0x04,0x60,0x81,0x18,0x20,0x43,0x08,0x11,0x80,0x11 } }, -{ 16, 0xdd70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x60,0x04,0x58,0x01,0x56,0x00 } }, -{ 16, 0xdd80, 0, {0x55,0x80,0x15,0x60,0x04,0x58,0x01,0x16,0x00,0x55,0x80,0x01,0x60,0x04,0x18,0x01 } }, -{ 16, 0xdd90, 0, {0x56,0x00,0x45,0x80,0x11,0x60,0x04,0x58,0x01,0x16,0x00,0x41,0x80,0x11,0x40,0x31 } }, -{ 16, 0xdda0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x06,0x01,0x41,0x80,0x50,0x60 } }, -{ 16, 0xddb0, 0, {0x14,0x18,0x05,0x06,0x01,0x41,0x80,0x50,0x60,0x04,0x18,0x05,0x06,0x00,0x41,0x80 } }, -{ 16, 0xddc0, 0, {0x10,0x60,0x14,0x18,0x05,0x06,0x01,0x41,0x80,0x50,0x60,0x14,0x18,0x05,0x00,0x20 } }, -{ 16, 0xddd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x80,0x40,0x20 } }, -{ 16, 0xdde0, 0, {0x10,0x48,0x04,0x12,0x01,0x00,0x80,0x41,0x20,0x10,0x08,0x04,0x02,0x01,0x04,0x80 } }, -{ 16, 0xddf0, 0, {0x40,0x20,0x50,0x48,0x04,0x12,0x01,0x00,0x84,0x40,0x20,0x10,0x08,0x04,0x00,0x20 } }, -{ 16, 0xde00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x46,0x03,0x51,0x80,0xd4,0x60 } }, -{ 16, 0xde10, 0, {0x30,0x18,0x0d,0x46,0x03,0x51,0x80,0xd5,0x60,0x35,0x18,0x0d,0x46,0x03,0x05,0x80 } }, -{ 16, 0xde20, 0, {0xd4,0x60,0x15,0x18,0x0d,0x46,0x03,0x11,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x31 } }, -{ 16, 0xde30, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x46,0x05,0x71,0x80,0x5c,0x60 } }, -{ 16, 0xde40, 0, {0x97,0x18,0x15,0xc6,0x05,0x71,0x81,0x5c,0x20,0x57,0x18,0x15,0xc6,0x03,0x70,0x81 } }, -{ 16, 0xde50, 0, {0x5c,0x60,0x57,0x18,0x11,0xc6,0x05,0x31,0x81,0x5c,0x60,0x77,0x18,0x15,0xc0,0x31 } }, -{ 16, 0xde60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x46,0x03,0x71,0x80,0xdc,0x60 } }, -{ 16, 0xde70, 0, {0x37,0x18,0x0d,0xc6,0x03,0x71,0x80,0xdd,0x60,0x37,0x18,0x05,0xc6,0x01,0x75,0x81 } }, -{ 16, 0xde80, 0, {0xdc,0x60,0x37,0x18,0x0d,0xc6,0x03,0x71,0x84,0x5c,0x60,0x17,0x18,0x19,0xc0,0x11 } }, -{ 16, 0xde90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x46,0x05,0x71,0x81,0x5c,0x60 } }, -{ 16, 0xdea0, 0, {0x57,0x18,0x14,0x86,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x05,0xc6,0x04,0x31,0x81 } }, -{ 16, 0xdeb0, 0, {0x5c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71,0x80,0x5c,0x60,0x43,0x18,0x15,0xc0,0x11 } }, -{ 16, 0xdec0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x20,0x80,0x48,0x20 } }, -{ 16, 0xded0, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x70,0x80 } }, -{ 16, 0xdee0, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x17,0x08,0x04,0x80,0x00 } }, -{ 16, 0xdef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x01,0x61,0x80,0x58,0x60 } }, -{ 16, 0xdf00, 0, {0x16,0x18,0x41,0x86,0x01,0x61,0x80,0x18,0x60,0x06,0x3c,0x05,0x86,0x04,0x61,0x80 } }, -{ 16, 0xdf10, 0, {0x18,0x60,0x16,0x18,0x01,0x86,0x00,0x61,0x80,0x58,0x60,0x56,0x18,0x15,0x80,0x10 } }, -{ 16, 0xdf20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x05,0x70,0x01,0x5c,0x00 } }, -{ 16, 0xdf30, 0, {0x57,0x00,0x15,0xc0,0x04,0x70,0x01,0x5c,0x00,0x57,0x00,0x10,0xc0,0x04,0x70,0x00 } }, -{ 16, 0xdf40, 0, {0x1c,0x00,0x47,0x00,0x11,0xc0,0x04,0x70,0x01,0x5c,0x00,0x47,0x00,0x01,0xc0,0x11 } }, -{ 16, 0xdf50, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x00,0x60,0x80,0x18,0x20 } }, -{ 16, 0xdf60, 0, {0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18,0x20,0x06,0x08,0x00,0x82,0x00,0x60,0x80 } }, -{ 16, 0xdf70, 0, {0x18,0x20,0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18,0x20,0x06,0x08,0x01,0x80,0x11 } }, -{ 16, 0xdf80, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x42,0x04,0x20,0x81,0x08,0x20 } }, -{ 16, 0xdf90, 0, {0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x11,0x82,0x04,0x20,0x80 } }, -{ 16, 0xdfa0, 0, {0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x00,0x80,0x11 } }, -{ 16, 0xdfb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x05,0x40,0x81,0x50,0x20 } }, -{ 16, 0xdfc0, 0, {0x54,0x08,0x15,0x02,0x05,0x40,0x81,0x10,0x20,0x54,0x0c,0x15,0x42,0x00,0x40,0x81 } }, -{ 16, 0xdfd0, 0, {0x50,0x20,0x44,0x08,0x11,0x02,0x05,0x40,0x81,0x10,0x20,0x14,0x08,0x05,0x00,0x11 } }, -{ 16, 0xdfe0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x01,0x50,0xc0,0x54,0x30 } }, -{ 16, 0xdff0, 0, {0x15,0x08,0x05,0x42,0x01,0x50,0xc0,0x54,0x30,0x15,0x0c,0x05,0x43,0x01,0x50,0xc0 } }, -{ 16, 0xe000, 0, {0x54,0x30,0x15,0x0c,0x05,0x42,0x01,0x50,0xc0,0x54,0x30,0x15,0x0c,0x05,0x40,0x10 } }, -{ 16, 0xe010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x42,0x00,0x10,0x80 } }, -{ 16, 0xe020, 0, {0x04,0x20,0x01,0x88,0x00,0x62,0x00,0x10,0x80,0x04,0x00,0x11,0x08,0x00,0x42,0x00 } }, -{ 16, 0xe030, 0, {0x10,0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x01,0x10,0x80,0x04,0x20,0x01,0x00,0x00 } }, -{ 16, 0xe040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x02,0x00,0x80,0x80,0x20 } }, -{ 16, 0xe050, 0, {0x20,0x08,0x08,0x02,0x02,0x20,0x80,0x80,0x20,0x20,0x28,0x00,0x02,0x02,0x00,0x80 } }, -{ 16, 0xe060, 0, {0x80,0x20,0x20,0x0a,0x08,0x02,0x02,0x00,0x80,0x00,0x20,0x20,0x08,0x08,0x00,0x11 } }, -{ 16, 0xe070, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x05,0x60,0x01,0x58,0x00 } }, -{ 16, 0xe080, 0, {0x56,0x00,0x05,0x80,0x05,0x60,0x01,0x58,0x08,0x56,0x00,0x15,0x80,0x07,0x60,0x02 } }, -{ 16, 0xe090, 0, {0x58,0x00,0x56,0x40,0x15,0x80,0x05,0x60,0x03,0x18,0x00,0x76,0x00,0x15,0x80,0x11 } }, -{ 16, 0xe0a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x03,0x60,0x00,0xd8,0x00 } }, -{ 16, 0xe0b0, 0, {0x36,0x00,0x0d,0x80,0x01,0x60,0x00,0xd8,0x0a,0x36,0x00,0x0d,0x80,0x05,0x70,0x09 } }, -{ 16, 0xe0c0, 0, {0xd8,0x01,0x36,0x00,0x0d,0x80,0x03,0x60,0x00,0xd8,0x00,0x57,0x00,0x0d,0x80,0x00 } }, -{ 16, 0xe0d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x30,0x01,0x0c,0x00 } }, -{ 16, 0xe0e0, 0, {0x43,0x00,0x10,0xc0,0x00,0x30,0x01,0x0c,0x00,0x43,0x20,0x10,0xc0,0x04,0x60,0x01 } }, -{ 16, 0xe0f0, 0, {0x0c,0x00,0x43,0x40,0x50,0xc1,0x04,0x30,0x01,0x0c,0x00,0x46,0x00,0x10,0xc0,0x00 } }, -{ 16, 0xe100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0c,0x00 } }, -{ 16, 0xe110, 0, {0x01,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xd0,0x00,0x20,0x00 } }, -{ 16, 0xe120, 0, {0x0c,0x00,0x03,0x40,0x00,0xc0,0x00,0x30,0x00,0x0d,0x00,0x02,0x00,0x00,0xc0,0x00 } }, -{ 16, 0xe130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,0x31,0x40,0x4c,0x50 } }, -{ 16, 0xe140, 0, {0x13,0x10,0x04,0xc4,0x01,0x31,0x40,0x4c,0x50,0x13,0x14,0x04,0xc5,0x11,0x31,0x41 } }, -{ 16, 0xe150, 0, {0x4c,0x50,0x13,0x14,0x04,0xc5,0x01,0x31,0x40,0x4c,0x50,0x13,0x14,0x04,0xc0,0x00 } }, -{ 16, 0xe160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x05,0x68,0xc1,0x5a,0x30 } }, -{ 16, 0xe170, 0, {0x56,0x8c,0x11,0xa3,0x04,0x68,0xc1,0x1a,0x30,0x56,0x8c,0x11,0xa3,0x05,0x68,0xc0 } }, -{ 16, 0xe180, 0, {0x5a,0x30,0x46,0x8c,0x11,0xa3,0x04,0x68,0xc1,0x5a,0x30,0x16,0x8c,0x15,0x80,0x00 } }, -{ 16, 0xe190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x00 } }, -{ 16, 0xe1a0, 0, {0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x20,0x00,0x90,0x00,0x20,0x00 } }, -{ 16, 0xe1b0, 0, {0x08,0x00,0x02,0x40,0x00,0x80,0x00,0x20,0x00,0x09,0x00,0x02,0x00,0x00,0x80,0x00 } }, -{ 16, 0xe1c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x44,0x62,0x01,0x18,0x84 } }, -{ 16, 0xe1d0, 0, {0x46,0x21,0x11,0x88,0x44,0x62,0x11,0x18,0x84,0x46,0x01,0x11,0x88,0x44,0x62,0x10 } }, -{ 16, 0xe1e0, 0, {0x18,0x84,0x46,0x21,0x11,0x88,0x44,0x62,0x11,0x18,0x84,0x06,0x21,0x11,0x80,0x00 } }, -{ 16, 0xe1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x50,0x11,0x54,0x04 } }, -{ 16, 0xe200, 0, {0x55,0x01,0x11,0x40,0x45,0x50,0x11,0x14,0x00,0x45,0x01,0x11,0x40,0x44,0x50,0x00 } }, -{ 16, 0xe210, 0, {0x14,0x04,0x45,0x00,0x15,0x40,0x44,0x50,0x11,0x14,0x04,0x55,0x01,0x11,0x40,0x00 } }, -{ 16, 0xe220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x21,0x42,0x08,0x50,0x82 } }, -{ 16, 0xe230, 0, {0x14,0x20,0x85,0x08,0x21,0x42,0x08,0x50,0x82,0x04,0x20,0x85,0x08,0x21,0x42,0x08 } }, -{ 16, 0xe240, 0, {0x50,0x82,0x14,0x20,0x05,0x08,0x21,0x42,0x08,0x50,0x82,0x14,0x20,0x85,0x00,0x00 } }, -{ 16, 0xe250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0 } }, -{ 16, 0xe260, 0, {0x10,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x40,0x0a,0x01,0x02,0x80 } }, -{ 16, 0xe270, 0, {0x40,0xa0,0x10,0x28,0x44,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x00,0x00 } }, -{ 16, 0xe280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x03,0x53,0x00,0xd4,0xc0 } }, -{ 16, 0xe290, 0, {0x35,0x30,0x0d,0x4c,0x01,0x53,0x00,0xd4,0xc0,0x35,0x10,0x0c,0x4c,0x03,0x53,0x00 } }, -{ 16, 0xe2a0, 0, {0xd4,0xc0,0x35,0x30,0x0d,0x4c,0x03,0x53,0x00,0xd4,0xc0,0x35,0x30,0x0d,0x40,0x00 } }, -{ 16, 0xe2b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x72,0x01,0x5c,0x80 } }, -{ 16, 0xe2c0, 0, {0x17,0x20,0x05,0xc8,0x06,0x72,0x01,0x5c,0x80,0x57,0x20,0x15,0xc8,0x02,0x72,0x01 } }, -{ 16, 0xe2d0, 0, {0x5c,0x80,0x57,0x20,0x15,0xc8,0x05,0x72,0x01,0x5c,0x80,0x37,0x20,0x11,0xc0,0x00 } }, -{ 16, 0xe2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x18,0x40,0xc6,0x12,0x31 } }, -{ 16, 0xe2f0, 0, {0x84,0x8c,0x21,0x23,0x08,0x48,0xc6,0x12,0x30,0x84,0x0c,0x61,0x23,0x10,0x48,0xc2 } }, -{ 16, 0xe300, 0, {0x12,0x31,0x84,0x8c,0x01,0x23,0x08,0x48,0xc6,0x12,0x31,0x04,0x8c,0x61,0x00,0x00 } }, -{ 16, 0xe310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff } }, -{ 16, 0xe320, 0, {0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff } }, -{ 16, 0xe330, 0, {0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x00,0x00 } }, -{ 16, 0xe340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xe350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xe360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xe370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xdb,0x0f,0xb6,0xc2,0xcd } }, -{ 16, 0xe380, 0, {0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xdf,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x7e } }, -{ 16, 0xe390, 0, {0xc2,0xcd,0xb0,0xb7,0xfd,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x00,0x00 } }, -{ 16, 0xe3a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x3c,0x4f,0xcf,0x13,0x33 } }, -{ 16, 0xe3b0, 0, {0xc4,0xcc,0xf1,0x33,0x3c,0x4c,0xcf,0x13,0x3f,0xc4,0xcc,0xf1,0x33,0x3c,0x4c,0xff } }, -{ 16, 0xe3c0, 0, {0x13,0x33,0xc4,0xcf,0xfd,0x33,0x3c,0x4c,0xcf,0x13,0x33,0xc4,0xcc,0xf1,0x00,0x00 } }, -{ 16, 0xe3d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x7e,0x4e,0xdf,0x93,0xb7 } }, -{ 16, 0xe3e0, 0, {0xe4,0xec,0x79,0x3b,0x1e,0x4e,0xdf,0x93,0xbf,0xe4,0x8d,0xf9,0x3b,0x78,0x4e,0xff } }, -{ 16, 0xe3f0, 0, {0x93,0xb7,0xe4,0xed,0xfd,0x3b,0x1e,0x4e,0xdf,0x93,0xb7,0x84,0xed,0xf9,0x00,0x00 } }, -{ 16, 0xe400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x70,0x40,0x9c,0x10 } }, -{ 16, 0xe410, 0, {0x27,0x1c,0x09,0xc1,0x01,0x30,0x40,0x1c,0x10,0x67,0x04,0x09,0xc1,0x02,0x70,0x41 } }, -{ 16, 0xe420, 0, {0x9c,0x11,0x07,0x14,0x01,0xc1,0x02,0x70,0x40,0x9c,0x50,0x07,0x1c,0x01,0xc0,0x00 } }, -{ 16, 0xe430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x05,0x71,0x01,0x5c,0x40 } }, -{ 16, 0xe440, 0, {0x57,0x10,0x55,0xc4,0x01,0x31,0x00,0x5c,0x40,0x57,0x10,0x15,0xc4,0x05,0x71,0x01 } }, -{ 16, 0xe450, 0, {0xdc,0x40,0x17,0x18,0x1d,0xc4,0x05,0x71,0x05,0x5c,0x40,0x57,0x10,0x1d,0xc0,0x00 } }, -{ 16, 0xe460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x20,0x80,0x48,0x20 } }, -{ 16, 0xe470, 0, {0x12,0x00,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 } }, -{ 16, 0xe480, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x60,0x12,0x08,0x04,0x80,0x00 } }, -{ 16, 0xe490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00 } }, -{ 16, 0xe4a0, 0, {0x06,0x00,0x41,0x80,0x00,0x60,0x00,0x18,0x00,0x46,0x00,0x01,0x80,0x00,0x60,0x00 } }, -{ 16, 0xe4b0, 0, {0x10,0x00,0x06,0x10,0x01,0x80,0x00,0x60,0x00,0x18,0x20,0x46,0x10,0x01,0x80,0x00 } }, -{ 16, 0xe4c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x72,0x01,0x1c,0x80 } }, -{ 16, 0xe4d0, 0, {0x47,0x20,0x11,0xc8,0x04,0x72,0x01,0x1c,0x80,0x07,0x20,0x11,0xc8,0x04,0x73,0x00 } }, -{ 16, 0xe4e0, 0, {0x1c,0x80,0x47,0x20,0x11,0xcc,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x11,0xc0,0x00 } }, -{ 16, 0xe4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00 } }, -{ 16, 0xe500, 0, {0x06,0x00,0x01,0x84,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x40 } }, -{ 16, 0xe510, 0, {0x18,0x00,0x06,0x04,0x01,0x81,0x00,0x60,0x00,0x18,0x00,0x06,0x14,0x01,0x80,0x00 } }, -{ 16, 0xe520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x22,0x01,0x08,0x80 } }, -{ 16, 0xe530, 0, {0x42,0x70,0x10,0x8c,0x04,0x22,0x01,0x08,0xc0,0x02,0x20,0x10,0x88,0x04,0x22,0x00 } }, -{ 16, 0xe540, 0, {0x08,0x80,0x42,0x50,0x10,0x08,0x04,0x22,0x01,0x09,0x00,0x42,0x40,0x10,0x80,0x00 } }, -{ 16, 0xe550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0x04,0x4a,0x81,0x12,0xa0 } }, -{ 16, 0xe560, 0, {0x44,0xa8,0x11,0x2a,0x04,0x4a,0x81,0x12,0xa0,0x04,0xa8,0x11,0x2a,0x04,0x4b,0x80 } }, -{ 16, 0xe570, 0, {0x12,0xa0,0x44,0x88,0x01,0x2e,0x04,0x4a,0x81,0x12,0x20,0x04,0x98,0x01,0x00,0x00 } }, -{ 16, 0xe580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x0e,0x00,0x53,0x00,0x14,0xc0 } }, -{ 16, 0xe590, 0, {0x05,0x30,0x01,0x4c,0x00,0x53,0x00,0x14,0xe0,0x05,0x30,0x01,0x4c,0x00,0x53,0x00 } }, -{ 16, 0xe5a0, 0, {0x04,0xc0,0x05,0x30,0x00,0x4c,0x00,0x03,0x00,0x14,0xc0,0x05,0x30,0x00,0x40,0x10 } }, -{ 16, 0xe5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x04,0x00,0x40,0x00,0x10,0x00 } }, -{ 16, 0xe5c0, 0, {0x04,0x58,0x01,0x04,0x00,0x40,0x00,0x10,0x00,0x04,0x00,0x01,0x00,0x00,0x41,0x00 } }, -{ 16, 0xe5d0, 0, {0x04,0x00,0x44,0x58,0x10,0x44,0x00,0x00,0x00,0x11,0x80,0x04,0x50,0x10,0x40,0x30 } }, -{ 16, 0xe5e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x40,0x02,0x00,0x00,0x80,0x00 } }, -{ 16, 0xe5f0, 0, {0x20,0x00,0x08,0x00,0x40,0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00 } }, -{ 16, 0xe600, 0, {0x84,0x00,0x00,0x00,0x08,0x40,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x40,0x30 } }, -{ 16, 0xe610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x40,0x00,0x60,0x01,0x18,0x00 } }, -{ 16, 0xe620, 0, {0x46,0x00,0x01,0x80,0x06,0x60,0x01,0x98,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01 } }, -{ 16, 0xe630, 0, {0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x20,0x01,0x18,0x00,0x66,0x00,0x11,0x80,0x30 } }, -{ 16, 0xe640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x40,0x00,0x60,0x00,0x98,0x00 } }, -{ 16, 0xe650, 0, {0x26,0x00,0x09,0x80,0x02,0x60,0x01,0x98,0x00,0x06,0x00,0x0c,0x80,0x02,0x60,0x00 } }, -{ 16, 0xe660, 0, {0x18,0x00,0x06,0x00,0x01,0x80,0x02,0x60,0x00,0x98,0x80,0x06,0x00,0x01,0x82,0x00 } }, -{ 16, 0xe670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x00,0x30,0x81,0x0c,0x20 } }, -{ 16, 0xe680, 0, {0x43,0x08,0x10,0xc2,0x24,0x30,0x81,0x8c,0x20,0x03,0x08,0x10,0xc2,0x04,0x20,0x80 } }, -{ 16, 0xe690, 0, {0x0c,0x20,0x03,0x08,0x18,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x18,0xc0,0x11 } }, -{ 16, 0xe6a0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x30,0x00,0x0c,0x00 } }, -{ 16, 0xe6b0, 0, {0x03,0x00,0x00,0xc0,0x40,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0x80,0x00,0x30,0x00 } }, -{ 16, 0xe6c0, 0, {0x0c,0x00,0x03,0x20,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x20,0x00,0xc0,0x00 } }, -{ 16, 0xe6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x02,0x10,0x30,0x80,0x0c,0x20 } }, -{ 16, 0xe6e0, 0, {0x03,0x08,0x00,0xc2,0x00,0x30,0x80,0x0c,0x20,0x03,0x08,0x00,0xc2,0x01,0x20,0x80 } }, -{ 16, 0xe6f0, 0, {0x0c,0x20,0x03,0x2c,0x00,0xc2,0x00,0x30,0x80,0x0c,0x30,0x43,0x2c,0x00,0xc0,0x00 } }, -{ 16, 0xe700, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x04,0x60,0x81,0x18,0x20 } }, -{ 16, 0xe710, 0, {0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x81 } }, -{ 16, 0xe720, 0, {0x18,0x20,0x46,0x0c,0x11,0xc2,0x04,0x60,0x81,0x18,0x30,0x46,0x0c,0x11,0xc0,0x11 } }, -{ 16, 0xe730, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x42,0x00,0x20,0x80,0x08,0x20 } }, -{ 16, 0xe740, 0, {0x02,0x28,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80 } }, -{ 16, 0xe750, 0, {0x08,0x20,0x02,0x08,0x01,0x82,0x00,0x20,0x80,0x08,0x20,0x03,0x08,0x01,0x80,0x00 } }, -{ 16, 0xe760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x42,0x04,0x60,0x81,0x18,0x20 } }, -{ 16, 0xe770, 0, {0x46,0x28,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x81 } }, -{ 16, 0xe780, 0, {0x18,0x20,0x46,0x08,0x10,0x82,0x04,0x60,0x81,0x18,0x20,0x43,0x08,0x10,0x80,0x00 } }, -{ 16, 0xe790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x40,0x04,0x50,0x01,0x14,0x00 } }, -{ 16, 0xe7a0, 0, {0x45,0x00,0x11,0x40,0x25,0x00,0x00,0x14,0x00,0x45,0x00,0x11,0x40,0x04,0x50,0x01 } }, -{ 16, 0xe7b0, 0, {0x14,0x00,0x45,0x00,0x00,0x40,0x04,0x50,0x01,0x40,0x00,0x01,0x00,0x00,0x42,0x11 } }, -{ 16, 0xe7c0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x06,0x00,0x41,0x80,0x10,0x60 } }, -{ 16, 0xe7d0, 0, {0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80 } }, -{ 16, 0xe7e0, 0, {0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x00,0x00 } }, -{ 16, 0xe7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x02,0x05,0x00,0x80,0x40,0x21 } }, -{ 16, 0xe800, 0, {0x10,0x08,0x04,0x00,0x01,0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x80 } }, -{ 16, 0xe810, 0, {0x40,0x20,0x50,0x08,0x14,0x02,0x11,0x00,0x84,0x40,0x20,0x10,0x08,0x14,0x00,0x00 } }, -{ 16, 0xe820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x46,0x01,0x51,0x80,0xd4,0x60 } }, -{ 16, 0xe830, 0, {0x35,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x15,0x18,0x0d,0x46,0x03,0x51,0x80 } }, -{ 16, 0xe840, 0, {0x54,0x60,0x15,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x11 } }, -{ 16, 0xe850, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x46,0x04,0x71,0x81,0x1c,0x60 } }, -{ 16, 0xe860, 0, {0x45,0x18,0x11,0xd6,0x04,0x71,0x81,0x1c,0x60,0x67,0x18,0x11,0xc6,0x04,0x71,0x81 } }, -{ 16, 0xe870, 0, {0x9c,0x60,0x47,0x18,0x11,0xc6,0x04,0x71,0x81,0x1c,0x60,0x67,0x18,0x11,0xc0,0x00 } }, -{ 16, 0xe880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x46,0x02,0x71,0x80,0x9c,0x60 } }, -{ 16, 0xe890, 0, {0x27,0x18,0x09,0xc6,0x00,0x71,0x80,0x9c,0x60,0x67,0x18,0x09,0xc6,0x02,0x71,0x80 } }, -{ 16, 0xe8a0, 0, {0x9c,0x61,0x27,0x18,0x01,0xc6,0x02,0x71,0x80,0x9c,0x60,0x07,0x18,0x01,0xc0,0x00 } }, -{ 16, 0xe8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x45,0x46,0x05,0x71,0x81,0x5c,0x60 } }, -{ 16, 0xe8c0, 0, {0x57,0x18,0x55,0xd6,0x01,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71,0x81 } }, -{ 16, 0xe8d0, 0, {0x5c,0x60,0x57,0x18,0x18,0xc6,0x05,0x71,0x81,0x5c,0x60,0x43,0x18,0x18,0x82,0x11 } }, -{ 16, 0xe8e0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x52,0x01,0x20,0x80,0x48,0x20 } }, -{ 16, 0xe8f0, 0, {0x12,0x48,0x04,0x90,0x01,0x20,0x80,0x49,0x20,0x12,0x08,0x04,0x82,0x01,0x24,0x80 } }, -{ 16, 0xe900, 0, {0x48,0x20,0x12,0x48,0x00,0x92,0x01,0x20,0x80,0x48,0x20,0x17,0x48,0x04,0x80,0x01 } }, -{ 16, 0xe910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x06,0x00,0x61,0x80,0x18,0x60 } }, -{ 16, 0xe920, 0, {0x06,0x3c,0x01,0x86,0x00,0x61,0x80,0x18,0x60,0x46,0x18,0x01,0x86,0x00,0x61,0x80 } }, -{ 16, 0xe930, 0, {0x18,0x60,0x06,0x18,0x01,0x86,0x00,0x61,0x80,0x18,0x60,0x46,0x18,0x01,0x80,0x01 } }, -{ 16, 0xe940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x60,0x04,0x78,0x01,0x1e,0x00 } }, -{ 16, 0xe950, 0, {0x47,0x80,0x11,0xe0,0x24,0x78,0x01,0x1e,0x00,0x07,0x80,0x11,0xe0,0x04,0x78,0x01 } }, -{ 16, 0xe960, 0, {0x1e,0x00,0x47,0x80,0x11,0xe0,0x04,0x38,0x01,0x1e,0x00,0x47,0x80,0x11,0xc0,0x11 } }, -{ 16, 0xe970, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x12,0x00,0x60,0x80,0x18,0x20 } }, -{ 16, 0xe980, 0, {0x06,0x48,0x01,0x92,0x00,0x60,0x80,0x19,0x20,0x06,0x08,0x01,0x82,0x00,0x64,0x80 } }, -{ 16, 0xe990, 0, {0x18,0x20,0x06,0x48,0x01,0x93,0x00,0x20,0x80,0x18,0x20,0x06,0x48,0x01,0x80,0x00 } }, -{ 16, 0xe9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x42,0x04,0x20,0x81,0x08,0x20 } }, -{ 16, 0xe9b0, 0, {0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x02,0x08,0x10,0x82,0x04,0x20,0x81 } }, -{ 16, 0xe9c0, 0, {0x08,0x20,0x42,0x08,0x10,0x8a,0x04,0x60,0x81,0x08,0x20,0x42,0x08,0x10,0x80,0x00 } }, -{ 16, 0xe9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x04,0x40,0x81,0x10,0x20 } }, -{ 16, 0xe9e0, 0, {0x44,0x08,0x11,0x02,0x04,0x40,0x81,0x10,0x20,0x04,0x08,0x11,0x02,0x04,0x40,0x81 } }, -{ 16, 0xe9f0, 0, {0x10,0x21,0x44,0x08,0x01,0x02,0x04,0x50,0x81,0x10,0x20,0x04,0x08,0x01,0x00,0x11 } }, -{ 16, 0xea00, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x03,0x00,0x50,0xc0,0x14,0x30 } }, -{ 16, 0xea10, 0, {0x05,0x0c,0x01,0x43,0x00,0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x43,0x00,0x50,0x80 } }, -{ 16, 0xea20, 0, {0x14,0x30,0x05,0x08,0x01,0x4a,0x00,0x50,0xc0,0x14,0x30,0x05,0x08,0x01,0x40,0x00 } }, -{ 16, 0xea30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x00,0x42,0x00,0x10,0x80 } }, -{ 16, 0xea40, 0, {0x04,0x20,0x01,0x08,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x00 } }, -{ 16, 0xea50, 0, {0x10,0x80,0x04,0x20,0x11,0x00,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x11,0x00,0x10 } }, -{ 16, 0xea60, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x02,0x00,0x80,0x80,0x20 } }, -{ 16, 0xea70, 0, {0x20,0x08,0x08,0x02,0x00,0x00,0x80,0x80,0x20,0x20,0x08,0x08,0x02,0x02,0x00,0x80 } }, -{ 16, 0xea80, 0, {0x80,0x20,0x20,0x08,0x08,0x02,0x02,0x00,0x80,0x80,0x20,0x20,0x08,0x08,0x00,0x11 } }, -{ 16, 0xea90, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x00,0x60,0x01,0x18,0x00 } }, -{ 16, 0xeaa0, 0, {0x46,0x00,0x11,0x80,0x06,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01 } }, -{ 16, 0xeab0, 0, {0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01,0x18,0x00,0x66,0x00,0x11,0x80,0x10 } }, -{ 16, 0xeac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x02,0x64,0x00,0x98,0x00 } }, -{ 16, 0xead0, 0, {0x26,0x00,0x09,0x90,0x06,0x60,0x01,0x98,0x00,0x26,0x40,0x09,0x80,0x02,0x60,0x00 } }, -{ 16, 0xeae0, 0, {0x98,0x00,0x26,0x00,0x00,0x90,0x02,0x60,0x00,0x98,0x00,0x07,0x00,0x01,0x80,0x00 } }, -{ 16, 0xeaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x60,0x04,0x38,0x05,0x0e,0x00 } }, -{ 16, 0xeb00, 0, {0x43,0x80,0x10,0xe0,0x44,0x38,0x01,0x0e,0x00,0x43,0x80,0x10,0xe0,0x04,0x38,0x01 } }, -{ 16, 0xeb10, 0, {0x0e,0x00,0x43,0x80,0x18,0xa0,0x04,0x38,0x01,0x0e,0x00,0x46,0x80,0x18,0x80,0x11 } }, -{ 16, 0xeb20, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x01,0x00,0x30,0x40,0x0c,0x10 } }, -{ 16, 0xeb30, 0, {0x03,0x04,0x00,0xc5,0x00,0x30,0x40,0x0c,0x10,0x03,0x14,0x00,0xc1,0x00,0x30,0x40 } }, -{ 16, 0xeb40, 0, {0x0c,0x10,0x03,0x04,0x00,0x87,0x40,0x30,0x40,0x0c,0x10,0x02,0x04,0x00,0x80,0x00 } }, -{ 16, 0xeb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x05,0x00,0x35,0x40,0x0c,0x50 } }, -{ 16, 0xeb60, 0, {0x03,0x14,0x00,0xd5,0x04,0x31,0x41,0x0c,0x50,0x03,0x5c,0x00,0xc5,0x00,0x31,0x00 } }, -{ 16, 0xeb70, 0, {0x0c,0x50,0x03,0x10,0x00,0x94,0x00,0x31,0x40,0x0c,0x50,0x43,0x10,0x00,0xc2,0x00 } }, -{ 16, 0xeb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x43,0x05,0x20,0xc1,0x18,0x30 } }, -{ 16, 0xeb90, 0, {0x46,0x0c,0x11,0x97,0x00,0x60,0xc0,0x18,0x30,0x46,0x1c,0x11,0x83,0x04,0x60,0xc1 } }, -{ 16, 0xeba0, 0, {0x18,0x30,0x52,0x0c,0x11,0x87,0x04,0x60,0xc1,0x18,0x30,0x46,0x0c,0x11,0x80,0x11 } }, -{ 16, 0xebb0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x00,0x00,0x21,0x40,0x08,0x00 } }, -{ 16, 0xebc0, 0, {0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x20,0x00 } }, -{ 16, 0xebd0, 0, {0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00 } }, -{ 16, 0xebe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x48,0x44,0x22,0x01,0x18,0x84 } }, -{ 16, 0xebf0, 0, {0x46,0x21,0x11,0x98,0x00,0x62,0x10,0x18,0x84,0x44,0x20,0x11,0x88,0x44,0x62,0x11 } }, -{ 16, 0xec00, 0, {0x18,0x84,0x42,0x21,0x11,0x80,0x44,0x62,0x11,0x18,0x84,0x46,0x21,0x11,0x80,0x00 } }, -{ 16, 0xec10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x40,0x04,0x50,0x11,0x14,0x04 } }, -{ 16, 0xec20, 0, {0x45,0x00,0x11,0x41,0x00,0x50,0x10,0x14,0x00,0x45,0x01,0x11,0x40,0x44,0x50,0x11 } }, -{ 16, 0xec30, 0, {0x14,0x04,0x45,0x01,0x01,0x40,0x44,0x50,0x11,0x14,0x04,0x05,0x01,0x01,0x40,0x11 } }, -{ 16, 0xec40, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x20,0x42,0x08,0x10,0x82 } }, -{ 16, 0xec50, 0, {0x04,0x20,0x01,0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08 } }, -{ 16, 0xec60, 0, {0x10,0x82,0x04,0x22,0x81,0x08,0x20,0x52,0x08,0x10,0x8a,0x04,0x22,0x81,0x00,0x00 } }, -{ 16, 0xec70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0a,0x01,0x02,0x84,0x40,0xa1 } }, -{ 16, 0xec80, 0, {0x10,0x28,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x0a,0x01,0x02,0x80 } }, -{ 16, 0xec90, 0, {0x40,0xa0,0x10,0x2c,0x14,0x0a,0x00,0x02,0x80,0x40,0xb0,0x10,0x2c,0x14,0x00,0x00 } }, -{ 16, 0xeca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x4d,0x03,0x53,0x40,0xd4,0xd0 } }, -{ 16, 0xecb0, 0, {0x35,0x30,0x0c,0x4d,0x03,0x53,0x40,0xd4,0xd0,0x35,0x34,0x0d,0x4d,0x03,0x53,0x40 } }, -{ 16, 0xecc0, 0, {0xd4,0xd0,0x35,0x34,0x0d,0x4d,0x02,0x13,0x40,0xd4,0xd0,0x35,0x34,0x0d,0x40,0x11 } }, -{ 16, 0xecd0, 0, {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x08,0x04,0x72,0x01,0x1c,0x80 } }, -{ 16, 0xece0, 0, {0x47,0x20,0x15,0xc8,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x11 } }, -{ 16, 0xecf0, 0, {0x1c,0x80,0x47,0x26,0x11,0xc8,0x44,0x72,0x01,0x1c,0x90,0x67,0x26,0x11,0xc0,0x00 } }, -{ 16, 0xed00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x08,0x40,0xc6,0x12,0x31 } }, -{ 16, 0xed10, 0, {0x84,0x8c,0x01,0x03,0x08,0x48,0xc6,0x12,0x30,0x84,0x0c,0x61,0x23,0x18,0x48,0xc2 } }, -{ 16, 0xed20, 0, {0x12,0x31,0x84,0x8c,0x01,0x03,0x08,0x48,0xc6,0x12,0x31,0x04,0x8c,0x01,0x00,0x00 } }, -{ 16, 0xed30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff } }, -{ 16, 0xed40, 0, {0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff } }, -{ 16, 0xed50, 0, {0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x00,0x00 } }, -{ 16, 0xed60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xed70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xed80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xed90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xfb,0x0f,0xb6,0xc2,0xcd } }, -{ 16, 0xeda0, 0, {0xb0,0xb7,0xfd,0x3f,0xfb,0x0b,0x36,0xc2,0xdf,0xb0,0xfb,0x6c,0x2c,0xdb,0x0b,0x7e } }, -{ 16, 0xedb0, 0, {0xc2,0xcd,0xb0,0xb7,0xfd,0x3f,0xfb,0x0b,0x36,0xc2,0xcd,0xf4,0xb7,0xfd,0x00,0x00 } }, -{ 16, 0xedc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0xfc,0x4f,0xcf,0x13,0x33 } }, -{ 16, 0xedd0, 0, {0xc4,0xcf,0xfd,0x3f,0xfc,0x4c,0xcf,0x13,0x3f,0xc4,0xfc,0xf1,0x33,0x3c,0x4c,0xff } }, -{ 16, 0xede0, 0, {0x13,0x33,0xc4,0xcf,0xfd,0x3f,0xfc,0x4c,0xcf,0x13,0x33,0xf4,0xcf,0xfd,0x00,0x00 } }, -{ 16, 0xedf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x7e,0x4e,0xdf,0x93,0xb7 } }, -{ 16, 0xee00, 0, {0xe4,0xed,0xf9,0x3f,0xfe,0x4e,0xdf,0x93,0xb7,0xe4,0xed,0xf9,0x3b,0x7e,0x4e,0xc7 } }, -{ 16, 0xee10, 0, {0x93,0xb7,0xe4,0xec,0x61,0x23,0x1e,0x4e,0xdf,0x93,0xb7,0x84,0xec,0x61,0x00,0x00 } }, -{ 16, 0xee20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x24,0xa1,0x4a,0x24 } }, -{ 16, 0xee30, 0, {0x63,0x01,0x14,0x02,0x44,0x00,0x81,0x0b,0x28,0x71,0x02,0x10,0x82,0x40,0x38,0x11 } }, -{ 16, 0xee40, 0, {0x41,0x04,0x50,0x08,0x18,0x82,0x87,0x38,0x31,0xc3,0x2c,0x52,0x0a,0x10,0x00,0x00 } }, -{ 16, 0xee50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x45,0x12,0x81,0x44,0x80 } }, -{ 16, 0xee60, 0, {0x71,0x21,0x1c,0x0a,0x07,0x1a,0x81,0x02,0xa0,0x52,0x20,0x14,0x48,0x07,0x12,0x81 } }, -{ 16, 0xee70, 0, {0xc6,0x80,0x60,0x20,0x08,0x88,0x47,0x02,0x01,0x4a,0x80,0x70,0x20,0x10,0x00,0x00 } }, -{ 16, 0xee80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc5,0x2c,0x01,0x4a,0x00 } }, -{ 16, 0xee90, 0, {0x52,0x09,0x1c,0x80,0x07,0x24,0x21,0x08,0x08,0x71,0x02,0x10,0x80,0x45,0x20,0xa1 } }, -{ 16, 0xeea0, 0, {0x49,0x28,0x52,0x01,0x14,0xc0,0x45,0x00,0x91,0xc4,0x00,0x72,0x02,0x10,0x00,0x00 } }, -{ 16, 0xeeb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x07,0x20,0x01,0xc1,0x00 } }, -{ 16, 0xeec0, 0, {0x71,0x09,0x10,0x80,0x07,0x00,0x01,0x01,0x00,0x70,0x08,0x18,0x80,0x07,0x00,0x01 } }, -{ 16, 0xeed0, 0, {0x89,0x20,0x52,0x01,0x0c,0x80,0x46,0x30,0x81,0x45,0x04,0x60,0x00,0x10,0x00,0x00 } }, -{ 16, 0xeee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc2,0x02,0x20,0x00,0x88 } }, -{ 16, 0xeef0, 0, {0x20,0x22,0x00,0x08,0xc2,0x22,0x80,0x40,0x88,0x02,0x22,0x00,0x08,0x82,0x0a,0xa0 } }, -{ 16, 0xef00, 0, {0x0c,0xa8,0x02,0x22,0x00,0x08,0x80,0x0a,0x00,0x80,0x8c,0x02,0x22,0x00,0x00,0x00 } }, -{ 16, 0xef10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x43,0x00,0x00,0x40,0x20 } }, -{ 16, 0xef20, 0, {0x30,0x08,0x04,0x40,0x41,0x30,0x10,0xc8,0x00,0x00,0x00,0x00,0x02,0x03,0x00,0x10 } }, -{ 16, 0xef30, 0, {0xc0,0x00,0x11,0x08,0x00,0xc2,0x43,0x10,0x80,0xc0,0x20,0x01,0x08,0x00,0x02,0x00 } }, -{ 16, 0xef40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xc3,0x0a,0x20,0xc1,0x8c } }, -{ 16, 0xef50, 0, {0x12,0x22,0x04,0x88,0x01,0x36,0x20,0xc3,0x08,0x12,0x28,0x04,0x08,0x01,0x04,0x00 } }, -{ 16, 0xef60, 0, {0x4a,0xa8,0x22,0x01,0x04,0xc8,0x41,0x26,0x30,0xc0,0x88,0x02,0x21,0x00,0x02,0x00 } }, -{ 16, 0xef70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x0a,0x10,0xc1,0x80 } }, -{ 16, 0xef80, 0, {0x32,0x21,0x0c,0x88,0x43,0x02,0x80,0x44,0x80,0x12,0x29,0x04,0x08,0x42,0x0a,0x90 } }, -{ 16, 0xef90, 0, {0x8a,0x80,0x00,0x20,0x04,0x48,0x03,0x0a,0x10,0x82,0x80,0x00,0x20,0x00,0x02,0x00 } }, -{ 16, 0xefa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x87,0x02,0xa1,0x80,0xac } }, -{ 16, 0xefb0, 0, {0x43,0x29,0x14,0x8a,0x84,0x02,0xa1,0x00,0xac,0x41,0x20,0x10,0x08,0x06,0x26,0x31 } }, -{ 16, 0xefc0, 0, {0x80,0xa4,0x60,0x20,0x14,0x4a,0x44,0x32,0x81,0x81,0xac,0x60,0x2a,0x18,0x02,0x00 } }, -{ 16, 0xefd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x07,0x22,0x01,0xc5,0x80 } }, -{ 16, 0xefe0, 0, {0x73,0x21,0x1c,0xc8,0x07,0x2a,0x01,0x0c,0x80,0x72,0x20,0x10,0x48,0x47,0x26,0x11 } }, -{ 16, 0xeff0, 0, {0xc5,0x80,0x73,0x20,0x1c,0x88,0x07,0x2a,0x11,0x49,0x80,0x70,0x20,0x14,0x02,0x00 } }, -{ 16, 0xf000, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x45,0x10,0x31,0xc9,0x0c } }, -{ 16, 0xf010, 0, {0x73,0x02,0x1c,0xc0,0x47,0x04,0x01,0x0a,0x0c,0x51,0x0a,0x10,0x82,0x47,0x20,0x31 } }, -{ 16, 0xf020, 0, {0xc8,0x00,0x72,0x02,0x1c,0x40,0x05,0x30,0x11,0xc4,0x00,0x72,0x01,0x18,0x02,0x00 } }, -{ 16, 0xf030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x10,0x06,0x24,0x01,0x45,0x04 } }, -{ 16, 0xf040, 0, {0x51,0x81,0x18,0x90,0x47,0x14,0x01,0x04,0x04,0x71,0x88,0x10,0x12,0x05,0x34,0x01 } }, -{ 16, 0xf050, 0, {0x44,0x04,0x51,0x40,0x18,0xd0,0x07,0x38,0x01,0xc4,0x04,0x52,0x01,0x14,0xc2,0x04 } }, -{ 16, 0xf060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x00,0x21,0x89,0x0c } }, -{ 16, 0xf070, 0, {0x60,0x01,0x1c,0xd0,0x45,0x24,0x01,0xc1,0x0c,0x42,0x01,0x00,0x00,0xc5,0x20,0x31 } }, -{ 16, 0xf080, 0, {0x41,0x08,0x40,0x00,0x18,0x80,0x45,0x00,0x21,0x41,0x0c,0x70,0x42,0x1c,0xc2,0x00 } }, -{ 16, 0xf090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x1c,0x80,0xc4,0x20 } }, -{ 16, 0xf0a0, 0, {0x31,0x08,0x10,0x42,0x42,0x08,0x80,0xc6,0x20,0x31,0x09,0x00,0x20,0x03,0x1c,0x90 } }, -{ 16, 0xf0b0, 0, {0xc4,0x20,0x01,0x49,0x0c,0x42,0x43,0x10,0x80,0x44,0x20,0x31,0x08,0x10,0x00,0x00 } }, -{ 16, 0xf0c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x83,0x20,0x30,0x48,0x0c } }, -{ 16, 0xf0d0, 0, {0x32,0x40,0x10,0x90,0x81,0x24,0x20,0xc8,0x04,0x32,0x40,0x10,0x20,0xc3,0x20,0x80 } }, -{ 16, 0xf0e0, 0, {0xc8,0x00,0x02,0x4a,0x0c,0xa0,0x01,0x24,0x10,0xc8,0x08,0x32,0x41,0x10,0x00,0x00 } }, -{ 16, 0xf0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x03,0x00,0x00,0xc9,0x04 } }, -{ 16, 0xf100, 0, {0x30,0x40,0x00,0x90,0x00,0x20,0x00,0x80,0x00,0x10,0x40,0x10,0x00,0x40,0x20,0x10 } }, -{ 16, 0xf110, 0, {0xc2,0x00,0x00,0x80,0x08,0x20,0x43,0x08,0x10,0x81,0x00,0x32,0x40,0x0c,0xc0,0x04 } }, -{ 16, 0xf120, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x40,0x00,0x00,0x00 } }, -{ 16, 0xf130, 0, {0x10,0x00,0x00,0xf0,0x10,0x20,0x00,0x00,0x00,0x10,0x00,0x00,0xf0,0x10,0x80,0x40 } }, -{ 16, 0xf140, 0, {0x00,0x00,0x00,0x40,0x00,0xf0,0x10,0x90,0x80,0x00,0x00,0x00,0x00,0x00,0xc0,0x00 } }, -{ 16, 0xf150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x10,0x80,0x90,0x40,0x00,0x00 } }, -{ 16, 0xf160, 0, {0x00,0x80,0x10,0x90,0xa0,0x90,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x80,0x00 } }, -{ 16, 0xf170, 0, {0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x90,0x00,0x00,0x00,0x00,0x40,0x10,0x8f,0x0f } }, -{ 16, 0xf180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xc6,0xba,0x06,0xc0,0x1c } }, -{ 16, 0xf190, 0, {0x49,0x28,0x61,0x14,0x2b,0x1c,0x0e,0x40,0x3f,0xd9,0xbf,0xd9,0xaa,0xbc,0x1a,0x5f } }, -{ 16, 0xf1a0, 0, {0x00,0x10,0xa6,0x50,0x3b,0x61,0xb3,0x25,0xbc,0x40,0x19,0xbf,0xff,0xe9,0x80,0x00 } }, -{ 16, 0xf1b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x92,0x14,0x94,0x80,0x0c } }, -{ 16, 0xf1c0, 0, {0x07,0x3f,0x2b,0x94,0x86,0x14,0x84,0x80,0x28,0x00,0x00,0x49,0x14,0x04,0x86,0x12 } }, -{ 16, 0xf1d0, 0, {0x80,0x00,0x41,0x27,0x34,0xd0,0x90,0x84,0x92,0x00,0x2d,0x8a,0x21,0x1e,0x80,0x00 } }, -{ 16, 0xf1e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xa2 } }, -{ 16, 0xf1f0, 0, {0xb1,0x01,0x01,0x00,0x00,0x00,0x00,0x08,0x84,0xb1,0x78,0x28,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf200, 0, {0x08,0xb1,0x32,0x14,0x14,0x00,0x00,0x00,0x00,0x08,0xa8,0x23,0x54,0x21,0x40,0x00 } }, -{ 16, 0xf210, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf220, 0, {0x00,0x00,0x00,0x2f,0xff,0xfe,0xf7,0xc0,0x00,0x00,0x00,0x00,0x2f,0xd7,0xfe,0xef } }, -{ 16, 0xf230, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf250, 0, {0x00,0x00,0x00,0x0f,0xef,0x77,0xff,0xc0,0x00,0x00,0x00,0x00,0x3e,0xff,0xfe,0xef } }, -{ 16, 0xf260, 0, {0x40,0x00,0x00,0x00,0x00,0x3f,0xff,0xbf,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf280, 0, {0x00,0x00,0x00,0x3f,0xff,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff } }, -{ 16, 0xf290, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0x7f,0x2f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf2a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf2b0, 0, {0x00,0x00,0x00,0x1f,0xff,0xff,0xef,0xc0,0x00,0x00,0x00,0x00,0x1f,0xef,0xef,0xef } }, -{ 16, 0xf2c0, 0, {0xc0,0x00,0x00,0x00,0x00,0x2f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf2d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf2e0, 0, {0x00,0x00,0x00,0x3f,0xff,0xef,0xff,0xc0,0x00,0x00,0x00,0x00,0x2f,0xaf,0xdf,0xff } }, -{ 16, 0xf2f0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xef,0xff,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf310, 0, {0x00,0x00,0x00,0x3f,0xdf,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff } }, -{ 16, 0xf320, 0, {0xc0,0x00,0x00,0x00,0x00,0x1f,0xff,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc4,0x24,0xa1,0x00,0x2c } }, -{ 16, 0xf340, 0, {0x52,0x0b,0x18,0xc2,0x86,0x2c,0xa1,0x80,0x38,0x62,0x0a,0x08,0x40,0xc4,0x2c,0xa1 } }, -{ 16, 0xf350, 0, {0x08,0x28,0x42,0x0b,0x14,0x00,0x85,0x14,0xa1,0x08,0x28,0x43,0x0a,0x10,0x00,0x00 } }, -{ 16, 0xf360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x12,0x01,0x03,0x80 } }, -{ 16, 0xf370, 0, {0x61,0x20,0x10,0x08,0x07,0x12,0x41,0x42,0x80,0x70,0x20,0x1c,0x08,0x04,0x1a,0x01 } }, -{ 16, 0xf380, 0, {0x84,0x81,0x40,0x20,0x18,0x08,0x46,0x36,0x81,0x05,0x80,0x63,0x20,0x10,0x00,0x01 } }, -{ 16, 0xf390, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x24,0x21,0x00,0x0c } }, -{ 16, 0xf3a0, 0, {0x52,0x02,0x14,0x00,0x87,0x28,0x21,0x81,0x08,0x72,0x06,0x1c,0x82,0x84,0x20,0x21 } }, -{ 16, 0xf3b0, 0, {0x48,0x18,0x42,0x03,0x54,0x80,0x45,0x30,0x25,0x4a,0x18,0x53,0x02,0x10,0x00,0x01 } }, -{ 16, 0xf3c0, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x22,0x01,0x01,0x80 } }, -{ 16, 0xf3d0, 0, {0x42,0x20,0x18,0xc8,0x44,0x22,0x01,0x80,0x84,0x42,0x20,0x1c,0x88,0x04,0x22,0x01 } }, -{ 16, 0xf3e0, 0, {0x00,0x80,0x40,0x20,0x10,0x88,0x44,0x36,0x01,0x40,0x80,0x41,0x00,0x10,0x00,0x00 } }, -{ 16, 0xf3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x08,0x20,0x00,0x0c } }, -{ 16, 0xf400, 0, {0x22,0x03,0x04,0x40,0x81,0x00,0x20,0x84,0x08,0x03,0x00,0x00,0x80,0xc2,0x00,0x20 } }, -{ 16, 0xf410, 0, {0xc4,0x08,0x00,0x03,0x08,0x88,0x82,0x16,0xa0,0x40,0x88,0x32,0x22,0x80,0x00,0x00 } }, -{ 16, 0xf420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x01,0x00,0x80,0x04,0x20 } }, -{ 16, 0xf430, 0, {0x10,0x08,0x0c,0xc2,0x12,0x10,0x84,0xc8,0x22,0x12,0x08,0x04,0x02,0x03,0x00,0x88 } }, -{ 16, 0xf440, 0, {0x00,0x21,0x00,0x0c,0x0c,0x40,0x41,0x30,0x00,0x84,0x20,0x10,0x08,0x00,0x02,0x00 } }, -{ 16, 0xf450, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x82,0x06,0x20,0x08,0x8c } }, -{ 16, 0xf460, 0, {0x32,0x22,0x0c,0x88,0x81,0x26,0x20,0x4d,0x88,0x23,0x22,0x80,0x88,0x83,0x06,0x20 } }, -{ 16, 0xf470, 0, {0x08,0x88,0x00,0x23,0x04,0x8a,0x81,0x36,0x20,0x4b,0x88,0x32,0x22,0x00,0x00,0x00 } }, -{ 16, 0xf480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x02,0x02,0x00,0x09,0x80 } }, -{ 16, 0xf490, 0, {0x32,0x20,0x04,0x88,0x60,0x22,0x00,0x89,0x84,0x00,0x20,0x08,0x98,0x00,0x02,0x00 } }, -{ 16, 0xf4a0, 0, {0x00,0x80,0x00,0x20,0x00,0x08,0x02,0x3a,0x80,0x48,0x80,0x30,0x20,0x00,0x02,0x00 } }, -{ 16, 0xf4b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0a,0xc4,0x1a,0xa1,0x80,0xa8 } }, -{ 16, 0xf4c0, 0, {0x41,0x2a,0x10,0xca,0xc7,0x1a,0xa1,0x04,0xad,0x71,0x2a,0x18,0x4a,0xd4,0x06,0xb1 } }, -{ 16, 0xf4d0, 0, {0x00,0xa8,0x71,0x2a,0x10,0x08,0x84,0x26,0x29,0x06,0xac,0x52,0x2a,0x10,0x02,0x00 } }, -{ 16, 0xf4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x2a,0x01,0x41,0x80 } }, -{ 16, 0xf4f0, 0, {0x42,0x20,0x1c,0x00,0x04,0x0a,0x01,0x09,0x84,0x51,0x20,0x1c,0x88,0x44,0x02,0x01 } }, -{ 16, 0xf500, 0, {0x08,0x80,0x40,0x20,0x10,0x4a,0x47,0x02,0x01,0x48,0x80,0x63,0x20,0x10,0x02,0x00 } }, -{ 16, 0xf510, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xc4,0x10,0x21,0x81,0x0c } }, -{ 16, 0xf520, 0, {0x41,0x02,0x0c,0x00,0xc0,0x20,0x61,0x0d,0x0e,0x72,0x02,0x1c,0x40,0xc4,0x08,0x31 } }, -{ 16, 0xf530, 0, {0x04,0x18,0x42,0x02,0x10,0x80,0x87,0x20,0xb1,0xc4,0x0c,0x53,0x02,0x10,0x00,0x00 } }, -{ 16, 0xf540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x20,0x07,0x24,0x01,0xcc,0x00 } }, -{ 16, 0xf550, 0, {0x72,0x40,0x14,0x00,0x04,0x24,0x01,0x08,0x00,0x73,0x41,0x10,0xc0,0x07,0x30,0x11 } }, -{ 16, 0xf560, 0, {0xcc,0x00,0x71,0x01,0x10,0x02,0x04,0x20,0x81,0x46,0x10,0x42,0x40,0x10,0x02,0x04 } }, -{ 16, 0xf570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xc5,0x10,0x21,0x00,0x08 } }, -{ 16, 0xf580, 0, {0x62,0x02,0x1c,0x90,0xc5,0x24,0x21,0x00,0x0c,0x70,0x82,0x1c,0x10,0xc4,0x20,0x31 } }, -{ 16, 0xf590, 0, {0x88,0x02,0x40,0x06,0x1c,0x00,0x85,0x00,0xa1,0x00,0x0c,0x40,0x42,0x00,0x02,0x00 } }, -{ 16, 0xf5a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x05,0x14,0x80,0x01,0x20 } }, -{ 16, 0xf5b0, 0, {0x30,0x08,0x0c,0x42,0x06,0x00,0x80,0x01,0x24,0x51,0x08,0x0c,0x02,0x41,0x00,0x80 } }, -{ 16, 0xf5c0, 0, {0x4c,0x20,0x00,0x08,0x0c,0x30,0x42,0x04,0x00,0x04,0x20,0x00,0x08,0x00,0x00,0x00 } }, -{ 16, 0xf5d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xc6,0x24,0x20,0x00,0x0c } }, -{ 16, 0xf5e0, 0, {0x32,0xc2,0x04,0x80,0xc7,0x30,0x20,0x00,0x0c,0x53,0xc2,0x04,0x10,0xc2,0x28,0x70 } }, -{ 16, 0xf5f0, 0, {0x0c,0x09,0x02,0x02,0x4c,0x80,0x81,0x04,0x30,0x09,0x0c,0x02,0x42,0x10,0x00,0x00 } }, -{ 16, 0xf600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x80,0x01,0x38,0x00,0x02,0x00 } }, -{ 16, 0xf610, 0, {0x12,0x40,0x0c,0x20,0x07,0x34,0x04,0x02,0x00,0x63,0x01,0x08,0x10,0x00,0x24,0x10 } }, -{ 16, 0xf620, 0, {0x04,0x00,0x02,0x01,0x04,0x82,0x01,0x08,0x80,0x09,0x10,0x02,0x40,0x10,0x00,0x04 } }, -{ 16, 0xf630, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x20,0x10,0x80,0x00,0x00 } }, -{ 16, 0xf640, 0, {0x20,0x80,0x00,0xf0,0x20,0x10,0x80,0x00,0x00,0x20,0x80,0x00,0xd0,0x80,0x00,0x00 } }, -{ 16, 0xf650, 0, {0x40,0x00,0x00,0x00,0x00,0x30,0x10,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0xcc,0x40 } }, -{ 16, 0xf660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x10,0x80,0x80,0x00,0x00,0x00 } }, -{ 16, 0xf670, 0, {0x00,0x00,0x10,0x90,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x00,0x90 } }, -{ 16, 0xf680, 0, {0x80,0x00,0x10,0x00,0x00,0x10,0xa0,0x80,0x00,0x00,0x00,0x20,0x00,0x10,0x8c,0x08 } }, -{ 16, 0xf690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x1a,0xbe,0x17,0x80,0x00 } }, -{ 16, 0xf6a0, 0, {0x3e,0x40,0x26,0x6f,0xba,0xe3,0x24,0x80,0x00,0x16,0x59,0xbd,0x82,0x81,0x82,0xd8 } }, -{ 16, 0xf6b0, 0, {0x80,0x00,0x00,0x19,0x99,0x86,0x80,0x64,0x80,0xc0,0x3f,0xd9,0x99,0x80,0x00,0x01 } }, -{ 16, 0xf6c0, 0, {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x16,0x02,0x94,0x00,0x16 } }, -{ 16, 0xf6d0, 0, {0xc0,0x16,0x94,0x82,0x90,0x16,0x10,0x80,0x21,0x18,0x28,0x28,0x02,0x0a,0x02,0x08 } }, -{ 16, 0xf6e0, 0, {0x80,0x00,0x00,0x00,0x00,0x02,0x82,0x80,0x14,0x00,0x01,0x14,0x11,0xa0,0x40,0x00 } }, -{ 16, 0xf6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x84 } }, -{ 16, 0xf700, 0, {0x02,0x84,0xa8,0x80,0x00,0x00,0x00,0x08,0x91,0x22,0x84,0x41,0xa2,0x08,0x24,0x01 } }, -{ 16, 0xf710, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x84,0x01,0x44,0x01,0x00,0x00 } }, -{ 16, 0xf720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf730, 0, {0x00,0x00,0x00,0x3e,0xf7,0xff,0xf7,0xc0,0x00,0x00,0x00,0x00,0x2f,0xe7,0xb7,0xff } }, -{ 16, 0xf740, 0, {0xc0,0x00,0x00,0x00,0x00,0x2f,0xfe,0x7f,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf760, 0, {0x00,0x00,0x00,0x36,0xbf,0xfe,0xdf,0xc0,0x00,0x00,0x00,0x00,0x0f,0xf7,0xdf,0xff } }, -{ 16, 0xf770, 0, {0xc0,0x00,0x00,0x00,0x00,0x3d,0xb7,0xb7,0xef,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf790, 0, {0x00,0x00,0x00,0x1f,0xdf,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x0f,0xdf,0xdf,0xff } }, -{ 16, 0xf7a0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xef,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf7c0, 0, {0x00,0x00,0x00,0x3f,0xbf,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0x7f,0xf7 } }, -{ 16, 0xf7d0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xdf,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf7f0, 0, {0x00,0x00,0x00,0x3f,0x7e,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x3f,0xfe,0xff,0xff } }, -{ 16, 0xf800, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 } }, -{ 16, 0xf820, 0, {0x00,0x00,0x00,0x37,0xff,0x6f,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff } }, -{ 16, 0xf830, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x20,0x01,0x02,0x00,0x00,0x00 } }, -{ 16, 0xf880, 0, {0x30,0x00,0x43,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf8a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf8c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf8d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x00,0x00,0x00,0x00,0x30 } }, -{ 16, 0xf900, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x00 } }, -{ 16, 0xf960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x30,0xc0,0x30 } }, -{ 16, 0xf9c0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xf9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x0f } }, -{ 16, 0xfa20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x3f } }, -{ 16, 0xfa80, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfa90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfad0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x30,0xc0,0x30,0xc0,0x0f } }, -{ 16, 0xfae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x6b,0x00,0xc0,0x00,0xcf,0x2c } }, -{ 16, 0xfb40, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfb90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x00 } }, -{ 16, 0xfba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfbb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfbc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfbd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfbe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfbf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x0f,0x00,0x0f,0x00,0x30 } }, -{ 16, 0xfc00, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x3f,0xc0,0x00 } }, -{ 16, 0xfc60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfc90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfcb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x3f,0xc0,0x3f,0xc0,0x30 } }, -{ 16, 0xfcc0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfcd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfcf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f } }, -{ 16, 0xfd20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x0f,0x00,0x0f,0x00,0x3f } }, -{ 16, 0xfd80, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfd90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfda0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfdb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfdc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfdd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x3f,0xc0,0x3f,0xc0,0x0f } }, -{ 16, 0xfde0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfdf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x33,0x5d,0x80,0xc0,0x00,0xfd,0xac } }, -{ 16, 0xfe40, 0, {0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfe90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfea0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfeb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfec0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfed0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x00,0x00,0x00,0x00,0x30 } }, -{ 16, 0xff00, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x00 } }, -{ 16, 0xff60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xff90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xffa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xffb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x30,0xc0,0x30,0xc0,0x30 } }, -{ 16, 0xffc0, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xffd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xffe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0xfff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8020, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x0f } }, -{ 16, 0x8030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8050, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x00,0x00,0x00,0x00,0x3f } }, -{ 16, 0x8090, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x80e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x30,0xc0,0x30,0xc0,0x0f } }, -{ 16, 0x80f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x74,0xc0,0xc0,0x00,0xf0,0xec } }, -{ 16, 0x8150, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x81a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x00 } }, -{ 16, 0x81b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x81c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x81d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x81e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x81f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xc0,0x0f,0x00,0x0f,0x00,0x30 } }, -{ 16, 0x8210, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x3f,0xc0,0x00 } }, -{ 16, 0x8270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8290, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x82a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x82b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x82c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x86,0x10,0x80,0x30,0x82,0x3d } }, -{ 16, 0x82d0, 0, {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x82e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x82f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8320, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f } }, -{ 16, 0x8330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x0f,0x00,0x0f,0x00,0x3f } }, -{ 16, 0x8390, 0, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x83a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x83b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x83c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x83d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x83e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x3f,0xc0,0x3f,0xc0,0x0f } }, -{ 16, 0x83f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8440, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x65,0x25,0xe4,0x80,0x00,0xb0,0x88 } }, -{ 16, 0x8450, 0, {0xab,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x84a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x84b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x84c0, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x20,0x01,0x02,0x02,0x00,0x00,0x30,0x00,0x43,0x00 } }, -{ 16, 0x84d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x84e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x84f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8510, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8530, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8590, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x85a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x85b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x85c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x85d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x85e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x85f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8630, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8650, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8680, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x86a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x86b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x86c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x86d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x86e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x86f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8710, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8730, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x87a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x87b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x87c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x87d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x87e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x87f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x88a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x88b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x88c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x88d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x88e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x88f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x89a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x89b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x89c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x89d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x89e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x89f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8a90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8aa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ad0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8af0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8b90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8bb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8bc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8bd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8be0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8bf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8c90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8cb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8cc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8cd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8cf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8d90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8da0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8db0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8dc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8dd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8de0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8df0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8e90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ea0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8eb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ec0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ed0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8f90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8fa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8fb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8fc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8fd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8fe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x8ff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9000, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9020, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9050, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x90a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x90b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x90c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x90d0, 0, {0x30,0x00,0x00,0x01,0x00,0x00,0x44,0x72,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x03 } }, -{ 16, 0x90e0, 0, {0x30,0x00,0x40,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x90f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 16, 0x9110, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x05,0x30,0x00,0xa0,0x01 } }, -{ 16, 0x9120, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x01,0x00,0x00,0xe1,0x5a,0x00,0x00,0x00,0x00 } }, -{ 12, 0x9130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } }, -{ 0 , 0x0000, 1, {0 }} -}; -// VERSION=1.1.1.131 -// DATE=2001dec06 -// PRODUCT=EMI 2|6 -/* - * This firmware is for the Emagic EMI 2|6 Audio Interface - * - * The firmware contained herein is Copyright (c) 1999-2002 Emagic - * as an unpublished work. This notice does not imply unrestricted - * or public access to this firmware which is a trade secret of Emagic, - * and which may not be reproduced, used, sold or transferred to - * any third party without Emagic's written consent. All Rights Reserved. - * - * This firmware may not be modified and may only be used with the - * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of - * any driver which includes this firmware, in whole or in part, - * requires the inclusion of this statement. - */ -static INTEL_HEX_RECORD g_Firmware[] = { -{ 3,0x0000,0,{0x02,0x43,0x56} }, -{ 3,0x0003,0,{0x02,0x4b,0xcd} }, -{ 3,0x000b,0,{0x02,0x4b,0xd2} }, -{ 3,0x0013,0,{0x02,0x4b,0x92} }, -{ 3,0x001b,0,{0x02,0x4b,0xd5} }, -{ 3,0x0023,0,{0x02,0x1b,0x39} }, -{ 3,0x002b,0,{0x02,0x43,0xe2} }, -{ 3,0x0033,0,{0x02,0x3f,0xf3} }, -{ 3,0x003b,0,{0x02,0x4b,0xc0} }, -{ 3,0x0043,0,{0x02,0x47,0x00} }, -{ 3,0x004b,0,{0x02,0x3f,0xfc} }, -{ 3,0x0053,0,{0x02,0x37,0xfa} }, -{ 3,0x005b,0,{0x02,0x4b,0xc7} }, -{ 3,0x0063,0,{0x02,0x46,0xfc} }, -{ 16,0x0500,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x01,0x01,0x00,0x01,0x01,0x02} }, -{ 16,0x0510,0,{0x00,0x01,0x09,0x02,0xb8,0x01,0x03,0x01,0x00,0x80,0xa0,0x09,0x04,0x00,0x00,0x00} }, -{ 16,0x0520,0,{0x01,0x01,0x00,0x00,0x0a,0x24,0x01,0x00,0x01,0x56,0x00,0x02,0x01,0x02,0x0c,0x24} }, -{ 16,0x0530,0,{0x02,0x01,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x15,0x24,0x06,0x05,0x01,0x02} }, -{ 16,0x0540,0,{0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09} }, -{ 16,0x0550,0,{0x24,0x03,0x02,0x04,0x03,0x00,0x05,0x00,0x0c,0x24,0x02,0x03,0x01,0x02,0x00,0x02} }, -{ 16,0x0560,0,{0x00,0x00,0x00,0x00,0x0d,0x24,0x06,0x06,0x03,0x02,0x03,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x0570,0,{0x00,0x09,0x24,0x03,0x04,0x01,0x01,0x00,0x06,0x00,0x09,0x04,0x01,0x00,0x00,0x01} }, -{ 16,0x0580,0,{0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01} }, -{ 16,0x0590,0,{0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x02,0x10,0x03,0x44,0xac,0x00,0x80,0xbb} }, -{ 16,0x05a0,0,{0x00,0x00,0x77,0x01,0x09,0x05,0x0a,0x05,0x84,0x01,0x01,0x00,0x8f,0x07,0x25,0x01} }, -{ 16,0x05b0,0,{0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x06,0x00,0x09,0x04,0x01} }, -{ 16,0x05c0,0,{0x02,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01,0x00,0x01,0x00,0x0e,0x24,0x02} }, -{ 16,0x05d0,0,{0x01,0x06,0x02,0x10,0x02,0x44,0xac,0x00,0x80,0xbb,0x00,0x09,0x05,0x0a,0x05,0x4c} }, -{ 16,0x05e0,0,{0x02,0x01,0x00,0x8f,0x07,0x25,0x01,0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03} }, -{ 16,0x05f0,0,{0x00,0x01,0x06,0x00,0x09,0x04,0x01,0x03,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01} }, -{ 16,0x0600,0,{0x01,0x00,0x01,0x00,0x0e,0x24,0x02,0x01,0x06,0x03,0x18,0x02,0x44,0xac,0x00,0x80} }, -{ 16,0x0610,0,{0xbb,0x00,0x09,0x05,0x0a,0x05,0x72,0x03,0x01,0x00,0x8f,0x07,0x25,0x01,0x01,0x00} }, -{ 16,0x0620,0,{0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x06,0x00,0x09,0x04,0x01,0x04,0x02} }, -{ 16,0x0630,0,{0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01,0x00,0x01,0x00,0x0b,0x24,0x02,0x01,0x02} }, -{ 16,0x0640,0,{0x03,0x18,0x01,0x00,0x77,0x01,0x09,0x05,0x0a,0x05,0x46,0x02,0x01,0x00,0x8f,0x07} }, -{ 16,0x0650,0,{0x25,0x01,0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x06,0x00,0x09} }, -{ 16,0x0660,0,{0x04,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x09,0x04,0x02,0x01,0x01,0x01,0x02,0x00} }, -{ 16,0x0670,0,{0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x02,0x10,0x03} }, -{ 16,0x0680,0,{0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05,0x8c,0x05,0x84,0x01,0x01} }, -{ 16,0x0690,0,{0x00,0x00,0x07,0x25,0x01,0x01,0x02,0x00,0x00,0x09,0x04,0x02,0x02,0x01,0x01,0x02} }, -{ 16,0x06a0,0,{0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x03,0x18} }, -{ 16,0x06b0,0,{0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05,0x8c,0x05,0x46,0x02} }, -{ 16,0x06c0,0,{0x01,0x00,0x00,0x07,0x25,0x01,0x01,0x02,0x00,0x00,0x05,0x0c,0x09,0x01,0xa1,0x01} }, -{ 16,0x06d0,0,{0x05,0x0c,0x09,0xe9,0x05,0x0c,0x09,0xea,0x15,0x00,0x25,0x01,0x95,0x02,0x75,0x01} }, -{ 16,0x06e0,0,{0x81,0x42,0x95,0x01,0x75,0x06,0x81,0x01,0x05,0x0c,0x09,0x00,0x05,0x0c,0x09,0x00} }, -{ 16,0x06f0,0,{0x15,0x00,0x25,0x01,0x95,0x02,0x75,0x01,0x91,0x06,0x95,0x01,0x75,0x06,0x91,0x03} }, -{ 16,0x0700,0,{0xc0,0x04,0x03,0x09,0x04,0x18,0x03,0x45,0x00,0x4d,0x00,0x41,0x00,0x47,0x00,0x49} }, -{ 16,0x0710,0,{0x00,0x43,0x00,0x20,0x00,0x47,0x00,0x6d,0x00,0x62,0x00,0x48,0x00,0x1e,0x03,0x45} }, -{ 16,0x0720,0,{0x00,0x6d,0x00,0x61,0x00,0x67,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x45,0x00,0x4d} }, -{ 16,0x0730,0,{0x00,0x49,0x00,0x20,0x00,0x32,0x00,0x7c,0x00,0x36,0x00,0x2a,0x03,0x43,0x00,0x6f} }, -{ 16,0x0740,0,{0x00,0x6e,0x00,0x66,0x00,0x69,0x00,0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74} }, -{ 16,0x0750,0,{0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69} }, -{ 16,0x0760,0,{0x00,0x6e,0x00,0x67,0x00,0x22,0x03,0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72} }, -{ 16,0x0770,0,{0x00,0x66,0x00,0x61,0x00,0x63,0x00,0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72} }, -{ 9,0x0780,0,{0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x00,0x00} }, -{ 16,0x0789,0,{0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} }, -{ 1,0x0799,0,{0x22} }, -{ 16,0x079a,0,{0x90,0x7f,0xd6,0xe0,0x44,0x80,0xf0,0x43,0x87,0x01,0x00,0x00,0x00,0x00,0x00,0x22} }, -{ 16,0x07aa,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0x8d,0xe0,0xc0,0xe0} }, -{ 16,0x07ba,0,{0x8c,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x05,0x86,0xc0,0x84,0xc0,0x85,0xe5,0x18} }, -{ 16,0x07ca,0,{0xb4,0x02,0x03,0x02,0x07,0xd9,0xb4,0x01,0x03,0x02,0x07,0xde,0x02,0x07,0xfa,0x7d} }, -{ 16,0x07da,0,{0x01,0x02,0x08,0x16,0xe5,0x19,0x14,0xf5,0x19,0xc3,0xb5,0x13,0x03,0x02,0x07,0xf5} }, -{ 16,0x07ea,0,{0x50,0x09,0xb4,0x00,0xea,0x75,0x19,0x0a,0x02,0x07,0xd9,0x7d,0x00,0x02,0x08,0x16} }, -{ 16,0x07fa,0,{0xe5,0x19,0x14,0xf5,0x19,0xc3,0xb5,0x14,0x03,0x02,0x08,0x11,0x50,0x09,0xb4,0x00} }, -{ 16,0x080a,0,{0xce,0x75,0x19,0x0a,0x02,0x07,0xd9,0x7d,0x02,0x02,0x08,0x16,0x7c,0x05,0x90,0x7f} }, -{ 16,0x081a,0,{0x99,0xe0,0x54,0x40,0xdc,0x03,0x02,0x08,0x43,0xb4,0x00,0x1d,0x90,0x7f,0xe3,0x74} }, -{ 16,0x082a,0,{0x7b,0xf0,0xa3,0x74,0x80,0xf0,0x90,0x7f,0xe2,0x74,0x40,0xf0,0x90,0x7f,0xe5,0xf0} }, -{ 16,0x083a,0,{0x90,0x7f,0xe2,0x74,0x00,0xf0,0x02,0x08,0x18,0x05,0x86,0x90,0x7f,0xe2,0x74,0x80} }, -{ 16,0x084a,0,{0xf0,0x90,0x79,0x65,0xe0,0xb4,0x01,0x03,0x02,0x08,0x9e,0xb4,0x02,0x03,0x02,0x08} }, -{ 16,0x085a,0,{0x96,0xb4,0x03,0x03,0x02,0x08,0x8e,0xb4,0x04,0x03,0x02,0x08,0x86,0xb4,0x05,0x03} }, -{ 16,0x086a,0,{0x02,0x08,0x7e,0xb4,0x06,0x03,0x02,0x08,0x76,0x02,0x08,0xf4,0x05,0x86,0x90,0x7f} }, -{ 16,0x087a,0,{0x6c,0x02,0x08,0xe9,0x05,0x86,0x90,0x7f,0x6c,0x02,0x08,0xdd,0x05,0x86,0x90,0x7f} }, -{ 16,0x088a,0,{0x6c,0x02,0x08,0xcf,0x05,0x86,0x90,0x7f,0x6c,0x02,0x08,0xc0,0x05,0x86,0x90,0x7f} }, -{ 16,0x089a,0,{0x6c,0x02,0x08,0xb2,0x05,0x86,0x90,0x7f,0x6c,0xf0,0x00,0xf0,0x00,0xf0,0x00,0xf0} }, -{ 16,0x08aa,0,{0x0d,0xed,0xb4,0x2d,0xf4,0x02,0x08,0xf4,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0d,0xed} }, -{ 16,0x08ba,0,{0xb4,0x2d,0xf5,0x02,0x08,0xf4,0xf0,0x00,0xf0,0x00,0xf0,0x00,0xf0,0x0d,0xed,0xb4} }, -{ 16,0x08ca,0,{0x31,0xf4,0x02,0x08,0xf4,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0d,0xed,0xb4,0x31,0xf5} }, -{ 16,0x08da,0,{0x02,0x08,0xf4,0xf0,0xf0,0xf0,0xf0,0x0d,0xed,0xb4,0x61,0xf7,0x02,0x08,0xf4,0xf0} }, -{ 16,0x08ea,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0x0d,0xed,0xb4,0x61,0xf5,0x90,0x7f,0xe2,0x74,0x00,0xf0} }, -{ 16,0x08fa,0,{0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xfc,0xd0,0xe0,0xfd} }, -{ 5,0x090a,0,{0xd0,0xe0,0xfe,0xd0,0xe0} }, -{ 6,0x090f,0,{0xff,0xd0,0xe0,0xd0,0xd0,0x22} }, -{ 16,0x0915,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x90,0x7f,0x6f,0xe5,0x0c,0xf0,0xe5,0x0d} }, -{ 13,0x0925,0,{0xf0,0xe5,0x0e,0xf0,0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xd0,0xd0,0x22} }, -{ 16,0x0932,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83} }, -{ 16,0x0942,0,{0x05,0x86,0xc0,0x84,0xc0,0x85,0x90,0x79,0x70,0xe0,0xff,0xbf,0x00,0x03,0x02,0x0a} }, -{ 16,0x0952,0,{0xb8,0x90,0x7f,0x96,0xe0,0x44,0x80,0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f} }, -{ 16,0x0962,0,{0x62,0xe0,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x96,0xe0,0x54,0x7f} }, -{ 16,0x0972,0,{0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x79,0x88,0xe0,0xb4,0x01,0x03,0x02,0x09} }, -{ 16,0x0982,0,{0xbe,0xb4,0x02,0x03,0x02,0x09,0xc3,0xb4,0x03,0x03,0x02,0x09,0xac,0xb4,0x04,0x03} }, -{ 16,0x0992,0,{0x02,0x09,0x9a,0x05,0x86,0x02,0x0a,0xb2,0xef,0x54,0x03,0xfe,0xef,0x03,0x03,0x54} }, -{ 16,0x09a2,0,{0x3f,0xff,0x90,0x7f,0x63,0x05,0x86,0x02,0x09,0xc9,0xef,0x54,0x03,0xfe,0xef,0x03} }, -{ 16,0x09b2,0,{0x03,0x54,0x3f,0xff,0x90,0x7f,0x63,0x05,0x86,0x02,0x0a,0x36,0x05,0x86,0x02,0x0a} }, -{ 16,0x09c2,0,{0xa5,0x05,0x86,0x02,0x0a,0x8e,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0} }, -{ 16,0x09d2,0,{0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86} }, -{ 16,0x09e2,0,{0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0} }, -{ 16,0x09f2,0,{0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86,0xdf,0xca,0xee,0xb4,0x00,0x03} }, -{ 16,0x0a02,0,{0x02,0x0a,0xb2,0xb4,0x01,0x03,0x02,0x0a,0x25,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05} }, -{ 16,0x0a12,0,{0x86,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0} }, -{ 16,0x0a22,0,{0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0x05,0x86} }, -{ 16,0x0a32,0,{0x02,0x0a,0xb2,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0} }, -{ 13,0x0a42,0,{0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86} }, -{ 16,0x0a4f,0,{0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xdf,0xd6} }, -{ 16,0x0a5f,0,{0xee,0xb4,0x00,0x03,0x02,0x0a,0xb2,0xb4,0x01,0x03,0x02,0x0a,0x80,0xe0,0xe0,0xe0} }, -{ 16,0x0a6f,0,{0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05} }, -{ 16,0x0a7f,0,{0x86,0xe0,0xe0,0xe0,0xe0,0x05,0x86,0xe0,0xe0,0x05,0x86,0x02,0x0a,0xb2,0xe0,0xe0} }, -{ 16,0x0a8f,0,{0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0} }, -{ 16,0x0a9f,0,{0xdf,0xec,0x02,0x0a,0xb2,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0} }, -{ 16,0x0aaf,0,{0xe0,0xdf,0xf2,0x90,0x7f,0xe2,0x74,0x00,0xf0,0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0} }, -{ 14,0x0abf,0,{0x83,0xd0,0x82,0xd0,0xe0,0xfe,0xd0,0xe0,0xff,0xd0,0xe0,0xd0,0xd0,0x22} }, -{ 16,0x0acd,0,{0xc0,0x82,0xc0,0x83,0xc0,0xe0,0xe8,0xc0,0xe0,0x78,0xd1,0xe8,0x14,0xf8,0x70,0xfb} }, -{ 10,0x0add,0,{0xd0,0xe0,0xf8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0x22} }, -{ 16,0x0ae7,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0x8d,0xe0,0xc0,0xe0} }, -{ 16,0x0af7,0,{0x8c,0xe0,0xc0,0xe0,0x75,0x86,0x00,0xc0,0x82,0xc0,0x83,0x05,0x86,0xc0,0x84,0xc0} }, -{ 16,0x0b07,0,{0x85,0x7e,0x00,0x90,0x79,0x8e,0xe0,0xb4,0x00,0x16,0x74,0x01,0xf0,0x90,0x06,0xca} }, -{ 16,0x0b17,0,{0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xe0,0xff,0x90,0x79,0x8d,0xf0,0x02,0x0b,0x39} }, -{ 16,0x0b27,0,{0x90,0x79,0x8d,0xe0,0xff,0x90,0x79,0x8f,0xe0,0xfd,0x90,0x79,0x90,0xe0,0xfc,0x02} }, -{ 16,0x0b37,0,{0x0b,0x46,0x90,0x06,0xca,0x05,0x86,0x90,0x7f,0x00,0x05,0x86,0x02,0x0b,0x51,0x8d} }, -{ 16,0x0b47,0,{0x84,0x8c,0x85,0x05,0x86,0x90,0x7f,0x00,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xa3} }, -{ 16,0x0b57,0,{0x0e,0xee,0xb4,0x40,0x03,0x02,0x0b,0x6c,0x05,0x86,0xdf,0xee,0x90,0x79,0x8e,0x74} }, -{ 16,0x0b67,0,{0x00,0xf0,0x02,0x0b,0x82,0x05,0x86,0xad,0x84,0xac,0x85,0x90,0x79,0x8f,0xed,0xf0} }, -{ 16,0x0b77,0,{0x90,0x79,0x90,0xec,0xf0,0x90,0x79,0x8d,0x1f,0xef,0xf0,0x90,0x7f,0xb5,0xee,0xf0} }, -{ 16,0x0b87,0,{0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xfc,0xd0,0xe0,0xfd} }, -{ 11,0x0b97,0,{0xd0,0xe0,0xfe,0xd0,0xe0,0xff,0xd0,0xe0,0xd0,0xd0,0x22} }, -{ 16,0x0ba2,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x90,0x7f,0xae,0xe0,0x54,0xe0,0xf0,0x90} }, -{ 16,0x0bb2,0,{0x7f,0x96,0xe0,0x44,0x08,0x54,0xfb,0xf0,0x90,0x7f,0x97,0xe0,0x54,0xbf,0xf0,0x90} }, -{ 16,0x0bc2,0,{0x7f,0xe3,0x74,0x7b,0xf0,0x90,0x7f,0xe4,0x74,0x40,0xf0,0x90,0x79,0x78,0xe0,0x90} }, -{ 16,0x0bd2,0,{0x7b,0x40,0xf0,0x90,0x7f,0xe2,0x74,0x48,0xf0,0x90,0x7f,0xe5,0xe0,0x90,0x7f,0xe2} }, -{ 16,0x0be2,0,{0x74,0x00,0xf0,0x90,0x7f,0x96,0xe0,0x54,0xf7,0x44,0x04,0xf0,0x90,0x7f,0xe3,0x74} }, -{ 16,0x0bf2,0,{0x7b,0xf0,0x90,0x7f,0xe4,0x74,0x40,0xf0,0x90,0x79,0x79,0xe0,0x90,0x7b,0x40,0xf0} }, -{ 16,0x0c02,0,{0x90,0x7f,0xe2,0x74,0x48,0xf0,0x90,0x7f,0xe5,0xe0,0x90,0x7f,0xe2,0x74,0x00,0xf0} }, -{ 16,0x0c12,0,{0x90,0x7f,0x96,0xe0,0x54,0xf3,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x1f,0xf0,0xd0,0x83} }, -{ 7,0x0c22,0,{0xd0,0x82,0xd0,0xe0,0xd0,0xd0,0x22} }, -{ 16,0x0c29,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x79,0x2f,0xe0,0x64,0xff,0xc3,0x24} }, -{ 11,0x0c39,0,{0x01,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0xd0,0xd0,0x22} }, -{ 16,0x0c44,0,{0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xe0,0x22,0x50,0x02,0xe7,0x22,0xbb,0xfe,0x02} }, -{ 9,0x0c54,0,{0xe3,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0x22} }, -{ 16,0x0c5d,0,{0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50} }, -{ 16,0x0c6d,0,{0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22} }, -{ 13,0x0c7d,0,{0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22} }, -{ 16,0x0c8a,0,{0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01} }, -{ 2,0x0c9a,0,{0xf3,0x22} }, -{ 16,0x0c9c,0,{0xf8,0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0} }, -{ 16,0x0cac,0,{0x22,0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8} }, -{ 2,0x0cbc,0,{0xf2,0x22} }, -{ 16,0x0cbe,0,{0xc2,0xd5,0xec,0x30,0xe7,0x09,0xb2,0xd5,0xe4,0xc3,0x9d,0xfd,0xe4,0x9c,0xfc,0xee} }, -{ 16,0x0cce,0,{0x30,0xe7,0x15,0xb2,0xd5,0xe4,0xc3,0x9f,0xff,0xe4,0x9e,0xfe,0x12,0x0e,0x40,0xc3} }, -{ 16,0x0cde,0,{0xe4,0x9d,0xfd,0xe4,0x9c,0xfc,0x80,0x03,0x12,0x0e,0x40,0x30,0xd5,0x07,0xc3,0xe4} }, -{ 6,0x0cee,0,{0x9f,0xff,0xe4,0x9e,0xfe,0x22} }, -{ 16,0x0cf4,0,{0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70,0x02} }, -{ 6,0x0d04,0,{0x15,0x83,0xe0,0x38,0xf0,0x22} }, -{ 16,0x0d0a,0,{0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0} }, -{ 16,0x0d1a,0,{0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe} }, -{ 16,0x0d2a,0,{0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83} }, -{ 8,0x0d3a,0,{0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22} }, -{ 16,0x0d42,0,{0xe8,0x8f,0xf0,0xa4,0xcc,0x8b,0xf0,0xa4,0x2c,0xfc,0xe9,0x8e,0xf0,0xa4,0x2c,0xfc} }, -{ 16,0x0d52,0,{0x8a,0xf0,0xed,0xa4,0x2c,0xfc,0xea,0x8e,0xf0,0xa4,0xcd,0xa8,0xf0,0x8b,0xf0,0xa4} }, -{ 16,0x0d62,0,{0x2d,0xcc,0x38,0x25,0xf0,0xfd,0xe9,0x8f,0xf0,0xa4,0x2c,0xcd,0x35,0xf0,0xfc,0xeb} }, -{ 16,0x0d72,0,{0x8e,0xf0,0xa4,0xfe,0xa9,0xf0,0xeb,0x8f,0xf0,0xa4,0xcf,0xc5,0xf0,0x2e,0xcd,0x39} }, -{ 15,0x0d82,0,{0xfe,0xe4,0x3c,0xfc,0xea,0xa4,0x2d,0xce,0x35,0xf0,0xfd,0xe4,0x3c,0xfc,0x22} }, -{ 16,0x0d91,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0} }, -{ 1,0x0da1,0,{0x22} }, -{ 16,0x0da2,0,{0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0e,0xa1} }, -{ 16,0x0db2,0,{0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x0e,0x95,0xbb,0xfe,0x07,0xe9,0x25,0x82,0xf8} }, -{ 16,0x0dc2,0,{0x02,0x0e,0xad,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0e,0xb9} }, -{ 16,0x0dd2,0,{0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0e,0xd5} }, -{ 16,0x0de2,0,{0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x0e,0xc9,0xbb,0xfe,0x07,0xe9,0x25,0x82,0xf8} }, -{ 4,0x0df2,0,{0x02,0x0e,0xe1,0x22} }, -{ 16,0x0df6,0,{0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x0f,0x06} }, -{ 16,0x0e06,0,{0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x0e,0xed,0xbb,0xfe,0x07,0xe9,0x25,0x82,0xf8} }, -{ 4,0x0e16,0,{0x02,0x0f,0x37,0x22} }, -{ 16,0x0e1a,0,{0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3} }, -{ 16,0x0e2a,0,{0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60} }, -{ 6,0x0e3a,0,{0xef,0xa3,0xa3,0xa3,0x80,0xdf} }, -{ 16,0x0e40,0,{0xbc,0x00,0x0b,0xbe,0x00,0x29,0xef,0x8d,0xf0,0x84,0xff,0xad,0xf0,0x22,0xe4,0xcc} }, -{ 16,0x0e50,0,{0xf8,0x75,0xf0,0x08,0xef,0x2f,0xff,0xee,0x33,0xfe,0xec,0x33,0xfc,0xee,0x9d,0xec} }, -{ 16,0x0e60,0,{0x98,0x40,0x05,0xfc,0xee,0x9d,0xfe,0x0f,0xd5,0xf0,0xe9,0xe4,0xce,0xfd,0x22,0xed} }, -{ 16,0x0e70,0,{0xf8,0xf5,0xf0,0xee,0x84,0x20,0xd2,0x1c,0xfe,0xad,0xf0,0x75,0xf0,0x08,0xef,0x2f} }, -{ 16,0x0e80,0,{0xff,0xed,0x33,0xfd,0x40,0x07,0x98,0x50,0x06,0xd5,0xf0,0xf2,0x22,0xc3,0x98,0xfd} }, -{ 5,0x0e90,0,{0x0f,0xd5,0xf0,0xea,0x22} }, -{ 12,0x0e95,0,{0xe6,0xfc,0x08,0xe6,0xfd,0x08,0xe6,0xfe,0x08,0xe6,0xff,0x22} }, -{ 12,0x0ea1,0,{0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22} }, -{ 12,0x0ead,0,{0xe2,0xfc,0x08,0xe2,0xfd,0x08,0xe2,0xfe,0x08,0xe2,0xff,0x22} }, -{ 16,0x0eb9,0,{0xe4,0x93,0xfc,0xa3,0xe4,0x93,0xfd,0xa3,0xe4,0x93,0xfe,0xa3,0xe4,0x93,0xff,0x22} }, -{ 12,0x0ec9,0,{0xec,0xf6,0x08,0xed,0xf6,0x08,0xee,0xf6,0x08,0xef,0xf6,0x22} }, -{ 12,0x0ed5,0,{0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x22} }, -{ 12,0x0ee1,0,{0xec,0xf2,0x08,0xed,0xf2,0x08,0xee,0xf2,0x08,0xef,0xf2,0x22} }, -{ 16,0x0eed,0,{0xd0,0x83,0xd0,0x82,0xe4,0x93,0xf6,0x08,0x74,0x01,0x93,0xf6,0x08,0x74,0x02,0x93} }, -{ 9,0x0efd,0,{0xf6,0x08,0x74,0x03,0x93,0xf6,0x74,0x04,0x73} }, -{ 16,0x0f06,0,{0xa8,0x82,0x85,0x83,0xf0,0xd0,0x83,0xd0,0x82,0x12,0x0f,0x1d,0x12,0x0f,0x1d,0x12} }, -{ 16,0x0f16,0,{0x0f,0x1d,0x12,0x0f,0x1d,0xe4,0x73,0xe4,0x93,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83} }, -{ 16,0x0f26,0,{0xc8,0xc5,0x82,0xc8,0xf0,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83,0xc8,0xc5,0x82,0xc8} }, -{ 1,0x0f36,0,{0x22} }, -{ 16,0x0f37,0,{0xd0,0x83,0xd0,0x82,0xe4,0x93,0xf2,0x08,0x74,0x01,0x93,0xf2,0x08,0x74,0x02,0x93} }, -{ 9,0x0f47,0,{0xf2,0x08,0x74,0x03,0x93,0xf2,0x74,0x04,0x73} }, -{ 16,0x0f50,0,{0xc2,0xaf,0xd2,0x2c,0x90,0x7f,0x93,0x74,0x30,0xf0,0x90,0x7f,0x9c,0x74,0xbf,0xf0} }, -{ 16,0x0f60,0,{0x90,0x7f,0x96,0xe0,0x54,0x30,0xf0,0x90,0x7f,0x94,0x74,0x30,0xf0,0x90,0x7f,0x9d} }, -{ 16,0x0f70,0,{0x74,0xcf,0xf0,0x90,0x7f,0x97,0x74,0xa0,0xf0,0x90,0x7f,0x95,0x74,0xcc,0xf0,0xe4} }, -{ 16,0x0f80,0,{0x90,0x7f,0x9e,0xf0,0xc2,0x2d,0xc2,0x2a,0xc2,0x2b,0xc2,0x2e,0x90,0x79,0x74,0x04} }, -{ 16,0x0f90,0,{0xf0,0x12,0x2e,0x94,0x12,0x49,0xe2,0x12,0x4b,0xe6,0x12,0x32,0x0d,0x12,0x3b,0x0d} }, -{ 16,0x0fa0,0,{0x12,0x41,0xfd,0x12,0x3e,0x99,0xe5,0x1f,0x70,0x18,0x75,0x1f,0x01,0x12,0x17,0xff} }, -{ 16,0x0fb0,0,{0x12,0x2f,0xff,0x12,0x49,0xc8,0x12,0x4b,0xd8,0x12,0x4b,0xda,0x12,0x49,0x6f,0x12} }, -{ 16,0x0fc0,0,{0x1b,0x40,0x12,0x39,0x8d,0x90,0x7f,0xaf,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0} }, -{ 16,0x0fd0,0,{0x44,0x1f,0xf0,0x90,0x7f,0xac,0x74,0xff,0xf0,0x90,0x7f,0xad,0xf0,0x90,0x7f,0xde} }, -{ 16,0x0fe0,0,{0xf0,0x90,0x7f,0xdf,0xf0,0x90,0x7f,0xab,0xf0,0x90,0x7f,0xa9,0xf0,0x90,0x7f,0xaa} }, -{ 16,0x0ff0,0,{0xf0,0x53,0x91,0xef,0x43,0xd8,0x20,0xd2,0xe8,0x43,0xd8,0x20,0x43,0xa8,0x80,0x22} }, -{ 16,0x1000,0,{0x90,0x79,0x63,0xe0,0x14,0x60,0x44,0x14,0x70,0x02,0x21,0xd0,0x14,0x70,0x02,0x41} }, -{ 16,0x1010,0,{0xd9,0x14,0x70,0x02,0x61,0xd7,0x24,0x04,0x60,0x02,0x81,0x56,0xe4,0x90,0x79,0x78} }, -{ 16,0x1020,0,{0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x54,0xfd,0xf0,0x90} }, -{ 16,0x1030,0,{0x79,0x7b,0xf0,0xe4,0x90,0x79,0x88,0xf0,0xa2,0xaf,0x33,0xf5,0x12,0xc2,0xaf,0x12} }, -{ 16,0x1040,0,{0x0b,0xa2,0xe5,0x12,0x70,0x02,0x81,0x56,0xd2,0xaf,0x22,0x90,0x79,0x2d,0xe0,0x64} }, -{ 16,0x1050,0,{0x01,0x70,0x79,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x30,0xf0,0x90,0x7f,0xff} }, -{ 16,0x1060,0,{0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0} }, -{ 16,0x1070,0,{0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12} }, -{ 16,0x1080,0,{0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90} }, -{ 16,0x1090,0,{0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe} }, -{ 16,0x10a0,0,{0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd} }, -{ 16,0x10b0,0,{0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x04} }, -{ 16,0x10c0,0,{0xf0,0x90,0x79,0x88,0x14,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d,0xe0} }, -{ 16,0x10d0,0,{0x64,0x02,0x70,0x79,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x34,0xf0,0x90,0x7f} }, -{ 16,0x10e0,0,{0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79} }, -{ 16,0x10f0,0,{0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5} }, -{ 16,0x1100,0,{0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0} }, -{ 16,0x1110,0,{0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54} }, -{ 16,0x1120,0,{0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44} }, -{ 16,0x1130,0,{0x02,0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74} }, -{ 16,0x1140,0,{0x04,0xf0,0x90,0x79,0x88,0x14,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d} }, -{ 16,0x1150,0,{0xe0,0x64,0x03,0x60,0x02,0x81,0x56,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x64} }, -{ 16,0x1160,0,{0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0} }, -{ 16,0x1170,0,{0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf} }, -{ 16,0x1180,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90} }, -{ 16,0x1190,0,{0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79} }, -{ 16,0x11a0,0,{0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79} }, -{ 16,0x11b0,0,{0x79,0xe0,0x44,0x04,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74} }, -{ 16,0x11c0,0,{0x04,0xf0,0x90,0x79,0x88,0x14,0xf0,0xe5,0x12,0x70,0x02,0x81,0x56,0xd2,0xaf,0x22} }, -{ 16,0x11d0,0,{0x90,0x79,0x2d,0xe0,0x64,0x01,0x70,0x7a,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74} }, -{ 16,0x11e0,0,{0x88,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b} }, -{ 16,0x11f0,0,{0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x54,0xfd,0xf0,0x90,0x79,0x7b,0xf0,0xa2} }, -{ 16,0x1200,0,{0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0} }, -{ 16,0x1210,0,{0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90} }, -{ 16,0x1220,0,{0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90} }, -{ 16,0x1230,0,{0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2} }, -{ 16,0x1240,0,{0x90,0x79,0x82,0x74,0x0c,0xf0,0x90,0x79,0x88,0x74,0x01,0xf0,0xe5,0x12,0x60,0x02} }, -{ 16,0x1250,0,{0xd2,0xaf,0x90,0x79,0x2d,0xe0,0x64,0x02,0x60,0x02,0x81,0x56,0x90,0x7f,0xf2,0xf0} }, -{ 16,0x1260,0,{0x90,0x7f,0xf3,0x74,0x94,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4,0x90,0x79,0x78} }, -{ 16,0x1270,0,{0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x54,0xfd,0xf0,0x90} }, -{ 16,0x1280,0,{0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79} }, -{ 16,0x1290,0,{0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0} }, -{ 16,0x12a0,0,{0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0} }, -{ 16,0x12b0,0,{0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0x90,0x79,0x84} }, -{ 16,0x12c0,0,{0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x0c,0xf0,0x90,0x79,0x88,0x74,0x01,0xf0} }, -{ 16,0x12d0,0,{0xe5,0x12,0x70,0x02,0x81,0x56,0xd2,0xaf,0x22,0x90,0x79,0x2d,0xe0,0x64,0x01,0x70} }, -{ 16,0x12e0,0,{0x77,0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0xcc,0xf0,0x90,0x7f,0xff,0x74,0xfc} }, -{ 16,0x12f0,0,{0xf0,0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfc} }, -{ 16,0x1300,0,{0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2} }, -{ 16,0x1310,0,{0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79} }, -{ 16,0x1320,0,{0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79} }, -{ 16,0x1330,0,{0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0x90} }, -{ 16,0x1340,0,{0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x12,0xf0,0x90,0x79,0x88,0x74} }, -{ 16,0x1350,0,{0x02,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d,0xe0,0x64,0x02,0x70,0x77} }, -{ 16,0x1360,0,{0x90,0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0xe0,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0} }, -{ 16,0x1370,0,{0xe4,0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfc,0xf0} }, -{ 16,0x1380,0,{0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90} }, -{ 16,0x1390,0,{0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f} }, -{ 16,0x13a0,0,{0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79} }, -{ 16,0x13b0,0,{0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0x90,0x79} }, -{ 16,0x13c0,0,{0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x12,0xf0,0x90,0x79,0x88,0x74,0x02} }, -{ 16,0x13d0,0,{0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x2d,0xe0,0x64,0x03,0x70,0x77,0x90} }, -{ 16,0x13e0,0,{0x7f,0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x94,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0xe4} }, -{ 16,0x13f0,0,{0x90,0x79,0x78,0xf0,0x90,0x79,0x7b,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfe,0xf0,0x44} }, -{ 16,0x1400,0,{0x02,0xf0,0x90,0x79,0x7b,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} }, -{ 16,0x1410,0,{0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90} }, -{ 16,0x1420,0,{0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90} }, -{ 16,0x1430,0,{0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x90,0x79,0x84} }, -{ 16,0x1440,0,{0xf0,0x12,0x0b,0xa2,0x90,0x79,0x82,0x74,0x06,0xf0,0x90,0x79,0x88,0x74,0x04,0xf0} }, -{ 7,0x1450,0,{0xe5,0x12,0x60,0x02,0xd2,0xaf,0x22} }, -{ 16,0x1457,0,{0xc2,0x28,0xc2,0x29,0x90,0x7f,0xe8,0xe0,0x12,0x0e,0x1a,0x14,0x84,0x00,0x14,0xe0} }, -{ 16,0x1467,0,{0x01,0x14,0xf6,0x02,0x16,0x7c,0x21,0x16,0xbe,0x22,0x15,0x91,0x80,0x15,0xd1,0x81} }, -{ 16,0x1477,0,{0x16,0x2e,0x82,0x16,0xcf,0xa1,0x17,0x05,0xa2,0x00,0x00,0x17,0x0a,0x90,0x7f,0xe9} }, -{ 16,0x1487,0,{0xe0,0x14,0x60,0x11,0x24,0xfe,0x60,0x28,0x24,0xfe,0x60,0x3b,0x24,0xfc,0x70,0x40} }, -{ 16,0x1497,0,{0x12,0x4a,0x2a,0xe1,0x16,0x12,0x4b,0xe0,0x40,0x02,0xe1,0x16,0x90,0x7f,0xea,0xe0} }, -{ 16,0x14a7,0,{0xb4,0x01,0x04,0xc2,0x2a,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16} }, -{ 16,0x14b7,0,{0x12,0x4b,0xe2,0x90,0x7f,0xea,0xe0,0xb4,0x01,0x04,0xd2,0x2a,0xe1,0x16,0x90,0x7f} }, -{ 16,0x14c7,0,{0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16} }, -{ 16,0x14d7,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x24,0xf5,0x70} }, -{ 16,0x14e7,0,{0x05,0x12,0x47,0x9c,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90} }, -{ 16,0x14f7,0,{0x7f,0xe9,0xe0,0x24,0xfd,0x60,0x54,0x24,0x02,0x60,0x02,0xa1,0x88,0x12,0x4b,0xe0} }, -{ 16,0x1507,0,{0x40,0x02,0xe1,0x16,0x90,0x7f,0xea,0xe0,0x70,0x38,0x90,0x7f,0xec,0xe0,0xf4,0x54} }, -{ 16,0x1517,0,{0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82} }, -{ 16,0x1527,0,{0xe4,0x34,0x7f,0xf5,0x83,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0x54,0x80,0xff,0x13,0x13} }, -{ 16,0x1537,0,{0x13,0x54,0x1f,0xff,0xe0,0x54,0x07,0x2f,0x90,0x7f,0xd7,0xf0,0xe0,0x44,0x20,0xf0} }, -{ 16,0x1547,0,{0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x12,0x4b,0xe2,0x40,0x02} }, -{ 16,0x1557,0,{0xe1,0x16,0x90,0x7f,0xea,0xe0,0x70,0x20,0x90,0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff} }, -{ 16,0x1567,0,{0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34} }, -{ 16,0x1577,0,{0x7f,0xf5,0x83,0x74,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1} }, -{ 16,0x1587,0,{0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x60,0x12} }, -{ 16,0x1597,0,{0x24,0xf8,0x60,0x09,0x24,0x02,0x70,0x29,0x12,0x17,0x1e,0xe1,0x16,0x12,0x4b,0xa0} }, -{ 16,0x15a7,0,{0xe1,0x16,0x12,0x4b,0xde,0xa2,0x2a,0xe4,0x33,0xff,0x25,0xe0,0xff,0xa2,0x2b,0xe4} }, -{ 16,0x15b7,0,{0x33,0x4f,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0xe1} }, -{ 16,0x15c7,0,{0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x60,0x37} }, -{ 16,0x15d7,0,{0x24,0xf6,0x60,0x2e,0x24,0x04,0x70,0x41,0x90,0x7f,0xeb,0xe0,0x24,0xde,0x60,0x0e} }, -{ 16,0x15e7,0,{0x04,0x70,0x16,0xd2,0x29,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0xd2,0x29} }, -{ 16,0x15f7,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 16,0x1607,0,{0xe1,0x16,0x12,0x44,0x63,0xe1,0x16,0x12,0x4b,0xde,0xe4,0x90,0x7f,0x00,0xf0,0xa3} }, -{ 16,0x1617,0,{0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0xe1,0x16,0x20,0x29,0x07,0x90,0x7f,0xb4,0xe0} }, -{ 16,0x1627,0,{0x44,0x01,0xf0,0xc2,0x29,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x24,0xf4,0x60,0x34,0x24} }, -{ 16,0x1637,0,{0x0c,0x70,0x39,0x12,0x4b,0xde,0x90,0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff,0xc4,0x54} }, -{ 16,0x1647,0,{0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34,0x7f,0xf5} }, -{ 16,0x1657,0,{0x83,0xe0,0x54,0xfd,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02} }, -{ 16,0x1667,0,{0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xb4,0xe0} }, -{ 16,0x1677,0,{0x44,0x01,0xf0,0xe1,0x16,0x90,0x7f,0xe9,0xe0,0x24,0xf6,0x60,0x12,0x14,0x60,0x1a} }, -{ 16,0x1687,0,{0x24,0x02,0x70,0x1d,0xd2,0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x12,0xd2} }, -{ 16,0x1697,0,{0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01} }, -{ 16,0x16a7,0,{0xf0,0x20,0x28,0x0f,0x90,0x79,0x85,0x74,0x01,0xf0,0x12,0x49,0x6f,0x90,0x7f,0xc5} }, -{ 16,0x16b7,0,{0x74,0x02,0xf0,0xc2,0x28,0x80,0x58,0x90,0x79,0x86,0x74,0x01,0xf0,0x12,0x49,0x6f} }, -{ 16,0x16c7,0,{0x90,0x7f,0xc5,0x74,0x02,0xf0,0x80,0x47,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x60,0x12} }, -{ 16,0x16d7,0,{0x14,0x60,0x1a,0x24,0x02,0x70,0x1d,0xd2,0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 16,0x16e7,0,{0x80,0x12,0xd2,0x28,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4} }, -{ 16,0x16f7,0,{0xe0,0x44,0x01,0xf0,0x20,0x28,0x03,0x12,0x1a,0x7b,0xc2,0x28,0x80,0x11,0x12,0x2c} }, -{ 16,0x1707,0,{0x2b,0x80,0x0c,0x12,0x4b,0xe4,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90} }, -{ 7,0x1717,0,{0x7f,0xb4,0xe0,0x44,0x02,0xf0,0x22} }, -{ 16,0x171e,0,{0x12,0x4b,0xdc,0x40,0x02,0xe1,0xe3,0x90,0x7f,0xeb,0xe0,0x24,0xfe,0x60,0x1e,0x14} }, -{ 16,0x172e,0,{0x60,0x46,0x14,0x60,0x6e,0x14,0x70,0x02,0xe1,0xd4,0x24,0x04,0x60,0x02,0xe1,0xdc} }, -{ 16,0x173e,0,{0x74,0x05,0x90,0x7f,0xd4,0xf0,0x74,0x00,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xea} }, -{ 16,0x174e,0,{0xe0,0xff,0x12,0x3f,0xa2,0x8b,0x33,0x8a,0x34,0x89,0x35,0xea,0x49,0x60,0x11,0xce} }, -{ 16,0x175e,0,{0xea,0xce,0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22} }, -{ 16,0x176e,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x12,0x48,0x00} }, -{ 16,0x177e,0,{0x8b,0x33,0x8a,0x34,0x89,0x35,0xea,0x49,0x60,0x11,0xce,0xea,0xce,0xee,0x90,0x7f} }, -{ 16,0x178e,0,{0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44} }, -{ 16,0x179e,0,{0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x90,0x7e,0xc0,0xe0,0xfd,0xa3,0xe0,0xfb} }, -{ 16,0x17ae,0,{0x12,0x44,0xd2,0x8b,0x33,0x8a,0x34,0x89,0x35,0xea,0x49,0x60,0x11,0xce,0xea,0xce} }, -{ 16,0x17be,0,{0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f} }, -{ 16,0x17ce,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f} }, -{ 5,0x17de,0,{0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x17e3,0,{0x22} }, -{ 16,0x17e4,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f} }, -{ 11,0x17f4,0,{0xab,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 1,0x17ff,0,{0x22} }, -{ 16,0x1800,0,{0xe4,0x90,0x78,0x15,0xf0,0x7b,0x01,0x90,0x78,0x12,0x04,0xf0,0xa3,0x74,0x78,0xf0} }, -{ 16,0x1810,0,{0xa3,0x74,0x58,0xf0,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} }, -{ 16,0x1820,0,{0x00,0x01,0x12,0x0c,0x5d,0xff,0x90,0x79,0x9a,0xe0,0x6f,0x60,0x18,0x90,0x78,0x15} }, -{ 16,0x1830,0,{0xe0,0xc3,0x94,0x06,0x50,0x0f,0xe0,0x04,0xf0,0x90,0x78,0x13,0xe4,0x75,0xf0,0x0f} }, -{ 16,0x1840,0,{0x12,0x0c,0xf4,0x80,0xcf,0x90,0x78,0x15,0xe0,0xb4,0x06,0x08,0x90,0x7f,0xb4,0xe0} }, -{ 16,0x1850,0,{0x44,0x01,0xf0,0x22,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12} }, -{ 16,0x1860,0,{0x0c,0x44,0xff,0x24,0xbf,0x70,0x02,0x41,0x7a,0x24,0xe0,0x70,0x02,0x41,0x4c,0x24} }, -{ 16,0x1870,0,{0x21,0x60,0x02,0x41,0x73,0x90,0x79,0x97,0xe0,0x24,0xfe,0x70,0x02,0x21,0x9a,0x14} }, -{ 16,0x1880,0,{0x70,0x02,0x21,0xef,0x24,0x02,0x60,0x02,0x41,0x44,0x90,0x79,0x2d,0xe0,0xa3,0xf0} }, -{ 16,0x1890,0,{0x90,0x79,0x23,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x0d} }, -{ 16,0x18a0,0,{0x42,0xc8,0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x79,0x22} }, -{ 16,0x18b0,0,{0xe0,0xfe,0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8} }, -{ 16,0x18c0,0,{0x90,0x79,0x21,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd} }, -{ 16,0x18d0,0,{0xec,0x38,0xfc,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} }, -{ 16,0x18e0,0,{0x02,0x12,0x0d,0xd2,0x90,0x00,0x02,0x12,0x0d,0xa2,0x7b,0x44,0x7a,0xac,0x79,0x00} }, -{ 16,0x18f0,0,{0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x05,0x90,0x79,0x2d,0x04,0xf0,0x90,0x78,0x12} }, -{ 16,0x1900,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12,0x0d,0xa2,0x7b,0x80} }, -{ 16,0x1910,0,{0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x06,0x90,0x79,0x2d,0x74} }, -{ 16,0x1920,0,{0x02,0xf0,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02} }, -{ 16,0x1930,0,{0x12,0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70} }, -{ 16,0x1940,0,{0x06,0x90,0x79,0x2d,0x74,0x03,0xf0,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0x75} }, -{ 16,0x1950,0,{0x0c,0x67,0x75,0x0d,0x06,0x75,0x0e,0x0b,0xef,0xb4,0x02,0x08,0xe4,0xf5,0x0c,0xf5} }, -{ 16,0x1960,0,{0x0d,0x75,0x0e,0x0c,0xef,0xb4,0x03,0x08,0xe4,0xf5,0x0c,0xf5,0x0d,0x75,0x0e,0x18} }, -{ 16,0x1970,0,{0xef,0xb4,0x03,0x0d,0x90,0x79,0x2e,0xe0,0x64,0x03,0x60,0x05,0xd2,0x2f,0x12,0x3d} }, -{ 16,0x1980,0,{0x79,0x90,0x79,0x2d,0xe0,0x64,0x03,0x60,0x0a,0xa3,0xe0,0xb4,0x03,0x05,0xc2,0x2f} }, -{ 16,0x1990,0,{0x12,0x3d,0x79,0x12,0x10,0x00,0x12,0x28,0x01,0x22,0x90,0x79,0x23,0xe0,0xff,0xe4} }, -{ 16,0x19a0,0,{0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x0d,0x42,0xc8,0xec,0xc8,0xc9,0xed} }, -{ 16,0x19b0,0,{0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x79,0x22,0xe0,0xfe,0xe4,0xfc,0xfd,0x2b} }, -{ 16,0x19c0,0,{0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x79,0x21,0xe0,0xff,0xe4} }, -{ 16,0x19d0,0,{0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x78,0x12} }, -{ 16,0x19e0,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x06,0x12,0x0d,0xd2,0x22,0x90} }, -{ 16,0x19f0,0,{0x79,0x23,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x0d,0x42} }, -{ 16,0x1a00,0,{0xc8,0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x79,0x22,0xe0} }, -{ 16,0x1a10,0,{0xfe,0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90} }, -{ 16,0x1a20,0,{0x79,0x21,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec} }, -{ 16,0x1a30,0,{0x38,0xfc,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a} }, -{ 16,0x1a40,0,{0x12,0x0d,0xd2,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0} }, -{ 16,0x1a50,0,{0x14,0x70,0x18,0x90,0x79,0x21,0xe0,0xff,0x90,0x78,0x12,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x1a60,0,{0xa3,0xe0,0xf9,0x90,0x00,0x0e,0xef,0x12,0x0c,0x9c,0x22,0x90,0x7f,0xb4,0xe0,0x44} }, -{ 10,0x1a70,0,{0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x1a7a,0,{0x22} }, -{ 16,0x1a7b,0,{0xe4,0xff,0xfe,0x7b,0x01,0x90,0x78,0x0f,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74} }, -{ 16,0x1a8b,0,{0x2b,0xf0,0x90,0x78,0x0f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02} }, -{ 16,0x1a9b,0,{0x12,0x0c,0x5d,0xfd,0x90,0x7f,0xec,0xe0,0x6d,0x60,0x13,0xef,0xc3,0x94,0x05,0x50} }, -{ 16,0x1aab,0,{0x0d,0x0f,0x90,0x78,0x10,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd4,0x8d,0x33} }, -{ 16,0x1abb,0,{0x90,0x78,0x0f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c} }, -{ 16,0x1acb,0,{0x5d,0xfd,0x90,0x7f,0xed,0xe0,0x6d,0x60,0x13,0xee,0xc3,0x94,0x0b,0x50,0x0d,0x0e} }, -{ 16,0x1adb,0,{0x90,0x78,0x10,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd4,0x90,0x7f,0xed,0xe0} }, -{ 16,0x1aeb,0,{0xf5,0x34,0xef,0x64,0x05,0x60,0x03,0xbe,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01} }, -{ 16,0x1afb,0,{0xf0,0x22,0x90,0x78,0x0f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44} }, -{ 16,0x1b0b,0,{0xff,0x24,0xf0,0x60,0x08,0x24,0x0f,0x70,0x0e,0x12,0x49,0x2a,0x22,0x12,0x4b,0x83} }, -{ 14,0x1b1b,0,{0x90,0x79,0x20,0xe5,0x34,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x1b29,0,{0x22} }, -{ 15,0x1b2a,0,{0x90,0x7f,0xea,0xe0,0xb4,0xff,0x04,0x12,0x34,0x16,0x22,0x12,0x38,0x00,0x22} }, -{ 7,0x1b39,0,{0x53,0x98,0xfe,0x53,0x98,0xfd,0x32} }, -{ 16,0x1b40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1b50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1b60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1b70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1b80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1b90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ba0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1bb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1bc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1bd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1be0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1bf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1c90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ca0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1cb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1cc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1cd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ce0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1cf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1d90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1da0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1db0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1dc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1dd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1de0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1df0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1e90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ea0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 14,0x1eb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ebe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ece,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ede,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1eee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1efe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f0e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f1e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f2e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 2,0x1f3e,0,{0x00,0x00} }, -{ 16,0x1f40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1f90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1fa0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1fb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1fc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1fd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1fe0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x1ff0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2000,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2010,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2020,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2030,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2040,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2050,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2060,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2070,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2080,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2090,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x20a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x20b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x20c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x20d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x20e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x20f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2100,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2110,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2120,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2130,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2140,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2150,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2160,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2170,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2180,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2190,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x21a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x21b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x21c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x21d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x21e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x21f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2200,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2210,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2220,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2230,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2240,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2250,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2260,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2270,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2280,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2290,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x22a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x22b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x22c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x22d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x22e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x22f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2300,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2310,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2320,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2330,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2340,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2350,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x2360,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 14,0x2370,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x237e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x238e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x239e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x23ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x23be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x23ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x23de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x23ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x23fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x240e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x241e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x242e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x243e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x244e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x245e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x246e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x247e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x248e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x249e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x24ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x24be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x24ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x24de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x24ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x24fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x250e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x251e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x252e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x253e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x254e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x255e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x256e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x257e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x258e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x259e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x25ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x25be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x25ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x25de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x25ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x25fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x260e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x261e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x262e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x263e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x264e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x265e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x266e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x267e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x268e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x269e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x26ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x26be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x26ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x26de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 14,0x26ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x26fc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x270c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x271c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x272c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x273c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x274c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x275c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x276c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x277c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x278c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x279c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x27ac,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x27bc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x27cc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x27dc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 16,0x27ec,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }, -{ 5,0x27fc,0,{0x00,0x00,0x00,0x00,0x22} }, -{ 16,0x2801,0,{0x90,0x79,0x64,0xe0,0x14,0x60,0x46,0x14,0x70,0x02,0x41,0x3c,0x24,0x02,0x60,0x02} }, -{ 16,0x2811,0,{0x81,0x2a,0x90,0x7f,0xfc,0x74,0xcc,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79} }, -{ 16,0x2821,0,{0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfd,0xf0,0x44} }, -{ 16,0x2831,0,{0x01,0xf0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} }, -{ 16,0x2841,0,{0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x7a,0xf0,0x22,0x90,0x79,0x2d} }, -{ 16,0x2851,0,{0xe0,0x64,0x01,0x60,0x02,0x01,0xf1,0x90,0x7f,0xfc,0x74,0xcc,0xf0,0x90,0x7f,0xff} }, -{ 16,0x2861,0,{0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79} }, -{ 16,0x2871,0,{0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79} }, -{ 16,0x2881,0,{0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79} }, -{ 16,0x2891,0,{0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} }, -{ 16,0x28a1,0,{0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90} }, -{ 16,0x28b1,0,{0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90} }, -{ 16,0x28c1,0,{0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0} }, -{ 16,0x28d1,0,{0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0,0x90,0x79,0x65} }, -{ 16,0x28e1,0,{0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0} }, -{ 16,0x28f1,0,{0x90,0x79,0x2d,0xe0,0x64,0x02,0x60,0x02,0x21,0x96,0x90,0x7f,0xfc,0x74,0xc8,0xf0} }, -{ 16,0x2901,0,{0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0} }, -{ 16,0x2911,0,{0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01} }, -{ 16,0x2921,0,{0x09,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb} }, -{ 16,0x2931,0,{0xf0,0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2} }, -{ 16,0x2941,0,{0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79} }, -{ 16,0x2951,0,{0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0} }, -{ 16,0x2961,0,{0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0} }, -{ 16,0x2971,0,{0x54,0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0} }, -{ 16,0x2981,0,{0x90,0x79,0x65,0x74,0x03,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c} }, -{ 16,0x2991,0,{0xf0,0x90,0x79,0x8b,0xf0,0x90,0x79,0x2d,0xe0,0x64,0x03,0x60,0x02,0x81,0x2a,0x90} }, -{ 16,0x29a1,0,{0x7f,0xfc,0x74,0x98,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01} }, -{ 16,0x29b1,0,{0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x90} }, -{ 16,0x29c1,0,{0x79,0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90} }, -{ 16,0x29d1,0,{0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf} }, -{ 16,0x29e1,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90} }, -{ 16,0x29f1,0,{0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79} }, -{ 16,0x2a01,0,{0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79} }, -{ 16,0x2a11,0,{0x79,0xe0,0x54,0xfd,0xf0,0x44,0x04,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90} }, -{ 16,0x2a21,0,{0x79,0x7a,0x74,0x01,0xf0,0x90,0x79,0x65,0x74,0x05,0xf0,0xe5,0x12,0x60,0x02,0xd2} }, -{ 16,0x2a31,0,{0xaf,0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x22,0x90,0x79,0x2d,0xe0,0x64} }, -{ 16,0x2a41,0,{0x01,0x60,0x02,0x41,0xe0,0x90,0x7f,0xfc,0x74,0xb4,0xf0,0x90,0x7f,0xff,0x74,0xfc} }, -{ 16,0x2a51,0,{0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x54} }, -{ 16,0x2a61,0,{0xfe,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0} }, -{ 16,0x2a71,0,{0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79,0x79,0xe0} }, -{ 16,0x2a81,0,{0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90} }, -{ 16,0x2a91,0,{0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f} }, -{ 16,0x2aa1,0,{0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79} }, -{ 16,0x2ab1,0,{0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0x90,0x79} }, -{ 16,0x2ac1,0,{0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0,0x90,0x79,0x65,0x04,0xf0} }, -{ 16,0x2ad1,0,{0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x90} }, -{ 16,0x2ae1,0,{0x79,0x2d,0xe0,0x64,0x02,0x60,0x02,0x61,0x85,0x90,0x7f,0xfc,0x74,0xb0,0xf0,0x90} }, -{ 16,0x2af1,0,{0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90} }, -{ 16,0x2b01,0,{0x79,0x79,0xf0,0x54,0xfe,0xf0,0x44,0x02,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09} }, -{ 16,0x2b11,0,{0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0} }, -{ 16,0x2b21,0,{0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf} }, -{ 16,0x2b31,0,{0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79} }, -{ 16,0x2b41,0,{0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80} }, -{ 16,0x2b51,0,{0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x44,0x02,0xf0,0x54} }, -{ 16,0x2b61,0,{0xfb,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x7a,0x74,0x01,0xf0,0x90} }, -{ 16,0x2b71,0,{0x79,0x65,0x74,0x04,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf,0xe4,0x90,0x79,0x8c,0xf0} }, -{ 16,0x2b81,0,{0x90,0x79,0x8b,0xf0,0x90,0x79,0x2d,0xe0,0x64,0x03,0x60,0x02,0x81,0x2a,0x90,0x7f} }, -{ 16,0x2b91,0,{0xfc,0x74,0x68,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0} }, -{ 16,0x2ba1,0,{0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x54,0xfe,0xf0,0x44,0x02,0xf0,0x90,0x79} }, -{ 16,0x2bb1,0,{0x7e,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79} }, -{ 16,0x2bc1,0,{0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4} }, -{ 16,0x2bd1,0,{0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x02,0xf0,0x90,0x79} }, -{ 16,0x2be1,0,{0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09,0x90,0x79,0x79} }, -{ 16,0x2bf1,0,{0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79} }, -{ 16,0x2c01,0,{0xe0,0x54,0xfd,0xf0,0x44,0x04,0xf0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79} }, -{ 16,0x2c11,0,{0x7a,0x74,0x01,0xf0,0x90,0x79,0x65,0x74,0x06,0xf0,0xe5,0x12,0x60,0x02,0xd2,0xaf} }, -{ 10,0x2c21,0,{0xe4,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x22} }, -{ 16,0x2c2b,0,{0xe4,0xff,0x7b,0x01,0x90,0x78,0x16,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0x58} }, -{ 16,0x2c3b,0,{0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12} }, -{ 16,0x2c4b,0,{0x0c,0x5d,0xfe,0x90,0x7f,0xec,0xe0,0x6e,0x60,0x13,0xef,0xc3,0x94,0x06,0x50,0x0d} }, -{ 16,0x2c5b,0,{0x0f,0x90,0x78,0x17,0xe4,0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x80,0xd4,0xbf,0x06,0x08} }, -{ 16,0x2c6b,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x2c7b,0,{0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xff,0x24,0x9f,0x70,0x02,0xc1,0x66,0x24,0x21,0x60} }, -{ 16,0x2c8b,0,{0x02,0xc1,0x8c,0x90,0x7f,0xe9,0xe0,0x24,0x7e,0x70,0x02,0xa1,0x30,0x14,0x70,0x02} }, -{ 16,0x2c9b,0,{0xa1,0xc8,0x24,0x02,0x60,0x02,0xc1,0x5e,0x90,0x00,0x02,0x12,0x0d,0xa2,0x7b,0x44} }, -{ 16,0x2cab,0,{0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74} }, -{ 16,0x2cbb,0,{0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90} }, -{ 16,0x2ccb,0,{0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12,0x0d,0xa2} }, -{ 16,0x2cdb,0,{0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f} }, -{ 16,0x2ceb,0,{0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03} }, -{ 16,0x2cfb,0,{0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12} }, -{ 16,0x2d0b,0,{0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x0d,0x91,0x60,0x02} }, -{ 16,0x2d1b,0,{0xc1,0x93,0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f} }, -{ 16,0x2d2b,0,{0xb5,0x74,0x03,0xf0,0x22,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} }, -{ 16,0x2d3b,0,{0x90,0x00,0x06,0x12,0x0d,0xa2,0x7b,0x44,0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12} }, -{ 16,0x2d4b,0,{0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3} }, -{ 16,0x2d5b,0,{0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3} }, -{ 16,0x2d6b,0,{0xe0,0xf9,0x90,0x00,0x06,0x12,0x0d,0xa2,0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00} }, -{ 16,0x2d7b,0,{0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0} }, -{ 16,0x2d8b,0,{0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0} }, -{ 16,0x2d9b,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x06,0x12,0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01} }, -{ 16,0x2dab,0,{0x78,0x00,0xc3,0x12,0x0d,0x91,0x60,0x02,0xc1,0x93,0x90,0x7f,0x00,0xf0,0xa3,0x74} }, -{ 16,0x2dbb,0,{0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90,0x78,0x16} }, -{ 16,0x2dcb,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a,0x12,0x0d,0xa2,0x7b,0x44} }, -{ 16,0x2ddb,0,{0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f,0x00,0x74} }, -{ 16,0x2deb,0,{0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90} }, -{ 16,0x2dfb,0,{0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a,0x12,0x0d,0xa2} }, -{ 16,0x2e0b,0,{0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x13,0x90,0x7f} }, -{ 16,0x2e1b,0,{0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03} }, -{ 16,0x2e2b,0,{0xf0,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x0a,0x12} }, -{ 16,0x2e3b,0,{0x0d,0xa2,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x0d,0x91,0x70,0x48} }, -{ 16,0x2e4b,0,{0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f,0xb5,0x74} }, -{ 16,0x2e5b,0,{0x03,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24} }, -{ 16,0x2e6b,0,{0x7f,0x70,0x16,0x90,0x78,0x16,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} }, -{ 16,0x2e7b,0,{0x0e,0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 8,0x2e8b,0,{0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x2e93,0,{0x22} }, -{ 16,0x2e94,0,{0x75,0x36,0x25,0x75,0x37,0x24,0x90,0x79,0x74,0xe0,0x64,0x01,0x70,0x54,0xf0,0xf5} }, -{ 16,0x2ea4,0,{0x35,0x75,0x22,0x01,0xe5,0x22,0x64,0x01,0x70,0x48,0x90,0x7f,0xa5,0xe0,0x44,0x80} }, -{ 16,0x2eb4,0,{0xf0,0x90,0x7f,0xa6,0xe5,0x36,0xf0,0x12,0x46,0xc0,0x74,0x4f,0x25,0x35,0xf5,0x82} }, -{ 16,0x2ec4,0,{0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x74,0x35,0x25} }, -{ 16,0x2ed4,0,{0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0} }, -{ 16,0x2ee4,0,{0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd,0x05,0x35,0xe5,0x35,0xc3,0x94,0x0d} }, -{ 16,0x2ef4,0,{0x40,0xb2,0x90,0x79,0x75,0xe0,0x64,0x01,0x60,0x02,0xe1,0xde,0xf0,0x90,0x79,0x20} }, -{ 16,0x2f04,0,{0xe0,0x64,0x05,0x60,0x02,0xe1,0x8d,0x7b,0x01,0x90,0x79,0x5c,0x04,0xf0,0xa3,0x74} }, -{ 16,0x2f14,0,{0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x75,0x33,0x07,0x90,0x79,0x5c,0xe0,0xfb,0xa3,0xe0} }, -{ 16,0x2f24,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c,0x5d,0x70,0x0f,0x90,0x00,0x04,0x12} }, -{ 16,0x2f34,0,{0x0c,0x5d,0x90,0x79,0x2f,0xf0,0x12,0x0c,0x29,0x80,0x06,0x90,0x79,0x2f,0x74,0xff} }, -{ 16,0x2f44,0,{0xf0,0xe4,0xf5,0x35,0x75,0x22,0x01,0x75,0x34,0x02,0xe5,0x22,0x64,0x01,0x70,0x39} }, -{ 16,0x2f54,0,{0x90,0x7f,0xa5,0xe0,0x44,0x80,0xf0,0x90,0x7f,0xa6,0xe5,0x36,0xf0,0x12,0x46,0xc0} }, -{ 16,0x2f64,0,{0xaf,0x34,0x05,0x34,0x90,0x7f,0xa6,0xef,0xf0,0x12,0x46,0xc0,0x90,0x79,0x2f,0xe0} }, -{ 16,0x2f74,0,{0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd} }, -{ 16,0x2f84,0,{0x05,0x35,0xe5,0x35,0xc3,0x94,0x06,0x40,0xc1,0x90,0x79,0x20,0xe0,0x64,0x06,0x70} }, -{ 16,0x2f94,0,{0x49,0x7b,0x01,0x90,0x79,0x5f,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0} }, -{ 16,0x2fa4,0,{0x75,0x33,0x03,0x90,0x79,0x5f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} }, -{ 16,0x2fb4,0,{0x01,0x12,0x0c,0x5d,0x70,0x1c,0x90,0x00,0x04,0x12,0x0c,0x5d,0x90,0x79,0x33,0xf0} }, -{ 16,0x2fc4,0,{0x70,0x03,0x74,0xff,0xf0,0x90,0x79,0x33,0xe0,0x54,0x7f,0xff,0xf0,0x25,0xe0,0xf0} }, -{ 10,0x2fd4,0,{0x80,0x05,0xe4,0x90,0x79,0x33,0xf0,0x12,0x47,0xdf} }, -{ 1,0x2fde,0,{0x22} }, -{ 16,0x2fdf,0,{0x90,0x79,0x78,0x74,0x03,0xf0,0x90,0x79,0x83,0xe0,0x90,0x79,0x79,0xf0,0xa2,0xaf} }, -{ 16,0x2fef,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x22} }, -{ 1,0x2fff,0,{0x22} }, -{ 16,0x3000,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x11,0x90,0x78,0x25,0x74,0x01,0xf0} }, -{ 16,0x3010,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x75,0x35,0x07,0xed,0xb4,0x06,0x11,0x90} }, -{ 16,0x3020,0,{0x78,0x25,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x75,0x35,0x03} }, -{ 16,0x3030,0,{0x90,0x7f,0xeb,0xe0,0x14,0x60,0x11,0x14,0x60,0x5b,0x24,0x02,0x60,0x02,0x41,0x05} }, -{ 16,0x3040,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x3d} }, -{ 16,0x3050,0,{0xe4,0xff,0xef,0xc3,0x95,0x35,0x50,0x2f,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x3060,0,{0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00} }, -{ 16,0x3070,0,{0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0} }, -{ 16,0x3080,0,{0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xcb,0x90,0x7f,0xb5,0xee,0xf0,0x22,0x90,0x7f,0xb4} }, -{ 16,0x3090,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7e,0x60,0x64,0x14,0x70,0x02} }, -{ 16,0x30a0,0,{0x21,0x55,0x14,0x70,0x02,0x21,0xa9,0x24,0x03,0x60,0x02,0x21,0xfd,0xe4,0xff,0xef} }, -{ 16,0x30b0,0,{0xc3,0x95,0x35,0x50,0x46,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} }, -{ 16,0x30c0,0,{0x90,0x00,0x03,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82} }, -{ 16,0x30d0,0,{0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x00,0x04,0x12,0x0c,0x5d,0xfd,0xcc,0xee} }, -{ 16,0x30e0,0,{0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78} }, -{ 16,0x30f0,0,{0x26,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0x90,0x7f,0xb5,0xee,0xf0} }, -{ 16,0x3100,0,{0x22,0xe4,0xff,0xef,0xc3,0x95,0x35,0x50,0x46,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0} }, -{ 16,0x3110,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x05,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74} }, -{ 16,0x3120,0,{0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x00,0x06,0x12,0x0c} }, -{ 16,0x3130,0,{0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83} }, -{ 16,0x3140,0,{0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0x90} }, -{ 16,0x3150,0,{0x7f,0xb5,0xee,0xf0,0x22,0xe4,0xff,0xef,0xc3,0x95,0x35,0x50,0x46,0x90,0x78,0x25} }, -{ 16,0x3160,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x07,0x12,0x0c,0x5d,0xfd,0xcc} }, -{ 16,0x3170,0,{0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90} }, -{ 16,0x3180,0,{0x00,0x08,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4} }, -{ 16,0x3190,0,{0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4} }, -{ 16,0x31a0,0,{0x0f,0x80,0xb4,0x90,0x7f,0xb5,0xee,0xf0,0x22,0xe4,0xff,0xef,0xc3,0x95,0x35,0x50} }, -{ 16,0x31b0,0,{0x46,0x90,0x78,0x25,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x09,0x12} }, -{ 16,0x31c0,0,{0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00,0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5} }, -{ 16,0x31d0,0,{0x83,0xed,0xf0,0x90,0x00,0x0a,0x12,0x0c,0x5d,0xfd,0xcc,0xee,0xcc,0x0e,0x74,0x00} }, -{ 16,0x31e0,0,{0x2c,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xed,0xf0,0x90,0x78,0x26,0xe4,0x75,0xf0} }, -{ 16,0x31f0,0,{0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0x90,0x7f,0xb5,0xee,0xf0,0x22,0x90,0x7f,0xb4} }, -{ 12,0x3200,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x320c,0,{0x22} }, -{ 16,0x320d,0,{0x7b,0x01,0x7a,0x78,0x79,0x2b,0x90,0x78,0x00,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9} }, -{ 16,0x321d,0,{0xf0,0x74,0x01,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} }, -{ 16,0x322d,0,{0xf9,0x90,0x00,0x01,0x74,0x01,0x12,0x0c,0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c} }, -{ 16,0x323d,0,{0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3} }, -{ 16,0x324d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x10,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3} }, -{ 16,0x325d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x05,0x12,0x0c,0x9c,0x90,0x00,0x02} }, -{ 16,0x326d,0,{0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78} }, -{ 16,0x327d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78} }, -{ 16,0x328d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x02,0x12,0x0c} }, -{ 16,0x329d,0,{0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12} }, -{ 16,0x32ad,0,{0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x01,0x12} }, -{ 16,0x32bd,0,{0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01} }, -{ 16,0x32cd,0,{0x74,0x03,0x12,0x0c,0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4} }, -{ 16,0x32dd,0,{0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} }, -{ 16,0x32ed,0,{0xf9,0x74,0x10,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} }, -{ 16,0x32fd,0,{0xf9,0x90,0x00,0x01,0x74,0x06,0x12,0x0c,0x9c,0x90,0x00,0x02,0xe4,0x12,0x0c,0x9c} }, -{ 16,0x330d,0,{0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3} }, -{ 16,0x331d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3} }, -{ 16,0x332d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x04,0x12,0x0c,0x9c,0x90,0x00,0x02} }, -{ 16,0x333d,0,{0xe4,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78} }, -{ 16,0x334d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78} }, -{ 16,0x335d,0,{0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x04,0x12,0x0c} }, -{ 16,0x336d,0,{0x9c,0x90,0x00,0x02,0x74,0x04,0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03} }, -{ 16,0x337d,0,{0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02} }, -{ 16,0x338d,0,{0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} }, -{ 16,0x339d,0,{0x01,0x74,0x03,0x12,0x0c,0x9c,0x90,0x00,0x02,0x74,0x04,0x12,0x0c,0x9c,0x90,0x78} }, -{ 16,0x33ad,0,{0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x33bd,0,{0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78,0x00,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x33cd,0,{0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x02,0x12,0x0c,0x9c,0x90,0x00,0x02,0x74,0x04} }, -{ 16,0x33dd,0,{0x12,0x0c,0x9c,0x90,0x78,0x01,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x00} }, -{ 16,0x33ed,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x02,0x12,0x0c,0x8a,0x90,0x78,0x00} }, -{ 16,0x33fd,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x01,0x12,0x0c,0x9c} }, -{ 8,0x340d,0,{0x90,0x00,0x02,0x74,0x04,0x12,0x0c,0x9c} }, -{ 1,0x3415,0,{0x22} }, -{ 16,0x3416,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x11,0x90,0x78,0x1f,0x74,0x01,0xf0} }, -{ 16,0x3426,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x75,0x35,0x07,0xed,0xb4,0x06,0x11,0x90} }, -{ 16,0x3436,0,{0x78,0x1f,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x75,0x35,0x03} }, -{ 16,0x3446,0,{0x90,0x79,0x99,0xe0,0x14,0x60,0x11,0x14,0x60,0x5b,0x24,0x02,0x60,0x02,0xc1,0x06} }, -{ 16,0x3456,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0,0x14,0x70,0x3e,0xe4} }, -{ 16,0x3466,0,{0xff,0xef,0xc3,0x95,0x35,0x50,0x2f,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82} }, -{ 16,0x3476,0,{0xe4,0x34,0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3} }, -{ 16,0x3486,0,{0xe0,0xf9,0x90,0x00,0x01,0xed,0x12,0x0c,0x9c,0x90,0x78,0x20,0xe4,0x75,0xf0,0x0b} }, -{ 16,0x3496,0,{0x12,0x0c,0xf4,0x0f,0x80,0xcb,0x90,0x79,0x75,0x74,0x01,0xf0,0x22,0x90,0x7f,0xb4} }, -{ 16,0x34a6,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0,0x24,0xfe,0x60,0x63,0x14,0x70,0x02} }, -{ 16,0x34b6,0,{0xa1,0x64,0x14,0x70,0x02,0xa1,0xb2,0x24,0x03,0x60,0x02,0xa1,0xfe,0xe4,0xff,0xef} }, -{ 16,0x34c6,0,{0xc3,0x95,0x35,0x50,0x44,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34} }, -{ 16,0x34d6,0,{0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} }, -{ 16,0x34e6,0,{0x90,0x00,0x03,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82} }, -{ 16,0x34f6,0,{0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x04,0x12,0x0c,0x9c,0x90,0x78,0x20,0xe4} }, -{ 16,0x3506,0,{0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb6,0x90,0x79,0x75,0x74,0x01,0xf0,0x22} }, -{ 16,0x3516,0,{0xe4,0xff,0xef,0xc3,0x95,0x35,0x40,0x02,0xc1,0x0d,0xcd,0xee,0xcd,0x0e,0x74,0x21} }, -{ 16,0x3526,0,{0x2d,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3} }, -{ 16,0x3536,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x05,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e} }, -{ 16,0x3546,0,{0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x06,0x12,0x0c} }, -{ 16,0x3556,0,{0x9c,0x90,0x78,0x20,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0xe4,0xff} }, -{ 16,0x3566,0,{0xef,0xc3,0x95,0x35,0x40,0x02,0xc1,0x0d,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5} }, -{ 16,0x3576,0,{0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x3586,0,{0xa3,0xe0,0xf9,0x90,0x00,0x07,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e,0x74,0x21} }, -{ 16,0x3596,0,{0x2d,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x08,0x12,0x0c,0x9c,0x90} }, -{ 16,0x35a6,0,{0x78,0x20,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb4,0xe4,0xff,0xef,0xc3} }, -{ 16,0x35b6,0,{0x95,0x35,0x50,0x53,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0x79} }, -{ 16,0x35c6,0,{0xf5,0x83,0xe0,0xfd,0x90,0x78,0x1f,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} }, -{ 16,0x35d6,0,{0x00,0x09,0xed,0x12,0x0c,0x9c,0xcd,0xee,0xcd,0x0e,0x74,0x21,0x2d,0xf5,0x82,0xe4} }, -{ 16,0x35e6,0,{0x34,0x79,0xf5,0x83,0xe0,0x90,0x00,0x0a,0x12,0x0c,0x9c,0x90,0x78,0x20,0xe4,0x75} }, -{ 16,0x35f6,0,{0xf0,0x0b,0x12,0x0c,0xf4,0x0f,0x80,0xb6,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22} }, -{ 7,0x3606,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x360d,0,{0x22} }, -{ 16,0x360e,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x10,0x90,0x78,0x28,0x74,0x01,0xf0} }, -{ 16,0x361e,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x7f,0x07,0xed,0xb4,0x06,0x10,0x90,0x78} }, -{ 16,0x362e,0,{0x28,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x7f,0x03,0x90,0x78} }, -{ 16,0x363e,0,{0x28,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xfd,0x90,0x7f,0xea} }, -{ 16,0x364e,0,{0xe0,0x6d,0x60,0x12,0xee,0xc3,0x9f,0x50,0x0d,0x90,0x78,0x29,0xe4,0x75,0xf0,0x0b} }, -{ 16,0x365e,0,{0x12,0x0c,0xf4,0x0e,0x80,0xd8,0x90,0x7f,0xeb,0xe0,0x14,0x60,0x11,0x14,0x60,0x46} }, -{ 16,0x366e,0,{0x24,0x02,0x60,0x02,0xe1,0x9a,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f} }, -{ 16,0x367e,0,{0xe9,0xe0,0x24,0x7f,0x70,0x28,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01} }, -{ 16,0x368e,0,{0xf0,0x22,0x90,0x78,0x28,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01} }, -{ 16,0x369e,0,{0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x22,0x90,0x7f} }, -{ 16,0x36ae,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7e,0x60,0x40,0x14,0x60} }, -{ 16,0x36be,0,{0x6f,0x14,0x70,0x02,0xe1,0x60,0x24,0x03,0x60,0x02,0xe1,0x92,0xee,0x6f,0x70,0x08} }, -{ 16,0x36ce,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x28,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x36de,0,{0xa3,0xe0,0xf9,0x90,0x00,0x03,0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x90,0x00,0x04} }, -{ 16,0x36ee,0,{0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0xee,0x6f} }, -{ 16,0x36fe,0,{0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x28,0xe0,0xfb,0xa3} }, -{ 16,0x370e,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x05,0x12,0x0c,0x5d,0x90,0x7f,0x00,0xf0,0x90} }, -{ 16,0x371e,0,{0x00,0x06,0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22} }, -{ 16,0x372e,0,{0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x28,0xe0} }, -{ 16,0x373e,0,{0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x07,0x12,0x0c,0x5d,0x90,0x7f,0x00} }, -{ 16,0x374e,0,{0xf0,0x90,0x00,0x08,0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02} }, -{ 16,0x375e,0,{0xf0,0x22,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78} }, -{ 16,0x376e,0,{0x28,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x09,0x12,0x0c,0x5d,0x90} }, -{ 16,0x377e,0,{0x7f,0x00,0xf0,0x90,0x00,0x0a,0x12,0x0c,0x5d,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5} }, -{ 16,0x378e,0,{0x74,0x02,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0} }, -{ 3,0x379e,0,{0x44,0x01,0xf0} }, -{ 1,0x37a1,0,{0x22} }, -{ 16,0x37a2,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0} }, -{ 16,0x37b2,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef} }, -{ 16,0x37c2,0,{0xc0,0xe0,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0x90,0x79,0x83,0xe0,0x54} }, -{ 16,0x37d2,0,{0xfd,0xf0,0x12,0x2f,0xdf,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0} }, -{ 16,0x37e2,0,{0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0} }, -{ 8,0x37f2,0,{0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 6,0x37fa,0,{0x53,0x91,0xbf,0xd2,0x26,0x32} }, -{ 16,0x3800,0,{0xe4,0xfe,0x90,0x79,0x20,0xe0,0xfd,0xb4,0x05,0x10,0x90,0x78,0x22,0x74,0x01,0xf0} }, -{ 16,0x3810,0,{0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0x7f,0x07,0xed,0xb4,0x06,0x10,0x90,0x78} }, -{ 16,0x3820,0,{0x22,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xff,0xf0,0x7f,0x03,0x90,0x78} }, -{ 16,0x3830,0,{0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xfd,0x90,0x79,0x98} }, -{ 16,0x3840,0,{0xe0,0x6d,0x60,0x12,0xee,0xc3,0x9f,0x50,0x0d,0x90,0x78,0x23,0xe4,0x75,0xf0,0x0b} }, -{ 16,0x3850,0,{0x12,0x0c,0xf4,0x0e,0x80,0xd8,0x90,0x79,0x99,0xe0,0x14,0x60,0x11,0x14,0x60,0x48} }, -{ 16,0x3860,0,{0x24,0x02,0x60,0x02,0x21,0x85,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79} }, -{ 16,0x3870,0,{0x97,0xe0,0x14,0x70,0x2b,0xee,0x6f,0x70,0x09,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 16,0x3880,0,{0x80,0x17,0x90,0x79,0x21,0xe0,0xfd,0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3} }, -{ 16,0x3890,0,{0xe0,0xf9,0x90,0x00,0x01,0xed,0x12,0x0c,0x9c,0x90,0x79,0x75,0x74,0x01,0xf0,0x22} }, -{ 16,0x38a0,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x97,0xe0,0x24,0xfe,0x60,0x43} }, -{ 16,0x38b0,0,{0x14,0x60,0x6e,0x14,0x70,0x02,0x21,0x4f,0x24,0x03,0x60,0x02,0x21,0x7d,0xee,0x6f} }, -{ 16,0x38c0,0,{0x70,0x09,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x21,0x90,0x79,0x21,0xe0,0xfd} }, -{ 16,0x38d0,0,{0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x03,0xed,0x12} }, -{ 16,0x38e0,0,{0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x04,0x12,0x0c,0x9c,0x90,0x79,0x75,0x74} }, -{ 16,0x38f0,0,{0x01,0xf0,0x22,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90} }, -{ 16,0x3900,0,{0x79,0x21,0xe0,0xfd,0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} }, -{ 16,0x3910,0,{0x00,0x05,0xed,0x12,0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x06,0x12,0x0c,0x9c} }, -{ 16,0x3920,0,{0x22,0xee,0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x21} }, -{ 16,0x3930,0,{0xe0,0xfd,0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x07} }, -{ 16,0x3940,0,{0xed,0x12,0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x08,0x12,0x0c,0x9c,0x22,0xee} }, -{ 16,0x3950,0,{0x6f,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x79,0x21,0xe0,0xfe} }, -{ 16,0x3960,0,{0x90,0x78,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x09,0xee,0x12} }, -{ 16,0x3970,0,{0x0c,0x9c,0x90,0x79,0x22,0xe0,0x90,0x00,0x0a,0x12,0x0c,0x9c,0x22,0x90,0x7f,0xb4} }, -{ 12,0x3980,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x398c,0,{0x22} }, -{ 16,0x398d,0,{0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xe4,0x90,0x79,0x83,0xf0,0x12,0x2f,0xdf,0x90,0x7f} }, -{ 16,0x399d,0,{0xe0,0x74,0x90,0xf0,0x90,0x7f,0xe1,0x74,0x04,0xf0,0xe4,0x90,0x7f,0xdd,0xf0,0x90} }, -{ 16,0x39ad,0,{0x7f,0xa1,0xf0,0x53,0x8e,0xf8,0x75,0x88,0x05,0x75,0xb8,0x20,0x75,0xf8,0x01,0x43} }, -{ 16,0x39bd,0,{0x8e,0x30,0xf5,0xc8,0x75,0xca,0x7f,0x75,0xcb,0xf8,0x43,0xa8,0x20,0x90,0x79,0x74} }, -{ 16,0x39cd,0,{0x04,0xf0,0xc2,0x22,0xe4,0xf5,0x0f,0x90,0x79,0x78,0xf0,0xa3,0xf0,0x90,0x79,0x62} }, -{ 16,0x39dd,0,{0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x79,0x66,0xf0,0xa3,0xf0,0x90,0x79,0x7b,0xf0,0xa3} }, -{ 16,0x39ed,0,{0xf0,0x90,0x79,0x84,0xf0,0x90,0x79,0x7d,0xf0,0x90,0x79,0x75,0xf0,0xa3,0xf0,0xa3} }, -{ 16,0x39fd,0,{0xf0,0xc2,0x23,0xc2,0x24,0xc2,0x25,0xc2,0x26,0xc2,0x20,0x90,0x7f,0x9b,0xe0,0xf5} }, -{ 16,0x3a0d,0,{0x0a,0x54,0x20,0xf5,0x0a,0x70,0x06,0x90,0x79,0x7e,0xf0,0x80,0x06,0x90,0x79,0x7e} }, -{ 16,0x3a1d,0,{0x74,0x01,0xf0,0x90,0x7f,0x9b,0xe0,0xf5,0x0a,0x54,0x02,0xf5,0x0a,0x70,0x06,0x90} }, -{ 16,0x3a2d,0,{0x79,0x7f,0xf0,0x80,0x06,0x90,0x79,0x7f,0x74,0x01,0xf0,0x90,0x79,0x78,0x74,0x02} }, -{ 16,0x3a3d,0,{0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7f,0xe0,0xb4,0x01,0x09} }, -{ 16,0x3a4d,0,{0x90,0x79,0x79,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0} }, -{ 16,0x3a5d,0,{0x90,0x79,0x79,0xe0,0x90,0x79,0x84,0xf0,0x12,0x0b,0xa2,0x90,0x79,0x78,0x74,0x01} }, -{ 16,0x3a6d,0,{0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0x90,0x79,0x7e,0xe0,0xb4,0x01,0x09} }, -{ 16,0x3a7d,0,{0x90,0x79,0x79,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0} }, -{ 16,0x3a8d,0,{0x90,0x79,0x79,0xe0,0x90,0x79,0x7c,0xf0,0x12,0x0b,0xa2,0xe4,0x90,0x79,0x78,0xf0} }, -{ 16,0x3a9d,0,{0xa3,0x04,0xf0,0xe4,0x90,0x79,0x88,0xf0,0x12,0x0b,0xa2,0x90,0x7f,0xfc,0x74,0xdd} }, -{ 16,0x3aad,0,{0xf0,0x90,0x7f,0xff,0x74,0xff,0xf0,0x90,0x79,0x78,0x74,0x01,0xf0,0xa3,0xf0,0x12} }, -{ 16,0x3abd,0,{0x0b,0xa2,0xe4,0x90,0x79,0x7a,0xf0,0x90,0x79,0x83,0x04,0xf0,0x12,0x2f,0xdf,0xe4} }, -{ 16,0x3acd,0,{0x90,0x79,0x30,0xf0,0x90,0x79,0x85,0xf0,0xa3,0xf0,0xa3,0xf0,0x12,0x2e,0x94,0x90} }, -{ 16,0x3add,0,{0x79,0x2d,0x74,0x02,0xf0,0x90,0x79,0x88,0x14,0xf0,0xc2,0x2f,0xe4,0x90,0x79,0x68} }, -{ 16,0x3aed,0,{0xf0,0x90,0x79,0x8a,0xf0,0x90,0x79,0x6a,0xf0,0xa3,0xf0,0x75,0x13,0x08,0x75,0x14} }, -{ 16,0x3afd,0,{0x08,0xf5,0x16,0xf5,0x15,0xf5,0x17,0x90,0x79,0x8c,0xf0,0x90,0x79,0x8b,0xf0,0x22} }, -{ 16,0x3b0d,0,{0x7b,0x01,0x7a,0x78,0x79,0x58,0x90,0x78,0x03,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9} }, -{ 16,0x3b1d,0,{0xf0,0x74,0x40,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} }, -{ 16,0x3b2d,0,{0xf9,0x90,0x00,0x01,0x74,0x0a,0x12,0x0c,0x9c,0x90,0x00,0x02,0x12,0x0d,0xf6,0x00} }, -{ 16,0x3b3d,0,{0x00,0xbb,0x80,0x90,0x00,0x06,0x12,0x0d,0xf6,0x00,0x00,0xac,0x44,0x90,0x00,0x0a} }, -{ 16,0x3b4d,0,{0x12,0x0d,0xf6,0x00,0x01,0x77,0x00,0x90,0x78,0x04,0xe4,0x75,0xf0,0x0f,0x12,0x0c} }, -{ 16,0x3b5d,0,{0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x40,0x12,0x0c} }, -{ 16,0x3b6d,0,{0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74} }, -{ 16,0x3b7d,0,{0x8c,0x12,0x0c,0x9c,0x90,0x00,0x02,0x12,0x0d,0xf6,0x00,0x00,0xbb,0x80,0x90,0x00} }, -{ 16,0x3b8d,0,{0x06,0x12,0x0d,0xf6,0x00,0x00,0xac,0x44,0x90,0x00,0x0a,0x12,0x0d,0xf6,0x00,0x01} }, -{ 16,0x3b9d,0,{0x77,0x00,0x90,0x78,0x04,0xe4,0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0} }, -{ 16,0x3bad,0,{0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x40,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0} }, -{ 16,0x3bbd,0,{0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x8f,0x12,0x0c,0x9c,0x90} }, -{ 16,0x3bcd,0,{0x78,0x04,0xe4,0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0} }, -{ 16,0x3bdd,0,{0xfa,0xa3,0xe0,0xf9,0x74,0x41,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0} }, -{ 16,0x3bed,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x84,0x12,0x0c,0x9c,0x90,0x78,0x04,0xe4} }, -{ 16,0x3bfd,0,{0x75,0xf0,0x0f,0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} }, -{ 16,0x3c0d,0,{0xf9,0x74,0x61,0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0} }, -{ 16,0x3c1d,0,{0xf9,0x90,0x00,0x01,0x74,0x81,0x12,0x0c,0x9c,0x90,0x78,0x04,0xe4,0x75,0xf0,0x0f} }, -{ 16,0x3c2d,0,{0x12,0x0c,0xf4,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x74,0x61} }, -{ 16,0x3c3d,0,{0x12,0x0c,0x8a,0x90,0x78,0x03,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00} }, -{ 6,0x3c4d,0,{0x01,0x74,0x01,0x12,0x0c,0x9c} }, -{ 1,0x3c53,0,{0x22} }, -{ 16,0x3c54,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0} }, -{ 16,0x3c64,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef} }, -{ 2,0x3c74,0,{0xc0,0xe0} }, -{ 16,0x3c76,0,{0x90,0x7f,0xa2,0xe0,0xf5,0x0b,0x90,0x7f,0x74,0xe0,0x90,0x79,0x70,0xf0,0x90,0x7f} }, -{ 16,0x3c86,0,{0x75,0xe0,0x90,0x79,0x71,0xf0,0x90,0x79,0x83,0xe0,0xff,0xfe,0x54,0x02,0xfe,0x70} }, -{ 16,0x3c96,0,{0x0d,0xef,0x44,0x02,0xf0,0x12,0x2f,0xdf,0x90,0x79,0x74,0x74,0x01,0xf0,0xe5,0x0b} }, -{ 16,0x3ca6,0,{0x20,0xe2,0x28,0x90,0x79,0x70,0xe0,0xfe,0xa3,0xe0,0x7c,0x00,0x24,0x00,0xf5,0x11} }, -{ 16,0x3cb6,0,{0xec,0x3e,0xf5,0x10,0x90,0x79,0x82,0xe0,0xfd,0xae,0x10,0xaf,0x11,0x12,0x0c,0xbe} }, -{ 16,0x3cc6,0,{0x90,0x79,0x70,0xef,0xf0,0x90,0x79,0x89,0x74,0x01,0xf0,0x12,0x48,0x43,0x12,0x48} }, -{ 16,0x3cd6,0,{0x76,0x90,0x79,0x89,0xe0,0x64,0x01,0x70,0x32,0x12,0x41,0x08,0x90,0x79,0x89,0xe4} }, -{ 16,0x3ce6,0,{0xf0,0x90,0x7f,0x98,0xe0,0x44,0x40,0xf0,0x90,0x7f,0x9e,0xe0,0x44,0x40,0xf0,0x90} }, -{ 16,0x3cf6,0,{0x7f,0x95,0x74,0x80,0xf0,0x75,0xe8,0x01,0x12,0x09,0x32,0x75,0xe8,0x0d,0x90,0x7f} }, -{ 16,0x3d06,0,{0x95,0x74,0xc0,0xf0,0x75,0xe8,0x0d,0xd2,0x20,0x80,0x05,0x75,0xe8,0x01,0xc2,0x20} }, -{ 16,0x3d16,0,{0x20,0x20,0x2b,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0x75,0x0c,0x67,0x75,0x0d} }, -{ 16,0x3d26,0,{0x06,0x75,0x0e,0x0b,0xef,0xb4,0x02,0x09,0x75,0x0c,0x00,0x75,0x0d,0x00,0x75,0x0e} }, -{ 16,0x3d36,0,{0x0c,0xef,0xb4,0x03,0x09,0x75,0x0c,0x00,0x75,0x0d,0x00,0x75,0x0e,0x18,0x75,0xca} }, -{ 16,0x3d46,0,{0x6f,0x75,0xcb,0xfe,0xd2,0xca,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xf0} }, -{ 16,0x3d56,0,{0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0} }, -{ 16,0x3d66,0,{0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0} }, -{ 3,0x3d76,0,{0xd0,0xe0,0x32} }, -{ 16,0x3d79,0,{0x75,0x33,0x25,0x75,0x34,0x24,0x90,0x79,0x5c,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0} }, -{ 16,0x3d89,0,{0xa3,0x74,0xb2,0xf0,0x20,0x2f,0x02,0xc1,0x17,0xe4,0xf5,0x35,0x75,0x22,0x01,0x90} }, -{ 16,0x3d99,0,{0x79,0x5c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x04,0x12,0x0c,0x5d} }, -{ 16,0x3da9,0,{0xf5,0x36,0x75,0x35,0x06,0x74,0x42,0x25,0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83} }, -{ 16,0x3db9,0,{0xe5,0x36,0xf0,0x05,0x35,0xe5,0x35,0xb4,0x0c,0xeb,0xe5,0x35,0xc3,0x94,0x0d,0x40} }, -{ 16,0x3dc9,0,{0x02,0xc1,0x98,0xe5,0x22,0x64,0x01,0x60,0x02,0xc1,0x98,0x90,0x7f,0xa5,0xe0,0x44} }, -{ 16,0x3dd9,0,{0x80,0xf0,0x90,0x7f,0xa6,0xe5,0x33,0xf0,0x12,0x46,0xc0,0x74,0x4f,0x25,0x35,0xf5} }, -{ 16,0x3de9,0,{0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x74,0x42} }, -{ 16,0x3df9,0,{0x25,0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46} }, -{ 16,0x3e09,0,{0xc0,0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd,0x05,0x35,0x80,0xac,0xe4,0xf5} }, -{ 16,0x3e19,0,{0x35,0x75,0x22,0x01,0x90,0x79,0x5c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} }, -{ 16,0x3e29,0,{0x00,0x04,0x12,0x0c,0x5d,0xf5,0x36,0x75,0x35,0x06,0x74,0x35,0x25,0x35,0xf5,0x82} }, -{ 16,0x3e39,0,{0xe4,0x34,0x79,0xf5,0x83,0xe5,0x36,0xf0,0x05,0x35,0xe5,0x35,0xb4,0x0c,0xeb,0xe5} }, -{ 16,0x3e49,0,{0x35,0xc3,0x94,0x0d,0x50,0x49,0xe5,0x22,0x64,0x01,0x70,0x43,0x90,0x7f,0xa5,0xe0} }, -{ 16,0x3e59,0,{0x44,0x80,0xf0,0x90,0x7f,0xa6,0xe5,0x33,0xf0,0x12,0x46,0xc0,0x74,0x4f,0x25,0x35} }, -{ 16,0x3e69,0,{0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12,0x46,0xc0,0x74} }, -{ 16,0x3e79,0,{0x35,0x25,0x35,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xe0,0x90,0x7f,0xa6,0xf0,0x12} }, -{ 15,0x3e89,0,{0x46,0xc0,0x90,0x7f,0xa5,0x74,0x40,0xf0,0x12,0x0a,0xcd,0x05,0x35,0x80,0xb0} }, -{ 1,0x3e98,0,{0x22} }, -{ 16,0x3e99,0,{0x90,0x78,0x09,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0xb2,0xf0,0xe4,0xff} }, -{ 16,0x3ea9,0,{0xfe,0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xef,0x12,0x0c,0x8a} }, -{ 16,0x3eb9,0,{0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0xe4,0x12} }, -{ 16,0x3ec9,0,{0x0c,0x9c,0x90,0x00,0x02,0x74,0x15,0x12,0x0c,0x9c,0x90,0x00,0x03,0xe4,0x12,0x0c} }, -{ 16,0x3ed9,0,{0x9c,0x90,0x00,0x04,0x74,0xff,0x12,0x0c,0x9c,0x90,0x00,0x05,0xe4,0x12,0x0c,0x9c} }, -{ 16,0x3ee9,0,{0x90,0x00,0x06,0x74,0xc3,0x12,0x0c,0x9c,0x90,0x00,0x07,0xe4,0x12,0x0c,0x9c,0x90} }, -{ 16,0x3ef9,0,{0x00,0x08,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x09,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x0a} }, -{ 16,0x3f09,0,{0x74,0x01,0x12,0x0c,0x9c,0x90,0x78,0x0a,0xe4,0x75,0xf0,0x0b,0x12,0x0c,0xf4,0x0f} }, -{ 16,0x3f19,0,{0x0e,0xbe,0x07,0x8d,0x90,0x78,0x09,0x74,0x01,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74} }, -{ 16,0x3f29,0,{0xff,0xf0,0xe4,0xff,0xfe,0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} }, -{ 16,0x3f39,0,{0xef,0x12,0x0c,0x8a,0x90,0x78,0x09,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90} }, -{ 16,0x3f49,0,{0x00,0x01,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x02,0x74,0x15,0x12,0x0c,0x9c,0x90,0x00} }, -{ 16,0x3f59,0,{0x03,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x04,0x74,0x80,0x12,0x0c,0x9c,0x90,0x00,0x05} }, -{ 16,0x3f69,0,{0xe4,0x12,0x0c,0x9c,0x90,0x00,0x06,0x74,0xc3,0x12,0x0c,0x9c,0x90,0x00,0x07,0xe4} }, -{ 16,0x3f79,0,{0x12,0x0c,0x9c,0x90,0x00,0x08,0xe4,0x12,0x0c,0x9c,0x90,0x00,0x09,0xe4,0x12,0x0c} }, -{ 16,0x3f89,0,{0x9c,0x90,0x00,0x0a,0x74,0x01,0x12,0x0c,0x9c,0x90,0x78,0x0a,0xe4,0x75,0xf0,0x0b} }, -{ 8,0x3f99,0,{0x12,0x0c,0xf4,0x0f,0x0e,0xbe,0x03,0x8d} }, -{ 1,0x3fa1,0,{0x22} }, -{ 16,0x3fa2,0,{0xe4,0xfe,0x75,0x3d,0xff,0x75,0x3e,0x05,0x75,0x3f,0x12,0xab,0x3d,0xaa,0x3e,0xa9} }, -{ 16,0x3fb2,0,{0x3f,0x90,0x00,0x01,0x12,0x0c,0x5d,0x64,0x02,0x70,0x2f,0xcd,0xee,0xcd,0x0e,0xed} }, -{ 16,0x3fc2,0,{0x6f,0x70,0x01,0x22,0x90,0x00,0x02,0x12,0x0d,0x0a,0x85,0xf0,0x3b,0xf5,0x3c,0x62} }, -{ 16,0x3fd2,0,{0x3b,0xe5,0x3b,0x62,0x3c,0xe5,0x3c,0x62,0x3b,0x29,0xfd,0xe5,0x3b,0x3a,0xc9,0xed} }, -{ 16,0x3fe2,0,{0xc9,0x75,0x3d,0xff,0xf5,0x3e,0x89,0x3f,0x80,0xc1,0x7b,0x00,0x7a,0x00,0x79,0x00} }, -{ 1,0x3ff2,0,{0x22} }, -{ 9,0x3ff3,0,{0x53,0xd8,0xef,0x43,0xd8,0x20,0xc2,0x2d,0x32} }, -{ 4,0x3ffc,0,{0x53,0x91,0xdf,0x32} }, -{ 16,0x4000,0,{0x90,0x79,0x87,0xe0,0xb4,0x01,0x1d,0x90,0x79,0x85,0xe0,0xb4,0x01,0x03,0x12,0x42} }, -{ 16,0x4010,0,{0xaa,0x90,0x79,0x86,0xe0,0xb4,0x01,0x03,0x12,0x18,0x00,0xe4,0x90,0x79,0x85,0xf0} }, -{ 16,0x4020,0,{0xa3,0xf0,0xa3,0xf0,0x12,0x2e,0x94,0x90,0x7f,0x9b,0xe0,0xf5,0x0a,0x54,0x02,0xf5} }, -{ 16,0x4030,0,{0x0a,0x70,0x04,0x90,0x79,0x7f,0xf0,0x90,0x7f,0x9b,0xe0,0xf5,0x0a,0x54,0x02,0xff} }, -{ 16,0x4040,0,{0xf5,0x0a,0xbf,0x02,0x06,0x90,0x79,0x7f,0x74,0x01,0xf0,0x90,0x7f,0x9b,0xe0,0xf5} }, -{ 16,0x4050,0,{0x0a,0x54,0x20,0xf5,0x0a,0x70,0x04,0x90,0x79,0x7e,0xf0,0x90,0x7f,0x9b,0xe0,0xf5} }, -{ 16,0x4060,0,{0x0a,0x54,0x20,0xff,0xf5,0x0a,0xbf,0x20,0x06,0x90,0x79,0x7e,0x74,0x01,0xf0,0x90} }, -{ 16,0x4070,0,{0x79,0x7f,0xe0,0xff,0x90,0x79,0x81,0xe0,0x6f,0x60,0x38,0x90,0x79,0x78,0x74,0x02} }, -{ 16,0x4080,0,{0xf0,0x90,0x79,0x84,0xe0,0x90,0x79,0x79,0xf0,0xef,0xb4,0x01,0x06,0xe0,0x54,0xfe} }, -{ 16,0x4090,0,{0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x44,0x01,0xf0,0x90,0x79,0x79,0xe0,0x90,0x79} }, -{ 16,0x40a0,0,{0x84,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0xe5,0x12,0x60} }, -{ 16,0x40b0,0,{0x02,0xd2,0xaf,0x90,0x79,0x7e,0xe0,0xff,0x90,0x79,0x80,0xe0,0x6f,0x60,0x38,0x90} }, -{ 16,0x40c0,0,{0x79,0x78,0x74,0x01,0xf0,0x90,0x79,0x7c,0xe0,0x90,0x79,0x79,0xf0,0xef,0xb4,0x01} }, -{ 16,0x40d0,0,{0x06,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x79,0x79,0xe0,0x54,0xfb,0xf0,0x90,0x79} }, -{ 16,0x40e0,0,{0x79,0xe0,0x90,0x79,0x7c,0xf0,0xa2,0xaf,0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b} }, -{ 16,0x40f0,0,{0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x90,0x79,0x7f,0xe0,0x90,0x79,0x81,0xf0,0x90} }, -{ 8,0x4100,0,{0x79,0x7e,0xe0,0x90,0x79,0x80,0xf0,0x22} }, -{ 16,0x4108,0,{0x90,0x79,0x2d,0xe0,0x64,0x01,0x70,0x35,0x90,0x79,0x70,0xe0,0xff,0xd3,0x94,0x2d} }, -{ 16,0x4118,0,{0x40,0x2b,0x90,0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0,0xe0,0xd3} }, -{ 16,0x4128,0,{0x94,0x0f,0x40,0x19,0xe4,0xf0,0xef,0xd3,0x94,0x31,0x40,0x08,0x90,0x79,0x2d,0x74} }, -{ 16,0x4138,0,{0x03,0xf0,0x80,0x06,0x90,0x79,0x2d,0x74,0x02,0xf0,0x12,0x10,0x00,0x90,0x79,0x2d} }, -{ 16,0x4148,0,{0xe0,0xb4,0x02,0x2c,0x90,0x79,0x70,0xe0,0xff,0xc3,0x94,0x2f,0x50,0x22,0xef,0xd3} }, -{ 16,0x4158,0,{0x94,0x2a,0x40,0x1c,0x90,0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0} }, -{ 16,0x4168,0,{0xe0,0xd3,0x94,0x0f,0x40,0x0a,0xe4,0xf0,0x90,0x79,0x2d,0x04,0xf0,0x12,0x10,0x00} }, -{ 16,0x4178,0,{0x90,0x79,0x2d,0xe0,0xb4,0x02,0x26,0x90,0x79,0x70,0xe0,0xd3,0x94,0x31,0x40,0x1d} }, -{ 16,0x4188,0,{0x90,0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f} }, -{ 16,0x4198,0,{0x40,0x0b,0xe4,0xf0,0x90,0x79,0x2d,0x74,0x03,0xf0,0x12,0x10,0x00,0x90,0x79,0x2d} }, -{ 16,0x41a8,0,{0xe0,0x64,0x03,0x70,0x3f,0x90,0x79,0x70,0xe0,0xff,0xc3,0x94,0x5f,0x50,0x35,0x90} }, -{ 16,0x41b8,0,{0x79,0x69,0x74,0x01,0xf0,0x90,0x79,0x68,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f,0x40} }, -{ 16,0x41c8,0,{0x23,0xe4,0xf0,0xef,0xc3,0x94,0x2f,0x50,0x0c,0xef,0xd3,0x94,0x2a,0x40,0x06,0x90} }, -{ 16,0x41d8,0,{0x79,0x2d,0x74,0x01,0xf0,0xef,0xd3,0x94,0x2f,0x40,0x06,0x90,0x79,0x2d,0x74,0x02} }, -{ 16,0x41e8,0,{0xf0,0x12,0x10,0x00,0x90,0x79,0x69,0xe0,0x70,0x05,0x90,0x79,0x68,0xf0,0x22,0xe4} }, -{ 5,0x41f8,0,{0x90,0x79,0x69,0xf0,0x22} }, -{ 16,0x41fd,0,{0x7b,0x01,0x7a,0x78,0x79,0x4c,0x90,0x78,0x06,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9} }, -{ 16,0x420d,0,{0xf0,0xe4,0x12,0x0c,0x8a,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9} }, -{ 16,0x421d,0,{0x90,0x00,0x01,0x74,0x01,0x12,0x0c,0x9c,0x90,0x78,0x07,0xe4,0x75,0xf0,0x03,0x12} }, -{ 16,0x422d,0,{0x0c,0xf4,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xe4,0x12,0x0c} }, -{ 16,0x423d,0,{0x8a,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74} }, -{ 16,0x424d,0,{0x02,0x12,0x0c,0x9c,0x90,0x78,0x07,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78} }, -{ 16,0x425d,0,{0x06,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xe4,0x12,0x0c,0x8a,0x90,0x78,0x06} }, -{ 16,0x426d,0,{0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x03,0x12,0x0c,0x9c} }, -{ 16,0x427d,0,{0x90,0x78,0x07,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x90,0x78,0x06,0xe0,0xfb,0xa3} }, -{ 16,0x428d,0,{0xe0,0xfa,0xa3,0xe0,0xf9,0xe4,0x12,0x0c,0x8a,0x90,0x78,0x06,0xe0,0xfb,0xa3,0xe0} }, -{ 12,0x429d,0,{0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x74,0x04,0x12,0x0c,0x9c} }, -{ 1,0x42a9,0,{0x22} }, -{ 16,0x42aa,0,{0xe4,0xff,0xfe,0x7b,0x01,0x90,0x78,0x0c,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74} }, -{ 16,0x42ba,0,{0x2b,0xf0,0x90,0x78,0x0c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02} }, -{ 16,0x42ca,0,{0x12,0x0c,0x5d,0xfd,0x90,0x79,0x9a,0xe0,0x6d,0x60,0x13,0xef,0xc3,0x94,0x05,0x50} }, -{ 16,0x42da,0,{0x0d,0x0f,0x90,0x78,0x0d,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd4,0x8d,0x33} }, -{ 16,0x42ea,0,{0x90,0x78,0x0c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x01,0x12,0x0c} }, -{ 16,0x42fa,0,{0x5d,0xfd,0x90,0x79,0x9b,0xe0,0xfc,0x6d,0x60,0x13,0xee,0xc3,0x94,0x0b,0x50,0x0d} }, -{ 16,0x430a,0,{0x0e,0x90,0x78,0x0d,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x80,0xd3,0x8c,0x34,0xef} }, -{ 16,0x431a,0,{0x64,0x05,0x60,0x03,0xbe,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90} }, -{ 16,0x432a,0,{0x78,0x0c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x0c,0x44,0xff,0x24,0xf0} }, -{ 16,0x433a,0,{0x60,0x08,0x24,0x0e,0x70,0x0e,0x12,0x49,0x4d,0x22,0x90,0x79,0x20,0xe5,0x34,0xf0} }, -{ 11,0x434a,0,{0x12,0x1b,0x2a,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0} }, -{ 1,0x4355,0,{0x22} }, -{ 12,0x4356,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x3f,0x02,0x43,0x9d} }, -{ 16,0x4362,0,{0x02,0x48,0xa9,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2} }, -{ 16,0x4372,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33} }, -{ 16,0x4382,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf} }, -{ 16,0x4392,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x46,0x61,0xe4,0x7e} }, -{ 16,0x43a2,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93} }, -{ 16,0x43b2,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3} }, -{ 16,0x43c2,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca} }, -{ 16,0x43d2,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe} }, -{ 16,0x43e2,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0} }, -{ 16,0x43f2,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef} }, -{ 16,0x4402,0,{0xc0,0xe0,0xc2,0xca,0xc2,0xcf,0x90,0x79,0x7a,0xe0,0xb4,0x01,0x1f,0x12,0x4b,0xae} }, -{ 16,0x4412,0,{0x12,0x47,0x58,0x53,0xa8,0xa0,0x90,0x7f,0xae,0xe4,0xf0,0x12,0x07,0xaa,0x12,0x4b} }, -{ 16,0x4422,0,{0xb7,0x90,0x7f,0xae,0x74,0x1f,0xf0,0x43,0xa8,0x05,0x80,0x03,0x53,0xa8,0xa0,0x53} }, -{ 16,0x4432,0,{0xa8,0xfa,0x75,0xe8,0x01,0x12,0x09,0x15,0x75,0xe8,0x0d,0x43,0xa8,0x05,0xd0,0xe0} }, -{ 16,0x4442,0,{0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa} }, -{ 16,0x4452,0,{0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0} }, -{ 1,0x4462,0,{0x32} }, -{ 16,0x4463,0,{0x90,0x7f,0xec,0xe0,0xf5,0x09,0x14,0x60,0x1d,0x14,0x60,0x2a,0x14,0x60,0x37,0x14} }, -{ 16,0x4473,0,{0x60,0x44,0x24,0x04,0x70,0x50,0x90,0x79,0x62,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} }, -{ 16,0x4483,0,{0xb5,0x74,0x01,0xf0,0x80,0x47,0x90,0x79,0x63,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} }, -{ 16,0x4493,0,{0xb5,0x74,0x01,0xf0,0x80,0x37,0x90,0x79,0x64,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} }, -{ 16,0x44a3,0,{0xb5,0x74,0x01,0xf0,0x80,0x27,0x90,0x79,0x66,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} }, -{ 16,0x44b3,0,{0xb5,0x74,0x01,0xf0,0x80,0x17,0x90,0x79,0x67,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f} }, -{ 15,0x44c3,0,{0xb5,0x74,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xd3,0x22} }, -{ 4,0x44d2,0,{0x8d,0x36,0x8b,0x37} }, -{ 16,0x44d6,0,{0x12,0x3f,0xa2,0xea,0x49,0x60,0x57,0x12,0x0c,0x44,0x7e,0x00,0x29,0xff,0xee,0x3a} }, -{ 16,0x44e6,0,{0xc9,0xef,0xc9,0x75,0x38,0xff,0xf5,0x39,0x89,0x3a,0xab,0x38,0xaa,0x39,0xa9,0x3a} }, -{ 16,0x44f6,0,{0x90,0x00,0x01,0x12,0x0c,0x5d,0xff,0x64,0x04,0x60,0x05,0xef,0x64,0x05,0x70,0x2e} }, -{ 16,0x4506,0,{0xef,0xb4,0x04,0x15,0x90,0x00,0x02,0x12,0x0c,0x5d,0x65,0x36,0x70,0x0b,0x90,0x00} }, -{ 16,0x4516,0,{0x03,0x12,0x0c,0x5d,0x65,0x37,0x70,0x01,0x22,0x12,0x0c,0x44,0x7e,0x00,0x29,0xff} }, -{ 16,0x4526,0,{0xee,0x3a,0xc9,0xef,0xc9,0x75,0x38,0xff,0xf5,0x39,0x89,0x3a,0x80,0xbc,0x7b,0x00} }, -{ 4,0x4536,0,{0x7a,0x00,0x79,0x00} }, -{ 1,0x453a,0,{0x22} }, -{ 16,0x453b,0,{0xe4,0xff,0x7b,0x01,0x90,0x78,0x1c,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0x4c} }, -{ 16,0x454b,0,{0xf0,0x90,0x78,0x1c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12} }, -{ 16,0x455b,0,{0x0c,0x5d,0xfe,0x90,0x7f,0xec,0xe0,0x6e,0x60,0x13,0xef,0xc3,0x94,0x04,0x50,0x0d} }, -{ 16,0x456b,0,{0x90,0x78,0x1d,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x0f,0x80,0xd4,0xbf,0x04,0x09} }, -{ 16,0x457b,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x14,0x90,0x79,0x21,0xe0,0xff,0x90,0x78} }, -{ 16,0x458b,0,{0x1c,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xef,0x12,0x0c,0x8a,0x90,0x7f,0xc5} }, -{ 3,0x459b,0,{0x74,0x01,0xf0} }, -{ 1,0x459e,0,{0x22} }, -{ 14,0x459f,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xee,0xc0,0xe0,0xef,0xc0,0xe0} }, -{ 16,0x45ad,0,{0x90,0x79,0x85,0xe0,0x64,0x01,0x60,0x05,0xa3,0xe0,0xb4,0x01,0x2d,0x90,0x79,0x87} }, -{ 16,0x45bd,0,{0x74,0x01,0xf0,0xe4,0xff,0x90,0x7f,0xc5,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x1b,0x74} }, -{ 16,0x45cd,0,{0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xfe,0x74,0x21,0x2f,0xf5,0x82} }, -{ 16,0x45dd,0,{0xe4,0x34,0x79,0xf5,0x83,0xee,0xf0,0x0f,0x80,0xdb,0x53,0x91,0xef,0x90,0x7f,0xaa} }, -{ 4,0x45ed,0,{0xe0,0x44,0x01,0xf0} }, -{ 15,0x45f1,0,{0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4600,0,{0xe4,0xff,0x7b,0x01,0x90,0x78,0x19,0x04,0xf0,0xa3,0x74,0x78,0xf0,0xa3,0x74,0x4c} }, -{ 16,0x4610,0,{0xf0,0x90,0x78,0x19,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x90,0x00,0x02,0x12} }, -{ 16,0x4620,0,{0x0c,0x5d,0xfe,0x90,0x7f,0xec,0xe0,0x6e,0x60,0x13,0xef,0xc3,0x94,0x04,0x50,0x0d} }, -{ 16,0x4630,0,{0x90,0x78,0x1a,0xe4,0x75,0xf0,0x03,0x12,0x0c,0xf4,0x0f,0x80,0xd4,0xbf,0x04,0x08} }, -{ 16,0x4640,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x78,0x19,0xe0,0xfb,0xa3,0xe0,0xfa} }, -{ 16,0x4650,0,{0xa3,0xe0,0xf9,0x12,0x0c,0x44,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} }, -{ 1,0x4660,0,{0x22} }, -{ 16,0x4661,0,{0x01,0x18,0x02,0x01,0x19,0x0a,0x01,0x1c,0x00,0xc1,0x28,0xc1,0x29,0x01,0x1f,0x01} }, -{ 15,0x4671,0,{0x44,0x79,0x9f,0x00,0x00,0x00,0x00,0x41,0x79,0xa3,0x00,0x41,0x79,0xa4,0x00} }, -{ 4,0x4680,0,{0x41,0x79,0x89,0x00} }, -{ 16,0x4684,0,{0x01,0x22,0x01,0x41,0x79,0x31,0xff,0x41,0x79,0x34,0x00,0x4d,0x79,0x35,0x3f,0x3f} }, -{ 16,0x4694,0,{0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4d,0x79,0x42,0x3f,0x3f} }, -{ 16,0x46a4,0,{0x06,0x08,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4d,0x79,0x4f,0x0a,0x0a} }, -{ 11,0x46b4,0,{0x09,0x00,0x01,0x09,0x02,0x03,0x04,0x05,0x06,0x07,0x08} }, -{ 1,0x46bf,0,{0x00} }, -{ 16,0x46c0,0,{0x12,0x0a,0xcd,0x90,0x7f,0xa5,0xe0,0xf5,0x21,0xe5,0x21,0x54,0x01,0xf5,0x21,0x64} }, -{ 16,0x46d0,0,{0x01,0x60,0x28,0xe5,0x22,0x64,0x01,0x70,0x22,0x90,0x7f,0xa5,0xe0,0xf5,0x21,0x54} }, -{ 16,0x46e0,0,{0x02,0xf5,0x21,0x70,0x03,0x75,0x22,0x01,0x90,0x7f,0xa5,0xe0,0xf5,0x21,0x54,0x04} }, -{ 12,0x46f0,0,{0xff,0xf5,0x21,0xbf,0x04,0xd3,0x75,0x22,0x01,0x80,0xce,0x22} }, -{ 4,0x46fc,0,{0x53,0xd8,0xf7,0x32} }, -{ 16,0x4700,0,{0x02,0x49,0xfa,0x00,0x02,0x3c,0x54,0x00,0x02,0x17,0xe4,0x00,0x02,0x4a,0x12,0x00} }, -{ 16,0x4710,0,{0x02,0x37,0xa2,0x00,0x02,0x47,0xff,0x00,0x02,0x4a,0x41,0x00,0x02,0x45,0x9f,0x00} }, -{ 16,0x4720,0,{0x02,0x49,0x8e,0x00,0x02,0x49,0xab,0x00,0x02,0x4a,0x58,0x00,0x02,0x4a,0x6f,0x00} }, -{ 16,0x4730,0,{0x02,0x4a,0x86,0x00,0x02,0x4a,0x9d,0x00,0x02,0x4a,0xb4,0x00,0x02,0x4a,0xcb,0x00} }, -{ 16,0x4740,0,{0x02,0x4a,0xe2,0x00,0x02,0x4a,0xf9,0x00,0x02,0x4b,0x10,0x00,0x02,0x4b,0x27,0x00} }, -{ 8,0x4750,0,{0x02,0x4b,0x3e,0x00,0x02,0x4b,0x55,0x00} }, -{ 16,0x4758,0,{0xe5,0x18,0x70,0x14,0x90,0x79,0x8c,0xe0,0x04,0xf0,0x90,0x79,0x8b,0xe0,0xc3,0x94} }, -{ 16,0x4768,0,{0x00,0x40,0x15,0xe0,0x14,0xf0,0x80,0x10,0x90,0x79,0x8b,0xe0,0x04,0xf0,0xa3,0xe0} }, -{ 16,0x4778,0,{0xc3,0x94,0x00,0x40,0x03,0xe0,0x14,0xf0,0x90,0x79,0x8b,0xe0,0xd3,0x94,0x14,0x40} }, -{ 16,0x4788,0,{0x04,0xe4,0xf5,0x18,0xf0,0x90,0x79,0x8c,0xe0,0xd3,0x94,0x14,0x40,0x05,0x75,0x18} }, -{ 4,0x4798,0,{0x01,0xe4,0xf0,0x22} }, -{ 16,0x479c,0,{0x90,0x7f,0xd7,0xe0,0xf5,0x33,0x90,0x7f,0xec,0xe0,0xf5,0x09,0x14,0x60,0x11,0x14} }, -{ 16,0x47ac,0,{0x60,0x1b,0x24,0x02,0x70,0x24,0x90,0x7f,0xea,0xe0,0x90,0x79,0x62,0xf0,0x80,0x21} }, -{ 16,0x47bc,0,{0x90,0x7f,0xea,0xe0,0x90,0x79,0x63,0xf0,0x12,0x10,0x00,0x80,0x14,0x90,0x7f,0xea} }, -{ 16,0x47cc,0,{0xe0,0x90,0x79,0x64,0xf0,0x12,0x28,0x01,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01} }, -{ 2,0x47dc,0,{0xf0,0xd3} }, -{ 1,0x47de,0,{0x22} }, -{ 16,0x47df,0,{0x90,0x79,0x78,0x74,0x04,0xf0,0x90,0x79,0x33,0xe0,0x90,0x79,0x79,0xf0,0xa2,0xaf} }, -{ 16,0x47ef,0,{0xe4,0x33,0xf5,0x12,0xc2,0xaf,0x12,0x0b,0xa2,0xe5,0x12,0x60,0x02,0xd2,0xaf,0x22} }, -{ 1,0x47ff,0,{0x32} }, -{ 2,0x4800,0,{0x8f,0x36} }, -{ 16,0x4802,0,{0xe4,0xf5,0x37,0x75,0x38,0xff,0x75,0x39,0x07,0x75,0x3a,0x01,0xab,0x38,0xaa,0x39} }, -{ 16,0x4812,0,{0xa9,0x3a,0x90,0x00,0x01,0x12,0x0c,0x5d,0xb4,0x03,0x1f,0xaf,0x37,0x05,0x37,0xef} }, -{ 16,0x4822,0,{0x65,0x36,0x70,0x01,0x22,0x12,0x0c,0x44,0x7e,0x00,0x29,0xff,0xee,0x3a,0xc9,0xef} }, -{ 16,0x4832,0,{0xc9,0x75,0x38,0xff,0xf5,0x39,0x89,0x3a,0x80,0xd2,0x7b,0x00,0x7a,0x00,0x79,0x00} }, -{ 1,0x4842,0,{0x22} }, -{ 16,0x4843,0,{0x30,0x26,0x2f,0xc2,0x26,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0xe4,0xf5,0x0c} }, -{ 16,0x4853,0,{0x75,0x0d,0xf8,0x75,0x0e,0x0a,0xef,0xb4,0x02,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0xf0} }, -{ 16,0x4863,0,{0x75,0x0e,0x0b,0xef,0xb4,0x03,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0xf8,0x75,0x0e,0x17} }, -{ 3,0x4873,0,{0xd2,0x22,0x22} }, -{ 16,0x4876,0,{0x30,0x25,0x2f,0xc2,0x25,0x90,0x79,0x2d,0xe0,0xff,0xb4,0x01,0x09,0x75,0x0c,0xc0} }, -{ 16,0x4886,0,{0x75,0x0d,0x14,0x75,0x0e,0x0b,0xef,0xb4,0x02,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0x10} }, -{ 16,0x4896,0,{0x75,0x0e,0x0c,0xef,0xb4,0x03,0x09,0xe4,0xf5,0x0c,0x75,0x0d,0x18,0x75,0x0e,0x18} }, -{ 3,0x48a6,0,{0xd2,0x22,0x22} }, -{ 16,0x48a9,0,{0xe4,0xf5,0x32,0x12,0x0f,0x50,0x20,0x2e,0x10,0xe5,0x32,0xc3,0x94,0x02,0x50,0x09} }, -{ 16,0x48b9,0,{0x05,0x32,0xd2,0x30,0x12,0x49,0x05,0x80,0xed,0x30,0x2e,0x05,0x12,0x14,0x57,0xc2} }, -{ 15,0x48c9,0,{0x2e,0x30,0x2d,0x06,0x12,0x07,0x9a,0x12,0x48,0xd9,0x12,0x40,0x00,0x80,0xea} }, -{ 1,0x48d8,0,{0x22} }, -{ 16,0x48d9,0,{0x90,0x7f,0xd6,0xe0,0xf5,0x1d,0x54,0x80,0xf5,0x1d,0x64,0x80,0x70,0x1d,0xc2,0xaf} }, -{ 16,0x48e9,0,{0xe0,0x44,0x80,0xf0,0xe0,0x44,0x01,0xf0,0x7f,0x0c,0x7e,0x00,0x12,0x4b,0x6c,0x90} }, -{ 12,0x48f9,0,{0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x53,0x87,0xfe,0xd2,0xaf,0x22} }, -{ 16,0x4905,0,{0x90,0x7f,0xd6,0xe0,0x54,0xfb,0xf0,0xe0,0x44,0x08,0xf0,0x30,0x30,0x04,0xe0,0x44} }, -{ 16,0x4915,0,{0x02,0xf0,0x7f,0xdc,0x7e,0x05,0x12,0x4b,0x6c,0x90,0x7f,0xd6,0xe0,0x54,0xf7,0xf0} }, -{ 5,0x4925,0,{0xe0,0x44,0x04,0xf0,0x22} }, -{ 16,0x492a,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x14,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x04,0x12} }, -{ 16,0x493a,0,{0x46,0x00,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44} }, -{ 3,0x494a,0,{0x01,0xf0,0x22} }, -{ 16,0x494d,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x13,0x90,0x7f,0xe9,0xe0,0x14,0x70,0x04,0x12,0x45} }, -{ 16,0x495d,0,{0x3b,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01} }, -{ 2,0x496d,0,{0xf0,0x22} }, -{ 16,0x496f,0,{0xe4,0xff,0x74,0xe8,0x2f,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xe0,0xfe,0x74,0x96} }, -{ 14,0x497f,0,{0x2f,0xf5,0x82,0xe4,0x34,0x79,0xf5,0x83,0xee,0xf0,0x0f,0xbf,0x08,0xe4} }, -{ 1,0x498d,0,{0x22} }, -{ 16,0x498e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x02,0xf0} }, -{ 13,0x499e,0,{0x90,0x7f,0xb7,0x74,0x03,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x49ab,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x02,0xf0} }, -{ 13,0x49bb,0,{0x90,0x7f,0xc7,0x74,0x03,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x49c8,0,{0x90,0x7f,0xd6,0xe0,0x30,0xe7,0x12,0xe0,0x44,0x01,0xf0,0x7f,0x14,0x7e,0x00,0x12} }, -{ 10,0x49d8,0,{0x4b,0x6c,0x90,0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x22} }, -{ 16,0x49e2,0,{0xe4,0xf5,0x1a,0x75,0x1b,0x01,0x90,0x79,0x91,0x04,0xf0,0xa3,0xf0,0xe4,0xa3,0xf0} }, -{ 8,0x49f2,0,{0xa3,0x74,0x0a,0xf0,0xe4,0xa3,0xf0,0x22} }, -{ 16,0x49fa,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x2e,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01} }, -{ 8,0x4a0a,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4a12,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x2d,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08} }, -{ 8,0x4a22,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4a2a,0,{0x90,0x7f,0xea,0xe0,0xf5,0x08,0xe4,0x90,0x79,0x62,0xf0,0xa3,0xf0,0xa3,0xf0,0x90} }, -{ 7,0x4a3a,0,{0x79,0x66,0xf0,0xa3,0xf0,0xd3,0x22} }, -{ 16,0x4a41,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x01,0xf0} }, -{ 7,0x4a51,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4a58,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x04,0xf0} }, -{ 7,0x4a68,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4a6f,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x04,0xf0} }, -{ 7,0x4a7f,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4a86,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x08,0xf0} }, -{ 7,0x4a96,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4a9d,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x08,0xf0} }, -{ 7,0x4aad,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4ab4,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x10,0xf0} }, -{ 7,0x4ac4,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4acb,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x10,0xf0} }, -{ 7,0x4adb,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4ae2,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x20,0xf0} }, -{ 7,0x4af2,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4af9,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x20,0xf0} }, -{ 7,0x4b09,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4b10,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x40,0xf0} }, -{ 7,0x4b20,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4b27,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x40,0xf0} }, -{ 7,0x4b37,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4b3e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x80,0xf0} }, -{ 7,0x4b4e,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4b55,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x80,0xf0} }, -{ 7,0x4b65,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x4b6c,0,{0x8e,0x33,0x8f,0x34,0xe5,0x34,0x15,0x34,0xae,0x33,0x70,0x02,0x15,0x33,0x4e,0x60} }, -{ 7,0x4b7c,0,{0x05,0x12,0x07,0x89,0x80,0xee,0x22} }, -{ 15,0x4b83,0,{0x90,0x7f,0xea,0xe0,0xb4,0xff,0x04,0x12,0x30,0x00,0x22,0x12,0x36,0x0e,0x22} }, -{ 14,0x4b92,0,{0xc0,0xe0,0xc2,0x8b,0xd2,0x24,0x30,0x23,0x02,0xc2,0x23,0xd0,0xe0,0x32} }, -{ 14,0x4ba0,0,{0x90,0x7f,0x00,0xe5,0x08,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0xd3,0x22} }, -{ 9,0x4bae,0,{0x30,0x24,0x05,0xc2,0x24,0x75,0x18,0x01,0x22} }, -{ 9,0x4bb7,0,{0x30,0x23,0x05,0xc2,0x23,0xe4,0xf5,0x18,0x22} }, -{ 7,0x4bc0,0,{0x53,0xc0,0xfe,0x53,0xc0,0xfd,0x32} }, -{ 6,0x4bc7,0,{0x53,0x91,0x7f,0xd2,0x25,0x32} }, -{ 5,0x4bcd,0,{0xc2,0x89,0xd2,0x23,0x32} }, -{ 3,0x4bd2,0,{0xc2,0x8d,0x32} }, -{ 3,0x4bd5,0,{0xc2,0x8f,0x32} }, -{ 2,0x4bd8,0,{0xd3,0x22} }, -{ 2,0x4bda,0,{0xd3,0x22} }, -{ 2,0x4bdc,0,{0xd3,0x22} }, -{ 2,0x4bde,0,{0xd3,0x22} }, -{ 2,0x4be0,0,{0xd3,0x22} }, -{ 2,0x4be2,0,{0xd3,0x22} }, -{ 2,0x4be4,0,{0xc3,0x22} }, -{ 1,0x4be6,0,{0x22} }, -{ 0,0x0000,1,{0 }} -}; -/* -VERSION=1.0.2.916 -DATE=12.02.2002 -*/ -/* - * This firmware is for the Emagic EMI 2|6 Audio Interface - * - * The firmware contained herein is Copyright (c) 1999-2002 Emagic - * as an unpublished work. This notice does not imply unrestricted - * or public access to this firmware which is a trade secret of Emagic, - * and which may not be reproduced, used, sold or transferred to - * any third party without Emagic's written consent. All Rights Reserved. - * - * This firmware may not be modified and may only be used with the - * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of - * any driver which includes this firmware, in whole or in part, - * requires the inclusion of this statement. - */ -static INTEL_HEX_RECORD g_Loader[] = { -{ 3,0x0000,0,{0x02,0x03,0x1c} }, -{ 3,0x0043,0,{0x02,0x04,0x00} }, -{ 16,0x0100,0,{0x90,0x7f,0xe9,0xe0,0x24,0x5b,0x60,0x60,0x24,0x02,0x60,0x03,0x02,0x01,0xbe,0x90} }, -{ 16,0x0110,0,{0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5,0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90} }, -{ 16,0x0120,0,{0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5,0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5} }, -{ 16,0x0130,0,{0x16,0x45,0x15,0x70,0x03,0x02,0x01,0xbe,0xe4,0x90,0x7f,0xc5,0xf0,0x90,0x7f,0xb4} }, -{ 16,0x0140,0,{0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c,0x12,0x02,0x77,0xaf,0x0c,0x7e} }, -{ 16,0x0150,0,{0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5,0x0a,0xc3,0xe5,0x16,0x9f,0xf5} }, -{ 16,0x0160,0,{0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xc7,0x90,0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5} }, -{ 16,0x0170,0,{0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90,0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5} }, -{ 16,0x0180,0,{0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5,0x16,0x45,0x15,0x60,0x30,0xe4,0x90} }, -{ 16,0x0190,0,{0x7f,0xc5,0xf0,0x90,0x7f,0xb4,0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c} }, -{ 16,0x01a0,0,{0x12,0x02,0x8f,0xaf,0x0c,0x7e,0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5} }, -{ 15,0x01b0,0,{0x0a,0xc3,0xe5,0x16,0x9f,0xf5,0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xca,0xc3} }, -{ 1,0x01bf,0,{0x22} }, -{ 16,0x01c0,0,{0xc2,0x20,0xd2,0xe8,0x43,0xd8,0x20,0x90,0x7f,0xab,0x74,0xff,0xf0,0x90,0x7f,0xa9} }, -{ 16,0x01d0,0,{0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x90,0x7f,0x95,0xe0,0x44,0xc0,0xf0,0x90} }, -{ 16,0x01e0,0,{0x7f,0x98,0xe0,0x44,0xc0,0xf0,0x90,0x7f,0x9e,0xe0,0x44,0xc0,0xf0,0xe4,0x90,0x7f} }, -{ 16,0x01f0,0,{0x94,0xf0,0x90,0x7f,0x9d,0xe0,0x44,0x0f,0xf0,0x90,0x7f,0x97,0xe0,0x54,0xf0,0xf0} }, -{ 16,0x0200,0,{0x90,0x7f,0xaf,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x0d,0xf0,0xd2,0xaf} }, -{ 16,0x0210,0,{0x90,0x7f,0x97,0xe0,0x54,0xf0,0xf0,0x20,0x20,0x42,0x75,0x14,0x00,0x75,0x13,0x00} }, -{ 16,0x0220,0,{0x75,0x12,0x00,0x75,0x11,0x00,0x7f,0x48,0x7e,0x92,0x7d,0x00,0x7c,0x00,0xab,0x14} }, -{ 16,0x0230,0,{0xaa,0x13,0xa9,0x12,0xa8,0x11,0xc3,0x12,0x04,0x9a,0x50,0xdb,0x20,0x20,0xd8,0x7a} }, -{ 16,0x0240,0,{0x00,0x79,0x00,0x78,0x00,0xe5,0x14,0x24,0x01,0xf5,0x14,0xea,0x35,0x13,0xf5,0x13} }, -{ 16,0x0250,0,{0xe9,0x35,0x12,0xf5,0x12,0xe8,0x35,0x11,0xf5,0x11,0x80,0xca,0x30,0x20,0xfd,0x12} }, -{ 16,0x0260,0,{0x01,0x00,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xb4,0xe0,0x44} }, -{ 6,0x0270,0,{0x02,0xf0,0xc2,0x20,0x80,0xe6} }, -{ 1,0x0276,0,{0x22} }, -{ 16,0x0277,0,{0xe5,0x0c,0xff,0xe5,0x0b,0xf5,0x82,0xe5,0x0a,0xf5,0x83,0x75,0x92,0x7e,0x74,0xc0} }, -{ 8,0x0287,0,{0xf8,0xe2,0x08,0xf0,0xa3,0xdf,0xfa,0x22} }, -{ 16,0x028f,0,{0x90,0x7f,0x96,0x85,0x83,0x92,0xa8,0x82,0x79,0x02,0x90,0x00,0x00,0xe0,0xb4,0x00} }, -{ 16,0x029f,0,{0x37,0x74,0x01,0xf0,0x90,0x7f,0x93,0xe0,0x54,0xfc,0xf0,0x90,0x7f,0x96,0xe0,0x54} }, -{ 16,0x02af,0,{0xfc,0xf0,0x90,0x7f,0x9c,0xe0,0x44,0x03,0xf0,0x90,0x7f,0x94,0xe0,0x54,0x7f,0xf0} }, -{ 16,0x02bf,0,{0x90,0x7f,0x97,0xe0,0x44,0x80,0xf0,0x90,0x7f,0x9d,0xe0,0x44,0x80,0xf0,0x90,0x7f} }, -{ 16,0x02cf,0,{0x97,0xe0,0x54,0x7f,0xf0,0x44,0x80,0xf0,0xe5,0x0c,0xff,0x90,0x7e,0xc0,0xe0,0xf5} }, -{ 16,0x02df,0,{0x28,0xe4,0xa2,0x47,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x46,0x33,0xf2,0x69,0xf2,0xe4} }, -{ 16,0x02ef,0,{0xa2,0x45,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x44,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x43} }, -{ 16,0x02ff,0,{0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x42,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x41,0x33,0xf2} }, -{ 13,0x030f,0,{0x69,0xf2,0xe4,0xa2,0x40,0x33,0xf2,0x69,0xf2,0xa3,0xdf,0xc2,0x22} }, -{ 12,0x031c,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x29,0x02,0x03,0x63} }, -{ 16,0x0328,0,{0x02,0x01,0xc0,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2} }, -{ 16,0x0338,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33} }, -{ 16,0x0348,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf} }, -{ 16,0x0358,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x04,0x84,0xe4,0x7e} }, -{ 16,0x0368,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93} }, -{ 16,0x0378,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3} }, -{ 16,0x0388,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca} }, -{ 16,0x0398,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe} }, -{ 16,0x03a8,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f} }, -{ 11,0x03b8,0,{0xab,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x03c3,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x20,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01} }, -{ 8,0x03d3,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x03db,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xd0} }, -{ 6,0x03eb,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 1,0x03f1,0,{0x32} }, -{ 1,0x03f2,0,{0x32} }, -{ 1,0x03f3,0,{0x32} }, -{ 1,0x03f4,0,{0x32} }, -{ 1,0x03f5,0,{0x32} }, -{ 1,0x03f6,0,{0x32} }, -{ 1,0x03f7,0,{0x32} }, -{ 1,0x03f8,0,{0x32} }, -{ 1,0x03f9,0,{0x32} }, -{ 1,0x03fa,0,{0x32} }, -{ 1,0x03fb,0,{0x32} }, -{ 1,0x03fc,0,{0x32} }, -{ 1,0x03fd,0,{0x32} }, -{ 1,0x03fe,0,{0x32} }, -{ 1,0x03ff,0,{0x32} }, -{ 16,0x0400,0,{0x02,0x03,0xc3,0x00,0x02,0x03,0xdb,0x00,0x02,0x03,0xa8,0x00,0x02,0x04,0x6e,0x00} }, -{ 16,0x0410,0,{0x02,0x04,0x58,0x00,0x02,0x03,0xf1,0x00,0x02,0x03,0xf2,0x00,0x02,0x03,0xf3,0x00} }, -{ 16,0x0420,0,{0x02,0x03,0xf4,0x00,0x02,0x03,0xf5,0x00,0x02,0x03,0xf6,0x00,0x02,0x03,0xf7,0x00} }, -{ 16,0x0430,0,{0x02,0x03,0xf8,0x00,0x02,0x03,0xf9,0x00,0x02,0x03,0xfa,0x00,0x02,0x03,0xfb,0x00} }, -{ 16,0x0440,0,{0x02,0x03,0xfc,0x00,0x02,0x03,0xfd,0x00,0x02,0x03,0xfe,0x00,0x02,0x03,0xff,0x00} }, -{ 8,0x0450,0,{0x02,0x04,0xab,0x00,0x02,0x04,0xac,0x00} }, -{ 16,0x0458,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0xd0} }, -{ 6,0x0468,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x046e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08,0xf0,0xd0} }, -{ 6,0x047e,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32} }, -{ 16,0x0484,0,{0x02,0x0a,0x00,0x0f,0x01,0x0c,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x41,0x00,0x00} }, -{ 1,0x0494,0,{0x00} }, -{ 4,0x0495,0,{0x02,0x17,0x00,0x00} }, -{ 1,0x0499,0,{0x00} }, -{ 16,0x049a,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0} }, -{ 1,0x04aa,0,{0x22} }, -{ 1,0x04ab,0,{0x32} }, -{ 1,0x04ac,0,{0x32} }, -{ 16,0x1100,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x01,0x01,0x00,0x01,0x01,0x02} }, -{ 16,0x1110,0,{0x00,0x01,0x09,0x02,0x20,0x00,0x01,0x01,0x03,0xa0,0x00,0x09,0x04,0x00,0x00,0x02} }, -{ 16,0x1120,0,{0xff,0x00,0x00,0x04,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40} }, -{ 16,0x1130,0,{0x00,0x00,0x04,0x03,0x09,0x04,0x26,0x03,0x41,0x00,0x6e,0x00,0x63,0x00,0x68,0x00} }, -{ 16,0x1140,0,{0x6f,0x00,0x72,0x00,0x20,0x00,0x43,0x00,0x68,0x00,0x69,0x00,0x70,0x00,0x73,0x00} }, -{ 16,0x1150,0,{0x2c,0x00,0x20,0x00,0x49,0x00,0x6e,0x00,0x63,0x00,0x2e,0x00,0x28,0x03,0x46,0x00} }, -{ 16,0x1160,0,{0x69,0x00,0x72,0x00,0x6d,0x00,0x77,0x00,0x61,0x00,0x72,0x00,0x65,0x00,0x20,0x00} }, -{ 16,0x1170,0,{0x46,0x00,0x72,0x00,0x61,0x00,0x6d,0x00,0x65,0x00,0x57,0x00,0x6f,0x00,0x72,0x00} }, -{ 16,0x1180,0,{0x6b,0x00,0x73,0x00,0x2a,0x03,0x43,0x00,0x6f,0x00,0x6e,0x00,0x66,0x00,0x69,0x00} }, -{ 16,0x1190,0,{0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00} }, -{ 16,0x11a0,0,{0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x22,0x03} }, -{ 16,0x11b0,0,{0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x66,0x00,0x61,0x00,0x63,0x00} }, -{ 16,0x11c0,0,{0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00} }, -{ 2,0x11d0,0,{0x00,0x00} }, -{ 0,0x0000,1,{0 }} -}; diff --git a/firmware/Makefile b/firmware/Makefile index dd76fa5..51ff1f3 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -27,6 +27,8 @@ fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ yamaha/ds1e_ctrl.fw +fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ + emi26/bitstream.fw fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ kaweth/new_code_fix.bin \ kaweth/trigger_code_fix.bin diff --git a/firmware/WHENCE b/firmware/WHENCE index b5be4bc..a2f9390 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -133,3 +133,37 @@ Licence: GPLv2+ Compiled from original 8051 source into Intel HEX, used in our binary ihex form. -------------------------------------------------------------------------- + +Driver: emi26 -- EMI 2|6 USB Audio interface + +File: emi26/bitstream.fw +Info: VERSION=1.1.1.131 DATE=2001dec06 + +File: emi26/firmware.fw +Info: VERSION=1.0.2.916 DATE=12.02.2002 + +File: emi26/loader.fw + +Converted from Intel HEX files, used in our binary representation of ihex. + +Original licence information: +/* + * This firmware is for the Emagic EMI 2|6 Audio Interface + * + * The firmware contained herein is Copyright (c) 1999-2002 Emagic + * as an unpublished work. This notice does not imply unrestricted + * or public access to this firmware which is a trade secret of Emagic, + * and which may not be reproduced, used, sold or transferred to + * any third party without Emagic's written consent. All Rights Reserved. + * + * Permission is hereby granted for the distribution of this firmware + * image as part of a Linux or other Open Source operating system kernel + * in text or binary form as required. + * + * This firmware may not be modified and may only be used with the + * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of + * any driver which includes this firmware, in whole or in part, + * requires the inclusion of this statement. + */ + +-------------------------------------------------------------------------- diff --git a/firmware/emi26/bitstream.HEX b/firmware/emi26/bitstream.HEX new file mode 100644 index 0000000..044d3f6 --- /dev/null +++ b/firmware/emi26/bitstream.HEX @@ -0,0 +1,4391 @@ +:10801000FFFFFFFFAA9955663000800100000007AE +:10802000300160010000000B3001200100803F2D75 +:108030003000C00100000000300080010000000995 +:10804000300020010000000030008001000000012D +:108050003000400050003E040812100000000000F4 +:108060000000000000000000000000000000000010 +:1080700000000000000000000000000000004004BC +:10808000800000000000000000121000000000004E +:1080900000000000000000000000000000000000E0 +:1080A000000000000000000000000000000040840C +:1080B000800000000000000000020000000000003E +:1080C00000000000000000000000000000000000B0 +:1080D0000000000000000000000000000000080098 +:1080E000C0000000000000000002000000000000CE +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:1081100080000000000000000012000000000000CD +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000043B +:108140008000000000000000081300000000000094 +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:10817000900000000000000000120000000000005D +:1081800000000000000000000000000000000000EF +:10819000000000000000000000000000000000845B +:1081A0009000000000000000F710011400250005F9 +:1081B0004001500094001500074001D000940025B4 +:1081C00080016002D800F6002F8002E004D8374416 +:1081D0009000000000000000C005F200CC903920A3 +:1081E0000D9803D200E78037040EF1837E00DF9004 +:1081F00031E48F79037C20DF2233C00CF022300081 +:108200007000000000000000801062008024222026 +:10821000089812E2008B8120940874022E008A01D3 +:1082200022C80892023D808B60228008B0022004A0 +:1082300030000000000000008805C800A0002000F9 +:108240000B1002C000A10024094A32024800B1000C +:1082500062C009A046CC2493492A8048302262019A +:108260007000000000000000C015A812A800220045 +:10827000089002E0008980224408B012A800A940BA +:1082800022C0089082AC009B042AC408B00270048B +:10829000600000000000000000148400E980B26467 +:1082A0004DA003EA20E9C036400EB0034400FB9025 +:1082B000B2880DBC03EC085B0038602CB06340044E +:1082C0007000000000000000E001B426DD9037409F +:1082D0004FE013F280FD003DA00D700375005E00BD +:1082E0003FA40DF9035C10EB0037200F3003B800FA +:1082F00060000000000000004010AC00E980324047 +:108300000CA183E800E90032420EB003AC48E9005A +:108310003A800EA403EC00EB00B2030EB00B100485 +:108320002000000000000000C8052E8089D12040F8 +:1083300008A002C0008180225808F5022F408B005F +:1083400020C00830437C008700224008F002320041 +:108350004000000000000000E00542019A4428A20D +:10836000081802C080A180A0000830028E00AB0077 +:108370002C400A30020C00A30020440A30023800CE +:1083800050000000000000006001320096822BA225 +:10839000885A02F200058029A0087842BE008E8427 +:1083A0002F610AD8024E10A78020280878021800F2 +:1083B000400000000000000048080800F224388057 +:1083C0002C1A03C400E058A0802E30038841E30239 +:1083D0003C400620038C00E30010000E31431202E3 +:1083E0000000000000000000401D9800EE013784EE +:1083F0009FD903F048FD1037C007B0035C00F610AA +:1084000033C00DE103ED20DF103F480FF023D0060D +:108410006000000000000000A805E402CB8030C02E +:108420000CA003E202C9003A400DB6036400EB0061 +:108430003EC00FB003ED00FB013EE00CB002EA00CD +:10844000700000000000000048119400870021C067 +:10845000286002D00085002D8048F0821C00B70003 +:108460002D000B5002DC00B7A02F80287A02D20426 +:108470006000000000000000C100BE00878021E015 +:10848000286802D70084802DE04979065309B58019 +:108490002DE20B7802DE80B7902DB0087902F00053 +:1084A00020000000000000004814CC10830128C800 +:1084B000082002C20681002CC88830620E21B3A0B9 +:1084C0002CC10BB602CC00B3002CE0083002D20461 +:1084D0003000000000000000E815A800CA40B0808D +:1084E0000C2C02F800C6203F900DA0037B01EEE0AB +:1084F0003FB40FEC03E800FA003FA00CA003FA041D +:1085000060000000000000004800E300F8092600B9 +:108510000FC183E010F8403C000F8003E001F80039 +:108520003E000F8103E004F8003E100F8003D200EC +:1085300030000000000000000810E402C9003E40C6 +:108540004F906326843902B2400C91032400F90055 +:108550003E400F90032400F1003A440F9003C20400 +:1085600030000000000000008004450089402E40DB +:1085700008920A2400B931226088948A2420B90024 +:108580002E400B90022400B90022680B9002E000FC +:108590001000000000000000180524A08D842F406A +:1085A0000BD1022400B900224A0810022C40B90065 +:1085B0002E400B90022400B9002A400B9002C60006 +:1085C00040000000000000000804140085802D40D9 +:1085D000085002040CB900A0500814220400B10095 +:1085E0002C400B10020400B128204A0B1302C201D8 +:1085F0000000000000000000B80D6000C0503E8088 +:108600000FC0432000F80030002C80232000F851D8 +:108610003E148F850B2140F8703A080F8483EE03D7 +:108620005000000000000000981DC400F9043E4006 +:108630000F9023D400FD003F500F9403F404FD007D +:108640003F418FD043E50CF9023F4A0F9203E60207 +:1086500070000000000000008805D401FD003D40CE +:108660000CD013F400D500336A1CDC833400D10431 +:108670003E500C9103E6C0DDB0336A2C9C83E600CB +:1086800070000000000000003810E009F8802E00A3 +:10869000888000E800BA0022B0088E02280088A86E +:1086A0002628088A22E20088E42230088C02CE04C0 +:1086B00030000000000000000805C400B1282E4072 +:1086C000081002C400990020424810026401918001 +:1086D0002C48081002C4C08140204A081202C2017E +:1086E00070000000000000001815A494A9022E409C +:1086F0000A90026400B90082600890026600891046 +:108700002462089002E40089022240189002C60404 +:108710006000000000000000A015E600B9043E4023 +:108720000C9013E400D1C012502890034400D900EB +:108730003E40289203E402D90032428C9012E804B1 +:1087400070000000000000002801A620F9003E4152 +:108750002D9003E400F9203E404F9001A400F90061 +:1087600036408F9207E400F100BE400F9003CA002C +:1087700060000000000000002810A000C8003E209B +:108780000C8003E040F80036122C0003E0C0F80033 +:1087900032100D8403A000F8023E080F8000CA04C6 +:1087A000200000000000000028053A908E002DA057 +:1087B00080E802FA00BE40238008E802FA008A003E +:1087C000368008A002E800BA002F800BA0038A00C0 +:1087D00040000000000000002805460283002C80B5 +:1087E000082242C680B1602EF4083822CE00A300D1 +:1087F00020C0083002AC00B1002E400B3002CA008D +:108800005000000000000000A0011E0285012DC2E2 +:10881000A84402D400BD0129401868D2DC008F8032 +:1088200025CC287342DC80B5302DC01B7202E800D5 +:108830004000000000000000A8081E04C6823DE0C1 +:108840000C4812D610F5803CA00C7003DE00E790B7 +:1088500023EA047A039E00F5803DE00F7A03EA02E2 +:108860000000000000000000080DAC009C003EC0AD +:108870000F8003E410F90036010FA003C000EB00E5 +:108880003ED84EB083EC00F9003EC00FB4438206E0 +:108890006000000000000000C005DE00CF8431E071 +:1088A0000EC843D600CD8033E0CDD9033A00FF880F +:1088B00033E00FF913FE24FD803F200CF6831000F7 +:1088C0007000000000000000A8119C00850021C479 +:1088D000284082D000D500238048C9021C00B70080 +:1088E00021C00B7102DE80B5102DC028F0022A04D1 +:1088F000600000000000000010009C00960021C0F5 +:108900000A4102F5408D0021400952029820B7002B +:1089100021C00B7006DC80B5002DC0087002040079 +:1089200020000000000000006014CC10980000C07F +:10893000880482C000910420030900028A00B30A5F +:1089400020C48B3402CC00B9002CC00030021804C3 +:108950003000000000000000F815AC00DB00B0C0E3 +:108960000E9C02C500C110B2C00DB00BA708FF00DD +:10897000B3C00FFA03FC00FD003ED40CF00B2E0434 +:1089800060000000000000008000EC04ED003E40AC +:108990000F8403E540F9403E60CEB4436400FB80A1 +:1089A0003EC20FB013EC00F9023EC04FB003E1002D +:1089B00030000000000000009010FF00CE0033C027 +:1089C0000EC0077404EC0011800CCA03FE60FF00A7 +:1089D0003FC00FF0833C00DD00B3502CF0032004B7 +:1089E000300000000000000081004C048B0B22705E +:1089F00008080367208A88A200288402E700BB00D9 +:108A00003EC00BB0022C00B900226108B0036040E8 +:108A1000100000000000000080052C008B2022E2E6 +:108A20000A8C022600A9802AC008B442ED00BB00CF +:108A30002EC00B30022C00B90020800830026000EC +:108A4000400000000000000008040E018100A0C0EA +:108A5000088102440081002881083202CC00B30062 +:108A600028C00B30020C80B10020C0083012420137 +:108A70000000000000000000800D6C00C20132C048 +:108A80002E80162C08E9003A400C8003EC00F70019 +:108A90002FC00FF00B2C00D90030400CF003600306 +:108AA0005000000000000000A00DF808FF003FC0CB +:108AB0000FC217FC00F70037000F8403FC00FF0013 +:108AC0003FC00FF003ED00FD003F400FF003E8064C +:108AD0007000000000000000C005FC00CF30174807 +:108AE0000C5903B900DF2835240D82A37C80FF00D8 +:108AF0003FC80FF203E4A0EF803FE18CD843300081 +:108B000070000000000000008010ED488934A37060 +:108B100028B02360008BC0224008B4822F40BFD110 +:108B20006FF48EBD02E700BB803AE008980A280483 +:108B300030000000000000008805C4B09100A8507B +:108B400008B202C884930024490B02024C00B3040B +:108B50002CC00B30428400B3002E000AB012220158 +:108B60007000000000000000C011AC0299182A44F7 +:108B700008B882A201BB0028600AA0126C00BB00EA +:108B80006EC00AB002E400BB002A002AB00238041A +:108B900060000000000000004011E408DAC03A6004 +:108BA0000C180AEB04DB0036E00785836C00FB0041 +:108BB0002EC00FB043E400EB003E880E18031004F3 +:108BC0007000000000000000E0419C10E9003760E8 +:108BD00087F0177000CF0137C04C9803BC00FB0032 +:108BE0003FC20FF003E400FF403FE40DD903F00063 +:108BF00060000000000000004010A400F4003040BD +:108C00000FB4039900FB003EC00D04232C08FB8821 +:108C100032C00FB003E600DB103E020FB083D00479 +:108C20002000000000000000C8052C00B950A24838 +:108C30008BB0032000D7802ED80080023C00BF807C +:108C400023E88BF002F4408B400C4203B602F200A2 +:108C50004000000000000000E0054C00B24400C8E5 +:108C60000B30128C00A38024C80B000ACC00B34444 +:108C700004C01B3602C501830C2CA00B3002F80087 +:108C8000500000000000000020011E08B790216481 +:108C90000BF8024A0497812FE40A78029E00B780FD +:108CA00021E08B7882D68687842DA00B7802C000C5 +:108CB000400000000000000048080400F20030C03E +:108CC0000F30038C00E30A3CC00F18038C00F30242 +:108CD00030C01F3001C680C3003CC00F1203DA024F +:108CE0000000000000000000400DBC00FF003F41FC +:108CF0000FF003B808FF083FC00DF0033C20FF0849 +:108D00003BD20FF003F440EF003FC40FD003D00676 +:108D10006000000000000000A805E400FE0032C270 +:108D20000C300B2600FB8036C00DA003EC00FBE0EE +:108D300032D00FB8436444DB043E800FB003E2003E +:108D4000700000000000000048119C00B700A1C0A6 +:108D50008870031000B72021C0087002DC80B33097 +:108D600031C80B7402140087402DC04B7002D20032 +:108D70006000000000000000C0009620B68020E0E7 +:108D800028F8029410B78127E2097802DE00B7A024 +:108D9000A9E80B3802760087802DA00B5802F0005E +:108DA00020000000000000004814CE10B30020C4D2 +:108DB0000820028010B30022C808B002CC11B30210 +:108DC00028C00B3002040093802CD20B1002D20476 +:108DD0003000000000000000E815A800FE4032A0AE +:108DE0000CE4039880FA0037A00DE083E800FE0051 +:108DF0003A800BA0036800D8A03F900FA003FA04AC +:108E000060000000000000004800E008F8083E0094 +:108E10000F80032000F8403E000F8003E000F804BC +:108E200030100F8003E002E8003E000F8003D20004 +:108E300030000000000000000810E400F1003240A3 +:108E40000E9083A400C9803E400E9003A400F90058 +:108E50003E400C9003E400C8003E408F90030204A3 +:108E6000300000000000000080046400B940A062EF +:108E7000081002241089002E400890022400B90036 +:108E80002E52089402C40089402E400B100360103B +:108E9000100000000000000018052400B91822444A +:108EA0000A9002AC0089102EC00A9002A400B9807A +:108EB0002E60089802E60289082E400B90020600F8 +:108EC000400000000000000008040480B120A04819 +:108ED000089002240881232C500810020480B1203D +:108EE0002C48281202E48081202C400B9802420575 +:108EF0000000000000000000B80D6140F850320092 +:108F00000E8503A1E0CA003E000E8503A000F80014 +:108F10002E009CA003E000C8283E000F80032E0115 +:108F20005000000000000000981DF440F5103F4480 +:108F30000FD003F400F1103D408FD403E450F9103A +:108F40003E450F9103D440FC003FC08FD023E60480 +:108F500070000000000000001805E620CDA8334096 +:108F60008DD0032680CD003D500C9A036400F9A0FB +:108F70007A6A0F9A63E680C9803E400F900306002C +:108F800070000000000000003810E10088E03600AA +:108F900008800A2142C8002E290CA4422000B840B3 +:108FA0002E000B8102E10088023A010BC0020E0480 +:108FB00030000000000000000805C40281082440C1 +:108FC000091002040091002C404B14024400B5101B +:108FD00029400B5002F500B5002D400BD0020201D4 +:108FE00070000000000000001811A6018900264052 +:108FF000089402240189002E401A90026C00BF02DE +:109000002F400BD002F402BD802B408BD83A0604CF +:109010006000000000000000A015E400C905364112 +:109020000D1C032400D9003E422F94036400F90074 +:109030003A400F9003C400F9003E700F100328045B +:10904000700000000000000028018408F9243E4060 +:109050000F9103E400F9003E410D1003A400F90054 +:109060003E400F9003E400C9003E640F9003CA0025 +:1090700060000000000000002810A008C880320234 +:109080000F80030000C8083A10CE8403E000FC0003 +:109090003F008FC003F080FC003F180FC043CA049C +:1090A0002000000000000000280528008E00A1809C +:1090B0000BE0022800DEC2239000A002E800BA0004 +:1090C0002E800BA002E800FA002E800BA002CA003E +:1090D000400000000000000028054C00998160C09D +:1090E0000B10020C0090102AFC0B3002CC00B300D5 +:1090F0002CC00B3002CC00B3002CC00B3002CA00D5 +:109100005000000000000000A0011C82954021C01A +:109110000B50021C8090802301097212DC00B60003 +:109120002D000B4002D000B4092D004B4082E80016 +:109130004000000000000000A8083E80DD80B1E093 +:109140000FDA030F80D48039E00B7A03DE00F5805C +:109150003D200F4803D610F6813DE08F6803EA02F8 +:109160000000000000000000081DAC00ED003E0003 +:109170000F910BEC10F8003E000EB003EC00F8006D +:109180003EC04FB003E800E9013E000F9003C20665 +:1091900060000000000000000005FE20BF8133A435 +:1091A0008C19033E00CD803FE00FF8833E00EF8036 +:1091B0003FE00FF913FA10FD803FA40FD803C00061 +:1091C0007000000000000000A8119C00BF2031C208 +:1091D000085A023C0287002D940B700A1C4086102E +:1091E0002D000B4002D400F6002D404B6002EA0433 +:1091F000600000000000000000009C00B701238018 +:109200002850021C0084002DC00B30021C00B50049 +:109210002D000B4006D040B4082D800B4802C00042 +:1092200020000000000000002014CC00B308A020A3 +:1092300008118A0E0080002C900B37020C00900061 +:109240002CC00B3042CC04A3802C500B3002C8043D +:109250003000000000000000A815BC00F98032605A +:109260000CD4033C8088003ED00FF8032800FA009D +:109270003EC00FB007EC01BB803E540FB006EA04BD +:1092800060000000000000008000EE08F9803AC095 +:109290000F9003EC00F8403E580FB043E900EB4458 +:1092A0003E000F8003E00DF8003E800F8003E000D9 +:1092B00030000000000000000110DC00CF0033404F +:1092C0000CD0033C30CC003BC02DF003D802CC00C6 +:1092D0003D000CC003F400EE0237400CE003C04434 +:1092E000300000000000000081046C18838420001E +:1092F0004A10020C00A8482E6008B002E90089401C +:109300002EC008B002E810B10120800A9003A040EE +:10931000100000000000000080052C008B82220855 +:109320000890022C1488042C0808B012E8008A0067 +:109330002EC00AB002E801B9002604089002E0003D +:10934000400000000000000008040C008380A2C060 +:109350000A92022C00A2002C00083402C8008300EC +:109360002C00280002C401BA0022C0022006C2015B +:109370000000000000000000000D6C00CA00B200F8 +:109380000C920B2C04C8043A000CB403E800C8008B +:109390002E000C8033E140E80036000C8003C0034F +:1093A0005000000000000000A01DFC00FF003D0078 +:1093B0000FD10BFC01FC003F000FF003D800FD00B3 +:1093C0003FC00FF003FC80FF003FC00FF007A8066E +:1093D0007000000000000000C015F300CF80356071 +:1093E0004E68435C00E78039C00CC1037E00CF3477 +:1093F00035E14DF2037C00DF383FC80FF803F00081 +:109400007000000000000000C018C800DB8422606B +:1094100008AC0A2C008B8022300891222C90276106 +:1094200022CA88FC22BF008B622FD009B803B00487 +:109430003000000000000000C805E280A9022440BE +:109440008234420400A90028C54832024C208330EF +:1094500020C00831020D00B3202CC40B3002F201F1 +:109460007000000000000000C005AA02B9042260DC +:1094700028B2022600898802C0083112EC008B0055 +:109480002AD008B002AC002B002EC00BB002B004F2 +:109490006000000000000000C005E200E30036208C +:1094A0000EA4636E00E1C01AC10C80036870CB008B +:1094B00036800DB0034C00FB043EC10FB003D00456 +:1094C0007000000000000000E001B804DF003F0071 +:1094D0000FE803FC00FD003F002B98033A007700E3 +:1094E00027E40FF003FC00DF003EC00DF043F8005E +:1094F00060000000000000005000A468CB203A90FB +:109500000F24A3AC00E9503AC00EB4832C08EB0042 +:109510003A900EB08BEC80FB003EC00EB00390047E +:109520002000000000000000C8010A008BA020807D +:109530000DA8022C04894028E808B2022C00AF00D4 +:109540000280087C033D803F002FC008B002360037 +:109550004000000000000000E0054900034028C072 +:109560002B284A2800A10068D20A2042A401A300A7 +:1095700002400A34020D0033002CC00A3000B8004B +:109580005000000000000000B8011A00879021E49C +:109590002BC8123A0085C02B21286802B600A78488 +:1095A00023600838801E00B7802DE00878022E0066 +:1095B000400000000000000048080800C1003854C6 +:1095C0000F26838000E03428C80E2C0B8C00E300AB +:1095D00078450E30038E80F3003CC80E30039202B3 +:1095E0000000000000000000401DB800F5023F44EC +:1095F0000D9003F800BD141FC00FE1235C449F428F +:109600003FC00FF4827D40FF103FC04F7007D0066F +:109610006000000000000000A805E802CB0038C090 +:109620003CA003EC00E9003EC00CB0032004FB2189 +:109630003E804FB403CF00CB003ECC4FB043EA0096 +:109640007000000000000000C8919800870021C051 +:10965000084002DC04B5002D002D70021C1CB7026E +:109660002DC00B7202DC0087402DCA8B7002F20401 +:1096700060000000000000008000BA0087882BE036 +:10968000187822D611A4822FE00878021200B7942D +:109690006D604B7A02DE40B7A02DE00B7806E0004B +:1096A00020000000000000004814C912838228D462 +:1096B000980006EF05B1902CC109B4020C04B30167 +:1096C0006CF00B3002CC00BB002EC00B3002D20479 +:1096D0003000000000000000E815B840CA803BA040 +:1096E0004CE502F880EE003D802CE00F3880FA0057 +:1096F0003FA90FA003E800BA023E808BA003FA0442 +:1097000060000000000000004800E010F8002602A1 +:109710000F8403E024F8003E004F80A3E030F800FF +:1097200036020F8023E00408003E000F8003D200C1 +:1097300030000000000000000810E400D900B6412D +:109740004E990BA40069103E400C9003A410C90070 +:109750003E400D9203E600F9003A400E9003C20429 +:1097600030000000000000008004640081002042FE +:1097700008149A240089006E500090022410D90227 +:109780006E400B9403A700B9002240089003E0004C +:109790001000000000000000180506009900A64116 +:1097A0000A90062C00A9096E5008910284048900D1 +:1097B0000E400B9402E549B9000A400A9002C60027 +:1097C0004000000000000000080406008100224064 +:1097D0000812220481A1002C4008160204009120E6 +:1097E0002C400B12428489B1202048081002C2018B +:1097F0000000000000000000B80D6140D8003600F5 +:109800000A8003A140E8002E000C0023A140C850AC +:109810002E140D8003E000F8503A000E8003EE0392 +:109820005000000000000000881DD400F500BF407B +:109830000FD103F444DD023D502BD123F400F91085 +:109840003F400D9103A448F9123E4E1F9003A6021B +:1098500070000000000000001815F400C5043B4033 +:109860000FD803A780FD00B3680DD843A510C9A089 +:1098700032514F5A433600C9A07A680BD003C60153 +:1098800070000000000000007818CA8888020200FA +:109890008D84222342F8002204288AA2AA9488E90F +:1098A00020A80A800A214080E22E280B8002CE04E4 +:1098B00030000000000000004805C420A104A8C03A +:1098C0000B1C2A2400390420402A1E02E480B11017 +:1098D0002A48091446040081382C5B0B1002D20080 +:1098E00030000000000000001805A412A924224046 +:1098F000299002240039000258081810E601B90026 +:10990000AA44089002240089000E410B9002C6046C +:109910006000000000000000A005E400E1012A64EE +:109920002F94132402716012604D9000C502F9005B +:109930003A400F90232402C9023A400F9002E804F3 +:1099400050000000000000006801A400D9003E6043 +:10995000AF90836488F9203E62039083A400C9001D +:1099600036600F1003C400F9007E400F9003DA0048 +:1099700060000000000000002800A100C882320042 +:109980006F0003A000D84030000E80036004F8018F +:109990003E104F808B2200F80032010E8003CA0473 +:1099A0002000000000000000280138000E00A990EF +:1099B0002FE62088009E8023800AE8032800BA0052 +:1099C00018800DEC023880BA00A28008A0038A003B +:1099D000400000000000000028056C02838020C8C1 +:1099E0000B20020C01921068C03A3C02CC103B02E2 +:1099F0000CC0283C024E00B30028C0283002CA0028 +:109A00005000000000000000A001140087422BC09D +:109A10002970229C00B6002BC20A60861C00B72168 +:109A200029C00074025C00379101E0087402A800AC +:109A30004000000000000000A8081E00C78021E0D0 +:109A40002F78029E00968039E02EF803DE30F7D0A2 +:109A50002DF20078035200F7A23BE00E7807EA02ED +:109A60000000000000000000081DB400FB000CC056 +:109A70000F3003EC10D300B4C02F80036C48FB0000 +:109A80003EC84D9003A400FB201EC00FB003C206C9 +:109A900060000000000000000005FE00CC802B2CC0 +:109AA0002FF8037E006E803BA10DD8433E00FF904F +:109AB00033E00FE933FE00CFC03FE20FD803C00010 +:109AC0007000000000000000A811B44087002104CD +:109AD0000878021C00860021C0289002DC00B71024 +:109AE00021C00F7302CC0087002DC00B5002EA008A +:109AF000600000000000000000009D00A400294854 +:109B00006AF0824C00AE00A1C42974025C40A3102C +:109B100061C20B6006C80087002DC00B5002C00454 +:109B200020000000000000002014E601A3022040F5 +:109B3000283C020C00834220C8081002CD00B3006C +:109B400028F00B3002CC0183042CC0831002C8041F +:109B50003000000000000000A815AA80EB0038C00B +:109B60000A90037C22A24032480DB00B3E00FF0059 +:109B700033F40F9003EC008F023FC00F9003EA0410 +:109B800060000000000000008000E000D9023EC03C +:109B90000EB603EC00FA203EC04F2423AC60FB005D +:109BA000A6C00E9003E400FB003CC10F9003E00050 +:109BB00030000000000000000110F802CF0033E088 +:109BC0002CF013BC002E10B1642EF0023C00FF02FA +:109BD0003FC14DEC63FE00B7003BC00CD803C0444E +:109BE000300000000000000080046C28818122E029 +:109BF0000A38023C04BAC932E02084022C00BB00BF +:109C00002EC00B9C02E781BB0422C00A9902E0002F +:109C10001000000000000000800528408880228895 +:109C200028BC42AC00BA002A80088402AC00BB0009 +:109C30002EC00BB082E890AB0062C008B012E0000A +:109C400040000000000000000804000089002A8095 +:109C500028B2020C00BA0020C00800028C00B30039 +:109C60002CC00B30204C14B30020C0083002C201BD +:109C70000000000000000000000D6800C800B2C035 +:109C80002CB203AC00FA003AC04EA503BC00FF00A2 +:109C90003FC009A003E904EF00BAC00CB001C00145 +:109CA0001000000000000000A019FC00F50035C005 +:109CB000AF3403FC00F40039C00FC2037C00FF0185 +:109CC0003FC00FF003FCA0FF003FC00FF003E8050A +:109CD0006000000000000000C005FC00FF293D20DE +:109CE0008EC1033248DC8023250EF2033CC0DF84A2 +:109CF00033C90FF203FC00CF8033400CF203300075 +:109D000070000000000000008010ECC0BB602E0856 +:109D100008810220048820204808F1822DC0830099 +:109D200022D409F502FC088B01224028B402200449 +:109D300030000000000000008805CC20B3092C8210 +:109D4000081016A010900828480A32020C00BB0028 +:109D50002CC00B3002CC02930120008A3122E20198 +:109D60007000000000000000C015AC04BB002C8097 +:109D7000088602A020A0002A600AB0102C00AB0CBC +:109D80006EC009B002CC009B0022600AB002F00451 +:109D900060000000000000000015EC00BB003E3435 +:109DA00008A00B8300D9023AE02EB00B2C00F880FB +:109DB0003EC04FB003EC00CA40B2720EB00BC004FC +:109DC0007000000000000000E001BC10FB003F003C +:109DD0000DF8137048DD4037C28DF003DC00DDC89C +:109DE00013C00FF003FC00EE407F400D70033800FD +:109DF00060000000000000004010AC00FB0132C019 +:109E00000410032040E8103AC00DB003AC08F8403D +:109E1000B2C02CB033A482DA40BA400FB003D004F1 +:109E20002000000000000000C8053C08BF8022C8D8 +:109E300008B700234488D022D0087082FC00B2E02A +:109E400003F408F50237048BD122604BFD02F200C7 +:109E50004000000000000000E0054C00B310A440EA +:109E60000800024800A0422AD00130028C00B380D2 +:109E70002CC0093102CC00890022E8033802F80026 +:109E8000500000000000000060011E00B780276441 +:109E9000684A0252008C8021E0087802DE00B78018 +:109EA0002DE21939025E30859821E40B7902D80041 +:109EB000400000000000000048080C00F3203400BF +:109EC0000CB8034880E22238C00D30038C00F30048 +:109ED0003EC00D3103EC00CB0038060F3083D202B8 +:109EE0000000000000000000401DBC00FF003B011E +:109EF0000FD0039000F6003FC00FF401FC00FF01FB +:109F000033C20EF513BC00ED003FC40FF003D006C2 +:109F10006000000000000000A805EC00FB003CC051 +:109F20000EA0016401D80032E02CB5032C00F20031 +:109F30007AC00DB4032D80C90232C00CB0032A00D0 +:109F4000700000000000000048119C80B7002DC088 +:109F50000D6002D001840021C00830021D00B7004E +:109F600021C80BF4031EC0860021C0087C035204E4 +:109F70006000000000000000C0009EC0B7902DE00F +:109F8000087806D601B48221E008780A1E00B5C020 +:109F900029E809780236C1978028B00A7A02300091 +:109FA00020000000000000004814CC00BB002CE0A2 +:109FB000093582C0C1A05120E40830028C00BBC426 +:109FC00020C00B300206009318AAB02A300A5204AF +:109FD0003000000000000000E815A800FA013DACC8 +:109FE0004CEC137810F680B3900CA0032800FE0010 +:109FF0003A810DA00F2A80DE043BA00EA0033A0494 +:10A0000060000000000000004800E000F8003E0092 +:10A010000D8002E100D8483E120F80136000F86006 +:10A020003E00078003A002E8042608058003920092 +:10A0300030000000000000000810E400F9043A407D +:10A040000C12032482C90036440F10032400F900C7 +:10A0500036400490030400C90012400C900302042F +:10A06000300000000000000080046400B98122403C +:10A0700008901A2400890022680B99022400B90074 +:10A08000224068900A24008900A24008900A20001B +:10A09000100000000000000018052400B91022E0A4 +:10A0A00008940004048B0826C00B90022404B90C09 +:10A0B00024400A1002240023022A40A810020600AD +:10A0C000400000000000000008040490B12022407D +:10A0D0000812020C108102A0500B12020480B1057C +:10A0E00000480A100204A0A100284A081200020138 +:10A0F0000000000000000000B80D6140F850BA14E4 +:10A100000C85030142C85034000F85032140F8003C +:10A1100036000E80132080E0001A080C00032E0386 +:10A120005000000000000000981DE444F9103F407A +:10A130002FD113F404F5003F400F910BE440FF28AA +:10A14000BE4E0D9683D4A2DD28374A0F9383E606D0 +:10A1500070000000000000009805E410CD003F40B2 +:10A160000FD00335025D0131440FD0032400F90004 +:10A1700032600C9883E640D900366A0C9E83260133 +:10A1800060000000000000003810E00088002E0091 +:10A190000B804202808A0022208880032008B88237 +:10A1A0002221088882E24288A8222008CE020E04DA +:10A1B00030000000000000000805C4028100684073 +:10A1C0000B10028401B900204049100A0400B508B0 +:10A1D0002146085002D4008D20254A0B500242012E +:10A1E00030000000000000001811A40089046E5423 +:10A1F0000B1012A401A900A2401890162400B90067 +:10A20000234018D002F4008D40214A0BD0024604AE +:10A210006000000000000000A015E400C9003A50F2 +:10A220008F960B8402F10130488D90032410F900C1 +:10A23000B2402C9003E640D1C036502F900B6804FA +:10A2400070000000000000002801A400F9003E603A +:10A250000F99C36400D9283E400D9003A400F94033 +:10A260003E400F9003E420F9403E400C90038A00EA +:10A2700060000000000000002810A000F801360077 +:10A280008F8003E002F80432000D80432002CC00EE +:10A290003F000FC0139002DC403F104CC0230A0463 +:10A2A000200000000000000028052800BA002280DD +:10A2B0000BE820F8004EC023A008A00368008A0025 +:10A2C0002E801FA0022A068A002EA00260030A0028 +:10A2D000400000000000000028056C00B30020C012 +:10A2E0000B3D02C003230020E001B0064C008B00B0 +:10A2F0002EC04B30028E0883802CC400348E4A005E +:10A300005000000000000000A0011C80B58061C06A +:10A310000B4002D400840823C20850025EC08401AE +:10A320002D008A0802102484086D000A03122800F8 +:10A330004000000000000000A8081E00F582216017 +:10A340000F7803D604AE8031E00D58237E00C6801E +:10A350002DE00B78038E00D7823DF00C7A036A0261 +:10A360000000000000000000081DAC00F100BAD899 +:10A370000F8003E412F800BE800E1003EC00F90019 +:10A380003E005F8003E008F8043C000F8003C20633 +:10A3900060000000000000004005FE20FF803FF04C +:10A3A0000FF803D200EF84B3610CB903FE00FF8005 +:10A3B00033E00CF8132211CD903F600CE80310003D +:10A3C0007000000000000000A8119C00F5002DC0E6 +:10A3D0000B0002D40484202340085A02DC00B4009D +:10A3E000210028C2021E0486042D8808D0022A04F7 +:10A3F000600000000000000010009C00B5002D402F +:10A400000B7002F420A70421C00A5002DC00BE0039 +:10A4100021C0087012000085002D4088680A0400E1 +:10A4200020000000000000006014CC00A1002EC03D +:10A430001B0806C420800020981A1002CC00B10826 +:10A4400020000800020C0182C02CAC2890221804C5 +:10A450003000000000000000A815BC00B3003E4022 +:10A460000FBA03E502E9043290AEB003FC10FB40E2 +:10A47000B2000C800B2C0282183FA00CD0032E04DB +:10A4800060000000000000009000EC04FB013E4072 +:10A490000FB643E400F8003E80019003EC00F88121 +:10A4A0003ED00DB453E000F9403E400FA003E00061 +:10A4B00030000000000000008010DC02CD8033601E +:10A4C0002CDA03FC00EC0033400FF2037C04FE00A6 +:10A4D00032000CC8033C00CE0031800CD1032404B0 +:10A4E000300000000000000091046C0009002A64A4 +:10A4F000088E02C210A0103E100B9802EC00B900AA +:10A5000002D808BE2220008900225008A002204064 +:10A51000100000000000000080052C000B202240ED +:10A5200008A002E542AB0422180BB0026C00B30095 +:10A5300020040801020004A8402210088002200024 +:10A54000400000000000000008040C0883002840C0 +:10A55000080402C402A8002C000B1202CC00B000B8 +:10A5600020C04030020C008B00A8C008300202114D +:10A570000000000000000000800D6C00C9003340A6 +:10A580000CB003EC02EB0032400FB0036C00FA0099 +:10A5900032000C80032080C80030000C80032003B0 +:10A5A0005000000000000000A019FC00FD003F402A +:10A5B0000FC213F000F4003F004FD403FC00F5007D +:10A5C0003FC08FF003FC40FF0037C02FF003E806C8 +:10A5D0007000000000000000C005F000CC00330057 +:10A5E0000ED00B3300CC0033E00FC0837C00CF20B3 +:10A5F0007B098CF803FE50CF383FE10DC203F00019 +:10A6000070000000000000008010E2009808208028 +:10A61000089802200088D022E00EB4227D199F699C +:10A620002E900830922881DB642EE18816A2E00487 +:10A6300030000000000000008805C80090242001C0 +:10A640000810160082830128C10B02820CE0A310BF +:10A65000280E1B9202848493202EC0083102E2014E +:10A660007000000000000000C015A81098002280B3 +:10A6700008900200608A102AC00A20026C18BB00F1 +:10A680006E602B900246208B002EC208B182F0042F +:10A6900060000000000000004011E402CB00B24066 +:10A6A0002C920327008800BAC00F88032C00EB040B +:10A6B0003AA0CF2CA3ED009B003CF02D8C33D004AE +:10A6C0007000000000000000E001B404EF003FC093 +:10A6D0000D5103F000F18137C00EF4039C10CF0040 +:10A6E0003D800CEC07B808FF021FC40FC803F80038 +:10A6F000600000000000000040109E00C3003840D1 +:10A700000C9203A480FB203AC00D94032C40FB0064 +:10A710003E010F8003E500EB003AC00D840B1004EE +:10A720002000000000000000C8052C088B0222C099 +:10A7300008920321008B4822C00BB7023D403F0125 +:10A7400022740B90022804BF00B2C00B85023200B5 +:10A750004000000000000000E005400180002800EB +:10A76000082C128840B04008C00B18020E00B3003D +:10A7700028201130020C00B3002400090006380024 +:10A78000500000000000000020011200848021A081 +:10A790002868123A00848025E08B58021E40B78258 +:10A7A00021A60B78021A00B78021200B580208005E +:10A7B000400000000000000048080800C8213809D7 +:10A7C0000C28038001F10038C00D85020C00FB004D +:10A7D00038850F10038C00EB103CC80D30031202BB +:10A7E0000000000000000000401D9800FC013F80B8 +:10A7F0000F6803D040FC003BC00DC003FC20FF00ED +:10A800003BC50FF00BB440FF183F000FF103D0061B +:10A810006000000000000000A805E400EB00B0416B +:10A820000CA003E004CA04B0E00EB003EC80CB201F +:10A8300032810CA003EE00DB003E000EB0032A00C4 +:10A84000700000000000000048119404870021C03F +:10A85000486002F000870021C0087002FCA0832835 +:10A86000A380086002DC0087202DC00B7002120458 +:10A870006000000000000000C0009C02A380216076 +:10A88000086802D200878021E0297802DE80879064 +:10A8900021A0194802FE0097802DE00A388230007E +:10A8A00020000000000000004814CC01838020C07C +:10A8B000082042C0308370A0C0893402CC028300DB +:10A8C00060C0290002CE0083002CC80BBC02120419 +:10A8D0003000000000000000E815A900EAE2329014 +:10A8E0002CE003FB02CEC032800FE403E8008A00B4 +:10A8F00033880D64C3FA00DA003D900EE00B3A0491 +:10A9000060000000000000004800C024F8083E126B +:10A910000FC003E048F0003E000E8093C000F80036 +:10A920007E010E80C2E040F8007E008F8403D200DA +:10A9300030000000000000000810E500C1013248AE +:10A940000C9803E640C90032400F90036600C9002E +:10A9500018610C90036420F9053E400C90830204BA +:10A9600030000000000000008004662089002052B2 +:10A970002810C22602A90022400B900A2700A90035 +:10A9800022700890022408B9002E400A900A200084 +:10A990001000000000000000180524028D00234074 +:10A9A00008D1028420890022600B11F224B08100BA +:10A9B0002A460890426408B9002E40089202060018 +:10A9C0004000000000000000080414808520234897 +:10A9D0000852028408810020400B12020480A1204A +:10A9E0002849289002040031202E4008320202013A +:10A9F0000000000000000000B80D6000C850B21454 +:10AA00000CC003A140C800B2000785032140C85014 +:10AA10003A150C85036140F8513E002C85032E0346 +:10AA20005000000000000000981DC448F9103E448A +:10AA30004F91037400F5443E400FD103E440F910F8 +:10AA400037440FD003D400F9103FC00FD103E606FE +:10AA500070000000000000001815F6A0DD8C3378AF +:10AA60000EDA033500CDA033400DF80B3681E980B6 +:10AA700033700C9103E440F9C03EC00FDC03C60004 +:10AA800070000000000000003810E104B840203CD5 +:10AA90000C850202848A402200088F822300B8E8D5 +:10AAA0002220088802E200B8D02E000B8C02CE04CF +:10AAB00030000000000000000805C400910060485C +:10AAC0004B1002048A814060404910028DA0A141D0 +:10AAD0002050091222C480B1202C404B3E02C201FA +:10AAE00070000000000000001815A408B904A04080 +:10AAF00048B0022400890082400890A6A400B9044E +:10AB00002254299502E540B9006E400B9202C6041A +:10AB10006000000000000000A005E4009100324049 +:10AB20000F90092400899032400D9403A400E9029B +:10AB300072600D9403E401F9013E600F9003E80494 +:10AB400070000000000000002801A440F9003E4011 +:10AB50004F9003E710F9803E400F10136400F1009E +:10AB6000BE400E9003E608F9013E640F9003CA0050 +:10AB700060000000000000002800A000F80032087B +:10AB80000C010B2040C84032000E84832000F804E2 +:10AB90003E040F80032100E8003E100F8803CA0422 +:10ABA0002000000000000000280538003E0423803B +:10ABB00008EC123944A600288108E0003808BA00E1 +:10ABC0003F800BA002A8008A022E800BE002CA0080 +:10ABD000400000000000000028054800310024D09B +:10ABE000083E12AE0881A02CC00A38004C00B30009 +:10ABF0006EC00A30020C00A3006CC00B3002CA0009 +:10AC00005000000000000000A0011800B51025C091 +:10AC10002860129010A5082DC20864225818B700A9 +:10AC20002D800B7902BEC087016DC00B6002E80069 +:10AC30004000000000000000A8081E00F584352038 +:10AC40008C18029210C5803D600EC80B5A0877F32D +:10AC50003DA00FF8031EB0E7853DE00F7803EA0240 +:10AC60000000000000000000081DAC00F104BA0163 +:10AC70000FA0436009E10038400EA003A814FB2098 +:10AC80003A800FB41B4C80FB293EC00FB023C20694 +:10AC900060000000000000000005FA00CD803BE0ED +:10ACA0004EF803F202D4813BE08E98073E44EF91C8 +:10ACB0003FE04FFC07EED0CF9833E40FF803C0001D +:10ACC0007000000000000000A801980085102DC44D +:10ACD0000D1102F000852031C40B7B003840D710E5 +:10ACE0002D800B7062FEE1871439C00B6002EA040C +:10ACF00060000000000000000010BC40A5002940DA +:10AD00000B5082DC4084042DC00B10065844A71061 +:10AD10002D800B7102DC00870421C20B5002C01091 +:10AD200020000000000000002014CC0AA1012C40EB +:10AD3000891802C100A10820C00B34064000930509 +:10AD40002C140B3C86CE10830128F10B1402C8048E +:10AD50003000000000000000A815A000ED003AC07F +:10AD600007BC63ED0081403EC00E88036400EF0025 +:10AD70007E500FF002FD42CF0072C01FB403EA0400 +:10AD800060000000000000008000E80099003EE044 +:10AD90004FB483ED9009403EC00FA183A801EB01A1 +:10ADA0003E000FB113EC0CFB003AC05F2023E00023 +:10ADB00030000000000000000110F800FD043FB06A +:10ADC0000D60033E00CD0033F00FF201F000FF03F1 +:10ADD0003F030FF001FC00FB0233C20FF0E300441D +:10ADE000300000000000000081046A00B9022EA0BB +:10ADF0004AAC020E80F9C036E10BA0022A08BB0063 +:10AE00002E200EB002EC00EB0022C08BB0022040DE +:10AE1000100000000000000080012300A90028C0ED +:10AE200009B2226C4089892AC00B14062600AB02A5 +:10AE30006EE009B0066C00B30222C00BB002200025 +:10AE4000400000000000000008040800B1002CC011 +:10AE50000A30022C00BB0064C00B320A0800330029 +:10AE60006C80023046CC18A30020C00B28020211CF +:10AE7000000000000000000000056800E90038C183 +:10AE80000DB10B2C0089003AC00B90036000FF024B +:10AE90003E800FF003FC80FF0032C08F800B000368 +:10AEA0005000000000000000A011D800FD043FC0C9 +:10AEB0002FF203FC11EF003FC00FF4437000FF00BE +:10AEC0003F0046F003FD00EF003FC00FC003E8065F +:10AED0007000000000000000C005FE00FF803DE0A3 +:10AEE0000CF913DE007F80B3E00FFC03BE40CF807F +:10AEF00033F00FF8037C04CC8033A00CF00B30014E +:10AF000070000000000000008010E02088002E206B +:10AF1000088212E080A88122020B80022080A88093 +:10AF200022080B80022C028804AA2008B002200408 +:10AF300020000000000000008805EC00A3082C8021 +:10AF4000083202C420A30028400B92028400A90109 +:10AF500028C81B1282CC40A80024E00A30422201FB +:10AF60003000000000000000C011A880A8022E40A0 +:10AF7000688010C800B8402A900BA0002800AA08DA +:10AF80002A020320028C00A8882E200AB002300476 +:10AF900060000000000000004015E804FA003C409A +:10AFA0000CA003E800EB003AC00F2053A800E340D8 +:10AFB0002A400FA0036C00A88034201EB0031004A8 +:10AFC0007000000000000000E001B4009D913F808F +:10AFD0000FDA23F400CC20370007D0137400BC0034 +:10AFE000B7800BD0437C00DC043B006DF003F8001D +:10AFF00060000000000000004010A800FA803A0045 +:10B000002CA00B2002CB623E500E88032000D910EA +:10B010003E708C8033EC80D8403A020DB0031004AF +:10B020002000000000000000C8010C00398022C090 +:10B030000C9D822C10D0402EA008B8034E028A40EE +:10B040000EA00DB0033D00D09036100BF002B20000 +:10B050004000000000000000E0054C00B10060C0AE +:10B060008A18028C0880400CA0023002CE00824870 +:10B070002C802B30068C008102209009B002380011 +:10B08000500000000000000020011200B690A33024 +:10B0900008E822B21487802D600849121261959049 +:10B0A0002D610A48161E80958025200B78028800A5 +:10B0B000400000000000000048080C00F100288C4F +:10B0C0008E1003848080002C020A9A02E400D000D3 +:10B0D0003E800B91038E80C20838800DB0031202AF +:10B0E0000000000000000000401DB000F6003F44DA +:10B0F0000F21137800FF003DC00FE0037800EF043C +:10B100003F408DE803DC04F6003F000FF083D006DB +:10B110006000000000000000A805E800E880324060 +:10B120000F880B280078023E800E28032800CA8072 +:10B1300032000FA003EC00C98032800FB0032A0058 +:10B14000700000000000000048118C008F00A180FA +:10B150000B70421400B7002D410B50421400A500A3 +:10B16000A1C00B5002FC80A50021000BF2021204CA +:10B170006000000000000000C000BA00A480293078 +:10B180004B48065208B4802D200B48423200848080 +:10B1900021200B4812DE40868129A00B780A30005E +:10B1A00020000000000000004814CC00830520E0CF +:10B1B0000B34026C10B3002CC00B364A0D0DA300EB +:10B1C00020C00B3482CC02A20028000B30021204F3 +:10B1D0003000000000000000E815A920EA4030A07F +:10B1E00007A0436940FA003C800FA0030840CA0052 +:10B1F00030A00FA403E800CE003B980FA0033A0450 +:10B2000060000000000000004800D200FC083F0081 +:10B210000BC203B000FC003F000FC003F000FC00B5 +:10B220003F040FC003E000F800B6020F8003D20015 +:10B2300030000000000000000810E400D9003E6863 +:10B240004C9101E408C9003E402C9203E402C9A0DD +:10B250003E700E9003C642C9003E400F1003020428 +:10B2600030000000000000008004640089860E6049 +:10B27000089802E40889102E60089002E400890C06 +:10B280002E60089002E68889002E400B9002A000F4 +:10B290001000000000000000180524009D102F4041 +:10B2A00028D006F402AD002F6008D002F4008D0013 +:10B2B0002F400AD002E40089002E600B90020600A5 +:10B2C00040000000000000000804340085002D400C +:10B2D000085802D400A5022D40085000D400850073 +:10B2E0002D40085402C48081002C600B140282019E +:10B2F0000000000000000000B80D6140D8523E0080 +:10B300000C0503E140E8043E140C8503E140C8004D +:10B310003E140EC003E000C0023E004F80232E0307 +:10B320005000000000000000981DF400F9013E40AC +:10B330004F9013E400D9001E400F9003C410F10099 +:10B340001E400F9003E4E0FD283F400F9403E60603 +:10B3500070000000000000001805A400FD003F4040 +:10B360004D5002E4009504334028D003F400FD0062 +:10B3700033400F91033400CD4033400F98810600D5 +:10B3800070000000000000003810E010B8002E002F +:10B390000B8002E010B8002200088002E000B80034 +:10B3A00022000B8803C280888022000B8C020E04CE +:10B3B00030000000000000000804C400B1002CC0F0 +:10B3C0000B1002C400BB002240081002C401B900E7 +:10B3D00020401B90020422890020600B128202018F +:10B3E00070000000000000001815A444B9002EC031 +:10B3F0004B9002E410B9020240089142E400B98087 +:10B4000022400B9202C400994022404B9012060445 +:10B410006000000000000000A015E600B9013E58E1 +:10B420000D9003E600D10032600C9802E640F9006E +:10B43000B2400F18032400C98032500F9023280413 +:10B4400070000000000000002801A400F9003E4246 +:10B450000B9003E708F900BE480F9003E400F900E1 +:10B460003E400F9803A400E9A0BE400F100B4A0015 +:10B4700060000000000000002810A000D8013E007D +:10B480000F808B2000F8203E010F8103E000F808B8 +:10B490003A000C8003E000D84032000F80130A0409 +:10B4A0002000000000000000280528008A802F915D +:10B4B0000BEE022801BE0020800BA002EA80B648F5 +:10B4C00022800DA002FA028641A3A60BA0030A0067 +:10B4D000400000000000000028054C0093802CC0B4 +:10B4E0000B30020C10B30028C00B3802CC00B300A4 +:10B4F00028C0093002C601836020700B300A4A0060 +:10B500005000000000000000A0012E8885082D805A +:10B510004BF8061C80B70021C00B5002D400B600C7 +:10B520002960097002D0A08D0021400B3202280052 +:10B530004000000000000000A8081E00D5803DE08B +:10B540008F78031E84B7823D600F5903DE00F780B9 +:10B550002960157803DE00C78031600F7C036A0222 +:10B560000000000000000000081DAC40E9003E8023 +:10B570000FA003ED30FB0036C10F9603E400B300CB +:10B5800034400FB783EC4021003E400FB003C206A9 +:10B5900060000000000000000005FE00FF8133E0B5 +:10B5A0000FF903DE20CF813FE00778033E00FF80E4 +:10B5B0003FE004F813FE02DE8033600FF803000062 +:10B5C0007000000000000000A8119C00B70021C41A +:10B5D0000B5A02DC4886502DC00B31029460B4181F +:10B5E0002D40487002E800A51021400B71022A048A +:10B5F000600000000000000000009C00BD0021422F +:10B600000B7002FC02850025400B50029C00B70025 +:10B610002F40287102DC00A60021C00B7002000040 +:10B62000200000000000000020146D80B120A05018 +:10B630000BB206CE00A0342EF00B18028520B34AC0 +:10B640002C54883802CC10A10020B00B3002080422 +:10B650003000000000000000A815BE80F308105460 +:10B660000B8813FF00C0803E640FB4830700F9C04D +:10B670003EF00CFC13F400EA0032700FF00B2A04C9 +:10B6800060000000000000008000EC00F9003E10A7 +:10B69000079103ECC058003E440F9203E400F90008 +:10B6A0003EC08FB303E000BB00BE440FB003E00018 +:10B6B00030000000000000000110FC02CD0433E067 +:10B6C0000CC0033C08FE0033602CD002B480CF00D5 +:10B6D0003F5207F013FC00CE1033420CB003C044BD +:10B6E000300000000000000081046C0089002AB0D6 +:10B6F0000888022C00BA0036440890002600DBC0FF +:10B700002E400BB002EC0083C028400AB002E0409B +:10B71000100000000000000080052C008B002208B3 +:10B720001AA2022C10B92022400830022C04AA547C +:10B730002EC00BB012CC008B08224008B002E000F3 +:10B74000400000000000000008040C0083042A00F0 +:10B750000A08820C00B8006440083002A400B0005F +:10B760002CC08B3010C8028B002A400A3002C20164 +:10B770000000000000000000000D6C00C900320055 +:10B780001A82033C00F90032400CD103AC00EB00FC +:10B790003E400FF003ED00C30032C08CB003C00385 +:10B7A0005000000000000000A019FC00F5003F0060 +:10B7B0000D804BFC007C003F400FD20B7400DF007B +:10B7C0001D408FF003FCA0FF003F800FF003E80650 +:10B7D0007000000000000000C005FC00DF843BE0BA +:10B7E0000FF80B3E00EC8033E10C30033C80CF4877 +:10B7F00037C00E4003E0C0C791B3040CF003300023 +:10B8000070000000000000008010EF048B802241D7 +:10B810000BB0822E008880A2E00AA292AD808742FF +:10B8200023D88AAD02E0C08B00204C48A40220043B +:10B8300030000000000000008805CC58BB002880C4 +:10B840000BB2422400A8002AC00A10020460A32000 +:10B8500024D20800428C839B0120490833C2220174 +:10B860007000000000000000C015AC00AB8822A0F2 +:10B870000BB802260CA8002AC00A9202A400AB064C +:10B8800022C00AB002E8009B00024008A042300437 +:10B8900060000000000000004015EC00D3803AE09A +:10B8A0000F18010600E83038660EB8032A40EB0096 +:10B8B00036C10E9603E280DA0832802CBB031004F6 +:10B8C0007000000000000000E0019C00DF003FC0AD +:10B8D0000FD003F400DC8037600FE803FA00DF01CB +:10B8E0003FC00FC043E64CEFA03F440FA003F80059 +:10B8F00060000000000000004010AC40DB0036801B +:10B900000C98032600F8003EC00E18038402E301E1 +:10B9100038C10EB403AC80CA183AD02C30031004DE +:10B920002000000000000000C8053F40B9882E80BC +:10B9300008BC02A300B0000EC008B00620008F04AF +:10B9400023C108B9122F008380364008AD023200AF +:10B950004000000000000000E0054C00B2002CC0D8 +:10B96000093202840033002CB20A36128C08930587 +:10B9700020C00B1802ED0091806A00081002380008 +:10B98000500000000000000020011E00B7802DE0E4 +:10B990000978029740B4802FA008E8020E409782F1 +:10B9A00021E09868821A189D902DA118580208006D +:10B9B000400000000000000048080CC0F3003EC03A +:10B9C0000DB0438440F0003C820E38128C44F330BA +:10B9D000BAC11E10478E22D11038180C30831202C3 +:10B9E0000000000000000000401DBC40FF003FC000 +:10B9F0000EE003F440FC003DC40FD001F441EF1809 +:10BA00003FC41FF003F848EF1433800FC103D00682 +:10BA10006000000000000000A805FC40FB003EC0E4 +:10BA20000F98032400CB003E400FB003A800DB2892 +:10BA30003EC41F9023EC00CA0032E00C9003EA00E1 +:10BA4000700000000000000048119C80B7002DC06D +:10BA50004B50521400D4012D800B6002D800A72057 +:10BA60002DC50B4016DC00840023C0084002D20420 +:10BA70006000000000000000C0009E80B7802DE044 +:10BA80000B780A960094802D601B7806D200A78060 +:10BA90002DE00B7822DE00878221E0085802F000BA +:10BAA00020000000000000004814CC00B3E42CC0CB +:10BAB0001B2102810090002CC80B3902CE00A3008C +:10BAC0002CC00B3002CD008B2020F008B202D20433 +:10BAD0003000000000000000E815A800FEA03F8232 +:10BAE0000FE8039830D6003FA00FE003BAC0FA0079 +:10BAF0003E800FEC33F802CE00B3B82CEC83FA048E +:10BB000060000000000000004800E018F8403E001F +:10BB10000F80026084F8052E048F8041E0007802D7 +:10BB20003E000F8183E020F800BE020F8003D200A8 +:10BB300030000000000000000810E618F9203E4028 +:10BB40000F9C03E440C90032610C9013C408C90182 +:10BB50003E410F18032400C9A032400F984302044D +:10BB6000300000000000000080046500B1C02240E9 +:10BB70000B9C02E71089002844089422E4108900F5 +:10BB80002E400B9F222660898022400B910A2000C4 +:10BB9000100000000000000018052480B9002EC02D +:10BBA0004BB402E42089202240089402EC00890072 +:10BBB0002E410B90020400894022400B90020600A7 +:10BBC000400000000000000008040400B104204010 +:10BBD0008B1002E40581002840281212C4828120C3 +:10BBE0002C480B120A0482810020480B1202020129 +:10BBF0000000000000000000B80D68A0FA023E142A +:10BC00000F8503E000C80032000C8503C140C85313 +:10BC10003E140F80030148C050B2140F85032E0359 +:10BC20005000000000000000981DE400FD00BF402F +:10BC30000F5013D402FD002FC00FD103F440F910B0 +:10BC40003E440FD103F440FF00BF440FD103E6068A +:10BC500070000000000000001805E6A0FD013E4451 +:10BC60000FD103D400C50033410FDB032720D9E0F7 +:10BC7000B2700DDA83F640CF1032782DDA03060069 +:10BC800070000000000000003810E100B8002E280D +:10BC90000B8842E010D80022000B8C0A230088C0D9 +:10BCA0002228088402C28080A0223048AA820E0482 +:10BCB00030000000000000000805C400B1002C4066 +:10BCC0008B1202C400990228408B160284819130A5 +:10BCD0002058091002C5008100644D083402020199 +:10BCE00070000000000000001815AC0CB9042E48CC +:10BCF0000B9406E4009940AA400B9222A40089000C +:10BD00006040089402E4008980A65008920206046C +:10BD10006000000000000000A015E400F9983E4813 +:10BD20000F9803E520D9003A640F9483A4C0D90288 +:10BD300072404D9042E482C94036400C900B28047A +:10BD400070000000000000002801AC28F9883E4087 +:10BD50000F9913E700F9C036600F90036600F100F9 +:10BD60007E400F9907E460F90038400F9803CA003D +:10BD700060000000000000002810A000F810320051 +:10BD80000F820B2100E80036040C8603E100D80086 +:10BD900032000F80036100C80032000F00030A0464 +:10BDA000200000000000000028052820BE0022809E +:10BDB00028EC021904820003800DE482E8008A0165 +:10BDC000AA808BED823B808E9036800BE0034A0088 +:10BDD000400000000000000028054200B38020C0A1 +:10BDE0006B341640C08310247288B002EC008300CC +:10BDF00024C00B04026F099B0024C00B30020A0010 +:10BE00005000000000000000A0011400B78023E4EF +:10BE100028788274148F0061E0095012DC048722B4 +:10BE200025C81B780214009440A5C00B602268004E +:10BE30004000000000000000A8081220B780B1E018 +:10BE40008FF8031202E78035E00C6806CFC2CFB04E +:10BE500025F40F58035A02D58075FA4FF8032A02C9 +:10BE60000000000000000000081DA590F3003DC088 +:10BE70004FB013A804FB003CC00F8043EC80EB6084 +:10BE80003AC90F3003EC00E9003EC80FA003C20618 +:10BE900060000000000000000005F600EE803FE0BA +:10BEA0000D8903D240E58139E03CF907FE00CF88D7 +:10BEB0003FE00FE803F208CE8033E00CF803000007 +:10BEC0007000000000000000A8119444C6002FC0BC +:10BED000085802D0C485242190085412DC8207003F +:10BEE0002DC00B7006D4008E4821C00A60022A04BF +:10BEF000600000000000000000009C00A7402DC072 +:10BF0000084202D000AD0029C0087022DC2887005A +:10BF10002DC00B400298009700A0C40870020000DA +:10BF200020000000000000002014CC0893002CE04A +:10BF3000083C22C10081002080881502CE30830099 +:10BF40002CC00B3C02CC0493C020F44A0C820804A1 +:10BF50003000000000000000A815A000E3C01FE0B2 +:10BF60006C1083E004EB003A524CB403FE02CF00A5 +:10BF70003FC00F8443E102D8C233C00C840B2A04B3 +:10BF800060000000000000008000E900EB103EC4EB +:10BF90000E9403E400FB183EC20FB603EC00FB0155 +:10BFA0003EC00F3503C428EA423EC00F8103E000C3 +:10BFB00030000000000000000110FC40FF0033C012 +:10BFC0000CC0A33028CDA033C00CE8030C00EF0553 +:10BFD0003DC00CCA833C00CD083FC20CA003C04446 +:10BFE000300000000000000081046700BB8020C01A +:10BFF00008AA020800A10134D108A4122C008B0069 +:10C000006EC088B2022C0889802EC00AA803A04006 +:10C01000100000000000000080052C00BA80A2C0C3 +:10C0200008A80AA0008B00A2C0481102AC048B0033 +:10C030002EC00080122A088B142CC0088802E00051 +:10C04000400000000000000008040C00B20022C004 +:10C0500008B2128000AB0124C00800020C04830067 +:10C060002CC00830020700820024C00808028201A8 +:10C070000000000000000000000D6C00FB0032C05A +:10C080000CA203A000C90032C02494033C02CF00DC +:10C090002FC004800B0902CB013FC02CA003C003BA +:10C0A0005000000000000000A019DC00FD023FC0AD +:10C0B0004FE4137000FD003FC00FC283FC00FF007F +:10C0C0003FC00FF003FC00FF003FC00FC003A806F5 +:10C0D0007000000000000000C005FC20EF303F04AD +:10C0E0006C88033A42E4913F0D0D48033CC0FF02C7 +:10C0F00033440CF403FC82DF3033600DF103300075 +:10C100007000000000000000A010ED008B702E18E1 +:10C1100088224A2C82EA262E0C0BB8423D80BF9022 +:10C120002A5428B402CD00DB402A4A483002A00439 +:10C1300030000000000000008805CCB0A3006C10A7 +:10C140000900822082A0202C884B80000C40B30183 +:10C1500020480B36028CE0836424402832022201FE +:10C160007000000000000000E011AC008B002E0009 +:10C17000098080A600BA112E880BB0002C00BB02EB +:10C18000024009B002EC008B002CC808B882B00451 +:10C1900060000000000000004015EC00EB003E9243 +:10C1A0000D80030A20E9003E504580012C04F30075 +:10C1B000906009B003EC008B0226508DBC03100484 +:10C1C0007000000000000000C001BC00FF023F80C2 +:10C1D0000EF9027C22AF003F6003C00BFC10FF0091 +:10C1E0003F4A4EF003FC00F7002B600F7003F8008D +:10C1F00060000000000000004010AC00FB00B00038 +:10C200000F820BA900C90032D20FA083AC00CB1063 +:10C210003E400CB003EC00DB0032502C95031004C0 +:10C220002000000000000000C8053C04BF0222807E +:10C230000B98002900CB4022C00B24023C088F50F1 +:10C240002E500DF002FD428F5822E048B502320018 +:10C250004000000000000000E0056C00B300244036 +:10C260004B940049009080043009000E4C008380FC +:10C270002CC00930226E42838020480838023800E2 +:10C28000500000000000000020011E00B780652063 +:10C290000B78827A088CC025A34B78025E048784D1 +:10C2A0002D61897802DE048780E96208780208003F +:10C2B000400000000000000048080C00FB0034486B +:10C2C0000F3B034800934834500D00036C00C3102B +:10C2D0001CC2053003CC40CB0032400C20031202BC +:10C2E0000000000000000000401DBC20FF010340D2 +:10C2F0000FF0231C00FF003B800FB0233C02FF50D7 +:10C300003DC40FF103EC00EF00B7C00FE103D0060E +:10C3100060000000000000008805EC00FB023EE029 +:10C320000C80034802C88132000F9042ECA0FB1041 +:10C330003EE00CB103EC40FB1032401FF0032A003A +:10C34000700000000000000048119C00B7242D8000 +:10C35000087042D8108C0221400B5002DD00E7200B +:10C360002F40087002DC05B70021C00BF002120458 +:10C370006000000000000000C0009E00B7902F4049 +:10C380000A68027A00978021E00B7802DE00B7800D +:10C390002DE0087806DE00B7A021600B784230005F +:10C3A00020000000000000004814CC00B3002CC0A6 +:10C3B0000A3402C800834A20F80B3102CC00A300E3 +:10C3C0002CC0083002CC00B30020B20B2042120473 +:10C3D0003000000000000000E815A800BA003F8807 +:10C3E0002EE0435988DE0033B00F6C03E800FA00FA +:10C3F0003E802CA003E804FA0023B80FE08B3A0437 +:10C4000060000000000000004800E004F8013E0069 +:10C41000098221E000F840BE140F8481E000E800AA +:10C420003E001F8003E000F800BE000F8803D2002A +:10C4300030000000000000000810E400E10032407D +:10C440000C9043E420D9003C440890032400F901F7 +:10C450003E480F10432500C900B2400C900302046F +:10C46000300000000000000080046400B900A0401B +:10C47000089802E608A9602E490894022400B90031 +:10C480002E700B900226028900A0400A900A20001C +:10C49000100000000000000018052400B900224030 +:10C4A000089804E60099802E400AB1022400B900E1 +:10C4B0000E400B900A0400810122C0081002060001 +:10C4C000400000000000000008040480B120224861 +:10C4D000081806C400A1002C482A30020480B122AA +:10C4E0002C480B12020580816022500A14020201BE +:10C4F0000000000000000000B80D6140F850321448 +:10C500000C8503E140D8503E140E800B2140FA0008 +:10C510003E940F85032000C00032000C80032E03E0 +:10C520005000000000000000981DE441F9103D4556 +:10C530000FD003F400FF003F450DD003E440F91095 +:10C540003F440F9103E442F9103F400FD403E60645 +:10C5500070000000000000001805E400F9003E40F3 +:10C560000CD003F4088D023F400FD003E400CD004F +:10C5700033400C90032400F90032404C982306000D +:10C5800070000000000000003810E000E8002E00FD +:10C59000488002E800D0002E800B8012E002880064 +:10C5A000A2000A80122200B881222808CF020E04BD +:10C5B00030000000000000000805C400B1002C405D +:10C5C000281002C40081002C400B1002C40091000E +:10C5D000264009100254A0B52CA542085082020141 +:10C5E00070000000000000001815A400A9002E50E3 +:10C5F000589002E4809B002E458B9202E400990043 +:10C6000026440B90026408B500254A08510206042E +:10C610006000000000000000A015E400F9003E5496 +:10C620000C9043C400C9903E700F9803E400D900F9 +:10C6300034604D900A6400F90036402C9E032804B3 +:10C6400070000000000000002801A400F9003C4038 +:10C650000F9C03E630F9003E620F9003E400E9000E +:10C660003A404E9003A400790C3A400F901BCA0048 +:10C6700060000000000000002810A000F8003E004C +:10C680000C8113E108C84832003C8003C000F01060 +:10C690003E060C8003F008CC0033040CC0030A04EF +:10C6A000200000000000000028052800BA002E80AD +:10C6B00008EC42FA208E0023A008E842E800BE8081 +:10C6C0002F8008A002E800DA00228048E0020A0079 +:10C6D000400000000000000028054C00B3002CC002 +:10C6E000093482C900838020F0083082CC00B380F6 +:10C6F0002CF008B002C1208000A0320800020A001D +:10C700005000000000000000A0011CC0B7012FC8AD +:10C71000895002D80287C421E2487082DC00B70049 +:10C720002C40087202CE00970823C008700228002F +:10C730004000000000000000A8081E00F7E13DE8EE +:10C740002D6803F200C780B0E0086803DF80F68040 +:10C750003DE08C7E03DA00CC8031200CC80B2A022D +:10C760000000000000000000081DAC08FB003CC0F9 +:10C770000E8003E008F9003E400FB002EC00FA0022 +:10C780003E402FB003E400FB003CC02FB003C206C4 +:10C7900060000000000000000005FE00FF927FEA3C +:10C7A0000CF803FE00CCA03F200DF9033E00CF8023 +:10C7B00033600FF803F600EF8433E02CC803000069 +:10C7C0007000000000000000A8119C00B7002FC8F6 +:10C7D000085402D800D6042D010869021C00850007 +:10C7E00021430B70039AC08C00A30208F1022A04B3 +:10C7F000600000000000000000009C00B7012DCC8C +:10C80000087002D40094282DC208C2025C00860081 +:10C8100021800B7102DC00A71021C00848024000F3 +:10C8200020000000000000002014CC08B3002CF011 +:10C83000080502C02090802E000800824C02800073 +:10C84000A0610B3002A0008000A03088B10A48042B +:10C850003000000000000000A815BC00FF002DC83B +:10C860000C3D03E400DB023EF02C904B7C00C10049 +:10C8700032204FF013E000E80132008CAC036A0470 +:10C8800060000000000000008000EC00FB043EC2DD +:10C890004FB003E004FA403EC24E9823AC10F800BB +:10C8A0003E5007B013AC00FB003EC20F9203A00045 +:10C8B00030000000000000000110DC00CF003FC08D +:10C8C0000CC8233682CF803F800CE003EC00F920B7 +:10C8D00033C00EF003F810DC0033004CE8210044B4 +:10C8E000300000000000000081046C00AB002EC08E +:10C8F0004A8D4221008B422ED208B003EC00B8884A +:10C9000034620DB002E4008B0022C008900A20407F +:10C91000100000000000000080052C008B002EC0DD +:10C9200008A0020D0089102E08289202EC04BB001A +:10C9300022A008B0026402B30220C008A202A00034 +:10C94000400000000000000008040C00A3002EC0FE +:10C950000A90220C1080002C00180282CC00B0003B +:10C960002640093002C820800020000810068201FD +:10C970000000000000000000000D6C00CB002EC085 +:10C980000CA102240088003C000C8003EC00FB009A +:10C9900032800EB003CC80DB0032C00CA0038003D9 +:10C9A0005000000000000000A01DFC00FF003FC080 +:10C9B0004FC213D410FC003F000F0003BC00FC006A +:10C9C0003F400FF023E012FC01BF000FD0036802CC +:10C9D0007000000000000000C005FC00C78033C0EC +:10C9E0008BB403B0C0CF2E1F0C4FC3033080FF01A8 +:10C9F0003F080FF0007C00FF2133E40CE00330001F +:10CA000070000000000000008010EE008B8223F018 +:10CA10000BB5120D8888C00E980B86022100BBC092 +:10CA20002EE44BF7832F44BF9022C848A6822004EF +:10CA300030000000000000008805CC098A0020506A +:10CA40004BB20A80CC83010C8C0B230A0460B31414 +:10CA500024404B3002CC10B30020C8E9110662011B +:10CA60007000000000000000C015AC018A80A244E4 +:10CA70000BB002A10488402EA00B20022820BB404E +:10CA80002E400BB0022C08BB0022C009B00270047B +:10CA900060000000000000004015EC00C38332E09D +:10CAA0008F0003A002CBC43E28078B032100F9C0EE +:10CAB0003E100FB003EC007B0032C00DA003500409 +:10CAC0007000000000000000E0019C02FF003FE059 +:10CAD0000FF4435E80FC943F000FC02BF250FD2109 +:10CAE0007E848FF0036C0CFF003FC00E6203B80021 +:10CAF00060000000000000004010AC00EB0032407D +:10CB00002C80036900CB30B2004FB343E500CB402B +:10CB100072182CB003EC28C3213AC10F94031004FF +:10CB20002000000000000000C8053C008B202250BF +:10CB300008B002280088C02A008BB402E800DB009D +:10CB4000623008F002FC008F8022C00B9547320053 +:10CB50004000000000000000E0054C00B10020C2D1 +:10CB60004830024980834260120B3002C8008202C2 +:10CB70002C3009B002CF0183502AC00B2002B8002C +:10CB8000500000000000000020011E009D80A0E079 +:10CB90000879225E60879029A00B7802C6009281F6 +:10CBA00005E0097802DE40878021E00B29020800B9 +:10CBB000400000000000000048080C40F20030C0B7 +:10CBC000083A034404C31430C00F2203CC80C200CF +:10CBD000A4D20D3013CC20C30038C44F044312023A +:10CBE0000000000000000000401D9C00EE003FE03F +:10CBF0000F7003B402F4103FC08FA003FC007E004E +:10CC00003BC00EF083EC00F7003FC00FC003D0061E +:10CC10006000000000000000A805FC00F9003EC014 +:10CC20000FA003AA12CB0132800FB0132814F98091 +:10CC30003A4003B403EC42CB183EC00FB0032A00C5 +:10CC4000700000000000000048119D00B5002DC4D8 +:10CC50000B704B7C00840021800B70029410B2009A +:10CC600029C00B7282DC0087202DC10E70021204D5 +:10CC70006000000000000000C0009E00B7802DE0B2 +:10CC80000B68029E00838021E05B38021E00B4C066 +:10CC900025E0097832CE0097802DE00B5C4E300005 +:10CCA00020000000000000004814CC00B3442CC059 +:10CCB0000B3C02CC40930820E00B30028C10B3C038 +:10CCC00028D81B3002CC0893016CC00AB882120429 +:10CCD0003000000000000000E815A800F6103E80BB +:10CCE0004BED83B800CEE4B3A30FE0033800FE00A1 +:10CCF0003B800DA002E800DA003E800FE8023A0413 +:10CD000060000000000000004800E010F8403E0015 +:10CD10000F80136000E0003E00430803E000F808C5 +:10CD20003A000F8003E000E8403E000E8023D2006E +:10CD300030000000000000000810C400D9C0BE4050 +:10CD40000F9003E600F9003240019A032400F90035 +:10CD50003E400F9003C44009100E400F9A03020496 +:10CD60003000000000000000800464048904A26018 +:10CD70008B9D80A600B98022404898022400B9000B +:10CD80002E408B9002E49489602E400B940B20007F +:10CD90001000000000000000180524009908AE48AB +:10CDA0004B1002E581B91020441B94022410B900F5 +:10CDB0006E600B9002E40089002E400B9402060086 +:10CDC0004000000000000000080404808900A06802 +:10CDD0000B12028489B12020481A12120480B12259 +:10CDE0000C480B1202C481A1202C400B120202013C +:10CDF0000000000000000000B80D6000D800BE0078 +:10CE00000F050BE140F80032140F85032140F800B4 +:10CE10002E800F8513E002C8003E140F05012E037B +:10CE20005000000000000000981DE440FD00BF44D9 +:10CE30000FD103F4407D10BF4445F12BF440FD10A9 +:10CE40003F440F9103E440D9103E400FD103A606A2 +:10CE500070000000000000001805F600FD001F62D1 +:10CE60000FD8823600BDA03B680CDC8326C8D9A051 +:10CE700033600D99835620D5A82E440CD8838604A0 +:10CE800070000000000000003810E148B8002E00DB +:10CE90000B0A822220B85022BA088A2222808800F7 +:10CEA0002201080C02200088002E28888802CE0467 +:10CEB00030000000000000000805C400B1002C4054 +:10CEC0001B100A8440B10028580A3202050099401C +:10CED0002065091042C40091002C400A3082C20132 +:10CEE00070000000000000001811A400B9002E40DE +:10CEF0001B9002A580B910224808104204100900B6 +:10CF00002240089002E4009B002C400A9422C604B0 +:10CF10006000000000000000A015E400F9203E4081 +:10CF20000F9013A710F960BA502E9C0A2584D1F0F7 +:10CF3000B2600D9003E400D9003E400E9003A800BB +:10CF400070000000000000002801A40CF9903E6A67 +:10CF50008F90236600F1083C400F9C43E440F98029 +:10CF60003A440F90032404E9023E402D9113CA0075 +:10CF700060000000000000002810A000E8203E0132 +:10CF80000C0003A120E85032102C8C032100E80093 +:10CF900032020F00132088C80832000F8C03CA0029 +:10CFA0002000000000000000280528208EE32F90BC +:10CFB0000AE0063B00EE04239008E00228088A02FB +:10CFC00075908BA04158908E802A810BE0038A10C7 +:10CFD000400000000000000028054E00A3006C6027 +:10CFE00008381A8E40A08020CC0930020C05A3041A +:10CFF00028C40B30020D0183C020C00B3002CA00D0 +:10D000005000000000000000A0011E0887002D62F3 +:10D010000B70921C08A00061C00960061C80A7006C +:10D0200021C00B72025801878829C00B6012A8002A +:10D030004000000000000000A8081E00E6803D60DF +:10D040000C78429600E480A3600D78033F00E380F3 +:10D0500021E00F7B031608C78031E24F7843EA02D4 +:10D060000000000000000000081D8C01F8003C409A +:10D070000EB002EC00F8013E404E3033ED20DB01F3 +:10D08000BEC00FB403EC00FB003ED80FA003C206E5 +:10D0900060000000000000000005FE00C78423605F +:10D0A0000C780BBE00FD803FE00FEB033E00CF800D +:10D0B0003B250CF8837E40CD8033E20BF903000062 +:10D0C0007000000000000000A8119C0287001548B5 +:10D0D0000870021420B600359A49C8039C84A70042 +:10D0E00039D00A70021A08A40021C00961422A043A +:10D0F000600000000000000000009C00870021404C +:10D100000871029400B5002D400BF1225C02070863 +:10D110002C50087002500087002DC40B50420000B4 +:10D1200020000000000000002014CC0083022440F6 +:10D13000183D0A0100B05824200930028F4083E0D6 +:10D140002CC10A30420800B3016CC009081608045B +:10D150003000000000000000A8158C008B00324059 +:10D160000C2503A848F8813E800F80637C00CB80AB +:10D170003AC00CF0036C00CA02BFC00F988B2A049F +:10D1800060000000000000008000EC00F9003E504C +:10D190002FA40BC800F0403ED00FA033EC20FB04BE +:10D1A0007AE00FB003ED08E90332C00D9003E00010 +:10D1B00030000000000000000110EC40EE003EC016 +:10D1C0000CDA037004CC02B1A00EF023EC00FF00D7 +:10D1D0003720CDB073EC88FB803FC00F3003004494 +:10D1E000300000000000000081046E0088802CE107 +:10D1F00008940AA902884022D008B942EC04BB0076 +:10D200002CD40DB002ED20BBD02EC00BB002A0403C +:10D21000100000000000000080052400AB802EF00C +:10D2200029A0826D0088082204089042EC00BB000F +:10D230002A8108B002E409BA042EC14B988220006A +:10D2400040000000000000000804040083002CC01F +:10D250000A210284108200E000180A12CC00B300F8 +:10D260000CC0093002CC90B0002CC00B100282011F +:10D270000000000000000000000D6400EB003E0014 +:10D280002CB40364088800B2000CB243FC00FB001D +:10D2900056000CF001E400FB003FC00F800B0003C0 +:10D2A0005000000000000000A01DF400FF003F40FF +:10D2B0002DF061F000F40027010DB111FC00FF0218 +:10D2C00007C00FF003EC40FF003FC00FC00368062B +:10D2D0007000000000000000C005F600EF903D4C1B +:10D2E0002CC013F408FD20374C8E82837484DCC27A +:10D2F0003FD80DF203ECC0FF813F000CF803F000B3 +:10D3000070000000000000008010E6008B242E5CFE +:10D31000088D02FF48B9902F540B84823E40A080B4 +:10D320002EC40AFC42ED80B9802E600A9812E004F7 +:10D3300030000000000000008805E401A300284838 +:10D340000A0042C400B1002C490B0A4204A29121F8 +:10D350002CC90831028CC1A3002C40081802A2017C +:10D360007000000000000000C015A0208B822E4439 +:10D37000588002E400BB102E400BA1120C01891052 +:10D380002EC00AB002EC01B8802EE20AA102F0041D +:10D3900060000000000000004015EB40EB403E60E4 +:10D3A0000E8733E400B9A136C00EA80B2600DAC000 +:10D3B0003EC08DB003EC00FB853EE108B80390054C +:10D3C0002000000000000000E001B800FF022F6014 +:10D3D00003E883FC10FD801F401FD013BE40EE0405 +:10D3E0003FC00FF043FC08FD003CC00FD011F80017 +:10D3F00060000000000000004010A400DB00B2400C +:10D400000E94032400D900BAC00C2003E490FB0062 +:10D410003AC00CB003EC01FA003ED02C9803900403 +:10D420002000000000000000C80503008B00224817 +:10D430000884222C00B90022C008A002ED008BA0B5 +:10D4400021C008F002FC00B9802EC008A002320002 +:10D450004000000000000000E0054520930022F895 +:10D460000B300A8440B2002040081002C4008080C3 +:10D4700028C02839024C00B1002CC0083002B80086 +:10D480005000000000000000200136009F80216055 +:10D490000938029E00B2C02060484812D6C686D025 +:10D4A00021E0087800DE80B7822DE008F80208004D +:10D4B000400000000000000048080C20D31030C8D5 +:10D4C0000F30038400F1003040241903E4C0E04031 +:10D4D0003AC00C3203CE80B1283CC00C301392020B +:10D4E0000000000000000000401D9C00E6007FC01E +:10D4F0000EF0237440FF103F404FD003FCD2CE0407 +:10D500003FC00FF403FC00FE003FC00F7103D012B8 +:10D510006000000000000000A805EE00CB0016C06F +:10D520000D80032720CB003EC20AB053E428C181FE +:10D5300032C10EB9032C00F18035E00CB8032A0487 +:10D54000700000000000000048119C0287102D4070 +:10D550000870035C00A7002D40287002D4048704E3 +:10D56000A1D00B72021D00F70021C00D5002120461 +:10D570006000000000000000C0009E00858025E0E3 +:10D58000097802370387802FE0087812C6108D8053 +:10D5900025E80B38021E80BC8425E0085802700084 +:10D5A00020000000000000004814CD8083882CC0BB +:10D5B000083C024E01A3D22EC408B102CC008380E5 +:10D5C00024C10B30020C00B340A0D209301252002B +:10D5D0003000000000000000E815BA00CAC0368024 +:10D5E0000D67132800CE003EA00CED03E800CEE04E +:10D5F00036801EA00B2804FE00B7B20CE00B7A00A8 +:10D6000060000000000000004800E040F8102E100C +:10D610000F8003E001D80A3E000F8003C002F80823 +:10D620003A000F8003E010E820BE000F8013920044 +:10D6300020000000000000000810E500FB003E4054 +:10D640000C91032600618032400C90032400C90035 +:10D650001E400C9C03E401F9003E400F9003C20001 +:10D66000300000000000000080046700B9002C407A +:10D67000009C02A600790022402890022400890024 +:10D680002C44089802E400B9802E400B9002E0017F +:10D69000000000000000000018012400BB0026501C +:10D6A00028908224849920224049900224008900F5 +:10D6B0002E40089002E400B9602E400B9002C60490 +:10D6C000400000000000000008040600B1002E48E1 +:10D6D0000812028480B120A04809120A0480810047 +:10D6E0002C48281242C48831002C400B1802C20179 +:10D6F0000000000000000000B80D6000F850361473 +:10D700000C80032000E80032140C85032140C8502F +:10D710003E140C8003E14038003E008F8003EE038E +:10D720005000000000000000981DD400FB043D44A0 +:10D730000F5123D448ED103D444ED123F442FD0057 +:10D740003E448F9103E458FD003F500F5003E6061E +:10D7500070000000000000001805F400F9003D40D2 +:10D760000CD003F400DD023E400C9003E440C910ED +:10D77000374007D0072400E5002F6A0F700306002A +:10D7800070000000000000003810E000B8003A000F +:10D79000808002E00088002E000A8053A2802CA026 +:10D7A00022000B800A2000B8002E100980030E040E +:10D7B00030000000000000000805C400B1006C400B +:10D7C0002A1002840181802E40091002F4008D0489 +:10D7D00020400B10028400B1002C400B9802420143 +:10D7E00070000000000000001811A420B9002A40B9 +:10D7F00088B402E601A9202E480A9000A440AD405A +:10D8000022400B9012A404B9012E410B9002060491 +:10D810006000000000000000A015E400F9C03E60B8 +:10D820000C9413A602D9421C600C9E01C604C100D0 +:10D83000B2401F9002A400E9083E684F980B6804AC +:10D8400070000000000000002801A640F920387098 +:10D850000F9103E400D9803E400F9C13A400F9000F +:10D860003E400F10036410F90A3E500D9A03CA009F +:10D8700060000000000000002810A100D8043E0055 +:10D880000C8113C002D8203E002D8403E000CC0898 +:10D890003A000F8043E000F841320007818B0A0410 +:10D8A000200000000000000028053A608A002FA830 +:10D8B0000AE022E8027E482E8008A042E8048E009A +:10D8C00023A80BA882E800EE00A2804B60020A00A9 +:10D8D000400000000000000028054C0093006CC0D0 +:10D8E000083002CC0013812CC0083002CE408240A8 +:10D8F00028E00B3802CC00B31024C08B38020A0099 +:10D900005000000000000000A0011E0087202FC072 +:10D910000A7002DC0AB6002CC8887206D80086009D +:10D9200021C00B7002DC84AF80A5C00BD0022800A0 +:10D930004000000000000000A8081E00D7803DA0A5 +:10D940001C7813D602D7803DEC087E23FE00CE80E3 +:10D9500039600F7803DF00F68075E00F78032A0244 +:10D960000000000000000000081D8C00FB103E803D +:10D970001FA021CC00FA003EC00EB003E802FA005E +:10D980003E400FB013EC00EA013AC00F9003C2060C +:10D9900060000000000000000005FC00FF803F6008 +:10D9A0000899077E00DD803FE20CF803F602DF8075 +:10D9B000B3E00CF8033E41CC8033E40FF803C00021 +:10D9C0007000000000000000A8119C40B7002DC0AE +:10D9D0000D5A22DC8075002DC0087102F0208700EE +:10D9E00021C00A70021C00D42821C00B7202EA0474 +:10D9F000600000000000000000009C40B7002D0007 +:10DA0000087222F40087002DC2087002D4008780BB +:10DA100025400930025C01AD0029D04B7002C000E6 +:10DA200020000000000000002014CC00BBC82CA087 +:10DA3000092002CE00A3002CE0A83D42C2008B804A +:10DA400024400B300A6C08A340A8E00B3402C80441 +:10DA50003000000000000000A815AD00FF483C2881 +:10DA60000CA9236C808B003FC00CFC03EC00D88019 +:10DA700034400D30037C02A34038680F2403EA04CD +:10DA800060000000000000008000ED88FB003E50B8 +:10DA90000FA103EC043AC03EC00FB083E802F810B7 +:10DAA0003A410E9003AC009B08B6400F8103E000A2 +:10DAB00030000000000000000110FC00FF00B32057 +:10DAC0000C50131C09CD8333C08370003C00DC1064 +:10DAD00032600EF1432C00CE043B700CF083004406 +:10DAE000300000000000000081046780BB0162215B +:10DAF0008A89202C0080E022C00BB003D8108C044F +:10DB00002240059002AC00D88036400A90022040A6 +:10DB1000100000000000000080052600BB00220667 +:10DB20000880022E00882022C009B002A4009900BB +:10DB300062C408B0062C008880224108A0022000A0 +:10DB4000400000000000000008040C00B30020406A +:10DB50000A00820C00800020C00B3022A00081004F +:10DB6000A0C00930028C00900024400A2802020163 +:10DB70000000000000000000000D6000FB0220001B +:10DB80002C92032C02880031C00BB502A400D104F2 +:10DB900032400E90032C40C9003A408CA003000391 +:10DBA0005000000000000000A01DF400FF002F0046 +:10DBB0000FC003DC00FC003FC10FF043F000FD008C +:10DBC0003F404FD003FC00F5003F400FE003E80664 +:10DBD0007000000000000000C005D880CC00B70431 +:10DBE0004EE1033C20DF10318006F0037F00FFC0D0 +:10DBF0003BC00EF2035E00EF1033D02CF203300076 +:10DC00007000000000000000C010E90088C6205C21 +:10DC100008A45765008F522AF009FC020400BB00DB +:10DC20002DD90974836428834422848806823004B1 +:10DC30003000000000000000C805C9008010200866 +:10DC400008311204B2A30020841B34020C80B320DC +:10DC50002CC70936028C809340ACC80831283201A9 +:10DC60007000000000000000C015A9008800A2504C +:10DC700008350224008B042EC109B0022494BB0095 +:10DC80002EC00BB002CC608B002E800880003004C8 +:10DC900060000000000000000015E702CB18B28011 +:10DCA0002CAC0A2E08EB0032124EB0032B80FB0086 +:10DCB0003AC00AB003AB08EB042E480CB88300044A +:10DCC0007000000000000000E001B680FF8039CA4B +:10DCD0000DE803D640E7043B664E7003B800FF0131 +:10DCE0003FC06CF0037006E70031040FC143F80039 +:10DCF000600000000000000040108500CB40329022 +:10DD00002FB00B6480FB08BA100DB0A72D00FB04E8 +:10DD10003EC08EB0036D00DB0132408C33039004B3 +:10DD20002000000000000000C005240083E0A2D015 +:10DD300040B0022504BF80A05008F80220008B02EA +:10DD40002FD008F00224008F80360108844236006C +:10DD50004000000000000000E8054400834820C4A3 +:10DD60000900024600B301A8901930128C00A304E8 +:10DD70002EE20AB0020C00834928C0093C02380098 +:10DD80005000000000000000F0013604838021E113 +:10DD90000838121E28B39821A0193882960087836C +:10DDA0002DE2087822368C87802DE00979023E002A +:10DDB000400000000000000048080400C33030C8E4 +:10DDC0004D000B4C80F31238C00D3A028C80F300EA +:10DDD0003CC00E300B0E00C30C3AC00D30031202D3 +:10DDE0000000000000000000401DB406FF103FC00E +:10DDF0000FB013BC00FF107FC00EF1A37C00FF1218 +:10DE00003FC20FF523BC41EF183780AEC003500668 +:10DE10006000000000000000A805E400DB003EDA1E +:10DE20000C800366108B0032808CB6034A004B8056 +:10DE300032C80CB4030A10DB003EC10CB0432A0008 +:10DE40007000000000000000C811B40087042CC05E +:10DE50000D70031C08874820810D72825C00D7007A +:10DE600021CC28F0021C1087202C0008400A320424 +:10DE7000600000000000000080009600B7812DE0E7 +:10DE80000848020E04878021E00878023E0187805E +:10DE900021E01879023A0197A02D6008380220008D +:10DEA00020000000000000004814C600A3C62CC0DB +:10DEB0000930020C01830020E00930024E0093007B +:10DEC00020C04930220F6483026CD428300212042F +:10DED0003000000000000000E811AB80FAE03C8850 +:10DEE0000CE0022802CA00B3A90CA0033B10CA0030 +:10DEF000A2800CA00B3800DA003FB00CE6033A0415 +:10DF000060000000000000004800C02098083E00AB +:10DF10000F800BE100F8013C104F0003A040F80017 +:10DF20003E100E8003E000F8003C022F0493D20064 +:10DF300030000000000000000810E400C1C13240C1 +:10DF40000C98032640F90032400C98032424F90071 +:10DF50003C600C1003A400F98232400C90030204D0 +:10DF6000300000000000000080046400890022509E +:10DF70000D98022580B90022520D9C022400B900A0 +:10DF80002E600890422400B940364008900A2000D4 +:10DF90001000000000000000180524008D00234040 +:10DFA0000812022400A110A26008928A2400B9017C +:10DFB0002E46089002A400B150224028908206000C +:10DFC0004000000000000000080404848520A1D85F +:10DFD0000910020480B32020402912060400B10178 +:10DFE0002C482812020400B1202448081202020121 +:10DFF0000000000000000000B80D61428A00B3007C +:10E000000C05032140E050B2002C80022140F0506A +:10E010003C140C8513A150F85032140C85232E03A8 +:10E020005000000000000000981DF440F9103E442C +:10E030000FD40BF444F9103F504F1103F400F900D2 +:10E040003E440F9153F414F9103F440FD103E602FC +:10E0500070000000000000009805E6A0DD88B366AF +:10E060000CDC833688BDA0376A0CDA0B2502C94068 +:10E070003F784F98B3E504CDA072780CD88B261466 +:10E0800070000000000000003810E30088422231D8 +:10E09000080A0222A0B8F922100D84126A80888032 +:10E0A0002E200B0802E280A8A8A23848A8020E0081 +:10E0B00030000000000000004805C4A28100204894 +:10E0C0000812424500B100244009140224008120B6 +:10E0D0002C580B1082C4049140646C0830821205E5 +:10E0E00070000000000000001815A4008900224103 +:10E0F00008908A6480B9002250099006640899004B +:10E100002E400B9006C401B90226618890020604D5 +:10E110006000000000000000A015E400C9002240DB +:10E120002C94236400B90036400990130500C900FF +:10E130003E404F9013E5C0D90026402C94032800A0 +:10E1400070000000000000006801A402E9083C40E3 +:10E150000F900BA400F1003E410F9043A488E90406 +:10E160003E400F9003E600E1003A409F9263DA00E0 +:10E17000600000000000000028108010E001320064 +:10E180008F80032000D80830018C0003E102C8040E +:10E190003E000C800B2100C80078000F86030A00A7 +:10E1A0002000000000000000280528008E402B827F +:10E1B0000BA0023A008E80238208E20228108A0017 +:10E1C0002F9828A01228008E202E804BE4020A00EF +:10E1D000400000000000000028054C02A240208002 +:10E1E0000BB0024E4093C0A0200836028C00930072 +:10E1F0002CE20830064C12930828C00BB0020A002B +:10E200005000000000000000A0011C0882402940CE +:10E210000B70025E08840823400870061C8087008B +:10E220002D200879125C0094002DC00B304228008C +:10E230004000000000000000A8083E00E48031A17A +:10E240000F58137600D08031C00C3803BE80D781C0 +:10E250003F208C79037F01D68039E84F68032A007C +:10E260000000000000000000081DBE00FA003E0093 +:10E270008F960BA400EA003CC00F9003AC20FB403B +:10E280002E000FB203ADA0EA003EC00FA01BC204D7 +:10E2900060000000000000004005FE08DE8133A49D +:10E2A0000EFC133E00FC8013200C68033E20FFC8C8 +:10E2B0003F601DF8037E00C78033E20CD8031000D6 +:10E2C0007000000000000000A8119C00864131C4CD +:10E2D0000879429C00BC1021408535035C00B700E2 +:10E2E0002DC00872022C00A70137C00851422A0035 +:10E2F000600000000000000010008C4082002481BB +:10E3000008D8021420B50020400960021C40B70064 +:10E310002C400B3022DC00970021C408400244004E +:10E3200020000000000000006014EC009206209025 +:10E330003815028600B80060500930024E01BB005B +:10E340002E400B3002CE20B30024F048020A5804BD +:10E350003000000000000000A815BC00CA00A69410 +:10E360002C90032E00FB05B2850D90033F90FF001B +:10E370007E801FF043FC219A0033C83CB2036A043C +:10E3800060000000000000009000EC02EA403D80C8 +:10E390000F1093ED00FB403E908F3003EC80FB00AC +:10E3A0003E911CB0032C10E8003EC81F9003A5103E +:10E3B00030000000000000008010FC02E40073A0A8 +:10E3C0000CFC037C02FF1013C41CC0033C00FF00C4 +:10E3D00037E00DF003FC00ED8031C00C3263200407 +:10E3E000300000000000000084006C008AC022B1F0 +:10E3F0008AB8434A10DB2020F00A94036C00BB0764 +:10E4000022B808B002EC11E8C0B2C02A921A20006B +:10E41000100000000000000080012C00AA8022985B +:10E420000890022F03BB012A8308B24E2C04AB02D2 +:10E4300022C428B022EC09B35062C008B002200008 +:10E44000400000000000000008040C018300608010 +:10E4500008120A440093002A804A30020C00B300DC +:10E4600060C0083002CC00B30260C0080046020160 +:10E470000000000000000000800D6C00E802228017 +:10E480002CF2432C00FB00BAC008A5023C00EF00B0 +:10E4900036C04DF013FD51FB0032C00CB00320011B +:10E4A0005000000000000000A01DFC007E043F8022 +:10E4B0000F3143F002FF0037C00FF003FC08FF00EC +:10E4C0003FC00FF003FC00EF003BC00FC003E81695 +:10E4D0007000000000000000C005F240FC803F24F6 +:10E4E0000DD853D604DF323FCC4CC043FC00DF6074 +:10E4F00037C00FC4037CD0DF2033D80DF843F000C1 +:10E5000070000000000000008018E880B0012E08B4 +:10E51000889002EC208B702FCC08B382FDE0BF40C6 +:10E5200022D80B9302FDC0AF1028F008BC12F004F3 +:10E5300030000000000000008805C400B0002E017B +:10E540000A1282EC80B3002CC80A00328C00A3307F +:10E5500020D20900028C80830028D80B3412F201EB +:10E560007000000000000000C005AC01B8022E00E1 +:10E570000A9012EC108B002EC00AB000EC00B30021 +:10E5800022C10B9202CC01AB002AC002B002F004FF +:10E5900060000000000000004015E000FA0C3EC0E2 +:10E5A0000FA013EE20DB003EC02E8853EC00FB00D2 +:10E5B000B2C08FAC83AC08DB001AC04FB003C004FC +:10E5C0007000000000000000E001B800FE003FC045 +:10E5D0002DE003FE807F003FC00DD203FC00BF0191 +:10E5E0003EC00DC803FC0CFF003FC009F023F8003B +:10E5F00060000000000000004010A400FA4032C19A +:10E600000FA0032908DB003EC00E8503EC20CB00E1 +:10E610003AC00EA403EC00FB003AC20EB003100493 +:10E620002000000000000000C8052C00BA6020C0D7 +:10E630000BA0020800AF002FD00BB502FE028F0026 +:10E640002FC00D800A3C00B70023C205F02236001F +:10E650004000000000000000C0044000B18820001D +:10E660000B10020C0083002EC80B08064D408300DF +:10E6700020C00830060C0893200AE04A3002380017 +:10E68000500000000000000020105A00B59021202A +:10E690000B58423E00A7802DE00B6902DE408792B6 +:10E6A0002DE00918029E01B78029E00370023E00A8 +:10E6B000400000000000000048084400F101300064 +:10E6C0005F18030C1083003CC40E0403EC008300AD +:10E6D00030C40C31038C00F30038C80E3103120231 +:10E6E00000000000000000004015BC00FD04BF0455 +:10E6F0004F5803F808EF083FC00FF001FC00FF4C33 +:10E700003FC10FD0033C00F70037C20D7203D006A3 +:10E7100060000000000000000805E200DB0032C0DD +:10E720004DA8032C08FB007EC88FB00B6F45EBC2D1 +:10E7300036C007A003EF20CB50B2C00C79032A00EB +:10E740007000000000000000481998008F0021C0F0 +:10E750000B60035C0037002DD20B30020CA887241D +:10E7600021D0097002DD88872A23E808700232046C +:10E7700060000000000000002000B600978021E04B +:10E780000B68021E00B7802DE88B48821E80A38490 +:10E7900025E80B6802CE02878021E0087A0220007B +:10E7A00020000000000000006804CC08838220E004 +:10E7B0008B2A024840B3002CC00B30820C0083002F +:10E7C00000C1093102CC00830020C008300A1204C5 +:10E7D0003000000000000000E815E800DAA032A8D0 +:10E7E0008DA8033B00FA003E800FE4036800EA02B4 +:10E7F00036800FE403E800CA0032802CA0033A04FC +:10E8000060000000000000004801A010F800BE20D9 +:10E810008FC103E024F8003E100F8403E000F801EC +:10E820003E000F8003E000F801BE100F8003D2000D +:10E8300030000000000000000810A400F940324041 +:10E84000CF9003E400C9000E500F1A032600F90010 +:10E850003E400F9081E400F98032400C9003C204E6 +:10E86000300000000000000080046404B104224075 +:10E870000B9002E400A9002E530B920A2648B9041B +:10E880002E400B9002E400B9800250089002E00094 +:10E89000100000000000000038052400BD002340E7 +:10E8A0000BD012C40089022E400B90222400B90024 +:10E8B0002E400B9002E400B1202040689022C60058 +:10E8C000400000000000000028141400BF12A14006 +:10E8D0000B5002C400A1202C480B12020410B111ED +:10E8E0002C480B1322C400B140205A081002C20168 +:10E8F0000000000000000000B80D6140F840321434 +:10E900000F4503E140C8503E158F850321E8F868A4 +:10E910003E140F8403E1E0F02832A8CC8023EE03FC +:10E9200050000000000000009815C410F9203E407F +:10E930000F9003F400F9103E440FD103E400F920D6 +:10E940003E440FD303E400F900BE400F9403E606F3 +:10E9500070000000000000001815E400FD103340B6 +:10E960000CD0032400D9003F404CD003F600FD90AA +:10E970003A400C9003E6A0FDA837680CD883260027 +:10E9800070000000000000003810E008C8A022005D +:10E99000088002200088002E000C8012E000B88061 +:10E9A00022000D0A02E380B0C020340884034E0424 +:10E9B000300000000000000048008409A100204150 +:10E9C000089002240091002C40081002C500B1609C +:10E9D00020400810A2C420B128244A081002520185 +:10E9E00070000000000000001814A4018100A24083 +:10E9F000A89000254089012C40089402E400B90049 +:10EA00002A40099002E401B90422414890024604D8 +:10EA10006000000000000000A014A520E9003240C2 +:10EA20004C100B2600D9003E402C9803E400F9005E +:10EA3000B2400C9003E400F90036402C90036804C7 +:10EA400070000000000000004801A400E9003E4002 +:10EA50000F9003E600F9003E400E9A03E400F9002F +:10EA600036400F9003E400F9003C400F9003DA00B9 +:10EA700060000000000000000810A100F800320053 +:10EA80000F8013A000C80032048C8003A0C0F800DF +:10EA90003A000F80032000C00932004C80010A04B4 +:10EAA000200000000000000028052800BE00208093 +:10EAB0000BE0028800AA0003A00AE602FA008A001E +:10EAC00032800BA00228008E80A3802820028A00BA +:10EAD000400000000000000028056C00B348204002 +:10EAE0000B10020C00830020C00834828E049900B1 +:10EAF0000AC01B30020C02905020600830020A004D +:10EB0000500000000000000080111C80BD0A214858 +:10EB10000B52029C40A3A020800A6002CE008520F8 +:10EB200021C40B7A061E80952021900870022800CF +:10EB3000400000000000000088081E80F780B179C6 +:10EB40000FDB023E20C7A0B160CC78139600F1F035 +:10EB500039E20F7B130F00D4A031602C70032A021E +:10EB600000000000000000000815AC00F7003E4067 +:10EB70000F9003ED80FB103E400BB023EC00F9201A +:10EB80003AD80FB00BED81ED103E800F3003C20676 +:10EB900060000000000000000004BE20EE80336032 +:10EBA0000CD8831E006F8033E00FB8113204F5805B +:10EBB00033E00FF8832F40FE80B3E00CF803100021 +:10EBC0007000000000000000A8189C00BC00A144D8 +:10EBD0000810035C008F0021800BEA221C80B50125 +:10EBE00021C00BF0021E80BE0023802A70022A047E +:10EBF000600000000000000000009C20A7002340EF +:10EC00000B500A3C00A70025C00A43021000B500C3 +:10EC100021C00B70821C80B40021C0087002040067 +:10EC2000200000000000000020048E04B3002240F9 +:10EC30000914024C00830020C00B24820400B100A0 +:10EC400020C08B3A022C01B00020800A30021A0446 +:10EC50003000000000000000A8159E00EB043340C7 +:10EC60002DDC031D60EF003200CF9A032800FD0069 +:10EC700033C18BFC0B3C00FC0032800C90032A0457 +:10EC800060000000000000008000AC10F8003E4072 +:10EC90000E9823AC04FB003C000F8420ED00F9002B +:10ECA0003EC04FB003EC00FD003E800F9003E40037 +:10ECB00030000000000000002110FC00CF80334035 +:10ECC0000CD083FC00EF003F400CF1413010CD0030 +:10ECD0003FC00070133C00E400B1D00C10032004CE +:10ECE0003000000000000000A1042C008AE42A404B +:10ECF000289002EC008B003E020A80022C828904DC +:10ED00002EC10AB00A2C00890222F22A98022000A1 +:10ED1000100000000000000080052C0280142A4032 +:10ED2000089002EC08AB042E84081082801089033E +:10ED30002CC04AB0222C00AA002280089102200098 +:10ED4000400000000000000008142C008000284053 +:10ED5000081102EC0083002C810A005A880001008F +:10ED60002CC00A30020C00820020800A100202012E +:10ED70000000000000000000000D6C00C9003A40D7 +:10ED80000CD403FC00EB003E400C9203A0004D00AD +:10ED90003FC00EF0333C80E80032C00C90032003EB +:10EDA0005000000000000000A011FC00FC003D40ED +:10EDB0000F5003FC023F043B014FC4137000FD00E1 +:10EDC0003FC01FF001FC40FC003FC00FD013E8061D +:10EDD0007000000000000000C005F8E0FF803DC0AA +:10EDE0000DF382F080FF4031CB0CF303FD04EFC143 +:10EDF00033E00F7903FE00CF4233F04CF8033000CC +:10EE00007000000000000000E010E908B9812FF058 +:10EE100008F452E920BF4023F00AF302FD088B00FA +:10EE200036E00B8022E8808F4022C008B082300498 +:10EE30003000000000000000C805CC00B1802CC5E7 +:10EE4000093242C8C0B33120C1083202CCD4BB2041 +:10EE500068C00B3002CC2093602088083202320157 +:10EE60007000000000000000E015A000BB802EC074 +:10EE700008B002EA00BB0062C10AB002CC00AB00DD +:10EE80002EC00BA000E800830022C108300230042D +:10EE900060000000000000000015E890FB803EC00C +:10EEA0000DB003E210FB0032C04CB013EC00E9548B +:10EEB0003AC00FB003E600CB00B2400CB00304042C +:10EEC0007000000000000000E001B800FF003FC03B +:10EED0008FF003F000F702BFC10FF023FC00DF0644 +:10EEE00037C08FC907FA92FF043F502FF003F80094 +:10EEF00060000000000000005010AC00C9003EC2DD +:10EF00000EB023E400EB003AC80EB003EC00F900A9 +:10EF10003EC00FB403A400FB003E800FB083D004BA +:10EF20002000000000000000C80528008B742DC0E0 +:10EF300008F002E4008F0021F008F002FC10D3007A +:10EF40002EC00B90122C00EF002EC00BB602F60064 +:10EF50004000000000000000E8054800A3002CC4A9 +:10EF60000A3002C000A30068F00A3012CC04A200EC +:10EF70002CC00B3002EC00B3012EC00B3402F800A1 +:10EF80005000000000000000B0010C0087802DE858 +:10EF9000087842DA00878025E0087902CE00968062 +:10EFA0002DE00BD902DE00A7802DE00B7802FC00DB +:10EFB000400000000000000048080C40E3103CC086 +:10EFC0000A3803E800EB0038C20A3003CC00E34003 +:10EFD0003CC00F3403CD00F3203C880F3003D20235 +:10EFE0000000000000000000401DB480FF043FC886 +:10EFF0000FF083F840FF183BC00FF483FC00EE02D3 +:10F000003FC00FF0033C00EF083F800FF013D00625 +:10F0100060000000000000008805E800CB003EF220 +:10F020004DB213E804CB0132F84DB2136D20F80055 +:10F030003EC00F30032400FB003E408FB8032A007F +:10F040007000000000000000C8118C0086002CC079 +:10F05000087302D812873020CB08F2021D05B500D4 +:10F060002DC00B60035010B7092DC00BF002320405 +:10F07000600000000000000080009E0087802DE4FA +:10F08000097A02CE01878021EC0978025E80B7C040 +:10F090002DE00BF8021E00B7A02D600B78022000B7 +:10F0A00020000000000000004814EE0082802CC008 +:10F0B000083002EC008300A0C00830020C00B380CE +:10F0C0002CC10B30024E00B3002CF10B300A12049D +:10F0D0003000000000000000E815BA80C6003E8045 +:10F0E0000DA003F840CA0032800DA0136800FE0294 +:10F0F0007E800FED833910FA003F8C0FA0033A0495 +:10F1000060000000000000004800E012F8903E009F +:10F110000F8003E000F8053E000E0003E000F880D9 +:10F120003E000F8003E060F8007E000F8003D200F5 +:10F1300030000000000000000810E400C9803264C4 +:10F140000F9043E406C1043A400F9003E400E90045 +:10F1500032400F90032400C10132400C9003C204DE +:10F1600030000000000000008004640089C02240DC +:10F170000B90022400890022501B90222400810061 +:10F1800022400B90222408C9002040089402E0008D +:10F190001000000000000000180524009920224003 +:10F1A0000B1002A40089002A580B90028400A900C9 +:10F1B00022400B100A0400990222C1089082C60066 +:10F1C0004000000000000000080404009102A0C8F4 +:10F1D0000B12020480812220489B120204908901B4 +:10F1E00020400B1002040281222240081002C201BA +:10F1F0000000000000000000B80D6142DA01320199 +:10F200000F8503A140C0503A018B8523A144E850EB +:10F21000B2000F85032148D85132142C8503EE0328 +:10F220005000000000000000981DF500ED023E4473 +:10F230000F9103F440F9103E440F9103E440FD00A8 +:10F240003E400FD003F400E910BF400F9003660664 +:10F2500070000000000000001805E621C5003368BA +:10F260000F9A036F88C9C033680C9E032780D9406A +:10F270003E400F9003C510D9E836500CD003E6008D +:10F2800070000000000000003810E10888008200D3 +:10F290000B8E82EBC888E02200288842A2808A80F8 +:10F2A00022000BAA02E20088C022A9088A038E0469 +:10F2B00030000000000000004805C400810020D09C +:10F2C0000B1132848481606050081606050091207D +:10F2D00020400B1082E409912024400810C2D20182 +:10F2E00070000000000000001815A40489042240EA +:10F2F0000B9002C400A9002241009002A4008100EA +:10F3000022400B9222E58099012261089002860436 +:10F310006000000000000000A014A582819032402F +:10F320000F90136702C90032400C90232404D9C007 +:10F33000B2400F9C03E600D90036500C9003E8045D +:10F3400070000000000000006800A680F9003E4048 +:10F350000F9003E700D900BC420F9053E404F9106A +:10F360003E400F9803E604E1003E402F9003DA0090 +:10F3700060000000000000002810811048103208D2 +:10F380000C800F2102C8003A040F80076000F8408B +:10F39000B2000F840B2000D80036100C8003CA0482 +:10F3A0002000000000000000280428048E80238034 +:10F3B00008A04228008A0023A04BA002E800BA005F +:10F3C00076800BA00208008A00328008E003CA00A1 +:10F3D000400000000000000028054C00820020D002 +:10F3E0000830020C009B0028C01AB0026C00B30267 +:10F3F00020C00B30020C00A30022C0283482CA00B7 +:10F40000500000000000000020011C00870020E0E8 +:10F410000878020C00972025C00B7102DC81B72010 +:10F4200021C00B7A423C80872021C0087002E8008E +:10F43000400000000000000028080E82C780B1E0F4 +:10F440002CFA061E08D3B139604E78125EA0FFF088 +:10F4500021E00FF8031F08E3A033E00C6803EA0281 +:10F460000000000000000000081DAC40FB003EC092 +:10F470000FB203EDA8EB103A800FB0C3EC40FB00D5 +:10F480003EC00FB083EC80EB70BEC40FB0038206A9 +:10F4900060000000000000004005FE00CE80B36068 +:10F4A0000FFC837E20EFB03BE00FB8033E00CF811E +:10F4B0003FE08FF883EF40FFC233E10CF803D00048 +:10F4C0007000000000000000A8119C8287182180B5 +:10F4D0000B30021C60D71021D00B7B023C00D70000 +:10F4E0002DC00B7002DE00BF00A3C4087003AA0485 +:10F4F00060000000000000000000BC11870021C077 +:10F500000B30021C00932069C00B70021C008700A6 +:10F510002DC00B7102DC20B71021C00860028400EE +:10F5200020000000000000006014CD00834020C0D7 +:10F530004B30020C01830020C00B30020C00938082 +:10F540002CC00B3002CC01B30020C008302298043C +:10F550003000000000000000A815BF20CAC03280A3 +:10F560000FF0033E009F003A800FF00B3C00CF9855 +:10F570003EC00FF603FF00FF0031E02CB003AE04E5 +:10F5800060000000000000008000CC80FB003E50C6 +:10F590000FB003AC02FB007E500FB003EC00FB0089 +:10F5A0003EC00FB203EC20F3003EC60F9003A00054 +:10F5B00030000000000000000110FC02CF9873C86A +:10F5C0000F70033C00FF0033280FB0021C004F00F7 +:10F5D0003FC00FF003FC00FF0133C00CE403E40460 +:10F5E000300000000000000080046C008380A2F85E +:10F5F0000BB0422C00BB0032100FB0036C04AB0008 +:10F600002EC00BB012EC04EB0022C04A9482E00042 +:10F61000100000000000000080056C008A0022003D +:10F620000BB0022C00B300A2C00B3002AC00AB0444 +:10F630002EC00BB042EC00BB0022C008B022E0009C +:10F64000400000000000000008000C008B012000BA +:10F650000B30060C00B30020C00A320ACC00A30015 +:10F660002CC00B3002CC00A30022C04A0012C20101 +:10F67000000000000000000000086C008B0422C0A5 +:10F680000FF1031C00FF0432C00BF203BC00EF00BB +:10F690003EC007F003FC80FF00B2C00CA003E003F3 +:10F6A0005000000000000000A019DC00F5003FC081 +:10F6B0000FF003FC01FF023BC00FF1037C00FF00D1 +:10F6C0003FC00FF013FC40EF003FC00FC003E8063F +:10F6D0007000000000000000C015F240CC80372010 +:10F6E0000CD803B044FC083F0E0FC103FC00CC94BF +:10F6F0003F0A2EC4037D80CF103FC00FC08330006F +:10F7000070000000000000008008E0908802228164 +:10F71000089213A4403B6022180B8102FCD48100A4 +:10F720003AB00A94023D40AF632FDF0B98002004EB +:10F7300030000000000000008805E0008800204044 +:10F74000883082C000B00828800A1002CC208001D6 +:10F750002C401B06028C90936068C04A0042220134 +:10F760007000000000000000C005A002880022C058 +:10F7700008B002E420BB8826980B8042CC188A008F +:10F780002EC21B9802AC00AB002EC00B9882300436 +:10F7900060000000000000000011E3C0CB02320056 +:10F7A0002C8003AE08B9003E700FB903EC02484844 +:10F7B0003CC00F8C93EC00DB001AC00EAC031004AD +:10F7C0007000000000000000E001B200FF00BB80FC +:10F7D0000FC043B640BD003B600FE803FC00FF9440 +:10F7E0003BE40E600F6C08EF013FC00F6003F800B0 +:10F7F00060000000000000004010A100FB003E601F +:10F800000FA003ED00F9403A000F9003EC02C90489 +:10F8100032D00F90032C08DB00B6C00DB403D00427 +:10F820002000000000000000C8050000B3892EE0A1 +:10F830000BA403A401B9002E010B9042FC108950C7 +:10F84000A2C08DB4023C448F0023C008B002F20075 +:10F850004000000000000000C0040C00B0802E003A +:10F860000B1202C800BA002CC00B2002CC00A20070 +:10F8700020002B2D9A2E42830028C0082002F80079 +:10F88000500000000000000020001E04B4802DA0E5 +:10F890000B58029200B6802DE00B6802DE40A68075 +:10F8A00021242948021E80878069E0086102C8007F +:10F8B000400000000000000048180C00F0303C4CF4 +:10F8C0000F3203C880B20038800F1B03EC00E03019 +:10F8D00030040FB1030E85CB003AC00C3103D202C5 +:10F8E0000000000000000000401CBC00FC113FC4F0 +:10F8F0000FB813B004FE023F800FC003FD00DF12FB +:10F900001D040FD043BC01EF1033C40EF303D00627 +:10F9100060000000000000000805EE00CB003E0083 +:10F920000F80032800F8003E403DB003EF08C900F7 +:10F930003A000CA003EC98FB2032D20CA8032A0258 +:10F94000700000000000000048119C0087012D801D +:10F950000B40421C043700A140086002CC808700A5 +:10F960002D802E7002DCA9B72821D0087002120069 +:10F9700060000000000000002000BE0287802D60B3 +:10F980004BE8025A01B48828E08878C2DE5286C06B +:10F990002960086802DE40B392E1E828280270007E +:10F9A00020000000000000006814CC008B802EC0F6 +:10F9B0000B20024D809B2020E0083802CC00838081 +:10F9C0002CC00AB002CC08B30020C0083102520497 +:10F9D0003000000000000000E805A800CAE03E80FA +:10F9E0001FA40B7900FE003F821DE003E800CE401B +:10F9F0003B882CE403E801FA0032800CE8037A0427 +:10FA000060000000000000004811A000F8093E005E +:10FA10008FC083A018F8003C200F8803E000F8088E +:10FA20003E200E8083E101F0003C000F800B92002D +:10FA300030000000000000000810A400F94232402D +:10FA40004C98030400C9003A400F90232400B98168 +:10FA50003C400C92032400F90532406C90C3C20470 +:10FA6000300000000000000080042414B900A254FB +:10FA7000089B1A240289002240289002A400B99011 +:10FA80002E40289C822504B9002240089812E000EC +:10FA9000100000000000000018052400AD00234005 +:10FAA000085002640089002A400810026400B9006E +:10FAB0006E400890022500A9002240089106C60069 +:10FAC000400000000000000008041400B510A1442C +:10FAD0002850024480813020480812028440B180BE +:10FAE0006CC80812020480B1342048081202C20116 +:10FAF0000000000000000000B80D6140E8403290B6 +:10FB00000CC5036140C0403A140F850321B0F85082 +:10FB10003E000C85032140F840B0140C8003EE0138 +:10FB20005000000000000000B81DC404F9220E4877 +:10FB30000F1013B440FD303F444FD100E484FF0167 +:10FB40003D440FD10BE440F9303E440FD103E604AD +:10FB500070000000000000003805E400DD403F5068 +:10FB60000CD0032C00C90036400F90132704F50178 +:10FB700037400CF003F620F9A832680CD003C60019 +:10FB800070000000000000001800E00088A02E288F +:10FB9000288002200088A022000B800A6280B80022 +:10FBA0002200088002E100B8E0223A08A002CE0458 +:10FBB00030000000000000004800840281002E4058 +:10FBC00008100A4402810824400A10024580B90046 +:10FBD0002440291002C400B1082444081002C201C4 +:10FBE00070000000000000001814A40489012E50C9 +:10FBF00048B2026400910022460B90026400B901F1 +:10FC000026C009B012E400B1002640089002C604E4 +:10FC10006000000000000000A004E400C9003C40B7 +:10FC20000C90036400C90236500E93032400F9902F +:10FC300036480D9483E408F900B6400C9403E804B8 +:10FC400070000000000000006810A400E9003E40C1 +:10FC50000F9013A400E9022E61059003A400F9009F +:10FC60003A400E9043E410F90038402F9003CA0048 +:10FC700060000000000000002810A000D80132043D +:10FC80000F8043C001C800B2010C80032000C840AF +:10FC900030008C8483E000C80032006C8403CA0406 +:10FCA000200000000000000008042800BA002380A3 +:10FCB0000BEA02E800AA00228008A00228008620A1 +:10FCC00037A08DE402F800DA00228008A002CA0002 +:10FCD000400000000000000008056C00B30020C0D8 +:10FCE0000BB8024C04830020C008B0020C02830051 +:10FCF0002040283402CE908300A0C0083002CA0001 +:10FD0000500000000000000020011CC0B588214008 +:10FD10000B7002DC80A32021E04832420E908E015D +:10FD20006550097002DE20932121C0087002E800AE +:10FD3000400000000000000028181E00FF80B1A055 +:10FD40000F48027E0087A033E0287A0B1F00C48092 +:10FD500031608C5803FE00C7C833E80C5803EA0230 +:10FD60000000000000000000081DAC00FF003E0085 +:10FD70000F9023ECA0FB403EC08FB503ED80F80050 +:10FD80003C400FB003E800FB023ED00F9003C206D8 +:10FD900060000000000000006004BE00FF803FE043 +:10FDA0000FD903FE20CFC833EA8FFC033F00FD804C +:10FDB0003F600EE803F200CF802FFE0C78030000B6 +:10FDC0007000000000000000A8009C00B5022DC0DB +:10FDD0000B5842DC80CF0021C10B30121C40B40212 +:10FDE0002D46087112C800E7002DC40870036A048C +:10FDF000600000000000000000009C00B7002D0221 +:10FE00000B4602DC08970021C90A30221C00B4000E +:10FE10002D400A5082C400B7002CC8285002401060 +:10FE2000200000000000000040148C18B3002E20B9 +:10FE30000B1802CF4A83C220C10B34220C04B858DD +:10FE40002C400B2802C800A3002CC0081402480450 +:10FE50003000000000000000A805BC00FB003E8050 +:10FE60000FA002FC00DFA0B3C00EF00B3C00FBC0F3 +:10FE70003CA00EBD03EC00FF003FC00C30036A0441 +:10FE80006000000000000000A010EC00F9003E013E +:10FE90008FB143EC00F3003EC04FB013EC00FB0009 +:10FEA0003E800C8403E10073003EC10FB243E000CA +:10FEB00030000000000000000150FC10FF8037C03F +:10FEC0000CE003FC20FF0833C00FF083BC00FF00F0 +:10FED00033C02E40031C01CF0011C04CD00300449E +:10FEE000300000000000000081046C04B3022272A4 +:10FEF00008A116EC00BB0422C00BB042EC00BA19FA +:10FF0000B6D0089C4A2680DB0022C00890036040DF +:10FF1000100000000000000080052C00B9106220D5 +:10FF200048A002EC00BB0022C00BB002EC10BB00EA +:10FF300066080AA81226109B002AC028B0262000B6 +:10FF4000400000000000000008000C00B900200084 +:10FF5000083202CC04B30020C04B3002CC00B30006 +:10FF600020000800020100930028C008300642115A +:10FF70000000000000000000001C6C00F900B2400E +:10FF80000C8202DC01FF00B2C00BF103BC00F900DF +:10FF900026402E80032104CF00BBC00C9003000339 +:10FFA0005000000000000000A01DFC00FD003F40CC +:10FFB0000F8103FC00FF003FC00FF023FC00FC009A +:10FFC0002D402FC003F088FF0037C08FD003E80218 +:10FFD0007000000000000000C005FE40FF8033C23A +:10FFE0000CF8037CA0FF903FC42CB403BC80CF402E +:10FFF00037E00FF1936E44BF303F202CF863F004DC +:1080100070000000000000008010EC00EB2023F056 +:1080200008B8523D00B3002EDC08F4421C428B40DD +:1080300022C80BF6036C88BB302E0008B202E004A5 +:1080400030000000000000008805CC00BB0820C004 +:108050000830024CA0B3202680883602CCA0936062 +:10806000A4C20A32424C90B3202C0B883082E20129 +:108070007000000000000000C015AC08BB22A2C0C8 +:1080800008B0022C00BB002E9008B002EC009B0050 +:1080900022C00BB0026C00BB022E2008B002F00020 +:1080A00060000000000000004015EC00B18332C009 +:1080B0000C1A036C10FB0034C00CB003EC08DA009F +:1080C00036C00EB00B6C00FB003E280CB002D00096 +:1080D0007000000000000000E001BC00ED803FC027 +:1080E0000FD403EC00FF003FC80FB0033C00EE408C +:1080F0003FC00F7003FC00FF003F800FF003F8004B +:1081000060000000000000004010AC00FB20B0C088 +:108110000FB403AC02CB0032900EB0036C00EB0046 +:108120003AC00CB002EC00FB003E910FB00390008F +:108130002000000000000000C8052C00BB8023D7F1 +:108140000B90023C148B006A0828F000BC008300EE +:10815000BEC088F0132C00EF002E800BB007B200D9 +:108160004000000000000000E0054C00B34020D0BB +:108170000B28028C00830120C01AB8006C10A100EB +:1081800068C02A30028C00B3022E004B3002F80483 +:10819000500000000000000020011E00B7A021E0F8 +:1081A0000BECC21E04878029E40879829E40AF90C0 +:1081B00029E00A38001E00A7902D240B78028800C1 +:1081C000400000000000000048080C50FB0930C0CF +:1081D0000F20028C40C30020C00A38034C44E10049 +:1081E000AAC00E31438E00F3003C000F3003D202D0 +:1081F0000000000000000000404DBC00FF203FD008 +:108200004F7003FC00FF003DC00FF343FC40D7005C +:10821000BFC00DF4C3FC40FF003F400FF003D00689 +:108220006000000000000000A805EC00FB0032D058 +:108230000D9001EDC0FB003EC01FBA03ACC0C800EA +:1082400032E08DB443EC00FB0036A00CB0036A00B2 +:10825000700000000000000048119C00B70021C819 +:10826000086002DC20B7002DC00F74A21C28D600C5 +:1082700035C00872025C08B744A180487002120041 +:108280006000000000000000C0009E00B78020E4F5 +:10829000097826DE00B7802DE20A70128C88818072 +:1082A00021E0097802DE00B3A025A028780270043E +:1082B00020000000000000004814CC01BB8020C05A +:1082C000083042EC00B3002CC00A30220C009300AE +:1082D00024C1083002CC00B30020E008B002120430 +:1082E0003000000000000000E815A800FA08B28085 +:1082F0000DE203E800FA003F800AA003A800CE5078 +:10830000328005A003E800FA0037A80CA0037A0425 +:10831000600000000000000048006008F8003C0019 +:108320000F8801E000F8043C004F0013C000F80083 +:108330003E000F80036000F8023E010F8003D20070 +:1083400030000000000000000810E400F990124026 +:108350000C9003A400C9003E700E94332408C90099 +:108360002A400B9003E400F9003A400F9003020406 +:10837000300000000000000080046400B942226068 +:10838000081002240089032E40089002A4018104F1 +:108390003E400B9002E400B90222400E9002200001 +:1083A000100000000000000018052400B9402A4A0F +:1083B000089102A40089002E401A900A2404890022 +:1083C0002A400B9002E400B1002A400B9002060004 +:1083D000400000000000000008040400B101A848AB +:1083E000889002048081402C5018140A841089401F +:1083F0002C400B1002C400312020400A100A020158 +:108400000000000000000000B80D6140F0503A008C +:108410002CA002A142C8003E00DE002321428800B9 +:1084200038140F8503E140F85038140F05032E016E +:108430005000000000000000981DE408FD003644D4 +:108440000FD0036440F9003D500F9403E5007D40D8 +:108450003E400F9403E400F9103F400E9003E60401 +:1084600070000000000000001805E400FD403368C3 +:108470000CD003E781F90033780DD81326A0CDA0E6 +:1084800032400D9B032400F9A03C442C9007860049 +:1084900070000000000000003810E000B8A0A2103A +:1084A0001880038284B880362C2E0F02A3A0D8E057 +:1084B00036228B080342A0F8E02E28088802CE045A +:1084C00030000000000000000805C400B100A0500A +:1084D000283002C580B10820400910A24408814814 +:1084E00020400B14020480B1382C4808128282010B +:1084F00070000000000000001811A400B10022402C +:10850000089202E400B90226584A9002E408994011 +:1085100026400B90026408B9012C48089012C6044A +:108520006000000000000000A015E400F980324067 +:10853000089883E404B90130400D900B6402C9002F +:1085400032400F90032400F9001E580C9003A80439 +:1085500070000000000000002801A400F9203C4049 +:108560000F9803A400B9003E428E104B8404F9001A +:108570003E408F9003E400E9003E400F9003CA00A4 +:1085800060000000000000002810A000D8003208A1 +:108590000F8483A004C8043E008380012000C00033 +:1085A00032000F0003A000C80032104E8013CA042E +:1085B0002000000000000000280528008E90A38005 +:1085C0000BE4022800CA002F804AA013A800AA00CA +:1085D00036810BA00228008A00228008A0038A00AE +:1085E000400000000000000028054C0093C020D08F +:1085F0000B34028C008B002CF08B18024C00830093 +:1086000060C00B30028C02830028C10A3002CA000D +:108610005000000000000000A0011E00B40B69C063 +:108620000958061E8097102FC24870829C80A708A8 +:1086300025CC0B70021E8187A2ABC4087302E80030 +:108640004000000000000000A8083E10DC8421E08B +:108650000F78429F02C7883DE02F71034E00CF8004 +:1086600021E20F78839E49CFD039E80E7803EA02E1 +:108670000000000000000000084DAC40CA003600B9 +:108680008F3023ECA8EB403CC00F9643ED80FB00FD +:108690003ED88FB143ED80FB2036CA0FB0A38206CF +:1086A00060000000000000000005FE80FC8031E05A +:1086B00005AA10FE44FF903FE1CFF9173F20D78075 +:1086C0008BE40FF8033E30FF8037E00FF8004000E6 +:1086D0007000000000000000A8119C00BD1021C027 +:1086E000084A02DCC0B7002DC20CD3021C808700F0 +:1086F00029C04B72021C00B70121C00BF0122A04E2 +:10870000600000000000000000009C903400218008 +:108710000970005C0CB7002DC408501A0C009700BB +:1087200021C04B30021C00B70025C00B7002400076 +:1087300020000000000000002014CC00B000600009 +:10874000083E02CC00B3020CE02BB0020C009300F8 +:1087500028C00BB0022C10B30020D603300208044E +:108760003000000000000000A815BC00FB00B200B3 +:1087700005BE037C00FF003E200CB0033C00D98006 +:1087800033C08BF0033C00FF0037E00FF0036A04B6 +:1087900060000000000000008000EC00FB043E00D0 +:1087A0000FA423CC00FB003E81089003EC00E914E9 +:1087B0003EC00FB003EC10FB003EC00FB003E00062 +:1087C00030000000000000000110FC00FF003780B6 +:1087D0000FFA03FC00CF003F9006DC233C00FD10A5 +:1087E00033C00FF00B3C00430033C00FF003C04414 +:1087F000300000000000000081006C09BB1922322B +:108800000BBE036C008B002C900DB802AC00B100C5 +:10881000F2C00BB012AC008B0022C00BB003A04022 +:10882000100000000000000080052C10B30026207E +:108830000B9012EC018B002AC20A90022C00BB00A4 +:10884000A2C00BB0022C00AB002AC00BB002E000AB +:10885000400000000000000008040C01B3002000EC +:108860000B00028C0083002EC00B34028C00BB0076 +:1088700020C00B30020D00A300A0C00B300282010B +:108880000000000000000000000D6C00BB043680FA +:108890000FB202FC02CF0238C00EF0033C00FB0016 +:1088A00023C00FF0033D02EF0033C00FF043C003BD +:1088B0005000000000000000A01DFC00FF003F0071 +:1088C0000FF4237C00FF003FC00DD003FC00FF002D +:1088D0003BC00FF003FC88DF003FC00FF003A80689 +:1088E0007000000000000000C005F050CE1233D030 +:1088F0004C868330805F6833C40FF3833CC0CC3830 +:10890000B3080CC603F1A0FF0033240CC203F0002F +:1089100070000000000000008010EC80D22023D8FE +:108920000D96028860AF4023DC0BF6023CC28860E3 +:108930002252089122E100B724A2488A848260046E +:1089400030000000000000008805C4008100E0C481 +:108950000A00020480A320A8C01B300A0C00A0005B +:10896000280C090202C480B31C2208190302E21178 +:108970007000000000000000C015A400998062C0D3 +:108980000BA032A451AB002AC08BB0000C00A9C0D0 +:108990002A2108B822E200BB0022841BA8427004EE +:1089A00060000000000000004015E200CBC932C0AA +:1089B0000E8B132210DB0132C00FB00B2C0068812C +:1089C0003A222C8823E300FB0030308D9C83D004B6 +:1089D0007000000000000000E001BA40F7043EC251 +:1089E0000DD823D8007B0037C00F7033FC10D200A5 +:1089F00035C08FC003F400F7023FE00E8003F8009B +:108A0000600000000000000040108120C80830C055 +:108A10000C00832440C3893AC00EB00B2C08C9480F +:108A200072540F9103ED02EB8A3A628C800B1004B2 +:108A30002000000000000000C8052B048840A3C2ED +:108A400002AE1227428F4423C20BF4023D000A40BB +:108A500022E00BB502EC208F44A2408DBD233200F2 +:108A60004000000000000000E0054940838124C16F +:108A700008280201009300A0E80A30828F60B390BA +:108A800060B80B28124A0093002090092002780059 +:108A9000500000000000000020011E0287A825E011 +:108AA0000A7B021A04878021E40B78828E02969159 +:108AB00021210B6940DB40979223A089588208004E +:108AC000400000000000000048082582C30034C0B8 +:108AD0000C9B4308D0D32038C00EB0038C00B300E9 +:108AE0002080071003E000D31038180D3003520225 +:108AF0000000000000000000401DB4007F201BD0DB +:108B00000FF103F840EF003FC00FB4037C20CF0407 +:108B1000BF400FF003E410EF183DC00FE003D00694 +:108B20006000000000000000A805E800E300B2C4F7 +:108B30000CA0032400DB6832C80CB403EC80C880AE +:108B4000B6E00CA0032E00CBE0B2600CB80B2A00FC +:108B5000700000000000000048119C028700A1C8BE +:108B60000870021C08970221D4087402DCC00700B8 +:108B700021C08870021800830821C0085002120426 +:108B80006000000000000000C0009E20AD8029E0D1 +:108B90000858021E0097B021E8087802DE10158000 +:108BA00021A10848025E0087A465A0087802300071 +:108BB00020000000000000004814CF108170A8C001 +:108BC00038300A0D009300A0C1283002CC028388FF +:108BD00020E038340A4D72830024E82834821204DD +:108BE0003000000000000000E815BA40EEC0BA8076 +:108BF0000CE0033910DA0032800CA003E800DEC874 +:108C000033A00CE0037B00CA0037B10CE4233A0424 +:108C100060000000000000004800C100F8003600BD +:108C20000F8003C02038003E000F0003E000F80270 +:108C30003A240F8083A001F8043A040D8013D20077 +:108C400030000000000000000810E444C100324081 +:108C50000C9032240CC10638400D90090400D90054 +:108C60003E400F18032400F9013E400F9003C20458 +:108C700030000000000000008004640689002A50D3 +:108C800008940A2400894222500A90122500890083 +:108C90002E500B9C0A2510B9002E500B9002E000BC +:108CA0001000000000000000180524208900204268 +:108CB0000810C2AC1089082A4209900224209900A9 +:108CC0002E420AB1822C20B9006E420B9002C600DF +:108CD0004000000000000000080404008300284851 +:108CE0000812628C80810020400210028480812062 +:108CF0002C490B12060484B3026C400B1202C20111 +:108D00000000000000000000B80D41E0C8783014F9 +:108D10004C0513A142C078381E0D87830140D05006 +:108D20003C140E05030140F8783C140F0503EE03D4 +:108D30005000000000000000981DFC00FF000E44E1 +:108D40002FF1037440F9003E400D90036440FD1084 +:108D50003F440FD101F440F9013FC00FD103E606B3 +:108D600070000000000000001805E622E988B2400B +:108D70000F90032416C98C367B8F9C83A790C90063 +:108D80003E500494132450C9E03E500F9003060057 +:108D900070000000000000003810E28088A0222847 +:108DA0000B8A022A8088A42230088E0A220288A018 +:108DB0002E2888AA12229088F42E200BC8020E04B6 +:108DC00030000000000000000805D420A508214262 +:108DD0000B50821431850825400A502294408508A2 +:108DE0006D40085002540295002D480B50824201FC +:108DF0007000000000000000181584008D10234052 +:108E00000BD00034018D00234158D00234008D086E +:108E10002F5008D20274809D002F480BDC024604BC +:108E20006000000000000000A015E740E9C03240EB +:108E30000F90092600C90436401F9023A408C9409A +:108E40003E400C940B6420D9023E410F9403680409 +:108E500070000000000000002801A400F9803E40DE +:108E60000F1403C508F9003E401F9023E400F900E9 +:108E70003C40AF98038600E9003E400F100B8A008B +:108E800060000000000000002810B000DC40B300CB +:108E90000FC0033102C404B1003C40031000FC4089 +:108EA00033000CC403B100CC00B3000CC403CA04EB +:108EB0002000000000000000280528008A8022A071 +:108EC0000BA0022A008A8422A108A0022808BA0165 +:108ED000228008A02B28008A802A8008E002CA008D +:108EE000400000000000000028054C029B8120E0AB +:108EF0008B3806CE00938020C00838020C00B38067 +:108F00006CE00AB0024C00930020E0083002CA0076 +:108F10005000000000000000A001100480082102A1 +:108F20004B4406D020900821028044021000B4C0B7 +:108F30002D10484002000094892930084002E800C2 +:108F40004000000000000000A8083200D68031A0D8 +:108F50000FE80BCA00D68023A004F80B1A00FF808C +:108F6000BFA02EC813DA025E8073A02C7803EA0239 +:108F70000000000000000000081DAC00F9003E40A9 +:108F80000F90032400E9003E400E8003E400F80047 +:108F900032400FB003E401E90436400F8003C206FB +:108FA00060000000000000000005FE00CD8033607E +:108FB0000CD8433600CD8033600CD923BE004D80E1 +:108FC000336008F80B3E00FD843F600FF903C000DA +:108FD0007000000000000000A8119004DE00238053 +:108FE000086002B8208E04238008680210008E20DA +:108FF00023820840021200F6002D800B41A0EA04F3 +:1090000060000000000000000000900084002100CB +:109010000841025040940021000A5202D800850203 +:1090200025040840221808B4002D100B7840C00019 +:1090300020000000000000002014EE22930020C059 +:10904000083802EC00930020C12A2002640282103A +:1090500024F00A3C422428B3002CE00B8882C80488 +:109060003000000000000000A815AD00CB00B2C029 +:10907000ACBE036E02DB00B2C01EA003E400CA1146 +:10908000B6D0ACBC032400FB003EC0CF8403EA048E +:1090900060000000000000008000E040F8003C009C +:1090A0002F8203A000E8003E001D9013A800F900E5 +:1090B0003A00818343E800E8033E040FB003E00078 +:1090C00030000000000000000110E000D6003780F2 +:1090D0000CA003F800CE0033800DA0132008CE00B2 +:1090E00033820C40733018CE001F804FC1430044C0 +:1090F000300000000000000081047C008D0023404F +:109100000AD002F4008D00234008D4803E428D40F6 +:10911000234008F0023E408D000F400BF402204037 +:10912000100000000000000080052C009900A640FF +:10913000089006E400910020408800022408804046 +:1091400020400AB002240089000E400B8402200057 +:1091500040000000000000000804000082002080A1 +:109160000A2106C801820020800832820808830094 +:1091700060800A0012088082002C800B300A0201F5 +:109180000000000000000000000D6000D800360064 +:109190000C8423E000C80032000D820B2002C800BE +:1091A00032000E00032002C8003E000F80030003BF +:1091B0005000000000000000A01DFC00BF003FC0E8 +:1091C0000FF003FC00FF00BFC08FB003FC08FF02DC +:1091D0003FC00DF003ED00FF023FC00FF003E806B3 +:1091E0007000000000000000C001F08CFF003D6036 +:1091F0002CB2837C90DF3831E00FF8033C00FF2075 +:109200003FC40EF4037C00F48033000DF803F0003B +:1092100070000000000000008010E120BB622E42C0 +:1092200028F4423E408F4422E00BB0837F44BFC10C +:109230002DDC2AF6023F45B880226188B802E0049E +:1092400030000000000000008805C580B2182EC85C +:109250002930320C08B32020C04B92020C00B340DE +:109260002CC08934124C00B00024C1493002E20104 +:109270007000000000000000C011A400BA0C2EE035 +:10928000A9B0062C008B00A2C00B90006C00BB00A4 +:109290002EC00B30026C00BA8026F008B002F00439 +:1092A00060000000000000004011EE00FBC43E78AA +:1092B0002DB0036C08FB0032C08B24832C00FB0014 +:1092C0003EC08FB00B6C08B2E016608DB023D004A6 +:1092D0007000000000000000E001BE98FF403FC0A9 +:1092E0000E7003DC00FF003FC00FE003FC00FF0036 +:1092F0003FC00EF003AC00FE00B9C00FF003F80051 +:1093000060000000000000004010AD00FA403ED0B8 +:109310000EB203EC00C3003EC00CA0032C01FB0006 +:109320003CC00EB803EC00DA003AD04FB023D004B2 +:109330002000000000000000C8052C00BA002CC06E +:1093400008F407BC14DF003EC01AA052BC00BF04E2 +:109350003FC08AF003BC00FA0022C80FB003F2003D +:109360004000000000000000E0054801B1006CC2B0 +:109370000A3042CC0083052CC00830028C01B304B3 +:109380002CC00A30228C00808028C00B3022F800CC +:10939000500000000000000020011E08B7806FE0B0 +:1093A0001878028E40B7802DE00A78029E00B780C0 +:1093B00029E10A78029E01BC8029E40B7802C800EA +:1093C000400000000000000048080940F1203CC4B3 +:1093D0000E3902CC00C3002CC40892038C88B31051 +:1093E0002CC40EB0078C00C20838C00F3043D20224 +:1093F0000000000000000000401DBC10FC007FC009 +:109400000FF083FC21DF083BC08F9001FC21FF0C93 +:109410003FC20FF103EC00EF0077C01EF00390068F +:109420006000000000000000A805E801F90032C05B +:109430000FB203EE90DBE13AC04D38132D30FB0044 +:109440003EE04FBA432C40FA003FC08CB003EA0024 +:10945000700000000000000048119C00B10021C015 +:109460000B7102CC20A72821C00B70135C08B71029 +:109470002DC44B34831CC1B7022DC01A7002D20414 +:109480006000000000000000C0009A20B4C425A2C3 +:109490000B7806DE00838029E01BF8025E80A7A01F +:1094A0002DC80A72021E00A68028E0087802F0008B +:1094B00020000000000000004814ED00B34024C369 +:1094C0000B3042CC00A30020C01B34024C00B30080 +:1094D0002CC04B30020C00B3882CD40A3002D204CA +:1094E0003000000000000000E815B800FE40B7A002 +:1094F0000FA003E800DA003A800FE2036800FA00E8 +:109500003E800FA00B2800EEE03FB004A003FA0459 +:1095100060000000000000004800E004F0083A107D +:109520000F8403E010F8003E004F8083E000F80055 +:109530003C000F80038000F8403E090F8003D200FA +:1095400030000000000000000810E420E900324470 +:109550000C90032400F9003E400F9013E400B90082 +:109560001E400C10032400C9A03C640C900382042C +:1095700030000000000000008004640089002268C0 +:109580000813022408F9002E481B9002E400B900D9 +:109590003E400C90022408F9402E600A9006E0003C +:1095A000100000000000000018012400A900204065 +:1095B0000890022400B9012E400B9002E400B9008B +:1095C0002E40089222240089002E40089002C600F6 +:1095D0004000000000000000080404808121E050E9 +:1095E00028160A0480A1402C404B1422C400B1006C +:1095F0002C500914020404B1002C400A1002C201CC +:109600000000000000000000B80D6140E85032008A +:109610008C80022000B8003E000B8033E010F80080 +:109620003E000C80032008CA003E000C8003AE03FD +:109630005000000000000000981DFC40FD102F416C +:109640004F9103E440F9403E404FD063E500F940BC +:109650003A502E94036500ED003F500F9003E6064C +:1096600070000000000000001815E600F9E033501B +:109670000CDA03A600D9803F400F9103A600F988B9 +:109680003E680CDE036600ED003B690C9003C600EB +:1096900070000000000000003810E108B8E0202051 +:1096A000188E26E10080A02E004B8842E150B84081 +:1096B0002E2A0D0A022008B8002E140D8002CE04B6 +:1096C00030000000000000000805C500B160204027 +:1096D0000831A2C50091482C401B12028400B10041 +:1096E0002C500916020500A3042840081002C201EC +:1096F00070000000000000001805A400B9082070E8 +:10970000289002E40089002E400B9002E408B9037F +:109710002C402990026400B9002E62099002C60410 +:109720006000000000000000A005E500F9D0B27064 +:10973000089003E400D9043E400F9003A410F902FE +:109740003E400D902B6400E98D3A600C9003E804D4 +:1097500070000000000000002801A400F9803E42D3 +:109760000F9003E400F9003E400F9A03E400F90073 +:109770003E402F1003A400F9223C404F9003CA0042 +:1097800060000000000000002800A000F04032004F +:109790000C8003C000F80032201F8003E000C800E6 +:1097A00032000C80022000C8C03E000C8003CA04B6 +:1097B000200000000000000028152810BA0023A097 +:1097C0000AE402E800BA002BA10BA002E800AA00FC +:1097D0002A810AA003E808DE002E800AA002CA003F +:1097E000400000000000000028054C00B304A0B1B8 +:1097F000083622CC00B30020E40B3002CC008300FA +:1098000020C00818020C0091012CC0083006CA00C4 +:109810005000000000000000A0011CC8B32121C2BC +:109820002A7002DC00B7A029C00B7202CE00A7810B +:1098300029C04A7402FE0097012CC00A7012E80089 +:109840004000000000000000A8081E80F7C031E0C2 +:109850000C4803DE11F78021E00B7A03DE00C380A1 +:1098600033D86C78033E00D6803DE00C7803EA02E2 +:109870000000000000000000080DAC08FB803EC0A6 +:109880000FD003EC04FB3C3EC00FB6076C01FB009D +:109890003ED00F9407EC01EA003EC00FB003C206B1 +:1098A00060000000000000000001FE00CFA43B604B +:1098B00008D9037E00CF803F254FFC87BE00CF80B4 +:1098C0007FFC0CFC037C00F69033E00FF803C00033 +:1098D0007000000000000000A8119C088F282140A3 +:1098E00008D0021C40A72031041B7802DC80D7007E +:1098F0002FC41AD0021E48B60061C00B7006EA04DD +:10990000600000000000000000008C008730694407 +:109910000850220C0087012D448B70068C108700A4 +:1099200029C90850021C44A60061C00B7002C00087 +:1099300020000000000000002014CD00838860405B +:109940000010024C002B002C411B3002CC00930075 +:109950002CC00A30420C00B24020F10B3002C80487 +:109960003000000000000000A815BD41CFC0BAF0D3 +:1099700028901B6C08CF002CC00FF003AC008B00AC +:109980003FC06CB04B2C01FB4022C80FB003EA046F +:1099900060000000000000008000EC04FB043FD4E5 +:1099A0000F1003AC00FB0032C05FB003EC00FB04FF +:1099B0003EC04F1013EC00FB883EC04FB003E000E8 +:1099C00030000000000000000110DC00C70033621E +:1099D0000CC00B3C00EF0033E01CF0133C08F70018 +:1099E00031C00ED803BC00FE003DC60CF003C044DD +:1099F000300000000000000081046C00CB0322470F +:109A00000898422C009B002AC00AB0022C00BB041C +:109A10002AC00AB002AC08FA002E6008B002E0408A +:109A2000100000000000000080052C009B0020407A +:109A30000898022C00BB0022880830022C00BB00D2 +:109A400022C08A9202AC00AA802EC008B006E000B4 +:109A5000400000000000000008040C008300A0404B +:109A60000810020C00B30028800A32120C00B30464 +:109A700028C00A30228C20B2002CC0083002C2015B +:109A80000000000000000000000D6C02CB00304020 +:109A90001C94032C00EF0032C088F08B2C00FB00DC +:109AA00033C0AEF003AC80EA013EC02CB003C0036B +:109AB0005000000000000000A01DFC00FF002F402F +:109AC00007D283FC00DF043FC00FB003FC00FF009F +:109AD0003FC00FD00BEC00EE003F400FF003E80654 +:109AE0007000000000000000C005F500CF083F48EE +:109AF0000FC39370D0DC303FD80CB2033CC0FF40A2 +:109B000033C42CF1036250FC3433000F5C03F000CB +:109B100070000000000000008010C4808B002F5AED +:109B20000BA61221C089702FDC08F2C23DD0BF40C5 +:109B300037DC88F50A2080E8102A160B9002E00432 +:109B400030000000000000008805C00083082C449D +:109B50000B02020C0080002CC80833428C90B330FA +:109B600028C84A3212800CB0A028280B1202E20149 +:109B70007000000000000000C015A2008B002E48FD +:109B80000BA022202088802EC028B00AAC00BB0089 +:109B90002EC00AB002A000AB822AA00BB202F004D1 +:109BA00060000000000000004015E700CB003EC050 +:109BB000CF9C0B2100D8883EC00CB003AC00FB004A +:109BC0003AC00EB043E840F8803A600F9803D004E2 +:109BD0007000000000000000E001B400FF000FE092 +:109BE00007A103E802FB003FC00F70237C00FF02C7 +:109BF00035C04DB0037420FC013F000FF803F8009E +:109C000060000000000000004010A500CB00BA403A +:109C10000C140B2F22C94032C08EB003AC00FB00E5 +:109C20003EC00EB003E400C90032002C90031004C3 +:109C30002000000000000000C80124008F00224026 +:109C40002CA54229008B04A3C10DF00A3C00BF00E3 +:109C50003FC008F0016900DA0522D00894037200C1 +:109C60004000000000000000E0056040830120C0CB +:109C70000900022000826022C00830424C10BB0262 +:109C80002CC008B01205009B002082093202380067 +:109C9000500000000000000020011690878020E0A6 +:109CA0000858021614848121E02939025E00B78029 +:109CB00028E00878027A80968121E009F8024800BD +:109CC0004000000000000000480808098B103844DC +:109CD0004D25120C00C21022C80A3803CC00F31024 +:109CE0002CC00C30038AC0D91032402D1003120250 +:109CF0000000000000000000401DBC80FF003F404D +:109D00000FF003F440ED003FC00EF303BC04FF006E +:109D10003FC20FF00BD400FF10BF800EF003D0063F +:109D20006000000000000000A805FA00CB023EC061 +:109D30000F9003A000CB003ACA0CB313AF24CB485A +:109D40001EC80FB6032C00FA003EC00F9003EA00B5 +:109D5000700000000000000048119C0887202DC4FE +:109D60000B5012DC0487002CC00870A21D00A74015 +:109D700025CB8B74821C00B7002DC10B7002D2045E +:109D80006000000000000000C0009A0187902DE0F4 +:109D90000B7802CE0086802DE4297A029E8087A06F +:109DA0006DE80B78021E00B5802D600B7802F00084 +:109DB00020000000000000004814CD0083022CE0C9 +:109DC0000B3002CC0083E02CC00830020C00A30052 +:109DD00024C00BB0020E20B3082CC00B3002D204FA +:109DE0003000000000000000E815B882CA003EA85C +:109DF0000FE003F8028E803E800DA05BA800CA0031 +:109E00003E800FA0033B80FE422F800FA803FA0480 +:109E100060000000000000004800E020F8003E0064 +:109E20000F0603C000F8113E000F0003E000F80029 +:109E300036000F800BE000F8043E200F8103D200B3 +:109E400030000000000000000810E400F9003E406F +:109E50000C9A032440C9C03E404C90032400F900F2 +:109E600036400790032400C90432600F9003C204F7 +:109E7000300000000000000080046400B9022E40A1 +:109E80000A9202250289E02E409890022400B9002F +:109E900022400990020400D90022440B9C02E000F9 +:109EA000100000000000000018052C00B9002C4034 +:109EB000089002242889002C40689042240CB104A8 +:109EC00026400B900A2C8081002240CB9282C60053 +:109ED000400000000000000008040400B1202C48ED +:109EE0000A1202048081212C4C0811020408B110CE +:109EF000204C09120224019120A0480B1002C2013B +:109F00000000000000000000B80D41E0F8503E14D1 +:109F10000C85032140C8503E1008068301F0F86804 +:109F200036100F05032940C85032940F8503EE0305 +:109F30005000000000000000981DF400F9103F449C +:109F40000FD10BF440FD122E4C03920BE400F920CC +:109F50003E4C0F9103FC00FD103F440FD003E6067A +:109F600070000000000000001805F620C9013E4006 +:109F70000FD0033C00BD0032630C9E432700E9C0B4 +:109F80003E680C98033400F9103F400FD003C60020 +:109F900070000000000000003810C220D8002E0021 +:109FA0000B80522804B8002238088803620088F029 +:109FB0002E3A488F0A2000B0802E000B8002CE047B +:109FC00030000000000000000805C48081002C4023 +:109FD0000B10020400B10020424814420580A12069 +:109FE0002C440810820400B1202C400B1002C20146 +:109FF00070000000000000001815A50199002E4017 +:10A000000B90022440BB0122410890122400A900B9 +:10A010002C400810402408B9406E500B9202C60430 +:10A020006000000000000000A015E714C9053E41D3 +:10A030000F900B2404F908B2402C900A2400E90088 +:10A040003E402C90032700F9803E600F9003E80407 +:10A05000700000000000000028018488F9003E48DC +:10A060000F9903E600F9023C40AF1003E412D90453 +:10A070003E400F9003E500F9C03E640F9083CA0094 +:10A0800060000000000000002810A100C8003E0091 +:10A090000F80032100C840B2000C80032010C800CC +:10A0A00032000C8003E080F80432002C800B0A049C +:10A0B000200000000000000028052800CA002E80B3 +:10A0C0000BE80A38108EC022800DA00228000A0476 +:10A0D000028028A002FB00BA0037B048EA020A005A +:10A0E000400000000000000028054C0093012CC037 +:10A0F0008BB0420C909B2020C04830422C00830043 +:10A1000020C0083002CD40B30024C80838020A003D +:10A110005000000000000000A001140087002DC0C6 +:10A120000B24061600930821C80931020C8087A071 +:10A1300021C0187202DC00B7B424E30878022800BA +:10A140004000000000000000A8081E0297A03DF09B +:10A150000F48033E00D68030E02C7A021E82C3F006 +:10A1600033EC0C7C03D600F78035E00CD8032A02D0 +:10A1700000000000000000000819A5A0FB003ECA76 +:10A180000F8003EC02EA003EC60FB40BED40FB006B +:10A19000BEC00FB643E000FB023E800F9003C20634 +:10A1A00060000000000000000005FE02CF883FE0D4 +:10A1B0000CB903FE00DD8133E08CFC033F04CF804B +:10A1C00033E24FFC033E00CFC033640CF803C00001 +:10A1D0007000000000000000A811944087002FC10B +:10A1E0000D69A2D040BC0023C008F0029C0087008B +:10A1F00021C00B700A3C048710214C086002EA045D +:10A20000600000000000000000009E0087002DC0DC +:10A21000096202D800970021C40870020C40970020 +:10A2200021C40B30025800A7082180086082C000BA +:10A2300020000000000000002014E42583002CC052 +:10A24000092202CC20B20020C028B0028C0093006A +:10A2500020C00B30426C20830820E208B802C804FA +:10A260003000000000000000A815A400CF003FC08F +:10A270000D9C03E800DB8033C00CF00B3C06DF00D4 +:10A28000B3C00BF0076800EF4032A80CA803EA0443 +:10A2900060000000000000008000EC00FB002EC009 +:10A2A0000F9403C540FA303EC00FB0036C00EB00C2 +:10A2B0003EC00F3013AD40FB023ED00FB403E000B0 +:10A2C00030000000000000000110E400C70031C1B0 +:10A2D0008CD0033400CD003DC00CF0017C00DB01CC +:10A2E0003DC04CF00B3002C30032000FD0030044DD +:10A2F000300000000000000081046E408B002AC086 +:10A30000288442228088803AC00DB002AC088B00BD +:10A310002EC008B00223208B0022308B8C022040FC +:10A320001000000000000000800524008B0022C007 +:10A330000838862A0089802AC008B002CC009B0019 +:10A340002EC008B04226008B0022710B8C02200028 +:10A35000400000000000000008040C00830028C03A +:10A360000832420000810028C00930528C08830066 +:10A370002CC018300600008300A0000B0002020170 +:10A380000000000000000000000D74028B0033C0CC +:10A390000C920B2002C8003BC00CF503FC00DF014F +:10A3A0003FC104F0332140CF0032000F800B000387 +:10A3B0005000000000000000A019FC00FF003FC09A +:10A3C0000FC403F0009C003BC00FF003FC00FF0033 +:10A3D0002FC00FF003F080FF003F000FC003E8061E +:10A3E0007000000000000000C005F0C0FFA0312494 +:10A3F0000EF0631004EF643FC04CF3031C80DF08D1 +:10A4000037C00FF003F0A0FC0031082CD203F0009D +:10A4100070000000000000008010E100BBC1224875 +:10A4200008FD022E0097002FC24871237E40BF0016 +:10A4300021C54BF502EF00BB4036E008A802E0045E +:10A4400030000000000000008805C584B311A2C9D7 +:10A450000A30020001B33028C40832420C00A308BD +:10A46000A0CA0A32828010B0412411083102E201F0 +:10A470007000000000000000C015A500BB0022E134 +:10A4800028B0022C809B002EC008B0026C00B300E4 +:10A4900022C00BB000EC20BB0026C0088002F004F4 +:10A4A00060000000000000004015E340F70432C0E7 +:10A4B0004EB0232E20EB001EC00CB0012C00FB0080 +:10A4C00036C01FB003E140FB0036980C9003D00467 +:10A4D0007000000000000000E001B604FF023FC071 +:10A4E0000FF003FE00EF023DC00FF023FC00FF0061 +:10A4F0003FC04FF003FC00F4003B400FA013F800F6 +:10A5000060000000000000004010AA20EB1036C0E0 +:10A510000DB007EC20DB0032C00CB0026C20EB0069 +:10A520003EC10DB003E020DBA032904CB00B100414 +:10A530002000000000000000C8052D008F8020C111 +:10A54000087012CF008F00A3C00DF0023C008F00F6 +:10A5500037C088F002EC00880020400880023200FA +:10A560004000000000000000E0054C00A3802481B2 +:10A57000093006CC40930028C108B002CF40A300A8 +:10A580002CC0093002CD00904060402810023800F5 +:10A59000500000000000000020010E00878023E032 +:10A5A000487902DE41978029E01978069E0087806D +:10A5B00025E0087802D203838021A0086802080001 +:10A5C000400000000000000048080C00A30034C058 +:10A5D0000D3042CC01D3103AC50C3903CC00E30452 +:10A5E0003CC40D3003CE00D00030400C30031202CA +:10A5F0000000000000000000401DBC00F7003FC04C +:10A600001FF053FC00EF0837D10FF0837C00F740B8 +:10A610003FC10FF103D000FF00BF840FC803D00675 +:10A620006000000000000000A805E000FB003EE024 +:10A630002CBE83EC00EB403EC00FB403ED20FB10BA +:10A64000B6D20FB483EC00DB8036C10C90212A0017 +:10A65000700000000000000048119400B7002FC0F7 +:10A660000836020C0887302DD98B7286DD00B320A6 +:10A6700021C80B7402D0028400A00028200212041A +:10A680006000000000000000C0009A00B7802DE0CC +:10A69000087A029D00A7A02DE00B78029E80A7807B +:10A6A00021E4087A269E18830421E008780A7000C5 +:10A6B00020000000000000004814CC00B3002CE093 +:10A6C0005830120E8283002CC00B3002CC01B30034 +:10A6D00020C10B3002C00888D2202008000252049A +:10A6E0003000000000000000E815B860FA003F826A +:10A6F0000CA003FA00AA001E808FA003E800F2005D +:10A7000032801FA003E800DA003688ACE0037A0448 +:10A7100060000000000000004800E100F8003E205A +:10A720004F8003E100F0003C000B8003E000F802E2 +:10A730003A000F8043F100FC0A3D000FC003920075 +:10A7400030000000000000000810E600C9903E4004 +:10A750000F9203E400D9003240049007E700F9109B +:10A7600030400C9043E409D98022402C100B0204A5 +:10A7700030000000000000008004646089C02E40AA +:10A780000B9826C58089002240289012E710B90056 +:10A790003640289012C583C980B640089002200038 +:10A7A00010000000000000001805040089402E4140 +:10A7B0004B9002E4009900A2400A9002E500B90023 +:10A7C000E241089042E4009D50AB4A08D0260600C2 +:10A7D00040000000000000000804048281202C508A +:10A7E0000B1002E400814020504A1432C400B140F2 +:10A7F0002451181412D40085402D4008500602013F +:10A800000000000000000000B80D6140C8003E00DC +:10A810000F8002E000D80032000A8002E010F80049 +:10A820003200048003E000D8003A000CC0032E037D +:10A830005000000000000000981DF440F9103F4156 +:10A840000F9403F500F9403E500D9403E510F940D4 +:10A850003E504F9403C500E94136500F9403E6067D +:10A8600070000000000000001805F600FDA83A4046 +:10A870000CD8233600E9A03E780F9E03B680CDE2C7 +:10A8800032680C9B0336824DA037688C9803060013 +:10A8900070000000000000003810EBA0B84020203D +:10A8A000088502215188C02E290B8E02E100D8E0D4 +:10A8B00022320D8D23614898D4A2102884020E0400 +:10A8C00030000000000000000805C500B3002A4A5F +:10A8D00028104EA408A16828440B1402C50081402A +:10A8E000A0500810020402912A204428144A0201B0 +:10A8F00070000000000000001815AC80B900224074 +:10A90000489006A400A9002E400B9022E400990074 +:10A9100022400910026402990022400890020604B5 +:10A920006000000000000000A015E400F9003858A5 +:10A930000C90538414A9043E400F9003E400C90016 +:10A9400032400C90032404D900B6404C900B2804EC +:10A9500070000000000000002801A400F9023E4938 +:10A960000F10436400D9003E400F9003C400F10271 +:10A970003E400F9003C402E9043C400F1C03CA0090 +:10A9800060000000000000002810A180C8203E00E8 +:10A990008C800B2000E8023E000F8003A082C800DC +:10A9A0006C000F80032010C80032020C80030A04E0 +:10A9B00020000000000000002805380086002E80DE +:10A9C00068A8803A008A002E800BA002F8008A0056 +:10A9D0002E800BA00A3A008E10238008A0030A00E4 +:10A9E000400000000000000028054D0083002CC03E +:10A9F0000838000C6023002CC00B3002CC408300D0 +:10AA00002CC00B30020C028A80A0E028300A4A00D9 +:10AA10005000000000000000A001162087022DC198 +:10AA20004870127C00A7202DC90B7200DC0087083B +:10AA30002DC41B32021D01874221C208700228006A +:10AA40004000000000000000A8083E02C7803DEC66 +:10AA50000C58031E00E7803DEC0F7F039600C78073 +:10AA60002DE20779030A06C38030208C38036A027E +:10AA70000000000000000000081DAC00FB003EC00C +:10AA80000F10438C00DB383ED80FB003CC04FB44DE +:10AA90003EC08FB613EC02FF023E000FB003C206A9 +:10AAA00060000000000000000005FA00FF8031E3B4 +:10AAB0000EF823FE02DF80B7E20EF8037E006DD0B1 +:10AAC00033E00CF89B76C0DF84B3E004F803C000E9 +:10AAD0007000000000000000A8119040B70221C4DF +:10AAE000087B42DC00870021C40B300010808D0001 +:10AAF00023C00DF20204428F0029C8287002EA0424 +:10AB0000600000000000000000009400B60023C0B8 +:10AB10000A72028C00870021C00A30020401A702D9 +:10AB200021C0087042008A870021C0287002C0003E +:10AB300020000000000000002014C500B000A0D0DC +:10AB400008B002C9428B0020C00B302204008300F1 +:10AB5000A0C0493002454093C0A8D4003502C804C3 +:10AB60003000000000000000A815AC00BB0031C0A0 +:10AB70000EB023CD00DF0037C00EF0016800E30007 +:10AB800033C01CF0034500DAC892D42CB403EA04A5 +:10AB900060000000000000008000E520FB003EC0D7 +:10ABA0000FB003EC00FB003EC04FB003AD00FB0054 +:10ABB0007EC01F3003A480E9203CC00F3203E000B8 +:10ABC00030000000000000000110DC00C70033C2AC +:10ABD0002CF0033E20DB0013C00C70033C80EF041C +:10ABE00073C10FF0223000C600B2C00CF003004465 +:10ABF0003000000000000000810069008B44A2C109 +:10AC000088B0036C008B0022C028B00A2D00BB0066 +:10AC100062C00BB00226028B8022C008B003204025 +:10AC20001000000000000000800528018A0822C0F2 +:10AC300008B2026C409B0028C048B0162904B90134 +:10AC400022C049B006AE098B8022E048B002200045 +:10AC5000400000000000000008040002820022C042 +:10AC600088B0024400830028C00830020800B10008 +:10AC700020C00B30028C00838020E008300A0201E3 +:10AC80000000000000000000000D6400CA0033C096 +:10AC90000CB2032C00DF003BC04CF5132C04EF007A +:10ACA000A3C00DF003A840CB00B2002CB0030003FA +:10ACB0005000000000000000A01DF000F4003FC0A4 +:10ACC0000FB103F000FF0037C00FF003FC00FF00DE +:10ACD0003FC007F00B7C08FF013F000FF003A80600 +:10ACE0007000000000000000C005F0C5ED333BCC53 +:10ACF0000CF0033040FF253FCC0CF3833CD0DF4801 +:10AD000037304CF303FD80CF2833D80CF1033000EB +:10AD100070000000000000008010ECD0BB3120CC9F +:10AD200088F3422050BF902FC40AF6027DC08F40A6 +:10AD300026408FF602FD00FF0839C808F602A0047D +:10AD400030000000000000008805C480A12028C950 +:10AD500008309A0009B3002CC02030024C908320A8 +:10AD600002080B3312CD80932024D808342222010C +:10AD70007000000000000000C011AE00BB1022C037 +:10AD800008B00226013B016EC008B0024C088B00DF +:10AD9000A2890BB002EC00AB006AC128B002B0047B +:10ADA000600000000000000040156E00E8C13AC0DD +:10ADB0002CB0432600FB063EC10CB00B2C02CB008E +:10ADC00034229FB043EC009B0236C18CB0031004C8 +:10ADD0007000000000000000E001BC00FC803DD0DD +:10ADE0002FF003FC00FB003DC0073003BC00EF0464 +:10ADF0003FE05EB001FC00FF001BC00FF003F80055 +:10AE000060000000000000004010AC00CB013EC913 +:10AE10000CB0172084EB00B2C10DB0036C00C3006E +:10AE200032500FB0030C40C3007EC00C300310043E +:10AE30002000000000000000C8052C008A582EE009 +:10AE400048F0022D00EF0123C008F0223C048F607F +:10AE500036540BF00A3D408F002FC008F0037200FB +:10AE60004000000000000000E005400089802C1038 +:10AE700008B0024900A3A024C00930024C0083C9D5 +:10AE800020904230124D0083006AC0093002380021 +:10AE900050000000000000002001160085806D6257 +:10AEA000087E025640278025E01978060E00838030 +:10AEB00061A00B78024E0087826DE009790248009C +:10AEC000400000000000000048082C02C3613C88DC +:10AED0002CBA124910E32C36C00D30534C44C30039 +:10AEE00020010F31034C00C3013CC02DB1031202FD +:10AEF0000000000000000000401DBC00FF003F00FB +:10AF00004FF109B000FF003BC00EF401FD24FF40EB +:10AF1000BFC007F003BC006F103FC41EF183D00612 +:10AF20006000000000000000A805C400E804320032 +:10AF30000CB603E802CB0036CA0FB503AD00FB2008 +:10AF40003E400FB303EC80FBA832C68CB6032A0048 +:10AF5000700000000000000048119402E60020008C +:10AF6000087302DC0087702DD00BF0021C84B72020 +:10AF70002DC00B7082DD24B74034C9287282920440 +:10AF80006000000000000000C000BE02AC80A120F4 +:10AF9000087900CE04878065E00B7A029E00B790A6 +:10AFA0006DA00B7802DE00B78021E0087802300047 +:10AFB00020000000000000004814ED82ABE020E417 +:10AFC000083002EE0483002CC11B30020C08B300D1 +:10AFD00064F60BB002CC04B30026C0083002920421 +:10AFE0003000000000000000E815BB80EE4931A0F1 +:10AFF0002CA003FA00CA0236800FA003A800FA02B0 +:10B000003F900FA063E800FA0032800CA0233A04BE +:10B0100060000000000000004800E00AE8003E0870 +:10B020000F8003E350F0003E000F8013E000F800B3 +:10B030003E000F8003E001F8017E000F8003D20084 +:10B0400030000000000000000810E440C9A13240B8 +:10B05000201101A640C98436400D900344004100F0 +:10B0600032400F900B2400F9003E404C10030204C4 +:10B070003000000000000000800464008982A240CB +:10B08000089C02250089C82240089042240089209B +:10B0900022600B90022410B9002E4008900360003B +:10B0A000100000000000000018052400890422CAD6 +:10B0B0000A900A2502892020402810026401A90074 +:10B0C000224B0B90022401B9002E41289002060069 +:10B0D00040000000000000000804049081A0204807 +:10B0E0000A320204808100204408110204D0A12009 +:10B0F00020400B11020600B1312C48081402420115 +:10B100000000000000000000B80D6142C854321475 +:10B110000E85032144C828B21A4C86936114E85066 +:10B1200022140F86832140F0401E140C00032E03CE +:10B130005000000000000000981D7444F5103F44CA +:10B140000D91037440F9003E480B9203E4C2D910FC +:10B15000BF400F9203E504F9303E440F9443E606E6 +:10B1600070000000000000001805F622CDA1336138 +:10B170000CD8D33410CDA83E608E9C93A708CD8008 +:10B1800033400E9AD336A0C98032600C9903060072 +:10B1900070000000000000003810E3888AA020281A +:10B1A000088022201288402C28088A022200880069 +:10B1B00022000B8C03210088D0A23E288D020E04B1 +:10B1C00030000000000000000805CE20A1482052F9 +:10B1D000291002240381002C520A1012851091407C +:10B1E000A4400A128244009128244028120202013D +:10B1F00070000000000000001815A400A9142240EF +:10B20000099002A40189042C4008900224009900AE +:10B2100022444B10422414990026400810020604D0 +:10B220006000000000000000A015E440E940B27892 +:10B230000D900B2422C9033E410E9003A402D900B5 +:10B24000165806900B6402D90036400C900B280467 +:10B25000700000000000000028018400D9803E4AF0 +:10B260000E90036420F9083E410F9003E400E108CA +:10B270003E400F9003C400E10038400F9003CA0025 +:10B2800060000000000000002810A009F040B0108D +:10B290004C000B2000F8003A001C0003E000C8003E +:10B2A00036000C80032000C80032000F80030A041F +:10B2B0002000000000000000280528003E8823A28E +:10B2C00048E0001980BE882E800DA042E8008E0064 +:10B2D000239008A00A3A00DA0036800BA00A0A0080 +:10B2E000400000000000000028054C00B38020E072 +:10B2F0002830C20F10B34028C00B3002EC1183403D +:10B3000028D20A30020CC0830020C00B30020A0091 +:10B310005000000000000000A0011C00B60021C089 +:10B320000820C21C10B5002DC80A7202DC40850836 +:10B3300029A21A72220C00933005C40B3222280075 +:10B340004000000000000000A8081600B280312074 +:10B350000C58031E00F78039F80B7C22CE40CF80BA +:10B360009B602E3B031A00C7A811E00F78032A0246 +:10B370000000000000000000081DA400FA003EC00C +:10B380000F9023E800FB003ED02DB603ED02F9003C +:10B3900032400DB007EC00FB603EC80FB503C2069B +:10B3A00060000000000000000005FE00FF8033A0E8 +:10B3B0000CF80B3240CE8137F00CBC03FE00FF844A +:10B3C00033E02CF883E602CF8533F00CFC03001445 +:10B3D0007000000000000000A8119C00BE0035C6EF +:10B3E0002830023040870023C0087A02DC00BE000B +:10B3F00023C0087012FE00870021C008F0022A0452 +:10B40000600000000000000000009520B6002080D1 +:10B410000831025C01870025C0087202DC00B6001A +:10B4200021D0097002D408930020C00870020000E7 +:10B4300020000000000000002014C400B0E02460E0 +:10B440000820064801800020C0083002CC04B30068 +:10B4500020840B3002E8009B0020C0083002080462 +:10B460003000000000000000A815AC00B9E03280F8 +:10B470006CB0236F00C30037C13CF003FC00FA003E +:10B48000B0C009F003EC10DF0073C00CF00B2A0011 +:10B4900060000000000000008000EC10F8003E4258 +:10B4A0000F2403A860F8003CC10FB003EC00F94082 +:10B4B0003E8004B023E100EB003EC00FB003E0008B +:10B4C00030000000000000000110F400EE003D30EC +:10B4D0000CC0031400CCA0B3C04C70035C10DF00A0 +:10B4E0003F000CF003F800CF0023C00CF003004035 +:10B4F000300000000000000081046400BA812E5872 +:10B500000888022780892022C028B0022C00888366 +:10B510002E2005B062E3008B002AC008B003604013 +:10B52000100000000000000080052600B9812E40B8 +:10B53000088C062600880022C008B0166C00988887 +:10B540002E2008B004E3010B0028C00830022000C0 +:10B55000400000000000000008040400B0002CC0FF +:10B5600028000E0010800020C00832020C00800469 +:10B570002E20093002C412830028C0083002420184 +:10B580000000000000000000000D6C00FA003E000A +:10B590002C910320008A0033C00CF0037C00D800FB +:10B5A0002E400CF003E080CF003BC00CF003000302 +:10B5B0005000000000000000A01DFC00FC013F4006 +:10B5C0000FC013F000F4003FC10FF423FC08FC008F +:10B5D0003F000FF003F040FF003FC00FF003E8060C +:10B5E0007000000000000000C005FC20CD1039C82C +:10B5F0000DC1033C80EF9023D80FF800FE00CF80F0 +:10B600001FD00FF903FF00E7C033C40FF003B000F1 +:10B610007000000000000000C010FE02894023F00E +:10B620000885103C008B00A3DC4BB282EC208B0021 +:10B6300026C04BB002EC10B9042AC90BB580F00447 +:10B640003000000000000000C805CC00816428C460 +:10B6500009B20A0CF0A32020C80B3202EC028308C6 +:10B660002CC8093202CC80ABA020C80B3200B2013A +:10B670007000000000000000C015AC10890022C05E +:10B6800008B2122C020B0022C00BB802EC008B0097 +:10B6900026C04BB046EC00B9000AC00BB002F00463 +:10B6A0006000000000000000D015EC10C9E03AC0B6 +:10B6B0000D28032C00EB1032C00F8203C400CB0016 +:10B6C0003EC10FB006EC08E900B2C00FB013900401 +:10B6D0007000000000000000E0019C00F5A03FC0E9 +:10B6E0000FE803FC08FF003FC08FC003FC00FF0011 +:10B6F00037C00FF003FC00FF043EC00FF003F8005A +:10B7000060000000000000005010AC00F94034C0A0 +:10B710000DB4032C00DB403EC02C80036408FB10FA +:10B720003EC68FB003EC00F98032C00CB00B14049D +:10B730002000000000000000C8053E20E9C837D402 +:10B7400048AA221C008B006FE0088582ED40BB8474 +:10B750002FC04BB803AD40B30023D408F70232002A +:10B760004000000000000000E0014C00B164A4C0F3 +:10B7700009200A0C04B8006CC0083802C840B38025 +:10B780002CD10B3002CC04B30028C00830023A00A0 +:10B790005000000000000000B0011E00A58025E060 +:10B7A000883A121E00A6902DE2087902DA00B782CC +:10B7B0002DE00378829E00BCC129E00878022C109D +:10B7C000400000000000000049080C00F30034C0F5 +:10B7D0000D3E030C00F0402EC00C3043C800F300B7 +:10B7E0003CC0073003CC80F20038C00C300312029A +:10B7F00000000000000000004019BD20F7003FC21B +:10B800000FF10BDC20DE043FD207F013F840FF00FD +:10B810003FC007F003FC00FD0037C00F7003D006E7 +:10B820006000000000000000AA05CF00DC003ECA56 +:10B830000FA000AC92C90032C00FB011A408FB00E9 +:10B840002EC04FB023EC00F9003EC40FB003EA0055 +:10B850007000000000000000C8919C00840001C03E +:10B860004B70221CC0870021C04B70021C00B70126 +:10B8700025D80B7022DC00B6002DC00B7222F2041A +:10B88000600000000000000080009E809780A9E01A +:10B890000BF802CE08858029E80BFC021700B78060 +:10B8A0002DE08B7802DE00B4C02DE80B7902E000B9 +:10B8B00020000000000000004814CC008308A0C055 +:10B8C0008B3C024C008300A0C01B3C0A0F29B30034 +:10B8D00024C00B3002CC00B3802CC00B3002D20449 +:10B8E0003000000000000000E815A800DE003A80EB +:10B8F0000FEA02E800CE003A800FE0033800FA00B9 +:10B900003E800FA003E800FE003E800BA003FA0477 +:10B9100060000000000000004800E000F804BA01E8 +:10B920000F820B8004F8803E000F86036000F80051 +:10B9300036000F8023E100F8003E000F8003D200A4 +:10B9400030000000000000000810E401F90032405F +:10B950000F9003E400490032400B9003240049009B +:10B960003C400D9003E408C9003E600C90030204C3 +:10B97000300000000000000080046400B940A264B0 +:10B980000B18022500D15036504E900A24028940EF +:10B990003A51089402E52289442E6028900A20003A +:10B9A000100000000000000018012400B10822402F +:10B9B0004B9282A500A90822500A10020C00A9404F +:10B9C0006E500B9402C40489446C488810024600EF +:10B9D000400000000000000000040400B140E0400E +:10B9E0001B140A0400B90024401A10220400A1000C +:10B9F00028400A1012C40081026C40081202420161 +:10BA00000000000000000000B80D6008B000320027 +:10BA10004F8002A150E05032140EA5232140E8507F +:10BA20003E140F8503E140C8501E140C85436E037D +:10BA30005000000000000000D819E500FD403E5015 +:10BA40000F7403A5005D003E500A5013F400D900A6 +:10BA50003A500D9013E400FF003E500F9103A606EC +:10BA600070000000000000001805F690BDE8236B90 +:10BA70000BDA0B3680C9003268469043E400490077 +:10BA800032680C90032440F90032600C9C03C6011C +:10BA900060000000000000007810E100B8E0A21192 +:10BAA0000B8E0A232288802A31288802620088802F +:10BAB000A23028888A2200B8A8A23908CA02CE0477 +:10BAC00030000000000000004805C50821000040CB +:10BAD0000314828580AD0821529850823423850852 +:10BAE00021520850065400B520215A095402D201AF +:10BAF00030000000000000001811A400B9612240CD +:10BB00000B90060400AD00694008D0027400850067 +:10BB100001400070067404B500234009D002C60439 +:10BB20006000000000000000A014A400E900324002 +:10BB30004F950BA400E90032408C90032400C9000B +:10BB400032400C90036408F90032403D9003E80451 +:10BB500070000000000000006801A408F9003E40E9 +:10BB60004F908BE404D9013E400D90036400D9014D +:10BB70003E400F9003A400F9003C400E9003DA0011 +:10BB800060000000000000002810A000F8403620EF +:10BB90001784032021C8007E022C80432000E80285 +:10BBA0003E010F8003E000C8401E000F8003CA045E +:10BBB000200000000000000028052A88B60223A00B +:10BBC0000BEC422B00D2806EB108A0220800EA04E0 +:10BBD0003A809FA003A8008A042E800BA802CA0006 +:10BBE000400000000000000028054C00B200A4E165 +:10BBF0008BB432474583902CF44B38120E44A3018A +:10BC00002CC04B3002CE0093006CC00B3802CA002F +:10BC10005000000000000000A0011C00B74421C239 +:10BC20000B5402540587002C409B6C021810A7048B +:10BC300029C00A70029B0097040D800B6082E80007 +:10BC40004000000000000000A8081E00F38035E05E +:10BC50000B3802521084802DA00FF80B1E00E680D6 +:10BC60001DA00B6803FE02D6803DE00F7803EA02B8 +:10BC700000000000000000000A1DAC00FB003EC1F7 +:10BC80008B900B800AB8012E000CB003E800FA007C +:10BC90003EC00FA043EC00EB003E800FA623C20283 +:10BCA00060000000000000000005FE00FE80332060 +:10BCB0004EC912F650EF903FE00C1900B642CF216A +:10BCC0003FE00EF902E6C0FF803FE04CDC0340009D +:10BCD0007000000000000000AA119400B70081402D +:10BCE00008030214C487012DC8086A12384087026D +:10BCF0002DC0087112D280B7002D800860022A047E +:10BD0000600000000000000000009C00B7102180CF +:10BD100008F4129404A6002CC018D202144886100D +:10BD20002D800A6132D400B6182DC40858020010C4 +:10BD300020000000000000002014C400B30020C058 +:10BD400040B022040082810CC008300A0A008A0038 +:10BD50002EC008A002C400BB002E800820020804E8 +:10BD60003000000000000000A815AC00FB00A0C0DF +:10BD7000249423AC10EBA00EC00CB0022E20C900FE +:10BD80002E400E9003EC00F9803E406CA00B2A047C +:10BD900060000000000000008000CC00FB003EC0FE +:10BDA0008990032C00FB023E404FA0036D01FB4134 +:10BDB0003EC08FB403E800FB203E500FA403E00018 +:10BDC00030000000000000000110FC00C320B2C0E1 +:10BDD0000DD0033800CD003F800DF003FC00FD02C4 +:10BDE00036000CD0033F08FC0412C00CA003C04472 +:10BDF000300000000000000080046C028BC822C0EC +:10BE000008980A2A4089202E018EB012EC80BBF0DF +:10BE100022E508BD022E00BB9022ED08A202E00040 +:10BE2000100000000000000080052C008B012200A3 +:10BE300049A81E04008B012EC0499002E400B900FD +:10BE400022400A90022C00B9002A40088002E0003B +:10BE500040000000000000000804040081002040B1 +:10BE6000082002040083002CC00A2042CC00B3004A +:10BE700020C00230020884B3040840082002C21126 +:10BE80000000000000000000000D6C008B00B2807C +:10BE90000DB1032402CB013EC04D9043E400F900F4 +:10BEA000B2002E900B2C80F800BAC02C8003C00387 +:10BEB0005000000000000000A01DF4007D003FC005 +:10BEC0000F7203D400FF003FC00EF147FC00FF00DB +:10BED0003BC00DF013FC50FF0037C00FE003E80635 +:10BEE0007000000000000000C005F0C4CC333F0427 +:10BEF0002CF6033860CC90B3200FF123F060FF01E3 +:10BF000023C80CF28A3C81DF303F640CD803300434 +:10BF100070000000000000008010E0C28A302E187F +:10BF200008F530A594582222214BF302E1009F70BE +:10BF30002BE40AF4121D40AF722C492F3082A00668 +:10BF400030000000000000008805C48080A02C980C +:10BF5000083222080082002800033202C084B30C99 +:10BF600020C05832928C30A3202EC0481242620169 +:10BF70007000000000000000C015A8008B002E20FB +:10BF800008B00A200198002A220BB002E6009B00AC +:10BF900022C00AB012AC04AB002EC003B002F00005 +:10BFA00060000000000000000015E500C8003EB081 +:10BFB0000CB0032900C8003A204FB003E220FB0177 +:10BFC000B0C00CB0032C00FB023C410C9043480471 +:10BFD0007000000000000000E001A280FE403E0072 +:10BFE0000FF063EC00BFC417420FF003EC00FF003A +:10BFF0001FC10FB0035C00FB003F404FF000B800D2 +:10C0000060000000000000004010A502C8003E9043 +:10C010002CB00B0106CB013E505FB0132110CB00BA +:10C020007EC00CB00B2C00CB0032C00C900310046F +:10C030002000000000000000C80528018BD02C342F +:10C0400048FF023000AA042E690FF0036810DF00D9 +:10C050002FD40DF0023E005F04B6C008B00372009A +:10C060004000000000000000E005699081802C0085 +:10C0700048B802080999004CB00B30020C008B0044 +:10C080002CC009B0400C40830000400A90023000F0 +:10C0900050000000000000002001160084882DE4FC +:10C0A0004839021600B4802DE00A7B065E009780B6 +:10C0B0002DE20978021E90978025648A7802480054 +:10C0C000400000000000000048080D0081102C9680 +:10C0D0000831230C0090203CC41BB8020840C30068 +:10C0E0002CC40D30030E40C31030C04E10071A127E +:10C0F0000000000000000000401DBC007D053FC5A1 +:10C100000FB10BF400EF001F450FF043FC01FF409F +:10C110003DC41FF006FC10FF003BC12DF103D0060B +:10C120006000000000000000A805EC04CB043EA065 +:10C1300044B6032804CB8032800FB3936008FB2001 +:10C140003ED21FB3032D80FB617E408C98032A00F2 +:10C1500070000000000000004811840C86052DC00E +:10C1600008F4828C908500A1C00BF0025C003700BF +:10C170002DD00B71021CC8B7482D400A7002120462 +:10C180006000000000000000C0009E0087802DA11C +:10C1900060784A16D0A78029E00B78529601B790B4 +:10C1A0002DE80B7A225E40B7A02FE14850223000E4 +:10C1B00020000000000000004814CC1083842CC034 +:10C1C000083002A41083CB28E00B302A4F409300A4 +:10C1D0002CC00B30024C10B3022CC0AA3002120447 +:10C1E0003000000000000000E815B800CEA03F803D +:10C1F0004CA02B3A00CE403BB80FA003B900BA00C8 +:10C200003E800FA0036800FA007E801CA00B3A0459 +:10C2100060000000000000004800E002F8003E045A +:10C220008F0003E04AF81026180F8003A080F80260 +:10C230003E008F000BA000F8023E000F8013D200DA +:10C2400030000000000000000810E420C900324067 +:10C250004D99032400C9023E680F90022400E900B2 +:10C2600030408C90030440C9003E400C900302040F +:10C270003000000000000000800464208906225085 +:10C280008B9CC22400D9012E400B90422408B90196 +:10C2900022460D900A260289002C400A1002200036 +:10C2A00010000000000000001801060091404270DC +:10C2B0000B90122C028B002E400B1022E410B100C8 +:10C2C000A240489012240899022E400890020600CD +:10C2D0004000000000000000080404929120E048A3 +:10C2E0000B1202040291102CC00B100684C0B11076 +:10C2F0002048891102058091402E442A94020201AF +:10C300000000000000000000B80D6140D85030145B +:10C310000F850B21E080403E000F878BE10CF86C0D +:10C3200032008406832004D8283E100C00032E031C +:10C330005000000000000000981DF440AD103F4583 +:10C340000F9103FC187D201F410F900374C0F92149 +:10C350003E440F9201E440E9003D484FD003E60619 +:10C3600070000000000000001805F780FDE0337049 +:10C370000CDA032620C94031400E9A032400F980CC +:10C380003B600F9C8336A0F9A1B0400F9103C6001B +:10C3900070000000000000003810E290B8A02228D1 +:10C3A00028880A220288A02200088802C280B88851 +:10C3B00022040B8E032280B8D02A200B8802CE04E0 +:10C3C00030000000000000000805C580B161005881 +:10C3D00048168A04A0890122401A14880420B1401A +:10C3E00028400B100A0420B12C204A0B1202C20173 +:10C3F00070000000000000001815A590BB40204010 +:10C40000089002244089426258081002E500B903EE +:10C4100022C00B9002A41431002A440B9002C604DF +:10C420006000000000000000A010A500F9013240EB +:10C430008C90032700C19430400E90032400F90033 +:10C440003A400F90032400F9003260079027E80576 +:10C4500020000000000000002800A418F900BE44DD +:10C460000F9003C400F900BE618F9003A400F10097 +:10C470001E400F10032408F9007E400F9003CA00ED +:10C4800020000000000000002810A181F800320404 +:10C490000C00D32100D8043A149C80032101C80069 +:10C4A00036000C80132010C80032002C8003CA0410 +:10C4B000200000000000000028043A00BE8423850C +:10C4C00008EC8368048A002F904DA0022801DA004E +:10C4D00023B00AA0022A08DA0122800FA002CA00B3 +:10C4E000000000000000000028054C00BBF020C048 +:10C4F000083C0A0C00930128C88930064C008302CE +:10C500002CF60830020400A30020C00A3002CA0042 +:10C51000500000000000000020011D11B300A0C069 +:10C520000850025C1087016D814932521EC387009A +:10C5300028E00A32261F00370023E00B7202C800F1 +:10C54000400000000000000028081200B7823120DF +:10C550000808370F08D7E03960197A0B5E0C83B2F0 +:10C560007DE00C7A0B3E02AFA0B1E00E7A03CA0266 +:10C570000000000000000000081DA010FB003EC0ED +:10C580006FB043EC11FB003E400FB503EC20FB50B5 +:10C5900036000FB543E5A1DB783EC00FB403C206F9 +:10C5A00060000000000000004005FE00FFA03FA06A +:10C5B0000DC9133E00CFD03DE802FF133E00CF82ED +:10C5C0003F600CFC233E10EF8033F20CFC83100024 +:10C5D0007000000000000000A8119C40B5012DD0A3 +:10C5E0000858021C4057102D5A283102BC019710E0 +:10C5F0002D000A70028404CF0029C00AF0022A0428 +:10C60000600000000000000000009000B72A2D82AA +:10C610000842223C0087110DCC8832021D00970091 +:10C620002CC40830021400A70023C0097082000047 +:10C6300020000000000000006014C020B0202C503A +:10C640000810022DC093E22C210830020E0893003E +:10C650002C400A30028C0093002AC00B30021804D0 +:10C660003000000000000000A815AC00F8C03E80BB +:10C670002CA00B3F00C7603ED00CF00B3C00CF005D +:10C680003E800CF00B2C00EF0033C10DF00B2A04A0 +:10C6900060000000000000008000EC40F3403E50CD +:10C6A0008EB403EC10FB003E090FB013EC42EB001C +:10C6B0003C008FB013C411E3003EC00EB003E00095 +:10C6C00030000000000000000110FC00FC8031225E +:10C6D0000CA8033C00CF0033A00EF003DC00CF0019 +:10C6E0001FF00CF003F400CF0233C00CF002005432 +:10C6F000300000000000000081046F00BBC0227009 +:10C700000AB9422C108B00761183B002EC10AB00FA +:10C710002EB00AB003EC048B00A2C028B002204067 +:10C72000100000000000000080056540B820224491 +:10C7300058340A2C008B0022844BB002EC008B0092 +:10C740006EC008B042E6048B0002C0083002A001AF +:10C7500040000000000000000C000000B10020C0FC +:10C760000A300A0C008B0324800B3002CC00A3009B +:10C770006C000A30028D00830020C0183002820055 +:10C78000000000000000000000086400F800300015 +:10C790004CA00B2C02CF0022400EF503FC00CF0171 +:10C7A0003E000CF012DD02CF0233C04CF00B8003D0 +:10C7B0001000000000000000A419F000FC003F4041 +:10C7C0000FB103DC00BF013F000FF223FC10FF009C +:10C7D0003F000FF001F484FF003DC04FF0136806E6 +:10C7E0007000000000000000C005FE40DF8033C87C +:10C7F0000CF8033C0A9FC03FF008B8023E00FF80DF +:10C800003FD80CF9612E406F903FE48FF1833000E8 +:10C8100070000000000000008010EC048B8023F00A +:10C8200008B8023D40AB000E084822826C20BB00D5 +:10C830002FD048B0022C00BB002EC10BB002300438 +:10C8400030000000000000008805CC028301A0C574 +:10C8500008B04A4CA0802428C80932024C00B30812 +:10C860002ED129B23A0C84A3212CC84BB20A320132 +:10C870007000000000000000C015AC088B0022C052 +:10C8800008B0024C008821242109B0466C00BB0688 +:10C890002EC009B0022C10BB002EC00BB002300419 +:10C8A00060000000000000004015EC00CB0032C02A +:10C8B0000CB9026C00CBC83AC02D900B2C08FB00C1 +:10C8C0003EC00D30422C00EB003EC00FB013000400 +:10C8D0007000000000000000E001BC00EF003DC05F +:10C8E0000FF003BC06EF823F404EC983BC00FF003F +:10C8F0007FC01CF0137C00FF043FC00FF003F80062 +:10C9000060000000000000004010AC00FB023EC0D0 +:10C910000EB003AC20D8403EC08C900B2C00FB0026 +:10C920003EC90DB033EC08FB023EC00FB00B5404FF +:10C930002000000000000000C8052C00B3002FC03C +:10C940000B3012FC0088A02E402894022C10BB044F +:10C950002DC028B002EC00BB002EC00B72063200C6 +:10C960004000000000000000E0056C00B3002CE077 +:10C970000A1002CD0093002CC008B0024C00B30096 +:10C9800028C0083002CC00B3002CC00B30023A00A3 +:10C99000500000000000000020011E40B7802DE282 +:10C9A0000B5802DE0297812FA00868025E00B78153 +:10C9B0002FE0087902DE00B7812DE00B78023C0001 +:10C9C000400000000000000048080C00F3003CC0DC +:10C9D0000E3203CC80D3003CC40C39034C08F31A4C +:10C9E0003CC60D3003CE20F3083CC00F300352028A +:10C9F0000000000000000000401DAC00FB002EC045 +:10CA00000BB003CC20EB003C800FB041AC00FB002E +:10CA10003CC20FB003EC40FB003EC00F3003D00619 +:10CA20006000000000000000A805EE02C38030CEC8 +:10CA30000D9803ACA0C380B2C00FB003EC00FB00A4 +:10CA40003ED24FB0092E084B013EC024B003EA008D +:10CA5000700000000000000048119C00870121C008 +:10CA60004850124C00870035C04B6002DC04B7010F +:10CA70002DC00B70021C0087002DC10C7202F20445 +:10CA80006000000000000000C0009E00878023E0DE +:10CA900008F802DE808F8121E04B7812DE043780B7 +:10CAA0002DE80BF8023E1887802FE0097902E0009C +:10CAB00020000000000000004814CC008300A0C04B +:10CAC0002830424C00830024C00B3806CC04B3004D +:10CAD0002CC00B30020C0283002CC0083002D204A0 +:10CAE0003000000000000000E815A800CA003180F6 +:10CAF00008E0029802CE0033840BEA03E800BA0093 +:10CB00003F810FA0032800CA003E800DE003FA0415 +:10CB100060000000000000004800E000F8003E0057 +:10CB20000E8423A000F8003A100F8003E000F80004 +:10CB30003E100F8013E000F8003E000D8003D2008D +:10CB400030000000000000000810E401F9003E4041 +:10CB50000C9A13E400C9003E400C9823E480F900CD +:10CB60003E402C98036400F9003E400C9003C20440 +:10CB7000300000000000000080046404B9002E4072 +:10CB8000689C22E40289017C508D9822E480B920BF +:10CB90002E5048100B2500B9442C40289000E0008E +:10CBA000100000000000000018052400B9002E50FD +:10CBB000089002E40489002E500A9202E400B900B1 +:10CBC0002C400891022400B9002E40089002C600B3 +:10CBD000400000000000000008040500B1012C40E6 +:10CBE000483002E40081002A404B1002C400B1002A +:10CBF0000CC00890020C00B3002E40481202C20183 +:10CC00000000000000000000B80D6000B8013E0008 +:10CC10001C8007E150C8502E141E8503E141F850D6 +:10CC20003E140C85132148F8503E140C8543EE0346 +:10CC300050000000000000009819C400F9003E51A7 +:10CC40000F5003E500FD003F401DD003F410F90034 +:10CC50003E500F50009400F9003D400F9103E6064E +:10CC600070000000000000001801E450CD003160A9 +:10CC700004D0033680C1422E501F9403E500E90220 +:10CC80002E720A90220508E9403E50409C0326007F +:10CC900070000000000000003810C28288002215D9 +:10CCA000088002235888A02E280BAA42E28288809E +:10CCB0002E382888022280B8A03A2808CD020E0417 +:10CCC00030000000000000000805C4008100A640FC +:10CCD00028100A242695000D400B50027400850888 +:10CCE0002F4079D2AA1400A5012F4038500212011A +:10CCF00070000000000000001815A4048900264000 +:10CD000008910224109D082F400BD002F4008D02E0 +:10CD10002F4009D0003400BD000B401870020604FB +:10CD20006000000000000000A015C400C9053641E5 +:10CD30004C90632400D9003E400B90034408C90086 +:10CD40003E401510032400E9003C400C90032804E9 +:10CD500070000000000000002801A404F9003A401F +:10CD60004F9803E400E9993E404F9003E420F90A0C +:10CD70003E400E90436424F9083A420F908BDA004B +:10CD800060000000000000002810A000C800120091 +:10CD90000C8043E000C84032000F8453E010F800DC +:10CDA0003E000D80232000D8003E000F80030A04BF +:10CDB0002000000000000000280538028200A18841 +:10CDC000086022C8008A4036A10BA002E910BA44CC +:10CDD0002C800CA41229028A442E980BA4020A006B +:10CDE000400000000000000028054C10830020E0F7 +:10CDF000183092C408934020E00B3002CD00B340BD +:10CE00002CC00B3A42CD0083402CD00B38024A0094 +:10CE10005000000000000000A0411C00870021C05D +:10CE2000287002D1009D8025C24B6002DC08B70249 +:10CE30002CC00A7402FE0087002DC00B340268006B +:10CE40004000000000000000A8081E00C78431E078 +:10CE50000C6803D600978031A00F5813DE08F782C4 +:10CE60003DA00FF80BDE00C7803DE00F788B6A0213 +:10CE70000000000000000000081DAD80F3003EC16E +:10CE80000FA023C002E9003E810F8003EC00FB00ED +:10CE90003EC00DB0132C00EB003EC00FB003820269 +:10CEA00060000000000000000005FF32C780336012 +:10CEB0000F78033EC84E8023640CF8033A00CE80FE +:10CEC00013EC06D8033A00DE8033A40CC803D0006C +:10CED0007000000000000000A8119C00871001C035 +:10CEE0000B7002185084002B4408601298008613BF +:10CEF00021C4885002188086002180086102EA045B +:10CF0000600000000000000000009C00870021403D +:10CF10000BF1025C800600210088D0025C008700D3 +:10CF200020898AF1021C0887102181884802C600E6 +:10CF300020000000000000002014CC108304A0C1D9 +:10CF40000B300A480C88066038080442EC018B0458 +:10CF500022C108300A2C008B002280002002D80455 +:10CF60003000000000000000A815BC00C3002280B3 +:10CF70008F9003640ACB02B2F2203512640AC90012 +:10CF8000B2400EA003240AC900A2402CA003EE0464 +:10CF900060000000000000008000EC00FB003C800E +:10CFA0000F9003A500DB403ED04DB413A408FB0155 +:10CFB0003EC01CA0036C00FB043E504FA403E000E5 +:10CFC00030000000000000000110FC00FF0033C032 +:10CFD0000CE8432600DF80B3E00FF8037C00CD00AF +:10CFE00033040CE0233440CD0023400CE003E00484 +:10CFF000300000000000000081046C10BB00A2D2D1 +:10D0000008280204608B1922C60EB18A2E408B902C +:10D0100022C108A4822C008B90226448A402E00064 +:10D02000100000000000000080052C00BB00220062 +:10D0300008912E24009B0022C08BB012200488008F +:10D040002240081022200088012AD0088042E000F7 +:10D05000400000000000000008040C00B304208021 +:10D060000810060410830020C08BB012000082005C +:10D0700020C02810420906820028C0082002C201F0 +:10D080000000000000000000000D7C00BB003240EA +:10D090002CB0032400D30032C05FB5030C02C100E2 +:10D0A000B2000CB00B0500C100B8C02C8013E00327 +:10D0B0005000000000000000A01DDC00FF001FC0A9 +:10D0C00087F001F400FF003FC00E7043FC107F00AA +:10D0D0003FC00F7003FC00FF0037C00FE003E806FD +:10D0E0007000000000000000C005F184FE6131D82E +:10D0F0000CB2C3FCE0CC807BC00EF1037CE0CC839F +:10D100003F200FF0CB3244DC843F254CF24330000B +:10D1100070000000000000008010E448B01022DC25 +:10D1200008B602FD92888523F440F102ED00882DB7 +:10D130000E600BBC122C10A8822E000AFC22A00448 +:10D1400030000000000000008805C080B32228C025 +:10D15000083082CC0188002CC04A3202CC00010188 +:10D1600028004BB002A00080002C090834026201A4 +:10D170007000000000000000C015AC04B2102AC10D +:10D1800008B002EC10898022C008B002EC088800C8 +:10D190002E4083B002A040B9802C210AB002F004D6 +:10D1A00060000000000000004015EC00FA00BAC06A +:10D1B0002CB043EC00C0803EC08EB0034C0CC810B5 +:10D1C0003E808FB0038210D8823E280CB00B5004F2 +:10D1D0007000000000000000E001B680FD0237C1D1 +:10D1E0000FB003FC00FD003EC00FB053FC02FF0176 +:10D1F0002FA48BF0837C00AD022F40037003B80096 +:10D2000060000000000000004010AC00FB0432C0D1 +:10D210004CB0232C00F8403EC20CB0032C00FB4164 +:10D2200032C20FB0432D00C8503E400CB00B10046A +:10D230002000000000000000C8052F90B95003C076 +:10D2400018F01A3C00B9322DE038F0603C04F900C7 +:10D250003EF00B7C802C00D9C02E400DF002320035 +:10D260004000000000000000E0054B24B21002C1A5 +:10D270002830026C04B2C12CC00830000C00B2008F +:10D280002824033C0A000082C82CA0083002380081 +:10D29000500000000000000020011600B48021E4CE +:10D2A000487B025E00B6806DE24879221E40AC8465 +:10D2B0002DE00BFA00524096802DE8193802080044 +:10D2C000400000000000000048080840F310B0C40F +:10D2D000083A024C90F3103CCC0831030C49B040A2 +:10D2E00030050F3007214043013EC21C304312027B +:10D2F0000000000000000000400DBC10FC103FC505 +:10D300000FF101BC04FF043FC40FB14BFC64F700F4 +:10D3100037C00F7253AC44FF013FC90FF403D0066E +:10D320006000000000000000A805EC08FA003EE0E4 +:10D330000CB0032C00CB023ECA0FB2072E00DB025A +:10D3400032080F31032C00CB043E800C35032A0039 +:10D35000700000000000000048119400B5002DC8C6 +:10D3600008700A1C2287002DC90BF2829C80A6003F +:10D37000098B0B700A1C0285002D40087002920474 +:10D380006000000000000000C0009E00B7802CEC90 +:10D39000087B025E4085892DEC8B7B024E848F805A +:10D3A00025640BFA02120897806FE1087A023000B8 +:10D3B00020000000000000004814CC20B3642CC002 +:10D3C0000830060C10838A6CC05B3042CC00AB1076 +:10D3D0002CF20B30020D0093042CD508300A920475 +:10D3E0003000000000000000E815BB00FEC03E80D9 +:10D3F0002CA0036800C6403F800FA0026800CE4406 +:10D4000036904F60031B70DED83FA00C20033A0417 +:10D4100060000000000000004800E040F8103E00FE +:10D420000F8003A010F8423E101F8003A000E80CFC +:10D430003A041F8003E000E8457E022F8003D200FB +:10D44000300000000000000008106400E980324055 +:10D450000F900B0408D98036400F10132408F900F0 +:10D4600072700F91132410C9103E690C90030204CE +:10D47000300000000000000080046408B9802240F1 +:10D480000B1002240089C422520B90422400B900E0 +:10D4900022E00B90122404D94A2E60089003600009 +:10D4A000100000000000000018052400B118224000 +:10D4B0000B900224008B2026490B90026400B900D7 +:10D4C000A2400B908A24008B002C40A890020600FA +:10D4D000400000000000000008040484B120A048BF +:10D4E0000B11060400830000404B11020449B110E7 +:10D4F00028400B1002244191002C500810024201D8 +:10D500000000000000000000B80D6940E85032142F +:10D510000F869321E2C800360A0B868B61A8F8407B +:10D5200022800F82A32108C8023E000C80432E03F4 +:10D530005000000000000000981DF448FD123E4419 +:10D540000F1203C4007D011E400B9203E480F520FE +:10D5500036400F9003D4907D003D400F9403E606C3 +:10D5600070000000000000001801F6C1DD88327272 +:10D570000C98032622DD003F622C998346A0C94007 +:10D58000B2400FD8032400FD0033512CD88306008D +:10D5900070000000000000003810E3C288C0223094 +:10D5A000088C4222118A012E00088852230080A391 +:10D5B0002A004B804222A0B80022280884028E0450 +:10D5C00030000000000000000805C400812D204844 +:10D5D000681480042081002E400B12120424812044 +:10D5E00020400B94320490B900204048104A0201B8 +:10D5F00070000000000000001815A40089202240DF +:10D60000089012240089002E4008900224088940C6 +:10D6100022500BB0022420B909A2440890028604CB +:10D620006000000000000000A015E400D908B2402E +:10D630004C10230404D9C13E408F900B0408C14014 +:10D6400012400F90432404F14130780C90032804D9 +:10D65000700000000000000028018664F9803E4050 +:10D660000F900BE400F9983E402F1003A402F9102C +:10D670003E400F900BE640F9903E600F9003CA00C9 +:10D6800060000000000000002810A000C841320027 +:10D690000C80072010C8103E0C0E8003E004C80068 +:10D6A000BA000F81432000F8703E000F000B0A04FF +:10D6B0002000000000000000280539028E20A38011 +:10D6C00028E00A3810AE043DA18EE002F8008E007A +:10D6D00076800B60037800BE402F820BA003CA0047 +:10D6E000400000000000000028054D008B8822C08B +:10D6F0001830020C0083442CD01B3012CC0683005F +:10D7000020C10B30820C01B3002C400B30020A0008 +:10D710005000000000000000A0011C00850020CC8B +:10D720000870061C84A70129C00B7222DC80873494 +:10D7300061800B10025C00B7002DC00B7002E80086 +:10D740004000000000000000A8080E008C8031E0BE +:10D750000CFE023F00C5802DE00E7803DFA0C7A0BD +:10D7600021600F78031E80F7803DE00F78032A02C6 +:10D770000000000000000000081DAC00F9003EC0E1 +:10D780000FB003EC00FA003EC006B003EC80FB28AB +:10D7900036D84FA003EC10FA003E500F3003C206FB +:10D7A00060000000000000000005FA00CC80B3E03B +:10D7B0000FF8033E00CF903F604FF8C33E00EF806C +:10D7C00033F00C7A033E70C59033F10C78030000FF +:10D7D0007000000000000000A811B800870021C000 +:10D7E0000B704A1C0087102DC04B710A3C448F12ED +:10D7F00021860D72021E008700234008700A2A0449 +:10D80000600000000000000000009C00840025C0B3 +:10D810000B710A0C00A7122D840B700A1C00B708AC +:10D82000234009F31A5C869708254008700200001F +:10D8300020000000000000002014CC20812026C021 +:10D840000B30022C0082422C800B30220C089B8073 +:10D8500020E00920024D08920024E508300A08045F +:10D860003000000000000000A815AE82CAE0B7C07A +:10D870000FF0133C0AC9C83E400FF0033C04FF847C +:10D8800032C00D90137C00D900F6C02C10032A047E +:10D8900060000000000000008000E400F3003AC1D6 +:10D8A0004FB003EC00F9083C000F3013EC00EB0420 +:10D8B000BE180F9023AC60E9023A404F9003E0009D +:10D8C00030000000000000000110FC00CA0033C05E +:10D8D0000CF003FC00CD027F400CF0423C00CF086E +:10D8E00037100FD003FC10CD083F662CD90300443D +:10D8F0003000000000000000810463808BE022C043 +:10D9000008B022EC00D8806E2068B01A2C01FB0011 +:10D9100022180B88434C0088A02CC01D9002204088 +:10D920001000000000000000800108808B2022C051 +:10D9300008B022EC0088882E6248B01ACC008B0018 +:10D9400026C04A8802EC0008842E4009900220007C +:10D95000400000000000000008040000830060C0D8 +:10D96000083002CC0090066C000830028C00A30442 +:10D9700020008B00064C2180006CC049100A020177 +:10D980000000000000000000000D6C00CA00B2C1E1 +:10D9900088B403EC10C8002E000CB00BBC088F003C +:10D9A0003600068003EC80C8023FC10C90030003E0 +:10D9B0005000000000000000A01DF000FF003FC06C +:10D9C0000F7283FC18FC033F008F70037C00FF0084 +:10D9D0003D000FC0238C06FC003F400ED003E8063C +:10D9E000700000000000000000C541037040DC1022 +:10D9F00037040DC1037040DC1037040DC1017040C5 +:10DA00009C10171405C1037040DC1017040DC031C1 +:10DA1000000000000000000000C5440571015C40EA +:10DA2000571015C40521015C40571015C401710140 +:10DA30005C40171005C40571055C41571015C011F5 +:10DA400050000000000000000080020120804820FB +:10DA500012080482012080482012080482012080DC +:10DA600048201208048201208048201208048020E7 +:10DA7000000000000000000000800000600058006E +:10DA80001600058001600058001600058005600042 +:10DA900058001618018001600058005600058020CB +:10DAA000000000000000000000C5480522011C80A5 +:10DAB000472011C80472015C80572011C8047241CC +:10DAC0005C80572011C80472011C80472015C031AA +:10DAD000500000000000000000C540006000180079 +:10DAE0000600018000600018000600018000600050 +:10DAF0001800060001800060001800060001803157 +:10DB0000000000000000000000C548042201088059 +:10DB10004220108804220108804220108004230142 +:10DB20000880422010880422010800422010802131 +:10DB3000000000000000000000C54A05428150A01E +:10DB4000442C110B04428110E05428110200428140 +:10DB500010A04438110B0542811021142815003102 +:10DB6000500000000000000000800C01570054C06D +:10DB70001530044C01130054C01570054C015300BE +:10DB800054C01530854C01130054C0153005402198 +:10DB90004000000000000000008000004000100075 +:10DBA000040000400010001062040001080441005D +:10DBB0001000441811000010001080040001012022 +:10DBC0000000000000000000004560020800820024 +:10DBD00020800860021800820020800820000820B1 +:10DBE000820000808020021800820020800801311D +:10DBF000500000000000000000C54005640158000E +:10DC000056001580056001580056401580056001DA +:10DC100058005600158005600158007600158031C7 +:10DC2000000000000000000000C540036000D800B4 +:10DC300036000D80036000980036001D88056000E6 +:10DC4000D80016000D80036000D88046000D80319A +:10DC5000000000000000000000C5420430810C20DC +:10DC6000430810C20430810C22410818C2043089D4 +:10DC70000C20030810C20430810C20430810C0108F +:10DC800050000000000000000080000030000C0088 +:10DC9000030000C00030000C00030000C000300092 +:10DCA0000C00030000C00030000C00030000C001A5 +:10DCB00000000000000000000080020130804C20C5 +:10DCC000130804C20130804C20130804C3013080C3 +:10DCD0004C20130804C20130804C30130804C021CA +:10DCE000000000000000000000C5420560815820CF +:10DCF0005608118205608158205608118300608102 +:10DD0000582046081182046081183056081580306A +:10DD1000500000000000000000C5420020800820E4 +:10DD20000208008200208008200208008200308063 +:10DD300008200200008200208008200308008031B3 +:10DD4000000000000000000000C5420460811820AF +:10DD500046481192046081192046281182003481BE +:10DD60001820464811920460811820430811801140 +:10DD7000000000000000000000C5600458015600CB +:10DD80005580156004580116005580016004180183 +:10DD90005600458011600458011600418011403141 +:10DDA000500000000000000000800601418050602B +:10DDB00014180506014180506004180506004180D2 +:10DDC00010601418050601418050601418050020E9 +:10DDD0000000000000000000000002010080402060 +:10DDE0001048041201008041201008040201048040 +:10DDF00040205048041201008440201008040020F4 +:10DE0000000000000000000000C546035180D460FF +:10DE100030180D46035180D56035180D4603058036 +:10DE2000D46015180D46031180D46035180D4031AB +:10DE3000500000000000000000C5460571805C60D5 +:10DE4000971815C60571815C20571815C603708197 +:10DE50005C60571811C60531815C60771815C031B8 +:10DE60000000000000000000004546037180DC60F7 +:10DE700037180DC6037180DD60371805C60175813E +:10DE8000DC6037180DC60371845C60171819C01167 +:10DE900000000000000000000045460571815C6044 +:10DEA000571814860571815C60571805C6043181C6 +:10DEB0005C60571815C60571805C60431815C01169 +:10DEC00050000000000000000000020120804820F7 +:10DED0001208048201208048201208048201708008 +:10DEE000482012080482012080482017080480007E +:10DEF0000000000000000000000006016180586082 +:10DF0000161841860161801860063C058604618010 +:10DF10001860161801860061805860561815801028 +:10DF200000000000000000000045400570015C009A +:10DF3000570015C00470015C00570010C004700049 +:10DF40001C00470011C00470015C00470001C011B3 +:10DF500050000000000000000045420060801820D2 +:10DF60000608018200608018200608008200608098 +:10DF70001820060801820060801820060801801120 +:10DF8000400000000000000000054204208108203D +:10DF90004208108204208108204208118204208057 +:10DFA00008204208108204208108204208008011C5 +:10DFB00000000000000000000045420540815020A4 +:10DFC000540815020540811020540C154200408170 +:10DFD000502044081102054081102014080500114A +:10DFE00050000000000000000001030150C0543048 +:10DFF000150805420150C05430150C05430150C0AE +:10E000005430150C05420150C05430150C05401019 +:10E010000000000000000000000008004200108026 +:10E0200004200188006200108004001108004200F2 +:10E03000108004200108004201108004200100002B +:10E040000000000000000000004542020080802027 +:10E050002008080202208080202028000202008080 +:10E060008020200A080202008000202008080011F9 +:10E07000500000000000000000454005600158000D +:10E08000560005800560015808560015800760029B +:10E090005800564015800560031800760015801161 +:10E0A000000000000000000000C540036000D80030 +:10E0B00036000D80016000D80A36000D8005700919 +:10E0C000D80136000D80036000D80057000D800095 +:10E0D00000000000000000000000000430010C00FF +:10E0E000430010C00030010C00432010C004600148 +:10E0F0000C00434050C10430010C00460010C00029 +:10E1000000000000000000000000000030000C00D3 +:10E11000010000C00030000C00030000D00020000F +:10E120000C00034000C00030000D00020000C000E1 +:10E1300000000000000000000000050131404C50CC +:10E14000131004C40131404C50131404C511314163 +:10E150004C50131404C50131404C50131404C0003A +:10E1600000000000000000000000230568C15A30D4 +:10E17000568C11A30468C11A30568C11A30568C0CF +:10E180005A30468C11A30468C15A30168C15800091 +:10E190000000000000000000000000002000080057 +:10E1A00002000080002000080002200090002000F3 +:10E1B00008000240008000200009000200008000EA +:10E1C0000000000000000000000008446201188404 +:10E1D0004621118844621118844601118844621056 +:10E1E0001884462111884462111884062111800088 +:10E1F0000000000000000000000000455011540421 +:10E200005501114045501114004501114044500082 +:10E2100014044500154044501114045501114000E8 +:10E2200000000000000000000000082142085082A9 +:10E2300014208508214208508204208508214208C4 +:10E2400050821420050821420850821420850000C5 +:10E25000000000000000000000000A01028040A051 +:10E260001028040A01028040A01028400A01028000 +:10E2700040A01028440A01028040A0102804000099 +:10E28000000000000000000000000C035300D4C098 +:10E2900035300D4C015300D4C035100C4C035300E5 +:10E2A000D4C035300D4C035300D4C035300D400080 +:10E2B00000000000000000000000080572015C8002 +:10E2C000172005C80672015C80572015C80272012C +:10E2D0005C80572015C80572015C80372011C00092 +:10E2E00000000000000000000000231840C61231AA +:10E2F000848C21230848C61230840C61231048C244 +:10E300001231848C01230848C61231048C6100004C +:10E31000000000000000000000003FFF4FFFD3FF9F +:10E32000F4FFFD3FFF4FFFD3FFF4FFFD3FFF4FFF23 +:10E33000D3FFF4FFFD3FFF4FFFD3FFF4FFFD0000CD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000002CDB0FB6C2CD42 +:10E38000B0B36C2CDB0B36C2DFB0B36C2CDB0B7E76 +:10E39000C2CDB0B7FD2CDB0B36C2CDB0B36C0000E4 +:10E3A00000000000000000000000333C4FCF13339A +:10E3B000C4CCF1333C4CCF133FC4CCF1333C4CFFC5 +:10E3C0001333C4CFFD333C4CCF1333C4CCF1000026 +:10E3D000000000000000000000003B7E4EDF93B70D +:10E3E000E4EC793B1E4EDF93BFE48DF93B784EFFA2 +:10E3F00093B7E4EDFD3B1E4EDF93B784EDF90000CB +:10E4000000000000000000000000010270409C10AD +:10E41000271C09C10130401C10670409C10270416A +:10E420009C11071401C10270409C50071C01C000E0 +:10E4300000000000000000000000040571015C40C5 +:10E44000571055C40131005C40571015C4057101C7 +:10E45000DC4017181DC40571055C4057101DC00035 +:10E4600000000000000000000000020120804820A1 +:10E4700012000482012080482012080482012080BA +:10E48000482012080482012080486012080480009D +:10E490000000000000000000000000006000180004 +:10E4A0000600418000600018004600018000600006 +:10E4B0001000061001800060001820461001800046 +:10E4C00000000000000000000000080472011C8031 +:10E4D000472011C80472011C80072011C804730072 +:10E4E0001C80472011CC0472011C80472011C00001 +:10E4F00000000000000000000000000060001800A4 +:10E5000006000184006000180006000180006040E1 +:10E510001800060401810060001800061401800044 +:10E520000000000000000000000008042201088034 +:10E530004270108C04220108C002201088042200BE +:10E540000880425010080422010900424010800057 +:10E55000000000000000000000002E044A8112A00C +:10E5600044A8112A044A8112A004A8112A044B804D +:10E5700012A04488012E044A811220049801000050 +:10E58000000000000000000008C00E00530014C08E +:10E590000530014C00530014E00530014C005300DD +:10E5A00004C00530004C00030014C00530004010CA +:10E5B000000000000000000008C00400400010003F +:10E5C0000458010400400010000400010000410054 +:10E5D00004004458104400000011800450104030E2 +:10E5E000000000000000000008C0400200008000A1 +:10E5F0002000080040000000002000080002000089 +:10E600008400000008400200008000200008403024 +:10E61000000000000000000008C040006001180079 +:10E6200046000180066001980046001180046001E8 +:10E630001800460011800420011800660011803087 +:10E640000000000000000000100140006000980081 +:10E6500026000980026001980006000C800260001C +:10E660001800060001800260009880060001820008 +:10E6700000000000000000004045420030810C20F6 +:10E68000430810C22430818C20030810C20420806B +:10E690000C20030818C20430810C20430818C01154 +:10E6A00050000000000000004000000030000C009E +:10E6B000030000C04030000C000300008000300068 +:10E6C0000C00032000C00030000C00032000C0003C +:10E6D00000000000000000004001021030800C200B +:10E6E000030800C20030800C20030800C201208013 +:10E6F0000C20032C00C20030800C30432C00C000E2 +:10E7000040000000000000004045420460811820E5 +:10E710004608118204608018204608118204608136 +:10E720001820460C11C20460811830460C11C0112B +:10E73000500000000000000040014200208008203E +:10E740000228008200208008200208008200208029 +:10E7500008200208018200208008200308018000B0 +:10E7600000000000000000005001420460811820F9 +:10E7700046281182046080182046081182046081B6 +:10E780001820460810820460811820430810800079 +:10E79000000000000000000040454004500114004B +:10E7A00045001140250000140045001140045001AF +:10E7B00014004500004004500140000100004211D7 +:10E7C000500000000000000048000600418010607A +:10E7D0000418010600418010600418010600418001 +:10E7E0001060041801060041801060041801000048 +:10E7F00000000000000000004800020500804021E9 +:10E80000100804000100804020100804020100806C +:10E810004020500814021100844020100814000009 +:10E820000000000000000000404546015180D46017 +:10E8300035180D46035180D46015180D46035180DC +:10E84000546015180D46035180D46035180D4011E1 +:10E8500050000000000000000001460471811C60AF +:10E86000451811D60471811C60671811C6047181A6 +:10E870009C60471811C60471811C60671811C000A4 +:10E8800000000000000000004005460271809C600E +:10E89000271809C60071809C60671809C60271803C +:10E8A0009C61271801C60271809C60071801C00096 +:10E8B00000000000000000005045460571815C60CA +:10E8C000571855D60171815C60571815C6057181BE +:10E8D0005C60571818C60571815C60431818821176 +:10E8E0005000000000000000400452012080482039 +:10E8F00012480490012080492012080482012480DB +:10E9000048201248009201208048201748048001C6 +:10E910000000000000000000400006006180186058 +:10E92000063C0186006180186046180186006180FF +:10E930001860061801860061801860461801800181 +:10E9400000000000000000000041600478011E008B +:10E95000478011E02478011E00078011E00478014F +:10E960001E00478011E00438011E00478011C011CD +:10E9700050000000000000004001120060801820DC +:10E980000648019200608019200608018200648018 +:10E9900018200648019300208018200648018000B6 +:10E9A0000000000000000000400142042081082017 +:10E9B000420810820420810820020810820420816D +:10E9C00008204208108A0460810820420810800054 +:10E9D000000000000000000040454204408110207B +:10E9E00044081102044081102004081102044081EF +:10E9F0001021440801020450811020040801001174 +:10EA000050000000000000004000030050C014301F +:10EA1000050C01430050C01430050C014300508028 +:10EA200014300508014A0050C014300508014000A8 +:10EA300000000000000000004000080042001080BC +:10EA40000420010800420010800420010800420058 +:10EA500010800420110000420010800420110010DA +:10EA6000400000000000000040454202008080207D +:10EA70002008080200008080202008080202008090 +:10EA80008020200808020200808020200808001151 +:10EA9000500000000000000040014000600118002C +:10EAA00046001180066001180046001180046001D4 +:10EAB00018004600118004600118006600118010E3 +:10EAC00000000000000000004001400264009800C7 +:10EAD0002600099006600198002640098002600027 +:10EAE0009800260000900260009800070001800056 +:10EAF00000000000000000004045600438050E00E2 +:10EB0000438010E04438010E00438010E0043801D7 +:10EB10000E00438018A00438010E004680188011B2 +:10EB200050000000000000005000010030400C10B8 +:10EB3000030400C50030400C10031400C100304035 +:10EB40000C10030400874030400C100204008000C9 +:10EB500000000000000000004004050035400C509B +:10EB6000031400D50431410C50035C00C500310092 +:10EB70000C50031000940031400C50431000C200B0 +:10EB800000000000000000004045430520C118308F +:10EB9000460C11970060C01830461C11830460C1F8 +:10EBA0001830520C11870460C11830460C118011C6 +:10EBB000500000000000000040010000214008005B +:10EBC00002000080002000080002000080002000F9 +:10EBD0000800020000800020000800020000800001 +:10EBE0000000000000000000400148442201188499 +:10EBF0004621119800621018844420118844621143 +:10EC00001884422111804462111884462111800029 +:10EC100000000000000000004045400450111404B2 +:10EC2000450011410050101400450111404450119D +:10EC30001404450101404450111404050101401120 +:10EC40005000000000000000400008204208108230 +:10EC50000420010820420810820420810820420874 +:10EC6000108204228108205208108A0422810000A8 +:10EC7000000000000000000000040A01028440A11E +:10EC80001028000A01028040A01028040A01028016 +:10EC900040A0102C140A00028040B0102C14000078 +:10ECA000000000000000000040454D035340D4D058 +:10ECB00035300C4D035340D4D035340D4D03534003 +:10ECC000D4D035340D4D021340D4D035340D40111D +:10ECD00050000000000000004001080472011C8088 +:10ECE000472015C80472011C80472011C804721106 +:10ECF0001C80472611C84472011C90672611C00071 +:10ED000000000000000000000000230840C612318F +:10ED1000848C01030848C61230840C61231848C251 +:10ED20001231848C01030848C61231048C010000A2 +:10ED3000000000000000000000003FFF4FFFD3FF75 +:10ED4000F4FFFD3FFF4FFFD3FFF4FFFD3FFF4FFFF9 +:10ED5000D3FFF4FFFD3FFF4FFFD3FFF4FFFD0000A3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED9000000000000000000000002DFB0FB6C2CDF7 +:10EDA000B0B7FD3FFB0B36C2DFB0FB6C2CDB0B7E3C +:10EDB000C2CDB0B7FD3FFB0B36C2CDF4B7FD0000AE +:10EDC0000000000000000000000033FC4FCF1333B0 +:10EDD000C4CFFD3FFC4CCF133FC4FCF1333C4CFF90 +:10EDE0001333C4CFFD3FFC4CCF1333F4CFFD0000F1 +:10EDF000000000000000000000003B7E4EDF93B7E3 +:10EE0000E4EDF93FFE4EDF93B7E4EDF93B7E4EC7EC +:10EE100093B7E4EC61231E4EDF93B784EC610000EE +:10EE20000000000000000000000000C524A14A24EA +:10EE3000630114024400810B2871021082403811D2 +:10EE4000410450081882873831C32C520A10000040 +:10EE5000000000000000000000000845128144800E +:10EE600071211C0A071A8102A0522014480712813E +:10EE7000C680602008884702014A80702010000088 +:10EE80000000000000000000000002C52C014A0044 +:10EE900052091C800724210808710210804520A116 +:10EEA0004928520114C0450091C4007202100000AC +:10EEB0000000000000000000000002072001C10067 +:10EEC0007109108007000101007008188007000117 +:10EED000892052010C8046308145046000100000FA +:10EEE0000000000000000000000008C202200088AE +:10EEF00020220008C22280408802220008820AA044 +:10EF00000CA802220008800A00808C022200000067 +:10EF10000000000000000000080002430000402044 +:10EF200030080440413010C8000000000203001007 +:10EF3000C000110800C2431080C020010800020078 +:10EF40000000000000000000080008C30A20C18C77 +:10EF500012220488013620C3081228040801040084 +:10EF60004AA8220104C8412630C0880221000200BC +:10EF70000000000000000000080008000A10C18026 +:10EF800032210C88430280448012290408420A90EE +:10EF90008A8000200448030A1082800020000200BA +:10EFA000000000000000000000000A8702A180AC01 +:10EFB0004329148A8402A100AC412010080626319E +:10EFC00080A46020144A44328181AC602A18020077 +:10EFD0000000000000000000080008072201C580B2 +:10EFE00073211CC8072A010C807220104847261183 +:10EFF000C58073201C88072A1149807020140200E4 +:10F000000000000000000000080000451031C90C9D +:10F0100073021CC04704010A0C510A1082472031B8 +:10F02000C80072021C40053011C4007201180200B1 +:10F030000000000000000000081010062401450434 +:10F04000518118904714010404718810120534018D +:10F050004404514018D0073801C404520114C204BA +:10F060000000000000000000000000870021890C63 +:10F0700060011CD0452401C10C42010000C52031B3 +:10F08000410840001880450021410C70421CC2001C +:10F090000000000000000000000002011C80C420ED +:10F0A00031081042420880C62031090020031C901C +:10F0B000C42001490C424310804420310810000054 +:10F0C0000000000000000000000030832030480CE9 +:10F0D00032401090812420C80432401020C3208088 +:10F0E000C800024A0CA0012410C8083241100000D8 +:10F0F0000000000000000000001090030000C904A0 +:10F10000304000900020008000104010004020108F +:10F11000C20000800820430810810032400CC00467 +:10F12000200000000000000000003000400000004F +:10F13000100000F01020000000100000F0108040CF +:10F140000000004000F01090800000000000C000AF +:10F1500000000000000000003C3C108090400000D7 +:10F1600000801090A09000000000001090808000AF +:10F1700000000000109080900000000040108F0FF1 +:10F180000000000000000000000024C6BA06C01CF9 +:10F19000492861142B1C0E403FD9BFD9AABC1A5F65 +:10F1A0000010A6503B61B325BC4019BFFFE98000A9 +:10F1B0000000000000000000000010921494800C79 +:10F1C000073F2B948614848028000049140486127B +:10F1D0008000412734D0908492002D8A211E800027 +:10F1E000000000000000000000000000000008A275 +:10F1F000B10101000000000884B17828000000007F +:10F2000008B13214140000000008A8235421400063 +:10F21000000000000000000000003FFFFFFFC000F2 +:10F220000000002FFFFEF7C0000000002FD7FEEF08 +:10F23000C0000000003FFF7FFFC000000000000092 +:10F24000000000000000000000003FFFFFFFC000C2 +:10F250000000000FEF77FFC0000000003EFFFEEF50 +:10F2600040000000003FFFBFFF4000000000000022 +:10F27000000000000000000000003FFFFFFFC00092 +:10F280000000003FFFDFFFC0000000003FFFFFFF66 +:10F29000C0000000003F7F2FFFC000000000000002 +:10F2A000000000000000000000003FFFFFFFC00062 +:10F2B0000000001FFFFFEFC0000000001FEFEFEF96 +:10F2C000C0000000002FFFFFFFC000000000000092 +:10F2D000000000000000000000003FFFFFFFC00032 +:10F2E0000000003FFFEFFFC0000000002FAFDFFF76 +:10F2F000C0000000003FEFFFF7C00000000000006A +:10F30000000000000000000000003FFFFFFFC00001 +:10F310000000003FDFDFFFC0000000003FFFFFFFF5 +:10F32000C0000000001FFFDFFFC000000000000061 +:10F330000000000000000000000002C424A1002C16 +:10F34000520B18C2862CA18038620A0840C42CA136 +:10F350000828420B14008514A10828430A10000055 +:10F3600000000000000000000000080412010380FB +:10F3700061201008071241428070201C08041A0105 +:10F3800084814020180846368105806320100001E2 +:10F390008000000000000000000000842421000C18 +:10F3A00052021400872821810872061C82842021C1 +:10F3B0004818420354804530254A18530210000172 +:10F3C000200000000000000000000804220101806D +:10F3D000422018C8442201808442201C8804220153 +:10F3E0000080402010884436014080410010000019 +:10F3F0000000000000000000000000C00820000C19 +:10F4000022030440810020840803000080C2002001 +:10F41000C408000308888216A040883222800000B9 +:10F42000000000000000000008000201008004202D +:10F4300010080CC2121084C82212080402030088AB +:10F440000021000C0C404130008420100800020014 +:10F450000000000000000000080008820620088C60 +:10F4600032220C888126204D882322808883062022 +:10F4700008880023048A8136204B8832220000004D +:10F4800000000000000000000800080202000980DF +:10F49000322004886022008984002008980002003D +:10F4A000008000200008023A8048803020000200DE +:10F4B000000000000000000008000AC41AA180A893 +:10F4C000412A10CAC71AA104AD712A184AD406B13C +:10F4D00000A8712A100884262906AC522A100200BE +:10F4E0000000000000000000080008042A0141801C +:10F4F00042201C00040A01098451201C8844020196 +:10F5000008804020104A4702014880632010020012 +:10F510008000000000000000080000C41021810CE1 +:10F5200041020C00C020610D0E72021C40C4083163 +:10F530000418420210808720B1C40C53021000004E +:10F540000000000000000000081020072401CC008B +:10F55000724014000424010800734110C0073011E8 +:10F56000CC007101100204208146104240100204B8 +:10F570000000000000000000080000C51021000885 +:10F5800062021C90C52421000C70821C10C4203122 +:10F59000880240061C008500A1000C4042000200C9 +:10F5A000000000000000000000002205148001207F +:10F5B00030080C42060080012451080C02410080F2 +:10F5C0004C2000080C304204000420000800000019 +:10F5D0000000000000000000000010C62420000C05 +:10F5E00032C20480C73020000C53C20410C22870FD +:10F5F0000C0902024C80810430090C024210000008 +:10F60000000000000000000000108001380002002F +:10F6100012400C200734040200630108100024107B +:10F620000400020104820108800910024010000455 +:10F6300030000000000000000000302010800000BA +:10F64000208000F02010800000208000D08000008A +:10F650004000000000301000800000000000CC409E +:10F6600000000000000000003C3C10808000000012 +:10F67000000010908080000000000010908000903A +:10F68000800010000010A0800000002000108C08F6 +:10F6900000000000000000000000341ABE178000C7 +:10F6A0003E40266FBAE32480001659BD828182D87D +:10F6B000800000199986806480C03FD9998000013C +:10F6C000F000000000000000000006160294001682 +:10F6D000C01694829016108021182828020A020869 +:10F6E00080000000000282801400011411A040007C +:10F6F000000000000000000000000000000008847E +:10F700000284A8800000000891228441A2082401FC +:10F7100030000000000000000008840144010000E7 +:10F72000000000000000000000003FFFFFFFC000DD +:10F730000000003EF7FFF7C0000000002FE7B7FF12 +:10F74000C0000000002FFE7FF7C000000000000096 +:10F75000000000000000000000003FFFFFFFC000AD +:10F7600000000036BFFEDFC0000000000FF7DFFF23 +:10F77000C0000000003DB7B7EFC00000000000006F +:10F78000000000000000000000003FFFFFFFC0007D +:10F790000000001FDFDFFFC0000000000FDFDFFF01 +:10F7A000C0000000003FEFFFFFC0000000000000AD +:10F7B000000000000000000000003FFFFFFFC0004D +:10F7C0000000003FBF7FFFC0000000003FFF7FF749 +:10F7D000C0000000003FDFFFFFC00000000000008D +:10F7E000000000000000000000003FFFFFFFC0001D +:10F7F0000000003F7EFFFF40000000003FFEFFFFD3 +:10F80000C0000000003FFFFFFFC00000000000003C +:10F81000000000000000000000003FFFFFFFC000EC +:10F8200000000037FF6FFFC0000000003FFFFFFF38 +:10F83000C0000000003FFFFFFFC00000000000000C +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000300020010200000035 +:10F880003000430C000000000000000000000000F9 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F00000000000000000000030C00000000030E8 +:10F90000C000000000000000000000000000000037 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F95000000000000000000000000030C030C000C7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B00000000000000000000030C030C030C03047 +:10F9C000C000000000000000000000000000000077 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA10000000000000000000000F00000000000FC8 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000003FC0000000003F48 +:10FA8000C0000000000000000000000000000000B6 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000F0030C030C00F28 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB3000000000000000000000136B00C000CF2C8C +:10FB40004000000000000000000000000000000075 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB900000000000000000000000000F000F000047 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF00000000000000000000030C00F000F0030C7 +:10FC0000C000000000000000000000000000000034 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000003FC03FC000A6 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB00000000000000000000030C03FC03FC03026 +:10FCC000C000000000000000000000000000000074 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD10000000000000000000000F000F000F000FA7 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000003FC00F000F003F27 +:10FD8000C0000000000000000000000000000000B3 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000F003FC03FC00F07 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE3000000000000000000006335D80C000FDAC43 +:10FE400002000000000000000000000000000000B0 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF00000000000000000000030C00000000030E2 +:10FF0000C000000000000000000000000000000031 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF5000000000000000000000000030C030C000C1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB00000000000000000000030C030C030C03041 +:10FFC000C000000000000000000000000000000071 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:108010000000000000000000000000000000000060 +:108020000000000000000000000F00000000000F32 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:108080000000000000000000003FC0000000003FB2 +:10809000C000000000000000000000000000000020 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000F0030C030C00F92 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:108140000000000000000000001374C0C000F0EC4C +:1081500040000000000000000000000000000000DF +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000F000F0000B1 +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:1082000000000000000000000030C00F000F003030 +:10821000C00000000000000000000000000000009E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:1082600000000000000000000000003FC03FC00010 +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C0000000000000000000001986108030823D90 +:1082D000800000000000000000000000000000001E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:108320000000000000000000000F000F000F000F11 +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:108380000000000000000000003FC00F000F003F91 +:10839000C00000000000000000000000000000001D +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E0000000000000000000000F003FC03FC00F71 +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:108440000000000000000000376525E48000B088CF +:10845000AB40000000000000000000000000000031 +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000300020010202000030004300E4 +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D00030000001000044723000800100000003F5 +:1090E0003000400C00000000000000000000000004 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:109110000000000030008001000000053000A001C8 +:1091200000000000300000010000E15A00000000D3 +:0C91300000000000000000000000000033 +:00000001FF +/* + * This firmware is for the Emagic EMI 2|6 Audio Interface + * + * The firmware contained herein is Copyright (c) 1999-2002 Emagic + * as an unpublished work. This notice does not imply unrestricted + * or public access to this firmware which is a trade secret of Emagic, + * and which may not be reproduced, used, sold or transferred to + * any third party without Emagic's written consent. All Rights Reserved. + * + * Permission is hereby granted for the distribution of this firmware + * image as part of a Linux or other Open Source operating system kernel + * in text or binary form as required. + * + * This firmware may not be modified and may only be used with the + * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of + * any driver which includes this firmware, in whole or in part, + * requires the inclusion of this statement. + * +/// VERSION=1.1.1.131 +// DATE=2001dec06 +// PRODUCT=EMI 2|6 diff --git a/firmware/emi26/firmware.HEX b/firmware/emi26/firmware.HEX new file mode 100644 index 0000000..1ca400e --- /dev/null +++ b/firmware/emi26/firmware.HEX @@ -0,0 +1,1261 @@ +:0300000002435662 +:03000300024BCDE0 +:03000B00024BD2D3 +:03001300024B920B +:03001B00024BD5C0 +:03002300021B3984 +:03002B000243E2AB +:03003300023FF396 +:03003B00024BC0B5 +:0300430002470071 +:03004B00023FFC75 +:030053000237FA77 +:03005B00024BC78E +:030063000246FC56 +:1005000012011001000000406A080101000101020F +:1005100000010902B80103010080A00904000000E5 +:10052000010100000A2401000156000201020C240E +:100530000201010100060000000015240605010269 +:10054000030000000000000000000000000000099F +:1005500024030204030005000C240203010200022C +:10056000000000000D240606030203000000000046 +:100570000009240304010100060009040100000130 +:100580000200000904010102010200000724010128 +:10059000000100112402010202100344AC0080BBE0 +:1005A0000000770109050A05840101008F07250174 +:1005B0000100000009058F01030001060009040184 +:1005C000020201020000072401010001000E2402C2 +:1005D000010602100244AC0080BB0009050A054C6C +:1005E0000201008F0725010100000009058F0103AA +:1005F00000010600090401030201020000072401B2 +:10060000010001000E2402010603180244AC008020 +:10061000BB0009050A05720301008F0725010100CF +:10062000000009058F01030001060009040104020E +:1006300001020000072401010001000B2402010255 +:1006400003180100770109050A05460201008F071A +:1006500025010100000009058F01030001060009C2 +:10066000040200000102000009040201010102006D +:1006700000072401040001001124020102021003FA +:1006800044AC0080BB0000770109058C05840101A2 +:100690000000072501010200000904020201010215 +:1006A00000000724010400010011240201020318C4 +:1006B0000344AC0080BB0000770109058C054602AD +:1006C00001000007250101020000050C0901A1013C +:1006D000050C09E9050C09EA1500250195027501CB +:1006E0008142950175068101050C0900050C090080 +:1006F0001500250195027501910695017506910376 +:10070000C004030904180345004D00410047004997 +:10071000004300200047006D00620048001E0345B2 +:10072000006D006100670069006300200045004D16 +:10073000004900200032007C0036002A0343006F8D +:10074000006E006600690067007500720061007449 +:100750000069006F006E0020005300740072006991 +:10076000006E006700220349006E0074006500728D +:100770000066006100630065002000530074007291 +:090780000069006E006700000032 +:100789007400F58690FDA57C05A3E582458370F983 +:01079900223D +:10079A00907FD6E04480F0438701000000000022E9 +:1007AA00C0D0C0E08FE0C0E08EE0C0E08DE0C0E0E5 +:1007BA008CE0C0E0C082C0830586C084C085E5188D +:1007CA00B402030207D9B401030207DE0207FA7D65 +:1007DA0001020816E51914F519C3B513030207F542 +:1007EA005009B400EA75190A0207D97D00020816F1 +:1007FA00E51914F519C3B514030208115009B40018 +:10080A00CE75190A0207D97D020208167C05907F67 +:10081A0099E05440DC03020843B4001D907FE3745E +:10082A007BF0A37480F0907FE27440F0907FE5F053 +:10083A00907FE27400F00208180586907FE27480C7 +:10084A00F0907965E0B4010302089EB4020302083D +:10085A0096B4030302088EB40403020886B405039F +:10086A0002087EB406030208760208F40586907F21 +:10087A006C0208E90586907F6C0208DD0586907F88 +:10088A006C0208CF0586907F6C0208C00586907FAF +:10089A006C0208B20586907F6CF000F000F000F060 +:1008AA000DEDB42DF40208F4F0F0F0F0F0F00DEDD7 +:1008BA00B42DF50208F4F000F000F000F00DEDB4EC +:1008CA0031F40208F4F0F0F0F0F0F00DEDB431F587 +:1008DA000208F4F0F0F0F00DEDB461F70208F4F05C +:1008EA00F0F0F0F0F00DEDB461F5907FE27400F0F5 +:1008FA00D085D0840586D083D082D0E0FCD0E0FDBC +:05090A00D0E0FED0E08A +:06090F00FFD0E0D0D02271 +:10091500C0D0C0E0C082C083907F6FE50CF0E50DCC +:0D092500F0E50EF0D083D082D0E0D0D022DB +:10093200C0D0C0E08FE0C0E08EE0C0E0C082C083E3 +:100942000586C084C085907970E0FFBF0003020A6B +:10095200B8907F96E04480F0907FE27480F0907FC0 +:1009620062E00586907FE27400F0907F96E0547F0B +:10097200F0907FE27480F0907988E0B4010302097C +:10098200BEB402030209C3B403030209ACB40403F4 +:1009920002099A0586020AB2EF5403FEEF030354DA +:1009A2003FFF907F6305860209C9EF5403FEEF0300 +:1009B20003543FFF907F630586020A360586020ACA +:1009C200A50586020A8EE0E0E0E0E0E00586E0E0D0 +:1009D200E00586E0E0E0E0E0E00586E0E0E00586B4 +:1009E200E0E0E0E0E0E00586E0E0E00586E0E0E06F +:1009F200E0E0E00586E0E0E00586DFCAEEB4000351 +:100A0200020AB2B40103020A25E0E0E0E0E0E005F8 +:100A120086E0E0E00586E0E0E0E0E0E00586E0E098 +:100A2200E00586E0E0E0E0E0E00586E0E0E0058663 +:100A3200020AB2E0E0E0E00586E0E00586E0E0E000 +:0D0A4200E00586E0E00586E0E0E0E00586E6 +:100A4F00E0E00586E0E0E0E00586E0E00586DFD641 +:100A5F00EEB40003020AB2B40103020A80E0E0E040 +:100A6F00E00586E0E00586E0E0E0E00586E0E005F1 +:100A7F0086E0E0E0E00586E0E00586020AB2E0E00D +:100A8F00E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E057 +:100A9F00DFEC020AB2E0E0E0E0E0E0E0E0E0E0E01E +:100AAF00E0DFF2907FE27400F0D085D0840586D02D +:0E0ABF0083D082D0E0FED0E0FFD0E0D0D02285 +:100ACD00C082C083C0E0E8C0E078D1E814F870FBC4 +:0A0ADD00D0E0F8D0E0D083D08222F0 +:100AE700C0D0C0E08FE0C0E08EE0C0E08DE0C0E0A5 +:100AF7008CE0C0E0758600C082C0830586C084C0D4 +:100B0700857E0090798EE0B400167401F09006CAD5 +:100B1700A3A3A3A3A3A3A3E0FF90798DF0020B39AE +:100B270090798DE0FF90798FE0FD907990E0FC025D +:100B37000B469006CA0586907F000586020B518DED +:100B4700848C850586907F000586E0A30586F0A343 +:100B57000EEEB44003020B6C0586DFEE90798E74BF +:100B670000F0020B820586AD84AC8590798FEDF09D +:100B7700907990ECF090798D1FEFF0907FB5EEF0C3 +:100B8700D085D0840586D083D082D0E0FCD0E0FD2C +:0B0B9700D0E0FED0E0FFD0E0D0D02284 +:100BA200C0D0C0E0C082C083907FAEE054E0F0903D +:100BB2007F96E0440854FBF0907F97E054BFF0909A +:100BC2007FE3747BF0907FE47440F0907978E0905A +:100BD2007B40F0907FE27448F0907FE5E0907FE206 +:100BE2007400F0907F96E054F74404F0907FE37431 +:100BF2007BF0907FE47440F0907979E0907B40F054 +:100C0200907FE27448F0907FE5E0907FE27400F01C +:100C1200907F96E054F3F0907FAEE0441FF0D083D3 +:070C2200D082D0E0D0D02207 +:100C2900C0D0C0E0C083C08290792FE064FFC324A4 +:0B0C390001F0D082D083D0E0D0D022A8 +:100C4400BB010689828A83E0225002E722BBFE02AE +:090C5400E32289828A83E49322E1 +:100C5D00BB010CE58229F582E5833AF583E022504C +:100C6D0006E92582F8E622BBFE06E92582F8E22296 +:0D0C7D00E58229F582E5833AF583E49322B0 +:100C8A00BB010689828A83F0225002F722BBFE0149 +:020C9A00F32243 +:100C9C00F8BB010DE58229F582E5833AF583E8F08E +:100CAC00225006E92582C8F622BBFE05E92582C83A +:020CBC00F22222 +:100CBE00C2D5EC30E709B2D5E4C39DFDE49CFCEE51 +:100CCE0030E715B2D5E4C39FFFE49EFE120E40C37B +:100CDE00E49DFDE49CFC8003120E4030D507C3E476 +:060CEE009FFFE49EFE22C0 +:100CF400C5F0F8A3E028F0C5F0F8E582158270028B +:060D04001583E038F02227 +:100D0A00BB0110E58229F582E5833AF583E0F5F027 +:100D1A00A3E0225009E92582F886F008E622BBFE04 +:100D2A000AE92582F8E2F5F008E222E5832AF5834A +:080D3A00E993F5F0A3E993220F +:100D4200E88FF0A4CC8BF0A42CFCE98EF0A42CFC50 +:100D52008AF0EDA42CFCEA8EF0A4CDA8F08BF0A4CE +:100D62002DCC3825F0FDE98FF0A42CCD35F0FCEB2D +:100D72008EF0A4FEA9F0EB8FF0A4CFC5F02ECD39F2 +:0F0D8200FEE43CFCEAA42DCE35F0FDE43CFC225F +:100D9100EB9FF5F0EA9E42F0E99D42F0E89C45F0B8 +:010DA100222F +:100DA200BB010DE58229F582E5833AF583020EA1A6 +:100DB2005007E92582F8020E95BBFE07E92582F865 +:100DC200020EADE58229F582E5833AF583020EB97A +:100DD200BB010DE58229F582E5833AF583020ED542 +:100DE2005007E92582F8020EC9BBFE07E92582F801 +:040DF200020EE122EA +:100DF600BB010DE58229F582E5833AF583020F06EC +:100E06005007E92582F8020EEDBBFE07E92582F8B8 +:040E1600020F37226E +:100E1A00D083D082F8E4937012740193700DA3A367 +:100E2A0093F8740193F5828883E47374029368607B +:060E3A00EFA3A3A380DF7B +:100E4000BC000BBE0029EF8DF084FFADF022E4CC96 +:100E5000F875F008EF2FFFEE33FEEC33FCEE9DEC5F +:100E6000984005FCEE9DFE0FD5F0E9E4CEFD22EDA5 +:100E7000F8F5F0EE8420D21CFEADF075F008EF2FEF +:100E8000FFED33FD4007985006D5F0F222C398FDE0 +:050E90000FD5F0EA227D +:0C0E9500E6FC08E6FD08E6FE08E6FF2289 +:0C0EA100E0FCA3E0FDA3E0FEA3E0FF22C4 +:0C0EAD00E2FC08E2FD08E2FE08E2FF2281 +:100EB900E493FCA3E493FDA3E493FEA3E493FF224C +:0C0EC900ECF608EDF608EEF608EFF62255 +:0C0ED500ECF0A3EDF0A3EEF0A3EFF02290 +:0C0EE100ECF208EDF208EEF208EFF2224D +:100EED00D083D082E493F608740193F608740293CC +:090EFD00F608740393F674047303 +:100F0600A8828583F0D083D082120F1D120F1D1286 +:100F16000F1D120F1DE473E493A3C583C5F0C583AB +:100F2600C8C582C8F0A3C583C5F0C583C8C582C835 +:010F36002298 +:100F3700D083D082E493F208740193F20874029389 +:090F4700F208740393F2740473C0 +:100F5000C2AFD22C907F937430F0907F9C74BFF01E +:100F6000907F96E05430F0907F947430F0907F9DA5 +:100F700074CFF0907F9774A0F0907F9574CCF0E4DC +:100F8000907F9EF0C22DC22AC22BC22E907974048B +:100F9000F0122E941249E2124BE612320D123B0D62 +:100FA0001241FD123E99E51F7018751F011217FFBF +:100FB000122FFF1249C8124BD8124BDA12496F1286 +:100FC0001B4012398D907FAFE04401F0907FAEE07E +:100FD000441FF0907FAC74FFF0907FADF0907FDE07 +:100FE000F0907FDFF0907FABF0907FA9F0907FAA28 +:100FF000F05391EF43D820D2E843D82043A8802271 +:10100000907963E014604414700221D0147002419E +:10101000D914700261D7240460028156E490797873 +:10102000F090797BE0907979F04401F054FDF090F4 +:10103000797BF0E4907988F0A2AF33F512C2AF1259 +:101040000BA2E51270028156D2AF2290792DE06496 +:10105000017079907FF2F0907FF37430F0907FFF11 +:1010600074FCF0E4907978F090797BE0907979F0F5 +:101070004401F04402F090797BF0A2AFE433F51222 +:10108000C2AF120BA29079787402F0907984E0904C +:101090007979F090797FE0B40109907979E054FE94 +:1010A000F08007907979E04401F0907979E054FD7F +:1010B000F054FBF0907984F0120BA29079827404C2 +:1010C000F090798814F0E5126002D2AF90792DE0AB +:1010D00064027079907FF2F0907FF37434F0907F27 +:1010E000FF74FCF0E4907978F090797BE090797966 +:1010F000F04401F04402F090797BF0A2AFE433F5C4 +:1011000012C2AF120BA29079787402F0907984E049 +:10111000907979F090797FE0B40109907979E05481 +:10112000FEF08007907979E04401F0907979E0440D +:1011300002F054FBF0907984F0120BA29079827443 +:1011400004F090798814F0E5126002D2AF90792D06 +:10115000E0640360028156907FF2F0907FF3746444 +:10116000F0907FFF74FCF0E4907978F090797BE068 +:10117000907979F04401F04402F090797BF0A2AFCD +:10118000E433F512C2AF120BA29079787402F0909A +:101190007984E0907979F090797FE0B401099079D1 +:1011A00079E054FEF08007907979E04401F090797D +:1011B00079E04404F0907984F0120BA29079827463 +:1011C00004F090798814F0E51270028156D2AF22B3 +:1011D00090792DE06401707A907FF2F0907FF37443 +:1011E00088F0907FFF74FCF0E4907978F090797B40 +:1011F000E0907979F04401F054FDF090797BF0A211 +:10120000AFE433F512C2AF120BA29079787402F0FA +:10121000907984E0907979F090797FE0B401099039 +:101220007979E054FEF08007907979E04401F090FC +:101230007979E054FDF054FBF0907984F0120BA220 +:10124000907982740CF09079887401F0E512600254 +:10125000D2AF90792DE0640260028156907FF2F067 +:10126000907FF37494F0907FFF74FCF0E4907978B1 +:10127000F090797BE0907979F04401F054FDF090A2 +:10128000797BF0A2AFE433F512C2AF120BA29079D2 +:10129000787402F0907984E0907979F090797FE029 +:1012A000B40109907979E054FEF08007907979E0F3 +:1012B0004401F0907979E04402F054FBF090798495 +:1012C000F0120BA2907982740CF09079887401F07E +:1012D000E51270028156D2AF2290792DE064017040 +:1012E00077907FF2F0907FF374CCF0907FFF74FCE6 +:1012F000F0E4907978F090797BE0907979F054FC83 +:10130000F090797BF0A2AFE433F512C2AF120BA2DA +:101310009079787402F0907984E0907979F09079FE +:101320007FE0B40109907979E054FEF0800790796C +:1013300079E04401F0907979E054FDF054FBF090AD +:101340007984F0120BA29079827412F090798874EB +:1013500002F0E5126002D2AF90792DE0640270775E +:10136000907FF2F0907FF374E0F0907FFF74FCF0D8 +:10137000E4907978F090797BE0907979F054FCF002 +:1013800090797BF0A2AFE433F512C2AF120BA290BA +:1013900079787402F0907984E0907979F090797F8F +:1013A000E0B40109907979E054FEF08007907979F2 +:1013B000E04401F0907979E04402F054FBF0907938 +:1013C00084F0120BA29079827412F09079887402E2 +:1013D000F0E5126002D2AF90792DE064037077904F +:1013E0007FF2F0907FF37494F0907FFF74FCF0E450 +:1013F000907978F090797BE0907979F054FEF04420 +:1014000002F090797BF0A2AFE433F512C2AF120B79 +:10141000A29079787402F0907984E0907979F090D4 +:10142000797FE0B40109907979E054FEF08007906B +:101430007979E04401F0907979E04404F09079847E +:10144000F0120BA29079827406F09079887404F0FF +:07145000E5126002D2AF2299 +:10145700C228C229907FE8E0120E1A14840014E013 +:101467000114F602167C2116BE2215918015D18132 +:10147700162E8216CFA11705A20000170A907FE942 +:10148700E014601124FE602824FE603B24FC7040B9 +:10149700124A2AE116124BE04002E116907FEAE079 +:1014A700B40104C22AE116907FB4E04401F0E116CA +:1014B700124BE2907FEAE0B40104D22AE116907F52 +:1014C700B4E04401F0E116907FB4E04401F0E11686 +:1014D700907FB4E04401F0E116907FE9E024F570D5 +:1014E7000512479CE116907FB4E04401F0E11690A5 +:1014F7007FE9E024FD605424026002A188124BE0DA +:101507004002E116907FEAE07038907FECE0F454F7 +:1015170080FFC4540FFFE054072F25E024B4F58261 +:10152700E4347FF583E4F0907FECE05480FF1313FD +:1015370013541FFFE054072F907FD7F0E04420F0AB +:10154700E116907FB4E04401F0E116124BE240024D +:10155700E116907FEAE07020907FECE0F45480FF82 +:10156700C4540FFFE054072F25E024B4F582E43478 +:101577007FF5837401F0E116907FB4E04401F0E158 +:1015870016907FB4E04401F0E116907FE9E0601225 +:1015970024F860092402702912171EE116124BA0C5 +:1015A700E116124BDEA22AE433FF25E0FFA22BE46B +:1015B700334F907F00F0E4A3F0907FB57402F0E121 +:1015C70016907FB4E04401F0E116907FE9E06037C0 +:1015D70024F6602E24047041907FEBE024DE600E39 +:1015E700047016D229907FB4E04401F0E116D229A5 +:1015F700907FB4E04401F0E116907FB4E04401F03D +:10160700E116124463E116124BDEE4907F00F0A36B +:10161700F0907FB57402F0E116202907907FB4E0BF +:101627004401F0C229E116907FE9E024F4603424F4 +:101637000C7039124BDE907FECE0F45480FFC454F9 +:101647000FFFE054072F25E024B4F582E4347FF53B +:1016570083E054FD907F00F0E4A3F0907FB574021F +:10166700F0E116907FB4E04401F0E116907FB4E01A +:101677004401F0E116907FE9E024F6601214601A45 +:101687002402701DD228907FB4E04401F08012D26A +:1016970028907FB4E04401F08007907FB4E04401D4 +:1016A700F020280F9079857401F012496F907FC55B +:1016B7007402F0C22880589079867401F012496F3D +:1016C700907FC57402F08047907FE9E024FE6012A6 +:1016D70014601A2402701DD228907FB4E04401F0F0 +:1016E7008012D228907FB4E04401F08007907FB445 +:1016F700E04401F0202803121A7BC2288011122C23 +:101707002B800C124BE45007907FB4E04401F0901B +:071717007FB4E04402F02260 +:10171E00124BDC4002E1E3907FEBE024FE601E14EE +:10172E00604614606E147002E1D424046002E1DCA1 +:10173E007405907FD4F07400907FD5F022907FEAEC +:10174E00E0FF123FA28B338A348935EA496011CE0D +:10175E00EACEEE907FD4F0CFE9CFEF907FD5F02296 +:10176E00907FB4E04401F022907FEAE0FF1248003F +:10177E008B338A348935EA496011CEEACEEE907FFA +:10178E00D4F0CFE9CFEF907FD5F022907FB4E04434 +:10179E0001F022907FEAE0FF907EC0E0FDA3E0FB27 +:1017AE001244D28B338A348935EA496011CEEACE9F +:1017BE00EE907FD4F0CFE9CFEF907FD5F022907FDF +:1017CE00B4E04401F022907FB4E04401F022907F17 +:0517DE00B4E04401F03D +:0117E30022E3 +:1017E400C0E0C083C082907FC4E4F05391EF907F47 +:0B17F400AB7404F0D082D083D0E03250 +:0117FF0022C7 +:10180000E4907815F07B0190781204F0A37478F0DE +:10181000A37458F0907812E0FBA3E0FAA3E0F990EB +:101820000001120C5DFF90799AE06F6018907815B6 +:10183000E0C39406500FE004F0907813E475F00FC5 +:10184000120CF480CF907815E0B40608907FB4E0D5 +:101850004401F022907812E0FBA3E0FAA3E0F91231 +:101860000C44FF24BF7002417A24E07002414C24F2 +:101870002160024173907997E024FE7002219A144E +:10188000700221EF24026002414490792DE0A3F020 +:10189000907923E0FFE4FCFDFEFBFA7901F8120DDC +:1018A00042C8ECC8C9EDC9CAEECACBEFCB907922C9 +:1018B000E0FEE4FCFD2BFBEA3EFAED39F9EC38F8EA +:1018C000907921E0FFE4FEEB2FFFEE3AFEED39FDCB +:1018D000EC38FC907812E0FBA3E0FAA3E0F990006A +:1018E00002120DD2900002120DA27B447AAC790054 +:1018F0007800C3120D91700590792D04F090781244 +:10190000E0FBA3E0FAA3E0F9900002120DA27B80B5 +:101910007ABB79007800C3120D91700690792D740E +:1019200002F0907812E0FBA3E0FAA3E0F990000245 +:10193000120DA27B007A7779017800C3120D9170A5 +:101940000690792D7403F090792DE0FFB4010975AC +:101950000C67750D06750E0BEFB40208E4F50CF577 +:101960000D750E0CEFB40308E4F50CF50D750E18AB +:10197000EFB4030D90792EE064036005D22F123D81 +:101980007990792DE06403600AA3E0B40305C22FC7 +:10199000123D7912100012280122907923E0FFE411 +:1019A000FCFDFEFBFA7901F8120D42C8ECC8C9ED46 +:1019B000C9CAEECACBEFCB907922E0FEE4FCFD2B46 +:1019C000FBEA3EFAED39F9EC38F8907921E0FFE4D2 +:1019D000FEEB2FFFEE3AFEED39FDEC38FC9078126D +:1019E000E0FBA3E0FAA3E0F9900006120DD22290EA +:1019F0007923E0FFE4FCFDFEFBFA7901F8120D42C9 +:101A0000C8ECC8C9EDC9CAEECACBEFCB907922E0C9 +:101A1000FEE4FCFD2BFBEA3EFAED39F9EC38F890D8 +:101A20007921E0FFE4FEEB2FFFEE3AFEED39FDEC0D +:101A300038FC907812E0FBA3E0FAA3E0F990000AEA +:101A4000120DD222907FB4E04401F022907997E009 +:101A5000147018907921E0FF907812E0FBA3E0FA6F +:101A6000A3E0F990000EEF120C9C22907FB4E044AA +:0A1A700001F022907FB4E04401F081 +:011A7A002249 +:101A7B00E4FFFE7B0190780F04F0A37478F0A3745D +:101A8B002BF090780FE0FBA3E0FAA3E0F9900002B3 +:101A9B00120C5DFD907FECE06D6013EFC39405506D +:101AAB000D0F907810E475F003120CF480D48D3385 +:101ABB0090780FE0FBA3E0FAA3E0F9900001120C81 +:101ACB005DFD907FEDE06D6013EEC3940B500D0E3A +:101ADB00907810E475F003120CF480D4907FEDE055 +:101AEB00F534EF64056003BE0B08907FB4E044014E +:101AFB00F02290780FE0FBA3E0FAA3E0F9120C447C +:101B0B00FF24F06008240F700E12492A22124B8317 +:0E1B1B00907920E534F022907FB4E04401F090 +:011B29002299 +:0F1B2A00907FEAE0B4FF04123416221238002232 +:071B39005398FE5398FD32A2 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:0E1EB000000000000000000000000000000024 +:101EBE000000000000000000000000000000000014 +:101ECE000000000000000000000000000000000004 +:101EDE0000000000000000000000000000000000F4 +:101EEE0000000000000000000000000000000000E4 +:101EFE0000000000000000000000000000000000D4 +:101F0E0000000000000000000000000000000000C3 +:101F1E0000000000000000000000000000000000B3 +:101F2E0000000000000000000000000000000000A3 +:021F3E000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:1020000000000000000000000000000000000000D0 +:1020100000000000000000000000000000000000C0 +:1020200000000000000000000000000000000000B0 +:1020300000000000000000000000000000000000A0 +:102040000000000000000000000000000000000090 +:102050000000000000000000000000000000000080 +:102060000000000000000000000000000000000070 +:102070000000000000000000000000000000000060 +:102080000000000000000000000000000000000050 +:102090000000000000000000000000000000000040 +:1020A0000000000000000000000000000000000030 +:1020B0000000000000000000000000000000000020 +:1020C0000000000000000000000000000000000010 +:1020D0000000000000000000000000000000000000 +:1020E00000000000000000000000000000000000F0 +:1020F00000000000000000000000000000000000E0 +:1021000000000000000000000000000000000000CF +:1021100000000000000000000000000000000000BF +:1021200000000000000000000000000000000000AF +:10213000000000000000000000000000000000009F +:10214000000000000000000000000000000000008F +:10215000000000000000000000000000000000007F +:10216000000000000000000000000000000000006F +:10217000000000000000000000000000000000005F +:10218000000000000000000000000000000000004F +:10219000000000000000000000000000000000003F +:1021A000000000000000000000000000000000002F +:1021B000000000000000000000000000000000001F +:1021C000000000000000000000000000000000000F +:1021D00000000000000000000000000000000000FF +:1021E00000000000000000000000000000000000EF +:1021F00000000000000000000000000000000000DF +:1022000000000000000000000000000000000000CE +:1022100000000000000000000000000000000000BE +:1022200000000000000000000000000000000000AE +:10223000000000000000000000000000000000009E +:10224000000000000000000000000000000000008E +:10225000000000000000000000000000000000007E +:10226000000000000000000000000000000000006E +:10227000000000000000000000000000000000005E +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000000000000000DE +:1023000000000000000000000000000000000000CD +:1023100000000000000000000000000000000000BD +:1023200000000000000000000000000000000000AD +:10233000000000000000000000000000000000009D +:10234000000000000000000000000000000000008D +:10235000000000000000000000000000000000007D +:10236000000000000000000000000000000000006D +:0E23700000000000000000000000000000005F +:10237E00000000000000000000000000000000004F +:10238E00000000000000000000000000000000003F +:10239E00000000000000000000000000000000002F +:1023AE00000000000000000000000000000000001F +:1023BE00000000000000000000000000000000000F +:1023CE0000000000000000000000000000000000FF +:1023DE0000000000000000000000000000000000EF +:1023EE0000000000000000000000000000000000DF +:1023FE0000000000000000000000000000000000CF +:10240E0000000000000000000000000000000000BE +:10241E0000000000000000000000000000000000AE +:10242E00000000000000000000000000000000009E +:10243E00000000000000000000000000000000008E +:10244E00000000000000000000000000000000007E +:10245E00000000000000000000000000000000006E +:10246E00000000000000000000000000000000005E +:10247E00000000000000000000000000000000004E +:10248E00000000000000000000000000000000003E +:10249E00000000000000000000000000000000002E +:1024AE00000000000000000000000000000000001E +:1024BE00000000000000000000000000000000000E +:1024CE0000000000000000000000000000000000FE +:1024DE0000000000000000000000000000000000EE +:1024EE0000000000000000000000000000000000DE +:1024FE0000000000000000000000000000000000CE +:10250E0000000000000000000000000000000000BD +:10251E0000000000000000000000000000000000AD +:10252E00000000000000000000000000000000009D +:10253E00000000000000000000000000000000008D +:10254E00000000000000000000000000000000007D +:10255E00000000000000000000000000000000006D +:10256E00000000000000000000000000000000005D +:10257E00000000000000000000000000000000004D +:10258E00000000000000000000000000000000003D +:10259E00000000000000000000000000000000002D +:1025AE00000000000000000000000000000000001D +:1025BE00000000000000000000000000000000000D +:1025CE0000000000000000000000000000000000FD +:1025DE0000000000000000000000000000000000ED +:1025EE0000000000000000000000000000000000DD +:1025FE0000000000000000000000000000000000CD +:10260E0000000000000000000000000000000000BC +:10261E0000000000000000000000000000000000AC +:10262E00000000000000000000000000000000009C +:10263E00000000000000000000000000000000008C +:10264E00000000000000000000000000000000007C +:10265E00000000000000000000000000000000006C +:10266E00000000000000000000000000000000005C +:10267E00000000000000000000000000000000004C +:10268E00000000000000000000000000000000003C +:10269E00000000000000000000000000000000002C +:1026AE00000000000000000000000000000000001C +:1026BE00000000000000000000000000000000000C +:1026CE0000000000000000000000000000000000FC +:1026DE0000000000000000000000000000000000EC +:0E26EE000000000000000000000000000000DE +:1026FC0000000000000000000000000000000000CE +:10270C0000000000000000000000000000000000BD +:10271C0000000000000000000000000000000000AD +:10272C00000000000000000000000000000000009D +:10273C00000000000000000000000000000000008D +:10274C00000000000000000000000000000000007D +:10275C00000000000000000000000000000000006D +:10276C00000000000000000000000000000000005D +:10277C00000000000000000000000000000000004D +:10278C00000000000000000000000000000000003D +:10279C00000000000000000000000000000000002D +:1027AC00000000000000000000000000000000001D +:1027BC00000000000000000000000000000000000D +:1027CC0000000000000000000000000000000000FD +:1027DC0000000000000000000000000000000000ED +:1027EC0000000000000000000000000000000000DD +:0527FC000000000022B6 +:10280100907964E0146046147002413C2402600235 +:10281100812A907FFC74CCF0907FFF74FCF090795A +:10282100787401F090797CE0907979F054FDF0446E +:1028310001F090797CF0A2AFE433F512C2AF120B34 +:10284100A2E5126002D2AFE490797AF02290792D5C +:10285100E06401600201F1907FFC74CCF0907FFF95 +:1028610074FCF09079787401F090797CE09079793A +:10287100F04401F04402F090797EE0B401099079CE +:1028810079E04404F08007907979E054FBF0907985 +:1028910079E090797CF0A2AFE433F512C2AF120B6C +:1028A100A29079787402F0907984E0907979F0902F +:1028B100797FE0B40109907979E054FEF0800790C6 +:1028C1007979E04401F0907979E054FDF054FBF01E +:1028D100907984F0120BA290797A7401F090796565 +:1028E100F0E5126002D2AFE490798CF090798BF030 +:1028F10090792DE0640260022196907FFC74C8F00B +:10290100907FFF74FCF09079787401F090797CE00D +:10291100907979F04401F04402F090797EE0B401BD +:1029210009907979E04404F08007907979E054FBCB +:10293100F0907979E090797CF0A2AFE433F512C29E +:10294100AF120BA29079787402F0907984E09079BB +:1029510079F090797FE0B40109907979E054FEF043 +:102961008007907979E04401F0907979E04402F0B0 +:1029710054FBF0907984F0120BA290797A7401F0F3 +:102981009079657403F0E5126002D2AFE490798C1E +:10299100F090798BF090792DE064036002812A90A8 +:1029A1007FFC7498F0907FFF74FCF090797874014B +:1029B100F090797CE0907979F04401F04402F09054 +:1029C100797EE0B40109907979E04404F0800790C0 +:1029D1007979E054FBF0907979E090797CF0A2AFBD +:1029E100E433F512C2AF120BA29079787402F09021 +:1029F1007984E0907979F090797FE0B40109907958 +:102A010079E054FEF08007907979E04401F0907903 +:102A110079E054FDF04404F0907984F0120BA29017 +:102A2100797A7401F09079657405F0E5126002D24B +:102A3100AFE490798CF090798BF02290792DE0645D +:102A410001600241E0907FFC74B4F0907FFF74FC60 +:102A5100F09079787401F090797CE0907979F05474 +:102A6100FEF04402F090797EE0B40109907979E0BA +:102A71004404F08007907979E054FBF0907979E093 +:102A810090797CF0A2AFE433F512C2AF120BA290A1 +:102A910079787402F0907984E0907979F090797F77 +:102AA100E0B40109907979E054FEF08007907979DA +:102AB100E04401F0907979E054FDF054FBF0907915 +:102AC10084F0120BA290797A7401F090796504F088 +:102AD100E5126002D2AFE490798CF090798BF0909E +:102AE100792DE0640260026185907FFC74B0F09002 +:102AF1007FFF74FCF09079787401F090797CE0901C +:102B01007979F054FEF04402F090797EE0B4010945 +:102B1100907979E04404F08007907979E054FBF0F2 +:102B2100907979E090797CF0A2AFE433F512C2AFED +:102B3100120BA29079787402F0907984E0907979FF +:102B4100F090797FE0B40109907979E054FEF0804A +:102B510007907979E04401F0907979E04402F054EA +:102B6100FBF0907984F0120BA290797A7401F090C5 +:102B710079657404F0E5126002D2AFE490798CF0CB +:102B810090798BF090792DE064036002812A907F27 +:102B9100FC7468F0907FFF74FCF09079787401F018 +:102BA10090797CE0907979F054FEF04402F09079CC +:102BB1007EE0B40109907979E04404F080079079CE +:102BC10079E054FBF0907979E090797CF0A2AFE460 +:102BD10033F512C2AF120BA29079787402F090799A +:102BE10084E0907979F090797FE0B4010990797966 +:102BF100E054FEF08007907979E04401F090797912 +:102C0100E054FDF04404F0907984F0120BA2907925 +:102C11007A7401F09079657406F0E5126002D2AF22 +:0A2C2100E490798CF090798BF0229A +:102C2B00E4FF7B0190781604F0A37478F0A374583A +:102C3B00F0907816E0FBA3E0FAA3E0F99000011204 +:102C4B000C5DFE907FECE06E6013EFC39406500DAD +:102C5B000F907817E475F00F120CF480D4BF0608B0 +:102C6B00907FB4E04401F022907816E0FBA3E0FAE9 +:102C7B00A3E0F9120C44FF249F7002C1662421606B +:102C8B0002C18C907FE9E0247E7002A130147002A7 +:102C9B00A1C824026002C15E900002120DA27B4407 +:102CAB007AAC79007800C3120D917013907F007489 +:102CBB0044F0A374ACF0E4A3F0907FB57403F090F0 +:102CCB007816E0FBA3E0FAA3E0F9900002120DA244 +:102CDB007B807ABB79007800C3120D917013907FC3 +:102CEB00007480F0A374BBF0E4A3F0907FB5740381 +:102CFB00F0907816E0FBA3E0FAA3E0F99000021243 +:102D0B000DA27B007A7779017800C3120D916002D6 +:102D1B00C193907F00F0A37477F0A37401F0907FC0 +:102D2B00B57403F022907816E0FBA3E0FAA3E0F968 +:102D3B00900006120DA27B447AAC79007800C31286 +:102D4B000D917013907F007444F0A374ACF0E4A366 +:102D5B00F0907FB57403F0907816E0FBA3E0FAA334 +:102D6B00E0F9900006120DA27B807ABB7900780007 +:102D7B00C3120D917013907F007480F0A374BBF09D +:102D8B00E4A3F0907FB57403F0907816E0FBA3E01A +:102D9B00FAA3E0F9900006120DA27B007A77790175 +:102DAB007800C3120D916002C193907F00F0A37461 +:102DBB0077F0A37401F0907FB57403F0229078162E +:102DCB00E0FBA3E0FAA3E0F990000A120DA27B440A +:102DDB007AAC79007800C3120D917013907F007458 +:102DEB0044F0A374ACF0E4A3F0907FB57403F090BF +:102DFB007816E0FBA3E0FAA3E0F990000A120DA20B +:102E0B007B807ABB79007800C3120D917013907F91 +:102E1B00007480F0A374BBF0E4A3F0907FB574034F +:102E2B00F0907816E0FBA3E0FAA3E0F990000A1209 +:102E3B000DA27B007A7779017800C3120D9170484F +:102E4B00907F00F0A37477F0A37401F0907FB574BA +:102E5B0003F022907FB4E04401F022907FE9E0245C +:102E6B007F7016907816E0FBA3E0FAA3E0F99000D0 +:102E7B000E120C5D907F00F022907FB4E04401F0C5 +:082E8B0022907FB4E04401F045 +:012E9300221C +:102E9400753625753724907974E064017054F0F523 +:102EA40035752201E52264017048907FA5E04480D5 +:102EB400F0907FA6E536F01246C0744F2535F582B2 +:102EC400E43479F583E0907FA6F01246C07435258A +:102ED40035F582E43479F583E0907FA6F01246C09C +:102EE400907FA57440F0120ACD0535E535C3940DE5 +:102EF40040B2907975E064016002E1DEF0907920DF +:102F0400E064056002E18D7B0190795C04F0A374B8 +:102F140078F0A374B2F075330790795CE0FBA3E01A +:102F2400FAA3E0F9900001120C5D700F90000412F6 +:102F34000C5D90792FF0120C29800690792F74FF84 +:102F4400F0E4F535752201753402E5226401703927 +:102F5400907FA5E04480F0907FA6E536F01246C04D +:102F6400AF340534907FA6EFF01246C090792FE07D +:102F7400907FA6F01246C0907FA57440F0120ACD4F +:102F84000535E535C3940640C1907920E0640670A8 +:102F9400497B0190795F04F0A37478F0A374FFF087 +:102FA40075330390795FE0FBA3E0FAA3E0F99000A6 +:102FB40001120C5D701C900004120C5D907933F0CA +:102FC400700374FFF0907933E0547FFFF025E0F054 +:0A2FD4008005E4907933F01247DF26 +:012FDE0022D0 +:102FDF009079787403F0907983E0907979F0A2AFCB +:102FEF00E433F512C2AF120BA2E5126002D2AF2288 +:012FFF0022AF +:10300000E4FE907920E0FDB405119078257401F07C +:10301000A37478F0A374B2F0753507EDB40611907F +:1030200078257401F0A37478F0A374FFF07535036C +:10303000907FEBE014601114605B24026002410594 +:10304000907FB4E04401F022907FE9E0247F703D5E +:10305000E4FFEFC39535502F907825E0FBA3E0FA0D +:10306000A3E0F9900001120C5DFDCCEECC0E7400D3 +:103070002CF582E4347FF583EDF0907826E475F04A +:103080000B120CF40F80CB907FB5EEF022907FB442 +:10309000E04401F022907FE9E0247E606414700235 +:1030A000215514700221A92403600221FDE4FFEFE1 +:1030B000C395355046907825E0FBA3E0FAA3E0F9EC +:1030C000900003120C5DFDCCEECC0E74002CF5824A +:1030D000E4347FF583EDF0900004120C5DFDCCEE3E +:1030E000CC0E74002CF582E4347FF583EDF09078FB +:1030F00026E475F00B120CF40F80B4907FB5EEF05F +:1031000022E4FFEFC395355046907825E0FBA3E01D +:10311000FAA3E0F9900005120C5DFDCCEECC0E7424 +:10312000002CF582E4347FF583EDF0900006120C5C +:103130005DFDCCEECC0E74002CF582E4347FF5837B +:10314000EDF0907826E475F00B120CF40F80B4903B +:103150007FB5EEF022E4FFEFC39535504690782519 +:10316000E0FBA3E0FAA3E0F9900007120C5DFDCCB0 +:10317000EECC0E74002CF582E4347FF583EDF090F4 +:103180000008120C5DFDCCEECC0E74002CF582E430 +:10319000347FF583EDF0907826E475F00B120CF493 +:1031A0000F80B4907FB5EEF022E4FFEFC395355069 +:1031B00046907825E0FBA3E0FAA3E0F9900009121D +:1031C0000C5DFDCCEECC0E74002CF582E4347FF562 +:1031D00083EDF090000A120C5DFDCCEECC0E740075 +:1031E0002CF582E4347FF583EDF0907826E475F0D9 +:1031F0000B120CF40F80B4907FB5EEF022907FB4E8 +:0C320000E04401F022907FB4E04401F0B3 +:01320C00229F +:10320D007B017A78792B907800EBF0A3EAF0A3E9B3 +:10321D00F07401120C8A907800E0FBA3E0FAA3E0B1 +:10322D00F99000017401120C9C900002E4120C9CA8 +:10323D00907801E475F003120CF4907800E0FBA394 +:10324D00E0FAA3E0F97410120C8A907800E0FBA369 +:10325D00E0FAA3E0F99000017405120C9C900002B5 +:10326D00E4120C9C907801E475F003120CF4907844 +:10327D0000E0FBA3E0FAA3E0F97402120C8A907847 +:10328D0000E0FBA3E0FAA3E0F99000017402120C38 +:10329D009C900002E4120C9C907801E475F00312EE +:1032AD000CF4907800E0FBA3E0FAA3E0F9740112AE +:1032BD000C8A907800E0FBA3E0FAA3E0F9900001FE +:1032CD007403120C9C900002E4120C9C907801E4A3 +:1032DD0075F003120CF4907800E0FBA3E0FAA3E084 +:1032ED00F97410120C8A907800E0FBA3E0FAA3E0C9 +:1032FD00F99000017406120C9C900002E4120C9CD3 +:10330D00907801E475F003120CF4907800E0FBA3C3 +:10331D00E0FAA3E0F97402120C8A907800E0FBA3A6 +:10332D00E0FAA3E0F99000017404120C9C900002E5 +:10333D00E4120C9C907801E475F003120CF4907873 +:10334D0000E0FBA3E0FAA3E0F97402120C8A907876 +:10335D0000E0FBA3E0FAA3E0F99000017404120C65 +:10336D009C9000027404120C9C907801E475F0039B +:10337D00120CF4907800E0FBA3E0FAA3E0F97402DC +:10338D00120C8A907800E0FBA3E0FAA3E0F990001C +:10339D00017403120C9C9000027404120C9C907822 +:1033AD0001E475F003120CF4907800E0FBA3E0FA51 +:1033BD00A3E0F97402120C8A907800E0FBA3E0FA06 +:1033CD00A3E0F99000017402120C9C9000027404A9 +:1033DD00120C9C907801E475F003120CF4907800B7 +:1033ED00E0FBA3E0FAA3E0F97402120C8A907800D6 +:1033FD00E0FBA3E0FAA3E0F99000017401120C9C2C +:08340D009000027404120C9CF3 +:013415002294 +:10341600E4FE907920E0FDB4051190781F7401F068 +:10342600A37478F0A374B2F0753507EDB406119065 +:10343600781F7401F0A37478F0A374FFF075350358 +:10344600907999E014601114605B24026002C10651 +:10345600907FB4E04401F022907997E014703EE446 +:10346600FFEFC39535502FCDEECD0E74212DF5828D +:10347600E43479F583E0FD90781FE0FBA3E0FAA33E +:10348600E0F9900001ED120C9C907820E475F00BA9 +:10349600120CF40F80CB9079757401F022907FB4F2 +:1034A600E04401F022907997E024FE6063147002F4 +:1034B600A164147002A1B224036002A1FEE4FFEF2E +:1034C600C395355044CDEECD0E74212DF582E434EE +:1034D60079F583E0FD90781FE0FBA3E0FAA3E0F91D +:1034E600900003ED120C9CCDEECD0E74212DF582CD +:1034F600E43479F583E0900004120C9C907820E483 +:1035060075F00B120CF40F80B69079757401F022E9 +:10351600E4FFEFC395354002C10DCDEECD0E74210B +:103526002DF582E43479F583E0FD90781FE0FBA366 +:10353600E0FAA3E0F9900005ED120C9CCDEECD0E5D +:1035460074212DF582E43479F583E0900006120C9F +:103556009C907820E475F00B120CF40F80B4E4FF15 +:10356600EFC395354002C10DCDEECD0E74212DF57C +:1035760082E43479F583E0FD90781FE0FBA3E0FA5E +:10358600A3E0F9900007ED120C9CCDEECD0E742150 +:103596002DF582E43479F583E0900008120C9C90B6 +:1035A6007820E475F00B120CF40F80B4E4FFEFC33F +:1035B60095355053CDEECD0E74212DF582E4347938 +:1035C600F583E0FD90781FE0FBA3E0FAA3E0F99015 +:1035D6000009ED120C9CCDEECD0E74212DF582E482 +:1035E6003479F583E090000A120C9C907820E475FB +:1035F600F00B120CF40F80B6907FB4E04401F02279 +:07360600907FB4E04401F0E5 +:01360D00229A +:10360E00E4FE907920E0FDB405109078287401F066 +:10361E00A37478F0A374B2F07F07EDB4061090781F +:10362E00287401F0A37478F0A374FFF07F039078F0 +:10363E0028E0FBA3E0FAA3E0F9120C44FD907FEA28 +:10364E00E06D6012EEC39F500D907829E475F00B7B +:10365E00120CF40E80D8907FEBE0146011146046CB +:10366E0024026002E19A907FB4E04401F022907F40 +:10367E00E9E0247F7028EE6F7008907FB4E044017B +:10368E00F022907828E0FBA3E0FAA3E0F990000185 +:10369E00120C5D907F00F0907FB57401F022907F48 +:1036AE00B4E04401F022907FE9E0247E6040146093 +:1036BE006F147002E16024036002E192EE6F7008F5 +:1036CE00907FB4E04401F022907828E0FBA3E0FA6A +:1036DE00A3E0F9900003120C5D907F00F0900004BF +:1036EE00120C5D907F01F0907FB57402F022EE6FA8 +:1036FE007008907FB4E04401F022907828E0FBA39C +:10370E00E0FAA3E0F9900005120C5D907F00F090B6 +:10371E000006120C5D907F01F0907FB57402F022CE +:10372E00EE6F7008907FB4E04401F022907828E0AC +:10373E00FBA3E0FAA3E0F9900007120C5D907F0066 +:10374E00F0900008120C5D907F01F0907FB574022E +:10375E00F022EE6F7008907FB4E04401F022907872 +:10376E0028E0FBA3E0FAA3E0F9900009120C5D90AB +:10377E007F00F090000A120C5D907F01F0907FB5F3 +:10378E007402F022907FB4E04401F022907FB4E006 +:03379E004401F0F3 +:0137A1002205 +:1037A200C0E0C0F0C083C082C0D0E8C0E0E9C0E0A1 +:1037B200EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EF5C +:1037C200C0E05391EF907FAB7410F0907983E05496 +:1037D200FDF0122FDFD0E0FFD0E0FED0E0FDD0E020 +:1037E200FCD0E0FBD0E0FAD0E0F9D0E0F8D0D0D0C5 +:0837F20082D083D0F0D0E03258 +:0637FA005391BFD22632FC +:10380000E4FE907920E0FDB405109078227401F078 +:10381000A37478F0A374B2F07F07EDB4061090782B +:10382000227401F0A37478F0A374FFF07F03907802 +:1038300022E0FBA3E0FAA3E0F9120C44FD90799892 +:10384000E06D6012EEC39F500D907823E475F00B8D +:10385000120CF40E80D8907999E01460111460482D +:10386000240260022185907FB4E04401F022907927 +:1038700097E014702BEE6F7009907FB4E04401F074 +:103880008017907921E0FD907822E0FBA3E0FAA375 +:10389000E0F9900001ED120C9C9079757401F02212 +:1038A000907FB4E04401F022907997E024FE6043D9 +:1038B00014606E147002214F24036002217DEE6FAC +:1038C0007009907FB4E04401F08021907921E0FDFF +:1038D000907822E0FBA3E0FAA3E0F9900003ED1258 +:1038E0000C9C907922E0900004120C9C90797574E5 +:1038F00001F022EE6F7008907FB4E04401F0229056 +:103900007921E0FD907822E0FBA3E0FAA3E0F990B2 +:103910000005ED120C9C907922E0900006120C9CA0 +:1039200022EE6F7008907FB4E04401F0229079217C +:10393000E0FD907822E0FBA3E0FAA3E0F990000715 +:10394000ED120C9C907922E0900008120C9C22EE63 +:103950006F7008907FB4E04401F022907921E0FE7E +:10396000907822E0FBA3E0FAA3E0F9900009EE12C0 +:103970000C9C907922E090000A120C9C22907FB45B +:0C398000E04401F022907FB4E04401F02C +:01398C002218 +:10398D00A2AFE433F512E4907983F0122FDF907F2C +:10399D00E07490F0907FE17404F0E4907FDDF0909E +:1039AD007FA1F0538EF875880575B82075F8014321 +:1039BD008E30F5C875CA7F75CBF843A82090797401 +:1039CD0004F0C222E4F50F907978F0A3F0907962BB +:1039DD00F0A3F0A3F0907966F0A3F090797BF0A3BB +:1039ED00F0907984F090797DF0907975F0A3F0A343 +:1039FD00F0C223C224C225C226C220907F9BE0F5CF +:103A0D000A5420F50A700690797EF0800690797E32 +:103A1D007401F0907F9BE0F50A5402F50A70069050 +:103A2D00797FF0800690797F7401F0907978740237 +:103A3D00F0907984E0907979F090797FE0B4010984 +:103A4D00907979E054FEF08007907979E04401F0A7 +:103A5D00907979E0907984F0120BA29079787401C5 +:103A6D00F090797CE0907979F090797EE0B401095D +:103A7D00907979E04404F08007907979E054FBF077 +:103A8D00907979E090797CF0120BA2E4907978F03E +:103A9D00A304F0E4907988F0120BA2907FFC74DD02 +:103AAD00F0907FFF74FFF09079787401F0A3F0121D +:103ABD000BA2E490797AF090798304F0122FDFE471 +:103ACD00907930F0907985F0A3F0A3F0122E9490B8 +:103ADD00792D7402F090798814F0C22FE4907968F2 +:103AED00F090798AF090796AF0A3F0751308751447 +:103AFD0008F516F515F51790798CF090798BF02265 +:103B0D007B017A787958907803EBF0A3EAF0A3E97A +:103B1D00F07440120C8A907803E0FBA3E0FAA3E066 +:103B2D00F9900001740A120C9C900002120DF6001F +:103B3D0000BB80900006120DF60000AC4490000A08 +:103B4D00120DF600017700907804E475F00F120C59 +:103B5D00F4907803E0FBA3E0FAA3E0F97440120CB3 +:103B6D008A907803E0FBA3E0FAA3E0F990000174DA +:103B7D008C120C9C900002120DF60000BB80900080 +:103B8D0006120DF60000AC4490000A120DF600016D +:103B9D007700907804E475F00F120CF4907803E040 +:103BAD00FBA3E0FAA3E0F97440120C8A907803E0CD +:103BBD00FBA3E0FAA3E0F9900001748F120C9C9026 +:103BCD007804E475F00F120CF4907803E0FBA3E099 +:103BDD00FAA3E0F97441120C8A907803E0FBA3E09C +:103BED00FAA3E0F99000017484120C9C907804E41F +:103BFD0075F00F120CF4907803E0FBA3E0FAA3E04C +:103C0D00F97461120C8A907803E0FBA3E0FAA3E04B +:103C1D00F99000017481120C9C907804E475F00FFA +:103C2D00120CF4907803E0FBA3E0FAA3E0F97461C1 +:103C3D00120C8A907803E0FBA3E0FAA3E0F9900060 +:063C4D00017401120C9C41 +:013C5300224E +:103C5400C0E0C0F0C083C082C0D0E8C0E0E9C0E0EA +:103C6400EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFA5 +:023C7400C0E0AE +:103C7600907FA2E0F50B907F74E0907970F0907FD2 +:103C860075E0907971F0907983E0FFFE5402FE7042 +:103C96000DEF4402F0122FDF9079747401F0E50BFA +:103CA60020E228907970E0FEA3E07C002400F51164 +:103CB600EC3EF510907982E0FDAE10AF11120CBE0D +:103CC600907970EFF09079897401F01248431248A8 +:103CD60076907989E064017032124108907989E41E +:103CE600F0907F98E04440F0907F9EE04440F09052 +:103CF6007F957480F075E80112093275E80D907FA2 +:103D06009574C0F075E80DD220800575E801C220D3 +:103D160020202B90792DE0FFB40109750C67750DF5 +:103D260006750E0BEFB40209750C00750D00750EC5 +:103D36000CEFB40309750C00750D00750E1875CAE5 +:103D46006F75CBFED2CA5391EF907FAB7402F0F041 +:103D5600D0E0FFD0E0FED0E0FDD0E0FCD0E0FBD02C +:103D6600E0FAD0E0F9D0E0F8D0D0D082D083D0F01D +:033D7600D0E03268 +:103D790075332575342490795C7401F0A37478F057 +:103D8900A374B2F0202F02C117E4F5357522019012 +:103D9900795CE0FBA3E0FAA3E0F9900004120C5D62 +:103DA900F53675350674422535F582E43479F5839F +:103DB900E536F00535E535B40CEBE535C3940D4032 +:103DC90002C198E52264016002C198907FA5E04490 +:103DD90080F0907FA6E533F01246C0744F2535F583 +:103DE90082E43479F583E0907FA6F01246C07442EC +:103DF9002535F582E43479F583E0907FA6F0124603 +:103E0900C0907FA57440F0120ACD053580ACE4F569 +:103E19003575220190795CE0FBA3E0FAA3E0F99003 +:103E29000004120C5DF53675350674352535F582B5 +:103E3900E43479F583E536F00535E535B40CEBE581 +:103E490035C3940D5049E52264017043907FA5E084 +:103E59004480F0907FA6E533F01246C0744F2535B3 +:103E6900F582E43479F583E0907FA6F01246C074B8 +:103E7900352535F582E43479F583E0907FA6F01293 +:0F3E890046C0907FA57440F0120ACD053580B079 +:013E98002207 +:103E99009078097401F0A37478F0A374B2F0E4FF88 +:103EA900FE907809E0FBA3E0FAA3E0F9EF120C8A8F +:103EB900907809E0FBA3E0FAA3E0F9900001E4128D +:103EC9000C9C9000027415120C9C900003E4120CD7 +:103ED9009C90000474FF120C9C900005E4120C9C49 +:103EE90090000674C3120C9C900007E4120C9C907D +:103EF9000008E4120C9C900009E4120C9C90000A42 +:103F09007401120C9C90780AE475F00B120CF40FF2 +:103F19000EBE078D9078097401F0A37478F0A3742C +:103F2900FFF0E4FFFE907809E0FBA3E0FAA3E0F9D3 +:103F3900EF120C8A907809E0FBA3E0FAA3E0F9906C +:103F49000001E4120C9C9000027415120C9C900064 +:103F590003E4120C9C9000047480120C9C900005E0 +:103F6900E4120C9C90000674C3120C9C900007E4A8 +:103F7900120C9C900008E4120C9C900009E4120CAD +:103F89009C90000A7401120C9C90780AE475F00B5D +:083F9900120CF40F0EBE038DA3 +:013FA10022FD +:103FA200E4FE753DFF753E05753F12AB3DAA3EA985 +:103FB2003F900001120C5D6402702FCDEECD0EED2C +:103FC2006F700122900002120D0A85F03BF53C62EF +:103FD2003BE53B623CE53C623B29FDE53B3AC9EDF2 +:103FE200C9753DFFF53E893F80C17B007A007900AB +:013FF20022AC +:093FF30053D8EF43D820C22D324F +:043FFC005391DF32CC +:10400000907987E0B4011D907985E0B401031242F4 +:10401000AA907986E0B40103121800E4907985F043 +:10402000A3F0A3F0122E94907F9BE0F50A5402F5C2 +:104030000A700490797FF0907F9BE0F50A5402FFAC +:10404000F50ABF020690797F7401F0907F9BE0F53E +:104050000A5420F50A700490797EF0907F9BE0F579 +:104060000A5420FFF50ABF200690797E7401F09073 +:10407000797FE0FF907981E06F6038907978740201 +:10408000F0907984E0907979F0EFB40106E054FE85 +:10409000F08007907979E04401F0907979E09079A7 +:1040A00084F0A2AFE433F512C2AF120BA2E51260A6 +:1040B00002D2AF90797EE0FF907980E06F60389017 +:1040C00079787401F090797CE0907979F0EFB4011F +:1040D00006E04404F08007907979E054FBF0907991 +:1040E00079E090797CF0A2AFE433F512C2AF120B05 +:1040F000A2E5126002D2AF90797FE0907981F090D2 +:08410000797EE0907980F02245 +:1041080090792DE064017035907970E0FFD3942D9B +:10411800402B9079697401F0907968E004F0E0D35D +:10412800940F4019E4F0EFD39431400890792D743E +:1041380003F0800690792D7402F012100090792D0A +:10414800E0B4022C907970E0FFC3942F5022EFD393 +:10415800942A401C9079697401F0907968E004F021 +:10416800E0D3940F400AE4F090792D04F012100087 +:1041780090792DE0B40226907970E0D39431401DF7 +:104188009079697401F0907968E004F0E0D3940FB5 +:10419800400BE4F090792D7403F012100090792D03 +:1041A800E06403703F907970E0FFC3945F503590EE +:1041B80079697401F0907968E004F0E0D3940F40D5 +:1041C80023E4F0EFC3942F500CEFD3942A400690C9 +:1041D800792D7401F0EFD3942F400690792D740255 +:1041E800F0121000907969E07005907968F022E487 +:0541F800907969F0223E +:1041FD007B017A78794C907806EBF0A3EAF0A3E98D +:10420D00F0E4120C8A907806E0FBA3E0FAA3E0F943 +:10421D009000017401120C9C907807E475F0031264 +:10422D000CF4907806E0FBA3E0FAA3E0F9E4120C9D +:10423D008A907806E0FBA3E0FAA3E0F99000017400 +:10424D0002120C9C907807E475F003120CF4907830 +:10425D0006E0FBA3E0FAA3E0F9E4120C8A907806DD +:10426D00E0FBA3E0FAA3E0F99000017403120C9CAB +:10427D00907807E475F003120CF4907806E0FBA338 +:10428D00E0FAA3E0F9E4120C8A907806E0FBA3E0D3 +:0C429D00FAA3E0F99000017404120C9CDC +:0142A90022F2 +:1042AA00E4FFFE7B0190780C04F0A37478F0A37409 +:1042BA002BF090780CE0FBA3E0FAA3E0F99000025F +:1042CA00120C5DFD90799AE06D6013EFC39405506E +:1042DA000D0F90780DE475F003120CF480D48D3331 +:1042EA0090780CE0FBA3E0FAA3E0F9900001120C2D +:1042FA005DFD90799BE0FC6D6013EEC3940B500D4D +:10430A000E90780DE475F003120CF480D38C34EF20 +:10431A0064056003BE0B08907FB4E04401F022906C +:10432A00780CE0FBA3E0FAA3E0F9120C44FF24F0B6 +:10433A006008240E700E12494D22907920E534F05F +:0B434A00121B2A22907FB4E04401F017 +:014355002245 +:0C435600787FE4F6D8FD75813F02439D9E +:104362000248A9E493A3F8E493A34003F68001F280 +:1043720008DFF48029E493A3F85407240CC8C3335C +:10438200C4540F4420C8834004F456800146F6DF2B +:10439200E4800B0102040810204080904661E47E14 +:1043A200019360BCA3FF543F30E509541FFEE49320 +:1043B200A360010ECF54C025E060A840B8E493A3E7 +:1043C200FAE493A3F8E493A3C8C582C8CAC583CA12 +:1043D200F0A3C8C582C8CAC583CADFE9DEE780BECA +:1043E200C0E0C0F0C083C082C0D0E8C0E0E9C0E055 +:1043F200EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EF10 +:10440200C0E0C2CAC2CF90797AE0B4011F124BAEAB +:1044120012475853A8A0907FAEE4F01207AA124B9D +:10442200B7907FAE741FF043A805800353A8A05332 +:10443200A8FA75E80112091575E80D43A805D0E040 +:10444200FFD0E0FED0E0FDD0E0FCD0E0FBD0E0FA0F +:10445200D0E0F9D0E0F8D0D0D082D083D0F0D0E054 +:014462003227 +:10446300907FECE0F50914601D14602A1460371482 +:10447300604424047050907962E0907F00F0907F54 +:10448300B57401F08047907963E0907F00F0907FEE +:10449300B57401F08037907964E0907F00F0907FED +:1044A300B57401F08027907966E0907F00F0907FEB +:1044B300B57401F08017907967E0907F00F0907FEA +:0F44C300B57401F08007907FB4E04401F0D3227C +:0444D2008D368B3761 +:1044D600123FA2EA496057120C447E0029FFEE3AC9 +:1044E600C9EFC97538FFF539893AAB38AA39A93AFF +:1044F600900001120C5DFF64046005EF6405702EE8 +:10450600EFB40415900002120C5D6536700B900036 +:1045160003120C5D6537700122120C447E0029FFE0 +:10452600EE3AC9EFC97538FFF539893A80BC7B0088 +:044536007A0079008E +:01453A00225E +:10453B00E4FF7B0190781C04F0A37478F0A3744C17 +:10454B00F090781CE0FBA3E0FAA3E0F990000212D4 +:10455B000C5DFE907FECE06E6013EFC39404500D86 +:10456B0090781DE475F003120CF40F80D4BF04098E +:10457B00907FB4E04401F08014907921E0FF9078B3 +:10458B001CE0FBA3E0FAA3E0F9EF120C8A907FC5C5 +:03459B007401F0B8 +:01459E0022FA +:0E459F00C0E0C083C082C0D0EEC0E0EFC0E03C +:1045AD00907985E064016005A3E0B4012D907987D1 +:1045BD007401F0E4FF907FC5E0FEEFC39E501B74C5 +:1045CD00C02FF582E4347EF583E0FE74212FF58251 +:1045DD00E43479F583EEF00F80DB5391EF907FAAF1 +:0445ED00E04401F0B5 +:0F45F100D0E0FFD0E0FED0D0D082D083D0E03237 +:10460000E4FF7B0190781904F0A37478F0A3744C54 +:10461000F0907819E0FBA3E0FAA3E0F99000021211 +:104620000C5DFE907FECE06E6013EFC39404500DC0 +:1046300090781AE475F003120CF40F80D4BF0408CC +:10464000907FB4E04401F022907819E0FBA3E0FAF7 +:10465000A3E0F9120C44907F00F0907FB57401F054 +:014660002237 +:1046610001180201190A011C00C128C129011F01F9 +:0F46710044799F000000004179A3004179A40023 +:0446800041798900F3 +:10468400012201417931FF417934004D79353F3FB1 +:1046940000080001000000000000154D79423F3F72 +:1046A40006080407000000000000154D794F0A0AAF +:0B46B4000900010902030405060708C5 +:0146BF0000FA +:1046C000120ACD907FA5E0F521E5215401F5216482 +:1046D000016028E52264017022907FA5E0F5215455 +:1046E00002F5217003752201907FA5E0F5215404A5 +:0C46F000FFF521BF04D375220180CE220B +:0446FC0053D8F73266 +:104700000249FA00023C54000217E400024A120077 +:104710000237A2000247FF00024A410002459F0003 +:1047200002498E000249AB00024A5800024A6F005B +:10473000024A8600024A9D00024AB400024ACB00A7 +:10474000024AE200024AF900024B1000024B270025 +:08475000024B3E00024B550034 +:10475800E518701490798CE004F090798BE0C3949C +:10476800004015E014F0801090798BE004F0A3E08D +:10477800C394004003E014F090798BE0D394144084 +:1047880004E4F518F090798CE0D39414400575187A +:0447980001E4F02226 +:10479C00907FD7E0F533907FECE0F50914601114AD +:1047AC00601B24027024907FEAE0907962F08021F3 +:1047BC00907FEAE0907963F01210008014907FEA09 +:1047CC00E0907964F01228018007907FB4E04401F6 +:0247DC00F0D318 +:0147DE0022B8 +:1047DF009079787404F0907933E0907979F0A2AF02 +:1047EF00E433F512C2AF120BA2E5126002D2AF2270 +:0147FF003287 +:024800008F36F1 +:10480200E4F5377538FF753907753A01AB38AA39BF +:10481200A93A900001120C5DB4031FAF370537EFC0 +:104822006536700122120C447E0029FFEE3AC9EF70 +:10483200C97538FFF539893A80D27B007A00790050 +:014842002253 +:1048430030262FC22690792DE0FFB40109E4F50C40 +:10485300750DF8750E0AEFB40209E4F50C750DF049 +:10486300750E0BEFB40309E4F50C750DF8750E170F +:03487300D222222C +:1048760030252FC22590792DE0FFB40109750CC0B3 +:10488600750D14750E0BEFB40209E4F50C750D10D9 +:10489600750E0CEFB40309E4F50C750D18750E18BA +:0348A600D22222F9 +:1048A900E4F532120F50202E10E532C3940250095C +:1048B9000532D23012490580ED302E05121457C247 +:0F48C9002E302D0612079A1248D912400080EAAD +:0148D80022BD +:1048D900907FD6E0F51D5480F51D6480701DC2AF30 +:1048E900E04480F0E04401F07F0C7E00124B6C90B4 +:0C48F9007FD6E054FEF05387FED2AF22C1 +:10490500907FD6E054FBF0E04408F0303004E044FA +:1049150002F07FDC7E05124B6C907FD6E054F7F0F9 +:05492500E04404F02253 +:10492A00907FEBE0147014907FE9E0247F7004120A +:10493A00460022907FB4E04401F022907FB4E04424 +:03494A0001F02257 +:10494D00907FEBE0147013907FE9E0147004124532 +:10495D003B22907FB4E04401F022907FB4E044010B +:02496D00F02236 +:10496F00E4FF74E82FF582E4347FF583E0FE74965C +:0E497F002FF582E43479F583EEF00FBF08E4E3 +:01498D002207 +:10498E00C0E0C083C0825391EF907FA9E04402F053 +:0D499E00907FB77403F0D082D083D0E03258 +:1049AB00C0E0C083C0825391EF907FAAE04402F035 +:0D49BB00907FC77403F0D082D083D0E0322B +:1049C800907FD6E030E712E04401F07F147E0012B9 +:0A49D8004B6C907FD6E054FEF022F5 +:1049E200E4F51A751B0190799104F0A3F0E4A3F0A9 +:0849F200A3740AF0E4A3F02213 +:1049FA00C0E0C083C082D22E5391EF907FAB740186 +:084A0A00F0D082D083D0E0322D +:104A1200C0E0C083C082D22D5391EF907FAB740867 +:084A2200F0D082D083D0E03215 +:104A2A00907FEAE0F508E4907962F0A3F0A3F090B1 +:074A3A007966F0A3F0D3221E +:104A4100C0E0C083C0825391EF907FA9E04401F0A0 +:074A5100D082D083D0E032D7 +:104A5800C0E0C083C0825391EF907FA9E04404F086 +:074A6800D082D083D0E032C0 +:104A6F00C0E0C083C0825391EF907FAAE04404F06E +:074A7F00D082D083D0E032A9 +:104A8600C0E0C083C0825391EF907FA9E04408F054 +:074A9600D082D083D0E03292 +:104A9D00C0E0C083C0825391EF907FAAE04408F03C +:074AAD00D082D083D0E0327B +:104AB400C0E0C083C0825391EF907FA9E04410F01E +:074AC400D082D083D0E03264 +:104ACB00C0E0C083C0825391EF907FAAE04410F006 +:074ADB00D082D083D0E0324D +:104AE200C0E0C083C0825391EF907FA9E04420F0E0 +:074AF200D082D083D0E03236 +:104AF900C0E0C083C0825391EF907FAAE04420F0C8 +:074B0900D082D083D0E0321E +:104B1000C0E0C083C0825391EF907FA9E04440F091 +:074B2000D082D083D0E03207 +:104B2700C0E0C083C0825391EF907FAAE04440F079 +:074B3700D082D083D0E032F0 +:104B3E00C0E0C083C0825391EF907FA9E04480F023 +:074B4E00D082D083D0E032D9 +:104B5500C0E0C083C0825391EF907FAAE04480F00B +:074B6500D082D083D0E032C2 +:104B6C008E338F34E5341534AE33700215334E600A +:074B7C000512078980EE22FB +:0F4B8300907FEAE0B4FF041230002212360E22B7 +:0E4B9200C0E0C28BD224302302C223D0E03216 +:0E4BA000907F00E508F0907FB57401F0D322FD +:094BAE00302405C224751801220F +:094BB700302305C223E4F51822A5 +:074BC00053C0FE53C0FD329B +:064BC70053917FD225325C +:054BCD00C289D2233271 +:034BD200C28D325F +:034BD500C28F325A +:024BD800D322E6 +:024BDA00D322E4 +:024BDC00D322E2 +:024BDE00D322E0 +:024BE000D322DE +:024BE200D322DC +:024BE400C322EA +:014BE60022AC +:00000001FF +/* + * This firmware is for the Emagic EMI 2|6 Audio Interface + * + * The firmware contained herein is Copyright (c) 1999-2002 Emagic + * as an unpublished work. This notice does not imply unrestricted + * or public access to this firmware which is a trade secret of Emagic, + * and which may not be reproduced, used, sold or transferred to + * any third party without Emagic's written consent. All Rights Reserved. + * + * This firmware may not be modified and may only be used with the + * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of + * any driver which includes this firmware, in whole or in part, + * requires the inclusion of this statement. + */ +/* +VERSION=1.0.2.916 +DATE=12.02.2002 +*/ diff --git a/firmware/emi26/loader.HEX b/firmware/emi26/loader.HEX new file mode 100644 index 0000000..77c439f --- /dev/null +++ b/firmware/emi26/loader.HEX @@ -0,0 +1,116 @@ +:0300000002031CDC +:03004300020400B4 +:10010000907FE9E0245B6060240260030201BE90FE +:100110007FEAE0750A00F50BA3E0FEE4EE420A90E8 +:100120007FEEE0751500F516A3E0FEE4EE4215E55E +:1001300016451570030201BEE4907FC5F0907FB4B0 +:10014000E020E3F9907FC5E0F50C120277AF0C7E5A +:1001500000EF250BF50BEE350AF50AC3E5169FF502 +:1001600016E5159EF51580C7907FEAE0750A00F543 +:100170000BA3E0FEE4EE420A907FEEE0751500F579 +:1001800016A3E0FEE4EE4215E51645156030E49056 +:100190007FC5F0907FB4E020E3F9907FC5E0F50CD7 +:1001A00012028FAF0C7E00EF250BF50BEE350AF532 +:0F01B0000AC3E5169FF516E5159EF51580CAC31F +:0101BF00221D +:1001C000C220D2E843D820907FAB74FFF0907FA983 +:1001D000F0907FAAF05391EF907F95E044C0F090AB +:1001E0007F98E044C0F0907F9EE044C0F0E4907FB0 +:1001F00094F0907F9DE0440FF0907F97E054F0F0F2 +:10020000907FAFE04401F0907FAEE0440DF0D2AFBC +:10021000907F97E054F0F020204275140075130091 +:100220007512007511007F487E927D007C00AB1432 +:10023000AA13A912A811C312049A50DB2020D87A5D +:100240000079007800E5142401F514EA3513F5135C +:10025000E93512F512E83511F51180CA3020FD128A +:1002600001005007907FB4E04401F0907FB4E04477 +:0602700002F0C22080E64E +:010276002265 +:10027700E50CFFE50BF582E50AF58375927E74C000 +:08028700F8E208F0A3DFFA22FF +:10028F00907F96858392A8827902900000E0B40057 +:10029F00377401F0907F93E054FCF0907F96E05418 +:1002AF00FCF0907F9CE04403F0907F94E0547FF04B +:1002BF00907F97E04480F0907F9DE04480F0907FA6 +:1002CF0097E0547FF04480F0E50CFF907EC0E0F59E +:1002DF0028E4A24733F269F2E4A24633F269F2E46A +:1002EF00A24533F269F2E4A24433F269F2E4A24385 +:1002FF0033F269F2E4A24233F269F2E4A24133F23B +:0D030F0069F2E4A24033F269F2A3DFC222DA +:0C031C00787FE4F6D8FD758129020363A8 +:100328000201C0E493A3F8E493A34003F68001F22A +:1003380008DFF48029E493A3F85407240CC8C333D6 +:10034800C4540F4420C8834004F456800146F6DFA5 +:10035800E4800B0102040810204080900484E47EAD +:10036800019360BCA3FF543F30E509541FFEE4939A +:10037800A360010ECF54C025E060A840B8E493A361 +:10038800FAE493A3F8E493A3C8C582C8CAC583CA8C +:10039800F0A3C8C582C8CAC583CADFE9DEE780BE44 +:1003A800C0E0C083C082907FC4E4F05391EF907F97 +:0B03B800AB7404F0D082D083D0E032A0 +:1003C300C0E0C083C082D2205391EF907FAB740111 +:0803D300F0D082D083D0E032AB +:1003DB00C0E0C083C0825391EF907FAB7402F0D02A +:0603EB0082D083D0E03255 +:0103F10032D9 +:0103F20032D8 +:0103F30032D7 +:0103F40032D6 +:0103F50032D5 +:0103F60032D4 +:0103F70032D3 +:0103F80032D2 +:0103F90032D1 +:0103FA0032D0 +:0103FB0032CF +:0103FC0032CE +:0103FD0032CD +:0103FE0032CC +:0103FF0032CB +:100400000203C3000203DB000203A80002046E0023 +:10041000020458000203F1000203F2000203F30099 +:100420000203F4000203F5000203F6000203F700E2 +:100430000203F8000203F9000203FA000203FB00C2 +:100440000203FC000203FD000203FE000203FF00A2 +:080450000204AB000204AC0041 +:10045800C0E0C083C0825391EF907FAB7410F0D09E +:0604680082D083D0E032D7 +:10046E00C0E0C083C0825391EF907FAB7408F0D090 +:06047E0082D083D0E032C1 +:10048400020A000F010C11040D00000000410000DD +:010494000067 +:04049500021700004A +:010499000062 +:10049A00EB9FF5F0EA9E42F0E99D42F0E89C45F0B8 +:0104AA00222F +:0104AB00321E +:0104AC00321D +:1011000012011001000000406A0801010001010203 +:10111000000109022000010103A0000904000002EF +:10112000FF0000040705820240000007050202409C +:10113000000004030904260341006E0063006800F8 +:101140006F007200200043006800690070007300A7 +:101150002C00200049006E0063002E00280346008A +:10116000690072006D007700610072006500200068 +:101170004600720061006D00650057006F0072004C +:101180006B0073002A0343006F006E006600690065 +:101190006700750072006100740069006F006E00E6 +:1011A000200053007400720069006E006700220383 +:1011B00049006E0074006500720066006100630003 +:1011C0006500200053007400720069006E00670023 +:0211D00000001D +:00000001FF +/* + * This firmware is for the Emagic EMI 2|6 Audio Interface + * + * The firmware contained herein is Copyright (c) 1999-2002 Emagic + * as an unpublished work. This notice does not imply unrestricted + * or public access to this firmware which is a trade secret of Emagic, + * and which may not be reproduced, used, sold or transferred to + * any third party without Emagic's written consent. All Rights Reserved. + * + * This firmware may not be modified and may only be used with the + * Emagic EMI 2|6 Audio Interface. Distribution and/or Modification of + * any driver which includes this firmware, in whole or in part, + * requires the inclusion of this statement. + */ -- cgit v0.10.2 From b8e24bfabb03527d1c876fcaf24cccb05e1cbc65 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 17:35:47 +0300 Subject: emi62: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 1a2b79a..20886c2 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -16,15 +16,8 @@ #include #include #include - -#define MAX_INTEL_HEX_RECORD_LENGTH 16 -typedef struct _INTEL_HEX_RECORD -{ - __u32 length; - __u32 address; - __u32 type; - __u8 data[MAX_INTEL_HEX_RECORD_LENGTH]; -} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD; +#include +#include /* include firmware (variables)*/ @@ -33,9 +26,9 @@ typedef struct _INTEL_HEX_RECORD //#undef SPDIF /* if you want MIDI uncomment this line */ #ifdef SPDIF -# include "emi62_fw_s.h" /* spdif fw */ +#define FIRMWARE_FW "emi62/spdif.fw" #else -# include "emi62_fw_m.h" /* midi fw */ +#define FIRMWARE_FW "emi62/midi.fw" #endif #define EMI62_VENDOR_ID 0x086a /* Emagic Soft-und Hardware GmBH */ @@ -48,7 +41,9 @@ typedef struct _INTEL_HEX_RECORD #define CPUCS_REG 0x7F92 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ #define INTERNAL_RAM(address) (address <= MAX_INTERNAL_ADDRESS) -static int emi62_writememory( struct usb_device *dev, int address, unsigned char *data, int length, __u8 bRequest); +static int emi62_writememory(struct usb_device *dev, int address, + const unsigned char *data, int length, + __u8 bRequest); static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi62_load_firmware (struct usb_device *dev); static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id); @@ -58,7 +53,9 @@ static void __exit emi62_exit (void); /* thanks to drivers/usb/serial/keyspan_pda.c code */ -static int emi62_writememory (struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) +static int emi62_writememory(struct usb_device *dev, int address, + const unsigned char *data, int length, + __u8 request) { int result; unsigned char *buffer = kmemdup(data, length, GFP_KERNEL); @@ -91,9 +88,12 @@ static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit) static int emi62_load_firmware (struct usb_device *dev) { + const struct firmware *loader_fw = NULL; + const struct firmware *bitstream_fw = NULL; + const struct firmware *firmware_fw = NULL; + const struct ihex_binrec *rec; int err; int i; - int pos = 0; /* Position in hex record */ __u32 addr; /* Address to write */ __u8 *buf; @@ -105,6 +105,22 @@ static int emi62_load_firmware (struct usb_device *dev) goto wraperr; } + err = request_ihex_firmware(&loader_fw, "emi62/loader.fw", &dev->dev); + if (err) + goto nofw; + + err = request_ihex_firmware(&bitstream_fw, "emi62/bitstream.fw", + &dev->dev); + if (err) + goto nofw; + + err = request_ihex_firmware(&firmware_fw, FIRMWARE_FW, &dev->dev); + if (err) { + nofw: + err( "%s - request_firmware() failed", __func__); + goto wraperr; + } + /* Assert reset (stop the CPU in the EMI) */ err = emi62_set_reset(dev,1); if (err < 0) { @@ -112,13 +128,18 @@ static int emi62_load_firmware (struct usb_device *dev) goto wraperr; } + rec = (const struct ihex_binrec *)loader_fw->data; + /* 1. We need to put the loader for the FPGA into the EZ-USB */ - for (i=0; g_emi62_loader[i].type == 0; i++) { - err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL); + while (rec) { + err = emi62_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } + rec = ihex_next_binrec(rec); } /* De-assert reset (let the CPU run) */ @@ -132,15 +153,16 @@ static int emi62_load_firmware (struct usb_device *dev) /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with * a single request. This is _much_ faster! */ + rec = (const struct ihex_binrec *)bitstream_fw->data; do { i = 0; - addr = g_emi62bs[pos].address; + addr = be32_to_cpu(rec->addr); /* intel hex records are terminated with type 0 element */ - while ((g_emi62bs[pos].type == 0) && (i + g_emi62bs[pos].length < FW_LOAD_SIZE)) { - memcpy(buf + i, g_emi62bs[pos].data, g_emi62bs[pos].length); - i += g_emi62bs[pos].length; - pos++; + while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) { + memcpy(buf + i, rec->data, be16_to_cpu(rec->len)); + i += be16_to_cpu(rec->len); + rec = ihex_next_binrec(rec); } err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); if (err < 0) { @@ -157,8 +179,11 @@ static int emi62_load_firmware (struct usb_device *dev) } /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ - for (i=0; g_emi62_loader[i].type == 0; i++) { - err = emi62_writememory(dev, g_emi62_loader[i].address, g_emi62_loader[i].data, g_emi62_loader[i].length, ANCHOR_LOAD_INTERNAL); + for (rec = (const struct ihex_binrec *)loader_fw->data; + rec; rec = ihex_next_binrec(rec)) { + err = emi62_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; @@ -175,29 +200,19 @@ static int emi62_load_firmware (struct usb_device *dev) /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ -/* FIXME: quick and dirty ifdefs */ -#ifdef SPDIF - for (i=0; g_HexSpdifFw62[i].type == 0; i++) { - if (!INTERNAL_RAM(g_HexSpdifFw62[i].address)) { - err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_EXTERNAL); + for (rec = (const struct ihex_binrec *)firmware_fw->data; + rec; rec = ihex_next_binrec(rec)) { + if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) { + err = emi62_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_EXTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } } -#else /* MIDI */ - for (i=0; g_HexMidiFw62[i].type == 0; i++) { - if (!INTERNAL_RAM(g_HexMidiFw62[i].address)) { - err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_EXTERNAL); - if (err < 0) { - err("%s - error loading firmware: error = %d\n", __func__, err); - goto wraperr; - return err; - } - } - } -#endif + /* Assert reset (stop the CPU in the EMI) */ err = emi62_set_reset(dev,1); if (err < 0) { @@ -205,29 +220,19 @@ static int emi62_load_firmware (struct usb_device *dev) goto wraperr; } -/* FIXME: quick and dirty ifdefs */ -#ifdef SPDIF - for (i=0; g_HexSpdifFw62[i].type == 0; i++) { - if (INTERNAL_RAM(g_HexSpdifFw62[i].address)) { - err = emi62_writememory(dev, g_HexSpdifFw62[i].address, g_HexSpdifFw62[i].data, g_HexSpdifFw62[i].length, ANCHOR_LOAD_INTERNAL); + for (rec = (const struct ihex_binrec *)firmware_fw->data; + rec; rec = ihex_next_binrec(rec)) { + if (INTERNAL_RAM(be32_to_cpu(rec->addr))) { + err = emi62_writememory(dev, be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len), + ANCHOR_LOAD_EXTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } } -#else /* MIDI */ - for (i=0; g_HexMidiFw62[i].type == 0; i++) { - if (INTERNAL_RAM(g_HexMidiFw62[i].address)) { - err = emi62_writememory(dev, g_HexMidiFw62[i].address, g_HexMidiFw62[i].data, g_HexMidiFw62[i].length, ANCHOR_LOAD_INTERNAL); - if (err < 0) { - err("%s - error loading firmware: error = %d\n", __func__, err); - goto wraperr; - } - } - } -#endif - + /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); if (err < 0) { @@ -236,6 +241,10 @@ static int emi62_load_firmware (struct usb_device *dev) } msleep(250); /* let device settle */ + release_firmware(loader_fw); + release_firmware(bitstream_fw); + release_firmware(firmware_fw); + kfree(buf); /* return 1 to fail the driver inialization @@ -243,6 +252,10 @@ static int emi62_load_firmware (struct usb_device *dev) return 1; wraperr: + release_firmware(loader_fw); + release_firmware(bitstream_fw); + release_firmware(firmware_fw); + kfree(buf); dev_err(&dev->dev, "Error\n"); return err; @@ -300,5 +313,8 @@ MODULE_AUTHOR("Tapio Laxström"); MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader."); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("emi62/loader.fw"); +MODULE_FIRMWARE("emi62/bitstream.fw"); +MODULE_FIRMWARE(FIRMWARE_FW); /* vi:ai:syntax=c:sw=8:ts=8:tw=80 */ diff --git a/drivers/usb/misc/emi62_fw_m.h b/drivers/usb/misc/emi62_fw_m.h deleted file mode 100644 index 3567c90..0000000 --- a/drivers/usb/misc/emi62_fw_m.h +++ /dev/null @@ -1,8853 +0,0 @@ -/* - * This file is generated from three different files, provided by Emagic. - */ -/* generated Tue Jun 3 21:36:11 EEST 2003 */ - -static INTEL_HEX_RECORD g_emi62bs[]={ - 16, 0x8010, 0, {0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x07 }, - 16, 0x8020, 0, {0x30,0x01,0x60,0x01,0x00,0x00,0x00,0x0d,0x30,0x01,0x20,0x01,0x00,0x80,0x3f,0x2d }, - 16, 0x8030, 0, {0x30,0x00,0xc0,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x09 }, - 16, 0x8040, 0, {0x30,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x01 }, - 16, 0x8050, 0, {0x30,0x00,0x40,0x00,0x50,0x00,0x58,0x1a,0x80,0x12,0x10,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8090, 0, {0x00,0x12,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x48 }, - 16, 0x80c0, 0, {0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8100, 0, {0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8130, 0, {0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8170, 0, {0x80,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81a0, 0, {0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x90,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81e0, 0, {0x7f,0x10,0x00,0x34,0x00,0x0d,0x00,0x03,0x40,0x00,0xd0,0x00,0x34,0x00,0x05,0x00 }, - 16, 0x81f0, 0, {0x07,0x40,0x01,0xd0,0x00,0x74,0x00,0x1d,0x00,0x07,0x40,0x01,0xd0,0x00,0x74,0x00 }, - 16, 0x8200, 0, {0x1d,0x80,0x07,0xe0,0x01,0xb8,0x00,0x6e,0x00,0x1b,0x80,0x06,0xe0,0x01,0x38,0x37 }, - 16, 0x8210, 0, {0xc4,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x80,0xfb,0x30,0x36,0xc8 }, - 16, 0x8220, 0, {0x4e,0x09,0x03,0xfc,0x84,0xff,0x10,0x3b,0xc0,0x0e,0xc8,0x07,0x22,0x80,0xff,0x22 }, - 16, 0x8230, 0, {0x33,0xc0,0x0f,0xc8,0x33,0x6e,0x00,0xfb,0x80,0x3f,0x20,0x0d,0xc2,0x53,0xd4,0x80 }, - 16, 0x8240, 0, {0xcc,0x3a,0x3f,0x00,0x0c,0xf1,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8250, 0, {0x80,0x00,0xed,0x60,0xbf,0x60,0x23,0xf0,0x0d,0x82,0x12,0x3c,0x60,0x8f,0x70,0x23 }, - 16, 0x8260, 0, {0xf0,0x08,0x88,0x02,0xa5,0x40,0xbf,0xd0,0x63,0xd6,0x0b,0x88,0x02,0x2e,0x0c,0xbb }, - 16, 0x8270, 0, {0x80,0x2e,0x20,0x88,0x8d,0x02,0xe6,0x40,0x80,0x60,0x2e,0x30,0x0a,0xb1,0x12,0x20 }, - 16, 0x8280, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x80,0xa3,0x40,0x2c,0xc4 }, - 16, 0x8290, 0, {0x4a,0x00,0x12,0x8c,0x88,0xa3,0x22,0x20,0xc4,0x0a,0x90,0x42,0x04,0xa9,0xa3,0x00 }, - 16, 0x82a0, 0, {0x24,0xc8,0x8b,0x80,0x02,0xcc,0x00,0xb3,0x00,0x2e,0x01,0x09,0x08,0x02,0x84,0x00 }, - 16, 0x82b0, 0, {0x80,0x20,0x2c,0x10,0x0a,0x32,0x42,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x82c0, 0, {0xc0,0x15,0xac,0x04,0xb3,0x00,0x2a,0xc0,0x08,0x08,0xa2,0x8c,0x00,0x8b,0x00,0xa2 }, - 16, 0x82d0, 0, {0xc1,0x10,0x98,0x42,0xa7,0x00,0xbb,0x01,0x66,0xc1,0x0b,0x80,0x02,0xac,0x04,0xbb }, - 16, 0x82e0, 0, {0x00,0x2e,0x00,0x0b,0xb8,0x12,0xe4,0x02,0x89,0x08,0x0e,0x40,0x0a,0xb0,0x02,0x30 }, - 16, 0x82f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xac,0x00,0xeb,0x00,0x3e,0xc0 }, - 16, 0x8300, 0, {0x4a,0xb8,0x23,0xec,0x18,0xeb,0x00,0x32,0xc0,0x0e,0x2c,0x12,0x22,0x10,0xeb,0x00 }, - 16, 0x8310, 0, {0x26,0xc0,0x4f,0x00,0x43,0xed,0x00,0xfb,0x00,0x2e,0x24,0x0d,0x80,0x13,0xe4,0x00 }, - 16, 0x8320, 0, {0xc8,0xd0,0x7c,0x12,0x0e,0xb0,0x03,0x40,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8330, 0, {0xe1,0x00,0xbc,0x00,0xff,0x00,0x35,0xc0,0x4f,0xe0,0x03,0x7c,0x08,0xff,0x01,0x17 }, - 16, 0x8340, 0, {0xc2,0x4d,0xc0,0x03,0xf4,0x08,0xf7,0x00,0x3b,0xc0,0x07,0xc0,0x03,0x7c,0x80,0xff }, - 16, 0x8350, 0, {0x24,0x3f,0x40,0x0c,0xf0,0x01,0xf4,0x04,0xbc,0x08,0x3f,0x28,0x0f,0xf0,0x03,0x78 }, - 16, 0x8360, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x08,0xfb,0x04,0x3a,0xc8 }, - 16, 0x8370, 0, {0x0f,0x94,0x03,0xec,0x10,0xf3,0x00,0x34,0xc0,0x0e,0xb0,0x03,0x61,0x04,0xfb,0x00 }, - 16, 0x8380, 0, {0x36,0xc0,0x0e,0xa3,0x03,0x2c,0x80,0xfb,0x72,0x3e,0x02,0x0f,0x8a,0x03,0xe4,0x02 }, - 16, 0x8390, 0, {0xc9,0x80,0x2a,0x50,0x0f,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x83a0, 0, {0xca,0x44,0x3c,0x00,0xbf,0x00,0x03,0xc0,0x08,0x80,0x03,0x7c,0x00,0xbf,0x00,0x3f }, - 16, 0x83b0, 0, {0xe2,0x08,0x90,0x43,0x60,0x00,0xbf,0x00,0x37,0xc0,0x08,0x90,0x01,0x6d,0x00,0xbb }, - 16, 0x83c0, 0, {0x40,0x2c,0x10,0x0b,0xb0,0x42,0xd7,0xc0,0x89,0x00,0x2a,0x7c,0x0b,0xf0,0x02,0xf2 }, - 16, 0x83d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x05,0x4c,0x00,0xb3,0x00,0x20,0xd5 }, - 16, 0x83e0, 0, {0x4a,0x00,0x00,0x0c,0x04,0x93,0x00,0x0c,0xf0,0x0b,0x09,0x02,0x08,0x01,0xb3,0x20 }, - 16, 0x83f0, 0, {0x28,0xc0,0x0a,0x0c,0x0a,0x0e,0x00,0xb3,0x00,0x24,0x30,0x09,0x00,0x02,0xc6,0x10 }, - 16, 0x8400, 0, {0x80,0x42,0x20,0x00,0x8b,0xb0,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8410, 0, {0x22,0x01,0x1e,0x00,0xb7,0x94,0x21,0xe4,0x48,0xd9,0x12,0x5e,0x40,0xb7,0x90,0x29 }, - 16, 0x8420, 0, {0xe0,0x8b,0x69,0x12,0xd6,0x80,0x37,0x82,0x2c,0xe8,0x08,0x4a,0x02,0x5e,0x00,0xb7 }, - 16, 0x8430, 0, {0xa4,0x2d,0x20,0x0b,0x79,0x02,0xd6,0x08,0x86,0x90,0x29,0xa0,0x0b,0x79,0x02,0xd8 }, - 16, 0x8440, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x0c,0x00,0xfb,0xa0,0x28,0xe8 }, - 16, 0x8450, 0, {0x0e,0x2a,0x02,0x8c,0x00,0xd3,0x00,0x64,0xc0,0x0f,0x00,0x43,0x0e,0xc4,0xf3,0x00 }, - 16, 0x8460, 0, {0x78,0xec,0x0e,0x0a,0x43,0x0e,0x20,0x73,0xe0,0x3c,0x02,0x4f,0x00,0x03,0xc4,0x40 }, - 16, 0x8470, 0, {0xc3,0x00,0x38,0xc0,0x0f,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8480, 0, {0x40,0x1d,0xbc,0x00,0xff,0x00,0xbc,0xcc,0x0e,0xb0,0x03,0xec,0x20,0xfb,0x00,0x3c }, - 16, 0x8490, 0, {0xc2,0x0c,0x20,0x03,0x6c,0x50,0xf3,0x00,0x36,0xc4,0x0f,0x40,0x03,0xfc,0x08,0xff }, - 16, 0x84a0, 0, {0x1a,0x3f,0x80,0x0f,0xf0,0x01,0xe4,0x30,0xff,0x02,0x3f,0xc0,0x0f,0xf0,0x63,0xd0 }, - 16, 0x84b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xec,0x40,0xfb,0x00,0xb2,0xd8 }, - 16, 0x84c0, 0, {0x0c,0xb0,0x01,0x2d,0x20,0xdb,0x01,0x3a,0xc8,0x8c,0x38,0x03,0xa8,0x00,0xfb,0x48 }, - 16, 0x84d0, 0, {0x3e,0xc9,0x0f,0x80,0x03,0xec,0x40,0xfb,0x01,0x3e,0x00,0x0f,0x08,0x03,0xa4,0x08 }, - 16, 0x84e0, 0, {0xfa,0x80,0xb2,0x80,0x0f,0xb1,0x02,0x6a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x84f0, 0, {0x48,0x19,0x1c,0x80,0xbf,0x30,0x21,0xca,0x08,0xf0,0x0a,0x0c,0x80,0x8f,0x50,0x21 }, - 16, 0x8500, 0, {0xc2,0x08,0x70,0x50,0x9c,0x00,0xb7,0x00,0x39,0xc4,0x0b,0x40,0x02,0x9c,0x04,0xb7 }, - 16, 0x8510, 0, {0x20,0x25,0x40,0x0b,0x70,0x02,0x14,0x80,0xb6,0x00,0x21,0x80,0x0b,0xf8,0x02,0x12 }, - 16, 0x8520, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0xb0,0x21,0xec }, - 16, 0x8530, 0, {0x0b,0x78,0x12,0xde,0x84,0x97,0x80,0x0d,0xe0,0x28,0xf8,0x02,0xde,0x00,0xb7,0x90 }, - 16, 0x8540, 0, {0x2d,0xe4,0x0b,0x68,0x82,0x5e,0x80,0xb7,0xa0,0x29,0x20,0x0b,0x48,0x02,0x96,0x00 }, - 16, 0x8550, 0, {0xb7,0x80,0x21,0xe1,0x0b,0x7a,0x02,0x70,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8560, 0, {0x48,0x04,0xcc,0x00,0xb3,0x00,0x20,0xc0,0x0b,0x38,0x02,0x8c,0x04,0x83,0x00,0x28 }, - 16, 0x8570, 0, {0xc0,0x88,0x39,0x02,0x4c,0x40,0xb3,0x04,0x28,0xc0,0x1b,0x10,0x02,0x8c,0x01,0xb3 }, - 16, 0x8580, 0, {0x04,0x24,0x88,0x4b,0x31,0x02,0x04,0x00,0xb3,0x80,0x20,0xf2,0x0b,0x30,0x02,0x02 }, - 16, 0x8590, 0, {0x24,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xfa,0x00,0x32,0x80 }, - 16, 0x85a0, 0, {0x0f,0xe8,0x03,0xe8,0x00,0xda,0x01,0x3a,0x80,0x8c,0xed,0x03,0xfb,0x04,0xfa,0x00 }, - 16, 0x85b0, 0, {0x3e,0x80,0x0f,0x6c,0x03,0xfb,0xc8,0xbe,0xc2,0x1f,0x80,0x0f,0xe5,0x03,0xa8,0x00 }, - 16, 0x85c0, 0, {0xfe,0x48,0x33,0x80,0x4f,0xa0,0x03,0x7a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x85d0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3c,0x00,0x0c,0x81,0x93,0x60,0x00,0xf8,0x01,0x36 }, - 16, 0x85e0, 0, {0x10,0x0f,0x80,0x03,0xa0,0x20,0xf8,0x00,0x2a,0x01,0x8f,0x84,0x13,0xe1,0x00,0xf8 }, - 16, 0x85f0, 0, {0x18,0x36,0x00,0x0f,0x80,0x13,0xe0,0x00,0xf8,0x20,0x3e,0x14,0x0f,0x80,0x03,0xd2 }, - 16, 0x8600, 0, {0x80,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe4,0x00,0xf1,0x00,0xaa,0x40 }, - 16, 0x8610, 0, {0x0c,0x90,0x03,0x24,0x00,0xe1,0x00,0x38,0x40,0x1c,0x90,0x03,0xe4,0x00,0xf9,0xa0 }, - 16, 0x8620, 0, {0x3a,0x40,0x47,0x9a,0x93,0xa2,0x80,0xf8,0x10,0x3e,0x40,0x0b,0x94,0x03,0xe6,0x40 }, - 16, 0x8630, 0, {0xf9,0xc0,0x3e,0x68,0x0b,0x10,0x03,0x02,0x84,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8640, 0, {0x80,0x04,0xe4,0x04,0xb9,0x00,0x22,0x40,0x08,0x90,0x02,0x24,0x04,0x89,0x00,0x36 }, - 16, 0x8650, 0, {0x40,0x08,0x90,0x02,0xe4,0x04,0xb9,0x80,0x2e,0x40,0x4f,0x94,0x03,0x61,0x10,0xe8 }, - 16, 0x8660, 0, {0x40,0x2e,0x40,0x0b,0x90,0x42,0xe6,0x04,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x02,0x20 }, - 16, 0x8670, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x04,0x24,0x00,0xb9,0x00,0x22,0x40 }, - 16, 0x8680, 0, {0x0a,0x10,0x52,0x04,0x04,0xa9,0x04,0x2a,0x40,0x08,0xb0,0x02,0xe4,0x01,0xb9,0x00 }, - 16, 0x8690, 0, {0x2e,0x40,0x0b,0x90,0x02,0xa8,0x0d,0xb8,0x40,0x2e,0x40,0x09,0x94,0x02,0xe5,0x00 }, - 16, 0x86a0, 0, {0xb9,0x04,0x2e,0x40,0x0b,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x86b0, 0, {0x08,0x04,0x04,0x80,0xb1,0x20,0x20,0xc8,0x0a,0x10,0x42,0x04,0x90,0x81,0x20,0x04 }, - 16, 0x86c0, 0, {0xc8,0x08,0x30,0x26,0xc4,0x00,0xb1,0x20,0x2c,0x48,0x0b,0x90,0x02,0x45,0x01,0xb1 }, - 16, 0x86d0, 0, {0x40,0x2c,0x40,0x0b,0x12,0x82,0xc4,0x00,0xb1,0x2b,0x2c,0x4a,0x0b,0x12,0x82,0x02 }, - 16, 0x86e0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x08,0x21,0x48,0xf8,0x50,0x32,0x00 }, - 16, 0x86f0, 0, {0x4e,0x85,0x0b,0x21,0x40,0xa8,0x52,0x2a,0x00,0x08,0x80,0x23,0xe1,0x40,0xf8,0x00 }, - 16, 0x8700, 0, {0x3a,0x14,0x0f,0xa0,0x43,0xa8,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x82,0x03,0xe0,0x00 }, - 16, 0x8710, 0, {0xf0,0x20,0x3e,0x88,0x4f,0x82,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8720, 0, {0x98,0x19,0xe4,0x40,0xf9,0x11,0x34,0x44,0x2d,0xd0,0x03,0xe4,0x50,0x79,0x10,0x38 }, - 16, 0x8730, 0, {0x44,0x2f,0xd0,0x03,0xf5,0x10,0xf9,0x10,0x3e,0x45,0x06,0x50,0x03,0xe5,0x00,0xe9 }, - 16, 0x8740, 0, {0x40,0x3f,0x40,0x0f,0xd0,0x43,0xf5,0x00,0xfd,0x28,0x3f,0x40,0x0f,0x92,0x83,0xe6 }, - 16, 0x8750, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0xe6,0x00,0xd9,0x90,0x37,0x69 }, - 16, 0x8760, 0, {0x4d,0x90,0x23,0x67,0x80,0xd9,0xe0,0x37,0x68,0x0e,0xd0,0x07,0xa4,0x00,0x05,0x86 }, - 16, 0x8770, 0, {0x3e,0x66,0x0d,0x50,0x23,0x26,0x00,0xc9,0x82,0x3d,0x40,0x0d,0xd8,0x07,0x36,0x02 }, - 16, 0x8780, 0, {0xcd,0xc0,0x33,0x60,0x0c,0x9c,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8790, 0, {0x38,0x10,0xe2,0x80,0x88,0xa2,0x22,0x10,0x28,0x8a,0x82,0x23,0x84,0x88,0xa0,0x22 }, - 16, 0x87a0, 0, {0x14,0x48,0x80,0x42,0x82,0x00,0x88,0x40,0x2e,0x30,0x08,0x80,0x02,0xa2,0x00,0xd8 }, - 16, 0x87b0, 0, {0x90,0x26,0x00,0x08,0x84,0x0a,0x21,0x00,0xc8,0xa0,0xa2,0x14,0x28,0x8c,0x02,0x0e }, - 16, 0x87c0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x20,0x91,0x40,0x2c,0x44 }, - 16, 0x87d0, 0, {0x18,0x10,0x02,0x85,0x04,0xb1,0x40,0x0c,0x40,0x0a,0x10,0x06,0x84,0x30,0x81,0x40 }, - 16, 0x87e0, 0, {0x2c,0x48,0x59,0x10,0x1a,0x04,0x60,0x81,0x09,0x2e,0x40,0x1b,0x14,0x02,0x25,0x00 }, - 16, 0x87f0, 0, {0x91,0xe0,0x20,0x60,0x08,0x16,0x02,0x00,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8800, 0, {0x18,0x15,0xa4,0x00,0x81,0x00,0x2a,0x41,0x08,0x90,0x02,0xa4,0x00,0xa1,0x00,0x2a }, - 16, 0x8810, 0, {0x41,0x08,0xb0,0x82,0x24,0x11,0x8b,0x00,0x2e,0x40,0x18,0x91,0x02,0xa0,0x04,0x98 }, - 16, 0x8820, 0, {0x20,0x2e,0x54,0x1b,0x90,0x82,0x2c,0x00,0x89,0x10,0x22,0x44,0x88,0x90,0x02,0x06 }, - 16, 0x8830, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xd9,0x00,0x3e,0x40 }, - 16, 0x8840, 0, {0x4c,0x90,0x03,0xa4,0x10,0xf9,0x00,0x3e,0x40,0x8e,0x10,0x02,0xa4,0xc2,0xc9,0x00 }, - 16, 0x8850, 0, {0x3e,0x40,0x0d,0x16,0x13,0x01,0x84,0xc8,0x20,0x3c,0x60,0x0f,0x90,0x12,0x04,0x00 }, - 16, 0x8860, 0, {0xd9,0x40,0x32,0x50,0x0c,0x90,0x03,0x28,0x84,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8870, 0, {0x28,0x01,0x84,0x00,0xf9,0x00,0x36,0x40,0x4f,0x99,0x4a,0x44,0x00,0x99,0x00,0xb4 }, - 16, 0x8880, 0, {0x40,0x0f,0x90,0x13,0xe6,0x00,0xf9,0x00,0x3c,0x40,0x0f,0x90,0x03,0xe3,0x00,0xf8 }, - 16, 0x8890, 0, {0x01,0x36,0x40,0x0c,0x99,0x03,0xe4,0x02,0xf9,0x80,0x3e,0x60,0x4f,0x90,0x0b,0xca }, - 16, 0x88a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x00,0x3c,0x00 }, - 16, 0x88b0, 0, {0x1d,0x80,0x03,0x20,0x00,0xe8,0x00,0x32,0x00,0x0c,0x84,0x83,0xe0,0x10,0xe8,0x20 }, - 16, 0x88c0, 0, {0x32,0x00,0x8e,0x84,0x03,0x21,0x80,0xc8,0x00,0x3a,0x19,0x0f,0x04,0x03,0xe0,0x24 }, - 16, 0x88d0, 0, {0xf0,0x02,0x3c,0x00,0x0f,0x80,0x13,0x8a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x88e0, 0, {0x28,0x05,0x28,0x02,0x8a,0x01,0x0f,0xa2,0x68,0xa0,0x00,0x28,0x00,0x8a,0x00,0x77 }, - 16, 0x88f0, 0, {0x80,0x68,0xe0,0x12,0xe8,0x00,0xde,0x00,0x36,0x81,0x08,0xe0,0x03,0x7a,0x08,0xae }, - 16, 0x8900, 0, {0xc4,0x2f,0x80,0x08,0xed,0x02,0xfa,0x00,0xbe,0xa0,0x3b,0x80,0x0b,0xa0,0x42,0x0a }, - 16, 0x8910, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x85,0x4c,0x00,0x93,0x00,0x2c,0xc0 }, - 16, 0x8920, 0, {0x88,0xb0,0x02,0x0c,0x14,0xa3,0x04,0x20,0xc4,0x18,0x38,0x02,0xec,0x10,0x93,0x54 }, - 16, 0x8930, 0, {0x28,0xc0,0x0a,0x00,0x02,0x4e,0x00,0x83,0x49,0x68,0xc0,0x02,0x39,0x42,0xce,0x40 }, - 16, 0x8940, 0, {0xb3,0x00,0x2c,0xe6,0x0b,0xb0,0x02,0x8b,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8950, 0, {0x20,0x01,0x1c,0x08,0x87,0x20,0x2c,0x80,0x18,0xf2,0x22,0x1c,0x00,0x87,0x10,0x21 }, - 16, 0x8960, 0, {0xc0,0x08,0x70,0x82,0xdc,0x80,0x96,0x80,0x2d,0xc0,0x0a,0x40,0x02,0x7d,0x40,0x27 }, - 16, 0x8970, 0, {0x64,0x6d,0xd0,0x48,0x60,0x42,0xd8,0x05,0xb6,0x04,0x29,0xc0,0x4b,0x72,0x02,0x28 }, - 16, 0x8980, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x3e,0x88,0xd7,0xe0,0x3d,0xe0 }, - 16, 0x8990, 0, {0x08,0x7c,0x42,0x3e,0x00,0xe3,0x82,0x20,0xe0,0x0c,0x68,0x03,0xdf,0x04,0xd7,0x80 }, - 16, 0x89a0, 0, {0x3b,0xe0,0x4e,0x48,0x0a,0x5e,0x80,0xc7,0xc2,0x19,0xe0,0x0e,0x78,0x03,0xd6,0x08 }, - 16, 0x89b0, 0, {0xf7,0x80,0x3d,0xe0,0x0f,0xf8,0x03,0xaa,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x89c0, 0, {0x08,0x1d,0xac,0x40,0xfb,0x40,0x7e,0x80,0x0e,0x36,0x83,0xed,0x40,0xdb,0x60,0x3e }, - 16, 0x89d0, 0, {0x80,0x0f,0xa0,0x03,0xed,0x28,0xda,0x00,0x32,0xc4,0x0c,0xb0,0x0b,0xcc,0x00,0xfb }, - 16, 0x89e0, 0, {0x00,0x3e,0xc0,0x0e,0x80,0x13,0xe0,0x10,0xf8,0x00,0x3e,0x00,0x0f,0xb1,0x53,0xc2 }, - 16, 0x89f0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xff,0xc0,0x33,0xe0 }, - 16, 0x8a00, 0, {0x0c,0xf9,0x03,0x7f,0x04,0xcf,0xd0,0x3f,0xe4,0x0f,0xb8,0x03,0xfe,0x00,0xff,0x94 }, - 16, 0x8a10, 0, {0x3f,0xe0,0x0f,0xc8,0x03,0x7e,0x10,0xf3,0x80,0x3b,0xe0,0x0f,0xf8,0x03,0xfe,0x48 }, - 16, 0x8a20, 0, {0xed,0x80,0x33,0x24,0x04,0xf8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8a30, 0, {0xa8,0x11,0x9c,0x80,0xbf,0x04,0x21,0x28,0x08,0xf8,0x02,0x1e,0xc0,0xcf,0x90,0x21 }, - 16, 0x8a40, 0, {0x4c,0x0b,0x5a,0x42,0xde,0x00,0xb7,0x80,0x2c,0xe8,0x0b,0x04,0x02,0x1c,0x00,0xb7 }, - 16, 0x8a50, 0, {0xa0,0x35,0x10,0x8f,0x71,0x13,0xde,0xc0,0x84,0x10,0x21,0x80,0x0d,0x71,0x02,0x2a }, - 16, 0x8a60, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x9c,0x08,0xb7,0x00,0x25,0xc8 }, - 16, 0x8a70, 0, {0x08,0x71,0x02,0xcc,0x80,0x97,0x00,0x29,0xc0,0x8b,0x72,0x06,0xdc,0x08,0xb5,0x00 }, - 16, 0x8a80, 0, {0x2d,0xc8,0x0b,0x40,0x02,0x1c,0x40,0xbf,0x10,0x21,0xc0,0x0b,0x74,0x02,0xd4,0x80 }, - 16, 0x8a90, 0, {0xa7,0x40,0x21,0x41,0x08,0x70,0x02,0x04,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8aa0, 0, {0x60,0x14,0xcc,0x00,0xb3,0x00,0x24,0x00,0x08,0x34,0x82,0xac,0x11,0x83,0x00,0x20 }, - 16, 0x8ab0, 0, {0x00,0x4b,0x18,0x26,0xcf,0x20,0xb1,0x06,0x2c,0xc1,0x0b,0x32,0x02,0x0e,0x08,0xb3 }, - 16, 0x8ac0, 0, {0x88,0x24,0x32,0x0a,0x30,0x12,0x84,0x08,0x80,0x00,0xa0,0x34,0x28,0x30,0x02,0x18 }, - 16, 0x8ad0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbc,0x00,0xff,0x00,0xb6,0x40 }, - 16, 0x8ae0, 0, {0x2c,0xf4,0x43,0xfc,0x01,0xdf,0x00,0x3a,0x00,0x03,0x92,0x03,0xff,0x88,0xf9,0x00 }, - 16, 0x8af0, 0, {0x2f,0xc0,0x1b,0x0e,0x4b,0x2e,0x90,0xfb,0xe0,0x30,0x32,0x0b,0x98,0x02,0xec,0x08 }, - 16, 0x8b00, 0, {0x6b,0xc0,0x32,0xc0,0x08,0xf0,0x09,0x3e,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8b10, 0, {0x80,0x00,0xec,0x00,0xf3,0x00,0x3a,0xc0,0x0f,0xb0,0x01,0x6c,0x00,0xfb,0x00,0x3a }, - 16, 0x8b20, 0, {0x10,0x0f,0xb4,0x03,0xec,0x00,0xf0,0x00,0x3c,0xc0,0x0f,0x80,0x0b,0xad,0x20,0xfb }, - 16, 0x8b30, 0, {0x40,0x3e,0x10,0x07,0xa8,0x63,0xe0,0x00,0xfb,0x80,0x3e,0xd8,0x0f,0xb0,0x03,0xe0 }, - 16, 0x8b40, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0x72,0x00 }, - 16, 0x8b50, 0, {0x0f,0xf0,0x23,0xfc,0x00,0xdf,0x00,0x3f,0x40,0x0f,0xc0,0x03,0xdc,0x00,0x8f,0x00 }, - 16, 0x8b60, 0, {0x33,0xc1,0x0c,0xc0,0x03,0xbe,0x00,0xff,0x90,0x3b,0x28,0x0e,0x59,0x03,0x2e,0x00 }, - 16, 0x8b70, 0, {0x7b,0x00,0x32,0xc4,0x0f,0xb0,0x03,0xd0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8b80, 0, {0xc1,0x04,0x6c,0x00,0xbb,0x00,0x62,0xa0,0x0f,0xb0,0x02,0xec,0x09,0x8b,0x00,0x2e }, - 16, 0x8b90, 0, {0x30,0x0b,0xa8,0x03,0xac,0x00,0xfa,0xc1,0x22,0xc1,0x08,0x8c,0x02,0x2c,0x00,0xb3 }, - 16, 0x8ba0, 0, {0x81,0x2a,0x00,0x0d,0x88,0xb2,0x22,0x00,0xb3,0xc0,0x22,0xc8,0x0b,0xb0,0x42,0x61 }, - 16, 0x8bb0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x6c,0x00,0xbb,0x01,0x22,0x62 }, - 16, 0x8bc0, 0, {0x0b,0xb0,0x02,0xec,0x04,0x8b,0x00,0x2e,0xa2,0x49,0x88,0x26,0xec,0x00,0xa8,0x80 }, - 16, 0x8bd0, 0, {0x22,0xc0,0x28,0x82,0x0a,0xac,0xa0,0xbb,0x08,0x22,0xc0,0x08,0x80,0x0a,0x28,0x84 }, - 16, 0x8be0, 0, {0xb9,0xc0,0xa2,0x00,0x0b,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8bf0, 0, {0x08,0x04,0x0c,0x00,0xb3,0x10,0x20,0x48,0x0a,0x32,0x02,0xcc,0x80,0x83,0x01,0x24 }, - 16, 0x8c00, 0, {0x00,0x0b,0x02,0x06,0x8c,0x60,0xa0,0x20,0x20,0xc8,0x08,0x01,0x02,0x0c,0x00,0xb3 }, - 16, 0x8c10, 0, {0x00,0x28,0x00,0x09,0x20,0x02,0x08,0x80,0xb1,0x00,0xa0,0x80,0x0b,0x30,0x02,0x42 }, - 16, 0x8c20, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x6c,0x00,0xff,0x00,0xa2,0x0e }, - 16, 0x8c30, 0, {0x0b,0xf1,0x03,0xfc,0x08,0xcf,0x20,0x3e,0xc0,0x0f,0x80,0x03,0xfc,0x84,0xa8,0x20 }, - 16, 0x8c40, 0, {0xb2,0xc8,0x8c,0x80,0x03,0xac,0x44,0xfb,0x70,0x3a,0xc0,0x0e,0x90,0x03,0x2c,0xa4 }, - 16, 0x8c50, 0, {0xfb,0x00,0xb2,0x40,0x0f,0xb0,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8c60, 0, {0xa0,0x1d,0xfc,0x00,0xff,0x26,0x3e,0x00,0x0f,0xb6,0x13,0xed,0x00,0xfb,0x10,0x3f }, - 16, 0x8c70, 0, {0x00,0x0f,0xc1,0x13,0xac,0x80,0xf8,0x12,0x3e,0xc6,0x4f,0x42,0x43,0xfc,0x04,0xff }, - 16, 0x8c80, 0, {0x31,0x3f,0x00,0x0f,0xf0,0x03,0xec,0x00,0xff,0x00,0xbf,0xc0,0x8f,0xf0,0x03,0xe8 }, - 16, 0x8c90, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x40,0xfc,0x80,0x36,0xc8 }, - 16, 0x8ca0, 0, {0x0f,0x09,0x03,0xc2,0x00,0xf8,0xc0,0x33,0xcc,0x2c,0x4c,0x03,0x63,0x90,0xe0,0x90 }, - 16, 0x8cb0, 0, {0x3a,0xc0,0x0d,0x50,0x0b,0x3c,0x04,0xdf,0x64,0x3f,0xc8,0x8d,0xf1,0x43,0x2c,0x00 }, - 16, 0x8cc0, 0, {0xd5,0x00,0x33,0xc0,0x45,0xf2,0x23,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8cd0, 0, {0x80,0x10,0xed,0x80,0xba,0x02,0x21,0xde,0x8b,0x82,0x22,0xe0,0x20,0xb0,0x00,0x2b }, - 16, 0x8ce0, 0, {0xec,0x09,0x80,0x02,0xe3,0x40,0xba,0x20,0x2f,0xdc,0x08,0x98,0x12,0x2c,0x00,0x8b }, - 16, 0x8cf0, 0, {0x51,0x2a,0xd0,0x08,0x72,0x22,0x2e,0x00,0x8d,0x80,0x21,0xd0,0x08,0xb6,0x82,0x20 }, - 16, 0x8d00, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x40,0xb9,0x28,0x24,0xc0 }, - 16, 0x8d10, 0, {0x4a,0x12,0x12,0x88,0x85,0xa8,0x20,0x20,0xc0,0x0b,0x22,0x02,0xc0,0x91,0xa1,0x00 }, - 16, 0x8d20, 0, {0x28,0xc2,0x0b,0x00,0x12,0x8c,0x40,0xa3,0x20,0x20,0xc4,0x0b,0x30,0x0a,0x0c,0x11 }, - 16, 0x8d30, 0, {0x99,0x00,0x20,0xc5,0x09,0x01,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8d40, 0, {0xc0,0x11,0xac,0x00,0xb8,0x80,0x22,0xc0,0x0b,0x88,0x02,0xee,0x01,0xb8,0xc1,0x2a }, - 16, 0x8d50, 0, {0xc0,0x1b,0xa8,0x06,0xe2,0x00,0xbb,0x80,0x2e,0xc0,0x8a,0x80,0x02,0xac,0x00,0xab }, - 16, 0x8d60, 0, {0x00,0x2e,0xc0,0x0a,0xb0,0x02,0x2c,0x00,0x99,0x00,0x24,0xc0,0x08,0x80,0x02,0x30 }, - 16, 0x8d70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xb0,0x80,0x36,0xc0 }, - 16, 0x8d80, 0, {0x0e,0xa8,0x13,0xe2,0x85,0xf3,0xc0,0x32,0xc0,0x0e,0x9c,0x23,0xe7,0x24,0xe8,0x82 }, - 16, 0x8d90, 0, {0x3a,0xc1,0x0f,0x94,0x03,0xac,0x02,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x2e,0x10 }, - 16, 0x8da0, 0, {0x51,0x00,0xb2,0xc0,0x0d,0xb0,0x03,0x50,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8db0, 0, {0xe0,0x01,0xbc,0x00,0xff,0x00,0x3f,0xc0,0x8f,0xd0,0x03,0xf0,0x04,0xfd,0x04,0x3f }, - 16, 0x8dc0, 0, {0xc0,0x4c,0xc0,0x03,0xf0,0x10,0xfc,0x00,0x1f,0xc0,0x0d,0xd1,0x23,0x1c,0x00,0xc7 }, - 16, 0x8dd0, 0, {0x00,0x39,0xc0,0x0d,0xf0,0x83,0xfe,0x44,0xed,0x00,0x3b,0xc0,0x0f,0x74,0x03,0xf8 }, - 16, 0x8de0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xf9,0x01,0xba,0xc1 }, - 16, 0x8df0, 0, {0x0c,0xb0,0x03,0xa1,0x08,0xfa,0x00,0x30,0xc8,0x8f,0x94,0x03,0x25,0x00,0xf9,0x00 }, - 16, 0x8e00, 0, {0x3c,0xc0,0x0f,0x04,0x83,0xec,0x00,0xfb,0x00,0x3e,0xe0,0x0f,0x71,0x0b,0x2c,0x40 }, - 16, 0x8e10, 0, {0xfd,0x08,0x37,0xc0,0x4e,0x91,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8e20, 0, {0xc8,0x05,0x3c,0x00,0xb9,0x00,0x23,0xc0,0x08,0x90,0x02,0x24,0x00,0xc8,0x00,0x37 }, - 16, 0x8e30, 0, {0xf0,0x0b,0x80,0x01,0x64,0x00,0x49,0x02,0x33,0xc0,0x84,0x9c,0x03,0x3c,0x00,0xbf }, - 16, 0x8e40, 0, {0x02,0x0f,0xd0,0x08,0xf4,0x02,0x0e,0x10,0xbd,0x80,0x33,0xe0,0x08,0x90,0x0a,0x32 }, - 16, 0x8e50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb0,0x06,0x20,0xc0 }, - 16, 0x8e60, 0, {0x08,0x00,0x42,0x84,0x00,0xa0,0x00,0x20,0xf0,0x0b,0x00,0x22,0xcc,0x00,0x90,0x00 }, - 16, 0x8e70, 0, {0x28,0xc0,0x02,0x3d,0x02,0x8c,0x00,0xb3,0x00,0x2c,0xc2,0x9a,0x38,0x02,0x06,0x04 }, - 16, 0x8e80, 0, {0xb1,0x12,0x20,0xe0,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8e90, 0, {0x20,0x01,0x1e,0x00,0xb6,0x80,0x21,0xe0,0x28,0xea,0x02,0x36,0x80,0x86,0x90,0x65 }, - 16, 0x8ea0, 0, {0xe0,0x1b,0xda,0x06,0x5e,0x01,0x9e,0x84,0x25,0xec,0x0a,0x78,0x02,0x5e,0x00,0xb7 }, - 16, 0x8eb0, 0, {0x80,0x2d,0xe0,0x08,0x79,0x4a,0x16,0x40,0xbd,0x80,0x25,0xe0,0x08,0x38,0x02,0x08 }, - 16, 0x8ec0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xfb,0x00,0x28,0xe0 }, - 16, 0x8ed0, 0, {0x08,0x18,0x02,0x8a,0x88,0xa1,0xa0,0x20,0xc2,0x1f,0x2a,0x23,0xe6,0xc8,0xf0,0xc0 }, - 16, 0x8ee0, 0, {0x3a,0xed,0x4e,0x34,0x02,0x8c,0x08,0xf3,0x81,0x1e,0xc0,0x0e,0x30,0x03,0x0e,0xc0 }, - 16, 0x8ef0, 0, {0xf1,0x00,0xb0,0xca,0x0e,0x21,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8f00, 0, {0x40,0x1d,0xbc,0x08,0xfe,0x10,0x3f,0xd2,0x0f,0xe0,0x03,0xec,0x04,0xff,0x14,0x7e }, - 16, 0x8f10, 0, {0xc0,0x0f,0xb1,0x23,0xfc,0x01,0xee,0x00,0x3a,0xc4,0x0d,0xb0,0x13,0xbc,0x00,0xff }, - 16, 0x8f20, 0, {0x00,0x3f,0xc0,0x0e,0xf0,0x83,0xfc,0x0c,0xfd,0x10,0x3b,0xc0,0x2f,0xe1,0x03,0xd0 }, - 16, 0x8f30, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x40,0xf0,0x80,0x32,0xd0 }, - 16, 0x8f40, 0, {0x0c,0xa0,0x03,0x6c,0x00,0xf3,0x80,0x32,0xda,0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00 }, - 16, 0x8f50, 0, {0x3e,0xcc,0x4c,0x98,0x13,0x2c,0x10,0xfb,0x04,0x3e,0xc4,0x0c,0xf2,0x83,0xa6,0x10 }, - 16, 0x8f60, 0, {0xdd,0x20,0x3f,0xd1,0x0c,0xb0,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8f70, 0, {0x48,0x11,0x9c,0x80,0xb7,0x00,0x21,0xc8,0x0c,0x70,0x02,0xdc,0x08,0xb7,0x00,0x21 }, - 16, 0x8f80, 0, {0xc8,0x0e,0x70,0x22,0xd8,0x00,0xb7,0x00,0x2c,0xc2,0x0a,0x70,0x0a,0x1f,0x08,0xb7 }, - 16, 0x8f90, 0, {0x00,0x39,0xc8,0x0a,0x70,0x02,0x14,0x00,0xc5,0x69,0x2c,0xca,0x2a,0x70,0x02,0xd2 }, - 16, 0x8fa0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xbf,0x81,0x64,0xe1 }, - 16, 0x8fb0, 0, {0x08,0x78,0x02,0x5a,0x01,0xbf,0x80,0x21,0xec,0x4b,0x78,0x46,0x9f,0x08,0x37,0x80 }, - 16, 0x8fc0, 0, {0x2d,0xe8,0x88,0x18,0x02,0x1e,0x81,0xb7,0xb0,0x2d,0xe0,0x09,0x7a,0x02,0x8e,0x00 }, - 16, 0x8fd0, 0, {0x95,0xa0,0x2d,0xe4,0x08,0x78,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8fe0, 0, {0x48,0x14,0xec,0x00,0xb3,0x60,0x20,0xc0,0x08,0xb6,0x02,0xcc,0x00,0xb3,0x01,0x20 }, - 16, 0x8ff0, 0, {0xc0,0x8a,0xb0,0x86,0xcf,0x00,0xbb,0x10,0x6c,0xc1,0x0a,0x38,0x02,0x0c,0x01,0xb3 }, - 16, 0x9000, 0, {0x02,0x28,0xc0,0x0b,0xb0,0x0a,0x0c,0x00,0x81,0x00,0x2e,0xc0,0x0a,0xb4,0x82,0xd2 }, - 16, 0x9010, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0x40,0xb6,0x80 }, - 16, 0x9020, 0, {0x0c,0xe4,0x03,0x78,0x80,0xfe,0x74,0x32,0x80,0x0b,0xe6,0x03,0xf9,0x00,0xfe,0x00 }, - 16, 0x9030, 0, {0x3e,0x80,0x0c,0xe0,0x03,0x28,0x00,0xfa,0x00,0x3e,0x80,0x4d,0xa0,0x03,0xa8,0x00 }, - 16, 0x9040, 0, {0xda,0x04,0x3e,0x80,0x0c,0xe4,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9050, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x2e,0x80,0x23,0xe0,0x00,0xf8,0x01,0x3c }, - 16, 0x9060, 0, {0x00,0x0e,0x80,0x03,0xe0,0x20,0xf8,0x20,0x3e,0x01,0x8f,0x89,0x03,0xe0,0x00,0xf8 }, - 16, 0x9070, 0, {0x00,0x3a,0x10,0x0e,0x80,0x01,0xe0,0x00,0xe8,0x40,0x7e,0x00,0x4f,0x80,0x03,0xd2 }, - 16, 0x9080, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x01,0x7e,0x40 }, - 16, 0x9090, 0, {0x2c,0x90,0x0b,0x24,0x00,0xf9,0x00,0x3e,0x68,0x05,0x90,0x13,0xa4,0x04,0xd9,0x00 }, - 16, 0x90a0, 0, {0x32,0x41,0x0e,0x91,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x60,0x0e,0x90,0x03,0x24,0x00 }, - 16, 0x90b0, 0, {0xf1,0x00,0x32,0x40,0x68,0x90,0x43,0x82,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x90c0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x6e,0x40,0x08,0x90,0x42,0x24,0x00,0xb9,0x00,0x2e }, - 16, 0x90d0, 0, {0x70,0x88,0x90,0x03,0x24,0x00,0xb9,0x00,0x22,0x40,0x08,0x98,0x12,0xe4,0x00,0xb9 }, - 16, 0x90e0, 0, {0x00,0x2e,0x40,0x0a,0x90,0x0a,0x26,0x00,0xb9,0x80,0xa2,0x40,0x08,0x90,0x12,0x20 }, - 16, 0x90f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x04,0x2c,0x40 }, - 16, 0x9100, 0, {0x08,0x90,0x02,0x24,0x01,0xb9,0x00,0x2a,0x40,0x0b,0xb0,0x02,0xa4,0x01,0xb9,0x00 }, - 16, 0x9110, 0, {0xe0,0x40,0x0a,0x90,0x82,0xa4,0x00,0xb9,0x00,0x2c,0x48,0x0a,0x98,0x02,0x24,0x80 }, - 16, 0x9120, 0, {0x39,0x20,0x22,0x40,0x2a,0x90,0x02,0x86,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9130, 0, {0x08,0x04,0x04,0x80,0x81,0x00,0x2c,0x48,0x08,0x10,0x12,0x04,0x10,0xb1,0x04,0x2c }, - 16, 0x9140, 0, {0xd8,0x0a,0x10,0x02,0x04,0x00,0xb1,0x00,0x20,0x48,0x08,0x10,0x02,0xc4,0x80,0xb1 }, - 16, 0x9150, 0, {0x22,0x2c,0x50,0x8a,0x32,0x82,0x05,0xa0,0xb1,0x2a,0x20,0x4a,0x0a,0x12,0x82,0x02 }, - 16, 0x9160, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x50,0xc8,0x52,0x2e,0x14 }, - 16, 0x9170, 0, {0x0c,0x85,0x03,0x21,0x40,0xf8,0x50,0x3a,0x00,0x1f,0x85,0x03,0xa1,0x40,0xf8,0x50 }, - 16, 0x9180, 0, {0x32,0x14,0x0e,0x80,0x03,0xa1,0x40,0xf8,0x50,0x3c,0x80,0x0e,0x02,0x03,0x20,0x80 }, - 16, 0x9190, 0, {0xfa,0x20,0x32,0x08,0x0e,0x82,0x13,0xae,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x91a0, 0, {0x98,0x1d,0xe4,0x50,0xfd,0x00,0x3e,0x44,0x0f,0xd0,0x03,0xf4,0x00,0xfd,0x00,0x3e }, - 16, 0x91b0, 0, {0x44,0x8d,0xd0,0x01,0xbd,0x00,0xfd,0x02,0x3e,0x44,0x0f,0xd4,0x00,0xe4,0x48,0x79 }, - 16, 0x91c0, 0, {0x14,0x3e,0x50,0x0f,0x92,0xa2,0xf4,0x08,0xfd,0x00,0x3e,0x4a,0x0d,0xd2,0x83,0xe6 }, - 16, 0x91d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe7,0x00,0xf9,0x10,0x3a,0x6e }, - 16, 0x91e0, 0, {0x0c,0xb1,0x03,0xe4,0x40,0xf9,0x44,0x3b,0x61,0x8e,0x94,0x03,0xe4,0x00,0xe9,0x40 }, - 16, 0x91f0, 0, {0x32,0x66,0x0f,0xda,0x0b,0xa7,0x28,0xc9,0xe0,0x3f,0x68,0x0c,0xda,0x83,0xb3,0x20 }, - 16, 0x9200, 0, {0xed,0xa0,0x33,0x79,0x08,0xd8,0x03,0x46,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9210, 0, {0x38,0x10,0xe2,0x00,0xb8,0xa0,0x2e,0x38,0x08,0x8a,0x02,0xe2,0x88,0xe8,0x81,0x2e }, - 16, 0x9220, 0, {0x14,0x09,0x0a,0x03,0xe2,0x80,0xb8,0x80,0x32,0x30,0x0b,0x85,0x02,0x21,0x01,0xa8 }, - 16, 0x9230, 0, {0xf4,0x38,0x2a,0x08,0x0e,0xca,0x23,0x90,0xc8,0x54,0x34,0x38,0x08,0x8a,0x92,0x0e }, - 16, 0x9240, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x00,0x28,0x40 }, - 16, 0x9250, 0, {0x19,0x10,0x02,0xc4,0x00,0xb1,0x20,0x28,0x40,0x0b,0x10,0x06,0xc4,0x20,0xa1,0xa2 }, - 16, 0x9260, 0, {0x6c,0x48,0x0b,0x10,0x02,0x84,0x08,0x81,0x20,0x2c,0x50,0x09,0x10,0x02,0xc4,0x04 }, - 16, 0x9270, 0, {0xb1,0x00,0x24,0x58,0x08,0x3c,0x02,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9280, 0, {0x18,0x15,0xa4,0x01,0xb9,0x20,0x2c,0x40,0x09,0x90,0x02,0xe4,0x10,0xa9,0x40,0x2e }, - 16, 0x9290, 0, {0x40,0x0b,0x90,0x02,0xa4,0x00,0xb1,0x01,0x2a,0x40,0x0b,0x94,0x02,0x24,0x00,0xa9 }, - 16, 0x92a0, 0, {0x00,0x2a,0x40,0x01,0x10,0x52,0x64,0x00,0x89,0x00,0x26,0x40,0x00,0x98,0x02,0x46 }, - 16, 0x92b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x61,0x3a,0x40 }, - 16, 0x92c0, 0, {0x0d,0x90,0x83,0xe5,0x20,0xf9,0x01,0x3a,0x40,0x2e,0x90,0x02,0xe4,0x40,0xe9,0x01 }, - 16, 0x92d0, 0, {0x9e,0x40,0x0f,0x94,0x03,0xa4,0x00,0x89,0x00,0x3e,0x40,0x2d,0x90,0x02,0xe6,0x08 }, - 16, 0x92e0, 0, {0xb9,0x01,0x36,0x40,0x2c,0x90,0x01,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x92f0, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x40,0x2e,0x90,0x03,0xe4,0x80,0xf9,0x00,0x3c }, - 16, 0x9300, 0, {0x40,0x0c,0x9c,0x23,0xe4,0x00,0xf9,0x00,0x36,0x40,0x0f,0x10,0x43,0x84,0x00,0xf9 }, - 16, 0x9310, 0, {0x02,0x3e,0x40,0x0e,0x90,0x03,0x80,0x80,0xf9,0x00,0x3c,0x40,0x2f,0x90,0x03,0x8a }, - 16, 0x9320, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x40,0x36,0x01 }, - 16, 0x9330, 0, {0x0d,0x84,0x03,0xe1,0x00,0xe8,0x40,0x3e,0x08,0x0c,0x80,0x03,0xe1,0x00,0xf8,0x00 }, - 16, 0x9340, 0, {0x32,0x00,0x8f,0x80,0x03,0xa0,0x10,0xf8,0x00,0x32,0x04,0x0e,0x80,0x83,0x60,0x00 }, - 16, 0x9350, 0, {0xf8,0x00,0x3e,0x00,0x0c,0x00,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9360, 0, {0x28,0x05,0x28,0x00,0x8a,0x01,0x22,0x80,0x08,0xa0,0x24,0xe8,0x00,0x0a,0x00,0x2f }, - 16, 0x9370, 0, {0x80,0x1a,0xa0,0x02,0x28,0x00,0xba,0x00,0x16,0x80,0x0b,0xe0,0x03,0x28,0x08,0xea }, - 16, 0x9380, 0, {0x00,0x33,0x90,0x08,0xec,0x1b,0x22,0x80,0xc6,0x14,0x2f,0x91,0x08,0xa0,0x43,0x4a }, - 16, 0x9390, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x00,0x24,0xc0 }, - 16, 0x93a0, 0, {0x09,0x30,0x12,0xcc,0x04,0xa3,0x04,0x6c,0xc0,0x09,0x30,0x02,0x8c,0x00,0xb3,0x00 }, - 16, 0x93b0, 0, {0x2c,0xc0,0x13,0x30,0x02,0x8c,0x00,0xb3,0x00,0xe6,0xb8,0x0a,0x38,0x02,0x44,0x08 }, - 16, 0x93c0, 0, {0x82,0x50,0x2c,0xd2,0x3a,0x30,0x02,0x8a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x93d0, 0, {0xa0,0x01,0x0e,0x80,0x97,0xb4,0x21,0xc4,0x49,0x71,0x02,0xde,0x81,0x87,0x21,0x2d }, - 16, 0x93e0, 0, {0xd0,0x0b,0x7b,0x02,0x1c,0x01,0xbf,0x20,0x29,0xc4,0x0b,0x30,0x02,0x5c,0x00,0xa7 }, - 16, 0x93f0, 0, {0xa1,0x21,0xc0,0x4a,0x70,0x8a,0x0c,0x81,0x84,0x00,0x2d,0xd0,0x0a,0x50,0x02,0xe8 }, - 16, 0x9400, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x82,0xdf,0xa0,0x34,0xec }, - 16, 0x9410, 0, {0x0d,0x79,0x02,0xfe,0x80,0xe7,0xe8,0x2f,0xa0,0x09,0x7a,0x02,0x9e,0x00,0xf7,0xa2 }, - 16, 0x9420, 0, {0x25,0xea,0x0b,0x48,0x03,0x9e,0x04,0xff,0xc0,0x65,0xe4,0x0e,0x68,0x03,0x5f,0x00 }, - 16, 0x9430, 0, {0xe4,0x80,0x3d,0xe0,0x0e,0xf8,0x03,0xaa,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9440, 0, {0x08,0x1d,0xac,0x48,0xeb,0x05,0x3e,0xd9,0x0e,0xb2,0x03,0xec,0x00,0xfb,0x60,0x3e }, - 16, 0x9450, 0, {0xc0,0x0e,0xb2,0x83,0xac,0x00,0xf3,0x50,0xa6,0xc0,0x4f,0xb0,0x03,0xac,0x00,0xfb }, - 16, 0x9460, 0, {0x80,0x3f,0xd8,0x0d,0xa0,0x03,0xec,0x0a,0xf9,0x00,0x3e,0xc0,0x0d,0x90,0x03,0x42 }, - 16, 0x9470, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xbb,0x90,0x3e,0xe0 }, - 16, 0x9480, 0, {0x08,0x39,0x03,0x9e,0x20,0xcf,0x82,0x77,0xe0,0x1f,0xf8,0x03,0xee,0x00,0xff,0xc0 }, - 16, 0x9490, 0, {0x3f,0xe5,0x0d,0xf9,0x03,0xee,0x00,0xfb,0x90,0x37,0xa0,0x08,0xf8,0x0f,0x1e,0x00 }, - 16, 0x94a0, 0, {0xcc,0x94,0x33,0x60,0x0d,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x94b0, 0, {0xa8,0x11,0x9c,0x00,0xb7,0x90,0x2f,0xe4,0x08,0x7a,0x02,0x1e,0x00,0x8f,0x12,0x25 }, - 16, 0x94c0, 0, {0xd8,0x0b,0xbb,0x02,0x1e,0x00,0xb7,0x00,0x2d,0xe8,0x08,0x7d,0x82,0xde,0x40,0xbb }, - 16, 0x94d0, 0, {0xa0,0x27,0x90,0x0a,0x76,0x02,0x5c,0x80,0x85,0x00,0x37,0xc4,0x4d,0x71,0x03,0xea }, - 16, 0x94e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x20,0x2d,0xc0 }, - 16, 0x94f0, 0, {0x29,0xf2,0x22,0xbc,0x80,0x97,0x00,0x25,0x41,0x0b,0x70,0x12,0x9c,0x00,0xb7,0x08 }, - 16, 0x9500, 0, {0x29,0xc0,0x08,0x42,0x12,0xdc,0x40,0xb7,0x00,0x29,0xc0,0x09,0x60,0x22,0xdc,0x10 }, - 16, 0x9510, 0, {0x80,0x00,0x21,0x40,0x09,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9520, 0, {0x20,0x14,0xcc,0x00,0xb3,0xc0,0x2e,0xc0,0x08,0x34,0x82,0x2d,0x00,0x93,0x00,0x24 }, - 16, 0x9530, 0, {0xc0,0x0b,0x30,0x02,0x0f,0x80,0x13,0x00,0x2c,0xc0,0x0a,0x34,0xa2,0xec,0x00,0xb3 }, - 16, 0x9540, 0, {0x00,0x28,0xc0,0x0b,0x00,0x02,0xcc,0x00,0x81,0x00,0x20,0xc0,0x09,0x30,0x02,0x89 }, - 16, 0x9550, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbc,0x00,0xff,0xe0,0x3f,0xc0 }, - 16, 0x9560, 0, {0x0c,0xf4,0x83,0xbd,0x00,0xdf,0x08,0x36,0x40,0x0b,0x75,0x42,0xfc,0x20,0xff,0x80 }, - 16, 0x9570, 0, {0x3b,0xc0,0x2c,0x3c,0x03,0xfc,0x00,0xbf,0x00,0xbe,0xc0,0x8d,0x90,0x0b,0xac,0x02 }, - 16, 0x9580, 0, {0xca,0x00,0x22,0x80,0x0d,0xb0,0x02,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9590, 0, {0x80,0x00,0xec,0x00,0xfb,0x08,0x1e,0xc0,0x0f,0xb0,0x13,0xec,0x00,0xeb,0x00,0x3a }, - 16, 0x95a0, 0, {0x10,0x0f,0xb0,0x23,0xac,0x01,0xfb,0x00,0x3e,0xc0,0x3c,0x84,0x03,0xec,0x00,0xfb }, - 16, 0x95b0, 0, {0x00,0x26,0x40,0x0e,0x94,0x0b,0x2c,0x00,0xf9,0x40,0x3e,0x90,0x0e,0x90,0x13,0xe0 }, - 16, 0x95c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x02,0xcf,0x00,0x3f,0xc0 }, - 16, 0x95d0, 0, {0x0d,0xf0,0x0b,0x3c,0x20,0xcf,0x00,0x3d,0x00,0x0e,0xf0,0x07,0x9c,0x01,0xcf,0x02 }, - 16, 0x95e0, 0, {0x3e,0xc0,0x0f,0xc4,0x03,0x3c,0x00,0xcf,0x00,0x0f,0xc0,0x0e,0x44,0x03,0x1f,0x02 }, - 16, 0x95f0, 0, {0xcc,0x00,0x3f,0x80,0x2c,0x70,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9600, 0, {0x81,0x04,0x6c,0x00,0x8b,0x02,0x2e,0xc0,0x0d,0xb0,0x02,0x2c,0x00,0xab,0x00,0x06 }, - 16, 0x9610, 0, {0x20,0x08,0xb0,0x03,0xfc,0x00,0xab,0x00,0x2e,0xc0,0x0f,0x80,0x06,0xbc,0x00,0xab }, - 16, 0x9620, 0, {0x04,0x3a,0xf0,0x0c,0x88,0x02,0x2c,0x00,0xc9,0x80,0x3a,0x92,0x08,0x90,0x0a,0xa0 }, - 16, 0x9630, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xab,0x00,0x2e,0xc0 }, - 16, 0x9640, 0, {0x09,0x30,0x02,0x2c,0x00,0x8b,0x00,0x26,0x60,0x0b,0xb0,0x02,0xac,0x00,0x8b,0x00 }, - 16, 0x9650, 0, {0x6e,0xc0,0x0b,0xb0,0x42,0x2c,0x00,0x9b,0x00,0x4c,0xe0,0x0a,0x90,0x22,0x2c,0x00 }, - 16, 0x9660, 0, {0x8a,0xc2,0x2c,0x40,0x08,0xb0,0x42,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9670, 0, {0x08,0x04,0x0c,0x00,0x83,0x0d,0x2c,0xc6,0x09,0x31,0x02,0x0d,0x81,0xa3,0x11,0x24 }, - 16, 0x9680, 0, {0x00,0x8a,0xb1,0xe2,0x4c,0x80,0xa3,0x00,0x2c,0xcc,0x0b,0x02,0x02,0x8c,0x80,0xa3 }, - 16, 0x9690, 0, {0x48,0x08,0xc0,0x08,0x00,0x0a,0x0d,0x00,0x81,0x00,0x28,0xc0,0x08,0x30,0x02,0x82 }, - 16, 0x96a0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xcb,0x20,0x2f,0xc8 }, - 16, 0x96b0, 0, {0x8d,0xf6,0x13,0x2d,0xb0,0x8f,0x00,0x36,0x40,0x0f,0xf0,0x02,0xad,0xa8,0x8f,0x10 }, - 16, 0x96c0, 0, {0x3f,0xca,0x0b,0x80,0x92,0x2c,0x10,0xdb,0x40,0x3f,0xc0,0x0e,0x00,0x03,0x2d,0x04 }, - 16, 0x96d0, 0, {0xc8,0x02,0x3e,0x40,0x0c,0xb0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x96e0, 0, {0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3f,0xc8,0x0e,0xf1,0x03,0xec,0x84,0xff,0x20,0x37 }, - 16, 0x96f0, 0, {0x00,0x0d,0xb2,0x03,0xbc,0xa0,0xff,0x00,0x3e,0xc9,0x0e,0x80,0x03,0xfd,0x11,0xff }, - 16, 0x9700, 0, {0x00,0x3b,0xc0,0x0e,0xc0,0x03,0xfc,0x80,0xed,0x00,0x3b,0xc0,0x0f,0xf0,0x43,0x68 }, - 16, 0x9710, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x90,0xcc,0x92,0x3b,0xc8 }, - 16, 0x9720, 0, {0x0d,0xf0,0x83,0x73,0x10,0xff,0x28,0x37,0xca,0x4f,0xb2,0x03,0xfc,0x00,0xdf,0x20 }, - 16, 0x9730, 0, {0xb3,0xc4,0x0d,0x68,0x43,0xfe,0x14,0xcb,0x84,0x33,0xe0,0x0d,0x78,0x03,0xbe,0x00 }, - 16, 0x9740, 0, {0xff,0x80,0x37,0xa0,0x0c,0xf3,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9750, 0, {0x80,0x00,0xfc,0x48,0x82,0x21,0x03,0xf4,0x0f,0xf6,0x42,0x20,0x04,0x8a,0x60,0x2b }, - 16, 0x9760, 0, {0xda,0x0b,0xf9,0x02,0x3f,0x04,0x8f,0x52,0x23,0xd5,0x4d,0x88,0x02,0xae,0x00,0xdb }, - 16, 0x9770, 0, {0x80,0x36,0xc0,0x08,0x80,0x02,0x20,0x04,0xb8,0x00,0x22,0x60,0x0d,0x74,0x03,0xe0 }, - 16, 0x9780, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0xa0,0x80,0x01,0x08,0xc0 }, - 16, 0x9790, 0, {0x4b,0x30,0x82,0x42,0x90,0xa3,0x08,0x2c,0xc8,0x1a,0x30,0x22,0x8d,0x00,0x93,0x00 }, - 16, 0x97a0, 0, {0x24,0xc8,0x09,0xa0,0x12,0x0c,0x04,0xab,0x00,0x62,0xc0,0x09,0xb0,0x02,0xcc,0x00 }, - 16, 0x97b0, 0, {0xb3,0x00,0x28,0x80,0x08,0x36,0x06,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x97c0, 0, {0xc0,0x15,0xac,0x00,0x88,0x08,0x22,0xc0,0x0a,0x30,0x1a,0x00,0x11,0x82,0x00,0x0a }, - 16, 0x97d0, 0, {0xc0,0x0b,0xb0,0x42,0x2c,0x00,0x8b,0x00,0x26,0xc0,0x09,0x91,0x02,0xec,0x20,0xbb }, - 16, 0x97e0, 0, {0x28,0x66,0xc0,0x08,0x80,0x02,0x60,0x00,0xb8,0x00,0x2a,0x40,0x81,0xb0,0x06,0xf8 }, - 16, 0x97f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xec,0x02,0xc8,0x04,0x3a,0xc0 }, - 16, 0x9800, 0, {0x89,0xb0,0x03,0x68,0x00,0xe9,0xc1,0x1e,0xc1,0x0e,0x30,0x03,0xec,0x00,0xdb,0x00 }, - 16, 0x9810, 0, {0x36,0xc1,0x0d,0x00,0x23,0x0e,0x00,0xeb,0x80,0x32,0xc8,0xcd,0x30,0x32,0xec,0x08 }, - 16, 0x9820, 0, {0xf3,0x00,0x3c,0x80,0x0c,0xb0,0x06,0x80,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9830, 0, {0xe0,0x01,0x9c,0x00,0x7c,0x00,0x3f,0xc0,0x0b,0xb0,0x43,0xfd,0x00,0xbe,0xc4,0x37 }, - 16, 0x9840, 0, {0xc0,0x1f,0xf0,0x03,0x5c,0x00,0xff,0x01,0x3b,0xc0,0x0e,0xc8,0x03,0xbf,0x20,0xdf }, - 16, 0x9850, 0, {0x00,0x3f,0xd0,0x0f,0xc0,0x13,0xb0,0x00,0x7c,0x00,0xb7,0x40,0x0f,0xf0,0x1b,0xb0 }, - 16, 0x9860, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x0c,0xd8,0x41,0x32,0xc0 }, - 16, 0x9870, 0, {0x0e,0xb0,0x07,0xa8,0x01,0x69,0x40,0xb2,0xc0,0x8d,0xb0,0xa3,0xec,0x08,0xf3,0x00 }, - 16, 0x9880, 0, {0x32,0xc0,0x0f,0x80,0x03,0xed,0x00,0xfb,0x48,0x3a,0xc0,0x0d,0xb0,0x83,0x2c,0x00 }, - 16, 0x9890, 0, {0xfb,0x20,0x3e,0x80,0x0f,0x70,0x23,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x98a0, 0, {0xc8,0x05,0x3c,0x00,0x88,0x00,0x23,0xc0,0x08,0xf0,0x06,0x2c,0x10,0x88,0x51,0x37 }, - 16, 0x98b0, 0, {0xc0,0x08,0xf0,0x07,0x7d,0x60,0x8f,0x02,0x37,0xc0,0x0b,0x8c,0x00,0x2d,0x00,0xb3 }, - 16, 0x98c0, 0, {0x00,0x38,0xc0,0x08,0x80,0x82,0x20,0x00,0xb8,0x00,0x2e,0x50,0x0b,0xf0,0x00,0x32 }, - 16, 0x98d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x98,0x00,0x28,0xc0 }, - 16, 0x98e0, 0, {0x0a,0x30,0x02,0x84,0x04,0xa3,0x00,0x00,0xc0,0x68,0x39,0x06,0x0c,0x10,0x93,0x20 }, - 16, 0x98f0, 0, {0x22,0xc0,0x9b,0x01,0xa0,0x8f,0x14,0x33,0x14,0x28,0xc0,0x09,0x3c,0x02,0x0c,0x01 }, - 16, 0x9900, 0, {0x93,0x40,0x2c,0x88,0x0b,0x30,0x02,0xb8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9910, 0, {0x60,0x01,0x1e,0x10,0x87,0x80,0x29,0xe0,0x08,0x78,0x02,0x3e,0x00,0x83,0x90,0x24 }, - 16, 0x9920, 0, {0xe0,0x08,0x78,0x10,0xce,0x04,0x07,0x91,0x25,0xe0,0x83,0xc9,0x02,0x1e,0x04,0xb7 }, - 16, 0x9930, 0, {0x84,0x2b,0xa4,0x08,0x48,0x42,0x12,0xcc,0xb4,0x80,0x2d,0x64,0x0b,0x78,0x02,0x19 }, - 16, 0x9940, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x2c,0x00,0xd0,0x10,0x28,0xc8 }, - 16, 0x9950, 0, {0x0e,0x3b,0x02,0x84,0x00,0xe3,0x40,0x30,0xc8,0x0c,0x38,0x62,0x8c,0x00,0x53,0x00 }, - 16, 0x9960, 0, {0x30,0xc4,0x1f,0x00,0x23,0x8c,0x3c,0xf3,0x80,0x18,0xc0,0x0d,0x30,0x03,0x0e,0x80 }, - 16, 0x9970, 0, {0xd3,0x10,0x3c,0x80,0x0f,0x30,0x03,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9980, 0, {0x40,0x1d,0xbd,0x00,0xf9,0x12,0xb4,0xc0,0x07,0xb0,0x03,0xcc,0x00,0x4a,0x00,0x77 }, - 16, 0x9990, 0, {0xc0,0x0e,0x71,0x43,0x6c,0x00,0xf3,0x00,0x3f,0xd0,0x1f,0xd0,0x53,0xac,0x68,0xfb }, - 16, 0x99a0, 0, {0x18,0x3d,0xc0,0x0f,0xc0,0x13,0xf0,0x50,0xfc,0x04,0x3f,0x40,0x0f,0xf4,0x03,0x90 }, - 16, 0x99b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xed,0x40,0xf8,0x04,0x3e,0xd2 }, - 16, 0x99c0, 0, {0x0f,0xb3,0x13,0xe0,0x10,0xf9,0x00,0xb2,0xcc,0x0e,0xba,0x03,0x6d,0x80,0xdb,0x02 }, - 16, 0x99d0, 0, {0x32,0xdc,0x4f,0x00,0x03,0x6c,0x04,0xf3,0x02,0x36,0x40,0x0e,0xb0,0x03,0xcc,0x00 }, - 16, 0x99e0, 0, {0x4b,0x00,0x3c,0x80,0x0c,0xf1,0x03,0x62,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x99f0, 0, {0x48,0x11,0x9c,0x00,0xb4,0x00,0x2d,0xc9,0x0b,0x70,0x82,0xdc,0x00,0xbc,0x04,0x21 }, - 16, 0x9a00, 0, {0xc4,0x4b,0x37,0x02,0x0c,0xa0,0x8f,0x74,0x21,0xc0,0x0b,0x40,0x02,0x1c,0x81,0xb7 }, - 16, 0x9a10, 0, {0x20,0x2b,0xc0,0x08,0x40,0x02,0xd0,0x02,0x84,0x00,0x2d,0x40,0x0a,0xf2,0x02,0x12 }, - 16, 0x9a20, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x80,0xb4,0xc0,0x2d,0xe4 }, - 16, 0x9a30, 0, {0x0b,0x7a,0x02,0xd2,0x00,0xb5,0x88,0x21,0xe8,0x0a,0x78,0x02,0xde,0x40,0x97,0x00 }, - 16, 0x9a40, 0, {0x21,0xe8,0x0b,0xcc,0x46,0x5e,0x28,0xb7,0xc4,0x21,0xf0,0x0a,0x78,0x02,0xfe,0x08 }, - 16, 0x9a50, 0, {0x97,0x84,0x2d,0xa0,0x08,0x78,0x02,0x70,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9a60, 0, {0x08,0x14,0xcc,0x00,0xb0,0xc0,0x2c,0xc0,0x9b,0xb0,0x02,0xcc,0x20,0xb3,0x60,0x22 }, - 16, 0x9a70, 0, {0xc0,0x0b,0x30,0x02,0x8c,0x00,0x83,0x01,0x20,0xc0,0x1b,0x06,0x16,0x4f,0x00,0xb3 }, - 16, 0x9a80, 0, {0xa0,0x2a,0xf0,0x08,0x00,0x02,0xe0,0x00,0x90,0x00,0x2c,0x40,0x0a,0x30,0x02,0x02 }, - 16, 0x9a90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x10,0xfe,0xc0,0x3e,0x80 }, - 16, 0x9aa0, 0, {0x0f,0xa0,0x03,0xf9,0x08,0xfe,0x40,0x22,0x80,0x0e,0xa0,0x03,0xe8,0x00,0xd2,0x00 }, - 16, 0x9ab0, 0, {0x32,0x80,0x8f,0xe0,0x03,0x58,0x00,0xf6,0x00,0x33,0xb0,0x0e,0x20,0x02,0xe8,0x0c }, - 16, 0x9ac0, 0, {0xd2,0x02,0x3c,0x80,0x0c,0xa0,0x03,0x7a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9ad0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x20,0x3e,0x01,0x0b,0x80,0x03,0xe0,0x00,0xf0,0x40,0x3e }, - 16, 0x9ae0, 0, {0x00,0x57,0x80,0x23,0x00,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x84,0x03,0xa0,0x30,0x38 }, - 16, 0x9af0, 0, {0x00,0x3a,0x08,0x0f,0xc4,0x03,0xf0,0x00,0xec,0x00,0x3f,0x10,0x0f,0x80,0x03,0xd2 }, - 16, 0x9b00, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x01,0x3c,0x48 }, - 16, 0x9b10, 0, {0x4c,0x90,0x0b,0x24,0x01,0xc9,0xc0,0x32,0x40,0xac,0x90,0x03,0xe4,0x00,0xd9,0x40 }, - 16, 0x9b20, 0, {0x30,0x40,0x0d,0x9a,0x03,0x22,0x84,0xc8,0x14,0x32,0x40,0x0e,0x90,0x03,0x24,0x00 }, - 16, 0x9b30, 0, {0xc9,0x00,0x82,0x68,0x2c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9b40, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x2e,0x40,0x08,0x90,0x22,0x24,0x00,0x89,0x02,0x82 }, - 16, 0x9b50, 0, {0x40,0x08,0x90,0x02,0xe7,0x40,0x89,0x80,0x36,0x41,0x8d,0x18,0x02,0xa0,0x24,0xa8 }, - 16, 0x9b60, 0, {0x04,0x62,0x40,0x08,0x94,0x83,0x24,0x00,0x89,0x01,0x22,0x72,0x08,0x90,0x0b,0x20 }, - 16, 0x9b70, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x99,0x00,0x2a,0x40 }, - 16, 0x9b80, 0, {0x28,0x90,0x12,0x04,0x00,0x89,0x00,0x22,0x40,0x08,0x90,0x02,0xa4,0x20,0x99,0x00 }, - 16, 0x9b90, 0, {0x22,0x40,0x18,0x90,0x06,0x20,0x01,0x88,0x08,0x62,0x40,0x0a,0x90,0x02,0x34,0x10 }, - 16, 0x9ba0, 0, {0x8d,0x81,0x23,0x41,0x08,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9bb0, 0, {0x08,0x04,0x04,0x80,0x81,0x04,0x2c,0x48,0x08,0x12,0x02,0x04,0x02,0x83,0x20,0x20 }, - 16, 0x9bc0, 0, {0x48,0x08,0x12,0x02,0xc4,0x80,0x83,0x60,0x24,0x48,0x19,0x34,0x62,0xa5,0x04,0xa1 }, - 16, 0x9bd0, 0, {0x02,0x60,0x40,0x08,0xd0,0x02,0x54,0x00,0x8d,0x00,0x29,0x40,0x08,0x12,0x82,0x02 }, - 16, 0x9be0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x3a,0x80 }, - 16, 0x9bf0, 0, {0x0c,0x85,0x02,0x21,0x44,0x88,0x50,0x32,0x14,0x4c,0x80,0x43,0xe0,0x00,0xd8,0x00 }, - 16, 0x9c00, 0, {0x22,0x14,0x0c,0x80,0x03,0x20,0x00,0xc8,0x00,0xa2,0x00,0x0e,0x80,0x03,0x20,0x00 }, - 16, 0x9c10, 0, {0xc8,0x00,0x33,0x00,0x0c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9c20, 0, {0x98,0x1d,0xe4,0x44,0xfd,0x00,0x3e,0x44,0x0f,0x91,0x03,0xf4,0x10,0xff,0x10,0x3e }, - 16, 0x9c30, 0, {0x44,0x0f,0x91,0x03,0xe4,0x40,0xf9,0x10,0x3e,0x44,0x0b,0xf0,0x13,0xe5,0x10,0xf9 }, - 16, 0x9c40, 0, {0x40,0x3f,0x4a,0x2f,0x92,0x8a,0xa4,0xa2,0xf9,0x28,0x36,0x40,0x0f,0x92,0x83,0xa6 }, - 16, 0x9c50, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xe6,0xc0,0xc1,0x00,0x3f,0x69 }, - 16, 0x9c60, 0, {0x0c,0x9a,0x43,0x6c,0x00,0xfd,0xa0,0x3e,0x78,0x2c,0xd8,0x07,0xd6,0x02,0xd5,0x96 }, - 16, 0x9c70, 0, {0x32,0x78,0x0d,0x90,0x03,0x27,0x00,0xfd,0xa0,0x35,0x50,0x06,0xd4,0x03,0xe5,0x00 }, - 16, 0x9c80, 0, {0xfd,0x40,0xb3,0x40,0x0f,0x98,0xa3,0x46,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9c90, 0, {0x38,0x10,0xe3,0xc2,0x88,0x88,0x2e,0x14,0xa8,0x8a,0xc2,0x22,0xa0,0xb8,0xc0,0x2c }, - 16, 0x9ca0, 0, {0x24,0x48,0x84,0x02,0xe1,0x00,0x98,0xc4,0x20,0x3c,0x08,0x8a,0x82,0x23,0x80,0xb8 }, - 16, 0x9cb0, 0, {0x04,0x22,0x20,0x08,0x88,0x03,0xa2,0x00,0xb8,0xa0,0x22,0x00,0x0b,0x88,0x02,0x0e }, - 16, 0x9cc0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0xa1,0x20,0x6c,0x40 }, - 16, 0x9cd0, 0, {0x0a,0x14,0x02,0x44,0x04,0xa1,0x68,0x2c,0x48,0x08,0x14,0x02,0xc5,0x00,0x81,0x60 }, - 16, 0x9ce0, 0, {0x20,0x48,0x19,0x90,0x02,0x85,0x81,0xb1,0x40,0x24,0x68,0x0a,0x12,0x42,0xc4,0x80 }, - 16, 0x9cf0, 0, {0xb9,0x20,0x20,0x40,0x8b,0x10,0x82,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9d00, 0, {0x18,0x05,0xa4,0x10,0xa9,0x00,0x6e,0xc0,0x0a,0x10,0x02,0x24,0x14,0xb9,0x00,0x2e }, - 16, 0x9d10, 0, {0x40,0x08,0x90,0x12,0xe4,0x00,0x99,0x00,0x22,0x40,0x08,0x80,0x06,0xa0,0x60,0xb9 }, - 16, 0x9d20, 0, {0x09,0x22,0x60,0x08,0x90,0x02,0xa4,0x00,0xb9,0x00,0x02,0x40,0x0b,0x10,0x06,0x06 }, - 16, 0x9d30, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0xe9,0x80,0x3e,0x41 }, - 16, 0x9d40, 0, {0x0e,0x90,0x03,0x64,0x00,0xe9,0xc0,0x3e,0x40,0x0c,0x90,0x02,0xe4,0x00,0xc9,0x00 }, - 16, 0x9d50, 0, {0x22,0x41,0x0d,0x80,0x02,0xa3,0x04,0xf1,0x40,0x36,0x40,0x0e,0x90,0x02,0xe4,0x00 }, - 16, 0x9d60, 0, {0xf1,0x00,0x12,0x40,0x0f,0x90,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9d70, 0, {0x28,0x01,0xa4,0x00,0xd9,0x22,0x3e,0x42,0x0d,0x90,0x03,0xe4,0x00,0xb9,0xc4,0x3c }, - 16, 0x9d80, 0, {0x40,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x02,0xae,0x40,0x0f,0x80,0x4b,0x62,0x10,0xf9 }, - 16, 0x9d90, 0, {0x20,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x02,0x7e,0x41,0x0f,0x90,0x13,0xca }, - 16, 0x9da0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x80,0x00,0xc8,0x00,0x38,0x00 }, - 16, 0x9db0, 0, {0x0f,0x80,0x20,0xe0,0x00,0xa8,0x20,0x32,0x00,0x0c,0x80,0x07,0xe0,0x80,0xc8,0x00 }, - 16, 0x9dc0, 0, {0x38,0x00,0x0d,0x80,0x83,0x21,0x10,0xf8,0x60,0x32,0x00,0x8e,0x80,0xb3,0x20,0x08 }, - 16, 0x9dd0, 0, {0xf8,0x00,0x3e,0x00,0x0c,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9de0, 0, {0x28,0x05,0x28,0x04,0x8a,0x00,0x33,0x90,0x43,0xa0,0x22,0x28,0x00,0x8e,0x80,0x76 }, - 16, 0x9df0, 0, {0x80,0x08,0xe1,0x03,0x19,0x00,0x86,0x80,0x22,0x80,0x0d,0x60,0x01,0x78,0x00,0xbe }, - 16, 0x9e00, 0, {0x00,0x36,0x80,0x0c,0xe4,0x02,0xa8,0x10,0xbe,0xa0,0x2f,0x80,0x0d,0xa0,0x02,0x0a }, - 16, 0x9e10, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x11,0x4c,0x04,0x03,0x04,0x2c,0xd4 }, - 16, 0x9e20, 0, {0x0b,0x30,0x02,0x4c,0x01,0xa3,0xc4,0x20,0xc0,0x28,0x35,0x02,0x86,0x00,0x83,0x80 }, - 16, 0x9e30, 0, {0x28,0xc0,0x08,0x38,0x06,0x0e,0x94,0x30,0xc0,0xa2,0xc0,0x0b,0x3c,0x02,0x0c,0x00 }, - 16, 0x9e40, 0, {0xb3,0x80,0x2c,0x48,0x08,0x30,0x02,0x8a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9e50, 0, {0xa0,0x01,0x0c,0x04,0x8f,0x80,0x21,0xc1,0x1b,0x72,0x42,0x1e,0xc0,0x83,0x88,0x21 }, - 16, 0x9e60, 0, {0xc0,0x18,0x28,0x06,0x10,0x21,0x86,0x38,0x21,0xc0,0x19,0xf7,0x02,0x5d,0xc0,0xb4 }, - 16, 0x9e70, 0, {0x41,0x27,0xd0,0x08,0x78,0xc6,0x9c,0x00,0xb7,0x00,0x2f,0x60,0x09,0x72,0x02,0x28 }, - 16, 0x9e80, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x02,0xc7,0x80,0x2d,0xa0 }, - 16, 0x9e90, 0, {0x0f,0x3e,0x03,0xfe,0x80,0xa7,0x80,0xa1,0xe0,0x0c,0x78,0x02,0x94,0x00,0x85,0xa0 }, - 16, 0x9ea0, 0, {0x39,0xe4,0x0c,0x78,0x13,0x1e,0x90,0xb5,0x84,0x31,0xe0,0x0f,0xf8,0x87,0x1e,0x04 }, - 16, 0x9eb0, 0, {0xf7,0x80,0x3d,0x60,0x0c,0x3b,0x03,0xaa,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9ec0, 0, {0x08,0x1d,0xad,0xe4,0xfb,0x54,0x3e,0x80,0x0f,0xb4,0x23,0xec,0x32,0xfb,0x00,0x3e }, - 16, 0x9ed0, 0, {0xd8,0x4f,0xa0,0x03,0xe4,0x00,0xf9,0x00,0x3e,0xc0,0x0f,0x30,0x33,0xec,0x04,0xf2 }, - 16, 0x9ee0, 0, {0x01,0x3e,0xc0,0x0f,0xb2,0x03,0xfe,0x10,0xfb,0x68,0x3c,0x41,0x0f,0xf0,0x43,0x82 }, - 16, 0x9ef0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xcf,0xe4,0x3f,0xe4 }, - 16, 0x9f00, 0, {0x0c,0xfc,0x03,0x7e,0x80,0xcf,0x81,0x33,0xfa,0x0f,0xf8,0x03,0xf6,0x00,0xff,0x80 }, - 16, 0x9f10, 0, {0x3f,0xe2,0x0f,0x79,0x03,0x3e,0x40,0xf4,0x80,0x33,0x60,0x0c,0xe8,0x03,0x3e,0x00 }, - 16, 0x9f20, 0, {0xff,0x80,0x33,0x60,0x0c,0xf8,0x83,0x50,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9f30, 0, {0xa8,0x11,0x9c,0x00,0xd7,0xa0,0x2d,0xc4,0x08,0xba,0x02,0x3c,0xa0,0x87,0x20,0x21 }, - 16, 0x9f40, 0, {0xc0,0x0f,0x52,0x03,0xd4,0x00,0xb6,0x10,0x2d,0xc0,0x8b,0x73,0x03,0x5c,0x40,0xb4 }, - 16, 0x9f50, 0, {0xb0,0x2b,0x48,0x28,0x41,0x02,0x0c,0x00,0xbf,0x18,0x35,0x46,0x28,0x72,0x42,0x2a }, - 16, 0x9f60, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x9c,0x00,0x87,0x41,0x2d,0x44 }, - 16, 0x9f70, 0, {0x0a,0x73,0x02,0x9c,0xc4,0x81,0x00,0x6d,0xc8,0x8b,0x70,0x02,0xd4,0x00,0xb7,0x00 }, - 16, 0x9f80, 0, {0x2d,0xc0,0x0b,0xf0,0x46,0x9c,0x55,0xb4,0x20,0x25,0x40,0x18,0x60,0x82,0x1c,0x00 }, - 16, 0x9f90, 0, {0xb7,0x00,0x23,0x40,0x08,0x70,0x46,0x44,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9fa0, 0, {0x60,0x14,0xcc,0x00,0x93,0x00,0x2c,0x40,0x0b,0xb0,0x02,0x0c,0x82,0x80,0xc0,0x20 }, - 16, 0x9fb0, 0, {0xc0,0x0a,0x10,0x02,0x04,0x00,0xb3,0x00,0x2c,0xc0,0x1b,0x30,0x00,0xcd,0x01,0xb0 }, - 16, 0x9fc0, 0, {0x40,0xac,0x78,0x88,0x8c,0x06,0x0d,0x60,0xb3,0x4c,0x24,0x12,0x08,0x30,0x0a,0x18 }, - 16, 0x9fd0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x15,0xbc,0x00,0xc7,0x00,0x2e,0x40 }, - 16, 0x9fe0, 0, {0x0e,0xf0,0x2a,0xbf,0x00,0xc8,0xc8,0xbf,0xc0,0x0b,0x90,0x02,0xe4,0x04,0xbf,0x00 }, - 16, 0x9ff0, 0, {0x3f,0xc0,0x0f,0xb2,0x0a,0xac,0x00,0xf8,0x80,0x34,0x49,0x0c,0xb9,0x0b,0x3f,0x00 }, - 16, 0xa000, 0, {0xfb,0xc0,0x30,0xf0,0x0c,0xf0,0x03,0x6e,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa010, 0, {0x80,0x00,0xcc,0x00,0xfb,0x80,0x3e,0x41,0x2c,0xb0,0x13,0xac,0x00,0xf8,0x00,0x3e }, - 16, 0xa020, 0, {0xc1,0x0f,0xa0,0x03,0xe8,0x00,0xfa,0x40,0x3e,0xc0,0x0f,0xb0,0x0b,0x6d,0x40,0xf8 }, - 16, 0xa030, 0, {0x10,0x3a,0x40,0x0f,0xb0,0x03,0xec,0x10,0xfe,0x40,0x3e,0xc0,0x0f,0xf0,0x03,0xe1 }, - 16, 0xa040, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xec,0x0c,0xdf,0x00,0x3b,0x80 }, - 16, 0xa050, 0, {0x0f,0xf0,0x0b,0x3c,0x08,0xe7,0x08,0x33,0xc0,0x0b,0xd0,0x23,0x74,0x00,0x54,0x00 }, - 16, 0xa060, 0, {0x33,0xc0,0x0f,0xf0,0x83,0xbe,0x20,0xfd,0x0c,0x3b,0x60,0x2c,0xe0,0x03,0x3c,0x00 }, - 16, 0xa070, 0, {0xcf,0x12,0x33,0x50,0x0c,0x30,0x03,0x80,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa080, 0, {0x81,0x04,0x6c,0x04,0xab,0x00,0x22,0xa0,0x0b,0xb0,0x06,0x0c,0x00,0xab,0x40,0x36 }, - 16, 0xa090, 0, {0xc0,0x0b,0xa8,0x02,0x66,0x00,0xb8,0x00,0x36,0xc1,0x0b,0x34,0x43,0xee,0x00,0xb2 }, - 16, 0xa0a0, 0, {0x00,0x22,0x60,0x08,0xb4,0x82,0x8c,0x04,0x8a,0x21,0x22,0x40,0x08,0xb0,0x02,0x20 }, - 16, 0xa0b0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x9b,0x00,0x2a,0x20 }, - 16, 0xa0c0, 0, {0x0b,0xb0,0x02,0x2c,0x00,0x88,0xc5,0x22,0xc0,0x0b,0x88,0x82,0xe6,0x01,0xbb,0x08 }, - 16, 0xa0d0, 0, {0x22,0xc0,0x0a,0xb2,0x82,0xac,0x60,0xb8,0x02,0x4a,0xc4,0x08,0xb1,0x02,0x2c,0x00 }, - 16, 0xa0e0, 0, {0x83,0x00,0x22,0xc0,0x08,0xb0,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa0f0, 0, {0x08,0x04,0x0c,0x00,0xab,0x20,0x20,0x01,0x0b,0x32,0x06,0x2c,0x00,0xa0,0x00,0x20 }, - 16, 0xa100, 0, {0xc0,0x09,0x04,0x22,0xc4,0x00,0xb2,0x00,0x24,0xc1,0x8b,0xb0,0x02,0x4c,0x00,0xb0 }, - 16, 0xa110, 0, {0x00,0x62,0xc0,0x48,0x30,0x02,0xac,0x10,0x82,0x00,0x20,0xc0,0x08,0x30,0x02,0x02 }, - 16, 0xa120, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x08,0xdf,0x2a,0x3a,0x00 }, - 16, 0xa130, 0, {0x0f,0xf5,0x12,0x3c,0x10,0xc9,0x00,0xa3,0xc0,0x0f,0x80,0x53,0xec,0x01,0xda,0x00 }, - 16, 0xa140, 0, {0x33,0xc0,0x0e,0xb0,0x03,0xac,0x04,0xf8,0x70,0x3a,0xc0,0x0c,0x60,0x43,0x2c,0x42 }, - 16, 0xa150, 0, {0xcd,0x00,0xb2,0x40,0x2c,0xf0,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa160, 0, {0xa0,0x19,0xfc,0x00,0xfb,0x01,0x3d,0x00,0x0f,0xb4,0x17,0xfc,0x00,0x3c,0x00,0x3f }, - 16, 0xa170, 0, {0xc0,0x4f,0xc0,0x03,0x74,0x08,0xfe,0x00,0x3f,0xc0,0x4f,0xf0,0x03,0xfc,0x08,0xf8 }, - 16, 0xa180, 0, {0x30,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x04,0xfc,0x00,0x3d,0x00,0x0f,0xf0,0x03,0xe8 }, - 16, 0xa190, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf4,0x90,0xef,0x00,0x3f,0xd8 }, - 16, 0xa1a0, 0, {0x0e,0xf3,0x03,0x2c,0x01,0xd4,0x80,0x37,0xcc,0x0d,0x89,0x43,0x12,0x50,0xec,0x2c }, - 16, 0xa1b0, 0, {0x32,0x05,0x0d,0xb0,0x53,0x3c,0xd4,0xc5,0x94,0x7f,0xa0,0x8f,0xf0,0x43,0x30,0x00 }, - 16, 0xa1c0, 0, {0xdc,0x00,0x33,0x00,0x0c,0x48,0x07,0xf0,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa1d0, 0, {0x80,0x10,0xe6,0x40,0x8b,0x70,0x2f,0xdc,0x08,0xf7,0x02,0x0c,0x80,0x8a,0x20,0x00 }, - 16, 0xa1e0, 0, {0xc8,0x4a,0x22,0x02,0xa0,0x00,0x8a,0x48,0x22,0x58,0x88,0xfd,0x02,0xad,0x02,0xa9 }, - 16, 0xa1f0, 0, {0x20,0x1e,0xa0,0x03,0x80,0x02,0x2c,0x04,0x8b,0x00,0x22,0xc0,0x4c,0x88,0x07,0x60 }, - 16, 0xa200, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x00,0x23,0x2c,0x2c,0xc9 }, - 16, 0xa210, 0, {0x02,0x30,0x02,0x0c,0x68,0xa0,0x28,0x2c,0xd0,0x09,0x12,0x02,0x84,0x00,0xa0,0x21 }, - 16, 0xa220, 0, {0x20,0x18,0x19,0x30,0x22,0x80,0xd0,0x83,0x06,0x0c,0xa0,0x0b,0xb0,0x06,0x00,0x12 }, - 16, 0xa230, 0, {0xa0,0x00,0x20,0x00,0x29,0x00,0x0e,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa240, 0, {0xc0,0x11,0xa8,0x30,0x8b,0x00,0x2e,0xc0,0x4a,0x30,0x0a,0x2c,0x14,0xa0,0x80,0x0a }, - 16, 0xa250, 0, {0xc1,0x08,0x88,0x86,0x87,0x00,0x83,0x00,0x22,0x49,0x08,0xb0,0x06,0xa0,0x40,0xab }, - 16, 0xa260, 0, {0x20,0x22,0x20,0x0b,0x80,0x0a,0x0c,0x04,0xab,0x02,0x22,0xc0,0x88,0x80,0x02,0xf0 }, - 16, 0xa270, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xef,0x40,0xeb,0x06,0x3e,0xc0 }, - 16, 0xa280, 0, {0x0e,0xb0,0x03,0x2c,0x02,0xf9,0xa0,0x3e,0xc0,0x0d,0x8c,0x03,0xaa,0x10,0xe9,0x40 }, - 16, 0xa290, 0, {0xb2,0x48,0x0d,0xb0,0x43,0xad,0x00,0xcb,0x86,0x2e,0x20,0x0f,0x30,0x03,0x24,0x00 }, - 16, 0xa2a0, 0, {0xf9,0x80,0x32,0xc0,0x0d,0x0c,0xc2,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa2b0, 0, {0xe0,0x01,0x94,0x00,0xff,0x00,0x3d,0xc0,0x0d,0xf0,0x03,0x7c,0x00,0xdf,0x00,0x37 }, - 16, 0xa2c0, 0, {0xc0,0x0f,0xe0,0x03,0xf0,0x00,0xfe,0x20,0x3f,0x40,0x0f,0x70,0x03,0xfe,0x00,0xff }, - 16, 0xa2d0, 0, {0x82,0x7f,0x00,0x0f,0xc0,0x03,0xf9,0x04,0xde,0x20,0xbd,0x00,0x0f,0xd9,0x0b,0x7c }, - 16, 0xa2e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x01,0xcb,0x00,0x3e,0xc0 }, - 16, 0xa2f0, 0, {0x2c,0xb0,0x0b,0x2c,0x00,0xe8,0x40,0x3e,0xc0,0x0f,0x94,0x07,0x29,0x00,0xc9,0x40 }, - 16, 0xa300, 0, {0xb2,0xc0,0x0f,0xb0,0x03,0x01,0x02,0xcb,0x00,0x32,0x04,0x4f,0xf0,0x43,0x34,0xc0 }, - 16, 0xa310, 0, {0xb5,0x1a,0x3f,0xc1,0x0f,0x80,0x93,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa320, 0, {0xc8,0x05,0x28,0x00,0x8f,0x00,0x2f,0xc0,0x08,0xf0,0x02,0x3c,0x04,0xd8,0x00,0x2b }, - 16, 0xa330, 0, {0xc0,0x0c,0x80,0x45,0x60,0x00,0x7b,0x58,0x22,0xc8,0x0b,0xfa,0x01,0x61,0x40,0x8b }, - 16, 0xa340, 0, {0x00,0x32,0x04,0x4b,0xce,0x02,0x28,0x00,0x3a,0x40,0x2e,0x07,0x0b,0x90,0x02,0x26 }, - 16, 0xa350, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x83,0x01,0x4c,0xc0 }, - 16, 0xa360, 0, {0x0b,0x30,0x02,0xec,0x10,0x90,0x00,0x2a,0xc0,0x0a,0x80,0x06,0xc0,0x04,0x83,0x04 }, - 16, 0xa370, 0, {0xa2,0x89,0x19,0x30,0x06,0xcc,0x00,0x83,0x00,0x20,0x90,0x0b,0x30,0xc2,0x48,0x00 }, - 16, 0xa380, 0, {0xb2,0x40,0x24,0x20,0x0b,0x09,0x00,0xb8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa390, 0, {0x20,0x01,0x06,0x04,0x87,0xa4,0x2d,0xe0,0x09,0x38,0x02,0xde,0x00,0x9e,0x81,0x29 }, - 16, 0xa3a0, 0, {0xe0,0x08,0x78,0x52,0xfa,0xc0,0x96,0x80,0x01,0xa0,0x8b,0x3a,0x22,0xce,0x40,0x8f }, - 16, 0xa3b0, 0, {0xb0,0x25,0xa0,0x0b,0x08,0x02,0x56,0x08,0xb5,0x90,0x2d,0xe4,0x4b,0xd8,0x22,0x0c }, - 16, 0xa3c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x02,0x83,0x80,0x2e,0xe8 }, - 16, 0xa3d0, 0, {0x0b,0x38,0x13,0xce,0x41,0xd3,0x10,0x28,0xc0,0x0e,0x3a,0x02,0xc6,0x08,0x4b,0x40 }, - 16, 0xa3e0, 0, {0x30,0x60,0x0d,0x3b,0x27,0xcf,0xc4,0xc3,0xa0,0x30,0x00,0x0f,0x30,0x43,0x48,0x40 }, - 16, 0xa3f0, 0, {0xf2,0x00,0x3c,0x04,0x0f,0x02,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa400, 0, {0x40,0x1d,0xb8,0x00,0xff,0x00,0x3f,0xc4,0x0e,0xf1,0x03,0x3c,0x00,0xff,0x01,0x33 }, - 16, 0xa410, 0, {0xc0,0x4d,0xb1,0x07,0x7c,0x90,0xff,0x00,0x3f,0x40,0x03,0xf1,0x03,0x70,0x00,0xfb }, - 16, 0xa420, 0, {0x10,0x3b,0x00,0x0f,0xc0,0x0b,0xb4,0x00,0xfd,0x00,0x3f,0xc4,0x0f,0xd0,0x03,0x90 }, - 16, 0xa430, 0, {0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x04,0xfb,0x84,0x3a,0xc2 }, - 16, 0xa440, 0, {0x4c,0xb4,0x93,0x2c,0x04,0xe9,0x00,0x3a,0xc4,0x8d,0x08,0x03,0x2e,0x00,0xcb,0x01 }, - 16, 0xa450, 0, {0x32,0x80,0x8f,0xb2,0x83,0xec,0x00,0xcb,0x80,0x32,0x00,0x0f,0xf9,0x03,0x3c,0x10 }, - 16, 0xa460, 0, {0xdf,0x81,0xb3,0xe0,0x8c,0xa0,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa470, 0, {0x48,0x11,0x94,0x08,0xb7,0x04,0x24,0xc8,0x1a,0x30,0x4a,0x1d,0x00,0xb7,0x01,0x2d }, - 16, 0xa480, 0, {0xc0,0x88,0x70,0x06,0x1c,0x00,0x82,0x00,0x21,0x80,0x4b,0x76,0x12,0xdc,0x00,0x87 }, - 16, 0xa490, 0, {0x00,0x29,0x40,0x8b,0x40,0x02,0x10,0x00,0xbc,0x00,0x20,0x01,0x28,0x70,0x03,0xb2 }, - 16, 0xa4a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x00,0xb3,0x90,0x2d,0xe4 }, - 16, 0xa4b0, 0, {0x09,0x79,0x02,0x1e,0x80,0xa7,0x80,0x2c,0xe8,0x19,0xf8,0x12,0x5e,0x01,0x87,0x80 }, - 16, 0xa4c0, 0, {0x25,0xe0,0x4b,0x78,0x06,0xd2,0x00,0x97,0x80,0x21,0x62,0x0b,0x3a,0x02,0x1e,0x00 }, - 16, 0xa4d0, 0, {0xb7,0x86,0x29,0xf0,0x08,0x68,0x06,0xe0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa4e0, 0, {0x48,0x14,0xcf,0xc0,0xb3,0x00,0x24,0xc0,0x8a,0x30,0x32,0x0c,0x00,0xb3,0x08,0x2c }, - 16, 0xa4f0, 0, {0xc0,0x08,0x30,0x12,0x0e,0x20,0x83,0x00,0x24,0xf1,0x0b,0x30,0x06,0xce,0x00,0x83 }, - 16, 0xa500, 0, {0x90,0x28,0x60,0x0b,0x00,0x2a,0x21,0x80,0xb0,0x08,0x28,0x00,0x08,0x37,0x02,0x92 }, - 16, 0xa510, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x00,0xfa,0x00,0x3e,0x80 }, - 16, 0xa520, 0, {0x4d,0xa0,0x03,0x28,0x00,0xee,0x41,0x3e,0x80,0x0d,0xe0,0x03,0x78,0x00,0x8e,0x40 }, - 16, 0xa530, 0, {0x27,0xa8,0x0b,0xa0,0x03,0xfb,0x02,0xca,0x82,0x33,0xa0,0x0f,0xa0,0x13,0x29,0x00 }, - 16, 0xa540, 0, {0xfa,0x40,0x3a,0x80,0x0c,0x6c,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa550, 0, {0x48,0x00,0xc0,0x00,0xf8,0x00,0x3a,0x00,0x0c,0x80,0x03,0xe0,0x08,0xf8,0x00,0x3e }, - 16, 0xa560, 0, {0x00,0x8f,0x80,0x23,0xa0,0x42,0xf8,0x09,0xba,0x10,0x4f,0x80,0x03,0xe0,0x60,0xf8 }, - 16, 0xa570, 0, {0x00,0x3e,0x20,0x0f,0xc0,0x03,0xf0,0x00,0xfc,0x00,0x27,0x00,0x8f,0x80,0x03,0x92 }, - 16, 0xa580, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe5,0x00,0x89,0x00,0x3e,0x40 }, - 16, 0xa590, 0, {0x6e,0x90,0x03,0xa4,0x08,0xc9,0x00,0x3c,0x40,0x0d,0x90,0x03,0x24,0x10,0xf9,0xa0 }, - 16, 0xa5a0, 0, {0x32,0x42,0x0c,0x90,0x13,0xc4,0x00,0xc9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x40 }, - 16, 0xa5b0, 0, {0xc9,0x20,0x3e,0x52,0xcf,0x90,0x09,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa5c0, 0, {0x80,0x04,0x66,0x00,0x89,0x04,0x2e,0x40,0x08,0x90,0x02,0x24,0x00,0xd9,0x00,0x3a }, - 16, 0xa5d0, 0, {0x41,0x08,0x90,0x05,0xa4,0x00,0xb9,0x40,0xa2,0x40,0x0d,0x90,0x02,0xe5,0x46,0x89 }, - 16, 0xa5e0, 0, {0x00,0x2e,0x40,0x0b,0x90,0x12,0xe5,0x00,0xa9,0xc8,0x2e,0x61,0x8b,0x94,0x42,0x20 }, - 16, 0xa5f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xa9,0x00,0x6c,0x40 }, - 16, 0xa600, 0, {0x48,0x10,0x22,0x84,0x03,0xa9,0x00,0x2e,0x40,0x09,0x90,0x02,0xe4,0x04,0xb1,0x08 }, - 16, 0xa610, 0, {0x28,0x40,0x18,0x98,0x02,0xe5,0x00,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0xf4,0x20 }, - 16, 0xa620, 0, {0x8d,0x00,0x2f,0x40,0x0b,0x94,0x42,0x86,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa630, 0, {0x08,0x04,0x04,0x80,0xa1,0x24,0x2c,0x48,0x18,0x12,0x02,0x04,0x80,0xa1,0x00,0x28 }, - 16, 0xa640, 0, {0x48,0x08,0x10,0x02,0x84,0x00,0x91,0x20,0x20,0x48,0x09,0x12,0x02,0xc4,0x94,0x81 }, - 16, 0xa650, 0, {0x00,0x2c,0x61,0x0b,0x5a,0x82,0xd4,0xa0,0xa5,0x28,0x2d,0x4a,0x0b,0x90,0x02,0x82 }, - 16, 0xa660, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x02,0xe8,0x50,0x2e,0x14 }, - 16, 0xa670, 0, {0x0e,0x85,0x03,0xa1,0x40,0xa8,0x50,0x3e,0x14,0x0d,0x85,0x01,0x81,0x40,0xf8,0x52 }, - 16, 0xa680, 0, {0x32,0x94,0x0c,0x80,0x13,0xc1,0x42,0xc0,0x51,0x3e,0x00,0x8f,0x82,0x03,0xe0,0x80 }, - 16, 0xa690, 0, {0xc8,0x20,0x3f,0x08,0x0f,0x80,0x03,0xae,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa6a0, 0, {0x98,0x19,0xf4,0x50,0xd9,0x11,0x3e,0x44,0x8f,0x91,0x43,0xe4,0x40,0xdd,0x00,0x3a }, - 16, 0xa6b0, 0, {0x44,0x4f,0xd0,0x27,0xb4,0x00,0xfd,0x12,0x3f,0x44,0x4f,0x91,0x43,0xf4,0x40,0xfd }, - 16, 0xa6c0, 0, {0x00,0x3f,0x41,0x0f,0x92,0x83,0xe4,0xa0,0xf9,0x28,0x3e,0x4a,0x0f,0xd0,0x03,0x66 }, - 16, 0xa6d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xf6,0x80,0xe9,0xc0,0x3e,0x78 }, - 16, 0xa6e0, 0, {0x8f,0x9b,0x03,0xa7,0x80,0xc9,0x40,0x36,0x78,0x0f,0x10,0x23,0xe5,0x04,0xdd,0xa4 }, - 16, 0xa6f0, 0, {0x33,0x62,0x0f,0xda,0x03,0xf6,0x60,0xc9,0x10,0x33,0x40,0x0e,0x98,0x93,0xe6,0x30 }, - 16, 0xa700, 0, {0xc9,0xc9,0x32,0x78,0x8c,0xd0,0x0b,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa710, 0, {0x38,0x10,0xe0,0x00,0x88,0xe2,0x2e,0x30,0x0b,0x88,0x42,0x23,0x40,0xa0,0xa1,0x22 }, - 16, 0xa720, 0, {0x38,0x0b,0x8a,0x02,0xe2,0x80,0xaa,0xe0,0x22,0x30,0x0b,0x80,0x23,0xab,0x02,0x88 }, - 16, 0xa730, 0, {0xa0,0x2a,0x00,0x0b,0x8c,0x02,0xe3,0x00,0x88,0xe0,0x23,0x38,0x08,0x80,0x02,0x0e }, - 16, 0xa740, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xa1,0x44,0x28,0x58 }, - 16, 0xa750, 0, {0x43,0x16,0x22,0x84,0x81,0x81,0x20,0x2c,0x58,0x49,0x10,0x80,0xc4,0x81,0x91,0x48 }, - 16, 0xa760, 0, {0x6c,0x4a,0x0b,0x14,0x02,0x44,0x84,0x81,0x01,0x60,0x40,0x0a,0x52,0x86,0xd4,0xa0 }, - 16, 0xa770, 0, {0x85,0x00,0xa1,0x50,0x68,0x90,0x06,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa780, 0, {0x18,0x05,0xa6,0x00,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0x04,0x00,0xa9,0x60,0x22 }, - 16, 0xa790, 0, {0x40,0x0b,0x95,0x02,0xe4,0x10,0xb1,0x00,0x4e,0x40,0x0b,0x90,0x66,0xac,0x80,0x89 }, - 16, 0xa7a0, 0, {0x00,0x2a,0x60,0x0b,0x90,0x52,0xf4,0x00,0x85,0x00,0x21,0x40,0x08,0x90,0x02,0xc6 }, - 16, 0xa7b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe6,0x20,0xe9,0x00,0x3e,0x40 }, - 16, 0xa7c0, 0, {0x0f,0x90,0x03,0xa4,0x10,0xc9,0x00,0x36,0x40,0x0f,0x94,0x01,0xe5,0x20,0xd9,0x40 }, - 16, 0xa7d0, 0, {0xba,0x68,0x8f,0x90,0x07,0xe6,0x00,0xc9,0x10,0x32,0x62,0x0e,0x90,0x02,0xe4,0x18 }, - 16, 0xa7e0, 0, {0xc9,0x00,0x32,0x40,0x0c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa7f0, 0, {0x28,0x01,0xa4,0x00,0xf9,0x04,0x3e,0x40,0x0b,0x90,0x03,0x64,0x00,0xf9,0x00,0x3e }, - 16, 0xa800, 0, {0x40,0x8f,0x90,0x03,0xe4,0x00,0xe9,0x02,0x72,0x68,0x0f,0x90,0x03,0xe6,0x00,0xf9 }, - 16, 0xa810, 0, {0x01,0x3e,0x42,0x0f,0x90,0x03,0xc4,0x02,0xf9,0x04,0x3e,0x40,0x4f,0x90,0x03,0x1a }, - 16, 0xa820, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x80,0x02,0xc8,0x00,0x32,0x00 }, - 16, 0xa830, 0, {0x0c,0x80,0x03,0x60,0x00,0xc8,0x40,0x36,0x00,0x0f,0x84,0x03,0xa0,0x00,0xd8,0x50 }, - 16, 0xa840, 0, {0xb2,0x10,0x8c,0x81,0x03,0xc1,0x20,0xc8,0x00,0x3e,0x00,0x0f,0xc0,0x13,0xf0,0x04 }, - 16, 0xa850, 0, {0x4c,0x00,0x3f,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa860, 0, {0x28,0x15,0x2a,0x00,0x8a,0x04,0x22,0x81,0x28,0xa0,0x12,0x28,0x00,0x8a,0x01,0x36 }, - 16, 0xa870, 0, {0x80,0x0b,0xa0,0x10,0x28,0x10,0xce,0x01,0x23,0x81,0x0c,0xa8,0x12,0xfb,0x00,0x8a }, - 16, 0xa880, 0, {0x01,0x3b,0x80,0x83,0xa0,0x42,0xe8,0x10,0x8a,0x00,0x2f,0x80,0x0b,0x60,0x42,0x0a }, - 16, 0xa890, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x00,0xa0,0xc0 }, - 16, 0xa8a0, 0, {0x18,0xb0,0x00,0xcc,0x00,0x9b,0x00,0x24,0xc0,0x0b,0x30,0x06,0x6c,0x00,0xa3,0x08 }, - 16, 0xa8b0, 0, {0x28,0xc8,0x09,0x30,0x02,0xcc,0x43,0x8b,0x00,0x2c,0x80,0x0b,0x30,0x02,0xcc,0x02 }, - 16, 0xa8c0, 0, {0x83,0x01,0x2c,0xc0,0x4b,0x30,0x00,0x4a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa8d0, 0, {0xa0,0x01,0x0c,0x24,0x87,0x94,0x21,0xe4,0x18,0x31,0x02,0xdc,0x80,0x97,0x10,0x25 }, - 16, 0xa8e0, 0, {0xcd,0x0b,0xf2,0x02,0x7c,0x00,0xa0,0x00,0x28,0xe0,0x18,0x70,0x02,0xdc,0x01,0x87 }, - 16, 0xa8f0, 0, {0x34,0x29,0x40,0x09,0x40,0x02,0xd0,0x04,0x84,0x04,0x2d,0x00,0x4b,0xd0,0x22,0x68 }, - 16, 0xa900, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x16,0x00,0xcf,0xa0,0x70,0xe9 }, - 16, 0xa910, 0, {0x18,0x7b,0x03,0xff,0x40,0x97,0xa0,0x35,0xe8,0x0f,0x74,0x02,0x5e,0x20,0xe4,0x80 }, - 16, 0xa920, 0, {0x39,0xa0,0x2d,0x78,0x03,0xfe,0x00,0xc7,0x80,0x3d,0xe0,0x5f,0x68,0x43,0xc2,0x00 }, - 16, 0xa930, 0, {0xc4,0x84,0x1d,0x60,0x0f,0x78,0x03,0x6a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa940, 0, {0x08,0x0d,0xa4,0x00,0x3b,0x00,0x2e,0xd8,0x0f,0xb4,0x03,0x2d,0x8a,0xeb,0x62,0x3a }, - 16, 0xa950, 0, {0xd0,0x0f,0xb2,0x87,0x0c,0xd0,0xd8,0x00,0x32,0xc0,0x4f,0x90,0x43,0xec,0x00,0xfb }, - 16, 0xa960, 0, {0x08,0x3e,0x40,0x8f,0x90,0x03,0xfc,0x00,0xff,0x04,0x3f,0x80,0x0f,0x00,0x2b,0x82 }, - 16, 0xa970, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xff,0xa0,0x3e,0xf4 }, - 16, 0xa980, 0, {0x0e,0xb8,0x03,0xee,0x08,0x4b,0xf0,0x7f,0xf4,0x0c,0xf9,0x23,0xee,0x48,0x78,0x90 }, - 16, 0xa990, 0, {0x32,0xe4,0x0c,0xf9,0x03,0xfe,0x00,0xff,0x80,0x3f,0xe4,0x1c,0x79,0x03,0x2e,0x40 }, - 16, 0xa9a0, 0, {0xff,0x80,0x33,0xe0,0x2c,0x78,0x07,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa9b0, 0, {0xa8,0x11,0x94,0x00,0xb3,0x00,0x0c,0xe5,0x0b,0x38,0x02,0xfe,0x80,0x8f,0x80,0x61 }, - 16, 0xa9c0, 0, {0xc4,0x28,0x78,0x00,0x4e,0x00,0xf4,0x84,0x25,0xa8,0x0c,0x70,0x02,0xcc,0x04,0xb3 }, - 16, 0xa9d0, 0, {0x90,0x25,0x40,0x0c,0x41,0x83,0x52,0x40,0xb4,0x10,0xa3,0x00,0x0c,0x52,0x03,0x6a }, - 16, 0xa9e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x00,0xb7,0x21,0x6d,0xc8 }, - 16, 0xa9f0, 0, {0x4b,0x70,0x02,0xdc,0x42,0xa7,0x31,0x29,0xc4,0x08,0x72,0x02,0xdc,0x00,0xb7,0x28 }, - 16, 0xaa00, 0, {0x24,0x80,0x08,0x70,0x06,0xd4,0x20,0xb7,0x01,0x2d,0xc1,0x08,0x60,0x02,0x50,0x80 }, - 16, 0xaa10, 0, {0xb4,0x08,0x21,0x62,0x09,0x74,0x06,0x80,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaa20, 0, {0x20,0x14,0xc7,0x04,0xb3,0x00,0x2c,0xc0,0x0b,0xb0,0x02,0xcc,0x00,0xa3,0x02,0x60 }, - 16, 0xaa30, 0, {0xc0,0x08,0x38,0x02,0x4e,0x44,0xa0,0xc0,0x24,0x91,0x08,0x30,0x02,0xc0,0x00,0xb3 }, - 16, 0xaa40, 0, {0x00,0x24,0x60,0x08,0x1c,0x02,0x4c,0x88,0xb3,0xc0,0x20,0xa0,0x08,0x00,0x0a,0x88 }, - 16, 0xaa50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xff,0x00,0x2f,0xc0 }, - 16, 0xaa60, 0, {0x4f,0xf0,0x13,0xfc,0x08,0xe7,0x8a,0x3f,0xc0,0x0c,0xf5,0xc2,0xfe,0x10,0xbb,0xc0 }, - 16, 0xaa70, 0, {0x32,0xd4,0x0c,0x30,0x13,0xe3,0x04,0xbf,0x00,0x2e,0x62,0x08,0xb9,0x02,0x6e,0x00 }, - 16, 0xaa80, 0, {0xfb,0x01,0x32,0xa4,0x4d,0x94,0x02,0xab,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaa90, 0, {0x80,0x00,0xec,0x60,0xfb,0x00,0x1e,0xc0,0x0f,0xb0,0x13,0xec,0x00,0x5b,0x00,0x3a }, - 16, 0xaaa0, 0, {0xc0,0x0f,0xb0,0x41,0xec,0x00,0x7b,0x45,0xba,0x40,0x2e,0xb0,0x15,0xe0,0x01,0xfb }, - 16, 0xaab0, 0, {0x00,0x3e,0x50,0x0e,0xc0,0x03,0xf0,0x40,0xfc,0x20,0x3f,0x50,0x8f,0x90,0x01,0x60 }, - 16, 0xaac0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf4,0x00,0xff,0x00,0x3f,0xc0 }, - 16, 0xaad0, 0, {0x8f,0xf0,0x03,0x1c,0x02,0xcf,0x00,0x36,0xc0,0x0d,0xf0,0x03,0x7c,0x00,0x7f,0x2a }, - 16, 0xaae0, 0, {0x3f,0x80,0x0f,0xf8,0x13,0x90,0x21,0xcf,0x00,0x3f,0x62,0x0c,0xe0,0x03,0x30,0x00 }, - 16, 0xaaf0, 0, {0xf8,0x00,0x3f,0x00,0x0f,0xd0,0x03,0x80,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xab00, 0, {0x81,0x04,0x64,0x11,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0x2c,0x00,0xdb,0x04,0x32 }, - 16, 0xab10, 0, {0xc0,0x0e,0xb0,0x02,0xec,0x00,0xbb,0x84,0x2e,0x40,0x0b,0xb9,0x42,0x22,0x42,0x8b }, - 16, 0xab20, 0, {0x01,0x2c,0x72,0x0a,0x90,0x42,0x2c,0x00,0xbb,0x00,0x2e,0xc2,0x8f,0x88,0x06,0xe0 }, - 16, 0xab30, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x24,0x00,0xbb,0x00,0x6e,0xc0 }, - 16, 0xab40, 0, {0x48,0xb0,0x42,0x2c,0x00,0x8b,0x00,0x26,0xc0,0x0a,0xb0,0x12,0xec,0x00,0xbb,0x40 }, - 16, 0xab50, 0, {0x2e,0xc8,0x0b,0xb0,0x12,0x2c,0x00,0x8b,0x00,0x2e,0x48,0x0a,0x30,0x02,0x6c,0x00 }, - 16, 0xab60, 0, {0xbb,0x00,0x2e,0x80,0x4b,0x98,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xab70, 0, {0x08,0x04,0x04,0x00,0xb3,0x00,0x6c,0xc2,0x4b,0x31,0x02,0x0c,0x50,0x9b,0x20,0x20 }, - 16, 0xab80, 0, {0xc0,0x0a,0x32,0x12,0xcc,0x80,0xb3,0x00,0x6c,0x0c,0x0b,0x31,0x02,0x0c,0x42,0x83 }, - 16, 0xab90, 0, {0x08,0x2e,0x40,0x0a,0x00,0x02,0x00,0x80,0xb0,0x00,0x2c,0x41,0x0b,0x10,0x02,0x42 }, - 16, 0xaba0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xbb,0x40,0x3f,0xcc }, - 16, 0xabb0, 0, {0x0e,0xf0,0x83,0x3d,0xa0,0xcf,0x20,0x37,0xc0,0x0c,0xf7,0xc3,0xfd,0x48,0xf3,0x00 }, - 16, 0xabc0, 0, {0x3e,0x88,0x0f,0xb4,0x13,0xa5,0x00,0x8f,0x30,0x3e,0x40,0x0c,0xa0,0x03,0x60,0x80 }, - 16, 0xabd0, 0, {0xf8,0x00,0x3e,0x00,0x0f,0x90,0x23,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xabe0, 0, {0xa0,0x19,0xf4,0x00,0xff,0x29,0x3f,0xc9,0x0f,0xf0,0x13,0xfc,0x94,0xef,0x12,0x3b }, - 16, 0xabf0, 0, {0xc0,0x8e,0xb2,0x07,0xfd,0x04,0xff,0x10,0x3f,0x0c,0x0f,0xf0,0x03,0xf0,0x00,0xfb }, - 16, 0xac00, 0, {0x20,0x3d,0x40,0x0f,0xd0,0x43,0xfc,0x40,0xff,0x04,0x3f,0xc0,0x0e,0xc0,0x43,0xe8 }, - 16, 0xac10, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0xa2,0xc7,0x20,0x3f,0x24 }, - 16, 0xac20, 0, {0x0c,0xf0,0x03,0x3c,0x80,0xcc,0x09,0x33,0xd1,0x0c,0xf1,0x23,0xfc,0x20,0xdf,0x36 }, - 16, 0xac30, 0, {0x3f,0xc0,0x0e,0x48,0x03,0xfe,0x00,0xff,0x80,0x37,0xe4,0x0d,0x78,0x03,0x11,0xa0 }, - 16, 0xac40, 0, {0xcf,0x00,0x37,0xc8,0x0c,0xf0,0x03,0x30,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xac50, 0, {0x80,0x10,0xff,0x00,0x8f,0xd1,0x2e,0x08,0x0d,0xb6,0x12,0x3d,0x45,0xf9,0x64,0x27 }, - 16, 0xac60, 0, {0xd0,0x88,0xba,0x14,0xcc,0x04,0x8f,0x40,0x23,0xf0,0x0b,0x88,0x02,0x2e,0x04,0xbb }, - 16, 0xac70, 0, {0x80,0xae,0xc0,0x08,0xb8,0x0a,0x21,0x00,0x88,0xd0,0x22,0x20,0x28,0xb0,0x02,0x20 }, - 16, 0xac80, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x93,0x00,0x2e,0x00 }, - 16, 0xac90, 0, {0x0a,0x34,0x82,0x8c,0xa0,0xa0,0x08,0x24,0xd8,0x09,0x31,0x02,0xcc,0x20,0xb3,0x32 }, - 16, 0xaca0, 0, {0x28,0xd0,0x4a,0x80,0x02,0xcc,0x0c,0xbb,0x00,0x22,0x40,0x89,0xb0,0x02,0x60,0x80 }, - 16, 0xacb0, 0, {0x93,0x00,0x24,0xd0,0x0b,0x30,0x02,0xa2,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xacc0, 0, {0xc0,0x11,0xac,0x00,0x9b,0x00,0x2e,0x20,0x09,0xb0,0x4a,0x2c,0x02,0xa0,0x00,0x06 }, - 16, 0xacd0, 0, {0xc0,0x09,0xb0,0x00,0xec,0x00,0xab,0x00,0x2a,0xc0,0x0b,0x88,0x02,0x6c,0x00,0xbb }, - 16, 0xace0, 0, {0x20,0x2a,0xe2,0x41,0xb8,0x2a,0x60,0x0a,0x98,0x00,0x26,0x00,0x0b,0xb0,0x02,0xb8 }, - 16, 0xacf0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x08,0xdb,0x02,0x3e,0x20 }, - 16, 0xad00, 0, {0x4c,0xb0,0x03,0x2c,0x02,0x8b,0x20,0x12,0xc0,0x29,0xb0,0x12,0xec,0x00,0xfb,0x00 }, - 16, 0xad10, 0, {0x3a,0xc0,0x0e,0x88,0x03,0xed,0x20,0xfb,0xc8,0x34,0xf0,0x0d,0xba,0x03,0x47,0x60 }, - 16, 0xad20, 0, {0xc9,0x00,0x36,0x40,0x0f,0xb0,0x0b,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xad30, 0, {0xe0,0x01,0x9c,0x00,0xef,0x00,0x0f,0x00,0x0f,0x30,0x00,0xfc,0x00,0xdf,0x90,0xbb }, - 16, 0xad40, 0, {0xc0,0xce,0xf0,0x03,0xfc,0x04,0xcb,0x00,0x17,0xc0,0x0f,0xc0,0x03,0xbc,0x84,0xff }, - 16, 0xad50, 0, {0x00,0x37,0xc0,0x0e,0xd0,0x63,0xb8,0x00,0xea,0x00,0x3a,0x80,0x0c,0x30,0x03,0x70 }, - 16, 0xad60, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x02,0x32,0x00 }, - 16, 0xad70, 0, {0x0f,0xb0,0x53,0x2c,0x00,0xfa,0x00,0x32,0xc0,0x8f,0xb0,0x07,0x2c,0x00,0xfb,0x00 }, - 16, 0xad80, 0, {0xb2,0xc0,0x0f,0x80,0x07,0xac,0x80,0xdb,0x24,0x7e,0xd0,0x0e,0xb0,0x23,0x74,0x04 }, - 16, 0xad90, 0, {0xdd,0x08,0xb5,0x40,0x0c,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xada0, 0, {0xc8,0x05,0x3c,0x00,0xbf,0xc0,0xa0,0x00,0x1b,0xf0,0x02,0x3f,0x60,0xea,0x50,0x23 }, - 16, 0xadb0, 0, {0xc0,0x08,0xfa,0x07,0xfc,0x00,0xdf,0x00,0x63,0xc0,0x48,0x18,0x02,0x2d,0x00,0xb3 }, - 16, 0xadc0, 0, {0x00,0x6e,0xc0,0x0d,0x3a,0x03,0x24,0x00,0x82,0x80,0x32,0x80,0x0d,0xf0,0x03,0x32 }, - 16, 0xadd0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x14,0xb3,0x59,0x20,0x80 }, - 16, 0xade0, 0, {0x09,0x30,0x02,0x2e,0x05,0xb0,0x44,0x2e,0xc0,0x09,0x34,0x82,0xec,0x00,0xab,0x04 }, - 16, 0xadf0, 0, {0x20,0xc0,0x09,0x21,0xb2,0x8e,0x04,0x93,0xc0,0x24,0xc0,0x0a,0x18,0x06,0x4c,0x00 }, - 16, 0xae00, 0, {0x92,0x50,0x20,0xc0,0x08,0x30,0x02,0x70,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xae10, 0, {0x20,0x01,0x1e,0x00,0xb7,0x80,0x61,0xe0,0x0b,0x78,0x0a,0x5e,0x01,0xb1,0xa0,0x2d }, - 16, 0xae20, 0, {0xe0,0x0a,0x78,0x02,0x5e,0x00,0x07,0x90,0x21,0xe0,0x18,0xc8,0x02,0x1e,0x00,0xb7 }, - 16, 0xae30, 0, {0x80,0x2d,0xe0,0x8a,0xd8,0x02,0x3e,0xc0,0x85,0x80,0x21,0x20,0x19,0x78,0x22,0x00 }, - 16, 0xae40, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf3,0x94,0x20,0x10 }, - 16, 0xae50, 0, {0x4b,0x30,0x07,0x0c,0x00,0xf3,0x00,0x3e,0xc8,0x0f,0x30,0x03,0xcc,0x00,0x23,0x10 }, - 16, 0xae60, 0, {0x00,0xcb,0x05,0x20,0x02,0x8c,0x60,0x93,0x0a,0x2e,0xc4,0x0a,0x01,0x07,0x4c,0x80 }, - 16, 0xae70, 0, {0xd2,0x01,0x30,0xc0,0x2c,0x30,0x0b,0x5a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xae80, 0, {0x40,0x1d,0xbc,0x00,0xff,0x01,0x0f,0x40,0x0f,0xf0,0x13,0xbc,0x00,0xef,0x26,0x73 }, - 16, 0xae90, 0, {0xc2,0x0c,0xb0,0x83,0xbc,0x40,0xff,0x18,0x3d,0xc0,0x4a,0xc1,0x03,0xfc,0x00,0xfb }, - 16, 0xaea0, 0, {0x12,0x3f,0xc4,0x4d,0xc1,0x0b,0xfc,0x81,0xfd,0x00,0x3f,0x20,0x0f,0xf0,0x03,0xd0 }, - 16, 0xaeb0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x20,0xcb,0x48,0x3e,0x00 }, - 16, 0xaec0, 0, {0x0c,0xb0,0x03,0x2d,0x20,0xe9,0x80,0xfa,0xc8,0x0d,0xb0,0x03,0xee,0x00,0xdb,0x24 }, - 16, 0xaed0, 0, {0x76,0xf3,0x8e,0x80,0x33,0xec,0x44,0xeb,0x10,0x3e,0xc0,0x0f,0x90,0x03,0xe8,0x04 }, - 16, 0xaee0, 0, {0xdc,0x00,0xb3,0x61,0x0c,0xb0,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaef0, 0, {0x48,0x11,0x8d,0x00,0x87,0x20,0x2f,0x01,0x28,0x70,0x02,0x0c,0x84,0x8d,0x04,0x31 }, - 16, 0xaf00, 0, {0xcc,0xc9,0x72,0x02,0xdd,0x00,0x37,0x33,0x21,0xd8,0x08,0x40,0x02,0xdc,0x00,0xb7 }, - 16, 0xaf10, 0, {0x20,0x3d,0xc0,0x09,0x50,0x22,0xf0,0x00,0x97,0x00,0x21,0x80,0x0a,0xfc,0x02,0x92 }, - 16, 0xaf20, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x1e,0x82,0x87,0xb0,0x2d,0x20 }, - 16, 0xaf30, 0, {0x08,0x39,0x02,0x1e,0x41,0xa7,0x80,0x24,0xe0,0x09,0x7a,0x32,0x8e,0x82,0x07,0xa0 }, - 16, 0xaf40, 0, {0x25,0xe0,0x8b,0x48,0x02,0x1e,0x00,0xa7,0xe1,0x2d,0xe0,0x4b,0x58,0x00,0xda,0x00 }, - 16, 0xaf50, 0, {0xa0,0x80,0x24,0x60,0x08,0x7a,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaf60, 0, {0x48,0x14,0xcc,0x00,0x83,0x00,0x2c,0x00,0x08,0x30,0x02,0x8c,0x00,0x93,0x00,0x22 }, - 16, 0xaf70, 0, {0xc1,0x09,0x30,0x42,0xcc,0x00,0x83,0x00,0x60,0xc0,0x08,0x1a,0x02,0xce,0x04,0xb3 }, - 16, 0xaf80, 0, {0xe0,0x28,0xa0,0x09,0x1c,0x82,0x4b,0x08,0xa3,0x80,0x24,0xa0,0x2a,0x30,0x02,0x9a }, - 16, 0xaf90, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xca,0x00,0x2f,0x88 }, - 16, 0xafa0, 0, {0x0c,0xa0,0x13,0x28,0x00,0xee,0x00,0x2e,0x80,0x2d,0xa0,0x03,0xe8,0x00,0xda,0x00 }, - 16, 0xafb0, 0, {0x76,0x80,0x0e,0xe8,0x03,0xbb,0x80,0xee,0x40,0x2f,0xa2,0x8f,0xe6,0x03,0xeb,0x86 }, - 16, 0xafc0, 0, {0xfa,0x80,0x37,0x82,0x0c,0x20,0x07,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xafd0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x40,0x1e,0x00,0x0f,0x80,0x0b,0x61,0x00,0xe8,0xc0,0x3a }, - 16, 0xafe0, 0, {0x00,0x0e,0x80,0x03,0xe0,0x01,0xf8,0x00,0x7e,0x10,0x1e,0x81,0x03,0xe0,0x08,0xf8 }, - 16, 0xaff0, 0, {0x00,0x3e,0x00,0x0d,0x80,0x03,0xc0,0x28,0xdc,0x50,0x3b,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xb000, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x02,0xc9,0x00,0x3e,0x42 }, - 16, 0xb010, 0, {0x0f,0x10,0x03,0xa6,0x00,0xc9,0x01,0x3a,0x40,0x0e,0x94,0x01,0xe4,0x10,0xf1,0x04 }, - 16, 0xb020, 0, {0x32,0x40,0x0f,0x9a,0x23,0x20,0x60,0xf8,0x04,0x0a,0x42,0x0e,0x90,0x13,0x24,0x00 }, - 16, 0xb030, 0, {0xc1,0x00,0x32,0x40,0x0f,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb040, 0, {0x80,0x04,0x67,0x08,0xa9,0x00,0x6e,0x40,0x08,0x90,0x02,0x27,0x82,0x89,0x00,0x26 }, - 16, 0xb050, 0, {0x40,0x08,0x9c,0x03,0xa4,0x10,0xb9,0x00,0x36,0x40,0x9b,0x1c,0x1a,0x23,0x04,0xb8 }, - 16, 0xb060, 0, {0x00,0x3a,0x40,0x0e,0x10,0x02,0x24,0x02,0xc9,0xa0,0xa2,0x40,0x0b,0x90,0x0a,0x20 }, - 16, 0xb070, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x25,0x80,0x89,0x04,0x2c,0x40 }, - 16, 0xb080, 0, {0x08,0x90,0x02,0x84,0x81,0x99,0x40,0x2e,0x40,0x1a,0x90,0x06,0xe4,0x01,0xb9,0x00 }, - 16, 0xb090, 0, {0xa6,0x41,0x1b,0x90,0x82,0x21,0x00,0xb8,0x10,0x2e,0x40,0x0a,0x92,0x0a,0xa4,0x01 }, - 16, 0xb0a0, 0, {0x8f,0x22,0x23,0x40,0x0b,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb0b0, 0, {0x08,0x04,0x04,0x80,0xa3,0x20,0x2c,0x41,0x09,0x12,0x02,0x04,0x80,0x81,0x20,0x24 }, - 16, 0xb0c0, 0, {0x48,0x0a,0x36,0x02,0xc4,0x80,0xb1,0x20,0x04,0xc8,0x4b,0x14,0x02,0x05,0x00,0xb1 }, - 16, 0xb0d0, 0, {0x05,0x28,0x50,0x0a,0x90,0x02,0x05,0x02,0x85,0x00,0x21,0x40,0x0b,0x12,0x02,0x02 }, - 16, 0xb0e0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x00,0x6e,0x14 }, - 16, 0xb0f0, 0, {0x2c,0x85,0x02,0xa1,0x40,0xc8,0x50,0x3a,0x14,0x0e,0x80,0x02,0xe1,0x40,0xb0,0x50 }, - 16, 0xb100, 0, {0x32,0x00,0x0b,0x80,0x03,0x20,0x00,0xfa,0x00,0x3e,0x00,0x0e,0x80,0x03,0xa0,0x02 }, - 16, 0xb110, 0, {0xc8,0x00,0x13,0x00,0x0f,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb120, 0, {0x98,0x1d,0xe4,0x48,0xf9,0x14,0x3f,0x40,0x0c,0x91,0x03,0xe4,0x42,0xfd,0x10,0x36 }, - 16, 0xb130, 0, {0x44,0x0d,0x91,0x23,0xa4,0x48,0xf9,0x11,0x38,0x44,0x0f,0xd0,0x03,0xe5,0x14,0x39 }, - 16, 0xb140, 0, {0x42,0x7b,0x40,0x8e,0xd0,0x01,0xf5,0x00,0xa9,0x40,0x3e,0x50,0x07,0x96,0x83,0xe6 }, - 16, 0xb150, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xf6,0x80,0xdd,0xae,0x3a,0x50 }, - 16, 0xb160, 0, {0x0d,0x9a,0x0b,0x76,0x80,0xcf,0x88,0x32,0x70,0x2d,0xda,0x03,0xa7,0x01,0xe9,0x92 }, - 16, 0xb170, 0, {0x37,0x68,0x0d,0x94,0x03,0xe7,0x00,0xed,0xa0,0x3a,0x50,0x0f,0xd0,0x03,0xe7,0x02 }, - 16, 0xb180, 0, {0xcd,0x80,0x33,0x68,0x0c,0xd8,0x83,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb190, 0, {0x38,0x10,0xe1,0x00,0x88,0x40,0x20,0x20,0x0c,0x8c,0x02,0x23,0x00,0x88,0xe0,0x22 }, - 16, 0xb1a0, 0, {0x30,0x08,0x84,0x02,0xe3,0x00,0xb8,0xe0,0x22,0x14,0x8d,0x88,0x02,0xe3,0x00,0xb8 }, - 16, 0xb1b0, 0, {0x50,0x2e,0xa8,0x8b,0x80,0x22,0xe3,0x48,0x88,0x50,0x22,0x00,0x08,0x8c,0x02,0x0e }, - 16, 0xb1c0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x40,0x91,0x00,0x2a,0x48 }, - 16, 0xb1d0, 0, {0x09,0x14,0x82,0x05,0x20,0x81,0x08,0x20,0x58,0x09,0x11,0x02,0x85,0x88,0xb1,0x40 }, - 16, 0xb1e0, 0, {0xa0,0x40,0x08,0x12,0x02,0xc5,0x80,0xa1,0x00,0x28,0x40,0x0b,0x18,0x02,0xc4,0x84 }, - 16, 0xb1f0, 0, {0xa1,0x00,0x24,0x50,0x08,0x10,0x92,0x03,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb200, 0, {0x18,0x15,0xac,0x10,0x9b,0x00,0x22,0x40,0x08,0x90,0x02,0x04,0x06,0x89,0x04,0x20 }, - 16, 0xb210, 0, {0x40,0x09,0x90,0x02,0xe4,0x01,0xb9,0x02,0x22,0x41,0x89,0xa0,0x82,0xe0,0xa0,0xb9 }, - 16, 0xb220, 0, {0x28,0x2e,0x44,0x0b,0xb0,0x02,0xe4,0x02,0xb9,0x00,0x26,0x40,0x28,0x10,0x02,0x06 }, - 16, 0xb230, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xd9,0x00,0x38,0x40 }, - 16, 0xb240, 0, {0x0d,0x90,0x03,0x24,0x00,0xc9,0xa0,0xa2,0x40,0x8d,0x90,0x03,0xa4,0x00,0xf9,0x00 }, - 16, 0xb250, 0, {0x36,0x40,0x0c,0x84,0x13,0xe2,0x00,0xe9,0x00,0x3a,0x50,0x0f,0x9c,0x02,0xe6,0x84 }, - 16, 0xb260, 0, {0xe9,0x00,0xb6,0x40,0x0c,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb270, 0, {0x28,0x01,0xa4,0x00,0xe1,0x00,0x3e,0x68,0x0e,0x10,0x03,0xa4,0x00,0xf1,0x28,0x3a }, - 16, 0xb280, 0, {0x40,0x0e,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x42,0x0f,0x80,0x23,0xe2,0x00,0xf9 }, - 16, 0xb290, 0, {0x00,0x3e,0x40,0x0f,0x91,0x23,0xe4,0x40,0xc1,0x00,0x3a,0x40,0x0f,0x90,0x0b,0xca }, - 16, 0xb2a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x80,0x00,0xc8,0x00,0x32,0x00 }, - 16, 0xb2b0, 0, {0x0c,0x80,0x03,0xa0,0x20,0xc8,0x40,0x3e,0x00,0x0e,0x81,0x63,0x60,0x00,0xf0,0x04 }, - 16, 0xb2c0, 0, {0x3c,0x01,0x0c,0x84,0x03,0xe0,0x00,0xc8,0x00,0x3e,0x00,0x0e,0x80,0x03,0xc1,0x00 }, - 16, 0xb2d0, 0, {0xd8,0x10,0x32,0x00,0x0c,0x80,0x23,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb2e0, 0, {0x28,0x05,0x38,0x60,0x8e,0x00,0x22,0x80,0x0a,0xa0,0x02,0x38,0x80,0xbe,0x00,0x3a }, - 16, 0xb2f0, 0, {0x80,0x08,0xe0,0x02,0x28,0x00,0xba,0x00,0x23,0x98,0x18,0xec,0x02,0xf8,0x20,0xae }, - 16, 0xb300, 0, {0x00,0x22,0x80,0x0b,0xe4,0x82,0xe8,0x02,0xce,0x44,0x28,0x80,0x0d,0xa0,0x0a,0x0a }, - 16, 0xb310, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x40,0x00,0x82,0x04,0xa0,0xc0 }, - 16, 0xb320, 0, {0x09,0x30,0x02,0x8e,0x04,0x83,0x50,0x6c,0xc0,0x0a,0x30,0x86,0x0c,0x00,0xb3,0x00 }, - 16, 0xb330, 0, {0x28,0x30,0x0a,0x36,0x12,0xcc,0x80,0x81,0x00,0x24,0xc0,0x0b,0x32,0x06,0xcc,0x00 }, - 16, 0xb340, 0, {0x80,0x88,0x64,0x60,0x28,0x10,0x02,0x02,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb350, 0, {0xa0,0x01,0x10,0x12,0x84,0x40,0x21,0xc8,0x0a,0x72,0x02,0x10,0x00,0xb7,0x00,0x2d }, - 16, 0xb360, 0, {0xcc,0x08,0x38,0x12,0x1c,0x00,0xb3,0x30,0x20,0x00,0x08,0x71,0x82,0xfe,0x00,0xa4 }, - 16, 0xb370, 0, {0x80,0x21,0xc8,0x0b,0x70,0x02,0xdc,0x01,0x87,0x00,0x2c,0x42,0x09,0x51,0x02,0x20 }, - 16, 0xb380, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xc2,0x80,0x31,0xf8 }, - 16, 0xb390, 0, {0x4c,0xfc,0x13,0x92,0x09,0xc7,0x80,0x3c,0xed,0x1e,0x78,0x27,0x1e,0x00,0xf7,0x8c }, - 16, 0xb3a0, 0, {0x79,0x20,0x08,0x7a,0x03,0xde,0x81,0x84,0x80,0x3d,0xe0,0x0e,0x78,0x03,0xfe,0x20 }, - 16, 0xb3b0, 0, {0xc5,0x81,0x35,0x60,0x2c,0x58,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb3c0, 0, {0x08,0x1d,0x80,0x00,0xf8,0x04,0x3e,0xd0,0x0f,0xb0,0x13,0xe0,0x00,0xfb,0x02,0x3a }, - 16, 0xb3d0, 0, {0xd0,0x0f,0xa0,0x0b,0xac,0x40,0xfb,0x00,0x3a,0x00,0x2f,0xb0,0x03,0xcc,0x00,0xf0 }, - 16, 0xb3e0, 0, {0x00,0x3a,0xc4,0x0f,0xb0,0x03,0xfc,0x41,0xf3,0x00,0x3a,0x40,0x0f,0x50,0x93,0xc2 }, - 16, 0xb3f0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xcc,0x81,0x3f,0xfc }, - 16, 0xb400, 0, {0x1c,0xf8,0x03,0x76,0x40,0xef,0x92,0x3f,0xe4,0x8c,0xf8,0x03,0xbf,0x10,0xff,0x80 }, - 16, 0xb410, 0, {0xb3,0x20,0x0e,0xf9,0x13,0xfe,0x24,0xfd,0x94,0x37,0xe0,0x1c,0xf9,0x03,0xee,0x00 }, - 16, 0xb420, 0, {0xcd,0x80,0xb3,0xe0,0x0c,0x58,0x02,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb430, 0, {0xa8,0x11,0x94,0x40,0x80,0x00,0x2f,0xc4,0x08,0x72,0x02,0xdd,0x08,0xd7,0x00,0x2d }, - 16, 0xb440, 0, {0xcc,0x08,0xde,0x03,0x5c,0x00,0xb7,0x04,0x21,0x80,0xc8,0x70,0x83,0xdc,0x00,0xb4 }, - 16, 0xb450, 0, {0xa0,0x2f,0xc0,0x0c,0x70,0x02,0xde,0x80,0x87,0x00,0x21,0xc2,0x0a,0x51,0x42,0x2a }, - 16, 0xb460, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x84,0x00,0x2d,0xc8 }, - 16, 0xb470, 0, {0x48,0x70,0x02,0x54,0x0c,0xa7,0x00,0x2c,0xc0,0x89,0x72,0x02,0x5c,0x00,0xb3,0x10 }, - 16, 0xb480, 0, {0x20,0x00,0x0a,0x70,0x06,0xdc,0x00,0xb4,0x20,0x2d,0xc0,0x08,0x70,0x02,0xdc,0x80 }, - 16, 0xb490, 0, {0x93,0x00,0x20,0xc0,0x08,0x50,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb4a0, 0, {0x20,0x14,0xc0,0x00,0x80,0x00,0x2e,0xc0,0x08,0x30,0x02,0xc4,0x08,0xa2,0x42,0x2c }, - 16, 0xb4b0, 0, {0xc1,0x09,0x20,0x02,0x4c,0x00,0xb3,0x00,0x20,0x80,0x08,0x3c,0x22,0x8c,0x20,0xb0 }, - 16, 0xb4c0, 0, {0x08,0x2e,0xe0,0x08,0x38,0x10,0xcf,0x0a,0x93,0x40,0xa0,0xf0,0x0a,0x10,0x02,0x08 }, - 16, 0xb4d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa8,0x00,0xc1,0x00,0x3f,0xc0 }, - 16, 0xb4e0, 0, {0x2c,0xf0,0x03,0x68,0x00,0xaa,0x00,0x3f,0xc0,0x2d,0x80,0x03,0x7c,0x00,0xff,0x00 }, - 16, 0xb4f0, 0, {0x32,0x00,0x0e,0xb0,0x12,0xed,0x24,0xfa,0x08,0x27,0xc8,0x10,0xb8,0xa2,0xff,0x60 }, - 16, 0xb500, 0, {0x98,0xa0,0xa2,0xe0,0x0c,0x50,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb510, 0, {0x80,0x00,0xc9,0x06,0xf8,0x41,0x3e,0xc0,0x0f,0xb0,0x03,0xe9,0x10,0x5a,0x20,0x3e }, - 16, 0xb520, 0, {0xc0,0x0e,0x80,0x03,0xec,0x00,0xf3,0x00,0x7e,0x01,0x0f,0xb0,0x93,0xed,0x00,0xf8 }, - 16, 0xb530, 0, {0x40,0x3e,0xc0,0x0e,0xb0,0x03,0xfc,0x00,0xe3,0x08,0x3c,0xc2,0x0f,0xd0,0x13,0xe0 }, - 16, 0xb540, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf3,0x02,0xcc,0x00,0x3b,0xc2 }, - 16, 0xb550, 0, {0x0c,0xf0,0x23,0xae,0x40,0xdf,0x81,0x39,0xc0,0x06,0xd0,0x03,0xfc,0x00,0xff,0x04 }, - 16, 0xb560, 0, {0x31,0x41,0x0c,0xf0,0x03,0xfc,0x00,0xcc,0xa0,0x37,0xc2,0x0c,0xf0,0x03,0x7c,0x04 }, - 16, 0xb570, 0, {0xcd,0x00,0x33,0xf0,0x0c,0xd0,0x03,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb580, 0, {0x81,0x04,0x60,0x00,0x88,0x80,0x22,0xc0,0x0a,0xb0,0x02,0xe9,0x00,0xab,0x44,0x2e }, - 16, 0xb590, 0, {0xc0,0x08,0x88,0x02,0xec,0x00,0xbb,0x00,0xa2,0x70,0x0a,0xb4,0x02,0xcc,0x00,0xa0 }, - 16, 0xb5a0, 0, {0x20,0x22,0xc0,0x0f,0xbc,0x02,0xcc,0x0a,0x8b,0x80,0xa2,0xc0,0x0d,0x90,0x02,0x20 }, - 16, 0xb5b0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x20,0x00,0x89,0x80,0x2a,0xc0 }, - 16, 0xb5c0, 0, {0x08,0xb0,0x02,0xcc,0x06,0x88,0x60,0x2e,0xc0,0x0a,0x98,0x06,0xec,0x01,0xbb,0x00 }, - 16, 0xb5d0, 0, {0x22,0x31,0x02,0xb2,0x02,0xec,0xa0,0x8a,0x00,0x26,0xc0,0x48,0xa8,0x02,0xec,0x04 }, - 16, 0xb5e0, 0, {0xa9,0x80,0x22,0x40,0x08,0x90,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb5f0, 0, {0x08,0x04,0x00,0x00,0x80,0x00,0x20,0xc0,0x0a,0x30,0x42,0xcc,0x00,0x80,0x01,0x2c }, - 16, 0xb600, 0, {0xc0,0x1a,0x12,0x02,0xcc,0x00,0xb3,0x00,0x20,0x00,0x4a,0x30,0x02,0xcc,0x00,0xa0 }, - 16, 0xb610, 0, {0x00,0x08,0xc0,0x0b,0x20,0x06,0xec,0xa0,0xa3,0x00,0xa0,0x40,0x29,0x10,0x00,0x02 }, - 16, 0xb620, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xc8,0x50,0x3b,0xc0 }, - 16, 0xb630, 0, {0x0c,0xb0,0x03,0xac,0x00,0xc9,0x00,0x3b,0xc0,0x0e,0x92,0x83,0xfc,0x00,0xbf,0x00 }, - 16, 0xb640, 0, {0x12,0x00,0x0c,0xb0,0x03,0xec,0x00,0x88,0x26,0x16,0xc0,0x0c,0x80,0x17,0x5c,0x80 }, - 16, 0xb650, 0, {0xe9,0x01,0x32,0x40,0x2c,0xd0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb660, 0, {0xa0,0x1d,0xd0,0x00,0xfc,0x20,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xfc,0x00,0x3f }, - 16, 0xb670, 0, {0xc0,0x0d,0x80,0x03,0xfc,0x08,0xff,0x00,0x3f,0x00,0x0f,0xf0,0x03,0xfc,0x10,0xf8 }, - 16, 0xb680, 0, {0x40,0x37,0xc0,0x0e,0xe0,0x21,0xfc,0x08,0xdf,0x00,0x3f,0x40,0x0f,0xd0,0x03,0xe0 }, - 16, 0xb690, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0xc0,0xff,0x21,0x71,0x24 }, - 16, 0xb6a0, 0, {0x0f,0xf1,0x83,0xf2,0x40,0xff,0x00,0x37,0xc4,0x9f,0xf2,0x47,0x3d,0x04,0xc7,0x20 }, - 16, 0xb6b0, 0, {0x33,0xc0,0x0c,0x78,0x23,0xfe,0x40,0xe8,0x10,0x27,0xc4,0x0f,0xf2,0x13,0x3c,0x84 }, - 16, 0xb6c0, 0, {0xc4,0x81,0x33,0x20,0x4c,0xf0,0x23,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb6d0, 0, {0x80,0x10,0xed,0x40,0xbf,0x54,0x62,0xc8,0x0b,0xf6,0x02,0xe0,0x00,0xbb,0xd0,0x22 }, - 16, 0xb6e0, 0, {0xf0,0x1f,0xf9,0x12,0x3d,0x80,0x9f,0x81,0x2b,0xe0,0x0a,0xb8,0x12,0xe8,0x00,0x8f }, - 16, 0xb6f0, 0, {0x04,0x22,0xd0,0x08,0xb3,0x8a,0xbf,0x42,0x8b,0x82,0x22,0xe0,0x28,0x8c,0x02,0x20 }, - 16, 0xb700, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xb3,0x28,0x28,0x08 }, - 16, 0xb710, 0, {0x0b,0x30,0x06,0x80,0x80,0xb3,0x02,0x24,0xd1,0x0b,0x30,0x02,0x8d,0x80,0x93,0x10 }, - 16, 0xb720, 0, {0x20,0xce,0x8b,0x30,0x02,0xcc,0x84,0xa1,0x21,0x2c,0xcc,0x0a,0x30,0x0a,0x4c,0x00 }, - 16, 0xb730, 0, {0x93,0x00,0x28,0xc0,0x08,0x3c,0x02,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb740, 0, {0xc0,0x15,0xac,0x10,0xbb,0x02,0x6a,0xe0,0x0b,0xb0,0x02,0xe1,0x08,0xbb,0x04,0x2a }, - 16, 0xb750, 0, {0xc0,0x0a,0xb0,0x12,0x8c,0x00,0x9b,0x00,0x2a,0xc0,0x0b,0xb1,0x06,0xc8,0x80,0x8b }, - 16, 0xb760, 0, {0x82,0x6a,0xc1,0x0a,0x30,0x02,0xac,0x18,0x88,0x10,0x2a,0x48,0x08,0x80,0x02,0x30 }, - 16, 0xb770, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xfb,0x00,0xaa,0x30 }, - 16, 0xb780, 0, {0x0f,0xb0,0x03,0xa8,0x00,0xf3,0x01,0xb6,0xc1,0x0b,0xb0,0x02,0xac,0x08,0x4b,0x00 }, - 16, 0xb790, 0, {0xb2,0xc0,0x0f,0xb8,0x02,0xec,0x10,0xa9,0x81,0x3e,0xc0,0x0f,0xb0,0x03,0x0c,0x00 }, - 16, 0xb7a0, 0, {0xcb,0xa0,0x18,0xd0,0x0c,0xb0,0x03,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb7b0, 0, {0xe0,0x01,0xbc,0x08,0xf7,0x00,0x37,0x00,0x0f,0xf0,0x03,0xfd,0x00,0xff,0x00,0x37 }, - 16, 0xb7c0, 0, {0xc0,0x0f,0xb0,0x07,0x7c,0x00,0xe7,0x00,0x3e,0xc0,0x0a,0xf0,0x03,0xfe,0x00,0xf7 }, - 16, 0xb7d0, 0, {0x00,0x36,0xc0,0x0c,0xf0,0x03,0xfc,0x00,0xff,0x80,0x37,0xe0,0x0f,0xa0,0x03,0xb8 }, - 16, 0xb7e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xdb,0x00,0x36,0x00 }, - 16, 0xb7f0, 0, {0x0e,0xb0,0x03,0x69,0x00,0xdb,0x09,0x3a,0xc0,0x1f,0x30,0x23,0xec,0x08,0xcb,0x20 }, - 16, 0xb800, 0, {0x34,0xc0,0x2f,0xb0,0x03,0xec,0x40,0xeb,0x48,0x3e,0xc4,0x4d,0xb0,0x8b,0x6c,0x00 }, - 16, 0xb810, 0, {0xcb,0x00,0x32,0x90,0x0f,0x30,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb820, 0, {0xc8,0x05,0x3c,0x00,0x8f,0x00,0x22,0x00,0x48,0xf0,0x22,0x2c,0x00,0x8f,0x00,0x23 }, - 16, 0xb830, 0, {0xe0,0x8b,0xf5,0x10,0x3c,0x00,0x8f,0x80,0x23,0xf0,0x80,0x98,0x03,0x2d,0x44,0xdb }, - 16, 0xb840, 0, {0x00,0x23,0xd4,0x08,0xf8,0x02,0x3c,0x00,0x83,0x00,0x22,0xc0,0x0b,0xa4,0x82,0x32 }, - 16, 0xb850, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x93,0x00,0x24,0x00 }, - 16, 0xb860, 0, {0x0b,0x30,0x02,0x84,0x00,0xb3,0x01,0x28,0xf6,0x09,0x34,0x32,0x8c,0x01,0xb3,0xd0 }, - 16, 0xb870, 0, {0x24,0xe8,0x0a,0x31,0x0a,0x86,0x00,0x83,0x00,0x2a,0xe0,0x00,0x30,0x02,0x8c,0x00 }, - 16, 0xb880, 0, {0x83,0x00,0x28,0xc0,0x89,0x38,0xa2,0x78,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb890, 0, {0x20,0x01,0x1e,0x00,0x97,0x94,0x23,0xe0,0x09,0x38,0x02,0x32,0x00,0x97,0xa1,0x21 }, - 16, 0xb8a0, 0, {0xe4,0x0b,0x78,0x02,0x1e,0x40,0xb7,0xa0,0x25,0xec,0x08,0xfc,0x02,0x3a,0x00,0x93 }, - 16, 0xb8b0, 0, {0xb8,0x21,0xe0,0x08,0x78,0x82,0x9e,0x40,0x87,0xc0,0x29,0xa0,0x0b,0x58,0x02,0x48 }, - 16, 0xb8c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x2c,0x00,0xdb,0x00,0x34,0x20 }, - 16, 0xb8d0, 0, {0x0f,0x3a,0x03,0x8e,0x00,0xf3,0xb0,0x28,0xc4,0x0b,0x3a,0x03,0xae,0x40,0xf3,0xa0 }, - 16, 0xb8e0, 0, {0x34,0xee,0x0f,0x30,0x23,0x84,0x00,0xe3,0xf0,0x38,0xc0,0x0c,0xb0,0x0b,0x8e,0x42 }, - 16, 0xb8f0, 0, {0xc3,0x00,0x38,0xc0,0x0f,0x30,0x63,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb900, 0, {0x40,0x1d,0xbc,0x00,0xeb,0x42,0x3a,0xc4,0x1e,0xb1,0x07,0x88,0xd1,0xe3,0x00,0x3f }, - 16, 0xb910, 0, {0xc5,0x8f,0xf1,0x63,0xac,0x10,0xcb,0x50,0x3b,0xc3,0x0f,0xd1,0x03,0xc8,0x00,0xbb }, - 16, 0xb920, 0, {0x20,0x3b,0xc0,0x2e,0xf1,0x03,0x1c,0x00,0xff,0x00,0x37,0xc0,0x4f,0xd1,0x03,0x90 }, - 16, 0xb930, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x40,0xfb,0x44,0xb2,0xc0 }, - 16, 0xb940, 0, {0x4f,0xb3,0x43,0x24,0x00,0xdb,0x10,0x36,0xc0,0x4c,0xbe,0x22,0x6d,0x20,0xcb,0x50 }, - 16, 0xb950, 0, {0x3e,0xc9,0x4c,0xb0,0x13,0x24,0x00,0xcf,0x20,0x33,0xc0,0x3d,0xf0,0x23,0x2c,0xc0 }, - 16, 0xb960, 0, {0xd8,0x00,0x3e,0x40,0x8f,0x30,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb970, 0, {0x48,0x11,0x9c,0x04,0xb7,0x60,0x21,0xc1,0x8b,0xf0,0xa2,0x14,0x10,0x87,0x00,0x0f }, - 16, 0xb980, 0, {0xc8,0x0d,0x71,0x0a,0x1d,0x00,0x87,0x00,0x2c,0xcc,0x48,0x70,0x2a,0x9c,0x00,0x87 }, - 16, 0xb990, 0, {0x0c,0x21,0xc0,0x0c,0x72,0x02,0x0c,0xa2,0x87,0x00,0x2d,0xc0,0x0b,0x70,0x02,0x12 }, - 16, 0xb9a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb3,0x80,0x21,0xe0 }, - 16, 0xb9b0, 0, {0x0b,0x7a,0x02,0xde,0x00,0xb7,0x81,0x05,0xe4,0x08,0x79,0x02,0x5c,0x80,0x87,0xa0 }, - 16, 0xb9c0, 0, {0x2d,0xe0,0x08,0xf8,0x06,0xb6,0x00,0x87,0x80,0x20,0xe4,0x0a,0x7b,0x12,0x1e,0x90 }, - 16, 0xb9d0, 0, {0x97,0x88,0x2d,0xe0,0x0b,0x78,0x0e,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb9e0, 0, {0x48,0x14,0xcc,0x00,0xb3,0x00,0x20,0xd0,0x0b,0xb0,0x02,0x6e,0x34,0xa3,0x00,0x2c }, - 16, 0xb9f0, 0, {0xc1,0x09,0x30,0x02,0x4c,0x00,0x83,0x00,0x2c,0xc0,0x48,0x10,0x02,0x8d,0x80,0x83 }, - 16, 0xba00, 0, {0xc0,0x00,0xc0,0x8a,0x30,0x12,0x0c,0x00,0x80,0x00,0x2c,0x16,0x0b,0x38,0x02,0x12 }, - 16, 0xba10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x00,0x33,0x88 }, - 16, 0xba20, 0, {0x0f,0xa0,0x03,0x79,0x90,0xfa,0x01,0x36,0x80,0x1c,0xa0,0x03,0x68,0x00,0xca,0x00 }, - 16, 0xba30, 0, {0x3e,0x81,0x2c,0xa0,0x0b,0xb9,0x0c,0xce,0xe2,0xb2,0x80,0x8e,0xa0,0x0b,0x28,0x00 }, - 16, 0xba40, 0, {0xda,0x80,0x3c,0xb0,0x0f,0xe0,0x83,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xba50, 0, {0x48,0x00,0xe0,0x00,0xf0,0x00,0x3e,0x00,0x0f,0x80,0x03,0xa0,0x00,0xc8,0x00,0x2e }, - 16, 0xba60, 0, {0x00,0x0f,0x84,0x23,0xa0,0x00,0xf0,0x40,0x3e,0x10,0x0f,0x84,0x03,0xe1,0x02,0xf8 }, - 16, 0xba70, 0, {0x48,0x3e,0x10,0x0c,0x80,0x03,0xc0,0x10,0xf8,0x80,0x3e,0x00,0x0f,0x00,0x03,0xd2 }, - 16, 0xba80, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0x36,0x42 }, - 16, 0xba90, 0, {0x0f,0x90,0x03,0x24,0x18,0xf9,0x10,0x3c,0x48,0x68,0x92,0x13,0xe4,0x00,0xa9,0x11 }, - 16, 0xbaa0, 0, {0xb2,0x60,0x0e,0x91,0x03,0x26,0x00,0xc9,0x00,0x32,0x60,0x0c,0x10,0x03,0x24,0x08 }, - 16, 0xbab0, 0, {0xc9,0x00,0x3e,0x40,0x0c,0x90,0x23,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbac0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x40,0x0b,0x90,0x02,0xa4,0x08,0x89,0x00,0x2e }, - 16, 0xbad0, 0, {0x42,0x48,0x94,0x02,0xe4,0x00,0x89,0x80,0x22,0x70,0x08,0x14,0x22,0xa4,0x02,0x89 }, - 16, 0xbae0, 0, {0x42,0x2a,0x70,0x28,0x90,0x0a,0x24,0x00,0xa9,0x00,0x2e,0x40,0x28,0x90,0x02,0xa0 }, - 16, 0xbaf0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x99,0x00,0x26,0xc0 }, - 16, 0xbb00, 0, {0x03,0x90,0x02,0x24,0x01,0xa9,0x00,0x0e,0x40,0x0a,0x90,0x46,0xc4,0x0a,0x89,0x00 }, - 16, 0xbb10, 0, {0x20,0x48,0x0a,0x90,0x02,0x05,0x80,0x81,0x41,0xa0,0x58,0x88,0x90,0x02,0x24,0x08 }, - 16, 0xbb20, 0, {0x8d,0x80,0x2f,0xc0,0x08,0x98,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbb30, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0x20,0x40,0x0b,0x12,0x02,0x84,0x00,0x81,0x24,0x2c }, - 16, 0xbb40, 0, {0x58,0x0a,0x32,0x22,0xc5,0x84,0xa1,0x00,0x20,0x50,0x08,0xb0,0x02,0x85,0x08,0x81 }, - 16, 0xbb50, 0, {0x40,0x20,0x5a,0x08,0x16,0x82,0x04,0x00,0xa5,0x00,0x2d,0x40,0x08,0x12,0x82,0x82 }, - 16, 0xbb60, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x36,0x14 }, - 16, 0xbb70, 0, {0x0f,0x85,0x23,0x01,0x40,0xe8,0x00,0x3e,0x00,0x0e,0x80,0x43,0xc0,0x08,0xca,0x00 }, - 16, 0xbb80, 0, {0x32,0x80,0x0e,0x80,0x03,0x20,0x00,0xc0,0x00,0x32,0x08,0x2c,0x02,0x03,0x20,0x08 }, - 16, 0xbb90, 0, {0xc8,0x00,0x3f,0x00,0x0c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbba0, 0, {0x98,0x1d,0xe4,0x40,0xf9,0x10,0x3f,0x40,0x0f,0x91,0x43,0xf4,0x04,0xf9,0x10,0x3e }, - 16, 0xbbb0, 0, {0x44,0x0d,0x11,0x03,0xe4,0x44,0x59,0x40,0x3e,0x50,0x4f,0x50,0x43,0xd4,0x02,0xfd }, - 16, 0xbbc0, 0, {0x40,0x3e,0x40,0x0f,0x90,0x0b,0xe5,0x00,0xf9,0x00,0x3e,0x40,0x4f,0xd0,0x03,0xe6 }, - 16, 0xbbd0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x66,0x60,0xc9,0xe0,0x32,0x44 }, - 16, 0xbbe0, 0, {0x0f,0x9c,0x03,0xe4,0x00,0xdd,0x84,0x3f,0x68,0x8f,0xd8,0x42,0xe6,0xa0,0xdd,0xa4 }, - 16, 0xbbf0, 0, {0x33,0x68,0x0d,0x70,0x03,0x25,0x00,0xc9,0xe0,0xb2,0x68,0x0c,0x9a,0xc3,0x26,0x00 }, - 16, 0xbc00, 0, {0x99,0x00,0x3e,0x40,0x0f,0x9a,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbc10, 0, {0x38,0x10,0xe3,0x00,0x88,0x80,0xaa,0x20,0x8b,0x88,0x02,0xe2,0x88,0xb8,0x01,0x2e }, - 16, 0xbc20, 0, {0x00,0x0b,0x84,0x02,0xe2,0xb0,0x88,0x50,0x22,0x14,0x08,0x80,0x02,0x82,0x80,0x88 }, - 16, 0xbc30, 0, {0xe0,0xb6,0x3a,0x08,0xce,0xa2,0x21,0x08,0x88,0x00,0x2e,0x00,0x0b,0xc4,0x02,0x0e }, - 16, 0xbc40, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0x81,0x60,0x68,0x48 }, - 16, 0xbc50, 0, {0x5b,0x16,0x02,0xc4,0x20,0xa1,0x40,0x6c,0x50,0x0b,0x14,0x02,0xc4,0x00,0xa1,0x00 }, - 16, 0xbc60, 0, {0x24,0x40,0x0b,0x90,0x22,0x14,0x90,0x85,0x42,0x21,0x50,0x5b,0x50,0x1a,0x15,0x00 }, - 16, 0xbc70, 0, {0x95,0x00,0x2d,0x40,0x0b,0x51,0x0a,0x82,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbc80, 0, {0x18,0x15,0xa4,0x01,0x89,0x00,0x2a,0x40,0x0b,0x90,0x46,0xe4,0x00,0xb9,0x01,0x2e }, - 16, 0xbc90, 0, {0x40,0x0b,0x90,0x20,0xe4,0x00,0xb9,0x00,0x26,0x40,0x18,0xb8,0x02,0xa4,0x02,0x8d }, - 16, 0xbca0, 0, {0x08,0x2f,0x40,0x8b,0xd0,0x02,0x24,0x00,0x8d,0x20,0x2f,0x48,0x0b,0xd0,0x02,0x86 }, - 16, 0xbcb0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x32,0x40 }, - 16, 0xbcc0, 0, {0x0f,0x90,0x02,0xe4,0x10,0x49,0x00,0x3e,0x40,0x0f,0x90,0x02,0xe4,0x00,0xe9,0x01 }, - 16, 0xbcd0, 0, {0x36,0x40,0x0f,0x18,0x13,0x24,0x10,0xc9,0x82,0x32,0x40,0x7f,0x90,0x23,0x24,0x00 }, - 16, 0xbce0, 0, {0xd9,0x20,0x3e,0x72,0x0f,0x90,0x03,0xa8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbcf0, 0, {0x28,0x01,0x84,0x02,0xf1,0x01,0x16,0x40,0x4f,0x90,0x03,0xe5,0x10,0xf9,0x08,0x2e }, - 16, 0xbd00, 0, {0x40,0x0f,0x90,0x13,0xe4,0x00,0xc9,0x01,0x3a,0x40,0x1f,0x90,0x03,0xe4,0x00,0xf9 }, - 16, 0xbd10, 0, {0x20,0x34,0x40,0x8c,0x90,0x03,0xc4,0x08,0xf9,0x00,0x3e,0x60,0x0f,0x10,0x03,0x4a }, - 16, 0xbd20, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x08,0xf8,0x00,0x3e,0x00 }, - 16, 0xbd30, 0, {0x0c,0x80,0x03,0x60,0x00,0xe8,0x00,0x3e,0x02,0x4f,0x80,0x13,0xe0,0x00,0xd0,0x00 }, - 16, 0xbd40, 0, {0x3e,0x00,0x0e,0x81,0x03,0x30,0x00,0xcc,0x40,0x33,0x00,0x0c,0xc0,0x0b,0x20,0x20 }, - 16, 0xbd50, 0, {0xe8,0x00,0x3e,0x10,0x0f,0xc0,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbd60, 0, {0x28,0x05,0x28,0x04,0xba,0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0xbe,0xc8,0x6f }, - 16, 0xbd70, 0, {0x80,0x0b,0xe1,0x22,0xa8,0x00,0x8e,0x20,0x2f,0x80,0x0b,0xe0,0x23,0x68,0x00,0x8a }, - 16, 0xbd80, 0, {0x00,0x22,0x80,0x08,0xe0,0x02,0x29,0x00,0x8a,0x00,0x2e,0xa8,0x0b,0xa0,0x00,0xca }, - 16, 0xbd90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x24,0xc0 }, - 16, 0xbda0, 0, {0x09,0x30,0x02,0x0c,0x00,0xb3,0xc1,0x2c,0xe0,0x0b,0x38,0x56,0x2c,0x10,0x13,0x00 }, - 16, 0xbdb0, 0, {0x2e,0xc0,0x0a,0x38,0x6a,0x20,0x00,0x88,0x00,0x20,0x00,0x09,0x80,0x22,0x4c,0x42 }, - 16, 0xbdc0, 0, {0xa3,0x00,0x2c,0xe0,0x0b,0x24,0x80,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbdd0, 0, {0xa0,0x01,0x1c,0x08,0xb7,0x24,0x2f,0xe0,0x09,0x39,0x02,0x1c,0x01,0xb6,0x00,0x2d }, - 16, 0xbde0, 0, {0x90,0x0b,0x60,0x92,0x8e,0x00,0x86,0x82,0x2d,0xc2,0x0b,0xf0,0x02,0x5c,0x06,0x87 }, - 16, 0xbdf0, 0, {0x00,0x60,0xc0,0x29,0x70,0x02,0x5c,0x00,0x86,0x00,0x2d,0xc0,0x0b,0x60,0x02,0xe8 }, - 16, 0xbe00, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1f,0x40,0xf3,0xe4,0x3d,0xe8 }, - 16, 0xbe10, 0, {0x0d,0x79,0x0b,0x1e,0xc0,0x67,0x80,0x2d,0xe0,0x0f,0x70,0x43,0x1d,0x80,0xd5,0x00 }, - 16, 0xbe20, 0, {0x3d,0x60,0x0e,0x78,0x03,0x1e,0x00,0xcd,0x80,0x31,0xe0,0x0d,0xc8,0x03,0x4e,0x00 }, - 16, 0xbe30, 0, {0xe5,0x80,0x3d,0xe0,0x0f,0x48,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbe40, 0, {0x08,0x1d,0xac,0x80,0xfb,0x00,0x70,0xc0,0x6e,0xb6,0x13,0xad,0x40,0xfa,0x00,0x3e }, - 16, 0xbe50, 0, {0xc0,0x0f,0x20,0x43,0x2d,0x18,0x59,0x00,0x3e,0x00,0x03,0xb0,0x0b,0xe0,0x00,0xfa }, - 16, 0xbe60, 0, {0x00,0xbe,0x00,0x0e,0xb0,0x13,0xac,0x00,0xf8,0x00,0x3e,0xc0,0x0f,0x80,0x03,0xc2 }, - 16, 0xbe70, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x40,0xff,0x80,0x3f,0xe6 }, - 16, 0xbe80, 0, {0x0f,0xf8,0x23,0x2e,0x04,0xff,0x90,0x3f,0xe4,0x0d,0xba,0x03,0xff,0x40,0xcf,0x80 }, - 16, 0xbe90, 0, {0x22,0xe1,0x0c,0x39,0x43,0x32,0x10,0xec,0x90,0x33,0x20,0x8e,0xc8,0x03,0xf2,0x00 }, - 16, 0xbea0, 0, {0xdf,0x80,0x3f,0x60,0x0f,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbeb0, 0, {0xa8,0x11,0x9c,0x40,0xb7,0x90,0x3c,0xe0,0x0b,0x3a,0x03,0x4e,0x80,0xf3,0xb1,0x2d }, - 16, 0xbec0, 0, {0x04,0x4c,0x38,0x23,0xae,0x00,0x80,0x80,0x34,0xe8,0x4d,0x78,0x02,0x3e,0x80,0x87 }, - 16, 0xbed0, 0, {0xa0,0x29,0xc0,0x08,0x70,0x02,0xc0,0x80,0x86,0x02,0x2d,0x41,0x0b,0x70,0x02,0xea }, - 16, 0xbee0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x48,0x37,0x01,0x2d,0xc9 }, - 16, 0xbef0, 0, {0x0b,0x72,0x22,0x1c,0x84,0xb5,0x16,0x0d,0xc4,0x19,0x40,0x42,0xdc,0x80,0x87,0x00 }, - 16, 0xbf00, 0, {0x20,0xc8,0x88,0x73,0x0a,0x9c,0x80,0xb5,0x00,0x29,0xc0,0x0a,0x48,0x02,0xc0,0x02 }, - 16, 0xbf10, 0, {0x95,0x00,0x2d,0x42,0x0b,0x58,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbf20, 0, {0x20,0x14,0xcc,0x00,0xb3,0x00,0x2a,0xe0,0x0b,0x30,0x02,0x4c,0x20,0xa1,0x01,0x24 }, - 16, 0xbf30, 0, {0xc1,0x08,0x00,0x02,0x8c,0x00,0x81,0x00,0x24,0x80,0x09,0x38,0x0a,0x60,0x80,0x92 }, - 16, 0xbf40, 0, {0x40,0x2a,0x00,0x0a,0x30,0x02,0xc0,0x00,0x80,0xc8,0x2c,0x72,0x0b,0x14,0x02,0xc8 }, - 16, 0xbf50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xff,0x00,0x2f,0xf4 }, - 16, 0xbf60, 0, {0x8f,0xf0,0x03,0x3c,0x00,0xb9,0x00,0x3e,0x40,0x09,0x90,0x03,0xfc,0x02,0xc3,0x01 }, - 16, 0xbf70, 0, {0x32,0xc0,0x48,0xb8,0x13,0xa1,0x00,0xba,0x00,0x2a,0x00,0x0a,0xa0,0x07,0xec,0x00 }, - 16, 0xbf80, 0, {0xdb,0xc8,0x3e,0x90,0x0f,0xa2,0x02,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbf90, 0, {0x80,0x00,0xec,0x00,0xfb,0x02,0x3e,0xc4,0x0f,0xb0,0x63,0xec,0x01,0xf8,0x40,0x3e }, - 16, 0xbfa0, 0, {0x40,0x0b,0x80,0x03,0xcc,0x00,0xfa,0x42,0x3e,0xc0,0x0f,0xb5,0x00,0xac,0x58,0xe9 }, - 16, 0xbfb0, 0, {0x82,0x3e,0xc0,0x1d,0x90,0x03,0xec,0x04,0xfa,0x00,0x3e,0x80,0x0f,0xa0,0x03,0xe0 }, - 16, 0xbfc0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x0c,0xdf,0x00,0x7f,0xc0 }, - 16, 0xbfd0, 0, {0x2c,0xf0,0x03,0x7c,0x01,0xc7,0x00,0x33,0x40,0x8f,0xd0,0x03,0xfc,0x00,0xd8,0x00 }, - 16, 0xbfe0, 0, {0x15,0x44,0x0c,0xe0,0x1b,0x3c,0x00,0xcb,0x0e,0x33,0xc0,0x5c,0x62,0x02,0x1c,0x02 }, - 16, 0xbff0, 0, {0xc5,0x00,0x2b,0x80,0x0f,0xc0,0x87,0x80,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc000, 0, {0x81,0x44,0x6c,0x10,0xbb,0x00,0x2e,0xc0,0x08,0xb0,0x52,0x0c,0x01,0xfa,0xc4,0x22 }, - 16, 0xc010, 0, {0x61,0x0b,0x88,0x03,0x6c,0x00,0x88,0x47,0x2a,0x00,0x0e,0x1c,0x02,0x20,0x02,0x88 }, - 16, 0xc020, 0, {0x00,0xaa,0x00,0x28,0x90,0x0a,0x2c,0x04,0xa8,0x00,0x22,0x90,0x0b,0x80,0x02,0xe0 }, - 16, 0xc030, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x2c,0x00,0xbb,0x00,0x2e,0xc1 }, - 16, 0xc040, 0, {0x08,0x30,0x12,0x6c,0x00,0x88,0x88,0x2a,0x30,0x0b,0xb8,0x02,0xec,0x00,0x9b,0x08 }, - 16, 0xc050, 0, {0x2a,0x40,0x08,0xb8,0x02,0x20,0x00,0x82,0x10,0x22,0x00,0x08,0xa0,0x22,0xa0,0x00 }, - 16, 0xc060, 0, {0x8b,0x00,0x2a,0x02,0x0b,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc070, 0, {0x08,0x00,0x0c,0x00,0xb3,0x20,0x2c,0xc2,0x08,0x36,0x02,0x2c,0xc0,0xa0,0x08,0x20 }, - 16, 0xc080, 0, {0x00,0x0b,0x33,0x46,0xcd,0x28,0x80,0x20,0x28,0xc0,0x0b,0x32,0x02,0x0c,0x20,0x81 }, - 16, 0xc090, 0, {0x30,0x28,0xc0,0x08,0x10,0x02,0x81,0x00,0xaa,0x00,0x28,0x00,0x03,0x30,0x02,0xc2 }, - 16, 0xc0a0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x7c,0x00,0xfb,0x28,0x2e,0xcc }, - 16, 0xc0b0, 0, {0x0c,0x70,0x53,0x7d,0x09,0x88,0x00,0xba,0x00,0x0f,0x80,0x03,0xfd,0x80,0xda,0x60 }, - 16, 0xc0c0, 0, {0x3a,0x50,0x8c,0xa2,0x83,0x2c,0x80,0x4b,0x20,0x30,0xc0,0x28,0xa0,0x03,0xa1,0x00 }, - 16, 0xc0d0, 0, {0xc9,0x00,0x3a,0x00,0x0f,0x90,0x03,0xc0,0x03,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc0e0, 0, {0xa0,0x1d,0xfc,0x04,0xfb,0x00,0x7e,0xc9,0x0b,0xb6,0x03,0xfc,0xc0,0xf8,0x0c,0x3f }, - 16, 0xc0f0, 0, {0x00,0x4f,0xc3,0x43,0x2c,0x00,0xb8,0x38,0x3f,0x8e,0x5e,0xf0,0x43,0xe0,0x10,0xf8 }, - 16, 0xc100, 0, {0x30,0x3f,0x01,0x0f,0xd0,0x03,0x70,0x00,0xfc,0x00,0x37,0x00,0x0d,0xd0,0x07,0xe9 }, - 16, 0xc110, 0, {0x03,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0xe0,0xcc,0x80,0x33,0xc0 }, - 16, 0xc120, 0, {0x0d,0xf0,0x83,0xfc,0x80,0xdc,0x94,0x33,0xc0,0x1c,0xf1,0x03,0x7d,0x8c,0xff,0x30 }, - 16, 0xc130, 0, {0x3f,0x30,0x8f,0xc8,0x03,0x7e,0x10,0xcf,0x90,0x39,0xa0,0x8d,0xf8,0x03,0xae,0x00 }, - 16, 0xc140, 0, {0xd5,0x80,0x13,0xe0,0x0c,0x58,0x03,0xf0,0x01,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc150, 0, {0x80,0x10,0xdd,0x08,0x88,0x00,0x23,0xc4,0x08,0xfc,0x02,0xec,0xa8,0xcb,0x20,0x21 }, - 16, 0xc160, 0, {0xc2,0x0d,0xf7,0x12,0x1c,0x40,0xdf,0x30,0x22,0xa0,0x0b,0x88,0x02,0x2e,0x04,0xdb }, - 16, 0xc170, 0, {0x21,0x22,0xc0,0x08,0xb8,0x22,0x2e,0x00,0xb9,0x80,0x2a,0x60,0x0a,0x88,0x02,0xe0 }, - 16, 0xc180, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x45,0xcc,0x10,0x80,0x2c,0x28,0xca }, - 16, 0xc190, 0, {0x68,0x30,0x02,0x8d,0x00,0x9b,0x20,0x28,0xc4,0x08,0x32,0x02,0xcc,0x10,0xb3,0x00 }, - 16, 0xc1a0, 0, {0x24,0x08,0x0b,0x80,0x42,0x6c,0x00,0x83,0x00,0x2a,0xca,0x3a,0xb0,0x02,0x8c,0x04 }, - 16, 0xc1b0, 0, {0xb0,0x04,0x28,0xc0,0x08,0x10,0x02,0xe3,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc1c0, 0, {0xc0,0x15,0x8c,0x02,0x80,0x40,0xaa,0xc0,0x08,0xb0,0x02,0xec,0x00,0x9b,0x20,0x2a }, - 16, 0xc1d0, 0, {0xc0,0x88,0xb0,0x02,0xac,0x00,0x9b,0x00,0x26,0xe0,0x03,0x80,0x82,0x2c,0x28,0x9b }, - 16, 0xc1e0, 0, {0x20,0x22,0xe1,0x0b,0xb2,0x02,0xac,0x80,0xb8,0x80,0x2a,0xc1,0x0a,0x98,0x02,0xf0 }, - 16, 0xc1f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xc8,0x50,0x3a,0xc0 }, - 16, 0xc200, 0, {0x0d,0xb0,0x03,0xec,0x00,0xdb,0x88,0xba,0xc0,0x08,0xb0,0x03,0x6c,0x08,0xfb,0x00 }, - 16, 0xc210, 0, {0x36,0x60,0x0f,0x8c,0x63,0x6c,0x00,0xcb,0xc0,0x3a,0x80,0x0e,0xbe,0x03,0xaf,0x84 }, - 16, 0xc220, 0, {0x79,0x80,0x3a,0x88,0x04,0x98,0x01,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc230, 0, {0xe0,0x01,0xbc,0x00,0xfc,0x80,0x35,0xc0,0x4f,0xf0,0x03,0xdc,0x00,0xef,0x00,0x37 }, - 16, 0xc240, 0, {0xc0,0xaf,0xf0,0x03,0x1c,0x01,0x6f,0x00,0x13,0x00,0x0f,0xc1,0x23,0xfc,0xb8,0xff }, - 16, 0xc250, 0, {0x04,0x37,0xc0,0x0c,0xf8,0x43,0x7e,0x04,0xfd,0x00,0x3f,0x04,0x0f,0xd0,0x03,0xf8 }, - 16, 0xc260, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xc8,0x40,0x3a,0xc0 }, - 16, 0xc270, 0, {0x0c,0xb0,0x03,0xec,0x00,0xfb,0x40,0x38,0xc1,0x0e,0xb0,0x43,0x2c,0x08,0xc3,0x00 }, - 16, 0xc280, 0, {0x3e,0x40,0x0e,0x82,0x03,0x6d,0x00,0xdb,0x40,0x32,0xc1,0x5f,0xb4,0xa3,0xed,0x20 }, - 16, 0xc290, 0, {0xc9,0x40,0x32,0xe0,0x8f,0x98,0x43,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc2a0, 0, {0xc8,0x05,0x3c,0x00,0x88,0x00,0x23,0xc0,0x28,0xf5,0xc2,0xfc,0x00,0xb3,0x04,0x23 }, - 16, 0xc2b0, 0, {0xc1,0x48,0xf0,0x22,0xbc,0x06,0xaf,0x00,0x0e,0x40,0x08,0x00,0x02,0xcd,0x00,0xbb }, - 16, 0xc2c0, 0, {0x01,0x20,0xc0,0x08,0x30,0x02,0xee,0x00,0x81,0xe0,0x34,0xa0,0x0b,0x90,0x02,0x32 }, - 16, 0xc2d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x02,0x80,0x00,0x28,0xc0 }, - 16, 0xc2e0, 0, {0x09,0x3c,0x02,0x4c,0x00,0xb3,0x00,0x2c,0xc0,0x0a,0xb0,0x02,0x0c,0x00,0x83,0x01 }, - 16, 0xc2f0, 0, {0x2c,0x00,0x0a,0x05,0x02,0xcd,0x58,0xbb,0x00,0x20,0x00,0x0a,0x3d,0x02,0xcf,0x40 }, - 16, 0xc300, 0, {0x21,0x20,0x60,0xc0,0x09,0x10,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc310, 0, {0x20,0x01,0x1e,0x00,0x84,0x80,0x28,0xe4,0x88,0x78,0x42,0xde,0x00,0xb7,0x90,0x65 }, - 16, 0xc320, 0, {0xe4,0x88,0x7a,0x42,0x9e,0x40,0xa7,0x90,0x2d,0xa0,0x0a,0x48,0x22,0xde,0x04,0xb7 }, - 16, 0xc330, 0, {0x80,0x23,0x60,0x48,0x78,0x42,0xfe,0x80,0xaf,0x90,0x65,0xe0,0x0b,0xe8,0x02,0xc8 }, - 16, 0xc340, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xc8,0x00,0x38,0xc0 }, - 16, 0xc350, 0, {0x0c,0x30,0x03,0xcc,0x00,0xfb,0x00,0x3c,0xc0,0x0e,0xba,0x03,0x0c,0x00,0xc3,0x00 }, - 16, 0xc360, 0, {0x3e,0x00,0x4e,0x22,0x02,0xcc,0xc0,0xfb,0x40,0x30,0xc0,0x0a,0x30,0x03,0xce,0x80 }, - 16, 0xc370, 0, {0xe1,0x41,0x30,0xc9,0x0f,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc380, 0, {0x40,0x1d,0xbc,0x20,0xfc,0x00,0x37,0xc2,0x0e,0xf1,0x23,0xec,0x40,0xff,0x04,0x3a }, - 16, 0xc390, 0, {0xc0,0x0f,0xb0,0x23,0xfc,0x00,0xff,0x04,0x3e,0xc0,0x0d,0xa0,0x03,0xfc,0x58,0xff }, - 16, 0xc3a0, 0, {0x00,0xbf,0xc0,0x06,0xf0,0x83,0xdc,0x62,0xdf,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0x10 }, - 16, 0xc3b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xed,0x80,0xc9,0x01,0x3e,0xc0 }, - 16, 0xc3c0, 0, {0x8c,0xb2,0x07,0xae,0x04,0xcb,0x80,0x3a,0xc8,0x4c,0xb2,0x03,0x2c,0x84,0xcb,0x30 }, - 16, 0xc3d0, 0, {0xb0,0xe0,0x0d,0x88,0x0b,0x2c,0x00,0xeb,0x00,0x30,0x00,0x0c,0xbc,0x83,0x2d,0x80 }, - 16, 0xc3e0, 0, {0xfb,0x00,0x32,0xc0,0x0c,0x90,0x03,0xea,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc3f0, 0, {0x48,0x11,0x9c,0x40,0x87,0x00,0x2c,0xcc,0x08,0x76,0x82,0x3c,0x82,0x87,0x00,0x21 }, - 16, 0xc400, 0, {0xc2,0x8d,0x32,0x82,0x0d,0x4c,0xa7,0x28,0x21,0x80,0x08,0x40,0x02,0x1d,0x80,0xbf }, - 16, 0xc410, 0, {0x20,0x35,0x40,0x09,0x72,0x43,0x5c,0xa0,0xb7,0x00,0x29,0xc0,0x08,0x70,0x02,0xd2 }, - 16, 0xc420, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x84,0x80,0x2d,0xe0 }, - 16, 0xc430, 0, {0x08,0x78,0x02,0xde,0xc0,0x8f,0x80,0x28,0xec,0x28,0x7b,0x0a,0x9e,0x94,0x83,0x84 }, - 16, 0xc440, 0, {0x23,0xe0,0x09,0x58,0x50,0x9e,0x10,0xa7,0xb0,0x23,0xe0,0x0b,0x78,0x02,0x1e,0x20 }, - 16, 0xc450, 0, {0xb7,0x80,0x21,0xe0,0x09,0x78,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc460, 0, {0x48,0x14,0xcc,0x02,0x82,0x1c,0x2c,0xc0,0x28,0x30,0x02,0x4c,0x00,0x83,0xc0,0x20 }, - 16, 0xc470, 0, {0xc0,0x08,0x30,0x02,0x0c,0x00,0xa3,0x00,0x60,0xd2,0x08,0x1d,0x02,0x0f,0x20,0xbb }, - 16, 0xc480, 0, {0x24,0x24,0xc0,0x0b,0x3c,0x02,0x4f,0x00,0xb3,0x80,0x28,0xd8,0x09,0x32,0x02,0xd2 }, - 16, 0xc490, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x11,0xa8,0x00,0xce,0x84,0x3e,0x80 }, - 16, 0xc4a0, 0, {0x0c,0xa0,0x03,0xe8,0x00,0xce,0xc0,0x3a,0x80,0x08,0xa0,0x03,0xa8,0x00,0xca,0x00 }, - 16, 0xc4b0, 0, {0x33,0x80,0x0d,0xec,0x03,0x3b,0x80,0xee,0x82,0x33,0x80,0x0a,0xc0,0x87,0x10,0x40 }, - 16, 0xc4c0, 0, {0xf6,0xc0,0x33,0x90,0xad,0x64,0x03,0xfa,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc4d0, 0, {0x48,0x00,0xc0,0x02,0xf8,0x00,0x3c,0x00,0x1f,0x04,0x03,0xa0,0x04,0xf8,0x30,0x3e }, - 16, 0xc4e0, 0, {0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x04,0x0f,0x80,0x93,0xe0,0x00,0xf8 }, - 16, 0xc4f0, 0, {0x10,0x3e,0x00,0x2c,0x84,0x03,0xe0,0x00,0xf8,0x18,0x3e,0x10,0x0e,0x80,0x03,0xd2 }, - 16, 0xc500, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0x3e,0x40 }, - 16, 0xc510, 0, {0x0e,0x90,0x03,0xa4,0x10,0xf9,0x00,0x3e,0x40,0x04,0x90,0x03,0x24,0x00,0x41,0x00 }, - 16, 0xc520, 0, {0x3e,0x40,0x0f,0x91,0x13,0xe1,0x08,0xf8,0x00,0x32,0x40,0x08,0x89,0x83,0xa2,0x00 }, - 16, 0xc530, 0, {0xc9,0x80,0x32,0x40,0x0c,0x90,0x0b,0x02,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc540, 0, {0x80,0x04,0x64,0x02,0x89,0x00,0x2e,0x40,0x0d,0x90,0x02,0x24,0x00,0xb9,0x00,0x2e }, - 16, 0xc550, 0, {0x40,0x48,0x90,0x02,0xa4,0x00,0x89,0x00,0x22,0x40,0x8b,0x94,0x42,0xe2,0x20,0xb8 }, - 16, 0xc560, 0, {0x00,0xa2,0x40,0x08,0x94,0x02,0xe5,0x04,0xa9,0x90,0x34,0x60,0x08,0x90,0x02,0x20 }, - 16, 0xc570, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x10,0x99,0x00,0x2e,0x40 }, - 16, 0xc580, 0, {0x0a,0x90,0x02,0xe4,0x00,0xb9,0x00,0x24,0x40,0x0a,0x10,0x02,0x04,0x00,0xa9,0x00 }, - 16, 0xc590, 0, {0x2a,0x40,0x0b,0x90,0x82,0xe0,0x01,0xb8,0x00,0x20,0x40,0x3a,0x90,0x02,0xa4,0x44 }, - 16, 0xc5a0, 0, {0x89,0x04,0x22,0x62,0x08,0x98,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc5b0, 0, {0x08,0x04,0x04,0x8a,0x81,0x00,0x2c,0x48,0x09,0x32,0x06,0x44,0x80,0xb1,0x00,0x2c }, - 16, 0xc5c0, 0, {0x48,0x0a,0x12,0x02,0x84,0x80,0xa1,0x20,0x20,0x50,0x0b,0x14,0x02,0xc5,0x00,0xb1 }, - 16, 0xc5d0, 0, {0x40,0x20,0x50,0x0a,0x24,0x02,0xc9,0x00,0xa3,0x00,0x24,0x40,0x08,0x11,0x02,0x02 }, - 16, 0xc5e0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x3e,0x14 }, - 16, 0xc5f0, 0, {0x0e,0x80,0x03,0xe1,0x40,0xf8,0x51,0x36,0x14,0x2e,0x85,0x43,0x21,0x42,0xe8,0x50 }, - 16, 0xc600, 0, {0x3a,0x00,0x0f,0x80,0x12,0xe0,0x00,0xf8,0x00,0x32,0x00,0x1e,0x80,0x43,0xa0,0x00 }, - 16, 0xc610, 0, {0xc8,0x01,0x32,0x00,0x0c,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc620, 0, {0x98,0x1d,0xe4,0x40,0xfd,0x00,0x3e,0x44,0x4e,0x11,0x03,0xa4,0x40,0xb5,0x00,0x3e }, - 16, 0xc630, 0, {0x44,0x0d,0x91,0x03,0xe4,0x40,0xd9,0x10,0x3f,0x40,0x0f,0x50,0x03,0xe5,0x00,0xf9 }, - 16, 0xc640, 0, {0x40,0x3f,0x40,0x0d,0x44,0x03,0xf1,0x00,0xf5,0x02,0x3d,0xc0,0x2f,0xd2,0x03,0xe6 }, - 16, 0xc650, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe7,0x00,0xe9,0x00,0x36,0x60 }, - 16, 0xc660, 0, {0x0d,0xda,0x03,0xe6,0x40,0xf9,0x40,0x3e,0x68,0x0c,0x9a,0x03,0x66,0x20,0x89,0xa0 }, - 16, 0xc670, 0, {0x33,0x40,0x0e,0x90,0x07,0xa6,0x00,0xf9,0x80,0x3e,0x50,0x0c,0xca,0x03,0xf3,0x80 }, - 16, 0xc680, 0, {0xc5,0x02,0x33,0x40,0x0c,0xc0,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc690, 0, {0x38,0x10,0xe3,0x04,0x88,0xa2,0x20,0x38,0x08,0x80,0x02,0xe3,0x40,0xb0,0x80,0x2e }, - 16, 0xc6a0, 0, {0x28,0x08,0x8a,0x82,0x23,0x80,0x88,0x80,0x22,0x00,0xdb,0x88,0x02,0x62,0x04,0xb8 }, - 16, 0xc6b0, 0, {0xb0,0x2e,0xa8,0x88,0x8e,0xa2,0xea,0x80,0x88,0x00,0x2a,0x00,0x28,0x88,0x03,0x8e }, - 16, 0xc6c0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x82,0xa9,0x08,0x2c,0x52 }, - 16, 0xc6d0, 0, {0x0b,0x14,0x02,0xc4,0x80,0xb1,0x21,0x0c,0x52,0x88,0x14,0x02,0x44,0x20,0x91,0x69 }, - 16, 0xc6e0, 0, {0x20,0x40,0x0a,0x10,0x82,0xc6,0xe0,0xb1,0x0c,0x2c,0x48,0x08,0x01,0x02,0xe1,0x93 }, - 16, 0xc6f0, 0, {0xa1,0x01,0x24,0x41,0x0a,0x10,0x02,0xc2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc700, 0, {0x18,0x15,0xa4,0x00,0x89,0x04,0x22,0x40,0x08,0x90,0x00,0xe4,0x00,0x39,0x02,0x0e }, - 16, 0xc710, 0, {0x40,0x08,0x10,0x62,0x24,0x00,0x91,0x00,0x62,0x40,0x8b,0x80,0x02,0xe0,0x54,0xb9 }, - 16, 0xc720, 0, {0x0c,0x2e,0x40,0x09,0xb6,0x52,0xec,0x00,0xa9,0x00,0x2a,0x40,0x0a,0x92,0x80,0x86 }, - 16, 0xc730, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe4,0x00,0xe1,0x60,0x36,0x40 }, - 16, 0xc740, 0, {0x0d,0x90,0x23,0xe4,0x00,0xf9,0x30,0x3e,0x40,0x2c,0x90,0x43,0x64,0x06,0xc9,0x00 }, - 16, 0xc750, 0, {0x32,0x49,0x0e,0x8d,0x93,0xe0,0x00,0xf9,0x00,0x2e,0x40,0x2c,0x94,0x03,0xc7,0x40 }, - 16, 0xc760, 0, {0xe9,0x20,0x30,0x55,0x0e,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc770, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x1e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x80,0x3c }, - 16, 0xc780, 0, {0x40,0x4f,0x90,0x03,0xe4,0x00,0xe9,0x04,0xbe,0x40,0x0f,0x88,0x33,0x62,0x00,0xf9 }, - 16, 0xc790, 0, {0xc2,0x3e,0x48,0x2e,0x88,0x33,0xe2,0x00,0xd9,0x00,0x3e,0x60,0x0d,0x80,0x03,0xca }, - 16, 0xc7a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x3e,0x00 }, - 16, 0xc7b0, 0, {0x0d,0x80,0x03,0xa0,0x04,0xe8,0x40,0xba,0x00,0x0c,0x80,0x03,0xe0,0x04,0xc8,0x00 }, - 16, 0xc7c0, 0, {0x3a,0x00,0x0e,0x8c,0x03,0xe0,0x00,0xf8,0x02,0x32,0x00,0x0e,0x80,0x03,0x61,0x20 }, - 16, 0xc7d0, 0, {0xf8,0x00,0x32,0x16,0x0f,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc7e0, 0, {0x28,0x05,0x28,0x00,0x8a,0x00,0x2e,0x80,0x08,0xe2,0x03,0x28,0x00,0x8a,0x00,0x22 }, - 16, 0xc7f0, 0, {0x80,0x08,0xa0,0x02,0xe8,0x04,0x8a,0x00,0x2e,0xa2,0x09,0xe8,0x02,0xfa,0x04,0xbe }, - 16, 0xc800, 0, {0x00,0xa2,0x80,0x08,0xcd,0x82,0x33,0x20,0xb6,0xc0,0x37,0xa0,0x4b,0xc8,0x82,0xca }, - 16, 0xc810, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x00,0x83,0x00,0x26,0xc0 }, - 16, 0xc820, 0, {0x09,0x38,0x02,0x4c,0x00,0xb3,0x00,0x24,0xc0,0x08,0x30,0x02,0xec,0x00,0x83,0x00 }, - 16, 0xc830, 0, {0x28,0xe0,0x0b,0x30,0x02,0xce,0x81,0xb3,0x00,0x62,0xc0,0x08,0x3c,0x02,0x4f,0x00 }, - 16, 0xc840, 0, {0xb3,0xa0,0x20,0xb0,0x03,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc850, 0, {0xa0,0x01,0x0c,0x41,0x87,0x34,0x2d,0xc0,0x08,0x60,0x02,0x9e,0x40,0xb7,0xa0,0x2d }, - 16, 0xc860, 0, {0xc0,0x08,0x73,0x02,0xdc,0x00,0x87,0x20,0x2d,0xc0,0x0b,0x70,0x82,0xdd,0x85,0xbf }, - 16, 0xc870, 0, {0x81,0x63,0xc8,0x88,0x7b,0x02,0x1c,0x00,0xb7,0x40,0x65,0x00,0x1b,0x72,0x02,0xe8 }, - 16, 0xc880, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x81,0x3d,0xe0 }, - 16, 0xc890, 0, {0xdd,0x70,0x03,0xfe,0x80,0xf7,0x90,0x3f,0xe0,0x2c,0x79,0x03,0xfe,0x80,0xc7,0xa0 }, - 16, 0xc8a0, 0, {0x39,0xe0,0x0f,0x7a,0x02,0xde,0x84,0xf7,0xc2,0x31,0xf2,0x0c,0x79,0x03,0x5e,0x04 }, - 16, 0xc8b0, 0, {0xf7,0x84,0x31,0x60,0x0f,0x7e,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc8c0, 0, {0x08,0x1d,0xad,0x0a,0xfb,0x60,0x7e,0xd4,0x0f,0x30,0x03,0x6c,0x00,0xcb,0x00,0x32 }, - 16, 0xc8d0, 0, {0xde,0x2f,0xb2,0x03,0xed,0x42,0x1b,0x60,0x3e,0xc1,0x0d,0xb1,0x03,0xec,0x50,0xf7 }, - 16, 0xc8e0, 0, {0x80,0x3d,0xd8,0x2e,0x32,0x03,0xec,0x30,0xfb,0x00,0x3e,0x40,0x0f,0xb0,0x03,0xc2 }, - 16, 0xc8f0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x00,0xcb,0xd0,0x3f,0xf0 }, - 16, 0xc900, 0, {0x4c,0xf8,0x13,0xfe,0x00,0xcf,0x88,0x3f,0xe0,0x0c,0xf8,0x43,0x3f,0x00,0xcf,0xc8 }, - 16, 0xc910, 0, {0x33,0xe0,0x0c,0xf8,0x03,0xfe,0x00,0xff,0x80,0x3f,0xe0,0x2c,0xf8,0x03,0xbe,0x20 }, - 16, 0xc920, 0, {0xc7,0x80,0x33,0xe0,0x0c,0xf8,0x01,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc930, 0, {0xa8,0x01,0xbc,0x40,0x87,0x90,0x3d,0xc0,0x08,0x40,0x02,0xdc,0x80,0xd7,0x00,0x2d }, - 16, 0xc940, 0, {0xc0,0x0c,0x30,0x03,0x7c,0x00,0x87,0x10,0x21,0xc4,0x1e,0x70,0x20,0xdc,0x44,0xb7 }, - 16, 0xc950, 0, {0x00,0x39,0xc0,0x0c,0x71,0x02,0x1c,0x40,0xd7,0x02,0x29,0x40,0x08,0x70,0x02,0x2a }, - 16, 0xc960, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x32,0x2d,0xc0 }, - 16, 0xc970, 0, {0x08,0x70,0x02,0xdc,0x01,0x87,0x00,0x2c,0xc0,0x2b,0x70,0x0a,0x5c,0x00,0x83,0x00 }, - 16, 0xc980, 0, {0x23,0xc0,0x08,0x70,0x02,0xdd,0x00,0xb7,0x00,0x2d,0xc4,0x0b,0xf0,0x02,0x9c,0x20 }, - 16, 0xc990, 0, {0x87,0x18,0x29,0x40,0x08,0x70,0x82,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc9a0, 0, {0x20,0x14,0xcc,0x00,0x83,0x02,0x28,0xc0,0x08,0x10,0x02,0xcc,0x08,0x83,0x40,0x2e }, - 16, 0xc9b0, 0, {0xc0,0x2a,0x30,0x02,0x0c,0x00,0x8b,0x00,0x20,0xf2,0x0a,0x30,0x02,0xce,0x00,0xb3 }, - 16, 0xc9c0, 0, {0x88,0x2a,0xd0,0x0a,0x30,0x06,0x0c,0x00,0x92,0x00,0x28,0x78,0x08,0x3c,0x42,0x08 }, - 16, 0xc9d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x02,0xc7,0x00,0x2f,0xc0 }, - 16, 0xc9e0, 0, {0x2c,0x90,0x02,0xfc,0x02,0x8f,0xd8,0x3f,0xc0,0x4b,0xf0,0x02,0x7c,0x02,0xcf,0x00 }, - 16, 0xc9f0, 0, {0x20,0xf2,0x08,0xb0,0x13,0xee,0x80,0xff,0x00,0x3f,0xd4,0x2e,0xbd,0x83,0xac,0x00 }, - 16, 0xca00, 0, {0xcb,0x80,0x3a,0xa0,0xac,0xb8,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xca10, 0, {0x80,0x00,0xec,0x00,0xfb,0x10,0x3e,0xc0,0x0f,0x84,0x03,0xec,0x10,0xfb,0x00,0x3e }, - 16, 0xca20, 0, {0xc0,0x01,0xb0,0x03,0xec,0x00,0xfb,0x00,0xbe,0xc0,0x0e,0xb0,0x23,0xec,0x08,0xfb }, - 16, 0xca30, 0, {0x10,0x3f,0xc0,0x0d,0xb4,0x03,0xed,0x04,0xf9,0x00,0x1e,0x14,0xcf,0xb0,0x83,0xe0 }, - 16, 0xca40, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xcf,0x00,0x30,0xc0 }, - 16, 0xca50, 0, {0x0c,0x40,0x03,0xac,0x00,0xff,0x00,0x3f,0xc0,0x2c,0xb0,0x03,0xbc,0x00,0xff,0x00 }, - 16, 0xca60, 0, {0xb3,0xe0,0x0d,0xfa,0x03,0x7e,0x80,0xcf,0x00,0x33,0xc0,0x0c,0xfc,0x43,0xff,0x20 }, - 16, 0xca70, 0, {0xff,0x00,0x3f,0x40,0x08,0xf8,0x03,0xc0,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xca80, 0, {0x81,0x04,0x6c,0x10,0xab,0x00,0x2a,0xc0,0x0a,0x8e,0x42,0x2c,0x04,0xbb,0x00,0x2e }, - 16, 0xca90, 0, {0xc0,0x08,0xb0,0x02,0x6c,0x00,0xbb,0x00,0x3a,0xc0,0x0e,0x30,0x02,0x0d,0x08,0x83 }, - 16, 0xcaa0, 0, {0x02,0x22,0xc0,0x0a,0xbc,0x02,0xef,0x00,0xbb,0xc0,0x2c,0x68,0x0a,0xb9,0x02,0xe0 }, - 16, 0xcab0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x0c,0x00,0x8b,0x00,0x22,0xc0 }, - 16, 0xcac0, 0, {0x08,0xb8,0x02,0xac,0x00,0xbb,0x02,0x2e,0xc0,0x08,0xb0,0x02,0xec,0x00,0xbb,0x00 }, - 16, 0xcad0, 0, {0x26,0x48,0x19,0xb0,0x02,0x6d,0x00,0x8b,0x00,0x22,0xc0,0x0a,0xb0,0x02,0xec,0x04 }, - 16, 0xcae0, 0, {0xbb,0x1c,0x2e,0x20,0x0a,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcaf0, 0, {0x08,0x14,0x0c,0x00,0xab,0x20,0x28,0xc0,0x0a,0x00,0x02,0x0c,0x00,0x93,0x04,0x2c }, - 16, 0xcb00, 0, {0xc1,0x08,0x30,0x02,0x4c,0x00,0xb3,0x00,0x24,0x41,0x09,0xb8,0x02,0x0c,0x02,0x83 }, - 16, 0xcb10, 0, {0x01,0xa0,0xc0,0x0a,0x30,0x02,0xcc,0x10,0x93,0x00,0x2c,0x00,0x0a,0x30,0x02,0xc2 }, - 16, 0xcb20, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x7c,0x00,0xcf,0x28,0x33,0xc0 }, - 16, 0xcb30, 0, {0x0c,0xa0,0x46,0xac,0x11,0xbf,0x00,0x3f,0xc0,0x5c,0xf0,0x43,0xfc,0x00,0xff,0x04 }, - 16, 0xcb40, 0, {0x32,0x40,0x0d,0xb0,0x03,0x6c,0x08,0xcb,0x04,0x31,0xc0,0x0c,0xb0,0x33,0xed,0x40 }, - 16, 0xcb50, 0, {0xfb,0x04,0x3e,0x40,0x0e,0xb0,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcb60, 0, {0xa0,0x15,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xc0,0x23,0xfc,0x01,0xff,0x00,0x3f }, - 16, 0xcb70, 0, {0xc0,0x4f,0xf0,0x87,0x7c,0x00,0xff,0x00,0x39,0x40,0x0e,0xf0,0x03,0xfc,0x00,0xff }, - 16, 0xcb80, 0, {0x00,0x3f,0xc0,0x0f,0x70,0x03,0xdc,0x80,0xff,0x00,0x3d,0x40,0x0f,0x70,0x03,0xe8 }, - 16, 0xcb90, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x40,0xeb,0x48,0x3e,0xc2 }, - 16, 0xcba0, 0, {0x0e,0x09,0x03,0xbc,0x60,0xc0,0x20,0x35,0x24,0x0e,0xd2,0x13,0x2c,0x60,0xfb,0x6a }, - 16, 0xcbb0, 0, {0x33,0xc0,0x0f,0xca,0x03,0x22,0x20,0xc0,0x80,0x37,0xc0,0x0d,0xf0,0x03,0x7c,0x00 }, - 16, 0xcbc0, 0, {0xef,0x00,0x33,0x24,0x0f,0xc8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcbd0, 0, {0x80,0x10,0xdd,0x00,0x8f,0x60,0x2f,0xd8,0x08,0xa2,0x02,0xfd,0x80,0xc8,0x70,0x22 }, - 16, 0xcbe0, 0, {0x00,0x2c,0xfd,0x07,0xdc,0x84,0xbf,0x60,0x23,0xd2,0x0b,0xbd,0x02,0x23,0x00,0x88 }, - 16, 0xcbf0, 0, {0x80,0xa2,0x20,0x88,0xb0,0x22,0x34,0x00,0xbb,0x50,0x22,0xc8,0x0b,0xb0,0x02,0x20 }, - 16, 0xcc00, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x40,0xa3,0x03,0x2c,0xc2 }, - 16, 0xcc10, 0, {0x0a,0x00,0x42,0x8c,0x82,0xa3,0x0a,0x24,0x80,0x0b,0x30,0x02,0xcc,0x90,0xb3,0x00 }, - 16, 0xcc20, 0, {0x28,0xd8,0x0b,0x10,0x02,0x8c,0x02,0x90,0x00,0x20,0xc0,0x0b,0x10,0x42,0x4c,0x00 }, - 16, 0xcc30, 0, {0xb3,0x04,0x24,0xc0,0x0b,0x30,0x0e,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcc40, 0, {0xc0,0x15,0xac,0x10,0x9b,0x04,0x2c,0xc0,0xf8,0x98,0x06,0xec,0x00,0xab,0x80,0x26 }, - 16, 0xcc50, 0, {0x20,0x08,0x90,0x2a,0xac,0x10,0xbb,0x00,0x0a,0xc0,0x1b,0xb0,0x22,0xad,0x00,0x98 }, - 16, 0xcc60, 0, {0x40,0x2a,0x70,0x4b,0xb0,0x02,0x2c,0x00,0xb3,0x00,0xa6,0x86,0x1b,0xb0,0x82,0xb0 }, - 16, 0xcc70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xeb,0x00,0x3e,0xc0 }, - 16, 0xcc80, 0, {0x8e,0x98,0x03,0xac,0x08,0xe8,0xc0,0x36,0x30,0x4f,0xb0,0x42,0xec,0x00,0xf9,0x80 }, - 16, 0xcc90, 0, {0x3a,0xc0,0x8f,0x88,0x42,0x20,0x10,0xc8,0x10,0x30,0xf0,0x0f,0x30,0x13,0x6c,0x10 }, - 16, 0xcca0, 0, {0xeb,0x00,0x36,0xf0,0x0f,0xbd,0x03,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xccb0, 0, {0xe0,0x01,0xbc,0x00,0xef,0x04,0x7f,0xc0,0x0f,0xf0,0x43,0xdc,0x00,0xc4,0x00,0x3b }, - 16, 0xccc0, 0, {0x40,0x8b,0xdc,0x03,0x7c,0x10,0xf9,0x90,0x36,0xc2,0x4f,0xf9,0x23,0x62,0x41,0xac }, - 16, 0xccd0, 0, {0x01,0x13,0x40,0x04,0xb0,0x03,0xe4,0x00,0xff,0x00,0x3b,0xc0,0x0f,0xc0,0x03,0x78 }, - 16, 0xcce0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8c,0x12,0xcb,0x00,0xf2,0xc0 }, - 16, 0xccf0, 0, {0x0f,0x80,0x03,0xac,0x08,0xd9,0x00,0x3a,0x80,0x0f,0x12,0x03,0xac,0x00,0xe1,0x00 }, - 16, 0xcd00, 0, {0x32,0xc0,0x0c,0x90,0x03,0xed,0x02,0xc8,0x40,0x3e,0xd0,0x0f,0x90,0x13,0x2c,0x02 }, - 16, 0xcd10, 0, {0xdb,0x00,0x3e,0x50,0x0c,0xb4,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcd20, 0, {0xc8,0x05,0x3c,0x00,0x8f,0x00,0x17,0xc0,0x08,0x90,0x02,0x3c,0x08,0x8d,0x00,0x22 }, - 16, 0xcd30, 0, {0x54,0x08,0xb4,0x03,0x3c,0x00,0x89,0x00,0x23,0xc0,0x40,0x35,0x02,0xcc,0x24,0x80 }, - 16, 0xcd40, 0, {0x00,0x22,0x74,0x4c,0xb0,0x02,0x2c,0x00,0x8f,0x00,0x2e,0xd4,0x0a,0xb0,0x0a,0x32 }, - 16, 0xcd50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x4c,0x02,0x83,0x00,0x24,0xc0 }, - 16, 0xcd60, 0, {0x09,0x00,0x02,0x8c,0x01,0x90,0x00,0x6a,0x41,0x0a,0x30,0x20,0x4e,0x10,0x31,0x02 }, - 16, 0xcd70, 0, {0x2c,0xc0,0x09,0x20,0x06,0xce,0x00,0x80,0x00,0x60,0xe0,0x0a,0x30,0x82,0x0c,0x08 }, - 16, 0xcd80, 0, {0x83,0x08,0x2c,0xd0,0x09,0xb0,0x02,0x78,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcd90, 0, {0x20,0x01,0x1e,0x04,0x87,0xb0,0x20,0xec,0x09,0xe9,0x02,0x8e,0x58,0x9d,0xb0,0x2b }, - 16, 0xcda0, 0, {0xa5,0x40,0x5b,0x06,0xde,0x40,0x95,0x94,0x2d,0xe4,0x19,0x7b,0x06,0xde,0x00,0x84 }, - 16, 0xcdb0, 0, {0x80,0x60,0xe0,0x0a,0x78,0x0a,0x16,0x10,0x87,0x80,0x2d,0x68,0x0b,0x79,0x02,0x48 }, - 16, 0xcdc0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xcb,0xa0,0x24,0xe0 }, - 16, 0xcdd0, 0, {0x0f,0x2a,0x03,0x8e,0x00,0xd2,0xd0,0x38,0xfa,0x0f,0x18,0xc3,0xce,0x24,0x31,0xb0 }, - 16, 0xcde0, 0, {0x3c,0xe5,0x0c,0x3b,0x17,0xce,0x04,0xc0,0x82,0x38,0xc2,0x9e,0x10,0x03,0x0c,0x00 }, - 16, 0xcdf0, 0, {0xc3,0x01,0x3e,0xc0,0x0d,0x81,0x03,0x52,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xce00, 0, {0x40,0x1d,0xbc,0x00,0xef,0x10,0x3e,0xc2,0x0e,0xb1,0x23,0x2c,0xc1,0xab,0x01,0x36 }, - 16, 0xce10, 0, {0x80,0x0f,0xb0,0x23,0x2d,0x90,0xe9,0x84,0x72,0xc8,0x62,0xf1,0x17,0xfc,0x00,0xfc }, - 16, 0xce20, 0, {0x00,0x3b,0xc4,0x1d,0xf0,0x03,0xec,0x00,0xef,0x08,0x3f,0xc8,0x0e,0xf1,0x03,0x90 }, - 16, 0xce30, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x80,0xfb,0xa4,0x3a,0xc8 }, - 16, 0xce40, 0, {0x0e,0x90,0x03,0x2c,0x04,0xca,0x00,0x30,0x60,0x2d,0x1a,0x27,0x6c,0x84,0xcb,0x60 }, - 16, 0xce50, 0, {0x32,0xd2,0x0c,0xa0,0x13,0x2d,0x84,0xcb,0x02,0x3e,0xc0,0x0d,0xb8,0x03,0xac,0x80 }, - 16, 0xce60, 0, {0xcb,0x81,0x32,0x80,0x0c,0xb0,0x03,0xaa,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xce70, 0, {0x48,0x11,0x9c,0xa4,0xb7,0x28,0x73,0xc2,0x08,0xf0,0x02,0x3c,0xc0,0x8f,0x00,0x31 }, - 16, 0xce80, 0, {0xc0,0x09,0x70,0x82,0x9c,0x80,0x87,0x0c,0x20,0xd8,0x09,0x70,0x22,0x1c,0x30,0x84 }, - 16, 0xce90, 0, {0x00,0x3d,0xc0,0x08,0x70,0x02,0x14,0x24,0x87,0xa0,0x21,0xc0,0x08,0x70,0x12,0x12 }, - 16, 0xcea0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x40,0xb3,0x95,0x29,0xe9 }, - 16, 0xceb0, 0, {0x0a,0x68,0x02,0x9e,0xd0,0x86,0xf0,0xa3,0xe0,0x08,0x78,0x12,0x9e,0x44,0xa3,0x82 }, - 16, 0xcec0, 0, {0x21,0xe8,0x0b,0x38,0x02,0x0e,0x10,0x87,0x80,0x2f,0xe0,0x0b,0x18,0x02,0x8e,0x02 }, - 16, 0xced0, 0, {0x87,0x00,0x21,0xe0,0x08,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcee0, 0, {0x48,0x14,0xcc,0x00,0xb3,0x00,0x24,0xc0,0x48,0x30,0x02,0x0c,0x04,0x83,0x80,0x20 }, - 16, 0xcef0, 0, {0xd0,0x09,0x10,0x02,0x8c,0x06,0xa3,0x80,0x20,0xc0,0x0b,0x30,0x02,0x0c,0x02,0x80 }, - 16, 0xcf00, 0, {0x40,0x28,0xd2,0x0a,0x30,0x02,0x0c,0x01,0x83,0x00,0x22,0x3c,0x08,0x87,0x02,0x12 }, - 16, 0xcf10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x18,0xfa,0x00,0x3a,0x80 }, - 16, 0xcf20, 0, {0x8e,0xe4,0x42,0x28,0x02,0xce,0x80,0x33,0x80,0x4d,0xa0,0x83,0xe8,0x00,0xea,0xa0 }, - 16, 0xcf30, 0, {0xb2,0x80,0x0a,0xa0,0x0a,0x28,0x00,0xce,0x18,0x2f,0x80,0x0f,0xa0,0x13,0xa8,0x00 }, - 16, 0xcf40, 0, {0xca,0x00,0x32,0x90,0x2c,0xac,0x0b,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcf50, 0, {0x48,0x00,0xe0,0x00,0xf8,0x04,0x3a,0x00,0x0f,0x80,0x83,0xc0,0x08,0xe8,0x03,0x3a }, - 16, 0xcf60, 0, {0x00,0x0e,0x80,0x22,0xc0,0x00,0xd0,0x00,0x7e,0x10,0xa4,0x80,0x03,0xc0,0x00,0xf8 }, - 16, 0xcf70, 0, {0x00,0x3e,0x10,0x0d,0x84,0x03,0xc0,0x00,0xf8,0x00,0xbe,0x00,0x0f,0x80,0x01,0x52 }, - 16, 0xcf80, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x02,0xc9,0x00,0x36,0x40 }, - 16, 0xcf90, 0, {0x0c,0x90,0x03,0x64,0x02,0x89,0x04,0x32,0x42,0x0d,0x92,0x03,0xe6,0x42,0xc9,0x00 }, - 16, 0xcfa0, 0, {0x32,0x70,0x0e,0x12,0x0b,0x24,0x08,0xc9,0x00,0x3e,0x45,0x0e,0x99,0x03,0xe4,0x02 }, - 16, 0xcfb0, 0, {0xc1,0x00,0x32,0x50,0x04,0x94,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcfc0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x6e,0x40,0x08,0x90,0x02,0x24,0x00,0x89,0x00,0x22 }, - 16, 0xcfd0, 0, {0x54,0x0b,0x90,0x03,0xe6,0x00,0x89,0x00,0x22,0x40,0x08,0x90,0x0a,0x24,0x00,0x89 }, - 16, 0xcfe0, 0, {0x00,0x38,0x48,0x08,0x90,0x82,0xe4,0x04,0xd9,0x00,0x22,0x40,0x08,0x90,0x02,0x20 }, - 16, 0xcff0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x01,0x2c,0x40 }, - 16, 0xd000, 0, {0x28,0x10,0x42,0x64,0x00,0xa1,0x04,0x22,0x50,0x01,0x90,0x42,0xe4,0x00,0x89,0x04 }, - 16, 0xd010, 0, {0x20,0x42,0x0a,0x90,0x42,0x34,0x00,0x89,0x00,0x6e,0x40,0x0a,0x90,0x00,0xe4,0x00 }, - 16, 0xd020, 0, {0x89,0x00,0x23,0x40,0x0a,0xd0,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd030, 0, {0x08,0x04,0x04,0x80,0x81,0x24,0x2c,0x48,0x08,0x10,0x02,0x04,0x80,0xa1,0x20,0x28 }, - 16, 0xd040, 0, {0x40,0x0b,0x10,0x02,0x85,0x80,0x81,0x20,0x20,0x48,0x08,0x50,0x62,0x14,0x02,0x81 }, - 16, 0xd050, 0, {0x03,0x2e,0x40,0x88,0x16,0x82,0xc4,0xa0,0x91,0x28,0x21,0x40,0x2a,0x50,0x02,0x02 }, - 16, 0xd060, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc8,0x50,0x2e,0x14 }, - 16, 0xd070, 0, {0x0c,0x85,0x03,0x61,0x40,0xe8,0x50,0xb2,0x15,0x4d,0x80,0x02,0xc0,0x00,0x48,0x50 }, - 16, 0xd080, 0, {0xb2,0x15,0x1a,0x80,0x13,0x30,0x08,0xc8,0x00,0x3e,0x00,0x0e,0x82,0x03,0xe0,0x80 }, - 16, 0xd090, 0, {0xc0,0x20,0x30,0x00,0x0e,0x40,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd0a0, 0, {0x98,0x1d,0xe4,0x40,0xf9,0x10,0x3e,0x44,0x0f,0xd0,0x03,0xe4,0x48,0xdd,0x10,0x37 }, - 16, 0xd0b0, 0, {0x40,0x0f,0xd4,0x07,0xe4,0x40,0xfd,0x10,0x3e,0x45,0x0f,0x94,0x03,0xe5,0x08,0xfd }, - 16, 0xd0c0, 0, {0x02,0x39,0xd0,0x0f,0xd0,0x43,0xf4,0xa0,0xf9,0x28,0x3e,0x4b,0x0d,0x92,0x83,0xe6 }, - 16, 0xd0d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x80,0xc9,0xa6,0x32,0x68 }, - 16, 0xd0e0, 0, {0x0c,0x90,0x03,0xa6,0x81,0xe9,0xe9,0x3b,0x40,0x0e,0x58,0x03,0x36,0x20,0xc9,0xa0 }, - 16, 0xd0f0, 0, {0x37,0x78,0x0d,0xda,0x03,0x36,0x26,0xc5,0x00,0x37,0x69,0x0e,0xde,0x03,0xa6,0x82 }, - 16, 0xd100, 0, {0xcd,0xc0,0x33,0x50,0x0f,0xd0,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd110, 0, {0x38,0x10,0xe3,0xa4,0x88,0xa9,0x22,0x3a,0x08,0x08,0x00,0x22,0xa0,0xb8,0xe5,0x30 }, - 16, 0xd120, 0, {0x20,0x28,0x80,0x22,0x43,0xa0,0x08,0xe8,0x2a,0x3d,0x08,0xa4,0x62,0x20,0x00,0x88 }, - 16, 0xd130, 0, {0x00,0x2e,0x10,0x08,0x8e,0x03,0x23,0xa0,0x88,0xa0,0x20,0x28,0x0b,0x8a,0x82,0x0e }, - 16, 0xd140, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x40,0x91,0x40,0x20,0x44 }, - 16, 0xd150, 0, {0x08,0x90,0xa2,0x85,0x10,0xa1,0x20,0x2c,0x42,0x0b,0x14,0x12,0x8c,0x01,0x91,0x10 }, - 16, 0xd160, 0, {0x2c,0x48,0x09,0x11,0x0a,0xc4,0x00,0x81,0x00,0x2c,0x50,0x0b,0x11,0x12,0xc5,0x01 }, - 16, 0xd170, 0, {0xb1,0x40,0x24,0x48,0x0b,0x18,0x0e,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd180, 0, {0x18,0x15,0xa4,0x00,0x91,0x00,0x22,0x41,0x08,0x94,0x42,0x24,0x00,0xb1,0x40,0x20 }, - 16, 0xd190, 0, {0x40,0x49,0xb2,0x62,0x24,0x00,0x99,0x00,0x0a,0x40,0x08,0x90,0x02,0xe5,0x80,0x89 }, - 16, 0xd1a0, 0, {0x00,0x2e,0x40,0x09,0xb0,0x02,0x24,0x80,0xb9,0x00,0x26,0x50,0x4b,0x90,0x02,0x06 }, - 16, 0xd1b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x02,0xd9,0x00,0xb2,0x40 }, - 16, 0xd1c0, 0, {0x2c,0x95,0x13,0xa4,0x10,0xe9,0x00,0xbe,0x60,0x8f,0x90,0x0b,0xa4,0x10,0x59,0x00 }, - 16, 0xd1d0, 0, {0x1e,0x40,0x9d,0x94,0x23,0xe4,0x02,0x89,0x00,0x34,0x40,0x0f,0x90,0x03,0xe6,0x08 }, - 16, 0xd1e0, 0, {0x79,0x00,0xb6,0x40,0x07,0x98,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd1f0, 0, {0x28,0x01,0x84,0x00,0xe9,0x02,0x3c,0x40,0x2f,0x98,0x02,0xe4,0x00,0xf9,0x42,0x3a }, - 16, 0xd200, 0, {0x68,0x0a,0x10,0x03,0xe4,0x10,0xe9,0x00,0x3e,0x40,0x0e,0x90,0x0f,0x26,0x00,0xf9 }, - 16, 0xd210, 0, {0x04,0x3e,0x40,0x0e,0x1c,0x03,0xe6,0x00,0xc1,0x00,0x3a,0x50,0x0f,0x99,0x83,0xca }, - 16, 0xd220, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xe8,0x00,0x3a,0x00 }, - 16, 0xd230, 0, {0x0c,0x84,0x03,0x20,0x00,0xd8,0x42,0x32,0x04,0x0c,0x88,0x13,0xe0,0x00,0xc8,0x00 }, - 16, 0xd240, 0, {0x30,0x00,0x0c,0x04,0x0b,0x00,0x00,0xd8,0x00,0x36,0x00,0x0e,0x80,0x23,0x00,0x00 }, - 16, 0xd250, 0, {0xc8,0x80,0x32,0x00,0x0c,0x80,0x01,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd260, 0, {0x28,0x05,0x28,0x10,0x8a,0x00,0x2e,0x80,0x28,0x20,0x22,0x28,0x00,0x8a,0x00,0x23 }, - 16, 0xd270, 0, {0xb0,0x88,0xe0,0x02,0x28,0x10,0xda,0x00,0xa3,0xb4,0x08,0xe8,0x10,0x28,0x00,0x8e }, - 16, 0xd280, 0, {0x20,0x23,0xa0,0x48,0xed,0x1a,0x28,0x00,0xde,0x00,0x23,0x90,0x0a,0xe0,0x02,0x0a }, - 16, 0xd290, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xa3,0x00,0x28,0xc0 }, - 16, 0xd2a0, 0, {0x08,0x30,0x0a,0x0c,0x00,0x93,0x00,0x20,0xc2,0x2a,0x30,0x22,0xa4,0x00,0xbb,0x00 }, - 16, 0xd2b0, 0, {0x08,0xe0,0x18,0x09,0x0a,0x4c,0x00,0x93,0x02,0x24,0xe8,0x02,0x08,0x06,0x4c,0x00 }, - 16, 0xd2c0, 0, {0x93,0x00,0x20,0xd8,0x0a,0x90,0x02,0x4a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd2d0, 0, {0xa0,0x01,0x1c,0x80,0x87,0x04,0x2d,0xc0,0x08,0x70,0x02,0x0e,0x00,0x87,0x10,0x25 }, - 16, 0xd2e0, 0, {0x00,0x0a,0x60,0x02,0x5e,0x00,0x97,0x00,0x29,0x82,0x08,0x50,0x12,0x54,0x00,0x8f }, - 16, 0xd2f0, 0, {0x80,0x61,0xd0,0x08,0x04,0x02,0x5c,0x01,0xb7,0x08,0xa9,0xa0,0x0a,0x50,0x82,0x68 }, - 16, 0xd300, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x80,0xe7,0x80,0x38,0xe4 }, - 16, 0xd310, 0, {0x08,0x7e,0x03,0x1f,0x00,0xdf,0x80,0xb1,0x21,0x1e,0x78,0x03,0xdc,0x04,0xf3,0x80 }, - 16, 0xd320, 0, {0x5b,0xe1,0x08,0x28,0x03,0x5e,0x00,0xd7,0x80,0x35,0x60,0x0e,0x68,0x03,0x4e,0x00 }, - 16, 0xd330, 0, {0xdf,0x80,0x31,0xe0,0x0e,0xf8,0x0b,0x6a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd340, 0, {0x08,0x1d,0xad,0x02,0xfb,0x74,0x3e,0xd0,0x4f,0xb2,0x83,0xed,0x00,0x7b,0x68,0x3a }, - 16, 0xd350, 0, {0x00,0x8d,0x80,0x03,0xa4,0x20,0xdb,0x01,0x36,0x80,0x6f,0xb0,0x41,0x84,0x00,0xeb }, - 16, 0xd360, 0, {0x00,0x3c,0xc0,0x0f,0xe6,0x83,0xbc,0x40,0xdb,0x00,0xb6,0x80,0x0f,0xb0,0x03,0x82 }, - 16, 0xd370, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x20,0xdf,0xc0,0x3b,0xe6 }, - 16, 0xd380, 0, {0x0e,0xf8,0x13,0xff,0x44,0xc7,0x82,0x3b,0xe0,0x0f,0xf9,0x03,0xbe,0x10,0xcf,0xc8 }, - 16, 0xd390, 0, {0x33,0x60,0x8d,0xeb,0x03,0x3e,0x00,0xdb,0x82,0x3f,0xe0,0x0c,0xd8,0x03,0x3e,0x40 }, - 16, 0xd3a0, 0, {0xce,0x80,0x33,0xe4,0x0f,0xf8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd3b0, 0, {0xa8,0x11,0xbc,0x40,0x87,0x00,0x21,0xe4,0x0b,0x78,0xa2,0xce,0x90,0xc7,0xb0,0x20 }, - 16, 0xd3c0, 0, {0xe8,0x0b,0x28,0x92,0xb6,0x88,0x87,0xa0,0x20,0x64,0x0b,0x35,0x03,0x14,0x00,0x87 }, - 16, 0xd3d0, 0, {0xb2,0x39,0xc0,0x2c,0xc0,0x03,0x5e,0x02,0xcf,0x00,0x31,0xce,0x0b,0x76,0x12,0x2a }, - 16, 0xd3e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa3,0x10,0x29,0xc8 }, - 16, 0xd3f0, 0, {0x0b,0x74,0x02,0xdc,0x80,0x8f,0x00,0x29,0xcc,0x0a,0x30,0x06,0x14,0x80,0x87,0x10 }, - 16, 0xd400, 0, {0x21,0xc0,0x0b,0x66,0x02,0x5c,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x51,0x02,0x1c,0x80 }, - 16, 0xd410, 0, {0x96,0x00,0x21,0xc0,0x5b,0x74,0x82,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd420, 0, {0x20,0x14,0xcc,0x08,0xa3,0x00,0x20,0xc0,0x0b,0xb8,0x02,0xcc,0x00,0x8b,0x40,0xa8 }, - 16, 0xd430, 0, {0xc0,0x8b,0x08,0x22,0x8c,0x02,0x83,0x00,0x60,0xc0,0x0b,0x30,0x42,0x04,0x00,0x83 }, - 16, 0xd440, 0, {0x40,0x28,0xfc,0x8a,0x00,0x02,0x6e,0x00,0x83,0x00,0xa0,0xd0,0x8b,0x38,0x02,0x08 }, - 16, 0xd450, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbc,0x02,0xef,0x00,0x3b,0xc0 }, - 16, 0xd460, 0, {0x4f,0xf8,0x02,0xfc,0x02,0xcf,0x00,0x38,0x12,0x0e,0x98,0x02,0x2c,0x00,0xcf,0x00 }, - 16, 0xd470, 0, {0x32,0xc0,0x09,0x90,0x03,0x64,0x02,0x81,0xc0,0x3e,0xd0,0x0f,0x90,0x07,0x3c,0x03 }, - 16, 0xd480, 0, {0xd9,0x00,0x32,0x60,0x0f,0x88,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd490, 0, {0x80,0x00,0xcc,0x00,0xdb,0x00,0x3e,0xc0,0x8f,0xb0,0x03,0xec,0x00,0xfb,0x02,0x36 }, - 16, 0xd4a0, 0, {0xc0,0x4f,0x90,0x02,0xe4,0x00,0xfb,0x00,0xbe,0x90,0x0f,0x9c,0x13,0xec,0x00,0xe9 }, - 16, 0xd4b0, 0, {0x18,0x3a,0xd0,0x04,0xd5,0x03,0xec,0x40,0xe9,0x00,0x3a,0x00,0x8f,0x80,0x03,0xe0 }, - 16, 0xd4c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xcf,0x00,0x3d,0xc1 }, - 16, 0xd4d0, 0, {0x8c,0xf0,0x03,0x2c,0x00,0xef,0x0a,0xb3,0x12,0x2c,0x70,0x23,0x14,0x0a,0x4f,0x00 }, - 16, 0xd4e0, 0, {0x35,0x60,0x0d,0xb0,0x03,0x04,0x00,0xcd,0x80,0x07,0xe8,0x0c,0xc4,0x03,0x2c,0x00 }, - 16, 0xd4f0, 0, {0xcd,0x00,0x31,0xe2,0x2c,0xe0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd500, 0, {0x81,0x04,0x6c,0x02,0xab,0x02,0x2e,0xc0,0x0e,0xb0,0x02,0x2c,0x00,0x8b,0x00,0x32 }, - 16, 0xd510, 0, {0x30,0x00,0x9c,0x03,0x6c,0x00,0x8b,0x04,0x22,0x36,0x08,0x34,0x4a,0x2c,0x08,0x89 }, - 16, 0xd520, 0, {0x90,0x20,0xb8,0x0f,0x84,0x00,0xac,0x02,0x89,0x00,0x36,0xa0,0x08,0xa4,0x02,0x20 }, - 16, 0xd530, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x2e,0xc0 }, - 16, 0xd540, 0, {0x08,0xb0,0x02,0x0c,0x00,0x8b,0x00,0x22,0xd1,0x08,0x88,0x12,0x26,0x00,0xa3,0x00 }, - 16, 0xd550, 0, {0x26,0x40,0x0b,0xb0,0x02,0x26,0x00,0x8b,0x00,0x26,0xc0,0x58,0x10,0x12,0x2c,0x04 }, - 16, 0xd560, 0, {0x82,0x80,0x2a,0x49,0x08,0x30,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd570, 0, {0x08,0x04,0x0c,0x00,0xa3,0x14,0x2c,0xc8,0x1a,0x34,0x8a,0x0c,0x84,0x83,0x40,0x22 }, - 16, 0xd580, 0, {0xc8,0x08,0x03,0x62,0x4c,0xc0,0xa3,0x60,0x20,0x40,0x0a,0x30,0x02,0x0c,0x00,0x8b }, - 16, 0xd590, 0, {0x45,0x08,0xc0,0x0b,0x10,0x02,0x8c,0xa0,0x83,0x00,0x26,0x40,0x08,0x30,0x0a,0x02 }, - 16, 0xd5a0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xcf,0x40,0x2f,0xd2 }, - 16, 0xd5b0, 0, {0x8c,0xf6,0x03,0x3c,0x22,0xcf,0x40,0x32,0xd6,0x4c,0xa6,0xc1,0x3d,0xa0,0x87,0x48 }, - 16, 0xd5c0, 0, {0x36,0x0d,0x0f,0xb1,0x02,0x24,0x42,0xcb,0x60,0x16,0xc0,0x0c,0xd0,0x03,0x2c,0x80 }, - 16, 0xd5d0, 0, {0xca,0x00,0x32,0xc0,0x0c,0x30,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd5e0, 0, {0xa0,0x19,0xfc,0x00,0xff,0x20,0x3e,0xca,0x0e,0xb0,0x03,0xec,0x20,0xdb,0x34,0x3a }, - 16, 0xd5f0, 0, {0xc8,0x0f,0x80,0x03,0xe4,0x10,0xdb,0x21,0x3e,0x18,0x0d,0xf2,0x03,0xfc,0x80,0xff }, - 16, 0xd600, 0, {0x30,0x35,0xc0,0x0f,0xc0,0x13,0xec,0x00,0xff,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xe8 }, - 16, 0xd610, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xfc,0x00,0xfb,0x0b,0x2f,0xca }, - 16, 0xd620, 0, {0x8d,0xf2,0x03,0xfa,0x00,0x96,0x80,0x3b,0xc4,0x0d,0xf1,0x03,0x7c,0x80,0xec,0x80 }, - 16, 0xd630, 0, {0x3b,0x08,0x0c,0xc2,0x03,0x74,0x02,0xcc,0x80,0x3f,0x48,0x0e,0xf0,0x03,0x30,0xa0 }, - 16, 0xd640, 0, {0xd5,0x80,0x3f,0x40,0x0c,0xf8,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd650, 0, {0x80,0x08,0xee,0x40,0xbf,0x80,0x2f,0xf0,0x0b,0xf7,0x22,0xee,0x20,0x8a,0x80,0x23 }, - 16, 0xd660, 0, {0xfc,0x88,0x75,0x12,0x3d,0x00,0x88,0x00,0x22,0x00,0x28,0x80,0x02,0x24,0x08,0x88 }, - 16, 0xd670, 0, {0x00,0x6f,0x50,0x00,0xf5,0x02,0x29,0x00,0x89,0x00,0x2e,0x54,0x0d,0x90,0x11,0xa0 }, - 16, 0xd680, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xb3,0x00,0x2c,0xc1 }, - 16, 0xd690, 0, {0x09,0x30,0x82,0xcc,0x82,0xbb,0x00,0x28,0xc0,0x49,0x32,0x02,0xcd,0x00,0xb8,0x00 }, - 16, 0xd6a0, 0, {0x2c,0x50,0x09,0x01,0x02,0x0c,0x40,0x80,0x00,0x6c,0x44,0x09,0x30,0x02,0x20,0x00 }, - 16, 0xd6b0, 0, {0xb0,0x00,0x2c,0x40,0x18,0x30,0x06,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd6c0, 0, {0xc0,0x01,0xac,0x00,0xbb,0x01,0x2e,0xc0,0x0b,0xb0,0x02,0xee,0x00,0xaa,0x00,0x4a }, - 16, 0xd6d0, 0, {0xc0,0x08,0xb0,0x52,0xec,0x00,0x98,0x02,0x26,0x40,0x09,0x80,0x02,0x6c,0x01,0xaa }, - 16, 0xd6e0, 0, {0x04,0x2e,0x40,0x09,0xb0,0x02,0x22,0x00,0xa9,0x80,0x2e,0x41,0x09,0x90,0x02,0xf0 }, - 16, 0xd6f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xec,0x00,0xfb,0x00,0x3e,0xc0 }, - 16, 0xd700, 0, {0x0d,0xb0,0x03,0xce,0x84,0xfa,0x00,0x1a,0xc0,0x8d,0xb0,0x43,0xec,0x00,0xf0,0x02 }, - 16, 0xd710, 0, {0x3f,0x00,0x0d,0xd1,0x03,0x35,0x00,0xcb,0x48,0x2e,0x40,0x2f,0xb0,0x09,0x22,0x80 }, - 16, 0xd720, 0, {0xf9,0xc8,0x1e,0xe0,0x08,0xb1,0xe2,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd730, 0, {0xe0,0x01,0xbc,0x00,0x7b,0x00,0x3f,0xc0,0x0f,0xf0,0x23,0xfc,0x00,0xde,0x00,0x24 }, - 16, 0xd740, 0, {0xc0,0x4f,0xf0,0x03,0x2c,0x00,0xec,0x20,0x3b,0x00,0x0e,0x98,0x03,0x94,0x02,0xdd }, - 16, 0xd750, 0, {0x00,0x3f,0x40,0x4e,0xf0,0x01,0xf8,0x00,0xdd,0x00,0x3c,0xe4,0x0f,0xd8,0x03,0xb8 }, - 16, 0xd760, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xac,0xc0,0xfb,0x20,0x32,0xc8 }, - 16, 0xd770, 0, {0x8d,0xb0,0x03,0xec,0x00,0xf9,0x00,0x3a,0xc2,0x2c,0x30,0x03,0x6c,0x04,0xd8,0x02 }, - 16, 0xd780, 0, {0x3c,0x44,0x8d,0x10,0x03,0xad,0x03,0xea,0x00,0x3c,0x40,0x0c,0x70,0x23,0xe4,0x00 }, - 16, 0xd790, 0, {0xc8,0x40,0x3a,0xc0,0x0d,0xbc,0x03,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd7a0, 0, {0xc8,0x01,0x3d,0x00,0xbf,0x42,0x23,0xf0,0x0d,0xf0,0x02,0xe5,0x00,0xe2,0x01,0x37 }, - 16, 0xd7b0, 0, {0xf1,0x08,0xf0,0x0e,0x3d,0xc0,0xa8,0x00,0x2e,0x54,0x28,0x90,0x02,0x2c,0x00,0x8a }, - 16, 0xd7c0, 0, {0x05,0x3b,0x41,0x48,0xf5,0x03,0x8c,0x00,0x89,0x00,0x22,0xd4,0x0e,0x95,0x02,0xf2 }, - 16, 0xd7d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x04,0x20,0xc0 }, - 16, 0xd7e0, 0, {0x89,0x30,0x02,0xcc,0x40,0xb2,0x00,0x2c,0xc4,0x48,0x30,0x02,0x2c,0x02,0xa2,0x00 }, - 16, 0xd7f0, 0, {0x2c,0x20,0x19,0x20,0x1a,0x80,0x08,0xb0,0x00,0x6c,0x40,0x08,0x30,0x02,0xc4,0x00 }, - 16, 0xd800, 0, {0x81,0x00,0x2c,0x40,0x08,0x30,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd810, 0, {0x20,0x01,0x1e,0x00,0xb7,0xa0,0xe1,0xe0,0x09,0x78,0x02,0xdf,0x04,0xae,0x80,0x2d }, - 16, 0xd820, 0, {0xe0,0x08,0x79,0x02,0x1e,0x10,0x87,0x90,0x2c,0x28,0x29,0x68,0x02,0x82,0x81,0xb4 }, - 16, 0xd830, 0, {0x80,0x2d,0x60,0x08,0x78,0x10,0xbc,0x00,0x8f,0x80,0x2d,0x60,0x0b,0x68,0x02,0xc8 }, - 16, 0xd840, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x0c,0x05,0xf3,0x92,0x30,0xca }, - 16, 0xd850, 0, {0x0d,0x30,0x03,0xcc,0x00,0xf3,0x00,0x3c,0xc0,0x0c,0x30,0x02,0x0c,0x80,0x70,0x00 }, - 16, 0xd860, 0, {0x2c,0x40,0x0d,0x20,0x03,0x89,0x00,0xb1,0x00,0x3e,0x40,0x2c,0x30,0x03,0xec,0x50 }, - 16, 0xd870, 0, {0xc3,0x20,0x3c,0x40,0x0c,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd880, 0, {0x40,0x1d,0xbc,0x00,0xff,0x00,0x3c,0xc0,0x0e,0xb0,0x83,0xec,0x40,0xea,0x00,0x36 }, - 16, 0xd890, 0, {0xc2,0x0f,0xb0,0x83,0xac,0x00,0xf8,0x00,0x3e,0x48,0x0e,0xe0,0x0b,0x7a,0x80,0xcf }, - 16, 0xd8a0, 0, {0x00,0x3b,0x44,0x0f,0xf0,0x03,0xec,0xc0,0xff,0x00,0x03,0x44,0x0e,0xe0,0x03,0xd0 }, - 16, 0xd8b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x23,0x3e,0xc8 }, - 16, 0xd8c0, 0, {0x1d,0xb0,0x03,0xee,0x00,0xca,0x00,0x3e,0xc8,0x0c,0xb2,0x03,0x2d,0x90,0xc8,0x84 }, - 16, 0xd8d0, 0, {0x36,0x00,0x2d,0xb0,0x03,0x60,0x18,0x9b,0x80,0x33,0x50,0x0c,0xf2,0x03,0xe2,0x00 }, - 16, 0xd8e0, 0, {0xc9,0x80,0x32,0x40,0x0c,0xb8,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd8f0, 0, {0x48,0x11,0x9c,0x00,0xb7,0x28,0x0c,0xd2,0x28,0x73,0x02,0xfc,0x00,0x86,0x04,0x2c }, - 16, 0xd900, 0, {0xcc,0x28,0x70,0x83,0x0c,0x20,0x95,0x01,0x20,0x00,0x09,0x30,0x12,0x10,0x04,0x85 }, - 16, 0xd910, 0, {0x00,0x21,0x52,0x08,0x75,0x02,0xd8,0x00,0x87,0x00,0x21,0x40,0x08,0x60,0x02,0x12 }, - 16, 0xd920, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0xd4,0xb7,0xb1,0x09,0xe1 }, - 16, 0xd930, 0, {0x08,0x78,0x22,0xde,0x00,0x95,0x80,0x2d,0xe0,0x08,0x78,0x0a,0x5e,0x42,0x94,0xc0 }, - 16, 0xd940, 0, {0x21,0x60,0x08,0x78,0x02,0x5a,0x00,0x87,0x80,0x2d,0x68,0x08,0x7a,0x02,0xd7,0x00 }, - 16, 0xd950, 0, {0x97,0x80,0x20,0x60,0x09,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd960, 0, {0x48,0x10,0xcc,0x00,0xb3,0x00,0x2c,0xc0,0x08,0xb0,0x02,0xcd,0x80,0x92,0x00,0x2c }, - 16, 0xd970, 0, {0xc0,0x08,0xb0,0x02,0xcc,0x00,0x90,0x80,0xa0,0x40,0x09,0x36,0x02,0x48,0x02,0x83 }, - 16, 0xd980, 0, {0xa0,0xac,0x40,0x2a,0x30,0x06,0xce,0x02,0x93,0x04,0xa0,0x40,0x09,0x20,0x0a,0x12 }, - 16, 0xd990, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x00,0x3a,0x80 }, - 16, 0xd9a0, 0, {0x0d,0xa0,0x03,0xfb,0x02,0xde,0x80,0x3e,0x80,0x0c,0xa0,0x03,0x28,0x00,0xce,0x80 }, - 16, 0xd9b0, 0, {0x32,0x80,0x0c,0xa4,0x03,0x78,0x00,0xce,0xa4,0x3f,0x80,0x0c,0xa0,0x07,0xf9,0x00 }, - 16, 0xd9c0, 0, {0xde,0x00,0x32,0x80,0x2d,0xe0,0x02,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd9d0, 0, {0x48,0x00,0xe1,0x00,0xf8,0x00,0x7c,0x00,0x0f,0x80,0x03,0xe0,0x40,0xe8,0x10,0x3c }, - 16, 0xd9e0, 0, {0x01,0xcf,0x80,0x0f,0x20,0x00,0xe8,0x00,0x3e,0x00,0x0e,0x04,0x03,0x90,0x00,0xe8 }, - 16, 0xd9f0, 0, {0x00,0x20,0x00,0x0d,0x80,0x07,0xe0,0x00,0xe8,0x00,0x3e,0x04,0x0e,0x80,0x03,0xd2 }, - 16, 0xda00, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x10,0x7e,0x41 }, - 16, 0xda10, 0, {0x0e,0x90,0x03,0x24,0x00,0xf9,0x00,0x36,0x68,0x0e,0x90,0x0f,0xa4,0x08,0xc9,0x00 }, - 16, 0xda20, 0, {0x3a,0x40,0x0c,0x90,0x0b,0x24,0x12,0xe9,0x00,0x3e,0x44,0x2c,0x90,0x03,0x64,0x24 }, - 16, 0xda30, 0, {0xf9,0x02,0x2e,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xda40, 0, {0x80,0x04,0x65,0x10,0xb9,0x80,0x3e,0x40,0x08,0x90,0x0a,0x26,0x00,0xb1,0x10,0x2a }, - 16, 0xda50, 0, {0x72,0x08,0x90,0x07,0x64,0x02,0x89,0x40,0x2e,0x40,0x28,0x90,0x12,0x25,0x00,0x89 }, - 16, 0xda60, 0, {0x45,0x3e,0x50,0x0d,0x90,0x0a,0x25,0x00,0xb9,0x40,0x2e,0x40,0x28,0x94,0x03,0xe0 }, - 16, 0xda70, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x2e,0x40 }, - 16, 0xda80, 0, {0x48,0x90,0x42,0x26,0x01,0xb9,0x40,0x26,0x40,0x0a,0x90,0x42,0x84,0x01,0x8b,0x08 }, - 16, 0xda90, 0, {0x2c,0x40,0x09,0xd0,0x82,0x34,0x32,0xa9,0x08,0x6e,0x42,0x08,0x10,0x02,0x24,0x20 }, - 16, 0xdaa0, 0, {0xb9,0x08,0x2c,0x40,0x18,0x90,0x82,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdab0, 0, {0x08,0x04,0x04,0x80,0xb3,0x20,0x28,0x48,0x08,0x12,0x02,0x04,0x01,0xb1,0x00,0x28 }, - 16, 0xdac0, 0, {0x58,0x08,0x12,0x02,0x05,0x89,0x81,0x40,0x2c,0x58,0x08,0x56,0x06,0x15,0x80,0x81 }, - 16, 0xdad0, 0, {0x40,0x28,0x50,0x09,0x14,0x02,0x05,0x80,0xb1,0x40,0x2c,0x5a,0x08,0x14,0x02,0xc2 }, - 16, 0xdae0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x68,0x00,0xf8,0x00,0x2e,0x00 }, - 16, 0xdaf0, 0, {0x2e,0x85,0x03,0x21,0x48,0xf8,0x00,0x36,0x00,0x8e,0x05,0x02,0xa0,0x08,0x80,0x00 }, - 16, 0xdb00, 0, {0x3e,0x00,0x0d,0x80,0x0b,0x10,0x04,0xe0,0x00,0x2c,0x00,0x4c,0x80,0x03,0x40,0x00 }, - 16, 0xdb10, 0, {0xf0,0x00,0x3e,0x08,0x0c,0x00,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdb20, 0, {0x98,0x1d,0xe4,0x40,0xf9,0x10,0x3e,0x44,0x0f,0x91,0x03,0xf4,0x00,0xfd,0x00,0x3e }, - 16, 0xdb30, 0, {0x44,0x0f,0x91,0x03,0xe4,0x40,0xfd,0x03,0x3f,0x44,0x1f,0x91,0x1b,0xe4,0x40,0xfd }, - 16, 0xdb40, 0, {0x01,0x3f,0x50,0x0e,0x94,0x03,0xf4,0x40,0xfd,0x00,0x3f,0x40,0x0f,0xd0,0x03,0xa6 }, - 16, 0xdb50, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf4,0x00,0xcd,0xa0,0x71,0x68 }, - 16, 0xdb60, 0, {0x8d,0x98,0x03,0xd4,0x00,0xcd,0x00,0x33,0x60,0x0c,0x98,0x8f,0x27,0x20,0xc9,0x40 }, - 16, 0xdb70, 0, {0x3e,0x78,0x0c,0x9e,0x8b,0x27,0x20,0xd1,0x11,0x30,0x60,0x8c,0x9c,0x03,0x25,0x00 }, - 16, 0xdb80, 0, {0xf9,0x40,0x3e,0x78,0x0f,0x90,0x03,0x46,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdb90, 0, {0x38,0x10,0xe0,0x10,0x88,0x01,0x22,0x01,0x08,0x8c,0x22,0xe8,0x00,0x88,0x02,0x2a }, - 16, 0xdba0, 0, {0x14,0x08,0x8c,0x0b,0x23,0x90,0x88,0xa0,0x2e,0xb0,0x08,0x8c,0x42,0x23,0x00,0x88 }, - 16, 0xdbb0, 0, {0xa0,0x36,0x2a,0x18,0x8a,0x02,0x22,0x00,0xb8,0xa0,0x2e,0x34,0x0b,0xca,0x82,0x0e }, - 16, 0xdbc0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x81,0x40,0x24,0x50 }, - 16, 0xdbd0, 0, {0x09,0x16,0x82,0xc4,0x00,0xa9,0x00,0x20,0x40,0x08,0x12,0x92,0x54,0x08,0x85,0x00 }, - 16, 0xdbe0, 0, {0x2f,0x4c,0x09,0x52,0x12,0x14,0x80,0x9d,0x00,0x21,0x50,0x08,0x54,0x22,0x14,0x80 }, - 16, 0xdbf0, 0, {0xb5,0x00,0x2d,0x48,0x0b,0xd0,0x02,0x42,0x05,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdc00, 0, {0x18,0x05,0xa4,0x02,0x89,0x01,0xa2,0x40,0x48,0x90,0x02,0xe4,0x02,0xa9,0x00,0x2a }, - 16, 0xdc10, 0, {0x40,0x68,0x90,0x02,0x64,0x10,0xad,0x00,0x2f,0x41,0x28,0x50,0x02,0x34,0x00,0x8d }, - 16, 0xdc20, 0, {0x44,0x27,0x40,0x39,0xd0,0x02,0x35,0x00,0xbd,0x14,0x2f,0x40,0x0b,0xd0,0x02,0x46 }, - 16, 0xdc30, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xc4,0x00,0xc9,0x00,0x36,0x40 }, - 16, 0xdc40, 0, {0x2d,0x90,0x03,0xe7,0x00,0xe1,0xe0,0x32,0x40,0x0c,0x90,0x0b,0x64,0x02,0xc9,0x08 }, - 16, 0xdc50, 0, {0x3c,0x50,0x0c,0x90,0x02,0x26,0x02,0xd9,0xc0,0x32,0x40,0x0c,0x90,0x13,0x27,0x00 }, - 16, 0xdc60, 0, {0xf9,0x20,0x3e,0x40,0x0f,0x90,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdc70, 0, {0x28,0x01,0xa4,0x02,0xf9,0x00,0x38,0x40,0x0f,0x90,0x03,0xe6,0x80,0xd9,0xa0,0x3c }, - 16, 0xdc80, 0, {0x40,0x0f,0x10,0x03,0xa4,0x00,0xd9,0x10,0x3e,0x40,0x0f,0x90,0x03,0xc4,0x92,0xf9 }, - 16, 0xdc90, 0, {0x21,0x3c,0x40,0x2e,0x90,0x0f,0xe6,0x80,0xf9,0x80,0x3e,0x40,0x0f,0x90,0x03,0x8a }, - 16, 0xdca0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x40,0xe8,0x10,0x3e,0x04 }, - 16, 0xdcb0, 0, {0x4e,0x80,0x03,0x20,0x80,0xd8,0x60,0x3a,0x02,0x0c,0x80,0x13,0x20,0x00,0xf8,0x40 }, - 16, 0xdcc0, 0, {0x36,0x10,0x2d,0x80,0x03,0xa0,0x08,0xe8,0x40,0x32,0x00,0x0d,0x00,0x03,0x21,0x02 }, - 16, 0xdcd0, 0, {0xc8,0x40,0xb2,0x00,0x0f,0xc0,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdce0, 0, {0x28,0x11,0x3b,0x10,0x86,0x01,0x2f,0xa0,0x0d,0xa0,0x02,0x38,0x00,0x8e,0xe0,0x23 }, - 16, 0xdcf0, 0, {0xa2,0x08,0xa0,0x02,0x28,0x00,0xba,0x80,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0x82 }, - 16, 0xdd00, 0, {0x00,0x2a,0x80,0x28,0xa0,0x02,0x2a,0x04,0x8a,0x80,0x22,0xa0,0x0b,0x60,0x02,0xca }, - 16, 0xdd10, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x43,0x80,0xa2,0x00,0x2c,0xa0 }, - 16, 0xdd20, 0, {0x08,0x30,0x02,0x2e,0x00,0x92,0x00,0x28,0xc0,0x28,0x30,0x02,0x2c,0x00,0xb3,0x80 }, - 16, 0xdd30, 0, {0x24,0xc0,0x09,0x30,0x0a,0x8c,0x00,0xa3,0x00,0x60,0xc0,0x08,0x30,0x0a,0x4c,0x00 }, - 16, 0xdd40, 0, {0x83,0x00,0x20,0xe0,0x0b,0x20,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdd50, 0, {0xa0,0x01,0x10,0x00,0x86,0x00,0x2d,0xc0,0x09,0x3a,0x02,0x35,0x00,0x86,0x00,0x21 }, - 16, 0xdd60, 0, {0xc0,0x08,0x73,0x02,0x10,0x00,0xbf,0x88,0x21,0x00,0x08,0x70,0x02,0x1c,0x08,0x8f }, - 16, 0xdd70, 0, {0x00,0x2b,0xc0,0x08,0x20,0x12,0x5e,0x20,0x87,0x88,0x21,0x83,0x0b,0x60,0x02,0xe8 }, - 16, 0xdd80, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xe5,0x81,0x3d,0xa0 }, - 16, 0xdd90, 0, {0x2c,0x7a,0x0b,0x1e,0x00,0xd4,0x80,0x38,0xe0,0x0c,0xfa,0x0b,0x1e,0x00,0xf6,0x80 }, - 16, 0xdda0, 0, {0x34,0xe0,0x0d,0x28,0x03,0x8a,0x00,0xe6,0x80,0x31,0x20,0x0c,0x78,0x03,0x7a,0x04 }, - 16, 0xddb0, 0, {0xce,0x84,0x31,0xe0,0x4f,0x78,0x43,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xddc0, 0, {0x08,0x0d,0x80,0x00,0xf8,0x00,0x3e,0xc0,0x0f,0xb5,0x23,0xe4,0x00,0xf0,0x04,0x36 }, - 16, 0xddd0, 0, {0x40,0x0f,0xb6,0x87,0xe0,0x00,0xf2,0x00,0x3e,0x00,0x1f,0xa0,0x0b,0xe8,0x00,0xfa }, - 16, 0xdde0, 0, {0x00,0x3e,0x00,0x0e,0xa0,0x03,0xa8,0x00,0xfa,0x00,0x3e,0x80,0x0f,0xb0,0x03,0xc2 }, - 16, 0xddf0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xcc,0x80,0x33,0xa0 }, - 16, 0xde00, 0, {0x0c,0xfc,0x03,0x3e,0x00,0xfc,0x80,0x37,0xe0,0x0f,0xb9,0x21,0x3e,0x00,0xfd,0x82 }, - 16, 0xde10, 0, {0x33,0xe0,0x2c,0xf8,0x03,0x7e,0x10,0xdf,0x84,0x3d,0xe0,0x0c,0xf8,0x03,0xf6,0x00 }, - 16, 0xde20, 0, {0xfd,0x80,0x3f,0x60,0x0c,0xe8,0x23,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xde30, 0, {0xa8,0x11,0x98,0x40,0x84,0x10,0x21,0xc0,0x08,0x70,0x02,0x10,0x80,0xb4,0x00,0x21 }, - 16, 0xde40, 0, {0xc8,0x0b,0x7a,0x02,0x10,0x00,0xfd,0x00,0x21,0x04,0x08,0x70,0x02,0x1c,0x42,0x87 }, - 16, 0xde50, 0, {0x00,0x2d,0xc4,0x48,0x61,0x02,0xd6,0x80,0xb5,0x00,0x2f,0x04,0x08,0x61,0x82,0x2a }, - 16, 0xde60, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x81,0x00,0x21,0x80 }, - 16, 0xde70, 0, {0x08,0x30,0x02,0x1c,0x10,0xbc,0x08,0x25,0x80,0x4b,0x30,0x0e,0x1c,0x00,0xb4,0x00 }, - 16, 0xde80, 0, {0x20,0xc0,0x08,0x20,0x02,0x58,0x00,0x96,0x00,0x2f,0x00,0x0a,0x70,0x02,0xd0,0x80 }, - 16, 0xde90, 0, {0xb4,0x18,0x2d,0x40,0x09,0xf8,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdea0, 0, {0x20,0x14,0xc8,0x02,0x80,0x00,0xa0,0xc0,0x08,0x30,0x22,0x0b,0xc0,0xb0,0xc0,0x22 }, - 16, 0xdeb0, 0, {0x80,0x0b,0x30,0x02,0x00,0x00,0xa0,0x04,0x22,0x00,0x28,0xa0,0x02,0x2b,0x00,0x8a }, - 16, 0xdec0, 0, {0x00,0x2c,0x00,0x08,0xa0,0x06,0xc0,0x00,0xb0,0xc2,0x2c,0x00,0x09,0xbc,0x1a,0x08 }, - 16, 0xded0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xc8,0x00,0x32,0xc0 }, - 16, 0xdee0, 0, {0x0c,0xf0,0x0b,0x26,0x00,0xf9,0xc0,0x36,0x00,0x0f,0xf0,0x13,0x2c,0x10,0xbb,0x40 }, - 16, 0xdef0, 0, {0xf2,0xc0,0x08,0x90,0x03,0x67,0x00,0xd9,0x80,0x3e,0xc0,0x08,0x90,0x02,0xec,0x00 }, - 16, 0xdf00, 0, {0xfb,0xd0,0x3e,0xc0,0x29,0x8c,0x00,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdf10, 0, {0x80,0x00,0xe0,0x00,0xf8,0x44,0x3c,0xd0,0x2f,0xb0,0x03,0xe4,0x00,0xf9,0x20,0x3e }, - 16, 0xdf20, 0, {0x40,0x0f,0x30,0x03,0xe0,0x00,0xfb,0x08,0x3e,0x00,0x0f,0x90,0x13,0xe4,0x42,0xf9 }, - 16, 0xdf30, 0, {0x10,0x3e,0xc0,0x0f,0x80,0x03,0xee,0x00,0xfb,0x00,0x3e,0x80,0x0e,0x82,0x03,0xe0 }, - 16, 0xdf40, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xe0,0x08,0xfc,0x80,0x32,0xe4 }, - 16, 0xdf50, 0, {0x0e,0xf0,0x03,0x74,0x00,0xfc,0x00,0x3f,0x40,0x0c,0xf0,0x0b,0x3c,0x00,0xfe,0x00 }, - 16, 0xdf60, 0, {0x3f,0xc0,0x0d,0xc1,0x03,0x20,0x20,0xcc,0x10,0x33,0x00,0x0c,0xd1,0x03,0x58,0x00 }, - 16, 0xdf70, 0, {0xce,0x00,0x2f,0xc0,0x0f,0xd1,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdf80, 0, {0x81,0x44,0x62,0x00,0xb0,0x40,0x2a,0xf1,0x08,0xb0,0x12,0x26,0x08,0xb8,0xc8,0x2e }, - 16, 0xdf90, 0, {0x70,0x0a,0xb0,0x02,0x20,0x00,0xba,0x00,0x2e,0x00,0x28,0x80,0x03,0x22,0x40,0x88 }, - 16, 0xdfa0, 0, {0x01,0x20,0x00,0x0a,0x80,0x02,0x28,0x00,0x8a,0x01,0x2e,0x80,0x8b,0x90,0x02,0x20 }, - 16, 0xdfb0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x26,0x00,0xb8,0x28,0x22,0x42 }, - 16, 0xdfc0, 0, {0x08,0x30,0x02,0x66,0x00,0xb8,0x80,0x2e,0x30,0x88,0xb0,0x02,0x2c,0x00,0xb9,0x01 }, - 16, 0xdfd0, 0, {0x2e,0xc0,0x88,0x90,0x02,0xa4,0x00,0x89,0x00,0x22,0xc0,0x08,0x90,0x02,0x24,0x0c }, - 16, 0xdfe0, 0, {0x89,0x01,0x2e,0x40,0x1b,0x80,0x02,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdff0, 0, {0x08,0x04,0x00,0x00,0xb0,0x00,0x28,0xc0,0x28,0x30,0x02,0x00,0x00,0xb0,0x00,0x2c }, - 16, 0xe000, 0, {0x40,0x0a,0x30,0x02,0x00,0x00,0xb1,0x00,0x2c,0x00,0x08,0x10,0x0a,0x04,0x00,0x81 }, - 16, 0xe010, 0, {0x01,0xa2,0xc0,0x08,0x00,0x0a,0x04,0x80,0x81,0x00,0x2c,0x00,0x1b,0x00,0x0a,0x02 }, - 16, 0xe020, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xf8,0x00,0x32,0x40 }, - 16, 0xe030, 0, {0x0e,0xf0,0x23,0x64,0x08,0xf8,0x00,0x2e,0x00,0x0c,0xf0,0x03,0x2c,0x00,0xf8,0x00 }, - 16, 0xe040, 0, {0x3e,0xc0,0x0c,0x80,0x03,0x20,0x02,0xc8,0x04,0x32,0x00,0x1c,0x90,0x03,0x20,0x00 }, - 16, 0xe050, 0, {0xc8,0x01,0x3e,0x41,0x9f,0x90,0x43,0x40,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe060, 0, {0xa0,0x1d,0xf0,0x00,0xfc,0x0c,0x3f,0xc0,0x0f,0xf0,0x03,0xf0,0x10,0xf4,0x00,0x3f }, - 16, 0xe070, 0, {0x00,0x0f,0xf4,0x23,0xf0,0x00,0xfc,0x00,0x3f,0x00,0x0e,0xc0,0x03,0xb0,0x00,0xfc }, - 16, 0xe080, 0, {0x00,0x3f,0x00,0x0f,0xc0,0x03,0xe1,0x00,0xfc,0x00,0x3f,0x01,0x1f,0x50,0x03,0xe8 }, - 16, 0xe090, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x0d,0xf0,0xd0,0xff,0x20,0x3e,0xd0 }, - 16, 0xe0a0, 0, {0x8e,0xb0,0x03,0xec,0xa0,0xdb,0x28,0x3e,0xcc,0x0c,0xb3,0x03,0xad,0x08,0xf8,0x3c }, - 16, 0xe0b0, 0, {0x32,0x23,0x0e,0x48,0x23,0x7a,0x00,0xfd,0x94,0x3f,0xe0,0x0f,0x78,0x33,0xee,0x08 }, - 16, 0xe0c0, 0, {0xbf,0x80,0x3f,0xe4,0x0f,0xf9,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0d0, 0, {0xa0,0x00,0xec,0xc8,0xbf,0xd1,0x0f,0xc8,0x0c,0x26,0x82,0xfd,0x24,0x8f,0x00,0x2e }, - 16, 0xe0e0, 0, {0x99,0x0a,0xf2,0x62,0x1d,0xd0,0x99,0x61,0x22,0x71,0x88,0x88,0x02,0xac,0x00,0xb8 }, - 16, 0xe0f0, 0, {0x22,0x2e,0x20,0x4b,0x88,0x03,0xa0,0x00,0x80,0x00,0x2e,0x08,0x0b,0x80,0x23,0x60 }, - 16, 0xe100, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x04,0xb3,0x03,0x0c,0xcc }, - 16, 0xe110, 0, {0x0a,0x13,0x12,0xcc,0x14,0xa3,0x0e,0x0c,0x58,0x0a,0x33,0x02,0x8c,0x10,0xa3,0x20 }, - 16, 0xe120, 0, {0xa0,0x0a,0x18,0x90,0x02,0x48,0xa0,0xb0,0x20,0x24,0x80,0x0a,0x20,0x02,0xcc,0x09 }, - 16, 0xe130, 0, {0xa1,0x00,0x2c,0x80,0x0b,0x32,0x42,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe140, 0, {0xe0,0x11,0xac,0x20,0xbb,0x00,0x2e,0xc0,0x4b,0x80,0xa2,0xec,0x00,0xab,0x00,0x4e }, - 16, 0xe150, 0, {0x46,0x2a,0xb0,0x02,0x2c,0x04,0x9b,0x80,0x2a,0x60,0x8a,0x9c,0x02,0xac,0x00,0xb9 }, - 16, 0xe160, 0, {0x81,0x2e,0x40,0x0b,0x98,0x02,0xa3,0x00,0x8a,0x00,0x2e,0x40,0x0b,0x80,0x04,0xf0 }, - 16, 0xe170, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe1,0x00,0xfb,0x04,0x3e,0xc0 }, - 16, 0xe180, 0, {0x0e,0xb4,0x03,0xec,0x0a,0xdb,0x02,0x2e,0xd1,0x0e,0xb0,0x03,0xac,0x00,0xfb,0x82 }, - 16, 0xe190, 0, {0x32,0x28,0x1e,0x0c,0x03,0x68,0x00,0xb9,0x00,0x3e,0x40,0x4f,0xb0,0x43,0xed,0x00 }, - 16, 0xe1a0, 0, {0xea,0x00,0x3e,0x40,0x0f,0x80,0x03,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1b0, 0, {0xc0,0x01,0xb8,0x18,0xff,0x02,0x1f,0xc0,0x0c,0xe2,0x03,0xfc,0x00,0xdf,0x03,0x2f }, - 16, 0xe1c0, 0, {0xa1,0x0f,0x70,0x03,0xfc,0x04,0xab,0x04,0x37,0x42,0x2d,0xd0,0x02,0x7c,0x00,0xfc }, - 16, 0xe1d0, 0, {0x00,0x3f,0x80,0x0f,0xc0,0x03,0xb0,0x00,0xfd,0x00,0x3f,0x80,0x0f,0xf0,0x03,0x78 }, - 16, 0xe1e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa9,0x00,0xdb,0x00,0x3c,0xc0 }, - 16, 0xe1f0, 0, {0x2e,0x94,0x01,0x6c,0x11,0xcb,0x00,0xb8,0xc0,0x0c,0xb0,0x03,0x6c,0x00,0xeb,0x01 }, - 16, 0xe200, 0, {0x32,0x10,0x07,0x92,0x03,0xa8,0x00,0xf8,0x00,0x3e,0x0c,0x07,0xa2,0x03,0xad,0x00 }, - 16, 0xe210, 0, {0xd8,0x00,0x32,0x00,0x0c,0x80,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe220, 0, {0xc8,0x05,0x28,0x08,0xbf,0x00,0x2f,0xc0,0x88,0x80,0x02,0x3c,0x08,0xef,0x03,0x22 }, - 16, 0xe230, 0, {0x00,0x0d,0xf5,0x00,0x3c,0x00,0x8b,0x82,0x22,0x60,0x03,0x9c,0x02,0x2c,0x10,0xb9 }, - 16, 0xe240, 0, {0xb0,0x22,0xf0,0x0b,0x90,0x02,0x20,0x00,0xbb,0x00,0x22,0xe2,0x0d,0xb0,0x02,0xf2 }, - 16, 0xe250, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x40,0x00,0xb3,0x02,0x2c,0xc0 }, - 16, 0xe260, 0, {0x08,0x30,0x02,0x6c,0x00,0x83,0x00,0x20,0xc0,0x09,0x34,0x04,0xec,0x00,0xa8,0x00 }, - 16, 0xe270, 0, {0x22,0xf0,0x0b,0x00,0x02,0x88,0x00,0xb3,0x00,0x28,0xe0,0x0b,0x14,0x02,0xa0,0x00 }, - 16, 0xe280, 0, {0x93,0x00,0x20,0xc0,0x08,0xb0,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe290, 0, {0x20,0x01,0x1e,0x04,0xb7,0x80,0x2d,0xe8,0x08,0x78,0x02,0x0e,0xc8,0xa7,0x90,0x21 }, - 16, 0xe2a0, 0, {0xa8,0x19,0x38,0x52,0x9e,0xc1,0x87,0x80,0x21,0xe2,0x0b,0xd9,0x82,0x9e,0x00,0xb6 }, - 16, 0xe2b0, 0, {0xa0,0x2d,0x20,0x0b,0x68,0x02,0x1e,0x00,0xb4,0xc1,0x21,0x20,0x09,0x48,0x02,0xc8 }, - 16, 0xe2c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x0c,0x80,0xb3,0x10,0x3e,0xe0 }, - 16, 0xe2d0, 0, {0x0e,0x3a,0x07,0x4e,0x00,0xcb,0x90,0x3a,0x61,0x0d,0x38,0x03,0xce,0xd1,0xe1,0x98 }, - 16, 0xe2e0, 0, {0x30,0xa4,0x8f,0x10,0x03,0x88,0x00,0xba,0xa1,0x3c,0x84,0x07,0x00,0x03,0x82,0xd4 }, - 16, 0xe2f0, 0, {0xd1,0x00,0x72,0x80,0x0c,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe300, 0, {0x40,0x15,0xbc,0x04,0xff,0x00,0x3f,0xc0,0x0f,0xc2,0x23,0xec,0xb0,0xff,0x00,0x32 }, - 16, 0xe310, 0, {0x04,0x06,0xb4,0x23,0x7c,0x10,0xbf,0x00,0x3e,0x84,0x0f,0xb0,0x03,0x7c,0x40,0xff }, - 16, 0xe320, 0, {0x00,0x33,0x40,0x0f,0xf0,0x03,0xfc,0x00,0xfe,0x00,0xbf,0x40,0x0f,0xc8,0x03,0xd0 }, - 16, 0xe330, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe4,0x00,0xcb,0x33,0x3e,0xc8 }, - 16, 0xe340, 0, {0x4c,0xb0,0x03,0xac,0x90,0xdb,0xa0,0x36,0xc0,0x0e,0xba,0x43,0x6c,0x00,0xc9,0x00 }, - 16, 0xe350, 0, {0x3e,0x40,0x0f,0x00,0x0f,0x28,0x00,0xfb,0x00,0x3e,0x40,0x0f,0x18,0x43,0x60,0x00 }, - 16, 0xe360, 0, {0xfa,0x00,0x3e,0x40,0x4f,0x08,0x0b,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe370, 0, {0x48,0x11,0x9c,0x10,0x07,0x08,0x2c,0xca,0x08,0x20,0x02,0x1c,0x20,0x87,0x28,0x3f }, - 16, 0xe380, 0, {0x80,0x8a,0xf0,0x02,0x1d,0x40,0x87,0x04,0x2d,0xc0,0x0b,0x70,0x02,0x1c,0x00,0xb6 }, - 16, 0xe390, 0, {0x00,0x2d,0x80,0x0b,0x60,0x03,0x1c,0x00,0xb5,0x00,0x2d,0x80,0x0b,0x70,0x02,0x12 }, - 16, 0xe3a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x87,0xa0,0x2d,0xe4 }, - 16, 0xe3b0, 0, {0x0a,0x58,0x02,0x1e,0x01,0x83,0x90,0x21,0x70,0x0b,0x79,0x02,0x9e,0x01,0x85,0xc0 }, - 16, 0xe3c0, 0, {0x2d,0xe0,0x4b,0x58,0x12,0x1a,0x00,0xb6,0x80,0x2d,0x20,0x0b,0x48,0x02,0x52,0x00 }, - 16, 0xe3d0, 0, {0xb4,0x80,0x2d,0x20,0x0b,0x48,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3e0, 0, {0x48,0x14,0xec,0x00,0x83,0x00,0x2c,0xc0,0x88,0x36,0x02,0x0c,0x02,0x83,0x00,0x6c }, - 16, 0xe3f0, 0, {0xc0,0x0b,0x30,0x0a,0xac,0x00,0x9b,0xe0,0x6c,0xc8,0x0b,0x32,0x02,0x0c,0x01,0xb3 }, - 16, 0xe400, 0, {0x00,0x2c,0xc0,0x0b,0x30,0x02,0x0c,0x10,0xb3,0x40,0x2c,0xc0,0x0b,0x3c,0x82,0x12 }, - 16, 0xe410, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x02,0xca,0x00,0x3e,0x80 }, - 16, 0xe420, 0, {0x0e,0xe4,0x8b,0x28,0x00,0xca,0x00,0x33,0x95,0x0f,0xa0,0x07,0xa8,0x02,0xce,0x40 }, - 16, 0xe430, 0, {0x3f,0xb0,0x0f,0xe4,0x82,0x28,0x00,0xfa,0x00,0x3e,0x80,0x0f,0xa0,0x23,0x68,0x00 }, - 16, 0xe440, 0, {0xfa,0x40,0x3e,0x81,0x4f,0xa4,0xe3,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe450, 0, {0x48,0x00,0xe0,0x80,0xf0,0x00,0x3c,0x00,0x2f,0x00,0x02,0x60,0x00,0xe8,0x00,0x3c }, - 16, 0xe460, 0, {0x00,0x0e,0x80,0x01,0x20,0x00,0xe8,0x04,0x5e,0x04,0x0f,0x80,0x03,0xe0,0x00,0xfc }, - 16, 0xe470, 0, {0x01,0x3f,0x10,0x0f,0xc4,0x03,0xb0,0x00,0xfc,0x09,0x3f,0x00,0x0f,0xc0,0x03,0xd2 }, - 16, 0xe480, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xa9,0x20,0x36,0x40 }, - 16, 0xe490, 0, {0x0e,0x90,0x03,0x44,0x04,0xd9,0x00,0x3e,0x40,0x0d,0x90,0x03,0xe4,0x04,0xc9,0x00 }, - 16, 0xe4a0, 0, {0x32,0x40,0x8f,0x90,0x0b,0xe4,0x08,0xf9,0x00,0x3e,0x44,0x0e,0x98,0x03,0xe6,0x00 }, - 16, 0xe4b0, 0, {0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4c0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x40,0x18,0x90,0x02,0x24,0x00,0x89,0x00,0x2e }, - 16, 0xe4d0, 0, {0x40,0x08,0x94,0x02,0xe4,0x00,0xd9,0x04,0x22,0x40,0x0b,0x1c,0x0b,0x64,0x00,0xb9 }, - 16, 0xe4e0, 0, {0x94,0x2c,0x50,0x08,0x9c,0x02,0xe4,0x14,0xb9,0x90,0x0e,0x40,0x0b,0x90,0x02,0xe0 }, - 16, 0xe4f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x02,0x89,0x00,0x26,0x40 }, - 16, 0xe500, 0, {0x4a,0x90,0x02,0x64,0x00,0x99,0x04,0x2e,0x40,0x08,0x98,0x82,0xe4,0x00,0x89,0x00 }, - 16, 0xe510, 0, {0x6a,0x40,0x0a,0x92,0x82,0xe4,0x00,0xbd,0x01,0x2f,0x50,0x12,0xd6,0x02,0xf4,0x40 }, - 16, 0xe520, 0, {0xbd,0x00,0x0f,0x40,0x0b,0xd0,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe530, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0x20,0x48,0x08,0x12,0x02,0x04,0x80,0x81,0x22,0x2c }, - 16, 0xe540, 0, {0x48,0xa8,0x12,0x06,0xc4,0x90,0x91,0x20,0x28,0x50,0x0b,0x90,0x02,0x45,0x00,0xb5 }, - 16, 0xe550, 0, {0x40,0x6d,0x40,0x08,0x50,0x12,0xd4,0x04,0xb5,0x02,0x2d,0x40,0x0b,0x50,0x02,0xc2 }, - 16, 0xe560, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc8,0x00,0x36,0x14 }, - 16, 0xe570, 0, {0x0a,0x85,0x03,0x41,0x40,0xd8,0x50,0x2e,0x14,0x0c,0x85,0x03,0xc1,0x40,0xc8,0x50 }, - 16, 0xe580, 0, {0xba,0x00,0x0e,0x80,0x23,0xe0,0x00,0x78,0x00,0x3e,0x00,0x0e,0x80,0x03,0xe0,0x04 }, - 16, 0xe590, 0, {0xf8,0x00,0x3e,0x00,0x0f,0xc0,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5a0, 0, {0x98,0x1d,0xf4,0x40,0xd9,0x10,0x3e,0x44,0x07,0xf1,0x03,0xe4,0x40,0xf9,0x10,0x3f }, - 16, 0xe5b0, 0, {0x44,0xaf,0x91,0x03,0xe4,0x40,0xfd,0x10,0x37,0x50,0x0f,0xd0,0x03,0xe4,0x00,0xf9 }, - 16, 0xe5c0, 0, {0x00,0x3e,0x40,0x0f,0x90,0x03,0xe4,0xa0,0xf9,0x28,0x3e,0x4a,0x0f,0x92,0x83,0xe6 }, - 16, 0xe5d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0xd4,0xfd,0xa2,0x3a,0x70 }, - 16, 0xe5e0, 0, {0x8c,0x9e,0x03,0x26,0x80,0xc9,0xa0,0x32,0x68,0x0c,0xdb,0x43,0x27,0x80,0x9d,0xa2 }, - 16, 0xe5f0, 0, {0xb7,0x40,0x0f,0x50,0x03,0x65,0x00,0xfd,0x00,0x3f,0xc1,0x07,0xd0,0x03,0xf5,0x04 }, - 16, 0xe600, 0, {0xfd,0x40,0x2f,0xc0,0x0c,0xd0,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe610, 0, {0x38,0x10,0xe3,0x88,0xb8,0x50,0x22,0x38,0x08,0x8e,0x00,0xa2,0xa0,0x88,0xe8,0x22 }, - 16, 0xe620, 0, {0x38,0x48,0x88,0x03,0x62,0x10,0xa8,0xe8,0x3c,0x00,0x0b,0x80,0x03,0x62,0x80,0xb8 }, - 16, 0xe630, 0, {0x01,0x2e,0x80,0x0b,0x80,0x21,0xa2,0x00,0xb0,0x84,0x2e,0x2a,0x28,0x8a,0x82,0xce }, - 16, 0xe640, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x40,0xb1,0x00,0x28,0x58 }, - 16, 0xe650, 0, {0x80,0x13,0x40,0x05,0x00,0x81,0x40,0x20,0x52,0x28,0x16,0x02,0x85,0x80,0x9b,0xc2 }, - 16, 0xe660, 0, {0x64,0x41,0x8b,0x98,0x02,0x04,0x00,0xb1,0x09,0x2c,0x40,0x1b,0x10,0x20,0xc4,0x00 }, - 16, 0xe670, 0, {0xb1,0x00,0x2c,0x40,0x48,0x10,0x02,0xc2,0x05,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe680, 0, {0x18,0x15,0xa5,0x84,0xb9,0x00,0x20,0x40,0x08,0x90,0x02,0x24,0x00,0x01,0x00,0x20 }, - 16, 0xe690, 0, {0x50,0x08,0x90,0x42,0x64,0x00,0xa9,0x10,0xae,0x58,0x03,0x98,0x02,0x64,0x00,0xb9 }, - 16, 0xe6a0, 0, {0x00,0x2e,0x40,0x0b,0x90,0x46,0xa4,0x10,0xb9,0x00,0x2e,0x41,0x08,0x90,0x02,0xc6 }, - 16, 0xe6b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe7,0x00,0xf9,0x00,0x2a,0x40 }, - 16, 0xe6c0, 0, {0x2c,0x94,0x0b,0x24,0x02,0xc9,0x00,0xb2,0x44,0x0c,0x90,0x03,0x24,0x04,0xd9,0x80 }, - 16, 0xe6d0, 0, {0xb6,0x41,0x8f,0x18,0x03,0x24,0x00,0xf9,0x60,0x3e,0x40,0x0f,0x96,0x03,0xe4,0x00 }, - 16, 0xe6e0, 0, {0xf9,0x80,0x3e,0x42,0x8c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6f0, 0, {0x28,0x01,0xa6,0x00,0xf1,0x00,0x3e,0x40,0x0f,0x1c,0x03,0xc4,0x00,0xf9,0x00,0x3e }, - 16, 0xe700, 0, {0x40,0x8f,0x90,0x23,0xc4,0x10,0xf9,0x00,0xbe,0x40,0x0f,0x90,0x0b,0xe4,0x00,0xf9 }, - 16, 0xe710, 0, {0x00,0x3e,0x40,0x07,0x90,0x23,0xe4,0x00,0xf9,0x20,0x3e,0x40,0x8f,0x90,0x03,0xca }, - 16, 0xe720, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xf8,0x00,0xbe,0x00 }, - 16, 0xe730, 0, {0x0e,0x84,0x03,0x20,0x00,0xc8,0x00,0x32,0x00,0x0c,0x00,0x83,0x20,0x00,0xf8,0x00 }, - 16, 0xe740, 0, {0x3e,0x00,0x0c,0x80,0x03,0xa0,0x00,0xf8,0x00,0x36,0x10,0x0f,0x80,0x43,0xe0,0x08 }, - 16, 0xe750, 0, {0xf8,0x00,0x32,0x00,0x0f,0x80,0x03,0xca,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe760, 0, {0x28,0x05,0x28,0x00,0xba,0x00,0x22,0x80,0x48,0xa0,0x03,0x68,0x00,0xaa,0x00,0x2a }, - 16, 0xe770, 0, {0x80,0x08,0xe0,0x03,0x68,0x00,0x82,0x00,0x2f,0x80,0x08,0xe6,0x02,0x28,0x04,0xbe }, - 16, 0xe780, 0, {0x40,0x23,0x80,0x0b,0xe8,0x02,0xea,0x00,0xbe,0x01,0x22,0x80,0x0b,0xe0,0x02,0xca }, - 16, 0xe790, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x01,0x93,0x01,0x20,0xc1 }, - 16, 0xe7a0, 0, {0x0a,0x30,0x02,0x0c,0x00,0xa3,0x00,0x20,0xc0,0x88,0x38,0x42,0x0c,0x00,0xa3,0x00 }, - 16, 0xe7b0, 0, {0x24,0xc0,0x0a,0x3e,0x42,0x8c,0x00,0xb2,0x4c,0x24,0xe0,0x4b,0x38,0x02,0xc4,0x41 }, - 16, 0xe7c0, 0, {0xb3,0x00,0x22,0xc0,0x0b,0x10,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7d0, 0, {0xa0,0x01,0x1c,0x00,0xb7,0x00,0x20,0xc9,0x48,0x70,0x02,0xdc,0x40,0xa7,0x14,0x2c }, - 16, 0xe7e0, 0, {0xc8,0x28,0x30,0x82,0x5c,0xc1,0x85,0x00,0x2d,0xe0,0x2a,0xf0,0x12,0x1c,0x80,0xb7 }, - 16, 0xe7f0, 0, {0xa0,0x21,0x82,0x0b,0x70,0x82,0xd4,0x11,0xb6,0x80,0x21,0x40,0x4b,0x50,0x02,0xe8 }, - 16, 0xe800, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x80,0xd5,0x80,0x29,0xea }, - 16, 0xe810, 0, {0x4e,0x3a,0x07,0x0e,0x80,0xe3,0xb0,0x31,0xfc,0x0c,0x48,0x03,0x0e,0x41,0xe7,0x80 }, - 16, 0xe820, 0, {0x3d,0xe0,0x0e,0x78,0x03,0x9e,0x80,0xf4,0xc4,0x35,0xe0,0x0f,0x78,0x27,0xde,0x00 }, - 16, 0xe830, 0, {0xf5,0x80,0xb1,0xe0,0x0f,0x58,0x03,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe840, 0, {0x08,0x1d,0xac,0x00,0x31,0x04,0x3a,0xc4,0x0f,0xb5,0x93,0x6d,0x08,0xfb,0x40,0x3a }, - 16, 0xe850, 0, {0xc8,0x63,0x80,0x23,0xec,0x98,0xe9,0x00,0x3e,0xc0,0x0d,0xb0,0x43,0xec,0x00,0xf3 }, - 16, 0xe860, 0, {0x80,0x3e,0x40,0x4f,0xa0,0x03,0xec,0x00,0xf8,0x68,0x3e,0x40,0x8f,0x98,0x03,0xc2 }, - 16, 0xe870, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x60,0xeb,0x90,0x3e,0xe4 }, - 16, 0xe880, 0, {0x0f,0xb8,0x00,0x3f,0x40,0xcb,0x80,0x7f,0xe0,0x0e,0xfb,0x03,0x2e,0x40,0xcb,0x80 }, - 16, 0xe890, 0, {0x3f,0xe0,0x0f,0x79,0x43,0x2e,0x60,0xca,0x81,0x33,0x64,0x8f,0xd9,0x03,0xfe,0x00 }, - 16, 0xe8a0, 0, {0xff,0x81,0x33,0xe0,0x0f,0xd9,0x8b,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8b0, 0, {0xa8,0x01,0x9c,0x00,0x87,0x81,0x19,0xe4,0x0b,0xfa,0x13,0x5e,0x80,0x87,0xb2,0x2d }, - 16, 0xe8c0, 0, {0xec,0x0d,0x79,0x01,0x9e,0x00,0xd5,0x90,0x2d,0xf8,0x0b,0x78,0x03,0x7e,0x08,0xab }, - 16, 0xe8d0, 0, {0x91,0x29,0x85,0x0b,0x51,0x02,0xdc,0x48,0xb6,0x40,0x21,0x40,0x0b,0x50,0x02,0x2a }, - 16, 0xe8e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x14,0xb5,0x20,0x6d,0xc8 }, - 16, 0xe8f0, 0, {0x0b,0x72,0x02,0x5c,0x80,0x87,0x20,0x69,0xc0,0x88,0x53,0x02,0xcc,0x81,0x97,0x50 }, - 16, 0xe900, 0, {0x2d,0xc8,0x0b,0xf7,0x0a,0xdc,0xc0,0x84,0x01,0x21,0x44,0x1b,0x70,0x22,0xdc,0x00 }, - 16, 0xe910, 0, {0xb5,0x00,0x21,0xc4,0x0b,0x50,0x86,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe920, 0, {0x20,0x14,0xcf,0x30,0x91,0x00,0x2c,0xc0,0x0b,0x34,0x02,0x4c,0x00,0x83,0x00,0x2c }, - 16, 0xe930, 0, {0xf2,0x0b,0x10,0x22,0x0c,0x00,0x91,0x00,0x2c,0xc8,0x0b,0x18,0x0a,0xcd,0x01,0xa3 }, - 16, 0xe940, 0, {0x00,0x28,0x60,0x0b,0x21,0x02,0xce,0x20,0xb8,0x40,0xa0,0x54,0x0b,0x18,0x02,0x08 }, - 16, 0xe950, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbd,0x00,0xf9,0x00,0x2f,0xc0 }, - 16, 0xe960, 0, {0x0f,0xf4,0x02,0x7c,0x12,0xcf,0x03,0x3f,0xc2,0x0e,0xb0,0x03,0xfc,0x04,0x9b,0x02 }, - 16, 0xe970, 0, {0x2e,0xf2,0x0f,0xa4,0x0b,0xdc,0x00,0xce,0x00,0xb0,0xc8,0x8f,0xa4,0x03,0xef,0x00 }, - 16, 0xe980, 0, {0xf8,0x80,0x32,0xf5,0x1f,0xdd,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe990, 0, {0x80,0x00,0xec,0x40,0xe9,0x00,0x3a,0xc0,0x0f,0xb1,0x03,0xcc,0x00,0xf3,0x00,0x3e }, - 16, 0xe9a0, 0, {0xc0,0x0d,0xb4,0x09,0xec,0x18,0xf9,0x10,0x3e,0x10,0x4f,0xb1,0x0a,0x6c,0x80,0xf9 }, - 16, 0xe9b0, 0, {0x89,0x36,0x82,0x0b,0xa6,0x03,0xec,0x50,0xf9,0x50,0x3e,0xc0,0x1f,0x90,0x03,0x60 }, - 16, 0xe9c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xfd,0xa0,0x3d,0xc0 }, - 16, 0xe9d0, 0, {0x0c,0x70,0x83,0x2c,0x00,0xef,0x02,0x35,0xc0,0x0d,0xe2,0x03,0xfc,0x04,0xff,0x02 }, - 16, 0xe9e0, 0, {0x2d,0xe0,0x8e,0xf0,0x03,0x3c,0x10,0xdc,0x00,0x3f,0x80,0x0c,0xd8,0x03,0xfc,0x00 }, - 16, 0xe9f0, 0, {0xde,0x18,0x33,0xf0,0x4f,0xd0,0x03,0xc0,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea00, 0, {0x81,0x00,0x6c,0x00,0xb9,0x00,0x2e,0xc0,0x4c,0xb0,0x03,0x6c,0x00,0x8b,0x02,0x36 }, - 16, 0xea10, 0, {0xc0,0x0d,0xac,0x12,0xec,0x00,0x79,0x00,0x2e,0x30,0x0d,0x3d,0x42,0xac,0x00,0x89 }, - 16, 0xea20, 0, {0x88,0x1a,0x10,0x0d,0x86,0x02,0xee,0x04,0xbb,0x40,0x22,0xe0,0x0b,0x90,0x02,0xe0 }, - 16, 0xea30, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x01,0xb9,0x00,0x2e,0xc0 }, - 16, 0xea40, 0, {0x08,0xb0,0x42,0xac,0x00,0x0b,0x05,0x26,0xc0,0x09,0x94,0x20,0xec,0x00,0xb9,0x80 }, - 16, 0xea50, 0, {0x6e,0xc4,0x88,0xb0,0x82,0x2c,0x00,0x9b,0x82,0x2e,0x42,0x08,0x81,0x02,0xe4,0x80 }, - 16, 0xea60, 0, {0xb8,0x00,0x22,0xc1,0x0b,0x90,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea70, 0, {0x08,0x04,0x0c,0x10,0xb1,0x25,0x2c,0xca,0x08,0x34,0x46,0xcc,0x08,0x83,0x00,0x24 }, - 16, 0xea80, 0, {0xc2,0x0b,0x02,0x52,0xcc,0x81,0x83,0x00,0x2c,0x00,0x19,0xb2,0x42,0xac,0x80,0x81 }, - 16, 0xea90, 0, {0x08,0x28,0x80,0x09,0x00,0x02,0xc4,0x40,0xb1,0x00,0x20,0xc0,0x0b,0x10,0x02,0xc2 }, - 16, 0xeaa0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x6c,0x00,0xb9,0x00,0x3f,0xd0 }, - 16, 0xeab0, 0, {0x08,0xf6,0x07,0xbc,0xc2,0xaf,0x30,0x75,0xdc,0x0d,0x16,0x02,0xfc,0xe0,0xb9,0x50 }, - 16, 0xeac0, 0, {0x3e,0xcc,0x0c,0xb0,0x23,0x2c,0x10,0xd9,0x00,0x3e,0x00,0x0c,0x90,0x03,0xec,0x00 }, - 16, 0xead0, 0, {0xde,0x01,0x32,0xc0,0x0f,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeae0, 0, {0xa0,0x19,0xfc,0x00,0xfd,0x10,0x3f,0xca,0x2e,0xf6,0x03,0x6d,0x94,0x9f,0x30,0x3a }, - 16, 0xeaf0, 0, {0xc9,0x0c,0x83,0x93,0xfc,0x80,0xff,0x11,0x7e,0x19,0x0b,0xb1,0x03,0xfc,0x40,0xfd }, - 16, 0xeb00, 0, {0x08,0x3b,0x00,0x0f,0xc0,0x03,0xfc,0x80,0x77,0x00,0xbf,0xc0,0x0f,0x50,0x03,0xe8 }, - 16, 0xeb10, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x00,0xf4,0x94,0x37,0xc8 }, - 16, 0xeb20, 0, {0x0d,0x69,0x63,0x7c,0x10,0xff,0x62,0x37,0xc0,0x0d,0xb4,0x03,0x7c,0x60,0xd4,0x80 }, - 16, 0xeb30, 0, {0x3f,0x40,0x0f,0x48,0x23,0x32,0x00,0xce,0x00,0xbf,0x40,0x8f,0xd1,0x03,0x30,0xe0 }, - 16, 0xeb40, 0, {0xff,0x30,0x3b,0x60,0x0f,0xd8,0x03,0xb0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb50, 0, {0x80,0x10,0xed,0x20,0xb8,0x24,0x23,0xf4,0x49,0xa2,0x02,0x3f,0x40,0x8f,0x51,0x23 }, - 16, 0xeb60, 0, {0xda,0x08,0xf6,0x12,0x3d,0x80,0x9b,0x80,0x2e,0x49,0x4b,0x80,0x03,0x40,0x00,0xd9 }, - 16, 0xeb70, 0, {0x01,0x22,0x74,0x0b,0xd5,0x02,0x21,0x00,0xbf,0x42,0x2e,0x49,0x0b,0x9c,0x02,0xe0 }, - 16, 0xeb80, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcd,0x80,0xb8,0x20,0x28,0xc1 }, - 16, 0xeb90, 0, {0x1b,0xa0,0x02,0x4c,0x00,0x93,0x20,0x2c,0xd8,0x0b,0x34,0x02,0xcc,0x00,0x90,0x01 }, - 16, 0xeba0, 0, {0x2c,0xc6,0x1a,0xa0,0x02,0x68,0x08,0x83,0x00,0xa4,0x40,0x0b,0x10,0x02,0x00,0x00 }, - 16, 0xebb0, 0, {0xb3,0x10,0x28,0x42,0x0b,0x14,0x02,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xebc0, 0, {0xc0,0x15,0xac,0x00,0xb8,0x60,0x2a,0xc0,0x1b,0xa0,0x8e,0xac,0x01,0x9b,0x05,0x26 }, - 16, 0xebd0, 0, {0xc0,0x03,0xb0,0x42,0x6c,0x00,0x9b,0x80,0x2e,0xc0,0x03,0xa0,0x06,0x69,0x00,0x99 }, - 16, 0xebe0, 0, {0x80,0xaa,0xc0,0x0b,0x90,0x02,0x63,0x00,0x3b,0x00,0x2e,0x58,0x4b,0x90,0x02,0xf0 }, - 16, 0xebf0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xec,0x04,0xf8,0x80,0xba,0xc0 }, - 16, 0xec00, 0, {0x0f,0x30,0x03,0x6c,0x10,0xdb,0x03,0x36,0xc0,0x8f,0xb0,0x03,0xec,0x08,0xd8,0x80 }, - 16, 0xec10, 0, {0x7e,0xe0,0x06,0x88,0x03,0x41,0x08,0xcb,0xa0,0x3e,0x64,0x0f,0x90,0x0b,0x2a,0x00 }, - 16, 0xec20, 0, {0x7b,0x00,0x3a,0x01,0x0f,0x90,0x03,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec30, 0, {0xe0,0x01,0xbc,0x00,0xfc,0x84,0x32,0xc0,0x0c,0xf9,0x03,0x5c,0x10,0xef,0x00,0x3b }, - 16, 0xec40, 0, {0xc0,0x0c,0x70,0x03,0x9c,0x00,0xec,0x01,0x3f,0xe4,0x4f,0xd1,0x03,0xf1,0x00,0xf3 }, - 16, 0xec50, 0, {0x05,0x33,0x60,0x0f,0xd0,0x03,0xbc,0x04,0xff,0x00,0x3f,0x21,0x0f,0xd0,0x03,0xf8 }, - 16, 0xec60, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xc8,0x40,0x3a,0xc6 }, - 16, 0xec70, 0, {0x0d,0xb4,0x03,0x6c,0x00,0xf3,0x00,0x34,0xc0,0x0e,0xb0,0x03,0x6c,0x00,0xe9,0x10 }, - 16, 0xec80, 0, {0x3a,0xc0,0x0f,0x84,0x03,0x2c,0x60,0xcb,0x00,0x32,0x60,0x0c,0x50,0x03,0x61,0x00 }, - 16, 0xec90, 0, {0xcb,0x00,0x3e,0x90,0x0e,0x90,0xa3,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeca0, 0, {0xc8,0x05,0x3c,0x02,0x88,0x01,0x01,0xf0,0x20,0xb0,0x01,0x3e,0x00,0x3f,0x00,0x33 }, - 16, 0xecb0, 0, {0xc0,0x0b,0xf0,0x32,0x3c,0x08,0x89,0x80,0x22,0xc0,0x01,0x15,0x12,0xac,0x00,0x8b }, - 16, 0xecc0, 0, {0x00,0x22,0xc0,0x48,0xdb,0x02,0x2f,0x40,0x8f,0x00,0x2e,0x01,0x08,0xd4,0x80,0x32 }, - 16, 0xecd0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x08,0x00,0x08,0xf0 }, - 16, 0xece0, 0, {0x08,0x00,0x12,0x4c,0x00,0x33,0x01,0x24,0xc0,0x4a,0x30,0x02,0x4c,0x00,0xa0,0x20 }, - 16, 0xecf0, 0, {0x28,0xc0,0x0b,0x10,0x02,0x46,0x04,0x83,0x04,0x20,0xc0,0x29,0x18,0x02,0x04,0x40 }, - 16, 0xed00, 0, {0xb3,0x00,0x2c,0x40,0x0a,0x1c,0x42,0xb1,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed10, 0, {0x20,0x01,0x1e,0x01,0x8d,0x80,0x21,0xe0,0x18,0xc8,0x02,0x1e,0x00,0xb3,0xa0,0x21 }, - 16, 0xed20, 0, {0xe0,0x1b,0x38,0x02,0x0e,0x01,0xa7,0x80,0x21,0xe0,0x09,0xd8,0x40,0xd6,0x40,0x87 }, - 16, 0xed30, 0, {0x80,0x01,0xe0,0x09,0x59,0x02,0x16,0x00,0x97,0x84,0x2d,0x60,0x08,0x58,0x40,0x00 }, - 16, 0xed40, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x2c,0x40,0xc0,0x00,0x38,0xc4 }, - 16, 0xed50, 0, {0x0c,0x30,0x27,0x4c,0x20,0xf3,0x01,0x34,0xc1,0x0e,0x3a,0x03,0x4c,0xc4,0xe0,0x00 }, - 16, 0xed60, 0, {0x18,0xc8,0x0f,0x34,0x03,0x44,0x40,0xc3,0x00,0x30,0xc0,0x0d,0x90,0x03,0x2e,0x00 }, - 16, 0xed70, 0, {0xf3,0x00,0x3e,0x40,0x0e,0x10,0x01,0x9a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed80, 0, {0x40,0x1d,0xbc,0x00,0xf9,0x00,0x0e,0xd4,0x0e,0xb0,0x03,0xec,0x20,0xfb,0x20,0x3f }, - 16, 0xed90, 0, {0xc4,0x0f,0xf1,0x03,0xec,0x60,0xdb,0x10,0x3f,0xc0,0x4f,0xf0,0x03,0xa4,0x46,0xfb }, - 16, 0xeda0, 0, {0x00,0xbd,0xc0,0x0e,0xd0,0x0b,0xb4,0x00,0xef,0x48,0x3f,0x40,0x0f,0x50,0x03,0xd0 }, - 16, 0xedb0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xf8,0x00,0x32,0xd4 }, - 16, 0xedc0, 0, {0x0f,0x80,0x03,0xad,0x00,0xeb,0x08,0x22,0xd2,0x0c,0xb6,0x03,0x6c,0x00,0xf2,0x80 }, - 16, 0xedd0, 0, {0x36,0xc0,0x0e,0xa0,0x03,0x28,0x10,0xcb,0x00,0xb2,0xc0,0x0f,0xd6,0x03,0x28,0x10 }, - 16, 0xede0, 0, {0xfb,0x20,0x3e,0x40,0x4f,0x99,0x13,0x2b,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xedf0, 0, {0x48,0x11,0x9d,0x10,0xb4,0x01,0x21,0xc1,0x8b,0xc0,0x02,0x1c,0xa0,0xbf,0x04,0x27 }, - 16, 0xee00, 0, {0xc8,0x08,0x75,0x02,0x1c,0xc0,0xb6,0x00,0x21,0xc0,0x08,0xf0,0x42,0x18,0x10,0x8f }, - 16, 0xee10, 0, {0x00,0x21,0xc0,0x0b,0x54,0xa2,0x1c,0x00,0xb7,0x04,0x2d,0x41,0x0b,0x52,0x02,0x12 }, - 16, 0xee20, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x80,0xb6,0x88,0xa5,0xe0 }, - 16, 0xee30, 0, {0x0b,0x78,0x12,0x9e,0x81,0xa7,0x90,0x25,0xe4,0x88,0x78,0x02,0x1e,0x80,0xbf,0x80 }, - 16, 0xee40, 0, {0x24,0x60,0x0b,0x68,0x02,0x1e,0x00,0x87,0x84,0x61,0xe0,0x0a,0x1a,0x0a,0x1a,0x00 }, - 16, 0xee50, 0, {0xb7,0xa0,0x2d,0xe0,0x0b,0xda,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee60, 0, {0x48,0x14,0xcc,0x00,0xba,0xc0,0xa4,0xc0,0x0b,0x34,0x02,0x0c,0x00,0xb3,0x00,0x24 }, - 16, 0xee70, 0, {0xc0,0x08,0xb0,0x0e,0x2c,0x00,0xb3,0x98,0x20,0x60,0x09,0x33,0x02,0x2c,0x00,0xa3 }, - 16, 0xee80, 0, {0xc8,0x20,0xc0,0x0b,0x10,0x02,0x0c,0x00,0xb3,0x00,0x2c,0xf0,0x0b,0x10,0x02,0x12 }, - 16, 0xee90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0x80,0x36,0x81 }, - 16, 0xeea0, 0, {0x0b,0xe0,0x03,0xa8,0x00,0xea,0x00,0xb2,0x80,0x08,0xa0,0x03,0x68,0x00,0xfe,0x00 }, - 16, 0xeeb0, 0, {0x36,0xa0,0x1f,0xe8,0x13,0x3b,0x82,0xce,0xe0,0x22,0x80,0x8e,0xa0,0x03,0x38,0x00 }, - 16, 0xeec0, 0, {0xba,0x00,0x3f,0xa2,0x0f,0xa0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeed0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x20,0x3a,0x10,0x07,0x80,0x03,0xc1,0x00,0xf8,0x00,0x38 }, - 16, 0xeee0, 0, {0x00,0x2f,0x80,0x03,0xa0,0x01,0xf8,0x42,0x3e,0x05,0x0e,0x80,0x0b,0xe0,0x80,0xd8 }, - 16, 0xeef0, 0, {0x00,0x3e,0x00,0x0f,0x84,0x03,0xe1,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x84,0x0b,0xd2 }, - 16, 0xef00, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc9,0x00,0x3a,0x50 }, - 16, 0xef10, 0, {0x8f,0x90,0x83,0xa4,0x02,0xd1,0x00,0xb2,0x40,0x4c,0x90,0x23,0x24,0x08,0xc9,0x01 }, - 16, 0xef20, 0, {0x3e,0x40,0x0c,0x90,0x03,0x24,0x00,0xc1,0x00,0x32,0x40,0x0f,0x14,0x0a,0x25,0x20 }, - 16, 0xef30, 0, {0xe9,0x00,0x3e,0x42,0x0f,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef40, 0, {0x80,0x04,0x64,0x0a,0x89,0x00,0x22,0x70,0x0b,0x90,0x12,0x25,0x80,0xc9,0x00,0x22 }, - 16, 0xef50, 0, {0x40,0x0a,0x90,0x03,0x64,0x00,0x89,0x20,0x2c,0x40,0x0a,0x90,0x0a,0x24,0x00,0x89 }, - 16, 0xef60, 0, {0xc1,0x32,0x40,0x0b,0x98,0x02,0x06,0x00,0x89,0x90,0x2e,0x40,0x0b,0x94,0x12,0xe0 }, - 16, 0xef70, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x04,0x00,0x89,0x00,0x6a,0x42 }, - 16, 0xef80, 0, {0x0a,0x10,0x02,0xa4,0x00,0x89,0x00,0xa2,0x40,0x0a,0x90,0x02,0x24,0x00,0x09,0x00 }, - 16, 0xef90, 0, {0x2e,0x40,0x58,0x10,0x02,0x24,0x00,0x89,0x80,0xaa,0x60,0x0b,0x90,0x02,0xa4,0x04 }, - 16, 0xefa0, 0, {0xa9,0x00,0x2e,0x40,0x0b,0x94,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xefb0, 0, {0x08,0x04,0x04,0x80,0x81,0x00,0x60,0x48,0x0b,0x10,0x02,0x04,0x81,0x81,0x20,0x60 }, - 16, 0xefc0, 0, {0x48,0x0a,0x12,0x02,0x44,0x88,0x81,0x00,0x0e,0x59,0x0a,0x14,0x02,0x05,0x00,0x81 }, - 16, 0xefd0, 0, {0xc0,0x28,0x50,0x49,0x30,0x02,0x8c,0x84,0x01,0x60,0x2c,0x50,0x0b,0x10,0x02,0xc2 }, - 16, 0xefe0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc0,0x54,0x2a,0x00 }, - 16, 0xeff0, 0, {0x0e,0x85,0x03,0xa0,0x00,0xc8,0x50,0x32,0x15,0x1e,0x05,0x22,0x21,0x42,0xc8,0x00 }, - 16, 0xf000, 0, {0x3e,0x00,0x0c,0x80,0x03,0x00,0x04,0xc8,0x00,0x3a,0x00,0x4f,0x85,0x03,0xa1,0x40 }, - 16, 0xf010, 0, {0x68,0x00,0x3e,0x00,0x0f,0x80,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf020, 0, {0x98,0x1d,0xe4,0x40,0xfd,0x03,0x3e,0x44,0x0f,0xd0,0x03,0xe4,0x48,0xe9,0x10,0x3e }, - 16, 0xf030, 0, {0x45,0x0f,0x91,0x13,0xe4,0x40,0xfd,0x00,0x3f,0x44,0x0f,0xd0,0x03,0xf4,0x02,0xfd }, - 16, 0xf040, 0, {0x40,0x33,0x50,0x0f,0xd4,0x23,0x74,0x40,0xf9,0x10,0x3f,0x40,0x0f,0x54,0x03,0xe6 }, - 16, 0xf050, 0, {0x02,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe4,0x00,0xf9,0x01,0x33,0x6a }, - 16, 0xf060, 0, {0x09,0x90,0x03,0xb6,0x34,0xf9,0xc8,0x32,0x64,0x0c,0x9a,0x03,0xe6,0xa0,0xdd,0x00 }, - 16, 0xf070, 0, {0x3c,0x70,0x0f,0x90,0x03,0xa5,0x00,0x89,0x80,0x33,0x32,0x0f,0xd8,0x13,0x3c,0x00 }, - 16, 0xf080, 0, {0xfd,0x00,0x70,0x50,0x0f,0xd0,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf090, 0, {0x38,0x10,0xe2,0x80,0xb8,0xa8,0x22,0x10,0x08,0x88,0x02,0x21,0x00,0xb8,0xc0,0x20 }, - 16, 0xf0a0, 0, {0x30,0x0d,0x8e,0x87,0x83,0x88,0x88,0x00,0x2e,0x34,0x0b,0x8a,0x82,0x22,0x80,0xdc }, - 16, 0xf0b0, 0, {0xe0,0x22,0x38,0x0b,0x80,0x02,0x20,0x00,0xf8,0xa8,0x2a,0x28,0x0b,0x80,0x02,0x0e }, - 16, 0xf0c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x20,0xb1,0x00,0x20,0x40 }, - 16, 0xf0d0, 0, {0x0a,0x92,0x92,0x84,0x11,0xb1,0x24,0x68,0x58,0x09,0x11,0x02,0xc4,0x20,0x91,0x01 }, - 16, 0xf0e0, 0, {0x2c,0x48,0x1b,0x50,0x02,0x74,0x84,0x95,0x48,0xac,0x48,0x0b,0x94,0x02,0x04,0x04 }, - 16, 0xf0f0, 0, {0xb1,0x02,0x24,0x48,0x0b,0x10,0x02,0x02,0x05,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf100, 0, {0x18,0x11,0xa4,0x00,0xb1,0x20,0x22,0x40,0x0a,0x90,0x06,0x2c,0x01,0xb9,0x00,0x2a }, - 16, 0xf110, 0, {0x40,0x09,0x90,0x02,0xa4,0x00,0x9b,0x08,0x2e,0x48,0x0b,0x12,0x1a,0x74,0x00,0x95 }, - 16, 0xf120, 0, {0x45,0x2e,0x60,0x03,0x90,0x02,0x24,0x00,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x02,0x06 }, - 16, 0xf130, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x80,0x30,0x40 }, - 16, 0xf140, 0, {0x0e,0x16,0x03,0xa4,0x00,0xb9,0x04,0x32,0x40,0x0d,0x90,0x02,0xe4,0x00,0xd9,0x40 }, - 16, 0xf150, 0, {0x2e,0x40,0x1f,0x98,0x03,0xe5,0x80,0xd9,0x00,0xae,0x60,0x07,0x10,0x0b,0x26,0x01 }, - 16, 0xf160, 0, {0xb9,0x00,0xa6,0x40,0x0f,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf170, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0xbe,0x40,0xac,0x92,0x03,0xe4,0x00,0xf9,0x00,0xb4 }, - 16, 0xf180, 0, {0x40,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x00,0x3e,0x60,0x0f,0x90,0x03,0xa4,0x80,0xf9 }, - 16, 0xf190, 0, {0x00,0x32,0x00,0x0f,0x90,0x83,0xe6,0x85,0xe1,0x00,0x32,0x44,0x0f,0x10,0x03,0xca }, - 16, 0xf1a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x00,0x32,0x00 }, - 16, 0xf1b0, 0, {0x0f,0x80,0x13,0xe0,0x94,0xe0,0x00,0x32,0x00,0x0c,0x80,0x03,0x60,0x00,0xc8,0x00 }, - 16, 0xf1c0, 0, {0x3e,0x00,0x0d,0x80,0x43,0x20,0x08,0xf8,0x00,0x32,0x00,0x0f,0x80,0x03,0xe0,0x40 }, - 16, 0xf1d0, 0, {0xf8,0x00,0x32,0x00,0x4c,0x80,0x23,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1e0, 0, {0x28,0x05,0x28,0x00,0xba,0x00,0x23,0x80,0x0b,0xa0,0x02,0xfb,0x04,0x6a,0x00,0x22 }, - 16, 0xf1f0, 0, {0x80,0x0a,0xa0,0x03,0x68,0x0a,0x8e,0x88,0x3a,0x80,0x08,0xa0,0x02,0x08,0x00,0xba }, - 16, 0xf200, 0, {0x00,0xb7,0x22,0x03,0xe4,0x02,0xfa,0x00,0x8a,0x00,0x22,0x80,0x08,0xe8,0x02,0xca }, - 16, 0xf210, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x60,0x41 }, - 16, 0xf220, 0, {0x03,0x30,0x02,0xcc,0x41,0xa3,0x00,0x04,0xc0,0x0b,0x30,0x02,0x2c,0x00,0xa3,0x80 }, - 16, 0xf230, 0, {0x2c,0xc0,0x09,0x38,0x02,0x0c,0x00,0xb3,0x00,0xa0,0xc0,0x0b,0x34,0x02,0xcc,0x80 }, - 16, 0xf240, 0, {0xa1,0x00,0x20,0xc0,0x08,0x38,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf250, 0, {0xa0,0x01,0x1c,0x40,0xb7,0x00,0x61,0x00,0x0b,0x71,0x02,0xdc,0x00,0xa3,0x00,0x25 }, - 16, 0xf260, 0, {0xc8,0x19,0x38,0x02,0x5c,0x80,0xa7,0x00,0x0f,0xe8,0x09,0x64,0x22,0x10,0x00,0xb3 }, - 16, 0xf270, 0, {0x00,0x25,0xc8,0x0b,0x60,0x02,0xf2,0x00,0x85,0x01,0x23,0xe8,0x08,0x70,0x82,0xe8 }, - 16, 0xf280, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x20,0xff,0x80,0xa1,0xa0 }, - 16, 0xf290, 0, {0x0f,0x7a,0x42,0xda,0x00,0xe7,0xe8,0x35,0xf0,0x2f,0x7b,0x62,0x1e,0x82,0xe6,0x80 }, - 16, 0xf2a0, 0, {0x1d,0xe0,0x0d,0xf8,0x0b,0x1e,0x00,0xf7,0x80,0x31,0xf0,0x0f,0x78,0x03,0xde,0x0c }, - 16, 0xf2b0, 0, {0xef,0x80,0x31,0xf8,0x2c,0x78,0x03,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2c0, 0, {0x08,0x1d,0xad,0x84,0xfb,0x68,0x3e,0x00,0x0f,0xb0,0x03,0xe8,0x00,0xfb,0x00,0xfa }, - 16, 0xf2d0, 0, {0xd8,0x0e,0xb5,0x03,0xed,0x00,0xdb,0x00,0x3a,0xc0,0x8e,0xa0,0x03,0xe0,0x00,0xfb }, - 16, 0xf2e0, 0, {0x40,0x3e,0xc0,0x0b,0xb0,0x43,0xc4,0x04,0xef,0x02,0xbf,0xc0,0x0f,0xb0,0x03,0xc2 }, - 16, 0xf2f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x42,0xc7,0x38,0x33,0x64 }, - 16, 0xf300, 0, {0x0e,0x7c,0x03,0x5e,0x00,0xdf,0xa0,0x37,0xf0,0x0d,0xf8,0x03,0xff,0x20,0xcf,0x81 }, - 16, 0xf310, 0, {0x33,0xe2,0x0c,0xd8,0x03,0xbe,0x00,0x7f,0xc0,0x33,0xe0,0x0c,0xf9,0x03,0x7e,0x00 }, - 16, 0xf320, 0, {0xfd,0x80,0x3f,0xe0,0x0f,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf330, 0, {0xa8,0x11,0x9c,0x00,0x87,0xa0,0x21,0x14,0x08,0x71,0x02,0x14,0x10,0xd7,0x20,0x35 }, - 16, 0xf340, 0, {0xc0,0x0c,0x70,0x03,0xbc,0x00,0x85,0x08,0x2b,0xc0,0x4d,0x46,0x02,0xd1,0x00,0xb7 }, - 16, 0xf350, 0, {0x00,0x21,0xc0,0x08,0x60,0x02,0x08,0x80,0xf5,0x20,0x3d,0xca,0x0f,0x54,0x03,0xea }, - 16, 0xf360, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x11,0x8f,0x01,0x20,0x84 }, - 16, 0xf370, 0, {0x1a,0xf0,0x02,0x18,0x00,0xa7,0x34,0x65,0xc0,0x09,0x71,0x02,0xdc,0x00,0x8e,0x00 }, - 16, 0xf380, 0, {0x29,0xc0,0x08,0x50,0x06,0x9c,0x00,0xbf,0x88,0x2d,0xc4,0x0a,0x60,0x26,0x58,0x24 }, - 16, 0xf390, 0, {0x97,0x00,0x6d,0xc0,0x9b,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3a0, 0, {0x20,0x14,0xcc,0x00,0x8b,0x40,0x20,0x00,0x18,0x30,0x02,0x00,0x00,0xbb,0x02,0x24 }, - 16, 0xf3b0, 0, {0xc0,0x08,0x30,0x20,0xcc,0x00,0x81,0xc0,0x28,0xc0,0x0b,0x04,0x82,0xe0,0x10,0xbb }, - 16, 0xf3c0, 0, {0xa0,0x2c,0xe0,0x0a,0x20,0x06,0x00,0x00,0xb3,0x00,0x28,0xc0,0x0a,0x10,0x02,0x88 }, - 16, 0xf3d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xcf,0x10,0x32,0x00 }, - 16, 0xf3e0, 0, {0x0e,0xf0,0x0b,0x24,0x00,0xef,0x00,0x37,0xc0,0x0d,0xf0,0x03,0xfc,0x06,0xc1,0x50 }, - 16, 0xf3f0, 0, {0x3b,0xc0,0x0c,0xb4,0x03,0xac,0x00,0xf8,0xc0,0xbe,0xc8,0x2e,0xb0,0x03,0x6e,0x01 }, - 16, 0xf400, 0, {0xfb,0x00,0x2d,0xc0,0x4b,0x90,0x02,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf410, 0, {0x80,0x00,0xec,0x04,0xfb,0x00,0x3e,0x00,0x0f,0xb0,0x03,0xad,0x00,0x9b,0x00,0x3e }, - 16, 0xf420, 0, {0xc0,0x0f,0x30,0x03,0xac,0x00,0xf8,0x00,0x2e,0xc0,0x05,0xb4,0x03,0xed,0x00,0xf8 }, - 16, 0xf430, 0, {0x40,0x32,0xc0,0x09,0x00,0x03,0xe0,0x91,0xe3,0x00,0x3e,0xc0,0x0f,0x90,0x11,0xe0 }, - 16, 0xf440, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xec,0x00,0xef,0x00,0x33,0x20 }, - 16, 0xf450, 0, {0x4f,0xf0,0x03,0xb4,0x00,0xef,0x03,0x3a,0xc0,0x0f,0xf0,0x03,0x3c,0x00,0xdc,0x00 }, - 16, 0xf460, 0, {0x31,0xc0,0x8d,0xf8,0x03,0xfe,0x04,0xcf,0x00,0x32,0xc8,0x0c,0xf0,0x0b,0x1c,0x00 }, - 16, 0xf470, 0, {0xcf,0x93,0x33,0xc0,0x8c,0x40,0x02,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf480, 0, {0x81,0x04,0x6c,0x00,0xbb,0x00,0xa2,0x04,0x0b,0x30,0x02,0x0e,0x00,0xab,0x00,0x2a }, - 16, 0xf490, 0, {0xc0,0x09,0xb0,0x03,0x6c,0x08,0xa8,0xc0,0x36,0xc0,0x08,0xbc,0x02,0xef,0x02,0xab }, - 16, 0xf4a0, 0, {0xd0,0x20,0xe0,0x08,0xb8,0x22,0x26,0x10,0x8b,0x00,0x22,0xc0,0x20,0x9c,0x02,0x20 }, - 16, 0xf4b0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xbb,0x00,0x26,0x00 }, - 16, 0xf4c0, 0, {0x0a,0xb0,0x02,0xa2,0x08,0xab,0x00,0x6a,0xc0,0x0b,0xb0,0x0a,0x0c,0x00,0x8b,0x80 }, - 16, 0xf4d0, 0, {0x22,0xc0,0x09,0xb1,0x02,0xec,0x40,0x88,0x08,0x22,0xc0,0x08,0xb8,0x02,0x26,0x00 }, - 16, 0xf4e0, 0, {0x8b,0x00,0x22,0xc0,0x08,0x98,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4f0, 0, {0x08,0x04,0x0c,0x00,0xb3,0x00,0x24,0x00,0x0b,0xb0,0x02,0x00,0x01,0x83,0x00,0x20 }, - 16, 0xf500, 0, {0xc0,0x09,0x30,0x02,0x4c,0x00,0x00,0x04,0x24,0xc0,0x08,0x30,0x06,0x4c,0x00,0x80 }, - 16, 0xf510, 0, {0x00,0x2c,0xc0,0x08,0x00,0x02,0x00,0x41,0x83,0x00,0xa2,0xc0,0x08,0x10,0x0a,0x82 }, - 16, 0xf520, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xef,0x08,0x26,0x00 }, - 16, 0xf530, 0, {0x0e,0xf0,0x02,0xa0,0x00,0xe7,0x00,0x3b,0xc0,0x0f,0xf5,0x43,0x3c,0x02,0xda,0x00 }, - 16, 0xf540, 0, {0x32,0xc0,0x0d,0xb0,0x03,0xec,0x00,0xcb,0x00,0xb2,0xc0,0x0c,0xa0,0x03,0x28,0x10 }, - 16, 0xf550, 0, {0xcb,0x00,0x32,0xc0,0x0c,0x80,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf560, 0, {0xa0,0x0d,0xfc,0x00,0xfb,0x00,0x3b,0x00,0x0f,0xf0,0x03,0xf0,0x00,0xff,0x02,0x3f }, - 16, 0xf570, 0, {0xc0,0x0d,0xf2,0x03,0xbc,0x00,0xf4,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xf7 }, - 16, 0xf580, 0, {0x00,0x33,0xc0,0x0f,0x60,0x03,0xf0,0x88,0xff,0x00,0x3f,0xc0,0x4f,0xd0,0x03,0x68 }, - 16, 0xf590, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x40,0xfc,0x31,0x3b,0x08 }, - 16, 0xf5a0, 0, {0x4f,0xf9,0x43,0xef,0x00,0xdf,0x30,0x32,0x21,0x0f,0x94,0x07,0x7d,0x80,0xef,0x38 }, - 16, 0xf5b0, 0, {0x32,0x09,0x1c,0x38,0x03,0xf2,0x21,0xfd,0x00,0x33,0xc4,0x0c,0xf0,0x02,0xfc,0x00 }, - 16, 0xf5c0, 0, {0xdf,0x00,0x33,0xc0,0x0f,0xf0,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5d0, 0, {0x80,0x10,0xec,0x88,0x8b,0x60,0x22,0xe5,0x0e,0xb2,0x22,0xec,0x80,0xaf,0x11,0x2a }, - 16, 0xf5e0, 0, {0x20,0x0b,0xb1,0x13,0xac,0x48,0x8b,0x45,0x34,0xcc,0x48,0xb0,0x02,0x6b,0x00,0xba }, - 16, 0xf5f0, 0, {0x82,0x36,0x00,0x08,0x88,0x22,0xc0,0x04,0x88,0x00,0xa2,0x08,0x8b,0x88,0x62,0x20 }, - 16, 0xf600, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xa1,0x30,0x28,0x00 }, - 16, 0xf610, 0, {0x0b,0x32,0x02,0xcc,0x00,0xa3,0x22,0x2c,0x00,0x8b,0x12,0x06,0xc8,0x80,0xa3,0x00 }, - 16, 0xf620, 0, {0x20,0x02,0xca,0x30,0x06,0xc4,0x01,0xb1,0x00,0x68,0x80,0x09,0x20,0x02,0x88,0x00 }, - 16, 0xf630, 0, {0x83,0x00,0x20,0xc2,0x0b,0x00,0x0a,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf640, 0, {0xc0,0x15,0xac,0x00,0x8b,0x61,0x62,0xc0,0x0b,0xb2,0x02,0xe8,0x00,0xab,0x02,0x2a }, - 16, 0xf650, 0, {0x61,0x1b,0x90,0x02,0xa8,0x00,0xab,0x00,0x20,0xc0,0x0a,0xb0,0x02,0x6c,0x04,0xba }, - 16, 0xf660, 0, {0x00,0x2e,0x40,0x89,0x90,0x02,0xe6,0x08,0x98,0x00,0x22,0x00,0x0b,0xb0,0x02,0xb0 }, - 16, 0xf670, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xee,0x00,0xf8,0x01,0x3a,0x04 }, - 16, 0xf680, 0, {0x0f,0xac,0x03,0xec,0x90,0xfb,0x02,0x3e,0xe0,0x0b,0x90,0x42,0x67,0x80,0xa8,0xc4 }, - 16, 0xf690, 0, {0x22,0x48,0x22,0x86,0x03,0xe1,0x40,0xb8,0x02,0x2a,0x40,0x29,0x90,0x03,0xec,0x02 }, - 16, 0xf6a0, 0, {0xc9,0x48,0x32,0x40,0x0f,0xb0,0x13,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6b0, 0, {0xe0,0x01,0xac,0x40,0xfb,0x00,0x1f,0xa2,0x0e,0xf8,0x82,0xfc,0x08,0xff,0x00,0x3f }, - 16, 0xf6c0, 0, {0xc0,0x0f,0xfa,0x43,0x96,0x44,0xd4,0x91,0x3f,0x40,0x0d,0xc0,0x03,0xfa,0x00,0xff }, - 16, 0xf6d0, 0, {0x08,0x25,0x80,0x0e,0xe0,0x03,0xd0,0x00,0xea,0x00,0x3f,0x80,0x0f,0xc0,0x03,0x78 }, - 16, 0xf6e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xe1,0x20,0x3a,0x50 }, - 16, 0xf6f0, 0, {0x0f,0x90,0x03,0x2c,0x00,0xeb,0x08,0x76,0x05,0x0e,0xb0,0x27,0xe0,0x10,0xea,0x40 }, - 16, 0xf700, 0, {0xb2,0xc0,0x0c,0xa4,0x43,0x25,0x00,0xf8,0x00,0x32,0x08,0x0f,0x80,0x43,0xe8,0x00 }, - 16, 0xf710, 0, {0xd1,0x08,0xee,0x40,0x0f,0x00,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf720, 0, {0xc8,0x05,0x2c,0x00,0x8b,0x00,0x22,0xd0,0x0b,0x90,0x82,0x2c,0x00,0x87,0x40,0x22 }, - 16, 0xf730, 0, {0x60,0x8b,0xb0,0x02,0xe0,0x00,0xd8,0x50,0x22,0xd0,0x0c,0xa0,0x03,0x6c,0x00,0xb3 }, - 16, 0xf740, 0, {0xc8,0x3e,0xd0,0x0b,0xb8,0x02,0x25,0x08,0x8a,0x20,0x2a,0x80,0x8b,0xb8,0x82,0xf2 }, - 16, 0xf750, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x64,0x00,0xa0,0xc0,0x24,0xc0 }, - 16, 0xf760, 0, {0x09,0x38,0x02,0x2c,0x00,0x83,0x03,0x20,0x00,0x10,0x30,0x22,0xcc,0x00,0x83,0x00 }, - 16, 0xf770, 0, {0x60,0x08,0x0a,0x30,0x82,0x4c,0x00,0xb1,0xc0,0x00,0xd1,0x0b,0x38,0x02,0x84,0x80 }, - 16, 0xf780, 0, {0x82,0x01,0x20,0x80,0x03,0x38,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf790, 0, {0x20,0x01,0x16,0x40,0x84,0x98,0x25,0xe0,0x0b,0x7a,0x02,0xfa,0x48,0xa3,0x20,0x61 }, - 16, 0xf7a0, 0, {0x24,0x0b,0x79,0x00,0xce,0xc0,0x93,0xa4,0x21,0xa6,0x0b,0x78,0x12,0xde,0x80,0xb6 }, - 16, 0xf7b0, 0, {0x80,0x2d,0x24,0x0b,0x4b,0x02,0x1a,0x40,0x85,0x81,0x21,0x60,0x0b,0x48,0x02,0xc8 }, - 16, 0xf7c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xe2,0xa0,0xb4,0xfe }, - 16, 0xf7d0, 0, {0x4b,0xb8,0x0b,0x0e,0x00,0xa3,0xb0,0x24,0xa8,0x0e,0x1b,0x02,0xce,0xc1,0xc3,0xc0 }, - 16, 0xf7e0, 0, {0x30,0x68,0x2e,0x3a,0x47,0x4e,0x80,0xf1,0x80,0x30,0x80,0x0f,0x22,0x83,0x80,0x00 }, - 16, 0xf7f0, 0, {0xc2,0x10,0x38,0x80,0x4f,0x00,0x07,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf800, 0, {0x40,0x0d,0xbc,0x10,0xfe,0x04,0x3b,0xc1,0x07,0xf0,0x03,0x1c,0xc8,0xdf,0x2a,0x0b }, - 16, 0xf810, 0, {0xc4,0x8f,0xd1,0x43,0xf8,0x02,0x7f,0x00,0x3f,0xc0,0x0c,0xf1,0x0f,0x3c,0x00,0xf2 }, - 16, 0xf820, 0, {0x11,0x3f,0x41,0x1f,0x52,0x03,0xbc,0x0e,0xed,0x14,0x3f,0x40,0x0f,0xf8,0x03,0xd0 }, - 16, 0xf830, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xe9,0x00,0x32,0x80 }, - 16, 0xf840, 0, {0x0e,0xbe,0x4b,0x6f,0x00,0xcb,0x82,0x7a,0xc0,0x2c,0xb0,0x03,0x2c,0x00,0xc9,0x00 }, - 16, 0xf850, 0, {0x32,0x00,0x2c,0x10,0x03,0x2c,0x08,0xc0,0x00,0x26,0x40,0x6c,0x90,0x13,0x24,0x12 }, - 16, 0xf860, 0, {0xc8,0x01,0x3e,0x00,0x0f,0xb8,0x0b,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf870, 0, {0x48,0x11,0x94,0x00,0x8d,0x00,0x21,0x80,0x0b,0x70,0x82,0x3c,0x20,0x83,0x32,0x29 }, - 16, 0xf880, 0, {0xc0,0x08,0xf0,0x20,0x14,0x00,0x80,0x00,0x23,0x00,0x08,0x50,0x06,0x9c,0x04,0xd7 }, - 16, 0xf890, 0, {0x02,0x28,0x80,0x08,0x60,0x02,0x08,0x10,0x87,0x00,0x2d,0xc0,0x0b,0x40,0x02,0x12 }, - 16, 0xf8a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xa7,0x80,0x21,0xe0 }, - 16, 0xf8b0, 0, {0x0b,0x5c,0x12,0x1e,0x04,0x87,0x82,0x0d,0xa0,0x09,0x78,0x16,0x02,0x00,0xb4,0x80 }, - 16, 0xf8c0, 0, {0x25,0xe0,0x0b,0x78,0x02,0x9e,0x00,0x84,0x80,0x21,0x22,0x08,0x08,0x02,0x12,0x01 }, - 16, 0xf8d0, 0, {0x84,0xc0,0x2d,0x20,0x0b,0x08,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8e0, 0, {0x48,0x14,0xcc,0x00,0x83,0x42,0xa0,0xd8,0x0b,0x34,0x82,0x0c,0x00,0xa3,0x02,0x20 }, - 16, 0xf8f0, 0, {0xe0,0x08,0xb0,0x02,0x0c,0x88,0xb3,0x21,0x24,0xd8,0x0b,0x3e,0x02,0x8c,0x00,0x93 }, - 16, 0xf900, 0, {0x08,0x28,0xc0,0x08,0x38,0x02,0x2c,0x05,0x8b,0x01,0x2c,0xe0,0x0b,0x30,0x02,0x12 }, - 16, 0xf910, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xee,0x00,0x33,0x90 }, - 16, 0xf920, 0, {0x0f,0xa0,0x0b,0x68,0x00,0xca,0x01,0x7f,0xa8,0x0c,0xaa,0x03,0x3a,0x12,0xfe,0xe2 }, - 16, 0xf930, 0, {0x37,0xb0,0x0f,0xee,0x02,0x18,0x00,0xca,0x40,0x36,0xa0,0x08,0xa0,0x8b,0x28,0x00 }, - 16, 0xf940, 0, {0xca,0x81,0x2e,0xa0,0x0f,0xe0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf950, 0, {0x48,0x00,0xe0,0x00,0xf8,0x08,0x3e,0x00,0x0f,0x80,0x03,0xa2,0x02,0xd8,0x40,0x3e }, - 16, 0xf960, 0, {0x08,0x0f,0x80,0x13,0xe0,0x40,0x48,0x40,0xb8,0x04,0x08,0x84,0x03,0x61,0x00,0xfc }, - 16, 0xf970, 0, {0x00,0x3f,0x00,0x4f,0xc0,0x03,0xf1,0x00,0xfc,0x00,0x3f,0x04,0x0f,0xc0,0x03,0xd2 }, - 16, 0xf980, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x00,0xf9,0x00,0x30,0x50 }, - 16, 0xf990, 0, {0x4c,0xb9,0x03,0x6c,0x18,0xf9,0x00,0x36,0x40,0x0e,0x9c,0x23,0xa4,0x02,0x41,0x00 }, - 16, 0xf9a0, 0, {0xb2,0x44,0x0e,0x9a,0x03,0xa6,0x80,0xc9,0x00,0x3a,0x60,0x0a,0x90,0x03,0xa4,0x80 }, - 16, 0xf9b0, 0, {0xc9,0x00,0x34,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9c0, 0, {0x80,0x04,0x64,0x00,0x89,0x40,0x22,0x78,0x08,0x94,0x02,0xe4,0x10,0xb9,0x00,0x3c }, - 16, 0xf9d0, 0, {0x62,0x18,0x94,0x82,0xa4,0x00,0x89,0xc8,0x22,0x70,0x48,0x1e,0x01,0x67,0x80,0xd1 }, - 16, 0xf9e0, 0, {0x00,0xbc,0x42,0x08,0x10,0x02,0x25,0x20,0x89,0x02,0x22,0x40,0x08,0x90,0x02,0xe0 }, - 16, 0xf9f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb1,0x28,0x22,0x40 }, - 16, 0xfa00, 0, {0x08,0xb0,0x82,0x64,0x04,0x39,0x41,0x2e,0x48,0x0a,0x90,0x02,0x04,0x18,0xa9,0x20 }, - 16, 0xfa10, 0, {0x22,0x42,0x4a,0x90,0x02,0x2c,0x04,0x89,0x04,0x2b,0x48,0x02,0xd0,0x02,0xb4,0x0a }, - 16, 0xfa20, 0, {0x8d,0x80,0x23,0xc0,0x48,0xd0,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa30, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0xa0,0x48,0x28,0x10,0x02,0xc4,0x00,0xb1,0x24,0x2a }, - 16, 0xfa40, 0, {0x40,0x08,0x12,0x42,0x85,0x80,0xa1,0x20,0xa0,0x48,0x08,0x90,0x02,0x44,0x00,0x95 }, - 16, 0xfa50, 0, {0x2c,0x2d,0x5a,0x0a,0x72,0x82,0x14,0xa0,0x85,0xa8,0x21,0x4a,0x08,0x52,0x82,0xc2 }, - 16, 0xfa60, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x41,0x40,0xf8,0x50,0x32,0x00 }, - 16, 0xfa70, 0, {0x8c,0x05,0x03,0x61,0x40,0xf8,0x51,0x2e,0x00,0x0a,0x85,0x02,0x20,0x00,0xe8,0x50 }, - 16, 0xfa80, 0, {0x32,0x14,0x06,0x85,0x17,0xa0,0x00,0xc8,0x20,0x3a,0x08,0x0e,0x82,0x03,0xa0,0x80 }, - 16, 0xfa90, 0, {0xc8,0x20,0x32,0x08,0x2c,0xc2,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfaa0, 0, {0x98,0x19,0xf4,0x40,0xff,0x10,0x3f,0x44,0x0b,0xb0,0x03,0xe4,0x00,0xf9,0x10,0x3d }, - 16, 0xfab0, 0, {0x40,0x0f,0xd1,0x03,0xf4,0x58,0x9d,0x10,0x3f,0x44,0x4f,0xd0,0x03,0xd5,0x00,0xf9 }, - 16, 0xfac0, 0, {0x00,0x3e,0x40,0x8d,0x90,0x03,0xe4,0xb8,0xf9,0x28,0xba,0x6a,0x0f,0x90,0x03,0xe6 }, - 16, 0xfad0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xe7,0x00,0xfd,0x88,0x3e,0x60 }, - 16, 0xfae0, 0, {0x8f,0xd0,0x03,0x24,0x01,0xdd,0x80,0x73,0x40,0x0f,0xd8,0x03,0xa6,0x04,0xcd,0xa2 }, - 16, 0xfaf0, 0, {0x33,0x78,0x1c,0xd0,0x03,0x34,0x01,0xf5,0x88,0x3b,0x68,0x0c,0xda,0x47,0x37,0x80 }, - 16, 0xfb00, 0, {0xcd,0x88,0x32,0x62,0x0c,0xda,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb10, 0, {0x38,0x10,0xe3,0x80,0xb8,0x80,0x2e,0x14,0x0b,0x0a,0x82,0x22,0x80,0xb8,0xf8,0xa2 }, - 16, 0xfb20, 0, {0x00,0x0b,0x8f,0xa3,0x83,0xe0,0x88,0xeb,0x22,0xa9,0x08,0x88,0x12,0xa0,0x05,0xb8 }, - 16, 0xfb30, 0, {0x00,0x2a,0xaa,0x88,0x80,0x13,0x62,0x82,0x88,0x80,0x22,0x28,0x88,0xa4,0x02,0x0e }, - 16, 0xfb40, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x0a,0x2c,0x41 }, - 16, 0xfb50, 0, {0x0b,0x10,0x06,0x04,0x20,0xa1,0x00,0x00,0x40,0x8b,0x10,0x46,0xc4,0x01,0x91,0x11 }, - 16, 0xfb60, 0, {0x24,0x58,0x68,0x90,0xc2,0x04,0x00,0xb1,0x00,0xa8,0x50,0x09,0x14,0x0a,0x05,0x95 }, - 16, 0xfb70, 0, {0xa1,0x08,0xa0,0x42,0x28,0x11,0x0a,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb80, 0, {0x18,0x15,0xa4,0x18,0xb9,0x20,0x2e,0x50,0x0b,0x90,0x06,0x24,0x09,0xb9,0x00,0x22 }, - 16, 0xfb90, 0, {0x40,0x8b,0x91,0x02,0x84,0x00,0x99,0x64,0x24,0x40,0x58,0x90,0x02,0xa4,0x20,0xbb }, - 16, 0xfba0, 0, {0x00,0x2a,0x40,0x09,0xb0,0x02,0x05,0x01,0xa9,0x00,0x22,0x40,0x88,0x92,0x02,0x06 }, - 16, 0xfbb0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x00,0xf9,0x40,0x3e,0x40 }, - 16, 0xfbc0, 0, {0x4f,0x98,0x0b,0x24,0x80,0xd9,0x00,0x22,0x72,0x0b,0x98,0x03,0xe4,0x84,0xd9,0x00 }, - 16, 0xfbd0, 0, {0xb6,0x70,0x08,0x99,0x02,0x24,0x00,0xb9,0x00,0x2a,0x40,0x0d,0x94,0xc2,0x25,0x00 }, - 16, 0xfbe0, 0, {0xa9,0x00,0x22,0x40,0x0c,0x94,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbf0, 0, {0x28,0x01,0xa6,0x80,0xf9,0x08,0x3e,0xc0,0x0f,0x91,0x43,0xe4,0x00,0xf9,0x00,0x3e }, - 16, 0xfc00, 0, {0x50,0x0f,0x98,0x03,0xa5,0x00,0xe9,0x00,0x3a,0x64,0x0f,0x90,0x03,0xe4,0x00,0xf9 }, - 16, 0xfc10, 0, {0x00,0x3c,0x40,0x6e,0x90,0x03,0xe4,0x20,0xd9,0x00,0x3c,0x40,0x0f,0x90,0x82,0xca }, - 16, 0xfc20, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xe8,0x00,0x3e,0x00 }, - 16, 0xfc30, 0, {0x4f,0x84,0x0b,0x20,0x00,0xf8,0x00,0x36,0x01,0x0e,0x80,0x03,0xe0,0x00,0xc8,0x40 }, - 16, 0xfc40, 0, {0x32,0x10,0x2d,0x80,0x03,0xe0,0x54,0xc8,0x00,0x36,0x10,0x0f,0x04,0x83,0xe0,0x50 }, - 16, 0xfc50, 0, {0xd8,0x04,0x12,0x00,0x0c,0x00,0x0b,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc60, 0, {0x28,0x05,0x28,0x00,0x8e,0x42,0x2e,0xa2,0x8b,0xea,0x02,0x28,0x08,0xbe,0x89,0x37 }, - 16, 0xfc70, 0, {0x84,0x48,0xe0,0x12,0x28,0x02,0x8e,0xc0,0x23,0xb0,0x4d,0x60,0x62,0xf8,0x00,0x86 }, - 16, 0xfc80, 0, {0x00,0x23,0x80,0x0b,0xe0,0x02,0xf8,0x00,0x0e,0x00,0x22,0x80,0x08,0xe4,0x02,0x0a }, - 16, 0xfc90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xa3,0x00,0x2c,0x80 }, - 16, 0xfca0, 0, {0x1b,0xb0,0x9a,0x4c,0x10,0x9b,0x80,0x24,0xc0,0x0a,0x30,0x00,0x0c,0x04,0x9b,0x20 }, - 16, 0xfcb0, 0, {0x20,0xd6,0x08,0x30,0x02,0x8e,0x08,0xa3,0x04,0x24,0xc0,0x19,0x34,0x02,0xc7,0x07 }, - 16, 0xfcc0, 0, {0xaa,0xa4,0xa0,0xc0,0x48,0x34,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfcd0, 0, {0xa0,0x01,0x0e,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x40,0x02,0x5c,0x40,0xb3,0x14,0x25 }, - 16, 0xfce0, 0, {0xe0,0x08,0x7a,0x02,0x9e,0xc0,0x92,0x40,0xa0,0x00,0x49,0x60,0x02,0xce,0x02,0x8e }, - 16, 0xfcf0, 0, {0x01,0x21,0xc0,0x8b,0x54,0x02,0xc4,0x08,0x86,0x40,0x21,0xc8,0x88,0x10,0x02,0x28 }, - 16, 0xfd00, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0xc0,0xe4,0x80,0x3d,0xe2 }, - 16, 0xfd10, 0, {0x0f,0x58,0x03,0x5e,0x90,0xb6,0xa2,0x35,0xe0,0x0e,0x7c,0x23,0x1c,0x00,0xd6,0x80 }, - 16, 0xfd20, 0, {0x31,0xe0,0x84,0x78,0x03,0xde,0x00,0xc7,0x80,0x35,0xe0,0x0f,0x68,0x03,0xde,0x00 }, - 16, 0xfd30, 0, {0xe3,0x80,0x33,0xe8,0x2c,0x78,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd40, 0, {0x08,0x1d,0xac,0x90,0xfa,0x00,0x7e,0x40,0x0f,0x90,0x03,0xac,0x01,0xfb,0x00,0x3c }, - 16, 0xfd50, 0, {0x41,0x0f,0x30,0x0b,0x2d,0x04,0xeb,0x01,0x3e,0xc0,0x0e,0xb0,0x03,0xec,0x00,0xfa }, - 16, 0xfd60, 0, {0x00,0x3f,0xc0,0x0f,0x80,0x03,0xec,0x00,0xe9,0x60,0x3e,0xe4,0x0f,0x90,0x03,0xc2 }, - 16, 0xfd70, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x20,0xff,0x90,0x3e,0x20 }, - 16, 0xfd80, 0, {0x0c,0xa9,0x07,0x2e,0x44,0xc9,0x91,0x30,0xa0,0x0c,0xb8,0x63,0x2f,0x44,0xcb,0xa1 }, - 16, 0xfd90, 0, {0x36,0x20,0x8c,0xf8,0x03,0x36,0x00,0xcf,0x82,0x33,0xe0,0x0c,0xf8,0x23,0x2e,0x00 }, - 16, 0xfda0, 0, {0xce,0xc0,0x3b,0xe0,0x0c,0x68,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfdb0, 0, {0xa8,0x11,0x9c,0x84,0xb3,0x54,0x2c,0xf4,0x28,0xba,0x8a,0x3e,0x40,0x81,0xa0,0x29 }, - 16, 0xfdc0, 0, {0xb0,0x0f,0x78,0x42,0xae,0x00,0x83,0x90,0x33,0xe8,0x0d,0xe1,0x00,0x85,0x40,0x82 }, - 16, 0xfdd0, 0, {0x24,0x23,0xc6,0x0d,0x71,0x03,0x5e,0xe0,0x87,0x00,0x2b,0xc1,0x0d,0x44,0x02,0x2a }, - 16, 0xfde0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x08,0x35,0x14,0x6d,0xc0 }, - 16, 0xfdf0, 0, {0x88,0x72,0x32,0x5c,0x80,0x84,0x30,0x2b,0x88,0x0a,0x70,0x42,0x5c,0xa8,0x91,0x08 }, - 16, 0xfe00, 0, {0x25,0xc8,0x09,0x70,0x02,0x4c,0x22,0x83,0x0a,0x61,0xc0,0x09,0x20,0x02,0x04,0x00 }, - 16, 0xfe10, 0, {0x87,0x00,0x21,0xc0,0x08,0x60,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfe20, 0, {0x20,0x14,0xcc,0x10,0xb3,0x85,0x6c,0xdc,0x08,0x34,0x02,0x4d,0x21,0x81,0x00,0x28 }, - 16, 0xfe30, 0, {0x02,0x4a,0x31,0x12,0xef,0x0c,0x91,0xc2,0x20,0xf0,0x08,0x30,0x42,0x8e,0x00,0x82 }, - 16, 0xfe40, 0, {0x40,0x20,0xc8,0x19,0x28,0x02,0x22,0x81,0x83,0xc0,0x28,0xd4,0x09,0x00,0x0a,0x08 }, - 16, 0xfe50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xfb,0xa0,0x3e,0xc0 }, - 16, 0xfe60, 0, {0x8c,0x04,0x12,0x7d,0x10,0xcf,0x02,0x3a,0x50,0x08,0xc0,0x42,0x7d,0x52,0x58,0x01 }, - 16, 0xfe70, 0, {0x36,0x22,0x69,0xd0,0x13,0x2a,0x00,0x88,0x82,0x32,0xf0,0x09,0xb8,0x82,0x2f,0x00 }, - 16, 0xfe80, 0, {0xc9,0xc8,0x23,0xc0,0x0c,0x8a,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfe90, 0, {0x80,0x00,0xec,0x00,0xb9,0x40,0x3c,0x50,0x4f,0x80,0x23,0xac,0x12,0xfb,0x00,0x2a }, - 16, 0xfea0, 0, {0xc0,0x6d,0x80,0x13,0xac,0x00,0xe8,0x04,0xba,0x10,0x0f,0x80,0x03,0xe8,0x00,0xf3 }, - 16, 0xfeb0, 0, {0x08,0x3c,0x80,0x0f,0x90,0x83,0xec,0x04,0xf9,0x60,0x2c,0xc2,0x0f,0x80,0x83,0xe0 }, - 16, 0xfec0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xec,0x2c,0x3f,0xf0 }, - 16, 0xfed0, 0, {0x8c,0xfa,0x8b,0xbc,0x00,0xfe,0x00,0x3f,0x00,0x0f,0x79,0x03,0x3c,0x00,0xce,0x08 }, - 16, 0xfee0, 0, {0x0b,0xc2,0x0c,0xf0,0x03,0xbc,0x00,0xfc,0x00,0x33,0x40,0x8c,0x7a,0x03,0x3a,0x00 }, - 16, 0xfef0, 0, {0xc5,0x00,0x33,0xc0,0x4c,0xc8,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xff00, 0, {0x81,0x04,0x6c,0x00,0x88,0xc0,0x2e,0xe0,0x08,0x94,0x02,0x2c,0x00,0xbb,0x80,0x66 }, - 16, 0xff10, 0, {0x30,0x16,0xb0,0x02,0x2c,0x00,0xda,0x4c,0x22,0xf0,0x08,0xf0,0x03,0xec,0x00,0xeb }, - 16, 0xff20, 0, {0xc0,0x22,0x68,0x00,0x94,0x02,0x2c,0x02,0xa9,0x80,0x22,0xc0,0x08,0x0c,0x02,0xa0 }, - 16, 0xff30, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xab,0x04,0x2e,0xc0 }, - 16, 0xff40, 0, {0x08,0xa4,0x06,0x2c,0x04,0xab,0x10,0x2e,0x60,0x43,0x80,0x82,0x6c,0x01,0x81,0x80 }, - 16, 0xff50, 0, {0x28,0x0a,0x08,0x91,0x00,0xe0,0x00,0xb8,0x80,0x02,0xe0,0x08,0x80,0x02,0x2d,0x80 }, - 16, 0xff60, 0, {0x88,0xc0,0x22,0xc0,0x08,0x82,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xff70, 0, {0x08,0x04,0x0c,0x00,0x80,0x44,0x2c,0xc8,0x28,0xa0,0x22,0x0c,0x04,0xb3,0x26,0x2c }, - 16, 0xff80, 0, {0xc8,0x88,0x01,0x06,0x0c,0xe0,0x91,0x20,0x20,0x0c,0x38,0x04,0x22,0xc0,0x48,0xa3 }, - 16, 0xff90, 0, {0x42,0xa0,0x81,0x08,0x00,0x02,0x0c,0x80,0x81,0x00,0x20,0xc0,0x28,0x00,0x02,0x82 }, - 16, 0xffa0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xa9,0x40,0x3e,0x44 }, - 16, 0xffb0, 0, {0x08,0xb1,0x03,0x2c,0x40,0xea,0x49,0x2e,0x0d,0x0b,0xb6,0x13,0x7d,0x80,0xc9,0x40 }, - 16, 0xffc0, 0, {0xba,0xd0,0x0c,0xb4,0x03,0xac,0x00,0xf8,0x00,0x32,0x40,0x0c,0x80,0x0b,0x20,0x00 }, - 16, 0xffd0, 0, {0xc5,0x00,0xb2,0xc0,0x0c,0x80,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xffe0, 0, {0xa0,0x1d,0xfc,0x04,0xfc,0x00,0x3d,0xc5,0x0b,0xf1,0x00,0xfc,0xd0,0x77,0x29,0x37 }, - 16, 0xfff0, 0, {0x0c,0x8e,0x74,0x03,0xfc,0x08,0xfd,0x69,0x3f,0xd8,0x0f,0xf0,0x03,0xbc,0x00,0xef }, - 16, 0x8010, 0, {0x00,0x3f,0x40,0x07,0xc0,0x03,0xf0,0x40,0xfd,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xe8 }, - 16, 0x8020, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x0d,0xfc,0xc0,0xdc,0x80,0x3f,0xc8 }, - 16, 0x8030, 0, {0x0f,0x48,0x03,0x7c,0x20,0xff,0x68,0x37,0xe0,0x0e,0xf1,0x03,0x9c,0x00,0xbf,0x20 }, - 16, 0x8040, 0, {0x37,0xe0,0x0c,0xc8,0x13,0x3c,0x40,0xed,0x60,0xbb,0xe4,0x2c,0x43,0x4b,0x70,0xa0 }, - 16, 0x8050, 0, {0xcc,0x2c,0x3f,0x09,0x0f,0xd8,0x43,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8060, 0, {0x80,0x00,0xed,0xc0,0xb8,0x80,0x2f,0xf4,0x0f,0x98,0x02,0x3f,0x00,0xbf,0x42,0x22 }, - 16, 0x8070, 0, {0xca,0x08,0xf4,0x02,0x3e,0x00,0xbf,0xd0,0x22,0x60,0x28,0x88,0x0a,0x3d,0x80,0x8d }, - 16, 0x8080, 0, {0x40,0x22,0xc8,0x08,0x81,0x02,0x21,0x80,0xdb,0xc0,0x2e,0xa5,0x0b,0x98,0x42,0x20 }, - 16, 0x8090, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x10,0xb0,0x00,0x2c,0xc0 }, - 16, 0x80a0, 0, {0x0b,0x20,0x02,0xcc,0x00,0xb3,0x20,0x26,0xc0,0x8a,0x36,0x12,0x8c,0x41,0xb3,0x00 }, - 16, 0x80b0, 0, {0x2e,0x40,0x08,0x00,0x02,0x0d,0x81,0xa1,0x30,0x22,0xc8,0x89,0xa2,0x42,0x08,0x20 }, - 16, 0x80c0, 0, {0xb0,0x00,0x2c,0x40,0x0b,0x90,0x26,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80d0, 0, {0xc0,0x15,0xac,0x00,0xb8,0x50,0x2e,0xc0,0x0a,0x90,0x02,0xac,0x00,0xbb,0x00,0x22 }, - 16, 0x80e0, 0, {0xc0,0x08,0xb0,0x62,0x2c,0x10,0xbb,0x04,0x2a,0xf0,0x4a,0x88,0x02,0x0c,0x00,0x81 }, - 16, 0x80f0, 0, {0x00,0x22,0xc0,0x09,0xb8,0x80,0x26,0x00,0xb8,0x80,0x2e,0x21,0x0b,0x90,0x02,0x30 }, - 16, 0x8100, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x15,0xec,0x00,0xd8,0xc0,0x3e,0xc0 }, - 16, 0x8110, 0, {0x0b,0x80,0x03,0xec,0x00,0xfb,0x00,0x36,0x80,0x0e,0xb0,0x03,0xac,0x00,0xfb,0x00 }, - 16, 0x8120, 0, {0x3c,0xe0,0x0c,0x0c,0x03,0x2c,0x00,0xe9,0x00,0x10,0xc0,0x0c,0x8c,0x03,0x06,0x00 }, - 16, 0x8130, 0, {0xf8,0xcd,0x3e,0x22,0x0f,0x18,0x03,0x40,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8140, 0, {0xe0,0x01,0xbc,0x00,0xff,0x00,0x3e,0xc0,0x0f,0xf0,0x03,0x7c,0x00,0xf7,0x02,0x3f }, - 16, 0x8150, 0, {0xe4,0x0f,0x70,0x03,0x7c,0x04,0xb7,0x00,0x37,0x40,0x0d,0xc0,0x03,0xfc,0x00,0xfd }, - 16, 0x8160, 0, {0x00,0x37,0xd0,0x0e,0xc0,0x43,0xf4,0x00,0xdf,0x00,0x3f,0x80,0x8f,0xda,0x03,0xf8 }, - 16, 0x8170, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xf8,0x10,0x3a,0xc0 }, - 16, 0x8180, 0, {0x6d,0xa6,0x13,0xec,0x00,0xcb,0x00,0x3a,0xd0,0x0f,0xb0,0x03,0x2c,0x10,0xdb,0x10 }, - 16, 0x8190, 0, {0x36,0xd8,0x0d,0x84,0x03,0xec,0x06,0xc9,0x08,0x3a,0xc0,0x0e,0x86,0x03,0xa8,0x60 }, - 16, 0x81a0, 0, {0xf8,0x20,0x3a,0x40,0x0c,0x90,0x03,0x54,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81b0, 0, {0x98,0x05,0x3c,0x00,0xbb,0x40,0x23,0xd0,0x08,0x30,0x02,0x3e,0x10,0xaf,0x00,0x20 }, - 16, 0x81c0, 0, {0xc0,0x0b,0xf0,0x02,0x3c,0x00,0x8f,0x50,0x2e,0xc8,0x06,0x8a,0x02,0xfc,0x00,0x8d }, - 16, 0x81d0, 0, {0x24,0x82,0xd6,0x08,0x32,0x02,0x2d,0x08,0x3a,0x40,0x22,0x80,0x0d,0x90,0x03,0x62 }, - 16, 0x81e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x4c,0x00,0xb0,0x20,0x28,0xc2 }, - 16, 0x81f0, 0, {0x08,0x04,0x02,0x8c,0x00,0x13,0x02,0x28,0xc0,0x0b,0x30,0x02,0x0c,0x30,0x93,0x80 }, - 16, 0x8200, 0, {0x24,0xd0,0x09,0x20,0x02,0xcc,0x00,0x91,0x40,0x08,0xc0,0x2a,0x14,0x02,0x81,0x00 }, - 16, 0x8210, 0, {0x90,0x00,0x68,0x00,0x08,0x18,0x02,0x3a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8220, 0, {0x70,0x01,0x1e,0x00,0xb4,0xa0,0x21,0xe0,0x08,0xc8,0x12,0x9e,0x00,0xb3,0x82,0x21 }, - 16, 0x8230, 0, {0xe0,0x0b,0x7a,0x0a,0x1e,0x00,0x97,0x80,0x2d,0xe1,0x0a,0x48,0x02,0xce,0x40,0x95 }, - 16, 0x8240, 0, {0x90,0x29,0xe4,0x08,0x58,0x02,0x9a,0x00,0xb7,0x88,0x21,0xe0,0x09,0x58,0x02,0x5c }, - 16, 0x8250, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x00,0x0c,0x00,0xf0,0x80,0x38,0xc4 }, - 16, 0x8260, 0, {0x0c,0x25,0x03,0x8c,0x20,0x93,0x00,0x38,0xc4,0x0f,0xb0,0x03,0x0c,0x80,0xd3,0x00 }, - 16, 0x8270, 0, {0x34,0xc0,0x0d,0x04,0x13,0xcc,0x08,0x99,0x00,0x2a,0xc0,0x0e,0x21,0x03,0x88,0x04 }, - 16, 0x8280, 0, {0xf3,0x00,0x38,0xc0,0x0c,0x11,0x83,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8290, 0, {0x42,0x15,0xbc,0x00,0xf4,0x00,0x3f,0xc3,0x0e,0xc0,0x03,0x1c,0x00,0xaf,0x4a,0x7f }, - 16, 0x82a0, 0, {0xc4,0x0f,0xb2,0x03,0xfd,0x01,0xef,0x10,0x3f,0x84,0x0f,0xc0,0x03,0xfc,0x00,0xe9 }, - 16, 0x82b0, 0, {0x00,0x37,0xc2,0x0e,0xf1,0x47,0x7c,0x00,0xf7,0x00,0x3d,0xc0,0x0f,0x50,0x03,0xd0 }, - 16, 0x82c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x15,0xec,0x08,0xf8,0x00,0x3e,0xca }, - 16, 0x82d0, 0, {0x0f,0x90,0x03,0xef,0x21,0xfb,0x80,0x7a,0x40,0x8f,0xb2,0xa1,0x2f,0x00,0xcb,0x60 }, - 16, 0x82e0, 0, {0x3e,0xc0,0x0f,0xb0,0x03,0xed,0xa0,0xe9,0x30,0x32,0xc0,0x2d,0xb0,0x03,0xe4,0x00 }, - 16, 0x82f0, 0, {0xf8,0x00,0x3e,0x00,0x0f,0xb0,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8300, 0, {0xc8,0x91,0x9d,0x00,0xb4,0x01,0x2d,0xc8,0x0b,0x70,0x02,0xcc,0x80,0x8f,0x20,0x21 }, - 16, 0x8310, 0, {0xc0,0x8b,0x76,0x03,0x5d,0x00,0x87,0x0a,0x2d,0xc0,0x0b,0x40,0x22,0xfd,0x00,0x8d }, - 16, 0x8320, 0, {0x10,0x23,0xc8,0x08,0x50,0x12,0xd4,0x00,0xb7,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xf2 }, - 16, 0x8330, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x9e,0x00,0xb4,0x80,0x2d,0xe0 }, - 16, 0x8340, 0, {0x0b,0x7c,0x02,0xde,0x40,0xa7,0x82,0x2d,0xe0,0x0b,0x3a,0x02,0x8e,0x00,0x87,0x90 }, - 16, 0x8350, 0, {0x2d,0xe0,0x0b,0x58,0x02,0x5e,0x00,0xa5,0xa2,0x65,0xe0,0x08,0x68,0x82,0xda,0x00 }, - 16, 0x8360, 0, {0x95,0x80,0x2d,0x60,0x0b,0x78,0x02,0xe0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8370, 0, {0x08,0x84,0xcc,0x00,0xb0,0x09,0x2c,0xc0,0x0b,0x38,0x02,0xcc,0x00,0x83,0x00,0x2e }, - 16, 0x8380, 0, {0xc0,0x0b,0x30,0x42,0x4c,0x00,0x83,0x00,0x2c,0xa0,0x0b,0x04,0x02,0xcc,0x00,0x81 }, - 16, 0x8390, 0, {0x00,0xa0,0xc0,0x08,0xb0,0x06,0xcf,0x80,0xb3,0x10,0x2c,0xc4,0x0b,0x31,0x02,0xc3 }, - 16, 0x83a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xfe,0x80,0x3e,0x80 }, - 16, 0x83b0, 0, {0x0f,0xe8,0x13,0xe8,0x00,0xea,0x00,0x3f,0xb0,0x0f,0xa0,0x03,0xa8,0x02,0xc2,0x00 }, - 16, 0x83c0, 0, {0x2f,0x88,0x0f,0xe0,0x03,0xe8,0x00,0xea,0x00,0x36,0x00,0x0c,0xe0,0x03,0xf9,0x20 }, - 16, 0x83d0, 0, {0xde,0x80,0x3f,0xa0,0x4f,0xa8,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x83e0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x10,0x3c,0x10,0x0f,0x80,0x83,0xe1,0x00,0xe8,0x00,0x22 }, - 16, 0x83f0, 0, {0x06,0x0f,0x00,0x13,0xe0,0x01,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x83,0xe0,0x00,0xf8 }, - 16, 0x8400, 0, {0x00,0x3e,0x00,0x0f,0x84,0x23,0xe0,0x00,0xf8,0x00,0x3e,0x10,0x0f,0x80,0x03,0xd2 }, - 16, 0x8410, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe4,0x00,0xf9,0x10,0x3e,0x44 }, - 16, 0x8420, 0, {0x0d,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0c,0x90,0x12,0x24,0x00,0xf9,0x10 }, - 16, 0x8430, 0, {0x32,0x40,0x8f,0x90,0x03,0xc4,0x00,0xc9,0x00,0x32,0x10,0x0c,0x9c,0x01,0x24,0x00 }, - 16, 0x8440, 0, {0xf9,0x10,0x3e,0x70,0x0f,0x90,0x02,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8450, 0, {0x80,0x14,0x64,0x00,0xb9,0xc0,0x2e,0x48,0x08,0x91,0x02,0xe4,0x00,0xb9,0x00,0x2e }, - 16, 0x8460, 0, {0x40,0x0d,0x90,0x03,0x67,0x00,0xb9,0x80,0x2a,0x60,0x0b,0x99,0x02,0xe4,0x00,0x81 }, - 16, 0x8470, 0, {0x00,0x22,0x40,0x2c,0x90,0x12,0x25,0x20,0xb9,0x48,0x2e,0x52,0x0b,0x94,0x02,0xe0 }, - 16, 0x8480, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x2e,0x40 }, - 16, 0x8490, 0, {0x68,0x90,0x46,0xe4,0x00,0xb9,0x00,0x2e,0xc0,0x08,0x90,0x02,0xa4,0x60,0xb9,0x00 }, - 16, 0x84a0, 0, {0x22,0x48,0x0b,0x90,0x06,0xe4,0x02,0x89,0x00,0xa0,0x40,0x08,0x90,0x02,0xa6,0x10 }, - 16, 0x84b0, 0, {0xb9,0x00,0x0e,0x40,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x84c0, 0, {0x08,0x04,0x04,0x80,0xb1,0x00,0x2c,0x48,0x08,0x10,0x02,0xc4,0x84,0xb1,0x20,0x2c }, - 16, 0x84d0, 0, {0x40,0x09,0x12,0x02,0xc4,0x80,0xb1,0x20,0x28,0x40,0x0b,0x10,0x02,0xc4,0x80,0x89 }, - 16, 0x84e0, 0, {0x20,0x20,0x40,0x4b,0x12,0x0a,0x84,0x84,0xb1,0x20,0x2c,0x48,0x8b,0x10,0x02,0xc2 }, - 16, 0x84f0, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xba,0x00,0x2e,0x00 }, - 16, 0x8500, 0, {0x0c,0x80,0x03,0xe8,0x08,0xf8,0x50,0x3e,0x14,0x0c,0x85,0x03,0x20,0x00,0xb8,0x00 }, - 16, 0x8510, 0, {0x32,0x00,0x0f,0xa0,0x03,0xe1,0x40,0xc8,0x50,0x32,0x14,0x0c,0xa5,0x03,0xa1,0x40 }, - 16, 0x8520, 0, {0xf8,0x00,0x3e,0x00,0x0f,0xa0,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8530, 0, {0x88,0x0d,0xe4,0x40,0xfd,0x00,0x3e,0x44,0x0f,0xd0,0x03,0xe4,0x40,0xb9,0x11,0x3f }, - 16, 0x8540, 0, {0x40,0x0f,0x91,0x03,0x64,0x44,0xf9,0x10,0x3f,0x40,0x0f,0xd0,0x03,0xe4,0x40,0xfd }, - 16, 0x8550, 0, {0x10,0x3f,0x10,0x8c,0xd1,0x03,0x74,0x40,0xff,0x10,0x3f,0x44,0x0f,0xd0,0x03,0xe6 }, - 16, 0x8560, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x66,0x20,0xed,0x00,0x33,0x69 }, - 16, 0x8570, 0, {0x4d,0x50,0x43,0x56,0x00,0xf9,0xa0,0x34,0x40,0x0f,0x9a,0x0b,0x34,0x00,0xdd,0x80 }, - 16, 0x8580, 0, {0x3b,0x40,0x0b,0x50,0x03,0xe4,0x00,0xf9,0x00,0x32,0xe0,0x0e,0xd0,0x03,0xf4,0x00 }, - 16, 0x8590, 0, {0xfd,0x00,0x3f,0x40,0x0c,0xd0,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x85a0, 0, {0x78,0x10,0xe2,0x80,0x88,0x04,0x22,0x10,0x0b,0x80,0x02,0x20,0x09,0xb8,0xf0,0x22 }, - 16, 0x85b0, 0, {0x00,0x0b,0x8e,0x12,0xa0,0x00,0xb8,0x52,0x2e,0x00,0x0b,0x80,0x02,0xe0,0x05,0xb8 }, - 16, 0x85c0, 0, {0xaa,0x23,0x3e,0x0d,0x80,0x02,0xe0,0x00,0xb8,0x00,0x3a,0x00,0x08,0x80,0x02,0xce }, - 16, 0x85d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x20,0xa9,0x00,0xa4,0x44 }, - 16, 0x85e0, 0, {0x09,0x90,0x02,0xc5,0x00,0xa1,0x08,0x2c,0x40,0x0b,0x11,0x82,0x04,0x00,0xb1,0x00 }, - 16, 0x85f0, 0, {0x28,0x40,0x0a,0x10,0x42,0xc4,0x00,0xb5,0x00,0xa1,0x40,0x08,0x10,0x02,0xc4,0x00 }, - 16, 0x8600, 0, {0xb1,0x01,0x2c,0x40,0x08,0x10,0x20,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8610, 0, {0x18,0x15,0xa4,0x00,0x89,0x04,0x22,0x40,0x0b,0x90,0x00,0xac,0x00,0x39,0x00,0x2a }, - 16, 0x8620, 0, {0x40,0x0b,0x10,0x02,0xa4,0x00,0xb9,0x00,0x2e,0x48,0x0b,0x90,0x12,0xe4,0x00,0xb9 }, - 16, 0x8630, 0, {0x00,0x21,0x60,0x09,0x92,0x22,0xe4,0x28,0xb9,0x00,0x0a,0x50,0x08,0x90,0x06,0xc6 }, - 16, 0x8640, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xe9,0x00,0x36,0x40 }, - 16, 0x8650, 0, {0x0d,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x48,0x0f,0x90,0x03,0x24,0x00,0xd9,0x00 }, - 16, 0x8660, 0, {0x3a,0x78,0x0e,0x98,0x03,0xe4,0x00,0xb9,0x00,0xb2,0x40,0x0e,0x92,0x23,0xe6,0x00 }, - 16, 0x8670, 0, {0xb9,0x50,0x3e,0x70,0x2c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8680, 0, {0x68,0x01,0x84,0x00,0xf9,0x00,0x3e,0x40,0x4f,0x9c,0x23,0x64,0x00,0xf9,0x04,0x36 }, - 16, 0x8690, 0, {0x48,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x60,0x0f,0x92,0x03,0xe4,0x00,0xf9 }, - 16, 0x86a0, 0, {0x00,0x3e,0x40,0x8f,0x90,0x83,0xe4,0x44,0xf9,0x00,0x78,0x64,0x0f,0x90,0x03,0xda }, - 16, 0x86b0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x00,0x3e,0x00 }, - 16, 0x86c0, 0, {0x0f,0x82,0x03,0xa0,0x40,0xe8,0x00,0x3e,0x00,0x0d,0x80,0x03,0x20,0xc0,0xc8,0x80 }, - 16, 0x86d0, 0, {0x3e,0x12,0x0f,0x80,0x03,0x60,0x00,0x7c,0x00,0x33,0x00,0x0d,0x80,0x13,0xe0,0x10 }, - 16, 0x86e0, 0, {0xc8,0x64,0x3e,0x08,0x0c,0x82,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x86f0, 0, {0x28,0x05,0x28,0x00,0xb6,0xe0,0x0f,0xa0,0x0b,0x60,0x82,0x38,0x00,0xaa,0x00,0x2e }, - 16, 0x8700, 0, {0x80,0x08,0xa0,0x42,0xba,0x00,0xae,0x20,0x2f,0x88,0x0b,0xe5,0x02,0x28,0x00,0xba }, - 16, 0x8710, 0, {0xd8,0x37,0x80,0x08,0xec,0x02,0xf8,0x04,0x8e,0x00,0x2f,0x90,0x0d,0xe0,0x02,0xca }, - 16, 0x8720, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb0,0x24,0x2c,0x60 }, - 16, 0x8730, 0, {0x0b,0x38,0x02,0x8e,0x80,0xab,0x00,0x2c,0xc0,0x09,0x30,0x02,0x0d,0x08,0x00,0x80 }, - 16, 0x8740, 0, {0x6c,0xd0,0x0b,0x34,0x02,0xcc,0x00,0xb8,0xc0,0x20,0x00,0x48,0x34,0x12,0xcc,0x40 }, - 16, 0x8750, 0, {0x83,0x00,0x2c,0xe0,0x0a,0x35,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8760, 0, {0xa0,0x01,0x1c,0x40,0xb7,0x00,0x2d,0x02,0x8b,0x60,0x02,0x9e,0x00,0x87,0x20,0x2f }, - 16, 0x8770, 0, {0xe0,0x08,0x72,0x02,0x9e,0x00,0xa4,0x00,0x2d,0xc0,0x0b,0xf8,0x02,0x9c,0xc0,0xb3 }, - 16, 0x8780, 0, {0x02,0xa5,0xc0,0x08,0x50,0x86,0xfe,0x00,0x87,0x00,0x2f,0xd0,0x09,0x70,0x02,0xe8 }, - 16, 0x8790, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf4,0x80,0x3d,0x20 }, - 16, 0x87a0, 0, {0x0f,0x58,0x03,0x9e,0x00,0x67,0x80,0x3d,0xf8,0x0d,0x38,0x02,0x1a,0x10,0x44,0x80 }, - 16, 0x87b0, 0, {0x3d,0xe0,0x0f,0x58,0x03,0xde,0x20,0xb4,0x80,0x33,0xa0,0x2c,0x68,0x03,0xd6,0x00 }, - 16, 0x87c0, 0, {0xc7,0x81,0x3d,0xe0,0x0c,0x78,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x87d0, 0, {0x08,0x1d,0xac,0x08,0xf8,0x00,0x3e,0x00,0x8f,0x80,0x03,0x6c,0x00,0x3b,0x12,0x3e }, - 16, 0x87e0, 0, {0xca,0x0f,0xb5,0x03,0xc8,0x00,0xf8,0x04,0x7e,0xc0,0x0f,0x90,0x03,0x6c,0x80,0xfb }, - 16, 0x87f0, 0, {0x04,0x3a,0x40,0x0f,0x90,0x23,0xc8,0x00,0xf9,0x01,0x3c,0xc0,0x0f,0xb0,0x03,0xc2 }, - 16, 0x8800, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xac,0x90,0x31,0x48 }, - 16, 0x8810, 0, {0x08,0xf8,0x03,0xfa,0x00,0xcf,0x80,0x3f,0xe0,0x0c,0xfc,0x13,0x3e,0x04,0xfc,0x80 }, - 16, 0x8820, 0, {0x35,0xa0,0x0c,0x78,0x03,0xbe,0x00,0xdf,0x80,0x3b,0x20,0x24,0xf8,0x03,0x2e,0x40 }, - 16, 0x8830, 0, {0xcf,0x80,0x33,0xe0,0x03,0xf9,0x03,0xd0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8840, 0, {0xa8,0x11,0xbc,0x00,0x80,0x00,0x01,0x00,0x08,0x72,0x02,0xd0,0x00,0x87,0x00,0x2d }, - 16, 0x8850, 0, {0xc8,0x0a,0xf0,0x02,0x98,0x40,0xf5,0x00,0x61,0x41,0x00,0x74,0x02,0x1c,0x00,0xb4 }, - 16, 0x8860, 0, {0x00,0x21,0xc8,0x08,0x60,0x02,0x3e,0x20,0x86,0x08,0x21,0xd8,0x0f,0x50,0x02,0xea }, - 16, 0x8870, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x9c,0x00,0xa4,0x00,0x21,0x00 }, - 16, 0x8880, 0, {0x08,0x50,0x02,0xd8,0x00,0x97,0x00,0x2d,0xc0,0x88,0x71,0x02,0x14,0x00,0xb0,0x00 }, - 16, 0x8890, 0, {0x25,0x90,0x08,0xc0,0x82,0x9c,0x40,0x93,0x00,0x29,0xa1,0x88,0x60,0x02,0x14,0x12 }, - 16, 0x88a0, 0, {0x87,0x40,0x29,0x40,0x0b,0x60,0x02,0xc4,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x88b0, 0, {0x60,0x14,0xcc,0x00,0x80,0xd0,0xa0,0x00,0x08,0x1c,0x02,0xc0,0x00,0x93,0x00,0x2c }, - 16, 0x88c0, 0, {0xd0,0x0a,0xb0,0x26,0x80,0x00,0xb3,0x00,0x24,0xe4,0x08,0x08,0x02,0x8c,0x00,0xb0 }, - 16, 0x88d0, 0, {0x02,0x02,0x41,0x08,0x08,0x02,0x03,0x01,0x81,0x00,0x28,0x42,0x1a,0x00,0x42,0xd8 }, - 16, 0x88e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x15,0xbc,0x00,0xe8,0xc0,0x32,0x80 }, - 16, 0x88f0, 0, {0x0c,0xb5,0x03,0xe4,0x00,0x9f,0x00,0x3d,0xe0,0x0c,0xf0,0x0b,0x24,0x00,0xf8,0x00 }, - 16, 0x8900, 0, {0x36,0xe0,0x0c,0x25,0x03,0xbc,0x05,0xd8,0x02,0x2a,0x00,0x08,0xba,0x02,0x2a,0x00 }, - 16, 0x8910, 0, {0xc1,0x02,0x3a,0x50,0x8b,0x90,0x03,0xee,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8920, 0, {0x80,0x00,0xec,0x00,0xfb,0x08,0x3e,0x80,0x0f,0xa1,0x03,0xec,0x04,0xeb,0x02,0x2e }, - 16, 0x8930, 0, {0xc6,0x0f,0xb0,0x17,0x44,0x00,0xe8,0x00,0x3a,0x40,0x0f,0x80,0x02,0x6c,0x00,0xfb }, - 16, 0x8940, 0, {0x00,0x3e,0xe0,0x0f,0x90,0x93,0xe1,0x00,0xd9,0x00,0x26,0x70,0x8f,0x90,0x01,0xe1 }, - 16, 0x8950, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xfc,0x00,0xfc,0x03,0x37,0x24 }, - 16, 0x8960, 0, {0x0d,0xf8,0x03,0xe0,0x00,0xff,0x00,0x3f,0xc1,0x8d,0xf0,0x0b,0x38,0x00,0xcc,0x00 }, - 16, 0x8970, 0, {0x3f,0xc0,0x0f,0xfa,0x03,0x3c,0x0c,0xfc,0x04,0x3b,0x80,0x0c,0xa0,0x03,0x94,0x20 }, - 16, 0x8980, 0, {0x89,0x05,0x3b,0x00,0x4f,0xd0,0x23,0xc0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8990, 0, {0x80,0x04,0x6c,0x00,0xb0,0x06,0x20,0x13,0x88,0xa8,0x02,0xeb,0x00,0xbb,0x00,0x2e }, - 16, 0x89a0, 0, {0xc0,0x08,0xb0,0x02,0x2a,0x00,0xa8,0x80,0x2e,0xe0,0x0b,0x94,0x1a,0x2c,0x00,0xbb }, - 16, 0x89b0, 0, {0x00,0xa2,0x40,0x29,0x98,0x02,0xe2,0x00,0xa9,0x84,0x22,0x20,0x0b,0x98,0x02,0xe0 }, - 16, 0x89c0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xb8,0x00,0x22,0x00 }, - 16, 0x89d0, 0, {0x09,0x82,0x02,0xe6,0x00,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0x26,0x00,0x88,0x80 }, - 16, 0x89e0, 0, {0x2e,0xa0,0x0b,0xa0,0x02,0x2c,0x00,0xb3,0x00,0x2a,0x00,0x09,0x98,0x02,0xea,0x20 }, - 16, 0x89f0, 0, {0xa9,0x80,0x2a,0x60,0x9b,0x98,0x82,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8a00, 0, {0x08,0x04,0x0c,0x00,0xb8,0x00,0x20,0x00,0x09,0x08,0x02,0xc4,0x00,0xb3,0x00,0x26 }, - 16, 0x8a10, 0, {0xc0,0x00,0x30,0x02,0x00,0x00,0x81,0x00,0x2c,0x41,0x0b,0x00,0x02,0x0c,0x00,0xb0 }, - 16, 0x8a20, 0, {0x00,0x20,0xc0,0x0b,0x00,0x02,0xc8,0x80,0xa8,0x00,0x20,0x41,0x0b,0x10,0x02,0xc2 }, - 16, 0x8a30, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x10,0xf8,0x50,0xb2,0x00 }, - 16, 0x8a40, 0, {0x0d,0x80,0x03,0xe0,0x00,0xfb,0x00,0x3d,0xc0,0x0d,0xf0,0x13,0x24,0x02,0xc8,0x06 }, - 16, 0x8a50, 0, {0x3e,0x80,0x0f,0xa0,0x03,0x3c,0x04,0xfb,0x00,0x78,0x80,0x0c,0xa0,0x03,0xe4,0x00 }, - 16, 0x8a60, 0, {0xe9,0x00,0x1a,0x40,0x0f,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8a70, 0, {0xa0,0x1d,0xfc,0x00,0xf4,0x20,0x3f,0x00,0x0e,0xc0,0x02,0xf0,0x01,0xff,0x00,0x3f }, - 16, 0x8a80, 0, {0xc0,0x0f,0xf0,0x23,0xf0,0x00,0xfd,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xfc,0x00,0xfc }, - 16, 0x8a90, 0, {0x00,0x3f,0x40,0x9c,0xc0,0x03,0xf0,0x40,0xfd,0x00,0x3f,0x40,0x0f,0xd0,0x43,0xe8 }, - 16, 0x8aa0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0x00,0xed,0x23,0xb7,0x48 }, - 16, 0x8ab0, 0, {0x0c,0xe1,0xc3,0x7c,0xc0,0xdd,0x80,0x37,0xe0,0x0f,0xcb,0x03,0xfe,0x08,0xfc,0x28 }, - 16, 0x8ac0, 0, {0x3f,0xf0,0x1c,0xfb,0x23,0x7c,0x01,0xff,0x14,0x77,0xe2,0x4f,0xe8,0x23,0x7c,0x00 }, - 16, 0x8ad0, 0, {0xc4,0x80,0x33,0x48,0x2c,0xf8,0x22,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ae0, 0, {0x80,0x10,0xe0,0xe0,0xc9,0xc0,0x22,0x5b,0x88,0x96,0x22,0x2d,0x00,0x89,0x22,0x22 }, - 16, 0x8af0, 0, {0xca,0x0b,0x9e,0x22,0xe2,0xa0,0xb9,0x61,0x2c,0xe0,0x88,0x9f,0x02,0x3d,0x85,0xbf }, - 16, 0x8b00, 0, {0x60,0x26,0x50,0x48,0xa0,0x02,0x3c,0x00,0x88,0x00,0x22,0x50,0x08,0xb0,0x02,0x20 }, - 16, 0x8b10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x80,0xb1,0x10,0x20,0x44 }, - 16, 0x8b20, 0, {0x0b,0xb2,0x02,0xce,0xd0,0x81,0x08,0x2c,0xc0,0x0b,0x01,0x02,0x8c,0x08,0xb3,0x08 }, - 16, 0x8b30, 0, {0x2c,0xc9,0x08,0x10,0x62,0x8c,0x60,0xb3,0x32,0x24,0x80,0x0a,0xa0,0x02,0x6c,0x03 }, - 16, 0x8b40, 0, {0x9a,0x01,0x26,0x44,0x48,0xb0,0x42,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8b50, 0, {0xc0,0x15,0xa4,0xa0,0x8b,0x02,0x22,0xe0,0x0b,0xb0,0x62,0xac,0x98,0x99,0x00,0x2a }, - 16, 0x8b60, 0, {0xc2,0x0b,0x98,0x06,0xe4,0x00,0xbb,0x02,0x2e,0xc0,0x08,0x91,0x42,0x2c,0x10,0xbb }, - 16, 0x8b70, 0, {0x00,0x6e,0x80,0x0a,0x80,0x02,0x6c,0x00,0x1b,0x00,0x06,0x40,0x48,0xb8,0x0a,0x70 }, - 16, 0x8b80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xe7,0x00,0xa1,0x00,0x76,0x78 }, - 16, 0x8b90, 0, {0x0f,0xb0,0x03,0xe8,0x10,0xd9,0x00,0x3e,0xd0,0x4b,0x9e,0x13,0xac,0x08,0xb8,0xa0 }, - 16, 0x8ba0, 0, {0x7e,0xc6,0x08,0xa8,0x02,0x2c,0x01,0xbb,0x00,0x26,0x30,0x4e,0x20,0x03,0x4c,0x18 }, - 16, 0x8bb0, 0, {0x99,0x80,0xb4,0x40,0x4c,0x3a,0x03,0x40,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8bc0, 0, {0xe0,0x01,0xb2,0x00,0xfd,0xc5,0x3b,0xc0,0x4c,0xd0,0x03,0x6a,0x02,0xed,0x06,0x33 }, - 16, 0x8bd0, 0, {0xc4,0x0f,0xd0,0x53,0xf8,0x00,0xfc,0x90,0x7f,0xc1,0x0f,0x78,0x03,0xbc,0x04,0xff }, - 16, 0x8be0, 0, {0x00,0x37,0x64,0x0c,0xf1,0x03,0xa4,0x00,0xed,0xa1,0x3b,0x40,0x0b,0xf0,0x83,0xb8 }, - 16, 0x8bf0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8c,0x00,0xcb,0x20,0x3e,0x71 }, - 16, 0x8c00, 0, {0x0f,0xb3,0x03,0x98,0x02,0xfb,0x02,0x36,0x48,0x0f,0x90,0x03,0xec,0x20,0xf8,0x00 }, - 16, 0x8c10, 0, {0x3e,0xcc,0x04,0x84,0x03,0x2c,0x00,0xdb,0x04,0x3c,0x10,0x0f,0xa0,0x03,0xec,0x00 }, - 16, 0x8c20, 0, {0x9b,0x00,0x32,0x40,0x0c,0x90,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8c30, 0, {0x88,0x05,0x2c,0x02,0x8b,0x48,0x2e,0xe0,0x0b,0x34,0x03,0x6b,0x00,0x8b,0xf5,0x22 }, - 16, 0x8c40, 0, {0xf2,0x0b,0x9c,0x03,0xaf,0x00,0xb8,0x50,0x2e,0xc0,0x08,0xb0,0x02,0x7c,0x00,0x8f }, - 16, 0x8c50, 0, {0x00,0x0e,0x5d,0x0b,0x80,0x02,0xf5,0x40,0x83,0x50,0x23,0x54,0x08,0x9c,0x02,0xe6 }, - 16, 0x8c60, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x04,0x4c,0x00,0x81,0x81,0x2e,0x40 }, - 16, 0x8c70, 0, {0x03,0x2c,0x02,0x04,0x33,0x99,0x00,0x20,0xf0,0x4a,0x28,0x80,0xcc,0x40,0xb0,0x00 }, - 16, 0x8c80, 0, {0x26,0x10,0x08,0x20,0x02,0x4c,0x00,0x83,0x00,0x2c,0xc0,0x09,0x20,0x02,0xcc,0x00 }, - 16, 0x8c90, 0, {0xa0,0x02,0x28,0x40,0x08,0x08,0x02,0x7a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ca0, 0, {0x20,0x01,0x0a,0x00,0x85,0x80,0x2d,0xf8,0x0b,0xda,0x02,0xd6,0x40,0x85,0xa0,0x21 }, - 16, 0x8cb0, 0, {0xe0,0x0b,0x48,0x06,0x92,0x04,0xb5,0x80,0x2d,0x21,0x08,0x00,0x02,0x4e,0x00,0x87 }, - 16, 0x8cc0, 0, {0xa4,0x2d,0x60,0x0b,0x68,0x02,0xde,0xc2,0xad,0x90,0x2b,0x60,0x28,0x58,0x82,0xdc }, - 16, 0x8cd0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x4c,0x40,0xc3,0x10,0x2c,0x6c }, - 16, 0x8ce0, 0, {0x0f,0x30,0x03,0x86,0xa2,0xf9,0xb0,0xb0,0xe0,0x0f,0x29,0x83,0xce,0x44,0xf3,0x80 }, - 16, 0x8cf0, 0, {0x3c,0xac,0x0c,0x30,0x03,0x0c,0x00,0xc3,0x00,0x3c,0xd5,0x0f,0x20,0x03,0xce,0xc1 }, - 16, 0x8d00, 0, {0xe0,0x10,0xb8,0x40,0x0c,0x00,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8d10, 0, {0xc0,0x1d,0xbc,0x00,0xeb,0x00,0x3e,0xcc,0x0f,0x32,0x03,0x64,0x08,0xf9,0x00,0x3b }, - 16, 0x8d20, 0, {0x90,0x0f,0xf0,0x43,0xe4,0x40,0xfb,0x34,0x3f,0x81,0x07,0xd1,0x03,0xad,0x20,0xeb }, - 16, 0x8d30, 0, {0x20,0x7f,0xc4,0x0f,0xe1,0x03,0xfc,0x50,0xcd,0x10,0x35,0x40,0x0f,0xd0,0x03,0xd0 }, - 16, 0x8d40, 0, {0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x04,0xfd,0x04,0x3d,0x40 }, - 16, 0x8d50, 0, {0x2d,0x30,0x02,0x3c,0x00,0xc9,0x01,0x3e,0xc0,0x4f,0xb8,0x43,0xec,0x10,0xfb,0x00 }, - 16, 0x8d60, 0, {0x32,0x40,0x0f,0xa0,0x23,0xec,0x80,0xcb,0x36,0x32,0x80,0x4d,0xa8,0x03,0x2c,0x10 }, - 16, 0x8d70, 0, {0xcb,0x00,0x32,0x40,0x0c,0x90,0x03,0x6a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8d80, 0, {0xc8,0x11,0x90,0x08,0xb5,0x00,0x2d,0xc0,0x08,0x50,0x02,0xbc,0x02,0x85,0x04,0x2d }, - 16, 0x8d90, 0, {0xc0,0x8e,0x60,0x06,0xd8,0x04,0xb7,0x04,0x21,0x40,0x0b,0x70,0x02,0xfc,0x80,0xaf }, - 16, 0x8da0, 0, {0x28,0x21,0xc0,0x0b,0x70,0x02,0x06,0x40,0x87,0x00,0x21,0x50,0x08,0x50,0x02,0x32 }, - 16, 0x8db0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x20,0xb7,0x80,0x2b,0x70 }, - 16, 0x8dc0, 0, {0x08,0xf8,0x06,0x1e,0x00,0x87,0x80,0x2d,0xe0,0x0b,0x70,0x32,0xde,0x04,0x37,0x84 }, - 16, 0x8dd0, 0, {0x25,0xe0,0x0b,0x68,0x06,0xde,0x80,0x87,0x80,0x21,0xa1,0x1b,0x68,0x02,0x1e,0x40 }, - 16, 0x8de0, 0, {0x9f,0x80,0x20,0x60,0x08,0x58,0x02,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8df0, 0, {0x48,0x14,0xcc,0x20,0xb3,0x00,0x2c,0x80,0x88,0xb4,0x22,0x8d,0x00,0x83,0x90,0x2c }, - 16, 0x8e00, 0, {0xc0,0x0a,0x38,0x02,0xce,0x08,0xbb,0x20,0x24,0xd0,0x0b,0xb3,0x02,0xcc,0x00,0xa3 }, - 16, 0x8e10, 0, {0x00,0x60,0xd2,0x0b,0x20,0x2a,0x04,0x08,0x93,0x50,0x20,0x40,0x08,0x17,0x0a,0x02 }, - 16, 0x8e20, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x00,0xba,0xa0,0x3f,0x84 }, - 16, 0x8e30, 0, {0x1c,0xe0,0x0b,0x38,0x40,0x8e,0x06,0x2e,0x80,0x0b,0xe3,0x03,0xf8,0x80,0xfe,0xe4 }, - 16, 0x8e40, 0, {0xb7,0x90,0x0f,0xec,0x02,0xe8,0x00,0x8a,0x00,0xa3,0xa0,0x09,0xe4,0x03,0x2a,0x02 }, - 16, 0x8e50, 0, {0xde,0xc0,0xf3,0x80,0x0c,0x6c,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8e60, 0, {0x48,0x01,0xe0,0x00,0xf8,0x40,0x3e,0x00,0x0f,0x84,0x13,0xe0,0x00,0xf8,0x00,0x2e }, - 16, 0x8e70, 0, {0x30,0x0a,0x84,0x03,0xe0,0x04,0xf8,0x00,0x3a,0x02,0x0f,0x80,0x13,0xe0,0x00,0xf8 }, - 16, 0x8e80, 0, {0x00,0x3e,0x04,0x0d,0x80,0x83,0xe0,0x40,0xe8,0x20,0x3e,0x00,0x2f,0x80,0x03,0xd2 }, - 16, 0x8e90, 0, {0x10,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xf9,0x00,0x3c,0x64 }, - 16, 0x8ea0, 0, {0x4e,0x90,0x83,0x24,0x80,0xc9,0x00,0x32,0xe0,0x0f,0x10,0x03,0x25,0x00,0xf9,0x00 }, - 16, 0x8eb0, 0, {0x32,0x44,0x0f,0x92,0x23,0x64,0x00,0xc1,0x00,0x32,0x40,0x0c,0x90,0x13,0xe4,0x00 }, - 16, 0x8ec0, 0, {0xc9,0x00,0x22,0x40,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ed0, 0, {0x80,0x04,0x64,0x00,0xb9,0x20,0x2e,0x40,0x48,0x96,0x22,0x25,0x00,0xd9,0xc0,0xa2 }, - 16, 0x8ee0, 0, {0x70,0x0b,0x98,0x02,0x24,0x00,0xb9,0x40,0xa2,0x70,0x4b,0x90,0x02,0x24,0x00,0xd9 }, - 16, 0x8ef0, 0, {0x00,0xa2,0x40,0x2c,0x94,0x22,0xe4,0x02,0x89,0x00,0xa2,0x40,0x28,0x94,0x13,0x20 }, - 16, 0x8f00, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xb9,0x00,0x2e,0x40 }, - 16, 0x8f10, 0, {0x0a,0x90,0x02,0x04,0x00,0x81,0x80,0xa2,0x44,0x0b,0x91,0x02,0x25,0x00,0x19,0x40 }, - 16, 0x8f20, 0, {0x62,0x40,0x0b,0xb4,0x02,0x44,0x00,0x89,0x00,0x20,0x40,0x08,0x90,0x82,0xc4,0x01 }, - 16, 0x8f30, 0, {0x83,0x02,0x28,0x40,0x48,0x90,0x82,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8f40, 0, {0x00,0x04,0x05,0x80,0xb1,0x00,0x6c,0x51,0x08,0x14,0x1a,0x05,0x00,0x93,0x00,0x20 }, - 16, 0x8f50, 0, {0x40,0x8b,0x14,0x02,0x05,0x00,0xb1,0x20,0x20,0x50,0x0b,0x14,0x06,0x04,0x80,0x91 }, - 16, 0x8f60, 0, {0x20,0x20,0x40,0x09,0x10,0x02,0xc4,0xa8,0x81,0x00,0x28,0x4a,0x08,0x90,0x4a,0x42 }, - 16, 0x8f70, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x00,0x3e,0x00 }, - 16, 0x8f80, 0, {0x0e,0x80,0x03,0x28,0x01,0xc8,0x50,0x32,0x94,0x8b,0xa0,0x03,0x20,0x00,0xb0,0x50 }, - 16, 0x8f90, 0, {0x32,0x80,0x0f,0x80,0x07,0x61,0x51,0xc8,0x50,0x22,0x00,0x0c,0x00,0x03,0xe0,0x84 }, - 16, 0x8fa0, 0, {0xc8,0x04,0x3a,0x08,0x0c,0x00,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8fb0, 0, {0x98,0x9d,0xf4,0x40,0xbd,0x41,0x3f,0x50,0x0f,0xf4,0x03,0xf5,0x10,0xfd,0x00,0x3e }, - 16, 0x8fc0, 0, {0x40,0x0f,0xd4,0x03,0xf4,0x00,0xff,0x10,0x2f,0x40,0x4f,0xd4,0x40,0xa4,0x48,0xf9 }, - 16, 0x8fd0, 0, {0x12,0x3f,0x5a,0x8e,0xd2,0x83,0xf4,0xa8,0xf5,0x2c,0x37,0x4a,0x0f,0xd2,0x83,0xa6 }, - 16, 0x8fe0, 0, {0x12,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x80,0xfd,0x28,0x3f,0x4c }, - 16, 0x8ff0, 0, {0x0f,0x50,0x03,0x3c,0x44,0xcd,0x40,0x3f,0xd0,0x0d,0xd0,0x02,0x14,0x01,0xfd,0xa0 }, - 16, 0x9000, 0, {0x31,0x40,0x03,0xd0,0x03,0xe7,0x89,0xf9,0x90,0x7e,0x50,0x0c,0x94,0x03,0xe6,0xc0 }, - 16, 0x9010, 0, {0xc9,0x10,0x32,0x6d,0x0f,0x91,0x02,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9020, 0, {0x38,0x10,0xe0,0x80,0xb8,0x01,0x2e,0x0c,0x8b,0x84,0x82,0x20,0x42,0x88,0xa0,0x6e }, - 16, 0x9030, 0, {0x20,0x08,0x80,0x03,0x60,0x00,0x98,0xe8,0x22,0x00,0x09,0x80,0x02,0xe3,0xc0,0xe8 }, - 16, 0x9040, 0, {0xd0,0x2e,0x28,0x08,0x8a,0x23,0xe2,0x84,0xd8,0xa0,0x22,0x3d,0x0b,0xc8,0x02,0xce }, - 16, 0x9050, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc5,0xb0,0xb1,0x00,0x2c,0x48 }, - 16, 0x9060, 0, {0x0b,0x13,0x02,0x04,0x02,0xb1,0x20,0x2e,0x40,0x88,0x10,0x22,0xc4,0x00,0xb1,0x14 }, - 16, 0x9070, 0, {0x24,0x40,0x0b,0x10,0x52,0xc4,0x00,0xb1,0x21,0x2d,0x48,0x0a,0x52,0x02,0xd5,0x00 }, - 16, 0x9080, 0, {0xbd,0x00,0xad,0x40,0x0b,0x52,0x02,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9090, 0, {0x18,0x55,0xa5,0x00,0xb9,0x82,0x2e,0x49,0x8b,0xb0,0x12,0x24,0x10,0x99,0x02,0x2e }, - 16, 0x90a0, 0, {0x40,0x08,0xb2,0x00,0x65,0x00,0x99,0x80,0x26,0x44,0x09,0x91,0x02,0xe4,0x09,0xa9 }, - 16, 0x90b0, 0, {0x04,0x2e,0x46,0x0a,0xd4,0x02,0xb4,0x00,0xbd,0x40,0x2f,0x40,0x0b,0xd0,0x02,0xc6 }, - 16, 0x90c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x40,0xf9,0x80,0x2e,0x62 }, - 16, 0x90d0, 0, {0x0f,0x9c,0x42,0x24,0x00,0x99,0x01,0x2e,0x68,0x2c,0x92,0x02,0x64,0x00,0xb9,0x40 }, - 16, 0x90e0, 0, {0xb6,0x60,0x0f,0x9a,0x03,0xe4,0x00,0xb9,0x00,0x2e,0x70,0x3e,0x99,0x06,0xe4,0x02 }, - 16, 0x90f0, 0, {0xf9,0x00,0x3e,0x40,0x0f,0x98,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9100, 0, {0x68,0x01,0xa6,0x00,0xf9,0x00,0x3e,0x40,0x1f,0x12,0xab,0xe4,0x00,0xe9,0x90,0x3e }, - 16, 0x9110, 0, {0x49,0x0e,0x98,0x03,0xe4,0x00,0xf1,0x00,0x3a,0x40,0x0d,0x98,0x03,0xe4,0x00,0xf9 }, - 16, 0x9120, 0, {0x01,0x3e,0x60,0x05,0x90,0x13,0xe4,0x00,0x59,0x20,0x32,0x40,0x8f,0x91,0x03,0xda }, - 16, 0x9130, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0xa0,0x00,0xc8,0x08,0x3e,0x01 }, - 16, 0x9140, 0, {0x0f,0x84,0x63,0x00,0x22,0xe8,0x20,0x3e,0x13,0x0f,0x84,0x03,0xe1,0xc0,0xd8,0x4c }, - 16, 0x9150, 0, {0x32,0x00,0x0c,0x84,0x43,0xe0,0x00,0xf8,0x00,0x22,0x10,0x0f,0x84,0x03,0x00,0x00 }, - 16, 0x9160, 0, {0xc8,0x00,0xb2,0x00,0x0c,0xc0,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9170, 0, {0x28,0x05,0x28,0x00,0x8e,0x00,0x2f,0x86,0x4b,0xe0,0x02,0x39,0x08,0x8e,0x20,0x2d }, - 16, 0x9180, 0, {0x90,0x0b,0xed,0x92,0xf8,0x02,0x8e,0xe0,0xa3,0x98,0x08,0xe0,0x02,0xe8,0x08,0xba }, - 16, 0x9190, 0, {0x00,0x62,0x80,0x08,0xa0,0x02,0x28,0x00,0x02,0x80,0x02,0x80,0x48,0xe0,0x03,0x4a }, - 16, 0x91a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x05,0x4c,0x00,0x83,0x10,0x2c,0xf0 }, - 16, 0x91b0, 0, {0x0a,0x14,0x2a,0x0d,0x1a,0xb3,0x01,0x24,0xd0,0x0b,0xbc,0x32,0xcc,0x08,0x03,0x00 }, - 16, 0x91c0, 0, {0x20,0xc8,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x02,0x22,0xc0,0x09,0x30,0x02,0x0c,0x11 }, - 16, 0x91d0, 0, {0x83,0x00,0x20,0xc0,0x28,0x20,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x91e0, 0, {0x20,0x01,0x1e,0x01,0x85,0x00,0x2d,0x00,0x0b,0x70,0x02,0x18,0x32,0x86,0x00,0x2d }, - 16, 0x91f0, 0, {0xc0,0x0b,0x60,0x16,0xfe,0x04,0x86,0x00,0x27,0xa0,0x8b,0x70,0x42,0xdc,0x80,0xb7 }, - 16, 0x9200, 0, {0x80,0x21,0x01,0x08,0xf8,0x0a,0x18,0x00,0x86,0x08,0x20,0xa0,0x08,0xe8,0x0a,0x68 }, - 16, 0x9210, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x3e,0x02,0xc6,0x80,0x3d,0xe0 }, - 16, 0x9220, 0, {0x0f,0x48,0x03,0x06,0x04,0xf5,0x82,0x35,0xe0,0x0f,0x78,0x03,0xda,0x00,0xd3,0x80 }, - 16, 0x9230, 0, {0x31,0x60,0x07,0x78,0x03,0xde,0x20,0xf3,0xb0,0x81,0xe0,0x4f,0x68,0x07,0x0e,0x02 }, - 16, 0x9240, 0, {0xcf,0x80,0x31,0xe0,0x0c,0x78,0x13,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9250, 0, {0x08,0x1d,0xad,0xa0,0xf9,0x00,0x3f,0x00,0x0f,0xb0,0x53,0xf8,0x10,0xa9,0x00,0x3e }, - 16, 0x9260, 0, {0x00,0x0f,0x80,0x01,0xec,0x00,0xfb,0x02,0x3a,0xc0,0x0c,0xb0,0x03,0xec,0x00,0xfb }, - 16, 0x9270, 0, {0x74,0x3c,0x00,0x0f,0x20,0x03,0xe8,0x00,0xfa,0x00,0x3e,0x80,0x0f,0x30,0x03,0xc2 }, - 16, 0x9280, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x02,0x8f,0x80,0x35,0xe0 }, - 16, 0x9290, 0, {0x8d,0xd9,0x03,0x2e,0xc4,0xf6,0x80,0x32,0xa4,0x0c,0xb8,0x03,0xde,0x00,0xcf,0x90 }, - 16, 0x92a0, 0, {0x3c,0xe4,0x0c,0xb8,0x03,0xfe,0x65,0xff,0x80,0x0f,0xec,0x8f,0xf8,0x03,0xfe,0x00 }, - 16, 0x92b0, 0, {0xc5,0x80,0x33,0xe0,0x0f,0x68,0x03,0x10,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x92c0, 0, {0xaa,0x11,0x9c,0x80,0x84,0xb0,0x20,0x20,0x29,0x73,0x0a,0x0e,0x82,0xa2,0xa0,0xa2 }, - 16, 0x92d0, 0, {0xa0,0x4f,0x3b,0x03,0x87,0x84,0xb2,0x80,0x2c,0xa0,0x0a,0x7d,0x02,0xde,0x80,0xf7 }, - 16, 0x92e0, 0, {0x20,0x25,0x06,0x08,0x70,0x02,0xc8,0x40,0x84,0x00,0x35,0x80,0x0b,0x60,0x03,0x6a }, - 16, 0x92f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x10,0x86,0x38,0x27,0xc0 }, - 16, 0x9300, 0, {0x49,0x54,0x06,0x54,0x40,0x1d,0x20,0x21,0xca,0x09,0x61,0x40,0xf8,0x80,0xb7,0x20 }, - 16, 0x9310, 0, {0x2f,0x00,0x89,0x70,0x12,0xdc,0x81,0xb7,0x04,0x2d,0xc9,0x0a,0x60,0x02,0xcc,0x00 }, - 16, 0x9320, 0, {0x8d,0x00,0x2d,0xc0,0x0b,0xf8,0x02,0x04,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9330, 0, {0x60,0x14,0xcd,0x28,0x80,0x00,0x24,0x00,0x09,0xb0,0x22,0x4c,0x02,0xa1,0x01,0x20 }, - 16, 0x9340, 0, {0x30,0x1b,0x23,0x02,0xaf,0x20,0xb3,0x08,0x2c,0x80,0x1b,0x30,0x00,0xcc,0x04,0xa3 }, - 16, 0x9350, 0, {0x01,0x26,0x30,0x08,0xac,0x22,0xe8,0x02,0x80,0x08,0x2e,0x80,0x4b,0xb4,0x02,0x58 }, - 16, 0x9360, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x10,0x8b,0x80,0x36,0xf0 }, - 16, 0x9370, 0, {0x2d,0xbc,0x0b,0x6c,0x01,0xda,0x04,0x22,0x40,0x7d,0x94,0x22,0xe4,0x00,0xab,0x44 }, - 16, 0x9380, 0, {0x2e,0xc0,0x09,0xb8,0x02,0xfc,0x00,0xbf,0x00,0x3e,0xf0,0xca,0x92,0x02,0xe4,0x02 }, - 16, 0x9390, 0, {0xcb,0x00,0x6e,0x40,0x0f,0x84,0x01,0x2e,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x93a0, 0, {0x80,0x00,0xec,0x00,0xfb,0x00,0x3a,0xe0,0x2e,0xbc,0x03,0x98,0x08,0xea,0x40,0x36 }, - 16, 0x93b0, 0, {0x43,0x8c,0x90,0x03,0xa4,0x44,0x2a,0x40,0x3e,0x10,0x0e,0xb5,0x83,0xec,0x14,0xfb }, - 16, 0x93c0, 0, {0x00,0x26,0x00,0x0e,0x92,0x03,0xe0,0x40,0xfa,0x00,0x16,0x00,0x0f,0x80,0x13,0xe0 }, - 16, 0x93d0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xec,0x02,0xfa,0x80,0x3f,0xe2 }, - 16, 0x93e0, 0, {0x0f,0xb0,0x0b,0x24,0x00,0xef,0x92,0xbb,0xe0,0x1c,0xd0,0x03,0x74,0x00,0xcf,0x05 }, - 16, 0x93f0, 0, {0x3b,0x40,0x0f,0xc8,0x03,0x5c,0x00,0xcf,0x00,0x32,0xc2,0x4d,0xc1,0x23,0x34,0x40 }, - 16, 0x9400, 0, {0xcf,0x00,0x17,0x44,0x0c,0xd1,0x83,0x00,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9410, 0, {0x81,0x04,0x6c,0x00,0x8b,0x84,0x2e,0x54,0x0b,0xbc,0x0a,0x29,0x80,0x8b,0x80,0x32 }, - 16, 0x9420, 0, {0x00,0x08,0x9c,0x03,0xa7,0x00,0xab,0x84,0x2e,0x7c,0x0b,0x80,0x02,0x2c,0x10,0xdb }, - 16, 0x9430, 0, {0x01,0x36,0x00,0x08,0x80,0x02,0x20,0x00,0x82,0x00,0x22,0x00,0x08,0x90,0x02,0x24 }, - 16, 0x9440, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x0c,0x00,0x89,0x10,0x66,0x90 }, - 16, 0x9450, 0, {0x0b,0xb8,0x02,0x6e,0x12,0xa3,0x41,0x20,0x04,0x0a,0x98,0x22,0xe2,0x00,0x89,0x19 }, - 16, 0x9460, 0, {0x2e,0xc0,0x4b,0x31,0x22,0x6c,0x08,0x83,0x00,0x22,0xc0,0x09,0x90,0x02,0x24,0x00 }, - 16, 0x9470, 0, {0x89,0x00,0x2a,0x40,0x08,0x80,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9480, 0, {0x08,0x10,0x0c,0x00,0x80,0x20,0x2c,0x0e,0x1b,0x30,0x02,0x04,0x41,0x80,0x20,0x20 }, - 16, 0x9490, 0, {0x12,0x18,0x16,0x42,0x00,0x50,0xa0,0x40,0x2c,0x88,0x1b,0x30,0x02,0x0c,0x81,0x93 }, - 16, 0x94a0, 0, {0x00,0x24,0x00,0x08,0x10,0x2a,0x00,0x0a,0x88,0x00,0x28,0x00,0x28,0x00,0x0a,0x02 }, - 16, 0x94b0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x7c,0x11,0xe8,0x00,0x26,0x98 }, - 16, 0x94c0, 0, {0x0f,0xb0,0x13,0x21,0x0c,0xeb,0x60,0x3a,0xd8,0x28,0x84,0xa2,0xe1,0x80,0xc8,0x20 }, - 16, 0x94d0, 0, {0x3e,0x5e,0x1f,0x82,0x03,0x7c,0x00,0xcf,0x00,0x32,0xc0,0x4d,0x80,0x07,0x25,0x00 }, - 16, 0x94e0, 0, {0xc9,0x00,0x32,0x40,0x0c,0x90,0x03,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x94f0, 0, {0xa1,0x11,0xfc,0x00,0xf8,0x13,0x1e,0x00,0x0b,0xf0,0x01,0xf0,0xd0,0xf9,0x19,0x1f }, - 16, 0x9500, 0, {0x08,0x4f,0xc0,0x13,0xa1,0x00,0xf8,0x62,0x3f,0xc0,0x0b,0xc4,0x07,0xed,0x00,0xff }, - 16, 0x9510, 0, {0x00,0x3f,0x00,0x0f,0xc0,0x23,0xf0,0xa0,0xfc,0x00,0x33,0x00,0x0f,0xd0,0x03,0xe8 }, - 16, 0x9520, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xff,0x0c,0x3f,0x20 }, - 16, 0x9530, 0, {0x0c,0xc9,0x03,0x32,0x00,0xcf,0x38,0x3f,0xd0,0x0f,0x48,0x03,0xfc,0xa0,0xce,0x22 }, - 16, 0x9540, 0, {0x33,0x00,0x0f,0xc1,0x03,0x3c,0x00,0xff,0x00,0x3d,0xc4,0x4c,0xc0,0x23,0x8c,0xe4 }, - 16, 0x9550, 0, {0xff,0x10,0x37,0x20,0x08,0xf1,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9560, 0, {0x80,0x10,0xfe,0x00,0xbf,0x80,0x2e,0x74,0x05,0x22,0x02,0xa2,0x10,0xdf,0x61,0x2f }, - 16, 0x9570, 0, {0xd0,0x8b,0x90,0x02,0x3d,0xa4,0xaa,0x90,0x22,0xf4,0x0b,0x07,0x12,0x1d,0x20,0xbb }, - 16, 0x9580, 0, {0xc0,0x2f,0xd8,0x88,0x97,0x82,0xfd,0x80,0xef,0x72,0x22,0x08,0x28,0xf6,0x23,0xe0 }, - 16, 0x9590, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x40,0xb3,0x00,0x2c,0x00 }, - 16, 0x95a0, 0, {0x08,0x82,0x02,0x22,0x00,0x83,0x01,0x08,0xcc,0x8b,0x20,0x82,0xcc,0x00,0x90,0x00 }, - 16, 0x95b0, 0, {0x20,0x00,0x4b,0x12,0x02,0x0d,0x80,0xb3,0x40,0x2c,0xd8,0x08,0x20,0x42,0x8c,0x80 }, - 16, 0x95c0, 0, {0xb3,0x20,0x26,0x02,0x18,0x33,0x26,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x95d0, 0, {0xc0,0x15,0xac,0x09,0xbb,0x00,0x2e,0x60,0x08,0x80,0x02,0xa2,0x00,0x9b,0x00,0x2e }, - 16, 0x95e0, 0, {0xc0,0x0b,0xac,0x02,0x2c,0x00,0xba,0x06,0x22,0xc2,0x0b,0x94,0x02,0xac,0x10,0xbb }, - 16, 0x95f0, 0, {0x00,0x2e,0xc1,0x08,0xa8,0x02,0xec,0x00,0xab,0x00,0x22,0x00,0x08,0xb0,0x06,0xf0 }, - 16, 0x9600, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x15,0xec,0x00,0xfb,0x04,0x3e,0x60 }, - 16, 0x9610, 0, {0x28,0x82,0x13,0x0e,0x08,0xcb,0x00,0x3a,0xc0,0x0f,0x8c,0x03,0xec,0x11,0xdb,0x20 }, - 16, 0x9620, 0, {0xb2,0x90,0x4b,0xa8,0x0b,0x2c,0x00,0xbb,0x00,0x2c,0xc0,0x0c,0x88,0x13,0xac,0x00 }, - 16, 0x9630, 0, {0xf3,0x00,0x36,0x06,0x48,0xb0,0x12,0xc4,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9640, 0, {0xe0,0x01,0xbc,0x00,0xfb,0x08,0x3d,0x40,0x8f,0xea,0x01,0xf4,0x00,0xff,0x01,0x2f }, - 16, 0x9650, 0, {0xc0,0x0f,0xd0,0x22,0xfc,0x04,0xaf,0x00,0x3f,0xc0,0x8f,0xe9,0x03,0x7c,0x00,0xff }, - 16, 0x9660, 0, {0x00,0x3f,0xc0,0x0f,0x90,0x43,0xfc,0x20,0xef,0x02,0x3f,0x00,0x8f,0xf0,0x03,0xb8 }, - 16, 0x9670, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x10,0xac,0x08,0xeb,0x00,0x12,0x40 }, - 16, 0x9680, 0, {0x0f,0x90,0x03,0x28,0x20,0xab,0x00,0x3a,0xc0,0x8f,0x85,0x83,0xac,0x10,0xf3,0x50 }, - 16, 0x9690, 0, {0x32,0x90,0x4c,0x34,0x13,0x6c,0x00,0xfb,0x00,0x3e,0xc0,0x0c,0x98,0x03,0x2c,0x40 }, - 16, 0x96a0, 0, {0xeb,0x80,0x32,0x12,0x0d,0xb0,0x0b,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x96b0, 0, {0x88,0x01,0x3c,0x10,0x0f,0x05,0xa2,0x50,0x0c,0x10,0x02,0x22,0x10,0x8f,0x00,0x23 }, - 16, 0x96c0, 0, {0xc0,0x0b,0x88,0x12,0x3c,0x00,0x9b,0x82,0x22,0xc0,0x08,0xb0,0x02,0x3c,0x00,0x8f }, - 16, 0x96d0, 0, {0xa0,0x2f,0xc0,0x08,0xb0,0x02,0x3c,0x08,0x8f,0x02,0x20,0x00,0x08,0xf0,0x03,0x26 }, - 16, 0x96e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4d,0x20,0x93,0x00,0x20,0xb2 }, - 16, 0x96f0, 0, {0x0b,0x10,0x02,0x01,0x00,0xa3,0x00,0x68,0xc0,0x0b,0x84,0x02,0xac,0x00,0xb3,0x80 }, - 16, 0x9700, 0, {0x20,0x40,0x0a,0x30,0x02,0x4c,0x00,0xa3,0x04,0x2c,0xc0,0x08,0x00,0x02,0x0d,0x00 }, - 16, 0x9710, 0, {0xa3,0x00,0x20,0x24,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9720, 0, {0x70,0x01,0x1c,0x20,0x97,0x80,0x23,0x60,0x08,0x78,0x12,0x3a,0x00,0x83,0x91,0x29 }, - 16, 0x9730, 0, {0xe4,0x0b,0x59,0x02,0x1e,0x00,0x97,0x90,0x20,0xfc,0x0a,0x78,0x02,0x1e,0x00,0x87 }, - 16, 0x9740, 0, {0x90,0x2d,0xe0,0x19,0x59,0x02,0x1e,0x80,0x83,0x80,0x61,0xa0,0x08,0x78,0x02,0x18 }, - 16, 0x9750, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x40,0xd3,0x32,0x30,0x06 }, - 16, 0x9760, 0, {0x0f,0x30,0x03,0x04,0x64,0xe3,0x01,0x38,0xc4,0x1f,0x30,0x07,0x8c,0x18,0xf1,0x00 }, - 16, 0x9770, 0, {0x30,0x4c,0x0e,0x30,0x03,0x4c,0x00,0xe3,0x00,0x2c,0xc0,0x0c,0x20,0x03,0x0e,0x00 }, - 16, 0x9780, 0, {0xe3,0x00,0x32,0x08,0x0c,0xb1,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9790, 0, {0x40,0x1d,0x9c,0x80,0xef,0x10,0x3d,0x44,0x4f,0xf1,0x07,0xcc,0x00,0xff,0x08,0x36 }, - 16, 0x97a0, 0, {0xc6,0xcf,0xb0,0x03,0xfc,0x00,0x97,0x00,0xbe,0xcc,0x0d,0xb1,0x03,0xfd,0x04,0xff }, - 16, 0x97b0, 0, {0x0c,0x3f,0xd2,0x9e,0xe0,0x4b,0xfd,0x20,0xff,0x02,0x3f,0x80,0x0e,0xf0,0x13,0xd0 }, - 16, 0x97c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xec,0xc0,0xcb,0x28,0x3e,0xc0 }, - 16, 0x97d0, 0, {0x0f,0x80,0x03,0xec,0x00,0xfb,0x01,0x32,0xe9,0x0c,0x28,0x03,0x2c,0x00,0xfb,0x00 }, - 16, 0x97e0, 0, {0x32,0xc0,0x0c,0xb4,0x83,0x2c,0x01,0xef,0x00,0xb2,0xc8,0x0c,0x20,0x03,0x6d,0x00 }, - 16, 0x97f0, 0, {0xcb,0x10,0x3e,0x00,0x0f,0xb2,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9800, 0, {0xc8,0x91,0x9c,0xc4,0x87,0x60,0x2d,0xc0,0x0b,0x60,0x02,0xdc,0x00,0xb7,0x12,0x20 }, - 16, 0x9810, 0, {0xcc,0x0a,0x70,0x02,0x1c,0xc0,0xb3,0x00,0xa0,0xc0,0xc8,0x70,0x22,0x1c,0x80,0xb7 }, - 16, 0x9820, 0, {0x24,0x21,0xc8,0x48,0x50,0x02,0x0c,0x80,0x87,0x10,0x2d,0x40,0x0b,0x72,0x82,0xf2 }, - 16, 0x9830, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x8e,0x02,0x87,0x80,0x2d,0xe0 }, - 16, 0x9840, 0, {0x0b,0x78,0x12,0xde,0x00,0xb7,0xa0,0x21,0xe0,0x08,0xf8,0x8e,0x1e,0x40,0xb7,0x88 }, - 16, 0x9850, 0, {0x21,0xe0,0x08,0x38,0x02,0x1e,0x40,0xb3,0xa1,0x20,0xe8,0x48,0xf8,0x82,0x5e,0x02 }, - 16, 0x9860, 0, {0x87,0x80,0x2d,0x22,0x0b,0x79,0x02,0xe0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9870, 0, {0x08,0x04,0xcc,0x04,0x83,0x02,0x2c,0xd4,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x00,0xa0 }, - 16, 0x9880, 0, {0xc0,0x8a,0x38,0x06,0x0c,0x00,0xb3,0x80,0x20,0xe1,0x48,0x39,0x12,0x2c,0x00,0xb3 }, - 16, 0x9890, 0, {0x00,0x22,0xc0,0x08,0xb0,0x82,0x6c,0x00,0x83,0x00,0x2c,0x48,0x0b,0x30,0x02,0xc2 }, - 16, 0x98a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xca,0x00,0x3f,0xa0 }, - 16, 0x98b0, 0, {0x0f,0xe4,0x03,0xd8,0x00,0xfa,0x00,0x32,0x80,0x0c,0xe8,0x03,0x28,0x00,0xfa,0x40 }, - 16, 0x98c0, 0, {0x32,0xa8,0x2c,0xa0,0x09,0x28,0x08,0xf2,0x00,0x32,0x80,0x0c,0xe4,0x03,0x68,0x00 }, - 16, 0x98d0, 0, {0xca,0x00,0x3f,0x80,0x0f,0xa0,0x03,0xfb,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x98e0, 0, {0x48,0x00,0xc0,0x00,0xf8,0x01,0x3e,0x12,0x0b,0x80,0x03,0xe0,0x40,0xf8,0x00,0x3e }, - 16, 0x98f0, 0, {0x00,0x4f,0x84,0x03,0xe0,0x04,0xf0,0x08,0x3e,0x00,0x4f,0x00,0x03,0xe0,0x00,0xf8 }, - 16, 0x9900, 0, {0x41,0x3e,0x00,0x2f,0x84,0x03,0xa0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0x9910, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe6,0x00,0xc9,0x12,0x3e,0x50 }, - 16, 0x9920, 0, {0x8f,0x90,0x83,0xe4,0x20,0xc1,0x00,0x3a,0x41,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00 }, - 16, 0x9930, 0, {0x30,0x68,0x0c,0x90,0x03,0x24,0x00,0xd9,0x00,0x3a,0x40,0x0e,0x98,0x03,0x24,0x00 }, - 16, 0x9940, 0, {0xc9,0x90,0x3e,0x69,0x0c,0x10,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9950, 0, {0x80,0x04,0x67,0x4a,0x89,0x80,0x2e,0x50,0x0b,0x90,0x02,0xe4,0x80,0xa9,0x00,0x22 }, - 16, 0x9960, 0, {0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x01,0x22,0x40,0x08,0x90,0x02,0x24,0x10,0x89 }, - 16, 0x9970, 0, {0x00,0x22,0x40,0x08,0x93,0x02,0x24,0x22,0x89,0x42,0x2c,0x60,0x48,0x90,0x02,0x20 }, - 16, 0x9980, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0x24,0x00,0x99,0x00,0x2e,0x40 }, - 16, 0x9990, 0, {0x0b,0x90,0x02,0xe4,0x00,0x89,0x00,0x2a,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x00 }, - 16, 0x99a0, 0, {0x23,0x40,0x08,0xd0,0x02,0x24,0x00,0x99,0x00,0x2a,0x40,0x0a,0x90,0x06,0x24,0x40 }, - 16, 0x99b0, 0, {0x89,0x41,0x2e,0x40,0x08,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x99c0, 0, {0x08,0x04,0x0c,0x80,0x91,0x20,0x2c,0x48,0x0b,0x10,0x02,0xc4,0x00,0xa1,0x20,0x20 }, - 16, 0x99d0, 0, {0x48,0x0b,0x10,0x02,0xc4,0x80,0xb1,0x20,0xa1,0x49,0x08,0x52,0x4a,0x04,0x80,0x81 }, - 16, 0x99e0, 0, {0x00,0x20,0x48,0x48,0x12,0x0a,0x04,0x80,0x81,0x20,0x2c,0x40,0x28,0x12,0x02,0x02 }, - 16, 0x99f0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x08,0xd8,0x04,0x3e,0x80 }, - 16, 0x9a00, 0, {0x0f,0x85,0x03,0xe0,0x00,0xc0,0x50,0x3a,0x14,0x0f,0xa5,0x03,0xe1,0x40,0xf8,0x02 }, - 16, 0x9a10, 0, {0x32,0x80,0x2c,0xc5,0x03,0x21,0x40,0xda,0x00,0x3a,0x14,0x0e,0x85,0x43,0x21,0x40 }, - 16, 0x9a20, 0, {0xc8,0x52,0x3e,0x14,0x0c,0x85,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9a30, 0, {0x88,0x1d,0xe4,0x44,0xe9,0x10,0x3f,0x44,0x4f,0xd0,0x02,0xfc,0x00,0xf9,0x12,0x3e }, - 16, 0x9a40, 0, {0x44,0x0f,0xd0,0x03,0xe4,0x40,0xfd,0x10,0x3e,0x44,0x4f,0x91,0x03,0xe4,0x40,0xe9 }, - 16, 0x9a50, 0, {0x40,0x3e,0x44,0x0f,0xd1,0x03,0xe4,0x40,0xf9,0x12,0x3f,0x40,0x0f,0x91,0x03,0xe6 }, - 16, 0x9a60, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xf6,0xa0,0xfd,0x80,0xb3,0x40 }, - 16, 0x9a70, 0, {0x0c,0x10,0x03,0x14,0x00,0xfd,0xa0,0x32,0x40,0x0f,0xd1,0x03,0xe4,0x00,0xf5,0x86 }, - 16, 0x9a80, 0, {0x33,0x60,0x2c,0x9a,0x83,0x24,0x04,0xfd,0xa8,0x22,0x40,0x0d,0x50,0x43,0xf4,0x00 }, - 16, 0x9a90, 0, {0xfd,0x00,0x33,0x40,0x0f,0x90,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9aa0, 0, {0x78,0x10,0xe1,0x00,0xb8,0x00,0x22,0x00,0x28,0x80,0x02,0x20,0x00,0xb8,0x00,0xa2 }, - 16, 0x9ab0, 0, {0x00,0x0b,0x8a,0x12,0xe0,0x00,0xb8,0x04,0x22,0x14,0x08,0x84,0x02,0x20,0x00,0xb8 }, - 16, 0x9ac0, 0, {0x40,0x20,0x00,0x88,0x80,0x02,0xe0,0x00,0xb8,0x00,0xa2,0x00,0x0b,0x80,0x02,0x0e }, - 16, 0x9ad0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x00,0xb1,0x42,0x20,0x40 }, - 16, 0x9ae0, 0, {0x08,0x10,0x02,0x04,0x00,0xb1,0x40,0x20,0x40,0x0b,0x10,0x06,0xc4,0x00,0xb1,0x40 }, - 16, 0x9af0, 0, {0x24,0x40,0x08,0x10,0x02,0x44,0x04,0xb1,0x00,0x60,0x40,0x09,0x10,0x02,0xc4,0x00 }, - 16, 0x9b00, 0, {0xb1,0x00,0x20,0x40,0x0b,0x10,0x02,0x12,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9b10, 0, {0x18,0x15,0xa4,0x00,0xb9,0x02,0x22,0x60,0x08,0x94,0x02,0x24,0x00,0xb9,0x01,0x22 }, - 16, 0x9b20, 0, {0x40,0x0b,0x90,0x06,0xe4,0x00,0xb9,0x20,0x26,0x40,0x08,0x94,0x02,0x64,0x08,0xb9 }, - 16, 0x9b30, 0, {0x00,0x22,0x40,0x08,0x92,0x02,0xec,0x08,0xb9,0x04,0x22,0x41,0x0b,0x10,0x02,0x06 }, - 16, 0x9b40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x10,0xf1,0x00,0x32,0x60 }, - 16, 0x9b50, 0, {0x0c,0x94,0x0b,0x25,0x00,0xf9,0x00,0x32,0x40,0x8f,0x94,0xd3,0xe4,0x00,0xf9,0x00 }, - 16, 0x9b60, 0, {0x36,0x40,0x4c,0x90,0x0b,0x64,0x00,0xf1,0x00,0x32,0x40,0x0d,0x92,0x12,0xe4,0x00 }, - 16, 0x9b70, 0, {0xf9,0x00,0x32,0x40,0x0f,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9b80, 0, {0x68,0x41,0xa4,0x00,0xf9,0x00,0x3c,0x40,0x8f,0x92,0x03,0xe4,0x00,0xf9,0x00,0x3e }, - 16, 0x9b90, 0, {0x40,0x0f,0x9c,0x03,0xe4,0x00,0xf9,0x00,0xba,0x40,0x2f,0x90,0x23,0xa4,0x00,0xf9 }, - 16, 0x9ba0, 0, {0x08,0xbe,0x40,0xcf,0x90,0x03,0xe4,0x10,0xf1,0x01,0x3e,0x41,0x0f,0x90,0x03,0xda }, - 16, 0x9bb0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0xc8,0xf8,0x00,0x3e,0x03 }, - 16, 0x9bc0, 0, {0x0c,0x84,0x03,0xa1,0x10,0xe8,0x00,0x32,0x00,0x8c,0x85,0x83,0xe0,0x00,0xc0,0x00 }, - 16, 0x9bd0, 0, {0x38,0x0c,0x2c,0x00,0x03,0x60,0x00,0xc8,0x00,0x3c,0x00,0x0d,0x80,0x02,0x20,0x10 }, - 16, 0x9be0, 0, {0xc8,0x20,0xb2,0x02,0x0f,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9bf0, 0, {0x28,0x05,0x39,0x10,0xbe,0x04,0x6f,0xa0,0x08,0xa0,0x02,0x3a,0x00,0x82,0x00,0xa2 }, - 16, 0x9c00, 0, {0x80,0x8d,0xec,0x03,0xa8,0x00,0x8a,0x00,0x23,0x80,0x08,0xa0,0x22,0x28,0x00,0x8e }, - 16, 0x9c10, 0, {0xcc,0x2f,0x80,0x08,0xe8,0xc2,0xb8,0x00,0x8e,0x60,0x23,0x90,0x0b,0xa0,0x02,0xca }, - 16, 0x9c20, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4e,0x08,0xb0,0x72,0x2c,0xd0 }, - 16, 0x9c30, 0, {0x28,0xb0,0x06,0x8c,0x01,0xa1,0x02,0x20,0xc0,0x08,0x38,0x02,0xcc,0x00,0x83,0x00 }, - 16, 0x9c40, 0, {0x20,0xc0,0x29,0x30,0x02,0x4c,0x00,0x81,0x00,0x2c,0xc0,0x08,0x32,0x02,0x0c,0x40 }, - 16, 0x9c50, 0, {0x83,0x00,0x20,0xf4,0x0b,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9c60, 0, {0xa0,0x01,0x1c,0x00,0xb4,0x00,0x2d,0xd0,0x48,0xf2,0x02,0x1e,0x21,0x85,0x20,0x20 }, - 16, 0x9c70, 0, {0xe8,0x09,0x72,0x02,0x8e,0x80,0x8f,0x01,0x20,0xc0,0x09,0x72,0x02,0x0e,0x80,0x87 }, - 16, 0x9c80, 0, {0x00,0x2d,0xcc,0x18,0x58,0x02,0x8e,0x00,0x85,0x00,0x21,0xc0,0x0b,0x72,0x02,0xe8 }, - 16, 0x9c90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xb4,0x80,0x2d,0xe0 }, - 16, 0x9ca0, 0, {0x0c,0x78,0x83,0x9a,0x00,0xed,0xd0,0x31,0xf4,0x0c,0x6a,0x03,0xde,0x82,0xc7,0x80 }, - 16, 0x9cb0, 0, {0x39,0xe0,0x0d,0xf8,0x83,0x5e,0xc2,0xc5,0x80,0x3d,0xe8,0x0c,0x68,0x03,0x12,0x00 }, - 16, 0x9cc0, 0, {0xcf,0x80,0x31,0xe0,0x0f,0x7e,0x83,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9cd0, 0, {0x08,0x0d,0xac,0x08,0xf8,0x00,0x3c,0xc0,0x0f,0xb3,0x03,0xec,0x00,0xf9,0x02,0x3e }, - 16, 0x9ce0, 0, {0xc8,0x0f,0xb0,0x03,0xed,0x40,0xfb,0x00,0xbe,0x80,0x0e,0xb3,0x03,0xed,0xc0,0xfb }, - 16, 0x9cf0, 0, {0x00,0x3e,0xd2,0x2e,0x80,0x03,0xec,0x02,0xf9,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xc2 }, - 16, 0x9d00, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xf0,0x91,0x33,0xe0 }, - 16, 0x9d10, 0, {0x8f,0xf8,0x03,0xfe,0x00,0xfd,0x80,0x3f,0xe0,0x0c,0x78,0x83,0x3f,0x00,0xcf,0x80 }, - 16, 0x9d20, 0, {0x3f,0xa0,0x0c,0xf8,0x03,0x3e,0x00,0xcd,0x80,0x3f,0xe0,0x0f,0xf8,0x13,0xfe,0x10 }, - 16, 0x9d30, 0, {0xff,0x80,0x3f,0x20,0x0f,0xf9,0x43,0xd0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9d40, 0, {0xa8,0x11,0x9c,0x00,0xb4,0xc1,0x31,0xc0,0x0b,0x70,0x02,0xd4,0x10,0xe5,0x20,0x2f }, - 16, 0x9d50, 0, {0xc8,0x0f,0x40,0x03,0x5c,0x00,0x87,0x00,0x2d,0x80,0x08,0x70,0x02,0x1c,0x40,0x87 }, - 16, 0x9d60, 0, {0x10,0x2d,0xc0,0x0b,0x76,0x02,0xdc,0x80,0xb7,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xea }, - 16, 0x9d70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9c,0x00,0xb6,0x22,0x21,0xd0 }, - 16, 0x9d80, 0, {0x0b,0x70,0x82,0xd8,0x40,0xb5,0x02,0x2d,0xc0,0x88,0x65,0x02,0x0c,0x00,0x87,0x18 }, - 16, 0x9d90, 0, {0x2c,0x04,0x08,0x30,0x02,0x8c,0x02,0x85,0x00,0x2d,0xc0,0x0b,0x70,0x46,0x90,0x10 }, - 16, 0x9da0, 0, {0xb6,0x00,0x2d,0x00,0x0b,0x70,0x22,0xc4,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9db0, 0, {0x60,0x14,0xcc,0x08,0xb2,0x00,0xa4,0xc0,0x0b,0x30,0x42,0xc6,0x10,0xa1,0x00,0x2c }, - 16, 0x9dc0, 0, {0xc0,0x0a,0x00,0x02,0x4c,0x00,0x83,0x00,0x2c,0x08,0x08,0x30,0x02,0x8c,0x00,0x83 }, - 16, 0x9dd0, 0, {0x00,0x2c,0xc0,0x0b,0x18,0x82,0xc4,0x00,0xb0,0x00,0x2c,0x40,0x0b,0x30,0x12,0xd8 }, - 16, 0x9de0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x15,0xac,0x00,0x38,0x00,0x32,0x50 }, - 16, 0x9df0, 0, {0x0f,0xf0,0x03,0xe6,0x20,0xfd,0x00,0x3f,0xc0,0x08,0xd0,0x02,0x3c,0x02,0xcb,0x80 }, - 16, 0x9e00, 0, {0x3c,0x50,0x2c,0xf0,0x0a,0xbc,0x00,0xc9,0x00,0x3f,0xc0,0x0f,0xbe,0x03,0xac,0x00 }, - 16, 0x9e10, 0, {0xfa,0x02,0x2e,0xf7,0x4f,0xf0,0x03,0xee,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9e20, 0, {0x80,0x00,0xec,0x00,0xf1,0x00,0x3a,0xf0,0x0f,0xb0,0x03,0xe9,0x00,0xf9,0x01,0x3e }, - 16, 0x9e30, 0, {0xc0,0x0f,0x90,0x13,0xec,0x00,0xf9,0x00,0x3e,0x55,0x0f,0xb0,0x01,0x6c,0x00,0xfb }, - 16, 0x9e40, 0, {0x02,0x3e,0xc0,0x0f,0x90,0x73,0xe0,0x00,0xf8,0x41,0x3e,0x00,0x0f,0x30,0x01,0xe0 }, - 16, 0x9e50, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xfc,0x00,0xfc,0x00,0x33,0xc0 }, - 16, 0x9e60, 0, {0x1f,0xf0,0x13,0xf0,0x08,0xfd,0x02,0x3f,0xc0,0x8d,0xc0,0x03,0x3c,0x00,0xcf,0xa0 }, - 16, 0x9e70, 0, {0x3f,0x80,0x0c,0x70,0x03,0x3c,0x10,0xfc,0x00,0x37,0xc0,0x0f,0xe0,0x03,0xb0,0x00 }, - 16, 0x9e80, 0, {0xfe,0x00,0x3f,0xc0,0x0c,0xf0,0x03,0x04,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9e90, 0, {0x84,0x04,0x6e,0x00,0xb9,0xc2,0xa2,0xf0,0x0b,0xb0,0x42,0xeb,0x00,0xb9,0x00,0x2e }, - 16, 0x9ea0, 0, {0xc0,0x0f,0x18,0x03,0x6c,0x00,0xd9,0x81,0x2e,0xb0,0x0a,0xb0,0x42,0x2c,0x00,0xba }, - 16, 0x9eb0, 0, {0xc6,0x2e,0xc0,0x0b,0x8c,0x02,0xe3,0x00,0xb8,0xc0,0x3c,0xa0,0x0d,0xb0,0x02,0x20 }, - 16, 0x9ec0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2f,0x00,0xb8,0x80,0x22,0xe2 }, - 16, 0x9ed0, 0, {0x0b,0xb0,0x02,0xe6,0x20,0xb9,0x00,0x2c,0xc0,0x08,0xb8,0x02,0x0c,0x00,0x8b,0x00 }, - 16, 0x9ee0, 0, {0x2e,0x30,0x48,0xb0,0x02,0x2c,0x00,0xb9,0xc0,0x2e,0xc1,0x0b,0x88,0x02,0xee,0x10 }, - 16, 0x9ef0, 0, {0xb9,0xc0,0x2e,0x20,0x19,0xb0,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9f00, 0, {0x08,0x04,0x0c,0x00,0xb0,0x00,0x20,0xc0,0x0b,0x30,0x06,0xc0,0x00,0x91,0x00,0x2c }, - 16, 0x9f10, 0, {0xc0,0x49,0x80,0x02,0x4c,0x04,0x91,0x00,0x2c,0x00,0x8a,0x30,0x0a,0x0c,0x04,0xb1 }, - 16, 0x9f20, 0, {0x00,0x2c,0xc0,0x1b,0x00,0x12,0x49,0x10,0xb1,0x00,0x2e,0x20,0x09,0x30,0x02,0x02 }, - 16, 0x9f30, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xb8,0x20,0x22,0xc0 }, - 16, 0x9f40, 0, {0x8b,0xf0,0x03,0xe0,0x08,0xfd,0x00,0x3f,0xc0,0x0c,0xa0,0x03,0x3c,0x00,0xcb,0x00 }, - 16, 0x9f50, 0, {0x3e,0x00,0x4c,0xf0,0x0a,0x3c,0x00,0xb9,0x00,0x37,0xc1,0x0f,0xa0,0x03,0xe0,0x00 }, - 16, 0x9f60, 0, {0xfa,0x00,0x3e,0x00,0x0d,0xf0,0x0b,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9f70, 0, {0xa0,0x1d,0xf0,0x01,0xfc,0x40,0x3f,0x80,0x4f,0xf0,0x02,0xf0,0x00,0xfd,0x00,0x3f }, - 16, 0x9f80, 0, {0xc1,0x0f,0xc0,0x03,0xfc,0x00,0xfd,0x00,0x3f,0x00,0x4f,0xf0,0x63,0xfc,0x00,0xfd }, - 16, 0x9f90, 0, {0x04,0x3f,0xc0,0x0f,0xc0,0x03,0xf0,0x80,0xfc,0x00,0x7b,0x00,0x0f,0xf0,0x43,0xe8 }, - 16, 0x9fa0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf8,0x00,0xc8,0x10,0x33,0x04 }, - 16, 0x9fb0, 0, {0x0c,0x40,0x02,0x34,0x00,0xc8,0x85,0x1f,0xc0,0x2d,0xd9,0x03,0xfc,0xc0,0xdb,0x28 }, - 16, 0x9fc0, 0, {0x37,0x64,0x0f,0xdb,0x03,0x3e,0x00,0xff,0x25,0x3f,0xc8,0x0e,0xf2,0x03,0xfe,0x20 }, - 16, 0x9fd0, 0, {0xff,0xa4,0x37,0xc4,0x0c,0xc8,0x03,0x30,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9fe0, 0, {0x80,0x10,0xe8,0x00,0x88,0x20,0x22,0x00,0x08,0x88,0x12,0x26,0x04,0x89,0x82,0x2e }, - 16, 0x9ff0, 0, {0xf4,0x48,0xb8,0x02,0xfc,0xc4,0x98,0xc2,0x22,0x7c,0x4b,0x9d,0x42,0x26,0x08,0xbf }, - 16, 0xa000, 0, {0x18,0x77,0xe4,0x08,0xf1,0x82,0xef,0x00,0xbb,0xd0,0x22,0xd8,0x08,0x90,0x83,0x60 }, - 16, 0xa010, 0, {0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x45,0xc8,0x04,0xa0,0x00,0x24,0x00 }, - 16, 0xa020, 0, {0x0a,0x00,0x02,0x0c,0x00,0x82,0x04,0x2c,0xe0,0x08,0x10,0x02,0xcc,0x80,0x83,0x00 }, - 16, 0xa030, 0, {0x24,0x00,0x0b,0x10,0x06,0xc8,0x01,0xb3,0x20,0x2c,0xc0,0x29,0x32,0x02,0xc8,0x08 }, - 16, 0xa040, 0, {0xb1,0x00,0x24,0xd0,0x08,0x82,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa050, 0, {0xc0,0x15,0xa8,0x00,0xa8,0x0c,0x26,0x00,0x0a,0x80,0x02,0x2c,0x14,0x8a,0x02,0x6e }, - 16, 0xa060, 0, {0xe0,0x08,0xb0,0x02,0x4c,0x08,0xa8,0x00,0x26,0x20,0x0b,0x9c,0x02,0xe4,0x00,0xbb }, - 16, 0xa070, 0, {0x04,0x22,0xc0,0x19,0xb0,0x02,0xe8,0x01,0xbb,0x11,0x02,0xc0,0x88,0x90,0x02,0xf0 }, - 16, 0xa080, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xec,0x02,0xea,0x40,0xb6,0x60 }, - 16, 0xa090, 0, {0x2e,0x98,0x0b,0x20,0x02,0xc8,0x02,0x3e,0xc0,0x0d,0x98,0x03,0xec,0x02,0xdb,0x88 }, - 16, 0xa0a0, 0, {0xb6,0x21,0x0f,0x88,0x03,0xac,0x08,0xfb,0x00,0x2c,0xc0,0x0e,0xb0,0x43,0xe5,0x80 }, - 16, 0xa0b0, 0, {0xf0,0x60,0x36,0xc0,0x0c,0x01,0x43,0x48,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa0c0, 0, {0xe0,0x01,0xbc,0x00,0xd6,0x01,0x3b,0x64,0x85,0xd9,0x03,0xf0,0x0c,0xff,0x00,0x3e }, - 16, 0xa0d0, 0, {0xc1,0x0f,0xfc,0x21,0xec,0x00,0xd7,0x90,0x3b,0x40,0x0f,0x50,0x03,0x3c,0x00,0xff }, - 16, 0xa0e0, 0, {0x00,0x3f,0xc0,0x8e,0xf0,0x03,0xf4,0x40,0xfd,0x88,0x3f,0xc0,0x2f,0xd0,0x02,0x78 }, - 16, 0xa0f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8c,0x00,0xda,0x40,0x3c,0x40 }, - 16, 0xa100, 0, {0x0f,0x10,0x03,0x48,0x00,0xf9,0x22,0x3c,0xc2,0x0e,0x90,0x83,0xec,0x02,0xdb,0x04 }, - 16, 0xa110, 0, {0x3a,0x08,0x0f,0x84,0x87,0xe8,0x00,0xcb,0x00,0x3e,0xc4,0x0e,0xb0,0x03,0xed,0x00 }, - 16, 0xa120, 0, {0xe8,0x42,0x3a,0xc0,0x0f,0x80,0x0b,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa130, 0, {0x88,0x05,0x2c,0x08,0x8a,0x00,0x2e,0x42,0x8b,0x90,0x02,0x28,0x18,0xbb,0x49,0x22 }, - 16, 0xa140, 0, {0xd0,0x38,0xbc,0x82,0xfc,0x00,0xe8,0x02,0x22,0x62,0xcb,0x9c,0x00,0xef,0x60,0xdf }, - 16, 0xa150, 0, {0x00,0x2f,0xc0,0x0b,0xf0,0x02,0xec,0x00,0x09,0x40,0x37,0xc0,0x0b,0x90,0x02,0x32 }, - 16, 0xa160, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x48,0x10,0x11,0x00,0x2c,0xa0 }, - 16, 0xa170, 0, {0x0b,0x20,0x02,0x44,0x00,0x90,0xc0,0x64,0x34,0x28,0x34,0x02,0xcc,0x00,0x93,0x84 }, - 16, 0xa180, 0, {0x28,0x40,0x0b,0x08,0x00,0xce,0x00,0x93,0x00,0x2c,0xc2,0x0a,0x30,0x02,0xc0,0x00 }, - 16, 0xa190, 0, {0xb2,0x40,0x22,0xc0,0x0b,0x20,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa1a0, 0, {0x70,0x01,0x1a,0x40,0x85,0x80,0x2d,0xa0,0x0b,0x68,0x06,0x16,0x80,0xbd,0x90,0x25 }, - 16, 0xa1b0, 0, {0x24,0x18,0x7b,0x42,0xde,0x40,0xa0,0x80,0x21,0xe0,0x0b,0x68,0x02,0xd6,0x00,0x97 }, - 16, 0xa1c0, 0, {0x90,0x2d,0xe0,0x0b,0x78,0x02,0xce,0x40,0x92,0x80,0x6d,0xe4,0x0b,0x78,0x02,0x08 }, - 16, 0xa1d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x28,0x00,0xd1,0x80,0x3c,0x88 }, - 16, 0xa1e0, 0, {0x0b,0x22,0x03,0x4e,0x80,0xf2,0xa1,0x3c,0x24,0x2a,0x39,0x03,0xcc,0x40,0xd3,0xac }, - 16, 0xa1f0, 0, {0x38,0xc5,0x0f,0x30,0x82,0xc8,0x00,0xd3,0x00,0x3c,0xc0,0x0e,0x30,0x13,0xc0,0x00 }, - 16, 0xa200, 0, {0xf1,0x00,0x38,0xc0,0x0f,0xa0,0x03,0x1a,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa210, 0, {0x40,0x1d,0xb8,0x10,0xfd,0x34,0x3e,0x80,0x0f,0xe0,0x03,0xee,0x00,0x72,0x00,0x3a }, - 16, 0xa220, 0, {0x00,0x0f,0xb0,0x63,0xec,0x40,0xf8,0x22,0x3e,0xc0,0x0f,0xf0,0x03,0xd4,0x40,0xff }, - 16, 0xa230, 0, {0x00,0x3f,0xd2,0x0f,0xf0,0x03,0xec,0x00,0xcf,0x00,0x37,0xc0,0x0f,0xf0,0x03,0xd0 }, - 16, 0xa240, 0, {0x06,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xee,0x00,0xeb,0x00,0x36,0xe0 }, - 16, 0xa250, 0, {0x0d,0xb0,0x03,0x20,0x00,0xf0,0x80,0x33,0xc0,0x08,0xb8,0x03,0x2c,0x80,0xcb,0x00 }, - 16, 0xa260, 0, {0x32,0x80,0x0f,0xa0,0x13,0x6e,0x08,0xcb,0x28,0x32,0xe0,0x0d,0xb4,0x83,0xe2,0x00 }, - 16, 0xa270, 0, {0xca,0x00,0x3e,0xe0,0x0c,0xa8,0x03,0x02,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa280, 0, {0xc8,0x11,0x8c,0x04,0x83,0x00,0x21,0xc0,0x48,0x70,0x02,0x10,0x00,0xb7,0x02,0x21 }, - 16, 0xa290, 0, {0xc0,0x4a,0x70,0x02,0x0d,0x48,0xd4,0x00,0x35,0xc0,0x0e,0x60,0x02,0xdc,0x00,0xa7 }, - 16, 0xa2a0, 0, {0x40,0x29,0xc0,0x09,0x72,0x02,0xd4,0x10,0xa6,0x02,0x2f,0xc8,0x08,0x70,0x02,0x12 }, - 16, 0xa2b0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x00,0xa7,0x80,0x20,0xe0 }, - 16, 0xa2c0, 0, {0x0a,0x38,0x02,0x1a,0x00,0xb5,0x80,0x21,0xe0,0x08,0xf8,0x22,0x5c,0x81,0x83,0x80 }, - 16, 0xa2d0, 0, {0x21,0xa1,0x0b,0x78,0x82,0x5a,0x10,0x83,0xa0,0x20,0xe8,0x0a,0x7b,0x02,0xda,0x00 }, - 16, 0xa2e0, 0, {0x97,0xc0,0x2d,0xe4,0x08,0xe8,0x02,0x08,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa2f0, 0, {0x08,0x14,0xcc,0x00,0x83,0x10,0x20,0xc0,0x0a,0x30,0x02,0x08,0x08,0xb3,0x70,0x20 }, - 16, 0xa300, 0, {0xf8,0x0a,0x30,0x42,0x4c,0x04,0x93,0x14,0x26,0xc4,0x0a,0x38,0x02,0xcc,0x00,0xa3 }, - 16, 0xa310, 0, {0x00,0x28,0xc0,0xaa,0x30,0x02,0xce,0x40,0xb3,0x88,0x2c,0xc0,0x28,0x30,0x0a,0x12 }, - 16, 0xa320, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa9,0x00,0xea,0x80,0xb6,0x90 }, - 16, 0xa330, 0, {0x2f,0x24,0x0b,0x39,0x04,0xbe,0xc0,0x33,0x92,0x0c,0xa0,0x0b,0x68,0x18,0xce,0xc0 }, - 16, 0xa340, 0, {0x33,0x80,0x0f,0xe9,0x43,0x78,0x00,0xca,0x00,0x32,0x80,0x0f,0xa0,0x13,0xf8,0x48 }, - 16, 0xa350, 0, {0xde,0x00,0x3e,0x80,0x0c,0xe0,0x02,0x3a,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa360, 0, {0x48,0x00,0xe0,0x24,0xf8,0x00,0x3e,0x12,0x0d,0x80,0x93,0xb0,0x28,0xf8,0x00,0xbc }, - 16, 0xa370, 0, {0x00,0x0f,0x84,0x03,0xa0,0x00,0xf0,0x00,0x3e,0x02,0x0e,0x80,0x00,0xe0,0x00,0xf8 }, - 16, 0xa380, 0, {0x01,0x3e,0x00,0x0d,0x80,0x03,0xe0,0x00,0xe8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xa390, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x00,0xb2,0x70 }, - 16, 0xa3a0, 0, {0x0f,0x90,0x01,0x04,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x98,0x03,0xe4,0x04,0xe9,0x08 }, - 16, 0xa3b0, 0, {0x3a,0x48,0x0c,0x9a,0x03,0xe4,0x00,0xf9,0x00,0x36,0x40,0x0b,0x10,0x0b,0x26,0x80 }, - 16, 0xa3c0, 0, {0xf1,0x80,0x32,0x40,0x0f,0x90,0x03,0xc2,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa3d0, 0, {0x80,0x04,0x64,0x00,0xb9,0x00,0x22,0x61,0x0b,0x90,0x02,0x24,0x08,0x89,0x00,0x2e }, - 16, 0xa3e0, 0, {0x40,0x0d,0x9a,0x02,0xe4,0x08,0xa9,0x00,0x22,0x78,0x0d,0x94,0x06,0xe4,0x10,0xb9 }, - 16, 0xa3f0, 0, {0x00,0x22,0x50,0x0b,0x90,0x02,0x25,0x80,0xb9,0x80,0x36,0x40,0x0b,0x90,0x02,0xe0 }, - 16, 0xa400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb5,0x00,0x23,0x42 }, - 16, 0xa410, 0, {0x0b,0xd0,0x0e,0xb4,0x00,0x89,0x04,0x2e,0x60,0x08,0x91,0x02,0xc4,0x04,0xb9,0x04 }, - 16, 0xa420, 0, {0x2a,0xc0,0x08,0x94,0x02,0xe4,0x10,0xb1,0x00,0x26,0x42,0x0a,0x90,0x02,0x24,0x00 }, - 16, 0xa430, 0, {0xb9,0x21,0x62,0x40,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa440, 0, {0x08,0x04,0x05,0x00,0xb5,0x40,0x21,0x50,0x4b,0x50,0x06,0x94,0x02,0x81,0x00,0x2c }, - 16, 0xa450, 0, {0x60,0x29,0x14,0x06,0xc5,0x00,0xa1,0x22,0x20,0x51,0x89,0x14,0x02,0xc4,0x00,0xb1 }, - 16, 0xa460, 0, {0x20,0x20,0x48,0x0b,0x14,0x02,0x04,0x01,0xb1,0x00,0x04,0x50,0x0b,0x10,0x02,0xc2 }, - 16, 0xa470, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x08,0xb8,0x00,0x32,0x00 }, - 16, 0xa480, 0, {0x8f,0x80,0x03,0xb0,0x00,0x88,0x00,0x3e,0x00,0x0c,0x80,0x03,0xe0,0x00,0xe8,0x04 }, - 16, 0xa490, 0, {0x3a,0x00,0x0c,0x80,0x02,0xe0,0x00,0xf8,0x50,0x36,0x00,0x0f,0x80,0x03,0x20,0x04 }, - 16, 0xa4a0, 0, {0xf8,0x01,0x12,0x00,0x4f,0x80,0x07,0xee,0x07,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa4b0, 0, {0x98,0x1d,0xe5,0x10,0xf9,0x40,0x3e,0x50,0x0f,0x94,0x02,0x65,0x01,0xfd,0x01,0x3d }, - 16, 0xa4c0, 0, {0x50,0x4f,0x50,0x13,0xe5,0x00,0xfd,0x10,0x1f,0x50,0x07,0xd4,0x43,0xd4,0x00,0xf9 }, - 16, 0xa4d0, 0, {0x10,0x1e,0x44,0x0f,0x94,0x03,0xd5,0x00,0xfd,0x40,0x3e,0x50,0x0f,0x52,0x83,0xee }, - 16, 0xa4e0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xe4,0x40,0xf9,0x60,0x3f,0x44 }, - 16, 0xa4f0, 0, {0x0f,0xd0,0xc3,0xe4,0x30,0xf9,0x01,0x3e,0x42,0x0c,0xd0,0x03,0xe7,0x80,0xdd,0xa0 }, - 16, 0xa500, 0, {0x33,0x40,0x0c,0xd0,0x03,0xfc,0x00,0xc9,0x90,0x3f,0x68,0x1e,0x91,0x03,0x34,0x00 }, - 16, 0xa510, 0, {0xfd,0x00,0x3e,0x68,0x0c,0x94,0x03,0x0e,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa520, 0, {0x39,0x10,0xe0,0x00,0xb8,0x42,0x2e,0x09,0x0b,0x84,0x02,0xe1,0x04,0xbe,0x00,0x2e }, - 16, 0xa530, 0, {0x10,0x08,0x80,0x22,0xc2,0x80,0x88,0x40,0x22,0x00,0x0a,0x80,0x02,0xe0,0x00,0xa8 }, - 16, 0xa540, 0, {0xd0,0x2e,0x10,0x4b,0x8a,0x03,0x60,0x00,0xba,0x00,0x2e,0x30,0x08,0x8a,0x02,0x86 }, - 16, 0xa550, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xc5,0x80,0xb1,0x60,0x6c,0xd0 }, - 16, 0xa560, 0, {0x0b,0x10,0x00,0xdc,0x0c,0xb5,0x00,0x2c,0x41,0x08,0x10,0x02,0xc5,0x80,0x91,0x10 }, - 16, 0xa570, 0, {0x68,0xc0,0x08,0x30,0x02,0xe4,0x0c,0x81,0x22,0x2c,0x50,0x08,0x10,0x42,0x04,0x00 }, - 16, 0xa580, 0, {0xa1,0x00,0x2c,0x5a,0x28,0x90,0x02,0x52,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa590, 0, {0x18,0x15,0xa4,0x00,0xb9,0x00,0x2e,0x41,0x0b,0x90,0x12,0xf4,0x80,0xbf,0x00,0x2e }, - 16, 0xa5a0, 0, {0x40,0x08,0x90,0x02,0xe4,0x00,0xa9,0x60,0x60,0x42,0x0a,0x94,0x12,0xe5,0x00,0xa9 }, - 16, 0xa5b0, 0, {0x00,0x2e,0x40,0x0b,0x90,0x02,0x64,0x20,0xb9,0x00,0x0e,0x40,0x09,0x90,0x02,0xc6 }, - 16, 0xa5c0, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0xf9,0x00,0x3e,0x41 }, - 16, 0xa5d0, 0, {0x0f,0x90,0x23,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0c,0x90,0x03,0xe4,0x04,0xd1,0xc0 }, - 16, 0xa5e0, 0, {0xba,0x70,0x0c,0x98,0x03,0xc4,0x00,0xc9,0x00,0x3e,0x40,0x0e,0x90,0x03,0x25,0x40 }, - 16, 0xa5f0, 0, {0xe9,0x40,0x3e,0x40,0x0c,0x10,0x03,0x68,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa600, 0, {0x68,0x01,0xa4,0x14,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x23,0xe4,0x08,0xf9,0xa0,0x3c }, - 16, 0xa610, 0, {0xc2,0x2f,0x90,0x03,0xc4,0x00,0xd9,0x80,0x3e,0x70,0x0f,0x91,0x43,0xe4,0x00,0xf9 }, - 16, 0xa620, 0, {0x00,0x3e,0x40,0x1f,0x90,0x13,0xe6,0x20,0xf9,0xa0,0x3c,0x40,0x4e,0x90,0x03,0x9a }, - 16, 0xa630, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf8,0x00,0x3e,0x02 }, - 16, 0xa640, 0, {0x0f,0x80,0x13,0x20,0x0c,0xfc,0x01,0x3e,0x00,0x0c,0x80,0x03,0xe0,0x00,0xc8,0x50 }, - 16, 0xa650, 0, {0x32,0x00,0x0f,0x80,0x0b,0x20,0x08,0xf8,0x00,0x32,0x00,0x2c,0x80,0x43,0xe0,0x40 }, - 16, 0xa660, 0, {0xf8,0x02,0x3a,0x00,0x8f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa670, 0, {0xa8,0x85,0x28,0x08,0x3a,0x00,0x0f,0x80,0x4b,0xa1,0x02,0x28,0x00,0xba,0x82,0x2e }, - 16, 0xa680, 0, {0x88,0x48,0xe4,0x02,0xe8,0x00,0xae,0x90,0xa3,0x90,0x0b,0xe0,0x00,0x38,0x00,0xba }, - 16, 0xa690, 0, {0x00,0x37,0xa0,0x08,0xa0,0x02,0xf8,0x00,0x9e,0xe0,0x22,0x80,0x0b,0xa0,0x23,0x42 }, - 16, 0xa6a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x10,0x33,0x00,0x2c,0xd0 }, - 16, 0xa6b0, 0, {0x0b,0x14,0x02,0x0c,0x00,0xb2,0x91,0x2c,0xd0,0x08,0x3e,0x02,0x4c,0x00,0x83,0x40 }, - 16, 0xa6c0, 0, {0x24,0xc2,0x0b,0x36,0x00,0x8c,0x00,0xb3,0x00,0x20,0xc0,0x09,0xb0,0x02,0xce,0x00 }, - 16, 0xa6d0, 0, {0xb3,0xcc,0x68,0xc0,0x0b,0x30,0x02,0x02,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa6e0, 0, {0xe0,0x01,0x1c,0x88,0xb7,0x25,0x2d,0xc0,0x8b,0x58,0x1a,0x1c,0x08,0xb6,0x00,0x2d }, - 16, 0xa6f0, 0, {0xc0,0x08,0x74,0x02,0xdc,0x40,0xa5,0x00,0x25,0xc0,0x1b,0x78,0x02,0x94,0x08,0xb7 }, - 16, 0xa700, 0, {0x80,0x25,0xe3,0x0a,0x71,0x02,0xdc,0x00,0x97,0x83,0x21,0xc8,0x8b,0xf1,0x02,0x48 }, - 16, 0xa710, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1f,0x00,0xf7,0xe2,0x7d,0xe0 }, - 16, 0xa720, 0, {0x0f,0x58,0x43,0x1e,0x18,0xf6,0x80,0x7c,0xe0,0x2c,0x68,0x02,0x5e,0x90,0xc3,0x80 }, - 16, 0xa730, 0, {0x35,0xe0,0x0f,0xf8,0x03,0x9e,0x04,0xff,0xa1,0x20,0xa1,0x0d,0x78,0x03,0xd6,0x00 }, - 16, 0xa740, 0, {0xf7,0x80,0x39,0xf8,0x0f,0x78,0x03,0x0a,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa750, 0, {0x48,0x1d,0xac,0x00,0xfb,0x40,0x7f,0x41,0x0f,0x10,0x03,0xec,0x04,0xfa,0x00,0x3e }, - 16, 0xa760, 0, {0xd0,0x0f,0xa0,0x03,0xed,0x00,0xe9,0x00,0x2a,0x00,0x0f,0xb0,0x03,0x64,0x00,0xfb }, - 16, 0xa770, 0, {0x40,0x3e,0xc0,0x0d,0xb0,0x03,0xe4,0x00,0xd3,0x00,0x36,0xc0,0x0f,0x38,0x03,0xc2 }, - 16, 0xa780, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x48,0xcf,0xc0,0x33,0x60 }, - 16, 0xa790, 0, {0x8c,0xc8,0x43,0xd6,0x00,0xcc,0x94,0x3f,0xb0,0x0d,0xf8,0x03,0x7f,0x00,0xdf,0x80 }, - 16, 0xa7a0, 0, {0x3f,0x60,0x0f,0xd8,0x03,0xde,0x00,0xcf,0xca,0x3d,0x60,0x0c,0xf8,0x13,0x3a,0x44 }, - 16, 0xa7b0, 0, {0xdd,0x80,0x3f,0xe0,0x0f,0xf8,0x43,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa7c0, 0, {0xa8,0x11,0x9c,0x00,0x8f,0x11,0x33,0xc0,0x48,0x41,0x12,0xc4,0x48,0x84,0x11,0x2c }, - 16, 0xa7d0, 0, {0xec,0x2a,0xba,0x03,0x3c,0x40,0xd7,0x48,0x2d,0x41,0x0b,0x60,0x02,0xd4,0x00,0xd7 }, - 16, 0xa7e0, 0, {0x01,0x3d,0xc0,0x0d,0xf0,0x03,0x5a,0x00,0x84,0x18,0x2d,0xc0,0x0b,0x70,0x03,0x6a }, - 16, 0xa7f0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x8c,0x08,0x87,0x00,0x21,0x40 }, - 16, 0xa800, 0, {0x09,0x40,0x02,0xd4,0x00,0xa4,0x92,0x2d,0xc8,0x09,0x62,0x82,0x5c,0x00,0x87,0x00 }, - 16, 0xa810, 0, {0x2d,0xc0,0x0b,0x50,0x02,0xfc,0x00,0x87,0x00,0x2d,0x04,0x08,0x70,0x02,0x1c,0x80 }, - 16, 0xa820, 0, {0xb5,0x00,0x2d,0xc0,0x0b,0xf0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa830, 0, {0x60,0x10,0xcc,0x00,0x83,0x00,0x20,0x40,0x09,0x00,0x22,0xc7,0x00,0xa0,0x41,0x2c }, - 16, 0xa840, 0, {0xc1,0x4b,0x08,0x02,0x2c,0x00,0x93,0x40,0x2c,0x7c,0x0b,0x38,0x02,0xc7,0x20,0x93 }, - 16, 0xa850, 0, {0x00,0x2c,0xc0,0x09,0x30,0x02,0x4f,0x84,0xb0,0x80,0x2c,0xc0,0x0b,0x32,0x10,0x50 }, - 16, 0xa860, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x15,0xbc,0x02,0xcf,0x00,0xb2,0x40 }, - 16, 0xa870, 0, {0x0d,0x10,0x03,0xe8,0x24,0xeb,0xc1,0x3e,0xc0,0x2d,0x98,0x13,0x7c,0x0a,0xc2,0x43 }, - 16, 0xa880, 0, {0x3e,0xb0,0x0f,0xa9,0x03,0xe9,0x20,0xcf,0x00,0x3e,0xc0,0x8c,0xf0,0x03,0x0d,0x20 }, - 16, 0xa890, 0, {0xfa,0xc0,0x3f,0xc0,0x0f,0x74,0x01,0x2a,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa8a0, 0, {0x80,0x00,0xec,0x00,0xfb,0x02,0x3a,0x40,0x8e,0x90,0x03,0xe8,0x14,0x5b,0x50,0x3c }, - 16, 0xa8b0, 0, {0x50,0x4e,0x84,0x03,0xec,0x00,0xf8,0x40,0x3e,0x80,0x07,0x81,0x03,0xec,0x08,0xf3 }, - 16, 0xa8c0, 0, {0x00,0x3a,0xc0,0x9f,0x30,0x03,0xec,0x00,0xcb,0x20,0x3e,0xc0,0x0f,0xb0,0x23,0xe8 }, - 16, 0xa8d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x90,0xfc,0x00,0xff,0x00,0x3f,0x40 }, - 16, 0xa8e0, 0, {0x0f,0xd0,0x03,0x38,0x20,0xcf,0x08,0x32,0xc1,0x0e,0xd0,0x03,0xfc,0x00,0xfe,0x08 }, - 16, 0xa8f0, 0, {0x31,0xe5,0x0e,0xe4,0x03,0x3a,0x00,0xff,0x00,0x33,0x80,0x0f,0xf0,0x2b,0x24,0x00 }, - 16, 0xa900, 0, {0xcc,0xa0,0x3f,0xc0,0x0f,0xf0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa910, 0, {0x80,0x04,0x6c,0x00,0xbb,0x00,0x3a,0x69,0x0b,0x90,0x6e,0x08,0x00,0x83,0x41,0x36 }, - 16, 0xa920, 0, {0x40,0xc8,0x88,0xc6,0xec,0x00,0x88,0x40,0x36,0x80,0x0d,0xa8,0x03,0x6e,0x50,0xbb }, - 16, 0xa930, 0, {0x00,0x36,0xc0,0x0b,0xb0,0x02,0x24,0x00,0xd9,0x08,0x2e,0xc0,0x0b,0xb0,0x03,0xe0 }, - 16, 0xa940, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xbb,0x00,0x2e,0x60 }, - 16, 0xa950, 0, {0x03,0x80,0x02,0x20,0x00,0x89,0x01,0x22,0x58,0x08,0x98,0x22,0xec,0x01,0xab,0x00 }, - 16, 0xa960, 0, {0x22,0x00,0x0a,0x10,0x02,0x28,0x00,0xbb,0x00,0x22,0x40,0x0b,0xb0,0x02,0x28,0x00 }, - 16, 0xa970, 0, {0x8a,0x00,0x2e,0xc0,0x0b,0xb0,0x42,0x20,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa980, 0, {0x08,0x04,0x0c,0x00,0xb3,0x00,0x28,0x40,0x8b,0x00,0x02,0x02,0x40,0x89,0x01,0x24 }, - 16, 0xa990, 0, {0xd2,0x28,0x10,0x02,0xcc,0x00,0x83,0x10,0x24,0x20,0x08,0x08,0x02,0x4e,0x00,0xb3 }, - 16, 0xa9a0, 0, {0x04,0xa0,0xc0,0x0b,0x30,0x02,0x08,0x88,0x92,0x00,0x2c,0xc0,0x0b,0xb0,0x02,0xc2 }, - 16, 0xa9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xff,0x00,0x3e,0x00 }, - 16, 0xa9c0, 0, {0x0f,0x80,0x02,0x20,0x10,0x89,0x50,0x22,0xd8,0x2e,0x96,0x22,0xfc,0x00,0xeb,0x40 }, - 16, 0xa9d0, 0, {0x32,0xc0,0x0a,0x90,0x03,0x28,0x00,0xff,0x00,0x22,0x00,0x0f,0xb0,0x03,0x2c,0xa0 }, - 16, 0xa9e0, 0, {0xc8,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x00,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa9f0, 0, {0xa0,0x19,0xfc,0x00,0xff,0x0c,0x3b,0x00,0x0f,0xc0,0x02,0x70,0x90,0xfd,0x00,0x3e }, - 16, 0xaa00, 0, {0xc9,0x0f,0x96,0xc3,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x04,0xff }, - 16, 0xaa10, 0, {0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xec,0x00,0xfc,0x00,0x3f,0xc0,0x0f,0x70,0x03,0xe8 }, - 16, 0xaa20, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xdc,0x80,0xfb,0x28,0x3f,0x00 }, - 16, 0xaa30, 0, {0x0c,0xc1,0x0b,0xf1,0x02,0xed,0x00,0x37,0x30,0x2c,0xf1,0x03,0xb2,0x40,0xff,0x00 }, - 16, 0xaa40, 0, {0xbb,0xc0,0x0f,0x48,0x06,0xb2,0x00,0xfc,0x80,0x3b,0xcc,0x0c,0xf0,0x03,0x70,0x80 }, - 16, 0xaa50, 0, {0xdf,0x28,0x33,0x04,0x0f,0xf4,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaa60, 0, {0x80,0x10,0xff,0x40,0xbf,0x60,0x2e,0x21,0x08,0x82,0x02,0x20,0x00,0xa9,0x28,0x2a }, - 16, 0xaa70, 0, {0x00,0x09,0xfa,0x02,0x20,0x00,0xbf,0x51,0x23,0xd8,0x09,0x98,0x02,0xe4,0x30,0xb0 }, - 16, 0xaa80, 0, {0x00,0x23,0xd0,0x08,0xf5,0xa2,0x25,0xa4,0x8f,0x42,0x3c,0x10,0x0b,0xb0,0x0a,0x20 }, - 16, 0xaa90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xb3,0x08,0x2c,0x00 }, - 16, 0xaaa0, 0, {0x28,0x00,0x1a,0xc0,0x84,0x20,0x00,0x24,0xc8,0x4b,0x31,0x42,0xc0,0x00,0x93,0x02 }, - 16, 0xaab0, 0, {0x20,0xc6,0x08,0x00,0x06,0xc0,0x81,0xb3,0x00,0x2c,0xd8,0x09,0x32,0x02,0xa0,0x40 }, - 16, 0xaac0, 0, {0x93,0x01,0x24,0x4c,0x0b,0x32,0x02,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaad0, 0, {0xc0,0x11,0xac,0x00,0xbb,0x02,0x2e,0x0a,0x08,0x80,0x82,0x60,0x00,0xa8,0x00,0x2e }, - 16, 0xaae0, 0, {0xe0,0x1b,0xb0,0x02,0x62,0x01,0x3b,0x00,0x22,0xc1,0x09,0x90,0x02,0xe2,0x00,0xbb }, - 16, 0xaaf0, 0, {0x60,0x26,0xc1,0x08,0xb0,0x2a,0x26,0x00,0x9b,0x04,0x2e,0x21,0x0b,0xb0,0x02,0x30 }, - 16, 0xab00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xec,0x10,0xfb,0x00,0x3e,0x10 }, - 16, 0xab10, 0, {0x08,0x84,0x13,0xec,0x02,0xa9,0x04,0x36,0x20,0x0f,0xb0,0x03,0xee,0x80,0xfb,0x00 }, - 16, 0xab20, 0, {0x3a,0xc0,0x0c,0xa0,0x03,0xa2,0x80,0x79,0x40,0x1e,0xc0,0x8c,0xb0,0x63,0x6a,0x10 }, - 16, 0xab30, 0, {0xd3,0x00,0x36,0xa2,0x07,0xb0,0x03,0x00,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xab40, 0, {0xe0,0x01,0xbc,0x00,0xff,0x00,0x3e,0x20,0x4d,0x41,0x03,0x9c,0x00,0xfd,0x20,0xab }, - 16, 0xab50, 0, {0x00,0x0c,0xf0,0x03,0xb8,0x00,0xf7,0x00,0x3f,0xc0,0x4d,0xc9,0x03,0xf4,0x00,0xff }, - 16, 0xab60, 0, {0x00,0x3b,0xc0,0x2e,0xf0,0x00,0xf0,0x00,0xef,0x00,0x3f,0x00,0x4b,0x70,0x03,0xf8 }, - 16, 0xab70, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x80,0xeb,0x00,0x7e,0x10 }, - 16, 0xab80, 0, {0x2e,0x84,0x03,0xec,0x00,0xe0,0x00,0x32,0x50,0x0f,0xb0,0x86,0x25,0x00,0xdb,0x20 }, - 16, 0xab90, 0, {0x3a,0xc0,0x0d,0xb0,0x63,0xe1,0x10,0xfb,0x48,0x38,0xc1,0x0f,0x30,0x03,0x2c,0x04 }, - 16, 0xaba0, 0, {0xfb,0x08,0x32,0xc0,0x0c,0xb0,0x0b,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xabb0, 0, {0xc8,0x05,0x3c,0x00,0x8f,0x00,0x64,0x29,0x28,0x80,0x03,0xec,0x02,0xe8,0x04,0xa8 }, - 16, 0xabc0, 0, {0x56,0x08,0xfc,0x07,0xe0,0x00,0x0f,0xa0,0xbf,0xc0,0x0b,0x95,0x02,0xa0,0x00,0xbb }, - 16, 0xabd0, 0, {0x05,0x37,0xc0,0x89,0xf0,0x0a,0x0d,0xc8,0xbf,0x08,0x2a,0x80,0x08,0xf0,0x02,0x32 }, - 16, 0xabe0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x01,0xb3,0x02,0x24,0xe0 }, - 16, 0xabf0, 0, {0x0a,0x30,0x12,0x80,0x03,0xa3,0x00,0xa8,0x00,0x02,0xb8,0x22,0xc0,0x00,0xb3,0x00 }, - 16, 0xac00, 0, {0x28,0xc1,0x0b,0x04,0x02,0x08,0x00,0xb9,0x40,0x28,0xc0,0x0b,0x30,0x02,0x03,0x04 }, - 16, 0xac10, 0, {0xb3,0x44,0x20,0x00,0x4a,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xac20, 0, {0x20,0x01,0x1e,0x20,0x17,0xa0,0x65,0xec,0x08,0x38,0x02,0xc2,0x41,0xb3,0x92,0x2b }, - 16, 0xac30, 0, {0x64,0x0a,0x38,0x02,0x36,0x01,0xb7,0x90,0x2d,0xe0,0x03,0xf8,0x00,0x9a,0x00,0xb5 }, - 16, 0xac40, 0, {0x80,0x2d,0xe0,0x89,0x78,0x12,0x1e,0x00,0xb7,0x80,0x29,0xe0,0x0a,0x78,0x02,0x08 }, - 16, 0xac50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x73,0xb0,0x24,0xc8 }, - 16, 0xac60, 0, {0x4e,0x30,0x0a,0x80,0x02,0xe2,0x00,0x38,0x94,0x0e,0x31,0xa2,0xc8,0x00,0x73,0x00 }, - 16, 0xac70, 0, {0x18,0xc4,0x05,0x00,0x03,0x00,0x00,0xf3,0x00,0x38,0xc0,0x07,0xb1,0x03,0x00,0x00 }, - 16, 0xac80, 0, {0xf3,0x01,0x30,0x41,0x0e,0xb0,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xac90, 0, {0x40,0x1d,0xbd,0x00,0xef,0x10,0x26,0xc8,0x03,0xb1,0x03,0xe0,0x00,0xea,0x81,0x78 }, - 16, 0xaca0, 0, {0xc5,0x0c,0xb5,0xe3,0xdc,0x00,0xc3,0x00,0x3e,0xc1,0x0f,0xf0,0x83,0xb0,0x00,0xff }, - 16, 0xacb0, 0, {0x00,0x37,0xc0,0x0d,0xf4,0x03,0xe4,0x00,0xf7,0x00,0x3f,0x40,0x0d,0xf0,0x03,0xd0 }, - 16, 0xacc0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xed,0x10,0xcb,0x28,0x3e,0xc0 }, - 16, 0xacd0, 0, {0x0d,0xb0,0x13,0xac,0x10,0xfb,0x00,0x3a,0x80,0x04,0xb4,0x03,0xac,0x00,0xfb,0x04 }, - 16, 0xace0, 0, {0x3e,0xc0,0x0f,0xa4,0xb3,0xe0,0x00,0xfb,0x80,0x32,0xc0,0x0f,0xb0,0x03,0xe8,0x00 }, - 16, 0xacf0, 0, {0xfb,0x48,0xb2,0x80,0x0f,0xb0,0x43,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xad00, 0, {0x48,0x11,0x9c,0x02,0x87,0x44,0x38,0xc0,0x8d,0x30,0x02,0x4c,0x00,0xff,0x00,0x21 }, - 16, 0xad10, 0, {0xc0,0x08,0x70,0x03,0x9c,0x00,0xb3,0x50,0x21,0xd4,0x4e,0x62,0x02,0xd0,0x00,0xbf }, - 16, 0xad20, 0, {0x00,0x35,0xd4,0x09,0x70,0x22,0xd8,0x00,0xbf,0x22,0x21,0xc0,0x0b,0x72,0x02,0xd2 }, - 16, 0xad30, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x40,0x87,0x80,0x2d,0xe0 }, - 16, 0xad40, 0, {0x09,0x78,0x02,0xde,0x00,0xb6,0x80,0x29,0xa1,0x28,0x7a,0x32,0xde,0x00,0x37,0xa0 }, - 16, 0xad50, 0, {0x25,0xe0,0x09,0x78,0x06,0xd2,0x00,0xb7,0x80,0x21,0xe8,0x0b,0x79,0x02,0xde,0x00 }, - 16, 0xad60, 0, {0xb7,0x90,0x21,0xe0,0x0b,0x79,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xad70, 0, {0x48,0x14,0xcc,0x04,0x83,0x01,0x28,0xc0,0x89,0xb0,0x0a,0x4f,0x00,0xb2,0x00,0x20 }, - 16, 0xad80, 0, {0xc4,0x88,0x30,0x16,0xcf,0x00,0xbb,0x04,0x20,0xc1,0x0a,0x32,0x06,0xc2,0x00,0xb3 }, - 16, 0xad90, 0, {0x00,0x24,0xc0,0x09,0x30,0x42,0xef,0x10,0xb3,0x00,0x20,0xc0,0x0b,0x30,0x02,0xd2 }, - 16, 0xada0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0x4a,0x00,0x3e,0x80 }, - 16, 0xadb0, 0, {0x2d,0xa0,0x0b,0xaa,0x80,0xfe,0x00,0x2b,0x80,0x0c,0xa0,0x43,0xfb,0x30,0xfa,0x00 }, - 16, 0xadc0, 0, {0x3e,0x80,0x0f,0xa0,0x83,0xfa,0x04,0xfe,0x18,0x22,0x80,0x0f,0xa0,0x03,0xfa,0x84 }, - 16, 0xadd0, 0, {0xf2,0x00,0x33,0xa2,0x0f,0xa0,0x03,0xf2,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xade0, 0, {0x48,0x00,0xe0,0x00,0xf0,0x00,0x3e,0x00,0x2f,0x80,0x03,0xa0,0x20,0xfc,0x02,0x3e }, - 16, 0xadf0, 0, {0x00,0x1f,0x84,0x03,0xa0,0x00,0xf8,0x40,0x3e,0x00,0x4f,0x80,0x01,0xe0,0x40,0xf8 }, - 16, 0xae00, 0, {0x40,0x3e,0x00,0x0d,0x80,0x13,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xae10, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc6,0x00,0xd9,0x00,0x36,0x40 }, - 16, 0xae20, 0, {0x0f,0x90,0x0b,0x04,0x00,0xc9,0x00,0x36,0x68,0x6c,0x94,0x03,0xe4,0x20,0xb9,0x90 }, - 16, 0xae30, 0, {0x36,0x40,0x0c,0x94,0x03,0xe4,0x00,0x29,0x80,0x3e,0x40,0x0f,0x90,0x03,0x24,0x20 }, - 16, 0xae40, 0, {0xc9,0x00,0x36,0x40,0x0f,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xae50, 0, {0x80,0x04,0x66,0x50,0x89,0x00,0x20,0x50,0x08,0x90,0x02,0x24,0x09,0xd9,0x00,0x20 }, - 16, 0xae60, 0, {0x48,0x48,0x90,0x06,0xe4,0x04,0x99,0xa0,0x22,0x40,0x0d,0xb8,0x22,0x64,0x00,0x09 }, - 16, 0xae70, 0, {0x50,0x32,0x40,0x0b,0x90,0x02,0x27,0x90,0x89,0x40,0x2a,0x40,0x0b,0x90,0x02,0xe0 }, - 16, 0xae80, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0x99,0x00,0x66,0x42 }, - 16, 0xae90, 0, {0x0a,0xd0,0x12,0x34,0x00,0x85,0x00,0x26,0x40,0x4a,0x90,0x02,0xe4,0x01,0xb9,0x01 }, - 16, 0xaea0, 0, {0x24,0x40,0x58,0x90,0x12,0xc4,0x00,0x29,0x40,0x2e,0x40,0x0b,0x10,0x0a,0x24,0x80 }, - 16, 0xaeb0, 0, {0x89,0x05,0x26,0x41,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaec0, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0x61,0x48,0x08,0x52,0x02,0x14,0x81,0x95,0x20,0x20 }, - 16, 0xaed0, 0, {0x40,0x0a,0x36,0x02,0xc4,0x00,0xb1,0x20,0x00,0x48,0x41,0x10,0x42,0x44,0x01,0xa1 }, - 16, 0xaee0, 0, {0x00,0x24,0x48,0x0b,0x12,0x12,0x04,0x80,0x81,0x20,0x28,0x48,0x0b,0x12,0x02,0xca }, - 16, 0xaef0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xd8,0x50,0x36,0x00 }, - 16, 0xaf00, 0, {0x0e,0x85,0x23,0x21,0x42,0x8c,0x54,0x34,0x14,0x0e,0x80,0x02,0xe1,0x40,0xf8,0x50 }, - 16, 0xaf10, 0, {0x36,0x14,0x04,0x80,0x03,0xe1,0x44,0xe8,0x50,0x7e,0x15,0x0f,0x85,0x03,0x21,0x42 }, - 16, 0xaf20, 0, {0x4a,0x00,0x36,0x14,0x0f,0x80,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaf30, 0, {0x98,0x1d,0xc4,0x40,0xf9,0x10,0x1e,0x44,0x4e,0x91,0x03,0xe4,0x40,0xf9,0x10,0x3f }, - 16, 0xaf40, 0, {0xc0,0x0d,0x91,0x03,0xf4,0x00,0xd9,0x14,0x3e,0x44,0x0f,0x90,0x03,0x74,0x00,0xdd }, - 16, 0xaf50, 0, {0x00,0x7a,0x44,0x0f,0x91,0x03,0xf4,0x40,0xf9,0x38,0x3f,0x44,0x0f,0x93,0x83,0xe7 }, - 16, 0xaf60, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xf6,0x80,0xf9,0xa4,0x3f,0x68 }, - 16, 0xaf70, 0, {0x0e,0x9e,0x43,0x67,0x80,0xd9,0xe4,0x3f,0x41,0x0f,0xd8,0x43,0x04,0x00,0xed,0xc0 }, - 16, 0xaf80, 0, {0x36,0x40,0x0c,0x90,0x03,0xe4,0x00,0xd5,0x40,0x32,0x40,0x0c,0x90,0x03,0xf4,0x00 }, - 16, 0xaf90, 0, {0xdd,0x00,0x32,0x40,0x2c,0x9a,0x03,0xc6,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xafa0, 0, {0x38,0x10,0xe0,0x00,0xe8,0xc0,0x2e,0x14,0x4d,0x8f,0x22,0x23,0xc0,0xf8,0xf0,0xaa }, - 16, 0xafb0, 0, {0x00,0x0c,0x80,0x03,0xa2,0xa0,0xd8,0x82,0x22,0x00,0x08,0x80,0x02,0xe8,0x00,0xd8 }, - 16, 0xafc0, 0, {0x80,0x2a,0x00,0x08,0x80,0x02,0xe8,0x08,0x88,0xa8,0x36,0x00,0x48,0x8a,0x82,0xce }, - 16, 0xafd0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x48,0x2e,0x40 }, - 16, 0xafe0, 0, {0x0a,0x12,0x22,0x44,0x00,0x91,0x04,0xa4,0x41,0x0a,0x94,0x06,0x24,0x00,0x91,0x42 }, - 16, 0xaff0, 0, {0x24,0x41,0x09,0x10,0x02,0xe4,0x01,0x91,0x20,0x24,0x40,0x09,0x10,0x02,0xc4,0x01 }, - 16, 0xb000, 0, {0x91,0x00,0x2c,0x40,0x09,0x14,0x02,0xc2,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb010, 0, {0x18,0x15,0xa4,0x00,0xa9,0x00,0x2e,0x40,0x48,0x10,0x02,0x24,0x00,0xb9,0x40,0xaa }, - 16, 0xb020, 0, {0x40,0x18,0xb0,0x02,0xe4,0x08,0x99,0x00,0x22,0x40,0x19,0x90,0x46,0xe4,0x80,0x99 }, - 16, 0xb030, 0, {0x04,0x2e,0x40,0x09,0x90,0x02,0xe4,0x01,0x99,0x04,0x26,0x50,0x09,0x90,0x02,0xc6 }, - 16, 0xb040, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe4,0x00,0xf9,0x06,0x3c,0x40 }, - 16, 0xb050, 0, {0x0a,0x90,0x03,0x64,0x02,0xd9,0x00,0xb6,0x50,0x0e,0x90,0x23,0x26,0x01,0xf9,0x00 }, - 16, 0xb060, 0, {0x36,0x40,0x29,0x94,0x83,0xe4,0x00,0xd9,0x48,0x36,0x40,0x0d,0x90,0x03,0xc7,0x00 }, - 16, 0xb070, 0, {0xd1,0x07,0x3a,0x50,0xcd,0x90,0x03,0xe8,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb080, 0, {0x28,0x01,0xa4,0x08,0xe9,0x00,0x3e,0x40,0x8f,0x90,0x03,0xc4,0x08,0xf1,0x00,0x3a }, - 16, 0xb090, 0, {0x68,0x8f,0x90,0x03,0xa4,0x41,0xf9,0x00,0xbe,0x40,0x0e,0x90,0x03,0xe4,0x00,0xf9 }, - 16, 0xb0a0, 0, {0xc0,0x38,0x40,0x2e,0x90,0x03,0xe6,0x40,0xe9,0x00,0x3e,0x68,0x06,0x90,0x03,0xca }, - 16, 0xb0b0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x05,0x3e,0x00 }, - 16, 0xb0c0, 0, {0x07,0x80,0x0b,0x20,0x00,0xe8,0x40,0x3e,0x10,0x0d,0x82,0x03,0x60,0x00,0xc8,0x00 }, - 16, 0xb0d0, 0, {0xb2,0x00,0x8d,0x83,0x03,0xe0,0x00,0xd8,0x50,0x3a,0x00,0x1e,0x80,0x03,0xe1,0x24 }, - 16, 0xb0e0, 0, {0xf8,0x00,0xb2,0x00,0x0f,0x80,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb0f0, 0, {0x28,0x05,0x38,0x00,0x8a,0x04,0x2f,0x84,0x6a,0xa0,0x0b,0xe8,0x08,0x8e,0x00,0x3d }, - 16, 0xb100, 0, {0x80,0x88,0xec,0x03,0x68,0x10,0xa6,0x01,0x36,0x80,0x08,0xa8,0x00,0xc8,0x10,0x8e }, - 16, 0xb110, 0, {0x10,0x22,0x80,0x08,0xa0,0x02,0xfb,0x20,0xbe,0x51,0x2a,0x80,0x0b,0xa0,0x02,0x82 }, - 16, 0xb120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x41,0x21,0x93,0x00,0x2c,0xf0 }, - 16, 0xb130, 0, {0x39,0x30,0x06,0x0c,0x00,0xa3,0x00,0x28,0x08,0x28,0xbc,0x02,0x2c,0x00,0x83,0x80 }, - 16, 0xb140, 0, {0x2a,0xc0,0x08,0x30,0x00,0xcc,0x00,0x9a,0x80,0x28,0xc0,0x0a,0x30,0x02,0xcd,0x00 }, - 16, 0xb150, 0, {0xb3,0x04,0x62,0xc1,0x0b,0x30,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb160, 0, {0xa0,0x01,0x1e,0x04,0x07,0x11,0x2c,0xd0,0x0a,0x32,0x22,0xdc,0xc1,0x87,0x00,0x6d }, - 16, 0xb170, 0, {0xd0,0x08,0x34,0x02,0x7c,0x00,0xa7,0x08,0x24,0xc8,0x08,0x70,0x02,0xdc,0x80,0x0f }, - 16, 0xb180, 0, {0x00,0x21,0xc4,0x08,0x73,0x06,0xdc,0x00,0xb2,0x00,0x61,0xc8,0x0b,0x3a,0x02,0x88 }, - 16, 0xb190, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x0a,0x00,0x57,0x81,0x2d,0xa0 }, - 16, 0xb1a0, 0, {0x2d,0x7c,0x02,0x3e,0x82,0xe3,0xe0,0x3b,0xe0,0x0c,0x78,0x03,0x1e,0x20,0xc7,0x80 }, - 16, 0xb1b0, 0, {0xb9,0xe8,0x2c,0x78,0x03,0xff,0x80,0xd6,0x80,0x3b,0xec,0x02,0x7a,0x03,0xde,0x00 }, - 16, 0xb1c0, 0, {0xf7,0x81,0x31,0xec,0x8f,0x7c,0x03,0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb1d0, 0, {0x08,0x1d,0xac,0x00,0xfb,0x00,0x1e,0x80,0x23,0xb6,0x83,0xed,0xa0,0xdb,0x64,0x3e }, - 16, 0xb1e0, 0, {0xc0,0x0e,0xb0,0x03,0xed,0xc0,0xf2,0x00,0x3e,0xd4,0x0a,0xb0,0x03,0xec,0x30,0xee }, - 16, 0xb1f0, 0, {0x64,0x3e,0xc0,0x07,0xb0,0xc3,0xe8,0x00,0xfb,0x01,0x3e,0xc8,0x0f,0xb8,0x03,0xc2 }, - 16, 0xb200, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xef,0x80,0x3b,0xe0 }, - 16, 0xb210, 0, {0x0f,0xf8,0x63,0x7e,0x04,0xcf,0xc0,0xb7,0x20,0x0e,0xf8,0x03,0xfc,0x00,0xc7,0x80 }, - 16, 0xb220, 0, {0x33,0xf0,0x0c,0xcc,0x03,0xfe,0x08,0xf7,0xc1,0x33,0xe0,0x4f,0xf8,0x03,0xb2,0x40 }, - 16, 0xb230, 0, {0xff,0xa0,0x31,0xe6,0x0c,0xf8,0x03,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb240, 0, {0xa8,0x11,0x9c,0x00,0xef,0x02,0x21,0x40,0x2d,0x70,0x02,0x1c,0x00,0xf7,0x10,0x29 }, - 16, 0xb250, 0, {0x40,0x08,0x70,0x22,0xfc,0xc0,0xa7,0x00,0x3d,0xc0,0x08,0x40,0x02,0xdc,0x00,0xb7 }, - 16, 0xb260, 0, {0x40,0x21,0xc0,0x0b,0x70,0x02,0xda,0x80,0xb7,0x24,0x29,0xc6,0x48,0xf0,0x02,0x2a }, - 16, 0xb270, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa7,0x00,0x28,0x84 }, - 16, 0xb280, 0, {0x0b,0x30,0x02,0x0c,0x00,0x93,0x00,0x25,0x80,0x0a,0x61,0x02,0xdc,0x01,0xa7,0x10 }, - 16, 0xb290, 0, {0x24,0xc0,0x08,0x40,0x82,0xdc,0x00,0x9f,0x00,0x25,0xc4,0x0b,0x70,0x02,0x94,0x25 }, - 16, 0xb2a0, 0, {0xb7,0x32,0x23,0xc4,0x1b,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb2b0, 0, {0x20,0x14,0xcc,0x0c,0xa3,0x00,0x20,0x00,0x29,0x30,0x0a,0x0c,0x00,0xa3,0x00,0x6c }, - 16, 0xb2c0, 0, {0x00,0x08,0x10,0x42,0xcd,0x10,0xaa,0x00,0xac,0xc0,0x00,0x04,0x02,0xcd,0x00,0xbb }, - 16, 0xb2d0, 0, {0x10,0x24,0xc0,0x03,0x30,0x42,0xc3,0x09,0xb3,0x00,0x2c,0xd0,0x0a,0x30,0x02,0x18 }, - 16, 0xb2e0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x80,0x00,0xef,0x00,0x3a,0x40 }, - 16, 0xb2f0, 0, {0x07,0xf0,0x43,0x3c,0x00,0x9f,0xc0,0xb6,0x14,0x0e,0x80,0x06,0xfc,0x01,0xcb,0x01 }, - 16, 0xb300, 0, {0x37,0xc0,0xac,0xb4,0x02,0xfc,0x00,0xd9,0x01,0x37,0xc0,0x4b,0xf0,0x13,0xae,0x08 }, - 16, 0xb310, 0, {0xfb,0x00,0x33,0xd0,0x2e,0xf0,0x0b,0x2a,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb320, 0, {0x80,0x00,0xec,0x00,0xfb,0x05,0x3e,0x40,0x0f,0x30,0x03,0xac,0x14,0xfb,0xa0,0x3a }, - 16, 0xb330, 0, {0xc0,0x0f,0x84,0x43,0xec,0x01,0xf9,0x40,0x3e,0xc0,0x0f,0xa2,0x03,0xec,0x21,0xf9 }, - 16, 0xb340, 0, {0x00,0x3a,0xc0,0x0f,0xb0,0x03,0xe4,0x20,0xf0,0x00,0xba,0xc0,0x0d,0xb0,0x03,0xe0 }, - 16, 0xb350, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf8,0x00,0xd7,0x01,0x35,0x68 }, - 16, 0xb360, 0, {0x6d,0xf0,0x03,0x3c,0x01,0xe7,0x00,0x33,0xc0,0x0d,0xc0,0x03,0xfc,0x24,0xcf,0x02 }, - 16, 0xb370, 0, {0x37,0xc0,0x0d,0xd2,0x02,0xfc,0x00,0xdf,0x01,0x33,0xc0,0x5e,0x70,0x33,0x1c,0x18 }, - 16, 0xb380, 0, {0xcf,0x41,0x31,0xc2,0x0c,0xf0,0x03,0x40,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb390, 0, {0x81,0x00,0x6c,0x00,0x8b,0x00,0x22,0x52,0x2a,0xb0,0x03,0x6c,0x00,0xab,0x00,0x28 }, - 16, 0xb3a0, 0, {0xc0,0x0a,0x8c,0x02,0xec,0x10,0x8b,0xe0,0x22,0xc0,0x0f,0x80,0x02,0xcc,0x00,0x8b }, - 16, 0xb3b0, 0, {0x80,0x22,0xc0,0x08,0xb0,0x02,0x2a,0x10,0xd9,0x80,0x22,0xc0,0xc8,0xb0,0x02,0xe0 }, - 16, 0xb3c0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x24,0x01,0x9b,0x00,0x26,0x80 }, - 16, 0xb3d0, 0, {0x29,0xb0,0x62,0x0c,0x00,0xab,0x01,0x6a,0x00,0x08,0x98,0x02,0xcc,0x00,0x9b,0x83 }, - 16, 0xb3e0, 0, {0x2e,0xc0,0xcb,0xb4,0x12,0xec,0x03,0x8b,0x80,0x28,0xc0,0x0a,0xb0,0x06,0xa2,0x00 }, - 16, 0xb3f0, 0, {0x8b,0x02,0x62,0xc0,0x08,0xb0,0x02,0xe0,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb400, 0, {0x08,0x04,0x0c,0x01,0x83,0x14,0x20,0x00,0x0a,0x30,0x02,0x4c,0x00,0x83,0x00,0x2a }, - 16, 0xb410, 0, {0x40,0x0a,0x10,0x00,0xcc,0x02,0x93,0x00,0x28,0xc0,0x0a,0x20,0x02,0xec,0x00,0x03 }, - 16, 0xb420, 0, {0x00,0x20,0xc0,0x08,0x30,0x16,0x00,0x80,0x91,0x00,0x60,0xc0,0x08,0x30,0x02,0xc2 }, - 16, 0xb430, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xdb,0x00,0x36,0x80 }, - 16, 0xb440, 0, {0x2d,0xf0,0x03,0x3c,0x00,0xaf,0x00,0x3a,0x80,0x0d,0x80,0x03,0xfc,0x00,0x5b,0x00 }, - 16, 0xb450, 0, {0x37,0xc0,0x09,0x90,0x03,0xfc,0x00,0xdf,0x00,0x33,0xc0,0x0a,0xf0,0x03,0xa4,0x20 }, - 16, 0xb460, 0, {0xcb,0x00,0xb3,0xc0,0x8c,0xb0,0x03,0x40,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb470, 0, {0xa0,0x1d,0xfc,0x04,0xff,0x20,0x0f,0x00,0x27,0xf0,0x03,0xfc,0x00,0xff,0x00,0x2d }, - 16, 0xb480, 0, {0x00,0x0b,0xd0,0x27,0xfc,0x00,0xef,0x00,0x37,0xc0,0x0f,0xc0,0x43,0xfc,0x00,0xff }, - 16, 0xb490, 0, {0x00,0x3f,0xc0,0x0d,0xf0,0x0b,0xe0,0x00,0xf5,0x00,0x3f,0xc0,0x1f,0xf0,0x03,0xe8 }, - 16, 0xb4a0, 0, {0x07,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf4,0xc0,0xfc,0x22,0x7f,0xc0 }, - 16, 0xb4b0, 0, {0x0c,0xd0,0x43,0x36,0x00,0xc4,0x81,0x34,0xc0,0x1c,0x89,0x07,0xf2,0x80,0xcf,0x80 }, - 16, 0xb4c0, 0, {0x33,0x60,0x0f,0x79,0x03,0x3c,0xe0,0xcf,0x08,0x33,0x48,0x0d,0xc4,0x03,0xf0,0x50 }, - 16, 0xb4d0, 0, {0xdc,0x90,0x37,0xcc,0x0f,0xf8,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb4e0, 0, {0x80,0x10,0xe9,0x90,0xb8,0x80,0x7e,0xe4,0x88,0x99,0x0a,0x26,0x08,0xa9,0x80,0x22 }, - 16, 0xb4f0, 0, {0xf4,0x2c,0x99,0x03,0xa7,0x02,0x89,0x80,0x22,0x34,0x0b,0x9a,0x03,0x7d,0x00,0xdf }, - 16, 0xb500, 0, {0x48,0x2b,0x60,0x08,0x05,0x02,0xe5,0x00,0x82,0x20,0x22,0xc4,0x8b,0xb0,0x02,0xe0 }, - 16, 0xb510, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc5,0x00,0xb0,0x10,0x2c,0xc0 }, - 16, 0xb520, 0, {0x2a,0x00,0x02,0xa4,0x08,0xa8,0x04,0xe0,0x80,0x0b,0x00,0x02,0xc4,0x41,0xb2,0x04 }, - 16, 0xb530, 0, {0xa4,0x0a,0x0b,0xb0,0x02,0x8c,0x81,0x83,0x20,0x60,0x50,0x98,0x12,0x12,0x8b,0x80 }, - 16, 0xb540, 0, {0x89,0x00,0x2c,0xc8,0x0b,0x30,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb550, 0, {0xc0,0x11,0xac,0x20,0xbb,0x02,0x2a,0xc0,0x0a,0x88,0x02,0xa4,0x08,0xa9,0x80,0xa2 }, - 16, 0xb560, 0, {0xe1,0x1b,0x9c,0x22,0xe6,0x00,0xb8,0x40,0x26,0x30,0x0b,0x90,0x02,0xcc,0x01,0x93 }, - 16, 0xb570, 0, {0x04,0x2a,0x40,0x39,0x98,0x82,0xec,0x14,0x8b,0x65,0x2a,0xc0,0x0b,0xb2,0x02,0xf8 }, - 16, 0xb580, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe7,0x00,0xb8,0x48,0x2e,0x00 }, - 16, 0xb590, 0, {0x0e,0x88,0x43,0x84,0x00,0xe3,0xc1,0x36,0xe8,0x0f,0x9c,0x12,0xe2,0x80,0xf3,0xc0 }, - 16, 0xb5a0, 0, {0x36,0x70,0x5f,0xa8,0x23,0xac,0x01,0xcb,0x04,0x22,0x40,0x4d,0x84,0x03,0xe2,0x00 }, - 16, 0xb5b0, 0, {0xd8,0x00,0x3e,0xc0,0x0f,0x90,0x03,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb5c0, 0, {0xe0,0x01,0xb3,0x09,0xfe,0x10,0x3e,0x81,0x0d,0xc0,0x03,0x74,0x0c,0xff,0x00,0x3d }, - 16, 0xb5d0, 0, {0xc1,0x8c,0xd0,0x83,0x14,0x00,0xcd,0x20,0x3a,0x40,0x0d,0xca,0x01,0x7c,0x00,0xff }, - 16, 0xb5e0, 0, {0x00,0x1f,0x40,0x0e,0xc0,0x23,0xf2,0x46,0xfe,0x84,0x37,0xc0,0x0f,0xd8,0x03,0xf8 }, - 16, 0xb5f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xdd,0x02,0x3d,0x40 }, - 16, 0xb600, 0, {0x0e,0x90,0x03,0xac,0x00,0xeb,0x48,0x3e,0xd0,0x0c,0x80,0x63,0xa2,0x08,0xca,0x00 }, - 16, 0xb610, 0, {0x32,0x08,0x0c,0xb0,0x03,0xac,0x08,0xeb,0x00,0x3e,0x40,0x0c,0xd4,0x83,0x58,0x20 }, - 16, 0xb620, 0, {0xf9,0x42,0x32,0xc0,0x0c,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb630, 0, {0xc8,0x05,0x28,0x02,0xdb,0x00,0x2e,0xe0,0x28,0x3a,0x02,0x2e,0x00,0xdb,0x60,0x76 }, - 16, 0xb640, 0, {0xe0,0x0d,0x8c,0x02,0xe0,0x00,0x88,0x02,0x36,0x58,0x68,0x15,0x83,0x7c,0x08,0xbf }, - 16, 0xb650, 0, {0x00,0x2d,0x60,0x08,0x90,0x02,0xa9,0x00,0xb3,0x05,0x23,0xc0,0x08,0xb0,0x02,0xf2 }, - 16, 0xb660, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x10,0x80,0x00,0x0c,0xc1 }, - 16, 0xb670, 0, {0x08,0x1c,0x82,0x06,0x00,0x93,0xc0,0x20,0xf6,0x0a,0x20,0x02,0x08,0x00,0x93,0x00 }, - 16, 0xb680, 0, {0x24,0x60,0x09,0x3c,0x02,0x0c,0x00,0x83,0x00,0x2c,0x60,0x09,0x01,0x12,0x00,0x40 }, - 16, 0xb690, 0, {0xb0,0x00,0xe0,0xc0,0x08,0x30,0x02,0x70,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb6a0, 0, {0x20,0x41,0x0a,0x40,0x86,0x81,0x2d,0xe0,0x58,0x18,0x0a,0x16,0xa0,0x97,0x80,0x25 }, - 16, 0xb6b0, 0, {0xe9,0x19,0x78,0x82,0xd6,0x00,0x97,0x80,0x25,0xa0,0x19,0xf8,0x02,0x5e,0x00,0xb7 }, - 16, 0xb6c0, 0, {0x80,0x2d,0x60,0x28,0x48,0x12,0x96,0x00,0xb4,0x80,0x21,0xe0,0x28,0x78,0x02,0xc8 }, - 16, 0xb6d0, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x81,0x30,0x3c,0xc2 }, - 16, 0xb6e0, 0, {0x0e,0x00,0x02,0x84,0x00,0xe3,0x40,0x28,0xe8,0x4c,0x29,0x03,0x0c,0x00,0xd3,0x00 }, - 16, 0xb6f0, 0, {0x34,0xc4,0x0d,0x31,0x03,0x8c,0x08,0xe3,0x00,0x3c,0x46,0x0c,0x20,0x03,0x00,0x80 }, - 16, 0xb700, 0, {0xf2,0x00,0x32,0xc0,0x0c,0x30,0x03,0xd2,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb710, 0, {0x40,0x19,0xb8,0x00,0xff,0x10,0x2f,0xc0,0x0f,0xc0,0x23,0xc4,0x80,0x7f,0x10,0x3e }, - 16, 0xb720, 0, {0xc0,0x0f,0xb1,0x03,0xdc,0x00,0xe7,0x00,0x3f,0x80,0x06,0xf1,0x43,0xfc,0x00,0xff }, - 16, 0xb730, 0, {0x08,0x7d,0x50,0x0e,0xe1,0x23,0xb4,0x08,0xfe,0x10,0x3f,0xc4,0x0f,0xf0,0x03,0xd0 }, - 16, 0xb740, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x02,0xcc,0x00,0x3e,0x00 }, - 16, 0xb750, 0, {0x2c,0xc0,0x03,0x04,0x01,0xcb,0x00,0x33,0x60,0x2c,0x90,0x13,0xe8,0x00,0x73,0x00 }, - 16, 0xb760, 0, {0xb2,0xc1,0x0f,0xa0,0x03,0xec,0x80,0xfb,0x28,0x3e,0x54,0x1f,0xd0,0x03,0xfe,0x02 }, - 16, 0xb770, 0, {0xc9,0x80,0x32,0xc0,0x0f,0xb0,0x03,0xca,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb780, 0, {0x48,0x11,0x80,0x00,0x86,0x00,0x2d,0x80,0x08,0x20,0x02,0x14,0x08,0x87,0x00,0x29 }, - 16, 0xb790, 0, {0x40,0x08,0x70,0x02,0xdc,0x00,0xb7,0x00,0x21,0xc0,0x0b,0x60,0x02,0x5c,0xa0,0x97 }, - 16, 0xb7a0, 0, {0x20,0x2d,0x48,0x0b,0x50,0x02,0xdc,0x10,0x8d,0x00,0x21,0xc8,0x0b,0x70,0x02,0xd2 }, - 16, 0xb7b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9f,0x00,0x85,0x81,0x2c,0x60 }, - 16, 0xb7c0, 0, {0x18,0x58,0x02,0xde,0x20,0xb7,0x82,0x28,0x60,0x5a,0x78,0x52,0xde,0x10,0xbf,0x80 }, - 16, 0xb7d0, 0, {0x21,0xe0,0x4b,0x78,0x06,0xde,0x40,0xb7,0xa0,0x2d,0x69,0x9b,0x78,0x12,0xce,0x00 }, - 16, 0xb7e0, 0, {0x87,0x80,0xe1,0xe4,0x0b,0x78,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb7f0, 0, {0x48,0x14,0xee,0x00,0x83,0x00,0x2c,0xc2,0x08,0x36,0x02,0x8c,0x08,0x83,0xf0,0x68 }, - 16, 0xb800, 0, {0x40,0x0a,0x3e,0x02,0xcd,0x40,0xb3,0x00,0x20,0xe0,0x0b,0x32,0x06,0x4c,0x00,0x9b }, - 16, 0xb810, 0, {0x00,0x0c,0x40,0x0b,0x30,0x02,0xcd,0x80,0x83,0x08,0x20,0xc0,0x0b,0xb1,0x02,0xda }, - 16, 0xb820, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xce,0x08,0x3f,0xb0 }, - 16, 0xb830, 0, {0x0c,0xe4,0x23,0xda,0x02,0xde,0x40,0xbb,0xb2,0x0e,0xe2,0x43,0xfa,0x00,0xfe,0x00 }, - 16, 0xb840, 0, {0x33,0x90,0x0b,0xe0,0x03,0xe8,0x00,0xfa,0x00,0x3e,0x81,0x0b,0xe0,0x13,0xf9,0x08 }, - 16, 0xb850, 0, {0xce,0x40,0x32,0x80,0x0f,0xa8,0x03,0xfa,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb860, 0, {0x48,0x00,0xe0,0x24,0x98,0x08,0x3c,0x04,0x0f,0x00,0x0b,0x60,0x00,0xf8,0x40,0x2e }, - 16, 0xb870, 0, {0x03,0x0d,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x06,0x0b,0x80,0x03,0xe0,0x00,0xd8 }, - 16, 0xb880, 0, {0x00,0x3c,0x00,0x03,0x8c,0x23,0xe1,0x00,0xf8,0x00,0x7e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xb890, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x00,0x3e,0x40 }, - 16, 0xb8a0, 0, {0x8c,0x90,0x03,0x25,0x00,0xe9,0x80,0x32,0x44,0x0f,0x94,0x02,0xe4,0x20,0xf9,0x00 }, - 16, 0xb8b0, 0, {0x32,0x70,0x0f,0x9a,0x43,0xe4,0x00,0xf9,0x00,0x32,0x40,0x0c,0x10,0x33,0x24,0x10 }, - 16, 0xb8c0, 0, {0xf9,0x01,0x3e,0x40,0x0f,0x90,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb8d0, 0, {0x80,0x04,0x64,0x00,0x89,0x82,0x2e,0x40,0x28,0x90,0x02,0x24,0x82,0x81,0xc0,0xa2 }, - 16, 0xb8e0, 0, {0x70,0x0b,0x9c,0x02,0xe4,0x00,0x31,0x42,0xa2,0x60,0x0b,0x94,0x82,0xe4,0x00,0xb9 }, - 16, 0xb8f0, 0, {0x00,0x2a,0x40,0x08,0x94,0xa2,0x25,0x00,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x0a,0x20 }, - 16, 0xb900, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x64,0x2e,0x40 }, - 16, 0xb910, 0, {0x08,0x90,0x42,0xa4,0x00,0x89,0x60,0x22,0x42,0x0b,0x90,0x02,0xe6,0x00,0xb9,0x80 }, - 16, 0xb920, 0, {0x22,0x40,0x0b,0x90,0x02,0xa4,0x04,0xb9,0x00,0x22,0x40,0x28,0x90,0x02,0x24,0x04 }, - 16, 0xb930, 0, {0xb9,0x00,0x2e,0x40,0x0b,0x90,0x02,0x0e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb940, 0, {0x08,0x04,0x05,0x80,0x81,0x00,0x2c,0xc1,0x48,0x10,0x02,0xa4,0x02,0x81,0x00,0x20 }, - 16, 0xb950, 0, {0x40,0x83,0x34,0x02,0xc4,0x00,0xbb,0x00,0x20,0xd0,0x0b,0x14,0x02,0xc4,0x80,0xb1 }, - 16, 0xb960, 0, {0x20,0xa0,0x68,0x18,0x14,0x1a,0x0d,0x00,0xb1,0x40,0x2c,0x50,0x0b,0x10,0x02,0x0a }, - 16, 0xb970, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x00,0x3e,0x00 }, - 16, 0xb980, 0, {0x8c,0x80,0x0b,0xa0,0x04,0xe8,0x00,0x32,0x00,0x07,0x80,0x03,0xe0,0x00,0xf8,0x00 }, - 16, 0xb990, 0, {0x32,0x00,0x1f,0x80,0x03,0xa1,0x40,0xf8,0x50,0x32,0x00,0x0c,0x80,0x03,0x20,0x00 }, - 16, 0xb9a0, 0, {0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb9b0, 0, {0x98,0x1d,0xf4,0x46,0xfd,0x40,0x3f,0x50,0x23,0xd4,0x13,0x74,0x04,0xf5,0x02,0x3f }, - 16, 0xb9c0, 0, {0x50,0x0f,0xd4,0x03,0xfd,0x00,0xbd,0x00,0x2f,0x50,0x0f,0xd0,0x03,0xe4,0x40,0xf9 }, - 16, 0xb9d0, 0, {0x10,0x3f,0x44,0x0f,0xd4,0x03,0xf5,0x08,0xfd,0x06,0x3e,0x50,0x0f,0xd2,0x83,0xe6 }, - 16, 0xb9e0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x40,0xed,0x04,0x3e,0x48 }, - 16, 0xb9f0, 0, {0x0c,0xb2,0x83,0xf4,0x00,0xc1,0x00,0x32,0x40,0x8c,0xd0,0x03,0x34,0x00,0xfd,0x00 }, - 16, 0xba00, 0, {0x37,0x40,0x0f,0xd0,0x03,0xe6,0x20,0xf9,0x88,0x3d,0x62,0x0c,0xd8,0x03,0xfe,0x24 }, - 16, 0xba10, 0, {0xc1,0x00,0x3e,0x78,0x0f,0xd0,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xba20, 0, {0x38,0x10,0xe1,0x00,0x88,0x40,0x2e,0x10,0x08,0xc4,0x23,0xa0,0x08,0x88,0x06,0x2a }, - 16, 0xba30, 0, {0x14,0x08,0x80,0x03,0x60,0x04,0xb8,0x00,0x22,0x00,0x0b,0x80,0x02,0xe2,0x00,0xb8 }, - 16, 0xba40, 0, {0x80,0x2e,0x00,0x08,0x8c,0x02,0xe3,0x80,0x88,0x02,0x2e,0x38,0x0b,0x88,0x02,0x0e }, - 16, 0xba50, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x80,0xa1,0xc0,0x2d,0x70 }, - 16, 0xba60, 0, {0x08,0x50,0x42,0xc4,0x00,0xa9,0x00,0x20,0xe0,0x2a,0x10,0x0a,0x04,0x10,0xb1,0x00 }, - 16, 0xba70, 0, {0x24,0x40,0x4b,0x10,0x06,0xc4,0x20,0xb1,0x08,0x6e,0x40,0x0b,0x16,0x82,0xc4,0x20 }, - 16, 0xba80, 0, {0x81,0x00,0x2c,0x50,0x0b,0x92,0x82,0x52,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xba90, 0, {0x18,0x11,0xa4,0x00,0xa9,0x01,0x2e,0x40,0x28,0xd0,0x20,0xa4,0x04,0xa9,0x00,0x2a }, - 16, 0xbaa0, 0, {0x40,0x1a,0xb0,0x12,0x24,0x00,0xb9,0x0c,0x22,0x42,0x0b,0x94,0x02,0xe4,0x00,0xb9 }, - 16, 0xbab0, 0, {0x00,0x6e,0x40,0x0b,0x96,0x02,0xe4,0x11,0x89,0x20,0x6e,0x40,0x0b,0x90,0x02,0x46 }, - 16, 0xbac0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0xc0,0xa9,0xc0,0x3e,0x50 }, - 16, 0xbad0, 0, {0x08,0x9c,0x83,0xe4,0x02,0xe9,0x00,0xb2,0x40,0x2a,0x92,0x12,0x26,0x40,0xf9,0x40 }, - 16, 0xbae0, 0, {0x36,0x70,0x0f,0x94,0x03,0xe4,0x04,0xf9,0x01,0x3c,0x40,0x0f,0x98,0x03,0xe6,0x02 }, - 16, 0xbaf0, 0, {0xc9,0x22,0x3e,0x40,0x0f,0x10,0x02,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbb00, 0, {0x28,0x01,0x86,0x04,0xd9,0x40,0x1c,0x40,0x0f,0x92,0x23,0xa4,0xb0,0xdb,0x04,0x3c }, - 16, 0xbb10, 0, {0xc0,0x0d,0x9a,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x44,0x0f,0x90,0x03,0xe4,0x00,0xf9 }, - 16, 0xbb20, 0, {0x00,0x3e,0x42,0x2c,0x90,0x23,0xe4,0x80,0xf9,0x00,0x3e,0x40,0x8f,0x92,0x03,0x92 }, - 16, 0xbb30, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xc8,0x20,0x32,0x00 }, - 16, 0xbb40, 0, {0x4c,0xc0,0x8b,0x20,0x02,0xc8,0x31,0x32,0x20,0x2d,0x84,0x03,0xe1,0x04,0xf8,0x48 }, - 16, 0xbb50, 0, {0xba,0x00,0x0f,0x89,0x03,0xe0,0x00,0xc8,0x00,0x32,0x00,0x0d,0x81,0x13,0x20,0x10 }, - 16, 0xbb60, 0, {0xf8,0x00,0x3a,0x00,0x0f,0x81,0x23,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbb70, 0, {0x28,0x05,0x28,0x00,0x0e,0x40,0x22,0x80,0x28,0xa4,0x02,0x19,0x00,0x52,0x80,0xa2 }, - 16, 0xbb80, 0, {0x80,0x4d,0xed,0x82,0xe8,0x00,0xb6,0x42,0x23,0xbd,0x0b,0xe8,0x02,0xe8,0x04,0xda }, - 16, 0xbb90, 0, {0x00,0x37,0x80,0x08,0xe0,0x02,0x3a,0x20,0xba,0x00,0x22,0x80,0x0b,0xa8,0x0a,0x0a }, - 16, 0xbba0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x80,0x60,0xc0 }, - 16, 0xbbb0, 0, {0x08,0x29,0x02,0x0d,0x00,0x92,0x40,0x24,0xc0,0x08,0xb4,0x02,0xcc,0x00,0xb3,0x00 }, - 16, 0xbbc0, 0, {0x68,0xe0,0x1b,0x30,0x02,0xcc,0x00,0x93,0x01,0x24,0xc0,0x69,0x38,0x02,0x6c,0x00 }, - 16, 0xbbd0, 0, {0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbbe0, 0, {0xa0,0x01,0x1c,0x40,0x83,0xc0,0x20,0x40,0x08,0x28,0x06,0x9c,0x18,0x9c,0x02,0x24 }, - 16, 0xbbf0, 0, {0xc0,0x09,0x70,0x02,0xd4,0x00,0xb7,0x00,0x21,0xc0,0x0b,0x70,0x02,0xce,0x40,0x97 }, - 16, 0xbc00, 0, {0xb0,0x25,0x40,0x08,0x78,0x1a,0x58,0x00,0xbf,0xa2,0x65,0xc8,0x0b,0x78,0x02,0x20 }, - 16, 0xbc10, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x0e,0x02,0x87,0x80,0xb1,0xa0 }, - 16, 0xbc20, 0, {0x0c,0x68,0x03,0x1a,0x08,0xd6,0x92,0x35,0xe4,0x28,0x78,0x42,0xd6,0x10,0xf5,0x80 }, - 16, 0xbc30, 0, {0x39,0xa0,0x0f,0x78,0x23,0xde,0x30,0xd3,0xa2,0x35,0xa0,0x4d,0xe8,0x03,0x5e,0x00 }, - 16, 0xbc40, 0, {0xf7,0xd0,0x3d,0xf8,0x0f,0xf0,0x03,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbc50, 0, {0x08,0x1d,0xac,0x00,0xfb,0x04,0x3e,0x00,0x0b,0xa0,0x03,0x48,0x04,0xfa,0x41,0x3a }, - 16, 0xbc60, 0, {0x50,0x0f,0xb0,0x03,0xe4,0x00,0xf1,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xed,0x88,0xfb }, - 16, 0xbc70, 0, {0x4d,0x3e,0x00,0x0f,0xf0,0x03,0xbc,0x08,0xfb,0x20,0x3a,0xc0,0x0f,0xb0,0x03,0xc2 }, - 16, 0xbc80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xdc,0x80,0xb3,0xe0 }, - 16, 0xbc90, 0, {0x0c,0xd8,0x03,0xce,0x00,0xc8,0xa0,0x31,0xa0,0x8d,0xe9,0x03,0xbe,0x00,0xb2,0x80 }, - 16, 0xbca0, 0, {0x33,0xe0,0x0c,0xe8,0x43,0x7e,0x04,0x0f,0x81,0x31,0xe4,0x0c,0xd8,0x03,0xf6,0x00 }, - 16, 0xbcb0, 0, {0xff,0x80,0x3f,0xe0,0x0f,0xf8,0x03,0x00,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbcc0, 0, {0xa8,0x11,0x9c,0x00,0xb4,0x40,0x35,0x40,0x08,0x50,0x82,0xde,0x80,0xd4,0x90,0x21 }, - 16, 0xbcd0, 0, {0xe0,0x0d,0x51,0x02,0xd4,0x40,0xb6,0xb0,0x2b,0x90,0x0e,0xe5,0x02,0x9c,0x40,0xd7 }, - 16, 0xbce0, 0, {0x22,0x19,0x5c,0x0d,0x70,0x02,0xd8,0x00,0xb7,0x20,0x2d,0xc0,0x0b,0xf0,0x03,0x6a }, - 16, 0xbcf0, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x93,0x10,0x21,0x80 }, - 16, 0xbd00, 0, {0x08,0x58,0x02,0xdc,0xc0,0x94,0x00,0x23,0xd0,0x08,0x70,0xa0,0xd4,0x20,0xb5,0x02 }, - 16, 0xbd10, 0, {0x29,0x80,0x09,0x60,0x82,0x0c,0x00,0x87,0x02,0x25,0xc0,0x19,0x40,0x02,0xd4,0x00 }, - 16, 0xbd20, 0, {0xb7,0x00,0x6d,0xc0,0x0b,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbd30, 0, {0x20,0x14,0xec,0x00,0xb3,0xc0,0x20,0x01,0x48,0x18,0x02,0xcc,0x02,0x81,0x44,0xa0 }, - 16, 0xbd40, 0, {0xc0,0x89,0x38,0x02,0xc7,0x80,0xb1,0x00,0x2c,0x09,0x4a,0x00,0x62,0xac,0x09,0x93 }, - 16, 0xbd50, 0, {0x01,0x28,0x40,0x19,0x30,0x02,0xcd,0x10,0xb3,0x90,0x2c,0xc0,0x0b,0x30,0x02,0xc8 }, - 16, 0xbd60, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x20,0xdb,0x62,0x22,0xe0 }, - 16, 0xbd70, 0, {0x6c,0xa0,0x03,0xe4,0x00,0x98,0x00,0x32,0xc0,0xec,0x98,0x23,0xae,0x08,0xfb,0x08 }, - 16, 0xbd80, 0, {0x3a,0x78,0x09,0x90,0x03,0x7c,0x10,0xcf,0x00,0x26,0x40,0x0c,0xb0,0x03,0xec,0x00 }, - 16, 0xbd90, 0, {0xff,0x80,0x3f,0xc0,0x0f,0x90,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbda0, 0, {0x80,0x00,0xec,0x20,0xfb,0x48,0x3c,0x61,0x0f,0xa0,0x43,0xed,0x00,0xf8,0x24,0x3e }, - 16, 0xbdb0, 0, {0x50,0x0f,0x90,0x83,0xe4,0x00,0xfb,0x00,0x3a,0x50,0x0f,0x80,0x43,0xec,0x08,0xfb }, - 16, 0xbdc0, 0, {0x00,0x3e,0x40,0x0f,0x40,0x03,0xf0,0x00,0xfb,0x00,0x3e,0xc1,0x0f,0x90,0x03,0x60 }, - 16, 0xbdd0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xdd,0xa0,0x32,0x80 }, - 16, 0xbde0, 0, {0x0c,0xe0,0x01,0xfc,0x00,0xdc,0x91,0x39,0xc0,0x3c,0x40,0x03,0x34,0x00,0xff,0x80 }, - 16, 0xbdf0, 0, {0x3f,0x00,0x0f,0xd0,0x07,0xfc,0x00,0xcb,0x00,0x3d,0x40,0x0c,0xe0,0x03,0x38,0x20 }, - 16, 0xbe00, 0, {0xcf,0x02,0x3d,0xc0,0x0c,0xd0,0x03,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbe10, 0, {0x81,0x04,0x6c,0x00,0x01,0x40,0x22,0x00,0x28,0xa0,0x02,0xce,0x86,0x83,0x64,0x22 }, - 16, 0xbe20, 0, {0xf4,0x08,0x8c,0x0f,0x64,0x00,0xbb,0x10,0x2e,0x60,0x0b,0x9c,0x03,0xac,0x01,0xdb }, - 16, 0xbe30, 0, {0x00,0x3e,0x60,0x08,0x8f,0x02,0x23,0x40,0x8b,0x00,0x3a,0xc0,0x0d,0x10,0x43,0x68 }, - 16, 0xbe40, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x99,0x00,0xa2,0xc0 }, - 16, 0xbe50, 0, {0x08,0x90,0x02,0xa6,0x07,0x98,0x00,0x02,0xc2,0x48,0x88,0x02,0x2c,0x00,0xba,0x02 }, - 16, 0xbe60, 0, {0x6e,0x60,0x0a,0x98,0x02,0xec,0x00,0x8b,0x01,0x2e,0x60,0x08,0x90,0x02,0x05,0x00 }, - 16, 0xbe70, 0, {0x8b,0x00,0x2e,0xc0,0x08,0xb1,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbe80, 0, {0x08,0x04,0x0c,0x10,0x81,0x00,0x20,0x40,0x28,0x10,0x26,0xcc,0x80,0x80,0x20,0xa0 }, - 16, 0xbe90, 0, {0xcc,0x18,0x14,0x42,0x04,0x00,0xb2,0x20,0x6c,0x40,0x0b,0x00,0x02,0x8c,0x00,0x83 }, - 16, 0xbea0, 0, {0x00,0x28,0x40,0x28,0x00,0x02,0x00,0x00,0x83,0x00,0x28,0xc0,0x09,0xb0,0x02,0x42 }, - 16, 0xbeb0, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xd9,0x00,0x22,0x80 }, - 16, 0xbec0, 0, {0x0c,0x90,0x03,0xac,0x80,0xda,0x29,0x2a,0xd2,0x28,0x80,0x02,0x24,0x00,0xfb,0x20 }, - 16, 0xbed0, 0, {0x3e,0x00,0x0f,0x90,0x02,0xfc,0x00,0x8f,0x00,0x2e,0x40,0x0c,0x80,0x0b,0x20,0x02 }, - 16, 0xbee0, 0, {0xcf,0x00,0x3e,0xc0,0x0c,0xb0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbef0, 0, {0xa0,0x1d,0xfc,0x00,0xfd,0x00,0x3f,0x00,0x0f,0xd0,0x63,0xfc,0x49,0xf5,0x00,0x3e }, - 16, 0xbf00, 0, {0xc0,0x0b,0xc0,0x01,0xf4,0x00,0x7f,0x40,0x3f,0x40,0x1f,0xd0,0x03,0xbc,0x00,0xff }, - 16, 0xbf10, 0, {0x00,0x3f,0x40,0x0f,0xc0,0x03,0xf0,0x00,0xff,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xe8 }, - 16, 0xbf20, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf2,0x40,0xec,0xa0,0x3f,0xe0 }, - 16, 0xbf30, 0, {0x0d,0x48,0x03,0x7d,0x80,0xf4,0x80,0x33,0x6c,0x0e,0xc8,0x03,0x32,0x00,0xdd,0x90 }, - 16, 0xbf40, 0, {0x3b,0xa0,0x2d,0xf0,0x03,0xfc,0xc0,0xff,0x00,0x3b,0xe0,0x8e,0xf0,0x03,0x3c,0x04 }, - 16, 0xbf50, 0, {0xec,0x60,0x31,0x00,0x0c,0xf0,0x03,0xb0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbf60, 0, {0x80,0x10,0xec,0x00,0xd9,0xc1,0x2e,0xe1,0x0d,0x88,0x02,0x3c,0x80,0xf8,0x80,0x36 }, - 16, 0xbf70, 0, {0x7d,0x18,0xa0,0x02,0x28,0xb0,0xea,0x20,0x22,0x20,0x08,0x77,0x02,0xfd,0x50,0xbb }, - 16, 0xbf80, 0, {0x80,0x22,0x40,0x0b,0xf4,0x42,0x3d,0x80,0x88,0x31,0x22,0x12,0x08,0xf6,0x02,0xe0 }, - 16, 0xbf90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x80,0x11,0x2e,0xc1 }, - 16, 0xbfa0, 0, {0x08,0x00,0x02,0x4d,0x80,0xb8,0x00,0x20,0x00,0x0a,0x02,0x82,0x00,0x00,0x99,0x20 }, - 16, 0xbfb0, 0, {0x22,0xc0,0x09,0x30,0x82,0xcc,0x00,0xb3,0x00,0x28,0xca,0x0b,0x34,0x82,0x0d,0x20 }, - 16, 0xbfc0, 0, {0x80,0x00,0xa0,0x8c,0x08,0x34,0x82,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbfd0, 0, {0xc0,0x15,0xac,0x40,0x99,0x80,0x2e,0xc2,0x09,0x94,0x02,0x2c,0x00,0xa9,0x80,0x26 }, - 16, 0xbfe0, 0, {0x60,0x08,0x38,0x42,0x22,0x20,0xba,0x41,0x62,0x46,0x3b,0xb0,0x02,0xec,0x01,0xbb }, - 16, 0xbff0, 0, {0x80,0x22,0x40,0x0b,0xb0,0x46,0x0c,0x18,0x88,0xc0,0x22,0x22,0x08,0xb0,0x06,0xf0 }, - 16, 0xc000, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xcc,0x00,0xc9,0x81,0x3c,0xc1 }, - 16, 0xc010, 0, {0x0c,0xa9,0x23,0x6c,0x00,0xb2,0x80,0x32,0x78,0x0a,0x8a,0x0b,0x26,0x00,0x99,0x01 }, - 16, 0xc020, 0, {0x30,0xe0,0x0d,0xb0,0x03,0xec,0x00,0xb9,0x00,0x3a,0xc0,0x1e,0xb0,0x03,0x2c,0x00 }, - 16, 0xc030, 0, {0xcb,0x80,0x32,0x61,0x0c,0xb0,0x13,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc040, 0, {0xe0,0x01,0xbc,0x10,0xdd,0x00,0x3f,0xc2,0x0f,0xe8,0x03,0xac,0x00,0xfe,0x00,0x3d }, - 16, 0xc050, 0, {0x40,0x0f,0xc0,0x43,0xf8,0x10,0xef,0x14,0xb7,0xe0,0x0c,0xf0,0x03,0xfc,0x00,0xf5 }, - 16, 0xc060, 0, {0x02,0x3f,0x44,0x4f,0xb0,0x4b,0xfc,0x02,0xd4,0x04,0x3d,0x40,0x2f,0xf0,0x03,0xf8 }, - 16, 0xc070, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xf9,0x08,0x3e,0x60 }, - 16, 0xc080, 0, {0x0d,0xa0,0x03,0xac,0x00,0xe8,0x50,0x32,0x00,0x0c,0x84,0x03,0xa5,0x00,0xe9,0x00 }, - 16, 0xc090, 0, {0x3a,0xd8,0x0f,0xb0,0x03,0x2c,0x00,0xf9,0x00,0x3a,0xc0,0x0f,0x30,0x03,0x2c,0x00 }, - 16, 0xc0a0, 0, {0xcb,0x44,0x3e,0xd4,0x0e,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc0b0, 0, {0xc8,0x05,0x2c,0x08,0xb9,0x80,0x2e,0xc0,0x0a,0x30,0x42,0x3c,0x00,0x89,0x04,0x76 }, - 16, 0xc0c0, 0, {0x60,0x08,0x90,0x62,0x20,0x00,0x82,0x04,0x22,0xd0,0x08,0xf0,0x43,0x7c,0x00,0xbb }, - 16, 0xc0d0, 0, {0x82,0x22,0x40,0x0b,0xf0,0x42,0x3c,0x00,0x8a,0xc0,0x2e,0xc1,0x08,0xf0,0x02,0xf2 }, - 16, 0xc0e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x10,0xb2,0xd0,0x2c,0xc0 }, - 16, 0xc0f0, 0, {0x29,0x18,0x02,0x8c,0x04,0xa1,0x00,0x24,0x9c,0x08,0x10,0x02,0x80,0x00,0xa1,0x01 }, - 16, 0xc100, 0, {0x0c,0xc1,0x2b,0x30,0x52,0x8c,0x04,0xb3,0x01,0x28,0x40,0x4b,0x30,0x02,0x4c,0x00 }, - 16, 0xc110, 0, {0x90,0x20,0x2c,0x20,0x0a,0x30,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc120, 0, {0x20,0x41,0x1e,0x00,0xb7,0xa2,0x25,0xe8,0x8a,0x68,0x02,0x1e,0x00,0x85,0x80,0x25 }, - 16, 0xc130, 0, {0x80,0x88,0xe8,0x02,0x3e,0x00,0x85,0x80,0x2f,0xe4,0x28,0x78,0x02,0xde,0x00,0xb7 }, - 16, 0xc140, 0, {0x80,0x61,0xe0,0x03,0x78,0x02,0x5e,0x82,0xb7,0x82,0x2d,0xe0,0x08,0x78,0x02,0xc8 }, - 16, 0xc150, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0d,0x00,0xf0,0x10,0x3c,0x80 }, - 16, 0xc160, 0, {0x0d,0x10,0x83,0x8c,0x00,0xe2,0x50,0x26,0x04,0x0c,0x11,0x03,0x88,0x40,0xeb,0x00 }, - 16, 0xc170, 0, {0x3c,0xc4,0x0f,0x30,0x03,0x8c,0x00,0xf3,0x08,0x38,0x40,0x07,0x30,0x03,0x6e,0x40 }, - 16, 0xc180, 0, {0xd0,0x08,0x3c,0x88,0x0e,0x30,0x43,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc190, 0, {0x40,0x1d,0xbc,0x00,0xfb,0x34,0x3c,0xc9,0x4e,0xb0,0x23,0xed,0x20,0xfb,0x04,0x3f }, - 16, 0xc1a0, 0, {0xc8,0x8f,0x70,0x53,0x4c,0x00,0xeb,0x10,0x31,0xc5,0x0e,0xf4,0x03,0x6d,0x00,0xf3 }, - 16, 0xc1b0, 0, {0x00,0x3f,0xc0,0x0f,0xf4,0x0b,0xbc,0x00,0xcd,0x00,0x3f,0xc0,0x0f,0xf4,0x83,0xd0 }, - 16, 0xc1c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xce,0x04,0xc9,0x04,0xb0,0xc1 }, - 16, 0xc1d0, 0, {0x0f,0x98,0x13,0x6c,0x90,0xcb,0x02,0x3e,0xc0,0x4f,0xb0,0x63,0xe4,0x00,0xf1,0x80 }, - 16, 0xc1e0, 0, {0x12,0xc0,0x0c,0xb5,0x03,0xec,0xc0,0xcf,0x83,0x32,0x40,0x0f,0xb3,0x23,0x2d,0xa4 }, - 16, 0xc1f0, 0, {0xfb,0x00,0x3e,0x00,0x0f,0xb4,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc200, 0, {0x48,0x11,0x9c,0x00,0x87,0x00,0x21,0xc0,0x2d,0x60,0x02,0x1c,0x00,0xd7,0x00,0x39 }, - 16, 0xc210, 0, {0xc0,0x0b,0x60,0x02,0xdc,0x00,0xb5,0x00,0x21,0xc0,0x2a,0x70,0x12,0xcc,0x80,0x87 }, - 16, 0xc220, 0, {0x00,0x35,0xc0,0x0b,0x72,0x52,0x1c,0x00,0xb7,0x00,0x2d,0x41,0x0b,0x32,0x02,0x12 }, - 16, 0xc230, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xbe,0x00,0x81,0xc0,0x23,0x20 }, - 16, 0xc240, 0, {0x0b,0xd8,0x02,0x5e,0x00,0x06,0xc0,0x2d,0xa0,0x0b,0x7c,0x12,0xde,0x08,0xbf,0x80 }, - 16, 0xc250, 0, {0xa1,0xe2,0x2a,0x7a,0x02,0xde,0x00,0x93,0x80,0x25,0x60,0x0b,0x78,0x1e,0x5e,0x50 }, - 16, 0xc260, 0, {0xb7,0x80,0x2d,0xa0,0x0b,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc270, 0, {0x48,0x14,0xce,0x00,0x83,0x60,0x20,0xc0,0x09,0x31,0x02,0x2c,0x00,0x93,0x00,0x28 }, - 16, 0xc280, 0, {0xc0,0x1b,0xb0,0x06,0xcc,0x80,0xb3,0x48,0x20,0xf0,0x0a,0x30,0x02,0xec,0x00,0x93 }, - 16, 0xc290, 0, {0x80,0x24,0xc0,0x0b,0xb0,0x02,0x4c,0x10,0xb3,0xc8,0x2c,0xd2,0x8b,0x30,0x02,0x12 }, - 16, 0xc2a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xbb,0x00,0xc6,0xc4,0x31,0x81 }, - 16, 0xc2b0, 0, {0x0f,0xe0,0x03,0x68,0x00,0xce,0x80,0x3f,0xa2,0x0b,0xe8,0x03,0xf9,0x00,0xfe,0x40 }, - 16, 0xc2c0, 0, {0x31,0x80,0x6e,0xa0,0x07,0xe8,0x00,0xda,0x00,0x26,0x81,0x0f,0xa0,0x02,0x68,0x01 }, - 16, 0xc2d0, 0, {0xf6,0xe0,0x3d,0x92,0x0f,0xa0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc2e0, 0, {0x48,0x00,0xe0,0xc2,0xf8,0x04,0x3e,0x14,0x0f,0x80,0x13,0xe0,0x10,0xf8,0x01,0x3e }, - 16, 0xc2f0, 0, {0x10,0x0f,0x80,0x43,0xe0,0x00,0xb8,0x00,0x3e,0x00,0x47,0x80,0x03,0xe0,0x02,0xe8 }, - 16, 0xc300, 0, {0x10,0x3e,0x00,0x0f,0x80,0x07,0xa0,0x00,0xf8,0x00,0x2e,0x00,0x0f,0x80,0x0b,0xd2 }, - 16, 0xc310, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x01,0x32,0x40 }, - 16, 0xc320, 0, {0x8c,0x90,0x03,0xe4,0x00,0xc9,0x00,0x36,0x42,0x0f,0x90,0x03,0xa4,0x00,0xc9,0x00 }, - 16, 0xc330, 0, {0x3e,0x42,0x0d,0x90,0x03,0x64,0x00,0xd9,0x00,0x3e,0x40,0x0f,0x90,0x0b,0x64,0x00 }, - 16, 0xc340, 0, {0xf9,0x90,0x32,0x41,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc350, 0, {0x80,0x04,0x64,0x00,0xb9,0xc8,0xa2,0x60,0x0a,0x92,0x02,0xe4,0x00,0x89,0x40,0x2e }, - 16, 0xc360, 0, {0x58,0x0b,0x90,0x02,0x04,0x00,0xd9,0x00,0x2e,0x42,0x08,0x90,0x02,0xe4,0x04,0x89 }, - 16, 0xc370, 0, {0x00,0x2e,0x40,0x0b,0x90,0x06,0x24,0x04,0xb9,0x08,0x2a,0x40,0x48,0x90,0x12,0x20 }, - 16, 0xc380, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x10,0x22,0x44 }, - 16, 0xc390, 0, {0x08,0x90,0x02,0xe4,0x00,0x89,0x00,0x22,0x45,0x8b,0x90,0x02,0xa4,0x00,0x89,0x00 }, - 16, 0xc3a0, 0, {0x2a,0x40,0x09,0x90,0x02,0xe4,0x00,0x99,0x80,0x2e,0x40,0x0b,0x90,0x26,0x24,0x00 }, - 16, 0xc3b0, 0, {0xb9,0x01,0x22,0x70,0x09,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc3c0, 0, {0x08,0x04,0x04,0x08,0xb1,0x20,0x20,0x40,0x0a,0x10,0x02,0xc4,0x80,0x83,0x00,0x2c }, - 16, 0xc3d0, 0, {0x50,0x4b,0x10,0x02,0x24,0x00,0x91,0x00,0x2e,0x40,0x08,0x12,0x02,0xc4,0x81,0x81 }, - 16, 0xc3e0, 0, {0xa2,0x6c,0x40,0x0b,0x12,0x02,0x04,0x80,0xb9,0x20,0x2a,0x48,0x29,0x12,0x02,0x02 }, - 16, 0xc3f0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x00,0x32,0x80 }, - 16, 0xc400, 0, {0x08,0x80,0x03,0xe1,0x42,0xc8,0x00,0x32,0x00,0x1f,0x85,0x03,0xa1,0x40,0xc8,0x50 }, - 16, 0xc410, 0, {0x3a,0x00,0x8d,0x85,0x03,0x61,0x40,0xd8,0x00,0x3e,0x00,0x0f,0x05,0x03,0x21,0x40 }, - 16, 0xc420, 0, {0xf8,0x50,0x32,0x14,0x0d,0x85,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc430, 0, {0x98,0x1d,0xf4,0x04,0xfd,0x10,0x3f,0x40,0x0f,0x50,0x03,0xc4,0x40,0xfd,0x00,0x3f }, - 16, 0xc440, 0, {0x51,0x0f,0xd0,0x03,0xf4,0x00,0xff,0x01,0x3d,0x40,0x0f,0x91,0x03,0xe4,0x40,0xfd }, - 16, 0xc450, 0, {0x10,0x3f,0x4a,0x0f,0x91,0x03,0xe4,0x40,0xfd,0x10,0x3f,0x44,0x0e,0x91,0x03,0xe6 }, - 16, 0xc460, 0, {0x02,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xc5,0x00,0xcd,0x00,0x31,0x40 }, - 16, 0xc470, 0, {0x0d,0xd0,0x43,0xe4,0x00,0xcd,0x00,0x33,0x40,0x4f,0x11,0x02,0xe4,0x04,0xc1,0x00 }, - 16, 0xc480, 0, {0x3d,0x40,0x0c,0x90,0x03,0xe4,0x00,0xed,0xa4,0x32,0x50,0x0f,0x90,0x03,0xe4,0x00 }, - 16, 0xc490, 0, {0xfd,0x00,0x3f,0x40,0x0f,0x90,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc4a0, 0, {0x38,0x10,0xe2,0x08,0xd8,0x00,0x32,0x01,0x00,0x80,0x12,0xc0,0x00,0x48,0x00,0x36 }, - 16, 0xc4b0, 0, {0x80,0x0b,0x8a,0x02,0xe0,0x00,0xa8,0x00,0x2e,0x00,0x0f,0x80,0x02,0xe0,0x00,0x88 }, - 16, 0xc4c0, 0, {0x50,0x34,0x28,0x0b,0x80,0x02,0xe0,0x00,0xb8,0x00,0x2e,0x00,0x0b,0x80,0x02,0xce }, - 16, 0xc4d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0x81,0x00,0x26,0x40 }, - 16, 0xc4e0, 0, {0x09,0x18,0x02,0xc4,0x08,0x21,0x00,0x28,0x40,0x8b,0x10,0x02,0xc4,0x00,0xb1,0x01 }, - 16, 0xc4f0, 0, {0x2e,0x40,0x18,0x10,0x02,0xc4,0x00,0xa1,0x01,0x20,0x48,0x1b,0x10,0x02,0xc4,0x00 }, - 16, 0xc500, 0, {0xb1,0x00,0x6c,0x40,0x0b,0x10,0x12,0xc2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc510, 0, {0x18,0x11,0xa4,0x00,0x99,0x80,0xa2,0x42,0x48,0x90,0x02,0xe4,0x00,0xa9,0x2a,0x26 }, - 16, 0xc520, 0, {0x44,0x0b,0x90,0x82,0xc4,0x81,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x42,0xc4,0x00,0x89 }, - 16, 0xc530, 0, {0x00,0x26,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x01,0x2e,0x41,0x0b,0x90,0x02,0xc6 }, - 16, 0xc540, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xc5,0x20,0xc9,0x84,0x30,0x70 }, - 16, 0xc550, 0, {0x0d,0x90,0x13,0xe4,0x02,0xe9,0x00,0x32,0x70,0x0f,0x94,0x03,0xe4,0x00,0xf9,0x40 }, - 16, 0xc560, 0, {0x3c,0x48,0x0c,0x90,0x03,0xe4,0x00,0xe1,0x00,0x32,0x40,0x0f,0x90,0x01,0xe4,0x00 }, - 16, 0xc570, 0, {0xf9,0x90,0x3e,0x60,0x0f,0x90,0x26,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc580, 0, {0x28,0x01,0xa5,0x00,0xf1,0x04,0x3a,0x44,0x8f,0x90,0x03,0xe4,0x10,0xc9,0x04,0x3e }, - 16, 0xc590, 0, {0x60,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x20,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x10,0xf9 }, - 16, 0xc5a0, 0, {0x90,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x80,0x3e,0x64,0x0f,0x90,0x07,0xca }, - 16, 0xc5b0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xc8,0x04,0x3a,0x00 }, - 16, 0xc5c0, 0, {0x1e,0x80,0x03,0x80,0x03,0xc8,0x40,0x2a,0x04,0x1f,0x80,0x03,0x20,0x00,0x88,0x00 }, - 16, 0xc5d0, 0, {0x32,0x30,0x0c,0x80,0x03,0x20,0x00,0xf8,0x00,0x3e,0x00,0x0c,0x80,0x03,0xe0,0x00 }, - 16, 0xc5e0, 0, {0xc8,0x80,0x3e,0x20,0x0f,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc5f0, 0, {0x28,0x05,0x38,0x00,0xae,0xd0,0x37,0x80,0x08,0xec,0x46,0x38,0x00,0xd6,0x04,0x23 }, - 16, 0xc600, 0, {0xa0,0x0b,0xa0,0x41,0x78,0x04,0xfa,0x00,0x37,0x80,0x0d,0xa0,0x02,0xa8,0x10,0xee }, - 16, 0xc610, 0, {0x21,0x2e,0x80,0x08,0xa0,0x02,0xe8,0x08,0x8e,0x80,0x2f,0xa0,0x8b,0xa0,0x02,0xca }, - 16, 0xc620, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x4c,0x02,0x83,0xc0,0xa8,0xe8 }, - 16, 0xc630, 0, {0x4a,0x36,0x02,0x8c,0x00,0x13,0xa0,0x28,0xc2,0x0b,0x30,0x06,0x0c,0x00,0xb3,0x00 }, - 16, 0xc640, 0, {0x24,0x84,0x09,0x30,0x02,0x0c,0x00,0xb3,0x20,0x28,0xc0,0x09,0x30,0x02,0xcc,0x00 }, - 16, 0xc650, 0, {0x83,0x80,0x2c,0xc0,0x0b,0x30,0x02,0xca,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc660, 0, {0xa0,0x01,0x3c,0x44,0xaf,0x40,0x25,0xc2,0x48,0xf8,0x82,0x1c,0xc8,0x9f,0x08,0x21 }, - 16, 0xc670, 0, {0xc0,0x8b,0xf8,0x02,0x5c,0x00,0xbf,0xb0,0x27,0x80,0x09,0x3a,0x02,0x9c,0x00,0xa5 }, - 16, 0xc680, 0, {0x02,0x2d,0xe8,0x09,0x70,0x02,0xce,0x80,0x85,0x08,0x2d,0xc2,0x0b,0x73,0x02,0xe8 }, - 16, 0xc690, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x82,0xa9,0xe0 }, - 16, 0xc6a0, 0, {0x0a,0x78,0x02,0x9e,0x40,0x97,0x84,0x39,0xa0,0x0b,0x7a,0x83,0x3f,0x80,0xd7,0x91 }, - 16, 0xc6b0, 0, {0x35,0xa0,0x0d,0x7a,0x09,0x1e,0x44,0xf7,0x80,0x3d,0xe8,0x2d,0x7a,0x03,0xde,0x82 }, - 16, 0xc6c0, 0, {0xc6,0x80,0x3d,0x20,0x4b,0x7b,0x23,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc6d0, 0, {0x08,0x1d,0xac,0x00,0xd3,0x00,0x3e,0xc1,0x0f,0x30,0x03,0xed,0x80,0xe3,0x00,0x3e }, - 16, 0xc6e0, 0, {0x80,0x0f,0xb6,0x21,0xec,0x08,0xdb,0x21,0x3e,0x80,0x0f,0xb5,0x03,0x6c,0x40,0xf9 }, - 16, 0xc6f0, 0, {0x00,0x3e,0xdc,0x0e,0xb2,0x03,0xed,0x40,0xf9,0x02,0x3e,0x80,0x0f,0xb0,0x03,0xc2 }, - 16, 0xc700, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xcf,0x80,0x3d,0xe0 }, - 16, 0xc710, 0, {0x0f,0xc8,0x43,0xfe,0x00,0xfe,0x84,0x3f,0xe0,0x0d,0xf8,0xc3,0xff,0x10,0xaf,0x90 }, - 16, 0xc720, 0, {0x35,0xa0,0x0c,0xfc,0x03,0x3e,0x14,0xec,0x84,0x3f,0xf0,0x0e,0xfc,0xc3,0xff,0x08 }, - 16, 0xc730, 0, {0x4f,0x80,0x33,0xe4,0x0c,0xf8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc740, 0, {0xa8,0x11,0x9c,0x00,0xd7,0xa2,0x2d,0xc4,0x0c,0x41,0xc2,0xdc,0x00,0x74,0x00,0x25 }, - 16, 0xc750, 0, {0x80,0x0f,0x72,0x42,0xdc,0x90,0xd7,0x38,0x2d,0x98,0x0a,0x70,0x02,0x1c,0x04,0x86 }, - 16, 0xc760, 0, {0x00,0x3f,0xc0,0x0d,0x70,0x02,0xcc,0x00,0x86,0x08,0x37,0xc6,0x28,0x70,0x02,0x2a }, - 16, 0xc770, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x60,0x2d,0xc2 }, - 16, 0xc780, 0, {0x0a,0x50,0x02,0xdc,0x00,0xb6,0x10,0x25,0xc2,0x09,0x70,0x86,0xdc,0x30,0x97,0x00 }, - 16, 0xc790, 0, {0x25,0x80,0x08,0x30,0x02,0x5c,0x00,0x87,0x08,0x2d,0xc0,0x08,0x70,0x02,0xcc,0x40 }, - 16, 0xc7a0, 0, {0x86,0x00,0x21,0x00,0x09,0x70,0x0a,0x00,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc7b0, 0, {0x20,0x14,0xed,0x80,0x93,0x00,0x0c,0xe1,0x28,0x18,0x02,0xcc,0x08,0xa0,0x00,0x24 }, - 16, 0xc7c0, 0, {0x12,0x1a,0x34,0x02,0xcf,0x04,0x93,0x40,0x2c,0x80,0x0a,0xb0,0x22,0x4c,0x02,0x81 }, - 16, 0xc7d0, 0, {0x80,0x28,0xe0,0x28,0x30,0x02,0xcc,0x00,0x88,0x82,0x24,0x20,0x08,0xb0,0x02,0x08 }, - 16, 0xc7e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbf,0x20,0xc9,0xe0,0x2c,0xf1 }, - 16, 0xc7f0, 0, {0x0e,0xbd,0x03,0xfc,0x00,0xb9,0x40,0x36,0x40,0x09,0xf5,0x02,0xfd,0x40,0xff,0x80 }, - 16, 0xc800, 0, {0x36,0xa2,0x08,0xf0,0x0b,0x7c,0x00,0xeb,0x80,0x2f,0xe0,0x0a,0xf0,0x43,0xfc,0x02 }, - 16, 0xc810, 0, {0x8b,0xd0,0x32,0xf0,0x0d,0xf0,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc820, 0, {0x80,0x00,0xec,0x10,0xfb,0x00,0x3e,0xc8,0x0f,0x94,0x13,0xec,0x00,0xf9,0x40,0x36 }, - 16, 0xc830, 0, {0x40,0x1f,0xb0,0x03,0xec,0x10,0xfb,0x01,0x3e,0xd0,0x0f,0xb0,0x03,0xac,0x00,0xf9 }, - 16, 0xc840, 0, {0x00,0x3e,0xc4,0x0f,0xb0,0x01,0xec,0x00,0xf9,0x04,0x3e,0x48,0x0f,0xb0,0x03,0xe0 }, - 16, 0xc850, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xdf,0x00,0x3f,0xc0 }, - 16, 0xc860, 0, {0x0c,0xe0,0x07,0xfc,0x00,0xfc,0x0a,0x27,0x00,0x4f,0xf0,0x03,0xfc,0x00,0xff,0x08 }, - 16, 0xc870, 0, {0x33,0x80,0x0c,0xf0,0x00,0x2c,0x00,0x5f,0x00,0x33,0xc0,0x0c,0xf0,0x01,0xfc,0x00 }, - 16, 0xc880, 0, {0xfe,0x00,0x23,0x40,0x0f,0xb0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc890, 0, {0x81,0x04,0x6c,0x00,0x8b,0x86,0x2e,0xe0,0x48,0x8f,0x02,0xec,0x08,0xb8,0xa0,0x36 }, - 16, 0xc8a0, 0, {0x30,0x4b,0xb0,0x03,0xac,0x0c,0x9b,0x02,0x3c,0xa0,0x0c,0xb0,0x43,0x6c,0x00,0xb1 }, - 16, 0xc8b0, 0, {0x00,0x28,0xc0,0x0d,0xb0,0x12,0xec,0x10,0xb9,0x80,0xa2,0x61,0x0b,0xb0,0x02,0x20 }, - 16, 0xc8c0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x9b,0x88,0x2e,0xe0 }, - 16, 0xc8d0, 0, {0x08,0xa0,0x02,0xec,0x01,0xbb,0x80,0x26,0x62,0x0b,0xb0,0x02,0xec,0x00,0xb3,0x01 }, - 16, 0xc8e0, 0, {0x2a,0x21,0x08,0xb0,0x12,0x2c,0x00,0xb8,0x00,0x22,0xc0,0x08,0xb0,0x12,0xec,0x14 }, - 16, 0xc8f0, 0, {0xb9,0x84,0x22,0xa2,0x0b,0xb0,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc900, 0, {0x08,0x04,0x0c,0x04,0x93,0x00,0x2c,0xe0,0x08,0x00,0x02,0xcc,0x09,0x91,0x00,0x20 }, - 16, 0xc910, 0, {0x40,0x0b,0x30,0x06,0x4c,0x04,0x13,0x00,0x26,0x00,0x08,0x30,0x02,0xcc,0x04,0xb2 }, - 16, 0xc920, 0, {0x00,0x2a,0xc0,0x01,0x30,0x00,0xcd,0x00,0xb0,0x00,0x20,0x80,0x0b,0x30,0x0a,0x02 }, - 16, 0xc930, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xdb,0x24,0x6e,0xc0 }, - 16, 0xc940, 0, {0x2c,0xa0,0x02,0xfc,0x00,0xba,0x04,0x26,0x40,0x4f,0xf0,0x57,0xfc,0x00,0x3f,0x01 }, - 16, 0xc950, 0, {0x3a,0x00,0x2c,0xf0,0x01,0x3c,0x00,0xdb,0x00,0x33,0xc0,0x84,0xf0,0x03,0xfd,0x08 }, - 16, 0xc960, 0, {0xfa,0x00,0x32,0x00,0x0f,0xf0,0x03,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc970, 0, {0xa0,0x19,0xdc,0x00,0xea,0x40,0x3f,0x00,0x07,0xc0,0x03,0xfc,0x04,0xfc,0x00,0x3f }, - 16, 0xc980, 0, {0x40,0x0f,0xf0,0x03,0x9c,0x00,0xff,0x00,0x3f,0x00,0x0e,0xf0,0x03,0x7c,0x00,0xfd }, - 16, 0xc990, 0, {0x00,0x3f,0xc1,0x0f,0xf0,0x03,0xfc,0x84,0xf4,0x00,0x3f,0x00,0x0f,0xf0,0x03,0xe8 }, - 16, 0xc9a0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf0,0x80,0xff,0x00,0x03,0xc2 }, - 16, 0xc9b0, 0, {0x0f,0xc2,0x03,0x3e,0x00,0xdf,0xc0,0x3e,0xc0,0x4d,0xdb,0x02,0xb0,0xc0,0xdc,0x30 }, - 16, 0xc9c0, 0, {0x3f,0xe0,0x0f,0xdb,0x23,0xf6,0x20,0xff,0x26,0x33,0xe0,0x0f,0x52,0x03,0x5e,0x00 }, - 16, 0xc9d0, 0, {0xff,0x80,0x33,0xc0,0x4c,0x49,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc9e0, 0, {0x80,0x10,0xe1,0xe0,0xb7,0x08,0x23,0xf0,0x0b,0xad,0x0a,0x2e,0x00,0x9a,0x04,0x2e }, - 16, 0xc9f0, 0, {0xb0,0x09,0x8f,0x03,0xa0,0x40,0xb9,0x30,0x2e,0xa0,0x0b,0x9f,0x03,0xa7,0x00,0xbb }, - 16, 0xca00, 0, {0x80,0x26,0xe0,0x0b,0xdd,0x02,0x2e,0x00,0xbb,0x80,0x22,0xf4,0x0a,0x92,0x02,0xa0 }, - 16, 0xca10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x80,0xb3,0x10,0x24,0xc0 }, - 16, 0xca20, 0, {0x0b,0x80,0x02,0xac,0x00,0xa3,0x24,0x2c,0xd0,0x08,0x10,0x06,0xc0,0x80,0xb2,0x01 }, - 16, 0xca30, 0, {0x2c,0xea,0x4b,0x00,0x12,0xc2,0x04,0xb3,0x10,0x08,0xc0,0x0a,0x90,0x02,0x0c,0x00 }, - 16, 0xca40, 0, {0x93,0x04,0x24,0xc0,0x09,0x82,0x02,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xca50, 0, {0xc0,0x15,0xa5,0x00,0xbb,0x00,0x22,0xc0,0x0b,0x80,0x02,0xac,0x08,0xbb,0x18,0x2e }, - 16, 0xca60, 0, {0xe0,0x18,0x88,0x02,0xec,0x01,0xba,0x00,0x2e,0x80,0x0b,0x98,0x86,0xe2,0x00,0xbb }, - 16, 0xca70, 0, {0x00,0x22,0xc4,0x0b,0x90,0x02,0x6c,0x00,0xbb,0x00,0xa6,0xc0,0x0b,0x90,0x00,0xb0 }, - 16, 0xca80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xe7,0x00,0xfb,0x00,0xb2,0xc0 }, - 16, 0xca90, 0, {0x0f,0xa8,0x03,0xac,0x02,0xeb,0x00,0x3e,0x60,0x0d,0x9e,0x03,0xec,0x00,0xd8,0x40 }, - 16, 0xcaa0, 0, {0x3e,0x40,0x0f,0x88,0x43,0xe2,0x00,0xfb,0x20,0x32,0xc0,0x0f,0x10,0x0b,0x6f,0x90 }, - 16, 0xcab0, 0, {0x5b,0x82,0x36,0xc0,0x2d,0x08,0x01,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcac0, 0, {0xe0,0x01,0xb7,0x08,0xf7,0x00,0x3f,0xc0,0x0f,0xf9,0x03,0x7c,0x08,0xcf,0x82,0x3c }, - 16, 0xcad0, 0, {0x00,0xaf,0xd0,0x21,0xbc,0x08,0xfd,0x10,0x3f,0x80,0x8f,0xc0,0x03,0xa4,0x00,0xf7 }, - 16, 0xcae0, 0, {0x01,0xbf,0xc0,0x07,0xd0,0x03,0xbd,0x30,0xff,0xa4,0x38,0xc0,0x0e,0xda,0x03,0xf8 }, - 16, 0xcaf0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa8,0x00,0xfb,0x00,0xb2,0xc1 }, - 16, 0xcb00, 0, {0x0e,0x81,0x03,0xec,0x40,0xfb,0x44,0x3a,0xc1,0x0e,0x95,0x03,0xe0,0x00,0xcb,0x41 }, - 16, 0xcb10, 0, {0x32,0x4d,0x0f,0x81,0x03,0xe0,0x20,0xc9,0x00,0x72,0xe8,0x44,0x91,0x03,0x6d,0x00 }, - 16, 0xcb20, 0, {0xcb,0x02,0x3e,0xc0,0x0c,0x80,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcb30, 0, {0xc8,0x05,0x24,0x00,0xbf,0x00,0x33,0xc4,0x08,0x1d,0x03,0x8c,0x00,0xbb,0x98,0x36 }, - 16, 0xcb40, 0, {0x48,0x4d,0x98,0x22,0xed,0x40,0xdb,0x00,0x36,0xb0,0x0b,0x98,0x02,0xe3,0x00,0xdb }, - 16, 0xcb50, 0, {0x00,0x32,0xe0,0x88,0xd8,0x02,0x2c,0x02,0xc3,0x80,0x2f,0xc0,0x08,0x90,0x03,0x72 }, - 16, 0xcb60, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x44,0x00,0xb3,0x00,0x20,0xf0 }, - 16, 0xcb70, 0, {0x18,0x08,0x02,0x4f,0x84,0xb1,0xc0,0x24,0xc0,0x89,0x06,0x02,0xc4,0x00,0x91,0x00 }, - 16, 0xcb80, 0, {0x20,0xf0,0x1b,0x18,0x82,0xc6,0x00,0x93,0x00,0x2c,0xd1,0x08,0x1e,0x02,0x0e,0x44 }, - 16, 0xcb90, 0, {0x93,0x94,0x2c,0xc0,0x08,0x20,0x02,0xb8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcba0, 0, {0x20,0x01,0x1e,0x04,0xb7,0x80,0x20,0xe2,0x08,0x68,0x06,0x9e,0x80,0xbf,0x84,0x25 }, - 16, 0xcbb0, 0, {0xa8,0x09,0x68,0x02,0xc6,0x00,0x93,0xa0,0x65,0xe4,0x0b,0x78,0x12,0xde,0x00,0x93 }, - 16, 0xcbc0, 0, {0x00,0xa1,0xe0,0x08,0xd8,0x02,0x1e,0xd0,0xa7,0x80,0x2d,0xe0,0x08,0xf8,0x02,0x48 }, - 16, 0xcbd0, 0, {0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xb3,0x20,0x30,0xc0 }, - 16, 0xcbe0, 0, {0x0a,0x22,0x02,0xce,0x40,0xf3,0xa0,0x3c,0xe8,0x0b,0x30,0x02,0xc1,0x00,0xd0,0xc1 }, - 16, 0xcbf0, 0, {0x30,0xc0,0x0b,0x21,0x13,0xcc,0x21,0xd3,0x00,0x2c,0xc0,0x2c,0x10,0x0b,0x0c,0x80 }, - 16, 0xcc00, 0, {0xd3,0x61,0x3c,0xc8,0x2c,0x20,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcc10, 0, {0x40,0x1d,0xbc,0x00,0xff,0x40,0x3b,0xc0,0x0f,0xe0,0x03,0xfc,0x00,0xf7,0x50,0x7f }, - 16, 0xcc20, 0, {0xc4,0x2e,0xf0,0x03,0xfc,0x40,0xfe,0x00,0x3f,0xc0,0x0f,0xf0,0x47,0xfc,0x00,0xff }, - 16, 0xcc30, 0, {0x00,0x7d,0xc2,0x0f,0xd0,0x01,0xbc,0x80,0x5f,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xd0 }, - 16, 0xcc40, 0, {0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xfb,0xc0,0x32,0xc8 }, - 16, 0xcc50, 0, {0x0e,0xe0,0x03,0xac,0xa0,0xeb,0x20,0x32,0x40,0x8c,0xa0,0x13,0x2c,0x00,0xd9,0x00 }, - 16, 0xcc60, 0, {0x3e,0x60,0x0c,0xb0,0x03,0xe8,0x00,0xfa,0x80,0x30,0xc0,0x3c,0x92,0x03,0xef,0x60 }, - 16, 0xcc70, 0, {0xc3,0x20,0x31,0xc4,0x0c,0xa0,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcc80, 0, {0x48,0x11,0x9c,0x00,0x33,0x20,0x21,0xda,0x0b,0x70,0x43,0x9c,0x01,0xb5,0x00,0x21 }, - 16, 0xcc90, 0, {0x00,0x0a,0xe0,0x02,0x1c,0x00,0xb7,0x00,0x2f,0xc0,0x0d,0x70,0x03,0x9c,0x00,0xb6 }, - 16, 0xcca0, 0, {0x00,0x31,0xc8,0x08,0x57,0x02,0xdc,0x00,0x87,0x50,0x21,0xc0,0x0a,0x70,0x42,0x92 }, - 16, 0xccb0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x11,0xb7,0x90,0x21,0xe0 }, - 16, 0xccc0, 0, {0x0b,0x68,0x82,0xde,0x08,0xa7,0x80,0x24,0x60,0x08,0x70,0x12,0x12,0x08,0x95,0x80 }, - 16, 0xccd0, 0, {0x2d,0x60,0x09,0x6c,0x02,0xde,0x00,0xb1,0x80,0x23,0xe0,0x0a,0x58,0x62,0xfe,0x00 }, - 16, 0xcce0, 0, {0x97,0xa0,0x21,0xe8,0x09,0xe8,0x02,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xccf0, 0, {0x48,0x14,0xcd,0x00,0xb3,0x00,0x20,0xc0,0x8b,0x3c,0x02,0x8c,0x00,0xbb,0x00,0x24 }, - 16, 0xcd00, 0, {0xc4,0x1a,0x3d,0x02,0x2f,0x88,0xb3,0x48,0x2c,0xe0,0x89,0x3e,0x02,0x8d,0x80,0x93 }, - 16, 0xcd10, 0, {0xd9,0xa4,0x40,0x88,0x10,0x02,0xcc,0x04,0x93,0xc8,0x20,0xc0,0x0b,0x30,0x02,0x92 }, - 16, 0xcd20, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x40,0xfa,0x00,0xb2,0x80 }, - 16, 0xcd30, 0, {0x0f,0xe0,0x03,0xe8,0x00,0xea,0x80,0x37,0xa0,0x0c,0xe8,0x13,0x3b,0x08,0xde,0x01 }, - 16, 0xcd40, 0, {0x3f,0x82,0x0c,0xe0,0x43,0xfa,0x80,0xfe,0x80,0x31,0x28,0x0c,0xa0,0x03,0xf0,0x02 }, - 16, 0xcd50, 0, {0xc4,0xc0,0xb2,0x80,0x0d,0xe0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcd60, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x10,0x0b,0x80,0x83,0xe0,0x00,0xf8,0x30,0x3a }, - 16, 0xcd70, 0, {0x00,0x6d,0x80,0x83,0xe1,0x44,0xb8,0x04,0x3e,0x10,0x0f,0x80,0x13,0xe0,0x00,0xf8 }, - 16, 0xcd80, 0, {0x00,0x3a,0x10,0x4f,0x04,0x03,0xe3,0x00,0xe8,0x10,0x3e,0x00,0x0e,0x80,0x03,0xd2 }, - 16, 0xcd90, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc9,0x00,0x38,0x40 }, - 16, 0xcda0, 0, {0x0f,0x1a,0x03,0x2e,0x00,0xfb,0xa0,0x36,0x60,0x0c,0x98,0x03,0xe6,0x04,0xd1,0x00 }, - 16, 0xcdb0, 0, {0x36,0x48,0x0e,0x91,0x02,0xe6,0x00,0xf9,0x00,0x3e,0x00,0x0c,0x99,0x03,0x62,0x40 }, - 16, 0xcdc0, 0, {0xf8,0x00,0xa0,0x68,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcdd0, 0, {0x80,0x04,0x64,0x02,0x89,0x04,0x2e,0x64,0x88,0x94,0x02,0xa5,0x00,0xb9,0x80,0x20 }, - 16, 0xcde0, 0, {0x64,0x0d,0x9c,0x02,0xe6,0x42,0x89,0x00,0x22,0x60,0x0b,0x9c,0x02,0xe4,0x10,0xb9 }, - 16, 0xcdf0, 0, {0x40,0x3a,0x50,0x08,0x9c,0x02,0x27,0x20,0xb9,0x00,0x22,0x40,0x08,0x10,0x03,0x60 }, - 16, 0xce00, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x89,0x00,0x22,0x40 }, - 16, 0xce10, 0, {0x0a,0x90,0x82,0x25,0x4c,0xb9,0x00,0x02,0x40,0x08,0x96,0x02,0xe4,0x10,0x89,0x00 }, - 16, 0xce20, 0, {0x26,0x50,0x13,0x94,0x02,0xe4,0x40,0xb9,0x08,0x2e,0x40,0x08,0x90,0x8a,0x24,0x00 }, - 16, 0xce30, 0, {0xb9,0x01,0x2a,0x40,0x08,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xce40, 0, {0x08,0x04,0x05,0x80,0x81,0x40,0x2c,0xc8,0x08,0x10,0x06,0x84,0x00,0xb1,0x04,0x20 }, - 16, 0xce50, 0, {0x49,0x09,0x14,0x42,0xcc,0x89,0x81,0x20,0x20,0x50,0x0b,0x14,0x46,0xc4,0x00,0xb1 }, - 16, 0xce60, 0, {0x00,0x2a,0xc0,0x28,0x14,0x02,0x01,0x01,0xb0,0x04,0x28,0x40,0x38,0x94,0x02,0x42 }, - 16, 0xce70, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0x88,0x00,0x3a,0x00 }, - 16, 0xce80, 0, {0x0e,0x80,0x23,0x20,0x00,0xf8,0x50,0xb2,0x00,0x0c,0x80,0x12,0xe1,0x40,0xd8,0x50 }, - 16, 0xce90, 0, {0x36,0x00,0x0e,0x80,0x03,0xe0,0x00,0xf8,0x00,0x2e,0x00,0x0c,0x80,0x53,0x60,0x04 }, - 16, 0xcea0, 0, {0xf8,0x00,0x3a,0x00,0x0c,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xceb0, 0, {0x98,0x1d,0xf4,0x40,0xf9,0x44,0x3e,0x44,0x0f,0xd4,0x03,0xe4,0x00,0xf1,0x00,0x3f }, - 16, 0xcec0, 0, {0x44,0x0f,0xd4,0x53,0xf4,0x44,0xfd,0x10,0x2f,0x40,0x0f,0xf4,0x03,0xfd,0x00,0xfd }, - 16, 0xced0, 0, {0x40,0x3b,0x10,0x0f,0xd4,0x23,0xd1,0x04,0x7c,0x43,0x36,0x50,0x0f,0x50,0x03,0xe6 }, - 16, 0xcee0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa6,0x00,0xf9,0x10,0x2e,0x62 }, - 16, 0xcef0, 0, {0x0f,0xd2,0x83,0xe4,0x00,0xbd,0x42,0x3e,0x61,0x0f,0xd0,0x03,0xf6,0xc0,0xc9,0xa2 }, - 16, 0xcf00, 0, {0x2b,0x40,0x0c,0xd0,0x03,0x34,0x00,0xf9,0x81,0x3e,0x68,0x08,0xc1,0x43,0xfa,0x00 }, - 16, 0xcf10, 0, {0xf5,0x80,0x3f,0x62,0x0c,0x14,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcf20, 0, {0x38,0x10,0xe1,0x20,0x88,0x11,0x2e,0x10,0x0b,0x80,0x02,0xe0,0x00,0xb8,0x82,0x2e }, - 16, 0xcf30, 0, {0x10,0x0b,0x80,0x00,0xe3,0xc4,0x88,0xf0,0x22,0x00,0x0b,0x80,0x0a,0x20,0x00,0xe8 }, - 16, 0xcf40, 0, {0x40,0x2f,0x14,0x08,0x88,0x02,0xe2,0x00,0xb8,0x00,0x2e,0x00,0x08,0x88,0x02,0x8e }, - 16, 0xcf50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0xc5,0x00,0xa1,0x00,0x2c,0x40 }, - 16, 0xcf60, 0, {0x0b,0x10,0x02,0xc4,0x18,0xb1,0x22,0x6c,0xd1,0x0b,0x10,0x26,0xc4,0x00,0x81,0x08 }, - 16, 0xcf70, 0, {0x2a,0x40,0x88,0x10,0x02,0x04,0x04,0xb5,0xc0,0x0f,0x40,0x0b,0x02,0x02,0x41,0xa0 }, - 16, 0xcf80, 0, {0xb1,0x40,0x2c,0x40,0x08,0x12,0x02,0x02,0x11,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcf90, 0, {0x18,0x15,0xa4,0x00,0x89,0x06,0x2e,0x40,0x0b,0x90,0x12,0xe4,0x00,0xb9,0x40,0x2e }, - 16, 0xcfa0, 0, {0x40,0x0b,0xb0,0x82,0xc4,0x02,0x89,0x44,0x22,0x40,0x0a,0x90,0x02,0x24,0x00,0xa9 }, - 16, 0xcfb0, 0, {0x00,0x27,0x48,0x09,0xb0,0x12,0xec,0x18,0xb9,0x01,0x2e,0x40,0x40,0x90,0x02,0x86 }, - 16, 0xcfc0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x84,0xe9,0x01,0x3e,0x40 }, - 16, 0xcfd0, 0, {0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x72,0x0f,0x90,0x03,0xe7,0x60,0x89,0x10 }, - 16, 0xcfe0, 0, {0x3a,0x40,0x0c,0x90,0x03,0x24,0x00,0xf9,0x44,0x3c,0x40,0x2d,0x90,0x03,0xe7,0x60 }, - 16, 0xcff0, 0, {0xf9,0x71,0x3e,0x40,0x28,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd000, 0, {0x28,0x01,0xa4,0x48,0xa9,0x00,0x3e,0xc0,0x0f,0x9a,0x43,0xec,0x00,0xf9,0x20,0x7e }, - 16, 0xd010, 0, {0xc8,0x0f,0x9a,0x07,0x66,0x00,0x79,0x80,0x7e,0x40,0x0f,0x1c,0x03,0xe7,0x00,0xe9 }, - 16, 0xd020, 0, {0xa0,0x3e,0x40,0x46,0x80,0x03,0xe0,0x20,0xf9,0x00,0x3c,0x40,0x0f,0x90,0x03,0xca }, - 16, 0xd030, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x80,0x00,0xf8,0x00,0x3a,0x00 }, - 16, 0xd040, 0, {0x0f,0x80,0x03,0xa0,0x08,0xe8,0x40,0x3a,0x10,0x0c,0x83,0x03,0xa1,0xc0,0xf0,0x40 }, - 16, 0xd050, 0, {0x3e,0x06,0x0f,0x84,0x03,0xe1,0x00,0xf8,0x00,0x3b,0x00,0x0f,0x81,0x03,0x20,0x00 }, - 16, 0xd060, 0, {0xf8,0x10,0xb2,0x00,0x4c,0x80,0x0b,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd070, 0, {0x28,0x05,0x28,0x00,0xba,0x00,0x2e,0xb0,0x0b,0xe8,0x02,0xe9,0x00,0x3e,0x90,0x02 }, - 16, 0xd080, 0, {0x81,0x08,0xe4,0x12,0x78,0x00,0xba,0x00,0x2d,0xb0,0x89,0xe8,0x22,0xf8,0x0c,0xba }, - 16, 0xd090, 0, {0x00,0x6e,0x80,0x03,0xc5,0x03,0x30,0x00,0xba,0x00,0x22,0xa8,0x08,0xa0,0x22,0x8a }, - 16, 0xd0a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x28,0xe8 }, - 16, 0xd0b0, 0, {0x1b,0x31,0x12,0x8c,0xc4,0xa3,0x92,0x2c,0x40,0x88,0x34,0x06,0x8e,0x00,0x93,0x00 }, - 16, 0xd0c0, 0, {0x2c,0xf0,0x19,0x31,0xa2,0xcc,0x04,0xb3,0x00,0x28,0x80,0x01,0x38,0x02,0x4c,0x00 }, - 16, 0xd0d0, 0, {0xb3,0x80,0x20,0xe0,0x0a,0xb0,0x12,0x02,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd0e0, 0, {0xa0,0x01,0x1c,0x00,0xb7,0x14,0x2d,0x42,0x0b,0x60,0x02,0xdc,0x00,0xb7,0x81,0x27 }, - 16, 0xd0f0, 0, {0xe0,0x18,0x60,0x02,0x58,0x18,0xb7,0x22,0x2d,0x80,0x09,0x70,0x22,0xdc,0x00,0xb7 }, - 16, 0xd100, 0, {0x00,0x2d,0x80,0x0b,0x3b,0x02,0x1d,0xd0,0xbf,0x80,0x28,0xc0,0x8a,0xf2,0x02,0xa0 }, - 16, 0xd110, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1f,0x80,0xf7,0xa0,0x39,0xe2 }, - 16, 0xd120, 0, {0x0f,0x68,0x03,0x9e,0x00,0xed,0x84,0x3d,0xe2,0x44,0x78,0x03,0x9e,0x00,0xf7,0xb4 }, - 16, 0xd130, 0, {0x2d,0xe0,0x0d,0x68,0x03,0xd6,0x00,0xf6,0x80,0x39,0xe0,0x0f,0x79,0x03,0x5e,0x90 }, - 16, 0xd140, 0, {0xf7,0x81,0x31,0x60,0x2e,0x7c,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd150, 0, {0x08,0x1d,0xad,0x00,0xfb,0x42,0x3e,0xc8,0x0f,0xa0,0x03,0xed,0xa0,0xbb,0x00,0x38 }, - 16, 0xd160, 0, {0xc8,0x0f,0xb0,0x03,0x68,0x00,0xfb,0x11,0x3e,0x40,0x09,0xb0,0x41,0xec,0x00,0xfa }, - 16, 0xd170, 0, {0x02,0x3e,0xc0,0x0f,0xb2,0x0b,0xed,0x80,0x3b,0x00,0x36,0x40,0x0d,0xb0,0x23,0x42 }, - 16, 0xd180, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x00,0xcf,0xd0,0x33,0xe4 }, - 16, 0xd190, 0, {0x4f,0xf9,0x03,0xde,0x40,0xdc,0x80,0x36,0xe4,0x0c,0xb9,0x13,0xfe,0x00,0xcf,0x90 }, - 16, 0xd1a0, 0, {0x37,0xe5,0x0f,0xf8,0x43,0xfe,0x00,0xcf,0x92,0x3f,0xa4,0x0f,0x78,0x03,0x1f,0x00 }, - 16, 0xd1b0, 0, {0xc5,0x80,0x33,0x60,0x0c,0xf8,0x20,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd1c0, 0, {0xa8,0x11,0xbc,0x00,0x0f,0x10,0x21,0x81,0x0b,0x60,0x03,0x84,0x00,0x8b,0x08,0x21 }, - 16, 0xd1d0, 0, {0x60,0x0a,0x7b,0x03,0x98,0x00,0x8b,0x10,0x29,0x84,0x0e,0x64,0x22,0xdc,0x40,0xd7 }, - 16, 0xd1e0, 0, {0x02,0x2d,0x84,0x0b,0x70,0x02,0x1c,0x00,0x85,0x18,0x21,0x40,0x0a,0xf0,0x22,0xaa }, - 16, 0xd1f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa7,0x14,0x69,0xc0 }, - 16, 0xd200, 0, {0x1a,0x60,0x12,0xfc,0x01,0xa4,0x10,0x2d,0xc0,0x0a,0x52,0x02,0x45,0x40,0x87,0x0c }, - 16, 0xd210, 0, {0x21,0x80,0x1b,0x60,0x82,0xd4,0x00,0x86,0x03,0x25,0xe0,0x1b,0x70,0x02,0x5c,0x40 }, - 16, 0xd220, 0, {0x9d,0x00,0x29,0x40,0x08,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd230, 0, {0x20,0x14,0xcd,0x00,0xa3,0x00,0x28,0xc0,0x1b,0x20,0x22,0x8c,0x11,0xa3,0x00,0x68 }, - 16, 0xd240, 0, {0xf6,0x0a,0x3c,0x06,0x82,0x00,0x83,0x80,0x28,0x84,0x0a,0x8c,0x82,0xcc,0x44,0x92 }, - 16, 0xd250, 0, {0x00,0x2c,0xc0,0x0b,0x30,0x02,0x4e,0x00,0x91,0x00,0x28,0x40,0x0a,0x30,0x02,0x88 }, - 16, 0xd260, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbe,0x22,0xef,0x04,0xba,0xc0 }, - 16, 0xd270, 0, {0x0f,0x14,0x93,0xec,0x02,0xf1,0xc3,0x3e,0xf0,0x0e,0x90,0x83,0x66,0x00,0xcf,0xd2 }, - 16, 0xd280, 0, {0x32,0x50,0x0f,0x9c,0x03,0xcb,0x00,0xc9,0x80,0x3e,0x28,0x0f,0xb0,0x03,0x4f,0x00 }, - 16, 0xd290, 0, {0xd1,0xc0,0xaa,0xc0,0x0c,0x71,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd2a0, 0, {0x80,0x00,0xec,0x20,0xdb,0x00,0x26,0x80,0x0f,0xa0,0x03,0xec,0x08,0x1b,0x00,0x36 }, - 16, 0xd2b0, 0, {0xc0,0x0f,0x86,0x01,0xe5,0x40,0xfb,0x02,0x3a,0x48,0x0e,0x94,0x03,0xec,0x80,0xf1 }, - 16, 0xd2c0, 0, {0x84,0x3e,0x00,0x4f,0xb0,0x03,0xad,0xc0,0xeb,0x20,0x36,0xc0,0x0f,0xb0,0x23,0xe0 }, - 16, 0xd2d0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xcf,0x00,0x3f,0x60 }, - 16, 0xd2e0, 0, {0x0c,0xe0,0x83,0x3e,0x80,0xed,0x08,0x33,0xd0,0x8f,0x50,0x03,0x9e,0x00,0xdf,0x00 }, - 16, 0xd2f0, 0, {0x33,0x40,0x0c,0xc0,0x03,0x30,0x00,0xcc,0x10,0x33,0x68,0x0c,0xf0,0x03,0x3c,0x84 }, - 16, 0xd300, 0, {0x8d,0x90,0x30,0x40,0x0c,0xf0,0x03,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd310, 0, {0x81,0x04,0x6c,0x00,0x8b,0x02,0x2c,0xf4,0x08,0xa8,0x62,0x0c,0x80,0x8b,0x80,0x2a }, - 16, 0xd320, 0, {0x60,0x0f,0x9c,0x02,0x2e,0x00,0x8b,0x00,0x20,0x60,0x0d,0x98,0x02,0x2c,0x80,0xd8 }, - 16, 0xd330, 0, {0x00,0x14,0x40,0x08,0x34,0x12,0x2e,0x00,0x8b,0x82,0x32,0x40,0x0d,0xb0,0x03,0x60 }, - 16, 0xd340, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x2e,0xd0 }, - 16, 0xd350, 0, {0x08,0xb8,0x02,0x2c,0x00,0x8a,0x84,0x22,0xc0,0x0b,0x88,0x02,0xe4,0xa0,0x83,0x00 }, - 16, 0xd360, 0, {0x22,0x62,0x0a,0x98,0x02,0x28,0x00,0x89,0x00,0x22,0x00,0x0a,0xb1,0x06,0x2c,0x00 }, - 16, 0xd370, 0, {0xab,0x00,0x22,0x40,0x08,0xb0,0x02,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd380, 0, {0x08,0x04,0x0c,0x02,0xa3,0x00,0x2c,0xc1,0x08,0x20,0x02,0x0c,0x02,0x8b,0x00,0x28 }, - 16, 0xd390, 0, {0xc2,0x0a,0x00,0x02,0x44,0x10,0x83,0x10,0x22,0x40,0x0b,0x10,0x06,0x0c,0x00,0x91 }, - 16, 0xd3a0, 0, {0x04,0xaa,0x00,0x28,0x30,0x02,0x2c,0x00,0xa1,0x01,0x20,0x40,0x09,0xb0,0x02,0x42 }, - 16, 0xd3b0, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0x8f,0x00,0x3e,0xc0 }, - 16, 0xd3c0, 0, {0x2c,0xa0,0x03,0x29,0x40,0xa8,0x40,0x32,0xcc,0x8b,0x80,0x02,0xe0,0x00,0xcf,0x40 }, - 16, 0xd3d0, 0, {0x32,0x00,0x0e,0x80,0x0a,0x20,0x00,0x88,0x00,0x22,0x40,0x0c,0xb0,0x03,0x2c,0x04 }, - 16, 0xd3e0, 0, {0xeb,0x00,0xb2,0x40,0x8c,0xb0,0x03,0x40,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd3f0, 0, {0xa0,0x1d,0xfc,0x00,0xdf,0x00,0x3f,0x40,0x0f,0xe0,0x03,0xfc,0x80,0xff,0x28,0x3d }, - 16, 0xd400, 0, {0xc0,0x0b,0xc1,0x03,0xb0,0x14,0xff,0x00,0x3f,0x00,0x0d,0xd0,0x03,0xdc,0x00,0xfc }, - 16, 0xd410, 0, {0x00,0x37,0x40,0x0f,0xf0,0x21,0xfc,0x00,0x1d,0x00,0x7b,0x40,0x8f,0xf0,0x03,0xe0 }, - 16, 0xd420, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd2,0x00,0xdf,0x00,0x31,0xa0 }, - 16, 0xd430, 0, {0x4d,0xf0,0x43,0x32,0x00,0xce,0x14,0x1b,0x68,0x0e,0xda,0x23,0xb2,0xc0,0x2f,0x00 }, - 16, 0xd440, 0, {0x3f,0xc2,0x2c,0xe8,0x03,0x3c,0x40,0xfd,0x08,0x3b,0xc8,0x4c,0xf0,0x83,0x3c,0xa0 }, - 16, 0xd450, 0, {0xcf,0x00,0x33,0xc4,0x0c,0xf3,0x07,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd460, 0, {0x80,0x10,0xe2,0x00,0x8f,0xc0,0x22,0xa0,0x08,0xfd,0x42,0x2f,0x00,0x8b,0x70,0x22 }, - 16, 0xd470, 0, {0x1e,0x48,0x89,0x02,0x27,0xc0,0x8f,0x5a,0x2e,0x50,0x48,0x30,0x02,0xbd,0xc0,0xbd }, - 16, 0xd480, 0, {0x40,0x23,0xc5,0x48,0xf4,0x82,0x3d,0x2c,0x87,0x70,0x22,0xc0,0x08,0xf1,0x03,0xe0 }, - 16, 0xd490, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe0,0x00,0x93,0x10,0x26,0x81 }, - 16, 0xd4a0, 0, {0x49,0x30,0x02,0x80,0x40,0x83,0x20,0x28,0x40,0x0a,0x10,0x02,0x80,0x00,0xa3,0x24 }, - 16, 0xd4b0, 0, {0x2c,0xca,0x08,0x32,0x82,0x0c,0x00,0x91,0x28,0x20,0xca,0x1b,0x32,0x02,0x0c,0x88 }, - 16, 0xd4c0, 0, {0x83,0x09,0x20,0xc8,0x09,0x32,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd4d0, 0, {0xc0,0x15,0xa3,0x14,0x8b,0x04,0x26,0x89,0x08,0xb0,0x02,0xac,0x22,0x8b,0x88,0x2a }, - 16, 0xd4e0, 0, {0x20,0x08,0x98,0x82,0xa6,0x10,0xab,0x00,0x2e,0xca,0x08,0xb0,0x82,0xac,0x00,0xb9 }, - 16, 0xd4f0, 0, {0x00,0x22,0xc0,0x29,0xb0,0x0a,0x2c,0x01,0x8b,0x00,0x22,0xc0,0x09,0xb0,0x22,0xf0 }, - 16, 0xd500, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe3,0x00,0xdb,0x00,0x34,0xe2 }, - 16, 0xd510, 0, {0x0d,0xb0,0x03,0xa3,0x00,0xca,0x80,0xba,0x70,0x0e,0x88,0x03,0xa6,0x00,0xeb,0x00 }, - 16, 0xd520, 0, {0x3e,0x90,0x0c,0xb5,0x03,0x2c,0x00,0xfb,0x10,0xba,0xc0,0x0e,0xb0,0x03,0x2c,0x02 }, - 16, 0xd530, 0, {0xcb,0x02,0x32,0xc0,0x09,0xb0,0x02,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd540, 0, {0xe0,0x01,0xb0,0x08,0xff,0x00,0xbb,0xe0,0x0f,0x70,0x03,0x65,0x00,0xf4,0x00,0x35 }, - 16, 0xd550, 0, {0x40,0x0f,0x40,0x03,0x54,0x00,0xdf,0x00,0x3e,0x40,0x0f,0xf8,0x03,0xec,0x00,0xf7 }, - 16, 0xd560, 0, {0x01,0x3d,0xc1,0x0e,0x30,0x03,0xec,0x00,0xff,0x00,0x3f,0xc0,0x8e,0xf0,0x03,0xb8 }, - 16, 0xd570, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa0,0x40,0xeb,0x08,0x3e,0x80 }, - 16, 0xd580, 0, {0x0d,0xb0,0x03,0xe0,0x00,0xc8,0x00,0x3a,0x51,0x0f,0x82,0x03,0x64,0x20,0xdb,0x00 }, - 16, 0xd590, 0, {0x3d,0x82,0x0c,0xbc,0x03,0x2c,0x10,0xdb,0x00,0x72,0xc0,0x0d,0xb1,0x03,0x0c,0x20 }, - 16, 0xd5a0, 0, {0xd3,0x00,0x32,0xc0,0x0f,0xb0,0x0b,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd5b0, 0, {0xc8,0x05,0x01,0x00,0x87,0xc0,0x2e,0xa8,0x08,0xf1,0x12,0xc5,0x40,0x88,0x00,0x22 }, - 16, 0xd5c0, 0, {0x40,0x0b,0x84,0x02,0x27,0x00,0xaf,0x00,0x2e,0xc0,0x08,0xbc,0x12,0x3c,0x00,0x8b }, - 16, 0xd5d0, 0, {0x01,0x23,0xc0,0x28,0xf5,0x4a,0x3d,0x28,0xdf,0x00,0x33,0xc0,0x4b,0xf0,0x03,0x32 }, - 16, 0xd5e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x48,0x80,0xa3,0x90,0x2c,0x00 }, - 16, 0xd5f0, 0, {0x08,0x30,0x02,0xc1,0x00,0x92,0x04,0x28,0x00,0x0b,0x14,0x12,0x43,0x00,0xb3,0x04 }, - 16, 0xd600, 0, {0x2c,0x30,0x0a,0xb0,0x0a,0x8c,0x00,0x93,0x00,0x60,0xc0,0x08,0x3c,0x06,0x0e,0x01 }, - 16, 0xd610, 0, {0xb3,0x00,0x2e,0xc0,0x8b,0x30,0x06,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd620, 0, {0x20,0x01,0x12,0x00,0x87,0x80,0x2d,0x24,0x08,0x78,0x02,0xd2,0x00,0x95,0x80,0x21 }, - 16, 0xd630, 0, {0xa0,0x0b,0x68,0x02,0x5a,0x20,0x87,0x80,0x2d,0x66,0x1a,0x7c,0x02,0x9e,0x00,0x87 }, - 16, 0xd640, 0, {0x80,0x21,0xe1,0x18,0x79,0x02,0x9e,0x40,0xb7,0x80,0xa1,0xe0,0x0b,0x78,0x02,0x48 }, - 16, 0xd650, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x00,0x00,0xe3,0xa0,0x3c,0x40 }, - 16, 0xd660, 0, {0x0c,0x30,0x03,0xc4,0x22,0xd9,0x00,0x38,0xd4,0x0f,0x30,0x83,0x68,0x40,0xf3,0x00 }, - 16, 0xd670, 0, {0x3c,0x80,0x0a,0x32,0x02,0x8c,0x00,0xdb,0x00,0xa2,0xc4,0x0c,0x30,0x03,0x0c,0x00 }, - 16, 0xd680, 0, {0xf3,0x00,0x3c,0xc0,0x0f,0xb1,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd690, 0, {0x40,0x0d,0xb0,0x00,0xff,0x10,0x3f,0x40,0x0e,0xf0,0x03,0xfc,0x00,0xed,0x00,0x3f }, - 16, 0xd6a0, 0, {0xc0,0x0f,0x30,0x13,0xbc,0x40,0x7f,0x10,0x3f,0xc1,0x2d,0xf0,0x03,0x7c,0x00,0xfb }, - 16, 0xd6b0, 0, {0x40,0x3f,0xc2,0x0e,0xf4,0x83,0x7c,0x00,0xdf,0x00,0x3f,0xc2,0x0f,0xf0,0x03,0x90 }, - 16, 0xd6c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xdb,0xa0,0x32,0xc0 }, - 16, 0xd6d0, 0, {0x0d,0xb7,0x03,0xe0,0x00,0xca,0x04,0x3e,0x80,0x0f,0xb8,0x03,0x2c,0x10,0xfb,0x00 }, - 16, 0xd6e0, 0, {0x33,0x00,0x8d,0xb0,0x03,0x2c,0x80,0xe9,0x40,0x3e,0xd2,0x0f,0xb4,0x03,0x2d,0x80 }, - 16, 0xd6f0, 0, {0xeb,0x20,0xb2,0xc0,0x0f,0xb2,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd700, 0, {0x48,0x11,0x90,0x00,0xb7,0x10,0x11,0xc0,0x08,0x70,0x82,0xd8,0x0a,0x87,0x01,0x2d }, - 16, 0xd710, 0, {0x80,0x89,0x70,0x03,0xd8,0x08,0xb7,0x0a,0x21,0x40,0x2c,0x70,0x02,0x0d,0xc0,0x85 }, - 16, 0xd720, 0, {0x01,0x79,0xc8,0x0b,0x32,0x02,0x0d,0x20,0x8f,0x28,0x21,0xc0,0x0b,0x72,0x82,0xd2 }, - 16, 0xd730, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x40,0x96,0x10,0x97,0x90,0x23,0xe0 }, - 16, 0xd740, 0, {0x09,0x7a,0x02,0xd6,0x00,0x97,0x80,0x2d,0xf0,0x0b,0x78,0x82,0x1e,0x00,0xb3,0xb0 }, - 16, 0xd750, 0, {0x21,0xa0,0x08,0x78,0x02,0x1e,0x00,0xa5,0x80,0x2d,0xe0,0x0b,0x7a,0x02,0x1e,0x80 }, - 16, 0xd760, 0, {0xa7,0xb0,0x21,0xe8,0x0b,0x79,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd770, 0, {0x48,0x14,0xc0,0x00,0xb3,0x00,0x20,0xe2,0x08,0x30,0x02,0xc6,0x40,0x93,0x70,0x2c }, - 16, 0xd780, 0, {0xc0,0x09,0x3c,0x02,0x8e,0x00,0xb3,0x00,0x20,0xd8,0x08,0x18,0x02,0x0c,0x00,0x81 }, - 16, 0xd790, 0, {0x90,0x2e,0xc0,0x0b,0x30,0x2a,0x2c,0x10,0x83,0x00,0xa0,0xc0,0x0b,0x30,0x02,0xd2 }, - 16, 0xd7a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x11,0xb9,0x00,0xda,0x02,0x33,0xb8 }, - 16, 0xd7b0, 0, {0x0d,0xa0,0x03,0xf8,0x00,0xde,0xc0,0x3f,0xb0,0x4f,0xec,0x06,0x38,0x40,0xfa,0x00 }, - 16, 0xd7c0, 0, {0xb3,0x90,0x0c,0x6c,0x0b,0x28,0x08,0xea,0x01,0x7e,0x80,0x0f,0xa0,0x03,0x28,0x00 }, - 16, 0xd7d0, 0, {0xea,0x00,0x32,0x80,0x0f,0xa0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd7e0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x40,0x3a,0x00,0x0f,0x84,0x03,0xe1,0x00,0xe8,0x02,0x3e }, - 16, 0xd7f0, 0, {0x00,0x0f,0x84,0x03,0xe1,0x40,0xf8,0x00,0x3e,0x00,0x0f,0x81,0x03,0xe0,0x00,0xf8 }, - 16, 0xd800, 0, {0x00,0x3a,0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xd810, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x20,0xf9,0xc0,0x3e,0x70 }, - 16, 0xd820, 0, {0x0e,0x90,0x02,0xe4,0x80,0xc9,0x00,0x32,0x42,0x0c,0x98,0x83,0xa4,0x84,0xf9,0x00 }, - 16, 0xd830, 0, {0xb2,0x60,0x0c,0x90,0x83,0x24,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x1a,0x02,0x24,0x00 }, - 16, 0xd840, 0, {0xc1,0x00,0xb2,0x40,0x0f,0x90,0x01,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd850, 0, {0x80,0x04,0x65,0x00,0xb9,0x81,0x2c,0x60,0x0d,0x94,0xc2,0xc7,0x08,0x89,0x00,0x22 }, - 16, 0xd860, 0, {0x40,0x08,0x95,0xc7,0xa4,0x00,0xb9,0x00,0x28,0x70,0xa8,0x94,0x0a,0x24,0x00,0x89 }, - 16, 0xd870, 0, {0x04,0x2e,0x40,0x28,0x90,0x2a,0x26,0x00,0x89,0x00,0x22,0x40,0x0b,0x90,0x02,0xe0 }, - 16, 0xd880, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x40,0x2e,0x40 }, - 16, 0xd890, 0, {0x0a,0x90,0x02,0xe5,0x00,0x81,0x00,0xa0,0x40,0x09,0x90,0x42,0xec,0x00,0xb1,0x00 }, - 16, 0xd8a0, 0, {0x22,0x58,0x08,0x90,0xa2,0x04,0x02,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0xa4,0xa0 }, - 16, 0xd8b0, 0, {0x89,0x00,0x22,0x40,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd8c0, 0, {0x08,0x04,0x04,0x00,0xb1,0x20,0x2e,0xc0,0x89,0x12,0x02,0xc4,0x80,0x81,0x20,0x20 }, - 16, 0xd8d0, 0, {0x40,0x61,0x10,0x42,0xc5,0x00,0xb1,0x20,0x28,0x48,0x18,0x90,0x42,0x04,0x80,0x81 }, - 16, 0xd8e0, 0, {0x28,0x2c,0x48,0x08,0x12,0x82,0x84,0xa0,0x81,0x20,0x20,0x48,0x0b,0x12,0x82,0xc2 }, - 16, 0xd8f0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x68,0x00,0xf8,0x00,0x2e,0x00 }, - 16, 0xd900, 0, {0x0e,0x80,0x03,0xe0,0x08,0xc8,0x50,0x32,0x14,0x0d,0x80,0x17,0xe8,0x04,0xf8,0x50 }, - 16, 0xd910, 0, {0x32,0x14,0x4c,0x05,0x0b,0x21,0x40,0xc8,0x20,0x3e,0x00,0x0c,0x87,0x03,0xa1,0xc2 }, - 16, 0xd920, 0, {0xc8,0x00,0x32,0x14,0x8f,0x82,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd930, 0, {0x98,0x1d,0xf4,0x00,0xf1,0x10,0x3d,0x40,0x0f,0x91,0x02,0xd4,0x42,0xfd,0x10,0x3f }, - 16, 0xd940, 0, {0x51,0x0e,0x54,0x13,0xb5,0x00,0xf9,0x10,0x35,0x44,0x2f,0xd0,0x03,0xe4,0x50,0xfd }, - 16, 0xd950, 0, {0x28,0x3e,0x4e,0x0f,0x90,0x03,0x64,0x00,0xf9,0x38,0x3e,0x44,0x0f,0x92,0x83,0xe6 }, - 16, 0xd960, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf4,0x00,0xfd,0x00,0x3d,0x40 }, - 16, 0xd970, 0, {0x2c,0xd0,0x03,0xb6,0x00,0xf9,0x82,0x3e,0x40,0x0c,0xd0,0x03,0xf4,0x00,0xf9,0x80 }, - 16, 0xd980, 0, {0x33,0x70,0x0c,0x50,0x03,0x34,0x00,0xc9,0xc0,0x3e,0x40,0x0c,0xda,0x03,0x16,0x80 }, - 16, 0xd990, 0, {0xc9,0x40,0x3e,0x62,0x2c,0x98,0x83,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd9a0, 0, {0x38,0x10,0xe0,0x00,0xb8,0x00,0x2e,0x00,0x08,0x80,0x02,0x28,0x00,0xb8,0x50,0x26 }, - 16, 0xd9b0, 0, {0x00,0x08,0xa0,0x02,0xe8,0x00,0xb8,0x00,0x2a,0x34,0x2a,0xaa,0x0a,0x20,0x00,0x88 }, - 16, 0xd9c0, 0, {0xc0,0x2e,0x2a,0x08,0x80,0x22,0x21,0x00,0xa8,0x80,0x2e,0x00,0x08,0x80,0x02,0x0e }, - 16, 0xd9d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2e,0x40 }, - 16, 0xd9e0, 0, {0x48,0x10,0x06,0x8d,0x00,0xb1,0x00,0x2c,0x40,0x28,0x10,0x02,0xc4,0x00,0xb1,0x40 }, - 16, 0xd9f0, 0, {0x2c,0x48,0x08,0x10,0x82,0x44,0x00,0x81,0x60,0x2c,0x40,0x28,0x14,0x0a,0x04,0x40 }, - 16, 0xda00, 0, {0x81,0x20,0x2c,0x40,0x08,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xda10, 0, {0x18,0x05,0xa4,0x40,0xb9,0x00,0x2e,0x40,0x08,0xb0,0x02,0x24,0x00,0xb9,0x28,0x2e }, - 16, 0xda20, 0, {0x50,0x08,0x90,0x22,0xe4,0x00,0xb9,0x00,0x2e,0x60,0x0b,0x12,0x42,0x64,0x00,0x89 }, - 16, 0xda30, 0, {0x00,0x2c,0x40,0x09,0x90,0x02,0x24,0x00,0xa9,0x00,0x2c,0x40,0x08,0x10,0x02,0x46 }, - 16, 0xda40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe6,0x00,0xf9,0x00,0x3c,0x42 }, - 16, 0xda50, 0, {0x0c,0x90,0x03,0xa7,0x40,0xf9,0x40,0x3e,0x70,0x0c,0x98,0x02,0xe5,0x40,0xf9,0x00 }, - 16, 0xda60, 0, {0x3e,0x40,0x0c,0x98,0x03,0x64,0x06,0xc9,0x01,0x2e,0x40,0x0c,0x90,0x03,0x24,0x04 }, - 16, 0xda70, 0, {0xc9,0x00,0x3e,0x40,0x0c,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xda80, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x83,0xe6,0x10,0xf9,0x00,0x36 }, - 16, 0xda90, 0, {0x68,0x0f,0x9c,0x03,0xe6,0x00,0xf9,0x00,0x3a,0x40,0x0e,0x98,0x93,0xa4,0x00,0xf9 }, - 16, 0xdaa0, 0, {0x00,0x3e,0x40,0x0e,0x90,0x83,0xc4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0x8a }, - 16, 0xdab0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf8,0x00,0x3e,0x04 }, - 16, 0xdac0, 0, {0x0c,0x80,0x03,0x21,0x02,0xc8,0x40,0x32,0x00,0x0f,0x80,0x03,0xe1,0x00,0xf0,0x00 }, - 16, 0xdad0, 0, {0x3e,0x02,0x0c,0x80,0x03,0x20,0x00,0xf8,0x00,0x3e,0x00,0x0c,0x00,0x03,0x20,0x00 }, - 16, 0xdae0, 0, {0xc8,0x00,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdaf0, 0, {0x28,0x15,0x3a,0x00,0xbe,0x02,0x2f,0xb0,0x08,0x68,0x12,0x38,0x00,0x8a,0x04,0x2a }, - 16, 0xdb00, 0, {0x80,0x0b,0xe0,0x42,0xfb,0x20,0xba,0x00,0x2f,0x91,0x08,0xe0,0x02,0x28,0x00,0xba }, - 16, 0xdb10, 0, {0x00,0x26,0x80,0x08,0xee,0x0a,0x38,0x00,0x8a,0x00,0x22,0x80,0x0b,0xa0,0x02,0x8a }, - 16, 0xdb20, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x42,0x00,0xb3,0x00,0x2c,0xc2 }, - 16, 0xdb30, 0, {0x28,0x38,0x0a,0x48,0x00,0x83,0x04,0x22,0xc0,0x0b,0x10,0x02,0xcd,0x80,0xb3,0x00 }, - 16, 0xdb40, 0, {0x2e,0xc0,0x08,0x1c,0x02,0x24,0x00,0xb3,0x00,0x2c,0xc0,0x08,0x34,0x12,0x0e,0x40 }, - 16, 0xdb50, 0, {0x83,0x00,0x20,0xc0,0x0b,0x30,0x12,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdb60, 0, {0xa0,0x01,0x11,0x00,0xb7,0x00,0x2f,0xc0,0x08,0x70,0xa2,0x4e,0x00,0x8f,0xb0,0x21 }, - 16, 0xdb70, 0, {0xcc,0x0b,0x60,0x12,0xdc,0x10,0xb7,0x30,0x2d,0xc0,0x08,0xd0,0x82,0x14,0x80,0xb7 }, - 16, 0xdb80, 0, {0x12,0x25,0xc8,0x28,0x60,0x02,0x14,0x00,0x87,0xb2,0x21,0xcc,0x0b,0x31,0x02,0xa8 }, - 16, 0xdb90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xf7,0x80,0x3d,0xe0 }, - 16, 0xdba0, 0, {0x0c,0x38,0x03,0x56,0x00,0xc7,0x90,0xb1,0xe4,0x0f,0x78,0x03,0xde,0x00,0xf7,0x90 }, - 16, 0xdbb0, 0, {0x1f,0x60,0x2c,0x48,0x0b,0x16,0xa0,0xf7,0x80,0x3c,0xf4,0x0c,0x38,0x03,0x1e,0x00 }, - 16, 0xdbc0, 0, {0xcf,0xa0,0xb1,0xe8,0x0f,0x7b,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdbd0, 0, {0x08,0x0d,0xa0,0x00,0xf8,0x00,0x3e,0xc0,0x0b,0xb0,0x03,0xac,0x00,0xf3,0x21,0x3e }, - 16, 0xdbe0, 0, {0xc8,0x07,0xb0,0x02,0xe4,0x00,0xfb,0x20,0x3f,0x40,0x0f,0x80,0x03,0xe4,0x80,0xfb }, - 16, 0xdbf0, 0, {0x00,0x36,0xd0,0x0f,0xa0,0x03,0xe0,0x08,0xfb,0x42,0x3e,0xd8,0x0f,0xb0,0x03,0xc2 }, - 16, 0xdc00, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf0,0x80,0xcf,0x80,0x31,0xe1 }, - 16, 0xdc10, 0, {0x0c,0xf8,0x03,0xda,0x10,0xef,0x80,0x3f,0xe4,0x0f,0xd8,0x03,0xfe,0x10,0xff,0x82 }, - 16, 0xdc20, 0, {0x3f,0xe0,0x4c,0xd8,0x1b,0x16,0x20,0xcf,0x80,0x3f,0xe0,0x4c,0xd8,0x30,0xee,0x40 }, - 16, 0xdc30, 0, {0xff,0xc0,0xb3,0xf4,0x0f,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdc40, 0, {0xa8,0x01,0x98,0x20,0x83,0x40,0x21,0xc0,0x08,0x71,0x02,0xdc,0x84,0x87,0x20,0x2d }, - 16, 0xdc50, 0, {0xc0,0x0b,0x60,0x02,0xd9,0x60,0xf7,0x00,0x2d,0xc0,0x08,0xf0,0x82,0x14,0x04,0x87 }, - 16, 0xdc60, 0, {0x00,0x2d,0xc0,0x08,0xf0,0x03,0x1e,0x00,0xb7,0x20,0x21,0xc0,0x8b,0x70,0x02,0xea }, - 16, 0xdc70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x00,0x87,0x00,0x21,0x80 }, - 16, 0xdc80, 0, {0x08,0x70,0x02,0xf5,0x04,0x27,0x00,0x2d,0xc0,0x8b,0x70,0x02,0xdc,0x00,0xb7,0x00 }, - 16, 0xdc90, 0, {0x2c,0x50,0x08,0x40,0x02,0x14,0x00,0x87,0x00,0x2d,0xc0,0x08,0x50,0x02,0x5c,0x04 }, - 16, 0xdca0, 0, {0xb7,0x00,0xa1,0xc0,0x8b,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdcb0, 0, {0x20,0x14,0xc8,0x00,0x80,0x00,0x00,0x80,0x08,0x30,0x02,0xce,0x00,0x83,0xc0,0x2c }, - 16, 0xdcc0, 0, {0xd0,0x4b,0x30,0x02,0xce,0x00,0xab,0x02,0x2c,0x40,0x48,0xbc,0x02,0x04,0x00,0x83 }, - 16, 0xdcd0, 0, {0x00,0x2c,0xc0,0x08,0x10,0x02,0x00,0x08,0xb3,0x00,0x20,0xc0,0x09,0x30,0x02,0xc8 }, - 16, 0xdce0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x83,0x40,0xc8,0x00,0x30,0xc0 }, - 16, 0xdcf0, 0, {0x2c,0xb0,0x03,0xec,0x00,0xef,0x88,0x3f,0xe6,0x07,0xb1,0x83,0xe1,0x00,0xbf,0x00 }, - 16, 0xdd00, 0, {0x3e,0xe0,0x0c,0xb8,0x03,0x34,0x00,0xcf,0x00,0x3f,0xc0,0x2c,0xb0,0x03,0x68,0x10 }, - 16, 0xdd10, 0, {0xff,0x00,0x33,0xc0,0x0f,0xf0,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdd20, 0, {0x80,0x00,0xe4,0x00,0xf1,0x40,0x3e,0xc0,0x0f,0xb4,0x03,0xed,0x40,0xfb,0x08,0x3e }, - 16, 0xdd30, 0, {0xc0,0x0f,0xa0,0x03,0xe5,0x20,0xfb,0x00,0x3e,0xe0,0x0d,0xb0,0x83,0xe4,0x00,0xf3 }, - 16, 0xdd40, 0, {0x00,0x3e,0xc0,0x0f,0x80,0x03,0xc4,0x00,0xfb,0x00,0x3e,0xc0,0x0f,0x30,0x03,0xe0 }, - 16, 0xdd50, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xca,0x00,0x33,0xe0 }, - 16, 0xdd60, 0, {0x4e,0xf0,0x03,0x34,0x00,0xff,0x00,0x3f,0xc0,0x8f,0xe8,0x03,0xf0,0x00,0xff,0x00 }, - 16, 0xdd70, 0, {0xb1,0x40,0x0c,0xe0,0x03,0x34,0x00,0xef,0x00,0xb3,0xc0,0x0c,0xf0,0x03,0x38,0x00 }, - 16, 0xdd80, 0, {0xcf,0x00,0x3d,0xc0,0x0a,0xf0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdd90, 0, {0x81,0x04,0x62,0x22,0x88,0x90,0x22,0xe0,0x08,0x3c,0x02,0x2e,0x08,0xbb,0x01,0x2e }, - 16, 0xdda0, 0, {0xc0,0x0b,0xa0,0x02,0x66,0x00,0xbb,0x00,0x22,0xa0,0x08,0xa9,0x02,0x24,0x00,0xbb }, - 16, 0xddb0, 0, {0x00,0x22,0xc0,0x28,0x2c,0x02,0xa2,0x00,0xdb,0x00,0x2e,0xc0,0x0a,0xb0,0x02,0xa0 }, - 16, 0xddc0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x22,0x00,0x98,0x00,0x22,0xc8 }, - 16, 0xddd0, 0, {0x0a,0x98,0x02,0x27,0x04,0xbb,0x00,0x2e,0xc0,0x0b,0xb1,0x02,0xe2,0x00,0xbb,0x00 }, - 16, 0xdde0, 0, {0x22,0xe2,0x08,0xb0,0x02,0xa4,0x00,0xab,0x00,0x20,0xc0,0x0a,0x88,0x82,0x23,0x00 }, - 16, 0xddf0, 0, {0x8b,0x00,0x2e,0xc0,0x08,0xb0,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xde00, 0, {0x08,0x14,0x04,0x00,0x91,0x40,0x22,0xc0,0x08,0x10,0x02,0x0c,0x00,0xb3,0x00,0x2c }, - 16, 0xde10, 0, {0xc0,0x4b,0x28,0x22,0x40,0x04,0xb3,0x00,0x20,0xc0,0x28,0x30,0x0a,0x04,0x04,0xb3 }, - 16, 0xde20, 0, {0x00,0x60,0xc0,0x08,0x00,0x02,0x84,0x20,0x93,0x00,0x2c,0xc0,0x0a,0x30,0x02,0x82 }, - 16, 0xde30, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x60,0x00,0xda,0x40,0xb2,0x80 }, - 16, 0xde40, 0, {0x0e,0x90,0x03,0x24,0x00,0xff,0x00,0x3f,0xc0,0x8f,0xa0,0x03,0xe0,0x09,0xff,0x00 }, - 16, 0xde50, 0, {0x32,0x40,0x08,0xa0,0x0b,0x34,0x00,0xeb,0x00,0x31,0xc0,0x0c,0x80,0x03,0x28,0x80 }, - 16, 0xde60, 0, {0xc7,0x00,0x3f,0xc0,0x0c,0xf0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xde70, 0, {0xa0,0x15,0xd0,0x00,0xec,0x20,0x3f,0x00,0x0f,0xc0,0x0b,0xfc,0x10,0xff,0x01,0x3f }, - 16, 0xde80, 0, {0xc0,0x0f,0xe0,0x03,0xf4,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xf4,0x00,0xff }, - 16, 0xde90, 0, {0x00,0x3f,0xc0,0x4f,0xc0,0x01,0xf0,0x08,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8 }, - 16, 0xdea0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xcc,0x90,0x37,0x20 }, - 16, 0xdeb0, 0, {0x0e,0xf0,0x13,0xbd,0x04,0xd4,0xc1,0x33,0x2c,0x4c,0xd9,0x23,0x32,0x60,0xff,0x20 }, - 16, 0xdec0, 0, {0x3d,0xe0,0x4f,0xc1,0x03,0xb6,0x40,0xcd,0x00,0x37,0xe0,0x0c,0xe2,0x8b,0x10,0xc0 }, - 16, 0xded0, 0, {0xcd,0x00,0x33,0xc6,0x0f,0xd8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdee0, 0, {0x80,0x10,0xee,0x08,0x8a,0x20,0x22,0x00,0x08,0xb7,0x02,0x2d,0x00,0x8a,0x00,0xb6 }, - 16, 0xdef0, 0, {0x3c,0x08,0x99,0x02,0x27,0x84,0xbf,0x68,0x2e,0x82,0x0b,0x01,0x02,0x24,0x40,0xd9 }, - 16, 0xdf00, 0, {0x42,0x20,0xc0,0x8a,0xac,0x02,0x2d,0xc2,0x82,0x48,0xa2,0xd0,0x0b,0x82,0x02,0x20 }, - 16, 0xdf10, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x88,0x04,0x26,0x80 }, - 16, 0xdf20, 0, {0x2a,0x30,0xc2,0xa5,0x80,0xa9,0x21,0x28,0x00,0x8a,0x00,0x02,0x00,0x00,0xa3,0x10 }, - 16, 0xdf30, 0, {0x2c,0xc8,0x0b,0x00,0x02,0xc4,0x90,0x83,0x42,0x24,0xc1,0x08,0x00,0x02,0x40,0x88 }, - 16, 0xdf40, 0, {0xa3,0x60,0xa8,0xc0,0x0b,0x00,0xc2,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdf50, 0, {0xc0,0x15,0xac,0x06,0x8a,0x00,0x22,0xe0,0x48,0xb0,0x02,0x2e,0x02,0xab,0x80,0x2e }, - 16, 0xdf60, 0, {0x20,0x4a,0x8c,0x02,0x26,0x20,0xbb,0x00,0x6e,0x80,0x0b,0x30,0xc2,0x46,0x04,0x9b }, - 16, 0xdf70, 0, {0x0a,0xa2,0xc0,0x0a,0x80,0x12,0x6c,0x40,0xa8,0x00,0x2a,0xc0,0x0b,0x8c,0x02,0x30 }, - 16, 0xdf80, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xc1,0x09,0x36,0x61 }, - 16, 0xdf90, 0, {0x0e,0x32,0x03,0xab,0x20,0xf8,0x84,0x3a,0x78,0x2e,0x98,0x03,0x26,0x00,0xeb,0x00 }, - 16, 0xdfa0, 0, {0x3e,0x40,0x4f,0x90,0x03,0xe2,0x00,0xc9,0x40,0x36,0xe0,0x0c,0xb4,0x03,0x6e,0x00 }, - 16, 0xdfb0, 0, {0xeb,0x00,0x3a,0xc0,0x0f,0x88,0x03,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdfc0, 0, {0xe0,0x01,0xbc,0x00,0xfd,0x00,0x3f,0x40,0x0f,0xfa,0x13,0xf8,0x10,0xdc,0x04,0x27 }, - 16, 0xdfd0, 0, {0x40,0x0d,0x50,0x43,0xf4,0x00,0xff,0x00,0x3f,0x40,0x0f,0xd9,0x03,0xb0,0x00,0xf9 }, - 16, 0xdfe0, 0, {0x01,0x3f,0xf0,0x0f,0xf0,0x23,0xb2,0x00,0xd4,0xa0,0x37,0xc0,0x0f,0xc0,0x0b,0xf8 }, - 16, 0xdff0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x20,0xeb,0x10,0xf2,0x00 }, - 16, 0xe000, 0, {0x0e,0xb4,0x03,0x21,0x80,0xc9,0x40,0x3a,0x48,0x0f,0x90,0x13,0xe1,0x20,0xfb,0x00 }, - 16, 0xe010, 0, {0x3e,0xc0,0x0c,0x84,0x03,0x24,0x00,0xfb,0x01,0x36,0xe0,0x0c,0x74,0x0b,0x9c,0x00 }, - 16, 0xe020, 0, {0xcf,0x00,0x32,0xe0,0x0f,0x84,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe030, 0, {0xc8,0x05,0x1e,0x00,0x8b,0x80,0x20,0x40,0x08,0xb8,0x02,0x83,0x80,0x81,0xa0,0x22 }, - 16, 0xe040, 0, {0x78,0x0b,0x91,0x83,0xe3,0x00,0xbf,0x00,0x0e,0xc1,0x0a,0xb4,0x03,0x64,0x04,0xb9 }, - 16, 0xe050, 0, {0x50,0x32,0xc0,0x0a,0xb2,0x02,0x20,0x00,0x88,0x00,0x23,0xd4,0x0b,0x88,0x02,0xf2 }, - 16, 0xe060, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x42,0xa0,0x80,0x20,0x00 }, - 16, 0xe070, 0, {0x48,0x00,0x02,0x0d,0x06,0x80,0x80,0x2a,0xd0,0x03,0x00,0x02,0xc8,0x00,0xb3,0x00 }, - 16, 0xe080, 0, {0x2c,0xc0,0x08,0x36,0x02,0x40,0x00,0xb9,0x02,0x22,0xc2,0x8b,0x26,0x02,0x0c,0x10 }, - 16, 0xe090, 0, {0x01,0x02,0x24,0xc0,0x4b,0xa1,0x02,0xf8,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0a0, 0, {0x20,0x01,0x1e,0x08,0x8e,0x80,0x21,0x21,0x08,0x28,0xc2,0x9e,0x00,0x8e,0x80,0x21 }, - 16, 0xe0b0, 0, {0x60,0x0b,0x78,0x02,0x9e,0x20,0xb7,0x82,0x2f,0xa1,0x0a,0x78,0x02,0x5e,0x00,0xb5 }, - 16, 0xe0c0, 0, {0x91,0xa1,0xe0,0x0b,0x29,0x02,0x32,0x44,0x86,0x80,0xa5,0xe0,0x0b,0x4c,0x02,0xc8 }, - 16, 0xe0d0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xe1,0x00,0x22,0x80 }, - 16, 0xe0e0, 0, {0x0e,0x00,0x0b,0x24,0x00,0xc0,0x44,0x28,0xad,0x0f,0x20,0x02,0xc8,0x00,0xf3,0x00 }, - 16, 0xe0f0, 0, {0x1c,0xc0,0x0c,0x01,0x03,0x48,0x4c,0xf2,0x04,0x30,0xc0,0x0f,0x15,0x03,0x80,0x40 }, - 16, 0xe100, 0, {0xc1,0x00,0x14,0xc8,0x0f,0x00,0x03,0xda,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe110, 0, {0x40,0x1d,0x9c,0x40,0xf7,0x00,0x3f,0xc0,0x8f,0xc0,0x03,0xe4,0x00,0xfa,0x01,0x3f }, - 16, 0xe120, 0, {0xc0,0x0f,0xf0,0x23,0xfc,0x08,0xfb,0x00,0x3f,0x80,0x0f,0xf0,0x01,0xfc,0x10,0xff }, - 16, 0xe130, 0, {0x00,0x3f,0xc0,0x0e,0xd1,0x03,0xfc,0x42,0xfe,0x80,0x3b,0xc0,0x0f,0xc0,0x03,0xd0 }, - 16, 0xe140, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x40,0xc8,0x00,0x3e,0xc0 }, - 16, 0xe150, 0, {0x0f,0x90,0x03,0xee,0x08,0xcb,0x00,0x32,0xc0,0x0f,0xa0,0x23,0xe6,0x03,0xcb,0x4c }, - 16, 0xe160, 0, {0x32,0x40,0x0f,0xb0,0x07,0xe8,0x00,0xf9,0x00,0x16,0x40,0x0c,0xa0,0x0b,0x6c,0x00 }, - 16, 0xe170, 0, {0xcf,0x02,0x32,0xc5,0x0c,0x80,0x03,0x02,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe180, 0, {0x48,0x11,0x9c,0x80,0x84,0x04,0x2d,0xc1,0x0b,0x40,0x40,0xdc,0x00,0x87,0x04,0x21 }, - 16, 0xe190, 0, {0xc0,0x4b,0x70,0x12,0xfc,0x01,0x8f,0x60,0x29,0x40,0x0b,0x70,0x13,0x9c,0x00,0xb5 }, - 16, 0xe1a0, 0, {0x00,0xa3,0x40,0x0a,0x60,0x02,0x00,0x00,0x84,0x00,0x21,0xc0,0x08,0x40,0x02,0x12 }, - 16, 0xe1b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x87,0x80,0x2d,0xa2 }, - 16, 0xe1c0, 0, {0x0b,0x4c,0x16,0xd6,0x08,0x97,0x88,0x21,0xa0,0x4b,0x68,0x02,0xde,0x04,0xa7,0x80 }, - 16, 0xe1d0, 0, {0x21,0xe0,0x0b,0x48,0x02,0xda,0x04,0xb6,0x82,0x25,0x60,0x0a,0xe8,0x62,0x1e,0x00 }, - 16, 0xe1e0, 0, {0x87,0x80,0x20,0xe8,0x08,0x48,0x02,0x08,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1f0, 0, {0x48,0x14,0xcc,0x00,0x8b,0x80,0x6c,0xf0,0x0b,0x3c,0x02,0xce,0x46,0x9b,0xc0,0x20 }, - 16, 0xe200, 0, {0xe4,0x0b,0x3c,0x02,0xcc,0x20,0xa3,0x00,0x28,0xe0,0x0b,0x30,0x02,0x8d,0x80,0xb1 }, - 16, 0xe210, 0, {0x80,0x22,0x44,0x0a,0x21,0x0a,0x03,0x82,0x80,0x80,0xa0,0xc0,0x08,0x06,0x0a,0x12 }, - 16, 0xe220, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x02,0xce,0x80,0x3f,0xa0 }, - 16, 0xe230, 0, {0x0f,0xe0,0x03,0xfa,0x40,0xde,0xc0,0xb3,0x90,0x0f,0xea,0x13,0xf9,0x08,0xea,0x04 }, - 16, 0xe240, 0, {0x33,0x82,0x8f,0xe4,0x03,0xfb,0x08,0xfe,0xa0,0x36,0xa0,0x0c,0xac,0x0b,0x6b,0x82 }, - 16, 0xe250, 0, {0xc6,0xa0,0x32,0x80,0x2c,0xe4,0x03,0x3a,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe260, 0, {0x48,0x00,0xe0,0x00,0xf8,0x90,0x3e,0x02,0x0f,0x80,0x83,0xe1,0x00,0xe8,0x20,0x3e }, - 16, 0xe270, 0, {0x03,0x0f,0x82,0x03,0xe1,0x40,0xd8,0x00,0x3e,0x20,0x0f,0x00,0x93,0xa0,0x40,0xf8 }, - 16, 0xe280, 0, {0x00,0x3e,0x10,0x8f,0x08,0x0b,0xf0,0x00,0xfc,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xe290, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xe9,0x00,0x36,0x40 }, - 16, 0xe2a0, 0, {0x0f,0x94,0x07,0xe6,0x00,0xf9,0x80,0xb0,0x40,0x0c,0x94,0x03,0xe4,0x40,0xf9,0x00 }, - 16, 0xe2b0, 0, {0x32,0x40,0x0f,0x94,0x0b,0xa4,0x00,0x71,0xc0,0x32,0x40,0x2c,0x94,0x23,0x24,0x02 }, - 16, 0xe2c0, 0, {0xc9,0x00,0x32,0x40,0x0c,0x90,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2d0, 0, {0x80,0x04,0x44,0x00,0x89,0x00,0x22,0x40,0x0b,0x98,0x02,0xe6,0x60,0xb9,0x00,0x22 }, - 16, 0xe2e0, 0, {0x60,0x0a,0x9c,0x02,0xe6,0x24,0xb9,0x04,0x36,0x40,0x0b,0x98,0x00,0x24,0x00,0xb9 }, - 16, 0xe2f0, 0, {0x80,0xa2,0x52,0x08,0x90,0x02,0x24,0x00,0x89,0x40,0x22,0x40,0x68,0x94,0x02,0x20 }, - 16, 0xe300, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xa9,0x00,0x26,0x40 }, - 16, 0xe310, 0, {0x03,0x94,0x02,0xe4,0x01,0xb9,0x10,0x22,0x55,0x08,0x90,0x22,0xe4,0x00,0xb1,0x00 }, - 16, 0xe320, 0, {0x26,0x40,0x0b,0x90,0x00,0x2c,0x09,0xb9,0x00,0x22,0x60,0x08,0x90,0x0a,0x1c,0x04 }, - 16, 0xe330, 0, {0x8d,0x08,0xa0,0x40,0x08,0x10,0x82,0x0e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe340, 0, {0x08,0x04,0x06,0x00,0x81,0x00,0x20,0x50,0x0b,0x12,0x42,0xc4,0x80,0xb1,0x04,0x20 }, - 16, 0xe350, 0, {0x50,0x0a,0x14,0x02,0xc5,0x00,0xb1,0x22,0x24,0x40,0x0b,0x12,0x22,0x04,0x01,0xb1 }, - 16, 0xe360, 0, {0x40,0x20,0x50,0x08,0x10,0x0a,0x15,0x00,0x85,0x40,0x28,0x50,0x08,0x14,0x0a,0x0a }, - 16, 0xe370, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xe8,0x50,0x36,0x00 }, - 16, 0xe380, 0, {0x0f,0x85,0x02,0xe1,0x40,0xf8,0x50,0x32,0x00,0x0c,0xa0,0x23,0xe0,0x10,0xf8,0x50 }, - 16, 0xe390, 0, {0xb2,0x14,0x0f,0xa5,0x03,0xa1,0x48,0xfa,0x00,0xb2,0x00,0x0c,0x80,0x03,0x20,0x04 }, - 16, 0xe3a0, 0, {0xc4,0x02,0x32,0x00,0x0c,0x00,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3b0, 0, {0x98,0x1d,0xe5,0x00,0xfd,0x00,0x3f,0x40,0x0f,0xd1,0x03,0xd4,0x44,0xf5,0x00,0x3f }, - 16, 0xe3c0, 0, {0x51,0x0f,0xd4,0x03,0xf5,0x00,0xf9,0x10,0x3b,0x40,0x0f,0xd1,0x00,0xf5,0x10,0xf5 }, - 16, 0xe3d0, 0, {0x40,0x7f,0x40,0x0f,0x54,0x2b,0xe5,0x00,0xf9,0x40,0x36,0x50,0x0f,0xd0,0x03,0xe6 }, - 16, 0xe3e0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x10,0xbd,0x40,0x33,0x40 }, - 16, 0xe3f0, 0, {0x0f,0xda,0x03,0x37,0x80,0xcd,0x00,0x3f,0x40,0x0f,0xd0,0x03,0xf4,0x00,0xe9,0xa0 }, - 16, 0xe400, 0, {0x3e,0x40,0x0c,0xde,0x17,0xa4,0x08,0xfd,0xc0,0x33,0x41,0x8d,0xda,0x13,0x26,0xa0 }, - 16, 0xe410, 0, {0xf9,0xa8,0x32,0x78,0x0c,0xb4,0x0b,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe420, 0, {0x38,0x10,0xe1,0x00,0xb8,0xa0,0x36,0x20,0x0b,0x8a,0x82,0xa2,0x80,0x2a,0xa8,0x2e }, - 16, 0xe430, 0, {0x00,0x0b,0x80,0x12,0xe0,0x04,0xb8,0xa1,0x2e,0x28,0x4a,0x8e,0x02,0x2a,0xa0,0xba }, - 16, 0xe440, 0, {0xc0,0x22,0x28,0x08,0x85,0x02,0x21,0x08,0xb8,0xe8,0xa2,0x3c,0x08,0xc8,0x02,0x0e }, - 16, 0xe450, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb9,0x00,0x20,0x4a }, - 16, 0xe460, 0, {0x0b,0x14,0x02,0x05,0x80,0x01,0x00,0x2c,0x41,0x0b,0x10,0x02,0xc4,0x04,0xa1,0x4a }, - 16, 0xe470, 0, {0x2e,0x42,0x08,0x14,0x02,0x84,0x10,0xb1,0x60,0xa0,0x4a,0x09,0x10,0x02,0x44,0x00 }, - 16, 0xe480, 0, {0xb5,0x01,0x29,0x40,0x18,0xd2,0x02,0x12,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe490, 0, {0x18,0x15,0xa4,0x00,0xb9,0x21,0x26,0x40,0x0b,0x96,0x02,0xa4,0x10,0xa9,0x00,0x2e }, - 16, 0xe4a0, 0, {0x40,0x0b,0x96,0x12,0xe4,0x20,0xb9,0x00,0x2e,0x41,0x0a,0x90,0x42,0x24,0x00,0xb9 }, - 16, 0xe4b0, 0, {0x00,0x22,0x41,0x08,0x98,0x22,0x64,0x00,0xb9,0x20,0x2b,0x41,0x28,0xd4,0x02,0x06 }, - 16, 0xe4c0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe4,0x00,0xf9,0xe0,0x32,0x58 }, - 16, 0xe4d0, 0, {0x0f,0x98,0x03,0x26,0x40,0xc9,0x40,0x3e,0x58,0x0f,0x9c,0x03,0xe4,0x00,0xe9,0x00 }, - 16, 0xe4e0, 0, {0x6e,0x40,0x0c,0x9a,0x02,0xa6,0x00,0xf9,0x44,0x32,0x40,0x0d,0x9a,0x0b,0x64,0x84 }, - 16, 0xe4f0, 0, {0xf9,0x00,0xba,0x40,0x0c,0x18,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe500, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x50,0x0f,0x90,0x03,0xe6,0x00,0xf9,0x04,0x3e }, - 16, 0xe510, 0, {0x48,0x0f,0x90,0x03,0xe4,0x40,0xf9,0x00,0x3e,0x65,0x0f,0x99,0x81,0xe4,0x50,0xf9 }, - 16, 0xe520, 0, {0x20,0x3e,0x40,0x8f,0x90,0x03,0xa4,0x80,0xf9,0x00,0x34,0x40,0x0f,0x92,0x03,0xd2 }, - 16, 0xe530, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x40,0x3e,0x10 }, - 16, 0xe540, 0, {0x0e,0x84,0x03,0x60,0x08,0xc8,0x00,0x3e,0x08,0x0f,0x80,0x83,0xe0,0x28,0xe8,0x04 }, - 16, 0xe550, 0, {0x3e,0x00,0x0c,0x84,0x03,0x21,0x1c,0xf0,0x48,0x32,0x00,0x0b,0x00,0x03,0xe0,0x02 }, - 16, 0xe560, 0, {0xc0,0x00,0x32,0x00,0x0c,0xc0,0x0b,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe570, 0, {0x28,0x05,0x38,0x00,0xb2,0x88,0x2e,0x80,0x08,0xe0,0x03,0x7a,0x80,0x8e,0x00,0x2f }, - 16, 0xe580, 0, {0xa0,0x0b,0xe8,0x02,0xf9,0x10,0xba,0x00,0x2c,0x80,0x28,0xe4,0x02,0x28,0x00,0xbe }, - 16, 0xe590, 0, {0x40,0x23,0xb8,0x08,0xe8,0x02,0xe8,0x04,0xca,0x20,0xa2,0x80,0x08,0xe8,0x02,0x0a }, - 16, 0xe5a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x01,0xb3,0x00,0x2c,0x40 }, - 16, 0xe5b0, 0, {0x08,0xb8,0x42,0x6c,0x02,0x83,0x00,0x2c,0xe0,0x0b,0x38,0x00,0xcf,0x40,0xb3,0x00 }, - 16, 0xe5c0, 0, {0x2c,0xc0,0x08,0xb4,0x0a,0x0c,0x00,0xb3,0x40,0xa2,0x82,0x0a,0x39,0x02,0xcc,0x00 }, - 16, 0xe5d0, 0, {0x93,0x80,0xa0,0xc0,0x29,0x20,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5e0, 0, {0xa0,0x01,0x1d,0x00,0xb7,0x00,0x2d,0x64,0x28,0x74,0x02,0x40,0x00,0x87,0x05,0x2d }, - 16, 0xe5f0, 0, {0x90,0x0b,0x74,0x02,0xdc,0x10,0xb7,0x30,0x2d,0xc8,0x08,0x34,0x06,0x1c,0x80,0xb7 }, - 16, 0xe600, 0, {0x00,0xa1,0xc0,0x0a,0x70,0x02,0xde,0x80,0x83,0x00,0x01,0x00,0x09,0x60,0x82,0x20 }, - 16, 0xe610, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1a,0x00,0xf7,0x80,0x3d,0x60 }, - 16, 0xe620, 0, {0x0e,0xd8,0x0b,0x5e,0x00,0xc7,0x80,0x3d,0xe0,0x0f,0x68,0x03,0xde,0x10,0xf7,0xa9 }, - 16, 0xe630, 0, {0x7f,0xe8,0x48,0x78,0x03,0x1f,0x30,0xff,0x94,0x33,0xa0,0x0e,0x78,0x03,0xcf,0x24 }, - 16, 0xe640, 0, {0xd6,0x80,0xb1,0xe0,0x0d,0xf8,0x43,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe650, 0, {0x08,0x1d,0xac,0x00,0xbb,0x00,0x0c,0x40,0x0f,0xb0,0x03,0xec,0x08,0xf9,0x00,0x3e }, - 16, 0xe660, 0, {0x00,0x0f,0x90,0x41,0xec,0x00,0xfb,0x61,0x7e,0xd0,0x0f,0xb0,0x03,0xec,0x80,0xfb }, - 16, 0xe670, 0, {0x40,0x3f,0x9b,0x0c,0xb0,0x03,0xed,0x90,0xfa,0x00,0x3c,0x00,0x0e,0xb0,0x03,0xc2 }, - 16, 0xe680, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xde,0x00,0xef,0x80,0x33,0x60 }, - 16, 0xe690, 0, {0x0d,0xd8,0x03,0x36,0x40,0xef,0x90,0x3e,0xe0,0x0f,0xf9,0x03,0xfe,0x00,0xff,0x80 }, - 16, 0xe6a0, 0, {0x33,0xfe,0x0c,0xfa,0x03,0xfe,0x00,0xcf,0x80,0xb3,0xe0,0x0f,0xf8,0x03,0xfe,0x00 }, - 16, 0xe6b0, 0, {0xcd,0x80,0x33,0xe0,0x0f,0xc8,0x43,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6c0, 0, {0xa8,0x11,0x9c,0x00,0x85,0x08,0x35,0x40,0x08,0x70,0x03,0x52,0x20,0x87,0x11,0x2c }, - 16, 0xe6d0, 0, {0xec,0x0b,0x71,0x02,0xd0,0x00,0xe7,0x00,0x35,0xc4,0x08,0x74,0x02,0xdc,0x40,0x87 }, - 16, 0xe6e0, 0, {0x10,0x21,0xc0,0x0b,0x70,0x02,0xfc,0x80,0x85,0x08,0x21,0x00,0x0b,0x41,0x82,0xea }, - 16, 0xe6f0, 0, {0x06,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x00,0xaf,0x00,0x23,0x50 }, - 16, 0xe700, 0, {0x09,0x50,0x02,0x1c,0x80,0xa7,0x01,0x29,0xc0,0x1b,0x60,0x06,0xdc,0x40,0xb7,0x10 }, - 16, 0xe710, 0, {0x21,0xc8,0x4a,0x52,0x02,0xdc,0x00,0x83,0x00,0x21,0xc0,0x0b,0x70,0x02,0xdc,0x13 }, - 16, 0xe720, 0, {0x84,0x00,0x25,0xc0,0x0b,0x58,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe730, 0, {0x20,0x14,0xcc,0x00,0x81,0x80,0x24,0x40,0x08,0x3e,0x02,0x6e,0x00,0x89,0x00,0x2c }, - 16, 0xe740, 0, {0xc0,0x0b,0xb4,0x02,0xca,0x80,0xa3,0x00,0x24,0xc0,0x0a,0x04,0x02,0xec,0x40,0x82 }, - 16, 0xe750, 0, {0x0a,0x20,0xc0,0x0b,0x30,0x02,0xcd,0x10,0x80,0xc0,0xa4,0x00,0x0b,0x1c,0x02,0xc8 }, - 16, 0xe760, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x84,0x00,0xeb,0x80,0x33,0x40 }, - 16, 0xe770, 0, {0x0d,0x8c,0x83,0x26,0x00,0xe9,0xa0,0x3e,0x78,0x8f,0x90,0x83,0xe1,0x00,0xff,0x00 }, - 16, 0xe780, 0, {0x31,0xd1,0x0e,0x84,0x23,0xfc,0x00,0xcb,0x82,0x32,0xc0,0x8f,0xb0,0x02,0xfd,0x40 }, - 16, 0xe790, 0, {0xcb,0x80,0xb6,0xc0,0x0f,0xa4,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7a0, 0, {0x80,0x00,0xec,0x00,0xfb,0x00,0x3e,0x40,0x0f,0xa0,0x03,0xe0,0x00,0xf9,0x01,0x3e }, - 16, 0xe7b0, 0, {0x42,0x0f,0x90,0x03,0xe5,0x54,0xe3,0x00,0x3e,0xc8,0x05,0x93,0x03,0xec,0x80,0xfb }, - 16, 0xe7c0, 0, {0xc1,0x3e,0xc0,0x0f,0x20,0x03,0xcc,0x48,0xf3,0x08,0x3a,0x00,0x0f,0xa0,0x43,0xe0 }, - 16, 0xe7d0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xcf,0x00,0x3f,0x40 }, - 16, 0xe7e0, 0, {0x0f,0x30,0x01,0x2c,0x0a,0xcd,0x10,0x33,0x00,0x0f,0xd0,0x83,0x14,0x00,0xcb,0x02 }, - 16, 0xe7f0, 0, {0x33,0xc0,0x0c,0xe1,0x03,0xec,0x10,0xcd,0x00,0x33,0xc0,0x0c,0xf0,0x33,0x3c,0x00 }, - 16, 0xe800, 0, {0xea,0x00,0x33,0xc0,0x0c,0xf0,0x83,0xc8,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe810, 0, {0x81,0x04,0x6e,0x00,0x8b,0x00,0x2e,0x40,0x0b,0xbc,0x02,0x2e,0x00,0x0b,0x00,0x22 }, - 16, 0xe820, 0, {0x30,0x0b,0x9c,0x02,0x27,0x80,0xab,0x00,0x2a,0xc0,0x08,0xb8,0x02,0xec,0x00,0x89 }, - 16, 0xe830, 0, {0xc0,0x20,0xe0,0x08,0xae,0x02,0x2c,0x08,0x8a,0x00,0x22,0x00,0x08,0xb0,0x42,0xe8 }, - 16, 0xe840, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2e,0x00,0x8b,0x04,0x2e,0x40 }, - 16, 0xe850, 0, {0x8b,0x8c,0x02,0xae,0x10,0x89,0x00,0x22,0x70,0x0b,0x8c,0x02,0xa2,0x00,0x8b,0x01 }, - 16, 0xe860, 0, {0x22,0xc0,0x08,0x80,0x02,0xec,0x10,0x82,0x88,0xa2,0x70,0x09,0xb8,0x02,0x2c,0x08 }, - 16, 0xe870, 0, {0x89,0x00,0x20,0xc0,0x28,0x80,0x22,0xe0,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe880, 0, {0x08,0x04,0x0c,0x04,0x81,0x00,0x2c,0x40,0x0b,0x20,0x02,0x80,0x00,0x81,0x04,0xa0 }, - 16, 0xe890, 0, {0x50,0x4b,0x00,0x0a,0x80,0x00,0xa3,0x01,0x2a,0xc1,0x20,0x10,0x02,0xcc,0x14,0x83 }, - 16, 0xe8a0, 0, {0x00,0x22,0xc0,0x08,0x20,0x02,0x0c,0x00,0x81,0x00,0xe0,0x00,0x08,0x00,0x02,0xc2 }, - 16, 0xe8b0, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x68,0x00,0xcb,0x00,0x3e,0x40 }, - 16, 0xe8c0, 0, {0x0f,0x90,0x0b,0xac,0x80,0xc9,0x00,0x32,0x10,0x0f,0x80,0x03,0xa4,0x00,0xcf,0x02 }, - 16, 0xe8d0, 0, {0x31,0xc0,0x0c,0x80,0x13,0xfc,0x02,0xcd,0x00,0x33,0xc0,0x2c,0x90,0x03,0x3c,0x02 }, - 16, 0xe8e0, 0, {0xe8,0x00,0xb2,0xc0,0x0c,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8f0, 0, {0xa0,0x1d,0xfc,0x02,0xf5,0x00,0x3d,0x40,0x8f,0xf0,0x23,0x6d,0x00,0xff,0x00,0x3f }, - 16, 0xe900, 0, {0x04,0x0f,0xc0,0x03,0x70,0x1c,0xff,0x01,0x3f,0xc0,0x4f,0xc0,0x03,0xfc,0x00,0xfd }, - 16, 0xe910, 0, {0x00,0x3f,0xc0,0x0f,0xe0,0x0f,0xfc,0x18,0xfc,0x00,0x3f,0x00,0x0f,0xd0,0x03,0xe8 }, - 16, 0xe920, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xd7,0x02,0x0f,0x30 }, - 16, 0xe930, 0, {0x0c,0xf2,0x01,0x7e,0x06,0x44,0x30,0x3f,0x20,0x0e,0xf0,0x02,0x7c,0x84,0xfd,0x20 }, - 16, 0xe940, 0, {0x27,0x08,0x0c,0xd0,0x01,0x36,0x00,0xff,0x60,0x33,0xcc,0x0b,0xf1,0x13,0x2c,0xc4 }, - 16, 0xe950, 0, {0xff,0x30,0x0f,0xcd,0x0c,0xf4,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe960, 0, {0x80,0x10,0xee,0x00,0x8f,0xc0,0x2e,0x00,0x08,0xfc,0x02,0x2e,0x00,0x8a,0x30,0x28 }, - 16, 0xe970, 0, {0x52,0x08,0xf6,0x82,0x3c,0x68,0xbd,0x90,0x32,0x34,0x48,0x9c,0x12,0x26,0x00,0xcf }, - 16, 0xe980, 0, {0x40,0x23,0xcc,0x0b,0xf6,0x02,0x3d,0x00,0xbf,0x10,0x2f,0xcc,0x88,0xf6,0x02,0xe0 }, - 16, 0xe990, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x93,0x10,0x2c,0x08 }, - 16, 0xe9a0, 0, {0x09,0x31,0x02,0x4c,0x00,0x9b,0x20,0x64,0x58,0x03,0x31,0x62,0x4c,0x81,0xa1,0x00 }, - 16, 0xe9b0, 0, {0x20,0x00,0x48,0x14,0x02,0x44,0x00,0x93,0x30,0x24,0xc0,0x0b,0x33,0x02,0x8d,0x84 }, - 16, 0xe9c0, 0, {0xb3,0x20,0x6c,0xc0,0x2a,0x36,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9d0, 0, {0xc0,0x15,0xac,0x10,0x9b,0x02,0x2e,0x41,0x0b,0xb0,0x02,0xa4,0x00,0x9a,0x00,0x4a }, - 16, 0xe9e0, 0, {0x60,0x88,0xb0,0x52,0x6c,0x01,0xb9,0x00,0x26,0x00,0x08,0x91,0x22,0xec,0x08,0xbb }, - 16, 0xe9f0, 0, {0x00,0x26,0xc0,0x0b,0xb0,0x02,0xac,0x00,0xbb,0x05,0x6e,0xc1,0x0a,0xb0,0x02,0xf0 }, - 16, 0xea00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xdb,0x01,0x3e,0x30 }, - 16, 0xea10, 0, {0x2d,0x30,0x03,0x47,0x60,0xd8,0xa0,0x16,0x38,0x8f,0xb0,0x03,0x6c,0x00,0x79,0x02 }, - 16, 0xea20, 0, {0x31,0x60,0x0c,0xc8,0x0a,0x66,0x00,0xbb,0x00,0xb6,0xc0,0x0f,0xb0,0x0b,0xac,0x00 }, - 16, 0xea30, 0, {0xfb,0x01,0x3e,0xc1,0x0e,0xb0,0x03,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea40, 0, {0xe0,0x01,0xbc,0x10,0xef,0x08,0x3f,0x24,0x0c,0xf0,0x03,0x76,0x20,0xee,0x90,0x35 }, - 16, 0xea50, 0, {0x40,0x0e,0x70,0x03,0xac,0x00,0xfd,0x00,0xbb,0x64,0x0f,0x88,0x13,0x34,0x80,0xcb }, - 16, 0xea60, 0, {0x00,0x3b,0xc0,0x0f,0xb0,0x03,0x6c,0x08,0xff,0x00,0x3e,0xc0,0x0d,0xf0,0x03,0xf8 }, - 16, 0xea70, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x01,0xfb,0x80,0x32,0x10 }, - 16, 0xea80, 0, {0x0e,0xb0,0x03,0xed,0x00,0xcb,0x50,0x3e,0x40,0x8c,0xb0,0x43,0x2c,0x10,0xf9,0x00 }, - 16, 0xea90, 0, {0x32,0x60,0x0c,0x40,0x0b,0x26,0x00,0xc3,0x04,0x36,0xc0,0x0c,0x30,0x03,0x2c,0x00 }, - 16, 0xeaa0, 0, {0x9b,0x00,0xb0,0xc0,0x0c,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeab0, 0, {0xc8,0x05,0x0e,0x80,0xbf,0x04,0x2a,0x40,0x00,0xf5,0x00,0xe6,0x00,0x82,0xd2,0x22 }, - 16, 0xeac0, 0, {0x40,0x0d,0xf0,0x22,0x3c,0x00,0x95,0x02,0x36,0x40,0x0a,0x80,0x02,0x2e,0x00,0x8f }, - 16, 0xead0, 0, {0x00,0x37,0xc0,0x0a,0xf0,0x42,0x3c,0x00,0x8f,0x00,0x23,0xc0,0x28,0xf0,0x02,0xf2 }, - 16, 0xeae0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4e,0x00,0xb3,0x00,0x22,0x20 }, - 16, 0xeaf0, 0, {0x4a,0x30,0x00,0xcc,0x00,0x81,0xc0,0x28,0x00,0x08,0x30,0x02,0x0c,0x10,0xa1,0x00 }, - 16, 0xeb00, 0, {0x28,0x80,0x18,0x30,0x22,0x04,0x04,0x83,0x00,0x24,0xc0,0x08,0x30,0x02,0xcc,0x08 }, - 16, 0xeb10, 0, {0x93,0x00,0x20,0xc0,0x08,0x30,0x06,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb20, 0, {0x20,0x01,0x1e,0x00,0xb7,0x80,0x29,0xa0,0x08,0x78,0x02,0xfe,0x20,0x8d,0x80,0x29 }, - 16, 0xeb30, 0, {0xe5,0x5b,0x38,0x42,0x1e,0x40,0xa1,0x81,0x25,0xa8,0x08,0x79,0x02,0x37,0x00,0x87 }, - 16, 0xeb40, 0, {0x80,0x25,0xe0,0x0a,0x78,0x0a,0xde,0x81,0x87,0x80,0x25,0xe5,0x48,0x78,0x02,0xc8 }, - 16, 0xeb50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xb3,0x10,0x30,0x12 }, - 16, 0xeb60, 0, {0x0e,0x30,0x12,0xcc,0xc0,0xc3,0x00,0x38,0x80,0x0c,0x31,0x06,0x0c,0x40,0xf1,0x00 }, - 16, 0xeb70, 0, {0x38,0x80,0x0c,0x30,0x43,0x04,0x42,0xc3,0x00,0x36,0xc0,0x0c,0x32,0x03,0xce,0xc0 }, - 16, 0xeb80, 0, {0xdb,0x00,0x30,0xc0,0x0c,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb90, 0, {0x40,0x1d,0xbc,0x00,0xff,0x10,0x3d,0x84,0x4f,0xf1,0x03,0xd0,0x40,0xfc,0x10,0x33 }, - 16, 0xeba0, 0, {0x80,0x5d,0xb1,0x83,0xfc,0x50,0xdd,0x0a,0x25,0x89,0x0f,0xb8,0x03,0xd4,0x00,0xff }, - 16, 0xebb0, 0, {0x10,0x3f,0xc0,0x0f,0xf4,0x03,0x3c,0x40,0xff,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xd0 }, - 16, 0xebc0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x20,0x3e,0x00 }, - 16, 0xebd0, 0, {0x0f,0xb5,0x03,0x29,0x20,0xf9,0x00,0x32,0xa0,0x0c,0xb0,0x83,0xec,0x00,0x49,0xc8 }, - 16, 0xebe0, 0, {0xb2,0xc0,0x8c,0xa0,0x03,0x64,0x00,0xfb,0x08,0x12,0xea,0x0c,0xb0,0x0b,0x2c,0x80 }, - 16, 0xebf0, 0, {0xfb,0x20,0x2e,0xd2,0x6c,0xb6,0x43,0xea,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec00, 0, {0x48,0x11,0x9c,0x00,0xb7,0x49,0x2d,0x00,0x0b,0x30,0x82,0x10,0x01,0xb5,0x02,0x83 }, - 16, 0xec10, 0, {0xc0,0x1a,0x72,0x22,0xdd,0x41,0x85,0x00,0x61,0xc0,0x18,0x20,0x20,0x14,0x00,0xbf }, - 16, 0xec20, 0, {0x40,0x35,0xd0,0x0d,0x34,0x02,0x1d,0x20,0xb7,0x28,0x25,0xc1,0x08,0x74,0x82,0xd2 }, - 16, 0xec30, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x04,0x37,0xa0,0x2d,0x20 }, - 16, 0xec40, 0, {0x0b,0x7a,0x12,0x16,0x01,0xb3,0x80,0x21,0xe2,0x08,0x78,0x42,0x9e,0x00,0x85,0x80 }, - 16, 0xec50, 0, {0x20,0xe1,0x18,0x68,0x02,0x56,0x00,0xb7,0xa0,0x25,0xe0,0x08,0x7a,0x02,0x1e,0x00 }, - 16, 0xec60, 0, {0xb7,0x90,0x2c,0xe5,0x88,0x7a,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec70, 0, {0x48,0x14,0xcc,0x00,0xb3,0x00,0x6c,0x24,0x1b,0x30,0x02,0x00,0x00,0xb0,0x00,0x20 }, - 16, 0xec80, 0, {0xf8,0x0a,0x30,0x02,0xcc,0x00,0x81,0x00,0x20,0xd8,0x18,0x20,0x02,0x04,0x00,0xb3 }, - 16, 0xec90, 0, {0x00,0x24,0xc0,0x09,0x30,0x02,0x0c,0x00,0xb3,0x00,0x26,0xc0,0x08,0x30,0x02,0xd2 }, - 16, 0xeca0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x00,0x3d,0x80 }, - 16, 0xecb0, 0, {0x0f,0x20,0x0b,0x28,0x80,0xfe,0x00,0x33,0xa0,0x0c,0xa0,0x03,0xe8,0x02,0xca,0x02 }, - 16, 0xecc0, 0, {0x32,0x90,0x2c,0xe4,0x03,0x78,0x00,0xfa,0x00,0x32,0x80,0x0c,0xa0,0x03,0x28,0x00 }, - 16, 0xecd0, 0, {0xfa,0x00,0x3e,0x80,0x0c,0xa0,0x03,0xfa,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xece0, 0, {0x48,0x00,0xe1,0x00,0xf0,0x00,0x3e,0x00,0x4f,0x80,0x03,0xe0,0x80,0xf8,0x00,0x3e }, - 16, 0xecf0, 0, {0x00,0x0f,0x80,0x23,0xc0,0x00,0xf8,0x02,0x3c,0x00,0x0f,0xc0,0x83,0x60,0x00,0xb8 }, - 16, 0xed00, 0, {0x00,0x3e,0x00,0x0f,0x80,0x23,0xe0,0x18,0xf8,0x01,0x36,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xed10, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe6,0x00,0xf9,0x21,0x32,0x60 }, - 16, 0xed20, 0, {0x0c,0x90,0x03,0x2c,0x44,0xf9,0x00,0xb2,0x40,0x0f,0x90,0x1b,0x24,0x00,0xe9,0x00 }, - 16, 0xed30, 0, {0x3e,0x40,0x0c,0x10,0x03,0xa4,0x00,0xf9,0x00,0x32,0x40,0x0f,0x10,0x33,0x24,0x10 }, - 16, 0xed40, 0, {0xf1,0x00,0x32,0x40,0x0c,0x90,0x03,0x02,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed50, 0, {0x80,0x04,0x64,0x00,0xb9,0x40,0xa2,0x41,0x08,0x90,0x02,0x24,0x80,0xe9,0x00,0x22 }, - 16, 0xed60, 0, {0x40,0x0b,0x90,0x12,0x24,0x00,0x89,0x00,0x6e,0x41,0x18,0x90,0x42,0x24,0x00,0xb9 }, - 16, 0xed70, 0, {0x04,0x2a,0x41,0x0b,0x90,0x03,0x64,0x00,0xf9,0x00,0x2a,0x40,0x0a,0x90,0x0a,0x20 }, - 16, 0xed80, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x80,0xb9,0x42,0x62,0x48 }, - 16, 0xed90, 0, {0x28,0x90,0x0a,0x24,0x00,0xb1,0x00,0x22,0x40,0x0b,0x10,0x02,0x24,0x10,0xb9,0x02 }, - 16, 0xeda0, 0, {0x2e,0x40,0x08,0xd0,0x02,0xa4,0x00,0xb1,0x00,0x22,0x40,0x0b,0x90,0x02,0x24,0x04 }, - 16, 0xedb0, 0, {0xb9,0x00,0x22,0x40,0x08,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xedc0, 0, {0x08,0x04,0x0c,0x00,0xb1,0x20,0x60,0x40,0x08,0x12,0x02,0x04,0x00,0xa1,0x20,0x20 }, - 16, 0xedd0, 0, {0x40,0x0b,0x12,0x02,0x04,0x80,0x91,0x20,0x2d,0x68,0x08,0x52,0x12,0x04,0x00,0xb1 }, - 16, 0xede0, 0, {0x28,0x28,0x4a,0x09,0x12,0x82,0x44,0xa0,0xb1,0x2c,0x28,0x4a,0x0a,0x12,0x82,0x02 }, - 16, 0xedf0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x00,0x32,0x14 }, - 16, 0xee00, 0, {0x0c,0x80,0x03,0x20,0x00,0xf8,0x50,0x32,0x14,0x0f,0x85,0x03,0x01,0x40,0xf8,0x00 }, - 16, 0xee10, 0, {0x2e,0x00,0x28,0xc0,0x03,0xa0,0x00,0xf8,0x24,0x30,0x08,0x0f,0x82,0x23,0x20,0x80 }, - 16, 0xee20, 0, {0xf8,0x20,0x32,0x08,0x0c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee30, 0, {0x98,0x1d,0xe4,0x08,0xf9,0x10,0x3f,0x40,0x8f,0x91,0x13,0xe4,0x00,0xed,0x10,0x3f }, - 16, 0xee40, 0, {0x50,0x0f,0x91,0x03,0xe4,0x40,0xa5,0x10,0x3e,0x44,0x0f,0x91,0x03,0xf4,0x04,0xf9 }, - 16, 0xee50, 0, {0x28,0x3e,0x4b,0x0b,0x92,0xa3,0xe4,0xa0,0xe9,0x28,0x3e,0x4a,0x0f,0x92,0x83,0xe6 }, - 16, 0xee60, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf4,0x00,0xcd,0x00,0x33,0x40 }, - 16, 0xee70, 0, {0x80,0xd0,0x01,0xf4,0x00,0xa5,0x00,0x26,0x40,0x0f,0x90,0x03,0x26,0x00,0xf1,0x88 }, - 16, 0xee80, 0, {0x3e,0x68,0x0d,0x98,0x83,0x44,0x00,0xc9,0xc0,0x3a,0x40,0x0c,0x98,0x03,0x24,0x08 }, - 16, 0xee90, 0, {0xf9,0xa0,0x32,0x78,0x0f,0x9a,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeea0, 0, {0x38,0x10,0xe0,0x02,0x88,0x00,0xa2,0x00,0x08,0x80,0x02,0xe0,0x00,0x0a,0x00,0x22 }, - 16, 0xeeb0, 0, {0x00,0x0b,0x80,0x02,0x20,0x00,0xb8,0x40,0x2e,0x14,0x08,0x80,0x43,0x30,0x00,0x88 }, - 16, 0xeec0, 0, {0xa0,0x22,0x2a,0x0a,0x8a,0x42,0xa0,0x05,0xb8,0x42,0x32,0x38,0x0b,0x80,0x02,0x0e }, - 16, 0xeed0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x03,0x91,0x00,0x24,0x40 }, - 16, 0xeee0, 0, {0x0b,0x10,0x02,0xc4,0x11,0xb1,0x04,0x20,0x41,0x1b,0x10,0x22,0x45,0x00,0xb5,0x00 }, - 16, 0xeef0, 0, {0x25,0x40,0x09,0x50,0x02,0x54,0x01,0x81,0x40,0x2c,0x40,0x09,0x14,0x92,0x44,0x00 }, - 16, 0xef00, 0, {0xb1,0x40,0x24,0x4c,0x0b,0x14,0x0a,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef10, 0, {0x18,0x15,0xa4,0x00,0x99,0x00,0x24,0x42,0x0b,0x90,0x02,0xe4,0x01,0x99,0x20,0x26 }, - 16, 0xef20, 0, {0x40,0xcb,0x90,0x02,0x64,0x00,0xbb,0x00,0x2f,0x41,0x0a,0xd0,0x02,0x34,0x00,0x89 }, - 16, 0xef30, 0, {0x00,0x26,0x40,0x0b,0x10,0x02,0xe4,0x00,0x31,0x00,0x62,0x40,0x0b,0x90,0x02,0x46 }, - 16, 0xef40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xc4,0x00,0xd9,0x01,0x36,0x50 }, - 16, 0xef50, 0, {0x2f,0x90,0x03,0xe6,0x60,0xf9,0x80,0x36,0x52,0x0b,0x90,0x0a,0x64,0x00,0xf9,0x00 }, - 16, 0xef60, 0, {0x36,0x40,0x0d,0x90,0x03,0x64,0x02,0x09,0x00,0x3e,0x40,0x0d,0x90,0x03,0x64,0x00 }, - 16, 0xef70, 0, {0xb9,0x00,0xb6,0x40,0x0f,0x90,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef80, 0, {0x28,0x01,0xa4,0x00,0xe1,0x00,0x3a,0x41,0x0c,0x90,0x23,0xe6,0x20,0xe9,0x00,0xba }, - 16, 0xef90, 0, {0x70,0x0f,0x90,0x03,0xa4,0x00,0xf9,0x00,0x3e,0x40,0x0d,0x10,0x13,0xa7,0x00,0xf9 }, - 16, 0xefa0, 0, {0x00,0x3a,0x40,0x0e,0x90,0x43,0xa4,0x08,0xf9,0x00,0x3a,0x40,0x0f,0x90,0x03,0x8a }, - 16, 0xefb0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x20,0xf8,0x00,0x32,0x00 }, - 16, 0xefc0, 0, {0x0f,0x80,0x83,0x21,0x00,0xf0,0x00,0x3a,0x11,0x09,0x80,0x03,0xe0,0x00,0xc8,0x01 }, - 16, 0xefd0, 0, {0x30,0x01,0x0c,0x80,0x03,0xb0,0x00,0xd0,0x00,0x34,0x00,0x0d,0x80,0x03,0x20,0x00 }, - 16, 0xefe0, 0, {0xc8,0x00,0x32,0x00,0x0c,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeff0, 0, {0x28,0x05,0x38,0x00,0xbe,0x00,0x22,0x80,0x03,0xe8,0x02,0x1a,0x08,0xbe,0x48,0x22 }, - 16, 0xf000, 0, {0x80,0x0a,0xa0,0x03,0xb8,0x00,0xca,0x08,0x22,0x80,0x0f,0xa4,0x02,0x08,0x00,0x8a }, - 16, 0xf010, 0, {0x00,0x22,0x80,0x8d,0xa0,0x02,0x28,0x00,0xda,0x00,0x2a,0x81,0x08,0xa0,0x02,0x8a }, - 16, 0xf020, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x44,0x00,0xb3,0x00,0x20,0x40 }, - 16, 0xf030, 0, {0x0b,0x30,0x02,0x08,0x00,0xb0,0x64,0x68,0xc1,0x08,0xb0,0x22,0xcc,0x0c,0x93,0x80 }, - 16, 0xf040, 0, {0x00,0xc0,0x48,0x36,0x02,0x88,0x00,0xb3,0x00,0x24,0xc0,0x08,0x30,0x06,0x0c,0x01 }, - 16, 0xf050, 0, {0xa3,0x02,0x2c,0xc0,0x08,0xb0,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf060, 0, {0xa0,0x01,0x14,0x08,0xb5,0x00,0x21,0x40,0x0b,0x38,0x82,0x1c,0x21,0xb7,0x00,0x23 }, - 16, 0xf070, 0, {0xe8,0x4a,0x72,0x26,0x9e,0x40,0x8f,0x81,0xab,0x40,0x42,0x70,0x52,0x38,0x00,0xa3 }, - 16, 0xf080, 0, {0x22,0x20,0xc4,0x49,0x31,0x02,0x1e,0x0a,0xb7,0x22,0x2d,0xe8,0x08,0x72,0x02,0xa8 }, - 16, 0xf090, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xf6,0x80,0x21,0xe0 }, - 16, 0xf0a0, 0, {0x0b,0x78,0x0b,0x1e,0x00,0xb4,0x82,0x3b,0xe8,0x4c,0x7c,0x13,0xfe,0x02,0x97,0x80 }, - 16, 0xf0b0, 0, {0x33,0xa0,0x08,0x38,0x03,0x9a,0x00,0xf7,0x88,0x35,0xe2,0x0c,0x78,0xe3,0x0e,0x00 }, - 16, 0xf0c0, 0, {0xe3,0xe8,0x34,0xf8,0x0c,0x3c,0x23,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0d0, 0, {0x08,0x1d,0xa8,0x04,0xf1,0x00,0x3e,0x42,0x0f,0xb0,0x13,0xec,0x00,0xfb,0x00,0xbe }, - 16, 0xf0e0, 0, {0xcc,0x1e,0xb6,0x07,0xed,0x80,0xfb,0x00,0x36,0x00,0x0f,0xb0,0x43,0x68,0x00,0xcb }, - 16, 0xf0f0, 0, {0x30,0x3e,0xd8,0x0f,0xb6,0x0b,0xed,0x40,0xcb,0x00,0x3a,0xc0,0x2f,0xb6,0x03,0xc2 }, - 16, 0xf100, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf2,0x40,0xfb,0x91,0x3d,0x4c }, - 16, 0xf110, 0, {0x80,0xf8,0x03,0xde,0x40,0xc6,0x80,0x1b,0xf0,0x4f,0xfd,0x07,0xff,0x00,0xcd,0x80 }, - 16, 0xf120, 0, {0x33,0xe0,0x0c,0x68,0x03,0xba,0x00,0xff,0x80,0x33,0xe0,0x07,0xf8,0x03,0x3f,0x10 }, - 16, 0xf130, 0, {0xcf,0x80,0x3f,0xe0,0x0c,0xfc,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf140, 0, {0xa8,0x11,0x90,0x00,0xb5,0xc0,0x2d,0x40,0x08,0x62,0x02,0xdc,0x20,0xd6,0x02,0x21 }, - 16, 0xf150, 0, {0xc8,0x8f,0x70,0x02,0xdc,0x81,0xb5,0x00,0x81,0x44,0x0d,0x61,0x22,0x18,0x04,0xb7 }, - 16, 0xf160, 0, {0x00,0x35,0xc0,0x0b,0x70,0x02,0xbc,0x00,0xa7,0x01,0x2d,0xc0,0x08,0x70,0x03,0xea }, - 16, 0xf170, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x01,0xb6,0x01,0x2f,0xc0 }, - 16, 0xf180, 0, {0x18,0x70,0x02,0xdc,0x0a,0x96,0x10,0x29,0xc1,0x4b,0x70,0x06,0xdc,0x10,0x85,0x00 }, - 16, 0xf190, 0, {0x25,0x80,0x08,0x60,0x82,0x1a,0x20,0xa3,0x00,0x25,0xc0,0x0b,0x31,0x02,0x5c,0x40 }, - 16, 0xf1a0, 0, {0x87,0x00,0x2d,0xc0,0x08,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1b0, 0, {0x20,0x14,0xc8,0x00,0xb1,0x00,0x2c,0x40,0x88,0x20,0x02,0xed,0x00,0x8a,0x60,0x20 }, - 16, 0xf1c0, 0, {0xc0,0x0a,0x30,0x02,0xcc,0x04,0xb1,0x00,0x24,0x00,0x28,0x24,0x02,0x0a,0x00,0x33 }, - 16, 0xf1d0, 0, {0x00,0x24,0xc0,0x0b,0xb0,0x02,0xcc,0x00,0xa3,0x00,0x2c,0xc0,0x88,0x30,0x02,0x88 }, - 16, 0xf1e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xfb,0x00,0x3e,0xc6 }, - 16, 0xf1f0, 0, {0x0c,0x80,0x03,0xe5,0x00,0x09,0xc8,0xab,0xe2,0x0b,0xf0,0x02,0xfc,0x00,0x4a,0x00 }, - 16, 0xf200, 0, {0x36,0xc0,0x08,0x90,0x03,0xa6,0x00,0xff,0x00,0x33,0xc0,0x0f,0xf0,0x03,0x7c,0x00 }, - 16, 0xf210, 0, {0x8f,0x00,0x2f,0xc0,0x28,0xf0,0x02,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf220, 0, {0x80,0x00,0xe1,0x00,0xfa,0x01,0x3e,0xc0,0x0f,0x80,0x03,0xec,0x00,0xf9,0x40,0x3e }, - 16, 0xf230, 0, {0xc0,0x07,0xb0,0x03,0xec,0x00,0xfa,0x00,0x3a,0x40,0x0f,0x90,0x23,0xe5,0x00,0xfb }, - 16, 0xf240, 0, {0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xac,0x00,0xfb,0x00,0x3c,0xc0,0x0f,0xb0,0x23,0xe0 }, - 16, 0xf250, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xfc,0x20,0x3f,0xc0 }, - 16, 0xf260, 0, {0x0c,0xc8,0x03,0xfc,0x20,0xcd,0x81,0xb3,0xc2,0x4f,0xf0,0x03,0xfc,0x00,0xca,0x00 }, - 16, 0xf270, 0, {0x3c,0x80,0x0c,0xd0,0x82,0x36,0x01,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0x3c,0x08 }, - 16, 0xf280, 0, {0xcf,0x04,0x3a,0xc0,0x5c,0xb0,0x03,0xc0,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf290, 0, {0x81,0x04,0x62,0x04,0xb8,0x40,0x2c,0x60,0x08,0x89,0x02,0xee,0x80,0xa9,0x60,0x2a }, - 16, 0xf2a0, 0, {0xc0,0x0b,0xb0,0x03,0x8c,0x00,0xaa,0x40,0x2e,0x00,0x08,0x10,0x02,0x26,0x81,0xeb }, - 16, 0xf2b0, 0, {0x00,0x26,0xc0,0x8b,0xb0,0x13,0x6c,0x00,0xdb,0x00,0x2e,0xc0,0x3d,0xb0,0x02,0xe0 }, - 16, 0xf2c0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x23,0x00,0xbb,0x03,0x2e,0xc8 }, - 16, 0xf2d0, 0, {0x09,0xb0,0x02,0xee,0x00,0x8b,0x10,0x26,0xc0,0x0b,0xb0,0x02,0xec,0x00,0xa8,0x00 }, - 16, 0xf2e0, 0, {0x2e,0xc0,0x08,0x88,0x22,0xa4,0x80,0xbb,0x00,0x2e,0xc0,0x4b,0xb0,0x22,0x0c,0x00 }, - 16, 0xf2f0, 0, {0x8b,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf300, 0, {0x08,0x04,0x00,0x00,0xb2,0x00,0x2e,0xc0,0x29,0x28,0x02,0xec,0x01,0xa0,0x02,0x20 }, - 16, 0xf310, 0, {0xc0,0x09,0x30,0x02,0xcc,0x00,0xa0,0x00,0x2c,0x40,0x08,0x00,0x42,0x84,0x00,0x93 }, - 16, 0xf320, 0, {0x00,0x6c,0xc0,0x0b,0x30,0x06,0x4d,0x00,0x93,0x00,0x2c,0xc0,0x08,0x30,0x02,0xc2 }, - 16, 0xf330, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xf8,0x20,0x2f,0xc0 }, - 16, 0xf340, 0, {0x0d,0xb0,0x03,0xec,0x00,0xcb,0x00,0x33,0xc0,0x0b,0xf0,0x03,0xfc,0x18,0xe8,0x00 }, - 16, 0xf350, 0, {0x2e,0x80,0x08,0x80,0x03,0xa4,0x00,0xbf,0x00,0x3f,0xc0,0x0f,0xf0,0x43,0x3d,0x11 }, - 16, 0xf360, 0, {0xcf,0x03,0x3e,0xc1,0x5d,0xf0,0x23,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf370, 0, {0xa0,0x1d,0xf0,0x00,0xfc,0x10,0x3f,0x40,0x0e,0xe0,0x03,0xfc,0x00,0xfc,0x00,0x3f }, - 16, 0xf380, 0, {0xc0,0x0f,0xf0,0x03,0xbc,0x00,0xfc,0x00,0x3f,0x00,0x2f,0xc0,0x03,0x74,0x00,0xef }, - 16, 0xf390, 0, {0x00,0x27,0xc0,0x0f,0xf0,0x03,0xfc,0x18,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8 }, - 16, 0xf3a0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xfc,0x88,0x9c,0x29,0x3f,0x08 }, - 16, 0xf3b0, 0, {0x0f,0xd2,0x83,0xec,0x00,0xff,0x08,0x3f,0x28,0x0f,0xca,0x03,0x3c,0x41,0xcf,0x20 }, - 16, 0xf3c0, 0, {0x73,0x2c,0x0c,0xc0,0x03,0x30,0x20,0xcf,0x60,0x33,0xd8,0x0f,0x78,0x03,0x3f,0x80 }, - 16, 0xf3d0, 0, {0xdd,0x92,0x33,0xc8,0x0f,0x50,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3e0, 0, {0x80,0x10,0xe5,0x40,0x88,0x40,0x2e,0x04,0x8b,0x94,0x02,0xe4,0x00,0xb9,0x00,0x0e }, - 16, 0xf3f0, 0, {0x7f,0x8f,0x9e,0x83,0x65,0x82,0xcf,0x68,0x3e,0x50,0x8d,0x04,0x92,0x2f,0x04,0xd3 }, - 16, 0xf400, 0, {0x40,0x74,0xdc,0x0d,0xa2,0x02,0x20,0x40,0x89,0x00,0x22,0xf0,0x0b,0x98,0x02,0x20 }, - 16, 0xf410, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x09,0xa0,0x85,0x2c,0x01 }, - 16, 0xf420, 0, {0x0b,0x00,0x10,0xcc,0x40,0xa2,0x08,0x2c,0x00,0xdb,0x11,0x02,0x89,0x00,0x93,0x30 }, - 16, 0xf430, 0, {0x20,0x05,0x08,0x13,0x02,0x80,0x08,0xa3,0x60,0x60,0xc0,0x0a,0xb0,0x82,0x08,0x84 }, - 16, 0xf440, 0, {0x81,0x20,0x20,0xd0,0x0b,0x10,0x02,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf450, 0, {0xc0,0x15,0xa4,0x12,0x88,0x80,0x6e,0x20,0x0b,0x88,0x82,0xee,0x00,0xba,0x81,0x2e }, - 16, 0xf460, 0, {0x60,0x5a,0x98,0x02,0xa2,0x00,0x8b,0x00,0x2a,0x60,0x08,0x11,0x1a,0x2c,0x00,0xbb }, - 16, 0xf470, 0, {0x00,0x22,0xc0,0x08,0xb8,0x0a,0x28,0x00,0x81,0x20,0x02,0xc0,0x0b,0x90,0x02,0xb0 }, - 16, 0xf480, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xed,0x00,0xd9,0x80,0x3e,0x20 }, - 16, 0xf490, 0, {0x4f,0x98,0x00,0xeb,0x20,0xfb,0xe0,0x2e,0x60,0x0b,0x8c,0x62,0xae,0x20,0x8b,0x00 }, - 16, 0xf4a0, 0, {0x22,0x60,0x08,0xbc,0x03,0xa0,0x20,0xeb,0x00,0x22,0xc1,0x0a,0x18,0x0b,0x25,0x00 }, - 16, 0xf4b0, 0, {0xd9,0x00,0xb2,0xc0,0x0f,0x90,0x0b,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4c0, 0, {0xe0,0x01,0x94,0x88,0xff,0x00,0x3f,0x01,0x0f,0xd0,0x01,0xf0,0x08,0xdd,0x01,0x3f }, - 16, 0xf4d0, 0, {0x42,0x07,0x40,0x03,0x5c,0x00,0xaf,0x00,0x3f,0x40,0x0f,0xf8,0x00,0xf0,0x00,0xdf }, - 16, 0xf4e0, 0, {0x00,0x3f,0xc0,0x0f,0xc0,0x23,0xf4,0x50,0xfd,0x80,0x3f,0xc0,0x0f,0xd0,0x03,0x78 }, - 16, 0xf4f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xac,0x00,0xd9,0x00,0x3e,0x40 }, - 16, 0xf500, 0, {0x0f,0x94,0x03,0xa8,0x20,0xca,0x40,0x3a,0x40,0x0f,0x94,0x03,0xea,0x08,0xfb,0x00 }, - 16, 0xf510, 0, {0x3a,0x00,0x4c,0xf6,0x23,0x2c,0x30,0xcb,0x00,0x36,0xc0,0x0d,0x90,0x03,0xa1,0x02 }, - 16, 0xf520, 0, {0xd9,0x00,0xba,0xc0,0x0f,0x98,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf530, 0, {0xc8,0x05,0x24,0x00,0x8a,0x00,0x2e,0x40,0x0b,0x95,0x02,0xe0,0x08,0x88,0x80,0x22 }, - 16, 0xf540, 0, {0x70,0x8f,0x8c,0x02,0xe0,0x00,0xbf,0x02,0x20,0x00,0x08,0xb8,0x02,0x0e,0x00,0xdf }, - 16, 0xf550, 0, {0x00,0x23,0xdd,0x08,0x98,0x82,0x2a,0x00,0x89,0x80,0x23,0xc0,0x0b,0x50,0x1a,0x32 }, - 16, 0xf560, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x44,0x00,0x83,0x05,0x24,0x41 }, - 16, 0xf570, 0, {0x09,0x10,0x02,0xce,0x00,0x83,0x90,0x2c,0x80,0x1b,0x24,0x82,0xcc,0x00,0xbb,0x00 }, - 16, 0xf580, 0, {0x2c,0x80,0x08,0x04,0x08,0x04,0x01,0x8b,0x00,0x22,0xc0,0x28,0x12,0x02,0x6c,0x80 }, - 16, 0xf590, 0, {0x81,0x48,0x24,0xc4,0x0b,0x10,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5a0, 0, {0x20,0x01,0x3e,0x42,0x86,0x80,0x2d,0x60,0x0b,0x68,0x02,0xf6,0x90,0x8d,0x80,0x21 }, - 16, 0xf5b0, 0, {0x22,0x0b,0x58,0x02,0xd7,0x40,0xb7,0x90,0x21,0xe0,0x08,0x49,0x92,0x1e,0x53,0x97 }, - 16, 0xf5c0, 0, {0x81,0x21,0xe0,0x48,0xc8,0x0a,0x52,0x22,0x85,0x88,0x25,0xe0,0x0b,0x58,0x02,0x08 }, - 16, 0xf5d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x83,0x00,0x34,0xc0 }, - 16, 0xf5e0, 0, {0x0f,0x00,0x03,0xce,0x20,0xc3,0x30,0x7c,0x94,0x0b,0x34,0x83,0xcc,0x14,0xf3,0x02 }, - 16, 0xf5f0, 0, {0x3c,0x80,0x0c,0x04,0x03,0x04,0x60,0xc3,0x00,0xb0,0xc0,0x0c,0x10,0x03,0xec,0x00 }, - 16, 0xf600, 0, {0xc9,0x00,0x3c,0xc4,0x0f,0x11,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf610, 0, {0x40,0x1d,0x9c,0x00,0xee,0x01,0x3f,0xc0,0x4f,0xe1,0x03,0xd4,0x40,0xf5,0x16,0x7a }, - 16, 0xf620, 0, {0xc0,0x4e,0xf0,0x03,0xf4,0x10,0x37,0x05,0x3d,0xc0,0x0f,0xc0,0x0b,0xdc,0x40,0xff }, - 16, 0xf630, 0, {0x00,0x3b,0xc2,0x0e,0xd0,0x07,0xbc,0x02,0xef,0x00,0x3b,0xc6,0x0f,0xd0,0x03,0xd0 }, - 16, 0xf640, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xf4,0x00,0xdd,0x84,0x33,0x80 }, - 16, 0xf650, 0, {0x04,0xf0,0x03,0x6c,0x02,0xcb,0x02,0x7e,0xc0,0x1f,0xa0,0x53,0xec,0x00,0xcb,0x20 }, - 16, 0xf660, 0, {0x34,0x40,0x0c,0xd0,0x0b,0x20,0x10,0xeb,0x00,0x1e,0xe0,0x0f,0x30,0x0b,0x2c,0x00 }, - 16, 0xf670, 0, {0xc1,0x00,0x32,0xc0,0x0f,0x91,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf680, 0, {0x48,0x11,0x9c,0x00,0x87,0x00,0x21,0x80,0x08,0x60,0x00,0x14,0x00,0x85,0x00,0x2d }, - 16, 0xf690, 0, {0x80,0x0b,0x70,0x52,0xd4,0x04,0x83,0x28,0x29,0xc0,0x28,0x50,0x03,0x50,0x00,0x87 }, - 16, 0xf6a0, 0, {0x40,0x25,0xc8,0x0f,0x60,0x02,0x04,0x00,0xa7,0x00,0x3d,0xc8,0x0b,0x52,0x02,0xd2 }, - 16, 0xf6b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x95,0x80,0x21,0xe0 }, - 16, 0xf6c0, 0, {0x09,0x38,0x02,0x1e,0x11,0xa7,0x80,0x2d,0xf0,0x0b,0x78,0x52,0xce,0x0a,0x97,0x95 }, - 16, 0xf6d0, 0, {0x21,0xe0,0x19,0x5c,0x02,0x0e,0x00,0xa7,0x80,0x29,0xc8,0x0b,0xf8,0x02,0x1e,0x20 }, - 16, 0xf6e0, 0, {0x8d,0x80,0x21,0xe0,0x0b,0x58,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6f0, 0, {0x48,0x14,0xcc,0x00,0x82,0xe0,0xa0,0xe8,0x29,0x30,0x06,0x0e,0x50,0xab,0x80,0x2c }, - 16, 0xf700, 0, {0xf0,0x0b,0x31,0x42,0xcc,0x00,0x93,0x00,0x28,0xc4,0x09,0x98,0x02,0x4c,0x28,0x83 }, - 16, 0xf710, 0, {0x00,0x24,0xc0,0x0a,0xb0,0x02,0x0d,0x00,0xa2,0x58,0x28,0xc0,0x0b,0x10,0x02,0xd2 }, - 16, 0xf720, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x00,0xde,0x80,0x31,0xa0 }, - 16, 0xf730, 0, {0x09,0xe2,0x0b,0x78,0x04,0xee,0xa4,0x2f,0xa4,0x8b,0xec,0x02,0xd8,0x00,0xda,0x00 }, - 16, 0xf740, 0, {0x27,0x81,0x0d,0xec,0x06,0x1b,0x00,0xea,0x04,0x3e,0x80,0x0b,0xe0,0x03,0x3b,0x00 }, - 16, 0xf750, 0, {0xce,0xc0,0x22,0x80,0x0f,0xa0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf760, 0, {0x48,0x00,0xe0,0x80,0xf8,0x10,0x3e,0x05,0x0e,0x88,0x03,0xe0,0x08,0x98,0x40,0x3e }, - 16, 0xf770, 0, {0x00,0x0f,0x84,0x83,0xe1,0x40,0xe8,0x00,0x3a,0x02,0x0e,0x80,0x43,0xe1,0x40,0xf8 }, - 16, 0xf780, 0, {0x00,0x36,0x00,0x0f,0x80,0x03,0xe0,0x20,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0xf790, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x00,0xe9,0x00,0x3e,0x40 }, - 16, 0xf7a0, 0, {0x0c,0x90,0x03,0x04,0x20,0xe9,0x90,0x32,0x68,0x0e,0x98,0x03,0xa4,0x00,0xc1,0x00 }, - 16, 0xf7b0, 0, {0x30,0x40,0x0c,0x94,0x83,0x24,0x08,0xc9,0x00,0x3e,0x40,0x0c,0x90,0x03,0xa4,0x00 }, - 16, 0xf7c0, 0, {0xc9,0x00,0x30,0x50,0x0c,0x1a,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7d0, 0, {0x80,0x04,0x64,0x00,0x89,0x40,0x2e,0x50,0x28,0x90,0x0a,0x24,0x08,0x89,0x06,0x16 }, - 16, 0xf7e0, 0, {0x61,0x0b,0x9c,0x02,0xe4,0x20,0xa9,0x00,0x36,0x40,0x0d,0x90,0x02,0x27,0x60,0xa9 }, - 16, 0xf7f0, 0, {0x00,0x2e,0x40,0x28,0x90,0x1a,0x24,0x00,0x89,0x00,0x36,0x40,0x28,0x98,0x02,0x20 }, - 16, 0xf800, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x2c,0x00,0xa9,0x08,0x2e,0xc2 }, - 16, 0xf810, 0, {0x09,0x10,0x00,0x24,0x00,0xa9,0x00,0x06,0x40,0x89,0x96,0x06,0xe6,0x00,0x89,0x00 }, - 16, 0xf820, 0, {0x22,0xc0,0x08,0x90,0x02,0x24,0x02,0x89,0x00,0x24,0x40,0x08,0x90,0x02,0x0c,0x06 }, - 16, 0xf830, 0, {0x83,0x00,0x22,0x40,0x08,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf840, 0, {0x08,0x04,0x05,0x00,0x81,0x44,0x2c,0x50,0x08,0x14,0x02,0x05,0x80,0x81,0x20,0x64 }, - 16, 0xf850, 0, {0x70,0x1b,0x14,0x02,0xe4,0x80,0xa1,0x20,0x64,0x40,0x19,0x12,0x0a,0x04,0x80,0xa1 }, - 16, 0xf860, 0, {0x00,0x2c,0x50,0x18,0x14,0x02,0x85,0x00,0x81,0x40,0x24,0x40,0x40,0x10,0x02,0x02 }, - 16, 0xf870, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xe0,0x00,0x3c,0x00 }, - 16, 0xf880, 0, {0x0d,0x80,0x02,0x00,0x00,0xaa,0x50,0x36,0x00,0x0f,0x80,0x03,0xe1,0x40,0xc8,0x52 }, - 16, 0xf890, 0, {0x72,0x14,0x0c,0x05,0x16,0x20,0x08,0xc8,0x50,0x3e,0x01,0x0c,0x80,0x03,0xa0,0x04 }, - 16, 0xf8a0, 0, {0xc8,0x00,0xb2,0x00,0x0c,0x80,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8b0, 0, {0x98,0x19,0xf5,0x02,0xfd,0x40,0x3f,0xd0,0x0f,0xd4,0x23,0xf4,0x44,0xfd,0x14,0x7f }, - 16, 0xf8c0, 0, {0x50,0x0f,0xd4,0x07,0xf4,0x40,0xf9,0x10,0x3f,0x50,0x07,0xd1,0x23,0xf4,0x40,0xf9 }, - 16, 0xf8d0, 0, {0x40,0x1e,0x50,0x07,0xd0,0x0b,0x75,0x00,0xfd,0x02,0x3e,0x50,0x0f,0xd4,0x03,0xe6 }, - 16, 0xf8e0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x00,0xc9,0xa8,0x3e,0x72 }, - 16, 0xf8f0, 0, {0x0f,0x98,0x03,0xe6,0xc0,0xfd,0xa0,0xb3,0x40,0x0f,0xd0,0x03,0x77,0x80,0xcd,0x90 }, - 16, 0xf900, 0, {0x7f,0x40,0x0f,0xda,0xa3,0x16,0x90,0xa9,0xc0,0x32,0x60,0x4c,0xb1,0x03,0x24,0x00 }, - 16, 0xf910, 0, {0xc1,0x00,0x33,0x6a,0x0b,0xda,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf920, 0, {0x38,0x10,0xe3,0x40,0x88,0xe0,0x2e,0x30,0x0b,0x8d,0x02,0xf3,0x40,0xb8,0xe8,0x76 }, - 16, 0xf930, 0, {0x00,0x4f,0x80,0x0a,0x22,0x80,0x88,0x90,0x6e,0x28,0x8f,0x8a,0x03,0x61,0x44,0xf8 }, - 16, 0xf940, 0, {0xe1,0x3e,0x2a,0x08,0x88,0x03,0x42,0xa0,0xdc,0xa0,0x3e,0x10,0x0b,0x85,0x0a,0x0e }, - 16, 0xf950, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0xa0,0x85,0x08,0x2d,0x48 }, - 16, 0xf960, 0, {0x1b,0x52,0x82,0xd4,0x80,0xb1,0x14,0x20,0x40,0x0b,0x18,0x02,0x05,0x82,0x81,0x00 }, - 16, 0xf970, 0, {0x6c,0x42,0x0b,0x12,0x82,0x04,0x00,0xa1,0x60,0x21,0x50,0x0b,0x50,0x02,0x14,0x90 }, - 16, 0xf980, 0, {0x95,0x2c,0x28,0x40,0x0b,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf990, 0, {0x18,0x15,0xa4,0x01,0x8d,0x44,0x2f,0x40,0x0b,0xd4,0x02,0xf4,0x04,0xb9,0x08,0x22 }, - 16, 0xf9a0, 0, {0x40,0x0a,0x92,0x02,0x2c,0x84,0x89,0x00,0x2e,0x40,0x0a,0x14,0x02,0x6c,0x80,0xa9 }, - 16, 0xf9b0, 0, {0x01,0x2a,0x40,0x09,0x50,0x0a,0x5c,0x02,0x8d,0x60,0x2a,0x40,0x0b,0x90,0x42,0x06 }, - 16, 0xf9c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x62,0xc9,0x02,0x3e,0x54 }, - 16, 0xf9d0, 0, {0x0f,0x90,0x03,0xe4,0x00,0xf9,0x40,0x22,0x46,0x0b,0x98,0x03,0x67,0x20,0xc9,0x01 }, - 16, 0xf9e0, 0, {0x2e,0x69,0x0b,0x94,0x0b,0x25,0x20,0xa9,0x00,0x22,0x40,0x2d,0x92,0x0a,0x26,0x22 }, - 16, 0xf9f0, 0, {0x99,0x00,0x2a,0x40,0x8f,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa00, 0, {0x28,0x01,0x86,0x02,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xe6,0x80,0xf1,0xa0,0x3e }, - 16, 0xfa10, 0, {0x62,0x0f,0x98,0x83,0xc6,0x20,0xf9,0x00,0x3e,0x49,0x0f,0x90,0x83,0xe4,0x00,0x71 }, - 16, 0xfa20, 0, {0x02,0x3e,0x40,0x0e,0x90,0x0b,0xe6,0x80,0xf9,0x80,0x3e,0x40,0x0f,0x90,0x03,0xca }, - 16, 0xfa30, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x10,0xc8,0x00,0x3e,0x00 }, - 16, 0xfa40, 0, {0x4f,0x80,0x43,0xb0,0x00,0xc8,0x41,0x32,0x00,0x0f,0x80,0x03,0x21,0x02,0xc8,0x02 }, - 16, 0xfa50, 0, {0x3e,0x10,0x4c,0x80,0x03,0x01,0x20,0xc8,0x00,0x3b,0x00,0x0c,0xc0,0x03,0xb0,0x00 }, - 16, 0xfa60, 0, {0xcc,0x04,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa70, 0, {0x28,0x05,0x28,0x00,0x8a,0x80,0x2e,0x80,0x0b,0xa0,0x02,0xf8,0x04,0x8e,0x00,0x23 }, - 16, 0xfa80, 0, {0xb2,0x0e,0xe0,0x82,0xf9,0x04,0x8a,0x00,0x2e,0x81,0x0c,0xe0,0x0a,0x3a,0x80,0xda }, - 16, 0xfa90, 0, {0x00,0x22,0xb6,0x08,0xa0,0x02,0x28,0x00,0x8e,0x00,0x2a,0x80,0x0b,0x60,0x0b,0x0a }, - 16, 0xfaa0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x44,0x02,0x93,0x81,0x2c,0xc0 }, - 16, 0xfab0, 0, {0x4b,0x30,0x02,0xc8,0x00,0x83,0xca,0x20,0xe0,0x19,0xb0,0x06,0x8c,0x00,0x81,0x04 }, - 16, 0xfac0, 0, {0x44,0x40,0x08,0x34,0x02,0x0d,0x00,0x83,0x00,0x2a,0x00,0x08,0x00,0x0a,0x80,0x40 }, - 16, 0xfad0, 0, {0x88,0x00,0x20,0xc0,0x0b,0x30,0x02,0x4b,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfae0, 0, {0xa0,0x01,0x04,0x02,0x97,0x08,0x2d,0xc0,0x0b,0x60,0x06,0xca,0x00,0x83,0x09,0x21 }, - 16, 0xfaf0, 0, {0xc0,0x0a,0x70,0x02,0xdc,0x00,0x85,0x31,0x2d,0x68,0x09,0x30,0x02,0x1c,0x14,0x93 }, - 16, 0xfb00, 0, {0x20,0x20,0xc0,0x08,0xf0,0x42,0x9c,0x02,0x8f,0x00,0x29,0x40,0x03,0x70,0x12,0x28 }, - 16, 0xfb10, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x16,0x00,0x96,0x84,0x3d,0xa0 }, - 16, 0xfb20, 0, {0x0f,0x78,0x03,0x9a,0x02,0x87,0x80,0xb1,0xe0,0x0b,0x78,0x03,0xb6,0x00,0xc5,0xa0 }, - 16, 0xfb30, 0, {0x35,0x61,0x0c,0x78,0x13,0x1e,0x02,0xc7,0x80,0x29,0x00,0x0c,0x48,0x03,0x90,0x00 }, - 16, 0xfb40, 0, {0xc4,0x80,0x31,0x60,0x0f,0x58,0x03,0x6a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb50, 0, {0x08,0x1d,0xa4,0x00,0xea,0x00,0x3e,0x80,0x0f,0xa0,0x03,0xe8,0x08,0xfb,0x00,0x3e }, - 16, 0xfb60, 0, {0x80,0x0f,0x90,0x13,0xe4,0x08,0xf9,0x00,0x3c,0x50,0x2e,0xf0,0x03,0xe8,0x08,0xfb }, - 16, 0xfb70, 0, {0x40,0x3e,0xc0,0x0b,0x30,0x13,0x6c,0x00,0xfb,0x00,0x3e,0x40,0x0f,0x30,0x03,0xc2 }, - 16, 0xfb80, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xd6,0x00,0xcd,0x80,0x33,0xe0 }, - 16, 0xfb90, 0, {0x0c,0xf8,0x03,0xfa,0x00,0xfd,0x80,0x3f,0xa0,0x0d,0xf8,0x03,0xfa,0x40,0xcd,0xd0 }, - 16, 0xfba0, 0, {0x77,0x7e,0x0c,0xe8,0x43,0x1e,0x00,0xcf,0xd8,0x3f,0xe0,0x0c,0xc8,0x03,0x3a,0xc4 }, - 16, 0xfbb0, 0, {0xcc,0x80,0x33,0xe0,0x0c,0xf8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbc0, 0, {0xa8,0x11,0x94,0x02,0x8d,0x00,0x21,0xc0,0x08,0x60,0x03,0xd8,0x10,0x35,0x20,0x8b }, - 16, 0xfbd0, 0, {0xd4,0x0d,0x64,0x03,0xd8,0xc0,0x85,0x00,0x2f,0x4e,0x07,0x64,0x02,0x9c,0x02,0xd7 }, - 16, 0xfbe0, 0, {0x30,0x2f,0x04,0x0d,0xf1,0x0b,0x54,0x40,0xaf,0x00,0x35,0x40,0x08,0x70,0x02,0x2a }, - 16, 0xfbf0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x40,0x84,0x18,0x21,0x80 }, - 16, 0xfc00, 0, {0x08,0x70,0x02,0xda,0x20,0xb5,0x00,0x09,0x00,0x08,0x70,0x02,0xd4,0x04,0x85,0x00 }, - 16, 0xfc10, 0, {0x6d,0x4c,0x89,0x60,0x02,0x5c,0x40,0x97,0x00,0x6d,0xc0,0x09,0x40,0x02,0x58,0x80 }, - 16, 0xfc20, 0, {0x84,0x88,0x25,0x40,0x08,0xd0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc30, 0, {0x20,0x14,0xc6,0x48,0x80,0x00,0x20,0x80,0x08,0xac,0x02,0xa8,0x00,0xb1,0x00,0xa8 }, - 16, 0xfc40, 0, {0x88,0x09,0x22,0x02,0x86,0x42,0x81,0x00,0x6c,0x52,0x0b,0x20,0x02,0xc7,0x52,0x83 }, - 16, 0xfc50, 0, {0x00,0x2c,0x00,0x08,0x34,0x82,0x67,0x00,0xa3,0x80,0x20,0x40,0x08,0x30,0x02,0x08 }, - 16, 0xfc60, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa3,0x00,0xcb,0xc0,0xb2,0x40 }, - 16, 0xfc70, 0, {0x2c,0x90,0x82,0xe6,0x00,0xbb,0x80,0xbe,0x78,0x08,0x8e,0x02,0xee,0x00,0x8d,0x00 }, - 16, 0xfc80, 0, {0x27,0x60,0x0d,0x90,0x0a,0x6f,0x00,0x9f,0x02,0x2e,0x00,0x09,0xb4,0x03,0x67,0x80 }, - 16, 0xfc90, 0, {0xca,0x40,0xe4,0xc0,0x0c,0x30,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfca0, 0, {0x80,0x00,0xe0,0x80,0xfb,0x22,0x3e,0x40,0x0f,0x80,0x13,0xe4,0x00,0xfb,0x80,0x3e }, - 16, 0xfcb0, 0, {0x40,0x0f,0x90,0x03,0xe5,0x00,0xf9,0x00,0x3e,0x40,0x0e,0x70,0x23,0xac,0x20,0xfb }, - 16, 0xfcc0, 0, {0x00,0x3e,0xc0,0x8f,0x80,0x03,0xe9,0x20,0xf9,0x08,0x3e,0x40,0x0f,0xb0,0x13,0xe0 }, - 16, 0xfcd0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xc6,0x00,0x32,0x00 }, - 16, 0xfce0, 0, {0x0f,0xd1,0x83,0x34,0x40,0xcf,0x00,0x3d,0x40,0x0c,0xd0,0x03,0xde,0x50,0x0d,0x00 }, - 16, 0xfcf0, 0, {0x73,0x40,0x0c,0xd1,0x03,0x7c,0x40,0x87,0x02,0xb3,0x00,0x0d,0xf4,0x03,0x24,0x00 }, - 16, 0xfd00, 0, {0xce,0x20,0x32,0x40,0x0c,0xd0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd10, 0, {0x81,0x04,0x61,0x22,0x8a,0x00,0x22,0x00,0x0b,0x80,0x40,0x25,0x00,0x89,0xc3,0x2e }, - 16, 0xfd20, 0, {0x20,0x0a,0x98,0x03,0xa1,0x00,0x89,0x00,0x36,0x40,0x88,0x94,0x02,0x0f,0x01,0xab }, - 16, 0xfd30, 0, {0x00,0x32,0xc0,0x08,0x04,0x0a,0x29,0x00,0xa9,0x02,0xa2,0x40,0x0d,0xb0,0x0a,0x20 }, - 16, 0xfd40, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x00,0x89,0x00,0x22,0x61 }, - 16, 0xfd50, 0, {0x0b,0x90,0x02,0x25,0x01,0x9b,0x88,0x2e,0x60,0x08,0x88,0x02,0xe8,0x00,0xb1,0x02 }, - 16, 0xfd60, 0, {0x24,0x40,0x18,0x90,0x02,0x2c,0x00,0xab,0x01,0x20,0xc1,0x08,0xb4,0x42,0x2c,0x00 }, - 16, 0xfd70, 0, {0x82,0x00,0x22,0xc0,0x08,0xb0,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd80, 0, {0x08,0x04,0x00,0x00,0x01,0x00,0x20,0x40,0x0b,0x00,0x0a,0x04,0x46,0x83,0x01,0x2c }, - 16, 0xfd90, 0, {0x40,0x1a,0x00,0x06,0x80,0x00,0x81,0x00,0x24,0x40,0x08,0x20,0x0a,0x0c,0x01,0xa3 }, - 16, 0xfda0, 0, {0x00,0x24,0x00,0x08,0x80,0x02,0x00,0x00,0xa1,0x00,0x20,0x40,0x09,0x30,0x02,0x02 }, - 16, 0xfdb0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x02,0xc8,0x00,0x22,0x00 }, - 16, 0xfdc0, 0, {0x0f,0x90,0x02,0x25,0x00,0xda,0x00,0x3e,0x40,0x0c,0x90,0x02,0xcc,0x00,0xfd,0x00 }, - 16, 0xfdd0, 0, {0x37,0x40,0x0c,0x10,0x13,0x2c,0x02,0xaf,0x00,0x32,0xc0,0x0d,0xb0,0x03,0x2c,0x00 }, - 16, 0xfde0, 0, {0xca,0x00,0x32,0x40,0x4c,0x90,0x0b,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfdf0, 0, {0xa0,0x1d,0xf0,0x00,0xfc,0x00,0x3f,0x00,0x07,0xc0,0x03,0xf4,0x1c,0xf4,0x00,0x3f }, - 16, 0xfe00, 0, {0x00,0x1f,0xc0,0x23,0xb0,0x02,0x9d,0x01,0x3f,0x40,0x8f,0xc0,0x07,0xfc,0x02,0xff }, - 16, 0xfe10, 0, {0x00,0x7b,0x00,0x0f,0xc0,0x03,0xf0,0x00,0xfd,0x00,0x3f,0x40,0x0f,0x70,0x03,0xe8 }, - 16, 0xfe20, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfa,0x00,0xcb,0x80,0x3f,0x24 }, - 16, 0xfe30, 0, {0x0a,0xc1,0x03,0xfc,0x24,0xcd,0x20,0x37,0x0a,0x0c,0xc2,0x83,0x30,0x80,0xdc,0x02 }, - 16, 0xfe40, 0, {0x3f,0xcc,0x0d,0xd9,0x03,0x3c,0x58,0xdf,0x30,0x33,0xc8,0x0d,0xf4,0x23,0x3c,0x40 }, - 16, 0xfe50, 0, {0xff,0x00,0x3f,0xc5,0x4f,0xf0,0x23,0xb0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfe60, 0, {0x80,0x00,0xec,0x02,0x0b,0x82,0x2e,0x08,0x0d,0xb7,0x02,0xfd,0x00,0x83,0x18,0x0a }, - 16, 0xfe70, 0, {0x58,0x0a,0x84,0xa2,0xa5,0xa0,0x89,0x30,0x22,0x55,0x08,0x12,0x62,0xbd,0x90,0x8f }, - 16, 0xfe80, 0, {0x62,0x21,0xd6,0x48,0xf3,0x02,0x3c,0xc5,0xbf,0x48,0x2f,0xd8,0x4b,0xb7,0x02,0xe0 }, - 16, 0xfe90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xec,0x00,0x83,0x00,0x2e,0x89 }, - 16, 0xfea0, 0, {0x28,0x00,0x02,0xec,0xa0,0x89,0x22,0x28,0x82,0x08,0x12,0x02,0x28,0x40,0x9a,0x08 }, - 16, 0xfeb0, 0, {0x28,0xc8,0x88,0xb2,0x0a,0x0d,0x10,0x93,0x10,0xa0,0xc8,0x28,0x30,0x02,0x4c,0x00 }, - 16, 0xfec0, 0, {0xb3,0x60,0x2c,0xc4,0x0b,0x30,0xc2,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfed0, 0, {0xc0,0x15,0xac,0x40,0x8b,0x00,0x2e,0x80,0x08,0xb1,0x02,0xec,0x02,0x8b,0x00,0x20 }, - 16, 0xfee0, 0, {0xd0,0x0a,0x90,0x02,0xac,0x00,0x0b,0x01,0x26,0x40,0x08,0x94,0x02,0x8c,0x00,0x8b }, - 16, 0xfef0, 0, {0x00,0x22,0xc0,0x08,0xb0,0x02,0x2c,0x10,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0xf0 }, - 16, 0xff00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x8c,0x20,0xcb,0x02,0x3e,0x2d }, - 16, 0xff10, 0, {0x08,0x80,0x03,0xec,0x08,0xc9,0x80,0x1e,0x04,0x0c,0xb0,0x03,0x01,0x08,0x50,0x18 }, - 16, 0xff20, 0, {0x3e,0x40,0x0c,0x04,0x03,0x2c,0x00,0xdb,0x01,0x32,0xc0,0x0c,0xb0,0x0b,0x2c,0x08 }, - 16, 0xff30, 0, {0xbb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x80,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xff40, 0, {0xe1,0x00,0xbc,0x00,0xff,0x00,0x3f,0x60,0x0f,0xc0,0x23,0xec,0x00,0xff,0xc0,0xbe }, - 16, 0xff50, 0, {0x60,0x8f,0xc9,0x23,0xf6,0x50,0xed,0x80,0xb8,0x50,0xaf,0xc0,0x03,0xfc,0x00,0xff }, - 16, 0xff60, 0, {0x00,0x3f,0xc1,0x0e,0xb0,0x03,0xfc,0x04,0xff,0x02,0x3f,0xc0,0x0f,0xf0,0x03,0xf8 }, - 16, 0xff70, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xeb,0x00,0x32,0x80 }, - 16, 0xff80, 0, {0x0d,0x90,0x03,0x2c,0x00,0x89,0x00,0x3e,0x98,0x8c,0x30,0x03,0x61,0x80,0xfa,0x40 }, - 16, 0xff90, 0, {0x3e,0x40,0x2c,0xa5,0x03,0x2c,0x00,0xfb,0x01,0x3c,0xc0,0x2c,0x30,0x03,0x2c,0x00 }, - 16, 0xffa0, 0, {0xdb,0x02,0x32,0xc0,0x0f,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xffb0, 0, {0xca,0x00,0x2e,0x80,0x8b,0x82,0xa0,0xc0,0x8c,0x90,0x02,0x3c,0x00,0x8b,0xf0,0x22 }, - 16, 0xffc0, 0, {0xc2,0x0d,0x80,0x02,0x27,0x00,0x8b,0x10,0x22,0x40,0x08,0x80,0x22,0x3c,0x00,0xbf }, - 16, 0xffd0, 0, {0x00,0x2f,0xc0,0x08,0xf0,0x02,0x3c,0x00,0xbf,0x01,0xa3,0xc0,0x0b,0xf0,0x12,0xf2 }, - 16, 0xffe0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x1c,0x20,0x40 }, - 16, 0xfff0, 0, {0x08,0x00,0x06,0x2c,0x00,0x9b,0x00,0x20,0xd0,0x08,0x20,0x02,0x4c,0x00,0xa3,0x00 }, - 16, 0x8010, 0, {0x2c,0xc0,0x08,0x10,0x0a,0x0c,0x00,0xbb,0x00,0x28,0xc0,0x09,0x30,0x02,0x0c,0x00 }, - 16, 0x8020, 0, {0xb3,0x00,0x20,0xc0,0x0b,0x30,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8030, 0, {0x22,0x11,0x1e,0x00,0x97,0xa0,0x21,0xa0,0x08,0x79,0x02,0x1e,0x00,0x97,0x90,0x21 }, - 16, 0x8040, 0, {0x60,0x09,0xe8,0x22,0x3e,0x00,0xaf,0x84,0x21,0xe4,0x48,0x5c,0x02,0x1e,0x00,0xb7 }, - 16, 0x8050, 0, {0x90,0x2d,0xe0,0x09,0x78,0x00,0x1e,0x09,0xb3,0x90,0x21,0xe4,0x0b,0x78,0x02,0xd8 }, - 16, 0x8060, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x18,0x2c,0x40,0xb3,0xb0,0x32,0x40 }, - 16, 0x8070, 0, {0x2c,0x81,0x13,0x0c,0x42,0xd1,0x00,0xb0,0xc0,0x8c,0x30,0x03,0x48,0x20,0xe3,0x01 }, - 16, 0x8080, 0, {0x3c,0xc0,0x0c,0x30,0x03,0x0c,0x00,0xf3,0x10,0x3c,0xc0,0xcd,0x32,0x0b,0x0c,0x40 }, - 16, 0x8090, 0, {0xd3,0x00,0x30,0xc0,0x0f,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x80a0, 0, {0x40,0x15,0xbc,0x00,0xe7,0x00,0x3f,0x80,0x0b,0xf1,0x03,0xfd,0x00,0x6d,0x00,0x32 }, - 16, 0x80b0, 0, {0x40,0x1f,0x70,0x07,0xd8,0x41,0xc3,0x10,0x3b,0xc0,0x0f,0xd1,0x03,0xfd,0x00,0xff }, - 16, 0x80c0, 0, {0x10,0x3f,0xc0,0x0e,0xf0,0x03,0xec,0x10,0xff,0x08,0x3f,0xc3,0x0f,0xf0,0x03,0xd0 }, - 16, 0x80d0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xec,0x04,0xfb,0x02,0x3e,0x40 }, - 16, 0x80e0, 0, {0x0b,0xa0,0x03,0xac,0x00,0xdb,0x00,0x36,0x80,0x0d,0xb0,0x03,0xac,0x00,0xe8,0x00 }, - 16, 0x80f0, 0, {0x36,0xc1,0x2e,0x90,0x03,0x2c,0x00,0xcb,0xa0,0x36,0xdc,0x0f,0xb0,0x03,0x2d,0x68 }, - 16, 0x8100, 0, {0xfb,0xa0,0x92,0xc2,0x0c,0xb1,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8110, 0, {0x48,0x11,0x9c,0x08,0x37,0x00,0x2d,0xc0,0x0b,0xe0,0x02,0x1d,0x80,0xb7,0x04,0x23 }, - 16, 0x8120, 0, {0x00,0x0a,0x40,0x02,0x1c,0x18,0x84,0x00,0x25,0xc0,0x18,0x50,0x32,0x0d,0x80,0xa3 }, - 16, 0x8130, 0, {0x30,0x21,0xcc,0x0b,0x34,0x82,0x1c,0x10,0xb7,0x30,0x21,0xc8,0x08,0x70,0x02,0xd2 }, - 16, 0x8140, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x20,0xb7,0x80,0x2d,0x60 }, - 16, 0x8150, 0, {0x0b,0xfc,0x22,0x9e,0x00,0x8d,0x80,0x25,0xa0,0x08,0xf8,0x22,0x92,0x00,0xb4,0x80 }, - 16, 0x8160, 0, {0x25,0xe0,0x08,0xf8,0x02,0x1e,0x00,0x87,0xb0,0x21,0xe0,0x09,0x7a,0x02,0x1e,0x18 }, - 16, 0x8170, 0, {0xb3,0x80,0x21,0xe0,0x08,0x78,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8180, 0, {0x48,0x04,0xc5,0x20,0xb3,0x01,0x2c,0xd8,0x0b,0x3c,0x02,0x2c,0x08,0xb9,0x00,0x20 }, - 16, 0x8190, 0, {0x03,0x0a,0x00,0x82,0x22,0x08,0x90,0x0d,0x26,0xe4,0x08,0x10,0x02,0x0c,0x00,0xa3 }, - 16, 0x81a0, 0, {0x00,0x22,0xc0,0x0b,0x30,0x02,0x6c,0x00,0xb3,0x00,0x22,0xc0,0x28,0x30,0x02,0xc2 }, - 16, 0x81b0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x99,0x00,0xfa,0x02,0x3f,0x90 }, - 16, 0x81c0, 0, {0x0f,0xec,0x23,0xa8,0x00,0xda,0x00,0x35,0x80,0x0d,0xe0,0x02,0xba,0x02,0xfe,0xc2 }, - 16, 0x81d0, 0, {0xb6,0xa0,0x0e,0xe4,0x0b,0x28,0x00,0xca,0x00,0xb2,0x80,0x0f,0xa0,0x0b,0x28,0x00 }, - 16, 0x81e0, 0, {0xfa,0x00,0x32,0x80,0x0c,0xa0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x81f0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x82,0x03,0xe0,0x00,0xf8,0x00,0x3e }, - 16, 0x8200, 0, {0x00,0x0f,0x81,0x03,0xe0,0x40,0xe8,0x10,0x3a,0x00,0x4f,0x84,0x83,0xe0,0x00,0xf8 }, - 16, 0x8210, 0, {0x00,0x3a,0x00,0x0f,0x00,0x03,0xa0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0x8220, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe5,0x00,0xc9,0x02,0x3e,0x40 }, - 16, 0x8230, 0, {0x0f,0x90,0x23,0x24,0x00,0xc9,0x00,0x32,0x68,0x2f,0x10,0x03,0x24,0x00,0xe9,0x14 }, - 16, 0x8240, 0, {0x32,0x40,0x0d,0x90,0x0b,0x04,0x00,0xd9,0x00,0x1e,0x40,0x0c,0x90,0x03,0x24,0x00 }, - 16, 0x8250, 0, {0xc9,0x00,0x36,0x40,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8260, 0, {0x80,0x14,0x64,0x00,0x89,0x01,0x2e,0x40,0x4b,0x90,0x12,0x24,0x00,0x89,0xc2,0xa2 }, - 16, 0x8270, 0, {0x60,0x88,0x90,0x03,0x64,0x00,0x89,0xc1,0xa2,0x40,0x48,0x16,0x03,0x64,0x02,0x89 }, - 16, 0x8280, 0, {0x00,0x2e,0x40,0x08,0x90,0x22,0x24,0x00,0x89,0x00,0x3e,0x40,0x28,0x90,0x0a,0x20 }, - 16, 0x8290, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x04,0x24,0x00,0x89,0x02,0x2e,0x40 }, - 16, 0x82a0, 0, {0x0b,0x10,0x02,0x24,0x00,0x89,0x10,0x22,0x40,0x89,0x90,0x02,0xac,0x00,0xa1,0x08 }, - 16, 0x82b0, 0, {0x22,0x40,0x09,0x98,0x02,0xa4,0x00,0x89,0x00,0x2a,0x40,0x08,0x90,0x02,0x24,0x00 }, - 16, 0x82c0, 0, {0x89,0x00,0x26,0x40,0x08,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x82d0, 0, {0x08,0x00,0x24,0x00,0x81,0x00,0x2c,0x41,0x0b,0x12,0x02,0x04,0x81,0x81,0x20,0x22 }, - 16, 0x82e0, 0, {0x48,0x08,0x12,0x02,0xc4,0x81,0x81,0x24,0x02,0x48,0x0a,0x90,0x02,0x84,0xa0,0x81 }, - 16, 0x82f0, 0, {0x28,0x6c,0x4a,0x08,0x12,0xd2,0x04,0xa1,0x81,0x28,0x2c,0x4a,0x08,0x12,0x82,0x02 }, - 16, 0x8300, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x08,0x61,0x40,0xc8,0x00,0x2e,0x14 }, - 16, 0x8310, 0, {0x0f,0x85,0x0b,0x21,0x42,0xca,0x50,0x22,0x14,0x0d,0x85,0x43,0xa1,0x40,0xe8,0x50 }, - 16, 0x8320, 0, {0x30,0x00,0x0d,0x85,0x02,0xa1,0xc0,0xd8,0x20,0x3a,0x08,0x2c,0x82,0x0b,0x20,0x82 }, - 16, 0x8330, 0, {0xc8,0x20,0x34,0x09,0x8c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8340, 0, {0x98,0x0d,0xfc,0x02,0xf9,0x00,0x3f,0x40,0x4f,0xd1,0x03,0xe4,0x40,0xf5,0x14,0xbf }, - 16, 0x8350, 0, {0x44,0x0d,0x51,0x23,0x5c,0x40,0xf5,0x10,0x1f,0x4e,0x4d,0x50,0x03,0x64,0x08,0xf9 }, - 16, 0x8360, 0, {0x28,0x3e,0x4a,0x8f,0x92,0x83,0xe4,0xa0,0xf9,0x28,0x3a,0x4b,0x0f,0x92,0x83,0xe6 }, - 16, 0x8370, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xf4,0x40,0xfd,0x00,0x30,0x40 }, - 16, 0x8380, 0, {0x0c,0x90,0x03,0x24,0x00,0xdd,0x00,0x3b,0x40,0x0e,0x90,0x03,0x74,0x00,0x5d,0x00 }, - 16, 0x8390, 0, {0x36,0x64,0x0d,0xd0,0x00,0xa6,0x00,0xf9,0x40,0x32,0x78,0x0c,0x99,0x03,0x24,0x40 }, - 16, 0x83a0, 0, {0xc9,0x90,0x32,0x50,0x0f,0x9b,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x83b0, 0, {0x38,0x10,0xe2,0x80,0xb8,0x00,0x22,0x01,0x08,0x80,0x0a,0x20,0x00,0x88,0x00,0x2a }, - 16, 0x83c0, 0, {0x00,0x08,0x80,0x02,0x20,0x00,0x88,0x00,0x22,0x20,0x08,0x8a,0x8b,0xe1,0x00,0xb8 }, - 16, 0x83d0, 0, {0x80,0x22,0x30,0x28,0x0d,0x02,0x22,0x00,0xd8,0xe4,0x22,0x28,0x0b,0x8f,0x0a,0x0e }, - 16, 0x83e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0xb1,0x00,0xa0,0x40 }, - 16, 0x83f0, 0, {0x08,0x10,0x02,0x04,0x00,0x89,0x00,0x08,0x40,0x0a,0x90,0x42,0x44,0x00,0x91,0x00 }, - 16, 0x8400, 0, {0x20,0x58,0x28,0x90,0x02,0x85,0x00,0x81,0x20,0xa0,0x4c,0x09,0x12,0x0a,0x04,0x80 }, - 16, 0x8410, 0, {0x91,0x40,0xa0,0x40,0x0b,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8420, 0, {0x18,0x15,0xa4,0x00,0xb9,0x02,0x20,0x40,0x08,0x90,0x02,0x04,0x00,0x89,0x01,0x22 }, - 16, 0x8430, 0, {0x40,0x28,0x90,0x22,0x04,0x00,0x89,0x10,0x22,0x40,0x08,0x90,0x02,0xe4,0x00,0xb1 }, - 16, 0x8440, 0, {0x00,0x22,0x40,0x81,0x90,0x02,0x04,0x00,0x91,0x00,0x22,0x40,0x0b,0x90,0x02,0x06 }, - 16, 0x8450, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe5,0x00,0xf1,0x00,0x32,0x60 }, - 16, 0x8460, 0, {0x2c,0x92,0x13,0x24,0x02,0xd1,0x10,0x3a,0x40,0x0e,0x12,0x03,0x66,0x04,0xd9,0x00 }, - 16, 0x8470, 0, {0xb6,0x40,0x0d,0x19,0x03,0xa4,0x00,0xf9,0x00,0x32,0x40,0x09,0x90,0x01,0x24,0x00 }, - 16, 0x8480, 0, {0xd9,0x02,0x22,0x40,0x0f,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8490, 0, {0x2a,0x01,0xa5,0x00,0xf9,0x00,0x3e,0x64,0x0f,0x10,0x03,0xe4,0x00,0xf9,0x81,0x3e }, - 16, 0x84a0, 0, {0x66,0x8f,0x90,0x23,0xe4,0x80,0xf9,0x04,0x3e,0x40,0x8f,0x90,0x03,0xe4,0x04,0xf9 }, - 16, 0x84b0, 0, {0x00,0x3c,0x40,0x0e,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x10,0x03,0xca }, - 16, 0x84c0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x10,0xa0,0x00,0xf8,0x24,0x3e,0x00 }, - 16, 0x84d0, 0, {0x2c,0x84,0x03,0x20,0x00,0xb8,0x20,0x3e,0x00,0x8c,0x80,0x03,0xa0,0x00,0x70,0x82 }, - 16, 0x84e0, 0, {0x32,0x00,0x0f,0x80,0x03,0x20,0x08,0xf8,0x00,0x32,0x00,0x2c,0x80,0x0b,0x20,0x08 }, - 16, 0x84f0, 0, {0xc8,0x00,0x3e,0x00,0x0c,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8500, 0, {0x28,0x05,0x28,0x04,0xbe,0x80,0x3a,0x80,0x08,0xa0,0x02,0x28,0x04,0x8e,0x00,0x6d }, - 16, 0x8510, 0, {0x90,0x0d,0xa0,0x02,0x3a,0x00,0x8e,0x80,0xa2,0x80,0x0e,0xe0,0x0b,0x68,0x00,0xba }, - 16, 0x8520, 0, {0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0xda,0x00,0x2e,0x80,0x08,0xa0,0x02,0xca }, - 16, 0x8530, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x81,0x4c,0x00,0xb1,0x00,0x2c,0xc0 }, - 16, 0x8540, 0, {0x08,0x30,0x02,0x0c,0x18,0xa3,0x02,0x2c,0x10,0x88,0x30,0x06,0x82,0x81,0xa0,0x00 }, - 16, 0x8550, 0, {0x2a,0xc0,0x0b,0x30,0x0a,0x4c,0x00,0xb3,0x00,0x20,0xc0,0x1a,0xb0,0x02,0x8c,0x01 }, - 16, 0x8560, 0, {0x83,0x00,0x2c,0xc0,0x08,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8570, 0, {0x20,0x01,0x1c,0x10,0xb4,0x0a,0x2b,0xc8,0x08,0x31,0x26,0x1c,0x00,0x86,0x00,0x2d }, - 16, 0x8580, 0, {0xc0,0x09,0x72,0x02,0x1d,0x00,0xa5,0x40,0x29,0xc0,0x0a,0x60,0x02,0x5c,0x88,0xb3 }, - 16, 0x8590, 0, {0x20,0x25,0xc8,0x0a,0x72,0x02,0x9c,0x80,0x97,0x20,0x2c,0xe8,0x80,0x72,0x02,0xe8 }, - 16, 0x85a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x16,0x00,0xb5,0x80,0x3d,0xe2 }, - 16, 0x85b0, 0, {0x0c,0x7a,0x8b,0x0e,0xc0,0xa7,0x81,0x2c,0x20,0x0c,0xfc,0x03,0x92,0x02,0xef,0x80 }, - 16, 0x85c0, 0, {0x39,0xe4,0x0b,0xd8,0x01,0x1f,0x00,0xf7,0x80,0xb3,0xf4,0x8e,0x79,0x03,0x8e,0x00 }, - 16, 0x85d0, 0, {0xc7,0xc4,0x3d,0xe8,0x2c,0x7b,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x85e0, 0, {0x08,0x1d,0xac,0x00,0xf8,0x00,0x3e,0xdd,0x87,0xb6,0x03,0xed,0xcc,0xe9,0x00,0x3e }, - 16, 0x85f0, 0, {0x40,0x0f,0xb0,0x07,0xcc,0x10,0x0b,0x00,0x36,0xd8,0x0f,0x80,0x43,0xad,0x80,0xfb }, - 16, 0x8600, 0, {0x28,0x3a,0xc0,0x0d,0xb4,0x03,0x6c,0xe2,0xeb,0x60,0x3e,0xd4,0x0f,0xb0,0x03,0xc2 }, - 16, 0x8610, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xfe,0x90,0x3f,0xe5 }, - 16, 0x8620, 0, {0x0e,0xf8,0x03,0x3e,0x10,0xff,0x90,0x17,0x60,0x0f,0xfc,0x03,0x7a,0x00,0xee,0x80 }, - 16, 0x8630, 0, {0x37,0xe2,0x0e,0x78,0x0f,0xff,0x40,0xef,0x88,0x1f,0xe0,0x0c,0xf8,0x83,0xfe,0x80 }, - 16, 0x8640, 0, {0xcf,0xd0,0xb3,0xf0,0x0c,0xf8,0xc3,0x10,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8650, 0, {0xa8,0x11,0x9c,0x40,0xb4,0x10,0x0f,0xcc,0x00,0x72,0x02,0x1c,0x00,0xb6,0x02,0x09 }, - 16, 0x8660, 0, {0xc0,0x28,0xf0,0x02,0x98,0x00,0xa6,0x00,0x21,0xc0,0x0b,0x60,0x03,0xfc,0x02,0x87 }, - 16, 0x8670, 0, {0x00,0x2d,0xc0,0x08,0x70,0x02,0xde,0x00,0x8f,0x10,0x21,0xc0,0x08,0xf0,0x03,0x6a }, - 16, 0x8680, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x94,0x00,0xb6,0x02,0x2f,0xc2 }, - 16, 0x8690, 0, {0x1a,0x30,0x80,0x1c,0x00,0xb6,0x08,0x01,0x40,0x0a,0xf0,0x02,0x18,0x00,0x87,0x00 }, - 16, 0x86a0, 0, {0x21,0xc0,0x0b,0xd0,0x02,0x9c,0x10,0x87,0x00,0x29,0xc0,0x08,0x70,0x02,0xdc,0x44 }, - 16, 0x86b0, 0, {0x87,0x10,0x64,0xc0,0x08,0x70,0x02,0x06,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x86c0, 0, {0x60,0x14,0xce,0x60,0xb0,0x00,0x2c,0xc0,0x08,0x34,0x0a,0x0c,0x08,0xb0,0x04,0x00 }, - 16, 0x86d0, 0, {0x40,0x08,0x30,0xa2,0x89,0x80,0xa2,0x62,0x20,0xe0,0x0b,0x00,0x0a,0xcc,0x08,0x83 }, - 16, 0x86e0, 0, {0x00,0x6c,0xc0,0x08,0x30,0x52,0xcc,0x00,0x83,0x00,0x24,0xc0,0x08,0x30,0x02,0x58 }, - 16, 0x86f0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xae,0x00,0xf8,0x00,0x3f,0xd0 }, - 16, 0x8700, 0, {0x0e,0xfc,0x03,0x3c,0x00,0xf9,0x00,0x92,0x84,0x0f,0xfc,0x03,0x64,0x00,0x80,0x00 }, - 16, 0x8710, 0, {0xb7,0xc3,0x0f,0xb8,0x83,0xbc,0x04,0xef,0x00,0x3f,0xc0,0x3c,0xf0,0x03,0xfc,0x02 }, - 16, 0x8720, 0, {0xcf,0x00,0x37,0xc0,0x28,0xf0,0x13,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8730, 0, {0x80,0x00,0xec,0x00,0xf8,0x41,0x3e,0xc8,0x0f,0x32,0x03,0xec,0x00,0xf8,0x00,0x3a }, - 16, 0x8740, 0, {0xc4,0x0f,0xb1,0x03,0xc4,0x00,0xf9,0x00,0x36,0xc0,0x0f,0xe4,0x0b,0xec,0x04,0xfb }, - 16, 0x8750, 0, {0x00,0x3e,0xc1,0x0f,0xb0,0x43,0xec,0x04,0xfb,0x00,0x3a,0xc0,0x0f,0xb0,0x03,0xe4 }, - 16, 0x8760, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf4,0x00,0xfc,0x80,0x3f,0xc0 }, - 16, 0x8770, 0, {0x1f,0xf0,0x03,0x3c,0x08,0xfb,0x00,0x33,0x80,0x2e,0xf0,0x13,0xa4,0x04,0xcb,0x00 }, - 16, 0x8780, 0, {0xb9,0xc0,0x2c,0xd8,0x0b,0x3c,0x00,0xff,0x00,0x3f,0xc0,0x09,0x70,0x00,0x2c,0x04 }, - 16, 0x8790, 0, {0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xc0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x87a0, 0, {0xc1,0x00,0x6c,0x00,0xb8,0x80,0x2e,0xc0,0x0b,0xb0,0x03,0x6c,0x00,0xb9,0x16,0x28 }, - 16, 0x87b0, 0, {0x72,0x08,0xb0,0x22,0x27,0x40,0xdb,0x00,0x22,0xc0,0x08,0xbd,0x82,0x2c,0x08,0xbb }, - 16, 0x87c0, 0, {0x00,0x2e,0xc0,0x48,0xb0,0x02,0x2c,0x00,0xbb,0x00,0x2e,0xc1,0x0b,0xb0,0x02,0xe0 }, - 16, 0x87d0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xb8,0x60,0x2e,0xc0 }, - 16, 0x87e0, 0, {0x0b,0xb0,0x02,0x2c,0x00,0xb1,0x00,0x2a,0x84,0x4a,0x30,0x22,0xac,0x20,0x98,0x80 }, - 16, 0x87f0, 0, {0x2a,0xc0,0x08,0x30,0x02,0xac,0x00,0x3b,0x00,0x2c,0xc0,0x0a,0xb0,0x02,0xac,0x08 }, - 16, 0x8800, 0, {0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x42,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8810, 0, {0x08,0x04,0x0c,0x01,0xb0,0x00,0x2c,0xc0,0x0b,0x30,0x02,0x4c,0x04,0xb0,0x00,0x2a }, - 16, 0x8820, 0, {0x80,0x08,0x30,0x02,0x00,0x00,0x10,0x04,0x28,0xc0,0x08,0x20,0x42,0x8c,0x00,0xb3 }, - 16, 0x8830, 0, {0x00,0x2c,0xc0,0x42,0x30,0x0a,0x8c,0x00,0xb3,0x00,0x2c,0xc0,0x8b,0x30,0x02,0xc2 }, - 16, 0x8840, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xf8,0x50,0x3f,0xc0 }, - 16, 0x8850, 0, {0x0b,0xf0,0x03,0x3c,0x00,0xfa,0x04,0x32,0x80,0x0e,0xf0,0x23,0xac,0x00,0xd9,0x00 }, - 16, 0x8860, 0, {0x3b,0xc0,0x0c,0x90,0x03,0xbc,0x04,0xff,0x00,0x3d,0xc0,0x2e,0xf0,0x0b,0x3c,0x00 }, - 16, 0x8870, 0, {0xff,0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8880, 0, {0xa0,0x1d,0xfc,0x00,0xfc,0x00,0x3f,0xc0,0x07,0xf0,0x03,0xfc,0x04,0x7c,0x02,0xb5 }, - 16, 0x8890, 0, {0x00,0x0f,0xf0,0x03,0xf0,0x00,0xfc,0x00,0x37,0xc0,0x0f,0xf0,0x13,0x7c,0x00,0xff }, - 16, 0x88a0, 0, {0x00,0x3f,0xc0,0x0d,0xf0,0x03,0x6d,0x00,0xff,0x00,0x3f,0xc0,0x1f,0xf0,0x03,0xe8 }, - 16, 0x88b0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd2,0x00,0xd5,0x80,0x33,0x0a }, - 16, 0x88c0, 0, {0x4c,0xf8,0x03,0xf2,0x00,0xfc,0x00,0x37,0x26,0x1f,0xca,0x03,0xbc,0xc4,0xcf,0x20 }, - 16, 0x88d0, 0, {0x33,0xe4,0x0f,0x78,0x03,0x3e,0x44,0xcf,0x00,0x3b,0xce,0x9f,0x68,0x13,0xd0,0x00 }, - 16, 0x88e0, 0, {0xcd,0x80,0xb3,0x60,0x0f,0xfa,0x83,0xf0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x88f0, 0, {0x80,0x10,0xe0,0x80,0xc9,0x28,0x22,0x30,0x08,0xb2,0x22,0xea,0x01,0xb8,0x82,0x20 }, - 16, 0x8900, 0, {0x50,0x4f,0x9c,0x00,0xa8,0xd1,0xdb,0x10,0xa6,0xe0,0x17,0xb8,0x03,0xec,0x80,0xdb }, - 16, 0x8910, 0, {0x08,0x1f,0xd0,0x0b,0xb8,0x02,0xf6,0x00,0xfb,0x80,0x22,0x40,0x0b,0xb0,0x02,0x60 }, - 16, 0x8920, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x20,0x81,0x80,0x20,0x00 }, - 16, 0x8930, 0, {0x8b,0x30,0x82,0xc0,0x00,0xb0,0x10,0x28,0x08,0x8b,0x11,0x30,0xc4,0x84,0x90,0x28 }, - 16, 0x8940, 0, {0x24,0xc8,0x0b,0x30,0x02,0x4c,0x00,0x83,0x10,0x04,0xc8,0x0b,0x30,0x02,0xcc,0x00 }, - 16, 0x8950, 0, {0xb3,0x00,0x24,0x40,0x0b,0x30,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8960, 0, {0xc0,0x15,0xa6,0x00,0x81,0x00,0x22,0x10,0x0b,0xb0,0x12,0xea,0x20,0xbb,0x00,0x2a }, - 16, 0x8970, 0, {0x70,0x0a,0x9c,0x02,0x62,0x00,0x98,0x88,0x26,0xc8,0x02,0xb2,0x02,0x8e,0x08,0x8b }, - 16, 0x8980, 0, {0x18,0x22,0xc0,0x0b,0xa0,0x02,0xee,0x20,0x3b,0x00,0x26,0x40,0x0b,0xb0,0x02,0x70 }, - 16, 0x8990, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe0,0x00,0xcb,0x00,0x32,0x80 }, - 16, 0x89a0, 0, {0x0f,0xb0,0x03,0xe7,0x00,0xb8,0x52,0x3e,0x20,0x4b,0x0c,0x43,0xef,0x82,0x9b,0xc0 }, - 16, 0x89b0, 0, {0x32,0xc0,0x0b,0xb0,0x02,0x6c,0x01,0x8b,0x80,0x2e,0xc0,0x0b,0xa0,0x83,0xe6,0x00 }, - 16, 0x89c0, 0, {0xfb,0x00,0x36,0x40,0x0f,0xf0,0x03,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x89d0, 0, {0xe0,0x01,0xb0,0x02,0xff,0x04,0x3f,0x90,0x0c,0xf1,0x01,0xf4,0x08,0x7d,0x80,0x37 }, - 16, 0x89e0, 0, {0x00,0x0f,0xc0,0x23,0x98,0x00,0xf7,0x00,0x2b,0xe0,0x0f,0xf8,0x23,0xfc,0x06,0xfb }, - 16, 0x89f0, 0, {0x83,0xbf,0xc0,0x87,0xd0,0x03,0xdc,0x00,0xef,0x00,0x3b,0xc0,0x0f,0xb0,0x01,0xf8 }, - 16, 0x8a00, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa6,0x00,0xcb,0x00,0x33,0x80 }, - 16, 0x8a10, 0, {0x0f,0xb0,0x03,0xe1,0x10,0xf2,0x40,0xb2,0x00,0x3d,0x94,0x17,0x2d,0x44,0xfa,0x41 }, - 16, 0x8a20, 0, {0x32,0xc0,0x9f,0xb0,0x23,0x2c,0x02,0xcb,0x40,0x32,0xc0,0x4f,0x90,0x03,0x3d,0x00 }, - 16, 0x8a30, 0, {0xcb,0x00,0x3e,0x40,0x0f,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8a40, 0, {0x88,0x05,0x26,0x00,0x8b,0x71,0x20,0xd5,0x03,0x99,0x02,0xe0,0x00,0xbb,0x80,0x22 }, - 16, 0x8a50, 0, {0x60,0x1c,0x80,0x03,0x60,0x00,0xb8,0x02,0x22,0xc2,0x0b,0x32,0x02,0x2c,0x01,0x8f }, - 16, 0x8a60, 0, {0x02,0xd7,0xc0,0x0b,0xa0,0x03,0x6d,0x40,0x53,0x80,0x2e,0xc0,0x0e,0xf0,0x43,0x72 }, - 16, 0x8a70, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x68,0x02,0x80,0x00,0x24,0x00 }, - 16, 0x8a80, 0, {0x0b,0x35,0x26,0xc2,0x00,0xb0,0x90,0x20,0xc0,0x88,0x00,0x02,0x4f,0x20,0xb3,0x02 }, - 16, 0x8a90, 0, {0x60,0xe2,0x1b,0x38,0x02,0x0c,0x00,0x88,0x00,0x60,0xc0,0x0b,0x34,0x82,0x4c,0x02 }, - 16, 0x8aa0, 0, {0xa1,0x90,0x2c,0x40,0x0b,0x30,0x02,0x30,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ab0, 0, {0x20,0x01,0x3a,0x08,0x8c,0xa0,0x2d,0x20,0x4b,0x78,0x02,0xda,0x00,0xb2,0x90,0x21 }, - 16, 0x8ac0, 0, {0x66,0x48,0x79,0x02,0xde,0x40,0xb7,0x91,0xa1,0xe0,0xdb,0xf8,0x02,0x1e,0x40,0x84 }, - 16, 0x8ad0, 0, {0x90,0x01,0xe0,0x8b,0xf9,0x02,0x5e,0x01,0x97,0x80,0x2d,0x60,0x0a,0x78,0x00,0x48 }, - 16, 0x8ae0, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x80,0x00,0x24,0x04 }, - 16, 0x8af0, 0, {0x0f,0x32,0x03,0xc4,0xa0,0xf1,0x42,0x30,0xc4,0x2c,0x31,0x02,0x44,0x00,0xf1,0x11 }, - 16, 0x8b00, 0, {0xa0,0xc0,0x0b,0x30,0x0b,0x0c,0x42,0x83,0x00,0x00,0xc0,0x0f,0x30,0x03,0x4c,0x02 }, - 16, 0x8b10, 0, {0xe3,0x00,0x3c,0x40,0x0b,0x30,0x01,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8b20, 0, {0xc0,0x1d,0xbc,0x00,0xfc,0xa5,0x33,0xc0,0x0f,0xd0,0x03,0xfc,0x01,0xbf,0x00,0x3f }, - 16, 0x8b30, 0, {0xc4,0x0e,0x71,0x03,0x74,0x00,0x75,0x10,0x3f,0xc0,0x05,0xf0,0x03,0xdc,0x40,0xff }, - 16, 0x8b40, 0, {0x04,0x3f,0xc0,0x0f,0xf0,0x43,0xfc,0x00,0x7f,0x00,0x3f,0x40,0x0e,0xf0,0x03,0xd0 }, - 16, 0x8b50, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x04,0xe8,0x00,0xf2,0x04,0xb3,0x80 }, - 16, 0x8b60, 0, {0x0f,0xb8,0x0b,0x2c,0x00,0xeb,0x80,0x32,0xc0,0x0c,0x20,0x13,0x2e,0x08,0xcb,0x01 }, - 16, 0x8b70, 0, {0x32,0xc5,0x0f,0xb1,0x03,0xec,0x48,0xc8,0x10,0x32,0xfa,0x8c,0x38,0x03,0x3c,0x90 }, - 16, 0x8b80, 0, {0xcb,0x00,0x3e,0x40,0x0f,0xb0,0x13,0xc2,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8b90, 0, {0xc8,0x10,0x98,0x00,0xf6,0x00,0x61,0x81,0x0b,0xf0,0x02,0x1c,0x00,0xd7,0x00,0xb7 }, - 16, 0x8ba0, 0, {0x80,0x0c,0x70,0x02,0xbc,0x10,0x8f,0x00,0x21,0xc8,0x8b,0x72,0x43,0xfc,0x88,0xdc }, - 16, 0x8bb0, 0, {0x00,0x37,0xc8,0x0d,0x50,0x02,0x1c,0x22,0x87,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xd3 }, - 16, 0x8bc0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x00,0xb6,0x80,0xa9,0xa0 }, - 16, 0x8bd0, 0, {0x4b,0x7c,0x02,0x5e,0x30,0xa3,0x88,0x21,0xf0,0x08,0x78,0x02,0x16,0x00,0x85,0x80 }, - 16, 0x8be0, 0, {0x21,0xe0,0x0b,0x78,0x02,0xde,0x00,0x87,0x80,0xa1,0xe4,0x08,0xd8,0x02,0x4e,0x00 }, - 16, 0x8bf0, 0, {0x97,0x80,0x2d,0x70,0x0b,0x78,0x02,0xc8,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8c00, 0, {0x48,0x14,0xec,0x00,0xb2,0x00,0x28,0xc0,0x0b,0x10,0x02,0x4e,0x90,0x93,0x02,0x22 }, - 16, 0x8c10, 0, {0xf0,0x08,0x38,0x42,0x8c,0x42,0x83,0x04,0x22,0xe4,0x4b,0x38,0x02,0x8e,0x40,0x83 }, - 16, 0x8c20, 0, {0x00,0x20,0xc0,0x09,0x38,0x22,0x4e,0x21,0x93,0x00,0x2e,0xe0,0x0b,0x30,0x02,0xdb }, - 16, 0x8c30, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x01,0xfa,0x00,0x3b,0x89 }, - 16, 0x8c40, 0, {0x0f,0xa0,0x02,0x78,0x08,0xae,0x40,0x23,0x80,0x2c,0x6c,0x0b,0x3a,0x00,0x8e,0x8c }, - 16, 0x8c50, 0, {0xb2,0x00,0x0b,0x80,0x82,0xe0,0x02,0x8e,0x00,0x22,0x80,0x0c,0xe8,0x02,0x7b,0x80 }, - 16, 0x8c60, 0, {0x9a,0x80,0x3e,0x80,0x0f,0xa0,0x03,0xfa,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8c70, 0, {0x48,0x00,0xe0,0x09,0xec,0x00,0x36,0x21,0x0b,0x80,0x13,0xa1,0x00,0xf8,0x60,0x3e }, - 16, 0x8c80, 0, {0x00,0x0f,0x81,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x43,0xe0,0x10,0xf8 }, - 16, 0x8c90, 0, {0x00,0xbe,0x00,0x0f,0x85,0x0b,0x80,0x00,0xe8,0x10,0x3e,0x00,0x0f,0x80,0x03,0xd2 }, - 16, 0x8ca0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x02,0x30,0x48 }, - 16, 0x8cb0, 0, {0x0c,0x99,0x13,0xa4,0x02,0xc9,0x00,0x3e,0x42,0x0c,0x90,0x8f,0x24,0x00,0xf9,0x00 }, - 16, 0x8cc0, 0, {0x32,0x28,0x0c,0x88,0x03,0xe0,0x00,0xc9,0x00,0xb2,0x40,0x0f,0x90,0x03,0xe7,0x00 }, - 16, 0x8cd0, 0, {0xc9,0x10,0x3e,0x40,0x0c,0x10,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ce0, 0, {0x80,0x04,0x64,0x01,0x89,0x80,0xa2,0x48,0x28,0x92,0x42,0xc5,0x00,0x89,0x40,0x2e }, - 16, 0x8cf0, 0, {0x40,0x2c,0x90,0x06,0x25,0x00,0xb9,0x00,0x22,0x50,0x08,0x98,0x02,0xc4,0x00,0x89 }, - 16, 0x8d00, 0, {0x01,0x76,0x40,0x4b,0x92,0x02,0xe5,0x02,0x89,0x00,0x2e,0x40,0x0d,0x90,0x03,0x60 }, - 16, 0x8d10, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x0c,0x85,0x20,0xa2,0x40 }, - 16, 0x8d20, 0, {0x08,0x90,0x06,0xe5,0x00,0x89,0x40,0x2e,0x40,0x09,0x90,0x42,0xa4,0xa0,0x31,0x00 }, - 16, 0x8d30, 0, {0x22,0x50,0x18,0x91,0x02,0xe4,0x00,0x81,0x00,0x22,0x40,0x0b,0x90,0x06,0xe4,0x00 }, - 16, 0x8d40, 0, {0x89,0x00,0x2e,0x40,0x09,0x90,0x02,0x0e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8d50, 0, {0x00,0x04,0x15,0x00,0x85,0x40,0x20,0x40,0x08,0x14,0x26,0xe4,0x00,0x81,0x00,0x2c }, - 16, 0x8d60, 0, {0x40,0x18,0x10,0x02,0x84,0x80,0xb1,0x20,0xa0,0x50,0x08,0x14,0x02,0xe5,0x02,0x81 }, - 16, 0x8d70, 0, {0x40,0x20,0x48,0x0b,0x10,0x06,0xcc,0x00,0x81,0x01,0x2c,0x50,0x09,0x14,0x02,0x4a }, - 16, 0x8d80, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0x8c,0x00,0x32,0x00 }, - 16, 0x8d90, 0, {0x0c,0x80,0x23,0xe0,0x00,0xc8,0x00,0x3e,0x14,0x0d,0x80,0x12,0xa1,0x44,0xf8,0x51 }, - 16, 0x8da0, 0, {0x32,0x00,0x2c,0x80,0x03,0xe0,0x00,0x88,0x04,0x22,0x14,0x0f,0x80,0x07,0xe0,0x00 }, - 16, 0x8db0, 0, {0xc8,0x00,0x3e,0x00,0x0d,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8dc0, 0, {0x98,0x9d,0xe4,0x00,0xf9,0x00,0x3f,0x50,0x0f,0xd0,0x03,0xdc,0x01,0xbd,0x42,0x3f }, - 16, 0x8dd0, 0, {0x50,0x4f,0xd4,0x43,0x74,0x41,0xfd,0x10,0x3f,0x10,0x1f,0xc4,0x13,0xf1,0x00,0xfd }, - 16, 0x8de0, 0, {0x40,0x7e,0x44,0x0f,0xd0,0x43,0xf5,0x01,0xfd,0x00,0x3f,0x40,0x0f,0x94,0x03,0xe6 }, - 16, 0x8df0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf4,0x00,0xdf,0x05,0x33,0x61 }, - 16, 0x8e00, 0, {0x0f,0x50,0x53,0x34,0x10,0xfd,0x04,0x33,0x44,0x4f,0x50,0x03,0x76,0xc1,0xcd,0xe0 }, - 16, 0x8e10, 0, {0x33,0x60,0x0c,0xce,0x03,0xf6,0xc0,0xe1,0xc0,0xb6,0x64,0x8f,0x50,0x0b,0x36,0x82 }, - 16, 0x8e20, 0, {0xcd,0x00,0x3e,0x44,0x4c,0x9e,0xc3,0xc6,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8e30, 0, {0x38,0x10,0xea,0x28,0x80,0xa0,0xb2,0x04,0x0b,0x8a,0x83,0x60,0x00,0xfa,0x00,0x36 }, - 16, 0x8e40, 0, {0x28,0x8b,0x80,0x03,0xe3,0xc8,0xc8,0x84,0x22,0x14,0x08,0x8a,0x02,0xe2,0x80,0xd8 }, - 16, 0x8e50, 0, {0x82,0x34,0x34,0x1b,0x80,0x03,0x60,0x04,0x88,0x00,0x2e,0x20,0x0a,0x8e,0x42,0xce }, - 16, 0x8e60, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x80,0x81,0x08,0x04,0x41 }, - 16, 0x8e70, 0, {0x0b,0x92,0x02,0x04,0x00,0xb1,0x00,0x2c,0x40,0x0b,0x18,0x02,0x24,0x00,0xb1,0x60 }, - 16, 0x8e80, 0, {0x26,0x40,0x0a,0x16,0x02,0xc5,0x00,0xa1,0xc0,0x20,0x48,0x0b,0x90,0x02,0x47,0x00 }, - 16, 0x8e90, 0, {0x91,0x01,0x2c,0x48,0x18,0x12,0x02,0xd2,0x01,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ea0, 0, {0x18,0x15,0xa4,0x0c,0x8b,0x04,0xa2,0x50,0x0b,0x91,0x02,0x24,0x04,0xa9,0x01,0x2e }, - 16, 0x8eb0, 0, {0x42,0x0b,0x90,0x02,0xa4,0x00,0xa9,0x00,0x26,0x60,0x0a,0x90,0x02,0xe6,0x00,0x81 }, - 16, 0x8ec0, 0, {0x00,0x22,0x40,0x8b,0xb0,0x02,0x24,0x08,0x99,0x10,0x2e,0x40,0x1a,0x90,0x02,0xc6 }, - 16, 0x8ed0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe5,0x00,0xc9,0x00,0x36,0x40 }, - 16, 0x8ee0, 0, {0x0f,0x10,0x02,0x25,0x00,0xb1,0x00,0x2e,0x60,0x0f,0x10,0x12,0x24,0x02,0xb9,0xa0 }, - 16, 0x8ef0, 0, {0xa4,0x40,0x2e,0x91,0x03,0xe6,0x00,0xa9,0x00,0x22,0x40,0x0b,0x19,0x80,0x64,0x04 }, - 16, 0x8f00, 0, {0xd9,0x81,0x2e,0x40,0x4c,0x90,0x03,0xe8,0x14,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8f10, 0, {0x68,0x01,0xa4,0x0a,0xe9,0x00,0xbe,0x48,0x0f,0x98,0x0b,0xe4,0x00,0xf9,0xc4,0x36 }, - 16, 0x8f20, 0, {0x70,0x1f,0x92,0x03,0xe6,0x90,0xc1,0x90,0x3a,0x40,0x8d,0x88,0x03,0xe4,0x00,0xf9 }, - 16, 0x8f30, 0, {0x90,0x3e,0x40,0x0b,0x98,0x03,0xe6,0x40,0xe9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xd2 }, - 16, 0x8f40, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0xa1,0x02,0xd8,0x20,0xb2,0x10 }, - 16, 0x8f50, 0, {0x0c,0x80,0x83,0x21,0x40,0xc8,0x58,0xb2,0x10,0x4c,0x80,0x0b,0x20,0x00,0xf8,0x42 }, - 16, 0x8f60, 0, {0x32,0x00,0x0f,0x80,0x03,0xe0,0x02,0xd8,0x00,0x72,0x00,0x1c,0x80,0x00,0x20,0x00 }, - 16, 0x8f70, 0, {0xf8,0x04,0x3e,0x00,0x0f,0x80,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8f80, 0, {0x28,0x05,0x38,0x04,0xce,0x41,0x23,0x80,0x08,0xe0,0x02,0x39,0x10,0xae,0x40,0x22 }, - 16, 0x8f90, 0, {0x80,0x08,0xe0,0x02,0x1a,0x00,0xba,0x00,0x2b,0xad,0x03,0x80,0x02,0xe8,0x00,0xca }, - 16, 0x8fa0, 0, {0x00,0x2a,0x80,0x0a,0xe0,0x02,0x18,0x00,0xba,0x00,0x1a,0x80,0x0b,0xa0,0x03,0x4a }, - 16, 0x8fb0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x05,0x6c,0x12,0x89,0x00,0xa0,0xe0 }, - 16, 0x8fc0, 0, {0x08,0x38,0x02,0x0d,0x88,0x83,0x00,0x04,0xe0,0x08,0x38,0x32,0x0e,0x25,0x31,0x01 }, - 16, 0x8fd0, 0, {0x24,0xe0,0x8b,0x38,0x02,0xe4,0x01,0x83,0x00,0x20,0xc0,0x08,0x30,0x02,0x8c,0x00 }, - 16, 0x8fe0, 0, {0xb3,0x00,0x2e,0xc0,0x0b,0x30,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x8ff0, 0, {0xa0,0x01,0x14,0x20,0x86,0x20,0x29,0xb0,0x08,0xf0,0x82,0x3e,0x04,0xa7,0x00,0x21 }, - 16, 0x9000, 0, {0x70,0x88,0x70,0x92,0x1c,0x20,0xbd,0x00,0x69,0xc0,0x0b,0x76,0x02,0xd4,0x80,0x8f }, - 16, 0x9010, 0, {0x21,0x29,0xe0,0x0a,0x60,0x86,0x98,0x01,0xb7,0x00,0x2d,0xc8,0x0b,0x3b,0x02,0x60 }, - 16, 0x9020, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x00,0xc7,0xa0,0xb0,0xe0 }, - 16, 0x9030, 0, {0x2c,0x78,0x0b,0x1a,0x00,0xc3,0x80,0x37,0xe0,0x28,0x78,0x03,0x1a,0x08,0xf5,0x90 }, - 16, 0x9040, 0, {0x35,0xe0,0x0f,0x7c,0x12,0xd6,0x82,0xc7,0x90,0x21,0xe4,0x08,0x78,0x03,0x9e,0x00 }, - 16, 0x9050, 0, {0xf5,0x80,0x3d,0xf1,0x0f,0x78,0x03,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9060, 0, {0x08,0x19,0xa4,0x00,0xee,0x80,0x36,0xc1,0x4f,0xd0,0x03,0xc8,0x00,0xfb,0x00,0x3e }, - 16, 0x9070, 0, {0x51,0x0f,0xb0,0x03,0xe4,0x08,0xf1,0x60,0x3e,0xc0,0x0f,0xb0,0x03,0xc5,0x00,0xeb }, - 16, 0x9080, 0, {0x10,0x3e,0xc0,0x0f,0xb0,0x09,0x6c,0x00,0xfb,0x00,0x3a,0xc0,0x0f,0xb0,0x03,0xc2 }, - 16, 0x9090, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfe,0x00,0xfd,0x88,0x33,0x60 }, - 16, 0x90a0, 0, {0x0f,0xf9,0x03,0xce,0x40,0xd7,0x84,0x37,0x70,0x0c,0xd8,0x23,0x36,0x00,0xc5,0x88 }, - 16, 0x90b0, 0, {0x33,0xe0,0x4f,0xf8,0x13,0xf7,0x28,0xdf,0x80,0x37,0xe2,0x0c,0x58,0x03,0x3e,0x00 }, - 16, 0x90c0, 0, {0xff,0x90,0x3f,0xe0,0x0c,0xf8,0x03,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x90d0, 0, {0xa9,0x11,0x9c,0x08,0xf6,0x00,0xa1,0x00,0x0b,0x63,0x02,0xd6,0x30,0x85,0x41,0x31 }, - 16, 0x90e0, 0, {0xc8,0x08,0x50,0x23,0x1c,0x00,0xd5,0x20,0xb1,0x80,0x0f,0x70,0x03,0xb4,0x00,0xc7 }, - 16, 0x90f0, 0, {0x00,0x21,0xc0,0x0f,0x40,0xa3,0x58,0x40,0xb7,0x00,0x3f,0xc4,0x0a,0xf0,0x02,0x2a }, - 16, 0x9100, 0, {0x06,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x40,0xb7,0x10,0x21,0xd2 }, - 16, 0x9110, 0, {0x0b,0x70,0x02,0xdc,0x42,0x86,0x00,0x25,0x61,0x08,0x51,0x02,0x50,0x00,0x95,0x00 }, - 16, 0x9120, 0, {0x25,0xc0,0x09,0x70,0x82,0xd4,0x00,0x87,0x00,0x24,0xc0,0x08,0x50,0x02,0x5c,0x00 }, - 16, 0x9130, 0, {0x95,0x04,0x2d,0xc0,0x08,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9140, 0, {0x20,0x14,0xcc,0x08,0xb2,0xd0,0x20,0xe0,0x4b,0x08,0x02,0xc4,0x00,0x80,0x80,0x20 }, - 16, 0x9150, 0, {0xf0,0x08,0x1a,0x02,0x85,0x48,0x81,0x10,0x20,0x40,0x0a,0x30,0x02,0xc6,0x10,0x93 }, - 16, 0x9160, 0, {0x00,0x20,0xc0,0x0a,0x1c,0x02,0x0d,0x40,0xb3,0x00,0x68,0xc4,0x0a,0xb0,0x02,0x09 }, - 16, 0x9170, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x01,0xfe,0x00,0x32,0xf0 }, - 16, 0x9180, 0, {0x0f,0x88,0x03,0xe6,0x00,0xc8,0xc8,0x36,0xf6,0x28,0xa6,0x0a,0x6d,0x00,0x9d,0x00 }, - 16, 0x9190, 0, {0x32,0x00,0x0b,0xb0,0x03,0xf6,0x03,0xc7,0x00,0x37,0xc0,0x08,0x9c,0x0a,0x6e,0x00 }, - 16, 0x91a0, 0, {0xbb,0x00,0x2f,0xc0,0x0c,0xf0,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x91b0, 0, {0x80,0x00,0xe4,0x01,0xeb,0x40,0x3e,0x80,0x4f,0xc1,0x03,0xe4,0x00,0xb8,0x08,0x3a }, - 16, 0x91c0, 0, {0x40,0x8f,0xa4,0x13,0x6c,0x20,0xf9,0x00,0x3e,0x70,0x0f,0xb0,0x03,0xa4,0x40,0xeb }, - 16, 0x91d0, 0, {0x00,0x3e,0xc0,0x0f,0x92,0x23,0xe8,0x00,0xf9,0x80,0x3e,0xc0,0x0f,0xb0,0x63,0xe0 }, - 16, 0x91e0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x08,0xce,0x08,0x33,0xc0 }, - 16, 0x91f0, 0, {0x0f,0xda,0x03,0x30,0x00,0xe4,0x04,0x35,0xc0,0x0d,0xa0,0x03,0x28,0x00,0xc5,0x00 }, - 16, 0x9200, 0, {0x33,0x00,0x0b,0xfa,0x03,0xf4,0x03,0xcb,0x00,0x31,0xc0,0x0c,0xd4,0x03,0x14,0x20 }, - 16, 0x9210, 0, {0xcd,0x80,0x23,0xc1,0x0c,0xf0,0x02,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9220, 0, {0x81,0x04,0x44,0x10,0xcb,0xd0,0x22,0xc0,0x0b,0x94,0x02,0x22,0x84,0xb8,0xc6,0x02 }, - 16, 0x9230, 0, {0x40,0x08,0x28,0x02,0xa5,0x80,0x89,0x00,0x22,0x60,0x0b,0xb8,0x02,0x64,0x00,0x8b }, - 16, 0x9240, 0, {0x00,0x2a,0xc0,0xc8,0x00,0x03,0x66,0x00,0x81,0x00,0x00,0xc0,0x0d,0xb0,0x0a,0xa8 }, - 16, 0x9250, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x13,0x00,0x22,0x40 }, - 16, 0x9260, 0, {0x8b,0x24,0x02,0x2a,0x00,0xbb,0x82,0x22,0x40,0x00,0xac,0x02,0x84,0x00,0x89,0x00 }, - 16, 0x9270, 0, {0x22,0x22,0x0b,0xb0,0x02,0xc4,0x00,0x9b,0x00,0x2a,0xc0,0x08,0xb0,0x02,0x2e,0x00 }, - 16, 0x9280, 0, {0x8b,0x10,0x2a,0xc0,0x08,0xb0,0x02,0xa0,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9290, 0, {0x08,0x04,0x0c,0x10,0x83,0x00,0x20,0x01,0x0b,0x20,0x02,0x00,0x80,0xb1,0x00,0x20 }, - 16, 0x92a0, 0, {0xc1,0x08,0x20,0x02,0x88,0x01,0x81,0x00,0xa0,0x00,0x0b,0x30,0x02,0x44,0x01,0x9b }, - 16, 0x92b0, 0, {0x00,0x28,0xc0,0x08,0xb0,0x02,0x48,0x06,0x89,0x00,0x2a,0xc0,0x09,0x30,0x02,0x82 }, - 16, 0x92c0, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x6c,0x00,0xc3,0x00,0xb2,0xc0 }, - 16, 0x92d0, 0, {0x0f,0xb0,0x03,0x28,0x20,0xfa,0x00,0xb1,0x40,0x0d,0xa0,0x07,0xa0,0x00,0xcd,0x00 }, - 16, 0x92e0, 0, {0x22,0x00,0x0f,0xb0,0x03,0xf4,0x00,0x9f,0x00,0x3b,0xc0,0x2c,0xb0,0x0b,0x24,0x00 }, - 16, 0x92f0, 0, {0xc9,0x00,0xba,0xc0,0x0c,0xb0,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9300, 0, {0xa0,0x1d,0xfc,0x06,0xff,0x02,0xaf,0xc0,0x0f,0xc0,0x03,0xf0,0x10,0xfc,0x00,0x3f }, - 16, 0x9310, 0, {0xc0,0x9f,0xe0,0x13,0xf0,0x00,0xfd,0x04,0x3f,0x40,0x4f,0xf0,0x03,0x74,0x00,0xef }, - 16, 0x9320, 0, {0x00,0x3f,0xc0,0x8f,0xe0,0x02,0xb4,0x01,0xfd,0x04,0x37,0xc0,0x0f,0xf0,0x43,0x68 }, - 16, 0x9330, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xc7,0x20,0xb3,0xc8 }, - 16, 0x9340, 0, {0x1c,0xf1,0x03,0x7c,0x20,0xcf,0x0a,0x3f,0xd0,0x0d,0xf0,0x03,0x7c,0x80,0x8f,0x32 }, - 16, 0x9350, 0, {0x33,0xc4,0x0f,0xf1,0x83,0x3c,0xe0,0xcf,0x10,0x33,0xc4,0x0d,0xf2,0x83,0x3c,0xe2 }, - 16, 0x9360, 0, {0xc7,0x80,0x17,0xcc,0x4c,0xf3,0x83,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9370, 0, {0x80,0x10,0xe3,0x40,0x88,0x68,0x22,0x30,0x08,0x06,0x02,0x01,0xa1,0x88,0xc4,0x0e }, - 16, 0x9380, 0, {0x14,0x08,0x87,0x80,0x01,0xc0,0x28,0x50,0x02,0x04,0x8b,0x86,0x02,0xa1,0x98,0x88 }, - 16, 0x9390, 0, {0x41,0x2a,0x04,0x0a,0x84,0x82,0xbd,0x80,0x8b,0x08,0x2b,0xc4,0x88,0xf4,0x03,0x60 }, - 16, 0x93a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x08,0x82,0x40,0x20,0x10 }, - 16, 0x93b0, 0, {0x08,0x21,0x12,0x44,0x04,0x82,0x04,0x2c,0x08,0x89,0x90,0x02,0x44,0x21,0x8b,0x00 }, - 16, 0x93c0, 0, {0x24,0x88,0x8b,0xa0,0x00,0x40,0x84,0x89,0x30,0x22,0x48,0x88,0xb0,0x02,0xcc,0x08 }, - 16, 0x93d0, 0, {0x88,0x20,0xa4,0xc8,0x00,0x32,0x0a,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x93e0, 0, {0xc0,0x15,0xa0,0x00,0x89,0x00,0x22,0xc1,0x88,0x90,0x62,0x28,0x08,0x89,0x08,0x2e }, - 16, 0x93f0, 0, {0xc0,0x08,0xa0,0x02,0x28,0x08,0xa8,0x00,0x26,0x42,0x0b,0x90,0x02,0xcc,0x50,0x8a }, - 16, 0x9400, 0, {0x22,0x2a,0x86,0x0a,0x80,0x02,0xec,0x00,0x88,0x84,0x2a,0xc1,0x08,0xb0,0x26,0x30 }, - 16, 0x9410, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xf0,0x02,0xcf,0x00,0x33,0xc0 }, - 16, 0x9420, 0, {0x48,0xf8,0x43,0x79,0x00,0x8d,0xc0,0x3f,0x30,0x8d,0x60,0x83,0x78,0x60,0xc4,0x58 }, - 16, 0x9430, 0, {0x37,0x20,0x0f,0x58,0x13,0x7b,0x02,0xcc,0xc4,0x31,0x20,0x0c,0x44,0x03,0xec,0x02 }, - 16, 0x9440, 0, {0x8b,0x80,0x36,0xc0,0x24,0xb0,0x12,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9450, 0, {0xe0,0x01,0x9c,0x00,0xf4,0x10,0x3d,0x00,0x6f,0xc9,0x13,0xd4,0x12,0xfe,0x90,0x3f }, - 16, 0x9460, 0, {0xf0,0x0f,0xda,0x23,0xf4,0x14,0xff,0x02,0x3b,0xf0,0x0f,0xea,0x23,0xb6,0x00,0xff }, - 16, 0x9470, 0, {0x82,0x3f,0xe1,0x8f,0xf4,0x03,0xbc,0x00,0xff,0x00,0x3f,0xc0,0xaf,0x70,0x03,0xf8 }, - 16, 0x9480, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa0,0x00,0xca,0x00,0x32,0x08 }, - 16, 0x9490, 0, {0x1c,0xa0,0x03,0xa5,0x20,0xcb,0x40,0xba,0x10,0x1f,0xb0,0x03,0xac,0x00,0xeb,0x00 }, - 16, 0x94a0, 0, {0x72,0x90,0x0c,0xb4,0x03,0x29,0x04,0xc9,0x52,0x32,0x50,0x0c,0xb4,0x03,0x0c,0x00 }, - 16, 0x94b0, 0, {0xf8,0x40,0x32,0xc1,0x0e,0xb0,0x0b,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x94c0, 0, {0xc8,0x05,0x2d,0x80,0x89,0x80,0x22,0xd9,0x08,0x90,0x22,0x2a,0x00,0x88,0x54,0x22 }, - 16, 0x94d0, 0, {0xc0,0x8b,0x80,0x22,0x20,0x19,0xc8,0x00,0x22,0x40,0x8d,0x80,0x1a,0x24,0x10,0xd2 }, - 16, 0x94e0, 0, {0x44,0x22,0x81,0x0d,0x80,0x03,0x7c,0x00,0xb0,0x00,0x37,0xc0,0x88,0xf0,0x02,0x32 }, - 16, 0x94f0, 0, {0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4e,0x00,0x81,0x00,0xa0,0xf0 }, - 16, 0x9500, 0, {0x08,0x90,0x02,0x89,0x02,0x80,0x00,0x22,0xc0,0x0b,0x00,0x22,0xa0,0x00,0xb0,0x00 }, - 16, 0x9510, 0, {0x20,0x40,0x08,0x00,0x02,0x04,0x00,0x82,0x60,0x20,0x80,0x08,0x00,0x02,0x0c,0x08 }, - 16, 0x9520, 0, {0xb2,0x00,0x22,0xc0,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9530, 0, {0x20,0x01,0x03,0x10,0x8e,0x90,0x23,0x24,0x08,0x6b,0x02,0x16,0x60,0x8f,0x80,0x21 }, - 16, 0x9540, 0, {0x28,0x0b,0xf9,0x06,0x1e,0x40,0x8f,0x80,0x23,0xa4,0x49,0x79,0x02,0x3a,0x40,0x9d }, - 16, 0x9550, 0, {0x90,0x23,0x64,0x09,0xf8,0x02,0x5e,0x40,0xbe,0x90,0x24,0xe4,0x28,0x79,0x02,0x08 }, - 16, 0x9560, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x42,0xc0,0x09,0x30,0x00 }, - 16, 0x9570, 0, {0x28,0x02,0x03,0x84,0x00,0x8a,0x20,0x30,0xc4,0x8b,0x11,0x03,0x84,0x50,0xb3,0x00 }, - 16, 0x9580, 0, {0x20,0xc0,0x0c,0xa4,0x22,0x04,0x00,0xcb,0x40,0x30,0xc5,0x0c,0x30,0x03,0x0e,0x40 }, - 16, 0x9590, 0, {0xf3,0x10,0x30,0xc4,0x0c,0xb0,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x95a0, 0, {0x40,0x1d,0xb0,0x04,0xfb,0x04,0x3d,0xc0,0x0f,0xf2,0x43,0xf8,0x04,0xfd,0x01,0x3f }, - 16, 0x95b0, 0, {0x0c,0x0f,0x61,0x03,0xf8,0x48,0xf4,0x00,0x3d,0x01,0x0f,0xd0,0x03,0xc8,0x00,0xfc }, - 16, 0x95c0, 0, {0x04,0xbd,0x04,0x0b,0x48,0x03,0xfc,0x18,0xff,0x14,0x3f,0xd5,0x0d,0xf0,0x03,0x90 }, - 16, 0x95d0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe0,0x00,0xf9,0x01,0x32,0xc0 }, - 16, 0x95e0, 0, {0x8e,0x90,0x03,0x28,0x02,0xd1,0x00,0x32,0xc0,0x0d,0xa8,0x0b,0x08,0x00,0xe8,0x00 }, - 16, 0x95f0, 0, {0x2e,0x40,0x0c,0x98,0x0b,0x2e,0x02,0xca,0x00,0xb2,0xa0,0x6c,0x80,0x23,0x2d,0x80 }, - 16, 0x9600, 0, {0xca,0x80,0x32,0xd0,0x0c,0xba,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9610, 0, {0x48,0x11,0x9c,0x00,0xb6,0x00,0xa3,0x00,0x08,0x60,0x02,0x04,0x00,0x86,0x04,0x29 }, - 16, 0x9620, 0, {0x00,0x08,0x50,0x42,0x14,0x04,0xa7,0x00,0x0d,0x80,0x4a,0x60,0x02,0x00,0x00,0x81 }, - 16, 0x9630, 0, {0x00,0x21,0x40,0x08,0x70,0x02,0x9d,0x42,0x86,0x01,0x20,0xc0,0x08,0x32,0x82,0x12 }, - 16, 0x9640, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x92,0x00,0xbc,0x80,0x63,0x20 }, - 16, 0x9650, 0, {0x82,0x08,0x02,0x52,0x00,0x84,0xc2,0x23,0x20,0x88,0x0c,0x02,0x33,0x00,0x84,0x80 }, - 16, 0x9660, 0, {0x2f,0x21,0x89,0x4c,0x02,0x12,0x14,0x94,0xc5,0x64,0x21,0x08,0x4c,0x02,0x0e,0x80 }, - 16, 0x9670, 0, {0x97,0x82,0xa1,0xec,0x08,0x79,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9680, 0, {0x48,0x14,0xcd,0x44,0xb3,0x00,0x20,0xc0,0x08,0x30,0x02,0x4d,0x80,0x03,0x88,0x28 }, - 16, 0x9690, 0, {0xc0,0x08,0x3c,0x06,0x0f,0x00,0xa3,0x43,0x2c,0xc2,0x1b,0x38,0x02,0x0f,0x00,0x9b }, - 16, 0x96a0, 0, {0x88,0x64,0xd0,0x08,0xb8,0x02,0x8c,0x10,0x93,0x00,0x20,0xc0,0x08,0x30,0x0a,0x12 }, - 16, 0x96b0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xaa,0x00,0xfa,0x05,0x32,0x80 }, - 16, 0x96c0, 0, {0x8e,0xa0,0x0b,0x69,0x00,0xca,0x40,0x32,0xa0,0x3c,0xa8,0x03,0x2a,0x00,0xea,0x26 }, - 16, 0x96d0, 0, {0x3e,0xb0,0x0d,0xa1,0x63,0x28,0x20,0xca,0x40,0x36,0xa0,0x0c,0xe0,0x13,0x28,0x09 }, - 16, 0x96e0, 0, {0xde,0x00,0x32,0x80,0x2c,0xa0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x96f0, 0, {0x48,0x00,0xf0,0x20,0xf4,0x00,0x3f,0x00,0x0f,0x40,0x23,0xb0,0x00,0xec,0x00,0x3f }, - 16, 0x9700, 0, {0x06,0x1e,0xc2,0x13,0xf0,0x88,0xfc,0x20,0x3f,0x04,0x8e,0xc0,0x03,0xf0,0x80,0xec }, - 16, 0x9710, 0, {0x40,0x3b,0x0c,0x0f,0xc0,0xa3,0xe0,0x00,0xe8,0x00,0x3e,0x00,0x4f,0x80,0x03,0xd2 }, - 16, 0x9720, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x00,0x32,0x40 }, - 16, 0x9730, 0, {0x0c,0x90,0x03,0x24,0x00,0xc9,0x80,0x32,0x40,0x0f,0x90,0x53,0xe4,0x10,0xc9,0x00 }, - 16, 0x9740, 0, {0x32,0x40,0x0d,0x90,0x03,0xe4,0x00,0xf9,0x00,0x36,0x40,0x8f,0x90,0x03,0x24,0x10 }, - 16, 0x9750, 0, {0xc9,0x01,0x3c,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9760, 0, {0x80,0x04,0x47,0x44,0x89,0x00,0x20,0x40,0x08,0x90,0x02,0x25,0x0a,0x81,0x10,0x22 }, - 16, 0x9770, 0, {0x40,0x48,0x90,0x03,0xc4,0x00,0x89,0x00,0x76,0x40,0x28,0x90,0x02,0xe4,0x10,0xb9 }, - 16, 0x9780, 0, {0x40,0xb2,0x40,0x0b,0x90,0x03,0x64,0x00,0x89,0x00,0x2e,0x41,0x08,0x90,0x42,0xe0 }, - 16, 0x9790, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x02,0xbd,0x00,0x23,0x48 }, - 16, 0x97a0, 0, {0x08,0xd0,0x06,0x1d,0x04,0x8d,0x00,0x29,0xc0,0x4a,0xd0,0x22,0xf4,0x00,0x85,0x00 }, - 16, 0x97b0, 0, {0x61,0x40,0x18,0xd0,0x12,0xfc,0x00,0xbd,0x40,0xa3,0x40,0x4b,0xf0,0x02,0x04,0x01 }, - 16, 0x97c0, 0, {0x8b,0x00,0x2e,0x40,0x08,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x97d0, 0, {0x08,0x04,0x36,0x80,0x85,0x20,0xa3,0x48,0x08,0x52,0x0a,0x14,0x81,0x85,0x20,0x29 }, - 16, 0x97e0, 0, {0x48,0x08,0x52,0x02,0xb4,0x80,0x85,0x20,0x25,0x48,0x88,0x52,0x02,0xd4,0x80,0xb5 }, - 16, 0x97f0, 0, {0x20,0x21,0x48,0x0b,0x52,0x02,0x44,0xa2,0x81,0x00,0x2c,0x4a,0x08,0x12,0x82,0xc2 }, - 16, 0x9800, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x51,0x22,0x00 }, - 16, 0x9810, 0, {0x2c,0x85,0x02,0x21,0x48,0xc8,0x00,0xba,0x14,0x0f,0x85,0x12,0xe1,0x42,0xc8,0x50 }, - 16, 0x9820, 0, {0x22,0x00,0x0c,0x00,0x03,0xe0,0x00,0xf8,0x50,0x32,0x00,0x07,0x45,0x03,0x20,0x80 }, - 16, 0x9830, 0, {0xc0,0x01,0x3e,0x08,0x2c,0x82,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9840, 0, {0x98,0x0d,0xe4,0x40,0xf1,0x10,0x3e,0x44,0x07,0x91,0x43,0xe4,0x58,0xf9,0x11,0x34 }, - 16, 0x9850, 0, {0x44,0x4f,0x91,0x02,0xe4,0x50,0xf9,0x10,0x3c,0x4f,0x0f,0x93,0x83,0xe4,0xf0,0xf9 }, - 16, 0x9860, 0, {0x11,0x3a,0x4f,0x0f,0x91,0x03,0xe4,0xa0,0xfd,0x28,0x3e,0x4a,0x0f,0x92,0x83,0xe6 }, - 16, 0x9870, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0xa0,0xcd,0xa0,0xb3,0x68 }, - 16, 0x9880, 0, {0x8c,0x9a,0x03,0x36,0x80,0xc5,0xa0,0x22,0x60,0x0c,0x9a,0x23,0x26,0x04,0xf9,0xa0 }, - 16, 0x9890, 0, {0x32,0x66,0x0c,0x9a,0x83,0x06,0x20,0xc5,0xa0,0x22,0x60,0x0c,0x9b,0x03,0x26,0x48 }, - 16, 0x98a0, 0, {0xc9,0x00,0x3e,0x78,0x0c,0x9a,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x98b0, 0, {0x38,0x00,0xe1,0x00,0x88,0x44,0x22,0x95,0x08,0x85,0x12,0xa1,0x42,0x88,0x40,0x02 }, - 16, 0x98c0, 0, {0x90,0x08,0x84,0x02,0x23,0xa0,0xba,0x40,0x22,0xa0,0x08,0x8e,0x92,0xa3,0xa0,0xa8 }, - 16, 0x98d0, 0, {0x40,0x2a,0x10,0x08,0xae,0x02,0x23,0x40,0x88,0x00,0x2e,0x38,0x08,0x84,0x12,0x0e }, - 16, 0x98e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x15,0xc4,0x00,0x8b,0x12,0x22,0x40 }, - 16, 0x98f0, 0, {0x08,0x90,0x02,0x44,0x00,0x81,0x40,0xa0,0x50,0x08,0x11,0x0a,0x05,0x00,0xb1,0x10 }, - 16, 0x9900, 0, {0xa0,0x48,0x08,0x90,0x02,0x04,0x00,0x81,0x40,0x20,0x50,0x28,0x11,0x02,0x44,0x82 }, - 16, 0x9910, 0, {0x81,0x00,0x2c,0x50,0x08,0x11,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9920, 0, {0x18,0x15,0xa4,0x02,0x89,0x40,0x22,0x40,0x08,0x94,0x12,0xa5,0x00,0x89,0x28,0x22 }, - 16, 0x9930, 0, {0x49,0x08,0x94,0x02,0x24,0x48,0xb9,0x14,0x22,0x40,0x08,0x94,0x02,0xa4,0x40,0xa1 }, - 16, 0x9940, 0, {0x50,0x2a,0x50,0x08,0x91,0x42,0x64,0x00,0x89,0x40,0x2e,0x40,0x08,0x10,0x02,0x06 }, - 16, 0x9950, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x30,0x70 }, - 16, 0x9960, 0, {0x2c,0x10,0x0b,0x66,0x00,0xc9,0x40,0x32,0x50,0x0c,0x90,0x03,0x26,0x20,0xf9,0xc0 }, - 16, 0x9970, 0, {0x32,0x70,0x0c,0x90,0x03,0x26,0x20,0xc9,0x00,0x32,0x40,0x0c,0x9c,0x03,0x64,0x00 }, - 16, 0x9980, 0, {0xc9,0x41,0x3e,0x40,0x2c,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9990, 0, {0x28,0x01,0xa4,0x00,0xf9,0x04,0x3e,0x48,0x0f,0x90,0x03,0xe4,0x88,0xf9,0x00,0x34 }, - 16, 0x99a0, 0, {0x41,0x2f,0x9c,0x03,0xe4,0x10,0xf9,0x00,0x3e,0x44,0x2f,0x99,0x03,0xe4,0x10,0xf9 }, - 16, 0x99b0, 0, {0x00,0x3e,0x50,0x0f,0x10,0x4b,0xa4,0x10,0xf9,0x20,0x3c,0x40,0x0f,0x90,0x03,0x4a }, - 16, 0x99c0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x3e,0x10 }, - 16, 0x99d0, 0, {0x2c,0x80,0x03,0x20,0x02,0xc0,0x40,0x32,0x00,0x1c,0x04,0x0f,0x21,0x00,0xc0,0x04 }, - 16, 0x99e0, 0, {0x38,0x00,0x0f,0x80,0x03,0x21,0x08,0xc8,0x60,0x30,0x10,0x0f,0x80,0x02,0x20,0x00 }, - 16, 0x99f0, 0, {0xf8,0x00,0x32,0x00,0x0c,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9a00, 0, {0x28,0x05,0x1a,0x20,0x82,0x04,0x2f,0x80,0x08,0xa0,0x02,0x38,0x00,0x8e,0x80,0x22 }, - 16, 0x9a10, 0, {0x80,0x08,0xe0,0x02,0x28,0x00,0x8a,0x00,0x22,0x81,0x0b,0x20,0x02,0x28,0x00,0xde }, - 16, 0x9a20, 0, {0xe4,0x36,0x80,0x0b,0xa0,0x42,0x28,0x00,0xba,0x04,0x22,0x80,0x08,0xa0,0x02,0xca }, - 16, 0x9a30, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x01,0x2c,0x80 }, - 16, 0x9a40, 0, {0x08,0x30,0x02,0x2e,0x60,0x82,0x90,0xa0,0xc0,0x48,0x30,0x02,0x0c,0x02,0x83,0x00 }, - 16, 0x9a50, 0, {0x28,0xc0,0x0b,0x30,0x0a,0x2c,0x00,0x83,0xc2,0x20,0xc0,0x0b,0x30,0x2a,0x2c,0x00 }, - 16, 0x9a60, 0, {0xb3,0x00,0xa0,0xc0,0x08,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9a70, 0, {0xa0,0x01,0x3c,0x00,0x87,0x01,0x2d,0xc2,0x08,0xf3,0x12,0x3c,0x00,0x8f,0x01,0x21 }, - 16, 0x9a80, 0, {0xc8,0x68,0x72,0x22,0x1e,0x04,0x87,0x20,0x21,0xc4,0x0b,0x70,0x02,0x3c,0x84,0x9f }, - 16, 0x9a90, 0, {0x00,0x25,0xc4,0x4b,0x70,0x02,0x1c,0x04,0xb7,0x81,0x21,0xc8,0x08,0x72,0x02,0xe8 }, - 16, 0x9aa0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x00,0x1e,0x00,0xc7,0x81,0x3c,0xa0 }, - 16, 0x9ab0, 0, {0x4c,0x7a,0x0b,0x1a,0x00,0xc6,0x80,0x30,0xe0,0x08,0xf8,0x82,0x0e,0x40,0xcf,0xf0 }, - 16, 0x9ac0, 0, {0x39,0xe8,0x0f,0x3a,0x03,0x1e,0x20,0xc7,0x80,0x31,0xe3,0x0f,0x38,0x23,0x1f,0x08 }, - 16, 0x9ad0, 0, {0xff,0xc0,0x33,0xf2,0x0c,0x7e,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9ae0, 0, {0x08,0x15,0x88,0x0a,0x7b,0x00,0x3e,0xc1,0x0b,0x34,0x23,0xc8,0x10,0xfb,0x02,0x3e }, - 16, 0x9af0, 0, {0xca,0x0f,0xb7,0x43,0xec,0x80,0xfb,0x00,0x2e,0xc2,0x0b,0xb4,0x83,0xed,0xd0,0xfa }, - 16, 0x9b00, 0, {0x00,0x3e,0xd9,0x0f,0xb3,0x83,0xec,0x80,0xbb,0x20,0x3e,0xd8,0x2f,0xb4,0x03,0xc2 }, - 16, 0x9b10, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xf5,0x91,0x31,0xa0 }, - 16, 0x9b20, 0, {0x0c,0xfc,0x03,0xfe,0x00,0xc4,0x81,0x31,0xee,0x8d,0xf8,0x0a,0x3e,0x30,0xcf,0x84 }, - 16, 0x9b30, 0, {0x33,0xe0,0x2c,0xf8,0x83,0xfe,0x10,0xfe,0x80,0x33,0xe0,0x0c,0xf9,0x19,0x3f,0x48 }, - 16, 0x9b40, 0, {0xcf,0xc0,0x33,0xe0,0x04,0xfc,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9b50, 0, {0xa8,0x11,0x9c,0x08,0xb7,0xa1,0x21,0xc8,0x08,0x71,0x02,0xf0,0xa0,0x85,0x20,0x21 }, - 16, 0x9b60, 0, {0xce,0x08,0x70,0x02,0x3c,0x80,0x8f,0x00,0x2b,0xc5,0x08,0x71,0x02,0xdc,0x10,0xb4 }, - 16, 0x9b70, 0, {0x00,0x21,0xc1,0x0a,0xf3,0x82,0x0c,0x00,0x87,0x01,0x29,0xc0,0x08,0x71,0x02,0x6a }, - 16, 0x9b80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9d,0x00,0xbd,0x21,0x27,0x82 }, - 16, 0x9b90, 0, {0x00,0x70,0x02,0xfc,0x04,0x8c,0x00,0xa7,0xcc,0xa8,0x70,0x02,0x3c,0x08,0xaf,0x00 }, - 16, 0x9ba0, 0, {0x21,0xc0,0x08,0x70,0x02,0xdc,0x00,0xb7,0x00,0x21,0xc4,0x08,0x70,0x16,0x1c,0x0a }, - 16, 0x9bb0, 0, {0x8f,0x00,0x21,0xc0,0x08,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9bc0, 0, {0x20,0x10,0xc8,0x00,0xbb,0x44,0x24,0xe2,0x08,0xb1,0x02,0xc2,0x80,0x01,0x80,0x24 }, - 16, 0x9bd0, 0, {0xd0,0x88,0x30,0x02,0x0f,0x52,0x83,0x91,0x28,0xe4,0x88,0x3d,0x02,0xce,0xd0,0xb0 }, - 16, 0x9be0, 0, {0xb2,0xa2,0xc0,0x0a,0x34,0x12,0x0c,0x02,0x83,0x00,0x28,0xc0,0x08,0x30,0x02,0x48 }, - 16, 0x9bf0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xfb,0x01,0xe4,0x40 }, - 16, 0x9c00, 0, {0x2c,0xf0,0x43,0xe5,0x00,0x8a,0x88,0x37,0xe0,0x00,0xfa,0x02,0x3d,0x00,0xef,0x00 }, - 16, 0x9c10, 0, {0x33,0xd1,0x0c,0xf4,0x03,0xfd,0x00,0xf9,0x40,0x33,0xe8,0x0c,0xfc,0x01,0x3c,0x04 }, - 16, 0x9c20, 0, {0xcf,0x02,0x33,0xc0,0x2c,0xf0,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9c30, 0, {0x80,0x00,0xee,0x08,0xf9,0x10,0x3a,0xd0,0x0f,0xb0,0x93,0xec,0x00,0xfb,0x0b,0x3a }, - 16, 0x9c40, 0, {0xc0,0x8e,0xb0,0x83,0xec,0x80,0xfb,0x09,0x7e,0xc8,0x0f,0xb2,0x13,0xec,0x00,0xf9 }, - 16, 0x9c50, 0, {0x00,0x3e,0xc2,0x8f,0xb2,0x4b,0xcc,0x04,0xfb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x60 }, - 16, 0x9c60, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x08,0x33,0xc0 }, - 16, 0x9c70, 0, {0x1c,0xf0,0x03,0x70,0x40,0xc4,0xc0,0x33,0xc2,0x0f,0xf0,0x03,0x1c,0x10,0xc7,0x00 }, - 16, 0x9c80, 0, {0x31,0xc0,0x0c,0x70,0x03,0x1c,0x00,0xc5,0x41,0x33,0xc0,0x0c,0xf0,0x23,0x2c,0x00 }, - 16, 0x9c90, 0, {0xcf,0x00,0xb3,0xc0,0x6c,0xf0,0x03,0x80,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9ca0, 0, {0x81,0x04,0x6a,0x00,0xb9,0x90,0x32,0xf1,0x08,0xb0,0x02,0x0a,0x10,0xd9,0x00,0x22 }, - 16, 0x9cb0, 0, {0xc1,0x0b,0xb0,0x02,0x2c,0x00,0xcb,0x06,0x22,0xc0,0x88,0xb0,0x12,0x2c,0x00,0x88 }, - 16, 0x9cc0, 0, {0x80,0x22,0xc1,0x0d,0xb0,0x02,0x2c,0x00,0x83,0x00,0x22,0xc1,0x08,0xb0,0x46,0xe0 }, - 16, 0x9cd0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x2e,0x00,0xb9,0x00,0x22,0xf0 }, - 16, 0x9ce0, 0, {0x08,0xb0,0x12,0x64,0x00,0x8a,0x00,0x22,0xc0,0x0b,0x30,0x42,0x2c,0x00,0x8b,0x00 }, - 16, 0x9cf0, 0, {0x22,0xc0,0x08,0xb0,0x02,0x2c,0x00,0x8a,0x00,0x22,0xc0,0x88,0x30,0x0a,0x2c,0x00 }, - 16, 0x9d00, 0, {0x8b,0x00,0x20,0xc0,0x08,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9d10, 0, {0x08,0x04,0x0c,0x04,0xb1,0x02,0xe4,0xc1,0x08,0xb0,0x22,0x20,0x02,0x93,0x00,0x20 }, - 16, 0x9d20, 0, {0xc0,0x0b,0x30,0x12,0x0c,0x02,0x83,0x02,0xa0,0xc0,0x28,0x30,0x0e,0x0c,0x02,0x80 }, - 16, 0x9d30, 0, {0x00,0xa0,0xc0,0x49,0x30,0x0a,0x0c,0x02,0x8b,0x00,0x20,0xc0,0x08,0x30,0x02,0xc2 }, - 16, 0x9d40, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xf9,0x24,0x32,0xc0 }, - 16, 0x9d50, 0, {0x08,0xf0,0x03,0x64,0x00,0xc8,0x00,0xb3,0xc0,0x1f,0xf0,0x0b,0x3c,0x00,0x8f,0x00 }, - 16, 0x9d60, 0, {0x33,0xc0,0x4c,0xf0,0x43,0x3c,0x08,0xc3,0x00,0x31,0xc0,0x0c,0xf0,0x03,0x3d,0x48 }, - 16, 0x9d70, 0, {0xcf,0x00,0x31,0xc0,0x0c,0xf0,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9d80, 0, {0xa0,0x1d,0xf0,0x04,0xf9,0x41,0x3b,0xc0,0x4f,0xf0,0x03,0xf0,0x11,0xfd,0x00,0x3f }, - 16, 0x9d90, 0, {0xc0,0x87,0x70,0x27,0xfc,0x00,0xef,0x06,0x3f,0xc0,0x0f,0xf0,0x02,0xfc,0x08,0xfc }, - 16, 0x9da0, 0, {0x00,0x3f,0xc0,0x47,0xf0,0x43,0xfc,0x00,0x77,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8 }, - 16, 0x9db0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd2,0x00,0xc7,0x01,0x37,0x0c }, - 16, 0x9dc0, 0, {0x0f,0xe8,0x23,0x10,0x4a,0xc4,0xc0,0x31,0x30,0x0c,0xc9,0x03,0x34,0x46,0xcf,0x10 }, - 16, 0x9dd0, 0, {0x33,0xd0,0x0c,0xf4,0x03,0x3c,0x58,0xcf,0x00,0x33,0xc0,0x2d,0xf1,0x03,0x3e,0x02 }, - 16, 0x9de0, 0, {0xcf,0x21,0x3f,0xe4,0x0f,0xf2,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9df0, 0, {0x80,0x10,0xe4,0x84,0x0b,0x40,0x22,0x4c,0x0b,0xa8,0x02,0x2c,0xc0,0x8b,0x20,0x22 }, - 16, 0x9e00, 0, {0xc8,0x4a,0x32,0x02,0x24,0x80,0x83,0x20,0x20,0xc0,0x08,0x30,0x02,0x20,0x00,0x8b }, - 16, 0x9e10, 0, {0x21,0x32,0xca,0x48,0x32,0x02,0x2c,0x30,0x8f,0x90,0x2e,0x88,0x0b,0xbd,0x12,0x20 }, - 16, 0x9e20, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xce,0x20,0xa3,0x40,0xe0,0x48 }, - 16, 0x9e30, 0, {0x4b,0x20,0x22,0x0c,0x02,0x82,0x00,0x2a,0x00,0x08,0x20,0x02,0x04,0x80,0x80,0x20 }, - 16, 0x9e40, 0, {0x20,0xc8,0x08,0x02,0x02,0x0c,0x00,0x80,0x0c,0x60,0x00,0x08,0x20,0x12,0x2c,0x88 }, - 16, 0x9e50, 0, {0x83,0x00,0x2c,0xe8,0x0b,0x30,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9e60, 0, {0xc0,0x15,0xae,0x00,0xab,0x01,0xa2,0x60,0x0b,0xa0,0x02,0x20,0x01,0x81,0x00,0x22 }, - 16, 0x9e70, 0, {0xc0,0x0a,0x90,0x12,0x04,0x20,0x8a,0x08,0x22,0xc1,0x08,0xa0,0x02,0x28,0x00,0x88 }, - 16, 0x9e80, 0, {0x00,0x24,0x44,0x08,0xa2,0x02,0xac,0x00,0x8b,0x04,0x2e,0x88,0x03,0xb0,0x02,0x70 }, - 16, 0x9e90, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xea,0x90,0x32,0x28 }, - 16, 0x9ea0, 0, {0x0f,0xb6,0x03,0x20,0x08,0xc9,0x04,0x3a,0xc0,0x4c,0x90,0x22,0x24,0x00,0xcb,0x40 }, - 16, 0x9eb0, 0, {0x32,0xa8,0x0c,0xb2,0x03,0x2c,0x00,0xcb,0x80,0xb2,0xe0,0x0c,0xb0,0x0b,0x04,0x00 }, - 16, 0x9ec0, 0, {0xcb,0x00,0x3e,0xc0,0x4f,0xb0,0x0b,0x50,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9ed0, 0, {0xe0,0x01,0xbc,0x00,0xdf,0x80,0x3b,0x81,0x0f,0xf0,0xc3,0xfc,0x00,0xbe,0x01,0x1f }, - 16, 0x9ee0, 0, {0x00,0x0f,0xe0,0x23,0xf4,0x00,0xff,0x00,0x3f,0xb0,0x4f,0xf0,0x43,0xd4,0x02,0xff }, - 16, 0x9ef0, 0, {0x91,0x3a,0xe0,0x4e,0xf0,0x03,0x7c,0x0c,0xff,0x00,0x2f,0x80,0x0f,0x30,0x03,0xb8 }, - 16, 0x9f00, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x01,0xca,0x00,0x72,0x50 }, - 16, 0x9f10, 0, {0x04,0xb4,0x03,0x2c,0x82,0xcb,0x00,0x32,0xe0,0x0c,0xb8,0x03,0x27,0x04,0xc8,0xc8 }, - 16, 0x9f20, 0, {0xb2,0xa2,0x0c,0x88,0x03,0x2c,0x00,0xc1,0x00,0x3e,0x00,0x2c,0x30,0x1b,0x2c,0x04 }, - 16, 0x9f30, 0, {0xfb,0x10,0x3e,0xc0,0x0f,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9f40, 0, {0xc8,0x05,0x2c,0x04,0x03,0x50,0xa2,0xe0,0x08,0x34,0x42,0x33,0x00,0x88,0x00,0x20 }, - 16, 0x9f50, 0, {0x10,0x0d,0x84,0x03,0x25,0x00,0x8a,0x40,0x22,0x90,0x08,0xa5,0x02,0x2c,0x00,0x89 }, - 16, 0x9f60, 0, {0xa4,0x3a,0x40,0x08,0xb0,0x02,0x2c,0x00,0xbf,0x84,0x2e,0x80,0x0b,0xf0,0x52,0x32 }, - 16, 0x9f70, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x6c,0x80,0x81,0x80,0x24,0x88 }, - 16, 0x9f80, 0, {0x89,0x3c,0x26,0x21,0x00,0x90,0x00,0x20,0x02,0x08,0x80,0x82,0x00,0x20,0x9b,0x00 }, - 16, 0x9f90, 0, {0x22,0x40,0x88,0xb0,0x12,0x0c,0x08,0x83,0x80,0x2c,0xc0,0x08,0x10,0x02,0x0c,0x00 }, - 16, 0x9fa0, 0, {0xb3,0x80,0x2c,0x40,0x0b,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0x9fb0, 0, {0x20,0x01,0x3e,0x0a,0x85,0xa0,0xa5,0x60,0x08,0xfb,0x82,0x3e,0x84,0x9f,0x81,0x63 }, - 16, 0x9fc0, 0, {0xe0,0x89,0x79,0x12,0x52,0x80,0x97,0x82,0x21,0x6c,0x18,0x78,0x02,0x12,0x00,0x87 }, - 16, 0x9fd0, 0, {0xa1,0x29,0xe0,0x08,0x5b,0x02,0x1e,0x00,0xb7,0xc0,0x2d,0x60,0x0b,0x78,0x02,0x08 }, - 16, 0x9fe0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x81,0x08,0x26,0xc2 }, - 16, 0x9ff0, 0, {0x2c,0x32,0x13,0x0e,0xa4,0xd2,0x00,0xb0,0x00,0x1c,0x21,0x12,0x24,0x02,0xd1,0x20 }, - 16, 0xa000, 0, {0x30,0xc8,0x0c,0x10,0x03,0x0c,0x00,0xc2,0x10,0x3c,0x80,0x0c,0x23,0x03,0x0c,0x40 }, - 16, 0xa010, 0, {0xf3,0x00,0x3c,0x48,0x0f,0x30,0x0b,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa020, 0, {0x40,0x1d,0xbc,0x00,0xfd,0x20,0xbb,0x40,0x07,0x72,0x02,0xf0,0x10,0xed,0x10,0x3f }, - 16, 0xa030, 0, {0xc4,0x0f,0xd1,0x63,0xb4,0x80,0xef,0x00,0x3f,0xc8,0x0f,0xf0,0x03,0xd8,0x00,0xfe }, - 16, 0xa040, 0, {0x34,0x3f,0xc4,0x0f,0xeb,0x43,0xfc,0x00,0xff,0x08,0x7f,0x40,0x0f,0xf1,0x83,0xd0 }, - 16, 0xa050, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xc8,0x00,0x33,0x80 }, - 16, 0xa060, 0, {0x8f,0x28,0x03,0x20,0x00,0x49,0x02,0x32,0xc0,0x0f,0x90,0x03,0x20,0x00,0xcb,0x00 }, - 16, 0xa070, 0, {0x32,0x40,0x4c,0xb0,0x0b,0x2c,0x00,0xcb,0x80,0x32,0xc0,0x0e,0x9e,0x03,0x24,0x00 }, - 16, 0xa080, 0, {0xfb,0x20,0x3e,0xc0,0x0f,0xb0,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa090, 0, {0x48,0x11,0x9c,0x00,0x8d,0x01,0x21,0xc0,0x0b,0x60,0x02,0x1d,0x00,0xd6,0x00,0x21 }, - 16, 0xa0a0, 0, {0x00,0x0b,0xe0,0x02,0x00,0x00,0x83,0x04,0x20,0x40,0x08,0x70,0x42,0x34,0x02,0x87 }, - 16, 0xa0b0, 0, {0x01,0x23,0xc0,0x28,0x51,0x0a,0x1c,0x04,0xb7,0x30,0x2d,0xc0,0x0b,0x72,0x03,0x92 }, - 16, 0xa0c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xa6,0x40,0x21,0xa0 }, - 16, 0xa0d0, 0, {0x0b,0x68,0x02,0x0e,0x00,0x8f,0x80,0x21,0xe0,0x0b,0x78,0x02,0x16,0x10,0xa5,0x80 }, - 16, 0xa0e0, 0, {0x21,0xe0,0x08,0x18,0x02,0x1e,0x00,0x83,0x80,0x21,0xa0,0x08,0x78,0x02,0x1f,0x00 }, - 16, 0xa0f0, 0, {0xb7,0x80,0x2d,0xe0,0x0b,0x38,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa100, 0, {0x48,0x14,0xec,0x12,0xa1,0x64,0x20,0xe6,0x0b,0x20,0x02,0x00,0x10,0x90,0x4a,0x20 }, - 16, 0xa110, 0, {0x20,0x4b,0x00,0x42,0x04,0x00,0x83,0x00,0x20,0xc2,0x08,0x30,0x02,0x8c,0x00,0x83 }, - 16, 0xa120, 0, {0x04,0x20,0xc0,0x08,0x30,0x02,0x0e,0x00,0xb3,0x00,0x2c,0xe0,0x4b,0x30,0x02,0x92 }, - 16, 0xa130, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xee,0xc0,0x33,0x90 }, - 16, 0xa140, 0, {0x0f,0xa0,0x1b,0x08,0x00,0xca,0x40,0xb2,0x82,0x0f,0xa0,0x0b,0x28,0x02,0xca,0x00 }, - 16, 0xa150, 0, {0xb2,0x90,0xac,0xa0,0x03,0x29,0x00,0xca,0x40,0xb2,0x80,0x8e,0xa4,0x03,0x2a,0x00 }, - 16, 0xa160, 0, {0xfa,0x00,0x3f,0xa8,0x0f,0xa0,0x0b,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa170, 0, {0x48,0x00,0xe2,0x02,0x90,0x00,0x3e,0x00,0x0f,0x88,0x03,0xf1,0x00,0xfc,0x02,0x3f }, - 16, 0xa180, 0, {0x20,0x0f,0xc8,0x03,0xc1,0x00,0xf0,0x00,0x3e,0x00,0x8f,0x00,0x01,0x60,0x02,0xf8 }, - 16, 0xa190, 0, {0x08,0x3e,0x00,0x0f,0x80,0x83,0xe0,0x00,0xf8,0x00,0x2e,0x00,0x8f,0x80,0x13,0x92 }, - 16, 0xa1a0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x00,0xb2,0x64 }, - 16, 0xa1b0, 0, {0x0f,0x91,0x03,0xe4,0x04,0xc9,0x00,0x32,0x40,0x6c,0x90,0x03,0x25,0x02,0xc9,0x90 }, - 16, 0xa1c0, 0, {0xb0,0x40,0x0c,0x90,0x03,0x24,0x20,0xc9,0xa0,0x3e,0x40,0x4c,0x90,0x23,0xe4,0x00 }, - 16, 0xa1d0, 0, {0xf1,0x00,0x92,0x40,0x0c,0x10,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa1e0, 0, {0x80,0x04,0x64,0x00,0x89,0x80,0xa2,0x40,0x0b,0x96,0x42,0xe5,0x04,0x89,0x00,0x22 }, - 16, 0xa1f0, 0, {0x40,0x08,0x90,0x02,0x24,0x08,0x09,0x41,0x22,0x40,0x48,0x90,0x42,0x24,0x04,0x89 }, - 16, 0xa200, 0, {0x80,0x26,0x40,0x08,0x90,0x02,0xe4,0x00,0xb9,0x00,0x22,0x40,0x08,0x94,0x02,0x20 }, - 16, 0xa210, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x25,0x00,0x89,0x20,0x22,0x40 }, - 16, 0xa220, 0, {0x0b,0x90,0x02,0xf4,0x84,0x85,0x00,0x21,0x40,0x48,0x50,0x02,0x24,0x20,0x8d,0x08 }, - 16, 0xa230, 0, {0x23,0x40,0x08,0xd0,0x02,0x94,0x00,0x8d,0x00,0x29,0x40,0x0a,0xd0,0x02,0xa4,0x08 }, - 16, 0xa240, 0, {0xb9,0x00,0x28,0x40,0x18,0x90,0xc2,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa250, 0, {0x08,0x04,0x05,0x00,0x81,0x00,0x20,0x51,0x0b,0x10,0x02,0xf5,0x80,0x85,0xc1,0xa1 }, - 16, 0xa260, 0, {0x50,0x08,0x54,0x0a,0x05,0x06,0x85,0x40,0x21,0x50,0x88,0x54,0x02,0x95,0x00,0x85 }, - 16, 0xa270, 0, {0x44,0x2d,0x50,0x2a,0x54,0x12,0xc5,0x01,0xb1,0x00,0x08,0x50,0x08,0x10,0x02,0x02 }, - 16, 0xa280, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xca,0x50,0x32,0x80 }, - 16, 0xa290, 0, {0x0f,0x80,0x03,0xe8,0x02,0xc8,0x01,0x32,0x00,0x2c,0xc0,0x03,0x20,0x00,0xc8,0x02 }, - 16, 0xa2a0, 0, {0x32,0x00,0x2c,0x80,0x0b,0xa0,0x00,0xc8,0x00,0x3a,0x00,0x4e,0x40,0x23,0xa0,0x08 }, - 16, 0xa2b0, 0, {0xf8,0x00,0x3a,0x00,0x2c,0x80,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa2c0, 0, {0x98,0x1d,0xdc,0x04,0xfd,0x40,0x3f,0x50,0x4f,0x90,0x63,0xe4,0x40,0xf1,0x02,0x3e }, - 16, 0xa2d0, 0, {0x41,0x0f,0x90,0x13,0xf5,0x04,0xf9,0x41,0x3e,0x50,0x0f,0x94,0x43,0x65,0x02,0xf9 }, - 16, 0xa2e0, 0, {0x41,0x36,0x50,0x4d,0x94,0x03,0xf4,0x00,0xf9,0x41,0x37,0x40,0x4f,0x94,0x03,0xe6 }, - 16, 0xa2f0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xfc,0x00,0xcd,0xa8,0x33,0x70 }, - 16, 0xa300, 0, {0x0f,0xd0,0x13,0xf6,0x88,0xcd,0x00,0x32,0x50,0x4f,0x14,0x23,0x07,0xa0,0xc9,0xc0 }, - 16, 0xa310, 0, {0x32,0x78,0x0c,0x9e,0x03,0x37,0x02,0xcd,0xc0,0x32,0x64,0x0f,0x98,0x03,0x24,0x00 }, - 16, 0xa320, 0, {0xcd,0x00,0x32,0x40,0x2c,0xda,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa330, 0, {0x38,0x10,0xe2,0x08,0x88,0xeb,0x22,0x30,0x0b,0x80,0x12,0xe8,0x04,0xa0,0xa0,0x2a }, - 16, 0xa340, 0, {0x20,0x0b,0x8a,0x0a,0x23,0x00,0x88,0x80,0x22,0x28,0x00,0xc8,0x42,0x23,0x80,0x80 }, - 16, 0xa350, 0, {0xd4,0x20,0x28,0x09,0x80,0x02,0x22,0x94,0xa8,0x00,0x2a,0x00,0x88,0x85,0x02,0x0e }, - 16, 0xa360, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0xa0,0x83,0x00,0x24,0xd8 }, - 16, 0xa370, 0, {0x8b,0x10,0x02,0xe5,0x14,0x89,0x0a,0x21,0x48,0x0b,0x52,0x02,0x54,0x80,0x85,0x40 }, - 16, 0xa380, 0, {0x25,0x58,0x09,0x56,0x02,0x45,0x02,0x81,0x20,0x20,0x50,0x0b,0x14,0x02,0x04,0x30 }, - 16, 0xa390, 0, {0x81,0x00,0x20,0x40,0x08,0x10,0x02,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa3a0, 0, {0x18,0x15,0xa4,0x12,0x89,0x00,0xa6,0x40,0x0b,0x90,0x42,0xe4,0x98,0xa9,0x80,0x2b }, - 16, 0xa3b0, 0, {0x40,0x0b,0x51,0x02,0x55,0x00,0x9d,0x08,0x27,0x48,0x09,0xf6,0x02,0x44,0x00,0x81 }, - 16, 0xa3c0, 0, {0x04,0x22,0x40,0x19,0x91,0x8a,0x24,0x80,0xa9,0x00,0x2a,0x40,0x08,0x90,0x02,0x46 }, - 16, 0xa3d0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x02,0xc9,0x04,0x36,0x58 }, - 16, 0xa3e0, 0, {0x0f,0x90,0x03,0xc5,0x00,0xc9,0x00,0x32,0x40,0x0f,0x90,0x13,0x64,0x02,0xc9,0x00 }, - 16, 0xa3f0, 0, {0x36,0x40,0x2d,0x90,0x0b,0x66,0x04,0xc9,0xe0,0xb2,0x48,0x8f,0x98,0x47,0x24,0x00 }, - 16, 0xa400, 0, {0xc9,0x00,0x72,0x40,0x0c,0x10,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa410, 0, {0x28,0x01,0xa5,0x08,0xf9,0x21,0x3a,0x40,0x0f,0x90,0x03,0xe6,0x04,0xf9,0x00,0x3e }, - 16, 0xa420, 0, {0x40,0x4f,0x98,0x83,0xa4,0x00,0xe9,0x40,0xba,0x60,0x0e,0x90,0x03,0xa4,0x80,0xf9 }, - 16, 0xa430, 0, {0xa3,0x3e,0x48,0x0f,0x98,0x0b,0xe4,0x00,0xf9,0x00,0x1e,0x40,0x0f,0x90,0x03,0x8a }, - 16, 0xa440, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa2,0x48,0xc8,0x20,0x32,0x08 }, - 16, 0xa450, 0, {0x1f,0x80,0x83,0xe1,0x22,0xc8,0x01,0x33,0x00,0x2c,0xc0,0x03,0x30,0x04,0xcc,0x40 }, - 16, 0xa460, 0, {0xb1,0x00,0x0c,0x44,0x03,0x20,0x12,0xc8,0x41,0x32,0x00,0x2d,0x84,0x0b,0x60,0x00 }, - 16, 0xa470, 0, {0xf8,0x00,0xb2,0x00,0x4c,0x80,0x0b,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa480, 0, {0x28,0x05,0x3a,0x00,0xa6,0x00,0x23,0x90,0x03,0xe4,0x92,0xf8,0x00,0x82,0x00,0x36 }, - 16, 0xa490, 0, {0x80,0x08,0xa0,0x03,0x68,0x00,0xca,0x00,0x22,0x83,0x08,0xa0,0x02,0x28,0x03,0x8a }, - 16, 0xa4a0, 0, {0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0xb6,0x80,0x22,0x80,0x0d,0xe8,0x02,0x0a }, - 16, 0xa4b0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6e,0x00,0x82,0x42,0x20,0xc0 }, - 16, 0xa4c0, 0, {0x0b,0x34,0x02,0xcd,0x09,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x02,0x98,0x00 }, - 16, 0xa4d0, 0, {0x20,0x20,0x28,0x00,0x0a,0x04,0x10,0x81,0x80,0x20,0xc0,0x08,0xb0,0x02,0x2c,0x00 }, - 16, 0xa4e0, 0, {0xb3,0x00,0x22,0xc0,0x18,0x31,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa4f0, 0, {0xa0,0x01,0x38,0x02,0xa3,0x00,0x21,0x40,0x1b,0x70,0x02,0xdc,0x20,0x84,0x05,0x65 }, - 16, 0xa500, 0, {0xe0,0x08,0xf0,0x02,0x7c,0x10,0x97,0x00,0x24,0xc0,0x08,0x30,0x02,0x54,0x88,0x87 }, - 16, 0xa510, 0, {0x09,0x21,0xe8,0x09,0x33,0x02,0x1c,0x80,0xb6,0x08,0x63,0xc8,0x09,0x38,0x12,0x28 }, - 16, 0xa520, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0xa0,0xa1,0xe0 }, - 16, 0xa530, 0, {0x0b,0x78,0x03,0xfe,0x00,0xc5,0x82,0x33,0x20,0x0c,0x48,0x03,0x1e,0x01,0xdf,0x80 }, - 16, 0xa540, 0, {0x31,0x20,0x0c,0x48,0x03,0x06,0x40,0x87,0x82,0x31,0xf8,0x0d,0x7b,0x03,0x5f,0x00 }, - 16, 0xa550, 0, {0xf3,0x80,0x31,0xf2,0x0c,0x60,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa560, 0, {0x08,0x1d,0x9c,0x00,0xfb,0x01,0x2f,0x40,0x07,0xb0,0x03,0xe8,0x04,0xf9,0x00,0x3e }, - 16, 0xa570, 0, {0xc1,0x0f,0xb0,0x03,0xe0,0x06,0xe8,0x02,0x3a,0xc0,0x0f,0xb0,0x01,0xa4,0x10,0xf9 }, - 16, 0xa580, 0, {0x40,0xbe,0xd0,0x06,0xb0,0x03,0xee,0x00,0xfa,0x00,0x3c,0xd8,0x0f,0xa0,0x03,0xc2 }, - 16, 0xa590, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xcf,0x88,0x33,0x64 }, - 16, 0xa5a0, 0, {0x2c,0xf8,0x03,0xfe,0x02,0xc4,0xb0,0x33,0x20,0x8c,0xd8,0x03,0x32,0x00,0xcc,0xb4 }, - 16, 0xa5b0, 0, {0x33,0xa0,0x0c,0xc8,0x03,0x16,0x20,0xcf,0xc0,0x33,0xf0,0x0c,0xf8,0x03,0xfe,0x00 }, - 16, 0xa5c0, 0, {0xcd,0x80,0x3f,0xe0,0x0f,0xd8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa5d0, 0, {0xa8,0x11,0xb5,0x04,0x87,0x12,0xa1,0x50,0x0a,0x74,0x12,0xc4,0x40,0x84,0x11,0x23 }, - 16, 0xa5e0, 0, {0xc0,0x28,0xe0,0x02,0x1c,0x02,0xa7,0x11,0x21,0x58,0x48,0x70,0x0a,0x14,0x00,0x8d }, - 16, 0xa5f0, 0, {0x00,0x23,0xc0,0x0b,0x70,0x02,0xfc,0x40,0x86,0x00,0x2d,0xc0,0x0b,0x50,0x02,0x2a }, - 16, 0xa600, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x00,0x87,0x40,0x21,0x00 }, - 16, 0xa610, 0, {0x18,0x71,0x02,0xdc,0x00,0x95,0x28,0xe1,0x02,0x08,0x50,0x02,0x3c,0x42,0xa7,0x22 }, - 16, 0xa620, 0, {0x21,0x80,0x88,0x41,0x02,0x14,0x00,0x85,0x00,0xa1,0xc0,0x09,0x71,0x02,0xdc,0x00 }, - 16, 0xa630, 0, {0xb5,0x10,0x2d,0xc0,0x0b,0x40,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa640, 0, {0x20,0x14,0xc4,0x10,0x83,0x84,0x20,0x11,0x08,0x30,0x02,0xc3,0x10,0x91,0x20,0x20 }, - 16, 0xa650, 0, {0xc0,0x08,0x28,0x12,0x00,0x00,0xa0,0x84,0x20,0x40,0x08,0x30,0x02,0x04,0x26,0x83 }, - 16, 0xa660, 0, {0x00,0x20,0xd0,0x0b,0x30,0x02,0xcc,0x00,0xb2,0x00,0x2c,0xc0,0x0b,0x00,0x02,0x08 }, - 16, 0xa670, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xad,0x00,0xcf,0x88,0xb2,0xe8 }, - 16, 0xa680, 0, {0x0c,0x30,0x13,0xce,0xc2,0xd0,0x82,0x32,0x00,0x0c,0x0e,0x0b,0x20,0x00,0xc8,0x88 }, - 16, 0xa690, 0, {0xb2,0x40,0x2c,0xba,0x43,0x37,0x02,0xcb,0x00,0xb3,0xc0,0x2c,0xf0,0x03,0xfc,0x12 }, - 16, 0xa6a0, 0, {0xfb,0x00,0x7f,0xd1,0x0f,0x30,0x0b,0x2b,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa6b0, 0, {0x80,0x00,0xed,0x02,0xf1,0x40,0x3e,0x41,0x0f,0xb0,0x23,0xed,0x00,0xe8,0x01,0x3e }, - 16, 0xa6c0, 0, {0xc8,0x0f,0xb0,0x13,0xec,0x04,0xdb,0x00,0x3c,0x80,0x0f,0x04,0x03,0xe4,0x40,0xf9 }, - 16, 0xa6d0, 0, {0x00,0x3c,0xc2,0x0e,0xb0,0x03,0xee,0x00,0x4b,0x41,0x3e,0xc0,0x0f,0xb0,0x03,0xe0 }, - 16, 0xa6e0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0x4b,0x00,0x32,0x42 }, - 16, 0xa6f0, 0, {0x0c,0xf0,0x03,0x36,0x80,0xcd,0x00,0x33,0x00,0x4c,0xc0,0x83,0x3c,0x04,0xf7,0x00 }, - 16, 0xa700, 0, {0x32,0x40,0x0c,0xb1,0x43,0x14,0x00,0xcd,0x80,0x33,0xc0,0x0c,0xf0,0x03,0xfc,0x00 }, - 16, 0xa710, 0, {0xff,0x00,0xb3,0xc2,0x0c,0xa0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa720, 0, {0x81,0x04,0x4f,0x02,0x8b,0x80,0x20,0x30,0x08,0xbc,0x02,0x20,0x10,0x89,0x00,0x22 }, - 16, 0xa730, 0, {0xc0,0x00,0xb0,0x03,0x60,0x04,0xb8,0x00,0xa2,0x90,0x28,0x8c,0x1a,0x24,0x02,0x8b }, - 16, 0xa740, 0, {0x83,0x22,0xc1,0x08,0xb0,0x02,0xfc,0x00,0xb3,0x60,0x20,0xc0,0x0d,0xa0,0x03,0xe0 }, - 16, 0xa750, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2e,0x00,0xab,0xc0,0x22,0x60 }, - 16, 0xa760, 0, {0x08,0xb8,0x02,0x29,0x00,0x88,0x01,0x20,0x00,0x08,0x90,0x02,0x20,0x00,0xb8,0x00 }, - 16, 0xa770, 0, {0x22,0xc0,0x08,0xb0,0x02,0xe4,0x00,0x81,0x24,0xa2,0xc0,0x09,0xb0,0x46,0xec,0x00 }, - 16, 0xa780, 0, {0xb9,0x00,0x22,0xc0,0x08,0x90,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa790, 0, {0x08,0x04,0x2c,0x00,0xa1,0x00,0xa0,0x41,0x08,0xb0,0x0a,0x20,0x53,0x88,0x00,0x20 }, - 16, 0xa7a0, 0, {0xc0,0x28,0xa0,0x02,0x4c,0x00,0xb3,0x00,0x20,0x00,0x88,0x00,0x02,0x84,0x00,0x83 }, - 16, 0xa7b0, 0, {0x04,0x20,0xc0,0x28,0x30,0x02,0xcc,0x00,0xb3,0x02,0x62,0xc0,0x09,0x10,0x02,0xc2 }, - 16, 0xa7c0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xe9,0x00,0x22,0x00 }, - 16, 0xa7d0, 0, {0x0c,0xb0,0x03,0x00,0x04,0xc9,0x00,0xb2,0x00,0x0c,0x90,0x03,0x2c,0x00,0xf3,0x00 }, - 16, 0xa7e0, 0, {0xb2,0xc0,0x8c,0xb0,0x03,0xb4,0x02,0x8f,0x00,0x23,0xc0,0x04,0xf0,0x03,0xec,0x08 }, - 16, 0xa7f0, 0, {0xf9,0x00,0x33,0xc0,0x0c,0x80,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa800, 0, {0xa0,0x1d,0xfc,0x10,0xdd,0x04,0x3f,0x00,0x0f,0xc0,0x23,0xf0,0x90,0xfd,0x00,0x2f }, - 16, 0xa810, 0, {0xc0,0x0f,0xe0,0x43,0xd0,0x00,0xfc,0x00,0x3f,0x00,0x8f,0xc0,0x22,0x74,0x00,0xfd }, - 16, 0xa820, 0, {0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x06,0x3f,0xc0,0x0f,0xc0,0x43,0xe8 }, - 16, 0xa830, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x80,0xef,0x20,0x11,0xc0 }, - 16, 0xa840, 0, {0x0e,0x72,0x03,0xbd,0xb0,0xcf,0x31,0xbf,0xcc,0x02,0xf0,0x03,0xfc,0xc6,0xcf,0x01 }, - 16, 0xa850, 0, {0x0b,0xc5,0x0f,0xf1,0x03,0x3c,0x04,0xef,0x61,0x33,0xd8,0x07,0xf0,0x03,0x34,0x80 }, - 16, 0xa860, 0, {0xcd,0x30,0x73,0xcc,0x0f,0xe8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa870, 0, {0x80,0x18,0xe9,0x00,0x88,0x69,0x22,0x10,0x08,0x8c,0x00,0x21,0x84,0x88,0x41,0x22 }, - 16, 0xa880, 0, {0x10,0x88,0x86,0x92,0x01,0x00,0x88,0x62,0x22,0x10,0x4b,0x87,0x02,0x21,0xa0,0x88 }, - 16, 0xa890, 0, {0x60,0x20,0x10,0x0b,0x86,0xa2,0x35,0xa0,0xab,0x60,0xa1,0xc4,0x0b,0xb8,0x02,0x20 }, - 16, 0xa8a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcd,0xa8,0x33,0x41,0x20,0xc6 }, - 16, 0xa8b0, 0, {0x4a,0x31,0x00,0x8c,0x10,0x93,0x33,0x28,0xcc,0x29,0x34,0x12,0x8c,0x50,0x93,0x1c }, - 16, 0xa8c0, 0, {0x28,0x84,0x01,0x20,0x4a,0x4c,0x41,0x83,0x10,0x24,0xcc,0x4b,0x31,0x42,0x4c,0x40 }, - 16, 0xa8d0, 0, {0x91,0x10,0x24,0xc0,0x0b,0x80,0x02,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa8e0, 0, {0xc0,0x05,0xa8,0x20,0x90,0x02,0x22,0x00,0x08,0x80,0x00,0x20,0x30,0xb8,0x08,0x26 }, - 16, 0xa8f0, 0, {0x00,0x01,0x80,0x82,0x20,0x20,0x18,0x08,0x42,0x40,0x03,0x91,0x02,0x60,0x00,0x08 }, - 16, 0xa900, 0, {0x01,0xa6,0x00,0x0b,0x80,0x00,0x6c,0x10,0xbb,0x01,0x26,0xc0,0x4b,0x90,0x0a,0x30 }, - 16, 0xa910, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xfd,0x00,0xfd,0x41,0x33,0xa1 }, - 16, 0xa920, 0, {0x0e,0xd2,0x03,0xb5,0x02,0xdf,0x42,0x3b,0x01,0x0f,0xd4,0x43,0xb5,0x00,0xcd,0x40 }, - 16, 0xa930, 0, {0x1b,0xc4,0x0d,0x78,0x03,0x70,0x02,0xec,0x00,0x17,0xa1,0x0f,0xe8,0x0b,0x2c,0x02 }, - 16, 0xa940, 0, {0xd9,0x90,0x26,0xc0,0x0f,0xac,0x03,0x00,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa950, 0, {0xe0,0x01,0xb8,0x00,0xee,0x00,0x1f,0x64,0x4f,0xe0,0x03,0xd8,0x10,0xc4,0x18,0x33 }, - 16, 0xa960, 0, {0xc0,0x0c,0xa0,0xa1,0xb8,0x09,0xe6,0x09,0x36,0x22,0x0f,0x88,0x23,0xbc,0x00,0xfb }, - 16, 0xa970, 0, {0x00,0x3b,0x64,0x0f,0xd9,0x03,0x9c,0x00,0xe3,0x04,0x3b,0xc0,0x0f,0xf4,0x03,0xf8 }, - 16, 0xa980, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8d,0x00,0xc9,0x40,0xb6,0x80 }, - 16, 0xa990, 0, {0x0f,0x10,0x03,0xa7,0x20,0xfb,0x50,0xb6,0x08,0x4c,0x14,0x03,0x65,0x22,0xd9,0x40 }, - 16, 0xa9a0, 0, {0xb6,0x80,0x0e,0xa0,0x0b,0x00,0x00,0xd8,0x00,0x76,0x82,0x28,0xa0,0x23,0x64,0x00 }, - 16, 0xa9b0, 0, {0xc9,0x04,0x12,0xc0,0x8e,0x80,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xa9c0, 0, {0xc8,0x05,0x2b,0x60,0x8a,0x09,0x20,0x50,0x08,0xa0,0x23,0xe9,0x00,0xb8,0xc0,0x22 }, - 16, 0xa9d0, 0, {0xf0,0x08,0xac,0x02,0x28,0x04,0x8a,0xc2,0x22,0x50,0x08,0x90,0x06,0x2c,0x00,0x8b }, - 16, 0xa9e0, 0, {0x04,0x22,0x51,0x08,0x94,0x02,0xe4,0x04,0x8b,0x04,0x37,0xc0,0x08,0x18,0x42,0x26 }, - 16, 0xa9f0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x04,0x4b,0x00,0x82,0xc8,0x24,0x43 }, - 16, 0xaa00, 0, {0x0b,0x26,0x0a,0x88,0x00,0xb0,0x80,0x22,0xe4,0x0b,0x20,0x42,0x69,0x00,0xa2,0x90 }, - 16, 0xaa10, 0, {0x28,0x40,0xe8,0x10,0x02,0x0c,0x00,0xbb,0x00,0x28,0x50,0x88,0x90,0x82,0xc4,0x01 }, - 16, 0xaa20, 0, {0x83,0x00,0x20,0xc0,0x0a,0x10,0x02,0xba,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaa30, 0, {0x20,0x10,0x4e,0x80,0x81,0x00,0x21,0xa8,0x08,0x58,0x02,0xd6,0x01,0xb7,0x90,0x68 }, - 16, 0xaa40, 0, {0x20,0x03,0x59,0x82,0x56,0x00,0xa5,0x84,0x2d,0xa2,0x18,0x69,0x22,0x02,0x00,0x34 }, - 16, 0xaa50, 0, {0x80,0x29,0xa8,0x08,0x68,0x06,0xc6,0x14,0x85,0x82,0x25,0xe0,0x08,0x58,0x82,0x1c }, - 16, 0xaa60, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x48,0x00,0xc2,0xf0,0x34,0x40 }, - 16, 0xaa70, 0, {0x0f,0x20,0x03,0x88,0x80,0xf8,0x10,0x30,0xc0,0x27,0x21,0x0b,0x48,0x80,0xea,0x20 }, - 16, 0xaa80, 0, {0x38,0x00,0x0c,0x00,0x12,0x0c,0x08,0x73,0x00,0xb8,0x40,0x0c,0x12,0x23,0x4c,0x02 }, - 16, 0xaa90, 0, {0x43,0x34,0x30,0xc0,0x0e,0x11,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaaa0, 0, {0x40,0x15,0xac,0x90,0xf9,0x01,0x2e,0x88,0x4b,0x90,0x11,0x64,0x00,0xfb,0x10,0x32 }, - 16, 0xaab0, 0, {0x00,0x00,0x91,0x03,0xa4,0x00,0xc9,0x00,0x32,0xc4,0x4d,0xb0,0x43,0xe0,0x04,0xc8 }, - 16, 0xaac0, 0, {0x00,0x36,0x89,0x0f,0xa8,0x03,0xed,0x00,0xf9,0x14,0x3e,0xc0,0x0f,0x10,0x43,0xd0 }, - 16, 0xaad0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xe8,0x00,0xc8,0x00,0x3a,0x00 }, - 16, 0xaae0, 0, {0x0c,0x00,0x53,0xa0,0x00,0xe8,0x01,0x32,0x01,0x0e,0x80,0x53,0x20,0x10,0xc8,0x00 }, - 16, 0xaaf0, 0, {0x3a,0x40,0x0c,0x90,0x03,0x20,0x10,0xe8,0x04,0xb6,0x00,0x84,0x80,0x03,0x2d,0x12 }, - 16, 0xab00, 0, {0xcb,0x00,0x2e,0xca,0x04,0x90,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xab10, 0, {0x4c,0x19,0x8c,0x00,0x87,0x02,0x21,0xc0,0x08,0x70,0x02,0x0c,0x00,0x83,0x00,0x21 }, - 16, 0xab20, 0, {0xc0,0x08,0x30,0x62,0x4c,0x04,0x83,0x00,0x21,0x80,0x48,0xe0,0x12,0x3c,0x00,0x87 }, - 16, 0xab30, 0, {0x00,0x21,0xc0,0x08,0x70,0x02,0x1c,0x00,0x85,0x01,0x24,0xd0,0x0a,0x50,0x02,0xf2 }, - 16, 0xab40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x9a,0x00,0x80,0x80,0x28,0x20 }, - 16, 0xab50, 0, {0x08,0x4c,0x22,0xd2,0x00,0xa4,0x80,0x24,0x30,0x0b,0x48,0x02,0x52,0x00,0x84,0xc0 }, - 16, 0xab60, 0, {0x21,0x20,0x09,0x48,0x68,0x13,0x00,0xa4,0x80,0x60,0x20,0x09,0x08,0x02,0x56,0x00 }, - 16, 0xab70, 0, {0x97,0x80,0x2d,0xe0,0x88,0x58,0x02,0xe0,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xab80, 0, {0x6c,0x04,0xcc,0x00,0x83,0x80,0x20,0xd8,0x08,0x30,0x02,0x4c,0x40,0x83,0x00,0x24 }, - 16, 0xab90, 0, {0xd1,0x09,0xb9,0x42,0x4e,0x00,0x83,0x00,0x20,0xc1,0x89,0x30,0x42,0x0c,0x00,0x83 }, - 16, 0xaba0, 0, {0xf0,0xa0,0xd9,0x19,0x36,0x22,0x66,0x06,0x91,0x00,0x0c,0xc1,0x0a,0x10,0x02,0xc2 }, - 16, 0xabb0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xe8,0x02,0xca,0xa5,0x2a,0x91 }, - 16, 0xabc0, 0, {0x28,0xa8,0x03,0xea,0x02,0xaa,0x00,0xb6,0xa0,0x0f,0xa0,0x0a,0x2a,0x92,0xca,0x83 }, - 16, 0xabd0, 0, {0xba,0x80,0x29,0xa0,0x03,0x2b,0x00,0xea,0x40,0x66,0x90,0x2d,0xe4,0x0b,0x6a,0x80 }, - 16, 0xabe0, 0, {0xda,0x00,0x3e,0x80,0x0c,0xe0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xabf0, 0, {0x48,0x01,0x80,0x00,0xfc,0x00,0x3d,0x00,0x0f,0xc0,0x03,0xb0,0x14,0xfc,0x00,0x3b }, - 16, 0xac00, 0, {0x12,0x0e,0xc0,0x43,0xb1,0x14,0xfc,0x00,0x3d,0x00,0x0e,0xc0,0x03,0xf0,0x20,0xf4 }, - 16, 0xac10, 0, {0x00,0x31,0x00,0x0e,0x44,0x13,0xa0,0x00,0xe8,0x06,0x36,0x00,0x4f,0x80,0x13,0xd2 }, - 16, 0xac20, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xd1,0x00,0x36,0x60 }, - 16, 0xac30, 0, {0x1c,0x18,0x0b,0x46,0x00,0xd9,0x80,0x30,0x40,0x2c,0x98,0x05,0x86,0x00,0xc1,0x80 }, - 16, 0xac40, 0, {0x92,0x40,0x0d,0x10,0x03,0x44,0x02,0x89,0x00,0x32,0x70,0x0c,0x98,0x01,0x24,0x00 }, - 16, 0xac50, 0, {0xc9,0x04,0x30,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xac60, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x40,0x08,0x94,0x02,0x24,0x80,0x89,0x01,0x22 }, - 16, 0xac70, 0, {0x40,0x48,0x91,0x02,0x24,0x00,0xd9,0x90,0x22,0x41,0x08,0x90,0x12,0x24,0x10,0x89 }, - 16, 0xac80, 0, {0x00,0x32,0x40,0x08,0x95,0x12,0x24,0x02,0x81,0x00,0xa2,0x41,0x0d,0x90,0x42,0xe0 }, - 16, 0xac90, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x05,0x24,0x02,0x9d,0x00,0x23,0x44 }, - 16, 0xaca0, 0, {0x08,0xd2,0x06,0x74,0x80,0xb5,0x20,0x23,0x40,0x1a,0xd0,0x06,0x35,0x90,0x8d,0x02 }, - 16, 0xacb0, 0, {0x2f,0x44,0x19,0xd0,0x02,0x74,0x00,0x8d,0x00,0x63,0x40,0x18,0xd4,0x02,0xa4,0x11 }, - 16, 0xacc0, 0, {0x89,0x00,0x22,0x40,0x08,0xb0,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xacd0, 0, {0x28,0x14,0x04,0x80,0x85,0x20,0x21,0x68,0x08,0x52,0x02,0x14,0x80,0xa5,0x20,0xa1 }, - 16, 0xace0, 0, {0x48,0x0a,0x72,0x38,0x14,0x80,0x95,0x24,0x2d,0x48,0x28,0x52,0x02,0x14,0x80,0x85 }, - 16, 0xacf0, 0, {0x20,0x21,0x48,0x08,0x52,0x06,0x84,0x80,0x81,0x20,0x20,0x4a,0x09,0x10,0x02,0xc2 }, - 16, 0xad00, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x0d,0x61,0x40,0xd8,0x50,0xb2,0x14 }, - 16, 0xad10, 0, {0x28,0xa0,0x03,0x61,0x40,0xf8,0x50,0x32,0x94,0x4e,0x85,0x04,0x21,0x42,0xc8,0x50 }, - 16, 0xad20, 0, {0x3c,0x14,0x0d,0x80,0x03,0x61,0x40,0x88,0x50,0xb2,0x14,0x2c,0xc5,0x09,0xa1,0x40 }, - 16, 0xad30, 0, {0xc8,0x50,0x32,0x1c,0x0c,0x80,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xad40, 0, {0x98,0x15,0xe4,0x40,0xf9,0x10,0x3a,0x44,0x0f,0x91,0x03,0xe4,0x40,0xd9,0x14,0x3e }, - 16, 0xad50, 0, {0x44,0x0d,0x91,0x43,0x64,0x40,0xe9,0x10,0x32,0x44,0x07,0x93,0xc3,0xe4,0x50,0xd1 }, - 16, 0xad60, 0, {0x10,0x7e,0x44,0x03,0x91,0x01,0x54,0x44,0xfd,0x14,0x3e,0x40,0x0f,0xd0,0x03,0xe6 }, - 16, 0xad70, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x80,0xdd,0xa0,0x33,0x68 }, - 16, 0xad80, 0, {0x1e,0xda,0x03,0x36,0x90,0xcd,0xa0,0x3b,0x68,0x0a,0xd8,0x23,0x76,0x0c,0xed,0x80 }, - 16, 0xad90, 0, {0x2b,0x62,0x0b,0x99,0x02,0xa7,0x80,0xf9,0xe1,0x37,0x68,0x0c,0xda,0x03,0x27,0x80 }, - 16, 0xada0, 0, {0xc9,0xa2,0x22,0x68,0x4c,0x50,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xadb0, 0, {0x38,0x18,0xe1,0x40,0x88,0x50,0x22,0x14,0x08,0x80,0x22,0x60,0x00,0x88,0x04,0x22 }, - 16, 0xadc0, 0, {0x00,0x08,0x04,0x26,0x01,0x00,0x88,0x50,0x22,0x10,0x08,0xaf,0x02,0x23,0x00,0x88 }, - 16, 0xadd0, 0, {0xc0,0xa0,0x10,0x88,0x84,0x02,0x23,0x80,0xa0,0x40,0x2a,0x10,0x08,0x80,0x12,0x4e }, - 16, 0xade0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x00,0x81,0x01,0x20,0x40 }, - 16, 0xadf0, 0, {0x0a,0x14,0x02,0x45,0x00,0x81,0x41,0x2c,0x50,0x0b,0x14,0x02,0x05,0x04,0xa1,0x00 }, - 16, 0xae00, 0, {0x28,0x40,0x82,0x10,0x02,0x84,0x40,0xa1,0x32,0x80,0x50,0x09,0x14,0x02,0x04,0xc4 }, - 16, 0xae10, 0, {0x91,0x10,0x64,0x44,0x28,0x10,0x02,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xae20, 0, {0x18,0x04,0xac,0x02,0x81,0x00,0x22,0xc1,0x08,0x90,0x02,0x44,0x02,0x89,0x02,0x26 }, - 16, 0xae30, 0, {0x41,0x09,0x90,0x0a,0x24,0x0c,0x89,0x04,0x22,0x50,0x08,0x90,0x26,0x24,0x00,0x89 }, - 16, 0xae40, 0, {0x00,0x22,0x41,0x09,0x10,0x22,0x24,0x40,0xb9,0x01,0x2e,0x40,0x08,0x90,0x02,0x46 }, - 16, 0xae50, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x10,0x89,0x00,0x32,0x40 }, - 16, 0xae60, 0, {0x0a,0x90,0x0b,0x24,0x10,0x89,0x00,0x1e,0x40,0x9b,0x90,0x02,0x24,0x10,0x29,0x00 }, - 16, 0xae70, 0, {0x1a,0x40,0x0e,0x94,0x41,0xa4,0x00,0x29,0x00,0x12,0x40,0x05,0x90,0x41,0x26,0x00 }, - 16, 0xae80, 0, {0xd9,0x00,0x24,0x40,0x0c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xae90, 0, {0x48,0x01,0xa4,0x02,0xa9,0x00,0xbc,0x40,0x0f,0x90,0x03,0xa4,0x04,0xf9,0x00,0x3a }, - 16, 0xaea0, 0, {0x41,0x0e,0x90,0x83,0x84,0x00,0xf9,0x00,0x3c,0x40,0x0e,0x90,0x02,0xc4,0x08,0xe9 }, - 16, 0xaeb0, 0, {0x00,0x3a,0x40,0x2e,0x90,0x0b,0xe6,0x00,0xe1,0x04,0x3a,0x40,0x0f,0x92,0x03,0x5a }, - 16, 0xaec0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa0,0x20,0xd8,0x00,0x36,0x02 }, - 16, 0xaed0, 0, {0x0e,0x00,0xa3,0xe0,0x18,0xc0,0x00,0x30,0x03,0x0f,0x80,0x33,0x20,0x00,0x40,0x00 }, - 16, 0xaee0, 0, {0x32,0x0d,0x0f,0x04,0x0b,0xa0,0x02,0xc8,0x02,0x32,0x02,0x8c,0x82,0x03,0x20,0x02 }, - 16, 0xaef0, 0, {0xc8,0x04,0x16,0x00,0x4e,0x80,0x01,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaf00, 0, {0x28,0x05,0x3b,0x00,0x8e,0xd8,0x23,0x80,0x08,0xe0,0x02,0xf8,0x80,0x8e,0x10,0x23 }, - 16, 0xaf10, 0, {0xa2,0x0b,0xe0,0x82,0x7a,0x20,0x8e,0x30,0x23,0xa1,0x0b,0xe0,0x02,0x28,0x00,0x8e }, - 16, 0xaf20, 0, {0x00,0x2b,0x88,0x08,0xe4,0x42,0x38,0x00,0x8e,0x04,0x23,0x80,0x08,0xa0,0x02,0x0a }, - 16, 0xaf30, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6f,0x40,0x93,0xc6,0x24,0x40 }, - 16, 0xaf40, 0, {0x0a,0x38,0x02,0xcc,0x00,0x83,0x01,0xac,0xf0,0x0b,0xb4,0x02,0x4c,0x04,0xa3,0x80 }, - 16, 0xaf50, 0, {0x28,0xd0,0x4b,0x30,0x02,0x4c,0x00,0xab,0x04,0x2a,0xc0,0x2a,0x30,0x0a,0xac,0x10 }, - 16, 0xaf60, 0, {0x93,0x00,0x20,0xc1,0x0a,0x31,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xaf70, 0, {0x80,0x11,0x1c,0x00,0x82,0x00,0x21,0x42,0x88,0x74,0x06,0xdc,0x0b,0x86,0x02,0x2d }, - 16, 0xaf80, 0, {0x80,0x0b,0x70,0x2a,0x58,0x00,0xa6,0x00,0xa9,0xc0,0x0b,0x70,0x02,0x5c,0x88,0xa7 }, - 16, 0xaf90, 0, {0x20,0x29,0xc0,0x0a,0x70,0x02,0x9c,0x10,0x97,0x20,0xa1,0xc8,0x08,0xd8,0x02,0x28 }, - 16, 0xafa0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x08,0x0e,0x00,0xd7,0x80,0x37,0x60 }, - 16, 0xafb0, 0, {0x0e,0x68,0x13,0xfe,0x00,0xcf,0x80,0x3d,0xe0,0x0f,0x78,0x23,0x1e,0x00,0xef,0x82 }, - 16, 0xafc0, 0, {0x31,0xe0,0x0f,0x3c,0xc3,0x7e,0x04,0xef,0x80,0xb1,0xe0,0x0e,0xe8,0x03,0xbe,0x80 }, - 16, 0xafd0, 0, {0xd7,0xe0,0x33,0xea,0x0e,0x78,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xafe0, 0, {0x08,0x15,0xac,0x00,0xfa,0x01,0x3e,0x00,0x0f,0xb0,0x03,0xe0,0x04,0xf8,0x00,0x32 }, - 16, 0xaff0, 0, {0x80,0x0f,0x80,0x43,0xac,0x0a,0xd8,0x00,0x36,0x40,0x0f,0xb0,0x03,0x2c,0x0c,0xdb }, - 16, 0xb000, 0, {0x00,0x26,0xc1,0x09,0xa0,0x13,0x6c,0x40,0xeb,0x40,0x3a,0xdc,0x0f,0x90,0x0b,0xc2 }, - 16, 0xb010, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0xbe,0x00,0xcf,0x81,0x33,0xe9 }, - 16, 0xb020, 0, {0x1f,0xf9,0x13,0xb6,0x50,0xef,0x80,0x1f,0xe4,0x04,0xc8,0x03,0x7e,0x00,0x6d,0x81 }, - 16, 0xb030, 0, {0x33,0x64,0x0c,0xf8,0x1b,0x3e,0x20,0x2f,0x88,0x93,0xe8,0x0f,0xfb,0x03,0x2e,0x80 }, - 16, 0xb040, 0, {0xcf,0xc0,0x73,0xe0,0x2c,0xd9,0x03,0xd0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb050, 0, {0xa8,0x18,0x90,0x42,0x89,0x18,0x21,0xc0,0x1f,0x71,0x02,0x14,0xc0,0xf7,0x20,0x27 }, - 16, 0xb060, 0, {0x40,0x40,0x71,0x12,0x18,0x00,0x87,0x20,0x21,0x80,0x48,0x71,0x02,0x3c,0x08,0x87 }, - 16, 0xb070, 0, {0x20,0x21,0x82,0x0b,0x61,0xa2,0x1e,0x44,0xdf,0x01,0x31,0xc8,0x08,0x73,0x02,0xea }, - 16, 0xb080, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x8c,0x00,0x87,0x00,0x21,0xc8 }, - 16, 0xb090, 0, {0x0b,0x70,0x02,0x9c,0x09,0x87,0x02,0x2d,0x82,0x99,0x40,0x02,0x04,0x00,0xa5,0x09 }, - 16, 0xb0a0, 0, {0x21,0x40,0x19,0x70,0x02,0x1c,0x00,0x87,0x05,0x25,0x48,0x4b,0x72,0x02,0x0c,0x40 }, - 16, 0xb0b0, 0, {0x87,0x00,0xa1,0xc0,0x48,0x50,0x02,0xc4,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb0c0, 0, {0x68,0x04,0xc1,0x20,0x89,0x4c,0xa0,0xb4,0x0a,0x38,0x02,0x22,0x00,0xa1,0xd0,0x24 }, - 16, 0xb0d0, 0, {0x30,0x09,0x80,0x02,0x27,0x44,0x81,0xc6,0x22,0x14,0x09,0x3d,0x2a,0x0f,0x02,0x8b }, - 16, 0xb0e0, 0, {0xc0,0xa6,0x20,0x0b,0x24,0x00,0x0c,0x10,0x93,0x81,0x20,0xc0,0x48,0x30,0x06,0xd8 }, - 16, 0xb0f0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x15,0xa1,0x00,0x89,0xc1,0x32,0xd1 }, - 16, 0xb100, 0, {0x03,0xbc,0x03,0xa9,0x20,0x89,0x41,0x3e,0x60,0x85,0xbc,0x8b,0x25,0x40,0xeb,0x41 }, - 16, 0xb110, 0, {0xa2,0xa0,0x0d,0xf0,0x13,0x3e,0x20,0xcf,0x90,0x36,0x30,0x4f,0xbc,0x0b,0x3c,0x00 }, - 16, 0xb120, 0, {0xcf,0x80,0x33,0xc1,0x0c,0xb1,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb130, 0, {0x80,0x00,0xed,0x00,0xf8,0x01,0x3c,0xd0,0x0f,0xb3,0x03,0xe8,0x82,0xd8,0x20,0x36 }, - 16, 0xb140, 0, {0x80,0x2e,0xb2,0x13,0xe1,0x00,0xfa,0x00,0x7e,0xc8,0x2e,0xb0,0x03,0xec,0x80,0xdb }, - 16, 0xb150, 0, {0x10,0x3a,0x08,0x4f,0xb2,0x23,0xcc,0x02,0xfb,0x10,0x3a,0xc0,0x0f,0x90,0x03,0xe4 }, - 16, 0xb160, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xf0,0x00,0xcd,0x10,0x33,0x42 }, - 16, 0xb170, 0, {0x0c,0xca,0x23,0x7c,0x00,0xcf,0x00,0x33,0x62,0x06,0xf0,0x01,0x3a,0x00,0xcf,0x08 }, - 16, 0xb180, 0, {0x33,0x80,0x1c,0xf0,0x81,0x3c,0x00,0xff,0x00,0x33,0xa0,0x0c,0xca,0x01,0xfc,0x04 }, - 16, 0xb190, 0, {0xcf,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xc0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb1a0, 0, {0xa1,0x04,0x6d,0x40,0x88,0x48,0xa2,0x31,0x08,0x10,0x02,0x20,0x10,0x88,0xb4,0x22 }, - 16, 0xb1b0, 0, {0xa0,0x08,0x80,0x00,0x6a,0x84,0x88,0x20,0x22,0x52,0x08,0xb0,0x0a,0x2c,0x10,0xbb }, - 16, 0xb1c0, 0, {0x00,0x32,0xb3,0x88,0x80,0x02,0xec,0x00,0xdb,0x00,0x2e,0xc0,0x0b,0x90,0x12,0xe1 }, - 16, 0xb1d0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x10,0x8a,0x01,0x22,0xa0 }, - 16, 0xb1e0, 0, {0x08,0xb0,0x42,0x60,0x20,0x80,0x00,0x20,0x44,0x1a,0x80,0x1a,0xe4,0x42,0xa0,0x06 }, - 16, 0xb1f0, 0, {0x22,0x00,0x78,0x30,0x02,0xac,0x00,0xbb,0x00,0xa2,0x44,0x08,0xb0,0x12,0xec,0x00 }, - 16, 0xb200, 0, {0x8b,0x00,0x0e,0xc0,0x0b,0x90,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb210, 0, {0x08,0x14,0x00,0x08,0x80,0x00,0x20,0x81,0x08,0x30,0x02,0x40,0x12,0x80,0x00,0xa0 }, - 16, 0xb220, 0, {0x40,0x08,0xb0,0x02,0xc0,0x00,0x82,0x00,0x00,0x80,0x08,0x30,0x02,0x8c,0x00,0xbb }, - 16, 0xb230, 0, {0x00,0x20,0x00,0x08,0x20,0x02,0xcc,0x80,0x93,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xc2 }, - 16, 0xb240, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xca,0x14,0x32,0x00 }, - 16, 0xb250, 0, {0x0c,0xb0,0x03,0x4c,0x00,0xca,0x00,0x32,0x00,0x0e,0x00,0x12,0xa0,0x00,0xc0,0x00 }, - 16, 0xb260, 0, {0x70,0x00,0x28,0xf0,0x13,0xac,0x00,0xfb,0x00,0x32,0x40,0x2c,0x10,0x43,0xec,0x00 }, - 16, 0xb270, 0, {0xcf,0x00,0x3f,0xc0,0x0f,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb280, 0, {0x20,0x15,0xf0,0x02,0xfc,0x00,0x1f,0x00,0x67,0x70,0x03,0xb0,0x00,0xfc,0x00,0x3f }, - 16, 0xb290, 0, {0x00,0x2d,0xc0,0x03,0x30,0x10,0xfc,0x01,0xbf,0x00,0x0f,0x70,0x03,0x7c,0x00,0xf7 }, - 16, 0xb2a0, 0, {0x04,0x3b,0x00,0x0f,0xc0,0x13,0xfd,0x10,0xff,0x00,0x3d,0xc0,0x0f,0xf0,0x03,0xe8 }, - 16, 0xb2b0, 0, {0x12,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf4,0xc0,0xcf,0x80,0x33,0x60 }, - 16, 0xb2c0, 0, {0x0e,0xc9,0x13,0x36,0x50,0xce,0x86,0x3f,0x08,0x0c,0xc0,0x03,0x3e,0x02,0xd7,0x80 }, - 16, 0xb2d0, 0, {0x39,0xe0,0x0f,0xf8,0x13,0x3e,0x40,0xc7,0x30,0x3b,0xce,0x0d,0xf6,0x03,0x3d,0x88 }, - 16, 0xb2e0, 0, {0xcf,0x31,0x33,0xe4,0x0f,0x78,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb2f0, 0, {0x80,0x10,0xe5,0xd0,0xdb,0x80,0x72,0x60,0x88,0x92,0x02,0xe4,0x10,0x8a,0x80,0x2e }, - 16, 0xb300, 0, {0x34,0x4a,0x8c,0x03,0x2e,0x00,0xab,0x80,0x02,0xe0,0x0b,0xb8,0x02,0x2c,0x80,0x8f }, - 16, 0xb310, 0, {0x60,0x13,0xd8,0x4a,0x76,0x02,0x9d,0x84,0xaf,0x30,0x22,0x48,0x0b,0x88,0x12,0xa0 }, - 16, 0xb320, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x00,0x8b,0x00,0x24,0x00 }, - 16, 0xb330, 0, {0x4a,0x00,0x02,0xac,0x80,0x83,0x00,0x2c,0x01,0x28,0x04,0x02,0xac,0x00,0x8b,0x01 }, - 16, 0xb340, 0, {0x20,0xc0,0x03,0xb0,0x02,0x0c,0x80,0x83,0x40,0x20,0xc1,0xa8,0x34,0x22,0x8d,0x13 }, - 16, 0xb350, 0, {0x83,0x20,0xac,0xc8,0x0b,0xb0,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb360, 0, {0xc0,0x15,0x86,0x00,0x9b,0x04,0xae,0x00,0x0a,0x90,0x02,0xec,0x00,0x0b,0x14,0x2e }, - 16, 0xb370, 0, {0xc6,0x02,0xb1,0x12,0x6c,0x00,0xab,0x20,0x2a,0xc1,0x0b,0xb0,0x42,0x2c,0x00,0x8b }, - 16, 0xb380, 0, {0x02,0x26,0xc1,0x0a,0xb0,0x02,0xac,0x00,0xab,0x04,0x2a,0x40,0x0b,0x90,0x02,0xf0 }, - 16, 0xb390, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xe7,0x00,0xc3,0x01,0x36,0x40 }, - 16, 0xb3a0, 0, {0x0e,0x88,0x13,0x24,0x02,0xca,0x00,0x1e,0x20,0x2c,0x8e,0x0b,0x2c,0x00,0xcb,0x00 }, - 16, 0xb3b0, 0, {0x2a,0xc0,0x0f,0xb8,0x03,0x2e,0x06,0xcb,0x00,0x3a,0xc0,0x4c,0xb0,0x13,0xac,0x0c }, - 16, 0xb3c0, 0, {0xcb,0x00,0x3e,0xc8,0x0f,0xb0,0x43,0x50,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb3d0, 0, {0xe0,0x01,0xb4,0x08,0xff,0x91,0x33,0x40,0x09,0xdc,0x01,0xf4,0x20,0x7e,0x02,0x2e }, - 16, 0xb3e0, 0, {0x40,0x0d,0x98,0x01,0xbc,0x80,0xef,0x80,0xb7,0xe4,0x8f,0xf4,0x0b,0xfe,0x40,0x7f }, - 16, 0xb3f0, 0, {0x00,0xb9,0xc0,0x4e,0xf0,0x03,0xfc,0x08,0xf7,0x00,0x37,0xc0,0x0f,0xe0,0x02,0xb8 }, - 16, 0xb400, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa1,0x44,0xcb,0x02,0x32,0x00 }, - 16, 0xb410, 0, {0x0d,0x80,0x0a,0x6d,0x00,0xeb,0x04,0x10,0x90,0x28,0x22,0x0b,0x2c,0xc2,0xcb,0x20 }, - 16, 0xb420, 0, {0x76,0xc0,0x0e,0xb1,0x03,0xec,0x01,0xcb,0x06,0x32,0xc1,0x0c,0x30,0x03,0x2c,0x02 }, - 16, 0xb430, 0, {0xcb,0x00,0x3e,0xd0,0x0c,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb440, 0, {0xc8,0x05,0x21,0x48,0xab,0x00,0x20,0x00,0x00,0x95,0x23,0x4c,0x08,0xbb,0x01,0x22 }, - 16, 0xb450, 0, {0xc0,0x08,0xb2,0x02,0x0c,0x08,0x83,0x88,0x92,0xd5,0x28,0x34,0x02,0xec,0x02,0x8f }, - 16, 0xb460, 0, {0x20,0x23,0xc0,0x4d,0xf0,0x01,0x7c,0x00,0xdf,0x00,0x2e,0xc0,0x0d,0x30,0x03,0x72 }, - 16, 0xb470, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x44,0x00,0x83,0x10,0x20,0x60 }, - 16, 0xb480, 0, {0x09,0x25,0x02,0x00,0x08,0xa0,0x00,0x4c,0x00,0x0b,0x0c,0x22,0x4f,0x12,0x93,0x40 }, - 16, 0xb490, 0, {0x00,0xc0,0x09,0x3e,0x02,0xec,0x00,0xab,0x80,0xa4,0xc0,0x09,0x30,0x22,0x2c,0x08 }, - 16, 0xb4a0, 0, {0xb3,0x01,0x0c,0x81,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb4b0, 0, {0x60,0x01,0x16,0x09,0xb7,0x80,0x21,0x64,0x08,0x78,0x06,0x12,0x00,0xb4,0x82,0x2d }, - 16, 0xb4c0, 0, {0xa4,0x1b,0x69,0x06,0x7e,0x04,0x17,0x92,0x25,0xe6,0x09,0x78,0x06,0xde,0x80,0xa7 }, - 16, 0xb4d0, 0, {0x90,0x25,0xe0,0x09,0x79,0x50,0x5e,0x04,0xb7,0x92,0x2f,0x61,0x09,0xc8,0x02,0x48 }, - 16, 0xb4e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x25,0x00,0xc3,0x00,0xb0,0x03 }, - 16, 0xb4f0, 0, {0x0d,0xa3,0x42,0x09,0x40,0xe1,0x00,0xbc,0x40,0x0f,0x11,0x03,0x4c,0x00,0x13,0x00 }, - 16, 0xb500, 0, {0x20,0xc0,0x09,0x32,0x03,0xcc,0x10,0xa3,0x00,0x26,0xc4,0x8d,0x30,0x2b,0x0c,0x80 }, - 16, 0xb510, 0, {0xf3,0x00,0x7c,0x80,0x0c,0x30,0x01,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb520, 0, {0x40,0x1d,0xbc,0x00,0xe7,0x10,0x3d,0x01,0x2f,0xf1,0x42,0xe8,0x00,0xf5,0x90,0x03 }, - 16, 0xb530, 0, {0xc1,0x0c,0xf1,0x43,0x9c,0x04,0xef,0x08,0x3b,0xc2,0x0c,0xf0,0x81,0xdc,0xa0,0xdf }, - 16, 0xb540, 0, {0x00,0x3b,0xc3,0x3f,0xf0,0x83,0xfc,0x05,0xdf,0x0c,0x3d,0x40,0x0f,0xd1,0x03,0xd0 }, - 16, 0xb550, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xf4,0x00,0xcb,0x80,0x30,0x40 }, - 16, 0xb560, 0, {0x2c,0xa0,0x03,0xe0,0x00,0xf8,0x80,0x32,0xc0,0x2e,0xb8,0x0b,0x2c,0x46,0xd3,0x00 }, - 16, 0xb570, 0, {0x30,0xc0,0x0c,0x30,0x03,0x0c,0x00,0xdb,0x48,0x32,0xc0,0x1f,0xb4,0x03,0x2c,0x88 }, - 16, 0xb580, 0, {0xcb,0x48,0x32,0x80,0x0c,0x30,0x13,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb590, 0, {0x48,0x11,0xb4,0x00,0x87,0x01,0x21,0x40,0x08,0x70,0x42,0xd0,0x08,0xb4,0x00,0x29 }, - 16, 0xb5a0, 0, {0xc0,0x08,0x70,0x02,0x1c,0x00,0x87,0x00,0x21,0xc8,0x0c,0x72,0x0a,0x1c,0x84,0x8f }, - 16, 0xb5b0, 0, {0x40,0x09,0xc4,0x8f,0x73,0x12,0x9c,0x40,0x83,0x20,0x21,0xc0,0x08,0x60,0x02,0x92 }, - 16, 0xb5c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x96,0x01,0xaf,0x80,0x21,0x20 }, - 16, 0xb5d0, 0, {0x08,0x68,0x02,0xda,0x00,0xbd,0x80,0x21,0xe0,0x09,0x78,0x02,0x1e,0x00,0x8f,0x88 }, - 16, 0xb5e0, 0, {0x83,0xe2,0x29,0xf8,0x82,0x5f,0x80,0x87,0xa0,0x25,0xe0,0x0b,0x3a,0x12,0x0e,0x50 }, - 16, 0xb5f0, 0, {0x97,0xa4,0x21,0xa0,0x29,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb600, 0, {0x08,0x14,0xcc,0x02,0xa1,0x81,0x00,0x00,0x48,0x70,0x02,0xc8,0x00,0xb1,0x00,0x2c }, - 16, 0xb610, 0, {0xf8,0x09,0x31,0x42,0x0c,0x10,0x83,0x00,0x20,0xe0,0x08,0x38,0x12,0x4e,0x00,0x83 }, - 16, 0xb620, 0, {0x00,0x6a,0xc0,0x0b,0x30,0x02,0x8c,0x04,0x93,0x00,0x20,0xe0,0x09,0x38,0x02,0x92 }, - 16, 0xb630, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x40,0xee,0x20,0x30,0x80 }, - 16, 0xb640, 0, {0x0c,0xa0,0x03,0xe8,0x00,0xfa,0x00,0x33,0xb0,0x0d,0xe4,0x03,0x32,0x88,0xcc,0x80 }, - 16, 0xb650, 0, {0x23,0x00,0x0d,0xc0,0x03,0x62,0x02,0xca,0x00,0x36,0x80,0x0f,0xa0,0x43,0x28,0x06 }, - 16, 0xb660, 0, {0xda,0x00,0x33,0xa0,0x0d,0x6a,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb670, 0, {0x48,0x00,0xe0,0x00,0x98,0x01,0xbe,0x00,0x0f,0x80,0x03,0xf0,0x00,0xbc,0x00,0x38 }, - 16, 0xb680, 0, {0x04,0x08,0x80,0xa3,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x13,0xa0,0x00,0xe0 }, - 16, 0xb690, 0, {0x00,0x3e,0x00,0x0e,0x00,0x03,0xc0,0x00,0xe8,0x00,0xbe,0x04,0x4e,0x80,0x07,0xd2 }, - 16, 0xb6a0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x80,0xc9,0x00,0x3e,0x68 }, - 16, 0xb6b0, 0, {0x0c,0x90,0x03,0x64,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x90,0x43,0xe0,0x00,0xc8,0x00 }, - 16, 0xb6c0, 0, {0x32,0x00,0x0c,0x80,0x13,0x20,0x00,0xc9,0x00,0x36,0x40,0x0c,0x90,0x03,0x64,0x00 }, - 16, 0xb6d0, 0, {0x81,0x00,0x32,0x40,0x04,0x90,0x13,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb6e0, 0, {0x80,0x04,0x65,0x06,0x89,0x40,0x2e,0x60,0x1a,0x14,0x2a,0x05,0x20,0x89,0x00,0x2e }, - 16, 0xb6f0, 0, {0x40,0x08,0x90,0x02,0xc4,0x08,0xc1,0x02,0x20,0x40,0x08,0x10,0x1a,0x24,0x00,0x89 }, - 16, 0xb700, 0, {0x10,0x32,0x41,0x08,0x90,0x12,0x24,0x00,0x89,0x04,0x36,0x40,0x88,0x94,0x0a,0x20 }, - 16, 0xb710, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x20,0x89,0x55,0x2e,0x40 }, - 16, 0xb720, 0, {0x08,0xd5,0x02,0x34,0x00,0x8d,0x00,0x2e,0x40,0x18,0x90,0x02,0xe4,0x00,0x99,0x00 }, - 16, 0xb730, 0, {0x26,0x40,0x08,0x90,0x02,0x04,0x0a,0x89,0x00,0x26,0x40,0x38,0x90,0x0a,0x24,0x00 }, - 16, 0xb740, 0, {0xa9,0x00,0x20,0x40,0x0a,0x90,0x82,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb750, 0, {0x08,0x04,0x05,0x00,0x81,0x00,0x2f,0x40,0x0a,0xd4,0x02,0x34,0x00,0x85,0x01,0x2c }, - 16, 0xb760, 0, {0x40,0x08,0x10,0x42,0xe4,0x06,0x99,0x00,0x22,0x40,0x08,0x10,0x02,0x05,0x00,0x81 }, - 16, 0xb770, 0, {0x40,0x28,0x50,0x08,0x14,0x12,0x05,0x00,0xa1,0x40,0x24,0x50,0x5a,0x10,0x02,0x02 }, - 16, 0xb780, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x04,0x3e,0x00 }, - 16, 0xb790, 0, {0x08,0x80,0x03,0x21,0x42,0xcc,0x00,0x3e,0x00,0x2c,0x80,0x02,0xe0,0x00,0xd8,0x00 }, - 16, 0xb7a0, 0, {0xb6,0x00,0x2c,0x80,0x02,0x20,0x02,0xc8,0x00,0x36,0x00,0x0c,0x80,0x03,0x60,0x02 }, - 16, 0xb7b0, 0, {0xe8,0x00,0x32,0x00,0x8e,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb7c0, 0, {0x98,0x1d,0xf5,0x00,0xf5,0x00,0x3e,0x40,0x87,0x90,0x03,0xe4,0x00,0xf1,0x00,0x3d }, - 16, 0xb7d0, 0, {0x50,0x0f,0x54,0x03,0xd1,0x00,0xec,0x40,0x3f,0x10,0x0b,0xc4,0x43,0xf1,0x00,0xf9 }, - 16, 0xb7e0, 0, {0x40,0x36,0x50,0x0f,0x94,0x13,0xe5,0x10,0xd9,0x44,0x3d,0x40,0x2d,0xd0,0x03,0xe6 }, - 16, 0xb7f0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x60,0xcd,0x02,0x3b,0x40 }, - 16, 0xb800, 0, {0x0c,0xd0,0x03,0xb4,0x40,0xfd,0x06,0x3e,0x40,0x0c,0x90,0x03,0x66,0x04,0xc9,0x82 }, - 16, 0xb810, 0, {0xb6,0x62,0x0f,0x18,0x0b,0x36,0x00,0xcd,0x40,0x32,0x61,0x0c,0x90,0x23,0x24,0x0a }, - 16, 0xb820, 0, {0xc9,0x00,0x32,0x40,0x4c,0xd0,0x43,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb830, 0, {0x39,0x10,0xe3,0x80,0xd8,0x00,0x22,0x00,0x0d,0x80,0x02,0x22,0x94,0xb8,0x00,0x2e }, - 16, 0xb840, 0, {0x00,0x0d,0x80,0x03,0x21,0x00,0x88,0x40,0x22,0x00,0x0b,0xc4,0x22,0x21,0x50,0x88 }, - 16, 0xb850, 0, {0x80,0x22,0x22,0x08,0x80,0x02,0x20,0x10,0x80,0x01,0x2a,0x00,0x0a,0x80,0x03,0x4e }, - 16, 0xb860, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xc6,0x00,0x89,0x00,0x2a,0x40 }, - 16, 0xb870, 0, {0x88,0x10,0x0a,0x84,0x08,0xb1,0x00,0x29,0x40,0x0a,0x70,0x0a,0xb5,0x00,0x8f,0x40 }, - 16, 0xb880, 0, {0x29,0xc0,0x0b,0xf4,0x02,0x24,0x00,0x81,0x20,0x28,0x44,0x89,0x10,0x02,0x04,0x04 }, - 16, 0xb890, 0, {0x81,0x02,0x2a,0x40,0x08,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb8a0, 0, {0x18,0x15,0xa6,0x00,0x99,0x20,0x22,0x40,0x09,0x90,0x12,0x24,0x80,0xb9,0x00,0x2f }, - 16, 0xb8b0, 0, {0x44,0x03,0xd0,0x02,0xf4,0x00,0x8d,0x00,0x2b,0x41,0x0b,0xd0,0x02,0x26,0x10,0x89 }, - 16, 0xb8c0, 0, {0x04,0x2a,0x40,0x09,0x90,0x6e,0x24,0x00,0x89,0x00,0x2a,0x40,0x0a,0x94,0x02,0x46 }, - 16, 0xb8d0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x15,0xe6,0x00,0xc9,0x00,0x38,0x42 }, - 16, 0xb8e0, 0, {0x0c,0x10,0x13,0xa6,0x04,0x79,0x08,0x3a,0x78,0x06,0x92,0x03,0xa4,0x08,0xc9,0x00 }, - 16, 0xb8f0, 0, {0x3a,0x60,0x8f,0x98,0x23,0x06,0x02,0xc9,0x02,0x3a,0x40,0x0d,0x90,0x03,0x04,0x00 }, - 16, 0xb900, 0, {0xc9,0x00,0x38,0x40,0x0c,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb910, 0, {0x28,0x01,0x84,0x10,0xf9,0x80,0xbe,0x40,0x4f,0x90,0x02,0xe4,0x00,0xf9,0x00,0x3c }, - 16, 0xb920, 0, {0x60,0x8d,0x92,0x03,0x24,0x42,0xe9,0x10,0x32,0x50,0x0f,0x94,0x03,0xe4,0x00,0xf9 }, - 16, 0xb930, 0, {0x00,0xb6,0x41,0x2e,0x10,0x03,0xe4,0x00,0xf9,0x00,0x2e,0x40,0x0f,0x90,0x03,0xca }, - 16, 0xb940, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x08,0xc8,0x00,0x3e,0x10 }, - 16, 0xb950, 0, {0x0f,0x88,0x03,0x20,0x08,0xf8,0xc0,0x1e,0x10,0x2c,0x40,0x03,0xf2,0x00,0xcc,0x00 }, - 16, 0xb960, 0, {0x3f,0x00,0x0c,0xc0,0x13,0x20,0x02,0xc0,0x00,0x30,0x00,0x0c,0x80,0x2b,0x20,0x10 }, - 16, 0xb970, 0, {0xc0,0x04,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb980, 0, {0xa8,0x05,0x3a,0x80,0x86,0xe0,0x2f,0xa0,0x1b,0xe0,0x02,0x3a,0x80,0xba,0x04,0x2e }, - 16, 0xb990, 0, {0x80,0x08,0xa0,0x03,0x88,0x08,0xc2,0x00,0x2e,0x81,0x08,0x60,0x02,0x28,0x10,0x8e }, - 16, 0xb9a0, 0, {0x81,0x03,0x80,0x08,0xe0,0x01,0x78,0x00,0x8e,0x04,0x03,0x80,0x09,0x68,0x03,0xca }, - 16, 0xb9b0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x60,0x2c,0x44 }, - 16, 0xb9c0, 0, {0x0b,0x38,0x02,0x0f,0x80,0xb1,0x00,0x2c,0xe5,0x03,0x30,0x10,0xcc,0x10,0x83,0x00 }, - 16, 0xb9d0, 0, {0x0c,0xc0,0x29,0x30,0x22,0x04,0x09,0x91,0x10,0x24,0xc0,0xc8,0x30,0x00,0x4c,0x04 }, - 16, 0xb9e0, 0, {0x93,0x02,0x24,0xc0,0x0b,0x31,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xb9f0, 0, {0xe0,0x01,0x18,0x80,0x87,0x00,0x2d,0x40,0x0b,0x74,0x42,0x1c,0x01,0xb5,0x01,0x2c }, - 16, 0xba00, 0, {0xc0,0x0b,0x60,0x02,0xb0,0x00,0x94,0x04,0x2f,0x20,0x09,0xc0,0x02,0x14,0x90,0x97 }, - 16, 0xba10, 0, {0x00,0x25,0xc8,0x08,0x70,0x02,0x4c,0x80,0x97,0x20,0x25,0xc0,0x09,0x70,0x02,0xe8 }, - 16, 0xba20, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3a,0x82,0xc6,0x80,0x2d,0x60 }, - 16, 0xba30, 0, {0x0b,0xf8,0x0b,0x1a,0x00,0xf5,0x80,0x3d,0xe0,0x8f,0x78,0x03,0xde,0x02,0xc7,0x80 }, - 16, 0xba40, 0, {0x2d,0xe0,0x0d,0x78,0x0b,0x17,0x02,0xdf,0x80,0x24,0xf8,0x2c,0xfd,0x03,0x5e,0x0c }, - 16, 0xba50, 0, {0xd7,0xe0,0x35,0xe0,0x0f,0x68,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xba60, 0, {0x48,0x1d,0xae,0x40,0xfa,0x04,0x3e,0x40,0x0f,0x80,0x13,0xec,0x04,0xf9,0x00,0x3e }, - 16, 0xba70, 0, {0xc1,0x0c,0xa0,0x13,0xc0,0x10,0xe8,0x00,0x3c,0x00,0x4e,0x80,0x43,0xc4,0x20,0x89 }, - 16, 0xba80, 0, {0x00,0xba,0xc0,0x07,0xb6,0x21,0xed,0x06,0xeb,0x68,0xba,0xcc,0x0f,0x20,0x13,0xc2 }, - 16, 0xba90, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xbe,0x00,0xc6,0x80,0x31,0x60 }, - 16, 0xbaa0, 0, {0x2d,0x78,0x0b,0x3e,0x48,0xec,0x92,0x3d,0x60,0x0c,0x58,0x03,0x5a,0x40,0xd5,0x80 }, - 16, 0xbab0, 0, {0x31,0x61,0x0c,0x58,0x23,0x36,0x00,0xcf,0x82,0x3f,0xe0,0x0c,0xf8,0x03,0xff,0x60 }, - 16, 0xbac0, 0, {0xcf,0x90,0x33,0xf0,0x0c,0x52,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbad0, 0, {0xa8,0x11,0xb8,0x84,0x86,0x14,0xb5,0xc0,0x08,0x70,0x02,0x1e,0xc0,0xc4,0x00,0x2d }, - 16, 0xbae0, 0, {0x40,0x08,0x40,0x02,0x14,0xd0,0x86,0x10,0x21,0x80,0x4c,0x62,0x42,0x34,0x40,0xa5 }, - 16, 0xbaf0, 0, {0x00,0x35,0xc0,0x28,0x70,0x42,0xdc,0xc2,0x8f,0x30,0x23,0xc0,0x08,0x50,0x02,0x2a }, - 16, 0xbb00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x98,0x28,0x8e,0x00,0xa5,0x40 }, - 16, 0xbb10, 0, {0x08,0xf1,0x02,0x18,0x64,0xb4,0x00,0x6d,0x42,0x08,0x50,0x02,0x18,0x01,0x85,0x08 }, - 16, 0xbb20, 0, {0x21,0x40,0x09,0x58,0x22,0x54,0x00,0x85,0x10,0x2d,0xc4,0x09,0x70,0x02,0xdc,0x04 }, - 16, 0xbb30, 0, {0x97,0x00,0x25,0xc0,0x08,0x44,0x02,0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbb40, 0, {0x60,0x14,0x8c,0x00,0x82,0x80,0x24,0xc0,0x08,0x80,0x02,0x2d,0x00,0x80,0x4a,0x2c }, - 16, 0xbb50, 0, {0x42,0x08,0x0a,0x42,0x06,0x00,0x92,0x84,0x20,0xa0,0x88,0x28,0x42,0x44,0x00,0xa3 }, - 16, 0xbb60, 0, {0x06,0x24,0xc0,0x0b,0x30,0x02,0xcc,0x10,0x93,0x04,0x24,0xc1,0x09,0x00,0x02,0x08 }, - 16, 0xbb70, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xcb,0x00,0x36,0x40 }, - 16, 0xbb80, 0, {0x0c,0xb4,0x13,0x2c,0x00,0xf9,0x00,0x3e,0xa0,0x0c,0xa2,0x03,0x04,0x08,0xc2,0x80 }, - 16, 0xbb90, 0, {0x30,0xa8,0x0d,0x2a,0x03,0x54,0x00,0xcb,0x00,0x3f,0xc0,0x0d,0xf0,0x03,0xfc,0x08 }, - 16, 0xbba0, 0, {0xdf,0x00,0x37,0xd0,0x0c,0xb0,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbbb0, 0, {0x80,0x00,0xe0,0x00,0xfb,0x10,0x3a,0x40,0x0e,0xb0,0x03,0xed,0x90,0xf9,0x11,0x7e }, - 16, 0xbbc0, 0, {0x80,0x4f,0xb0,0x53,0xe8,0x40,0xe9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xa6,0x08,0xf9 }, - 16, 0xbbd0, 0, {0x01,0x3a,0xc0,0x0c,0xb0,0x13,0xcc,0x00,0xeb,0x02,0x3a,0xc6,0x8e,0xb8,0x03,0xe0 }, - 16, 0xbbe0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x0c,0xce,0x00,0x3f,0xe0 }, - 16, 0xbbf0, 0, {0x2c,0xf0,0x83,0x3a,0x48,0xcd,0x01,0x35,0x80,0x0c,0x60,0x12,0x34,0x0a,0xce,0x00 }, - 16, 0xbc00, 0, {0xb3,0x80,0x2c,0xe0,0x0b,0x74,0x00,0xc9,0x10,0xb3,0xc1,0x0f,0xf0,0x1b,0x3c,0x00 }, - 16, 0xbc10, 0, {0xcf,0x00,0xb7,0xc0,0x2c,0xe0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbc20, 0, {0x81,0x04,0x6e,0x10,0x88,0x80,0x2c,0xc0,0x18,0x98,0x02,0x2d,0x80,0x81,0x00,0x36 }, - 16, 0xbc30, 0, {0x91,0x08,0xb0,0x03,0x68,0x00,0xc9,0x00,0x22,0x40,0x08,0x90,0x02,0x24,0x00,0x83 }, - 16, 0xbc40, 0, {0x80,0x36,0xc0,0x0b,0x30,0x02,0x2c,0x02,0x83,0x00,0x20,0xc0,0x08,0x20,0x03,0x60 }, - 16, 0xbc50, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x06,0x00,0x8a,0x80,0x2e,0x45 }, - 16, 0xbc60, 0, {0x28,0x88,0x02,0x24,0x02,0x88,0x02,0x02,0x02,0x08,0x80,0x02,0xa2,0x00,0x98,0x00 }, - 16, 0xbc70, 0, {0x22,0x00,0x08,0x80,0x12,0x24,0x00,0x89,0x01,0x22,0xc1,0x0a,0xb0,0x02,0x6c,0x00 }, - 16, 0xbc80, 0, {0xab,0x00,0x22,0xc1,0x08,0x90,0x12,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbc90, 0, {0x08,0x04,0x00,0x00,0x80,0x00,0x2c,0xc0,0x48,0x08,0x12,0x00,0x80,0x80,0x02,0x24 }, - 16, 0xbca0, 0, {0x00,0x08,0x18,0x42,0xac,0x02,0x8b,0x80,0x22,0xe0,0x08,0xb8,0x12,0x04,0x02,0x83 }, - 16, 0xbcb0, 0, {0x00,0x20,0xc0,0x0b,0x30,0x42,0x0c,0x00,0xa3,0x01,0x60,0xc0,0x48,0x10,0x02,0x42 }, - 16, 0xbcc0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x68,0x08,0xca,0x00,0x2e,0x40 }, - 16, 0xbcd0, 0, {0x08,0x80,0x03,0x00,0x00,0xc8,0x06,0x32,0x00,0x0c,0x80,0x02,0xa0,0x00,0xd8,0x00 }, - 16, 0xbce0, 0, {0x32,0x00,0x0c,0x80,0x03,0x74,0x00,0xcb,0x00,0x22,0xc0,0x0f,0xf0,0x03,0x3c,0x00 }, - 16, 0xbcf0, 0, {0xef,0x00,0x37,0xc0,0x0c,0x80,0x01,0x40,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbd00, 0, {0xa0,0x19,0xfc,0x00,0xfc,0x04,0x3f,0xc0,0x0f,0xc0,0x03,0xe1,0x00,0xfc,0x00,0x3b }, - 16, 0xbd10, 0, {0x00,0x0f,0xd0,0x03,0x7c,0x00,0xef,0x00,0x2f,0xc0,0x0f,0xf0,0x11,0xf4,0x10,0xfd }, - 16, 0xbd20, 0, {0x02,0x3d,0xc0,0x4f,0xf0,0x03,0xdc,0x00,0xdf,0x04,0x3f,0xc0,0x0f,0xc0,0x43,0xe9 }, - 16, 0xbd30, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x41,0x02,0x70,0x20,0xdc,0x10 }, - 16, 0xbd40, 0, {0x67,0x04,0x0d,0xc1,0x02,0x70,0x20,0x9c,0x10,0x37,0x04,0x0d,0xc1,0x06,0x70,0x40 }, - 16, 0xbd50, 0, {0x4c,0x10,0x37,0x14,0x15,0xc1,0x03,0x70,0x40,0xdc,0x10,0x13,0x04,0x0d,0xc1,0x07 }, - 16, 0xbd60, 0, {0x70,0x40,0xdc,0x10,0x37,0x04,0x0d,0xc0,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbd70, 0, {0x00,0xc5,0x44,0x05,0x71,0x21,0x5c,0x40,0x57,0x10,0x15,0xc4,0x05,0x71,0x05,0x5c }, - 16, 0xbd80, 0, {0x40,0x57,0x10,0x15,0xc4,0x06,0x71,0x01,0x4c,0x40,0x57,0x10,0x0d,0xc4,0x05,0x71 }, - 16, 0xbd90, 0, {0x05,0x5c,0x40,0x53,0x10,0x15,0xc4,0x07,0x71,0x01,0x5c,0x40,0x57,0x10,0x15,0xc0 }, - 16, 0xbda0, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x01,0x20,0x80,0x48,0x20 }, - 16, 0xbdb0, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 }, - 16, 0xbdc0, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01 }, - 16, 0xbdd0, 0, {0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbde0, 0, {0x00,0x84,0x00,0x01,0x60,0x00,0x58,0x00,0x56,0x00,0x05,0x80,0x01,0x60,0x04,0x58 }, - 16, 0xbdf0, 0, {0x00,0x16,0x00,0x05,0x80,0x01,0x20,0x01,0x58,0x00,0x16,0x00,0x05,0x80,0x01,0x60 }, - 16, 0xbe00, 0, {0x00,0x58,0x00,0x56,0x00,0x05,0x80,0x01,0x60,0x00,0x58,0x00,0x16,0x00,0x01,0x80 }, - 16, 0xbe10, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x05,0x72,0x11,0x5c,0x80 }, - 16, 0xbe20, 0, {0x17,0x20,0x15,0xd8,0x05,0x32,0x11,0x1c,0x80,0x47,0x20,0x14,0x88,0x00,0x72,0x01 }, - 16, 0xbe30, 0, {0x1c,0x80,0x57,0x20,0x05,0xc8,0x04,0x72,0x01,0x5c,0x80,0x57,0x20,0x15,0xc8,0x01 }, - 16, 0xbe40, 0, {0x72,0x01,0x5c,0x80,0x57,0x24,0x15,0xc0,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbe50, 0, {0x00,0xc1,0x40,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x40,0x20,0x00,0x18 }, - 16, 0xbe60, 0, {0x00,0x06,0x00,0x01,0x90,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x41,0x80,0x00,0x60 }, - 16, 0xbe70, 0, {0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x10,0x06,0x00,0x01,0x80 }, - 16, 0xbe80, 0, {0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x04,0x22,0x01,0x08,0x80 }, - 16, 0xbe90, 0, {0x02,0x20,0x10,0x88,0x04,0x62,0x01,0x08,0x80,0x42,0x20,0x10,0x88,0x00,0x20,0x01 }, - 16, 0xbea0, 0, {0x08,0x80,0x42,0x20,0x00,0x88,0x04,0x22,0x01,0x08,0x00,0x42,0x20,0x10,0x88,0x00 }, - 16, 0xbeb0, 0, {0x22,0x01,0x08,0x80,0x42,0x30,0x10,0x80,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbec0, 0, {0x00,0xc5,0x4a,0x05,0x42,0x81,0x50,0xa0,0x04,0x28,0x15,0x0a,0x05,0x52,0x81,0x10 }, - 16, 0xbed0, 0, {0xa0,0x44,0x28,0x11,0x1a,0x00,0x40,0x80,0x10,0xa0,0x54,0x28,0x05,0x0a,0x05,0x42 }, - 16, 0xbee0, 0, {0x81,0x51,0x20,0x14,0x28,0x15,0x0a,0x01,0x42,0x81,0x50,0xa0,0x54,0x28,0x15,0x00 }, - 16, 0xbef0, 0, {0x31,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0c,0x01,0x53,0x40,0x54,0xc0 }, - 16, 0xbf00, 0, {0x15,0x30,0x05,0x5c,0x01,0x57,0x40,0x54,0xc0,0x15,0x30,0x05,0x5c,0x01,0x53,0x00 }, - 16, 0xbf10, 0, {0x55,0xc0,0x15,0x74,0x05,0x4c,0x01,0x53,0x00,0x55,0xc0,0x15,0x74,0x05,0x4c,0x01 }, - 16, 0xbf20, 0, {0x53,0x00,0x54,0xc0,0x11,0x30,0x01,0x40,0x21,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbf30, 0, {0x00,0x80,0x00,0x00,0x40,0x00,0x10,0x00,0x04,0x00,0x01,0x00,0x00,0x40,0x00,0x10 }, - 16, 0xbf40, 0, {0x00,0x04,0x00,0x01,0x00,0x00,0x42,0x00,0x10,0x00,0x04,0x00,0x11,0x00,0x00,0x40 }, - 16, 0xbf50, 0, {0x00,0x10,0xc1,0x04,0x00,0x01,0x00,0x00,0x40,0x00,0x10,0x00,0x01,0x10,0x01,0x01 }, - 16, 0xbf60, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x60,0x02,0x08,0x00,0x82,0x00 }, - 16, 0xbf70, 0, {0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00 }, - 16, 0xbf80, 0, {0x82,0x00,0x20,0x84,0x00,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x84,0x08,0x20,0x02 }, - 16, 0xbf90, 0, {0x08,0x00,0x82,0x00,0x21,0x80,0x08,0x01,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xbfa0, 0, {0x00,0xc5,0x40,0x05,0x60,0x01,0x58,0x00,0x96,0x00,0x15,0x90,0x05,0x64,0x02,0x58 }, - 16, 0xbfb0, 0, {0x00,0x56,0x00,0x55,0x90,0x05,0x60,0x01,0xd9,0x00,0x16,0x40,0x15,0x80,0x05,0x60 }, - 16, 0xbfc0, 0, {0x01,0x59,0x00,0x76,0x40,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x56,0x00,0x15,0x80 }, - 16, 0xbfd0, 0, {0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x40,0x03,0x60,0x00,0xd8,0x00 }, - 16, 0xbfe0, 0, {0x36,0x00,0x4d,0x80,0x03,0x60,0x00,0xd8,0x00,0x36,0x00,0x0d,0x80,0x07,0x62,0x00 }, - 16, 0xbff0, 0, {0x58,0x00,0x36,0x00,0x0d,0x80,0x07,0x60,0x00,0xd8,0x80,0x16,0x00,0x0d,0x80,0x03 }, - 16, 0xc000, 0, {0x60,0x00,0xd8,0x00,0x36,0x00,0x1d,0x80,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc010, 0, {0x00,0xc5,0x42,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c }, - 16, 0xc020, 0, {0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0xc1,0x0c,0x20,0x43,0x08,0x10,0xc2,0x06,0x30 }, - 16, 0xc030, 0, {0x81,0x0c,0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x18,0xc0 }, - 16, 0xc040, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x30,0x00,0x0c,0x00 }, - 16, 0xc050, 0, {0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x40,0x30,0x00 }, - 16, 0xc060, 0, {0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00 }, - 16, 0xc070, 0, {0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc080, 0, {0x00,0x80,0x02,0x01,0x30,0x80,0x4c,0x20,0x13,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c }, - 16, 0xc090, 0, {0x20,0x13,0x08,0x04,0xc2,0x25,0x30,0x81,0x4c,0x20,0x13,0x08,0x04,0xc2,0x01,0x30 }, - 16, 0xc0a0, 0, {0x80,0x4c,0x32,0x53,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c,0x20,0x13,0x08,0x04,0xc0 }, - 16, 0xc0b0, 0, {0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x05,0x62,0x81,0x58,0x20 }, - 16, 0xc0c0, 0, {0x56,0x08,0x15,0x82,0x04,0x60,0x81,0x58,0x20,0x46,0x08,0x15,0x82,0x01,0x60,0xc1 }, - 16, 0xc0d0, 0, {0x58,0x20,0x46,0x08,0x15,0x82,0x01,0x60,0x81,0x58,0x30,0x56,0x08,0x15,0x82,0x05 }, - 16, 0xc0e0, 0, {0x60,0x81,0x58,0x20,0x56,0x08,0x05,0x80,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc0f0, 0, {0x00,0xc5,0x42,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08 }, - 16, 0xc100, 0, {0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x0c,0x20,0x02,0x08,0x00,0x82,0x00,0x20 }, - 16, 0xc110, 0, {0x80,0x08,0x20,0x03,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x80 }, - 16, 0xc120, 0, {0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x04,0x66,0x81,0x18,0x20 }, - 16, 0xc130, 0, {0x46,0x08,0x11,0x82,0x04,0x64,0x81,0x18,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0x81 }, - 16, 0xc140, 0, {0x0c,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0x81,0x19,0x20,0x43,0x08,0x11,0x82,0x04 }, - 16, 0xc150, 0, {0x60,0x81,0x19,0x20,0x46,0x48,0x01,0x80,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc160, 0, {0x00,0xc5,0x60,0x05,0x58,0x01,0x56,0x00,0x55,0x80,0x15,0x60,0x04,0x58,0x01,0x56 }, - 16, 0xc170, 0, {0x00,0x45,0x80,0x11,0x60,0x00,0x58,0x00,0x06,0x00,0x45,0x80,0x15,0x60,0x01,0x58 }, - 16, 0xc180, 0, {0x01,0x16,0x00,0x01,0x80,0x15,0x60,0x05,0x58,0x01,0x56,0x00,0x55,0x80,0x05,0x40 }, - 16, 0xc190, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x06,0x01,0x49,0x80,0x10,0x60 }, - 16, 0xc1a0, 0, {0x14,0x18,0x05,0x06,0x01,0x79,0x80,0x50,0x60,0x14,0x18,0x01,0x06,0x01,0x41,0x80 }, - 16, 0xc1b0, 0, {0x50,0x60,0x04,0x18,0x05,0x06,0x01,0x41,0x80,0x10,0x60,0x14,0x18,0x05,0x06,0x01 }, - 16, 0xc1c0, 0, {0x41,0x80,0x50,0x60,0x14,0x18,0x05,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc1d0, 0, {0x00,0x80,0x02,0x01,0x04,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x04,0x04,0x40 }, - 16, 0xc1e0, 0, {0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x84,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00 }, - 16, 0xc1f0, 0, {0x80,0x41,0x20,0x10,0x08,0x04,0x02,0x11,0x00,0x80,0x41,0x20,0x10,0x48,0x04,0x00 }, - 16, 0xc200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x46,0x03,0x51,0x80,0xd4,0x60 }, - 16, 0xc210, 0, {0x35,0x18,0x0d,0x46,0x02,0x11,0x80,0xd4,0x60,0x35,0x18,0x0d,0x46,0x03,0x11,0x80 }, - 16, 0xc220, 0, {0xd4,0x60,0x35,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x46,0x03 }, - 16, 0xc230, 0, {0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x31,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc240, 0, {0x00,0xc5,0x46,0x05,0x70,0x81,0x5c,0x60,0x07,0x18,0x15,0xc6,0x04,0x71,0x81,0x1c }, - 16, 0xc250, 0, {0x60,0x17,0x18,0x15,0xc6,0x05,0x31,0x81,0xdc,0x60,0x57,0x18,0x15,0xc6,0x05,0x71 }, - 16, 0xc260, 0, {0x80,0x1c,0x60,0x77,0x18,0x15,0xce,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc0 }, - 16, 0xc270, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x46,0x02,0x71,0x80,0x9c,0x61 }, - 16, 0xc280, 0, {0x77,0x18,0x0d,0xc6,0x02,0x71,0x80,0x9c,0x60,0x37,0x18,0x0d,0xc2,0x03,0x31,0x80 }, - 16, 0xc290, 0, {0x5c,0x60,0x27,0x18,0x0d,0xc6,0x03,0x71,0x80,0x9c,0x60,0x17,0x18,0x0d,0xce,0x03 }, - 16, 0xc2a0, 0, {0x71,0x80,0xdc,0x60,0x37,0x18,0x0d,0xc0,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc2b0, 0, {0x00,0x45,0x46,0x05,0x75,0x81,0x5c,0x60,0x77,0x18,0x15,0xc6,0x05,0x75,0x81,0x5c }, - 16, 0xc2c0, 0, {0x60,0x57,0x18,0x15,0xc6,0x05,0x31,0x81,0x0c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71 }, - 16, 0xc2d0, 0, {0x81,0x5c,0x60,0x43,0x18,0x15,0xc6,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc0 }, - 16, 0xc2e0, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x01,0x20,0x80,0x48,0x20 }, - 16, 0xc2f0, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 }, - 16, 0xc300, 0, {0x5c,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x00,0x17,0x08,0x04,0x82,0x01 }, - 16, 0xc310, 0, {0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc320, 0, {0x00,0x00,0x06,0x01,0x63,0x80,0x58,0x60,0x16,0x18,0x05,0x86,0x01,0x61,0x80,0x58 }, - 16, 0xc330, 0, {0x60,0x16,0x18,0x05,0x86,0x01,0x61,0x81,0x58,0x60,0x16,0x18,0x05,0x86,0x01,0x61 }, - 16, 0xc340, 0, {0x80,0x58,0x60,0x56,0x18,0x05,0x86,0x01,0x61,0x80,0x58,0x60,0x16,0x18,0x05,0x80 }, - 16, 0xc350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x05,0x70,0x01,0x5c,0x00 }, - 16, 0xc360, 0, {0x17,0x00,0x15,0xc0,0x85,0x74,0x01,0x1c,0x00,0x47,0x00,0x11,0xc0,0x05,0x70,0x01 }, - 16, 0xc370, 0, {0x5c,0x00,0x53,0x00,0x10,0xc0,0x05,0x70,0x01,0x5c,0x00,0x57,0x00,0x14,0xc9,0x04 }, - 16, 0xc380, 0, {0x70,0x01,0x1c,0x00,0x57,0x00,0x15,0xc0,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc390, 0, {0x00,0x45,0x42,0x00,0x60,0xc0,0x18,0x20,0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18 }, - 16, 0xc3a0, 0, {0x20,0x06,0x08,0x01,0x82,0x00,0x20,0x80,0x18,0x30,0x02,0x08,0x00,0x82,0x10,0x60 }, - 16, 0xc3b0, 0, {0x80,0x18,0x20,0x06,0x08,0x00,0x82,0x00,0x60,0x80,0x18,0x20,0x06,0x08,0x01,0x80 }, - 16, 0xc3c0, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x42,0x04,0x20,0x81,0x08,0x20 }, - 16, 0xc3d0, 0, {0x02,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81 }, - 16, 0xc3e0, 0, {0x08,0x20,0x46,0x08,0x11,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x11,0x82,0x04 }, - 16, 0xc3f0, 0, {0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x80,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc400, 0, {0x00,0x45,0x42,0x05,0x40,0xc5,0x50,0x20,0x14,0x08,0x15,0x00,0x04,0x40,0x81,0x50 }, - 16, 0xc410, 0, {0x20,0x54,0x08,0x11,0x02,0x05,0x00,0x80,0x10,0x20,0x45,0x0c,0x11,0x42,0x04,0x40 }, - 16, 0xc420, 0, {0x81,0x50,0x20,0x14,0x0c,0x15,0x42,0x04,0x40,0x81,0x10,0x20,0x54,0x08,0x15,0x00 }, - 16, 0xc430, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x03,0x01,0x50,0xc0,0x44,0x30 }, - 16, 0xc440, 0, {0x15,0x0c,0x05,0x43,0x01,0x50,0xc0,0x4c,0x30,0x15,0x0c,0x05,0x43,0x21,0x50,0xc0 }, - 16, 0xc450, 0, {0x54,0x30,0x15,0x0c,0x05,0x43,0x01,0x50,0xc0,0x54,0x30,0x15,0x0c,0x05,0x43,0x01 }, - 16, 0xc460, 0, {0x50,0xc0,0x54,0x20,0x15,0x0c,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc470, 0, {0x00,0x00,0x08,0x00,0x42,0x00,0x04,0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x00,0x04 }, - 16, 0xc480, 0, {0x80,0x04,0x20,0x01,0x08,0x00,0x02,0x00,0x10,0x00,0x04,0x00,0x01,0x08,0x00,0x42 }, - 16, 0xc490, 0, {0x00,0x10,0x80,0x04,0x00,0x01,0x08,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x01,0x00 }, - 16, 0xc4a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x02,0x00,0x80,0x84,0x20 }, - 16, 0xc4b0, 0, {0x20,0x08,0x08,0x02,0x02,0x00,0x80,0x84,0x20,0x20,0x08,0x08,0x02,0x02,0x00,0x80 }, - 16, 0xc4c0, 0, {0x80,0xa0,0x20,0x28,0x08,0x02,0x02,0x00,0x80,0x80,0x20,0x20,0x28,0x08,0x02,0x02 }, - 16, 0xc4d0, 0, {0x00,0x80,0x80,0x20,0x20,0x08,0x08,0x00,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc4e0, 0, {0x00,0x45,0x40,0x05,0x60,0x41,0x58,0x00,0x56,0x00,0x15,0x80,0x05,0x60,0x01,0x58 }, - 16, 0xc4f0, 0, {0x00,0x56,0x00,0x15,0x80,0x05,0x20,0x01,0xd8,0x00,0x56,0x00,0x15,0x80,0x05,0x60 }, - 16, 0xc500, 0, {0x01,0x58,0x00,0x76,0x00,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x56,0x00,0x15,0x80 }, - 16, 0xc510, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x03,0x60,0x00,0xd8,0x00 }, - 16, 0xc520, 0, {0x26,0x00,0x0d,0x80,0x02,0x60,0x00,0xd8,0x00,0x36,0x00,0x0d,0x80,0x07,0x60,0x01 }, - 16, 0xc530, 0, {0x5c,0x00,0x36,0x00,0x0d,0x80,0x03,0x60,0x00,0xd8,0x00,0x57,0x00,0x0d,0x80,0x02 }, - 16, 0xc540, 0, {0x60,0x00,0x98,0x00,0x36,0x00,0x0d,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc550, 0, {0x00,0x00,0x00,0x04,0x30,0x21,0x0c,0x00,0x43,0x00,0x10,0xc0,0x04,0x30,0x01,0x0c }, - 16, 0xc560, 0, {0x00,0x43,0x00,0x10,0xc0,0x04,0x30,0x01,0x18,0x00,0x43,0x00,0x10,0xc0,0x04,0x30 }, - 16, 0xc570, 0, {0x01,0x0c,0x00,0x46,0x00,0x10,0xc0,0x04,0x30,0x01,0x0c,0x00,0x43,0x00,0x10,0xc0 }, - 16, 0xc580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0c,0x00 }, - 16, 0xc590, 0, {0x03,0x00,0x00,0xc0,0x00,0x35,0x08,0x0c,0x00,0x03,0x00,0x00,0xc6,0x00,0x14,0x00 }, - 16, 0xc5a0, 0, {0x08,0x00,0x03,0x40,0x00,0xc0,0x00,0x30,0x00,0x0d,0x40,0x02,0x00,0x00,0xc0,0x00 }, - 16, 0xc5b0, 0, {0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc5c0, 0, {0x00,0x00,0x05,0x01,0x31,0x40,0x4c,0x50,0x13,0x14,0x04,0xc5,0x01,0x31,0xc0,0x4c }, - 16, 0xc5d0, 0, {0x50,0x13,0x14,0x04,0xc5,0x05,0x31,0x41,0x4c,0x50,0x13,0x14,0x04,0xc5,0x01,0x31 }, - 16, 0xc5e0, 0, {0x40,0x4c,0x70,0x53,0x14,0x04,0xc5,0x01,0x31,0x40,0x4c,0x40,0x13,0x14,0x04,0xc0 }, - 16, 0xc5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x05,0x68,0xc1,0x5a,0x30 }, - 16, 0xc600, 0, {0x56,0x8c,0x15,0xa3,0x05,0x69,0xc1,0x5a,0x30,0x46,0x8c,0x11,0xa7,0x01,0x68,0xc0 }, - 16, 0xc610, 0, {0x1a,0x30,0x56,0x8c,0x11,0xa3,0x04,0x68,0xc1,0x1a,0x30,0x16,0x8c,0x15,0xa3,0x04 }, - 16, 0xc620, 0, {0x68,0xc1,0x5a,0x30,0x56,0x8c,0x11,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc630, 0, {0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x24,0x00,0x08 }, - 16, 0xc640, 0, {0x01,0x02,0x00,0x00,0x80,0x00,0x24,0x00,0x08,0x80,0x02,0x60,0x00,0x80,0x00,0x20 }, - 16, 0xc650, 0, {0x00,0x09,0x40,0x02,0x20,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80 }, - 16, 0xc660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x44,0x62,0x11,0x18,0x84 }, - 16, 0xc670, 0, {0x46,0x21,0x11,0x88,0x44,0x62,0x09,0x18,0x84,0x46,0x21,0x11,0x88,0x60,0x62,0x10 }, - 16, 0xc680, 0, {0x18,0x04,0x46,0x01,0x11,0x88,0x44,0x62,0x11,0x18,0x80,0x06,0x01,0x11,0x88,0x44 }, - 16, 0xc690, 0, {0x62,0x11,0x18,0x84,0x46,0x21,0x11,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc6a0, 0, {0x00,0x00,0x00,0x45,0x50,0x11,0x54,0x04,0x55,0x01,0x15,0x40,0x44,0x50,0x11,0x54 }, - 16, 0xc6b0, 0, {0x04,0x45,0x01,0x11,0x40,0x40,0x50,0x10,0x54,0x04,0x45,0x01,0x15,0x40,0x44,0x50 }, - 16, 0xc6c0, 0, {0x11,0x14,0x00,0x15,0x01,0x15,0x40,0x44,0x50,0x11,0x54,0x04,0x55,0x00,0x11,0x40 }, - 16, 0xc6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x21,0x42,0x08,0x50,0x82 }, - 16, 0xc6e0, 0, {0x14,0x20,0x85,0x08,0x21,0x42,0x00,0x50,0x82,0x14,0x20,0x85,0x08,0x20,0x42,0x08 }, - 16, 0xc6f0, 0, {0x50,0x82,0x15,0x20,0x05,0x48,0x21,0x42,0x08,0x50,0x82,0x14,0x20,0x81,0x40,0x21 }, - 16, 0xc700, 0, {0x42,0x08,0x50,0x82,0x14,0x20,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc710, 0, {0x00,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x0a,0x01,0x02,0x84,0x40 }, - 16, 0xc720, 0, {0xa1,0x10,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa0,0x00,0x28,0x00,0x0a,0x01,0x02 }, - 16, 0xc730, 0, {0x80,0x40,0xb0,0x10,0x28,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x00 }, - 16, 0xc740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x03,0x53,0x00,0xd4,0xc0 }, - 16, 0xc750, 0, {0x35,0x30,0x0d,0x4c,0x03,0x53,0x00,0xd4,0xc0,0x35,0x30,0x0d,0x4c,0x03,0x53,0x00 }, - 16, 0xc760, 0, {0xd4,0xc0,0x21,0x30,0x08,0x4c,0x03,0x53,0x00,0xd4,0xc0,0x35,0x30,0x08,0x4c,0x03 }, - 16, 0xc770, 0, {0x53,0x00,0xd4,0xc0,0x35,0x30,0x0d,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc780, 0, {0x00,0x00,0x08,0x04,0x70,0x01,0x5c,0x80,0x07,0x20,0x25,0xc9,0x04,0x72,0x01,0x5c }, - 16, 0xc790, 0, {0x80,0x47,0x20,0x15,0xc8,0x00,0x72,0x05,0xdc,0x80,0x57,0x20,0x15,0xc8,0x05,0x72 }, - 16, 0xc7a0, 0, {0x01,0x1c,0x90,0x67,0x20,0x15,0xc8,0x05,0x72,0x01,0x1c,0x80,0x57,0x20,0x15,0xc0 }, - 16, 0xc7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x18,0x48,0xc2,0x12,0x31 }, - 16, 0xc7c0, 0, {0x84,0x8c,0x61,0x03,0x18,0x40,0xc8,0x12,0x31,0x84,0x8c,0x61,0x03,0x18,0x48,0xc4 }, - 16, 0xc7d0, 0, {0x10,0x31,0x84,0x0c,0x41,0x23,0x18,0x48,0xc6,0x10,0x30,0x04,0x0c,0x61,0x23,0x18 }, - 16, 0xc7e0, 0, {0x48,0xc6,0x12,0x30,0x84,0x8c,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc7f0, 0, {0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3 }, - 16, 0xc800, 0, {0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f }, - 16, 0xc810, 0, {0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xbd,0x00 }, - 16, 0xc820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc860, 0, {0x00,0x00,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x09,0x36,0xc2 }, - 16, 0xc870, 0, {0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b }, - 16, 0xc880, 0, {0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x2c,0x00 }, - 16, 0xc890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x3c,0x4c,0xcf,0x13,0x33 }, - 16, 0xc8a0, 0, {0xc4,0xcc,0xf1,0x33,0x3c,0x4d,0x4e,0x93,0x33,0xc4,0xcc,0xf1,0x2b,0x3c,0x4c,0xcf }, - 16, 0xc8b0, 0, {0x13,0x33,0xc4,0xcc,0xe9,0x33,0x3c,0x4c,0xcf,0x12,0xb5,0xc4,0xcc,0xf1,0x33,0x3c }, - 16, 0xc8c0, 0, {0x4c,0xcf,0x13,0x33,0xc4,0xcd,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc8d0, 0, {0x00,0x00,0x3b,0x7e,0x4e,0xc7,0x93,0xb7,0xe4,0xed,0xf9,0x23,0x7e,0x4e,0x47,0x93 }, - 16, 0xc8e0, 0, {0xb7,0xe4,0xed,0xf9,0x3f,0x7e,0x4e,0xde,0x12,0x37,0xe4,0x8d,0xf9,0x3b,0x7e,0x4e }, - 16, 0xc8f0, 0, {0xdf,0x93,0xf7,0x84,0x8d,0xf9,0x3b,0x7e,0x4e,0xdf,0x93,0xb1,0xe4,0xed,0xb9,0x00 }, - 16, 0xc900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x70,0x40,0x9c,0x11 }, - 16, 0xc910, 0, {0x67,0x04,0x19,0xc3,0x02,0x70,0x40,0x9c,0x10,0x27,0x04,0x09,0xc1,0x02,0x70,0x40 }, - 16, 0xc920, 0, {0x1c,0x10,0x27,0x14,0x01,0xc1,0x02,0x70,0x40,0x9c,0x50,0x07,0x04,0x09,0xc1,0x02 }, - 16, 0xc930, 0, {0x70,0x40,0x9c,0x10,0x67,0x14,0x11,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc940, 0, {0x00,0x00,0x04,0x05,0x71,0x01,0x5c,0x40,0x57,0x10,0x15,0xc4,0x05,0x71,0x01,0x5c }, - 16, 0xc950, 0, {0x40,0x57,0x10,0x15,0xc6,0x05,0x71,0x01,0x5c,0x40,0x57,0x10,0x10,0xc4,0x05,0x71 }, - 16, 0xc960, 0, {0x01,0x5c,0x64,0x03,0x10,0x55,0xc4,0x05,0x71,0x01,0x5c,0x40,0x57,0x10,0x15,0xc0 }, - 16, 0xc970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x20,0x80,0x48,0x20 }, - 16, 0xc980, 0, {0x12,0x08,0x04,0x82,0x01,0x21,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x01,0x20,0x80 }, - 16, 0xc990, 0, {0x48,0x20,0x12,0x08,0x05,0xc2,0x01,0x20,0x80,0x48,0x24,0x17,0x08,0x04,0x82,0x01 }, - 16, 0xc9a0, 0, {0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xc9b0, 0, {0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x46,0x00,0x11,0x84,0x00,0x60,0x00,0x18 }, - 16, 0xc9c0, 0, {0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x01,0x18,0x00,0x06,0x10,0x91,0x80,0x00,0x60 }, - 16, 0xc9d0, 0, {0x00,0x18,0x46,0x46,0x18,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x10,0x01,0x80 }, - 16, 0xc9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x73,0x01,0x1c,0x80 }, - 16, 0xc9f0, 0, {0x07,0x20,0x01,0xc8,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x01 }, - 16, 0xca00, 0, {0x1c,0x80,0x47,0x22,0x11,0xc8,0x04,0x72,0x01,0x1c,0x80,0x07,0x20,0x11,0xc8,0x04 }, - 16, 0xca10, 0, {0x72,0x01,0x1c,0x80,0x07,0x28,0x11,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xca20, 0, {0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18 }, - 16, 0xca30, 0, {0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60 }, - 16, 0xca40, 0, {0x00,0x18,0x00,0x46,0x04,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80 }, - 16, 0xca50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x04,0x22,0x01,0x08,0x80 }, - 16, 0xca60, 0, {0x02,0x20,0x00,0x90,0x04,0x27,0x81,0x08,0x80,0x42,0x20,0x10,0x98,0x04,0x24,0x01 }, - 16, 0xca70, 0, {0x08,0x80,0x42,0x48,0x10,0x88,0x04,0x22,0x01,0x09,0x40,0x42,0x60,0x10,0x88,0x04 }, - 16, 0xca80, 0, {0x22,0x01,0x08,0xc0,0x02,0x40,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xca90, 0, {0x00,0x00,0x2a,0x04,0x4b,0x81,0x12,0xa0,0x04,0xa8,0x01,0x2a,0x04,0x4a,0x81,0x12 }, - 16, 0xcaa0, 0, {0xa0,0x44,0xa8,0x11,0x2a,0x04,0x48,0x80,0x12,0xa0,0x44,0x88,0x01,0x2a,0x04,0x4a }, - 16, 0xcab0, 0, {0x81,0x12,0x20,0x04,0xac,0x11,0x2a,0x04,0x4a,0x81,0x12,0xb0,0x44,0x9c,0x11,0x00 }, - 16, 0xcac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x0c,0x00,0x53,0x00,0x14,0xc0 }, - 16, 0xcad0, 0, {0x05,0x30,0x01,0x44,0x00,0x53,0x00,0x14,0xc0,0x05,0x30,0x04,0x0c,0x00,0x53,0x00 }, - 16, 0xcae0, 0, {0x14,0xc0,0x05,0xb0,0x01,0x4c,0x00,0x53,0x00,0x16,0xc0,0x01,0x30,0x01,0x4c,0x00 }, - 16, 0xcaf0, 0, {0x53,0x00,0x14,0xc0,0x01,0x38,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcb00, 0, {0x08,0xc0,0x00,0x10,0x40,0x00,0x10,0x00,0x04,0x00,0x01,0x10,0x00,0x44,0x80,0x10 }, - 16, 0xcb10, 0, {0x00,0x04,0x00,0x01,0x10,0x00,0x46,0x00,0x00,0x00,0x04,0x60,0x01,0x00,0x00,0x40 }, - 16, 0xcb20, 0, {0x00,0x11,0x60,0x02,0x40,0x01,0x00,0x10,0x40,0x00,0x10,0x60,0x01,0x50,0x10,0x40 }, - 16, 0xcb30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x40,0x02,0x00,0x00,0x80,0x00 }, - 16, 0xcb40, 0, {0x20,0x00,0x08,0x08,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00 }, - 16, 0xcb50, 0, {0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x08,0x00,0x02 }, - 16, 0xcb60, 0, {0x00,0x00,0x80,0x00,0x21,0x00,0x08,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcb70, 0, {0x08,0xc0,0x40,0x04,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01,0x18 }, - 16, 0xcb80, 0, {0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01,0xc8,0x00,0x46,0x00,0x19,0x80,0x00,0x60 }, - 16, 0xcb90, 0, {0x00,0x18,0x00,0x66,0x00,0x11,0x80,0x04,0x60,0x01,0x18,0x00,0x06,0x00,0x11,0x80 }, - 16, 0xcba0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x02,0x60,0x00,0x98,0x00 }, - 16, 0xcbb0, 0, {0x26,0x00,0x09,0x81,0x02,0x60,0x01,0x98,0x00,0x26,0x00,0x09,0x80,0x06,0x62,0x00 }, - 16, 0xcbc0, 0, {0x48,0x00,0x26,0x20,0x01,0xc0,0x02,0x60,0x01,0x98,0x00,0x07,0x00,0x09,0x80,0x02 }, - 16, 0xcbd0, 0, {0x60,0x00,0x98,0x00,0x26,0x00,0x11,0x82,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcbe0, 0, {0x40,0x45,0x42,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x85,0x8c }, - 16, 0xcbf0, 0, {0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x48,0x11,0x82,0x04,0x30 }, - 16, 0xcc00, 0, {0x81,0x8d,0x20,0x46,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x0c,0x10,0xc0 }, - 16, 0xcc10, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x00,0x00,0x30,0x00,0x0c,0x00 }, - 16, 0xcc20, 0, {0x03,0x00,0x00,0xc0,0x00,0x10,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00 }, - 16, 0xcc30, 0, {0x08,0x00,0x03,0x00,0x00,0x80,0x00,0x30,0x00,0x0c,0x80,0x02,0x00,0x00,0xc0,0x00 }, - 16, 0xcc40, 0, {0x30,0x00,0x0c,0x00,0x03,0x20,0x00,0xc0,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcc50, 0, {0x40,0x00,0x02,0x00,0x30,0x80,0x0c,0x21,0x03,0x08,0x00,0xc2,0x00,0x30,0x80,0x0c }, - 16, 0xcc60, 0, {0x20,0x03,0x08,0x00,0xc2,0x04,0x30,0xc1,0x0c,0x20,0x03,0x0c,0x10,0xc2,0x00,0x30 }, - 16, 0xcc70, 0, {0x80,0x0c,0xb0,0x43,0x08,0x00,0xc2,0x00,0x30,0x80,0x0c,0x20,0x03,0x28,0x10,0xc0 }, - 16, 0xcc80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x04,0x60,0x81,0x18,0x20 }, - 16, 0xcc90, 0, {0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0x81 }, - 16, 0xcca0, 0, {0x18,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x06,0x08,0x11,0x82,0x04 }, - 16, 0xccb0, 0, {0x60,0x81,0x18,0x20,0x46,0x0c,0x11,0xc0,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xccc0, 0, {0x40,0x01,0x42,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08 }, - 16, 0xccd0, 0, {0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x0c,0x20,0x02,0x08,0x00,0xc2,0x00,0x20 }, - 16, 0xcce0, 0, {0x80,0x08,0x20,0x42,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x01,0x80 }, - 16, 0xccf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x42,0x04,0x60,0x81,0x18,0x20 }, - 16, 0xcd00, 0, {0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0xc1 }, - 16, 0xcd10, 0, {0x0c,0x20,0x46,0x0c,0x10,0xc2,0x04,0x60,0x80,0x18,0x30,0x42,0x08,0x11,0x82,0x04 }, - 16, 0xcd20, 0, {0x60,0x81,0x18,0x20,0x46,0x08,0x10,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcd30, 0, {0x40,0x45,0x40,0x04,0x50,0x01,0x14,0x00,0x45,0x00,0x11,0x40,0x04,0x50,0x00,0x14 }, - 16, 0xcd40, 0, {0x00,0x45,0x00,0x11,0x40,0x00,0x50,0x00,0x04,0x00,0x45,0x00,0x00,0x40,0x04,0x50 }, - 16, 0xcd50, 0, {0x00,0x14,0x00,0x01,0x00,0x11,0x40,0x04,0x50,0x01,0x14,0x00,0x45,0x00,0x00,0x42 }, - 16, 0xcd60, 0, {0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x06,0x00,0x41,0x80,0x10,0x60 }, - 16, 0xcd70, 0, {0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80 }, - 16, 0xcd80, 0, {0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x06,0x00 }, - 16, 0xcd90, 0, {0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcda0, 0, {0x48,0x00,0x02,0x01,0x00,0x80,0x40,0x21,0x10,0x08,0x04,0x02,0x01,0x00,0x80,0x40 }, - 16, 0xcdb0, 0, {0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x80,0x40,0x21,0x10,0x08,0x04,0x02,0x01,0x00 }, - 16, 0xcdc0, 0, {0x80,0x40,0x30,0x10,0x08,0x04,0x02,0x11,0x00,0x84,0x40,0x20,0x10,0x08,0x14,0x00 }, - 16, 0xcdd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x46,0x03,0x51,0x80,0xd4,0x60 }, - 16, 0xcde0, 0, {0x35,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x46,0x03,0x51,0x80 }, - 16, 0xcdf0, 0, {0xd4,0x60,0x35,0x10,0x0d,0x46,0x03,0x51,0x80,0xd4,0x40,0x35,0x18,0x0d,0x46,0x03 }, - 16, 0xce00, 0, {0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xce10, 0, {0x00,0x01,0x46,0x04,0x71,0x81,0x1c,0x60,0x07,0x18,0x11,0xce,0x04,0x71,0x81,0x1c }, - 16, 0xce20, 0, {0x60,0x47,0x18,0x01,0xc6,0x04,0x71,0x81,0x9c,0x60,0x47,0x18,0x19,0xc6,0x04,0x71 }, - 16, 0xce30, 0, {0x80,0x1c,0x60,0x67,0x18,0x11,0xc6,0x04,0x71,0x81,0x1c,0x60,0x47,0x18,0x11,0xc0 }, - 16, 0xce40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x46,0x02,0x71,0x80,0x9c,0x60 }, - 16, 0xce50, 0, {0x27,0x18,0x09,0xc6,0x06,0x71,0x80,0x1c,0x60,0x27,0x18,0x09,0xc6,0x01,0x31,0x80 }, - 16, 0xce60, 0, {0x1c,0x60,0x07,0x18,0x09,0xc6,0x02,0x71,0x80,0x9c,0x60,0x07,0x18,0x09,0xc6,0x12 }, - 16, 0xce70, 0, {0x71,0x80,0x9c,0x60,0x33,0x18,0x01,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xce80, 0, {0x50,0x45,0x46,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71,0x80,0x5c }, - 16, 0xce90, 0, {0x60,0x57,0x18,0x15,0xc6,0x01,0x31,0x81,0x0c,0x60,0x17,0x18,0x10,0xc6,0x05,0x71 }, - 16, 0xcea0, 0, {0x81,0x5c,0x60,0x03,0x18,0x15,0xc6,0x05,0x71,0x81,0x5c,0x60,0x53,0x18,0x18,0x82 }, - 16, 0xceb0, 0, {0x10,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x12,0x01,0x24,0x80,0x48,0x20 }, - 16, 0xcec0, 0, {0x12,0x08,0x04,0x82,0x01,0x24,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 }, - 16, 0xced0, 0, {0x58,0x20,0x52,0x0c,0x05,0x82,0x01,0x20,0x80,0x49,0x20,0x02,0x08,0x04,0x82,0x01 }, - 16, 0xcee0, 0, {0x20,0x80,0x49,0x20,0x12,0x48,0x04,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcef0, 0, {0x40,0x04,0x06,0x00,0x61,0x80,0x18,0x60,0x06,0x18,0x01,0x86,0x04,0x61,0x80,0x18 }, - 16, 0xcf00, 0, {0x60,0x06,0x18,0x01,0x86,0x00,0x61,0x81,0x48,0x60,0x06,0x18,0x14,0x86,0x00,0x61 }, - 16, 0xcf10, 0, {0x80,0x18,0x60,0x42,0x18,0x01,0x86,0x00,0x61,0x80,0x18,0x60,0x06,0x18,0x00,0x80 }, - 16, 0xcf20, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x60,0x04,0x78,0x01,0x1e,0x00 }, - 16, 0xcf30, 0, {0x47,0x80,0x11,0xe8,0x00,0x78,0x01,0x1e,0x00,0x47,0x80,0x11,0xe0,0x04,0x78,0x01 }, - 16, 0xcf40, 0, {0x1e,0x00,0x43,0x80,0x11,0xe0,0x04,0x78,0x01,0x1e,0x00,0x03,0x80,0x15,0xe0,0x04 }, - 16, 0xcf50, 0, {0x78,0x01,0x1e,0x00,0x47,0x80,0x11,0xc0,0x10,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcf60, 0, {0x40,0x01,0x12,0x00,0x64,0x80,0x18,0x20,0x06,0x08,0x01,0x82,0x00,0x64,0x80,0x18 }, - 16, 0xcf70, 0, {0x20,0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18,0x30,0x02,0x08,0x01,0x82,0x00,0x60 }, - 16, 0xcf80, 0, {0x80,0x19,0x30,0x42,0x08,0x00,0x82,0x00,0x60,0x80,0x19,0x20,0x06,0x48,0x01,0x80 }, - 16, 0xcf90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x42,0x04,0x20,0x81,0x08,0x20 }, - 16, 0xcfa0, 0, {0x42,0x08,0x10,0x82,0x00,0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81 }, - 16, 0xcfb0, 0, {0x08,0x20,0x46,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x11,0x82,0x04 }, - 16, 0xcfc0, 0, {0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xcfd0, 0, {0x40,0x45,0x42,0x04,0x40,0x81,0x10,0x20,0x44,0x08,0x11,0x02,0x00,0x40,0x81,0x10 }, - 16, 0xcfe0, 0, {0x20,0x44,0x08,0x11,0x02,0x04,0x40,0x80,0x10,0x20,0x45,0x08,0x01,0x02,0x04,0x40 }, - 16, 0xcff0, 0, {0x81,0x10,0x21,0x00,0x0c,0x11,0x02,0x04,0x40,0x81,0x10,0x20,0x44,0x08,0x01,0x00 }, - 16, 0xd000, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x03,0x00,0x50,0xc0,0x14,0x30 }, - 16, 0xd010, 0, {0x05,0x0c,0x01,0x43,0x00,0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x43,0x00,0x50,0xc0 }, - 16, 0xd020, 0, {0x14,0x30,0x05,0x0c,0x01,0x43,0x00,0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x43,0x00 }, - 16, 0xd030, 0, {0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd040, 0, {0x40,0x00,0x08,0x00,0x42,0x04,0x10,0x80,0x04,0x20,0x01,0x09,0x00,0x42,0x01,0x10 }, - 16, 0xd050, 0, {0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x00,0x10,0x00,0x04,0x20,0x01,0x08,0x00,0x42 }, - 16, 0xd060, 0, {0x00,0x10,0x00,0x04,0x00,0x01,0x08,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x11,0x00 }, - 16, 0xd070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x02,0x00,0x80,0x80,0x20 }, - 16, 0xd080, 0, {0x20,0x08,0x08,0x02,0x02,0x00,0x80,0x00,0x20,0x20,0x08,0x08,0x02,0x00,0x00,0x80 }, - 16, 0xd090, 0, {0x80,0xa0,0x00,0x0a,0x08,0x02,0x02,0x00,0x80,0x80,0x34,0x62,0x28,0x08,0x02,0x02 }, - 16, 0xd0a0, 0, {0x00,0x80,0x80,0x30,0x20,0x0c,0x08,0x00,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd0b0, 0, {0x40,0x01,0x40,0x04,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x03,0x18 }, - 16, 0xd0c0, 0, {0x00,0x46,0x00,0x11,0x80,0x06,0x60,0x01,0x98,0x00,0x46,0x00,0x11,0x80,0x04,0x60 }, - 16, 0xd0d0, 0, {0x01,0x18,0x00,0x66,0x00,0x11,0x80,0x04,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80 }, - 16, 0xd0e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x00,0x02,0x60,0x00,0x98,0x00 }, - 16, 0xd0f0, 0, {0x26,0x00,0x09,0x80,0x02,0x64,0x00,0x98,0x00,0x26,0x00,0x19,0x90,0x02,0x60,0x00 }, - 16, 0xd100, 0, {0x1d,0x00,0x26,0x00,0x01,0xc0,0x02,0x60,0x00,0x99,0x00,0x06,0x40,0x19,0x80,0x02 }, - 16, 0xd110, 0, {0x60,0x00,0x98,0x00,0x66,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd120, 0, {0x40,0x45,0x60,0x04,0x38,0x01,0x0e,0x00,0x43,0x80,0x10,0xe0,0x04,0x38,0x01,0x0e }, - 16, 0xd130, 0, {0x00,0x43,0x80,0x10,0xe0,0x04,0x38,0x01,0x1a,0x00,0x43,0x80,0x11,0xa0,0x04,0x38 }, - 16, 0xd140, 0, {0x01,0x0e,0x00,0x02,0x80,0x40,0xe0,0x04,0x38,0x01,0x0e,0x00,0x43,0x80,0x18,0x80 }, - 16, 0xd150, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x04,0x01,0x00,0x30,0x40,0x0c,0x10 }, - 16, 0xd160, 0, {0x03,0x04,0x00,0xc9,0x00,0x30,0x40,0x0c,0x10,0x03,0x04,0x00,0xc1,0x00,0x30,0x40 }, - 16, 0xd170, 0, {0x08,0x10,0x03,0x04,0x00,0x81,0x00,0x30,0x40,0x0c,0x78,0x02,0x14,0x00,0xc1,0x00 }, - 16, 0xd180, 0, {0x30,0x40,0x0c,0x10,0x03,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd190, 0, {0x40,0x00,0x05,0x00,0x31,0x40,0x0c,0x50,0x03,0x14,0x00,0xc5,0x00,0x35,0x40,0x0c }, - 16, 0xd1a0, 0, {0x50,0x03,0x14,0x10,0xd5,0x00,0x31,0x41,0x0d,0x50,0x03,0x14,0x10,0xc5,0x00,0x31 }, - 16, 0xd1b0, 0, {0x40,0x0d,0x48,0x43,0x54,0x10,0xc5,0x00,0x31,0x40,0x0c,0x40,0x43,0x10,0x00,0xc2 }, - 16, 0xd1c0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x43,0x04,0x60,0xc1,0x18,0x30 }, - 16, 0xd1d0, 0, {0x46,0x0c,0x11,0x83,0x04,0x61,0xc1,0x18,0x30,0x46,0x0c,0x01,0x87,0x04,0x60,0xc1 }, - 16, 0xd1e0, 0, {0x18,0x30,0x46,0x08,0x11,0x83,0x04,0x60,0xc1,0x18,0x20,0x06,0x0c,0x01,0x83,0x04 }, - 16, 0xd1f0, 0, {0x60,0xc1,0x18,0x30,0x46,0x0c,0x11,0x80,0x10,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd200, 0, {0x40,0x01,0x40,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08 }, - 16, 0xd210, 0, {0x00,0x02,0x00,0x00,0x81,0x00,0x20,0x00,0x08,0x80,0x02,0x00,0x00,0xc0,0x00,0x20 }, - 16, 0xd220, 0, {0x00,0x08,0x40,0x43,0x30,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80 }, - 16, 0xd230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x48,0x44,0x62,0x11,0x18,0x84 }, - 16, 0xd240, 0, {0x46,0x21,0x11,0x88,0x44,0x63,0x01,0x18,0x84,0x46,0x21,0x01,0x88,0x04,0x62,0x11 }, - 16, 0xd250, 0, {0x18,0x04,0x46,0x21,0x10,0xc8,0x44,0x62,0x11,0x18,0x05,0x43,0x01,0x81,0x88,0x44 }, - 16, 0xd260, 0, {0x62,0x11,0x18,0x84,0x46,0x21,0x11,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd270, 0, {0x40,0x45,0x40,0x04,0x50,0x01,0x14,0x04,0x45,0x01,0x11,0x40,0x44,0x50,0x01,0x14 }, - 16, 0xd280, 0, {0x04,0x45,0x01,0x01,0x40,0x45,0x00,0x10,0x14,0x04,0x45,0x03,0x00,0x40,0x44,0x50 }, - 16, 0xd290, 0, {0x11,0x14,0x04,0x01,0x05,0x41,0x40,0x44,0x50,0x11,0x14,0x04,0x05,0x01,0x01,0x40 }, - 16, 0xd2a0, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x20,0x42,0x08,0x10,0x82 }, - 16, 0xd2b0, 0, {0x04,0x20,0x81,0x08,0x00,0x42,0x00,0x10,0x82,0x04,0x20,0x81,0x08,0x00,0x42,0x08 }, - 16, 0xd2c0, 0, {0x10,0x82,0x05,0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x8a,0x05,0x20,0x05,0x08,0x20 }, - 16, 0xd2d0, 0, {0x42,0x08,0x10,0x82,0x04,0x22,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd2e0, 0, {0x00,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x02,0x01,0x02,0x80,0x40 }, - 16, 0xd2f0, 0, {0xa0,0x10,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa0,0x00,0x29,0x04,0x0a,0x01,0x02 }, - 16, 0xd300, 0, {0x80,0x40,0xa4,0x00,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa8,0x10,0x2b,0x14,0x00 }, - 16, 0xd310, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x4d,0x03,0x53,0x40,0xd4,0xd0 }, - 16, 0xd320, 0, {0x35,0x34,0x0d,0x4d,0x03,0x53,0x40,0xd4,0xd0,0x35,0x34,0x0d,0x4d,0x03,0x53,0x40 }, - 16, 0xd330, 0, {0xd4,0xd0,0x21,0x34,0x4d,0x4d,0x03,0x53,0x40,0xd4,0xd9,0x61,0x34,0x04,0x0d,0x03 }, - 16, 0xd340, 0, {0x53,0x40,0xc0,0xd8,0x35,0x37,0x0d,0x40,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd350, 0, {0x40,0x01,0x48,0x04,0x72,0x00,0x1c,0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x01,0x1c }, - 16, 0xd360, 0, {0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x00,0x9c,0x80,0x47,0x20,0x19,0xc8,0x00,0x72 }, - 16, 0xd370, 0, {0x01,0x1c,0x88,0x67,0x20,0x11,0xc8,0x04,0x72,0x01,0x5c,0x82,0x47,0x22,0x11,0xc0 }, - 16, 0xd380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x08,0x48,0xc2,0x12,0x31 }, - 16, 0xd390, 0, {0x84,0x8c,0x61,0x23,0x10,0x40,0xc0,0x12,0x31,0x84,0x8c,0x61,0x03,0x10,0x48,0xc4 }, - 16, 0xd3a0, 0, {0x10,0x31,0x84,0x8c,0x41,0x23,0x18,0x48,0xc6,0x10,0x30,0x04,0x0c,0x41,0x23,0x18 }, - 16, 0xd3b0, 0, {0x48,0xc6,0x12,0x30,0x84,0x8c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd3c0, 0, {0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3 }, - 16, 0xd3d0, 0, {0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f }, - 16, 0xd3e0, 0, {0xff,0xd3,0xff,0xf4,0xff,0xdd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x00 }, - 16, 0xd3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd430, 0, {0x00,0x00,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2 }, - 16, 0xd440, 0, {0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b }, - 16, 0xd450, 0, {0x36,0xc2,0xcd,0xb0,0xb3,0x4c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x00 }, - 16, 0xd460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x5c,0x4c,0xd7,0x13,0x33 }, - 16, 0xd470, 0, {0xc4,0xcc,0xf1,0x33,0x3a,0x4a,0xd6,0x93,0x33,0xc4,0xcc,0xf1,0x2b,0x3a,0x4c,0xcf }, - 16, 0xd480, 0, {0x13,0x33,0xc4,0xcc,0xe9,0x33,0x3c,0x4c,0xcf,0x12,0xb5,0xa4,0xac,0xc9,0x33,0x3c }, - 16, 0xd490, 0, {0x4c,0xcf,0x13,0x35,0xc4,0xcd,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd4a0, 0, {0x00,0x00,0x3b,0x7e,0x4e,0xdf,0x93,0xb7,0xe4,0xed,0xf9,0x3b,0x7e,0x4e,0xdf,0x93 }, - 16, 0xd4b0, 0, {0xb7,0xe4,0xed,0xf9,0x3b,0x7e,0x4e,0xde,0x12,0x37,0xe4,0xed,0xe1,0x3b,0x7e,0x4e }, - 16, 0xd4c0, 0, {0xdf,0x92,0x31,0x84,0x8d,0xd9,0x3b,0x7e,0x4e,0xdf,0x93,0xb1,0xe4,0xec,0x61,0x00 }, - 16, 0xd4d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x04,0xa1,0x83,0x2c }, - 16, 0xd4e0, 0, {0x03,0x0a,0x10,0x82,0xc1,0x34,0x10,0x8f,0x00,0x40,0x09,0x14,0x02,0x03,0x14,0x91 }, - 16, 0xd4f0, 0, {0x00,0x08,0x42,0x0b,0x18,0x82,0xc4,0x00,0x31,0xca,0x0c,0x52,0x02,0x10,0x80,0x85 }, - 16, 0xd500, 0, {0x00,0x21,0x82,0x28,0x40,0x0a,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd510, 0, {0x00,0x00,0x0a,0x04,0x02,0x01,0x40,0x80,0x73,0x28,0x10,0x48,0x07,0x06,0x01,0x04 }, - 16, 0xd520, 0, {0xa4,0x41,0x21,0x14,0x08,0x44,0x06,0x11,0x40,0x80,0x70,0x20,0x14,0x0a,0x04,0x02 }, - 16, 0xd530, 0, {0x00,0xc8,0x84,0x41,0x21,0x1c,0x08,0x06,0x12,0x01,0xc0,0x80,0x60,0x20,0x14,0x00 }, - 16, 0xd540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x84,0x04,0x21,0x82,0x08 }, - 16, 0xd550, 0, {0x53,0x02,0x10,0x80,0xc5,0x00,0x81,0x4a,0x04,0x42,0x02,0x14,0x00,0x04,0x20,0x21 }, - 16, 0xd560, 0, {0x80,0xa8,0x72,0x22,0x1c,0x88,0xc4,0x06,0xa1,0x42,0x8c,0x52,0x22,0x1c,0x88,0x85 }, - 16, 0xd570, 0, {0x26,0x21,0xc0,0x88,0x50,0x22,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd580, 0, {0x00,0x00,0x02,0x44,0x00,0x01,0x01,0x00,0x62,0x00,0x10,0x00,0x04,0x00,0x01,0x01 }, - 16, 0xd590, 0, {0x20,0x40,0x00,0x1c,0x00,0x44,0x04,0x01,0x02,0x20,0x62,0x00,0x1c,0x80,0x04,0x04 }, - 16, 0xd5a0, 0, {0x80,0x89,0x20,0x50,0x08,0x14,0x80,0x04,0x24,0x01,0xc1,0x00,0x50,0x00,0x18,0x00 }, - 16, 0xd5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,0x38,0x20,0x04,0x0c }, - 16, 0xd5c0, 0, {0x31,0x0a,0x00,0x00,0x02,0x18,0x20,0x8c,0xa8,0x10,0x28,0x08,0x88,0xc1,0x14,0x10 }, - 16, 0xd5d0, 0, {0xc6,0x00,0x22,0x03,0x08,0x02,0x01,0x08,0xb0,0x00,0x0c,0x21,0x02,0x00,0x82,0x80 }, - 16, 0xd5e0, 0, {0x08,0x00,0x49,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd5f0, 0, {0x00,0x00,0x00,0x01,0x00,0x80,0x08,0x20,0x03,0x00,0x04,0x02,0x43,0x20,0x00,0x40 }, - 16, 0xd600, 0, {0x00,0x20,0x00,0x04,0x42,0x01,0x10,0x80,0x84,0x20,0x11,0x08,0x04,0x00,0x00,0x00 }, - 16, 0xd610, 0, {0x00,0x44,0x24,0x20,0x09,0x08,0x40,0x03,0x00,0x90,0xc4,0x20,0x20,0x08,0x0c,0x02 }, - 16, 0xd620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x81,0x08,0x20,0x04,0x88 }, - 16, 0xd630, 0, {0x02,0x22,0x08,0x08,0xc3,0x2a,0x90,0x40,0x84,0x10,0x20,0x04,0x80,0xc2,0x26,0x20 }, - 16, 0xd640, 0, {0x49,0x88,0x22,0x22,0x0c,0x08,0xc1,0x26,0xa0,0xc9,0x8c,0x12,0x2a,0x04,0x88,0x43 }, - 16, 0xd650, 0, {0x0e,0xa0,0xcb,0x88,0x10,0x22,0x0c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd660, 0, {0x08,0x00,0x0a,0x40,0x32,0x00,0x01,0x80,0x31,0x28,0x00,0x00,0x01,0x12,0x80,0x8d }, - 16, 0xd670, 0, {0x84,0x00,0x28,0x0c,0x08,0x01,0x32,0x00,0x8c,0x80,0x02,0x20,0x0c,0x08,0x01,0x2e }, - 16, 0xd680, 0, {0x00,0xc3,0x80,0x02,0x20,0x04,0x08,0x43,0x02,0x00,0x40,0x80,0x10,0x20,0x04,0x02 }, - 16, 0xd690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x87,0x0a,0x21,0x04,0x88 }, - 16, 0xd6a0, 0, {0x11,0x2a,0x1c,0x0a,0x06,0x22,0x21,0x40,0xa0,0x42,0x2a,0x10,0x88,0x85,0x0a,0xa1 }, - 16, 0xd6b0, 0, {0x06,0xa4,0x62,0x22,0x1c,0x0a,0xc4,0x02,0x21,0x80,0x8c,0x52,0x22,0x14,0x48,0x86 }, - 16, 0xd6c0, 0, {0x22,0x20,0x08,0xa8,0x60,0x2a,0x14,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd6d0, 0, {0x00,0x00,0x08,0x45,0x06,0x01,0x89,0x80,0x63,0x20,0x1c,0x88,0x40,0x34,0x11,0x01 }, - 16, 0xd6e0, 0, {0xa4,0x50,0x28,0x18,0x48,0x04,0x0e,0x01,0x4b,0x80,0x73,0x28,0x1c,0x8a,0x04,0x06 }, - 16, 0xd6f0, 0, {0x91,0x49,0x04,0x63,0x20,0x1c,0x8a,0x06,0x26,0x01,0x85,0x80,0x70,0x20,0x18,0x02 }, - 16, 0xd700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x85,0x00,0xb1,0x45,0x2c }, - 16, 0xd710, 0, {0x70,0x02,0x14,0xc0,0x07,0x08,0x21,0x49,0x00,0x42,0x01,0x14,0x82,0x05,0x00,0x11 }, - 16, 0xd720, 0, {0x84,0x00,0x52,0x02,0x1c,0x00,0xc4,0x00,0x21,0xc4,0x2c,0x53,0x02,0x1c,0x02,0x81 }, - 16, 0xd730, 0, {0x04,0xa1,0xcd,0x08,0x50,0x02,0x14,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd740, 0, {0x08,0x10,0x12,0x04,0x34,0x01,0xcc,0x00,0x73,0x40,0x1c,0x90,0x45,0x04,0x01,0x48 }, - 16, 0xd750, 0, {0x04,0x60,0x41,0x18,0xc0,0x44,0x04,0x01,0x05,0x04,0x73,0x48,0x14,0x50,0x47,0x34 }, - 16, 0xd760, 0, {0x01,0x45,0x20,0x62,0x08,0x1c,0xc2,0x04,0x0c,0x81,0xc7,0x00,0x73,0x80,0x18,0xc2 }, - 16, 0xd770, 0, {0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x84,0x10,0x21,0xcc,0x28 }, - 16, 0xd780, 0, {0x42,0x02,0x14,0x12,0xc5,0x10,0x21,0x84,0x04,0x40,0x00,0x1c,0x80,0x84,0x00,0x91 }, - 16, 0xd790, 0, {0x00,0x08,0x73,0x82,0x1c,0x90,0x05,0x0c,0x01,0xcf,0x0c,0x40,0x02,0x14,0x30,0x45 }, - 16, 0xd7a0, 0, {0x20,0xa1,0xc0,0x08,0x50,0x02,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd7b0, 0, {0x00,0x00,0x00,0x45,0x0c,0x81,0x00,0x00,0x01,0x08,0x08,0x00,0x05,0x18,0x91,0x05 }, - 16, 0xd7c0, 0, {0x04,0x00,0x01,0x04,0x40,0x06,0x18,0x00,0x02,0x24,0x70,0x40,0x04,0x00,0x40,0x00 }, - 16, 0xd7d0, 0, {0x01,0xc4,0x24,0x00,0x88,0x04,0x00,0x43,0x10,0x00,0x40,0x20,0x00,0x88,0x00,0x00 }, - 16, 0xd7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x85,0x24,0x31,0x02,0x0c }, - 16, 0xd7f0, 0, {0x02,0xc2,0x04,0x10,0xc4,0x28,0x21,0x49,0x0c,0x02,0xc0,0x04,0xb2,0x06,0x1c,0x20 }, - 16, 0xd800, 0, {0x03,0x08,0x50,0x42,0x0c,0x80,0x01,0x04,0xa1,0x49,0x0c,0x00,0xc2,0x0c,0x10,0x43 }, - 16, 0xd810, 0, {0x24,0xa0,0xc1,0x08,0x10,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd820, 0, {0x00,0x10,0xa2,0x00,0x20,0x00,0xcd,0x00,0x00,0x40,0x04,0x20,0x01,0x10,0x00,0x09 }, - 16, 0xd830, 0, {0x04,0x02,0x49,0x0c,0x92,0x07,0x30,0x00,0x00,0x00,0x33,0x08,0x0c,0x92,0x41,0x00 }, - 16, 0xd840, 0, {0x80,0xcc,0x00,0x00,0x00,0x0c,0x00,0x43,0x28,0x80,0xc2,0x00,0x10,0x00,0x00,0x00 }, - 16, 0xd850, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x50,0x80,0x00,0x00 }, - 16, 0xd860, 0, {0x10,0x00,0x00,0xf0,0x00,0x10,0x80,0x00,0x00,0x00,0x80,0x00,0xd0,0x80,0x80,0x00 }, - 16, 0xd870, 0, {0x00,0x00,0x00,0x80,0x10,0x90,0x80,0x80,0x00,0x00,0x00,0x00,0x80,0x10,0x90,0x80 }, - 16, 0xd880, 0, {0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd890, 0, {0x3c,0x3c,0x10,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0xa0,0x80,0x00,0x00 }, - 16, 0xd8a0, 0, {0x00,0x00,0x40,0x10,0x90,0x80,0xa0,0x00,0x00,0x00,0x00,0xc0,0x10,0x90,0x80,0xa0 }, - 16, 0xd8b0, 0, {0x00,0x00,0x00,0x20,0x80,0x10,0x90,0xa0,0xa0,0x00,0x00,0x00,0x00,0x80,0x10,0x8f }, - 16, 0xd8c0, 0, {0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xc2,0xe4,0x81,0x80,0x3f }, - 16, 0xd8d0, 0, {0xd9,0xbf,0xd9,0x98,0x71,0x9d,0x42,0x80,0x00,0x26,0x7f,0xe6,0x72,0xab,0x7c,0x3a }, - 16, 0xd8e0, 0, {0x40,0x00,0x19,0x80,0x26,0x48,0xdd,0x3c,0x91,0xc0,0x26,0x40,0x26,0x40,0x38,0x31 }, - 16, 0xd8f0, 0, {0xdb,0x61,0xc0,0x19,0x99,0xbf,0xc9,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd900, 0, {0x00,0x00,0x10,0x80,0x10,0x14,0x80,0x06,0x84,0x97,0x96,0x86,0x96,0x06,0x90,0x00 }, - 16, 0xd910, 0, {0x3f,0xa1,0x28,0x01,0x02,0x90,0x12,0x00,0x80,0x17,0x88,0x16,0x9e,0x90,0x90,0x04 }, - 16, 0xd920, 0, {0x10,0x00,0x36,0xbe,0xbe,0x9e,0x86,0x16,0x12,0x84,0x80,0x13,0xbe,0x97,0xae,0x80 }, - 16, 0xd930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x82 }, - 16, 0xd940, 0, {0x81,0x84,0x21,0x40,0x00,0x00,0x00,0x08,0xa1,0x38,0x01,0x78,0x00,0x00,0x00,0x00 }, - 16, 0xd950, 0, {0x08,0xb8,0x21,0x72,0x68,0x80,0x00,0x00,0x00,0x08,0x98,0x44,0x88,0x68,0x80,0x00 }, - 16, 0xd960, 0, {0x00,0x00,0x08,0xb8,0x01,0x78,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd970, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xf7,0xaf,0xff,0xc0 }, - 16, 0xd980, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff }, - 16, 0xd990, 0, {0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xbf,0xff,0xc0,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }, - 16, 0xd9b0, 0, {0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0x40,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff }, - 16, 0xd9c0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff }, - 16, 0xd9d0, 0, {0x2f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xd9e0, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0xc0 }, - 16, 0xd9f0, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff }, - 16, 0xda00, 0, {0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0x80,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xda10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }, - 16, 0xda20, 0, {0x00,0x00,0x00,0x3f,0xff,0xbf,0xbf,0xc0,0x00,0x00,0x00,0x00,0x3f,0xdf,0xbf,0xdf }, - 16, 0xda30, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xef,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x3f,0xdf }, - 16, 0xda40, 0, {0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xda50, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0x3e,0xaf,0xff,0xc0 }, - 16, 0xda60, 0, {0x00,0x00,0x00,0x00,0x1f,0xff,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xe7,0xfe }, - 16, 0xda70, 0, {0xef,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xdf,0xc0,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xda80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }, - 16, 0xda90, 0, {0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x2f,0xf7,0xff,0xff }, - 16, 0xdaa0, 0, {0xc0,0x00,0x00,0x00,0x00,0x2f,0xff,0xff,0xdf,0xc0,0x00,0x00,0x00,0x00,0x3f,0xf7 }, - 16, 0xdab0, 0, {0xdf,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdac0, 0, {0x00,0x00,0x02,0xc4,0x00,0xb1,0xc3,0x2c,0x50,0x09,0x14,0x82,0xc4,0x30,0x91,0xc7 }, - 16, 0xdad0, 0, {0x24,0x60,0x08,0x1c,0x82,0x07,0x34,0x91,0x4c,0x04,0x43,0x0a,0x10,0xc2,0x84,0x04 }, - 16, 0xdae0, 0, {0x91,0x84,0x24,0x52,0x0b,0x18,0x02,0xc4,0x24,0xb1,0xc3,0x2c,0x40,0x0a,0x10,0x80 }, - 16, 0xdaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x02,0x01,0xc4,0x80 }, - 16, 0xdb00, 0, {0x60,0x20,0x1c,0x08,0x44,0x22,0x01,0xc0,0x84,0x50,0x01,0x9c,0x08,0x07,0x0a,0x01 }, - 16, 0xdb10, 0, {0xc0,0x84,0x72,0x20,0x1c,0xc8,0x04,0x12,0x11,0x44,0x80,0x41,0x01,0x1c,0x80,0x07 }, - 16, 0xdb20, 0, {0x08,0x11,0xc4,0x00,0x70,0x00,0x10,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdb30, 0, {0x00,0x00,0x00,0x86,0x2c,0x21,0x4a,0x0c,0x52,0x02,0x1c,0x80,0x04,0x20,0x21,0xca }, - 16, 0xdb40, 0, {0x10,0x62,0x02,0x1c,0x81,0x47,0x04,0x21,0xc3,0x20,0x51,0x01,0x1c,0x80,0x04,0x2c }, - 16, 0xdb50, 0, {0x01,0xcb,0x04,0x52,0x03,0x14,0x40,0xc7,0x20,0x31,0xc8,0x0c,0x50,0x22,0x10,0x80 }, - 16, 0xdb60, 0, {0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x20,0x01,0x89,0x00 }, - 16, 0xdb70, 0, {0x52,0x00,0x14,0x80,0x04,0x28,0x01,0x45,0x04,0x62,0x00,0x10,0x80,0x46,0x30,0x11 }, - 16, 0xdb80, 0, {0x0d,0x00,0x42,0x01,0x14,0xc0,0x44,0x00,0x11,0x05,0x00,0x50,0x00,0x1c,0x00,0x44 }, - 16, 0xdb90, 0, {0x28,0x01,0x49,0x00,0x70,0x00,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdba0, 0, {0x00,0x00,0x08,0xc0,0x02,0x30,0x0c,0x8c,0x30,0x22,0x08,0x88,0xc2,0x26,0x00,0x08 }, - 16, 0xdbb0, 0, {0x80,0x20,0x22,0x0c,0x88,0x81,0x02,0x10,0xc4,0x80,0x10,0x22,0x0c,0x08,0x40,0x02 }, - 16, 0xdbc0, 0, {0x10,0x48,0x88,0x01,0x23,0x04,0xc8,0x42,0x02,0x10,0x46,0x8c,0x12,0x22,0x00,0x00 }, - 16, 0xdbd0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0xc8,0x20 }, - 16, 0xdbe0, 0, {0x11,0x09,0x00,0x80,0x41,0x10,0x90,0x08,0x24,0x30,0x08,0x04,0x42,0x41,0x00,0x90 }, - 16, 0xdbf0, 0, {0xc4,0x20,0x00,0x08,0x04,0x42,0x00,0x10,0x80,0x4c,0x20,0x23,0x09,0x04,0xc2,0x43 }, - 16, 0xdc00, 0, {0x30,0x80,0x40,0x20,0x11,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdc10, 0, {0x08,0x00,0x08,0x81,0x02,0x20,0xc9,0x8c,0x12,0x20,0x04,0x48,0x41,0x22,0x00,0x09 }, - 16, 0xdc20, 0, {0x88,0x30,0x20,0x0c,0x88,0x03,0x0e,0x00,0x49,0x8c,0x10,0x22,0x0c,0x88,0x40,0x2e }, - 16, 0xdc30, 0, {0x00,0xc9,0x84,0x13,0x21,0x04,0xc8,0xc3,0x22,0x00,0xcb,0x8c,0x32,0x22,0x00,0x00 }, - 16, 0xdc40, 0, {0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x01,0x02,0x00,0x4b,0x80 }, - 16, 0xdc50, 0, {0x32,0x21,0x08,0x88,0x41,0x02,0x10,0x0f,0x80,0x10,0x21,0x8c,0x08,0x41,0x02,0x00 }, - 16, 0xdc60, 0, {0x87,0x84,0x10,0x20,0x04,0x88,0x00,0x02,0x00,0x47,0x80,0x10,0x21,0x0c,0x88,0x41 }, - 16, 0xdc70, 0, {0x16,0x10,0x46,0x80,0x30,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdc80, 0, {0x00,0x00,0x0a,0xc4,0x22,0xa1,0x08,0xa4,0x72,0x2a,0x14,0x0a,0x85,0x02,0x81,0x84 }, - 16, 0xdc90, 0, {0xa0,0x42,0x28,0x1c,0x0a,0xc5,0x02,0x91,0x40,0xb8,0x73,0x29,0x10,0xca,0xc4,0x02 }, - 16, 0xdca0, 0, {0xa1,0x80,0xa4,0x42,0x2a,0x14,0xca,0x85,0x22,0x91,0x80,0xa8,0x70,0x2a,0x18,0x02 }, - 16, 0xdcb0, 0, {0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x1e,0x01,0xc8,0x80 }, - 16, 0xdcc0, 0, {0x43,0x20,0x18,0x08,0x45,0x3e,0x01,0x0c,0x80,0x61,0x20,0x9c,0x48,0x06,0x12,0x81 }, - 16, 0xdcd0, 0, {0xc0,0x80,0x73,0x00,0x10,0x88,0x06,0x02,0x01,0xc8,0x00,0x42,0x20,0x10,0xc8,0x07 }, - 16, 0xdce0, 0, {0x02,0x11,0xcd,0x80,0x51,0x20,0x14,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdcf0, 0, {0x08,0x00,0x00,0xc4,0x24,0x21,0xc8,0x0c,0x42,0x01,0x14,0x00,0x00,0x28,0x10,0x4c }, - 16, 0xdd00, 0, {0x08,0x52,0x02,0x14,0x80,0x45,0x24,0x29,0x40,0x04,0x72,0x00,0x10,0xc0,0x05,0x24 }, - 16, 0xdd10, 0, {0x11,0x44,0x08,0x43,0x01,0x14,0xc0,0x47,0x24,0x20,0x48,0x08,0x72,0x02,0x10,0x00 }, - 16, 0xdd20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x07,0x10,0x11,0x06,0x00 }, - 16, 0xdd30, 0, {0x72,0x00,0x18,0xd0,0x46,0x20,0x01,0x4d,0x00,0x71,0x40,0x10,0x50,0x07,0x30,0x11 }, - 16, 0xdd40, 0, {0xc3,0x00,0x71,0x41,0x10,0xb0,0x05,0x2c,0x01,0x49,0x00,0x43,0x00,0x1c,0x50,0x45 }, - 16, 0xdd50, 0, {0x30,0x01,0x8c,0x00,0x61,0x40,0x18,0x42,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdd60, 0, {0x00,0x00,0x30,0xc5,0x00,0x21,0xc0,0x0c,0x40,0x01,0x14,0x12,0x44,0x04,0x31,0x84 }, - 16, 0xdd70, 0, {0x24,0x40,0x80,0x14,0xa1,0xc7,0x00,0x01,0x40,0x08,0x40,0x01,0x14,0x20,0x05,0x20 }, - 16, 0xdd80, 0, {0x11,0xc0,0x02,0x60,0x82,0x18,0x00,0x87,0x24,0x11,0x40,0x08,0x40,0x42,0x10,0x02 }, - 16, 0xdd90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0c,0x80,0xc4,0x24 }, - 16, 0xdda0, 0, {0x31,0x48,0x0c,0x00,0x01,0x08,0xc1,0x41,0x00,0x00,0x49,0x00,0x42,0x03,0x08,0x10 }, - 16, 0xddb0, 0, {0x80,0x20,0x21,0x09,0x0c,0x02,0x02,0x18,0x80,0xc1,0x24,0x30,0x08,0x0c,0x42,0x01 }, - 16, 0xddc0, 0, {0x10,0x80,0x83,0x20,0x11,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xddd0, 0, {0x00,0x00,0x10,0xc1,0x04,0x20,0x48,0x0c,0x12,0x42,0x04,0x00,0x83,0x00,0x31,0x48 }, - 16, 0xdde0, 0, {0x00,0x02,0x41,0x04,0xa0,0x07,0x0c,0x20,0x40,0x00,0x12,0xc2,0x0c,0x80,0xc1,0x20 }, - 16, 0xddf0, 0, {0x20,0xc8,0x00,0x12,0xc1,0x0c,0xb0,0x41,0x20,0x00,0x49,0x08,0x02,0x42,0x00,0x00 }, - 16, 0xde00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x80,0x01,0x00,0x10,0x81,0x00 }, - 16, 0xde10, 0, {0x30,0x40,0x08,0x20,0x03,0x00,0x10,0xc1,0x20,0x02,0x00,0x04,0x80,0x40,0x30,0x90 }, - 16, 0xde20, 0, {0x01,0x14,0x02,0x40,0x04,0x80,0x40,0x20,0x00,0x09,0x04,0x32,0x01,0x08,0xa0,0x03 }, - 16, 0xde30, 0, {0x04,0x10,0x08,0x00,0x22,0x40,0x00,0x00,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xde40, 0, {0x00,0x00,0x30,0x00,0x10,0x80,0x00,0x00,0x00,0x40,0x00,0xf0,0x00,0x00,0x00,0x00 }, - 16, 0xde50, 0, {0x00,0x10,0x80,0x00,0xf0,0x00,0x80,0x80,0x00,0x00,0x20,0x00,0x00,0xf0,0x10,0xa0 }, - 16, 0xde60, 0, {0x00,0x00,0x00,0x20,0x00,0x00,0xf0,0x00,0x10,0x00,0x00,0x00,0x20,0x80,0x00,0xcc }, - 16, 0xde70, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x10,0xa0,0x80,0x00,0x00,0x00 }, - 16, 0xde80, 0, {0x00,0x00,0x10,0x90,0x80,0xc0,0x40,0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x80,0x00 }, - 16, 0xde90, 0, {0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x80 }, - 16, 0xdea0, 0, {0xe0,0x00,0x00,0x00,0x00,0x00,0x10,0x8c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdeb0, 0, {0x00,0x00,0x09,0x4d,0xb1,0xe9,0x00,0x26,0x40,0x2a,0x7f,0xe3,0xf2,0x54,0x98,0xc0 }, - 16, 0xdec0, 0, {0x3f,0xe6,0x40,0x00,0x01,0x42,0x91,0xd0,0xc0,0x13,0xe5,0x87,0x63,0x83,0xb8,0xcd }, - 16, 0xded0, 0, {0xf9,0x00,0x26,0x7f,0x00,0x00,0x35,0x2e,0xd5,0x03,0x40,0x3f,0xd9,0xbf,0xb1,0x80 }, - 16, 0xdee0, 0, {0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x16,0x14,0x00,0x1c }, - 16, 0xdef0, 0, {0xa8,0x3f,0x88,0x16,0x00,0x80,0x84,0x80,0x37,0x9e,0xba,0xa0,0x50,0x10,0x02,0x12 }, - 16, 0xdf00, 0, {0x00,0x17,0x96,0x97,0x26,0x50,0x10,0x10,0x82,0x80,0x1e,0x80,0xde,0xbe,0x94,0x14 }, - 16, 0xdf10, 0, {0x02,0x10,0x80,0x17,0xbe,0x81,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdf20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xa8,0x44,0x94,0x28,0x80,0x00,0x00,0x00,0x08 }, - 16, 0xdf30, 0, {0x94,0x21,0x44,0x51,0x00,0x00,0x00,0x00,0x08,0x84,0x42,0x41,0x01,0x00,0x00,0x00 }, - 16, 0xdf40, 0, {0x00,0x08,0xa1,0x72,0x23,0x41,0x40,0x00,0x00,0x00,0x08,0xb8,0x01,0x78,0x32,0x40 }, - 16, 0xdf50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }, - 16, 0xdf60, 0, {0x00,0x00,0x00,0x3f,0xf7,0xfe,0xd7,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xd7,0xdf }, - 16, 0xdf70, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x37,0x7f }, - 16, 0xdf80, 0, {0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdf90, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x1e,0xff,0xde,0x77,0xc0 }, - 16, 0xdfa0, 0, {0x00,0x00,0x00,0x00,0x1f,0xef,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff }, - 16, 0xdfb0, 0, {0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xdfc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }, - 16, 0xdfd0, 0, {0x00,0x00,0x00,0x1f,0xcf,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xbf }, - 16, 0xdfe0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xbf,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff }, - 16, 0xdff0, 0, {0xff,0xbf,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe000, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0 }, - 16, 0xe010, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x1f,0xff,0x1f }, - 16, 0xe020, 0, {0x7f,0xc0,0x00,0x00,0x00,0x00,0x2f,0xdf,0xff,0xcf,0xc0,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }, - 16, 0xe040, 0, {0x00,0x00,0x00,0x3f,0xbf,0xaf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff }, - 16, 0xe050, 0, {0xc0,0x00,0x00,0x00,0x00,0x3e,0xde,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff }, - 16, 0xe060, 0, {0xff,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe070, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0x7f,0xff,0xff,0xc0 }, - 16, 0xe080, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xfe,0xbe }, - 16, 0xe090, 0, {0x7f,0xc0,0x00,0x00,0x00,0x00,0x3e,0xff,0xd7,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe0e0, 0, {0x30,0x00,0x20,0x01,0x02,0x00,0x00,0x00,0x30,0x00,0x43,0x8e,0x00,0x00,0x00,0x00 }, - 16, 0xe0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe210, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe290, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe320, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe390, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe440, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe450, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe510, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe530, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe590, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe630, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe650, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe680, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe710, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe730, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xe9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xea90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xead0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeb90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xebb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xebc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xebd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xebe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xebf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xec90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xecb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xecc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xecd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xece0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xecf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xed90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeda0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xedb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xedc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xedd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xede0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xedf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xee90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeea0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeeb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeec0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeed0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef20, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x20,0x01,0x02,0x02,0x00,0x00,0x30,0x00,0x43,0x80 }, - 16, 0xef30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xef90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xefa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xefb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xefc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xefd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xefe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xeff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf000, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf020, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf050, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf210, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf290, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf320, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf390, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf440, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf450, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf510, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf530, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf590, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf630, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf650, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf680, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf710, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf730, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xf9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfa90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfad0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfb90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfbf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfc90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfcb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfcc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfcd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfcf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd30, 0, {0x30,0x00,0x00,0x01,0x00,0x00,0x5f,0xa7,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x03 }, - 16, 0xfd40, 0, {0x30,0x00,0x40,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 16, 0xfd70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01 }, - 16, 0xfd80, 0, {0x00,0x00,0x00,0x05,0x30,0x00,0xa0,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x01 }, - 16, 0xfd90, 0, {0x00,0x00,0x6b,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - 4, 0xfda0, 0, {0x00,0x00,0x00,0x00 }, - 0 , 0x0000, 1, {0} -}; -// VERSION= 1.0.0.191 -// DATE= 2002oct28 -static INTEL_HEX_RECORD g_HexMidiFw62[] = { - 3,0x0000,0,{0x02,0x46,0xb9}, - 3,0x0003,0,{0x02,0x0f,0xfd}, - 3,0x000b,0,{0x02,0x4e,0x0f}, - 3,0x0013,0,{0x02,0x17,0xfd}, - 3,0x001b,0,{0x02,0x4e,0x12}, - 3,0x0023,0,{0x02,0x4d,0xef}, - 3,0x002b,0,{0x02,0x48,0x00}, - 3,0x0033,0,{0x02,0x4d,0xe6}, - 3,0x003b,0,{0x02,0x4d,0xf6}, - 3,0x0043,0,{0x02,0x49,0x00}, - 3,0x004b,0,{0x02,0x4e,0x03}, - 3,0x0053,0,{0x02,0x48,0xfa}, - 3,0x005b,0,{0x02,0x4d,0xfd}, - 3,0x0063,0,{0x02,0x4e,0x07}, - 16,0x0500,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x11,0x01,0x00,0x01,0x01,0x02}, - 16,0x0510,0,{0x00,0x01,0x09,0x02,0x08,0x02,0x05,0x01,0x00,0x80,0x32,0x09,0x04,0x00,0x00,0x00}, - 16,0x0520,0,{0x01,0x01,0x00,0x00,0x0a,0x24,0x01,0x00,0x01,0x56,0x00,0x02,0x01,0x02,0x0c,0x24}, - 16,0x0530,0,{0x02,0x01,0x01,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x0d,0x24,0x06,0x05,0x01,0x02}, - 16,0x0540,0,{0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x24,0x03,0x02,0x04,0x03,0x00,0x05,0x00}, - 16,0x0550,0,{0x0c,0x24,0x02,0x03,0x05,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x15,0x24,0x06,0x06}, - 16,0x0560,0,{0x03,0x02,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00}, - 16,0x0570,0,{0x00,0x09,0x24,0x03,0x04,0x01,0x01,0x00,0x06,0x00,0x09,0x04,0x01,0x00,0x00,0x01}, - 16,0x0580,0,{0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01}, - 16,0x0590,0,{0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x02,0x10,0x03,0x44,0xac,0x00,0x80,0xbb}, - 16,0x05a0,0,{0x00,0x00,0x77,0x01,0x09,0x05,0x0a,0x05,0x84,0x01,0x01,0x00,0x8f,0x07,0x25,0x01}, - 16,0x05b0,0,{0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x05,0x00,0x09,0x04,0x01}, - 16,0x05c0,0,{0x02,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01,0x00,0x01,0x00,0x11,0x24,0x02}, - 16,0x05d0,0,{0x01,0x02,0x03,0x18,0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05}, - 16,0x05e0,0,{0x0a,0x05,0x46,0x02,0x01,0x00,0x8f,0x07,0x25,0x01,0x01,0x00,0x00,0x00,0x09,0x05}, - 16,0x05f0,0,{0x8f,0x01,0x03,0x00,0x01,0x05,0x00,0x09,0x04,0x02,0x00,0x00,0x01,0x02,0x00,0x00}, - 16,0x0600,0,{0x09,0x04,0x02,0x01,0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00}, - 16,0x0610,0,{0x0e,0x24,0x02,0x01,0x06,0x02,0x10,0x02,0x44,0xac,0x00,0x80,0xbb,0x00,0x09,0x05}, - 16,0x0620,0,{0x8c,0x05,0x4c,0x02,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04}, - 16,0x0630,0,{0x02,0x02,0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x0e,0x24}, - 16,0x0640,0,{0x02,0x01,0x06,0x03,0x18,0x02,0x44,0xac,0x00,0x80,0xbb,0x00,0x09,0x05,0x8c,0x05}, - 16,0x0650,0,{0x72,0x03,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04,0x02,0x03}, - 16,0x0660,0,{0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02,0x01}, - 16,0x0670,0,{0x02,0x02,0x10,0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05,0x8c}, - 16,0x0680,0,{0x05,0x84,0x01,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04,0x02}, - 16,0x0690,0,{0x04,0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02}, - 16,0x06a0,0,{0x01,0x02,0x03,0x18,0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05}, - 16,0x06b0,0,{0x8c,0x05,0x46,0x02,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04}, - 16,0x06c0,0,{0x03,0x00,0x00,0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x09,0x00,0x01,0x04}, - 16,0x06d0,0,{0x09,0x04,0x04,0x00,0x02,0x01,0x03,0x00,0x00,0x07,0x24,0x01,0x00,0x01,0x24,0x00}, - 16,0x06e0,0,{0x06,0x24,0x02,0x01,0x07,0x00,0x09,0x24,0x03,0x02,0x08,0x01,0x07,0x01,0x00,0x06}, - 16,0x06f0,0,{0x24,0x02,0x02,0x09,0x00,0x09,0x24,0x03,0x01,0x0a,0x01,0x09,0x01,0x00,0x09,0x05}, - 16,0x0700,0,{0x01,0x02,0x04,0x00,0x00,0x00,0x00,0x05,0x25,0x01,0x01,0x07,0x09,0x05,0x81,0x02}, - 16,0x0710,0,{0x04,0x00,0x00,0x00,0x00,0x05,0x25,0x01,0x01,0x0a,0x04,0x03,0x09,0x04,0x18,0x03}, - 16,0x0720,0,{0x45,0x00,0x6d,0x00,0x61,0x00,0x67,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x47,0x00}, - 16,0x0730,0,{0x6d,0x00,0x62,0x00,0x48,0x00,0x22,0x03,0x45,0x00,0x6d,0x00,0x61,0x00,0x67,0x00}, - 16,0x0740,0,{0x69,0x00,0x63,0x00,0x20,0x00,0x45,0x00,0x4d,0x00,0x49,0x00,0x20,0x00,0x36,0x00}, - 16,0x0750,0,{0x7c,0x00,0x32,0x00,0x20,0x00,0x6d,0x00,0x2a,0x03,0x43,0x00,0x6f,0x00,0x6e,0x00}, - 16,0x0760,0,{0x66,0x00,0x69,0x00,0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x69,0x00}, - 16,0x0770,0,{0x6f,0x00,0x6e,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00}, - 16,0x0780,0,{0x67,0x00,0x22,0x03,0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x66,0x00}, - 16,0x0790,0,{0x61,0x00,0x63,0x00,0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00}, - 6,0x07a0,0,{0x6e,0x00,0x67,0x00,0x00,0x00}, - 16,0x07a6,0,{0xe4,0x90,0x76,0x66,0xf0,0x12,0x44,0xad,0x20,0x26,0x13,0x90,0x76,0x66,0xe0,0xc3}, - 16,0x07b6,0,{0x94,0x02,0x50,0x0a,0xe0,0x04,0xf0,0xd2,0x42,0x12,0x4b,0x7f,0x80,0xea,0x30,0x26}, - 16,0x07c6,0,{0x05,0x12,0x28,0x01,0xc2,0x26,0x30,0x25,0x2b,0x90,0x76,0x96,0xe0,0x54,0xfc,0xf0}, - 16,0x07d6,0,{0x90,0x80,0x03,0xf0,0x12,0x14,0x96,0x90,0x76,0x96,0xe0,0x44,0x03,0xf0,0x90,0x80}, - 16,0x07e6,0,{0x03,0xf0,0xe4,0x90,0x76,0x67,0xf0,0x90,0x76,0x67,0xe0,0x04,0xf0,0xe0,0xb4,0x4b}, - 10,0x07f6,0,{0xf6,0x12,0x47,0xfa,0x12,0x41,0x1b,0x80,0xc5,0x22}, - 16,0x0800,0,{0xe4,0x90,0x76,0x31,0xf0,0x90,0x76,0x31,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0f}, - 16,0x0810,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xed,0xe0,0xfd,0xee,0x6d}, - 16,0x0820,0,{0x60,0x0e,0xef,0xc3,0x94,0x0b,0x50,0x08,0x90,0x76,0x31,0xe0,0x04,0xf0,0x80,0xd5}, - 16,0x0830,0,{0xef,0xb4,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x03}, - 16,0x0840,0,{0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x33,0xf0,0x24}, - 16,0x0850,0,{0xf0,0x60,0x0a,0x24,0x0e,0x60,0x02,0x81,0x87,0x12,0x4b,0xc7,0x22,0x90,0x7f,0xed}, - 16,0x0860,0,{0xe0,0x64,0x05,0x70,0x51,0x90,0x76,0x18,0x74,0x05,0xf0,0x90,0x76,0x37,0x74,0x01}, - 16,0x0870,0,{0xf0,0x90,0x76,0x39,0x74,0x03,0xf0,0x90,0x76,0x21,0xf0,0xe4,0x90,0x76,0x20,0xf0}, - 16,0x0880,0,{0x90,0x7f,0xea,0xe0,0xf4,0x60,0x2f,0x90,0x76,0x20,0xe0,0xff,0x75,0xf0,0x0a,0xa4}, - 16,0x0890,0,{0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd}, - 16,0x08a0,0,{0xee,0x6d,0x60,0x12,0x90,0x76,0x21,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76}, - 16,0x08b0,0,{0x20,0xe0,0x04,0xf0,0x80,0xd1,0x90,0x7f,0xed,0xe0,0x64,0x06,0x70,0x52,0x90,0x76}, - 16,0x08c0,0,{0x18,0x74,0x06,0xf0,0x90,0x76,0x37,0x74,0x04,0xf0,0x90,0x76,0x39,0x74,0x0a,0xf0}, - 16,0x08d0,0,{0x90,0x76,0x21,0xf0,0x90,0x76,0x20,0x74,0x03,0xf0,0x90,0x7f,0xea,0xe0,0xf4,0x60}, - 16,0x08e0,0,{0x2f,0x90,0x76,0x20,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34}, - 16,0x08f0,0,{0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd,0xee,0x6d,0x60,0x12,0x90,0x76}, - 16,0x0900,0,{0x21,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xd1}, - 16,0x0910,0,{0x90,0x76,0x20,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x0920,0,{0xf5,0x83,0xe0,0x90,0x72,0x29,0xf0,0xe4,0x90,0x76,0x3b,0xf0,0x90,0x76,0x21,0xe0}, - 16,0x0930,0,{0xfe,0xef,0x6e,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xeb}, - 16,0x0940,0,{0xe0,0x14,0x60,0x13,0x14,0x70,0x02,0x21,0xe2,0x24,0x02,0x60,0x02,0x81,0x7f,0x90}, - 16,0x0950,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x14,0x70,0x7c,0x90,0x7f}, - 16,0x0960,0,{0xea,0xe0,0xf4,0x70,0x48,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76,0x39}, - 16,0x0970,0,{0xe0,0xfe,0x90,0x76,0x20,0xe0,0xfd,0xc3,0x9e,0x50,0x2b,0x90,0x76,0x3b,0xe0,0xfe}, - 16,0x0980,0,{0x04,0xf0,0x74,0xc0,0x2e,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xfe,0xed,0x75}, - 16,0x0990,0,{0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xee,0xf0,0x90,0x76}, - 16,0x09a0,0,{0x20,0xe0,0x04,0xf0,0x80,0xc7,0x90,0x76,0x3f,0x74,0x01,0xf0,0x22,0x90,0x7e,0xc0}, - 16,0x09b0,0,{0xe0,0xfe,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x09c0,0,{0xee,0xf0,0xe0,0xb4,0x01,0x08,0x90,0x76,0x3e,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90}, - 16,0x09d0,0,{0x76,0x3e,0xf0,0x90,0x76,0x3f,0x74,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01}, - 16,0x09e0,0,{0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x70,0x02,0x41,0xa3,0x14,0x70,0x02,0x61}, - 16,0x09f0,0,{0x3f,0x14,0x70,0x02,0x61,0xdb,0x24,0x03,0x60,0x02,0x81,0x77,0x90,0x7f,0xea,0xe0}, - 16,0x0a00,0,{0xf4,0x70,0x6b,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76,0x39,0xe0,0xff}, - 16,0x0a10,0,{0x90,0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x50,0x4e,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0}, - 16,0x0a20,0,{0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a}, - 16,0x0a30,0,{0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x3b,0xe0}, - 16,0x0a40,0,{0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee}, - 16,0x0a50,0,{0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90}, - 16,0x0a60,0,{0x76,0x20,0xe0,0x04,0xf0,0x80,0xa4,0x90,0x76,0x40,0x74,0x01,0xf0,0x22,0x90,0x7e}, - 16,0x0a70,0,{0xc0,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82}, - 16,0x0a80,0,{0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75,0xf0,0x0a}, - 16,0x0a90,0,{0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x41,0x74}, - 16,0x0aa0,0,{0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x66,0x90,0x76,0x37,0xe0,0x90,0x76}, - 16,0x0ab0,0,{0x20,0xf0,0x90,0x76,0x39,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x40,0x02}, - 16,0x0ac0,0,{0x81,0x8e,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34}, - 16,0x0ad0,0,{0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4,0x34}, - 16,0x0ae0,0,{0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5}, - 16,0x0af0,0,{0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xaf,0xf5}, - 16,0x0b00,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xa2}, - 16,0x0b10,0,{0x90,0x7e,0xc0,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xae}, - 16,0x0b20,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75}, - 16,0x0b30,0,{0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90}, - 16,0x0b40,0,{0x7f,0xea,0xe0,0xf4,0x70,0x66,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76}, - 16,0x0b50,0,{0x39,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x40,0x02,0x81,0x8e,0x90,0x76}, - 16,0x0b60,0,{0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0}, - 16,0x0b70,0,{0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef}, - 16,0x0b80,0,{0xf0,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e}, - 16,0x0b90,0,{0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x0ba0,0,{0xf5,0x83,0xef,0xf0,0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xa2,0x90,0x7e,0xc0,0xe0}, - 16,0x0bb0,0,{0xff,0x90,0x76,0x20,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34}, - 16,0x0bc0,0,{0x75,0xf5,0x83,0xef,0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24}, - 16,0x0bd0,0,{0xb1,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4}, - 16,0x0be0,0,{0x70,0x66,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76,0x39,0xe0,0xff,0x90}, - 16,0x0bf0,0,{0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x40,0x02,0x81,0x8e,0x90,0x76,0x3b,0xe0,0xff,0x04}, - 16,0x0c00,0,{0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0}, - 16,0x0c10,0,{0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x3b}, - 16,0x0c20,0,{0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff}, - 16,0x0c30,0,{0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0}, - 16,0x0c40,0,{0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xa2,0x90,0x7e,0xc0,0xe0,0xff,0x90,0x76,0x20}, - 16,0x0c50,0,{0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef}, - 16,0x0c60,0,{0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4}, - 16,0x0c70,0,{0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90}, - 15,0x0c80,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22}, - 16,0x0c8f,0,{0x41,0x76,0x68,0x01,0x41,0x76,0x6a,0x02,0x41,0x76,0x6b,0x0a,0xc1,0x20,0xc1,0x21}, - 2,0x0c9f,0,{0xc1,0x2f}, - 4,0x0ca1,0,{0x41,0x76,0x23,0x00}, - 16,0x0ca5,0,{0x41,0x72,0x01,0x01,0x45,0x72,0x05,0x00,0x02,0xc9,0x00,0x00,0x45,0x72,0x0a,0x00}, - 16,0x0cb5,0,{0x01,0x02,0x03,0x04,0x4d,0x72,0x0f,0xd1,0x00,0xd1,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0cc5,0,{0x28,0x28,0x09,0x00,0x4d,0x72,0x1c,0x01,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}, - 16,0x0cd5,0,{0x08,0x09,0x0a,0x0b,0x41,0x72,0x2e,0x22,0x41,0x72,0x2f,0x23,0x41,0x72,0x30,0x20}, - 16,0x0ce5,0,{0x41,0x72,0x31,0x21,0x62,0xd2,0x72,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0cf5,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d05,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d15,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d25,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d35,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d45,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d55,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d65,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x0d75,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01}, - 16,0x0d85,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, - 16,0x0d95,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, - 16,0x0da5,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, - 16,0x0db5,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, - 16,0x0dc5,0,{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, - 16,0x0dd5,0,{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, - 16,0x0de5,0,{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, - 16,0x0df5,0,{0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}, - 16,0x0e05,0,{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}, - 16,0x0e15,0,{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}, - 16,0x0e25,0,{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}, - 16,0x0e35,0,{0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}, - 16,0x0e45,0,{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}, - 16,0x0e55,0,{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}, - 16,0x0e65,0,{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}, - 16,0x0e75,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}, - 16,0x0e85,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}, - 16,0x0e95,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}, - 16,0x0ea5,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x06}, - 16,0x0eb5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06}, - 16,0x0ec5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06}, - 16,0x0ed5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06}, - 16,0x0ee5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08}, - 16,0x0ef5,0,{0x08,0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d}, - 16,0x0f05,0,{0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,0x11,0x11,0x11,0x12,0x12,0x12,0x13}, - 16,0x0f15,0,{0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18}, - 16,0x0f25,0,{0x18,0x19,0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c}, - 16,0x0f35,0,{0x1c,0x1d,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x1f,0x20,0x20,0x20}, - 16,0x0f45,0,{0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x24,0x24,0x25,0x25,0x26,0x26,0x27,0x27}, - 16,0x0f55,0,{0x28,0x28,0x29,0x29,0x2a,0x2a,0x2b,0x2b,0x2c,0x2c,0x2d,0x2d,0x2e,0x2e,0x2f,0x2f}, - 16,0x0f65,0,{0x30,0x30,0x31,0x31,0x32,0x32,0x33,0x33,0x34,0x34,0x35,0x35,0x36,0x36,0x37,0x37}, - 16,0x0f75,0,{0x38,0x38,0x39,0x39,0x3a,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44}, - 16,0x0f85,0,{0x45,0x46,0x47,0x48,0x49,0x49,0x4a,0x4b,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52}, - 16,0x0f95,0,{0x53,0x54,0x55,0x55,0x56,0x56,0x57,0x57,0x58,0x5a,0x5b,0x5d,0x5e,0x5f,0x61,0x62}, - 16,0x0fa5,0,{0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6f,0x71,0x72,0x73,0x74}, - 16,0x0fb5,0,{0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7e,0x80,0x01,0x37,0x01,0x01,0x38,0x00}, - 1,0x0fc5,0,{0x00}, - 16,0x0fc6,0,{0xe4,0xff,0x74,0x46,0x2f,0xf5,0x82,0xe4,0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x20}, - 16,0x0fd6,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x4e,0x2f,0xf5,0x82,0xe4}, - 16,0x0fe6,0,{0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x30,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83}, - 6,0x0ff6,0,{0xee,0xf0,0x0f,0xbf,0x08,0xcc}, - 1,0x0ffc,0,{0x22}, - 3,0x0ffd,0,{0xc2,0x89,0x32}, - 16,0x1000,0,{0xe4,0x90,0x76,0x2c,0xf0,0x90,0x76,0x2c,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0f}, - 16,0x1010,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xed,0xe0,0xfd,0xee,0x6d}, - 16,0x1020,0,{0x60,0x0e,0xef,0xc3,0x94,0x0b,0x50,0x08,0x90,0x76,0x2c,0xe0,0x04,0xf0,0x80,0xd5}, - 16,0x1030,0,{0xef,0xb4,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x03}, - 16,0x1040,0,{0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x2e,0xf0,0x24}, - 16,0x1050,0,{0xf0,0x60,0x0a,0x24,0x0f,0x60,0x02,0x81,0x7d,0x12,0x4b,0xa4,0x22,0x90,0x7f,0xed}, - 16,0x1060,0,{0xe0,0x64,0x05,0x70,0x51,0x90,0x76,0x18,0x74,0x05,0xf0,0x90,0x76,0x38,0x74,0x01}, - 16,0x1070,0,{0xf0,0x90,0x76,0x3a,0x74,0x03,0xf0,0x90,0x76,0x1c,0xf0,0xe4,0x90,0x76,0x1b,0xf0}, - 16,0x1080,0,{0x90,0x7f,0xea,0xe0,0xf4,0x60,0x2f,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4}, - 16,0x1090,0,{0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd}, - 16,0x10a0,0,{0xee,0x6d,0x60,0x12,0x90,0x76,0x1c,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76}, - 16,0x10b0,0,{0x1b,0xe0,0x04,0xf0,0x80,0xd1,0x90,0x7f,0xed,0xe0,0x64,0x06,0x70,0x52,0x90,0x76}, - 16,0x10c0,0,{0x18,0x74,0x06,0xf0,0x90,0x76,0x38,0x74,0x04,0xf0,0x90,0x76,0x3a,0x74,0x0a,0xf0}, - 16,0x10d0,0,{0x90,0x76,0x1c,0xf0,0x90,0x76,0x1b,0x74,0x03,0xf0,0x90,0x7f,0xea,0xe0,0xf4,0x60}, - 16,0x10e0,0,{0x2f,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34}, - 16,0x10f0,0,{0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd,0xee,0x6d,0x60,0x12,0x90,0x76}, - 16,0x1100,0,{0x1c,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76,0x1b,0xe0,0x04,0xf0,0x80,0xd1}, - 16,0x1110,0,{0xe4,0x90,0x76,0x1e,0xf0,0x90,0x76,0x1c,0xe0,0xff,0x90,0x76,0x1b,0xe0,0xfe,0x6f}, - 16,0x1120,0,{0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xeb,0xe0,0x14,0x60}, - 16,0x1130,0,{0x13,0x14,0x70,0x02,0x21,0xbf,0x24,0x02,0x60,0x02,0x81,0x75,0x90,0x7f,0xb4,0xe0}, - 16,0x1140,0,{0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x6b,0x90,0x7f,0xea,0xe0}, - 16,0x1150,0,{0xf4,0x70,0x4a,0x90,0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff}, - 16,0x1160,0,{0x90,0x76,0x1b,0xe0,0xfd,0xc3,0x9f,0x50,0x2b,0xed,0x75,0xf0,0x0a,0xa4,0x24,0xab}, - 16,0x1170,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0}, - 16,0x1180,0,{0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0}, - 16,0x1190,0,{0x04,0xf0,0x80,0xc7,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0xee,0x75,0xf0}, - 16,0x11a0,0,{0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0}, - 16,0x11b0,0,{0x90,0x7f,0xb5,0x74,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90}, - 16,0x11c0,0,{0x7f,0xe9,0xe0,0x24,0x7e,0x70,0x02,0x41,0x7e,0x14,0x70,0x02,0x61,0x23,0x14,0x70}, - 16,0x11d0,0,{0x02,0x61,0xc8,0x24,0x03,0x60,0x02,0x81,0x6d,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x6d}, - 16,0x11e0,0,{0x90,0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff,0x90,0x76,0x1b}, - 16,0x11f0,0,{0xe0,0xc3,0x9f,0x50,0x4f,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4}, - 16,0x1200,0,{0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0,0x74,0x00,0x2d}, - 16,0x1210,0,{0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xee,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xad}, - 16,0x1220,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfe,0x04,0xf0}, - 16,0x1230,0,{0x74,0x00,0x2e,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0}, - 16,0x1240,0,{0x04,0xf0,0x80,0xa4,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0x90,0x76,0x1b}, - 16,0x1250,0,{0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0}, - 16,0x1260,0,{0x90,0x7f,0x00,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x1270,0,{0xf5,0x83,0xe0,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f}, - 16,0x1280,0,{0xea,0xe0,0xf4,0x70,0x6d,0x90,0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a}, - 16,0x1290,0,{0xe0,0xff,0x90,0x76,0x1b,0xe0,0xc3,0x9f,0x50,0x4f,0xe0,0xff,0x75,0xf0,0x0a,0xa4}, - 16,0x12a0,0,{0x24,0xae,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x76,0x1e,0xe0,0xfd}, - 16,0x12b0,0,{0x04,0xf0,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xee,0xf0,0xef,0x75}, - 16,0x12c0,0,{0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76}, - 16,0x12d0,0,{0x1e,0xe0,0xfe,0x04,0xf0,0x74,0x00,0x2e,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef}, - 16,0x12e0,0,{0xf0,0x90,0x76,0x1b,0xe0,0x04,0xf0,0x80,0xa4,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5}, - 16,0x12f0,0,{0xf0,0x22,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4}, - 16,0x1300,0,{0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xaf}, - 16,0x1310,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74}, - 16,0x1320,0,{0x02,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x6d,0x90,0x76,0x38,0xe0,0x90,0x76}, - 16,0x1330,0,{0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff,0x90,0x76,0x1b,0xe0,0xc3,0x9f,0x50,0x4f,0xe0}, - 16,0x1340,0,{0xff,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe}, - 16,0x1350,0,{0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0x7f,0xf5}, - 16,0x1360,0,{0x83,0xee,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x1370,0,{0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfe,0x04,0xf0,0x74,0x00,0x2e,0xf5,0x82,0xe4}, - 16,0x1380,0,{0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0,0x04,0xf0,0x80,0xa4,0x90,0x76}, - 16,0x1390,0,{0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4}, - 16,0x13a0,0,{0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0xef,0x75}, - 16,0x13b0,0,{0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x01}, - 16,0x13c0,0,{0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x6d,0x90}, - 16,0x13d0,0,{0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff,0x90,0x76,0x1b,0xe0}, - 16,0x13e0,0,{0xc3,0x9f,0x50,0x4f,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34}, - 16,0x13f0,0,{0x75,0xf5,0x83,0xe0,0xfe,0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0,0x74,0x00,0x2d,0xf5}, - 16,0x1400,0,{0x82,0xe4,0x34,0x7f,0xf5,0x83,0xee,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5}, - 16,0x1410,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfe,0x04,0xf0,0x74}, - 16,0x1420,0,{0x00,0x2e,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0,0x04}, - 16,0x1430,0,{0xf0,0x80,0xa4,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0x90,0x76,0x1b,0xe0}, - 16,0x1440,0,{0xff,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90}, - 16,0x1450,0,{0x7f,0x00,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x1460,0,{0x83,0xe0,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f,0xb4}, - 16,0x1470,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4}, - 5,0x1480,0,{0xe0,0x44,0x01,0xf0,0x22}, - 16,0x1485,0,{0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9}, - 1,0x1495,0,{0x22}, - 16,0x1496,0,{0x90,0x7f,0xd6,0xe0,0x44,0x80,0xf0,0x43,0x87,0x01,0x00,0x00,0x00,0x00,0x00,0x22}, - 16,0x14a6,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0x8d,0xe0,0xc0,0xe0}, - 16,0x14b6,0,{0x8c,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x05,0x86,0xc0,0x84,0xc0,0x85,0x7d,0x00}, - 16,0x14c6,0,{0x90,0x7f,0xe3,0x74,0x7b,0xf0,0xa3,0x74,0x80,0xf0,0x7c,0x11,0x90,0x7f,0x99,0xe0}, - 16,0x14d6,0,{0x54,0x40,0xdc,0x03,0x02,0x14,0xf3,0xb4,0x00,0x13,0x90,0x7f,0xe2,0x74,0x40,0xf0}, - 16,0x14e6,0,{0x90,0x7f,0xe5,0xf0,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x02,0x14,0xd2,0x90,0x76,0x90}, - 16,0x14f6,0,{0xe0,0xb4,0x01,0x12,0x90,0x76,0x8f,0xe0,0x2d,0xfd,0x90,0x7f,0xe2,0x74,0x80,0xf0}, - 16,0x1506,0,{0x90,0x7f,0x6c,0x02,0x15,0x57,0xb4,0x02,0x12,0x90,0x76,0x8f,0xe0,0x2d,0xfd,0x90}, - 16,0x1516,0,{0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f,0x6c,0x02,0x15,0x96,0xb4,0x03,0x12,0x90,0x76}, - 16,0x1526,0,{0x8f,0xe0,0x2d,0xfd,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f,0x6c,0x02,0x15,0xe1}, - 16,0x1536,0,{0xb4,0x04,0x12,0x90,0x76,0x8f,0xe0,0x2d,0xfd,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90}, - 16,0x1546,0,{0x7f,0x6c,0x02,0x16,0x10,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f,0x6c,0x02,0x16}, - 16,0x1556,0,{0x40,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xdd,0xf2,0x7d}, - 16,0x1566,0,{0x02,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x54,0x04,0xb4}, - 16,0x1576,0,{0x00,0x05,0x05,0x86,0x02,0x16,0x40,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x05,0x86,0xf0}, - 16,0x1586,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xdd,0xd4,0x02,0x16,0x40}, - 16,0x1596,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}, - 16,0x15a6,0,{0xf0,0xf0,0xdd,0xec,0x7d,0x02,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f}, - 16,0x15b6,0,{0x9b,0xe0,0x54,0x04,0xb4,0x00,0x05,0x05,0x86,0x02,0x16,0x40,0x90,0x7f,0xe2,0x74}, - 16,0x15c6,0,{0x80,0xf0,0x05,0x86,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}, - 6,0x15d6,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}, - 16,0x15dc,0,{0xdd,0xce,0x02,0x16,0x40,0xf0,0xf0,0xf0,0xf0,0xdd,0xfa,0x7d,0x02,0x05,0x86,0x90}, - 16,0x15ec,0,{0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x54,0x04,0xb4,0x00,0x05,0x05,0x86}, - 16,0x15fc,0,{0x02,0x16,0x40,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x05,0x86,0xf0,0xf0,0xf0,0xf0,0xdd}, - 16,0x160c,0,{0xdc,0x02,0x16,0x40,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xdd,0xf8,0x7d,0x02,0x05,0x86}, - 16,0x161c,0,{0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x54,0x04,0xb4,0x00,0x05,0x05}, - 16,0x162c,0,{0x86,0x02,0x16,0x40,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x05,0x86,0xf0,0xf0,0xf0,0xf0}, - 16,0x163c,0,{0xf0,0xf0,0xdd,0xda,0x90,0x7f,0xe2,0x74,0x00,0xf0,0xd0,0x85,0xd0,0x84,0x05,0x86}, - 16,0x164c,0,{0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xfc,0xd0,0xe0,0xfd,0xd0,0xe0,0xfe,0xd0,0xe0,0xff}, - 5,0x165c,0,{0xd0,0xe0,0xd0,0xd0,0x22}, - 16,0x1661,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x90,0x76,0x7c,0xe0,0x90,0x7f,0x6f,0xf0}, - 16,0x1671,0,{0x90,0x76,0x7d,0xe0,0x90,0x7f,0x6f,0xf0,0x90,0x76,0x7e,0xe0,0x90,0x7f,0x6f,0xf0}, - 9,0x1681,0,{0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xd0,0xd0,0x22}, - 16,0x168a,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83}, - 16,0x169a,0,{0x05,0x86,0xc0,0x84,0xc0,0x85,0x90,0x76,0x87,0xe0,0xff,0xbf,0x00,0x03,0x02,0x17}, - 16,0x16aa,0,{0x01,0x90,0x7f,0x96,0xe0,0x44,0x80,0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f}, - 16,0x16ba,0,{0x62,0xe0,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x96,0xe0,0x54,0x7f}, - 16,0x16ca,0,{0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x76,0x8e,0xe0,0xb4,0x01,0x05,0x05,0x86}, - 16,0x16da,0,{0x02,0x16,0xf6,0xb4,0x02,0x05,0x05,0x86,0x02,0x16,0xeb,0x05,0x86,0x02,0x16,0xfb}, - 16,0x16ea,0,{0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xdf,0xf8,0x02,0x16,0xfb,0xe0,0xe0,0xe0,0xe0,0xdf}, - 16,0x16fa,0,{0xfa,0x90,0x7f,0xe2,0x74,0x00,0xf0,0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0,0x83,0xd0}, - 12,0x170a,0,{0x82,0xd0,0xe0,0xfe,0xd0,0xe0,0xff,0xd0,0xe0,0xd0,0xd0,0x22}, - 16,0x1716,0,{0xc0,0x82,0xc0,0x83,0xc0,0xe0,0xe8,0xc0,0xe0,0x78,0xd1,0xe8,0x14,0xf8,0x70,0xfb}, - 10,0x1726,0,{0xd0,0xe0,0xf8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0x22}, - 16,0x1730,0,{0xc0,0x82,0xc0,0x83,0xc0,0xe0,0xe8,0xc0,0xe0,0x78,0x78,0xe8,0x14,0xf8,0x70,0xfb}, - 10,0x1740,0,{0xd0,0xe0,0xf8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0x22}, - 7,0x174a,0,{0x90,0x7f,0xc5,0x74,0x02,0xf0,0x22}, - 16,0x1751,0,{0x90,0x7e,0xc0,0xe0,0x90,0x76,0x45,0xf0,0x90,0x7e,0xc1,0xe0,0x90,0x76,0x44,0xf0}, - 16,0x1761,0,{0x90,0x7e,0xc2,0xe0,0x90,0x76,0x43,0xf0,0xb4,0x00,0x03,0x02,0x17,0x78,0x90,0x76}, - 16,0x1771,0,{0x19,0x74,0x03,0xf0,0x02,0x17,0x8e,0x90,0x76,0x44,0xe0,0xb4,0xbb,0x09,0x90,0x76}, - 16,0x1781,0,{0x19,0x74,0x02,0xf0,0x02,0x17,0x8e,0x90,0x76,0x19,0x74,0x01,0xf0,0x90,0x76,0x42}, - 3,0x1791,0,{0xe4,0xf0,0x22}, - 4,0x1794,0,{0x8d,0x29,0x8b,0x2a}, - 16,0x1798,0,{0x12,0x4a,0x55,0xea,0x49,0x60,0x57,0x12,0x36,0x92,0x7e,0x00,0x29,0xff,0xee,0x3a}, - 16,0x17a8,0,{0xc9,0xef,0xc9,0x75,0x2b,0xff,0xf5,0x2c,0x89,0x2d,0xab,0x2b,0xaa,0x2c,0xa9,0x2d}, - 16,0x17b8,0,{0x90,0x00,0x01,0x12,0x36,0xab,0xff,0x64,0x04,0x60,0x05,0xef,0x64,0x05,0x70,0x2e}, - 16,0x17c8,0,{0xef,0xb4,0x04,0x15,0x90,0x00,0x02,0x12,0x36,0xab,0x65,0x29,0x70,0x0b,0x90,0x00}, - 16,0x17d8,0,{0x03,0x12,0x36,0xab,0x65,0x2a,0x70,0x01,0x22,0x12,0x36,0x92,0x7e,0x00,0x29,0xff}, - 16,0x17e8,0,{0xee,0x3a,0xc9,0xef,0xc9,0x75,0x2b,0xff,0xf5,0x2c,0x89,0x2d,0x80,0xbc,0x7b,0x00}, - 4,0x17f8,0,{0x7a,0x00,0x79,0x00}, - 1,0x17fc,0,{0x22}, - 3,0x17fd,0,{0xc2,0x8b,0x32}, - 16,0x1800,0,{0x90,0x76,0x90,0xe0,0x14,0x60,0x37,0x14,0x70,0x02,0x01,0xd8,0x14,0x70,0x02,0x21}, - 16,0x1810,0,{0x72,0x14,0x70,0x02,0x41,0x3b,0x24,0x04,0x60,0x02,0x61,0x03,0x90,0x7f,0xfc,0x74}, - 16,0x1820,0,{0xcc,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x95,0xe0,0x44,0x01,0xf0,0x54}, - 16,0x1830,0,{0x05,0xf0,0x90,0x80,0x01,0xf0,0xe4,0x90,0x76,0x1a,0xf0,0xc2,0x2e,0x22,0x90,0x76}, - 16,0x1840,0,{0x95,0xe0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x30,0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80}, - 16,0x1850,0,{0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90,0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90}, - 16,0x1860,0,{0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x22,0x90}, - 16,0x1870,0,{0x7f,0xfc,0x74,0x74,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b}, - 16,0x1880,0,{0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80}, - 16,0x1890,0,{0xf0,0xef,0xb4,0x02,0x22,0x90,0x7f,0xfc,0x74,0x68,0xf0,0x90,0x7f,0xff,0x74,0xfc}, - 16,0x18a0,0,{0xf0,0x90,0x76,0x8f,0x74,0x2f,0xf0,0x90,0x76,0x97,0xe0,0x44,0x02,0xf0,0xe4,0x90}, - 16,0x18b0,0,{0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe}, - 16,0x18c0,0,{0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfb}, - 16,0x18d0,0,{0xf0,0x90,0x80,0x02,0xf0,0xd2,0x2e,0x22,0x90,0x76,0x95,0xe0,0x54,0xfe,0xf0,0x44}, - 16,0x18e0,0,{0x02,0xf0,0x30,0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0,0x54}, - 16,0x18f0,0,{0xfb,0xf0,0x90,0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90,0x76,0x95,0xe0,0x90,0x80,0x01}, - 16,0x1900,0,{0xf0,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x22,0x90,0x7f,0xfc,0x74,0x30,0xf0,0x90}, - 16,0x1910,0,{0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b,0xf0,0x90,0x76,0x97,0xe0,0x54}, - 16,0x1920,0,{0xfd,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0xef,0xb4,0x02,0x22,0x90}, - 16,0x1930,0,{0x7f,0xfc,0x74,0x1c,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2f}, - 16,0x1940,0,{0xf0,0x90,0x76,0x97,0xe0,0x44,0x02,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80}, - 16,0x1950,0,{0xf0,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97}, - 16,0x1960,0,{0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfb,0xf0,0x90,0x80,0x02,0xf0,0xd2}, - 16,0x1970,0,{0x2e,0x22,0x90,0x76,0x95,0xe0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x44,0x08,0xf0,0x30}, - 16,0x1980,0,{0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90}, - 16,0x1990,0,{0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90,0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x90,0x76}, - 16,0x19a0,0,{0x19,0xe0,0xff,0xb4,0x01,0x25,0x90,0x7f,0xfc,0x74,0xcc,0xf0,0x90,0x7f,0xff,0x74}, - 16,0x19b0,0,{0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0x54}, - 16,0x19c0,0,{0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0xef,0xb4,0x02,0x25,0x90}, - 16,0x19d0,0,{0x7f,0xfc,0x74,0xc8,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2f}, - 16,0x19e0,0,{0xf0,0x90,0x76,0x97,0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0}, - 16,0x19f0,0,{0x90,0x76,0x80,0xf0,0xef,0xb4,0x03,0x25,0x90,0x7f,0xfc,0x74,0x98,0xf0,0x90,0x7f}, - 16,0x1a00,0,{0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x5f,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd}, - 16,0x1a10,0,{0xf0,0x44,0x04,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0x30,0x3f,0x09}, - 16,0x1a20,0,{0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0}, - 16,0x1a30,0,{0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0xd2,0x2e,0x22,0x90,0x76,0x95,0xe0,0x54}, - 16,0x1a40,0,{0xfe,0xf0,0x44,0x02,0xf0,0x44,0x08,0xf0,0x30,0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80}, - 16,0x1a50,0,{0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90,0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90}, - 16,0x1a60,0,{0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x25,0x90}, - 16,0x1a70,0,{0x7f,0xfc,0x74,0xb4,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b}, - 16,0x1a80,0,{0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0}, - 16,0x1a90,0,{0x90,0x76,0x80,0xf0,0xef,0xb4,0x02,0x25,0x90,0x7f,0xfc,0x74,0xb0,0xf0,0x90,0x7f}, - 16,0x1aa0,0,{0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2f,0xf0,0x90,0x76,0x97,0xe0,0x44,0x02}, - 16,0x1ab0,0,{0xf0,0x54,0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0xef,0xb4,0x03}, - 16,0x1ac0,0,{0x25,0x90,0x7f,0xfc,0x74,0x68,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f}, - 16,0x1ad0,0,{0x74,0x5f,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0x44,0x04,0xf0,0xe4,0x90,0x76}, - 16,0x1ae0,0,{0x81,0xf0,0x90,0x76,0x80,0xf0,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0}, - 16,0x1af0,0,{0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02}, - 4,0x1b00,0,{0xf0,0xd2,0x2e,0x22}, - 16,0x1b04,0,{0x30,0x2c,0x38,0xc2,0x2c,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x0e,0x90,0x76,0x7c}, - 16,0x1b14,0,{0x74,0xc0,0xf0,0xa3,0x74,0x14,0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0d,0xe4}, - 16,0x1b24,0,{0x90,0x76,0x7c,0xf0,0xa3,0x74,0x10,0xf0,0xa3,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0b}, - 12,0x1b34,0,{0xe4,0x90,0x76,0x7c,0xf0,0xa3,0x74,0x18,0xf0,0xa3,0xf0,0x22}, - 16,0x1b40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1b50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1b60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1b70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1b80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1b90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ba0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1bb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1bc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1bd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1be0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1bf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1c90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ca0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1cb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1cc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1cd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ce0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1cf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1d90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1da0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1db0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1dc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1dd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1de0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1df0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1e90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ea0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 14,0x1eb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ebe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ece,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ede,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1eee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1efe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f0e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f1e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f2e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 2,0x1f3e,0,{0x00,0x00}, - 16,0x1f40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1f90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1fa0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1fb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1fc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1fd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1fe0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x1ff0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2000,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2010,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2020,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2030,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2040,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2050,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2060,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2070,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2080,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2090,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x20a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x20b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x20c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x20d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x20e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x20f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2100,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2110,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2120,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2130,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2140,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2150,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2160,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2170,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2180,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2190,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x21a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x21b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x21c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x21d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x21e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x21f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2200,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2210,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2220,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2230,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2240,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2250,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2260,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2270,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2280,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2290,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x22a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x22b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x22c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x22d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x22e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x22f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2300,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2310,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2320,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2330,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2340,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2350,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x2360,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 14,0x2370,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x237e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x238e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x239e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x23ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x23be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x23ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x23de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x23ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x23fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x240e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x241e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x242e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x243e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x244e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x245e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x246e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x247e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x248e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x249e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x24ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x24be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x24ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x24de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x24ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x24fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x250e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x251e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x252e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x253e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x254e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x255e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x256e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x257e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x258e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x259e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x25ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x25be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x25ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x25de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x25ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x25fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x260e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x261e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x262e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x263e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x264e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x265e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x266e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x267e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x268e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x269e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x26ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x26be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x26ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x26de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 14,0x26ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x26fc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x270c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x271c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x272c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x273c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x274c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x275c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x276c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x277c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x278c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x279c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x27ac,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x27bc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x27cc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x27dc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 16,0x27ec,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - 5,0x27fc,0,{0x00,0x00,0x00,0x00,0x22}, - 16,0x2801,0,{0xc2,0x20,0xc2,0x21,0xc2,0x2a,0x90,0x7f,0xe8,0xe0,0x12,0x37,0xf9,0x28,0x30,0x00}, - 16,0x2811,0,{0x28,0x8c,0x01,0x28,0xa2,0x02,0x2a,0x1f,0x21,0x2a,0x6a,0x22,0x29,0x3d,0x80,0x29}, - 16,0x2821,0,{0x7d,0x81,0x29,0xd1,0x82,0x2a,0x84,0xa1,0x2a,0xba,0xa2,0x00,0x00,0x2a,0xbf,0x90}, - 16,0x2831,0,{0x7f,0xe9,0xe0,0x14,0x60,0x11,0x24,0xfe,0x60,0x28,0x24,0xfe,0x60,0x3b,0x24,0xfc}, - 16,0x2841,0,{0x70,0x40,0x12,0x3f,0xe5,0x41,0xcb,0x12,0x4e,0x1d,0x40,0x02,0x41,0xcb,0x90,0x7f}, - 16,0x2851,0,{0xea,0xe0,0xb4,0x01,0x04,0xc2,0x22,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0}, - 16,0x2861,0,{0x41,0xcb,0x12,0x4e,0x1f,0x90,0x7f,0xea,0xe0,0xb4,0x01,0x04,0xd2,0x22,0x41,0xcb}, - 16,0x2871,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0}, - 16,0x2881,0,{0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xe9,0xe0,0x24}, - 16,0x2891,0,{0xf5,0x70,0x05,0x12,0x48,0x63,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41}, - 16,0x28a1,0,{0xcb,0x90,0x7f,0xe9,0xe0,0x24,0xfd,0x60,0x54,0x24,0x02,0x60,0x02,0x21,0x34,0x12}, - 16,0x28b1,0,{0x4e,0x1d,0x40,0x02,0x41,0xcb,0x90,0x7f,0xea,0xe0,0x70,0x38,0x90,0x7f,0xec,0xe0}, - 16,0x28c1,0,{0xf4,0x54,0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4}, - 16,0x28d1,0,{0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0x54,0x80,0xff}, - 16,0x28e1,0,{0x13,0x13,0x13,0x54,0x1f,0xff,0xe0,0x54,0x07,0x2f,0x90,0x7f,0xd7,0xf0,0xe0,0x44}, - 16,0x28f1,0,{0x20,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x12,0x4e,0x1f}, - 16,0x2901,0,{0x40,0x02,0x41,0xcb,0x90,0x7f,0xea,0xe0,0x70,0x20,0x90,0x7f,0xec,0xe0,0xf4,0x54}, - 16,0x2911,0,{0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82}, - 16,0x2921,0,{0xe4,0x34,0x7f,0xf5,0x83,0x74,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01}, - 16,0x2931,0,{0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xe9,0xe0}, - 16,0x2941,0,{0x60,0x12,0x24,0xf8,0x60,0x09,0x24,0x02,0x70,0x29,0x12,0x43,0xe7,0x41,0xcb,0x12}, - 16,0x2951,0,{0x4d,0xca,0x41,0xcb,0x12,0x4e,0x1b,0xa2,0x22,0xe4,0x33,0xff,0x25,0xe0,0xff,0xa2}, - 16,0x2961,0,{0x23,0xe4,0x33,0x4f,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02}, - 16,0x2971,0,{0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xe9,0xe0}, - 16,0x2981,0,{0x60,0x33,0x24,0xf6,0x60,0x2a,0x24,0x04,0x70,0x3d,0x90,0x7f,0xeb,0xe0,0x24,0xde}, - 16,0x2991,0,{0x60,0x0c,0x04,0x70,0x12,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f}, - 16,0x29a1,0,{0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb}, - 16,0x29b1,0,{0x12,0x47,0x45,0x41,0xcb,0x12,0x4e,0x1b,0xe4,0x90,0x7f,0x00,0xf0,0xa3,0xf0,0x90}, - 16,0x29c1,0,{0x7f,0xb5,0x74,0x02,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb}, - 16,0x29d1,0,{0x90,0x7f,0xe9,0xe0,0x24,0xf4,0x60,0x34,0x24,0x0c,0x70,0x39,0x12,0x4e,0x1b,0x90}, - 16,0x29e1,0,{0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25}, - 16,0x29f1,0,{0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xe0,0x54,0xfd,0x90,0x7f,0x00}, - 16,0x2a01,0,{0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0}, - 16,0x2a11,0,{0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f}, - 16,0x2a21,0,{0xe9,0xe0,0x24,0xf6,0x60,0x12,0x14,0x60,0x1a,0x24,0x02,0x70,0x1d,0xd2,0x20,0x90}, - 16,0x2a31,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x12,0xd2,0x20,0x90,0x7f,0xb4,0xe0,0x44,0x01}, - 16,0x2a41,0,{0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x20,0x20,0x18,0x90,0x7f,0xee}, - 16,0x2a51,0,{0xe0,0x70,0x04,0xa3,0xe0,0x60,0x0b,0xd2,0x29,0xd2,0x27,0x12,0x17,0x4a,0xd2,0x2a}, - 16,0x2a61,0,{0x80,0x03,0x12,0x08,0x00,0xc2,0x20,0x80,0x61,0x90,0x7f,0xee,0xe0,0x70,0x04,0xa3}, - 16,0x2a71,0,{0xe0,0x60,0x0b,0xd2,0x29,0xd2,0x28,0x12,0x17,0x4a,0xd2,0x2a,0x80,0x4c,0x12,0x38}, - 16,0x2a81,0,{0x74,0x80,0x47,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x60,0x12,0x14,0x60,0x1a,0x24,0x02}, - 16,0x2a91,0,{0x70,0x1d,0xd2,0x21,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x12,0xd2,0x21,0x90}, - 16,0x2aa1,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x20}, - 16,0x2ab1,0,{0x21,0x03,0x12,0x10,0x00,0xc2,0x21,0x80,0x11,0x12,0x2a,0xd6,0x80,0x0c,0x12,0x4e}, - 16,0x2ac1,0,{0x21,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x20,0x2a,0x07,0x90,0x7f,0xb4}, - 5,0x2ad1,0,{0xe0,0x44,0x02,0xf0,0x22}, - 16,0x2ad6,0,{0xe4,0x90,0x76,0x27,0xf0,0x90,0x76,0x27,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x42}, - 16,0x2ae6,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}, - 16,0x2af6,0,{0x60,0x0e,0xef,0xc3,0x94,0x06,0x50,0x08,0x90,0x76,0x27,0xe0,0x04,0xf0,0x80,0xd5}, - 16,0x2b06,0,{0xef,0xb4,0x06,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x0f}, - 16,0x2b16,0,{0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x28,0xf0,0x24}, - 16,0x2b26,0,{0x9f,0x70,0x02,0xa1,0x74,0x24,0x21,0x60,0x02,0xa1,0xa1,0x90,0x7f,0xe9,0xe0,0x24}, - 16,0x2b36,0,{0x7e,0x70,0x02,0x61,0xfc,0x14,0x70,0x02,0x81,0xb5,0x24,0x02,0x60,0x02,0xa1,0x6c}, - 16,0x2b46,0,{0xef,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc}, - 16,0x2b56,0,{0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x44,0x7a,0xac,0x79,0x00,0x78}, - 16,0x2b66,0,{0x00,0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3,0x74,0xac}, - 16,0x2b76,0,{0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0}, - 16,0x2b86,0,{0x0f,0xa4,0x24,0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd}, - 16,0x2b96,0,{0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12}, - 16,0x2ba6,0,{0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3}, - 16,0x2bb6,0,{0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24}, - 16,0x2bc6,0,{0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe}, - 16,0x2bd6,0,{0xa3,0xe0,0xff,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x37,0xab,0x60}, - 16,0x2be6,0,{0x02,0xa1,0xa8,0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90}, - 16,0x2bf6,0,{0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x47}, - 16,0x2c06,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3}, - 16,0x2c16,0,{0xe0,0xff,0x7b,0x44,0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12,0x37,0xab,0x70,0x13}, - 16,0x2c26,0,{0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5}, - 16,0x2c36,0,{0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4}, - 16,0x2c46,0,{0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b}, - 16,0x2c56,0,{0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00}, - 16,0x2c66,0,{0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0}, - 16,0x2c76,0,{0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x2c86,0,{0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x00,0x7a,0x77}, - 16,0x2c96,0,{0x79,0x01,0x78,0x00,0xc3,0x12,0x37,0xab,0x60,0x02,0xa1,0xa8,0x90,0x7f,0x00,0xf0}, - 16,0x2ca6,0,{0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90}, - 16,0x2cb6,0,{0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x2cc6,0,{0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x44,0x7a,0xac,0x79}, - 16,0x2cd6,0,{0x00,0x78,0x00,0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3}, - 16,0x2ce6,0,{0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0}, - 16,0x2cf6,0,{0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3}, - 16,0x2d06,0,{0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00}, - 16,0x2d16,0,{0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0}, - 16,0x2d26,0,{0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f}, - 16,0x2d36,0,{0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3}, - 16,0x2d46,0,{0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x37}, - 16,0x2d56,0,{0xab,0x70,0x4f,0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90}, - 16,0x2d66,0,{0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f}, - 16,0x2d76,0,{0xe9,0xe0,0x24,0x7f,0x70,0x1e,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x4f}, - 16,0x2d86,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74}, - 16,0x2d96,0,{0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xb4,0xe0,0x44}, - 3,0x2da6,0,{0x01,0xf0,0x22}, - 16,0x2da9,0,{0xe4,0x90,0x76,0x36,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4}, - 16,0x2db9,0,{0x34,0x75,0xf5,0x83,0x74,0x01,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82}, - 16,0x2dc9,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x01,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5}, - 16,0x2dd9,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff}, - 16,0x2de9,0,{0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x10,0xf0}, - 16,0x2df9,0,{0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x05}, - 16,0x2e09,0,{0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4}, - 16,0x2e19,0,{0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5}, - 16,0x2e29,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f}, - 16,0x2e39,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24}, - 16,0x2e49,0,{0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0}, - 16,0x2e59,0,{0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}, - 16,0x2e69,0,{0x01,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x2e79,0,{0x74,0x03,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x2e89,0,{0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24}, - 16,0x2e99,0,{0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x10,0xf0,0xef,0x75,0xf0,0x03,0xa4}, - 16,0x2ea9,0,{0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x06,0xf0,0xef,0x75,0xf0,0x03}, - 16,0x2eb9,0,{0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0}, - 16,0x2ec9,0,{0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x2ed9,0,{0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x2ee9,0,{0xf5,0x83,0x74,0x04,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34}, - 16,0x2ef9,0,{0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03}, - 16,0x2f09,0,{0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0}, - 16,0x2f19,0,{0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x08,0xf0,0xef,0x75}, - 16,0x2f29,0,{0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x90}, - 16,0x2f39,0,{0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4}, - 16,0x2f49,0,{0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82}, - 16,0x2f59,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x0a,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5}, - 16,0x2f69,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0}, - 16,0x2f79,0,{0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02}, - 16,0x2f89,0,{0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}, - 16,0x2f99,0,{0x09,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x2fa9,0,{0x74,0x04,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24}, - 16,0x2fb9,0,{0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4}, - 16,0x2fc9,0,{0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x07,0xf0,0xef,0x75,0xf0,0x03}, - 14,0x2fd9,0,{0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x22}, - 16,0x2fe7,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x26,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01}, - 8,0x2ff7,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 1,0x2fff,0,{0x32}, - 16,0x3000,0,{0x90,0x7f,0xb6,0xe0,0x20,0xe1,0x02,0xc2,0x3d,0xd2,0x36,0x20,0x36,0x02,0x41,0x6e}, - 16,0x3010,0,{0x30,0x3d,0x02,0x41,0x6e,0x90,0x80,0x07,0xe0,0x60,0x04,0xd2,0x36,0x80,0x02,0xc2}, - 16,0x3020,0,{0x36,0x20,0x36,0x02,0x41,0x2e,0xd2,0x35,0xe4,0xf5,0x1a,0x90,0x80,0x04,0xe0,0xf5}, - 16,0x3030,0,{0x19,0x74,0x08,0x25,0x0e,0xf8,0xa6,0x19,0x85,0x19,0x18,0xe5,0x18,0x20,0xe7,0x04}, - 16,0x3040,0,{0xd2,0x38,0x80,0x02,0xc2,0x38,0x30,0x38,0x02,0x21,0xd4,0xe4,0xf5,0x16,0xe5,0x19}, - 16,0x3050,0,{0xb4,0xf0,0x0c,0xd2,0x39,0x75,0x08,0x04,0x75,0x09,0xf0,0x05,0x0e,0x80,0x02,0x05}, - 16,0x3060,0,{0x16,0xe5,0x19,0x64,0xf7,0x70,0x3d,0xc2,0x39,0xe5,0x0e,0x24,0xfe,0x60,0x17,0x14}, - 16,0x3070,0,{0x60,0x22,0x24,0x03,0x70,0x29,0x75,0x08,0x05,0x75,0x09,0xf7,0xe4,0xf5,0x0a,0xf5}, - 16,0x3080,0,{0x0b,0x75,0x0e,0x04,0x80,0x20,0x75,0x08,0x06,0x75,0x0a,0xf7,0xe4,0xf5,0x0b,0x75}, - 16,0x3090,0,{0x0e,0x04,0x80,0x12,0x75,0x08,0x07,0x75,0x0b,0xf7,0x75,0x0e,0x04,0x80,0x07,0x12}, - 16,0x30a0,0,{0x4d,0xda,0x80,0x02,0x05,0x16,0xe5,0x19,0x54,0xf8,0x64,0xf8,0x70,0x3b,0xc2,0x35}, - 16,0x30b0,0,{0xe5,0x19,0x24,0x07,0x60,0x0c,0x24,0xfc,0x60,0x08,0x24,0x05,0x24,0xf8,0x50,0x06}, - 16,0x30c0,0,{0x80,0x08,0xd2,0x3a,0x80,0x06,0xc2,0x3a,0x80,0x02,0xd2,0x3a,0x75,0x1a,0x01,0x20}, - 16,0x30d0,0,{0x3a,0x19,0x90,0x7e,0x80,0x74,0x0f,0xf0,0xa3,0xe5,0x19,0xf0,0xe4,0xa3,0xf0,0xa3}, - 16,0x30e0,0,{0xf0,0x90,0x7f,0xb7,0x74,0x04,0xf0,0x80,0x02,0x05,0x16,0x20,0x39,0x6d,0xe5,0x19}, - 16,0x30f0,0,{0x64,0xf7,0x60,0x67,0xe5,0x1a,0x70,0x63,0xe5,0x18,0x54,0xf0,0x64,0xf0,0x70,0x59}, - 16,0x3100,0,{0x85,0x18,0x19,0xf5,0x0e,0xe5,0x19,0x24,0x0f,0x60,0x1b,0x24,0xfe,0x60,0x17,0x24}, - 16,0x3110,0,{0xfd,0x60,0x22,0x14,0x60,0x1f,0x24,0x05,0x70,0x2f,0x75,0x08,0x03,0x05,0x0e,0x85}, - 16,0x3120,0,{0x18,0x09,0xd2,0x37,0x80,0x28,0x75,0x08,0x02,0x05,0x0e,0x85,0x18,0x09,0x75,0x14}, - 16,0x3130,0,{0x01,0xd2,0x37,0x80,0x19,0x75,0x08,0x05,0x05,0x0e,0x85,0x18,0x09,0xe4,0xf5,0x0a}, - 16,0x3140,0,{0xf5,0x0b,0x75,0x0e,0x03,0xd2,0x37,0x80,0x05,0x12,0x4d,0xda,0xc2,0x35,0x30,0x35}, - 16,0x3150,0,{0x0a,0x85,0x08,0x13,0x85,0x18,0x12,0x80,0x02,0x05,0x16,0x85,0x18,0x19,0xe5,0x16}, - 16,0x3160,0,{0x64,0x04,0x70,0x62,0xf5,0x0e,0xe5,0x19,0x54,0xf0,0xf5,0x19,0xf5,0x15,0x85,0x18}, - 16,0x3170,0,{0x19,0xe5,0x15,0x24,0x70,0x60,0x18,0x24,0xf0,0x60,0x14,0x24,0xf0,0x60,0x10,0x24}, - 16,0x3180,0,{0xf0,0x60,0x1e,0x24,0xf0,0x60,0x1a,0x24,0xf0,0x60,0x04,0x24,0x60,0x70,0x27,0xe5}, - 16,0x3190,0,{0x15,0xc4,0x54,0x0f,0xf5,0x19,0xf5,0x08,0x05,0x0e,0x85,0x18,0x09,0xd2,0x37,0x80}, - 16,0x31a0,0,{0x1a,0xe5,0x15,0xc4,0x54,0x0f,0xf5,0x19,0xf5,0x08,0x05,0x0e,0x85,0x18,0x09,0x75}, - 16,0x31b0,0,{0x14,0x01,0xd2,0x37,0x80,0x05,0x12,0x4d,0xda,0xc2,0x35,0x30,0x35,0x0a,0x85,0x19}, - 16,0x31c0,0,{0x13,0x85,0x18,0x12,0x80,0x02,0x05,0x16,0xe5,0x16,0xd3,0x94,0x05,0x40,0x57,0x12}, - 16,0x31d0,0,{0x4d,0xda,0x80,0x52,0x30,0x39,0x17,0xe5,0x0e,0x70,0x0a,0x85,0x08,0x09,0x75,0x08}, - 16,0x31e0,0,{0x04,0x05,0x0e,0x80,0x41,0x74,0x08,0x25,0x0e,0xf8,0xa6,0x19,0x80,0x38,0x20,0x37}, - 16,0x31f0,0,{0x2a,0xe5,0x0e,0xb4,0x01,0x0f,0x85,0x08,0x0a,0x85,0x09,0x0b,0x85,0x13,0x08,0x85}, - 16,0x3200,0,{0x12,0x09,0x75,0x0e,0x04,0xe5,0x14,0xb4,0x01,0x1c,0x85,0x08,0x0a,0xe4,0xf5,0x0b}, - 16,0x3210,0,{0x85,0x13,0x08,0x85,0x12,0x09,0x75,0x0e,0x04,0x80,0x0b,0xe5,0x14,0xb4,0x01,0x06}, - 16,0x3220,0,{0xe4,0xf5,0x0b,0x75,0x0e,0x04,0xe4,0xf5,0x1a,0x30,0x35,0x02,0x05,0x0e,0xe5,0x0e}, - 16,0x3230,0,{0xd3,0x94,0x03,0x50,0x02,0x01,0x0b,0xc2,0x37,0xe4,0xf5,0x0e,0xf5,0x10,0xc2,0x36}, - 16,0x3240,0,{0xd2,0x3d,0xf5,0x14,0x74,0x08,0x25,0x10,0xf8,0xe6,0xff,0x74,0x80,0x25,0x10,0xf5}, - 16,0x3250,0,{0x82,0xe4,0x34,0x7e,0xf5,0x83,0xef,0xf0,0x74,0x08,0x25,0x10,0xf8,0xe4,0xf6,0x05}, - 15,0x3260,0,{0x10,0xe5,0x10,0xb4,0x04,0xde,0x90,0x7f,0xb7,0x74,0x04,0xf0,0x01,0x0b,0x22}, - 16,0x326f,0,{0x90,0x76,0x18,0xe0,0xff,0x64,0x05,0x70,0x42,0x90,0x75,0xab,0xe0,0xb4,0x01,0x19}, - 16,0x327f,0,{0x90,0x72,0x37,0x74,0x01,0xf0,0xe4,0x90,0x80,0x20,0xf0,0x90,0x80,0x31,0xf0,0x90}, - 16,0x328f,0,{0x80,0x28,0xf0,0x90,0x80,0x39,0xf0,0x80,0x22,0xe4,0x90,0x72,0x37,0xf0,0x90,0x75}, - 16,0x329f,0,{0xad,0xe0,0x90,0x72,0x2b,0xf0,0xe0,0x24,0x80,0xf0,0xe0,0x90,0x80,0x20,0xf0,0x90}, - 16,0x32af,0,{0x80,0x31,0xf0,0x90,0x80,0x28,0xf0,0x90,0x80,0x39,0xf0,0xef,0x64,0x06,0x60,0x02}, - 16,0x32bf,0,{0x81,0x99,0x90,0x72,0x39,0x74,0x04,0xf0,0x90,0x72,0x39,0xe0,0xff,0x24,0xfe,0x90}, - 16,0x32cf,0,{0x72,0x04,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x32df,0,{0x83,0xe0,0x64,0x01,0x70,0x54,0x90,0x72,0x36,0x04,0xf0,0x90,0x72,0x04,0xe0,0xff}, - 16,0x32ef,0,{0x24,0xfd,0x60,0x28,0x24,0xfe,0x60,0x24,0x24,0x03,0x24,0xfb,0x50,0x04,0x60,0x1c}, - 16,0x32ff,0,{0x81,0x8c,0x74,0x20,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x74,0x28}, - 16,0x330f,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x81,0x8c,0x90,0x72,0x04,0xe0}, - 16,0x331f,0,{0xff,0x24,0x30,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x74,0x38,0x2f,0xf5}, - 16,0x332f,0,{0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x81,0x8c,0xe4,0x90,0x72,0x36,0xf0,0x90}, - 16,0x333f,0,{0x72,0x39,0xe0,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x334f,0,{0xe0,0xff,0x7e,0x00,0x90,0x75,0x0c,0xee,0xf0,0xa3,0xef,0xf0,0x70,0x06,0x90,0x72}, - 16,0x335f,0,{0x02,0x74,0x3b,0xf0,0x90,0x75,0x0c,0xe0,0xfe,0xa3,0xe0,0xff,0x64,0x80,0x4e,0x70}, - 16,0x336f,0,{0x04,0x90,0x72,0x02,0xf0,0xef,0x4e,0x70,0x02,0x81,0x35,0xef,0x64,0x80,0x4e,0x70}, - 16,0x337f,0,{0x02,0x81,0x35,0xef,0xf8,0xe4,0x90,0x75,0x0d,0xf0,0xe8,0x90,0x75,0x0c,0xf0,0x90}, - 16,0x338f,0,{0x72,0x34,0xe0,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x339f,0,{0xe0,0xff,0x90,0x72,0x02,0xf0,0x90,0x75,0x0d,0xe0,0x2f,0xf0,0x90,0x75,0x0c,0xe0}, - 16,0x33af,0,{0x34,0x00,0xf0,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0xfc,0xfd,0x7b,0xd6,0x7a,0xa5,0xf9}, - 16,0x33bf,0,{0xf8,0xd3,0x12,0x37,0x95,0x40,0x0a,0x90,0x75,0x0c,0x74,0xa5,0xf0,0xa3,0x74,0xd6}, - 16,0x33cf,0,{0xf0,0x90,0x75,0x0d,0xe0,0x24,0x2a,0xf0,0x90,0x75,0x0c,0xe0,0x34,0x5a,0xf0,0xe0}, - 16,0x33df,0,{0xfe,0xa3,0xe0,0x78,0x05,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x90,0x75}, - 16,0x33ef,0,{0x0c,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x72,0x2c,0xee,0xf0,0xa3,0xef,0xf0,0xd3,0x94}, - 16,0x33ff,0,{0xd2,0xee,0x64,0x80,0x94,0x82,0x40,0x0a,0x90,0x72,0x2c,0x74,0x02,0xf0,0xa3,0x74}, - 16,0x340f,0,{0xd2,0xf0,0xc3,0x90,0x72,0x2c,0xe0,0x64,0x80,0x94,0x80,0x50,0x04,0xe4,0xf0,0xa3}, - 16,0x341f,0,{0xf0,0x90,0x72,0x2c,0xe0,0xfe,0xa3,0xe0,0x24,0x3a,0xf5,0x82,0xee,0x34,0x72,0xf5}, - 16,0x342f,0,{0x83,0xe0,0x90,0x72,0x02,0xf0,0x90,0x72,0x04,0xe0,0xff,0x24,0xfd,0x60,0x2d,0x24}, - 16,0x343f,0,{0xfe,0x60,0x29,0x24,0x03,0x24,0xfb,0x50,0x04,0x60,0x21,0x80,0x40,0x90,0x72,0x02}, - 16,0x344f,0,{0xe0,0xfe,0x74,0x20,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x28}, - 16,0x345f,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x80,0x21,0x90,0x72,0x02,0xe0}, - 16,0x346f,0,{0xff,0x90,0x72,0x04,0xe0,0xfe,0x24,0x30,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xef}, - 16,0x347f,0,{0xf0,0x74,0x38,0x2e,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xef,0xf0,0x90,0x72,0x39}, - 11,0x348f,0,{0xe0,0x04,0xf0,0xe0,0x64,0x0a,0x60,0x02,0x41,0xc7,0x22}, - 16,0x349a,0,{0x90,0x76,0x18,0xe0,0xff,0xb4,0x05,0x23,0x90,0x72,0x37,0xe0,0x70,0x1d,0x90,0x75}, - 16,0x34aa,0,{0xad,0xe0,0x90,0x72,0x2b,0xf0,0xe0,0x24,0x80,0xf0,0xe0,0x90,0x80,0x20,0xf0,0x90}, - 16,0x34ba,0,{0x80,0x31,0xf0,0x90,0x80,0x28,0xf0,0x90,0x80,0x39,0xf0,0xef,0x64,0x06,0x60,0x02}, - 16,0x34ca,0,{0xc1,0x91,0x90,0x72,0x36,0xe0,0x60,0x02,0xc1,0x91,0x90,0x76,0x40,0xe0,0x70,0x31}, - 16,0x34da,0,{0x90,0x72,0x03,0x74,0x03,0xf0,0x90,0x72,0x03,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24}, - 16,0x34ea,0,{0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x72,0x29,0xe0,0xfd,0xee}, - 16,0x34fa,0,{0x6d,0x60,0x0e,0xef,0xc3,0x94,0x0a,0x50,0x08,0x90,0x72,0x03,0xe0,0x04,0xf0,0x80}, - 16,0x350a,0,{0xd5,0x90,0x72,0x39,0x74,0x04,0xf0,0x90,0x76,0x40,0xe0,0x70,0x08,0x90,0x72,0x03}, - 16,0x351a,0,{0xe0,0x90,0x72,0x39,0xf0,0x90,0x72,0x39,0xe0,0xfd,0x24,0xfe,0x90,0x72,0x2a,0xf0}, - 16,0x352a,0,{0xed,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff}, - 16,0x353a,0,{0x7e,0x00,0x90,0x75,0x0c,0xee,0xf0,0xa3,0xef,0xf0,0x70,0x06,0x90,0x72,0x02,0x74}, - 16,0x354a,0,{0x80,0xf0,0x90,0x75,0x0c,0xe0,0xfe,0xa3,0xe0,0xff,0x64,0x80,0x4e,0x70,0x04,0x90}, - 16,0x355a,0,{0x72,0x02,0xf0,0xef,0x4e,0x70,0x02,0xc1,0x1b,0xef,0x64,0x80,0x4e,0x70,0x02,0xc1}, - 16,0x356a,0,{0x1b,0xef,0xf8,0xe4,0x90,0x75,0x0d,0xf0,0xe8,0x90,0x75,0x0c,0xf0,0xed,0x75,0xf0}, - 16,0x357a,0,{0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x72,0x02}, - 16,0x358a,0,{0xf0,0x90,0x75,0x0d,0xe0,0x2f,0xf0,0x90,0x75,0x0c,0xe0,0x34,0x00,0xf0,0xe0,0xfe}, - 16,0x359a,0,{0xa3,0xe0,0xff,0xe4,0xfc,0xfd,0x7b,0xd6,0x7a,0xa5,0xf9,0xf8,0xd3,0x12,0x37,0x95}, - 16,0x35aa,0,{0x40,0x0a,0x90,0x75,0x0c,0x74,0xa5,0xf0,0xa3,0x74,0xd6,0xf0,0x90,0x75,0x0d,0xe0}, - 16,0x35ba,0,{0x24,0x2a,0xf0,0x90,0x75,0x0c,0xe0,0x34,0x5a,0xf0,0xe0,0xfe,0xa3,0xe0,0x78,0x05}, - 16,0x35ca,0,{0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x90,0x75,0x0c,0xee,0xf0,0xa3,0xef}, - 16,0x35da,0,{0xf0,0x90,0x72,0x2c,0xee,0xf0,0xa3,0xef,0xf0,0xd3,0x94,0xd2,0xee,0x64,0x80,0x94}, - 16,0x35ea,0,{0x82,0x40,0x0a,0x90,0x72,0x2c,0x74,0x02,0xf0,0xa3,0x74,0xd2,0xf0,0xc3,0x90,0x72}, - 16,0x35fa,0,{0x2c,0xe0,0x64,0x80,0x94,0x80,0x50,0x04,0xe4,0xf0,0xa3,0xf0,0x90,0x72,0x2c,0xe0}, - 16,0x360a,0,{0xfe,0xa3,0xe0,0x24,0x3a,0xf5,0x82,0xee,0x34,0x72,0xf5,0x83,0xe0,0x90,0x72,0x02}, - 16,0x361a,0,{0xf0,0x90,0x72,0x2a,0xe0,0xff,0x24,0xfd,0x60,0x2d,0x24,0xfe,0x60,0x29,0x24,0x03}, - 16,0x362a,0,{0x24,0xfb,0x50,0x04,0x60,0x21,0x80,0x40,0x90,0x72,0x02,0xe0,0xfe,0x74,0x20,0x2f}, - 16,0x363a,0,{0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x28,0x2f,0xf5,0x82,0xe4,0x34}, - 16,0x364a,0,{0x80,0xf5,0x83,0xee,0xf0,0x80,0x21,0x90,0x72,0x02,0xe0,0xff,0x90,0x72,0x2a,0xe0}, - 16,0x365a,0,{0xfe,0x24,0x30,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xef,0xf0,0x74,0x38,0x2e,0xf5}, - 16,0x366a,0,{0x82,0xe4,0x34,0x80,0xf5,0x83,0xef,0xf0,0x90,0x76,0x40,0xe0,0x70,0x06,0x90,0x72}, - 16,0x367a,0,{0x39,0x74,0x0a,0xf0,0x90,0x72,0x39,0xe0,0x04,0xf0,0xe0,0xc3,0x94,0x0a,0x50,0x02}, - 8,0x368a,0,{0xa1,0x11,0xe4,0x90,0x76,0x40,0xf0,0x22}, - 16,0x3692,0,{0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xe0,0x22,0x50,0x02,0xe7,0x22,0xbb,0xfe,0x02}, - 9,0x36a2,0,{0xe3,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0x22}, - 16,0x36ab,0,{0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50}, - 16,0x36bb,0,{0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22}, - 13,0x36cb,0,{0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22}, - 16,0x36d8,0,{0xc2,0xd5,0xec,0x30,0xe7,0x09,0xb2,0xd5,0xe4,0xc3,0x9d,0xfd,0xe4,0x9c,0xfc,0xee}, - 16,0x36e8,0,{0x30,0xe7,0x15,0xb2,0xd5,0xe4,0xc3,0x9f,0xff,0xe4,0x9e,0xfe,0x12,0x38,0x1f,0xc3}, - 16,0x36f8,0,{0xe4,0x9d,0xfd,0xe4,0x9c,0xfc,0x80,0x03,0x12,0x38,0x1f,0x30,0xd5,0x07,0xc3,0xe4}, - 6,0x3708,0,{0x9f,0xff,0xe4,0x9e,0xfe,0x22}, - 16,0x370e,0,{0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0}, - 16,0x371e,0,{0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe}, - 16,0x372e,0,{0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83}, - 8,0x373e,0,{0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22}, - 16,0x3746,0,{0xe8,0x8f,0xf0,0xa4,0xcc,0x8b,0xf0,0xa4,0x2c,0xfc,0xe9,0x8e,0xf0,0xa4,0x2c,0xfc}, - 16,0x3756,0,{0x8a,0xf0,0xed,0xa4,0x2c,0xfc,0xea,0x8e,0xf0,0xa4,0xcd,0xa8,0xf0,0x8b,0xf0,0xa4}, - 16,0x3766,0,{0x2d,0xcc,0x38,0x25,0xf0,0xfd,0xe9,0x8f,0xf0,0xa4,0x2c,0xcd,0x35,0xf0,0xfc,0xeb}, - 16,0x3776,0,{0x8e,0xf0,0xa4,0xfe,0xa9,0xf0,0xeb,0x8f,0xf0,0xa4,0xcf,0xc5,0xf0,0x2e,0xcd,0x39}, - 15,0x3786,0,{0xfe,0xe4,0x3c,0xfc,0xea,0xa4,0x2d,0xce,0x35,0xf0,0xfd,0xe4,0x3c,0xfc,0x22}, - 16,0x3795,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xec,0x64,0x80,0xc8}, - 6,0x37a5,0,{0x64,0x80,0x98,0x45,0xf0,0x22}, - 16,0x37ab,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0}, - 1,0x37bb,0,{0x22}, - 12,0x37bc,0,{0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x22}, - 16,0x37c8,0,{0xa8,0x82,0x85,0x83,0xf0,0xd0,0x83,0xd0,0x82,0x12,0x37,0xdf,0x12,0x37,0xdf,0x12}, - 16,0x37d8,0,{0x37,0xdf,0x12,0x37,0xdf,0xe4,0x73,0xe4,0x93,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83}, - 16,0x37e8,0,{0xc8,0xc5,0x82,0xc8,0xf0,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83,0xc8,0xc5,0x82,0xc8}, - 1,0x37f8,0,{0x22}, - 16,0x37f9,0,{0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3}, - 16,0x3809,0,{0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60}, - 6,0x3819,0,{0xef,0xa3,0xa3,0xa3,0x80,0xdf}, - 16,0x381f,0,{0xbc,0x00,0x0b,0xbe,0x00,0x29,0xef,0x8d,0xf0,0x84,0xff,0xad,0xf0,0x22,0xe4,0xcc}, - 16,0x382f,0,{0xf8,0x75,0xf0,0x08,0xef,0x2f,0xff,0xee,0x33,0xfe,0xec,0x33,0xfc,0xee,0x9d,0xec}, - 16,0x383f,0,{0x98,0x40,0x05,0xfc,0xee,0x9d,0xfe,0x0f,0xd5,0xf0,0xe9,0xe4,0xce,0xfd,0x22,0xed}, - 16,0x384f,0,{0xf8,0xf5,0xf0,0xee,0x84,0x20,0xd2,0x1c,0xfe,0xad,0xf0,0x75,0xf0,0x08,0xef,0x2f}, - 16,0x385f,0,{0xff,0xed,0x33,0xfd,0x40,0x07,0x98,0x50,0x06,0xd5,0xf0,0xf2,0x22,0xc3,0x98,0xfd}, - 5,0x386f,0,{0x0f,0xd5,0xf0,0xea,0x22}, - 16,0x3874,0,{0xe4,0x90,0x76,0x29,0xf0,0x90,0x76,0x29,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x42}, - 16,0x3884,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}, - 16,0x3894,0,{0x60,0x0e,0xef,0xc3,0x94,0x06,0x50,0x08,0x90,0x76,0x29,0xe0,0x04,0xf0,0x80,0xd5}, - 16,0x38a4,0,{0xef,0xb4,0x06,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x0f}, - 16,0x38b4,0,{0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x2a,0xf0,0x24}, - 16,0x38c4,0,{0xbf,0x70,0x02,0x41,0x41,0x24,0xe0,0x70,0x02,0x41,0x12,0x24,0x21,0x60,0x02,0x41}, - 16,0x38d4,0,{0x3a,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x60,0x7d,0x14,0x70,0x02,0x21,0xb2,0x24,0x02}, - 16,0x38e4,0,{0x60,0x02,0x41,0x0a,0x12,0x17,0x51,0x90,0x76,0x42,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3}, - 16,0x38f4,0,{0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x76,0x29,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5}, - 16,0x3904,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xbc,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01}, - 16,0x3914,0,{0x12,0x90,0x76,0x7c,0x74,0x67,0xf0,0x90,0x76,0x7d,0x74,0x06,0xf0,0x90,0x76,0x7e}, - 16,0x3924,0,{0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0f,0xe4,0x90,0x76,0x7c,0xf0,0x90,0x76,0x7d,0xf0}, - 16,0x3934,0,{0x90,0x76,0x7e,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0f,0xe4,0x90,0x76,0x7c,0xf0,0x90}, - 16,0x3944,0,{0x76,0x7d,0xf0,0x90,0x76,0x7e,0x74,0x18,0xf0,0x90,0x76,0x1a,0x74,0x01,0xf0,0x12}, - 16,0x3954,0,{0x3e,0x9f,0x12,0x18,0x00,0x22,0x90,0x7e,0xc2,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb}, - 16,0x3964,0,{0xfa,0x79,0x01,0xf8,0x12,0x37,0x46,0xc8,0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca}, - 16,0x3974,0,{0xcb,0xef,0xcb,0x90,0x7e,0xc1,0xe0,0xfe,0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa}, - 16,0x3984,0,{0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x7e,0xc0,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff}, - 16,0x3994,0,{0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x76,0x29,0xe0,0x75,0xf0,0x0f}, - 16,0x39a4,0,{0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xbc,0x22,0x90,0x7e}, - 16,0x39b4,0,{0xc2,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x37,0x46,0xc8}, - 16,0x39c4,0,{0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x7e,0xc1,0xe0,0xfe}, - 16,0x39d4,0,{0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x7e}, - 16,0x39e4,0,{0xc0,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38}, - 16,0x39f4,0,{0xfc,0x90,0x76,0x29,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x3a04,0,{0xf5,0x83,0x12,0x37,0xbc,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f}, - 16,0x3a14,0,{0xe9,0xe0,0x14,0x70,0x19,0x90,0x7e,0xc0,0xe0,0xff,0x90,0x76,0x29,0xe0,0x75,0xf0}, - 16,0x3a24,0,{0x0f,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90,0x7f}, - 14,0x3a34,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22}, - 16,0x3a42,0,{0xe4,0x90,0x76,0x35,0xf0,0x90,0x76,0x35,0xe0,0xff,0xc3,0x94,0x03,0x40,0x02,0x41}, - 16,0x3a52,0,{0xff,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef}, - 16,0x3a62,0,{0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4}, - 16,0x3a72,0,{0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}, - 16,0x3a82,0,{0xf0,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x3a92,0,{0x74,0xff,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x3aa2,0,{0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x3ab2,0,{0x83,0x74,0x80,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x3ac2,0,{0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x3ad2,0,{0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x3ae2,0,{0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x3af2,0,{0xf5,0x83,0x74,0x01,0xf0,0x90,0x76,0x35,0xe0,0x04,0xf0,0x41,0x47,0x90,0x76,0x3c}, - 16,0x3b02,0,{0x74,0x0a,0xf0,0xe4,0xa3,0xf0,0x90,0x76,0x35,0x74,0x03,0xf0,0x90,0x76,0x3c,0xe0}, - 16,0x3b12,0,{0xff,0x90,0x76,0x35,0xe0,0xfe,0xc3,0x9f,0x40,0x02,0x61,0xd2,0x90,0x76,0x3d,0xe0}, - 16,0x3b22,0,{0xff,0x04,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x3b32,0,{0x83,0xef,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x3b42,0,{0x83,0xe4,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5}, - 16,0x3b52,0,{0x83,0x74,0x5e,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75}, - 16,0x3b62,0,{0xf5,0x83,0x74,0xba,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4,0x34}, - 16,0x3b72,0,{0x75,0xf5,0x83,0x74,0x05,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4}, - 16,0x3b82,0,{0x34,0x75,0xf5,0x83,0x74,0x80,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82}, - 16,0x3b92,0,{0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82}, - 16,0x3ba2,0,{0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82}, - 16,0x3bb2,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x15,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5}, - 16,0x3bc2,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x35,0xe0,0x04,0xf0,0x61,0x0e}, - 1,0x3bd2,0,{0x22}, - 16,0x3bd3,0,{0xe4,0x90,0x76,0x36,0xf0,0xe0,0xfb,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4}, - 16,0x3be3,0,{0x34,0x75,0xf5,0x83,0x74,0x40,0xf0,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82}, - 16,0x3bf3,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x0a,0xf0,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5}, - 16,0x3c03,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x00,0xac,0x44,0xeb,0x75,0xf0}, - 16,0x3c13,0,{0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x00}, - 16,0x3c23,0,{0xac,0x44,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 16,0x3c33,0,{0x12,0x37,0xc8,0x00,0x01,0x77,0x00,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xfb,0x75}, - 16,0x3c43,0,{0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x40,0xf0,0xeb}, - 16,0x3c53,0,{0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x8c,0xf0}, - 16,0x3c63,0,{0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37}, - 16,0x3c73,0,{0xc8,0x00,0x00,0xac,0x44,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34}, - 16,0x3c83,0,{0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x00,0xac,0x44,0xeb,0x75,0xf0,0x0f,0xa4,0x24}, - 16,0x3c93,0,{0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x01,0x77,0x00,0x90}, - 16,0x3ca3,0,{0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4}, - 16,0x3cb3,0,{0x34,0x75,0xf5,0x83,0x74,0x40,0xf0,0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82}, - 16,0x3cc3,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x8f,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff}, - 16,0x3cd3,0,{0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x41,0xf0}, - 16,0x3ce3,0,{0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x84}, - 16,0x3cf3,0,{0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5}, - 16,0x3d03,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x61,0xf0,0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42}, - 16,0x3d13,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x81,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0}, - 16,0x3d23,0,{0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}, - 16,0x3d33,0,{0x61,0xf0,0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}, - 4,0x3d43,0,{0x74,0x01,0xf0,0x22}, - 16,0x3d47,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0}, - 16,0x3d57,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef}, - 16,0x3d67,0,{0xc0,0xe0,0x90,0x7f,0xa2,0xe0,0x90,0x76,0x7f,0xf0,0x90,0x7f,0x74,0xe0,0x90,0x76}, - 16,0x3d77,0,{0x87,0xf0,0x90,0x7f,0x75,0xe0,0x90,0x76,0x88,0xf0,0x90,0x7f,0x98,0xe0,0x44,0x02}, - 16,0x3d87,0,{0xf0,0x90,0x76,0x96,0xe0,0xff,0x20,0xe1,0x0c,0x44,0x02,0xf0,0x90,0x80,0x03,0xf0}, - 16,0x3d97,0,{0xd2,0x32,0x12,0x4b,0x28,0x90,0x76,0x7f,0xe0,0x20,0xe2,0x50,0x90,0x76,0x87,0xe0}, - 16,0x3da7,0,{0xfe,0xa3,0xe0,0x7c,0x00,0x24,0x00,0xf5,0x34,0xec,0x3e,0xf5,0x33,0x90,0x76,0x98}, - 16,0x3db7,0,{0xe0,0xfd,0xae,0x33,0xaf,0x34,0x12,0x36,0xd8,0x90,0x76,0x87,0xef,0xf0,0xd2,0x2f}, - 16,0x3dc7,0,{0x30,0x31,0x29,0x20,0x3f,0x26,0xc2,0x31,0x90,0x7f,0x94,0xe0,0x54,0xcf,0xf0,0x90}, - 16,0x3dd7,0,{0x7f,0x9a,0xe0,0x30,0xe4,0x04,0xd2,0x2d,0xc2,0x2c,0x90,0x7f,0x9a,0xe0,0x20,0xe5}, - 16,0x3de7,0,{0x04,0xc2,0x2d,0xd2,0x2c,0x90,0x7f,0x94,0xe0,0x44,0x30,0xf0,0x12,0x48,0xbd,0x12}, - 16,0x3df7,0,{0x1b,0x04,0x30,0x2f,0x12,0x12,0x42,0x1f,0xc2,0x2f,0x75,0xe8,0x01,0x12,0x16,0x8a}, - 16,0x3e07,0,{0x75,0xe8,0x0d,0xd2,0x2b,0x80,0x05,0x75,0xe8,0x01,0xc2,0x2b,0x20,0x2b,0x34,0x90}, - 16,0x3e17,0,{0x76,0x19,0xe0,0xff,0xb4,0x01,0x0e,0x90,0x76,0x7c,0x74,0x67,0xf0,0xa3,0x74,0x06}, - 16,0x3e27,0,{0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0b,0x90,0x76,0x7c,0xe4,0xf0,0xa3,0xf0}, - 16,0x3e37,0,{0xa3,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0b,0x90,0x76,0x7c,0xe4,0xf0,0xa3,0xf0,0xa3}, - 16,0x3e47,0,{0x74,0x18,0xf0,0x75,0xca,0xd3,0x75,0xcb,0xfe,0xd2,0xca,0x30,0x34,0x04,0xc2,0x34}, - 16,0x3e57,0,{0x80,0x02,0xd2,0x34,0x30,0x34,0x0d,0x90,0x76,0x89,0xe0,0xc3,0x94,0x03,0x40,0x04}, - 16,0x3e67,0,{0xe0,0x24,0xfd,0xf0,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xf0,0x90,0x7f}, - 16,0x3e77,0,{0x98,0xe0,0x54,0xfd,0xf0,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0}, - 16,0x3e87,0,{0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0}, - 8,0x3e97,0,{0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0x32}, - 16,0x3e9f,0,{0x90,0x76,0x92,0xe0,0x14,0x60,0x1d,0x14,0x70,0x02,0xe1,0x54,0x24,0x02,0x60,0x02}, - 16,0x3eaf,0,{0xe1,0xe4,0x90,0x76,0x94,0x74,0x01,0xf0,0x90,0x80,0x00,0xf0,0xe4,0x90,0x76,0x8e}, - 16,0x3ebf,0,{0xf0,0xd2,0x31,0x22,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x1b,0xe4,0x90,0x7f,0xf2}, - 16,0x3ecf,0,{0xf0,0x90,0x7f,0xf3,0x74,0x30,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97}, - 16,0x3edf,0,{0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x02,0x1b,0xe4,0x90,0x7f,0xf2,0xf0}, - 16,0x3eef,0,{0x90,0x7f,0xf3,0x74,0x34,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97,0xe0}, - 16,0x3eff,0,{0x44,0x02,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x03,0x18,0xe4,0x90,0x7f,0xf2,0xf0,0x90}, - 16,0x3f0f,0,{0x7f,0xf3,0x74,0x64,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97,0xe0,0x44}, - 16,0x3f1f,0,{0x04,0xf0,0x90,0x76,0x94,0xe0,0x44,0x01,0xf0,0x90,0x80,0x00,0xf0,0x30,0x3f,0x09}, - 16,0x3f2f,0,{0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0}, - 16,0x3f3f,0,{0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0x90,0x76,0x98,0x74,0x04,0xf0,0x90,0x76}, - 16,0x3f4f,0,{0x8e,0x74,0x01,0xf0,0x22,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x1b,0xe4,0x90,0x7f}, - 16,0x3f5f,0,{0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x44,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76}, - 16,0x3f6f,0,{0x97,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x02,0x1b,0xe4,0x90,0x7f,0xf2}, - 16,0x3f7f,0,{0xf0,0x90,0x7f,0xf3,0x74,0x4c,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97}, - 16,0x3f8f,0,{0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x03,0x18,0xe4,0x90,0x7f,0xf2,0xf0}, - 16,0x3f9f,0,{0x90,0x7f,0xf3,0x74,0x94,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97,0xe0}, - 16,0x3faf,0,{0x44,0x04,0xf0,0x90,0x76,0x94,0xe0,0x54,0xfe,0xf0,0x90,0x80,0x00,0xf0,0x30,0x3f}, - 16,0x3fbf,0,{0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01}, - 16,0x3fcf,0,{0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0x90,0x76,0x98,0x74,0x06,0xf0,0x90}, - 6,0x3fdf,0,{0x76,0x8e,0x74,0x02,0xf0,0x22}, - 16,0x3fe5,0,{0x90,0x7f,0xea,0xe0,0x90,0x76,0x82,0xf0,0xe4,0x90,0x76,0x91,0xf0,0x90,0x76,0x92}, - 11,0x3ff5,0,{0xf0,0x90,0x76,0x90,0xf0,0x90,0x76,0x93,0xf0,0xd3,0x22}, - 16,0x4000,0,{0xe5,0x11,0xd3,0x94,0x00,0x50,0x02,0x21,0x06,0x90,0x76,0x89,0xe0,0xc3,0x94,0x08}, - 16,0x4010,0,{0x40,0x02,0x21,0x06,0x74,0x40,0x25,0x0f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0}, - 16,0x4020,0,{0xf5,0x17,0xe5,0x0d,0x60,0x0e,0x90,0x80,0x05,0xe5,0x17,0xf0,0x90,0x76,0x89,0xe0}, - 16,0x4030,0,{0x04,0xf0,0x01,0xda,0xe5,0x17,0x12,0x37,0xf9,0x40,0xc1,0x02,0x40,0x67,0x05,0x40}, - 16,0x4040,0,{0x7a,0x06,0x40,0x98,0x07,0x40,0xc1,0x0c,0x40,0xc1,0x0d,0x40,0xc7,0x0f,0x40,0xcb}, - 16,0x4050,0,{0xf6,0x40,0xcb,0xf8,0x40,0xcb,0xfa,0x40,0xcb,0xfb,0x40,0xcb,0xfc,0x40,0xcb,0xfe}, - 16,0x4060,0,{0x40,0xcb,0xff,0x00,0x00,0x40,0xda,0x90,0x7e,0x41,0xe0,0x90,0x80,0x05,0xf0,0x90}, - 16,0x4070,0,{0x76,0x89,0xe0,0x04,0xf0,0x75,0x11,0x01,0x80,0x60,0x90,0x7e,0x41,0xe0,0x90,0x80}, - 16,0x4080,0,{0x05,0xf0,0x90,0x7e,0x42,0xe0,0x90,0x80,0x05,0xf0,0x90,0x76,0x89,0xe0,0x04,0xf0}, - 16,0x4090,0,{0xe0,0x04,0xf0,0x75,0x11,0x01,0x80,0x42,0x90,0x7e,0x41,0xe0,0x90,0x80,0x05,0xf0}, - 16,0x40a0,0,{0x90,0x7e,0x42,0xe0,0x90,0x80,0x05,0xf0,0x90,0x7e,0x43,0xe0,0x90,0x80,0x05,0xf0}, - 16,0x40b0,0,{0x90,0x76,0x89,0xe0,0x04,0xf0,0xe0,0x04,0xf0,0xe0,0x04,0xf0,0x75,0x11,0x01,0x80}, - 16,0x40c0,0,{0x19,0xd2,0x3b,0xd2,0x3c,0x80,0x13,0xd2,0x3b,0x80,0x0f,0x90,0x80,0x05,0xe5,0x17}, - 16,0x40d0,0,{0xf0,0x90,0x76,0x89,0xe0,0x04,0xf0,0x75,0x11,0x01,0x20,0x3b,0x04,0x05,0x0d,0x80}, - 16,0x40e0,0,{0x1f,0x30,0x3c,0x1c,0x90,0x7e,0x41,0xe0,0x90,0x80,0x05,0xf0,0x90,0x7e,0x42,0xe0}, - 16,0x40f0,0,{0x90,0x80,0x05,0xf0,0x90,0x76,0x89,0xe0,0x04,0xf0,0xe0,0x04,0xf0,0x75,0x11,0x01}, - 16,0x4100,0,{0x05,0x0f,0x15,0x11,0x01,0x00,0xe5,0x11,0x70,0x10,0xc2,0x33,0xf5,0x0d,0xf5,0x0f}, - 11,0x4110,0,{0x90,0x7f,0xc7,0x74,0x04,0xf0,0xc2,0x3b,0xc2,0x3c,0x22}, - 16,0x411b,0,{0x90,0x76,0x8d,0xe0,0x64,0x01,0x70,0x27,0x30,0x27,0x08,0xc2,0x27,0x12,0x08,0x00}, - 16,0x412b,0,{0x12,0x17,0x4a,0x30,0x28,0x08,0xc2,0x28,0x12,0x38,0x74,0x12,0x17,0x4a,0x30,0x2a}, - 16,0x413b,0,{0x0e,0xe4,0x90,0x76,0x8d,0xf0,0xc2,0x2a,0x90,0x7f,0xb4,0xe0,0x44,0x02,0xf0,0x90}, - 16,0x414b,0,{0x76,0x3f,0xe0,0xb4,0x01,0x05,0xe4,0xf0,0x12,0x32,0x6f,0x90,0x76,0x41,0xe0,0xb4}, - 16,0x415b,0,{0x01,0x05,0xe4,0xf0,0x12,0x34,0x9a,0x90,0x76,0x40,0xe0,0xb4,0x01,0x03,0x12,0x34}, - 16,0x416b,0,{0x9a,0x12,0x30,0x00,0x30,0x33,0x03,0x12,0x40,0x00,0x90,0x7f,0x9b,0xe0,0x20,0xe4}, - 16,0x417b,0,{0x02,0xc2,0x3f,0x90,0x7f,0x9b,0xe0,0x30,0xe4,0x02,0xd2,0x3f,0x90,0x7f,0x9b,0xe0}, - 16,0x418b,0,{0x20,0xe5,0x02,0xc2,0x3e,0x90,0x7f,0x9b,0xe0,0x30,0xe5,0x02,0xd2,0x3e,0xa2,0x41}, - 16,0x419b,0,{0x30,0x3f,0x01,0xb3,0x50,0x1f,0xa2,0x3f,0x92,0x41,0x30,0x3f,0x09,0x90,0x76,0x97}, - 16,0x41ab,0,{0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97}, - 16,0x41bb,0,{0xe0,0x90,0x80,0x02,0xf0,0x30,0x3f,0x34,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x0e}, - 16,0x41cb,0,{0x90,0x76,0x7c,0x74,0x67,0xf0,0xa3,0x74,0x06,0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4}, - 16,0x41db,0,{0x02,0x0b,0xe4,0x90,0x76,0x7c,0xf0,0xa3,0xf0,0xa3,0x74,0x0c,0xf0,0xef,0xb4,0x03}, - 16,0x41eb,0,{0x0b,0xe4,0x90,0x76,0x7c,0xf0,0xa3,0xf0,0xa3,0x74,0x18,0xf0,0xa2,0x40,0x30,0x3e}, - 16,0x41fb,0,{0x01,0xb3,0x50,0x1f,0xa2,0x3e,0x92,0x40,0x30,0x3e,0x09,0x90,0x76,0x95,0xe0,0x44}, - 16,0x420b,0,{0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90,0x76,0x95,0xe0,0x90}, - 4,0x421b,0,{0x80,0x01,0xf0,0x22}, - 16,0x421f,0,{0x90,0x76,0x19,0xe0,0x64,0x01,0x70,0x35,0x90,0x76,0x87,0xe0,0xff,0xd3,0x94,0x2d}, - 16,0x422f,0,{0x40,0x2b,0x90,0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0,0xe0,0xd3}, - 16,0x423f,0,{0x94,0x0f,0x40,0x19,0xe4,0xf0,0xef,0xd3,0x94,0x31,0x40,0x08,0x90,0x76,0x19,0x74}, - 16,0x424f,0,{0x03,0xf0,0x80,0x06,0x90,0x76,0x19,0x74,0x02,0xf0,0x12,0x3e,0x9f,0x90,0x76,0x19}, - 16,0x425f,0,{0xe0,0xb4,0x02,0x2c,0x90,0x76,0x87,0xe0,0xff,0xc3,0x94,0x2f,0x50,0x22,0xef,0xd3}, - 16,0x426f,0,{0x94,0x2a,0x40,0x1c,0x90,0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0}, - 16,0x427f,0,{0xe0,0xd3,0x94,0x0f,0x40,0x0a,0xe4,0xf0,0x90,0x76,0x19,0x04,0xf0,0x12,0x3e,0x9f}, - 16,0x428f,0,{0x90,0x76,0x19,0xe0,0xb4,0x02,0x26,0x90,0x76,0x87,0xe0,0xd3,0x94,0x31,0x40,0x1d}, - 16,0x429f,0,{0x90,0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f}, - 16,0x42af,0,{0x40,0x0b,0xe4,0xf0,0x90,0x76,0x19,0x74,0x03,0xf0,0x12,0x3e,0x9f,0x90,0x76,0x19}, - 16,0x42bf,0,{0xe0,0x64,0x03,0x70,0x3f,0x90,0x76,0x87,0xe0,0xff,0xc3,0x94,0x5f,0x50,0x35,0x90}, - 16,0x42cf,0,{0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f,0x40}, - 16,0x42df,0,{0x23,0xe4,0xf0,0xef,0xc3,0x94,0x2f,0x50,0x0c,0xef,0xd3,0x94,0x2a,0x40,0x06,0x90}, - 16,0x42ef,0,{0x76,0x19,0x74,0x01,0xf0,0xef,0xd3,0x94,0x2f,0x40,0x06,0x90,0x76,0x19,0x74,0x02}, - 16,0x42ff,0,{0xf0,0x12,0x3e,0x9f,0x90,0x76,0x86,0xe0,0x70,0x05,0x90,0x76,0x85,0xf0,0x22,0xe4}, - 5,0x430f,0,{0x90,0x76,0x86,0xf0,0x22}, - 16,0x4314,0,{0xe4,0x90,0x76,0x96,0xf0,0x90,0x80,0x03,0xf0,0x90,0x7f,0xe0,0x74,0x90,0xf0,0x90}, - 16,0x4324,0,{0x7f,0xe1,0x74,0x04,0xf0,0xe4,0x90,0x7f,0xdd,0xf0,0x90,0x7f,0xa1,0xf0,0x53,0x8e}, - 16,0x4334,0,{0xf8,0x75,0x88,0x05,0x75,0xb8,0x20,0x75,0xf8,0x01,0x43,0x8e,0x30,0xf5,0xc8,0x75}, - 16,0x4344,0,{0xca,0x7f,0x75,0xcb,0xf8,0x43,0xa8,0x20,0x12,0x45,0x65,0xc2,0x2c,0xc2,0x2d,0xc2}, - 16,0x4354,0,{0x2b,0xc2,0x2f,0x90,0x7f,0xfc,0x74,0xdd,0xf0,0x90,0x7f,0xff,0x74,0xff,0xf0,0x90}, - 16,0x4364,0,{0x7f,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x19,0x74,0x01,0xf0,0xe4,0x90,0x76,0x85}, - 16,0x4374,0,{0xf0,0xa3,0xf0,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0x12,0x49,0xae,0x12,0x0f}, - 16,0x4384,0,{0xc6,0x12,0x4a,0xf1,0x90,0x7f,0x97,0xe0,0x44,0x08,0xf0,0xe0,0x54,0xb9,0xf0,0xd2}, - 16,0x4394,0,{0x30,0x20,0x30,0x18,0x12,0x4a,0xa6,0x12,0x30,0x00,0x12,0x40,0x00,0x12,0x42,0x1f}, - 16,0x43a4,0,{0x12,0x48,0xbd,0x12,0x1b,0x04,0x12,0x16,0x61,0x12,0x42,0x1f,0x12,0x4a,0xa6,0xc2}, - 16,0x43b4,0,{0x2f,0xc2,0x31,0xc2,0x32,0xc2,0x34,0xc2,0x33,0xc2,0x29,0xc2,0x27,0xc2,0x28,0xe4}, - 16,0x43c4,0,{0xf5,0x11,0x90,0x76,0x89,0xf0,0x90,0x76,0x3f,0xf0,0x90,0x76,0x41,0xf0,0x90,0x76}, - 16,0x43d4,0,{0x40,0xf0,0x90,0x76,0x8a,0xf0,0xa3,0xf0,0xa3,0x04,0xf0,0xe4,0xa3,0xf0,0x90,0x76}, - 3,0x43e4,0,{0x99,0xf0,0x22}, - 16,0x43e7,0,{0x12,0x4e,0x19,0x40,0x02,0x81,0xac,0x90,0x7f,0xeb,0xe0,0x24,0xfe,0x60,0x1e,0x14}, - 16,0x43f7,0,{0x60,0x46,0x14,0x60,0x6e,0x14,0x70,0x02,0x81,0x9d,0x24,0x04,0x60,0x02,0x81,0xa5}, - 16,0x4407,0,{0x74,0x05,0x90,0x7f,0xd4,0xf0,0x74,0x00,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xea}, - 16,0x4417,0,{0xe0,0xff,0x12,0x4a,0x55,0x8b,0x20,0x8a,0x21,0x89,0x22,0xea,0x49,0x60,0x11,0xce}, - 16,0x4427,0,{0xea,0xce,0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22}, - 16,0x4437,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x12,0x47,0xb7}, - 16,0x4447,0,{0x8b,0x20,0x8a,0x21,0x89,0x22,0xea,0x49,0x60,0x11,0xce,0xea,0xce,0xee,0x90,0x7f}, - 16,0x4457,0,{0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44}, - 16,0x4467,0,{0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x90,0x7e,0xc0,0xe0,0xfd,0xa3,0xe0,0xfb}, - 16,0x4477,0,{0x12,0x17,0x94,0x8b,0x20,0x8a,0x21,0x89,0x22,0xea,0x49,0x60,0x11,0xce,0xea,0xce}, - 16,0x4487,0,{0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f}, - 16,0x4497,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f}, - 5,0x44a7,0,{0xb4,0xe0,0x44,0x01,0xf0}, - 1,0x44ac,0,{0x22}, - 16,0x44ad,0,{0xc2,0xaf,0xd2,0x24,0x90,0x7f,0x93,0x74,0x30,0xf0,0x90,0x7f,0x9c,0x74,0xbb,0xf0}, - 16,0x44bd,0,{0x90,0x7f,0x96,0xe0,0x44,0x30,0xf0,0xe0,0x54,0x30,0xf0,0x90,0x7f,0x94,0x74,0x30}, - 16,0x44cd,0,{0xf0,0x90,0x7f,0x9d,0x74,0xcf,0xf0,0x90,0x7f,0x97,0x74,0xa0,0xf0,0x90,0x7f,0x95}, - 16,0x44dd,0,{0x74,0xc0,0xf0,0x90,0x7f,0x9e,0x74,0x03,0xf0,0x90,0x7f,0x99,0xe0,0x30,0xe2,0x09}, - 16,0x44ed,0,{0x90,0x05,0x19,0x74,0xa0,0xf0,0xe4,0xa3,0xf0,0xc2,0x25,0xc2,0x22,0xc2,0x23,0xc2}, - 16,0x44fd,0,{0x26,0x12,0x4b,0x28,0x12,0x2d,0xa9,0x12,0x3b,0xd3,0x12,0x46,0x19,0x12,0x3a,0x42}, - 16,0x450d,0,{0x90,0x76,0x68,0x74,0x01,0xf0,0x70,0x0f,0x12,0x4c,0x29,0x12,0x4e,0x15,0x12,0x4e}, - 16,0x451d,0,{0x17,0x12,0x1b,0x40,0x12,0x14,0x96,0x12,0x43,0x14,0x90,0x7f,0xaf,0xe0,0x44,0x01}, - 16,0x452d,0,{0xf0,0x90,0x7f,0xae,0xe0,0x44,0x1f,0xf0,0x90,0x7f,0xac,0x74,0xff,0xf0,0x90,0x7f}, - 16,0x453d,0,{0xad,0xf0,0x90,0x7f,0xde,0xf0,0x90,0x7f,0xdf,0xf0,0x90,0x7f,0xab,0xf0,0x90,0x7f}, - 16,0x454d,0,{0xa9,0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x43,0xd8,0x20,0xd2,0xe8,0x43,0xd8}, - 8,0x455d,0,{0x20,0x53,0xa8,0xa0,0x43,0xa8,0x80,0x22}, - 16,0x4565,0,{0x90,0x76,0x9a,0x74,0x02,0xf0,0xe4,0x90,0x76,0x91,0xf0,0xa3,0xf0,0x90,0x76,0x90}, - 16,0x4575,0,{0xf0,0x90,0x76,0x93,0xf0,0x90,0x76,0x96,0x74,0x03,0xf0,0x90,0x80,0x03,0xf0,0xe4}, - 16,0x4585,0,{0x90,0x76,0x97,0xf0,0x90,0x80,0x02,0xf0,0x90,0x76,0x94,0x04,0xf0,0x90,0x80,0x00}, - 16,0x4595,0,{0xf0,0xe4,0x90,0x76,0x8e,0xf0,0x90,0x76,0x1a,0xf0,0x90,0x76,0x95,0x04,0xf0,0xc2}, - 16,0x45a5,0,{0x2e,0x90,0x7f,0x9b,0xe0,0xff,0x54,0x10,0xff,0x70,0x02,0xc2,0x3f,0x90,0x7f,0x9b}, - 16,0x45b5,0,{0xe0,0xff,0x54,0x10,0xfe,0xff,0xbe,0x10,0x02,0xd2,0x3f,0x90,0x7f,0x9b,0xe0,0xff}, - 16,0x45c5,0,{0x54,0x20,0xff,0x70,0x02,0xc2,0x3e,0x90,0x7f,0x9b,0xe0,0xff,0x54,0x20,0xfe,0xff}, - 16,0x45d5,0,{0xbe,0x20,0x02,0xd2,0x3e,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80}, - 16,0x45e5,0,{0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0}, - 16,0x45f5,0,{0x30,0x3e,0x09,0x90,0x76,0x95,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0}, - 16,0x4605,0,{0x54,0xfb,0xf0,0x90,0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0xa2,0x3e,0x92,0x40,0xa2}, - 3,0x4615,0,{0x3f,0x92,0x41}, - 1,0x4618,0,{0x22}, - 16,0x4619,0,{0xe4,0x90,0x76,0x36,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4}, - 16,0x4629,0,{0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4}, - 16,0x4639,0,{0x34,0x75,0xf5,0x83,0x74,0x01,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75}, - 16,0x4649,0,{0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75}, - 16,0x4659,0,{0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0x90}, - 16,0x4669,0,{0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4}, - 16,0x4679,0,{0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4}, - 16,0x4689,0,{0x34,0x75,0xf5,0x83,0x74,0x03,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75}, - 16,0x4699,0,{0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75}, - 16,0x46a9,0,{0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x22}, - 12,0x46b9,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x38,0x02,0x47,0x00}, - 16,0x46c5,0,{0x02,0x07,0xa6,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2}, - 16,0x46d5,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33}, - 16,0x46e5,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf}, - 16,0x46f5,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x0c,0x8f,0xe4,0x7e}, - 16,0x4705,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93}, - 16,0x4715,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3}, - 16,0x4725,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca}, - 16,0x4735,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe}, - 16,0x4745,0,{0x90,0x7f,0xec,0xe0,0x90,0x76,0x83,0xf0,0xe0,0x14,0x60,0x1d,0x14,0x60,0x2a,0x14}, - 16,0x4755,0,{0x60,0x37,0x14,0x60,0x44,0x24,0x04,0x70,0x50,0x90,0x76,0x91,0xe0,0x90,0x7f,0x00}, - 16,0x4765,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x47,0x90,0x76,0x92,0xe0,0x90,0x7f,0x00}, - 16,0x4775,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x37,0x90,0x76,0x90,0xe0,0x90,0x7f,0x00}, - 16,0x4785,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x27,0x90,0x76,0x84,0xe0,0x90,0x7f,0x00}, - 16,0x4795,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x17,0x90,0x76,0x93,0xe0,0x90,0x7f,0x00}, - 16,0x47a5,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0}, - 2,0x47b5,0,{0xd3,0x22}, - 2,0x47b7,0,{0x8f,0x2e}, - 16,0x47b9,0,{0xe4,0xf5,0x2f,0x75,0x30,0xff,0x75,0x31,0x07,0x75,0x32,0x1a,0xab,0x30,0xaa,0x31}, - 16,0x47c9,0,{0xa9,0x32,0x90,0x00,0x01,0x12,0x36,0xab,0xb4,0x03,0x1f,0xaf,0x2f,0x05,0x2f,0xef}, - 16,0x47d9,0,{0x65,0x2e,0x70,0x01,0x22,0x12,0x36,0x92,0x7e,0x00,0x29,0xff,0xee,0x3a,0xc9,0xef}, - 16,0x47e9,0,{0xc9,0x75,0x30,0xff,0xf5,0x31,0x89,0x32,0x80,0xd2,0x7b,0x00,0x7a,0x00,0x79,0x00}, - 1,0x47f9,0,{0x22}, - 6,0x47fa,0,{0x12,0x4b,0x28,0xc2,0x31,0x22}, - 16,0x4800,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0}, - 16,0x4810,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef}, - 16,0x4820,0,{0xc0,0xe0,0xc2,0xca,0xc2,0xcf,0x90,0x7f,0x98,0xe0,0x44,0x01,0xf0,0x30,0x2e,0x03}, - 16,0x4830,0,{0x12,0x14,0xa6,0x90,0x7f,0x98,0xe0,0x54,0xfe,0xf0,0x53,0xa8,0xfa,0x12,0x16,0x61}, - 16,0x4840,0,{0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0}, - 16,0x4850,0,{0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0}, - 3,0x4860,0,{0xd0,0xe0,0x32}, - 16,0x4863,0,{0x90,0x7f,0xec,0xe0,0x90,0x76,0x83,0xf0,0xe0,0x14,0x60,0x17,0x14,0x60,0x21,0x14}, - 16,0x4873,0,{0x60,0x2b,0x14,0x60,0x32,0x24,0x04,0x70,0x38,0x90,0x7f,0xea,0xe0,0x90,0x76,0x91}, - 16,0x4883,0,{0xf0,0x80,0x35,0x90,0x7f,0xea,0xe0,0x90,0x76,0x92,0xf0,0x12,0x3e,0x9f,0x80,0x28}, - 16,0x4893,0,{0x90,0x7f,0xea,0xe0,0x90,0x76,0x90,0xf0,0x12,0x18,0x00,0x80,0x1b,0x90,0x7f,0xea}, - 16,0x48a3,0,{0xe0,0x90,0x76,0x84,0xf0,0x80,0x11,0x90,0x7f,0xea,0xe0,0x90,0x76,0x93,0xf0,0x80}, - 10,0x48b3,0,{0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xd3,0x22}, - 16,0x48bd,0,{0x30,0x2d,0x39,0xc2,0x2d,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x0d,0xe4,0x90,0x76}, - 16,0x48cd,0,{0x7c,0xf0,0xa3,0x74,0xf8,0xf0,0xa3,0x74,0x0a,0xf0,0xef,0xb4,0x02,0x0d,0xe4,0x90}, - 16,0x48dd,0,{0x76,0x7c,0xf0,0xa3,0x74,0xf0,0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x03,0x0d,0xe4}, - 13,0x48ed,0,{0x90,0x76,0x7c,0xf0,0xa3,0x74,0xf8,0xf0,0xa3,0x74,0x17,0xf0,0x22}, - 6,0x48fa,0,{0x53,0x91,0xbf,0xd2,0x2d,0x32}, - 16,0x4900,0,{0x02,0x2f,0xe7,0x00,0x02,0x3d,0x47,0x00,0x02,0x4d,0xb4,0x00,0x02,0x4c,0x43,0x00}, - 16,0x4910,0,{0x02,0x4b,0xe9,0x00,0x02,0x2f,0xff,0x00,0x02,0x4c,0x5b,0x00,0x02,0x4c,0x0a,0x00}, - 16,0x4920,0,{0x02,0x4c,0x72,0x00,0x02,0x4b,0x5a,0x00,0x02,0x4c,0x89,0x00,0x02,0x4c,0xa0,0x00}, - 16,0x4930,0,{0x02,0x4c,0xb7,0x00,0x02,0x4c,0xce,0x00,0x02,0x4c,0xe5,0x00,0x02,0x4c,0xfc,0x00}, - 16,0x4940,0,{0x02,0x4d,0x13,0x00,0x02,0x4d,0x2a,0x00,0x02,0x4d,0x41,0x00,0x02,0x4d,0x58,0x00}, - 8,0x4950,0,{0x02,0x4d,0x6f,0x00,0x02,0x4d,0x86,0x00}, - 16,0x4958,0,{0xe4,0x90,0x76,0x26,0xf0,0x90,0x76,0x26,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x34}, - 16,0x4968,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}, - 16,0x4978,0,{0x60,0x0e,0xef,0xc3,0x94,0x04,0x50,0x08,0x90,0x76,0x26,0xe0,0x04,0xf0,0x80,0xd5}, - 16,0x4988,0,{0xef,0xb4,0x04,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x03}, - 16,0x4998,0,{0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0x90}, - 6,0x49a8,0,{0x7f,0xb5,0x74,0x01,0xf0,0x22}, - 16,0x49ae,0,{0x90,0x76,0x46,0x74,0x80,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3}, - 16,0x49be,0,{0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0x74,0x80,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0}, - 16,0x49ce,0,{0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3}, - 16,0x49de,0,{0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0}, - 16,0x49ee,0,{0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0}, - 5,0x49fe,0,{0xa3,0xf0,0xa3,0xf0,0x22}, - 16,0x4a03,0,{0xe4,0x90,0x76,0x25,0xf0,0x90,0x76,0x25,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x34}, - 16,0x4a13,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}, - 16,0x4a23,0,{0x60,0x0e,0xef,0xc3,0x94,0x04,0x50,0x08,0x90,0x76,0x25,0xe0,0x04,0xf0,0x80,0xd5}, - 16,0x4a33,0,{0xef,0xb4,0x04,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7e,0xc0,0xe0}, - 16,0x4a43,0,{0xfe,0xef,0x75,0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xee}, - 2,0x4a53,0,{0xf0,0x22}, - 16,0x4a55,0,{0xe4,0xfe,0x75,0x1d,0xff,0x75,0x1e,0x05,0x75,0x1f,0x12,0xab,0x1d,0xaa,0x1e,0xa9}, - 16,0x4a65,0,{0x1f,0x90,0x00,0x01,0x12,0x36,0xab,0x64,0x02,0x70,0x2f,0xcd,0xee,0xcd,0x0e,0xed}, - 16,0x4a75,0,{0x6f,0x70,0x01,0x22,0x90,0x00,0x02,0x12,0x37,0x0e,0x85,0xf0,0x1b,0xf5,0x1c,0x62}, - 16,0x4a85,0,{0x1b,0xe5,0x1b,0x62,0x1c,0xe5,0x1c,0x62,0x1b,0x29,0xfd,0xe5,0x1b,0x3a,0xc9,0xed}, - 16,0x4a95,0,{0xc9,0x75,0x1d,0xff,0xf5,0x1e,0x89,0x1f,0x80,0xc1,0x7b,0x00,0x7a,0x00,0x79,0x00}, - 1,0x4aa5,0,{0x22}, - 16,0x4aa6,0,{0xe4,0x90,0x76,0x9b,0xf0,0x90,0x76,0x9b,0xe0,0xff,0x04,0xf0,0xef,0x60,0x08,0xe0}, - 16,0x4ab6,0,{0x24,0x08,0xf8,0xe4,0xf6,0x80,0xee,0x90,0x76,0x96,0xe0,0x44,0x04,0xf0,0x44,0x08}, - 16,0x4ac6,0,{0xf0,0x90,0x80,0x03,0xf0,0xe4,0xf5,0x18,0xd2,0x35,0xf5,0x0e,0xf5,0x10,0xd2,0x36}, - 16,0x4ad6,0,{0x75,0x12,0x11,0x75,0x13,0x22,0xc2,0x37,0xc2,0x39,0xc2,0x38,0xf5,0x16,0xf5,0x14}, - 11,0x4ae6,0,{0xf5,0x1a,0xf5,0x0d,0xc2,0x3b,0xc2,0x3c,0xc2,0x3d,0x22}, - 16,0x4af1,0,{0xe4,0xff,0x74,0x56,0x2f,0xf5,0x82,0xe4,0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x28}, - 16,0x4b01,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x5e,0x2f,0xf5,0x82,0xe4}, - 16,0x4b11,0,{0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x38,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83}, - 6,0x4b21,0,{0xee,0xf0,0x0f,0xbf,0x08,0xcc}, - 1,0x4b27,0,{0x22}, - 16,0x4b28,0,{0xe4,0x90,0x72,0x36,0xf0,0xa3,0xf0,0x90,0x7f,0x97,0xe0,0x54,0xfb,0xf0,0xe4,0x90}, - 16,0x4b38,0,{0x72,0x33,0xf0,0x90,0x72,0x32,0xf0,0x90,0x72,0x01,0x04,0xf0,0xe4,0x90,0x72,0x33}, - 16,0x4b48,0,{0xf0,0x90,0x72,0x32,0xf0,0x90,0x72,0x01,0x04,0xf0,0x90,0x7f,0x97,0xe0,0x44,0x04}, - 2,0x4b58,0,{0xf0,0x22}, - 16,0x4b5a,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x02,0xf0}, - 16,0x4b6a,0,{0x90,0x7f,0xc7,0xe0,0xf5,0x11,0x75,0x0f,0x00,0x75,0x0d,0x00,0xd2,0x33,0xd0,0x82}, - 5,0x4b7a,0,{0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4b7f,0,{0x90,0x7f,0xd6,0xe0,0x54,0xfb,0xf0,0xe0,0x44,0x08,0xf0,0x30,0x42,0x04,0xe0,0x44}, - 16,0x4b8f,0,{0x02,0xf0,0x7f,0xdc,0x7e,0x05,0x12,0x4d,0x9d,0x90,0x7f,0xd6,0xe0,0x54,0xf7,0xf0}, - 5,0x4b9f,0,{0xe0,0x44,0x04,0xf0,0x22}, - 16,0x4ba4,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x14,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x04,0x12}, - 16,0x4bb4,0,{0x49,0x58,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44}, - 3,0x4bc4,0,{0x01,0xf0,0x22}, - 16,0x4bc7,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x13,0x90,0x7f,0xe9,0xe0,0x14,0x70,0x04,0x12,0x4a}, - 16,0x4bd7,0,{0x03,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01}, - 2,0x4be7,0,{0xf0,0x22}, - 16,0x4be9,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0x90}, - 16,0x4bf9,0,{0x76,0x96,0xe0,0x54,0xfd,0xf0,0x90,0x80,0x03,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0}, - 1,0x4c09,0,{0x32}, - 16,0x4c0a,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x01,0xf0}, - 15,0x4c1a,0,{0xc2,0x29,0x90,0x76,0x8d,0x74,0x01,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4c29,0,{0x90,0x7f,0xd6,0xe0,0x30,0xe7,0x12,0xe0,0x44,0x01,0xf0,0x7f,0x14,0x7e,0x00,0x12}, - 10,0x4c39,0,{0x4d,0x9d,0x90,0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x22}, - 16,0x4c43,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x25,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08}, - 8,0x4c53,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4c5b,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x01,0xf0}, - 7,0x4c6b,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4c72,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x02,0xf0}, - 7,0x4c82,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4c89,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x04,0xf0}, - 7,0x4c99,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4ca0,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x04,0xf0}, - 7,0x4cb0,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4cb7,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x08,0xf0}, - 7,0x4cc7,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4cce,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x08,0xf0}, - 7,0x4cde,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4ce5,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x10,0xf0}, - 7,0x4cf5,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4cfc,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x10,0xf0}, - 7,0x4d0c,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d13,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x20,0xf0}, - 7,0x4d23,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d2a,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x20,0xf0}, - 7,0x4d3a,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d41,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x40,0xf0}, - 7,0x4d51,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d58,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x40,0xf0}, - 7,0x4d68,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d6f,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x80,0xf0}, - 7,0x4d7f,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d86,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x80,0xf0}, - 7,0x4d96,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4d9d,0,{0x8e,0x35,0x8f,0x36,0xe5,0x36,0x15,0x36,0xae,0x35,0x70,0x02,0x15,0x35,0x4e,0x60}, - 7,0x4dad,0,{0x05,0x12,0x14,0x85,0x80,0xee,0x22}, - 16,0x4db4,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x04,0xf0,0xd0}, - 6,0x4dc4,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x4dca,0,{0x90,0x76,0x82,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0xd3,0x22}, - 12,0x4dda,0,{0xc2,0x37,0xe4,0xf5,0x0e,0xf5,0x10,0xc2,0x36,0xf5,0x14,0x22}, - 9,0x4de6,0,{0xc2,0x25,0x53,0xd8,0xef,0x43,0xd8,0x20,0x32}, - 7,0x4def,0,{0x53,0x98,0xfe,0x53,0x98,0xfd,0x32}, - 7,0x4df6,0,{0x53,0xc0,0xfe,0x53,0xc0,0xfd,0x32}, - 6,0x4dfd,0,{0x53,0x91,0x7f,0xd2,0x2c,0x32}, - 4,0x4e03,0,{0x53,0x91,0xdf,0x32}, - 4,0x4e07,0,{0x53,0xd8,0xf7,0x32}, - 4,0x4e0b,0,{0x12,0x17,0x30,0x22}, - 3,0x4e0f,0,{0xc2,0x8d,0x32}, - 3,0x4e12,0,{0xc2,0x8f,0x32}, - 2,0x4e15,0,{0xd3,0x22}, - 2,0x4e17,0,{0xd3,0x22}, - 2,0x4e19,0,{0xd3,0x22}, - 2,0x4e1b,0,{0xd3,0x22}, - 2,0x4e1d,0,{0xd3,0x22}, - 2,0x4e1f,0,{0xd3,0x22}, - 2,0x4e21,0,{0xc3,0x22}, - 0,0x0000,1,{0} -}; -/* Source: EMI62MFW.HEX -:100C8F004176680141766A0241766B0AC120C12123 -:1044AD00C2AFD224907F937430F0907F9C74BBF098 -:1044BD00907F96E04430F0E05430F0907F9474306B -:1044CD00F0907F9D74CFF0907F9774A0F0907F95C2 -:1044DD0074C0F0907F9E7403F0907F99E030E209F4 -:1044ED0090051974A0F0E4A3F0C225C222C223C224 -:1044FD0026124B28122DA9123BD3124619123A42FD -:10450D009076687401F0700F124C29124E15124EF0 -:10451D0017121B40121496124314907FAFE0440102 -:10452D00F0907FAEE0441FF0907FAC74FFF0907F71 -:10453D00ADF0907FDEF0907FDFF0907FABF0907F5D -:10454D00A9F0907FAAF05391EF43D820D2E843D839 -:08455D002053A8A043A880220E -:1007A600E4907666F01244AD202613907666E0C398 -:1007B6009402500AE004F0D242124B7F80EA3026BF -:1007C60005122801C22630252B907696E054FCF0BF -:1007D600908003F0121496907696E04403F0908091 -:1007E60003F0E4907667F0907667E004F0E0B44BAF -:0A07F600F61247FA12411B80C522DB -:10280100C220C221C22A907FE8E01237F9283000A5 -:10281100288C0128A2022A1F212A6A22293D802907 -:102821007D8129D1822A84A12ABAA200002ABF90DF -:102831007FE9E014601124FE602824FE603B24FC43 -:102841007040123FE541CB124E1D400241CB907FBB -:10285100EAE0B40104C22241CB907FB4E04401F02C -:1028610041CB124E1F907FEAE0B40104D22241CB4A -:10287100907FB4E04401F041CB907FB4E04401F09B -:1028810041CB907FB4E04401F041CB907FE9E0245B -:10289100F5700512486341CB907FB4E04401F041EB -:1028A100CB907FE9E024FD605424026002213412C0 -:1028B1004E1D400241CB907FEAE07038907FECE002 -:1028C100F45480FFC4540FFFE054072F25E024B4D3 -:1028D100F582E4347FF583E4F0907FECE05480FFEF -:1028E100131313541FFFE054072F907FD7F0E044D8 -:1028F10020F041CB907FB4E04401F041CB124E1F58 -:10290100400241CB907FEAE07020907FECE0F454EC -:1029110080FFC4540FFFE054072F25E024B4F58253 -:10292100E4347FF5837401F041CB907FB4E044013E -:10293100F041CB907FB4E04401F041CB907FE9E0DE -:10294100601224F86009240270291243E741CB1276 -:102951004DCA41CB124E1BA222E433FF25E0FFA258 -:1029610023E4334F907F00F0E4A3F0907FB574022D -:10297100F041CB907FB4E04401F041CB907FE9E09E -:10298100603324F6602A2404703D907FEBE024DE5E -:10299100600C047012907FB4E04401F041CB907F51 -:1029A100B4E04401F041CB907FB4E04401F041CB6D -:1029B10012474541CB124E1BE4907F00F0A3F090EB -:1029C1007FB57402F041CB907FB4E04401F041CB7C -:1029D100907FE9E024F46034240C7039124E1B908E -:1029E1007FECE0F45480FFC4540FFFE054072F251F -:1029F100E024B4F582E4347FF583E054FD907F0058 -:102A0100F0E4A3F0907FB57402F041CB907FB4E085 -:102A11004401F041CB907FB4E04401F041CB907F81 -:102A2100E9E024F6601214601A2402701DD220908D -:102A31007FB4E04401F08012D220907FB4E04401E1 -:102A4100F08007907FB4E04401F0202018907FEEE1 -:102A5100E07004A3E0600BD229D22712174AD22AD0 -:102A61008003120800C2208061907FEEE07004A311 -:102A7100E0600BD229D22812174AD22A804C123890 -:102A8100748047907FE9E024FE601214601A2402EA -:102A9100701DD221907FB4E04401F08012D22190C8 -:102AA1007FB4E04401F08007907FB4E04401F0205E -:102AB1002103121000C2218011122AD6800C124E5D -:102AC100215007907FB4E04401F0202A07907FB4A1 -:052AD100E04402F022C8 -:1043E700124E19400281AC907FEBE024FE601E1450 -:1043F700604614606E147002819D2404600281A5DA -:104407007405907FD4F07400907FD5F022907FEAF6 -:10441700E0FF124A558B208A218922EA496011CE92 -:10442700EACEEE907FD4F0CFE9CFEF907FD5F022A0 -:10443700907FB4E04401F022907FEAE0FF1247B793 -:104447008B208A218922EA496011CEEACEEE907F3D -:10445700D4F0CFE9CFEF907FD5F022907FB4E0443E -:1044670001F022907FEAE0FF907EC0E0FDA3E0FB31 -:104477001217948B208A218922EA496011CEEACE4D -:10448700EE907FD4F0CFE9CFEF907FD5F022907FE9 -:10449700B4E04401F022907FB4E04401F022907F21 -:0544A700B4E04401F047 -:0144AC0022ED -:03003300024DE695 -:094DE600C22553D8EF43D8203256 -:020C9F00C12F63 -:0647FA00124B28C231221F -:10431400E4907696F0908003F0907FE07490F090B3 -:104324007FE17404F0E4907FDDF0907FA1F0538E80 -:10433400F875880575B82075F801438E30F5C87591 -:10434400CA7F75CBF843A820124565C22CC22DC282 -:104354002BC22F907FFC74DDF0907FFF74FFF090F0 -:104364007F97E04401F09076197401F0E49076852B -:10437400F0A3F0907681F0907680F01249AE120F9F -:10438400C6124AF1907F97E04408F0E054B9F0D2A5 -:1043940030203018124AA612300012400012421F78 -:1043A4001248BD121B0412166112421F124AA6C201 -:1043B4002FC231C232C234C233C229C227C228E456 -:1043C400F511907689F090763FF0907641F09076F2 -:1043D40040F090768AF0A3F0A304F0E4A3F0907682 -:0343E40099F0222B -:1048BD00302D39C22D907619E0FFB4010DE49076BC -:1048CD007CF0A374F8F0A3740AF0EFB4020DE49039 -:1048DD00767CF0A374F0F0A3740BF0EFB4030DE449 -:0D48ED0090767CF0A374F8F0A37417F0220D -:101B0400302C38C22C907619E0FFB4010E90767C0C -:101B140074C0F0A37414F0A3740BF0EFB4020DE4DA -:101B240090767CF0A37410F0A3740CF0EFB4030B64 -:0C1B3400E490767CF0A37418F0A3F0227B -:10411B0090768DE064017027302708C227120800C3 -:10412B0012174A302808C22812387412174A302A3C -:10413B000EE490768DF0C22A907FB4E04402F090AA -:10414B00763FE0B40105E4F012326F907641E0B4B3 -:10415B000105E4F012349A907640E0B40103123476 -:10416B009A123000303303124000907F9BE020E422 -:10417B0002C23F907F9BE030E402D23F907F9BE0F6 -:10418B0020E502C23E907F9BE030E502D23EA24189 -:10419B00303F01B3501FA23F9241303F09907697B9 -:1041AB00E054FEF08007907697E04401F09076970C -:1041BB00E0908002F0303F34907619E0FFB4010EAE -:1041CB0090767C7467F0A37406F0A3740BF0EFB4D5 -:1041DB00020BE490767CF0A3F0A3740CF0EFB40325 -:1041EB000BE490767CF0A3F0A37418F0A240303E61 -:1041FB0001B3501FA23E9240303E09907695E044A9 -:10420B0004F08007907695E054FBF0907695E09063 -:04421B008001F0220C -:024E1500D322A6 -:024E1700D322A4 -:024E1900D322A2 -:103FE500907FEAE0907682F0E4907691F090769278 -:0B3FF500F0907690F0907693F0D322CD -:104DCA00907682E0907F00F0907FB57401F0D32254 -:10486300907FECE0907683F0E014601714602114DD -:10487300602B14603224047038907FEAE0907691C4 -:10488300F08035907FEAE0907692F0123E9F802888 -:10489300907FEAE0907690F0121800801B907FEAF8 -:1048A300E0907684F08011907FEAE0907693F08038 -:0A48B30007907FB4E04401F0D32227 -:10474500907FECE0907683F0E014601D14602A14ED -:10475500603714604424047050907691E0907F0097 -:10476500F0907FB57401F08047907692E0907F00DD -:10477500F0907FB57401F08037907690E0907F00DF -:10478500F0907FB57401F08027907684E0907F00EB -:10479500F0907FB57401F08017907693E0907F00DC -:1047A500F0907FB57401F08007907FB4E04401F08C -:0247B500D3220D -:024E1B00D322A0 -:024E1D00D3229E -:024E1F00D3229C -:024E2100C322AA -:102FE700C0E0C083C082D2265391EF907FAB7401BB -:082FF700F0D082D083D0E0325B -:104DB400C0E0C083C0825391EF907FAB7404F0D005 -:064DC40082D083D0E03232 -:103D4700C0E0C0F0C083C082C0D0E8C0E0E9C0E0F6 -:103D5700EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFB1 -:103D6700C0E0907FA2E090767FF0907F74E090763D -:103D770087F0907F75E0907688F0907F98E0440216 -:103D8700F0907696E0FF20E10C4402F0908003F07B -:103D9700D232124B2890767FE020E250907687E06F -:103DA700FEA3E07C002400F534EC3EF533907698D2 -:103DB700E0FDAE33AF341236D8907687EFF0D22FCE -:103DC700303129203F26C231907F94E054CFF090C4 -:103DD7007F9AE030E404D22DC22C907F9AE020E550 -:103DE70004C22DD22C907F94E04430F01248BD12CB -:103DF7001B04302F1212421FC22F75E80112168AB8 -:103E070075E80DD22B800575E801C22B202B349065 -:103E17007619E0FFB4010E90767C7467F0A3740600 -:103E2700F0A3740BF0EFB4020B90767CE4F0A3F0F0 -:103E3700A3740CF0EFB4030B90767CE4F0A3F0A32B -:103E47007418F075CAD375CBFED2CA303404C234A5 -:103E57008002D23430340D907689E0C39403400455 -:103E6700E024FDF05391EF907FAB7402F0F0907F68 -:103E770098E054FDF0D0E0FFD0E0FED0E0FDD0E0C8 -:103E8700FCD0E0FBD0E0FAD0E0F9D0E0F8D0D0D019 -:083E970082D083D0F0D0E032AC -:104BE900C0E0C083C0825391EF907FAB7410F09006 -:104BF9007696E054FDF0908003F0D082D083D0E027 -:014C09003278 -:012FFF00329F -:104C4300C0E0C083C082D2255391EF907FAB74083C -:084C5300F0D082D083D0E032E2 -:104C5B00C0E0C083C0825391EF907FA9E04401F084 -:074C6B00D082D083D0E032BB -:104C0A00C0E0C083C0825391EF907FAAE04401F0D4 -:0F4C1A00C22990768D7401F0D082D083D0E03221 -:104C7200C0E0C083C0825391EF907FA9E04402F06C -:074C8200D082D083D0E032A4 -:104B5A00C0E0C083C0825391EF907FAAE04402F084 -:104B6A00907FC7E0F511750F00750D00D233D08222 -:054B7A00D083D0E03201 -:104C8900C0E0C083C0825391EF907FA9E04404F053 -:074C9900D082D083D0E0328D -:104CA000C0E0C083C0825391EF907FAAE04404F03B -:074CB000D082D083D0E03276 -:104CB700C0E0C083C0825391EF907FA9E04408F021 -:074CC700D082D083D0E0325F -:104CCE00C0E0C083C0825391EF907FAAE04408F009 -:074CDE00D082D083D0E03248 -:104CE500C0E0C083C0825391EF907FA9E04410F0EB -:074CF500D082D083D0E03231 -:104CFC00C0E0C083C0825391EF907FAAE04410F0D3 -:074D0C00D082D083D0E03219 -:104D1300C0E0C083C0825391EF907FA9E04420F0AC -:074D2300D082D083D0E03202 -:104D2A00C0E0C083C0825391EF907FAAE04420F094 -:074D3A00D082D083D0E032EB -:104D4100C0E0C083C0825391EF907FA9E04440F05E -:074D5100D082D083D0E032D4 -:104D5800C0E0C083C0825391EF907FAAE04440F046 -:074D6800D082D083D0E032BD -:104D6F00C0E0C083C0825391EF907FA9E04480F0F0 -:074D7F00D082D083D0E032A6 -:104D8600C0E0C083C0825391EF907FAAE04480F0D8 -:074D9600D082D083D0E0328F -:10421F00907619E064017035907687E0FFD3942D86 -:10422F00402B9076867401F0907685E004F0E0D311 -:10423F00940F4019E4F0EFD394314008907619743D -:10424F0003F080069076197402F0123E9F90761953 -:10425F00E0B4022C907687E0FFC3942F5022EFD367 -:10426F00942A401C9076867401F0907685E004F0D5 -:10427F00E0D3940F400AE4F090761904F0123E9FB9 -:10428F00907619E0B40226907687E0D39431401DE2 -:10429F009076867401F0907685E004F0E0D3940F69 -:1042AF00400BE4F09076197403F0123E9F9076194C -:1042BF00E06403703F907687E0FFC3945F503590C2 -:1042CF0076867401F0907685E004F0E0D3940F4089 -:1042DF0023E4F0EFC3942F500CEFD3942A400690B1 -:1042EF0076197401F0EFD3942F400690761974026B -:1042FF00F0123E9F907686E07005907685F022E46E -:05430F00907686F0220B -:1045650090769A7402F0E4907691F0A3F0907690AC -:10457500F0907693F09076967403F0908003F0E4D3 -:10458500907697F0908002F090769404F0908000F9 -:10459500F0E490768EF090761AF090769504F0C25D -:1045A5002E907F9BE0FF5410FF7002C23F907F9BCF -:1045B500E0FF5410FEFFBE1002D23F907F9BE0FF4C -:1045C5005420FF7002C23E907F9BE0FF5420FEFF07 -:1045D500BE2002D23E303F09907697E054FEF0802F -:1045E50007907697E04401F0907697E0908002F08E -:1045F500303E09907695E04404F08007907695E08A -:1046050054FBF0907695E0908001F0A23E9240A296 -:034615003F924190 -:01461800227F -:103E9F00907692E014601D147002E15424026002C7 -:103EAF00E1E49076947401F0908000F0E490768EC7 -:103EBF00F0D23122907619E0FFB4011BE4907FF22B -:103ECF00F0907FF37430F0907FFF74FCF090769752 -:103EDF00E054FDF054FBF0EFB4021BE4907FF2F0DE -:103EEF00907FF37434F0907FFF74FCF0907697E03E -:103EFF004402F054FBF0EFB40318E4907FF2F0901B -:103F0F007FF37464F0907FFF74FCF0907697E04439 -:103F1F0004F0907694E04401F0908000F0303F0977 -:103F2F00907697E054FEF08007907697E04401F08A -:103F3F00907697E0908002F09076987404F09076E7 -:103F4F008E7401F022907619E0FFB4011BE4907F8C -:103F5F00F2F0907FF37444F0907FFF74FCF0907652 -:103F6F0097E054FDF054FBF0EFB4021BE4907FF2A6 -:103F7F00F0907FF3744CF0907FFF74FCF090769785 -:103F8F00E04402F054FBF0EFB40318E4907FF2F03A -:103F9F00907FF37494F0907FFF74FCF0907697E02D -:103FAF004404F0907694E054FEF0908000F0303F9F -:103FBF0009907697E054FEF08007907697E04401E1 -:103FCF00F0907697E0908002F09076987406F090DB -:063FDF00768E7402F02250 -:10180000907690E014603714700201D814700221B1 -:1018100072147002413B240460026103907FFC74E7 -:10182000CCF0907FFF74FCF0907695E04401F0548A -:1018300005F0908001F0E490761AF0C22E229076A6 -:1018400095E04401F04402F0303E06E04404F080AC -:1018500007907695E054FBF090761AE0B40108907A -:101860007695E0908001F0907619E0FFB401229027 -:101870007FFC7474F0907FFF74FCF090768F742B73 -:10188000F0907697E054FDF0E4907681F0907680C9 -:10189000F0EFB40222907FFC7468F0907FFF74FC3C -:1018A000F090768F742FF0907697E04402F0E490F9 -:1018B0007681F0907680F0303F09907697E054FE84 -:1018C000F08007907697E04401F0907697E054FB23 -:1018D000F0908002F0D22E22907695E054FEF044F3 -:1018E00002F0303E06E04404F08007907695E05424 -:1018F000FBF090761AE0B40108907695E0908001B4 -:10190000F0907619E0FFB40122907FFC7430F090E3 -:101910007FFF74FCF090768F742BF0907697E054F4 -:10192000FDF0E4907681F0907680F0EFB4022290A2 -:101930007FFC741CF0907FFF74FCF090768F742F06 -:10194000F0907697E04402F0E4907681F090768013 -:10195000F0303F09907697E054FEF080079076973C -:10196000E04401F0907697E054FBF0908002F0D2D2 -:101970002E22907695E04401F04402F04408F030C5 -:101980003E06E04404F08007907695E054FBF0902A -:10199000761AE0B40108907695E0908001F0907698 -:1019A00019E0FFB40125907FFC74CCF0907FFF74A8 -:1019B000FCF090768F742BF0907697E054FDF05405 -:1019C000FBF0E4907681F0907680F0EFB402259001 -:1019D0007FFC74C8F0907FFF74FCF090768F742FBA -:1019E000F0907697E04402F054FBF0E4907681F0BA -:1019F000907680F0EFB40325907FFC7498F0907F90 -:101A0000FF74FCF090768F745FF0907697E054FD51 -:101A1000F04404F0E4907681F0907680F0303F0955 -:101A2000907697E054FEF08007907697E04401F0BE -:101A3000907697E0908002F0D22E22907695E05436 -:101A4000FEF04402F04408F0303E06E04404F0802A -:101A500007907695E054FBF090761AE0B401089078 -:101A60007695E0908001F0907619E0FFB401259022 -:101A70007FFC74B4F0907FFF74FCF090768F742B31 -:101A8000F0907697E054FDF054FBF0E4907681F00E -:101A9000907680F0EFB40225907FFC74B0F0907FD8 -:101AA000FF74FCF090768F742FF0907697E04402EC -:101AB000F054FBF0E4907681F0907680F0EFB40380 -:101AC00025907FFC7468F0907FFF74FCF090768F17 -:101AD000745FF0907697E054FDF04404F0E4907663 -:101AE00081F0907680F0303F09907697E054FEF0D8 -:101AF0008007907697E04401F0907697E09080021E -:041B0000F0D22E22CF -:040CA1004176230075 -:102DA900E4907636F0E0FF75F003A4240EF582E492 -:102DB9003475F5837401F0EF75F003A4240FF582DF -:102DC900E43475F5837401F0EF75F003A42410F56C -:102DD90082E43475F583E4F0907636E004F0E0FFA0 -:102DE90075F003A4240EF582E43475F5837410F0AC -:102DF900EF75F003A4240FF582E43475F5837405A7 -:102E0900F0EF75F003A42410F582E43475F583E43A -:102E1900F0907636E004F0E0FF75F003A4240EF597 -:102E290082E43475F5837402F0EF75F003A4240F7E -:102E3900F582E43475F5837402F0EF75F003A42488 -:102E490010F582E43475F583E4F0907636E004F009 -:102E5900E0FF75F003A4240EF582E43475F583745C -:102E690001F0EF75F003A4240FF582E43475F583BE -:102E79007403F0EF75F003A42410F582E43475F5BA -:102E890083E4F0907636E004F0E0FF75F003A424C3 -:102E99000EF582E43475F5837410F0EF75F003A430 -:102EA900240FF582E43475F5837406F0EF75F003A9 -:102EB900A42410F582E43475F583E4F0907636E0C5 -:102EC90004F0E0FF75F003A4240EF582E43475F5EF -:102ED900837402F0EF75F003A4240FF582E43475CE -:102EE900F5837404F0EF75F003A42410F582E4343B -:102EF90075F583E4F0907636E004F0E0FF75F003B1 -:102F0900A4240EF582E43475F5837402F0EF75F0AC -:102F190003A4240FF582E43475F5837408F0EF7582 -:102F2900F003A42410F582E43475F5837404F09059 -:102F39007636E004F0E0FF75F003A4240EF582E490 -:102F49003475F5837402F0EF75F003A4240FF5824C -:102F5900E43475F583740AF0EF75F003A42410F5D1 -:102F690082E43475F5837404F0907636E004F0E079 -:102F7900FF75F003A4240EF582E43475F583740219 -:102F8900F0EF75F003A4240FF582E43475F583742A -:102F990009F0EF75F003A42410F582E43475F58384 -:102FA9007404F0907636E004F0E0FF75F003A42491 -:102FB9000EF582E43475F5837402F0EF75F003A41D -:102FC900240FF582E43475F5837407F0EF75F00387 -:0E2FD900A42410F582E43475F5837404F0220C -:103BD300E4907636F0E0FB75F00FA42441F582E41F -:103BE3003475F5837440F0EB75F00FA42442F5822D -:103BF300E43475F583740AF0EB75F00FA42443F5F0 -:103C030082E43475F5831237C80000AC44EB75F0D9 -:103C13000FA42447F582E43475F5831237C80000F6 -:103C2300AC44EB75F00FA4244BF582E43475F583B3 -:103C33001237C800017700907636E004F0E0FB7598 -:103C4300F00FA42441F582E43475F5837440F0EB5E -:103C530075F00FA42442F582E43475F583748CF077 -:103C6300EB75F00FA42443F582E43475F583123722 -:103C7300C80000AC44EB75F00FA42447F582E4348C -:103C830075F5831237C80000AC44EB75F00FA4241C -:103C93004BF582E43475F5831237C8000177009041 -:103CA3007636E004F0E0FF75F00FA42441F582E4DA -:103CB3003475F5837440F0EF75F00FA42442F58258 -:103CC300E43475F583748FF0907636E004F0E0FF0A -:103CD30075F00FA42441F582E43475F5837441F043 -:103CE300EF75F00FA42442F582E43475F5837484F0 -:103CF300F0907636E004F0E0FF75F00FA42441F570 -:103D030082E43475F5837461F0EF75F00FA42442F7 -:103D1300F582E43475F5837481F0907636E004F02F -:103D2300E0FF75F00FA42441F582E43475F5837444 -:103D330061F0EF75F00FA42442F582E43475F58346 -:043D43007401F022F5 -:10461900E4907636F0E0FF75F003A42432F582E4E5 -:104629003475F583E4F0EF75F003A42433F582E4DF -:104639003475F5837401F0907636E004F0E0FF7587 -:10464900F003A42432F582E43475F583E4F0EF75C0 -:10465900F003A42433F582E43475F5837402F090F1 -:104669007636E004F0E0FF75F003A42432F582E425 -:104679003475F583E4F0EF75F003A42433F582E48F -:104689003475F5837403F0907636E004F0E0FF7535 -:10469900F003A42432F582E43475F583E4F0EF7570 -:1046A900F003A42433F582E43475F5837404F0220D -:103A4200E4907635F0907635E0FFC394034002416E -:103A5200FFEF75F00AA424AAF582E43475F583EF2A -:103A6200F0EF75F00AA424ABF582E43475F583E433 -:103A7200F0EF75F00AA424ACF582E43475F5837492 -:103A8200F0F0EF75F00AA424ADF582E43475F58305 -:103A920074FFF0EF75F00AA424AEF582E43475F5F4 -:103AA20083E4F0EF75F00AA424AFF582E43475F5EF -:103AB200837480F0EF75F00AA424B0F582E43475C3 -:103AC200F583E4F0EF75F00AA424B1F582E43475CD -:103AD200F583E4F0EF75F00AA424B2F582E43475BC -:103AE200F583E4F0EF75F00AA424B3F582E43475AB -:103AF200F5837401F0907635E004F0414790763C0E -:103B0200740AF0E4A3F09076357403F090763CE00A -:103B1200FF907635E0FEC39F400261D290763DE091 -:103B2200FF04F0EE75F00AA424AAF582E43475F5D8 -:103B320083EFF0EE75F00AA424ABF582E43475F558 -:103B420083E4F0EE75F00AA424ACF582E43475F552 -:103B520083745EF0EE75F00AA424ADF582E4347548 -:103B6200F58374BAF0EE75F00AA424AEF582E4345B -:103B720075F5837405F0EE75F00AA424AFF582E4BE -:103B82003475F5837480F0EE75F00AA424B0F582E2 -:103B9200E43475F583E4F0EE75F00AA424B1F582FD -:103BA200E43475F583E4F0EE75F00AA424B2F582EC -:103BB200E43475F5837415F0EE75F00AA424B3F5B8 -:103BC20082E43475F583E4F0907635E004F0610E1A -:013BD20022D0 -:10080000E4907631F0907631E0FF75F003A4240F88 -:10081000F582E43475F583E0FE907FEDE0FDEE6D4A -:10082000600EEFC3940B5008907631E004F080D551 -:10083000EFB40B08907FB4E04401F022EF75F003B1 -:10084000A4240EF582E43475F583E0907633F02429 -:10085000F0600A240E60028187124BC722907FED60 -:10086000E0640570519076187405F0907637740145 -:10087000F09076397403F0907621F0E4907620F0D1 -:10088000907FEAE0F4602F907620E0FF75F00AA4F4 -:1008900024AAF582E43475F583E0FE907FEAE0FD5A -:1008A000EE6D6012907621E0FEEFC39E50089076C8 -:1008B00020E004F080D1907FEDE0640670529076E5 -:1008C000187406F09076377404F0907639740AF054 -:1008D000907621F09076207403F0907FEAE0F46047 -:1008E0002F907620E0FF75F00AA424AAF582E43464 -:1008F00075F583E0FE907FEAE0FDEE6D6012907684 -:1009000021E0FEEFC39E5008907620E004F080D1F5 -:10091000907620E0FF75F00AA424AAF582E43475ED -:10092000F583E0907229F0E490763BF0907621E038 -:10093000FEEF6E7008907FB4E04401F022907FEBF0 -:10094000E014601314700221E224026002817F909F -:100950007FB4E04401F022907FE9E014707C907F46 -:10096000EAE0F47048907637E0907620F09076399F -:10097000E0FE907620E0FDC39E502B90763BE0FE9B -:1009800004F074C02EF582E4347EF583E0FEED754C -:10099000F00AA424ABF582E43475F583EEF090768A -:1009A00020E004F080C790763F7401F022907EC072 -:1009B000E0FEEF75F00AA424ABF582E43475F5830C -:1009C000EEF0E0B4010890763E7401F08005E4900A -:1009D000763EF090763F7401F022907FB4E04401BF -:1009E000F022907FE9E024FE700241A314700261BE -:1009F0003F14700261DB240360028177907FEAE09C -:100A0000F4706B907637E0907620F0907639E0FFC6 -:100A1000907620E0FEC39F504E90763BE0FF04F0BE -:100A200074C02FF582E4347EF583E0FFEE75F00AA2 -:100A3000A424ACF582E43475F583EFF090763BE0C6 -:100A4000FF04F074C02FF582E4347EF583E0FFEEFE -:100A500075F00AA424ADF582E43475F583EFF090C7 -:100A60007620E004F080A49076407401F022907E1D -:100A7000C0E0FF907620E0FE75F00AA424ACF58279 -:100A8000E43475F583EFF0907EC1E0FFEE75F00A77 -:100A9000A424ADF582E43475F583EFF090764174CB -:100AA00001F022907FEAE0F47066907637E090766D -:100AB00020F0907639E0FF907620E0FEC39F400260 -:100AC000818E90763BE0FF04F074C02FF582E43411 -:100AD0007EF583E0FFEE75F00AA424AEF582E434DF -:100AE00075F583EFF090763BE0FF04F074C02FF5CE -:100AF00082E4347EF583E0FFEE75F00AA424AFF5BE -:100B000082E43475F583EFF0907620E004F080A263 -:100B1000907EC0E0FF907620E0FE75F00AA424AE3F -:100B2000F582E43475F583EFF0907EC1E0FFEE7559 -:100B3000F00AA424AFF582E43475F583EFF0229037 -:100B40007FEAE0F47066907637E0907620F0907659 -:100B500039E0FF907620E0FEC39F4002818E9076C0 -:100B60003BE0FF04F074C02FF582E4347EF583E0AF -:100B7000FFEE75F00AA424B0F582E43475F583EF36 -:100B8000F090763BE0FF04F074C02FF582E4347EF1 -:100B9000F583E0FFEE75F00AA424B1F582E4347524 -:100BA000F583EFF0907620E004F080A2907EC0E024 -:100BB000FF907620E0FE75F00AA424B0F582E434BC -:100BC00075F583EFF0907EC1E0FFEE75F00AA42486 -:100BD000B1F582E43475F583EFF022907FEAE0F41A -:100BE0007066907637E0907620F0907639E0FF904E -:100BF0007620E0FEC39F4002818E90763BE0FF04AA -:100C0000F074C02FF582E4347EF583E0FFEE75F0DA -:100C10000AA424B2F582E43475F583EFF090763BB4 -:100C2000E0FF04F074C02FF582E4347EF583E0FF2A -:100C3000EE75F00AA424B3F582E43475F583EFF081 -:100C4000907620E004F080A2907EC0E0FF907620B5 -:100C5000E0FE75F00AA424B2F582E43475F583EF62 -:100C6000F0907EC1E0FFEE75F00AA424B3F582E4B3 -:100C70003475F583EFF022907FB4E04401F02290C8 -:0F0C80007FB4E04401F022907FB4E04401F02201 -:10100000E490762CF090762CE0FF75F003A4240F8A -:10101000F582E43475F583E0FE907FEDE0FDEE6D42 -:10102000600EEFC3940B500890762CE004F080D54E -:10103000EFB40B08907FB4E04401F022EF75F003A9 -:10104000A4240EF582E43475F583E090762EF02426 -:10105000F0600A240F6002817D124BA422907FED84 -:10106000E0640570519076187405F090763874013C -:10107000F090763A7403F090761CF0E490761BF0D2 -:10108000907FEAE0F4602F90761BE0FF75F00AA4F1 -:1010900024AAF582E43475F583E0FE907FEAE0FD52 -:1010A000EE6D601290761CE0FEEFC39E50089076C5 -:1010B0001BE004F080D1907FEDE0640670529076E2 -:1010C000187406F09076387404F090763A740AF04A -:1010D00090761CF090761B7403F0907FEAE0F46049 -:1010E0002F90761BE0FF75F00AA424AAF582E43461 -:1010F00075F583E0FE907FEAE0FDEE6D601290767C -:101100001CE0FEEFC39E500890761BE004F080D1F7 -:10111000E490761EF090761CE0FF90761BE0FE6F68 -:101120007008907FB4E04401F022907FEBE01460FF -:101130001314700221BF240260028175907FB4E015 -:101140004401F022907FE9E0247F706B907FEAE019 -:10115000F4704A907638E090761BF090763AE0FF93 -:1011600090761BE0FDC39F502BED75F00AA424ABD5 -:10117000F582E43475F583E0FF90761EE0FD04F01F -:1011800074002DF582E4347FF583EFF090761BE058 -:1011900004F080C790761EE0907FB5F022EE75F0E7 -:1011A0000AA424ABF582E43475F583E0907F00F067 -:1011B000907FB57401F022907FB4E04401F022905A -:1011C0007FE9E0247E7002417E1470026123147076 -:1011D0000261C824036002816D907FEAE0F4706DC3 -:1011E000907638E090761BF090763AE0FF90761B90 -:1011F000E0C39F504FE0FF75F00AA424ACF582E4F1 -:101200003475F583E0FE90761EE0FD04F074002D49 -:10121000F582E4347FF583EEF0EF75F00AA424AD97 -:10122000F582E43475F583E0FF90761EE0FE04F06D -:1012300074002EF582E4347FF583EFF090761BE0A6 -:1012400004F080A490761EE0907FB5F02290761B8B -:10125000E0FF75F00AA424ACF582E43475F583E070 -:10126000907F00F0EF75F00AA424ADF582E43475A8 -:10127000F583E0907F01F0907FB57402F022907FBB -:10128000EAE0F4706D907638E090761BF090763A54 -:10129000E0FF90761BE0C39F504FE0FF75F00AA47B -:1012A00024AEF582E43475F583E0FE90761EE0FD11 -:1012B00004F074002DF582E4347FF583EEF0EF75D1 -:1012C000F00AA424AFF582E43475F583E0FF90764C -:1012D0001EE0FE04F074002EF582E4347FF583EF07 -:1012E000F090761BE004F080A490761EE0907FB52D -:1012F000F02290761BE0FF75F00AA424AEF582E49C -:101300003475F583E0907F00F0EF75F00AA424AF08 -:10131000F582E43475F583E0907F01F0907FB57439 -:1013200002F022907FEAE0F4706D907638E09076DB -:101330001BF090763AE0FF90761BE0C39F504FE0A1 -:10134000FF75F00AA424B0F582E43475F583E0FE5D -:1013500090761EE0FD04F074002DF582E4347FF5F4 -:1013600083EEF0EF75F00AA424B1F582E43475F54C -:1013700083E0FF90761EE0FE04F074002EF582E418 -:10138000347FF583EFF090761BE004F080A4907634 -:101390001EE0907FB5F02290761BE0FF75F00AA466 -:1013A00024B0F582E43475F583E0907F00F0EF75AA -:1013B000F00AA424B1F582E43475F583E0907F014E -:1013C000F0907FB57402F022907FEAE0F4706D90A7 -:1013D0007638E090761BF090763AE0FF90761BE04E -:1013E000C39F504FE0FF75F00AA424B2F582E434A5 -:1013F00075F583E0FE90761EE0FD04F074002DF597 -:1014000082E4347FF583EEF0EF75F00AA424B3F59F -:1014100082E43475F583E0FF90761EE0FE04F074FC -:10142000002EF582E4347FF583EFF090761BE00424 -:10143000F080A490761EE0907FB5F02290761BE0BD -:10144000FF75F00AA424B2F582E43475F583E090C8 -:101450007F00F0EF75F00AA424B3F582E43475F54B -:1014600083E0907F01F0907FB57402F022907FB40A -:10147000E04401F022907FB4E04401F022907FB478 -:05148000E04401F02230 -:10387400E4907629F0907629E0FF75F00FA42442B5 -:10388400F582E43475F583E0FE907FECE0FDEE6DA7 -:10389400600EEFC394065008907629E004F080D5BA -:1038A400EFB40608907FB4E04401F022EF75F00F06 -:1038B400A42441F582E43475F583E090762AF0245B -:1038C400BF7002414124E070024112242160024190 -:1038D4003A907FE9E024FE607D14700221B2240254 -:1038E4006002410A121751907642E0FCA3E0FDA366 -:1038F400E0FEA3E0FF907629E075F00FA42443F5E1 -:1039040082E43475F5831237BC907619E0FFB40174 -:103914001290767C7467F090767D7406F090767ED3 -:10392400740BF0EFB4020FE490767CF090767DF0A7 -:1039340090767E740CF0EFB4030FE490767CF090F4 -:10394400767DF090767E7418F090761A7401F012F9 -:103954003E9F12180022907EC2E0FFE4FCFDFEFBB5 -:10396400FA7901F8123746C8ECC8C9EDC9CAEECADB -:10397400CBEFCB907EC1E0FEE4FCFD2BFBEA3EFAEC -:10398400ED39F9EC38F8907EC0E0FFE4FEEB2FFF50 -:10399400EE3AFEED39FDEC38FC907629E075F00F37 -:1039A400A42447F582E43475F5831237BC22907E53 -:1039B400C2E0FFE4FCFDFEFBFA7901F8123746C8C9 -:1039C400ECC8C9EDC9CAEECACBEFCB907EC1E0FE0C -:1039D400E4FCFD2BFBEA3EFAED39F9EC38F8907E75 -:1039E400C0E0FFE4FEEB2FFFEE3AFEED39FDEC38CC -:1039F400FC907629E075F00FA4244BF582E434752D -:103A0400F5831237BC22907FB4E04401F022907F0A -:103A1400E9E0147019907EC0E0FF907629E075F01B -:103A24000FA4244FF582E43475F583EFF022907FE0 -:0E3A3400B4E04401F022907FB4E04401F0229F -:102AD600E4907627F0907627E0FF75F00FA4244265 -:102AE600F582E43475F583E0FE907FECE0FDEE6D53 -:102AF600600EEFC394065008907627E004F080D568 -:102B0600EFB40608907FB4E04401F022EF75F00FB1 -:102B1600A42441F582E43475F583E0907628F02408 -:102B26009F7002A17424216002A1A1907FE9E02494 -:102B36007E700261FC14700281B524026002A16CF1 -:102B4600EF75F00FA42443F582E43475F583E0FCB9 -:102B5600A3E0FDA3E0FEA3E0FF7B447AAC79007816 -:102B660000C31237AB7013907F007444F0A374ACAB -:102B7600F0E4A3F0907FB57403F0907627E075F04B -:102B86000FA42443F582E43475F583E0FCA3E0FD4D -:102B9600A3E0FEA3E0FF7B807ABB79007800C31236 -:102BA60037AB7013907F007480F0A374BBF0E4A37E -:102BB600F0907FB57403F0907627E075F00FA424AB -:102BC60043F582E43475F583E0FCA3E0FDA3E0FE63 -:102BD600A3E0FF7B007A7779017800C31237AB60F8 -:102BE60002A1A8907F00F0A37477F0A37401F0907F -:102BF6007FB57403F022907627E075F00FA4244782 -:102C0600F582E43475F583E0FCA3E0FDA3E0FEA3C2 -:102C1600E0FF7B447AAC79007800C31237AB7013BF -:102C2600907F007444F0A374ACF0E4A3F0907FB5F9 -:102C36007403F0907627E075F00FA42447F582E43C -:102C46003475F583E0FCA3E0FDA3E0FEA3E0FF7B83 -:102C5600807ABB79007800C31237AB7013907F007F -:102C66007480F0A374BBF0E4A3F0907FB57403F016 -:102C7600907627E075F00FA42447F582E43475F5C5 -:102C860083E0FCA3E0FDA3E0FEA3E0FF7B007A77F0 -:102C960079017800C31237AB6002A1A8907F00F0DB -:102CA600A37477F0A37401F0907FB57403F02290BB -:102CB6007627E075F00FA4244BF582E43475F5838E -:102CC600E0FCA3E0FDA3E0FEA3E0FF7B447AAC7941 -:102CD600007800C31237AB7013907F007444F0A3E2 -:102CE60074ACF0E4A3F0907FB57403F0907627E01F -:102CF60075F00FA4244BF582E43475F583E0FCA34C -:102D0600E0FDA3E0FEA3E0FF7B807ABB79007800BC -:102D1600C31237AB7013907F007480F0A374BBF0BE -:102D2600E4A3F0907FB57403F0907627E075F00F7A -:102D3600A4244BF582E43475F583E0FCA3E0FDA3FF -:102D4600E0FEA3E0FF7B007A7779017800C31237B3 -:102D5600AB704F907F00F0A37477F0A37401F090EE -:102D66007FB57403F022907FB4E04401F022907F97 -:102D7600E9E0247F701E907627E075F00FA4244FBB -:102D8600F582E43475F583E0907F00F0907FB574AA -:102D960001F08007907FB4E04401F0907FB4E044F6 -:032DA60001F02217 -:104BA400907FEBE0147014907FE9E0247F7004128E -:104BB400495822907FB4E04401F022907FB4E0444D -:034BC40001F022DB -:104BC700907FEBE0147013907FE9E0147004124AB1 -:104BD7000322907FB4E04401F022907FB4E04401C7 -:024BE700F022BA -:10495800E4907626F0907626E0FF75F003A42434E0 -:10496800F582E43475F583E0FE907FECE0FDEE6DB2 -:10497800600EEFC394045008907626E004F080D5CA -:10498800EFB40408907FB4E04401F022EF75F0031F -:10499800A42432F582E43475F583E0907F00F0902A -:0649A8007FB57401F0224E -:104A0300E4907625F0907625E0FF75F003A4243436 -:104A1300F582E43475F583E0FE907FECE0FDEE6D06 -:104A2300600EEFC394045008907625E004F080D51F -:104A3300EFB40408907FB4E04401F022907EC0E01C -:104A4300FEEF75F003A42432F582E43475F583EEAA -:024A5300F0224F -:03000300020FFDEC -:030FFD00C2893274 -:030013000217FDD4 -:0317FD00C28B326A -:03004B00024E035F -:044E03005391DF32B6 -:030053000248FA66 -:0648FA005391BFD22D32E4 -:03005B00024DFD56 -:064DFD0053917FD22C321D -:03006300024E0743 -:044E070053D8F73253 -:03000B00024E0F93 -:034E0F00C28D321F -:03001B00024E1280 -:034E1200C28F321A -:03002300024DEF9C -:074DEF005398FE5398FD32BA -:03003B00024DF67D -:074DF60053C0FE53C0FD3263 -:03002B0002480088 -:10480000C0E0C0F0C083C082C0D0E8C0E0E9C0E032 -:10481000EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFED -:10482000C0E0C2CAC2CF907F98E04401F0302E03AE -:104830001214A6907F98E054FEF053A8FA12166165 -:10484000D0E0FFD0E0FED0E0FDD0E0FCD0E0FBD037 -:10485000E0FAD0E0F9D0E0F8D0D0D082D083D0F028 -:03486000D0E03273 -:104AA600E490769BF090769BE0FF04F0EF6008E0E0 -:104AB6002408F8E4F680EE907696E04404F0440884 -:104AC600F0908003F0E4F518D235F50EF510D236E5 -:104AD600751211751322C237C239C238F516F5148C -:0B4AE600F51AF50DC23BC23CC23D2298 -:10300000907FB6E020E102C23DD236203602416E0A -:10301000303D02416E908007E06004D2368002C2EB -:1030200036203602412ED235E4F51A908004E0F5C0 -:10303000197408250EF8A619851918E51820E70453 -:10304000D2388002C23830380221D4E4F516E519AE -:10305000B4F00CD2397508047509F0050E8002052C -:1030600016E51964F7703DC239E50E24FE601714A9 -:103070006022240370297508057509F7E4F50AF53F -:103080000B750E048020750806750AF7E4F50B75BC -:103090000E048012750807750BF7750E0480071271 -:1030A0004DDA80020516E51954F864F8703BC23514 -:1030B000E5192407600C24FC6008240524F8500658 -:1030C0008008D23A8006C23A8002D23A751A0120AC -:1030D0003A19907E80740FF0A3E519F0E4A3F0A3F1 -:1030E000F0907FB77404F08002051620396DE51961 -:1030F00064F76067E51A7063E51854F064F070597E -:10310000851819F50EE519240F601B24FE6017249D -:10311000FD602214601F2405702F750803050E85BD -:103120001809D2378028750802050E85180975140C -:1031300001D2378019750805050E851809E4F50ACE -:10314000F50B750E03D2378005124DDAC2353035D6 -:103150000A85081385181280020516851819E516C8 -:1031600064047062F50EE51954F0F519F51585182B -:1031700019E5152470601824F0601424F060102400 -:10318000F0601E24F0601A24F0600424607027E5CB -:1031900015C4540FF519F508050E851809D23780A6 -:1031A0001AE515C4540FF519F508050E85180975AB -:1031B0001401D2378005124DDAC23530350A85192F -:1031C0001385181280020516E516D3940540571290 -:1031D0004DDA8052303917E50E700A8508097508F6 -:1031E00004050E80417408250EF8A6198038203792 -:1031F0002AE50EB4010F85080A85090B8513088599 -:103200001209750E04E514B4011C85080AE4F50BD7 -:10321000851308851209750E04800BE514B40106A8 -:10322000E4F50B750E04E4F51A303502050EE50ED3 -:10323000D394035002010BC237E4F50EF510C236E9 -:10324000D23DF51474082510F8E6FF74802510F5BA -:1032500082E4347EF583EFF074082510F8E4F60577 -:0F32600010E510B404DE907FB77404F0010B2268 -:0C4DDA00C237E4F50EF510C236F51422C5 -:10400000E511D3940050022106907689E0C394080C -:10401000400221067440250FF582E4347EF583E0EA -:10402000F517E50D600E908005E517F0907689E0B4 -:1040300004F001DAE5171237F940C1024067054084 -:104040007A0640980740C10C40C10D40C70F40CBD5 -:10405000F640CBF840CBFA40CBFB40CBFC40CBFE4C -:1040600040CBFF000040DA907E41E0908005F09068 -:104070007689E004F07511018060907E41E09080C7 -:1040800005F0907E42E0908005F0907689E004F0A3 -:10409000E004F07511018042907E41E0908005F0CF -:1040A000907E42E0908005F0907E43E0908005F0A5 -:1040B000907689E004F0E004F0E004F075110180EE -:1040C00019D23BD23C8013D23B800F908005E5177C -:1040D000F0907689E004F0751101203B04050D8015 -:1040E0001F303C1C907E41E0908005F0907E42E0C5 -:1040F000908005F0907689E004F0E004F0751101FD -:10410000050F15110100E5117010C233F50DF50F03 -:0B411000907FC77404F0C23BC23C2249 -:104C2900907FD6E030E712E04401F07F147E001255 -:0A4C39004D9D907FD6E054FEF0225E -:104B7F00907FD6E054FBF0E04408F0304204E0446C -:104B8F0002F07FDC7E05124D9D907FD6E054F7F04A -:054B9F00E04404F022D7 -:104D9D008E358F36E5361536AE35700215354E60CB -:074DAD000512148580EE22BF -:104A5500E4FE751DFF751E05751F12AB1DAA1EA967 -:104A65001F9000011236AB6402702FCDEECD0EED16 -:104A75006F70012290000212370E85F01BF51C6243 -:104A85001BE51B621CE51C621B29FDE51B3AC9EDF4 -:104A9500C9751DFFF51E891F80C17B007A0079004D -:014AA50022EE -:041794008D298B2AE6 -:10179800124A55EA4960571236927E0029FFEE3AFE -:1017A800C9EFC9752BFFF52C892DAB2BAA2CA92DB8 -:1017B8009000011236ABFF64046005EF6405702EDB -:1017C800EFB404159000021236AB6529700B900037 -:1017D800031236AB652A7001221236927E0029FF69 -:1017E800EE3AC9EFC9752BFFF52C892D80BC7B001B -:0417F8007A007900FA -:0117FC0022CA -:0247B7008F2E43 -:1047B900E4F52F7530FF75310775321AAB30AA3120 -:1047C900A9329000011236ABB4031FAF2F052FEFAA -:1047D900652E7001221236927E0029FFEE3AC9EF4A -:1047E900C97530FFF531893280D27B007A007900B2 -:0147F900229D -:1005000012011001000000406A08110100010102FF -:100510000001090208020501008032090400000000 -:10052000010100000A2401000156000201020C240E -:10053000020101010002000000000D240605010275 -:10054000030000000000000924030204030005006A -:100550000C24020305020006000000001524060614 -:100560000302000003000300030003000300030074 -:100570000009240304010100060009040100000130 -:100580000200000904010102010200000724010128 -:10059000000100112402010202100344AC0080BBE0 -:1005A0000000770109050A05840101008F07250174 -:1005B0000100000009058F01030001050009040185 -:1005C00002020102000007240101000100112402BF -:1005D000010203180344AC0080BB00007701090549 -:1005E0000A05460201008F072501010000000905E8 -:1005F0008F01030001050009040200000102000050 -:1006000009040201010102000007240104000100A5 -:100610000E2402010602100244AC0080BB00090552 -:100620008C054C02010000072501000200000904AE -:1006300002020101020000072401040001000E244F -:1006400002010603180244AC0080BB0009058C05BA -:1006500072030100000725010002000009040203E3 -:10066000010102000007240104000100112402011D -:100670000202100344AC0080BB0000770109058C26 -:1006800005840101000007250100020000090402A1 -:1006900004010102000007240104000100112402EA -:1006A000010203180344AC0080BB00007701090578 -:1006B0008C05460201000007250100020000090424 -:1006C00003000001010000092401000109000104E8 -:1006D00009040400020103000007240100012400B2 -:1006E000062402010700092403020801070100068D -:1006F0002402020900092403010A01090100090575 -:10070000010204000000000525010107090581021E -:100710000400000000052501010A04030904180370 -:1007200045006D006100670069006300200047001C -:100730006D0062004800220345006D006100670003 -:1007400069006300200045004D004900200036008C -:100750007C00320020006D002A0343006F006E0011 -:10076000660069006700750072006100740069002E -:100770006F006E00200053007400720069006E006C -:100780006700220349006E00740065007200660075 -:10079000610063006500200053007400720069006E -:0607A0006E00670000007E -:101485007400F58690FDA57C05A3E582458370F97A -:011495002234 -:10149600907FD6E04480F0438701000000000022E0 -:1014A600C0D0C0E08FE0C0E08EE0C0E08DE0C0E0DC -:1014B6008CE0C0E0C082C0830586C084C0857D0004 -:1014C600907FE3747BF0A37480F07C11907F99E0A9 -:1014D6005440DC030214F3B40013907FE27440F02E -:1014E600907FE5F0907FE27400F00214D29076903F -:1014F600E0B4011290768FE02DFD907FE27480F0CB -:10150600907F6C021557B4021290768FE02DFD90F5 -:101516007FE27480F0907F6C021596B40312907689 -:101526008FE02DFD907FE27480F0907F6C0215E1D4 -:10153600B4041290768FE02DFD907FE27480F090D7 -:101546007F6C021610907FE27480F0907F6C02161A -:1015560040F0F0F0F0F0F0F0F0F0F0F0F0DDF27DB9 -:10156600020586907FE27400F0907F9BE05404B4FD -:1015760000050586021640907FE27480F00586F02D -:10158600F0F0F0F0F0F0F0F0F0F0F0DDD4021640FC -:10159600F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F045 -:1015A600F0F0DDEC7D020586907FE27400F0907F1E -:1015B6009BE05404B400050586021640907FE27451 -:1015C60080F00586F0F0F0F0F0F0F0F0F0F0F0F0DA -:0615D600F0F0F0F0F0F06F -:1015DC00DDCE021640F0F0F0F0DDFA7D02058690CB -:1015EC007FE27400F0907F9BE05404B40005058604 -:1015FC00021640907FE27480F00586F0F0F0F0DD8A -:10160C00DC021640F0F0F0F0F0F0DDF87D0205861B -:10161C00907FE27400F0907F9BE05404B4000505C9 -:10162C0086021640907FE27480F00586F0F0F0F0B0 -:10163C00F0F0DDDA907FE27400F0D085D08405867E -:10164C00D083D082D0E0FCD0E0FDD0E0FED0E0FF33 -:05165C00D0E0D0D02217 -:10166100C0D0C0E0C082C08390767CE0907F6FF0F4 -:1016710090767DE0907F6FF090767EE0907F6FF0C6 -:09168100D083D082D0E0D0D02249 -:10168A00C0D0C0E08FE0C0E08EE0C0E0C082C0837E -:10169A000586C084C085907687E0FFBF00030217E5 -:1016AA0001907F96E04480F0907FE27480F0907F12 -:1016BA0062E00586907FE27400F0907F96E0547FA6 -:1016CA00F0907FE27480F090768EE0B40105058692 -:1016DA000216F6B4020505860216EB05860216FB0B -:1016EA00E0E0E0E0E0E0DFF80216FBE0E0E0E0DF67 -:1016FA00FA907FE27400F0D085D0840586D083D03A -:0C170A0082D0E0FED0E0FFD0E0D0D02282 -:10171600C082C083C0E0E8C0E078D1E814F870FB6E -:0A172600D0E0F8D0E0D083D082229A -:100CA500417201014572050002C9000045720A0042 -:100CB500010203044D720FD100D1000000000000B5 -:100CC500282809004D721C010001020304050607CE -:100CD50008090A0B41722E2241722F2341723020DE -:100CE5004172312162D2723A00000000000000001A -:100CF50000000000000000000000000000000000EF -:100D050000000000000000000000000000000000DE -:100D150000000000000000000000000000000000CE -:100D250000000000000000000000000000000000BE -:100D350000000000000000000000000000000000AE -:100D4500000000000000000000000000000000009E -:100D5500000000000000000000000000000000008E -:100D6500000000000000000000000000000000007E -:100D75000000000000000000000001010101010168 -:100D8500010101010101010101010101010101014E -:100D9500010101010101010101010101010101013E -:100DA500010101010101010101010101010101012E -:100DB5000101010101010101020202020202020216 -:100DC50002020202020202020202020202020202FE -:100DD50002020202020202020202020202020202EE -:100DE50002020202020202020202020202020202DE -:100DF50002020202020303030303030303030303C3 -:100E050003030303030303030303030303030303AD -:100E1500030303030303030303030303030303039D -:100E2500030303030303030303030303030303038D -:100E3500030304040404040404040404040404046F -:100E4500040404040404040404040404040404045D -:100E5500040404040404040404040404040404044D -:100E6500040404040404040404040404040404043D -:100E7500050505050505050505050505050505051D -:100E8500050505050505050505050505050505050D -:100E950005050505050505050505050505050505FD -:100EA50005050505050505050505050505050606EB -:100EB50006060606060606060606060606060606CD -:100EC50006060606060606060606060606060606BD -:100ED50006060606060606060606060606060606AD -:100EE5000606060606060606060606070707080896 -:100EF500080909090A0A0A0B0B0B0C0C0C0D0D0D40 -:100F05000E0E0E0F0F0F10101011111112121213D9 -:100F15001313141414151515161616171717181874 -:100F250018191919191A1A1A1A1B1B1B1B1C1C1C18 -:100F35001C1D1D1D1D1E1E1E1E1F1F1F1F202020C8 -:100F45002121212222222323242425252626272761 -:100F5500282829292A2A2B2B2C2C2D2D2E2E2F2FD4 -:100F65003030313132323333343435353636373744 -:100F7500383839393A3A3B3C3D3E3F40414243449B -:100F85004546474849494A4B4B4C4D4E4F505152A7 -:100F95005354555556565757585A5B5D5E5F6162B7 -:100FA500636465666768696A6B6C6D6F717273748B -:100FB50075767778797A7B7C7E80013701013800F8 -:104B2800E4907236F0A3F0907F97E054FBF0E490A5 -:104B38007233F0907232F090720104F0E4907233A4 -:104B4800F0907232F090720104F0907F97E0440484 -:024B5800F02249 -:10326F00907618E0FF640570429075ABE0B40119D9 -:10327F009072377401F0E4908020F0908031F090DC -:10328F008028F0908039F08022E4907237F09075AA -:10329F00ADE090722BF0E02480F0E0908020F09071 -:1032AF008031F0908028F0908039F0EF6406600252 -:1032BF0081999072397404F0907239E0FF24FE9076 -:1032CF007204F0EF75F00AA424ABF582E43475F5BF -:1032DF0083E06401705490723604F0907204E0FF42 -:1032EF0024FD602824FE6024240324FB5004601C6A -:1032FF00818C74202FF582E43480F583E4F07428F8 -:10330F002FF582E43480F583E4F0818C907204E031 -:10331F00FF2430F582E43480F583E4F074382FF520 -:10332F0082E43480F583E4F0818CE4907236F0907F -:10333F007239E075F00AA424ADF582E43475F58393 -:10334F00E0FF7E0090750CEEF0A3EFF07006907228 -:10335F0002743BF090750CE0FEA3E0FF64804E70AA -:10336F0004907202F0EF4E70028135EF64804E7060 -:10337F00028135EFF8E490750DF0E890750CF09040 -:10338F007234E075F00AA424ACF582E43475F58349 -:10339F00E0FF907202F090750DE02FF090750CE049 -:1033AF003400F0E0FEA3E0FFE4FCFD7BD67AA5F944 -:1033BF00F8D3123795400A90750C74A5F0A374D604 -:1033CF00F090750DE0242AF090750CE0345AF0E07F -:1033DF00FEA3E07805CEA2E713CE13D8F8FF9075C1 -:1033EF000CEEF0A3EFF090722CEEF0A3EFF0D3946D -:1033FF00D2EE64809482400A90722C7402F0A3740F -:10340F00D2F0C390722CE0648094805004E4F0A357 -:10341F00F090722CE0FEA3E0243AF582EE3472F5C0 -:10342F0083E0907202F0907204E0FF24FD602D247F -:10343F00FE6029240324FB50046021804090720217 -:10344F00E0FE74202FF582E43480F583EEF07428CB -:10345F002FF582E43480F583EEF08021907202E044 -:10346F00FF907204E0FE2430F582E43480F583EFA0 -:10347F00F074382EF582E43480F583EFF0907239D2 -:0B348F00E004F0E0640A600241C72284 -:10349A00907618E0FFB40523907237E0701D90759E -:1034AA00ADE090722BF0E02480F0E0908020F09064 -:1034BA008031F0908028F0908039F0EF6406600245 -:1034CA00C191907236E06002C191907640E070310D -:1034DA009072037403F0907203E0FF75F00AA4245B -:1034EA00AAF582E43475F583E0FE907229E0FDEED8 -:1034FA006D600EEFC3940A5008907203E004F080E6 -:10350A00D59072397404F0907640E0700890720396 -:10351A00E0907239F0907239E0FD24FE90722AF040 -:10352A00ED75F00AA424ADF582E43475F583E0FF65 -:10353A007E0090750CEEF0A3EFF0700690720274A4 -:10354A0080F090750CE0FEA3E0FF64804E7004905A -:10355A007202F0EF4E7002C11BEF64804E7002C11E -:10356A001BEFF8E490750DF0E890750CF0ED75F02E -:10357A000AA424ACF582E43475F583E0FF90720264 -:10358A00F090750DE02FF090750CE03400F0E0FE3D -:10359A00A3E0FFE4FCFD7BD67AA5F9F8D3123795B0 -:1035AA00400A90750C74A5F0A374D6F090750DE0DE -:1035BA00242AF090750CE0345AF0E0FEA3E0780576 -:1035CA00CEA2E713CE13D8F8FF90750CEEF0A3EF56 -:1035DA00F090722CEEF0A3EFF0D394D2EE648094C4 -:1035EA0082400A90722C7402F0A374D2F0C39072D3 -:1035FA002CE0648094805004E4F0A3F090722CE0F4 -:10360A00FEA3E0243AF582EE3472F583E09072026A -:10361A00F090722AE0FF24FD602D24FE6029240325 -:10362A0024FB500460218040907202E0FE74202F37 -:10363A00F582E43480F583EEF074282FF582E434C1 -:10364A0080F583EEF08021907202E0FF90722AE00A -:10365A00FE2430F582E43480F583EFF074382EF5D9 -:10366A0082E43480F583EFF0907640E07006907241 -:10367A0039740AF0907239E004F0E0C3940A5002F7 -:08368A00A111E4907640F0224A -:044E0B001217302228 -:1049AE009076467480F0E4A3F0A3F0A3F0A3F0A3F6 -:1049BE00F0A3F0A3F0A3F0A37480F0E4A3F0A3F0AF -:1049CE00A3F0A3F0A3F0A3F0A37440F0E4A3F0A32C -:1049DE007440F0E4A3F0A3F0A3F0A3F0A3F0A3F0CF -:1049EE00A37440F0E4A3F0A37440F0E4A3F0A3F0AA -:0549FE00A3F0A3F0226C -:100FC600E4FF74462FF582E43476F583E0FE742060 -:100FD6002FF582E43480F583EEF0744E2FF582E42B -:100FE6003476F583E0FE74302FF582E43480F583A1 -:060FF600EEF00FBF08CC75 -:010FFC0022D2 -:104AF100E4FF74562FF582E43476F583E0FE7428E2 -:104B01002FF582E43480F583EEF0745E2FF582E4B4 -:104B11003476F583E0FE74382FF582E43480F58332 -:064B2100EEF00FBF08CC0E -:014B2700226B -:10173000C082C083C0E0E8C0E07878E814F870FBAD -:0A174000D0E0F8D0E0D083D0822280 -:030043000249006F -:10490000022FE700023D4700024DB400024C430075 -:10491000024BE900022FFF00024C5B00024C0A0030 -:10492000024C7200024B5A00024C8900024CA0005B -:10493000024CB700024CCE00024CE500024CFC00D9 -:10494000024D1300024D2A00024D4100024D580055 -:08495000024D6F00024D8600CC -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:0E1EB000000000000000000000000000000024 -:101EBE000000000000000000000000000000000014 -:101ECE000000000000000000000000000000000004 -:101EDE0000000000000000000000000000000000F4 -:101EEE0000000000000000000000000000000000E4 -:101EFE0000000000000000000000000000000000D4 -:101F0E0000000000000000000000000000000000C3 -:101F1E0000000000000000000000000000000000B3 -:101F2E0000000000000000000000000000000000A3 -:021F3E000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:0E23700000000000000000000000000000005F -:10237E00000000000000000000000000000000004F -:10238E00000000000000000000000000000000003F -:10239E00000000000000000000000000000000002F -:1023AE00000000000000000000000000000000001F -:1023BE00000000000000000000000000000000000F -:1023CE0000000000000000000000000000000000FF -:1023DE0000000000000000000000000000000000EF -:1023EE0000000000000000000000000000000000DF -:1023FE0000000000000000000000000000000000CF -:10240E0000000000000000000000000000000000BE -:10241E0000000000000000000000000000000000AE -:10242E00000000000000000000000000000000009E -:10243E00000000000000000000000000000000008E -:10244E00000000000000000000000000000000007E -:10245E00000000000000000000000000000000006E -:10246E00000000000000000000000000000000005E -:10247E00000000000000000000000000000000004E -:10248E00000000000000000000000000000000003E -:10249E00000000000000000000000000000000002E -:1024AE00000000000000000000000000000000001E -:1024BE00000000000000000000000000000000000E -:1024CE0000000000000000000000000000000000FE -:1024DE0000000000000000000000000000000000EE -:1024EE0000000000000000000000000000000000DE -:1024FE0000000000000000000000000000000000CE -:10250E0000000000000000000000000000000000BD -:10251E0000000000000000000000000000000000AD -:10252E00000000000000000000000000000000009D -:10253E00000000000000000000000000000000008D -:10254E00000000000000000000000000000000007D -:10255E00000000000000000000000000000000006D -:10256E00000000000000000000000000000000005D -:10257E00000000000000000000000000000000004D -:10258E00000000000000000000000000000000003D -:10259E00000000000000000000000000000000002D -:1025AE00000000000000000000000000000000001D -:1025BE00000000000000000000000000000000000D -:1025CE0000000000000000000000000000000000FD -:1025DE0000000000000000000000000000000000ED -:1025EE0000000000000000000000000000000000DD -:1025FE0000000000000000000000000000000000CD -:10260E0000000000000000000000000000000000BC -:10261E0000000000000000000000000000000000AC -:10262E00000000000000000000000000000000009C -:10263E00000000000000000000000000000000008C -:10264E00000000000000000000000000000000007C -:10265E00000000000000000000000000000000006C -:10266E00000000000000000000000000000000005C -:10267E00000000000000000000000000000000004C -:10268E00000000000000000000000000000000003C -:10269E00000000000000000000000000000000002C -:1026AE00000000000000000000000000000000001C -:1026BE00000000000000000000000000000000000C -:1026CE0000000000000000000000000000000000FC -:1026DE0000000000000000000000000000000000EC -:0E26EE000000000000000000000000000000DE -:1026FC0000000000000000000000000000000000CE -:10270C0000000000000000000000000000000000BD -:10271C0000000000000000000000000000000000AD -:10272C00000000000000000000000000000000009D -:10273C00000000000000000000000000000000008D -:10274C00000000000000000000000000000000007D -:10275C00000000000000000000000000000000006D -:10276C00000000000000000000000000000000005D -:10277C00000000000000000000000000000000004D -:10278C00000000000000000000000000000000003D -:10279C00000000000000000000000000000000002D -:1027AC00000000000000000000000000000000001D -:1027BC00000000000000000000000000000000000D -:1027CC0000000000000000000000000000000000FD -:1027DC0000000000000000000000000000000000ED -:1027EC0000000000000000000000000000000000DD -:0527FC000000000022B6 -:07174A00907FC57402F0223C -:10175100907EC0E0907645F0907EC1E0907644F0B6 -:10176100907EC2E0907643F0B40003021778907641 -:10177100197403F002178E907644E0B4BB09907699 -:10178100197402F002178E9076197401F090764266 -:03179100E4F0225F -:030000000246B9FC -:0C46B900787FE4F6D8FD758138024700D8 -:10369200BB010689828A83E0225002E722BBFE0236 -:0936A200E32289828A83E4932269 -:1036AB00BB010CE58229F582E5833AF583E02250D4 -:1036BB0006E92582F8E622BBFE06E92582F8E2221E -:0D36CB00E58229F582E5833AF583E4932238 -:1036D800C2D5EC30E709B2D5E4C39DFDE49CFCEE0D -:1036E80030E715B2D5E4C39FFFE49EFE12381FC32E -:1036F800E49DFDE49CFC800312381F30D507C3E429 -:063708009FFFE49EFE227B -:10370E00BB0110E58229F582E5833AF583E0F5F0F9 -:10371E00A3E0225009E92582F886F008E622BBFED6 -:10372E000AE92582F8E2F5F008E222E5832AF5831C -:08373E00E993F5F0A3E99322E1 -:10374600E88FF0A4CC8BF0A42CFCE98EF0A42CFC22 -:103756008AF0EDA42CFCEA8EF0A4CDA8F08BF0A4A0 -:103766002DCC3825F0FDE98FF0A42CCD35F0FCEBFF -:103776008EF0A4FEA9F0EB8FF0A4CFC5F02ECD39C4 -:0F378600FEE43CFCEAA42DCE35F0FDE43CFC2231 -:10379500EB9FF5F0EA9E42F0E99D42F0EC6480C8AB -:0637A50064809845F0224B -:1037AB00EB9FF5F0EA9E42F0E99D42F0E89C45F074 -:0137BB0022EB -:0C37BC00ECF0A3EDF0A3EEF0A3EFF02280 -:1037C800A8828583F0D083D0821237DF1237DF12C8 -:1037D80037DF1237DFE473E493A3C583C5F0C583ED -:1037E800C8C582C8F0A3C583C5F0C583C8C582C84B -:0137F80022AE -:1037F900D083D082F8E4937012740193700DA3A35F -:1038090093F8740193F5828883E473740293686072 -:06381900EFA3A3A380DF72 -:1046C5000207A6E493A3F8E493A34003F68001F25E -:1046D50008DFF48029E493A3F85407240CC8C333F6 -:1046E500C4540F4420C8834004F456800146F6DFC5 -:1046F500E4800B0102040810204080900C8FE47EBA -:10470500019360BCA3FF543F30E509541FFEE493B9 -:10471500A360010ECF54C025E060A840B8E493A380 -:10472500FAE493A3F8E493A3C8C582C8CAC583CAAB -:10473500F0A3C8C582C8CAC583CADFE9DEE780BE63 -:010FC500002B -:10381F00BC000BBE0029EF8DF084FFADF022E4CC8D -:10382F00F875F008EF2FFFEE33FEEC33FCEE9DEC56 -:10383F00984005FCEE9DFE0FD5F0E9E4CEFD22ED9C -:10384F00F8F5F0EE8420D21CFEADF075F008EF2FE6 -:10385F00FFED33FD4007985006D5F0F222C398FDD7 -:05386F000FD5F0EA2274 -:00000001FF -/* -VERSION=1.04.062 -DATE=16.10.2002 -*/ -static INTEL_HEX_RECORD g_emi62_loader[] = { - 3,0x0000,0,{0x02,0x02,0x87}, - 3,0x0043,0,{0x02,0x04,0x00}, - 16,0x0100,0,{0xe4,0xff,0xfe,0xc2,0x20,0xd2,0xe8,0x43,0xd8,0x20,0x90,0x7f,0xab,0x74,0xff,0xf0}, - 16,0x0110,0,{0x90,0x7f,0xa9,0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x90,0x7f,0x95,0x74,0xc0}, - 16,0x0120,0,{0xf0,0x90,0x7f,0x9e,0xf0,0x90,0x7f,0x98,0xf0,0xe4,0x90,0x7f,0x94,0xf0,0x90,0x7f}, - 16,0x0130,0,{0x9d,0x74,0xff,0xf0,0x90,0x7f,0x97,0x74,0xa0,0xf0,0x90,0x7f,0x93,0xe0,0x54,0xfc}, - 16,0x0140,0,{0xf0,0x90,0x7f,0x9c,0x74,0x03,0xf0,0xe4,0x90,0x7f,0x96,0xf0,0x90,0x7f,0xaf,0xe0}, - 16,0x0150,0,{0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x0d,0xf0,0xd2,0xaf,0x0f,0xbf,0x00,0x01}, - 16,0x0160,0,{0x0e,0xbe,0x07,0xf8,0xbf,0x08,0xf5,0x20,0x20,0x42,0x75,0x14,0x00,0x75,0x13,0x00}, - 16,0x0170,0,{0x75,0x12,0x00,0x75,0x11,0x00,0x7f,0x48,0x7e,0x92,0x7d,0x00,0x7c,0x00,0xab,0x14}, - 16,0x0180,0,{0xaa,0x13,0xa9,0x12,0xa8,0x11,0xc3,0x12,0x03,0xed,0x50,0xdb,0x20,0x20,0xd8,0x7a}, - 16,0x0190,0,{0x00,0x79,0x00,0x78,0x00,0xe5,0x14,0x24,0x01,0xf5,0x14,0xea,0x35,0x13,0xf5,0x13}, - 16,0x01a0,0,{0xe9,0x35,0x12,0xf5,0x12,0xe8,0x35,0x11,0xf5,0x11,0x80,0xca,0x30,0x20,0xfd,0x12}, - 16,0x01b0,0,{0x01,0xc7,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xb4,0xe0,0x44}, - 6,0x01c0,0,{0x02,0xf0,0xc2,0x20,0x80,0xe6}, - 1,0x01c6,0,{0x22}, - 16,0x01c7,0,{0x90,0x7f,0xe9,0xe0,0x24,0x5b,0x60,0x60,0x24,0x02,0x60,0x03,0x02,0x02,0x85,0x90}, - 16,0x01d7,0,{0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5,0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90}, - 16,0x01e7,0,{0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5,0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5}, - 16,0x01f7,0,{0x16,0x45,0x15,0x70,0x03,0x02,0x02,0x85,0xe4,0x90,0x7f,0xc5,0xf0,0x90,0x7f,0xb4}, - 16,0x0207,0,{0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c,0x12,0x03,0x13,0xaf,0x0c,0x7e}, - 16,0x0217,0,{0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5,0x0a,0xc3,0xe5,0x16,0x9f,0xf5}, - 16,0x0227,0,{0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xc7,0x90,0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5}, - 16,0x0237,0,{0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90,0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5}, - 16,0x0247,0,{0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5,0x16,0x45,0x15,0x60,0x30,0xe4,0x90}, - 16,0x0257,0,{0x7f,0xc5,0xf0,0x90,0x7f,0xb4,0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c}, - 16,0x0267,0,{0x12,0x03,0x2b,0xaf,0x0c,0x7e,0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5}, - 15,0x0277,0,{0x0a,0xc3,0xe5,0x16,0x9f,0xf5,0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xca,0xc3}, - 1,0x0286,0,{0x22}, - 12,0x0287,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x29,0x02,0x02,0xce}, - 16,0x0293,0,{0x02,0x01,0x00,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2}, - 16,0x02a3,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33}, - 16,0x02b3,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf}, - 16,0x02c3,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x04,0x6e,0xe4,0x7e}, - 16,0x02d3,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93}, - 16,0x02e3,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3}, - 16,0x02f3,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca}, - 16,0x0303,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe}, - 16,0x0313,0,{0xe5,0x0c,0xff,0xe5,0x0b,0xf5,0x82,0xe5,0x0a,0xf5,0x83,0x75,0x92,0x7e,0x74,0xc0}, - 8,0x0323,0,{0xf8,0xe2,0x08,0xf0,0xa3,0xdf,0xfa,0x22}, - 16,0x032b,0,{0x90,0x7f,0x96,0x85,0x83,0x92,0xa8,0x82,0x79,0x02,0x90,0x00,0x00,0xe0,0xb4,0x00}, - 16,0x033b,0,{0x0d,0x74,0x01,0xf0,0x90,0x7f,0x97,0xe0,0x54,0x7f,0xf0,0x44,0x80,0xf0,0xe5,0x0c}, - 16,0x034b,0,{0xff,0x90,0x7e,0xc0,0xe0,0xf5,0x28,0xe4,0xa2,0x47,0x33,0xf2,0x69,0xf2,0xe4,0xa2}, - 16,0x035b,0,{0x46,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x45,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x44,0x33}, - 16,0x036b,0,{0xf2,0x69,0xf2,0xe4,0xa2,0x43,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x42,0x33,0xf2,0x69}, - 16,0x037b,0,{0xf2,0xe4,0xa2,0x41,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x40,0x33,0xf2,0x69,0xf2,0xa3}, - 3,0x038b,0,{0xdf,0xc2,0x22}, - 16,0x038e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f}, - 11,0x039e,0,{0xab,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x03a9,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x20,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01}, - 8,0x03b9,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x03c1,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xd0}, - 6,0x03d1,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x03d7,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0xd0}, - 6,0x03e7,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x03ed,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0}, - 1,0x03fd,0,{0x22}, - 1,0x03fe,0,{0x32}, - 1,0x03ff,0,{0x32}, - 16,0x0400,0,{0x02,0x03,0xa9,0x00,0x02,0x03,0xc1,0x00,0x02,0x03,0x8e,0x00,0x02,0x04,0x58,0x00}, - 16,0x0410,0,{0x02,0x03,0xd7,0x00,0x02,0x03,0xfe,0x00,0x02,0x03,0xff,0x00,0x02,0x04,0x84,0x00}, - 16,0x0420,0,{0x02,0x04,0x85,0x00,0x02,0x04,0x86,0x00,0x02,0x04,0x87,0x00,0x02,0x04,0x88,0x00}, - 16,0x0430,0,{0x02,0x04,0x89,0x00,0x02,0x04,0x8a,0x00,0x02,0x04,0x8b,0x00,0x02,0x04,0x8c,0x00}, - 16,0x0440,0,{0x02,0x04,0x8d,0x00,0x02,0x04,0x8e,0x00,0x02,0x04,0x8f,0x00,0x02,0x04,0x90,0x00}, - 8,0x0450,0,{0x02,0x04,0x91,0x00,0x02,0x04,0x92,0x00}, - 16,0x0458,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08,0xf0,0xd0}, - 6,0x0468,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}, - 16,0x046e,0,{0x02,0x0a,0x00,0x0f,0x01,0x0c,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x41,0x00,0x00}, - 1,0x047e,0,{0x00}, - 4,0x047f,0,{0x02,0x17,0x00,0x00}, - 1,0x0483,0,{0x00}, - 1,0x0484,0,{0x32}, - 1,0x0485,0,{0x32}, - 1,0x0486,0,{0x32}, - 1,0x0487,0,{0x32}, - 1,0x0488,0,{0x32}, - 1,0x0489,0,{0x32}, - 1,0x048a,0,{0x32}, - 1,0x048b,0,{0x32}, - 1,0x048c,0,{0x32}, - 1,0x048d,0,{0x32}, - 1,0x048e,0,{0x32}, - 1,0x048f,0,{0x32}, - 1,0x0490,0,{0x32}, - 1,0x0491,0,{0x32}, - 1,0x0492,0,{0x32}, - 16,0x1100,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x01,0x01,0x00,0x01,0x01,0x02}, - 16,0x1110,0,{0x00,0x01,0x09,0x02,0x20,0x00,0x01,0x01,0x03,0xa0,0x00,0x09,0x04,0x00,0x00,0x02}, - 16,0x1120,0,{0xff,0x00,0x00,0x04,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40}, - 16,0x1130,0,{0x00,0x00,0x04,0x03,0x09,0x04,0x26,0x03,0x41,0x00,0x6e,0x00,0x63,0x00,0x68,0x00}, - 16,0x1140,0,{0x6f,0x00,0x72,0x00,0x20,0x00,0x43,0x00,0x68,0x00,0x69,0x00,0x70,0x00,0x73,0x00}, - 16,0x1150,0,{0x2c,0x00,0x20,0x00,0x49,0x00,0x6e,0x00,0x63,0x00,0x2e,0x00,0x28,0x03,0x46,0x00}, - 16,0x1160,0,{0x69,0x00,0x72,0x00,0x6d,0x00,0x77,0x00,0x61,0x00,0x72,0x00,0x65,0x00,0x20,0x00}, - 16,0x1170,0,{0x46,0x00,0x72,0x00,0x61,0x00,0x6d,0x00,0x65,0x00,0x57,0x00,0x6f,0x00,0x72,0x00}, - 16,0x1180,0,{0x6b,0x00,0x73,0x00,0x2a,0x03,0x43,0x00,0x6f,0x00,0x6e,0x00,0x66,0x00,0x69,0x00}, - 16,0x1190,0,{0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00}, - 16,0x11a0,0,{0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x22,0x03}, - 16,0x11b0,0,{0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x66,0x00,0x61,0x00,0x63,0x00}, - 16,0x11c0,0,{0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00}, - 2,0x11d0,0,{0x00,0x00}, - 0,0x0000,1,{0} -}; -/* Source: EMILOAD.HEX -:10046E00020A000F010C11040D00000000410000F3 -:01047E00007D -:1001C700907FE9E0245B606024026003020285906F -:1001D7007FEAE0750A00F50BA3E0FEE4EE420A9021 -:1001E7007FEEE0751500F516A3E0FEE4EE4215E597 -:1001F7001645157003020285E4907FC5F0907FB421 -:10020700E020E3F9907FC5E0F50C120313AF0C7EF5 -:1002170000EF250BF50BEE350AF50AC3E5169FF53A -:1002270016E5159EF51580C7907FEAE0750A00F57B -:100237000BA3E0FEE4EE420A907FEEE0751500F5B1 -:1002470016A3E0FEE4EE4215E51645156030E4908E -:100257007FC5F0907FB4E020E3F9907FC5E0F50C0F -:1002670012032BAF0C7E00EF250BF50BEE350AF5CD -:0F0277000AC3E5169FF516E5159EF51580CAC357 -:010286002255 -:1003A900C0E0C083C082D2205391EF907FAB74012B -:0803B900F0D082D083D0E032C5 -:10038E00C0E0C083C082907FC4E4F05391EF907FB1 -:0B039E00AB7404F0D082D083D0E032BA -:1003C100C0E0C083C0825391EF907FAB7402F0D044 -:0603D10082D083D0E0326F -:1003D700C0E0C083C0825391EF907FAB7410F0D020 -:0603E70082D083D0E03259 -:0103FE0032CC -:10045800C0E0C083C0825391EF907FAB7408F0D0A6 -:0604680082D083D0E032D7 -:0103FF0032CB -:010484003245 -:010485003244 -:010486003243 -:010487003242 -:010488003241 -:010489003240 -:01048A00323F -:01048B00323E -:01048C00323D -:01048D00323C -:01048E00323B -:01048F00323A -:010490003239 -:010491003238 -:010492003237 -:04047F000217000060 -:10010000E4FFFEC220D2E843D820907FAB74FFF01A -:10011000907FA9F0907FAAF05391EF907F9574C0E3 -:10012000F0907F9EF0907F98F0E4907F94F0907F25 -:100130009D74FFF0907F9774A0F0907F93E054FC43 -:10014000F0907F9C7403F0E4907F96F0907FAFE096 -:100150004401F0907FAEE0440DF0D2AF0FBF00013C -:100160000EBE07F8BF08F520204275140075130075 -:100170007512007511007F487E927D007C00AB14E3 -:10018000AA13A912A811C31203ED50DB2020D87ABC -:100190000079007800E5142401F514EA3513F5130D -:1001A000E93512F512E83511F51180CA3020FD123B -:1001B00001C75007907FB4E04401F0907FB4E04461 -:0601C00002F0C22080E6FF -:0101C6002216 -:1011000012011001000000406A0801010001010203 -:10111000000109022000010103A0000904000002EF -:10112000FF0000040705820240000007050202409C -:10113000000004030904260341006E0063006800F8 -:101140006F007200200043006800690070007300A7 -:101150002C00200049006E0063002E00280346008A -:10116000690072006D007700610072006500200068 -:101170004600720061006D00650057006F0072004C -:101180006B0073002A0343006F006E006600690065 -:101190006700750072006100740069006F006E00E6 -:1011A000200053007400720069006E006700220383 -:1011B00049006E0074006500720066006100630003 -:1011C0006500200053007400720069006E00670023 -:0211D00000001D -:10031300E50CFFE50BF582E50AF58375927E74C063 -:08032300F8E208F0A3DFFA2262 -:10032B00907F96858392A8827902900000E0B400BA -:10033B000D7401F0907F97E0547FF04480F0E50C52 -:10034B00FF907EC0E0F528E4A24733F269F2E4A205 -:10035B004633F269F2E4A24533F269F2E4A2443384 -:10036B00F269F2E4A24333F269F2E4A24233F26996 -:10037B00F2E4A24133F269F2E4A24033F269F2A350 -:03038B00DFC222AC -:03004300020400B4 -:100400000203A9000203C10002038E000204580087 -:100410000203D7000203FE000203FF00020484006F -:10042000020485000204860002048700020488009A -:100430000204890002048A0002048B0002048C007A -:1004400002048D0002048E0002048F00020490005A -:08045000020491000204920075 -:0300000002028772 -:0C028700787FE4F6D8FD7581290202CED4 -:1003ED00EB9FF5F0EA9E42F0E99D42F0E89C45F066 -:0103FD0022DD -:10029300020100E493A3F8E493A34003F68001F280 -:1002A30008DFF48029E493A3F85407240CC8C3336C -:1002B300C4540F4420C8834004F456800146F6DF3B -:1002C300E4800B010204081020408090046EE47E59 -:1002D300019360BCA3FF543F30E509541FFEE49330 -:1002E300A360010ECF54C025E060A840B8E493A3F7 -:1002F300FAE493A3F8E493A3C8C582C8CAC583CA22 -:10030300F0A3C8C582C8CAC583CADFE9DEE780BED9 -:010483000078 -:00000001FF -/* -VERSION=1.0.2.002 -DATE=10.01.2002 -EMI26_62 -*/ diff --git a/drivers/usb/misc/emi62_fw_s.h b/drivers/usb/misc/emi62_fw_s.h deleted file mode 100644 index cef05e8..0000000 --- a/drivers/usb/misc/emi62_fw_s.h +++ /dev/null @@ -1,8837 +0,0 @@ -/* - * This file is generated from three different files, provided by Emagic. - */ -/* generated Tue Apr 15 21:59:42 EEST 2003 */ - -static INTEL_HEX_RECORD g_emi62bs[]={ - {16, 0x8010, 0, {0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x07 }}, - {16, 0x8020, 0, {0x30,0x01,0x60,0x01,0x00,0x00,0x00,0x0d,0x30,0x01,0x20,0x01,0x00,0x80,0x3f,0x2d }}, - {16, 0x8030, 0, {0x30,0x00,0xc0,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x09 }}, - {16, 0x8040, 0, {0x30,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x01 }}, - {16, 0x8050, 0, {0x30,0x00,0x40,0x00,0x50,0x00,0x58,0x1a,0x80,0x12,0x10,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8090, 0, {0x00,0x12,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x48 }}, - {16, 0x80c0, 0, {0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8100, 0, {0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8130, 0, {0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8170, 0, {0x80,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81a0, 0, {0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x90,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81e0, 0, {0x7f,0x10,0x00,0x34,0x00,0x0d,0x00,0x03,0x40,0x00,0xd0,0x00,0x34,0x00,0x05,0x00 }}, - {16, 0x81f0, 0, {0x07,0x40,0x01,0xd0,0x00,0x74,0x00,0x1d,0x00,0x07,0x40,0x01,0xd0,0x00,0x74,0x00 }}, - {16, 0x8200, 0, {0x1d,0x80,0x07,0xe0,0x01,0xb8,0x00,0x6e,0x00,0x1b,0x80,0x06,0xe0,0x01,0x38,0x37 }}, - {16, 0x8210, 0, {0xc4,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x80,0xfb,0x30,0x36,0xc8 }}, - {16, 0x8220, 0, {0x4e,0x09,0x03,0xfc,0x84,0xff,0x10,0x3b,0xc0,0x0e,0xc8,0x07,0x22,0x80,0xff,0x22 }}, - {16, 0x8230, 0, {0x33,0xc0,0x0f,0xc8,0x33,0x6e,0x00,0xfb,0x80,0x3f,0x20,0x0d,0xc2,0x53,0xd4,0x80 }}, - {16, 0x8240, 0, {0xcc,0x3a,0x3f,0x00,0x0c,0xf1,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8250, 0, {0x80,0x00,0xed,0x60,0xbf,0x60,0x23,0xf0,0x0d,0x82,0x12,0x3c,0x60,0x8f,0x70,0x23 }}, - {16, 0x8260, 0, {0xf0,0x08,0x88,0x02,0xa5,0x40,0xbf,0xd0,0x63,0xd6,0x0b,0x88,0x02,0x2e,0x0c,0xbb }}, - {16, 0x8270, 0, {0x80,0x2e,0x20,0x88,0x8d,0x02,0xe6,0x40,0x80,0x60,0x2e,0x30,0x0a,0xb1,0x12,0x20 }}, - {16, 0x8280, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x80,0xa3,0x40,0x2c,0xc4 }}, - {16, 0x8290, 0, {0x4a,0x00,0x12,0x8c,0x88,0xa3,0x22,0x20,0xc4,0x0a,0x90,0x42,0x04,0xa9,0xa3,0x00 }}, - {16, 0x82a0, 0, {0x24,0xc8,0x8b,0x80,0x02,0xcc,0x00,0xb3,0x00,0x2e,0x01,0x09,0x08,0x02,0x84,0x00 }}, - {16, 0x82b0, 0, {0x80,0x20,0x2c,0x10,0x0a,0x32,0x42,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x82c0, 0, {0xc0,0x15,0xac,0x04,0xb3,0x00,0x2a,0xc0,0x08,0x08,0xa2,0x8c,0x00,0x8b,0x00,0xa2 }}, - {16, 0x82d0, 0, {0xc1,0x10,0x98,0x42,0xa7,0x00,0xbb,0x01,0x66,0xc1,0x0b,0x80,0x02,0xac,0x04,0xbb }}, - {16, 0x82e0, 0, {0x00,0x2e,0x00,0x0b,0xb8,0x12,0xe4,0x02,0x89,0x08,0x0e,0x40,0x0a,0xb0,0x02,0x30 }}, - {16, 0x82f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xac,0x00,0xeb,0x00,0x3e,0xc0 }}, - {16, 0x8300, 0, {0x4a,0xb8,0x23,0xec,0x18,0xeb,0x00,0x32,0xc0,0x0e,0x2c,0x12,0x22,0x10,0xeb,0x00 }}, - {16, 0x8310, 0, {0x26,0xc0,0x4f,0x00,0x43,0xed,0x00,0xfb,0x00,0x2e,0x24,0x0d,0x80,0x13,0xe4,0x00 }}, - {16, 0x8320, 0, {0xc8,0xd0,0x7c,0x12,0x0e,0xb0,0x03,0x40,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8330, 0, {0xe1,0x00,0xbc,0x00,0xff,0x00,0x35,0xc0,0x4f,0xe0,0x03,0x7c,0x08,0xff,0x01,0x17 }}, - {16, 0x8340, 0, {0xc2,0x4d,0xc0,0x03,0xf4,0x08,0xf7,0x00,0x3b,0xc0,0x07,0xc0,0x03,0x7c,0x80,0xff }}, - {16, 0x8350, 0, {0x24,0x3f,0x40,0x0c,0xf0,0x01,0xf4,0x04,0xbc,0x08,0x3f,0x28,0x0f,0xf0,0x03,0x78 }}, - {16, 0x8360, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x08,0xfb,0x04,0x3a,0xc8 }}, - {16, 0x8370, 0, {0x0f,0x94,0x03,0xec,0x10,0xf3,0x00,0x34,0xc0,0x0e,0xb0,0x03,0x61,0x04,0xfb,0x00 }}, - {16, 0x8380, 0, {0x36,0xc0,0x0e,0xa3,0x03,0x2c,0x80,0xfb,0x72,0x3e,0x02,0x0f,0x8a,0x03,0xe4,0x02 }}, - {16, 0x8390, 0, {0xc9,0x80,0x2a,0x50,0x0f,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x83a0, 0, {0xca,0x44,0x3c,0x00,0xbf,0x00,0x03,0xc0,0x08,0x80,0x03,0x7c,0x00,0xbf,0x00,0x3f }}, - {16, 0x83b0, 0, {0xe2,0x08,0x90,0x43,0x60,0x00,0xbf,0x00,0x37,0xc0,0x08,0x90,0x01,0x6d,0x00,0xbb }}, - {16, 0x83c0, 0, {0x40,0x2c,0x10,0x0b,0xb0,0x42,0xd7,0xc0,0x89,0x00,0x2a,0x7c,0x0b,0xf0,0x02,0xf2 }}, - {16, 0x83d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x05,0x4c,0x00,0xb3,0x00,0x20,0xd5 }}, - {16, 0x83e0, 0, {0x4a,0x00,0x00,0x0c,0x04,0x93,0x00,0x0c,0xf0,0x0b,0x09,0x02,0x08,0x01,0xb3,0x20 }}, - {16, 0x83f0, 0, {0x28,0xc0,0x0a,0x0c,0x0a,0x0e,0x00,0xb3,0x00,0x24,0x30,0x09,0x00,0x02,0xc6,0x10 }}, - {16, 0x8400, 0, {0x80,0x42,0x20,0x00,0x8b,0xb0,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8410, 0, {0x22,0x01,0x1e,0x00,0xb7,0x94,0x21,0xe4,0x48,0xd9,0x12,0x5e,0x40,0xb7,0x90,0x29 }}, - {16, 0x8420, 0, {0xe0,0x8b,0x69,0x12,0xd6,0x80,0x37,0x82,0x2c,0xe8,0x08,0x4a,0x02,0x5e,0x00,0xb7 }}, - {16, 0x8430, 0, {0xa4,0x2d,0x20,0x0b,0x79,0x02,0xd6,0x08,0x86,0x90,0x29,0xa0,0x0b,0x79,0x02,0xd8 }}, - {16, 0x8440, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x0c,0x00,0xfb,0xa0,0x28,0xe8 }}, - {16, 0x8450, 0, {0x0e,0x2a,0x02,0x8c,0x00,0xd3,0x00,0x64,0xc0,0x0f,0x00,0x43,0x0e,0xc4,0xf3,0x00 }}, - {16, 0x8460, 0, {0x78,0xec,0x0e,0x0a,0x43,0x0e,0x20,0x73,0xe0,0x3c,0x02,0x4f,0x00,0x03,0xc4,0x40 }}, - {16, 0x8470, 0, {0xc3,0x00,0x38,0xc0,0x0f,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8480, 0, {0x40,0x1d,0xbc,0x00,0xff,0x00,0xbc,0xcc,0x0e,0xb0,0x03,0xec,0x20,0xfb,0x00,0x3c }}, - {16, 0x8490, 0, {0xc2,0x0c,0x20,0x03,0x6c,0x50,0xf3,0x00,0x36,0xc4,0x0f,0x40,0x03,0xfc,0x08,0xff }}, - {16, 0x84a0, 0, {0x1a,0x3f,0x80,0x0f,0xf0,0x01,0xe4,0x30,0xff,0x02,0x3f,0xc0,0x0f,0xf0,0x63,0xd0 }}, - {16, 0x84b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xec,0x40,0xfb,0x00,0xb2,0xd8 }}, - {16, 0x84c0, 0, {0x0c,0xb0,0x01,0x2d,0x20,0xdb,0x01,0x3a,0xc8,0x8c,0x38,0x03,0xa8,0x00,0xfb,0x48 }}, - {16, 0x84d0, 0, {0x3e,0xc9,0x0f,0x80,0x03,0xec,0x40,0xfb,0x01,0x3e,0x00,0x0f,0x08,0x03,0xa4,0x08 }}, - {16, 0x84e0, 0, {0xfa,0x80,0xb2,0x80,0x0f,0xb1,0x02,0x6a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x84f0, 0, {0x48,0x19,0x1c,0x80,0xbf,0x30,0x21,0xca,0x08,0xf0,0x0a,0x0c,0x80,0x8f,0x50,0x21 }}, - {16, 0x8500, 0, {0xc2,0x08,0x70,0x50,0x9c,0x00,0xb7,0x00,0x39,0xc4,0x0b,0x40,0x02,0x9c,0x04,0xb7 }}, - {16, 0x8510, 0, {0x20,0x25,0x40,0x0b,0x70,0x02,0x14,0x80,0xb6,0x00,0x21,0x80,0x0b,0xf8,0x02,0x12 }}, - {16, 0x8520, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb7,0xb0,0x21,0xec }}, - {16, 0x8530, 0, {0x0b,0x78,0x12,0xde,0x84,0x97,0x80,0x0d,0xe0,0x28,0xf8,0x02,0xde,0x00,0xb7,0x90 }}, - {16, 0x8540, 0, {0x2d,0xe4,0x0b,0x68,0x82,0x5e,0x80,0xb7,0xa0,0x29,0x20,0x0b,0x48,0x02,0x96,0x00 }}, - {16, 0x8550, 0, {0xb7,0x80,0x21,0xe1,0x0b,0x7a,0x02,0x70,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8560, 0, {0x48,0x04,0xcc,0x00,0xb3,0x00,0x20,0xc0,0x0b,0x38,0x02,0x8c,0x04,0x83,0x00,0x28 }}, - {16, 0x8570, 0, {0xc0,0x88,0x39,0x02,0x4c,0x40,0xb3,0x04,0x28,0xc0,0x1b,0x10,0x02,0x8c,0x01,0xb3 }}, - {16, 0x8580, 0, {0x04,0x24,0x88,0x4b,0x31,0x02,0x04,0x00,0xb3,0x80,0x20,0xf2,0x0b,0x30,0x02,0x02 }}, - {16, 0x8590, 0, {0x24,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xfa,0x00,0x32,0x80 }}, - {16, 0x85a0, 0, {0x0f,0xe8,0x03,0xe8,0x00,0xda,0x01,0x3a,0x80,0x8c,0xed,0x03,0xfb,0x04,0xfa,0x00 }}, - {16, 0x85b0, 0, {0x3e,0x80,0x0f,0x6c,0x03,0xfb,0xc8,0xbe,0xc2,0x1f,0x80,0x0f,0xe5,0x03,0xa8,0x00 }}, - {16, 0x85c0, 0, {0xfe,0x48,0x33,0x80,0x4f,0xa0,0x03,0x7a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x85d0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3c,0x00,0x0c,0x81,0x93,0x60,0x00,0xf8,0x01,0x36 }}, - {16, 0x85e0, 0, {0x10,0x0f,0x80,0x03,0xa0,0x20,0xf8,0x00,0x2a,0x01,0x8f,0x84,0x13,0xe1,0x00,0xf8 }}, - {16, 0x85f0, 0, {0x18,0x36,0x00,0x0f,0x80,0x13,0xe0,0x00,0xf8,0x20,0x3e,0x14,0x0f,0x80,0x03,0xd2 }}, - {16, 0x8600, 0, {0x80,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe4,0x00,0xf1,0x00,0xaa,0x40 }}, - {16, 0x8610, 0, {0x0c,0x90,0x03,0x24,0x00,0xe1,0x00,0x38,0x40,0x1c,0x90,0x03,0xe4,0x00,0xf9,0xa0 }}, - {16, 0x8620, 0, {0x3a,0x40,0x47,0x9a,0x93,0xa2,0x80,0xf8,0x10,0x3e,0x40,0x0b,0x94,0x03,0xe6,0x40 }}, - {16, 0x8630, 0, {0xf9,0xc0,0x3e,0x68,0x0b,0x10,0x03,0x02,0x84,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8640, 0, {0x80,0x04,0xe4,0x04,0xb9,0x00,0x22,0x40,0x08,0x90,0x02,0x24,0x04,0x89,0x00,0x36 }}, - {16, 0x8650, 0, {0x40,0x08,0x90,0x02,0xe4,0x04,0xb9,0x80,0x2e,0x40,0x4f,0x94,0x03,0x61,0x10,0xe8 }}, - {16, 0x8660, 0, {0x40,0x2e,0x40,0x0b,0x90,0x42,0xe6,0x04,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x02,0x20 }}, - {16, 0x8670, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x04,0x24,0x00,0xb9,0x00,0x22,0x40 }}, - {16, 0x8680, 0, {0x0a,0x10,0x52,0x04,0x04,0xa9,0x04,0x2a,0x40,0x08,0xb0,0x02,0xe4,0x01,0xb9,0x00 }}, - {16, 0x8690, 0, {0x2e,0x40,0x0b,0x90,0x02,0xa8,0x0d,0xb8,0x40,0x2e,0x40,0x09,0x94,0x02,0xe5,0x00 }}, - {16, 0x86a0, 0, {0xb9,0x04,0x2e,0x40,0x0b,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x86b0, 0, {0x08,0x04,0x04,0x80,0xb1,0x20,0x20,0xc8,0x0a,0x10,0x42,0x04,0x90,0x81,0x20,0x04 }}, - {16, 0x86c0, 0, {0xc8,0x08,0x30,0x26,0xc4,0x00,0xb1,0x20,0x2c,0x48,0x0b,0x90,0x02,0x45,0x01,0xb1 }}, - {16, 0x86d0, 0, {0x40,0x2c,0x40,0x0b,0x12,0x82,0xc4,0x00,0xb1,0x2b,0x2c,0x4a,0x0b,0x12,0x82,0x02 }}, - {16, 0x86e0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x08,0x21,0x48,0xf8,0x50,0x32,0x00 }}, - {16, 0x86f0, 0, {0x4e,0x85,0x0b,0x21,0x40,0xa8,0x52,0x2a,0x00,0x08,0x80,0x23,0xe1,0x40,0xf8,0x00 }}, - {16, 0x8700, 0, {0x3a,0x14,0x0f,0xa0,0x43,0xa8,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x82,0x03,0xe0,0x00 }}, - {16, 0x8710, 0, {0xf0,0x20,0x3e,0x88,0x4f,0x82,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8720, 0, {0x98,0x19,0xe4,0x40,0xf9,0x11,0x34,0x44,0x2d,0xd0,0x03,0xe4,0x50,0x79,0x10,0x38 }}, - {16, 0x8730, 0, {0x44,0x2f,0xd0,0x03,0xf5,0x10,0xf9,0x10,0x3e,0x45,0x06,0x50,0x03,0xe5,0x00,0xe9 }}, - {16, 0x8740, 0, {0x40,0x3f,0x40,0x0f,0xd0,0x43,0xf5,0x00,0xfd,0x28,0x3f,0x40,0x0f,0x92,0x83,0xe6 }}, - {16, 0x8750, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0xe6,0x00,0xd9,0x90,0x37,0x69 }}, - {16, 0x8760, 0, {0x4d,0x90,0x23,0x67,0x80,0xd9,0xe0,0x37,0x68,0x0e,0xd0,0x07,0xa4,0x00,0x05,0x86 }}, - {16, 0x8770, 0, {0x3e,0x66,0x0d,0x50,0x23,0x26,0x00,0xc9,0x82,0x3d,0x40,0x0d,0xd8,0x07,0x36,0x02 }}, - {16, 0x8780, 0, {0xcd,0xc0,0x33,0x60,0x0c,0x9c,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8790, 0, {0x38,0x10,0xe2,0x80,0x88,0xa2,0x22,0x10,0x28,0x8a,0x82,0x23,0x84,0x88,0xa0,0x22 }}, - {16, 0x87a0, 0, {0x14,0x48,0x80,0x42,0x82,0x00,0x88,0x40,0x2e,0x30,0x08,0x80,0x02,0xa2,0x00,0xd8 }}, - {16, 0x87b0, 0, {0x90,0x26,0x00,0x08,0x84,0x0a,0x21,0x00,0xc8,0xa0,0xa2,0x14,0x28,0x8c,0x02,0x0e }}, - {16, 0x87c0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x20,0x91,0x40,0x2c,0x44 }}, - {16, 0x87d0, 0, {0x18,0x10,0x02,0x85,0x04,0xb1,0x40,0x0c,0x40,0x0a,0x10,0x06,0x84,0x30,0x81,0x40 }}, - {16, 0x87e0, 0, {0x2c,0x48,0x59,0x10,0x1a,0x04,0x60,0x81,0x09,0x2e,0x40,0x1b,0x14,0x02,0x25,0x00 }}, - {16, 0x87f0, 0, {0x91,0xe0,0x20,0x60,0x08,0x16,0x02,0x00,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8800, 0, {0x18,0x15,0xa4,0x00,0x81,0x00,0x2a,0x41,0x08,0x90,0x02,0xa4,0x00,0xa1,0x00,0x2a }}, - {16, 0x8810, 0, {0x41,0x08,0xb0,0x82,0x24,0x11,0x8b,0x00,0x2e,0x40,0x18,0x91,0x02,0xa0,0x04,0x98 }}, - {16, 0x8820, 0, {0x20,0x2e,0x54,0x1b,0x90,0x82,0x2c,0x00,0x89,0x10,0x22,0x44,0x88,0x90,0x02,0x06 }}, - {16, 0x8830, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xd9,0x00,0x3e,0x40 }}, - {16, 0x8840, 0, {0x4c,0x90,0x03,0xa4,0x10,0xf9,0x00,0x3e,0x40,0x8e,0x10,0x02,0xa4,0xc2,0xc9,0x00 }}, - {16, 0x8850, 0, {0x3e,0x40,0x0d,0x16,0x13,0x01,0x84,0xc8,0x20,0x3c,0x60,0x0f,0x90,0x12,0x04,0x00 }}, - {16, 0x8860, 0, {0xd9,0x40,0x32,0x50,0x0c,0x90,0x03,0x28,0x84,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8870, 0, {0x28,0x01,0x84,0x00,0xf9,0x00,0x36,0x40,0x4f,0x99,0x4a,0x44,0x00,0x99,0x00,0xb4 }}, - {16, 0x8880, 0, {0x40,0x0f,0x90,0x13,0xe6,0x00,0xf9,0x00,0x3c,0x40,0x0f,0x90,0x03,0xe3,0x00,0xf8 }}, - {16, 0x8890, 0, {0x01,0x36,0x40,0x0c,0x99,0x03,0xe4,0x02,0xf9,0x80,0x3e,0x60,0x4f,0x90,0x0b,0xca }}, - {16, 0x88a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x00,0x3c,0x00 }}, - {16, 0x88b0, 0, {0x1d,0x80,0x03,0x20,0x00,0xe8,0x00,0x32,0x00,0x0c,0x84,0x83,0xe0,0x10,0xe8,0x20 }}, - {16, 0x88c0, 0, {0x32,0x00,0x8e,0x84,0x03,0x21,0x80,0xc8,0x00,0x3a,0x19,0x0f,0x04,0x03,0xe0,0x24 }}, - {16, 0x88d0, 0, {0xf0,0x02,0x3c,0x00,0x0f,0x80,0x13,0x8a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x88e0, 0, {0x28,0x05,0x28,0x02,0x8a,0x01,0x0f,0xa2,0x68,0xa0,0x00,0x28,0x00,0x8a,0x00,0x77 }}, - {16, 0x88f0, 0, {0x80,0x68,0xe0,0x12,0xe8,0x00,0xde,0x00,0x36,0x81,0x08,0xe0,0x03,0x7a,0x08,0xae }}, - {16, 0x8900, 0, {0xc4,0x2f,0x80,0x08,0xed,0x02,0xfa,0x00,0xbe,0xa0,0x3b,0x80,0x0b,0xa0,0x42,0x0a }}, - {16, 0x8910, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x85,0x4c,0x00,0x93,0x00,0x2c,0xc0 }}, - {16, 0x8920, 0, {0x88,0xb0,0x02,0x0c,0x14,0xa3,0x04,0x20,0xc4,0x18,0x38,0x02,0xec,0x10,0x93,0x54 }}, - {16, 0x8930, 0, {0x28,0xc0,0x0a,0x00,0x02,0x4e,0x00,0x83,0x49,0x68,0xc0,0x02,0x39,0x42,0xce,0x40 }}, - {16, 0x8940, 0, {0xb3,0x00,0x2c,0xe6,0x0b,0xb0,0x02,0x8b,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8950, 0, {0x20,0x01,0x1c,0x08,0x87,0x20,0x2c,0x80,0x18,0xf2,0x22,0x1c,0x00,0x87,0x10,0x21 }}, - {16, 0x8960, 0, {0xc0,0x08,0x70,0x82,0xdc,0x80,0x96,0x80,0x2d,0xc0,0x0a,0x40,0x02,0x7d,0x40,0x27 }}, - {16, 0x8970, 0, {0x64,0x6d,0xd0,0x48,0x60,0x42,0xd8,0x05,0xb6,0x04,0x29,0xc0,0x4b,0x72,0x02,0x28 }}, - {16, 0x8980, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x3e,0x88,0xd7,0xe0,0x3d,0xe0 }}, - {16, 0x8990, 0, {0x08,0x7c,0x42,0x3e,0x00,0xe3,0x82,0x20,0xe0,0x0c,0x68,0x03,0xdf,0x04,0xd7,0x80 }}, - {16, 0x89a0, 0, {0x3b,0xe0,0x4e,0x48,0x0a,0x5e,0x80,0xc7,0xc2,0x19,0xe0,0x0e,0x78,0x03,0xd6,0x08 }}, - {16, 0x89b0, 0, {0xf7,0x80,0x3d,0xe0,0x0f,0xf8,0x03,0xaa,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x89c0, 0, {0x08,0x1d,0xac,0x40,0xfb,0x40,0x7e,0x80,0x0e,0x36,0x83,0xed,0x40,0xdb,0x60,0x3e }}, - {16, 0x89d0, 0, {0x80,0x0f,0xa0,0x03,0xed,0x28,0xda,0x00,0x32,0xc4,0x0c,0xb0,0x0b,0xcc,0x00,0xfb }}, - {16, 0x89e0, 0, {0x00,0x3e,0xc0,0x0e,0x80,0x13,0xe0,0x10,0xf8,0x00,0x3e,0x00,0x0f,0xb1,0x53,0xc2 }}, - {16, 0x89f0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xff,0xc0,0x33,0xe0 }}, - {16, 0x8a00, 0, {0x0c,0xf9,0x03,0x7f,0x04,0xcf,0xd0,0x3f,0xe4,0x0f,0xb8,0x03,0xfe,0x00,0xff,0x94 }}, - {16, 0x8a10, 0, {0x3f,0xe0,0x0f,0xc8,0x03,0x7e,0x10,0xf3,0x80,0x3b,0xe0,0x0f,0xf8,0x03,0xfe,0x48 }}, - {16, 0x8a20, 0, {0xed,0x80,0x33,0x24,0x04,0xf8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8a30, 0, {0xa8,0x11,0x9c,0x80,0xbf,0x04,0x21,0x28,0x08,0xf8,0x02,0x1e,0xc0,0xcf,0x90,0x21 }}, - {16, 0x8a40, 0, {0x4c,0x0b,0x5a,0x42,0xde,0x00,0xb7,0x80,0x2c,0xe8,0x0b,0x04,0x02,0x1c,0x00,0xb7 }}, - {16, 0x8a50, 0, {0xa0,0x35,0x10,0x8f,0x71,0x13,0xde,0xc0,0x84,0x10,0x21,0x80,0x0d,0x71,0x02,0x2a }}, - {16, 0x8a60, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x9c,0x08,0xb7,0x00,0x25,0xc8 }}, - {16, 0x8a70, 0, {0x08,0x71,0x02,0xcc,0x80,0x97,0x00,0x29,0xc0,0x8b,0x72,0x06,0xdc,0x08,0xb5,0x00 }}, - {16, 0x8a80, 0, {0x2d,0xc8,0x0b,0x40,0x02,0x1c,0x40,0xbf,0x10,0x21,0xc0,0x0b,0x74,0x02,0xd4,0x80 }}, - {16, 0x8a90, 0, {0xa7,0x40,0x21,0x41,0x08,0x70,0x02,0x04,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8aa0, 0, {0x60,0x14,0xcc,0x00,0xb3,0x00,0x24,0x00,0x08,0x34,0x82,0xac,0x11,0x83,0x00,0x20 }}, - {16, 0x8ab0, 0, {0x00,0x4b,0x18,0x26,0xcf,0x20,0xb1,0x06,0x2c,0xc1,0x0b,0x32,0x02,0x0e,0x08,0xb3 }}, - {16, 0x8ac0, 0, {0x88,0x24,0x32,0x0a,0x30,0x12,0x84,0x08,0x80,0x00,0xa0,0x34,0x28,0x30,0x02,0x18 }}, - {16, 0x8ad0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbc,0x00,0xff,0x00,0xb6,0x40 }}, - {16, 0x8ae0, 0, {0x2c,0xf4,0x43,0xfc,0x01,0xdf,0x00,0x3a,0x00,0x03,0x92,0x03,0xff,0x88,0xf9,0x00 }}, - {16, 0x8af0, 0, {0x2f,0xc0,0x1b,0x0e,0x4b,0x2e,0x90,0xfb,0xe0,0x30,0x32,0x0b,0x98,0x02,0xec,0x08 }}, - {16, 0x8b00, 0, {0x6b,0xc0,0x32,0xc0,0x08,0xf0,0x09,0x3e,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8b10, 0, {0x80,0x00,0xec,0x00,0xf3,0x00,0x3a,0xc0,0x0f,0xb0,0x01,0x6c,0x00,0xfb,0x00,0x3a }}, - {16, 0x8b20, 0, {0x10,0x0f,0xb4,0x03,0xec,0x00,0xf0,0x00,0x3c,0xc0,0x0f,0x80,0x0b,0xad,0x20,0xfb }}, - {16, 0x8b30, 0, {0x40,0x3e,0x10,0x07,0xa8,0x63,0xe0,0x00,0xfb,0x80,0x3e,0xd8,0x0f,0xb0,0x03,0xe0 }}, - {16, 0x8b40, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x00,0x72,0x00 }}, - {16, 0x8b50, 0, {0x0f,0xf0,0x23,0xfc,0x00,0xdf,0x00,0x3f,0x40,0x0f,0xc0,0x03,0xdc,0x00,0x8f,0x00 }}, - {16, 0x8b60, 0, {0x33,0xc1,0x0c,0xc0,0x03,0xbe,0x00,0xff,0x90,0x3b,0x28,0x0e,0x59,0x03,0x2e,0x00 }}, - {16, 0x8b70, 0, {0x7b,0x00,0x32,0xc4,0x0f,0xb0,0x03,0xd0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8b80, 0, {0xc1,0x04,0x6c,0x00,0xbb,0x00,0x62,0xa0,0x0f,0xb0,0x02,0xec,0x09,0x8b,0x00,0x2e }}, - {16, 0x8b90, 0, {0x30,0x0b,0xa8,0x03,0xac,0x00,0xfa,0xc1,0x22,0xc1,0x08,0x8c,0x02,0x2c,0x00,0xb3 }}, - {16, 0x8ba0, 0, {0x81,0x2a,0x00,0x0d,0x88,0xb2,0x22,0x00,0xb3,0xc0,0x22,0xc8,0x0b,0xb0,0x42,0x61 }}, - {16, 0x8bb0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x6c,0x00,0xbb,0x01,0x22,0x62 }}, - {16, 0x8bc0, 0, {0x0b,0xb0,0x02,0xec,0x04,0x8b,0x00,0x2e,0xa2,0x49,0x88,0x26,0xec,0x00,0xa8,0x80 }}, - {16, 0x8bd0, 0, {0x22,0xc0,0x28,0x82,0x0a,0xac,0xa0,0xbb,0x08,0x22,0xc0,0x08,0x80,0x0a,0x28,0x84 }}, - {16, 0x8be0, 0, {0xb9,0xc0,0xa2,0x00,0x0b,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8bf0, 0, {0x08,0x04,0x0c,0x00,0xb3,0x10,0x20,0x48,0x0a,0x32,0x02,0xcc,0x80,0x83,0x01,0x24 }}, - {16, 0x8c00, 0, {0x00,0x0b,0x02,0x06,0x8c,0x60,0xa0,0x20,0x20,0xc8,0x08,0x01,0x02,0x0c,0x00,0xb3 }}, - {16, 0x8c10, 0, {0x00,0x28,0x00,0x09,0x20,0x02,0x08,0x80,0xb1,0x00,0xa0,0x80,0x0b,0x30,0x02,0x42 }}, - {16, 0x8c20, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x6c,0x00,0xff,0x00,0xa2,0x0e }}, - {16, 0x8c30, 0, {0x0b,0xf1,0x03,0xfc,0x08,0xcf,0x20,0x3e,0xc0,0x0f,0x80,0x03,0xfc,0x84,0xa8,0x20 }}, - {16, 0x8c40, 0, {0xb2,0xc8,0x8c,0x80,0x03,0xac,0x44,0xfb,0x70,0x3a,0xc0,0x0e,0x90,0x03,0x2c,0xa4 }}, - {16, 0x8c50, 0, {0xfb,0x00,0xb2,0x40,0x0f,0xb0,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8c60, 0, {0xa0,0x1d,0xfc,0x00,0xff,0x26,0x3e,0x00,0x0f,0xb6,0x13,0xed,0x00,0xfb,0x10,0x3f }}, - {16, 0x8c70, 0, {0x00,0x0f,0xc1,0x13,0xac,0x80,0xf8,0x12,0x3e,0xc6,0x4f,0x42,0x43,0xfc,0x04,0xff }}, - {16, 0x8c80, 0, {0x31,0x3f,0x00,0x0f,0xf0,0x03,0xec,0x00,0xff,0x00,0xbf,0xc0,0x8f,0xf0,0x03,0xe8 }}, - {16, 0x8c90, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x40,0xfc,0x80,0x36,0xc8 }}, - {16, 0x8ca0, 0, {0x0f,0x09,0x03,0xc2,0x00,0xf8,0xc0,0x33,0xcc,0x2c,0x4c,0x03,0x63,0x90,0xe0,0x90 }}, - {16, 0x8cb0, 0, {0x3a,0xc0,0x0d,0x50,0x0b,0x3c,0x04,0xdf,0x64,0x3f,0xc8,0x8d,0xf1,0x43,0x2c,0x00 }}, - {16, 0x8cc0, 0, {0xd5,0x00,0x33,0xc0,0x45,0xf2,0x23,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8cd0, 0, {0x80,0x10,0xed,0x80,0xba,0x02,0x21,0xde,0x8b,0x82,0x22,0xe0,0x20,0xb0,0x00,0x2b }}, - {16, 0x8ce0, 0, {0xec,0x09,0x80,0x02,0xe3,0x40,0xba,0x20,0x2f,0xdc,0x08,0x98,0x12,0x2c,0x00,0x8b }}, - {16, 0x8cf0, 0, {0x51,0x2a,0xd0,0x08,0x72,0x22,0x2e,0x00,0x8d,0x80,0x21,0xd0,0x08,0xb6,0x82,0x20 }}, - {16, 0x8d00, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x40,0xb9,0x28,0x24,0xc0 }}, - {16, 0x8d10, 0, {0x4a,0x12,0x12,0x88,0x85,0xa8,0x20,0x20,0xc0,0x0b,0x22,0x02,0xc0,0x91,0xa1,0x00 }}, - {16, 0x8d20, 0, {0x28,0xc2,0x0b,0x00,0x12,0x8c,0x40,0xa3,0x20,0x20,0xc4,0x0b,0x30,0x0a,0x0c,0x11 }}, - {16, 0x8d30, 0, {0x99,0x00,0x20,0xc5,0x09,0x01,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8d40, 0, {0xc0,0x11,0xac,0x00,0xb8,0x80,0x22,0xc0,0x0b,0x88,0x02,0xee,0x01,0xb8,0xc1,0x2a }}, - {16, 0x8d50, 0, {0xc0,0x1b,0xa8,0x06,0xe2,0x00,0xbb,0x80,0x2e,0xc0,0x8a,0x80,0x02,0xac,0x00,0xab }}, - {16, 0x8d60, 0, {0x00,0x2e,0xc0,0x0a,0xb0,0x02,0x2c,0x00,0x99,0x00,0x24,0xc0,0x08,0x80,0x02,0x30 }}, - {16, 0x8d70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xb0,0x80,0x36,0xc0 }}, - {16, 0x8d80, 0, {0x0e,0xa8,0x13,0xe2,0x85,0xf3,0xc0,0x32,0xc0,0x0e,0x9c,0x23,0xe7,0x24,0xe8,0x82 }}, - {16, 0x8d90, 0, {0x3a,0xc1,0x0f,0x94,0x03,0xac,0x02,0xeb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x2e,0x10 }}, - {16, 0x8da0, 0, {0x51,0x00,0xb2,0xc0,0x0d,0xb0,0x03,0x50,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8db0, 0, {0xe0,0x01,0xbc,0x00,0xff,0x00,0x3f,0xc0,0x8f,0xd0,0x03,0xf0,0x04,0xfd,0x04,0x3f }}, - {16, 0x8dc0, 0, {0xc0,0x4c,0xc0,0x03,0xf0,0x10,0xfc,0x00,0x1f,0xc0,0x0d,0xd1,0x23,0x1c,0x00,0xc7 }}, - {16, 0x8dd0, 0, {0x00,0x39,0xc0,0x0d,0xf0,0x83,0xfe,0x44,0xed,0x00,0x3b,0xc0,0x0f,0x74,0x03,0xf8 }}, - {16, 0x8de0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xf9,0x01,0xba,0xc1 }}, - {16, 0x8df0, 0, {0x0c,0xb0,0x03,0xa1,0x08,0xfa,0x00,0x30,0xc8,0x8f,0x94,0x03,0x25,0x00,0xf9,0x00 }}, - {16, 0x8e00, 0, {0x3c,0xc0,0x0f,0x04,0x83,0xec,0x00,0xfb,0x00,0x3e,0xe0,0x0f,0x71,0x0b,0x2c,0x40 }}, - {16, 0x8e10, 0, {0xfd,0x08,0x37,0xc0,0x4e,0x91,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8e20, 0, {0xc8,0x05,0x3c,0x00,0xb9,0x00,0x23,0xc0,0x08,0x90,0x02,0x24,0x00,0xc8,0x00,0x37 }}, - {16, 0x8e30, 0, {0xf0,0x0b,0x80,0x01,0x64,0x00,0x49,0x02,0x33,0xc0,0x84,0x9c,0x03,0x3c,0x00,0xbf }}, - {16, 0x8e40, 0, {0x02,0x0f,0xd0,0x08,0xf4,0x02,0x0e,0x10,0xbd,0x80,0x33,0xe0,0x08,0x90,0x0a,0x32 }}, - {16, 0x8e50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb0,0x06,0x20,0xc0 }}, - {16, 0x8e60, 0, {0x08,0x00,0x42,0x84,0x00,0xa0,0x00,0x20,0xf0,0x0b,0x00,0x22,0xcc,0x00,0x90,0x00 }}, - {16, 0x8e70, 0, {0x28,0xc0,0x02,0x3d,0x02,0x8c,0x00,0xb3,0x00,0x2c,0xc2,0x9a,0x38,0x02,0x06,0x04 }}, - {16, 0x8e80, 0, {0xb1,0x12,0x20,0xe0,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8e90, 0, {0x20,0x01,0x1e,0x00,0xb6,0x80,0x21,0xe0,0x28,0xea,0x02,0x36,0x80,0x86,0x90,0x65 }}, - {16, 0x8ea0, 0, {0xe0,0x1b,0xda,0x06,0x5e,0x01,0x9e,0x84,0x25,0xec,0x0a,0x78,0x02,0x5e,0x00,0xb7 }}, - {16, 0x8eb0, 0, {0x80,0x2d,0xe0,0x08,0x79,0x4a,0x16,0x40,0xbd,0x80,0x25,0xe0,0x08,0x38,0x02,0x08 }}, - {16, 0x8ec0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xfb,0x00,0x28,0xe0 }}, - {16, 0x8ed0, 0, {0x08,0x18,0x02,0x8a,0x88,0xa1,0xa0,0x20,0xc2,0x1f,0x2a,0x23,0xe6,0xc8,0xf0,0xc0 }}, - {16, 0x8ee0, 0, {0x3a,0xed,0x4e,0x34,0x02,0x8c,0x08,0xf3,0x81,0x1e,0xc0,0x0e,0x30,0x03,0x0e,0xc0 }}, - {16, 0x8ef0, 0, {0xf1,0x00,0xb0,0xca,0x0e,0x21,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8f00, 0, {0x40,0x1d,0xbc,0x08,0xfe,0x10,0x3f,0xd2,0x0f,0xe0,0x03,0xec,0x04,0xff,0x14,0x7e }}, - {16, 0x8f10, 0, {0xc0,0x0f,0xb1,0x23,0xfc,0x01,0xee,0x00,0x3a,0xc4,0x0d,0xb0,0x13,0xbc,0x00,0xff }}, - {16, 0x8f20, 0, {0x00,0x3f,0xc0,0x0e,0xf0,0x83,0xfc,0x0c,0xfd,0x10,0x3b,0xc0,0x2f,0xe1,0x03,0xd0 }}, - {16, 0x8f30, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x40,0xf0,0x80,0x32,0xd0 }}, - {16, 0x8f40, 0, {0x0c,0xa0,0x03,0x6c,0x00,0xf3,0x80,0x32,0xda,0x0f,0xb0,0x03,0xec,0x00,0xfb,0x00 }}, - {16, 0x8f50, 0, {0x3e,0xcc,0x4c,0x98,0x13,0x2c,0x10,0xfb,0x04,0x3e,0xc4,0x0c,0xf2,0x83,0xa6,0x10 }}, - {16, 0x8f60, 0, {0xdd,0x20,0x3f,0xd1,0x0c,0xb0,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8f70, 0, {0x48,0x11,0x9c,0x80,0xb7,0x00,0x21,0xc8,0x0c,0x70,0x02,0xdc,0x08,0xb7,0x00,0x21 }}, - {16, 0x8f80, 0, {0xc8,0x0e,0x70,0x22,0xd8,0x00,0xb7,0x00,0x2c,0xc2,0x0a,0x70,0x0a,0x1f,0x08,0xb7 }}, - {16, 0x8f90, 0, {0x00,0x39,0xc8,0x0a,0x70,0x02,0x14,0x00,0xc5,0x69,0x2c,0xca,0x2a,0x70,0x02,0xd2 }}, - {16, 0x8fa0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xbf,0x81,0x64,0xe1 }}, - {16, 0x8fb0, 0, {0x08,0x78,0x02,0x5a,0x01,0xbf,0x80,0x21,0xec,0x4b,0x78,0x46,0x9f,0x08,0x37,0x80 }}, - {16, 0x8fc0, 0, {0x2d,0xe8,0x88,0x18,0x02,0x1e,0x81,0xb7,0xb0,0x2d,0xe0,0x09,0x7a,0x02,0x8e,0x00 }}, - {16, 0x8fd0, 0, {0x95,0xa0,0x2d,0xe4,0x08,0x78,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8fe0, 0, {0x48,0x14,0xec,0x00,0xb3,0x60,0x20,0xc0,0x08,0xb6,0x02,0xcc,0x00,0xb3,0x01,0x20 }}, - {16, 0x8ff0, 0, {0xc0,0x8a,0xb0,0x86,0xcf,0x00,0xbb,0x10,0x6c,0xc1,0x0a,0x38,0x02,0x0c,0x01,0xb3 }}, - {16, 0x9000, 0, {0x02,0x28,0xc0,0x0b,0xb0,0x0a,0x0c,0x00,0x81,0x00,0x2e,0xc0,0x0a,0xb4,0x82,0xd2 }}, - {16, 0x9010, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0x40,0xb6,0x80 }}, - {16, 0x9020, 0, {0x0c,0xe4,0x03,0x78,0x80,0xfe,0x74,0x32,0x80,0x0b,0xe6,0x03,0xf9,0x00,0xfe,0x00 }}, - {16, 0x9030, 0, {0x3e,0x80,0x0c,0xe0,0x03,0x28,0x00,0xfa,0x00,0x3e,0x80,0x4d,0xa0,0x03,0xa8,0x00 }}, - {16, 0x9040, 0, {0xda,0x04,0x3e,0x80,0x0c,0xe4,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9050, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x2e,0x80,0x23,0xe0,0x00,0xf8,0x01,0x3c }}, - {16, 0x9060, 0, {0x00,0x0e,0x80,0x03,0xe0,0x20,0xf8,0x20,0x3e,0x01,0x8f,0x89,0x03,0xe0,0x00,0xf8 }}, - {16, 0x9070, 0, {0x00,0x3a,0x10,0x0e,0x80,0x01,0xe0,0x00,0xe8,0x40,0x7e,0x00,0x4f,0x80,0x03,0xd2 }}, - {16, 0x9080, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x01,0x7e,0x40 }}, - {16, 0x9090, 0, {0x2c,0x90,0x0b,0x24,0x00,0xf9,0x00,0x3e,0x68,0x05,0x90,0x13,0xa4,0x04,0xd9,0x00 }}, - {16, 0x90a0, 0, {0x32,0x41,0x0e,0x91,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x60,0x0e,0x90,0x03,0x24,0x00 }}, - {16, 0x90b0, 0, {0xf1,0x00,0x32,0x40,0x68,0x90,0x43,0x82,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x90c0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x6e,0x40,0x08,0x90,0x42,0x24,0x00,0xb9,0x00,0x2e }}, - {16, 0x90d0, 0, {0x70,0x88,0x90,0x03,0x24,0x00,0xb9,0x00,0x22,0x40,0x08,0x98,0x12,0xe4,0x00,0xb9 }}, - {16, 0x90e0, 0, {0x00,0x2e,0x40,0x0a,0x90,0x0a,0x26,0x00,0xb9,0x80,0xa2,0x40,0x08,0x90,0x12,0x20 }}, - {16, 0x90f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x04,0x2c,0x40 }}, - {16, 0x9100, 0, {0x08,0x90,0x02,0x24,0x01,0xb9,0x00,0x2a,0x40,0x0b,0xb0,0x02,0xa4,0x01,0xb9,0x00 }}, - {16, 0x9110, 0, {0xe0,0x40,0x0a,0x90,0x82,0xa4,0x00,0xb9,0x00,0x2c,0x48,0x0a,0x98,0x02,0x24,0x80 }}, - {16, 0x9120, 0, {0x39,0x20,0x22,0x40,0x2a,0x90,0x02,0x86,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9130, 0, {0x08,0x04,0x04,0x80,0x81,0x00,0x2c,0x48,0x08,0x10,0x12,0x04,0x10,0xb1,0x04,0x2c }}, - {16, 0x9140, 0, {0xd8,0x0a,0x10,0x02,0x04,0x00,0xb1,0x00,0x20,0x48,0x08,0x10,0x02,0xc4,0x80,0xb1 }}, - {16, 0x9150, 0, {0x22,0x2c,0x50,0x8a,0x32,0x82,0x05,0xa0,0xb1,0x2a,0x20,0x4a,0x0a,0x12,0x82,0x02 }}, - {16, 0x9160, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x50,0xc8,0x52,0x2e,0x14 }}, - {16, 0x9170, 0, {0x0c,0x85,0x03,0x21,0x40,0xf8,0x50,0x3a,0x00,0x1f,0x85,0x03,0xa1,0x40,0xf8,0x50 }}, - {16, 0x9180, 0, {0x32,0x14,0x0e,0x80,0x03,0xa1,0x40,0xf8,0x50,0x3c,0x80,0x0e,0x02,0x03,0x20,0x80 }}, - {16, 0x9190, 0, {0xfa,0x20,0x32,0x08,0x0e,0x82,0x13,0xae,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x91a0, 0, {0x98,0x1d,0xe4,0x50,0xfd,0x00,0x3e,0x44,0x0f,0xd0,0x03,0xf4,0x00,0xfd,0x00,0x3e }}, - {16, 0x91b0, 0, {0x44,0x8d,0xd0,0x01,0xbd,0x00,0xfd,0x02,0x3e,0x44,0x0f,0xd4,0x00,0xe4,0x48,0x79 }}, - {16, 0x91c0, 0, {0x14,0x3e,0x50,0x0f,0x92,0xa2,0xf4,0x08,0xfd,0x00,0x3e,0x4a,0x0d,0xd2,0x83,0xe6 }}, - {16, 0x91d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe7,0x00,0xf9,0x10,0x3a,0x6e }}, - {16, 0x91e0, 0, {0x0c,0xb1,0x03,0xe4,0x40,0xf9,0x44,0x3b,0x61,0x8e,0x94,0x03,0xe4,0x00,0xe9,0x40 }}, - {16, 0x91f0, 0, {0x32,0x66,0x0f,0xda,0x0b,0xa7,0x28,0xc9,0xe0,0x3f,0x68,0x0c,0xda,0x83,0xb3,0x20 }}, - {16, 0x9200, 0, {0xed,0xa0,0x33,0x79,0x08,0xd8,0x03,0x46,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9210, 0, {0x38,0x10,0xe2,0x00,0xb8,0xa0,0x2e,0x38,0x08,0x8a,0x02,0xe2,0x88,0xe8,0x81,0x2e }}, - {16, 0x9220, 0, {0x14,0x09,0x0a,0x03,0xe2,0x80,0xb8,0x80,0x32,0x30,0x0b,0x85,0x02,0x21,0x01,0xa8 }}, - {16, 0x9230, 0, {0xf4,0x38,0x2a,0x08,0x0e,0xca,0x23,0x90,0xc8,0x54,0x34,0x38,0x08,0x8a,0x92,0x0e }}, - {16, 0x9240, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x00,0x28,0x40 }}, - {16, 0x9250, 0, {0x19,0x10,0x02,0xc4,0x00,0xb1,0x20,0x28,0x40,0x0b,0x10,0x06,0xc4,0x20,0xa1,0xa2 }}, - {16, 0x9260, 0, {0x6c,0x48,0x0b,0x10,0x02,0x84,0x08,0x81,0x20,0x2c,0x50,0x09,0x10,0x02,0xc4,0x04 }}, - {16, 0x9270, 0, {0xb1,0x00,0x24,0x58,0x08,0x3c,0x02,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9280, 0, {0x18,0x15,0xa4,0x01,0xb9,0x20,0x2c,0x40,0x09,0x90,0x02,0xe4,0x10,0xa9,0x40,0x2e }}, - {16, 0x9290, 0, {0x40,0x0b,0x90,0x02,0xa4,0x00,0xb1,0x01,0x2a,0x40,0x0b,0x94,0x02,0x24,0x00,0xa9 }}, - {16, 0x92a0, 0, {0x00,0x2a,0x40,0x01,0x10,0x52,0x64,0x00,0x89,0x00,0x26,0x40,0x00,0x98,0x02,0x46 }}, - {16, 0x92b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x61,0x3a,0x40 }}, - {16, 0x92c0, 0, {0x0d,0x90,0x83,0xe5,0x20,0xf9,0x01,0x3a,0x40,0x2e,0x90,0x02,0xe4,0x40,0xe9,0x01 }}, - {16, 0x92d0, 0, {0x9e,0x40,0x0f,0x94,0x03,0xa4,0x00,0x89,0x00,0x3e,0x40,0x2d,0x90,0x02,0xe6,0x08 }}, - {16, 0x92e0, 0, {0xb9,0x01,0x36,0x40,0x2c,0x90,0x01,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x92f0, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x40,0x2e,0x90,0x03,0xe4,0x80,0xf9,0x00,0x3c }}, - {16, 0x9300, 0, {0x40,0x0c,0x9c,0x23,0xe4,0x00,0xf9,0x00,0x36,0x40,0x0f,0x10,0x43,0x84,0x00,0xf9 }}, - {16, 0x9310, 0, {0x02,0x3e,0x40,0x0e,0x90,0x03,0x80,0x80,0xf9,0x00,0x3c,0x40,0x2f,0x90,0x03,0x8a }}, - {16, 0x9320, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x40,0x36,0x01 }}, - {16, 0x9330, 0, {0x0d,0x84,0x03,0xe1,0x00,0xe8,0x40,0x3e,0x08,0x0c,0x80,0x03,0xe1,0x00,0xf8,0x00 }}, - {16, 0x9340, 0, {0x32,0x00,0x8f,0x80,0x03,0xa0,0x10,0xf8,0x00,0x32,0x04,0x0e,0x80,0x83,0x60,0x00 }}, - {16, 0x9350, 0, {0xf8,0x00,0x3e,0x00,0x0c,0x00,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9360, 0, {0x28,0x05,0x28,0x00,0x8a,0x01,0x22,0x80,0x08,0xa0,0x24,0xe8,0x00,0x0a,0x00,0x2f }}, - {16, 0x9370, 0, {0x80,0x1a,0xa0,0x02,0x28,0x00,0xba,0x00,0x16,0x80,0x0b,0xe0,0x03,0x28,0x08,0xea }}, - {16, 0x9380, 0, {0x00,0x33,0x90,0x08,0xec,0x1b,0x22,0x80,0xc6,0x14,0x2f,0x91,0x08,0xa0,0x43,0x4a }}, - {16, 0x9390, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x93,0x00,0x24,0xc0 }}, - {16, 0x93a0, 0, {0x09,0x30,0x12,0xcc,0x04,0xa3,0x04,0x6c,0xc0,0x09,0x30,0x02,0x8c,0x00,0xb3,0x00 }}, - {16, 0x93b0, 0, {0x2c,0xc0,0x13,0x30,0x02,0x8c,0x00,0xb3,0x00,0xe6,0xb8,0x0a,0x38,0x02,0x44,0x08 }}, - {16, 0x93c0, 0, {0x82,0x50,0x2c,0xd2,0x3a,0x30,0x02,0x8a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x93d0, 0, {0xa0,0x01,0x0e,0x80,0x97,0xb4,0x21,0xc4,0x49,0x71,0x02,0xde,0x81,0x87,0x21,0x2d }}, - {16, 0x93e0, 0, {0xd0,0x0b,0x7b,0x02,0x1c,0x01,0xbf,0x20,0x29,0xc4,0x0b,0x30,0x02,0x5c,0x00,0xa7 }}, - {16, 0x93f0, 0, {0xa1,0x21,0xc0,0x4a,0x70,0x8a,0x0c,0x81,0x84,0x00,0x2d,0xd0,0x0a,0x50,0x02,0xe8 }}, - {16, 0x9400, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x82,0xdf,0xa0,0x34,0xec }}, - {16, 0x9410, 0, {0x0d,0x79,0x02,0xfe,0x80,0xe7,0xe8,0x2f,0xa0,0x09,0x7a,0x02,0x9e,0x00,0xf7,0xa2 }}, - {16, 0x9420, 0, {0x25,0xea,0x0b,0x48,0x03,0x9e,0x04,0xff,0xc0,0x65,0xe4,0x0e,0x68,0x03,0x5f,0x00 }}, - {16, 0x9430, 0, {0xe4,0x80,0x3d,0xe0,0x0e,0xf8,0x03,0xaa,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9440, 0, {0x08,0x1d,0xac,0x48,0xeb,0x05,0x3e,0xd9,0x0e,0xb2,0x03,0xec,0x00,0xfb,0x60,0x3e }}, - {16, 0x9450, 0, {0xc0,0x0e,0xb2,0x83,0xac,0x00,0xf3,0x50,0xa6,0xc0,0x4f,0xb0,0x03,0xac,0x00,0xfb }}, - {16, 0x9460, 0, {0x80,0x3f,0xd8,0x0d,0xa0,0x03,0xec,0x0a,0xf9,0x00,0x3e,0xc0,0x0d,0x90,0x03,0x42 }}, - {16, 0x9470, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xbb,0x90,0x3e,0xe0 }}, - {16, 0x9480, 0, {0x08,0x39,0x03,0x9e,0x20,0xcf,0x82,0x77,0xe0,0x1f,0xf8,0x03,0xee,0x00,0xff,0xc0 }}, - {16, 0x9490, 0, {0x3f,0xe5,0x0d,0xf9,0x03,0xee,0x00,0xfb,0x90,0x37,0xa0,0x08,0xf8,0x0f,0x1e,0x00 }}, - {16, 0x94a0, 0, {0xcc,0x94,0x33,0x60,0x0d,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x94b0, 0, {0xa8,0x11,0x9c,0x00,0xb7,0x90,0x2f,0xe4,0x08,0x7a,0x02,0x1e,0x00,0x8f,0x12,0x25 }}, - {16, 0x94c0, 0, {0xd8,0x0b,0xbb,0x02,0x1e,0x00,0xb7,0x00,0x2d,0xe8,0x08,0x7d,0x82,0xde,0x40,0xbb }}, - {16, 0x94d0, 0, {0xa0,0x27,0x90,0x0a,0x76,0x02,0x5c,0x80,0x85,0x00,0x37,0xc4,0x4d,0x71,0x03,0xea }}, - {16, 0x94e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xb7,0x20,0x2d,0xc0 }}, - {16, 0x94f0, 0, {0x29,0xf2,0x22,0xbc,0x80,0x97,0x00,0x25,0x41,0x0b,0x70,0x12,0x9c,0x00,0xb7,0x08 }}, - {16, 0x9500, 0, {0x29,0xc0,0x08,0x42,0x12,0xdc,0x40,0xb7,0x00,0x29,0xc0,0x09,0x60,0x22,0xdc,0x10 }}, - {16, 0x9510, 0, {0x80,0x00,0x21,0x40,0x09,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9520, 0, {0x20,0x14,0xcc,0x00,0xb3,0xc0,0x2e,0xc0,0x08,0x34,0x82,0x2d,0x00,0x93,0x00,0x24 }}, - {16, 0x9530, 0, {0xc0,0x0b,0x30,0x02,0x0f,0x80,0x13,0x00,0x2c,0xc0,0x0a,0x34,0xa2,0xec,0x00,0xb3 }}, - {16, 0x9540, 0, {0x00,0x28,0xc0,0x0b,0x00,0x02,0xcc,0x00,0x81,0x00,0x20,0xc0,0x09,0x30,0x02,0x89 }}, - {16, 0x9550, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbc,0x00,0xff,0xe0,0x3f,0xc0 }}, - {16, 0x9560, 0, {0x0c,0xf4,0x83,0xbd,0x00,0xdf,0x08,0x36,0x40,0x0b,0x75,0x42,0xfc,0x20,0xff,0x80 }}, - {16, 0x9570, 0, {0x3b,0xc0,0x2c,0x3c,0x03,0xfc,0x00,0xbf,0x00,0xbe,0xc0,0x8d,0x90,0x0b,0xac,0x02 }}, - {16, 0x9580, 0, {0xca,0x00,0x22,0x80,0x0d,0xb0,0x02,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9590, 0, {0x80,0x00,0xec,0x00,0xfb,0x08,0x1e,0xc0,0x0f,0xb0,0x13,0xec,0x00,0xeb,0x00,0x3a }}, - {16, 0x95a0, 0, {0x10,0x0f,0xb0,0x23,0xac,0x01,0xfb,0x00,0x3e,0xc0,0x3c,0x84,0x03,0xec,0x00,0xfb }}, - {16, 0x95b0, 0, {0x00,0x26,0x40,0x0e,0x94,0x0b,0x2c,0x00,0xf9,0x40,0x3e,0x90,0x0e,0x90,0x13,0xe0 }}, - {16, 0x95c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x02,0xcf,0x00,0x3f,0xc0 }}, - {16, 0x95d0, 0, {0x0d,0xf0,0x0b,0x3c,0x20,0xcf,0x00,0x3d,0x00,0x0e,0xf0,0x07,0x9c,0x01,0xcf,0x02 }}, - {16, 0x95e0, 0, {0x3e,0xc0,0x0f,0xc4,0x03,0x3c,0x00,0xcf,0x00,0x0f,0xc0,0x0e,0x44,0x03,0x1f,0x02 }}, - {16, 0x95f0, 0, {0xcc,0x00,0x3f,0x80,0x2c,0x70,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9600, 0, {0x81,0x04,0x6c,0x00,0x8b,0x02,0x2e,0xc0,0x0d,0xb0,0x02,0x2c,0x00,0xab,0x00,0x06 }}, - {16, 0x9610, 0, {0x20,0x08,0xb0,0x03,0xfc,0x00,0xab,0x00,0x2e,0xc0,0x0f,0x80,0x06,0xbc,0x00,0xab }}, - {16, 0x9620, 0, {0x04,0x3a,0xf0,0x0c,0x88,0x02,0x2c,0x00,0xc9,0x80,0x3a,0x92,0x08,0x90,0x0a,0xa0 }}, - {16, 0x9630, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xab,0x00,0x2e,0xc0 }}, - {16, 0x9640, 0, {0x09,0x30,0x02,0x2c,0x00,0x8b,0x00,0x26,0x60,0x0b,0xb0,0x02,0xac,0x00,0x8b,0x00 }}, - {16, 0x9650, 0, {0x6e,0xc0,0x0b,0xb0,0x42,0x2c,0x00,0x9b,0x00,0x4c,0xe0,0x0a,0x90,0x22,0x2c,0x00 }}, - {16, 0x9660, 0, {0x8a,0xc2,0x2c,0x40,0x08,0xb0,0x42,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9670, 0, {0x08,0x04,0x0c,0x00,0x83,0x0d,0x2c,0xc6,0x09,0x31,0x02,0x0d,0x81,0xa3,0x11,0x24 }}, - {16, 0x9680, 0, {0x00,0x8a,0xb1,0xe2,0x4c,0x80,0xa3,0x00,0x2c,0xcc,0x0b,0x02,0x02,0x8c,0x80,0xa3 }}, - {16, 0x9690, 0, {0x48,0x08,0xc0,0x08,0x00,0x0a,0x0d,0x00,0x81,0x00,0x28,0xc0,0x08,0x30,0x02,0x82 }}, - {16, 0x96a0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xcb,0x20,0x2f,0xc8 }}, - {16, 0x96b0, 0, {0x8d,0xf6,0x13,0x2d,0xb0,0x8f,0x00,0x36,0x40,0x0f,0xf0,0x02,0xad,0xa8,0x8f,0x10 }}, - {16, 0x96c0, 0, {0x3f,0xca,0x0b,0x80,0x92,0x2c,0x10,0xdb,0x40,0x3f,0xc0,0x0e,0x00,0x03,0x2d,0x04 }}, - {16, 0x96d0, 0, {0xc8,0x02,0x3e,0x40,0x0c,0xb0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x96e0, 0, {0xa0,0x1d,0xfc,0x00,0xff,0x00,0x3f,0xc8,0x0e,0xf1,0x03,0xec,0x84,0xff,0x20,0x37 }}, - {16, 0x96f0, 0, {0x00,0x0d,0xb2,0x03,0xbc,0xa0,0xff,0x00,0x3e,0xc9,0x0e,0x80,0x03,0xfd,0x11,0xff }}, - {16, 0x9700, 0, {0x00,0x3b,0xc0,0x0e,0xc0,0x03,0xfc,0x80,0xed,0x00,0x3b,0xc0,0x0f,0xf0,0x43,0x68 }}, - {16, 0x9710, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x90,0xcc,0x92,0x3b,0xc8 }}, - {16, 0x9720, 0, {0x0d,0xf0,0x83,0x73,0x10,0xff,0x28,0x37,0xca,0x4f,0xb2,0x03,0xfc,0x00,0xdf,0x20 }}, - {16, 0x9730, 0, {0xb3,0xc4,0x0d,0x68,0x43,0xfe,0x14,0xcb,0x84,0x33,0xe0,0x0d,0x78,0x03,0xbe,0x00 }}, - {16, 0x9740, 0, {0xff,0x80,0x37,0xa0,0x0c,0xf3,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9750, 0, {0x80,0x00,0xfc,0x48,0x82,0x21,0x03,0xf4,0x0f,0xf6,0x42,0x20,0x04,0x8a,0x60,0x2b }}, - {16, 0x9760, 0, {0xda,0x0b,0xf9,0x02,0x3f,0x04,0x8f,0x52,0x23,0xd5,0x4d,0x88,0x02,0xae,0x00,0xdb }}, - {16, 0x9770, 0, {0x80,0x36,0xc0,0x08,0x80,0x02,0x20,0x04,0xb8,0x00,0x22,0x60,0x0d,0x74,0x03,0xe0 }}, - {16, 0x9780, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0xa0,0x80,0x01,0x08,0xc0 }}, - {16, 0x9790, 0, {0x4b,0x30,0x82,0x42,0x90,0xa3,0x08,0x2c,0xc8,0x1a,0x30,0x22,0x8d,0x00,0x93,0x00 }}, - {16, 0x97a0, 0, {0x24,0xc8,0x09,0xa0,0x12,0x0c,0x04,0xab,0x00,0x62,0xc0,0x09,0xb0,0x02,0xcc,0x00 }}, - {16, 0x97b0, 0, {0xb3,0x00,0x28,0x80,0x08,0x36,0x06,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x97c0, 0, {0xc0,0x15,0xac,0x00,0x88,0x08,0x22,0xc0,0x0a,0x30,0x1a,0x00,0x11,0x82,0x00,0x0a }}, - {16, 0x97d0, 0, {0xc0,0x0b,0xb0,0x42,0x2c,0x00,0x8b,0x00,0x26,0xc0,0x09,0x91,0x02,0xec,0x20,0xbb }}, - {16, 0x97e0, 0, {0x28,0x66,0xc0,0x08,0x80,0x02,0x60,0x00,0xb8,0x00,0x2a,0x40,0x81,0xb0,0x06,0xf8 }}, - {16, 0x97f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xec,0x02,0xc8,0x04,0x3a,0xc0 }}, - {16, 0x9800, 0, {0x89,0xb0,0x03,0x68,0x00,0xe9,0xc1,0x1e,0xc1,0x0e,0x30,0x03,0xec,0x00,0xdb,0x00 }}, - {16, 0x9810, 0, {0x36,0xc1,0x0d,0x00,0x23,0x0e,0x00,0xeb,0x80,0x32,0xc8,0xcd,0x30,0x32,0xec,0x08 }}, - {16, 0x9820, 0, {0xf3,0x00,0x3c,0x80,0x0c,0xb0,0x06,0x80,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9830, 0, {0xe0,0x01,0x9c,0x00,0x7c,0x00,0x3f,0xc0,0x0b,0xb0,0x43,0xfd,0x00,0xbe,0xc4,0x37 }}, - {16, 0x9840, 0, {0xc0,0x1f,0xf0,0x03,0x5c,0x00,0xff,0x01,0x3b,0xc0,0x0e,0xc8,0x03,0xbf,0x20,0xdf }}, - {16, 0x9850, 0, {0x00,0x3f,0xd0,0x0f,0xc0,0x13,0xb0,0x00,0x7c,0x00,0xb7,0x40,0x0f,0xf0,0x1b,0xb0 }}, - {16, 0x9860, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x0c,0xd8,0x41,0x32,0xc0 }}, - {16, 0x9870, 0, {0x0e,0xb0,0x07,0xa8,0x01,0x69,0x40,0xb2,0xc0,0x8d,0xb0,0xa3,0xec,0x08,0xf3,0x00 }}, - {16, 0x9880, 0, {0x32,0xc0,0x0f,0x80,0x03,0xed,0x00,0xfb,0x48,0x3a,0xc0,0x0d,0xb0,0x83,0x2c,0x00 }}, - {16, 0x9890, 0, {0xfb,0x20,0x3e,0x80,0x0f,0x70,0x23,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x98a0, 0, {0xc8,0x05,0x3c,0x00,0x88,0x00,0x23,0xc0,0x08,0xf0,0x06,0x2c,0x10,0x88,0x51,0x37 }}, - {16, 0x98b0, 0, {0xc0,0x08,0xf0,0x07,0x7d,0x60,0x8f,0x02,0x37,0xc0,0x0b,0x8c,0x00,0x2d,0x00,0xb3 }}, - {16, 0x98c0, 0, {0x00,0x38,0xc0,0x08,0x80,0x82,0x20,0x00,0xb8,0x00,0x2e,0x50,0x0b,0xf0,0x00,0x32 }}, - {16, 0x98d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x98,0x00,0x28,0xc0 }}, - {16, 0x98e0, 0, {0x0a,0x30,0x02,0x84,0x04,0xa3,0x00,0x00,0xc0,0x68,0x39,0x06,0x0c,0x10,0x93,0x20 }}, - {16, 0x98f0, 0, {0x22,0xc0,0x9b,0x01,0xa0,0x8f,0x14,0x33,0x14,0x28,0xc0,0x09,0x3c,0x02,0x0c,0x01 }}, - {16, 0x9900, 0, {0x93,0x40,0x2c,0x88,0x0b,0x30,0x02,0xb8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9910, 0, {0x60,0x01,0x1e,0x10,0x87,0x80,0x29,0xe0,0x08,0x78,0x02,0x3e,0x00,0x83,0x90,0x24 }}, - {16, 0x9920, 0, {0xe0,0x08,0x78,0x10,0xce,0x04,0x07,0x91,0x25,0xe0,0x83,0xc9,0x02,0x1e,0x04,0xb7 }}, - {16, 0x9930, 0, {0x84,0x2b,0xa4,0x08,0x48,0x42,0x12,0xcc,0xb4,0x80,0x2d,0x64,0x0b,0x78,0x02,0x19 }}, - {16, 0x9940, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x2c,0x00,0xd0,0x10,0x28,0xc8 }}, - {16, 0x9950, 0, {0x0e,0x3b,0x02,0x84,0x00,0xe3,0x40,0x30,0xc8,0x0c,0x38,0x62,0x8c,0x00,0x53,0x00 }}, - {16, 0x9960, 0, {0x30,0xc4,0x1f,0x00,0x23,0x8c,0x3c,0xf3,0x80,0x18,0xc0,0x0d,0x30,0x03,0x0e,0x80 }}, - {16, 0x9970, 0, {0xd3,0x10,0x3c,0x80,0x0f,0x30,0x03,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9980, 0, {0x40,0x1d,0xbd,0x00,0xf9,0x12,0xb4,0xc0,0x07,0xb0,0x03,0xcc,0x00,0x4a,0x00,0x77 }}, - {16, 0x9990, 0, {0xc0,0x0e,0x71,0x43,0x6c,0x00,0xf3,0x00,0x3f,0xd0,0x1f,0xd0,0x53,0xac,0x68,0xfb }}, - {16, 0x99a0, 0, {0x18,0x3d,0xc0,0x0f,0xc0,0x13,0xf0,0x50,0xfc,0x04,0x3f,0x40,0x0f,0xf4,0x03,0x90 }}, - {16, 0x99b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xed,0x40,0xf8,0x04,0x3e,0xd2 }}, - {16, 0x99c0, 0, {0x0f,0xb3,0x13,0xe0,0x10,0xf9,0x00,0xb2,0xcc,0x0e,0xba,0x03,0x6d,0x80,0xdb,0x02 }}, - {16, 0x99d0, 0, {0x32,0xdc,0x4f,0x00,0x03,0x6c,0x04,0xf3,0x02,0x36,0x40,0x0e,0xb0,0x03,0xcc,0x00 }}, - {16, 0x99e0, 0, {0x4b,0x00,0x3c,0x80,0x0c,0xf1,0x03,0x62,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x99f0, 0, {0x48,0x11,0x9c,0x00,0xb4,0x00,0x2d,0xc9,0x0b,0x70,0x82,0xdc,0x00,0xbc,0x04,0x21 }}, - {16, 0x9a00, 0, {0xc4,0x4b,0x37,0x02,0x0c,0xa0,0x8f,0x74,0x21,0xc0,0x0b,0x40,0x02,0x1c,0x81,0xb7 }}, - {16, 0x9a10, 0, {0x20,0x2b,0xc0,0x08,0x40,0x02,0xd0,0x02,0x84,0x00,0x2d,0x40,0x0a,0xf2,0x02,0x12 }}, - {16, 0x9a20, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x80,0xb4,0xc0,0x2d,0xe4 }}, - {16, 0x9a30, 0, {0x0b,0x7a,0x02,0xd2,0x00,0xb5,0x88,0x21,0xe8,0x0a,0x78,0x02,0xde,0x40,0x97,0x00 }}, - {16, 0x9a40, 0, {0x21,0xe8,0x0b,0xcc,0x46,0x5e,0x28,0xb7,0xc4,0x21,0xf0,0x0a,0x78,0x02,0xfe,0x08 }}, - {16, 0x9a50, 0, {0x97,0x84,0x2d,0xa0,0x08,0x78,0x02,0x70,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9a60, 0, {0x08,0x14,0xcc,0x00,0xb0,0xc0,0x2c,0xc0,0x9b,0xb0,0x02,0xcc,0x20,0xb3,0x60,0x22 }}, - {16, 0x9a70, 0, {0xc0,0x0b,0x30,0x02,0x8c,0x00,0x83,0x01,0x20,0xc0,0x1b,0x06,0x16,0x4f,0x00,0xb3 }}, - {16, 0x9a80, 0, {0xa0,0x2a,0xf0,0x08,0x00,0x02,0xe0,0x00,0x90,0x00,0x2c,0x40,0x0a,0x30,0x02,0x02 }}, - {16, 0x9a90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x10,0xfe,0xc0,0x3e,0x80 }}, - {16, 0x9aa0, 0, {0x0f,0xa0,0x03,0xf9,0x08,0xfe,0x40,0x22,0x80,0x0e,0xa0,0x03,0xe8,0x00,0xd2,0x00 }}, - {16, 0x9ab0, 0, {0x32,0x80,0x8f,0xe0,0x03,0x58,0x00,0xf6,0x00,0x33,0xb0,0x0e,0x20,0x02,0xe8,0x0c }}, - {16, 0x9ac0, 0, {0xd2,0x02,0x3c,0x80,0x0c,0xa0,0x03,0x7a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9ad0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x20,0x3e,0x01,0x0b,0x80,0x03,0xe0,0x00,0xf0,0x40,0x3e }}, - {16, 0x9ae0, 0, {0x00,0x57,0x80,0x23,0x00,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x84,0x03,0xa0,0x30,0x38 }}, - {16, 0x9af0, 0, {0x00,0x3a,0x08,0x0f,0xc4,0x03,0xf0,0x00,0xec,0x00,0x3f,0x10,0x0f,0x80,0x03,0xd2 }}, - {16, 0x9b00, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x01,0x3c,0x48 }}, - {16, 0x9b10, 0, {0x4c,0x90,0x0b,0x24,0x01,0xc9,0xc0,0x32,0x40,0xac,0x90,0x03,0xe4,0x00,0xd9,0x40 }}, - {16, 0x9b20, 0, {0x30,0x40,0x0d,0x9a,0x03,0x22,0x84,0xc8,0x14,0x32,0x40,0x0e,0x90,0x03,0x24,0x00 }}, - {16, 0x9b30, 0, {0xc9,0x00,0x82,0x68,0x2c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9b40, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x2e,0x40,0x08,0x90,0x22,0x24,0x00,0x89,0x02,0x82 }}, - {16, 0x9b50, 0, {0x40,0x08,0x90,0x02,0xe7,0x40,0x89,0x80,0x36,0x41,0x8d,0x18,0x02,0xa0,0x24,0xa8 }}, - {16, 0x9b60, 0, {0x04,0x62,0x40,0x08,0x94,0x83,0x24,0x00,0x89,0x01,0x22,0x72,0x08,0x90,0x0b,0x20 }}, - {16, 0x9b70, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x99,0x00,0x2a,0x40 }}, - {16, 0x9b80, 0, {0x28,0x90,0x12,0x04,0x00,0x89,0x00,0x22,0x40,0x08,0x90,0x02,0xa4,0x20,0x99,0x00 }}, - {16, 0x9b90, 0, {0x22,0x40,0x18,0x90,0x06,0x20,0x01,0x88,0x08,0x62,0x40,0x0a,0x90,0x02,0x34,0x10 }}, - {16, 0x9ba0, 0, {0x8d,0x81,0x23,0x41,0x08,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9bb0, 0, {0x08,0x04,0x04,0x80,0x81,0x04,0x2c,0x48,0x08,0x12,0x02,0x04,0x02,0x83,0x20,0x20 }}, - {16, 0x9bc0, 0, {0x48,0x08,0x12,0x02,0xc4,0x80,0x83,0x60,0x24,0x48,0x19,0x34,0x62,0xa5,0x04,0xa1 }}, - {16, 0x9bd0, 0, {0x02,0x60,0x40,0x08,0xd0,0x02,0x54,0x00,0x8d,0x00,0x29,0x40,0x08,0x12,0x82,0x02 }}, - {16, 0x9be0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x3a,0x80 }}, - {16, 0x9bf0, 0, {0x0c,0x85,0x02,0x21,0x44,0x88,0x50,0x32,0x14,0x4c,0x80,0x43,0xe0,0x00,0xd8,0x00 }}, - {16, 0x9c00, 0, {0x22,0x14,0x0c,0x80,0x03,0x20,0x00,0xc8,0x00,0xa2,0x00,0x0e,0x80,0x03,0x20,0x00 }}, - {16, 0x9c10, 0, {0xc8,0x00,0x33,0x00,0x0c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9c20, 0, {0x98,0x1d,0xe4,0x44,0xfd,0x00,0x3e,0x44,0x0f,0x91,0x03,0xf4,0x10,0xff,0x10,0x3e }}, - {16, 0x9c30, 0, {0x44,0x0f,0x91,0x03,0xe4,0x40,0xf9,0x10,0x3e,0x44,0x0b,0xf0,0x13,0xe5,0x10,0xf9 }}, - {16, 0x9c40, 0, {0x40,0x3f,0x4a,0x2f,0x92,0x8a,0xa4,0xa2,0xf9,0x28,0x36,0x40,0x0f,0x92,0x83,0xa6 }}, - {16, 0x9c50, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xe6,0xc0,0xc1,0x00,0x3f,0x69 }}, - {16, 0x9c60, 0, {0x0c,0x9a,0x43,0x6c,0x00,0xfd,0xa0,0x3e,0x78,0x2c,0xd8,0x07,0xd6,0x02,0xd5,0x96 }}, - {16, 0x9c70, 0, {0x32,0x78,0x0d,0x90,0x03,0x27,0x00,0xfd,0xa0,0x35,0x50,0x06,0xd4,0x03,0xe5,0x00 }}, - {16, 0x9c80, 0, {0xfd,0x40,0xb3,0x40,0x0f,0x98,0xa3,0x46,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9c90, 0, {0x38,0x10,0xe3,0xc2,0x88,0x88,0x2e,0x14,0xa8,0x8a,0xc2,0x22,0xa0,0xb8,0xc0,0x2c }}, - {16, 0x9ca0, 0, {0x24,0x48,0x84,0x02,0xe1,0x00,0x98,0xc4,0x20,0x3c,0x08,0x8a,0x82,0x23,0x80,0xb8 }}, - {16, 0x9cb0, 0, {0x04,0x22,0x20,0x08,0x88,0x03,0xa2,0x00,0xb8,0xa0,0x22,0x00,0x0b,0x88,0x02,0x0e }}, - {16, 0x9cc0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0xa1,0x20,0x6c,0x40 }}, - {16, 0x9cd0, 0, {0x0a,0x14,0x02,0x44,0x04,0xa1,0x68,0x2c,0x48,0x08,0x14,0x02,0xc5,0x00,0x81,0x60 }}, - {16, 0x9ce0, 0, {0x20,0x48,0x19,0x90,0x02,0x85,0x81,0xb1,0x40,0x24,0x68,0x0a,0x12,0x42,0xc4,0x80 }}, - {16, 0x9cf0, 0, {0xb9,0x20,0x20,0x40,0x8b,0x10,0x82,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9d00, 0, {0x18,0x05,0xa4,0x10,0xa9,0x00,0x6e,0xc0,0x0a,0x10,0x02,0x24,0x14,0xb9,0x00,0x2e }}, - {16, 0x9d10, 0, {0x40,0x08,0x90,0x12,0xe4,0x00,0x99,0x00,0x22,0x40,0x08,0x80,0x06,0xa0,0x60,0xb9 }}, - {16, 0x9d20, 0, {0x09,0x22,0x60,0x08,0x90,0x02,0xa4,0x00,0xb9,0x00,0x02,0x40,0x0b,0x10,0x06,0x06 }}, - {16, 0x9d30, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0xe9,0x80,0x3e,0x41 }}, - {16, 0x9d40, 0, {0x0e,0x90,0x03,0x64,0x00,0xe9,0xc0,0x3e,0x40,0x0c,0x90,0x02,0xe4,0x00,0xc9,0x00 }}, - {16, 0x9d50, 0, {0x22,0x41,0x0d,0x80,0x02,0xa3,0x04,0xf1,0x40,0x36,0x40,0x0e,0x90,0x02,0xe4,0x00 }}, - {16, 0x9d60, 0, {0xf1,0x00,0x12,0x40,0x0f,0x90,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9d70, 0, {0x28,0x01,0xa4,0x00,0xd9,0x22,0x3e,0x42,0x0d,0x90,0x03,0xe4,0x00,0xb9,0xc4,0x3c }}, - {16, 0x9d80, 0, {0x40,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x02,0xae,0x40,0x0f,0x80,0x4b,0x62,0x10,0xf9 }}, - {16, 0x9d90, 0, {0x20,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x02,0x7e,0x41,0x0f,0x90,0x13,0xca }}, - {16, 0x9da0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x80,0x00,0xc8,0x00,0x38,0x00 }}, - {16, 0x9db0, 0, {0x0f,0x80,0x20,0xe0,0x00,0xa8,0x20,0x32,0x00,0x0c,0x80,0x07,0xe0,0x80,0xc8,0x00 }}, - {16, 0x9dc0, 0, {0x38,0x00,0x0d,0x80,0x83,0x21,0x10,0xf8,0x60,0x32,0x00,0x8e,0x80,0xb3,0x20,0x08 }}, - {16, 0x9dd0, 0, {0xf8,0x00,0x3e,0x00,0x0c,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9de0, 0, {0x28,0x05,0x28,0x04,0x8a,0x00,0x33,0x90,0x43,0xa0,0x22,0x28,0x00,0x8e,0x80,0x76 }}, - {16, 0x9df0, 0, {0x80,0x08,0xe1,0x03,0x19,0x00,0x86,0x80,0x22,0x80,0x0d,0x60,0x01,0x78,0x00,0xbe }}, - {16, 0x9e00, 0, {0x00,0x36,0x80,0x0c,0xe4,0x02,0xa8,0x10,0xbe,0xa0,0x2f,0x80,0x0d,0xa0,0x02,0x0a }}, - {16, 0x9e10, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x11,0x4c,0x04,0x03,0x04,0x2c,0xd4 }}, - {16, 0x9e20, 0, {0x0b,0x30,0x02,0x4c,0x01,0xa3,0xc4,0x20,0xc0,0x28,0x35,0x02,0x86,0x00,0x83,0x80 }}, - {16, 0x9e30, 0, {0x28,0xc0,0x08,0x38,0x06,0x0e,0x94,0x30,0xc0,0xa2,0xc0,0x0b,0x3c,0x02,0x0c,0x00 }}, - {16, 0x9e40, 0, {0xb3,0x80,0x2c,0x48,0x08,0x30,0x02,0x8a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9e50, 0, {0xa0,0x01,0x0c,0x04,0x8f,0x80,0x21,0xc1,0x1b,0x72,0x42,0x1e,0xc0,0x83,0x88,0x21 }}, - {16, 0x9e60, 0, {0xc0,0x18,0x28,0x06,0x10,0x21,0x86,0x38,0x21,0xc0,0x19,0xf7,0x02,0x5d,0xc0,0xb4 }}, - {16, 0x9e70, 0, {0x41,0x27,0xd0,0x08,0x78,0xc6,0x9c,0x00,0xb7,0x00,0x2f,0x60,0x09,0x72,0x02,0x28 }}, - {16, 0x9e80, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x02,0xc7,0x80,0x2d,0xa0 }}, - {16, 0x9e90, 0, {0x0f,0x3e,0x03,0xfe,0x80,0xa7,0x80,0xa1,0xe0,0x0c,0x78,0x02,0x94,0x00,0x85,0xa0 }}, - {16, 0x9ea0, 0, {0x39,0xe4,0x0c,0x78,0x13,0x1e,0x90,0xb5,0x84,0x31,0xe0,0x0f,0xf8,0x87,0x1e,0x04 }}, - {16, 0x9eb0, 0, {0xf7,0x80,0x3d,0x60,0x0c,0x3b,0x03,0xaa,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9ec0, 0, {0x08,0x1d,0xad,0xe4,0xfb,0x54,0x3e,0x80,0x0f,0xb4,0x23,0xec,0x32,0xfb,0x00,0x3e }}, - {16, 0x9ed0, 0, {0xd8,0x4f,0xa0,0x03,0xe4,0x00,0xf9,0x00,0x3e,0xc0,0x0f,0x30,0x33,0xec,0x04,0xf2 }}, - {16, 0x9ee0, 0, {0x01,0x3e,0xc0,0x0f,0xb2,0x03,0xfe,0x10,0xfb,0x68,0x3c,0x41,0x0f,0xf0,0x43,0x82 }}, - {16, 0x9ef0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xcf,0xe4,0x3f,0xe4 }}, - {16, 0x9f00, 0, {0x0c,0xfc,0x03,0x7e,0x80,0xcf,0x81,0x33,0xfa,0x0f,0xf8,0x03,0xf6,0x00,0xff,0x80 }}, - {16, 0x9f10, 0, {0x3f,0xe2,0x0f,0x79,0x03,0x3e,0x40,0xf4,0x80,0x33,0x60,0x0c,0xe8,0x03,0x3e,0x00 }}, - {16, 0x9f20, 0, {0xff,0x80,0x33,0x60,0x0c,0xf8,0x83,0x50,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9f30, 0, {0xa8,0x11,0x9c,0x00,0xd7,0xa0,0x2d,0xc4,0x08,0xba,0x02,0x3c,0xa0,0x87,0x20,0x21 }}, - {16, 0x9f40, 0, {0xc0,0x0f,0x52,0x03,0xd4,0x00,0xb6,0x10,0x2d,0xc0,0x8b,0x73,0x03,0x5c,0x40,0xb4 }}, - {16, 0x9f50, 0, {0xb0,0x2b,0x48,0x28,0x41,0x02,0x0c,0x00,0xbf,0x18,0x35,0x46,0x28,0x72,0x42,0x2a }}, - {16, 0x9f60, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x9c,0x00,0x87,0x41,0x2d,0x44 }}, - {16, 0x9f70, 0, {0x0a,0x73,0x02,0x9c,0xc4,0x81,0x00,0x6d,0xc8,0x8b,0x70,0x02,0xd4,0x00,0xb7,0x00 }}, - {16, 0x9f80, 0, {0x2d,0xc0,0x0b,0xf0,0x46,0x9c,0x55,0xb4,0x20,0x25,0x40,0x18,0x60,0x82,0x1c,0x00 }}, - {16, 0x9f90, 0, {0xb7,0x00,0x23,0x40,0x08,0x70,0x46,0x44,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9fa0, 0, {0x60,0x14,0xcc,0x00,0x93,0x00,0x2c,0x40,0x0b,0xb0,0x02,0x0c,0x82,0x80,0xc0,0x20 }}, - {16, 0x9fb0, 0, {0xc0,0x0a,0x10,0x02,0x04,0x00,0xb3,0x00,0x2c,0xc0,0x1b,0x30,0x00,0xcd,0x01,0xb0 }}, - {16, 0x9fc0, 0, {0x40,0xac,0x78,0x88,0x8c,0x06,0x0d,0x60,0xb3,0x4c,0x24,0x12,0x08,0x30,0x0a,0x18 }}, - {16, 0x9fd0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x15,0xbc,0x00,0xc7,0x00,0x2e,0x40 }}, - {16, 0x9fe0, 0, {0x0e,0xf0,0x2a,0xbf,0x00,0xc8,0xc8,0xbf,0xc0,0x0b,0x90,0x02,0xe4,0x04,0xbf,0x00 }}, - {16, 0x9ff0, 0, {0x3f,0xc0,0x0f,0xb2,0x0a,0xac,0x00,0xf8,0x80,0x34,0x49,0x0c,0xb9,0x0b,0x3f,0x00 }}, - {16, 0xa000, 0, {0xfb,0xc0,0x30,0xf0,0x0c,0xf0,0x03,0x6e,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa010, 0, {0x80,0x00,0xcc,0x00,0xfb,0x80,0x3e,0x41,0x2c,0xb0,0x13,0xac,0x00,0xf8,0x00,0x3e }}, - {16, 0xa020, 0, {0xc1,0x0f,0xa0,0x03,0xe8,0x00,0xfa,0x40,0x3e,0xc0,0x0f,0xb0,0x0b,0x6d,0x40,0xf8 }}, - {16, 0xa030, 0, {0x10,0x3a,0x40,0x0f,0xb0,0x03,0xec,0x10,0xfe,0x40,0x3e,0xc0,0x0f,0xf0,0x03,0xe1 }}, - {16, 0xa040, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xec,0x0c,0xdf,0x00,0x3b,0x80 }}, - {16, 0xa050, 0, {0x0f,0xf0,0x0b,0x3c,0x08,0xe7,0x08,0x33,0xc0,0x0b,0xd0,0x23,0x74,0x00,0x54,0x00 }}, - {16, 0xa060, 0, {0x33,0xc0,0x0f,0xf0,0x83,0xbe,0x20,0xfd,0x0c,0x3b,0x60,0x2c,0xe0,0x03,0x3c,0x00 }}, - {16, 0xa070, 0, {0xcf,0x12,0x33,0x50,0x0c,0x30,0x03,0x80,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa080, 0, {0x81,0x04,0x6c,0x04,0xab,0x00,0x22,0xa0,0x0b,0xb0,0x06,0x0c,0x00,0xab,0x40,0x36 }}, - {16, 0xa090, 0, {0xc0,0x0b,0xa8,0x02,0x66,0x00,0xb8,0x00,0x36,0xc1,0x0b,0x34,0x43,0xee,0x00,0xb2 }}, - {16, 0xa0a0, 0, {0x00,0x22,0x60,0x08,0xb4,0x82,0x8c,0x04,0x8a,0x21,0x22,0x40,0x08,0xb0,0x02,0x20 }}, - {16, 0xa0b0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x9b,0x00,0x2a,0x20 }}, - {16, 0xa0c0, 0, {0x0b,0xb0,0x02,0x2c,0x00,0x88,0xc5,0x22,0xc0,0x0b,0x88,0x82,0xe6,0x01,0xbb,0x08 }}, - {16, 0xa0d0, 0, {0x22,0xc0,0x0a,0xb2,0x82,0xac,0x60,0xb8,0x02,0x4a,0xc4,0x08,0xb1,0x02,0x2c,0x00 }}, - {16, 0xa0e0, 0, {0x83,0x00,0x22,0xc0,0x08,0xb0,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa0f0, 0, {0x08,0x04,0x0c,0x00,0xab,0x20,0x20,0x01,0x0b,0x32,0x06,0x2c,0x00,0xa0,0x00,0x20 }}, - {16, 0xa100, 0, {0xc0,0x09,0x04,0x22,0xc4,0x00,0xb2,0x00,0x24,0xc1,0x8b,0xb0,0x02,0x4c,0x00,0xb0 }}, - {16, 0xa110, 0, {0x00,0x62,0xc0,0x48,0x30,0x02,0xac,0x10,0x82,0x00,0x20,0xc0,0x08,0x30,0x02,0x02 }}, - {16, 0xa120, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x08,0xdf,0x2a,0x3a,0x00 }}, - {16, 0xa130, 0, {0x0f,0xf5,0x12,0x3c,0x10,0xc9,0x00,0xa3,0xc0,0x0f,0x80,0x53,0xec,0x01,0xda,0x00 }}, - {16, 0xa140, 0, {0x33,0xc0,0x0e,0xb0,0x03,0xac,0x04,0xf8,0x70,0x3a,0xc0,0x0c,0x60,0x43,0x2c,0x42 }}, - {16, 0xa150, 0, {0xcd,0x00,0xb2,0x40,0x2c,0xf0,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa160, 0, {0xa0,0x19,0xfc,0x00,0xfb,0x01,0x3d,0x00,0x0f,0xb4,0x17,0xfc,0x00,0x3c,0x00,0x3f }}, - {16, 0xa170, 0, {0xc0,0x4f,0xc0,0x03,0x74,0x08,0xfe,0x00,0x3f,0xc0,0x4f,0xf0,0x03,0xfc,0x08,0xf8 }}, - {16, 0xa180, 0, {0x30,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x04,0xfc,0x00,0x3d,0x00,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xa190, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf4,0x90,0xef,0x00,0x3f,0xd8 }}, - {16, 0xa1a0, 0, {0x0e,0xf3,0x03,0x2c,0x01,0xd4,0x80,0x37,0xcc,0x0d,0x89,0x43,0x12,0x50,0xec,0x2c }}, - {16, 0xa1b0, 0, {0x32,0x05,0x0d,0xb0,0x53,0x3c,0xd4,0xc5,0x94,0x7f,0xa0,0x8f,0xf0,0x43,0x30,0x00 }}, - {16, 0xa1c0, 0, {0xdc,0x00,0x33,0x00,0x0c,0x48,0x07,0xf0,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa1d0, 0, {0x80,0x10,0xe6,0x40,0x8b,0x70,0x2f,0xdc,0x08,0xf7,0x02,0x0c,0x80,0x8a,0x20,0x00 }}, - {16, 0xa1e0, 0, {0xc8,0x4a,0x22,0x02,0xa0,0x00,0x8a,0x48,0x22,0x58,0x88,0xfd,0x02,0xad,0x02,0xa9 }}, - {16, 0xa1f0, 0, {0x20,0x1e,0xa0,0x03,0x80,0x02,0x2c,0x04,0x8b,0x00,0x22,0xc0,0x4c,0x88,0x07,0x60 }}, - {16, 0xa200, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x00,0x23,0x2c,0x2c,0xc9 }}, - {16, 0xa210, 0, {0x02,0x30,0x02,0x0c,0x68,0xa0,0x28,0x2c,0xd0,0x09,0x12,0x02,0x84,0x00,0xa0,0x21 }}, - {16, 0xa220, 0, {0x20,0x18,0x19,0x30,0x22,0x80,0xd0,0x83,0x06,0x0c,0xa0,0x0b,0xb0,0x06,0x00,0x12 }}, - {16, 0xa230, 0, {0xa0,0x00,0x20,0x00,0x29,0x00,0x0e,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa240, 0, {0xc0,0x11,0xa8,0x30,0x8b,0x00,0x2e,0xc0,0x4a,0x30,0x0a,0x2c,0x14,0xa0,0x80,0x0a }}, - {16, 0xa250, 0, {0xc1,0x08,0x88,0x86,0x87,0x00,0x83,0x00,0x22,0x49,0x08,0xb0,0x06,0xa0,0x40,0xab }}, - {16, 0xa260, 0, {0x20,0x22,0x20,0x0b,0x80,0x0a,0x0c,0x04,0xab,0x02,0x22,0xc0,0x88,0x80,0x02,0xf0 }}, - {16, 0xa270, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xef,0x40,0xeb,0x06,0x3e,0xc0 }}, - {16, 0xa280, 0, {0x0e,0xb0,0x03,0x2c,0x02,0xf9,0xa0,0x3e,0xc0,0x0d,0x8c,0x03,0xaa,0x10,0xe9,0x40 }}, - {16, 0xa290, 0, {0xb2,0x48,0x0d,0xb0,0x43,0xad,0x00,0xcb,0x86,0x2e,0x20,0x0f,0x30,0x03,0x24,0x00 }}, - {16, 0xa2a0, 0, {0xf9,0x80,0x32,0xc0,0x0d,0x0c,0xc2,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa2b0, 0, {0xe0,0x01,0x94,0x00,0xff,0x00,0x3d,0xc0,0x0d,0xf0,0x03,0x7c,0x00,0xdf,0x00,0x37 }}, - {16, 0xa2c0, 0, {0xc0,0x0f,0xe0,0x03,0xf0,0x00,0xfe,0x20,0x3f,0x40,0x0f,0x70,0x03,0xfe,0x00,0xff }}, - {16, 0xa2d0, 0, {0x82,0x7f,0x00,0x0f,0xc0,0x03,0xf9,0x04,0xde,0x20,0xbd,0x00,0x0f,0xd9,0x0b,0x7c }}, - {16, 0xa2e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x01,0xcb,0x00,0x3e,0xc0 }}, - {16, 0xa2f0, 0, {0x2c,0xb0,0x0b,0x2c,0x00,0xe8,0x40,0x3e,0xc0,0x0f,0x94,0x07,0x29,0x00,0xc9,0x40 }}, - {16, 0xa300, 0, {0xb2,0xc0,0x0f,0xb0,0x03,0x01,0x02,0xcb,0x00,0x32,0x04,0x4f,0xf0,0x43,0x34,0xc0 }}, - {16, 0xa310, 0, {0xb5,0x1a,0x3f,0xc1,0x0f,0x80,0x93,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa320, 0, {0xc8,0x05,0x28,0x00,0x8f,0x00,0x2f,0xc0,0x08,0xf0,0x02,0x3c,0x04,0xd8,0x00,0x2b }}, - {16, 0xa330, 0, {0xc0,0x0c,0x80,0x45,0x60,0x00,0x7b,0x58,0x22,0xc8,0x0b,0xfa,0x01,0x61,0x40,0x8b }}, - {16, 0xa340, 0, {0x00,0x32,0x04,0x4b,0xce,0x02,0x28,0x00,0x3a,0x40,0x2e,0x07,0x0b,0x90,0x02,0x26 }}, - {16, 0xa350, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x83,0x01,0x4c,0xc0 }}, - {16, 0xa360, 0, {0x0b,0x30,0x02,0xec,0x10,0x90,0x00,0x2a,0xc0,0x0a,0x80,0x06,0xc0,0x04,0x83,0x04 }}, - {16, 0xa370, 0, {0xa2,0x89,0x19,0x30,0x06,0xcc,0x00,0x83,0x00,0x20,0x90,0x0b,0x30,0xc2,0x48,0x00 }}, - {16, 0xa380, 0, {0xb2,0x40,0x24,0x20,0x0b,0x09,0x00,0xb8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa390, 0, {0x20,0x01,0x06,0x04,0x87,0xa4,0x2d,0xe0,0x09,0x38,0x02,0xde,0x00,0x9e,0x81,0x29 }}, - {16, 0xa3a0, 0, {0xe0,0x08,0x78,0x52,0xfa,0xc0,0x96,0x80,0x01,0xa0,0x8b,0x3a,0x22,0xce,0x40,0x8f }}, - {16, 0xa3b0, 0, {0xb0,0x25,0xa0,0x0b,0x08,0x02,0x56,0x08,0xb5,0x90,0x2d,0xe4,0x4b,0xd8,0x22,0x0c }}, - {16, 0xa3c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x02,0x83,0x80,0x2e,0xe8 }}, - {16, 0xa3d0, 0, {0x0b,0x38,0x13,0xce,0x41,0xd3,0x10,0x28,0xc0,0x0e,0x3a,0x02,0xc6,0x08,0x4b,0x40 }}, - {16, 0xa3e0, 0, {0x30,0x60,0x0d,0x3b,0x27,0xcf,0xc4,0xc3,0xa0,0x30,0x00,0x0f,0x30,0x43,0x48,0x40 }}, - {16, 0xa3f0, 0, {0xf2,0x00,0x3c,0x04,0x0f,0x02,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa400, 0, {0x40,0x1d,0xb8,0x00,0xff,0x00,0x3f,0xc4,0x0e,0xf1,0x03,0x3c,0x00,0xff,0x01,0x33 }}, - {16, 0xa410, 0, {0xc0,0x4d,0xb1,0x07,0x7c,0x90,0xff,0x00,0x3f,0x40,0x03,0xf1,0x03,0x70,0x00,0xfb }}, - {16, 0xa420, 0, {0x10,0x3b,0x00,0x0f,0xc0,0x0b,0xb4,0x00,0xfd,0x00,0x3f,0xc4,0x0f,0xd0,0x03,0x90 }}, - {16, 0xa430, 0, {0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x04,0xfb,0x84,0x3a,0xc2 }}, - {16, 0xa440, 0, {0x4c,0xb4,0x93,0x2c,0x04,0xe9,0x00,0x3a,0xc4,0x8d,0x08,0x03,0x2e,0x00,0xcb,0x01 }}, - {16, 0xa450, 0, {0x32,0x80,0x8f,0xb2,0x83,0xec,0x00,0xcb,0x80,0x32,0x00,0x0f,0xf9,0x03,0x3c,0x10 }}, - {16, 0xa460, 0, {0xdf,0x81,0xb3,0xe0,0x8c,0xa0,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa470, 0, {0x48,0x11,0x94,0x08,0xb7,0x04,0x24,0xc8,0x1a,0x30,0x4a,0x1d,0x00,0xb7,0x01,0x2d }}, - {16, 0xa480, 0, {0xc0,0x88,0x70,0x06,0x1c,0x00,0x82,0x00,0x21,0x80,0x4b,0x76,0x12,0xdc,0x00,0x87 }}, - {16, 0xa490, 0, {0x00,0x29,0x40,0x8b,0x40,0x02,0x10,0x00,0xbc,0x00,0x20,0x01,0x28,0x70,0x03,0xb2 }}, - {16, 0xa4a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x00,0xb3,0x90,0x2d,0xe4 }}, - {16, 0xa4b0, 0, {0x09,0x79,0x02,0x1e,0x80,0xa7,0x80,0x2c,0xe8,0x19,0xf8,0x12,0x5e,0x01,0x87,0x80 }}, - {16, 0xa4c0, 0, {0x25,0xe0,0x4b,0x78,0x06,0xd2,0x00,0x97,0x80,0x21,0x62,0x0b,0x3a,0x02,0x1e,0x00 }}, - {16, 0xa4d0, 0, {0xb7,0x86,0x29,0xf0,0x08,0x68,0x06,0xe0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa4e0, 0, {0x48,0x14,0xcf,0xc0,0xb3,0x00,0x24,0xc0,0x8a,0x30,0x32,0x0c,0x00,0xb3,0x08,0x2c }}, - {16, 0xa4f0, 0, {0xc0,0x08,0x30,0x12,0x0e,0x20,0x83,0x00,0x24,0xf1,0x0b,0x30,0x06,0xce,0x00,0x83 }}, - {16, 0xa500, 0, {0x90,0x28,0x60,0x0b,0x00,0x2a,0x21,0x80,0xb0,0x08,0x28,0x00,0x08,0x37,0x02,0x92 }}, - {16, 0xa510, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x00,0xfa,0x00,0x3e,0x80 }}, - {16, 0xa520, 0, {0x4d,0xa0,0x03,0x28,0x00,0xee,0x41,0x3e,0x80,0x0d,0xe0,0x03,0x78,0x00,0x8e,0x40 }}, - {16, 0xa530, 0, {0x27,0xa8,0x0b,0xa0,0x03,0xfb,0x02,0xca,0x82,0x33,0xa0,0x0f,0xa0,0x13,0x29,0x00 }}, - {16, 0xa540, 0, {0xfa,0x40,0x3a,0x80,0x0c,0x6c,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa550, 0, {0x48,0x00,0xc0,0x00,0xf8,0x00,0x3a,0x00,0x0c,0x80,0x03,0xe0,0x08,0xf8,0x00,0x3e }}, - {16, 0xa560, 0, {0x00,0x8f,0x80,0x23,0xa0,0x42,0xf8,0x09,0xba,0x10,0x4f,0x80,0x03,0xe0,0x60,0xf8 }}, - {16, 0xa570, 0, {0x00,0x3e,0x20,0x0f,0xc0,0x03,0xf0,0x00,0xfc,0x00,0x27,0x00,0x8f,0x80,0x03,0x92 }}, - {16, 0xa580, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe5,0x00,0x89,0x00,0x3e,0x40 }}, - {16, 0xa590, 0, {0x6e,0x90,0x03,0xa4,0x08,0xc9,0x00,0x3c,0x40,0x0d,0x90,0x03,0x24,0x10,0xf9,0xa0 }}, - {16, 0xa5a0, 0, {0x32,0x42,0x0c,0x90,0x13,0xc4,0x00,0xc9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x40 }}, - {16, 0xa5b0, 0, {0xc9,0x20,0x3e,0x52,0xcf,0x90,0x09,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa5c0, 0, {0x80,0x04,0x66,0x00,0x89,0x04,0x2e,0x40,0x08,0x90,0x02,0x24,0x00,0xd9,0x00,0x3a }}, - {16, 0xa5d0, 0, {0x41,0x08,0x90,0x05,0xa4,0x00,0xb9,0x40,0xa2,0x40,0x0d,0x90,0x02,0xe5,0x46,0x89 }}, - {16, 0xa5e0, 0, {0x00,0x2e,0x40,0x0b,0x90,0x12,0xe5,0x00,0xa9,0xc8,0x2e,0x61,0x8b,0x94,0x42,0x20 }}, - {16, 0xa5f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xa9,0x00,0x6c,0x40 }}, - {16, 0xa600, 0, {0x48,0x10,0x22,0x84,0x03,0xa9,0x00,0x2e,0x40,0x09,0x90,0x02,0xe4,0x04,0xb1,0x08 }}, - {16, 0xa610, 0, {0x28,0x40,0x18,0x98,0x02,0xe5,0x00,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0xf4,0x20 }}, - {16, 0xa620, 0, {0x8d,0x00,0x2f,0x40,0x0b,0x94,0x42,0x86,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa630, 0, {0x08,0x04,0x04,0x80,0xa1,0x24,0x2c,0x48,0x18,0x12,0x02,0x04,0x80,0xa1,0x00,0x28 }}, - {16, 0xa640, 0, {0x48,0x08,0x10,0x02,0x84,0x00,0x91,0x20,0x20,0x48,0x09,0x12,0x02,0xc4,0x94,0x81 }}, - {16, 0xa650, 0, {0x00,0x2c,0x61,0x0b,0x5a,0x82,0xd4,0xa0,0xa5,0x28,0x2d,0x4a,0x0b,0x90,0x02,0x82 }}, - {16, 0xa660, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x02,0xe8,0x50,0x2e,0x14 }}, - {16, 0xa670, 0, {0x0e,0x85,0x03,0xa1,0x40,0xa8,0x50,0x3e,0x14,0x0d,0x85,0x01,0x81,0x40,0xf8,0x52 }}, - {16, 0xa680, 0, {0x32,0x94,0x0c,0x80,0x13,0xc1,0x42,0xc0,0x51,0x3e,0x00,0x8f,0x82,0x03,0xe0,0x80 }}, - {16, 0xa690, 0, {0xc8,0x20,0x3f,0x08,0x0f,0x80,0x03,0xae,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa6a0, 0, {0x98,0x19,0xf4,0x50,0xd9,0x11,0x3e,0x44,0x8f,0x91,0x43,0xe4,0x40,0xdd,0x00,0x3a }}, - {16, 0xa6b0, 0, {0x44,0x4f,0xd0,0x27,0xb4,0x00,0xfd,0x12,0x3f,0x44,0x4f,0x91,0x43,0xf4,0x40,0xfd }}, - {16, 0xa6c0, 0, {0x00,0x3f,0x41,0x0f,0x92,0x83,0xe4,0xa0,0xf9,0x28,0x3e,0x4a,0x0f,0xd0,0x03,0x66 }}, - {16, 0xa6d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x11,0xf6,0x80,0xe9,0xc0,0x3e,0x78 }}, - {16, 0xa6e0, 0, {0x8f,0x9b,0x03,0xa7,0x80,0xc9,0x40,0x36,0x78,0x0f,0x10,0x23,0xe5,0x04,0xdd,0xa4 }}, - {16, 0xa6f0, 0, {0x33,0x62,0x0f,0xda,0x03,0xf6,0x60,0xc9,0x10,0x33,0x40,0x0e,0x98,0x93,0xe6,0x30 }}, - {16, 0xa700, 0, {0xc9,0xc9,0x32,0x78,0x8c,0xd0,0x0b,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa710, 0, {0x38,0x10,0xe0,0x00,0x88,0xe2,0x2e,0x30,0x0b,0x88,0x42,0x23,0x40,0xa0,0xa1,0x22 }}, - {16, 0xa720, 0, {0x38,0x0b,0x8a,0x02,0xe2,0x80,0xaa,0xe0,0x22,0x30,0x0b,0x80,0x23,0xab,0x02,0x88 }}, - {16, 0xa730, 0, {0xa0,0x2a,0x00,0x0b,0x8c,0x02,0xe3,0x00,0x88,0xe0,0x23,0x38,0x08,0x80,0x02,0x0e }}, - {16, 0xa740, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xa1,0x44,0x28,0x58 }}, - {16, 0xa750, 0, {0x43,0x16,0x22,0x84,0x81,0x81,0x20,0x2c,0x58,0x49,0x10,0x80,0xc4,0x81,0x91,0x48 }}, - {16, 0xa760, 0, {0x6c,0x4a,0x0b,0x14,0x02,0x44,0x84,0x81,0x01,0x60,0x40,0x0a,0x52,0x86,0xd4,0xa0 }}, - {16, 0xa770, 0, {0x85,0x00,0xa1,0x50,0x68,0x90,0x06,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa780, 0, {0x18,0x05,0xa6,0x00,0x89,0x00,0x2e,0x40,0x0b,0x90,0x02,0x04,0x00,0xa9,0x60,0x22 }}, - {16, 0xa790, 0, {0x40,0x0b,0x95,0x02,0xe4,0x10,0xb1,0x00,0x4e,0x40,0x0b,0x90,0x66,0xac,0x80,0x89 }}, - {16, 0xa7a0, 0, {0x00,0x2a,0x60,0x0b,0x90,0x52,0xf4,0x00,0x85,0x00,0x21,0x40,0x08,0x90,0x02,0xc6 }}, - {16, 0xa7b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe6,0x20,0xe9,0x00,0x3e,0x40 }}, - {16, 0xa7c0, 0, {0x0f,0x90,0x03,0xa4,0x10,0xc9,0x00,0x36,0x40,0x0f,0x94,0x01,0xe5,0x20,0xd9,0x40 }}, - {16, 0xa7d0, 0, {0xba,0x68,0x8f,0x90,0x07,0xe6,0x00,0xc9,0x10,0x32,0x62,0x0e,0x90,0x02,0xe4,0x18 }}, - {16, 0xa7e0, 0, {0xc9,0x00,0x32,0x40,0x0c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa7f0, 0, {0x28,0x01,0xa4,0x00,0xf9,0x04,0x3e,0x40,0x0b,0x90,0x03,0x64,0x00,0xf9,0x00,0x3e }}, - {16, 0xa800, 0, {0x40,0x8f,0x90,0x03,0xe4,0x00,0xe9,0x02,0x72,0x68,0x0f,0x90,0x03,0xe6,0x00,0xf9 }}, - {16, 0xa810, 0, {0x01,0x3e,0x42,0x0f,0x90,0x03,0xc4,0x02,0xf9,0x04,0x3e,0x40,0x4f,0x90,0x03,0x1a }}, - {16, 0xa820, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x80,0x02,0xc8,0x00,0x32,0x00 }}, - {16, 0xa830, 0, {0x0c,0x80,0x03,0x60,0x00,0xc8,0x40,0x36,0x00,0x0f,0x84,0x03,0xa0,0x00,0xd8,0x50 }}, - {16, 0xa840, 0, {0xb2,0x10,0x8c,0x81,0x03,0xc1,0x20,0xc8,0x00,0x3e,0x00,0x0f,0xc0,0x13,0xf0,0x04 }}, - {16, 0xa850, 0, {0x4c,0x00,0x3f,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa860, 0, {0x28,0x15,0x2a,0x00,0x8a,0x04,0x22,0x81,0x28,0xa0,0x12,0x28,0x00,0x8a,0x01,0x36 }}, - {16, 0xa870, 0, {0x80,0x0b,0xa0,0x10,0x28,0x10,0xce,0x01,0x23,0x81,0x0c,0xa8,0x12,0xfb,0x00,0x8a }}, - {16, 0xa880, 0, {0x01,0x3b,0x80,0x83,0xa0,0x42,0xe8,0x10,0x8a,0x00,0x2f,0x80,0x0b,0x60,0x42,0x0a }}, - {16, 0xa890, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x00,0xa0,0xc0 }}, - {16, 0xa8a0, 0, {0x18,0xb0,0x00,0xcc,0x00,0x9b,0x00,0x24,0xc0,0x0b,0x30,0x06,0x6c,0x00,0xa3,0x08 }}, - {16, 0xa8b0, 0, {0x28,0xc8,0x09,0x30,0x02,0xcc,0x43,0x8b,0x00,0x2c,0x80,0x0b,0x30,0x02,0xcc,0x02 }}, - {16, 0xa8c0, 0, {0x83,0x01,0x2c,0xc0,0x4b,0x30,0x00,0x4a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa8d0, 0, {0xa0,0x01,0x0c,0x24,0x87,0x94,0x21,0xe4,0x18,0x31,0x02,0xdc,0x80,0x97,0x10,0x25 }}, - {16, 0xa8e0, 0, {0xcd,0x0b,0xf2,0x02,0x7c,0x00,0xa0,0x00,0x28,0xe0,0x18,0x70,0x02,0xdc,0x01,0x87 }}, - {16, 0xa8f0, 0, {0x34,0x29,0x40,0x09,0x40,0x02,0xd0,0x04,0x84,0x04,0x2d,0x00,0x4b,0xd0,0x22,0x68 }}, - {16, 0xa900, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x16,0x00,0xcf,0xa0,0x70,0xe9 }}, - {16, 0xa910, 0, {0x18,0x7b,0x03,0xff,0x40,0x97,0xa0,0x35,0xe8,0x0f,0x74,0x02,0x5e,0x20,0xe4,0x80 }}, - {16, 0xa920, 0, {0x39,0xa0,0x2d,0x78,0x03,0xfe,0x00,0xc7,0x80,0x3d,0xe0,0x5f,0x68,0x43,0xc2,0x00 }}, - {16, 0xa930, 0, {0xc4,0x84,0x1d,0x60,0x0f,0x78,0x03,0x6a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa940, 0, {0x08,0x0d,0xa4,0x00,0x3b,0x00,0x2e,0xd8,0x0f,0xb4,0x03,0x2d,0x8a,0xeb,0x62,0x3a }}, - {16, 0xa950, 0, {0xd0,0x0f,0xb2,0x87,0x0c,0xd0,0xd8,0x00,0x32,0xc0,0x4f,0x90,0x43,0xec,0x00,0xfb }}, - {16, 0xa960, 0, {0x08,0x3e,0x40,0x8f,0x90,0x03,0xfc,0x00,0xff,0x04,0x3f,0x80,0x0f,0x00,0x2b,0x82 }}, - {16, 0xa970, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xff,0xa0,0x3e,0xf4 }}, - {16, 0xa980, 0, {0x0e,0xb8,0x03,0xee,0x08,0x4b,0xf0,0x7f,0xf4,0x0c,0xf9,0x23,0xee,0x48,0x78,0x90 }}, - {16, 0xa990, 0, {0x32,0xe4,0x0c,0xf9,0x03,0xfe,0x00,0xff,0x80,0x3f,0xe4,0x1c,0x79,0x03,0x2e,0x40 }}, - {16, 0xa9a0, 0, {0xff,0x80,0x33,0xe0,0x2c,0x78,0x07,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa9b0, 0, {0xa8,0x11,0x94,0x00,0xb3,0x00,0x0c,0xe5,0x0b,0x38,0x02,0xfe,0x80,0x8f,0x80,0x61 }}, - {16, 0xa9c0, 0, {0xc4,0x28,0x78,0x00,0x4e,0x00,0xf4,0x84,0x25,0xa8,0x0c,0x70,0x02,0xcc,0x04,0xb3 }}, - {16, 0xa9d0, 0, {0x90,0x25,0x40,0x0c,0x41,0x83,0x52,0x40,0xb4,0x10,0xa3,0x00,0x0c,0x52,0x03,0x6a }}, - {16, 0xa9e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x00,0xb7,0x21,0x6d,0xc8 }}, - {16, 0xa9f0, 0, {0x4b,0x70,0x02,0xdc,0x42,0xa7,0x31,0x29,0xc4,0x08,0x72,0x02,0xdc,0x00,0xb7,0x28 }}, - {16, 0xaa00, 0, {0x24,0x80,0x08,0x70,0x06,0xd4,0x20,0xb7,0x01,0x2d,0xc1,0x08,0x60,0x02,0x50,0x80 }}, - {16, 0xaa10, 0, {0xb4,0x08,0x21,0x62,0x09,0x74,0x06,0x80,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaa20, 0, {0x20,0x14,0xc7,0x04,0xb3,0x00,0x2c,0xc0,0x0b,0xb0,0x02,0xcc,0x00,0xa3,0x02,0x60 }}, - {16, 0xaa30, 0, {0xc0,0x08,0x38,0x02,0x4e,0x44,0xa0,0xc0,0x24,0x91,0x08,0x30,0x02,0xc0,0x00,0xb3 }}, - {16, 0xaa40, 0, {0x00,0x24,0x60,0x08,0x1c,0x02,0x4c,0x88,0xb3,0xc0,0x20,0xa0,0x08,0x00,0x0a,0x88 }}, - {16, 0xaa50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xff,0x00,0x2f,0xc0 }}, - {16, 0xaa60, 0, {0x4f,0xf0,0x13,0xfc,0x08,0xe7,0x8a,0x3f,0xc0,0x0c,0xf5,0xc2,0xfe,0x10,0xbb,0xc0 }}, - {16, 0xaa70, 0, {0x32,0xd4,0x0c,0x30,0x13,0xe3,0x04,0xbf,0x00,0x2e,0x62,0x08,0xb9,0x02,0x6e,0x00 }}, - {16, 0xaa80, 0, {0xfb,0x01,0x32,0xa4,0x4d,0x94,0x02,0xab,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaa90, 0, {0x80,0x00,0xec,0x60,0xfb,0x00,0x1e,0xc0,0x0f,0xb0,0x13,0xec,0x00,0x5b,0x00,0x3a }}, - {16, 0xaaa0, 0, {0xc0,0x0f,0xb0,0x41,0xec,0x00,0x7b,0x45,0xba,0x40,0x2e,0xb0,0x15,0xe0,0x01,0xfb }}, - {16, 0xaab0, 0, {0x00,0x3e,0x50,0x0e,0xc0,0x03,0xf0,0x40,0xfc,0x20,0x3f,0x50,0x8f,0x90,0x01,0x60 }}, - {16, 0xaac0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf4,0x00,0xff,0x00,0x3f,0xc0 }}, - {16, 0xaad0, 0, {0x8f,0xf0,0x03,0x1c,0x02,0xcf,0x00,0x36,0xc0,0x0d,0xf0,0x03,0x7c,0x00,0x7f,0x2a }}, - {16, 0xaae0, 0, {0x3f,0x80,0x0f,0xf8,0x13,0x90,0x21,0xcf,0x00,0x3f,0x62,0x0c,0xe0,0x03,0x30,0x00 }}, - {16, 0xaaf0, 0, {0xf8,0x00,0x3f,0x00,0x0f,0xd0,0x03,0x80,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xab00, 0, {0x81,0x04,0x64,0x11,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0x2c,0x00,0xdb,0x04,0x32 }}, - {16, 0xab10, 0, {0xc0,0x0e,0xb0,0x02,0xec,0x00,0xbb,0x84,0x2e,0x40,0x0b,0xb9,0x42,0x22,0x42,0x8b }}, - {16, 0xab20, 0, {0x01,0x2c,0x72,0x0a,0x90,0x42,0x2c,0x00,0xbb,0x00,0x2e,0xc2,0x8f,0x88,0x06,0xe0 }}, - {16, 0xab30, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x24,0x00,0xbb,0x00,0x6e,0xc0 }}, - {16, 0xab40, 0, {0x48,0xb0,0x42,0x2c,0x00,0x8b,0x00,0x26,0xc0,0x0a,0xb0,0x12,0xec,0x00,0xbb,0x40 }}, - {16, 0xab50, 0, {0x2e,0xc8,0x0b,0xb0,0x12,0x2c,0x00,0x8b,0x00,0x2e,0x48,0x0a,0x30,0x02,0x6c,0x00 }}, - {16, 0xab60, 0, {0xbb,0x00,0x2e,0x80,0x4b,0x98,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xab70, 0, {0x08,0x04,0x04,0x00,0xb3,0x00,0x6c,0xc2,0x4b,0x31,0x02,0x0c,0x50,0x9b,0x20,0x20 }}, - {16, 0xab80, 0, {0xc0,0x0a,0x32,0x12,0xcc,0x80,0xb3,0x00,0x6c,0x0c,0x0b,0x31,0x02,0x0c,0x42,0x83 }}, - {16, 0xab90, 0, {0x08,0x2e,0x40,0x0a,0x00,0x02,0x00,0x80,0xb0,0x00,0x2c,0x41,0x0b,0x10,0x02,0x42 }}, - {16, 0xaba0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xbb,0x40,0x3f,0xcc }}, - {16, 0xabb0, 0, {0x0e,0xf0,0x83,0x3d,0xa0,0xcf,0x20,0x37,0xc0,0x0c,0xf7,0xc3,0xfd,0x48,0xf3,0x00 }}, - {16, 0xabc0, 0, {0x3e,0x88,0x0f,0xb4,0x13,0xa5,0x00,0x8f,0x30,0x3e,0x40,0x0c,0xa0,0x03,0x60,0x80 }}, - {16, 0xabd0, 0, {0xf8,0x00,0x3e,0x00,0x0f,0x90,0x23,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xabe0, 0, {0xa0,0x19,0xf4,0x00,0xff,0x29,0x3f,0xc9,0x0f,0xf0,0x13,0xfc,0x94,0xef,0x12,0x3b }}, - {16, 0xabf0, 0, {0xc0,0x8e,0xb2,0x07,0xfd,0x04,0xff,0x10,0x3f,0x0c,0x0f,0xf0,0x03,0xf0,0x00,0xfb }}, - {16, 0xac00, 0, {0x20,0x3d,0x40,0x0f,0xd0,0x43,0xfc,0x40,0xff,0x04,0x3f,0xc0,0x0e,0xc0,0x43,0xe8 }}, - {16, 0xac10, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0xa2,0xc7,0x20,0x3f,0x24 }}, - {16, 0xac20, 0, {0x0c,0xf0,0x03,0x3c,0x80,0xcc,0x09,0x33,0xd1,0x0c,0xf1,0x23,0xfc,0x20,0xdf,0x36 }}, - {16, 0xac30, 0, {0x3f,0xc0,0x0e,0x48,0x03,0xfe,0x00,0xff,0x80,0x37,0xe4,0x0d,0x78,0x03,0x11,0xa0 }}, - {16, 0xac40, 0, {0xcf,0x00,0x37,0xc8,0x0c,0xf0,0x03,0x30,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xac50, 0, {0x80,0x10,0xff,0x00,0x8f,0xd1,0x2e,0x08,0x0d,0xb6,0x12,0x3d,0x45,0xf9,0x64,0x27 }}, - {16, 0xac60, 0, {0xd0,0x88,0xba,0x14,0xcc,0x04,0x8f,0x40,0x23,0xf0,0x0b,0x88,0x02,0x2e,0x04,0xbb }}, - {16, 0xac70, 0, {0x80,0xae,0xc0,0x08,0xb8,0x0a,0x21,0x00,0x88,0xd0,0x22,0x20,0x28,0xb0,0x02,0x20 }}, - {16, 0xac80, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x93,0x00,0x2e,0x00 }}, - {16, 0xac90, 0, {0x0a,0x34,0x82,0x8c,0xa0,0xa0,0x08,0x24,0xd8,0x09,0x31,0x02,0xcc,0x20,0xb3,0x32 }}, - {16, 0xaca0, 0, {0x28,0xd0,0x4a,0x80,0x02,0xcc,0x0c,0xbb,0x00,0x22,0x40,0x89,0xb0,0x02,0x60,0x80 }}, - {16, 0xacb0, 0, {0x93,0x00,0x24,0xd0,0x0b,0x30,0x02,0xa2,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xacc0, 0, {0xc0,0x11,0xac,0x00,0x9b,0x00,0x2e,0x20,0x09,0xb0,0x4a,0x2c,0x02,0xa0,0x00,0x06 }}, - {16, 0xacd0, 0, {0xc0,0x09,0xb0,0x00,0xec,0x00,0xab,0x00,0x2a,0xc0,0x0b,0x88,0x02,0x6c,0x00,0xbb }}, - {16, 0xace0, 0, {0x20,0x2a,0xe2,0x41,0xb8,0x2a,0x60,0x0a,0x98,0x00,0x26,0x00,0x0b,0xb0,0x02,0xb8 }}, - {16, 0xacf0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x08,0xdb,0x02,0x3e,0x20 }}, - {16, 0xad00, 0, {0x4c,0xb0,0x03,0x2c,0x02,0x8b,0x20,0x12,0xc0,0x29,0xb0,0x12,0xec,0x00,0xfb,0x00 }}, - {16, 0xad10, 0, {0x3a,0xc0,0x0e,0x88,0x03,0xed,0x20,0xfb,0xc8,0x34,0xf0,0x0d,0xba,0x03,0x47,0x60 }}, - {16, 0xad20, 0, {0xc9,0x00,0x36,0x40,0x0f,0xb0,0x0b,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xad30, 0, {0xe0,0x01,0x9c,0x00,0xef,0x00,0x0f,0x00,0x0f,0x30,0x00,0xfc,0x00,0xdf,0x90,0xbb }}, - {16, 0xad40, 0, {0xc0,0xce,0xf0,0x03,0xfc,0x04,0xcb,0x00,0x17,0xc0,0x0f,0xc0,0x03,0xbc,0x84,0xff }}, - {16, 0xad50, 0, {0x00,0x37,0xc0,0x0e,0xd0,0x63,0xb8,0x00,0xea,0x00,0x3a,0x80,0x0c,0x30,0x03,0x70 }}, - {16, 0xad60, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xfb,0x02,0x32,0x00 }}, - {16, 0xad70, 0, {0x0f,0xb0,0x53,0x2c,0x00,0xfa,0x00,0x32,0xc0,0x8f,0xb0,0x07,0x2c,0x00,0xfb,0x00 }}, - {16, 0xad80, 0, {0xb2,0xc0,0x0f,0x80,0x07,0xac,0x80,0xdb,0x24,0x7e,0xd0,0x0e,0xb0,0x23,0x74,0x04 }}, - {16, 0xad90, 0, {0xdd,0x08,0xb5,0x40,0x0c,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xada0, 0, {0xc8,0x05,0x3c,0x00,0xbf,0xc0,0xa0,0x00,0x1b,0xf0,0x02,0x3f,0x60,0xea,0x50,0x23 }}, - {16, 0xadb0, 0, {0xc0,0x08,0xfa,0x07,0xfc,0x00,0xdf,0x00,0x63,0xc0,0x48,0x18,0x02,0x2d,0x00,0xb3 }}, - {16, 0xadc0, 0, {0x00,0x6e,0xc0,0x0d,0x3a,0x03,0x24,0x00,0x82,0x80,0x32,0x80,0x0d,0xf0,0x03,0x32 }}, - {16, 0xadd0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x14,0xb3,0x59,0x20,0x80 }}, - {16, 0xade0, 0, {0x09,0x30,0x02,0x2e,0x05,0xb0,0x44,0x2e,0xc0,0x09,0x34,0x82,0xec,0x00,0xab,0x04 }}, - {16, 0xadf0, 0, {0x20,0xc0,0x09,0x21,0xb2,0x8e,0x04,0x93,0xc0,0x24,0xc0,0x0a,0x18,0x06,0x4c,0x00 }}, - {16, 0xae00, 0, {0x92,0x50,0x20,0xc0,0x08,0x30,0x02,0x70,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xae10, 0, {0x20,0x01,0x1e,0x00,0xb7,0x80,0x61,0xe0,0x0b,0x78,0x0a,0x5e,0x01,0xb1,0xa0,0x2d }}, - {16, 0xae20, 0, {0xe0,0x0a,0x78,0x02,0x5e,0x00,0x07,0x90,0x21,0xe0,0x18,0xc8,0x02,0x1e,0x00,0xb7 }}, - {16, 0xae30, 0, {0x80,0x2d,0xe0,0x8a,0xd8,0x02,0x3e,0xc0,0x85,0x80,0x21,0x20,0x19,0x78,0x22,0x00 }}, - {16, 0xae40, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xf3,0x94,0x20,0x10 }}, - {16, 0xae50, 0, {0x4b,0x30,0x07,0x0c,0x00,0xf3,0x00,0x3e,0xc8,0x0f,0x30,0x03,0xcc,0x00,0x23,0x10 }}, - {16, 0xae60, 0, {0x00,0xcb,0x05,0x20,0x02,0x8c,0x60,0x93,0x0a,0x2e,0xc4,0x0a,0x01,0x07,0x4c,0x80 }}, - {16, 0xae70, 0, {0xd2,0x01,0x30,0xc0,0x2c,0x30,0x0b,0x5a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xae80, 0, {0x40,0x1d,0xbc,0x00,0xff,0x01,0x0f,0x40,0x0f,0xf0,0x13,0xbc,0x00,0xef,0x26,0x73 }}, - {16, 0xae90, 0, {0xc2,0x0c,0xb0,0x83,0xbc,0x40,0xff,0x18,0x3d,0xc0,0x4a,0xc1,0x03,0xfc,0x00,0xfb }}, - {16, 0xaea0, 0, {0x12,0x3f,0xc4,0x4d,0xc1,0x0b,0xfc,0x81,0xfd,0x00,0x3f,0x20,0x0f,0xf0,0x03,0xd0 }}, - {16, 0xaeb0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x20,0xcb,0x48,0x3e,0x00 }}, - {16, 0xaec0, 0, {0x0c,0xb0,0x03,0x2d,0x20,0xe9,0x80,0xfa,0xc8,0x0d,0xb0,0x03,0xee,0x00,0xdb,0x24 }}, - {16, 0xaed0, 0, {0x76,0xf3,0x8e,0x80,0x33,0xec,0x44,0xeb,0x10,0x3e,0xc0,0x0f,0x90,0x03,0xe8,0x04 }}, - {16, 0xaee0, 0, {0xdc,0x00,0xb3,0x61,0x0c,0xb0,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaef0, 0, {0x48,0x11,0x8d,0x00,0x87,0x20,0x2f,0x01,0x28,0x70,0x02,0x0c,0x84,0x8d,0x04,0x31 }}, - {16, 0xaf00, 0, {0xcc,0xc9,0x72,0x02,0xdd,0x00,0x37,0x33,0x21,0xd8,0x08,0x40,0x02,0xdc,0x00,0xb7 }}, - {16, 0xaf10, 0, {0x20,0x3d,0xc0,0x09,0x50,0x22,0xf0,0x00,0x97,0x00,0x21,0x80,0x0a,0xfc,0x02,0x92 }}, - {16, 0xaf20, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x1e,0x82,0x87,0xb0,0x2d,0x20 }}, - {16, 0xaf30, 0, {0x08,0x39,0x02,0x1e,0x41,0xa7,0x80,0x24,0xe0,0x09,0x7a,0x32,0x8e,0x82,0x07,0xa0 }}, - {16, 0xaf40, 0, {0x25,0xe0,0x8b,0x48,0x02,0x1e,0x00,0xa7,0xe1,0x2d,0xe0,0x4b,0x58,0x00,0xda,0x00 }}, - {16, 0xaf50, 0, {0xa0,0x80,0x24,0x60,0x08,0x7a,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaf60, 0, {0x48,0x14,0xcc,0x00,0x83,0x00,0x2c,0x00,0x08,0x30,0x02,0x8c,0x00,0x93,0x00,0x22 }}, - {16, 0xaf70, 0, {0xc1,0x09,0x30,0x42,0xcc,0x00,0x83,0x00,0x60,0xc0,0x08,0x1a,0x02,0xce,0x04,0xb3 }}, - {16, 0xaf80, 0, {0xe0,0x28,0xa0,0x09,0x1c,0x82,0x4b,0x08,0xa3,0x80,0x24,0xa0,0x2a,0x30,0x02,0x9a }}, - {16, 0xaf90, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xca,0x00,0x2f,0x88 }}, - {16, 0xafa0, 0, {0x0c,0xa0,0x13,0x28,0x00,0xee,0x00,0x2e,0x80,0x2d,0xa0,0x03,0xe8,0x00,0xda,0x00 }}, - {16, 0xafb0, 0, {0x76,0x80,0x0e,0xe8,0x03,0xbb,0x80,0xee,0x40,0x2f,0xa2,0x8f,0xe6,0x03,0xeb,0x86 }}, - {16, 0xafc0, 0, {0xfa,0x80,0x37,0x82,0x0c,0x20,0x07,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xafd0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x40,0x1e,0x00,0x0f,0x80,0x0b,0x61,0x00,0xe8,0xc0,0x3a }}, - {16, 0xafe0, 0, {0x00,0x0e,0x80,0x03,0xe0,0x01,0xf8,0x00,0x7e,0x10,0x1e,0x81,0x03,0xe0,0x08,0xf8 }}, - {16, 0xaff0, 0, {0x00,0x3e,0x00,0x0d,0x80,0x03,0xc0,0x28,0xdc,0x50,0x3b,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xb000, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x02,0xc9,0x00,0x3e,0x42 }}, - {16, 0xb010, 0, {0x0f,0x10,0x03,0xa6,0x00,0xc9,0x01,0x3a,0x40,0x0e,0x94,0x01,0xe4,0x10,0xf1,0x04 }}, - {16, 0xb020, 0, {0x32,0x40,0x0f,0x9a,0x23,0x20,0x60,0xf8,0x04,0x0a,0x42,0x0e,0x90,0x13,0x24,0x00 }}, - {16, 0xb030, 0, {0xc1,0x00,0x32,0x40,0x0f,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb040, 0, {0x80,0x04,0x67,0x08,0xa9,0x00,0x6e,0x40,0x08,0x90,0x02,0x27,0x82,0x89,0x00,0x26 }}, - {16, 0xb050, 0, {0x40,0x08,0x9c,0x03,0xa4,0x10,0xb9,0x00,0x36,0x40,0x9b,0x1c,0x1a,0x23,0x04,0xb8 }}, - {16, 0xb060, 0, {0x00,0x3a,0x40,0x0e,0x10,0x02,0x24,0x02,0xc9,0xa0,0xa2,0x40,0x0b,0x90,0x0a,0x20 }}, - {16, 0xb070, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x25,0x80,0x89,0x04,0x2c,0x40 }}, - {16, 0xb080, 0, {0x08,0x90,0x02,0x84,0x81,0x99,0x40,0x2e,0x40,0x1a,0x90,0x06,0xe4,0x01,0xb9,0x00 }}, - {16, 0xb090, 0, {0xa6,0x41,0x1b,0x90,0x82,0x21,0x00,0xb8,0x10,0x2e,0x40,0x0a,0x92,0x0a,0xa4,0x01 }}, - {16, 0xb0a0, 0, {0x8f,0x22,0x23,0x40,0x0b,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb0b0, 0, {0x08,0x04,0x04,0x80,0xa3,0x20,0x2c,0x41,0x09,0x12,0x02,0x04,0x80,0x81,0x20,0x24 }}, - {16, 0xb0c0, 0, {0x48,0x0a,0x36,0x02,0xc4,0x80,0xb1,0x20,0x04,0xc8,0x4b,0x14,0x02,0x05,0x00,0xb1 }}, - {16, 0xb0d0, 0, {0x05,0x28,0x50,0x0a,0x90,0x02,0x05,0x02,0x85,0x00,0x21,0x40,0x0b,0x12,0x02,0x02 }}, - {16, 0xb0e0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x00,0x6e,0x14 }}, - {16, 0xb0f0, 0, {0x2c,0x85,0x02,0xa1,0x40,0xc8,0x50,0x3a,0x14,0x0e,0x80,0x02,0xe1,0x40,0xb0,0x50 }}, - {16, 0xb100, 0, {0x32,0x00,0x0b,0x80,0x03,0x20,0x00,0xfa,0x00,0x3e,0x00,0x0e,0x80,0x03,0xa0,0x02 }}, - {16, 0xb110, 0, {0xc8,0x00,0x13,0x00,0x0f,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb120, 0, {0x98,0x1d,0xe4,0x48,0xf9,0x14,0x3f,0x40,0x0c,0x91,0x03,0xe4,0x42,0xfd,0x10,0x36 }}, - {16, 0xb130, 0, {0x44,0x0d,0x91,0x23,0xa4,0x48,0xf9,0x11,0x38,0x44,0x0f,0xd0,0x03,0xe5,0x14,0x39 }}, - {16, 0xb140, 0, {0x42,0x7b,0x40,0x8e,0xd0,0x01,0xf5,0x00,0xa9,0x40,0x3e,0x50,0x07,0x96,0x83,0xe6 }}, - {16, 0xb150, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xf6,0x80,0xdd,0xae,0x3a,0x50 }}, - {16, 0xb160, 0, {0x0d,0x9a,0x0b,0x76,0x80,0xcf,0x88,0x32,0x70,0x2d,0xda,0x03,0xa7,0x01,0xe9,0x92 }}, - {16, 0xb170, 0, {0x37,0x68,0x0d,0x94,0x03,0xe7,0x00,0xed,0xa0,0x3a,0x50,0x0f,0xd0,0x03,0xe7,0x02 }}, - {16, 0xb180, 0, {0xcd,0x80,0x33,0x68,0x0c,0xd8,0x83,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb190, 0, {0x38,0x10,0xe1,0x00,0x88,0x40,0x20,0x20,0x0c,0x8c,0x02,0x23,0x00,0x88,0xe0,0x22 }}, - {16, 0xb1a0, 0, {0x30,0x08,0x84,0x02,0xe3,0x00,0xb8,0xe0,0x22,0x14,0x8d,0x88,0x02,0xe3,0x00,0xb8 }}, - {16, 0xb1b0, 0, {0x50,0x2e,0xa8,0x8b,0x80,0x22,0xe3,0x48,0x88,0x50,0x22,0x00,0x08,0x8c,0x02,0x0e }}, - {16, 0xb1c0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x40,0x91,0x00,0x2a,0x48 }}, - {16, 0xb1d0, 0, {0x09,0x14,0x82,0x05,0x20,0x81,0x08,0x20,0x58,0x09,0x11,0x02,0x85,0x88,0xb1,0x40 }}, - {16, 0xb1e0, 0, {0xa0,0x40,0x08,0x12,0x02,0xc5,0x80,0xa1,0x00,0x28,0x40,0x0b,0x18,0x02,0xc4,0x84 }}, - {16, 0xb1f0, 0, {0xa1,0x00,0x24,0x50,0x08,0x10,0x92,0x03,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb200, 0, {0x18,0x15,0xac,0x10,0x9b,0x00,0x22,0x40,0x08,0x90,0x02,0x04,0x06,0x89,0x04,0x20 }}, - {16, 0xb210, 0, {0x40,0x09,0x90,0x02,0xe4,0x01,0xb9,0x02,0x22,0x41,0x89,0xa0,0x82,0xe0,0xa0,0xb9 }}, - {16, 0xb220, 0, {0x28,0x2e,0x44,0x0b,0xb0,0x02,0xe4,0x02,0xb9,0x00,0x26,0x40,0x28,0x10,0x02,0x06 }}, - {16, 0xb230, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xd9,0x00,0x38,0x40 }}, - {16, 0xb240, 0, {0x0d,0x90,0x03,0x24,0x00,0xc9,0xa0,0xa2,0x40,0x8d,0x90,0x03,0xa4,0x00,0xf9,0x00 }}, - {16, 0xb250, 0, {0x36,0x40,0x0c,0x84,0x13,0xe2,0x00,0xe9,0x00,0x3a,0x50,0x0f,0x9c,0x02,0xe6,0x84 }}, - {16, 0xb260, 0, {0xe9,0x00,0xb6,0x40,0x0c,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb270, 0, {0x28,0x01,0xa4,0x00,0xe1,0x00,0x3e,0x68,0x0e,0x10,0x03,0xa4,0x00,0xf1,0x28,0x3a }}, - {16, 0xb280, 0, {0x40,0x0e,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x42,0x0f,0x80,0x23,0xe2,0x00,0xf9 }}, - {16, 0xb290, 0, {0x00,0x3e,0x40,0x0f,0x91,0x23,0xe4,0x40,0xc1,0x00,0x3a,0x40,0x0f,0x90,0x0b,0xca }}, - {16, 0xb2a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x80,0x00,0xc8,0x00,0x32,0x00 }}, - {16, 0xb2b0, 0, {0x0c,0x80,0x03,0xa0,0x20,0xc8,0x40,0x3e,0x00,0x0e,0x81,0x63,0x60,0x00,0xf0,0x04 }}, - {16, 0xb2c0, 0, {0x3c,0x01,0x0c,0x84,0x03,0xe0,0x00,0xc8,0x00,0x3e,0x00,0x0e,0x80,0x03,0xc1,0x00 }}, - {16, 0xb2d0, 0, {0xd8,0x10,0x32,0x00,0x0c,0x80,0x23,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb2e0, 0, {0x28,0x05,0x38,0x60,0x8e,0x00,0x22,0x80,0x0a,0xa0,0x02,0x38,0x80,0xbe,0x00,0x3a }}, - {16, 0xb2f0, 0, {0x80,0x08,0xe0,0x02,0x28,0x00,0xba,0x00,0x23,0x98,0x18,0xec,0x02,0xf8,0x20,0xae }}, - {16, 0xb300, 0, {0x00,0x22,0x80,0x0b,0xe4,0x82,0xe8,0x02,0xce,0x44,0x28,0x80,0x0d,0xa0,0x0a,0x0a }}, - {16, 0xb310, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x40,0x00,0x82,0x04,0xa0,0xc0 }}, - {16, 0xb320, 0, {0x09,0x30,0x02,0x8e,0x04,0x83,0x50,0x6c,0xc0,0x0a,0x30,0x86,0x0c,0x00,0xb3,0x00 }}, - {16, 0xb330, 0, {0x28,0x30,0x0a,0x36,0x12,0xcc,0x80,0x81,0x00,0x24,0xc0,0x0b,0x32,0x06,0xcc,0x00 }}, - {16, 0xb340, 0, {0x80,0x88,0x64,0x60,0x28,0x10,0x02,0x02,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb350, 0, {0xa0,0x01,0x10,0x12,0x84,0x40,0x21,0xc8,0x0a,0x72,0x02,0x10,0x00,0xb7,0x00,0x2d }}, - {16, 0xb360, 0, {0xcc,0x08,0x38,0x12,0x1c,0x00,0xb3,0x30,0x20,0x00,0x08,0x71,0x82,0xfe,0x00,0xa4 }}, - {16, 0xb370, 0, {0x80,0x21,0xc8,0x0b,0x70,0x02,0xdc,0x01,0x87,0x00,0x2c,0x42,0x09,0x51,0x02,0x20 }}, - {16, 0xb380, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xc2,0x80,0x31,0xf8 }}, - {16, 0xb390, 0, {0x4c,0xfc,0x13,0x92,0x09,0xc7,0x80,0x3c,0xed,0x1e,0x78,0x27,0x1e,0x00,0xf7,0x8c }}, - {16, 0xb3a0, 0, {0x79,0x20,0x08,0x7a,0x03,0xde,0x81,0x84,0x80,0x3d,0xe0,0x0e,0x78,0x03,0xfe,0x20 }}, - {16, 0xb3b0, 0, {0xc5,0x81,0x35,0x60,0x2c,0x58,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb3c0, 0, {0x08,0x1d,0x80,0x00,0xf8,0x04,0x3e,0xd0,0x0f,0xb0,0x13,0xe0,0x00,0xfb,0x02,0x3a }}, - {16, 0xb3d0, 0, {0xd0,0x0f,0xa0,0x0b,0xac,0x40,0xfb,0x00,0x3a,0x00,0x2f,0xb0,0x03,0xcc,0x00,0xf0 }}, - {16, 0xb3e0, 0, {0x00,0x3a,0xc4,0x0f,0xb0,0x03,0xfc,0x41,0xf3,0x00,0x3a,0x40,0x0f,0x50,0x93,0xc2 }}, - {16, 0xb3f0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xcc,0x81,0x3f,0xfc }}, - {16, 0xb400, 0, {0x1c,0xf8,0x03,0x76,0x40,0xef,0x92,0x3f,0xe4,0x8c,0xf8,0x03,0xbf,0x10,0xff,0x80 }}, - {16, 0xb410, 0, {0xb3,0x20,0x0e,0xf9,0x13,0xfe,0x24,0xfd,0x94,0x37,0xe0,0x1c,0xf9,0x03,0xee,0x00 }}, - {16, 0xb420, 0, {0xcd,0x80,0xb3,0xe0,0x0c,0x58,0x02,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb430, 0, {0xa8,0x11,0x94,0x40,0x80,0x00,0x2f,0xc4,0x08,0x72,0x02,0xdd,0x08,0xd7,0x00,0x2d }}, - {16, 0xb440, 0, {0xcc,0x08,0xde,0x03,0x5c,0x00,0xb7,0x04,0x21,0x80,0xc8,0x70,0x83,0xdc,0x00,0xb4 }}, - {16, 0xb450, 0, {0xa0,0x2f,0xc0,0x0c,0x70,0x02,0xde,0x80,0x87,0x00,0x21,0xc2,0x0a,0x51,0x42,0x2a }}, - {16, 0xb460, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x84,0x00,0x2d,0xc8 }}, - {16, 0xb470, 0, {0x48,0x70,0x02,0x54,0x0c,0xa7,0x00,0x2c,0xc0,0x89,0x72,0x02,0x5c,0x00,0xb3,0x10 }}, - {16, 0xb480, 0, {0x20,0x00,0x0a,0x70,0x06,0xdc,0x00,0xb4,0x20,0x2d,0xc0,0x08,0x70,0x02,0xdc,0x80 }}, - {16, 0xb490, 0, {0x93,0x00,0x20,0xc0,0x08,0x50,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb4a0, 0, {0x20,0x14,0xc0,0x00,0x80,0x00,0x2e,0xc0,0x08,0x30,0x02,0xc4,0x08,0xa2,0x42,0x2c }}, - {16, 0xb4b0, 0, {0xc1,0x09,0x20,0x02,0x4c,0x00,0xb3,0x00,0x20,0x80,0x08,0x3c,0x22,0x8c,0x20,0xb0 }}, - {16, 0xb4c0, 0, {0x08,0x2e,0xe0,0x08,0x38,0x10,0xcf,0x0a,0x93,0x40,0xa0,0xf0,0x0a,0x10,0x02,0x08 }}, - {16, 0xb4d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa8,0x00,0xc1,0x00,0x3f,0xc0 }}, - {16, 0xb4e0, 0, {0x2c,0xf0,0x03,0x68,0x00,0xaa,0x00,0x3f,0xc0,0x2d,0x80,0x03,0x7c,0x00,0xff,0x00 }}, - {16, 0xb4f0, 0, {0x32,0x00,0x0e,0xb0,0x12,0xed,0x24,0xfa,0x08,0x27,0xc8,0x10,0xb8,0xa2,0xff,0x60 }}, - {16, 0xb500, 0, {0x98,0xa0,0xa2,0xe0,0x0c,0x50,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb510, 0, {0x80,0x00,0xc9,0x06,0xf8,0x41,0x3e,0xc0,0x0f,0xb0,0x03,0xe9,0x10,0x5a,0x20,0x3e }}, - {16, 0xb520, 0, {0xc0,0x0e,0x80,0x03,0xec,0x00,0xf3,0x00,0x7e,0x01,0x0f,0xb0,0x93,0xed,0x00,0xf8 }}, - {16, 0xb530, 0, {0x40,0x3e,0xc0,0x0e,0xb0,0x03,0xfc,0x00,0xe3,0x08,0x3c,0xc2,0x0f,0xd0,0x13,0xe0 }}, - {16, 0xb540, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf3,0x02,0xcc,0x00,0x3b,0xc2 }}, - {16, 0xb550, 0, {0x0c,0xf0,0x23,0xae,0x40,0xdf,0x81,0x39,0xc0,0x06,0xd0,0x03,0xfc,0x00,0xff,0x04 }}, - {16, 0xb560, 0, {0x31,0x41,0x0c,0xf0,0x03,0xfc,0x00,0xcc,0xa0,0x37,0xc2,0x0c,0xf0,0x03,0x7c,0x04 }}, - {16, 0xb570, 0, {0xcd,0x00,0x33,0xf0,0x0c,0xd0,0x03,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb580, 0, {0x81,0x04,0x60,0x00,0x88,0x80,0x22,0xc0,0x0a,0xb0,0x02,0xe9,0x00,0xab,0x44,0x2e }}, - {16, 0xb590, 0, {0xc0,0x08,0x88,0x02,0xec,0x00,0xbb,0x00,0xa2,0x70,0x0a,0xb4,0x02,0xcc,0x00,0xa0 }}, - {16, 0xb5a0, 0, {0x20,0x22,0xc0,0x0f,0xbc,0x02,0xcc,0x0a,0x8b,0x80,0xa2,0xc0,0x0d,0x90,0x02,0x20 }}, - {16, 0xb5b0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x20,0x00,0x89,0x80,0x2a,0xc0 }}, - {16, 0xb5c0, 0, {0x08,0xb0,0x02,0xcc,0x06,0x88,0x60,0x2e,0xc0,0x0a,0x98,0x06,0xec,0x01,0xbb,0x00 }}, - {16, 0xb5d0, 0, {0x22,0x31,0x02,0xb2,0x02,0xec,0xa0,0x8a,0x00,0x26,0xc0,0x48,0xa8,0x02,0xec,0x04 }}, - {16, 0xb5e0, 0, {0xa9,0x80,0x22,0x40,0x08,0x90,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb5f0, 0, {0x08,0x04,0x00,0x00,0x80,0x00,0x20,0xc0,0x0a,0x30,0x42,0xcc,0x00,0x80,0x01,0x2c }}, - {16, 0xb600, 0, {0xc0,0x1a,0x12,0x02,0xcc,0x00,0xb3,0x00,0x20,0x00,0x4a,0x30,0x02,0xcc,0x00,0xa0 }}, - {16, 0xb610, 0, {0x00,0x08,0xc0,0x0b,0x20,0x06,0xec,0xa0,0xa3,0x00,0xa0,0x40,0x29,0x10,0x00,0x02 }}, - {16, 0xb620, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xc8,0x50,0x3b,0xc0 }}, - {16, 0xb630, 0, {0x0c,0xb0,0x03,0xac,0x00,0xc9,0x00,0x3b,0xc0,0x0e,0x92,0x83,0xfc,0x00,0xbf,0x00 }}, - {16, 0xb640, 0, {0x12,0x00,0x0c,0xb0,0x03,0xec,0x00,0x88,0x26,0x16,0xc0,0x0c,0x80,0x17,0x5c,0x80 }}, - {16, 0xb650, 0, {0xe9,0x01,0x32,0x40,0x2c,0xd0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb660, 0, {0xa0,0x1d,0xd0,0x00,0xfc,0x20,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xfc,0x00,0x3f }}, - {16, 0xb670, 0, {0xc0,0x0d,0x80,0x03,0xfc,0x08,0xff,0x00,0x3f,0x00,0x0f,0xf0,0x03,0xfc,0x10,0xf8 }}, - {16, 0xb680, 0, {0x40,0x37,0xc0,0x0e,0xe0,0x21,0xfc,0x08,0xdf,0x00,0x3f,0x40,0x0f,0xd0,0x03,0xe0 }}, - {16, 0xb690, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0xc0,0xff,0x21,0x71,0x24 }}, - {16, 0xb6a0, 0, {0x0f,0xf1,0x83,0xf2,0x40,0xff,0x00,0x37,0xc4,0x9f,0xf2,0x47,0x3d,0x04,0xc7,0x20 }}, - {16, 0xb6b0, 0, {0x33,0xc0,0x0c,0x78,0x23,0xfe,0x40,0xe8,0x10,0x27,0xc4,0x0f,0xf2,0x13,0x3c,0x84 }}, - {16, 0xb6c0, 0, {0xc4,0x81,0x33,0x20,0x4c,0xf0,0x23,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb6d0, 0, {0x80,0x10,0xed,0x40,0xbf,0x54,0x62,0xc8,0x0b,0xf6,0x02,0xe0,0x00,0xbb,0xd0,0x22 }}, - {16, 0xb6e0, 0, {0xf0,0x1f,0xf9,0x12,0x3d,0x80,0x9f,0x81,0x2b,0xe0,0x0a,0xb8,0x12,0xe8,0x00,0x8f }}, - {16, 0xb6f0, 0, {0x04,0x22,0xd0,0x08,0xb3,0x8a,0xbf,0x42,0x8b,0x82,0x22,0xe0,0x28,0x8c,0x02,0x20 }}, - {16, 0xb700, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xb3,0x28,0x28,0x08 }}, - {16, 0xb710, 0, {0x0b,0x30,0x06,0x80,0x80,0xb3,0x02,0x24,0xd1,0x0b,0x30,0x02,0x8d,0x80,0x93,0x10 }}, - {16, 0xb720, 0, {0x20,0xce,0x8b,0x30,0x02,0xcc,0x84,0xa1,0x21,0x2c,0xcc,0x0a,0x30,0x0a,0x4c,0x00 }}, - {16, 0xb730, 0, {0x93,0x00,0x28,0xc0,0x08,0x3c,0x02,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb740, 0, {0xc0,0x15,0xac,0x10,0xbb,0x02,0x6a,0xe0,0x0b,0xb0,0x02,0xe1,0x08,0xbb,0x04,0x2a }}, - {16, 0xb750, 0, {0xc0,0x0a,0xb0,0x12,0x8c,0x00,0x9b,0x00,0x2a,0xc0,0x0b,0xb1,0x06,0xc8,0x80,0x8b }}, - {16, 0xb760, 0, {0x82,0x6a,0xc1,0x0a,0x30,0x02,0xac,0x18,0x88,0x10,0x2a,0x48,0x08,0x80,0x02,0x30 }}, - {16, 0xb770, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xfb,0x00,0xaa,0x30 }}, - {16, 0xb780, 0, {0x0f,0xb0,0x03,0xa8,0x00,0xf3,0x01,0xb6,0xc1,0x0b,0xb0,0x02,0xac,0x08,0x4b,0x00 }}, - {16, 0xb790, 0, {0xb2,0xc0,0x0f,0xb8,0x02,0xec,0x10,0xa9,0x81,0x3e,0xc0,0x0f,0xb0,0x03,0x0c,0x00 }}, - {16, 0xb7a0, 0, {0xcb,0xa0,0x18,0xd0,0x0c,0xb0,0x03,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb7b0, 0, {0xe0,0x01,0xbc,0x08,0xf7,0x00,0x37,0x00,0x0f,0xf0,0x03,0xfd,0x00,0xff,0x00,0x37 }}, - {16, 0xb7c0, 0, {0xc0,0x0f,0xb0,0x07,0x7c,0x00,0xe7,0x00,0x3e,0xc0,0x0a,0xf0,0x03,0xfe,0x00,0xf7 }}, - {16, 0xb7d0, 0, {0x00,0x36,0xc0,0x0c,0xf0,0x03,0xfc,0x00,0xff,0x80,0x37,0xe0,0x0f,0xa0,0x03,0xb8 }}, - {16, 0xb7e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xdb,0x00,0x36,0x00 }}, - {16, 0xb7f0, 0, {0x0e,0xb0,0x03,0x69,0x00,0xdb,0x09,0x3a,0xc0,0x1f,0x30,0x23,0xec,0x08,0xcb,0x20 }}, - {16, 0xb800, 0, {0x34,0xc0,0x2f,0xb0,0x03,0xec,0x40,0xeb,0x48,0x3e,0xc4,0x4d,0xb0,0x8b,0x6c,0x00 }}, - {16, 0xb810, 0, {0xcb,0x00,0x32,0x90,0x0f,0x30,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb820, 0, {0xc8,0x05,0x3c,0x00,0x8f,0x00,0x22,0x00,0x48,0xf0,0x22,0x2c,0x00,0x8f,0x00,0x23 }}, - {16, 0xb830, 0, {0xe0,0x8b,0xf5,0x10,0x3c,0x00,0x8f,0x80,0x23,0xf0,0x80,0x98,0x03,0x2d,0x44,0xdb }}, - {16, 0xb840, 0, {0x00,0x23,0xd4,0x08,0xf8,0x02,0x3c,0x00,0x83,0x00,0x22,0xc0,0x0b,0xa4,0x82,0x32 }}, - {16, 0xb850, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x93,0x00,0x24,0x00 }}, - {16, 0xb860, 0, {0x0b,0x30,0x02,0x84,0x00,0xb3,0x01,0x28,0xf6,0x09,0x34,0x32,0x8c,0x01,0xb3,0xd0 }}, - {16, 0xb870, 0, {0x24,0xe8,0x0a,0x31,0x0a,0x86,0x00,0x83,0x00,0x2a,0xe0,0x00,0x30,0x02,0x8c,0x00 }}, - {16, 0xb880, 0, {0x83,0x00,0x28,0xc0,0x89,0x38,0xa2,0x78,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb890, 0, {0x20,0x01,0x1e,0x00,0x97,0x94,0x23,0xe0,0x09,0x38,0x02,0x32,0x00,0x97,0xa1,0x21 }}, - {16, 0xb8a0, 0, {0xe4,0x0b,0x78,0x02,0x1e,0x40,0xb7,0xa0,0x25,0xec,0x08,0xfc,0x02,0x3a,0x00,0x93 }}, - {16, 0xb8b0, 0, {0xb8,0x21,0xe0,0x08,0x78,0x82,0x9e,0x40,0x87,0xc0,0x29,0xa0,0x0b,0x58,0x02,0x48 }}, - {16, 0xb8c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x2c,0x00,0xdb,0x00,0x34,0x20 }}, - {16, 0xb8d0, 0, {0x0f,0x3a,0x03,0x8e,0x00,0xf3,0xb0,0x28,0xc4,0x0b,0x3a,0x03,0xae,0x40,0xf3,0xa0 }}, - {16, 0xb8e0, 0, {0x34,0xee,0x0f,0x30,0x23,0x84,0x00,0xe3,0xf0,0x38,0xc0,0x0c,0xb0,0x0b,0x8e,0x42 }}, - {16, 0xb8f0, 0, {0xc3,0x00,0x38,0xc0,0x0f,0x30,0x63,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb900, 0, {0x40,0x1d,0xbc,0x00,0xeb,0x42,0x3a,0xc4,0x1e,0xb1,0x07,0x88,0xd1,0xe3,0x00,0x3f }}, - {16, 0xb910, 0, {0xc5,0x8f,0xf1,0x63,0xac,0x10,0xcb,0x50,0x3b,0xc3,0x0f,0xd1,0x03,0xc8,0x00,0xbb }}, - {16, 0xb920, 0, {0x20,0x3b,0xc0,0x2e,0xf1,0x03,0x1c,0x00,0xff,0x00,0x37,0xc0,0x4f,0xd1,0x03,0x90 }}, - {16, 0xb930, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x40,0xfb,0x44,0xb2,0xc0 }}, - {16, 0xb940, 0, {0x4f,0xb3,0x43,0x24,0x00,0xdb,0x10,0x36,0xc0,0x4c,0xbe,0x22,0x6d,0x20,0xcb,0x50 }}, - {16, 0xb950, 0, {0x3e,0xc9,0x4c,0xb0,0x13,0x24,0x00,0xcf,0x20,0x33,0xc0,0x3d,0xf0,0x23,0x2c,0xc0 }}, - {16, 0xb960, 0, {0xd8,0x00,0x3e,0x40,0x8f,0x30,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb970, 0, {0x48,0x11,0x9c,0x04,0xb7,0x60,0x21,0xc1,0x8b,0xf0,0xa2,0x14,0x10,0x87,0x00,0x0f }}, - {16, 0xb980, 0, {0xc8,0x0d,0x71,0x0a,0x1d,0x00,0x87,0x00,0x2c,0xcc,0x48,0x70,0x2a,0x9c,0x00,0x87 }}, - {16, 0xb990, 0, {0x0c,0x21,0xc0,0x0c,0x72,0x02,0x0c,0xa2,0x87,0x00,0x2d,0xc0,0x0b,0x70,0x02,0x12 }}, - {16, 0xb9a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xb3,0x80,0x21,0xe0 }}, - {16, 0xb9b0, 0, {0x0b,0x7a,0x02,0xde,0x00,0xb7,0x81,0x05,0xe4,0x08,0x79,0x02,0x5c,0x80,0x87,0xa0 }}, - {16, 0xb9c0, 0, {0x2d,0xe0,0x08,0xf8,0x06,0xb6,0x00,0x87,0x80,0x20,0xe4,0x0a,0x7b,0x12,0x1e,0x90 }}, - {16, 0xb9d0, 0, {0x97,0x88,0x2d,0xe0,0x0b,0x78,0x0e,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb9e0, 0, {0x48,0x14,0xcc,0x00,0xb3,0x00,0x20,0xd0,0x0b,0xb0,0x02,0x6e,0x34,0xa3,0x00,0x2c }}, - {16, 0xb9f0, 0, {0xc1,0x09,0x30,0x02,0x4c,0x00,0x83,0x00,0x2c,0xc0,0x48,0x10,0x02,0x8d,0x80,0x83 }}, - {16, 0xba00, 0, {0xc0,0x00,0xc0,0x8a,0x30,0x12,0x0c,0x00,0x80,0x00,0x2c,0x16,0x0b,0x38,0x02,0x12 }}, - {16, 0xba10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x00,0x33,0x88 }}, - {16, 0xba20, 0, {0x0f,0xa0,0x03,0x79,0x90,0xfa,0x01,0x36,0x80,0x1c,0xa0,0x03,0x68,0x00,0xca,0x00 }}, - {16, 0xba30, 0, {0x3e,0x81,0x2c,0xa0,0x0b,0xb9,0x0c,0xce,0xe2,0xb2,0x80,0x8e,0xa0,0x0b,0x28,0x00 }}, - {16, 0xba40, 0, {0xda,0x80,0x3c,0xb0,0x0f,0xe0,0x83,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xba50, 0, {0x48,0x00,0xe0,0x00,0xf0,0x00,0x3e,0x00,0x0f,0x80,0x03,0xa0,0x00,0xc8,0x00,0x2e }}, - {16, 0xba60, 0, {0x00,0x0f,0x84,0x23,0xa0,0x00,0xf0,0x40,0x3e,0x10,0x0f,0x84,0x03,0xe1,0x02,0xf8 }}, - {16, 0xba70, 0, {0x48,0x3e,0x10,0x0c,0x80,0x03,0xc0,0x10,0xf8,0x80,0x3e,0x00,0x0f,0x00,0x03,0xd2 }}, - {16, 0xba80, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0x36,0x42 }}, - {16, 0xba90, 0, {0x0f,0x90,0x03,0x24,0x18,0xf9,0x10,0x3c,0x48,0x68,0x92,0x13,0xe4,0x00,0xa9,0x11 }}, - {16, 0xbaa0, 0, {0xb2,0x60,0x0e,0x91,0x03,0x26,0x00,0xc9,0x00,0x32,0x60,0x0c,0x10,0x03,0x24,0x08 }}, - {16, 0xbab0, 0, {0xc9,0x00,0x3e,0x40,0x0c,0x90,0x23,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbac0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x40,0x0b,0x90,0x02,0xa4,0x08,0x89,0x00,0x2e }}, - {16, 0xbad0, 0, {0x42,0x48,0x94,0x02,0xe4,0x00,0x89,0x80,0x22,0x70,0x08,0x14,0x22,0xa4,0x02,0x89 }}, - {16, 0xbae0, 0, {0x42,0x2a,0x70,0x28,0x90,0x0a,0x24,0x00,0xa9,0x00,0x2e,0x40,0x28,0x90,0x02,0xa0 }}, - {16, 0xbaf0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x99,0x00,0x26,0xc0 }}, - {16, 0xbb00, 0, {0x03,0x90,0x02,0x24,0x01,0xa9,0x00,0x0e,0x40,0x0a,0x90,0x46,0xc4,0x0a,0x89,0x00 }}, - {16, 0xbb10, 0, {0x20,0x48,0x0a,0x90,0x02,0x05,0x80,0x81,0x41,0xa0,0x58,0x88,0x90,0x02,0x24,0x08 }}, - {16, 0xbb20, 0, {0x8d,0x80,0x2f,0xc0,0x08,0x98,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbb30, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0x20,0x40,0x0b,0x12,0x02,0x84,0x00,0x81,0x24,0x2c }}, - {16, 0xbb40, 0, {0x58,0x0a,0x32,0x22,0xc5,0x84,0xa1,0x00,0x20,0x50,0x08,0xb0,0x02,0x85,0x08,0x81 }}, - {16, 0xbb50, 0, {0x40,0x20,0x5a,0x08,0x16,0x82,0x04,0x00,0xa5,0x00,0x2d,0x40,0x08,0x12,0x82,0x82 }}, - {16, 0xbb60, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x36,0x14 }}, - {16, 0xbb70, 0, {0x0f,0x85,0x23,0x01,0x40,0xe8,0x00,0x3e,0x00,0x0e,0x80,0x43,0xc0,0x08,0xca,0x00 }}, - {16, 0xbb80, 0, {0x32,0x80,0x0e,0x80,0x03,0x20,0x00,0xc0,0x00,0x32,0x08,0x2c,0x02,0x03,0x20,0x08 }}, - {16, 0xbb90, 0, {0xc8,0x00,0x3f,0x00,0x0c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbba0, 0, {0x98,0x1d,0xe4,0x40,0xf9,0x10,0x3f,0x40,0x0f,0x91,0x43,0xf4,0x04,0xf9,0x10,0x3e }}, - {16, 0xbbb0, 0, {0x44,0x0d,0x11,0x03,0xe4,0x44,0x59,0x40,0x3e,0x50,0x4f,0x50,0x43,0xd4,0x02,0xfd }}, - {16, 0xbbc0, 0, {0x40,0x3e,0x40,0x0f,0x90,0x0b,0xe5,0x00,0xf9,0x00,0x3e,0x40,0x4f,0xd0,0x03,0xe6 }}, - {16, 0xbbd0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x66,0x60,0xc9,0xe0,0x32,0x44 }}, - {16, 0xbbe0, 0, {0x0f,0x9c,0x03,0xe4,0x00,0xdd,0x84,0x3f,0x68,0x8f,0xd8,0x42,0xe6,0xa0,0xdd,0xa4 }}, - {16, 0xbbf0, 0, {0x33,0x68,0x0d,0x70,0x03,0x25,0x00,0xc9,0xe0,0xb2,0x68,0x0c,0x9a,0xc3,0x26,0x00 }}, - {16, 0xbc00, 0, {0x99,0x00,0x3e,0x40,0x0f,0x9a,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbc10, 0, {0x38,0x10,0xe3,0x00,0x88,0x80,0xaa,0x20,0x8b,0x88,0x02,0xe2,0x88,0xb8,0x01,0x2e }}, - {16, 0xbc20, 0, {0x00,0x0b,0x84,0x02,0xe2,0xb0,0x88,0x50,0x22,0x14,0x08,0x80,0x02,0x82,0x80,0x88 }}, - {16, 0xbc30, 0, {0xe0,0xb6,0x3a,0x08,0xce,0xa2,0x21,0x08,0x88,0x00,0x2e,0x00,0x0b,0xc4,0x02,0x0e }}, - {16, 0xbc40, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0x81,0x60,0x68,0x48 }}, - {16, 0xbc50, 0, {0x5b,0x16,0x02,0xc4,0x20,0xa1,0x40,0x6c,0x50,0x0b,0x14,0x02,0xc4,0x00,0xa1,0x00 }}, - {16, 0xbc60, 0, {0x24,0x40,0x0b,0x90,0x22,0x14,0x90,0x85,0x42,0x21,0x50,0x5b,0x50,0x1a,0x15,0x00 }}, - {16, 0xbc70, 0, {0x95,0x00,0x2d,0x40,0x0b,0x51,0x0a,0x82,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbc80, 0, {0x18,0x15,0xa4,0x01,0x89,0x00,0x2a,0x40,0x0b,0x90,0x46,0xe4,0x00,0xb9,0x01,0x2e }}, - {16, 0xbc90, 0, {0x40,0x0b,0x90,0x20,0xe4,0x00,0xb9,0x00,0x26,0x40,0x18,0xb8,0x02,0xa4,0x02,0x8d }}, - {16, 0xbca0, 0, {0x08,0x2f,0x40,0x8b,0xd0,0x02,0x24,0x00,0x8d,0x20,0x2f,0x48,0x0b,0xd0,0x02,0x86 }}, - {16, 0xbcb0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x32,0x40 }}, - {16, 0xbcc0, 0, {0x0f,0x90,0x02,0xe4,0x10,0x49,0x00,0x3e,0x40,0x0f,0x90,0x02,0xe4,0x00,0xe9,0x01 }}, - {16, 0xbcd0, 0, {0x36,0x40,0x0f,0x18,0x13,0x24,0x10,0xc9,0x82,0x32,0x40,0x7f,0x90,0x23,0x24,0x00 }}, - {16, 0xbce0, 0, {0xd9,0x20,0x3e,0x72,0x0f,0x90,0x03,0xa8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbcf0, 0, {0x28,0x01,0x84,0x02,0xf1,0x01,0x16,0x40,0x4f,0x90,0x03,0xe5,0x10,0xf9,0x08,0x2e }}, - {16, 0xbd00, 0, {0x40,0x0f,0x90,0x13,0xe4,0x00,0xc9,0x01,0x3a,0x40,0x1f,0x90,0x03,0xe4,0x00,0xf9 }}, - {16, 0xbd10, 0, {0x20,0x34,0x40,0x8c,0x90,0x03,0xc4,0x08,0xf9,0x00,0x3e,0x60,0x0f,0x10,0x03,0x4a }}, - {16, 0xbd20, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x08,0xf8,0x00,0x3e,0x00 }}, - {16, 0xbd30, 0, {0x0c,0x80,0x03,0x60,0x00,0xe8,0x00,0x3e,0x02,0x4f,0x80,0x13,0xe0,0x00,0xd0,0x00 }}, - {16, 0xbd40, 0, {0x3e,0x00,0x0e,0x81,0x03,0x30,0x00,0xcc,0x40,0x33,0x00,0x0c,0xc0,0x0b,0x20,0x20 }}, - {16, 0xbd50, 0, {0xe8,0x00,0x3e,0x10,0x0f,0xc0,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbd60, 0, {0x28,0x05,0x28,0x04,0xba,0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0xbe,0xc8,0x6f }}, - {16, 0xbd70, 0, {0x80,0x0b,0xe1,0x22,0xa8,0x00,0x8e,0x20,0x2f,0x80,0x0b,0xe0,0x23,0x68,0x00,0x8a }}, - {16, 0xbd80, 0, {0x00,0x22,0x80,0x08,0xe0,0x02,0x29,0x00,0x8a,0x00,0x2e,0xa8,0x0b,0xa0,0x00,0xca }}, - {16, 0xbd90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x24,0xc0 }}, - {16, 0xbda0, 0, {0x09,0x30,0x02,0x0c,0x00,0xb3,0xc1,0x2c,0xe0,0x0b,0x38,0x56,0x2c,0x10,0x13,0x00 }}, - {16, 0xbdb0, 0, {0x2e,0xc0,0x0a,0x38,0x6a,0x20,0x00,0x88,0x00,0x20,0x00,0x09,0x80,0x22,0x4c,0x42 }}, - {16, 0xbdc0, 0, {0xa3,0x00,0x2c,0xe0,0x0b,0x24,0x80,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbdd0, 0, {0xa0,0x01,0x1c,0x08,0xb7,0x24,0x2f,0xe0,0x09,0x39,0x02,0x1c,0x01,0xb6,0x00,0x2d }}, - {16, 0xbde0, 0, {0x90,0x0b,0x60,0x92,0x8e,0x00,0x86,0x82,0x2d,0xc2,0x0b,0xf0,0x02,0x5c,0x06,0x87 }}, - {16, 0xbdf0, 0, {0x00,0x60,0xc0,0x29,0x70,0x02,0x5c,0x00,0x86,0x00,0x2d,0xc0,0x0b,0x60,0x02,0xe8 }}, - {16, 0xbe00, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1f,0x40,0xf3,0xe4,0x3d,0xe8 }}, - {16, 0xbe10, 0, {0x0d,0x79,0x0b,0x1e,0xc0,0x67,0x80,0x2d,0xe0,0x0f,0x70,0x43,0x1d,0x80,0xd5,0x00 }}, - {16, 0xbe20, 0, {0x3d,0x60,0x0e,0x78,0x03,0x1e,0x00,0xcd,0x80,0x31,0xe0,0x0d,0xc8,0x03,0x4e,0x00 }}, - {16, 0xbe30, 0, {0xe5,0x80,0x3d,0xe0,0x0f,0x48,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbe40, 0, {0x08,0x1d,0xac,0x80,0xfb,0x00,0x70,0xc0,0x6e,0xb6,0x13,0xad,0x40,0xfa,0x00,0x3e }}, - {16, 0xbe50, 0, {0xc0,0x0f,0x20,0x43,0x2d,0x18,0x59,0x00,0x3e,0x00,0x03,0xb0,0x0b,0xe0,0x00,0xfa }}, - {16, 0xbe60, 0, {0x00,0xbe,0x00,0x0e,0xb0,0x13,0xac,0x00,0xf8,0x00,0x3e,0xc0,0x0f,0x80,0x03,0xc2 }}, - {16, 0xbe70, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x40,0xff,0x80,0x3f,0xe6 }}, - {16, 0xbe80, 0, {0x0f,0xf8,0x23,0x2e,0x04,0xff,0x90,0x3f,0xe4,0x0d,0xba,0x03,0xff,0x40,0xcf,0x80 }}, - {16, 0xbe90, 0, {0x22,0xe1,0x0c,0x39,0x43,0x32,0x10,0xec,0x90,0x33,0x20,0x8e,0xc8,0x03,0xf2,0x00 }}, - {16, 0xbea0, 0, {0xdf,0x80,0x3f,0x60,0x0f,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbeb0, 0, {0xa8,0x11,0x9c,0x40,0xb7,0x90,0x3c,0xe0,0x0b,0x3a,0x03,0x4e,0x80,0xf3,0xb1,0x2d }}, - {16, 0xbec0, 0, {0x04,0x4c,0x38,0x23,0xae,0x00,0x80,0x80,0x34,0xe8,0x4d,0x78,0x02,0x3e,0x80,0x87 }}, - {16, 0xbed0, 0, {0xa0,0x29,0xc0,0x08,0x70,0x02,0xc0,0x80,0x86,0x02,0x2d,0x41,0x0b,0x70,0x02,0xea }}, - {16, 0xbee0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x48,0x37,0x01,0x2d,0xc9 }}, - {16, 0xbef0, 0, {0x0b,0x72,0x22,0x1c,0x84,0xb5,0x16,0x0d,0xc4,0x19,0x40,0x42,0xdc,0x80,0x87,0x00 }}, - {16, 0xbf00, 0, {0x20,0xc8,0x88,0x73,0x0a,0x9c,0x80,0xb5,0x00,0x29,0xc0,0x0a,0x48,0x02,0xc0,0x02 }}, - {16, 0xbf10, 0, {0x95,0x00,0x2d,0x42,0x0b,0x58,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbf20, 0, {0x20,0x14,0xcc,0x00,0xb3,0x00,0x2a,0xe0,0x0b,0x30,0x02,0x4c,0x20,0xa1,0x01,0x24 }}, - {16, 0xbf30, 0, {0xc1,0x08,0x00,0x02,0x8c,0x00,0x81,0x00,0x24,0x80,0x09,0x38,0x0a,0x60,0x80,0x92 }}, - {16, 0xbf40, 0, {0x40,0x2a,0x00,0x0a,0x30,0x02,0xc0,0x00,0x80,0xc8,0x2c,0x72,0x0b,0x14,0x02,0xc8 }}, - {16, 0xbf50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xff,0x00,0x2f,0xf4 }}, - {16, 0xbf60, 0, {0x8f,0xf0,0x03,0x3c,0x00,0xb9,0x00,0x3e,0x40,0x09,0x90,0x03,0xfc,0x02,0xc3,0x01 }}, - {16, 0xbf70, 0, {0x32,0xc0,0x48,0xb8,0x13,0xa1,0x00,0xba,0x00,0x2a,0x00,0x0a,0xa0,0x07,0xec,0x00 }}, - {16, 0xbf80, 0, {0xdb,0xc8,0x3e,0x90,0x0f,0xa2,0x02,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbf90, 0, {0x80,0x00,0xec,0x00,0xfb,0x02,0x3e,0xc4,0x0f,0xb0,0x63,0xec,0x01,0xf8,0x40,0x3e }}, - {16, 0xbfa0, 0, {0x40,0x0b,0x80,0x03,0xcc,0x00,0xfa,0x42,0x3e,0xc0,0x0f,0xb5,0x00,0xac,0x58,0xe9 }}, - {16, 0xbfb0, 0, {0x82,0x3e,0xc0,0x1d,0x90,0x03,0xec,0x04,0xfa,0x00,0x3e,0x80,0x0f,0xa0,0x03,0xe0 }}, - {16, 0xbfc0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x0c,0xdf,0x00,0x7f,0xc0 }}, - {16, 0xbfd0, 0, {0x2c,0xf0,0x03,0x7c,0x01,0xc7,0x00,0x33,0x40,0x8f,0xd0,0x03,0xfc,0x00,0xd8,0x00 }}, - {16, 0xbfe0, 0, {0x15,0x44,0x0c,0xe0,0x1b,0x3c,0x00,0xcb,0x0e,0x33,0xc0,0x5c,0x62,0x02,0x1c,0x02 }}, - {16, 0xbff0, 0, {0xc5,0x00,0x2b,0x80,0x0f,0xc0,0x87,0x80,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc000, 0, {0x81,0x44,0x6c,0x10,0xbb,0x00,0x2e,0xc0,0x08,0xb0,0x52,0x0c,0x01,0xfa,0xc4,0x22 }}, - {16, 0xc010, 0, {0x61,0x0b,0x88,0x03,0x6c,0x00,0x88,0x47,0x2a,0x00,0x0e,0x1c,0x02,0x20,0x02,0x88 }}, - {16, 0xc020, 0, {0x00,0xaa,0x00,0x28,0x90,0x0a,0x2c,0x04,0xa8,0x00,0x22,0x90,0x0b,0x80,0x02,0xe0 }}, - {16, 0xc030, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x2c,0x00,0xbb,0x00,0x2e,0xc1 }}, - {16, 0xc040, 0, {0x08,0x30,0x12,0x6c,0x00,0x88,0x88,0x2a,0x30,0x0b,0xb8,0x02,0xec,0x00,0x9b,0x08 }}, - {16, 0xc050, 0, {0x2a,0x40,0x08,0xb8,0x02,0x20,0x00,0x82,0x10,0x22,0x00,0x08,0xa0,0x22,0xa0,0x00 }}, - {16, 0xc060, 0, {0x8b,0x00,0x2a,0x02,0x0b,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc070, 0, {0x08,0x00,0x0c,0x00,0xb3,0x20,0x2c,0xc2,0x08,0x36,0x02,0x2c,0xc0,0xa0,0x08,0x20 }}, - {16, 0xc080, 0, {0x00,0x0b,0x33,0x46,0xcd,0x28,0x80,0x20,0x28,0xc0,0x0b,0x32,0x02,0x0c,0x20,0x81 }}, - {16, 0xc090, 0, {0x30,0x28,0xc0,0x08,0x10,0x02,0x81,0x00,0xaa,0x00,0x28,0x00,0x03,0x30,0x02,0xc2 }}, - {16, 0xc0a0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x7c,0x00,0xfb,0x28,0x2e,0xcc }}, - {16, 0xc0b0, 0, {0x0c,0x70,0x53,0x7d,0x09,0x88,0x00,0xba,0x00,0x0f,0x80,0x03,0xfd,0x80,0xda,0x60 }}, - {16, 0xc0c0, 0, {0x3a,0x50,0x8c,0xa2,0x83,0x2c,0x80,0x4b,0x20,0x30,0xc0,0x28,0xa0,0x03,0xa1,0x00 }}, - {16, 0xc0d0, 0, {0xc9,0x00,0x3a,0x00,0x0f,0x90,0x03,0xc0,0x03,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc0e0, 0, {0xa0,0x1d,0xfc,0x04,0xfb,0x00,0x7e,0xc9,0x0b,0xb6,0x03,0xfc,0xc0,0xf8,0x0c,0x3f }}, - {16, 0xc0f0, 0, {0x00,0x4f,0xc3,0x43,0x2c,0x00,0xb8,0x38,0x3f,0x8e,0x5e,0xf0,0x43,0xe0,0x10,0xf8 }}, - {16, 0xc100, 0, {0x30,0x3f,0x01,0x0f,0xd0,0x03,0x70,0x00,0xfc,0x00,0x37,0x00,0x0d,0xd0,0x07,0xe9 }}, - {16, 0xc110, 0, {0x03,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0xe0,0xcc,0x80,0x33,0xc0 }}, - {16, 0xc120, 0, {0x0d,0xf0,0x83,0xfc,0x80,0xdc,0x94,0x33,0xc0,0x1c,0xf1,0x03,0x7d,0x8c,0xff,0x30 }}, - {16, 0xc130, 0, {0x3f,0x30,0x8f,0xc8,0x03,0x7e,0x10,0xcf,0x90,0x39,0xa0,0x8d,0xf8,0x03,0xae,0x00 }}, - {16, 0xc140, 0, {0xd5,0x80,0x13,0xe0,0x0c,0x58,0x03,0xf0,0x01,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc150, 0, {0x80,0x10,0xdd,0x08,0x88,0x00,0x23,0xc4,0x08,0xfc,0x02,0xec,0xa8,0xcb,0x20,0x21 }}, - {16, 0xc160, 0, {0xc2,0x0d,0xf7,0x12,0x1c,0x40,0xdf,0x30,0x22,0xa0,0x0b,0x88,0x02,0x2e,0x04,0xdb }}, - {16, 0xc170, 0, {0x21,0x22,0xc0,0x08,0xb8,0x22,0x2e,0x00,0xb9,0x80,0x2a,0x60,0x0a,0x88,0x02,0xe0 }}, - {16, 0xc180, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x45,0xcc,0x10,0x80,0x2c,0x28,0xca }}, - {16, 0xc190, 0, {0x68,0x30,0x02,0x8d,0x00,0x9b,0x20,0x28,0xc4,0x08,0x32,0x02,0xcc,0x10,0xb3,0x00 }}, - {16, 0xc1a0, 0, {0x24,0x08,0x0b,0x80,0x42,0x6c,0x00,0x83,0x00,0x2a,0xca,0x3a,0xb0,0x02,0x8c,0x04 }}, - {16, 0xc1b0, 0, {0xb0,0x04,0x28,0xc0,0x08,0x10,0x02,0xe3,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc1c0, 0, {0xc0,0x15,0x8c,0x02,0x80,0x40,0xaa,0xc0,0x08,0xb0,0x02,0xec,0x00,0x9b,0x20,0x2a }}, - {16, 0xc1d0, 0, {0xc0,0x88,0xb0,0x02,0xac,0x00,0x9b,0x00,0x26,0xe0,0x03,0x80,0x82,0x2c,0x28,0x9b }}, - {16, 0xc1e0, 0, {0x20,0x22,0xe1,0x0b,0xb2,0x02,0xac,0x80,0xb8,0x80,0x2a,0xc1,0x0a,0x98,0x02,0xf0 }}, - {16, 0xc1f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xc8,0x50,0x3a,0xc0 }}, - {16, 0xc200, 0, {0x0d,0xb0,0x03,0xec,0x00,0xdb,0x88,0xba,0xc0,0x08,0xb0,0x03,0x6c,0x08,0xfb,0x00 }}, - {16, 0xc210, 0, {0x36,0x60,0x0f,0x8c,0x63,0x6c,0x00,0xcb,0xc0,0x3a,0x80,0x0e,0xbe,0x03,0xaf,0x84 }}, - {16, 0xc220, 0, {0x79,0x80,0x3a,0x88,0x04,0x98,0x01,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc230, 0, {0xe0,0x01,0xbc,0x00,0xfc,0x80,0x35,0xc0,0x4f,0xf0,0x03,0xdc,0x00,0xef,0x00,0x37 }}, - {16, 0xc240, 0, {0xc0,0xaf,0xf0,0x03,0x1c,0x01,0x6f,0x00,0x13,0x00,0x0f,0xc1,0x23,0xfc,0xb8,0xff }}, - {16, 0xc250, 0, {0x04,0x37,0xc0,0x0c,0xf8,0x43,0x7e,0x04,0xfd,0x00,0x3f,0x04,0x0f,0xd0,0x03,0xf8 }}, - {16, 0xc260, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xc8,0x40,0x3a,0xc0 }}, - {16, 0xc270, 0, {0x0c,0xb0,0x03,0xec,0x00,0xfb,0x40,0x38,0xc1,0x0e,0xb0,0x43,0x2c,0x08,0xc3,0x00 }}, - {16, 0xc280, 0, {0x3e,0x40,0x0e,0x82,0x03,0x6d,0x00,0xdb,0x40,0x32,0xc1,0x5f,0xb4,0xa3,0xed,0x20 }}, - {16, 0xc290, 0, {0xc9,0x40,0x32,0xe0,0x8f,0x98,0x43,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc2a0, 0, {0xc8,0x05,0x3c,0x00,0x88,0x00,0x23,0xc0,0x28,0xf5,0xc2,0xfc,0x00,0xb3,0x04,0x23 }}, - {16, 0xc2b0, 0, {0xc1,0x48,0xf0,0x22,0xbc,0x06,0xaf,0x00,0x0e,0x40,0x08,0x00,0x02,0xcd,0x00,0xbb }}, - {16, 0xc2c0, 0, {0x01,0x20,0xc0,0x08,0x30,0x02,0xee,0x00,0x81,0xe0,0x34,0xa0,0x0b,0x90,0x02,0x32 }}, - {16, 0xc2d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x02,0x80,0x00,0x28,0xc0 }}, - {16, 0xc2e0, 0, {0x09,0x3c,0x02,0x4c,0x00,0xb3,0x00,0x2c,0xc0,0x0a,0xb0,0x02,0x0c,0x00,0x83,0x01 }}, - {16, 0xc2f0, 0, {0x2c,0x00,0x0a,0x05,0x02,0xcd,0x58,0xbb,0x00,0x20,0x00,0x0a,0x3d,0x02,0xcf,0x40 }}, - {16, 0xc300, 0, {0x21,0x20,0x60,0xc0,0x09,0x10,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc310, 0, {0x20,0x01,0x1e,0x00,0x84,0x80,0x28,0xe4,0x88,0x78,0x42,0xde,0x00,0xb7,0x90,0x65 }}, - {16, 0xc320, 0, {0xe4,0x88,0x7a,0x42,0x9e,0x40,0xa7,0x90,0x2d,0xa0,0x0a,0x48,0x22,0xde,0x04,0xb7 }}, - {16, 0xc330, 0, {0x80,0x23,0x60,0x48,0x78,0x42,0xfe,0x80,0xaf,0x90,0x65,0xe0,0x0b,0xe8,0x02,0xc8 }}, - {16, 0xc340, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xc8,0x00,0x38,0xc0 }}, - {16, 0xc350, 0, {0x0c,0x30,0x03,0xcc,0x00,0xfb,0x00,0x3c,0xc0,0x0e,0xba,0x03,0x0c,0x00,0xc3,0x00 }}, - {16, 0xc360, 0, {0x3e,0x00,0x4e,0x22,0x02,0xcc,0xc0,0xfb,0x40,0x30,0xc0,0x0a,0x30,0x03,0xce,0x80 }}, - {16, 0xc370, 0, {0xe1,0x41,0x30,0xc9,0x0f,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc380, 0, {0x40,0x1d,0xbc,0x20,0xfc,0x00,0x37,0xc2,0x0e,0xf1,0x23,0xec,0x40,0xff,0x04,0x3a }}, - {16, 0xc390, 0, {0xc0,0x0f,0xb0,0x23,0xfc,0x00,0xff,0x04,0x3e,0xc0,0x0d,0xa0,0x03,0xfc,0x58,0xff }}, - {16, 0xc3a0, 0, {0x00,0xbf,0xc0,0x06,0xf0,0x83,0xdc,0x62,0xdf,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0x10 }}, - {16, 0xc3b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xed,0x80,0xc9,0x01,0x3e,0xc0 }}, - {16, 0xc3c0, 0, {0x8c,0xb2,0x07,0xae,0x04,0xcb,0x80,0x3a,0xc8,0x4c,0xb2,0x03,0x2c,0x84,0xcb,0x30 }}, - {16, 0xc3d0, 0, {0xb0,0xe0,0x0d,0x88,0x0b,0x2c,0x00,0xeb,0x00,0x30,0x00,0x0c,0xbc,0x83,0x2d,0x80 }}, - {16, 0xc3e0, 0, {0xfb,0x00,0x32,0xc0,0x0c,0x90,0x03,0xea,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc3f0, 0, {0x48,0x11,0x9c,0x40,0x87,0x00,0x2c,0xcc,0x08,0x76,0x82,0x3c,0x82,0x87,0x00,0x21 }}, - {16, 0xc400, 0, {0xc2,0x8d,0x32,0x82,0x0d,0x4c,0xa7,0x28,0x21,0x80,0x08,0x40,0x02,0x1d,0x80,0xbf }}, - {16, 0xc410, 0, {0x20,0x35,0x40,0x09,0x72,0x43,0x5c,0xa0,0xb7,0x00,0x29,0xc0,0x08,0x70,0x02,0xd2 }}, - {16, 0xc420, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x84,0x80,0x2d,0xe0 }}, - {16, 0xc430, 0, {0x08,0x78,0x02,0xde,0xc0,0x8f,0x80,0x28,0xec,0x28,0x7b,0x0a,0x9e,0x94,0x83,0x84 }}, - {16, 0xc440, 0, {0x23,0xe0,0x09,0x58,0x50,0x9e,0x10,0xa7,0xb0,0x23,0xe0,0x0b,0x78,0x02,0x1e,0x20 }}, - {16, 0xc450, 0, {0xb7,0x80,0x21,0xe0,0x09,0x78,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc460, 0, {0x48,0x14,0xcc,0x02,0x82,0x1c,0x2c,0xc0,0x28,0x30,0x02,0x4c,0x00,0x83,0xc0,0x20 }}, - {16, 0xc470, 0, {0xc0,0x08,0x30,0x02,0x0c,0x00,0xa3,0x00,0x60,0xd2,0x08,0x1d,0x02,0x0f,0x20,0xbb }}, - {16, 0xc480, 0, {0x24,0x24,0xc0,0x0b,0x3c,0x02,0x4f,0x00,0xb3,0x80,0x28,0xd8,0x09,0x32,0x02,0xd2 }}, - {16, 0xc490, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x11,0xa8,0x00,0xce,0x84,0x3e,0x80 }}, - {16, 0xc4a0, 0, {0x0c,0xa0,0x03,0xe8,0x00,0xce,0xc0,0x3a,0x80,0x08,0xa0,0x03,0xa8,0x00,0xca,0x00 }}, - {16, 0xc4b0, 0, {0x33,0x80,0x0d,0xec,0x03,0x3b,0x80,0xee,0x82,0x33,0x80,0x0a,0xc0,0x87,0x10,0x40 }}, - {16, 0xc4c0, 0, {0xf6,0xc0,0x33,0x90,0xad,0x64,0x03,0xfa,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc4d0, 0, {0x48,0x00,0xc0,0x02,0xf8,0x00,0x3c,0x00,0x1f,0x04,0x03,0xa0,0x04,0xf8,0x30,0x3e }}, - {16, 0xc4e0, 0, {0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x04,0x0f,0x80,0x93,0xe0,0x00,0xf8 }}, - {16, 0xc4f0, 0, {0x10,0x3e,0x00,0x2c,0x84,0x03,0xe0,0x00,0xf8,0x18,0x3e,0x10,0x0e,0x80,0x03,0xd2 }}, - {16, 0xc500, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xd9,0x00,0x3e,0x40 }}, - {16, 0xc510, 0, {0x0e,0x90,0x03,0xa4,0x10,0xf9,0x00,0x3e,0x40,0x04,0x90,0x03,0x24,0x00,0x41,0x00 }}, - {16, 0xc520, 0, {0x3e,0x40,0x0f,0x91,0x13,0xe1,0x08,0xf8,0x00,0x32,0x40,0x08,0x89,0x83,0xa2,0x00 }}, - {16, 0xc530, 0, {0xc9,0x80,0x32,0x40,0x0c,0x90,0x0b,0x02,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc540, 0, {0x80,0x04,0x64,0x02,0x89,0x00,0x2e,0x40,0x0d,0x90,0x02,0x24,0x00,0xb9,0x00,0x2e }}, - {16, 0xc550, 0, {0x40,0x48,0x90,0x02,0xa4,0x00,0x89,0x00,0x22,0x40,0x8b,0x94,0x42,0xe2,0x20,0xb8 }}, - {16, 0xc560, 0, {0x00,0xa2,0x40,0x08,0x94,0x02,0xe5,0x04,0xa9,0x90,0x34,0x60,0x08,0x90,0x02,0x20 }}, - {16, 0xc570, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x10,0x99,0x00,0x2e,0x40 }}, - {16, 0xc580, 0, {0x0a,0x90,0x02,0xe4,0x00,0xb9,0x00,0x24,0x40,0x0a,0x10,0x02,0x04,0x00,0xa9,0x00 }}, - {16, 0xc590, 0, {0x2a,0x40,0x0b,0x90,0x82,0xe0,0x01,0xb8,0x00,0x20,0x40,0x3a,0x90,0x02,0xa4,0x44 }}, - {16, 0xc5a0, 0, {0x89,0x04,0x22,0x62,0x08,0x98,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc5b0, 0, {0x08,0x04,0x04,0x8a,0x81,0x00,0x2c,0x48,0x09,0x32,0x06,0x44,0x80,0xb1,0x00,0x2c }}, - {16, 0xc5c0, 0, {0x48,0x0a,0x12,0x02,0x84,0x80,0xa1,0x20,0x20,0x50,0x0b,0x14,0x02,0xc5,0x00,0xb1 }}, - {16, 0xc5d0, 0, {0x40,0x20,0x50,0x0a,0x24,0x02,0xc9,0x00,0xa3,0x00,0x24,0x40,0x08,0x11,0x02,0x02 }}, - {16, 0xc5e0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xd8,0x50,0x3e,0x14 }}, - {16, 0xc5f0, 0, {0x0e,0x80,0x03,0xe1,0x40,0xf8,0x51,0x36,0x14,0x2e,0x85,0x43,0x21,0x42,0xe8,0x50 }}, - {16, 0xc600, 0, {0x3a,0x00,0x0f,0x80,0x12,0xe0,0x00,0xf8,0x00,0x32,0x00,0x1e,0x80,0x43,0xa0,0x00 }}, - {16, 0xc610, 0, {0xc8,0x01,0x32,0x00,0x0c,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc620, 0, {0x98,0x1d,0xe4,0x40,0xfd,0x00,0x3e,0x44,0x4e,0x11,0x03,0xa4,0x40,0xb5,0x00,0x3e }}, - {16, 0xc630, 0, {0x44,0x0d,0x91,0x03,0xe4,0x40,0xd9,0x10,0x3f,0x40,0x0f,0x50,0x03,0xe5,0x00,0xf9 }}, - {16, 0xc640, 0, {0x40,0x3f,0x40,0x0d,0x44,0x03,0xf1,0x00,0xf5,0x02,0x3d,0xc0,0x2f,0xd2,0x03,0xe6 }}, - {16, 0xc650, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe7,0x00,0xe9,0x00,0x36,0x60 }}, - {16, 0xc660, 0, {0x0d,0xda,0x03,0xe6,0x40,0xf9,0x40,0x3e,0x68,0x0c,0x9a,0x03,0x66,0x20,0x89,0xa0 }}, - {16, 0xc670, 0, {0x33,0x40,0x0e,0x90,0x07,0xa6,0x00,0xf9,0x80,0x3e,0x50,0x0c,0xca,0x03,0xf3,0x80 }}, - {16, 0xc680, 0, {0xc5,0x02,0x33,0x40,0x0c,0xc0,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc690, 0, {0x38,0x10,0xe3,0x04,0x88,0xa2,0x20,0x38,0x08,0x80,0x02,0xe3,0x40,0xb0,0x80,0x2e }}, - {16, 0xc6a0, 0, {0x28,0x08,0x8a,0x82,0x23,0x80,0x88,0x80,0x22,0x00,0xdb,0x88,0x02,0x62,0x04,0xb8 }}, - {16, 0xc6b0, 0, {0xb0,0x2e,0xa8,0x88,0x8e,0xa2,0xea,0x80,0x88,0x00,0x2a,0x00,0x28,0x88,0x03,0x8e }}, - {16, 0xc6c0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x82,0xa9,0x08,0x2c,0x52 }}, - {16, 0xc6d0, 0, {0x0b,0x14,0x02,0xc4,0x80,0xb1,0x21,0x0c,0x52,0x88,0x14,0x02,0x44,0x20,0x91,0x69 }}, - {16, 0xc6e0, 0, {0x20,0x40,0x0a,0x10,0x82,0xc6,0xe0,0xb1,0x0c,0x2c,0x48,0x08,0x01,0x02,0xe1,0x93 }}, - {16, 0xc6f0, 0, {0xa1,0x01,0x24,0x41,0x0a,0x10,0x02,0xc2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc700, 0, {0x18,0x15,0xa4,0x00,0x89,0x04,0x22,0x40,0x08,0x90,0x00,0xe4,0x00,0x39,0x02,0x0e }}, - {16, 0xc710, 0, {0x40,0x08,0x10,0x62,0x24,0x00,0x91,0x00,0x62,0x40,0x8b,0x80,0x02,0xe0,0x54,0xb9 }}, - {16, 0xc720, 0, {0x0c,0x2e,0x40,0x09,0xb6,0x52,0xec,0x00,0xa9,0x00,0x2a,0x40,0x0a,0x92,0x80,0x86 }}, - {16, 0xc730, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe4,0x00,0xe1,0x60,0x36,0x40 }}, - {16, 0xc740, 0, {0x0d,0x90,0x23,0xe4,0x00,0xf9,0x30,0x3e,0x40,0x2c,0x90,0x43,0x64,0x06,0xc9,0x00 }}, - {16, 0xc750, 0, {0x32,0x49,0x0e,0x8d,0x93,0xe0,0x00,0xf9,0x00,0x2e,0x40,0x2c,0x94,0x03,0xc7,0x40 }}, - {16, 0xc760, 0, {0xe9,0x20,0x30,0x55,0x0e,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc770, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x1e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x80,0x3c }}, - {16, 0xc780, 0, {0x40,0x4f,0x90,0x03,0xe4,0x00,0xe9,0x04,0xbe,0x40,0x0f,0x88,0x33,0x62,0x00,0xf9 }}, - {16, 0xc790, 0, {0xc2,0x3e,0x48,0x2e,0x88,0x33,0xe2,0x00,0xd9,0x00,0x3e,0x60,0x0d,0x80,0x03,0xca }}, - {16, 0xc7a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x3e,0x00 }}, - {16, 0xc7b0, 0, {0x0d,0x80,0x03,0xa0,0x04,0xe8,0x40,0xba,0x00,0x0c,0x80,0x03,0xe0,0x04,0xc8,0x00 }}, - {16, 0xc7c0, 0, {0x3a,0x00,0x0e,0x8c,0x03,0xe0,0x00,0xf8,0x02,0x32,0x00,0x0e,0x80,0x03,0x61,0x20 }}, - {16, 0xc7d0, 0, {0xf8,0x00,0x32,0x16,0x0f,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc7e0, 0, {0x28,0x05,0x28,0x00,0x8a,0x00,0x2e,0x80,0x08,0xe2,0x03,0x28,0x00,0x8a,0x00,0x22 }}, - {16, 0xc7f0, 0, {0x80,0x08,0xa0,0x02,0xe8,0x04,0x8a,0x00,0x2e,0xa2,0x09,0xe8,0x02,0xfa,0x04,0xbe }}, - {16, 0xc800, 0, {0x00,0xa2,0x80,0x08,0xcd,0x82,0x33,0x20,0xb6,0xc0,0x37,0xa0,0x4b,0xc8,0x82,0xca }}, - {16, 0xc810, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6c,0x00,0x83,0x00,0x26,0xc0 }}, - {16, 0xc820, 0, {0x09,0x38,0x02,0x4c,0x00,0xb3,0x00,0x24,0xc0,0x08,0x30,0x02,0xec,0x00,0x83,0x00 }}, - {16, 0xc830, 0, {0x28,0xe0,0x0b,0x30,0x02,0xce,0x81,0xb3,0x00,0x62,0xc0,0x08,0x3c,0x02,0x4f,0x00 }}, - {16, 0xc840, 0, {0xb3,0xa0,0x20,0xb0,0x03,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc850, 0, {0xa0,0x01,0x0c,0x41,0x87,0x34,0x2d,0xc0,0x08,0x60,0x02,0x9e,0x40,0xb7,0xa0,0x2d }}, - {16, 0xc860, 0, {0xc0,0x08,0x73,0x02,0xdc,0x00,0x87,0x20,0x2d,0xc0,0x0b,0x70,0x82,0xdd,0x85,0xbf }}, - {16, 0xc870, 0, {0x81,0x63,0xc8,0x88,0x7b,0x02,0x1c,0x00,0xb7,0x40,0x65,0x00,0x1b,0x72,0x02,0xe8 }}, - {16, 0xc880, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x81,0x3d,0xe0 }}, - {16, 0xc890, 0, {0xdd,0x70,0x03,0xfe,0x80,0xf7,0x90,0x3f,0xe0,0x2c,0x79,0x03,0xfe,0x80,0xc7,0xa0 }}, - {16, 0xc8a0, 0, {0x39,0xe0,0x0f,0x7a,0x02,0xde,0x84,0xf7,0xc2,0x31,0xf2,0x0c,0x79,0x03,0x5e,0x04 }}, - {16, 0xc8b0, 0, {0xf7,0x84,0x31,0x60,0x0f,0x7e,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc8c0, 0, {0x08,0x1d,0xad,0x0a,0xfb,0x60,0x7e,0xd4,0x0f,0x30,0x03,0x6c,0x00,0xcb,0x00,0x32 }}, - {16, 0xc8d0, 0, {0xde,0x2f,0xb2,0x03,0xed,0x42,0x1b,0x60,0x3e,0xc1,0x0d,0xb1,0x03,0xec,0x50,0xf7 }}, - {16, 0xc8e0, 0, {0x80,0x3d,0xd8,0x2e,0x32,0x03,0xec,0x30,0xfb,0x00,0x3e,0x40,0x0f,0xb0,0x03,0xc2 }}, - {16, 0xc8f0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x00,0xcb,0xd0,0x3f,0xf0 }}, - {16, 0xc900, 0, {0x4c,0xf8,0x13,0xfe,0x00,0xcf,0x88,0x3f,0xe0,0x0c,0xf8,0x43,0x3f,0x00,0xcf,0xc8 }}, - {16, 0xc910, 0, {0x33,0xe0,0x0c,0xf8,0x03,0xfe,0x00,0xff,0x80,0x3f,0xe0,0x2c,0xf8,0x03,0xbe,0x20 }}, - {16, 0xc920, 0, {0xc7,0x80,0x33,0xe0,0x0c,0xf8,0x01,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc930, 0, {0xa8,0x01,0xbc,0x40,0x87,0x90,0x3d,0xc0,0x08,0x40,0x02,0xdc,0x80,0xd7,0x00,0x2d }}, - {16, 0xc940, 0, {0xc0,0x0c,0x30,0x03,0x7c,0x00,0x87,0x10,0x21,0xc4,0x1e,0x70,0x20,0xdc,0x44,0xb7 }}, - {16, 0xc950, 0, {0x00,0x39,0xc0,0x0c,0x71,0x02,0x1c,0x40,0xd7,0x02,0x29,0x40,0x08,0x70,0x02,0x2a }}, - {16, 0xc960, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x32,0x2d,0xc0 }}, - {16, 0xc970, 0, {0x08,0x70,0x02,0xdc,0x01,0x87,0x00,0x2c,0xc0,0x2b,0x70,0x0a,0x5c,0x00,0x83,0x00 }}, - {16, 0xc980, 0, {0x23,0xc0,0x08,0x70,0x02,0xdd,0x00,0xb7,0x00,0x2d,0xc4,0x0b,0xf0,0x02,0x9c,0x20 }}, - {16, 0xc990, 0, {0x87,0x18,0x29,0x40,0x08,0x70,0x82,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc9a0, 0, {0x20,0x14,0xcc,0x00,0x83,0x02,0x28,0xc0,0x08,0x10,0x02,0xcc,0x08,0x83,0x40,0x2e }}, - {16, 0xc9b0, 0, {0xc0,0x2a,0x30,0x02,0x0c,0x00,0x8b,0x00,0x20,0xf2,0x0a,0x30,0x02,0xce,0x00,0xb3 }}, - {16, 0xc9c0, 0, {0x88,0x2a,0xd0,0x0a,0x30,0x06,0x0c,0x00,0x92,0x00,0x28,0x78,0x08,0x3c,0x42,0x08 }}, - {16, 0xc9d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x02,0xc7,0x00,0x2f,0xc0 }}, - {16, 0xc9e0, 0, {0x2c,0x90,0x02,0xfc,0x02,0x8f,0xd8,0x3f,0xc0,0x4b,0xf0,0x02,0x7c,0x02,0xcf,0x00 }}, - {16, 0xc9f0, 0, {0x20,0xf2,0x08,0xb0,0x13,0xee,0x80,0xff,0x00,0x3f,0xd4,0x2e,0xbd,0x83,0xac,0x00 }}, - {16, 0xca00, 0, {0xcb,0x80,0x3a,0xa0,0xac,0xb8,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xca10, 0, {0x80,0x00,0xec,0x00,0xfb,0x10,0x3e,0xc0,0x0f,0x84,0x03,0xec,0x10,0xfb,0x00,0x3e }}, - {16, 0xca20, 0, {0xc0,0x01,0xb0,0x03,0xec,0x00,0xfb,0x00,0xbe,0xc0,0x0e,0xb0,0x23,0xec,0x08,0xfb }}, - {16, 0xca30, 0, {0x10,0x3f,0xc0,0x0d,0xb4,0x03,0xed,0x04,0xf9,0x00,0x1e,0x14,0xcf,0xb0,0x83,0xe0 }}, - {16, 0xca40, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xcf,0x00,0x30,0xc0 }}, - {16, 0xca50, 0, {0x0c,0x40,0x03,0xac,0x00,0xff,0x00,0x3f,0xc0,0x2c,0xb0,0x03,0xbc,0x00,0xff,0x00 }}, - {16, 0xca60, 0, {0xb3,0xe0,0x0d,0xfa,0x03,0x7e,0x80,0xcf,0x00,0x33,0xc0,0x0c,0xfc,0x43,0xff,0x20 }}, - {16, 0xca70, 0, {0xff,0x00,0x3f,0x40,0x08,0xf8,0x03,0xc0,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xca80, 0, {0x81,0x04,0x6c,0x10,0xab,0x00,0x2a,0xc0,0x0a,0x8e,0x42,0x2c,0x04,0xbb,0x00,0x2e }}, - {16, 0xca90, 0, {0xc0,0x08,0xb0,0x02,0x6c,0x00,0xbb,0x00,0x3a,0xc0,0x0e,0x30,0x02,0x0d,0x08,0x83 }}, - {16, 0xcaa0, 0, {0x02,0x22,0xc0,0x0a,0xbc,0x02,0xef,0x00,0xbb,0xc0,0x2c,0x68,0x0a,0xb9,0x02,0xe0 }}, - {16, 0xcab0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x0c,0x00,0x8b,0x00,0x22,0xc0 }}, - {16, 0xcac0, 0, {0x08,0xb8,0x02,0xac,0x00,0xbb,0x02,0x2e,0xc0,0x08,0xb0,0x02,0xec,0x00,0xbb,0x00 }}, - {16, 0xcad0, 0, {0x26,0x48,0x19,0xb0,0x02,0x6d,0x00,0x8b,0x00,0x22,0xc0,0x0a,0xb0,0x02,0xec,0x04 }}, - {16, 0xcae0, 0, {0xbb,0x1c,0x2e,0x20,0x0a,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcaf0, 0, {0x08,0x14,0x0c,0x00,0xab,0x20,0x28,0xc0,0x0a,0x00,0x02,0x0c,0x00,0x93,0x04,0x2c }}, - {16, 0xcb00, 0, {0xc1,0x08,0x30,0x02,0x4c,0x00,0xb3,0x00,0x24,0x41,0x09,0xb8,0x02,0x0c,0x02,0x83 }}, - {16, 0xcb10, 0, {0x01,0xa0,0xc0,0x0a,0x30,0x02,0xcc,0x10,0x93,0x00,0x2c,0x00,0x0a,0x30,0x02,0xc2 }}, - {16, 0xcb20, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x7c,0x00,0xcf,0x28,0x33,0xc0 }}, - {16, 0xcb30, 0, {0x0c,0xa0,0x46,0xac,0x11,0xbf,0x00,0x3f,0xc0,0x5c,0xf0,0x43,0xfc,0x00,0xff,0x04 }}, - {16, 0xcb40, 0, {0x32,0x40,0x0d,0xb0,0x03,0x6c,0x08,0xcb,0x04,0x31,0xc0,0x0c,0xb0,0x33,0xed,0x40 }}, - {16, 0xcb50, 0, {0xfb,0x04,0x3e,0x40,0x0e,0xb0,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcb60, 0, {0xa0,0x15,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xc0,0x23,0xfc,0x01,0xff,0x00,0x3f }}, - {16, 0xcb70, 0, {0xc0,0x4f,0xf0,0x87,0x7c,0x00,0xff,0x00,0x39,0x40,0x0e,0xf0,0x03,0xfc,0x00,0xff }}, - {16, 0xcb80, 0, {0x00,0x3f,0xc0,0x0f,0x70,0x03,0xdc,0x80,0xff,0x00,0x3d,0x40,0x0f,0x70,0x03,0xe8 }}, - {16, 0xcb90, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x40,0xeb,0x48,0x3e,0xc2 }}, - {16, 0xcba0, 0, {0x0e,0x09,0x03,0xbc,0x60,0xc0,0x20,0x35,0x24,0x0e,0xd2,0x13,0x2c,0x60,0xfb,0x6a }}, - {16, 0xcbb0, 0, {0x33,0xc0,0x0f,0xca,0x03,0x22,0x20,0xc0,0x80,0x37,0xc0,0x0d,0xf0,0x03,0x7c,0x00 }}, - {16, 0xcbc0, 0, {0xef,0x00,0x33,0x24,0x0f,0xc8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcbd0, 0, {0x80,0x10,0xdd,0x00,0x8f,0x60,0x2f,0xd8,0x08,0xa2,0x02,0xfd,0x80,0xc8,0x70,0x22 }}, - {16, 0xcbe0, 0, {0x00,0x2c,0xfd,0x07,0xdc,0x84,0xbf,0x60,0x23,0xd2,0x0b,0xbd,0x02,0x23,0x00,0x88 }}, - {16, 0xcbf0, 0, {0x80,0xa2,0x20,0x88,0xb0,0x22,0x34,0x00,0xbb,0x50,0x22,0xc8,0x0b,0xb0,0x02,0x20 }}, - {16, 0xcc00, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x40,0xa3,0x03,0x2c,0xc2 }}, - {16, 0xcc10, 0, {0x0a,0x00,0x42,0x8c,0x82,0xa3,0x0a,0x24,0x80,0x0b,0x30,0x02,0xcc,0x90,0xb3,0x00 }}, - {16, 0xcc20, 0, {0x28,0xd8,0x0b,0x10,0x02,0x8c,0x02,0x90,0x00,0x20,0xc0,0x0b,0x10,0x42,0x4c,0x00 }}, - {16, 0xcc30, 0, {0xb3,0x04,0x24,0xc0,0x0b,0x30,0x0e,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcc40, 0, {0xc0,0x15,0xac,0x10,0x9b,0x04,0x2c,0xc0,0xf8,0x98,0x06,0xec,0x00,0xab,0x80,0x26 }}, - {16, 0xcc50, 0, {0x20,0x08,0x90,0x2a,0xac,0x10,0xbb,0x00,0x0a,0xc0,0x1b,0xb0,0x22,0xad,0x00,0x98 }}, - {16, 0xcc60, 0, {0x40,0x2a,0x70,0x4b,0xb0,0x02,0x2c,0x00,0xb3,0x00,0xa6,0x86,0x1b,0xb0,0x82,0xb0 }}, - {16, 0xcc70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xeb,0x00,0x3e,0xc0 }}, - {16, 0xcc80, 0, {0x8e,0x98,0x03,0xac,0x08,0xe8,0xc0,0x36,0x30,0x4f,0xb0,0x42,0xec,0x00,0xf9,0x80 }}, - {16, 0xcc90, 0, {0x3a,0xc0,0x8f,0x88,0x42,0x20,0x10,0xc8,0x10,0x30,0xf0,0x0f,0x30,0x13,0x6c,0x10 }}, - {16, 0xcca0, 0, {0xeb,0x00,0x36,0xf0,0x0f,0xbd,0x03,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xccb0, 0, {0xe0,0x01,0xbc,0x00,0xef,0x04,0x7f,0xc0,0x0f,0xf0,0x43,0xdc,0x00,0xc4,0x00,0x3b }}, - {16, 0xccc0, 0, {0x40,0x8b,0xdc,0x03,0x7c,0x10,0xf9,0x90,0x36,0xc2,0x4f,0xf9,0x23,0x62,0x41,0xac }}, - {16, 0xccd0, 0, {0x01,0x13,0x40,0x04,0xb0,0x03,0xe4,0x00,0xff,0x00,0x3b,0xc0,0x0f,0xc0,0x03,0x78 }}, - {16, 0xcce0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8c,0x12,0xcb,0x00,0xf2,0xc0 }}, - {16, 0xccf0, 0, {0x0f,0x80,0x03,0xac,0x08,0xd9,0x00,0x3a,0x80,0x0f,0x12,0x03,0xac,0x00,0xe1,0x00 }}, - {16, 0xcd00, 0, {0x32,0xc0,0x0c,0x90,0x03,0xed,0x02,0xc8,0x40,0x3e,0xd0,0x0f,0x90,0x13,0x2c,0x02 }}, - {16, 0xcd10, 0, {0xdb,0x00,0x3e,0x50,0x0c,0xb4,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcd20, 0, {0xc8,0x05,0x3c,0x00,0x8f,0x00,0x17,0xc0,0x08,0x90,0x02,0x3c,0x08,0x8d,0x00,0x22 }}, - {16, 0xcd30, 0, {0x54,0x08,0xb4,0x03,0x3c,0x00,0x89,0x00,0x23,0xc0,0x40,0x35,0x02,0xcc,0x24,0x80 }}, - {16, 0xcd40, 0, {0x00,0x22,0x74,0x4c,0xb0,0x02,0x2c,0x00,0x8f,0x00,0x2e,0xd4,0x0a,0xb0,0x0a,0x32 }}, - {16, 0xcd50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x4c,0x02,0x83,0x00,0x24,0xc0 }}, - {16, 0xcd60, 0, {0x09,0x00,0x02,0x8c,0x01,0x90,0x00,0x6a,0x41,0x0a,0x30,0x20,0x4e,0x10,0x31,0x02 }}, - {16, 0xcd70, 0, {0x2c,0xc0,0x09,0x20,0x06,0xce,0x00,0x80,0x00,0x60,0xe0,0x0a,0x30,0x82,0x0c,0x08 }}, - {16, 0xcd80, 0, {0x83,0x08,0x2c,0xd0,0x09,0xb0,0x02,0x78,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcd90, 0, {0x20,0x01,0x1e,0x04,0x87,0xb0,0x20,0xec,0x09,0xe9,0x02,0x8e,0x58,0x9d,0xb0,0x2b }}, - {16, 0xcda0, 0, {0xa5,0x40,0x5b,0x06,0xde,0x40,0x95,0x94,0x2d,0xe4,0x19,0x7b,0x06,0xde,0x00,0x84 }}, - {16, 0xcdb0, 0, {0x80,0x60,0xe0,0x0a,0x78,0x0a,0x16,0x10,0x87,0x80,0x2d,0x68,0x0b,0x79,0x02,0x48 }}, - {16, 0xcdc0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xcb,0xa0,0x24,0xe0 }}, - {16, 0xcdd0, 0, {0x0f,0x2a,0x03,0x8e,0x00,0xd2,0xd0,0x38,0xfa,0x0f,0x18,0xc3,0xce,0x24,0x31,0xb0 }}, - {16, 0xcde0, 0, {0x3c,0xe5,0x0c,0x3b,0x17,0xce,0x04,0xc0,0x82,0x38,0xc2,0x9e,0x10,0x03,0x0c,0x00 }}, - {16, 0xcdf0, 0, {0xc3,0x01,0x3e,0xc0,0x0d,0x81,0x03,0x52,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xce00, 0, {0x40,0x1d,0xbc,0x00,0xef,0x10,0x3e,0xc2,0x0e,0xb1,0x23,0x2c,0xc1,0xab,0x01,0x36 }}, - {16, 0xce10, 0, {0x80,0x0f,0xb0,0x23,0x2d,0x90,0xe9,0x84,0x72,0xc8,0x62,0xf1,0x17,0xfc,0x00,0xfc }}, - {16, 0xce20, 0, {0x00,0x3b,0xc4,0x1d,0xf0,0x03,0xec,0x00,0xef,0x08,0x3f,0xc8,0x0e,0xf1,0x03,0x90 }}, - {16, 0xce30, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x80,0xfb,0xa4,0x3a,0xc8 }}, - {16, 0xce40, 0, {0x0e,0x90,0x03,0x2c,0x04,0xca,0x00,0x30,0x60,0x2d,0x1a,0x27,0x6c,0x84,0xcb,0x60 }}, - {16, 0xce50, 0, {0x32,0xd2,0x0c,0xa0,0x13,0x2d,0x84,0xcb,0x02,0x3e,0xc0,0x0d,0xb8,0x03,0xac,0x80 }}, - {16, 0xce60, 0, {0xcb,0x81,0x32,0x80,0x0c,0xb0,0x03,0xaa,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xce70, 0, {0x48,0x11,0x9c,0xa4,0xb7,0x28,0x73,0xc2,0x08,0xf0,0x02,0x3c,0xc0,0x8f,0x00,0x31 }}, - {16, 0xce80, 0, {0xc0,0x09,0x70,0x82,0x9c,0x80,0x87,0x0c,0x20,0xd8,0x09,0x70,0x22,0x1c,0x30,0x84 }}, - {16, 0xce90, 0, {0x00,0x3d,0xc0,0x08,0x70,0x02,0x14,0x24,0x87,0xa0,0x21,0xc0,0x08,0x70,0x12,0x12 }}, - {16, 0xcea0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x40,0xb3,0x95,0x29,0xe9 }}, - {16, 0xceb0, 0, {0x0a,0x68,0x02,0x9e,0xd0,0x86,0xf0,0xa3,0xe0,0x08,0x78,0x12,0x9e,0x44,0xa3,0x82 }}, - {16, 0xcec0, 0, {0x21,0xe8,0x0b,0x38,0x02,0x0e,0x10,0x87,0x80,0x2f,0xe0,0x0b,0x18,0x02,0x8e,0x02 }}, - {16, 0xced0, 0, {0x87,0x00,0x21,0xe0,0x08,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcee0, 0, {0x48,0x14,0xcc,0x00,0xb3,0x00,0x24,0xc0,0x48,0x30,0x02,0x0c,0x04,0x83,0x80,0x20 }}, - {16, 0xcef0, 0, {0xd0,0x09,0x10,0x02,0x8c,0x06,0xa3,0x80,0x20,0xc0,0x0b,0x30,0x02,0x0c,0x02,0x80 }}, - {16, 0xcf00, 0, {0x40,0x28,0xd2,0x0a,0x30,0x02,0x0c,0x01,0x83,0x00,0x22,0x3c,0x08,0x87,0x02,0x12 }}, - {16, 0xcf10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x18,0xfa,0x00,0x3a,0x80 }}, - {16, 0xcf20, 0, {0x8e,0xe4,0x42,0x28,0x02,0xce,0x80,0x33,0x80,0x4d,0xa0,0x83,0xe8,0x00,0xea,0xa0 }}, - {16, 0xcf30, 0, {0xb2,0x80,0x0a,0xa0,0x0a,0x28,0x00,0xce,0x18,0x2f,0x80,0x0f,0xa0,0x13,0xa8,0x00 }}, - {16, 0xcf40, 0, {0xca,0x00,0x32,0x90,0x2c,0xac,0x0b,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcf50, 0, {0x48,0x00,0xe0,0x00,0xf8,0x04,0x3a,0x00,0x0f,0x80,0x83,0xc0,0x08,0xe8,0x03,0x3a }}, - {16, 0xcf60, 0, {0x00,0x0e,0x80,0x22,0xc0,0x00,0xd0,0x00,0x7e,0x10,0xa4,0x80,0x03,0xc0,0x00,0xf8 }}, - {16, 0xcf70, 0, {0x00,0x3e,0x10,0x0d,0x84,0x03,0xc0,0x00,0xf8,0x00,0xbe,0x00,0x0f,0x80,0x01,0x52 }}, - {16, 0xcf80, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x02,0xc9,0x00,0x36,0x40 }}, - {16, 0xcf90, 0, {0x0c,0x90,0x03,0x64,0x02,0x89,0x04,0x32,0x42,0x0d,0x92,0x03,0xe6,0x42,0xc9,0x00 }}, - {16, 0xcfa0, 0, {0x32,0x70,0x0e,0x12,0x0b,0x24,0x08,0xc9,0x00,0x3e,0x45,0x0e,0x99,0x03,0xe4,0x02 }}, - {16, 0xcfb0, 0, {0xc1,0x00,0x32,0x50,0x04,0x94,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcfc0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x6e,0x40,0x08,0x90,0x02,0x24,0x00,0x89,0x00,0x22 }}, - {16, 0xcfd0, 0, {0x54,0x0b,0x90,0x03,0xe6,0x00,0x89,0x00,0x22,0x40,0x08,0x90,0x0a,0x24,0x00,0x89 }}, - {16, 0xcfe0, 0, {0x00,0x38,0x48,0x08,0x90,0x82,0xe4,0x04,0xd9,0x00,0x22,0x40,0x08,0x90,0x02,0x20 }}, - {16, 0xcff0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x01,0x2c,0x40 }}, - {16, 0xd000, 0, {0x28,0x10,0x42,0x64,0x00,0xa1,0x04,0x22,0x50,0x01,0x90,0x42,0xe4,0x00,0x89,0x04 }}, - {16, 0xd010, 0, {0x20,0x42,0x0a,0x90,0x42,0x34,0x00,0x89,0x00,0x6e,0x40,0x0a,0x90,0x00,0xe4,0x00 }}, - {16, 0xd020, 0, {0x89,0x00,0x23,0x40,0x0a,0xd0,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd030, 0, {0x08,0x04,0x04,0x80,0x81,0x24,0x2c,0x48,0x08,0x10,0x02,0x04,0x80,0xa1,0x20,0x28 }}, - {16, 0xd040, 0, {0x40,0x0b,0x10,0x02,0x85,0x80,0x81,0x20,0x20,0x48,0x08,0x50,0x62,0x14,0x02,0x81 }}, - {16, 0xd050, 0, {0x03,0x2e,0x40,0x88,0x16,0x82,0xc4,0xa0,0x91,0x28,0x21,0x40,0x2a,0x50,0x02,0x02 }}, - {16, 0xd060, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc8,0x50,0x2e,0x14 }}, - {16, 0xd070, 0, {0x0c,0x85,0x03,0x61,0x40,0xe8,0x50,0xb2,0x15,0x4d,0x80,0x02,0xc0,0x00,0x48,0x50 }}, - {16, 0xd080, 0, {0xb2,0x15,0x1a,0x80,0x13,0x30,0x08,0xc8,0x00,0x3e,0x00,0x0e,0x82,0x03,0xe0,0x80 }}, - {16, 0xd090, 0, {0xc0,0x20,0x30,0x00,0x0e,0x40,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd0a0, 0, {0x98,0x1d,0xe4,0x40,0xf9,0x10,0x3e,0x44,0x0f,0xd0,0x03,0xe4,0x48,0xdd,0x10,0x37 }}, - {16, 0xd0b0, 0, {0x40,0x0f,0xd4,0x07,0xe4,0x40,0xfd,0x10,0x3e,0x45,0x0f,0x94,0x03,0xe5,0x08,0xfd }}, - {16, 0xd0c0, 0, {0x02,0x39,0xd0,0x0f,0xd0,0x43,0xf4,0xa0,0xf9,0x28,0x3e,0x4b,0x0d,0x92,0x83,0xe6 }}, - {16, 0xd0d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x80,0xc9,0xa6,0x32,0x68 }}, - {16, 0xd0e0, 0, {0x0c,0x90,0x03,0xa6,0x81,0xe9,0xe9,0x3b,0x40,0x0e,0x58,0x03,0x36,0x20,0xc9,0xa0 }}, - {16, 0xd0f0, 0, {0x37,0x78,0x0d,0xda,0x03,0x36,0x26,0xc5,0x00,0x37,0x69,0x0e,0xde,0x03,0xa6,0x82 }}, - {16, 0xd100, 0, {0xcd,0xc0,0x33,0x50,0x0f,0xd0,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd110, 0, {0x38,0x10,0xe3,0xa4,0x88,0xa9,0x22,0x3a,0x08,0x08,0x00,0x22,0xa0,0xb8,0xe5,0x30 }}, - {16, 0xd120, 0, {0x20,0x28,0x80,0x22,0x43,0xa0,0x08,0xe8,0x2a,0x3d,0x08,0xa4,0x62,0x20,0x00,0x88 }}, - {16, 0xd130, 0, {0x00,0x2e,0x10,0x08,0x8e,0x03,0x23,0xa0,0x88,0xa0,0x20,0x28,0x0b,0x8a,0x82,0x0e }}, - {16, 0xd140, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x40,0x91,0x40,0x20,0x44 }}, - {16, 0xd150, 0, {0x08,0x90,0xa2,0x85,0x10,0xa1,0x20,0x2c,0x42,0x0b,0x14,0x12,0x8c,0x01,0x91,0x10 }}, - {16, 0xd160, 0, {0x2c,0x48,0x09,0x11,0x0a,0xc4,0x00,0x81,0x00,0x2c,0x50,0x0b,0x11,0x12,0xc5,0x01 }}, - {16, 0xd170, 0, {0xb1,0x40,0x24,0x48,0x0b,0x18,0x0e,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd180, 0, {0x18,0x15,0xa4,0x00,0x91,0x00,0x22,0x41,0x08,0x94,0x42,0x24,0x00,0xb1,0x40,0x20 }}, - {16, 0xd190, 0, {0x40,0x49,0xb2,0x62,0x24,0x00,0x99,0x00,0x0a,0x40,0x08,0x90,0x02,0xe5,0x80,0x89 }}, - {16, 0xd1a0, 0, {0x00,0x2e,0x40,0x09,0xb0,0x02,0x24,0x80,0xb9,0x00,0x26,0x50,0x4b,0x90,0x02,0x06 }}, - {16, 0xd1b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x02,0xd9,0x00,0xb2,0x40 }}, - {16, 0xd1c0, 0, {0x2c,0x95,0x13,0xa4,0x10,0xe9,0x00,0xbe,0x60,0x8f,0x90,0x0b,0xa4,0x10,0x59,0x00 }}, - {16, 0xd1d0, 0, {0x1e,0x40,0x9d,0x94,0x23,0xe4,0x02,0x89,0x00,0x34,0x40,0x0f,0x90,0x03,0xe6,0x08 }}, - {16, 0xd1e0, 0, {0x79,0x00,0xb6,0x40,0x07,0x98,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd1f0, 0, {0x28,0x01,0x84,0x00,0xe9,0x02,0x3c,0x40,0x2f,0x98,0x02,0xe4,0x00,0xf9,0x42,0x3a }}, - {16, 0xd200, 0, {0x68,0x0a,0x10,0x03,0xe4,0x10,0xe9,0x00,0x3e,0x40,0x0e,0x90,0x0f,0x26,0x00,0xf9 }}, - {16, 0xd210, 0, {0x04,0x3e,0x40,0x0e,0x1c,0x03,0xe6,0x00,0xc1,0x00,0x3a,0x50,0x0f,0x99,0x83,0xca }}, - {16, 0xd220, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xe8,0x00,0x3a,0x00 }}, - {16, 0xd230, 0, {0x0c,0x84,0x03,0x20,0x00,0xd8,0x42,0x32,0x04,0x0c,0x88,0x13,0xe0,0x00,0xc8,0x00 }}, - {16, 0xd240, 0, {0x30,0x00,0x0c,0x04,0x0b,0x00,0x00,0xd8,0x00,0x36,0x00,0x0e,0x80,0x23,0x00,0x00 }}, - {16, 0xd250, 0, {0xc8,0x80,0x32,0x00,0x0c,0x80,0x01,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd260, 0, {0x28,0x05,0x28,0x10,0x8a,0x00,0x2e,0x80,0x28,0x20,0x22,0x28,0x00,0x8a,0x00,0x23 }}, - {16, 0xd270, 0, {0xb0,0x88,0xe0,0x02,0x28,0x10,0xda,0x00,0xa3,0xb4,0x08,0xe8,0x10,0x28,0x00,0x8e }}, - {16, 0xd280, 0, {0x20,0x23,0xa0,0x48,0xed,0x1a,0x28,0x00,0xde,0x00,0x23,0x90,0x0a,0xe0,0x02,0x0a }}, - {16, 0xd290, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xa3,0x00,0x28,0xc0 }}, - {16, 0xd2a0, 0, {0x08,0x30,0x0a,0x0c,0x00,0x93,0x00,0x20,0xc2,0x2a,0x30,0x22,0xa4,0x00,0xbb,0x00 }}, - {16, 0xd2b0, 0, {0x08,0xe0,0x18,0x09,0x0a,0x4c,0x00,0x93,0x02,0x24,0xe8,0x02,0x08,0x06,0x4c,0x00 }}, - {16, 0xd2c0, 0, {0x93,0x00,0x20,0xd8,0x0a,0x90,0x02,0x4a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd2d0, 0, {0xa0,0x01,0x1c,0x80,0x87,0x04,0x2d,0xc0,0x08,0x70,0x02,0x0e,0x00,0x87,0x10,0x25 }}, - {16, 0xd2e0, 0, {0x00,0x0a,0x60,0x02,0x5e,0x00,0x97,0x00,0x29,0x82,0x08,0x50,0x12,0x54,0x00,0x8f }}, - {16, 0xd2f0, 0, {0x80,0x61,0xd0,0x08,0x04,0x02,0x5c,0x01,0xb7,0x08,0xa9,0xa0,0x0a,0x50,0x82,0x68 }}, - {16, 0xd300, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x80,0xe7,0x80,0x38,0xe4 }}, - {16, 0xd310, 0, {0x08,0x7e,0x03,0x1f,0x00,0xdf,0x80,0xb1,0x21,0x1e,0x78,0x03,0xdc,0x04,0xf3,0x80 }}, - {16, 0xd320, 0, {0x5b,0xe1,0x08,0x28,0x03,0x5e,0x00,0xd7,0x80,0x35,0x60,0x0e,0x68,0x03,0x4e,0x00 }}, - {16, 0xd330, 0, {0xdf,0x80,0x31,0xe0,0x0e,0xf8,0x0b,0x6a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd340, 0, {0x08,0x1d,0xad,0x02,0xfb,0x74,0x3e,0xd0,0x4f,0xb2,0x83,0xed,0x00,0x7b,0x68,0x3a }}, - {16, 0xd350, 0, {0x00,0x8d,0x80,0x03,0xa4,0x20,0xdb,0x01,0x36,0x80,0x6f,0xb0,0x41,0x84,0x00,0xeb }}, - {16, 0xd360, 0, {0x00,0x3c,0xc0,0x0f,0xe6,0x83,0xbc,0x40,0xdb,0x00,0xb6,0x80,0x0f,0xb0,0x03,0x82 }}, - {16, 0xd370, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x20,0xdf,0xc0,0x3b,0xe6 }}, - {16, 0xd380, 0, {0x0e,0xf8,0x13,0xff,0x44,0xc7,0x82,0x3b,0xe0,0x0f,0xf9,0x03,0xbe,0x10,0xcf,0xc8 }}, - {16, 0xd390, 0, {0x33,0x60,0x8d,0xeb,0x03,0x3e,0x00,0xdb,0x82,0x3f,0xe0,0x0c,0xd8,0x03,0x3e,0x40 }}, - {16, 0xd3a0, 0, {0xce,0x80,0x33,0xe4,0x0f,0xf8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd3b0, 0, {0xa8,0x11,0xbc,0x40,0x87,0x00,0x21,0xe4,0x0b,0x78,0xa2,0xce,0x90,0xc7,0xb0,0x20 }}, - {16, 0xd3c0, 0, {0xe8,0x0b,0x28,0x92,0xb6,0x88,0x87,0xa0,0x20,0x64,0x0b,0x35,0x03,0x14,0x00,0x87 }}, - {16, 0xd3d0, 0, {0xb2,0x39,0xc0,0x2c,0xc0,0x03,0x5e,0x02,0xcf,0x00,0x31,0xce,0x0b,0x76,0x12,0x2a }}, - {16, 0xd3e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa3,0x10,0x29,0xc8 }}, - {16, 0xd3f0, 0, {0x0b,0x74,0x02,0xdc,0x80,0x8f,0x00,0x29,0xcc,0x0a,0x30,0x06,0x14,0x80,0x87,0x10 }}, - {16, 0xd400, 0, {0x21,0xc0,0x0b,0x66,0x02,0x5c,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x51,0x02,0x1c,0x80 }}, - {16, 0xd410, 0, {0x96,0x00,0x21,0xc0,0x5b,0x74,0x82,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd420, 0, {0x20,0x14,0xcc,0x08,0xa3,0x00,0x20,0xc0,0x0b,0xb8,0x02,0xcc,0x00,0x8b,0x40,0xa8 }}, - {16, 0xd430, 0, {0xc0,0x8b,0x08,0x22,0x8c,0x02,0x83,0x00,0x60,0xc0,0x0b,0x30,0x42,0x04,0x00,0x83 }}, - {16, 0xd440, 0, {0x40,0x28,0xfc,0x8a,0x00,0x02,0x6e,0x00,0x83,0x00,0xa0,0xd0,0x8b,0x38,0x02,0x08 }}, - {16, 0xd450, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbc,0x02,0xef,0x00,0x3b,0xc0 }}, - {16, 0xd460, 0, {0x4f,0xf8,0x02,0xfc,0x02,0xcf,0x00,0x38,0x12,0x0e,0x98,0x02,0x2c,0x00,0xcf,0x00 }}, - {16, 0xd470, 0, {0x32,0xc0,0x09,0x90,0x03,0x64,0x02,0x81,0xc0,0x3e,0xd0,0x0f,0x90,0x07,0x3c,0x03 }}, - {16, 0xd480, 0, {0xd9,0x00,0x32,0x60,0x0f,0x88,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd490, 0, {0x80,0x00,0xcc,0x00,0xdb,0x00,0x3e,0xc0,0x8f,0xb0,0x03,0xec,0x00,0xfb,0x02,0x36 }}, - {16, 0xd4a0, 0, {0xc0,0x4f,0x90,0x02,0xe4,0x00,0xfb,0x00,0xbe,0x90,0x0f,0x9c,0x13,0xec,0x00,0xe9 }}, - {16, 0xd4b0, 0, {0x18,0x3a,0xd0,0x04,0xd5,0x03,0xec,0x40,0xe9,0x00,0x3a,0x00,0x8f,0x80,0x03,0xe0 }}, - {16, 0xd4c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xcf,0x00,0x3d,0xc1 }}, - {16, 0xd4d0, 0, {0x8c,0xf0,0x03,0x2c,0x00,0xef,0x0a,0xb3,0x12,0x2c,0x70,0x23,0x14,0x0a,0x4f,0x00 }}, - {16, 0xd4e0, 0, {0x35,0x60,0x0d,0xb0,0x03,0x04,0x00,0xcd,0x80,0x07,0xe8,0x0c,0xc4,0x03,0x2c,0x00 }}, - {16, 0xd4f0, 0, {0xcd,0x00,0x31,0xe2,0x2c,0xe0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd500, 0, {0x81,0x04,0x6c,0x02,0xab,0x02,0x2e,0xc0,0x0e,0xb0,0x02,0x2c,0x00,0x8b,0x00,0x32 }}, - {16, 0xd510, 0, {0x30,0x00,0x9c,0x03,0x6c,0x00,0x8b,0x04,0x22,0x36,0x08,0x34,0x4a,0x2c,0x08,0x89 }}, - {16, 0xd520, 0, {0x90,0x20,0xb8,0x0f,0x84,0x00,0xac,0x02,0x89,0x00,0x36,0xa0,0x08,0xa4,0x02,0x20 }}, - {16, 0xd530, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x2e,0xc0 }}, - {16, 0xd540, 0, {0x08,0xb0,0x02,0x0c,0x00,0x8b,0x00,0x22,0xd1,0x08,0x88,0x12,0x26,0x00,0xa3,0x00 }}, - {16, 0xd550, 0, {0x26,0x40,0x0b,0xb0,0x02,0x26,0x00,0x8b,0x00,0x26,0xc0,0x58,0x10,0x12,0x2c,0x04 }}, - {16, 0xd560, 0, {0x82,0x80,0x2a,0x49,0x08,0x30,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd570, 0, {0x08,0x04,0x0c,0x00,0xa3,0x14,0x2c,0xc8,0x1a,0x34,0x8a,0x0c,0x84,0x83,0x40,0x22 }}, - {16, 0xd580, 0, {0xc8,0x08,0x03,0x62,0x4c,0xc0,0xa3,0x60,0x20,0x40,0x0a,0x30,0x02,0x0c,0x00,0x8b }}, - {16, 0xd590, 0, {0x45,0x08,0xc0,0x0b,0x10,0x02,0x8c,0xa0,0x83,0x00,0x26,0x40,0x08,0x30,0x0a,0x02 }}, - {16, 0xd5a0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xcf,0x40,0x2f,0xd2 }}, - {16, 0xd5b0, 0, {0x8c,0xf6,0x03,0x3c,0x22,0xcf,0x40,0x32,0xd6,0x4c,0xa6,0xc1,0x3d,0xa0,0x87,0x48 }}, - {16, 0xd5c0, 0, {0x36,0x0d,0x0f,0xb1,0x02,0x24,0x42,0xcb,0x60,0x16,0xc0,0x0c,0xd0,0x03,0x2c,0x80 }}, - {16, 0xd5d0, 0, {0xca,0x00,0x32,0xc0,0x0c,0x30,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd5e0, 0, {0xa0,0x19,0xfc,0x00,0xff,0x20,0x3e,0xca,0x0e,0xb0,0x03,0xec,0x20,0xdb,0x34,0x3a }}, - {16, 0xd5f0, 0, {0xc8,0x0f,0x80,0x03,0xe4,0x10,0xdb,0x21,0x3e,0x18,0x0d,0xf2,0x03,0xfc,0x80,0xff }}, - {16, 0xd600, 0, {0x30,0x35,0xc0,0x0f,0xc0,0x13,0xec,0x00,0xff,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xd610, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x11,0xfc,0x00,0xfb,0x0b,0x2f,0xca }}, - {16, 0xd620, 0, {0x8d,0xf2,0x03,0xfa,0x00,0x96,0x80,0x3b,0xc4,0x0d,0xf1,0x03,0x7c,0x80,0xec,0x80 }}, - {16, 0xd630, 0, {0x3b,0x08,0x0c,0xc2,0x03,0x74,0x02,0xcc,0x80,0x3f,0x48,0x0e,0xf0,0x03,0x30,0xa0 }}, - {16, 0xd640, 0, {0xd5,0x80,0x3f,0x40,0x0c,0xf8,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd650, 0, {0x80,0x08,0xee,0x40,0xbf,0x80,0x2f,0xf0,0x0b,0xf7,0x22,0xee,0x20,0x8a,0x80,0x23 }}, - {16, 0xd660, 0, {0xfc,0x88,0x75,0x12,0x3d,0x00,0x88,0x00,0x22,0x00,0x28,0x80,0x02,0x24,0x08,0x88 }}, - {16, 0xd670, 0, {0x00,0x6f,0x50,0x00,0xf5,0x02,0x29,0x00,0x89,0x00,0x2e,0x54,0x0d,0x90,0x11,0xa0 }}, - {16, 0xd680, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xb3,0x00,0x2c,0xc1 }}, - {16, 0xd690, 0, {0x09,0x30,0x82,0xcc,0x82,0xbb,0x00,0x28,0xc0,0x49,0x32,0x02,0xcd,0x00,0xb8,0x00 }}, - {16, 0xd6a0, 0, {0x2c,0x50,0x09,0x01,0x02,0x0c,0x40,0x80,0x00,0x6c,0x44,0x09,0x30,0x02,0x20,0x00 }}, - {16, 0xd6b0, 0, {0xb0,0x00,0x2c,0x40,0x18,0x30,0x06,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd6c0, 0, {0xc0,0x01,0xac,0x00,0xbb,0x01,0x2e,0xc0,0x0b,0xb0,0x02,0xee,0x00,0xaa,0x00,0x4a }}, - {16, 0xd6d0, 0, {0xc0,0x08,0xb0,0x52,0xec,0x00,0x98,0x02,0x26,0x40,0x09,0x80,0x02,0x6c,0x01,0xaa }}, - {16, 0xd6e0, 0, {0x04,0x2e,0x40,0x09,0xb0,0x02,0x22,0x00,0xa9,0x80,0x2e,0x41,0x09,0x90,0x02,0xf0 }}, - {16, 0xd6f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xec,0x00,0xfb,0x00,0x3e,0xc0 }}, - {16, 0xd700, 0, {0x0d,0xb0,0x03,0xce,0x84,0xfa,0x00,0x1a,0xc0,0x8d,0xb0,0x43,0xec,0x00,0xf0,0x02 }}, - {16, 0xd710, 0, {0x3f,0x00,0x0d,0xd1,0x03,0x35,0x00,0xcb,0x48,0x2e,0x40,0x2f,0xb0,0x09,0x22,0x80 }}, - {16, 0xd720, 0, {0xf9,0xc8,0x1e,0xe0,0x08,0xb1,0xe2,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd730, 0, {0xe0,0x01,0xbc,0x00,0x7b,0x00,0x3f,0xc0,0x0f,0xf0,0x23,0xfc,0x00,0xde,0x00,0x24 }}, - {16, 0xd740, 0, {0xc0,0x4f,0xf0,0x03,0x2c,0x00,0xec,0x20,0x3b,0x00,0x0e,0x98,0x03,0x94,0x02,0xdd }}, - {16, 0xd750, 0, {0x00,0x3f,0x40,0x4e,0xf0,0x01,0xf8,0x00,0xdd,0x00,0x3c,0xe4,0x0f,0xd8,0x03,0xb8 }}, - {16, 0xd760, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xac,0xc0,0xfb,0x20,0x32,0xc8 }}, - {16, 0xd770, 0, {0x8d,0xb0,0x03,0xec,0x00,0xf9,0x00,0x3a,0xc2,0x2c,0x30,0x03,0x6c,0x04,0xd8,0x02 }}, - {16, 0xd780, 0, {0x3c,0x44,0x8d,0x10,0x03,0xad,0x03,0xea,0x00,0x3c,0x40,0x0c,0x70,0x23,0xe4,0x00 }}, - {16, 0xd790, 0, {0xc8,0x40,0x3a,0xc0,0x0d,0xbc,0x03,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd7a0, 0, {0xc8,0x01,0x3d,0x00,0xbf,0x42,0x23,0xf0,0x0d,0xf0,0x02,0xe5,0x00,0xe2,0x01,0x37 }}, - {16, 0xd7b0, 0, {0xf1,0x08,0xf0,0x0e,0x3d,0xc0,0xa8,0x00,0x2e,0x54,0x28,0x90,0x02,0x2c,0x00,0x8a }}, - {16, 0xd7c0, 0, {0x05,0x3b,0x41,0x48,0xf5,0x03,0x8c,0x00,0x89,0x00,0x22,0xd4,0x0e,0x95,0x02,0xf2 }}, - {16, 0xd7d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x04,0x20,0xc0 }}, - {16, 0xd7e0, 0, {0x89,0x30,0x02,0xcc,0x40,0xb2,0x00,0x2c,0xc4,0x48,0x30,0x02,0x2c,0x02,0xa2,0x00 }}, - {16, 0xd7f0, 0, {0x2c,0x20,0x19,0x20,0x1a,0x80,0x08,0xb0,0x00,0x6c,0x40,0x08,0x30,0x02,0xc4,0x00 }}, - {16, 0xd800, 0, {0x81,0x00,0x2c,0x40,0x08,0x30,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd810, 0, {0x20,0x01,0x1e,0x00,0xb7,0xa0,0xe1,0xe0,0x09,0x78,0x02,0xdf,0x04,0xae,0x80,0x2d }}, - {16, 0xd820, 0, {0xe0,0x08,0x79,0x02,0x1e,0x10,0x87,0x90,0x2c,0x28,0x29,0x68,0x02,0x82,0x81,0xb4 }}, - {16, 0xd830, 0, {0x80,0x2d,0x60,0x08,0x78,0x10,0xbc,0x00,0x8f,0x80,0x2d,0x60,0x0b,0x68,0x02,0xc8 }}, - {16, 0xd840, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x0c,0x05,0xf3,0x92,0x30,0xca }}, - {16, 0xd850, 0, {0x0d,0x30,0x03,0xcc,0x00,0xf3,0x00,0x3c,0xc0,0x0c,0x30,0x02,0x0c,0x80,0x70,0x00 }}, - {16, 0xd860, 0, {0x2c,0x40,0x0d,0x20,0x03,0x89,0x00,0xb1,0x00,0x3e,0x40,0x2c,0x30,0x03,0xec,0x50 }}, - {16, 0xd870, 0, {0xc3,0x20,0x3c,0x40,0x0c,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd880, 0, {0x40,0x1d,0xbc,0x00,0xff,0x00,0x3c,0xc0,0x0e,0xb0,0x83,0xec,0x40,0xea,0x00,0x36 }}, - {16, 0xd890, 0, {0xc2,0x0f,0xb0,0x83,0xac,0x00,0xf8,0x00,0x3e,0x48,0x0e,0xe0,0x0b,0x7a,0x80,0xcf }}, - {16, 0xd8a0, 0, {0x00,0x3b,0x44,0x0f,0xf0,0x03,0xec,0xc0,0xff,0x00,0x03,0x44,0x0e,0xe0,0x03,0xd0 }}, - {16, 0xd8b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x23,0x3e,0xc8 }}, - {16, 0xd8c0, 0, {0x1d,0xb0,0x03,0xee,0x00,0xca,0x00,0x3e,0xc8,0x0c,0xb2,0x03,0x2d,0x90,0xc8,0x84 }}, - {16, 0xd8d0, 0, {0x36,0x00,0x2d,0xb0,0x03,0x60,0x18,0x9b,0x80,0x33,0x50,0x0c,0xf2,0x03,0xe2,0x00 }}, - {16, 0xd8e0, 0, {0xc9,0x80,0x32,0x40,0x0c,0xb8,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd8f0, 0, {0x48,0x11,0x9c,0x00,0xb7,0x28,0x0c,0xd2,0x28,0x73,0x02,0xfc,0x00,0x86,0x04,0x2c }}, - {16, 0xd900, 0, {0xcc,0x28,0x70,0x83,0x0c,0x20,0x95,0x01,0x20,0x00,0x09,0x30,0x12,0x10,0x04,0x85 }}, - {16, 0xd910, 0, {0x00,0x21,0x52,0x08,0x75,0x02,0xd8,0x00,0x87,0x00,0x21,0x40,0x08,0x60,0x02,0x12 }}, - {16, 0xd920, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0xd4,0xb7,0xb1,0x09,0xe1 }}, - {16, 0xd930, 0, {0x08,0x78,0x22,0xde,0x00,0x95,0x80,0x2d,0xe0,0x08,0x78,0x0a,0x5e,0x42,0x94,0xc0 }}, - {16, 0xd940, 0, {0x21,0x60,0x08,0x78,0x02,0x5a,0x00,0x87,0x80,0x2d,0x68,0x08,0x7a,0x02,0xd7,0x00 }}, - {16, 0xd950, 0, {0x97,0x80,0x20,0x60,0x09,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd960, 0, {0x48,0x10,0xcc,0x00,0xb3,0x00,0x2c,0xc0,0x08,0xb0,0x02,0xcd,0x80,0x92,0x00,0x2c }}, - {16, 0xd970, 0, {0xc0,0x08,0xb0,0x02,0xcc,0x00,0x90,0x80,0xa0,0x40,0x09,0x36,0x02,0x48,0x02,0x83 }}, - {16, 0xd980, 0, {0xa0,0xac,0x40,0x2a,0x30,0x06,0xce,0x02,0x93,0x04,0xa0,0x40,0x09,0x20,0x0a,0x12 }}, - {16, 0xd990, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x00,0x3a,0x80 }}, - {16, 0xd9a0, 0, {0x0d,0xa0,0x03,0xfb,0x02,0xde,0x80,0x3e,0x80,0x0c,0xa0,0x03,0x28,0x00,0xce,0x80 }}, - {16, 0xd9b0, 0, {0x32,0x80,0x0c,0xa4,0x03,0x78,0x00,0xce,0xa4,0x3f,0x80,0x0c,0xa0,0x07,0xf9,0x00 }}, - {16, 0xd9c0, 0, {0xde,0x00,0x32,0x80,0x2d,0xe0,0x02,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd9d0, 0, {0x48,0x00,0xe1,0x00,0xf8,0x00,0x7c,0x00,0x0f,0x80,0x03,0xe0,0x40,0xe8,0x10,0x3c }}, - {16, 0xd9e0, 0, {0x01,0xcf,0x80,0x0f,0x20,0x00,0xe8,0x00,0x3e,0x00,0x0e,0x04,0x03,0x90,0x00,0xe8 }}, - {16, 0xd9f0, 0, {0x00,0x20,0x00,0x0d,0x80,0x07,0xe0,0x00,0xe8,0x00,0x3e,0x04,0x0e,0x80,0x03,0xd2 }}, - {16, 0xda00, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x10,0x7e,0x41 }}, - {16, 0xda10, 0, {0x0e,0x90,0x03,0x24,0x00,0xf9,0x00,0x36,0x68,0x0e,0x90,0x0f,0xa4,0x08,0xc9,0x00 }}, - {16, 0xda20, 0, {0x3a,0x40,0x0c,0x90,0x0b,0x24,0x12,0xe9,0x00,0x3e,0x44,0x2c,0x90,0x03,0x64,0x24 }}, - {16, 0xda30, 0, {0xf9,0x02,0x2e,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xda40, 0, {0x80,0x04,0x65,0x10,0xb9,0x80,0x3e,0x40,0x08,0x90,0x0a,0x26,0x00,0xb1,0x10,0x2a }}, - {16, 0xda50, 0, {0x72,0x08,0x90,0x07,0x64,0x02,0x89,0x40,0x2e,0x40,0x28,0x90,0x12,0x25,0x00,0x89 }}, - {16, 0xda60, 0, {0x45,0x3e,0x50,0x0d,0x90,0x0a,0x25,0x00,0xb9,0x40,0x2e,0x40,0x28,0x94,0x03,0xe0 }}, - {16, 0xda70, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x2e,0x40 }}, - {16, 0xda80, 0, {0x48,0x90,0x42,0x26,0x01,0xb9,0x40,0x26,0x40,0x0a,0x90,0x42,0x84,0x01,0x8b,0x08 }}, - {16, 0xda90, 0, {0x2c,0x40,0x09,0xd0,0x82,0x34,0x32,0xa9,0x08,0x6e,0x42,0x08,0x10,0x02,0x24,0x20 }}, - {16, 0xdaa0, 0, {0xb9,0x08,0x2c,0x40,0x18,0x90,0x82,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdab0, 0, {0x08,0x04,0x04,0x80,0xb3,0x20,0x28,0x48,0x08,0x12,0x02,0x04,0x01,0xb1,0x00,0x28 }}, - {16, 0xdac0, 0, {0x58,0x08,0x12,0x02,0x05,0x89,0x81,0x40,0x2c,0x58,0x08,0x56,0x06,0x15,0x80,0x81 }}, - {16, 0xdad0, 0, {0x40,0x28,0x50,0x09,0x14,0x02,0x05,0x80,0xb1,0x40,0x2c,0x5a,0x08,0x14,0x02,0xc2 }}, - {16, 0xdae0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x68,0x00,0xf8,0x00,0x2e,0x00 }}, - {16, 0xdaf0, 0, {0x2e,0x85,0x03,0x21,0x48,0xf8,0x00,0x36,0x00,0x8e,0x05,0x02,0xa0,0x08,0x80,0x00 }}, - {16, 0xdb00, 0, {0x3e,0x00,0x0d,0x80,0x0b,0x10,0x04,0xe0,0x00,0x2c,0x00,0x4c,0x80,0x03,0x40,0x00 }}, - {16, 0xdb10, 0, {0xf0,0x00,0x3e,0x08,0x0c,0x00,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdb20, 0, {0x98,0x1d,0xe4,0x40,0xf9,0x10,0x3e,0x44,0x0f,0x91,0x03,0xf4,0x00,0xfd,0x00,0x3e }}, - {16, 0xdb30, 0, {0x44,0x0f,0x91,0x03,0xe4,0x40,0xfd,0x03,0x3f,0x44,0x1f,0x91,0x1b,0xe4,0x40,0xfd }}, - {16, 0xdb40, 0, {0x01,0x3f,0x50,0x0e,0x94,0x03,0xf4,0x40,0xfd,0x00,0x3f,0x40,0x0f,0xd0,0x03,0xa6 }}, - {16, 0xdb50, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf4,0x00,0xcd,0xa0,0x71,0x68 }}, - {16, 0xdb60, 0, {0x8d,0x98,0x03,0xd4,0x00,0xcd,0x00,0x33,0x60,0x0c,0x98,0x8f,0x27,0x20,0xc9,0x40 }}, - {16, 0xdb70, 0, {0x3e,0x78,0x0c,0x9e,0x8b,0x27,0x20,0xd1,0x11,0x30,0x60,0x8c,0x9c,0x03,0x25,0x00 }}, - {16, 0xdb80, 0, {0xf9,0x40,0x3e,0x78,0x0f,0x90,0x03,0x46,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdb90, 0, {0x38,0x10,0xe0,0x10,0x88,0x01,0x22,0x01,0x08,0x8c,0x22,0xe8,0x00,0x88,0x02,0x2a }}, - {16, 0xdba0, 0, {0x14,0x08,0x8c,0x0b,0x23,0x90,0x88,0xa0,0x2e,0xb0,0x08,0x8c,0x42,0x23,0x00,0x88 }}, - {16, 0xdbb0, 0, {0xa0,0x36,0x2a,0x18,0x8a,0x02,0x22,0x00,0xb8,0xa0,0x2e,0x34,0x0b,0xca,0x82,0x0e }}, - {16, 0xdbc0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0x81,0x40,0x24,0x50 }}, - {16, 0xdbd0, 0, {0x09,0x16,0x82,0xc4,0x00,0xa9,0x00,0x20,0x40,0x08,0x12,0x92,0x54,0x08,0x85,0x00 }}, - {16, 0xdbe0, 0, {0x2f,0x4c,0x09,0x52,0x12,0x14,0x80,0x9d,0x00,0x21,0x50,0x08,0x54,0x22,0x14,0x80 }}, - {16, 0xdbf0, 0, {0xb5,0x00,0x2d,0x48,0x0b,0xd0,0x02,0x42,0x05,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdc00, 0, {0x18,0x05,0xa4,0x02,0x89,0x01,0xa2,0x40,0x48,0x90,0x02,0xe4,0x02,0xa9,0x00,0x2a }}, - {16, 0xdc10, 0, {0x40,0x68,0x90,0x02,0x64,0x10,0xad,0x00,0x2f,0x41,0x28,0x50,0x02,0x34,0x00,0x8d }}, - {16, 0xdc20, 0, {0x44,0x27,0x40,0x39,0xd0,0x02,0x35,0x00,0xbd,0x14,0x2f,0x40,0x0b,0xd0,0x02,0x46 }}, - {16, 0xdc30, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xc4,0x00,0xc9,0x00,0x36,0x40 }}, - {16, 0xdc40, 0, {0x2d,0x90,0x03,0xe7,0x00,0xe1,0xe0,0x32,0x40,0x0c,0x90,0x0b,0x64,0x02,0xc9,0x08 }}, - {16, 0xdc50, 0, {0x3c,0x50,0x0c,0x90,0x02,0x26,0x02,0xd9,0xc0,0x32,0x40,0x0c,0x90,0x13,0x27,0x00 }}, - {16, 0xdc60, 0, {0xf9,0x20,0x3e,0x40,0x0f,0x90,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdc70, 0, {0x28,0x01,0xa4,0x02,0xf9,0x00,0x38,0x40,0x0f,0x90,0x03,0xe6,0x80,0xd9,0xa0,0x3c }}, - {16, 0xdc80, 0, {0x40,0x0f,0x10,0x03,0xa4,0x00,0xd9,0x10,0x3e,0x40,0x0f,0x90,0x03,0xc4,0x92,0xf9 }}, - {16, 0xdc90, 0, {0x21,0x3c,0x40,0x2e,0x90,0x0f,0xe6,0x80,0xf9,0x80,0x3e,0x40,0x0f,0x90,0x03,0x8a }}, - {16, 0xdca0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x40,0xe8,0x10,0x3e,0x04 }}, - {16, 0xdcb0, 0, {0x4e,0x80,0x03,0x20,0x80,0xd8,0x60,0x3a,0x02,0x0c,0x80,0x13,0x20,0x00,0xf8,0x40 }}, - {16, 0xdcc0, 0, {0x36,0x10,0x2d,0x80,0x03,0xa0,0x08,0xe8,0x40,0x32,0x00,0x0d,0x00,0x03,0x21,0x02 }}, - {16, 0xdcd0, 0, {0xc8,0x40,0xb2,0x00,0x0f,0xc0,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdce0, 0, {0x28,0x11,0x3b,0x10,0x86,0x01,0x2f,0xa0,0x0d,0xa0,0x02,0x38,0x00,0x8e,0xe0,0x23 }}, - {16, 0xdcf0, 0, {0xa2,0x08,0xa0,0x02,0x28,0x00,0xba,0x80,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0x82 }}, - {16, 0xdd00, 0, {0x00,0x2a,0x80,0x28,0xa0,0x02,0x2a,0x04,0x8a,0x80,0x22,0xa0,0x0b,0x60,0x02,0xca }}, - {16, 0xdd10, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x43,0x80,0xa2,0x00,0x2c,0xa0 }}, - {16, 0xdd20, 0, {0x08,0x30,0x02,0x2e,0x00,0x92,0x00,0x28,0xc0,0x28,0x30,0x02,0x2c,0x00,0xb3,0x80 }}, - {16, 0xdd30, 0, {0x24,0xc0,0x09,0x30,0x0a,0x8c,0x00,0xa3,0x00,0x60,0xc0,0x08,0x30,0x0a,0x4c,0x00 }}, - {16, 0xdd40, 0, {0x83,0x00,0x20,0xe0,0x0b,0x20,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdd50, 0, {0xa0,0x01,0x10,0x00,0x86,0x00,0x2d,0xc0,0x09,0x3a,0x02,0x35,0x00,0x86,0x00,0x21 }}, - {16, 0xdd60, 0, {0xc0,0x08,0x73,0x02,0x10,0x00,0xbf,0x88,0x21,0x00,0x08,0x70,0x02,0x1c,0x08,0x8f }}, - {16, 0xdd70, 0, {0x00,0x2b,0xc0,0x08,0x20,0x12,0x5e,0x20,0x87,0x88,0x21,0x83,0x0b,0x60,0x02,0xe8 }}, - {16, 0xdd80, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xe5,0x81,0x3d,0xa0 }}, - {16, 0xdd90, 0, {0x2c,0x7a,0x0b,0x1e,0x00,0xd4,0x80,0x38,0xe0,0x0c,0xfa,0x0b,0x1e,0x00,0xf6,0x80 }}, - {16, 0xdda0, 0, {0x34,0xe0,0x0d,0x28,0x03,0x8a,0x00,0xe6,0x80,0x31,0x20,0x0c,0x78,0x03,0x7a,0x04 }}, - {16, 0xddb0, 0, {0xce,0x84,0x31,0xe0,0x4f,0x78,0x43,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xddc0, 0, {0x08,0x0d,0x80,0x00,0xf8,0x00,0x3e,0xc0,0x0f,0xb5,0x23,0xe4,0x00,0xf0,0x04,0x36 }}, - {16, 0xddd0, 0, {0x40,0x0f,0xb6,0x87,0xe0,0x00,0xf2,0x00,0x3e,0x00,0x1f,0xa0,0x0b,0xe8,0x00,0xfa }}, - {16, 0xdde0, 0, {0x00,0x3e,0x00,0x0e,0xa0,0x03,0xa8,0x00,0xfa,0x00,0x3e,0x80,0x0f,0xb0,0x03,0xc2 }}, - {16, 0xddf0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xcc,0x80,0x33,0xa0 }}, - {16, 0xde00, 0, {0x0c,0xfc,0x03,0x3e,0x00,0xfc,0x80,0x37,0xe0,0x0f,0xb9,0x21,0x3e,0x00,0xfd,0x82 }}, - {16, 0xde10, 0, {0x33,0xe0,0x2c,0xf8,0x03,0x7e,0x10,0xdf,0x84,0x3d,0xe0,0x0c,0xf8,0x03,0xf6,0x00 }}, - {16, 0xde20, 0, {0xfd,0x80,0x3f,0x60,0x0c,0xe8,0x23,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xde30, 0, {0xa8,0x11,0x98,0x40,0x84,0x10,0x21,0xc0,0x08,0x70,0x02,0x10,0x80,0xb4,0x00,0x21 }}, - {16, 0xde40, 0, {0xc8,0x0b,0x7a,0x02,0x10,0x00,0xfd,0x00,0x21,0x04,0x08,0x70,0x02,0x1c,0x42,0x87 }}, - {16, 0xde50, 0, {0x00,0x2d,0xc4,0x48,0x61,0x02,0xd6,0x80,0xb5,0x00,0x2f,0x04,0x08,0x61,0x82,0x2a }}, - {16, 0xde60, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x81,0x00,0x21,0x80 }}, - {16, 0xde70, 0, {0x08,0x30,0x02,0x1c,0x10,0xbc,0x08,0x25,0x80,0x4b,0x30,0x0e,0x1c,0x00,0xb4,0x00 }}, - {16, 0xde80, 0, {0x20,0xc0,0x08,0x20,0x02,0x58,0x00,0x96,0x00,0x2f,0x00,0x0a,0x70,0x02,0xd0,0x80 }}, - {16, 0xde90, 0, {0xb4,0x18,0x2d,0x40,0x09,0xf8,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdea0, 0, {0x20,0x14,0xc8,0x02,0x80,0x00,0xa0,0xc0,0x08,0x30,0x22,0x0b,0xc0,0xb0,0xc0,0x22 }}, - {16, 0xdeb0, 0, {0x80,0x0b,0x30,0x02,0x00,0x00,0xa0,0x04,0x22,0x00,0x28,0xa0,0x02,0x2b,0x00,0x8a }}, - {16, 0xdec0, 0, {0x00,0x2c,0x00,0x08,0xa0,0x06,0xc0,0x00,0xb0,0xc2,0x2c,0x00,0x09,0xbc,0x1a,0x08 }}, - {16, 0xded0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xc8,0x00,0x32,0xc0 }}, - {16, 0xdee0, 0, {0x0c,0xf0,0x0b,0x26,0x00,0xf9,0xc0,0x36,0x00,0x0f,0xf0,0x13,0x2c,0x10,0xbb,0x40 }}, - {16, 0xdef0, 0, {0xf2,0xc0,0x08,0x90,0x03,0x67,0x00,0xd9,0x80,0x3e,0xc0,0x08,0x90,0x02,0xec,0x00 }}, - {16, 0xdf00, 0, {0xfb,0xd0,0x3e,0xc0,0x29,0x8c,0x00,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdf10, 0, {0x80,0x00,0xe0,0x00,0xf8,0x44,0x3c,0xd0,0x2f,0xb0,0x03,0xe4,0x00,0xf9,0x20,0x3e }}, - {16, 0xdf20, 0, {0x40,0x0f,0x30,0x03,0xe0,0x00,0xfb,0x08,0x3e,0x00,0x0f,0x90,0x13,0xe4,0x42,0xf9 }}, - {16, 0xdf30, 0, {0x10,0x3e,0xc0,0x0f,0x80,0x03,0xee,0x00,0xfb,0x00,0x3e,0x80,0x0e,0x82,0x03,0xe0 }}, - {16, 0xdf40, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xe0,0x08,0xfc,0x80,0x32,0xe4 }}, - {16, 0xdf50, 0, {0x0e,0xf0,0x03,0x74,0x00,0xfc,0x00,0x3f,0x40,0x0c,0xf0,0x0b,0x3c,0x00,0xfe,0x00 }}, - {16, 0xdf60, 0, {0x3f,0xc0,0x0d,0xc1,0x03,0x20,0x20,0xcc,0x10,0x33,0x00,0x0c,0xd1,0x03,0x58,0x00 }}, - {16, 0xdf70, 0, {0xce,0x00,0x2f,0xc0,0x0f,0xd1,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdf80, 0, {0x81,0x44,0x62,0x00,0xb0,0x40,0x2a,0xf1,0x08,0xb0,0x12,0x26,0x08,0xb8,0xc8,0x2e }}, - {16, 0xdf90, 0, {0x70,0x0a,0xb0,0x02,0x20,0x00,0xba,0x00,0x2e,0x00,0x28,0x80,0x03,0x22,0x40,0x88 }}, - {16, 0xdfa0, 0, {0x01,0x20,0x00,0x0a,0x80,0x02,0x28,0x00,0x8a,0x01,0x2e,0x80,0x8b,0x90,0x02,0x20 }}, - {16, 0xdfb0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x26,0x00,0xb8,0x28,0x22,0x42 }}, - {16, 0xdfc0, 0, {0x08,0x30,0x02,0x66,0x00,0xb8,0x80,0x2e,0x30,0x88,0xb0,0x02,0x2c,0x00,0xb9,0x01 }}, - {16, 0xdfd0, 0, {0x2e,0xc0,0x88,0x90,0x02,0xa4,0x00,0x89,0x00,0x22,0xc0,0x08,0x90,0x02,0x24,0x0c }}, - {16, 0xdfe0, 0, {0x89,0x01,0x2e,0x40,0x1b,0x80,0x02,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdff0, 0, {0x08,0x04,0x00,0x00,0xb0,0x00,0x28,0xc0,0x28,0x30,0x02,0x00,0x00,0xb0,0x00,0x2c }}, - {16, 0xe000, 0, {0x40,0x0a,0x30,0x02,0x00,0x00,0xb1,0x00,0x2c,0x00,0x08,0x10,0x0a,0x04,0x00,0x81 }}, - {16, 0xe010, 0, {0x01,0xa2,0xc0,0x08,0x00,0x0a,0x04,0x80,0x81,0x00,0x2c,0x00,0x1b,0x00,0x0a,0x02 }}, - {16, 0xe020, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xf8,0x00,0x32,0x40 }}, - {16, 0xe030, 0, {0x0e,0xf0,0x23,0x64,0x08,0xf8,0x00,0x2e,0x00,0x0c,0xf0,0x03,0x2c,0x00,0xf8,0x00 }}, - {16, 0xe040, 0, {0x3e,0xc0,0x0c,0x80,0x03,0x20,0x02,0xc8,0x04,0x32,0x00,0x1c,0x90,0x03,0x20,0x00 }}, - {16, 0xe050, 0, {0xc8,0x01,0x3e,0x41,0x9f,0x90,0x43,0x40,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe060, 0, {0xa0,0x1d,0xf0,0x00,0xfc,0x0c,0x3f,0xc0,0x0f,0xf0,0x03,0xf0,0x10,0xf4,0x00,0x3f }}, - {16, 0xe070, 0, {0x00,0x0f,0xf4,0x23,0xf0,0x00,0xfc,0x00,0x3f,0x00,0x0e,0xc0,0x03,0xb0,0x00,0xfc }}, - {16, 0xe080, 0, {0x00,0x3f,0x00,0x0f,0xc0,0x03,0xe1,0x00,0xfc,0x00,0x3f,0x01,0x1f,0x50,0x03,0xe8 }}, - {16, 0xe090, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x0d,0xf0,0xd0,0xff,0x20,0x3e,0xd0 }}, - {16, 0xe0a0, 0, {0x8e,0xb0,0x03,0xec,0xa0,0xdb,0x28,0x3e,0xcc,0x0c,0xb3,0x03,0xad,0x08,0xf8,0x3c }}, - {16, 0xe0b0, 0, {0x32,0x23,0x0e,0x48,0x23,0x7a,0x00,0xfd,0x94,0x3f,0xe0,0x0f,0x78,0x33,0xee,0x08 }}, - {16, 0xe0c0, 0, {0xbf,0x80,0x3f,0xe4,0x0f,0xf9,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0d0, 0, {0xa0,0x00,0xec,0xc8,0xbf,0xd1,0x0f,0xc8,0x0c,0x26,0x82,0xfd,0x24,0x8f,0x00,0x2e }}, - {16, 0xe0e0, 0, {0x99,0x0a,0xf2,0x62,0x1d,0xd0,0x99,0x61,0x22,0x71,0x88,0x88,0x02,0xac,0x00,0xb8 }}, - {16, 0xe0f0, 0, {0x22,0x2e,0x20,0x4b,0x88,0x03,0xa0,0x00,0x80,0x00,0x2e,0x08,0x0b,0x80,0x23,0x60 }}, - {16, 0xe100, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x04,0xb3,0x03,0x0c,0xcc }}, - {16, 0xe110, 0, {0x0a,0x13,0x12,0xcc,0x14,0xa3,0x0e,0x0c,0x58,0x0a,0x33,0x02,0x8c,0x10,0xa3,0x20 }}, - {16, 0xe120, 0, {0xa0,0x0a,0x18,0x90,0x02,0x48,0xa0,0xb0,0x20,0x24,0x80,0x0a,0x20,0x02,0xcc,0x09 }}, - {16, 0xe130, 0, {0xa1,0x00,0x2c,0x80,0x0b,0x32,0x42,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe140, 0, {0xe0,0x11,0xac,0x20,0xbb,0x00,0x2e,0xc0,0x4b,0x80,0xa2,0xec,0x00,0xab,0x00,0x4e }}, - {16, 0xe150, 0, {0x46,0x2a,0xb0,0x02,0x2c,0x04,0x9b,0x80,0x2a,0x60,0x8a,0x9c,0x02,0xac,0x00,0xb9 }}, - {16, 0xe160, 0, {0x81,0x2e,0x40,0x0b,0x98,0x02,0xa3,0x00,0x8a,0x00,0x2e,0x40,0x0b,0x80,0x04,0xf0 }}, - {16, 0xe170, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe1,0x00,0xfb,0x04,0x3e,0xc0 }}, - {16, 0xe180, 0, {0x0e,0xb4,0x03,0xec,0x0a,0xdb,0x02,0x2e,0xd1,0x0e,0xb0,0x03,0xac,0x00,0xfb,0x82 }}, - {16, 0xe190, 0, {0x32,0x28,0x1e,0x0c,0x03,0x68,0x00,0xb9,0x00,0x3e,0x40,0x4f,0xb0,0x43,0xed,0x00 }}, - {16, 0xe1a0, 0, {0xea,0x00,0x3e,0x40,0x0f,0x80,0x03,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1b0, 0, {0xc0,0x01,0xb8,0x18,0xff,0x02,0x1f,0xc0,0x0c,0xe2,0x03,0xfc,0x00,0xdf,0x03,0x2f }}, - {16, 0xe1c0, 0, {0xa1,0x0f,0x70,0x03,0xfc,0x04,0xab,0x04,0x37,0x42,0x2d,0xd0,0x02,0x7c,0x00,0xfc }}, - {16, 0xe1d0, 0, {0x00,0x3f,0x80,0x0f,0xc0,0x03,0xb0,0x00,0xfd,0x00,0x3f,0x80,0x0f,0xf0,0x03,0x78 }}, - {16, 0xe1e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa9,0x00,0xdb,0x00,0x3c,0xc0 }}, - {16, 0xe1f0, 0, {0x2e,0x94,0x01,0x6c,0x11,0xcb,0x00,0xb8,0xc0,0x0c,0xb0,0x03,0x6c,0x00,0xeb,0x01 }}, - {16, 0xe200, 0, {0x32,0x10,0x07,0x92,0x03,0xa8,0x00,0xf8,0x00,0x3e,0x0c,0x07,0xa2,0x03,0xad,0x00 }}, - {16, 0xe210, 0, {0xd8,0x00,0x32,0x00,0x0c,0x80,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe220, 0, {0xc8,0x05,0x28,0x08,0xbf,0x00,0x2f,0xc0,0x88,0x80,0x02,0x3c,0x08,0xef,0x03,0x22 }}, - {16, 0xe230, 0, {0x00,0x0d,0xf5,0x00,0x3c,0x00,0x8b,0x82,0x22,0x60,0x03,0x9c,0x02,0x2c,0x10,0xb9 }}, - {16, 0xe240, 0, {0xb0,0x22,0xf0,0x0b,0x90,0x02,0x20,0x00,0xbb,0x00,0x22,0xe2,0x0d,0xb0,0x02,0xf2 }}, - {16, 0xe250, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x40,0x00,0xb3,0x02,0x2c,0xc0 }}, - {16, 0xe260, 0, {0x08,0x30,0x02,0x6c,0x00,0x83,0x00,0x20,0xc0,0x09,0x34,0x04,0xec,0x00,0xa8,0x00 }}, - {16, 0xe270, 0, {0x22,0xf0,0x0b,0x00,0x02,0x88,0x00,0xb3,0x00,0x28,0xe0,0x0b,0x14,0x02,0xa0,0x00 }}, - {16, 0xe280, 0, {0x93,0x00,0x20,0xc0,0x08,0xb0,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe290, 0, {0x20,0x01,0x1e,0x04,0xb7,0x80,0x2d,0xe8,0x08,0x78,0x02,0x0e,0xc8,0xa7,0x90,0x21 }}, - {16, 0xe2a0, 0, {0xa8,0x19,0x38,0x52,0x9e,0xc1,0x87,0x80,0x21,0xe2,0x0b,0xd9,0x82,0x9e,0x00,0xb6 }}, - {16, 0xe2b0, 0, {0xa0,0x2d,0x20,0x0b,0x68,0x02,0x1e,0x00,0xb4,0xc1,0x21,0x20,0x09,0x48,0x02,0xc8 }}, - {16, 0xe2c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x0c,0x80,0xb3,0x10,0x3e,0xe0 }}, - {16, 0xe2d0, 0, {0x0e,0x3a,0x07,0x4e,0x00,0xcb,0x90,0x3a,0x61,0x0d,0x38,0x03,0xce,0xd1,0xe1,0x98 }}, - {16, 0xe2e0, 0, {0x30,0xa4,0x8f,0x10,0x03,0x88,0x00,0xba,0xa1,0x3c,0x84,0x07,0x00,0x03,0x82,0xd4 }}, - {16, 0xe2f0, 0, {0xd1,0x00,0x72,0x80,0x0c,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe300, 0, {0x40,0x15,0xbc,0x04,0xff,0x00,0x3f,0xc0,0x0f,0xc2,0x23,0xec,0xb0,0xff,0x00,0x32 }}, - {16, 0xe310, 0, {0x04,0x06,0xb4,0x23,0x7c,0x10,0xbf,0x00,0x3e,0x84,0x0f,0xb0,0x03,0x7c,0x40,0xff }}, - {16, 0xe320, 0, {0x00,0x33,0x40,0x0f,0xf0,0x03,0xfc,0x00,0xfe,0x00,0xbf,0x40,0x0f,0xc8,0x03,0xd0 }}, - {16, 0xe330, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe4,0x00,0xcb,0x33,0x3e,0xc8 }}, - {16, 0xe340, 0, {0x4c,0xb0,0x03,0xac,0x90,0xdb,0xa0,0x36,0xc0,0x0e,0xba,0x43,0x6c,0x00,0xc9,0x00 }}, - {16, 0xe350, 0, {0x3e,0x40,0x0f,0x00,0x0f,0x28,0x00,0xfb,0x00,0x3e,0x40,0x0f,0x18,0x43,0x60,0x00 }}, - {16, 0xe360, 0, {0xfa,0x00,0x3e,0x40,0x4f,0x08,0x0b,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe370, 0, {0x48,0x11,0x9c,0x10,0x07,0x08,0x2c,0xca,0x08,0x20,0x02,0x1c,0x20,0x87,0x28,0x3f }}, - {16, 0xe380, 0, {0x80,0x8a,0xf0,0x02,0x1d,0x40,0x87,0x04,0x2d,0xc0,0x0b,0x70,0x02,0x1c,0x00,0xb6 }}, - {16, 0xe390, 0, {0x00,0x2d,0x80,0x0b,0x60,0x03,0x1c,0x00,0xb5,0x00,0x2d,0x80,0x0b,0x70,0x02,0x12 }}, - {16, 0xe3a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x87,0xa0,0x2d,0xe4 }}, - {16, 0xe3b0, 0, {0x0a,0x58,0x02,0x1e,0x01,0x83,0x90,0x21,0x70,0x0b,0x79,0x02,0x9e,0x01,0x85,0xc0 }}, - {16, 0xe3c0, 0, {0x2d,0xe0,0x4b,0x58,0x12,0x1a,0x00,0xb6,0x80,0x2d,0x20,0x0b,0x48,0x02,0x52,0x00 }}, - {16, 0xe3d0, 0, {0xb4,0x80,0x2d,0x20,0x0b,0x48,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3e0, 0, {0x48,0x14,0xec,0x00,0x83,0x00,0x2c,0xc0,0x88,0x36,0x02,0x0c,0x02,0x83,0x00,0x6c }}, - {16, 0xe3f0, 0, {0xc0,0x0b,0x30,0x0a,0xac,0x00,0x9b,0xe0,0x6c,0xc8,0x0b,0x32,0x02,0x0c,0x01,0xb3 }}, - {16, 0xe400, 0, {0x00,0x2c,0xc0,0x0b,0x30,0x02,0x0c,0x10,0xb3,0x40,0x2c,0xc0,0x0b,0x3c,0x82,0x12 }}, - {16, 0xe410, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x02,0xca,0x00,0x3e,0x80 }}, - {16, 0xe420, 0, {0x0e,0xe4,0x8b,0x28,0x00,0xca,0x00,0x33,0x95,0x0f,0xa0,0x07,0xa8,0x02,0xce,0x40 }}, - {16, 0xe430, 0, {0x3f,0xb0,0x0f,0xe4,0x82,0x28,0x00,0xfa,0x00,0x3e,0x80,0x0f,0xa0,0x23,0x68,0x00 }}, - {16, 0xe440, 0, {0xfa,0x40,0x3e,0x81,0x4f,0xa4,0xe3,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe450, 0, {0x48,0x00,0xe0,0x80,0xf0,0x00,0x3c,0x00,0x2f,0x00,0x02,0x60,0x00,0xe8,0x00,0x3c }}, - {16, 0xe460, 0, {0x00,0x0e,0x80,0x01,0x20,0x00,0xe8,0x04,0x5e,0x04,0x0f,0x80,0x03,0xe0,0x00,0xfc }}, - {16, 0xe470, 0, {0x01,0x3f,0x10,0x0f,0xc4,0x03,0xb0,0x00,0xfc,0x09,0x3f,0x00,0x0f,0xc0,0x03,0xd2 }}, - {16, 0xe480, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xa9,0x20,0x36,0x40 }}, - {16, 0xe490, 0, {0x0e,0x90,0x03,0x44,0x04,0xd9,0x00,0x3e,0x40,0x0d,0x90,0x03,0xe4,0x04,0xc9,0x00 }}, - {16, 0xe4a0, 0, {0x32,0x40,0x8f,0x90,0x0b,0xe4,0x08,0xf9,0x00,0x3e,0x44,0x0e,0x98,0x03,0xe6,0x00 }}, - {16, 0xe4b0, 0, {0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4c0, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x40,0x18,0x90,0x02,0x24,0x00,0x89,0x00,0x2e }}, - {16, 0xe4d0, 0, {0x40,0x08,0x94,0x02,0xe4,0x00,0xd9,0x04,0x22,0x40,0x0b,0x1c,0x0b,0x64,0x00,0xb9 }}, - {16, 0xe4e0, 0, {0x94,0x2c,0x50,0x08,0x9c,0x02,0xe4,0x14,0xb9,0x90,0x0e,0x40,0x0b,0x90,0x02,0xe0 }}, - {16, 0xe4f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x02,0x89,0x00,0x26,0x40 }}, - {16, 0xe500, 0, {0x4a,0x90,0x02,0x64,0x00,0x99,0x04,0x2e,0x40,0x08,0x98,0x82,0xe4,0x00,0x89,0x00 }}, - {16, 0xe510, 0, {0x6a,0x40,0x0a,0x92,0x82,0xe4,0x00,0xbd,0x01,0x2f,0x50,0x12,0xd6,0x02,0xf4,0x40 }}, - {16, 0xe520, 0, {0xbd,0x00,0x0f,0x40,0x0b,0xd0,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe530, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0x20,0x48,0x08,0x12,0x02,0x04,0x80,0x81,0x22,0x2c }}, - {16, 0xe540, 0, {0x48,0xa8,0x12,0x06,0xc4,0x90,0x91,0x20,0x28,0x50,0x0b,0x90,0x02,0x45,0x00,0xb5 }}, - {16, 0xe550, 0, {0x40,0x6d,0x40,0x08,0x50,0x12,0xd4,0x04,0xb5,0x02,0x2d,0x40,0x0b,0x50,0x02,0xc2 }}, - {16, 0xe560, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc8,0x00,0x36,0x14 }}, - {16, 0xe570, 0, {0x0a,0x85,0x03,0x41,0x40,0xd8,0x50,0x2e,0x14,0x0c,0x85,0x03,0xc1,0x40,0xc8,0x50 }}, - {16, 0xe580, 0, {0xba,0x00,0x0e,0x80,0x23,0xe0,0x00,0x78,0x00,0x3e,0x00,0x0e,0x80,0x03,0xe0,0x04 }}, - {16, 0xe590, 0, {0xf8,0x00,0x3e,0x00,0x0f,0xc0,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5a0, 0, {0x98,0x1d,0xf4,0x40,0xd9,0x10,0x3e,0x44,0x07,0xf1,0x03,0xe4,0x40,0xf9,0x10,0x3f }}, - {16, 0xe5b0, 0, {0x44,0xaf,0x91,0x03,0xe4,0x40,0xfd,0x10,0x37,0x50,0x0f,0xd0,0x03,0xe4,0x00,0xf9 }}, - {16, 0xe5c0, 0, {0x00,0x3e,0x40,0x0f,0x90,0x03,0xe4,0xa0,0xf9,0x28,0x3e,0x4a,0x0f,0x92,0x83,0xe6 }}, - {16, 0xe5d0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0xd4,0xfd,0xa2,0x3a,0x70 }}, - {16, 0xe5e0, 0, {0x8c,0x9e,0x03,0x26,0x80,0xc9,0xa0,0x32,0x68,0x0c,0xdb,0x43,0x27,0x80,0x9d,0xa2 }}, - {16, 0xe5f0, 0, {0xb7,0x40,0x0f,0x50,0x03,0x65,0x00,0xfd,0x00,0x3f,0xc1,0x07,0xd0,0x03,0xf5,0x04 }}, - {16, 0xe600, 0, {0xfd,0x40,0x2f,0xc0,0x0c,0xd0,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe610, 0, {0x38,0x10,0xe3,0x88,0xb8,0x50,0x22,0x38,0x08,0x8e,0x00,0xa2,0xa0,0x88,0xe8,0x22 }}, - {16, 0xe620, 0, {0x38,0x48,0x88,0x03,0x62,0x10,0xa8,0xe8,0x3c,0x00,0x0b,0x80,0x03,0x62,0x80,0xb8 }}, - {16, 0xe630, 0, {0x01,0x2e,0x80,0x0b,0x80,0x21,0xa2,0x00,0xb0,0x84,0x2e,0x2a,0x28,0x8a,0x82,0xce }}, - {16, 0xe640, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x40,0xb1,0x00,0x28,0x58 }}, - {16, 0xe650, 0, {0x80,0x13,0x40,0x05,0x00,0x81,0x40,0x20,0x52,0x28,0x16,0x02,0x85,0x80,0x9b,0xc2 }}, - {16, 0xe660, 0, {0x64,0x41,0x8b,0x98,0x02,0x04,0x00,0xb1,0x09,0x2c,0x40,0x1b,0x10,0x20,0xc4,0x00 }}, - {16, 0xe670, 0, {0xb1,0x00,0x2c,0x40,0x48,0x10,0x02,0xc2,0x05,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe680, 0, {0x18,0x15,0xa5,0x84,0xb9,0x00,0x20,0x40,0x08,0x90,0x02,0x24,0x00,0x01,0x00,0x20 }}, - {16, 0xe690, 0, {0x50,0x08,0x90,0x42,0x64,0x00,0xa9,0x10,0xae,0x58,0x03,0x98,0x02,0x64,0x00,0xb9 }}, - {16, 0xe6a0, 0, {0x00,0x2e,0x40,0x0b,0x90,0x46,0xa4,0x10,0xb9,0x00,0x2e,0x41,0x08,0x90,0x02,0xc6 }}, - {16, 0xe6b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe7,0x00,0xf9,0x00,0x2a,0x40 }}, - {16, 0xe6c0, 0, {0x2c,0x94,0x0b,0x24,0x02,0xc9,0x00,0xb2,0x44,0x0c,0x90,0x03,0x24,0x04,0xd9,0x80 }}, - {16, 0xe6d0, 0, {0xb6,0x41,0x8f,0x18,0x03,0x24,0x00,0xf9,0x60,0x3e,0x40,0x0f,0x96,0x03,0xe4,0x00 }}, - {16, 0xe6e0, 0, {0xf9,0x80,0x3e,0x42,0x8c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6f0, 0, {0x28,0x01,0xa6,0x00,0xf1,0x00,0x3e,0x40,0x0f,0x1c,0x03,0xc4,0x00,0xf9,0x00,0x3e }}, - {16, 0xe700, 0, {0x40,0x8f,0x90,0x23,0xc4,0x10,0xf9,0x00,0xbe,0x40,0x0f,0x90,0x0b,0xe4,0x00,0xf9 }}, - {16, 0xe710, 0, {0x00,0x3e,0x40,0x07,0x90,0x23,0xe4,0x00,0xf9,0x20,0x3e,0x40,0x8f,0x90,0x03,0xca }}, - {16, 0xe720, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xf8,0x00,0xbe,0x00 }}, - {16, 0xe730, 0, {0x0e,0x84,0x03,0x20,0x00,0xc8,0x00,0x32,0x00,0x0c,0x00,0x83,0x20,0x00,0xf8,0x00 }}, - {16, 0xe740, 0, {0x3e,0x00,0x0c,0x80,0x03,0xa0,0x00,0xf8,0x00,0x36,0x10,0x0f,0x80,0x43,0xe0,0x08 }}, - {16, 0xe750, 0, {0xf8,0x00,0x32,0x00,0x0f,0x80,0x03,0xca,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe760, 0, {0x28,0x05,0x28,0x00,0xba,0x00,0x22,0x80,0x48,0xa0,0x03,0x68,0x00,0xaa,0x00,0x2a }}, - {16, 0xe770, 0, {0x80,0x08,0xe0,0x03,0x68,0x00,0x82,0x00,0x2f,0x80,0x08,0xe6,0x02,0x28,0x04,0xbe }}, - {16, 0xe780, 0, {0x40,0x23,0x80,0x0b,0xe8,0x02,0xea,0x00,0xbe,0x01,0x22,0x80,0x0b,0xe0,0x02,0xca }}, - {16, 0xe790, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x01,0x93,0x01,0x20,0xc1 }}, - {16, 0xe7a0, 0, {0x0a,0x30,0x02,0x0c,0x00,0xa3,0x00,0x20,0xc0,0x88,0x38,0x42,0x0c,0x00,0xa3,0x00 }}, - {16, 0xe7b0, 0, {0x24,0xc0,0x0a,0x3e,0x42,0x8c,0x00,0xb2,0x4c,0x24,0xe0,0x4b,0x38,0x02,0xc4,0x41 }}, - {16, 0xe7c0, 0, {0xb3,0x00,0x22,0xc0,0x0b,0x10,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7d0, 0, {0xa0,0x01,0x1c,0x00,0xb7,0x00,0x20,0xc9,0x48,0x70,0x02,0xdc,0x40,0xa7,0x14,0x2c }}, - {16, 0xe7e0, 0, {0xc8,0x28,0x30,0x82,0x5c,0xc1,0x85,0x00,0x2d,0xe0,0x2a,0xf0,0x12,0x1c,0x80,0xb7 }}, - {16, 0xe7f0, 0, {0xa0,0x21,0x82,0x0b,0x70,0x82,0xd4,0x11,0xb6,0x80,0x21,0x40,0x4b,0x50,0x02,0xe8 }}, - {16, 0xe800, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x80,0xd5,0x80,0x29,0xea }}, - {16, 0xe810, 0, {0x4e,0x3a,0x07,0x0e,0x80,0xe3,0xb0,0x31,0xfc,0x0c,0x48,0x03,0x0e,0x41,0xe7,0x80 }}, - {16, 0xe820, 0, {0x3d,0xe0,0x0e,0x78,0x03,0x9e,0x80,0xf4,0xc4,0x35,0xe0,0x0f,0x78,0x27,0xde,0x00 }}, - {16, 0xe830, 0, {0xf5,0x80,0xb1,0xe0,0x0f,0x58,0x03,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe840, 0, {0x08,0x1d,0xac,0x00,0x31,0x04,0x3a,0xc4,0x0f,0xb5,0x93,0x6d,0x08,0xfb,0x40,0x3a }}, - {16, 0xe850, 0, {0xc8,0x63,0x80,0x23,0xec,0x98,0xe9,0x00,0x3e,0xc0,0x0d,0xb0,0x43,0xec,0x00,0xf3 }}, - {16, 0xe860, 0, {0x80,0x3e,0x40,0x4f,0xa0,0x03,0xec,0x00,0xf8,0x68,0x3e,0x40,0x8f,0x98,0x03,0xc2 }}, - {16, 0xe870, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x60,0xeb,0x90,0x3e,0xe4 }}, - {16, 0xe880, 0, {0x0f,0xb8,0x00,0x3f,0x40,0xcb,0x80,0x7f,0xe0,0x0e,0xfb,0x03,0x2e,0x40,0xcb,0x80 }}, - {16, 0xe890, 0, {0x3f,0xe0,0x0f,0x79,0x43,0x2e,0x60,0xca,0x81,0x33,0x64,0x8f,0xd9,0x03,0xfe,0x00 }}, - {16, 0xe8a0, 0, {0xff,0x81,0x33,0xe0,0x0f,0xd9,0x8b,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8b0, 0, {0xa8,0x01,0x9c,0x00,0x87,0x81,0x19,0xe4,0x0b,0xfa,0x13,0x5e,0x80,0x87,0xb2,0x2d }}, - {16, 0xe8c0, 0, {0xec,0x0d,0x79,0x01,0x9e,0x00,0xd5,0x90,0x2d,0xf8,0x0b,0x78,0x03,0x7e,0x08,0xab }}, - {16, 0xe8d0, 0, {0x91,0x29,0x85,0x0b,0x51,0x02,0xdc,0x48,0xb6,0x40,0x21,0x40,0x0b,0x50,0x02,0x2a }}, - {16, 0xe8e0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x14,0xb5,0x20,0x6d,0xc8 }}, - {16, 0xe8f0, 0, {0x0b,0x72,0x02,0x5c,0x80,0x87,0x20,0x69,0xc0,0x88,0x53,0x02,0xcc,0x81,0x97,0x50 }}, - {16, 0xe900, 0, {0x2d,0xc8,0x0b,0xf7,0x0a,0xdc,0xc0,0x84,0x01,0x21,0x44,0x1b,0x70,0x22,0xdc,0x00 }}, - {16, 0xe910, 0, {0xb5,0x00,0x21,0xc4,0x0b,0x50,0x86,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe920, 0, {0x20,0x14,0xcf,0x30,0x91,0x00,0x2c,0xc0,0x0b,0x34,0x02,0x4c,0x00,0x83,0x00,0x2c }}, - {16, 0xe930, 0, {0xf2,0x0b,0x10,0x22,0x0c,0x00,0x91,0x00,0x2c,0xc8,0x0b,0x18,0x0a,0xcd,0x01,0xa3 }}, - {16, 0xe940, 0, {0x00,0x28,0x60,0x0b,0x21,0x02,0xce,0x20,0xb8,0x40,0xa0,0x54,0x0b,0x18,0x02,0x08 }}, - {16, 0xe950, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x11,0xbd,0x00,0xf9,0x00,0x2f,0xc0 }}, - {16, 0xe960, 0, {0x0f,0xf4,0x02,0x7c,0x12,0xcf,0x03,0x3f,0xc2,0x0e,0xb0,0x03,0xfc,0x04,0x9b,0x02 }}, - {16, 0xe970, 0, {0x2e,0xf2,0x0f,0xa4,0x0b,0xdc,0x00,0xce,0x00,0xb0,0xc8,0x8f,0xa4,0x03,0xef,0x00 }}, - {16, 0xe980, 0, {0xf8,0x80,0x32,0xf5,0x1f,0xdd,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe990, 0, {0x80,0x00,0xec,0x40,0xe9,0x00,0x3a,0xc0,0x0f,0xb1,0x03,0xcc,0x00,0xf3,0x00,0x3e }}, - {16, 0xe9a0, 0, {0xc0,0x0d,0xb4,0x09,0xec,0x18,0xf9,0x10,0x3e,0x10,0x4f,0xb1,0x0a,0x6c,0x80,0xf9 }}, - {16, 0xe9b0, 0, {0x89,0x36,0x82,0x0b,0xa6,0x03,0xec,0x50,0xf9,0x50,0x3e,0xc0,0x1f,0x90,0x03,0x60 }}, - {16, 0xe9c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xfd,0xa0,0x3d,0xc0 }}, - {16, 0xe9d0, 0, {0x0c,0x70,0x83,0x2c,0x00,0xef,0x02,0x35,0xc0,0x0d,0xe2,0x03,0xfc,0x04,0xff,0x02 }}, - {16, 0xe9e0, 0, {0x2d,0xe0,0x8e,0xf0,0x03,0x3c,0x10,0xdc,0x00,0x3f,0x80,0x0c,0xd8,0x03,0xfc,0x00 }}, - {16, 0xe9f0, 0, {0xde,0x18,0x33,0xf0,0x4f,0xd0,0x03,0xc0,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea00, 0, {0x81,0x00,0x6c,0x00,0xb9,0x00,0x2e,0xc0,0x4c,0xb0,0x03,0x6c,0x00,0x8b,0x02,0x36 }}, - {16, 0xea10, 0, {0xc0,0x0d,0xac,0x12,0xec,0x00,0x79,0x00,0x2e,0x30,0x0d,0x3d,0x42,0xac,0x00,0x89 }}, - {16, 0xea20, 0, {0x88,0x1a,0x10,0x0d,0x86,0x02,0xee,0x04,0xbb,0x40,0x22,0xe0,0x0b,0x90,0x02,0xe0 }}, - {16, 0xea30, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x01,0xb9,0x00,0x2e,0xc0 }}, - {16, 0xea40, 0, {0x08,0xb0,0x42,0xac,0x00,0x0b,0x05,0x26,0xc0,0x09,0x94,0x20,0xec,0x00,0xb9,0x80 }}, - {16, 0xea50, 0, {0x6e,0xc4,0x88,0xb0,0x82,0x2c,0x00,0x9b,0x82,0x2e,0x42,0x08,0x81,0x02,0xe4,0x80 }}, - {16, 0xea60, 0, {0xb8,0x00,0x22,0xc1,0x0b,0x90,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea70, 0, {0x08,0x04,0x0c,0x10,0xb1,0x25,0x2c,0xca,0x08,0x34,0x46,0xcc,0x08,0x83,0x00,0x24 }}, - {16, 0xea80, 0, {0xc2,0x0b,0x02,0x52,0xcc,0x81,0x83,0x00,0x2c,0x00,0x19,0xb2,0x42,0xac,0x80,0x81 }}, - {16, 0xea90, 0, {0x08,0x28,0x80,0x09,0x00,0x02,0xc4,0x40,0xb1,0x00,0x20,0xc0,0x0b,0x10,0x02,0xc2 }}, - {16, 0xeaa0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x6c,0x00,0xb9,0x00,0x3f,0xd0 }}, - {16, 0xeab0, 0, {0x08,0xf6,0x07,0xbc,0xc2,0xaf,0x30,0x75,0xdc,0x0d,0x16,0x02,0xfc,0xe0,0xb9,0x50 }}, - {16, 0xeac0, 0, {0x3e,0xcc,0x0c,0xb0,0x23,0x2c,0x10,0xd9,0x00,0x3e,0x00,0x0c,0x90,0x03,0xec,0x00 }}, - {16, 0xead0, 0, {0xde,0x01,0x32,0xc0,0x0f,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeae0, 0, {0xa0,0x19,0xfc,0x00,0xfd,0x10,0x3f,0xca,0x2e,0xf6,0x03,0x6d,0x94,0x9f,0x30,0x3a }}, - {16, 0xeaf0, 0, {0xc9,0x0c,0x83,0x93,0xfc,0x80,0xff,0x11,0x7e,0x19,0x0b,0xb1,0x03,0xfc,0x40,0xfd }}, - {16, 0xeb00, 0, {0x08,0x3b,0x00,0x0f,0xc0,0x03,0xfc,0x80,0x77,0x00,0xbf,0xc0,0x0f,0x50,0x03,0xe8 }}, - {16, 0xeb10, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xfc,0x00,0xf4,0x94,0x37,0xc8 }}, - {16, 0xeb20, 0, {0x0d,0x69,0x63,0x7c,0x10,0xff,0x62,0x37,0xc0,0x0d,0xb4,0x03,0x7c,0x60,0xd4,0x80 }}, - {16, 0xeb30, 0, {0x3f,0x40,0x0f,0x48,0x23,0x32,0x00,0xce,0x00,0xbf,0x40,0x8f,0xd1,0x03,0x30,0xe0 }}, - {16, 0xeb40, 0, {0xff,0x30,0x3b,0x60,0x0f,0xd8,0x03,0xb0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb50, 0, {0x80,0x10,0xed,0x20,0xb8,0x24,0x23,0xf4,0x49,0xa2,0x02,0x3f,0x40,0x8f,0x51,0x23 }}, - {16, 0xeb60, 0, {0xda,0x08,0xf6,0x12,0x3d,0x80,0x9b,0x80,0x2e,0x49,0x4b,0x80,0x03,0x40,0x00,0xd9 }}, - {16, 0xeb70, 0, {0x01,0x22,0x74,0x0b,0xd5,0x02,0x21,0x00,0xbf,0x42,0x2e,0x49,0x0b,0x9c,0x02,0xe0 }}, - {16, 0xeb80, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcd,0x80,0xb8,0x20,0x28,0xc1 }}, - {16, 0xeb90, 0, {0x1b,0xa0,0x02,0x4c,0x00,0x93,0x20,0x2c,0xd8,0x0b,0x34,0x02,0xcc,0x00,0x90,0x01 }}, - {16, 0xeba0, 0, {0x2c,0xc6,0x1a,0xa0,0x02,0x68,0x08,0x83,0x00,0xa4,0x40,0x0b,0x10,0x02,0x00,0x00 }}, - {16, 0xebb0, 0, {0xb3,0x10,0x28,0x42,0x0b,0x14,0x02,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xebc0, 0, {0xc0,0x15,0xac,0x00,0xb8,0x60,0x2a,0xc0,0x1b,0xa0,0x8e,0xac,0x01,0x9b,0x05,0x26 }}, - {16, 0xebd0, 0, {0xc0,0x03,0xb0,0x42,0x6c,0x00,0x9b,0x80,0x2e,0xc0,0x03,0xa0,0x06,0x69,0x00,0x99 }}, - {16, 0xebe0, 0, {0x80,0xaa,0xc0,0x0b,0x90,0x02,0x63,0x00,0x3b,0x00,0x2e,0x58,0x4b,0x90,0x02,0xf0 }}, - {16, 0xebf0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xec,0x04,0xf8,0x80,0xba,0xc0 }}, - {16, 0xec00, 0, {0x0f,0x30,0x03,0x6c,0x10,0xdb,0x03,0x36,0xc0,0x8f,0xb0,0x03,0xec,0x08,0xd8,0x80 }}, - {16, 0xec10, 0, {0x7e,0xe0,0x06,0x88,0x03,0x41,0x08,0xcb,0xa0,0x3e,0x64,0x0f,0x90,0x0b,0x2a,0x00 }}, - {16, 0xec20, 0, {0x7b,0x00,0x3a,0x01,0x0f,0x90,0x03,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec30, 0, {0xe0,0x01,0xbc,0x00,0xfc,0x84,0x32,0xc0,0x0c,0xf9,0x03,0x5c,0x10,0xef,0x00,0x3b }}, - {16, 0xec40, 0, {0xc0,0x0c,0x70,0x03,0x9c,0x00,0xec,0x01,0x3f,0xe4,0x4f,0xd1,0x03,0xf1,0x00,0xf3 }}, - {16, 0xec50, 0, {0x05,0x33,0x60,0x0f,0xd0,0x03,0xbc,0x04,0xff,0x00,0x3f,0x21,0x0f,0xd0,0x03,0xf8 }}, - {16, 0xec60, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xc8,0x40,0x3a,0xc6 }}, - {16, 0xec70, 0, {0x0d,0xb4,0x03,0x6c,0x00,0xf3,0x00,0x34,0xc0,0x0e,0xb0,0x03,0x6c,0x00,0xe9,0x10 }}, - {16, 0xec80, 0, {0x3a,0xc0,0x0f,0x84,0x03,0x2c,0x60,0xcb,0x00,0x32,0x60,0x0c,0x50,0x03,0x61,0x00 }}, - {16, 0xec90, 0, {0xcb,0x00,0x3e,0x90,0x0e,0x90,0xa3,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeca0, 0, {0xc8,0x05,0x3c,0x02,0x88,0x01,0x01,0xf0,0x20,0xb0,0x01,0x3e,0x00,0x3f,0x00,0x33 }}, - {16, 0xecb0, 0, {0xc0,0x0b,0xf0,0x32,0x3c,0x08,0x89,0x80,0x22,0xc0,0x01,0x15,0x12,0xac,0x00,0x8b }}, - {16, 0xecc0, 0, {0x00,0x22,0xc0,0x48,0xdb,0x02,0x2f,0x40,0x8f,0x00,0x2e,0x01,0x08,0xd4,0x80,0x32 }}, - {16, 0xecd0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0x08,0x00,0x08,0xf0 }}, - {16, 0xece0, 0, {0x08,0x00,0x12,0x4c,0x00,0x33,0x01,0x24,0xc0,0x4a,0x30,0x02,0x4c,0x00,0xa0,0x20 }}, - {16, 0xecf0, 0, {0x28,0xc0,0x0b,0x10,0x02,0x46,0x04,0x83,0x04,0x20,0xc0,0x29,0x18,0x02,0x04,0x40 }}, - {16, 0xed00, 0, {0xb3,0x00,0x2c,0x40,0x0a,0x1c,0x42,0xb1,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed10, 0, {0x20,0x01,0x1e,0x01,0x8d,0x80,0x21,0xe0,0x18,0xc8,0x02,0x1e,0x00,0xb3,0xa0,0x21 }}, - {16, 0xed20, 0, {0xe0,0x1b,0x38,0x02,0x0e,0x01,0xa7,0x80,0x21,0xe0,0x09,0xd8,0x40,0xd6,0x40,0x87 }}, - {16, 0xed30, 0, {0x80,0x01,0xe0,0x09,0x59,0x02,0x16,0x00,0x97,0x84,0x2d,0x60,0x08,0x58,0x40,0x00 }}, - {16, 0xed40, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x2c,0x40,0xc0,0x00,0x38,0xc4 }}, - {16, 0xed50, 0, {0x0c,0x30,0x27,0x4c,0x20,0xf3,0x01,0x34,0xc1,0x0e,0x3a,0x03,0x4c,0xc4,0xe0,0x00 }}, - {16, 0xed60, 0, {0x18,0xc8,0x0f,0x34,0x03,0x44,0x40,0xc3,0x00,0x30,0xc0,0x0d,0x90,0x03,0x2e,0x00 }}, - {16, 0xed70, 0, {0xf3,0x00,0x3e,0x40,0x0e,0x10,0x01,0x9a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed80, 0, {0x40,0x1d,0xbc,0x00,0xf9,0x00,0x0e,0xd4,0x0e,0xb0,0x03,0xec,0x20,0xfb,0x20,0x3f }}, - {16, 0xed90, 0, {0xc4,0x0f,0xf1,0x03,0xec,0x60,0xdb,0x10,0x3f,0xc0,0x4f,0xf0,0x03,0xa4,0x46,0xfb }}, - {16, 0xeda0, 0, {0x00,0xbd,0xc0,0x0e,0xd0,0x0b,0xb4,0x00,0xef,0x48,0x3f,0x40,0x0f,0x50,0x03,0xd0 }}, - {16, 0xedb0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xf8,0x00,0x32,0xd4 }}, - {16, 0xedc0, 0, {0x0f,0x80,0x03,0xad,0x00,0xeb,0x08,0x22,0xd2,0x0c,0xb6,0x03,0x6c,0x00,0xf2,0x80 }}, - {16, 0xedd0, 0, {0x36,0xc0,0x0e,0xa0,0x03,0x28,0x10,0xcb,0x00,0xb2,0xc0,0x0f,0xd6,0x03,0x28,0x10 }}, - {16, 0xede0, 0, {0xfb,0x20,0x3e,0x40,0x4f,0x99,0x13,0x2b,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xedf0, 0, {0x48,0x11,0x9d,0x10,0xb4,0x01,0x21,0xc1,0x8b,0xc0,0x02,0x1c,0xa0,0xbf,0x04,0x27 }}, - {16, 0xee00, 0, {0xc8,0x08,0x75,0x02,0x1c,0xc0,0xb6,0x00,0x21,0xc0,0x08,0xf0,0x42,0x18,0x10,0x8f }}, - {16, 0xee10, 0, {0x00,0x21,0xc0,0x0b,0x54,0xa2,0x1c,0x00,0xb7,0x04,0x2d,0x41,0x0b,0x52,0x02,0x12 }}, - {16, 0xee20, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x80,0xb6,0x88,0xa5,0xe0 }}, - {16, 0xee30, 0, {0x0b,0x78,0x12,0x9e,0x81,0xa7,0x90,0x25,0xe4,0x88,0x78,0x02,0x1e,0x80,0xbf,0x80 }}, - {16, 0xee40, 0, {0x24,0x60,0x0b,0x68,0x02,0x1e,0x00,0x87,0x84,0x61,0xe0,0x0a,0x1a,0x0a,0x1a,0x00 }}, - {16, 0xee50, 0, {0xb7,0xa0,0x2d,0xe0,0x0b,0xda,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee60, 0, {0x48,0x14,0xcc,0x00,0xba,0xc0,0xa4,0xc0,0x0b,0x34,0x02,0x0c,0x00,0xb3,0x00,0x24 }}, - {16, 0xee70, 0, {0xc0,0x08,0xb0,0x0e,0x2c,0x00,0xb3,0x98,0x20,0x60,0x09,0x33,0x02,0x2c,0x00,0xa3 }}, - {16, 0xee80, 0, {0xc8,0x20,0xc0,0x0b,0x10,0x02,0x0c,0x00,0xb3,0x00,0x2c,0xf0,0x0b,0x10,0x02,0x12 }}, - {16, 0xee90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfe,0x80,0x36,0x81 }}, - {16, 0xeea0, 0, {0x0b,0xe0,0x03,0xa8,0x00,0xea,0x00,0xb2,0x80,0x08,0xa0,0x03,0x68,0x00,0xfe,0x00 }}, - {16, 0xeeb0, 0, {0x36,0xa0,0x1f,0xe8,0x13,0x3b,0x82,0xce,0xe0,0x22,0x80,0x8e,0xa0,0x03,0x38,0x00 }}, - {16, 0xeec0, 0, {0xba,0x00,0x3f,0xa2,0x0f,0xa0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeed0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x20,0x3a,0x10,0x07,0x80,0x03,0xc1,0x00,0xf8,0x00,0x38 }}, - {16, 0xeee0, 0, {0x00,0x2f,0x80,0x03,0xa0,0x01,0xf8,0x42,0x3e,0x05,0x0e,0x80,0x0b,0xe0,0x80,0xd8 }}, - {16, 0xeef0, 0, {0x00,0x3e,0x00,0x0f,0x84,0x03,0xe1,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x84,0x0b,0xd2 }}, - {16, 0xef00, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc9,0x00,0x3a,0x50 }}, - {16, 0xef10, 0, {0x8f,0x90,0x83,0xa4,0x02,0xd1,0x00,0xb2,0x40,0x4c,0x90,0x23,0x24,0x08,0xc9,0x01 }}, - {16, 0xef20, 0, {0x3e,0x40,0x0c,0x90,0x03,0x24,0x00,0xc1,0x00,0x32,0x40,0x0f,0x14,0x0a,0x25,0x20 }}, - {16, 0xef30, 0, {0xe9,0x00,0x3e,0x42,0x0f,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef40, 0, {0x80,0x04,0x64,0x0a,0x89,0x00,0x22,0x70,0x0b,0x90,0x12,0x25,0x80,0xc9,0x00,0x22 }}, - {16, 0xef50, 0, {0x40,0x0a,0x90,0x03,0x64,0x00,0x89,0x20,0x2c,0x40,0x0a,0x90,0x0a,0x24,0x00,0x89 }}, - {16, 0xef60, 0, {0xc1,0x32,0x40,0x0b,0x98,0x02,0x06,0x00,0x89,0x90,0x2e,0x40,0x0b,0x94,0x12,0xe0 }}, - {16, 0xef70, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x04,0x00,0x89,0x00,0x6a,0x42 }}, - {16, 0xef80, 0, {0x0a,0x10,0x02,0xa4,0x00,0x89,0x00,0xa2,0x40,0x0a,0x90,0x02,0x24,0x00,0x09,0x00 }}, - {16, 0xef90, 0, {0x2e,0x40,0x58,0x10,0x02,0x24,0x00,0x89,0x80,0xaa,0x60,0x0b,0x90,0x02,0xa4,0x04 }}, - {16, 0xefa0, 0, {0xa9,0x00,0x2e,0x40,0x0b,0x94,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xefb0, 0, {0x08,0x04,0x04,0x80,0x81,0x00,0x60,0x48,0x0b,0x10,0x02,0x04,0x81,0x81,0x20,0x60 }}, - {16, 0xefc0, 0, {0x48,0x0a,0x12,0x02,0x44,0x88,0x81,0x00,0x0e,0x59,0x0a,0x14,0x02,0x05,0x00,0x81 }}, - {16, 0xefd0, 0, {0xc0,0x28,0x50,0x49,0x30,0x02,0x8c,0x84,0x01,0x60,0x2c,0x50,0x0b,0x10,0x02,0xc2 }}, - {16, 0xefe0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xc0,0x54,0x2a,0x00 }}, - {16, 0xeff0, 0, {0x0e,0x85,0x03,0xa0,0x00,0xc8,0x50,0x32,0x15,0x1e,0x05,0x22,0x21,0x42,0xc8,0x00 }}, - {16, 0xf000, 0, {0x3e,0x00,0x0c,0x80,0x03,0x00,0x04,0xc8,0x00,0x3a,0x00,0x4f,0x85,0x03,0xa1,0x40 }}, - {16, 0xf010, 0, {0x68,0x00,0x3e,0x00,0x0f,0x80,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf020, 0, {0x98,0x1d,0xe4,0x40,0xfd,0x03,0x3e,0x44,0x0f,0xd0,0x03,0xe4,0x48,0xe9,0x10,0x3e }}, - {16, 0xf030, 0, {0x45,0x0f,0x91,0x13,0xe4,0x40,0xfd,0x00,0x3f,0x44,0x0f,0xd0,0x03,0xf4,0x02,0xfd }}, - {16, 0xf040, 0, {0x40,0x33,0x50,0x0f,0xd4,0x23,0x74,0x40,0xf9,0x10,0x3f,0x40,0x0f,0x54,0x03,0xe6 }}, - {16, 0xf050, 0, {0x02,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe4,0x00,0xf9,0x01,0x33,0x6a }}, - {16, 0xf060, 0, {0x09,0x90,0x03,0xb6,0x34,0xf9,0xc8,0x32,0x64,0x0c,0x9a,0x03,0xe6,0xa0,0xdd,0x00 }}, - {16, 0xf070, 0, {0x3c,0x70,0x0f,0x90,0x03,0xa5,0x00,0x89,0x80,0x33,0x32,0x0f,0xd8,0x13,0x3c,0x00 }}, - {16, 0xf080, 0, {0xfd,0x00,0x70,0x50,0x0f,0xd0,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf090, 0, {0x38,0x10,0xe2,0x80,0xb8,0xa8,0x22,0x10,0x08,0x88,0x02,0x21,0x00,0xb8,0xc0,0x20 }}, - {16, 0xf0a0, 0, {0x30,0x0d,0x8e,0x87,0x83,0x88,0x88,0x00,0x2e,0x34,0x0b,0x8a,0x82,0x22,0x80,0xdc }}, - {16, 0xf0b0, 0, {0xe0,0x22,0x38,0x0b,0x80,0x02,0x20,0x00,0xf8,0xa8,0x2a,0x28,0x0b,0x80,0x02,0x0e }}, - {16, 0xf0c0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x20,0xb1,0x00,0x20,0x40 }}, - {16, 0xf0d0, 0, {0x0a,0x92,0x92,0x84,0x11,0xb1,0x24,0x68,0x58,0x09,0x11,0x02,0xc4,0x20,0x91,0x01 }}, - {16, 0xf0e0, 0, {0x2c,0x48,0x1b,0x50,0x02,0x74,0x84,0x95,0x48,0xac,0x48,0x0b,0x94,0x02,0x04,0x04 }}, - {16, 0xf0f0, 0, {0xb1,0x02,0x24,0x48,0x0b,0x10,0x02,0x02,0x05,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf100, 0, {0x18,0x11,0xa4,0x00,0xb1,0x20,0x22,0x40,0x0a,0x90,0x06,0x2c,0x01,0xb9,0x00,0x2a }}, - {16, 0xf110, 0, {0x40,0x09,0x90,0x02,0xa4,0x00,0x9b,0x08,0x2e,0x48,0x0b,0x12,0x1a,0x74,0x00,0x95 }}, - {16, 0xf120, 0, {0x45,0x2e,0x60,0x03,0x90,0x02,0x24,0x00,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x02,0x06 }}, - {16, 0xf130, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xf9,0x80,0x30,0x40 }}, - {16, 0xf140, 0, {0x0e,0x16,0x03,0xa4,0x00,0xb9,0x04,0x32,0x40,0x0d,0x90,0x02,0xe4,0x00,0xd9,0x40 }}, - {16, 0xf150, 0, {0x2e,0x40,0x1f,0x98,0x03,0xe5,0x80,0xd9,0x00,0xae,0x60,0x07,0x10,0x0b,0x26,0x01 }}, - {16, 0xf160, 0, {0xb9,0x00,0xa6,0x40,0x0f,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf170, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0xbe,0x40,0xac,0x92,0x03,0xe4,0x00,0xf9,0x00,0xb4 }}, - {16, 0xf180, 0, {0x40,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x00,0x3e,0x60,0x0f,0x90,0x03,0xa4,0x80,0xf9 }}, - {16, 0xf190, 0, {0x00,0x32,0x00,0x0f,0x90,0x83,0xe6,0x85,0xe1,0x00,0x32,0x44,0x0f,0x10,0x03,0xca }}, - {16, 0xf1a0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x00,0x32,0x00 }}, - {16, 0xf1b0, 0, {0x0f,0x80,0x13,0xe0,0x94,0xe0,0x00,0x32,0x00,0x0c,0x80,0x03,0x60,0x00,0xc8,0x00 }}, - {16, 0xf1c0, 0, {0x3e,0x00,0x0d,0x80,0x43,0x20,0x08,0xf8,0x00,0x32,0x00,0x0f,0x80,0x03,0xe0,0x40 }}, - {16, 0xf1d0, 0, {0xf8,0x00,0x32,0x00,0x4c,0x80,0x23,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1e0, 0, {0x28,0x05,0x28,0x00,0xba,0x00,0x23,0x80,0x0b,0xa0,0x02,0xfb,0x04,0x6a,0x00,0x22 }}, - {16, 0xf1f0, 0, {0x80,0x0a,0xa0,0x03,0x68,0x0a,0x8e,0x88,0x3a,0x80,0x08,0xa0,0x02,0x08,0x00,0xba }}, - {16, 0xf200, 0, {0x00,0xb7,0x22,0x03,0xe4,0x02,0xfa,0x00,0x8a,0x00,0x22,0x80,0x08,0xe8,0x02,0xca }}, - {16, 0xf210, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x60,0x41 }}, - {16, 0xf220, 0, {0x03,0x30,0x02,0xcc,0x41,0xa3,0x00,0x04,0xc0,0x0b,0x30,0x02,0x2c,0x00,0xa3,0x80 }}, - {16, 0xf230, 0, {0x2c,0xc0,0x09,0x38,0x02,0x0c,0x00,0xb3,0x00,0xa0,0xc0,0x0b,0x34,0x02,0xcc,0x80 }}, - {16, 0xf240, 0, {0xa1,0x00,0x20,0xc0,0x08,0x38,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf250, 0, {0xa0,0x01,0x1c,0x40,0xb7,0x00,0x61,0x00,0x0b,0x71,0x02,0xdc,0x00,0xa3,0x00,0x25 }}, - {16, 0xf260, 0, {0xc8,0x19,0x38,0x02,0x5c,0x80,0xa7,0x00,0x0f,0xe8,0x09,0x64,0x22,0x10,0x00,0xb3 }}, - {16, 0xf270, 0, {0x00,0x25,0xc8,0x0b,0x60,0x02,0xf2,0x00,0x85,0x01,0x23,0xe8,0x08,0x70,0x82,0xe8 }}, - {16, 0xf280, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x20,0xff,0x80,0xa1,0xa0 }}, - {16, 0xf290, 0, {0x0f,0x7a,0x42,0xda,0x00,0xe7,0xe8,0x35,0xf0,0x2f,0x7b,0x62,0x1e,0x82,0xe6,0x80 }}, - {16, 0xf2a0, 0, {0x1d,0xe0,0x0d,0xf8,0x0b,0x1e,0x00,0xf7,0x80,0x31,0xf0,0x0f,0x78,0x03,0xde,0x0c }}, - {16, 0xf2b0, 0, {0xef,0x80,0x31,0xf8,0x2c,0x78,0x03,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2c0, 0, {0x08,0x1d,0xad,0x84,0xfb,0x68,0x3e,0x00,0x0f,0xb0,0x03,0xe8,0x00,0xfb,0x00,0xfa }}, - {16, 0xf2d0, 0, {0xd8,0x0e,0xb5,0x03,0xed,0x00,0xdb,0x00,0x3a,0xc0,0x8e,0xa0,0x03,0xe0,0x00,0xfb }}, - {16, 0xf2e0, 0, {0x40,0x3e,0xc0,0x0b,0xb0,0x43,0xc4,0x04,0xef,0x02,0xbf,0xc0,0x0f,0xb0,0x03,0xc2 }}, - {16, 0xf2f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x42,0xc7,0x38,0x33,0x64 }}, - {16, 0xf300, 0, {0x0e,0x7c,0x03,0x5e,0x00,0xdf,0xa0,0x37,0xf0,0x0d,0xf8,0x03,0xff,0x20,0xcf,0x81 }}, - {16, 0xf310, 0, {0x33,0xe2,0x0c,0xd8,0x03,0xbe,0x00,0x7f,0xc0,0x33,0xe0,0x0c,0xf9,0x03,0x7e,0x00 }}, - {16, 0xf320, 0, {0xfd,0x80,0x3f,0xe0,0x0f,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf330, 0, {0xa8,0x11,0x9c,0x00,0x87,0xa0,0x21,0x14,0x08,0x71,0x02,0x14,0x10,0xd7,0x20,0x35 }}, - {16, 0xf340, 0, {0xc0,0x0c,0x70,0x03,0xbc,0x00,0x85,0x08,0x2b,0xc0,0x4d,0x46,0x02,0xd1,0x00,0xb7 }}, - {16, 0xf350, 0, {0x00,0x21,0xc0,0x08,0x60,0x02,0x08,0x80,0xf5,0x20,0x3d,0xca,0x0f,0x54,0x03,0xea }}, - {16, 0xf360, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x11,0x8f,0x01,0x20,0x84 }}, - {16, 0xf370, 0, {0x1a,0xf0,0x02,0x18,0x00,0xa7,0x34,0x65,0xc0,0x09,0x71,0x02,0xdc,0x00,0x8e,0x00 }}, - {16, 0xf380, 0, {0x29,0xc0,0x08,0x50,0x06,0x9c,0x00,0xbf,0x88,0x2d,0xc4,0x0a,0x60,0x26,0x58,0x24 }}, - {16, 0xf390, 0, {0x97,0x00,0x6d,0xc0,0x9b,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3a0, 0, {0x20,0x14,0xcc,0x00,0x8b,0x40,0x20,0x00,0x18,0x30,0x02,0x00,0x00,0xbb,0x02,0x24 }}, - {16, 0xf3b0, 0, {0xc0,0x08,0x30,0x20,0xcc,0x00,0x81,0xc0,0x28,0xc0,0x0b,0x04,0x82,0xe0,0x10,0xbb }}, - {16, 0xf3c0, 0, {0xa0,0x2c,0xe0,0x0a,0x20,0x06,0x00,0x00,0xb3,0x00,0x28,0xc0,0x0a,0x10,0x02,0x88 }}, - {16, 0xf3d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xcf,0x10,0x32,0x00 }}, - {16, 0xf3e0, 0, {0x0e,0xf0,0x0b,0x24,0x00,0xef,0x00,0x37,0xc0,0x0d,0xf0,0x03,0xfc,0x06,0xc1,0x50 }}, - {16, 0xf3f0, 0, {0x3b,0xc0,0x0c,0xb4,0x03,0xac,0x00,0xf8,0xc0,0xbe,0xc8,0x2e,0xb0,0x03,0x6e,0x01 }}, - {16, 0xf400, 0, {0xfb,0x00,0x2d,0xc0,0x4b,0x90,0x02,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf410, 0, {0x80,0x00,0xec,0x04,0xfb,0x00,0x3e,0x00,0x0f,0xb0,0x03,0xad,0x00,0x9b,0x00,0x3e }}, - {16, 0xf420, 0, {0xc0,0x0f,0x30,0x03,0xac,0x00,0xf8,0x00,0x2e,0xc0,0x05,0xb4,0x03,0xed,0x00,0xf8 }}, - {16, 0xf430, 0, {0x40,0x32,0xc0,0x09,0x00,0x03,0xe0,0x91,0xe3,0x00,0x3e,0xc0,0x0f,0x90,0x11,0xe0 }}, - {16, 0xf440, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xec,0x00,0xef,0x00,0x33,0x20 }}, - {16, 0xf450, 0, {0x4f,0xf0,0x03,0xb4,0x00,0xef,0x03,0x3a,0xc0,0x0f,0xf0,0x03,0x3c,0x00,0xdc,0x00 }}, - {16, 0xf460, 0, {0x31,0xc0,0x8d,0xf8,0x03,0xfe,0x04,0xcf,0x00,0x32,0xc8,0x0c,0xf0,0x0b,0x1c,0x00 }}, - {16, 0xf470, 0, {0xcf,0x93,0x33,0xc0,0x8c,0x40,0x02,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf480, 0, {0x81,0x04,0x6c,0x00,0xbb,0x00,0xa2,0x04,0x0b,0x30,0x02,0x0e,0x00,0xab,0x00,0x2a }}, - {16, 0xf490, 0, {0xc0,0x09,0xb0,0x03,0x6c,0x08,0xa8,0xc0,0x36,0xc0,0x08,0xbc,0x02,0xef,0x02,0xab }}, - {16, 0xf4a0, 0, {0xd0,0x20,0xe0,0x08,0xb8,0x22,0x26,0x10,0x8b,0x00,0x22,0xc0,0x20,0x9c,0x02,0x20 }}, - {16, 0xf4b0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xbb,0x00,0x26,0x00 }}, - {16, 0xf4c0, 0, {0x0a,0xb0,0x02,0xa2,0x08,0xab,0x00,0x6a,0xc0,0x0b,0xb0,0x0a,0x0c,0x00,0x8b,0x80 }}, - {16, 0xf4d0, 0, {0x22,0xc0,0x09,0xb1,0x02,0xec,0x40,0x88,0x08,0x22,0xc0,0x08,0xb8,0x02,0x26,0x00 }}, - {16, 0xf4e0, 0, {0x8b,0x00,0x22,0xc0,0x08,0x98,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4f0, 0, {0x08,0x04,0x0c,0x00,0xb3,0x00,0x24,0x00,0x0b,0xb0,0x02,0x00,0x01,0x83,0x00,0x20 }}, - {16, 0xf500, 0, {0xc0,0x09,0x30,0x02,0x4c,0x00,0x00,0x04,0x24,0xc0,0x08,0x30,0x06,0x4c,0x00,0x80 }}, - {16, 0xf510, 0, {0x00,0x2c,0xc0,0x08,0x00,0x02,0x00,0x41,0x83,0x00,0xa2,0xc0,0x08,0x10,0x0a,0x82 }}, - {16, 0xf520, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xef,0x08,0x26,0x00 }}, - {16, 0xf530, 0, {0x0e,0xf0,0x02,0xa0,0x00,0xe7,0x00,0x3b,0xc0,0x0f,0xf5,0x43,0x3c,0x02,0xda,0x00 }}, - {16, 0xf540, 0, {0x32,0xc0,0x0d,0xb0,0x03,0xec,0x00,0xcb,0x00,0xb2,0xc0,0x0c,0xa0,0x03,0x28,0x10 }}, - {16, 0xf550, 0, {0xcb,0x00,0x32,0xc0,0x0c,0x80,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf560, 0, {0xa0,0x0d,0xfc,0x00,0xfb,0x00,0x3b,0x00,0x0f,0xf0,0x03,0xf0,0x00,0xff,0x02,0x3f }}, - {16, 0xf570, 0, {0xc0,0x0d,0xf2,0x03,0xbc,0x00,0xf4,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xf7 }}, - {16, 0xf580, 0, {0x00,0x33,0xc0,0x0f,0x60,0x03,0xf0,0x88,0xff,0x00,0x3f,0xc0,0x4f,0xd0,0x03,0x68 }}, - {16, 0xf590, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x40,0xfc,0x31,0x3b,0x08 }}, - {16, 0xf5a0, 0, {0x4f,0xf9,0x43,0xef,0x00,0xdf,0x30,0x32,0x21,0x0f,0x94,0x07,0x7d,0x80,0xef,0x38 }}, - {16, 0xf5b0, 0, {0x32,0x09,0x1c,0x38,0x03,0xf2,0x21,0xfd,0x00,0x33,0xc4,0x0c,0xf0,0x02,0xfc,0x00 }}, - {16, 0xf5c0, 0, {0xdf,0x00,0x33,0xc0,0x0f,0xf0,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5d0, 0, {0x80,0x10,0xec,0x88,0x8b,0x60,0x22,0xe5,0x0e,0xb2,0x22,0xec,0x80,0xaf,0x11,0x2a }}, - {16, 0xf5e0, 0, {0x20,0x0b,0xb1,0x13,0xac,0x48,0x8b,0x45,0x34,0xcc,0x48,0xb0,0x02,0x6b,0x00,0xba }}, - {16, 0xf5f0, 0, {0x82,0x36,0x00,0x08,0x88,0x22,0xc0,0x04,0x88,0x00,0xa2,0x08,0x8b,0x88,0x62,0x20 }}, - {16, 0xf600, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xa1,0x30,0x28,0x00 }}, - {16, 0xf610, 0, {0x0b,0x32,0x02,0xcc,0x00,0xa3,0x22,0x2c,0x00,0x8b,0x12,0x06,0xc8,0x80,0xa3,0x00 }}, - {16, 0xf620, 0, {0x20,0x02,0xca,0x30,0x06,0xc4,0x01,0xb1,0x00,0x68,0x80,0x09,0x20,0x02,0x88,0x00 }}, - {16, 0xf630, 0, {0x83,0x00,0x20,0xc2,0x0b,0x00,0x0a,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf640, 0, {0xc0,0x15,0xac,0x00,0x8b,0x61,0x62,0xc0,0x0b,0xb2,0x02,0xe8,0x00,0xab,0x02,0x2a }}, - {16, 0xf650, 0, {0x61,0x1b,0x90,0x02,0xa8,0x00,0xab,0x00,0x20,0xc0,0x0a,0xb0,0x02,0x6c,0x04,0xba }}, - {16, 0xf660, 0, {0x00,0x2e,0x40,0x89,0x90,0x02,0xe6,0x08,0x98,0x00,0x22,0x00,0x0b,0xb0,0x02,0xb0 }}, - {16, 0xf670, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xee,0x00,0xf8,0x01,0x3a,0x04 }}, - {16, 0xf680, 0, {0x0f,0xac,0x03,0xec,0x90,0xfb,0x02,0x3e,0xe0,0x0b,0x90,0x42,0x67,0x80,0xa8,0xc4 }}, - {16, 0xf690, 0, {0x22,0x48,0x22,0x86,0x03,0xe1,0x40,0xb8,0x02,0x2a,0x40,0x29,0x90,0x03,0xec,0x02 }}, - {16, 0xf6a0, 0, {0xc9,0x48,0x32,0x40,0x0f,0xb0,0x13,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6b0, 0, {0xe0,0x01,0xac,0x40,0xfb,0x00,0x1f,0xa2,0x0e,0xf8,0x82,0xfc,0x08,0xff,0x00,0x3f }}, - {16, 0xf6c0, 0, {0xc0,0x0f,0xfa,0x43,0x96,0x44,0xd4,0x91,0x3f,0x40,0x0d,0xc0,0x03,0xfa,0x00,0xff }}, - {16, 0xf6d0, 0, {0x08,0x25,0x80,0x0e,0xe0,0x03,0xd0,0x00,0xea,0x00,0x3f,0x80,0x0f,0xc0,0x03,0x78 }}, - {16, 0xf6e0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xe1,0x20,0x3a,0x50 }}, - {16, 0xf6f0, 0, {0x0f,0x90,0x03,0x2c,0x00,0xeb,0x08,0x76,0x05,0x0e,0xb0,0x27,0xe0,0x10,0xea,0x40 }}, - {16, 0xf700, 0, {0xb2,0xc0,0x0c,0xa4,0x43,0x25,0x00,0xf8,0x00,0x32,0x08,0x0f,0x80,0x43,0xe8,0x00 }}, - {16, 0xf710, 0, {0xd1,0x08,0xee,0x40,0x0f,0x00,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf720, 0, {0xc8,0x05,0x2c,0x00,0x8b,0x00,0x22,0xd0,0x0b,0x90,0x82,0x2c,0x00,0x87,0x40,0x22 }}, - {16, 0xf730, 0, {0x60,0x8b,0xb0,0x02,0xe0,0x00,0xd8,0x50,0x22,0xd0,0x0c,0xa0,0x03,0x6c,0x00,0xb3 }}, - {16, 0xf740, 0, {0xc8,0x3e,0xd0,0x0b,0xb8,0x02,0x25,0x08,0x8a,0x20,0x2a,0x80,0x8b,0xb8,0x82,0xf2 }}, - {16, 0xf750, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x64,0x00,0xa0,0xc0,0x24,0xc0 }}, - {16, 0xf760, 0, {0x09,0x38,0x02,0x2c,0x00,0x83,0x03,0x20,0x00,0x10,0x30,0x22,0xcc,0x00,0x83,0x00 }}, - {16, 0xf770, 0, {0x60,0x08,0x0a,0x30,0x82,0x4c,0x00,0xb1,0xc0,0x00,0xd1,0x0b,0x38,0x02,0x84,0x80 }}, - {16, 0xf780, 0, {0x82,0x01,0x20,0x80,0x03,0x38,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf790, 0, {0x20,0x01,0x16,0x40,0x84,0x98,0x25,0xe0,0x0b,0x7a,0x02,0xfa,0x48,0xa3,0x20,0x61 }}, - {16, 0xf7a0, 0, {0x24,0x0b,0x79,0x00,0xce,0xc0,0x93,0xa4,0x21,0xa6,0x0b,0x78,0x12,0xde,0x80,0xb6 }}, - {16, 0xf7b0, 0, {0x80,0x2d,0x24,0x0b,0x4b,0x02,0x1a,0x40,0x85,0x81,0x21,0x60,0x0b,0x48,0x02,0xc8 }}, - {16, 0xf7c0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xe2,0xa0,0xb4,0xfe }}, - {16, 0xf7d0, 0, {0x4b,0xb8,0x0b,0x0e,0x00,0xa3,0xb0,0x24,0xa8,0x0e,0x1b,0x02,0xce,0xc1,0xc3,0xc0 }}, - {16, 0xf7e0, 0, {0x30,0x68,0x2e,0x3a,0x47,0x4e,0x80,0xf1,0x80,0x30,0x80,0x0f,0x22,0x83,0x80,0x00 }}, - {16, 0xf7f0, 0, {0xc2,0x10,0x38,0x80,0x4f,0x00,0x07,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf800, 0, {0x40,0x0d,0xbc,0x10,0xfe,0x04,0x3b,0xc1,0x07,0xf0,0x03,0x1c,0xc8,0xdf,0x2a,0x0b }}, - {16, 0xf810, 0, {0xc4,0x8f,0xd1,0x43,0xf8,0x02,0x7f,0x00,0x3f,0xc0,0x0c,0xf1,0x0f,0x3c,0x00,0xf2 }}, - {16, 0xf820, 0, {0x11,0x3f,0x41,0x1f,0x52,0x03,0xbc,0x0e,0xed,0x14,0x3f,0x40,0x0f,0xf8,0x03,0xd0 }}, - {16, 0xf830, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xe9,0x00,0x32,0x80 }}, - {16, 0xf840, 0, {0x0e,0xbe,0x4b,0x6f,0x00,0xcb,0x82,0x7a,0xc0,0x2c,0xb0,0x03,0x2c,0x00,0xc9,0x00 }}, - {16, 0xf850, 0, {0x32,0x00,0x2c,0x10,0x03,0x2c,0x08,0xc0,0x00,0x26,0x40,0x6c,0x90,0x13,0x24,0x12 }}, - {16, 0xf860, 0, {0xc8,0x01,0x3e,0x00,0x0f,0xb8,0x0b,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf870, 0, {0x48,0x11,0x94,0x00,0x8d,0x00,0x21,0x80,0x0b,0x70,0x82,0x3c,0x20,0x83,0x32,0x29 }}, - {16, 0xf880, 0, {0xc0,0x08,0xf0,0x20,0x14,0x00,0x80,0x00,0x23,0x00,0x08,0x50,0x06,0x9c,0x04,0xd7 }}, - {16, 0xf890, 0, {0x02,0x28,0x80,0x08,0x60,0x02,0x08,0x10,0x87,0x00,0x2d,0xc0,0x0b,0x40,0x02,0x12 }}, - {16, 0xf8a0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xa7,0x80,0x21,0xe0 }}, - {16, 0xf8b0, 0, {0x0b,0x5c,0x12,0x1e,0x04,0x87,0x82,0x0d,0xa0,0x09,0x78,0x16,0x02,0x00,0xb4,0x80 }}, - {16, 0xf8c0, 0, {0x25,0xe0,0x0b,0x78,0x02,0x9e,0x00,0x84,0x80,0x21,0x22,0x08,0x08,0x02,0x12,0x01 }}, - {16, 0xf8d0, 0, {0x84,0xc0,0x2d,0x20,0x0b,0x08,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8e0, 0, {0x48,0x14,0xcc,0x00,0x83,0x42,0xa0,0xd8,0x0b,0x34,0x82,0x0c,0x00,0xa3,0x02,0x20 }}, - {16, 0xf8f0, 0, {0xe0,0x08,0xb0,0x02,0x0c,0x88,0xb3,0x21,0x24,0xd8,0x0b,0x3e,0x02,0x8c,0x00,0x93 }}, - {16, 0xf900, 0, {0x08,0x28,0xc0,0x08,0x38,0x02,0x2c,0x05,0x8b,0x01,0x2c,0xe0,0x0b,0x30,0x02,0x12 }}, - {16, 0xf910, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xee,0x00,0x33,0x90 }}, - {16, 0xf920, 0, {0x0f,0xa0,0x0b,0x68,0x00,0xca,0x01,0x7f,0xa8,0x0c,0xaa,0x03,0x3a,0x12,0xfe,0xe2 }}, - {16, 0xf930, 0, {0x37,0xb0,0x0f,0xee,0x02,0x18,0x00,0xca,0x40,0x36,0xa0,0x08,0xa0,0x8b,0x28,0x00 }}, - {16, 0xf940, 0, {0xca,0x81,0x2e,0xa0,0x0f,0xe0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf950, 0, {0x48,0x00,0xe0,0x00,0xf8,0x08,0x3e,0x00,0x0f,0x80,0x03,0xa2,0x02,0xd8,0x40,0x3e }}, - {16, 0xf960, 0, {0x08,0x0f,0x80,0x13,0xe0,0x40,0x48,0x40,0xb8,0x04,0x08,0x84,0x03,0x61,0x00,0xfc }}, - {16, 0xf970, 0, {0x00,0x3f,0x00,0x4f,0xc0,0x03,0xf1,0x00,0xfc,0x00,0x3f,0x04,0x0f,0xc0,0x03,0xd2 }}, - {16, 0xf980, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x00,0xf9,0x00,0x30,0x50 }}, - {16, 0xf990, 0, {0x4c,0xb9,0x03,0x6c,0x18,0xf9,0x00,0x36,0x40,0x0e,0x9c,0x23,0xa4,0x02,0x41,0x00 }}, - {16, 0xf9a0, 0, {0xb2,0x44,0x0e,0x9a,0x03,0xa6,0x80,0xc9,0x00,0x3a,0x60,0x0a,0x90,0x03,0xa4,0x80 }}, - {16, 0xf9b0, 0, {0xc9,0x00,0x34,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9c0, 0, {0x80,0x04,0x64,0x00,0x89,0x40,0x22,0x78,0x08,0x94,0x02,0xe4,0x10,0xb9,0x00,0x3c }}, - {16, 0xf9d0, 0, {0x62,0x18,0x94,0x82,0xa4,0x00,0x89,0xc8,0x22,0x70,0x48,0x1e,0x01,0x67,0x80,0xd1 }}, - {16, 0xf9e0, 0, {0x00,0xbc,0x42,0x08,0x10,0x02,0x25,0x20,0x89,0x02,0x22,0x40,0x08,0x90,0x02,0xe0 }}, - {16, 0xf9f0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb1,0x28,0x22,0x40 }}, - {16, 0xfa00, 0, {0x08,0xb0,0x82,0x64,0x04,0x39,0x41,0x2e,0x48,0x0a,0x90,0x02,0x04,0x18,0xa9,0x20 }}, - {16, 0xfa10, 0, {0x22,0x42,0x4a,0x90,0x02,0x2c,0x04,0x89,0x04,0x2b,0x48,0x02,0xd0,0x02,0xb4,0x0a }}, - {16, 0xfa20, 0, {0x8d,0x80,0x23,0xc0,0x48,0xd0,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa30, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0xa0,0x48,0x28,0x10,0x02,0xc4,0x00,0xb1,0x24,0x2a }}, - {16, 0xfa40, 0, {0x40,0x08,0x12,0x42,0x85,0x80,0xa1,0x20,0xa0,0x48,0x08,0x90,0x02,0x44,0x00,0x95 }}, - {16, 0xfa50, 0, {0x2c,0x2d,0x5a,0x0a,0x72,0x82,0x14,0xa0,0x85,0xa8,0x21,0x4a,0x08,0x52,0x82,0xc2 }}, - {16, 0xfa60, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x41,0x40,0xf8,0x50,0x32,0x00 }}, - {16, 0xfa70, 0, {0x8c,0x05,0x03,0x61,0x40,0xf8,0x51,0x2e,0x00,0x0a,0x85,0x02,0x20,0x00,0xe8,0x50 }}, - {16, 0xfa80, 0, {0x32,0x14,0x06,0x85,0x17,0xa0,0x00,0xc8,0x20,0x3a,0x08,0x0e,0x82,0x03,0xa0,0x80 }}, - {16, 0xfa90, 0, {0xc8,0x20,0x32,0x08,0x2c,0xc2,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfaa0, 0, {0x98,0x19,0xf4,0x40,0xff,0x10,0x3f,0x44,0x0b,0xb0,0x03,0xe4,0x00,0xf9,0x10,0x3d }}, - {16, 0xfab0, 0, {0x40,0x0f,0xd1,0x03,0xf4,0x58,0x9d,0x10,0x3f,0x44,0x4f,0xd0,0x03,0xd5,0x00,0xf9 }}, - {16, 0xfac0, 0, {0x00,0x3e,0x40,0x8d,0x90,0x03,0xe4,0xb8,0xf9,0x28,0xba,0x6a,0x0f,0x90,0x03,0xe6 }}, - {16, 0xfad0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xe7,0x00,0xfd,0x88,0x3e,0x60 }}, - {16, 0xfae0, 0, {0x8f,0xd0,0x03,0x24,0x01,0xdd,0x80,0x73,0x40,0x0f,0xd8,0x03,0xa6,0x04,0xcd,0xa2 }}, - {16, 0xfaf0, 0, {0x33,0x78,0x1c,0xd0,0x03,0x34,0x01,0xf5,0x88,0x3b,0x68,0x0c,0xda,0x47,0x37,0x80 }}, - {16, 0xfb00, 0, {0xcd,0x88,0x32,0x62,0x0c,0xda,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb10, 0, {0x38,0x10,0xe3,0x80,0xb8,0x80,0x2e,0x14,0x0b,0x0a,0x82,0x22,0x80,0xb8,0xf8,0xa2 }}, - {16, 0xfb20, 0, {0x00,0x0b,0x8f,0xa3,0x83,0xe0,0x88,0xeb,0x22,0xa9,0x08,0x88,0x12,0xa0,0x05,0xb8 }}, - {16, 0xfb30, 0, {0x00,0x2a,0xaa,0x88,0x80,0x13,0x62,0x82,0x88,0x80,0x22,0x28,0x88,0xa4,0x02,0x0e }}, - {16, 0xfb40, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x0a,0x2c,0x41 }}, - {16, 0xfb50, 0, {0x0b,0x10,0x06,0x04,0x20,0xa1,0x00,0x00,0x40,0x8b,0x10,0x46,0xc4,0x01,0x91,0x11 }}, - {16, 0xfb60, 0, {0x24,0x58,0x68,0x90,0xc2,0x04,0x00,0xb1,0x00,0xa8,0x50,0x09,0x14,0x0a,0x05,0x95 }}, - {16, 0xfb70, 0, {0xa1,0x08,0xa0,0x42,0x28,0x11,0x0a,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb80, 0, {0x18,0x15,0xa4,0x18,0xb9,0x20,0x2e,0x50,0x0b,0x90,0x06,0x24,0x09,0xb9,0x00,0x22 }}, - {16, 0xfb90, 0, {0x40,0x8b,0x91,0x02,0x84,0x00,0x99,0x64,0x24,0x40,0x58,0x90,0x02,0xa4,0x20,0xbb }}, - {16, 0xfba0, 0, {0x00,0x2a,0x40,0x09,0xb0,0x02,0x05,0x01,0xa9,0x00,0x22,0x40,0x88,0x92,0x02,0x06 }}, - {16, 0xfbb0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x00,0xf9,0x40,0x3e,0x40 }}, - {16, 0xfbc0, 0, {0x4f,0x98,0x0b,0x24,0x80,0xd9,0x00,0x22,0x72,0x0b,0x98,0x03,0xe4,0x84,0xd9,0x00 }}, - {16, 0xfbd0, 0, {0xb6,0x70,0x08,0x99,0x02,0x24,0x00,0xb9,0x00,0x2a,0x40,0x0d,0x94,0xc2,0x25,0x00 }}, - {16, 0xfbe0, 0, {0xa9,0x00,0x22,0x40,0x0c,0x94,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbf0, 0, {0x28,0x01,0xa6,0x80,0xf9,0x08,0x3e,0xc0,0x0f,0x91,0x43,0xe4,0x00,0xf9,0x00,0x3e }}, - {16, 0xfc00, 0, {0x50,0x0f,0x98,0x03,0xa5,0x00,0xe9,0x00,0x3a,0x64,0x0f,0x90,0x03,0xe4,0x00,0xf9 }}, - {16, 0xfc10, 0, {0x00,0x3c,0x40,0x6e,0x90,0x03,0xe4,0x20,0xd9,0x00,0x3c,0x40,0x0f,0x90,0x82,0xca }}, - {16, 0xfc20, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xe8,0x00,0x3e,0x00 }}, - {16, 0xfc30, 0, {0x4f,0x84,0x0b,0x20,0x00,0xf8,0x00,0x36,0x01,0x0e,0x80,0x03,0xe0,0x00,0xc8,0x40 }}, - {16, 0xfc40, 0, {0x32,0x10,0x2d,0x80,0x03,0xe0,0x54,0xc8,0x00,0x36,0x10,0x0f,0x04,0x83,0xe0,0x50 }}, - {16, 0xfc50, 0, {0xd8,0x04,0x12,0x00,0x0c,0x00,0x0b,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc60, 0, {0x28,0x05,0x28,0x00,0x8e,0x42,0x2e,0xa2,0x8b,0xea,0x02,0x28,0x08,0xbe,0x89,0x37 }}, - {16, 0xfc70, 0, {0x84,0x48,0xe0,0x12,0x28,0x02,0x8e,0xc0,0x23,0xb0,0x4d,0x60,0x62,0xf8,0x00,0x86 }}, - {16, 0xfc80, 0, {0x00,0x23,0x80,0x0b,0xe0,0x02,0xf8,0x00,0x0e,0x00,0x22,0x80,0x08,0xe4,0x02,0x0a }}, - {16, 0xfc90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xa3,0x00,0x2c,0x80 }}, - {16, 0xfca0, 0, {0x1b,0xb0,0x9a,0x4c,0x10,0x9b,0x80,0x24,0xc0,0x0a,0x30,0x00,0x0c,0x04,0x9b,0x20 }}, - {16, 0xfcb0, 0, {0x20,0xd6,0x08,0x30,0x02,0x8e,0x08,0xa3,0x04,0x24,0xc0,0x19,0x34,0x02,0xc7,0x07 }}, - {16, 0xfcc0, 0, {0xaa,0xa4,0xa0,0xc0,0x48,0x34,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfcd0, 0, {0xa0,0x01,0x0e,0x00,0x87,0x00,0x2d,0xc0,0x0b,0x40,0x02,0x5c,0x40,0xb3,0x14,0x25 }}, - {16, 0xfce0, 0, {0xe0,0x08,0x7a,0x02,0x9e,0xc0,0x92,0x40,0xa0,0x00,0x49,0x60,0x02,0xce,0x02,0x8e }}, - {16, 0xfcf0, 0, {0x01,0x21,0xc0,0x8b,0x54,0x02,0xc4,0x08,0x86,0x40,0x21,0xc8,0x88,0x10,0x02,0x28 }}, - {16, 0xfd00, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0xc0,0xe4,0x80,0x3d,0xe2 }}, - {16, 0xfd10, 0, {0x0f,0x58,0x03,0x5e,0x90,0xb6,0xa2,0x35,0xe0,0x0e,0x7c,0x23,0x1c,0x00,0xd6,0x80 }}, - {16, 0xfd20, 0, {0x31,0xe0,0x84,0x78,0x03,0xde,0x00,0xc7,0x80,0x35,0xe0,0x0f,0x68,0x03,0xde,0x00 }}, - {16, 0xfd30, 0, {0xe3,0x80,0x33,0xe8,0x2c,0x78,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd40, 0, {0x08,0x1d,0xac,0x90,0xfa,0x00,0x7e,0x40,0x0f,0x90,0x03,0xac,0x01,0xfb,0x00,0x3c }}, - {16, 0xfd50, 0, {0x41,0x0f,0x30,0x0b,0x2d,0x04,0xeb,0x01,0x3e,0xc0,0x0e,0xb0,0x03,0xec,0x00,0xfa }}, - {16, 0xfd60, 0, {0x00,0x3f,0xc0,0x0f,0x80,0x03,0xec,0x00,0xe9,0x60,0x3e,0xe4,0x0f,0x90,0x03,0xc2 }}, - {16, 0xfd70, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x20,0xff,0x90,0x3e,0x20 }}, - {16, 0xfd80, 0, {0x0c,0xa9,0x07,0x2e,0x44,0xc9,0x91,0x30,0xa0,0x0c,0xb8,0x63,0x2f,0x44,0xcb,0xa1 }}, - {16, 0xfd90, 0, {0x36,0x20,0x8c,0xf8,0x03,0x36,0x00,0xcf,0x82,0x33,0xe0,0x0c,0xf8,0x23,0x2e,0x00 }}, - {16, 0xfda0, 0, {0xce,0xc0,0x3b,0xe0,0x0c,0x68,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfdb0, 0, {0xa8,0x11,0x9c,0x84,0xb3,0x54,0x2c,0xf4,0x28,0xba,0x8a,0x3e,0x40,0x81,0xa0,0x29 }}, - {16, 0xfdc0, 0, {0xb0,0x0f,0x78,0x42,0xae,0x00,0x83,0x90,0x33,0xe8,0x0d,0xe1,0x00,0x85,0x40,0x82 }}, - {16, 0xfdd0, 0, {0x24,0x23,0xc6,0x0d,0x71,0x03,0x5e,0xe0,0x87,0x00,0x2b,0xc1,0x0d,0x44,0x02,0x2a }}, - {16, 0xfde0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x08,0x35,0x14,0x6d,0xc0 }}, - {16, 0xfdf0, 0, {0x88,0x72,0x32,0x5c,0x80,0x84,0x30,0x2b,0x88,0x0a,0x70,0x42,0x5c,0xa8,0x91,0x08 }}, - {16, 0xfe00, 0, {0x25,0xc8,0x09,0x70,0x02,0x4c,0x22,0x83,0x0a,0x61,0xc0,0x09,0x20,0x02,0x04,0x00 }}, - {16, 0xfe10, 0, {0x87,0x00,0x21,0xc0,0x08,0x60,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfe20, 0, {0x20,0x14,0xcc,0x10,0xb3,0x85,0x6c,0xdc,0x08,0x34,0x02,0x4d,0x21,0x81,0x00,0x28 }}, - {16, 0xfe30, 0, {0x02,0x4a,0x31,0x12,0xef,0x0c,0x91,0xc2,0x20,0xf0,0x08,0x30,0x42,0x8e,0x00,0x82 }}, - {16, 0xfe40, 0, {0x40,0x20,0xc8,0x19,0x28,0x02,0x22,0x81,0x83,0xc0,0x28,0xd4,0x09,0x00,0x0a,0x08 }}, - {16, 0xfe50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xfb,0xa0,0x3e,0xc0 }}, - {16, 0xfe60, 0, {0x8c,0x04,0x12,0x7d,0x10,0xcf,0x02,0x3a,0x50,0x08,0xc0,0x42,0x7d,0x52,0x58,0x01 }}, - {16, 0xfe70, 0, {0x36,0x22,0x69,0xd0,0x13,0x2a,0x00,0x88,0x82,0x32,0xf0,0x09,0xb8,0x82,0x2f,0x00 }}, - {16, 0xfe80, 0, {0xc9,0xc8,0x23,0xc0,0x0c,0x8a,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfe90, 0, {0x80,0x00,0xec,0x00,0xb9,0x40,0x3c,0x50,0x4f,0x80,0x23,0xac,0x12,0xfb,0x00,0x2a }}, - {16, 0xfea0, 0, {0xc0,0x6d,0x80,0x13,0xac,0x00,0xe8,0x04,0xba,0x10,0x0f,0x80,0x03,0xe8,0x00,0xf3 }}, - {16, 0xfeb0, 0, {0x08,0x3c,0x80,0x0f,0x90,0x83,0xec,0x04,0xf9,0x60,0x2c,0xc2,0x0f,0x80,0x83,0xe0 }}, - {16, 0xfec0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xec,0x2c,0x3f,0xf0 }}, - {16, 0xfed0, 0, {0x8c,0xfa,0x8b,0xbc,0x00,0xfe,0x00,0x3f,0x00,0x0f,0x79,0x03,0x3c,0x00,0xce,0x08 }}, - {16, 0xfee0, 0, {0x0b,0xc2,0x0c,0xf0,0x03,0xbc,0x00,0xfc,0x00,0x33,0x40,0x8c,0x7a,0x03,0x3a,0x00 }}, - {16, 0xfef0, 0, {0xc5,0x00,0x33,0xc0,0x4c,0xc8,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xff00, 0, {0x81,0x04,0x6c,0x00,0x88,0xc0,0x2e,0xe0,0x08,0x94,0x02,0x2c,0x00,0xbb,0x80,0x66 }}, - {16, 0xff10, 0, {0x30,0x16,0xb0,0x02,0x2c,0x00,0xda,0x4c,0x22,0xf0,0x08,0xf0,0x03,0xec,0x00,0xeb }}, - {16, 0xff20, 0, {0xc0,0x22,0x68,0x00,0x94,0x02,0x2c,0x02,0xa9,0x80,0x22,0xc0,0x08,0x0c,0x02,0xa0 }}, - {16, 0xff30, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xab,0x04,0x2e,0xc0 }}, - {16, 0xff40, 0, {0x08,0xa4,0x06,0x2c,0x04,0xab,0x10,0x2e,0x60,0x43,0x80,0x82,0x6c,0x01,0x81,0x80 }}, - {16, 0xff50, 0, {0x28,0x0a,0x08,0x91,0x00,0xe0,0x00,0xb8,0x80,0x02,0xe0,0x08,0x80,0x02,0x2d,0x80 }}, - {16, 0xff60, 0, {0x88,0xc0,0x22,0xc0,0x08,0x82,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xff70, 0, {0x08,0x04,0x0c,0x00,0x80,0x44,0x2c,0xc8,0x28,0xa0,0x22,0x0c,0x04,0xb3,0x26,0x2c }}, - {16, 0xff80, 0, {0xc8,0x88,0x01,0x06,0x0c,0xe0,0x91,0x20,0x20,0x0c,0x38,0x04,0x22,0xc0,0x48,0xa3 }}, - {16, 0xff90, 0, {0x42,0xa0,0x81,0x08,0x00,0x02,0x0c,0x80,0x81,0x00,0x20,0xc0,0x28,0x00,0x02,0x82 }}, - {16, 0xffa0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0xa9,0x40,0x3e,0x44 }}, - {16, 0xffb0, 0, {0x08,0xb1,0x03,0x2c,0x40,0xea,0x49,0x2e,0x0d,0x0b,0xb6,0x13,0x7d,0x80,0xc9,0x40 }}, - {16, 0xffc0, 0, {0xba,0xd0,0x0c,0xb4,0x03,0xac,0x00,0xf8,0x00,0x32,0x40,0x0c,0x80,0x0b,0x20,0x00 }}, - {16, 0xffd0, 0, {0xc5,0x00,0xb2,0xc0,0x0c,0x80,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xffe0, 0, {0xa0,0x1d,0xfc,0x04,0xfc,0x00,0x3d,0xc5,0x0b,0xf1,0x00,0xfc,0xd0,0x77,0x29,0x37 }}, - {16, 0xfff0, 0, {0x0c,0x8e,0x74,0x03,0xfc,0x08,0xfd,0x69,0x3f,0xd8,0x0f,0xf0,0x03,0xbc,0x00,0xef }}, - {16, 0x8010, 0, {0x00,0x3f,0x40,0x07,0xc0,0x03,0xf0,0x40,0xfd,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xe8 }}, - {16, 0x8020, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x0d,0xfc,0xc0,0xdc,0x80,0x3f,0xc8 }}, - {16, 0x8030, 0, {0x0f,0x48,0x03,0x7c,0x20,0xff,0x68,0x37,0xe0,0x0e,0xf1,0x03,0x9c,0x00,0xbf,0x20 }}, - {16, 0x8040, 0, {0x37,0xe0,0x0c,0xc8,0x13,0x3c,0x40,0xed,0x60,0xbb,0xe4,0x2c,0x43,0x4b,0x70,0xa0 }}, - {16, 0x8050, 0, {0xcc,0x2c,0x3f,0x09,0x0f,0xd8,0x43,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8060, 0, {0x80,0x00,0xed,0xc0,0xb8,0x80,0x2f,0xf4,0x0f,0x98,0x02,0x3f,0x00,0xbf,0x42,0x22 }}, - {16, 0x8070, 0, {0xca,0x08,0xf4,0x02,0x3e,0x00,0xbf,0xd0,0x22,0x60,0x28,0x88,0x0a,0x3d,0x80,0x8d }}, - {16, 0x8080, 0, {0x40,0x22,0xc8,0x08,0x81,0x02,0x21,0x80,0xdb,0xc0,0x2e,0xa5,0x0b,0x98,0x42,0x20 }}, - {16, 0x8090, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x10,0xb0,0x00,0x2c,0xc0 }}, - {16, 0x80a0, 0, {0x0b,0x20,0x02,0xcc,0x00,0xb3,0x20,0x26,0xc0,0x8a,0x36,0x12,0x8c,0x41,0xb3,0x00 }}, - {16, 0x80b0, 0, {0x2e,0x40,0x08,0x00,0x02,0x0d,0x81,0xa1,0x30,0x22,0xc8,0x89,0xa2,0x42,0x08,0x20 }}, - {16, 0x80c0, 0, {0xb0,0x00,0x2c,0x40,0x0b,0x90,0x26,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80d0, 0, {0xc0,0x15,0xac,0x00,0xb8,0x50,0x2e,0xc0,0x0a,0x90,0x02,0xac,0x00,0xbb,0x00,0x22 }}, - {16, 0x80e0, 0, {0xc0,0x08,0xb0,0x62,0x2c,0x10,0xbb,0x04,0x2a,0xf0,0x4a,0x88,0x02,0x0c,0x00,0x81 }}, - {16, 0x80f0, 0, {0x00,0x22,0xc0,0x09,0xb8,0x80,0x26,0x00,0xb8,0x80,0x2e,0x21,0x0b,0x90,0x02,0x30 }}, - {16, 0x8100, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x15,0xec,0x00,0xd8,0xc0,0x3e,0xc0 }}, - {16, 0x8110, 0, {0x0b,0x80,0x03,0xec,0x00,0xfb,0x00,0x36,0x80,0x0e,0xb0,0x03,0xac,0x00,0xfb,0x00 }}, - {16, 0x8120, 0, {0x3c,0xe0,0x0c,0x0c,0x03,0x2c,0x00,0xe9,0x00,0x10,0xc0,0x0c,0x8c,0x03,0x06,0x00 }}, - {16, 0x8130, 0, {0xf8,0xcd,0x3e,0x22,0x0f,0x18,0x03,0x40,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8140, 0, {0xe0,0x01,0xbc,0x00,0xff,0x00,0x3e,0xc0,0x0f,0xf0,0x03,0x7c,0x00,0xf7,0x02,0x3f }}, - {16, 0x8150, 0, {0xe4,0x0f,0x70,0x03,0x7c,0x04,0xb7,0x00,0x37,0x40,0x0d,0xc0,0x03,0xfc,0x00,0xfd }}, - {16, 0x8160, 0, {0x00,0x37,0xd0,0x0e,0xc0,0x43,0xf4,0x00,0xdf,0x00,0x3f,0x80,0x8f,0xda,0x03,0xf8 }}, - {16, 0x8170, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xf8,0x10,0x3a,0xc0 }}, - {16, 0x8180, 0, {0x6d,0xa6,0x13,0xec,0x00,0xcb,0x00,0x3a,0xd0,0x0f,0xb0,0x03,0x2c,0x10,0xdb,0x10 }}, - {16, 0x8190, 0, {0x36,0xd8,0x0d,0x84,0x03,0xec,0x06,0xc9,0x08,0x3a,0xc0,0x0e,0x86,0x03,0xa8,0x60 }}, - {16, 0x81a0, 0, {0xf8,0x20,0x3a,0x40,0x0c,0x90,0x03,0x54,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81b0, 0, {0x98,0x05,0x3c,0x00,0xbb,0x40,0x23,0xd0,0x08,0x30,0x02,0x3e,0x10,0xaf,0x00,0x20 }}, - {16, 0x81c0, 0, {0xc0,0x0b,0xf0,0x02,0x3c,0x00,0x8f,0x50,0x2e,0xc8,0x06,0x8a,0x02,0xfc,0x00,0x8d }}, - {16, 0x81d0, 0, {0x24,0x82,0xd6,0x08,0x32,0x02,0x2d,0x08,0x3a,0x40,0x22,0x80,0x0d,0x90,0x03,0x62 }}, - {16, 0x81e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x4c,0x00,0xb0,0x20,0x28,0xc2 }}, - {16, 0x81f0, 0, {0x08,0x04,0x02,0x8c,0x00,0x13,0x02,0x28,0xc0,0x0b,0x30,0x02,0x0c,0x30,0x93,0x80 }}, - {16, 0x8200, 0, {0x24,0xd0,0x09,0x20,0x02,0xcc,0x00,0x91,0x40,0x08,0xc0,0x2a,0x14,0x02,0x81,0x00 }}, - {16, 0x8210, 0, {0x90,0x00,0x68,0x00,0x08,0x18,0x02,0x3a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8220, 0, {0x70,0x01,0x1e,0x00,0xb4,0xa0,0x21,0xe0,0x08,0xc8,0x12,0x9e,0x00,0xb3,0x82,0x21 }}, - {16, 0x8230, 0, {0xe0,0x0b,0x7a,0x0a,0x1e,0x00,0x97,0x80,0x2d,0xe1,0x0a,0x48,0x02,0xce,0x40,0x95 }}, - {16, 0x8240, 0, {0x90,0x29,0xe4,0x08,0x58,0x02,0x9a,0x00,0xb7,0x88,0x21,0xe0,0x09,0x58,0x02,0x5c }}, - {16, 0x8250, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x00,0x0c,0x00,0xf0,0x80,0x38,0xc4 }}, - {16, 0x8260, 0, {0x0c,0x25,0x03,0x8c,0x20,0x93,0x00,0x38,0xc4,0x0f,0xb0,0x03,0x0c,0x80,0xd3,0x00 }}, - {16, 0x8270, 0, {0x34,0xc0,0x0d,0x04,0x13,0xcc,0x08,0x99,0x00,0x2a,0xc0,0x0e,0x21,0x03,0x88,0x04 }}, - {16, 0x8280, 0, {0xf3,0x00,0x38,0xc0,0x0c,0x11,0x83,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8290, 0, {0x42,0x15,0xbc,0x00,0xf4,0x00,0x3f,0xc3,0x0e,0xc0,0x03,0x1c,0x00,0xaf,0x4a,0x7f }}, - {16, 0x82a0, 0, {0xc4,0x0f,0xb2,0x03,0xfd,0x01,0xef,0x10,0x3f,0x84,0x0f,0xc0,0x03,0xfc,0x00,0xe9 }}, - {16, 0x82b0, 0, {0x00,0x37,0xc2,0x0e,0xf1,0x47,0x7c,0x00,0xf7,0x00,0x3d,0xc0,0x0f,0x50,0x03,0xd0 }}, - {16, 0x82c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x15,0xec,0x08,0xf8,0x00,0x3e,0xca }}, - {16, 0x82d0, 0, {0x0f,0x90,0x03,0xef,0x21,0xfb,0x80,0x7a,0x40,0x8f,0xb2,0xa1,0x2f,0x00,0xcb,0x60 }}, - {16, 0x82e0, 0, {0x3e,0xc0,0x0f,0xb0,0x03,0xed,0xa0,0xe9,0x30,0x32,0xc0,0x2d,0xb0,0x03,0xe4,0x00 }}, - {16, 0x82f0, 0, {0xf8,0x00,0x3e,0x00,0x0f,0xb0,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8300, 0, {0xc8,0x91,0x9d,0x00,0xb4,0x01,0x2d,0xc8,0x0b,0x70,0x02,0xcc,0x80,0x8f,0x20,0x21 }}, - {16, 0x8310, 0, {0xc0,0x8b,0x76,0x03,0x5d,0x00,0x87,0x0a,0x2d,0xc0,0x0b,0x40,0x22,0xfd,0x00,0x8d }}, - {16, 0x8320, 0, {0x10,0x23,0xc8,0x08,0x50,0x12,0xd4,0x00,0xb7,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xf2 }}, - {16, 0x8330, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x9e,0x00,0xb4,0x80,0x2d,0xe0 }}, - {16, 0x8340, 0, {0x0b,0x7c,0x02,0xde,0x40,0xa7,0x82,0x2d,0xe0,0x0b,0x3a,0x02,0x8e,0x00,0x87,0x90 }}, - {16, 0x8350, 0, {0x2d,0xe0,0x0b,0x58,0x02,0x5e,0x00,0xa5,0xa2,0x65,0xe0,0x08,0x68,0x82,0xda,0x00 }}, - {16, 0x8360, 0, {0x95,0x80,0x2d,0x60,0x0b,0x78,0x02,0xe0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8370, 0, {0x08,0x84,0xcc,0x00,0xb0,0x09,0x2c,0xc0,0x0b,0x38,0x02,0xcc,0x00,0x83,0x00,0x2e }}, - {16, 0x8380, 0, {0xc0,0x0b,0x30,0x42,0x4c,0x00,0x83,0x00,0x2c,0xa0,0x0b,0x04,0x02,0xcc,0x00,0x81 }}, - {16, 0x8390, 0, {0x00,0xa0,0xc0,0x08,0xb0,0x06,0xcf,0x80,0xb3,0x10,0x2c,0xc4,0x0b,0x31,0x02,0xc3 }}, - {16, 0x83a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xfe,0x80,0x3e,0x80 }}, - {16, 0x83b0, 0, {0x0f,0xe8,0x13,0xe8,0x00,0xea,0x00,0x3f,0xb0,0x0f,0xa0,0x03,0xa8,0x02,0xc2,0x00 }}, - {16, 0x83c0, 0, {0x2f,0x88,0x0f,0xe0,0x03,0xe8,0x00,0xea,0x00,0x36,0x00,0x0c,0xe0,0x03,0xf9,0x20 }}, - {16, 0x83d0, 0, {0xde,0x80,0x3f,0xa0,0x4f,0xa8,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x83e0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x10,0x3c,0x10,0x0f,0x80,0x83,0xe1,0x00,0xe8,0x00,0x22 }}, - {16, 0x83f0, 0, {0x06,0x0f,0x00,0x13,0xe0,0x01,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x83,0xe0,0x00,0xf8 }}, - {16, 0x8400, 0, {0x00,0x3e,0x00,0x0f,0x84,0x23,0xe0,0x00,0xf8,0x00,0x3e,0x10,0x0f,0x80,0x03,0xd2 }}, - {16, 0x8410, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe4,0x00,0xf9,0x10,0x3e,0x44 }}, - {16, 0x8420, 0, {0x0d,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0c,0x90,0x12,0x24,0x00,0xf9,0x10 }}, - {16, 0x8430, 0, {0x32,0x40,0x8f,0x90,0x03,0xc4,0x00,0xc9,0x00,0x32,0x10,0x0c,0x9c,0x01,0x24,0x00 }}, - {16, 0x8440, 0, {0xf9,0x10,0x3e,0x70,0x0f,0x90,0x02,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8450, 0, {0x80,0x14,0x64,0x00,0xb9,0xc0,0x2e,0x48,0x08,0x91,0x02,0xe4,0x00,0xb9,0x00,0x2e }}, - {16, 0x8460, 0, {0x40,0x0d,0x90,0x03,0x67,0x00,0xb9,0x80,0x2a,0x60,0x0b,0x99,0x02,0xe4,0x00,0x81 }}, - {16, 0x8470, 0, {0x00,0x22,0x40,0x2c,0x90,0x12,0x25,0x20,0xb9,0x48,0x2e,0x52,0x0b,0x94,0x02,0xe0 }}, - {16, 0x8480, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x00,0x2e,0x40 }}, - {16, 0x8490, 0, {0x68,0x90,0x46,0xe4,0x00,0xb9,0x00,0x2e,0xc0,0x08,0x90,0x02,0xa4,0x60,0xb9,0x00 }}, - {16, 0x84a0, 0, {0x22,0x48,0x0b,0x90,0x06,0xe4,0x02,0x89,0x00,0xa0,0x40,0x08,0x90,0x02,0xa6,0x10 }}, - {16, 0x84b0, 0, {0xb9,0x00,0x0e,0x40,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x84c0, 0, {0x08,0x04,0x04,0x80,0xb1,0x00,0x2c,0x48,0x08,0x10,0x02,0xc4,0x84,0xb1,0x20,0x2c }}, - {16, 0x84d0, 0, {0x40,0x09,0x12,0x02,0xc4,0x80,0xb1,0x20,0x28,0x40,0x0b,0x10,0x02,0xc4,0x80,0x89 }}, - {16, 0x84e0, 0, {0x20,0x20,0x40,0x4b,0x12,0x0a,0x84,0x84,0xb1,0x20,0x2c,0x48,0x8b,0x10,0x02,0xc2 }}, - {16, 0x84f0, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xba,0x00,0x2e,0x00 }}, - {16, 0x8500, 0, {0x0c,0x80,0x03,0xe8,0x08,0xf8,0x50,0x3e,0x14,0x0c,0x85,0x03,0x20,0x00,0xb8,0x00 }}, - {16, 0x8510, 0, {0x32,0x00,0x0f,0xa0,0x03,0xe1,0x40,0xc8,0x50,0x32,0x14,0x0c,0xa5,0x03,0xa1,0x40 }}, - {16, 0x8520, 0, {0xf8,0x00,0x3e,0x00,0x0f,0xa0,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8530, 0, {0x88,0x0d,0xe4,0x40,0xfd,0x00,0x3e,0x44,0x0f,0xd0,0x03,0xe4,0x40,0xb9,0x11,0x3f }}, - {16, 0x8540, 0, {0x40,0x0f,0x91,0x03,0x64,0x44,0xf9,0x10,0x3f,0x40,0x0f,0xd0,0x03,0xe4,0x40,0xfd }}, - {16, 0x8550, 0, {0x10,0x3f,0x10,0x8c,0xd1,0x03,0x74,0x40,0xff,0x10,0x3f,0x44,0x0f,0xd0,0x03,0xe6 }}, - {16, 0x8560, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x66,0x20,0xed,0x00,0x33,0x69 }}, - {16, 0x8570, 0, {0x4d,0x50,0x43,0x56,0x00,0xf9,0xa0,0x34,0x40,0x0f,0x9a,0x0b,0x34,0x00,0xdd,0x80 }}, - {16, 0x8580, 0, {0x3b,0x40,0x0b,0x50,0x03,0xe4,0x00,0xf9,0x00,0x32,0xe0,0x0e,0xd0,0x03,0xf4,0x00 }}, - {16, 0x8590, 0, {0xfd,0x00,0x3f,0x40,0x0c,0xd0,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x85a0, 0, {0x78,0x10,0xe2,0x80,0x88,0x04,0x22,0x10,0x0b,0x80,0x02,0x20,0x09,0xb8,0xf0,0x22 }}, - {16, 0x85b0, 0, {0x00,0x0b,0x8e,0x12,0xa0,0x00,0xb8,0x52,0x2e,0x00,0x0b,0x80,0x02,0xe0,0x05,0xb8 }}, - {16, 0x85c0, 0, {0xaa,0x23,0x3e,0x0d,0x80,0x02,0xe0,0x00,0xb8,0x00,0x3a,0x00,0x08,0x80,0x02,0xce }}, - {16, 0x85d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x20,0xa9,0x00,0xa4,0x44 }}, - {16, 0x85e0, 0, {0x09,0x90,0x02,0xc5,0x00,0xa1,0x08,0x2c,0x40,0x0b,0x11,0x82,0x04,0x00,0xb1,0x00 }}, - {16, 0x85f0, 0, {0x28,0x40,0x0a,0x10,0x42,0xc4,0x00,0xb5,0x00,0xa1,0x40,0x08,0x10,0x02,0xc4,0x00 }}, - {16, 0x8600, 0, {0xb1,0x01,0x2c,0x40,0x08,0x10,0x20,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8610, 0, {0x18,0x15,0xa4,0x00,0x89,0x04,0x22,0x40,0x0b,0x90,0x00,0xac,0x00,0x39,0x00,0x2a }}, - {16, 0x8620, 0, {0x40,0x0b,0x10,0x02,0xa4,0x00,0xb9,0x00,0x2e,0x48,0x0b,0x90,0x12,0xe4,0x00,0xb9 }}, - {16, 0x8630, 0, {0x00,0x21,0x60,0x09,0x92,0x22,0xe4,0x28,0xb9,0x00,0x0a,0x50,0x08,0x90,0x06,0xc6 }}, - {16, 0x8640, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xe9,0x00,0x36,0x40 }}, - {16, 0x8650, 0, {0x0d,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x48,0x0f,0x90,0x03,0x24,0x00,0xd9,0x00 }}, - {16, 0x8660, 0, {0x3a,0x78,0x0e,0x98,0x03,0xe4,0x00,0xb9,0x00,0xb2,0x40,0x0e,0x92,0x23,0xe6,0x00 }}, - {16, 0x8670, 0, {0xb9,0x50,0x3e,0x70,0x2c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8680, 0, {0x68,0x01,0x84,0x00,0xf9,0x00,0x3e,0x40,0x4f,0x9c,0x23,0x64,0x00,0xf9,0x04,0x36 }}, - {16, 0x8690, 0, {0x48,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x60,0x0f,0x92,0x03,0xe4,0x00,0xf9 }}, - {16, 0x86a0, 0, {0x00,0x3e,0x40,0x8f,0x90,0x83,0xe4,0x44,0xf9,0x00,0x78,0x64,0x0f,0x90,0x03,0xda }}, - {16, 0x86b0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x00,0x3e,0x00 }}, - {16, 0x86c0, 0, {0x0f,0x82,0x03,0xa0,0x40,0xe8,0x00,0x3e,0x00,0x0d,0x80,0x03,0x20,0xc0,0xc8,0x80 }}, - {16, 0x86d0, 0, {0x3e,0x12,0x0f,0x80,0x03,0x60,0x00,0x7c,0x00,0x33,0x00,0x0d,0x80,0x13,0xe0,0x10 }}, - {16, 0x86e0, 0, {0xc8,0x64,0x3e,0x08,0x0c,0x82,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x86f0, 0, {0x28,0x05,0x28,0x00,0xb6,0xe0,0x0f,0xa0,0x0b,0x60,0x82,0x38,0x00,0xaa,0x00,0x2e }}, - {16, 0x8700, 0, {0x80,0x08,0xa0,0x42,0xba,0x00,0xae,0x20,0x2f,0x88,0x0b,0xe5,0x02,0x28,0x00,0xba }}, - {16, 0x8710, 0, {0xd8,0x37,0x80,0x08,0xec,0x02,0xf8,0x04,0x8e,0x00,0x2f,0x90,0x0d,0xe0,0x02,0xca }}, - {16, 0x8720, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb0,0x24,0x2c,0x60 }}, - {16, 0x8730, 0, {0x0b,0x38,0x02,0x8e,0x80,0xab,0x00,0x2c,0xc0,0x09,0x30,0x02,0x0d,0x08,0x00,0x80 }}, - {16, 0x8740, 0, {0x6c,0xd0,0x0b,0x34,0x02,0xcc,0x00,0xb8,0xc0,0x20,0x00,0x48,0x34,0x12,0xcc,0x40 }}, - {16, 0x8750, 0, {0x83,0x00,0x2c,0xe0,0x0a,0x35,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8760, 0, {0xa0,0x01,0x1c,0x40,0xb7,0x00,0x2d,0x02,0x8b,0x60,0x02,0x9e,0x00,0x87,0x20,0x2f }}, - {16, 0x8770, 0, {0xe0,0x08,0x72,0x02,0x9e,0x00,0xa4,0x00,0x2d,0xc0,0x0b,0xf8,0x02,0x9c,0xc0,0xb3 }}, - {16, 0x8780, 0, {0x02,0xa5,0xc0,0x08,0x50,0x86,0xfe,0x00,0x87,0x00,0x2f,0xd0,0x09,0x70,0x02,0xe8 }}, - {16, 0x8790, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xf4,0x80,0x3d,0x20 }}, - {16, 0x87a0, 0, {0x0f,0x58,0x03,0x9e,0x00,0x67,0x80,0x3d,0xf8,0x0d,0x38,0x02,0x1a,0x10,0x44,0x80 }}, - {16, 0x87b0, 0, {0x3d,0xe0,0x0f,0x58,0x03,0xde,0x20,0xb4,0x80,0x33,0xa0,0x2c,0x68,0x03,0xd6,0x00 }}, - {16, 0x87c0, 0, {0xc7,0x81,0x3d,0xe0,0x0c,0x78,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x87d0, 0, {0x08,0x1d,0xac,0x08,0xf8,0x00,0x3e,0x00,0x8f,0x80,0x03,0x6c,0x00,0x3b,0x12,0x3e }}, - {16, 0x87e0, 0, {0xca,0x0f,0xb5,0x03,0xc8,0x00,0xf8,0x04,0x7e,0xc0,0x0f,0x90,0x03,0x6c,0x80,0xfb }}, - {16, 0x87f0, 0, {0x04,0x3a,0x40,0x0f,0x90,0x23,0xc8,0x00,0xf9,0x01,0x3c,0xc0,0x0f,0xb0,0x03,0xc2 }}, - {16, 0x8800, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xac,0x90,0x31,0x48 }}, - {16, 0x8810, 0, {0x08,0xf8,0x03,0xfa,0x00,0xcf,0x80,0x3f,0xe0,0x0c,0xfc,0x13,0x3e,0x04,0xfc,0x80 }}, - {16, 0x8820, 0, {0x35,0xa0,0x0c,0x78,0x03,0xbe,0x00,0xdf,0x80,0x3b,0x20,0x24,0xf8,0x03,0x2e,0x40 }}, - {16, 0x8830, 0, {0xcf,0x80,0x33,0xe0,0x03,0xf9,0x03,0xd0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8840, 0, {0xa8,0x11,0xbc,0x00,0x80,0x00,0x01,0x00,0x08,0x72,0x02,0xd0,0x00,0x87,0x00,0x2d }}, - {16, 0x8850, 0, {0xc8,0x0a,0xf0,0x02,0x98,0x40,0xf5,0x00,0x61,0x41,0x00,0x74,0x02,0x1c,0x00,0xb4 }}, - {16, 0x8860, 0, {0x00,0x21,0xc8,0x08,0x60,0x02,0x3e,0x20,0x86,0x08,0x21,0xd8,0x0f,0x50,0x02,0xea }}, - {16, 0x8870, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x9c,0x00,0xa4,0x00,0x21,0x00 }}, - {16, 0x8880, 0, {0x08,0x50,0x02,0xd8,0x00,0x97,0x00,0x2d,0xc0,0x88,0x71,0x02,0x14,0x00,0xb0,0x00 }}, - {16, 0x8890, 0, {0x25,0x90,0x08,0xc0,0x82,0x9c,0x40,0x93,0x00,0x29,0xa1,0x88,0x60,0x02,0x14,0x12 }}, - {16, 0x88a0, 0, {0x87,0x40,0x29,0x40,0x0b,0x60,0x02,0xc4,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x88b0, 0, {0x60,0x14,0xcc,0x00,0x80,0xd0,0xa0,0x00,0x08,0x1c,0x02,0xc0,0x00,0x93,0x00,0x2c }}, - {16, 0x88c0, 0, {0xd0,0x0a,0xb0,0x26,0x80,0x00,0xb3,0x00,0x24,0xe4,0x08,0x08,0x02,0x8c,0x00,0xb0 }}, - {16, 0x88d0, 0, {0x02,0x02,0x41,0x08,0x08,0x02,0x03,0x01,0x81,0x00,0x28,0x42,0x1a,0x00,0x42,0xd8 }}, - {16, 0x88e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x15,0xbc,0x00,0xe8,0xc0,0x32,0x80 }}, - {16, 0x88f0, 0, {0x0c,0xb5,0x03,0xe4,0x00,0x9f,0x00,0x3d,0xe0,0x0c,0xf0,0x0b,0x24,0x00,0xf8,0x00 }}, - {16, 0x8900, 0, {0x36,0xe0,0x0c,0x25,0x03,0xbc,0x05,0xd8,0x02,0x2a,0x00,0x08,0xba,0x02,0x2a,0x00 }}, - {16, 0x8910, 0, {0xc1,0x02,0x3a,0x50,0x8b,0x90,0x03,0xee,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8920, 0, {0x80,0x00,0xec,0x00,0xfb,0x08,0x3e,0x80,0x0f,0xa1,0x03,0xec,0x04,0xeb,0x02,0x2e }}, - {16, 0x8930, 0, {0xc6,0x0f,0xb0,0x17,0x44,0x00,0xe8,0x00,0x3a,0x40,0x0f,0x80,0x02,0x6c,0x00,0xfb }}, - {16, 0x8940, 0, {0x00,0x3e,0xe0,0x0f,0x90,0x93,0xe1,0x00,0xd9,0x00,0x26,0x70,0x8f,0x90,0x01,0xe1 }}, - {16, 0x8950, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xfc,0x00,0xfc,0x03,0x37,0x24 }}, - {16, 0x8960, 0, {0x0d,0xf8,0x03,0xe0,0x00,0xff,0x00,0x3f,0xc1,0x8d,0xf0,0x0b,0x38,0x00,0xcc,0x00 }}, - {16, 0x8970, 0, {0x3f,0xc0,0x0f,0xfa,0x03,0x3c,0x0c,0xfc,0x04,0x3b,0x80,0x0c,0xa0,0x03,0x94,0x20 }}, - {16, 0x8980, 0, {0x89,0x05,0x3b,0x00,0x4f,0xd0,0x23,0xc0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8990, 0, {0x80,0x04,0x6c,0x00,0xb0,0x06,0x20,0x13,0x88,0xa8,0x02,0xeb,0x00,0xbb,0x00,0x2e }}, - {16, 0x89a0, 0, {0xc0,0x08,0xb0,0x02,0x2a,0x00,0xa8,0x80,0x2e,0xe0,0x0b,0x94,0x1a,0x2c,0x00,0xbb }}, - {16, 0x89b0, 0, {0x00,0xa2,0x40,0x29,0x98,0x02,0xe2,0x00,0xa9,0x84,0x22,0x20,0x0b,0x98,0x02,0xe0 }}, - {16, 0x89c0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xb8,0x00,0x22,0x00 }}, - {16, 0x89d0, 0, {0x09,0x82,0x02,0xe6,0x00,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0x26,0x00,0x88,0x80 }}, - {16, 0x89e0, 0, {0x2e,0xa0,0x0b,0xa0,0x02,0x2c,0x00,0xb3,0x00,0x2a,0x00,0x09,0x98,0x02,0xea,0x20 }}, - {16, 0x89f0, 0, {0xa9,0x80,0x2a,0x60,0x9b,0x98,0x82,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8a00, 0, {0x08,0x04,0x0c,0x00,0xb8,0x00,0x20,0x00,0x09,0x08,0x02,0xc4,0x00,0xb3,0x00,0x26 }}, - {16, 0x8a10, 0, {0xc0,0x00,0x30,0x02,0x00,0x00,0x81,0x00,0x2c,0x41,0x0b,0x00,0x02,0x0c,0x00,0xb0 }}, - {16, 0x8a20, 0, {0x00,0x20,0xc0,0x0b,0x00,0x02,0xc8,0x80,0xa8,0x00,0x20,0x41,0x0b,0x10,0x02,0xc2 }}, - {16, 0x8a30, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x10,0xf8,0x50,0xb2,0x00 }}, - {16, 0x8a40, 0, {0x0d,0x80,0x03,0xe0,0x00,0xfb,0x00,0x3d,0xc0,0x0d,0xf0,0x13,0x24,0x02,0xc8,0x06 }}, - {16, 0x8a50, 0, {0x3e,0x80,0x0f,0xa0,0x03,0x3c,0x04,0xfb,0x00,0x78,0x80,0x0c,0xa0,0x03,0xe4,0x00 }}, - {16, 0x8a60, 0, {0xe9,0x00,0x1a,0x40,0x0f,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8a70, 0, {0xa0,0x1d,0xfc,0x00,0xf4,0x20,0x3f,0x00,0x0e,0xc0,0x02,0xf0,0x01,0xff,0x00,0x3f }}, - {16, 0x8a80, 0, {0xc0,0x0f,0xf0,0x23,0xf0,0x00,0xfd,0x00,0x3f,0xc0,0x0f,0xc0,0x03,0xfc,0x00,0xfc }}, - {16, 0x8a90, 0, {0x00,0x3f,0x40,0x9c,0xc0,0x03,0xf0,0x40,0xfd,0x00,0x3f,0x40,0x0f,0xd0,0x43,0xe8 }}, - {16, 0x8aa0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf0,0x00,0xed,0x23,0xb7,0x48 }}, - {16, 0x8ab0, 0, {0x0c,0xe1,0xc3,0x7c,0xc0,0xdd,0x80,0x37,0xe0,0x0f,0xcb,0x03,0xfe,0x08,0xfc,0x28 }}, - {16, 0x8ac0, 0, {0x3f,0xf0,0x1c,0xfb,0x23,0x7c,0x01,0xff,0x14,0x77,0xe2,0x4f,0xe8,0x23,0x7c,0x00 }}, - {16, 0x8ad0, 0, {0xc4,0x80,0x33,0x48,0x2c,0xf8,0x22,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ae0, 0, {0x80,0x10,0xe0,0xe0,0xc9,0xc0,0x22,0x5b,0x88,0x96,0x22,0x2d,0x00,0x89,0x22,0x22 }}, - {16, 0x8af0, 0, {0xca,0x0b,0x9e,0x22,0xe2,0xa0,0xb9,0x61,0x2c,0xe0,0x88,0x9f,0x02,0x3d,0x85,0xbf }}, - {16, 0x8b00, 0, {0x60,0x26,0x50,0x48,0xa0,0x02,0x3c,0x00,0x88,0x00,0x22,0x50,0x08,0xb0,0x02,0x20 }}, - {16, 0x8b10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc0,0x80,0xb1,0x10,0x20,0x44 }}, - {16, 0x8b20, 0, {0x0b,0xb2,0x02,0xce,0xd0,0x81,0x08,0x2c,0xc0,0x0b,0x01,0x02,0x8c,0x08,0xb3,0x08 }}, - {16, 0x8b30, 0, {0x2c,0xc9,0x08,0x10,0x62,0x8c,0x60,0xb3,0x32,0x24,0x80,0x0a,0xa0,0x02,0x6c,0x03 }}, - {16, 0x8b40, 0, {0x9a,0x01,0x26,0x44,0x48,0xb0,0x42,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8b50, 0, {0xc0,0x15,0xa4,0xa0,0x8b,0x02,0x22,0xe0,0x0b,0xb0,0x62,0xac,0x98,0x99,0x00,0x2a }}, - {16, 0x8b60, 0, {0xc2,0x0b,0x98,0x06,0xe4,0x00,0xbb,0x02,0x2e,0xc0,0x08,0x91,0x42,0x2c,0x10,0xbb }}, - {16, 0x8b70, 0, {0x00,0x6e,0x80,0x0a,0x80,0x02,0x6c,0x00,0x1b,0x00,0x06,0x40,0x48,0xb8,0x0a,0x70 }}, - {16, 0x8b80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xe7,0x00,0xa1,0x00,0x76,0x78 }}, - {16, 0x8b90, 0, {0x0f,0xb0,0x03,0xe8,0x10,0xd9,0x00,0x3e,0xd0,0x4b,0x9e,0x13,0xac,0x08,0xb8,0xa0 }}, - {16, 0x8ba0, 0, {0x7e,0xc6,0x08,0xa8,0x02,0x2c,0x01,0xbb,0x00,0x26,0x30,0x4e,0x20,0x03,0x4c,0x18 }}, - {16, 0x8bb0, 0, {0x99,0x80,0xb4,0x40,0x4c,0x3a,0x03,0x40,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8bc0, 0, {0xe0,0x01,0xb2,0x00,0xfd,0xc5,0x3b,0xc0,0x4c,0xd0,0x03,0x6a,0x02,0xed,0x06,0x33 }}, - {16, 0x8bd0, 0, {0xc4,0x0f,0xd0,0x53,0xf8,0x00,0xfc,0x90,0x7f,0xc1,0x0f,0x78,0x03,0xbc,0x04,0xff }}, - {16, 0x8be0, 0, {0x00,0x37,0x64,0x0c,0xf1,0x03,0xa4,0x00,0xed,0xa1,0x3b,0x40,0x0b,0xf0,0x83,0xb8 }}, - {16, 0x8bf0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8c,0x00,0xcb,0x20,0x3e,0x71 }}, - {16, 0x8c00, 0, {0x0f,0xb3,0x03,0x98,0x02,0xfb,0x02,0x36,0x48,0x0f,0x90,0x03,0xec,0x20,0xf8,0x00 }}, - {16, 0x8c10, 0, {0x3e,0xcc,0x04,0x84,0x03,0x2c,0x00,0xdb,0x04,0x3c,0x10,0x0f,0xa0,0x03,0xec,0x00 }}, - {16, 0x8c20, 0, {0x9b,0x00,0x32,0x40,0x0c,0x90,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8c30, 0, {0x88,0x05,0x2c,0x02,0x8b,0x48,0x2e,0xe0,0x0b,0x34,0x03,0x6b,0x00,0x8b,0xf5,0x22 }}, - {16, 0x8c40, 0, {0xf2,0x0b,0x9c,0x03,0xaf,0x00,0xb8,0x50,0x2e,0xc0,0x08,0xb0,0x02,0x7c,0x00,0x8f }}, - {16, 0x8c50, 0, {0x00,0x0e,0x5d,0x0b,0x80,0x02,0xf5,0x40,0x83,0x50,0x23,0x54,0x08,0x9c,0x02,0xe6 }}, - {16, 0x8c60, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x04,0x4c,0x00,0x81,0x81,0x2e,0x40 }}, - {16, 0x8c70, 0, {0x03,0x2c,0x02,0x04,0x33,0x99,0x00,0x20,0xf0,0x4a,0x28,0x80,0xcc,0x40,0xb0,0x00 }}, - {16, 0x8c80, 0, {0x26,0x10,0x08,0x20,0x02,0x4c,0x00,0x83,0x00,0x2c,0xc0,0x09,0x20,0x02,0xcc,0x00 }}, - {16, 0x8c90, 0, {0xa0,0x02,0x28,0x40,0x08,0x08,0x02,0x7a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ca0, 0, {0x20,0x01,0x0a,0x00,0x85,0x80,0x2d,0xf8,0x0b,0xda,0x02,0xd6,0x40,0x85,0xa0,0x21 }}, - {16, 0x8cb0, 0, {0xe0,0x0b,0x48,0x06,0x92,0x04,0xb5,0x80,0x2d,0x21,0x08,0x00,0x02,0x4e,0x00,0x87 }}, - {16, 0x8cc0, 0, {0xa4,0x2d,0x60,0x0b,0x68,0x02,0xde,0xc2,0xad,0x90,0x2b,0x60,0x28,0x58,0x82,0xdc }}, - {16, 0x8cd0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x4c,0x40,0xc3,0x10,0x2c,0x6c }}, - {16, 0x8ce0, 0, {0x0f,0x30,0x03,0x86,0xa2,0xf9,0xb0,0xb0,0xe0,0x0f,0x29,0x83,0xce,0x44,0xf3,0x80 }}, - {16, 0x8cf0, 0, {0x3c,0xac,0x0c,0x30,0x03,0x0c,0x00,0xc3,0x00,0x3c,0xd5,0x0f,0x20,0x03,0xce,0xc1 }}, - {16, 0x8d00, 0, {0xe0,0x10,0xb8,0x40,0x0c,0x00,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8d10, 0, {0xc0,0x1d,0xbc,0x00,0xeb,0x00,0x3e,0xcc,0x0f,0x32,0x03,0x64,0x08,0xf9,0x00,0x3b }}, - {16, 0x8d20, 0, {0x90,0x0f,0xf0,0x43,0xe4,0x40,0xfb,0x34,0x3f,0x81,0x07,0xd1,0x03,0xad,0x20,0xeb }}, - {16, 0x8d30, 0, {0x20,0x7f,0xc4,0x0f,0xe1,0x03,0xfc,0x50,0xcd,0x10,0x35,0x40,0x0f,0xd0,0x03,0xd0 }}, - {16, 0x8d40, 0, {0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x04,0xfd,0x04,0x3d,0x40 }}, - {16, 0x8d50, 0, {0x2d,0x30,0x02,0x3c,0x00,0xc9,0x01,0x3e,0xc0,0x4f,0xb8,0x43,0xec,0x10,0xfb,0x00 }}, - {16, 0x8d60, 0, {0x32,0x40,0x0f,0xa0,0x23,0xec,0x80,0xcb,0x36,0x32,0x80,0x4d,0xa8,0x03,0x2c,0x10 }}, - {16, 0x8d70, 0, {0xcb,0x00,0x32,0x40,0x0c,0x90,0x03,0x6a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8d80, 0, {0xc8,0x11,0x90,0x08,0xb5,0x00,0x2d,0xc0,0x08,0x50,0x02,0xbc,0x02,0x85,0x04,0x2d }}, - {16, 0x8d90, 0, {0xc0,0x8e,0x60,0x06,0xd8,0x04,0xb7,0x04,0x21,0x40,0x0b,0x70,0x02,0xfc,0x80,0xaf }}, - {16, 0x8da0, 0, {0x28,0x21,0xc0,0x0b,0x70,0x02,0x06,0x40,0x87,0x00,0x21,0x50,0x08,0x50,0x02,0x32 }}, - {16, 0x8db0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x20,0xb7,0x80,0x2b,0x70 }}, - {16, 0x8dc0, 0, {0x08,0xf8,0x06,0x1e,0x00,0x87,0x80,0x2d,0xe0,0x0b,0x70,0x32,0xde,0x04,0x37,0x84 }}, - {16, 0x8dd0, 0, {0x25,0xe0,0x0b,0x68,0x06,0xde,0x80,0x87,0x80,0x21,0xa1,0x1b,0x68,0x02,0x1e,0x40 }}, - {16, 0x8de0, 0, {0x9f,0x80,0x20,0x60,0x08,0x58,0x02,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8df0, 0, {0x48,0x14,0xcc,0x20,0xb3,0x00,0x2c,0x80,0x88,0xb4,0x22,0x8d,0x00,0x83,0x90,0x2c }}, - {16, 0x8e00, 0, {0xc0,0x0a,0x38,0x02,0xce,0x08,0xbb,0x20,0x24,0xd0,0x0b,0xb3,0x02,0xcc,0x00,0xa3 }}, - {16, 0x8e10, 0, {0x00,0x60,0xd2,0x0b,0x20,0x2a,0x04,0x08,0x93,0x50,0x20,0x40,0x08,0x17,0x0a,0x02 }}, - {16, 0x8e20, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xba,0x00,0xba,0xa0,0x3f,0x84 }}, - {16, 0x8e30, 0, {0x1c,0xe0,0x0b,0x38,0x40,0x8e,0x06,0x2e,0x80,0x0b,0xe3,0x03,0xf8,0x80,0xfe,0xe4 }}, - {16, 0x8e40, 0, {0xb7,0x90,0x0f,0xec,0x02,0xe8,0x00,0x8a,0x00,0xa3,0xa0,0x09,0xe4,0x03,0x2a,0x02 }}, - {16, 0x8e50, 0, {0xde,0xc0,0xf3,0x80,0x0c,0x6c,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8e60, 0, {0x48,0x01,0xe0,0x00,0xf8,0x40,0x3e,0x00,0x0f,0x84,0x13,0xe0,0x00,0xf8,0x00,0x2e }}, - {16, 0x8e70, 0, {0x30,0x0a,0x84,0x03,0xe0,0x04,0xf8,0x00,0x3a,0x02,0x0f,0x80,0x13,0xe0,0x00,0xf8 }}, - {16, 0x8e80, 0, {0x00,0x3e,0x04,0x0d,0x80,0x83,0xe0,0x40,0xe8,0x20,0x3e,0x00,0x2f,0x80,0x03,0xd2 }}, - {16, 0x8e90, 0, {0x10,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xf9,0x00,0x3c,0x64 }}, - {16, 0x8ea0, 0, {0x4e,0x90,0x83,0x24,0x80,0xc9,0x00,0x32,0xe0,0x0f,0x10,0x03,0x25,0x00,0xf9,0x00 }}, - {16, 0x8eb0, 0, {0x32,0x44,0x0f,0x92,0x23,0x64,0x00,0xc1,0x00,0x32,0x40,0x0c,0x90,0x13,0xe4,0x00 }}, - {16, 0x8ec0, 0, {0xc9,0x00,0x22,0x40,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ed0, 0, {0x80,0x04,0x64,0x00,0xb9,0x20,0x2e,0x40,0x48,0x96,0x22,0x25,0x00,0xd9,0xc0,0xa2 }}, - {16, 0x8ee0, 0, {0x70,0x0b,0x98,0x02,0x24,0x00,0xb9,0x40,0xa2,0x70,0x4b,0x90,0x02,0x24,0x00,0xd9 }}, - {16, 0x8ef0, 0, {0x00,0xa2,0x40,0x2c,0x94,0x22,0xe4,0x02,0x89,0x00,0xa2,0x40,0x28,0x94,0x13,0x20 }}, - {16, 0x8f00, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0xb9,0x00,0x2e,0x40 }}, - {16, 0x8f10, 0, {0x0a,0x90,0x02,0x04,0x00,0x81,0x80,0xa2,0x44,0x0b,0x91,0x02,0x25,0x00,0x19,0x40 }}, - {16, 0x8f20, 0, {0x62,0x40,0x0b,0xb4,0x02,0x44,0x00,0x89,0x00,0x20,0x40,0x08,0x90,0x82,0xc4,0x01 }}, - {16, 0x8f30, 0, {0x83,0x02,0x28,0x40,0x48,0x90,0x82,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8f40, 0, {0x00,0x04,0x05,0x80,0xb1,0x00,0x6c,0x51,0x08,0x14,0x1a,0x05,0x00,0x93,0x00,0x20 }}, - {16, 0x8f50, 0, {0x40,0x8b,0x14,0x02,0x05,0x00,0xb1,0x20,0x20,0x50,0x0b,0x14,0x06,0x04,0x80,0x91 }}, - {16, 0x8f60, 0, {0x20,0x20,0x40,0x09,0x10,0x02,0xc4,0xa8,0x81,0x00,0x28,0x4a,0x08,0x90,0x4a,0x42 }}, - {16, 0x8f70, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x00,0x3e,0x00 }}, - {16, 0x8f80, 0, {0x0e,0x80,0x03,0x28,0x01,0xc8,0x50,0x32,0x94,0x8b,0xa0,0x03,0x20,0x00,0xb0,0x50 }}, - {16, 0x8f90, 0, {0x32,0x80,0x0f,0x80,0x07,0x61,0x51,0xc8,0x50,0x22,0x00,0x0c,0x00,0x03,0xe0,0x84 }}, - {16, 0x8fa0, 0, {0xc8,0x04,0x3a,0x08,0x0c,0x00,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8fb0, 0, {0x98,0x9d,0xf4,0x40,0xbd,0x41,0x3f,0x50,0x0f,0xf4,0x03,0xf5,0x10,0xfd,0x00,0x3e }}, - {16, 0x8fc0, 0, {0x40,0x0f,0xd4,0x03,0xf4,0x00,0xff,0x10,0x2f,0x40,0x4f,0xd4,0x40,0xa4,0x48,0xf9 }}, - {16, 0x8fd0, 0, {0x12,0x3f,0x5a,0x8e,0xd2,0x83,0xf4,0xa8,0xf5,0x2c,0x37,0x4a,0x0f,0xd2,0x83,0xa6 }}, - {16, 0x8fe0, 0, {0x12,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x80,0xfd,0x28,0x3f,0x4c }}, - {16, 0x8ff0, 0, {0x0f,0x50,0x03,0x3c,0x44,0xcd,0x40,0x3f,0xd0,0x0d,0xd0,0x02,0x14,0x01,0xfd,0xa0 }}, - {16, 0x9000, 0, {0x31,0x40,0x03,0xd0,0x03,0xe7,0x89,0xf9,0x90,0x7e,0x50,0x0c,0x94,0x03,0xe6,0xc0 }}, - {16, 0x9010, 0, {0xc9,0x10,0x32,0x6d,0x0f,0x91,0x02,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9020, 0, {0x38,0x10,0xe0,0x80,0xb8,0x01,0x2e,0x0c,0x8b,0x84,0x82,0x20,0x42,0x88,0xa0,0x6e }}, - {16, 0x9030, 0, {0x20,0x08,0x80,0x03,0x60,0x00,0x98,0xe8,0x22,0x00,0x09,0x80,0x02,0xe3,0xc0,0xe8 }}, - {16, 0x9040, 0, {0xd0,0x2e,0x28,0x08,0x8a,0x23,0xe2,0x84,0xd8,0xa0,0x22,0x3d,0x0b,0xc8,0x02,0xce }}, - {16, 0x9050, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc5,0xb0,0xb1,0x00,0x2c,0x48 }}, - {16, 0x9060, 0, {0x0b,0x13,0x02,0x04,0x02,0xb1,0x20,0x2e,0x40,0x88,0x10,0x22,0xc4,0x00,0xb1,0x14 }}, - {16, 0x9070, 0, {0x24,0x40,0x0b,0x10,0x52,0xc4,0x00,0xb1,0x21,0x2d,0x48,0x0a,0x52,0x02,0xd5,0x00 }}, - {16, 0x9080, 0, {0xbd,0x00,0xad,0x40,0x0b,0x52,0x02,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9090, 0, {0x18,0x55,0xa5,0x00,0xb9,0x82,0x2e,0x49,0x8b,0xb0,0x12,0x24,0x10,0x99,0x02,0x2e }}, - {16, 0x90a0, 0, {0x40,0x08,0xb2,0x00,0x65,0x00,0x99,0x80,0x26,0x44,0x09,0x91,0x02,0xe4,0x09,0xa9 }}, - {16, 0x90b0, 0, {0x04,0x2e,0x46,0x0a,0xd4,0x02,0xb4,0x00,0xbd,0x40,0x2f,0x40,0x0b,0xd0,0x02,0xc6 }}, - {16, 0x90c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x40,0xf9,0x80,0x2e,0x62 }}, - {16, 0x90d0, 0, {0x0f,0x9c,0x42,0x24,0x00,0x99,0x01,0x2e,0x68,0x2c,0x92,0x02,0x64,0x00,0xb9,0x40 }}, - {16, 0x90e0, 0, {0xb6,0x60,0x0f,0x9a,0x03,0xe4,0x00,0xb9,0x00,0x2e,0x70,0x3e,0x99,0x06,0xe4,0x02 }}, - {16, 0x90f0, 0, {0xf9,0x00,0x3e,0x40,0x0f,0x98,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9100, 0, {0x68,0x01,0xa6,0x00,0xf9,0x00,0x3e,0x40,0x1f,0x12,0xab,0xe4,0x00,0xe9,0x90,0x3e }}, - {16, 0x9110, 0, {0x49,0x0e,0x98,0x03,0xe4,0x00,0xf1,0x00,0x3a,0x40,0x0d,0x98,0x03,0xe4,0x00,0xf9 }}, - {16, 0x9120, 0, {0x01,0x3e,0x60,0x05,0x90,0x13,0xe4,0x00,0x59,0x20,0x32,0x40,0x8f,0x91,0x03,0xda }}, - {16, 0x9130, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0xa0,0x00,0xc8,0x08,0x3e,0x01 }}, - {16, 0x9140, 0, {0x0f,0x84,0x63,0x00,0x22,0xe8,0x20,0x3e,0x13,0x0f,0x84,0x03,0xe1,0xc0,0xd8,0x4c }}, - {16, 0x9150, 0, {0x32,0x00,0x0c,0x84,0x43,0xe0,0x00,0xf8,0x00,0x22,0x10,0x0f,0x84,0x03,0x00,0x00 }}, - {16, 0x9160, 0, {0xc8,0x00,0xb2,0x00,0x0c,0xc0,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9170, 0, {0x28,0x05,0x28,0x00,0x8e,0x00,0x2f,0x86,0x4b,0xe0,0x02,0x39,0x08,0x8e,0x20,0x2d }}, - {16, 0x9180, 0, {0x90,0x0b,0xed,0x92,0xf8,0x02,0x8e,0xe0,0xa3,0x98,0x08,0xe0,0x02,0xe8,0x08,0xba }}, - {16, 0x9190, 0, {0x00,0x62,0x80,0x08,0xa0,0x02,0x28,0x00,0x02,0x80,0x02,0x80,0x48,0xe0,0x03,0x4a }}, - {16, 0x91a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x05,0x4c,0x00,0x83,0x10,0x2c,0xf0 }}, - {16, 0x91b0, 0, {0x0a,0x14,0x2a,0x0d,0x1a,0xb3,0x01,0x24,0xd0,0x0b,0xbc,0x32,0xcc,0x08,0x03,0x00 }}, - {16, 0x91c0, 0, {0x20,0xc8,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x02,0x22,0xc0,0x09,0x30,0x02,0x0c,0x11 }}, - {16, 0x91d0, 0, {0x83,0x00,0x20,0xc0,0x28,0x20,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x91e0, 0, {0x20,0x01,0x1e,0x01,0x85,0x00,0x2d,0x00,0x0b,0x70,0x02,0x18,0x32,0x86,0x00,0x2d }}, - {16, 0x91f0, 0, {0xc0,0x0b,0x60,0x16,0xfe,0x04,0x86,0x00,0x27,0xa0,0x8b,0x70,0x42,0xdc,0x80,0xb7 }}, - {16, 0x9200, 0, {0x80,0x21,0x01,0x08,0xf8,0x0a,0x18,0x00,0x86,0x08,0x20,0xa0,0x08,0xe8,0x0a,0x68 }}, - {16, 0x9210, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x3e,0x02,0xc6,0x80,0x3d,0xe0 }}, - {16, 0x9220, 0, {0x0f,0x48,0x03,0x06,0x04,0xf5,0x82,0x35,0xe0,0x0f,0x78,0x03,0xda,0x00,0xd3,0x80 }}, - {16, 0x9230, 0, {0x31,0x60,0x07,0x78,0x03,0xde,0x20,0xf3,0xb0,0x81,0xe0,0x4f,0x68,0x07,0x0e,0x02 }}, - {16, 0x9240, 0, {0xcf,0x80,0x31,0xe0,0x0c,0x78,0x13,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9250, 0, {0x08,0x1d,0xad,0xa0,0xf9,0x00,0x3f,0x00,0x0f,0xb0,0x53,0xf8,0x10,0xa9,0x00,0x3e }}, - {16, 0x9260, 0, {0x00,0x0f,0x80,0x01,0xec,0x00,0xfb,0x02,0x3a,0xc0,0x0c,0xb0,0x03,0xec,0x00,0xfb }}, - {16, 0x9270, 0, {0x74,0x3c,0x00,0x0f,0x20,0x03,0xe8,0x00,0xfa,0x00,0x3e,0x80,0x0f,0x30,0x03,0xc2 }}, - {16, 0x9280, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x02,0x8f,0x80,0x35,0xe0 }}, - {16, 0x9290, 0, {0x8d,0xd9,0x03,0x2e,0xc4,0xf6,0x80,0x32,0xa4,0x0c,0xb8,0x03,0xde,0x00,0xcf,0x90 }}, - {16, 0x92a0, 0, {0x3c,0xe4,0x0c,0xb8,0x03,0xfe,0x65,0xff,0x80,0x0f,0xec,0x8f,0xf8,0x03,0xfe,0x00 }}, - {16, 0x92b0, 0, {0xc5,0x80,0x33,0xe0,0x0f,0x68,0x03,0x10,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x92c0, 0, {0xaa,0x11,0x9c,0x80,0x84,0xb0,0x20,0x20,0x29,0x73,0x0a,0x0e,0x82,0xa2,0xa0,0xa2 }}, - {16, 0x92d0, 0, {0xa0,0x4f,0x3b,0x03,0x87,0x84,0xb2,0x80,0x2c,0xa0,0x0a,0x7d,0x02,0xde,0x80,0xf7 }}, - {16, 0x92e0, 0, {0x20,0x25,0x06,0x08,0x70,0x02,0xc8,0x40,0x84,0x00,0x35,0x80,0x0b,0x60,0x03,0x6a }}, - {16, 0x92f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x10,0x86,0x38,0x27,0xc0 }}, - {16, 0x9300, 0, {0x49,0x54,0x06,0x54,0x40,0x1d,0x20,0x21,0xca,0x09,0x61,0x40,0xf8,0x80,0xb7,0x20 }}, - {16, 0x9310, 0, {0x2f,0x00,0x89,0x70,0x12,0xdc,0x81,0xb7,0x04,0x2d,0xc9,0x0a,0x60,0x02,0xcc,0x00 }}, - {16, 0x9320, 0, {0x8d,0x00,0x2d,0xc0,0x0b,0xf8,0x02,0x04,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9330, 0, {0x60,0x14,0xcd,0x28,0x80,0x00,0x24,0x00,0x09,0xb0,0x22,0x4c,0x02,0xa1,0x01,0x20 }}, - {16, 0x9340, 0, {0x30,0x1b,0x23,0x02,0xaf,0x20,0xb3,0x08,0x2c,0x80,0x1b,0x30,0x00,0xcc,0x04,0xa3 }}, - {16, 0x9350, 0, {0x01,0x26,0x30,0x08,0xac,0x22,0xe8,0x02,0x80,0x08,0x2e,0x80,0x4b,0xb4,0x02,0x58 }}, - {16, 0x9360, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x10,0x8b,0x80,0x36,0xf0 }}, - {16, 0x9370, 0, {0x2d,0xbc,0x0b,0x6c,0x01,0xda,0x04,0x22,0x40,0x7d,0x94,0x22,0xe4,0x00,0xab,0x44 }}, - {16, 0x9380, 0, {0x2e,0xc0,0x09,0xb8,0x02,0xfc,0x00,0xbf,0x00,0x3e,0xf0,0xca,0x92,0x02,0xe4,0x02 }}, - {16, 0x9390, 0, {0xcb,0x00,0x6e,0x40,0x0f,0x84,0x01,0x2e,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x93a0, 0, {0x80,0x00,0xec,0x00,0xfb,0x00,0x3a,0xe0,0x2e,0xbc,0x03,0x98,0x08,0xea,0x40,0x36 }}, - {16, 0x93b0, 0, {0x43,0x8c,0x90,0x03,0xa4,0x44,0x2a,0x40,0x3e,0x10,0x0e,0xb5,0x83,0xec,0x14,0xfb }}, - {16, 0x93c0, 0, {0x00,0x26,0x00,0x0e,0x92,0x03,0xe0,0x40,0xfa,0x00,0x16,0x00,0x0f,0x80,0x13,0xe0 }}, - {16, 0x93d0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xec,0x02,0xfa,0x80,0x3f,0xe2 }}, - {16, 0x93e0, 0, {0x0f,0xb0,0x0b,0x24,0x00,0xef,0x92,0xbb,0xe0,0x1c,0xd0,0x03,0x74,0x00,0xcf,0x05 }}, - {16, 0x93f0, 0, {0x3b,0x40,0x0f,0xc8,0x03,0x5c,0x00,0xcf,0x00,0x32,0xc2,0x4d,0xc1,0x23,0x34,0x40 }}, - {16, 0x9400, 0, {0xcf,0x00,0x17,0x44,0x0c,0xd1,0x83,0x00,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9410, 0, {0x81,0x04,0x6c,0x00,0x8b,0x84,0x2e,0x54,0x0b,0xbc,0x0a,0x29,0x80,0x8b,0x80,0x32 }}, - {16, 0x9420, 0, {0x00,0x08,0x9c,0x03,0xa7,0x00,0xab,0x84,0x2e,0x7c,0x0b,0x80,0x02,0x2c,0x10,0xdb }}, - {16, 0x9430, 0, {0x01,0x36,0x00,0x08,0x80,0x02,0x20,0x00,0x82,0x00,0x22,0x00,0x08,0x90,0x02,0x24 }}, - {16, 0x9440, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x0c,0x00,0x89,0x10,0x66,0x90 }}, - {16, 0x9450, 0, {0x0b,0xb8,0x02,0x6e,0x12,0xa3,0x41,0x20,0x04,0x0a,0x98,0x22,0xe2,0x00,0x89,0x19 }}, - {16, 0x9460, 0, {0x2e,0xc0,0x4b,0x31,0x22,0x6c,0x08,0x83,0x00,0x22,0xc0,0x09,0x90,0x02,0x24,0x00 }}, - {16, 0x9470, 0, {0x89,0x00,0x2a,0x40,0x08,0x80,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9480, 0, {0x08,0x10,0x0c,0x00,0x80,0x20,0x2c,0x0e,0x1b,0x30,0x02,0x04,0x41,0x80,0x20,0x20 }}, - {16, 0x9490, 0, {0x12,0x18,0x16,0x42,0x00,0x50,0xa0,0x40,0x2c,0x88,0x1b,0x30,0x02,0x0c,0x81,0x93 }}, - {16, 0x94a0, 0, {0x00,0x24,0x00,0x08,0x10,0x2a,0x00,0x0a,0x88,0x00,0x28,0x00,0x28,0x00,0x0a,0x02 }}, - {16, 0x94b0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x7c,0x11,0xe8,0x00,0x26,0x98 }}, - {16, 0x94c0, 0, {0x0f,0xb0,0x13,0x21,0x0c,0xeb,0x60,0x3a,0xd8,0x28,0x84,0xa2,0xe1,0x80,0xc8,0x20 }}, - {16, 0x94d0, 0, {0x3e,0x5e,0x1f,0x82,0x03,0x7c,0x00,0xcf,0x00,0x32,0xc0,0x4d,0x80,0x07,0x25,0x00 }}, - {16, 0x94e0, 0, {0xc9,0x00,0x32,0x40,0x0c,0x90,0x03,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x94f0, 0, {0xa1,0x11,0xfc,0x00,0xf8,0x13,0x1e,0x00,0x0b,0xf0,0x01,0xf0,0xd0,0xf9,0x19,0x1f }}, - {16, 0x9500, 0, {0x08,0x4f,0xc0,0x13,0xa1,0x00,0xf8,0x62,0x3f,0xc0,0x0b,0xc4,0x07,0xed,0x00,0xff }}, - {16, 0x9510, 0, {0x00,0x3f,0x00,0x0f,0xc0,0x23,0xf0,0xa0,0xfc,0x00,0x33,0x00,0x0f,0xd0,0x03,0xe8 }}, - {16, 0x9520, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xff,0x0c,0x3f,0x20 }}, - {16, 0x9530, 0, {0x0c,0xc9,0x03,0x32,0x00,0xcf,0x38,0x3f,0xd0,0x0f,0x48,0x03,0xfc,0xa0,0xce,0x22 }}, - {16, 0x9540, 0, {0x33,0x00,0x0f,0xc1,0x03,0x3c,0x00,0xff,0x00,0x3d,0xc4,0x4c,0xc0,0x23,0x8c,0xe4 }}, - {16, 0x9550, 0, {0xff,0x10,0x37,0x20,0x08,0xf1,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9560, 0, {0x80,0x10,0xfe,0x00,0xbf,0x80,0x2e,0x74,0x05,0x22,0x02,0xa2,0x10,0xdf,0x61,0x2f }}, - {16, 0x9570, 0, {0xd0,0x8b,0x90,0x02,0x3d,0xa4,0xaa,0x90,0x22,0xf4,0x0b,0x07,0x12,0x1d,0x20,0xbb }}, - {16, 0x9580, 0, {0xc0,0x2f,0xd8,0x88,0x97,0x82,0xfd,0x80,0xef,0x72,0x22,0x08,0x28,0xf6,0x23,0xe0 }}, - {16, 0x9590, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x40,0xb3,0x00,0x2c,0x00 }}, - {16, 0x95a0, 0, {0x08,0x82,0x02,0x22,0x00,0x83,0x01,0x08,0xcc,0x8b,0x20,0x82,0xcc,0x00,0x90,0x00 }}, - {16, 0x95b0, 0, {0x20,0x00,0x4b,0x12,0x02,0x0d,0x80,0xb3,0x40,0x2c,0xd8,0x08,0x20,0x42,0x8c,0x80 }}, - {16, 0x95c0, 0, {0xb3,0x20,0x26,0x02,0x18,0x33,0x26,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x95d0, 0, {0xc0,0x15,0xac,0x09,0xbb,0x00,0x2e,0x60,0x08,0x80,0x02,0xa2,0x00,0x9b,0x00,0x2e }}, - {16, 0x95e0, 0, {0xc0,0x0b,0xac,0x02,0x2c,0x00,0xba,0x06,0x22,0xc2,0x0b,0x94,0x02,0xac,0x10,0xbb }}, - {16, 0x95f0, 0, {0x00,0x2e,0xc1,0x08,0xa8,0x02,0xec,0x00,0xab,0x00,0x22,0x00,0x08,0xb0,0x06,0xf0 }}, - {16, 0x9600, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x15,0xec,0x00,0xfb,0x04,0x3e,0x60 }}, - {16, 0x9610, 0, {0x28,0x82,0x13,0x0e,0x08,0xcb,0x00,0x3a,0xc0,0x0f,0x8c,0x03,0xec,0x11,0xdb,0x20 }}, - {16, 0x9620, 0, {0xb2,0x90,0x4b,0xa8,0x0b,0x2c,0x00,0xbb,0x00,0x2c,0xc0,0x0c,0x88,0x13,0xac,0x00 }}, - {16, 0x9630, 0, {0xf3,0x00,0x36,0x06,0x48,0xb0,0x12,0xc4,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9640, 0, {0xe0,0x01,0xbc,0x00,0xfb,0x08,0x3d,0x40,0x8f,0xea,0x01,0xf4,0x00,0xff,0x01,0x2f }}, - {16, 0x9650, 0, {0xc0,0x0f,0xd0,0x22,0xfc,0x04,0xaf,0x00,0x3f,0xc0,0x8f,0xe9,0x03,0x7c,0x00,0xff }}, - {16, 0x9660, 0, {0x00,0x3f,0xc0,0x0f,0x90,0x43,0xfc,0x20,0xef,0x02,0x3f,0x00,0x8f,0xf0,0x03,0xb8 }}, - {16, 0x9670, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x10,0xac,0x08,0xeb,0x00,0x12,0x40 }}, - {16, 0x9680, 0, {0x0f,0x90,0x03,0x28,0x20,0xab,0x00,0x3a,0xc0,0x8f,0x85,0x83,0xac,0x10,0xf3,0x50 }}, - {16, 0x9690, 0, {0x32,0x90,0x4c,0x34,0x13,0x6c,0x00,0xfb,0x00,0x3e,0xc0,0x0c,0x98,0x03,0x2c,0x40 }}, - {16, 0x96a0, 0, {0xeb,0x80,0x32,0x12,0x0d,0xb0,0x0b,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x96b0, 0, {0x88,0x01,0x3c,0x10,0x0f,0x05,0xa2,0x50,0x0c,0x10,0x02,0x22,0x10,0x8f,0x00,0x23 }}, - {16, 0x96c0, 0, {0xc0,0x0b,0x88,0x12,0x3c,0x00,0x9b,0x82,0x22,0xc0,0x08,0xb0,0x02,0x3c,0x00,0x8f }}, - {16, 0x96d0, 0, {0xa0,0x2f,0xc0,0x08,0xb0,0x02,0x3c,0x08,0x8f,0x02,0x20,0x00,0x08,0xf0,0x03,0x26 }}, - {16, 0x96e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4d,0x20,0x93,0x00,0x20,0xb2 }}, - {16, 0x96f0, 0, {0x0b,0x10,0x02,0x01,0x00,0xa3,0x00,0x68,0xc0,0x0b,0x84,0x02,0xac,0x00,0xb3,0x80 }}, - {16, 0x9700, 0, {0x20,0x40,0x0a,0x30,0x02,0x4c,0x00,0xa3,0x04,0x2c,0xc0,0x08,0x00,0x02,0x0d,0x00 }}, - {16, 0x9710, 0, {0xa3,0x00,0x20,0x24,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9720, 0, {0x70,0x01,0x1c,0x20,0x97,0x80,0x23,0x60,0x08,0x78,0x12,0x3a,0x00,0x83,0x91,0x29 }}, - {16, 0x9730, 0, {0xe4,0x0b,0x59,0x02,0x1e,0x00,0x97,0x90,0x20,0xfc,0x0a,0x78,0x02,0x1e,0x00,0x87 }}, - {16, 0x9740, 0, {0x90,0x2d,0xe0,0x19,0x59,0x02,0x1e,0x80,0x83,0x80,0x61,0xa0,0x08,0x78,0x02,0x18 }}, - {16, 0x9750, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x40,0xd3,0x32,0x30,0x06 }}, - {16, 0x9760, 0, {0x0f,0x30,0x03,0x04,0x64,0xe3,0x01,0x38,0xc4,0x1f,0x30,0x07,0x8c,0x18,0xf1,0x00 }}, - {16, 0x9770, 0, {0x30,0x4c,0x0e,0x30,0x03,0x4c,0x00,0xe3,0x00,0x2c,0xc0,0x0c,0x20,0x03,0x0e,0x00 }}, - {16, 0x9780, 0, {0xe3,0x00,0x32,0x08,0x0c,0xb1,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9790, 0, {0x40,0x1d,0x9c,0x80,0xef,0x10,0x3d,0x44,0x4f,0xf1,0x07,0xcc,0x00,0xff,0x08,0x36 }}, - {16, 0x97a0, 0, {0xc6,0xcf,0xb0,0x03,0xfc,0x00,0x97,0x00,0xbe,0xcc,0x0d,0xb1,0x03,0xfd,0x04,0xff }}, - {16, 0x97b0, 0, {0x0c,0x3f,0xd2,0x9e,0xe0,0x4b,0xfd,0x20,0xff,0x02,0x3f,0x80,0x0e,0xf0,0x13,0xd0 }}, - {16, 0x97c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xec,0xc0,0xcb,0x28,0x3e,0xc0 }}, - {16, 0x97d0, 0, {0x0f,0x80,0x03,0xec,0x00,0xfb,0x01,0x32,0xe9,0x0c,0x28,0x03,0x2c,0x00,0xfb,0x00 }}, - {16, 0x97e0, 0, {0x32,0xc0,0x0c,0xb4,0x83,0x2c,0x01,0xef,0x00,0xb2,0xc8,0x0c,0x20,0x03,0x6d,0x00 }}, - {16, 0x97f0, 0, {0xcb,0x10,0x3e,0x00,0x0f,0xb2,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9800, 0, {0xc8,0x91,0x9c,0xc4,0x87,0x60,0x2d,0xc0,0x0b,0x60,0x02,0xdc,0x00,0xb7,0x12,0x20 }}, - {16, 0x9810, 0, {0xcc,0x0a,0x70,0x02,0x1c,0xc0,0xb3,0x00,0xa0,0xc0,0xc8,0x70,0x22,0x1c,0x80,0xb7 }}, - {16, 0x9820, 0, {0x24,0x21,0xc8,0x48,0x50,0x02,0x0c,0x80,0x87,0x10,0x2d,0x40,0x0b,0x72,0x82,0xf2 }}, - {16, 0x9830, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x8e,0x02,0x87,0x80,0x2d,0xe0 }}, - {16, 0x9840, 0, {0x0b,0x78,0x12,0xde,0x00,0xb7,0xa0,0x21,0xe0,0x08,0xf8,0x8e,0x1e,0x40,0xb7,0x88 }}, - {16, 0x9850, 0, {0x21,0xe0,0x08,0x38,0x02,0x1e,0x40,0xb3,0xa1,0x20,0xe8,0x48,0xf8,0x82,0x5e,0x02 }}, - {16, 0x9860, 0, {0x87,0x80,0x2d,0x22,0x0b,0x79,0x02,0xe0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9870, 0, {0x08,0x04,0xcc,0x04,0x83,0x02,0x2c,0xd4,0x0b,0x30,0x02,0xcc,0x00,0xb3,0x00,0xa0 }}, - {16, 0x9880, 0, {0xc0,0x8a,0x38,0x06,0x0c,0x00,0xb3,0x80,0x20,0xe1,0x48,0x39,0x12,0x2c,0x00,0xb3 }}, - {16, 0x9890, 0, {0x00,0x22,0xc0,0x08,0xb0,0x82,0x6c,0x00,0x83,0x00,0x2c,0x48,0x0b,0x30,0x02,0xc2 }}, - {16, 0x98a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0xa8,0x00,0xca,0x00,0x3f,0xa0 }}, - {16, 0x98b0, 0, {0x0f,0xe4,0x03,0xd8,0x00,0xfa,0x00,0x32,0x80,0x0c,0xe8,0x03,0x28,0x00,0xfa,0x40 }}, - {16, 0x98c0, 0, {0x32,0xa8,0x2c,0xa0,0x09,0x28,0x08,0xf2,0x00,0x32,0x80,0x0c,0xe4,0x03,0x68,0x00 }}, - {16, 0x98d0, 0, {0xca,0x00,0x3f,0x80,0x0f,0xa0,0x03,0xfb,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x98e0, 0, {0x48,0x00,0xc0,0x00,0xf8,0x01,0x3e,0x12,0x0b,0x80,0x03,0xe0,0x40,0xf8,0x00,0x3e }}, - {16, 0x98f0, 0, {0x00,0x4f,0x84,0x03,0xe0,0x04,0xf0,0x08,0x3e,0x00,0x4f,0x00,0x03,0xe0,0x00,0xf8 }}, - {16, 0x9900, 0, {0x41,0x3e,0x00,0x2f,0x84,0x03,0xa0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0x9910, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe6,0x00,0xc9,0x12,0x3e,0x50 }}, - {16, 0x9920, 0, {0x8f,0x90,0x83,0xe4,0x20,0xc1,0x00,0x3a,0x41,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00 }}, - {16, 0x9930, 0, {0x30,0x68,0x0c,0x90,0x03,0x24,0x00,0xd9,0x00,0x3a,0x40,0x0e,0x98,0x03,0x24,0x00 }}, - {16, 0x9940, 0, {0xc9,0x90,0x3e,0x69,0x0c,0x10,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9950, 0, {0x80,0x04,0x67,0x4a,0x89,0x80,0x2e,0x50,0x0b,0x90,0x02,0xe4,0x80,0xa9,0x00,0x22 }}, - {16, 0x9960, 0, {0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x01,0x22,0x40,0x08,0x90,0x02,0x24,0x10,0x89 }}, - {16, 0x9970, 0, {0x00,0x22,0x40,0x08,0x93,0x02,0x24,0x22,0x89,0x42,0x2c,0x60,0x48,0x90,0x02,0x20 }}, - {16, 0x9980, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0x24,0x00,0x99,0x00,0x2e,0x40 }}, - {16, 0x9990, 0, {0x0b,0x90,0x02,0xe4,0x00,0x89,0x00,0x2a,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x00 }}, - {16, 0x99a0, 0, {0x23,0x40,0x08,0xd0,0x02,0x24,0x00,0x99,0x00,0x2a,0x40,0x0a,0x90,0x06,0x24,0x40 }}, - {16, 0x99b0, 0, {0x89,0x41,0x2e,0x40,0x08,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x99c0, 0, {0x08,0x04,0x0c,0x80,0x91,0x20,0x2c,0x48,0x0b,0x10,0x02,0xc4,0x00,0xa1,0x20,0x20 }}, - {16, 0x99d0, 0, {0x48,0x0b,0x10,0x02,0xc4,0x80,0xb1,0x20,0xa1,0x49,0x08,0x52,0x4a,0x04,0x80,0x81 }}, - {16, 0x99e0, 0, {0x00,0x20,0x48,0x48,0x12,0x0a,0x04,0x80,0x81,0x20,0x2c,0x40,0x28,0x12,0x02,0x02 }}, - {16, 0x99f0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x08,0xd8,0x04,0x3e,0x80 }}, - {16, 0x9a00, 0, {0x0f,0x85,0x03,0xe0,0x00,0xc0,0x50,0x3a,0x14,0x0f,0xa5,0x03,0xe1,0x40,0xf8,0x02 }}, - {16, 0x9a10, 0, {0x32,0x80,0x2c,0xc5,0x03,0x21,0x40,0xda,0x00,0x3a,0x14,0x0e,0x85,0x43,0x21,0x40 }}, - {16, 0x9a20, 0, {0xc8,0x52,0x3e,0x14,0x0c,0x85,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9a30, 0, {0x88,0x1d,0xe4,0x44,0xe9,0x10,0x3f,0x44,0x4f,0xd0,0x02,0xfc,0x00,0xf9,0x12,0x3e }}, - {16, 0x9a40, 0, {0x44,0x0f,0xd0,0x03,0xe4,0x40,0xfd,0x10,0x3e,0x44,0x4f,0x91,0x03,0xe4,0x40,0xe9 }}, - {16, 0x9a50, 0, {0x40,0x3e,0x44,0x0f,0xd1,0x03,0xe4,0x40,0xf9,0x12,0x3f,0x40,0x0f,0x91,0x03,0xe6 }}, - {16, 0x9a60, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xf6,0xa0,0xfd,0x80,0xb3,0x40 }}, - {16, 0x9a70, 0, {0x0c,0x10,0x03,0x14,0x00,0xfd,0xa0,0x32,0x40,0x0f,0xd1,0x03,0xe4,0x00,0xf5,0x86 }}, - {16, 0x9a80, 0, {0x33,0x60,0x2c,0x9a,0x83,0x24,0x04,0xfd,0xa8,0x22,0x40,0x0d,0x50,0x43,0xf4,0x00 }}, - {16, 0x9a90, 0, {0xfd,0x00,0x33,0x40,0x0f,0x90,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9aa0, 0, {0x78,0x10,0xe1,0x00,0xb8,0x00,0x22,0x00,0x28,0x80,0x02,0x20,0x00,0xb8,0x00,0xa2 }}, - {16, 0x9ab0, 0, {0x00,0x0b,0x8a,0x12,0xe0,0x00,0xb8,0x04,0x22,0x14,0x08,0x84,0x02,0x20,0x00,0xb8 }}, - {16, 0x9ac0, 0, {0x40,0x20,0x00,0x88,0x80,0x02,0xe0,0x00,0xb8,0x00,0xa2,0x00,0x0b,0x80,0x02,0x0e }}, - {16, 0x9ad0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x00,0xb1,0x42,0x20,0x40 }}, - {16, 0x9ae0, 0, {0x08,0x10,0x02,0x04,0x00,0xb1,0x40,0x20,0x40,0x0b,0x10,0x06,0xc4,0x00,0xb1,0x40 }}, - {16, 0x9af0, 0, {0x24,0x40,0x08,0x10,0x02,0x44,0x04,0xb1,0x00,0x60,0x40,0x09,0x10,0x02,0xc4,0x00 }}, - {16, 0x9b00, 0, {0xb1,0x00,0x20,0x40,0x0b,0x10,0x02,0x12,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9b10, 0, {0x18,0x15,0xa4,0x00,0xb9,0x02,0x22,0x60,0x08,0x94,0x02,0x24,0x00,0xb9,0x01,0x22 }}, - {16, 0x9b20, 0, {0x40,0x0b,0x90,0x06,0xe4,0x00,0xb9,0x20,0x26,0x40,0x08,0x94,0x02,0x64,0x08,0xb9 }}, - {16, 0x9b30, 0, {0x00,0x22,0x40,0x08,0x92,0x02,0xec,0x08,0xb9,0x04,0x22,0x41,0x0b,0x10,0x02,0x06 }}, - {16, 0x9b40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x10,0xf1,0x00,0x32,0x60 }}, - {16, 0x9b50, 0, {0x0c,0x94,0x0b,0x25,0x00,0xf9,0x00,0x32,0x40,0x8f,0x94,0xd3,0xe4,0x00,0xf9,0x00 }}, - {16, 0x9b60, 0, {0x36,0x40,0x4c,0x90,0x0b,0x64,0x00,0xf1,0x00,0x32,0x40,0x0d,0x92,0x12,0xe4,0x00 }}, - {16, 0x9b70, 0, {0xf9,0x00,0x32,0x40,0x0f,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9b80, 0, {0x68,0x41,0xa4,0x00,0xf9,0x00,0x3c,0x40,0x8f,0x92,0x03,0xe4,0x00,0xf9,0x00,0x3e }}, - {16, 0x9b90, 0, {0x40,0x0f,0x9c,0x03,0xe4,0x00,0xf9,0x00,0xba,0x40,0x2f,0x90,0x23,0xa4,0x00,0xf9 }}, - {16, 0x9ba0, 0, {0x08,0xbe,0x40,0xcf,0x90,0x03,0xe4,0x10,0xf1,0x01,0x3e,0x41,0x0f,0x90,0x03,0xda }}, - {16, 0x9bb0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0xc8,0xf8,0x00,0x3e,0x03 }}, - {16, 0x9bc0, 0, {0x0c,0x84,0x03,0xa1,0x10,0xe8,0x00,0x32,0x00,0x8c,0x85,0x83,0xe0,0x00,0xc0,0x00 }}, - {16, 0x9bd0, 0, {0x38,0x0c,0x2c,0x00,0x03,0x60,0x00,0xc8,0x00,0x3c,0x00,0x0d,0x80,0x02,0x20,0x10 }}, - {16, 0x9be0, 0, {0xc8,0x20,0xb2,0x02,0x0f,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9bf0, 0, {0x28,0x05,0x39,0x10,0xbe,0x04,0x6f,0xa0,0x08,0xa0,0x02,0x3a,0x00,0x82,0x00,0xa2 }}, - {16, 0x9c00, 0, {0x80,0x8d,0xec,0x03,0xa8,0x00,0x8a,0x00,0x23,0x80,0x08,0xa0,0x22,0x28,0x00,0x8e }}, - {16, 0x9c10, 0, {0xcc,0x2f,0x80,0x08,0xe8,0xc2,0xb8,0x00,0x8e,0x60,0x23,0x90,0x0b,0xa0,0x02,0xca }}, - {16, 0x9c20, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4e,0x08,0xb0,0x72,0x2c,0xd0 }}, - {16, 0x9c30, 0, {0x28,0xb0,0x06,0x8c,0x01,0xa1,0x02,0x20,0xc0,0x08,0x38,0x02,0xcc,0x00,0x83,0x00 }}, - {16, 0x9c40, 0, {0x20,0xc0,0x29,0x30,0x02,0x4c,0x00,0x81,0x00,0x2c,0xc0,0x08,0x32,0x02,0x0c,0x40 }}, - {16, 0x9c50, 0, {0x83,0x00,0x20,0xf4,0x0b,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9c60, 0, {0xa0,0x01,0x1c,0x00,0xb4,0x00,0x2d,0xd0,0x48,0xf2,0x02,0x1e,0x21,0x85,0x20,0x20 }}, - {16, 0x9c70, 0, {0xe8,0x09,0x72,0x02,0x8e,0x80,0x8f,0x01,0x20,0xc0,0x09,0x72,0x02,0x0e,0x80,0x87 }}, - {16, 0x9c80, 0, {0x00,0x2d,0xcc,0x18,0x58,0x02,0x8e,0x00,0x85,0x00,0x21,0xc0,0x0b,0x72,0x02,0xe8 }}, - {16, 0x9c90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xb4,0x80,0x2d,0xe0 }}, - {16, 0x9ca0, 0, {0x0c,0x78,0x83,0x9a,0x00,0xed,0xd0,0x31,0xf4,0x0c,0x6a,0x03,0xde,0x82,0xc7,0x80 }}, - {16, 0x9cb0, 0, {0x39,0xe0,0x0d,0xf8,0x83,0x5e,0xc2,0xc5,0x80,0x3d,0xe8,0x0c,0x68,0x03,0x12,0x00 }}, - {16, 0x9cc0, 0, {0xcf,0x80,0x31,0xe0,0x0f,0x7e,0x83,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9cd0, 0, {0x08,0x0d,0xac,0x08,0xf8,0x00,0x3c,0xc0,0x0f,0xb3,0x03,0xec,0x00,0xf9,0x02,0x3e }}, - {16, 0x9ce0, 0, {0xc8,0x0f,0xb0,0x03,0xed,0x40,0xfb,0x00,0xbe,0x80,0x0e,0xb3,0x03,0xed,0xc0,0xfb }}, - {16, 0x9cf0, 0, {0x00,0x3e,0xd2,0x2e,0x80,0x03,0xec,0x02,0xf9,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xc2 }}, - {16, 0x9d00, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xf0,0x91,0x33,0xe0 }}, - {16, 0x9d10, 0, {0x8f,0xf8,0x03,0xfe,0x00,0xfd,0x80,0x3f,0xe0,0x0c,0x78,0x83,0x3f,0x00,0xcf,0x80 }}, - {16, 0x9d20, 0, {0x3f,0xa0,0x0c,0xf8,0x03,0x3e,0x00,0xcd,0x80,0x3f,0xe0,0x0f,0xf8,0x13,0xfe,0x10 }}, - {16, 0x9d30, 0, {0xff,0x80,0x3f,0x20,0x0f,0xf9,0x43,0xd0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9d40, 0, {0xa8,0x11,0x9c,0x00,0xb4,0xc1,0x31,0xc0,0x0b,0x70,0x02,0xd4,0x10,0xe5,0x20,0x2f }}, - {16, 0x9d50, 0, {0xc8,0x0f,0x40,0x03,0x5c,0x00,0x87,0x00,0x2d,0x80,0x08,0x70,0x02,0x1c,0x40,0x87 }}, - {16, 0x9d60, 0, {0x10,0x2d,0xc0,0x0b,0x76,0x02,0xdc,0x80,0xb7,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xea }}, - {16, 0x9d70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x9c,0x00,0xb6,0x22,0x21,0xd0 }}, - {16, 0x9d80, 0, {0x0b,0x70,0x82,0xd8,0x40,0xb5,0x02,0x2d,0xc0,0x88,0x65,0x02,0x0c,0x00,0x87,0x18 }}, - {16, 0x9d90, 0, {0x2c,0x04,0x08,0x30,0x02,0x8c,0x02,0x85,0x00,0x2d,0xc0,0x0b,0x70,0x46,0x90,0x10 }}, - {16, 0x9da0, 0, {0xb6,0x00,0x2d,0x00,0x0b,0x70,0x22,0xc4,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9db0, 0, {0x60,0x14,0xcc,0x08,0xb2,0x00,0xa4,0xc0,0x0b,0x30,0x42,0xc6,0x10,0xa1,0x00,0x2c }}, - {16, 0x9dc0, 0, {0xc0,0x0a,0x00,0x02,0x4c,0x00,0x83,0x00,0x2c,0x08,0x08,0x30,0x02,0x8c,0x00,0x83 }}, - {16, 0x9dd0, 0, {0x00,0x2c,0xc0,0x0b,0x18,0x82,0xc4,0x00,0xb0,0x00,0x2c,0x40,0x0b,0x30,0x12,0xd8 }}, - {16, 0x9de0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x15,0xac,0x00,0x38,0x00,0x32,0x50 }}, - {16, 0x9df0, 0, {0x0f,0xf0,0x03,0xe6,0x20,0xfd,0x00,0x3f,0xc0,0x08,0xd0,0x02,0x3c,0x02,0xcb,0x80 }}, - {16, 0x9e00, 0, {0x3c,0x50,0x2c,0xf0,0x0a,0xbc,0x00,0xc9,0x00,0x3f,0xc0,0x0f,0xbe,0x03,0xac,0x00 }}, - {16, 0x9e10, 0, {0xfa,0x02,0x2e,0xf7,0x4f,0xf0,0x03,0xee,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9e20, 0, {0x80,0x00,0xec,0x00,0xf1,0x00,0x3a,0xf0,0x0f,0xb0,0x03,0xe9,0x00,0xf9,0x01,0x3e }}, - {16, 0x9e30, 0, {0xc0,0x0f,0x90,0x13,0xec,0x00,0xf9,0x00,0x3e,0x55,0x0f,0xb0,0x01,0x6c,0x00,0xfb }}, - {16, 0x9e40, 0, {0x02,0x3e,0xc0,0x0f,0x90,0x73,0xe0,0x00,0xf8,0x41,0x3e,0x00,0x0f,0x30,0x01,0xe0 }}, - {16, 0x9e50, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0xfc,0x00,0xfc,0x00,0x33,0xc0 }}, - {16, 0x9e60, 0, {0x1f,0xf0,0x13,0xf0,0x08,0xfd,0x02,0x3f,0xc0,0x8d,0xc0,0x03,0x3c,0x00,0xcf,0xa0 }}, - {16, 0x9e70, 0, {0x3f,0x80,0x0c,0x70,0x03,0x3c,0x10,0xfc,0x00,0x37,0xc0,0x0f,0xe0,0x03,0xb0,0x00 }}, - {16, 0x9e80, 0, {0xfe,0x00,0x3f,0xc0,0x0c,0xf0,0x03,0x04,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9e90, 0, {0x84,0x04,0x6e,0x00,0xb9,0xc2,0xa2,0xf0,0x0b,0xb0,0x42,0xeb,0x00,0xb9,0x00,0x2e }}, - {16, 0x9ea0, 0, {0xc0,0x0f,0x18,0x03,0x6c,0x00,0xd9,0x81,0x2e,0xb0,0x0a,0xb0,0x42,0x2c,0x00,0xba }}, - {16, 0x9eb0, 0, {0xc6,0x2e,0xc0,0x0b,0x8c,0x02,0xe3,0x00,0xb8,0xc0,0x3c,0xa0,0x0d,0xb0,0x02,0x20 }}, - {16, 0x9ec0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2f,0x00,0xb8,0x80,0x22,0xe2 }}, - {16, 0x9ed0, 0, {0x0b,0xb0,0x02,0xe6,0x20,0xb9,0x00,0x2c,0xc0,0x08,0xb8,0x02,0x0c,0x00,0x8b,0x00 }}, - {16, 0x9ee0, 0, {0x2e,0x30,0x48,0xb0,0x02,0x2c,0x00,0xb9,0xc0,0x2e,0xc1,0x0b,0x88,0x02,0xee,0x10 }}, - {16, 0x9ef0, 0, {0xb9,0xc0,0x2e,0x20,0x19,0xb0,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9f00, 0, {0x08,0x04,0x0c,0x00,0xb0,0x00,0x20,0xc0,0x0b,0x30,0x06,0xc0,0x00,0x91,0x00,0x2c }}, - {16, 0x9f10, 0, {0xc0,0x49,0x80,0x02,0x4c,0x04,0x91,0x00,0x2c,0x00,0x8a,0x30,0x0a,0x0c,0x04,0xb1 }}, - {16, 0x9f20, 0, {0x00,0x2c,0xc0,0x1b,0x00,0x12,0x49,0x10,0xb1,0x00,0x2e,0x20,0x09,0x30,0x02,0x02 }}, - {16, 0x9f30, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xb8,0x20,0x22,0xc0 }}, - {16, 0x9f40, 0, {0x8b,0xf0,0x03,0xe0,0x08,0xfd,0x00,0x3f,0xc0,0x0c,0xa0,0x03,0x3c,0x00,0xcb,0x00 }}, - {16, 0x9f50, 0, {0x3e,0x00,0x4c,0xf0,0x0a,0x3c,0x00,0xb9,0x00,0x37,0xc1,0x0f,0xa0,0x03,0xe0,0x00 }}, - {16, 0x9f60, 0, {0xfa,0x00,0x3e,0x00,0x0d,0xf0,0x0b,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9f70, 0, {0xa0,0x1d,0xf0,0x01,0xfc,0x40,0x3f,0x80,0x4f,0xf0,0x02,0xf0,0x00,0xfd,0x00,0x3f }}, - {16, 0x9f80, 0, {0xc1,0x0f,0xc0,0x03,0xfc,0x00,0xfd,0x00,0x3f,0x00,0x4f,0xf0,0x63,0xfc,0x00,0xfd }}, - {16, 0x9f90, 0, {0x04,0x3f,0xc0,0x0f,0xc0,0x03,0xf0,0x80,0xfc,0x00,0x7b,0x00,0x0f,0xf0,0x43,0xe8 }}, - {16, 0x9fa0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf8,0x00,0xc8,0x10,0x33,0x04 }}, - {16, 0x9fb0, 0, {0x0c,0x40,0x02,0x34,0x00,0xc8,0x85,0x1f,0xc0,0x2d,0xd9,0x03,0xfc,0xc0,0xdb,0x28 }}, - {16, 0x9fc0, 0, {0x37,0x64,0x0f,0xdb,0x03,0x3e,0x00,0xff,0x25,0x3f,0xc8,0x0e,0xf2,0x03,0xfe,0x20 }}, - {16, 0x9fd0, 0, {0xff,0xa4,0x37,0xc4,0x0c,0xc8,0x03,0x30,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9fe0, 0, {0x80,0x10,0xe8,0x00,0x88,0x20,0x22,0x00,0x08,0x88,0x12,0x26,0x04,0x89,0x82,0x2e }}, - {16, 0x9ff0, 0, {0xf4,0x48,0xb8,0x02,0xfc,0xc4,0x98,0xc2,0x22,0x7c,0x4b,0x9d,0x42,0x26,0x08,0xbf }}, - {16, 0xa000, 0, {0x18,0x77,0xe4,0x08,0xf1,0x82,0xef,0x00,0xbb,0xd0,0x22,0xd8,0x08,0x90,0x83,0x60 }}, - {16, 0xa010, 0, {0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x45,0xc8,0x04,0xa0,0x00,0x24,0x00 }}, - {16, 0xa020, 0, {0x0a,0x00,0x02,0x0c,0x00,0x82,0x04,0x2c,0xe0,0x08,0x10,0x02,0xcc,0x80,0x83,0x00 }}, - {16, 0xa030, 0, {0x24,0x00,0x0b,0x10,0x06,0xc8,0x01,0xb3,0x20,0x2c,0xc0,0x29,0x32,0x02,0xc8,0x08 }}, - {16, 0xa040, 0, {0xb1,0x00,0x24,0xd0,0x08,0x82,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa050, 0, {0xc0,0x15,0xa8,0x00,0xa8,0x0c,0x26,0x00,0x0a,0x80,0x02,0x2c,0x14,0x8a,0x02,0x6e }}, - {16, 0xa060, 0, {0xe0,0x08,0xb0,0x02,0x4c,0x08,0xa8,0x00,0x26,0x20,0x0b,0x9c,0x02,0xe4,0x00,0xbb }}, - {16, 0xa070, 0, {0x04,0x22,0xc0,0x19,0xb0,0x02,0xe8,0x01,0xbb,0x11,0x02,0xc0,0x88,0x90,0x02,0xf0 }}, - {16, 0xa080, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xec,0x02,0xea,0x40,0xb6,0x60 }}, - {16, 0xa090, 0, {0x2e,0x98,0x0b,0x20,0x02,0xc8,0x02,0x3e,0xc0,0x0d,0x98,0x03,0xec,0x02,0xdb,0x88 }}, - {16, 0xa0a0, 0, {0xb6,0x21,0x0f,0x88,0x03,0xac,0x08,0xfb,0x00,0x2c,0xc0,0x0e,0xb0,0x43,0xe5,0x80 }}, - {16, 0xa0b0, 0, {0xf0,0x60,0x36,0xc0,0x0c,0x01,0x43,0x48,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa0c0, 0, {0xe0,0x01,0xbc,0x00,0xd6,0x01,0x3b,0x64,0x85,0xd9,0x03,0xf0,0x0c,0xff,0x00,0x3e }}, - {16, 0xa0d0, 0, {0xc1,0x0f,0xfc,0x21,0xec,0x00,0xd7,0x90,0x3b,0x40,0x0f,0x50,0x03,0x3c,0x00,0xff }}, - {16, 0xa0e0, 0, {0x00,0x3f,0xc0,0x8e,0xf0,0x03,0xf4,0x40,0xfd,0x88,0x3f,0xc0,0x2f,0xd0,0x02,0x78 }}, - {16, 0xa0f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8c,0x00,0xda,0x40,0x3c,0x40 }}, - {16, 0xa100, 0, {0x0f,0x10,0x03,0x48,0x00,0xf9,0x22,0x3c,0xc2,0x0e,0x90,0x83,0xec,0x02,0xdb,0x04 }}, - {16, 0xa110, 0, {0x3a,0x08,0x0f,0x84,0x87,0xe8,0x00,0xcb,0x00,0x3e,0xc4,0x0e,0xb0,0x03,0xed,0x00 }}, - {16, 0xa120, 0, {0xe8,0x42,0x3a,0xc0,0x0f,0x80,0x0b,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa130, 0, {0x88,0x05,0x2c,0x08,0x8a,0x00,0x2e,0x42,0x8b,0x90,0x02,0x28,0x18,0xbb,0x49,0x22 }}, - {16, 0xa140, 0, {0xd0,0x38,0xbc,0x82,0xfc,0x00,0xe8,0x02,0x22,0x62,0xcb,0x9c,0x00,0xef,0x60,0xdf }}, - {16, 0xa150, 0, {0x00,0x2f,0xc0,0x0b,0xf0,0x02,0xec,0x00,0x09,0x40,0x37,0xc0,0x0b,0x90,0x02,0x32 }}, - {16, 0xa160, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x48,0x10,0x11,0x00,0x2c,0xa0 }}, - {16, 0xa170, 0, {0x0b,0x20,0x02,0x44,0x00,0x90,0xc0,0x64,0x34,0x28,0x34,0x02,0xcc,0x00,0x93,0x84 }}, - {16, 0xa180, 0, {0x28,0x40,0x0b,0x08,0x00,0xce,0x00,0x93,0x00,0x2c,0xc2,0x0a,0x30,0x02,0xc0,0x00 }}, - {16, 0xa190, 0, {0xb2,0x40,0x22,0xc0,0x0b,0x20,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa1a0, 0, {0x70,0x01,0x1a,0x40,0x85,0x80,0x2d,0xa0,0x0b,0x68,0x06,0x16,0x80,0xbd,0x90,0x25 }}, - {16, 0xa1b0, 0, {0x24,0x18,0x7b,0x42,0xde,0x40,0xa0,0x80,0x21,0xe0,0x0b,0x68,0x02,0xd6,0x00,0x97 }}, - {16, 0xa1c0, 0, {0x90,0x2d,0xe0,0x0b,0x78,0x02,0xce,0x40,0x92,0x80,0x6d,0xe4,0x0b,0x78,0x02,0x08 }}, - {16, 0xa1d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x28,0x00,0xd1,0x80,0x3c,0x88 }}, - {16, 0xa1e0, 0, {0x0b,0x22,0x03,0x4e,0x80,0xf2,0xa1,0x3c,0x24,0x2a,0x39,0x03,0xcc,0x40,0xd3,0xac }}, - {16, 0xa1f0, 0, {0x38,0xc5,0x0f,0x30,0x82,0xc8,0x00,0xd3,0x00,0x3c,0xc0,0x0e,0x30,0x13,0xc0,0x00 }}, - {16, 0xa200, 0, {0xf1,0x00,0x38,0xc0,0x0f,0xa0,0x03,0x1a,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa210, 0, {0x40,0x1d,0xb8,0x10,0xfd,0x34,0x3e,0x80,0x0f,0xe0,0x03,0xee,0x00,0x72,0x00,0x3a }}, - {16, 0xa220, 0, {0x00,0x0f,0xb0,0x63,0xec,0x40,0xf8,0x22,0x3e,0xc0,0x0f,0xf0,0x03,0xd4,0x40,0xff }}, - {16, 0xa230, 0, {0x00,0x3f,0xd2,0x0f,0xf0,0x03,0xec,0x00,0xcf,0x00,0x37,0xc0,0x0f,0xf0,0x03,0xd0 }}, - {16, 0xa240, 0, {0x06,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xee,0x00,0xeb,0x00,0x36,0xe0 }}, - {16, 0xa250, 0, {0x0d,0xb0,0x03,0x20,0x00,0xf0,0x80,0x33,0xc0,0x08,0xb8,0x03,0x2c,0x80,0xcb,0x00 }}, - {16, 0xa260, 0, {0x32,0x80,0x0f,0xa0,0x13,0x6e,0x08,0xcb,0x28,0x32,0xe0,0x0d,0xb4,0x83,0xe2,0x00 }}, - {16, 0xa270, 0, {0xca,0x00,0x3e,0xe0,0x0c,0xa8,0x03,0x02,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa280, 0, {0xc8,0x11,0x8c,0x04,0x83,0x00,0x21,0xc0,0x48,0x70,0x02,0x10,0x00,0xb7,0x02,0x21 }}, - {16, 0xa290, 0, {0xc0,0x4a,0x70,0x02,0x0d,0x48,0xd4,0x00,0x35,0xc0,0x0e,0x60,0x02,0xdc,0x00,0xa7 }}, - {16, 0xa2a0, 0, {0x40,0x29,0xc0,0x09,0x72,0x02,0xd4,0x10,0xa6,0x02,0x2f,0xc8,0x08,0x70,0x02,0x12 }}, - {16, 0xa2b0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x00,0xa7,0x80,0x20,0xe0 }}, - {16, 0xa2c0, 0, {0x0a,0x38,0x02,0x1a,0x00,0xb5,0x80,0x21,0xe0,0x08,0xf8,0x22,0x5c,0x81,0x83,0x80 }}, - {16, 0xa2d0, 0, {0x21,0xa1,0x0b,0x78,0x82,0x5a,0x10,0x83,0xa0,0x20,0xe8,0x0a,0x7b,0x02,0xda,0x00 }}, - {16, 0xa2e0, 0, {0x97,0xc0,0x2d,0xe4,0x08,0xe8,0x02,0x08,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa2f0, 0, {0x08,0x14,0xcc,0x00,0x83,0x10,0x20,0xc0,0x0a,0x30,0x02,0x08,0x08,0xb3,0x70,0x20 }}, - {16, 0xa300, 0, {0xf8,0x0a,0x30,0x42,0x4c,0x04,0x93,0x14,0x26,0xc4,0x0a,0x38,0x02,0xcc,0x00,0xa3 }}, - {16, 0xa310, 0, {0x00,0x28,0xc0,0xaa,0x30,0x02,0xce,0x40,0xb3,0x88,0x2c,0xc0,0x28,0x30,0x0a,0x12 }}, - {16, 0xa320, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa9,0x00,0xea,0x80,0xb6,0x90 }}, - {16, 0xa330, 0, {0x2f,0x24,0x0b,0x39,0x04,0xbe,0xc0,0x33,0x92,0x0c,0xa0,0x0b,0x68,0x18,0xce,0xc0 }}, - {16, 0xa340, 0, {0x33,0x80,0x0f,0xe9,0x43,0x78,0x00,0xca,0x00,0x32,0x80,0x0f,0xa0,0x13,0xf8,0x48 }}, - {16, 0xa350, 0, {0xde,0x00,0x3e,0x80,0x0c,0xe0,0x02,0x3a,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa360, 0, {0x48,0x00,0xe0,0x24,0xf8,0x00,0x3e,0x12,0x0d,0x80,0x93,0xb0,0x28,0xf8,0x00,0xbc }}, - {16, 0xa370, 0, {0x00,0x0f,0x84,0x03,0xa0,0x00,0xf0,0x00,0x3e,0x02,0x0e,0x80,0x00,0xe0,0x00,0xf8 }}, - {16, 0xa380, 0, {0x01,0x3e,0x00,0x0d,0x80,0x03,0xe0,0x00,0xe8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xa390, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x00,0xb2,0x70 }}, - {16, 0xa3a0, 0, {0x0f,0x90,0x01,0x04,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x98,0x03,0xe4,0x04,0xe9,0x08 }}, - {16, 0xa3b0, 0, {0x3a,0x48,0x0c,0x9a,0x03,0xe4,0x00,0xf9,0x00,0x36,0x40,0x0b,0x10,0x0b,0x26,0x80 }}, - {16, 0xa3c0, 0, {0xf1,0x80,0x32,0x40,0x0f,0x90,0x03,0xc2,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa3d0, 0, {0x80,0x04,0x64,0x00,0xb9,0x00,0x22,0x61,0x0b,0x90,0x02,0x24,0x08,0x89,0x00,0x2e }}, - {16, 0xa3e0, 0, {0x40,0x0d,0x9a,0x02,0xe4,0x08,0xa9,0x00,0x22,0x78,0x0d,0x94,0x06,0xe4,0x10,0xb9 }}, - {16, 0xa3f0, 0, {0x00,0x22,0x50,0x0b,0x90,0x02,0x25,0x80,0xb9,0x80,0x36,0x40,0x0b,0x90,0x02,0xe0 }}, - {16, 0xa400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb5,0x00,0x23,0x42 }}, - {16, 0xa410, 0, {0x0b,0xd0,0x0e,0xb4,0x00,0x89,0x04,0x2e,0x60,0x08,0x91,0x02,0xc4,0x04,0xb9,0x04 }}, - {16, 0xa420, 0, {0x2a,0xc0,0x08,0x94,0x02,0xe4,0x10,0xb1,0x00,0x26,0x42,0x0a,0x90,0x02,0x24,0x00 }}, - {16, 0xa430, 0, {0xb9,0x21,0x62,0x40,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa440, 0, {0x08,0x04,0x05,0x00,0xb5,0x40,0x21,0x50,0x4b,0x50,0x06,0x94,0x02,0x81,0x00,0x2c }}, - {16, 0xa450, 0, {0x60,0x29,0x14,0x06,0xc5,0x00,0xa1,0x22,0x20,0x51,0x89,0x14,0x02,0xc4,0x00,0xb1 }}, - {16, 0xa460, 0, {0x20,0x20,0x48,0x0b,0x14,0x02,0x04,0x01,0xb1,0x00,0x04,0x50,0x0b,0x10,0x02,0xc2 }}, - {16, 0xa470, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x08,0xb8,0x00,0x32,0x00 }}, - {16, 0xa480, 0, {0x8f,0x80,0x03,0xb0,0x00,0x88,0x00,0x3e,0x00,0x0c,0x80,0x03,0xe0,0x00,0xe8,0x04 }}, - {16, 0xa490, 0, {0x3a,0x00,0x0c,0x80,0x02,0xe0,0x00,0xf8,0x50,0x36,0x00,0x0f,0x80,0x03,0x20,0x04 }}, - {16, 0xa4a0, 0, {0xf8,0x01,0x12,0x00,0x4f,0x80,0x07,0xee,0x07,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa4b0, 0, {0x98,0x1d,0xe5,0x10,0xf9,0x40,0x3e,0x50,0x0f,0x94,0x02,0x65,0x01,0xfd,0x01,0x3d }}, - {16, 0xa4c0, 0, {0x50,0x4f,0x50,0x13,0xe5,0x00,0xfd,0x10,0x1f,0x50,0x07,0xd4,0x43,0xd4,0x00,0xf9 }}, - {16, 0xa4d0, 0, {0x10,0x1e,0x44,0x0f,0x94,0x03,0xd5,0x00,0xfd,0x40,0x3e,0x50,0x0f,0x52,0x83,0xee }}, - {16, 0xa4e0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xe4,0x40,0xf9,0x60,0x3f,0x44 }}, - {16, 0xa4f0, 0, {0x0f,0xd0,0xc3,0xe4,0x30,0xf9,0x01,0x3e,0x42,0x0c,0xd0,0x03,0xe7,0x80,0xdd,0xa0 }}, - {16, 0xa500, 0, {0x33,0x40,0x0c,0xd0,0x03,0xfc,0x00,0xc9,0x90,0x3f,0x68,0x1e,0x91,0x03,0x34,0x00 }}, - {16, 0xa510, 0, {0xfd,0x00,0x3e,0x68,0x0c,0x94,0x03,0x0e,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa520, 0, {0x39,0x10,0xe0,0x00,0xb8,0x42,0x2e,0x09,0x0b,0x84,0x02,0xe1,0x04,0xbe,0x00,0x2e }}, - {16, 0xa530, 0, {0x10,0x08,0x80,0x22,0xc2,0x80,0x88,0x40,0x22,0x00,0x0a,0x80,0x02,0xe0,0x00,0xa8 }}, - {16, 0xa540, 0, {0xd0,0x2e,0x10,0x4b,0x8a,0x03,0x60,0x00,0xba,0x00,0x2e,0x30,0x08,0x8a,0x02,0x86 }}, - {16, 0xa550, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xc5,0x80,0xb1,0x60,0x6c,0xd0 }}, - {16, 0xa560, 0, {0x0b,0x10,0x00,0xdc,0x0c,0xb5,0x00,0x2c,0x41,0x08,0x10,0x02,0xc5,0x80,0x91,0x10 }}, - {16, 0xa570, 0, {0x68,0xc0,0x08,0x30,0x02,0xe4,0x0c,0x81,0x22,0x2c,0x50,0x08,0x10,0x42,0x04,0x00 }}, - {16, 0xa580, 0, {0xa1,0x00,0x2c,0x5a,0x28,0x90,0x02,0x52,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa590, 0, {0x18,0x15,0xa4,0x00,0xb9,0x00,0x2e,0x41,0x0b,0x90,0x12,0xf4,0x80,0xbf,0x00,0x2e }}, - {16, 0xa5a0, 0, {0x40,0x08,0x90,0x02,0xe4,0x00,0xa9,0x60,0x60,0x42,0x0a,0x94,0x12,0xe5,0x00,0xa9 }}, - {16, 0xa5b0, 0, {0x00,0x2e,0x40,0x0b,0x90,0x02,0x64,0x20,0xb9,0x00,0x0e,0x40,0x09,0x90,0x02,0xc6 }}, - {16, 0xa5c0, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe4,0x00,0xf9,0x00,0x3e,0x41 }}, - {16, 0xa5d0, 0, {0x0f,0x90,0x23,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0c,0x90,0x03,0xe4,0x04,0xd1,0xc0 }}, - {16, 0xa5e0, 0, {0xba,0x70,0x0c,0x98,0x03,0xc4,0x00,0xc9,0x00,0x3e,0x40,0x0e,0x90,0x03,0x25,0x40 }}, - {16, 0xa5f0, 0, {0xe9,0x40,0x3e,0x40,0x0c,0x10,0x03,0x68,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa600, 0, {0x68,0x01,0xa4,0x14,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x23,0xe4,0x08,0xf9,0xa0,0x3c }}, - {16, 0xa610, 0, {0xc2,0x2f,0x90,0x03,0xc4,0x00,0xd9,0x80,0x3e,0x70,0x0f,0x91,0x43,0xe4,0x00,0xf9 }}, - {16, 0xa620, 0, {0x00,0x3e,0x40,0x1f,0x90,0x13,0xe6,0x20,0xf9,0xa0,0x3c,0x40,0x4e,0x90,0x03,0x9a }}, - {16, 0xa630, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf8,0x00,0x3e,0x02 }}, - {16, 0xa640, 0, {0x0f,0x80,0x13,0x20,0x0c,0xfc,0x01,0x3e,0x00,0x0c,0x80,0x03,0xe0,0x00,0xc8,0x50 }}, - {16, 0xa650, 0, {0x32,0x00,0x0f,0x80,0x0b,0x20,0x08,0xf8,0x00,0x32,0x00,0x2c,0x80,0x43,0xe0,0x40 }}, - {16, 0xa660, 0, {0xf8,0x02,0x3a,0x00,0x8f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa670, 0, {0xa8,0x85,0x28,0x08,0x3a,0x00,0x0f,0x80,0x4b,0xa1,0x02,0x28,0x00,0xba,0x82,0x2e }}, - {16, 0xa680, 0, {0x88,0x48,0xe4,0x02,0xe8,0x00,0xae,0x90,0xa3,0x90,0x0b,0xe0,0x00,0x38,0x00,0xba }}, - {16, 0xa690, 0, {0x00,0x37,0xa0,0x08,0xa0,0x02,0xf8,0x00,0x9e,0xe0,0x22,0x80,0x0b,0xa0,0x23,0x42 }}, - {16, 0xa6a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x10,0x33,0x00,0x2c,0xd0 }}, - {16, 0xa6b0, 0, {0x0b,0x14,0x02,0x0c,0x00,0xb2,0x91,0x2c,0xd0,0x08,0x3e,0x02,0x4c,0x00,0x83,0x40 }}, - {16, 0xa6c0, 0, {0x24,0xc2,0x0b,0x36,0x00,0x8c,0x00,0xb3,0x00,0x20,0xc0,0x09,0xb0,0x02,0xce,0x00 }}, - {16, 0xa6d0, 0, {0xb3,0xcc,0x68,0xc0,0x0b,0x30,0x02,0x02,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa6e0, 0, {0xe0,0x01,0x1c,0x88,0xb7,0x25,0x2d,0xc0,0x8b,0x58,0x1a,0x1c,0x08,0xb6,0x00,0x2d }}, - {16, 0xa6f0, 0, {0xc0,0x08,0x74,0x02,0xdc,0x40,0xa5,0x00,0x25,0xc0,0x1b,0x78,0x02,0x94,0x08,0xb7 }}, - {16, 0xa700, 0, {0x80,0x25,0xe3,0x0a,0x71,0x02,0xdc,0x00,0x97,0x83,0x21,0xc8,0x8b,0xf1,0x02,0x48 }}, - {16, 0xa710, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1f,0x00,0xf7,0xe2,0x7d,0xe0 }}, - {16, 0xa720, 0, {0x0f,0x58,0x43,0x1e,0x18,0xf6,0x80,0x7c,0xe0,0x2c,0x68,0x02,0x5e,0x90,0xc3,0x80 }}, - {16, 0xa730, 0, {0x35,0xe0,0x0f,0xf8,0x03,0x9e,0x04,0xff,0xa1,0x20,0xa1,0x0d,0x78,0x03,0xd6,0x00 }}, - {16, 0xa740, 0, {0xf7,0x80,0x39,0xf8,0x0f,0x78,0x03,0x0a,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa750, 0, {0x48,0x1d,0xac,0x00,0xfb,0x40,0x7f,0x41,0x0f,0x10,0x03,0xec,0x04,0xfa,0x00,0x3e }}, - {16, 0xa760, 0, {0xd0,0x0f,0xa0,0x03,0xed,0x00,0xe9,0x00,0x2a,0x00,0x0f,0xb0,0x03,0x64,0x00,0xfb }}, - {16, 0xa770, 0, {0x40,0x3e,0xc0,0x0d,0xb0,0x03,0xe4,0x00,0xd3,0x00,0x36,0xc0,0x0f,0x38,0x03,0xc2 }}, - {16, 0xa780, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x48,0xcf,0xc0,0x33,0x60 }}, - {16, 0xa790, 0, {0x8c,0xc8,0x43,0xd6,0x00,0xcc,0x94,0x3f,0xb0,0x0d,0xf8,0x03,0x7f,0x00,0xdf,0x80 }}, - {16, 0xa7a0, 0, {0x3f,0x60,0x0f,0xd8,0x03,0xde,0x00,0xcf,0xca,0x3d,0x60,0x0c,0xf8,0x13,0x3a,0x44 }}, - {16, 0xa7b0, 0, {0xdd,0x80,0x3f,0xe0,0x0f,0xf8,0x43,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa7c0, 0, {0xa8,0x11,0x9c,0x00,0x8f,0x11,0x33,0xc0,0x48,0x41,0x12,0xc4,0x48,0x84,0x11,0x2c }}, - {16, 0xa7d0, 0, {0xec,0x2a,0xba,0x03,0x3c,0x40,0xd7,0x48,0x2d,0x41,0x0b,0x60,0x02,0xd4,0x00,0xd7 }}, - {16, 0xa7e0, 0, {0x01,0x3d,0xc0,0x0d,0xf0,0x03,0x5a,0x00,0x84,0x18,0x2d,0xc0,0x0b,0x70,0x03,0x6a }}, - {16, 0xa7f0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x8c,0x08,0x87,0x00,0x21,0x40 }}, - {16, 0xa800, 0, {0x09,0x40,0x02,0xd4,0x00,0xa4,0x92,0x2d,0xc8,0x09,0x62,0x82,0x5c,0x00,0x87,0x00 }}, - {16, 0xa810, 0, {0x2d,0xc0,0x0b,0x50,0x02,0xfc,0x00,0x87,0x00,0x2d,0x04,0x08,0x70,0x02,0x1c,0x80 }}, - {16, 0xa820, 0, {0xb5,0x00,0x2d,0xc0,0x0b,0xf0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa830, 0, {0x60,0x10,0xcc,0x00,0x83,0x00,0x20,0x40,0x09,0x00,0x22,0xc7,0x00,0xa0,0x41,0x2c }}, - {16, 0xa840, 0, {0xc1,0x4b,0x08,0x02,0x2c,0x00,0x93,0x40,0x2c,0x7c,0x0b,0x38,0x02,0xc7,0x20,0x93 }}, - {16, 0xa850, 0, {0x00,0x2c,0xc0,0x09,0x30,0x02,0x4f,0x84,0xb0,0x80,0x2c,0xc0,0x0b,0x32,0x10,0x50 }}, - {16, 0xa860, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x15,0xbc,0x02,0xcf,0x00,0xb2,0x40 }}, - {16, 0xa870, 0, {0x0d,0x10,0x03,0xe8,0x24,0xeb,0xc1,0x3e,0xc0,0x2d,0x98,0x13,0x7c,0x0a,0xc2,0x43 }}, - {16, 0xa880, 0, {0x3e,0xb0,0x0f,0xa9,0x03,0xe9,0x20,0xcf,0x00,0x3e,0xc0,0x8c,0xf0,0x03,0x0d,0x20 }}, - {16, 0xa890, 0, {0xfa,0xc0,0x3f,0xc0,0x0f,0x74,0x01,0x2a,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa8a0, 0, {0x80,0x00,0xec,0x00,0xfb,0x02,0x3a,0x40,0x8e,0x90,0x03,0xe8,0x14,0x5b,0x50,0x3c }}, - {16, 0xa8b0, 0, {0x50,0x4e,0x84,0x03,0xec,0x00,0xf8,0x40,0x3e,0x80,0x07,0x81,0x03,0xec,0x08,0xf3 }}, - {16, 0xa8c0, 0, {0x00,0x3a,0xc0,0x9f,0x30,0x03,0xec,0x00,0xcb,0x20,0x3e,0xc0,0x0f,0xb0,0x23,0xe8 }}, - {16, 0xa8d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x90,0xfc,0x00,0xff,0x00,0x3f,0x40 }}, - {16, 0xa8e0, 0, {0x0f,0xd0,0x03,0x38,0x20,0xcf,0x08,0x32,0xc1,0x0e,0xd0,0x03,0xfc,0x00,0xfe,0x08 }}, - {16, 0xa8f0, 0, {0x31,0xe5,0x0e,0xe4,0x03,0x3a,0x00,0xff,0x00,0x33,0x80,0x0f,0xf0,0x2b,0x24,0x00 }}, - {16, 0xa900, 0, {0xcc,0xa0,0x3f,0xc0,0x0f,0xf0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa910, 0, {0x80,0x04,0x6c,0x00,0xbb,0x00,0x3a,0x69,0x0b,0x90,0x6e,0x08,0x00,0x83,0x41,0x36 }}, - {16, 0xa920, 0, {0x40,0xc8,0x88,0xc6,0xec,0x00,0x88,0x40,0x36,0x80,0x0d,0xa8,0x03,0x6e,0x50,0xbb }}, - {16, 0xa930, 0, {0x00,0x36,0xc0,0x0b,0xb0,0x02,0x24,0x00,0xd9,0x08,0x2e,0xc0,0x0b,0xb0,0x03,0xe0 }}, - {16, 0xa940, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xbb,0x00,0x2e,0x60 }}, - {16, 0xa950, 0, {0x03,0x80,0x02,0x20,0x00,0x89,0x01,0x22,0x58,0x08,0x98,0x22,0xec,0x01,0xab,0x00 }}, - {16, 0xa960, 0, {0x22,0x00,0x0a,0x10,0x02,0x28,0x00,0xbb,0x00,0x22,0x40,0x0b,0xb0,0x02,0x28,0x00 }}, - {16, 0xa970, 0, {0x8a,0x00,0x2e,0xc0,0x0b,0xb0,0x42,0x20,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa980, 0, {0x08,0x04,0x0c,0x00,0xb3,0x00,0x28,0x40,0x8b,0x00,0x02,0x02,0x40,0x89,0x01,0x24 }}, - {16, 0xa990, 0, {0xd2,0x28,0x10,0x02,0xcc,0x00,0x83,0x10,0x24,0x20,0x08,0x08,0x02,0x4e,0x00,0xb3 }}, - {16, 0xa9a0, 0, {0x04,0xa0,0xc0,0x0b,0x30,0x02,0x08,0x88,0x92,0x00,0x2c,0xc0,0x0b,0xb0,0x02,0xc2 }}, - {16, 0xa9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xff,0x00,0x3e,0x00 }}, - {16, 0xa9c0, 0, {0x0f,0x80,0x02,0x20,0x10,0x89,0x50,0x22,0xd8,0x2e,0x96,0x22,0xfc,0x00,0xeb,0x40 }}, - {16, 0xa9d0, 0, {0x32,0xc0,0x0a,0x90,0x03,0x28,0x00,0xff,0x00,0x22,0x00,0x0f,0xb0,0x03,0x2c,0xa0 }}, - {16, 0xa9e0, 0, {0xc8,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x00,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa9f0, 0, {0xa0,0x19,0xfc,0x00,0xff,0x0c,0x3b,0x00,0x0f,0xc0,0x02,0x70,0x90,0xfd,0x00,0x3e }}, - {16, 0xaa00, 0, {0xc9,0x0f,0x96,0xc3,0xfc,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x04,0xff }}, - {16, 0xaa10, 0, {0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xec,0x00,0xfc,0x00,0x3f,0xc0,0x0f,0x70,0x03,0xe8 }}, - {16, 0xaa20, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xdc,0x80,0xfb,0x28,0x3f,0x00 }}, - {16, 0xaa30, 0, {0x0c,0xc1,0x0b,0xf1,0x02,0xed,0x00,0x37,0x30,0x2c,0xf1,0x03,0xb2,0x40,0xff,0x00 }}, - {16, 0xaa40, 0, {0xbb,0xc0,0x0f,0x48,0x06,0xb2,0x00,0xfc,0x80,0x3b,0xcc,0x0c,0xf0,0x03,0x70,0x80 }}, - {16, 0xaa50, 0, {0xdf,0x28,0x33,0x04,0x0f,0xf4,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaa60, 0, {0x80,0x10,0xff,0x40,0xbf,0x60,0x2e,0x21,0x08,0x82,0x02,0x20,0x00,0xa9,0x28,0x2a }}, - {16, 0xaa70, 0, {0x00,0x09,0xfa,0x02,0x20,0x00,0xbf,0x51,0x23,0xd8,0x09,0x98,0x02,0xe4,0x30,0xb0 }}, - {16, 0xaa80, 0, {0x00,0x23,0xd0,0x08,0xf5,0xa2,0x25,0xa4,0x8f,0x42,0x3c,0x10,0x0b,0xb0,0x0a,0x20 }}, - {16, 0xaa90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0xb3,0x08,0x2c,0x00 }}, - {16, 0xaaa0, 0, {0x28,0x00,0x1a,0xc0,0x84,0x20,0x00,0x24,0xc8,0x4b,0x31,0x42,0xc0,0x00,0x93,0x02 }}, - {16, 0xaab0, 0, {0x20,0xc6,0x08,0x00,0x06,0xc0,0x81,0xb3,0x00,0x2c,0xd8,0x09,0x32,0x02,0xa0,0x40 }}, - {16, 0xaac0, 0, {0x93,0x01,0x24,0x4c,0x0b,0x32,0x02,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaad0, 0, {0xc0,0x11,0xac,0x00,0xbb,0x02,0x2e,0x0a,0x08,0x80,0x82,0x60,0x00,0xa8,0x00,0x2e }}, - {16, 0xaae0, 0, {0xe0,0x1b,0xb0,0x02,0x62,0x01,0x3b,0x00,0x22,0xc1,0x09,0x90,0x02,0xe2,0x00,0xbb }}, - {16, 0xaaf0, 0, {0x60,0x26,0xc1,0x08,0xb0,0x2a,0x26,0x00,0x9b,0x04,0x2e,0x21,0x0b,0xb0,0x02,0x30 }}, - {16, 0xab00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xec,0x10,0xfb,0x00,0x3e,0x10 }}, - {16, 0xab10, 0, {0x08,0x84,0x13,0xec,0x02,0xa9,0x04,0x36,0x20,0x0f,0xb0,0x03,0xee,0x80,0xfb,0x00 }}, - {16, 0xab20, 0, {0x3a,0xc0,0x0c,0xa0,0x03,0xa2,0x80,0x79,0x40,0x1e,0xc0,0x8c,0xb0,0x63,0x6a,0x10 }}, - {16, 0xab30, 0, {0xd3,0x00,0x36,0xa2,0x07,0xb0,0x03,0x00,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xab40, 0, {0xe0,0x01,0xbc,0x00,0xff,0x00,0x3e,0x20,0x4d,0x41,0x03,0x9c,0x00,0xfd,0x20,0xab }}, - {16, 0xab50, 0, {0x00,0x0c,0xf0,0x03,0xb8,0x00,0xf7,0x00,0x3f,0xc0,0x4d,0xc9,0x03,0xf4,0x00,0xff }}, - {16, 0xab60, 0, {0x00,0x3b,0xc0,0x2e,0xf0,0x00,0xf0,0x00,0xef,0x00,0x3f,0x00,0x4b,0x70,0x03,0xf8 }}, - {16, 0xab70, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x80,0xeb,0x00,0x7e,0x10 }}, - {16, 0xab80, 0, {0x2e,0x84,0x03,0xec,0x00,0xe0,0x00,0x32,0x50,0x0f,0xb0,0x86,0x25,0x00,0xdb,0x20 }}, - {16, 0xab90, 0, {0x3a,0xc0,0x0d,0xb0,0x63,0xe1,0x10,0xfb,0x48,0x38,0xc1,0x0f,0x30,0x03,0x2c,0x04 }}, - {16, 0xaba0, 0, {0xfb,0x08,0x32,0xc0,0x0c,0xb0,0x0b,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xabb0, 0, {0xc8,0x05,0x3c,0x00,0x8f,0x00,0x64,0x29,0x28,0x80,0x03,0xec,0x02,0xe8,0x04,0xa8 }}, - {16, 0xabc0, 0, {0x56,0x08,0xfc,0x07,0xe0,0x00,0x0f,0xa0,0xbf,0xc0,0x0b,0x95,0x02,0xa0,0x00,0xbb }}, - {16, 0xabd0, 0, {0x05,0x37,0xc0,0x89,0xf0,0x0a,0x0d,0xc8,0xbf,0x08,0x2a,0x80,0x08,0xf0,0x02,0x32 }}, - {16, 0xabe0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x01,0xb3,0x02,0x24,0xe0 }}, - {16, 0xabf0, 0, {0x0a,0x30,0x12,0x80,0x03,0xa3,0x00,0xa8,0x00,0x02,0xb8,0x22,0xc0,0x00,0xb3,0x00 }}, - {16, 0xac00, 0, {0x28,0xc1,0x0b,0x04,0x02,0x08,0x00,0xb9,0x40,0x28,0xc0,0x0b,0x30,0x02,0x03,0x04 }}, - {16, 0xac10, 0, {0xb3,0x44,0x20,0x00,0x4a,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xac20, 0, {0x20,0x01,0x1e,0x20,0x17,0xa0,0x65,0xec,0x08,0x38,0x02,0xc2,0x41,0xb3,0x92,0x2b }}, - {16, 0xac30, 0, {0x64,0x0a,0x38,0x02,0x36,0x01,0xb7,0x90,0x2d,0xe0,0x03,0xf8,0x00,0x9a,0x00,0xb5 }}, - {16, 0xac40, 0, {0x80,0x2d,0xe0,0x89,0x78,0x12,0x1e,0x00,0xb7,0x80,0x29,0xe0,0x0a,0x78,0x02,0x08 }}, - {16, 0xac50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x73,0xb0,0x24,0xc8 }}, - {16, 0xac60, 0, {0x4e,0x30,0x0a,0x80,0x02,0xe2,0x00,0x38,0x94,0x0e,0x31,0xa2,0xc8,0x00,0x73,0x00 }}, - {16, 0xac70, 0, {0x18,0xc4,0x05,0x00,0x03,0x00,0x00,0xf3,0x00,0x38,0xc0,0x07,0xb1,0x03,0x00,0x00 }}, - {16, 0xac80, 0, {0xf3,0x01,0x30,0x41,0x0e,0xb0,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xac90, 0, {0x40,0x1d,0xbd,0x00,0xef,0x10,0x26,0xc8,0x03,0xb1,0x03,0xe0,0x00,0xea,0x81,0x78 }}, - {16, 0xaca0, 0, {0xc5,0x0c,0xb5,0xe3,0xdc,0x00,0xc3,0x00,0x3e,0xc1,0x0f,0xf0,0x83,0xb0,0x00,0xff }}, - {16, 0xacb0, 0, {0x00,0x37,0xc0,0x0d,0xf4,0x03,0xe4,0x00,0xf7,0x00,0x3f,0x40,0x0d,0xf0,0x03,0xd0 }}, - {16, 0xacc0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xed,0x10,0xcb,0x28,0x3e,0xc0 }}, - {16, 0xacd0, 0, {0x0d,0xb0,0x13,0xac,0x10,0xfb,0x00,0x3a,0x80,0x04,0xb4,0x03,0xac,0x00,0xfb,0x04 }}, - {16, 0xace0, 0, {0x3e,0xc0,0x0f,0xa4,0xb3,0xe0,0x00,0xfb,0x80,0x32,0xc0,0x0f,0xb0,0x03,0xe8,0x00 }}, - {16, 0xacf0, 0, {0xfb,0x48,0xb2,0x80,0x0f,0xb0,0x43,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xad00, 0, {0x48,0x11,0x9c,0x02,0x87,0x44,0x38,0xc0,0x8d,0x30,0x02,0x4c,0x00,0xff,0x00,0x21 }}, - {16, 0xad10, 0, {0xc0,0x08,0x70,0x03,0x9c,0x00,0xb3,0x50,0x21,0xd4,0x4e,0x62,0x02,0xd0,0x00,0xbf }}, - {16, 0xad20, 0, {0x00,0x35,0xd4,0x09,0x70,0x22,0xd8,0x00,0xbf,0x22,0x21,0xc0,0x0b,0x72,0x02,0xd2 }}, - {16, 0xad30, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x40,0x87,0x80,0x2d,0xe0 }}, - {16, 0xad40, 0, {0x09,0x78,0x02,0xde,0x00,0xb6,0x80,0x29,0xa1,0x28,0x7a,0x32,0xde,0x00,0x37,0xa0 }}, - {16, 0xad50, 0, {0x25,0xe0,0x09,0x78,0x06,0xd2,0x00,0xb7,0x80,0x21,0xe8,0x0b,0x79,0x02,0xde,0x00 }}, - {16, 0xad60, 0, {0xb7,0x90,0x21,0xe0,0x0b,0x79,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xad70, 0, {0x48,0x14,0xcc,0x04,0x83,0x01,0x28,0xc0,0x89,0xb0,0x0a,0x4f,0x00,0xb2,0x00,0x20 }}, - {16, 0xad80, 0, {0xc4,0x88,0x30,0x16,0xcf,0x00,0xbb,0x04,0x20,0xc1,0x0a,0x32,0x06,0xc2,0x00,0xb3 }}, - {16, 0xad90, 0, {0x00,0x24,0xc0,0x09,0x30,0x42,0xef,0x10,0xb3,0x00,0x20,0xc0,0x0b,0x30,0x02,0xd2 }}, - {16, 0xada0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0x4a,0x00,0x3e,0x80 }}, - {16, 0xadb0, 0, {0x2d,0xa0,0x0b,0xaa,0x80,0xfe,0x00,0x2b,0x80,0x0c,0xa0,0x43,0xfb,0x30,0xfa,0x00 }}, - {16, 0xadc0, 0, {0x3e,0x80,0x0f,0xa0,0x83,0xfa,0x04,0xfe,0x18,0x22,0x80,0x0f,0xa0,0x03,0xfa,0x84 }}, - {16, 0xadd0, 0, {0xf2,0x00,0x33,0xa2,0x0f,0xa0,0x03,0xf2,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xade0, 0, {0x48,0x00,0xe0,0x00,0xf0,0x00,0x3e,0x00,0x2f,0x80,0x03,0xa0,0x20,0xfc,0x02,0x3e }}, - {16, 0xadf0, 0, {0x00,0x1f,0x84,0x03,0xa0,0x00,0xf8,0x40,0x3e,0x00,0x4f,0x80,0x01,0xe0,0x40,0xf8 }}, - {16, 0xae00, 0, {0x40,0x3e,0x00,0x0d,0x80,0x13,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xae10, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc6,0x00,0xd9,0x00,0x36,0x40 }}, - {16, 0xae20, 0, {0x0f,0x90,0x0b,0x04,0x00,0xc9,0x00,0x36,0x68,0x6c,0x94,0x03,0xe4,0x20,0xb9,0x90 }}, - {16, 0xae30, 0, {0x36,0x40,0x0c,0x94,0x03,0xe4,0x00,0x29,0x80,0x3e,0x40,0x0f,0x90,0x03,0x24,0x20 }}, - {16, 0xae40, 0, {0xc9,0x00,0x36,0x40,0x0f,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xae50, 0, {0x80,0x04,0x66,0x50,0x89,0x00,0x20,0x50,0x08,0x90,0x02,0x24,0x09,0xd9,0x00,0x20 }}, - {16, 0xae60, 0, {0x48,0x48,0x90,0x06,0xe4,0x04,0x99,0xa0,0x22,0x40,0x0d,0xb8,0x22,0x64,0x00,0x09 }}, - {16, 0xae70, 0, {0x50,0x32,0x40,0x0b,0x90,0x02,0x27,0x90,0x89,0x40,0x2a,0x40,0x0b,0x90,0x02,0xe0 }}, - {16, 0xae80, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x00,0x99,0x00,0x66,0x42 }}, - {16, 0xae90, 0, {0x0a,0xd0,0x12,0x34,0x00,0x85,0x00,0x26,0x40,0x4a,0x90,0x02,0xe4,0x01,0xb9,0x01 }}, - {16, 0xaea0, 0, {0x24,0x40,0x58,0x90,0x12,0xc4,0x00,0x29,0x40,0x2e,0x40,0x0b,0x10,0x0a,0x24,0x80 }}, - {16, 0xaeb0, 0, {0x89,0x05,0x26,0x41,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaec0, 0, {0x08,0x04,0x04,0x80,0x81,0x20,0x61,0x48,0x08,0x52,0x02,0x14,0x81,0x95,0x20,0x20 }}, - {16, 0xaed0, 0, {0x40,0x0a,0x36,0x02,0xc4,0x00,0xb1,0x20,0x00,0x48,0x41,0x10,0x42,0x44,0x01,0xa1 }}, - {16, 0xaee0, 0, {0x00,0x24,0x48,0x0b,0x12,0x12,0x04,0x80,0x81,0x20,0x28,0x48,0x0b,0x12,0x02,0xca }}, - {16, 0xaef0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xd8,0x50,0x36,0x00 }}, - {16, 0xaf00, 0, {0x0e,0x85,0x23,0x21,0x42,0x8c,0x54,0x34,0x14,0x0e,0x80,0x02,0xe1,0x40,0xf8,0x50 }}, - {16, 0xaf10, 0, {0x36,0x14,0x04,0x80,0x03,0xe1,0x44,0xe8,0x50,0x7e,0x15,0x0f,0x85,0x03,0x21,0x42 }}, - {16, 0xaf20, 0, {0x4a,0x00,0x36,0x14,0x0f,0x80,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaf30, 0, {0x98,0x1d,0xc4,0x40,0xf9,0x10,0x1e,0x44,0x4e,0x91,0x03,0xe4,0x40,0xf9,0x10,0x3f }}, - {16, 0xaf40, 0, {0xc0,0x0d,0x91,0x03,0xf4,0x00,0xd9,0x14,0x3e,0x44,0x0f,0x90,0x03,0x74,0x00,0xdd }}, - {16, 0xaf50, 0, {0x00,0x7a,0x44,0x0f,0x91,0x03,0xf4,0x40,0xf9,0x38,0x3f,0x44,0x0f,0x93,0x83,0xe7 }}, - {16, 0xaf60, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xf6,0x80,0xf9,0xa4,0x3f,0x68 }}, - {16, 0xaf70, 0, {0x0e,0x9e,0x43,0x67,0x80,0xd9,0xe4,0x3f,0x41,0x0f,0xd8,0x43,0x04,0x00,0xed,0xc0 }}, - {16, 0xaf80, 0, {0x36,0x40,0x0c,0x90,0x03,0xe4,0x00,0xd5,0x40,0x32,0x40,0x0c,0x90,0x03,0xf4,0x00 }}, - {16, 0xaf90, 0, {0xdd,0x00,0x32,0x40,0x2c,0x9a,0x03,0xc6,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xafa0, 0, {0x38,0x10,0xe0,0x00,0xe8,0xc0,0x2e,0x14,0x4d,0x8f,0x22,0x23,0xc0,0xf8,0xf0,0xaa }}, - {16, 0xafb0, 0, {0x00,0x0c,0x80,0x03,0xa2,0xa0,0xd8,0x82,0x22,0x00,0x08,0x80,0x02,0xe8,0x00,0xd8 }}, - {16, 0xafc0, 0, {0x80,0x2a,0x00,0x08,0x80,0x02,0xe8,0x08,0x88,0xa8,0x36,0x00,0x48,0x8a,0x82,0xce }}, - {16, 0xafd0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb1,0x48,0x2e,0x40 }}, - {16, 0xafe0, 0, {0x0a,0x12,0x22,0x44,0x00,0x91,0x04,0xa4,0x41,0x0a,0x94,0x06,0x24,0x00,0x91,0x42 }}, - {16, 0xaff0, 0, {0x24,0x41,0x09,0x10,0x02,0xe4,0x01,0x91,0x20,0x24,0x40,0x09,0x10,0x02,0xc4,0x01 }}, - {16, 0xb000, 0, {0x91,0x00,0x2c,0x40,0x09,0x14,0x02,0xc2,0x01,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb010, 0, {0x18,0x15,0xa4,0x00,0xa9,0x00,0x2e,0x40,0x48,0x10,0x02,0x24,0x00,0xb9,0x40,0xaa }}, - {16, 0xb020, 0, {0x40,0x18,0xb0,0x02,0xe4,0x08,0x99,0x00,0x22,0x40,0x19,0x90,0x46,0xe4,0x80,0x99 }}, - {16, 0xb030, 0, {0x04,0x2e,0x40,0x09,0x90,0x02,0xe4,0x01,0x99,0x04,0x26,0x50,0x09,0x90,0x02,0xc6 }}, - {16, 0xb040, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe4,0x00,0xf9,0x06,0x3c,0x40 }}, - {16, 0xb050, 0, {0x0a,0x90,0x03,0x64,0x02,0xd9,0x00,0xb6,0x50,0x0e,0x90,0x23,0x26,0x01,0xf9,0x00 }}, - {16, 0xb060, 0, {0x36,0x40,0x29,0x94,0x83,0xe4,0x00,0xd9,0x48,0x36,0x40,0x0d,0x90,0x03,0xc7,0x00 }}, - {16, 0xb070, 0, {0xd1,0x07,0x3a,0x50,0xcd,0x90,0x03,0xe8,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb080, 0, {0x28,0x01,0xa4,0x08,0xe9,0x00,0x3e,0x40,0x8f,0x90,0x03,0xc4,0x08,0xf1,0x00,0x3a }}, - {16, 0xb090, 0, {0x68,0x8f,0x90,0x03,0xa4,0x41,0xf9,0x00,0xbe,0x40,0x0e,0x90,0x03,0xe4,0x00,0xf9 }}, - {16, 0xb0a0, 0, {0xc0,0x38,0x40,0x2e,0x90,0x03,0xe6,0x40,0xe9,0x00,0x3e,0x68,0x06,0x90,0x03,0xca }}, - {16, 0xb0b0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xd8,0x05,0x3e,0x00 }}, - {16, 0xb0c0, 0, {0x07,0x80,0x0b,0x20,0x00,0xe8,0x40,0x3e,0x10,0x0d,0x82,0x03,0x60,0x00,0xc8,0x00 }}, - {16, 0xb0d0, 0, {0xb2,0x00,0x8d,0x83,0x03,0xe0,0x00,0xd8,0x50,0x3a,0x00,0x1e,0x80,0x03,0xe1,0x24 }}, - {16, 0xb0e0, 0, {0xf8,0x00,0xb2,0x00,0x0f,0x80,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb0f0, 0, {0x28,0x05,0x38,0x00,0x8a,0x04,0x2f,0x84,0x6a,0xa0,0x0b,0xe8,0x08,0x8e,0x00,0x3d }}, - {16, 0xb100, 0, {0x80,0x88,0xec,0x03,0x68,0x10,0xa6,0x01,0x36,0x80,0x08,0xa8,0x00,0xc8,0x10,0x8e }}, - {16, 0xb110, 0, {0x10,0x22,0x80,0x08,0xa0,0x02,0xfb,0x20,0xbe,0x51,0x2a,0x80,0x0b,0xa0,0x02,0x82 }}, - {16, 0xb120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x41,0x21,0x93,0x00,0x2c,0xf0 }}, - {16, 0xb130, 0, {0x39,0x30,0x06,0x0c,0x00,0xa3,0x00,0x28,0x08,0x28,0xbc,0x02,0x2c,0x00,0x83,0x80 }}, - {16, 0xb140, 0, {0x2a,0xc0,0x08,0x30,0x00,0xcc,0x00,0x9a,0x80,0x28,0xc0,0x0a,0x30,0x02,0xcd,0x00 }}, - {16, 0xb150, 0, {0xb3,0x04,0x62,0xc1,0x0b,0x30,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb160, 0, {0xa0,0x01,0x1e,0x04,0x07,0x11,0x2c,0xd0,0x0a,0x32,0x22,0xdc,0xc1,0x87,0x00,0x6d }}, - {16, 0xb170, 0, {0xd0,0x08,0x34,0x02,0x7c,0x00,0xa7,0x08,0x24,0xc8,0x08,0x70,0x02,0xdc,0x80,0x0f }}, - {16, 0xb180, 0, {0x00,0x21,0xc4,0x08,0x73,0x06,0xdc,0x00,0xb2,0x00,0x61,0xc8,0x0b,0x3a,0x02,0x88 }}, - {16, 0xb190, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x0a,0x00,0x57,0x81,0x2d,0xa0 }}, - {16, 0xb1a0, 0, {0x2d,0x7c,0x02,0x3e,0x82,0xe3,0xe0,0x3b,0xe0,0x0c,0x78,0x03,0x1e,0x20,0xc7,0x80 }}, - {16, 0xb1b0, 0, {0xb9,0xe8,0x2c,0x78,0x03,0xff,0x80,0xd6,0x80,0x3b,0xec,0x02,0x7a,0x03,0xde,0x00 }}, - {16, 0xb1c0, 0, {0xf7,0x81,0x31,0xec,0x8f,0x7c,0x03,0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb1d0, 0, {0x08,0x1d,0xac,0x00,0xfb,0x00,0x1e,0x80,0x23,0xb6,0x83,0xed,0xa0,0xdb,0x64,0x3e }}, - {16, 0xb1e0, 0, {0xc0,0x0e,0xb0,0x03,0xed,0xc0,0xf2,0x00,0x3e,0xd4,0x0a,0xb0,0x03,0xec,0x30,0xee }}, - {16, 0xb1f0, 0, {0x64,0x3e,0xc0,0x07,0xb0,0xc3,0xe8,0x00,0xfb,0x01,0x3e,0xc8,0x0f,0xb8,0x03,0xc2 }}, - {16, 0xb200, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xef,0x80,0x3b,0xe0 }}, - {16, 0xb210, 0, {0x0f,0xf8,0x63,0x7e,0x04,0xcf,0xc0,0xb7,0x20,0x0e,0xf8,0x03,0xfc,0x00,0xc7,0x80 }}, - {16, 0xb220, 0, {0x33,0xf0,0x0c,0xcc,0x03,0xfe,0x08,0xf7,0xc1,0x33,0xe0,0x4f,0xf8,0x03,0xb2,0x40 }}, - {16, 0xb230, 0, {0xff,0xa0,0x31,0xe6,0x0c,0xf8,0x03,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb240, 0, {0xa8,0x11,0x9c,0x00,0xef,0x02,0x21,0x40,0x2d,0x70,0x02,0x1c,0x00,0xf7,0x10,0x29 }}, - {16, 0xb250, 0, {0x40,0x08,0x70,0x22,0xfc,0xc0,0xa7,0x00,0x3d,0xc0,0x08,0x40,0x02,0xdc,0x00,0xb7 }}, - {16, 0xb260, 0, {0x40,0x21,0xc0,0x0b,0x70,0x02,0xda,0x80,0xb7,0x24,0x29,0xc6,0x48,0xf0,0x02,0x2a }}, - {16, 0xb270, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa7,0x00,0x28,0x84 }}, - {16, 0xb280, 0, {0x0b,0x30,0x02,0x0c,0x00,0x93,0x00,0x25,0x80,0x0a,0x61,0x02,0xdc,0x01,0xa7,0x10 }}, - {16, 0xb290, 0, {0x24,0xc0,0x08,0x40,0x82,0xdc,0x00,0x9f,0x00,0x25,0xc4,0x0b,0x70,0x02,0x94,0x25 }}, - {16, 0xb2a0, 0, {0xb7,0x32,0x23,0xc4,0x1b,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb2b0, 0, {0x20,0x14,0xcc,0x0c,0xa3,0x00,0x20,0x00,0x29,0x30,0x0a,0x0c,0x00,0xa3,0x00,0x6c }}, - {16, 0xb2c0, 0, {0x00,0x08,0x10,0x42,0xcd,0x10,0xaa,0x00,0xac,0xc0,0x00,0x04,0x02,0xcd,0x00,0xbb }}, - {16, 0xb2d0, 0, {0x10,0x24,0xc0,0x03,0x30,0x42,0xc3,0x09,0xb3,0x00,0x2c,0xd0,0x0a,0x30,0x02,0x18 }}, - {16, 0xb2e0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x80,0x00,0xef,0x00,0x3a,0x40 }}, - {16, 0xb2f0, 0, {0x07,0xf0,0x43,0x3c,0x00,0x9f,0xc0,0xb6,0x14,0x0e,0x80,0x06,0xfc,0x01,0xcb,0x01 }}, - {16, 0xb300, 0, {0x37,0xc0,0xac,0xb4,0x02,0xfc,0x00,0xd9,0x01,0x37,0xc0,0x4b,0xf0,0x13,0xae,0x08 }}, - {16, 0xb310, 0, {0xfb,0x00,0x33,0xd0,0x2e,0xf0,0x0b,0x2a,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb320, 0, {0x80,0x00,0xec,0x00,0xfb,0x05,0x3e,0x40,0x0f,0x30,0x03,0xac,0x14,0xfb,0xa0,0x3a }}, - {16, 0xb330, 0, {0xc0,0x0f,0x84,0x43,0xec,0x01,0xf9,0x40,0x3e,0xc0,0x0f,0xa2,0x03,0xec,0x21,0xf9 }}, - {16, 0xb340, 0, {0x00,0x3a,0xc0,0x0f,0xb0,0x03,0xe4,0x20,0xf0,0x00,0xba,0xc0,0x0d,0xb0,0x03,0xe0 }}, - {16, 0xb350, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf8,0x00,0xd7,0x01,0x35,0x68 }}, - {16, 0xb360, 0, {0x6d,0xf0,0x03,0x3c,0x01,0xe7,0x00,0x33,0xc0,0x0d,0xc0,0x03,0xfc,0x24,0xcf,0x02 }}, - {16, 0xb370, 0, {0x37,0xc0,0x0d,0xd2,0x02,0xfc,0x00,0xdf,0x01,0x33,0xc0,0x5e,0x70,0x33,0x1c,0x18 }}, - {16, 0xb380, 0, {0xcf,0x41,0x31,0xc2,0x0c,0xf0,0x03,0x40,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb390, 0, {0x81,0x00,0x6c,0x00,0x8b,0x00,0x22,0x52,0x2a,0xb0,0x03,0x6c,0x00,0xab,0x00,0x28 }}, - {16, 0xb3a0, 0, {0xc0,0x0a,0x8c,0x02,0xec,0x10,0x8b,0xe0,0x22,0xc0,0x0f,0x80,0x02,0xcc,0x00,0x8b }}, - {16, 0xb3b0, 0, {0x80,0x22,0xc0,0x08,0xb0,0x02,0x2a,0x10,0xd9,0x80,0x22,0xc0,0xc8,0xb0,0x02,0xe0 }}, - {16, 0xb3c0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x24,0x01,0x9b,0x00,0x26,0x80 }}, - {16, 0xb3d0, 0, {0x29,0xb0,0x62,0x0c,0x00,0xab,0x01,0x6a,0x00,0x08,0x98,0x02,0xcc,0x00,0x9b,0x83 }}, - {16, 0xb3e0, 0, {0x2e,0xc0,0xcb,0xb4,0x12,0xec,0x03,0x8b,0x80,0x28,0xc0,0x0a,0xb0,0x06,0xa2,0x00 }}, - {16, 0xb3f0, 0, {0x8b,0x02,0x62,0xc0,0x08,0xb0,0x02,0xe0,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb400, 0, {0x08,0x04,0x0c,0x01,0x83,0x14,0x20,0x00,0x0a,0x30,0x02,0x4c,0x00,0x83,0x00,0x2a }}, - {16, 0xb410, 0, {0x40,0x0a,0x10,0x00,0xcc,0x02,0x93,0x00,0x28,0xc0,0x0a,0x20,0x02,0xec,0x00,0x03 }}, - {16, 0xb420, 0, {0x00,0x20,0xc0,0x08,0x30,0x16,0x00,0x80,0x91,0x00,0x60,0xc0,0x08,0x30,0x02,0xc2 }}, - {16, 0xb430, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xdb,0x00,0x36,0x80 }}, - {16, 0xb440, 0, {0x2d,0xf0,0x03,0x3c,0x00,0xaf,0x00,0x3a,0x80,0x0d,0x80,0x03,0xfc,0x00,0x5b,0x00 }}, - {16, 0xb450, 0, {0x37,0xc0,0x09,0x90,0x03,0xfc,0x00,0xdf,0x00,0x33,0xc0,0x0a,0xf0,0x03,0xa4,0x20 }}, - {16, 0xb460, 0, {0xcb,0x00,0xb3,0xc0,0x8c,0xb0,0x03,0x40,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb470, 0, {0xa0,0x1d,0xfc,0x04,0xff,0x20,0x0f,0x00,0x27,0xf0,0x03,0xfc,0x00,0xff,0x00,0x2d }}, - {16, 0xb480, 0, {0x00,0x0b,0xd0,0x27,0xfc,0x00,0xef,0x00,0x37,0xc0,0x0f,0xc0,0x43,0xfc,0x00,0xff }}, - {16, 0xb490, 0, {0x00,0x3f,0xc0,0x0d,0xf0,0x0b,0xe0,0x00,0xf5,0x00,0x3f,0xc0,0x1f,0xf0,0x03,0xe8 }}, - {16, 0xb4a0, 0, {0x07,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf4,0xc0,0xfc,0x22,0x7f,0xc0 }}, - {16, 0xb4b0, 0, {0x0c,0xd0,0x43,0x36,0x00,0xc4,0x81,0x34,0xc0,0x1c,0x89,0x07,0xf2,0x80,0xcf,0x80 }}, - {16, 0xb4c0, 0, {0x33,0x60,0x0f,0x79,0x03,0x3c,0xe0,0xcf,0x08,0x33,0x48,0x0d,0xc4,0x03,0xf0,0x50 }}, - {16, 0xb4d0, 0, {0xdc,0x90,0x37,0xcc,0x0f,0xf8,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb4e0, 0, {0x80,0x10,0xe9,0x90,0xb8,0x80,0x7e,0xe4,0x88,0x99,0x0a,0x26,0x08,0xa9,0x80,0x22 }}, - {16, 0xb4f0, 0, {0xf4,0x2c,0x99,0x03,0xa7,0x02,0x89,0x80,0x22,0x34,0x0b,0x9a,0x03,0x7d,0x00,0xdf }}, - {16, 0xb500, 0, {0x48,0x2b,0x60,0x08,0x05,0x02,0xe5,0x00,0x82,0x20,0x22,0xc4,0x8b,0xb0,0x02,0xe0 }}, - {16, 0xb510, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc5,0x00,0xb0,0x10,0x2c,0xc0 }}, - {16, 0xb520, 0, {0x2a,0x00,0x02,0xa4,0x08,0xa8,0x04,0xe0,0x80,0x0b,0x00,0x02,0xc4,0x41,0xb2,0x04 }}, - {16, 0xb530, 0, {0xa4,0x0a,0x0b,0xb0,0x02,0x8c,0x81,0x83,0x20,0x60,0x50,0x98,0x12,0x12,0x8b,0x80 }}, - {16, 0xb540, 0, {0x89,0x00,0x2c,0xc8,0x0b,0x30,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb550, 0, {0xc0,0x11,0xac,0x20,0xbb,0x02,0x2a,0xc0,0x0a,0x88,0x02,0xa4,0x08,0xa9,0x80,0xa2 }}, - {16, 0xb560, 0, {0xe1,0x1b,0x9c,0x22,0xe6,0x00,0xb8,0x40,0x26,0x30,0x0b,0x90,0x02,0xcc,0x01,0x93 }}, - {16, 0xb570, 0, {0x04,0x2a,0x40,0x39,0x98,0x82,0xec,0x14,0x8b,0x65,0x2a,0xc0,0x0b,0xb2,0x02,0xf8 }}, - {16, 0xb580, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe7,0x00,0xb8,0x48,0x2e,0x00 }}, - {16, 0xb590, 0, {0x0e,0x88,0x43,0x84,0x00,0xe3,0xc1,0x36,0xe8,0x0f,0x9c,0x12,0xe2,0x80,0xf3,0xc0 }}, - {16, 0xb5a0, 0, {0x36,0x70,0x5f,0xa8,0x23,0xac,0x01,0xcb,0x04,0x22,0x40,0x4d,0x84,0x03,0xe2,0x00 }}, - {16, 0xb5b0, 0, {0xd8,0x00,0x3e,0xc0,0x0f,0x90,0x03,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb5c0, 0, {0xe0,0x01,0xb3,0x09,0xfe,0x10,0x3e,0x81,0x0d,0xc0,0x03,0x74,0x0c,0xff,0x00,0x3d }}, - {16, 0xb5d0, 0, {0xc1,0x8c,0xd0,0x83,0x14,0x00,0xcd,0x20,0x3a,0x40,0x0d,0xca,0x01,0x7c,0x00,0xff }}, - {16, 0xb5e0, 0, {0x00,0x1f,0x40,0x0e,0xc0,0x23,0xf2,0x46,0xfe,0x84,0x37,0xc0,0x0f,0xd8,0x03,0xf8 }}, - {16, 0xb5f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xdd,0x02,0x3d,0x40 }}, - {16, 0xb600, 0, {0x0e,0x90,0x03,0xac,0x00,0xeb,0x48,0x3e,0xd0,0x0c,0x80,0x63,0xa2,0x08,0xca,0x00 }}, - {16, 0xb610, 0, {0x32,0x08,0x0c,0xb0,0x03,0xac,0x08,0xeb,0x00,0x3e,0x40,0x0c,0xd4,0x83,0x58,0x20 }}, - {16, 0xb620, 0, {0xf9,0x42,0x32,0xc0,0x0c,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb630, 0, {0xc8,0x05,0x28,0x02,0xdb,0x00,0x2e,0xe0,0x28,0x3a,0x02,0x2e,0x00,0xdb,0x60,0x76 }}, - {16, 0xb640, 0, {0xe0,0x0d,0x8c,0x02,0xe0,0x00,0x88,0x02,0x36,0x58,0x68,0x15,0x83,0x7c,0x08,0xbf }}, - {16, 0xb650, 0, {0x00,0x2d,0x60,0x08,0x90,0x02,0xa9,0x00,0xb3,0x05,0x23,0xc0,0x08,0xb0,0x02,0xf2 }}, - {16, 0xb660, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x10,0x80,0x00,0x0c,0xc1 }}, - {16, 0xb670, 0, {0x08,0x1c,0x82,0x06,0x00,0x93,0xc0,0x20,0xf6,0x0a,0x20,0x02,0x08,0x00,0x93,0x00 }}, - {16, 0xb680, 0, {0x24,0x60,0x09,0x3c,0x02,0x0c,0x00,0x83,0x00,0x2c,0x60,0x09,0x01,0x12,0x00,0x40 }}, - {16, 0xb690, 0, {0xb0,0x00,0xe0,0xc0,0x08,0x30,0x02,0x70,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb6a0, 0, {0x20,0x41,0x0a,0x40,0x86,0x81,0x2d,0xe0,0x58,0x18,0x0a,0x16,0xa0,0x97,0x80,0x25 }}, - {16, 0xb6b0, 0, {0xe9,0x19,0x78,0x82,0xd6,0x00,0x97,0x80,0x25,0xa0,0x19,0xf8,0x02,0x5e,0x00,0xb7 }}, - {16, 0xb6c0, 0, {0x80,0x2d,0x60,0x28,0x48,0x12,0x96,0x00,0xb4,0x80,0x21,0xe0,0x28,0x78,0x02,0xc8 }}, - {16, 0xb6d0, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x81,0x30,0x3c,0xc2 }}, - {16, 0xb6e0, 0, {0x0e,0x00,0x02,0x84,0x00,0xe3,0x40,0x28,0xe8,0x4c,0x29,0x03,0x0c,0x00,0xd3,0x00 }}, - {16, 0xb6f0, 0, {0x34,0xc4,0x0d,0x31,0x03,0x8c,0x08,0xe3,0x00,0x3c,0x46,0x0c,0x20,0x03,0x00,0x80 }}, - {16, 0xb700, 0, {0xf2,0x00,0x32,0xc0,0x0c,0x30,0x03,0xd2,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb710, 0, {0x40,0x19,0xb8,0x00,0xff,0x10,0x2f,0xc0,0x0f,0xc0,0x23,0xc4,0x80,0x7f,0x10,0x3e }}, - {16, 0xb720, 0, {0xc0,0x0f,0xb1,0x03,0xdc,0x00,0xe7,0x00,0x3f,0x80,0x06,0xf1,0x43,0xfc,0x00,0xff }}, - {16, 0xb730, 0, {0x08,0x7d,0x50,0x0e,0xe1,0x23,0xb4,0x08,0xfe,0x10,0x3f,0xc4,0x0f,0xf0,0x03,0xd0 }}, - {16, 0xb740, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x02,0xcc,0x00,0x3e,0x00 }}, - {16, 0xb750, 0, {0x2c,0xc0,0x03,0x04,0x01,0xcb,0x00,0x33,0x60,0x2c,0x90,0x13,0xe8,0x00,0x73,0x00 }}, - {16, 0xb760, 0, {0xb2,0xc1,0x0f,0xa0,0x03,0xec,0x80,0xfb,0x28,0x3e,0x54,0x1f,0xd0,0x03,0xfe,0x02 }}, - {16, 0xb770, 0, {0xc9,0x80,0x32,0xc0,0x0f,0xb0,0x03,0xca,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb780, 0, {0x48,0x11,0x80,0x00,0x86,0x00,0x2d,0x80,0x08,0x20,0x02,0x14,0x08,0x87,0x00,0x29 }}, - {16, 0xb790, 0, {0x40,0x08,0x70,0x02,0xdc,0x00,0xb7,0x00,0x21,0xc0,0x0b,0x60,0x02,0x5c,0xa0,0x97 }}, - {16, 0xb7a0, 0, {0x20,0x2d,0x48,0x0b,0x50,0x02,0xdc,0x10,0x8d,0x00,0x21,0xc8,0x0b,0x70,0x02,0xd2 }}, - {16, 0xb7b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9f,0x00,0x85,0x81,0x2c,0x60 }}, - {16, 0xb7c0, 0, {0x18,0x58,0x02,0xde,0x20,0xb7,0x82,0x28,0x60,0x5a,0x78,0x52,0xde,0x10,0xbf,0x80 }}, - {16, 0xb7d0, 0, {0x21,0xe0,0x4b,0x78,0x06,0xde,0x40,0xb7,0xa0,0x2d,0x69,0x9b,0x78,0x12,0xce,0x00 }}, - {16, 0xb7e0, 0, {0x87,0x80,0xe1,0xe4,0x0b,0x78,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb7f0, 0, {0x48,0x14,0xee,0x00,0x83,0x00,0x2c,0xc2,0x08,0x36,0x02,0x8c,0x08,0x83,0xf0,0x68 }}, - {16, 0xb800, 0, {0x40,0x0a,0x3e,0x02,0xcd,0x40,0xb3,0x00,0x20,0xe0,0x0b,0x32,0x06,0x4c,0x00,0x9b }}, - {16, 0xb810, 0, {0x00,0x0c,0x40,0x0b,0x30,0x02,0xcd,0x80,0x83,0x08,0x20,0xc0,0x0b,0xb1,0x02,0xda }}, - {16, 0xb820, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xce,0x08,0x3f,0xb0 }}, - {16, 0xb830, 0, {0x0c,0xe4,0x23,0xda,0x02,0xde,0x40,0xbb,0xb2,0x0e,0xe2,0x43,0xfa,0x00,0xfe,0x00 }}, - {16, 0xb840, 0, {0x33,0x90,0x0b,0xe0,0x03,0xe8,0x00,0xfa,0x00,0x3e,0x81,0x0b,0xe0,0x13,0xf9,0x08 }}, - {16, 0xb850, 0, {0xce,0x40,0x32,0x80,0x0f,0xa8,0x03,0xfa,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb860, 0, {0x48,0x00,0xe0,0x24,0x98,0x08,0x3c,0x04,0x0f,0x00,0x0b,0x60,0x00,0xf8,0x40,0x2e }}, - {16, 0xb870, 0, {0x03,0x0d,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x06,0x0b,0x80,0x03,0xe0,0x00,0xd8 }}, - {16, 0xb880, 0, {0x00,0x3c,0x00,0x03,0x8c,0x23,0xe1,0x00,0xf8,0x00,0x7e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xb890, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x00,0x3e,0x40 }}, - {16, 0xb8a0, 0, {0x8c,0x90,0x03,0x25,0x00,0xe9,0x80,0x32,0x44,0x0f,0x94,0x02,0xe4,0x20,0xf9,0x00 }}, - {16, 0xb8b0, 0, {0x32,0x70,0x0f,0x9a,0x43,0xe4,0x00,0xf9,0x00,0x32,0x40,0x0c,0x10,0x33,0x24,0x10 }}, - {16, 0xb8c0, 0, {0xf9,0x01,0x3e,0x40,0x0f,0x90,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb8d0, 0, {0x80,0x04,0x64,0x00,0x89,0x82,0x2e,0x40,0x28,0x90,0x02,0x24,0x82,0x81,0xc0,0xa2 }}, - {16, 0xb8e0, 0, {0x70,0x0b,0x9c,0x02,0xe4,0x00,0x31,0x42,0xa2,0x60,0x0b,0x94,0x82,0xe4,0x00,0xb9 }}, - {16, 0xb8f0, 0, {0x00,0x2a,0x40,0x08,0x94,0xa2,0x25,0x00,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x0a,0x20 }}, - {16, 0xb900, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0x89,0x64,0x2e,0x40 }}, - {16, 0xb910, 0, {0x08,0x90,0x42,0xa4,0x00,0x89,0x60,0x22,0x42,0x0b,0x90,0x02,0xe6,0x00,0xb9,0x80 }}, - {16, 0xb920, 0, {0x22,0x40,0x0b,0x90,0x02,0xa4,0x04,0xb9,0x00,0x22,0x40,0x28,0x90,0x02,0x24,0x04 }}, - {16, 0xb930, 0, {0xb9,0x00,0x2e,0x40,0x0b,0x90,0x02,0x0e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb940, 0, {0x08,0x04,0x05,0x80,0x81,0x00,0x2c,0xc1,0x48,0x10,0x02,0xa4,0x02,0x81,0x00,0x20 }}, - {16, 0xb950, 0, {0x40,0x83,0x34,0x02,0xc4,0x00,0xbb,0x00,0x20,0xd0,0x0b,0x14,0x02,0xc4,0x80,0xb1 }}, - {16, 0xb960, 0, {0x20,0xa0,0x68,0x18,0x14,0x1a,0x0d,0x00,0xb1,0x40,0x2c,0x50,0x0b,0x10,0x02,0x0a }}, - {16, 0xb970, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x00,0x3e,0x00 }}, - {16, 0xb980, 0, {0x8c,0x80,0x0b,0xa0,0x04,0xe8,0x00,0x32,0x00,0x07,0x80,0x03,0xe0,0x00,0xf8,0x00 }}, - {16, 0xb990, 0, {0x32,0x00,0x1f,0x80,0x03,0xa1,0x40,0xf8,0x50,0x32,0x00,0x0c,0x80,0x03,0x20,0x00 }}, - {16, 0xb9a0, 0, {0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb9b0, 0, {0x98,0x1d,0xf4,0x46,0xfd,0x40,0x3f,0x50,0x23,0xd4,0x13,0x74,0x04,0xf5,0x02,0x3f }}, - {16, 0xb9c0, 0, {0x50,0x0f,0xd4,0x03,0xfd,0x00,0xbd,0x00,0x2f,0x50,0x0f,0xd0,0x03,0xe4,0x40,0xf9 }}, - {16, 0xb9d0, 0, {0x10,0x3f,0x44,0x0f,0xd4,0x03,0xf5,0x08,0xfd,0x06,0x3e,0x50,0x0f,0xd2,0x83,0xe6 }}, - {16, 0xb9e0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xe6,0x40,0xed,0x04,0x3e,0x48 }}, - {16, 0xb9f0, 0, {0x0c,0xb2,0x83,0xf4,0x00,0xc1,0x00,0x32,0x40,0x8c,0xd0,0x03,0x34,0x00,0xfd,0x00 }}, - {16, 0xba00, 0, {0x37,0x40,0x0f,0xd0,0x03,0xe6,0x20,0xf9,0x88,0x3d,0x62,0x0c,0xd8,0x03,0xfe,0x24 }}, - {16, 0xba10, 0, {0xc1,0x00,0x3e,0x78,0x0f,0xd0,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xba20, 0, {0x38,0x10,0xe1,0x00,0x88,0x40,0x2e,0x10,0x08,0xc4,0x23,0xa0,0x08,0x88,0x06,0x2a }}, - {16, 0xba30, 0, {0x14,0x08,0x80,0x03,0x60,0x04,0xb8,0x00,0x22,0x00,0x0b,0x80,0x02,0xe2,0x00,0xb8 }}, - {16, 0xba40, 0, {0x80,0x2e,0x00,0x08,0x8c,0x02,0xe3,0x80,0x88,0x02,0x2e,0x38,0x0b,0x88,0x02,0x0e }}, - {16, 0xba50, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x80,0xa1,0xc0,0x2d,0x70 }}, - {16, 0xba60, 0, {0x08,0x50,0x42,0xc4,0x00,0xa9,0x00,0x20,0xe0,0x2a,0x10,0x0a,0x04,0x10,0xb1,0x00 }}, - {16, 0xba70, 0, {0x24,0x40,0x4b,0x10,0x06,0xc4,0x20,0xb1,0x08,0x6e,0x40,0x0b,0x16,0x82,0xc4,0x20 }}, - {16, 0xba80, 0, {0x81,0x00,0x2c,0x50,0x0b,0x92,0x82,0x52,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xba90, 0, {0x18,0x11,0xa4,0x00,0xa9,0x01,0x2e,0x40,0x28,0xd0,0x20,0xa4,0x04,0xa9,0x00,0x2a }}, - {16, 0xbaa0, 0, {0x40,0x1a,0xb0,0x12,0x24,0x00,0xb9,0x0c,0x22,0x42,0x0b,0x94,0x02,0xe4,0x00,0xb9 }}, - {16, 0xbab0, 0, {0x00,0x6e,0x40,0x0b,0x96,0x02,0xe4,0x11,0x89,0x20,0x6e,0x40,0x0b,0x90,0x02,0x46 }}, - {16, 0xbac0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0xc0,0xa9,0xc0,0x3e,0x50 }}, - {16, 0xbad0, 0, {0x08,0x9c,0x83,0xe4,0x02,0xe9,0x00,0xb2,0x40,0x2a,0x92,0x12,0x26,0x40,0xf9,0x40 }}, - {16, 0xbae0, 0, {0x36,0x70,0x0f,0x94,0x03,0xe4,0x04,0xf9,0x01,0x3c,0x40,0x0f,0x98,0x03,0xe6,0x02 }}, - {16, 0xbaf0, 0, {0xc9,0x22,0x3e,0x40,0x0f,0x10,0x02,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbb00, 0, {0x28,0x01,0x86,0x04,0xd9,0x40,0x1c,0x40,0x0f,0x92,0x23,0xa4,0xb0,0xdb,0x04,0x3c }}, - {16, 0xbb10, 0, {0xc0,0x0d,0x9a,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x44,0x0f,0x90,0x03,0xe4,0x00,0xf9 }}, - {16, 0xbb20, 0, {0x00,0x3e,0x42,0x2c,0x90,0x23,0xe4,0x80,0xf9,0x00,0x3e,0x40,0x8f,0x92,0x03,0x92 }}, - {16, 0xbb30, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xc8,0x20,0x32,0x00 }}, - {16, 0xbb40, 0, {0x4c,0xc0,0x8b,0x20,0x02,0xc8,0x31,0x32,0x20,0x2d,0x84,0x03,0xe1,0x04,0xf8,0x48 }}, - {16, 0xbb50, 0, {0xba,0x00,0x0f,0x89,0x03,0xe0,0x00,0xc8,0x00,0x32,0x00,0x0d,0x81,0x13,0x20,0x10 }}, - {16, 0xbb60, 0, {0xf8,0x00,0x3a,0x00,0x0f,0x81,0x23,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbb70, 0, {0x28,0x05,0x28,0x00,0x0e,0x40,0x22,0x80,0x28,0xa4,0x02,0x19,0x00,0x52,0x80,0xa2 }}, - {16, 0xbb80, 0, {0x80,0x4d,0xed,0x82,0xe8,0x00,0xb6,0x42,0x23,0xbd,0x0b,0xe8,0x02,0xe8,0x04,0xda }}, - {16, 0xbb90, 0, {0x00,0x37,0x80,0x08,0xe0,0x02,0x3a,0x20,0xba,0x00,0x22,0x80,0x0b,0xa8,0x0a,0x0a }}, - {16, 0xbba0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x80,0x60,0xc0 }}, - {16, 0xbbb0, 0, {0x08,0x29,0x02,0x0d,0x00,0x92,0x40,0x24,0xc0,0x08,0xb4,0x02,0xcc,0x00,0xb3,0x00 }}, - {16, 0xbbc0, 0, {0x68,0xe0,0x1b,0x30,0x02,0xcc,0x00,0x93,0x01,0x24,0xc0,0x69,0x38,0x02,0x6c,0x00 }}, - {16, 0xbbd0, 0, {0xb3,0x00,0x2c,0xc0,0x0b,0x30,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbbe0, 0, {0xa0,0x01,0x1c,0x40,0x83,0xc0,0x20,0x40,0x08,0x28,0x06,0x9c,0x18,0x9c,0x02,0x24 }}, - {16, 0xbbf0, 0, {0xc0,0x09,0x70,0x02,0xd4,0x00,0xb7,0x00,0x21,0xc0,0x0b,0x70,0x02,0xce,0x40,0x97 }}, - {16, 0xbc00, 0, {0xb0,0x25,0x40,0x08,0x78,0x1a,0x58,0x00,0xbf,0xa2,0x65,0xc8,0x0b,0x78,0x02,0x20 }}, - {16, 0xbc10, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x0e,0x02,0x87,0x80,0xb1,0xa0 }}, - {16, 0xbc20, 0, {0x0c,0x68,0x03,0x1a,0x08,0xd6,0x92,0x35,0xe4,0x28,0x78,0x42,0xd6,0x10,0xf5,0x80 }}, - {16, 0xbc30, 0, {0x39,0xa0,0x0f,0x78,0x23,0xde,0x30,0xd3,0xa2,0x35,0xa0,0x4d,0xe8,0x03,0x5e,0x00 }}, - {16, 0xbc40, 0, {0xf7,0xd0,0x3d,0xf8,0x0f,0xf0,0x03,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbc50, 0, {0x08,0x1d,0xac,0x00,0xfb,0x04,0x3e,0x00,0x0b,0xa0,0x03,0x48,0x04,0xfa,0x41,0x3a }}, - {16, 0xbc60, 0, {0x50,0x0f,0xb0,0x03,0xe4,0x00,0xf1,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xed,0x88,0xfb }}, - {16, 0xbc70, 0, {0x4d,0x3e,0x00,0x0f,0xf0,0x03,0xbc,0x08,0xfb,0x20,0x3a,0xc0,0x0f,0xb0,0x03,0xc2 }}, - {16, 0xbc80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xdc,0x80,0xb3,0xe0 }}, - {16, 0xbc90, 0, {0x0c,0xd8,0x03,0xce,0x00,0xc8,0xa0,0x31,0xa0,0x8d,0xe9,0x03,0xbe,0x00,0xb2,0x80 }}, - {16, 0xbca0, 0, {0x33,0xe0,0x0c,0xe8,0x43,0x7e,0x04,0x0f,0x81,0x31,0xe4,0x0c,0xd8,0x03,0xf6,0x00 }}, - {16, 0xbcb0, 0, {0xff,0x80,0x3f,0xe0,0x0f,0xf8,0x03,0x00,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbcc0, 0, {0xa8,0x11,0x9c,0x00,0xb4,0x40,0x35,0x40,0x08,0x50,0x82,0xde,0x80,0xd4,0x90,0x21 }}, - {16, 0xbcd0, 0, {0xe0,0x0d,0x51,0x02,0xd4,0x40,0xb6,0xb0,0x2b,0x90,0x0e,0xe5,0x02,0x9c,0x40,0xd7 }}, - {16, 0xbce0, 0, {0x22,0x19,0x5c,0x0d,0x70,0x02,0xd8,0x00,0xb7,0x20,0x2d,0xc0,0x0b,0xf0,0x03,0x6a }}, - {16, 0xbcf0, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x93,0x10,0x21,0x80 }}, - {16, 0xbd00, 0, {0x08,0x58,0x02,0xdc,0xc0,0x94,0x00,0x23,0xd0,0x08,0x70,0xa0,0xd4,0x20,0xb5,0x02 }}, - {16, 0xbd10, 0, {0x29,0x80,0x09,0x60,0x82,0x0c,0x00,0x87,0x02,0x25,0xc0,0x19,0x40,0x02,0xd4,0x00 }}, - {16, 0xbd20, 0, {0xb7,0x00,0x6d,0xc0,0x0b,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbd30, 0, {0x20,0x14,0xec,0x00,0xb3,0xc0,0x20,0x01,0x48,0x18,0x02,0xcc,0x02,0x81,0x44,0xa0 }}, - {16, 0xbd40, 0, {0xc0,0x89,0x38,0x02,0xc7,0x80,0xb1,0x00,0x2c,0x09,0x4a,0x00,0x62,0xac,0x09,0x93 }}, - {16, 0xbd50, 0, {0x01,0x28,0x40,0x19,0x30,0x02,0xcd,0x10,0xb3,0x90,0x2c,0xc0,0x0b,0x30,0x02,0xc8 }}, - {16, 0xbd60, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x20,0xdb,0x62,0x22,0xe0 }}, - {16, 0xbd70, 0, {0x6c,0xa0,0x03,0xe4,0x00,0x98,0x00,0x32,0xc0,0xec,0x98,0x23,0xae,0x08,0xfb,0x08 }}, - {16, 0xbd80, 0, {0x3a,0x78,0x09,0x90,0x03,0x7c,0x10,0xcf,0x00,0x26,0x40,0x0c,0xb0,0x03,0xec,0x00 }}, - {16, 0xbd90, 0, {0xff,0x80,0x3f,0xc0,0x0f,0x90,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbda0, 0, {0x80,0x00,0xec,0x20,0xfb,0x48,0x3c,0x61,0x0f,0xa0,0x43,0xed,0x00,0xf8,0x24,0x3e }}, - {16, 0xbdb0, 0, {0x50,0x0f,0x90,0x83,0xe4,0x00,0xfb,0x00,0x3a,0x50,0x0f,0x80,0x43,0xec,0x08,0xfb }}, - {16, 0xbdc0, 0, {0x00,0x3e,0x40,0x0f,0x40,0x03,0xf0,0x00,0xfb,0x00,0x3e,0xc1,0x0f,0x90,0x03,0x60 }}, - {16, 0xbdd0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xdd,0xa0,0x32,0x80 }}, - {16, 0xbde0, 0, {0x0c,0xe0,0x01,0xfc,0x00,0xdc,0x91,0x39,0xc0,0x3c,0x40,0x03,0x34,0x00,0xff,0x80 }}, - {16, 0xbdf0, 0, {0x3f,0x00,0x0f,0xd0,0x07,0xfc,0x00,0xcb,0x00,0x3d,0x40,0x0c,0xe0,0x03,0x38,0x20 }}, - {16, 0xbe00, 0, {0xcf,0x02,0x3d,0xc0,0x0c,0xd0,0x03,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbe10, 0, {0x81,0x04,0x6c,0x00,0x01,0x40,0x22,0x00,0x28,0xa0,0x02,0xce,0x86,0x83,0x64,0x22 }}, - {16, 0xbe20, 0, {0xf4,0x08,0x8c,0x0f,0x64,0x00,0xbb,0x10,0x2e,0x60,0x0b,0x9c,0x03,0xac,0x01,0xdb }}, - {16, 0xbe30, 0, {0x00,0x3e,0x60,0x08,0x8f,0x02,0x23,0x40,0x8b,0x00,0x3a,0xc0,0x0d,0x10,0x43,0x68 }}, - {16, 0xbe40, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x99,0x00,0xa2,0xc0 }}, - {16, 0xbe50, 0, {0x08,0x90,0x02,0xa6,0x07,0x98,0x00,0x02,0xc2,0x48,0x88,0x02,0x2c,0x00,0xba,0x02 }}, - {16, 0xbe60, 0, {0x6e,0x60,0x0a,0x98,0x02,0xec,0x00,0x8b,0x01,0x2e,0x60,0x08,0x90,0x02,0x05,0x00 }}, - {16, 0xbe70, 0, {0x8b,0x00,0x2e,0xc0,0x08,0xb1,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbe80, 0, {0x08,0x04,0x0c,0x10,0x81,0x00,0x20,0x40,0x28,0x10,0x26,0xcc,0x80,0x80,0x20,0xa0 }}, - {16, 0xbe90, 0, {0xcc,0x18,0x14,0x42,0x04,0x00,0xb2,0x20,0x6c,0x40,0x0b,0x00,0x02,0x8c,0x00,0x83 }}, - {16, 0xbea0, 0, {0x00,0x28,0x40,0x28,0x00,0x02,0x00,0x00,0x83,0x00,0x28,0xc0,0x09,0xb0,0x02,0x42 }}, - {16, 0xbeb0, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xd9,0x00,0x22,0x80 }}, - {16, 0xbec0, 0, {0x0c,0x90,0x03,0xac,0x80,0xda,0x29,0x2a,0xd2,0x28,0x80,0x02,0x24,0x00,0xfb,0x20 }}, - {16, 0xbed0, 0, {0x3e,0x00,0x0f,0x90,0x02,0xfc,0x00,0x8f,0x00,0x2e,0x40,0x0c,0x80,0x0b,0x20,0x02 }}, - {16, 0xbee0, 0, {0xcf,0x00,0x3e,0xc0,0x0c,0xb0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbef0, 0, {0xa0,0x1d,0xfc,0x00,0xfd,0x00,0x3f,0x00,0x0f,0xd0,0x63,0xfc,0x49,0xf5,0x00,0x3e }}, - {16, 0xbf00, 0, {0xc0,0x0b,0xc0,0x01,0xf4,0x00,0x7f,0x40,0x3f,0x40,0x1f,0xd0,0x03,0xbc,0x00,0xff }}, - {16, 0xbf10, 0, {0x00,0x3f,0x40,0x0f,0xc0,0x03,0xf0,0x00,0xff,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xbf20, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf2,0x40,0xec,0xa0,0x3f,0xe0 }}, - {16, 0xbf30, 0, {0x0d,0x48,0x03,0x7d,0x80,0xf4,0x80,0x33,0x6c,0x0e,0xc8,0x03,0x32,0x00,0xdd,0x90 }}, - {16, 0xbf40, 0, {0x3b,0xa0,0x2d,0xf0,0x03,0xfc,0xc0,0xff,0x00,0x3b,0xe0,0x8e,0xf0,0x03,0x3c,0x04 }}, - {16, 0xbf50, 0, {0xec,0x60,0x31,0x00,0x0c,0xf0,0x03,0xb0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbf60, 0, {0x80,0x10,0xec,0x00,0xd9,0xc1,0x2e,0xe1,0x0d,0x88,0x02,0x3c,0x80,0xf8,0x80,0x36 }}, - {16, 0xbf70, 0, {0x7d,0x18,0xa0,0x02,0x28,0xb0,0xea,0x20,0x22,0x20,0x08,0x77,0x02,0xfd,0x50,0xbb }}, - {16, 0xbf80, 0, {0x80,0x22,0x40,0x0b,0xf4,0x42,0x3d,0x80,0x88,0x31,0x22,0x12,0x08,0xf6,0x02,0xe0 }}, - {16, 0xbf90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x80,0x11,0x2e,0xc1 }}, - {16, 0xbfa0, 0, {0x08,0x00,0x02,0x4d,0x80,0xb8,0x00,0x20,0x00,0x0a,0x02,0x82,0x00,0x00,0x99,0x20 }}, - {16, 0xbfb0, 0, {0x22,0xc0,0x09,0x30,0x82,0xcc,0x00,0xb3,0x00,0x28,0xca,0x0b,0x34,0x82,0x0d,0x20 }}, - {16, 0xbfc0, 0, {0x80,0x00,0xa0,0x8c,0x08,0x34,0x82,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbfd0, 0, {0xc0,0x15,0xac,0x40,0x99,0x80,0x2e,0xc2,0x09,0x94,0x02,0x2c,0x00,0xa9,0x80,0x26 }}, - {16, 0xbfe0, 0, {0x60,0x08,0x38,0x42,0x22,0x20,0xba,0x41,0x62,0x46,0x3b,0xb0,0x02,0xec,0x01,0xbb }}, - {16, 0xbff0, 0, {0x80,0x22,0x40,0x0b,0xb0,0x46,0x0c,0x18,0x88,0xc0,0x22,0x22,0x08,0xb0,0x06,0xf0 }}, - {16, 0xc000, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xcc,0x00,0xc9,0x81,0x3c,0xc1 }}, - {16, 0xc010, 0, {0x0c,0xa9,0x23,0x6c,0x00,0xb2,0x80,0x32,0x78,0x0a,0x8a,0x0b,0x26,0x00,0x99,0x01 }}, - {16, 0xc020, 0, {0x30,0xe0,0x0d,0xb0,0x03,0xec,0x00,0xb9,0x00,0x3a,0xc0,0x1e,0xb0,0x03,0x2c,0x00 }}, - {16, 0xc030, 0, {0xcb,0x80,0x32,0x61,0x0c,0xb0,0x13,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc040, 0, {0xe0,0x01,0xbc,0x10,0xdd,0x00,0x3f,0xc2,0x0f,0xe8,0x03,0xac,0x00,0xfe,0x00,0x3d }}, - {16, 0xc050, 0, {0x40,0x0f,0xc0,0x43,0xf8,0x10,0xef,0x14,0xb7,0xe0,0x0c,0xf0,0x03,0xfc,0x00,0xf5 }}, - {16, 0xc060, 0, {0x02,0x3f,0x44,0x4f,0xb0,0x4b,0xfc,0x02,0xd4,0x04,0x3d,0x40,0x2f,0xf0,0x03,0xf8 }}, - {16, 0xc070, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xf9,0x08,0x3e,0x60 }}, - {16, 0xc080, 0, {0x0d,0xa0,0x03,0xac,0x00,0xe8,0x50,0x32,0x00,0x0c,0x84,0x03,0xa5,0x00,0xe9,0x00 }}, - {16, 0xc090, 0, {0x3a,0xd8,0x0f,0xb0,0x03,0x2c,0x00,0xf9,0x00,0x3a,0xc0,0x0f,0x30,0x03,0x2c,0x00 }}, - {16, 0xc0a0, 0, {0xcb,0x44,0x3e,0xd4,0x0e,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc0b0, 0, {0xc8,0x05,0x2c,0x08,0xb9,0x80,0x2e,0xc0,0x0a,0x30,0x42,0x3c,0x00,0x89,0x04,0x76 }}, - {16, 0xc0c0, 0, {0x60,0x08,0x90,0x62,0x20,0x00,0x82,0x04,0x22,0xd0,0x08,0xf0,0x43,0x7c,0x00,0xbb }}, - {16, 0xc0d0, 0, {0x82,0x22,0x40,0x0b,0xf0,0x42,0x3c,0x00,0x8a,0xc0,0x2e,0xc1,0x08,0xf0,0x02,0xf2 }}, - {16, 0xc0e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x10,0xb2,0xd0,0x2c,0xc0 }}, - {16, 0xc0f0, 0, {0x29,0x18,0x02,0x8c,0x04,0xa1,0x00,0x24,0x9c,0x08,0x10,0x02,0x80,0x00,0xa1,0x01 }}, - {16, 0xc100, 0, {0x0c,0xc1,0x2b,0x30,0x52,0x8c,0x04,0xb3,0x01,0x28,0x40,0x4b,0x30,0x02,0x4c,0x00 }}, - {16, 0xc110, 0, {0x90,0x20,0x2c,0x20,0x0a,0x30,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc120, 0, {0x20,0x41,0x1e,0x00,0xb7,0xa2,0x25,0xe8,0x8a,0x68,0x02,0x1e,0x00,0x85,0x80,0x25 }}, - {16, 0xc130, 0, {0x80,0x88,0xe8,0x02,0x3e,0x00,0x85,0x80,0x2f,0xe4,0x28,0x78,0x02,0xde,0x00,0xb7 }}, - {16, 0xc140, 0, {0x80,0x61,0xe0,0x03,0x78,0x02,0x5e,0x82,0xb7,0x82,0x2d,0xe0,0x08,0x78,0x02,0xc8 }}, - {16, 0xc150, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0d,0x00,0xf0,0x10,0x3c,0x80 }}, - {16, 0xc160, 0, {0x0d,0x10,0x83,0x8c,0x00,0xe2,0x50,0x26,0x04,0x0c,0x11,0x03,0x88,0x40,0xeb,0x00 }}, - {16, 0xc170, 0, {0x3c,0xc4,0x0f,0x30,0x03,0x8c,0x00,0xf3,0x08,0x38,0x40,0x07,0x30,0x03,0x6e,0x40 }}, - {16, 0xc180, 0, {0xd0,0x08,0x3c,0x88,0x0e,0x30,0x43,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc190, 0, {0x40,0x1d,0xbc,0x00,0xfb,0x34,0x3c,0xc9,0x4e,0xb0,0x23,0xed,0x20,0xfb,0x04,0x3f }}, - {16, 0xc1a0, 0, {0xc8,0x8f,0x70,0x53,0x4c,0x00,0xeb,0x10,0x31,0xc5,0x0e,0xf4,0x03,0x6d,0x00,0xf3 }}, - {16, 0xc1b0, 0, {0x00,0x3f,0xc0,0x0f,0xf4,0x0b,0xbc,0x00,0xcd,0x00,0x3f,0xc0,0x0f,0xf4,0x83,0xd0 }}, - {16, 0xc1c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xce,0x04,0xc9,0x04,0xb0,0xc1 }}, - {16, 0xc1d0, 0, {0x0f,0x98,0x13,0x6c,0x90,0xcb,0x02,0x3e,0xc0,0x4f,0xb0,0x63,0xe4,0x00,0xf1,0x80 }}, - {16, 0xc1e0, 0, {0x12,0xc0,0x0c,0xb5,0x03,0xec,0xc0,0xcf,0x83,0x32,0x40,0x0f,0xb3,0x23,0x2d,0xa4 }}, - {16, 0xc1f0, 0, {0xfb,0x00,0x3e,0x00,0x0f,0xb4,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc200, 0, {0x48,0x11,0x9c,0x00,0x87,0x00,0x21,0xc0,0x2d,0x60,0x02,0x1c,0x00,0xd7,0x00,0x39 }}, - {16, 0xc210, 0, {0xc0,0x0b,0x60,0x02,0xdc,0x00,0xb5,0x00,0x21,0xc0,0x2a,0x70,0x12,0xcc,0x80,0x87 }}, - {16, 0xc220, 0, {0x00,0x35,0xc0,0x0b,0x72,0x52,0x1c,0x00,0xb7,0x00,0x2d,0x41,0x0b,0x32,0x02,0x12 }}, - {16, 0xc230, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xbe,0x00,0x81,0xc0,0x23,0x20 }}, - {16, 0xc240, 0, {0x0b,0xd8,0x02,0x5e,0x00,0x06,0xc0,0x2d,0xa0,0x0b,0x7c,0x12,0xde,0x08,0xbf,0x80 }}, - {16, 0xc250, 0, {0xa1,0xe2,0x2a,0x7a,0x02,0xde,0x00,0x93,0x80,0x25,0x60,0x0b,0x78,0x1e,0x5e,0x50 }}, - {16, 0xc260, 0, {0xb7,0x80,0x2d,0xa0,0x0b,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc270, 0, {0x48,0x14,0xce,0x00,0x83,0x60,0x20,0xc0,0x09,0x31,0x02,0x2c,0x00,0x93,0x00,0x28 }}, - {16, 0xc280, 0, {0xc0,0x1b,0xb0,0x06,0xcc,0x80,0xb3,0x48,0x20,0xf0,0x0a,0x30,0x02,0xec,0x00,0x93 }}, - {16, 0xc290, 0, {0x80,0x24,0xc0,0x0b,0xb0,0x02,0x4c,0x10,0xb3,0xc8,0x2c,0xd2,0x8b,0x30,0x02,0x12 }}, - {16, 0xc2a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xbb,0x00,0xc6,0xc4,0x31,0x81 }}, - {16, 0xc2b0, 0, {0x0f,0xe0,0x03,0x68,0x00,0xce,0x80,0x3f,0xa2,0x0b,0xe8,0x03,0xf9,0x00,0xfe,0x40 }}, - {16, 0xc2c0, 0, {0x31,0x80,0x6e,0xa0,0x07,0xe8,0x00,0xda,0x00,0x26,0x81,0x0f,0xa0,0x02,0x68,0x01 }}, - {16, 0xc2d0, 0, {0xf6,0xe0,0x3d,0x92,0x0f,0xa0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc2e0, 0, {0x48,0x00,0xe0,0xc2,0xf8,0x04,0x3e,0x14,0x0f,0x80,0x13,0xe0,0x10,0xf8,0x01,0x3e }}, - {16, 0xc2f0, 0, {0x10,0x0f,0x80,0x43,0xe0,0x00,0xb8,0x00,0x3e,0x00,0x47,0x80,0x03,0xe0,0x02,0xe8 }}, - {16, 0xc300, 0, {0x10,0x3e,0x00,0x0f,0x80,0x07,0xa0,0x00,0xf8,0x00,0x2e,0x00,0x0f,0x80,0x0b,0xd2 }}, - {16, 0xc310, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x01,0x32,0x40 }}, - {16, 0xc320, 0, {0x8c,0x90,0x03,0xe4,0x00,0xc9,0x00,0x36,0x42,0x0f,0x90,0x03,0xa4,0x00,0xc9,0x00 }}, - {16, 0xc330, 0, {0x3e,0x42,0x0d,0x90,0x03,0x64,0x00,0xd9,0x00,0x3e,0x40,0x0f,0x90,0x0b,0x64,0x00 }}, - {16, 0xc340, 0, {0xf9,0x90,0x32,0x41,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc350, 0, {0x80,0x04,0x64,0x00,0xb9,0xc8,0xa2,0x60,0x0a,0x92,0x02,0xe4,0x00,0x89,0x40,0x2e }}, - {16, 0xc360, 0, {0x58,0x0b,0x90,0x02,0x04,0x00,0xd9,0x00,0x2e,0x42,0x08,0x90,0x02,0xe4,0x04,0x89 }}, - {16, 0xc370, 0, {0x00,0x2e,0x40,0x0b,0x90,0x06,0x24,0x04,0xb9,0x08,0x2a,0x40,0x48,0x90,0x12,0x20 }}, - {16, 0xc380, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x10,0x22,0x44 }}, - {16, 0xc390, 0, {0x08,0x90,0x02,0xe4,0x00,0x89,0x00,0x22,0x45,0x8b,0x90,0x02,0xa4,0x00,0x89,0x00 }}, - {16, 0xc3a0, 0, {0x2a,0x40,0x09,0x90,0x02,0xe4,0x00,0x99,0x80,0x2e,0x40,0x0b,0x90,0x26,0x24,0x00 }}, - {16, 0xc3b0, 0, {0xb9,0x01,0x22,0x70,0x09,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc3c0, 0, {0x08,0x04,0x04,0x08,0xb1,0x20,0x20,0x40,0x0a,0x10,0x02,0xc4,0x80,0x83,0x00,0x2c }}, - {16, 0xc3d0, 0, {0x50,0x4b,0x10,0x02,0x24,0x00,0x91,0x00,0x2e,0x40,0x08,0x12,0x02,0xc4,0x81,0x81 }}, - {16, 0xc3e0, 0, {0xa2,0x6c,0x40,0x0b,0x12,0x02,0x04,0x80,0xb9,0x20,0x2a,0x48,0x29,0x12,0x02,0x02 }}, - {16, 0xc3f0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x61,0x40,0xf8,0x00,0x32,0x80 }}, - {16, 0xc400, 0, {0x08,0x80,0x03,0xe1,0x42,0xc8,0x00,0x32,0x00,0x1f,0x85,0x03,0xa1,0x40,0xc8,0x50 }}, - {16, 0xc410, 0, {0x3a,0x00,0x8d,0x85,0x03,0x61,0x40,0xd8,0x00,0x3e,0x00,0x0f,0x05,0x03,0x21,0x40 }}, - {16, 0xc420, 0, {0xf8,0x50,0x32,0x14,0x0d,0x85,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc430, 0, {0x98,0x1d,0xf4,0x04,0xfd,0x10,0x3f,0x40,0x0f,0x50,0x03,0xc4,0x40,0xfd,0x00,0x3f }}, - {16, 0xc440, 0, {0x51,0x0f,0xd0,0x03,0xf4,0x00,0xff,0x01,0x3d,0x40,0x0f,0x91,0x03,0xe4,0x40,0xfd }}, - {16, 0xc450, 0, {0x10,0x3f,0x4a,0x0f,0x91,0x03,0xe4,0x40,0xfd,0x10,0x3f,0x44,0x0e,0x91,0x03,0xe6 }}, - {16, 0xc460, 0, {0x02,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xc5,0x00,0xcd,0x00,0x31,0x40 }}, - {16, 0xc470, 0, {0x0d,0xd0,0x43,0xe4,0x00,0xcd,0x00,0x33,0x40,0x4f,0x11,0x02,0xe4,0x04,0xc1,0x00 }}, - {16, 0xc480, 0, {0x3d,0x40,0x0c,0x90,0x03,0xe4,0x00,0xed,0xa4,0x32,0x50,0x0f,0x90,0x03,0xe4,0x00 }}, - {16, 0xc490, 0, {0xfd,0x00,0x3f,0x40,0x0f,0x90,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc4a0, 0, {0x38,0x10,0xe2,0x08,0xd8,0x00,0x32,0x01,0x00,0x80,0x12,0xc0,0x00,0x48,0x00,0x36 }}, - {16, 0xc4b0, 0, {0x80,0x0b,0x8a,0x02,0xe0,0x00,0xa8,0x00,0x2e,0x00,0x0f,0x80,0x02,0xe0,0x00,0x88 }}, - {16, 0xc4c0, 0, {0x50,0x34,0x28,0x0b,0x80,0x02,0xe0,0x00,0xb8,0x00,0x2e,0x00,0x0b,0x80,0x02,0xce }}, - {16, 0xc4d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0x81,0x00,0x26,0x40 }}, - {16, 0xc4e0, 0, {0x09,0x18,0x02,0xc4,0x08,0x21,0x00,0x28,0x40,0x8b,0x10,0x02,0xc4,0x00,0xb1,0x01 }}, - {16, 0xc4f0, 0, {0x2e,0x40,0x18,0x10,0x02,0xc4,0x00,0xa1,0x01,0x20,0x48,0x1b,0x10,0x02,0xc4,0x00 }}, - {16, 0xc500, 0, {0xb1,0x00,0x6c,0x40,0x0b,0x10,0x12,0xc2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc510, 0, {0x18,0x11,0xa4,0x00,0x99,0x80,0xa2,0x42,0x48,0x90,0x02,0xe4,0x00,0xa9,0x2a,0x26 }}, - {16, 0xc520, 0, {0x44,0x0b,0x90,0x82,0xc4,0x81,0xb9,0x00,0x2e,0x40,0x0b,0x90,0x42,0xc4,0x00,0x89 }}, - {16, 0xc530, 0, {0x00,0x26,0x40,0x0b,0x90,0x02,0xe4,0x00,0xb9,0x01,0x2e,0x41,0x0b,0x90,0x02,0xc6 }}, - {16, 0xc540, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xc5,0x20,0xc9,0x84,0x30,0x70 }}, - {16, 0xc550, 0, {0x0d,0x90,0x13,0xe4,0x02,0xe9,0x00,0x32,0x70,0x0f,0x94,0x03,0xe4,0x00,0xf9,0x40 }}, - {16, 0xc560, 0, {0x3c,0x48,0x0c,0x90,0x03,0xe4,0x00,0xe1,0x00,0x32,0x40,0x0f,0x90,0x01,0xe4,0x00 }}, - {16, 0xc570, 0, {0xf9,0x90,0x3e,0x60,0x0f,0x90,0x26,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc580, 0, {0x28,0x01,0xa5,0x00,0xf1,0x04,0x3a,0x44,0x8f,0x90,0x03,0xe4,0x10,0xc9,0x04,0x3e }}, - {16, 0xc590, 0, {0x60,0x0f,0x90,0x03,0xe4,0x00,0xe9,0x20,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x10,0xf9 }}, - {16, 0xc5a0, 0, {0x90,0x3e,0x40,0x0f,0x90,0x03,0xe4,0x00,0xf9,0x80,0x3e,0x64,0x0f,0x90,0x07,0xca }}, - {16, 0xc5b0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa1,0x00,0xc8,0x04,0x3a,0x00 }}, - {16, 0xc5c0, 0, {0x1e,0x80,0x03,0x80,0x03,0xc8,0x40,0x2a,0x04,0x1f,0x80,0x03,0x20,0x00,0x88,0x00 }}, - {16, 0xc5d0, 0, {0x32,0x30,0x0c,0x80,0x03,0x20,0x00,0xf8,0x00,0x3e,0x00,0x0c,0x80,0x03,0xe0,0x00 }}, - {16, 0xc5e0, 0, {0xc8,0x80,0x3e,0x20,0x0f,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc5f0, 0, {0x28,0x05,0x38,0x00,0xae,0xd0,0x37,0x80,0x08,0xec,0x46,0x38,0x00,0xd6,0x04,0x23 }}, - {16, 0xc600, 0, {0xa0,0x0b,0xa0,0x41,0x78,0x04,0xfa,0x00,0x37,0x80,0x0d,0xa0,0x02,0xa8,0x10,0xee }}, - {16, 0xc610, 0, {0x21,0x2e,0x80,0x08,0xa0,0x02,0xe8,0x08,0x8e,0x80,0x2f,0xa0,0x8b,0xa0,0x02,0xca }}, - {16, 0xc620, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x01,0x4c,0x02,0x83,0xc0,0xa8,0xe8 }}, - {16, 0xc630, 0, {0x4a,0x36,0x02,0x8c,0x00,0x13,0xa0,0x28,0xc2,0x0b,0x30,0x06,0x0c,0x00,0xb3,0x00 }}, - {16, 0xc640, 0, {0x24,0x84,0x09,0x30,0x02,0x0c,0x00,0xb3,0x20,0x28,0xc0,0x09,0x30,0x02,0xcc,0x00 }}, - {16, 0xc650, 0, {0x83,0x80,0x2c,0xc0,0x0b,0x30,0x02,0xca,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc660, 0, {0xa0,0x01,0x3c,0x44,0xaf,0x40,0x25,0xc2,0x48,0xf8,0x82,0x1c,0xc8,0x9f,0x08,0x21 }}, - {16, 0xc670, 0, {0xc0,0x8b,0xf8,0x02,0x5c,0x00,0xbf,0xb0,0x27,0x80,0x09,0x3a,0x02,0x9c,0x00,0xa5 }}, - {16, 0xc680, 0, {0x02,0x2d,0xe8,0x09,0x70,0x02,0xce,0x80,0x85,0x08,0x2d,0xc2,0x0b,0x73,0x02,0xe8 }}, - {16, 0xc690, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0x82,0xa9,0xe0 }}, - {16, 0xc6a0, 0, {0x0a,0x78,0x02,0x9e,0x40,0x97,0x84,0x39,0xa0,0x0b,0x7a,0x83,0x3f,0x80,0xd7,0x91 }}, - {16, 0xc6b0, 0, {0x35,0xa0,0x0d,0x7a,0x09,0x1e,0x44,0xf7,0x80,0x3d,0xe8,0x2d,0x7a,0x03,0xde,0x82 }}, - {16, 0xc6c0, 0, {0xc6,0x80,0x3d,0x20,0x4b,0x7b,0x23,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc6d0, 0, {0x08,0x1d,0xac,0x00,0xd3,0x00,0x3e,0xc1,0x0f,0x30,0x03,0xed,0x80,0xe3,0x00,0x3e }}, - {16, 0xc6e0, 0, {0x80,0x0f,0xb6,0x21,0xec,0x08,0xdb,0x21,0x3e,0x80,0x0f,0xb5,0x03,0x6c,0x40,0xf9 }}, - {16, 0xc6f0, 0, {0x00,0x3e,0xdc,0x0e,0xb2,0x03,0xed,0x40,0xf9,0x02,0x3e,0x80,0x0f,0xb0,0x03,0xc2 }}, - {16, 0xc700, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xcf,0x80,0x3d,0xe0 }}, - {16, 0xc710, 0, {0x0f,0xc8,0x43,0xfe,0x00,0xfe,0x84,0x3f,0xe0,0x0d,0xf8,0xc3,0xff,0x10,0xaf,0x90 }}, - {16, 0xc720, 0, {0x35,0xa0,0x0c,0xfc,0x03,0x3e,0x14,0xec,0x84,0x3f,0xf0,0x0e,0xfc,0xc3,0xff,0x08 }}, - {16, 0xc730, 0, {0x4f,0x80,0x33,0xe4,0x0c,0xf8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc740, 0, {0xa8,0x11,0x9c,0x00,0xd7,0xa2,0x2d,0xc4,0x0c,0x41,0xc2,0xdc,0x00,0x74,0x00,0x25 }}, - {16, 0xc750, 0, {0x80,0x0f,0x72,0x42,0xdc,0x90,0xd7,0x38,0x2d,0x98,0x0a,0x70,0x02,0x1c,0x04,0x86 }}, - {16, 0xc760, 0, {0x00,0x3f,0xc0,0x0d,0x70,0x02,0xcc,0x00,0x86,0x08,0x37,0xc6,0x28,0x70,0x02,0x2a }}, - {16, 0xc770, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0x87,0x60,0x2d,0xc2 }}, - {16, 0xc780, 0, {0x0a,0x50,0x02,0xdc,0x00,0xb6,0x10,0x25,0xc2,0x09,0x70,0x86,0xdc,0x30,0x97,0x00 }}, - {16, 0xc790, 0, {0x25,0x80,0x08,0x30,0x02,0x5c,0x00,0x87,0x08,0x2d,0xc0,0x08,0x70,0x02,0xcc,0x40 }}, - {16, 0xc7a0, 0, {0x86,0x00,0x21,0x00,0x09,0x70,0x0a,0x00,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc7b0, 0, {0x20,0x14,0xed,0x80,0x93,0x00,0x0c,0xe1,0x28,0x18,0x02,0xcc,0x08,0xa0,0x00,0x24 }}, - {16, 0xc7c0, 0, {0x12,0x1a,0x34,0x02,0xcf,0x04,0x93,0x40,0x2c,0x80,0x0a,0xb0,0x22,0x4c,0x02,0x81 }}, - {16, 0xc7d0, 0, {0x80,0x28,0xe0,0x28,0x30,0x02,0xcc,0x00,0x88,0x82,0x24,0x20,0x08,0xb0,0x02,0x08 }}, - {16, 0xc7e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbf,0x20,0xc9,0xe0,0x2c,0xf1 }}, - {16, 0xc7f0, 0, {0x0e,0xbd,0x03,0xfc,0x00,0xb9,0x40,0x36,0x40,0x09,0xf5,0x02,0xfd,0x40,0xff,0x80 }}, - {16, 0xc800, 0, {0x36,0xa2,0x08,0xf0,0x0b,0x7c,0x00,0xeb,0x80,0x2f,0xe0,0x0a,0xf0,0x43,0xfc,0x02 }}, - {16, 0xc810, 0, {0x8b,0xd0,0x32,0xf0,0x0d,0xf0,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc820, 0, {0x80,0x00,0xec,0x10,0xfb,0x00,0x3e,0xc8,0x0f,0x94,0x13,0xec,0x00,0xf9,0x40,0x36 }}, - {16, 0xc830, 0, {0x40,0x1f,0xb0,0x03,0xec,0x10,0xfb,0x01,0x3e,0xd0,0x0f,0xb0,0x03,0xac,0x00,0xf9 }}, - {16, 0xc840, 0, {0x00,0x3e,0xc4,0x0f,0xb0,0x01,0xec,0x00,0xf9,0x04,0x3e,0x48,0x0f,0xb0,0x03,0xe0 }}, - {16, 0xc850, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xdf,0x00,0x3f,0xc0 }}, - {16, 0xc860, 0, {0x0c,0xe0,0x07,0xfc,0x00,0xfc,0x0a,0x27,0x00,0x4f,0xf0,0x03,0xfc,0x00,0xff,0x08 }}, - {16, 0xc870, 0, {0x33,0x80,0x0c,0xf0,0x00,0x2c,0x00,0x5f,0x00,0x33,0xc0,0x0c,0xf0,0x01,0xfc,0x00 }}, - {16, 0xc880, 0, {0xfe,0x00,0x23,0x40,0x0f,0xb0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc890, 0, {0x81,0x04,0x6c,0x00,0x8b,0x86,0x2e,0xe0,0x48,0x8f,0x02,0xec,0x08,0xb8,0xa0,0x36 }}, - {16, 0xc8a0, 0, {0x30,0x4b,0xb0,0x03,0xac,0x0c,0x9b,0x02,0x3c,0xa0,0x0c,0xb0,0x43,0x6c,0x00,0xb1 }}, - {16, 0xc8b0, 0, {0x00,0x28,0xc0,0x0d,0xb0,0x12,0xec,0x10,0xb9,0x80,0xa2,0x61,0x0b,0xb0,0x02,0x20 }}, - {16, 0xc8c0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x9b,0x88,0x2e,0xe0 }}, - {16, 0xc8d0, 0, {0x08,0xa0,0x02,0xec,0x01,0xbb,0x80,0x26,0x62,0x0b,0xb0,0x02,0xec,0x00,0xb3,0x01 }}, - {16, 0xc8e0, 0, {0x2a,0x21,0x08,0xb0,0x12,0x2c,0x00,0xb8,0x00,0x22,0xc0,0x08,0xb0,0x12,0xec,0x14 }}, - {16, 0xc8f0, 0, {0xb9,0x84,0x22,0xa2,0x0b,0xb0,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc900, 0, {0x08,0x04,0x0c,0x04,0x93,0x00,0x2c,0xe0,0x08,0x00,0x02,0xcc,0x09,0x91,0x00,0x20 }}, - {16, 0xc910, 0, {0x40,0x0b,0x30,0x06,0x4c,0x04,0x13,0x00,0x26,0x00,0x08,0x30,0x02,0xcc,0x04,0xb2 }}, - {16, 0xc920, 0, {0x00,0x2a,0xc0,0x01,0x30,0x00,0xcd,0x00,0xb0,0x00,0x20,0x80,0x0b,0x30,0x0a,0x02 }}, - {16, 0xc930, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xdb,0x24,0x6e,0xc0 }}, - {16, 0xc940, 0, {0x2c,0xa0,0x02,0xfc,0x00,0xba,0x04,0x26,0x40,0x4f,0xf0,0x57,0xfc,0x00,0x3f,0x01 }}, - {16, 0xc950, 0, {0x3a,0x00,0x2c,0xf0,0x01,0x3c,0x00,0xdb,0x00,0x33,0xc0,0x84,0xf0,0x03,0xfd,0x08 }}, - {16, 0xc960, 0, {0xfa,0x00,0x32,0x00,0x0f,0xf0,0x03,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc970, 0, {0xa0,0x19,0xdc,0x00,0xea,0x40,0x3f,0x00,0x07,0xc0,0x03,0xfc,0x04,0xfc,0x00,0x3f }}, - {16, 0xc980, 0, {0x40,0x0f,0xf0,0x03,0x9c,0x00,0xff,0x00,0x3f,0x00,0x0e,0xf0,0x03,0x7c,0x00,0xfd }}, - {16, 0xc990, 0, {0x00,0x3f,0xc1,0x0f,0xf0,0x03,0xfc,0x84,0xf4,0x00,0x3f,0x00,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xc9a0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,0xf0,0x80,0xff,0x00,0x03,0xc2 }}, - {16, 0xc9b0, 0, {0x0f,0xc2,0x03,0x3e,0x00,0xdf,0xc0,0x3e,0xc0,0x4d,0xdb,0x02,0xb0,0xc0,0xdc,0x30 }}, - {16, 0xc9c0, 0, {0x3f,0xe0,0x0f,0xdb,0x23,0xf6,0x20,0xff,0x26,0x33,0xe0,0x0f,0x52,0x03,0x5e,0x00 }}, - {16, 0xc9d0, 0, {0xff,0x80,0x33,0xc0,0x4c,0x49,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc9e0, 0, {0x80,0x10,0xe1,0xe0,0xb7,0x08,0x23,0xf0,0x0b,0xad,0x0a,0x2e,0x00,0x9a,0x04,0x2e }}, - {16, 0xc9f0, 0, {0xb0,0x09,0x8f,0x03,0xa0,0x40,0xb9,0x30,0x2e,0xa0,0x0b,0x9f,0x03,0xa7,0x00,0xbb }}, - {16, 0xca00, 0, {0x80,0x26,0xe0,0x0b,0xdd,0x02,0x2e,0x00,0xbb,0x80,0x22,0xf4,0x0a,0x92,0x02,0xa0 }}, - {16, 0xca10, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x80,0xb3,0x10,0x24,0xc0 }}, - {16, 0xca20, 0, {0x0b,0x80,0x02,0xac,0x00,0xa3,0x24,0x2c,0xd0,0x08,0x10,0x06,0xc0,0x80,0xb2,0x01 }}, - {16, 0xca30, 0, {0x2c,0xea,0x4b,0x00,0x12,0xc2,0x04,0xb3,0x10,0x08,0xc0,0x0a,0x90,0x02,0x0c,0x00 }}, - {16, 0xca40, 0, {0x93,0x04,0x24,0xc0,0x09,0x82,0x02,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xca50, 0, {0xc0,0x15,0xa5,0x00,0xbb,0x00,0x22,0xc0,0x0b,0x80,0x02,0xac,0x08,0xbb,0x18,0x2e }}, - {16, 0xca60, 0, {0xe0,0x18,0x88,0x02,0xec,0x01,0xba,0x00,0x2e,0x80,0x0b,0x98,0x86,0xe2,0x00,0xbb }}, - {16, 0xca70, 0, {0x00,0x22,0xc4,0x0b,0x90,0x02,0x6c,0x00,0xbb,0x00,0xa6,0xc0,0x0b,0x90,0x00,0xb0 }}, - {16, 0xca80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x11,0xe7,0x00,0xfb,0x00,0xb2,0xc0 }}, - {16, 0xca90, 0, {0x0f,0xa8,0x03,0xac,0x02,0xeb,0x00,0x3e,0x60,0x0d,0x9e,0x03,0xec,0x00,0xd8,0x40 }}, - {16, 0xcaa0, 0, {0x3e,0x40,0x0f,0x88,0x43,0xe2,0x00,0xfb,0x20,0x32,0xc0,0x0f,0x10,0x0b,0x6f,0x90 }}, - {16, 0xcab0, 0, {0x5b,0x82,0x36,0xc0,0x2d,0x08,0x01,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcac0, 0, {0xe0,0x01,0xb7,0x08,0xf7,0x00,0x3f,0xc0,0x0f,0xf9,0x03,0x7c,0x08,0xcf,0x82,0x3c }}, - {16, 0xcad0, 0, {0x00,0xaf,0xd0,0x21,0xbc,0x08,0xfd,0x10,0x3f,0x80,0x8f,0xc0,0x03,0xa4,0x00,0xf7 }}, - {16, 0xcae0, 0, {0x01,0xbf,0xc0,0x07,0xd0,0x03,0xbd,0x30,0xff,0xa4,0x38,0xc0,0x0e,0xda,0x03,0xf8 }}, - {16, 0xcaf0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa8,0x00,0xfb,0x00,0xb2,0xc1 }}, - {16, 0xcb00, 0, {0x0e,0x81,0x03,0xec,0x40,0xfb,0x44,0x3a,0xc1,0x0e,0x95,0x03,0xe0,0x00,0xcb,0x41 }}, - {16, 0xcb10, 0, {0x32,0x4d,0x0f,0x81,0x03,0xe0,0x20,0xc9,0x00,0x72,0xe8,0x44,0x91,0x03,0x6d,0x00 }}, - {16, 0xcb20, 0, {0xcb,0x02,0x3e,0xc0,0x0c,0x80,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcb30, 0, {0xc8,0x05,0x24,0x00,0xbf,0x00,0x33,0xc4,0x08,0x1d,0x03,0x8c,0x00,0xbb,0x98,0x36 }}, - {16, 0xcb40, 0, {0x48,0x4d,0x98,0x22,0xed,0x40,0xdb,0x00,0x36,0xb0,0x0b,0x98,0x02,0xe3,0x00,0xdb }}, - {16, 0xcb50, 0, {0x00,0x32,0xe0,0x88,0xd8,0x02,0x2c,0x02,0xc3,0x80,0x2f,0xc0,0x08,0x90,0x03,0x72 }}, - {16, 0xcb60, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x44,0x00,0xb3,0x00,0x20,0xf0 }}, - {16, 0xcb70, 0, {0x18,0x08,0x02,0x4f,0x84,0xb1,0xc0,0x24,0xc0,0x89,0x06,0x02,0xc4,0x00,0x91,0x00 }}, - {16, 0xcb80, 0, {0x20,0xf0,0x1b,0x18,0x82,0xc6,0x00,0x93,0x00,0x2c,0xd1,0x08,0x1e,0x02,0x0e,0x44 }}, - {16, 0xcb90, 0, {0x93,0x94,0x2c,0xc0,0x08,0x20,0x02,0xb8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcba0, 0, {0x20,0x01,0x1e,0x04,0xb7,0x80,0x20,0xe2,0x08,0x68,0x06,0x9e,0x80,0xbf,0x84,0x25 }}, - {16, 0xcbb0, 0, {0xa8,0x09,0x68,0x02,0xc6,0x00,0x93,0xa0,0x65,0xe4,0x0b,0x78,0x12,0xde,0x00,0x93 }}, - {16, 0xcbc0, 0, {0x00,0xa1,0xe0,0x08,0xd8,0x02,0x1e,0xd0,0xa7,0x80,0x2d,0xe0,0x08,0xf8,0x02,0x48 }}, - {16, 0xcbd0, 0, {0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x08,0x00,0xb3,0x20,0x30,0xc0 }}, - {16, 0xcbe0, 0, {0x0a,0x22,0x02,0xce,0x40,0xf3,0xa0,0x3c,0xe8,0x0b,0x30,0x02,0xc1,0x00,0xd0,0xc1 }}, - {16, 0xcbf0, 0, {0x30,0xc0,0x0b,0x21,0x13,0xcc,0x21,0xd3,0x00,0x2c,0xc0,0x2c,0x10,0x0b,0x0c,0x80 }}, - {16, 0xcc00, 0, {0xd3,0x61,0x3c,0xc8,0x2c,0x20,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcc10, 0, {0x40,0x1d,0xbc,0x00,0xff,0x40,0x3b,0xc0,0x0f,0xe0,0x03,0xfc,0x00,0xf7,0x50,0x7f }}, - {16, 0xcc20, 0, {0xc4,0x2e,0xf0,0x03,0xfc,0x40,0xfe,0x00,0x3f,0xc0,0x0f,0xf0,0x47,0xfc,0x00,0xff }}, - {16, 0xcc30, 0, {0x00,0x7d,0xc2,0x0f,0xd0,0x01,0xbc,0x80,0x5f,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xd0 }}, - {16, 0xcc40, 0, {0x02,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe4,0x00,0xfb,0xc0,0x32,0xc8 }}, - {16, 0xcc50, 0, {0x0e,0xe0,0x03,0xac,0xa0,0xeb,0x20,0x32,0x40,0x8c,0xa0,0x13,0x2c,0x00,0xd9,0x00 }}, - {16, 0xcc60, 0, {0x3e,0x60,0x0c,0xb0,0x03,0xe8,0x00,0xfa,0x80,0x30,0xc0,0x3c,0x92,0x03,0xef,0x60 }}, - {16, 0xcc70, 0, {0xc3,0x20,0x31,0xc4,0x0c,0xa0,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcc80, 0, {0x48,0x11,0x9c,0x00,0x33,0x20,0x21,0xda,0x0b,0x70,0x43,0x9c,0x01,0xb5,0x00,0x21 }}, - {16, 0xcc90, 0, {0x00,0x0a,0xe0,0x02,0x1c,0x00,0xb7,0x00,0x2f,0xc0,0x0d,0x70,0x03,0x9c,0x00,0xb6 }}, - {16, 0xcca0, 0, {0x00,0x31,0xc8,0x08,0x57,0x02,0xdc,0x00,0x87,0x50,0x21,0xc0,0x0a,0x70,0x42,0x92 }}, - {16, 0xccb0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9a,0x11,0xb7,0x90,0x21,0xe0 }}, - {16, 0xccc0, 0, {0x0b,0x68,0x82,0xde,0x08,0xa7,0x80,0x24,0x60,0x08,0x70,0x12,0x12,0x08,0x95,0x80 }}, - {16, 0xccd0, 0, {0x2d,0x60,0x09,0x6c,0x02,0xde,0x00,0xb1,0x80,0x23,0xe0,0x0a,0x58,0x62,0xfe,0x00 }}, - {16, 0xcce0, 0, {0x97,0xa0,0x21,0xe8,0x09,0xe8,0x02,0x30,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xccf0, 0, {0x48,0x14,0xcd,0x00,0xb3,0x00,0x20,0xc0,0x8b,0x3c,0x02,0x8c,0x00,0xbb,0x00,0x24 }}, - {16, 0xcd00, 0, {0xc4,0x1a,0x3d,0x02,0x2f,0x88,0xb3,0x48,0x2c,0xe0,0x89,0x3e,0x02,0x8d,0x80,0x93 }}, - {16, 0xcd10, 0, {0xd9,0xa4,0x40,0x88,0x10,0x02,0xcc,0x04,0x93,0xc8,0x20,0xc0,0x0b,0x30,0x02,0x92 }}, - {16, 0xcd20, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x40,0xfa,0x00,0xb2,0x80 }}, - {16, 0xcd30, 0, {0x0f,0xe0,0x03,0xe8,0x00,0xea,0x80,0x37,0xa0,0x0c,0xe8,0x13,0x3b,0x08,0xde,0x01 }}, - {16, 0xcd40, 0, {0x3f,0x82,0x0c,0xe0,0x43,0xfa,0x80,0xfe,0x80,0x31,0x28,0x0c,0xa0,0x03,0xf0,0x02 }}, - {16, 0xcd50, 0, {0xc4,0xc0,0xb2,0x80,0x0d,0xe0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcd60, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x10,0x0b,0x80,0x83,0xe0,0x00,0xf8,0x30,0x3a }}, - {16, 0xcd70, 0, {0x00,0x6d,0x80,0x83,0xe1,0x44,0xb8,0x04,0x3e,0x10,0x0f,0x80,0x13,0xe0,0x00,0xf8 }}, - {16, 0xcd80, 0, {0x00,0x3a,0x10,0x4f,0x04,0x03,0xe3,0x00,0xe8,0x10,0x3e,0x00,0x0e,0x80,0x03,0xd2 }}, - {16, 0xcd90, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xc9,0x00,0x38,0x40 }}, - {16, 0xcda0, 0, {0x0f,0x1a,0x03,0x2e,0x00,0xfb,0xa0,0x36,0x60,0x0c,0x98,0x03,0xe6,0x04,0xd1,0x00 }}, - {16, 0xcdb0, 0, {0x36,0x48,0x0e,0x91,0x02,0xe6,0x00,0xf9,0x00,0x3e,0x00,0x0c,0x99,0x03,0x62,0x40 }}, - {16, 0xcdc0, 0, {0xf8,0x00,0xa0,0x68,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcdd0, 0, {0x80,0x04,0x64,0x02,0x89,0x04,0x2e,0x64,0x88,0x94,0x02,0xa5,0x00,0xb9,0x80,0x20 }}, - {16, 0xcde0, 0, {0x64,0x0d,0x9c,0x02,0xe6,0x42,0x89,0x00,0x22,0x60,0x0b,0x9c,0x02,0xe4,0x10,0xb9 }}, - {16, 0xcdf0, 0, {0x40,0x3a,0x50,0x08,0x9c,0x02,0x27,0x20,0xb9,0x00,0x22,0x40,0x08,0x10,0x03,0x60 }}, - {16, 0xce00, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x00,0x89,0x00,0x22,0x40 }}, - {16, 0xce10, 0, {0x0a,0x90,0x82,0x25,0x4c,0xb9,0x00,0x02,0x40,0x08,0x96,0x02,0xe4,0x10,0x89,0x00 }}, - {16, 0xce20, 0, {0x26,0x50,0x13,0x94,0x02,0xe4,0x40,0xb9,0x08,0x2e,0x40,0x08,0x90,0x8a,0x24,0x00 }}, - {16, 0xce30, 0, {0xb9,0x01,0x2a,0x40,0x08,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xce40, 0, {0x08,0x04,0x05,0x80,0x81,0x40,0x2c,0xc8,0x08,0x10,0x06,0x84,0x00,0xb1,0x04,0x20 }}, - {16, 0xce50, 0, {0x49,0x09,0x14,0x42,0xcc,0x89,0x81,0x20,0x20,0x50,0x0b,0x14,0x46,0xc4,0x00,0xb1 }}, - {16, 0xce60, 0, {0x00,0x2a,0xc0,0x28,0x14,0x02,0x01,0x01,0xb0,0x04,0x28,0x40,0x38,0x94,0x02,0x42 }}, - {16, 0xce70, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0x88,0x00,0x3a,0x00 }}, - {16, 0xce80, 0, {0x0e,0x80,0x23,0x20,0x00,0xf8,0x50,0xb2,0x00,0x0c,0x80,0x12,0xe1,0x40,0xd8,0x50 }}, - {16, 0xce90, 0, {0x36,0x00,0x0e,0x80,0x03,0xe0,0x00,0xf8,0x00,0x2e,0x00,0x0c,0x80,0x53,0x60,0x04 }}, - {16, 0xcea0, 0, {0xf8,0x00,0x3a,0x00,0x0c,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xceb0, 0, {0x98,0x1d,0xf4,0x40,0xf9,0x44,0x3e,0x44,0x0f,0xd4,0x03,0xe4,0x00,0xf1,0x00,0x3f }}, - {16, 0xcec0, 0, {0x44,0x0f,0xd4,0x53,0xf4,0x44,0xfd,0x10,0x2f,0x40,0x0f,0xf4,0x03,0xfd,0x00,0xfd }}, - {16, 0xced0, 0, {0x40,0x3b,0x10,0x0f,0xd4,0x23,0xd1,0x04,0x7c,0x43,0x36,0x50,0x0f,0x50,0x03,0xe6 }}, - {16, 0xcee0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xa6,0x00,0xf9,0x10,0x2e,0x62 }}, - {16, 0xcef0, 0, {0x0f,0xd2,0x83,0xe4,0x00,0xbd,0x42,0x3e,0x61,0x0f,0xd0,0x03,0xf6,0xc0,0xc9,0xa2 }}, - {16, 0xcf00, 0, {0x2b,0x40,0x0c,0xd0,0x03,0x34,0x00,0xf9,0x81,0x3e,0x68,0x08,0xc1,0x43,0xfa,0x00 }}, - {16, 0xcf10, 0, {0xf5,0x80,0x3f,0x62,0x0c,0x14,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcf20, 0, {0x38,0x10,0xe1,0x20,0x88,0x11,0x2e,0x10,0x0b,0x80,0x02,0xe0,0x00,0xb8,0x82,0x2e }}, - {16, 0xcf30, 0, {0x10,0x0b,0x80,0x00,0xe3,0xc4,0x88,0xf0,0x22,0x00,0x0b,0x80,0x0a,0x20,0x00,0xe8 }}, - {16, 0xcf40, 0, {0x40,0x2f,0x14,0x08,0x88,0x02,0xe2,0x00,0xb8,0x00,0x2e,0x00,0x08,0x88,0x02,0x8e }}, - {16, 0xcf50, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0xc5,0x00,0xa1,0x00,0x2c,0x40 }}, - {16, 0xcf60, 0, {0x0b,0x10,0x02,0xc4,0x18,0xb1,0x22,0x6c,0xd1,0x0b,0x10,0x26,0xc4,0x00,0x81,0x08 }}, - {16, 0xcf70, 0, {0x2a,0x40,0x88,0x10,0x02,0x04,0x04,0xb5,0xc0,0x0f,0x40,0x0b,0x02,0x02,0x41,0xa0 }}, - {16, 0xcf80, 0, {0xb1,0x40,0x2c,0x40,0x08,0x12,0x02,0x02,0x11,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcf90, 0, {0x18,0x15,0xa4,0x00,0x89,0x06,0x2e,0x40,0x0b,0x90,0x12,0xe4,0x00,0xb9,0x40,0x2e }}, - {16, 0xcfa0, 0, {0x40,0x0b,0xb0,0x82,0xc4,0x02,0x89,0x44,0x22,0x40,0x0a,0x90,0x02,0x24,0x00,0xa9 }}, - {16, 0xcfb0, 0, {0x00,0x27,0x48,0x09,0xb0,0x12,0xec,0x18,0xb9,0x01,0x2e,0x40,0x40,0x90,0x02,0x86 }}, - {16, 0xcfc0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x84,0xe9,0x01,0x3e,0x40 }}, - {16, 0xcfd0, 0, {0x0f,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x72,0x0f,0x90,0x03,0xe7,0x60,0x89,0x10 }}, - {16, 0xcfe0, 0, {0x3a,0x40,0x0c,0x90,0x03,0x24,0x00,0xf9,0x44,0x3c,0x40,0x2d,0x90,0x03,0xe7,0x60 }}, - {16, 0xcff0, 0, {0xf9,0x71,0x3e,0x40,0x28,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd000, 0, {0x28,0x01,0xa4,0x48,0xa9,0x00,0x3e,0xc0,0x0f,0x9a,0x43,0xec,0x00,0xf9,0x20,0x7e }}, - {16, 0xd010, 0, {0xc8,0x0f,0x9a,0x07,0x66,0x00,0x79,0x80,0x7e,0x40,0x0f,0x1c,0x03,0xe7,0x00,0xe9 }}, - {16, 0xd020, 0, {0xa0,0x3e,0x40,0x46,0x80,0x03,0xe0,0x20,0xf9,0x00,0x3c,0x40,0x0f,0x90,0x03,0xca }}, - {16, 0xd030, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0x80,0x00,0xf8,0x00,0x3a,0x00 }}, - {16, 0xd040, 0, {0x0f,0x80,0x03,0xa0,0x08,0xe8,0x40,0x3a,0x10,0x0c,0x83,0x03,0xa1,0xc0,0xf0,0x40 }}, - {16, 0xd050, 0, {0x3e,0x06,0x0f,0x84,0x03,0xe1,0x00,0xf8,0x00,0x3b,0x00,0x0f,0x81,0x03,0x20,0x00 }}, - {16, 0xd060, 0, {0xf8,0x10,0xb2,0x00,0x4c,0x80,0x0b,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd070, 0, {0x28,0x05,0x28,0x00,0xba,0x00,0x2e,0xb0,0x0b,0xe8,0x02,0xe9,0x00,0x3e,0x90,0x02 }}, - {16, 0xd080, 0, {0x81,0x08,0xe4,0x12,0x78,0x00,0xba,0x00,0x2d,0xb0,0x89,0xe8,0x22,0xf8,0x0c,0xba }}, - {16, 0xd090, 0, {0x00,0x6e,0x80,0x03,0xc5,0x03,0x30,0x00,0xba,0x00,0x22,0xa8,0x08,0xa0,0x22,0x8a }}, - {16, 0xd0a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0xb3,0x00,0x28,0xe8 }}, - {16, 0xd0b0, 0, {0x1b,0x31,0x12,0x8c,0xc4,0xa3,0x92,0x2c,0x40,0x88,0x34,0x06,0x8e,0x00,0x93,0x00 }}, - {16, 0xd0c0, 0, {0x2c,0xf0,0x19,0x31,0xa2,0xcc,0x04,0xb3,0x00,0x28,0x80,0x01,0x38,0x02,0x4c,0x00 }}, - {16, 0xd0d0, 0, {0xb3,0x80,0x20,0xe0,0x0a,0xb0,0x12,0x02,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd0e0, 0, {0xa0,0x01,0x1c,0x00,0xb7,0x14,0x2d,0x42,0x0b,0x60,0x02,0xdc,0x00,0xb7,0x81,0x27 }}, - {16, 0xd0f0, 0, {0xe0,0x18,0x60,0x02,0x58,0x18,0xb7,0x22,0x2d,0x80,0x09,0x70,0x22,0xdc,0x00,0xb7 }}, - {16, 0xd100, 0, {0x00,0x2d,0x80,0x0b,0x3b,0x02,0x1d,0xd0,0xbf,0x80,0x28,0xc0,0x8a,0xf2,0x02,0xa0 }}, - {16, 0xd110, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1f,0x80,0xf7,0xa0,0x39,0xe2 }}, - {16, 0xd120, 0, {0x0f,0x68,0x03,0x9e,0x00,0xed,0x84,0x3d,0xe2,0x44,0x78,0x03,0x9e,0x00,0xf7,0xb4 }}, - {16, 0xd130, 0, {0x2d,0xe0,0x0d,0x68,0x03,0xd6,0x00,0xf6,0x80,0x39,0xe0,0x0f,0x79,0x03,0x5e,0x90 }}, - {16, 0xd140, 0, {0xf7,0x81,0x31,0x60,0x2e,0x7c,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd150, 0, {0x08,0x1d,0xad,0x00,0xfb,0x42,0x3e,0xc8,0x0f,0xa0,0x03,0xed,0xa0,0xbb,0x00,0x38 }}, - {16, 0xd160, 0, {0xc8,0x0f,0xb0,0x03,0x68,0x00,0xfb,0x11,0x3e,0x40,0x09,0xb0,0x41,0xec,0x00,0xfa }}, - {16, 0xd170, 0, {0x02,0x3e,0xc0,0x0f,0xb2,0x0b,0xed,0x80,0x3b,0x00,0x36,0x40,0x0d,0xb0,0x23,0x42 }}, - {16, 0xd180, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0x00,0xcf,0xd0,0x33,0xe4 }}, - {16, 0xd190, 0, {0x4f,0xf9,0x03,0xde,0x40,0xdc,0x80,0x36,0xe4,0x0c,0xb9,0x13,0xfe,0x00,0xcf,0x90 }}, - {16, 0xd1a0, 0, {0x37,0xe5,0x0f,0xf8,0x43,0xfe,0x00,0xcf,0x92,0x3f,0xa4,0x0f,0x78,0x03,0x1f,0x00 }}, - {16, 0xd1b0, 0, {0xc5,0x80,0x33,0x60,0x0c,0xf8,0x20,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd1c0, 0, {0xa8,0x11,0xbc,0x00,0x0f,0x10,0x21,0x81,0x0b,0x60,0x03,0x84,0x00,0x8b,0x08,0x21 }}, - {16, 0xd1d0, 0, {0x60,0x0a,0x7b,0x03,0x98,0x00,0x8b,0x10,0x29,0x84,0x0e,0x64,0x22,0xdc,0x40,0xd7 }}, - {16, 0xd1e0, 0, {0x02,0x2d,0x84,0x0b,0x70,0x02,0x1c,0x00,0x85,0x18,0x21,0x40,0x0a,0xf0,0x22,0xaa }}, - {16, 0xd1f0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x00,0xa7,0x14,0x69,0xc0 }}, - {16, 0xd200, 0, {0x1a,0x60,0x12,0xfc,0x01,0xa4,0x10,0x2d,0xc0,0x0a,0x52,0x02,0x45,0x40,0x87,0x0c }}, - {16, 0xd210, 0, {0x21,0x80,0x1b,0x60,0x82,0xd4,0x00,0x86,0x03,0x25,0xe0,0x1b,0x70,0x02,0x5c,0x40 }}, - {16, 0xd220, 0, {0x9d,0x00,0x29,0x40,0x08,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd230, 0, {0x20,0x14,0xcd,0x00,0xa3,0x00,0x28,0xc0,0x1b,0x20,0x22,0x8c,0x11,0xa3,0x00,0x68 }}, - {16, 0xd240, 0, {0xf6,0x0a,0x3c,0x06,0x82,0x00,0x83,0x80,0x28,0x84,0x0a,0x8c,0x82,0xcc,0x44,0x92 }}, - {16, 0xd250, 0, {0x00,0x2c,0xc0,0x0b,0x30,0x02,0x4e,0x00,0x91,0x00,0x28,0x40,0x0a,0x30,0x02,0x88 }}, - {16, 0xd260, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbe,0x22,0xef,0x04,0xba,0xc0 }}, - {16, 0xd270, 0, {0x0f,0x14,0x93,0xec,0x02,0xf1,0xc3,0x3e,0xf0,0x0e,0x90,0x83,0x66,0x00,0xcf,0xd2 }}, - {16, 0xd280, 0, {0x32,0x50,0x0f,0x9c,0x03,0xcb,0x00,0xc9,0x80,0x3e,0x28,0x0f,0xb0,0x03,0x4f,0x00 }}, - {16, 0xd290, 0, {0xd1,0xc0,0xaa,0xc0,0x0c,0x71,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd2a0, 0, {0x80,0x00,0xec,0x20,0xdb,0x00,0x26,0x80,0x0f,0xa0,0x03,0xec,0x08,0x1b,0x00,0x36 }}, - {16, 0xd2b0, 0, {0xc0,0x0f,0x86,0x01,0xe5,0x40,0xfb,0x02,0x3a,0x48,0x0e,0x94,0x03,0xec,0x80,0xf1 }}, - {16, 0xd2c0, 0, {0x84,0x3e,0x00,0x4f,0xb0,0x03,0xad,0xc0,0xeb,0x20,0x36,0xc0,0x0f,0xb0,0x23,0xe0 }}, - {16, 0xd2d0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xdc,0x00,0xcf,0x00,0x3f,0x60 }}, - {16, 0xd2e0, 0, {0x0c,0xe0,0x83,0x3e,0x80,0xed,0x08,0x33,0xd0,0x8f,0x50,0x03,0x9e,0x00,0xdf,0x00 }}, - {16, 0xd2f0, 0, {0x33,0x40,0x0c,0xc0,0x03,0x30,0x00,0xcc,0x10,0x33,0x68,0x0c,0xf0,0x03,0x3c,0x84 }}, - {16, 0xd300, 0, {0x8d,0x90,0x30,0x40,0x0c,0xf0,0x03,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd310, 0, {0x81,0x04,0x6c,0x00,0x8b,0x02,0x2c,0xf4,0x08,0xa8,0x62,0x0c,0x80,0x8b,0x80,0x2a }}, - {16, 0xd320, 0, {0x60,0x0f,0x9c,0x02,0x2e,0x00,0x8b,0x00,0x20,0x60,0x0d,0x98,0x02,0x2c,0x80,0xd8 }}, - {16, 0xd330, 0, {0x00,0x14,0x40,0x08,0x34,0x12,0x2e,0x00,0x8b,0x82,0x32,0x40,0x0d,0xb0,0x03,0x60 }}, - {16, 0xd340, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x8b,0x00,0x2e,0xd0 }}, - {16, 0xd350, 0, {0x08,0xb8,0x02,0x2c,0x00,0x8a,0x84,0x22,0xc0,0x0b,0x88,0x02,0xe4,0xa0,0x83,0x00 }}, - {16, 0xd360, 0, {0x22,0x62,0x0a,0x98,0x02,0x28,0x00,0x89,0x00,0x22,0x00,0x0a,0xb1,0x06,0x2c,0x00 }}, - {16, 0xd370, 0, {0xab,0x00,0x22,0x40,0x08,0xb0,0x02,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd380, 0, {0x08,0x04,0x0c,0x02,0xa3,0x00,0x2c,0xc1,0x08,0x20,0x02,0x0c,0x02,0x8b,0x00,0x28 }}, - {16, 0xd390, 0, {0xc2,0x0a,0x00,0x02,0x44,0x10,0x83,0x10,0x22,0x40,0x0b,0x10,0x06,0x0c,0x00,0x91 }}, - {16, 0xd3a0, 0, {0x04,0xaa,0x00,0x28,0x30,0x02,0x2c,0x00,0xa1,0x01,0x20,0x40,0x09,0xb0,0x02,0x42 }}, - {16, 0xd3b0, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x7c,0x00,0x8f,0x00,0x3e,0xc0 }}, - {16, 0xd3c0, 0, {0x2c,0xa0,0x03,0x29,0x40,0xa8,0x40,0x32,0xcc,0x8b,0x80,0x02,0xe0,0x00,0xcf,0x40 }}, - {16, 0xd3d0, 0, {0x32,0x00,0x0e,0x80,0x0a,0x20,0x00,0x88,0x00,0x22,0x40,0x0c,0xb0,0x03,0x2c,0x04 }}, - {16, 0xd3e0, 0, {0xeb,0x00,0xb2,0x40,0x8c,0xb0,0x03,0x40,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd3f0, 0, {0xa0,0x1d,0xfc,0x00,0xdf,0x00,0x3f,0x40,0x0f,0xe0,0x03,0xfc,0x80,0xff,0x28,0x3d }}, - {16, 0xd400, 0, {0xc0,0x0b,0xc1,0x03,0xb0,0x14,0xff,0x00,0x3f,0x00,0x0d,0xd0,0x03,0xdc,0x00,0xfc }}, - {16, 0xd410, 0, {0x00,0x37,0x40,0x0f,0xf0,0x21,0xfc,0x00,0x1d,0x00,0x7b,0x40,0x8f,0xf0,0x03,0xe0 }}, - {16, 0xd420, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd2,0x00,0xdf,0x00,0x31,0xa0 }}, - {16, 0xd430, 0, {0x4d,0xf0,0x43,0x32,0x00,0xce,0x14,0x1b,0x68,0x0e,0xda,0x23,0xb2,0xc0,0x2f,0x00 }}, - {16, 0xd440, 0, {0x3f,0xc2,0x2c,0xe8,0x03,0x3c,0x40,0xfd,0x08,0x3b,0xc8,0x4c,0xf0,0x83,0x3c,0xa0 }}, - {16, 0xd450, 0, {0xcf,0x00,0x33,0xc4,0x0c,0xf3,0x07,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd460, 0, {0x80,0x10,0xe2,0x00,0x8f,0xc0,0x22,0xa0,0x08,0xfd,0x42,0x2f,0x00,0x8b,0x70,0x22 }}, - {16, 0xd470, 0, {0x1e,0x48,0x89,0x02,0x27,0xc0,0x8f,0x5a,0x2e,0x50,0x48,0x30,0x02,0xbd,0xc0,0xbd }}, - {16, 0xd480, 0, {0x40,0x23,0xc5,0x48,0xf4,0x82,0x3d,0x2c,0x87,0x70,0x22,0xc0,0x08,0xf1,0x03,0xe0 }}, - {16, 0xd490, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xe0,0x00,0x93,0x10,0x26,0x81 }}, - {16, 0xd4a0, 0, {0x49,0x30,0x02,0x80,0x40,0x83,0x20,0x28,0x40,0x0a,0x10,0x02,0x80,0x00,0xa3,0x24 }}, - {16, 0xd4b0, 0, {0x2c,0xca,0x08,0x32,0x82,0x0c,0x00,0x91,0x28,0x20,0xca,0x1b,0x32,0x02,0x0c,0x88 }}, - {16, 0xd4c0, 0, {0x83,0x09,0x20,0xc8,0x09,0x32,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd4d0, 0, {0xc0,0x15,0xa3,0x14,0x8b,0x04,0x26,0x89,0x08,0xb0,0x02,0xac,0x22,0x8b,0x88,0x2a }}, - {16, 0xd4e0, 0, {0x20,0x08,0x98,0x82,0xa6,0x10,0xab,0x00,0x2e,0xca,0x08,0xb0,0x82,0xac,0x00,0xb9 }}, - {16, 0xd4f0, 0, {0x00,0x22,0xc0,0x29,0xb0,0x0a,0x2c,0x01,0x8b,0x00,0x22,0xc0,0x09,0xb0,0x22,0xf0 }}, - {16, 0xd500, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe3,0x00,0xdb,0x00,0x34,0xe2 }}, - {16, 0xd510, 0, {0x0d,0xb0,0x03,0xa3,0x00,0xca,0x80,0xba,0x70,0x0e,0x88,0x03,0xa6,0x00,0xeb,0x00 }}, - {16, 0xd520, 0, {0x3e,0x90,0x0c,0xb5,0x03,0x2c,0x00,0xfb,0x10,0xba,0xc0,0x0e,0xb0,0x03,0x2c,0x02 }}, - {16, 0xd530, 0, {0xcb,0x02,0x32,0xc0,0x09,0xb0,0x02,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd540, 0, {0xe0,0x01,0xb0,0x08,0xff,0x00,0xbb,0xe0,0x0f,0x70,0x03,0x65,0x00,0xf4,0x00,0x35 }}, - {16, 0xd550, 0, {0x40,0x0f,0x40,0x03,0x54,0x00,0xdf,0x00,0x3e,0x40,0x0f,0xf8,0x03,0xec,0x00,0xf7 }}, - {16, 0xd560, 0, {0x01,0x3d,0xc1,0x0e,0x30,0x03,0xec,0x00,0xff,0x00,0x3f,0xc0,0x8e,0xf0,0x03,0xb8 }}, - {16, 0xd570, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa0,0x40,0xeb,0x08,0x3e,0x80 }}, - {16, 0xd580, 0, {0x0d,0xb0,0x03,0xe0,0x00,0xc8,0x00,0x3a,0x51,0x0f,0x82,0x03,0x64,0x20,0xdb,0x00 }}, - {16, 0xd590, 0, {0x3d,0x82,0x0c,0xbc,0x03,0x2c,0x10,0xdb,0x00,0x72,0xc0,0x0d,0xb1,0x03,0x0c,0x20 }}, - {16, 0xd5a0, 0, {0xd3,0x00,0x32,0xc0,0x0f,0xb0,0x0b,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd5b0, 0, {0xc8,0x05,0x01,0x00,0x87,0xc0,0x2e,0xa8,0x08,0xf1,0x12,0xc5,0x40,0x88,0x00,0x22 }}, - {16, 0xd5c0, 0, {0x40,0x0b,0x84,0x02,0x27,0x00,0xaf,0x00,0x2e,0xc0,0x08,0xbc,0x12,0x3c,0x00,0x8b }}, - {16, 0xd5d0, 0, {0x01,0x23,0xc0,0x28,0xf5,0x4a,0x3d,0x28,0xdf,0x00,0x33,0xc0,0x4b,0xf0,0x03,0x32 }}, - {16, 0xd5e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x48,0x80,0xa3,0x90,0x2c,0x00 }}, - {16, 0xd5f0, 0, {0x08,0x30,0x02,0xc1,0x00,0x92,0x04,0x28,0x00,0x0b,0x14,0x12,0x43,0x00,0xb3,0x04 }}, - {16, 0xd600, 0, {0x2c,0x30,0x0a,0xb0,0x0a,0x8c,0x00,0x93,0x00,0x60,0xc0,0x08,0x3c,0x06,0x0e,0x01 }}, - {16, 0xd610, 0, {0xb3,0x00,0x2e,0xc0,0x8b,0x30,0x06,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd620, 0, {0x20,0x01,0x12,0x00,0x87,0x80,0x2d,0x24,0x08,0x78,0x02,0xd2,0x00,0x95,0x80,0x21 }}, - {16, 0xd630, 0, {0xa0,0x0b,0x68,0x02,0x5a,0x20,0x87,0x80,0x2d,0x66,0x1a,0x7c,0x02,0x9e,0x00,0x87 }}, - {16, 0xd640, 0, {0x80,0x21,0xe1,0x18,0x79,0x02,0x9e,0x40,0xb7,0x80,0xa1,0xe0,0x0b,0x78,0x02,0x48 }}, - {16, 0xd650, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x00,0x00,0xe3,0xa0,0x3c,0x40 }}, - {16, 0xd660, 0, {0x0c,0x30,0x03,0xc4,0x22,0xd9,0x00,0x38,0xd4,0x0f,0x30,0x83,0x68,0x40,0xf3,0x00 }}, - {16, 0xd670, 0, {0x3c,0x80,0x0a,0x32,0x02,0x8c,0x00,0xdb,0x00,0xa2,0xc4,0x0c,0x30,0x03,0x0c,0x00 }}, - {16, 0xd680, 0, {0xf3,0x00,0x3c,0xc0,0x0f,0xb1,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd690, 0, {0x40,0x0d,0xb0,0x00,0xff,0x10,0x3f,0x40,0x0e,0xf0,0x03,0xfc,0x00,0xed,0x00,0x3f }}, - {16, 0xd6a0, 0, {0xc0,0x0f,0x30,0x13,0xbc,0x40,0x7f,0x10,0x3f,0xc1,0x2d,0xf0,0x03,0x7c,0x00,0xfb }}, - {16, 0xd6b0, 0, {0x40,0x3f,0xc2,0x0e,0xf4,0x83,0x7c,0x00,0xdf,0x00,0x3f,0xc2,0x0f,0xf0,0x03,0x90 }}, - {16, 0xd6c0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xdb,0xa0,0x32,0xc0 }}, - {16, 0xd6d0, 0, {0x0d,0xb7,0x03,0xe0,0x00,0xca,0x04,0x3e,0x80,0x0f,0xb8,0x03,0x2c,0x10,0xfb,0x00 }}, - {16, 0xd6e0, 0, {0x33,0x00,0x8d,0xb0,0x03,0x2c,0x80,0xe9,0x40,0x3e,0xd2,0x0f,0xb4,0x03,0x2d,0x80 }}, - {16, 0xd6f0, 0, {0xeb,0x20,0xb2,0xc0,0x0f,0xb2,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd700, 0, {0x48,0x11,0x90,0x00,0xb7,0x10,0x11,0xc0,0x08,0x70,0x82,0xd8,0x0a,0x87,0x01,0x2d }}, - {16, 0xd710, 0, {0x80,0x89,0x70,0x03,0xd8,0x08,0xb7,0x0a,0x21,0x40,0x2c,0x70,0x02,0x0d,0xc0,0x85 }}, - {16, 0xd720, 0, {0x01,0x79,0xc8,0x0b,0x32,0x02,0x0d,0x20,0x8f,0x28,0x21,0xc0,0x0b,0x72,0x82,0xd2 }}, - {16, 0xd730, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x40,0x96,0x10,0x97,0x90,0x23,0xe0 }}, - {16, 0xd740, 0, {0x09,0x7a,0x02,0xd6,0x00,0x97,0x80,0x2d,0xf0,0x0b,0x78,0x82,0x1e,0x00,0xb3,0xb0 }}, - {16, 0xd750, 0, {0x21,0xa0,0x08,0x78,0x02,0x1e,0x00,0xa5,0x80,0x2d,0xe0,0x0b,0x7a,0x02,0x1e,0x80 }}, - {16, 0xd760, 0, {0xa7,0xb0,0x21,0xe8,0x0b,0x79,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd770, 0, {0x48,0x14,0xc0,0x00,0xb3,0x00,0x20,0xe2,0x08,0x30,0x02,0xc6,0x40,0x93,0x70,0x2c }}, - {16, 0xd780, 0, {0xc0,0x09,0x3c,0x02,0x8e,0x00,0xb3,0x00,0x20,0xd8,0x08,0x18,0x02,0x0c,0x00,0x81 }}, - {16, 0xd790, 0, {0x90,0x2e,0xc0,0x0b,0x30,0x2a,0x2c,0x10,0x83,0x00,0xa0,0xc0,0x0b,0x30,0x02,0xd2 }}, - {16, 0xd7a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x11,0xb9,0x00,0xda,0x02,0x33,0xb8 }}, - {16, 0xd7b0, 0, {0x0d,0xa0,0x03,0xf8,0x00,0xde,0xc0,0x3f,0xb0,0x4f,0xec,0x06,0x38,0x40,0xfa,0x00 }}, - {16, 0xd7c0, 0, {0xb3,0x90,0x0c,0x6c,0x0b,0x28,0x08,0xea,0x01,0x7e,0x80,0x0f,0xa0,0x03,0x28,0x00 }}, - {16, 0xd7d0, 0, {0xea,0x00,0x32,0x80,0x0f,0xa0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd7e0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x40,0x3a,0x00,0x0f,0x84,0x03,0xe1,0x00,0xe8,0x02,0x3e }}, - {16, 0xd7f0, 0, {0x00,0x0f,0x84,0x03,0xe1,0x40,0xf8,0x00,0x3e,0x00,0x0f,0x81,0x03,0xe0,0x00,0xf8 }}, - {16, 0xd800, 0, {0x00,0x3a,0x00,0x0f,0x80,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xd810, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x20,0xf9,0xc0,0x3e,0x70 }}, - {16, 0xd820, 0, {0x0e,0x90,0x02,0xe4,0x80,0xc9,0x00,0x32,0x42,0x0c,0x98,0x83,0xa4,0x84,0xf9,0x00 }}, - {16, 0xd830, 0, {0xb2,0x60,0x0c,0x90,0x83,0x24,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x1a,0x02,0x24,0x00 }}, - {16, 0xd840, 0, {0xc1,0x00,0xb2,0x40,0x0f,0x90,0x01,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd850, 0, {0x80,0x04,0x65,0x00,0xb9,0x81,0x2c,0x60,0x0d,0x94,0xc2,0xc7,0x08,0x89,0x00,0x22 }}, - {16, 0xd860, 0, {0x40,0x08,0x95,0xc7,0xa4,0x00,0xb9,0x00,0x28,0x70,0xa8,0x94,0x0a,0x24,0x00,0x89 }}, - {16, 0xd870, 0, {0x04,0x2e,0x40,0x28,0x90,0x2a,0x26,0x00,0x89,0x00,0x22,0x40,0x0b,0x90,0x02,0xe0 }}, - {16, 0xd880, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xb9,0x40,0x2e,0x40 }}, - {16, 0xd890, 0, {0x0a,0x90,0x02,0xe5,0x00,0x81,0x00,0xa0,0x40,0x09,0x90,0x42,0xec,0x00,0xb1,0x00 }}, - {16, 0xd8a0, 0, {0x22,0x58,0x08,0x90,0xa2,0x04,0x02,0x89,0x00,0x2e,0x40,0x08,0x90,0x02,0xa4,0xa0 }}, - {16, 0xd8b0, 0, {0x89,0x00,0x22,0x40,0x0b,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd8c0, 0, {0x08,0x04,0x04,0x00,0xb1,0x20,0x2e,0xc0,0x89,0x12,0x02,0xc4,0x80,0x81,0x20,0x20 }}, - {16, 0xd8d0, 0, {0x40,0x61,0x10,0x42,0xc5,0x00,0xb1,0x20,0x28,0x48,0x18,0x90,0x42,0x04,0x80,0x81 }}, - {16, 0xd8e0, 0, {0x28,0x2c,0x48,0x08,0x12,0x82,0x84,0xa0,0x81,0x20,0x20,0x48,0x0b,0x12,0x82,0xc2 }}, - {16, 0xd8f0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x68,0x00,0xf8,0x00,0x2e,0x00 }}, - {16, 0xd900, 0, {0x0e,0x80,0x03,0xe0,0x08,0xc8,0x50,0x32,0x14,0x0d,0x80,0x17,0xe8,0x04,0xf8,0x50 }}, - {16, 0xd910, 0, {0x32,0x14,0x4c,0x05,0x0b,0x21,0x40,0xc8,0x20,0x3e,0x00,0x0c,0x87,0x03,0xa1,0xc2 }}, - {16, 0xd920, 0, {0xc8,0x00,0x32,0x14,0x8f,0x82,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd930, 0, {0x98,0x1d,0xf4,0x00,0xf1,0x10,0x3d,0x40,0x0f,0x91,0x02,0xd4,0x42,0xfd,0x10,0x3f }}, - {16, 0xd940, 0, {0x51,0x0e,0x54,0x13,0xb5,0x00,0xf9,0x10,0x35,0x44,0x2f,0xd0,0x03,0xe4,0x50,0xfd }}, - {16, 0xd950, 0, {0x28,0x3e,0x4e,0x0f,0x90,0x03,0x64,0x00,0xf9,0x38,0x3e,0x44,0x0f,0x92,0x83,0xe6 }}, - {16, 0xd960, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x15,0xf4,0x00,0xfd,0x00,0x3d,0x40 }}, - {16, 0xd970, 0, {0x2c,0xd0,0x03,0xb6,0x00,0xf9,0x82,0x3e,0x40,0x0c,0xd0,0x03,0xf4,0x00,0xf9,0x80 }}, - {16, 0xd980, 0, {0x33,0x70,0x0c,0x50,0x03,0x34,0x00,0xc9,0xc0,0x3e,0x40,0x0c,0xda,0x03,0x16,0x80 }}, - {16, 0xd990, 0, {0xc9,0x40,0x3e,0x62,0x2c,0x98,0x83,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd9a0, 0, {0x38,0x10,0xe0,0x00,0xb8,0x00,0x2e,0x00,0x08,0x80,0x02,0x28,0x00,0xb8,0x50,0x26 }}, - {16, 0xd9b0, 0, {0x00,0x08,0xa0,0x02,0xe8,0x00,0xb8,0x00,0x2a,0x34,0x2a,0xaa,0x0a,0x20,0x00,0x88 }}, - {16, 0xd9c0, 0, {0xc0,0x2e,0x2a,0x08,0x80,0x22,0x21,0x00,0xa8,0x80,0x2e,0x00,0x08,0x80,0x02,0x0e }}, - {16, 0xd9d0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x00,0xb1,0x00,0x2e,0x40 }}, - {16, 0xd9e0, 0, {0x48,0x10,0x06,0x8d,0x00,0xb1,0x00,0x2c,0x40,0x28,0x10,0x02,0xc4,0x00,0xb1,0x40 }}, - {16, 0xd9f0, 0, {0x2c,0x48,0x08,0x10,0x82,0x44,0x00,0x81,0x60,0x2c,0x40,0x28,0x14,0x0a,0x04,0x40 }}, - {16, 0xda00, 0, {0x81,0x20,0x2c,0x40,0x08,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xda10, 0, {0x18,0x05,0xa4,0x40,0xb9,0x00,0x2e,0x40,0x08,0xb0,0x02,0x24,0x00,0xb9,0x28,0x2e }}, - {16, 0xda20, 0, {0x50,0x08,0x90,0x22,0xe4,0x00,0xb9,0x00,0x2e,0x60,0x0b,0x12,0x42,0x64,0x00,0x89 }}, - {16, 0xda30, 0, {0x00,0x2c,0x40,0x09,0x90,0x02,0x24,0x00,0xa9,0x00,0x2c,0x40,0x08,0x10,0x02,0x46 }}, - {16, 0xda40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x05,0xe6,0x00,0xf9,0x00,0x3c,0x42 }}, - {16, 0xda50, 0, {0x0c,0x90,0x03,0xa7,0x40,0xf9,0x40,0x3e,0x70,0x0c,0x98,0x02,0xe5,0x40,0xf9,0x00 }}, - {16, 0xda60, 0, {0x3e,0x40,0x0c,0x98,0x03,0x64,0x06,0xc9,0x01,0x2e,0x40,0x0c,0x90,0x03,0x24,0x04 }}, - {16, 0xda70, 0, {0xc9,0x00,0x3e,0x40,0x0c,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xda80, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x83,0xe6,0x10,0xf9,0x00,0x36 }}, - {16, 0xda90, 0, {0x68,0x0f,0x9c,0x03,0xe6,0x00,0xf9,0x00,0x3a,0x40,0x0e,0x98,0x93,0xa4,0x00,0xf9 }}, - {16, 0xdaa0, 0, {0x00,0x3e,0x40,0x0e,0x90,0x83,0xc4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0x8a }}, - {16, 0xdab0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0xa0,0x00,0xf8,0x00,0x3e,0x04 }}, - {16, 0xdac0, 0, {0x0c,0x80,0x03,0x21,0x02,0xc8,0x40,0x32,0x00,0x0f,0x80,0x03,0xe1,0x00,0xf0,0x00 }}, - {16, 0xdad0, 0, {0x3e,0x02,0x0c,0x80,0x03,0x20,0x00,0xf8,0x00,0x3e,0x00,0x0c,0x00,0x03,0x20,0x00 }}, - {16, 0xdae0, 0, {0xc8,0x00,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdaf0, 0, {0x28,0x15,0x3a,0x00,0xbe,0x02,0x2f,0xb0,0x08,0x68,0x12,0x38,0x00,0x8a,0x04,0x2a }}, - {16, 0xdb00, 0, {0x80,0x0b,0xe0,0x42,0xfb,0x20,0xba,0x00,0x2f,0x91,0x08,0xe0,0x02,0x28,0x00,0xba }}, - {16, 0xdb10, 0, {0x00,0x26,0x80,0x08,0xee,0x0a,0x38,0x00,0x8a,0x00,0x22,0x80,0x0b,0xa0,0x02,0x8a }}, - {16, 0xdb20, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x42,0x00,0xb3,0x00,0x2c,0xc2 }}, - {16, 0xdb30, 0, {0x28,0x38,0x0a,0x48,0x00,0x83,0x04,0x22,0xc0,0x0b,0x10,0x02,0xcd,0x80,0xb3,0x00 }}, - {16, 0xdb40, 0, {0x2e,0xc0,0x08,0x1c,0x02,0x24,0x00,0xb3,0x00,0x2c,0xc0,0x08,0x34,0x12,0x0e,0x40 }}, - {16, 0xdb50, 0, {0x83,0x00,0x20,0xc0,0x0b,0x30,0x12,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdb60, 0, {0xa0,0x01,0x11,0x00,0xb7,0x00,0x2f,0xc0,0x08,0x70,0xa2,0x4e,0x00,0x8f,0xb0,0x21 }}, - {16, 0xdb70, 0, {0xcc,0x0b,0x60,0x12,0xdc,0x10,0xb7,0x30,0x2d,0xc0,0x08,0xd0,0x82,0x14,0x80,0xb7 }}, - {16, 0xdb80, 0, {0x12,0x25,0xc8,0x28,0x60,0x02,0x14,0x00,0x87,0xb2,0x21,0xcc,0x0b,0x31,0x02,0xa8 }}, - {16, 0xdb90, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xf7,0x80,0x3d,0xe0 }}, - {16, 0xdba0, 0, {0x0c,0x38,0x03,0x56,0x00,0xc7,0x90,0xb1,0xe4,0x0f,0x78,0x03,0xde,0x00,0xf7,0x90 }}, - {16, 0xdbb0, 0, {0x1f,0x60,0x2c,0x48,0x0b,0x16,0xa0,0xf7,0x80,0x3c,0xf4,0x0c,0x38,0x03,0x1e,0x00 }}, - {16, 0xdbc0, 0, {0xcf,0xa0,0xb1,0xe8,0x0f,0x7b,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdbd0, 0, {0x08,0x0d,0xa0,0x00,0xf8,0x00,0x3e,0xc0,0x0b,0xb0,0x03,0xac,0x00,0xf3,0x21,0x3e }}, - {16, 0xdbe0, 0, {0xc8,0x07,0xb0,0x02,0xe4,0x00,0xfb,0x20,0x3f,0x40,0x0f,0x80,0x03,0xe4,0x80,0xfb }}, - {16, 0xdbf0, 0, {0x00,0x36,0xd0,0x0f,0xa0,0x03,0xe0,0x08,0xfb,0x42,0x3e,0xd8,0x0f,0xb0,0x03,0xc2 }}, - {16, 0xdc00, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf0,0x80,0xcf,0x80,0x31,0xe1 }}, - {16, 0xdc10, 0, {0x0c,0xf8,0x03,0xda,0x10,0xef,0x80,0x3f,0xe4,0x0f,0xd8,0x03,0xfe,0x10,0xff,0x82 }}, - {16, 0xdc20, 0, {0x3f,0xe0,0x4c,0xd8,0x1b,0x16,0x20,0xcf,0x80,0x3f,0xe0,0x4c,0xd8,0x30,0xee,0x40 }}, - {16, 0xdc30, 0, {0xff,0xc0,0xb3,0xf4,0x0f,0xf8,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdc40, 0, {0xa8,0x01,0x98,0x20,0x83,0x40,0x21,0xc0,0x08,0x71,0x02,0xdc,0x84,0x87,0x20,0x2d }}, - {16, 0xdc50, 0, {0xc0,0x0b,0x60,0x02,0xd9,0x60,0xf7,0x00,0x2d,0xc0,0x08,0xf0,0x82,0x14,0x04,0x87 }}, - {16, 0xdc60, 0, {0x00,0x2d,0xc0,0x08,0xf0,0x03,0x1e,0x00,0xb7,0x20,0x21,0xc0,0x8b,0x70,0x02,0xea }}, - {16, 0xdc70, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x00,0x87,0x00,0x21,0x80 }}, - {16, 0xdc80, 0, {0x08,0x70,0x02,0xf5,0x04,0x27,0x00,0x2d,0xc0,0x8b,0x70,0x02,0xdc,0x00,0xb7,0x00 }}, - {16, 0xdc90, 0, {0x2c,0x50,0x08,0x40,0x02,0x14,0x00,0x87,0x00,0x2d,0xc0,0x08,0x50,0x02,0x5c,0x04 }}, - {16, 0xdca0, 0, {0xb7,0x00,0xa1,0xc0,0x8b,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdcb0, 0, {0x20,0x14,0xc8,0x00,0x80,0x00,0x00,0x80,0x08,0x30,0x02,0xce,0x00,0x83,0xc0,0x2c }}, - {16, 0xdcc0, 0, {0xd0,0x4b,0x30,0x02,0xce,0x00,0xab,0x02,0x2c,0x40,0x48,0xbc,0x02,0x04,0x00,0x83 }}, - {16, 0xdcd0, 0, {0x00,0x2c,0xc0,0x08,0x10,0x02,0x00,0x08,0xb3,0x00,0x20,0xc0,0x09,0x30,0x02,0xc8 }}, - {16, 0xdce0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x83,0x40,0xc8,0x00,0x30,0xc0 }}, - {16, 0xdcf0, 0, {0x2c,0xb0,0x03,0xec,0x00,0xef,0x88,0x3f,0xe6,0x07,0xb1,0x83,0xe1,0x00,0xbf,0x00 }}, - {16, 0xdd00, 0, {0x3e,0xe0,0x0c,0xb8,0x03,0x34,0x00,0xcf,0x00,0x3f,0xc0,0x2c,0xb0,0x03,0x68,0x10 }}, - {16, 0xdd10, 0, {0xff,0x00,0x33,0xc0,0x0f,0xf0,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdd20, 0, {0x80,0x00,0xe4,0x00,0xf1,0x40,0x3e,0xc0,0x0f,0xb4,0x03,0xed,0x40,0xfb,0x08,0x3e }}, - {16, 0xdd30, 0, {0xc0,0x0f,0xa0,0x03,0xe5,0x20,0xfb,0x00,0x3e,0xe0,0x0d,0xb0,0x83,0xe4,0x00,0xf3 }}, - {16, 0xdd40, 0, {0x00,0x3e,0xc0,0x0f,0x80,0x03,0xc4,0x00,0xfb,0x00,0x3e,0xc0,0x0f,0x30,0x03,0xe0 }}, - {16, 0xdd50, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xca,0x00,0x33,0xe0 }}, - {16, 0xdd60, 0, {0x4e,0xf0,0x03,0x34,0x00,0xff,0x00,0x3f,0xc0,0x8f,0xe8,0x03,0xf0,0x00,0xff,0x00 }}, - {16, 0xdd70, 0, {0xb1,0x40,0x0c,0xe0,0x03,0x34,0x00,0xef,0x00,0xb3,0xc0,0x0c,0xf0,0x03,0x38,0x00 }}, - {16, 0xdd80, 0, {0xcf,0x00,0x3d,0xc0,0x0a,0xf0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdd90, 0, {0x81,0x04,0x62,0x22,0x88,0x90,0x22,0xe0,0x08,0x3c,0x02,0x2e,0x08,0xbb,0x01,0x2e }}, - {16, 0xdda0, 0, {0xc0,0x0b,0xa0,0x02,0x66,0x00,0xbb,0x00,0x22,0xa0,0x08,0xa9,0x02,0x24,0x00,0xbb }}, - {16, 0xddb0, 0, {0x00,0x22,0xc0,0x28,0x2c,0x02,0xa2,0x00,0xdb,0x00,0x2e,0xc0,0x0a,0xb0,0x02,0xa0 }}, - {16, 0xddc0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x22,0x00,0x98,0x00,0x22,0xc8 }}, - {16, 0xddd0, 0, {0x0a,0x98,0x02,0x27,0x04,0xbb,0x00,0x2e,0xc0,0x0b,0xb1,0x02,0xe2,0x00,0xbb,0x00 }}, - {16, 0xdde0, 0, {0x22,0xe2,0x08,0xb0,0x02,0xa4,0x00,0xab,0x00,0x20,0xc0,0x0a,0x88,0x82,0x23,0x00 }}, - {16, 0xddf0, 0, {0x8b,0x00,0x2e,0xc0,0x08,0xb0,0x02,0xa0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xde00, 0, {0x08,0x14,0x04,0x00,0x91,0x40,0x22,0xc0,0x08,0x10,0x02,0x0c,0x00,0xb3,0x00,0x2c }}, - {16, 0xde10, 0, {0xc0,0x4b,0x28,0x22,0x40,0x04,0xb3,0x00,0x20,0xc0,0x28,0x30,0x0a,0x04,0x04,0xb3 }}, - {16, 0xde20, 0, {0x00,0x60,0xc0,0x08,0x00,0x02,0x84,0x20,0x93,0x00,0x2c,0xc0,0x0a,0x30,0x02,0x82 }}, - {16, 0xde30, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x60,0x00,0xda,0x40,0xb2,0x80 }}, - {16, 0xde40, 0, {0x0e,0x90,0x03,0x24,0x00,0xff,0x00,0x3f,0xc0,0x8f,0xa0,0x03,0xe0,0x09,0xff,0x00 }}, - {16, 0xde50, 0, {0x32,0x40,0x08,0xa0,0x0b,0x34,0x00,0xeb,0x00,0x31,0xc0,0x0c,0x80,0x03,0x28,0x80 }}, - {16, 0xde60, 0, {0xc7,0x00,0x3f,0xc0,0x0c,0xf0,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xde70, 0, {0xa0,0x15,0xd0,0x00,0xec,0x20,0x3f,0x00,0x0f,0xc0,0x0b,0xfc,0x10,0xff,0x01,0x3f }}, - {16, 0xde80, 0, {0xc0,0x0f,0xe0,0x03,0xf4,0x00,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xf4,0x00,0xff }}, - {16, 0xde90, 0, {0x00,0x3f,0xc0,0x4f,0xc0,0x01,0xf0,0x08,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xdea0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xcc,0x90,0x37,0x20 }}, - {16, 0xdeb0, 0, {0x0e,0xf0,0x13,0xbd,0x04,0xd4,0xc1,0x33,0x2c,0x4c,0xd9,0x23,0x32,0x60,0xff,0x20 }}, - {16, 0xdec0, 0, {0x3d,0xe0,0x4f,0xc1,0x03,0xb6,0x40,0xcd,0x00,0x37,0xe0,0x0c,0xe2,0x8b,0x10,0xc0 }}, - {16, 0xded0, 0, {0xcd,0x00,0x33,0xc6,0x0f,0xd8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdee0, 0, {0x80,0x10,0xee,0x08,0x8a,0x20,0x22,0x00,0x08,0xb7,0x02,0x2d,0x00,0x8a,0x00,0xb6 }}, - {16, 0xdef0, 0, {0x3c,0x08,0x99,0x02,0x27,0x84,0xbf,0x68,0x2e,0x82,0x0b,0x01,0x02,0x24,0x40,0xd9 }}, - {16, 0xdf00, 0, {0x42,0x20,0xc0,0x8a,0xac,0x02,0x2d,0xc2,0x82,0x48,0xa2,0xd0,0x0b,0x82,0x02,0x20 }}, - {16, 0xdf10, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x88,0x04,0x26,0x80 }}, - {16, 0xdf20, 0, {0x2a,0x30,0xc2,0xa5,0x80,0xa9,0x21,0x28,0x00,0x8a,0x00,0x02,0x00,0x00,0xa3,0x10 }}, - {16, 0xdf30, 0, {0x2c,0xc8,0x0b,0x00,0x02,0xc4,0x90,0x83,0x42,0x24,0xc1,0x08,0x00,0x02,0x40,0x88 }}, - {16, 0xdf40, 0, {0xa3,0x60,0xa8,0xc0,0x0b,0x00,0xc2,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdf50, 0, {0xc0,0x15,0xac,0x06,0x8a,0x00,0x22,0xe0,0x48,0xb0,0x02,0x2e,0x02,0xab,0x80,0x2e }}, - {16, 0xdf60, 0, {0x20,0x4a,0x8c,0x02,0x26,0x20,0xbb,0x00,0x6e,0x80,0x0b,0x30,0xc2,0x46,0x04,0x9b }}, - {16, 0xdf70, 0, {0x0a,0xa2,0xc0,0x0a,0x80,0x12,0x6c,0x40,0xa8,0x00,0x2a,0xc0,0x0b,0x8c,0x02,0x30 }}, - {16, 0xdf80, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xc1,0x09,0x36,0x61 }}, - {16, 0xdf90, 0, {0x0e,0x32,0x03,0xab,0x20,0xf8,0x84,0x3a,0x78,0x2e,0x98,0x03,0x26,0x00,0xeb,0x00 }}, - {16, 0xdfa0, 0, {0x3e,0x40,0x4f,0x90,0x03,0xe2,0x00,0xc9,0x40,0x36,0xe0,0x0c,0xb4,0x03,0x6e,0x00 }}, - {16, 0xdfb0, 0, {0xeb,0x00,0x3a,0xc0,0x0f,0x88,0x03,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdfc0, 0, {0xe0,0x01,0xbc,0x00,0xfd,0x00,0x3f,0x40,0x0f,0xfa,0x13,0xf8,0x10,0xdc,0x04,0x27 }}, - {16, 0xdfd0, 0, {0x40,0x0d,0x50,0x43,0xf4,0x00,0xff,0x00,0x3f,0x40,0x0f,0xd9,0x03,0xb0,0x00,0xf9 }}, - {16, 0xdfe0, 0, {0x01,0x3f,0xf0,0x0f,0xf0,0x23,0xb2,0x00,0xd4,0xa0,0x37,0xc0,0x0f,0xc0,0x0b,0xf8 }}, - {16, 0xdff0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x20,0xeb,0x10,0xf2,0x00 }}, - {16, 0xe000, 0, {0x0e,0xb4,0x03,0x21,0x80,0xc9,0x40,0x3a,0x48,0x0f,0x90,0x13,0xe1,0x20,0xfb,0x00 }}, - {16, 0xe010, 0, {0x3e,0xc0,0x0c,0x84,0x03,0x24,0x00,0xfb,0x01,0x36,0xe0,0x0c,0x74,0x0b,0x9c,0x00 }}, - {16, 0xe020, 0, {0xcf,0x00,0x32,0xe0,0x0f,0x84,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe030, 0, {0xc8,0x05,0x1e,0x00,0x8b,0x80,0x20,0x40,0x08,0xb8,0x02,0x83,0x80,0x81,0xa0,0x22 }}, - {16, 0xe040, 0, {0x78,0x0b,0x91,0x83,0xe3,0x00,0xbf,0x00,0x0e,0xc1,0x0a,0xb4,0x03,0x64,0x04,0xb9 }}, - {16, 0xe050, 0, {0x50,0x32,0xc0,0x0a,0xb2,0x02,0x20,0x00,0x88,0x00,0x23,0xd4,0x0b,0x88,0x02,0xf2 }}, - {16, 0xe060, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x42,0xa0,0x80,0x20,0x00 }}, - {16, 0xe070, 0, {0x48,0x00,0x02,0x0d,0x06,0x80,0x80,0x2a,0xd0,0x03,0x00,0x02,0xc8,0x00,0xb3,0x00 }}, - {16, 0xe080, 0, {0x2c,0xc0,0x08,0x36,0x02,0x40,0x00,0xb9,0x02,0x22,0xc2,0x8b,0x26,0x02,0x0c,0x10 }}, - {16, 0xe090, 0, {0x01,0x02,0x24,0xc0,0x4b,0xa1,0x02,0xf8,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0a0, 0, {0x20,0x01,0x1e,0x08,0x8e,0x80,0x21,0x21,0x08,0x28,0xc2,0x9e,0x00,0x8e,0x80,0x21 }}, - {16, 0xe0b0, 0, {0x60,0x0b,0x78,0x02,0x9e,0x20,0xb7,0x82,0x2f,0xa1,0x0a,0x78,0x02,0x5e,0x00,0xb5 }}, - {16, 0xe0c0, 0, {0x91,0xa1,0xe0,0x0b,0x29,0x02,0x32,0x44,0x86,0x80,0xa5,0xe0,0x0b,0x4c,0x02,0xc8 }}, - {16, 0xe0d0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xe1,0x00,0x22,0x80 }}, - {16, 0xe0e0, 0, {0x0e,0x00,0x0b,0x24,0x00,0xc0,0x44,0x28,0xad,0x0f,0x20,0x02,0xc8,0x00,0xf3,0x00 }}, - {16, 0xe0f0, 0, {0x1c,0xc0,0x0c,0x01,0x03,0x48,0x4c,0xf2,0x04,0x30,0xc0,0x0f,0x15,0x03,0x80,0x40 }}, - {16, 0xe100, 0, {0xc1,0x00,0x14,0xc8,0x0f,0x00,0x03,0xda,0x02,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe110, 0, {0x40,0x1d,0x9c,0x40,0xf7,0x00,0x3f,0xc0,0x8f,0xc0,0x03,0xe4,0x00,0xfa,0x01,0x3f }}, - {16, 0xe120, 0, {0xc0,0x0f,0xf0,0x23,0xfc,0x08,0xfb,0x00,0x3f,0x80,0x0f,0xf0,0x01,0xfc,0x10,0xff }}, - {16, 0xe130, 0, {0x00,0x3f,0xc0,0x0e,0xd1,0x03,0xfc,0x42,0xfe,0x80,0x3b,0xc0,0x0f,0xc0,0x03,0xd0 }}, - {16, 0xe140, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x40,0xc8,0x00,0x3e,0xc0 }}, - {16, 0xe150, 0, {0x0f,0x90,0x03,0xee,0x08,0xcb,0x00,0x32,0xc0,0x0f,0xa0,0x23,0xe6,0x03,0xcb,0x4c }}, - {16, 0xe160, 0, {0x32,0x40,0x0f,0xb0,0x07,0xe8,0x00,0xf9,0x00,0x16,0x40,0x0c,0xa0,0x0b,0x6c,0x00 }}, - {16, 0xe170, 0, {0xcf,0x02,0x32,0xc5,0x0c,0x80,0x03,0x02,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe180, 0, {0x48,0x11,0x9c,0x80,0x84,0x04,0x2d,0xc1,0x0b,0x40,0x40,0xdc,0x00,0x87,0x04,0x21 }}, - {16, 0xe190, 0, {0xc0,0x4b,0x70,0x12,0xfc,0x01,0x8f,0x60,0x29,0x40,0x0b,0x70,0x13,0x9c,0x00,0xb5 }}, - {16, 0xe1a0, 0, {0x00,0xa3,0x40,0x0a,0x60,0x02,0x00,0x00,0x84,0x00,0x21,0xc0,0x08,0x40,0x02,0x12 }}, - {16, 0xe1b0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x87,0x80,0x2d,0xa2 }}, - {16, 0xe1c0, 0, {0x0b,0x4c,0x16,0xd6,0x08,0x97,0x88,0x21,0xa0,0x4b,0x68,0x02,0xde,0x04,0xa7,0x80 }}, - {16, 0xe1d0, 0, {0x21,0xe0,0x0b,0x48,0x02,0xda,0x04,0xb6,0x82,0x25,0x60,0x0a,0xe8,0x62,0x1e,0x00 }}, - {16, 0xe1e0, 0, {0x87,0x80,0x20,0xe8,0x08,0x48,0x02,0x08,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1f0, 0, {0x48,0x14,0xcc,0x00,0x8b,0x80,0x6c,0xf0,0x0b,0x3c,0x02,0xce,0x46,0x9b,0xc0,0x20 }}, - {16, 0xe200, 0, {0xe4,0x0b,0x3c,0x02,0xcc,0x20,0xa3,0x00,0x28,0xe0,0x0b,0x30,0x02,0x8d,0x80,0xb1 }}, - {16, 0xe210, 0, {0x80,0x22,0x44,0x0a,0x21,0x0a,0x03,0x82,0x80,0x80,0xa0,0xc0,0x08,0x06,0x0a,0x12 }}, - {16, 0xe220, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x02,0xce,0x80,0x3f,0xa0 }}, - {16, 0xe230, 0, {0x0f,0xe0,0x03,0xfa,0x40,0xde,0xc0,0xb3,0x90,0x0f,0xea,0x13,0xf9,0x08,0xea,0x04 }}, - {16, 0xe240, 0, {0x33,0x82,0x8f,0xe4,0x03,0xfb,0x08,0xfe,0xa0,0x36,0xa0,0x0c,0xac,0x0b,0x6b,0x82 }}, - {16, 0xe250, 0, {0xc6,0xa0,0x32,0x80,0x2c,0xe4,0x03,0x3a,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe260, 0, {0x48,0x00,0xe0,0x00,0xf8,0x90,0x3e,0x02,0x0f,0x80,0x83,0xe1,0x00,0xe8,0x20,0x3e }}, - {16, 0xe270, 0, {0x03,0x0f,0x82,0x03,0xe1,0x40,0xd8,0x00,0x3e,0x20,0x0f,0x00,0x93,0xa0,0x40,0xf8 }}, - {16, 0xe280, 0, {0x00,0x3e,0x10,0x8f,0x08,0x0b,0xf0,0x00,0xfc,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xe290, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xe9,0x00,0x36,0x40 }}, - {16, 0xe2a0, 0, {0x0f,0x94,0x07,0xe6,0x00,0xf9,0x80,0xb0,0x40,0x0c,0x94,0x03,0xe4,0x40,0xf9,0x00 }}, - {16, 0xe2b0, 0, {0x32,0x40,0x0f,0x94,0x0b,0xa4,0x00,0x71,0xc0,0x32,0x40,0x2c,0x94,0x23,0x24,0x02 }}, - {16, 0xe2c0, 0, {0xc9,0x00,0x32,0x40,0x0c,0x90,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2d0, 0, {0x80,0x04,0x44,0x00,0x89,0x00,0x22,0x40,0x0b,0x98,0x02,0xe6,0x60,0xb9,0x00,0x22 }}, - {16, 0xe2e0, 0, {0x60,0x0a,0x9c,0x02,0xe6,0x24,0xb9,0x04,0x36,0x40,0x0b,0x98,0x00,0x24,0x00,0xb9 }}, - {16, 0xe2f0, 0, {0x80,0xa2,0x52,0x08,0x90,0x02,0x24,0x00,0x89,0x40,0x22,0x40,0x68,0x94,0x02,0x20 }}, - {16, 0xe300, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x00,0xa9,0x00,0x26,0x40 }}, - {16, 0xe310, 0, {0x03,0x94,0x02,0xe4,0x01,0xb9,0x10,0x22,0x55,0x08,0x90,0x22,0xe4,0x00,0xb1,0x00 }}, - {16, 0xe320, 0, {0x26,0x40,0x0b,0x90,0x00,0x2c,0x09,0xb9,0x00,0x22,0x60,0x08,0x90,0x0a,0x1c,0x04 }}, - {16, 0xe330, 0, {0x8d,0x08,0xa0,0x40,0x08,0x10,0x82,0x0e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe340, 0, {0x08,0x04,0x06,0x00,0x81,0x00,0x20,0x50,0x0b,0x12,0x42,0xc4,0x80,0xb1,0x04,0x20 }}, - {16, 0xe350, 0, {0x50,0x0a,0x14,0x02,0xc5,0x00,0xb1,0x22,0x24,0x40,0x0b,0x12,0x22,0x04,0x01,0xb1 }}, - {16, 0xe360, 0, {0x40,0x20,0x50,0x08,0x10,0x0a,0x15,0x00,0x85,0x40,0x28,0x50,0x08,0x14,0x0a,0x0a }}, - {16, 0xe370, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xe8,0x50,0x36,0x00 }}, - {16, 0xe380, 0, {0x0f,0x85,0x02,0xe1,0x40,0xf8,0x50,0x32,0x00,0x0c,0xa0,0x23,0xe0,0x10,0xf8,0x50 }}, - {16, 0xe390, 0, {0xb2,0x14,0x0f,0xa5,0x03,0xa1,0x48,0xfa,0x00,0xb2,0x00,0x0c,0x80,0x03,0x20,0x04 }}, - {16, 0xe3a0, 0, {0xc4,0x02,0x32,0x00,0x0c,0x00,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3b0, 0, {0x98,0x1d,0xe5,0x00,0xfd,0x00,0x3f,0x40,0x0f,0xd1,0x03,0xd4,0x44,0xf5,0x00,0x3f }}, - {16, 0xe3c0, 0, {0x51,0x0f,0xd4,0x03,0xf5,0x00,0xf9,0x10,0x3b,0x40,0x0f,0xd1,0x00,0xf5,0x10,0xf5 }}, - {16, 0xe3d0, 0, {0x40,0x7f,0x40,0x0f,0x54,0x2b,0xe5,0x00,0xf9,0x40,0x36,0x50,0x0f,0xd0,0x03,0xe6 }}, - {16, 0xe3e0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x10,0xbd,0x40,0x33,0x40 }}, - {16, 0xe3f0, 0, {0x0f,0xda,0x03,0x37,0x80,0xcd,0x00,0x3f,0x40,0x0f,0xd0,0x03,0xf4,0x00,0xe9,0xa0 }}, - {16, 0xe400, 0, {0x3e,0x40,0x0c,0xde,0x17,0xa4,0x08,0xfd,0xc0,0x33,0x41,0x8d,0xda,0x13,0x26,0xa0 }}, - {16, 0xe410, 0, {0xf9,0xa8,0x32,0x78,0x0c,0xb4,0x0b,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe420, 0, {0x38,0x10,0xe1,0x00,0xb8,0xa0,0x36,0x20,0x0b,0x8a,0x82,0xa2,0x80,0x2a,0xa8,0x2e }}, - {16, 0xe430, 0, {0x00,0x0b,0x80,0x12,0xe0,0x04,0xb8,0xa1,0x2e,0x28,0x4a,0x8e,0x02,0x2a,0xa0,0xba }}, - {16, 0xe440, 0, {0xc0,0x22,0x28,0x08,0x85,0x02,0x21,0x08,0xb8,0xe8,0xa2,0x3c,0x08,0xc8,0x02,0x0e }}, - {16, 0xe450, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc5,0x00,0xb9,0x00,0x20,0x4a }}, - {16, 0xe460, 0, {0x0b,0x14,0x02,0x05,0x80,0x01,0x00,0x2c,0x41,0x0b,0x10,0x02,0xc4,0x04,0xa1,0x4a }}, - {16, 0xe470, 0, {0x2e,0x42,0x08,0x14,0x02,0x84,0x10,0xb1,0x60,0xa0,0x4a,0x09,0x10,0x02,0x44,0x00 }}, - {16, 0xe480, 0, {0xb5,0x01,0x29,0x40,0x18,0xd2,0x02,0x12,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe490, 0, {0x18,0x15,0xa4,0x00,0xb9,0x21,0x26,0x40,0x0b,0x96,0x02,0xa4,0x10,0xa9,0x00,0x2e }}, - {16, 0xe4a0, 0, {0x40,0x0b,0x96,0x12,0xe4,0x20,0xb9,0x00,0x2e,0x41,0x0a,0x90,0x42,0x24,0x00,0xb9 }}, - {16, 0xe4b0, 0, {0x00,0x22,0x41,0x08,0x98,0x22,0x64,0x00,0xb9,0x20,0x2b,0x41,0x28,0xd4,0x02,0x06 }}, - {16, 0xe4c0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x11,0xe4,0x00,0xf9,0xe0,0x32,0x58 }}, - {16, 0xe4d0, 0, {0x0f,0x98,0x03,0x26,0x40,0xc9,0x40,0x3e,0x58,0x0f,0x9c,0x03,0xe4,0x00,0xe9,0x00 }}, - {16, 0xe4e0, 0, {0x6e,0x40,0x0c,0x9a,0x02,0xa6,0x00,0xf9,0x44,0x32,0x40,0x0d,0x9a,0x0b,0x64,0x84 }}, - {16, 0xe4f0, 0, {0xf9,0x00,0xba,0x40,0x0c,0x18,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe500, 0, {0x28,0x01,0xa4,0x00,0xf9,0x00,0x3e,0x50,0x0f,0x90,0x03,0xe6,0x00,0xf9,0x04,0x3e }}, - {16, 0xe510, 0, {0x48,0x0f,0x90,0x03,0xe4,0x40,0xf9,0x00,0x3e,0x65,0x0f,0x99,0x81,0xe4,0x50,0xf9 }}, - {16, 0xe520, 0, {0x20,0x3e,0x40,0x8f,0x90,0x03,0xa4,0x80,0xf9,0x00,0x34,0x40,0x0f,0x92,0x03,0xd2 }}, - {16, 0xe530, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xf8,0x40,0x3e,0x10 }}, - {16, 0xe540, 0, {0x0e,0x84,0x03,0x60,0x08,0xc8,0x00,0x3e,0x08,0x0f,0x80,0x83,0xe0,0x28,0xe8,0x04 }}, - {16, 0xe550, 0, {0x3e,0x00,0x0c,0x84,0x03,0x21,0x1c,0xf0,0x48,0x32,0x00,0x0b,0x00,0x03,0xe0,0x02 }}, - {16, 0xe560, 0, {0xc0,0x00,0x32,0x00,0x0c,0xc0,0x0b,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe570, 0, {0x28,0x05,0x38,0x00,0xb2,0x88,0x2e,0x80,0x08,0xe0,0x03,0x7a,0x80,0x8e,0x00,0x2f }}, - {16, 0xe580, 0, {0xa0,0x0b,0xe8,0x02,0xf9,0x10,0xba,0x00,0x2c,0x80,0x28,0xe4,0x02,0x28,0x00,0xbe }}, - {16, 0xe590, 0, {0x40,0x23,0xb8,0x08,0xe8,0x02,0xe8,0x04,0xca,0x20,0xa2,0x80,0x08,0xe8,0x02,0x0a }}, - {16, 0xe5a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x01,0xb3,0x00,0x2c,0x40 }}, - {16, 0xe5b0, 0, {0x08,0xb8,0x42,0x6c,0x02,0x83,0x00,0x2c,0xe0,0x0b,0x38,0x00,0xcf,0x40,0xb3,0x00 }}, - {16, 0xe5c0, 0, {0x2c,0xc0,0x08,0xb4,0x0a,0x0c,0x00,0xb3,0x40,0xa2,0x82,0x0a,0x39,0x02,0xcc,0x00 }}, - {16, 0xe5d0, 0, {0x93,0x80,0xa0,0xc0,0x29,0x20,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5e0, 0, {0xa0,0x01,0x1d,0x00,0xb7,0x00,0x2d,0x64,0x28,0x74,0x02,0x40,0x00,0x87,0x05,0x2d }}, - {16, 0xe5f0, 0, {0x90,0x0b,0x74,0x02,0xdc,0x10,0xb7,0x30,0x2d,0xc8,0x08,0x34,0x06,0x1c,0x80,0xb7 }}, - {16, 0xe600, 0, {0x00,0xa1,0xc0,0x0a,0x70,0x02,0xde,0x80,0x83,0x00,0x01,0x00,0x09,0x60,0x82,0x20 }}, - {16, 0xe610, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1a,0x00,0xf7,0x80,0x3d,0x60 }}, - {16, 0xe620, 0, {0x0e,0xd8,0x0b,0x5e,0x00,0xc7,0x80,0x3d,0xe0,0x0f,0x68,0x03,0xde,0x10,0xf7,0xa9 }}, - {16, 0xe630, 0, {0x7f,0xe8,0x48,0x78,0x03,0x1f,0x30,0xff,0x94,0x33,0xa0,0x0e,0x78,0x03,0xcf,0x24 }}, - {16, 0xe640, 0, {0xd6,0x80,0xb1,0xe0,0x0d,0xf8,0x43,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe650, 0, {0x08,0x1d,0xac,0x00,0xbb,0x00,0x0c,0x40,0x0f,0xb0,0x03,0xec,0x08,0xf9,0x00,0x3e }}, - {16, 0xe660, 0, {0x00,0x0f,0x90,0x41,0xec,0x00,0xfb,0x61,0x7e,0xd0,0x0f,0xb0,0x03,0xec,0x80,0xfb }}, - {16, 0xe670, 0, {0x40,0x3f,0x9b,0x0c,0xb0,0x03,0xed,0x90,0xfa,0x00,0x3c,0x00,0x0e,0xb0,0x03,0xc2 }}, - {16, 0xe680, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xde,0x00,0xef,0x80,0x33,0x60 }}, - {16, 0xe690, 0, {0x0d,0xd8,0x03,0x36,0x40,0xef,0x90,0x3e,0xe0,0x0f,0xf9,0x03,0xfe,0x00,0xff,0x80 }}, - {16, 0xe6a0, 0, {0x33,0xfe,0x0c,0xfa,0x03,0xfe,0x00,0xcf,0x80,0xb3,0xe0,0x0f,0xf8,0x03,0xfe,0x00 }}, - {16, 0xe6b0, 0, {0xcd,0x80,0x33,0xe0,0x0f,0xc8,0x43,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6c0, 0, {0xa8,0x11,0x9c,0x00,0x85,0x08,0x35,0x40,0x08,0x70,0x03,0x52,0x20,0x87,0x11,0x2c }}, - {16, 0xe6d0, 0, {0xec,0x0b,0x71,0x02,0xd0,0x00,0xe7,0x00,0x35,0xc4,0x08,0x74,0x02,0xdc,0x40,0x87 }}, - {16, 0xe6e0, 0, {0x10,0x21,0xc0,0x0b,0x70,0x02,0xfc,0x80,0x85,0x08,0x21,0x00,0x0b,0x41,0x82,0xea }}, - {16, 0xe6f0, 0, {0x06,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x00,0xaf,0x00,0x23,0x50 }}, - {16, 0xe700, 0, {0x09,0x50,0x02,0x1c,0x80,0xa7,0x01,0x29,0xc0,0x1b,0x60,0x06,0xdc,0x40,0xb7,0x10 }}, - {16, 0xe710, 0, {0x21,0xc8,0x4a,0x52,0x02,0xdc,0x00,0x83,0x00,0x21,0xc0,0x0b,0x70,0x02,0xdc,0x13 }}, - {16, 0xe720, 0, {0x84,0x00,0x25,0xc0,0x0b,0x58,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe730, 0, {0x20,0x14,0xcc,0x00,0x81,0x80,0x24,0x40,0x08,0x3e,0x02,0x6e,0x00,0x89,0x00,0x2c }}, - {16, 0xe740, 0, {0xc0,0x0b,0xb4,0x02,0xca,0x80,0xa3,0x00,0x24,0xc0,0x0a,0x04,0x02,0xec,0x40,0x82 }}, - {16, 0xe750, 0, {0x0a,0x20,0xc0,0x0b,0x30,0x02,0xcd,0x10,0x80,0xc0,0xa4,0x00,0x0b,0x1c,0x02,0xc8 }}, - {16, 0xe760, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0x84,0x00,0xeb,0x80,0x33,0x40 }}, - {16, 0xe770, 0, {0x0d,0x8c,0x83,0x26,0x00,0xe9,0xa0,0x3e,0x78,0x8f,0x90,0x83,0xe1,0x00,0xff,0x00 }}, - {16, 0xe780, 0, {0x31,0xd1,0x0e,0x84,0x23,0xfc,0x00,0xcb,0x82,0x32,0xc0,0x8f,0xb0,0x02,0xfd,0x40 }}, - {16, 0xe790, 0, {0xcb,0x80,0xb6,0xc0,0x0f,0xa4,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7a0, 0, {0x80,0x00,0xec,0x00,0xfb,0x00,0x3e,0x40,0x0f,0xa0,0x03,0xe0,0x00,0xf9,0x01,0x3e }}, - {16, 0xe7b0, 0, {0x42,0x0f,0x90,0x03,0xe5,0x54,0xe3,0x00,0x3e,0xc8,0x05,0x93,0x03,0xec,0x80,0xfb }}, - {16, 0xe7c0, 0, {0xc1,0x3e,0xc0,0x0f,0x20,0x03,0xcc,0x48,0xf3,0x08,0x3a,0x00,0x0f,0xa0,0x43,0xe0 }}, - {16, 0xe7d0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xcf,0x00,0x3f,0x40 }}, - {16, 0xe7e0, 0, {0x0f,0x30,0x01,0x2c,0x0a,0xcd,0x10,0x33,0x00,0x0f,0xd0,0x83,0x14,0x00,0xcb,0x02 }}, - {16, 0xe7f0, 0, {0x33,0xc0,0x0c,0xe1,0x03,0xec,0x10,0xcd,0x00,0x33,0xc0,0x0c,0xf0,0x33,0x3c,0x00 }}, - {16, 0xe800, 0, {0xea,0x00,0x33,0xc0,0x0c,0xf0,0x83,0xc8,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe810, 0, {0x81,0x04,0x6e,0x00,0x8b,0x00,0x2e,0x40,0x0b,0xbc,0x02,0x2e,0x00,0x0b,0x00,0x22 }}, - {16, 0xe820, 0, {0x30,0x0b,0x9c,0x02,0x27,0x80,0xab,0x00,0x2a,0xc0,0x08,0xb8,0x02,0xec,0x00,0x89 }}, - {16, 0xe830, 0, {0xc0,0x20,0xe0,0x08,0xae,0x02,0x2c,0x08,0x8a,0x00,0x22,0x00,0x08,0xb0,0x42,0xe8 }}, - {16, 0xe840, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2e,0x00,0x8b,0x04,0x2e,0x40 }}, - {16, 0xe850, 0, {0x8b,0x8c,0x02,0xae,0x10,0x89,0x00,0x22,0x70,0x0b,0x8c,0x02,0xa2,0x00,0x8b,0x01 }}, - {16, 0xe860, 0, {0x22,0xc0,0x08,0x80,0x02,0xec,0x10,0x82,0x88,0xa2,0x70,0x09,0xb8,0x02,0x2c,0x08 }}, - {16, 0xe870, 0, {0x89,0x00,0x20,0xc0,0x28,0x80,0x22,0xe0,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe880, 0, {0x08,0x04,0x0c,0x04,0x81,0x00,0x2c,0x40,0x0b,0x20,0x02,0x80,0x00,0x81,0x04,0xa0 }}, - {16, 0xe890, 0, {0x50,0x4b,0x00,0x0a,0x80,0x00,0xa3,0x01,0x2a,0xc1,0x20,0x10,0x02,0xcc,0x14,0x83 }}, - {16, 0xe8a0, 0, {0x00,0x22,0xc0,0x08,0x20,0x02,0x0c,0x00,0x81,0x00,0xe0,0x00,0x08,0x00,0x02,0xc2 }}, - {16, 0xe8b0, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x68,0x00,0xcb,0x00,0x3e,0x40 }}, - {16, 0xe8c0, 0, {0x0f,0x90,0x0b,0xac,0x80,0xc9,0x00,0x32,0x10,0x0f,0x80,0x03,0xa4,0x00,0xcf,0x02 }}, - {16, 0xe8d0, 0, {0x31,0xc0,0x0c,0x80,0x13,0xfc,0x02,0xcd,0x00,0x33,0xc0,0x2c,0x90,0x03,0x3c,0x02 }}, - {16, 0xe8e0, 0, {0xe8,0x00,0xb2,0xc0,0x0c,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8f0, 0, {0xa0,0x1d,0xfc,0x02,0xf5,0x00,0x3d,0x40,0x8f,0xf0,0x23,0x6d,0x00,0xff,0x00,0x3f }}, - {16, 0xe900, 0, {0x04,0x0f,0xc0,0x03,0x70,0x1c,0xff,0x01,0x3f,0xc0,0x4f,0xc0,0x03,0xfc,0x00,0xfd }}, - {16, 0xe910, 0, {0x00,0x3f,0xc0,0x0f,0xe0,0x0f,0xfc,0x18,0xfc,0x00,0x3f,0x00,0x0f,0xd0,0x03,0xe8 }}, - {16, 0xe920, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfe,0x00,0xd7,0x02,0x0f,0x30 }}, - {16, 0xe930, 0, {0x0c,0xf2,0x01,0x7e,0x06,0x44,0x30,0x3f,0x20,0x0e,0xf0,0x02,0x7c,0x84,0xfd,0x20 }}, - {16, 0xe940, 0, {0x27,0x08,0x0c,0xd0,0x01,0x36,0x00,0xff,0x60,0x33,0xcc,0x0b,0xf1,0x13,0x2c,0xc4 }}, - {16, 0xe950, 0, {0xff,0x30,0x0f,0xcd,0x0c,0xf4,0x03,0xf0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe960, 0, {0x80,0x10,0xee,0x00,0x8f,0xc0,0x2e,0x00,0x08,0xfc,0x02,0x2e,0x00,0x8a,0x30,0x28 }}, - {16, 0xe970, 0, {0x52,0x08,0xf6,0x82,0x3c,0x68,0xbd,0x90,0x32,0x34,0x48,0x9c,0x12,0x26,0x00,0xcf }}, - {16, 0xe980, 0, {0x40,0x23,0xcc,0x0b,0xf6,0x02,0x3d,0x00,0xbf,0x10,0x2f,0xcc,0x88,0xf6,0x02,0xe0 }}, - {16, 0xe990, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x00,0x93,0x10,0x2c,0x08 }}, - {16, 0xe9a0, 0, {0x09,0x31,0x02,0x4c,0x00,0x9b,0x20,0x64,0x58,0x03,0x31,0x62,0x4c,0x81,0xa1,0x00 }}, - {16, 0xe9b0, 0, {0x20,0x00,0x48,0x14,0x02,0x44,0x00,0x93,0x30,0x24,0xc0,0x0b,0x33,0x02,0x8d,0x84 }}, - {16, 0xe9c0, 0, {0xb3,0x20,0x6c,0xc0,0x2a,0x36,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9d0, 0, {0xc0,0x15,0xac,0x10,0x9b,0x02,0x2e,0x41,0x0b,0xb0,0x02,0xa4,0x00,0x9a,0x00,0x4a }}, - {16, 0xe9e0, 0, {0x60,0x88,0xb0,0x52,0x6c,0x01,0xb9,0x00,0x26,0x00,0x08,0x91,0x22,0xec,0x08,0xbb }}, - {16, 0xe9f0, 0, {0x00,0x26,0xc0,0x0b,0xb0,0x02,0xac,0x00,0xbb,0x05,0x6e,0xc1,0x0a,0xb0,0x02,0xf0 }}, - {16, 0xea00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xdb,0x01,0x3e,0x30 }}, - {16, 0xea10, 0, {0x2d,0x30,0x03,0x47,0x60,0xd8,0xa0,0x16,0x38,0x8f,0xb0,0x03,0x6c,0x00,0x79,0x02 }}, - {16, 0xea20, 0, {0x31,0x60,0x0c,0xc8,0x0a,0x66,0x00,0xbb,0x00,0xb6,0xc0,0x0f,0xb0,0x0b,0xac,0x00 }}, - {16, 0xea30, 0, {0xfb,0x01,0x3e,0xc1,0x0e,0xb0,0x03,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea40, 0, {0xe0,0x01,0xbc,0x10,0xef,0x08,0x3f,0x24,0x0c,0xf0,0x03,0x76,0x20,0xee,0x90,0x35 }}, - {16, 0xea50, 0, {0x40,0x0e,0x70,0x03,0xac,0x00,0xfd,0x00,0xbb,0x64,0x0f,0x88,0x13,0x34,0x80,0xcb }}, - {16, 0xea60, 0, {0x00,0x3b,0xc0,0x0f,0xb0,0x03,0x6c,0x08,0xff,0x00,0x3e,0xc0,0x0d,0xf0,0x03,0xf8 }}, - {16, 0xea70, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x01,0xfb,0x80,0x32,0x10 }}, - {16, 0xea80, 0, {0x0e,0xb0,0x03,0xed,0x00,0xcb,0x50,0x3e,0x40,0x8c,0xb0,0x43,0x2c,0x10,0xf9,0x00 }}, - {16, 0xea90, 0, {0x32,0x60,0x0c,0x40,0x0b,0x26,0x00,0xc3,0x04,0x36,0xc0,0x0c,0x30,0x03,0x2c,0x00 }}, - {16, 0xeaa0, 0, {0x9b,0x00,0xb0,0xc0,0x0c,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeab0, 0, {0xc8,0x05,0x0e,0x80,0xbf,0x04,0x2a,0x40,0x00,0xf5,0x00,0xe6,0x00,0x82,0xd2,0x22 }}, - {16, 0xeac0, 0, {0x40,0x0d,0xf0,0x22,0x3c,0x00,0x95,0x02,0x36,0x40,0x0a,0x80,0x02,0x2e,0x00,0x8f }}, - {16, 0xead0, 0, {0x00,0x37,0xc0,0x0a,0xf0,0x42,0x3c,0x00,0x8f,0x00,0x23,0xc0,0x28,0xf0,0x02,0xf2 }}, - {16, 0xeae0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4e,0x00,0xb3,0x00,0x22,0x20 }}, - {16, 0xeaf0, 0, {0x4a,0x30,0x00,0xcc,0x00,0x81,0xc0,0x28,0x00,0x08,0x30,0x02,0x0c,0x10,0xa1,0x00 }}, - {16, 0xeb00, 0, {0x28,0x80,0x18,0x30,0x22,0x04,0x04,0x83,0x00,0x24,0xc0,0x08,0x30,0x02,0xcc,0x08 }}, - {16, 0xeb10, 0, {0x93,0x00,0x20,0xc0,0x08,0x30,0x06,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb20, 0, {0x20,0x01,0x1e,0x00,0xb7,0x80,0x29,0xa0,0x08,0x78,0x02,0xfe,0x20,0x8d,0x80,0x29 }}, - {16, 0xeb30, 0, {0xe5,0x5b,0x38,0x42,0x1e,0x40,0xa1,0x81,0x25,0xa8,0x08,0x79,0x02,0x37,0x00,0x87 }}, - {16, 0xeb40, 0, {0x80,0x25,0xe0,0x0a,0x78,0x0a,0xde,0x81,0x87,0x80,0x25,0xe5,0x48,0x78,0x02,0xc8 }}, - {16, 0xeb50, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0xb3,0x10,0x30,0x12 }}, - {16, 0xeb60, 0, {0x0e,0x30,0x12,0xcc,0xc0,0xc3,0x00,0x38,0x80,0x0c,0x31,0x06,0x0c,0x40,0xf1,0x00 }}, - {16, 0xeb70, 0, {0x38,0x80,0x0c,0x30,0x43,0x04,0x42,0xc3,0x00,0x36,0xc0,0x0c,0x32,0x03,0xce,0xc0 }}, - {16, 0xeb80, 0, {0xdb,0x00,0x30,0xc0,0x0c,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb90, 0, {0x40,0x1d,0xbc,0x00,0xff,0x10,0x3d,0x84,0x4f,0xf1,0x03,0xd0,0x40,0xfc,0x10,0x33 }}, - {16, 0xeba0, 0, {0x80,0x5d,0xb1,0x83,0xfc,0x50,0xdd,0x0a,0x25,0x89,0x0f,0xb8,0x03,0xd4,0x00,0xff }}, - {16, 0xebb0, 0, {0x10,0x3f,0xc0,0x0f,0xf4,0x03,0x3c,0x40,0xff,0x00,0x3b,0xc0,0x0f,0xf0,0x03,0xd0 }}, - {16, 0xebc0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xfb,0x20,0x3e,0x00 }}, - {16, 0xebd0, 0, {0x0f,0xb5,0x03,0x29,0x20,0xf9,0x00,0x32,0xa0,0x0c,0xb0,0x83,0xec,0x00,0x49,0xc8 }}, - {16, 0xebe0, 0, {0xb2,0xc0,0x8c,0xa0,0x03,0x64,0x00,0xfb,0x08,0x12,0xea,0x0c,0xb0,0x0b,0x2c,0x80 }}, - {16, 0xebf0, 0, {0xfb,0x20,0x2e,0xd2,0x6c,0xb6,0x43,0xea,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec00, 0, {0x48,0x11,0x9c,0x00,0xb7,0x49,0x2d,0x00,0x0b,0x30,0x82,0x10,0x01,0xb5,0x02,0x83 }}, - {16, 0xec10, 0, {0xc0,0x1a,0x72,0x22,0xdd,0x41,0x85,0x00,0x61,0xc0,0x18,0x20,0x20,0x14,0x00,0xbf }}, - {16, 0xec20, 0, {0x40,0x35,0xd0,0x0d,0x34,0x02,0x1d,0x20,0xb7,0x28,0x25,0xc1,0x08,0x74,0x82,0xd2 }}, - {16, 0xec30, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x04,0x37,0xa0,0x2d,0x20 }}, - {16, 0xec40, 0, {0x0b,0x7a,0x12,0x16,0x01,0xb3,0x80,0x21,0xe2,0x08,0x78,0x42,0x9e,0x00,0x85,0x80 }}, - {16, 0xec50, 0, {0x20,0xe1,0x18,0x68,0x02,0x56,0x00,0xb7,0xa0,0x25,0xe0,0x08,0x7a,0x02,0x1e,0x00 }}, - {16, 0xec60, 0, {0xb7,0x90,0x2c,0xe5,0x88,0x7a,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec70, 0, {0x48,0x14,0xcc,0x00,0xb3,0x00,0x6c,0x24,0x1b,0x30,0x02,0x00,0x00,0xb0,0x00,0x20 }}, - {16, 0xec80, 0, {0xf8,0x0a,0x30,0x02,0xcc,0x00,0x81,0x00,0x20,0xd8,0x18,0x20,0x02,0x04,0x00,0xb3 }}, - {16, 0xec90, 0, {0x00,0x24,0xc0,0x09,0x30,0x02,0x0c,0x00,0xb3,0x00,0x26,0xc0,0x08,0x30,0x02,0xd2 }}, - {16, 0xeca0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x00,0xfa,0x00,0x3d,0x80 }}, - {16, 0xecb0, 0, {0x0f,0x20,0x0b,0x28,0x80,0xfe,0x00,0x33,0xa0,0x0c,0xa0,0x03,0xe8,0x02,0xca,0x02 }}, - {16, 0xecc0, 0, {0x32,0x90,0x2c,0xe4,0x03,0x78,0x00,0xfa,0x00,0x32,0x80,0x0c,0xa0,0x03,0x28,0x00 }}, - {16, 0xecd0, 0, {0xfa,0x00,0x3e,0x80,0x0c,0xa0,0x03,0xfa,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xece0, 0, {0x48,0x00,0xe1,0x00,0xf0,0x00,0x3e,0x00,0x4f,0x80,0x03,0xe0,0x80,0xf8,0x00,0x3e }}, - {16, 0xecf0, 0, {0x00,0x0f,0x80,0x23,0xc0,0x00,0xf8,0x02,0x3c,0x00,0x0f,0xc0,0x83,0x60,0x00,0xb8 }}, - {16, 0xed00, 0, {0x00,0x3e,0x00,0x0f,0x80,0x23,0xe0,0x18,0xf8,0x01,0x36,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xed10, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe6,0x00,0xf9,0x21,0x32,0x60 }}, - {16, 0xed20, 0, {0x0c,0x90,0x03,0x2c,0x44,0xf9,0x00,0xb2,0x40,0x0f,0x90,0x1b,0x24,0x00,0xe9,0x00 }}, - {16, 0xed30, 0, {0x3e,0x40,0x0c,0x10,0x03,0xa4,0x00,0xf9,0x00,0x32,0x40,0x0f,0x10,0x33,0x24,0x10 }}, - {16, 0xed40, 0, {0xf1,0x00,0x32,0x40,0x0c,0x90,0x03,0x02,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed50, 0, {0x80,0x04,0x64,0x00,0xb9,0x40,0xa2,0x41,0x08,0x90,0x02,0x24,0x80,0xe9,0x00,0x22 }}, - {16, 0xed60, 0, {0x40,0x0b,0x90,0x12,0x24,0x00,0x89,0x00,0x6e,0x41,0x18,0x90,0x42,0x24,0x00,0xb9 }}, - {16, 0xed70, 0, {0x04,0x2a,0x41,0x0b,0x90,0x03,0x64,0x00,0xf9,0x00,0x2a,0x40,0x0a,0x90,0x0a,0x20 }}, - {16, 0xed80, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x24,0x80,0xb9,0x42,0x62,0x48 }}, - {16, 0xed90, 0, {0x28,0x90,0x0a,0x24,0x00,0xb1,0x00,0x22,0x40,0x0b,0x10,0x02,0x24,0x10,0xb9,0x02 }}, - {16, 0xeda0, 0, {0x2e,0x40,0x08,0xd0,0x02,0xa4,0x00,0xb1,0x00,0x22,0x40,0x0b,0x90,0x02,0x24,0x04 }}, - {16, 0xedb0, 0, {0xb9,0x00,0x22,0x40,0x08,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xedc0, 0, {0x08,0x04,0x0c,0x00,0xb1,0x20,0x60,0x40,0x08,0x12,0x02,0x04,0x00,0xa1,0x20,0x20 }}, - {16, 0xedd0, 0, {0x40,0x0b,0x12,0x02,0x04,0x80,0x91,0x20,0x2d,0x68,0x08,0x52,0x12,0x04,0x00,0xb1 }}, - {16, 0xede0, 0, {0x28,0x28,0x4a,0x09,0x12,0x82,0x44,0xa0,0xb1,0x2c,0x28,0x4a,0x0a,0x12,0x82,0x02 }}, - {16, 0xedf0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x00,0x32,0x14 }}, - {16, 0xee00, 0, {0x0c,0x80,0x03,0x20,0x00,0xf8,0x50,0x32,0x14,0x0f,0x85,0x03,0x01,0x40,0xf8,0x00 }}, - {16, 0xee10, 0, {0x2e,0x00,0x28,0xc0,0x03,0xa0,0x00,0xf8,0x24,0x30,0x08,0x0f,0x82,0x23,0x20,0x80 }}, - {16, 0xee20, 0, {0xf8,0x20,0x32,0x08,0x0c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee30, 0, {0x98,0x1d,0xe4,0x08,0xf9,0x10,0x3f,0x40,0x8f,0x91,0x13,0xe4,0x00,0xed,0x10,0x3f }}, - {16, 0xee40, 0, {0x50,0x0f,0x91,0x03,0xe4,0x40,0xa5,0x10,0x3e,0x44,0x0f,0x91,0x03,0xf4,0x04,0xf9 }}, - {16, 0xee50, 0, {0x28,0x3e,0x4b,0x0b,0x92,0xa3,0xe4,0xa0,0xe9,0x28,0x3e,0x4a,0x0f,0x92,0x83,0xe6 }}, - {16, 0xee60, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf4,0x00,0xcd,0x00,0x33,0x40 }}, - {16, 0xee70, 0, {0x80,0xd0,0x01,0xf4,0x00,0xa5,0x00,0x26,0x40,0x0f,0x90,0x03,0x26,0x00,0xf1,0x88 }}, - {16, 0xee80, 0, {0x3e,0x68,0x0d,0x98,0x83,0x44,0x00,0xc9,0xc0,0x3a,0x40,0x0c,0x98,0x03,0x24,0x08 }}, - {16, 0xee90, 0, {0xf9,0xa0,0x32,0x78,0x0f,0x9a,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeea0, 0, {0x38,0x10,0xe0,0x02,0x88,0x00,0xa2,0x00,0x08,0x80,0x02,0xe0,0x00,0x0a,0x00,0x22 }}, - {16, 0xeeb0, 0, {0x00,0x0b,0x80,0x02,0x20,0x00,0xb8,0x40,0x2e,0x14,0x08,0x80,0x43,0x30,0x00,0x88 }}, - {16, 0xeec0, 0, {0xa0,0x22,0x2a,0x0a,0x8a,0x42,0xa0,0x05,0xb8,0x42,0x32,0x38,0x0b,0x80,0x02,0x0e }}, - {16, 0xeed0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x03,0x91,0x00,0x24,0x40 }}, - {16, 0xeee0, 0, {0x0b,0x10,0x02,0xc4,0x11,0xb1,0x04,0x20,0x41,0x1b,0x10,0x22,0x45,0x00,0xb5,0x00 }}, - {16, 0xeef0, 0, {0x25,0x40,0x09,0x50,0x02,0x54,0x01,0x81,0x40,0x2c,0x40,0x09,0x14,0x92,0x44,0x00 }}, - {16, 0xef00, 0, {0xb1,0x40,0x24,0x4c,0x0b,0x14,0x0a,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef10, 0, {0x18,0x15,0xa4,0x00,0x99,0x00,0x24,0x42,0x0b,0x90,0x02,0xe4,0x01,0x99,0x20,0x26 }}, - {16, 0xef20, 0, {0x40,0xcb,0x90,0x02,0x64,0x00,0xbb,0x00,0x2f,0x41,0x0a,0xd0,0x02,0x34,0x00,0x89 }}, - {16, 0xef30, 0, {0x00,0x26,0x40,0x0b,0x10,0x02,0xe4,0x00,0x31,0x00,0x62,0x40,0x0b,0x90,0x02,0x46 }}, - {16, 0xef40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xc4,0x00,0xd9,0x01,0x36,0x50 }}, - {16, 0xef50, 0, {0x2f,0x90,0x03,0xe6,0x60,0xf9,0x80,0x36,0x52,0x0b,0x90,0x0a,0x64,0x00,0xf9,0x00 }}, - {16, 0xef60, 0, {0x36,0x40,0x0d,0x90,0x03,0x64,0x02,0x09,0x00,0x3e,0x40,0x0d,0x90,0x03,0x64,0x00 }}, - {16, 0xef70, 0, {0xb9,0x00,0xb6,0x40,0x0f,0x90,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef80, 0, {0x28,0x01,0xa4,0x00,0xe1,0x00,0x3a,0x41,0x0c,0x90,0x23,0xe6,0x20,0xe9,0x00,0xba }}, - {16, 0xef90, 0, {0x70,0x0f,0x90,0x03,0xa4,0x00,0xf9,0x00,0x3e,0x40,0x0d,0x10,0x13,0xa7,0x00,0xf9 }}, - {16, 0xefa0, 0, {0x00,0x3a,0x40,0x0e,0x90,0x43,0xa4,0x08,0xf9,0x00,0x3a,0x40,0x0f,0x90,0x03,0x8a }}, - {16, 0xefb0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x20,0xf8,0x00,0x32,0x00 }}, - {16, 0xefc0, 0, {0x0f,0x80,0x83,0x21,0x00,0xf0,0x00,0x3a,0x11,0x09,0x80,0x03,0xe0,0x00,0xc8,0x01 }}, - {16, 0xefd0, 0, {0x30,0x01,0x0c,0x80,0x03,0xb0,0x00,0xd0,0x00,0x34,0x00,0x0d,0x80,0x03,0x20,0x00 }}, - {16, 0xefe0, 0, {0xc8,0x00,0x32,0x00,0x0c,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeff0, 0, {0x28,0x05,0x38,0x00,0xbe,0x00,0x22,0x80,0x03,0xe8,0x02,0x1a,0x08,0xbe,0x48,0x22 }}, - {16, 0xf000, 0, {0x80,0x0a,0xa0,0x03,0xb8,0x00,0xca,0x08,0x22,0x80,0x0f,0xa4,0x02,0x08,0x00,0x8a }}, - {16, 0xf010, 0, {0x00,0x22,0x80,0x8d,0xa0,0x02,0x28,0x00,0xda,0x00,0x2a,0x81,0x08,0xa0,0x02,0x8a }}, - {16, 0xf020, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x44,0x00,0xb3,0x00,0x20,0x40 }}, - {16, 0xf030, 0, {0x0b,0x30,0x02,0x08,0x00,0xb0,0x64,0x68,0xc1,0x08,0xb0,0x22,0xcc,0x0c,0x93,0x80 }}, - {16, 0xf040, 0, {0x00,0xc0,0x48,0x36,0x02,0x88,0x00,0xb3,0x00,0x24,0xc0,0x08,0x30,0x06,0x0c,0x01 }}, - {16, 0xf050, 0, {0xa3,0x02,0x2c,0xc0,0x08,0xb0,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf060, 0, {0xa0,0x01,0x14,0x08,0xb5,0x00,0x21,0x40,0x0b,0x38,0x82,0x1c,0x21,0xb7,0x00,0x23 }}, - {16, 0xf070, 0, {0xe8,0x4a,0x72,0x26,0x9e,0x40,0x8f,0x81,0xab,0x40,0x42,0x70,0x52,0x38,0x00,0xa3 }}, - {16, 0xf080, 0, {0x22,0x20,0xc4,0x49,0x31,0x02,0x1e,0x0a,0xb7,0x22,0x2d,0xe8,0x08,0x72,0x02,0xa8 }}, - {16, 0xf090, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x12,0x00,0xf6,0x80,0x21,0xe0 }}, - {16, 0xf0a0, 0, {0x0b,0x78,0x0b,0x1e,0x00,0xb4,0x82,0x3b,0xe8,0x4c,0x7c,0x13,0xfe,0x02,0x97,0x80 }}, - {16, 0xf0b0, 0, {0x33,0xa0,0x08,0x38,0x03,0x9a,0x00,0xf7,0x88,0x35,0xe2,0x0c,0x78,0xe3,0x0e,0x00 }}, - {16, 0xf0c0, 0, {0xe3,0xe8,0x34,0xf8,0x0c,0x3c,0x23,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0d0, 0, {0x08,0x1d,0xa8,0x04,0xf1,0x00,0x3e,0x42,0x0f,0xb0,0x13,0xec,0x00,0xfb,0x00,0xbe }}, - {16, 0xf0e0, 0, {0xcc,0x1e,0xb6,0x07,0xed,0x80,0xfb,0x00,0x36,0x00,0x0f,0xb0,0x43,0x68,0x00,0xcb }}, - {16, 0xf0f0, 0, {0x30,0x3e,0xd8,0x0f,0xb6,0x0b,0xed,0x40,0xcb,0x00,0x3a,0xc0,0x2f,0xb6,0x03,0xc2 }}, - {16, 0xf100, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf2,0x40,0xfb,0x91,0x3d,0x4c }}, - {16, 0xf110, 0, {0x80,0xf8,0x03,0xde,0x40,0xc6,0x80,0x1b,0xf0,0x4f,0xfd,0x07,0xff,0x00,0xcd,0x80 }}, - {16, 0xf120, 0, {0x33,0xe0,0x0c,0x68,0x03,0xba,0x00,0xff,0x80,0x33,0xe0,0x07,0xf8,0x03,0x3f,0x10 }}, - {16, 0xf130, 0, {0xcf,0x80,0x3f,0xe0,0x0c,0xfc,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf140, 0, {0xa8,0x11,0x90,0x00,0xb5,0xc0,0x2d,0x40,0x08,0x62,0x02,0xdc,0x20,0xd6,0x02,0x21 }}, - {16, 0xf150, 0, {0xc8,0x8f,0x70,0x02,0xdc,0x81,0xb5,0x00,0x81,0x44,0x0d,0x61,0x22,0x18,0x04,0xb7 }}, - {16, 0xf160, 0, {0x00,0x35,0xc0,0x0b,0x70,0x02,0xbc,0x00,0xa7,0x01,0x2d,0xc0,0x08,0x70,0x03,0xea }}, - {16, 0xf170, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x01,0xb6,0x01,0x2f,0xc0 }}, - {16, 0xf180, 0, {0x18,0x70,0x02,0xdc,0x0a,0x96,0x10,0x29,0xc1,0x4b,0x70,0x06,0xdc,0x10,0x85,0x00 }}, - {16, 0xf190, 0, {0x25,0x80,0x08,0x60,0x82,0x1a,0x20,0xa3,0x00,0x25,0xc0,0x0b,0x31,0x02,0x5c,0x40 }}, - {16, 0xf1a0, 0, {0x87,0x00,0x2d,0xc0,0x08,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1b0, 0, {0x20,0x14,0xc8,0x00,0xb1,0x00,0x2c,0x40,0x88,0x20,0x02,0xed,0x00,0x8a,0x60,0x20 }}, - {16, 0xf1c0, 0, {0xc0,0x0a,0x30,0x02,0xcc,0x04,0xb1,0x00,0x24,0x00,0x28,0x24,0x02,0x0a,0x00,0x33 }}, - {16, 0xf1d0, 0, {0x00,0x24,0xc0,0x0b,0xb0,0x02,0xcc,0x00,0xa3,0x00,0x2c,0xc0,0x88,0x30,0x02,0x88 }}, - {16, 0xf1e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa0,0x00,0xfb,0x00,0x3e,0xc6 }}, - {16, 0xf1f0, 0, {0x0c,0x80,0x03,0xe5,0x00,0x09,0xc8,0xab,0xe2,0x0b,0xf0,0x02,0xfc,0x00,0x4a,0x00 }}, - {16, 0xf200, 0, {0x36,0xc0,0x08,0x90,0x03,0xa6,0x00,0xff,0x00,0x33,0xc0,0x0f,0xf0,0x03,0x7c,0x00 }}, - {16, 0xf210, 0, {0x8f,0x00,0x2f,0xc0,0x28,0xf0,0x02,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf220, 0, {0x80,0x00,0xe1,0x00,0xfa,0x01,0x3e,0xc0,0x0f,0x80,0x03,0xec,0x00,0xf9,0x40,0x3e }}, - {16, 0xf230, 0, {0xc0,0x07,0xb0,0x03,0xec,0x00,0xfa,0x00,0x3a,0x40,0x0f,0x90,0x23,0xe5,0x00,0xfb }}, - {16, 0xf240, 0, {0x00,0x3e,0xc0,0x0f,0xb0,0x03,0xac,0x00,0xfb,0x00,0x3c,0xc0,0x0f,0xb0,0x23,0xe0 }}, - {16, 0xf250, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xfc,0x20,0x3f,0xc0 }}, - {16, 0xf260, 0, {0x0c,0xc8,0x03,0xfc,0x20,0xcd,0x81,0xb3,0xc2,0x4f,0xf0,0x03,0xfc,0x00,0xca,0x00 }}, - {16, 0xf270, 0, {0x3c,0x80,0x0c,0xd0,0x82,0x36,0x01,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0x3c,0x08 }}, - {16, 0xf280, 0, {0xcf,0x04,0x3a,0xc0,0x5c,0xb0,0x03,0xc0,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf290, 0, {0x81,0x04,0x62,0x04,0xb8,0x40,0x2c,0x60,0x08,0x89,0x02,0xee,0x80,0xa9,0x60,0x2a }}, - {16, 0xf2a0, 0, {0xc0,0x0b,0xb0,0x03,0x8c,0x00,0xaa,0x40,0x2e,0x00,0x08,0x10,0x02,0x26,0x81,0xeb }}, - {16, 0xf2b0, 0, {0x00,0x26,0xc0,0x8b,0xb0,0x13,0x6c,0x00,0xdb,0x00,0x2e,0xc0,0x3d,0xb0,0x02,0xe0 }}, - {16, 0xf2c0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x23,0x00,0xbb,0x03,0x2e,0xc8 }}, - {16, 0xf2d0, 0, {0x09,0xb0,0x02,0xee,0x00,0x8b,0x10,0x26,0xc0,0x0b,0xb0,0x02,0xec,0x00,0xa8,0x00 }}, - {16, 0xf2e0, 0, {0x2e,0xc0,0x08,0x88,0x22,0xa4,0x80,0xbb,0x00,0x2e,0xc0,0x4b,0xb0,0x22,0x0c,0x00 }}, - {16, 0xf2f0, 0, {0x8b,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf300, 0, {0x08,0x04,0x00,0x00,0xb2,0x00,0x2e,0xc0,0x29,0x28,0x02,0xec,0x01,0xa0,0x02,0x20 }}, - {16, 0xf310, 0, {0xc0,0x09,0x30,0x02,0xcc,0x00,0xa0,0x00,0x2c,0x40,0x08,0x00,0x42,0x84,0x00,0x93 }}, - {16, 0xf320, 0, {0x00,0x6c,0xc0,0x0b,0x30,0x06,0x4d,0x00,0x93,0x00,0x2c,0xc0,0x08,0x30,0x02,0xc2 }}, - {16, 0xf330, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xf8,0x20,0x2f,0xc0 }}, - {16, 0xf340, 0, {0x0d,0xb0,0x03,0xec,0x00,0xcb,0x00,0x33,0xc0,0x0b,0xf0,0x03,0xfc,0x18,0xe8,0x00 }}, - {16, 0xf350, 0, {0x2e,0x80,0x08,0x80,0x03,0xa4,0x00,0xbf,0x00,0x3f,0xc0,0x0f,0xf0,0x43,0x3d,0x11 }}, - {16, 0xf360, 0, {0xcf,0x03,0x3e,0xc1,0x5d,0xf0,0x23,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf370, 0, {0xa0,0x1d,0xf0,0x00,0xfc,0x10,0x3f,0x40,0x0e,0xe0,0x03,0xfc,0x00,0xfc,0x00,0x3f }}, - {16, 0xf380, 0, {0xc0,0x0f,0xf0,0x03,0xbc,0x00,0xfc,0x00,0x3f,0x00,0x2f,0xc0,0x03,0x74,0x00,0xef }}, - {16, 0xf390, 0, {0x00,0x27,0xc0,0x0f,0xf0,0x03,0xfc,0x18,0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xf3a0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x15,0xfc,0x88,0x9c,0x29,0x3f,0x08 }}, - {16, 0xf3b0, 0, {0x0f,0xd2,0x83,0xec,0x00,0xff,0x08,0x3f,0x28,0x0f,0xca,0x03,0x3c,0x41,0xcf,0x20 }}, - {16, 0xf3c0, 0, {0x73,0x2c,0x0c,0xc0,0x03,0x30,0x20,0xcf,0x60,0x33,0xd8,0x0f,0x78,0x03,0x3f,0x80 }}, - {16, 0xf3d0, 0, {0xdd,0x92,0x33,0xc8,0x0f,0x50,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3e0, 0, {0x80,0x10,0xe5,0x40,0x88,0x40,0x2e,0x04,0x8b,0x94,0x02,0xe4,0x00,0xb9,0x00,0x0e }}, - {16, 0xf3f0, 0, {0x7f,0x8f,0x9e,0x83,0x65,0x82,0xcf,0x68,0x3e,0x50,0x8d,0x04,0x92,0x2f,0x04,0xd3 }}, - {16, 0xf400, 0, {0x40,0x74,0xdc,0x0d,0xa2,0x02,0x20,0x40,0x89,0x00,0x22,0xf0,0x0b,0x98,0x02,0x20 }}, - {16, 0xf410, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc8,0x09,0xa0,0x85,0x2c,0x01 }}, - {16, 0xf420, 0, {0x0b,0x00,0x10,0xcc,0x40,0xa2,0x08,0x2c,0x00,0xdb,0x11,0x02,0x89,0x00,0x93,0x30 }}, - {16, 0xf430, 0, {0x20,0x05,0x08,0x13,0x02,0x80,0x08,0xa3,0x60,0x60,0xc0,0x0a,0xb0,0x82,0x08,0x84 }}, - {16, 0xf440, 0, {0x81,0x20,0x20,0xd0,0x0b,0x10,0x02,0xa2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf450, 0, {0xc0,0x15,0xa4,0x12,0x88,0x80,0x6e,0x20,0x0b,0x88,0x82,0xee,0x00,0xba,0x81,0x2e }}, - {16, 0xf460, 0, {0x60,0x5a,0x98,0x02,0xa2,0x00,0x8b,0x00,0x2a,0x60,0x08,0x11,0x1a,0x2c,0x00,0xbb }}, - {16, 0xf470, 0, {0x00,0x22,0xc0,0x08,0xb8,0x0a,0x28,0x00,0x81,0x20,0x02,0xc0,0x0b,0x90,0x02,0xb0 }}, - {16, 0xf480, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xed,0x00,0xd9,0x80,0x3e,0x20 }}, - {16, 0xf490, 0, {0x4f,0x98,0x00,0xeb,0x20,0xfb,0xe0,0x2e,0x60,0x0b,0x8c,0x62,0xae,0x20,0x8b,0x00 }}, - {16, 0xf4a0, 0, {0x22,0x60,0x08,0xbc,0x03,0xa0,0x20,0xeb,0x00,0x22,0xc1,0x0a,0x18,0x0b,0x25,0x00 }}, - {16, 0xf4b0, 0, {0xd9,0x00,0xb2,0xc0,0x0f,0x90,0x0b,0x90,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4c0, 0, {0xe0,0x01,0x94,0x88,0xff,0x00,0x3f,0x01,0x0f,0xd0,0x01,0xf0,0x08,0xdd,0x01,0x3f }}, - {16, 0xf4d0, 0, {0x42,0x07,0x40,0x03,0x5c,0x00,0xaf,0x00,0x3f,0x40,0x0f,0xf8,0x00,0xf0,0x00,0xdf }}, - {16, 0xf4e0, 0, {0x00,0x3f,0xc0,0x0f,0xc0,0x23,0xf4,0x50,0xfd,0x80,0x3f,0xc0,0x0f,0xd0,0x03,0x78 }}, - {16, 0xf4f0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xac,0x00,0xd9,0x00,0x3e,0x40 }}, - {16, 0xf500, 0, {0x0f,0x94,0x03,0xa8,0x20,0xca,0x40,0x3a,0x40,0x0f,0x94,0x03,0xea,0x08,0xfb,0x00 }}, - {16, 0xf510, 0, {0x3a,0x00,0x4c,0xf6,0x23,0x2c,0x30,0xcb,0x00,0x36,0xc0,0x0d,0x90,0x03,0xa1,0x02 }}, - {16, 0xf520, 0, {0xd9,0x00,0xba,0xc0,0x0f,0x98,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf530, 0, {0xc8,0x05,0x24,0x00,0x8a,0x00,0x2e,0x40,0x0b,0x95,0x02,0xe0,0x08,0x88,0x80,0x22 }}, - {16, 0xf540, 0, {0x70,0x8f,0x8c,0x02,0xe0,0x00,0xbf,0x02,0x20,0x00,0x08,0xb8,0x02,0x0e,0x00,0xdf }}, - {16, 0xf550, 0, {0x00,0x23,0xdd,0x08,0x98,0x82,0x2a,0x00,0x89,0x80,0x23,0xc0,0x0b,0x50,0x1a,0x32 }}, - {16, 0xf560, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x44,0x00,0x83,0x05,0x24,0x41 }}, - {16, 0xf570, 0, {0x09,0x10,0x02,0xce,0x00,0x83,0x90,0x2c,0x80,0x1b,0x24,0x82,0xcc,0x00,0xbb,0x00 }}, - {16, 0xf580, 0, {0x2c,0x80,0x08,0x04,0x08,0x04,0x01,0x8b,0x00,0x22,0xc0,0x28,0x12,0x02,0x6c,0x80 }}, - {16, 0xf590, 0, {0x81,0x48,0x24,0xc4,0x0b,0x10,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5a0, 0, {0x20,0x01,0x3e,0x42,0x86,0x80,0x2d,0x60,0x0b,0x68,0x02,0xf6,0x90,0x8d,0x80,0x21 }}, - {16, 0xf5b0, 0, {0x22,0x0b,0x58,0x02,0xd7,0x40,0xb7,0x90,0x21,0xe0,0x08,0x49,0x92,0x1e,0x53,0x97 }}, - {16, 0xf5c0, 0, {0x81,0x21,0xe0,0x48,0xc8,0x0a,0x52,0x22,0x85,0x88,0x25,0xe0,0x0b,0x58,0x02,0x08 }}, - {16, 0xf5d0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x83,0x00,0x34,0xc0 }}, - {16, 0xf5e0, 0, {0x0f,0x00,0x03,0xce,0x20,0xc3,0x30,0x7c,0x94,0x0b,0x34,0x83,0xcc,0x14,0xf3,0x02 }}, - {16, 0xf5f0, 0, {0x3c,0x80,0x0c,0x04,0x03,0x04,0x60,0xc3,0x00,0xb0,0xc0,0x0c,0x10,0x03,0xec,0x00 }}, - {16, 0xf600, 0, {0xc9,0x00,0x3c,0xc4,0x0f,0x11,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf610, 0, {0x40,0x1d,0x9c,0x00,0xee,0x01,0x3f,0xc0,0x4f,0xe1,0x03,0xd4,0x40,0xf5,0x16,0x7a }}, - {16, 0xf620, 0, {0xc0,0x4e,0xf0,0x03,0xf4,0x10,0x37,0x05,0x3d,0xc0,0x0f,0xc0,0x0b,0xdc,0x40,0xff }}, - {16, 0xf630, 0, {0x00,0x3b,0xc2,0x0e,0xd0,0x07,0xbc,0x02,0xef,0x00,0x3b,0xc6,0x0f,0xd0,0x03,0xd0 }}, - {16, 0xf640, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xf4,0x00,0xdd,0x84,0x33,0x80 }}, - {16, 0xf650, 0, {0x04,0xf0,0x03,0x6c,0x02,0xcb,0x02,0x7e,0xc0,0x1f,0xa0,0x53,0xec,0x00,0xcb,0x20 }}, - {16, 0xf660, 0, {0x34,0x40,0x0c,0xd0,0x0b,0x20,0x10,0xeb,0x00,0x1e,0xe0,0x0f,0x30,0x0b,0x2c,0x00 }}, - {16, 0xf670, 0, {0xc1,0x00,0x32,0xc0,0x0f,0x91,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf680, 0, {0x48,0x11,0x9c,0x00,0x87,0x00,0x21,0x80,0x08,0x60,0x00,0x14,0x00,0x85,0x00,0x2d }}, - {16, 0xf690, 0, {0x80,0x0b,0x70,0x52,0xd4,0x04,0x83,0x28,0x29,0xc0,0x28,0x50,0x03,0x50,0x00,0x87 }}, - {16, 0xf6a0, 0, {0x40,0x25,0xc8,0x0f,0x60,0x02,0x04,0x00,0xa7,0x00,0x3d,0xc8,0x0b,0x52,0x02,0xd2 }}, - {16, 0xf6b0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x8e,0x00,0x95,0x80,0x21,0xe0 }}, - {16, 0xf6c0, 0, {0x09,0x38,0x02,0x1e,0x11,0xa7,0x80,0x2d,0xf0,0x0b,0x78,0x52,0xce,0x0a,0x97,0x95 }}, - {16, 0xf6d0, 0, {0x21,0xe0,0x19,0x5c,0x02,0x0e,0x00,0xa7,0x80,0x29,0xc8,0x0b,0xf8,0x02,0x1e,0x20 }}, - {16, 0xf6e0, 0, {0x8d,0x80,0x21,0xe0,0x0b,0x58,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6f0, 0, {0x48,0x14,0xcc,0x00,0x82,0xe0,0xa0,0xe8,0x29,0x30,0x06,0x0e,0x50,0xab,0x80,0x2c }}, - {16, 0xf700, 0, {0xf0,0x0b,0x31,0x42,0xcc,0x00,0x93,0x00,0x28,0xc4,0x09,0x98,0x02,0x4c,0x28,0x83 }}, - {16, 0xf710, 0, {0x00,0x24,0xc0,0x0a,0xb0,0x02,0x0d,0x00,0xa2,0x58,0x28,0xc0,0x0b,0x10,0x02,0xd2 }}, - {16, 0xf720, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x00,0xde,0x80,0x31,0xa0 }}, - {16, 0xf730, 0, {0x09,0xe2,0x0b,0x78,0x04,0xee,0xa4,0x2f,0xa4,0x8b,0xec,0x02,0xd8,0x00,0xda,0x00 }}, - {16, 0xf740, 0, {0x27,0x81,0x0d,0xec,0x06,0x1b,0x00,0xea,0x04,0x3e,0x80,0x0b,0xe0,0x03,0x3b,0x00 }}, - {16, 0xf750, 0, {0xce,0xc0,0x22,0x80,0x0f,0xa0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf760, 0, {0x48,0x00,0xe0,0x80,0xf8,0x10,0x3e,0x05,0x0e,0x88,0x03,0xe0,0x08,0x98,0x40,0x3e }}, - {16, 0xf770, 0, {0x00,0x0f,0x84,0x83,0xe1,0x40,0xe8,0x00,0x3a,0x02,0x0e,0x80,0x43,0xe1,0x40,0xf8 }}, - {16, 0xf780, 0, {0x00,0x36,0x00,0x0f,0x80,0x03,0xe0,0x20,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0xf790, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xc4,0x00,0xe9,0x00,0x3e,0x40 }}, - {16, 0xf7a0, 0, {0x0c,0x90,0x03,0x04,0x20,0xe9,0x90,0x32,0x68,0x0e,0x98,0x03,0xa4,0x00,0xc1,0x00 }}, - {16, 0xf7b0, 0, {0x30,0x40,0x0c,0x94,0x83,0x24,0x08,0xc9,0x00,0x3e,0x40,0x0c,0x90,0x03,0xa4,0x00 }}, - {16, 0xf7c0, 0, {0xc9,0x00,0x30,0x50,0x0c,0x1a,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7d0, 0, {0x80,0x04,0x64,0x00,0x89,0x40,0x2e,0x50,0x28,0x90,0x0a,0x24,0x08,0x89,0x06,0x16 }}, - {16, 0xf7e0, 0, {0x61,0x0b,0x9c,0x02,0xe4,0x20,0xa9,0x00,0x36,0x40,0x0d,0x90,0x02,0x27,0x60,0xa9 }}, - {16, 0xf7f0, 0, {0x00,0x2e,0x40,0x28,0x90,0x1a,0x24,0x00,0x89,0x00,0x36,0x40,0x28,0x98,0x02,0x20 }}, - {16, 0xf800, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x2c,0x00,0xa9,0x08,0x2e,0xc2 }}, - {16, 0xf810, 0, {0x09,0x10,0x00,0x24,0x00,0xa9,0x00,0x06,0x40,0x89,0x96,0x06,0xe6,0x00,0x89,0x00 }}, - {16, 0xf820, 0, {0x22,0xc0,0x08,0x90,0x02,0x24,0x02,0x89,0x00,0x24,0x40,0x08,0x90,0x02,0x0c,0x06 }}, - {16, 0xf830, 0, {0x83,0x00,0x22,0x40,0x08,0x90,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf840, 0, {0x08,0x04,0x05,0x00,0x81,0x44,0x2c,0x50,0x08,0x14,0x02,0x05,0x80,0x81,0x20,0x64 }}, - {16, 0xf850, 0, {0x70,0x1b,0x14,0x02,0xe4,0x80,0xa1,0x20,0x64,0x40,0x19,0x12,0x0a,0x04,0x80,0xa1 }}, - {16, 0xf860, 0, {0x00,0x2c,0x50,0x18,0x14,0x02,0x85,0x00,0x81,0x40,0x24,0x40,0x40,0x10,0x02,0x02 }}, - {16, 0xf870, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xe0,0x00,0x3c,0x00 }}, - {16, 0xf880, 0, {0x0d,0x80,0x02,0x00,0x00,0xaa,0x50,0x36,0x00,0x0f,0x80,0x03,0xe1,0x40,0xc8,0x52 }}, - {16, 0xf890, 0, {0x72,0x14,0x0c,0x05,0x16,0x20,0x08,0xc8,0x50,0x3e,0x01,0x0c,0x80,0x03,0xa0,0x04 }}, - {16, 0xf8a0, 0, {0xc8,0x00,0xb2,0x00,0x0c,0x80,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8b0, 0, {0x98,0x19,0xf5,0x02,0xfd,0x40,0x3f,0xd0,0x0f,0xd4,0x23,0xf4,0x44,0xfd,0x14,0x7f }}, - {16, 0xf8c0, 0, {0x50,0x0f,0xd4,0x07,0xf4,0x40,0xf9,0x10,0x3f,0x50,0x07,0xd1,0x23,0xf4,0x40,0xf9 }}, - {16, 0xf8d0, 0, {0x40,0x1e,0x50,0x07,0xd0,0x0b,0x75,0x00,0xfd,0x02,0x3e,0x50,0x0f,0xd4,0x03,0xe6 }}, - {16, 0xf8e0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x00,0xc9,0xa8,0x3e,0x72 }}, - {16, 0xf8f0, 0, {0x0f,0x98,0x03,0xe6,0xc0,0xfd,0xa0,0xb3,0x40,0x0f,0xd0,0x03,0x77,0x80,0xcd,0x90 }}, - {16, 0xf900, 0, {0x7f,0x40,0x0f,0xda,0xa3,0x16,0x90,0xa9,0xc0,0x32,0x60,0x4c,0xb1,0x03,0x24,0x00 }}, - {16, 0xf910, 0, {0xc1,0x00,0x33,0x6a,0x0b,0xda,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf920, 0, {0x38,0x10,0xe3,0x40,0x88,0xe0,0x2e,0x30,0x0b,0x8d,0x02,0xf3,0x40,0xb8,0xe8,0x76 }}, - {16, 0xf930, 0, {0x00,0x4f,0x80,0x0a,0x22,0x80,0x88,0x90,0x6e,0x28,0x8f,0x8a,0x03,0x61,0x44,0xf8 }}, - {16, 0xf940, 0, {0xe1,0x3e,0x2a,0x08,0x88,0x03,0x42,0xa0,0xdc,0xa0,0x3e,0x10,0x0b,0x85,0x0a,0x0e }}, - {16, 0xf950, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0xa0,0x85,0x08,0x2d,0x48 }}, - {16, 0xf960, 0, {0x1b,0x52,0x82,0xd4,0x80,0xb1,0x14,0x20,0x40,0x0b,0x18,0x02,0x05,0x82,0x81,0x00 }}, - {16, 0xf970, 0, {0x6c,0x42,0x0b,0x12,0x82,0x04,0x00,0xa1,0x60,0x21,0x50,0x0b,0x50,0x02,0x14,0x90 }}, - {16, 0xf980, 0, {0x95,0x2c,0x28,0x40,0x0b,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf990, 0, {0x18,0x15,0xa4,0x01,0x8d,0x44,0x2f,0x40,0x0b,0xd4,0x02,0xf4,0x04,0xb9,0x08,0x22 }}, - {16, 0xf9a0, 0, {0x40,0x0a,0x92,0x02,0x2c,0x84,0x89,0x00,0x2e,0x40,0x0a,0x14,0x02,0x6c,0x80,0xa9 }}, - {16, 0xf9b0, 0, {0x01,0x2a,0x40,0x09,0x50,0x0a,0x5c,0x02,0x8d,0x60,0x2a,0x40,0x0b,0x90,0x42,0x06 }}, - {16, 0xf9c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe6,0x62,0xc9,0x02,0x3e,0x54 }}, - {16, 0xf9d0, 0, {0x0f,0x90,0x03,0xe4,0x00,0xf9,0x40,0x22,0x46,0x0b,0x98,0x03,0x67,0x20,0xc9,0x01 }}, - {16, 0xf9e0, 0, {0x2e,0x69,0x0b,0x94,0x0b,0x25,0x20,0xa9,0x00,0x22,0x40,0x2d,0x92,0x0a,0x26,0x22 }}, - {16, 0xf9f0, 0, {0x99,0x00,0x2a,0x40,0x8f,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa00, 0, {0x28,0x01,0x86,0x02,0xf9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xe6,0x80,0xf1,0xa0,0x3e }}, - {16, 0xfa10, 0, {0x62,0x0f,0x98,0x83,0xc6,0x20,0xf9,0x00,0x3e,0x49,0x0f,0x90,0x83,0xe4,0x00,0x71 }}, - {16, 0xfa20, 0, {0x02,0x3e,0x40,0x0e,0x90,0x0b,0xe6,0x80,0xf9,0x80,0x3e,0x40,0x0f,0x90,0x03,0xca }}, - {16, 0xfa30, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x10,0xc8,0x00,0x3e,0x00 }}, - {16, 0xfa40, 0, {0x4f,0x80,0x43,0xb0,0x00,0xc8,0x41,0x32,0x00,0x0f,0x80,0x03,0x21,0x02,0xc8,0x02 }}, - {16, 0xfa50, 0, {0x3e,0x10,0x4c,0x80,0x03,0x01,0x20,0xc8,0x00,0x3b,0x00,0x0c,0xc0,0x03,0xb0,0x00 }}, - {16, 0xfa60, 0, {0xcc,0x04,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa70, 0, {0x28,0x05,0x28,0x00,0x8a,0x80,0x2e,0x80,0x0b,0xa0,0x02,0xf8,0x04,0x8e,0x00,0x23 }}, - {16, 0xfa80, 0, {0xb2,0x0e,0xe0,0x82,0xf9,0x04,0x8a,0x00,0x2e,0x81,0x0c,0xe0,0x0a,0x3a,0x80,0xda }}, - {16, 0xfa90, 0, {0x00,0x22,0xb6,0x08,0xa0,0x02,0x28,0x00,0x8e,0x00,0x2a,0x80,0x0b,0x60,0x0b,0x0a }}, - {16, 0xfaa0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x44,0x02,0x93,0x81,0x2c,0xc0 }}, - {16, 0xfab0, 0, {0x4b,0x30,0x02,0xc8,0x00,0x83,0xca,0x20,0xe0,0x19,0xb0,0x06,0x8c,0x00,0x81,0x04 }}, - {16, 0xfac0, 0, {0x44,0x40,0x08,0x34,0x02,0x0d,0x00,0x83,0x00,0x2a,0x00,0x08,0x00,0x0a,0x80,0x40 }}, - {16, 0xfad0, 0, {0x88,0x00,0x20,0xc0,0x0b,0x30,0x02,0x4b,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfae0, 0, {0xa0,0x01,0x04,0x02,0x97,0x08,0x2d,0xc0,0x0b,0x60,0x06,0xca,0x00,0x83,0x09,0x21 }}, - {16, 0xfaf0, 0, {0xc0,0x0a,0x70,0x02,0xdc,0x00,0x85,0x31,0x2d,0x68,0x09,0x30,0x02,0x1c,0x14,0x93 }}, - {16, 0xfb00, 0, {0x20,0x20,0xc0,0x08,0xf0,0x42,0x9c,0x02,0x8f,0x00,0x29,0x40,0x03,0x70,0x12,0x28 }}, - {16, 0xfb10, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x16,0x00,0x96,0x84,0x3d,0xa0 }}, - {16, 0xfb20, 0, {0x0f,0x78,0x03,0x9a,0x02,0x87,0x80,0xb1,0xe0,0x0b,0x78,0x03,0xb6,0x00,0xc5,0xa0 }}, - {16, 0xfb30, 0, {0x35,0x61,0x0c,0x78,0x13,0x1e,0x02,0xc7,0x80,0x29,0x00,0x0c,0x48,0x03,0x90,0x00 }}, - {16, 0xfb40, 0, {0xc4,0x80,0x31,0x60,0x0f,0x58,0x03,0x6a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb50, 0, {0x08,0x1d,0xa4,0x00,0xea,0x00,0x3e,0x80,0x0f,0xa0,0x03,0xe8,0x08,0xfb,0x00,0x3e }}, - {16, 0xfb60, 0, {0x80,0x0f,0x90,0x13,0xe4,0x08,0xf9,0x00,0x3c,0x50,0x2e,0xf0,0x03,0xe8,0x08,0xfb }}, - {16, 0xfb70, 0, {0x40,0x3e,0xc0,0x0b,0x30,0x13,0x6c,0x00,0xfb,0x00,0x3e,0x40,0x0f,0x30,0x03,0xc2 }}, - {16, 0xfb80, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xd6,0x00,0xcd,0x80,0x33,0xe0 }}, - {16, 0xfb90, 0, {0x0c,0xf8,0x03,0xfa,0x00,0xfd,0x80,0x3f,0xa0,0x0d,0xf8,0x03,0xfa,0x40,0xcd,0xd0 }}, - {16, 0xfba0, 0, {0x77,0x7e,0x0c,0xe8,0x43,0x1e,0x00,0xcf,0xd8,0x3f,0xe0,0x0c,0xc8,0x03,0x3a,0xc4 }}, - {16, 0xfbb0, 0, {0xcc,0x80,0x33,0xe0,0x0c,0xf8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbc0, 0, {0xa8,0x11,0x94,0x02,0x8d,0x00,0x21,0xc0,0x08,0x60,0x03,0xd8,0x10,0x35,0x20,0x8b }}, - {16, 0xfbd0, 0, {0xd4,0x0d,0x64,0x03,0xd8,0xc0,0x85,0x00,0x2f,0x4e,0x07,0x64,0x02,0x9c,0x02,0xd7 }}, - {16, 0xfbe0, 0, {0x30,0x2f,0x04,0x0d,0xf1,0x0b,0x54,0x40,0xaf,0x00,0x35,0x40,0x08,0x70,0x02,0x2a }}, - {16, 0xfbf0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x40,0x84,0x18,0x21,0x80 }}, - {16, 0xfc00, 0, {0x08,0x70,0x02,0xda,0x20,0xb5,0x00,0x09,0x00,0x08,0x70,0x02,0xd4,0x04,0x85,0x00 }}, - {16, 0xfc10, 0, {0x6d,0x4c,0x89,0x60,0x02,0x5c,0x40,0x97,0x00,0x6d,0xc0,0x09,0x40,0x02,0x58,0x80 }}, - {16, 0xfc20, 0, {0x84,0x88,0x25,0x40,0x08,0xd0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc30, 0, {0x20,0x14,0xc6,0x48,0x80,0x00,0x20,0x80,0x08,0xac,0x02,0xa8,0x00,0xb1,0x00,0xa8 }}, - {16, 0xfc40, 0, {0x88,0x09,0x22,0x02,0x86,0x42,0x81,0x00,0x6c,0x52,0x0b,0x20,0x02,0xc7,0x52,0x83 }}, - {16, 0xfc50, 0, {0x00,0x2c,0x00,0x08,0x34,0x82,0x67,0x00,0xa3,0x80,0x20,0x40,0x08,0x30,0x02,0x08 }}, - {16, 0xfc60, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xa3,0x00,0xcb,0xc0,0xb2,0x40 }}, - {16, 0xfc70, 0, {0x2c,0x90,0x82,0xe6,0x00,0xbb,0x80,0xbe,0x78,0x08,0x8e,0x02,0xee,0x00,0x8d,0x00 }}, - {16, 0xfc80, 0, {0x27,0x60,0x0d,0x90,0x0a,0x6f,0x00,0x9f,0x02,0x2e,0x00,0x09,0xb4,0x03,0x67,0x80 }}, - {16, 0xfc90, 0, {0xca,0x40,0xe4,0xc0,0x0c,0x30,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfca0, 0, {0x80,0x00,0xe0,0x80,0xfb,0x22,0x3e,0x40,0x0f,0x80,0x13,0xe4,0x00,0xfb,0x80,0x3e }}, - {16, 0xfcb0, 0, {0x40,0x0f,0x90,0x03,0xe5,0x00,0xf9,0x00,0x3e,0x40,0x0e,0x70,0x23,0xac,0x20,0xfb }}, - {16, 0xfcc0, 0, {0x00,0x3e,0xc0,0x8f,0x80,0x03,0xe9,0x20,0xf9,0x08,0x3e,0x40,0x0f,0xb0,0x13,0xe0 }}, - {16, 0xfcd0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x00,0xc6,0x00,0x32,0x00 }}, - {16, 0xfce0, 0, {0x0f,0xd1,0x83,0x34,0x40,0xcf,0x00,0x3d,0x40,0x0c,0xd0,0x03,0xde,0x50,0x0d,0x00 }}, - {16, 0xfcf0, 0, {0x73,0x40,0x0c,0xd1,0x03,0x7c,0x40,0x87,0x02,0xb3,0x00,0x0d,0xf4,0x03,0x24,0x00 }}, - {16, 0xfd00, 0, {0xce,0x20,0x32,0x40,0x0c,0xd0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd10, 0, {0x81,0x04,0x61,0x22,0x8a,0x00,0x22,0x00,0x0b,0x80,0x40,0x25,0x00,0x89,0xc3,0x2e }}, - {16, 0xfd20, 0, {0x20,0x0a,0x98,0x03,0xa1,0x00,0x89,0x00,0x36,0x40,0x88,0x94,0x02,0x0f,0x01,0xab }}, - {16, 0xfd30, 0, {0x00,0x32,0xc0,0x08,0x04,0x0a,0x29,0x00,0xa9,0x02,0xa2,0x40,0x0d,0xb0,0x0a,0x20 }}, - {16, 0xfd40, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x00,0x89,0x00,0x22,0x61 }}, - {16, 0xfd50, 0, {0x0b,0x90,0x02,0x25,0x01,0x9b,0x88,0x2e,0x60,0x08,0x88,0x02,0xe8,0x00,0xb1,0x02 }}, - {16, 0xfd60, 0, {0x24,0x40,0x18,0x90,0x02,0x2c,0x00,0xab,0x01,0x20,0xc1,0x08,0xb4,0x42,0x2c,0x00 }}, - {16, 0xfd70, 0, {0x82,0x00,0x22,0xc0,0x08,0xb0,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd80, 0, {0x08,0x04,0x00,0x00,0x01,0x00,0x20,0x40,0x0b,0x00,0x0a,0x04,0x46,0x83,0x01,0x2c }}, - {16, 0xfd90, 0, {0x40,0x1a,0x00,0x06,0x80,0x00,0x81,0x00,0x24,0x40,0x08,0x20,0x0a,0x0c,0x01,0xa3 }}, - {16, 0xfda0, 0, {0x00,0x24,0x00,0x08,0x80,0x02,0x00,0x00,0xa1,0x00,0x20,0x40,0x09,0x30,0x02,0x02 }}, - {16, 0xfdb0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x02,0xc8,0x00,0x22,0x00 }}, - {16, 0xfdc0, 0, {0x0f,0x90,0x02,0x25,0x00,0xda,0x00,0x3e,0x40,0x0c,0x90,0x02,0xcc,0x00,0xfd,0x00 }}, - {16, 0xfdd0, 0, {0x37,0x40,0x0c,0x10,0x13,0x2c,0x02,0xaf,0x00,0x32,0xc0,0x0d,0xb0,0x03,0x2c,0x00 }}, - {16, 0xfde0, 0, {0xca,0x00,0x32,0x40,0x4c,0x90,0x0b,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfdf0, 0, {0xa0,0x1d,0xf0,0x00,0xfc,0x00,0x3f,0x00,0x07,0xc0,0x03,0xf4,0x1c,0xf4,0x00,0x3f }}, - {16, 0xfe00, 0, {0x00,0x1f,0xc0,0x23,0xb0,0x02,0x9d,0x01,0x3f,0x40,0x8f,0xc0,0x07,0xfc,0x02,0xff }}, - {16, 0xfe10, 0, {0x00,0x7b,0x00,0x0f,0xc0,0x03,0xf0,0x00,0xfd,0x00,0x3f,0x40,0x0f,0x70,0x03,0xe8 }}, - {16, 0xfe20, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfa,0x00,0xcb,0x80,0x3f,0x24 }}, - {16, 0xfe30, 0, {0x0a,0xc1,0x03,0xfc,0x24,0xcd,0x20,0x37,0x0a,0x0c,0xc2,0x83,0x30,0x80,0xdc,0x02 }}, - {16, 0xfe40, 0, {0x3f,0xcc,0x0d,0xd9,0x03,0x3c,0x58,0xdf,0x30,0x33,0xc8,0x0d,0xf4,0x23,0x3c,0x40 }}, - {16, 0xfe50, 0, {0xff,0x00,0x3f,0xc5,0x4f,0xf0,0x23,0xb0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfe60, 0, {0x80,0x00,0xec,0x02,0x0b,0x82,0x2e,0x08,0x0d,0xb7,0x02,0xfd,0x00,0x83,0x18,0x0a }}, - {16, 0xfe70, 0, {0x58,0x0a,0x84,0xa2,0xa5,0xa0,0x89,0x30,0x22,0x55,0x08,0x12,0x62,0xbd,0x90,0x8f }}, - {16, 0xfe80, 0, {0x62,0x21,0xd6,0x48,0xf3,0x02,0x3c,0xc5,0xbf,0x48,0x2f,0xd8,0x4b,0xb7,0x02,0xe0 }}, - {16, 0xfe90, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xec,0x00,0x83,0x00,0x2e,0x89 }}, - {16, 0xfea0, 0, {0x28,0x00,0x02,0xec,0xa0,0x89,0x22,0x28,0x82,0x08,0x12,0x02,0x28,0x40,0x9a,0x08 }}, - {16, 0xfeb0, 0, {0x28,0xc8,0x88,0xb2,0x0a,0x0d,0x10,0x93,0x10,0xa0,0xc8,0x28,0x30,0x02,0x4c,0x00 }}, - {16, 0xfec0, 0, {0xb3,0x60,0x2c,0xc4,0x0b,0x30,0xc2,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfed0, 0, {0xc0,0x15,0xac,0x40,0x8b,0x00,0x2e,0x80,0x08,0xb1,0x02,0xec,0x02,0x8b,0x00,0x20 }}, - {16, 0xfee0, 0, {0xd0,0x0a,0x90,0x02,0xac,0x00,0x0b,0x01,0x26,0x40,0x08,0x94,0x02,0x8c,0x00,0x8b }}, - {16, 0xfef0, 0, {0x00,0x22,0xc0,0x08,0xb0,0x02,0x2c,0x10,0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x02,0xf0 }}, - {16, 0xff00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x8c,0x20,0xcb,0x02,0x3e,0x2d }}, - {16, 0xff10, 0, {0x08,0x80,0x03,0xec,0x08,0xc9,0x80,0x1e,0x04,0x0c,0xb0,0x03,0x01,0x08,0x50,0x18 }}, - {16, 0xff20, 0, {0x3e,0x40,0x0c,0x04,0x03,0x2c,0x00,0xdb,0x01,0x32,0xc0,0x0c,0xb0,0x0b,0x2c,0x08 }}, - {16, 0xff30, 0, {0xbb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x80,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xff40, 0, {0xe1,0x00,0xbc,0x00,0xff,0x00,0x3f,0x60,0x0f,0xc0,0x23,0xec,0x00,0xff,0xc0,0xbe }}, - {16, 0xff50, 0, {0x60,0x8f,0xc9,0x23,0xf6,0x50,0xed,0x80,0xb8,0x50,0xaf,0xc0,0x03,0xfc,0x00,0xff }}, - {16, 0xff60, 0, {0x00,0x3f,0xc1,0x0e,0xb0,0x03,0xfc,0x04,0xff,0x02,0x3f,0xc0,0x0f,0xf0,0x03,0xf8 }}, - {16, 0xff70, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x00,0xeb,0x00,0x32,0x80 }}, - {16, 0xff80, 0, {0x0d,0x90,0x03,0x2c,0x00,0x89,0x00,0x3e,0x98,0x8c,0x30,0x03,0x61,0x80,0xfa,0x40 }}, - {16, 0xff90, 0, {0x3e,0x40,0x2c,0xa5,0x03,0x2c,0x00,0xfb,0x01,0x3c,0xc0,0x2c,0x30,0x03,0x2c,0x00 }}, - {16, 0xffa0, 0, {0xdb,0x02,0x32,0xc0,0x0f,0xb0,0x03,0xd0,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xffb0, 0, {0xca,0x00,0x2e,0x80,0x8b,0x82,0xa0,0xc0,0x8c,0x90,0x02,0x3c,0x00,0x8b,0xf0,0x22 }}, - {16, 0xffc0, 0, {0xc2,0x0d,0x80,0x02,0x27,0x00,0x8b,0x10,0x22,0x40,0x08,0x80,0x22,0x3c,0x00,0xbf }}, - {16, 0xffd0, 0, {0x00,0x2f,0xc0,0x08,0xf0,0x02,0x3c,0x00,0xbf,0x01,0xa3,0xc0,0x0b,0xf0,0x12,0xf2 }}, - {16, 0xffe0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4c,0x00,0xb3,0x1c,0x20,0x40 }}, - {16, 0xfff0, 0, {0x08,0x00,0x06,0x2c,0x00,0x9b,0x00,0x20,0xd0,0x08,0x20,0x02,0x4c,0x00,0xa3,0x00 }}, - {16, 0x8010, 0, {0x2c,0xc0,0x08,0x10,0x0a,0x0c,0x00,0xbb,0x00,0x28,0xc0,0x09,0x30,0x02,0x0c,0x00 }}, - {16, 0x8020, 0, {0xb3,0x00,0x20,0xc0,0x0b,0x30,0x02,0xf8,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8030, 0, {0x22,0x11,0x1e,0x00,0x97,0xa0,0x21,0xa0,0x08,0x79,0x02,0x1e,0x00,0x97,0x90,0x21 }}, - {16, 0x8040, 0, {0x60,0x09,0xe8,0x22,0x3e,0x00,0xaf,0x84,0x21,0xe4,0x48,0x5c,0x02,0x1e,0x00,0xb7 }}, - {16, 0x8050, 0, {0x90,0x2d,0xe0,0x09,0x78,0x00,0x1e,0x09,0xb3,0x90,0x21,0xe4,0x0b,0x78,0x02,0xd8 }}, - {16, 0x8060, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x18,0x2c,0x40,0xb3,0xb0,0x32,0x40 }}, - {16, 0x8070, 0, {0x2c,0x81,0x13,0x0c,0x42,0xd1,0x00,0xb0,0xc0,0x8c,0x30,0x03,0x48,0x20,0xe3,0x01 }}, - {16, 0x8080, 0, {0x3c,0xc0,0x0c,0x30,0x03,0x0c,0x00,0xf3,0x10,0x3c,0xc0,0xcd,0x32,0x0b,0x0c,0x40 }}, - {16, 0x8090, 0, {0xd3,0x00,0x30,0xc0,0x0f,0x30,0x03,0xd2,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x80a0, 0, {0x40,0x15,0xbc,0x00,0xe7,0x00,0x3f,0x80,0x0b,0xf1,0x03,0xfd,0x00,0x6d,0x00,0x32 }}, - {16, 0x80b0, 0, {0x40,0x1f,0x70,0x07,0xd8,0x41,0xc3,0x10,0x3b,0xc0,0x0f,0xd1,0x03,0xfd,0x00,0xff }}, - {16, 0x80c0, 0, {0x10,0x3f,0xc0,0x0e,0xf0,0x03,0xec,0x10,0xff,0x08,0x3f,0xc3,0x0f,0xf0,0x03,0xd0 }}, - {16, 0x80d0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xec,0x04,0xfb,0x02,0x3e,0x40 }}, - {16, 0x80e0, 0, {0x0b,0xa0,0x03,0xac,0x00,0xdb,0x00,0x36,0x80,0x0d,0xb0,0x03,0xac,0x00,0xe8,0x00 }}, - {16, 0x80f0, 0, {0x36,0xc1,0x2e,0x90,0x03,0x2c,0x00,0xcb,0xa0,0x36,0xdc,0x0f,0xb0,0x03,0x2d,0x68 }}, - {16, 0x8100, 0, {0xfb,0xa0,0x92,0xc2,0x0c,0xb1,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8110, 0, {0x48,0x11,0x9c,0x08,0x37,0x00,0x2d,0xc0,0x0b,0xe0,0x02,0x1d,0x80,0xb7,0x04,0x23 }}, - {16, 0x8120, 0, {0x00,0x0a,0x40,0x02,0x1c,0x18,0x84,0x00,0x25,0xc0,0x18,0x50,0x32,0x0d,0x80,0xa3 }}, - {16, 0x8130, 0, {0x30,0x21,0xcc,0x0b,0x34,0x82,0x1c,0x10,0xb7,0x30,0x21,0xc8,0x08,0x70,0x02,0xd2 }}, - {16, 0x8140, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x20,0xb7,0x80,0x2d,0x60 }}, - {16, 0x8150, 0, {0x0b,0xfc,0x22,0x9e,0x00,0x8d,0x80,0x25,0xa0,0x08,0xf8,0x22,0x92,0x00,0xb4,0x80 }}, - {16, 0x8160, 0, {0x25,0xe0,0x08,0xf8,0x02,0x1e,0x00,0x87,0xb0,0x21,0xe0,0x09,0x7a,0x02,0x1e,0x18 }}, - {16, 0x8170, 0, {0xb3,0x80,0x21,0xe0,0x08,0x78,0x02,0xf0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8180, 0, {0x48,0x04,0xc5,0x20,0xb3,0x01,0x2c,0xd8,0x0b,0x3c,0x02,0x2c,0x08,0xb9,0x00,0x20 }}, - {16, 0x8190, 0, {0x03,0x0a,0x00,0x82,0x22,0x08,0x90,0x0d,0x26,0xe4,0x08,0x10,0x02,0x0c,0x00,0xa3 }}, - {16, 0x81a0, 0, {0x00,0x22,0xc0,0x0b,0x30,0x02,0x6c,0x00,0xb3,0x00,0x22,0xc0,0x28,0x30,0x02,0xc2 }}, - {16, 0x81b0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x05,0x99,0x00,0xfa,0x02,0x3f,0x90 }}, - {16, 0x81c0, 0, {0x0f,0xec,0x23,0xa8,0x00,0xda,0x00,0x35,0x80,0x0d,0xe0,0x02,0xba,0x02,0xfe,0xc2 }}, - {16, 0x81d0, 0, {0xb6,0xa0,0x0e,0xe4,0x0b,0x28,0x00,0xca,0x00,0xb2,0x80,0x0f,0xa0,0x0b,0x28,0x00 }}, - {16, 0x81e0, 0, {0xfa,0x00,0x32,0x80,0x0c,0xa0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x81f0, 0, {0x48,0x00,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x82,0x03,0xe0,0x00,0xf8,0x00,0x3e }}, - {16, 0x8200, 0, {0x00,0x0f,0x81,0x03,0xe0,0x40,0xe8,0x10,0x3a,0x00,0x4f,0x84,0x83,0xe0,0x00,0xf8 }}, - {16, 0x8210, 0, {0x00,0x3a,0x00,0x0f,0x00,0x03,0xa0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0x8220, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0xe5,0x00,0xc9,0x02,0x3e,0x40 }}, - {16, 0x8230, 0, {0x0f,0x90,0x23,0x24,0x00,0xc9,0x00,0x32,0x68,0x2f,0x10,0x03,0x24,0x00,0xe9,0x14 }}, - {16, 0x8240, 0, {0x32,0x40,0x0d,0x90,0x0b,0x04,0x00,0xd9,0x00,0x1e,0x40,0x0c,0x90,0x03,0x24,0x00 }}, - {16, 0x8250, 0, {0xc9,0x00,0x36,0x40,0x0c,0x90,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8260, 0, {0x80,0x14,0x64,0x00,0x89,0x01,0x2e,0x40,0x4b,0x90,0x12,0x24,0x00,0x89,0xc2,0xa2 }}, - {16, 0x8270, 0, {0x60,0x88,0x90,0x03,0x64,0x00,0x89,0xc1,0xa2,0x40,0x48,0x16,0x03,0x64,0x02,0x89 }}, - {16, 0x8280, 0, {0x00,0x2e,0x40,0x08,0x90,0x22,0x24,0x00,0x89,0x00,0x3e,0x40,0x28,0x90,0x0a,0x20 }}, - {16, 0x8290, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x04,0x24,0x00,0x89,0x02,0x2e,0x40 }}, - {16, 0x82a0, 0, {0x0b,0x10,0x02,0x24,0x00,0x89,0x10,0x22,0x40,0x89,0x90,0x02,0xac,0x00,0xa1,0x08 }}, - {16, 0x82b0, 0, {0x22,0x40,0x09,0x98,0x02,0xa4,0x00,0x89,0x00,0x2a,0x40,0x08,0x90,0x02,0x24,0x00 }}, - {16, 0x82c0, 0, {0x89,0x00,0x26,0x40,0x08,0x10,0x02,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x82d0, 0, {0x08,0x00,0x24,0x00,0x81,0x00,0x2c,0x41,0x0b,0x12,0x02,0x04,0x81,0x81,0x20,0x22 }}, - {16, 0x82e0, 0, {0x48,0x08,0x12,0x02,0xc4,0x81,0x81,0x24,0x02,0x48,0x0a,0x90,0x02,0x84,0xa0,0x81 }}, - {16, 0x82f0, 0, {0x28,0x6c,0x4a,0x08,0x12,0xd2,0x04,0xa1,0x81,0x28,0x2c,0x4a,0x08,0x12,0x82,0x02 }}, - {16, 0x8300, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x08,0x61,0x40,0xc8,0x00,0x2e,0x14 }}, - {16, 0x8310, 0, {0x0f,0x85,0x0b,0x21,0x42,0xca,0x50,0x22,0x14,0x0d,0x85,0x43,0xa1,0x40,0xe8,0x50 }}, - {16, 0x8320, 0, {0x30,0x00,0x0d,0x85,0x02,0xa1,0xc0,0xd8,0x20,0x3a,0x08,0x2c,0x82,0x0b,0x20,0x82 }}, - {16, 0x8330, 0, {0xc8,0x20,0x34,0x09,0x8c,0x82,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8340, 0, {0x98,0x0d,0xfc,0x02,0xf9,0x00,0x3f,0x40,0x4f,0xd1,0x03,0xe4,0x40,0xf5,0x14,0xbf }}, - {16, 0x8350, 0, {0x44,0x0d,0x51,0x23,0x5c,0x40,0xf5,0x10,0x1f,0x4e,0x4d,0x50,0x03,0x64,0x08,0xf9 }}, - {16, 0x8360, 0, {0x28,0x3e,0x4a,0x8f,0x92,0x83,0xe4,0xa0,0xf9,0x28,0x3a,0x4b,0x0f,0x92,0x83,0xe6 }}, - {16, 0x8370, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xf4,0x40,0xfd,0x00,0x30,0x40 }}, - {16, 0x8380, 0, {0x0c,0x90,0x03,0x24,0x00,0xdd,0x00,0x3b,0x40,0x0e,0x90,0x03,0x74,0x00,0x5d,0x00 }}, - {16, 0x8390, 0, {0x36,0x64,0x0d,0xd0,0x00,0xa6,0x00,0xf9,0x40,0x32,0x78,0x0c,0x99,0x03,0x24,0x40 }}, - {16, 0x83a0, 0, {0xc9,0x90,0x32,0x50,0x0f,0x9b,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x83b0, 0, {0x38,0x10,0xe2,0x80,0xb8,0x00,0x22,0x01,0x08,0x80,0x0a,0x20,0x00,0x88,0x00,0x2a }}, - {16, 0x83c0, 0, {0x00,0x08,0x80,0x02,0x20,0x00,0x88,0x00,0x22,0x20,0x08,0x8a,0x8b,0xe1,0x00,0xb8 }}, - {16, 0x83d0, 0, {0x80,0x22,0x30,0x28,0x0d,0x02,0x22,0x00,0xd8,0xe4,0x22,0x28,0x0b,0x8f,0x0a,0x0e }}, - {16, 0x83e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0x80,0xb1,0x00,0xa0,0x40 }}, - {16, 0x83f0, 0, {0x08,0x10,0x02,0x04,0x00,0x89,0x00,0x08,0x40,0x0a,0x90,0x42,0x44,0x00,0x91,0x00 }}, - {16, 0x8400, 0, {0x20,0x58,0x28,0x90,0x02,0x85,0x00,0x81,0x20,0xa0,0x4c,0x09,0x12,0x0a,0x04,0x80 }}, - {16, 0x8410, 0, {0x91,0x40,0xa0,0x40,0x0b,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8420, 0, {0x18,0x15,0xa4,0x00,0xb9,0x02,0x20,0x40,0x08,0x90,0x02,0x04,0x00,0x89,0x01,0x22 }}, - {16, 0x8430, 0, {0x40,0x28,0x90,0x22,0x04,0x00,0x89,0x10,0x22,0x40,0x08,0x90,0x02,0xe4,0x00,0xb1 }}, - {16, 0x8440, 0, {0x00,0x22,0x40,0x81,0x90,0x02,0x04,0x00,0x91,0x00,0x22,0x40,0x0b,0x90,0x02,0x06 }}, - {16, 0x8450, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe5,0x00,0xf1,0x00,0x32,0x60 }}, - {16, 0x8460, 0, {0x2c,0x92,0x13,0x24,0x02,0xd1,0x10,0x3a,0x40,0x0e,0x12,0x03,0x66,0x04,0xd9,0x00 }}, - {16, 0x8470, 0, {0xb6,0x40,0x0d,0x19,0x03,0xa4,0x00,0xf9,0x00,0x32,0x40,0x09,0x90,0x01,0x24,0x00 }}, - {16, 0x8480, 0, {0xd9,0x02,0x22,0x40,0x0f,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8490, 0, {0x2a,0x01,0xa5,0x00,0xf9,0x00,0x3e,0x64,0x0f,0x10,0x03,0xe4,0x00,0xf9,0x81,0x3e }}, - {16, 0x84a0, 0, {0x66,0x8f,0x90,0x23,0xe4,0x80,0xf9,0x04,0x3e,0x40,0x8f,0x90,0x03,0xe4,0x04,0xf9 }}, - {16, 0x84b0, 0, {0x00,0x3c,0x40,0x0e,0x90,0x03,0xe4,0x00,0xf9,0x00,0x3e,0x40,0x0f,0x10,0x03,0xca }}, - {16, 0x84c0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x10,0xa0,0x00,0xf8,0x24,0x3e,0x00 }}, - {16, 0x84d0, 0, {0x2c,0x84,0x03,0x20,0x00,0xb8,0x20,0x3e,0x00,0x8c,0x80,0x03,0xa0,0x00,0x70,0x82 }}, - {16, 0x84e0, 0, {0x32,0x00,0x0f,0x80,0x03,0x20,0x08,0xf8,0x00,0x32,0x00,0x2c,0x80,0x0b,0x20,0x08 }}, - {16, 0x84f0, 0, {0xc8,0x00,0x3e,0x00,0x0c,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8500, 0, {0x28,0x05,0x28,0x04,0xbe,0x80,0x3a,0x80,0x08,0xa0,0x02,0x28,0x04,0x8e,0x00,0x6d }}, - {16, 0x8510, 0, {0x90,0x0d,0xa0,0x02,0x3a,0x00,0x8e,0x80,0xa2,0x80,0x0e,0xe0,0x0b,0x68,0x00,0xba }}, - {16, 0x8520, 0, {0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0xda,0x00,0x2e,0x80,0x08,0xa0,0x02,0xca }}, - {16, 0x8530, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x81,0x4c,0x00,0xb1,0x00,0x2c,0xc0 }}, - {16, 0x8540, 0, {0x08,0x30,0x02,0x0c,0x18,0xa3,0x02,0x2c,0x10,0x88,0x30,0x06,0x82,0x81,0xa0,0x00 }}, - {16, 0x8550, 0, {0x2a,0xc0,0x0b,0x30,0x0a,0x4c,0x00,0xb3,0x00,0x20,0xc0,0x1a,0xb0,0x02,0x8c,0x01 }}, - {16, 0x8560, 0, {0x83,0x00,0x2c,0xc0,0x08,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8570, 0, {0x20,0x01,0x1c,0x10,0xb4,0x0a,0x2b,0xc8,0x08,0x31,0x26,0x1c,0x00,0x86,0x00,0x2d }}, - {16, 0x8580, 0, {0xc0,0x09,0x72,0x02,0x1d,0x00,0xa5,0x40,0x29,0xc0,0x0a,0x60,0x02,0x5c,0x88,0xb3 }}, - {16, 0x8590, 0, {0x20,0x25,0xc8,0x0a,0x72,0x02,0x9c,0x80,0x97,0x20,0x2c,0xe8,0x80,0x72,0x02,0xe8 }}, - {16, 0x85a0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x08,0x16,0x00,0xb5,0x80,0x3d,0xe2 }}, - {16, 0x85b0, 0, {0x0c,0x7a,0x8b,0x0e,0xc0,0xa7,0x81,0x2c,0x20,0x0c,0xfc,0x03,0x92,0x02,0xef,0x80 }}, - {16, 0x85c0, 0, {0x39,0xe4,0x0b,0xd8,0x01,0x1f,0x00,0xf7,0x80,0xb3,0xf4,0x8e,0x79,0x03,0x8e,0x00 }}, - {16, 0x85d0, 0, {0xc7,0xc4,0x3d,0xe8,0x2c,0x7b,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x85e0, 0, {0x08,0x1d,0xac,0x00,0xf8,0x00,0x3e,0xdd,0x87,0xb6,0x03,0xed,0xcc,0xe9,0x00,0x3e }}, - {16, 0x85f0, 0, {0x40,0x0f,0xb0,0x07,0xcc,0x10,0x0b,0x00,0x36,0xd8,0x0f,0x80,0x43,0xad,0x80,0xfb }}, - {16, 0x8600, 0, {0x28,0x3a,0xc0,0x0d,0xb4,0x03,0x6c,0xe2,0xeb,0x60,0x3e,0xd4,0x0f,0xb0,0x03,0xc2 }}, - {16, 0x8610, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xfe,0x00,0xfe,0x90,0x3f,0xe5 }}, - {16, 0x8620, 0, {0x0e,0xf8,0x03,0x3e,0x10,0xff,0x90,0x17,0x60,0x0f,0xfc,0x03,0x7a,0x00,0xee,0x80 }}, - {16, 0x8630, 0, {0x37,0xe2,0x0e,0x78,0x0f,0xff,0x40,0xef,0x88,0x1f,0xe0,0x0c,0xf8,0x83,0xfe,0x80 }}, - {16, 0x8640, 0, {0xcf,0xd0,0xb3,0xf0,0x0c,0xf8,0xc3,0x10,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8650, 0, {0xa8,0x11,0x9c,0x40,0xb4,0x10,0x0f,0xcc,0x00,0x72,0x02,0x1c,0x00,0xb6,0x02,0x09 }}, - {16, 0x8660, 0, {0xc0,0x28,0xf0,0x02,0x98,0x00,0xa6,0x00,0x21,0xc0,0x0b,0x60,0x03,0xfc,0x02,0x87 }}, - {16, 0x8670, 0, {0x00,0x2d,0xc0,0x08,0x70,0x02,0xde,0x00,0x8f,0x10,0x21,0xc0,0x08,0xf0,0x03,0x6a }}, - {16, 0x8680, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x94,0x00,0xb6,0x02,0x2f,0xc2 }}, - {16, 0x8690, 0, {0x1a,0x30,0x80,0x1c,0x00,0xb6,0x08,0x01,0x40,0x0a,0xf0,0x02,0x18,0x00,0x87,0x00 }}, - {16, 0x86a0, 0, {0x21,0xc0,0x0b,0xd0,0x02,0x9c,0x10,0x87,0x00,0x29,0xc0,0x08,0x70,0x02,0xdc,0x44 }}, - {16, 0x86b0, 0, {0x87,0x10,0x64,0xc0,0x08,0x70,0x02,0x06,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x86c0, 0, {0x60,0x14,0xce,0x60,0xb0,0x00,0x2c,0xc0,0x08,0x34,0x0a,0x0c,0x08,0xb0,0x04,0x00 }}, - {16, 0x86d0, 0, {0x40,0x08,0x30,0xa2,0x89,0x80,0xa2,0x62,0x20,0xe0,0x0b,0x00,0x0a,0xcc,0x08,0x83 }}, - {16, 0x86e0, 0, {0x00,0x6c,0xc0,0x08,0x30,0x52,0xcc,0x00,0x83,0x00,0x24,0xc0,0x08,0x30,0x02,0x58 }}, - {16, 0x86f0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xae,0x00,0xf8,0x00,0x3f,0xd0 }}, - {16, 0x8700, 0, {0x0e,0xfc,0x03,0x3c,0x00,0xf9,0x00,0x92,0x84,0x0f,0xfc,0x03,0x64,0x00,0x80,0x00 }}, - {16, 0x8710, 0, {0xb7,0xc3,0x0f,0xb8,0x83,0xbc,0x04,0xef,0x00,0x3f,0xc0,0x3c,0xf0,0x03,0xfc,0x02 }}, - {16, 0x8720, 0, {0xcf,0x00,0x37,0xc0,0x28,0xf0,0x13,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8730, 0, {0x80,0x00,0xec,0x00,0xf8,0x41,0x3e,0xc8,0x0f,0x32,0x03,0xec,0x00,0xf8,0x00,0x3a }}, - {16, 0x8740, 0, {0xc4,0x0f,0xb1,0x03,0xc4,0x00,0xf9,0x00,0x36,0xc0,0x0f,0xe4,0x0b,0xec,0x04,0xfb }}, - {16, 0x8750, 0, {0x00,0x3e,0xc1,0x0f,0xb0,0x43,0xec,0x04,0xfb,0x00,0x3a,0xc0,0x0f,0xb0,0x03,0xe4 }}, - {16, 0x8760, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf4,0x00,0xfc,0x80,0x3f,0xc0 }}, - {16, 0x8770, 0, {0x1f,0xf0,0x03,0x3c,0x08,0xfb,0x00,0x33,0x80,0x2e,0xf0,0x13,0xa4,0x04,0xcb,0x00 }}, - {16, 0x8780, 0, {0xb9,0xc0,0x2c,0xd8,0x0b,0x3c,0x00,0xff,0x00,0x3f,0xc0,0x09,0x70,0x00,0x2c,0x04 }}, - {16, 0x8790, 0, {0xff,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xc0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x87a0, 0, {0xc1,0x00,0x6c,0x00,0xb8,0x80,0x2e,0xc0,0x0b,0xb0,0x03,0x6c,0x00,0xb9,0x16,0x28 }}, - {16, 0x87b0, 0, {0x72,0x08,0xb0,0x22,0x27,0x40,0xdb,0x00,0x22,0xc0,0x08,0xbd,0x82,0x2c,0x08,0xbb }}, - {16, 0x87c0, 0, {0x00,0x2e,0xc0,0x48,0xb0,0x02,0x2c,0x00,0xbb,0x00,0x2e,0xc1,0x0b,0xb0,0x02,0xe0 }}, - {16, 0x87d0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0xb8,0x60,0x2e,0xc0 }}, - {16, 0x87e0, 0, {0x0b,0xb0,0x02,0x2c,0x00,0xb1,0x00,0x2a,0x84,0x4a,0x30,0x22,0xac,0x20,0x98,0x80 }}, - {16, 0x87f0, 0, {0x2a,0xc0,0x08,0x30,0x02,0xac,0x00,0x3b,0x00,0x2c,0xc0,0x0a,0xb0,0x02,0xac,0x08 }}, - {16, 0x8800, 0, {0xbb,0x00,0x2e,0xc0,0x0b,0xb0,0x42,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8810, 0, {0x08,0x04,0x0c,0x01,0xb0,0x00,0x2c,0xc0,0x0b,0x30,0x02,0x4c,0x04,0xb0,0x00,0x2a }}, - {16, 0x8820, 0, {0x80,0x08,0x30,0x02,0x00,0x00,0x10,0x04,0x28,0xc0,0x08,0x20,0x42,0x8c,0x00,0xb3 }}, - {16, 0x8830, 0, {0x00,0x2c,0xc0,0x42,0x30,0x0a,0x8c,0x00,0xb3,0x00,0x2c,0xc0,0x8b,0x30,0x02,0xc2 }}, - {16, 0x8840, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x64,0x00,0xf8,0x50,0x3f,0xc0 }}, - {16, 0x8850, 0, {0x0b,0xf0,0x03,0x3c,0x00,0xfa,0x04,0x32,0x80,0x0e,0xf0,0x23,0xac,0x00,0xd9,0x00 }}, - {16, 0x8860, 0, {0x3b,0xc0,0x0c,0x90,0x03,0xbc,0x04,0xff,0x00,0x3d,0xc0,0x2e,0xf0,0x0b,0x3c,0x00 }}, - {16, 0x8870, 0, {0xff,0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8880, 0, {0xa0,0x1d,0xfc,0x00,0xfc,0x00,0x3f,0xc0,0x07,0xf0,0x03,0xfc,0x04,0x7c,0x02,0xb5 }}, - {16, 0x8890, 0, {0x00,0x0f,0xf0,0x03,0xf0,0x00,0xfc,0x00,0x37,0xc0,0x0f,0xf0,0x13,0x7c,0x00,0xff }}, - {16, 0x88a0, 0, {0x00,0x3f,0xc0,0x0d,0xf0,0x03,0x6d,0x00,0xff,0x00,0x3f,0xc0,0x1f,0xf0,0x03,0xe8 }}, - {16, 0x88b0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd2,0x00,0xd5,0x80,0x33,0x0a }}, - {16, 0x88c0, 0, {0x4c,0xf8,0x03,0xf2,0x00,0xfc,0x00,0x37,0x26,0x1f,0xca,0x03,0xbc,0xc4,0xcf,0x20 }}, - {16, 0x88d0, 0, {0x33,0xe4,0x0f,0x78,0x03,0x3e,0x44,0xcf,0x00,0x3b,0xce,0x9f,0x68,0x13,0xd0,0x00 }}, - {16, 0x88e0, 0, {0xcd,0x80,0xb3,0x60,0x0f,0xfa,0x83,0xf0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x88f0, 0, {0x80,0x10,0xe0,0x80,0xc9,0x28,0x22,0x30,0x08,0xb2,0x22,0xea,0x01,0xb8,0x82,0x20 }}, - {16, 0x8900, 0, {0x50,0x4f,0x9c,0x00,0xa8,0xd1,0xdb,0x10,0xa6,0xe0,0x17,0xb8,0x03,0xec,0x80,0xdb }}, - {16, 0x8910, 0, {0x08,0x1f,0xd0,0x0b,0xb8,0x02,0xf6,0x00,0xfb,0x80,0x22,0x40,0x0b,0xb0,0x02,0x60 }}, - {16, 0x8920, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x20,0x81,0x80,0x20,0x00 }}, - {16, 0x8930, 0, {0x8b,0x30,0x82,0xc0,0x00,0xb0,0x10,0x28,0x08,0x8b,0x11,0x30,0xc4,0x84,0x90,0x28 }}, - {16, 0x8940, 0, {0x24,0xc8,0x0b,0x30,0x02,0x4c,0x00,0x83,0x10,0x04,0xc8,0x0b,0x30,0x02,0xcc,0x00 }}, - {16, 0x8950, 0, {0xb3,0x00,0x24,0x40,0x0b,0x30,0x02,0xe2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8960, 0, {0xc0,0x15,0xa6,0x00,0x81,0x00,0x22,0x10,0x0b,0xb0,0x12,0xea,0x20,0xbb,0x00,0x2a }}, - {16, 0x8970, 0, {0x70,0x0a,0x9c,0x02,0x62,0x00,0x98,0x88,0x26,0xc8,0x02,0xb2,0x02,0x8e,0x08,0x8b }}, - {16, 0x8980, 0, {0x18,0x22,0xc0,0x0b,0xa0,0x02,0xee,0x20,0x3b,0x00,0x26,0x40,0x0b,0xb0,0x02,0x70 }}, - {16, 0x8990, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xe0,0x00,0xcb,0x00,0x32,0x80 }}, - {16, 0x89a0, 0, {0x0f,0xb0,0x03,0xe7,0x00,0xb8,0x52,0x3e,0x20,0x4b,0x0c,0x43,0xef,0x82,0x9b,0xc0 }}, - {16, 0x89b0, 0, {0x32,0xc0,0x0b,0xb0,0x02,0x6c,0x01,0x8b,0x80,0x2e,0xc0,0x0b,0xa0,0x83,0xe6,0x00 }}, - {16, 0x89c0, 0, {0xfb,0x00,0x36,0x40,0x0f,0xf0,0x03,0xd0,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x89d0, 0, {0xe0,0x01,0xb0,0x02,0xff,0x04,0x3f,0x90,0x0c,0xf1,0x01,0xf4,0x08,0x7d,0x80,0x37 }}, - {16, 0x89e0, 0, {0x00,0x0f,0xc0,0x23,0x98,0x00,0xf7,0x00,0x2b,0xe0,0x0f,0xf8,0x23,0xfc,0x06,0xfb }}, - {16, 0x89f0, 0, {0x83,0xbf,0xc0,0x87,0xd0,0x03,0xdc,0x00,0xef,0x00,0x3b,0xc0,0x0f,0xb0,0x01,0xf8 }}, - {16, 0x8a00, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa6,0x00,0xcb,0x00,0x33,0x80 }}, - {16, 0x8a10, 0, {0x0f,0xb0,0x03,0xe1,0x10,0xf2,0x40,0xb2,0x00,0x3d,0x94,0x17,0x2d,0x44,0xfa,0x41 }}, - {16, 0x8a20, 0, {0x32,0xc0,0x9f,0xb0,0x23,0x2c,0x02,0xcb,0x40,0x32,0xc0,0x4f,0x90,0x03,0x3d,0x00 }}, - {16, 0x8a30, 0, {0xcb,0x00,0x3e,0x40,0x0f,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8a40, 0, {0x88,0x05,0x26,0x00,0x8b,0x71,0x20,0xd5,0x03,0x99,0x02,0xe0,0x00,0xbb,0x80,0x22 }}, - {16, 0x8a50, 0, {0x60,0x1c,0x80,0x03,0x60,0x00,0xb8,0x02,0x22,0xc2,0x0b,0x32,0x02,0x2c,0x01,0x8f }}, - {16, 0x8a60, 0, {0x02,0xd7,0xc0,0x0b,0xa0,0x03,0x6d,0x40,0x53,0x80,0x2e,0xc0,0x0e,0xf0,0x43,0x72 }}, - {16, 0x8a70, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x68,0x02,0x80,0x00,0x24,0x00 }}, - {16, 0x8a80, 0, {0x0b,0x35,0x26,0xc2,0x00,0xb0,0x90,0x20,0xc0,0x88,0x00,0x02,0x4f,0x20,0xb3,0x02 }}, - {16, 0x8a90, 0, {0x60,0xe2,0x1b,0x38,0x02,0x0c,0x00,0x88,0x00,0x60,0xc0,0x0b,0x34,0x82,0x4c,0x02 }}, - {16, 0x8aa0, 0, {0xa1,0x90,0x2c,0x40,0x0b,0x30,0x02,0x30,0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ab0, 0, {0x20,0x01,0x3a,0x08,0x8c,0xa0,0x2d,0x20,0x4b,0x78,0x02,0xda,0x00,0xb2,0x90,0x21 }}, - {16, 0x8ac0, 0, {0x66,0x48,0x79,0x02,0xde,0x40,0xb7,0x91,0xa1,0xe0,0xdb,0xf8,0x02,0x1e,0x40,0x84 }}, - {16, 0x8ad0, 0, {0x90,0x01,0xe0,0x8b,0xf9,0x02,0x5e,0x01,0x97,0x80,0x2d,0x60,0x0a,0x78,0x00,0x48 }}, - {16, 0x8ae0, 0, {0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x80,0x00,0x24,0x04 }}, - {16, 0x8af0, 0, {0x0f,0x32,0x03,0xc4,0xa0,0xf1,0x42,0x30,0xc4,0x2c,0x31,0x02,0x44,0x00,0xf1,0x11 }}, - {16, 0x8b00, 0, {0xa0,0xc0,0x0b,0x30,0x0b,0x0c,0x42,0x83,0x00,0x00,0xc0,0x0f,0x30,0x03,0x4c,0x02 }}, - {16, 0x8b10, 0, {0xe3,0x00,0x3c,0x40,0x0b,0x30,0x01,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8b20, 0, {0xc0,0x1d,0xbc,0x00,0xfc,0xa5,0x33,0xc0,0x0f,0xd0,0x03,0xfc,0x01,0xbf,0x00,0x3f }}, - {16, 0x8b30, 0, {0xc4,0x0e,0x71,0x03,0x74,0x00,0x75,0x10,0x3f,0xc0,0x05,0xf0,0x03,0xdc,0x40,0xff }}, - {16, 0x8b40, 0, {0x04,0x3f,0xc0,0x0f,0xf0,0x43,0xfc,0x00,0x7f,0x00,0x3f,0x40,0x0e,0xf0,0x03,0xd0 }}, - {16, 0x8b50, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x04,0xe8,0x00,0xf2,0x04,0xb3,0x80 }}, - {16, 0x8b60, 0, {0x0f,0xb8,0x0b,0x2c,0x00,0xeb,0x80,0x32,0xc0,0x0c,0x20,0x13,0x2e,0x08,0xcb,0x01 }}, - {16, 0x8b70, 0, {0x32,0xc5,0x0f,0xb1,0x03,0xec,0x48,0xc8,0x10,0x32,0xfa,0x8c,0x38,0x03,0x3c,0x90 }}, - {16, 0x8b80, 0, {0xcb,0x00,0x3e,0x40,0x0f,0xb0,0x13,0xc2,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8b90, 0, {0xc8,0x10,0x98,0x00,0xf6,0x00,0x61,0x81,0x0b,0xf0,0x02,0x1c,0x00,0xd7,0x00,0xb7 }}, - {16, 0x8ba0, 0, {0x80,0x0c,0x70,0x02,0xbc,0x10,0x8f,0x00,0x21,0xc8,0x8b,0x72,0x43,0xfc,0x88,0xdc }}, - {16, 0x8bb0, 0, {0x00,0x37,0xc8,0x0d,0x50,0x02,0x1c,0x22,0x87,0x00,0x2d,0xc0,0x0b,0x70,0x02,0xd3 }}, - {16, 0x8bc0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x9e,0x00,0xb6,0x80,0xa9,0xa0 }}, - {16, 0x8bd0, 0, {0x4b,0x7c,0x02,0x5e,0x30,0xa3,0x88,0x21,0xf0,0x08,0x78,0x02,0x16,0x00,0x85,0x80 }}, - {16, 0x8be0, 0, {0x21,0xe0,0x0b,0x78,0x02,0xde,0x00,0x87,0x80,0xa1,0xe4,0x08,0xd8,0x02,0x4e,0x00 }}, - {16, 0x8bf0, 0, {0x97,0x80,0x2d,0x70,0x0b,0x78,0x02,0xc8,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8c00, 0, {0x48,0x14,0xec,0x00,0xb2,0x00,0x28,0xc0,0x0b,0x10,0x02,0x4e,0x90,0x93,0x02,0x22 }}, - {16, 0x8c10, 0, {0xf0,0x08,0x38,0x42,0x8c,0x42,0x83,0x04,0x22,0xe4,0x4b,0x38,0x02,0x8e,0x40,0x83 }}, - {16, 0x8c20, 0, {0x00,0x20,0xc0,0x09,0x38,0x22,0x4e,0x21,0x93,0x00,0x2e,0xe0,0x0b,0x30,0x02,0xdb }}, - {16, 0x8c30, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xa8,0x01,0xfa,0x00,0x3b,0x89 }}, - {16, 0x8c40, 0, {0x0f,0xa0,0x02,0x78,0x08,0xae,0x40,0x23,0x80,0x2c,0x6c,0x0b,0x3a,0x00,0x8e,0x8c }}, - {16, 0x8c50, 0, {0xb2,0x00,0x0b,0x80,0x82,0xe0,0x02,0x8e,0x00,0x22,0x80,0x0c,0xe8,0x02,0x7b,0x80 }}, - {16, 0x8c60, 0, {0x9a,0x80,0x3e,0x80,0x0f,0xa0,0x03,0xfa,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8c70, 0, {0x48,0x00,0xe0,0x09,0xec,0x00,0x36,0x21,0x0b,0x80,0x13,0xa1,0x00,0xf8,0x60,0x3e }}, - {16, 0x8c80, 0, {0x00,0x0f,0x81,0x03,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x43,0xe0,0x10,0xf8 }}, - {16, 0x8c90, 0, {0x00,0xbe,0x00,0x0f,0x85,0x0b,0x80,0x00,0xe8,0x10,0x3e,0x00,0x0f,0x80,0x03,0xd2 }}, - {16, 0x8ca0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x02,0x30,0x48 }}, - {16, 0x8cb0, 0, {0x0c,0x99,0x13,0xa4,0x02,0xc9,0x00,0x3e,0x42,0x0c,0x90,0x8f,0x24,0x00,0xf9,0x00 }}, - {16, 0x8cc0, 0, {0x32,0x28,0x0c,0x88,0x03,0xe0,0x00,0xc9,0x00,0xb2,0x40,0x0f,0x90,0x03,0xe7,0x00 }}, - {16, 0x8cd0, 0, {0xc9,0x10,0x3e,0x40,0x0c,0x10,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ce0, 0, {0x80,0x04,0x64,0x01,0x89,0x80,0xa2,0x48,0x28,0x92,0x42,0xc5,0x00,0x89,0x40,0x2e }}, - {16, 0x8cf0, 0, {0x40,0x2c,0x90,0x06,0x25,0x00,0xb9,0x00,0x22,0x50,0x08,0x98,0x02,0xc4,0x00,0x89 }}, - {16, 0x8d00, 0, {0x01,0x76,0x40,0x4b,0x92,0x02,0xe5,0x02,0x89,0x00,0x2e,0x40,0x0d,0x90,0x03,0x60 }}, - {16, 0x8d10, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x0c,0x85,0x20,0xa2,0x40 }}, - {16, 0x8d20, 0, {0x08,0x90,0x06,0xe5,0x00,0x89,0x40,0x2e,0x40,0x09,0x90,0x42,0xa4,0xa0,0x31,0x00 }}, - {16, 0x8d30, 0, {0x22,0x50,0x18,0x91,0x02,0xe4,0x00,0x81,0x00,0x22,0x40,0x0b,0x90,0x06,0xe4,0x00 }}, - {16, 0x8d40, 0, {0x89,0x00,0x2e,0x40,0x09,0x90,0x02,0x0e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8d50, 0, {0x00,0x04,0x15,0x00,0x85,0x40,0x20,0x40,0x08,0x14,0x26,0xe4,0x00,0x81,0x00,0x2c }}, - {16, 0x8d60, 0, {0x40,0x18,0x10,0x02,0x84,0x80,0xb1,0x20,0xa0,0x50,0x08,0x14,0x02,0xe5,0x02,0x81 }}, - {16, 0x8d70, 0, {0x40,0x20,0x48,0x0b,0x10,0x06,0xcc,0x00,0x81,0x01,0x2c,0x50,0x09,0x14,0x02,0x4a }}, - {16, 0x8d80, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0x8c,0x00,0x32,0x00 }}, - {16, 0x8d90, 0, {0x0c,0x80,0x23,0xe0,0x00,0xc8,0x00,0x3e,0x14,0x0d,0x80,0x12,0xa1,0x44,0xf8,0x51 }}, - {16, 0x8da0, 0, {0x32,0x00,0x2c,0x80,0x03,0xe0,0x00,0x88,0x04,0x22,0x14,0x0f,0x80,0x07,0xe0,0x00 }}, - {16, 0x8db0, 0, {0xc8,0x00,0x3e,0x00,0x0d,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8dc0, 0, {0x98,0x9d,0xe4,0x00,0xf9,0x00,0x3f,0x50,0x0f,0xd0,0x03,0xdc,0x01,0xbd,0x42,0x3f }}, - {16, 0x8dd0, 0, {0x50,0x4f,0xd4,0x43,0x74,0x41,0xfd,0x10,0x3f,0x10,0x1f,0xc4,0x13,0xf1,0x00,0xfd }}, - {16, 0x8de0, 0, {0x40,0x7e,0x44,0x0f,0xd0,0x43,0xf5,0x01,0xfd,0x00,0x3f,0x40,0x0f,0x94,0x03,0xe6 }}, - {16, 0x8df0, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf4,0x00,0xdf,0x05,0x33,0x61 }}, - {16, 0x8e00, 0, {0x0f,0x50,0x53,0x34,0x10,0xfd,0x04,0x33,0x44,0x4f,0x50,0x03,0x76,0xc1,0xcd,0xe0 }}, - {16, 0x8e10, 0, {0x33,0x60,0x0c,0xce,0x03,0xf6,0xc0,0xe1,0xc0,0xb6,0x64,0x8f,0x50,0x0b,0x36,0x82 }}, - {16, 0x8e20, 0, {0xcd,0x00,0x3e,0x44,0x4c,0x9e,0xc3,0xc6,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8e30, 0, {0x38,0x10,0xea,0x28,0x80,0xa0,0xb2,0x04,0x0b,0x8a,0x83,0x60,0x00,0xfa,0x00,0x36 }}, - {16, 0x8e40, 0, {0x28,0x8b,0x80,0x03,0xe3,0xc8,0xc8,0x84,0x22,0x14,0x08,0x8a,0x02,0xe2,0x80,0xd8 }}, - {16, 0x8e50, 0, {0x82,0x34,0x34,0x1b,0x80,0x03,0x60,0x04,0x88,0x00,0x2e,0x20,0x0a,0x8e,0x42,0xce }}, - {16, 0x8e60, 0, {0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x05,0xc4,0x80,0x81,0x08,0x04,0x41 }}, - {16, 0x8e70, 0, {0x0b,0x92,0x02,0x04,0x00,0xb1,0x00,0x2c,0x40,0x0b,0x18,0x02,0x24,0x00,0xb1,0x60 }}, - {16, 0x8e80, 0, {0x26,0x40,0x0a,0x16,0x02,0xc5,0x00,0xa1,0xc0,0x20,0x48,0x0b,0x90,0x02,0x47,0x00 }}, - {16, 0x8e90, 0, {0x91,0x01,0x2c,0x48,0x18,0x12,0x02,0xd2,0x01,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ea0, 0, {0x18,0x15,0xa4,0x0c,0x8b,0x04,0xa2,0x50,0x0b,0x91,0x02,0x24,0x04,0xa9,0x01,0x2e }}, - {16, 0x8eb0, 0, {0x42,0x0b,0x90,0x02,0xa4,0x00,0xa9,0x00,0x26,0x60,0x0a,0x90,0x02,0xe6,0x00,0x81 }}, - {16, 0x8ec0, 0, {0x00,0x22,0x40,0x8b,0xb0,0x02,0x24,0x08,0x99,0x10,0x2e,0x40,0x1a,0x90,0x02,0xc6 }}, - {16, 0x8ed0, 0, {0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe5,0x00,0xc9,0x00,0x36,0x40 }}, - {16, 0x8ee0, 0, {0x0f,0x10,0x02,0x25,0x00,0xb1,0x00,0x2e,0x60,0x0f,0x10,0x12,0x24,0x02,0xb9,0xa0 }}, - {16, 0x8ef0, 0, {0xa4,0x40,0x2e,0x91,0x03,0xe6,0x00,0xa9,0x00,0x22,0x40,0x0b,0x19,0x80,0x64,0x04 }}, - {16, 0x8f00, 0, {0xd9,0x81,0x2e,0x40,0x4c,0x90,0x03,0xe8,0x14,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8f10, 0, {0x68,0x01,0xa4,0x0a,0xe9,0x00,0xbe,0x48,0x0f,0x98,0x0b,0xe4,0x00,0xf9,0xc4,0x36 }}, - {16, 0x8f20, 0, {0x70,0x1f,0x92,0x03,0xe6,0x90,0xc1,0x90,0x3a,0x40,0x8d,0x88,0x03,0xe4,0x00,0xf9 }}, - {16, 0x8f30, 0, {0x90,0x3e,0x40,0x0b,0x98,0x03,0xe6,0x40,0xe9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xd2 }}, - {16, 0x8f40, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0xa1,0x02,0xd8,0x20,0xb2,0x10 }}, - {16, 0x8f50, 0, {0x0c,0x80,0x83,0x21,0x40,0xc8,0x58,0xb2,0x10,0x4c,0x80,0x0b,0x20,0x00,0xf8,0x42 }}, - {16, 0x8f60, 0, {0x32,0x00,0x0f,0x80,0x03,0xe0,0x02,0xd8,0x00,0x72,0x00,0x1c,0x80,0x00,0x20,0x00 }}, - {16, 0x8f70, 0, {0xf8,0x04,0x3e,0x00,0x0f,0x80,0x03,0x02,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8f80, 0, {0x28,0x05,0x38,0x04,0xce,0x41,0x23,0x80,0x08,0xe0,0x02,0x39,0x10,0xae,0x40,0x22 }}, - {16, 0x8f90, 0, {0x80,0x08,0xe0,0x02,0x1a,0x00,0xba,0x00,0x2b,0xad,0x03,0x80,0x02,0xe8,0x00,0xca }}, - {16, 0x8fa0, 0, {0x00,0x2a,0x80,0x0a,0xe0,0x02,0x18,0x00,0xba,0x00,0x1a,0x80,0x0b,0xa0,0x03,0x4a }}, - {16, 0x8fb0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x05,0x6c,0x12,0x89,0x00,0xa0,0xe0 }}, - {16, 0x8fc0, 0, {0x08,0x38,0x02,0x0d,0x88,0x83,0x00,0x04,0xe0,0x08,0x38,0x32,0x0e,0x25,0x31,0x01 }}, - {16, 0x8fd0, 0, {0x24,0xe0,0x8b,0x38,0x02,0xe4,0x01,0x83,0x00,0x20,0xc0,0x08,0x30,0x02,0x8c,0x00 }}, - {16, 0x8fe0, 0, {0xb3,0x00,0x2e,0xc0,0x0b,0x30,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x8ff0, 0, {0xa0,0x01,0x14,0x20,0x86,0x20,0x29,0xb0,0x08,0xf0,0x82,0x3e,0x04,0xa7,0x00,0x21 }}, - {16, 0x9000, 0, {0x70,0x88,0x70,0x92,0x1c,0x20,0xbd,0x00,0x69,0xc0,0x0b,0x76,0x02,0xd4,0x80,0x8f }}, - {16, 0x9010, 0, {0x21,0x29,0xe0,0x0a,0x60,0x86,0x98,0x01,0xb7,0x00,0x2d,0xc8,0x0b,0x3b,0x02,0x60 }}, - {16, 0x9020, 0, {0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3e,0x00,0xc7,0xa0,0xb0,0xe0 }}, - {16, 0x9030, 0, {0x2c,0x78,0x0b,0x1a,0x00,0xc3,0x80,0x37,0xe0,0x28,0x78,0x03,0x1a,0x08,0xf5,0x90 }}, - {16, 0x9040, 0, {0x35,0xe0,0x0f,0x7c,0x12,0xd6,0x82,0xc7,0x90,0x21,0xe4,0x08,0x78,0x03,0x9e,0x00 }}, - {16, 0x9050, 0, {0xf5,0x80,0x3d,0xf1,0x0f,0x78,0x03,0x22,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9060, 0, {0x08,0x19,0xa4,0x00,0xee,0x80,0x36,0xc1,0x4f,0xd0,0x03,0xc8,0x00,0xfb,0x00,0x3e }}, - {16, 0x9070, 0, {0x51,0x0f,0xb0,0x03,0xe4,0x08,0xf1,0x60,0x3e,0xc0,0x0f,0xb0,0x03,0xc5,0x00,0xeb }}, - {16, 0x9080, 0, {0x10,0x3e,0xc0,0x0f,0xb0,0x09,0x6c,0x00,0xfb,0x00,0x3a,0xc0,0x0f,0xb0,0x03,0xc2 }}, - {16, 0x9090, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfe,0x00,0xfd,0x88,0x33,0x60 }}, - {16, 0x90a0, 0, {0x0f,0xf9,0x03,0xce,0x40,0xd7,0x84,0x37,0x70,0x0c,0xd8,0x23,0x36,0x00,0xc5,0x88 }}, - {16, 0x90b0, 0, {0x33,0xe0,0x4f,0xf8,0x13,0xf7,0x28,0xdf,0x80,0x37,0xe2,0x0c,0x58,0x03,0x3e,0x00 }}, - {16, 0x90c0, 0, {0xff,0x90,0x3f,0xe0,0x0c,0xf8,0x03,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x90d0, 0, {0xa9,0x11,0x9c,0x08,0xf6,0x00,0xa1,0x00,0x0b,0x63,0x02,0xd6,0x30,0x85,0x41,0x31 }}, - {16, 0x90e0, 0, {0xc8,0x08,0x50,0x23,0x1c,0x00,0xd5,0x20,0xb1,0x80,0x0f,0x70,0x03,0xb4,0x00,0xc7 }}, - {16, 0x90f0, 0, {0x00,0x21,0xc0,0x0f,0x40,0xa3,0x58,0x40,0xb7,0x00,0x3f,0xc4,0x0a,0xf0,0x02,0x2a }}, - {16, 0x9100, 0, {0x06,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x40,0xb7,0x10,0x21,0xd2 }}, - {16, 0x9110, 0, {0x0b,0x70,0x02,0xdc,0x42,0x86,0x00,0x25,0x61,0x08,0x51,0x02,0x50,0x00,0x95,0x00 }}, - {16, 0x9120, 0, {0x25,0xc0,0x09,0x70,0x82,0xd4,0x00,0x87,0x00,0x24,0xc0,0x08,0x50,0x02,0x5c,0x00 }}, - {16, 0x9130, 0, {0x95,0x04,0x2d,0xc0,0x08,0x70,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9140, 0, {0x20,0x14,0xcc,0x08,0xb2,0xd0,0x20,0xe0,0x4b,0x08,0x02,0xc4,0x00,0x80,0x80,0x20 }}, - {16, 0x9150, 0, {0xf0,0x08,0x1a,0x02,0x85,0x48,0x81,0x10,0x20,0x40,0x0a,0x30,0x02,0xc6,0x10,0x93 }}, - {16, 0x9160, 0, {0x00,0x20,0xc0,0x0a,0x1c,0x02,0x0d,0x40,0xb3,0x00,0x68,0xc4,0x0a,0xb0,0x02,0x09 }}, - {16, 0x9170, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x01,0xfe,0x00,0x32,0xf0 }}, - {16, 0x9180, 0, {0x0f,0x88,0x03,0xe6,0x00,0xc8,0xc8,0x36,0xf6,0x28,0xa6,0x0a,0x6d,0x00,0x9d,0x00 }}, - {16, 0x9190, 0, {0x32,0x00,0x0b,0xb0,0x03,0xf6,0x03,0xc7,0x00,0x37,0xc0,0x08,0x9c,0x0a,0x6e,0x00 }}, - {16, 0x91a0, 0, {0xbb,0x00,0x2f,0xc0,0x0c,0xf0,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x91b0, 0, {0x80,0x00,0xe4,0x01,0xeb,0x40,0x3e,0x80,0x4f,0xc1,0x03,0xe4,0x00,0xb8,0x08,0x3a }}, - {16, 0x91c0, 0, {0x40,0x8f,0xa4,0x13,0x6c,0x20,0xf9,0x00,0x3e,0x70,0x0f,0xb0,0x03,0xa4,0x40,0xeb }}, - {16, 0x91d0, 0, {0x00,0x3e,0xc0,0x0f,0x92,0x23,0xe8,0x00,0xf9,0x80,0x3e,0xc0,0x0f,0xb0,0x63,0xe0 }}, - {16, 0x91e0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x08,0xce,0x08,0x33,0xc0 }}, - {16, 0x91f0, 0, {0x0f,0xda,0x03,0x30,0x00,0xe4,0x04,0x35,0xc0,0x0d,0xa0,0x03,0x28,0x00,0xc5,0x00 }}, - {16, 0x9200, 0, {0x33,0x00,0x0b,0xfa,0x03,0xf4,0x03,0xcb,0x00,0x31,0xc0,0x0c,0xd4,0x03,0x14,0x20 }}, - {16, 0x9210, 0, {0xcd,0x80,0x23,0xc1,0x0c,0xf0,0x02,0x08,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9220, 0, {0x81,0x04,0x44,0x10,0xcb,0xd0,0x22,0xc0,0x0b,0x94,0x02,0x22,0x84,0xb8,0xc6,0x02 }}, - {16, 0x9230, 0, {0x40,0x08,0x28,0x02,0xa5,0x80,0x89,0x00,0x22,0x60,0x0b,0xb8,0x02,0x64,0x00,0x8b }}, - {16, 0x9240, 0, {0x00,0x2a,0xc0,0xc8,0x00,0x03,0x66,0x00,0x81,0x00,0x00,0xc0,0x0d,0xb0,0x0a,0xa8 }}, - {16, 0x9250, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2c,0x00,0x13,0x00,0x22,0x40 }}, - {16, 0x9260, 0, {0x8b,0x24,0x02,0x2a,0x00,0xbb,0x82,0x22,0x40,0x00,0xac,0x02,0x84,0x00,0x89,0x00 }}, - {16, 0x9270, 0, {0x22,0x22,0x0b,0xb0,0x02,0xc4,0x00,0x9b,0x00,0x2a,0xc0,0x08,0xb0,0x02,0x2e,0x00 }}, - {16, 0x9280, 0, {0x8b,0x10,0x2a,0xc0,0x08,0xb0,0x02,0xa0,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9290, 0, {0x08,0x04,0x0c,0x10,0x83,0x00,0x20,0x01,0x0b,0x20,0x02,0x00,0x80,0xb1,0x00,0x20 }}, - {16, 0x92a0, 0, {0xc1,0x08,0x20,0x02,0x88,0x01,0x81,0x00,0xa0,0x00,0x0b,0x30,0x02,0x44,0x01,0x9b }}, - {16, 0x92b0, 0, {0x00,0x28,0xc0,0x08,0xb0,0x02,0x48,0x06,0x89,0x00,0x2a,0xc0,0x09,0x30,0x02,0x82 }}, - {16, 0x92c0, 0, {0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x6c,0x00,0xc3,0x00,0xb2,0xc0 }}, - {16, 0x92d0, 0, {0x0f,0xb0,0x03,0x28,0x20,0xfa,0x00,0xb1,0x40,0x0d,0xa0,0x07,0xa0,0x00,0xcd,0x00 }}, - {16, 0x92e0, 0, {0x22,0x00,0x0f,0xb0,0x03,0xf4,0x00,0x9f,0x00,0x3b,0xc0,0x2c,0xb0,0x0b,0x24,0x00 }}, - {16, 0x92f0, 0, {0xc9,0x00,0xba,0xc0,0x0c,0xb0,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9300, 0, {0xa0,0x1d,0xfc,0x06,0xff,0x02,0xaf,0xc0,0x0f,0xc0,0x03,0xf0,0x10,0xfc,0x00,0x3f }}, - {16, 0x9310, 0, {0xc0,0x9f,0xe0,0x13,0xf0,0x00,0xfd,0x04,0x3f,0x40,0x4f,0xf0,0x03,0x74,0x00,0xef }}, - {16, 0x9320, 0, {0x00,0x3f,0xc0,0x8f,0xe0,0x02,0xb4,0x01,0xfd,0x04,0x37,0xc0,0x0f,0xf0,0x43,0x68 }}, - {16, 0x9330, 0, {0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x00,0xc7,0x20,0xb3,0xc8 }}, - {16, 0x9340, 0, {0x1c,0xf1,0x03,0x7c,0x20,0xcf,0x0a,0x3f,0xd0,0x0d,0xf0,0x03,0x7c,0x80,0x8f,0x32 }}, - {16, 0x9350, 0, {0x33,0xc4,0x0f,0xf1,0x83,0x3c,0xe0,0xcf,0x10,0x33,0xc4,0x0d,0xf2,0x83,0x3c,0xe2 }}, - {16, 0x9360, 0, {0xc7,0x80,0x17,0xcc,0x4c,0xf3,0x83,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9370, 0, {0x80,0x10,0xe3,0x40,0x88,0x68,0x22,0x30,0x08,0x06,0x02,0x01,0xa1,0x88,0xc4,0x0e }}, - {16, 0x9380, 0, {0x14,0x08,0x87,0x80,0x01,0xc0,0x28,0x50,0x02,0x04,0x8b,0x86,0x02,0xa1,0x98,0x88 }}, - {16, 0x9390, 0, {0x41,0x2a,0x04,0x0a,0x84,0x82,0xbd,0x80,0x8b,0x08,0x2b,0xc4,0x88,0xf4,0x03,0x60 }}, - {16, 0x93a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcc,0x08,0x82,0x40,0x20,0x10 }}, - {16, 0x93b0, 0, {0x08,0x21,0x12,0x44,0x04,0x82,0x04,0x2c,0x08,0x89,0x90,0x02,0x44,0x21,0x8b,0x00 }}, - {16, 0x93c0, 0, {0x24,0x88,0x8b,0xa0,0x00,0x40,0x84,0x89,0x30,0x22,0x48,0x88,0xb0,0x02,0xcc,0x08 }}, - {16, 0x93d0, 0, {0x88,0x20,0xa4,0xc8,0x00,0x32,0x0a,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x93e0, 0, {0xc0,0x15,0xa0,0x00,0x89,0x00,0x22,0xc1,0x88,0x90,0x62,0x28,0x08,0x89,0x08,0x2e }}, - {16, 0x93f0, 0, {0xc0,0x08,0xa0,0x02,0x28,0x08,0xa8,0x00,0x26,0x42,0x0b,0x90,0x02,0xcc,0x50,0x8a }}, - {16, 0x9400, 0, {0x22,0x2a,0x86,0x0a,0x80,0x02,0xec,0x00,0x88,0x84,0x2a,0xc1,0x08,0xb0,0x26,0x30 }}, - {16, 0x9410, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xf0,0x02,0xcf,0x00,0x33,0xc0 }}, - {16, 0x9420, 0, {0x48,0xf8,0x43,0x79,0x00,0x8d,0xc0,0x3f,0x30,0x8d,0x60,0x83,0x78,0x60,0xc4,0x58 }}, - {16, 0x9430, 0, {0x37,0x20,0x0f,0x58,0x13,0x7b,0x02,0xcc,0xc4,0x31,0x20,0x0c,0x44,0x03,0xec,0x02 }}, - {16, 0x9440, 0, {0x8b,0x80,0x36,0xc0,0x24,0xb0,0x12,0x10,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9450, 0, {0xe0,0x01,0x9c,0x00,0xf4,0x10,0x3d,0x00,0x6f,0xc9,0x13,0xd4,0x12,0xfe,0x90,0x3f }}, - {16, 0x9460, 0, {0xf0,0x0f,0xda,0x23,0xf4,0x14,0xff,0x02,0x3b,0xf0,0x0f,0xea,0x23,0xb6,0x00,0xff }}, - {16, 0x9470, 0, {0x82,0x3f,0xe1,0x8f,0xf4,0x03,0xbc,0x00,0xff,0x00,0x3f,0xc0,0xaf,0x70,0x03,0xf8 }}, - {16, 0x9480, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa0,0x00,0xca,0x00,0x32,0x08 }}, - {16, 0x9490, 0, {0x1c,0xa0,0x03,0xa5,0x20,0xcb,0x40,0xba,0x10,0x1f,0xb0,0x03,0xac,0x00,0xeb,0x00 }}, - {16, 0x94a0, 0, {0x72,0x90,0x0c,0xb4,0x03,0x29,0x04,0xc9,0x52,0x32,0x50,0x0c,0xb4,0x03,0x0c,0x00 }}, - {16, 0x94b0, 0, {0xf8,0x40,0x32,0xc1,0x0e,0xb0,0x0b,0x50,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x94c0, 0, {0xc8,0x05,0x2d,0x80,0x89,0x80,0x22,0xd9,0x08,0x90,0x22,0x2a,0x00,0x88,0x54,0x22 }}, - {16, 0x94d0, 0, {0xc0,0x8b,0x80,0x22,0x20,0x19,0xc8,0x00,0x22,0x40,0x8d,0x80,0x1a,0x24,0x10,0xd2 }}, - {16, 0x94e0, 0, {0x44,0x22,0x81,0x0d,0x80,0x03,0x7c,0x00,0xb0,0x00,0x37,0xc0,0x88,0xf0,0x02,0x32 }}, - {16, 0x94f0, 0, {0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x4e,0x00,0x81,0x00,0xa0,0xf0 }}, - {16, 0x9500, 0, {0x08,0x90,0x02,0x89,0x02,0x80,0x00,0x22,0xc0,0x0b,0x00,0x22,0xa0,0x00,0xb0,0x00 }}, - {16, 0x9510, 0, {0x20,0x40,0x08,0x00,0x02,0x04,0x00,0x82,0x60,0x20,0x80,0x08,0x00,0x02,0x0c,0x08 }}, - {16, 0x9520, 0, {0xb2,0x00,0x22,0xc0,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9530, 0, {0x20,0x01,0x03,0x10,0x8e,0x90,0x23,0x24,0x08,0x6b,0x02,0x16,0x60,0x8f,0x80,0x21 }}, - {16, 0x9540, 0, {0x28,0x0b,0xf9,0x06,0x1e,0x40,0x8f,0x80,0x23,0xa4,0x49,0x79,0x02,0x3a,0x40,0x9d }}, - {16, 0x9550, 0, {0x90,0x23,0x64,0x09,0xf8,0x02,0x5e,0x40,0xbe,0x90,0x24,0xe4,0x28,0x79,0x02,0x08 }}, - {16, 0x9560, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x42,0xc0,0x09,0x30,0x00 }}, - {16, 0x9570, 0, {0x28,0x02,0x03,0x84,0x00,0x8a,0x20,0x30,0xc4,0x8b,0x11,0x03,0x84,0x50,0xb3,0x00 }}, - {16, 0x9580, 0, {0x20,0xc0,0x0c,0xa4,0x22,0x04,0x00,0xcb,0x40,0x30,0xc5,0x0c,0x30,0x03,0x0e,0x40 }}, - {16, 0x9590, 0, {0xf3,0x10,0x30,0xc4,0x0c,0xb0,0x03,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x95a0, 0, {0x40,0x1d,0xb0,0x04,0xfb,0x04,0x3d,0xc0,0x0f,0xf2,0x43,0xf8,0x04,0xfd,0x01,0x3f }}, - {16, 0x95b0, 0, {0x0c,0x0f,0x61,0x03,0xf8,0x48,0xf4,0x00,0x3d,0x01,0x0f,0xd0,0x03,0xc8,0x00,0xfc }}, - {16, 0x95c0, 0, {0x04,0xbd,0x04,0x0b,0x48,0x03,0xfc,0x18,0xff,0x14,0x3f,0xd5,0x0d,0xf0,0x03,0x90 }}, - {16, 0x95d0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xe0,0x00,0xf9,0x01,0x32,0xc0 }}, - {16, 0x95e0, 0, {0x8e,0x90,0x03,0x28,0x02,0xd1,0x00,0x32,0xc0,0x0d,0xa8,0x0b,0x08,0x00,0xe8,0x00 }}, - {16, 0x95f0, 0, {0x2e,0x40,0x0c,0x98,0x0b,0x2e,0x02,0xca,0x00,0xb2,0xa0,0x6c,0x80,0x23,0x2d,0x80 }}, - {16, 0x9600, 0, {0xca,0x80,0x32,0xd0,0x0c,0xba,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9610, 0, {0x48,0x11,0x9c,0x00,0xb6,0x00,0xa3,0x00,0x08,0x60,0x02,0x04,0x00,0x86,0x04,0x29 }}, - {16, 0x9620, 0, {0x00,0x08,0x50,0x42,0x14,0x04,0xa7,0x00,0x0d,0x80,0x4a,0x60,0x02,0x00,0x00,0x81 }}, - {16, 0x9630, 0, {0x00,0x21,0x40,0x08,0x70,0x02,0x9d,0x42,0x86,0x01,0x20,0xc0,0x08,0x32,0x82,0x12 }}, - {16, 0x9640, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x92,0x00,0xbc,0x80,0x63,0x20 }}, - {16, 0x9650, 0, {0x82,0x08,0x02,0x52,0x00,0x84,0xc2,0x23,0x20,0x88,0x0c,0x02,0x33,0x00,0x84,0x80 }}, - {16, 0x9660, 0, {0x2f,0x21,0x89,0x4c,0x02,0x12,0x14,0x94,0xc5,0x64,0x21,0x08,0x4c,0x02,0x0e,0x80 }}, - {16, 0x9670, 0, {0x97,0x82,0xa1,0xec,0x08,0x79,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9680, 0, {0x48,0x14,0xcd,0x44,0xb3,0x00,0x20,0xc0,0x08,0x30,0x02,0x4d,0x80,0x03,0x88,0x28 }}, - {16, 0x9690, 0, {0xc0,0x08,0x3c,0x06,0x0f,0x00,0xa3,0x43,0x2c,0xc2,0x1b,0x38,0x02,0x0f,0x00,0x9b }}, - {16, 0x96a0, 0, {0x88,0x64,0xd0,0x08,0xb8,0x02,0x8c,0x10,0x93,0x00,0x20,0xc0,0x08,0x30,0x0a,0x12 }}, - {16, 0x96b0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xaa,0x00,0xfa,0x05,0x32,0x80 }}, - {16, 0x96c0, 0, {0x8e,0xa0,0x0b,0x69,0x00,0xca,0x40,0x32,0xa0,0x3c,0xa8,0x03,0x2a,0x00,0xea,0x26 }}, - {16, 0x96d0, 0, {0x3e,0xb0,0x0d,0xa1,0x63,0x28,0x20,0xca,0x40,0x36,0xa0,0x0c,0xe0,0x13,0x28,0x09 }}, - {16, 0x96e0, 0, {0xde,0x00,0x32,0x80,0x2c,0xa0,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x96f0, 0, {0x48,0x00,0xf0,0x20,0xf4,0x00,0x3f,0x00,0x0f,0x40,0x23,0xb0,0x00,0xec,0x00,0x3f }}, - {16, 0x9700, 0, {0x06,0x1e,0xc2,0x13,0xf0,0x88,0xfc,0x20,0x3f,0x04,0x8e,0xc0,0x03,0xf0,0x80,0xec }}, - {16, 0x9710, 0, {0x40,0x3b,0x0c,0x0f,0xc0,0xa3,0xe0,0x00,0xe8,0x00,0x3e,0x00,0x4f,0x80,0x03,0xd2 }}, - {16, 0x9720, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x00,0xf9,0x00,0x32,0x40 }}, - {16, 0x9730, 0, {0x0c,0x90,0x03,0x24,0x00,0xc9,0x80,0x32,0x40,0x0f,0x90,0x53,0xe4,0x10,0xc9,0x00 }}, - {16, 0x9740, 0, {0x32,0x40,0x0d,0x90,0x03,0xe4,0x00,0xf9,0x00,0x36,0x40,0x8f,0x90,0x03,0x24,0x10 }}, - {16, 0x9750, 0, {0xc9,0x01,0x3c,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9760, 0, {0x80,0x04,0x47,0x44,0x89,0x00,0x20,0x40,0x08,0x90,0x02,0x25,0x0a,0x81,0x10,0x22 }}, - {16, 0x9770, 0, {0x40,0x48,0x90,0x03,0xc4,0x00,0x89,0x00,0x76,0x40,0x28,0x90,0x02,0xe4,0x10,0xb9 }}, - {16, 0x9780, 0, {0x40,0xb2,0x40,0x0b,0x90,0x03,0x64,0x00,0x89,0x00,0x2e,0x41,0x08,0x90,0x42,0xe0 }}, - {16, 0x9790, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x24,0x02,0xbd,0x00,0x23,0x48 }}, - {16, 0x97a0, 0, {0x08,0xd0,0x06,0x1d,0x04,0x8d,0x00,0x29,0xc0,0x4a,0xd0,0x22,0xf4,0x00,0x85,0x00 }}, - {16, 0x97b0, 0, {0x61,0x40,0x18,0xd0,0x12,0xfc,0x00,0xbd,0x40,0xa3,0x40,0x4b,0xf0,0x02,0x04,0x01 }}, - {16, 0x97c0, 0, {0x8b,0x00,0x2e,0x40,0x08,0x90,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x97d0, 0, {0x08,0x04,0x36,0x80,0x85,0x20,0xa3,0x48,0x08,0x52,0x0a,0x14,0x81,0x85,0x20,0x29 }}, - {16, 0x97e0, 0, {0x48,0x08,0x52,0x02,0xb4,0x80,0x85,0x20,0x25,0x48,0x88,0x52,0x02,0xd4,0x80,0xb5 }}, - {16, 0x97f0, 0, {0x20,0x21,0x48,0x0b,0x52,0x02,0x44,0xa2,0x81,0x00,0x2c,0x4a,0x08,0x12,0x82,0xc2 }}, - {16, 0x9800, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xf8,0x51,0x22,0x00 }}, - {16, 0x9810, 0, {0x2c,0x85,0x02,0x21,0x48,0xc8,0x00,0xba,0x14,0x0f,0x85,0x12,0xe1,0x42,0xc8,0x50 }}, - {16, 0x9820, 0, {0x22,0x00,0x0c,0x00,0x03,0xe0,0x00,0xf8,0x50,0x32,0x00,0x07,0x45,0x03,0x20,0x80 }}, - {16, 0x9830, 0, {0xc0,0x01,0x3e,0x08,0x2c,0x82,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9840, 0, {0x98,0x0d,0xe4,0x40,0xf1,0x10,0x3e,0x44,0x07,0x91,0x43,0xe4,0x58,0xf9,0x11,0x34 }}, - {16, 0x9850, 0, {0x44,0x4f,0x91,0x02,0xe4,0x50,0xf9,0x10,0x3c,0x4f,0x0f,0x93,0x83,0xe4,0xf0,0xf9 }}, - {16, 0x9860, 0, {0x11,0x3a,0x4f,0x0f,0x91,0x03,0xe4,0xa0,0xfd,0x28,0x3e,0x4a,0x0f,0x92,0x83,0xe6 }}, - {16, 0x9870, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0xa0,0xcd,0xa0,0xb3,0x68 }}, - {16, 0x9880, 0, {0x8c,0x9a,0x03,0x36,0x80,0xc5,0xa0,0x22,0x60,0x0c,0x9a,0x23,0x26,0x04,0xf9,0xa0 }}, - {16, 0x9890, 0, {0x32,0x66,0x0c,0x9a,0x83,0x06,0x20,0xc5,0xa0,0x22,0x60,0x0c,0x9b,0x03,0x26,0x48 }}, - {16, 0x98a0, 0, {0xc9,0x00,0x3e,0x78,0x0c,0x9a,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x98b0, 0, {0x38,0x00,0xe1,0x00,0x88,0x44,0x22,0x95,0x08,0x85,0x12,0xa1,0x42,0x88,0x40,0x02 }}, - {16, 0x98c0, 0, {0x90,0x08,0x84,0x02,0x23,0xa0,0xba,0x40,0x22,0xa0,0x08,0x8e,0x92,0xa3,0xa0,0xa8 }}, - {16, 0x98d0, 0, {0x40,0x2a,0x10,0x08,0xae,0x02,0x23,0x40,0x88,0x00,0x2e,0x38,0x08,0x84,0x12,0x0e }}, - {16, 0x98e0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x15,0xc4,0x00,0x8b,0x12,0x22,0x40 }}, - {16, 0x98f0, 0, {0x08,0x90,0x02,0x44,0x00,0x81,0x40,0xa0,0x50,0x08,0x11,0x0a,0x05,0x00,0xb1,0x10 }}, - {16, 0x9900, 0, {0xa0,0x48,0x08,0x90,0x02,0x04,0x00,0x81,0x40,0x20,0x50,0x28,0x11,0x02,0x44,0x82 }}, - {16, 0x9910, 0, {0x81,0x00,0x2c,0x50,0x08,0x11,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9920, 0, {0x18,0x15,0xa4,0x02,0x89,0x40,0x22,0x40,0x08,0x94,0x12,0xa5,0x00,0x89,0x28,0x22 }}, - {16, 0x9930, 0, {0x49,0x08,0x94,0x02,0x24,0x48,0xb9,0x14,0x22,0x40,0x08,0x94,0x02,0xa4,0x40,0xa1 }}, - {16, 0x9940, 0, {0x50,0x2a,0x50,0x08,0x91,0x42,0x64,0x00,0x89,0x40,0x2e,0x40,0x08,0x10,0x02,0x06 }}, - {16, 0x9950, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x00,0xc9,0x00,0x30,0x70 }}, - {16, 0x9960, 0, {0x2c,0x10,0x0b,0x66,0x00,0xc9,0x40,0x32,0x50,0x0c,0x90,0x03,0x26,0x20,0xf9,0xc0 }}, - {16, 0x9970, 0, {0x32,0x70,0x0c,0x90,0x03,0x26,0x20,0xc9,0x00,0x32,0x40,0x0c,0x9c,0x03,0x64,0x00 }}, - {16, 0x9980, 0, {0xc9,0x41,0x3e,0x40,0x2c,0x90,0x0b,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9990, 0, {0x28,0x01,0xa4,0x00,0xf9,0x04,0x3e,0x48,0x0f,0x90,0x03,0xe4,0x88,0xf9,0x00,0x34 }}, - {16, 0x99a0, 0, {0x41,0x2f,0x9c,0x03,0xe4,0x10,0xf9,0x00,0x3e,0x44,0x2f,0x99,0x03,0xe4,0x10,0xf9 }}, - {16, 0x99b0, 0, {0x00,0x3e,0x50,0x0f,0x10,0x4b,0xa4,0x10,0xf9,0x20,0x3c,0x40,0x0f,0x90,0x03,0x4a }}, - {16, 0x99c0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x00,0xc8,0x00,0x3e,0x10 }}, - {16, 0x99d0, 0, {0x2c,0x80,0x03,0x20,0x02,0xc0,0x40,0x32,0x00,0x1c,0x04,0x0f,0x21,0x00,0xc0,0x04 }}, - {16, 0x99e0, 0, {0x38,0x00,0x0f,0x80,0x03,0x21,0x08,0xc8,0x60,0x30,0x10,0x0f,0x80,0x02,0x20,0x00 }}, - {16, 0x99f0, 0, {0xf8,0x00,0x32,0x00,0x0c,0x80,0x03,0xca,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9a00, 0, {0x28,0x05,0x1a,0x20,0x82,0x04,0x2f,0x80,0x08,0xa0,0x02,0x38,0x00,0x8e,0x80,0x22 }}, - {16, 0x9a10, 0, {0x80,0x08,0xe0,0x02,0x28,0x00,0x8a,0x00,0x22,0x81,0x0b,0x20,0x02,0x28,0x00,0xde }}, - {16, 0x9a20, 0, {0xe4,0x36,0x80,0x0b,0xa0,0x42,0x28,0x00,0xba,0x04,0x22,0x80,0x08,0xa0,0x02,0xca }}, - {16, 0x9a30, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x01,0x2c,0x80 }}, - {16, 0x9a40, 0, {0x08,0x30,0x02,0x2e,0x60,0x82,0x90,0xa0,0xc0,0x48,0x30,0x02,0x0c,0x02,0x83,0x00 }}, - {16, 0x9a50, 0, {0x28,0xc0,0x0b,0x30,0x0a,0x2c,0x00,0x83,0xc2,0x20,0xc0,0x0b,0x30,0x2a,0x2c,0x00 }}, - {16, 0x9a60, 0, {0xb3,0x00,0xa0,0xc0,0x08,0x30,0x02,0xca,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9a70, 0, {0xa0,0x01,0x3c,0x00,0x87,0x01,0x2d,0xc2,0x08,0xf3,0x12,0x3c,0x00,0x8f,0x01,0x21 }}, - {16, 0x9a80, 0, {0xc8,0x68,0x72,0x22,0x1e,0x04,0x87,0x20,0x21,0xc4,0x0b,0x70,0x02,0x3c,0x84,0x9f }}, - {16, 0x9a90, 0, {0x00,0x25,0xc4,0x4b,0x70,0x02,0x1c,0x04,0xb7,0x81,0x21,0xc8,0x08,0x72,0x02,0xe8 }}, - {16, 0x9aa0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x00,0x1e,0x00,0xc7,0x81,0x3c,0xa0 }}, - {16, 0x9ab0, 0, {0x4c,0x7a,0x0b,0x1a,0x00,0xc6,0x80,0x30,0xe0,0x08,0xf8,0x82,0x0e,0x40,0xcf,0xf0 }}, - {16, 0x9ac0, 0, {0x39,0xe8,0x0f,0x3a,0x03,0x1e,0x20,0xc7,0x80,0x31,0xe3,0x0f,0x38,0x23,0x1f,0x08 }}, - {16, 0x9ad0, 0, {0xff,0xc0,0x33,0xf2,0x0c,0x7e,0x03,0xea,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9ae0, 0, {0x08,0x15,0x88,0x0a,0x7b,0x00,0x3e,0xc1,0x0b,0x34,0x23,0xc8,0x10,0xfb,0x02,0x3e }}, - {16, 0x9af0, 0, {0xca,0x0f,0xb7,0x43,0xec,0x80,0xfb,0x00,0x2e,0xc2,0x0b,0xb4,0x83,0xed,0xd0,0xfa }}, - {16, 0x9b00, 0, {0x00,0x3e,0xd9,0x0f,0xb3,0x83,0xec,0x80,0xbb,0x20,0x3e,0xd8,0x2f,0xb4,0x03,0xc2 }}, - {16, 0x9b10, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xfe,0x00,0xf5,0x91,0x31,0xa0 }}, - {16, 0x9b20, 0, {0x0c,0xfc,0x03,0xfe,0x00,0xc4,0x81,0x31,0xee,0x8d,0xf8,0x0a,0x3e,0x30,0xcf,0x84 }}, - {16, 0x9b30, 0, {0x33,0xe0,0x2c,0xf8,0x83,0xfe,0x10,0xfe,0x80,0x33,0xe0,0x0c,0xf9,0x19,0x3f,0x48 }}, - {16, 0x9b40, 0, {0xcf,0xc0,0x33,0xe0,0x04,0xfc,0x03,0xc0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9b50, 0, {0xa8,0x11,0x9c,0x08,0xb7,0xa1,0x21,0xc8,0x08,0x71,0x02,0xf0,0xa0,0x85,0x20,0x21 }}, - {16, 0x9b60, 0, {0xce,0x08,0x70,0x02,0x3c,0x80,0x8f,0x00,0x2b,0xc5,0x08,0x71,0x02,0xdc,0x10,0xb4 }}, - {16, 0x9b70, 0, {0x00,0x21,0xc1,0x0a,0xf3,0x82,0x0c,0x00,0x87,0x01,0x29,0xc0,0x08,0x71,0x02,0x6a }}, - {16, 0x9b80, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9d,0x00,0xbd,0x21,0x27,0x82 }}, - {16, 0x9b90, 0, {0x00,0x70,0x02,0xfc,0x04,0x8c,0x00,0xa7,0xcc,0xa8,0x70,0x02,0x3c,0x08,0xaf,0x00 }}, - {16, 0x9ba0, 0, {0x21,0xc0,0x08,0x70,0x02,0xdc,0x00,0xb7,0x00,0x21,0xc4,0x08,0x70,0x16,0x1c,0x0a }}, - {16, 0x9bb0, 0, {0x8f,0x00,0x21,0xc0,0x08,0x70,0x02,0xc0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9bc0, 0, {0x20,0x10,0xc8,0x00,0xbb,0x44,0x24,0xe2,0x08,0xb1,0x02,0xc2,0x80,0x01,0x80,0x24 }}, - {16, 0x9bd0, 0, {0xd0,0x88,0x30,0x02,0x0f,0x52,0x83,0x91,0x28,0xe4,0x88,0x3d,0x02,0xce,0xd0,0xb0 }}, - {16, 0x9be0, 0, {0xb2,0xa2,0xc0,0x0a,0x34,0x12,0x0c,0x02,0x83,0x00,0x28,0xc0,0x08,0x30,0x02,0x48 }}, - {16, 0x9bf0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xac,0x00,0xfb,0x01,0xe4,0x40 }}, - {16, 0x9c00, 0, {0x2c,0xf0,0x43,0xe5,0x00,0x8a,0x88,0x37,0xe0,0x00,0xfa,0x02,0x3d,0x00,0xef,0x00 }}, - {16, 0x9c10, 0, {0x33,0xd1,0x0c,0xf4,0x03,0xfd,0x00,0xf9,0x40,0x33,0xe8,0x0c,0xfc,0x01,0x3c,0x04 }}, - {16, 0x9c20, 0, {0xcf,0x02,0x33,0xc0,0x2c,0xf0,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9c30, 0, {0x80,0x00,0xee,0x08,0xf9,0x10,0x3a,0xd0,0x0f,0xb0,0x93,0xec,0x00,0xfb,0x0b,0x3a }}, - {16, 0x9c40, 0, {0xc0,0x8e,0xb0,0x83,0xec,0x80,0xfb,0x09,0x7e,0xc8,0x0f,0xb2,0x13,0xec,0x00,0xf9 }}, - {16, 0x9c50, 0, {0x00,0x3e,0xc2,0x8f,0xb2,0x4b,0xcc,0x04,0xfb,0x00,0x3e,0xc0,0x0f,0xb0,0x03,0x60 }}, - {16, 0x9c60, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0xff,0x08,0x33,0xc0 }}, - {16, 0x9c70, 0, {0x1c,0xf0,0x03,0x70,0x40,0xc4,0xc0,0x33,0xc2,0x0f,0xf0,0x03,0x1c,0x10,0xc7,0x00 }}, - {16, 0x9c80, 0, {0x31,0xc0,0x0c,0x70,0x03,0x1c,0x00,0xc5,0x41,0x33,0xc0,0x0c,0xf0,0x23,0x2c,0x00 }}, - {16, 0x9c90, 0, {0xcf,0x00,0xb3,0xc0,0x6c,0xf0,0x03,0x80,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9ca0, 0, {0x81,0x04,0x6a,0x00,0xb9,0x90,0x32,0xf1,0x08,0xb0,0x02,0x0a,0x10,0xd9,0x00,0x22 }}, - {16, 0x9cb0, 0, {0xc1,0x0b,0xb0,0x02,0x2c,0x00,0xcb,0x06,0x22,0xc0,0x88,0xb0,0x12,0x2c,0x00,0x88 }}, - {16, 0x9cc0, 0, {0x80,0x22,0xc1,0x0d,0xb0,0x02,0x2c,0x00,0x83,0x00,0x22,0xc1,0x08,0xb0,0x46,0xe0 }}, - {16, 0x9cd0, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x2e,0x00,0xb9,0x00,0x22,0xf0 }}, - {16, 0x9ce0, 0, {0x08,0xb0,0x12,0x64,0x00,0x8a,0x00,0x22,0xc0,0x0b,0x30,0x42,0x2c,0x00,0x8b,0x00 }}, - {16, 0x9cf0, 0, {0x22,0xc0,0x08,0xb0,0x02,0x2c,0x00,0x8a,0x00,0x22,0xc0,0x88,0x30,0x0a,0x2c,0x00 }}, - {16, 0x9d00, 0, {0x8b,0x00,0x20,0xc0,0x08,0xb0,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9d10, 0, {0x08,0x04,0x0c,0x04,0xb1,0x02,0xe4,0xc1,0x08,0xb0,0x22,0x20,0x02,0x93,0x00,0x20 }}, - {16, 0x9d20, 0, {0xc0,0x0b,0x30,0x12,0x0c,0x02,0x83,0x02,0xa0,0xc0,0x28,0x30,0x0e,0x0c,0x02,0x80 }}, - {16, 0x9d30, 0, {0x00,0xa0,0xc0,0x49,0x30,0x0a,0x0c,0x02,0x8b,0x00,0x20,0xc0,0x08,0x30,0x02,0xc2 }}, - {16, 0x9d40, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xf9,0x24,0x32,0xc0 }}, - {16, 0x9d50, 0, {0x08,0xf0,0x03,0x64,0x00,0xc8,0x00,0xb3,0xc0,0x1f,0xf0,0x0b,0x3c,0x00,0x8f,0x00 }}, - {16, 0x9d60, 0, {0x33,0xc0,0x4c,0xf0,0x43,0x3c,0x08,0xc3,0x00,0x31,0xc0,0x0c,0xf0,0x03,0x3d,0x48 }}, - {16, 0x9d70, 0, {0xcf,0x00,0x31,0xc0,0x0c,0xf0,0x03,0x80,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9d80, 0, {0xa0,0x1d,0xf0,0x04,0xf9,0x41,0x3b,0xc0,0x4f,0xf0,0x03,0xf0,0x11,0xfd,0x00,0x3f }}, - {16, 0x9d90, 0, {0xc0,0x87,0x70,0x27,0xfc,0x00,0xef,0x06,0x3f,0xc0,0x0f,0xf0,0x02,0xfc,0x08,0xfc }}, - {16, 0x9da0, 0, {0x00,0x3f,0xc0,0x47,0xf0,0x43,0xfc,0x00,0x77,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xe8 }}, - {16, 0x9db0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xd2,0x00,0xc7,0x01,0x37,0x0c }}, - {16, 0x9dc0, 0, {0x0f,0xe8,0x23,0x10,0x4a,0xc4,0xc0,0x31,0x30,0x0c,0xc9,0x03,0x34,0x46,0xcf,0x10 }}, - {16, 0x9dd0, 0, {0x33,0xd0,0x0c,0xf4,0x03,0x3c,0x58,0xcf,0x00,0x33,0xc0,0x2d,0xf1,0x03,0x3e,0x02 }}, - {16, 0x9de0, 0, {0xcf,0x21,0x3f,0xe4,0x0f,0xf2,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9df0, 0, {0x80,0x10,0xe4,0x84,0x0b,0x40,0x22,0x4c,0x0b,0xa8,0x02,0x2c,0xc0,0x8b,0x20,0x22 }}, - {16, 0x9e00, 0, {0xc8,0x4a,0x32,0x02,0x24,0x80,0x83,0x20,0x20,0xc0,0x08,0x30,0x02,0x20,0x00,0x8b }}, - {16, 0x9e10, 0, {0x21,0x32,0xca,0x48,0x32,0x02,0x2c,0x30,0x8f,0x90,0x2e,0x88,0x0b,0xbd,0x12,0x20 }}, - {16, 0x9e20, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xce,0x20,0xa3,0x40,0xe0,0x48 }}, - {16, 0x9e30, 0, {0x4b,0x20,0x22,0x0c,0x02,0x82,0x00,0x2a,0x00,0x08,0x20,0x02,0x04,0x80,0x80,0x20 }}, - {16, 0x9e40, 0, {0x20,0xc8,0x08,0x02,0x02,0x0c,0x00,0x80,0x0c,0x60,0x00,0x08,0x20,0x12,0x2c,0x88 }}, - {16, 0x9e50, 0, {0x83,0x00,0x2c,0xe8,0x0b,0x30,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9e60, 0, {0xc0,0x15,0xae,0x00,0xab,0x01,0xa2,0x60,0x0b,0xa0,0x02,0x20,0x01,0x81,0x00,0x22 }}, - {16, 0x9e70, 0, {0xc0,0x0a,0x90,0x12,0x04,0x20,0x8a,0x08,0x22,0xc1,0x08,0xa0,0x02,0x28,0x00,0x88 }}, - {16, 0x9e80, 0, {0x00,0x24,0x44,0x08,0xa2,0x02,0xac,0x00,0x8b,0x04,0x2e,0x88,0x03,0xb0,0x02,0x70 }}, - {16, 0x9e90, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x15,0xec,0x00,0xea,0x90,0x32,0x28 }}, - {16, 0x9ea0, 0, {0x0f,0xb6,0x03,0x20,0x08,0xc9,0x04,0x3a,0xc0,0x4c,0x90,0x22,0x24,0x00,0xcb,0x40 }}, - {16, 0x9eb0, 0, {0x32,0xa8,0x0c,0xb2,0x03,0x2c,0x00,0xcb,0x80,0xb2,0xe0,0x0c,0xb0,0x0b,0x04,0x00 }}, - {16, 0x9ec0, 0, {0xcb,0x00,0x3e,0xc0,0x4f,0xb0,0x0b,0x50,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9ed0, 0, {0xe0,0x01,0xbc,0x00,0xdf,0x80,0x3b,0x81,0x0f,0xf0,0xc3,0xfc,0x00,0xbe,0x01,0x1f }}, - {16, 0x9ee0, 0, {0x00,0x0f,0xe0,0x23,0xf4,0x00,0xff,0x00,0x3f,0xb0,0x4f,0xf0,0x43,0xd4,0x02,0xff }}, - {16, 0x9ef0, 0, {0x91,0x3a,0xe0,0x4e,0xf0,0x03,0x7c,0x0c,0xff,0x00,0x2f,0x80,0x0f,0x30,0x03,0xb8 }}, - {16, 0x9f00, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xac,0x01,0xca,0x00,0x72,0x50 }}, - {16, 0x9f10, 0, {0x04,0xb4,0x03,0x2c,0x82,0xcb,0x00,0x32,0xe0,0x0c,0xb8,0x03,0x27,0x04,0xc8,0xc8 }}, - {16, 0x9f20, 0, {0xb2,0xa2,0x0c,0x88,0x03,0x2c,0x00,0xc1,0x00,0x3e,0x00,0x2c,0x30,0x1b,0x2c,0x04 }}, - {16, 0x9f30, 0, {0xfb,0x10,0x3e,0xc0,0x0f,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9f40, 0, {0xc8,0x05,0x2c,0x04,0x03,0x50,0xa2,0xe0,0x08,0x34,0x42,0x33,0x00,0x88,0x00,0x20 }}, - {16, 0x9f50, 0, {0x10,0x0d,0x84,0x03,0x25,0x00,0x8a,0x40,0x22,0x90,0x08,0xa5,0x02,0x2c,0x00,0x89 }}, - {16, 0x9f60, 0, {0xa4,0x3a,0x40,0x08,0xb0,0x02,0x2c,0x00,0xbf,0x84,0x2e,0x80,0x0b,0xf0,0x52,0x32 }}, - {16, 0x9f70, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x6c,0x80,0x81,0x80,0x24,0x88 }}, - {16, 0x9f80, 0, {0x89,0x3c,0x26,0x21,0x00,0x90,0x00,0x20,0x02,0x08,0x80,0x82,0x00,0x20,0x9b,0x00 }}, - {16, 0x9f90, 0, {0x22,0x40,0x88,0xb0,0x12,0x0c,0x08,0x83,0x80,0x2c,0xc0,0x08,0x10,0x02,0x0c,0x00 }}, - {16, 0x9fa0, 0, {0xb3,0x80,0x2c,0x40,0x0b,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0x9fb0, 0, {0x20,0x01,0x3e,0x0a,0x85,0xa0,0xa5,0x60,0x08,0xfb,0x82,0x3e,0x84,0x9f,0x81,0x63 }}, - {16, 0x9fc0, 0, {0xe0,0x89,0x79,0x12,0x52,0x80,0x97,0x82,0x21,0x6c,0x18,0x78,0x02,0x12,0x00,0x87 }}, - {16, 0x9fd0, 0, {0xa1,0x29,0xe0,0x08,0x5b,0x02,0x1e,0x00,0xb7,0xc0,0x2d,0x60,0x0b,0x78,0x02,0x08 }}, - {16, 0x9fe0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x0c,0x00,0x81,0x08,0x26,0xc2 }}, - {16, 0x9ff0, 0, {0x2c,0x32,0x13,0x0e,0xa4,0xd2,0x00,0xb0,0x00,0x1c,0x21,0x12,0x24,0x02,0xd1,0x20 }}, - {16, 0xa000, 0, {0x30,0xc8,0x0c,0x10,0x03,0x0c,0x00,0xc2,0x10,0x3c,0x80,0x0c,0x23,0x03,0x0c,0x40 }}, - {16, 0xa010, 0, {0xf3,0x00,0x3c,0x48,0x0f,0x30,0x0b,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa020, 0, {0x40,0x1d,0xbc,0x00,0xfd,0x20,0xbb,0x40,0x07,0x72,0x02,0xf0,0x10,0xed,0x10,0x3f }}, - {16, 0xa030, 0, {0xc4,0x0f,0xd1,0x63,0xb4,0x80,0xef,0x00,0x3f,0xc8,0x0f,0xf0,0x03,0xd8,0x00,0xfe }}, - {16, 0xa040, 0, {0x34,0x3f,0xc4,0x0f,0xeb,0x43,0xfc,0x00,0xff,0x08,0x7f,0x40,0x0f,0xf1,0x83,0xd0 }}, - {16, 0xa050, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xec,0x00,0xc8,0x00,0x33,0x80 }}, - {16, 0xa060, 0, {0x8f,0x28,0x03,0x20,0x00,0x49,0x02,0x32,0xc0,0x0f,0x90,0x03,0x20,0x00,0xcb,0x00 }}, - {16, 0xa070, 0, {0x32,0x40,0x4c,0xb0,0x0b,0x2c,0x00,0xcb,0x80,0x32,0xc0,0x0e,0x9e,0x03,0x24,0x00 }}, - {16, 0xa080, 0, {0xfb,0x20,0x3e,0xc0,0x0f,0xb0,0x03,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa090, 0, {0x48,0x11,0x9c,0x00,0x8d,0x01,0x21,0xc0,0x0b,0x60,0x02,0x1d,0x00,0xd6,0x00,0x21 }}, - {16, 0xa0a0, 0, {0x00,0x0b,0xe0,0x02,0x00,0x00,0x83,0x04,0x20,0x40,0x08,0x70,0x42,0x34,0x02,0x87 }}, - {16, 0xa0b0, 0, {0x01,0x23,0xc0,0x28,0x51,0x0a,0x1c,0x04,0xb7,0x30,0x2d,0xc0,0x0b,0x72,0x03,0x92 }}, - {16, 0xa0c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x9e,0x00,0xa6,0x40,0x21,0xa0 }}, - {16, 0xa0d0, 0, {0x0b,0x68,0x02,0x0e,0x00,0x8f,0x80,0x21,0xe0,0x0b,0x78,0x02,0x16,0x10,0xa5,0x80 }}, - {16, 0xa0e0, 0, {0x21,0xe0,0x08,0x18,0x02,0x1e,0x00,0x83,0x80,0x21,0xa0,0x08,0x78,0x02,0x1f,0x00 }}, - {16, 0xa0f0, 0, {0xb7,0x80,0x2d,0xe0,0x0b,0x38,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa100, 0, {0x48,0x14,0xec,0x12,0xa1,0x64,0x20,0xe6,0x0b,0x20,0x02,0x00,0x10,0x90,0x4a,0x20 }}, - {16, 0xa110, 0, {0x20,0x4b,0x00,0x42,0x04,0x00,0x83,0x00,0x20,0xc2,0x08,0x30,0x02,0x8c,0x00,0x83 }}, - {16, 0xa120, 0, {0x04,0x20,0xc0,0x08,0x30,0x02,0x0e,0x00,0xb3,0x00,0x2c,0xe0,0x4b,0x30,0x02,0x92 }}, - {16, 0xa130, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb8,0x00,0xee,0xc0,0x33,0x90 }}, - {16, 0xa140, 0, {0x0f,0xa0,0x1b,0x08,0x00,0xca,0x40,0xb2,0x82,0x0f,0xa0,0x0b,0x28,0x02,0xca,0x00 }}, - {16, 0xa150, 0, {0xb2,0x90,0xac,0xa0,0x03,0x29,0x00,0xca,0x40,0xb2,0x80,0x8e,0xa4,0x03,0x2a,0x00 }}, - {16, 0xa160, 0, {0xfa,0x00,0x3f,0xa8,0x0f,0xa0,0x0b,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa170, 0, {0x48,0x00,0xe2,0x02,0x90,0x00,0x3e,0x00,0x0f,0x88,0x03,0xf1,0x00,0xfc,0x02,0x3f }}, - {16, 0xa180, 0, {0x20,0x0f,0xc8,0x03,0xc1,0x00,0xf0,0x00,0x3e,0x00,0x8f,0x00,0x01,0x60,0x02,0xf8 }}, - {16, 0xa190, 0, {0x08,0x3e,0x00,0x0f,0x80,0x83,0xe0,0x00,0xf8,0x00,0x2e,0x00,0x8f,0x80,0x13,0x92 }}, - {16, 0xa1a0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x02,0xc9,0x00,0xb2,0x64 }}, - {16, 0xa1b0, 0, {0x0f,0x91,0x03,0xe4,0x04,0xc9,0x00,0x32,0x40,0x6c,0x90,0x03,0x25,0x02,0xc9,0x90 }}, - {16, 0xa1c0, 0, {0xb0,0x40,0x0c,0x90,0x03,0x24,0x20,0xc9,0xa0,0x3e,0x40,0x4c,0x90,0x23,0xe4,0x00 }}, - {16, 0xa1d0, 0, {0xf1,0x00,0x92,0x40,0x0c,0x10,0x03,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa1e0, 0, {0x80,0x04,0x64,0x00,0x89,0x80,0xa2,0x40,0x0b,0x96,0x42,0xe5,0x04,0x89,0x00,0x22 }}, - {16, 0xa1f0, 0, {0x40,0x08,0x90,0x02,0x24,0x08,0x09,0x41,0x22,0x40,0x48,0x90,0x42,0x24,0x04,0x89 }}, - {16, 0xa200, 0, {0x80,0x26,0x40,0x08,0x90,0x02,0xe4,0x00,0xb9,0x00,0x22,0x40,0x08,0x94,0x02,0x20 }}, - {16, 0xa210, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x25,0x00,0x89,0x20,0x22,0x40 }}, - {16, 0xa220, 0, {0x0b,0x90,0x02,0xf4,0x84,0x85,0x00,0x21,0x40,0x48,0x50,0x02,0x24,0x20,0x8d,0x08 }}, - {16, 0xa230, 0, {0x23,0x40,0x08,0xd0,0x02,0x94,0x00,0x8d,0x00,0x29,0x40,0x0a,0xd0,0x02,0xa4,0x08 }}, - {16, 0xa240, 0, {0xb9,0x00,0x28,0x40,0x18,0x90,0xc2,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa250, 0, {0x08,0x04,0x05,0x00,0x81,0x00,0x20,0x51,0x0b,0x10,0x02,0xf5,0x80,0x85,0xc1,0xa1 }}, - {16, 0xa260, 0, {0x50,0x08,0x54,0x0a,0x05,0x06,0x85,0x40,0x21,0x50,0x88,0x54,0x02,0x95,0x00,0x85 }}, - {16, 0xa270, 0, {0x44,0x2d,0x50,0x2a,0x54,0x12,0xc5,0x01,0xb1,0x00,0x08,0x50,0x08,0x10,0x02,0x02 }}, - {16, 0xa280, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xca,0x50,0x32,0x80 }}, - {16, 0xa290, 0, {0x0f,0x80,0x03,0xe8,0x02,0xc8,0x01,0x32,0x00,0x2c,0xc0,0x03,0x20,0x00,0xc8,0x02 }}, - {16, 0xa2a0, 0, {0x32,0x00,0x2c,0x80,0x0b,0xa0,0x00,0xc8,0x00,0x3a,0x00,0x4e,0x40,0x23,0xa0,0x08 }}, - {16, 0xa2b0, 0, {0xf8,0x00,0x3a,0x00,0x2c,0x80,0x0b,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa2c0, 0, {0x98,0x1d,0xdc,0x04,0xfd,0x40,0x3f,0x50,0x4f,0x90,0x63,0xe4,0x40,0xf1,0x02,0x3e }}, - {16, 0xa2d0, 0, {0x41,0x0f,0x90,0x13,0xf5,0x04,0xf9,0x41,0x3e,0x50,0x0f,0x94,0x43,0x65,0x02,0xf9 }}, - {16, 0xa2e0, 0, {0x41,0x36,0x50,0x4d,0x94,0x03,0xf4,0x00,0xf9,0x41,0x37,0x40,0x4f,0x94,0x03,0xe6 }}, - {16, 0xa2f0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0xfc,0x00,0xcd,0xa8,0x33,0x70 }}, - {16, 0xa300, 0, {0x0f,0xd0,0x13,0xf6,0x88,0xcd,0x00,0x32,0x50,0x4f,0x14,0x23,0x07,0xa0,0xc9,0xc0 }}, - {16, 0xa310, 0, {0x32,0x78,0x0c,0x9e,0x03,0x37,0x02,0xcd,0xc0,0x32,0x64,0x0f,0x98,0x03,0x24,0x00 }}, - {16, 0xa320, 0, {0xcd,0x00,0x32,0x40,0x2c,0xda,0x03,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa330, 0, {0x38,0x10,0xe2,0x08,0x88,0xeb,0x22,0x30,0x0b,0x80,0x12,0xe8,0x04,0xa0,0xa0,0x2a }}, - {16, 0xa340, 0, {0x20,0x0b,0x8a,0x0a,0x23,0x00,0x88,0x80,0x22,0x28,0x00,0xc8,0x42,0x23,0x80,0x80 }}, - {16, 0xa350, 0, {0xd4,0x20,0x28,0x09,0x80,0x02,0x22,0x94,0xa8,0x00,0x2a,0x00,0x88,0x85,0x02,0x0e }}, - {16, 0xa360, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xc4,0xa0,0x83,0x00,0x24,0xd8 }}, - {16, 0xa370, 0, {0x8b,0x10,0x02,0xe5,0x14,0x89,0x0a,0x21,0x48,0x0b,0x52,0x02,0x54,0x80,0x85,0x40 }}, - {16, 0xa380, 0, {0x25,0x58,0x09,0x56,0x02,0x45,0x02,0x81,0x20,0x20,0x50,0x0b,0x14,0x02,0x04,0x30 }}, - {16, 0xa390, 0, {0x81,0x00,0x20,0x40,0x08,0x10,0x02,0x42,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa3a0, 0, {0x18,0x15,0xa4,0x12,0x89,0x00,0xa6,0x40,0x0b,0x90,0x42,0xe4,0x98,0xa9,0x80,0x2b }}, - {16, 0xa3b0, 0, {0x40,0x0b,0x51,0x02,0x55,0x00,0x9d,0x08,0x27,0x48,0x09,0xf6,0x02,0x44,0x00,0x81 }}, - {16, 0xa3c0, 0, {0x04,0x22,0x40,0x19,0x91,0x8a,0x24,0x80,0xa9,0x00,0x2a,0x40,0x08,0x90,0x02,0x46 }}, - {16, 0xa3d0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe7,0x02,0xc9,0x04,0x36,0x58 }}, - {16, 0xa3e0, 0, {0x0f,0x90,0x03,0xc5,0x00,0xc9,0x00,0x32,0x40,0x0f,0x90,0x13,0x64,0x02,0xc9,0x00 }}, - {16, 0xa3f0, 0, {0x36,0x40,0x2d,0x90,0x0b,0x66,0x04,0xc9,0xe0,0xb2,0x48,0x8f,0x98,0x47,0x24,0x00 }}, - {16, 0xa400, 0, {0xc9,0x00,0x72,0x40,0x0c,0x10,0x03,0x68,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa410, 0, {0x28,0x01,0xa5,0x08,0xf9,0x21,0x3a,0x40,0x0f,0x90,0x03,0xe6,0x04,0xf9,0x00,0x3e }}, - {16, 0xa420, 0, {0x40,0x4f,0x98,0x83,0xa4,0x00,0xe9,0x40,0xba,0x60,0x0e,0x90,0x03,0xa4,0x80,0xf9 }}, - {16, 0xa430, 0, {0xa3,0x3e,0x48,0x0f,0x98,0x0b,0xe4,0x00,0xf9,0x00,0x1e,0x40,0x0f,0x90,0x03,0x8a }}, - {16, 0xa440, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa2,0x48,0xc8,0x20,0x32,0x08 }}, - {16, 0xa450, 0, {0x1f,0x80,0x83,0xe1,0x22,0xc8,0x01,0x33,0x00,0x2c,0xc0,0x03,0x30,0x04,0xcc,0x40 }}, - {16, 0xa460, 0, {0xb1,0x00,0x0c,0x44,0x03,0x20,0x12,0xc8,0x41,0x32,0x00,0x2d,0x84,0x0b,0x60,0x00 }}, - {16, 0xa470, 0, {0xf8,0x00,0xb2,0x00,0x4c,0x80,0x0b,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa480, 0, {0x28,0x05,0x3a,0x00,0xa6,0x00,0x23,0x90,0x03,0xe4,0x92,0xf8,0x00,0x82,0x00,0x36 }}, - {16, 0xa490, 0, {0x80,0x08,0xa0,0x03,0x68,0x00,0xca,0x00,0x22,0x83,0x08,0xa0,0x02,0x28,0x03,0x8a }}, - {16, 0xa4a0, 0, {0x00,0x22,0x80,0x08,0xa0,0x02,0x28,0x00,0xb6,0x80,0x22,0x80,0x0d,0xe8,0x02,0x0a }}, - {16, 0xa4b0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6e,0x00,0x82,0x42,0x20,0xc0 }}, - {16, 0xa4c0, 0, {0x0b,0x34,0x02,0xcd,0x09,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x02,0x98,0x00 }}, - {16, 0xa4d0, 0, {0x20,0x20,0x28,0x00,0x0a,0x04,0x10,0x81,0x80,0x20,0xc0,0x08,0xb0,0x02,0x2c,0x00 }}, - {16, 0xa4e0, 0, {0xb3,0x00,0x22,0xc0,0x18,0x31,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa4f0, 0, {0xa0,0x01,0x38,0x02,0xa3,0x00,0x21,0x40,0x1b,0x70,0x02,0xdc,0x20,0x84,0x05,0x65 }}, - {16, 0xa500, 0, {0xe0,0x08,0xf0,0x02,0x7c,0x10,0x97,0x00,0x24,0xc0,0x08,0x30,0x02,0x54,0x88,0x87 }}, - {16, 0xa510, 0, {0x09,0x21,0xe8,0x09,0x33,0x02,0x1c,0x80,0xb6,0x08,0x63,0xc8,0x09,0x38,0x12,0x28 }}, - {16, 0xa520, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x1e,0x00,0xc7,0xa0,0xa1,0xe0 }}, - {16, 0xa530, 0, {0x0b,0x78,0x03,0xfe,0x00,0xc5,0x82,0x33,0x20,0x0c,0x48,0x03,0x1e,0x01,0xdf,0x80 }}, - {16, 0xa540, 0, {0x31,0x20,0x0c,0x48,0x03,0x06,0x40,0x87,0x82,0x31,0xf8,0x0d,0x7b,0x03,0x5f,0x00 }}, - {16, 0xa550, 0, {0xf3,0x80,0x31,0xf2,0x0c,0x60,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa560, 0, {0x08,0x1d,0x9c,0x00,0xfb,0x01,0x2f,0x40,0x07,0xb0,0x03,0xe8,0x04,0xf9,0x00,0x3e }}, - {16, 0xa570, 0, {0xc1,0x0f,0xb0,0x03,0xe0,0x06,0xe8,0x02,0x3a,0xc0,0x0f,0xb0,0x01,0xa4,0x10,0xf9 }}, - {16, 0xa580, 0, {0x40,0xbe,0xd0,0x06,0xb0,0x03,0xee,0x00,0xfa,0x00,0x3c,0xd8,0x0f,0xa0,0x03,0xc2 }}, - {16, 0xa590, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xf6,0x00,0xcf,0x88,0x33,0x64 }}, - {16, 0xa5a0, 0, {0x2c,0xf8,0x03,0xfe,0x02,0xc4,0xb0,0x33,0x20,0x8c,0xd8,0x03,0x32,0x00,0xcc,0xb4 }}, - {16, 0xa5b0, 0, {0x33,0xa0,0x0c,0xc8,0x03,0x16,0x20,0xcf,0xc0,0x33,0xf0,0x0c,0xf8,0x03,0xfe,0x00 }}, - {16, 0xa5c0, 0, {0xcd,0x80,0x3f,0xe0,0x0f,0xd8,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa5d0, 0, {0xa8,0x11,0xb5,0x04,0x87,0x12,0xa1,0x50,0x0a,0x74,0x12,0xc4,0x40,0x84,0x11,0x23 }}, - {16, 0xa5e0, 0, {0xc0,0x28,0xe0,0x02,0x1c,0x02,0xa7,0x11,0x21,0x58,0x48,0x70,0x0a,0x14,0x00,0x8d }}, - {16, 0xa5f0, 0, {0x00,0x23,0xc0,0x0b,0x70,0x02,0xfc,0x40,0x86,0x00,0x2d,0xc0,0x0b,0x50,0x02,0x2a }}, - {16, 0xa600, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x00,0x87,0x40,0x21,0x00 }}, - {16, 0xa610, 0, {0x18,0x71,0x02,0xdc,0x00,0x95,0x28,0xe1,0x02,0x08,0x50,0x02,0x3c,0x42,0xa7,0x22 }}, - {16, 0xa620, 0, {0x21,0x80,0x88,0x41,0x02,0x14,0x00,0x85,0x00,0xa1,0xc0,0x09,0x71,0x02,0xdc,0x00 }}, - {16, 0xa630, 0, {0xb5,0x10,0x2d,0xc0,0x0b,0x40,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa640, 0, {0x20,0x14,0xc4,0x10,0x83,0x84,0x20,0x11,0x08,0x30,0x02,0xc3,0x10,0x91,0x20,0x20 }}, - {16, 0xa650, 0, {0xc0,0x08,0x28,0x12,0x00,0x00,0xa0,0x84,0x20,0x40,0x08,0x30,0x02,0x04,0x26,0x83 }}, - {16, 0xa660, 0, {0x00,0x20,0xd0,0x0b,0x30,0x02,0xcc,0x00,0xb2,0x00,0x2c,0xc0,0x0b,0x00,0x02,0x08 }}, - {16, 0xa670, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xad,0x00,0xcf,0x88,0xb2,0xe8 }}, - {16, 0xa680, 0, {0x0c,0x30,0x13,0xce,0xc2,0xd0,0x82,0x32,0x00,0x0c,0x0e,0x0b,0x20,0x00,0xc8,0x88 }}, - {16, 0xa690, 0, {0xb2,0x40,0x2c,0xba,0x43,0x37,0x02,0xcb,0x00,0xb3,0xc0,0x2c,0xf0,0x03,0xfc,0x12 }}, - {16, 0xa6a0, 0, {0xfb,0x00,0x7f,0xd1,0x0f,0x30,0x0b,0x2b,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa6b0, 0, {0x80,0x00,0xed,0x02,0xf1,0x40,0x3e,0x41,0x0f,0xb0,0x23,0xed,0x00,0xe8,0x01,0x3e }}, - {16, 0xa6c0, 0, {0xc8,0x0f,0xb0,0x13,0xec,0x04,0xdb,0x00,0x3c,0x80,0x0f,0x04,0x03,0xe4,0x40,0xf9 }}, - {16, 0xa6d0, 0, {0x00,0x3c,0xc2,0x0e,0xb0,0x03,0xee,0x00,0x4b,0x41,0x3e,0xc0,0x0f,0xb0,0x03,0xe0 }}, - {16, 0xa6e0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xfc,0x00,0x4b,0x00,0x32,0x42 }}, - {16, 0xa6f0, 0, {0x0c,0xf0,0x03,0x36,0x80,0xcd,0x00,0x33,0x00,0x4c,0xc0,0x83,0x3c,0x04,0xf7,0x00 }}, - {16, 0xa700, 0, {0x32,0x40,0x0c,0xb1,0x43,0x14,0x00,0xcd,0x80,0x33,0xc0,0x0c,0xf0,0x03,0xfc,0x00 }}, - {16, 0xa710, 0, {0xff,0x00,0xb3,0xc2,0x0c,0xa0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa720, 0, {0x81,0x04,0x4f,0x02,0x8b,0x80,0x20,0x30,0x08,0xbc,0x02,0x20,0x10,0x89,0x00,0x22 }}, - {16, 0xa730, 0, {0xc0,0x00,0xb0,0x03,0x60,0x04,0xb8,0x00,0xa2,0x90,0x28,0x8c,0x1a,0x24,0x02,0x8b }}, - {16, 0xa740, 0, {0x83,0x22,0xc1,0x08,0xb0,0x02,0xfc,0x00,0xb3,0x60,0x20,0xc0,0x0d,0xa0,0x03,0xe0 }}, - {16, 0xa750, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x2e,0x00,0xab,0xc0,0x22,0x60 }}, - {16, 0xa760, 0, {0x08,0xb8,0x02,0x29,0x00,0x88,0x01,0x20,0x00,0x08,0x90,0x02,0x20,0x00,0xb8,0x00 }}, - {16, 0xa770, 0, {0x22,0xc0,0x08,0xb0,0x02,0xe4,0x00,0x81,0x24,0xa2,0xc0,0x09,0xb0,0x46,0xec,0x00 }}, - {16, 0xa780, 0, {0xb9,0x00,0x22,0xc0,0x08,0x90,0x02,0x20,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa790, 0, {0x08,0x04,0x2c,0x00,0xa1,0x00,0xa0,0x41,0x08,0xb0,0x0a,0x20,0x53,0x88,0x00,0x20 }}, - {16, 0xa7a0, 0, {0xc0,0x28,0xa0,0x02,0x4c,0x00,0xb3,0x00,0x20,0x00,0x88,0x00,0x02,0x84,0x00,0x83 }}, - {16, 0xa7b0, 0, {0x04,0x20,0xc0,0x28,0x30,0x02,0xcc,0x00,0xb3,0x02,0x62,0xc0,0x09,0x10,0x02,0xc2 }}, - {16, 0xa7c0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x6c,0x00,0xe9,0x00,0x22,0x00 }}, - {16, 0xa7d0, 0, {0x0c,0xb0,0x03,0x00,0x04,0xc9,0x00,0xb2,0x00,0x0c,0x90,0x03,0x2c,0x00,0xf3,0x00 }}, - {16, 0xa7e0, 0, {0xb2,0xc0,0x8c,0xb0,0x03,0xb4,0x02,0x8f,0x00,0x23,0xc0,0x04,0xf0,0x03,0xec,0x08 }}, - {16, 0xa7f0, 0, {0xf9,0x00,0x33,0xc0,0x0c,0x80,0x03,0x00,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa800, 0, {0xa0,0x1d,0xfc,0x10,0xdd,0x04,0x3f,0x00,0x0f,0xc0,0x23,0xf0,0x90,0xfd,0x00,0x2f }}, - {16, 0xa810, 0, {0xc0,0x0f,0xe0,0x43,0xd0,0x00,0xfc,0x00,0x3f,0x00,0x8f,0xc0,0x22,0x74,0x00,0xfd }}, - {16, 0xa820, 0, {0x04,0x3f,0xc0,0x0f,0xf0,0x03,0xfc,0x00,0xff,0x06,0x3f,0xc0,0x0f,0xc0,0x43,0xe8 }}, - {16, 0xa830, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xfc,0x80,0xef,0x20,0x11,0xc0 }}, - {16, 0xa840, 0, {0x0e,0x72,0x03,0xbd,0xb0,0xcf,0x31,0xbf,0xcc,0x02,0xf0,0x03,0xfc,0xc6,0xcf,0x01 }}, - {16, 0xa850, 0, {0x0b,0xc5,0x0f,0xf1,0x03,0x3c,0x04,0xef,0x61,0x33,0xd8,0x07,0xf0,0x03,0x34,0x80 }}, - {16, 0xa860, 0, {0xcd,0x30,0x73,0xcc,0x0f,0xe8,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa870, 0, {0x80,0x18,0xe9,0x00,0x88,0x69,0x22,0x10,0x08,0x8c,0x00,0x21,0x84,0x88,0x41,0x22 }}, - {16, 0xa880, 0, {0x10,0x88,0x86,0x92,0x01,0x00,0x88,0x62,0x22,0x10,0x4b,0x87,0x02,0x21,0xa0,0x88 }}, - {16, 0xa890, 0, {0x60,0x20,0x10,0x0b,0x86,0xa2,0x35,0xa0,0xab,0x60,0xa1,0xc4,0x0b,0xb8,0x02,0x20 }}, - {16, 0xa8a0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xcd,0xa8,0x33,0x41,0x20,0xc6 }}, - {16, 0xa8b0, 0, {0x4a,0x31,0x00,0x8c,0x10,0x93,0x33,0x28,0xcc,0x29,0x34,0x12,0x8c,0x50,0x93,0x1c }}, - {16, 0xa8c0, 0, {0x28,0x84,0x01,0x20,0x4a,0x4c,0x41,0x83,0x10,0x24,0xcc,0x4b,0x31,0x42,0x4c,0x40 }}, - {16, 0xa8d0, 0, {0x91,0x10,0x24,0xc0,0x0b,0x80,0x02,0x22,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa8e0, 0, {0xc0,0x05,0xa8,0x20,0x90,0x02,0x22,0x00,0x08,0x80,0x00,0x20,0x30,0xb8,0x08,0x26 }}, - {16, 0xa8f0, 0, {0x00,0x01,0x80,0x82,0x20,0x20,0x18,0x08,0x42,0x40,0x03,0x91,0x02,0x60,0x00,0x08 }}, - {16, 0xa900, 0, {0x01,0xa6,0x00,0x0b,0x80,0x00,0x6c,0x10,0xbb,0x01,0x26,0xc0,0x4b,0x90,0x0a,0x30 }}, - {16, 0xa910, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xfd,0x00,0xfd,0x41,0x33,0xa1 }}, - {16, 0xa920, 0, {0x0e,0xd2,0x03,0xb5,0x02,0xdf,0x42,0x3b,0x01,0x0f,0xd4,0x43,0xb5,0x00,0xcd,0x40 }}, - {16, 0xa930, 0, {0x1b,0xc4,0x0d,0x78,0x03,0x70,0x02,0xec,0x00,0x17,0xa1,0x0f,0xe8,0x0b,0x2c,0x02 }}, - {16, 0xa940, 0, {0xd9,0x90,0x26,0xc0,0x0f,0xac,0x03,0x00,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa950, 0, {0xe0,0x01,0xb8,0x00,0xee,0x00,0x1f,0x64,0x4f,0xe0,0x03,0xd8,0x10,0xc4,0x18,0x33 }}, - {16, 0xa960, 0, {0xc0,0x0c,0xa0,0xa1,0xb8,0x09,0xe6,0x09,0x36,0x22,0x0f,0x88,0x23,0xbc,0x00,0xfb }}, - {16, 0xa970, 0, {0x00,0x3b,0x64,0x0f,0xd9,0x03,0x9c,0x00,0xe3,0x04,0x3b,0xc0,0x0f,0xf4,0x03,0xf8 }}, - {16, 0xa980, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x8d,0x00,0xc9,0x40,0xb6,0x80 }}, - {16, 0xa990, 0, {0x0f,0x10,0x03,0xa7,0x20,0xfb,0x50,0xb6,0x08,0x4c,0x14,0x03,0x65,0x22,0xd9,0x40 }}, - {16, 0xa9a0, 0, {0xb6,0x80,0x0e,0xa0,0x0b,0x00,0x00,0xd8,0x00,0x76,0x82,0x28,0xa0,0x23,0x64,0x00 }}, - {16, 0xa9b0, 0, {0xc9,0x04,0x12,0xc0,0x8e,0x80,0x03,0x90,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xa9c0, 0, {0xc8,0x05,0x2b,0x60,0x8a,0x09,0x20,0x50,0x08,0xa0,0x23,0xe9,0x00,0xb8,0xc0,0x22 }}, - {16, 0xa9d0, 0, {0xf0,0x08,0xac,0x02,0x28,0x04,0x8a,0xc2,0x22,0x50,0x08,0x90,0x06,0x2c,0x00,0x8b }}, - {16, 0xa9e0, 0, {0x04,0x22,0x51,0x08,0x94,0x02,0xe4,0x04,0x8b,0x04,0x37,0xc0,0x08,0x18,0x42,0x26 }}, - {16, 0xa9f0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x04,0x4b,0x00,0x82,0xc8,0x24,0x43 }}, - {16, 0xaa00, 0, {0x0b,0x26,0x0a,0x88,0x00,0xb0,0x80,0x22,0xe4,0x0b,0x20,0x42,0x69,0x00,0xa2,0x90 }}, - {16, 0xaa10, 0, {0x28,0x40,0xe8,0x10,0x02,0x0c,0x00,0xbb,0x00,0x28,0x50,0x88,0x90,0x82,0xc4,0x01 }}, - {16, 0xaa20, 0, {0x83,0x00,0x20,0xc0,0x0a,0x10,0x02,0xba,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaa30, 0, {0x20,0x10,0x4e,0x80,0x81,0x00,0x21,0xa8,0x08,0x58,0x02,0xd6,0x01,0xb7,0x90,0x68 }}, - {16, 0xaa40, 0, {0x20,0x03,0x59,0x82,0x56,0x00,0xa5,0x84,0x2d,0xa2,0x18,0x69,0x22,0x02,0x00,0x34 }}, - {16, 0xaa50, 0, {0x80,0x29,0xa8,0x08,0x68,0x06,0xc6,0x14,0x85,0x82,0x25,0xe0,0x08,0x58,0x82,0x1c }}, - {16, 0xaa60, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x48,0x00,0xc2,0xf0,0x34,0x40 }}, - {16, 0xaa70, 0, {0x0f,0x20,0x03,0x88,0x80,0xf8,0x10,0x30,0xc0,0x27,0x21,0x0b,0x48,0x80,0xea,0x20 }}, - {16, 0xaa80, 0, {0x38,0x00,0x0c,0x00,0x12,0x0c,0x08,0x73,0x00,0xb8,0x40,0x0c,0x12,0x23,0x4c,0x02 }}, - {16, 0xaa90, 0, {0x43,0x34,0x30,0xc0,0x0e,0x11,0x03,0x92,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaaa0, 0, {0x40,0x15,0xac,0x90,0xf9,0x01,0x2e,0x88,0x4b,0x90,0x11,0x64,0x00,0xfb,0x10,0x32 }}, - {16, 0xaab0, 0, {0x00,0x00,0x91,0x03,0xa4,0x00,0xc9,0x00,0x32,0xc4,0x4d,0xb0,0x43,0xe0,0x04,0xc8 }}, - {16, 0xaac0, 0, {0x00,0x36,0x89,0x0f,0xa8,0x03,0xed,0x00,0xf9,0x14,0x3e,0xc0,0x0f,0x10,0x43,0xd0 }}, - {16, 0xaad0, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0xe8,0x00,0xc8,0x00,0x3a,0x00 }}, - {16, 0xaae0, 0, {0x0c,0x00,0x53,0xa0,0x00,0xe8,0x01,0x32,0x01,0x0e,0x80,0x53,0x20,0x10,0xc8,0x00 }}, - {16, 0xaaf0, 0, {0x3a,0x40,0x0c,0x90,0x03,0x20,0x10,0xe8,0x04,0xb6,0x00,0x84,0x80,0x03,0x2d,0x12 }}, - {16, 0xab00, 0, {0xcb,0x00,0x2e,0xca,0x04,0x90,0x03,0xea,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xab10, 0, {0x4c,0x19,0x8c,0x00,0x87,0x02,0x21,0xc0,0x08,0x70,0x02,0x0c,0x00,0x83,0x00,0x21 }}, - {16, 0xab20, 0, {0xc0,0x08,0x30,0x62,0x4c,0x04,0x83,0x00,0x21,0x80,0x48,0xe0,0x12,0x3c,0x00,0x87 }}, - {16, 0xab30, 0, {0x00,0x21,0xc0,0x08,0x70,0x02,0x1c,0x00,0x85,0x01,0x24,0xd0,0x0a,0x50,0x02,0xf2 }}, - {16, 0xab40, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x9a,0x00,0x80,0x80,0x28,0x20 }}, - {16, 0xab50, 0, {0x08,0x4c,0x22,0xd2,0x00,0xa4,0x80,0x24,0x30,0x0b,0x48,0x02,0x52,0x00,0x84,0xc0 }}, - {16, 0xab60, 0, {0x21,0x20,0x09,0x48,0x68,0x13,0x00,0xa4,0x80,0x60,0x20,0x09,0x08,0x02,0x56,0x00 }}, - {16, 0xab70, 0, {0x97,0x80,0x2d,0xe0,0x88,0x58,0x02,0xe0,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xab80, 0, {0x6c,0x04,0xcc,0x00,0x83,0x80,0x20,0xd8,0x08,0x30,0x02,0x4c,0x40,0x83,0x00,0x24 }}, - {16, 0xab90, 0, {0xd1,0x09,0xb9,0x42,0x4e,0x00,0x83,0x00,0x20,0xc1,0x89,0x30,0x42,0x0c,0x00,0x83 }}, - {16, 0xaba0, 0, {0xf0,0xa0,0xd9,0x19,0x36,0x22,0x66,0x06,0x91,0x00,0x0c,0xc1,0x0a,0x10,0x02,0xc2 }}, - {16, 0xabb0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xe8,0x02,0xca,0xa5,0x2a,0x91 }}, - {16, 0xabc0, 0, {0x28,0xa8,0x03,0xea,0x02,0xaa,0x00,0xb6,0xa0,0x0f,0xa0,0x0a,0x2a,0x92,0xca,0x83 }}, - {16, 0xabd0, 0, {0xba,0x80,0x29,0xa0,0x03,0x2b,0x00,0xea,0x40,0x66,0x90,0x2d,0xe4,0x0b,0x6a,0x80 }}, - {16, 0xabe0, 0, {0xda,0x00,0x3e,0x80,0x0c,0xe0,0x03,0xfa,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xabf0, 0, {0x48,0x01,0x80,0x00,0xfc,0x00,0x3d,0x00,0x0f,0xc0,0x03,0xb0,0x14,0xfc,0x00,0x3b }}, - {16, 0xac00, 0, {0x12,0x0e,0xc0,0x43,0xb1,0x14,0xfc,0x00,0x3d,0x00,0x0e,0xc0,0x03,0xf0,0x20,0xf4 }}, - {16, 0xac10, 0, {0x00,0x31,0x00,0x0e,0x44,0x13,0xa0,0x00,0xe8,0x06,0x36,0x00,0x4f,0x80,0x13,0xd2 }}, - {16, 0xac20, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa4,0x00,0xd1,0x00,0x36,0x60 }}, - {16, 0xac30, 0, {0x1c,0x18,0x0b,0x46,0x00,0xd9,0x80,0x30,0x40,0x2c,0x98,0x05,0x86,0x00,0xc1,0x80 }}, - {16, 0xac40, 0, {0x92,0x40,0x0d,0x10,0x03,0x44,0x02,0x89,0x00,0x32,0x70,0x0c,0x98,0x01,0x24,0x00 }}, - {16, 0xac50, 0, {0xc9,0x04,0x30,0x40,0x0c,0x90,0x03,0xc2,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xac60, 0, {0x80,0x04,0x64,0x00,0x89,0x00,0x22,0x40,0x08,0x94,0x02,0x24,0x80,0x89,0x01,0x22 }}, - {16, 0xac70, 0, {0x40,0x48,0x91,0x02,0x24,0x00,0xd9,0x90,0x22,0x41,0x08,0x90,0x12,0x24,0x10,0x89 }}, - {16, 0xac80, 0, {0x00,0x32,0x40,0x08,0x95,0x12,0x24,0x02,0x81,0x00,0xa2,0x41,0x0d,0x90,0x42,0xe0 }}, - {16, 0xac90, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x05,0x24,0x02,0x9d,0x00,0x23,0x44 }}, - {16, 0xaca0, 0, {0x08,0xd2,0x06,0x74,0x80,0xb5,0x20,0x23,0x40,0x1a,0xd0,0x06,0x35,0x90,0x8d,0x02 }}, - {16, 0xacb0, 0, {0x2f,0x44,0x19,0xd0,0x02,0x74,0x00,0x8d,0x00,0x63,0x40,0x18,0xd4,0x02,0xa4,0x11 }}, - {16, 0xacc0, 0, {0x89,0x00,0x22,0x40,0x08,0xb0,0x02,0xc6,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xacd0, 0, {0x28,0x14,0x04,0x80,0x85,0x20,0x21,0x68,0x08,0x52,0x02,0x14,0x80,0xa5,0x20,0xa1 }}, - {16, 0xace0, 0, {0x48,0x0a,0x72,0x38,0x14,0x80,0x95,0x24,0x2d,0x48,0x28,0x52,0x02,0x14,0x80,0x85 }}, - {16, 0xacf0, 0, {0x20,0x21,0x48,0x08,0x52,0x06,0x84,0x80,0x81,0x20,0x20,0x4a,0x09,0x10,0x02,0xc2 }}, - {16, 0xad00, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x0d,0x61,0x40,0xd8,0x50,0xb2,0x14 }}, - {16, 0xad10, 0, {0x28,0xa0,0x03,0x61,0x40,0xf8,0x50,0x32,0x94,0x4e,0x85,0x04,0x21,0x42,0xc8,0x50 }}, - {16, 0xad20, 0, {0x3c,0x14,0x0d,0x80,0x03,0x61,0x40,0x88,0x50,0xb2,0x14,0x2c,0xc5,0x09,0xa1,0x40 }}, - {16, 0xad30, 0, {0xc8,0x50,0x32,0x1c,0x0c,0x80,0x03,0xee,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xad40, 0, {0x98,0x15,0xe4,0x40,0xf9,0x10,0x3a,0x44,0x0f,0x91,0x03,0xe4,0x40,0xd9,0x14,0x3e }}, - {16, 0xad50, 0, {0x44,0x0d,0x91,0x43,0x64,0x40,0xe9,0x10,0x32,0x44,0x07,0x93,0xc3,0xe4,0x50,0xd1 }}, - {16, 0xad60, 0, {0x10,0x7e,0x44,0x03,0x91,0x01,0x54,0x44,0xfd,0x14,0x3e,0x40,0x0f,0xd0,0x03,0xe6 }}, - {16, 0xad70, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x80,0xdd,0xa0,0x33,0x68 }}, - {16, 0xad80, 0, {0x1e,0xda,0x03,0x36,0x90,0xcd,0xa0,0x3b,0x68,0x0a,0xd8,0x23,0x76,0x0c,0xed,0x80 }}, - {16, 0xad90, 0, {0x2b,0x62,0x0b,0x99,0x02,0xa7,0x80,0xf9,0xe1,0x37,0x68,0x0c,0xda,0x03,0x27,0x80 }}, - {16, 0xada0, 0, {0xc9,0xa2,0x22,0x68,0x4c,0x50,0x03,0xc6,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xadb0, 0, {0x38,0x18,0xe1,0x40,0x88,0x50,0x22,0x14,0x08,0x80,0x22,0x60,0x00,0x88,0x04,0x22 }}, - {16, 0xadc0, 0, {0x00,0x08,0x04,0x26,0x01,0x00,0x88,0x50,0x22,0x10,0x08,0xaf,0x02,0x23,0x00,0x88 }}, - {16, 0xadd0, 0, {0xc0,0xa0,0x10,0x88,0x84,0x02,0x23,0x80,0xa0,0x40,0x2a,0x10,0x08,0x80,0x12,0x4e }}, - {16, 0xade0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x84,0x00,0x81,0x01,0x20,0x40 }}, - {16, 0xadf0, 0, {0x0a,0x14,0x02,0x45,0x00,0x81,0x41,0x2c,0x50,0x0b,0x14,0x02,0x05,0x04,0xa1,0x00 }}, - {16, 0xae00, 0, {0x28,0x40,0x82,0x10,0x02,0x84,0x40,0xa1,0x32,0x80,0x50,0x09,0x14,0x02,0x04,0xc4 }}, - {16, 0xae10, 0, {0x91,0x10,0x64,0x44,0x28,0x10,0x02,0xd2,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xae20, 0, {0x18,0x04,0xac,0x02,0x81,0x00,0x22,0xc1,0x08,0x90,0x02,0x44,0x02,0x89,0x02,0x26 }}, - {16, 0xae30, 0, {0x41,0x09,0x90,0x0a,0x24,0x0c,0x89,0x04,0x22,0x50,0x08,0x90,0x26,0x24,0x00,0x89 }}, - {16, 0xae40, 0, {0x00,0x22,0x41,0x09,0x10,0x22,0x24,0x40,0xb9,0x01,0x2e,0x40,0x08,0x90,0x02,0x46 }}, - {16, 0xae50, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x15,0xe4,0x10,0x89,0x00,0x32,0x40 }}, - {16, 0xae60, 0, {0x0a,0x90,0x0b,0x24,0x10,0x89,0x00,0x1e,0x40,0x9b,0x90,0x02,0x24,0x10,0x29,0x00 }}, - {16, 0xae70, 0, {0x1a,0x40,0x0e,0x94,0x41,0xa4,0x00,0x29,0x00,0x12,0x40,0x05,0x90,0x41,0x26,0x00 }}, - {16, 0xae80, 0, {0xd9,0x00,0x24,0x40,0x0c,0x90,0x03,0xe8,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xae90, 0, {0x48,0x01,0xa4,0x02,0xa9,0x00,0xbc,0x40,0x0f,0x90,0x03,0xa4,0x04,0xf9,0x00,0x3a }}, - {16, 0xaea0, 0, {0x41,0x0e,0x90,0x83,0x84,0x00,0xf9,0x00,0x3c,0x40,0x0e,0x90,0x02,0xc4,0x08,0xe9 }}, - {16, 0xaeb0, 0, {0x00,0x3a,0x40,0x2e,0x90,0x0b,0xe6,0x00,0xe1,0x04,0x3a,0x40,0x0f,0x92,0x03,0x5a }}, - {16, 0xaec0, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xa0,0x20,0xd8,0x00,0x36,0x02 }}, - {16, 0xaed0, 0, {0x0e,0x00,0xa3,0xe0,0x18,0xc0,0x00,0x30,0x03,0x0f,0x80,0x33,0x20,0x00,0x40,0x00 }}, - {16, 0xaee0, 0, {0x32,0x0d,0x0f,0x04,0x0b,0xa0,0x02,0xc8,0x02,0x32,0x02,0x8c,0x82,0x03,0x20,0x02 }}, - {16, 0xaef0, 0, {0xc8,0x04,0x16,0x00,0x4e,0x80,0x01,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaf00, 0, {0x28,0x05,0x3b,0x00,0x8e,0xd8,0x23,0x80,0x08,0xe0,0x02,0xf8,0x80,0x8e,0x10,0x23 }}, - {16, 0xaf10, 0, {0xa2,0x0b,0xe0,0x82,0x7a,0x20,0x8e,0x30,0x23,0xa1,0x0b,0xe0,0x02,0x28,0x00,0x8e }}, - {16, 0xaf20, 0, {0x00,0x2b,0x88,0x08,0xe4,0x42,0x38,0x00,0x8e,0x04,0x23,0x80,0x08,0xa0,0x02,0x0a }}, - {16, 0xaf30, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x6f,0x40,0x93,0xc6,0x24,0x40 }}, - {16, 0xaf40, 0, {0x0a,0x38,0x02,0xcc,0x00,0x83,0x01,0xac,0xf0,0x0b,0xb4,0x02,0x4c,0x04,0xa3,0x80 }}, - {16, 0xaf50, 0, {0x28,0xd0,0x4b,0x30,0x02,0x4c,0x00,0xab,0x04,0x2a,0xc0,0x2a,0x30,0x0a,0xac,0x10 }}, - {16, 0xaf60, 0, {0x93,0x00,0x20,0xc1,0x0a,0x31,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xaf70, 0, {0x80,0x11,0x1c,0x00,0x82,0x00,0x21,0x42,0x88,0x74,0x06,0xdc,0x0b,0x86,0x02,0x2d }}, - {16, 0xaf80, 0, {0x80,0x0b,0x70,0x2a,0x58,0x00,0xa6,0x00,0xa9,0xc0,0x0b,0x70,0x02,0x5c,0x88,0xa7 }}, - {16, 0xaf90, 0, {0x20,0x29,0xc0,0x0a,0x70,0x02,0x9c,0x10,0x97,0x20,0xa1,0xc8,0x08,0xd8,0x02,0x28 }}, - {16, 0xafa0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x08,0x0e,0x00,0xd7,0x80,0x37,0x60 }}, - {16, 0xafb0, 0, {0x0e,0x68,0x13,0xfe,0x00,0xcf,0x80,0x3d,0xe0,0x0f,0x78,0x23,0x1e,0x00,0xef,0x82 }}, - {16, 0xafc0, 0, {0x31,0xe0,0x0f,0x3c,0xc3,0x7e,0x04,0xef,0x80,0xb1,0xe0,0x0e,0xe8,0x03,0xbe,0x80 }}, - {16, 0xafd0, 0, {0xd7,0xe0,0x33,0xea,0x0e,0x78,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xafe0, 0, {0x08,0x15,0xac,0x00,0xfa,0x01,0x3e,0x00,0x0f,0xb0,0x03,0xe0,0x04,0xf8,0x00,0x32 }}, - {16, 0xaff0, 0, {0x80,0x0f,0x80,0x43,0xac,0x0a,0xd8,0x00,0x36,0x40,0x0f,0xb0,0x03,0x2c,0x0c,0xdb }}, - {16, 0xb000, 0, {0x00,0x26,0xc1,0x09,0xa0,0x13,0x6c,0x40,0xeb,0x40,0x3a,0xdc,0x0f,0x90,0x0b,0xc2 }}, - {16, 0xb010, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0xbe,0x00,0xcf,0x81,0x33,0xe9 }}, - {16, 0xb020, 0, {0x1f,0xf9,0x13,0xb6,0x50,0xef,0x80,0x1f,0xe4,0x04,0xc8,0x03,0x7e,0x00,0x6d,0x81 }}, - {16, 0xb030, 0, {0x33,0x64,0x0c,0xf8,0x1b,0x3e,0x20,0x2f,0x88,0x93,0xe8,0x0f,0xfb,0x03,0x2e,0x80 }}, - {16, 0xb040, 0, {0xcf,0xc0,0x73,0xe0,0x2c,0xd9,0x03,0xd0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb050, 0, {0xa8,0x18,0x90,0x42,0x89,0x18,0x21,0xc0,0x1f,0x71,0x02,0x14,0xc0,0xf7,0x20,0x27 }}, - {16, 0xb060, 0, {0x40,0x40,0x71,0x12,0x18,0x00,0x87,0x20,0x21,0x80,0x48,0x71,0x02,0x3c,0x08,0x87 }}, - {16, 0xb070, 0, {0x20,0x21,0x82,0x0b,0x61,0xa2,0x1e,0x44,0xdf,0x01,0x31,0xc8,0x08,0x73,0x02,0xea }}, - {16, 0xb080, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x8c,0x00,0x87,0x00,0x21,0xc8 }}, - {16, 0xb090, 0, {0x0b,0x70,0x02,0x9c,0x09,0x87,0x02,0x2d,0x82,0x99,0x40,0x02,0x04,0x00,0xa5,0x09 }}, - {16, 0xb0a0, 0, {0x21,0x40,0x19,0x70,0x02,0x1c,0x00,0x87,0x05,0x25,0x48,0x4b,0x72,0x02,0x0c,0x40 }}, - {16, 0xb0b0, 0, {0x87,0x00,0xa1,0xc0,0x48,0x50,0x02,0xc4,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb0c0, 0, {0x68,0x04,0xc1,0x20,0x89,0x4c,0xa0,0xb4,0x0a,0x38,0x02,0x22,0x00,0xa1,0xd0,0x24 }}, - {16, 0xb0d0, 0, {0x30,0x09,0x80,0x02,0x27,0x44,0x81,0xc6,0x22,0x14,0x09,0x3d,0x2a,0x0f,0x02,0x8b }}, - {16, 0xb0e0, 0, {0xc0,0xa6,0x20,0x0b,0x24,0x00,0x0c,0x10,0x93,0x81,0x20,0xc0,0x48,0x30,0x06,0xd8 }}, - {16, 0xb0f0, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x15,0xa1,0x00,0x89,0xc1,0x32,0xd1 }}, - {16, 0xb100, 0, {0x03,0xbc,0x03,0xa9,0x20,0x89,0x41,0x3e,0x60,0x85,0xbc,0x8b,0x25,0x40,0xeb,0x41 }}, - {16, 0xb110, 0, {0xa2,0xa0,0x0d,0xf0,0x13,0x3e,0x20,0xcf,0x90,0x36,0x30,0x4f,0xbc,0x0b,0x3c,0x00 }}, - {16, 0xb120, 0, {0xcf,0x80,0x33,0xc1,0x0c,0xb1,0x03,0xea,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb130, 0, {0x80,0x00,0xed,0x00,0xf8,0x01,0x3c,0xd0,0x0f,0xb3,0x03,0xe8,0x82,0xd8,0x20,0x36 }}, - {16, 0xb140, 0, {0x80,0x2e,0xb2,0x13,0xe1,0x00,0xfa,0x00,0x7e,0xc8,0x2e,0xb0,0x03,0xec,0x80,0xdb }}, - {16, 0xb150, 0, {0x10,0x3a,0x08,0x4f,0xb2,0x23,0xcc,0x02,0xfb,0x10,0x3a,0xc0,0x0f,0x90,0x03,0xe4 }}, - {16, 0xb160, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0xf0,0x00,0xcd,0x10,0x33,0x42 }}, - {16, 0xb170, 0, {0x0c,0xca,0x23,0x7c,0x00,0xcf,0x00,0x33,0x62,0x06,0xf0,0x01,0x3a,0x00,0xcf,0x08 }}, - {16, 0xb180, 0, {0x33,0x80,0x1c,0xf0,0x81,0x3c,0x00,0xff,0x00,0x33,0xa0,0x0c,0xca,0x01,0xfc,0x04 }}, - {16, 0xb190, 0, {0xcf,0x00,0x3f,0xc0,0x0f,0xf0,0x03,0xc0,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb1a0, 0, {0xa1,0x04,0x6d,0x40,0x88,0x48,0xa2,0x31,0x08,0x10,0x02,0x20,0x10,0x88,0xb4,0x22 }}, - {16, 0xb1b0, 0, {0xa0,0x08,0x80,0x00,0x6a,0x84,0x88,0x20,0x22,0x52,0x08,0xb0,0x0a,0x2c,0x10,0xbb }}, - {16, 0xb1c0, 0, {0x00,0x32,0xb3,0x88,0x80,0x02,0xec,0x00,0xdb,0x00,0x2e,0xc0,0x0b,0x90,0x12,0xe1 }}, - {16, 0xb1d0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x10,0x8a,0x01,0x22,0xa0 }}, - {16, 0xb1e0, 0, {0x08,0xb0,0x42,0x60,0x20,0x80,0x00,0x20,0x44,0x1a,0x80,0x1a,0xe4,0x42,0xa0,0x06 }}, - {16, 0xb1f0, 0, {0x22,0x00,0x78,0x30,0x02,0xac,0x00,0xbb,0x00,0xa2,0x44,0x08,0xb0,0x12,0xec,0x00 }}, - {16, 0xb200, 0, {0x8b,0x00,0x0e,0xc0,0x0b,0x90,0x02,0xe0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb210, 0, {0x08,0x14,0x00,0x08,0x80,0x00,0x20,0x81,0x08,0x30,0x02,0x40,0x12,0x80,0x00,0xa0 }}, - {16, 0xb220, 0, {0x40,0x08,0xb0,0x02,0xc0,0x00,0x82,0x00,0x00,0x80,0x08,0x30,0x02,0x8c,0x00,0xbb }}, - {16, 0xb230, 0, {0x00,0x20,0x00,0x08,0x20,0x02,0xcc,0x80,0x93,0x00,0x2c,0xc0,0x0b,0x30,0x02,0xc2 }}, - {16, 0xb240, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x60,0x00,0xca,0x14,0x32,0x00 }}, - {16, 0xb250, 0, {0x0c,0xb0,0x03,0x4c,0x00,0xca,0x00,0x32,0x00,0x0e,0x00,0x12,0xa0,0x00,0xc0,0x00 }}, - {16, 0xb260, 0, {0x70,0x00,0x28,0xf0,0x13,0xac,0x00,0xfb,0x00,0x32,0x40,0x2c,0x10,0x43,0xec,0x00 }}, - {16, 0xb270, 0, {0xcf,0x00,0x3f,0xc0,0x0f,0x90,0x03,0xc0,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb280, 0, {0x20,0x15,0xf0,0x02,0xfc,0x00,0x1f,0x00,0x67,0x70,0x03,0xb0,0x00,0xfc,0x00,0x3f }}, - {16, 0xb290, 0, {0x00,0x2d,0xc0,0x03,0x30,0x10,0xfc,0x01,0xbf,0x00,0x0f,0x70,0x03,0x7c,0x00,0xf7 }}, - {16, 0xb2a0, 0, {0x04,0x3b,0x00,0x0f,0xc0,0x13,0xfd,0x10,0xff,0x00,0x3d,0xc0,0x0f,0xf0,0x03,0xe8 }}, - {16, 0xb2b0, 0, {0x12,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x05,0xf4,0xc0,0xcf,0x80,0x33,0x60 }}, - {16, 0xb2c0, 0, {0x0e,0xc9,0x13,0x36,0x50,0xce,0x86,0x3f,0x08,0x0c,0xc0,0x03,0x3e,0x02,0xd7,0x80 }}, - {16, 0xb2d0, 0, {0x39,0xe0,0x0f,0xf8,0x13,0x3e,0x40,0xc7,0x30,0x3b,0xce,0x0d,0xf6,0x03,0x3d,0x88 }}, - {16, 0xb2e0, 0, {0xcf,0x31,0x33,0xe4,0x0f,0x78,0x03,0x30,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb2f0, 0, {0x80,0x10,0xe5,0xd0,0xdb,0x80,0x72,0x60,0x88,0x92,0x02,0xe4,0x10,0x8a,0x80,0x2e }}, - {16, 0xb300, 0, {0x34,0x4a,0x8c,0x03,0x2e,0x00,0xab,0x80,0x02,0xe0,0x0b,0xb8,0x02,0x2c,0x80,0x8f }}, - {16, 0xb310, 0, {0x60,0x13,0xd8,0x4a,0x76,0x02,0x9d,0x84,0xaf,0x30,0x22,0x48,0x0b,0x88,0x12,0xa0 }}, - {16, 0xb320, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x05,0xc4,0x00,0x8b,0x00,0x24,0x00 }}, - {16, 0xb330, 0, {0x4a,0x00,0x02,0xac,0x80,0x83,0x00,0x2c,0x01,0x28,0x04,0x02,0xac,0x00,0x8b,0x01 }}, - {16, 0xb340, 0, {0x20,0xc0,0x03,0xb0,0x02,0x0c,0x80,0x83,0x40,0x20,0xc1,0xa8,0x34,0x22,0x8d,0x13 }}, - {16, 0xb350, 0, {0x83,0x20,0xac,0xc8,0x0b,0xb0,0x02,0x62,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb360, 0, {0xc0,0x15,0x86,0x00,0x9b,0x04,0xae,0x00,0x0a,0x90,0x02,0xec,0x00,0x0b,0x14,0x2e }}, - {16, 0xb370, 0, {0xc6,0x02,0xb1,0x12,0x6c,0x00,0xab,0x20,0x2a,0xc1,0x0b,0xb0,0x42,0x2c,0x00,0x8b }}, - {16, 0xb380, 0, {0x02,0x26,0xc1,0x0a,0xb0,0x02,0xac,0x00,0xab,0x04,0x2a,0x40,0x0b,0x90,0x02,0xf0 }}, - {16, 0xb390, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0xe7,0x00,0xc3,0x01,0x36,0x40 }}, - {16, 0xb3a0, 0, {0x0e,0x88,0x13,0x24,0x02,0xca,0x00,0x1e,0x20,0x2c,0x8e,0x0b,0x2c,0x00,0xcb,0x00 }}, - {16, 0xb3b0, 0, {0x2a,0xc0,0x0f,0xb8,0x03,0x2e,0x06,0xcb,0x00,0x3a,0xc0,0x4c,0xb0,0x13,0xac,0x0c }}, - {16, 0xb3c0, 0, {0xcb,0x00,0x3e,0xc8,0x0f,0xb0,0x43,0x50,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb3d0, 0, {0xe0,0x01,0xb4,0x08,0xff,0x91,0x33,0x40,0x09,0xdc,0x01,0xf4,0x20,0x7e,0x02,0x2e }}, - {16, 0xb3e0, 0, {0x40,0x0d,0x98,0x01,0xbc,0x80,0xef,0x80,0xb7,0xe4,0x8f,0xf4,0x0b,0xfe,0x40,0x7f }}, - {16, 0xb3f0, 0, {0x00,0xb9,0xc0,0x4e,0xf0,0x03,0xfc,0x08,0xf7,0x00,0x37,0xc0,0x0f,0xe0,0x02,0xb8 }}, - {16, 0xb400, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xa1,0x44,0xcb,0x02,0x32,0x00 }}, - {16, 0xb410, 0, {0x0d,0x80,0x0a,0x6d,0x00,0xeb,0x04,0x10,0x90,0x28,0x22,0x0b,0x2c,0xc2,0xcb,0x20 }}, - {16, 0xb420, 0, {0x76,0xc0,0x0e,0xb1,0x03,0xec,0x01,0xcb,0x06,0x32,0xc1,0x0c,0x30,0x03,0x2c,0x02 }}, - {16, 0xb430, 0, {0xcb,0x00,0x3e,0xd0,0x0c,0xb0,0x03,0x10,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb440, 0, {0xc8,0x05,0x21,0x48,0xab,0x00,0x20,0x00,0x00,0x95,0x23,0x4c,0x08,0xbb,0x01,0x22 }}, - {16, 0xb450, 0, {0xc0,0x08,0xb2,0x02,0x0c,0x08,0x83,0x88,0x92,0xd5,0x28,0x34,0x02,0xec,0x02,0x8f }}, - {16, 0xb460, 0, {0x20,0x23,0xc0,0x4d,0xf0,0x01,0x7c,0x00,0xdf,0x00,0x2e,0xc0,0x0d,0x30,0x03,0x72 }}, - {16, 0xb470, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x05,0x44,0x00,0x83,0x10,0x20,0x60 }}, - {16, 0xb480, 0, {0x09,0x25,0x02,0x00,0x08,0xa0,0x00,0x4c,0x00,0x0b,0x0c,0x22,0x4f,0x12,0x93,0x40 }}, - {16, 0xb490, 0, {0x00,0xc0,0x09,0x3e,0x02,0xec,0x00,0xab,0x80,0xa4,0xc0,0x09,0x30,0x22,0x2c,0x08 }}, - {16, 0xb4a0, 0, {0xb3,0x01,0x0c,0x81,0x08,0x30,0x02,0x38,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb4b0, 0, {0x60,0x01,0x16,0x09,0xb7,0x80,0x21,0x64,0x08,0x78,0x06,0x12,0x00,0xb4,0x82,0x2d }}, - {16, 0xb4c0, 0, {0xa4,0x1b,0x69,0x06,0x7e,0x04,0x17,0x92,0x25,0xe6,0x09,0x78,0x06,0xde,0x80,0xa7 }}, - {16, 0xb4d0, 0, {0x90,0x25,0xe0,0x09,0x79,0x50,0x5e,0x04,0xb7,0x92,0x2f,0x61,0x09,0xc8,0x02,0x48 }}, - {16, 0xb4e0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x25,0x00,0xc3,0x00,0xb0,0x03 }}, - {16, 0xb4f0, 0, {0x0d,0xa3,0x42,0x09,0x40,0xe1,0x00,0xbc,0x40,0x0f,0x11,0x03,0x4c,0x00,0x13,0x00 }}, - {16, 0xb500, 0, {0x20,0xc0,0x09,0x32,0x03,0xcc,0x10,0xa3,0x00,0x26,0xc4,0x8d,0x30,0x2b,0x0c,0x80 }}, - {16, 0xb510, 0, {0xf3,0x00,0x7c,0x80,0x0c,0x30,0x01,0x12,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb520, 0, {0x40,0x1d,0xbc,0x00,0xe7,0x10,0x3d,0x01,0x2f,0xf1,0x42,0xe8,0x00,0xf5,0x90,0x03 }}, - {16, 0xb530, 0, {0xc1,0x0c,0xf1,0x43,0x9c,0x04,0xef,0x08,0x3b,0xc2,0x0c,0xf0,0x81,0xdc,0xa0,0xdf }}, - {16, 0xb540, 0, {0x00,0x3b,0xc3,0x3f,0xf0,0x83,0xfc,0x05,0xdf,0x0c,0x3d,0x40,0x0f,0xd1,0x03,0xd0 }}, - {16, 0xb550, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0xf4,0x00,0xcb,0x80,0x30,0x40 }}, - {16, 0xb560, 0, {0x2c,0xa0,0x03,0xe0,0x00,0xf8,0x80,0x32,0xc0,0x2e,0xb8,0x0b,0x2c,0x46,0xd3,0x00 }}, - {16, 0xb570, 0, {0x30,0xc0,0x0c,0x30,0x03,0x0c,0x00,0xdb,0x48,0x32,0xc0,0x1f,0xb4,0x03,0x2c,0x88 }}, - {16, 0xb580, 0, {0xcb,0x48,0x32,0x80,0x0c,0x30,0x13,0x2a,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb590, 0, {0x48,0x11,0xb4,0x00,0x87,0x01,0x21,0x40,0x08,0x70,0x42,0xd0,0x08,0xb4,0x00,0x29 }}, - {16, 0xb5a0, 0, {0xc0,0x08,0x70,0x02,0x1c,0x00,0x87,0x00,0x21,0xc8,0x0c,0x72,0x0a,0x1c,0x84,0x8f }}, - {16, 0xb5b0, 0, {0x40,0x09,0xc4,0x8f,0x73,0x12,0x9c,0x40,0x83,0x20,0x21,0xc0,0x08,0x60,0x02,0x92 }}, - {16, 0xb5c0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x96,0x01,0xaf,0x80,0x21,0x20 }}, - {16, 0xb5d0, 0, {0x08,0x68,0x02,0xda,0x00,0xbd,0x80,0x21,0xe0,0x09,0x78,0x02,0x1e,0x00,0x8f,0x88 }}, - {16, 0xb5e0, 0, {0x83,0xe2,0x29,0xf8,0x82,0x5f,0x80,0x87,0xa0,0x25,0xe0,0x0b,0x3a,0x12,0x0e,0x50 }}, - {16, 0xb5f0, 0, {0x97,0xa4,0x21,0xa0,0x29,0x78,0x02,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb600, 0, {0x08,0x14,0xcc,0x02,0xa1,0x81,0x00,0x00,0x48,0x70,0x02,0xc8,0x00,0xb1,0x00,0x2c }}, - {16, 0xb610, 0, {0xf8,0x09,0x31,0x42,0x0c,0x10,0x83,0x00,0x20,0xe0,0x08,0x38,0x12,0x4e,0x00,0x83 }}, - {16, 0xb620, 0, {0x00,0x6a,0xc0,0x0b,0x30,0x02,0x8c,0x04,0x93,0x00,0x20,0xe0,0x09,0x38,0x02,0x92 }}, - {16, 0xb630, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0x15,0xb9,0x40,0xee,0x20,0x30,0x80 }}, - {16, 0xb640, 0, {0x0c,0xa0,0x03,0xe8,0x00,0xfa,0x00,0x33,0xb0,0x0d,0xe4,0x03,0x32,0x88,0xcc,0x80 }}, - {16, 0xb650, 0, {0x23,0x00,0x0d,0xc0,0x03,0x62,0x02,0xca,0x00,0x36,0x80,0x0f,0xa0,0x43,0x28,0x06 }}, - {16, 0xb660, 0, {0xda,0x00,0x33,0xa0,0x0d,0x6a,0x03,0x3a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb670, 0, {0x48,0x00,0xe0,0x00,0x98,0x01,0xbe,0x00,0x0f,0x80,0x03,0xf0,0x00,0xbc,0x00,0x38 }}, - {16, 0xb680, 0, {0x04,0x08,0x80,0xa3,0xe0,0x00,0xf8,0x00,0x3e,0x00,0x0f,0x80,0x13,0xa0,0x00,0xe0 }}, - {16, 0xb690, 0, {0x00,0x3e,0x00,0x0e,0x00,0x03,0xc0,0x00,0xe8,0x00,0xbe,0x04,0x4e,0x80,0x07,0xd2 }}, - {16, 0xb6a0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0xe4,0x80,0xc9,0x00,0x3e,0x68 }}, - {16, 0xb6b0, 0, {0x0c,0x90,0x03,0x64,0x00,0xc9,0x00,0x3e,0x40,0x0c,0x90,0x43,0xe0,0x00,0xc8,0x00 }}, - {16, 0xb6c0, 0, {0x32,0x00,0x0c,0x80,0x13,0x20,0x00,0xc9,0x00,0x36,0x40,0x0c,0x90,0x03,0x64,0x00 }}, - {16, 0xb6d0, 0, {0x81,0x00,0x32,0x40,0x04,0x90,0x13,0x02,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb6e0, 0, {0x80,0x04,0x65,0x06,0x89,0x40,0x2e,0x60,0x1a,0x14,0x2a,0x05,0x20,0x89,0x00,0x2e }}, - {16, 0xb6f0, 0, {0x40,0x08,0x90,0x02,0xc4,0x08,0xc1,0x02,0x20,0x40,0x08,0x10,0x1a,0x24,0x00,0x89 }}, - {16, 0xb700, 0, {0x10,0x32,0x41,0x08,0x90,0x12,0x24,0x00,0x89,0x04,0x36,0x40,0x88,0x94,0x0a,0x20 }}, - {16, 0xb710, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0x04,0x20,0x89,0x55,0x2e,0x40 }}, - {16, 0xb720, 0, {0x08,0xd5,0x02,0x34,0x00,0x8d,0x00,0x2e,0x40,0x18,0x90,0x02,0xe4,0x00,0x99,0x00 }}, - {16, 0xb730, 0, {0x26,0x40,0x08,0x90,0x02,0x04,0x0a,0x89,0x00,0x26,0x40,0x38,0x90,0x0a,0x24,0x00 }}, - {16, 0xb740, 0, {0xa9,0x00,0x20,0x40,0x0a,0x90,0x82,0x06,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb750, 0, {0x08,0x04,0x05,0x00,0x81,0x00,0x2f,0x40,0x0a,0xd4,0x02,0x34,0x00,0x85,0x01,0x2c }}, - {16, 0xb760, 0, {0x40,0x08,0x10,0x42,0xe4,0x06,0x99,0x00,0x22,0x40,0x08,0x10,0x02,0x05,0x00,0x81 }}, - {16, 0xb770, 0, {0x40,0x28,0x50,0x08,0x14,0x12,0x05,0x00,0xa1,0x40,0x24,0x50,0x5a,0x10,0x02,0x02 }}, - {16, 0xb780, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0x0d,0x60,0x00,0xc8,0x04,0x3e,0x00 }}, - {16, 0xb790, 0, {0x08,0x80,0x03,0x21,0x42,0xcc,0x00,0x3e,0x00,0x2c,0x80,0x02,0xe0,0x00,0xd8,0x00 }}, - {16, 0xb7a0, 0, {0xb6,0x00,0x2c,0x80,0x02,0x20,0x02,0xc8,0x00,0x36,0x00,0x0c,0x80,0x03,0x60,0x02 }}, - {16, 0xb7b0, 0, {0xe8,0x00,0x32,0x00,0x8e,0x80,0x03,0x2e,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb7c0, 0, {0x98,0x1d,0xf5,0x00,0xf5,0x00,0x3e,0x40,0x87,0x90,0x03,0xe4,0x00,0xf1,0x00,0x3d }}, - {16, 0xb7d0, 0, {0x50,0x0f,0x54,0x03,0xd1,0x00,0xec,0x40,0x3f,0x10,0x0b,0xc4,0x43,0xf1,0x00,0xf9 }}, - {16, 0xb7e0, 0, {0x40,0x36,0x50,0x0f,0x94,0x13,0xe5,0x10,0xd9,0x44,0x3d,0x40,0x2d,0xd0,0x03,0xe6 }}, - {16, 0xb7f0, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x05,0xf6,0x60,0xcd,0x02,0x3b,0x40 }}, - {16, 0xb800, 0, {0x0c,0xd0,0x03,0xb4,0x40,0xfd,0x06,0x3e,0x40,0x0c,0x90,0x03,0x66,0x04,0xc9,0x82 }}, - {16, 0xb810, 0, {0xb6,0x62,0x0f,0x18,0x0b,0x36,0x00,0xcd,0x40,0x32,0x61,0x0c,0x90,0x23,0x24,0x0a }}, - {16, 0xb820, 0, {0xc9,0x00,0x32,0x40,0x4c,0xd0,0x43,0x06,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb830, 0, {0x39,0x10,0xe3,0x80,0xd8,0x00,0x22,0x00,0x0d,0x80,0x02,0x22,0x94,0xb8,0x00,0x2e }}, - {16, 0xb840, 0, {0x00,0x0d,0x80,0x03,0x21,0x00,0x88,0x40,0x22,0x00,0x0b,0xc4,0x22,0x21,0x50,0x88 }}, - {16, 0xb850, 0, {0x80,0x22,0x22,0x08,0x80,0x02,0x20,0x10,0x80,0x01,0x2a,0x00,0x0a,0x80,0x03,0x4e }}, - {16, 0xb860, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xc6,0x00,0x89,0x00,0x2a,0x40 }}, - {16, 0xb870, 0, {0x88,0x10,0x0a,0x84,0x08,0xb1,0x00,0x29,0x40,0x0a,0x70,0x0a,0xb5,0x00,0x8f,0x40 }}, - {16, 0xb880, 0, {0x29,0xc0,0x0b,0xf4,0x02,0x24,0x00,0x81,0x20,0x28,0x44,0x89,0x10,0x02,0x04,0x04 }}, - {16, 0xb890, 0, {0x81,0x02,0x2a,0x40,0x08,0x10,0x02,0x02,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb8a0, 0, {0x18,0x15,0xa6,0x00,0x99,0x20,0x22,0x40,0x09,0x90,0x12,0x24,0x80,0xb9,0x00,0x2f }}, - {16, 0xb8b0, 0, {0x44,0x03,0xd0,0x02,0xf4,0x00,0x8d,0x00,0x2b,0x41,0x0b,0xd0,0x02,0x26,0x10,0x89 }}, - {16, 0xb8c0, 0, {0x04,0x2a,0x40,0x09,0x90,0x6e,0x24,0x00,0x89,0x00,0x2a,0x40,0x0a,0x94,0x02,0x46 }}, - {16, 0xb8d0, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x15,0xe6,0x00,0xc9,0x00,0x38,0x42 }}, - {16, 0xb8e0, 0, {0x0c,0x10,0x13,0xa6,0x04,0x79,0x08,0x3a,0x78,0x06,0x92,0x03,0xa4,0x08,0xc9,0x00 }}, - {16, 0xb8f0, 0, {0x3a,0x60,0x8f,0x98,0x23,0x06,0x02,0xc9,0x02,0x3a,0x40,0x0d,0x90,0x03,0x04,0x00 }}, - {16, 0xb900, 0, {0xc9,0x00,0x38,0x40,0x0c,0x90,0x03,0x28,0x04,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb910, 0, {0x28,0x01,0x84,0x10,0xf9,0x80,0xbe,0x40,0x4f,0x90,0x02,0xe4,0x00,0xf9,0x00,0x3c }}, - {16, 0xb920, 0, {0x60,0x8d,0x92,0x03,0x24,0x42,0xe9,0x10,0x32,0x50,0x0f,0x94,0x03,0xe4,0x00,0xf9 }}, - {16, 0xb930, 0, {0x00,0xb6,0x41,0x2e,0x10,0x03,0xe4,0x00,0xf9,0x00,0x2e,0x40,0x0f,0x90,0x03,0xca }}, - {16, 0xb940, 0, {0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x10,0xa0,0x08,0xc8,0x00,0x3e,0x10 }}, - {16, 0xb950, 0, {0x0f,0x88,0x03,0x20,0x08,0xf8,0xc0,0x1e,0x10,0x2c,0x40,0x03,0xf2,0x00,0xcc,0x00 }}, - {16, 0xb960, 0, {0x3f,0x00,0x0c,0xc0,0x13,0x20,0x02,0xc0,0x00,0x30,0x00,0x0c,0x80,0x2b,0x20,0x10 }}, - {16, 0xb970, 0, {0xc0,0x04,0x32,0x00,0x0f,0x80,0x03,0x0a,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb980, 0, {0xa8,0x05,0x3a,0x80,0x86,0xe0,0x2f,0xa0,0x1b,0xe0,0x02,0x3a,0x80,0xba,0x04,0x2e }}, - {16, 0xb990, 0, {0x80,0x08,0xa0,0x03,0x88,0x08,0xc2,0x00,0x2e,0x81,0x08,0x60,0x02,0x28,0x10,0x8e }}, - {16, 0xb9a0, 0, {0x81,0x03,0x80,0x08,0xe0,0x01,0x78,0x00,0x8e,0x04,0x03,0x80,0x09,0x68,0x03,0xca }}, - {16, 0xb9b0, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x05,0x4c,0x00,0x83,0x60,0x2c,0x44 }}, - {16, 0xb9c0, 0, {0x0b,0x38,0x02,0x0f,0x80,0xb1,0x00,0x2c,0xe5,0x03,0x30,0x10,0xcc,0x10,0x83,0x00 }}, - {16, 0xb9d0, 0, {0x0c,0xc0,0x29,0x30,0x22,0x04,0x09,0x91,0x10,0x24,0xc0,0xc8,0x30,0x00,0x4c,0x04 }}, - {16, 0xb9e0, 0, {0x93,0x02,0x24,0xc0,0x0b,0x31,0x02,0x0a,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xb9f0, 0, {0xe0,0x01,0x18,0x80,0x87,0x00,0x2d,0x40,0x0b,0x74,0x42,0x1c,0x01,0xb5,0x01,0x2c }}, - {16, 0xba00, 0, {0xc0,0x0b,0x60,0x02,0xb0,0x00,0x94,0x04,0x2f,0x20,0x09,0xc0,0x02,0x14,0x90,0x97 }}, - {16, 0xba10, 0, {0x00,0x25,0xc8,0x08,0x70,0x02,0x4c,0x80,0x97,0x20,0x25,0xc0,0x09,0x70,0x02,0xe8 }}, - {16, 0xba20, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x08,0x3a,0x82,0xc6,0x80,0x2d,0x60 }}, - {16, 0xba30, 0, {0x0b,0xf8,0x0b,0x1a,0x00,0xf5,0x80,0x3d,0xe0,0x8f,0x78,0x03,0xde,0x02,0xc7,0x80 }}, - {16, 0xba40, 0, {0x2d,0xe0,0x0d,0x78,0x0b,0x17,0x02,0xdf,0x80,0x24,0xf8,0x2c,0xfd,0x03,0x5e,0x0c }}, - {16, 0xba50, 0, {0xd7,0xe0,0x35,0xe0,0x0f,0x68,0x03,0x2a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xba60, 0, {0x48,0x1d,0xae,0x40,0xfa,0x04,0x3e,0x40,0x0f,0x80,0x13,0xec,0x04,0xf9,0x00,0x3e }}, - {16, 0xba70, 0, {0xc1,0x0c,0xa0,0x13,0xc0,0x10,0xe8,0x00,0x3c,0x00,0x4e,0x80,0x43,0xc4,0x20,0x89 }}, - {16, 0xba80, 0, {0x00,0xba,0xc0,0x07,0xb6,0x21,0xed,0x06,0xeb,0x68,0xba,0xcc,0x0f,0x20,0x13,0xc2 }}, - {16, 0xba90, 0, {0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xbe,0x00,0xc6,0x80,0x31,0x60 }}, - {16, 0xbaa0, 0, {0x2d,0x78,0x0b,0x3e,0x48,0xec,0x92,0x3d,0x60,0x0c,0x58,0x03,0x5a,0x40,0xd5,0x80 }}, - {16, 0xbab0, 0, {0x31,0x61,0x0c,0x58,0x23,0x36,0x00,0xcf,0x82,0x3f,0xe0,0x0c,0xf8,0x03,0xff,0x60 }}, - {16, 0xbac0, 0, {0xcf,0x90,0x33,0xf0,0x0c,0x52,0x03,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbad0, 0, {0xa8,0x11,0xb8,0x84,0x86,0x14,0xb5,0xc0,0x08,0x70,0x02,0x1e,0xc0,0xc4,0x00,0x2d }}, - {16, 0xbae0, 0, {0x40,0x08,0x40,0x02,0x14,0xd0,0x86,0x10,0x21,0x80,0x4c,0x62,0x42,0x34,0x40,0xa5 }}, - {16, 0xbaf0, 0, {0x00,0x35,0xc0,0x28,0x70,0x42,0xdc,0xc2,0x8f,0x30,0x23,0xc0,0x08,0x50,0x02,0x2a }}, - {16, 0xbb00, 0, {0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x98,0x28,0x8e,0x00,0xa5,0x40 }}, - {16, 0xbb10, 0, {0x08,0xf1,0x02,0x18,0x64,0xb4,0x00,0x6d,0x42,0x08,0x50,0x02,0x18,0x01,0x85,0x08 }}, - {16, 0xbb20, 0, {0x21,0x40,0x09,0x58,0x22,0x54,0x00,0x85,0x10,0x2d,0xc4,0x09,0x70,0x02,0xdc,0x04 }}, - {16, 0xbb30, 0, {0x97,0x00,0x25,0xc0,0x08,0x44,0x02,0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbb40, 0, {0x60,0x14,0x8c,0x00,0x82,0x80,0x24,0xc0,0x08,0x80,0x02,0x2d,0x00,0x80,0x4a,0x2c }}, - {16, 0xbb50, 0, {0x42,0x08,0x0a,0x42,0x06,0x00,0x92,0x84,0x20,0xa0,0x88,0x28,0x42,0x44,0x00,0xa3 }}, - {16, 0xbb60, 0, {0x06,0x24,0xc0,0x0b,0x30,0x02,0xcc,0x10,0x93,0x04,0x24,0xc1,0x09,0x00,0x02,0x08 }}, - {16, 0xbb70, 0, {0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x15,0xbc,0x00,0xcb,0x00,0x36,0x40 }}, - {16, 0xbb80, 0, {0x0c,0xb4,0x13,0x2c,0x00,0xf9,0x00,0x3e,0xa0,0x0c,0xa2,0x03,0x04,0x08,0xc2,0x80 }}, - {16, 0xbb90, 0, {0x30,0xa8,0x0d,0x2a,0x03,0x54,0x00,0xcb,0x00,0x3f,0xc0,0x0d,0xf0,0x03,0xfc,0x08 }}, - {16, 0xbba0, 0, {0xdf,0x00,0x37,0xd0,0x0c,0xb0,0x03,0x2a,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbbb0, 0, {0x80,0x00,0xe0,0x00,0xfb,0x10,0x3a,0x40,0x0e,0xb0,0x03,0xed,0x90,0xf9,0x11,0x7e }}, - {16, 0xbbc0, 0, {0x80,0x4f,0xb0,0x53,0xe8,0x40,0xe9,0x00,0x3e,0x40,0x0f,0x90,0x03,0xa6,0x08,0xf9 }}, - {16, 0xbbd0, 0, {0x01,0x3a,0xc0,0x0c,0xb0,0x13,0xcc,0x00,0xeb,0x02,0x3a,0xc6,0x8e,0xb8,0x03,0xe0 }}, - {16, 0xbbe0, 0, {0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0xf0,0x0c,0xce,0x00,0x3f,0xe0 }}, - {16, 0xbbf0, 0, {0x2c,0xf0,0x83,0x3a,0x48,0xcd,0x01,0x35,0x80,0x0c,0x60,0x12,0x34,0x0a,0xce,0x00 }}, - {16, 0xbc00, 0, {0xb3,0x80,0x2c,0xe0,0x0b,0x74,0x00,0xc9,0x10,0xb3,0xc1,0x0f,0xf0,0x1b,0x3c,0x00 }}, - {16, 0xbc10, 0, {0xcf,0x00,0xb7,0xc0,0x2c,0xe0,0x03,0x00,0x44,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbc20, 0, {0x81,0x04,0x6e,0x10,0x88,0x80,0x2c,0xc0,0x18,0x98,0x02,0x2d,0x80,0x81,0x00,0x36 }}, - {16, 0xbc30, 0, {0x91,0x08,0xb0,0x03,0x68,0x00,0xc9,0x00,0x22,0x40,0x08,0x90,0x02,0x24,0x00,0x83 }}, - {16, 0xbc40, 0, {0x80,0x36,0xc0,0x0b,0x30,0x02,0x2c,0x02,0x83,0x00,0x20,0xc0,0x08,0x20,0x03,0x60 }}, - {16, 0xbc50, 0, {0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x05,0x06,0x00,0x8a,0x80,0x2e,0x45 }}, - {16, 0xbc60, 0, {0x28,0x88,0x02,0x24,0x02,0x88,0x02,0x02,0x02,0x08,0x80,0x02,0xa2,0x00,0x98,0x00 }}, - {16, 0xbc70, 0, {0x22,0x00,0x08,0x80,0x12,0x24,0x00,0x89,0x01,0x22,0xc1,0x0a,0xb0,0x02,0x6c,0x00 }}, - {16, 0xbc80, 0, {0xab,0x00,0x22,0xc1,0x08,0x90,0x12,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbc90, 0, {0x08,0x04,0x00,0x00,0x80,0x00,0x2c,0xc0,0x48,0x08,0x12,0x00,0x80,0x80,0x02,0x24 }}, - {16, 0xbca0, 0, {0x00,0x08,0x18,0x42,0xac,0x02,0x8b,0x80,0x22,0xe0,0x08,0xb8,0x12,0x04,0x02,0x83 }}, - {16, 0xbcb0, 0, {0x00,0x20,0xc0,0x0b,0x30,0x42,0x0c,0x00,0xa3,0x01,0x60,0xc0,0x48,0x10,0x02,0x42 }}, - {16, 0xbcc0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x68,0x08,0xca,0x00,0x2e,0x40 }}, - {16, 0xbcd0, 0, {0x08,0x80,0x03,0x00,0x00,0xc8,0x06,0x32,0x00,0x0c,0x80,0x02,0xa0,0x00,0xd8,0x00 }}, - {16, 0xbce0, 0, {0x32,0x00,0x0c,0x80,0x03,0x74,0x00,0xcb,0x00,0x22,0xc0,0x0f,0xf0,0x03,0x3c,0x00 }}, - {16, 0xbcf0, 0, {0xef,0x00,0x37,0xc0,0x0c,0x80,0x01,0x40,0x03,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbd00, 0, {0xa0,0x19,0xfc,0x00,0xfc,0x04,0x3f,0xc0,0x0f,0xc0,0x03,0xe1,0x00,0xfc,0x00,0x3b }}, - {16, 0xbd10, 0, {0x00,0x0f,0xd0,0x03,0x7c,0x00,0xef,0x00,0x2f,0xc0,0x0f,0xf0,0x11,0xf4,0x10,0xfd }}, - {16, 0xbd20, 0, {0x02,0x3d,0xc0,0x4f,0xf0,0x03,0xdc,0x00,0xdf,0x04,0x3f,0xc0,0x0f,0xc0,0x43,0xe9 }}, - {16, 0xbd30, 0, {0x06,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x41,0x02,0x70,0x20,0xdc,0x10 }}, - {16, 0xbd40, 0, {0x67,0x04,0x0d,0xc1,0x02,0x70,0x20,0x9c,0x10,0x37,0x04,0x0d,0xc1,0x06,0x70,0x40 }}, - {16, 0xbd50, 0, {0x4c,0x10,0x37,0x14,0x15,0xc1,0x03,0x70,0x40,0xdc,0x10,0x13,0x04,0x0d,0xc1,0x07 }}, - {16, 0xbd60, 0, {0x70,0x40,0xdc,0x10,0x37,0x04,0x0d,0xc0,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbd70, 0, {0x00,0xc5,0x44,0x05,0x71,0x21,0x5c,0x40,0x57,0x10,0x15,0xc4,0x05,0x71,0x05,0x5c }}, - {16, 0xbd80, 0, {0x40,0x57,0x10,0x15,0xc4,0x06,0x71,0x01,0x4c,0x40,0x57,0x10,0x0d,0xc4,0x05,0x71 }}, - {16, 0xbd90, 0, {0x05,0x5c,0x40,0x53,0x10,0x15,0xc4,0x07,0x71,0x01,0x5c,0x40,0x57,0x10,0x15,0xc0 }}, - {16, 0xbda0, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x02,0x01,0x20,0x80,0x48,0x20 }}, - {16, 0xbdb0, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 }}, - {16, 0xbdc0, 0, {0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01 }}, - {16, 0xbdd0, 0, {0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbde0, 0, {0x00,0x84,0x00,0x01,0x60,0x00,0x58,0x00,0x56,0x00,0x05,0x80,0x01,0x60,0x04,0x58 }}, - {16, 0xbdf0, 0, {0x00,0x16,0x00,0x05,0x80,0x01,0x20,0x01,0x58,0x00,0x16,0x00,0x05,0x80,0x01,0x60 }}, - {16, 0xbe00, 0, {0x00,0x58,0x00,0x56,0x00,0x05,0x80,0x01,0x60,0x00,0x58,0x00,0x16,0x00,0x01,0x80 }}, - {16, 0xbe10, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x05,0x72,0x11,0x5c,0x80 }}, - {16, 0xbe20, 0, {0x17,0x20,0x15,0xd8,0x05,0x32,0x11,0x1c,0x80,0x47,0x20,0x14,0x88,0x00,0x72,0x01 }}, - {16, 0xbe30, 0, {0x1c,0x80,0x57,0x20,0x05,0xc8,0x04,0x72,0x01,0x5c,0x80,0x57,0x20,0x15,0xc8,0x01 }}, - {16, 0xbe40, 0, {0x72,0x01,0x5c,0x80,0x57,0x24,0x15,0xc0,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbe50, 0, {0x00,0xc1,0x40,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x40,0x20,0x00,0x18 }}, - {16, 0xbe60, 0, {0x00,0x06,0x00,0x01,0x90,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x41,0x80,0x00,0x60 }}, - {16, 0xbe70, 0, {0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x10,0x06,0x00,0x01,0x80 }}, - {16, 0xbe80, 0, {0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x48,0x04,0x22,0x01,0x08,0x80 }}, - {16, 0xbe90, 0, {0x02,0x20,0x10,0x88,0x04,0x62,0x01,0x08,0x80,0x42,0x20,0x10,0x88,0x00,0x20,0x01 }}, - {16, 0xbea0, 0, {0x08,0x80,0x42,0x20,0x00,0x88,0x04,0x22,0x01,0x08,0x00,0x42,0x20,0x10,0x88,0x00 }}, - {16, 0xbeb0, 0, {0x22,0x01,0x08,0x80,0x42,0x30,0x10,0x80,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbec0, 0, {0x00,0xc5,0x4a,0x05,0x42,0x81,0x50,0xa0,0x04,0x28,0x15,0x0a,0x05,0x52,0x81,0x10 }}, - {16, 0xbed0, 0, {0xa0,0x44,0x28,0x11,0x1a,0x00,0x40,0x80,0x10,0xa0,0x54,0x28,0x05,0x0a,0x05,0x42 }}, - {16, 0xbee0, 0, {0x81,0x51,0x20,0x14,0x28,0x15,0x0a,0x01,0x42,0x81,0x50,0xa0,0x54,0x28,0x15,0x00 }}, - {16, 0xbef0, 0, {0x31,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0c,0x01,0x53,0x40,0x54,0xc0 }}, - {16, 0xbf00, 0, {0x15,0x30,0x05,0x5c,0x01,0x57,0x40,0x54,0xc0,0x15,0x30,0x05,0x5c,0x01,0x53,0x00 }}, - {16, 0xbf10, 0, {0x55,0xc0,0x15,0x74,0x05,0x4c,0x01,0x53,0x00,0x55,0xc0,0x15,0x74,0x05,0x4c,0x01 }}, - {16, 0xbf20, 0, {0x53,0x00,0x54,0xc0,0x11,0x30,0x01,0x40,0x21,0x10,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbf30, 0, {0x00,0x80,0x00,0x00,0x40,0x00,0x10,0x00,0x04,0x00,0x01,0x00,0x00,0x40,0x00,0x10 }}, - {16, 0xbf40, 0, {0x00,0x04,0x00,0x01,0x00,0x00,0x42,0x00,0x10,0x00,0x04,0x00,0x11,0x00,0x00,0x40 }}, - {16, 0xbf50, 0, {0x00,0x10,0xc1,0x04,0x00,0x01,0x00,0x00,0x40,0x00,0x10,0x00,0x01,0x10,0x01,0x01 }}, - {16, 0xbf60, 0, {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x60,0x02,0x08,0x00,0x82,0x00 }}, - {16, 0xbf70, 0, {0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00 }}, - {16, 0xbf80, 0, {0x82,0x00,0x20,0x84,0x00,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x84,0x08,0x20,0x02 }}, - {16, 0xbf90, 0, {0x08,0x00,0x82,0x00,0x21,0x80,0x08,0x01,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xbfa0, 0, {0x00,0xc5,0x40,0x05,0x60,0x01,0x58,0x00,0x96,0x00,0x15,0x90,0x05,0x64,0x02,0x58 }}, - {16, 0xbfb0, 0, {0x00,0x56,0x00,0x55,0x90,0x05,0x60,0x01,0xd9,0x00,0x16,0x40,0x15,0x80,0x05,0x60 }}, - {16, 0xbfc0, 0, {0x01,0x59,0x00,0x76,0x40,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x56,0x00,0x15,0x80 }}, - {16, 0xbfd0, 0, {0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x40,0x03,0x60,0x00,0xd8,0x00 }}, - {16, 0xbfe0, 0, {0x36,0x00,0x4d,0x80,0x03,0x60,0x00,0xd8,0x00,0x36,0x00,0x0d,0x80,0x07,0x62,0x00 }}, - {16, 0xbff0, 0, {0x58,0x00,0x36,0x00,0x0d,0x80,0x07,0x60,0x00,0xd8,0x80,0x16,0x00,0x0d,0x80,0x03 }}, - {16, 0xc000, 0, {0x60,0x00,0xd8,0x00,0x36,0x00,0x1d,0x80,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc010, 0, {0x00,0xc5,0x42,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c }}, - {16, 0xc020, 0, {0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0xc1,0x0c,0x20,0x43,0x08,0x10,0xc2,0x06,0x30 }}, - {16, 0xc030, 0, {0x81,0x0c,0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x18,0xc0 }}, - {16, 0xc040, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x30,0x00,0x0c,0x00 }}, - {16, 0xc050, 0, {0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x40,0x30,0x00 }}, - {16, 0xc060, 0, {0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00 }}, - {16, 0xc070, 0, {0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc080, 0, {0x00,0x80,0x02,0x01,0x30,0x80,0x4c,0x20,0x13,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c }}, - {16, 0xc090, 0, {0x20,0x13,0x08,0x04,0xc2,0x25,0x30,0x81,0x4c,0x20,0x13,0x08,0x04,0xc2,0x01,0x30 }}, - {16, 0xc0a0, 0, {0x80,0x4c,0x32,0x53,0x08,0x04,0xc2,0x01,0x30,0x80,0x4c,0x20,0x13,0x08,0x04,0xc0 }}, - {16, 0xc0b0, 0, {0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x05,0x62,0x81,0x58,0x20 }}, - {16, 0xc0c0, 0, {0x56,0x08,0x15,0x82,0x04,0x60,0x81,0x58,0x20,0x46,0x08,0x15,0x82,0x01,0x60,0xc1 }}, - {16, 0xc0d0, 0, {0x58,0x20,0x46,0x08,0x15,0x82,0x01,0x60,0x81,0x58,0x30,0x56,0x08,0x15,0x82,0x05 }}, - {16, 0xc0e0, 0, {0x60,0x81,0x58,0x20,0x56,0x08,0x05,0x80,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc0f0, 0, {0x00,0xc5,0x42,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08 }}, - {16, 0xc100, 0, {0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x0c,0x20,0x02,0x08,0x00,0x82,0x00,0x20 }}, - {16, 0xc110, 0, {0x80,0x08,0x20,0x03,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x80 }}, - {16, 0xc120, 0, {0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x42,0x04,0x66,0x81,0x18,0x20 }}, - {16, 0xc130, 0, {0x46,0x08,0x11,0x82,0x04,0x64,0x81,0x18,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0x81 }}, - {16, 0xc140, 0, {0x0c,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0x81,0x19,0x20,0x43,0x08,0x11,0x82,0x04 }}, - {16, 0xc150, 0, {0x60,0x81,0x19,0x20,0x46,0x48,0x01,0x80,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc160, 0, {0x00,0xc5,0x60,0x05,0x58,0x01,0x56,0x00,0x55,0x80,0x15,0x60,0x04,0x58,0x01,0x56 }}, - {16, 0xc170, 0, {0x00,0x45,0x80,0x11,0x60,0x00,0x58,0x00,0x06,0x00,0x45,0x80,0x15,0x60,0x01,0x58 }}, - {16, 0xc180, 0, {0x01,0x16,0x00,0x01,0x80,0x15,0x60,0x05,0x58,0x01,0x56,0x00,0x55,0x80,0x05,0x40 }}, - {16, 0xc190, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x06,0x01,0x49,0x80,0x10,0x60 }}, - {16, 0xc1a0, 0, {0x14,0x18,0x05,0x06,0x01,0x79,0x80,0x50,0x60,0x14,0x18,0x01,0x06,0x01,0x41,0x80 }}, - {16, 0xc1b0, 0, {0x50,0x60,0x04,0x18,0x05,0x06,0x01,0x41,0x80,0x10,0x60,0x14,0x18,0x05,0x06,0x01 }}, - {16, 0xc1c0, 0, {0x41,0x80,0x50,0x60,0x14,0x18,0x05,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc1d0, 0, {0x00,0x80,0x02,0x01,0x04,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x04,0x04,0x40 }}, - {16, 0xc1e0, 0, {0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x84,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00 }}, - {16, 0xc1f0, 0, {0x80,0x41,0x20,0x10,0x08,0x04,0x02,0x11,0x00,0x80,0x41,0x20,0x10,0x48,0x04,0x00 }}, - {16, 0xc200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x46,0x03,0x51,0x80,0xd4,0x60 }}, - {16, 0xc210, 0, {0x35,0x18,0x0d,0x46,0x02,0x11,0x80,0xd4,0x60,0x35,0x18,0x0d,0x46,0x03,0x11,0x80 }}, - {16, 0xc220, 0, {0xd4,0x60,0x35,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x46,0x03 }}, - {16, 0xc230, 0, {0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x31,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc240, 0, {0x00,0xc5,0x46,0x05,0x70,0x81,0x5c,0x60,0x07,0x18,0x15,0xc6,0x04,0x71,0x81,0x1c }}, - {16, 0xc250, 0, {0x60,0x17,0x18,0x15,0xc6,0x05,0x31,0x81,0xdc,0x60,0x57,0x18,0x15,0xc6,0x05,0x71 }}, - {16, 0xc260, 0, {0x80,0x1c,0x60,0x77,0x18,0x15,0xce,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc0 }}, - {16, 0xc270, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x46,0x02,0x71,0x80,0x9c,0x61 }}, - {16, 0xc280, 0, {0x77,0x18,0x0d,0xc6,0x02,0x71,0x80,0x9c,0x60,0x37,0x18,0x0d,0xc2,0x03,0x31,0x80 }}, - {16, 0xc290, 0, {0x5c,0x60,0x27,0x18,0x0d,0xc6,0x03,0x71,0x80,0x9c,0x60,0x17,0x18,0x0d,0xce,0x03 }}, - {16, 0xc2a0, 0, {0x71,0x80,0xdc,0x60,0x37,0x18,0x0d,0xc0,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc2b0, 0, {0x00,0x45,0x46,0x05,0x75,0x81,0x5c,0x60,0x77,0x18,0x15,0xc6,0x05,0x75,0x81,0x5c }}, - {16, 0xc2c0, 0, {0x60,0x57,0x18,0x15,0xc6,0x05,0x31,0x81,0x0c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71 }}, - {16, 0xc2d0, 0, {0x81,0x5c,0x60,0x43,0x18,0x15,0xc6,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc0 }}, - {16, 0xc2e0, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x01,0x20,0x80,0x48,0x20 }}, - {16, 0xc2f0, 0, {0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 }}, - {16, 0xc300, 0, {0x5c,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80,0x48,0x00,0x17,0x08,0x04,0x82,0x01 }}, - {16, 0xc310, 0, {0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc320, 0, {0x00,0x00,0x06,0x01,0x63,0x80,0x58,0x60,0x16,0x18,0x05,0x86,0x01,0x61,0x80,0x58 }}, - {16, 0xc330, 0, {0x60,0x16,0x18,0x05,0x86,0x01,0x61,0x81,0x58,0x60,0x16,0x18,0x05,0x86,0x01,0x61 }}, - {16, 0xc340, 0, {0x80,0x58,0x60,0x56,0x18,0x05,0x86,0x01,0x61,0x80,0x58,0x60,0x16,0x18,0x05,0x80 }}, - {16, 0xc350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x40,0x05,0x70,0x01,0x5c,0x00 }}, - {16, 0xc360, 0, {0x17,0x00,0x15,0xc0,0x85,0x74,0x01,0x1c,0x00,0x47,0x00,0x11,0xc0,0x05,0x70,0x01 }}, - {16, 0xc370, 0, {0x5c,0x00,0x53,0x00,0x10,0xc0,0x05,0x70,0x01,0x5c,0x00,0x57,0x00,0x14,0xc9,0x04 }}, - {16, 0xc380, 0, {0x70,0x01,0x1c,0x00,0x57,0x00,0x15,0xc0,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc390, 0, {0x00,0x45,0x42,0x00,0x60,0xc0,0x18,0x20,0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18 }}, - {16, 0xc3a0, 0, {0x20,0x06,0x08,0x01,0x82,0x00,0x20,0x80,0x18,0x30,0x02,0x08,0x00,0x82,0x10,0x60 }}, - {16, 0xc3b0, 0, {0x80,0x18,0x20,0x06,0x08,0x00,0x82,0x00,0x60,0x80,0x18,0x20,0x06,0x08,0x01,0x80 }}, - {16, 0xc3c0, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x42,0x04,0x20,0x81,0x08,0x20 }}, - {16, 0xc3d0, 0, {0x02,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81 }}, - {16, 0xc3e0, 0, {0x08,0x20,0x46,0x08,0x11,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x11,0x82,0x04 }}, - {16, 0xc3f0, 0, {0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x80,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc400, 0, {0x00,0x45,0x42,0x05,0x40,0xc5,0x50,0x20,0x14,0x08,0x15,0x00,0x04,0x40,0x81,0x50 }}, - {16, 0xc410, 0, {0x20,0x54,0x08,0x11,0x02,0x05,0x00,0x80,0x10,0x20,0x45,0x0c,0x11,0x42,0x04,0x40 }}, - {16, 0xc420, 0, {0x81,0x50,0x20,0x14,0x0c,0x15,0x42,0x04,0x40,0x81,0x10,0x20,0x54,0x08,0x15,0x00 }}, - {16, 0xc430, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x03,0x01,0x50,0xc0,0x44,0x30 }}, - {16, 0xc440, 0, {0x15,0x0c,0x05,0x43,0x01,0x50,0xc0,0x4c,0x30,0x15,0x0c,0x05,0x43,0x21,0x50,0xc0 }}, - {16, 0xc450, 0, {0x54,0x30,0x15,0x0c,0x05,0x43,0x01,0x50,0xc0,0x54,0x30,0x15,0x0c,0x05,0x43,0x01 }}, - {16, 0xc460, 0, {0x50,0xc0,0x54,0x20,0x15,0x0c,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc470, 0, {0x00,0x00,0x08,0x00,0x42,0x00,0x04,0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x00,0x04 }}, - {16, 0xc480, 0, {0x80,0x04,0x20,0x01,0x08,0x00,0x02,0x00,0x10,0x00,0x04,0x00,0x01,0x08,0x00,0x42 }}, - {16, 0xc490, 0, {0x00,0x10,0x80,0x04,0x00,0x01,0x08,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x01,0x00 }}, - {16, 0xc4a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x42,0x02,0x00,0x80,0x84,0x20 }}, - {16, 0xc4b0, 0, {0x20,0x08,0x08,0x02,0x02,0x00,0x80,0x84,0x20,0x20,0x08,0x08,0x02,0x02,0x00,0x80 }}, - {16, 0xc4c0, 0, {0x80,0xa0,0x20,0x28,0x08,0x02,0x02,0x00,0x80,0x80,0x20,0x20,0x28,0x08,0x02,0x02 }}, - {16, 0xc4d0, 0, {0x00,0x80,0x80,0x20,0x20,0x08,0x08,0x00,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc4e0, 0, {0x00,0x45,0x40,0x05,0x60,0x41,0x58,0x00,0x56,0x00,0x15,0x80,0x05,0x60,0x01,0x58 }}, - {16, 0xc4f0, 0, {0x00,0x56,0x00,0x15,0x80,0x05,0x20,0x01,0xd8,0x00,0x56,0x00,0x15,0x80,0x05,0x60 }}, - {16, 0xc500, 0, {0x01,0x58,0x00,0x76,0x00,0x15,0x80,0x05,0x60,0x01,0x58,0x00,0x56,0x00,0x15,0x80 }}, - {16, 0xc510, 0, {0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x40,0x03,0x60,0x00,0xd8,0x00 }}, - {16, 0xc520, 0, {0x26,0x00,0x0d,0x80,0x02,0x60,0x00,0xd8,0x00,0x36,0x00,0x0d,0x80,0x07,0x60,0x01 }}, - {16, 0xc530, 0, {0x5c,0x00,0x36,0x00,0x0d,0x80,0x03,0x60,0x00,0xd8,0x00,0x57,0x00,0x0d,0x80,0x02 }}, - {16, 0xc540, 0, {0x60,0x00,0x98,0x00,0x36,0x00,0x0d,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc550, 0, {0x00,0x00,0x00,0x04,0x30,0x21,0x0c,0x00,0x43,0x00,0x10,0xc0,0x04,0x30,0x01,0x0c }}, - {16, 0xc560, 0, {0x00,0x43,0x00,0x10,0xc0,0x04,0x30,0x01,0x18,0x00,0x43,0x00,0x10,0xc0,0x04,0x30 }}, - {16, 0xc570, 0, {0x01,0x0c,0x00,0x46,0x00,0x10,0xc0,0x04,0x30,0x01,0x0c,0x00,0x43,0x00,0x10,0xc0 }}, - {16, 0xc580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0c,0x00 }}, - {16, 0xc590, 0, {0x03,0x00,0x00,0xc0,0x00,0x35,0x08,0x0c,0x00,0x03,0x00,0x00,0xc6,0x00,0x14,0x00 }}, - {16, 0xc5a0, 0, {0x08,0x00,0x03,0x40,0x00,0xc0,0x00,0x30,0x00,0x0d,0x40,0x02,0x00,0x00,0xc0,0x00 }}, - {16, 0xc5b0, 0, {0x30,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc5c0, 0, {0x00,0x00,0x05,0x01,0x31,0x40,0x4c,0x50,0x13,0x14,0x04,0xc5,0x01,0x31,0xc0,0x4c }}, - {16, 0xc5d0, 0, {0x50,0x13,0x14,0x04,0xc5,0x05,0x31,0x41,0x4c,0x50,0x13,0x14,0x04,0xc5,0x01,0x31 }}, - {16, 0xc5e0, 0, {0x40,0x4c,0x70,0x53,0x14,0x04,0xc5,0x01,0x31,0x40,0x4c,0x40,0x13,0x14,0x04,0xc0 }}, - {16, 0xc5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x05,0x68,0xc1,0x5a,0x30 }}, - {16, 0xc600, 0, {0x56,0x8c,0x15,0xa3,0x05,0x69,0xc1,0x5a,0x30,0x46,0x8c,0x11,0xa7,0x01,0x68,0xc0 }}, - {16, 0xc610, 0, {0x1a,0x30,0x56,0x8c,0x11,0xa3,0x04,0x68,0xc1,0x1a,0x30,0x16,0x8c,0x15,0xa3,0x04 }}, - {16, 0xc620, 0, {0x68,0xc1,0x5a,0x30,0x56,0x8c,0x11,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc630, 0, {0x00,0x00,0x00,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x24,0x00,0x08 }}, - {16, 0xc640, 0, {0x01,0x02,0x00,0x00,0x80,0x00,0x24,0x00,0x08,0x80,0x02,0x60,0x00,0x80,0x00,0x20 }}, - {16, 0xc650, 0, {0x00,0x09,0x40,0x02,0x20,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80 }}, - {16, 0xc660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x44,0x62,0x11,0x18,0x84 }}, - {16, 0xc670, 0, {0x46,0x21,0x11,0x88,0x44,0x62,0x09,0x18,0x84,0x46,0x21,0x11,0x88,0x60,0x62,0x10 }}, - {16, 0xc680, 0, {0x18,0x04,0x46,0x01,0x11,0x88,0x44,0x62,0x11,0x18,0x80,0x06,0x01,0x11,0x88,0x44 }}, - {16, 0xc690, 0, {0x62,0x11,0x18,0x84,0x46,0x21,0x11,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc6a0, 0, {0x00,0x00,0x00,0x45,0x50,0x11,0x54,0x04,0x55,0x01,0x15,0x40,0x44,0x50,0x11,0x54 }}, - {16, 0xc6b0, 0, {0x04,0x45,0x01,0x11,0x40,0x40,0x50,0x10,0x54,0x04,0x45,0x01,0x15,0x40,0x44,0x50 }}, - {16, 0xc6c0, 0, {0x11,0x14,0x00,0x15,0x01,0x15,0x40,0x44,0x50,0x11,0x54,0x04,0x55,0x00,0x11,0x40 }}, - {16, 0xc6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x21,0x42,0x08,0x50,0x82 }}, - {16, 0xc6e0, 0, {0x14,0x20,0x85,0x08,0x21,0x42,0x00,0x50,0x82,0x14,0x20,0x85,0x08,0x20,0x42,0x08 }}, - {16, 0xc6f0, 0, {0x50,0x82,0x15,0x20,0x05,0x48,0x21,0x42,0x08,0x50,0x82,0x14,0x20,0x81,0x40,0x21 }}, - {16, 0xc700, 0, {0x42,0x08,0x50,0x82,0x14,0x20,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc710, 0, {0x00,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x0a,0x01,0x02,0x84,0x40 }}, - {16, 0xc720, 0, {0xa1,0x10,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa0,0x00,0x28,0x00,0x0a,0x01,0x02 }}, - {16, 0xc730, 0, {0x80,0x40,0xb0,0x10,0x28,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x00 }}, - {16, 0xc740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x03,0x53,0x00,0xd4,0xc0 }}, - {16, 0xc750, 0, {0x35,0x30,0x0d,0x4c,0x03,0x53,0x00,0xd4,0xc0,0x35,0x30,0x0d,0x4c,0x03,0x53,0x00 }}, - {16, 0xc760, 0, {0xd4,0xc0,0x21,0x30,0x08,0x4c,0x03,0x53,0x00,0xd4,0xc0,0x35,0x30,0x08,0x4c,0x03 }}, - {16, 0xc770, 0, {0x53,0x00,0xd4,0xc0,0x35,0x30,0x0d,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc780, 0, {0x00,0x00,0x08,0x04,0x70,0x01,0x5c,0x80,0x07,0x20,0x25,0xc9,0x04,0x72,0x01,0x5c }}, - {16, 0xc790, 0, {0x80,0x47,0x20,0x15,0xc8,0x00,0x72,0x05,0xdc,0x80,0x57,0x20,0x15,0xc8,0x05,0x72 }}, - {16, 0xc7a0, 0, {0x01,0x1c,0x90,0x67,0x20,0x15,0xc8,0x05,0x72,0x01,0x1c,0x80,0x57,0x20,0x15,0xc0 }}, - {16, 0xc7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x18,0x48,0xc2,0x12,0x31 }}, - {16, 0xc7c0, 0, {0x84,0x8c,0x61,0x03,0x18,0x40,0xc8,0x12,0x31,0x84,0x8c,0x61,0x03,0x18,0x48,0xc4 }}, - {16, 0xc7d0, 0, {0x10,0x31,0x84,0x0c,0x41,0x23,0x18,0x48,0xc6,0x10,0x30,0x04,0x0c,0x61,0x23,0x18 }}, - {16, 0xc7e0, 0, {0x48,0xc6,0x12,0x30,0x84,0x8c,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc7f0, 0, {0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3 }}, - {16, 0xc800, 0, {0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f }}, - {16, 0xc810, 0, {0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xbd,0x00 }}, - {16, 0xc820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc860, 0, {0x00,0x00,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x09,0x36,0xc2 }}, - {16, 0xc870, 0, {0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b }}, - {16, 0xc880, 0, {0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x2c,0x00 }}, - {16, 0xc890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x3c,0x4c,0xcf,0x13,0x33 }}, - {16, 0xc8a0, 0, {0xc4,0xcc,0xf1,0x33,0x3c,0x4d,0x4e,0x93,0x33,0xc4,0xcc,0xf1,0x2b,0x3c,0x4c,0xcf }}, - {16, 0xc8b0, 0, {0x13,0x33,0xc4,0xcc,0xe9,0x33,0x3c,0x4c,0xcf,0x12,0xb5,0xc4,0xcc,0xf1,0x33,0x3c }}, - {16, 0xc8c0, 0, {0x4c,0xcf,0x13,0x33,0xc4,0xcd,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc8d0, 0, {0x00,0x00,0x3b,0x7e,0x4e,0xc7,0x93,0xb7,0xe4,0xed,0xf9,0x23,0x7e,0x4e,0x47,0x93 }}, - {16, 0xc8e0, 0, {0xb7,0xe4,0xed,0xf9,0x3f,0x7e,0x4e,0xde,0x12,0x37,0xe4,0x8d,0xf9,0x3b,0x7e,0x4e }}, - {16, 0xc8f0, 0, {0xdf,0x93,0xf7,0x84,0x8d,0xf9,0x3b,0x7e,0x4e,0xdf,0x93,0xb1,0xe4,0xed,0xb9,0x00 }}, - {16, 0xc900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x70,0x40,0x9c,0x11 }}, - {16, 0xc910, 0, {0x67,0x04,0x19,0xc3,0x02,0x70,0x40,0x9c,0x10,0x27,0x04,0x09,0xc1,0x02,0x70,0x40 }}, - {16, 0xc920, 0, {0x1c,0x10,0x27,0x14,0x01,0xc1,0x02,0x70,0x40,0x9c,0x50,0x07,0x04,0x09,0xc1,0x02 }}, - {16, 0xc930, 0, {0x70,0x40,0x9c,0x10,0x67,0x14,0x11,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc940, 0, {0x00,0x00,0x04,0x05,0x71,0x01,0x5c,0x40,0x57,0x10,0x15,0xc4,0x05,0x71,0x01,0x5c }}, - {16, 0xc950, 0, {0x40,0x57,0x10,0x15,0xc6,0x05,0x71,0x01,0x5c,0x40,0x57,0x10,0x10,0xc4,0x05,0x71 }}, - {16, 0xc960, 0, {0x01,0x5c,0x64,0x03,0x10,0x55,0xc4,0x05,0x71,0x01,0x5c,0x40,0x57,0x10,0x15,0xc0 }}, - {16, 0xc970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x20,0x80,0x48,0x20 }}, - {16, 0xc980, 0, {0x12,0x08,0x04,0x82,0x01,0x21,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x01,0x20,0x80 }}, - {16, 0xc990, 0, {0x48,0x20,0x12,0x08,0x05,0xc2,0x01,0x20,0x80,0x48,0x24,0x17,0x08,0x04,0x82,0x01 }}, - {16, 0xc9a0, 0, {0x20,0x80,0x48,0x20,0x12,0x08,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xc9b0, 0, {0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x46,0x00,0x11,0x84,0x00,0x60,0x00,0x18 }}, - {16, 0xc9c0, 0, {0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x01,0x18,0x00,0x06,0x10,0x91,0x80,0x00,0x60 }}, - {16, 0xc9d0, 0, {0x00,0x18,0x46,0x46,0x18,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x10,0x01,0x80 }}, - {16, 0xc9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x73,0x01,0x1c,0x80 }}, - {16, 0xc9f0, 0, {0x07,0x20,0x01,0xc8,0x04,0x72,0x01,0x1c,0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x01 }}, - {16, 0xca00, 0, {0x1c,0x80,0x47,0x22,0x11,0xc8,0x04,0x72,0x01,0x1c,0x80,0x07,0x20,0x11,0xc8,0x04 }}, - {16, 0xca10, 0, {0x72,0x01,0x1c,0x80,0x07,0x28,0x11,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xca20, 0, {0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18 }}, - {16, 0xca30, 0, {0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60 }}, - {16, 0xca40, 0, {0x00,0x18,0x00,0x46,0x04,0x01,0x80,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80 }}, - {16, 0xca50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x04,0x22,0x01,0x08,0x80 }}, - {16, 0xca60, 0, {0x02,0x20,0x00,0x90,0x04,0x27,0x81,0x08,0x80,0x42,0x20,0x10,0x98,0x04,0x24,0x01 }}, - {16, 0xca70, 0, {0x08,0x80,0x42,0x48,0x10,0x88,0x04,0x22,0x01,0x09,0x40,0x42,0x60,0x10,0x88,0x04 }}, - {16, 0xca80, 0, {0x22,0x01,0x08,0xc0,0x02,0x40,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xca90, 0, {0x00,0x00,0x2a,0x04,0x4b,0x81,0x12,0xa0,0x04,0xa8,0x01,0x2a,0x04,0x4a,0x81,0x12 }}, - {16, 0xcaa0, 0, {0xa0,0x44,0xa8,0x11,0x2a,0x04,0x48,0x80,0x12,0xa0,0x44,0x88,0x01,0x2a,0x04,0x4a }}, - {16, 0xcab0, 0, {0x81,0x12,0x20,0x04,0xac,0x11,0x2a,0x04,0x4a,0x81,0x12,0xb0,0x44,0x9c,0x11,0x00 }}, - {16, 0xcac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x0c,0x00,0x53,0x00,0x14,0xc0 }}, - {16, 0xcad0, 0, {0x05,0x30,0x01,0x44,0x00,0x53,0x00,0x14,0xc0,0x05,0x30,0x04,0x0c,0x00,0x53,0x00 }}, - {16, 0xcae0, 0, {0x14,0xc0,0x05,0xb0,0x01,0x4c,0x00,0x53,0x00,0x16,0xc0,0x01,0x30,0x01,0x4c,0x00 }}, - {16, 0xcaf0, 0, {0x53,0x00,0x14,0xc0,0x01,0x38,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcb00, 0, {0x08,0xc0,0x00,0x10,0x40,0x00,0x10,0x00,0x04,0x00,0x01,0x10,0x00,0x44,0x80,0x10 }}, - {16, 0xcb10, 0, {0x00,0x04,0x00,0x01,0x10,0x00,0x46,0x00,0x00,0x00,0x04,0x60,0x01,0x00,0x00,0x40 }}, - {16, 0xcb20, 0, {0x00,0x11,0x60,0x02,0x40,0x01,0x00,0x10,0x40,0x00,0x10,0x60,0x01,0x50,0x10,0x40 }}, - {16, 0xcb30, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x40,0x02,0x00,0x00,0x80,0x00 }}, - {16, 0xcb40, 0, {0x20,0x00,0x08,0x08,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00 }}, - {16, 0xcb50, 0, {0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x00,0x00,0x08,0x00,0x02 }}, - {16, 0xcb60, 0, {0x00,0x00,0x80,0x00,0x21,0x00,0x08,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcb70, 0, {0x08,0xc0,0x40,0x04,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01,0x18 }}, - {16, 0xcb80, 0, {0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x01,0xc8,0x00,0x46,0x00,0x19,0x80,0x00,0x60 }}, - {16, 0xcb90, 0, {0x00,0x18,0x00,0x66,0x00,0x11,0x80,0x04,0x60,0x01,0x18,0x00,0x06,0x00,0x11,0x80 }}, - {16, 0xcba0, 0, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x02,0x60,0x00,0x98,0x00 }}, - {16, 0xcbb0, 0, {0x26,0x00,0x09,0x81,0x02,0x60,0x01,0x98,0x00,0x26,0x00,0x09,0x80,0x06,0x62,0x00 }}, - {16, 0xcbc0, 0, {0x48,0x00,0x26,0x20,0x01,0xc0,0x02,0x60,0x01,0x98,0x00,0x07,0x00,0x09,0x80,0x02 }}, - {16, 0xcbd0, 0, {0x60,0x00,0x98,0x00,0x26,0x00,0x11,0x82,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcbe0, 0, {0x40,0x45,0x42,0x04,0x30,0x81,0x0c,0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x85,0x8c }}, - {16, 0xcbf0, 0, {0x20,0x43,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x48,0x11,0x82,0x04,0x30 }}, - {16, 0xcc00, 0, {0x81,0x8d,0x20,0x46,0x08,0x10,0xc2,0x04,0x30,0x81,0x0c,0x20,0x43,0x0c,0x10,0xc0 }}, - {16, 0xcc10, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x00,0x00,0x30,0x00,0x0c,0x00 }}, - {16, 0xcc20, 0, {0x03,0x00,0x00,0xc0,0x00,0x10,0x00,0x0c,0x00,0x03,0x00,0x00,0xc0,0x00,0x30,0x00 }}, - {16, 0xcc30, 0, {0x08,0x00,0x03,0x00,0x00,0x80,0x00,0x30,0x00,0x0c,0x80,0x02,0x00,0x00,0xc0,0x00 }}, - {16, 0xcc40, 0, {0x30,0x00,0x0c,0x00,0x03,0x20,0x00,0xc0,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcc50, 0, {0x40,0x00,0x02,0x00,0x30,0x80,0x0c,0x21,0x03,0x08,0x00,0xc2,0x00,0x30,0x80,0x0c }}, - {16, 0xcc60, 0, {0x20,0x03,0x08,0x00,0xc2,0x04,0x30,0xc1,0x0c,0x20,0x03,0x0c,0x10,0xc2,0x00,0x30 }}, - {16, 0xcc70, 0, {0x80,0x0c,0xb0,0x43,0x08,0x00,0xc2,0x00,0x30,0x80,0x0c,0x20,0x03,0x28,0x10,0xc0 }}, - {16, 0xcc80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x04,0x60,0x81,0x18,0x20 }}, - {16, 0xcc90, 0, {0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0x81 }}, - {16, 0xcca0, 0, {0x18,0x20,0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x06,0x08,0x11,0x82,0x04 }}, - {16, 0xccb0, 0, {0x60,0x81,0x18,0x20,0x46,0x0c,0x11,0xc0,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xccc0, 0, {0x40,0x01,0x42,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x08 }}, - {16, 0xccd0, 0, {0x20,0x02,0x08,0x00,0x82,0x00,0x20,0x80,0x0c,0x20,0x02,0x08,0x00,0xc2,0x00,0x20 }}, - {16, 0xcce0, 0, {0x80,0x08,0x20,0x42,0x08,0x00,0x82,0x00,0x20,0x80,0x08,0x20,0x02,0x08,0x01,0x80 }}, - {16, 0xccf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x42,0x04,0x60,0x81,0x18,0x20 }}, - {16, 0xcd00, 0, {0x46,0x08,0x11,0x82,0x04,0x60,0x80,0x18,0x20,0x46,0x08,0x11,0x82,0x00,0x60,0xc1 }}, - {16, 0xcd10, 0, {0x0c,0x20,0x46,0x0c,0x10,0xc2,0x04,0x60,0x80,0x18,0x30,0x42,0x08,0x11,0x82,0x04 }}, - {16, 0xcd20, 0, {0x60,0x81,0x18,0x20,0x46,0x08,0x10,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcd30, 0, {0x40,0x45,0x40,0x04,0x50,0x01,0x14,0x00,0x45,0x00,0x11,0x40,0x04,0x50,0x00,0x14 }}, - {16, 0xcd40, 0, {0x00,0x45,0x00,0x11,0x40,0x00,0x50,0x00,0x04,0x00,0x45,0x00,0x00,0x40,0x04,0x50 }}, - {16, 0xcd50, 0, {0x00,0x14,0x00,0x01,0x00,0x11,0x40,0x04,0x50,0x01,0x14,0x00,0x45,0x00,0x00,0x42 }}, - {16, 0xcd60, 0, {0x01,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x06,0x00,0x41,0x80,0x10,0x60 }}, - {16, 0xcd70, 0, {0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80 }}, - {16, 0xcd80, 0, {0x10,0x60,0x04,0x18,0x01,0x06,0x00,0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x06,0x00 }}, - {16, 0xcd90, 0, {0x41,0x80,0x10,0x60,0x04,0x18,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcda0, 0, {0x48,0x00,0x02,0x01,0x00,0x80,0x40,0x21,0x10,0x08,0x04,0x02,0x01,0x00,0x80,0x40 }}, - {16, 0xcdb0, 0, {0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x80,0x40,0x21,0x10,0x08,0x04,0x02,0x01,0x00 }}, - {16, 0xcdc0, 0, {0x80,0x40,0x30,0x10,0x08,0x04,0x02,0x11,0x00,0x84,0x40,0x20,0x10,0x08,0x14,0x00 }}, - {16, 0xcdd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x46,0x03,0x51,0x80,0xd4,0x60 }}, - {16, 0xcde0, 0, {0x35,0x18,0x0d,0x46,0x03,0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x46,0x03,0x51,0x80 }}, - {16, 0xcdf0, 0, {0xd4,0x60,0x35,0x10,0x0d,0x46,0x03,0x51,0x80,0xd4,0x40,0x35,0x18,0x0d,0x46,0x03 }}, - {16, 0xce00, 0, {0x51,0x80,0xd4,0x60,0x35,0x18,0x0d,0x40,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xce10, 0, {0x00,0x01,0x46,0x04,0x71,0x81,0x1c,0x60,0x07,0x18,0x11,0xce,0x04,0x71,0x81,0x1c }}, - {16, 0xce20, 0, {0x60,0x47,0x18,0x01,0xc6,0x04,0x71,0x81,0x9c,0x60,0x47,0x18,0x19,0xc6,0x04,0x71 }}, - {16, 0xce30, 0, {0x80,0x1c,0x60,0x67,0x18,0x11,0xc6,0x04,0x71,0x81,0x1c,0x60,0x47,0x18,0x11,0xc0 }}, - {16, 0xce40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x46,0x02,0x71,0x80,0x9c,0x60 }}, - {16, 0xce50, 0, {0x27,0x18,0x09,0xc6,0x06,0x71,0x80,0x1c,0x60,0x27,0x18,0x09,0xc6,0x01,0x31,0x80 }}, - {16, 0xce60, 0, {0x1c,0x60,0x07,0x18,0x09,0xc6,0x02,0x71,0x80,0x9c,0x60,0x07,0x18,0x09,0xc6,0x12 }}, - {16, 0xce70, 0, {0x71,0x80,0x9c,0x60,0x33,0x18,0x01,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xce80, 0, {0x50,0x45,0x46,0x05,0x71,0x81,0x5c,0x60,0x57,0x18,0x15,0xc6,0x05,0x71,0x80,0x5c }}, - {16, 0xce90, 0, {0x60,0x57,0x18,0x15,0xc6,0x01,0x31,0x81,0x0c,0x60,0x17,0x18,0x10,0xc6,0x05,0x71 }}, - {16, 0xcea0, 0, {0x81,0x5c,0x60,0x03,0x18,0x15,0xc6,0x05,0x71,0x81,0x5c,0x60,0x53,0x18,0x18,0x82 }}, - {16, 0xceb0, 0, {0x10,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x12,0x01,0x24,0x80,0x48,0x20 }}, - {16, 0xcec0, 0, {0x12,0x08,0x04,0x82,0x01,0x24,0x80,0x48,0x20,0x12,0x08,0x04,0x82,0x01,0x20,0x80 }}, - {16, 0xced0, 0, {0x58,0x20,0x52,0x0c,0x05,0x82,0x01,0x20,0x80,0x49,0x20,0x02,0x08,0x04,0x82,0x01 }}, - {16, 0xcee0, 0, {0x20,0x80,0x49,0x20,0x12,0x48,0x04,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcef0, 0, {0x40,0x04,0x06,0x00,0x61,0x80,0x18,0x60,0x06,0x18,0x01,0x86,0x04,0x61,0x80,0x18 }}, - {16, 0xcf00, 0, {0x60,0x06,0x18,0x01,0x86,0x00,0x61,0x81,0x48,0x60,0x06,0x18,0x14,0x86,0x00,0x61 }}, - {16, 0xcf10, 0, {0x80,0x18,0x60,0x42,0x18,0x01,0x86,0x00,0x61,0x80,0x18,0x60,0x06,0x18,0x00,0x80 }}, - {16, 0xcf20, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x60,0x04,0x78,0x01,0x1e,0x00 }}, - {16, 0xcf30, 0, {0x47,0x80,0x11,0xe8,0x00,0x78,0x01,0x1e,0x00,0x47,0x80,0x11,0xe0,0x04,0x78,0x01 }}, - {16, 0xcf40, 0, {0x1e,0x00,0x43,0x80,0x11,0xe0,0x04,0x78,0x01,0x1e,0x00,0x03,0x80,0x15,0xe0,0x04 }}, - {16, 0xcf50, 0, {0x78,0x01,0x1e,0x00,0x47,0x80,0x11,0xc0,0x10,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcf60, 0, {0x40,0x01,0x12,0x00,0x64,0x80,0x18,0x20,0x06,0x08,0x01,0x82,0x00,0x64,0x80,0x18 }}, - {16, 0xcf70, 0, {0x20,0x06,0x08,0x01,0x82,0x00,0x60,0x80,0x18,0x30,0x02,0x08,0x01,0x82,0x00,0x60 }}, - {16, 0xcf80, 0, {0x80,0x19,0x30,0x42,0x08,0x00,0x82,0x00,0x60,0x80,0x19,0x20,0x06,0x48,0x01,0x80 }}, - {16, 0xcf90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x42,0x04,0x20,0x81,0x08,0x20 }}, - {16, 0xcfa0, 0, {0x42,0x08,0x10,0x82,0x00,0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x82,0x04,0x20,0x81 }}, - {16, 0xcfb0, 0, {0x08,0x20,0x46,0x08,0x10,0x82,0x04,0x20,0x81,0x08,0x20,0x42,0x08,0x11,0x82,0x04 }}, - {16, 0xcfc0, 0, {0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xcfd0, 0, {0x40,0x45,0x42,0x04,0x40,0x81,0x10,0x20,0x44,0x08,0x11,0x02,0x00,0x40,0x81,0x10 }}, - {16, 0xcfe0, 0, {0x20,0x44,0x08,0x11,0x02,0x04,0x40,0x80,0x10,0x20,0x45,0x08,0x01,0x02,0x04,0x40 }}, - {16, 0xcff0, 0, {0x81,0x10,0x21,0x00,0x0c,0x11,0x02,0x04,0x40,0x81,0x10,0x20,0x44,0x08,0x01,0x00 }}, - {16, 0xd000, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x03,0x00,0x50,0xc0,0x14,0x30 }}, - {16, 0xd010, 0, {0x05,0x0c,0x01,0x43,0x00,0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x43,0x00,0x50,0xc0 }}, - {16, 0xd020, 0, {0x14,0x30,0x05,0x0c,0x01,0x43,0x00,0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x43,0x00 }}, - {16, 0xd030, 0, {0x50,0xc0,0x14,0x30,0x05,0x0c,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd040, 0, {0x40,0x00,0x08,0x00,0x42,0x04,0x10,0x80,0x04,0x20,0x01,0x09,0x00,0x42,0x01,0x10 }}, - {16, 0xd050, 0, {0x80,0x04,0x20,0x01,0x08,0x00,0x42,0x00,0x10,0x00,0x04,0x20,0x01,0x08,0x00,0x42 }}, - {16, 0xd060, 0, {0x00,0x10,0x00,0x04,0x00,0x01,0x08,0x00,0x42,0x00,0x10,0x80,0x04,0x20,0x11,0x00 }}, - {16, 0xd070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x42,0x02,0x00,0x80,0x80,0x20 }}, - {16, 0xd080, 0, {0x20,0x08,0x08,0x02,0x02,0x00,0x80,0x00,0x20,0x20,0x08,0x08,0x02,0x00,0x00,0x80 }}, - {16, 0xd090, 0, {0x80,0xa0,0x00,0x0a,0x08,0x02,0x02,0x00,0x80,0x80,0x34,0x62,0x28,0x08,0x02,0x02 }}, - {16, 0xd0a0, 0, {0x00,0x80,0x80,0x30,0x20,0x0c,0x08,0x00,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd0b0, 0, {0x40,0x01,0x40,0x04,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80,0x04,0x60,0x03,0x18 }}, - {16, 0xd0c0, 0, {0x00,0x46,0x00,0x11,0x80,0x06,0x60,0x01,0x98,0x00,0x46,0x00,0x11,0x80,0x04,0x60 }}, - {16, 0xd0d0, 0, {0x01,0x18,0x00,0x66,0x00,0x11,0x80,0x04,0x60,0x01,0x18,0x00,0x46,0x00,0x11,0x80 }}, - {16, 0xd0e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x00,0x02,0x60,0x00,0x98,0x00 }}, - {16, 0xd0f0, 0, {0x26,0x00,0x09,0x80,0x02,0x64,0x00,0x98,0x00,0x26,0x00,0x19,0x90,0x02,0x60,0x00 }}, - {16, 0xd100, 0, {0x1d,0x00,0x26,0x00,0x01,0xc0,0x02,0x60,0x00,0x99,0x00,0x06,0x40,0x19,0x80,0x02 }}, - {16, 0xd110, 0, {0x60,0x00,0x98,0x00,0x66,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd120, 0, {0x40,0x45,0x60,0x04,0x38,0x01,0x0e,0x00,0x43,0x80,0x10,0xe0,0x04,0x38,0x01,0x0e }}, - {16, 0xd130, 0, {0x00,0x43,0x80,0x10,0xe0,0x04,0x38,0x01,0x1a,0x00,0x43,0x80,0x11,0xa0,0x04,0x38 }}, - {16, 0xd140, 0, {0x01,0x0e,0x00,0x02,0x80,0x40,0xe0,0x04,0x38,0x01,0x0e,0x00,0x43,0x80,0x18,0x80 }}, - {16, 0xd150, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x04,0x01,0x00,0x30,0x40,0x0c,0x10 }}, - {16, 0xd160, 0, {0x03,0x04,0x00,0xc9,0x00,0x30,0x40,0x0c,0x10,0x03,0x04,0x00,0xc1,0x00,0x30,0x40 }}, - {16, 0xd170, 0, {0x08,0x10,0x03,0x04,0x00,0x81,0x00,0x30,0x40,0x0c,0x78,0x02,0x14,0x00,0xc1,0x00 }}, - {16, 0xd180, 0, {0x30,0x40,0x0c,0x10,0x03,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd190, 0, {0x40,0x00,0x05,0x00,0x31,0x40,0x0c,0x50,0x03,0x14,0x00,0xc5,0x00,0x35,0x40,0x0c }}, - {16, 0xd1a0, 0, {0x50,0x03,0x14,0x10,0xd5,0x00,0x31,0x41,0x0d,0x50,0x03,0x14,0x10,0xc5,0x00,0x31 }}, - {16, 0xd1b0, 0, {0x40,0x0d,0x48,0x43,0x54,0x10,0xc5,0x00,0x31,0x40,0x0c,0x40,0x43,0x10,0x00,0xc2 }}, - {16, 0xd1c0, 0, {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x43,0x04,0x60,0xc1,0x18,0x30 }}, - {16, 0xd1d0, 0, {0x46,0x0c,0x11,0x83,0x04,0x61,0xc1,0x18,0x30,0x46,0x0c,0x01,0x87,0x04,0x60,0xc1 }}, - {16, 0xd1e0, 0, {0x18,0x30,0x46,0x08,0x11,0x83,0x04,0x60,0xc1,0x18,0x20,0x06,0x0c,0x01,0x83,0x04 }}, - {16, 0xd1f0, 0, {0x60,0xc1,0x18,0x30,0x46,0x0c,0x11,0x80,0x10,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd200, 0, {0x40,0x01,0x40,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0x00,0x20,0x00,0x08 }}, - {16, 0xd210, 0, {0x00,0x02,0x00,0x00,0x81,0x00,0x20,0x00,0x08,0x80,0x02,0x00,0x00,0xc0,0x00,0x20 }}, - {16, 0xd220, 0, {0x00,0x08,0x40,0x43,0x30,0x00,0x80,0x00,0x20,0x00,0x08,0x00,0x02,0x00,0x00,0x80 }}, - {16, 0xd230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x48,0x44,0x62,0x11,0x18,0x84 }}, - {16, 0xd240, 0, {0x46,0x21,0x11,0x88,0x44,0x63,0x01,0x18,0x84,0x46,0x21,0x01,0x88,0x04,0x62,0x11 }}, - {16, 0xd250, 0, {0x18,0x04,0x46,0x21,0x10,0xc8,0x44,0x62,0x11,0x18,0x05,0x43,0x01,0x81,0x88,0x44 }}, - {16, 0xd260, 0, {0x62,0x11,0x18,0x84,0x46,0x21,0x11,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd270, 0, {0x40,0x45,0x40,0x04,0x50,0x01,0x14,0x04,0x45,0x01,0x11,0x40,0x44,0x50,0x01,0x14 }}, - {16, 0xd280, 0, {0x04,0x45,0x01,0x01,0x40,0x45,0x00,0x10,0x14,0x04,0x45,0x03,0x00,0x40,0x44,0x50 }}, - {16, 0xd290, 0, {0x11,0x14,0x04,0x01,0x05,0x41,0x40,0x44,0x50,0x11,0x14,0x04,0x05,0x01,0x01,0x40 }}, - {16, 0xd2a0, 0, {0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x20,0x42,0x08,0x10,0x82 }}, - {16, 0xd2b0, 0, {0x04,0x20,0x81,0x08,0x00,0x42,0x00,0x10,0x82,0x04,0x20,0x81,0x08,0x00,0x42,0x08 }}, - {16, 0xd2c0, 0, {0x10,0x82,0x05,0x20,0x81,0x08,0x20,0x42,0x08,0x10,0x8a,0x05,0x20,0x05,0x08,0x20 }}, - {16, 0xd2d0, 0, {0x42,0x08,0x10,0x82,0x04,0x22,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd2e0, 0, {0x00,0x00,0x0a,0x01,0x02,0x80,0x40,0xa0,0x10,0x28,0x04,0x02,0x01,0x02,0x80,0x40 }}, - {16, 0xd2f0, 0, {0xa0,0x10,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa0,0x00,0x29,0x04,0x0a,0x01,0x02 }}, - {16, 0xd300, 0, {0x80,0x40,0xa4,0x00,0x28,0x04,0x0a,0x01,0x02,0x80,0x40,0xa8,0x10,0x2b,0x14,0x00 }}, - {16, 0xd310, 0, {0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x45,0x4d,0x03,0x53,0x40,0xd4,0xd0 }}, - {16, 0xd320, 0, {0x35,0x34,0x0d,0x4d,0x03,0x53,0x40,0xd4,0xd0,0x35,0x34,0x0d,0x4d,0x03,0x53,0x40 }}, - {16, 0xd330, 0, {0xd4,0xd0,0x21,0x34,0x4d,0x4d,0x03,0x53,0x40,0xd4,0xd9,0x61,0x34,0x04,0x0d,0x03 }}, - {16, 0xd340, 0, {0x53,0x40,0xc0,0xd8,0x35,0x37,0x0d,0x40,0x11,0x50,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd350, 0, {0x40,0x01,0x48,0x04,0x72,0x00,0x1c,0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x01,0x1c }}, - {16, 0xd360, 0, {0x80,0x47,0x20,0x11,0xc8,0x04,0x72,0x00,0x9c,0x80,0x47,0x20,0x19,0xc8,0x00,0x72 }}, - {16, 0xd370, 0, {0x01,0x1c,0x88,0x67,0x20,0x11,0xc8,0x04,0x72,0x01,0x5c,0x82,0x47,0x22,0x11,0xc0 }}, - {16, 0xd380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x08,0x48,0xc2,0x12,0x31 }}, - {16, 0xd390, 0, {0x84,0x8c,0x61,0x23,0x10,0x40,0xc0,0x12,0x31,0x84,0x8c,0x61,0x03,0x10,0x48,0xc4 }}, - {16, 0xd3a0, 0, {0x10,0x31,0x84,0x8c,0x41,0x23,0x18,0x48,0xc6,0x10,0x30,0x04,0x0c,0x41,0x23,0x18 }}, - {16, 0xd3b0, 0, {0x48,0xc6,0x12,0x30,0x84,0x8c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd3c0, 0, {0x00,0x00,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3 }}, - {16, 0xd3d0, 0, {0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x3f,0xff,0x4f }}, - {16, 0xd3e0, 0, {0xff,0xd3,0xff,0xf4,0xff,0xdd,0x3f,0xff,0x4f,0xff,0xd3,0xff,0xf4,0xff,0xfd,0x00 }}, - {16, 0xd3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd430, 0, {0x00,0x00,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2 }}, - {16, 0xd440, 0, {0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x2c,0xdb,0x0b }}, - {16, 0xd450, 0, {0x36,0xc2,0xcd,0xb0,0xb3,0x4c,0x2c,0xdb,0x0b,0x36,0xc2,0xcd,0xb0,0xb3,0x6c,0x00 }}, - {16, 0xd460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x5c,0x4c,0xd7,0x13,0x33 }}, - {16, 0xd470, 0, {0xc4,0xcc,0xf1,0x33,0x3a,0x4a,0xd6,0x93,0x33,0xc4,0xcc,0xf1,0x2b,0x3a,0x4c,0xcf }}, - {16, 0xd480, 0, {0x13,0x33,0xc4,0xcc,0xe9,0x33,0x3c,0x4c,0xcf,0x12,0xb5,0xa4,0xac,0xc9,0x33,0x3c }}, - {16, 0xd490, 0, {0x4c,0xcf,0x13,0x35,0xc4,0xcd,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd4a0, 0, {0x00,0x00,0x3b,0x7e,0x4e,0xdf,0x93,0xb7,0xe4,0xed,0xf9,0x3b,0x7e,0x4e,0xdf,0x93 }}, - {16, 0xd4b0, 0, {0xb7,0xe4,0xed,0xf9,0x3b,0x7e,0x4e,0xde,0x12,0x37,0xe4,0xed,0xe1,0x3b,0x7e,0x4e }}, - {16, 0xd4c0, 0, {0xdf,0x92,0x31,0x84,0x8d,0xd9,0x3b,0x7e,0x4e,0xdf,0x93,0xb1,0xe4,0xec,0x61,0x00 }}, - {16, 0xd4d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x04,0xa1,0x83,0x2c }}, - {16, 0xd4e0, 0, {0x03,0x0a,0x10,0x82,0xc1,0x34,0x10,0x8f,0x00,0x40,0x09,0x14,0x02,0x03,0x14,0x91 }}, - {16, 0xd4f0, 0, {0x00,0x08,0x42,0x0b,0x18,0x82,0xc4,0x00,0x31,0xca,0x0c,0x52,0x02,0x10,0x80,0x85 }}, - {16, 0xd500, 0, {0x00,0x21,0x82,0x28,0x40,0x0a,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd510, 0, {0x00,0x00,0x0a,0x04,0x02,0x01,0x40,0x80,0x73,0x28,0x10,0x48,0x07,0x06,0x01,0x04 }}, - {16, 0xd520, 0, {0xa4,0x41,0x21,0x14,0x08,0x44,0x06,0x11,0x40,0x80,0x70,0x20,0x14,0x0a,0x04,0x02 }}, - {16, 0xd530, 0, {0x00,0xc8,0x84,0x41,0x21,0x1c,0x08,0x06,0x12,0x01,0xc0,0x80,0x60,0x20,0x14,0x00 }}, - {16, 0xd540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x84,0x04,0x21,0x82,0x08 }}, - {16, 0xd550, 0, {0x53,0x02,0x10,0x80,0xc5,0x00,0x81,0x4a,0x04,0x42,0x02,0x14,0x00,0x04,0x20,0x21 }}, - {16, 0xd560, 0, {0x80,0xa8,0x72,0x22,0x1c,0x88,0xc4,0x06,0xa1,0x42,0x8c,0x52,0x22,0x1c,0x88,0x85 }}, - {16, 0xd570, 0, {0x26,0x21,0xc0,0x88,0x50,0x22,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd580, 0, {0x00,0x00,0x02,0x44,0x00,0x01,0x01,0x00,0x62,0x00,0x10,0x00,0x04,0x00,0x01,0x01 }}, - {16, 0xd590, 0, {0x20,0x40,0x00,0x1c,0x00,0x44,0x04,0x01,0x02,0x20,0x62,0x00,0x1c,0x80,0x04,0x04 }}, - {16, 0xd5a0, 0, {0x80,0x89,0x20,0x50,0x08,0x14,0x80,0x04,0x24,0x01,0xc1,0x00,0x50,0x00,0x18,0x00 }}, - {16, 0xd5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,0x38,0x20,0x04,0x0c }}, - {16, 0xd5c0, 0, {0x31,0x0a,0x00,0x00,0x02,0x18,0x20,0x8c,0xa8,0x10,0x28,0x08,0x88,0xc1,0x14,0x10 }}, - {16, 0xd5d0, 0, {0xc6,0x00,0x22,0x03,0x08,0x02,0x01,0x08,0xb0,0x00,0x0c,0x21,0x02,0x00,0x82,0x80 }}, - {16, 0xd5e0, 0, {0x08,0x00,0x49,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd5f0, 0, {0x00,0x00,0x00,0x01,0x00,0x80,0x08,0x20,0x03,0x00,0x04,0x02,0x43,0x20,0x00,0x40 }}, - {16, 0xd600, 0, {0x00,0x20,0x00,0x04,0x42,0x01,0x10,0x80,0x84,0x20,0x11,0x08,0x04,0x00,0x00,0x00 }}, - {16, 0xd610, 0, {0x00,0x44,0x24,0x20,0x09,0x08,0x40,0x03,0x00,0x90,0xc4,0x20,0x20,0x08,0x0c,0x02 }}, - {16, 0xd620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x81,0x08,0x20,0x04,0x88 }}, - {16, 0xd630, 0, {0x02,0x22,0x08,0x08,0xc3,0x2a,0x90,0x40,0x84,0x10,0x20,0x04,0x80,0xc2,0x26,0x20 }}, - {16, 0xd640, 0, {0x49,0x88,0x22,0x22,0x0c,0x08,0xc1,0x26,0xa0,0xc9,0x8c,0x12,0x2a,0x04,0x88,0x43 }}, - {16, 0xd650, 0, {0x0e,0xa0,0xcb,0x88,0x10,0x22,0x0c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd660, 0, {0x08,0x00,0x0a,0x40,0x32,0x00,0x01,0x80,0x31,0x28,0x00,0x00,0x01,0x12,0x80,0x8d }}, - {16, 0xd670, 0, {0x84,0x00,0x28,0x0c,0x08,0x01,0x32,0x00,0x8c,0x80,0x02,0x20,0x0c,0x08,0x01,0x2e }}, - {16, 0xd680, 0, {0x00,0xc3,0x80,0x02,0x20,0x04,0x08,0x43,0x02,0x00,0x40,0x80,0x10,0x20,0x04,0x02 }}, - {16, 0xd690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x87,0x0a,0x21,0x04,0x88 }}, - {16, 0xd6a0, 0, {0x11,0x2a,0x1c,0x0a,0x06,0x22,0x21,0x40,0xa0,0x42,0x2a,0x10,0x88,0x85,0x0a,0xa1 }}, - {16, 0xd6b0, 0, {0x06,0xa4,0x62,0x22,0x1c,0x0a,0xc4,0x02,0x21,0x80,0x8c,0x52,0x22,0x14,0x48,0x86 }}, - {16, 0xd6c0, 0, {0x22,0x20,0x08,0xa8,0x60,0x2a,0x14,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd6d0, 0, {0x00,0x00,0x08,0x45,0x06,0x01,0x89,0x80,0x63,0x20,0x1c,0x88,0x40,0x34,0x11,0x01 }}, - {16, 0xd6e0, 0, {0xa4,0x50,0x28,0x18,0x48,0x04,0x0e,0x01,0x4b,0x80,0x73,0x28,0x1c,0x8a,0x04,0x06 }}, - {16, 0xd6f0, 0, {0x91,0x49,0x04,0x63,0x20,0x1c,0x8a,0x06,0x26,0x01,0x85,0x80,0x70,0x20,0x18,0x02 }}, - {16, 0xd700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x85,0x00,0xb1,0x45,0x2c }}, - {16, 0xd710, 0, {0x70,0x02,0x14,0xc0,0x07,0x08,0x21,0x49,0x00,0x42,0x01,0x14,0x82,0x05,0x00,0x11 }}, - {16, 0xd720, 0, {0x84,0x00,0x52,0x02,0x1c,0x00,0xc4,0x00,0x21,0xc4,0x2c,0x53,0x02,0x1c,0x02,0x81 }}, - {16, 0xd730, 0, {0x04,0xa1,0xcd,0x08,0x50,0x02,0x14,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd740, 0, {0x08,0x10,0x12,0x04,0x34,0x01,0xcc,0x00,0x73,0x40,0x1c,0x90,0x45,0x04,0x01,0x48 }}, - {16, 0xd750, 0, {0x04,0x60,0x41,0x18,0xc0,0x44,0x04,0x01,0x05,0x04,0x73,0x48,0x14,0x50,0x47,0x34 }}, - {16, 0xd760, 0, {0x01,0x45,0x20,0x62,0x08,0x1c,0xc2,0x04,0x0c,0x81,0xc7,0x00,0x73,0x80,0x18,0xc2 }}, - {16, 0xd770, 0, {0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x84,0x10,0x21,0xcc,0x28 }}, - {16, 0xd780, 0, {0x42,0x02,0x14,0x12,0xc5,0x10,0x21,0x84,0x04,0x40,0x00,0x1c,0x80,0x84,0x00,0x91 }}, - {16, 0xd790, 0, {0x00,0x08,0x73,0x82,0x1c,0x90,0x05,0x0c,0x01,0xcf,0x0c,0x40,0x02,0x14,0x30,0x45 }}, - {16, 0xd7a0, 0, {0x20,0xa1,0xc0,0x08,0x50,0x02,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd7b0, 0, {0x00,0x00,0x00,0x45,0x0c,0x81,0x00,0x00,0x01,0x08,0x08,0x00,0x05,0x18,0x91,0x05 }}, - {16, 0xd7c0, 0, {0x04,0x00,0x01,0x04,0x40,0x06,0x18,0x00,0x02,0x24,0x70,0x40,0x04,0x00,0x40,0x00 }}, - {16, 0xd7d0, 0, {0x01,0xc4,0x24,0x00,0x88,0x04,0x00,0x43,0x10,0x00,0x40,0x20,0x00,0x88,0x00,0x00 }}, - {16, 0xd7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x85,0x24,0x31,0x02,0x0c }}, - {16, 0xd7f0, 0, {0x02,0xc2,0x04,0x10,0xc4,0x28,0x21,0x49,0x0c,0x02,0xc0,0x04,0xb2,0x06,0x1c,0x20 }}, - {16, 0xd800, 0, {0x03,0x08,0x50,0x42,0x0c,0x80,0x01,0x04,0xa1,0x49,0x0c,0x00,0xc2,0x0c,0x10,0x43 }}, - {16, 0xd810, 0, {0x24,0xa0,0xc1,0x08,0x10,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd820, 0, {0x00,0x10,0xa2,0x00,0x20,0x00,0xcd,0x00,0x00,0x40,0x04,0x20,0x01,0x10,0x00,0x09 }}, - {16, 0xd830, 0, {0x04,0x02,0x49,0x0c,0x92,0x07,0x30,0x00,0x00,0x00,0x33,0x08,0x0c,0x92,0x41,0x00 }}, - {16, 0xd840, 0, {0x80,0xcc,0x00,0x00,0x00,0x0c,0x00,0x43,0x28,0x80,0xc2,0x00,0x10,0x00,0x00,0x00 }}, - {16, 0xd850, 0, {0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x50,0x80,0x00,0x00 }}, - {16, 0xd860, 0, {0x10,0x00,0x00,0xf0,0x00,0x10,0x80,0x00,0x00,0x00,0x80,0x00,0xd0,0x80,0x80,0x00 }}, - {16, 0xd870, 0, {0x00,0x00,0x00,0x80,0x10,0x90,0x80,0x80,0x00,0x00,0x00,0x00,0x80,0x10,0x90,0x80 }}, - {16, 0xd880, 0, {0x00,0x00,0x00,0x00,0x00,0xc0,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd890, 0, {0x3c,0x3c,0x10,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0xa0,0x80,0x00,0x00 }}, - {16, 0xd8a0, 0, {0x00,0x00,0x40,0x10,0x90,0x80,0xa0,0x00,0x00,0x00,0x00,0xc0,0x10,0x90,0x80,0xa0 }}, - {16, 0xd8b0, 0, {0x00,0x00,0x00,0x20,0x80,0x10,0x90,0xa0,0xa0,0x00,0x00,0x00,0x00,0x80,0x10,0x8f }}, - {16, 0xd8c0, 0, {0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xc2,0xe4,0x81,0x80,0x3f }}, - {16, 0xd8d0, 0, {0xd9,0xbf,0xd9,0x98,0x71,0x9d,0x42,0x80,0x00,0x26,0x7f,0xe6,0x72,0xab,0x7c,0x3a }}, - {16, 0xd8e0, 0, {0x40,0x00,0x19,0x80,0x26,0x48,0xdd,0x3c,0x91,0xc0,0x26,0x40,0x26,0x40,0x38,0x31 }}, - {16, 0xd8f0, 0, {0xdb,0x61,0xc0,0x19,0x99,0xbf,0xc9,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd900, 0, {0x00,0x00,0x10,0x80,0x10,0x14,0x80,0x06,0x84,0x97,0x96,0x86,0x96,0x06,0x90,0x00 }}, - {16, 0xd910, 0, {0x3f,0xa1,0x28,0x01,0x02,0x90,0x12,0x00,0x80,0x17,0x88,0x16,0x9e,0x90,0x90,0x04 }}, - {16, 0xd920, 0, {0x10,0x00,0x36,0xbe,0xbe,0x9e,0x86,0x16,0x12,0x84,0x80,0x13,0xbe,0x97,0xae,0x80 }}, - {16, 0xd930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x82 }}, - {16, 0xd940, 0, {0x81,0x84,0x21,0x40,0x00,0x00,0x00,0x08,0xa1,0x38,0x01,0x78,0x00,0x00,0x00,0x00 }}, - {16, 0xd950, 0, {0x08,0xb8,0x21,0x72,0x68,0x80,0x00,0x00,0x00,0x08,0x98,0x44,0x88,0x68,0x80,0x00 }}, - {16, 0xd960, 0, {0x00,0x00,0x08,0xb8,0x01,0x78,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd970, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xf7,0xaf,0xff,0xc0 }}, - {16, 0xd980, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff }}, - {16, 0xd990, 0, {0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xbf,0xff,0xc0,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }}, - {16, 0xd9b0, 0, {0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0x40,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff }}, - {16, 0xd9c0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff }}, - {16, 0xd9d0, 0, {0x2f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xd9e0, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0xc0 }}, - {16, 0xd9f0, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff }}, - {16, 0xda00, 0, {0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0x80,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xda10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }}, - {16, 0xda20, 0, {0x00,0x00,0x00,0x3f,0xff,0xbf,0xbf,0xc0,0x00,0x00,0x00,0x00,0x3f,0xdf,0xbf,0xdf }}, - {16, 0xda30, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xef,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x3f,0xdf }}, - {16, 0xda40, 0, {0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xda50, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0x3e,0xaf,0xff,0xc0 }}, - {16, 0xda60, 0, {0x00,0x00,0x00,0x00,0x1f,0xff,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xe7,0xfe }}, - {16, 0xda70, 0, {0xef,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xdf,0xc0,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xda80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }}, - {16, 0xda90, 0, {0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x2f,0xf7,0xff,0xff }}, - {16, 0xdaa0, 0, {0xc0,0x00,0x00,0x00,0x00,0x2f,0xff,0xff,0xdf,0xc0,0x00,0x00,0x00,0x00,0x3f,0xf7 }}, - {16, 0xdab0, 0, {0xdf,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdac0, 0, {0x00,0x00,0x02,0xc4,0x00,0xb1,0xc3,0x2c,0x50,0x09,0x14,0x82,0xc4,0x30,0x91,0xc7 }}, - {16, 0xdad0, 0, {0x24,0x60,0x08,0x1c,0x82,0x07,0x34,0x91,0x4c,0x04,0x43,0x0a,0x10,0xc2,0x84,0x04 }}, - {16, 0xdae0, 0, {0x91,0x84,0x24,0x52,0x0b,0x18,0x02,0xc4,0x24,0xb1,0xc3,0x2c,0x40,0x0a,0x10,0x80 }}, - {16, 0xdaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x02,0x01,0xc4,0x80 }}, - {16, 0xdb00, 0, {0x60,0x20,0x1c,0x08,0x44,0x22,0x01,0xc0,0x84,0x50,0x01,0x9c,0x08,0x07,0x0a,0x01 }}, - {16, 0xdb10, 0, {0xc0,0x84,0x72,0x20,0x1c,0xc8,0x04,0x12,0x11,0x44,0x80,0x41,0x01,0x1c,0x80,0x07 }}, - {16, 0xdb20, 0, {0x08,0x11,0xc4,0x00,0x70,0x00,0x10,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdb30, 0, {0x00,0x00,0x00,0x86,0x2c,0x21,0x4a,0x0c,0x52,0x02,0x1c,0x80,0x04,0x20,0x21,0xca }}, - {16, 0xdb40, 0, {0x10,0x62,0x02,0x1c,0x81,0x47,0x04,0x21,0xc3,0x20,0x51,0x01,0x1c,0x80,0x04,0x2c }}, - {16, 0xdb50, 0, {0x01,0xcb,0x04,0x52,0x03,0x14,0x40,0xc7,0x20,0x31,0xc8,0x0c,0x50,0x22,0x10,0x80 }}, - {16, 0xdb60, 0, {0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x20,0x01,0x89,0x00 }}, - {16, 0xdb70, 0, {0x52,0x00,0x14,0x80,0x04,0x28,0x01,0x45,0x04,0x62,0x00,0x10,0x80,0x46,0x30,0x11 }}, - {16, 0xdb80, 0, {0x0d,0x00,0x42,0x01,0x14,0xc0,0x44,0x00,0x11,0x05,0x00,0x50,0x00,0x1c,0x00,0x44 }}, - {16, 0xdb90, 0, {0x28,0x01,0x49,0x00,0x70,0x00,0x10,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdba0, 0, {0x00,0x00,0x08,0xc0,0x02,0x30,0x0c,0x8c,0x30,0x22,0x08,0x88,0xc2,0x26,0x00,0x08 }}, - {16, 0xdbb0, 0, {0x80,0x20,0x22,0x0c,0x88,0x81,0x02,0x10,0xc4,0x80,0x10,0x22,0x0c,0x08,0x40,0x02 }}, - {16, 0xdbc0, 0, {0x10,0x48,0x88,0x01,0x23,0x04,0xc8,0x42,0x02,0x10,0x46,0x8c,0x12,0x22,0x00,0x00 }}, - {16, 0xdbd0, 0, {0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0x00,0x00,0x80,0xc8,0x20 }}, - {16, 0xdbe0, 0, {0x11,0x09,0x00,0x80,0x41,0x10,0x90,0x08,0x24,0x30,0x08,0x04,0x42,0x41,0x00,0x90 }}, - {16, 0xdbf0, 0, {0xc4,0x20,0x00,0x08,0x04,0x42,0x00,0x10,0x80,0x4c,0x20,0x23,0x09,0x04,0xc2,0x43 }}, - {16, 0xdc00, 0, {0x30,0x80,0x40,0x20,0x11,0x08,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdc10, 0, {0x08,0x00,0x08,0x81,0x02,0x20,0xc9,0x8c,0x12,0x20,0x04,0x48,0x41,0x22,0x00,0x09 }}, - {16, 0xdc20, 0, {0x88,0x30,0x20,0x0c,0x88,0x03,0x0e,0x00,0x49,0x8c,0x10,0x22,0x0c,0x88,0x40,0x2e }}, - {16, 0xdc30, 0, {0x00,0xc9,0x84,0x13,0x21,0x04,0xc8,0xc3,0x22,0x00,0xcb,0x8c,0x32,0x22,0x00,0x00 }}, - {16, 0xdc40, 0, {0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x01,0x02,0x00,0x4b,0x80 }}, - {16, 0xdc50, 0, {0x32,0x21,0x08,0x88,0x41,0x02,0x10,0x0f,0x80,0x10,0x21,0x8c,0x08,0x41,0x02,0x00 }}, - {16, 0xdc60, 0, {0x87,0x84,0x10,0x20,0x04,0x88,0x00,0x02,0x00,0x47,0x80,0x10,0x21,0x0c,0x88,0x41 }}, - {16, 0xdc70, 0, {0x16,0x10,0x46,0x80,0x30,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdc80, 0, {0x00,0x00,0x0a,0xc4,0x22,0xa1,0x08,0xa4,0x72,0x2a,0x14,0x0a,0x85,0x02,0x81,0x84 }}, - {16, 0xdc90, 0, {0xa0,0x42,0x28,0x1c,0x0a,0xc5,0x02,0x91,0x40,0xb8,0x73,0x29,0x10,0xca,0xc4,0x02 }}, - {16, 0xdca0, 0, {0xa1,0x80,0xa4,0x42,0x2a,0x14,0xca,0x85,0x22,0x91,0x80,0xa8,0x70,0x2a,0x18,0x02 }}, - {16, 0xdcb0, 0, {0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x1e,0x01,0xc8,0x80 }}, - {16, 0xdcc0, 0, {0x43,0x20,0x18,0x08,0x45,0x3e,0x01,0x0c,0x80,0x61,0x20,0x9c,0x48,0x06,0x12,0x81 }}, - {16, 0xdcd0, 0, {0xc0,0x80,0x73,0x00,0x10,0x88,0x06,0x02,0x01,0xc8,0x00,0x42,0x20,0x10,0xc8,0x07 }}, - {16, 0xdce0, 0, {0x02,0x11,0xcd,0x80,0x51,0x20,0x14,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdcf0, 0, {0x08,0x00,0x00,0xc4,0x24,0x21,0xc8,0x0c,0x42,0x01,0x14,0x00,0x00,0x28,0x10,0x4c }}, - {16, 0xdd00, 0, {0x08,0x52,0x02,0x14,0x80,0x45,0x24,0x29,0x40,0x04,0x72,0x00,0x10,0xc0,0x05,0x24 }}, - {16, 0xdd10, 0, {0x11,0x44,0x08,0x43,0x01,0x14,0xc0,0x47,0x24,0x20,0x48,0x08,0x72,0x02,0x10,0x00 }}, - {16, 0xdd20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x07,0x10,0x11,0x06,0x00 }}, - {16, 0xdd30, 0, {0x72,0x00,0x18,0xd0,0x46,0x20,0x01,0x4d,0x00,0x71,0x40,0x10,0x50,0x07,0x30,0x11 }}, - {16, 0xdd40, 0, {0xc3,0x00,0x71,0x41,0x10,0xb0,0x05,0x2c,0x01,0x49,0x00,0x43,0x00,0x1c,0x50,0x45 }}, - {16, 0xdd50, 0, {0x30,0x01,0x8c,0x00,0x61,0x40,0x18,0x42,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdd60, 0, {0x00,0x00,0x30,0xc5,0x00,0x21,0xc0,0x0c,0x40,0x01,0x14,0x12,0x44,0x04,0x31,0x84 }}, - {16, 0xdd70, 0, {0x24,0x40,0x80,0x14,0xa1,0xc7,0x00,0x01,0x40,0x08,0x40,0x01,0x14,0x20,0x05,0x20 }}, - {16, 0xdd80, 0, {0x11,0xc0,0x02,0x60,0x82,0x18,0x00,0x87,0x24,0x11,0x40,0x08,0x40,0x42,0x10,0x02 }}, - {16, 0xdd90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0c,0x80,0xc4,0x24 }}, - {16, 0xdda0, 0, {0x31,0x48,0x0c,0x00,0x01,0x08,0xc1,0x41,0x00,0x00,0x49,0x00,0x42,0x03,0x08,0x10 }}, - {16, 0xddb0, 0, {0x80,0x20,0x21,0x09,0x0c,0x02,0x02,0x18,0x80,0xc1,0x24,0x30,0x08,0x0c,0x42,0x01 }}, - {16, 0xddc0, 0, {0x10,0x80,0x83,0x20,0x11,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xddd0, 0, {0x00,0x00,0x10,0xc1,0x04,0x20,0x48,0x0c,0x12,0x42,0x04,0x00,0x83,0x00,0x31,0x48 }}, - {16, 0xdde0, 0, {0x00,0x02,0x41,0x04,0xa0,0x07,0x0c,0x20,0x40,0x00,0x12,0xc2,0x0c,0x80,0xc1,0x20 }}, - {16, 0xddf0, 0, {0x20,0xc8,0x00,0x12,0xc1,0x0c,0xb0,0x41,0x20,0x00,0x49,0x08,0x02,0x42,0x00,0x00 }}, - {16, 0xde00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x80,0x01,0x00,0x10,0x81,0x00 }}, - {16, 0xde10, 0, {0x30,0x40,0x08,0x20,0x03,0x00,0x10,0xc1,0x20,0x02,0x00,0x04,0x80,0x40,0x30,0x90 }}, - {16, 0xde20, 0, {0x01,0x14,0x02,0x40,0x04,0x80,0x40,0x20,0x00,0x09,0x04,0x32,0x01,0x08,0xa0,0x03 }}, - {16, 0xde30, 0, {0x04,0x10,0x08,0x00,0x22,0x40,0x00,0x00,0x04,0x30,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xde40, 0, {0x00,0x00,0x30,0x00,0x10,0x80,0x00,0x00,0x00,0x40,0x00,0xf0,0x00,0x00,0x00,0x00 }}, - {16, 0xde50, 0, {0x00,0x10,0x80,0x00,0xf0,0x00,0x80,0x80,0x00,0x00,0x20,0x00,0x00,0xf0,0x10,0xa0 }}, - {16, 0xde60, 0, {0x00,0x00,0x00,0x20,0x00,0x00,0xf0,0x00,0x10,0x00,0x00,0x00,0x20,0x80,0x00,0xcc }}, - {16, 0xde70, 0, {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x10,0xa0,0x80,0x00,0x00,0x00 }}, - {16, 0xde80, 0, {0x00,0x00,0x10,0x90,0x80,0xc0,0x40,0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x80,0x00 }}, - {16, 0xde90, 0, {0x00,0x00,0x00,0x00,0x10,0x90,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x10,0x90,0x80 }}, - {16, 0xdea0, 0, {0xe0,0x00,0x00,0x00,0x00,0x00,0x10,0x8c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdeb0, 0, {0x00,0x00,0x09,0x4d,0xb1,0xe9,0x00,0x26,0x40,0x2a,0x7f,0xe3,0xf2,0x54,0x98,0xc0 }}, - {16, 0xdec0, 0, {0x3f,0xe6,0x40,0x00,0x01,0x42,0x91,0xd0,0xc0,0x13,0xe5,0x87,0x63,0x83,0xb8,0xcd }}, - {16, 0xded0, 0, {0xf9,0x00,0x26,0x7f,0x00,0x00,0x35,0x2e,0xd5,0x03,0x40,0x3f,0xd9,0xbf,0xb1,0x80 }}, - {16, 0xdee0, 0, {0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x02,0x16,0x14,0x00,0x1c }}, - {16, 0xdef0, 0, {0xa8,0x3f,0x88,0x16,0x00,0x80,0x84,0x80,0x37,0x9e,0xba,0xa0,0x50,0x10,0x02,0x12 }}, - {16, 0xdf00, 0, {0x00,0x17,0x96,0x97,0x26,0x50,0x10,0x10,0x82,0x80,0x1e,0x80,0xde,0xbe,0x94,0x14 }}, - {16, 0xdf10, 0, {0x02,0x10,0x80,0x17,0xbe,0x81,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdf20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xa8,0x44,0x94,0x28,0x80,0x00,0x00,0x00,0x08 }}, - {16, 0xdf30, 0, {0x94,0x21,0x44,0x51,0x00,0x00,0x00,0x00,0x08,0x84,0x42,0x41,0x01,0x00,0x00,0x00 }}, - {16, 0xdf40, 0, {0x00,0x08,0xa1,0x72,0x23,0x41,0x40,0x00,0x00,0x00,0x08,0xb8,0x01,0x78,0x32,0x40 }}, - {16, 0xdf50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }}, - {16, 0xdf60, 0, {0x00,0x00,0x00,0x3f,0xf7,0xfe,0xd7,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xd7,0xdf }}, - {16, 0xdf70, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x37,0x7f }}, - {16, 0xdf80, 0, {0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdf90, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x1e,0xff,0xde,0x77,0xc0 }}, - {16, 0xdfa0, 0, {0x00,0x00,0x00,0x00,0x1f,0xef,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff }}, - {16, 0xdfb0, 0, {0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xdfc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }}, - {16, 0xdfd0, 0, {0x00,0x00,0x00,0x1f,0xcf,0xdf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xbf }}, - {16, 0xdfe0, 0, {0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xbf,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff }}, - {16, 0xdff0, 0, {0xff,0xbf,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe000, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0 }}, - {16, 0xe010, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x1f,0xff,0x1f }}, - {16, 0xe020, 0, {0x7f,0xc0,0x00,0x00,0x00,0x00,0x2f,0xdf,0xff,0xcf,0xc0,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00 }}, - {16, 0xe040, 0, {0x00,0x00,0x00,0x3f,0xbf,0xaf,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff }}, - {16, 0xe050, 0, {0xc0,0x00,0x00,0x00,0x00,0x3e,0xde,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xff }}, - {16, 0xe060, 0, {0xff,0xf7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe070, 0, {0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0x7f,0xff,0xff,0xc0 }}, - {16, 0xe080, 0, {0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x3f,0xfe,0xbe }}, - {16, 0xe090, 0, {0x7f,0xc0,0x00,0x00,0x00,0x00,0x3e,0xff,0xd7,0x7f,0xc0,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe0e0, 0, {0x30,0x00,0x20,0x01,0x02,0x00,0x00,0x00,0x30,0x00,0x43,0x8e,0x00,0x00,0x00,0x00 }}, - {16, 0xe0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe210, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe290, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe320, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe390, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe440, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe450, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe510, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe530, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe590, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe630, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe650, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe680, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe710, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe730, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xe9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xea90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xead0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeb90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xebb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xebc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xebd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xebe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xebf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xec90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xecb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xecc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xecd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xece0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xecf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xed90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeda0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xedb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xedc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xedd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xede0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xedf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xee90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeea0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeeb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeec0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeed0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeee0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeef0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef20, 0, {0x00,0x00,0x00,0x00,0x30,0x00,0x20,0x01,0x02,0x02,0x00,0x00,0x30,0x00,0x43,0x80 }}, - {16, 0xef30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xef90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xefa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xefb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xefc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xefd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xefe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xeff0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf000, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf010, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf020, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf030, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf040, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf050, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf060, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf070, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf080, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf090, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf0f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf100, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf110, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf120, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf130, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf140, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf150, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf160, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf170, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf180, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf190, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf1f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf200, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf210, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf220, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf230, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf240, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf250, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf260, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf270, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf280, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf290, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf2f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf300, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf310, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf320, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf330, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf340, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf350, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf360, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf370, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf380, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf390, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf3f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf400, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf410, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf420, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf430, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf440, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf450, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf460, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf470, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf480, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf490, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf4f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf500, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf510, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf520, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf530, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf540, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf550, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf560, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf570, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf580, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf590, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf5f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf600, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf610, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf620, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf630, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf640, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf650, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf660, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf670, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf680, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf690, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf6f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf700, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf710, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf720, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf730, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf740, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf750, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf760, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf770, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf780, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf790, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf7f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf800, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf810, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf820, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf830, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf840, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf850, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf860, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf870, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf880, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf890, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf8f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf900, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf910, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf920, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf930, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf940, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf950, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf960, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf970, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf980, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf990, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9a0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9b0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9c0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9d0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9e0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xf9f0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfa90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfaa0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfab0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfac0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfad0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfae0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfaf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfb90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfba0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbe0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfbf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc30, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc40, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc80, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfc90, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfca0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfcb0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfcc0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfcd0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfce0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfcf0, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd00, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd10, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd20, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd30, 0, {0x30,0x00,0x00,0x01,0x00,0x00,0x5f,0xa7,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x03 }}, - {16, 0xfd40, 0, {0x30,0x00,0x40,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd50, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd60, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {16, 0xfd70, 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x80,0x01 }}, - {16, 0xfd80, 0, {0x00,0x00,0x00,0x05,0x30,0x00,0xa0,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x01 }}, - {16, 0xfd90, 0, {0x00,0x00,0x6b,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}, - {4, 0xfda0, 0, {0x00,0x00,0x00,0x00 }}, - {0 , 0x0000, 1, {0}} -}; -// VERSION= 1.0.0.191 -// DATE= 2002oct28 -static INTEL_HEX_RECORD g_HexSpdifFw62[] = { - {3,0x0000,0,{0x02,0x45,0xf9}}, - { 3,0x0003,0,{0x02,0x0f,0xfd}}, - { 3,0x000b,0,{0x02,0x4d,0x9b}}, - { 3,0x0013,0,{0x02,0x17,0xfd}}, - { 3,0x001b,0,{0x02,0x4d,0x9e}}, - { 3,0x0023,0,{0x02,0x4d,0x75}}, - { 3,0x002b,0,{0x02,0x46,0xf7}}, - { 3,0x0033,0,{0x02,0x4d,0x6c}}, - { 3,0x003b,0,{0x02,0x4d,0x7c}}, - { 3,0x0043,0,{0x02,0x49,0x00}}, - { 3,0x004b,0,{0x02,0x4d,0x8f}}, - { 3,0x0053,0,{0x02,0x4d,0x83}}, - { 3,0x005b,0,{0x02,0x4d,0x89}}, - { 3,0x0063,0,{0x02,0x4d,0x93}}, - {16,0x0500,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x11,0x01,0x00,0x01,0x01,0x02}}, - {16,0x0510,0,{0x00,0x01,0x09,0x02,0xac,0x01,0x03,0x01,0x00,0x80,0x32,0x09,0x04,0x00,0x00,0x00}}, - {16,0x0520,0,{0x01,0x01,0x00,0x00,0x0a,0x24,0x01,0x00,0x01,0x56,0x00,0x02,0x01,0x02,0x0c,0x24}}, - {16,0x0530,0,{0x02,0x01,0x01,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x0d,0x24,0x06,0x05,0x01,0x02}}, - {16,0x0540,0,{0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x24,0x03,0x02,0x04,0x03,0x00,0x05,0x00}}, - {16,0x0550,0,{0x0c,0x24,0x02,0x03,0x05,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x15,0x24,0x06,0x06}}, - {16,0x0560,0,{0x03,0x02,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00}}, - {16,0x0570,0,{0x00,0x09,0x24,0x03,0x04,0x01,0x01,0x00,0x06,0x00,0x09,0x04,0x01,0x00,0x00,0x01}}, - {16,0x0580,0,{0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01}}, - {16,0x0590,0,{0x00,0x01,0x00,0x11,0x24,0x02,0x01,0x02,0x02,0x10,0x03,0x44,0xac,0x00,0x80,0xbb}}, - {16,0x05a0,0,{0x00,0x00,0x77,0x01,0x09,0x05,0x0a,0x05,0x84,0x01,0x01,0x00,0x8f,0x07,0x25,0x01}}, - {16,0x05b0,0,{0x01,0x00,0x00,0x00,0x09,0x05,0x8f,0x01,0x03,0x00,0x01,0x05,0x00,0x09,0x04,0x01}}, - {16,0x05c0,0,{0x02,0x02,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x01,0x00,0x01,0x00,0x11,0x24,0x02}}, - {16,0x05d0,0,{0x01,0x02,0x03,0x18,0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05}}, - {16,0x05e0,0,{0x0a,0x05,0x46,0x02,0x01,0x00,0x8f,0x07,0x25,0x01,0x01,0x00,0x00,0x00,0x09,0x05}}, - {16,0x05f0,0,{0x8f,0x01,0x03,0x00,0x01,0x05,0x00,0x09,0x04,0x02,0x00,0x00,0x01,0x02,0x00,0x00}}, - {16,0x0600,0,{0x09,0x04,0x02,0x01,0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00}}, - {16,0x0610,0,{0x0e,0x24,0x02,0x01,0x06,0x02,0x10,0x02,0x44,0xac,0x00,0x80,0xbb,0x00,0x09,0x05}}, - {16,0x0620,0,{0x8c,0x05,0x4c,0x02,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04}}, - {16,0x0630,0,{0x02,0x02,0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x0e,0x24}}, - {16,0x0640,0,{0x02,0x01,0x06,0x03,0x18,0x02,0x44,0xac,0x00,0x80,0xbb,0x00,0x09,0x05,0x8c,0x05}}, - {16,0x0650,0,{0x72,0x03,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04,0x02,0x03}}, - {16,0x0660,0,{0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02,0x01}}, - {16,0x0670,0,{0x02,0x02,0x10,0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05,0x8c}}, - {16,0x0680,0,{0x05,0x84,0x01,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x09,0x04,0x02}}, - {16,0x0690,0,{0x04,0x01,0x01,0x02,0x00,0x00,0x07,0x24,0x01,0x04,0x00,0x01,0x00,0x11,0x24,0x02}}, - {16,0x06a0,0,{0x01,0x02,0x03,0x18,0x03,0x44,0xac,0x00,0x80,0xbb,0x00,0x00,0x77,0x01,0x09,0x05}}, - {16,0x06b0,0,{0x8c,0x05,0x46,0x02,0x01,0x00,0x00,0x07,0x25,0x01,0x00,0x02,0x00,0x00,0x04,0x03}}, - {16,0x06c0,0,{0x09,0x04,0x18,0x03,0x45,0x00,0x6d,0x00,0x61,0x00,0x67,0x00,0x69,0x00,0x63,0x00}}, - {16,0x06d0,0,{0x20,0x00,0x47,0x00,0x6d,0x00,0x62,0x00,0x48,0x00,0x22,0x03,0x45,0x00,0x6d,0x00}}, - {16,0x06e0,0,{0x61,0x00,0x67,0x00,0x69,0x00,0x63,0x00,0x20,0x00,0x45,0x00,0x4d,0x00,0x49,0x00}}, - {16,0x06f0,0,{0x20,0x00,0x36,0x00,0x7c,0x00,0x32,0x00,0x20,0x00,0x6d,0x00,0x2a,0x03,0x43,0x00}}, - {16,0x0700,0,{0x6f,0x00,0x6e,0x00,0x66,0x00,0x69,0x00,0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00}}, - {16,0x0710,0,{0x74,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00}}, - {16,0x0720,0,{0x69,0x00,0x6e,0x00,0x67,0x00,0x22,0x03,0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00}}, - {16,0x0730,0,{0x72,0x00,0x66,0x00,0x61,0x00,0x63,0x00,0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00}}, - {10,0x0740,0,{0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x00,0x00}}, - {16,0x074a,0,{0x90,0x76,0x9a,0x74,0x02,0xf0,0xe4,0x90,0x76,0x91,0xf0,0xa3,0xf0,0x90,0x76,0x90}}, - {16,0x075a,0,{0xf0,0x90,0x76,0x93,0xf0,0x90,0x76,0x96,0x74,0x03,0xf0,0x90,0x80,0x03,0xf0,0xe4}}, - {16,0x076a,0,{0x90,0x76,0x97,0xf0,0x90,0x80,0x02,0xf0,0x90,0x76,0x94,0x04,0xf0,0x90,0x80,0x00}}, - {16,0x077a,0,{0xf0,0xe4,0x90,0x76,0x8e,0xf0,0x90,0x76,0x1a,0xf0,0x90,0x76,0x95,0x04,0xf0,0xc2}}, - {16,0x078a,0,{0x2e,0x90,0x7f,0x9b,0xe0,0xff,0x54,0x10,0xff,0x70,0x02,0xc2,0x3f,0x90,0x7f,0x9b}}, - {16,0x079a,0,{0xe0,0xff,0x54,0x10,0xfe,0xff,0xbe,0x10,0x02,0xd2,0x3f,0x90,0x7f,0x9b,0xe0,0xff}}, - {16,0x07aa,0,{0x54,0x20,0xff,0x70,0x02,0xc2,0x3e,0x90,0x7f,0x9b,0xe0,0xff,0x54,0x20,0xfe,0xff}}, - {16,0x07ba,0,{0xbe,0x20,0x02,0xd2,0x3e,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80}}, - {16,0x07ca,0,{0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0}}, - {16,0x07da,0,{0x30,0x3e,0x09,0x90,0x76,0x95,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0}}, - {16,0x07ea,0,{0x54,0xfb,0xf0,0x90,0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0xa2,0x3e,0x92,0x40,0xa2}}, - { 3,0x07fa,0,{0x3f,0x92,0x41}}, - { 1,0x07fd,0,{0x22}}, - { 2,0x07fe,0,{0xd3,0x22}}, - {16,0x0800,0,{0xe4,0x90,0x76,0x31,0xf0,0x90,0x76,0x31,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0f}}, - {16,0x0810,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xed,0xe0,0xfd,0xee,0x6d}}, - {16,0x0820,0,{0x60,0x0e,0xef,0xc3,0x94,0x0b,0x50,0x08,0x90,0x76,0x31,0xe0,0x04,0xf0,0x80,0xd5}}, - {16,0x0830,0,{0xef,0xb4,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x03}}, - {16,0x0840,0,{0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x33,0xf0,0x24}}, - {16,0x0850,0,{0xf0,0x60,0x0a,0x24,0x0e,0x60,0x02,0x81,0x87,0x12,0x4b,0x3e,0x22,0x90,0x7f,0xed}}, - {16,0x0860,0,{0xe0,0x64,0x05,0x70,0x51,0x90,0x76,0x18,0x74,0x05,0xf0,0x90,0x76,0x37,0x74,0x01}}, - {16,0x0870,0,{0xf0,0x90,0x76,0x39,0x74,0x03,0xf0,0x90,0x76,0x21,0xf0,0xe4,0x90,0x76,0x20,0xf0}}, - {16,0x0880,0,{0x90,0x7f,0xea,0xe0,0xf4,0x60,0x2f,0x90,0x76,0x20,0xe0,0xff,0x75,0xf0,0x0a,0xa4}}, - {16,0x0890,0,{0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd}}, - {16,0x08a0,0,{0xee,0x6d,0x60,0x12,0x90,0x76,0x21,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76}}, - {16,0x08b0,0,{0x20,0xe0,0x04,0xf0,0x80,0xd1,0x90,0x7f,0xed,0xe0,0x64,0x06,0x70,0x52,0x90,0x76}}, - {16,0x08c0,0,{0x18,0x74,0x06,0xf0,0x90,0x76,0x37,0x74,0x04,0xf0,0x90,0x76,0x39,0x74,0x0a,0xf0}}, - {16,0x08d0,0,{0x90,0x76,0x21,0xf0,0x90,0x76,0x20,0x74,0x03,0xf0,0x90,0x7f,0xea,0xe0,0xf4,0x60}}, - {16,0x08e0,0,{0x2f,0x90,0x76,0x20,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34}}, - {16,0x08f0,0,{0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd,0xee,0x6d,0x60,0x12,0x90,0x76}}, - {16,0x0900,0,{0x21,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xd1}}, - {16,0x0910,0,{0x90,0x76,0x20,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x0920,0,{0xf5,0x83,0xe0,0x90,0x72,0x29,0xf0,0xe4,0x90,0x76,0x3b,0xf0,0x90,0x76,0x21,0xe0}}, - {16,0x0930,0,{0xfe,0xef,0x6e,0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xeb}}, - {16,0x0940,0,{0xe0,0x14,0x60,0x13,0x14,0x70,0x02,0x21,0xe2,0x24,0x02,0x60,0x02,0x81,0x7f,0x90}}, - {16,0x0950,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x14,0x70,0x7c,0x90,0x7f}}, - {16,0x0960,0,{0xea,0xe0,0xf4,0x70,0x48,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76,0x39}}, - {16,0x0970,0,{0xe0,0xfe,0x90,0x76,0x20,0xe0,0xfd,0xc3,0x9e,0x50,0x2b,0x90,0x76,0x3b,0xe0,0xfe}}, - {16,0x0980,0,{0x04,0xf0,0x74,0xc0,0x2e,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xfe,0xed,0x75}}, - {16,0x0990,0,{0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xee,0xf0,0x90,0x76}}, - {16,0x09a0,0,{0x20,0xe0,0x04,0xf0,0x80,0xc7,0x90,0x76,0x3f,0x74,0x01,0xf0,0x22,0x90,0x7e,0xc0}}, - {16,0x09b0,0,{0xe0,0xfe,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x09c0,0,{0xee,0xf0,0xe0,0xb4,0x01,0x08,0x90,0x76,0x3e,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90}}, - {16,0x09d0,0,{0x76,0x3e,0xf0,0x90,0x76,0x3f,0x74,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01}}, - {16,0x09e0,0,{0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x70,0x02,0x41,0xa3,0x14,0x70,0x02,0x61}}, - {16,0x09f0,0,{0x3f,0x14,0x70,0x02,0x61,0xdb,0x24,0x03,0x60,0x02,0x81,0x77,0x90,0x7f,0xea,0xe0}}, - {16,0x0a00,0,{0xf4,0x70,0x6b,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76,0x39,0xe0,0xff}}, - {16,0x0a10,0,{0x90,0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x50,0x4e,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0}}, - {16,0x0a20,0,{0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a}}, - {16,0x0a30,0,{0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x3b,0xe0}}, - {16,0x0a40,0,{0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee}}, - {16,0x0a50,0,{0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90}}, - {16,0x0a60,0,{0x76,0x20,0xe0,0x04,0xf0,0x80,0xa4,0x90,0x76,0x40,0x74,0x01,0xf0,0x22,0x90,0x7e}}, - {16,0x0a70,0,{0xc0,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82}}, - {16,0x0a80,0,{0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75,0xf0,0x0a}}, - {16,0x0a90,0,{0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x41,0x74}}, - {16,0x0aa0,0,{0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x66,0x90,0x76,0x37,0xe0,0x90,0x76}}, - {16,0x0ab0,0,{0x20,0xf0,0x90,0x76,0x39,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x40,0x02}}, - {16,0x0ac0,0,{0x81,0x8e,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34}}, - {16,0x0ad0,0,{0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4,0x34}}, - {16,0x0ae0,0,{0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5}}, - {16,0x0af0,0,{0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xaf,0xf5}}, - {16,0x0b00,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xa2}}, - {16,0x0b10,0,{0x90,0x7e,0xc0,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xae}}, - {16,0x0b20,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75}}, - {16,0x0b30,0,{0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90}}, - {16,0x0b40,0,{0x7f,0xea,0xe0,0xf4,0x70,0x66,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76}}, - {16,0x0b50,0,{0x39,0xe0,0xff,0x90,0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x40,0x02,0x81,0x8e,0x90,0x76}}, - {16,0x0b60,0,{0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0}}, - {16,0x0b70,0,{0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef}}, - {16,0x0b80,0,{0xf0,0x90,0x76,0x3b,0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e}}, - {16,0x0b90,0,{0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x0ba0,0,{0xf5,0x83,0xef,0xf0,0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xa2,0x90,0x7e,0xc0,0xe0}}, - {16,0x0bb0,0,{0xff,0x90,0x76,0x20,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34}}, - {16,0x0bc0,0,{0x75,0xf5,0x83,0xef,0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24}}, - {16,0x0bd0,0,{0xb1,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4}}, - {16,0x0be0,0,{0x70,0x66,0x90,0x76,0x37,0xe0,0x90,0x76,0x20,0xf0,0x90,0x76,0x39,0xe0,0xff,0x90}}, - {16,0x0bf0,0,{0x76,0x20,0xe0,0xfe,0xc3,0x9f,0x40,0x02,0x81,0x8e,0x90,0x76,0x3b,0xe0,0xff,0x04}}, - {16,0x0c00,0,{0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff,0xee,0x75,0xf0}}, - {16,0x0c10,0,{0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x90,0x76,0x3b}}, - {16,0x0c20,0,{0xe0,0xff,0x04,0xf0,0x74,0xc0,0x2f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0,0xff}}, - {16,0x0c30,0,{0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0}}, - {16,0x0c40,0,{0x90,0x76,0x20,0xe0,0x04,0xf0,0x80,0xa2,0x90,0x7e,0xc0,0xe0,0xff,0x90,0x76,0x20}}, - {16,0x0c50,0,{0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef}}, - {16,0x0c60,0,{0xf0,0x90,0x7e,0xc1,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4}}, - {16,0x0c70,0,{0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90}}, - {15,0x0c80,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22}}, - {16,0x0c8f,0,{0x41,0x76,0x68,0x01,0x41,0x76,0x6a,0x02,0x41,0x76,0x6b,0x0a,0xc1,0x20,0xc1,0x21}}, - { 2,0x0c9f,0,{0xc1,0x2f}}, - { 4,0x0ca1,0,{0x41,0x76,0x23,0x00}}, - {16,0x0ca5,0,{0x41,0x72,0x01,0x01,0x45,0x72,0x05,0x00,0x02,0xc9,0x00,0x00,0x45,0x72,0x0a,0x00}}, - {16,0x0cb5,0,{0x01,0x02,0x03,0x04,0x4d,0x72,0x0f,0xd1,0x00,0xd1,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0cc5,0,{0x28,0x28,0x09,0x00,0x4d,0x72,0x1c,0x01,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}}, - {16,0x0cd5,0,{0x08,0x09,0x0a,0x0b,0x41,0x72,0x2e,0x22,0x41,0x72,0x2f,0x23,0x41,0x72,0x30,0x20}}, - {16,0x0ce5,0,{0x41,0x72,0x31,0x21,0x62,0xd2,0x72,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0cf5,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d05,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d15,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d25,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d35,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d45,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d55,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d65,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x0d75,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01}}, - {16,0x0d85,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}}, - {16,0x0d95,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}}, - {16,0x0da5,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}}, - {16,0x0db5,0,{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}}, - {16,0x0dc5,0,{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}}, - {16,0x0dd5,0,{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}}, - {16,0x0de5,0,{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}}, - {16,0x0df5,0,{0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}}, - {16,0x0e05,0,{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}}, - {16,0x0e15,0,{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}}, - {16,0x0e25,0,{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03}}, - {16,0x0e35,0,{0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}}, - {16,0x0e45,0,{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}}, - {16,0x0e55,0,{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}}, - {16,0x0e65,0,{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04}}, - {16,0x0e75,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}}, - {16,0x0e85,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}}, - {16,0x0e95,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05}}, - {16,0x0ea5,0,{0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x06}}, - {16,0x0eb5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06}}, - {16,0x0ec5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06}}, - {16,0x0ed5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06}}, - {16,0x0ee5,0,{0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08}}, - {16,0x0ef5,0,{0x08,0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d}}, - {16,0x0f05,0,{0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,0x11,0x11,0x11,0x12,0x12,0x12,0x13}}, - {16,0x0f15,0,{0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18}}, - {16,0x0f25,0,{0x18,0x19,0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c}}, - {16,0x0f35,0,{0x1c,0x1d,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x1f,0x20,0x20,0x20}}, - {16,0x0f45,0,{0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x24,0x24,0x25,0x25,0x26,0x26,0x27,0x27}}, - {16,0x0f55,0,{0x28,0x28,0x29,0x29,0x2a,0x2a,0x2b,0x2b,0x2c,0x2c,0x2d,0x2d,0x2e,0x2e,0x2f,0x2f}}, - {16,0x0f65,0,{0x30,0x30,0x31,0x31,0x32,0x32,0x33,0x33,0x34,0x34,0x35,0x35,0x36,0x36,0x37,0x37}}, - {16,0x0f75,0,{0x38,0x38,0x39,0x39,0x3a,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44}}, - {16,0x0f85,0,{0x45,0x46,0x47,0x48,0x49,0x49,0x4a,0x4b,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52}}, - {16,0x0f95,0,{0x53,0x54,0x55,0x55,0x56,0x56,0x57,0x57,0x58,0x5a,0x5b,0x5d,0x5e,0x5f,0x61,0x62}}, - {16,0x0fa5,0,{0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6f,0x71,0x72,0x73,0x74}}, - {16,0x0fb5,0,{0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7e,0x80,0x01,0x37,0x01,0x01,0x38,0x00}}, - { 1,0x0fc5,0,{0x00}}, - {16,0x0fc6,0,{0xe4,0xff,0x74,0x46,0x2f,0xf5,0x82,0xe4,0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x20}}, - {16,0x0fd6,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x4e,0x2f,0xf5,0x82,0xe4}}, - {16,0x0fe6,0,{0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x30,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83}}, - { 6,0x0ff6,0,{0xee,0xf0,0x0f,0xbf,0x08,0xcc}}, - { 1,0x0ffc,0,{0x22}}, - { 3,0x0ffd,0,{0xc2,0x89,0x32}}, - {16,0x1000,0,{0xe4,0x90,0x76,0x2c,0xf0,0x90,0x76,0x2c,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0f}}, - {16,0x1010,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xed,0xe0,0xfd,0xee,0x6d}}, - {16,0x1020,0,{0x60,0x0e,0xef,0xc3,0x94,0x0b,0x50,0x08,0x90,0x76,0x2c,0xe0,0x04,0xf0,0x80,0xd5}}, - {16,0x1030,0,{0xef,0xb4,0x0b,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x03}}, - {16,0x1040,0,{0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x2e,0xf0,0x24}}, - {16,0x1050,0,{0xf0,0x60,0x0a,0x24,0x0f,0x60,0x02,0x81,0x7d,0x12,0x4b,0x1b,0x22,0x90,0x7f,0xed}}, - {16,0x1060,0,{0xe0,0x64,0x05,0x70,0x51,0x90,0x76,0x18,0x74,0x05,0xf0,0x90,0x76,0x38,0x74,0x01}}, - {16,0x1070,0,{0xf0,0x90,0x76,0x3a,0x74,0x03,0xf0,0x90,0x76,0x1c,0xf0,0xe4,0x90,0x76,0x1b,0xf0}}, - {16,0x1080,0,{0x90,0x7f,0xea,0xe0,0xf4,0x60,0x2f,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4}}, - {16,0x1090,0,{0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd}}, - {16,0x10a0,0,{0xee,0x6d,0x60,0x12,0x90,0x76,0x1c,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76}}, - {16,0x10b0,0,{0x1b,0xe0,0x04,0xf0,0x80,0xd1,0x90,0x7f,0xed,0xe0,0x64,0x06,0x70,0x52,0x90,0x76}}, - {16,0x10c0,0,{0x18,0x74,0x06,0xf0,0x90,0x76,0x38,0x74,0x04,0xf0,0x90,0x76,0x3a,0x74,0x0a,0xf0}}, - {16,0x10d0,0,{0x90,0x76,0x1c,0xf0,0x90,0x76,0x1b,0x74,0x03,0xf0,0x90,0x7f,0xea,0xe0,0xf4,0x60}}, - {16,0x10e0,0,{0x2f,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34}}, - {16,0x10f0,0,{0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xea,0xe0,0xfd,0xee,0x6d,0x60,0x12,0x90,0x76}}, - {16,0x1100,0,{0x1c,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x08,0x90,0x76,0x1b,0xe0,0x04,0xf0,0x80,0xd1}}, - {16,0x1110,0,{0xe4,0x90,0x76,0x1e,0xf0,0x90,0x76,0x1c,0xe0,0xff,0x90,0x76,0x1b,0xe0,0xfe,0x6f}}, - {16,0x1120,0,{0x70,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xeb,0xe0,0x14,0x60}}, - {16,0x1130,0,{0x13,0x14,0x70,0x02,0x21,0xbf,0x24,0x02,0x60,0x02,0x81,0x75,0x90,0x7f,0xb4,0xe0}}, - {16,0x1140,0,{0x44,0x01,0xf0,0x22,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x6b,0x90,0x7f,0xea,0xe0}}, - {16,0x1150,0,{0xf4,0x70,0x4a,0x90,0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff}}, - {16,0x1160,0,{0x90,0x76,0x1b,0xe0,0xfd,0xc3,0x9f,0x50,0x2b,0xed,0x75,0xf0,0x0a,0xa4,0x24,0xab}}, - {16,0x1170,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0}}, - {16,0x1180,0,{0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0}}, - {16,0x1190,0,{0x04,0xf0,0x80,0xc7,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0xee,0x75,0xf0}}, - {16,0x11a0,0,{0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0}}, - {16,0x11b0,0,{0x90,0x7f,0xb5,0x74,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90}}, - {16,0x11c0,0,{0x7f,0xe9,0xe0,0x24,0x7e,0x70,0x02,0x41,0x7e,0x14,0x70,0x02,0x61,0x23,0x14,0x70}}, - {16,0x11d0,0,{0x02,0x61,0xc8,0x24,0x03,0x60,0x02,0x81,0x6d,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x6d}}, - {16,0x11e0,0,{0x90,0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff,0x90,0x76,0x1b}}, - {16,0x11f0,0,{0xe0,0xc3,0x9f,0x50,0x4f,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4}}, - {16,0x1200,0,{0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0,0x74,0x00,0x2d}}, - {16,0x1210,0,{0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xee,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xad}}, - {16,0x1220,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfe,0x04,0xf0}}, - {16,0x1230,0,{0x74,0x00,0x2e,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0}}, - {16,0x1240,0,{0x04,0xf0,0x80,0xa4,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0x90,0x76,0x1b}}, - {16,0x1250,0,{0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0}}, - {16,0x1260,0,{0x90,0x7f,0x00,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x1270,0,{0xf5,0x83,0xe0,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f}}, - {16,0x1280,0,{0xea,0xe0,0xf4,0x70,0x6d,0x90,0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a}}, - {16,0x1290,0,{0xe0,0xff,0x90,0x76,0x1b,0xe0,0xc3,0x9f,0x50,0x4f,0xe0,0xff,0x75,0xf0,0x0a,0xa4}}, - {16,0x12a0,0,{0x24,0xae,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x76,0x1e,0xe0,0xfd}}, - {16,0x12b0,0,{0x04,0xf0,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xee,0xf0,0xef,0x75}}, - {16,0x12c0,0,{0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76}}, - {16,0x12d0,0,{0x1e,0xe0,0xfe,0x04,0xf0,0x74,0x00,0x2e,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef}}, - {16,0x12e0,0,{0xf0,0x90,0x76,0x1b,0xe0,0x04,0xf0,0x80,0xa4,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5}}, - {16,0x12f0,0,{0xf0,0x22,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4}}, - {16,0x1300,0,{0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xaf}}, - {16,0x1310,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74}}, - {16,0x1320,0,{0x02,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x6d,0x90,0x76,0x38,0xe0,0x90,0x76}}, - {16,0x1330,0,{0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff,0x90,0x76,0x1b,0xe0,0xc3,0x9f,0x50,0x4f,0xe0}}, - {16,0x1340,0,{0xff,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe}}, - {16,0x1350,0,{0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0x7f,0xf5}}, - {16,0x1360,0,{0x83,0xee,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x1370,0,{0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfe,0x04,0xf0,0x74,0x00,0x2e,0xf5,0x82,0xe4}}, - {16,0x1380,0,{0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0,0x04,0xf0,0x80,0xa4,0x90,0x76}}, - {16,0x1390,0,{0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0x90,0x76,0x1b,0xe0,0xff,0x75,0xf0,0x0a,0xa4}}, - {16,0x13a0,0,{0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0xef,0x75}}, - {16,0x13b0,0,{0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x01}}, - {16,0x13c0,0,{0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xf4,0x70,0x6d,0x90}}, - {16,0x13d0,0,{0x76,0x38,0xe0,0x90,0x76,0x1b,0xf0,0x90,0x76,0x3a,0xe0,0xff,0x90,0x76,0x1b,0xe0}}, - {16,0x13e0,0,{0xc3,0x9f,0x50,0x4f,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34}}, - {16,0x13f0,0,{0x75,0xf5,0x83,0xe0,0xfe,0x90,0x76,0x1e,0xe0,0xfd,0x04,0xf0,0x74,0x00,0x2d,0xf5}}, - {16,0x1400,0,{0x82,0xe4,0x34,0x7f,0xf5,0x83,0xee,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5}}, - {16,0x1410,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x76,0x1e,0xe0,0xfe,0x04,0xf0,0x74}}, - {16,0x1420,0,{0x00,0x2e,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xef,0xf0,0x90,0x76,0x1b,0xe0,0x04}}, - {16,0x1430,0,{0xf0,0x80,0xa4,0x90,0x76,0x1e,0xe0,0x90,0x7f,0xb5,0xf0,0x22,0x90,0x76,0x1b,0xe0}}, - {16,0x1440,0,{0xff,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90}}, - {16,0x1450,0,{0x7f,0x00,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x1460,0,{0x83,0xe0,0x90,0x7f,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x22,0x90,0x7f,0xb4}}, - {16,0x1470,0,{0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4}}, - { 5,0x1480,0,{0xe0,0x44,0x01,0xf0,0x22}}, - {16,0x1485,0,{0x74,0x00,0xf5,0x86,0x90,0xfd,0xa5,0x7c,0x05,0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9}}, - { 1,0x1495,0,{0x22}}, - {16,0x1496,0,{0x90,0x7f,0xd6,0xe0,0x44,0x80,0xf0,0x43,0x87,0x01,0x00,0x00,0x00,0x00,0x00,0x22}}, - {16,0x14a6,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0x8d,0xe0,0xc0,0xe0}}, - {16,0x14b6,0,{0x8c,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x05,0x86,0xc0,0x84,0xc0,0x85,0x7d,0x00}}, - {16,0x14c6,0,{0x90,0x7f,0xe3,0x74,0x7b,0xf0,0xa3,0x74,0x80,0xf0,0x7c,0x11,0x90,0x7f,0x99,0xe0}}, - {16,0x14d6,0,{0x54,0x40,0xdc,0x03,0x02,0x14,0xf3,0xb4,0x00,0x13,0x90,0x7f,0xe2,0x74,0x40,0xf0}}, - {16,0x14e6,0,{0x90,0x7f,0xe5,0xf0,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x02,0x14,0xd2,0x90,0x76,0x90}}, - {16,0x14f6,0,{0xe0,0xb4,0x01,0x12,0x90,0x76,0x8f,0xe0,0x2d,0xfd,0x90,0x7f,0xe2,0x74,0x80,0xf0}}, - {16,0x1506,0,{0x90,0x7f,0x6c,0x02,0x15,0x57,0xb4,0x02,0x12,0x90,0x76,0x8f,0xe0,0x2d,0xfd,0x90}}, - {16,0x1516,0,{0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f,0x6c,0x02,0x15,0x96,0xb4,0x03,0x12,0x90,0x76}}, - {16,0x1526,0,{0x8f,0xe0,0x2d,0xfd,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f,0x6c,0x02,0x15,0xe1}}, - {16,0x1536,0,{0xb4,0x04,0x12,0x90,0x76,0x8f,0xe0,0x2d,0xfd,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90}}, - {16,0x1546,0,{0x7f,0x6c,0x02,0x16,0x10,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f,0x6c,0x02,0x16}}, - {16,0x1556,0,{0x40,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xdd,0xf2,0x7d}}, - {16,0x1566,0,{0x02,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x54,0x04,0xb4}}, - {16,0x1576,0,{0x00,0x05,0x05,0x86,0x02,0x16,0x40,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x05,0x86,0xf0}}, - {16,0x1586,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xdd,0xd4,0x02,0x16,0x40}}, - {16,0x1596,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}}, - {16,0x15a6,0,{0xf0,0xf0,0xdd,0xec,0x7d,0x02,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f}}, - {16,0x15b6,0,{0x9b,0xe0,0x54,0x04,0xb4,0x00,0x05,0x05,0x86,0x02,0x16,0x40,0x90,0x7f,0xe2,0x74}}, - {16,0x15c6,0,{0x80,0xf0,0x05,0x86,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}}, - { 6,0x15d6,0,{0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}}, - {16,0x15dc,0,{0xdd,0xce,0x02,0x16,0x40,0xf0,0xf0,0xf0,0xf0,0xdd,0xfa,0x7d,0x02,0x05,0x86,0x90}}, - {16,0x15ec,0,{0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x54,0x04,0xb4,0x00,0x05,0x05,0x86}}, - {16,0x15fc,0,{0x02,0x16,0x40,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x05,0x86,0xf0,0xf0,0xf0,0xf0,0xdd}}, - {16,0x160c,0,{0xdc,0x02,0x16,0x40,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xdd,0xf8,0x7d,0x02,0x05,0x86}}, - {16,0x161c,0,{0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x54,0x04,0xb4,0x00,0x05,0x05}}, - {16,0x162c,0,{0x86,0x02,0x16,0x40,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x05,0x86,0xf0,0xf0,0xf0,0xf0}}, - {16,0x163c,0,{0xf0,0xf0,0xdd,0xda,0x90,0x7f,0xe2,0x74,0x00,0xf0,0xd0,0x85,0xd0,0x84,0x05,0x86}}, - {16,0x164c,0,{0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xfc,0xd0,0xe0,0xfd,0xd0,0xe0,0xfe,0xd0,0xe0,0xff}}, - { 5,0x165c,0,{0xd0,0xe0,0xd0,0xd0,0x22}}, - {16,0x1661,0,{0xc0,0xd0,0xc0,0xe0,0xc0,0x82,0xc0,0x83,0x90,0x76,0x7c,0xe0,0x90,0x7f,0x6f,0xf0}}, - {16,0x1671,0,{0x90,0x76,0x7d,0xe0,0x90,0x7f,0x6f,0xf0,0x90,0x76,0x7e,0xe0,0x90,0x7f,0x6f,0xf0}}, - { 9,0x1681,0,{0xd0,0x83,0xd0,0x82,0xd0,0xe0,0xd0,0xd0,0x22}}, - {16,0x168a,0,{0xc0,0xd0,0xc0,0xe0,0x8f,0xe0,0xc0,0xe0,0x8e,0xe0,0xc0,0xe0,0xc0,0x82,0xc0,0x83}}, - {16,0x169a,0,{0x05,0x86,0xc0,0x84,0xc0,0x85,0x90,0x76,0x87,0xe0,0xff,0xbf,0x00,0x03,0x02,0x17}}, - {16,0x16aa,0,{0x01,0x90,0x7f,0x96,0xe0,0x44,0x80,0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x7f}}, - {16,0x16ba,0,{0x62,0xe0,0x05,0x86,0x90,0x7f,0xe2,0x74,0x00,0xf0,0x90,0x7f,0x96,0xe0,0x54,0x7f}}, - {16,0x16ca,0,{0xf0,0x90,0x7f,0xe2,0x74,0x80,0xf0,0x90,0x76,0x8e,0xe0,0xb4,0x01,0x05,0x05,0x86}}, - {16,0x16da,0,{0x02,0x16,0xf6,0xb4,0x02,0x05,0x05,0x86,0x02,0x16,0xeb,0x05,0x86,0x02,0x16,0xfb}}, - {16,0x16ea,0,{0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xdf,0xf8,0x02,0x16,0xfb,0xe0,0xe0,0xe0,0xe0,0xdf}}, - {16,0x16fa,0,{0xfa,0x90,0x7f,0xe2,0x74,0x00,0xf0,0xd0,0x85,0xd0,0x84,0x05,0x86,0xd0,0x83,0xd0}}, - {12,0x170a,0,{0x82,0xd0,0xe0,0xfe,0xd0,0xe0,0xff,0xd0,0xe0,0xd0,0xd0,0x22}}, - {16,0x1716,0,{0xc0,0x82,0xc0,0x83,0xc0,0xe0,0xe8,0xc0,0xe0,0x78,0xd1,0xe8,0x14,0xf8,0x70,0xfb}}, - {10,0x1726,0,{0xd0,0xe0,0xf8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0x22}}, - {16,0x1730,0,{0xc0,0x82,0xc0,0x83,0xc0,0xe0,0xe8,0xc0,0xe0,0x78,0x78,0xe8,0x14,0xf8,0x70,0xfb}}, - {10,0x1740,0,{0xd0,0xe0,0xf8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0x22}}, - { 7,0x174a,0,{0x90,0x7f,0xc5,0x74,0x02,0xf0,0x22}}, - {16,0x1751,0,{0x90,0x7e,0xc0,0xe0,0x90,0x76,0x45,0xf0,0x90,0x7e,0xc1,0xe0,0x90,0x76,0x44,0xf0}}, - {16,0x1761,0,{0x90,0x7e,0xc2,0xe0,0x90,0x76,0x43,0xf0,0xb4,0x00,0x03,0x02,0x17,0x78,0x90,0x76}}, - {16,0x1771,0,{0x19,0x74,0x03,0xf0,0x02,0x17,0x8e,0x90,0x76,0x44,0xe0,0xb4,0xbb,0x09,0x90,0x76}}, - {16,0x1781,0,{0x19,0x74,0x02,0xf0,0x02,0x17,0x8e,0x90,0x76,0x19,0x74,0x01,0xf0,0x90,0x76,0x42}}, - { 3,0x1791,0,{0xe4,0xf0,0x22}}, - { 4,0x1794,0,{0x8d,0x29,0x8b,0x2a}}, - {16,0x1798,0,{0x12,0x49,0xff,0xea,0x49,0x60,0x57,0x12,0x36,0x92,0x7e,0x00,0x29,0xff,0xee,0x3a}}, - {16,0x17a8,0,{0xc9,0xef,0xc9,0x75,0x2b,0xff,0xf5,0x2c,0x89,0x2d,0xab,0x2b,0xaa,0x2c,0xa9,0x2d}}, - {16,0x17b8,0,{0x90,0x00,0x01,0x12,0x36,0xab,0xff,0x64,0x04,0x60,0x05,0xef,0x64,0x05,0x70,0x2e}}, - {16,0x17c8,0,{0xef,0xb4,0x04,0x15,0x90,0x00,0x02,0x12,0x36,0xab,0x65,0x29,0x70,0x0b,0x90,0x00}}, - {16,0x17d8,0,{0x03,0x12,0x36,0xab,0x65,0x2a,0x70,0x01,0x22,0x12,0x36,0x92,0x7e,0x00,0x29,0xff}}, - {16,0x17e8,0,{0xee,0x3a,0xc9,0xef,0xc9,0x75,0x2b,0xff,0xf5,0x2c,0x89,0x2d,0x80,0xbc,0x7b,0x00}}, - { 4,0x17f8,0,{0x7a,0x00,0x79,0x00}}, - { 1,0x17fc,0,{0x22}}, - { 3,0x17fd,0,{0xc2,0x8b,0x32}}, - {16,0x1800,0,{0x90,0x76,0x90,0xe0,0x14,0x60,0x37,0x14,0x70,0x02,0x01,0xd8,0x14,0x70,0x02,0x21}}, - {16,0x1810,0,{0x72,0x14,0x70,0x02,0x41,0x3b,0x24,0x04,0x60,0x02,0x61,0x03,0x90,0x7f,0xfc,0x74}}, - {16,0x1820,0,{0xcc,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x95,0xe0,0x44,0x01,0xf0,0x54}}, - {16,0x1830,0,{0x05,0xf0,0x90,0x80,0x01,0xf0,0xe4,0x90,0x76,0x1a,0xf0,0xc2,0x2e,0x22,0x90,0x76}}, - {16,0x1840,0,{0x95,0xe0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x30,0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80}}, - {16,0x1850,0,{0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90,0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90}}, - {16,0x1860,0,{0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x22,0x90}}, - {16,0x1870,0,{0x7f,0xfc,0x74,0x74,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b}}, - {16,0x1880,0,{0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80}}, - {16,0x1890,0,{0xf0,0xef,0xb4,0x02,0x22,0x90,0x7f,0xfc,0x74,0x68,0xf0,0x90,0x7f,0xff,0x74,0xfc}}, - {16,0x18a0,0,{0xf0,0x90,0x76,0x8f,0x74,0x2f,0xf0,0x90,0x76,0x97,0xe0,0x44,0x02,0xf0,0xe4,0x90}}, - {16,0x18b0,0,{0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe}}, - {16,0x18c0,0,{0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfb}}, - {16,0x18d0,0,{0xf0,0x90,0x80,0x02,0xf0,0xd2,0x2e,0x22,0x90,0x76,0x95,0xe0,0x54,0xfe,0xf0,0x44}}, - {16,0x18e0,0,{0x02,0xf0,0x30,0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0,0x54}}, - {16,0x18f0,0,{0xfb,0xf0,0x90,0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90,0x76,0x95,0xe0,0x90,0x80,0x01}}, - {16,0x1900,0,{0xf0,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x22,0x90,0x7f,0xfc,0x74,0x30,0xf0,0x90}}, - {16,0x1910,0,{0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b,0xf0,0x90,0x76,0x97,0xe0,0x54}}, - {16,0x1920,0,{0xfd,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0xef,0xb4,0x02,0x22,0x90}}, - {16,0x1930,0,{0x7f,0xfc,0x74,0x1c,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2f}}, - {16,0x1940,0,{0xf0,0x90,0x76,0x97,0xe0,0x44,0x02,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80}}, - {16,0x1950,0,{0xf0,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97}}, - {16,0x1960,0,{0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfb,0xf0,0x90,0x80,0x02,0xf0,0xd2}}, - {16,0x1970,0,{0x2e,0x22,0x90,0x76,0x95,0xe0,0x44,0x01,0xf0,0x44,0x02,0xf0,0x44,0x08,0xf0,0x30}}, - {16,0x1980,0,{0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90}}, - {16,0x1990,0,{0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90,0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x90,0x76}}, - {16,0x19a0,0,{0x19,0xe0,0xff,0xb4,0x01,0x25,0x90,0x7f,0xfc,0x74,0xcc,0xf0,0x90,0x7f,0xff,0x74}}, - {16,0x19b0,0,{0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0x54}}, - {16,0x19c0,0,{0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0xef,0xb4,0x02,0x25,0x90}}, - {16,0x19d0,0,{0x7f,0xfc,0x74,0xc8,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2f}}, - {16,0x19e0,0,{0xf0,0x90,0x76,0x97,0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0}}, - {16,0x19f0,0,{0x90,0x76,0x80,0xf0,0xef,0xb4,0x03,0x25,0x90,0x7f,0xfc,0x74,0x98,0xf0,0x90,0x7f}}, - {16,0x1a00,0,{0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x5f,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd}}, - {16,0x1a10,0,{0xf0,0x44,0x04,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0x30,0x3f,0x09}}, - {16,0x1a20,0,{0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0}}, - {16,0x1a30,0,{0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0xd2,0x2e,0x22,0x90,0x76,0x95,0xe0,0x54}}, - {16,0x1a40,0,{0xfe,0xf0,0x44,0x02,0xf0,0x44,0x08,0xf0,0x30,0x3e,0x06,0xe0,0x44,0x04,0xf0,0x80}}, - {16,0x1a50,0,{0x07,0x90,0x76,0x95,0xe0,0x54,0xfb,0xf0,0x90,0x76,0x1a,0xe0,0xb4,0x01,0x08,0x90}}, - {16,0x1a60,0,{0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x25,0x90}}, - {16,0x1a70,0,{0x7f,0xfc,0x74,0xb4,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2b}}, - {16,0x1a80,0,{0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0}}, - {16,0x1a90,0,{0x90,0x76,0x80,0xf0,0xef,0xb4,0x02,0x25,0x90,0x7f,0xfc,0x74,0xb0,0xf0,0x90,0x7f}}, - {16,0x1aa0,0,{0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f,0x74,0x2f,0xf0,0x90,0x76,0x97,0xe0,0x44,0x02}}, - {16,0x1ab0,0,{0xf0,0x54,0xfb,0xf0,0xe4,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0xef,0xb4,0x03}}, - {16,0x1ac0,0,{0x25,0x90,0x7f,0xfc,0x74,0x68,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x8f}}, - {16,0x1ad0,0,{0x74,0x5f,0xf0,0x90,0x76,0x97,0xe0,0x54,0xfd,0xf0,0x44,0x04,0xf0,0xe4,0x90,0x76}}, - {16,0x1ae0,0,{0x81,0xf0,0x90,0x76,0x80,0xf0,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0}}, - {16,0x1af0,0,{0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02}}, - { 4,0x1b00,0,{0xf0,0xd2,0x2e,0x22}}, - {16,0x1b04,0,{0x30,0x2c,0x38,0xc2,0x2c,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x0e,0x90,0x76,0x7c}}, - {16,0x1b14,0,{0x74,0xc0,0xf0,0xa3,0x74,0x14,0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0d,0xe4}}, - {16,0x1b24,0,{0x90,0x76,0x7c,0xf0,0xa3,0x74,0x10,0xf0,0xa3,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0b}}, - {12,0x1b34,0,{0xe4,0x90,0x76,0x7c,0xf0,0xa3,0x74,0x18,0xf0,0xa3,0xf0,0x22}}, - {16,0x1b40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1b50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1b60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1b70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1b80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1b90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ba0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1bb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1bc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1bd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1be0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1bf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1c90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ca0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1cb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1cc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1cd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ce0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1cf0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1d90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1da0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1db0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1dc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1dd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1de0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1df0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e00,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e10,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e20,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e30,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1e90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ea0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {14,0x1eb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ebe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ece,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ede,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1eee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1efe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f0e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f1e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f2e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - { 2,0x1f3e,0,{0x00,0x00}}, - {16,0x1f40,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f50,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f60,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f70,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f80,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1f90,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1fa0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1fb0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1fc0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1fd0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1fe0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x1ff0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2000,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2010,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2020,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2030,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2040,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2050,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2060,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2070,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2080,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2090,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x20a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x20b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x20c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x20d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x20e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x20f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2100,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2110,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2120,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2130,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2140,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2150,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2160,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2170,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2180,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2190,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x21a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x21b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x21c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x21d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x21e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x21f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2200,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2210,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2220,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2230,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2240,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2250,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2260,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2270,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2280,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2290,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x22a0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x22b0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x22c0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x22d0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x22e0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x22f0,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2300,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2310,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2320,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2330,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2340,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2350,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x2360,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {14,0x2370,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x237e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x238e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x239e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x23ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x23be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x23ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x23de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x23ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x23fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x240e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x241e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x242e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x243e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x244e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x245e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x246e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x247e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x248e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x249e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x24ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x24be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x24ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x24de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x24ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x24fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x250e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x251e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x252e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x253e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x254e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x255e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x256e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x257e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x258e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x259e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x25ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x25be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x25ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x25de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x25ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x25fe,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x260e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x261e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x262e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x263e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x264e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x265e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x266e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x267e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x268e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x269e,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x26ae,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x26be,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x26ce,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x26de,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {14,0x26ee,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x26fc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x270c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x271c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x272c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x273c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x274c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x275c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x276c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x277c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x278c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x279c,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x27ac,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x27bc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x27cc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x27dc,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - {16,0x27ec,0,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, - { 5,0x27fc,0,{0x00,0x00,0x00,0x00,0x22}}, - {16,0x2801,0,{0xc2,0x20,0xc2,0x21,0xc2,0x2a,0x90,0x7f,0xe8,0xe0,0x12,0x37,0xf9,0x28,0x30,0x00}}, - {16,0x2811,0,{0x28,0x8c,0x01,0x28,0xa2,0x02,0x2a,0x1f,0x21,0x2a,0x6a,0x22,0x29,0x3d,0x80,0x29}}, - {16,0x2821,0,{0x7d,0x81,0x29,0xd1,0x82,0x2a,0x84,0xa1,0x2a,0xba,0xa2,0x00,0x00,0x2a,0xbf,0x90}}, - {16,0x2831,0,{0x7f,0xe9,0xe0,0x14,0x60,0x11,0x24,0xfe,0x60,0x28,0x24,0xfe,0x60,0x3b,0x24,0xfc}}, - {16,0x2841,0,{0x70,0x40,0x12,0x4b,0xa0,0x41,0xcb,0x12,0x4d,0xa7,0x40,0x02,0x41,0xcb,0x90,0x7f}}, - {16,0x2851,0,{0xea,0xe0,0xb4,0x01,0x04,0xc2,0x22,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0}}, - {16,0x2861,0,{0x41,0xcb,0x12,0x4d,0xa9,0x90,0x7f,0xea,0xe0,0xb4,0x01,0x04,0xd2,0x22,0x41,0xcb}}, - {16,0x2871,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0}}, - {16,0x2881,0,{0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xe9,0xe0,0x24}}, - {16,0x2891,0,{0xf5,0x70,0x05,0x12,0x48,0x00,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41}}, - {16,0x28a1,0,{0xcb,0x90,0x7f,0xe9,0xe0,0x24,0xfd,0x60,0x54,0x24,0x02,0x60,0x02,0x21,0x34,0x12}}, - {16,0x28b1,0,{0x4d,0xa7,0x40,0x02,0x41,0xcb,0x90,0x7f,0xea,0xe0,0x70,0x38,0x90,0x7f,0xec,0xe0}}, - {16,0x28c1,0,{0xf4,0x54,0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4}}, - {16,0x28d1,0,{0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0x54,0x80,0xff}}, - {16,0x28e1,0,{0x13,0x13,0x13,0x54,0x1f,0xff,0xe0,0x54,0x07,0x2f,0x90,0x7f,0xd7,0xf0,0xe0,0x44}}, - {16,0x28f1,0,{0x20,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x12,0x4d,0xa9}}, - {16,0x2901,0,{0x40,0x02,0x41,0xcb,0x90,0x7f,0xea,0xe0,0x70,0x20,0x90,0x7f,0xec,0xe0,0xf4,0x54}}, - {16,0x2911,0,{0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25,0xe0,0x24,0xb4,0xf5,0x82}}, - {16,0x2921,0,{0xe4,0x34,0x7f,0xf5,0x83,0x74,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01}}, - {16,0x2931,0,{0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xe9,0xe0}}, - {16,0x2941,0,{0x60,0x12,0x24,0xf8,0x60,0x09,0x24,0x02,0x70,0x29,0x12,0x43,0xdb,0x41,0xcb,0x12}}, - {16,0x2951,0,{0x4d,0x5c,0x41,0xcb,0x12,0x4d,0xa5,0xa2,0x22,0xe4,0x33,0xff,0x25,0xe0,0xff,0xa2}}, - {16,0x2961,0,{0x23,0xe4,0x33,0x4f,0x90,0x7f,0x00,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02}}, - {16,0x2971,0,{0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xe9,0xe0}}, - {16,0x2981,0,{0x60,0x33,0x24,0xf6,0x60,0x2a,0x24,0x04,0x70,0x3d,0x90,0x7f,0xeb,0xe0,0x24,0xde}}, - {16,0x2991,0,{0x60,0x0c,0x04,0x70,0x12,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f}}, - {16,0x29a1,0,{0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb}}, - {16,0x29b1,0,{0x12,0x46,0x85,0x41,0xcb,0x12,0x4d,0xa5,0xe4,0x90,0x7f,0x00,0xf0,0xa3,0xf0,0x90}}, - {16,0x29c1,0,{0x7f,0xb5,0x74,0x02,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb}}, - {16,0x29d1,0,{0x90,0x7f,0xe9,0xe0,0x24,0xf4,0x60,0x34,0x24,0x0c,0x70,0x39,0x12,0x4d,0xa5,0x90}}, - {16,0x29e1,0,{0x7f,0xec,0xe0,0xf4,0x54,0x80,0xff,0xc4,0x54,0x0f,0xff,0xe0,0x54,0x07,0x2f,0x25}}, - {16,0x29f1,0,{0xe0,0x24,0xb4,0xf5,0x82,0xe4,0x34,0x7f,0xf5,0x83,0xe0,0x54,0xfd,0x90,0x7f,0x00}}, - {16,0x2a01,0,{0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0}}, - {16,0x2a11,0,{0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x41,0xcb,0x90,0x7f}}, - {16,0x2a21,0,{0xe9,0xe0,0x24,0xf6,0x60,0x12,0x14,0x60,0x1a,0x24,0x02,0x70,0x1d,0xd2,0x20,0x90}}, - {16,0x2a31,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x12,0xd2,0x20,0x90,0x7f,0xb4,0xe0,0x44,0x01}}, - {16,0x2a41,0,{0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x20,0x20,0x18,0x90,0x7f,0xee}}, - {16,0x2a51,0,{0xe0,0x70,0x04,0xa3,0xe0,0x60,0x0b,0xd2,0x29,0xd2,0x27,0x12,0x17,0x4a,0xd2,0x2a}}, - {16,0x2a61,0,{0x80,0x03,0x12,0x08,0x00,0xc2,0x20,0x80,0x61,0x90,0x7f,0xee,0xe0,0x70,0x04,0xa3}}, - {16,0x2a71,0,{0xe0,0x60,0x0b,0xd2,0x29,0xd2,0x28,0x12,0x17,0x4a,0xd2,0x2a,0x80,0x4c,0x12,0x38}}, - {16,0x2a81,0,{0x74,0x80,0x47,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x60,0x12,0x14,0x60,0x1a,0x24,0x02}}, - {16,0x2a91,0,{0x70,0x1d,0xd2,0x21,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x12,0xd2,0x21,0x90}}, - {16,0x2aa1,0,{0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x20}}, - {16,0x2ab1,0,{0x21,0x03,0x12,0x10,0x00,0xc2,0x21,0x80,0x11,0x12,0x2a,0xd6,0x80,0x0c,0x12,0x4d}}, - {16,0x2ac1,0,{0xab,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x20,0x2a,0x07,0x90,0x7f,0xb4}}, - { 5,0x2ad1,0,{0xe0,0x44,0x02,0xf0,0x22}}, - {16,0x2ad6,0,{0xe4,0x90,0x76,0x27,0xf0,0x90,0x76,0x27,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x42}}, - {16,0x2ae6,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}}, - {16,0x2af6,0,{0x60,0x0e,0xef,0xc3,0x94,0x06,0x50,0x08,0x90,0x76,0x27,0xe0,0x04,0xf0,0x80,0xd5}}, - {16,0x2b06,0,{0xef,0xb4,0x06,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x0f}}, - {16,0x2b16,0,{0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x28,0xf0,0x24}}, - {16,0x2b26,0,{0x9f,0x70,0x02,0xa1,0x74,0x24,0x21,0x60,0x02,0xa1,0xa1,0x90,0x7f,0xe9,0xe0,0x24}}, - {16,0x2b36,0,{0x7e,0x70,0x02,0x61,0xfc,0x14,0x70,0x02,0x81,0xb5,0x24,0x02,0x60,0x02,0xa1,0x6c}}, - {16,0x2b46,0,{0xef,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc}}, - {16,0x2b56,0,{0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x44,0x7a,0xac,0x79,0x00,0x78}}, - {16,0x2b66,0,{0x00,0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3,0x74,0xac}}, - {16,0x2b76,0,{0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0}}, - {16,0x2b86,0,{0x0f,0xa4,0x24,0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd}}, - {16,0x2b96,0,{0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12}}, - {16,0x2ba6,0,{0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3}}, - {16,0x2bb6,0,{0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24}}, - {16,0x2bc6,0,{0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe}}, - {16,0x2bd6,0,{0xa3,0xe0,0xff,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x37,0xab,0x60}}, - {16,0x2be6,0,{0x02,0xa1,0xa8,0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90}}, - {16,0x2bf6,0,{0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x47}}, - {16,0x2c06,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3}}, - {16,0x2c16,0,{0xe0,0xff,0x7b,0x44,0x7a,0xac,0x79,0x00,0x78,0x00,0xc3,0x12,0x37,0xab,0x70,0x13}}, - {16,0x2c26,0,{0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3,0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5}}, - {16,0x2c36,0,{0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4}}, - {16,0x2c46,0,{0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b}}, - {16,0x2c56,0,{0x80,0x7a,0xbb,0x79,0x00,0x78,0x00,0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00}}, - {16,0x2c66,0,{0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0}}, - {16,0x2c76,0,{0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x2c86,0,{0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x00,0x7a,0x77}}, - {16,0x2c96,0,{0x79,0x01,0x78,0x00,0xc3,0x12,0x37,0xab,0x60,0x02,0xa1,0xa8,0x90,0x7f,0x00,0xf0}}, - {16,0x2ca6,0,{0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90}}, - {16,0x2cb6,0,{0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x2cc6,0,{0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x44,0x7a,0xac,0x79}}, - {16,0x2cd6,0,{0x00,0x78,0x00,0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x44,0xf0,0xa3}}, - {16,0x2ce6,0,{0x74,0xac,0xf0,0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0}}, - {16,0x2cf6,0,{0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3}}, - {16,0x2d06,0,{0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x80,0x7a,0xbb,0x79,0x00,0x78,0x00}}, - {16,0x2d16,0,{0xc3,0x12,0x37,0xab,0x70,0x13,0x90,0x7f,0x00,0x74,0x80,0xf0,0xa3,0x74,0xbb,0xf0}}, - {16,0x2d26,0,{0xe4,0xa3,0xf0,0x90,0x7f,0xb5,0x74,0x03,0xf0,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f}}, - {16,0x2d36,0,{0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3}}, - {16,0x2d46,0,{0xe0,0xfe,0xa3,0xe0,0xff,0x7b,0x00,0x7a,0x77,0x79,0x01,0x78,0x00,0xc3,0x12,0x37}}, - {16,0x2d56,0,{0xab,0x70,0x4f,0x90,0x7f,0x00,0xf0,0xa3,0x74,0x77,0xf0,0xa3,0x74,0x01,0xf0,0x90}}, - {16,0x2d66,0,{0x7f,0xb5,0x74,0x03,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f}}, - {16,0x2d76,0,{0xe9,0xe0,0x24,0x7f,0x70,0x1e,0x90,0x76,0x27,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x4f}}, - {16,0x2d86,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74}}, - {16,0x2d96,0,{0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xb4,0xe0,0x44}}, - { 3,0x2da6,0,{0x01,0xf0,0x22}}, - {16,0x2da9,0,{0xe4,0x90,0x76,0x36,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4}}, - {16,0x2db9,0,{0x34,0x75,0xf5,0x83,0x74,0x01,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82}}, - {16,0x2dc9,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x01,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5}}, - {16,0x2dd9,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff}}, - {16,0x2de9,0,{0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x10,0xf0}}, - {16,0x2df9,0,{0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x05}}, - {16,0x2e09,0,{0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4}}, - {16,0x2e19,0,{0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5}}, - {16,0x2e29,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f}}, - {16,0x2e39,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24}}, - {16,0x2e49,0,{0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0}}, - {16,0x2e59,0,{0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}}, - {16,0x2e69,0,{0x01,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x2e79,0,{0x74,0x03,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x2e89,0,{0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24}}, - {16,0x2e99,0,{0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x10,0xf0,0xef,0x75,0xf0,0x03,0xa4}}, - {16,0x2ea9,0,{0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x06,0xf0,0xef,0x75,0xf0,0x03}}, - {16,0x2eb9,0,{0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0}}, - {16,0x2ec9,0,{0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x2ed9,0,{0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x2ee9,0,{0xf5,0x83,0x74,0x04,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34}}, - {16,0x2ef9,0,{0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03}}, - {16,0x2f09,0,{0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0}}, - {16,0x2f19,0,{0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x08,0xf0,0xef,0x75}}, - {16,0x2f29,0,{0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x90}}, - {16,0x2f39,0,{0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4}}, - {16,0x2f49,0,{0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82}}, - {16,0x2f59,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x0a,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5}}, - {16,0x2f69,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0}}, - {16,0x2f79,0,{0xff,0x75,0xf0,0x03,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02}}, - {16,0x2f89,0,{0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}}, - {16,0x2f99,0,{0x09,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x2fa9,0,{0x74,0x04,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24}}, - {16,0x2fb9,0,{0x0e,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0xef,0x75,0xf0,0x03,0xa4}}, - {16,0x2fc9,0,{0x24,0x0f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x07,0xf0,0xef,0x75,0xf0,0x03}}, - {14,0x2fd9,0,{0xa4,0x24,0x10,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x22}}, - {16,0x2fe7,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x26,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01}}, - { 8,0x2ff7,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - { 1,0x2fff,0,{0x32}}, - {16,0x3000,0,{0x90,0x7f,0xb6,0xe0,0x20,0xe1,0x02,0xc2,0x3d,0xd2,0x36,0x20,0x36,0x02,0x41,0x6e}}, - {16,0x3010,0,{0x30,0x3d,0x02,0x41,0x6e,0x90,0x80,0x07,0xe0,0x60,0x04,0xd2,0x36,0x80,0x02,0xc2}}, - {16,0x3020,0,{0x36,0x20,0x36,0x02,0x41,0x2e,0xd2,0x35,0xe4,0xf5,0x1a,0x90,0x80,0x04,0xe0,0xf5}}, - {16,0x3030,0,{0x19,0x74,0x08,0x25,0x0e,0xf8,0xa6,0x19,0x85,0x19,0x18,0xe5,0x18,0x20,0xe7,0x04}}, - {16,0x3040,0,{0xd2,0x38,0x80,0x02,0xc2,0x38,0x30,0x38,0x02,0x21,0xd4,0xe4,0xf5,0x16,0xe5,0x19}}, - {16,0x3050,0,{0xb4,0xf0,0x0c,0xd2,0x39,0x75,0x08,0x04,0x75,0x09,0xf0,0x05,0x0e,0x80,0x02,0x05}}, - {16,0x3060,0,{0x16,0xe5,0x19,0x64,0xf7,0x70,0x3d,0xc2,0x39,0xe5,0x0e,0x24,0xfe,0x60,0x17,0x14}}, - {16,0x3070,0,{0x60,0x22,0x24,0x03,0x70,0x29,0x75,0x08,0x05,0x75,0x09,0xf7,0xe4,0xf5,0x0a,0xf5}}, - {16,0x3080,0,{0x0b,0x75,0x0e,0x04,0x80,0x20,0x75,0x08,0x06,0x75,0x0a,0xf7,0xe4,0xf5,0x0b,0x75}}, - {16,0x3090,0,{0x0e,0x04,0x80,0x12,0x75,0x08,0x07,0x75,0x0b,0xf7,0x75,0x0e,0x04,0x80,0x07,0x12}}, - {16,0x30a0,0,{0x48,0xf3,0x80,0x02,0x05,0x16,0xe5,0x19,0x54,0xf8,0x64,0xf8,0x70,0x3b,0xc2,0x35}}, - {16,0x30b0,0,{0xe5,0x19,0x24,0x07,0x60,0x0c,0x24,0xfc,0x60,0x08,0x24,0x05,0x24,0xf8,0x50,0x06}}, - {16,0x30c0,0,{0x80,0x08,0xd2,0x3a,0x80,0x06,0xc2,0x3a,0x80,0x02,0xd2,0x3a,0x75,0x1a,0x01,0x20}}, - {16,0x30d0,0,{0x3a,0x19,0x90,0x7e,0x80,0x74,0x0f,0xf0,0xa3,0xe5,0x19,0xf0,0xe4,0xa3,0xf0,0xa3}}, - {16,0x30e0,0,{0xf0,0x90,0x7f,0xb7,0x74,0x04,0xf0,0x80,0x02,0x05,0x16,0x20,0x39,0x6d,0xe5,0x19}}, - {16,0x30f0,0,{0x64,0xf7,0x60,0x67,0xe5,0x1a,0x70,0x63,0xe5,0x18,0x54,0xf0,0x64,0xf0,0x70,0x59}}, - {16,0x3100,0,{0x85,0x18,0x19,0xf5,0x0e,0xe5,0x19,0x24,0x0f,0x60,0x1b,0x24,0xfe,0x60,0x17,0x24}}, - {16,0x3110,0,{0xfd,0x60,0x22,0x14,0x60,0x1f,0x24,0x05,0x70,0x2f,0x75,0x08,0x03,0x05,0x0e,0x85}}, - {16,0x3120,0,{0x18,0x09,0xd2,0x37,0x80,0x28,0x75,0x08,0x02,0x05,0x0e,0x85,0x18,0x09,0x75,0x14}}, - {16,0x3130,0,{0x01,0xd2,0x37,0x80,0x19,0x75,0x08,0x05,0x05,0x0e,0x85,0x18,0x09,0xe4,0xf5,0x0a}}, - {16,0x3140,0,{0xf5,0x0b,0x75,0x0e,0x03,0xd2,0x37,0x80,0x05,0x12,0x48,0xf3,0xc2,0x35,0x30,0x35}}, - {16,0x3150,0,{0x0a,0x85,0x08,0x13,0x85,0x18,0x12,0x80,0x02,0x05,0x16,0x85,0x18,0x19,0xe5,0x16}}, - {16,0x3160,0,{0x64,0x04,0x70,0x62,0xf5,0x0e,0xe5,0x19,0x54,0xf0,0xf5,0x19,0xf5,0x15,0x85,0x18}}, - {16,0x3170,0,{0x19,0xe5,0x15,0x24,0x70,0x60,0x18,0x24,0xf0,0x60,0x14,0x24,0xf0,0x60,0x10,0x24}}, - {16,0x3180,0,{0xf0,0x60,0x1e,0x24,0xf0,0x60,0x1a,0x24,0xf0,0x60,0x04,0x24,0x60,0x70,0x27,0xe5}}, - {16,0x3190,0,{0x15,0xc4,0x54,0x0f,0xf5,0x19,0xf5,0x08,0x05,0x0e,0x85,0x18,0x09,0xd2,0x37,0x80}}, - {16,0x31a0,0,{0x1a,0xe5,0x15,0xc4,0x54,0x0f,0xf5,0x19,0xf5,0x08,0x05,0x0e,0x85,0x18,0x09,0x75}}, - {16,0x31b0,0,{0x14,0x01,0xd2,0x37,0x80,0x05,0x12,0x48,0xf3,0xc2,0x35,0x30,0x35,0x0a,0x85,0x19}}, - {16,0x31c0,0,{0x13,0x85,0x18,0x12,0x80,0x02,0x05,0x16,0xe5,0x16,0xd3,0x94,0x05,0x40,0x57,0x12}}, - {16,0x31d0,0,{0x48,0xf3,0x80,0x52,0x30,0x39,0x17,0xe5,0x0e,0x70,0x0a,0x85,0x08,0x09,0x75,0x08}}, - {16,0x31e0,0,{0x04,0x05,0x0e,0x80,0x41,0x74,0x08,0x25,0x0e,0xf8,0xa6,0x19,0x80,0x38,0x20,0x37}}, - {16,0x31f0,0,{0x2a,0xe5,0x0e,0xb4,0x01,0x0f,0x85,0x08,0x0a,0x85,0x09,0x0b,0x85,0x13,0x08,0x85}}, - {16,0x3200,0,{0x12,0x09,0x75,0x0e,0x04,0xe5,0x14,0xb4,0x01,0x1c,0x85,0x08,0x0a,0xe4,0xf5,0x0b}}, - {16,0x3210,0,{0x85,0x13,0x08,0x85,0x12,0x09,0x75,0x0e,0x04,0x80,0x0b,0xe5,0x14,0xb4,0x01,0x06}}, - {16,0x3220,0,{0xe4,0xf5,0x0b,0x75,0x0e,0x04,0xe4,0xf5,0x1a,0x30,0x35,0x02,0x05,0x0e,0xe5,0x0e}}, - {16,0x3230,0,{0xd3,0x94,0x03,0x50,0x02,0x01,0x0b,0xc2,0x37,0xe4,0xf5,0x0e,0xf5,0x10,0xc2,0x36}}, - {16,0x3240,0,{0xd2,0x3d,0xf5,0x14,0x74,0x08,0x25,0x10,0xf8,0xe6,0xff,0x74,0x80,0x25,0x10,0xf5}}, - {16,0x3250,0,{0x82,0xe4,0x34,0x7e,0xf5,0x83,0xef,0xf0,0x74,0x08,0x25,0x10,0xf8,0xe4,0xf6,0x05}}, - {15,0x3260,0,{0x10,0xe5,0x10,0xb4,0x04,0xde,0x90,0x7f,0xb7,0x74,0x04,0xf0,0x01,0x0b,0x22}}, - {16,0x326f,0,{0x90,0x76,0x18,0xe0,0xff,0x64,0x05,0x70,0x42,0x90,0x75,0xab,0xe0,0xb4,0x01,0x19}}, - {16,0x327f,0,{0x90,0x72,0x37,0x74,0x01,0xf0,0xe4,0x90,0x80,0x20,0xf0,0x90,0x80,0x31,0xf0,0x90}}, - {16,0x328f,0,{0x80,0x28,0xf0,0x90,0x80,0x39,0xf0,0x80,0x22,0xe4,0x90,0x72,0x37,0xf0,0x90,0x75}}, - {16,0x329f,0,{0xad,0xe0,0x90,0x72,0x2b,0xf0,0xe0,0x24,0x80,0xf0,0xe0,0x90,0x80,0x20,0xf0,0x90}}, - {16,0x32af,0,{0x80,0x31,0xf0,0x90,0x80,0x28,0xf0,0x90,0x80,0x39,0xf0,0xef,0x64,0x06,0x60,0x02}}, - {16,0x32bf,0,{0x81,0x99,0x90,0x72,0x39,0x74,0x04,0xf0,0x90,0x72,0x39,0xe0,0xff,0x24,0xfe,0x90}}, - {16,0x32cf,0,{0x72,0x04,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x32df,0,{0x83,0xe0,0x64,0x01,0x70,0x54,0x90,0x72,0x36,0x04,0xf0,0x90,0x72,0x04,0xe0,0xff}}, - {16,0x32ef,0,{0x24,0xfd,0x60,0x28,0x24,0xfe,0x60,0x24,0x24,0x03,0x24,0xfb,0x50,0x04,0x60,0x1c}}, - {16,0x32ff,0,{0x81,0x8c,0x74,0x20,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x74,0x28}}, - {16,0x330f,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x81,0x8c,0x90,0x72,0x04,0xe0}}, - {16,0x331f,0,{0xff,0x24,0x30,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x74,0x38,0x2f,0xf5}}, - {16,0x332f,0,{0x82,0xe4,0x34,0x80,0xf5,0x83,0xe4,0xf0,0x81,0x8c,0xe4,0x90,0x72,0x36,0xf0,0x90}}, - {16,0x333f,0,{0x72,0x39,0xe0,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x334f,0,{0xe0,0xff,0x7e,0x00,0x90,0x75,0x0c,0xee,0xf0,0xa3,0xef,0xf0,0x70,0x06,0x90,0x72}}, - {16,0x335f,0,{0x02,0x74,0x3b,0xf0,0x90,0x75,0x0c,0xe0,0xfe,0xa3,0xe0,0xff,0x64,0x80,0x4e,0x70}}, - {16,0x336f,0,{0x04,0x90,0x72,0x02,0xf0,0xef,0x4e,0x70,0x02,0x81,0x35,0xef,0x64,0x80,0x4e,0x70}}, - {16,0x337f,0,{0x02,0x81,0x35,0xef,0xf8,0xe4,0x90,0x75,0x0d,0xf0,0xe8,0x90,0x75,0x0c,0xf0,0x90}}, - {16,0x338f,0,{0x72,0x34,0xe0,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x339f,0,{0xe0,0xff,0x90,0x72,0x02,0xf0,0x90,0x75,0x0d,0xe0,0x2f,0xf0,0x90,0x75,0x0c,0xe0}}, - {16,0x33af,0,{0x34,0x00,0xf0,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0xfc,0xfd,0x7b,0xd6,0x7a,0xa5,0xf9}}, - {16,0x33bf,0,{0xf8,0xd3,0x12,0x37,0x95,0x40,0x0a,0x90,0x75,0x0c,0x74,0xa5,0xf0,0xa3,0x74,0xd6}}, - {16,0x33cf,0,{0xf0,0x90,0x75,0x0d,0xe0,0x24,0x2a,0xf0,0x90,0x75,0x0c,0xe0,0x34,0x5a,0xf0,0xe0}}, - {16,0x33df,0,{0xfe,0xa3,0xe0,0x78,0x05,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x90,0x75}}, - {16,0x33ef,0,{0x0c,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x72,0x2c,0xee,0xf0,0xa3,0xef,0xf0,0xd3,0x94}}, - {16,0x33ff,0,{0xd2,0xee,0x64,0x80,0x94,0x82,0x40,0x0a,0x90,0x72,0x2c,0x74,0x02,0xf0,0xa3,0x74}}, - {16,0x340f,0,{0xd2,0xf0,0xc3,0x90,0x72,0x2c,0xe0,0x64,0x80,0x94,0x80,0x50,0x04,0xe4,0xf0,0xa3}}, - {16,0x341f,0,{0xf0,0x90,0x72,0x2c,0xe0,0xfe,0xa3,0xe0,0x24,0x3a,0xf5,0x82,0xee,0x34,0x72,0xf5}}, - {16,0x342f,0,{0x83,0xe0,0x90,0x72,0x02,0xf0,0x90,0x72,0x04,0xe0,0xff,0x24,0xfd,0x60,0x2d,0x24}}, - {16,0x343f,0,{0xfe,0x60,0x29,0x24,0x03,0x24,0xfb,0x50,0x04,0x60,0x21,0x80,0x40,0x90,0x72,0x02}}, - {16,0x344f,0,{0xe0,0xfe,0x74,0x20,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x28}}, - {16,0x345f,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x80,0x21,0x90,0x72,0x02,0xe0}}, - {16,0x346f,0,{0xff,0x90,0x72,0x04,0xe0,0xfe,0x24,0x30,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xef}}, - {16,0x347f,0,{0xf0,0x74,0x38,0x2e,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xef,0xf0,0x90,0x72,0x39}}, - {11,0x348f,0,{0xe0,0x04,0xf0,0xe0,0x64,0x0a,0x60,0x02,0x41,0xc7,0x22}}, - {16,0x349a,0,{0x90,0x76,0x18,0xe0,0xff,0xb4,0x05,0x23,0x90,0x72,0x37,0xe0,0x70,0x1d,0x90,0x75}}, - {16,0x34aa,0,{0xad,0xe0,0x90,0x72,0x2b,0xf0,0xe0,0x24,0x80,0xf0,0xe0,0x90,0x80,0x20,0xf0,0x90}}, - {16,0x34ba,0,{0x80,0x31,0xf0,0x90,0x80,0x28,0xf0,0x90,0x80,0x39,0xf0,0xef,0x64,0x06,0x60,0x02}}, - {16,0x34ca,0,{0xc1,0x91,0x90,0x72,0x36,0xe0,0x60,0x02,0xc1,0x91,0x90,0x76,0x40,0xe0,0x70,0x31}}, - {16,0x34da,0,{0x90,0x72,0x03,0x74,0x03,0xf0,0x90,0x72,0x03,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24}}, - {16,0x34ea,0,{0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x72,0x29,0xe0,0xfd,0xee}}, - {16,0x34fa,0,{0x6d,0x60,0x0e,0xef,0xc3,0x94,0x0a,0x50,0x08,0x90,0x72,0x03,0xe0,0x04,0xf0,0x80}}, - {16,0x350a,0,{0xd5,0x90,0x72,0x39,0x74,0x04,0xf0,0x90,0x76,0x40,0xe0,0x70,0x08,0x90,0x72,0x03}}, - {16,0x351a,0,{0xe0,0x90,0x72,0x39,0xf0,0x90,0x72,0x39,0xe0,0xfd,0x24,0xfe,0x90,0x72,0x2a,0xf0}}, - {16,0x352a,0,{0xed,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff}}, - {16,0x353a,0,{0x7e,0x00,0x90,0x75,0x0c,0xee,0xf0,0xa3,0xef,0xf0,0x70,0x06,0x90,0x72,0x02,0x74}}, - {16,0x354a,0,{0x80,0xf0,0x90,0x75,0x0c,0xe0,0xfe,0xa3,0xe0,0xff,0x64,0x80,0x4e,0x70,0x04,0x90}}, - {16,0x355a,0,{0x72,0x02,0xf0,0xef,0x4e,0x70,0x02,0xc1,0x1b,0xef,0x64,0x80,0x4e,0x70,0x02,0xc1}}, - {16,0x356a,0,{0x1b,0xef,0xf8,0xe4,0x90,0x75,0x0d,0xf0,0xe8,0x90,0x75,0x0c,0xf0,0xed,0x75,0xf0}}, - {16,0x357a,0,{0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xff,0x90,0x72,0x02}}, - {16,0x358a,0,{0xf0,0x90,0x75,0x0d,0xe0,0x2f,0xf0,0x90,0x75,0x0c,0xe0,0x34,0x00,0xf0,0xe0,0xfe}}, - {16,0x359a,0,{0xa3,0xe0,0xff,0xe4,0xfc,0xfd,0x7b,0xd6,0x7a,0xa5,0xf9,0xf8,0xd3,0x12,0x37,0x95}}, - {16,0x35aa,0,{0x40,0x0a,0x90,0x75,0x0c,0x74,0xa5,0xf0,0xa3,0x74,0xd6,0xf0,0x90,0x75,0x0d,0xe0}}, - {16,0x35ba,0,{0x24,0x2a,0xf0,0x90,0x75,0x0c,0xe0,0x34,0x5a,0xf0,0xe0,0xfe,0xa3,0xe0,0x78,0x05}}, - {16,0x35ca,0,{0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x90,0x75,0x0c,0xee,0xf0,0xa3,0xef}}, - {16,0x35da,0,{0xf0,0x90,0x72,0x2c,0xee,0xf0,0xa3,0xef,0xf0,0xd3,0x94,0xd2,0xee,0x64,0x80,0x94}}, - {16,0x35ea,0,{0x82,0x40,0x0a,0x90,0x72,0x2c,0x74,0x02,0xf0,0xa3,0x74,0xd2,0xf0,0xc3,0x90,0x72}}, - {16,0x35fa,0,{0x2c,0xe0,0x64,0x80,0x94,0x80,0x50,0x04,0xe4,0xf0,0xa3,0xf0,0x90,0x72,0x2c,0xe0}}, - {16,0x360a,0,{0xfe,0xa3,0xe0,0x24,0x3a,0xf5,0x82,0xee,0x34,0x72,0xf5,0x83,0xe0,0x90,0x72,0x02}}, - {16,0x361a,0,{0xf0,0x90,0x72,0x2a,0xe0,0xff,0x24,0xfd,0x60,0x2d,0x24,0xfe,0x60,0x29,0x24,0x03}}, - {16,0x362a,0,{0x24,0xfb,0x50,0x04,0x60,0x21,0x80,0x40,0x90,0x72,0x02,0xe0,0xfe,0x74,0x20,0x2f}}, - {16,0x363a,0,{0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x28,0x2f,0xf5,0x82,0xe4,0x34}}, - {16,0x364a,0,{0x80,0xf5,0x83,0xee,0xf0,0x80,0x21,0x90,0x72,0x02,0xe0,0xff,0x90,0x72,0x2a,0xe0}}, - {16,0x365a,0,{0xfe,0x24,0x30,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xef,0xf0,0x74,0x38,0x2e,0xf5}}, - {16,0x366a,0,{0x82,0xe4,0x34,0x80,0xf5,0x83,0xef,0xf0,0x90,0x76,0x40,0xe0,0x70,0x06,0x90,0x72}}, - {16,0x367a,0,{0x39,0x74,0x0a,0xf0,0x90,0x72,0x39,0xe0,0x04,0xf0,0xe0,0xc3,0x94,0x0a,0x50,0x02}}, - { 8,0x368a,0,{0xa1,0x11,0xe4,0x90,0x76,0x40,0xf0,0x22}}, - {16,0x3692,0,{0xbb,0x01,0x06,0x89,0x82,0x8a,0x83,0xe0,0x22,0x50,0x02,0xe7,0x22,0xbb,0xfe,0x02}}, - { 9,0x36a2,0,{0xe3,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0x22}}, - {16,0x36ab,0,{0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50}}, - {16,0x36bb,0,{0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22}}, - {13,0x36cb,0,{0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22}}, - {16,0x36d8,0,{0xc2,0xd5,0xec,0x30,0xe7,0x09,0xb2,0xd5,0xe4,0xc3,0x9d,0xfd,0xe4,0x9c,0xfc,0xee}}, - {16,0x36e8,0,{0x30,0xe7,0x15,0xb2,0xd5,0xe4,0xc3,0x9f,0xff,0xe4,0x9e,0xfe,0x12,0x38,0x1f,0xc3}}, - {16,0x36f8,0,{0xe4,0x9d,0xfd,0xe4,0x9c,0xfc,0x80,0x03,0x12,0x38,0x1f,0x30,0xd5,0x07,0xc3,0xe4}}, - { 6,0x3708,0,{0x9f,0xff,0xe4,0x9e,0xfe,0x22}}, - {16,0x370e,0,{0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0}}, - {16,0x371e,0,{0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe}}, - {16,0x372e,0,{0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83}}, - { 8,0x373e,0,{0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22}}, - {16,0x3746,0,{0xe8,0x8f,0xf0,0xa4,0xcc,0x8b,0xf0,0xa4,0x2c,0xfc,0xe9,0x8e,0xf0,0xa4,0x2c,0xfc}}, - {16,0x3756,0,{0x8a,0xf0,0xed,0xa4,0x2c,0xfc,0xea,0x8e,0xf0,0xa4,0xcd,0xa8,0xf0,0x8b,0xf0,0xa4}}, - {16,0x3766,0,{0x2d,0xcc,0x38,0x25,0xf0,0xfd,0xe9,0x8f,0xf0,0xa4,0x2c,0xcd,0x35,0xf0,0xfc,0xeb}}, - {16,0x3776,0,{0x8e,0xf0,0xa4,0xfe,0xa9,0xf0,0xeb,0x8f,0xf0,0xa4,0xcf,0xc5,0xf0,0x2e,0xcd,0x39}}, - {15,0x3786,0,{0xfe,0xe4,0x3c,0xfc,0xea,0xa4,0x2d,0xce,0x35,0xf0,0xfd,0xe4,0x3c,0xfc,0x22}}, - {16,0x3795,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xec,0x64,0x80,0xc8}}, - { 6,0x37a5,0,{0x64,0x80,0x98,0x45,0xf0,0x22}}, - {16,0x37ab,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0}}, - { 1,0x37bb,0,{0x22}}, - {12,0x37bc,0,{0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x22}}, - {16,0x37c8,0,{0xa8,0x82,0x85,0x83,0xf0,0xd0,0x83,0xd0,0x82,0x12,0x37,0xdf,0x12,0x37,0xdf,0x12}}, - {16,0x37d8,0,{0x37,0xdf,0x12,0x37,0xdf,0xe4,0x73,0xe4,0x93,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83}}, - {16,0x37e8,0,{0xc8,0xc5,0x82,0xc8,0xf0,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83,0xc8,0xc5,0x82,0xc8}}, - { 1,0x37f8,0,{0x22}}, - {16,0x37f9,0,{0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3}}, - {16,0x3809,0,{0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60}}, - { 6,0x3819,0,{0xef,0xa3,0xa3,0xa3,0x80,0xdf}}, - {16,0x381f,0,{0xbc,0x00,0x0b,0xbe,0x00,0x29,0xef,0x8d,0xf0,0x84,0xff,0xad,0xf0,0x22,0xe4,0xcc}}, - {16,0x382f,0,{0xf8,0x75,0xf0,0x08,0xef,0x2f,0xff,0xee,0x33,0xfe,0xec,0x33,0xfc,0xee,0x9d,0xec}}, - {16,0x383f,0,{0x98,0x40,0x05,0xfc,0xee,0x9d,0xfe,0x0f,0xd5,0xf0,0xe9,0xe4,0xce,0xfd,0x22,0xed}}, - {16,0x384f,0,{0xf8,0xf5,0xf0,0xee,0x84,0x20,0xd2,0x1c,0xfe,0xad,0xf0,0x75,0xf0,0x08,0xef,0x2f}}, - {16,0x385f,0,{0xff,0xed,0x33,0xfd,0x40,0x07,0x98,0x50,0x06,0xd5,0xf0,0xf2,0x22,0xc3,0x98,0xfd}}, - { 5,0x386f,0,{0x0f,0xd5,0xf0,0xea,0x22}}, - {16,0x3874,0,{0xe4,0x90,0x76,0x29,0xf0,0x90,0x76,0x29,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x42}}, - {16,0x3884,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}}, - {16,0x3894,0,{0x60,0x0e,0xef,0xc3,0x94,0x06,0x50,0x08,0x90,0x76,0x29,0xe0,0x04,0xf0,0x80,0xd5}}, - {16,0x38a4,0,{0xef,0xb4,0x06,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x0f}}, - {16,0x38b4,0,{0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x76,0x2a,0xf0,0x24}}, - {16,0x38c4,0,{0xbf,0x70,0x02,0x41,0x41,0x24,0xe0,0x70,0x02,0x41,0x12,0x24,0x21,0x60,0x02,0x41}}, - {16,0x38d4,0,{0x3a,0x90,0x7f,0xe9,0xe0,0x24,0xfe,0x60,0x7d,0x14,0x70,0x02,0x21,0xb2,0x24,0x02}}, - {16,0x38e4,0,{0x60,0x02,0x41,0x0a,0x12,0x17,0x51,0x90,0x76,0x42,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3}}, - {16,0x38f4,0,{0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x76,0x29,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5}}, - {16,0x3904,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xbc,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01}}, - {16,0x3914,0,{0x12,0x90,0x76,0x7c,0x74,0x67,0xf0,0x90,0x76,0x7d,0x74,0x06,0xf0,0x90,0x76,0x7e}}, - {16,0x3924,0,{0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0f,0xe4,0x90,0x76,0x7c,0xf0,0x90,0x76,0x7d,0xf0}}, - {16,0x3934,0,{0x90,0x76,0x7e,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0f,0xe4,0x90,0x76,0x7c,0xf0,0x90}}, - {16,0x3944,0,{0x76,0x7d,0xf0,0x90,0x76,0x7e,0x74,0x18,0xf0,0x90,0x76,0x1a,0x74,0x01,0xf0,0x12}}, - {16,0x3954,0,{0x3e,0x8f,0x12,0x18,0x00,0x22,0x90,0x7e,0xc2,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb}}, - {16,0x3964,0,{0xfa,0x79,0x01,0xf8,0x12,0x37,0x46,0xc8,0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca}}, - {16,0x3974,0,{0xcb,0xef,0xcb,0x90,0x7e,0xc1,0xe0,0xfe,0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa}}, - {16,0x3984,0,{0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x7e,0xc0,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff}}, - {16,0x3994,0,{0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x76,0x29,0xe0,0x75,0xf0,0x0f}}, - {16,0x39a4,0,{0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xbc,0x22,0x90,0x7e}}, - {16,0x39b4,0,{0xc2,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xfb,0xfa,0x79,0x01,0xf8,0x12,0x37,0x46,0xc8}}, - {16,0x39c4,0,{0xec,0xc8,0xc9,0xed,0xc9,0xca,0xee,0xca,0xcb,0xef,0xcb,0x90,0x7e,0xc1,0xe0,0xfe}}, - {16,0x39d4,0,{0xe4,0xfc,0xfd,0x2b,0xfb,0xea,0x3e,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x7e}}, - {16,0x39e4,0,{0xc0,0xe0,0xff,0xe4,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38}}, - {16,0x39f4,0,{0xfc,0x90,0x76,0x29,0xe0,0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x3a04,0,{0xf5,0x83,0x12,0x37,0xbc,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f}}, - {16,0x3a14,0,{0xe9,0xe0,0x14,0x70,0x19,0x90,0x7e,0xc0,0xe0,0xff,0x90,0x76,0x29,0xe0,0x75,0xf0}}, - {16,0x3a24,0,{0x0f,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef,0xf0,0x22,0x90,0x7f}}, - {14,0x3a34,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22}}, - {16,0x3a42,0,{0xe4,0x90,0x76,0x35,0xf0,0x90,0x76,0x35,0xe0,0xff,0xc3,0x94,0x03,0x40,0x02,0x41}}, - {16,0x3a52,0,{0xff,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xef}}, - {16,0x3a62,0,{0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4}}, - {16,0x3a72,0,{0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}}, - {16,0x3a82,0,{0xf0,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x3a92,0,{0x74,0xff,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x3aa2,0,{0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x3ab2,0,{0x83,0x74,0x80,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x3ac2,0,{0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x3ad2,0,{0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x3ae2,0,{0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x3af2,0,{0xf5,0x83,0x74,0x01,0xf0,0x90,0x76,0x35,0xe0,0x04,0xf0,0x41,0x47,0x90,0x76,0x3c}}, - {16,0x3b02,0,{0x74,0x0a,0xf0,0xe4,0xa3,0xf0,0x90,0x76,0x35,0x74,0x03,0xf0,0x90,0x76,0x3c,0xe0}}, - {16,0x3b12,0,{0xff,0x90,0x76,0x35,0xe0,0xfe,0xc3,0x9f,0x40,0x02,0x61,0xd2,0x90,0x76,0x3d,0xe0}}, - {16,0x3b22,0,{0xff,0x04,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xaa,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x3b32,0,{0x83,0xef,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xab,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x3b42,0,{0x83,0xe4,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xac,0xf5,0x82,0xe4,0x34,0x75,0xf5}}, - {16,0x3b52,0,{0x83,0x74,0x5e,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xad,0xf5,0x82,0xe4,0x34,0x75}}, - {16,0x3b62,0,{0xf5,0x83,0x74,0xba,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xae,0xf5,0x82,0xe4,0x34}}, - {16,0x3b72,0,{0x75,0xf5,0x83,0x74,0x05,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xaf,0xf5,0x82,0xe4}}, - {16,0x3b82,0,{0x34,0x75,0xf5,0x83,0x74,0x80,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb0,0xf5,0x82}}, - {16,0x3b92,0,{0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb1,0xf5,0x82}}, - {16,0x3ba2,0,{0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb2,0xf5,0x82}}, - {16,0x3bb2,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x15,0xf0,0xee,0x75,0xf0,0x0a,0xa4,0x24,0xb3,0xf5}}, - {16,0x3bc2,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0x90,0x76,0x35,0xe0,0x04,0xf0,0x61,0x0e}}, - { 1,0x3bd2,0,{0x22}}, - {16,0x3bd3,0,{0xe4,0x90,0x76,0x36,0xf0,0xe0,0xfb,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4}}, - {16,0x3be3,0,{0x34,0x75,0xf5,0x83,0x74,0x40,0xf0,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82}}, - {16,0x3bf3,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x0a,0xf0,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5}}, - {16,0x3c03,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x00,0xac,0x44,0xeb,0x75,0xf0}}, - {16,0x3c13,0,{0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x00}}, - {16,0x3c23,0,{0xac,0x44,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - {16,0x3c33,0,{0x12,0x37,0xc8,0x00,0x01,0x77,0x00,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xfb,0x75}}, - {16,0x3c43,0,{0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x40,0xf0,0xeb}}, - {16,0x3c53,0,{0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x8c,0xf0}}, - {16,0x3c63,0,{0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x43,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37}}, - {16,0x3c73,0,{0xc8,0x00,0x00,0xac,0x44,0xeb,0x75,0xf0,0x0f,0xa4,0x24,0x47,0xf5,0x82,0xe4,0x34}}, - {16,0x3c83,0,{0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x00,0xac,0x44,0xeb,0x75,0xf0,0x0f,0xa4,0x24}}, - {16,0x3c93,0,{0x4b,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x12,0x37,0xc8,0x00,0x01,0x77,0x00,0x90}}, - {16,0x3ca3,0,{0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4}}, - {16,0x3cb3,0,{0x34,0x75,0xf5,0x83,0x74,0x40,0xf0,0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82}}, - {16,0x3cc3,0,{0xe4,0x34,0x75,0xf5,0x83,0x74,0x8f,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff}}, - {16,0x3cd3,0,{0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x41,0xf0}}, - {16,0x3ce3,0,{0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x84}}, - {16,0x3cf3,0,{0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5}}, - {16,0x3d03,0,{0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x61,0xf0,0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42}}, - {16,0x3d13,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x81,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0}}, - {16,0x3d23,0,{0xe0,0xff,0x75,0xf0,0x0f,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74}}, - {16,0x3d33,0,{0x61,0xf0,0xef,0x75,0xf0,0x0f,0xa4,0x24,0x42,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83}}, - { 4,0x3d43,0,{0x74,0x01,0xf0,0x22}}, - {16,0x3d47,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0}}, - {16,0x3d57,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef}}, - {16,0x3d67,0,{0xc0,0xe0,0x90,0x7f,0xa2,0xe0,0x90,0x76,0x7f,0xf0,0x90,0x7f,0x74,0xe0,0x90,0x76}}, - {16,0x3d77,0,{0x87,0xf0,0x90,0x7f,0x75,0xe0,0x90,0x76,0x88,0xf0,0x90,0x7f,0x98,0xe0,0x44,0x02}}, - {16,0x3d87,0,{0xf0,0x90,0x76,0x96,0xe0,0xff,0x20,0xe1,0x0c,0x44,0x02,0xf0,0x90,0x80,0x03,0xf0}}, - {16,0x3d97,0,{0xd2,0x32,0x12,0x4a,0xc4,0x90,0x76,0x7f,0xe0,0x20,0xe2,0x50,0x90,0x76,0x87,0xe0}}, - {16,0x3da7,0,{0xfe,0xa3,0xe0,0x7c,0x00,0x24,0x00,0xf5,0x34,0xec,0x3e,0xf5,0x33,0x90,0x76,0x98}}, - {16,0x3db7,0,{0xe0,0xfd,0xae,0x33,0xaf,0x34,0x12,0x36,0xd8,0x90,0x76,0x87,0xef,0xf0,0xd2,0x2f}}, - {16,0x3dc7,0,{0x30,0x31,0x29,0x20,0x3f,0x26,0xc2,0x31,0x90,0x7f,0x94,0xe0,0x54,0xcf,0xf0,0x90}}, - {16,0x3dd7,0,{0x7f,0x9a,0xe0,0x30,0xe4,0x04,0xd2,0x2d,0xc2,0x2c,0x90,0x7f,0x9a,0xe0,0x20,0xe5}}, - {16,0x3de7,0,{0x04,0xc2,0x2d,0xd2,0x2c,0x90,0x7f,0x94,0xe0,0x44,0x30,0xf0,0x12,0x4a,0x50,0x12}}, - {16,0x3df7,0,{0x1b,0x04,0x30,0x2f,0x12,0x12,0x42,0x16,0xc2,0x2f,0x75,0xe8,0x01,0x12,0x16,0x8a}}, - {16,0x3e07,0,{0x75,0xe8,0x0d,0xd2,0x2b,0x80,0x05,0x75,0xe8,0x01,0xc2,0x2b,0x20,0x2b,0x34,0x90}}, - {16,0x3e17,0,{0x76,0x19,0xe0,0xff,0xb4,0x01,0x0e,0x90,0x76,0x7c,0x74,0x67,0xf0,0xa3,0x74,0x06}}, - {16,0x3e27,0,{0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0b,0x90,0x76,0x7c,0xe4,0xf0,0xa3,0xf0}}, - {16,0x3e37,0,{0xa3,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0b,0x90,0x76,0x7c,0xe4,0xf0,0xa3,0xf0,0xa3}}, - {16,0x3e47,0,{0x74,0x18,0xf0,0x75,0xca,0xd3,0x75,0xcb,0xfe,0xd2,0xca,0x30,0x34,0x04,0xc2,0x34}}, - {16,0x3e57,0,{0x80,0x02,0xd2,0x34,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xf0,0x90,0x7f}}, - {16,0x3e67,0,{0x98,0xe0,0x54,0xfd,0xf0,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0}}, - {16,0x3e77,0,{0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0}}, - { 8,0x3e87,0,{0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0x32}}, - {16,0x3e8f,0,{0x90,0x76,0x92,0xe0,0x14,0x60,0x1d,0x14,0x70,0x02,0xe1,0x44,0x24,0x02,0x60,0x02}}, - {16,0x3e9f,0,{0xe1,0xd4,0x90,0x76,0x94,0x74,0x01,0xf0,0x90,0x80,0x00,0xf0,0xe4,0x90,0x76,0x8e}}, - {16,0x3eaf,0,{0xf0,0xd2,0x31,0x22,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x1b,0xe4,0x90,0x7f,0xf2}}, - {16,0x3ebf,0,{0xf0,0x90,0x7f,0xf3,0x74,0x30,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97}}, - {16,0x3ecf,0,{0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x02,0x1b,0xe4,0x90,0x7f,0xf2,0xf0}}, - {16,0x3edf,0,{0x90,0x7f,0xf3,0x74,0x34,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97,0xe0}}, - {16,0x3eef,0,{0x44,0x02,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x03,0x18,0xe4,0x90,0x7f,0xf2,0xf0,0x90}}, - {16,0x3eff,0,{0x7f,0xf3,0x74,0x64,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97,0xe0,0x44}}, - {16,0x3f0f,0,{0x04,0xf0,0x90,0x76,0x94,0xe0,0x44,0x01,0xf0,0x90,0x80,0x00,0xf0,0x30,0x3f,0x09}}, - {16,0x3f1f,0,{0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01,0xf0}}, - {16,0x3f2f,0,{0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0x90,0x76,0x98,0x74,0x04,0xf0,0x90,0x76}}, - {16,0x3f3f,0,{0x8e,0x74,0x01,0xf0,0x22,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x1b,0xe4,0x90,0x7f}}, - {16,0x3f4f,0,{0xf2,0xf0,0x90,0x7f,0xf3,0x74,0x44,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76}}, - {16,0x3f5f,0,{0x97,0xe0,0x54,0xfd,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x02,0x1b,0xe4,0x90,0x7f,0xf2}}, - {16,0x3f6f,0,{0xf0,0x90,0x7f,0xf3,0x74,0x4c,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97}}, - {16,0x3f7f,0,{0xe0,0x44,0x02,0xf0,0x54,0xfb,0xf0,0xef,0xb4,0x03,0x18,0xe4,0x90,0x7f,0xf2,0xf0}}, - {16,0x3f8f,0,{0x90,0x7f,0xf3,0x74,0x94,0xf0,0x90,0x7f,0xff,0x74,0xfc,0xf0,0x90,0x76,0x97,0xe0}}, - {16,0x3f9f,0,{0x44,0x04,0xf0,0x90,0x76,0x94,0xe0,0x54,0xfe,0xf0,0x90,0x80,0x00,0xf0,0x30,0x3f}}, - {16,0x3faf,0,{0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97,0xe0,0x44,0x01}}, - {16,0x3fbf,0,{0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0x90,0x76,0x98,0x74,0x06,0xf0,0x90}}, - { 6,0x3fcf,0,{0x76,0x8e,0x74,0x02,0xf0,0x22}}, - {16,0x3fd5,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x02,0xf0}}, - {16,0x3fe5,0,{0x90,0x7f,0xc7,0xe0,0xf5,0x11,0x75,0x0f,0x00,0x75,0x0d,0x00,0xd2,0x33,0xd0,0x82}}, - { 5,0x3ff5,0,{0xd0,0x83,0xd0,0xe0,0x32}}, - { 6,0x3ffa,0,{0x12,0x4a,0xc4,0xc2,0x31,0x22}}, - {16,0x4000,0,{0xe5,0x11,0xd3,0x94,0x00,0x50,0x02,0x21,0x06,0x90,0x76,0x89,0xe0,0xc3,0x94,0x08}}, - {16,0x4010,0,{0x40,0x02,0x21,0x06,0x74,0x40,0x25,0x0f,0xf5,0x82,0xe4,0x34,0x7e,0xf5,0x83,0xe0}}, - {16,0x4020,0,{0xf5,0x17,0xe5,0x0d,0x60,0x0e,0x90,0x80,0x05,0xe5,0x17,0xf0,0x90,0x76,0x89,0xe0}}, - {16,0x4030,0,{0x04,0xf0,0x01,0xda,0xe5,0x17,0x12,0x37,0xf9,0x40,0xc1,0x02,0x40,0x67,0x05,0x40}}, - {16,0x4040,0,{0x7a,0x06,0x40,0x98,0x07,0x40,0xc1,0x0c,0x40,0xc1,0x0d,0x40,0xc7,0x0f,0x40,0xcb}}, - {16,0x4050,0,{0xf6,0x40,0xcb,0xf8,0x40,0xcb,0xfa,0x40,0xcb,0xfb,0x40,0xcb,0xfc,0x40,0xcb,0xfe}}, - {16,0x4060,0,{0x40,0xcb,0xff,0x00,0x00,0x40,0xda,0x90,0x7e,0x41,0xe0,0x90,0x80,0x05,0xf0,0x90}}, - {16,0x4070,0,{0x76,0x89,0xe0,0x04,0xf0,0x75,0x11,0x01,0x80,0x60,0x90,0x7e,0x41,0xe0,0x90,0x80}}, - {16,0x4080,0,{0x05,0xf0,0x90,0x7e,0x42,0xe0,0x90,0x80,0x05,0xf0,0x90,0x76,0x89,0xe0,0x04,0xf0}}, - {16,0x4090,0,{0xe0,0x04,0xf0,0x75,0x11,0x01,0x80,0x42,0x90,0x7e,0x41,0xe0,0x90,0x80,0x05,0xf0}}, - {16,0x40a0,0,{0x90,0x7e,0x42,0xe0,0x90,0x80,0x05,0xf0,0x90,0x7e,0x43,0xe0,0x90,0x80,0x05,0xf0}}, - {16,0x40b0,0,{0x90,0x76,0x89,0xe0,0x04,0xf0,0xe0,0x04,0xf0,0xe0,0x04,0xf0,0x75,0x11,0x01,0x80}}, - {16,0x40c0,0,{0x19,0xd2,0x3b,0xd2,0x3c,0x80,0x13,0xd2,0x3b,0x80,0x0f,0x90,0x80,0x05,0xe5,0x17}}, - {16,0x40d0,0,{0xf0,0x90,0x76,0x89,0xe0,0x04,0xf0,0x75,0x11,0x01,0x20,0x3b,0x04,0x05,0x0d,0x80}}, - {16,0x40e0,0,{0x1f,0x30,0x3c,0x1c,0x90,0x7e,0x41,0xe0,0x90,0x80,0x05,0xf0,0x90,0x7e,0x42,0xe0}}, - {16,0x40f0,0,{0x90,0x80,0x05,0xf0,0x90,0x76,0x89,0xe0,0x04,0xf0,0xe0,0x04,0xf0,0x75,0x11,0x01}}, - {16,0x4100,0,{0x05,0x0f,0x15,0x11,0x01,0x00,0xe5,0x11,0x70,0x10,0xc2,0x33,0xf5,0x0d,0xf5,0x0f}}, - {11,0x4110,0,{0x90,0x7f,0xc7,0x74,0x04,0xf0,0xc2,0x3b,0xc2,0x3c,0x22}}, - {16,0x411b,0,{0x90,0x76,0x8d,0xe0,0x64,0x01,0x70,0x27,0x30,0x27,0x08,0xc2,0x27,0x12,0x08,0x00}}, - {16,0x412b,0,{0x12,0x17,0x4a,0x30,0x28,0x08,0xc2,0x28,0x12,0x38,0x74,0x12,0x17,0x4a,0x30,0x2a}}, - {16,0x413b,0,{0x0e,0xe4,0x90,0x76,0x8d,0xf0,0xc2,0x2a,0x90,0x7f,0xb4,0xe0,0x44,0x02,0xf0,0x90}}, - {16,0x414b,0,{0x76,0x3f,0xe0,0xb4,0x01,0x05,0xe4,0xf0,0x12,0x32,0x6f,0x90,0x76,0x41,0xe0,0xb4}}, - {16,0x415b,0,{0x01,0x05,0xe4,0xf0,0x12,0x34,0x9a,0x90,0x76,0x40,0xe0,0xb4,0x01,0x03,0x12,0x34}}, - {16,0x416b,0,{0x9a,0x90,0x7f,0x9b,0xe0,0x20,0xe4,0x02,0xc2,0x3f,0x90,0x7f,0x9b,0xe0,0x30,0xe4}}, - {16,0x417b,0,{0x02,0xd2,0x3f,0x90,0x7f,0x9b,0xe0,0x20,0xe5,0x02,0xc2,0x3e,0x90,0x7f,0x9b,0xe0}}, - {16,0x418b,0,{0x30,0xe5,0x02,0xd2,0x3e,0xa2,0x41,0x30,0x3f,0x01,0xb3,0x50,0x1f,0xa2,0x3f,0x92}}, - {16,0x419b,0,{0x41,0x30,0x3f,0x09,0x90,0x76,0x97,0xe0,0x54,0xfe,0xf0,0x80,0x07,0x90,0x76,0x97}}, - {16,0x41ab,0,{0xe0,0x44,0x01,0xf0,0x90,0x76,0x97,0xe0,0x90,0x80,0x02,0xf0,0x30,0x3f,0x34,0x90}}, - {16,0x41bb,0,{0x76,0x19,0xe0,0xff,0xb4,0x01,0x0e,0x90,0x76,0x7c,0x74,0x67,0xf0,0xa3,0x74,0x06}}, - {16,0x41cb,0,{0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x02,0x0b,0xe4,0x90,0x76,0x7c,0xf0,0xa3,0xf0}}, - {16,0x41db,0,{0xa3,0x74,0x0c,0xf0,0xef,0xb4,0x03,0x0b,0xe4,0x90,0x76,0x7c,0xf0,0xa3,0xf0,0xa3}}, - {16,0x41eb,0,{0x74,0x18,0xf0,0xa2,0x40,0x30,0x3e,0x01,0xb3,0x50,0x1f,0xa2,0x3e,0x92,0x40,0x30}}, - {16,0x41fb,0,{0x3e,0x09,0x90,0x76,0x95,0xe0,0x44,0x04,0xf0,0x80,0x07,0x90,0x76,0x95,0xe0,0x54}}, - {11,0x420b,0,{0xfb,0xf0,0x90,0x76,0x95,0xe0,0x90,0x80,0x01,0xf0,0x22}}, - {16,0x4216,0,{0x90,0x76,0x19,0xe0,0x64,0x01,0x70,0x35,0x90,0x76,0x87,0xe0,0xff,0xd3,0x94,0x2d}}, - {16,0x4226,0,{0x40,0x2b,0x90,0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0,0xe0,0xd3}}, - {16,0x4236,0,{0x94,0x0f,0x40,0x19,0xe4,0xf0,0xef,0xd3,0x94,0x31,0x40,0x08,0x90,0x76,0x19,0x74}}, - {16,0x4246,0,{0x03,0xf0,0x80,0x06,0x90,0x76,0x19,0x74,0x02,0xf0,0x12,0x3e,0x8f,0x90,0x76,0x19}}, - {16,0x4256,0,{0xe0,0xb4,0x02,0x2c,0x90,0x76,0x87,0xe0,0xff,0xc3,0x94,0x2f,0x50,0x22,0xef,0xd3}}, - {16,0x4266,0,{0x94,0x2a,0x40,0x1c,0x90,0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0}}, - {16,0x4276,0,{0xe0,0xd3,0x94,0x0f,0x40,0x0a,0xe4,0xf0,0x90,0x76,0x19,0x04,0xf0,0x12,0x3e,0x8f}}, - {16,0x4286,0,{0x90,0x76,0x19,0xe0,0xb4,0x02,0x26,0x90,0x76,0x87,0xe0,0xd3,0x94,0x31,0x40,0x1d}}, - {16,0x4296,0,{0x90,0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f}}, - {16,0x42a6,0,{0x40,0x0b,0xe4,0xf0,0x90,0x76,0x19,0x74,0x03,0xf0,0x12,0x3e,0x8f,0x90,0x76,0x19}}, - {16,0x42b6,0,{0xe0,0x64,0x03,0x70,0x3f,0x90,0x76,0x87,0xe0,0xff,0xc3,0x94,0x5f,0x50,0x35,0x90}}, - {16,0x42c6,0,{0x76,0x86,0x74,0x01,0xf0,0x90,0x76,0x85,0xe0,0x04,0xf0,0xe0,0xd3,0x94,0x0f,0x40}}, - {16,0x42d6,0,{0x23,0xe4,0xf0,0xef,0xc3,0x94,0x2f,0x50,0x0c,0xef,0xd3,0x94,0x2a,0x40,0x06,0x90}}, - {16,0x42e6,0,{0x76,0x19,0x74,0x01,0xf0,0xef,0xd3,0x94,0x2f,0x40,0x06,0x90,0x76,0x19,0x74,0x02}}, - {16,0x42f6,0,{0xf0,0x12,0x3e,0x8f,0x90,0x76,0x86,0xe0,0x70,0x05,0x90,0x76,0x85,0xf0,0x22,0xe4}}, - { 5,0x4306,0,{0x90,0x76,0x86,0xf0,0x22}}, - {16,0x430b,0,{0xe4,0x90,0x76,0x96,0xf0,0x90,0x80,0x03,0xf0,0x90,0x7f,0xe0,0x74,0x90,0xf0,0x90}}, - {16,0x431b,0,{0x7f,0xe1,0x74,0x04,0xf0,0xe4,0x90,0x7f,0xdd,0xf0,0x90,0x7f,0xa1,0xf0,0x53,0x8e}}, - {16,0x432b,0,{0xf8,0x75,0x88,0x05,0x75,0xb8,0x20,0x75,0xf8,0x01,0x43,0x8e,0x30,0xf5,0xc8,0x75}}, - {16,0x433b,0,{0xca,0x7f,0x75,0xcb,0xf8,0x43,0xa8,0x20,0x12,0x07,0x4a,0xc2,0x2c,0xc2,0x2d,0xc2}}, - {16,0x434b,0,{0x2b,0xc2,0x2f,0x90,0x7f,0xfc,0x74,0xdd,0xf0,0x90,0x7f,0xff,0x74,0xff,0xf0,0x90}}, - {16,0x435b,0,{0x7f,0x97,0xe0,0x44,0x01,0xf0,0x90,0x76,0x19,0x74,0x01,0xf0,0xe4,0x90,0x76,0x85}}, - {16,0x436b,0,{0xf0,0xa3,0xf0,0x90,0x76,0x81,0xf0,0x90,0x76,0x80,0xf0,0x12,0x49,0x58,0x12,0x0f}}, - {16,0x437b,0,{0xc6,0x12,0x4a,0x8d,0x90,0x7f,0x97,0xe0,0x44,0x08,0xf0,0xe0,0x54,0xb9,0xf0,0xd2}}, - {16,0x438b,0,{0x30,0x20,0x30,0x18,0x12,0x47,0xb4,0x12,0x30,0x00,0x12,0x40,0x00,0x12,0x42,0x16}}, - {16,0x439b,0,{0x12,0x4a,0x50,0x12,0x1b,0x04,0x12,0x16,0x61,0x12,0x42,0x16,0xc2,0x2f,0xc2,0x31}}, - {16,0x43ab,0,{0xc2,0x32,0xc2,0x34,0xc2,0x33,0xc2,0x29,0xc2,0x27,0xc2,0x28,0xe4,0xf5,0x11,0x90}}, - {16,0x43bb,0,{0x76,0x89,0xf0,0x90,0x76,0x3f,0xf0,0x90,0x76,0x41,0xf0,0x90,0x76,0x40,0xf0,0x90}}, - {16,0x43cb,0,{0x76,0x8a,0xf0,0xa3,0xf0,0xa3,0x04,0xf0,0xe4,0xa3,0xf0,0x90,0x76,0x99,0xf0,0x22}}, - {16,0x43db,0,{0x12,0x4d,0xa3,0x40,0x02,0x81,0xa0,0x90,0x7f,0xeb,0xe0,0x24,0xfe,0x60,0x1e,0x14}}, - {16,0x43eb,0,{0x60,0x46,0x14,0x60,0x6e,0x14,0x70,0x02,0x81,0x91,0x24,0x04,0x60,0x02,0x81,0x99}}, - {16,0x43fb,0,{0x74,0x05,0x90,0x7f,0xd4,0xf0,0x74,0x00,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xea}}, - {16,0x440b,0,{0xe0,0xff,0x12,0x49,0xff,0x8b,0x20,0x8a,0x21,0x89,0x22,0xea,0x49,0x60,0x11,0xce}}, - {16,0x441b,0,{0xea,0xce,0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22}}, - {16,0x442b,0,{0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x12,0x48,0xb0}}, - {16,0x443b,0,{0x8b,0x20,0x8a,0x21,0x89,0x22,0xea,0x49,0x60,0x11,0xce,0xea,0xce,0xee,0x90,0x7f}}, - {16,0x444b,0,{0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44}}, - {16,0x445b,0,{0x01,0xf0,0x22,0x90,0x7f,0xea,0xe0,0xff,0x90,0x7e,0xc0,0xe0,0xfd,0xa3,0xe0,0xfb}}, - {16,0x446b,0,{0x12,0x17,0x94,0x8b,0x20,0x8a,0x21,0x89,0x22,0xea,0x49,0x60,0x11,0xce,0xea,0xce}}, - {16,0x447b,0,{0xee,0x90,0x7f,0xd4,0xf0,0xcf,0xe9,0xcf,0xef,0x90,0x7f,0xd5,0xf0,0x22,0x90,0x7f}}, - {16,0x448b,0,{0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f}}, - { 5,0x449b,0,{0xb4,0xe0,0x44,0x01,0xf0}}, - { 1,0x44a0,0,{0x22}}, - {16,0x44a1,0,{0xc2,0xaf,0xd2,0x24,0x90,0x7f,0x93,0x74,0x30,0xf0,0x90,0x7f,0x9c,0x74,0xbb,0xf0}}, - {16,0x44b1,0,{0x90,0x7f,0x96,0xe0,0x44,0x30,0xf0,0xe0,0x54,0x30,0xf0,0x90,0x7f,0x94,0x74,0x30}}, - {16,0x44c1,0,{0xf0,0x90,0x7f,0x9d,0x74,0xcf,0xf0,0x90,0x7f,0x97,0x74,0xa0,0xf0,0x90,0x7f,0x95}}, - {16,0x44d1,0,{0x74,0xc0,0xf0,0x90,0x7f,0x9e,0x74,0x03,0xf0,0x90,0x7f,0x99,0xe0,0x30,0xe2,0x09}}, - {16,0x44e1,0,{0x90,0x05,0x19,0x74,0xa0,0xf0,0xe4,0xa3,0xf0,0xc2,0x25,0xc2,0x22,0xc2,0x23,0xc2}}, - {16,0x44f1,0,{0x26,0x12,0x4a,0xc4,0x12,0x2d,0xa9,0x12,0x3b,0xd3,0x12,0x45,0x59,0x12,0x3a,0x42}}, - {16,0x4501,0,{0x90,0x76,0x68,0x74,0x01,0xf0,0x70,0x0f,0x12,0x4b,0xbb,0x12,0x07,0xfe,0x12,0x4d}}, - {16,0x4511,0,{0xa1,0x12,0x1b,0x40,0x12,0x14,0x96,0x12,0x43,0x0b,0x90,0x7f,0xaf,0xe0,0x44,0x01}}, - {16,0x4521,0,{0xf0,0x90,0x7f,0xae,0xe0,0x44,0x1f,0xf0,0x90,0x7f,0xac,0x74,0xff,0xf0,0x90,0x7f}}, - {16,0x4531,0,{0xad,0xf0,0x90,0x7f,0xde,0xf0,0x90,0x7f,0xdf,0xf0,0x90,0x7f,0xab,0xf0,0x90,0x7f}}, - {16,0x4541,0,{0xa9,0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x43,0xd8,0x20,0xd2,0xe8,0x43,0xd8}}, - { 8,0x4551,0,{0x20,0x53,0xa8,0xa0,0x43,0xa8,0x80,0x22}}, - {16,0x4559,0,{0xe4,0x90,0x76,0x36,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4}}, - {16,0x4569,0,{0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4}}, - {16,0x4579,0,{0x34,0x75,0xf5,0x83,0x74,0x01,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75}}, - {16,0x4589,0,{0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75}}, - {16,0x4599,0,{0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x02,0xf0,0x90}}, - {16,0x45a9,0,{0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4}}, - {16,0x45b9,0,{0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75,0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4}}, - {16,0x45c9,0,{0x34,0x75,0xf5,0x83,0x74,0x03,0xf0,0x90,0x76,0x36,0xe0,0x04,0xf0,0xe0,0xff,0x75}}, - {16,0x45d9,0,{0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe4,0xf0,0xef,0x75}}, - {16,0x45e9,0,{0xf0,0x03,0xa4,0x24,0x33,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0x74,0x04,0xf0,0x22}}, - {12,0x45f9,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x38,0x02,0x46,0x40}}, - {16,0x4605,0,{0x02,0x47,0x5a,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2}}, - {16,0x4615,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33}}, - {16,0x4625,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf}}, - {16,0x4635,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x0c,0x8f,0xe4,0x7e}}, - {16,0x4645,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93}}, - {16,0x4655,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3}}, - {16,0x4665,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca}}, - {16,0x4675,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe}}, - {16,0x4685,0,{0x90,0x7f,0xec,0xe0,0x90,0x76,0x83,0xf0,0xe0,0x14,0x60,0x1d,0x14,0x60,0x2a,0x14}}, - {16,0x4695,0,{0x60,0x37,0x14,0x60,0x44,0x24,0x04,0x70,0x50,0x90,0x76,0x91,0xe0,0x90,0x7f,0x00}}, - {16,0x46a5,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x47,0x90,0x76,0x92,0xe0,0x90,0x7f,0x00}}, - {16,0x46b5,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x37,0x90,0x76,0x90,0xe0,0x90,0x7f,0x00}}, - {16,0x46c5,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x27,0x90,0x76,0x84,0xe0,0x90,0x7f,0x00}}, - {16,0x46d5,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x17,0x90,0x76,0x93,0xe0,0x90,0x7f,0x00}}, - {16,0x46e5,0,{0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0x80,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0}}, - { 2,0x46f5,0,{0xd3,0x22}}, - {16,0x46f7,0,{0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0}}, - {16,0x4707,0,{0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef}}, - {16,0x4717,0,{0xc0,0xe0,0xc2,0xca,0xc2,0xcf,0x90,0x7f,0x98,0xe0,0x44,0x01,0xf0,0x30,0x2e,0x03}}, - {16,0x4727,0,{0x12,0x14,0xa6,0x90,0x7f,0x98,0xe0,0x54,0xfe,0xf0,0x53,0xa8,0xfa,0x12,0x16,0x61}}, - {16,0x4737,0,{0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0}}, - {16,0x4747,0,{0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0}}, - { 3,0x4757,0,{0xd0,0xe0,0x32}}, - {16,0x475a,0,{0xe4,0x90,0x76,0x66,0xf0,0x12,0x44,0xa1,0x20,0x26,0x13,0x90,0x76,0x66,0xe0,0xc3}}, - {16,0x476a,0,{0x94,0x02,0x50,0x0a,0xe0,0x04,0xf0,0xd2,0x42,0x12,0x4a,0xf6,0x80,0xea,0x30,0x26}}, - {16,0x477a,0,{0x05,0x12,0x28,0x01,0xc2,0x26,0x30,0x25,0x2b,0x90,0x76,0x96,0xe0,0x54,0xfc,0xf0}}, - {16,0x478a,0,{0x90,0x80,0x03,0xf0,0x12,0x14,0x96,0x90,0x76,0x96,0xe0,0x44,0x03,0xf0,0x90,0x80}}, - {16,0x479a,0,{0x03,0xf0,0xe4,0x90,0x76,0x67,0xf0,0x90,0x76,0x67,0xe0,0x04,0xf0,0xe0,0xb4,0x4b}}, - {10,0x47aa,0,{0xf6,0x12,0x3f,0xfa,0x12,0x41,0x1b,0x80,0xc5,0x22}}, - {16,0x47b4,0,{0xe4,0x90,0x76,0x9b,0xf0,0x90,0x76,0x9b,0xe0,0xff,0x04,0xf0,0xef,0x60,0x08,0xe0}}, - {16,0x47c4,0,{0x24,0x08,0xf8,0xe4,0xf6,0x80,0xee,0x90,0x76,0x96,0xe0,0x54,0xfb,0xf0,0x54,0xf7}}, - {16,0x47d4,0,{0xf0,0x90,0x80,0x03,0xf0,0xe4,0xf5,0x18,0xd2,0x35,0xf5,0x0e,0xf5,0x10,0xd2,0x36}}, - {16,0x47e4,0,{0x75,0x12,0x11,0x75,0x13,0x22,0xc2,0x37,0xc2,0x39,0xc2,0x38,0xf5,0x16,0xf5,0x14}}, - {11,0x47f4,0,{0xf5,0x1a,0xf5,0x0d,0xc2,0x3b,0xc2,0x3c,0xc2,0x3d,0x22}}, - {16,0x4800,0,{0x90,0x7f,0xec,0xe0,0x90,0x76,0x83,0xf0,0xe0,0x14,0x60,0x17,0x14,0x60,0x21,0x14}}, - {16,0x4810,0,{0x60,0x2b,0x14,0x60,0x32,0x24,0x04,0x70,0x38,0x90,0x7f,0xea,0xe0,0x90,0x76,0x91}}, - {16,0x4820,0,{0xf0,0x80,0x35,0x90,0x7f,0xea,0xe0,0x90,0x76,0x92,0xf0,0x12,0x3e,0x8f,0x80,0x28}}, - {16,0x4830,0,{0x90,0x7f,0xea,0xe0,0x90,0x76,0x90,0xf0,0x12,0x18,0x00,0x80,0x1b,0x90,0x7f,0xea}}, - {16,0x4840,0,{0xe0,0x90,0x76,0x84,0xf0,0x80,0x11,0x90,0x7f,0xea,0xe0,0x90,0x76,0x93,0xf0,0x80}}, - {10,0x4850,0,{0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0xd3,0x22}}, - {16,0x485a,0,{0xe4,0x90,0x76,0x26,0xf0,0x90,0x76,0x26,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x34}}, - {16,0x486a,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}}, - {16,0x487a,0,{0x60,0x0e,0xef,0xc3,0x94,0x04,0x50,0x08,0x90,0x76,0x26,0xe0,0x04,0xf0,0x80,0xd5}}, - {16,0x488a,0,{0xef,0xb4,0x04,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0xef,0x75,0xf0,0x03}}, - {16,0x489a,0,{0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0x90,0x7f,0x00,0xf0,0x90}}, - { 6,0x48aa,0,{0x7f,0xb5,0x74,0x01,0xf0,0x22}}, - { 2,0x48b0,0,{0x8f,0x2e}}, - {16,0x48b2,0,{0xe4,0xf5,0x2f,0x75,0x30,0xff,0x75,0x31,0x06,0x75,0x32,0xbe,0xab,0x30,0xaa,0x31}}, - {16,0x48c2,0,{0xa9,0x32,0x90,0x00,0x01,0x12,0x36,0xab,0xb4,0x03,0x1f,0xaf,0x2f,0x05,0x2f,0xef}}, - {16,0x48d2,0,{0x65,0x2e,0x70,0x01,0x22,0x12,0x36,0x92,0x7e,0x00,0x29,0xff,0xee,0x3a,0xc9,0xef}}, - {16,0x48e2,0,{0xc9,0x75,0x30,0xff,0xf5,0x31,0x89,0x32,0x80,0xd2,0x7b,0x00,0x7a,0x00,0x79,0x00}}, - { 1,0x48f2,0,{0x22}}, - {12,0x48f3,0,{0xc2,0x37,0xe4,0xf5,0x0e,0xf5,0x10,0xc2,0x36,0xf5,0x14,0x22}}, - {16,0x4900,0,{0x02,0x2f,0xe7,0x00,0x02,0x3d,0x47,0x00,0x02,0x4d,0x46,0x00,0x02,0x4b,0xd5,0x00}}, - {16,0x4910,0,{0x02,0x4b,0x60,0x00,0x02,0x2f,0xff,0x00,0x02,0x4b,0xed,0x00,0x02,0x4b,0x81,0x00}}, - {16,0x4920,0,{0x02,0x4c,0x04,0x00,0x02,0x3f,0xd5,0x00,0x02,0x4c,0x1b,0x00,0x02,0x4c,0x32,0x00}}, - {16,0x4930,0,{0x02,0x4c,0x49,0x00,0x02,0x4c,0x60,0x00,0x02,0x4c,0x77,0x00,0x02,0x4c,0x8e,0x00}}, - {16,0x4940,0,{0x02,0x4c,0xa5,0x00,0x02,0x4c,0xbc,0x00,0x02,0x4c,0xd3,0x00,0x02,0x4c,0xea,0x00}}, - { 8,0x4950,0,{0x02,0x4d,0x01,0x00,0x02,0x4d,0x18,0x00}}, - {16,0x4958,0,{0x90,0x76,0x46,0x74,0x80,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3}}, - {16,0x4968,0,{0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0x74,0x80,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0}}, - {16,0x4978,0,{0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3}}, - {16,0x4988,0,{0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0}}, - {16,0x4998,0,{0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0}}, - { 5,0x49a8,0,{0xa3,0xf0,0xa3,0xf0,0x22}}, - {16,0x49ad,0,{0xe4,0x90,0x76,0x25,0xf0,0x90,0x76,0x25,0xe0,0xff,0x75,0xf0,0x03,0xa4,0x24,0x34}}, - {16,0x49bd,0,{0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xe0,0xfe,0x90,0x7f,0xec,0xe0,0xfd,0xee,0x6d}}, - {16,0x49cd,0,{0x60,0x0e,0xef,0xc3,0x94,0x04,0x50,0x08,0x90,0x76,0x25,0xe0,0x04,0xf0,0x80,0xd5}}, - {16,0x49dd,0,{0xef,0xb4,0x04,0x08,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7e,0xc0,0xe0}}, - {16,0x49ed,0,{0xfe,0xef,0x75,0xf0,0x03,0xa4,0x24,0x32,0xf5,0x82,0xe4,0x34,0x75,0xf5,0x83,0xee}}, - { 2,0x49fd,0,{0xf0,0x22}}, - {16,0x49ff,0,{0xe4,0xfe,0x75,0x1d,0xff,0x75,0x1e,0x05,0x75,0x1f,0x12,0xab,0x1d,0xaa,0x1e,0xa9}}, - {16,0x4a0f,0,{0x1f,0x90,0x00,0x01,0x12,0x36,0xab,0x64,0x02,0x70,0x2f,0xcd,0xee,0xcd,0x0e,0xed}}, - {16,0x4a1f,0,{0x6f,0x70,0x01,0x22,0x90,0x00,0x02,0x12,0x37,0x0e,0x85,0xf0,0x1b,0xf5,0x1c,0x62}}, - {16,0x4a2f,0,{0x1b,0xe5,0x1b,0x62,0x1c,0xe5,0x1c,0x62,0x1b,0x29,0xfd,0xe5,0x1b,0x3a,0xc9,0xed}}, - {16,0x4a3f,0,{0xc9,0x75,0x1d,0xff,0xf5,0x1e,0x89,0x1f,0x80,0xc1,0x7b,0x00,0x7a,0x00,0x79,0x00}}, - { 1,0x4a4f,0,{0x22}}, - {16,0x4a50,0,{0x30,0x2d,0x39,0xc2,0x2d,0x90,0x76,0x19,0xe0,0xff,0xb4,0x01,0x0d,0xe4,0x90,0x76}}, - {16,0x4a60,0,{0x7c,0xf0,0xa3,0x74,0xf8,0xf0,0xa3,0x74,0x0a,0xf0,0xef,0xb4,0x02,0x0d,0xe4,0x90}}, - {16,0x4a70,0,{0x76,0x7c,0xf0,0xa3,0x74,0xf0,0xf0,0xa3,0x74,0x0b,0xf0,0xef,0xb4,0x03,0x0d,0xe4}}, - {13,0x4a80,0,{0x90,0x76,0x7c,0xf0,0xa3,0x74,0xf8,0xf0,0xa3,0x74,0x17,0xf0,0x22}}, - {16,0x4a8d,0,{0xe4,0xff,0x74,0x56,0x2f,0xf5,0x82,0xe4,0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x28}}, - {16,0x4a9d,0,{0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83,0xee,0xf0,0x74,0x5e,0x2f,0xf5,0x82,0xe4}}, - {16,0x4aad,0,{0x34,0x76,0xf5,0x83,0xe0,0xfe,0x74,0x38,0x2f,0xf5,0x82,0xe4,0x34,0x80,0xf5,0x83}}, - { 6,0x4abd,0,{0xee,0xf0,0x0f,0xbf,0x08,0xcc}}, - { 1,0x4ac3,0,{0x22}}, - {16,0x4ac4,0,{0xe4,0x90,0x72,0x36,0xf0,0xa3,0xf0,0x90,0x7f,0x97,0xe0,0x54,0xfb,0xf0,0xe4,0x90}}, - {16,0x4ad4,0,{0x72,0x33,0xf0,0x90,0x72,0x32,0xf0,0x90,0x72,0x01,0x04,0xf0,0xe4,0x90,0x72,0x33}}, - {16,0x4ae4,0,{0xf0,0x90,0x72,0x32,0xf0,0x90,0x72,0x01,0x04,0xf0,0x90,0x7f,0x97,0xe0,0x44,0x04}}, - { 2,0x4af4,0,{0xf0,0x22}}, - {16,0x4af6,0,{0x90,0x7f,0xd6,0xe0,0x54,0xfb,0xf0,0xe0,0x44,0x08,0xf0,0x30,0x42,0x04,0xe0,0x44}}, - {16,0x4b06,0,{0x02,0xf0,0x7f,0xdc,0x7e,0x05,0x12,0x4d,0x2f,0x90,0x7f,0xd6,0xe0,0x54,0xf7,0xf0}}, - { 5,0x4b16,0,{0xe0,0x44,0x04,0xf0,0x22}}, - {16,0x4b1b,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x14,0x90,0x7f,0xe9,0xe0,0x24,0x7f,0x70,0x04,0x12}}, - {16,0x4b2b,0,{0x48,0x5a,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44}}, - { 3,0x4b3b,0,{0x01,0xf0,0x22}}, - {16,0x4b3e,0,{0x90,0x7f,0xeb,0xe0,0x14,0x70,0x13,0x90,0x7f,0xe9,0xe0,0x14,0x70,0x04,0x12,0x49}}, - {16,0x4b4e,0,{0xad,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x22,0x90,0x7f,0xb4,0xe0,0x44,0x01}}, - { 2,0x4b5e,0,{0xf0,0x22}}, - {16,0x4b60,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0x90}}, - {16,0x4b70,0,{0x76,0x96,0xe0,0x54,0xfd,0xf0,0x90,0x80,0x03,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0}}, - { 1,0x4b80,0,{0x32}}, - {16,0x4b81,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x01,0xf0}}, - {15,0x4b91,0,{0xc2,0x29,0x90,0x76,0x8d,0x74,0x01,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4ba0,0,{0x90,0x7f,0xea,0xe0,0x90,0x76,0x82,0xf0,0xe4,0x90,0x76,0x91,0xf0,0x90,0x76,0x92}}, - {11,0x4bb0,0,{0xf0,0x90,0x76,0x90,0xf0,0x90,0x76,0x93,0xf0,0xd3,0x22}}, - {16,0x4bbb,0,{0x90,0x7f,0xd6,0xe0,0x30,0xe7,0x12,0xe0,0x44,0x01,0xf0,0x7f,0x14,0x7e,0x00,0x12}}, - {10,0x4bcb,0,{0x4d,0x2f,0x90,0x7f,0xd6,0xe0,0x54,0xfe,0xf0,0x22}}, - {16,0x4bd5,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x25,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08}}, - { 8,0x4be5,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4bed,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x01,0xf0}}, - { 7,0x4bfd,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c04,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x02,0xf0}}, - { 7,0x4c14,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c1b,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x04,0xf0}}, - { 7,0x4c2b,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c32,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x04,0xf0}}, - { 7,0x4c42,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c49,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x08,0xf0}}, - { 7,0x4c59,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c60,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x08,0xf0}}, - { 7,0x4c70,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c77,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x10,0xf0}}, - { 7,0x4c87,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4c8e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x10,0xf0}}, - { 7,0x4c9e,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4ca5,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x20,0xf0}}, - { 7,0x4cb5,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4cbc,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x20,0xf0}}, - { 7,0x4ccc,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4cd3,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x40,0xf0}}, - { 7,0x4ce3,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4cea,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x40,0xf0}}, - { 7,0x4cfa,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4d01,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xa9,0xe0,0x44,0x80,0xf0}}, - { 7,0x4d11,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4d18,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xaa,0xe0,0x44,0x80,0xf0}}, - { 7,0x4d28,0,{0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4d2f,0,{0x8e,0x35,0x8f,0x36,0xe5,0x36,0x15,0x36,0xae,0x35,0x70,0x02,0x15,0x35,0x4e,0x60}}, - { 7,0x4d3f,0,{0x05,0x12,0x14,0x85,0x80,0xee,0x22}}, - {16,0x4d46,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x04,0xf0,0xd0}}, - { 6,0x4d56,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x4d5c,0,{0x90,0x76,0x82,0xe0,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0,0xd3,0x22}}, - { 9,0x4d6c,0,{0xc2,0x25,0x53,0xd8,0xef,0x43,0xd8,0x20,0x32}}, - { 7,0x4d75,0,{0x53,0x98,0xfe,0x53,0x98,0xfd,0x32}}, - { 7,0x4d7c,0,{0x53,0xc0,0xfe,0x53,0xc0,0xfd,0x32}}, - { 6,0x4d83,0,{0x53,0x91,0xbf,0xd2,0x2d,0x32}}, - { 6,0x4d89,0,{0x53,0x91,0x7f,0xd2,0x2c,0x32}}, - { 4,0x4d8f,0,{0x53,0x91,0xdf,0x32}}, - { 4,0x4d93,0,{0x53,0xd8,0xf7,0x32}}, - { 4,0x4d97,0,{0x12,0x17,0x30,0x22}}, - { 3,0x4d9b,0,{0xc2,0x8d,0x32}}, - { 3,0x4d9e,0,{0xc2,0x8f,0x32}}, - { 2,0x4da1,0,{0xd3,0x22}}, - { 2,0x4da3,0,{0xd3,0x22}}, - { 2,0x4da5,0,{0xd3,0x22}}, - { 2,0x4da7,0,{0xd3,0x22}}, - { 2,0x4da9,0,{0xd3,0x22}}, - { 2,0x4dab,0,{0xc3,0x22}}, - { 0,0x0000,1,{0}} -}; -/* Source: EMI62SFW.HEX -:100C8F004176680141766A0241766B0AC120C12123 -:1044A100C2AFD224907F937430F0907F9C74BBF0A4 -:1044B100907F96E04430F0E05430F0907F94743077 -:1044C100F0907F9D74CFF0907F9774A0F0907F95CE -:1044D10074C0F0907F9E7403F0907F99E030E20900 -:1044E10090051974A0F0E4A3F0C225C222C223C230 -:1044F10026124AC4122DA9123BD3124559123A422F -:104501009076687401F0700F124BBB1207FE124DCA -:10451100A1121B4012149612430B907FAFE044018D -:10452100F0907FAEE0441FF0907FAC74FFF0907F7D -:10453100ADF0907FDEF0907FDFF0907FABF0907F69 -:10454100A9F0907FAAF05391EF43D820D2E843D845 -:084551002053A8A043A880221A -:10475A00E4907666F01244A1202613907666E0C3B0 -:10476A009402500AE004F0D242124AF680EA302655 -:10477A0005122801C22630252B907696E054FCF0CB -:10478A00908003F0121496907696E04403F090809D -:10479A0003F0E4907667F0907667E004F0E0B44BBB -:0A47AA00F6123FFA12411B80C522EF -:10280100C220C221C22A907FE8E01237F9283000A5 -:10281100288C0128A2022A1F212A6A22293D802907 -:102821007D8129D1822A84A12ABAA200002ABF90DF -:102831007FE9E014601124FE602824FE603B24FC43 -:102841007040124BA041CB124DA7400241CB907F6B -:10285100EAE0B40104C22241CB907FB4E04401F02C -:1028610041CB124DA9907FEAE0B40104D22241CBC1 -:10287100907FB4E04401F041CB907FB4E04401F09B -:1028810041CB907FB4E04401F041CB907FE9E0245B -:10289100F5700512480041CB907FB4E04401F0414E -:1028A100CB907FE9E024FD605424026002213412C0 -:1028B1004DA7400241CB907FEAE07038907FECE079 -:1028C100F45480FFC4540FFFE054072F25E024B4D3 -:1028D100F582E4347FF583E4F0907FECE05480FFEF -:1028E100131313541FFFE054072F907FD7F0E044D8 -:1028F10020F041CB907FB4E04401F041CB124DA9CF -:10290100400241CB907FEAE07020907FECE0F454EC -:1029110080FFC4540FFFE054072F25E024B4F58253 -:10292100E4347FF5837401F041CB907FB4E044013E -:10293100F041CB907FB4E04401F041CB907FE9E0DE -:10294100601224F86009240270291243DB41CB1282 -:102951004D5C41CB124DA5A222E433FF25E0FFA23D -:1029610023E4334F907F00F0E4A3F0907FB574022D -:10297100F041CB907FB4E04401F041CB907FE9E09E -:10298100603324F6602A2404703D907FEBE024DE5E -:10299100600C047012907FB4E04401F041CB907F51 -:1029A100B4E04401F041CB907FB4E04401F041CB6D -:1029B10012468541CB124DA5E4907F00F0A3F09023 -:1029C1007FB57402F041CB907FB4E04401F041CB7C -:1029D100907FE9E024F46034240C7039124DA59005 -:1029E1007FECE0F45480FFC4540FFFE054072F251F -:1029F100E024B4F582E4347FF583E054FD907F0058 -:102A0100F0E4A3F0907FB57402F041CB907FB4E085 -:102A11004401F041CB907FB4E04401F041CB907F81 -:102A2100E9E024F6601214601A2402701DD220908D -:102A31007FB4E04401F08012D220907FB4E04401E1 -:102A4100F08007907FB4E04401F0202018907FEEE1 -:102A5100E07004A3E0600BD229D22712174AD22AD0 -:102A61008003120800C2208061907FEEE07004A311 -:102A7100E0600BD229D22812174AD22A804C123890 -:102A8100748047907FE9E024FE601214601A2402EA -:102A9100701DD221907FB4E04401F08012D22190C8 -:102AA1007FB4E04401F08007907FB4E04401F0205E -:102AB1002103121000C2218011122AD6800C124D5E -:102AC100AB5007907FB4E04401F0202A07907FB417 -:052AD100E04402F022C8 -:1043DB00124DA3400281A0907FEBE024FE601E14DF -:1043EB00604614606E1470028191240460028199FE -:1043FB007405907FD4F07400907FD5F022907FEA03 -:10440B00E0FF1249FF8B208A218922EA496011CEF5 -:10441B00EACEEE907FD4F0CFE9CFEF907FD5F022AC -:10442B00907FB4E04401F022907FEAE0FF1248B0A5 -:10443B008B208A218922EA496011CEEACEEE907F49 -:10444B00D4F0CFE9CFEF907FD5F022907FB4E0444A -:10445B0001F022907FEAE0FF907EC0E0FDA3E0FB3D -:10446B001217948B208A218922EA496011CEEACE59 -:10447B00EE907FD4F0CFE9CFEF907FD5F022907FF5 -:10448B00B4E04401F022907FB4E04401F022907F2D -:05449B00B4E04401F053 -:0144A00022F9 -:03003300024D6C0F -:094D6C00C22553D8EF43D82032D0 -:020C9F00C12F63 -:063FFA00124AC4C231228C -:10430B00E4907696F0908003F0907FE07490F090BC -:10431B007FE17404F0E4907FDDF0907FA1F0538E89 -:10432B00F875880575B82075F801438E30F5C8759A -:10433B00CA7F75CBF843A82012074AC22CC22DC2E4 -:10434B002BC22F907FFC74DDF0907FFF74FFF090F9 -:10435B007F97E04401F09076197401F0E490768534 -:10436B00F0A3F0907681F0907680F0124958120FFE -:10437B00C6124A8D907F97E04408F0E054B9F0D212 -:10438B00302030181247B41230001240001242167F -:10439B00124A50121B04121661124216C22FC2315E -:1043AB00C232C234C233C229C227C228E4F51190EB -:1043BB007689F090763FF0907641F0907640F090D1 -:1043CB00768AF0A3F0A304F0E4A3F0907699F022A0 -:104A5000302D39C22D907619E0FFB4010DE4907627 -:104A60007CF0A374F8F0A3740AF0EFB4020DE490A4 -:104A7000767CF0A374F0F0A3740BF0EFB4030DE4B4 -:0D4A800090767CF0A374F8F0A37417F02278 -:101B0400302C38C22C907619E0FFB4010E90767C0C -:101B140074C0F0A37414F0A3740BF0EFB4020DE4DA -:101B240090767CF0A37410F0A3740CF0EFB4030B64 -:0C1B3400E490767CF0A37418F0A3F0227B -:10411B0090768DE064017027302708C227120800C3 -:10412B0012174A302808C22812387412174A302A3C -:10413B000EE490768DF0C22A907FB4E04402F090AA -:10414B00763FE0B40105E4F012326F907641E0B4B3 -:10415B000105E4F012349A907640E0B40103123476 -:10416B009A907F9BE020E402C23F907F9BE030E47B -:10417B0002D23F907F9BE020E502C23E907F9BE006 -:10418B0030E502D23EA241303F01B3501FA23F9215 -:10419B0041303F09907697E054FEF0800790769778 -:1041AB00E04401F0907697E0908002F0303F34903D -:1041BB007619E0FFB4010E90767C7467F0A3740659 -:1041CB00F0A3740BF0EFB4020BE490767CF0A3F049 -:1041DB00A3740CF0EFB4030BE490767CF0A3F0A384 -:1041EB007418F0A240303E01B3501FA23E924030F3 -:1041FB003E09907695E04404F08007907695E05464 -:0B420B00FBF0907695E0908001F0221F -:0207FE00D32204 -:024DA100D3221B -:024DA300D32219 -:104BA000907FEAE0907682F0E4907691F0907692B1 -:0B4BB000F0907690F0907693F0D32206 -:104D5C00907682E0907F00F0907FB57401F0D322C2 -:10480000907FECE0907683F0E01460171460211440 -:10481000602B14603224047038907FEAE090769127 -:10482000F08035907FEAE0907692F0123E8F8028FB -:10483000907FEAE0907690F0121800801B907FEA5B -:10484000E0907684F08011907FEAE0907693F0809B -:0A48500007907FB4E04401F0D3228A -:10468500907FECE0907683F0E014601D14602A14AE -:10469500603714604424047050907691E0907F0058 -:1046A500F0907FB57401F08047907692E0907F009E -:1046B500F0907FB57401F08037907690E0907F00A0 -:1046C500F0907FB57401F08027907684E0907F00AC -:1046D500F0907FB57401F08017907693E0907F009D -:1046E500F0907FB57401F08007907FB4E04401F04D -:0246F500D322CE -:024DA500D32217 -:024DA700D32215 -:024DA900D32213 -:024DAB00C32221 -:102FE700C0E0C083C082D2265391EF907FAB7401BB -:082FF700F0D082D083D0E0325B -:104D4600C0E0C083C0825391EF907FAB7404F0D073 -:064D560082D083D0E032A0 -:103D4700C0E0C0F0C083C082C0D0E8C0E0E9C0E0F6 -:103D5700EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFB1 -:103D6700C0E0907FA2E090767FF0907F74E090763D -:103D770087F0907F75E0907688F0907F98E0440216 -:103D8700F0907696E0FF20E10C4402F0908003F07B -:103D9700D232124AC490767FE020E250907687E0D4 -:103DA700FEA3E07C002400F534EC3EF533907698D2 -:103DB700E0FDAE33AF341236D8907687EFF0D22FCE -:103DC700303129203F26C231907F94E054CFF090C4 -:103DD7007F9AE030E404D22DC22C907F9AE020E550 -:103DE70004C22DD22C907F94E04430F0124A501236 -:103DF7001B04302F12124216C22F75E80112168AC1 -:103E070075E80DD22B800575E801C22B202B349065 -:103E17007619E0FFB4010E90767C7467F0A3740600 -:103E2700F0A3740BF0EFB4020B90767CE4F0A3F0F0 -:103E3700A3740CF0EFB4030B90767CE4F0A3F0A32B -:103E47007418F075CAD375CBFED2CA303404C234A5 -:103E57008002D2345391EF907FAB7402F0F0907FE1 -:103E670098E054FDF0D0E0FFD0E0FED0E0FDD0E0D8 -:103E7700FCD0E0FBD0E0FAD0E0F9D0E0F8D0D0D029 -:083E870082D083D0F0D0E032BC -:104B6000C0E0C083C0825391EF907FAB7410F0908F -:104B70007696E054FDF0908003F0D082D083D0E0B0 -:014B80003202 -:012FFF00329F -:104BD500C0E0C083C082D2255391EF907FAB7408AB -:084BE500F0D082D083D0E03251 -:104BED00C0E0C083C0825391EF907FA9E04401F0F3 -:074BFD00D082D083D0E0322A -:104B8100C0E0C083C0825391EF907FAAE04401F05E -:0F4B9100C22990768D7401F0D082D083D0E032AB -:104C0400C0E0C083C0825391EF907FA9E04402F0DA -:074C1400D082D083D0E03212 -:103FD500C0E0C083C0825391EF907FAAE04402F015 -:103FE500907FC7E0F511750F00750D00D233D082B3 -:053FF500D083D0E03292 -:104C1B00C0E0C083C0825391EF907FA9E04404F0C1 -:074C2B00D082D083D0E032FB -:104C3200C0E0C083C0825391EF907FAAE04404F0A9 -:074C4200D082D083D0E032E4 -:104C4900C0E0C083C0825391EF907FA9E04408F08F -:074C5900D082D083D0E032CD -:104C6000C0E0C083C0825391EF907FAAE04408F077 -:074C7000D082D083D0E032B6 -:104C7700C0E0C083C0825391EF907FA9E04410F059 -:074C8700D082D083D0E0329F -:104C8E00C0E0C083C0825391EF907FAAE04410F041 -:074C9E00D082D083D0E03288 -:104CA500C0E0C083C0825391EF907FA9E04420F01B -:074CB500D082D083D0E03271 -:104CBC00C0E0C083C0825391EF907FAAE04420F003 -:074CCC00D082D083D0E0325A -:104CD300C0E0C083C0825391EF907FA9E04440F0CD -:074CE300D082D083D0E03243 -:104CEA00C0E0C083C0825391EF907FAAE04440F0B5 -:074CFA00D082D083D0E0322C -:104D0100C0E0C083C0825391EF907FA9E04480F05E -:074D1100D082D083D0E03214 -:104D1800C0E0C083C0825391EF907FAAE04480F046 -:074D2800D082D083D0E032FD -:10421600907619E064017035907687E0FFD3942D8F -:10422600402B9076867401F0907685E004F0E0D31A -:10423600940F4019E4F0EFD3943140089076197446 -:1042460003F080069076197402F0123E8F9076196C -:10425600E0B4022C907687E0FFC3942F5022EFD370 -:10426600942A401C9076867401F0907685E004F0DE -:10427600E0D3940F400AE4F090761904F0123E8FD2 -:10428600907619E0B40226907687E0D39431401DEB -:104296009076867401F0907685E004F0E0D3940F72 -:1042A600400BE4F09076197403F0123E8F90761965 -:1042B600E06403703F907687E0FFC3945F503590CB -:1042C60076867401F0907685E004F0E0D3940F4092 -:1042D60023E4F0EFC3942F500CEFD3942A400690BA -:1042E60076197401F0EFD3942F4006907619740274 -:1042F600F0123E8F907686E07005907685F022E487 -:05430600907686F02214 -:10074A0090769A7402F0E4907691F0A3F090769005 -:10075A00F0907693F09076967403F0908003F0E42C -:10076A00907697F0908002F090769404F090800052 -:10077A00F0E490768EF090761AF090769504F0C2B6 -:10078A002E907F9BE0FF5410FF7002C23F907F9B28 -:10079A00E0FF5410FEFFBE1002D23F907F9BE0FFA5 -:1007AA005420FF7002C23E907F9BE0FF5420FEFF60 -:1007BA00BE2002D23E303F09907697E054FEF08088 -:1007CA0007907697E04401F0907697E0908002F0E7 -:1007DA00303E09907695E04404F08007907695E0E3 -:1007EA0054FBF0907695E0908001F0A23E9240A2F0 -:0307FA003F9241EA -:0107FD0022D9 -:103E8F00907692E014601D147002E14424026002E7 -:103E9F00E1D49076947401F0908000F0E490768EE7 -:103EAF00F0D23122907619E0FFB4011BE4907FF23B -:103EBF00F0907FF37430F0907FFF74FCF090769762 -:103ECF00E054FDF054FBF0EFB4021BE4907FF2F0EE -:103EDF00907FF37434F0907FFF74FCF0907697E04E -:103EEF004402F054FBF0EFB40318E4907FF2F0902B -:103EFF007FF37464F0907FFF74FCF0907697E0444A -:103F0F0004F0907694E04401F0908000F0303F0987 -:103F1F00907697E054FEF08007907697E04401F09A -:103F2F00907697E0908002F09076987404F09076F7 -:103F3F008E7401F022907619E0FFB4011BE4907F9C -:103F4F00F2F0907FF37444F0907FFF74FCF0907662 -:103F5F0097E054FDF054FBF0EFB4021BE4907FF2B6 -:103F6F00F0907FF3744CF0907FFF74FCF090769795 -:103F7F00E04402F054FBF0EFB40318E4907FF2F04A -:103F8F00907FF37494F0907FFF74FCF0907697E03D -:103F9F004404F0907694E054FEF0908000F0303FAF -:103FAF0009907697E054FEF08007907697E04401F1 -:103FBF00F0907697E0908002F09076987406F090EB -:063FCF00768E7402F02260 -:10180000907690E014603714700201D814700221B1 -:1018100072147002413B240460026103907FFC74E7 -:10182000CCF0907FFF74FCF0907695E04401F0548A -:1018300005F0908001F0E490761AF0C22E229076A6 -:1018400095E04401F04402F0303E06E04404F080AC -:1018500007907695E054FBF090761AE0B40108907A -:101860007695E0908001F0907619E0FFB401229027 -:101870007FFC7474F0907FFF74FCF090768F742B73 -:10188000F0907697E054FDF0E4907681F0907680C9 -:10189000F0EFB40222907FFC7468F0907FFF74FC3C -:1018A000F090768F742FF0907697E04402F0E490F9 -:1018B0007681F0907680F0303F09907697E054FE84 -:1018C000F08007907697E04401F0907697E054FB23 -:1018D000F0908002F0D22E22907695E054FEF044F3 -:1018E00002F0303E06E04404F08007907695E05424 -:1018F000FBF090761AE0B40108907695E0908001B4 -:10190000F0907619E0FFB40122907FFC7430F090E3 -:101910007FFF74FCF090768F742BF0907697E054F4 -:10192000FDF0E4907681F0907680F0EFB4022290A2 -:101930007FFC741CF0907FFF74FCF090768F742F06 -:10194000F0907697E04402F0E4907681F090768013 -:10195000F0303F09907697E054FEF080079076973C -:10196000E04401F0907697E054FBF0908002F0D2D2 -:101970002E22907695E04401F04402F04408F030C5 -:101980003E06E04404F08007907695E054FBF0902A -:10199000761AE0B40108907695E0908001F0907698 -:1019A00019E0FFB40125907FFC74CCF0907FFF74A8 -:1019B000FCF090768F742BF0907697E054FDF05405 -:1019C000FBF0E4907681F0907680F0EFB402259001 -:1019D0007FFC74C8F0907FFF74FCF090768F742FBA -:1019E000F0907697E04402F054FBF0E4907681F0BA -:1019F000907680F0EFB40325907FFC7498F0907F90 -:101A0000FF74FCF090768F745FF0907697E054FD51 -:101A1000F04404F0E4907681F0907680F0303F0955 -:101A2000907697E054FEF08007907697E04401F0BE -:101A3000907697E0908002F0D22E22907695E05436 -:101A4000FEF04402F04408F0303E06E04404F0802A -:101A500007907695E054FBF090761AE0B401089078 -:101A60007695E0908001F0907619E0FFB401259022 -:101A70007FFC74B4F0907FFF74FCF090768F742B31 -:101A8000F0907697E054FDF054FBF0E4907681F00E -:101A9000907680F0EFB40225907FFC74B0F0907FD8 -:101AA000FF74FCF090768F742FF0907697E04402EC -:101AB000F054FBF0E4907681F0907680F0EFB40380 -:101AC00025907FFC7468F0907FFF74FCF090768F17 -:101AD000745FF0907697E054FDF04404F0E4907663 -:101AE00081F0907680F0303F09907697E054FEF0D8 -:101AF0008007907697E04401F0907697E09080021E -:041B0000F0D22E22CF -:040CA1004176230075 -:102DA900E4907636F0E0FF75F003A4240EF582E492 -:102DB9003475F5837401F0EF75F003A4240FF582DF -:102DC900E43475F5837401F0EF75F003A42410F56C -:102DD90082E43475F583E4F0907636E004F0E0FFA0 -:102DE90075F003A4240EF582E43475F5837410F0AC -:102DF900EF75F003A4240FF582E43475F5837405A7 -:102E0900F0EF75F003A42410F582E43475F583E43A -:102E1900F0907636E004F0E0FF75F003A4240EF597 -:102E290082E43475F5837402F0EF75F003A4240F7E -:102E3900F582E43475F5837402F0EF75F003A42488 -:102E490010F582E43475F583E4F0907636E004F009 -:102E5900E0FF75F003A4240EF582E43475F583745C -:102E690001F0EF75F003A4240FF582E43475F583BE -:102E79007403F0EF75F003A42410F582E43475F5BA -:102E890083E4F0907636E004F0E0FF75F003A424C3 -:102E99000EF582E43475F5837410F0EF75F003A430 -:102EA900240FF582E43475F5837406F0EF75F003A9 -:102EB900A42410F582E43475F583E4F0907636E0C5 -:102EC90004F0E0FF75F003A4240EF582E43475F5EF -:102ED900837402F0EF75F003A4240FF582E43475CE -:102EE900F5837404F0EF75F003A42410F582E4343B -:102EF90075F583E4F0907636E004F0E0FF75F003B1 -:102F0900A4240EF582E43475F5837402F0EF75F0AC -:102F190003A4240FF582E43475F5837408F0EF7582 -:102F2900F003A42410F582E43475F5837404F09059 -:102F39007636E004F0E0FF75F003A4240EF582E490 -:102F49003475F5837402F0EF75F003A4240FF5824C -:102F5900E43475F583740AF0EF75F003A42410F5D1 -:102F690082E43475F5837404F0907636E004F0E079 -:102F7900FF75F003A4240EF582E43475F583740219 -:102F8900F0EF75F003A4240FF582E43475F583742A -:102F990009F0EF75F003A42410F582E43475F58384 -:102FA9007404F0907636E004F0E0FF75F003A42491 -:102FB9000EF582E43475F5837402F0EF75F003A41D -:102FC900240FF582E43475F5837407F0EF75F00387 -:0E2FD900A42410F582E43475F5837404F0220C -:103BD300E4907636F0E0FB75F00FA42441F582E41F -:103BE3003475F5837440F0EB75F00FA42442F5822D -:103BF300E43475F583740AF0EB75F00FA42443F5F0 -:103C030082E43475F5831237C80000AC44EB75F0D9 -:103C13000FA42447F582E43475F5831237C80000F6 -:103C2300AC44EB75F00FA4244BF582E43475F583B3 -:103C33001237C800017700907636E004F0E0FB7598 -:103C4300F00FA42441F582E43475F5837440F0EB5E -:103C530075F00FA42442F582E43475F583748CF077 -:103C6300EB75F00FA42443F582E43475F583123722 -:103C7300C80000AC44EB75F00FA42447F582E4348C -:103C830075F5831237C80000AC44EB75F00FA4241C -:103C93004BF582E43475F5831237C8000177009041 -:103CA3007636E004F0E0FF75F00FA42441F582E4DA -:103CB3003475F5837440F0EF75F00FA42442F58258 -:103CC300E43475F583748FF0907636E004F0E0FF0A -:103CD30075F00FA42441F582E43475F5837441F043 -:103CE300EF75F00FA42442F582E43475F5837484F0 -:103CF300F0907636E004F0E0FF75F00FA42441F570 -:103D030082E43475F5837461F0EF75F00FA42442F7 -:103D1300F582E43475F5837481F0907636E004F02F -:103D2300E0FF75F00FA42441F582E43475F5837444 -:103D330061F0EF75F00FA42442F582E43475F58346 -:043D43007401F022F5 -:10455900E4907636F0E0FF75F003A42432F582E4A6 -:104569003475F583E4F0EF75F003A42433F582E4A0 -:104579003475F5837401F0907636E004F0E0FF7548 -:10458900F003A42432F582E43475F583E4F0EF7581 -:10459900F003A42433F582E43475F5837402F090B2 -:1045A9007636E004F0E0FF75F003A42432F582E4E6 -:1045B9003475F583E4F0EF75F003A42433F582E450 -:1045C9003475F5837403F0907636E004F0E0FF75F6 -:1045D900F003A42432F582E43475F583E4F0EF7531 -:1045E900F003A42433F582E43475F5837404F022CE -:103A4200E4907635F0907635E0FFC394034002416E -:103A5200FFEF75F00AA424AAF582E43475F583EF2A -:103A6200F0EF75F00AA424ABF582E43475F583E433 -:103A7200F0EF75F00AA424ACF582E43475F5837492 -:103A8200F0F0EF75F00AA424ADF582E43475F58305 -:103A920074FFF0EF75F00AA424AEF582E43475F5F4 -:103AA20083E4F0EF75F00AA424AFF582E43475F5EF -:103AB200837480F0EF75F00AA424B0F582E43475C3 -:103AC200F583E4F0EF75F00AA424B1F582E43475CD -:103AD200F583E4F0EF75F00AA424B2F582E43475BC -:103AE200F583E4F0EF75F00AA424B3F582E43475AB -:103AF200F5837401F0907635E004F0414790763C0E -:103B0200740AF0E4A3F09076357403F090763CE00A -:103B1200FF907635E0FEC39F400261D290763DE091 -:103B2200FF04F0EE75F00AA424AAF582E43475F5D8 -:103B320083EFF0EE75F00AA424ABF582E43475F558 -:103B420083E4F0EE75F00AA424ACF582E43475F552 -:103B520083745EF0EE75F00AA424ADF582E4347548 -:103B6200F58374BAF0EE75F00AA424AEF582E4345B -:103B720075F5837405F0EE75F00AA424AFF582E4BE -:103B82003475F5837480F0EE75F00AA424B0F582E2 -:103B9200E43475F583E4F0EE75F00AA424B1F582FD -:103BA200E43475F583E4F0EE75F00AA424B2F582EC -:103BB200E43475F5837415F0EE75F00AA424B3F5B8 -:103BC20082E43475F583E4F0907635E004F0610E1A -:013BD20022D0 -:10080000E4907631F0907631E0FF75F003A4240F88 -:10081000F582E43475F583E0FE907FEDE0FDEE6D4A -:10082000600EEFC3940B5008907631E004F080D551 -:10083000EFB40B08907FB4E04401F022EF75F003B1 -:10084000A4240EF582E43475F583E0907633F02429 -:10085000F0600A240E60028187124B3E22907FEDE9 -:10086000E0640570519076187405F0907637740145 -:10087000F09076397403F0907621F0E4907620F0D1 -:10088000907FEAE0F4602F907620E0FF75F00AA4F4 -:1008900024AAF582E43475F583E0FE907FEAE0FD5A -:1008A000EE6D6012907621E0FEEFC39E50089076C8 -:1008B00020E004F080D1907FEDE0640670529076E5 -:1008C000187406F09076377404F0907639740AF054 -:1008D000907621F09076207403F0907FEAE0F46047 -:1008E0002F907620E0FF75F00AA424AAF582E43464 -:1008F00075F583E0FE907FEAE0FDEE6D6012907684 -:1009000021E0FEEFC39E5008907620E004F080D1F5 -:10091000907620E0FF75F00AA424AAF582E43475ED -:10092000F583E0907229F0E490763BF0907621E038 -:10093000FEEF6E7008907FB4E04401F022907FEBF0 -:10094000E014601314700221E224026002817F909F -:100950007FB4E04401F022907FE9E014707C907F46 -:10096000EAE0F47048907637E0907620F09076399F -:10097000E0FE907620E0FDC39E502B90763BE0FE9B -:1009800004F074C02EF582E4347EF583E0FEED754C -:10099000F00AA424ABF582E43475F583EEF090768A -:1009A00020E004F080C790763F7401F022907EC072 -:1009B000E0FEEF75F00AA424ABF582E43475F5830C -:1009C000EEF0E0B4010890763E7401F08005E4900A -:1009D000763EF090763F7401F022907FB4E04401BF -:1009E000F022907FE9E024FE700241A314700261BE -:1009F0003F14700261DB240360028177907FEAE09C -:100A0000F4706B907637E0907620F0907639E0FFC6 -:100A1000907620E0FEC39F504E90763BE0FF04F0BE -:100A200074C02FF582E4347EF583E0FFEE75F00AA2 -:100A3000A424ACF582E43475F583EFF090763BE0C6 -:100A4000FF04F074C02FF582E4347EF583E0FFEEFE -:100A500075F00AA424ADF582E43475F583EFF090C7 -:100A60007620E004F080A49076407401F022907E1D -:100A7000C0E0FF907620E0FE75F00AA424ACF58279 -:100A8000E43475F583EFF0907EC1E0FFEE75F00A77 -:100A9000A424ADF582E43475F583EFF090764174CB -:100AA00001F022907FEAE0F47066907637E090766D -:100AB00020F0907639E0FF907620E0FEC39F400260 -:100AC000818E90763BE0FF04F074C02FF582E43411 -:100AD0007EF583E0FFEE75F00AA424AEF582E434DF -:100AE00075F583EFF090763BE0FF04F074C02FF5CE -:100AF00082E4347EF583E0FFEE75F00AA424AFF5BE -:100B000082E43475F583EFF0907620E004F080A263 -:100B1000907EC0E0FF907620E0FE75F00AA424AE3F -:100B2000F582E43475F583EFF0907EC1E0FFEE7559 -:100B3000F00AA424AFF582E43475F583EFF0229037 -:100B40007FEAE0F47066907637E0907620F0907659 -:100B500039E0FF907620E0FEC39F4002818E9076C0 -:100B60003BE0FF04F074C02FF582E4347EF583E0AF -:100B7000FFEE75F00AA424B0F582E43475F583EF36 -:100B8000F090763BE0FF04F074C02FF582E4347EF1 -:100B9000F583E0FFEE75F00AA424B1F582E4347524 -:100BA000F583EFF0907620E004F080A2907EC0E024 -:100BB000FF907620E0FE75F00AA424B0F582E434BC -:100BC00075F583EFF0907EC1E0FFEE75F00AA42486 -:100BD000B1F582E43475F583EFF022907FEAE0F41A -:100BE0007066907637E0907620F0907639E0FF904E -:100BF0007620E0FEC39F4002818E90763BE0FF04AA -:100C0000F074C02FF582E4347EF583E0FFEE75F0DA -:100C10000AA424B2F582E43475F583EFF090763BB4 -:100C2000E0FF04F074C02FF582E4347EF583E0FF2A -:100C3000EE75F00AA424B3F582E43475F583EFF081 -:100C4000907620E004F080A2907EC0E0FF907620B5 -:100C5000E0FE75F00AA424B2F582E43475F583EF62 -:100C6000F0907EC1E0FFEE75F00AA424B3F582E4B3 -:100C70003475F583EFF022907FB4E04401F02290C8 -:0F0C80007FB4E04401F022907FB4E04401F02201 -:10100000E490762CF090762CE0FF75F003A4240F8A -:10101000F582E43475F583E0FE907FEDE0FDEE6D42 -:10102000600EEFC3940B500890762CE004F080D54E -:10103000EFB40B08907FB4E04401F022EF75F003A9 -:10104000A4240EF582E43475F583E090762EF02426 -:10105000F0600A240F6002817D124B1B22907FED0D -:10106000E0640570519076187405F090763874013C -:10107000F090763A7403F090761CF0E490761BF0D2 -:10108000907FEAE0F4602F90761BE0FF75F00AA4F1 -:1010900024AAF582E43475F583E0FE907FEAE0FD52 -:1010A000EE6D601290761CE0FEEFC39E50089076C5 -:1010B0001BE004F080D1907FEDE0640670529076E2 -:1010C000187406F09076387404F090763A740AF04A -:1010D00090761CF090761B7403F0907FEAE0F46049 -:1010E0002F90761BE0FF75F00AA424AAF582E43461 -:1010F00075F583E0FE907FEAE0FDEE6D601290767C -:101100001CE0FEEFC39E500890761BE004F080D1F7 -:10111000E490761EF090761CE0FF90761BE0FE6F68 -:101120007008907FB4E04401F022907FEBE01460FF -:101130001314700221BF240260028175907FB4E015 -:101140004401F022907FE9E0247F706B907FEAE019 -:10115000F4704A907638E090761BF090763AE0FF93 -:1011600090761BE0FDC39F502BED75F00AA424ABD5 -:10117000F582E43475F583E0FF90761EE0FD04F01F -:1011800074002DF582E4347FF583EFF090761BE058 -:1011900004F080C790761EE0907FB5F022EE75F0E7 -:1011A0000AA424ABF582E43475F583E0907F00F067 -:1011B000907FB57401F022907FB4E04401F022905A -:1011C0007FE9E0247E7002417E1470026123147076 -:1011D0000261C824036002816D907FEAE0F4706DC3 -:1011E000907638E090761BF090763AE0FF90761B90 -:1011F000E0C39F504FE0FF75F00AA424ACF582E4F1 -:101200003475F583E0FE90761EE0FD04F074002D49 -:10121000F582E4347FF583EEF0EF75F00AA424AD97 -:10122000F582E43475F583E0FF90761EE0FE04F06D -:1012300074002EF582E4347FF583EFF090761BE0A6 -:1012400004F080A490761EE0907FB5F02290761B8B -:10125000E0FF75F00AA424ACF582E43475F583E070 -:10126000907F00F0EF75F00AA424ADF582E43475A8 -:10127000F583E0907F01F0907FB57402F022907FBB -:10128000EAE0F4706D907638E090761BF090763A54 -:10129000E0FF90761BE0C39F504FE0FF75F00AA47B -:1012A00024AEF582E43475F583E0FE90761EE0FD11 -:1012B00004F074002DF582E4347FF583EEF0EF75D1 -:1012C000F00AA424AFF582E43475F583E0FF90764C -:1012D0001EE0FE04F074002EF582E4347FF583EF07 -:1012E000F090761BE004F080A490761EE0907FB52D -:1012F000F02290761BE0FF75F00AA424AEF582E49C -:101300003475F583E0907F00F0EF75F00AA424AF08 -:10131000F582E43475F583E0907F01F0907FB57439 -:1013200002F022907FEAE0F4706D907638E09076DB -:101330001BF090763AE0FF90761BE0C39F504FE0A1 -:10134000FF75F00AA424B0F582E43475F583E0FE5D -:1013500090761EE0FD04F074002DF582E4347FF5F4 -:1013600083EEF0EF75F00AA424B1F582E43475F54C -:1013700083E0FF90761EE0FE04F074002EF582E418 -:10138000347FF583EFF090761BE004F080A4907634 -:101390001EE0907FB5F02290761BE0FF75F00AA466 -:1013A00024B0F582E43475F583E0907F00F0EF75AA -:1013B000F00AA424B1F582E43475F583E0907F014E -:1013C000F0907FB57402F022907FEAE0F4706D90A7 -:1013D0007638E090761BF090763AE0FF90761BE04E -:1013E000C39F504FE0FF75F00AA424B2F582E434A5 -:1013F00075F583E0FE90761EE0FD04F074002DF597 -:1014000082E4347FF583EEF0EF75F00AA424B3F59F -:1014100082E43475F583E0FF90761EE0FE04F074FC -:10142000002EF582E4347FF583EFF090761BE00424 -:10143000F080A490761EE0907FB5F02290761BE0BD -:10144000FF75F00AA424B2F582E43475F583E090C8 -:101450007F00F0EF75F00AA424B3F582E43475F54B -:1014600083E0907F01F0907FB57402F022907FB40A -:10147000E04401F022907FB4E04401F022907FB478 -:05148000E04401F02230 -:10387400E4907629F0907629E0FF75F00FA42442B5 -:10388400F582E43475F583E0FE907FECE0FDEE6DA7 -:10389400600EEFC394065008907629E004F080D5BA -:1038A400EFB40608907FB4E04401F022EF75F00F06 -:1038B400A42441F582E43475F583E090762AF0245B -:1038C400BF7002414124E070024112242160024190 -:1038D4003A907FE9E024FE607D14700221B2240254 -:1038E4006002410A121751907642E0FCA3E0FDA366 -:1038F400E0FEA3E0FF907629E075F00FA42443F5E1 -:1039040082E43475F5831237BC907619E0FFB40174 -:103914001290767C7467F090767D7406F090767ED3 -:10392400740BF0EFB4020FE490767CF090767DF0A7 -:1039340090767E740CF0EFB4030FE490767CF090F4 -:10394400767DF090767E7418F090761A7401F012F9 -:103954003E8F12180022907EC2E0FFE4FCFDFEFBC5 -:10396400FA7901F8123746C8ECC8C9EDC9CAEECADB -:10397400CBEFCB907EC1E0FEE4FCFD2BFBEA3EFAEC -:10398400ED39F9EC38F8907EC0E0FFE4FEEB2FFF50 -:10399400EE3AFEED39FDEC38FC907629E075F00F37 -:1039A400A42447F582E43475F5831237BC22907E53 -:1039B400C2E0FFE4FCFDFEFBFA7901F8123746C8C9 -:1039C400ECC8C9EDC9CAEECACBEFCB907EC1E0FE0C -:1039D400E4FCFD2BFBEA3EFAED39F9EC38F8907E75 -:1039E400C0E0FFE4FEEB2FFFEE3AFEED39FDEC38CC -:1039F400FC907629E075F00FA4244BF582E434752D -:103A0400F5831237BC22907FB4E04401F022907F0A -:103A1400E9E0147019907EC0E0FF907629E075F01B -:103A24000FA4244FF582E43475F583EFF022907FE0 -:0E3A3400B4E04401F022907FB4E04401F0229F -:102AD600E4907627F0907627E0FF75F00FA4244265 -:102AE600F582E43475F583E0FE907FECE0FDEE6D53 -:102AF600600EEFC394065008907627E004F080D568 -:102B0600EFB40608907FB4E04401F022EF75F00FB1 -:102B1600A42441F582E43475F583E0907628F02408 -:102B26009F7002A17424216002A1A1907FE9E02494 -:102B36007E700261FC14700281B524026002A16CF1 -:102B4600EF75F00FA42443F582E43475F583E0FCB9 -:102B5600A3E0FDA3E0FEA3E0FF7B447AAC79007816 -:102B660000C31237AB7013907F007444F0A374ACAB -:102B7600F0E4A3F0907FB57403F0907627E075F04B -:102B86000FA42443F582E43475F583E0FCA3E0FD4D -:102B9600A3E0FEA3E0FF7B807ABB79007800C31236 -:102BA60037AB7013907F007480F0A374BBF0E4A37E -:102BB600F0907FB57403F0907627E075F00FA424AB -:102BC60043F582E43475F583E0FCA3E0FDA3E0FE63 -:102BD600A3E0FF7B007A7779017800C31237AB60F8 -:102BE60002A1A8907F00F0A37477F0A37401F0907F -:102BF6007FB57403F022907627E075F00FA4244782 -:102C0600F582E43475F583E0FCA3E0FDA3E0FEA3C2 -:102C1600E0FF7B447AAC79007800C31237AB7013BF -:102C2600907F007444F0A374ACF0E4A3F0907FB5F9 -:102C36007403F0907627E075F00FA42447F582E43C -:102C46003475F583E0FCA3E0FDA3E0FEA3E0FF7B83 -:102C5600807ABB79007800C31237AB7013907F007F -:102C66007480F0A374BBF0E4A3F0907FB57403F016 -:102C7600907627E075F00FA42447F582E43475F5C5 -:102C860083E0FCA3E0FDA3E0FEA3E0FF7B007A77F0 -:102C960079017800C31237AB6002A1A8907F00F0DB -:102CA600A37477F0A37401F0907FB57403F02290BB -:102CB6007627E075F00FA4244BF582E43475F5838E -:102CC600E0FCA3E0FDA3E0FEA3E0FF7B447AAC7941 -:102CD600007800C31237AB7013907F007444F0A3E2 -:102CE60074ACF0E4A3F0907FB57403F0907627E01F -:102CF60075F00FA4244BF582E43475F583E0FCA34C -:102D0600E0FDA3E0FEA3E0FF7B807ABB79007800BC -:102D1600C31237AB7013907F007480F0A374BBF0BE -:102D2600E4A3F0907FB57403F0907627E075F00F7A -:102D3600A4244BF582E43475F583E0FCA3E0FDA3FF -:102D4600E0FEA3E0FF7B007A7779017800C31237B3 -:102D5600AB704F907F00F0A37477F0A37401F090EE -:102D66007FB57403F022907FB4E04401F022907F97 -:102D7600E9E0247F701E907627E075F00FA4244FBB -:102D8600F582E43475F583E0907F00F0907FB574AA -:102D960001F08007907FB4E04401F0907FB4E044F6 -:032DA60001F02217 -:104B1B00907FEBE0147014907FE9E0247F70041217 -:104B2B00485A22907FB4E04401F022907FB4E044D5 -:034B3B0001F02264 -:104B3E00907FEBE0147013907FE9E014700412493B -:104B4E00AD22907FB4E04401F022907FB4E04401A6 -:024B5E00F02243 -:10485A00E4907626F0907626E0FF75F003A42434DF -:10486A00F582E43475F583E0FE907FECE0FDEE6DB1 -:10487A00600EEFC394045008907626E004F080D5C9 -:10488A00EFB40408907FB4E04401F022EF75F0031E -:10489A00A42432F582E43475F583E0907F00F09029 -:0648AA007FB57401F0224D -:1049AD00E4907625F0907625E0FF75F003A424348D -:1049BD00F582E43475F583E0FE907FECE0FDEE6D5D -:1049CD00600EEFC394045008907625E004F080D576 -:1049DD00EFB40408907FB4E04401F022907EC0E073 -:1049ED00FEEF75F003A42432F582E43475F583EE01 -:0249FD00F022A6 -:03000300020FFDEC -:030FFD00C2893274 -:030013000217FDD4 -:0317FD00C28B326A -:03004B00024D8FD4 -:044D8F005391DF322B -:03005300024D83D8 -:064D83005391BFD22D3256 -:03005B00024D89CA -:064D890053917FD22C3291 -:03006300024D93B8 -:044D930053D8F732C8 -:03000B00024D9B08 -:034D9B00C28D3294 -:03001B00024D9EF5 -:034D9E00C28F328F -:03002300024D7516 -:074D75005398FE5398FD3234 -:03003B00024D7CF7 -:074D7C0053C0FE53C0FD32DD -:03002B000246F793 -:1046F700C0E0C0F0C083C082C0D0E8C0E0E9C0E03D -:10470700EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFF7 -:10471700C0E0C2CAC2CF907F98E04401F0302E03B8 -:104727001214A6907F98E054FEF053A8FA1216616F -:10473700D0E0FFD0E0FED0E0FDD0E0FCD0E0FBD041 -:10474700E0FAD0E0F9D0E0F8D0D0D082D083D0F032 -:03475700D0E0327D -:1047B400E490769BF090769BE0FF04F0EF6008E0D5 -:1047C4002408F8E4F680EE907696E054FBF054F773 -:1047D400F0908003F0E4F518D235F50EF510D236DA -:1047E400751211751322C237C239C238F516F51481 -:0B47F400F51AF50DC23BC23CC23D228D -:10300000907FB6E020E102C23DD236203602416E0A -:10301000303D02416E908007E06004D2368002C2EB -:1030200036203602412ED235E4F51A908004E0F5C0 -:10303000197408250EF8A619851918E51820E70453 -:10304000D2388002C23830380221D4E4F516E519AE -:10305000B4F00CD2397508047509F0050E8002052C -:1030600016E51964F7703DC239E50E24FE601714A9 -:103070006022240370297508057509F7E4F50AF53F -:103080000B750E048020750806750AF7E4F50B75BC -:103090000E048012750807750BF7750E0480071271 -:1030A00048F380020516E51954F864F8703BC23500 -:1030B000E5192407600C24FC6008240524F8500658 -:1030C0008008D23A8006C23A8002D23A751A0120AC -:1030D0003A19907E80740FF0A3E519F0E4A3F0A3F1 -:1030E000F0907FB77404F08002051620396DE51961 -:1030F00064F76067E51A7063E51854F064F070597E -:10310000851819F50EE519240F601B24FE6017249D -:10311000FD602214601F2405702F750803050E85BD -:103120001809D2378028750802050E85180975140C -:1031300001D2378019750805050E851809E4F50ACE -:10314000F50B750E03D23780051248F3C2353035C2 -:103150000A85081385181280020516851819E516C8 -:1031600064047062F50EE51954F0F519F51585182B -:1031700019E5152470601824F0601424F060102400 -:10318000F0601E24F0601A24F0600424607027E5CB -:1031900015C4540FF519F508050E851809D23780A6 -:1031A0001AE515C4540FF519F508050E85180975AB -:1031B0001401D23780051248F3C23530350A85191B -:1031C0001385181280020516E516D3940540571290 -:1031D00048F38052303917E50E700A8508097508E2 -:1031E00004050E80417408250EF8A6198038203792 -:1031F0002AE50EB4010F85080A85090B8513088599 -:103200001209750E04E514B4011C85080AE4F50BD7 -:10321000851308851209750E04800BE514B40106A8 -:10322000E4F50B750E04E4F51A303502050EE50ED3 -:10323000D394035002010BC237E4F50EF510C236E9 -:10324000D23DF51474082510F8E6FF74802510F5BA -:1032500082E4347EF583EFF074082510F8E4F60577 -:0F32600010E510B404DE907FB77404F0010B2268 -:0C48F300C237E4F50EF510C236F51422B1 -:10400000E511D3940050022106907689E0C394080C -:10401000400221067440250FF582E4347EF583E0EA -:10402000F517E50D600E908005E517F0907689E0B4 -:1040300004F001DAE5171237F940C1024067054084 -:104040007A0640980740C10C40C10D40C70F40CBD5 -:10405000F640CBF840CBFA40CBFB40CBFC40CBFE4C -:1040600040CBFF000040DA907E41E0908005F09068 -:104070007689E004F07511018060907E41E09080C7 -:1040800005F0907E42E0908005F0907689E004F0A3 -:10409000E004F07511018042907E41E0908005F0CF -:1040A000907E42E0908005F0907E43E0908005F0A5 -:1040B000907689E004F0E004F0E004F075110180EE -:1040C00019D23BD23C8013D23B800F908005E5177C -:1040D000F0907689E004F0751101203B04050D8015 -:1040E0001F303C1C907E41E0908005F0907E42E0C5 -:1040F000908005F0907689E004F0E004F0751101FD -:10410000050F15110100E5117010C233F50DF50F03 -:0B411000907FC77404F0C23BC23C2249 -:104BBB00907FD6E030E712E04401F07F147E0012C4 -:0A4BCB004D2F907FD6E054FEF0223B -:104AF600907FD6E054FBF0E04408F0304204E044F6 -:104B060002F07FDC7E05124D2F907FD6E054F7F041 -:054B1600E04404F02260 -:104D2F008E358F36E5361536AE35700215354E6039 -:074D3F000512148580EE222D -:1049FF00E4FE751DFF751E05751F12AB1DAA1EA9BE -:104A0F001F9000011236AB6402702FCDEECD0EED6C -:104A1F006F70012290000212370E85F01BF51C6299 -:104A2F001BE51B621CE51C621B29FDE51B3AC9ED4A -:104A3F00C9751DFFF51E891F80C17B007A007900A3 -:014A4F002244 -:041794008D298B2AE6 -:101798001249FFEA4960571236927E0029FFEE3A55 -:1017A800C9EFC9752BFFF52C892DAB2BAA2CA92DB8 -:1017B8009000011236ABFF64046005EF6405702EDB -:1017C800EFB404159000021236AB6529700B900037 -:1017D800031236AB652A7001221236927E0029FF69 -:1017E800EE3AC9EFC9752BFFF52C892D80BC7B001B -:0417F8007A007900FA -:0117FC0022CA -:0248B0008F2E49 -:1048B200E4F52F7530FF7531067532BEAB30AA3183 -:1048C200A9329000011236ABB4031FAF2F052FEFB0 -:1048D200652E7001221236927E0029FFEE3AC9EF50 -:1048E200C97530FFF531893280D27B007A007900B8 -:0148F20022A3 -:1005000012011001000000406A08110100010102FF -:1005100000010902AC01030100803209040000005F -:10052000010100000A2401000156000201020C240E -:10053000020101010002000000000D240605010275 -:10054000030000000000000924030204030005006A -:100550000C24020305020006000000001524060614 -:100560000302000003000300030003000300030074 -:100570000009240304010100060009040100000130 -:100580000200000904010102010200000724010128 -:10059000000100112402010202100344AC0080BBE0 -:1005A0000000770109050A05840101008F07250174 -:1005B0000100000009058F01030001050009040185 -:1005C00002020102000007240101000100112402BF -:1005D000010203180344AC0080BB00007701090549 -:1005E0000A05460201008F072501010000000905E8 -:1005F0008F01030001050009040200000102000050 -:1006000009040201010102000007240104000100A5 -:100610000E2402010602100244AC0080BB00090552 -:100620008C054C02010000072501000200000904AE -:1006300002020101020000072401040001000E244F -:1006400002010603180244AC0080BB0009058C05BA -:1006500072030100000725010002000009040203E3 -:10066000010102000007240104000100112402011D -:100670000202100344AC0080BB0000770109058C26 -:1006800005840101000007250100020000090402A1 -:1006900004010102000007240104000100112402EA -:1006A000010203180344AC0080BB00007701090578 -:1006B0008C0546020100000725010002000004032A -:1006C0000904180345006D006100670069006300BC -:1006D000200047006D0062004800220345006D00C5 -:1006E0006100670069006300200045004D0049007B -:1006F000200036007C00320020006D002A034300F9 -:100700006F006E006600690067007500720061008E -:10071000740069006F006E002000530074007200C6 -:1007200069006E006700220349006E0074006500D6 -:1007300072006600610063006500200053007400D1 -:0A074000720069006E0067000000FF -:101485007400F58690FDA57C05A3E582458370F97A -:011495002234 -:10149600907FD6E04480F0438701000000000022E0 -:1014A600C0D0C0E08FE0C0E08EE0C0E08DE0C0E0DC -:1014B6008CE0C0E0C082C0830586C084C0857D0004 -:1014C600907FE3747BF0A37480F07C11907F99E0A9 -:1014D6005440DC030214F3B40013907FE27440F02E -:1014E600907FE5F0907FE27400F00214D29076903F -:1014F600E0B4011290768FE02DFD907FE27480F0CB -:10150600907F6C021557B4021290768FE02DFD90F5 -:101516007FE27480F0907F6C021596B40312907689 -:101526008FE02DFD907FE27480F0907F6C0215E1D4 -:10153600B4041290768FE02DFD907FE27480F090D7 -:101546007F6C021610907FE27480F0907F6C02161A -:1015560040F0F0F0F0F0F0F0F0F0F0F0F0DDF27DB9 -:10156600020586907FE27400F0907F9BE05404B4FD -:1015760000050586021640907FE27480F00586F02D -:10158600F0F0F0F0F0F0F0F0F0F0F0DDD4021640FC -:10159600F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F045 -:1015A600F0F0DDEC7D020586907FE27400F0907F1E -:1015B6009BE05404B400050586021640907FE27451 -:1015C60080F00586F0F0F0F0F0F0F0F0F0F0F0F0DA -:0615D600F0F0F0F0F0F06F -:1015DC00DDCE021640F0F0F0F0DDFA7D02058690CB -:1015EC007FE27400F0907F9BE05404B40005058604 -:1015FC00021640907FE27480F00586F0F0F0F0DD8A -:10160C00DC021640F0F0F0F0F0F0DDF87D0205861B -:10161C00907FE27400F0907F9BE05404B4000505C9 -:10162C0086021640907FE27480F00586F0F0F0F0B0 -:10163C00F0F0DDDA907FE27400F0D085D08405867E -:10164C00D083D082D0E0FCD0E0FDD0E0FED0E0FF33 -:05165C00D0E0D0D02217 -:10166100C0D0C0E0C082C08390767CE0907F6FF0F4 -:1016710090767DE0907F6FF090767EE0907F6FF0C6 -:09168100D083D082D0E0D0D02249 -:10168A00C0D0C0E08FE0C0E08EE0C0E0C082C0837E -:10169A000586C084C085907687E0FFBF00030217E5 -:1016AA0001907F96E04480F0907FE27480F0907F12 -:1016BA0062E00586907FE27400F0907F96E0547FA6 -:1016CA00F0907FE27480F090768EE0B40105058692 -:1016DA000216F6B4020505860216EB05860216FB0B -:1016EA00E0E0E0E0E0E0DFF80216FBE0E0E0E0DF67 -:1016FA00FA907FE27400F0D085D0840586D083D03A -:0C170A0082D0E0FED0E0FFD0E0D0D02282 -:10171600C082C083C0E0E8C0E078D1E814F870FB6E -:0A172600D0E0F8D0E0D083D082229A -:100CA500417201014572050002C9000045720A0042 -:100CB500010203044D720FD100D1000000000000B5 -:100CC500282809004D721C010001020304050607CE -:100CD50008090A0B41722E2241722F2341723020DE -:100CE5004172312162D2723A00000000000000001A -:100CF50000000000000000000000000000000000EF -:100D050000000000000000000000000000000000DE -:100D150000000000000000000000000000000000CE -:100D250000000000000000000000000000000000BE -:100D350000000000000000000000000000000000AE -:100D4500000000000000000000000000000000009E -:100D5500000000000000000000000000000000008E -:100D6500000000000000000000000000000000007E -:100D75000000000000000000000001010101010168 -:100D8500010101010101010101010101010101014E -:100D9500010101010101010101010101010101013E -:100DA500010101010101010101010101010101012E -:100DB5000101010101010101020202020202020216 -:100DC50002020202020202020202020202020202FE -:100DD50002020202020202020202020202020202EE -:100DE50002020202020202020202020202020202DE -:100DF50002020202020303030303030303030303C3 -:100E050003030303030303030303030303030303AD -:100E1500030303030303030303030303030303039D -:100E2500030303030303030303030303030303038D -:100E3500030304040404040404040404040404046F -:100E4500040404040404040404040404040404045D -:100E5500040404040404040404040404040404044D -:100E6500040404040404040404040404040404043D -:100E7500050505050505050505050505050505051D -:100E8500050505050505050505050505050505050D -:100E950005050505050505050505050505050505FD -:100EA50005050505050505050505050505050606EB -:100EB50006060606060606060606060606060606CD -:100EC50006060606060606060606060606060606BD -:100ED50006060606060606060606060606060606AD -:100EE5000606060606060606060606070707080896 -:100EF500080909090A0A0A0B0B0B0C0C0C0D0D0D40 -:100F05000E0E0E0F0F0F10101011111112121213D9 -:100F15001313141414151515161616171717181874 -:100F250018191919191A1A1A1A1B1B1B1B1C1C1C18 -:100F35001C1D1D1D1D1E1E1E1E1F1F1F1F202020C8 -:100F45002121212222222323242425252626272761 -:100F5500282829292A2A2B2B2C2C2D2D2E2E2F2FD4 -:100F65003030313132323333343435353636373744 -:100F7500383839393A3A3B3C3D3E3F40414243449B -:100F85004546474849494A4B4B4C4D4E4F505152A7 -:100F95005354555556565757585A5B5D5E5F6162B7 -:100FA500636465666768696A6B6C6D6F717273748B -:100FB50075767778797A7B7C7E80013701013800F8 -:104AC400E4907236F0A3F0907F97E054FBF0E4900A -:104AD4007233F0907232F090720104F0E490723309 -:104AE400F0907232F090720104F0907F97E04404E9 -:024AF400F022AE -:10326F00907618E0FF640570429075ABE0B40119D9 -:10327F009072377401F0E4908020F0908031F090DC -:10328F008028F0908039F08022E4907237F09075AA -:10329F00ADE090722BF0E02480F0E0908020F09071 -:1032AF008031F0908028F0908039F0EF6406600252 -:1032BF0081999072397404F0907239E0FF24FE9076 -:1032CF007204F0EF75F00AA424ABF582E43475F5BF -:1032DF0083E06401705490723604F0907204E0FF42 -:1032EF0024FD602824FE6024240324FB5004601C6A -:1032FF00818C74202FF582E43480F583E4F07428F8 -:10330F002FF582E43480F583E4F0818C907204E031 -:10331F00FF2430F582E43480F583E4F074382FF520 -:10332F0082E43480F583E4F0818CE4907236F0907F -:10333F007239E075F00AA424ADF582E43475F58393 -:10334F00E0FF7E0090750CEEF0A3EFF07006907228 -:10335F0002743BF090750CE0FEA3E0FF64804E70AA -:10336F0004907202F0EF4E70028135EF64804E7060 -:10337F00028135EFF8E490750DF0E890750CF09040 -:10338F007234E075F00AA424ACF582E43475F58349 -:10339F00E0FF907202F090750DE02FF090750CE049 -:1033AF003400F0E0FEA3E0FFE4FCFD7BD67AA5F944 -:1033BF00F8D3123795400A90750C74A5F0A374D604 -:1033CF00F090750DE0242AF090750CE0345AF0E07F -:1033DF00FEA3E07805CEA2E713CE13D8F8FF9075C1 -:1033EF000CEEF0A3EFF090722CEEF0A3EFF0D3946D -:1033FF00D2EE64809482400A90722C7402F0A3740F -:10340F00D2F0C390722CE0648094805004E4F0A357 -:10341F00F090722CE0FEA3E0243AF582EE3472F5C0 -:10342F0083E0907202F0907204E0FF24FD602D247F -:10343F00FE6029240324FB50046021804090720217 -:10344F00E0FE74202FF582E43480F583EEF07428CB -:10345F002FF582E43480F583EEF08021907202E044 -:10346F00FF907204E0FE2430F582E43480F583EFA0 -:10347F00F074382EF582E43480F583EFF0907239D2 -:0B348F00E004F0E0640A600241C72284 -:10349A00907618E0FFB40523907237E0701D90759E -:1034AA00ADE090722BF0E02480F0E0908020F09064 -:1034BA008031F0908028F0908039F0EF6406600245 -:1034CA00C191907236E06002C191907640E070310D -:1034DA009072037403F0907203E0FF75F00AA4245B -:1034EA00AAF582E43475F583E0FE907229E0FDEED8 -:1034FA006D600EEFC3940A5008907203E004F080E6 -:10350A00D59072397404F0907640E0700890720396 -:10351A00E0907239F0907239E0FD24FE90722AF040 -:10352A00ED75F00AA424ADF582E43475F583E0FF65 -:10353A007E0090750CEEF0A3EFF0700690720274A4 -:10354A0080F090750CE0FEA3E0FF64804E7004905A -:10355A007202F0EF4E7002C11BEF64804E7002C11E -:10356A001BEFF8E490750DF0E890750CF0ED75F02E -:10357A000AA424ACF582E43475F583E0FF90720264 -:10358A00F090750DE02FF090750CE03400F0E0FE3D -:10359A00A3E0FFE4FCFD7BD67AA5F9F8D3123795B0 -:1035AA00400A90750C74A5F0A374D6F090750DE0DE -:1035BA00242AF090750CE0345AF0E0FEA3E0780576 -:1035CA00CEA2E713CE13D8F8FF90750CEEF0A3EF56 -:1035DA00F090722CEEF0A3EFF0D394D2EE648094C4 -:1035EA0082400A90722C7402F0A374D2F0C39072D3 -:1035FA002CE0648094805004E4F0A3F090722CE0F4 -:10360A00FEA3E0243AF582EE3472F583E09072026A -:10361A00F090722AE0FF24FD602D24FE6029240325 -:10362A0024FB500460218040907202E0FE74202F37 -:10363A00F582E43480F583EEF074282FF582E434C1 -:10364A0080F583EEF08021907202E0FF90722AE00A -:10365A00FE2430F582E43480F583EFF074382EF5D9 -:10366A0082E43480F583EFF0907640E07006907241 -:10367A0039740AF0907239E004F0E0C3940A5002F7 -:08368A00A111E4907640F0224A -:044D9700121730229D -:104958009076467480F0E4A3F0A3F0A3F0A3F0A34C -:10496800F0A3F0A3F0A3F0A37480F0E4A3F0A3F005 -:10497800A3F0A3F0A3F0A3F0A37440F0E4A3F0A382 -:104988007440F0E4A3F0A3F0A3F0A3F0A3F0A3F025 -:10499800A37440F0E4A3F0A37440F0E4A3F0A3F000 -:0549A800A3F0A3F022C2 -:100FC600E4FF74462FF582E43476F583E0FE742060 -:100FD6002FF582E43480F583EEF0744E2FF582E42B -:100FE6003476F583E0FE74302FF582E43480F583A1 -:060FF600EEF00FBF08CC75 -:010FFC0022D2 -:104A8D00E4FF74562FF582E43476F583E0FE742846 -:104A9D002FF582E43480F583EEF0745E2FF582E419 -:104AAD003476F583E0FE74382FF582E43480F58397 -:064ABD00EEF00FBF08CC73 -:014AC30022D0 -:10173000C082C083C0E0E8C0E07878E814F870FBAD -:0A174000D0E0F8D0E0D083D0822280 -:030043000249006F -:10490000022FE700023D4700024D4600024BD50052 -:10491000024B6000022FFF00024BED00024B8100B2 -:10492000024C0400023FD500024C1B00024C320036 -:10493000024C4900024C6000024C7700024C8E0091 -:10494000024CA500024CBC00024CD300024CEA0011 -:08495000024D0100024D1800A8 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:0E1EB000000000000000000000000000000024 -:101EBE000000000000000000000000000000000014 -:101ECE000000000000000000000000000000000004 -:101EDE0000000000000000000000000000000000F4 -:101EEE0000000000000000000000000000000000E4 -:101EFE0000000000000000000000000000000000D4 -:101F0E0000000000000000000000000000000000C3 -:101F1E0000000000000000000000000000000000B3 -:101F2E0000000000000000000000000000000000A3 -:021F3E000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:0E23700000000000000000000000000000005F -:10237E00000000000000000000000000000000004F -:10238E00000000000000000000000000000000003F -:10239E00000000000000000000000000000000002F -:1023AE00000000000000000000000000000000001F -:1023BE00000000000000000000000000000000000F -:1023CE0000000000000000000000000000000000FF -:1023DE0000000000000000000000000000000000EF -:1023EE0000000000000000000000000000000000DF -:1023FE0000000000000000000000000000000000CF -:10240E0000000000000000000000000000000000BE -:10241E0000000000000000000000000000000000AE -:10242E00000000000000000000000000000000009E -:10243E00000000000000000000000000000000008E -:10244E00000000000000000000000000000000007E -:10245E00000000000000000000000000000000006E -:10246E00000000000000000000000000000000005E -:10247E00000000000000000000000000000000004E -:10248E00000000000000000000000000000000003E -:10249E00000000000000000000000000000000002E -:1024AE00000000000000000000000000000000001E -:1024BE00000000000000000000000000000000000E -:1024CE0000000000000000000000000000000000FE -:1024DE0000000000000000000000000000000000EE -:1024EE0000000000000000000000000000000000DE -:1024FE0000000000000000000000000000000000CE -:10250E0000000000000000000000000000000000BD -:10251E0000000000000000000000000000000000AD -:10252E00000000000000000000000000000000009D -:10253E00000000000000000000000000000000008D -:10254E00000000000000000000000000000000007D -:10255E00000000000000000000000000000000006D -:10256E00000000000000000000000000000000005D -:10257E00000000000000000000000000000000004D -:10258E00000000000000000000000000000000003D -:10259E00000000000000000000000000000000002D -:1025AE00000000000000000000000000000000001D -:1025BE00000000000000000000000000000000000D -:1025CE0000000000000000000000000000000000FD -:1025DE0000000000000000000000000000000000ED -:1025EE0000000000000000000000000000000000DD -:1025FE0000000000000000000000000000000000CD -:10260E0000000000000000000000000000000000BC -:10261E0000000000000000000000000000000000AC -:10262E00000000000000000000000000000000009C -:10263E00000000000000000000000000000000008C -:10264E00000000000000000000000000000000007C -:10265E00000000000000000000000000000000006C -:10266E00000000000000000000000000000000005C -:10267E00000000000000000000000000000000004C -:10268E00000000000000000000000000000000003C -:10269E00000000000000000000000000000000002C -:1026AE00000000000000000000000000000000001C -:1026BE00000000000000000000000000000000000C -:1026CE0000000000000000000000000000000000FC -:1026DE0000000000000000000000000000000000EC -:0E26EE000000000000000000000000000000DE -:1026FC0000000000000000000000000000000000CE -:10270C0000000000000000000000000000000000BD -:10271C0000000000000000000000000000000000AD -:10272C00000000000000000000000000000000009D -:10273C00000000000000000000000000000000008D -:10274C00000000000000000000000000000000007D -:10275C00000000000000000000000000000000006D -:10276C00000000000000000000000000000000005D -:10277C00000000000000000000000000000000004D -:10278C00000000000000000000000000000000003D -:10279C00000000000000000000000000000000002D -:1027AC00000000000000000000000000000000001D -:1027BC00000000000000000000000000000000000D -:1027CC0000000000000000000000000000000000FD -:1027DC0000000000000000000000000000000000ED -:1027EC0000000000000000000000000000000000DD -:0527FC000000000022B6 -:07174A00907FC57402F0223C -:10175100907EC0E0907645F0907EC1E0907644F0B6 -:10176100907EC2E0907643F0B40003021778907641 -:10177100197403F002178E907644E0B4BB09907699 -:10178100197402F002178E9076197401F090764266 -:03179100E4F0225F -:030000000245F9BD -:0C45F900787FE4F6D8FD7581380246405A -:10369200BB010689828A83E0225002E722BBFE0236 -:0936A200E32289828A83E4932269 -:1036AB00BB010CE58229F582E5833AF583E02250D4 -:1036BB0006E92582F8E622BBFE06E92582F8E2221E -:0D36CB00E58229F582E5833AF583E4932238 -:1036D800C2D5EC30E709B2D5E4C39DFDE49CFCEE0D -:1036E80030E715B2D5E4C39FFFE49EFE12381FC32E -:1036F800E49DFDE49CFC800312381F30D507C3E429 -:063708009FFFE49EFE227B -:10370E00BB0110E58229F582E5833AF583E0F5F0F9 -:10371E00A3E0225009E92582F886F008E622BBFED6 -:10372E000AE92582F8E2F5F008E222E5832AF5831C -:08373E00E993F5F0A3E99322E1 -:10374600E88FF0A4CC8BF0A42CFCE98EF0A42CFC22 -:103756008AF0EDA42CFCEA8EF0A4CDA8F08BF0A4A0 -:103766002DCC3825F0FDE98FF0A42CCD35F0FCEBFF -:103776008EF0A4FEA9F0EB8FF0A4CFC5F02ECD39C4 -:0F378600FEE43CFCEAA42DCE35F0FDE43CFC2231 -:10379500EB9FF5F0EA9E42F0E99D42F0EC6480C8AB -:0637A50064809845F0224B -:1037AB00EB9FF5F0EA9E42F0E99D42F0E89C45F074 -:0137BB0022EB -:0C37BC00ECF0A3EDF0A3EEF0A3EFF02280 -:1037C800A8828583F0D083D0821237DF1237DF12C8 -:1037D80037DF1237DFE473E493A3C583C5F0C583ED -:1037E800C8C582C8F0A3C583C5F0C583C8C582C84B -:0137F80022AE -:1037F900D083D082F8E4937012740193700DA3A35F -:1038090093F8740193F5828883E473740293686072 -:06381900EFA3A3A380DF72 -:1046050002475AE493A3F8E493A34003F68001F22A -:1046150008DFF48029E493A3F85407240CC8C333B6 -:10462500C4540F4420C8834004F456800146F6DF85 -:10463500E4800B0102040810204080900C8FE47E7A -:10464500019360BCA3FF543F30E509541FFEE4937A -:10465500A360010ECF54C025E060A840B8E493A341 -:10466500FAE493A3F8E493A3C8C582C8CAC583CA6C -:10467500F0A3C8C582C8CAC583CADFE9DEE780BE24 -:010FC500002B -:10381F00BC000BBE0029EF8DF084FFADF022E4CC8D -:10382F00F875F008EF2FFFEE33FEEC33FCEE9DEC56 -:10383F00984005FCEE9DFE0FD5F0E9E4CEFD22ED9C -:10384F00F8F5F0EE8420D21CFEADF075F008EF2FE6 -:10385F00FFED33FD4007985006D5F0F222C398FDD7 -:05386F000FD5F0EA2274 -:00000001FF -*/ -/* -VERSION=1.04.062 -DATE=16.10.2002 -*/ -static INTEL_HEX_RECORD g_emi62_loader[] = { - { 3,0x0000,0,{0x02,0x02,0x87}}, - { 3,0x0043,0,{0x02,0x04,0x00}}, - {16,0x0100,0,{0xe4,0xff,0xfe,0xc2,0x20,0xd2,0xe8,0x43,0xd8,0x20,0x90,0x7f,0xab,0x74,0xff,0xf0}}, - {16,0x0110,0,{0x90,0x7f,0xa9,0xf0,0x90,0x7f,0xaa,0xf0,0x53,0x91,0xef,0x90,0x7f,0x95,0x74,0xc0}}, - {16,0x0120,0,{0xf0,0x90,0x7f,0x9e,0xf0,0x90,0x7f,0x98,0xf0,0xe4,0x90,0x7f,0x94,0xf0,0x90,0x7f}}, - {16,0x0130,0,{0x9d,0x74,0xff,0xf0,0x90,0x7f,0x97,0x74,0xa0,0xf0,0x90,0x7f,0x93,0xe0,0x54,0xfc}}, - {16,0x0140,0,{0xf0,0x90,0x7f,0x9c,0x74,0x03,0xf0,0xe4,0x90,0x7f,0x96,0xf0,0x90,0x7f,0xaf,0xe0}}, - {16,0x0150,0,{0x44,0x01,0xf0,0x90,0x7f,0xae,0xe0,0x44,0x0d,0xf0,0xd2,0xaf,0x0f,0xbf,0x00,0x01}}, - {16,0x0160,0,{0x0e,0xbe,0x07,0xf8,0xbf,0x08,0xf5,0x20,0x20,0x42,0x75,0x14,0x00,0x75,0x13,0x00}}, - {16,0x0170,0,{0x75,0x12,0x00,0x75,0x11,0x00,0x7f,0x48,0x7e,0x92,0x7d,0x00,0x7c,0x00,0xab,0x14}}, - {16,0x0180,0,{0xaa,0x13,0xa9,0x12,0xa8,0x11,0xc3,0x12,0x03,0xed,0x50,0xdb,0x20,0x20,0xd8,0x7a}}, - {16,0x0190,0,{0x00,0x79,0x00,0x78,0x00,0xe5,0x14,0x24,0x01,0xf5,0x14,0xea,0x35,0x13,0xf5,0x13}}, - {16,0x01a0,0,{0xe9,0x35,0x12,0xf5,0x12,0xe8,0x35,0x11,0xf5,0x11,0x80,0xca,0x30,0x20,0xfd,0x12}}, - {16,0x01b0,0,{0x01,0xc7,0x50,0x07,0x90,0x7f,0xb4,0xe0,0x44,0x01,0xf0,0x90,0x7f,0xb4,0xe0,0x44}}, - { 6,0x01c0,0,{0x02,0xf0,0xc2,0x20,0x80,0xe6}}, - { 1,0x01c6,0,{0x22}}, - {16,0x01c7,0,{0x90,0x7f,0xe9,0xe0,0x24,0x5b,0x60,0x60,0x24,0x02,0x60,0x03,0x02,0x02,0x85,0x90}}, - {16,0x01d7,0,{0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5,0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90}}, - {16,0x01e7,0,{0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5,0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5}}, - {16,0x01f7,0,{0x16,0x45,0x15,0x70,0x03,0x02,0x02,0x85,0xe4,0x90,0x7f,0xc5,0xf0,0x90,0x7f,0xb4}}, - {16,0x0207,0,{0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c,0x12,0x03,0x13,0xaf,0x0c,0x7e}}, - {16,0x0217,0,{0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5,0x0a,0xc3,0xe5,0x16,0x9f,0xf5}}, - {16,0x0227,0,{0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xc7,0x90,0x7f,0xea,0xe0,0x75,0x0a,0x00,0xf5}}, - {16,0x0237,0,{0x0b,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x0a,0x90,0x7f,0xee,0xe0,0x75,0x15,0x00,0xf5}}, - {16,0x0247,0,{0x16,0xa3,0xe0,0xfe,0xe4,0xee,0x42,0x15,0xe5,0x16,0x45,0x15,0x60,0x30,0xe4,0x90}}, - {16,0x0257,0,{0x7f,0xc5,0xf0,0x90,0x7f,0xb4,0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xc5,0xe0,0xf5,0x0c}}, - {16,0x0267,0,{0x12,0x03,0x2b,0xaf,0x0c,0x7e,0x00,0xef,0x25,0x0b,0xf5,0x0b,0xee,0x35,0x0a,0xf5}}, - {15,0x0277,0,{0x0a,0xc3,0xe5,0x16,0x9f,0xf5,0x16,0xe5,0x15,0x9e,0xf5,0x15,0x80,0xca,0xc3}}, - { 1,0x0286,0,{0x22}}, - {12,0x0287,0,{0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x29,0x02,0x02,0xce}}, - {16,0x0293,0,{0x02,0x01,0x00,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2}}, - {16,0x02a3,0,{0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33}}, - {16,0x02b3,0,{0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf}}, - {16,0x02c3,0,{0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x04,0x6e,0xe4,0x7e}}, - {16,0x02d3,0,{0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93}}, - {16,0x02e3,0,{0xa3,0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3}}, - {16,0x02f3,0,{0xfa,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca}}, - {16,0x0303,0,{0xf0,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe}}, - {16,0x0313,0,{0xe5,0x0c,0xff,0xe5,0x0b,0xf5,0x82,0xe5,0x0a,0xf5,0x83,0x75,0x92,0x7e,0x74,0xc0}}, - { 8,0x0323,0,{0xf8,0xe2,0x08,0xf0,0xa3,0xdf,0xfa,0x22}}, - {16,0x032b,0,{0x90,0x7f,0x96,0x85,0x83,0x92,0xa8,0x82,0x79,0x02,0x90,0x00,0x00,0xe0,0xb4,0x00}}, - {16,0x033b,0,{0x0d,0x74,0x01,0xf0,0x90,0x7f,0x97,0xe0,0x54,0x7f,0xf0,0x44,0x80,0xf0,0xe5,0x0c}}, - {16,0x034b,0,{0xff,0x90,0x7e,0xc0,0xe0,0xf5,0x28,0xe4,0xa2,0x47,0x33,0xf2,0x69,0xf2,0xe4,0xa2}}, - {16,0x035b,0,{0x46,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x45,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x44,0x33}}, - {16,0x036b,0,{0xf2,0x69,0xf2,0xe4,0xa2,0x43,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x42,0x33,0xf2,0x69}}, - {16,0x037b,0,{0xf2,0xe4,0xa2,0x41,0x33,0xf2,0x69,0xf2,0xe4,0xa2,0x40,0x33,0xf2,0x69,0xf2,0xa3}}, - { 3,0x038b,0,{0xdf,0xc2,0x22}}, - {16,0x038e,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x90,0x7f,0xc4,0xe4,0xf0,0x53,0x91,0xef,0x90,0x7f}}, - {11,0x039e,0,{0xab,0x74,0x04,0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x03a9,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xd2,0x20,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x01}}, - { 8,0x03b9,0,{0xf0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x03c1,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x02,0xf0,0xd0}}, - { 6,0x03d1,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x03d7,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x10,0xf0,0xd0}}, - { 6,0x03e7,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x03ed,0,{0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0}}, - { 1,0x03fd,0,{0x22}}, - { 1,0x03fe,0,{0x32}}, - { 1,0x03ff,0,{0x32}}, - {16,0x0400,0,{0x02,0x03,0xa9,0x00,0x02,0x03,0xc1,0x00,0x02,0x03,0x8e,0x00,0x02,0x04,0x58,0x00}}, - {16,0x0410,0,{0x02,0x03,0xd7,0x00,0x02,0x03,0xfe,0x00,0x02,0x03,0xff,0x00,0x02,0x04,0x84,0x00}}, - {16,0x0420,0,{0x02,0x04,0x85,0x00,0x02,0x04,0x86,0x00,0x02,0x04,0x87,0x00,0x02,0x04,0x88,0x00}}, - {16,0x0430,0,{0x02,0x04,0x89,0x00,0x02,0x04,0x8a,0x00,0x02,0x04,0x8b,0x00,0x02,0x04,0x8c,0x00}}, - {16,0x0440,0,{0x02,0x04,0x8d,0x00,0x02,0x04,0x8e,0x00,0x02,0x04,0x8f,0x00,0x02,0x04,0x90,0x00}}, - { 8,0x0450,0,{0x02,0x04,0x91,0x00,0x02,0x04,0x92,0x00}}, - {16,0x0458,0,{0xc0,0xe0,0xc0,0x83,0xc0,0x82,0x53,0x91,0xef,0x90,0x7f,0xab,0x74,0x08,0xf0,0xd0}}, - { 6,0x0468,0,{0x82,0xd0,0x83,0xd0,0xe0,0x32}}, - {16,0x046e,0,{0x02,0x0a,0x00,0x0f,0x01,0x0c,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x41,0x00,0x00}}, - { 1,0x047e,0,{0x00}}, - { 4,0x047f,0,{0x02,0x17,0x00,0x00}}, - { 1,0x0483,0,{0x00}}, - { 1,0x0484,0,{0x32}}, - { 1,0x0485,0,{0x32}}, - { 1,0x0486,0,{0x32}}, - { 1,0x0487,0,{0x32}}, - { 1,0x0488,0,{0x32}}, - { 1,0x0489,0,{0x32}}, - { 1,0x048a,0,{0x32}}, - { 1,0x048b,0,{0x32}}, - { 1,0x048c,0,{0x32}}, - { 1,0x048d,0,{0x32}}, - { 1,0x048e,0,{0x32}}, - { 1,0x048f,0,{0x32}}, - { 1,0x0490,0,{0x32}}, - { 1,0x0491,0,{0x32}}, - { 1,0x0492,0,{0x32}}, - {16,0x1100,0,{0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x40,0x6a,0x08,0x01,0x01,0x00,0x01,0x01,0x02}}, - {16,0x1110,0,{0x00,0x01,0x09,0x02,0x20,0x00,0x01,0x01,0x03,0xa0,0x00,0x09,0x04,0x00,0x00,0x02}}, - {16,0x1120,0,{0xff,0x00,0x00,0x04,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40}}, - {16,0x1130,0,{0x00,0x00,0x04,0x03,0x09,0x04,0x26,0x03,0x41,0x00,0x6e,0x00,0x63,0x00,0x68,0x00}}, - {16,0x1140,0,{0x6f,0x00,0x72,0x00,0x20,0x00,0x43,0x00,0x68,0x00,0x69,0x00,0x70,0x00,0x73,0x00}}, - {16,0x1150,0,{0x2c,0x00,0x20,0x00,0x49,0x00,0x6e,0x00,0x63,0x00,0x2e,0x00,0x28,0x03,0x46,0x00}}, - {16,0x1160,0,{0x69,0x00,0x72,0x00,0x6d,0x00,0x77,0x00,0x61,0x00,0x72,0x00,0x65,0x00,0x20,0x00}}, - {16,0x1170,0,{0x46,0x00,0x72,0x00,0x61,0x00,0x6d,0x00,0x65,0x00,0x57,0x00,0x6f,0x00,0x72,0x00}}, - {16,0x1180,0,{0x6b,0x00,0x73,0x00,0x2a,0x03,0x43,0x00,0x6f,0x00,0x6e,0x00,0x66,0x00,0x69,0x00}}, - {16,0x1190,0,{0x67,0x00,0x75,0x00,0x72,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6f,0x00,0x6e,0x00}}, - {16,0x11a0,0,{0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00,0x22,0x03}}, - {16,0x11b0,0,{0x49,0x00,0x6e,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x66,0x00,0x61,0x00,0x63,0x00}}, - {16,0x11c0,0,{0x65,0x00,0x20,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6e,0x00,0x67,0x00}}, - { 2,0x11d0,0,{0x00,0x00}}, - { 0,0x0000,1,{0}} -}; -/* Source: EMILOAD.HEX -:10046E00020A000F010C11040D00000000410000F3 -:01047E00007D -:1001C700907FE9E0245B606024026003020285906F -:1001D7007FEAE0750A00F50BA3E0FEE4EE420A9021 -:1001E7007FEEE0751500F516A3E0FEE4EE4215E597 -:1001F7001645157003020285E4907FC5F0907FB421 -:10020700E020E3F9907FC5E0F50C120313AF0C7EF5 -:1002170000EF250BF50BEE350AF50AC3E5169FF53A -:1002270016E5159EF51580C7907FEAE0750A00F57B -:100237000BA3E0FEE4EE420A907FEEE0751500F5B1 -:1002470016A3E0FEE4EE4215E51645156030E4908E -:100257007FC5F0907FB4E020E3F9907FC5E0F50C0F -:1002670012032BAF0C7E00EF250BF50BEE350AF5CD -:0F0277000AC3E5169FF516E5159EF51580CAC357 -:010286002255 -:1003A900C0E0C083C082D2205391EF907FAB74012B -:0803B900F0D082D083D0E032C5 -:10038E00C0E0C083C082907FC4E4F05391EF907FB1 -:0B039E00AB7404F0D082D083D0E032BA -:1003C100C0E0C083C0825391EF907FAB7402F0D044 -:0603D10082D083D0E0326F -:1003D700C0E0C083C0825391EF907FAB7410F0D020 -:0603E70082D083D0E03259 -:0103FE0032CC -:10045800C0E0C083C0825391EF907FAB7408F0D0A6 -:0604680082D083D0E032D7 -:0103FF0032CB -:010484003245 -:010485003244 -:010486003243 -:010487003242 -:010488003241 -:010489003240 -:01048A00323F -:01048B00323E -:01048C00323D -:01048D00323C -:01048E00323B -:01048F00323A -:010490003239 -:010491003238 -:010492003237 -:04047F000217000060 -:10010000E4FFFEC220D2E843D820907FAB74FFF01A -:10011000907FA9F0907FAAF05391EF907F9574C0E3 -:10012000F0907F9EF0907F98F0E4907F94F0907F25 -:100130009D74FFF0907F9774A0F0907F93E054FC43 -:10014000F0907F9C7403F0E4907F96F0907FAFE096 -:100150004401F0907FAEE0440DF0D2AF0FBF00013C -:100160000EBE07F8BF08F520204275140075130075 -:100170007512007511007F487E927D007C00AB14E3 -:10018000AA13A912A811C31203ED50DB2020D87ABC -:100190000079007800E5142401F514EA3513F5130D -:1001A000E93512F512E83511F51180CA3020FD123B -:1001B00001C75007907FB4E04401F0907FB4E04461 -:0601C00002F0C22080E6FF -:0101C6002216 -:1011000012011001000000406A0801010001010203 -:10111000000109022000010103A0000904000002EF -:10112000FF0000040705820240000007050202409C -:10113000000004030904260341006E0063006800F8 -:101140006F007200200043006800690070007300A7 -:101150002C00200049006E0063002E00280346008A -:10116000690072006D007700610072006500200068 -:101170004600720061006D00650057006F0072004C -:101180006B0073002A0343006F006E006600690065 -:101190006700750072006100740069006F006E00E6 -:1011A000200053007400720069006E006700220383 -:1011B00049006E0074006500720066006100630003 -:1011C0006500200053007400720069006E00670023 -:0211D00000001D -:10031300E50CFFE50BF582E50AF58375927E74C063 -:08032300F8E208F0A3DFFA2262 -:10032B00907F96858392A8827902900000E0B400BA -:10033B000D7401F0907F97E0547FF04480F0E50C52 -:10034B00FF907EC0E0F528E4A24733F269F2E4A205 -:10035B004633F269F2E4A24533F269F2E4A2443384 -:10036B00F269F2E4A24333F269F2E4A24233F26996 -:10037B00F2E4A24133F269F2E4A24033F269F2A350 -:03038B00DFC222AC -:03004300020400B4 -:100400000203A9000203C10002038E000204580087 -:100410000203D7000203FE000203FF00020484006F -:10042000020485000204860002048700020488009A -:100430000204890002048A0002048B0002048C007A -:1004400002048D0002048E0002048F00020490005A -:08045000020491000204920075 -:0300000002028772 -:0C028700787FE4F6D8FD7581290202CED4 -:1003ED00EB9FF5F0EA9E42F0E99D42F0E89C45F066 -:0103FD0022DD -:10029300020100E493A3F8E493A34003F68001F280 -:1002A30008DFF48029E493A3F85407240CC8C3336C -:1002B300C4540F4420C8834004F456800146F6DF3B -:1002C300E4800B010204081020408090046EE47E59 -:1002D300019360BCA3FF543F30E509541FFEE49330 -:1002E300A360010ECF54C025E060A840B8E493A3F7 -:1002F300FAE493A3F8E493A3C8C582C8CAC583CA22 -:10030300F0A3C8C582C8CAC583CADFE9DEE780BED9 -:010483000078 -:00000001FF -*/ -/* -VERSION=1.0.2.002 -DATE=10.01.2002 -EMI26_62 -*/ diff --git a/firmware/Makefile b/firmware/Makefile index 51ff1f3..2b34074 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -29,6 +29,8 @@ fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ yamaha/ds1e_ctrl.fw fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ emi26/bitstream.fw +fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \ + emi62/spdif.fw emi62/midi.fw fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ kaweth/new_code_fix.bin \ kaweth/trigger_code_fix.bin diff --git a/firmware/WHENCE b/firmware/WHENCE index a2f9390..8e35d7b 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -167,3 +167,26 @@ Original licence information: */ -------------------------------------------------------------------------- + +Driver: emi62 -- EMI 6|2m USB Audio interface + +File: emi62/bitstream.fw +Info: VERSION=1.0.0.191 DATE= 2002oct28 + +File: emi62/loader.fw +Source: EMILOAD.HEX +Info: VERSION=1.0.2.002 DATE=10.01.2002 + +File: emi62/midi.fw +Source: EMI62MFW.HEX +Info: VERSION=1.04.062 DATE=16.10.2002 + +File: emi62/spdif.fw +Source: EMI62SFW.HEX +Info: VERSION=1.04.062 DATE=16.10.2002 + +Converted from Intel HEX files, used in our binary representation of ihex. + +Original licence information: None + +-------------------------------------------------------------------------- diff --git a/firmware/emi62/bitstream.HEX b/firmware/emi62/bitstream.HEX new file mode 100644 index 0000000..3c6ecc3 --- /dev/null +++ b/firmware/emi62/bitstream.HEX @@ -0,0 +1,4372 @@ +:10801000FFFFFFFFAA9955663000800100000007AE +:10802000300160010000000B3001200100803F2D75 +:108030003000C00100000000300080010000000995 +:10804000300020010000000030008001000000012D +:108050003000400050003E040812100000000000F4 +:108060000000000000000000000000000000000010 +:1080700000000000000000000000000000004004BC +:10808000800000000000000000121000000000004E +:1080900000000000000000000000000000000000E0 +:1080A000000000000000000000000000000040840C +:1080B000800000000000000000020000000000003E +:1080C00000000000000000000000000000000000B0 +:1080D0000000000000000000000000000000080098 +:1080E000C0000000000000000002000000000000CE +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:1081100080000000000000000012000000000000CD +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000043B +:108140008000000000000000081300000000000094 +:10815000000000000000000000000000000000001F +:10816000000000000000000000000000000000000F +:10817000900000000000000000120000000000005D +:1081800000000000000000000000000000000000EF +:10819000000000000000000000000000000000845B +:1081A0009000000000000000F710011400250005F9 +:1081B0004001500094001500074001D000940025B4 +:1081C00080016002D800F6002F8002E004D8374416 +:1081D0009000000000000000C005F200CC903920A3 +:1081E0000D9803D200E78037040EF1837E00DF9004 +:1081F00031E48F79037C20DF2233C00CF022300081 +:108200007000000000000000801062008024222026 +:10821000089812E2008B8120940874022E008A01D3 +:1082200022C80892023D808B60228008B0022004A0 +:1082300030000000000000008805C800A0002000F9 +:108240000B1002C000A10024094A32024800B1000C +:1082500062C009A046CC2493492A8048302262019A +:108260007000000000000000C015A812A800220045 +:10827000089002E0008980224408B012A800A940BA +:1082800022C0089082AC009B042AC408B00270048B +:10829000600000000000000000148400E980B26467 +:1082A0004DA003EA20E9C036400EB0034400FB9025 +:1082B000B2880DBC03EC085B0038602CB06340044E +:1082C0007000000000000000E001B426DD9037409F +:1082D0004FE013F280FD003DA00D700375005E00BD +:1082E0003FA40DF9035C10EB0037200F3003B800FA +:1082F00060000000000000004010AC00E980324047 +:108300000CA183E800E90032420EB003AC48E9005A +:108310003A800EA403EC00EB00B2030EB00B100485 +:108320002000000000000000C8052E8089D12040F8 +:1083300008A002C0008180225808F5022F408B005F +:1083400020C00830437C008700224008F002320041 +:108350004000000000000000E00542019A4428A20D +:10836000081802C080A180A0000830028E00AB0077 +:108370002C400A30020C00A30020440A30023800CE +:1083800050000000000000006001320096822BA225 +:10839000885A02F200058029A0087842BE008E8427 +:1083A0002F610AD8024E10A78020280878021800F2 +:1083B000400000000000000048080800F224388057 +:1083C0002C1A03C400E058A0802E30038841E30239 +:1083D0003C400620038C00E30010000E31431202E3 +:1083E0000000000000000000401D9800EE013784EE +:1083F0009FD903F048FD1037C007B0035C00F610AA +:1084000033C00DE103ED20DF103F480FF023D0060D +:108410006000000000000000A805E402CB8030C02E +:108420000CA003E202C9003A400DB6036400EB0061 +:108430003EC00FB003ED00FB013EE00CB002EA00CD +:10844000700000000000000048119400870021C067 +:10845000286002D00085002D8048F0821C00B70003 +:108460002D000B5002DC00B7A02F80287A02D20426 +:108470006000000000000000C100BE00878021E015 +:10848000286802D70084802DE04979065309B58019 +:108490002DE20B7802DE80B7902DB0087902F00053 +:1084A00020000000000000004814CC10830128C800 +:1084B000082002C20681002CC88830620E21B3A0B9 +:1084C0002CC10BB602CC00B3002CE0083002D20461 +:1084D0003000000000000000E815A800CA40B0808D +:1084E0000C2C02F800C6203F900DA0037B01EEE0AB +:1084F0003FB40FEC03E800FA003FA00CA003FA041D +:1085000060000000000000004800E300F8092600B9 +:108510000FC183E010F8403C000F8003E001F80039 +:108520003E000F8103E004F8003E100F8003D200EC +:1085300030000000000000000810E402C9003E40C6 +:108540004F906326843902B2400C91032400F90055 +:108550003E400F90032400F1003A440F9003C20400 +:1085600030000000000000008004450089402E40DB +:1085700008920A2400B931226088948A2420B90024 +:108580002E400B90022400B90022680B9002E000FC +:108590001000000000000000180524A08D842F406A +:1085A0000BD1022400B900224A0810022C40B90065 +:1085B0002E400B90022400B9002A400B9002C60006 +:1085C00040000000000000000804140085802D40D9 +:1085D000085002040CB900A0500814220400B10095 +:1085E0002C400B10020400B128204A0B1302C201D8 +:1085F0000000000000000000B80D6000C0503E8088 +:108600000FC0432000F80030002C80232000F851D8 +:108610003E148F850B2140F8703A080F8483EE03D7 +:108620005000000000000000981DC400F9043E4006 +:108630000F9023D400FD003F500F9403F404FD007D +:108640003F418FD043E50CF9023F4A0F9203E60207 +:1086500070000000000000008805D401FD003D40CE +:108660000CD013F400D500336A1CDC833400D10431 +:108670003E500C9103E6C0DDB0336A2C9C83E600CB +:1086800070000000000000003810E009F8802E00A3 +:10869000888000E800BA0022B0088E02280088A86E +:1086A0002628088A22E20088E42230088C02CE04C0 +:1086B00030000000000000000805C400B1282E4072 +:1086C000081002C400990020424810026401918001 +:1086D0002C48081002C4C08140204A081202C2017E +:1086E00070000000000000001815A494A9022E409C +:1086F0000A90026400B90082600890026600891046 +:108700002462089002E40089022240189002C60404 +:108710006000000000000000A015E600B9043E4023 +:108720000C9013E400D1C012502890034400D900EB +:108730003E40289203E402D90032428C9012E804B1 +:1087400070000000000000002801A620F9003E4152 +:108750002D9003E400F9203E404F9001A400F90061 +:1087600036408F9207E400F100BE400F9003CA002C +:1087700060000000000000002810A000C8003E209B +:108780000C8003E040F80036122C0003E0C0F80033 +:1087900032100D8403A000F8023E080F8000CA04C6 +:1087A000200000000000000028053A908E002DA057 +:1087B00080E802FA00BE40238008E802FA008A003E +:1087C000368008A002E800BA002F800BA0038A00C0 +:1087D00040000000000000002805460283002C80B5 +:1087E000082242C680B1602EF4083822CE00A300D1 +:1087F00020C0083002AC00B1002E400B3002CA008D +:108800005000000000000000A0011E0285012DC2E2 +:10881000A84402D400BD0129401868D2DC008F8032 +:1088200025CC287342DC80B5302DC01B7202E800D5 +:108830004000000000000000A8081E04C6823DE0C1 +:108840000C4812D610F5803CA00C7003DE00E790B7 +:1088500023EA047A039E00F5803DE00F7A03EA02E2 +:108860000000000000000000080DAC009C003EC0AD +:108870000F8003E410F90036010FA003C000EB00E5 +:108880003ED84EB083EC00F9003EC00FB4438206E0 +:108890006000000000000000C005DE00CF8431E071 +:1088A0000EC843D600CD8033E0CDD9033A00FF880F +:1088B00033E00FF913FE24FD803F200CF6831000F7 +:1088C0007000000000000000A8119C00850021C479 +:1088D000284082D000D500238048C9021C00B70080 +:1088E00021C00B7102DE80B5102DC028F0022A04D1 +:1088F000600000000000000010009C00960021C0F5 +:108900000A4102F5408D0021400952029820B7002B +:1089100021C00B7006DC80B5002DC0087002040079 +:1089200020000000000000006014CC10980000C07F +:10893000880482C000910420030900028A00B30A5F +:1089400020C48B3402CC00B9002CC00030021804C3 +:108950003000000000000000F815AC00DB00B0C0E3 +:108960000E9C02C500C110B2C00DB00BA708FF00DD +:10897000B3C00FFA03FC00FD003ED40CF00B2E0434 +:1089800060000000000000008000EC04ED003E40AC +:108990000F8403E540F9403E60CEB4436400FB80A1 +:1089A0003EC20FB013EC00F9023EC04FB003E1002D +:1089B00030000000000000009010FF00CE0033C027 +:1089C0000EC0077404EC0011800CCA03FE60FF00A7 +:1089D0003FC00FF0833C00DD00B3502CF0032004B7 +:1089E000300000000000000081004C048B0B22705E +:1089F00008080367208A88A200288402E700BB00D9 +:108A00003EC00BB0022C00B900226108B0036040E8 +:108A1000100000000000000080052C008B2022E2E6 +:108A20000A8C022600A9802AC008B442ED00BB00CF +:108A30002EC00B30022C00B90020800830026000EC +:108A4000400000000000000008040E018100A0C0EA +:108A5000088102440081002881083202CC00B30062 +:108A600028C00B30020C80B10020C0083012420137 +:108A70000000000000000000800D6C00C20132C048 +:108A80002E80162C08E9003A400C8003EC00F70019 +:108A90002FC00FF00B2C00D90030400CF003600306 +:108AA0005000000000000000A00DF808FF003FC0CB +:108AB0000FC217FC00F70037000F8403FC00FF0013 +:108AC0003FC00FF003ED00FD003F400FF003E8064C +:108AD0007000000000000000C005FC00CF30174807 +:108AE0000C5903B900DF2835240D82A37C80FF00D8 +:108AF0003FC80FF203E4A0EF803FE18CD843300081 +:108B000070000000000000008010ED488934A37060 +:108B100028B02360008BC0224008B4822F40BFD110 +:108B20006FF48EBD02E700BB803AE008980A280483 +:108B300030000000000000008805C4B09100A8507B +:108B400008B202C884930024490B02024C00B3040B +:108B50002CC00B30428400B3002E000AB012220158 +:108B60007000000000000000C011AC0299182A44F7 +:108B700008B882A201BB0028600AA0126C00BB00EA +:108B80006EC00AB002E400BB002A002AB00238041A +:108B900060000000000000004011E408DAC03A6004 +:108BA0000C180AEB04DB0036E00785836C00FB0041 +:108BB0002EC00FB043E400EB003E880E18031004F3 +:108BC0007000000000000000E0419C10E9003760E8 +:108BD00087F0177000CF0137C04C9803BC00FB0032 +:108BE0003FC20FF003E400FF403FE40DD903F00063 +:108BF00060000000000000004010A400F4003040BD +:108C00000FB4039900FB003EC00D04232C08FB8821 +:108C100032C00FB003E600DB103E020FB083D00479 +:108C20002000000000000000C8052C00B950A24838 +:108C30008BB0032000D7802ED80080023C00BF807C +:108C400023E88BF002F4408B400C4203B602F200A2 +:108C50004000000000000000E0054C00B24400C8E5 +:108C60000B30128C00A38024C80B000ACC00B34444 +:108C700004C01B3602C501830C2CA00B3002F80087 +:108C8000500000000000000020011E08B790216481 +:108C90000BF8024A0497812FE40A78029E00B780FD +:108CA00021E08B7882D68687842DA00B7802C000C5 +:108CB000400000000000000048080400F20030C03E +:108CC0000F30038C00E30A3CC00F18038C00F30242 +:108CD00030C01F3001C680C3003CC00F1203DA024F +:108CE0000000000000000000400DBC00FF003F41FC +:108CF0000FF003B808FF083FC00DF0033C20FF0849 +:108D00003BD20FF003F440EF003FC40FD003D00676 +:108D10006000000000000000A805E400FE0032C270 +:108D20000C300B2600FB8036C00DA003EC00FBE0EE +:108D300032D00FB8436444DB043E800FB003E2003E +:108D4000700000000000000048119C00B700A1C0A6 +:108D50008870031000B72021C0087002DC80B33097 +:108D600031C80B7402140087402DC04B7002D20032 +:108D70006000000000000000C0009620B68020E0E7 +:108D800028F8029410B78127E2097802DE00B7A024 +:108D9000A9E80B3802760087802DA00B5802F0005E +:108DA00020000000000000004814CE10B30020C4D2 +:108DB0000820028010B30022C808B002CC11B30210 +:108DC00028C00B3002040093802CD20B1002D20476 +:108DD0003000000000000000E815A800FE4032A0AE +:108DE0000CE4039880FA0037A00DE083E800FE0051 +:108DF0003A800BA0036800D8A03F900FA003FA04AC +:108E000060000000000000004800E008F8083E0094 +:108E10000F80032000F8403E000F8003E000F804BC +:108E200030100F8003E002E8003E000F8003D20004 +:108E300030000000000000000810E400F1003240A3 +:108E40000E9083A400C9803E400E9003A400F90058 +:108E50003E400C9003E400C8003E408F90030204A3 +:108E6000300000000000000080046400B940A062EF +:108E7000081002241089002E400890022400B90036 +:108E80002E52089402C40089402E400B100360103B +:108E9000100000000000000018052400B91822444A +:108EA0000A9002AC0089102EC00A9002A400B9807A +:108EB0002E60089802E60289082E400B90020600F8 +:108EC000400000000000000008040480B120A04819 +:108ED000089002240881232C500810020480B1203D +:108EE0002C48281202E48081202C400B9802420575 +:108EF0000000000000000000B80D6140F850320092 +:108F00000E8503A1E0CA003E000E8503A000F80014 +:108F10002E009CA003E000C8283E000F80032E0115 +:108F20005000000000000000981DF440F5103F4480 +:108F30000FD003F400F1103D408FD403E450F9103A +:108F40003E450F9103D440FC003FC08FD023E60480 +:108F500070000000000000001805E620CDA8334096 +:108F60008DD0032680CD003D500C9A036400F9A0FB +:108F70007A6A0F9A63E680C9803E400F900306002C +:108F800070000000000000003810E10088E03600AA +:108F900008800A2142C8002E290CA4422000B840B3 +:108FA0002E000B8102E10088023A010BC0020E0480 +:108FB00030000000000000000805C40281082440C1 +:108FC000091002040091002C404B14024400B5101B +:108FD00029400B5002F500B5002D400BD0020201D4 +:108FE00070000000000000001811A6018900264052 +:108FF000089402240189002E401A90026C00BF02DE +:109000002F400BD002F402BD802B408BD83A0604CF +:109010006000000000000000A015E400C905364112 +:109020000D1C032400D9003E422F94036400F90074 +:109030003A400F9003C400F9003E700F100328045B +:10904000700000000000000028018408F9243E4060 +:109050000F9103E400F9003E410D1003A400F90054 +:109060003E400F9003E400C9003E640F9003CA0025 +:1090700060000000000000002810A008C880320234 +:109080000F80030000C8083A10CE8403E000FC0003 +:109090003F008FC003F080FC003F180FC043CA049C +:1090A0002000000000000000280528008E00A1809C +:1090B0000BE0022800DEC2239000A002E800BA0004 +:1090C0002E800BA002E800FA002E800BA002CA003E +:1090D000400000000000000028054C00998160C09D +:1090E0000B10020C0090102AFC0B3002CC00B300D5 +:1090F0002CC00B3002CC00B3002CC00B3002CA00D5 +:109100005000000000000000A0011C82954021C01A +:109110000B50021C8090802301097212DC00B60003 +:109120002D000B4002D000B4092D004B4082E80016 +:109130004000000000000000A8083E80DD80B1E093 +:109140000FDA030F80D48039E00B7A03DE00F5805C +:109150003D200F4803D610F6813DE08F6803EA02F8 +:109160000000000000000000081DAC00ED003E0003 +:109170000F910BEC10F8003E000EB003EC00F8006D +:109180003EC04FB003E800E9013E000F9003C20665 +:1091900060000000000000000005FE20BF8133A435 +:1091A0008C19033E00CD803FE00FF8833E00EF8036 +:1091B0003FE00FF913FA10FD803FA40FD803C00061 +:1091C0007000000000000000A8119C00BF2031C208 +:1091D000085A023C0287002D940B700A1C4086102E +:1091E0002D000B4002D400F6002D404B6002EA0433 +:1091F000600000000000000000009C00B701238018 +:109200002850021C0084002DC00B30021C00B50049 +:109210002D000B4006D040B4082D800B4802C00042 +:1092200020000000000000002014CC00B308A020A3 +:1092300008118A0E0080002C900B37020C00900061 +:109240002CC00B3042CC04A3802C500B3002C8043D +:109250003000000000000000A815BC00F98032605A +:109260000CD4033C8088003ED00FF8032800FA009D +:109270003EC00FB007EC01BB803E540FB006EA04BD +:1092800060000000000000008000EE08F9803AC095 +:109290000F9003EC00F8403E580FB043E900EB4458 +:1092A0003E000F8003E00DF8003E800F8003E000D9 +:1092B00030000000000000000110DC00CF0033404F +:1092C0000CD0033C30CC003BC02DF003D802CC00C6 +:1092D0003D000CC003F400EE0237400CE003C04434 +:1092E000300000000000000081046C18838420001E +:1092F0004A10020C00A8482E6008B002E90089401C +:109300002EC008B002E810B10120800A9003A040EE +:10931000100000000000000080052C008B82220855 +:109320000890022C1488042C0808B012E8008A0067 +:109330002EC00AB002E801B9002604089002E0003D +:10934000400000000000000008040C008380A2C060 +:109350000A92022C00A2002C00083402C8008300EC +:109360002C00280002C401BA0022C0022006C2015B +:109370000000000000000000000D6C00CA00B200F8 +:109380000C920B2C04C8043A000CB403E800C8008B +:109390002E000C8033E140E80036000C8003C0034F +:1093A0005000000000000000A01DFC00FF003D0078 +:1093B0000FD10BFC01FC003F000FF003D800FD00B3 +:1093C0003FC00FF003FC80FF003FC00FF007A8066E +:1093D0007000000000000000C015F300CF80356071 +:1093E0004E68435C00E78039C00CC1037E00CF3477 +:1093F00035E14DF2037C00DF383FC80FF803F00081 +:109400007000000000000000C018C800DB8422606B +:1094100008AC0A2C008B8022300891222C90276106 +:1094200022CA88FC22BF008B622FD009B803B00487 +:109430003000000000000000C805E280A9022440BE +:109440008234420400A90028C54832024C208330EF +:1094500020C00831020D00B3202CC40B3002F201F1 +:109460007000000000000000C005AA02B9042260DC +:1094700028B2022600898802C0083112EC008B0055 +:109480002AD008B002AC002B002EC00BB002B004F2 +:109490006000000000000000C005E200E30036208C +:1094A0000EA4636E00E1C01AC10C80036870CB008B +:1094B00036800DB0034C00FB043EC10FB003D00456 +:1094C0007000000000000000E001B804DF003F0071 +:1094D0000FE803FC00FD003F002B98033A007700E3 +:1094E00027E40FF003FC00DF003EC00DF043F8005E +:1094F00060000000000000005000A468CB203A90FB +:109500000F24A3AC00E9503AC00EB4832C08EB0042 +:109510003A900EB08BEC80FB003EC00EB00390047E +:109520002000000000000000C8010A008BA020807D +:109530000DA8022C04894028E808B2022C00AF00D4 +:109540000280087C033D803F002FC008B002360037 +:109550004000000000000000E0054900034028C072 +:109560002B284A2800A10068D20A2042A401A300A7 +:1095700002400A34020D0033002CC00A3000B8004B +:109580005000000000000000B8011A00879021E49C +:109590002BC8123A0085C02B21286802B600A78488 +:1095A00023600838801E00B7802DE00878022E0066 +:1095B000400000000000000048080800C1003854C6 +:1095C0000F26838000E03428C80E2C0B8C00E300AB +:1095D00078450E30038E80F3003CC80E30039202B3 +:1095E0000000000000000000401DB800F5023F44EC +:1095F0000D9003F800BD141FC00FE1235C449F428F +:109600003FC00FF4827D40FF103FC04F7007D0066F +:109610006000000000000000A805E802CB0038C090 +:109620003CA003EC00E9003EC00CB0032004FB2189 +:109630003E804FB403CF00CB003ECC4FB043EA0096 +:109640007000000000000000C8919800870021C051 +:10965000084002DC04B5002D002D70021C1CB7026E +:109660002DC00B7202DC0087402DCA8B7002F20401 +:1096700060000000000000008000BA0087882BE036 +:10968000187822D611A4822FE00878021200B7942D +:109690006D604B7A02DE40B7A02DE00B7806E0004B +:1096A00020000000000000004814C912838228D462 +:1096B000980006EF05B1902CC109B4020C04B30167 +:1096C0006CF00B3002CC00BB002EC00B3002D20479 +:1096D0003000000000000000E815B840CA803BA040 +:1096E0004CE502F880EE003D802CE00F3880FA0057 +:1096F0003FA90FA003E800BA023E808BA003FA0442 +:1097000060000000000000004800E010F8002602A1 +:109710000F8403E024F8003E004F80A3E030F800FF +:1097200036020F8023E00408003E000F8003D200C1 +:1097300030000000000000000810E400D900B6412D +:109740004E990BA40069103E400C9003A410C90070 +:109750003E400D9203E600F9003A400E9003C20429 +:1097600030000000000000008004640081002042FE +:1097700008149A240089006E500090022410D90227 +:109780006E400B9403A700B9002240089003E0004C +:109790001000000000000000180506009900A64116 +:1097A0000A90062C00A9096E5008910284048900D1 +:1097B0000E400B9402E549B9000A400A9002C60027 +:1097C0004000000000000000080406008100224064 +:1097D0000812220481A1002C4008160204009120E6 +:1097E0002C400B12428489B1202048081002C2018B +:1097F0000000000000000000B80D6140D8003600F5 +:109800000A8003A140E8002E000C0023A140C850AC +:109810002E140D8003E000F8503A000E8003EE0392 +:109820005000000000000000881DD400F500BF407B +:109830000FD103F444DD023D502BD123F400F91085 +:109840003F400D9103A448F9123E4E1F9003A6021B +:1098500070000000000000001815F400C5043B4033 +:109860000FD803A780FD00B3680DD843A510C9A089 +:1098700032514F5A433600C9A07A680BD003C60153 +:1098800070000000000000007818CA8888020200FA +:109890008D84222342F8002204288AA2AA9488E90F +:1098A00020A80A800A214080E22E280B8002CE04E4 +:1098B00030000000000000004805C420A104A8C03A +:1098C0000B1C2A2400390420402A1E02E480B11017 +:1098D0002A48091446040081382C5B0B1002D20080 +:1098E00030000000000000001805A412A924224046 +:1098F000299002240039000258081810E601B90026 +:10990000AA44089002240089000E410B9002C6046C +:109910006000000000000000A005E400E1012A64EE +:109920002F94132402716012604D9000C502F9005B +:109930003A400F90232402C9023A400F9002E804F3 +:1099400050000000000000006801A400D9003E6043 +:10995000AF90836488F9203E62039083A400C9001D +:1099600036600F1003C400F9007E400F9003DA0048 +:1099700060000000000000002800A100C882320042 +:109980006F0003A000D84030000E80036004F8018F +:109990003E104F808B2200F80032010E8003CA0473 +:1099A0002000000000000000280138000E00A990EF +:1099B0002FE62088009E8023800AE8032800BA0052 +:1099C00018800DEC023880BA00A28008A0038A003B +:1099D000400000000000000028056C02838020C8C1 +:1099E0000B20020C01921068C03A3C02CC103B02E2 +:1099F0000CC0283C024E00B30028C0283002CA0028 +:109A00005000000000000000A001140087422BC09D +:109A10002970229C00B6002BC20A60861C00B72168 +:109A200029C00074025C00379101E0087402A800AC +:109A30004000000000000000A8081E00C78021E0D0 +:109A40002F78029E00968039E02EF803DE30F7D0A2 +:109A50002DF20078035200F7A23BE00E7807EA02ED +:109A60000000000000000000081DB400FB000CC056 +:109A70000F3003EC10D300B4C02F80036C48FB0000 +:109A80003EC84D9003A400FB201EC00FB003C206C9 +:109A900060000000000000000005FE00CC802B2CC0 +:109AA0002FF8037E006E803BA10DD8433E00FF904F +:109AB00033E00FE933FE00CFC03FE20FD803C00010 +:109AC0007000000000000000A811B44087002104CD +:109AD0000878021C00860021C0289002DC00B71024 +:109AE00021C00F7302CC0087002DC00B5002EA008A +:109AF000600000000000000000009D00A400294854 +:109B00006AF0824C00AE00A1C42974025C40A3102C +:109B100061C20B6006C80087002DC00B5002C00454 +:109B200020000000000000002014E601A3022040F5 +:109B3000283C020C00834220C8081002CD00B3006C +:109B400028F00B3002CC0183042CC0831002C8041F +:109B50003000000000000000A815AA80EB0038C00B +:109B60000A90037C22A24032480DB00B3E00FF0059 +:109B700033F40F9003EC008F023FC00F9003EA0410 +:109B800060000000000000008000E000D9023EC03C +:109B90000EB603EC00FA203EC04F2423AC60FB005D +:109BA000A6C00E9003E400FB003CC10F9003E00050 +:109BB00030000000000000000110F802CF0033E088 +:109BC0002CF013BC002E10B1642EF0023C00FF02FA +:109BD0003FC14DEC63FE00B7003BC00CD803C0444E +:109BE000300000000000000080046C28818122E029 +:109BF0000A38023C04BAC932E02084022C00BB00BF +:109C00002EC00B9C02E781BB0422C00A9902E0002F +:109C10001000000000000000800528408880228895 +:109C200028BC42AC00BA002A80088402AC00BB0009 +:109C30002EC00BB082E890AB0062C008B012E0000A +:109C400040000000000000000804000089002A8095 +:109C500028B2020C00BA0020C00800028C00B30039 +:109C60002CC00B30204C14B30020C0083002C201BD +:109C70000000000000000000000D6800C800B2C035 +:109C80002CB203AC00FA003AC04EA503BC00FF00A2 +:109C90003FC009A003E904EF00BAC00CB001C00145 +:109CA0001000000000000000A019FC00F50035C005 +:109CB000AF3403FC00F40039C00FC2037C00FF0185 +:109CC0003FC00FF003FCA0FF003FC00FF003E8050A +:109CD0006000000000000000C005FC00FF293D20DE +:109CE0008EC1033248DC8023250EF2033CC0DF84A2 +:109CF00033C90FF203FC00CF8033400CF203300075 +:109D000070000000000000008010ECC0BB602E0856 +:109D100008810220048820204808F1822DC0830099 +:109D200022D409F502FC088B01224028B402200449 +:109D300030000000000000008805CC20B3092C8210 +:109D4000081016A010900828480A32020C00BB0028 +:109D50002CC00B3002CC02930120008A3122E20198 +:109D60007000000000000000C015AC04BB002C8097 +:109D7000088602A020A0002A600AB0102C00AB0CBC +:109D80006EC009B002CC009B0022600AB002F00451 +:109D900060000000000000000015EC00BB003E3435 +:109DA00008A00B8300D9023AE02EB00B2C00F880FB +:109DB0003EC04FB003EC00CA40B2720EB00BC004FC +:109DC0007000000000000000E001BC10FB003F003C +:109DD0000DF8137048DD4037C28DF003DC00DDC89C +:109DE00013C00FF003FC00EE407F400D70033800FD +:109DF00060000000000000004010AC00FB0132C019 +:109E00000410032040E8103AC00DB003AC08F8403D +:109E1000B2C02CB033A482DA40BA400FB003D004F1 +:109E20002000000000000000C8053C08BF8022C8D8 +:109E300008B700234488D022D0087082FC00B2E02A +:109E400003F408F50237048BD122604BFD02F200C7 +:109E50004000000000000000E0054C00B310A440EA +:109E60000800024800A0422AD00130028C00B380D2 +:109E70002CC0093102CC00890022E8033802F80026 +:109E8000500000000000000060011E00B780276441 +:109E9000684A0252008C8021E0087802DE00B78018 +:109EA0002DE21939025E30859821E40B7902D80041 +:109EB000400000000000000048080C00F3203400BF +:109EC0000CB8034880E22238C00D30038C00F30048 +:109ED0003EC00D3103EC00CB0038060F3083D202B8 +:109EE0000000000000000000401DBC00FF003B011E +:109EF0000FD0039000F6003FC00FF401FC00FF01FB +:109F000033C20EF513BC00ED003FC40FF003D006C2 +:109F10006000000000000000A805EC00FB003CC051 +:109F20000EA0016401D80032E02CB5032C00F20031 +:109F30007AC00DB4032D80C90232C00CB0032A00D0 +:109F4000700000000000000048119C80B7002DC088 +:109F50000D6002D001840021C00830021D00B7004E +:109F600021C80BF4031EC0860021C0087C035204E4 +:109F70006000000000000000C0009EC0B7902DE00F +:109F8000087806D601B48221E008780A1E00B5C020 +:109F900029E809780236C1978028B00A7A02300091 +:109FA00020000000000000004814CC00BB002CE0A2 +:109FB000093582C0C1A05120E40830028C00BBC426 +:109FC00020C00B300206009318AAB02A300A5204AF +:109FD0003000000000000000E815A800FA013DACC8 +:109FE0004CEC137810F680B3900CA0032800FE0010 +:109FF0003A810DA00F2A80DE043BA00EA0033A0494 +:10A0000060000000000000004800E000F8003E0092 +:10A010000D8002E100D8483E120F80136000F86006 +:10A020003E00078003A002E8042608058003920092 +:10A0300030000000000000000810E400F9043A407D +:10A040000C12032482C90036440F10032400F900C7 +:10A0500036400490030400C90012400C900302042F +:10A06000300000000000000080046400B98122403C +:10A0700008901A2400890022680B99022400B90074 +:10A08000224068900A24008900A24008900A20001B +:10A09000100000000000000018052400B91022E0A4 +:10A0A00008940004048B0826C00B90022404B90C09 +:10A0B00024400A1002240023022A40A810020600AD +:10A0C000400000000000000008040490B12022407D +:10A0D0000812020C108102A0500B12020480B1057C +:10A0E00000480A100204A0A100284A081200020138 +:10A0F0000000000000000000B80D6140F850BA14E4 +:10A100000C85030142C85034000F85032140F8003C +:10A1100036000E80132080E0001A080C00032E0386 +:10A120005000000000000000981DE444F9103F407A +:10A130002FD113F404F5003F400F910BE440FF28AA +:10A14000BE4E0D9683D4A2DD28374A0F9383E606D0 +:10A1500070000000000000009805E410CD003F40B2 +:10A160000FD00335025D0131440FD0032400F90004 +:10A1700032600C9883E640D900366A0C9E83260133 +:10A1800060000000000000003810E00088002E0091 +:10A190000B804202808A0022208880032008B88237 +:10A1A0002221088882E24288A8222008CE020E04DA +:10A1B00030000000000000000805C4028100684073 +:10A1C0000B10028401B900204049100A0400B508B0 +:10A1D0002146085002D4008D20254A0B500242012E +:10A1E00030000000000000001811A40089046E5423 +:10A1F0000B1012A401A900A2401890162400B90067 +:10A20000234018D002F4008D40214A0BD0024604AE +:10A210006000000000000000A015E400C9003A50F2 +:10A220008F960B8402F10130488D90032410F900C1 +:10A23000B2402C9003E640D1C036502F900B6804FA +:10A2400070000000000000002801A400F9003E603A +:10A250000F99C36400D9283E400D9003A400F94033 +:10A260003E400F9003E420F9403E400C90038A00EA +:10A2700060000000000000002810A000F801360077 +:10A280008F8003E002F80432000D80432002CC00EE +:10A290003F000FC0139002DC403F104CC0230A0463 +:10A2A000200000000000000028052800BA002280DD +:10A2B0000BE820F8004EC023A008A00368008A0025 +:10A2C0002E801FA0022A068A002EA00260030A0028 +:10A2D000400000000000000028056C00B30020C012 +:10A2E0000B3D02C003230020E001B0064C008B00B0 +:10A2F0002EC04B30028E0883802CC400348E4A005E +:10A300005000000000000000A0011C80B58061C06A +:10A310000B4002D400840823C20850025EC08401AE +:10A320002D008A0802102484086D000A03122800F8 +:10A330004000000000000000A8081E00F582216017 +:10A340000F7803D604AE8031E00D58237E00C6801E +:10A350002DE00B78038E00D7823DF00C7A036A0261 +:10A360000000000000000000081DAC00F100BAD899 +:10A370000F8003E412F800BE800E1003EC00F90019 +:10A380003E005F8003E008F8043C000F8003C20633 +:10A3900060000000000000004005FE20FF803FF04C +:10A3A0000FF803D200EF84B3610CB903FE00FF8005 +:10A3B00033E00CF8132211CD903F600CE80310003D +:10A3C0007000000000000000A8119C00F5002DC0E6 +:10A3D0000B0002D40484202340085A02DC00B4009D +:10A3E000210028C2021E0486042D8808D0022A04F7 +:10A3F000600000000000000010009C00B5002D402F +:10A400000B7002F420A70421C00A5002DC00BE0039 +:10A4100021C0087012000085002D4088680A0400E1 +:10A4200020000000000000006014CC00A1002EC03D +:10A430001B0806C420800020981A1002CC00B10826 +:10A4400020000800020C0182C02CAC2890221804C5 +:10A450003000000000000000A815BC00B3003E4022 +:10A460000FBA03E502E9043290AEB003FC10FB40E2 +:10A47000B2000C800B2C0282183FA00CD0032E04DB +:10A4800060000000000000009000EC04FB013E4072 +:10A490000FB643E400F8003E80019003EC00F88121 +:10A4A0003ED00DB453E000F9403E400FA003E00061 +:10A4B00030000000000000008010DC02CD8033601E +:10A4C0002CDA03FC00EC0033400FF2037C04FE00A6 +:10A4D00032000CC8033C00CE0031800CD1032404B0 +:10A4E000300000000000000091046C0009002A64A4 +:10A4F000088E02C210A0103E100B9802EC00B900AA +:10A5000002D808BE2220008900225008A002204064 +:10A51000100000000000000080052C000B202240ED +:10A5200008A002E542AB0422180BB0026C00B30095 +:10A5300020040801020004A8402210088002200024 +:10A54000400000000000000008040C0883002840C0 +:10A55000080402C402A8002C000B1202CC00B000B8 +:10A5600020C04030020C008B00A8C008300202114D +:10A570000000000000000000800D6C00C9003340A6 +:10A580000CB003EC02EB0032400FB0036C00FA0099 +:10A5900032000C80032080C80030000C80032003B0 +:10A5A0005000000000000000A019FC00FD003F402A +:10A5B0000FC213F000F4003F004FD403FC00F5007D +:10A5C0003FC08FF003FC40FF0037C02FF003E806C8 +:10A5D0007000000000000000C005F000CC00330057 +:10A5E0000ED00B3300CC0033E00FC0837C00CF20B3 +:10A5F0007B098CF803FE50CF383FE10DC203F00019 +:10A6000070000000000000008010E2009808208028 +:10A61000089802200088D022E00EB4227D199F699C +:10A620002E900830922881DB642EE18816A2E00487 +:10A6300030000000000000008805C80090242001C0 +:10A640000810160082830128C10B02820CE0A310BF +:10A65000280E1B9202848493202EC0083102E2014E +:10A660007000000000000000C015A81098002280B3 +:10A6700008900200608A102AC00A20026C18BB00F1 +:10A680006E602B900246208B002EC208B182F0042F +:10A6900060000000000000004011E402CB00B24066 +:10A6A0002C920327008800BAC00F88032C00EB040B +:10A6B0003AA0CF2CA3ED009B003CF02D8C33D004AE +:10A6C0007000000000000000E001B404EF003FC093 +:10A6D0000D5103F000F18137C00EF4039C10CF0040 +:10A6E0003D800CEC07B808FF021FC40FC803F80038 +:10A6F000600000000000000040109E00C3003840D1 +:10A700000C9203A480FB203AC00D94032C40FB0064 +:10A710003E010F8003E500EB003AC00D840B1004EE +:10A720002000000000000000C8052C088B0222C099 +:10A7300008920321008B4822C00BB7023D403F0125 +:10A7400022740B90022804BF00B2C00B85023200B5 +:10A750004000000000000000E005400180002800EB +:10A76000082C128840B04008C00B18020E00B3003D +:10A7700028201130020C00B3002400090006380024 +:10A78000500000000000000020011200848021A081 +:10A790002868123A00848025E08B58021E40B78258 +:10A7A00021A60B78021A00B78021200B580208005E +:10A7B000400000000000000048080800C8213809D7 +:10A7C0000C28038001F10038C00D85020C00FB004D +:10A7D00038850F10038C00EB103CC80D30031202BB +:10A7E0000000000000000000401D9800FC013F80B8 +:10A7F0000F6803D040FC003BC00DC003FC20FF00ED +:10A800003BC50FF00BB440FF183F000FF103D0061B +:10A810006000000000000000A805E400EB00B0416B +:10A820000CA003E004CA04B0E00EB003EC80CB201F +:10A8300032810CA003EE00DB003E000EB0032A00C4 +:10A84000700000000000000048119404870021C03F +:10A85000486002F000870021C0087002FCA0832835 +:10A86000A380086002DC0087202DC00B7002120458 +:10A870006000000000000000C0009C02A380216076 +:10A88000086802D200878021E0297802DE80879064 +:10A8900021A0194802FE0097802DE00A388230007E +:10A8A00020000000000000004814CC01838020C07C +:10A8B000082042C0308370A0C0893402CC028300DB +:10A8C00060C0290002CE0083002CC80BBC02120419 +:10A8D0003000000000000000E815A900EAE2329014 +:10A8E0002CE003FB02CEC032800FE403E8008A00B4 +:10A8F00033880D64C3FA00DA003D900EE00B3A0491 +:10A9000060000000000000004800C024F8083E126B +:10A910000FC003E048F0003E000E8093C000F80036 +:10A920007E010E80C2E040F8007E008F8403D200DA +:10A9300030000000000000000810E500C1013248AE +:10A940000C9803E640C90032400F90036600C9002E +:10A9500018610C90036420F9053E400C90830204BA +:10A9600030000000000000008004662089002052B2 +:10A970002810C22602A90022400B900A2700A90035 +:10A9800022700890022408B9002E400A900A200084 +:10A990001000000000000000180524028D00234074 +:10A9A00008D1028420890022600B11F224B08100BA +:10A9B0002A460890426408B9002E40089202060018 +:10A9C0004000000000000000080414808520234897 +:10A9D0000852028408810020400B12020480A1204A +:10A9E0002849289002040031202E4008320202013A +:10A9F0000000000000000000B80D6000C850B21454 +:10AA00000CC003A140C800B2000785032140C85014 +:10AA10003A150C85036140F8513E002C85032E0346 +:10AA20005000000000000000981DC448F9103E448A +:10AA30004F91037400F5443E400FD103E440F910F8 +:10AA400037440FD003D400F9103FC00FD103E606FE +:10AA500070000000000000001815F6A0DD8C3378AF +:10AA60000EDA033500CDA033400DF80B3681E980B6 +:10AA700033700C9103E440F9C03EC00FDC03C60004 +:10AA800070000000000000003810E104B840203CD5 +:10AA90000C850202848A402200088F822300B8E8D5 +:10AAA0002220088802E200B8D02E000B8C02CE04CF +:10AAB00030000000000000000805C400910060485C +:10AAC0004B1002048A814060404910028DA0A141D0 +:10AAD0002050091222C480B1202C404B3E02C201FA +:10AAE00070000000000000001815A408B904A04080 +:10AAF00048B0022400890082400890A6A400B9044E +:10AB00002254299502E540B9006E400B9202C6041A +:10AB10006000000000000000A005E4009100324049 +:10AB20000F90092400899032400D9403A400E9029B +:10AB300072600D9403E401F9013E600F9003E80494 +:10AB400070000000000000002801A440F9003E4011 +:10AB50004F9003E710F9803E400F10136400F1009E +:10AB6000BE400E9003E608F9013E640F9003CA0050 +:10AB700060000000000000002800A000F80032087B +:10AB80000C010B2040C84032000E84832000F804E2 +:10AB90003E040F80032100E8003E100F8803CA0422 +:10ABA0002000000000000000280538003E0423803B +:10ABB00008EC123944A600288108E0003808BA00E1 +:10ABC0003F800BA002A8008A022E800BE002CA0080 +:10ABD000400000000000000028054800310024D09B +:10ABE000083E12AE0881A02CC00A38004C00B30009 +:10ABF0006EC00A30020C00A3006CC00B3002CA0009 +:10AC00005000000000000000A0011800B51025C091 +:10AC10002860129010A5082DC20864225818B700A9 +:10AC20002D800B7902BEC087016DC00B6002E80069 +:10AC30004000000000000000A8081E00F584352038 +:10AC40008C18029210C5803D600EC80B5A0877F32D +:10AC50003DA00FF8031EB0E7853DE00F7803EA0240 +:10AC60000000000000000000081DAC00F104BA0163 +:10AC70000FA0436009E10038400EA003A814FB2098 +:10AC80003A800FB41B4C80FB293EC00FB023C20694 +:10AC900060000000000000000005FA00CD803BE0ED +:10ACA0004EF803F202D4813BE08E98073E44EF91C8 +:10ACB0003FE04FFC07EED0CF9833E40FF803C0001D +:10ACC0007000000000000000A801980085102DC44D +:10ACD0000D1102F000852031C40B7B003840D710E5 +:10ACE0002D800B7062FEE1871439C00B6002EA040C +:10ACF00060000000000000000010BC40A5002940DA +:10AD00000B5082DC4084042DC00B10065844A71061 +:10AD10002D800B7102DC00870421C20B5002C01091 +:10AD200020000000000000002014CC0AA1012C40EB +:10AD3000891802C100A10820C00B34064000930509 +:10AD40002C140B3C86CE10830128F10B1402C8048E +:10AD50003000000000000000A815A000ED003AC07F +:10AD600007BC63ED0081403EC00E88036400EF0025 +:10AD70007E500FF002FD42CF0072C01FB403EA0400 +:10AD800060000000000000008000E80099003EE044 +:10AD90004FB483ED9009403EC00FA183A801EB01A1 +:10ADA0003E000FB113EC0CFB003AC05F2023E00023 +:10ADB00030000000000000000110F800FD043FB06A +:10ADC0000D60033E00CD0033F00FF201F000FF03F1 +:10ADD0003F030FF001FC00FB0233C20FF0E300441D +:10ADE000300000000000000081046A00B9022EA0BB +:10ADF0004AAC020E80F9C036E10BA0022A08BB0063 +:10AE00002E200EB002EC00EB0022C08BB0022040DE +:10AE1000100000000000000080012300A90028C0ED +:10AE200009B2226C4089892AC00B14062600AB02A5 +:10AE30006EE009B0066C00B30222C00BB002200025 +:10AE4000400000000000000008040800B1002CC011 +:10AE50000A30022C00BB0064C00B320A0800330029 +:10AE60006C80023046CC18A30020C00B28020211CF +:10AE7000000000000000000000056800E90038C183 +:10AE80000DB10B2C0089003AC00B90036000FF024B +:10AE90003E800FF003FC80FF0032C08F800B000368 +:10AEA0005000000000000000A011D800FD043FC0C9 +:10AEB0002FF203FC11EF003FC00FF4437000FF00BE +:10AEC0003F0046F003FD00EF003FC00FC003E8065F +:10AED0007000000000000000C005FE00FF803DE0A3 +:10AEE0000CF913DE007F80B3E00FFC03BE40CF807F +:10AEF00033F00FF8037C04CC8033A00CF00B30014E +:10AF000070000000000000008010E02088002E206B +:10AF1000088212E080A88122020B80022080A88093 +:10AF200022080B80022C028804AA2008B002200408 +:10AF300020000000000000008805EC00A3082C8021 +:10AF4000083202C420A30028400B92028400A90109 +:10AF500028C81B1282CC40A80024E00A30422201FB +:10AF60003000000000000000C011A880A8022E40A0 +:10AF7000688010C800B8402A900BA0002800AA08DA +:10AF80002A020320028C00A8882E200AB002300476 +:10AF900060000000000000004015E804FA003C409A +:10AFA0000CA003E800EB003AC00F2053A800E340D8 +:10AFB0002A400FA0036C00A88034201EB0031004A8 +:10AFC0007000000000000000E001B4009D913F808F +:10AFD0000FDA23F400CC20370007D0137400BC0034 +:10AFE000B7800BD0437C00DC043B006DF003F8001D +:10AFF00060000000000000004010A800FA803A0045 +:10B000002CA00B2002CB623E500E88032000D910EA +:10B010003E708C8033EC80D8403A020DB0031004AF +:10B020002000000000000000C8010C00398022C090 +:10B030000C9D822C10D0402EA008B8034E028A40EE +:10B040000EA00DB0033D00D09036100BF002B20000 +:10B050004000000000000000E0054C00B10060C0AE +:10B060008A18028C0880400CA0023002CE00824870 +:10B070002C802B30068C008102209009B002380011 +:10B08000500000000000000020011200B690A33024 +:10B0900008E822B21487802D600849121261959049 +:10B0A0002D610A48161E80958025200B78028800A5 +:10B0B000400000000000000048080C00F100288C4F +:10B0C0008E1003848080002C020A9A02E400D000D3 +:10B0D0003E800B91038E80C20838800DB0031202AF +:10B0E0000000000000000000401DB000F6003F44DA +:10B0F0000F21137800FF003DC00FE0037800EF043C +:10B100003F408DE803DC04F6003F000FF083D006DB +:10B110006000000000000000A805E800E880324060 +:10B120000F880B280078023E800E28032800CA8072 +:10B1300032000FA003EC00C98032800FB0032A0058 +:10B14000700000000000000048118C008F00A180FA +:10B150000B70421400B7002D410B50421400A500A3 +:10B16000A1C00B5002FC80A50021000BF2021204CA +:10B170006000000000000000C000BA00A480293078 +:10B180004B48065208B4802D200B48423200848080 +:10B1900021200B4812DE40868129A00B780A30005E +:10B1A00020000000000000004814CC00830520E0CF +:10B1B0000B34026C10B3002CC00B364A0D0DA300EB +:10B1C00020C00B3482CC02A20028000B30021204F3 +:10B1D0003000000000000000E815A920EA4030A07F +:10B1E00007A0436940FA003C800FA0030840CA0052 +:10B1F00030A00FA403E800CE003B980FA0033A0450 +:10B2000060000000000000004800D200FC083F0081 +:10B210000BC203B000FC003F000FC003F000FC00B5 +:10B220003F040FC003E000F800B6020F8003D20015 +:10B2300030000000000000000810E400D9003E6863 +:10B240004C9101E408C9003E402C9203E402C9A0DD +:10B250003E700E9003C642C9003E400F1003020428 +:10B2600030000000000000008004640089860E6049 +:10B27000089802E40889102E60089002E400890C06 +:10B280002E60089002E68889002E400B9002A000F4 +:10B290001000000000000000180524009D102F4041 +:10B2A00028D006F402AD002F6008D002F4008D0013 +:10B2B0002F400AD002E40089002E600B90020600A5 +:10B2C00040000000000000000804340085002D400C +:10B2D000085802D400A5022D40085000D400850073 +:10B2E0002D40085402C48081002C600B140282019E +:10B2F0000000000000000000B80D6140D8523E0080 +:10B300000C0503E140E8043E140C8503E140C8004D +:10B310003E140EC003E000C0023E004F80232E0307 +:10B320005000000000000000981DF400F9013E40AC +:10B330004F9013E400D9001E400F9003C410F10099 +:10B340001E400F9003E4E0FD283F400F9403E60603 +:10B3500070000000000000001805A400FD003F4040 +:10B360004D5002E4009504334028D003F400FD0062 +:10B3700033400F91033400CD4033400F98810600D5 +:10B3800070000000000000003810E010B8002E002F +:10B390000B8002E010B8002200088002E000B80034 +:10B3A00022000B8803C280888022000B8C020E04CE +:10B3B00030000000000000000804C400B1002CC0F0 +:10B3C0000B1002C400BB002240081002C401B900E7 +:10B3D00020401B90020422890020600B128202018F +:10B3E00070000000000000001815A444B9002EC031 +:10B3F0004B9002E410B9020240089142E400B98087 +:10B4000022400B9202C400994022404B9012060445 +:10B410006000000000000000A015E600B9013E58E1 +:10B420000D9003E600D10032600C9802E640F9006E +:10B43000B2400F18032400C98032500F9023280413 +:10B4400070000000000000002801A400F9003E4246 +:10B450000B9003E708F900BE480F9003E400F900E1 +:10B460003E400F9803A400E9A0BE400F100B4A0015 +:10B4700060000000000000002810A000D8013E007D +:10B480000F808B2000F8203E010F8103E000F808B8 +:10B490003A000C8003E000D84032000F80130A0409 +:10B4A0002000000000000000280528008A802F915D +:10B4B0000BEE022801BE0020800BA002EA80B648F5 +:10B4C00022800DA002FA028641A3A60BA0030A0067 +:10B4D000400000000000000028054C0093802CC0B4 +:10B4E0000B30020C10B30028C00B3802CC00B300A4 +:10B4F00028C0093002C601836020700B300A4A0060 +:10B500005000000000000000A0012E8885082D805A +:10B510004BF8061C80B70021C00B5002D400B600C7 +:10B520002960097002D0A08D0021400B3202280052 +:10B530004000000000000000A8081E00D5803DE08B +:10B540008F78031E84B7823D600F5903DE00F780B9 +:10B550002960157803DE00C78031600F7C036A0222 +:10B560000000000000000000081DAC40E9003E8023 +:10B570000FA003ED30FB0036C10F9603E400B300CB +:10B5800034400FB783EC4021003E400FB003C206A9 +:10B5900060000000000000000005FE00FF8133E0B5 +:10B5A0000FF903DE20CF813FE00778033E00FF80E4 +:10B5B0003FE004F813FE02DE8033600FF803000062 +:10B5C0007000000000000000A8119C00B70021C41A +:10B5D0000B5A02DC4886502DC00B31029460B4181F +:10B5E0002D40487002E800A51021400B71022A048A +:10B5F000600000000000000000009C00BD0021422F +:10B600000B7002FC02850025400B50029C00B70025 +:10B610002F40287102DC00A60021C00B7002000040 +:10B62000200000000000000020146D80B120A05018 +:10B630000BB206CE00A0342EF00B18028520B34AC0 +:10B640002C54883802CC10A10020B00B3002080422 +:10B650003000000000000000A815BE80F308105460 +:10B660000B8813FF00C0803E640FB4830700F9C04D +:10B670003EF00CFC13F400EA0032700FF00B2A04C9 +:10B6800060000000000000008000EC00F9003E10A7 +:10B69000079103ECC058003E440F9203E400F90008 +:10B6A0003EC08FB303E000BB00BE440FB003E00018 +:10B6B00030000000000000000110FC02CD0433E067 +:10B6C0000CC0033C08FE0033602CD002B480CF00D5 +:10B6D0003F5207F013FC00CE1033420CB003C044BD +:10B6E000300000000000000081046C0089002AB0D6 +:10B6F0000888022C00BA0036440890002600DBC0FF +:10B700002E400BB002EC0083C028400AB002E0409B +:10B71000100000000000000080052C008B002208B3 +:10B720001AA2022C10B92022400830022C04AA547C +:10B730002EC00BB012CC008B08224008B002E000F3 +:10B74000400000000000000008040C0083042A00F0 +:10B750000A08820C00B8006440083002A400B0005F +:10B760002CC08B3010C8028B002A400A3002C20164 +:10B770000000000000000000000D6C00C900320055 +:10B780001A82033C00F90032400CD103AC00EB00FC +:10B790003E400FF003ED00C30032C08CB003C00385 +:10B7A0005000000000000000A019FC00F5003F0060 +:10B7B0000D804BFC007C003F400FD20B7400DF007B +:10B7C0001D408FF003FCA0FF003F800FF003E80650 +:10B7D0007000000000000000C005FC00DF843BE0BA +:10B7E0000FF80B3E00EC8033E10C30033C80CF4877 +:10B7F00037C00E4003E0C0C791B3040CF003300023 +:10B8000070000000000000008010EF048B802241D7 +:10B810000BB0822E008880A2E00AA292AD808742FF +:10B8200023D88AAD02E0C08B00204C48A40220043B +:10B8300030000000000000008805CC58BB002880C4 +:10B840000BB2422400A8002AC00A10020460A32000 +:10B8500024D20800428C839B0120490833C2220174 +:10B860007000000000000000C015AC00AB8822A0F2 +:10B870000BB802260CA8002AC00A9202A400AB064C +:10B8800022C00AB002E8009B00024008A042300437 +:10B8900060000000000000004015EC00D3803AE09A +:10B8A0000F18010600E83038660EB8032A40EB0096 +:10B8B00036C10E9603E280DA0832802CBB031004F6 +:10B8C0007000000000000000E0019C00DF003FC0AD +:10B8D0000FD003F400DC8037600FE803FA00DF01CB +:10B8E0003FC00FC043E64CEFA03F440FA003F80059 +:10B8F00060000000000000004010AC40DB0036801B +:10B900000C98032600F8003EC00E18038402E301E1 +:10B9100038C10EB403AC80CA183AD02C30031004DE +:10B920002000000000000000C8053F40B9882E80BC +:10B9300008BC02A300B0000EC008B00620008F04AF +:10B9400023C108B9122F008380364008AD023200AF +:10B950004000000000000000E0054C00B2002CC0D8 +:10B96000093202840033002CB20A36128C08930587 +:10B9700020C00B1802ED0091806A00081002380008 +:10B98000500000000000000020011E00B7802DE0E4 +:10B990000978029740B4802FA008E8020E409782F1 +:10B9A00021E09868821A189D902DA118580208006D +:10B9B000400000000000000048080CC0F3003EC03A +:10B9C0000DB0438440F0003C820E38128C44F330BA +:10B9D000BAC11E10478E22D11038180C30831202C3 +:10B9E0000000000000000000401DBC40FF003FC000 +:10B9F0000EE003F440FC003DC40FD001F441EF1809 +:10BA00003FC41FF003F848EF1433800FC103D00682 +:10BA10006000000000000000A805FC40FB003EC0E4 +:10BA20000F98032400CB003E400FB003A800DB2892 +:10BA30003EC41F9023EC00CA0032E00C9003EA00E1 +:10BA4000700000000000000048119C80B7002DC06D +:10BA50004B50521400D4012D800B6002D800A72057 +:10BA60002DC50B4016DC00840023C0084002D20420 +:10BA70006000000000000000C0009E80B7802DE044 +:10BA80000B780A960094802D601B7806D200A78060 +:10BA90002DE00B7822DE00878221E0085802F000BA +:10BAA00020000000000000004814CC00B3E42CC0CB +:10BAB0001B2102810090002CC80B3902CE00A3008C +:10BAC0002CC00B3002CD008B2020F008B202D20433 +:10BAD0003000000000000000E815A800FEA03F8232 +:10BAE0000FE8039830D6003FA00FE003BAC0FA0079 +:10BAF0003E800FEC33F802CE00B3B82CEC83FA048E +:10BB000060000000000000004800E018F8403E001F +:10BB10000F80026084F8052E048F8041E0007802D7 +:10BB20003E000F8183E020F800BE020F8003D200A8 +:10BB300030000000000000000810E618F9203E4028 +:10BB40000F9C03E440C90032610C9013C408C90182 +:10BB50003E410F18032400C9A032400F984302044D +:10BB6000300000000000000080046500B1C02240E9 +:10BB70000B9C02E71089002844089422E4108900F5 +:10BB80002E400B9F222660898022400B910A2000C4 +:10BB9000100000000000000018052480B9002EC02D +:10BBA0004BB402E42089202240089402EC00890072 +:10BBB0002E410B90020400894022400B90020600A7 +:10BBC000400000000000000008040400B104204010 +:10BBD0008B1002E40581002840281212C4828120C3 +:10BBE0002C480B120A0482810020480B1202020129 +:10BBF0000000000000000000B80D68A0FA023E142A +:10BC00000F8503E000C80032000C8503C140C85313 +:10BC10003E140F80030148C050B2140F85032E0359 +:10BC20005000000000000000981DE400FD00BF402F +:10BC30000F5013D402FD002FC00FD103F440F910B0 +:10BC40003E440FD103F440FF00BF440FD103E6068A +:10BC500070000000000000001805E6A0FD013E4451 +:10BC60000FD103D400C50033410FDB032720D9E0F7 +:10BC7000B2700DDA83F640CF1032782DDA03060069 +:10BC800070000000000000003810E100B8002E280D +:10BC90000B8842E010D80022000B8C0A230088C0D9 +:10BCA0002228088402C28080A0223048AA820E0482 +:10BCB00030000000000000000805C400B1002C4066 +:10BCC0008B1202C400990228408B160284819130A5 +:10BCD0002058091002C5008100644D083402020199 +:10BCE00070000000000000001815AC0CB9042E48CC +:10BCF0000B9406E4009940AA400B9222A40089000C +:10BD00006040089402E4008980A65008920206046C +:10BD10006000000000000000A015E400F9983E4813 +:10BD20000F9803E520D9003A640F9483A4C0D90288 +:10BD300072404D9042E482C94036400C900B28047A +:10BD400070000000000000002801AC28F9883E4087 +:10BD50000F9913E700F9C036600F90036600F100F9 +:10BD60007E400F9907E460F90038400F9803CA003D +:10BD700060000000000000002810A000F810320051 +:10BD80000F820B2100E80036040C8603E100D80086 +:10BD900032000F80036100C80032000F00030A0464 +:10BDA000200000000000000028052820BE0022809E +:10BDB00028EC021904820003800DE482E8008A0165 +:10BDC000AA808BED823B808E9036800BE0034A0088 +:10BDD000400000000000000028054200B38020C0A1 +:10BDE0006B341640C08310247288B002EC008300CC +:10BDF00024C00B04026F099B0024C00B30020A0010 +:10BE00005000000000000000A0011400B78023E4EF +:10BE100028788274148F0061E0095012DC048722B4 +:10BE200025C81B780214009440A5C00B602268004E +:10BE30004000000000000000A8081220B780B1E018 +:10BE40008FF8031202E78035E00C6806CFC2CFB04E +:10BE500025F40F58035A02D58075FA4FF8032A02C9 +:10BE60000000000000000000081DA590F3003DC088 +:10BE70004FB013A804FB003CC00F8043EC80EB6084 +:10BE80003AC90F3003EC00E9003EC80FA003C20618 +:10BE900060000000000000000005F600EE803FE0BA +:10BEA0000D8903D240E58139E03CF907FE00CF88D7 +:10BEB0003FE00FE803F208CE8033E00CF803000007 +:10BEC0007000000000000000A8119444C6002FC0BC +:10BED000085802D0C485242190085412DC8207003F +:10BEE0002DC00B7006D4008E4821C00A60022A04BF +:10BEF000600000000000000000009C00A7402DC072 +:10BF0000084202D000AD0029C0087022DC2887005A +:10BF10002DC00B400298009700A0C40870020000DA +:10BF200020000000000000002014CC0893002CE04A +:10BF3000083C22C10081002080881502CE30830099 +:10BF40002CC00B3C02CC0493C020F44A0C820804A1 +:10BF50003000000000000000A815A000E3C01FE0B2 +:10BF60006C1083E004EB003A524CB403FE02CF00A5 +:10BF70003FC00F8443E102D8C233C00C840B2A04B3 +:10BF800060000000000000008000E900EB103EC4EB +:10BF90000E9403E400FB183EC20FB603EC00FB0155 +:10BFA0003EC00F3503C428EA423EC00F8103E000C3 +:10BFB00030000000000000000110FC40FF0033C012 +:10BFC0000CC0A33028CDA033C00CE8030C00EF0553 +:10BFD0003DC00CCA833C00CD083FC20CA003C04446 +:10BFE000300000000000000081046700BB8020C01A +:10BFF00008AA020800A10134D108A4122C008B0069 +:10C000006EC088B2022C0889802EC00AA803A04006 +:10C01000100000000000000080052C00BA80A2C0C3 +:10C0200008A80AA0008B00A2C0481102AC048B0033 +:10C030002EC00080122A088B142CC0088802E00051 +:10C04000400000000000000008040C00B20022C004 +:10C0500008B2128000AB0124C00800020C04830067 +:10C060002CC00830020700820024C00808028201A8 +:10C070000000000000000000000D6C00FB0032C05A +:10C080000CA203A000C90032C02494033C02CF00DC +:10C090002FC004800B0902CB013FC02CA003C003BA +:10C0A0005000000000000000A019DC00FD023FC0AD +:10C0B0004FE4137000FD003FC00FC283FC00FF007F +:10C0C0003FC00FF003FC00FF003FC00FC003A806F5 +:10C0D0007000000000000000C005FC20EF303F04AD +:10C0E0006C88033A42E4913F0D0D48033CC0FF02C7 +:10C0F00033440CF403FC82DF3033600DF103300075 +:10C100007000000000000000A010ED008B702E18E1 +:10C1100088224A2C82EA262E0C0BB8423D80BF9022 +:10C120002A5428B402CD00DB402A4A483002A00439 +:10C1300030000000000000008805CCB0A3006C10A7 +:10C140000900822082A0202C884B80000C40B30183 +:10C1500020480B36028CE0836424402832022201FE +:10C160007000000000000000E011AC008B002E0009 +:10C17000098080A600BA112E880BB0002C00BB02EB +:10C18000024009B002EC008B002CC808B882B00451 +:10C1900060000000000000004015EC00EB003E9243 +:10C1A0000D80030A20E9003E504580012C04F30075 +:10C1B000906009B003EC008B0226508DBC03100484 +:10C1C0007000000000000000C001BC00FF023F80C2 +:10C1D0000EF9027C22AF003F6003C00BFC10FF0091 +:10C1E0003F4A4EF003FC00F7002B600F7003F8008D +:10C1F00060000000000000004010AC00FB00B00038 +:10C200000F820BA900C90032D20FA083AC00CB1063 +:10C210003E400CB003EC00DB0032502C95031004C0 +:10C220002000000000000000C8053C04BF0222807E +:10C230000B98002900CB4022C00B24023C088F50F1 +:10C240002E500DF002FD428F5822E048B502320018 +:10C250004000000000000000E0056C00B300244036 +:10C260004B940049009080043009000E4C008380FC +:10C270002CC00930226E42838020480838023800E2 +:10C28000500000000000000020011E00B780652063 +:10C290000B78827A088CC025A34B78025E048784D1 +:10C2A0002D61897802DE048780E96208780208003F +:10C2B000400000000000000048080C00FB0034486B +:10C2C0000F3B034800934834500D00036C00C3102B +:10C2D0001CC2053003CC40CB0032400C20031202BC +:10C2E0000000000000000000401DBC20FF010340D2 +:10C2F0000FF0231C00FF003B800FB0233C02FF50D7 +:10C300003DC40FF103EC00EF00B7C00FE103D0060E +:10C3100060000000000000008805EC00FB023EE029 +:10C320000C80034802C88132000F9042ECA0FB1041 +:10C330003EE00CB103EC40FB1032401FF0032A003A +:10C34000700000000000000048119C00B7242D8000 +:10C35000087042D8108C0221400B5002DD00E7200B +:10C360002F40087002DC05B70021C00BF002120458 +:10C370006000000000000000C0009E00B7902F4049 +:10C380000A68027A00978021E00B7802DE00B7800D +:10C390002DE0087806DE00B7A021600B784230005F +:10C3A00020000000000000004814CC00B3002CC0A6 +:10C3B0000A3402C800834A20F80B3102CC00A300E3 +:10C3C0002CC0083002CC00B30020B20B2042120473 +:10C3D0003000000000000000E815A800BA003F8807 +:10C3E0002EE0435988DE0033B00F6C03E800FA00FA +:10C3F0003E802CA003E804FA0023B80FE08B3A0437 +:10C4000060000000000000004800E004F8013E0069 +:10C41000098221E000F840BE140F8481E000E800AA +:10C420003E001F8003E000F800BE000F8803D2002A +:10C4300030000000000000000810E400E10032407D +:10C440000C9043E420D9003C440890032400F901F7 +:10C450003E480F10432500C900B2400C900302046F +:10C46000300000000000000080046400B900A0401B +:10C47000089802E608A9602E490894022400B90031 +:10C480002E700B900226028900A0400A900A20001C +:10C49000100000000000000018052400B900224030 +:10C4A000089804E60099802E400AB1022400B900E1 +:10C4B0000E400B900A0400810122C0081002060001 +:10C4C000400000000000000008040480B120224861 +:10C4D000081806C400A1002C482A30020480B122AA +:10C4E0002C480B12020580816022500A14020201BE +:10C4F0000000000000000000B80D6140F850321448 +:10C500000C8503E140D8503E140E800B2140FA0008 +:10C510003E940F85032000C00032000C80032E03E0 +:10C520005000000000000000981DE441F9103D4556 +:10C530000FD003F400FF003F450DD003E440F91095 +:10C540003F440F9103E442F9103F400FD403E60645 +:10C5500070000000000000001805E400F9003E40F3 +:10C560000CD003F4088D023F400FD003E400CD004F +:10C5700033400C90032400F90032404C982306000D +:10C5800070000000000000003810E000E8002E00FD +:10C59000488002E800D0002E800B8012E002880064 +:10C5A000A2000A80122200B881222808CF020E04BD +:10C5B00030000000000000000805C400B1002C405D +:10C5C000281002C40081002C400B1002C40091000E +:10C5D000264009100254A0B52CA542085082020141 +:10C5E00070000000000000001815A400A9002E50E3 +:10C5F000589002E4809B002E458B9202E400990043 +:10C6000026440B90026408B500254A08510206042E +:10C610006000000000000000A015E400F9003E5496 +:10C620000C9043C400C9903E700F9803E400D900F9 +:10C6300034604D900A6400F90036402C9E032804B3 +:10C6400070000000000000002801A400F9003C4038 +:10C650000F9C03E630F9003E620F9003E400E9000E +:10C660003A404E9003A400790C3A400F901BCA0048 +:10C6700060000000000000002810A000F8003E004C +:10C680000C8113E108C84832003C8003C000F01060 +:10C690003E060C8003F008CC0033040CC0030A04EF +:10C6A000200000000000000028052800BA002E80AD +:10C6B00008EC42FA208E0023A008E842E800BE8081 +:10C6C0002F8008A002E800DA00228048E0020A0079 +:10C6D000400000000000000028054C00B3002CC002 +:10C6E000093482C900838020F0083082CC00B380F6 +:10C6F0002CF008B002C1208000A0320800020A001D +:10C700005000000000000000A0011CC0B7012FC8AD +:10C71000895002D80287C421E2487082DC00B70049 +:10C720002C40087202CE00970823C008700228002F +:10C730004000000000000000A8081E00F7E13DE8EE +:10C740002D6803F200C780B0E0086803DF80F68040 +:10C750003DE08C7E03DA00CC8031200CC80B2A022D +:10C760000000000000000000081DAC08FB003CC0F9 +:10C770000E8003E008F9003E400FB002EC00FA0022 +:10C780003E402FB003E400FB003CC02FB003C206C4 +:10C7900060000000000000000005FE00FF927FEA3C +:10C7A0000CF803FE00CCA03F200DF9033E00CF8023 +:10C7B00033600FF803F600EF8433E02CC803000069 +:10C7C0007000000000000000A8119C00B7002FC8F6 +:10C7D000085402D800D6042D010869021C00850007 +:10C7E00021430B70039AC08C00A30208F1022A04B3 +:10C7F000600000000000000000009C00B7012DCC8C +:10C80000087002D40094282DC208C2025C00860081 +:10C8100021800B7102DC00A71021C00848024000F3 +:10C8200020000000000000002014CC08B3002CF011 +:10C83000080502C02090802E000800824C02800073 +:10C84000A0610B3002A0008000A03088B10A48042B +:10C850003000000000000000A815BC00FF002DC83B +:10C860000C3D03E400DB023EF02C904B7C00C10049 +:10C8700032204FF013E000E80132008CAC036A0470 +:10C8800060000000000000008000EC00FB043EC2DD +:10C890004FB003E004FA403EC24E9823AC10F800BB +:10C8A0003E5007B013AC00FB003EC20F9203A00045 +:10C8B00030000000000000000110DC00CF003FC08D +:10C8C0000CC8233682CF803F800CE003EC00F920B7 +:10C8D00033C00EF003F810DC0033004CE8210044B4 +:10C8E000300000000000000081046C00AB002EC08E +:10C8F0004A8D4221008B422ED208B003EC00B8884A +:10C9000034620DB002E4008B0022C008900A20407F +:10C91000100000000000000080052C008B002EC0DD +:10C9200008A0020D0089102E08289202EC04BB001A +:10C9300022A008B0026402B30220C008A202A00034 +:10C94000400000000000000008040C00A3002EC0FE +:10C950000A90220C1080002C00180282CC00B0003B +:10C960002640093002C820800020000810068201FD +:10C970000000000000000000000D6C00CB002EC085 +:10C980000CA102240088003C000C8003EC00FB009A +:10C9900032800EB003CC80DB0032C00CA0038003D9 +:10C9A0005000000000000000A01DFC00FF003FC080 +:10C9B0004FC213D410FC003F000F0003BC00FC006A +:10C9C0003F400FF023E012FC01BF000FD0036802CC +:10C9D0007000000000000000C005FC00C78033C0EC +:10C9E0008BB403B0C0CF2E1F0C4FC3033080FF01A8 +:10C9F0003F080FF0007C00FF2133E40CE00330001F +:10CA000070000000000000008010EE008B8223F018 +:10CA10000BB5120D8888C00E980B86022100BBC092 +:10CA20002EE44BF7832F44BF9022C848A6822004EF +:10CA300030000000000000008805CC098A0020506A +:10CA40004BB20A80CC83010C8C0B230A0460B31414 +:10CA500024404B3002CC10B30020C8E9110662011B +:10CA60007000000000000000C015AC018A80A244E4 +:10CA70000BB002A10488402EA00B20022820BB404E +:10CA80002E400BB0022C08BB0022C009B00270047B +:10CA900060000000000000004015EC00C38332E09D +:10CAA0008F0003A002CBC43E28078B032100F9C0EE +:10CAB0003E100FB003EC007B0032C00DA003500409 +:10CAC0007000000000000000E0019C02FF003FE059 +:10CAD0000FF4435E80FC943F000FC02BF250FD2109 +:10CAE0007E848FF0036C0CFF003FC00E6203B80021 +:10CAF00060000000000000004010AC00EB0032407D +:10CB00002C80036900CB30B2004FB343E500CB402B +:10CB100072182CB003EC28C3213AC10F94031004FF +:10CB20002000000000000000C8053C008B202250BF +:10CB300008B002280088C02A008BB402E800DB009D +:10CB4000623008F002FC008F8022C00B9547320053 +:10CB50004000000000000000E0054C00B10020C2D1 +:10CB60004830024980834260120B3002C8008202C2 +:10CB70002C3009B002CF0183502AC00B2002B8002C +:10CB8000500000000000000020011E009D80A0E079 +:10CB90000879225E60879029A00B7802C6009281F6 +:10CBA00005E0097802DE40878021E00B29020800B9 +:10CBB000400000000000000048080C40F20030C0B7 +:10CBC000083A034404C31430C00F2203CC80C200CF +:10CBD000A4D20D3013CC20C30038C44F044312023A +:10CBE0000000000000000000401D9C00EE003FE03F +:10CBF0000F7003B402F4103FC08FA003FC007E004E +:10CC00003BC00EF083EC00F7003FC00FC003D0061E +:10CC10006000000000000000A805FC00F9003EC014 +:10CC20000FA003AA12CB0132800FB0132814F98091 +:10CC30003A4003B403EC42CB183EC00FB0032A00C5 +:10CC4000700000000000000048119D00B5002DC4D8 +:10CC50000B704B7C00840021800B70029410B2009A +:10CC600029C00B7282DC0087202DC10E70021204D5 +:10CC70006000000000000000C0009E00B7802DE0B2 +:10CC80000B68029E00838021E05B38021E00B4C066 +:10CC900025E0097832CE0097802DE00B5C4E300005 +:10CCA00020000000000000004814CC00B3442CC059 +:10CCB0000B3C02CC40930820E00B30028C10B3C038 +:10CCC00028D81B3002CC0893016CC00AB882120429 +:10CCD0003000000000000000E815A800F6103E80BB +:10CCE0004BED83B800CEE4B3A30FE0033800FE00A1 +:10CCF0003B800DA002E800DA003E800FE8023A0413 +:10CD000060000000000000004800E010F8403E0015 +:10CD10000F80136000E0003E00430803E000F808C5 +:10CD20003A000F8003E000E8403E000E8023D2006E +:10CD300030000000000000000810C400D9C0BE4050 +:10CD40000F9003E600F9003240019A032400F90035 +:10CD50003E400F9003C44009100E400F9A03020496 +:10CD60003000000000000000800464048904A26018 +:10CD70008B9D80A600B98022404898022400B9000B +:10CD80002E408B9002E49489602E400B940B20007F +:10CD90001000000000000000180524009908AE48AB +:10CDA0004B1002E581B91020441B94022410B900F5 +:10CDB0006E600B9002E40089002E400B9402060086 +:10CDC0004000000000000000080404808900A06802 +:10CDD0000B12028489B12020481A12120480B12259 +:10CDE0000C480B1202C481A1202C400B120202013C +:10CDF0000000000000000000B80D6000D800BE0078 +:10CE00000F050BE140F80032140F85032140F800B4 +:10CE10002E800F8513E002C8003E140F05012E037B +:10CE20005000000000000000981DE440FD00BF44D9 +:10CE30000FD103F4407D10BF4445F12BF440FD10A9 +:10CE40003F440F9103E440D9103E400FD103A606A2 +:10CE500070000000000000001805F600FD001F62D1 +:10CE60000FD8823600BDA03B680CDC8326C8D9A051 +:10CE700033600D99835620D5A82E440CD8838604A0 +:10CE800070000000000000003810E148B8002E00DB +:10CE90000B0A822220B85022BA088A2222808800F7 +:10CEA0002201080C02200088002E28888802CE0467 +:10CEB00030000000000000000805C400B1002C4054 +:10CEC0001B100A8440B10028580A3202050099401C +:10CED0002065091042C40091002C400A3082C20132 +:10CEE00070000000000000001811A400B9002E40DE +:10CEF0001B9002A580B910224808104204100900B6 +:10CF00002240089002E4009B002C400A9422C604B0 +:10CF10006000000000000000A015E400F9203E4081 +:10CF20000F9013A710F960BA502E9C0A2584D1F0F7 +:10CF3000B2600D9003E400D9003E400E9003A800BB +:10CF400070000000000000002801A40CF9903E6A67 +:10CF50008F90236600F1083C400F9C43E440F98029 +:10CF60003A440F90032404E9023E402D9113CA0075 +:10CF700060000000000000002810A000E8203E0132 +:10CF80000C0003A120E85032102C8C032100E80093 +:10CF900032020F00132088C80832000F8C03CA0029 +:10CFA0002000000000000000280528208EE32F90BC +:10CFB0000AE0063B00EE04239008E00228088A02FB +:10CFC00075908BA04158908E802A810BE0038A10C7 +:10CFD000400000000000000028054E00A3006C6027 +:10CFE00008381A8E40A08020CC0930020C05A3041A +:10CFF00028C40B30020D0183C020C00B3002CA00D0 +:10D000005000000000000000A0011E0887002D62F3 +:10D010000B70921C08A00061C00960061C80A7006C +:10D0200021C00B72025801878829C00B6012A8002A +:10D030004000000000000000A8081E00E6803D60DF +:10D040000C78429600E480A3600D78033F00E380F3 +:10D0500021E00F7B031608C78031E24F7843EA02D4 +:10D060000000000000000000081D8C01F8003C409A +:10D070000EB002EC00F8013E404E3033ED20DB01F3 +:10D08000BEC00FB403EC00FB003ED80FA003C206E5 +:10D0900060000000000000000005FE00C78423605F +:10D0A0000C780BBE00FD803FE00FEB033E00CF800D +:10D0B0003B250CF8837E40CD8033E20BF903000062 +:10D0C0007000000000000000A8119C0287001548B5 +:10D0D0000870021420B600359A49C8039C84A70042 +:10D0E00039D00A70021A08A40021C00961422A043A +:10D0F000600000000000000000009C00870021404C +:10D100000871029400B5002D400BF1225C02070863 +:10D110002C50087002500087002DC40B50420000B4 +:10D1200020000000000000002014CC0083022440F6 +:10D13000183D0A0100B05824200930028F4083E0D6 +:10D140002CC10A30420800B3016CC009081608045B +:10D150003000000000000000A8158C008B00324059 +:10D160000C2503A848F8813E800F80637C00CB80AB +:10D170003AC00CF0036C00CA02BFC00F988B2A049F +:10D1800060000000000000008000EC00F9003E504C +:10D190002FA40BC800F0403ED00FA033EC20FB04BE +:10D1A0007AE00FB003ED08E90332C00D9003E00010 +:10D1B00030000000000000000110EC40EE003EC016 +:10D1C0000CDA037004CC02B1A00EF023EC00FF00D7 +:10D1D0003720CDB073EC88FB803FC00F3003004494 +:10D1E000300000000000000081046E0088802CE107 +:10D1F00008940AA902884022D008B942EC04BB0076 +:10D200002CD40DB002ED20BBD02EC00BB002A0403C +:10D21000100000000000000080052400AB802EF00C +:10D2200029A0826D0088082204089042EC00BB000F +:10D230002A8108B002E409BA042EC14B988220006A +:10D2400040000000000000000804040083002CC01F +:10D250000A210284108200E000180A12CC00B300F8 +:10D260000CC0093002CC90B0002CC00B100282011F +:10D270000000000000000000000D6400EB003E0014 +:10D280002CB40364088800B2000CB243FC00FB001D +:10D2900056000CF001E400FB003FC00F800B0003C0 +:10D2A0005000000000000000A01DF400FF003F40FF +:10D2B0002DF061F000F40027010DB111FC00FF0218 +:10D2C00007C00FF003EC40FF003FC00FC00368062B +:10D2D0007000000000000000C005F600EF903D4C1B +:10D2E0002CC013F408FD20374C8E82837484DCC27A +:10D2F0003FD80DF203ECC0FF813F000CF803F000B3 +:10D3000070000000000000008010E6008B242E5CFE +:10D31000088D02FF48B9902F540B84823E40A080B4 +:10D320002EC40AFC42ED80B9802E600A9812E004F7 +:10D3300030000000000000008805E401A300284838 +:10D340000A0042C400B1002C490B0A4204A29121F8 +:10D350002CC90831028CC1A3002C40081802A2017C +:10D360007000000000000000C015A0208B822E4439 +:10D37000588002E400BB102E400BA1120C01891052 +:10D380002EC00AB002EC01B8802EE20AA102F0041D +:10D3900060000000000000004015EB40EB403E60E4 +:10D3A0000E8733E400B9A136C00EA80B2600DAC000 +:10D3B0003EC08DB003EC00FB853EE108B80390054C +:10D3C0002000000000000000E001B800FF022F6014 +:10D3D00003E883FC10FD801F401FD013BE40EE0405 +:10D3E0003FC00FF043FC08FD003CC00FD011F80017 +:10D3F00060000000000000004010A400DB00B2400C +:10D400000E94032400D900BAC00C2003E490FB0062 +:10D410003AC00CB003EC01FA003ED02C9803900403 +:10D420002000000000000000C80503008B00224817 +:10D430000884222C00B90022C008A002ED008BA0B5 +:10D4400021C008F002FC00B9802EC008A002320002 +:10D450004000000000000000E0054520930022F895 +:10D460000B300A8440B2002040081002C4008080C3 +:10D4700028C02839024C00B1002CC0083002B80086 +:10D480005000000000000000200136009F80216055 +:10D490000938029E00B2C02060484812D6C686D025 +:10D4A00021E0087800DE80B7822DE008F80208004D +:10D4B000400000000000000048080C20D31030C8D5 +:10D4C0000F30038400F1003040241903E4C0E04031 +:10D4D0003AC00C3203CE80B1283CC00C301392020B +:10D4E0000000000000000000401D9C00E6007FC01E +:10D4F0000EF0237440FF103F404FD003FCD2CE0407 +:10D500003FC00FF403FC00FE003FC00F7103D012B8 +:10D510006000000000000000A805EE00CB0016C06F +:10D520000D80032720CB003EC20AB053E428C181FE +:10D5300032C10EB9032C00F18035E00CB8032A0487 +:10D54000700000000000000048119C0287102D4070 +:10D550000870035C00A7002D40287002D4048704E3 +:10D56000A1D00B72021D00F70021C00D5002120461 +:10D570006000000000000000C0009E00858025E0E3 +:10D58000097802370387802FE0087812C6108D8053 +:10D5900025E80B38021E80BC8425E0085802700084 +:10D5A00020000000000000004814CD8083882CC0BB +:10D5B000083C024E01A3D22EC408B102CC008380E5 +:10D5C00024C10B30020C00B340A0D209301252002B +:10D5D0003000000000000000E815BA00CAC0368024 +:10D5E0000D67132800CE003EA00CED03E800CEE04E +:10D5F00036801EA00B2804FE00B7B20CE00B7A00A8 +:10D6000060000000000000004800E040F8102E100C +:10D610000F8003E001D80A3E000F8003C002F80823 +:10D620003A000F8003E010E820BE000F8013920044 +:10D6300020000000000000000810E500FB003E4054 +:10D640000C91032600618032400C90032400C90035 +:10D650001E400C9C03E401F9003E400F9003C20001 +:10D66000300000000000000080046700B9002C407A +:10D67000009C02A600790022402890022400890024 +:10D680002C44089802E400B9802E400B9002E0017F +:10D69000000000000000000018012400BB0026501C +:10D6A00028908224849920224049900224008900F5 +:10D6B0002E40089002E400B9602E400B9002C60490 +:10D6C000400000000000000008040600B1002E48E1 +:10D6D0000812028480B120A04809120A0480810047 +:10D6E0002C48281242C48831002C400B1802C20179 +:10D6F0000000000000000000B80D6000F850361473 +:10D700000C80032000E80032140C85032140C8502F +:10D710003E140C8003E14038003E008F8003EE038E +:10D720005000000000000000981DD400FB043D44A0 +:10D730000F5123D448ED103D444ED123F442FD0057 +:10D740003E448F9103E458FD003F500F5003E6061E +:10D7500070000000000000001805F400F9003D40D2 +:10D760000CD003F400DD023E400C9003E440C910ED +:10D77000374007D0072400E5002F6A0F700306002A +:10D7800070000000000000003810E000B8003A000F +:10D79000808002E00088002E000A8053A2802CA026 +:10D7A00022000B800A2000B8002E100980030E040E +:10D7B00030000000000000000805C400B1006C400B +:10D7C0002A1002840181802E40091002F4008D0489 +:10D7D00020400B10028400B1002C400B9802420143 +:10D7E00070000000000000001811A420B9002A40B9 +:10D7F00088B402E601A9202E480A9000A440AD405A +:10D8000022400B9012A404B9012E410B9002060491 +:10D810006000000000000000A015E400F9C03E60B8 +:10D820000C9413A602D9421C600C9E01C604C100D0 +:10D83000B2401F9002A400E9083E684F980B6804AC +:10D8400070000000000000002801A640F920387098 +:10D850000F9103E400D9803E400F9C13A400F9000F +:10D860003E400F10036410F90A3E500D9A03CA009F +:10D8700060000000000000002810A100D8043E0055 +:10D880000C8113C002D8203E002D8403E000CC0898 +:10D890003A000F8043E000F841320007818B0A0410 +:10D8A000200000000000000028053A608A002FA830 +:10D8B0000AE022E8027E482E8008A042E8048E009A +:10D8C00023A80BA882E800EE00A2804B60020A00A9 +:10D8D000400000000000000028054C0093006CC0D0 +:10D8E000083002CC0013812CC0083002CE408240A8 +:10D8F00028E00B3802CC00B31024C08B38020A0099 +:10D900005000000000000000A0011E0087202FC072 +:10D910000A7002DC0AB6002CC8887206D80086009D +:10D9200021C00B7002DC84AF80A5C00BD0022800A0 +:10D930004000000000000000A8081E00D7803DA0A5 +:10D940001C7813D602D7803DEC087E23FE00CE80E3 +:10D9500039600F7803DF00F68075E00F78032A0244 +:10D960000000000000000000081D8C00FB103E803D +:10D970001FA021CC00FA003EC00EB003E802FA005E +:10D980003E400FB013EC00EA013AC00F9003C2060C +:10D9900060000000000000000005FC00FF803F6008 +:10D9A0000899077E00DD803FE20CF803F602DF8075 +:10D9B000B3E00CF8033E41CC8033E40FF803C00021 +:10D9C0007000000000000000A8119C40B7002DC0AE +:10D9D0000D5A22DC8075002DC0087102F0208700EE +:10D9E00021C00A70021C00D42821C00B7202EA0474 +:10D9F000600000000000000000009C40B7002D0007 +:10DA0000087222F40087002DC2087002D4008780BB +:10DA100025400930025C01AD0029D04B7002C000E6 +:10DA200020000000000000002014CC00BBC82CA087 +:10DA3000092002CE00A3002CE0A83D42C2008B804A +:10DA400024400B300A6C08A340A8E00B3402C80441 +:10DA50003000000000000000A815AD00FF483C2881 +:10DA60000CA9236C808B003FC00CFC03EC00D88019 +:10DA700034400D30037C02A34038680F2403EA04CD +:10DA800060000000000000008000ED88FB003E50B8 +:10DA90000FA103EC043AC03EC00FB083E802F810B7 +:10DAA0003A410E9003AC009B08B6400F8103E000A2 +:10DAB00030000000000000000110FC00FF00B32057 +:10DAC0000C50131C09CD8333C08370003C00DC1064 +:10DAD00032600EF1432C00CE043B700CF083004406 +:10DAE000300000000000000081046780BB0162215B +:10DAF0008A89202C0080E022C00BB003D8108C044F +:10DB00002240059002AC00D88036400A90022040A6 +:10DB1000100000000000000080052600BB00220667 +:10DB20000880022E00882022C009B002A4009900BB +:10DB300062C408B0062C008880224108A0022000A0 +:10DB4000400000000000000008040C00B30020406A +:10DB50000A00820C00800020C00B3022A00081004F +:10DB6000A0C00930028C00900024400A2802020163 +:10DB70000000000000000000000D6000FB0220001B +:10DB80002C92032C02880031C00BB502A400D104F2 +:10DB900032400E90032C40C9003A408CA003000391 +:10DBA0005000000000000000A01DF400FF002F0046 +:10DBB0000FC003DC00FC003FC10FF043F000FD008C +:10DBC0003F404FD003FC00F5003F400FE003E80664 +:10DBD0007000000000000000C005D880CC00B70431 +:10DBE0004EE1033C20DF10318006F0037F00FFC0D0 +:10DBF0003BC00EF2035E00EF1033D02CF203300076 +:10DC00007000000000000000C010E90088C6205C21 +:10DC100008A45765008F522AF009FC020400BB00DB +:10DC20002DD90974836428834422848806823004B1 +:10DC30003000000000000000C805C9008010200866 +:10DC400008311204B2A30020841B34020C80B320DC +:10DC50002CC70936028C809340ACC80831283201A9 +:10DC60007000000000000000C015A9008800A2504C +:10DC700008350224008B042EC109B0022494BB0095 +:10DC80002EC00BB002CC608B002E800880003004C8 +:10DC900060000000000000000015E702CB18B28011 +:10DCA0002CAC0A2E08EB0032124EB0032B80FB0086 +:10DCB0003AC00AB003AB08EB042E480CB88300044A +:10DCC0007000000000000000E001B680FF8039CA4B +:10DCD0000DE803D640E7043B664E7003B800FF0131 +:10DCE0003FC06CF0037006E70031040FC143F80039 +:10DCF000600000000000000040108500CB40329022 +:10DD00002FB00B6480FB08BA100DB0A72D00FB04E8 +:10DD10003EC08EB0036D00DB0132408C33039004B3 +:10DD20002000000000000000C005240083E0A2D015 +:10DD300040B0022504BF80A05008F80220008B02EA +:10DD40002FD008F00224008F80360108844236006C +:10DD50004000000000000000E8054400834820C4A3 +:10DD60000900024600B301A8901930128C00A304E8 +:10DD70002EE20AB0020C00834928C0093C02380098 +:10DD80005000000000000000F0013604838021E113 +:10DD90000838121E28B39821A0193882960087836C +:10DDA0002DE2087822368C87802DE00979023E002A +:10DDB000400000000000000048080400C33030C8E4 +:10DDC0004D000B4C80F31238C00D3A028C80F300EA +:10DDD0003CC00E300B0E00C30C3AC00D30031202D3 +:10DDE0000000000000000000401DB406FF103FC00E +:10DDF0000FB013BC00FF107FC00EF1A37C00FF1218 +:10DE00003FC20FF523BC41EF183780AEC003500668 +:10DE10006000000000000000A805E400DB003EDA1E +:10DE20000C800366108B0032808CB6034A004B8056 +:10DE300032C80CB4030A10DB003EC10CB0432A0008 +:10DE40007000000000000000C811B40087042CC05E +:10DE50000D70031C08874820810D72825C00D7007A +:10DE600021CC28F0021C1087202C0008400A320424 +:10DE7000600000000000000080009600B7812DE0E7 +:10DE80000848020E04878021E00878023E0187805E +:10DE900021E01879023A0197A02D6008380220008D +:10DEA00020000000000000004814C600A3C62CC0DB +:10DEB0000930020C01830020E00930024E0093007B +:10DEC00020C04930220F6483026CD428300212042F +:10DED0003000000000000000E811AB80FAE03C8850 +:10DEE0000CE0022802CA00B3A90CA0033B10CA0030 +:10DEF000A2800CA00B3800DA003FB00CE6033A0415 +:10DF000060000000000000004800C02098083E00AB +:10DF10000F800BE100F8013C104F0003A040F80017 +:10DF20003E100E8003E000F8003C022F0493D20064 +:10DF300030000000000000000810E400C1C13240C1 +:10DF40000C98032640F90032400C98032424F90071 +:10DF50003C600C1003A400F98232400C90030204D0 +:10DF6000300000000000000080046400890022509E +:10DF70000D98022580B90022520D9C022400B900A0 +:10DF80002E600890422400B940364008900A2000D4 +:10DF90001000000000000000180524008D00234040 +:10DFA0000812022400A110A26008928A2400B9017C +:10DFB0002E46089002A400B150224028908206000C +:10DFC0004000000000000000080404848520A1D85F +:10DFD0000910020480B32020402912060400B10178 +:10DFE0002C482812020400B1202448081202020121 +:10DFF0000000000000000000B80D61428A00B3007C +:10E000000C05032140E050B2002C80022140F0506A +:10E010003C140C8513A150F85032140C85232E03A8 +:10E020005000000000000000981DF440F9103E442C +:10E030000FD40BF444F9103F504F1103F400F900D2 +:10E040003E440F9153F414F9103F440FD103E602FC +:10E0500070000000000000009805E6A0DD88B366AF +:10E060000CDC833688BDA0376A0CDA0B2502C94068 +:10E070003F784F98B3E504CDA072780CD88B261466 +:10E0800070000000000000003810E30088422231D8 +:10E09000080A0222A0B8F922100D84126A80888032 +:10E0A0002E200B0802E280A8A8A23848A8020E0081 +:10E0B00030000000000000004805C4A28100204894 +:10E0C0000812424500B100244009140224008120B6 +:10E0D0002C580B1082C4049140646C0830821205E5 +:10E0E00070000000000000001815A4008900224103 +:10E0F00008908A6480B9002250099006640899004B +:10E100002E400B9006C401B90226618890020604D5 +:10E110006000000000000000A015E400C9002240DB +:10E120002C94236400B90036400990130500C900FF +:10E130003E404F9013E5C0D90026402C94032800A0 +:10E1400070000000000000006801A402E9083C40E3 +:10E150000F900BA400F1003E410F9043A488E90406 +:10E160003E400F9003E600E1003A409F9263DA00E0 +:10E17000600000000000000028108010E001320064 +:10E180008F80032000D80830018C0003E102C8040E +:10E190003E000C800B2100C80078000F86030A00A7 +:10E1A0002000000000000000280528008E402B827F +:10E1B0000BA0023A008E80238208E20228108A0017 +:10E1C0002F9828A01228008E202E804BE4020A00EF +:10E1D000400000000000000028054C02A240208002 +:10E1E0000BB0024E4093C0A0200836028C00930072 +:10E1F0002CE20830064C12930828C00BB0020A002B +:10E200005000000000000000A0011C0882402940CE +:10E210000B70025E08840823400870061C8087008B +:10E220002D200879125C0094002DC00B304228008C +:10E230004000000000000000A8083E00E48031A17A +:10E240000F58137600D08031C00C3803BE80D781C0 +:10E250003F208C79037F01D68039E84F68032A007C +:10E260000000000000000000081DBE00FA003E0093 +:10E270008F960BA400EA003CC00F9003AC20FB403B +:10E280002E000FB203ADA0EA003EC00FA01BC204D7 +:10E2900060000000000000004005FE08DE8133A49D +:10E2A0000EFC133E00FC8013200C68033E20FFC8C8 +:10E2B0003F601DF8037E00C78033E20CD8031000D6 +:10E2C0007000000000000000A8119C00864131C4CD +:10E2D0000879429C00BC1021408535035C00B700E2 +:10E2E0002DC00872022C00A70137C00851422A0035 +:10E2F000600000000000000010008C4082002481BB +:10E3000008D8021420B50020400960021C40B70064 +:10E310002C400B3022DC00970021C408400244004E +:10E3200020000000000000006014EC009206209025 +:10E330003815028600B80060500930024E01BB005B +:10E340002E400B3002CE20B30024F048020A5804BD +:10E350003000000000000000A815BC00CA00A69410 +:10E360002C90032E00FB05B2850D90033F90FF001B +:10E370007E801FF043FC219A0033C83CB2036A043C +:10E3800060000000000000009000EC02EA403D80C8 +:10E390000F1093ED00FB403E908F3003EC80FB00AC +:10E3A0003E911CB0032C10E8003EC81F9003A5103E +:10E3B00030000000000000008010FC02E40073A0A8 +:10E3C0000CFC037C02FF1013C41CC0033C00FF00C4 +:10E3D00037E00DF003FC00ED8031C00C3263200407 +:10E3E000300000000000000084006C008AC022B1F0 +:10E3F0008AB8434A10DB2020F00A94036C00BB0764 +:10E4000022B808B002EC11E8C0B2C02A921A20006B +:10E41000100000000000000080012C00AA8022985B +:10E420000890022F03BB012A8308B24E2C04AB02D2 +:10E4300022C428B022EC09B35062C008B002200008 +:10E44000400000000000000008040C018300608010 +:10E4500008120A440093002A804A30020C00B300DC +:10E4600060C0083002CC00B30260C0080046020160 +:10E470000000000000000000800D6C00E802228017 +:10E480002CF2432C00FB00BAC008A5023C00EF00B0 +:10E4900036C04DF013FD51FB0032C00CB00320011B +:10E4A0005000000000000000A01DFC007E043F8022 +:10E4B0000F3143F002FF0037C00FF003FC08FF00EC +:10E4C0003FC00FF003FC00EF003BC00FC003E81695 +:10E4D0007000000000000000C005F240FC803F24F6 +:10E4E0000DD853D604DF323FCC4CC043FC00DF6074 +:10E4F00037C00FC4037CD0DF2033D80DF843F000C1 +:10E5000070000000000000008018E880B0012E08B4 +:10E51000889002EC208B702FCC08B382FDE0BF40C6 +:10E5200022D80B9302FDC0AF1028F008BC12F004F3 +:10E5300030000000000000008805C400B0002E017B +:10E540000A1282EC80B3002CC80A00328C00A3307F +:10E5500020D20900028C80830028D80B3412F201EB +:10E560007000000000000000C005AC01B8022E00E1 +:10E570000A9012EC108B002EC00AB000EC00B30021 +:10E5800022C10B9202CC01AB002AC002B002F004FF +:10E5900060000000000000004015E000FA0C3EC0E2 +:10E5A0000FA013EE20DB003EC02E8853EC00FB00D2 +:10E5B000B2C08FAC83AC08DB001AC04FB003C004FC +:10E5C0007000000000000000E001B800FE003FC045 +:10E5D0002DE003FE807F003FC00DD203FC00BF0191 +:10E5E0003EC00DC803FC0CFF003FC009F023F8003B +:10E5F00060000000000000004010A400FA4032C19A +:10E600000FA0032908DB003EC00E8503EC20CB00E1 +:10E610003AC00EA403EC00FB003AC20EB003100493 +:10E620002000000000000000C8052C00BA6020C0D7 +:10E630000BA0020800AF002FD00BB502FE028F0026 +:10E640002FC00D800A3C00B70023C205F02236001F +:10E650004000000000000000C0044000B18820001D +:10E660000B10020C0083002EC80B08064D408300DF +:10E6700020C00830060C0893200AE04A3002380017 +:10E68000500000000000000020105A00B59021202A +:10E690000B58423E00A7802DE00B6902DE408792B6 +:10E6A0002DE00918029E01B78029E00370023E00A8 +:10E6B000400000000000000048084400F101300064 +:10E6C0005F18030C1083003CC40E0403EC008300AD +:10E6D00030C40C31038C00F30038C80E3103120231 +:10E6E00000000000000000004015BC00FD04BF0455 +:10E6F0004F5803F808EF083FC00FF001FC00FF4C33 +:10E700003FC10FD0033C00F70037C20D7203D006A3 +:10E7100060000000000000000805E200DB0032C0DD +:10E720004DA8032C08FB007EC88FB00B6F45EBC2D1 +:10E7300036C007A003EF20CB50B2C00C79032A00EB +:10E740007000000000000000481998008F0021C0F0 +:10E750000B60035C0037002DD20B30020CA887241D +:10E7600021D0097002DD88872A23E808700232046C +:10E7700060000000000000002000B600978021E04B +:10E780000B68021E00B7802DE88B48821E80A38490 +:10E7900025E80B6802CE02878021E0087A0220007B +:10E7A00020000000000000006804CC08838220E004 +:10E7B0008B2A024840B3002CC00B30820C0083002F +:10E7C00000C1093102CC00830020C008300A1204C5 +:10E7D0003000000000000000E815E800DAA032A8D0 +:10E7E0008DA8033B00FA003E800FE4036800EA02B4 +:10E7F00036800FE403E800CA0032802CA0033A04FC +:10E8000060000000000000004801A010F800BE20D9 +:10E810008FC103E024F8003E100F8403E000F801EC +:10E820003E000F8003E000F801BE100F8003D2000D +:10E8300030000000000000000810A400F940324041 +:10E84000CF9003E400C9000E500F1A032600F90010 +:10E850003E400F9081E400F98032400C9003C204E6 +:10E86000300000000000000080046404B104224075 +:10E870000B9002E400A9002E530B920A2648B9041B +:10E880002E400B9002E400B9800250089002E00094 +:10E89000100000000000000038052400BD002340E7 +:10E8A0000BD012C40089022E400B90222400B90024 +:10E8B0002E400B9002E400B1202040689022C60058 +:10E8C000400000000000000028141400BF12A14006 +:10E8D0000B5002C400A1202C480B12020410B111ED +:10E8E0002C480B1322C400B140205A081002C20168 +:10E8F0000000000000000000B80D6140F840321434 +:10E900000F4503E140C8503E158F850321E8F868A4 +:10E910003E140F8403E1E0F02832A8CC8023EE03FC +:10E9200050000000000000009815C410F9203E407F +:10E930000F9003F400F9103E440FD103E400F920D6 +:10E940003E440FD303E400F900BE400F9403E606F3 +:10E9500070000000000000001815E400FD103340B6 +:10E960000CD0032400D9003F404CD003F600FD90AA +:10E970003A400C9003E6A0FDA837680CD883260027 +:10E9800070000000000000003810E008C8A022005D +:10E99000088002200088002E000C8012E000B88061 +:10E9A00022000D0A02E380B0C020340884034E0424 +:10E9B000300000000000000048008409A100204150 +:10E9C000089002240091002C40081002C500B1609C +:10E9D00020400810A2C420B128244A081002520185 +:10E9E00070000000000000001814A4018100A24083 +:10E9F000A89000254089012C40089402E400B90049 +:10EA00002A40099002E401B90422414890024604D8 +:10EA10006000000000000000A014A520E9003240C2 +:10EA20004C100B2600D9003E402C9803E400F9005E +:10EA3000B2400C9003E400F90036402C90036804C7 +:10EA400070000000000000004801A400E9003E4002 +:10EA50000F9003E600F9003E400E9A03E400F9002F +:10EA600036400F9003E400F9003C400F9003DA00B9 +:10EA700060000000000000000810A100F800320053 +:10EA80000F8013A000C80032048C8003A0C0F800DF +:10EA90003A000F80032000C00932004C80010A04B4 +:10EAA000200000000000000028052800BE00208093 +:10EAB0000BE0028800AA0003A00AE602FA008A001E +:10EAC00032800BA00228008E80A3802820028A00BA +:10EAD000400000000000000028056C00B348204002 +:10EAE0000B10020C00830020C00834828E049900B1 +:10EAF0000AC01B30020C02905020600830020A004D +:10EB0000500000000000000080111C80BD0A214858 +:10EB10000B52029C40A3A020800A6002CE008520F8 +:10EB200021C40B7A061E80952021900870022800CF +:10EB3000400000000000000088081E80F780B179C6 +:10EB40000FDB023E20C7A0B160CC78139600F1F035 +:10EB500039E20F7B130F00D4A031602C70032A021E +:10EB600000000000000000000815AC00F7003E4067 +:10EB70000F9003ED80FB103E400BB023EC00F9201A +:10EB80003AD80FB00BED81ED103E800F3003C20676 +:10EB900060000000000000000004BE20EE80336032 +:10EBA0000CD8831E006F8033E00FB8113204F5805B +:10EBB00033E00FF8832F40FE80B3E00CF803100021 +:10EBC0007000000000000000A8189C00BC00A144D8 +:10EBD0000810035C008F0021800BEA221C80B50125 +:10EBE00021C00BF0021E80BE0023802A70022A047E +:10EBF000600000000000000000009C20A7002340EF +:10EC00000B500A3C00A70025C00A43021000B500C3 +:10EC100021C00B70821C80B40021C0087002040067 +:10EC2000200000000000000020048E04B3002240F9 +:10EC30000914024C00830020C00B24820400B100A0 +:10EC400020C08B3A022C01B00020800A30021A0446 +:10EC50003000000000000000A8159E00EB043340C7 +:10EC60002DDC031D60EF003200CF9A032800FD0069 +:10EC700033C18BFC0B3C00FC0032800C90032A0457 +:10EC800060000000000000008000AC10F8003E4072 +:10EC90000E9823AC04FB003C000F8420ED00F9002B +:10ECA0003EC04FB003EC00FD003E800F9003E40037 +:10ECB00030000000000000002110FC00CF80334035 +:10ECC0000CD083FC00EF003F400CF1413010CD0030 +:10ECD0003FC00070133C00E400B1D00C10032004CE +:10ECE0003000000000000000A1042C008AE42A404B +:10ECF000289002EC008B003E020A80022C828904DC +:10ED00002EC10AB00A2C00890222F22A98022000A1 +:10ED1000100000000000000080052C0280142A4032 +:10ED2000089002EC08AB042E84081082801089033E +:10ED30002CC04AB0222C00AA002280089102200098 +:10ED4000400000000000000008142C008000284053 +:10ED5000081102EC0083002C810A005A880001008F +:10ED60002CC00A30020C00820020800A100202012E +:10ED70000000000000000000000D6C00C9003A40D7 +:10ED80000CD403FC00EB003E400C9203A0004D00AD +:10ED90003FC00EF0333C80E80032C00C90032003EB +:10EDA0005000000000000000A011FC00FC003D40ED +:10EDB0000F5003FC023F043B014FC4137000FD00E1 +:10EDC0003FC01FF001FC40FC003FC00FD013E8061D +:10EDD0007000000000000000C005F8E0FF803DC0AA +:10EDE0000DF382F080FF4031CB0CF303FD04EFC143 +:10EDF00033E00F7903FE00CF4233F04CF8033000CC +:10EE00007000000000000000E010E908B9812FF058 +:10EE100008F452E920BF4023F00AF302FD088B00FA +:10EE200036E00B8022E8808F4022C008B082300498 +:10EE30003000000000000000C805CC00B1802CC5E7 +:10EE4000093242C8C0B33120C1083202CCD4BB2041 +:10EE500068C00B3002CC2093602088083202320157 +:10EE60007000000000000000E015A000BB802EC074 +:10EE700008B002EA00BB0062C10AB002CC00AB00DD +:10EE80002EC00BA000E800830022C108300230042D +:10EE900060000000000000000015E890FB803EC00C +:10EEA0000DB003E210FB0032C04CB013EC00E9548B +:10EEB0003AC00FB003E600CB00B2400CB00304042C +:10EEC0007000000000000000E001B800FF003FC03B +:10EED0008FF003F000F702BFC10FF023FC00DF0644 +:10EEE00037C08FC907FA92FF043F502FF003F80094 +:10EEF00060000000000000005010AC00C9003EC2DD +:10EF00000EB023E400EB003AC80EB003EC00F900A9 +:10EF10003EC00FB403A400FB003E800FB083D004BA +:10EF20002000000000000000C80528008B742DC0E0 +:10EF300008F002E4008F0021F008F002FC10D3007A +:10EF40002EC00B90122C00EF002EC00BB602F60064 +:10EF50004000000000000000E8054800A3002CC4A9 +:10EF60000A3002C000A30068F00A3012CC04A200EC +:10EF70002CC00B3002EC00B3012EC00B3402F800A1 +:10EF80005000000000000000B0010C0087802DE858 +:10EF9000087842DA00878025E0087902CE00968062 +:10EFA0002DE00BD902DE00A7802DE00B7802FC00DB +:10EFB000400000000000000048080C40E3103CC086 +:10EFC0000A3803E800EB0038C20A3003CC00E34003 +:10EFD0003CC00F3403CD00F3203C880F3003D20235 +:10EFE0000000000000000000401DB480FF043FC886 +:10EFF0000FF083F840FF183BC00FF483FC00EE02D3 +:10F000003FC00FF0033C00EF083F800FF013D00625 +:10F0100060000000000000008805E800CB003EF220 +:10F020004DB213E804CB0132F84DB2136D20F80055 +:10F030003EC00F30032400FB003E408FB8032A007F +:10F040007000000000000000C8118C0086002CC079 +:10F05000087302D812873020CB08F2021D05B500D4 +:10F060002DC00B60035010B7092DC00BF002320405 +:10F07000600000000000000080009E0087802DE4FA +:10F08000097A02CE01878021EC0978025E80B7C040 +:10F090002DE00BF8021E00B7A02D600B78022000B7 +:10F0A00020000000000000004814EE0082802CC008 +:10F0B000083002EC008300A0C00830020C00B380CE +:10F0C0002CC10B30024E00B3002CF10B300A12049D +:10F0D0003000000000000000E815BA80C6003E8045 +:10F0E0000DA003F840CA0032800DA0136800FE0294 +:10F0F0007E800FED833910FA003F8C0FA0033A0495 +:10F1000060000000000000004800E012F8903E009F +:10F110000F8003E000F8053E000E0003E000F880D9 +:10F120003E000F8003E060F8007E000F8003D200F5 +:10F1300030000000000000000810E400C9803264C4 +:10F140000F9043E406C1043A400F9003E400E90045 +:10F1500032400F90032400C10132400C9003C204DE +:10F1600030000000000000008004640089C02240DC +:10F170000B90022400890022501B90222400810061 +:10F1800022400B90222408C9002040089402E0008D +:10F190001000000000000000180524009920224003 +:10F1A0000B1002A40089002A580B90028400A900C9 +:10F1B00022400B100A0400990222C1089082C60066 +:10F1C0004000000000000000080404009102A0C8F4 +:10F1D0000B12020480812220489B120204908901B4 +:10F1E00020400B1002040281222240081002C201BA +:10F1F0000000000000000000B80D6142DA01320199 +:10F200000F8503A140C0503A018B8523A144E850EB +:10F21000B2000F85032148D85132142C8503EE0328 +:10F220005000000000000000981DF500ED023E4473 +:10F230000F9103F440F9103E440F9103E440FD00A8 +:10F240003E400FD003F400E910BF400F9003660664 +:10F2500070000000000000001805E621C5003368BA +:10F260000F9A036F88C9C033680C9E032780D9406A +:10F270003E400F9003C510D9E836500CD003E6008D +:10F2800070000000000000003810E10888008200D3 +:10F290000B8E82EBC888E02200288842A2808A80F8 +:10F2A00022000BAA02E20088C022A9088A038E0469 +:10F2B00030000000000000004805C400810020D09C +:10F2C0000B1132848481606050081606050091207D +:10F2D00020400B1082E409912024400810C2D20182 +:10F2E00070000000000000001815A40489042240EA +:10F2F0000B9002C400A9002241009002A4008100EA +:10F3000022400B9222E58099012261089002860436 +:10F310006000000000000000A014A582819032402F +:10F320000F90136702C90032400C90232404D9C007 +:10F33000B2400F9C03E600D90036500C9003E8045D +:10F3400070000000000000006800A680F9003E4048 +:10F350000F9003E700D900BC420F9053E404F9106A +:10F360003E400F9803E604E1003E402F9003DA0090 +:10F3700060000000000000002810811048103208D2 +:10F380000C800F2102C8003A040F80076000F8408B +:10F39000B2000F840B2000D80036100C8003CA0482 +:10F3A0002000000000000000280428048E80238034 +:10F3B00008A04228008A0023A04BA002E800BA005F +:10F3C00076800BA00208008A00328008E003CA00A1 +:10F3D000400000000000000028054C00820020D002 +:10F3E0000830020C009B0028C01AB0026C00B30267 +:10F3F00020C00B30020C00A30022C0283482CA00B7 +:10F40000500000000000000020011C00870020E0E8 +:10F410000878020C00972025C00B7102DC81B72010 +:10F4200021C00B7A423C80872021C0087002E8008E +:10F43000400000000000000028080E82C780B1E0F4 +:10F440002CFA061E08D3B139604E78125EA0FFF088 +:10F4500021E00FF8031F08E3A033E00C6803EA0281 +:10F460000000000000000000081DAC40FB003EC092 +:10F470000FB203EDA8EB103A800FB0C3EC40FB00D5 +:10F480003EC00FB083EC80EB70BEC40FB0038206A9 +:10F4900060000000000000004005FE00CE80B36068 +:10F4A0000FFC837E20EFB03BE00FB8033E00CF811E +:10F4B0003FE08FF883EF40FFC233E10CF803D00048 +:10F4C0007000000000000000A8119C8287182180B5 +:10F4D0000B30021C60D71021D00B7B023C00D70000 +:10F4E0002DC00B7002DE00BF00A3C4087003AA0485 +:10F4F00060000000000000000000BC11870021C077 +:10F500000B30021C00932069C00B70021C008700A6 +:10F510002DC00B7102DC20B71021C00860028400EE +:10F5200020000000000000006014CD00834020C0D7 +:10F530004B30020C01830020C00B30020C00938082 +:10F540002CC00B3002CC01B30020C008302298043C +:10F550003000000000000000A815BF20CAC03280A3 +:10F560000FF0033E009F003A800FF00B3C00CF9855 +:10F570003EC00FF603FF00FF0031E02CB003AE04E5 +:10F5800060000000000000008000CC80FB003E50C6 +:10F590000FB003AC02FB007E500FB003EC00FB0089 +:10F5A0003EC00FB203EC20F3003EC60F9003A00054 +:10F5B00030000000000000000110FC02CF9873C86A +:10F5C0000F70033C00FF0033280FB0021C004F00F7 +:10F5D0003FC00FF003FC00FF0133C00CE403E40460 +:10F5E000300000000000000080046C008380A2F85E +:10F5F0000BB0422C00BB0032100FB0036C04AB0008 +:10F600002EC00BB012EC04EB0022C04A9482E00042 +:10F61000100000000000000080056C008A0022003D +:10F620000BB0022C00B300A2C00B3002AC00AB0444 +:10F630002EC00BB042EC00BB0022C008B022E0009C +:10F64000400000000000000008000C008B012000BA +:10F650000B30060C00B30020C00A320ACC00A30015 +:10F660002CC00B3002CC00A30022C04A0012C20101 +:10F67000000000000000000000086C008B0422C0A5 +:10F680000FF1031C00FF0432C00BF203BC00EF00BB +:10F690003EC007F003FC80FF00B2C00CA003E003F3 +:10F6A0005000000000000000A019DC00F5003FC081 +:10F6B0000FF003FC01FF023BC00FF1037C00FF00D1 +:10F6C0003FC00FF013FC40EF003FC00FC003E8063F +:10F6D0007000000000000000C015F240CC80372010 +:10F6E0000CD803B044FC083F0E0FC103FC00CC94BF +:10F6F0003F0A2EC4037D80CF103FC00FC08330006F +:10F7000070000000000000008008E0908802228164 +:10F71000089213A4403B6022180B8102FCD48100A4 +:10F720003AB00A94023D40AF632FDF0B98002004EB +:10F7300030000000000000008805E0008800204044 +:10F74000883082C000B00828800A1002CC208001D6 +:10F750002C401B06028C90936068C04A0042220134 +:10F760007000000000000000C005A002880022C058 +:10F7700008B002E420BB8826980B8042CC188A008F +:10F780002EC21B9802AC00AB002EC00B9882300436 +:10F7900060000000000000000011E3C0CB02320056 +:10F7A0002C8003AE08B9003E700FB903EC02484844 +:10F7B0003CC00F8C93EC00DB001AC00EAC031004AD +:10F7C0007000000000000000E001B200FF00BB80FC +:10F7D0000FC043B640BD003B600FE803FC00FF9440 +:10F7E0003BE40E600F6C08EF013FC00F6003F800B0 +:10F7F00060000000000000004010A100FB003E601F +:10F800000FA003ED00F9403A000F9003EC02C90489 +:10F8100032D00F90032C08DB00B6C00DB403D00427 +:10F820002000000000000000C8050000B3892EE0A1 +:10F830000BA403A401B9002E010B9042FC108950C7 +:10F84000A2C08DB4023C448F0023C008B002F20075 +:10F850004000000000000000C0040C00B0802E003A +:10F860000B1202C800BA002CC00B2002CC00A20070 +:10F8700020002B2D9A2E42830028C0082002F80079 +:10F88000500000000000000020001E04B4802DA0E5 +:10F890000B58029200B6802DE00B6802DE40A68075 +:10F8A00021242948021E80878069E0086102C8007F +:10F8B000400000000000000048180C00F0303C4CF4 +:10F8C0000F3203C880B20038800F1B03EC00E03019 +:10F8D00030040FB1030E85CB003AC00C3103D202C5 +:10F8E0000000000000000000401CBC00FC113FC4F0 +:10F8F0000FB813B004FE023F800FC003FD00DF12FB +:10F900001D040FD043BC01EF1033C40EF303D00627 +:10F9100060000000000000000805EE00CB003E0083 +:10F920000F80032800F8003E403DB003EF08C900F7 +:10F930003A000CA003EC98FB2032D20CA8032A0258 +:10F94000700000000000000048119C0087012D801D +:10F950000B40421C043700A140086002CC808700A5 +:10F960002D802E7002DCA9B72821D0087002120069 +:10F9700060000000000000002000BE0287802D60B3 +:10F980004BE8025A01B48828E08878C2DE5286C06B +:10F990002960086802DE40B392E1E828280270007E +:10F9A00020000000000000006814CC008B802EC0F6 +:10F9B0000B20024D809B2020E0083802CC00838081 +:10F9C0002CC00AB002CC08B30020C0083102520497 +:10F9D0003000000000000000E805A800CAE03E80FA +:10F9E0001FA40B7900FE003F821DE003E800CE401B +:10F9F0003B882CE403E801FA0032800CE8037A0427 +:10FA000060000000000000004811A000F8093E005E +:10FA10008FC083A018F8003C200F8803E000F8088E +:10FA20003E200E8083E101F0003C000F800B92002D +:10FA300030000000000000000810A400F94232402D +:10FA40004C98030400C9003A400F90232400B98168 +:10FA50003C400C92032400F90532406C90C3C20470 +:10FA6000300000000000000080042414B900A254FB +:10FA7000089B1A240289002240289002A400B99011 +:10FA80002E40289C822504B9002240089812E000EC +:10FA9000100000000000000018052400AD00234005 +:10FAA000085002640089002A400810026400B9006E +:10FAB0006E400890022500A9002240089106C60069 +:10FAC000400000000000000008041400B510A1442C +:10FAD0002850024480813020480812028440B180BE +:10FAE0006CC80812020480B1342048081202C20116 +:10FAF0000000000000000000B80D6140E8403290B6 +:10FB00000CC5036140C0403A140F850321B0F85082 +:10FB10003E000C85032140F840B0140C8003EE0138 +:10FB20005000000000000000B81DC404F9220E4877 +:10FB30000F1013B440FD303F444FD100E484FF0167 +:10FB40003D440FD10BE440F9303E440FD103E604AD +:10FB500070000000000000003805E400DD403F5068 +:10FB60000CD0032C00C90036400F90132704F50178 +:10FB700037400CF003F620F9A832680CD003C60019 +:10FB800070000000000000001800E00088A02E288F +:10FB9000288002200088A022000B800A6280B80022 +:10FBA0002200088002E100B8E0223A08A002CE0458 +:10FBB00030000000000000004800840281002E4058 +:10FBC00008100A4402810824400A10024580B90046 +:10FBD0002440291002C400B1082444081002C201C4 +:10FBE00070000000000000001814A40489012E50C9 +:10FBF00048B2026400910022460B90026400B901F1 +:10FC000026C009B012E400B1002640089002C604E4 +:10FC10006000000000000000A004E400C9003C40B7 +:10FC20000C90036400C90236500E93032400F9902F +:10FC300036480D9483E408F900B6400C9403E804B8 +:10FC400070000000000000006810A400E9003E40C1 +:10FC50000F9013A400E9022E61059003A400F9009F +:10FC60003A400E9043E410F90038402F9003CA0048 +:10FC700060000000000000002810A000D80132043D +:10FC80000F8043C001C800B2010C80032000C840AF +:10FC900030008C8483E000C80032006C8403CA0406 +:10FCA000200000000000000008042800BA002380A3 +:10FCB0000BEA02E800AA00228008A00228008620A1 +:10FCC00037A08DE402F800DA00228008A002CA0002 +:10FCD000400000000000000008056C00B30020C0D8 +:10FCE0000BB8024C04830020C008B0020C02830051 +:10FCF0002040283402CE908300A0C0083002CA0001 +:10FD0000500000000000000020011CC0B588214008 +:10FD10000B7002DC80A32021E04832420E908E015D +:10FD20006550097002DE20932121C0087002E800AE +:10FD3000400000000000000028181E00FF80B1A055 +:10FD40000F48027E0087A033E0287A0B1F00C48092 +:10FD500031608C5803FE00C7C833E80C5803EA0230 +:10FD60000000000000000000081DAC00FF003E0085 +:10FD70000F9023ECA0FB403EC08FB503ED80F80050 +:10FD80003C400FB003E800FB023ED00F9003C206D8 +:10FD900060000000000000006004BE00FF803FE043 +:10FDA0000FD903FE20CFC833EA8FFC033F00FD804C +:10FDB0003F600EE803F200CF802FFE0C78030000B6 +:10FDC0007000000000000000A8009C00B5022DC0DB +:10FDD0000B5842DC80CF0021C10B30121C40B40212 +:10FDE0002D46087112C800E7002DC40870036A048C +:10FDF000600000000000000000009C00B7002D0221 +:10FE00000B4602DC08970021C90A30221C00B4000E +:10FE10002D400A5082C400B7002CC8285002401060 +:10FE2000200000000000000040148C18B3002E20B9 +:10FE30000B1802CF4A83C220C10B34220C04B858DD +:10FE40002C400B2802C800A3002CC0081402480450 +:10FE50003000000000000000A805BC00FB003E8050 +:10FE60000FA002FC00DFA0B3C00EF00B3C00FBC0F3 +:10FE70003CA00EBD03EC00FF003FC00C30036A0441 +:10FE80006000000000000000A010EC00F9003E013E +:10FE90008FB143EC00F3003EC04FB013EC00FB0009 +:10FEA0003E800C8403E10073003EC10FB243E000CA +:10FEB00030000000000000000150FC10FF8037C03F +:10FEC0000CE003FC20FF0833C00FF083BC00FF00F0 +:10FED00033C02E40031C01CF0011C04CD00300449E +:10FEE000300000000000000081046C04B3022272A4 +:10FEF00008A116EC00BB0422C00BB042EC00BA19FA +:10FF0000B6D0089C4A2680DB0022C00890036040DF +:10FF1000100000000000000080052C00B9106220D5 +:10FF200048A002EC00BB0022C00BB002EC10BB00EA +:10FF300066080AA81226109B002AC028B0262000B6 +:10FF4000400000000000000008000C00B900200084 +:10FF5000083202CC04B30020C04B3002CC00B30006 +:10FF600020000800020100930028C008300642115A +:10FF70000000000000000000001C6C00F900B2400E +:10FF80000C8202DC01FF00B2C00BF103BC00F900DF +:10FF900026402E80032104CF00BBC00C9003000339 +:10FFA0005000000000000000A01DFC00FD003F40CC +:10FFB0000F8103FC00FF003FC00FF023FC00FC009A +:10FFC0002D402FC003F088FF0037C08FD003E80218 +:10FFD0007000000000000000C005FE40FF8033C23A +:10FFE0000CF8037CA0FF903FC42CB403BC80CF402E +:10FFF00037E00FF1936E44BF303F202CF863F004DC +:1080100070000000000000008010EC00EB2023F056 +:1080200008B8523D00B3002EDC08F4421C428B40DD +:1080300022C80BF6036C88BB302E0008B202E004A5 +:1080400030000000000000008805CC00BB0820C004 +:108050000830024CA0B3202680883602CCA0936062 +:10806000A4C20A32424C90B3202C0B883082E20129 +:108070007000000000000000C015AC08BB22A2C0C8 +:1080800008B0022C00BB002E9008B002EC009B0050 +:1080900022C00BB0026C00BB022E2008B002F00020 +:1080A00060000000000000004015EC00B18332C009 +:1080B0000C1A036C10FB0034C00CB003EC08DA009F +:1080C00036C00EB00B6C00FB003E280CB002D00096 +:1080D0007000000000000000E001BC00ED803FC027 +:1080E0000FD403EC00FF003FC80FB0033C00EE408C +:1080F0003FC00F7003FC00FF003F800FF003F8004B +:1081000060000000000000004010AC00FB20B0C088 +:108110000FB403AC02CB0032900EB0036C00EB0046 +:108120003AC00CB002EC00FB003E910FB00390008F +:108130002000000000000000C8052C00BB8023D7F1 +:108140000B90023C148B006A0828F000BC008300EE +:10815000BEC088F0132C00EF002E800BB007B200D9 +:108160004000000000000000E0054C00B34020D0BB +:108170000B28028C00830120C01AB8006C10A100EB +:1081800068C02A30028C00B3022E004B3002F80483 +:10819000500000000000000020011E00B7A021E0F8 +:1081A0000BECC21E04878029E40879829E40AF90C0 +:1081B00029E00A38001E00A7902D240B78028800C1 +:1081C000400000000000000048080C50FB0930C0CF +:1081D0000F20028C40C30020C00A38034C44E10049 +:1081E000AAC00E31438E00F3003C000F3003D202D0 +:1081F0000000000000000000404DBC00FF203FD008 +:108200004F7003FC00FF003DC00FF343FC40D7005C +:10821000BFC00DF4C3FC40FF003F400FF003D00689 +:108220006000000000000000A805EC00FB0032D058 +:108230000D9001EDC0FB003EC01FBA03ACC0C800EA +:1082400032E08DB443EC00FB0036A00CB0036A00B2 +:10825000700000000000000048119C00B70021C819 +:10826000086002DC20B7002DC00F74A21C28D600C5 +:1082700035C00872025C08B744A180487002120041 +:108280006000000000000000C0009E00B78020E4F5 +:10829000097826DE00B7802DE20A70128C88818072 +:1082A00021E0097802DE00B3A025A028780270043E +:1082B00020000000000000004814CC01BB8020C05A +:1082C000083042EC00B3002CC00A30220C009300AE +:1082D00024C1083002CC00B30020E008B002120430 +:1082E0003000000000000000E815A800FA08B28085 +:1082F0000DE203E800FA003F800AA003A800CE5078 +:10830000328005A003E800FA0037A80CA0037A0425 +:10831000600000000000000048006008F8003C0019 +:108320000F8801E000F8043C004F0013C000F80083 +:108330003E000F80036000F8023E010F8003D20070 +:1083400030000000000000000810E400F990124026 +:108350000C9003A400C9003E700E94332408C90099 +:108360002A400B9003E400F9003A400F9003020406 +:10837000300000000000000080046400B942226068 +:10838000081002240089032E40089002A4018104F1 +:108390003E400B9002E400B90222400E9002200001 +:1083A000100000000000000018052400B9402A4A0F +:1083B000089102A40089002E401A900A2404890022 +:1083C0002A400B9002E400B1002A400B9002060004 +:1083D000400000000000000008040400B101A848AB +:1083E000889002048081402C5018140A841089401F +:1083F0002C400B1002C400312020400A100A020158 +:108400000000000000000000B80D6140F0503A008C +:108410002CA002A142C8003E00DE002321428800B9 +:1084200038140F8503E140F85038140F05032E016E +:108430005000000000000000981DE408FD003644D4 +:108440000FD0036440F9003D500F9403E5007D40D8 +:108450003E400F9403E400F9103F400E9003E60401 +:1084600070000000000000001805E400FD403368C3 +:108470000CD003E781F90033780DD81326A0CDA0E6 +:1084800032400D9B032400F9A03C442C9007860049 +:1084900070000000000000003810E000B8A0A2103A +:1084A0001880038284B880362C2E0F02A3A0D8E057 +:1084B00036228B080342A0F8E02E28088802CE045A +:1084C00030000000000000000805C400B100A0500A +:1084D000283002C580B10820400910A24408814814 +:1084E00020400B14020480B1382C4808128282010B +:1084F00070000000000000001811A400B10022402C +:10850000089202E400B90226584A9002E408994011 +:1085100026400B90026408B9012C48089012C6044A +:108520006000000000000000A015E400F980324067 +:10853000089883E404B90130400D900B6402C9002F +:1085400032400F90032400F9001E580C9003A80439 +:1085500070000000000000002801A400F9203C4049 +:108560000F9803A400B9003E428E104B8404F9001A +:108570003E408F9003E400E9003E400F9003CA00A4 +:1085800060000000000000002810A000D8003208A1 +:108590000F8483A004C8043E008380012000C00033 +:1085A00032000F0003A000C80032104E8013CA042E +:1085B0002000000000000000280528008E90A38005 +:1085C0000BE4022800CA002F804AA013A800AA00CA +:1085D00036810BA00228008A00228008A0038A00AE +:1085E000400000000000000028054C0093C020D08F +:1085F0000B34028C008B002CF08B18024C00830093 +:1086000060C00B30028C02830028C10A3002CA000D +:108610005000000000000000A0011E00B40B69C063 +:108620000958061E8097102FC24870829C80A708A8 +:1086300025CC0B70021E8187A2ABC4087302E80030 +:108640004000000000000000A8083E10DC8421E08B +:108650000F78429F02C7883DE02F71034E00CF8004 +:1086600021E20F78839E49CFD039E80E7803EA02E1 +:108670000000000000000000084DAC40CA003600B9 +:108680008F3023ECA8EB403CC00F9643ED80FB00FD +:108690003ED88FB143ED80FB2036CA0FB0A38206CF +:1086A00060000000000000000005FE80FC8031E05A +:1086B00005AA10FE44FF903FE1CFF9173F20D78075 +:1086C0008BE40FF8033E30FF8037E00FF8004000E6 +:1086D0007000000000000000A8119C00BD1021C027 +:1086E000084A02DCC0B7002DC20CD3021C808700F0 +:1086F00029C04B72021C00B70121C00BF0122A04E2 +:10870000600000000000000000009C903400218008 +:108710000970005C0CB7002DC408501A0C009700BB +:1087200021C04B30021C00B70025C00B7002400076 +:1087300020000000000000002014CC00B000600009 +:10874000083E02CC00B3020CE02BB0020C009300F8 +:1087500028C00BB0022C10B30020D603300208044E +:108760003000000000000000A815BC00FB00B200B3 +:1087700005BE037C00FF003E200CB0033C00D98006 +:1087800033C08BF0033C00FF0037E00FF0036A04B6 +:1087900060000000000000008000EC00FB043E00D0 +:1087A0000FA423CC00FB003E81089003EC00E914E9 +:1087B0003EC00FB003EC10FB003EC00FB003E00062 +:1087C00030000000000000000110FC00FF003780B6 +:1087D0000FFA03FC00CF003F9006DC233C00FD10A5 +:1087E00033C00FF00B3C00430033C00FF003C04414 +:1087F000300000000000000081006C09BB1922322B +:108800000BBE036C008B002C900DB802AC00B100C5 +:10881000F2C00BB012AC008B0022C00BB003A04022 +:10882000100000000000000080052C10B30026207E +:108830000B9012EC018B002AC20A90022C00BB00A4 +:10884000A2C00BB0022C00AB002AC00BB002E000AB +:10885000400000000000000008040C01B3002000EC +:108860000B00028C0083002EC00B34028C00BB0076 +:1088700020C00B30020D00A300A0C00B300282010B +:108880000000000000000000000D6C00BB043680FA +:108890000FB202FC02CF0238C00EF0033C00FB0016 +:1088A00023C00FF0033D02EF0033C00FF043C003BD +:1088B0005000000000000000A01DFC00FF003F0071 +:1088C0000FF4237C00FF003FC00DD003FC00FF002D +:1088D0003BC00FF003FC88DF003FC00FF003A80689 +:1088E0007000000000000000C005F050CE1233D030 +:1088F0004C868330805F6833C40FF3833CC0CC3830 +:10890000B3080CC603F1A0FF0033240CC203F0002F +:1089100070000000000000008010EC80D22023D8FE +:108920000D96028860AF4023DC0BF6023CC28860E3 +:108930002252089122E100B724A2488A848260046E +:1089400030000000000000008805C4008100E0C481 +:108950000A00020480A320A8C01B300A0C00A0005B +:10896000280C090202C480B31C2208190302E21178 +:108970007000000000000000C015A400998062C0D3 +:108980000BA032A451AB002AC08BB0000C00A9C0D0 +:108990002A2108B822E200BB0022841BA8427004EE +:1089A00060000000000000004015E200CBC932C0AA +:1089B0000E8B132210DB0132C00FB00B2C0068812C +:1089C0003A222C8823E300FB0030308D9C83D004B6 +:1089D0007000000000000000E001BA40F7043EC251 +:1089E0000DD823D8007B0037C00F7033FC10D200A5 +:1089F00035C08FC003F400F7023FE00E8003F8009B +:108A0000600000000000000040108120C80830C055 +:108A10000C00832440C3893AC00EB00B2C08C9480F +:108A200072540F9103ED02EB8A3A628C800B1004B2 +:108A30002000000000000000C8052B048840A3C2ED +:108A400002AE1227428F4423C20BF4023D000A40BB +:108A500022E00BB502EC208F44A2408DBD233200F2 +:108A60004000000000000000E0054940838124C16F +:108A700008280201009300A0E80A30828F60B390BA +:108A800060B80B28124A0093002090092002780059 +:108A9000500000000000000020011E0287A825E011 +:108AA0000A7B021A04878021E40B78828E02969159 +:108AB00021210B6940DB40979223A089588208004E +:108AC000400000000000000048082582C30034C0B8 +:108AD0000C9B4308D0D32038C00EB0038C00B300E9 +:108AE0002080071003E000D31038180D3003520225 +:108AF0000000000000000000401DB4007F201BD0DB +:108B00000FF103F840EF003FC00FB4037C20CF0407 +:108B1000BF400FF003E410EF183DC00FE003D00694 +:108B20006000000000000000A805E800E300B2C4F7 +:108B30000CA0032400DB6832C80CB403EC80C880AE +:108B4000B6E00CA0032E00CBE0B2600CB80B2A00FC +:108B5000700000000000000048119C028700A1C8BE +:108B60000870021C08970221D4087402DCC00700B8 +:108B700021C08870021800830821C0085002120426 +:108B80006000000000000000C0009E20AD8029E0D1 +:108B90000858021E0097B021E8087802DE10158000 +:108BA00021A10848025E0087A465A0087802300071 +:108BB00020000000000000004814CF108170A8C001 +:108BC00038300A0D009300A0C1283002CC028388FF +:108BD00020E038340A4D72830024E82834821204DD +:108BE0003000000000000000E815BA40EEC0BA8076 +:108BF0000CE0033910DA0032800CA003E800DEC874 +:108C000033A00CE0037B00CA0037B10CE4233A0424 +:108C100060000000000000004800C100F8003600BD +:108C20000F8003C02038003E000F0003E000F80270 +:108C30003A240F8083A001F8043A040D8013D20077 +:108C400030000000000000000810E444C100324081 +:108C50000C9032240CC10638400D90090400D90054 +:108C60003E400F18032400F9013E400F9003C20458 +:108C700030000000000000008004640689002A50D3 +:108C800008940A2400894222500A90122500890083 +:108C90002E500B9C0A2510B9002E500B9002E000BC +:108CA0001000000000000000180524208900204268 +:108CB0000810C2AC1089082A4209900224209900A9 +:108CC0002E420AB1822C20B9006E420B9002C600DF +:108CD0004000000000000000080404008300284851 +:108CE0000812628C80810020400210028480812062 +:108CF0002C490B12060484B3026C400B1202C20111 +:108D00000000000000000000B80D41E0C8783014F9 +:108D10004C0513A142C078381E0D87830140D05006 +:108D20003C140E05030140F8783C140F0503EE03D4 +:108D30005000000000000000981DFC00FF000E44E1 +:108D40002FF1037440F9003E400D90036440FD1084 +:108D50003F440FD101F440F9013FC00FD103E606B3 +:108D600070000000000000001805E622E988B2400B +:108D70000F90032416C98C367B8F9C83A790C90063 +:108D80003E500494132450C9E03E500F9003060057 +:108D900070000000000000003810E28088A0222847 +:108DA0000B8A022A8088A42230088E0A220288A018 +:108DB0002E2888AA12229088F42E200BC8020E04B6 +:108DC00030000000000000000805D420A508214262 +:108DD0000B50821431850825400A502294408508A2 +:108DE0006D40085002540295002D480B50824201FC +:108DF0007000000000000000181584008D10234052 +:108E00000BD00034018D00234158D00234008D086E +:108E10002F5008D20274809D002F480BDC024604BC +:108E20006000000000000000A015E740E9C03240EB +:108E30000F90092600C90436401F9023A408C9409A +:108E40003E400C940B6420D9023E410F9403680409 +:108E500070000000000000002801A400F9803E40DE +:108E60000F1403C508F9003E401F9023E400F900E9 +:108E70003C40AF98038600E9003E400F100B8A008B +:108E800060000000000000002810B000DC40B300CB +:108E90000FC0033102C404B1003C40031000FC4089 +:108EA00033000CC403B100CC00B3000CC403CA04EB +:108EB0002000000000000000280528008A8022A071 +:108EC0000BA0022A008A8422A108A0022808BA0165 +:108ED000228008A02B28008A802A8008E002CA008D +:108EE000400000000000000028054C029B8120E0AB +:108EF0008B3806CE00938020C00838020C00B38067 +:108F00006CE00AB0024C00930020E0083002CA0076 +:108F10005000000000000000A001100480082102A1 +:108F20004B4406D020900821028044021000B4C0B7 +:108F30002D10484002000094892930084002E800C2 +:108F40004000000000000000A8083200D68031A0D8 +:108F50000FE80BCA00D68023A004F80B1A00FF808C +:108F6000BFA02EC813DA025E8073A02C7803EA0239 +:108F70000000000000000000081DAC00F9003E40A9 +:108F80000F90032400E9003E400E8003E400F80047 +:108F900032400FB003E401E90436400F8003C206FB +:108FA00060000000000000000005FE00CD8033607E +:108FB0000CD8433600CD8033600CD923BE004D80E1 +:108FC000336008F80B3E00FD843F600FF903C000DA +:108FD0007000000000000000A8119004DE00238053 +:108FE000086002B8208E04238008680210008E20DA +:108FF00023820840021200F6002D800B41A0EA04F3 +:1090000060000000000000000000900084002100CB +:109010000841025040940021000A5202D800850203 +:1090200025040840221808B4002D100B7840C00019 +:1090300020000000000000002014EE22930020C059 +:10904000083802EC00930020C12A2002640282103A +:1090500024F00A3C422428B3002CE00B8882C80488 +:109060003000000000000000A815AD00CB00B2C029 +:10907000ACBE036E02DB00B2C01EA003E400CA1146 +:10908000B6D0ACBC032400FB003EC0CF8403EA048E +:1090900060000000000000008000E040F8003C009C +:1090A0002F8203A000E8003E001D9013A800F900E5 +:1090B0003A00818343E800E8033E040FB003E00078 +:1090C00030000000000000000110E000D6003780F2 +:1090D0000CA003F800CE0033800DA0132008CE00B2 +:1090E00033820C40733018CE001F804FC1430044C0 +:1090F000300000000000000081047C008D0023404F +:109100000AD002F4008D00234008D4803E428D40F6 +:10911000234008F0023E408D000F400BF402204037 +:10912000100000000000000080052C009900A640FF +:10913000089006E400910020408800022408804046 +:1091400020400AB002240089000E400B8402200057 +:1091500040000000000000000804000082002080A1 +:109160000A2106C801820020800832820808830094 +:1091700060800A0012088082002C800B300A0201F5 +:109180000000000000000000000D6000D800360064 +:109190000C8423E000C80032000D820B2002C800BE +:1091A00032000E00032002C8003E000F80030003BF +:1091B0005000000000000000A01DFC00BF003FC0E8 +:1091C0000FF003FC00FF00BFC08FB003FC08FF02DC +:1091D0003FC00DF003ED00FF023FC00FF003E806B3 +:1091E0007000000000000000C001F08CFF003D6036 +:1091F0002CB2837C90DF3831E00FF8033C00FF2075 +:109200003FC40EF4037C00F48033000DF803F0003B +:1092100070000000000000008010E120BB622E42C0 +:1092200028F4423E408F4422E00BB0837F44BFC10C +:109230002DDC2AF6023F45B880226188B802E0049E +:1092400030000000000000008805C580B2182EC85C +:109250002930320C08B32020C04B92020C00B340DE +:109260002CC08934124C00B00024C1493002E20104 +:109270007000000000000000C011A400BA0C2EE035 +:10928000A9B0062C008B00A2C00B90006C00BB00A4 +:109290002EC00B30026C00BA8026F008B002F00439 +:1092A00060000000000000004011EE00FBC43E78AA +:1092B0002DB0036C08FB0032C08B24832C00FB0014 +:1092C0003EC08FB00B6C08B2E016608DB023D004A6 +:1092D0007000000000000000E001BE98FF403FC0A9 +:1092E0000E7003DC00FF003FC00FE003FC00FF0036 +:1092F0003FC00EF003AC00FE00B9C00FF003F80051 +:1093000060000000000000004010AD00FA403ED0B8 +:109310000EB203EC00C3003EC00CA0032C01FB0006 +:109320003CC00EB803EC00DA003AD04FB023D004B2 +:109330002000000000000000C8052C00BA002CC06E +:1093400008F407BC14DF003EC01AA052BC00BF04E2 +:109350003FC08AF003BC00FA0022C80FB003F2003D +:109360004000000000000000E0054801B1006CC2B0 +:109370000A3042CC0083052CC00830028C01B304B3 +:109380002CC00A30228C00808028C00B3022F800CC +:10939000500000000000000020011E08B7806FE0B0 +:1093A0001878028E40B7802DE00A78029E00B780C0 +:1093B00029E10A78029E01BC8029E40B7802C800EA +:1093C000400000000000000048080940F1203CC4B3 +:1093D0000E3902CC00C3002CC40892038C88B31051 +:1093E0002CC40EB0078C00C20838C00F3043D20224 +:1093F0000000000000000000401DBC10FC007FC009 +:109400000FF083FC21DF083BC08F9001FC21FF0C93 +:109410003FC20FF103EC00EF0077C01EF00390068F +:109420006000000000000000A805E801F90032C05B +:109430000FB203EE90DBE13AC04D38132D30FB0044 +:109440003EE04FBA432C40FA003FC08CB003EA0024 +:10945000700000000000000048119C00B10021C015 +:109460000B7102CC20A72821C00B70135C08B71029 +:109470002DC44B34831CC1B7022DC01A7002D20414 +:109480006000000000000000C0009A20B4C425A2C3 +:109490000B7806DE00838029E01BF8025E80A7A01F +:1094A0002DC80A72021E00A68028E0087802F0008B +:1094B00020000000000000004814ED00B34024C369 +:1094C0000B3042CC00A30020C01B34024C00B30080 +:1094D0002CC04B30020C00B3882CD40A3002D204CA +:1094E0003000000000000000E815B800FE40B7A002 +:1094F0000FA003E800DA003A800FE2036800FA00E8 +:109500003E800FA00B2800EEE03FB004A003FA0459 +:1095100060000000000000004800E004F0083A107D +:109520000F8403E010F8003E004F8083E000F80055 +:109530003C000F80038000F8403E090F8003D200FA +:1095400030000000000000000810E420E900324470 +:109550000C90032400F9003E400F9013E400B90082 +:109560001E400C10032400C9A03C640C900382042C +:1095700030000000000000008004640089002268C0 +:109580000813022408F9002E481B9002E400B900D9 +:109590003E400C90022408F9402E600A9006E0003C +:1095A000100000000000000018012400A900204065 +:1095B0000890022400B9012E400B9002E400B9008B +:1095C0002E40089222240089002E40089002C600F6 +:1095D0004000000000000000080404808121E050E9 +:1095E00028160A0480A1402C404B1422C400B1006C +:1095F0002C500914020404B1002C400A1002C201CC +:109600000000000000000000B80D6140E85032008A +:109610008C80022000B8003E000B8033E010F80080 +:109620003E000C80032008CA003E000C8003AE03FD +:109630005000000000000000981DFC40FD102F416C +:109640004F9103E440F9403E404FD063E500F940BC +:109650003A502E94036500ED003F500F9003E6064C +:1096600070000000000000001815E600F9E033501B +:109670000CDA03A600D9803F400F9103A600F988B9 +:109680003E680CDE036600ED003B690C9003C600EB +:1096900070000000000000003810E108B8E0202051 +:1096A000188E26E10080A02E004B8842E150B84081 +:1096B0002E2A0D0A022008B8002E140D8002CE04B6 +:1096C00030000000000000000805C500B160204027 +:1096D0000831A2C50091482C401B12028400B10041 +:1096E0002C500916020500A3042840081002C201EC +:1096F00070000000000000001805A400B9082070E8 +:10970000289002E40089002E400B9002E408B9037F +:109710002C402990026400B9002E62099002C60410 +:109720006000000000000000A005E500F9D0B27064 +:10973000089003E400D9043E400F9003A410F902FE +:109740003E400D902B6400E98D3A600C9003E804D4 +:1097500070000000000000002801A400F9803E42D3 +:109760000F9003E400F9003E400F9A03E400F90073 +:109770003E402F1003A400F9223C404F9003CA0042 +:1097800060000000000000002800A000F04032004F +:109790000C8003C000F80032201F8003E000C800E6 +:1097A00032000C80022000C8C03E000C8003CA04B6 +:1097B000200000000000000028152810BA0023A097 +:1097C0000AE402E800BA002BA10BA002E800AA00FC +:1097D0002A810AA003E808DE002E800AA002CA003F +:1097E000400000000000000028054C00B304A0B1B8 +:1097F000083622CC00B30020E40B3002CC008300FA +:1098000020C00818020C0091012CC0083006CA00C4 +:109810005000000000000000A0011CC8B32121C2BC +:109820002A7002DC00B7A029C00B7202CE00A7810B +:1098300029C04A7402FE0097012CC00A7012E80089 +:109840004000000000000000A8081E80F7C031E0C2 +:109850000C4803DE11F78021E00B7A03DE00C380A1 +:1098600033D86C78033E00D6803DE00C7803EA02E2 +:109870000000000000000000080DAC08FB803EC0A6 +:109880000FD003EC04FB3C3EC00FB6076C01FB009D +:109890003ED00F9407EC01EA003EC00FB003C206B1 +:1098A00060000000000000000001FE00CFA43B604B +:1098B00008D9037E00CF803F254FFC87BE00CF80B4 +:1098C0007FFC0CFC037C00F69033E00FF803C00033 +:1098D0007000000000000000A8119C088F282140A3 +:1098E00008D0021C40A72031041B7802DC80D7007E +:1098F0002FC41AD0021E48B60061C00B7006EA04DD +:10990000600000000000000000008C008730694407 +:109910000850220C0087012D448B70068C108700A4 +:1099200029C90850021C44A60061C00B7002C00087 +:1099300020000000000000002014CD00838860405B +:109940000010024C002B002C411B3002CC00930075 +:109950002CC00A30420C00B24020F10B3002C80487 +:109960003000000000000000A815BD41CFC0BAF0D3 +:1099700028901B6C08CF002CC00FF003AC008B00AC +:109980003FC06CB04B2C01FB4022C80FB003EA046F +:1099900060000000000000008000EC04FB043FD4E5 +:1099A0000F1003AC00FB0032C05FB003EC00FB04FF +:1099B0003EC04F1013EC00FB883EC04FB003E000E8 +:1099C00030000000000000000110DC00C70033621E +:1099D0000CC00B3C00EF0033E01CF0133C08F70018 +:1099E00031C00ED803BC00FE003DC60CF003C044DD +:1099F000300000000000000081046C00CB0322470F +:109A00000898422C009B002AC00AB0022C00BB041C +:109A10002AC00AB002AC08FA002E6008B002E0408A +:109A2000100000000000000080052C009B0020407A +:109A30000898022C00BB0022880830022C00BB00D2 +:109A400022C08A9202AC00AA802EC008B006E000B4 +:109A5000400000000000000008040C008300A0404B +:109A60000810020C00B30028800A32120C00B30464 +:109A700028C00A30228C20B2002CC0083002C2015B +:109A80000000000000000000000D6C02CB00304020 +:109A90001C94032C00EF0032C088F08B2C00FB00DC +:109AA00033C0AEF003AC80EA013EC02CB003C0036B +:109AB0005000000000000000A01DFC00FF002F402F +:109AC00007D283FC00DF043FC00FB003FC00FF009F +:109AD0003FC00FD00BEC00EE003F400FF003E80654 +:109AE0007000000000000000C005F500CF083F48EE +:109AF0000FC39370D0DC303FD80CB2033CC0FF40A2 +:109B000033C42CF1036250FC3433000F5C03F000CB +:109B100070000000000000008010C4808B002F5AED +:109B20000BA61221C089702FDC08F2C23DD0BF40C5 +:109B300037DC88F50A2080E8102A160B9002E00432 +:109B400030000000000000008805C00083082C449D +:109B50000B02020C0080002CC80833428C90B330FA +:109B600028C84A3212800CB0A028280B1202E20149 +:109B70007000000000000000C015A2008B002E48FD +:109B80000BA022202088802EC028B00AAC00BB0089 +:109B90002EC00AB002A000AB822AA00BB202F004D1 +:109BA00060000000000000004015E700CB003EC050 +:109BB000CF9C0B2100D8883EC00CB003AC00FB004A +:109BC0003AC00EB043E840F8803A600F9803D004E2 +:109BD0007000000000000000E001B400FF000FE092 +:109BE00007A103E802FB003FC00F70237C00FF02C7 +:109BF00035C04DB0037420FC013F000FF803F8009E +:109C000060000000000000004010A500CB00BA403A +:109C10000C140B2F22C94032C08EB003AC00FB00E5 +:109C20003EC00EB003E400C90032002C90031004C3 +:109C30002000000000000000C80124008F00224026 +:109C40002CA54229008B04A3C10DF00A3C00BF00E3 +:109C50003FC008F0016900DA0522D00894037200C1 +:109C60004000000000000000E0056040830120C0CB +:109C70000900022000826022C00830424C10BB0262 +:109C80002CC008B01205009B002082093202380067 +:109C9000500000000000000020011690878020E0A6 +:109CA0000858021614848121E02939025E00B78029 +:109CB00028E00878027A80968121E009F8024800BD +:109CC0004000000000000000480808098B103844DC +:109CD0004D25120C00C21022C80A3803CC00F31024 +:109CE0002CC00C30038AC0D91032402D1003120250 +:109CF0000000000000000000401DBC80FF003F404D +:109D00000FF003F440ED003FC00EF303BC04FF006E +:109D10003FC20FF00BD400FF10BF800EF003D0063F +:109D20006000000000000000A805FA00CB023EC061 +:109D30000F9003A000CB003ACA0CB313AF24CB485A +:109D40001EC80FB6032C00FA003EC00F9003EA00B5 +:109D5000700000000000000048119C0887202DC4FE +:109D60000B5012DC0487002CC00870A21D00A74015 +:109D700025CB8B74821C00B7002DC10B7002D2045E +:109D80006000000000000000C0009A0187902DE0F4 +:109D90000B7802CE0086802DE4297A029E8087A06F +:109DA0006DE80B78021E00B5802D600B7802F00084 +:109DB00020000000000000004814CD0083022CE0C9 +:109DC0000B3002CC0083E02CC00830020C00A30052 +:109DD00024C00BB0020E20B3082CC00B3002D204FA +:109DE0003000000000000000E815B882CA003EA85C +:109DF0000FE003F8028E803E800DA05BA800CA0031 +:109E00003E800FA0033B80FE422F800FA803FA0480 +:109E100060000000000000004800E020F8003E0064 +:109E20000F0603C000F8113E000F0003E000F80029 +:109E300036000F800BE000F8043E200F8103D200B3 +:109E400030000000000000000810E400F9003E406F +:109E50000C9A032440C9C03E404C90032400F900F2 +:109E600036400790032400C90432600F9003C204F7 +:109E7000300000000000000080046400B9022E40A1 +:109E80000A9202250289E02E409890022400B9002F +:109E900022400990020400D90022440B9C02E000F9 +:109EA000100000000000000018052C00B9002C4034 +:109EB000089002242889002C40689042240CB104A8 +:109EC00026400B900A2C8081002240CB9282C60053 +:109ED000400000000000000008040400B1202C48ED +:109EE0000A1202048081212C4C0811020408B110CE +:109EF000204C09120224019120A0480B1002C2013B +:109F00000000000000000000B80D41E0F8503E14D1 +:109F10000C85032140C8503E1008068301F0F86804 +:109F200036100F05032940C85032940F8503EE0305 +:109F30005000000000000000981DF400F9103F449C +:109F40000FD10BF440FD122E4C03920BE400F920CC +:109F50003E4C0F9103FC00FD103F440FD003E6067A +:109F600070000000000000001805F620C9013E4006 +:109F70000FD0033C00BD0032630C9E432700E9C0B4 +:109F80003E680C98033400F9103F400FD003C60020 +:109F900070000000000000003810C220D8002E0021 +:109FA0000B80522804B8002238088803620088F029 +:109FB0002E3A488F0A2000B0802E000B8002CE047B +:109FC00030000000000000000805C48081002C4023 +:109FD0000B10020400B10020424814420580A12069 +:109FE0002C440810820400B1202C400B1002C20146 +:109FF00070000000000000001815A50199002E4017 +:10A000000B90022440BB0122410890122400A900B9 +:10A010002C400810402408B9406E500B9202C60430 +:10A020006000000000000000A015E714C9053E41D3 +:10A030000F900B2404F908B2402C900A2400E90088 +:10A040003E402C90032700F9803E600F9003E80407 +:10A05000700000000000000028018488F9003E48DC +:10A060000F9903E600F9023C40AF1003E412D90453 +:10A070003E400F9003E500F9C03E640F9083CA0094 +:10A0800060000000000000002810A100C8003E0091 +:10A090000F80032100C840B2000C80032010C800CC +:10A0A00032000C8003E080F80432002C800B0A049C +:10A0B000200000000000000028052800CA002E80B3 +:10A0C0000BE80A38108EC022800DA00228000A0476 +:10A0D000028028A002FB00BA0037B048EA020A005A +:10A0E000400000000000000028054C0093012CC037 +:10A0F0008BB0420C909B2020C04830422C00830043 +:10A1000020C0083002CD40B30024C80838020A003D +:10A110005000000000000000A001140087002DC0C6 +:10A120000B24061600930821C80931020C8087A071 +:10A1300021C0187202DC00B7B424E30878022800BA +:10A140004000000000000000A8081E0297A03DF09B +:10A150000F48033E00D68030E02C7A021E82C3F006 +:10A1600033EC0C7C03D600F78035E00CD8032A02D0 +:10A1700000000000000000000819A5A0FB003ECA76 +:10A180000F8003EC02EA003EC60FB40BED40FB006B +:10A19000BEC00FB643E000FB023E800F9003C20634 +:10A1A00060000000000000000005FE02CF883FE0D4 +:10A1B0000CB903FE00DD8133E08CFC033F04CF804B +:10A1C00033E24FFC033E00CFC033640CF803C00001 +:10A1D0007000000000000000A811944087002FC10B +:10A1E0000D69A2D040BC0023C008F0029C0087008B +:10A1F00021C00B700A3C048710214C086002EA045D +:10A20000600000000000000000009E0087002DC0DC +:10A21000096202D800970021C40870020C40970020 +:10A2200021C40B30025800A7082180086082C000BA +:10A2300020000000000000002014E42583002CC052 +:10A24000092202CC20B20020C028B0028C0093006A +:10A2500020C00B30426C20830820E208B802C804FA +:10A260003000000000000000A815A400CF003FC08F +:10A270000D9C03E800DB8033C00CF00B3C06DF00D4 +:10A28000B3C00BF0076800EF4032A80CA803EA0443 +:10A2900060000000000000008000EC00FB002EC009 +:10A2A0000F9403C540FA303EC00FB0036C00EB00C2 +:10A2B0003EC00F3013AD40FB023ED00FB403E000B0 +:10A2C00030000000000000000110E400C70031C1B0 +:10A2D0008CD0033400CD003DC00CF0017C00DB01CC +:10A2E0003DC04CF00B3002C30032000FD0030044DD +:10A2F000300000000000000081046E408B002AC086 +:10A30000288442228088803AC00DB002AC088B00BD +:10A310002EC008B00223208B0022308B8C022040FC +:10A320001000000000000000800524008B0022C007 +:10A330000838862A0089802AC008B002CC009B0019 +:10A340002EC008B04226008B0022710B8C02200028 +:10A35000400000000000000008040C00830028C03A +:10A360000832420000810028C00930528C08830066 +:10A370002CC018300600008300A0000B0002020170 +:10A380000000000000000000000D74028B0033C0CC +:10A390000C920B2002C8003BC00CF503FC00DF014F +:10A3A0003FC104F0332140CF0032000F800B000387 +:10A3B0005000000000000000A019FC00FF003FC09A +:10A3C0000FC403F0009C003BC00FF003FC00FF0033 +:10A3D0002FC00FF003F080FF003F000FC003E8061E +:10A3E0007000000000000000C005F0C0FFA0312494 +:10A3F0000EF0631004EF643FC04CF3031C80DF08D1 +:10A4000037C00FF003F0A0FC0031082CD203F0009D +:10A4100070000000000000008010E100BBC1224875 +:10A4200008FD022E0097002FC24871237E40BF0016 +:10A4300021C54BF502EF00BB4036E008A802E0045E +:10A4400030000000000000008805C584B311A2C9D7 +:10A450000A30020001B33028C40832420C00A308BD +:10A46000A0CA0A32828010B0412411083102E201F0 +:10A470007000000000000000C015A500BB0022E134 +:10A4800028B0022C809B002EC008B0026C00B300E4 +:10A4900022C00BB000EC20BB0026C0088002F004F4 +:10A4A00060000000000000004015E340F70432C0E7 +:10A4B0004EB0232E20EB001EC00CB0012C00FB0080 +:10A4C00036C01FB003E140FB0036980C9003D00467 +:10A4D0007000000000000000E001B604FF023FC071 +:10A4E0000FF003FE00EF023DC00FF023FC00FF0061 +:10A4F0003FC04FF003FC00F4003B400FA013F800F6 +:10A5000060000000000000004010AA20EB1036C0E0 +:10A510000DB007EC20DB0032C00CB0026C20EB0069 +:10A520003EC10DB003E020DBA032904CB00B100414 +:10A530002000000000000000C8052D008F8020C111 +:10A54000087012CF008F00A3C00DF0023C008F00F6 +:10A5500037C088F002EC00880020400880023200FA +:10A560004000000000000000E0054C00A3802481B2 +:10A57000093006CC40930028C108B002CF40A300A8 +:10A580002CC0093002CD00904060402810023800F5 +:10A59000500000000000000020010E00878023E032 +:10A5A000487902DE41978029E01978069E0087806D +:10A5B00025E0087802D203838021A0086802080001 +:10A5C000400000000000000048080C00A30034C058 +:10A5D0000D3042CC01D3103AC50C3903CC00E30452 +:10A5E0003CC40D3003CE00D00030400C30031202CA +:10A5F0000000000000000000401DBC00F7003FC04C +:10A600001FF053FC00EF0837D10FF0837C00F740B8 +:10A610003FC10FF103D000FF00BF840FC803D00675 +:10A620006000000000000000A805E000FB003EE024 +:10A630002CBE83EC00EB403EC00FB403ED20FB10BA +:10A64000B6D20FB483EC00DB8036C10C90212A0017 +:10A65000700000000000000048119400B7002FC0F7 +:10A660000836020C0887302DD98B7286DD00B320A6 +:10A6700021C80B7402D0028400A00028200212041A +:10A680006000000000000000C0009A00B7802DE0CC +:10A69000087A029D00A7A02DE00B78029E80A7807B +:10A6A00021E4087A269E18830421E008780A7000C5 +:10A6B00020000000000000004814CC00B3002CE093 +:10A6C0005830120E8283002CC00B3002CC01B30034 +:10A6D00020C10B3002C00888D2202008000252049A +:10A6E0003000000000000000E815B860FA003F826A +:10A6F0000CA003FA00AA001E808FA003E800F2005D +:10A7000032801FA003E800DA003688ACE0037A0448 +:10A7100060000000000000004800E100F8003E205A +:10A720004F8003E100F0003C000B8003E000F802E2 +:10A730003A000F8043F100FC0A3D000FC003920075 +:10A7400030000000000000000810E600C9903E4004 +:10A750000F9203E400D9003240049007E700F9109B +:10A7600030400C9043E409D98022402C100B0204A5 +:10A7700030000000000000008004646089C02E40AA +:10A780000B9826C58089002240289012E710B90056 +:10A790003640289012C583C980B640089002200038 +:10A7A00010000000000000001805040089402E4140 +:10A7B0004B9002E4009900A2400A9002E500B90023 +:10A7C000E241089042E4009D50AB4A08D0260600C2 +:10A7D00040000000000000000804048281202C508A +:10A7E0000B1002E400814020504A1432C400B140F2 +:10A7F0002451181412D40085402D4008500602013F +:10A800000000000000000000B80D6140C8003E00DC +:10A810000F8002E000D80032000A8002E010F80049 +:10A820003200048003E000D8003A000CC0032E037D +:10A830005000000000000000981DF440F9103F4156 +:10A840000F9403F500F9403E500D9403E510F940D4 +:10A850003E504F9403C500E94136500F9403E6067D +:10A8600070000000000000001805F600FDA83A4046 +:10A870000CD8233600E9A03E780F9E03B680CDE2C7 +:10A8800032680C9B0336824DA037688C9803060013 +:10A8900070000000000000003810EBA0B84020203D +:10A8A000088502215188C02E290B8E02E100D8E0D4 +:10A8B00022320D8D23614898D4A2102884020E0400 +:10A8C00030000000000000000805C500B3002A4A5F +:10A8D00028104EA408A16828440B1402C50081402A +:10A8E000A0500810020402912A204428144A0201B0 +:10A8F00070000000000000001815AC80B900224074 +:10A90000489006A400A9002E400B9022E400990074 +:10A9100022400910026402990022400890020604B5 +:10A920006000000000000000A015E400F9003858A5 +:10A930000C90538414A9043E400F9003E400C90016 +:10A9400032400C90032404D900B6404C900B2804EC +:10A9500070000000000000002801A400F9023E4938 +:10A960000F10436400D9003E400F9003C400F10271 +:10A970003E400F9003C402E9043C400F1C03CA0090 +:10A9800060000000000000002810A180C8203E00E8 +:10A990008C800B2000E8023E000F8003A082C800DC +:10A9A0006C000F80032010C80032020C80030A04E0 +:10A9B00020000000000000002805380086002E80DE +:10A9C00068A8803A008A002E800BA002F8008A0056 +:10A9D0002E800BA00A3A008E10238008A0030A00E4 +:10A9E000400000000000000028054D0083002CC03E +:10A9F0000838000C6023002CC00B3002CC408300D0 +:10AA00002CC00B30020C028A80A0E028300A4A00D9 +:10AA10005000000000000000A001162087022DC198 +:10AA20004870127C00A7202DC90B7200DC0087083B +:10AA30002DC41B32021D01874221C208700228006A +:10AA40004000000000000000A8083E02C7803DEC66 +:10AA50000C58031E00E7803DEC0F7F039600C78073 +:10AA60002DE20779030A06C38030208C38036A027E +:10AA70000000000000000000081DAC00FB003EC00C +:10AA80000F10438C00DB383ED80FB003CC04FB44DE +:10AA90003EC08FB613EC02FF023E000FB003C206A9 +:10AAA00060000000000000000005FA00FF8031E3B4 +:10AAB0000EF823FE02DF80B7E20EF8037E006DD0B1 +:10AAC00033E00CF89B76C0DF84B3E004F803C000E9 +:10AAD0007000000000000000A8119040B70221C4DF +:10AAE000087B42DC00870021C40B300010808D0001 +:10AAF00023C00DF20204428F0029C8287002EA0424 +:10AB0000600000000000000000009400B60023C0B8 +:10AB10000A72028C00870021C00A30020401A702D9 +:10AB200021C0087042008A870021C0287002C0003E +:10AB300020000000000000002014C500B000A0D0DC +:10AB400008B002C9428B0020C00B302204008300F1 +:10AB5000A0C0493002454093C0A8D4003502C804C3 +:10AB60003000000000000000A815AC00BB0031C0A0 +:10AB70000EB023CD00DF0037C00EF0016800E30007 +:10AB800033C01CF0034500DAC892D42CB403EA04A5 +:10AB900060000000000000008000E520FB003EC0D7 +:10ABA0000FB003EC00FB003EC04FB003AD00FB0054 +:10ABB0007EC01F3003A480E9203CC00F3203E000B8 +:10ABC00030000000000000000110DC00C70033C2AC +:10ABD0002CF0033E20DB0013C00C70033C80EF041C +:10ABE00073C10FF0223000C600B2C00CF003004465 +:10ABF0003000000000000000810069008B44A2C109 +:10AC000088B0036C008B0022C028B00A2D00BB0066 +:10AC100062C00BB00226028B8022C008B003204025 +:10AC20001000000000000000800528018A0822C0F2 +:10AC300008B2026C409B0028C048B0162904B90134 +:10AC400022C049B006AE098B8022E048B002200045 +:10AC5000400000000000000008040002820022C042 +:10AC600088B0024400830028C00830020800B10008 +:10AC700020C00B30028C00838020E008300A0201E3 +:10AC80000000000000000000000D6400CA0033C096 +:10AC90000CB2032C00DF003BC04CF5132C04EF007A +:10ACA000A3C00DF003A840CB00B2002CB0030003FA +:10ACB0005000000000000000A01DF000F4003FC0A4 +:10ACC0000FB103F000FF0037C00FF003FC00FF00DE +:10ACD0003FC007F00B7C08FF013F000FF003A80600 +:10ACE0007000000000000000C005F0C5ED333BCC53 +:10ACF0000CF0033040FF253FCC0CF3833CD0DF4801 +:10AD000037304CF303FD80CF2833D80CF1033000EB +:10AD100070000000000000008010ECD0BB3120CC9F +:10AD200088F3422050BF902FC40AF6027DC08F40A6 +:10AD300026408FF602FD00FF0839C808F602A0047D +:10AD400030000000000000008805C480A12028C950 +:10AD500008309A0009B3002CC02030024C908320A8 +:10AD600002080B3312CD80932024D808342222010C +:10AD70007000000000000000C011AE00BB1022C037 +:10AD800008B00226013B016EC008B0024C088B00DF +:10AD9000A2890BB002EC00AB006AC128B002B0047B +:10ADA000600000000000000040156E00E8C13AC0DD +:10ADB0002CB0432600FB063EC10CB00B2C02CB008E +:10ADC00034229FB043EC009B0236C18CB0031004C8 +:10ADD0007000000000000000E001BC00FC803DD0DD +:10ADE0002FF003FC00FB003DC0073003BC00EF0464 +:10ADF0003FE05EB001FC00FF001BC00FF003F80055 +:10AE000060000000000000004010AC00CB013EC913 +:10AE10000CB0172084EB00B2C10DB0036C00C3006E +:10AE200032500FB0030C40C3007EC00C300310043E +:10AE30002000000000000000C8052C008A582EE009 +:10AE400048F0022D00EF0123C008F0223C048F607F +:10AE500036540BF00A3D408F002FC008F0037200FB +:10AE60004000000000000000E005400089802C1038 +:10AE700008B0024900A3A024C00930024C0083C9D5 +:10AE800020904230124D0083006AC0093002380021 +:10AE900050000000000000002001160085806D6257 +:10AEA000087E025640278025E01978060E00838030 +:10AEB00061A00B78024E0087826DE009790248009C +:10AEC000400000000000000048082C02C3613C88DC +:10AED0002CBA124910E32C36C00D30534C44C30039 +:10AEE00020010F31034C00C3013CC02DB1031202FD +:10AEF0000000000000000000401DBC00FF003F00FB +:10AF00004FF109B000FF003BC00EF401FD24FF40EB +:10AF1000BFC007F003BC006F103FC41EF183D00612 +:10AF20006000000000000000A805C400E804320032 +:10AF30000CB603E802CB0036CA0FB503AD00FB2008 +:10AF40003E400FB303EC80FBA832C68CB6032A0048 +:10AF5000700000000000000048119402E60020008C +:10AF6000087302DC0087702DD00BF0021C84B72020 +:10AF70002DC00B7082DD24B74034C9287282920440 +:10AF80006000000000000000C000BE02AC80A120F4 +:10AF9000087900CE04878065E00B7A029E00B790A6 +:10AFA0006DA00B7802DE00B78021E0087802300047 +:10AFB00020000000000000004814ED82ABE020E417 +:10AFC000083002EE0483002CC11B30020C08B300D1 +:10AFD00064F60BB002CC04B30026C0083002920421 +:10AFE0003000000000000000E815BB80EE4931A0F1 +:10AFF0002CA003FA00CA0236800FA003A800FA02B0 +:10B000003F900FA063E800FA0032800CA0233A04BE +:10B0100060000000000000004800E00AE8003E0870 +:10B020000F8003E350F0003E000F8013E000F800B3 +:10B030003E000F8003E001F8017E000F8003D20084 +:10B0400030000000000000000810E440C9A13240B8 +:10B05000201101A640C98436400D900344004100F0 +:10B0600032400F900B2400F9003E404C10030204C4 +:10B070003000000000000000800464008982A240CB +:10B08000089C02250089C82240089042240089209B +:10B0900022600B90022410B9002E4008900360003B +:10B0A000100000000000000018052400890422CAD6 +:10B0B0000A900A2502892020402810026401A90074 +:10B0C000224B0B90022401B9002E41289002060069 +:10B0D00040000000000000000804049081A0204807 +:10B0E0000A320204808100204408110204D0A12009 +:10B0F00020400B11020600B1312C48081402420115 +:10B100000000000000000000B80D6142C854321475 +:10B110000E85032144C828B21A4C86936114E85066 +:10B1200022140F86832140F0401E140C00032E03CE +:10B130005000000000000000981D7444F5103F44CA +:10B140000D91037440F9003E480B9203E4C2D910FC +:10B15000BF400F9203E504F9303E440F9443E606E6 +:10B1600070000000000000001805F622CDA1336138 +:10B170000CD8D33410CDA83E608E9C93A708CD8008 +:10B1800033400E9AD336A0C98032600C9903060072 +:10B1900070000000000000003810E3888AA020281A +:10B1A000088022201288402C28088A022200880069 +:10B1B00022000B8C03210088D0A23E288D020E04B1 +:10B1C00030000000000000000805CE20A1482052F9 +:10B1D000291002240381002C520A1012851091407C +:10B1E000A4400A128244009128244028120202013D +:10B1F00070000000000000001815A400A9142240EF +:10B20000099002A40189042C4008900224009900AE +:10B2100022444B10422414990026400810020604D0 +:10B220006000000000000000A015E440E940B27892 +:10B230000D900B2422C9033E410E9003A402D900B5 +:10B24000165806900B6402D90036400C900B280467 +:10B25000700000000000000028018400D9803E4AF0 +:10B260000E90036420F9083E410F9003E400E108CA +:10B270003E400F9003C400E10038400F9003CA0025 +:10B2800060000000000000002810A009F040B0108D +:10B290004C000B2000F8003A001C0003E000C8003E +:10B2A00036000C80032000C80032000F80030A041F +:10B2B0002000000000000000280528003E8823A28E +:10B2C00048E0001980BE882E800DA042E8008E0064 +:10B2D000239008A00A3A00DA0036800BA00A0A0080 +:10B2E000400000000000000028054C00B38020E072 +:10B2F0002830C20F10B34028C00B3002EC1183403D +:10B3000028D20A30020CC0830020C00B30020A0091 +:10B310005000000000000000A0011C00B60021C089 +:10B320000820C21C10B5002DC80A7202DC40850836 +:10B3300029A21A72220C00933005C40B3222280075 +:10B340004000000000000000A8081600B280312074 +:10B350000C58031E00F78039F80B7C22CE40CF80BA +:10B360009B602E3B031A00C7A811E00F78032A0246 +:10B370000000000000000000081DA400FA003EC00C +:10B380000F9023E800FB003ED02DB603ED02F9003C +:10B3900032400DB007EC00FB603EC80FB503C2069B +:10B3A00060000000000000000005FE00FF8033A0E8 +:10B3B0000CF80B3240CE8137F00CBC03FE00FF844A +:10B3C00033E02CF883E602CF8533F00CFC03001445 +:10B3D0007000000000000000A8119C00BE0035C6EF +:10B3E0002830023040870023C0087A02DC00BE000B +:10B3F00023C0087012FE00870021C008F0022A0452 +:10B40000600000000000000000009520B6002080D1 +:10B410000831025C01870025C0087202DC00B6001A +:10B4200021D0097002D408930020C00870020000E7 +:10B4300020000000000000002014C400B0E02460E0 +:10B440000820064801800020C0083002CC04B30068 +:10B4500020840B3002E8009B0020C0083002080462 +:10B460003000000000000000A815AC00B9E03280F8 +:10B470006CB0236F00C30037C13CF003FC00FA003E +:10B48000B0C009F003EC10DF0073C00CF00B2A0011 +:10B4900060000000000000008000EC10F8003E4258 +:10B4A0000F2403A860F8003CC10FB003EC00F94082 +:10B4B0003E8004B023E100EB003EC00FB003E0008B +:10B4C00030000000000000000110F400EE003D30EC +:10B4D0000CC0031400CCA0B3C04C70035C10DF00A0 +:10B4E0003F000CF003F800CF0023C00CF003004035 +:10B4F000300000000000000081046400BA812E5872 +:10B500000888022780892022C028B0022C00888366 +:10B510002E2005B062E3008B002AC008B003604013 +:10B52000100000000000000080052600B9812E40B8 +:10B53000088C062600880022C008B0166C00988887 +:10B540002E2008B004E3010B0028C00830022000C0 +:10B55000400000000000000008040400B0002CC0FF +:10B5600028000E0010800020C00832020C00800469 +:10B570002E20093002C412830028C0083002420184 +:10B580000000000000000000000D6C00FA003E000A +:10B590002C910320008A0033C00CF0037C00D800FB +:10B5A0002E400CF003E080CF003BC00CF003000302 +:10B5B0005000000000000000A01DFC00FC013F4006 +:10B5C0000FC013F000F4003FC10FF423FC08FC008F +:10B5D0003F000FF003F040FF003FC00FF003E8060C +:10B5E0007000000000000000C005FC20CD1039C82C +:10B5F0000DC1033C80EF9023D80FF800FE00CF80F0 +:10B600001FD00FF903FF00E7C033C40FF003B000F1 +:10B610007000000000000000C010FE02894023F00E +:10B620000885103C008B00A3DC4BB282EC208B0021 +:10B6300026C04BB002EC10B9042AC90BB580F00447 +:10B640003000000000000000C805CC00816428C460 +:10B6500009B20A0CF0A32020C80B3202EC028308C6 +:10B660002CC8093202CC80ABA020C80B3200B2013A +:10B670007000000000000000C015AC10890022C05E +:10B6800008B2122C020B0022C00BB802EC008B0097 +:10B6900026C04BB046EC00B9000AC00BB002F00463 +:10B6A0006000000000000000D015EC10C9E03AC0B6 +:10B6B0000D28032C00EB1032C00F8203C400CB0016 +:10B6C0003EC10FB006EC08E900B2C00FB013900401 +:10B6D0007000000000000000E0019C00F5A03FC0E9 +:10B6E0000FE803FC08FF003FC08FC003FC00FF0011 +:10B6F00037C00FF003FC00FF043EC00FF003F8005A +:10B7000060000000000000005010AC00F94034C0A0 +:10B710000DB4032C00DB403EC02C80036408FB10FA +:10B720003EC68FB003EC00F98032C00CB00B14049D +:10B730002000000000000000C8053E20E9C837D402 +:10B7400048AA221C008B006FE0088582ED40BB8474 +:10B750002FC04BB803AD40B30023D408F70232002A +:10B760004000000000000000E0014C00B164A4C0F3 +:10B7700009200A0C04B8006CC0083802C840B38025 +:10B780002CD10B3002CC04B30028C00830023A00A0 +:10B790005000000000000000B0011E00A58025E060 +:10B7A000883A121E00A6902DE2087902DA00B782CC +:10B7B0002DE00378829E00BCC129E00878022C109D +:10B7C000400000000000000049080C00F30034C0F5 +:10B7D0000D3E030C00F0402EC00C3043C800F300B7 +:10B7E0003CC0073003CC80F20038C00C300312029A +:10B7F00000000000000000004019BD20F7003FC21B +:10B800000FF10BDC20DE043FD207F013F840FF00FD +:10B810003FC007F003FC00FD0037C00F7003D006E7 +:10B820006000000000000000AA05CF00DC003ECA56 +:10B830000FA000AC92C90032C00FB011A408FB00E9 +:10B840002EC04FB023EC00F9003EC40FB003EA0055 +:10B850007000000000000000C8919C00840001C03E +:10B860004B70221CC0870021C04B70021C00B70126 +:10B8700025D80B7022DC00B6002DC00B7222F2041A +:10B88000600000000000000080009E809780A9E01A +:10B890000BF802CE08858029E80BFC021700B78060 +:10B8A0002DE08B7802DE00B4C02DE80B7902E000B9 +:10B8B00020000000000000004814CC008308A0C055 +:10B8C0008B3C024C008300A0C01B3C0A0F29B30034 +:10B8D00024C00B3002CC00B3802CC00B3002D20449 +:10B8E0003000000000000000E815A800DE003A80EB +:10B8F0000FEA02E800CE003A800FE0033800FA00B9 +:10B900003E800FA003E800FE003E800BA003FA0477 +:10B9100060000000000000004800E000F804BA01E8 +:10B920000F820B8004F8803E000F86036000F80051 +:10B9300036000F8023E100F8003E000F8003D200A4 +:10B9400030000000000000000810E401F90032405F +:10B950000F9003E400490032400B9003240049009B +:10B960003C400D9003E408C9003E600C90030204C3 +:10B97000300000000000000080046400B940A264B0 +:10B980000B18022500D15036504E900A24028940EF +:10B990003A51089402E52289442E6028900A20003A +:10B9A000100000000000000018012400B10822402F +:10B9B0004B9282A500A90822500A10020C00A9404F +:10B9C0006E500B9402C40489446C488810024600EF +:10B9D000400000000000000000040400B140E0400E +:10B9E0001B140A0400B90024401A10220400A1000C +:10B9F00028400A1012C40081026C40081202420161 +:10BA00000000000000000000B80D6008B000320027 +:10BA10004F8002A150E05032140EA5232140E8507F +:10BA20003E140F8503E140C8501E140C85436E037D +:10BA30005000000000000000D819E500FD403E5015 +:10BA40000F7403A5005D003E500A5013F400D900A6 +:10BA50003A500D9013E400FF003E500F9103A606EC +:10BA600070000000000000001805F690BDE8236B90 +:10BA70000BDA0B3680C9003268469043E400490077 +:10BA800032680C90032440F90032600C9C03C6011C +:10BA900060000000000000007810E100B8E0A21192 +:10BAA0000B8E0A232288802A31288802620088802F +:10BAB000A23028888A2200B8A8A23908CA02CE0477 +:10BAC00030000000000000004805C50821000040CB +:10BAD0000314828580AD0821529850823423850852 +:10BAE00021520850065400B520215A095402D201AF +:10BAF00030000000000000001811A400B9612240CD +:10BB00000B90060400AD00694008D0027400850067 +:10BB100001400070067404B500234009D002C60439 +:10BB20006000000000000000A014A400E900324002 +:10BB30004F950BA400E90032408C90032400C9000B +:10BB400032400C90036408F90032403D9003E80451 +:10BB500070000000000000006801A408F9003E40E9 +:10BB60004F908BE404D9013E400D90036400D9014D +:10BB70003E400F9003A400F9003C400E9003DA0011 +:10BB800060000000000000002810A000F8403620EF +:10BB90001784032021C8007E022C80432000E80285 +:10BBA0003E010F8003E000C8401E000F8003CA045E +:10BBB000200000000000000028052A88B60223A00B +:10BBC0000BEC422B00D2806EB108A0220800EA04E0 +:10BBD0003A809FA003A8008A042E800BA802CA0006 +:10BBE000400000000000000028054C00B200A4E165 +:10BBF0008BB432474583902CF44B38120E44A3018A +:10BC00002CC04B3002CE0093006CC00B3802CA002F +:10BC10005000000000000000A0011C00B74421C239 +:10BC20000B5402540587002C409B6C021810A7048B +:10BC300029C00A70029B0097040D800B6082E80007 +:10BC40004000000000000000A8081E00F38035E05E +:10BC50000B3802521084802DA00FF80B1E00E680D6 +:10BC60001DA00B6803FE02D6803DE00F7803EA02B8 +:10BC700000000000000000000A1DAC00FB003EC1F7 +:10BC80008B900B800AB8012E000CB003E800FA007C +:10BC90003EC00FA043EC00EB003E800FA623C20283 +:10BCA00060000000000000000005FE00FE80332060 +:10BCB0004EC912F650EF903FE00C1900B642CF216A +:10BCC0003FE00EF902E6C0FF803FE04CDC0340009D +:10BCD0007000000000000000AA119400B70081402D +:10BCE00008030214C487012DC8086A12384087026D +:10BCF0002DC0087112D280B7002D800860022A047E +:10BD0000600000000000000000009C00B7102180CF +:10BD100008F4129404A6002CC018D202144886100D +:10BD20002D800A6132D400B6182DC40858020010C4 +:10BD300020000000000000002014C400B30020C058 +:10BD400040B022040082810CC008300A0A008A0038 +:10BD50002EC008A002C400BB002E800820020804E8 +:10BD60003000000000000000A815AC00FB00A0C0DF +:10BD7000249423AC10EBA00EC00CB0022E20C900FE +:10BD80002E400E9003EC00F9803E406CA00B2A047C +:10BD900060000000000000008000CC00FB003EC0FE +:10BDA0008990032C00FB023E404FA0036D01FB4134 +:10BDB0003EC08FB403E800FB203E500FA403E00018 +:10BDC00030000000000000000110FC00C320B2C0E1 +:10BDD0000DD0033800CD003F800DF003FC00FD02C4 +:10BDE00036000CD0033F08FC0412C00CA003C04472 +:10BDF000300000000000000080046C028BC822C0EC +:10BE000008980A2A4089202E018EB012EC80BBF0DF +:10BE100022E508BD022E00BB9022ED08A202E00040 +:10BE2000100000000000000080052C008B012200A3 +:10BE300049A81E04008B012EC0499002E400B900FD +:10BE400022400A90022C00B9002A40088002E0003B +:10BE500040000000000000000804040081002040B1 +:10BE6000082002040083002CC00A2042CC00B3004A +:10BE700020C00230020884B3040840082002C21126 +:10BE80000000000000000000000D6C008B00B2807C +:10BE90000DB1032402CB013EC04D9043E400F900F4 +:10BEA000B2002E900B2C80F800BAC02C8003C00387 +:10BEB0005000000000000000A01DF4007D003FC005 +:10BEC0000F7203D400FF003FC00EF147FC00FF00DB +:10BED0003BC00DF013FC50FF0037C00FE003E80635 +:10BEE0007000000000000000C005F0C4CC333F0427 +:10BEF0002CF6033860CC90B3200FF123F060FF01E3 +:10BF000023C80CF28A3C81DF303F640CD803300434 +:10BF100070000000000000008010E0C28A302E187F +:10BF200008F530A594582222214BF302E1009F70BE +:10BF30002BE40AF4121D40AF722C492F3082A00668 +:10BF400030000000000000008805C48080A02C980C +:10BF5000083222080082002800033202C084B30C99 +:10BF600020C05832928C30A3202EC0481242620169 +:10BF70007000000000000000C015A8008B002E20FB +:10BF800008B00A200198002A220BB002E6009B00AC +:10BF900022C00AB012AC04AB002EC003B002F00005 +:10BFA00060000000000000000015E500C8003EB081 +:10BFB0000CB0032900C8003A204FB003E220FB0177 +:10BFC000B0C00CB0032C00FB023C410C9043480471 +:10BFD0007000000000000000E001A280FE403E0072 +:10BFE0000FF063EC00BFC417420FF003EC00FF003A +:10BFF0001FC10FB0035C00FB003F404FF000B800D2 +:10C0000060000000000000004010A502C8003E9043 +:10C010002CB00B0106CB013E505FB0132110CB00BA +:10C020007EC00CB00B2C00CB0032C00C900310046F +:10C030002000000000000000C80528018BD02C342F +:10C0400048FF023000AA042E690FF0036810DF00D9 +:10C050002FD40DF0023E005F04B6C008B00372009A +:10C060004000000000000000E005699081802C0085 +:10C0700048B802080999004CB00B30020C008B0044 +:10C080002CC009B0400C40830000400A90023000F0 +:10C0900050000000000000002001160084882DE4FC +:10C0A0004839021600B4802DE00A7B065E009780B6 +:10C0B0002DE20978021E90978025648A7802480054 +:10C0C000400000000000000048080D0081102C9680 +:10C0D0000831230C0090203CC41BB8020840C30068 +:10C0E0002CC40D30030E40C31030C04E10071A127E +:10C0F0000000000000000000401DBC007D053FC5A1 +:10C100000FB10BF400EF001F450FF043FC01FF409F +:10C110003DC41FF006FC10FF003BC12DF103D0060B +:10C120006000000000000000A805EC04CB043EA065 +:10C1300044B6032804CB8032800FB3936008FB2001 +:10C140003ED21FB3032D80FB617E408C98032A00F2 +:10C1500070000000000000004811840C86052DC00E +:10C1600008F4828C908500A1C00BF0025C003700BF +:10C170002DD00B71021CC8B7482D400A7002120462 +:10C180006000000000000000C0009E0087802DA11C +:10C1900060784A16D0A78029E00B78529601B790B4 +:10C1A0002DE80B7A225E40B7A02FE14850223000E4 +:10C1B00020000000000000004814CC1083842CC034 +:10C1C000083002A41083CB28E00B302A4F409300A4 +:10C1D0002CC00B30024C10B3022CC0AA3002120447 +:10C1E0003000000000000000E815B800CEA03F803D +:10C1F0004CA02B3A00CE403BB80FA003B900BA00C8 +:10C200003E800FA0036800FA007E801CA00B3A0459 +:10C2100060000000000000004800E002F8003E045A +:10C220008F0003E04AF81026180F8003A080F80260 +:10C230003E008F000BA000F8023E000F8013D200DA +:10C2400030000000000000000810E420C900324067 +:10C250004D99032400C9023E680F90022400E900B2 +:10C2600030408C90030440C9003E400C900302040F +:10C270003000000000000000800464208906225085 +:10C280008B9CC22400D9012E400B90422408B90196 +:10C2900022460D900A260289002C400A1002200036 +:10C2A00010000000000000001801060091404270DC +:10C2B0000B90122C028B002E400B1022E410B100C8 +:10C2C000A240489012240899022E400890020600CD +:10C2D0004000000000000000080404929120E048A3 +:10C2E0000B1202040291102CC00B100684C0B11076 +:10C2F0002048891102058091402E442A94020201AF +:10C300000000000000000000B80D6140D85030145B +:10C310000F850B21E080403E000F878BE10CF86C0D +:10C3200032008406832004D8283E100C00032E031C +:10C330005000000000000000981DF440AD103F4583 +:10C340000F9103FC187D201F410F900374C0F92149 +:10C350003E440F9201E440E9003D484FD003E60619 +:10C3600070000000000000001805F780FDE0337049 +:10C370000CDA032620C94031400E9A032400F980CC +:10C380003B600F9C8336A0F9A1B0400F9103C6001B +:10C3900070000000000000003810E290B8A02228D1 +:10C3A00028880A220288A02200088802C280B88851 +:10C3B00022040B8E032280B8D02A200B8802CE04E0 +:10C3C00030000000000000000805C580B161005881 +:10C3D00048168A04A0890122401A14880420B1401A +:10C3E00028400B100A0420B12C204A0B1202C20173 +:10C3F00070000000000000001815A590BB40204010 +:10C40000089002244089426258081002E500B903EE +:10C4100022C00B9002A41431002A440B9002C604DF +:10C420006000000000000000A010A500F9013240EB +:10C430008C90032700C19430400E90032400F90033 +:10C440003A400F90032400F9003260079027E80576 +:10C4500020000000000000002800A418F900BE44DD +:10C460000F9003C400F900BE618F9003A400F10097 +:10C470001E400F10032408F9007E400F9003CA00ED +:10C4800020000000000000002810A181F800320404 +:10C490000C00D32100D8043A149C80032101C80069 +:10C4A00036000C80132010C80032002C8003CA0410 +:10C4B000200000000000000028043A00BE8423850C +:10C4C00008EC8368048A002F904DA0022801DA004E +:10C4D00023B00AA0022A08DA0122800FA002CA00B3 +:10C4E000000000000000000028054C00BBF020C048 +:10C4F000083C0A0C00930128C88930064C008302CE +:10C500002CF60830020400A30020C00A3002CA0042 +:10C51000500000000000000020011D11B300A0C069 +:10C520000850025C1087016D814932521EC387009A +:10C5300028E00A32261F00370023E00B7202C800F1 +:10C54000400000000000000028081200B7823120DF +:10C550000808370F08D7E03960197A0B5E0C83B2F0 +:10C560007DE00C7A0B3E02AFA0B1E00E7A03CA0266 +:10C570000000000000000000081DA010FB003EC0ED +:10C580006FB043EC11FB003E400FB503EC20FB50B5 +:10C5900036000FB543E5A1DB783EC00FB403C206F9 +:10C5A00060000000000000004005FE00FFA03FA06A +:10C5B0000DC9133E00CFD03DE802FF133E00CF82ED +:10C5C0003F600CFC233E10EF8033F20CFC83100024 +:10C5D0007000000000000000A8119C40B5012DD0A3 +:10C5E0000858021C4057102D5A283102BC019710E0 +:10C5F0002D000A70028404CF0029C00AF0022A0428 +:10C60000600000000000000000009000B72A2D82AA +:10C610000842223C0087110DCC8832021D00970091 +:10C620002CC40830021400A70023C0097082000047 +:10C6300020000000000000006014C020B0202C503A +:10C640000810022DC093E22C210830020E0893003E +:10C650002C400A30028C0093002AC00B30021804D0 +:10C660003000000000000000A815AC00F8C03E80BB +:10C670002CA00B3F00C7603ED00CF00B3C00CF005D +:10C680003E800CF00B2C00EF0033C10DF00B2A04A0 +:10C6900060000000000000008000EC40F3403E50CD +:10C6A0008EB403EC10FB003E090FB013EC42EB001C +:10C6B0003C008FB013C411E3003EC00EB003E00095 +:10C6C00030000000000000000110FC00FC8031225E +:10C6D0000CA8033C00CF0033A00EF003DC00CF0019 +:10C6E0001FF00CF003F400CF0233C00CF002005432 +:10C6F000300000000000000081046F00BBC0227009 +:10C700000AB9422C108B00761183B002EC10AB00FA +:10C710002EB00AB003EC048B00A2C028B002204067 +:10C72000100000000000000080056540B820224491 +:10C7300058340A2C008B0022844BB002EC008B0092 +:10C740006EC008B042E6048B0002C0083002A001AF +:10C7500040000000000000000C000000B10020C0FC +:10C760000A300A0C008B0324800B3002CC00A3009B +:10C770006C000A30028D00830020C0183002820055 +:10C78000000000000000000000086400F800300015 +:10C790004CA00B2C02CF0022400EF503FC00CF0171 +:10C7A0003E000CF012DD02CF0233C04CF00B8003D0 +:10C7B0001000000000000000A419F000FC003F4041 +:10C7C0000FB103DC00BF013F000FF223FC10FF009C +:10C7D0003F000FF001F484FF003DC04FF0136806E6 +:10C7E0007000000000000000C005FE40DF8033C87C +:10C7F0000CF8033C0A9FC03FF008B8023E00FF80DF +:10C800003FD80CF9612E406F903FE48FF1833000E8 +:10C8100070000000000000008010EC048B8023F00A +:10C8200008B8023D40AB000E084822826C20BB00D5 +:10C830002FD048B0022C00BB002EC10BB002300438 +:10C8400030000000000000008805CC028301A0C574 +:10C8500008B04A4CA0802428C80932024C00B30812 +:10C860002ED129B23A0C84A3212CC84BB20A320132 +:10C870007000000000000000C015AC088B0022C052 +:10C8800008B0024C008821242109B0466C00BB0688 +:10C890002EC009B0022C10BB002EC00BB002300419 +:10C8A00060000000000000004015EC00CB0032C02A +:10C8B0000CB9026C00CBC83AC02D900B2C08FB00C1 +:10C8C0003EC00D30422C00EB003EC00FB013000400 +:10C8D0007000000000000000E001BC00EF003DC05F +:10C8E0000FF003BC06EF823F404EC983BC00FF003F +:10C8F0007FC01CF0137C00FF043FC00FF003F80062 +:10C9000060000000000000004010AC00FB023EC0D0 +:10C910000EB003AC20D8403EC08C900B2C00FB0026 +:10C920003EC90DB033EC08FB023EC00FB00B5404FF +:10C930002000000000000000C8052C00B3002FC03C +:10C940000B3012FC0088A02E402894022C10BB044F +:10C950002DC028B002EC00BB002EC00B72063200C6 +:10C960004000000000000000E0056C00B3002CE077 +:10C970000A1002CD0093002CC008B0024C00B30096 +:10C9800028C0083002CC00B3002CC00B30023A00A3 +:10C99000500000000000000020011E40B7802DE282 +:10C9A0000B5802DE0297812FA00868025E00B78153 +:10C9B0002FE0087902DE00B7812DE00B78023C0001 +:10C9C000400000000000000048080C00F3003CC0DC +:10C9D0000E3203CC80D3003CC40C39034C08F31A4C +:10C9E0003CC60D3003CE20F3083CC00F300352028A +:10C9F0000000000000000000401DAC00FB002EC045 +:10CA00000BB003CC20EB003C800FB041AC00FB002E +:10CA10003CC20FB003EC40FB003EC00F3003D00619 +:10CA20006000000000000000A805EE02C38030CEC8 +:10CA30000D9803ACA0C380B2C00FB003EC00FB00A4 +:10CA40003ED24FB0092E084B013EC024B003EA008D +:10CA5000700000000000000048119C00870121C008 +:10CA60004850124C00870035C04B6002DC04B7010F +:10CA70002DC00B70021C0087002DC10C7202F20445 +:10CA80006000000000000000C0009E00878023E0DE +:10CA900008F802DE808F8121E04B7812DE043780B7 +:10CAA0002DE80BF8023E1887802FE0097902E0009C +:10CAB00020000000000000004814CC008300A0C04B +:10CAC0002830424C00830024C00B3806CC04B3004D +:10CAD0002CC00B30020C0283002CC0083002D204A0 +:10CAE0003000000000000000E815A800CA003180F6 +:10CAF00008E0029802CE0033840BEA03E800BA0093 +:10CB00003F810FA0032800CA003E800DE003FA0415 +:10CB100060000000000000004800E000F8003E0057 +:10CB20000E8423A000F8003A100F8003E000F80004 +:10CB30003E100F8013E000F8003E000D8003D2008D +:10CB400030000000000000000810E401F9003E4041 +:10CB50000C9A13E400C9003E400C9823E480F900CD +:10CB60003E402C98036400F9003E400C9003C20440 +:10CB7000300000000000000080046404B9002E4072 +:10CB8000689C22E40289017C508D9822E480B920BF +:10CB90002E5048100B2500B9442C40289000E0008E +:10CBA000100000000000000018052400B9002E50FD +:10CBB000089002E40489002E500A9202E400B900B1 +:10CBC0002C400891022400B9002E40089002C600B3 +:10CBD000400000000000000008040500B1012C40E6 +:10CBE000483002E40081002A404B1002C400B1002A +:10CBF0000CC00890020C00B3002E40481202C20183 +:10CC00000000000000000000B80D6000B8013E0008 +:10CC10001C8007E150C8502E141E8503E141F850D6 +:10CC20003E140C85132148F8503E140C8543EE0346 +:10CC300050000000000000009819C400F9003E51A7 +:10CC40000F5003E500FD003F401DD003F410F90034 +:10CC50003E500F50009400F9003D400F9103E6064E +:10CC600070000000000000001801E450CD003160A9 +:10CC700004D0033680C1422E501F9403E500E90220 +:10CC80002E720A90220508E9403E50409C0326007F +:10CC900070000000000000003810C28288002215D9 +:10CCA000088002235888A02E280BAA42E28288809E +:10CCB0002E382888022280B8A03A2808CD020E0417 +:10CCC00030000000000000000805C4008100A640FC +:10CCD00028100A242695000D400B50027400850888 +:10CCE0002F4079D2AA1400A5012F4038500212011A +:10CCF00070000000000000001815A4048900264000 +:10CD000008910224109D082F400BD002F4008D02E0 +:10CD10002F4009D0003400BD000B401870020604FB +:10CD20006000000000000000A015C400C9053641E5 +:10CD30004C90632400D9003E400B90034408C90086 +:10CD40003E401510032400E9003C400C90032804E9 +:10CD500070000000000000002801A404F9003A401F +:10CD60004F9803E400E9993E404F9003E420F90A0C +:10CD70003E400E90436424F9083A420F908BDA004B +:10CD800060000000000000002810A000C800120091 +:10CD90000C8043E000C84032000F8453E010F800DC +:10CDA0003E000D80232000D8003E000F80030A04BF +:10CDB0002000000000000000280538028200A18841 +:10CDC000086022C8008A4036A10BA002E910BA44CC +:10CDD0002C800CA41229028A442E980BA4020A006B +:10CDE000400000000000000028054C10830020E0F7 +:10CDF000183092C408934020E00B3002CD00B340BD +:10CE00002CC00B3A42CD0083402CD00B38024A0094 +:10CE10005000000000000000A0411C00870021C05D +:10CE2000287002D1009D8025C24B6002DC08B70249 +:10CE30002CC00A7402FE0087002DC00B340268006B +:10CE40004000000000000000A8081E00C78431E078 +:10CE50000C6803D600978031A00F5813DE08F782C4 +:10CE60003DA00FF80BDE00C7803DE00F788B6A0213 +:10CE70000000000000000000081DAD80F3003EC16E +:10CE80000FA023C002E9003E810F8003EC00FB00ED +:10CE90003EC00DB0132C00EB003EC00FB003820269 +:10CEA00060000000000000000005FF32C780336012 +:10CEB0000F78033EC84E8023640CF8033A00CE80FE +:10CEC00013EC06D8033A00DE8033A40CC803D0006C +:10CED0007000000000000000A8119C00871001C035 +:10CEE0000B7002185084002B4408601298008613BF +:10CEF00021C4885002188086002180086102EA045B +:10CF0000600000000000000000009C00870021403D +:10CF10000BF1025C800600210088D0025C008700D3 +:10CF200020898AF1021C0887102181884802C600E6 +:10CF300020000000000000002014CC108304A0C1D9 +:10CF40000B300A480C88066038080442EC018B0458 +:10CF500022C108300A2C008B002280002002D80455 +:10CF60003000000000000000A815BC00C3002280B3 +:10CF70008F9003640ACB02B2F2203512640AC90012 +:10CF8000B2400EA003240AC900A2402CA003EE0464 +:10CF900060000000000000008000EC00FB003C800E +:10CFA0000F9003A500DB403ED04DB413A408FB0155 +:10CFB0003EC01CA0036C00FB043E504FA403E000E5 +:10CFC00030000000000000000110FC00FF0033C032 +:10CFD0000CE8432600DF80B3E00FF8037C00CD00AF +:10CFE00033040CE0233440CD0023400CE003E00484 +:10CFF000300000000000000081046C10BB00A2D2D1 +:10D0000008280204608B1922C60EB18A2E408B902C +:10D0100022C108A4822C008B90226448A402E00064 +:10D02000100000000000000080052C00BB00220062 +:10D0300008912E24009B0022C08BB012200488008F +:10D040002240081022200088012AD0088042E000F7 +:10D05000400000000000000008040C00B304208021 +:10D060000810060410830020C08BB012000082005C +:10D0700020C02810420906820028C0082002C201F0 +:10D080000000000000000000000D7C00BB003240EA +:10D090002CB0032400D30032C05FB5030C02C100E2 +:10D0A000B2000CB00B0500C100B8C02C8013E00327 +:10D0B0005000000000000000A01DDC00FF001FC0A9 +:10D0C00087F001F400FF003FC00E7043FC107F00AA +:10D0D0003FC00F7003FC00FF0037C00FE003E806FD +:10D0E0007000000000000000C005F184FE6131D82E +:10D0F0000CB2C3FCE0CC807BC00EF1037CE0CC839F +:10D100003F200FF0CB3244DC843F254CF24330000B +:10D1100070000000000000008010E448B01022DC25 +:10D1200008B602FD92888523F440F102ED00882DB7 +:10D130000E600BBC122C10A8822E000AFC22A00448 +:10D1400030000000000000008805C080B32228C025 +:10D15000083082CC0188002CC04A3202CC00010188 +:10D1600028004BB002A00080002C090834026201A4 +:10D170007000000000000000C015AC04B2102AC10D +:10D1800008B002EC10898022C008B002EC088800C8 +:10D190002E4083B002A040B9802C210AB002F004D6 +:10D1A00060000000000000004015EC00FA00BAC06A +:10D1B0002CB043EC00C0803EC08EB0034C0CC810B5 +:10D1C0003E808FB0038210D8823E280CB00B5004F2 +:10D1D0007000000000000000E001B680FD0237C1D1 +:10D1E0000FB003FC00FD003EC00FB053FC02FF0176 +:10D1F0002FA48BF0837C00AD022F40037003B80096 +:10D2000060000000000000004010AC00FB0432C0D1 +:10D210004CB0232C00F8403EC20CB0032C00FB4164 +:10D2200032C20FB0432D00C8503E400CB00B10046A +:10D230002000000000000000C8052F90B95003C076 +:10D2400018F01A3C00B9322DE038F0603C04F900C7 +:10D250003EF00B7C802C00D9C02E400DF002320035 +:10D260004000000000000000E0054B24B21002C1A5 +:10D270002830026C04B2C12CC00830000C00B2008F +:10D280002824033C0A000082C82CA0083002380081 +:10D29000500000000000000020011600B48021E4CE +:10D2A000487B025E00B6806DE24879221E40AC8465 +:10D2B0002DE00BFA00524096802DE8193802080044 +:10D2C000400000000000000048080840F310B0C40F +:10D2D000083A024C90F3103CCC0831030C49B040A2 +:10D2E00030050F3007214043013EC21C304312027B +:10D2F0000000000000000000400DBC10FC103FC505 +:10D300000FF101BC04FF043FC40FB14BFC64F700F4 +:10D3100037C00F7253AC44FF013FC90FF403D0066E +:10D320006000000000000000A805EC08FA003EE0E4 +:10D330000CB0032C00CB023ECA0FB2072E00DB025A +:10D3400032080F31032C00CB043E800C35032A0039 +:10D35000700000000000000048119400B5002DC8C6 +:10D3600008700A1C2287002DC90BF2829C80A6003F +:10D37000098B0B700A1C0285002D40087002920474 +:10D380006000000000000000C0009E00B7802CEC90 +:10D39000087B025E4085892DEC8B7B024E848F805A +:10D3A00025640BFA02120897806FE1087A023000B8 +:10D3B00020000000000000004814CC20B3642CC002 +:10D3C0000830060C10838A6CC05B3042CC00AB1076 +:10D3D0002CF20B30020D0093042CD508300A920475 +:10D3E0003000000000000000E815BB00FEC03E80D9 +:10D3F0002CA0036800C6403F800FA0026800CE4406 +:10D4000036904F60031B70DED83FA00C20033A0417 +:10D4100060000000000000004800E040F8103E00FE +:10D420000F8003A010F8423E101F8003A000E80CFC +:10D430003A041F8003E000E8457E022F8003D200FB +:10D44000300000000000000008106400E980324055 +:10D450000F900B0408D98036400F10132408F900F0 +:10D4600072700F91132410C9103E690C90030204CE +:10D47000300000000000000080046408B9802240F1 +:10D480000B1002240089C422520B90422400B900E0 +:10D4900022E00B90122404D94A2E60089003600009 +:10D4A000100000000000000018052400B118224000 +:10D4B0000B900224008B2026490B90026400B900D7 +:10D4C000A2400B908A24008B002C40A890020600FA +:10D4D000400000000000000008040484B120A048BF +:10D4E0000B11060400830000404B11020449B110E7 +:10D4F00028400B1002244191002C500810024201D8 +:10D500000000000000000000B80D6940E85032142F +:10D510000F869321E2C800360A0B868B61A8F8407B +:10D5200022800F82A32108C8023E000C80432E03F4 +:10D530005000000000000000981DF448FD123E4419 +:10D540000F1203C4007D011E400B9203E480F520FE +:10D5500036400F9003D4907D003D400F9403E606C3 +:10D5600070000000000000001801F6C1DD88327272 +:10D570000C98032622DD003F622C998346A0C94007 +:10D58000B2400FD8032400FD0033512CD88306008D +:10D5900070000000000000003810E3C288C0223094 +:10D5A000088C4222118A012E00088852230080A391 +:10D5B0002A004B804222A0B80022280884028E0450 +:10D5C00030000000000000000805C400812D204844 +:10D5D000681480042081002E400B12120424812044 +:10D5E00020400B94320490B900204048104A0201B8 +:10D5F00070000000000000001815A40089202240DF +:10D60000089012240089002E4008900224088940C6 +:10D6100022500BB0022420B909A2440890028604CB +:10D620006000000000000000A015E400D908B2402E +:10D630004C10230404D9C13E408F900B0408C14014 +:10D6400012400F90432404F14130780C90032804D9 +:10D65000700000000000000028018664F9803E4050 +:10D660000F900BE400F9983E402F1003A402F9102C +:10D670003E400F900BE640F9903E600F9003CA00C9 +:10D6800060000000000000002810A000C841320027 +:10D690000C80072010C8103E0C0E8003E004C80068 +:10D6A000BA000F81432000F8703E000F000B0A04FF +:10D6B0002000000000000000280539028E20A38011 +:10D6C00028E00A3810AE043DA18EE002F8008E007A +:10D6D00076800B60037800BE402F820BA003CA0047 +:10D6E000400000000000000028054D008B8822C08B +:10D6F0001830020C0083442CD01B3012CC0683005F +:10D7000020C10B30820C01B3002C400B30020A0008 +:10D710005000000000000000A0011C00850020CC8B +:10D720000870061C84A70129C00B7222DC80873494 +:10D7300061800B10025C00B7002DC00B7002E80086 +:10D740004000000000000000A8080E008C8031E0BE +:10D750000CFE023F00C5802DE00E7803DFA0C7A0BD +:10D7600021600F78031E80F7803DE00F78032A02C6 +:10D770000000000000000000081DAC00F9003EC0E1 +:10D780000FB003EC00FA003EC006B003EC80FB28AB +:10D7900036D84FA003EC10FA003E500F3003C206FB +:10D7A00060000000000000000005FA00CC80B3E03B +:10D7B0000FF8033E00CF903F604FF8C33E00EF806C +:10D7C00033F00C7A033E70C59033F10C78030000FF +:10D7D0007000000000000000A811B800870021C000 +:10D7E0000B704A1C0087102DC04B710A3C448F12ED +:10D7F00021860D72021E008700234008700A2A0449 +:10D80000600000000000000000009C00840025C0B3 +:10D810000B710A0C00A7122D840B700A1C00B708AC +:10D82000234009F31A5C869708254008700200001F +:10D8300020000000000000002014CC20812026C021 +:10D840000B30022C0082422C800B30220C089B8073 +:10D8500020E00920024D08920024E508300A08045F +:10D860003000000000000000A815AE82CAE0B7C07A +:10D870000FF0133C0AC9C83E400FF0033C04FF847C +:10D8800032C00D90137C00D900F6C02C10032A047E +:10D8900060000000000000008000E400F3003AC1D6 +:10D8A0004FB003EC00F9083C000F3013EC00EB0420 +:10D8B000BE180F9023AC60E9023A404F9003E0009D +:10D8C00030000000000000000110FC00CA0033C05E +:10D8D0000CF003FC00CD027F400CF0423C00CF086E +:10D8E00037100FD003FC10CD083F662CD90300443D +:10D8F0003000000000000000810463808BE022C043 +:10D9000008B022EC00D8806E2068B01A2C01FB0011 +:10D9100022180B88434C0088A02CC01D9002204088 +:10D920001000000000000000800108808B2022C051 +:10D9300008B022EC0088882E6248B01ACC008B0018 +:10D9400026C04A8802EC0008842E4009900220007C +:10D95000400000000000000008040000830060C0D8 +:10D96000083002CC0090066C000830028C00A30442 +:10D9700020008B00064C2180006CC049100A020177 +:10D980000000000000000000000D6C00CA00B2C1E1 +:10D9900088B403EC10C8002E000CB00BBC088F003C +:10D9A0003600068003EC80C8023FC10C90030003E0 +:10D9B0005000000000000000A01DF000FF003FC06C +:10D9C0000F7283FC18FC033F008F70037C00FF0084 +:10D9D0003D000FC0238C06FC003F400ED003E8063C +:10D9E000700000000000000000C541037040DC1022 +:10D9F00037040DC1037040DC1037040DC1017040C5 +:10DA00009C10171405C1037040DC1017040DC031C1 +:10DA1000000000000000000000C5440571015C40EA +:10DA2000571015C40521015C40571015C401710140 +:10DA30005C40171005C40571055C41571015C011F5 +:10DA400050000000000000000080020120804820FB +:10DA500012080482012080482012080482012080DC +:10DA600048201208048201208048201208048020E7 +:10DA7000000000000000000000800000600058006E +:10DA80001600058001600058001600058005600042 +:10DA900058001618018001600058005600058020CB +:10DAA000000000000000000000C5480522011C80A5 +:10DAB000472011C80472015C80572011C8047241CC +:10DAC0005C80572011C80472011C80472015C031AA +:10DAD000500000000000000000C540006000180079 +:10DAE0000600018000600018000600018000600050 +:10DAF0001800060001800060001800060001803157 +:10DB0000000000000000000000C548042201088059 +:10DB10004220108804220108804220108004230142 +:10DB20000880422010880422010800422010802131 +:10DB3000000000000000000000C54A05428150A01E +:10DB4000442C110B04428110E05428110200428140 +:10DB500010A04438110B0542811021142815003102 +:10DB6000500000000000000000800C01570054C06D +:10DB70001530044C01130054C01570054C015300BE +:10DB800054C01530854C01130054C0153005402198 +:10DB90004000000000000000008000004000100075 +:10DBA000040000400010001062040001080441005D +:10DBB0001000441811000010001080040001012022 +:10DBC0000000000000000000004560020800820024 +:10DBD00020800860021800820020800820000820B1 +:10DBE000820000808020021800820020800801311D +:10DBF000500000000000000000C54005640158000E +:10DC000056001580056001580056401580056001DA +:10DC100058005600158005600158007600158031C7 +:10DC2000000000000000000000C540036000D800B4 +:10DC300036000D80036000980036001D88056000E6 +:10DC4000D80016000D80036000D88046000D80319A +:10DC5000000000000000000000C5420430810C20DC +:10DC6000430810C20430810C22410818C2043089D4 +:10DC70000C20030810C20430810C20430810C0108F +:10DC800050000000000000000080000030000C0088 +:10DC9000030000C00030000C00030000C000300092 +:10DCA0000C00030000C00030000C00030000C001A5 +:10DCB00000000000000000000080020130804C20C5 +:10DCC000130804C20130804C20130804C3013080C3 +:10DCD0004C20130804C20130804C30130804C021CA +:10DCE000000000000000000000C5420560815820CF +:10DCF0005608118205608158205608118300608102 +:10DD0000582046081182046081183056081580306A +:10DD1000500000000000000000C5420020800820E4 +:10DD20000208008200208008200208008200308063 +:10DD300008200200008200208008200308008031B3 +:10DD4000000000000000000000C5420460811820AF +:10DD500046481192046081192046281182003481BE +:10DD60001820464811920460811820430811801140 +:10DD7000000000000000000000C5600458015600CB +:10DD80005580156004580116005580016004180183 +:10DD90005600458011600458011600418011403141 +:10DDA000500000000000000000800601418050602B +:10DDB00014180506014180506004180506004180D2 +:10DDC00010601418050601418050601418050020E9 +:10DDD0000000000000000000000002010080402060 +:10DDE0001048041201008041201008040201048040 +:10DDF00040205048041201008440201008040020F4 +:10DE0000000000000000000000C546035180D460FF +:10DE100030180D46035180D56035180D4603058036 +:10DE2000D46015180D46031180D46035180D4031AB +:10DE3000500000000000000000C5460571805C60D5 +:10DE4000971815C60571815C20571815C603708197 +:10DE50005C60571811C60531815C60771815C031B8 +:10DE60000000000000000000004546037180DC60F7 +:10DE700037180DC6037180DD60371805C60175813E +:10DE8000DC6037180DC60371845C60171819C01167 +:10DE900000000000000000000045460571815C6044 +:10DEA000571814860571815C60571805C6043181C6 +:10DEB0005C60571815C60571805C60431815C01169 +:10DEC00050000000000000000000020120804820F7 +:10DED0001208048201208048201208048201708008 +:10DEE000482012080482012080482017080480007E +:10DEF0000000000000000000000006016180586082 +:10DF0000161841860161801860063C058604618010 +:10DF10001860161801860061805860561815801028 +:10DF200000000000000000000045400570015C009A +:10DF3000570015C00470015C00570010C004700049 +:10DF40001C00470011C00470015C00470001C011B3 +:10DF500050000000000000000045420060801820D2 +:10DF60000608018200608018200608008200608098 +:10DF70001820060801820060801820060801801120 +:10DF8000400000000000000000054204208108203D +:10DF90004208108204208108204208118204208057 +:10DFA00008204208108204208108204208008011C5 +:10DFB00000000000000000000045420540815020A4 +:10DFC000540815020540811020540C154200408170 +:10DFD000502044081102054081102014080500114A +:10DFE00050000000000000000001030150C0543048 +:10DFF000150805420150C05430150C05430150C0AE +:10E000005430150C05420150C05430150C05401019 +:10E010000000000000000000000008004200108026 +:10E0200004200188006200108004001108004200F2 +:10E03000108004200108004201108004200100002B +:10E040000000000000000000004542020080802027 +:10E050002008080202208080202028000202008080 +:10E060008020200A080202008000202008080011F9 +:10E07000500000000000000000454005600158000D +:10E08000560005800560015808560015800760029B +:10E090005800564015800560031800760015801161 +:10E0A000000000000000000000C540036000D80030 +:10E0B00036000D80016000D80A36000D8005700919 +:10E0C000D80136000D80036000D80057000D800095 +:10E0D00000000000000000000000000430010C00FF +:10E0E000430010C00030010C00432010C004600148 +:10E0F0000C00434050C10430010C00460010C00029 +:10E1000000000000000000000000000030000C00D3 +:10E11000010000C00030000C00030000D00020000F +:10E120000C00034000C00030000D00020000C000E1 +:10E1300000000000000000000000050131404C50CC +:10E14000131004C40131404C50131404C511314163 +:10E150004C50131404C50131404C50131404C0003A +:10E1600000000000000000000000230568C15A30D4 +:10E17000568C11A30468C11A30568C11A30568C0CF +:10E180005A30468C11A30468C15A30168C15800091 +:10E190000000000000000000000000002000080057 +:10E1A00002000080002000080002200090002000F3 +:10E1B00008000240008000200009000200008000EA +:10E1C0000000000000000000000008446201188404 +:10E1D0004621118844621118844601118844621056 +:10E1E0001884462111884462111884062111800088 +:10E1F0000000000000000000000000455011540421 +:10E200005501114045501114004501114044500082 +:10E2100014044500154044501114045501114000E8 +:10E2200000000000000000000000082142085082A9 +:10E2300014208508214208508204208508214208C4 +:10E2400050821420050821420850821420850000C5 +:10E25000000000000000000000000A01028040A051 +:10E260001028040A01028040A01028400A01028000 +:10E2700040A01028440A01028040A0102804000099 +:10E28000000000000000000000000C035300D4C098 +:10E2900035300D4C015300D4C035100C4C035300E5 +:10E2A000D4C035300D4C035300D4C035300D400080 +:10E2B00000000000000000000000080572015C8002 +:10E2C000172005C80672015C80572015C80272012C +:10E2D0005C80572015C80572015C80372011C00092 +:10E2E00000000000000000000000231840C61231AA +:10E2F000848C21230848C61230840C61231048C244 +:10E300001231848C01230848C61231048C6100004C +:10E31000000000000000000000003FFF4FFFD3FF9F +:10E32000F4FFFD3FFF4FFFD3FFF4FFFD3FFF4FFF23 +:10E33000D3FFF4FFFD3FFF4FFFD3FFF4FFFD0000CD +:10E3400000000000000000000000000000000000CD +:10E3500000000000000000000000000000000000BD +:10E3600000000000000000000000000000000000AD +:10E37000000000000000000000002CDB0FB6C2CD42 +:10E38000B0B36C2CDB0B36C2DFB0B36C2CDB0B7E76 +:10E39000C2CDB0B7FD2CDB0B36C2CDB0B36C0000E4 +:10E3A00000000000000000000000333C4FCF13339A +:10E3B000C4CCF1333C4CCF133FC4CCF1333C4CFFC5 +:10E3C0001333C4CFFD333C4CCF1333C4CCF1000026 +:10E3D000000000000000000000003B7E4EDF93B70D +:10E3E000E4EC793B1E4EDF93BFE48DF93B784EFFA2 +:10E3F00093B7E4EDFD3B1E4EDF93B784EDF90000CB +:10E4000000000000000000000000010270409C10AD +:10E41000271C09C10130401C10670409C10270416A +:10E420009C11071401C10270409C50071C01C000E0 +:10E4300000000000000000000000040571015C40C5 +:10E44000571055C40131005C40571015C4057101C7 +:10E45000DC4017181DC40571055C4057101DC00035 +:10E4600000000000000000000000020120804820A1 +:10E4700012000482012080482012080482012080BA +:10E48000482012080482012080486012080480009D +:10E490000000000000000000000000006000180004 +:10E4A0000600418000600018004600018000600006 +:10E4B0001000061001800060001820461001800046 +:10E4C00000000000000000000000080472011C8031 +:10E4D000472011C80472011C80072011C804730072 +:10E4E0001C80472011CC0472011C80472011C00001 +:10E4F00000000000000000000000000060001800A4 +:10E5000006000184006000180006000180006040E1 +:10E510001800060401810060001800061401800044 +:10E520000000000000000000000008042201088034 +:10E530004270108C04220108C002201088042200BE +:10E540000880425010080422010900424010800057 +:10E55000000000000000000000002E044A8112A00C +:10E5600044A8112A044A8112A004A8112A044B804D +:10E5700012A04488012E044A811220049801000050 +:10E58000000000000000000008C00E00530014C08E +:10E590000530014C00530014E00530014C005300DD +:10E5A00004C00530004C00030014C00530004010CA +:10E5B000000000000000000008C00400400010003F +:10E5C0000458010400400010000400010000410054 +:10E5D00004004458104400000011800450104030E2 +:10E5E000000000000000000008C0400200008000A1 +:10E5F0002000080040000000002000080002000089 +:10E600008400000008400200008000200008403024 +:10E61000000000000000000008C040006001180079 +:10E6200046000180066001980046001180046001E8 +:10E630001800460011800420011800660011803087 +:10E640000000000000000000100140006000980081 +:10E6500026000980026001980006000C800260001C +:10E660001800060001800260009880060001820008 +:10E6700000000000000000004045420030810C20F6 +:10E68000430810C22430818C20030810C20420806B +:10E690000C20030818C20430810C20430818C01154 +:10E6A00050000000000000004000000030000C009E +:10E6B000030000C04030000C000300008000300068 +:10E6C0000C00032000C00030000C00032000C0003C +:10E6D00000000000000000004001021030800C200B +:10E6E000030800C20030800C20030800C201208013 +:10E6F0000C20032C00C20030800C30432C00C000E2 +:10E7000040000000000000004045420460811820E5 +:10E710004608118204608018204608118204608136 +:10E720001820460C11C20460811830460C11C0112B +:10E73000500000000000000040014200208008203E +:10E740000228008200208008200208008200208029 +:10E7500008200208018200208008200308018000B0 +:10E7600000000000000000005001420460811820F9 +:10E7700046281182046080182046081182046081B6 +:10E780001820460810820460811820430810800079 +:10E79000000000000000000040454004500114004B +:10E7A00045001140250000140045001140045001AF +:10E7B00014004500004004500140000100004211D7 +:10E7C000500000000000000048000600418010607A +:10E7D0000418010600418010600418010600418001 +:10E7E0001060041801060041801060041801000048 +:10E7F00000000000000000004800020500804021E9 +:10E80000100804000100804020100804020100806C +:10E810004020500814021100844020100814000009 +:10E820000000000000000000404546015180D46017 +:10E8300035180D46035180D46015180D46035180DC +:10E84000546015180D46035180D46035180D4011E1 +:10E8500050000000000000000001460471811C60AF +:10E86000451811D60471811C60671811C6047181A6 +:10E870009C60471811C60471811C60671811C000A4 +:10E8800000000000000000004005460271809C600E +:10E89000271809C60071809C60671809C60271803C +:10E8A0009C61271801C60271809C60071801C00096 +:10E8B00000000000000000005045460571815C60CA +:10E8C000571855D60171815C60571815C6057181BE +:10E8D0005C60571818C60571815C60431818821176 +:10E8E0005000000000000000400452012080482039 +:10E8F00012480490012080492012080482012480DB +:10E9000048201248009201208048201748048001C6 +:10E910000000000000000000400006006180186058 +:10E92000063C0186006180186046180186006180FF +:10E930001860061801860061801860461801800181 +:10E9400000000000000000000041600478011E008B +:10E95000478011E02478011E00078011E00478014F +:10E960001E00478011E00438011E00478011C011CD +:10E9700050000000000000004001120060801820DC +:10E980000648019200608019200608018200648018 +:10E9900018200648019300208018200648018000B6 +:10E9A0000000000000000000400142042081082017 +:10E9B000420810820420810820020810820420816D +:10E9C00008204208108A0460810820420810800054 +:10E9D000000000000000000040454204408110207B +:10E9E00044081102044081102004081102044081EF +:10E9F0001021440801020450811020040801001174 +:10EA000050000000000000004000030050C014301F +:10EA1000050C01430050C01430050C014300508028 +:10EA200014300508014A0050C014300508014000A8 +:10EA300000000000000000004000080042001080BC +:10EA40000420010800420010800420010800420058 +:10EA500010800420110000420010800420110010DA +:10EA6000400000000000000040454202008080207D +:10EA70002008080200008080202008080202008090 +:10EA80008020200808020200808020200808001151 +:10EA9000500000000000000040014000600118002C +:10EAA00046001180066001180046001180046001D4 +:10EAB00018004600118004600118006600118010E3 +:10EAC00000000000000000004001400264009800C7 +:10EAD0002600099006600198002640098002600027 +:10EAE0009800260000900260009800070001800056 +:10EAF00000000000000000004045600438050E00E2 +:10EB0000438010E04438010E00438010E0043801D7 +:10EB10000E00438018A00438010E004680188011B2 +:10EB200050000000000000005000010030400C10B8 +:10EB3000030400C50030400C10031400C100304035 +:10EB40000C10030400874030400C100204008000C9 +:10EB500000000000000000004004050035400C509B +:10EB6000031400D50431410C50035C00C500310092 +:10EB70000C50031000940031400C50431000C200B0 +:10EB800000000000000000004045430520C118308F +:10EB9000460C11970060C01830461C11830460C1F8 +:10EBA0001830520C11870460C11830460C118011C6 +:10EBB000500000000000000040010000214008005B +:10EBC00002000080002000080002000080002000F9 +:10EBD0000800020000800020000800020000800001 +:10EBE0000000000000000000400148442201188499 +:10EBF0004621119800621018844420118844621143 +:10EC00001884422111804462111884462111800029 +:10EC100000000000000000004045400450111404B2 +:10EC2000450011410050101400450111404450119D +:10EC30001404450101404450111404050101401120 +:10EC40005000000000000000400008204208108230 +:10EC50000420010820420810820420810820420874 +:10EC6000108204228108205208108A0422810000A8 +:10EC7000000000000000000000040A01028440A11E +:10EC80001028000A01028040A01028040A01028016 +:10EC900040A0102C140A00028040B0102C14000078 +:10ECA000000000000000000040454D035340D4D058 +:10ECB00035300C4D035340D4D035340D4D03534003 +:10ECC000D4D035340D4D021340D4D035340D40111D +:10ECD00050000000000000004001080472011C8088 +:10ECE000472015C80472011C80472011C804721106 +:10ECF0001C80472611C84472011C90672611C00071 +:10ED000000000000000000000000230840C612318F +:10ED1000848C01030848C61230840C61231848C251 +:10ED20001231848C01030848C61231048C010000A2 +:10ED3000000000000000000000003FFF4FFFD3FF75 +:10ED4000F4FFFD3FFF4FFFD3FFF4FFFD3FFF4FFFF9 +:10ED5000D3FFF4FFFD3FFF4FFFD3FFF4FFFD0000A3 +:10ED600000000000000000000000000000000000A3 +:10ED70000000000000000000000000000000000093 +:10ED80000000000000000000000000000000000083 +:10ED9000000000000000000000002DFB0FB6C2CDF7 +:10EDA000B0B7FD3FFB0B36C2DFB0FB6C2CDB0B7E3C +:10EDB000C2CDB0B7FD3FFB0B36C2CDF4B7FD0000AE +:10EDC0000000000000000000000033FC4FCF1333B0 +:10EDD000C4CFFD3FFC4CCF133FC4FCF1333C4CFF90 +:10EDE0001333C4CFFD3FFC4CCF1333F4CFFD0000F1 +:10EDF000000000000000000000003B7E4EDF93B7E3 +:10EE0000E4EDF93FFE4EDF93B7E4EDF93B7E4EC7EC +:10EE100093B7E4EC61231E4EDF93B784EC610000EE +:10EE20000000000000000000000000C524A14A24EA +:10EE3000630114024400810B2871021082403811D2 +:10EE4000410450081882873831C32C520A10000040 +:10EE5000000000000000000000000845128144800E +:10EE600071211C0A071A8102A0522014480712813E +:10EE7000C680602008884702014A80702010000088 +:10EE80000000000000000000000002C52C014A0044 +:10EE900052091C800724210808710210804520A116 +:10EEA0004928520114C0450091C4007202100000AC +:10EEB0000000000000000000000002072001C10067 +:10EEC0007109108007000101007008188007000117 +:10EED000892052010C8046308145046000100000FA +:10EEE0000000000000000000000008C202200088AE +:10EEF00020220008C22280408802220008820AA044 +:10EF00000CA802220008800A00808C022200000067 +:10EF10000000000000000000080002430000402044 +:10EF200030080440413010C8000000000203001007 +:10EF3000C000110800C2431080C020010800020078 +:10EF40000000000000000000080008C30A20C18C77 +:10EF500012220488013620C3081228040801040084 +:10EF60004AA8220104C8412630C0880221000200BC +:10EF70000000000000000000080008000A10C18026 +:10EF800032210C88430280448012290408420A90EE +:10EF90008A8000200448030A1082800020000200BA +:10EFA000000000000000000000000A8702A180AC01 +:10EFB0004329148A8402A100AC412010080626319E +:10EFC00080A46020144A44328181AC602A18020077 +:10EFD0000000000000000000080008072201C580B2 +:10EFE00073211CC8072A010C807220104847261183 +:10EFF000C58073201C88072A1149807020140200E4 +:10F000000000000000000000080000451031C90C9D +:10F0100073021CC04704010A0C510A1082472031B8 +:10F02000C80072021C40053011C4007201180200B1 +:10F030000000000000000000081010062401450434 +:10F04000518118904714010404718810120534018D +:10F050004404514018D0073801C404520114C204BA +:10F060000000000000000000000000870021890C63 +:10F0700060011CD0452401C10C42010000C52031B3 +:10F08000410840001880450021410C70421CC2001C +:10F090000000000000000000000002011C80C420ED +:10F0A00031081042420880C62031090020031C901C +:10F0B000C42001490C424310804420310810000054 +:10F0C0000000000000000000000030832030480CE9 +:10F0D00032401090812420C80432401020C3208088 +:10F0E000C800024A0CA0012410C8083241100000D8 +:10F0F0000000000000000000001090030000C904A0 +:10F10000304000900020008000104010004020108F +:10F11000C20000800820430810810032400CC00467 +:10F12000200000000000000000003000400000004F +:10F13000100000F01020000000100000F0108040CF +:10F140000000004000F01090800000000000C000AF +:10F1500000000000000000003C3C108090400000D7 +:10F1600000801090A09000000000001090808000AF +:10F1700000000000109080900000000040108F0FF1 +:10F180000000000000000000000024C6BA06C01CF9 +:10F19000492861142B1C0E403FD9BFD9AABC1A5F65 +:10F1A0000010A6503B61B325BC4019BFFFE98000A9 +:10F1B0000000000000000000000010921494800C79 +:10F1C000073F2B948614848028000049140486127B +:10F1D0008000412734D0908492002D8A211E800027 +:10F1E000000000000000000000000000000008A275 +:10F1F000B10101000000000884B17828000000007F +:10F2000008B13214140000000008A8235421400063 +:10F21000000000000000000000003FFFFFFFC000F2 +:10F220000000002FFFFEF7C0000000002FD7FEEF08 +:10F23000C0000000003FFF7FFFC000000000000092 +:10F24000000000000000000000003FFFFFFFC000C2 +:10F250000000000FEF77FFC0000000003EFFFEEF50 +:10F2600040000000003FFFBFFF4000000000000022 +:10F27000000000000000000000003FFFFFFFC00092 +:10F280000000003FFFDFFFC0000000003FFFFFFF66 +:10F29000C0000000003F7F2FFFC000000000000002 +:10F2A000000000000000000000003FFFFFFFC00062 +:10F2B0000000001FFFFFEFC0000000001FEFEFEF96 +:10F2C000C0000000002FFFFFFFC000000000000092 +:10F2D000000000000000000000003FFFFFFFC00032 +:10F2E0000000003FFFEFFFC0000000002FAFDFFF76 +:10F2F000C0000000003FEFFFF7C00000000000006A +:10F30000000000000000000000003FFFFFFFC00001 +:10F310000000003FDFDFFFC0000000003FFFFFFFF5 +:10F32000C0000000001FFFDFFFC000000000000061 +:10F330000000000000000000000002C424A1002C16 +:10F34000520B18C2862CA18038620A0840C42CA136 +:10F350000828420B14008514A10828430A10000055 +:10F3600000000000000000000000080412010380FB +:10F3700061201008071241428070201C08041A0105 +:10F3800084814020180846368105806320100001E2 +:10F390008000000000000000000000842421000C18 +:10F3A00052021400872821810872061C82842021C1 +:10F3B0004818420354804530254A18530210000172 +:10F3C000200000000000000000000804220101806D +:10F3D000422018C8442201808442201C8804220153 +:10F3E0000080402010884436014080410010000019 +:10F3F0000000000000000000000000C00820000C19 +:10F4000022030440810020840803000080C2002001 +:10F41000C408000308888216A040883222800000B9 +:10F42000000000000000000008000201008004202D +:10F4300010080CC2121084C82212080402030088AB +:10F440000021000C0C404130008420100800020014 +:10F450000000000000000000080008820620088C60 +:10F4600032220C888126204D882322808883062022 +:10F4700008880023048A8136204B8832220000004D +:10F4800000000000000000000800080202000980DF +:10F49000322004886022008984002008980002003D +:10F4A000008000200008023A8048803020000200DE +:10F4B000000000000000000008000AC41AA180A893 +:10F4C000412A10CAC71AA104AD712A184AD406B13C +:10F4D00000A8712A100884262906AC522A100200BE +:10F4E0000000000000000000080008042A0141801C +:10F4F00042201C00040A01098451201C8844020196 +:10F5000008804020104A4702014880632010020012 +:10F510008000000000000000080000C41021810CE1 +:10F5200041020C00C020610D0E72021C40C4083163 +:10F530000418420210808720B1C40C53021000004E +:10F540000000000000000000081020072401CC008B +:10F55000724014000424010800734110C0073011E8 +:10F56000CC007101100204208146104240100204B8 +:10F570000000000000000000080000C51021000885 +:10F5800062021C90C52421000C70821C10C4203122 +:10F59000880240061C008500A1000C4042000200C9 +:10F5A000000000000000000000002205148001207F +:10F5B00030080C42060080012451080C02410080F2 +:10F5C0004C2000080C304204000420000800000019 +:10F5D0000000000000000000000010C62420000C05 +:10F5E00032C20480C73020000C53C20410C22870FD +:10F5F0000C0902024C80810430090C024210000008 +:10F60000000000000000000000108001380002002F +:10F6100012400C200734040200630108100024107B +:10F620000400020104820108800910024010000455 +:10F6300030000000000000000000302010800000BA +:10F64000208000F02010800000208000D08000008A +:10F650004000000000301000800000000000CC409E +:10F6600000000000000000003C3C10808000000012 +:10F67000000010908080000000000010908000903A +:10F68000800010000010A0800000002000108C08F6 +:10F6900000000000000000000000341ABE178000C7 +:10F6A0003E40266FBAE32480001659BD828182D87D +:10F6B000800000199986806480C03FD9998000013C +:10F6C000F000000000000000000006160294001682 +:10F6D000C01694829016108021182828020A020869 +:10F6E00080000000000282801400011411A040007C +:10F6F000000000000000000000000000000008847E +:10F700000284A8800000000891228441A2082401FC +:10F7100030000000000000000008840144010000E7 +:10F72000000000000000000000003FFFFFFFC000DD +:10F730000000003EF7FFF7C0000000002FE7B7FF12 +:10F74000C0000000002FFE7FF7C000000000000096 +:10F75000000000000000000000003FFFFFFFC000AD +:10F7600000000036BFFEDFC0000000000FF7DFFF23 +:10F77000C0000000003DB7B7EFC00000000000006F +:10F78000000000000000000000003FFFFFFFC0007D +:10F790000000001FDFDFFFC0000000000FDFDFFF01 +:10F7A000C0000000003FEFFFFFC0000000000000AD +:10F7B000000000000000000000003FFFFFFFC0004D +:10F7C0000000003FBF7FFFC0000000003FFF7FF749 +:10F7D000C0000000003FDFFFFFC00000000000008D +:10F7E000000000000000000000003FFFFFFFC0001D +:10F7F0000000003F7EFFFF40000000003FFEFFFFD3 +:10F80000C0000000003FFFFFFFC00000000000003C +:10F81000000000000000000000003FFFFFFFC000EC +:10F8200000000037FF6FFFC0000000003FFFFFFF38 +:10F83000C0000000003FFFFFFFC00000000000000C +:10F8400000000000000000000000000000000000B8 +:10F8500000000000000000000000000000000000A8 +:10F860000000000000000000000000000000000098 +:10F870000000000000000000300020010200000035 +:10F880003000430C000000000000000000000000F9 +:10F890000000000000000000000000000000000068 +:10F8A0000000000000000000000000000000000058 +:10F8B0000000000000000000000000000000000048 +:10F8C0000000000000000000000000000000000038 +:10F8D0000000000000000000000000000000000028 +:10F8E0000000000000000000000000000000000018 +:10F8F00000000000000000000030C00000000030E8 +:10F90000C000000000000000000000000000000037 +:10F9100000000000000000000000000000000000E7 +:10F9200000000000000000000000000000000000D7 +:10F9300000000000000000000000000000000000C7 +:10F9400000000000000000000000000000000000B7 +:10F95000000000000000000000000030C030C000C7 +:10F960000000000000000000000000000000000097 +:10F970000000000000000000000000000000000087 +:10F980000000000000000000000000000000000077 +:10F990000000000000000000000000000000000067 +:10F9A0000000000000000000000000000000000057 +:10F9B00000000000000000000030C030C030C03047 +:10F9C000C000000000000000000000000000000077 +:10F9D0000000000000000000000000000000000027 +:10F9E0000000000000000000000000000000000017 +:10F9F0000000000000000000000000000000000007 +:10FA000000000000000000000000000000000000F6 +:10FA10000000000000000000000F00000000000FC8 +:10FA200000000000000000000000000000000000D6 +:10FA300000000000000000000000000000000000C6 +:10FA400000000000000000000000000000000000B6 +:10FA500000000000000000000000000000000000A6 +:10FA60000000000000000000000000000000000096 +:10FA70000000000000000000003FC0000000003F48 +:10FA8000C0000000000000000000000000000000B6 +:10FA90000000000000000000000000000000000066 +:10FAA0000000000000000000000000000000000056 +:10FAB0000000000000000000000000000000000046 +:10FAC0000000000000000000000000000000000036 +:10FAD0000000000000000000000F0030C030C00F28 +:10FAE0000000000000000000000000000000000016 +:10FAF0000000000000000000000000000000000006 +:10FB000000000000000000000000000000000000F5 +:10FB100000000000000000000000000000000000E5 +:10FB200000000000000000000000000000000000D5 +:10FB3000000000000000000000136B00C000CF2C8C +:10FB40004000000000000000000000000000000075 +:10FB500000000000000000000000000000000000A5 +:10FB60000000000000000000000000000000000095 +:10FB70000000000000000000000000000000000085 +:10FB80000000000000000000000000000000000075 +:10FB900000000000000000000000000F000F000047 +:10FBA0000000000000000000000000000000000055 +:10FBB0000000000000000000000000000000000045 +:10FBC0000000000000000000000000000000000035 +:10FBD0000000000000000000000000000000000025 +:10FBE0000000000000000000000000000000000015 +:10FBF00000000000000000000030C00F000F0030C7 +:10FC0000C000000000000000000000000000000034 +:10FC100000000000000000000000000000000000E4 +:10FC200000000000000000000000000000000000D4 +:10FC300000000000000000000000000000000000C4 +:10FC400000000000000000000000000000000000B4 +:10FC500000000000000000000000003FC03FC000A6 +:10FC60000000000000000000000000000000000094 +:10FC70000000000000000000000000000000000084 +:10FC80000000000000000000000000000000000074 +:10FC90000000000000000000000000000000000064 +:10FCA0000000000000000000000000000000000054 +:10FCB00000000000000000000030C03FC03FC03026 +:10FCC000C000000000000000000000000000000074 +:10FCD0000000000000000000000000000000000024 +:10FCE0000000000000000000000000000000000014 +:10FCF0000000000000000000000000000000000004 +:10FD000000000000000000000000000000000000F3 +:10FD10000000000000000000000F000F000F000FA7 +:10FD200000000000000000000000000000000000D3 +:10FD300000000000000000000000000000000000C3 +:10FD400000000000000000000000000000000000B3 +:10FD500000000000000000000000000000000000A3 +:10FD60000000000000000000000000000000000093 +:10FD70000000000000000000003FC00F000F003F27 +:10FD8000C0000000000000000000000000000000B3 +:10FD90000000000000000000000000000000000063 +:10FDA0000000000000000000000000000000000053 +:10FDB0000000000000000000000000000000000043 +:10FDC0000000000000000000000000000000000033 +:10FDD0000000000000000000000F003FC03FC00F07 +:10FDE0000000000000000000000000000000000013 +:10FDF0000000000000000000000000000000000003 +:10FE000000000000000000000000000000000000F2 +:10FE100000000000000000000000000000000000E2 +:10FE200000000000000000000000000000000000D2 +:10FE3000000000000000000006335D80C000FDAC43 +:10FE400002000000000000000000000000000000B0 +:10FE500000000000000000000000000000000000A2 +:10FE60000000000000000000000000000000000092 +:10FE70000000000000000000000000000000000082 +:10FE80000000000000000000000000000000000072 +:10FE90000000000000000000000000000000000062 +:10FEA0000000000000000000000000000000000052 +:10FEB0000000000000000000000000000000000042 +:10FEC0000000000000000000000000000000000032 +:10FED0000000000000000000000000000000000022 +:10FEE0000000000000000000000000000000000012 +:10FEF00000000000000000000030C00000000030E2 +:10FF0000C000000000000000000000000000000031 +:10FF100000000000000000000000000000000000E1 +:10FF200000000000000000000000000000000000D1 +:10FF300000000000000000000000000000000000C1 +:10FF400000000000000000000000000000000000B1 +:10FF5000000000000000000000000030C030C000C1 +:10FF60000000000000000000000000000000000091 +:10FF70000000000000000000000000000000000081 +:10FF80000000000000000000000000000000000071 +:10FF90000000000000000000000000000000000061 +:10FFA0000000000000000000000000000000000051 +:10FFB00000000000000000000030C030C030C03041 +:10FFC000C000000000000000000000000000000071 +:10FFD0000000000000000000000000000000000021 +:10FFE0000000000000000000000000000000000011 +:10FFF0000000000000000000000000000000000001 +:108010000000000000000000000000000000000060 +:108020000000000000000000000F00000000000F32 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:108080000000000000000000003FC0000000003FB2 +:10809000C000000000000000000000000000000020 +:1080A00000000000000000000000000000000000D0 +:1080B00000000000000000000000000000000000C0 +:1080C00000000000000000000000000000000000B0 +:1080D00000000000000000000000000000000000A0 +:1080E0000000000000000000000F0030C030C00F92 +:1080F0000000000000000000000000000000000080 +:10810000000000000000000000000000000000006F +:10811000000000000000000000000000000000005F +:10812000000000000000000000000000000000004F +:10813000000000000000000000000000000000003F +:108140000000000000000000001374C0C000F0EC4C +:1081500040000000000000000000000000000000DF +:10816000000000000000000000000000000000000F +:1081700000000000000000000000000000000000FF +:1081800000000000000000000000000000000000EF +:1081900000000000000000000000000000000000DF +:1081A00000000000000000000000000F000F0000B1 +:1081B00000000000000000000000000000000000BF +:1081C00000000000000000000000000000000000AF +:1081D000000000000000000000000000000000009F +:1081E000000000000000000000000000000000008F +:1081F000000000000000000000000000000000007F +:1082000000000000000000000030C00F000F003030 +:10821000C00000000000000000000000000000009E +:10822000000000000000000000000000000000004E +:10823000000000000000000000000000000000003E +:10824000000000000000000000000000000000002E +:10825000000000000000000000000000000000001E +:1082600000000000000000000000003FC03FC00010 +:1082700000000000000000000000000000000000FE +:1082800000000000000000000000000000000000EE +:1082900000000000000000000000000000000000DE +:1082A00000000000000000000000000000000000CE +:1082B00000000000000000000000000000000000BE +:1082C0000000000000000000001986108030823D90 +:1082D000800000000000000000000000000000001E +:1082E000000000000000000000000000000000008E +:1082F000000000000000000000000000000000007E +:10830000000000000000000000000000000000006D +:10831000000000000000000000000000000000005D +:108320000000000000000000000F000F000F000F11 +:10833000000000000000000000000000000000003D +:10834000000000000000000000000000000000002D +:10835000000000000000000000000000000000001D +:10836000000000000000000000000000000000000D +:1083700000000000000000000000000000000000FD +:108380000000000000000000003FC00F000F003F91 +:10839000C00000000000000000000000000000001D +:1083A00000000000000000000000000000000000CD +:1083B00000000000000000000000000000000000BD +:1083C00000000000000000000000000000000000AD +:1083D000000000000000000000000000000000009D +:1083E0000000000000000000000F003FC03FC00F71 +:1083F000000000000000000000000000000000007D +:10840000000000000000000000000000000000006C +:10841000000000000000000000000000000000005C +:10842000000000000000000000000000000000004C +:10843000000000000000000000000000000000003C +:108440000000000000000000376525E48000B088CF +:10845000AB40000000000000000000000000000031 +:10846000000000000000000000000000000000000C +:1084700000000000000000000000000000000000FC +:1084800000000000000000000000000000000000EC +:1084900000000000000000000000000000000000DC +:1084A00000000000000000000000000000000000CC +:1084B00000000000000000000000000000000000BC +:1084C00000000000300020010202000030004300E4 +:1084D000000000000000000000000000000000009C +:1084E000000000000000000000000000000000008C +:1084F000000000000000000000000000000000007C +:10850000000000000000000000000000000000006B +:10851000000000000000000000000000000000005B +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:10860000000000000000000000000000000000006A +:10861000000000000000000000000000000000005A +:10862000000000000000000000000000000000004A +:10863000000000000000000000000000000000003A +:10864000000000000000000000000000000000002A +:10865000000000000000000000000000000000001A +:10866000000000000000000000000000000000000A +:1086700000000000000000000000000000000000FA +:1086800000000000000000000000000000000000EA +:1086900000000000000000000000000000000000DA +:1086A00000000000000000000000000000000000CA +:1086B00000000000000000000000000000000000BA +:1086C00000000000000000000000000000000000AA +:1086D000000000000000000000000000000000009A +:1086E000000000000000000000000000000000008A +:1086F000000000000000000000000000000000007A +:108700000000000000000000000000000000000069 +:108710000000000000000000000000000000000059 +:108720000000000000000000000000000000000049 +:108730000000000000000000000000000000000039 +:108740000000000000000000000000000000000029 +:108750000000000000000000000000000000000019 +:108760000000000000000000000000000000000009 +:1087700000000000000000000000000000000000F9 +:1087800000000000000000000000000000000000E9 +:1087900000000000000000000000000000000000D9 +:1087A00000000000000000000000000000000000C9 +:1087B00000000000000000000000000000000000B9 +:1087C00000000000000000000000000000000000A9 +:1087D0000000000000000000000000000000000099 +:1087E0000000000000000000000000000000000089 +:1087F0000000000000000000000000000000000079 +:108800000000000000000000000000000000000068 +:108810000000000000000000000000000000000058 +:108820000000000000000000000000000000000048 +:108830000000000000000000000000000000000038 +:108840000000000000000000000000000000000028 +:108850000000000000000000000000000000000018 +:108860000000000000000000000000000000000008 +:1088700000000000000000000000000000000000F8 +:1088800000000000000000000000000000000000E8 +:1088900000000000000000000000000000000000D8 +:1088A00000000000000000000000000000000000C8 +:1088B00000000000000000000000000000000000B8 +:1088C00000000000000000000000000000000000A8 +:1088D0000000000000000000000000000000000098 +:1088E0000000000000000000000000000000000088 +:1088F0000000000000000000000000000000000078 +:108900000000000000000000000000000000000067 +:108910000000000000000000000000000000000057 +:108920000000000000000000000000000000000047 +:108930000000000000000000000000000000000037 +:108940000000000000000000000000000000000027 +:108950000000000000000000000000000000000017 +:108960000000000000000000000000000000000007 +:1089700000000000000000000000000000000000F7 +:1089800000000000000000000000000000000000E7 +:1089900000000000000000000000000000000000D7 +:1089A00000000000000000000000000000000000C7 +:1089B00000000000000000000000000000000000B7 +:1089C00000000000000000000000000000000000A7 +:1089D0000000000000000000000000000000000097 +:1089E0000000000000000000000000000000000087 +:1089F0000000000000000000000000000000000077 +:108A00000000000000000000000000000000000066 +:108A10000000000000000000000000000000000056 +:108A20000000000000000000000000000000000046 +:108A30000000000000000000000000000000000036 +:108A40000000000000000000000000000000000026 +:108A50000000000000000000000000000000000016 +:108A60000000000000000000000000000000000006 +:108A700000000000000000000000000000000000F6 +:108A800000000000000000000000000000000000E6 +:108A900000000000000000000000000000000000D6 +:108AA00000000000000000000000000000000000C6 +:108AB00000000000000000000000000000000000B6 +:108AC00000000000000000000000000000000000A6 +:108AD0000000000000000000000000000000000096 +:108AE0000000000000000000000000000000000086 +:108AF0000000000000000000000000000000000076 +:108B00000000000000000000000000000000000065 +:108B10000000000000000000000000000000000055 +:108B20000000000000000000000000000000000045 +:108B30000000000000000000000000000000000035 +:108B40000000000000000000000000000000000025 +:108B50000000000000000000000000000000000015 +:108B60000000000000000000000000000000000005 +:108B700000000000000000000000000000000000F5 +:108B800000000000000000000000000000000000E5 +:108B900000000000000000000000000000000000D5 +:108BA00000000000000000000000000000000000C5 +:108BB00000000000000000000000000000000000B5 +:108BC00000000000000000000000000000000000A5 +:108BD0000000000000000000000000000000000095 +:108BE0000000000000000000000000000000000085 +:108BF0000000000000000000000000000000000075 +:108C00000000000000000000000000000000000064 +:108C10000000000000000000000000000000000054 +:108C20000000000000000000000000000000000044 +:108C30000000000000000000000000000000000034 +:108C40000000000000000000000000000000000024 +:108C50000000000000000000000000000000000014 +:108C60000000000000000000000000000000000004 +:108C700000000000000000000000000000000000F4 +:108C800000000000000000000000000000000000E4 +:108C900000000000000000000000000000000000D4 +:108CA00000000000000000000000000000000000C4 +:108CB00000000000000000000000000000000000B4 +:108CC00000000000000000000000000000000000A4 +:108CD0000000000000000000000000000000000094 +:108CE0000000000000000000000000000000000084 +:108CF0000000000000000000000000000000000074 +:108D00000000000000000000000000000000000063 +:108D10000000000000000000000000000000000053 +:108D20000000000000000000000000000000000043 +:108D30000000000000000000000000000000000033 +:108D40000000000000000000000000000000000023 +:108D50000000000000000000000000000000000013 +:108D60000000000000000000000000000000000003 +:108D700000000000000000000000000000000000F3 +:108D800000000000000000000000000000000000E3 +:108D900000000000000000000000000000000000D3 +:108DA00000000000000000000000000000000000C3 +:108DB00000000000000000000000000000000000B3 +:108DC00000000000000000000000000000000000A3 +:108DD0000000000000000000000000000000000093 +:108DE0000000000000000000000000000000000083 +:108DF0000000000000000000000000000000000073 +:108E00000000000000000000000000000000000062 +:108E10000000000000000000000000000000000052 +:108E20000000000000000000000000000000000042 +:108E30000000000000000000000000000000000032 +:108E40000000000000000000000000000000000022 +:108E50000000000000000000000000000000000012 +:108E60000000000000000000000000000000000002 +:108E700000000000000000000000000000000000F2 +:108E800000000000000000000000000000000000E2 +:108E900000000000000000000000000000000000D2 +:108EA00000000000000000000000000000000000C2 +:108EB00000000000000000000000000000000000B2 +:108EC00000000000000000000000000000000000A2 +:108ED0000000000000000000000000000000000092 +:108EE0000000000000000000000000000000000082 +:108EF0000000000000000000000000000000000072 +:108F00000000000000000000000000000000000061 +:108F10000000000000000000000000000000000051 +:108F20000000000000000000000000000000000041 +:108F30000000000000000000000000000000000031 +:108F40000000000000000000000000000000000021 +:108F50000000000000000000000000000000000011 +:108F60000000000000000000000000000000000001 +:108F700000000000000000000000000000000000F1 +:108F800000000000000000000000000000000000E1 +:108F900000000000000000000000000000000000D1 +:108FA00000000000000000000000000000000000C1 +:108FB00000000000000000000000000000000000B1 +:108FC00000000000000000000000000000000000A1 +:108FD0000000000000000000000000000000000091 +:108FE0000000000000000000000000000000000081 +:108FF0000000000000000000000000000000000071 +:109000000000000000000000000000000000000060 +:109010000000000000000000000000000000000050 +:109020000000000000000000000000000000000040 +:109030000000000000000000000000000000000030 +:109040000000000000000000000000000000000020 +:109050000000000000000000000000000000000010 +:109060000000000000000000000000000000000000 +:1090700000000000000000000000000000000000F0 +:1090800000000000000000000000000000000000E0 +:1090900000000000000000000000000000000000D0 +:1090A00000000000000000000000000000000000C0 +:1090B00000000000000000000000000000000000B0 +:1090C00000000000000000000000000000000000A0 +:1090D00030000001000044723000800100000003F5 +:1090E0003000400C00000000000000000000000004 +:1090F0000000000000000000000000000000000070 +:10910000000000000000000000000000000000005F +:109110000000000030008001000000053000A001C8 +:1091200000000000300000010000E15A00000000D3 +:0C91300000000000000000000000000033 +:00000001FF +// VERSION= 1.0.0.191 +// DATE= 2002oct28 diff --git a/firmware/emi62/loader.HEX b/firmware/emi62/loader.HEX new file mode 100644 index 0000000..0edb2dc --- /dev/null +++ b/firmware/emi62/loader.HEX @@ -0,0 +1,107 @@ +:0300000002028772 +:03004300020400B4 +:10010000E4FFFEC220D2E843D820907FAB74FFF01A +:10011000907FA9F0907FAAF05391EF907F9574C0E3 +:10012000F0907F9EF0907F98F0E4907F94F0907F25 +:100130009D74FFF0907F9774A0F0907F93E054FC43 +:10014000F0907F9C7403F0E4907F96F0907FAFE096 +:100150004401F0907FAEE0440DF0D2AF0FBF00013C +:100160000EBE07F8BF08F520204275140075130075 +:100170007512007511007F487E927D007C00AB14E3 +:10018000AA13A912A811C31203ED50DB2020D87ABC +:100190000079007800E5142401F514EA3513F5130D +:1001A000E93512F512E83511F51180CA3020FD123B +:1001B00001C75007907FB4E04401F0907FB4E04461 +:0601C00002F0C22080E6FF +:0101C6002216 +:1001C700907FE9E0245B606024026003020285906F +:1001D7007FEAE0750A00F50BA3E0FEE4EE420A9021 +:1001E7007FEEE0751500F516A3E0FEE4EE4215E597 +:1001F7001645157003020285E4907FC5F0907FB421 +:10020700E020E3F9907FC5E0F50C120313AF0C7EF5 +:1002170000EF250BF50BEE350AF50AC3E5169FF53A +:1002270016E5159EF51580C7907FEAE0750A00F57B +:100237000BA3E0FEE4EE420A907FEEE0751500F5B1 +:1002470016A3E0FEE4EE4215E51645156030E4908E +:100257007FC5F0907FB4E020E3F9907FC5E0F50C0F +:1002670012032BAF0C7E00EF250BF50BEE350AF5CD +:0F0277000AC3E5169FF516E5159EF51580CAC357 +:010286002255 +:0C028700787FE4F6D8FD7581290202CED4 +:10029300020100E493A3F8E493A34003F68001F280 +:1002A30008DFF48029E493A3F85407240CC8C3336C +:1002B300C4540F4420C8834004F456800146F6DF3B +:1002C300E4800B010204081020408090046EE47E59 +:1002D300019360BCA3FF543F30E509541FFEE49330 +:1002E300A360010ECF54C025E060A840B8E493A3F7 +:1002F300FAE493A3F8E493A3C8C582C8CAC583CA22 +:10030300F0A3C8C582C8CAC583CADFE9DEE780BED9 +:10031300E50CFFE50BF582E50AF58375927E74C063 +:08032300F8E208F0A3DFFA2262 +:10032B00907F96858392A8827902900000E0B400BA +:10033B000D7401F0907F97E0547FF04480F0E50C52 +:10034B00FF907EC0E0F528E4A24733F269F2E4A205 +:10035B004633F269F2E4A24533F269F2E4A2443384 +:10036B00F269F2E4A24333F269F2E4A24233F26996 +:10037B00F2E4A24133F269F2E4A24033F269F2A350 +:03038B00DFC222AC +:10038E00C0E0C083C082907FC4E4F05391EF907FB1 +:0B039E00AB7404F0D082D083D0E032BA +:1003A900C0E0C083C082D2205391EF907FAB74012B +:0803B900F0D082D083D0E032C5 +:1003C100C0E0C083C0825391EF907FAB7402F0D044 +:0603D10082D083D0E0326F +:1003D700C0E0C083C0825391EF907FAB7410F0D020 +:0603E70082D083D0E03259 +:1003ED00EB9FF5F0EA9E42F0E99D42F0E89C45F066 +:0103FD0022DD +:0103FE0032CC +:0103FF0032CB +:100400000203A9000203C10002038E000204580087 +:100410000203D7000203FE000203FF00020484006F +:10042000020485000204860002048700020488009A +:100430000204890002048A0002048B0002048C007A +:1004400002048D0002048E0002048F00020490005A +:08045000020491000204920075 +:10045800C0E0C083C0825391EF907FAB7408F0D0A6 +:0604680082D083D0E032D7 +:10046E00020A000F010C11040D00000000410000F3 +:01047E00007D +:04047F000217000060 +:010483000078 +:010484003245 +:010485003244 +:010486003243 +:010487003242 +:010488003241 +:010489003240 +:01048A00323F +:01048B00323E +:01048C00323D +:01048D00323C +:01048E00323B +:01048F00323A +:010490003239 +:010491003238 +:010492003237 +:1011000012011001000000406A0801010001010203 +:10111000000109022000010103A0000904000002EF +:10112000FF0000040705820240000007050202409C +:10113000000004030904260341006E0063006800F8 +:101140006F007200200043006800690070007300A7 +:101150002C00200049006E0063002E00280346008A +:10116000690072006D007700610072006500200068 +:101170004600720061006D00650057006F0072004C +:101180006B0073002A0343006F006E006600690065 +:101190006700750072006100740069006F006E00E6 +:1011A000200053007400720069006E006700220383 +:1011B00049006E0074006500720066006100630003 +:1011C0006500200053007400720069006E00670023 +:0211D00000001D +:00000001FF +/* +Source: EMILOAD.HEX +VERSION=1.0.2.002 +DATE=10.01.2002 +EMI26_62 +*/ diff --git a/firmware/emi62/midi.HEX b/firmware/emi62/midi.HEX new file mode 100644 index 0000000..32a0d65 --- /dev/null +++ b/firmware/emi62/midi.HEX @@ -0,0 +1,1266 @@ +:030000000246B9FC +:03000300020FFDEC +:03000B00024E0F93 +:030013000217FDD4 +:03001B00024E1280 +:03002300024DEF9C +:03002B0002480088 +:03003300024DE695 +:03003B00024DF67D +:030043000249006F +:03004B00024E035F +:030053000248FA66 +:03005B00024DFD56 +:03006300024E0743 +:1005000012011001000000406A08110100010102FF +:100510000001090208020501008032090400000000 +:10052000010100000A2401000156000201020C240E +:10053000020101010002000000000D240605010275 +:10054000030000000000000924030204030005006A +:100550000C24020305020006000000001524060614 +:100560000302000003000300030003000300030074 +:100570000009240304010100060009040100000130 +:100580000200000904010102010200000724010128 +:10059000000100112402010202100344AC0080BBE0 +:1005A0000000770109050A05840101008F07250174 +:1005B0000100000009058F01030001050009040185 +:1005C00002020102000007240101000100112402BF +:1005D000010203180344AC0080BB00007701090549 +:1005E0000A05460201008F072501010000000905E8 +:1005F0008F01030001050009040200000102000050 +:1006000009040201010102000007240104000100A5 +:100610000E2402010602100244AC0080BB00090552 +:100620008C054C02010000072501000200000904AE +:1006300002020101020000072401040001000E244F +:1006400002010603180244AC0080BB0009058C05BA +:1006500072030100000725010002000009040203E3 +:10066000010102000007240104000100112402011D +:100670000202100344AC0080BB0000770109058C26 +:1006800005840101000007250100020000090402A1 +:1006900004010102000007240104000100112402EA +:1006A000010203180344AC0080BB00007701090578 +:1006B0008C05460201000007250100020000090424 +:1006C00003000001010000092401000109000104E8 +:1006D00009040400020103000007240100012400B2 +:1006E000062402010700092403020801070100068D +:1006F0002402020900092403010A01090100090575 +:10070000010204000000000525010107090581021E +:100710000400000000052501010A04030904180370 +:1007200045006D006100670069006300200047001C +:100730006D0062004800220345006D006100670003 +:1007400069006300200045004D004900200036008C +:100750007C00320020006D002A0343006F006E0011 +:10076000660069006700750072006100740069002E +:100770006F006E00200053007400720069006E006C +:100780006700220349006E00740065007200660075 +:10079000610063006500200053007400720069006E +:0607A0006E00670000007E +:1007A600E4907666F01244AD202613907666E0C398 +:1007B6009402500AE004F0D242124B7F80EA3026BF +:1007C60005122801C22630252B907696E054FCF0BF +:1007D600908003F0121496907696E04403F0908091 +:1007E60003F0E4907667F0907667E004F0E0B44BAF +:0A07F600F61247FA12411B80C522DB +:10080000E4907631F0907631E0FF75F003A4240F88 +:10081000F582E43475F583E0FE907FEDE0FDEE6D4A +:10082000600EEFC3940B5008907631E004F080D551 +:10083000EFB40B08907FB4E04401F022EF75F003B1 +:10084000A4240EF582E43475F583E0907633F02429 +:10085000F0600A240E60028187124BC722907FED60 +:10086000E0640570519076187405F0907637740145 +:10087000F09076397403F0907621F0E4907620F0D1 +:10088000907FEAE0F4602F907620E0FF75F00AA4F4 +:1008900024AAF582E43475F583E0FE907FEAE0FD5A +:1008A000EE6D6012907621E0FEEFC39E50089076C8 +:1008B00020E004F080D1907FEDE0640670529076E5 +:1008C000187406F09076377404F0907639740AF054 +:1008D000907621F09076207403F0907FEAE0F46047 +:1008E0002F907620E0FF75F00AA424AAF582E43464 +:1008F00075F583E0FE907FEAE0FDEE6D6012907684 +:1009000021E0FEEFC39E5008907620E004F080D1F5 +:10091000907620E0FF75F00AA424AAF582E43475ED +:10092000F583E0907229F0E490763BF0907621E038 +:10093000FEEF6E7008907FB4E04401F022907FEBF0 +:10094000E014601314700221E224026002817F909F +:100950007FB4E04401F022907FE9E014707C907F46 +:10096000EAE0F47048907637E0907620F09076399F +:10097000E0FE907620E0FDC39E502B90763BE0FE9B +:1009800004F074C02EF582E4347EF583E0FEED754C +:10099000F00AA424ABF582E43475F583EEF090768A +:1009A00020E004F080C790763F7401F022907EC072 +:1009B000E0FEEF75F00AA424ABF582E43475F5830C +:1009C000EEF0E0B4010890763E7401F08005E4900A +:1009D000763EF090763F7401F022907FB4E04401BF +:1009E000F022907FE9E024FE700241A314700261BE +:1009F0003F14700261DB240360028177907FEAE09C +:100A0000F4706B907637E0907620F0907639E0FFC6 +:100A1000907620E0FEC39F504E90763BE0FF04F0BE +:100A200074C02FF582E4347EF583E0FFEE75F00AA2 +:100A3000A424ACF582E43475F583EFF090763BE0C6 +:100A4000FF04F074C02FF582E4347EF583E0FFEEFE +:100A500075F00AA424ADF582E43475F583EFF090C7 +:100A60007620E004F080A49076407401F022907E1D +:100A7000C0E0FF907620E0FE75F00AA424ACF58279 +:100A8000E43475F583EFF0907EC1E0FFEE75F00A77 +:100A9000A424ADF582E43475F583EFF090764174CB +:100AA00001F022907FEAE0F47066907637E090766D +:100AB00020F0907639E0FF907620E0FEC39F400260 +:100AC000818E90763BE0FF04F074C02FF582E43411 +:100AD0007EF583E0FFEE75F00AA424AEF582E434DF +:100AE00075F583EFF090763BE0FF04F074C02FF5CE +:100AF00082E4347EF583E0FFEE75F00AA424AFF5BE +:100B000082E43475F583EFF0907620E004F080A263 +:100B1000907EC0E0FF907620E0FE75F00AA424AE3F +:100B2000F582E43475F583EFF0907EC1E0FFEE7559 +:100B3000F00AA424AFF582E43475F583EFF0229037 +:100B40007FEAE0F47066907637E0907620F0907659 +:100B500039E0FF907620E0FEC39F4002818E9076C0 +:100B60003BE0FF04F074C02FF582E4347EF583E0AF +:100B7000FFEE75F00AA424B0F582E43475F583EF36 +:100B8000F090763BE0FF04F074C02FF582E4347EF1 +:100B9000F583E0FFEE75F00AA424B1F582E4347524 +:100BA000F583EFF0907620E004F080A2907EC0E024 +:100BB000FF907620E0FE75F00AA424B0F582E434BC +:100BC00075F583EFF0907EC1E0FFEE75F00AA42486 +:100BD000B1F582E43475F583EFF022907FEAE0F41A +:100BE0007066907637E0907620F0907639E0FF904E +:100BF0007620E0FEC39F4002818E90763BE0FF04AA +:100C0000F074C02FF582E4347EF583E0FFEE75F0DA +:100C10000AA424B2F582E43475F583EFF090763BB4 +:100C2000E0FF04F074C02FF582E4347EF583E0FF2A +:100C3000EE75F00AA424B3F582E43475F583EFF081 +:100C4000907620E004F080A2907EC0E0FF907620B5 +:100C5000E0FE75F00AA424B2F582E43475F583EF62 +:100C6000F0907EC1E0FFEE75F00AA424B3F582E4B3 +:100C70003475F583EFF022907FB4E04401F02290C8 +:0F0C80007FB4E04401F022907FB4E04401F02201 +:100C8F004176680141766A0241766B0AC120C12123 +:020C9F00C12F63 +:040CA1004176230075 +:100CA500417201014572050002C9000045720A0042 +:100CB500010203044D720FD100D1000000000000B5 +:100CC500282809004D721C010001020304050607CE +:100CD50008090A0B41722E2241722F2341723020DE +:100CE5004172312162D2723A00000000000000001A +:100CF50000000000000000000000000000000000EF +:100D050000000000000000000000000000000000DE +:100D150000000000000000000000000000000000CE +:100D250000000000000000000000000000000000BE +:100D350000000000000000000000000000000000AE +:100D4500000000000000000000000000000000009E +:100D5500000000000000000000000000000000008E +:100D6500000000000000000000000000000000007E +:100D75000000000000000000000001010101010168 +:100D8500010101010101010101010101010101014E +:100D9500010101010101010101010101010101013E +:100DA500010101010101010101010101010101012E +:100DB5000101010101010101020202020202020216 +:100DC50002020202020202020202020202020202FE +:100DD50002020202020202020202020202020202EE +:100DE50002020202020202020202020202020202DE +:100DF50002020202020303030303030303030303C3 +:100E050003030303030303030303030303030303AD +:100E1500030303030303030303030303030303039D +:100E2500030303030303030303030303030303038D +:100E3500030304040404040404040404040404046F +:100E4500040404040404040404040404040404045D +:100E5500040404040404040404040404040404044D +:100E6500040404040404040404040404040404043D +:100E7500050505050505050505050505050505051D +:100E8500050505050505050505050505050505050D +:100E950005050505050505050505050505050505FD +:100EA50005050505050505050505050505050606EB +:100EB50006060606060606060606060606060606CD +:100EC50006060606060606060606060606060606BD +:100ED50006060606060606060606060606060606AD +:100EE5000606060606060606060606070707080896 +:100EF500080909090A0A0A0B0B0B0C0C0C0D0D0D40 +:100F05000E0E0E0F0F0F10101011111112121213D9 +:100F15001313141414151515161616171717181874 +:100F250018191919191A1A1A1A1B1B1B1B1C1C1C18 +:100F35001C1D1D1D1D1E1E1E1E1F1F1F1F202020C8 +:100F45002121212222222323242425252626272761 +:100F5500282829292A2A2B2B2C2C2D2D2E2E2F2FD4 +:100F65003030313132323333343435353636373744 +:100F7500383839393A3A3B3C3D3E3F40414243449B +:100F85004546474849494A4B4B4C4D4E4F505152A7 +:100F95005354555556565757585A5B5D5E5F6162B7 +:100FA500636465666768696A6B6C6D6F717273748B +:100FB50075767778797A7B7C7E80013701013800F8 +:010FC500002B +:100FC600E4FF74462FF582E43476F583E0FE742060 +:100FD6002FF582E43480F583EEF0744E2FF582E42B +:100FE6003476F583E0FE74302FF582E43480F583A1 +:060FF600EEF00FBF08CC75 +:010FFC0022D2 +:030FFD00C2893274 +:10100000E490762CF090762CE0FF75F003A4240F8A +:10101000F582E43475F583E0FE907FEDE0FDEE6D42 +:10102000600EEFC3940B500890762CE004F080D54E +:10103000EFB40B08907FB4E04401F022EF75F003A9 +:10104000A4240EF582E43475F583E090762EF02426 +:10105000F0600A240F6002817D124BA422907FED84 +:10106000E0640570519076187405F090763874013C +:10107000F090763A7403F090761CF0E490761BF0D2 +:10108000907FEAE0F4602F90761BE0FF75F00AA4F1 +:1010900024AAF582E43475F583E0FE907FEAE0FD52 +:1010A000EE6D601290761CE0FEEFC39E50089076C5 +:1010B0001BE004F080D1907FEDE0640670529076E2 +:1010C000187406F09076387404F090763A740AF04A +:1010D00090761CF090761B7403F0907FEAE0F46049 +:1010E0002F90761BE0FF75F00AA424AAF582E43461 +:1010F00075F583E0FE907FEAE0FDEE6D601290767C +:101100001CE0FEEFC39E500890761BE004F080D1F7 +:10111000E490761EF090761CE0FF90761BE0FE6F68 +:101120007008907FB4E04401F022907FEBE01460FF +:101130001314700221BF240260028175907FB4E015 +:101140004401F022907FE9E0247F706B907FEAE019 +:10115000F4704A907638E090761BF090763AE0FF93 +:1011600090761BE0FDC39F502BED75F00AA424ABD5 +:10117000F582E43475F583E0FF90761EE0FD04F01F +:1011800074002DF582E4347FF583EFF090761BE058 +:1011900004F080C790761EE0907FB5F022EE75F0E7 +:1011A0000AA424ABF582E43475F583E0907F00F067 +:1011B000907FB57401F022907FB4E04401F022905A +:1011C0007FE9E0247E7002417E1470026123147076 +:1011D0000261C824036002816D907FEAE0F4706DC3 +:1011E000907638E090761BF090763AE0FF90761B90 +:1011F000E0C39F504FE0FF75F00AA424ACF582E4F1 +:101200003475F583E0FE90761EE0FD04F074002D49 +:10121000F582E4347FF583EEF0EF75F00AA424AD97 +:10122000F582E43475F583E0FF90761EE0FE04F06D +:1012300074002EF582E4347FF583EFF090761BE0A6 +:1012400004F080A490761EE0907FB5F02290761B8B +:10125000E0FF75F00AA424ACF582E43475F583E070 +:10126000907F00F0EF75F00AA424ADF582E43475A8 +:10127000F583E0907F01F0907FB57402F022907FBB +:10128000EAE0F4706D907638E090761BF090763A54 +:10129000E0FF90761BE0C39F504FE0FF75F00AA47B +:1012A00024AEF582E43475F583E0FE90761EE0FD11 +:1012B00004F074002DF582E4347FF583EEF0EF75D1 +:1012C000F00AA424AFF582E43475F583E0FF90764C +:1012D0001EE0FE04F074002EF582E4347FF583EF07 +:1012E000F090761BE004F080A490761EE0907FB52D +:1012F000F02290761BE0FF75F00AA424AEF582E49C +:101300003475F583E0907F00F0EF75F00AA424AF08 +:10131000F582E43475F583E0907F01F0907FB57439 +:1013200002F022907FEAE0F4706D907638E09076DB +:101330001BF090763AE0FF90761BE0C39F504FE0A1 +:10134000FF75F00AA424B0F582E43475F583E0FE5D +:1013500090761EE0FD04F074002DF582E4347FF5F4 +:1013600083EEF0EF75F00AA424B1F582E43475F54C +:1013700083E0FF90761EE0FE04F074002EF582E418 +:10138000347FF583EFF090761BE004F080A4907634 +:101390001EE0907FB5F02290761BE0FF75F00AA466 +:1013A00024B0F582E43475F583E0907F00F0EF75AA +:1013B000F00AA424B1F582E43475F583E0907F014E +:1013C000F0907FB57402F022907FEAE0F4706D90A7 +:1013D0007638E090761BF090763AE0FF90761BE04E +:1013E000C39F504FE0FF75F00AA424B2F582E434A5 +:1013F00075F583E0FE90761EE0FD04F074002DF597 +:1014000082E4347FF583EEF0EF75F00AA424B3F59F +:1014100082E43475F583E0FF90761EE0FE04F074FC +:10142000002EF582E4347FF583EFF090761BE00424 +:10143000F080A490761EE0907FB5F02290761BE0BD +:10144000FF75F00AA424B2F582E43475F583E090C8 +:101450007F00F0EF75F00AA424B3F582E43475F54B +:1014600083E0907F01F0907FB57402F022907FB40A +:10147000E04401F022907FB4E04401F022907FB478 +:05148000E04401F02230 +:101485007400F58690FDA57C05A3E582458370F97A +:011495002234 +:10149600907FD6E04480F0438701000000000022E0 +:1014A600C0D0C0E08FE0C0E08EE0C0E08DE0C0E0DC +:1014B6008CE0C0E0C082C0830586C084C0857D0004 +:1014C600907FE3747BF0A37480F07C11907F99E0A9 +:1014D6005440DC030214F3B40013907FE27440F02E +:1014E600907FE5F0907FE27400F00214D29076903F +:1014F600E0B4011290768FE02DFD907FE27480F0CB +:10150600907F6C021557B4021290768FE02DFD90F5 +:101516007FE27480F0907F6C021596B40312907689 +:101526008FE02DFD907FE27480F0907F6C0215E1D4 +:10153600B4041290768FE02DFD907FE27480F090D7 +:101546007F6C021610907FE27480F0907F6C02161A +:1015560040F0F0F0F0F0F0F0F0F0F0F0F0DDF27DB9 +:10156600020586907FE27400F0907F9BE05404B4FD +:1015760000050586021640907FE27480F00586F02D +:10158600F0F0F0F0F0F0F0F0F0F0F0DDD4021640FC +:10159600F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F045 +:1015A600F0F0DDEC7D020586907FE27400F0907F1E +:1015B6009BE05404B400050586021640907FE27451 +:1015C60080F00586F0F0F0F0F0F0F0F0F0F0F0F0DA +:0615D600F0F0F0F0F0F06F +:1015DC00DDCE021640F0F0F0F0DDFA7D02058690CB +:1015EC007FE27400F0907F9BE05404B40005058604 +:1015FC00021640907FE27480F00586F0F0F0F0DD8A +:10160C00DC021640F0F0F0F0F0F0DDF87D0205861B +:10161C00907FE27400F0907F9BE05404B4000505C9 +:10162C0086021640907FE27480F00586F0F0F0F0B0 +:10163C00F0F0DDDA907FE27400F0D085D08405867E +:10164C00D083D082D0E0FCD0E0FDD0E0FED0E0FF33 +:05165C00D0E0D0D02217 +:10166100C0D0C0E0C082C08390767CE0907F6FF0F4 +:1016710090767DE0907F6FF090767EE0907F6FF0C6 +:09168100D083D082D0E0D0D02249 +:10168A00C0D0C0E08FE0C0E08EE0C0E0C082C0837E +:10169A000586C084C085907687E0FFBF00030217E5 +:1016AA0001907F96E04480F0907FE27480F0907F12 +:1016BA0062E00586907FE27400F0907F96E0547FA6 +:1016CA00F0907FE27480F090768EE0B40105058692 +:1016DA000216F6B4020505860216EB05860216FB0B +:1016EA00E0E0E0E0E0E0DFF80216FBE0E0E0E0DF67 +:1016FA00FA907FE27400F0D085D0840586D083D03A +:0C170A0082D0E0FED0E0FFD0E0D0D02282 +:10171600C082C083C0E0E8C0E078D1E814F870FB6E +:0A172600D0E0F8D0E0D083D082229A +:10173000C082C083C0E0E8C0E07878E814F870FBAD +:0A174000D0E0F8D0E0D083D0822280 +:07174A00907FC57402F0223C +:10175100907EC0E0907645F0907EC1E0907644F0B6 +:10176100907EC2E0907643F0B40003021778907641 +:10177100197403F002178E907644E0B4BB09907699 +:10178100197402F002178E9076197401F090764266 +:03179100E4F0225F +:041794008D298B2AE6 +:10179800124A55EA4960571236927E0029FFEE3AFE +:1017A800C9EFC9752BFFF52C892DAB2BAA2CA92DB8 +:1017B8009000011236ABFF64046005EF6405702EDB +:1017C800EFB404159000021236AB6529700B900037 +:1017D800031236AB652A7001221236927E0029FF69 +:1017E800EE3AC9EFC9752BFFF52C892D80BC7B001B +:0417F8007A007900FA +:0117FC0022CA +:0317FD00C28B326A +:10180000907690E014603714700201D814700221B1 +:1018100072147002413B240460026103907FFC74E7 +:10182000CCF0907FFF74FCF0907695E04401F0548A +:1018300005F0908001F0E490761AF0C22E229076A6 +:1018400095E04401F04402F0303E06E04404F080AC +:1018500007907695E054FBF090761AE0B40108907A +:101860007695E0908001F0907619E0FFB401229027 +:101870007FFC7474F0907FFF74FCF090768F742B73 +:10188000F0907697E054FDF0E4907681F0907680C9 +:10189000F0EFB40222907FFC7468F0907FFF74FC3C +:1018A000F090768F742FF0907697E04402F0E490F9 +:1018B0007681F0907680F0303F09907697E054FE84 +:1018C000F08007907697E04401F0907697E054FB23 +:1018D000F0908002F0D22E22907695E054FEF044F3 +:1018E00002F0303E06E04404F08007907695E05424 +:1018F000FBF090761AE0B40108907695E0908001B4 +:10190000F0907619E0FFB40122907FFC7430F090E3 +:101910007FFF74FCF090768F742BF0907697E054F4 +:10192000FDF0E4907681F0907680F0EFB4022290A2 +:101930007FFC741CF0907FFF74FCF090768F742F06 +:10194000F0907697E04402F0E4907681F090768013 +:10195000F0303F09907697E054FEF080079076973C +:10196000E04401F0907697E054FBF0908002F0D2D2 +:101970002E22907695E04401F04402F04408F030C5 +:101980003E06E04404F08007907695E054FBF0902A +:10199000761AE0B40108907695E0908001F0907698 +:1019A00019E0FFB40125907FFC74CCF0907FFF74A8 +:1019B000FCF090768F742BF0907697E054FDF05405 +:1019C000FBF0E4907681F0907680F0EFB402259001 +:1019D0007FFC74C8F0907FFF74FCF090768F742FBA +:1019E000F0907697E04402F054FBF0E4907681F0BA +:1019F000907680F0EFB40325907FFC7498F0907F90 +:101A0000FF74FCF090768F745FF0907697E054FD51 +:101A1000F04404F0E4907681F0907680F0303F0955 +:101A2000907697E054FEF08007907697E04401F0BE +:101A3000907697E0908002F0D22E22907695E05436 +:101A4000FEF04402F04408F0303E06E04404F0802A +:101A500007907695E054FBF090761AE0B401089078 +:101A60007695E0908001F0907619E0FFB401259022 +:101A70007FFC74B4F0907FFF74FCF090768F742B31 +:101A8000F0907697E054FDF054FBF0E4907681F00E +:101A9000907680F0EFB40225907FFC74B0F0907FD8 +:101AA000FF74FCF090768F742FF0907697E04402EC +:101AB000F054FBF0E4907681F0907680F0EFB40380 +:101AC00025907FFC7468F0907FFF74FCF090768F17 +:101AD000745FF0907697E054FDF04404F0E4907663 +:101AE00081F0907680F0303F09907697E054FEF0D8 +:101AF0008007907697E04401F0907697E09080021E +:041B0000F0D22E22CF +:101B0400302C38C22C907619E0FFB4010E90767C0C +:101B140074C0F0A37414F0A3740BF0EFB4020DE4DA +:101B240090767CF0A37410F0A3740CF0EFB4030B64 +:0C1B3400E490767CF0A37418F0A3F0227B +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:0E1EB000000000000000000000000000000024 +:101EBE000000000000000000000000000000000014 +:101ECE000000000000000000000000000000000004 +:101EDE0000000000000000000000000000000000F4 +:101EEE0000000000000000000000000000000000E4 +:101EFE0000000000000000000000000000000000D4 +:101F0E0000000000000000000000000000000000C3 +:101F1E0000000000000000000000000000000000B3 +:101F2E0000000000000000000000000000000000A3 +:021F3E000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:1020000000000000000000000000000000000000D0 +:1020100000000000000000000000000000000000C0 +:1020200000000000000000000000000000000000B0 +:1020300000000000000000000000000000000000A0 +:102040000000000000000000000000000000000090 +:102050000000000000000000000000000000000080 +:102060000000000000000000000000000000000070 +:102070000000000000000000000000000000000060 +:102080000000000000000000000000000000000050 +:102090000000000000000000000000000000000040 +:1020A0000000000000000000000000000000000030 +:1020B0000000000000000000000000000000000020 +:1020C0000000000000000000000000000000000010 +:1020D0000000000000000000000000000000000000 +:1020E00000000000000000000000000000000000F0 +:1020F00000000000000000000000000000000000E0 +:1021000000000000000000000000000000000000CF +:1021100000000000000000000000000000000000BF +:1021200000000000000000000000000000000000AF +:10213000000000000000000000000000000000009F +:10214000000000000000000000000000000000008F +:10215000000000000000000000000000000000007F +:10216000000000000000000000000000000000006F +:10217000000000000000000000000000000000005F +:10218000000000000000000000000000000000004F +:10219000000000000000000000000000000000003F +:1021A000000000000000000000000000000000002F +:1021B000000000000000000000000000000000001F +:1021C000000000000000000000000000000000000F +:1021D00000000000000000000000000000000000FF +:1021E00000000000000000000000000000000000EF +:1021F00000000000000000000000000000000000DF +:1022000000000000000000000000000000000000CE +:1022100000000000000000000000000000000000BE +:1022200000000000000000000000000000000000AE +:10223000000000000000000000000000000000009E +:10224000000000000000000000000000000000008E +:10225000000000000000000000000000000000007E +:10226000000000000000000000000000000000006E +:10227000000000000000000000000000000000005E +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000000000000000DE +:1023000000000000000000000000000000000000CD +:1023100000000000000000000000000000000000BD +:1023200000000000000000000000000000000000AD +:10233000000000000000000000000000000000009D +:10234000000000000000000000000000000000008D +:10235000000000000000000000000000000000007D +:10236000000000000000000000000000000000006D +:0E23700000000000000000000000000000005F +:10237E00000000000000000000000000000000004F +:10238E00000000000000000000000000000000003F +:10239E00000000000000000000000000000000002F +:1023AE00000000000000000000000000000000001F +:1023BE00000000000000000000000000000000000F +:1023CE0000000000000000000000000000000000FF +:1023DE0000000000000000000000000000000000EF +:1023EE0000000000000000000000000000000000DF +:1023FE0000000000000000000000000000000000CF +:10240E0000000000000000000000000000000000BE +:10241E0000000000000000000000000000000000AE +:10242E00000000000000000000000000000000009E +:10243E00000000000000000000000000000000008E +:10244E00000000000000000000000000000000007E +:10245E00000000000000000000000000000000006E +:10246E00000000000000000000000000000000005E +:10247E00000000000000000000000000000000004E +:10248E00000000000000000000000000000000003E +:10249E00000000000000000000000000000000002E +:1024AE00000000000000000000000000000000001E +:1024BE00000000000000000000000000000000000E +:1024CE0000000000000000000000000000000000FE +:1024DE0000000000000000000000000000000000EE +:1024EE0000000000000000000000000000000000DE +:1024FE0000000000000000000000000000000000CE +:10250E0000000000000000000000000000000000BD +:10251E0000000000000000000000000000000000AD +:10252E00000000000000000000000000000000009D +:10253E00000000000000000000000000000000008D +:10254E00000000000000000000000000000000007D +:10255E00000000000000000000000000000000006D +:10256E00000000000000000000000000000000005D +:10257E00000000000000000000000000000000004D +:10258E00000000000000000000000000000000003D +:10259E00000000000000000000000000000000002D +:1025AE00000000000000000000000000000000001D +:1025BE00000000000000000000000000000000000D +:1025CE0000000000000000000000000000000000FD +:1025DE0000000000000000000000000000000000ED +:1025EE0000000000000000000000000000000000DD +:1025FE0000000000000000000000000000000000CD +:10260E0000000000000000000000000000000000BC +:10261E0000000000000000000000000000000000AC +:10262E00000000000000000000000000000000009C +:10263E00000000000000000000000000000000008C +:10264E00000000000000000000000000000000007C +:10265E00000000000000000000000000000000006C +:10266E00000000000000000000000000000000005C +:10267E00000000000000000000000000000000004C +:10268E00000000000000000000000000000000003C +:10269E00000000000000000000000000000000002C +:1026AE00000000000000000000000000000000001C +:1026BE00000000000000000000000000000000000C +:1026CE0000000000000000000000000000000000FC +:1026DE0000000000000000000000000000000000EC +:0E26EE000000000000000000000000000000DE +:1026FC0000000000000000000000000000000000CE +:10270C0000000000000000000000000000000000BD +:10271C0000000000000000000000000000000000AD +:10272C00000000000000000000000000000000009D +:10273C00000000000000000000000000000000008D +:10274C00000000000000000000000000000000007D +:10275C00000000000000000000000000000000006D +:10276C00000000000000000000000000000000005D +:10277C00000000000000000000000000000000004D +:10278C00000000000000000000000000000000003D +:10279C00000000000000000000000000000000002D +:1027AC00000000000000000000000000000000001D +:1027BC00000000000000000000000000000000000D +:1027CC0000000000000000000000000000000000FD +:1027DC0000000000000000000000000000000000ED +:1027EC0000000000000000000000000000000000DD +:0527FC000000000022B6 +:10280100C220C221C22A907FE8E01237F9283000A5 +:10281100288C0128A2022A1F212A6A22293D802907 +:102821007D8129D1822A84A12ABAA200002ABF90DF +:102831007FE9E014601124FE602824FE603B24FC43 +:102841007040123FE541CB124E1D400241CB907FBB +:10285100EAE0B40104C22241CB907FB4E04401F02C +:1028610041CB124E1F907FEAE0B40104D22241CB4A +:10287100907FB4E04401F041CB907FB4E04401F09B +:1028810041CB907FB4E04401F041CB907FE9E0245B +:10289100F5700512486341CB907FB4E04401F041EB +:1028A100CB907FE9E024FD605424026002213412C0 +:1028B1004E1D400241CB907FEAE07038907FECE002 +:1028C100F45480FFC4540FFFE054072F25E024B4D3 +:1028D100F582E4347FF583E4F0907FECE05480FFEF +:1028E100131313541FFFE054072F907FD7F0E044D8 +:1028F10020F041CB907FB4E04401F041CB124E1F58 +:10290100400241CB907FEAE07020907FECE0F454EC +:1029110080FFC4540FFFE054072F25E024B4F58253 +:10292100E4347FF5837401F041CB907FB4E044013E +:10293100F041CB907FB4E04401F041CB907FE9E0DE +:10294100601224F86009240270291243E741CB1276 +:102951004DCA41CB124E1BA222E433FF25E0FFA258 +:1029610023E4334F907F00F0E4A3F0907FB574022D +:10297100F041CB907FB4E04401F041CB907FE9E09E +:10298100603324F6602A2404703D907FEBE024DE5E +:10299100600C047012907FB4E04401F041CB907F51 +:1029A100B4E04401F041CB907FB4E04401F041CB6D +:1029B10012474541CB124E1BE4907F00F0A3F090EB +:1029C1007FB57402F041CB907FB4E04401F041CB7C +:1029D100907FE9E024F46034240C7039124E1B908E +:1029E1007FECE0F45480FFC4540FFFE054072F251F +:1029F100E024B4F582E4347FF583E054FD907F0058 +:102A0100F0E4A3F0907FB57402F041CB907FB4E085 +:102A11004401F041CB907FB4E04401F041CB907F81 +:102A2100E9E024F6601214601A2402701DD220908D +:102A31007FB4E04401F08012D220907FB4E04401E1 +:102A4100F08007907FB4E04401F0202018907FEEE1 +:102A5100E07004A3E0600BD229D22712174AD22AD0 +:102A61008003120800C2208061907FEEE07004A311 +:102A7100E0600BD229D22812174AD22A804C123890 +:102A8100748047907FE9E024FE601214601A2402EA +:102A9100701DD221907FB4E04401F08012D22190C8 +:102AA1007FB4E04401F08007907FB4E04401F0205E +:102AB1002103121000C2218011122AD6800C124E5D +:102AC100215007907FB4E04401F0202A07907FB4A1 +:052AD100E04402F022C8 +:102AD600E4907627F0907627E0FF75F00FA4244265 +:102AE600F582E43475F583E0FE907FECE0FDEE6D53 +:102AF600600EEFC394065008907627E004F080D568 +:102B0600EFB40608907FB4E04401F022EF75F00FB1 +:102B1600A42441F582E43475F583E0907628F02408 +:102B26009F7002A17424216002A1A1907FE9E02494 +:102B36007E700261FC14700281B524026002A16CF1 +:102B4600EF75F00FA42443F582E43475F583E0FCB9 +:102B5600A3E0FDA3E0FEA3E0FF7B447AAC79007816 +:102B660000C31237AB7013907F007444F0A374ACAB +:102B7600F0E4A3F0907FB57403F0907627E075F04B +:102B86000FA42443F582E43475F583E0FCA3E0FD4D +:102B9600A3E0FEA3E0FF7B807ABB79007800C31236 +:102BA60037AB7013907F007480F0A374BBF0E4A37E +:102BB600F0907FB57403F0907627E075F00FA424AB +:102BC60043F582E43475F583E0FCA3E0FDA3E0FE63 +:102BD600A3E0FF7B007A7779017800C31237AB60F8 +:102BE60002A1A8907F00F0A37477F0A37401F0907F +:102BF6007FB57403F022907627E075F00FA4244782 +:102C0600F582E43475F583E0FCA3E0FDA3E0FEA3C2 +:102C1600E0FF7B447AAC79007800C31237AB7013BF +:102C2600907F007444F0A374ACF0E4A3F0907FB5F9 +:102C36007403F0907627E075F00FA42447F582E43C +:102C46003475F583E0FCA3E0FDA3E0FEA3E0FF7B83 +:102C5600807ABB79007800C31237AB7013907F007F +:102C66007480F0A374BBF0E4A3F0907FB57403F016 +:102C7600907627E075F00FA42447F582E43475F5C5 +:102C860083E0FCA3E0FDA3E0FEA3E0FF7B007A77F0 +:102C960079017800C31237AB6002A1A8907F00F0DB +:102CA600A37477F0A37401F0907FB57403F02290BB +:102CB6007627E075F00FA4244BF582E43475F5838E +:102CC600E0FCA3E0FDA3E0FEA3E0FF7B447AAC7941 +:102CD600007800C31237AB7013907F007444F0A3E2 +:102CE60074ACF0E4A3F0907FB57403F0907627E01F +:102CF60075F00FA4244BF582E43475F583E0FCA34C +:102D0600E0FDA3E0FEA3E0FF7B807ABB79007800BC +:102D1600C31237AB7013907F007480F0A374BBF0BE +:102D2600E4A3F0907FB57403F0907627E075F00F7A +:102D3600A4244BF582E43475F583E0FCA3E0FDA3FF +:102D4600E0FEA3E0FF7B007A7779017800C31237B3 +:102D5600AB704F907F00F0A37477F0A37401F090EE +:102D66007FB57403F022907FB4E04401F022907F97 +:102D7600E9E0247F701E907627E075F00FA4244FBB +:102D8600F582E43475F583E0907F00F0907FB574AA +:102D960001F08007907FB4E04401F0907FB4E044F6 +:032DA60001F02217 +:102DA900E4907636F0E0FF75F003A4240EF582E492 +:102DB9003475F5837401F0EF75F003A4240FF582DF +:102DC900E43475F5837401F0EF75F003A42410F56C +:102DD90082E43475F583E4F0907636E004F0E0FFA0 +:102DE90075F003A4240EF582E43475F5837410F0AC +:102DF900EF75F003A4240FF582E43475F5837405A7 +:102E0900F0EF75F003A42410F582E43475F583E43A +:102E1900F0907636E004F0E0FF75F003A4240EF597 +:102E290082E43475F5837402F0EF75F003A4240F7E +:102E3900F582E43475F5837402F0EF75F003A42488 +:102E490010F582E43475F583E4F0907636E004F009 +:102E5900E0FF75F003A4240EF582E43475F583745C +:102E690001F0EF75F003A4240FF582E43475F583BE +:102E79007403F0EF75F003A42410F582E43475F5BA +:102E890083E4F0907636E004F0E0FF75F003A424C3 +:102E99000EF582E43475F5837410F0EF75F003A430 +:102EA900240FF582E43475F5837406F0EF75F003A9 +:102EB900A42410F582E43475F583E4F0907636E0C5 +:102EC90004F0E0FF75F003A4240EF582E43475F5EF +:102ED900837402F0EF75F003A4240FF582E43475CE +:102EE900F5837404F0EF75F003A42410F582E4343B +:102EF90075F583E4F0907636E004F0E0FF75F003B1 +:102F0900A4240EF582E43475F5837402F0EF75F0AC +:102F190003A4240FF582E43475F5837408F0EF7582 +:102F2900F003A42410F582E43475F5837404F09059 +:102F39007636E004F0E0FF75F003A4240EF582E490 +:102F49003475F5837402F0EF75F003A4240FF5824C +:102F5900E43475F583740AF0EF75F003A42410F5D1 +:102F690082E43475F5837404F0907636E004F0E079 +:102F7900FF75F003A4240EF582E43475F583740219 +:102F8900F0EF75F003A4240FF582E43475F583742A +:102F990009F0EF75F003A42410F582E43475F58384 +:102FA9007404F0907636E004F0E0FF75F003A42491 +:102FB9000EF582E43475F5837402F0EF75F003A41D +:102FC900240FF582E43475F5837407F0EF75F00387 +:0E2FD900A42410F582E43475F5837404F0220C +:102FE700C0E0C083C082D2265391EF907FAB7401BB +:082FF700F0D082D083D0E0325B +:012FFF00329F +:10300000907FB6E020E102C23DD236203602416E0A +:10301000303D02416E908007E06004D2368002C2EB +:1030200036203602412ED235E4F51A908004E0F5C0 +:10303000197408250EF8A619851918E51820E70453 +:10304000D2388002C23830380221D4E4F516E519AE +:10305000B4F00CD2397508047509F0050E8002052C +:1030600016E51964F7703DC239E50E24FE601714A9 +:103070006022240370297508057509F7E4F50AF53F +:103080000B750E048020750806750AF7E4F50B75BC +:103090000E048012750807750BF7750E0480071271 +:1030A0004DDA80020516E51954F864F8703BC23514 +:1030B000E5192407600C24FC6008240524F8500658 +:1030C0008008D23A8006C23A8002D23A751A0120AC +:1030D0003A19907E80740FF0A3E519F0E4A3F0A3F1 +:1030E000F0907FB77404F08002051620396DE51961 +:1030F00064F76067E51A7063E51854F064F070597E +:10310000851819F50EE519240F601B24FE6017249D +:10311000FD602214601F2405702F750803050E85BD +:103120001809D2378028750802050E85180975140C +:1031300001D2378019750805050E851809E4F50ACE +:10314000F50B750E03D2378005124DDAC2353035D6 +:103150000A85081385181280020516851819E516C8 +:1031600064047062F50EE51954F0F519F51585182B +:1031700019E5152470601824F0601424F060102400 +:10318000F0601E24F0601A24F0600424607027E5CB +:1031900015C4540FF519F508050E851809D23780A6 +:1031A0001AE515C4540FF519F508050E85180975AB +:1031B0001401D2378005124DDAC23530350A85192F +:1031C0001385181280020516E516D3940540571290 +:1031D0004DDA8052303917E50E700A8508097508F6 +:1031E00004050E80417408250EF8A6198038203792 +:1031F0002AE50EB4010F85080A85090B8513088599 +:103200001209750E04E514B4011C85080AE4F50BD7 +:10321000851308851209750E04800BE514B40106A8 +:10322000E4F50B750E04E4F51A303502050EE50ED3 +:10323000D394035002010BC237E4F50EF510C236E9 +:10324000D23DF51474082510F8E6FF74802510F5BA +:1032500082E4347EF583EFF074082510F8E4F60577 +:0F32600010E510B404DE907FB77404F0010B2268 +:10326F00907618E0FF640570429075ABE0B40119D9 +:10327F009072377401F0E4908020F0908031F090DC +:10328F008028F0908039F08022E4907237F09075AA +:10329F00ADE090722BF0E02480F0E0908020F09071 +:1032AF008031F0908028F0908039F0EF6406600252 +:1032BF0081999072397404F0907239E0FF24FE9076 +:1032CF007204F0EF75F00AA424ABF582E43475F5BF +:1032DF0083E06401705490723604F0907204E0FF42 +:1032EF0024FD602824FE6024240324FB5004601C6A +:1032FF00818C74202FF582E43480F583E4F07428F8 +:10330F002FF582E43480F583E4F0818C907204E031 +:10331F00FF2430F582E43480F583E4F074382FF520 +:10332F0082E43480F583E4F0818CE4907236F0907F +:10333F007239E075F00AA424ADF582E43475F58393 +:10334F00E0FF7E0090750CEEF0A3EFF07006907228 +:10335F0002743BF090750CE0FEA3E0FF64804E70AA +:10336F0004907202F0EF4E70028135EF64804E7060 +:10337F00028135EFF8E490750DF0E890750CF09040 +:10338F007234E075F00AA424ACF582E43475F58349 +:10339F00E0FF907202F090750DE02FF090750CE049 +:1033AF003400F0E0FEA3E0FFE4FCFD7BD67AA5F944 +:1033BF00F8D3123795400A90750C74A5F0A374D604 +:1033CF00F090750DE0242AF090750CE0345AF0E07F +:1033DF00FEA3E07805CEA2E713CE13D8F8FF9075C1 +:1033EF000CEEF0A3EFF090722CEEF0A3EFF0D3946D +:1033FF00D2EE64809482400A90722C7402F0A3740F +:10340F00D2F0C390722CE0648094805004E4F0A357 +:10341F00F090722CE0FEA3E0243AF582EE3472F5C0 +:10342F0083E0907202F0907204E0FF24FD602D247F +:10343F00FE6029240324FB50046021804090720217 +:10344F00E0FE74202FF582E43480F583EEF07428CB +:10345F002FF582E43480F583EEF08021907202E044 +:10346F00FF907204E0FE2430F582E43480F583EFA0 +:10347F00F074382EF582E43480F583EFF0907239D2 +:0B348F00E004F0E0640A600241C72284 +:10349A00907618E0FFB40523907237E0701D90759E +:1034AA00ADE090722BF0E02480F0E0908020F09064 +:1034BA008031F0908028F0908039F0EF6406600245 +:1034CA00C191907236E06002C191907640E070310D +:1034DA009072037403F0907203E0FF75F00AA4245B +:1034EA00AAF582E43475F583E0FE907229E0FDEED8 +:1034FA006D600EEFC3940A5008907203E004F080E6 +:10350A00D59072397404F0907640E0700890720396 +:10351A00E0907239F0907239E0FD24FE90722AF040 +:10352A00ED75F00AA424ADF582E43475F583E0FF65 +:10353A007E0090750CEEF0A3EFF0700690720274A4 +:10354A0080F090750CE0FEA3E0FF64804E7004905A +:10355A007202F0EF4E7002C11BEF64804E7002C11E +:10356A001BEFF8E490750DF0E890750CF0ED75F02E +:10357A000AA424ACF582E43475F583E0FF90720264 +:10358A00F090750DE02FF090750CE03400F0E0FE3D +:10359A00A3E0FFE4FCFD7BD67AA5F9F8D3123795B0 +:1035AA00400A90750C74A5F0A374D6F090750DE0DE +:1035BA00242AF090750CE0345AF0E0FEA3E0780576 +:1035CA00CEA2E713CE13D8F8FF90750CEEF0A3EF56 +:1035DA00F090722CEEF0A3EFF0D394D2EE648094C4 +:1035EA0082400A90722C7402F0A374D2F0C39072D3 +:1035FA002CE0648094805004E4F0A3F090722CE0F4 +:10360A00FEA3E0243AF582EE3472F583E09072026A +:10361A00F090722AE0FF24FD602D24FE6029240325 +:10362A0024FB500460218040907202E0FE74202F37 +:10363A00F582E43480F583EEF074282FF582E434C1 +:10364A0080F583EEF08021907202E0FF90722AE00A +:10365A00FE2430F582E43480F583EFF074382EF5D9 +:10366A0082E43480F583EFF0907640E07006907241 +:10367A0039740AF0907239E004F0E0C3940A5002F7 +:08368A00A111E4907640F0224A +:10369200BB010689828A83E0225002E722BBFE0236 +:0936A200E32289828A83E4932269 +:1036AB00BB010CE58229F582E5833AF583E02250D4 +:1036BB0006E92582F8E622BBFE06E92582F8E2221E +:0D36CB00E58229F582E5833AF583E4932238 +:1036D800C2D5EC30E709B2D5E4C39DFDE49CFCEE0D +:1036E80030E715B2D5E4C39FFFE49EFE12381FC32E +:1036F800E49DFDE49CFC800312381F30D507C3E429 +:063708009FFFE49EFE227B +:10370E00BB0110E58229F582E5833AF583E0F5F0F9 +:10371E00A3E0225009E92582F886F008E622BBFED6 +:10372E000AE92582F8E2F5F008E222E5832AF5831C +:08373E00E993F5F0A3E99322E1 +:10374600E88FF0A4CC8BF0A42CFCE98EF0A42CFC22 +:103756008AF0EDA42CFCEA8EF0A4CDA8F08BF0A4A0 +:103766002DCC3825F0FDE98FF0A42CCD35F0FCEBFF +:103776008EF0A4FEA9F0EB8FF0A4CFC5F02ECD39C4 +:0F378600FEE43CFCEAA42DCE35F0FDE43CFC2231 +:10379500EB9FF5F0EA9E42F0E99D42F0EC6480C8AB +:0637A50064809845F0224B +:1037AB00EB9FF5F0EA9E42F0E99D42F0E89C45F074 +:0137BB0022EB +:0C37BC00ECF0A3EDF0A3EEF0A3EFF02280 +:1037C800A8828583F0D083D0821237DF1237DF12C8 +:1037D80037DF1237DFE473E493A3C583C5F0C583ED +:1037E800C8C582C8F0A3C583C5F0C583C8C582C84B +:0137F80022AE +:1037F900D083D082F8E4937012740193700DA3A35F +:1038090093F8740193F5828883E473740293686072 +:06381900EFA3A3A380DF72 +:10381F00BC000BBE0029EF8DF084FFADF022E4CC8D +:10382F00F875F008EF2FFFEE33FEEC33FCEE9DEC56 +:10383F00984005FCEE9DFE0FD5F0E9E4CEFD22ED9C +:10384F00F8F5F0EE8420D21CFEADF075F008EF2FE6 +:10385F00FFED33FD4007985006D5F0F222C398FDD7 +:05386F000FD5F0EA2274 +:10387400E4907629F0907629E0FF75F00FA42442B5 +:10388400F582E43475F583E0FE907FECE0FDEE6DA7 +:10389400600EEFC394065008907629E004F080D5BA +:1038A400EFB40608907FB4E04401F022EF75F00F06 +:1038B400A42441F582E43475F583E090762AF0245B +:1038C400BF7002414124E070024112242160024190 +:1038D4003A907FE9E024FE607D14700221B2240254 +:1038E4006002410A121751907642E0FCA3E0FDA366 +:1038F400E0FEA3E0FF907629E075F00FA42443F5E1 +:1039040082E43475F5831237BC907619E0FFB40174 +:103914001290767C7467F090767D7406F090767ED3 +:10392400740BF0EFB4020FE490767CF090767DF0A7 +:1039340090767E740CF0EFB4030FE490767CF090F4 +:10394400767DF090767E7418F090761A7401F012F9 +:103954003E9F12180022907EC2E0FFE4FCFDFEFBB5 +:10396400FA7901F8123746C8ECC8C9EDC9CAEECADB +:10397400CBEFCB907EC1E0FEE4FCFD2BFBEA3EFAEC +:10398400ED39F9EC38F8907EC0E0FFE4FEEB2FFF50 +:10399400EE3AFEED39FDEC38FC907629E075F00F37 +:1039A400A42447F582E43475F5831237BC22907E53 +:1039B400C2E0FFE4FCFDFEFBFA7901F8123746C8C9 +:1039C400ECC8C9EDC9CAEECACBEFCB907EC1E0FE0C +:1039D400E4FCFD2BFBEA3EFAED39F9EC38F8907E75 +:1039E400C0E0FFE4FEEB2FFFEE3AFEED39FDEC38CC +:1039F400FC907629E075F00FA4244BF582E434752D +:103A0400F5831237BC22907FB4E04401F022907F0A +:103A1400E9E0147019907EC0E0FF907629E075F01B +:103A24000FA4244FF582E43475F583EFF022907FE0 +:0E3A3400B4E04401F022907FB4E04401F0229F +:103A4200E4907635F0907635E0FFC394034002416E +:103A5200FFEF75F00AA424AAF582E43475F583EF2A +:103A6200F0EF75F00AA424ABF582E43475F583E433 +:103A7200F0EF75F00AA424ACF582E43475F5837492 +:103A8200F0F0EF75F00AA424ADF582E43475F58305 +:103A920074FFF0EF75F00AA424AEF582E43475F5F4 +:103AA20083E4F0EF75F00AA424AFF582E43475F5EF +:103AB200837480F0EF75F00AA424B0F582E43475C3 +:103AC200F583E4F0EF75F00AA424B1F582E43475CD +:103AD200F583E4F0EF75F00AA424B2F582E43475BC +:103AE200F583E4F0EF75F00AA424B3F582E43475AB +:103AF200F5837401F0907635E004F0414790763C0E +:103B0200740AF0E4A3F09076357403F090763CE00A +:103B1200FF907635E0FEC39F400261D290763DE091 +:103B2200FF04F0EE75F00AA424AAF582E43475F5D8 +:103B320083EFF0EE75F00AA424ABF582E43475F558 +:103B420083E4F0EE75F00AA424ACF582E43475F552 +:103B520083745EF0EE75F00AA424ADF582E4347548 +:103B6200F58374BAF0EE75F00AA424AEF582E4345B +:103B720075F5837405F0EE75F00AA424AFF582E4BE +:103B82003475F5837480F0EE75F00AA424B0F582E2 +:103B9200E43475F583E4F0EE75F00AA424B1F582FD +:103BA200E43475F583E4F0EE75F00AA424B2F582EC +:103BB200E43475F5837415F0EE75F00AA424B3F5B8 +:103BC20082E43475F583E4F0907635E004F0610E1A +:013BD20022D0 +:103BD300E4907636F0E0FB75F00FA42441F582E41F +:103BE3003475F5837440F0EB75F00FA42442F5822D +:103BF300E43475F583740AF0EB75F00FA42443F5F0 +:103C030082E43475F5831237C80000AC44EB75F0D9 +:103C13000FA42447F582E43475F5831237C80000F6 +:103C2300AC44EB75F00FA4244BF582E43475F583B3 +:103C33001237C800017700907636E004F0E0FB7598 +:103C4300F00FA42441F582E43475F5837440F0EB5E +:103C530075F00FA42442F582E43475F583748CF077 +:103C6300EB75F00FA42443F582E43475F583123722 +:103C7300C80000AC44EB75F00FA42447F582E4348C +:103C830075F5831237C80000AC44EB75F00FA4241C +:103C93004BF582E43475F5831237C8000177009041 +:103CA3007636E004F0E0FF75F00FA42441F582E4DA +:103CB3003475F5837440F0EF75F00FA42442F58258 +:103CC300E43475F583748FF0907636E004F0E0FF0A +:103CD30075F00FA42441F582E43475F5837441F043 +:103CE300EF75F00FA42442F582E43475F5837484F0 +:103CF300F0907636E004F0E0FF75F00FA42441F570 +:103D030082E43475F5837461F0EF75F00FA42442F7 +:103D1300F582E43475F5837481F0907636E004F02F +:103D2300E0FF75F00FA42441F582E43475F5837444 +:103D330061F0EF75F00FA42442F582E43475F58346 +:043D43007401F022F5 +:103D4700C0E0C0F0C083C082C0D0E8C0E0E9C0E0F6 +:103D5700EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFB1 +:103D6700C0E0907FA2E090767FF0907F74E090763D +:103D770087F0907F75E0907688F0907F98E0440216 +:103D8700F0907696E0FF20E10C4402F0908003F07B +:103D9700D232124B2890767FE020E250907687E06F +:103DA700FEA3E07C002400F534EC3EF533907698D2 +:103DB700E0FDAE33AF341236D8907687EFF0D22FCE +:103DC700303129203F26C231907F94E054CFF090C4 +:103DD7007F9AE030E404D22DC22C907F9AE020E550 +:103DE70004C22DD22C907F94E04430F01248BD12CB +:103DF7001B04302F1212421FC22F75E80112168AB8 +:103E070075E80DD22B800575E801C22B202B349065 +:103E17007619E0FFB4010E90767C7467F0A3740600 +:103E2700F0A3740BF0EFB4020B90767CE4F0A3F0F0 +:103E3700A3740CF0EFB4030B90767CE4F0A3F0A32B +:103E47007418F075CAD375CBFED2CA303404C234A5 +:103E57008002D23430340D907689E0C39403400455 +:103E6700E024FDF05391EF907FAB7402F0F0907F68 +:103E770098E054FDF0D0E0FFD0E0FED0E0FDD0E0C8 +:103E8700FCD0E0FBD0E0FAD0E0F9D0E0F8D0D0D019 +:083E970082D083D0F0D0E032AC +:103E9F00907692E014601D147002E15424026002C7 +:103EAF00E1E49076947401F0908000F0E490768EC7 +:103EBF00F0D23122907619E0FFB4011BE4907FF22B +:103ECF00F0907FF37430F0907FFF74FCF090769752 +:103EDF00E054FDF054FBF0EFB4021BE4907FF2F0DE +:103EEF00907FF37434F0907FFF74FCF0907697E03E +:103EFF004402F054FBF0EFB40318E4907FF2F0901B +:103F0F007FF37464F0907FFF74FCF0907697E04439 +:103F1F0004F0907694E04401F0908000F0303F0977 +:103F2F00907697E054FEF08007907697E04401F08A +:103F3F00907697E0908002F09076987404F09076E7 +:103F4F008E7401F022907619E0FFB4011BE4907F8C +:103F5F00F2F0907FF37444F0907FFF74FCF0907652 +:103F6F0097E054FDF054FBF0EFB4021BE4907FF2A6 +:103F7F00F0907FF3744CF0907FFF74FCF090769785 +:103F8F00E04402F054FBF0EFB40318E4907FF2F03A +:103F9F00907FF37494F0907FFF74FCF0907697E02D +:103FAF004404F0907694E054FEF0908000F0303F9F +:103FBF0009907697E054FEF08007907697E04401E1 +:103FCF00F0907697E0908002F09076987406F090DB +:063FDF00768E7402F02250 +:103FE500907FEAE0907682F0E4907691F090769278 +:0B3FF500F0907690F0907693F0D322CD +:10400000E511D3940050022106907689E0C394080C +:10401000400221067440250FF582E4347EF583E0EA +:10402000F517E50D600E908005E517F0907689E0B4 +:1040300004F001DAE5171237F940C1024067054084 +:104040007A0640980740C10C40C10D40C70F40CBD5 +:10405000F640CBF840CBFA40CBFB40CBFC40CBFE4C +:1040600040CBFF000040DA907E41E0908005F09068 +:104070007689E004F07511018060907E41E09080C7 +:1040800005F0907E42E0908005F0907689E004F0A3 +:10409000E004F07511018042907E41E0908005F0CF +:1040A000907E42E0908005F0907E43E0908005F0A5 +:1040B000907689E004F0E004F0E004F075110180EE +:1040C00019D23BD23C8013D23B800F908005E5177C +:1040D000F0907689E004F0751101203B04050D8015 +:1040E0001F303C1C907E41E0908005F0907E42E0C5 +:1040F000908005F0907689E004F0E004F0751101FD +:10410000050F15110100E5117010C233F50DF50F03 +:0B411000907FC77404F0C23BC23C2249 +:10411B0090768DE064017027302708C227120800C3 +:10412B0012174A302808C22812387412174A302A3C +:10413B000EE490768DF0C22A907FB4E04402F090AA +:10414B00763FE0B40105E4F012326F907641E0B4B3 +:10415B000105E4F012349A907640E0B40103123476 +:10416B009A123000303303124000907F9BE020E422 +:10417B0002C23F907F9BE030E402D23F907F9BE0F6 +:10418B0020E502C23E907F9BE030E502D23EA24189 +:10419B00303F01B3501FA23F9241303F09907697B9 +:1041AB00E054FEF08007907697E04401F09076970C +:1041BB00E0908002F0303F34907619E0FFB4010EAE +:1041CB0090767C7467F0A37406F0A3740BF0EFB4D5 +:1041DB00020BE490767CF0A3F0A3740CF0EFB40325 +:1041EB000BE490767CF0A3F0A37418F0A240303E61 +:1041FB0001B3501FA23E9240303E09907695E044A9 +:10420B0004F08007907695E054FBF0907695E09063 +:04421B008001F0220C +:10421F00907619E064017035907687E0FFD3942D86 +:10422F00402B9076867401F0907685E004F0E0D311 +:10423F00940F4019E4F0EFD394314008907619743D +:10424F0003F080069076197402F0123E9F90761953 +:10425F00E0B4022C907687E0FFC3942F5022EFD367 +:10426F00942A401C9076867401F0907685E004F0D5 +:10427F00E0D3940F400AE4F090761904F0123E9FB9 +:10428F00907619E0B40226907687E0D39431401DE2 +:10429F009076867401F0907685E004F0E0D3940F69 +:1042AF00400BE4F09076197403F0123E9F9076194C +:1042BF00E06403703F907687E0FFC3945F503590C2 +:1042CF0076867401F0907685E004F0E0D3940F4089 +:1042DF0023E4F0EFC3942F500CEFD3942A400690B1 +:1042EF0076197401F0EFD3942F400690761974026B +:1042FF00F0123E9F907686E07005907685F022E46E +:05430F00907686F0220B +:10431400E4907696F0908003F0907FE07490F090B3 +:104324007FE17404F0E4907FDDF0907FA1F0538E80 +:10433400F875880575B82075F801438E30F5C87591 +:10434400CA7F75CBF843A820124565C22CC22DC282 +:104354002BC22F907FFC74DDF0907FFF74FFF090F0 +:104364007F97E04401F09076197401F0E49076852B +:10437400F0A3F0907681F0907680F01249AE120F9F +:10438400C6124AF1907F97E04408F0E054B9F0D2A5 +:1043940030203018124AA612300012400012421F78 +:1043A4001248BD121B0412166112421F124AA6C201 +:1043B4002FC231C232C234C233C229C227C228E456 +:1043C400F511907689F090763FF0907641F09076F2 +:1043D40040F090768AF0A3F0A304F0E4A3F0907682 +:0343E40099F0222B +:1043E700124E19400281AC907FEBE024FE601E1450 +:1043F700604614606E147002819D2404600281A5DA +:104407007405907FD4F07400907FD5F022907FEAF6 +:10441700E0FF124A558B208A218922EA496011CE92 +:10442700EACEEE907FD4F0CFE9CFEF907FD5F022A0 +:10443700907FB4E04401F022907FEAE0FF1247B793 +:104447008B208A218922EA496011CEEACEEE907F3D +:10445700D4F0CFE9CFEF907FD5F022907FB4E0443E +:1044670001F022907FEAE0FF907EC0E0FDA3E0FB31 +:104477001217948B208A218922EA496011CEEACE4D +:10448700EE907FD4F0CFE9CFEF907FD5F022907FE9 +:10449700B4E04401F022907FB4E04401F022907F21 +:0544A700B4E04401F047 +:0144AC0022ED +:1044AD00C2AFD224907F937430F0907F9C74BBF098 +:1044BD00907F96E04430F0E05430F0907F9474306B +:1044CD00F0907F9D74CFF0907F9774A0F0907F95C2 +:1044DD0074C0F0907F9E7403F0907F99E030E209F4 +:1044ED0090051974A0F0E4A3F0C225C222C223C224 +:1044FD0026124B28122DA9123BD3124619123A42FD +:10450D009076687401F0700F124C29124E15124EF0 +:10451D0017121B40121496124314907FAFE0440102 +:10452D00F0907FAEE0441FF0907FAC74FFF0907F71 +:10453D00ADF0907FDEF0907FDFF0907FABF0907F5D +:10454D00A9F0907FAAF05391EF43D820D2E843D839 +:08455D002053A8A043A880220E +:1045650090769A7402F0E4907691F0A3F0907690AC +:10457500F0907693F09076967403F0908003F0E4D3 +:10458500907697F0908002F090769404F0908000F9 +:10459500F0E490768EF090761AF090769504F0C25D +:1045A5002E907F9BE0FF5410FF7002C23F907F9BCF +:1045B500E0FF5410FEFFBE1002D23F907F9BE0FF4C +:1045C5005420FF7002C23E907F9BE0FF5420FEFF07 +:1045D500BE2002D23E303F09907697E054FEF0802F +:1045E50007907697E04401F0907697E0908002F08E +:1045F500303E09907695E04404F08007907695E08A +:1046050054FBF0907695E0908001F0A23E9240A296 +:034615003F924190 +:01461800227F +:10461900E4907636F0E0FF75F003A42432F582E4E5 +:104629003475F583E4F0EF75F003A42433F582E4DF +:104639003475F5837401F0907636E004F0E0FF7587 +:10464900F003A42432F582E43475F583E4F0EF75C0 +:10465900F003A42433F582E43475F5837402F090F1 +:104669007636E004F0E0FF75F003A42432F582E425 +:104679003475F583E4F0EF75F003A42433F582E48F +:104689003475F5837403F0907636E004F0E0FF7535 +:10469900F003A42432F582E43475F583E4F0EF7570 +:1046A900F003A42433F582E43475F5837404F0220D +:0C46B900787FE4F6D8FD758138024700D8 +:1046C5000207A6E493A3F8E493A34003F68001F25E +:1046D50008DFF48029E493A3F85407240CC8C333F6 +:1046E500C4540F4420C8834004F456800146F6DFC5 +:1046F500E4800B0102040810204080900C8FE47EBA +:10470500019360BCA3FF543F30E509541FFEE493B9 +:10471500A360010ECF54C025E060A840B8E493A380 +:10472500FAE493A3F8E493A3C8C582C8CAC583CAAB +:10473500F0A3C8C582C8CAC583CADFE9DEE780BE63 +:10474500907FECE0907683F0E014601D14602A14ED +:10475500603714604424047050907691E0907F0097 +:10476500F0907FB57401F08047907692E0907F00DD +:10477500F0907FB57401F08037907690E0907F00DF +:10478500F0907FB57401F08027907684E0907F00EB +:10479500F0907FB57401F08017907693E0907F00DC +:1047A500F0907FB57401F08007907FB4E04401F08C +:0247B500D3220D +:0247B7008F2E43 +:1047B900E4F52F7530FF75310775321AAB30AA3120 +:1047C900A9329000011236ABB4031FAF2F052FEFAA +:1047D900652E7001221236927E0029FFEE3AC9EF4A +:1047E900C97530FFF531893280D27B007A007900B2 +:0147F900229D +:0647FA00124B28C231221F +:10480000C0E0C0F0C083C082C0D0E8C0E0E9C0E032 +:10481000EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFED +:10482000C0E0C2CAC2CF907F98E04401F0302E03AE +:104830001214A6907F98E054FEF053A8FA12166165 +:10484000D0E0FFD0E0FED0E0FDD0E0FCD0E0FBD037 +:10485000E0FAD0E0F9D0E0F8D0D0D082D083D0F028 +:03486000D0E03273 +:10486300907FECE0907683F0E014601714602114DD +:10487300602B14603224047038907FEAE0907691C4 +:10488300F08035907FEAE0907692F0123E9F802888 +:10489300907FEAE0907690F0121800801B907FEAF8 +:1048A300E0907684F08011907FEAE0907693F08038 +:0A48B30007907FB4E04401F0D32227 +:1048BD00302D39C22D907619E0FFB4010DE49076BC +:1048CD007CF0A374F8F0A3740AF0EFB4020DE49039 +:1048DD00767CF0A374F0F0A3740BF0EFB4030DE449 +:0D48ED0090767CF0A374F8F0A37417F0220D +:0648FA005391BFD22D32E4 +:10490000022FE700023D4700024DB400024C430075 +:10491000024BE900022FFF00024C5B00024C0A0030 +:10492000024C7200024B5A00024C8900024CA0005B +:10493000024CB700024CCE00024CE500024CFC00D9 +:10494000024D1300024D2A00024D4100024D580055 +:08495000024D6F00024D8600CC +:10495800E4907626F0907626E0FF75F003A42434E0 +:10496800F582E43475F583E0FE907FECE0FDEE6DB2 +:10497800600EEFC394045008907626E004F080D5CA +:10498800EFB40408907FB4E04401F022EF75F0031F +:10499800A42432F582E43475F583E0907F00F0902A +:0649A8007FB57401F0224E +:1049AE009076467480F0E4A3F0A3F0A3F0A3F0A3F6 +:1049BE00F0A3F0A3F0A3F0A37480F0E4A3F0A3F0AF +:1049CE00A3F0A3F0A3F0A3F0A37440F0E4A3F0A32C +:1049DE007440F0E4A3F0A3F0A3F0A3F0A3F0A3F0CF +:1049EE00A37440F0E4A3F0A37440F0E4A3F0A3F0AA +:0549FE00A3F0A3F0226C +:104A0300E4907625F0907625E0FF75F003A4243436 +:104A1300F582E43475F583E0FE907FECE0FDEE6D06 +:104A2300600EEFC394045008907625E004F080D51F +:104A3300EFB40408907FB4E04401F022907EC0E01C +:104A4300FEEF75F003A42432F582E43475F583EEAA +:024A5300F0224F +:104A5500E4FE751DFF751E05751F12AB1DAA1EA967 +:104A65001F9000011236AB6402702FCDEECD0EED16 +:104A75006F70012290000212370E85F01BF51C6243 +:104A85001BE51B621CE51C621B29FDE51B3AC9EDF4 +:104A9500C9751DFFF51E891F80C17B007A0079004D +:014AA50022EE +:104AA600E490769BF090769BE0FF04F0EF6008E0E0 +:104AB6002408F8E4F680EE907696E04404F0440884 +:104AC600F0908003F0E4F518D235F50EF510D236E5 +:104AD600751211751322C237C239C238F516F5148C +:0B4AE600F51AF50DC23BC23CC23D2298 +:104AF100E4FF74562FF582E43476F583E0FE7428E2 +:104B01002FF582E43480F583EEF0745E2FF582E4B4 +:104B11003476F583E0FE74382FF582E43480F58332 +:064B2100EEF00FBF08CC0E +:014B2700226B +:104B2800E4907236F0A3F0907F97E054FBF0E490A5 +:104B38007233F0907232F090720104F0E4907233A4 +:104B4800F0907232F090720104F0907F97E0440484 +:024B5800F02249 +:104B5A00C0E0C083C0825391EF907FAAE04402F084 +:104B6A00907FC7E0F511750F00750D00D233D08222 +:054B7A00D083D0E03201 +:104B7F00907FD6E054FBF0E04408F0304204E0446C +:104B8F0002F07FDC7E05124D9D907FD6E054F7F04A +:054B9F00E04404F022D7 +:104BA400907FEBE0147014907FE9E0247F7004128E +:104BB400495822907FB4E04401F022907FB4E0444D +:034BC40001F022DB +:104BC700907FEBE0147013907FE9E0147004124AB1 +:104BD7000322907FB4E04401F022907FB4E04401C7 +:024BE700F022BA +:104BE900C0E0C083C0825391EF907FAB7410F09006 +:104BF9007696E054FDF0908003F0D082D083D0E027 +:014C09003278 +:104C0A00C0E0C083C0825391EF907FAAE04401F0D4 +:0F4C1A00C22990768D7401F0D082D083D0E03221 +:104C2900907FD6E030E712E04401F07F147E001255 +:0A4C39004D9D907FD6E054FEF0225E +:104C4300C0E0C083C082D2255391EF907FAB74083C +:084C5300F0D082D083D0E032E2 +:104C5B00C0E0C083C0825391EF907FA9E04401F084 +:074C6B00D082D083D0E032BB +:104C7200C0E0C083C0825391EF907FA9E04402F06C +:074C8200D082D083D0E032A4 +:104C8900C0E0C083C0825391EF907FA9E04404F053 +:074C9900D082D083D0E0328D +:104CA000C0E0C083C0825391EF907FAAE04404F03B +:074CB000D082D083D0E03276 +:104CB700C0E0C083C0825391EF907FA9E04408F021 +:074CC700D082D083D0E0325F +:104CCE00C0E0C083C0825391EF907FAAE04408F009 +:074CDE00D082D083D0E03248 +:104CE500C0E0C083C0825391EF907FA9E04410F0EB +:074CF500D082D083D0E03231 +:104CFC00C0E0C083C0825391EF907FAAE04410F0D3 +:074D0C00D082D083D0E03219 +:104D1300C0E0C083C0825391EF907FA9E04420F0AC +:074D2300D082D083D0E03202 +:104D2A00C0E0C083C0825391EF907FAAE04420F094 +:074D3A00D082D083D0E032EB +:104D4100C0E0C083C0825391EF907FA9E04440F05E +:074D5100D082D083D0E032D4 +:104D5800C0E0C083C0825391EF907FAAE04440F046 +:074D6800D082D083D0E032BD +:104D6F00C0E0C083C0825391EF907FA9E04480F0F0 +:074D7F00D082D083D0E032A6 +:104D8600C0E0C083C0825391EF907FAAE04480F0D8 +:074D9600D082D083D0E0328F +:104D9D008E358F36E5361536AE35700215354E60CB +:074DAD000512148580EE22BF +:104DB400C0E0C083C0825391EF907FAB7404F0D005 +:064DC40082D083D0E03232 +:104DCA00907682E0907F00F0907FB57401F0D32254 +:0C4DDA00C237E4F50EF510C236F51422C5 +:094DE600C22553D8EF43D8203256 +:074DEF005398FE5398FD32BA +:074DF60053C0FE53C0FD3263 +:064DFD0053917FD22C321D +:044E03005391DF32B6 +:044E070053D8F73253 +:044E0B001217302228 +:034E0F00C28D321F +:034E1200C28F321A +:024E1500D322A6 +:024E1700D322A4 +:024E1900D322A2 +:024E1B00D322A0 +:024E1D00D3229E +:024E1F00D3229C +:024E2100C322AA +:00000001FF +/* +Source: EMI62MFW.HEX +VERSION=1.04.062 +DATE=16.10.2002 +*/ diff --git a/firmware/emi62/spdif.HEX b/firmware/emi62/spdif.HEX new file mode 100644 index 0000000..322d50c --- /dev/null +++ b/firmware/emi62/spdif.HEX @@ -0,0 +1,1257 @@ +:030000000245F9BD +:03000300020FFDEC +:03000B00024D9B08 +:030013000217FDD4 +:03001B00024D9EF5 +:03002300024D7516 +:03002B000246F793 +:03003300024D6C0F +:03003B00024D7CF7 +:030043000249006F +:03004B00024D8FD4 +:03005300024D83D8 +:03005B00024D89CA +:03006300024D93B8 +:1005000012011001000000406A08110100010102FF +:1005100000010902AC01030100803209040000005F +:10052000010100000A2401000156000201020C240E +:10053000020101010002000000000D240605010275 +:10054000030000000000000924030204030005006A +:100550000C24020305020006000000001524060614 +:100560000302000003000300030003000300030074 +:100570000009240304010100060009040100000130 +:100580000200000904010102010200000724010128 +:10059000000100112402010202100344AC0080BBE0 +:1005A0000000770109050A05840101008F07250174 +:1005B0000100000009058F01030001050009040185 +:1005C00002020102000007240101000100112402BF +:1005D000010203180344AC0080BB00007701090549 +:1005E0000A05460201008F072501010000000905E8 +:1005F0008F01030001050009040200000102000050 +:1006000009040201010102000007240104000100A5 +:100610000E2402010602100244AC0080BB00090552 +:100620008C054C02010000072501000200000904AE +:1006300002020101020000072401040001000E244F +:1006400002010603180244AC0080BB0009058C05BA +:1006500072030100000725010002000009040203E3 +:10066000010102000007240104000100112402011D +:100670000202100344AC0080BB0000770109058C26 +:1006800005840101000007250100020000090402A1 +:1006900004010102000007240104000100112402EA +:1006A000010203180344AC0080BB00007701090578 +:1006B0008C0546020100000725010002000004032A +:1006C0000904180345006D006100670069006300BC +:1006D000200047006D0062004800220345006D00C5 +:1006E0006100670069006300200045004D0049007B +:1006F000200036007C00320020006D002A034300F9 +:100700006F006E006600690067007500720061008E +:10071000740069006F006E002000530074007200C6 +:1007200069006E006700220349006E0074006500D6 +:1007300072006600610063006500200053007400D1 +:0A074000720069006E0067000000FF +:10074A0090769A7402F0E4907691F0A3F090769005 +:10075A00F0907693F09076967403F0908003F0E42C +:10076A00907697F0908002F090769404F090800052 +:10077A00F0E490768EF090761AF090769504F0C2B6 +:10078A002E907F9BE0FF5410FF7002C23F907F9B28 +:10079A00E0FF5410FEFFBE1002D23F907F9BE0FFA5 +:1007AA005420FF7002C23E907F9BE0FF5420FEFF60 +:1007BA00BE2002D23E303F09907697E054FEF08088 +:1007CA0007907697E04401F0907697E0908002F0E7 +:1007DA00303E09907695E04404F08007907695E0E3 +:1007EA0054FBF0907695E0908001F0A23E9240A2F0 +:0307FA003F9241EA +:0107FD0022D9 +:0207FE00D32204 +:10080000E4907631F0907631E0FF75F003A4240F88 +:10081000F582E43475F583E0FE907FEDE0FDEE6D4A +:10082000600EEFC3940B5008907631E004F080D551 +:10083000EFB40B08907FB4E04401F022EF75F003B1 +:10084000A4240EF582E43475F583E0907633F02429 +:10085000F0600A240E60028187124B3E22907FEDE9 +:10086000E0640570519076187405F0907637740145 +:10087000F09076397403F0907621F0E4907620F0D1 +:10088000907FEAE0F4602F907620E0FF75F00AA4F4 +:1008900024AAF582E43475F583E0FE907FEAE0FD5A +:1008A000EE6D6012907621E0FEEFC39E50089076C8 +:1008B00020E004F080D1907FEDE0640670529076E5 +:1008C000187406F09076377404F0907639740AF054 +:1008D000907621F09076207403F0907FEAE0F46047 +:1008E0002F907620E0FF75F00AA424AAF582E43464 +:1008F00075F583E0FE907FEAE0FDEE6D6012907684 +:1009000021E0FEEFC39E5008907620E004F080D1F5 +:10091000907620E0FF75F00AA424AAF582E43475ED +:10092000F583E0907229F0E490763BF0907621E038 +:10093000FEEF6E7008907FB4E04401F022907FEBF0 +:10094000E014601314700221E224026002817F909F +:100950007FB4E04401F022907FE9E014707C907F46 +:10096000EAE0F47048907637E0907620F09076399F +:10097000E0FE907620E0FDC39E502B90763BE0FE9B +:1009800004F074C02EF582E4347EF583E0FEED754C +:10099000F00AA424ABF582E43475F583EEF090768A +:1009A00020E004F080C790763F7401F022907EC072 +:1009B000E0FEEF75F00AA424ABF582E43475F5830C +:1009C000EEF0E0B4010890763E7401F08005E4900A +:1009D000763EF090763F7401F022907FB4E04401BF +:1009E000F022907FE9E024FE700241A314700261BE +:1009F0003F14700261DB240360028177907FEAE09C +:100A0000F4706B907637E0907620F0907639E0FFC6 +:100A1000907620E0FEC39F504E90763BE0FF04F0BE +:100A200074C02FF582E4347EF583E0FFEE75F00AA2 +:100A3000A424ACF582E43475F583EFF090763BE0C6 +:100A4000FF04F074C02FF582E4347EF583E0FFEEFE +:100A500075F00AA424ADF582E43475F583EFF090C7 +:100A60007620E004F080A49076407401F022907E1D +:100A7000C0E0FF907620E0FE75F00AA424ACF58279 +:100A8000E43475F583EFF0907EC1E0FFEE75F00A77 +:100A9000A424ADF582E43475F583EFF090764174CB +:100AA00001F022907FEAE0F47066907637E090766D +:100AB00020F0907639E0FF907620E0FEC39F400260 +:100AC000818E90763BE0FF04F074C02FF582E43411 +:100AD0007EF583E0FFEE75F00AA424AEF582E434DF +:100AE00075F583EFF090763BE0FF04F074C02FF5CE +:100AF00082E4347EF583E0FFEE75F00AA424AFF5BE +:100B000082E43475F583EFF0907620E004F080A263 +:100B1000907EC0E0FF907620E0FE75F00AA424AE3F +:100B2000F582E43475F583EFF0907EC1E0FFEE7559 +:100B3000F00AA424AFF582E43475F583EFF0229037 +:100B40007FEAE0F47066907637E0907620F0907659 +:100B500039E0FF907620E0FEC39F4002818E9076C0 +:100B60003BE0FF04F074C02FF582E4347EF583E0AF +:100B7000FFEE75F00AA424B0F582E43475F583EF36 +:100B8000F090763BE0FF04F074C02FF582E4347EF1 +:100B9000F583E0FFEE75F00AA424B1F582E4347524 +:100BA000F583EFF0907620E004F080A2907EC0E024 +:100BB000FF907620E0FE75F00AA424B0F582E434BC +:100BC00075F583EFF0907EC1E0FFEE75F00AA42486 +:100BD000B1F582E43475F583EFF022907FEAE0F41A +:100BE0007066907637E0907620F0907639E0FF904E +:100BF0007620E0FEC39F4002818E90763BE0FF04AA +:100C0000F074C02FF582E4347EF583E0FFEE75F0DA +:100C10000AA424B2F582E43475F583EFF090763BB4 +:100C2000E0FF04F074C02FF582E4347EF583E0FF2A +:100C3000EE75F00AA424B3F582E43475F583EFF081 +:100C4000907620E004F080A2907EC0E0FF907620B5 +:100C5000E0FE75F00AA424B2F582E43475F583EF62 +:100C6000F0907EC1E0FFEE75F00AA424B3F582E4B3 +:100C70003475F583EFF022907FB4E04401F02290C8 +:0F0C80007FB4E04401F022907FB4E04401F02201 +:100C8F004176680141766A0241766B0AC120C12123 +:020C9F00C12F63 +:040CA1004176230075 +:100CA500417201014572050002C9000045720A0042 +:100CB500010203044D720FD100D1000000000000B5 +:100CC500282809004D721C010001020304050607CE +:100CD50008090A0B41722E2241722F2341723020DE +:100CE5004172312162D2723A00000000000000001A +:100CF50000000000000000000000000000000000EF +:100D050000000000000000000000000000000000DE +:100D150000000000000000000000000000000000CE +:100D250000000000000000000000000000000000BE +:100D350000000000000000000000000000000000AE +:100D4500000000000000000000000000000000009E +:100D5500000000000000000000000000000000008E +:100D6500000000000000000000000000000000007E +:100D75000000000000000000000001010101010168 +:100D8500010101010101010101010101010101014E +:100D9500010101010101010101010101010101013E +:100DA500010101010101010101010101010101012E +:100DB5000101010101010101020202020202020216 +:100DC50002020202020202020202020202020202FE +:100DD50002020202020202020202020202020202EE +:100DE50002020202020202020202020202020202DE +:100DF50002020202020303030303030303030303C3 +:100E050003030303030303030303030303030303AD +:100E1500030303030303030303030303030303039D +:100E2500030303030303030303030303030303038D +:100E3500030304040404040404040404040404046F +:100E4500040404040404040404040404040404045D +:100E5500040404040404040404040404040404044D +:100E6500040404040404040404040404040404043D +:100E7500050505050505050505050505050505051D +:100E8500050505050505050505050505050505050D +:100E950005050505050505050505050505050505FD +:100EA50005050505050505050505050505050606EB +:100EB50006060606060606060606060606060606CD +:100EC50006060606060606060606060606060606BD +:100ED50006060606060606060606060606060606AD +:100EE5000606060606060606060606070707080896 +:100EF500080909090A0A0A0B0B0B0C0C0C0D0D0D40 +:100F05000E0E0E0F0F0F10101011111112121213D9 +:100F15001313141414151515161616171717181874 +:100F250018191919191A1A1A1A1B1B1B1B1C1C1C18 +:100F35001C1D1D1D1D1E1E1E1E1F1F1F1F202020C8 +:100F45002121212222222323242425252626272761 +:100F5500282829292A2A2B2B2C2C2D2D2E2E2F2FD4 +:100F65003030313132323333343435353636373744 +:100F7500383839393A3A3B3C3D3E3F40414243449B +:100F85004546474849494A4B4B4C4D4E4F505152A7 +:100F95005354555556565757585A5B5D5E5F6162B7 +:100FA500636465666768696A6B6C6D6F717273748B +:100FB50075767778797A7B7C7E80013701013800F8 +:010FC500002B +:100FC600E4FF74462FF582E43476F583E0FE742060 +:100FD6002FF582E43480F583EEF0744E2FF582E42B +:100FE6003476F583E0FE74302FF582E43480F583A1 +:060FF600EEF00FBF08CC75 +:010FFC0022D2 +:030FFD00C2893274 +:10100000E490762CF090762CE0FF75F003A4240F8A +:10101000F582E43475F583E0FE907FEDE0FDEE6D42 +:10102000600EEFC3940B500890762CE004F080D54E +:10103000EFB40B08907FB4E04401F022EF75F003A9 +:10104000A4240EF582E43475F583E090762EF02426 +:10105000F0600A240F6002817D124B1B22907FED0D +:10106000E0640570519076187405F090763874013C +:10107000F090763A7403F090761CF0E490761BF0D2 +:10108000907FEAE0F4602F90761BE0FF75F00AA4F1 +:1010900024AAF582E43475F583E0FE907FEAE0FD52 +:1010A000EE6D601290761CE0FEEFC39E50089076C5 +:1010B0001BE004F080D1907FEDE0640670529076E2 +:1010C000187406F09076387404F090763A740AF04A +:1010D00090761CF090761B7403F0907FEAE0F46049 +:1010E0002F90761BE0FF75F00AA424AAF582E43461 +:1010F00075F583E0FE907FEAE0FDEE6D601290767C +:101100001CE0FEEFC39E500890761BE004F080D1F7 +:10111000E490761EF090761CE0FF90761BE0FE6F68 +:101120007008907FB4E04401F022907FEBE01460FF +:101130001314700221BF240260028175907FB4E015 +:101140004401F022907FE9E0247F706B907FEAE019 +:10115000F4704A907638E090761BF090763AE0FF93 +:1011600090761BE0FDC39F502BED75F00AA424ABD5 +:10117000F582E43475F583E0FF90761EE0FD04F01F +:1011800074002DF582E4347FF583EFF090761BE058 +:1011900004F080C790761EE0907FB5F022EE75F0E7 +:1011A0000AA424ABF582E43475F583E0907F00F067 +:1011B000907FB57401F022907FB4E04401F022905A +:1011C0007FE9E0247E7002417E1470026123147076 +:1011D0000261C824036002816D907FEAE0F4706DC3 +:1011E000907638E090761BF090763AE0FF90761B90 +:1011F000E0C39F504FE0FF75F00AA424ACF582E4F1 +:101200003475F583E0FE90761EE0FD04F074002D49 +:10121000F582E4347FF583EEF0EF75F00AA424AD97 +:10122000F582E43475F583E0FF90761EE0FE04F06D +:1012300074002EF582E4347FF583EFF090761BE0A6 +:1012400004F080A490761EE0907FB5F02290761B8B +:10125000E0FF75F00AA424ACF582E43475F583E070 +:10126000907F00F0EF75F00AA424ADF582E43475A8 +:10127000F583E0907F01F0907FB57402F022907FBB +:10128000EAE0F4706D907638E090761BF090763A54 +:10129000E0FF90761BE0C39F504FE0FF75F00AA47B +:1012A00024AEF582E43475F583E0FE90761EE0FD11 +:1012B00004F074002DF582E4347FF583EEF0EF75D1 +:1012C000F00AA424AFF582E43475F583E0FF90764C +:1012D0001EE0FE04F074002EF582E4347FF583EF07 +:1012E000F090761BE004F080A490761EE0907FB52D +:1012F000F02290761BE0FF75F00AA424AEF582E49C +:101300003475F583E0907F00F0EF75F00AA424AF08 +:10131000F582E43475F583E0907F01F0907FB57439 +:1013200002F022907FEAE0F4706D907638E09076DB +:101330001BF090763AE0FF90761BE0C39F504FE0A1 +:10134000FF75F00AA424B0F582E43475F583E0FE5D +:1013500090761EE0FD04F074002DF582E4347FF5F4 +:1013600083EEF0EF75F00AA424B1F582E43475F54C +:1013700083E0FF90761EE0FE04F074002EF582E418 +:10138000347FF583EFF090761BE004F080A4907634 +:101390001EE0907FB5F02290761BE0FF75F00AA466 +:1013A00024B0F582E43475F583E0907F00F0EF75AA +:1013B000F00AA424B1F582E43475F583E0907F014E +:1013C000F0907FB57402F022907FEAE0F4706D90A7 +:1013D0007638E090761BF090763AE0FF90761BE04E +:1013E000C39F504FE0FF75F00AA424B2F582E434A5 +:1013F00075F583E0FE90761EE0FD04F074002DF597 +:1014000082E4347FF583EEF0EF75F00AA424B3F59F +:1014100082E43475F583E0FF90761EE0FE04F074FC +:10142000002EF582E4347FF583EFF090761BE00424 +:10143000F080A490761EE0907FB5F02290761BE0BD +:10144000FF75F00AA424B2F582E43475F583E090C8 +:101450007F00F0EF75F00AA424B3F582E43475F54B +:1014600083E0907F01F0907FB57402F022907FB40A +:10147000E04401F022907FB4E04401F022907FB478 +:05148000E04401F02230 +:101485007400F58690FDA57C05A3E582458370F97A +:011495002234 +:10149600907FD6E04480F0438701000000000022E0 +:1014A600C0D0C0E08FE0C0E08EE0C0E08DE0C0E0DC +:1014B6008CE0C0E0C082C0830586C084C0857D0004 +:1014C600907FE3747BF0A37480F07C11907F99E0A9 +:1014D6005440DC030214F3B40013907FE27440F02E +:1014E600907FE5F0907FE27400F00214D29076903F +:1014F600E0B4011290768FE02DFD907FE27480F0CB +:10150600907F6C021557B4021290768FE02DFD90F5 +:101516007FE27480F0907F6C021596B40312907689 +:101526008FE02DFD907FE27480F0907F6C0215E1D4 +:10153600B4041290768FE02DFD907FE27480F090D7 +:101546007F6C021610907FE27480F0907F6C02161A +:1015560040F0F0F0F0F0F0F0F0F0F0F0F0DDF27DB9 +:10156600020586907FE27400F0907F9BE05404B4FD +:1015760000050586021640907FE27480F00586F02D +:10158600F0F0F0F0F0F0F0F0F0F0F0DDD4021640FC +:10159600F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F045 +:1015A600F0F0DDEC7D020586907FE27400F0907F1E +:1015B6009BE05404B400050586021640907FE27451 +:1015C60080F00586F0F0F0F0F0F0F0F0F0F0F0F0DA +:0615D600F0F0F0F0F0F06F +:1015DC00DDCE021640F0F0F0F0DDFA7D02058690CB +:1015EC007FE27400F0907F9BE05404B40005058604 +:1015FC00021640907FE27480F00586F0F0F0F0DD8A +:10160C00DC021640F0F0F0F0F0F0DDF87D0205861B +:10161C00907FE27400F0907F9BE05404B4000505C9 +:10162C0086021640907FE27480F00586F0F0F0F0B0 +:10163C00F0F0DDDA907FE27400F0D085D08405867E +:10164C00D083D082D0E0FCD0E0FDD0E0FED0E0FF33 +:05165C00D0E0D0D02217 +:10166100C0D0C0E0C082C08390767CE0907F6FF0F4 +:1016710090767DE0907F6FF090767EE0907F6FF0C6 +:09168100D083D082D0E0D0D02249 +:10168A00C0D0C0E08FE0C0E08EE0C0E0C082C0837E +:10169A000586C084C085907687E0FFBF00030217E5 +:1016AA0001907F96E04480F0907FE27480F0907F12 +:1016BA0062E00586907FE27400F0907F96E0547FA6 +:1016CA00F0907FE27480F090768EE0B40105058692 +:1016DA000216F6B4020505860216EB05860216FB0B +:1016EA00E0E0E0E0E0E0DFF80216FBE0E0E0E0DF67 +:1016FA00FA907FE27400F0D085D0840586D083D03A +:0C170A0082D0E0FED0E0FFD0E0D0D02282 +:10171600C082C083C0E0E8C0E078D1E814F870FB6E +:0A172600D0E0F8D0E0D083D082229A +:10173000C082C083C0E0E8C0E07878E814F870FBAD +:0A174000D0E0F8D0E0D083D0822280 +:07174A00907FC57402F0223C +:10175100907EC0E0907645F0907EC1E0907644F0B6 +:10176100907EC2E0907643F0B40003021778907641 +:10177100197403F002178E907644E0B4BB09907699 +:10178100197402F002178E9076197401F090764266 +:03179100E4F0225F +:041794008D298B2AE6 +:101798001249FFEA4960571236927E0029FFEE3A55 +:1017A800C9EFC9752BFFF52C892DAB2BAA2CA92DB8 +:1017B8009000011236ABFF64046005EF6405702EDB +:1017C800EFB404159000021236AB6529700B900037 +:1017D800031236AB652A7001221236927E0029FF69 +:1017E800EE3AC9EFC9752BFFF52C892D80BC7B001B +:0417F8007A007900FA +:0117FC0022CA +:0317FD00C28B326A +:10180000907690E014603714700201D814700221B1 +:1018100072147002413B240460026103907FFC74E7 +:10182000CCF0907FFF74FCF0907695E04401F0548A +:1018300005F0908001F0E490761AF0C22E229076A6 +:1018400095E04401F04402F0303E06E04404F080AC +:1018500007907695E054FBF090761AE0B40108907A +:101860007695E0908001F0907619E0FFB401229027 +:101870007FFC7474F0907FFF74FCF090768F742B73 +:10188000F0907697E054FDF0E4907681F0907680C9 +:10189000F0EFB40222907FFC7468F0907FFF74FC3C +:1018A000F090768F742FF0907697E04402F0E490F9 +:1018B0007681F0907680F0303F09907697E054FE84 +:1018C000F08007907697E04401F0907697E054FB23 +:1018D000F0908002F0D22E22907695E054FEF044F3 +:1018E00002F0303E06E04404F08007907695E05424 +:1018F000FBF090761AE0B40108907695E0908001B4 +:10190000F0907619E0FFB40122907FFC7430F090E3 +:101910007FFF74FCF090768F742BF0907697E054F4 +:10192000FDF0E4907681F0907680F0EFB4022290A2 +:101930007FFC741CF0907FFF74FCF090768F742F06 +:10194000F0907697E04402F0E4907681F090768013 +:10195000F0303F09907697E054FEF080079076973C +:10196000E04401F0907697E054FBF0908002F0D2D2 +:101970002E22907695E04401F04402F04408F030C5 +:101980003E06E04404F08007907695E054FBF0902A +:10199000761AE0B40108907695E0908001F0907698 +:1019A00019E0FFB40125907FFC74CCF0907FFF74A8 +:1019B000FCF090768F742BF0907697E054FDF05405 +:1019C000FBF0E4907681F0907680F0EFB402259001 +:1019D0007FFC74C8F0907FFF74FCF090768F742FBA +:1019E000F0907697E04402F054FBF0E4907681F0BA +:1019F000907680F0EFB40325907FFC7498F0907F90 +:101A0000FF74FCF090768F745FF0907697E054FD51 +:101A1000F04404F0E4907681F0907680F0303F0955 +:101A2000907697E054FEF08007907697E04401F0BE +:101A3000907697E0908002F0D22E22907695E05436 +:101A4000FEF04402F04408F0303E06E04404F0802A +:101A500007907695E054FBF090761AE0B401089078 +:101A60007695E0908001F0907619E0FFB401259022 +:101A70007FFC74B4F0907FFF74FCF090768F742B31 +:101A8000F0907697E054FDF054FBF0E4907681F00E +:101A9000907680F0EFB40225907FFC74B0F0907FD8 +:101AA000FF74FCF090768F742FF0907697E04402EC +:101AB000F054FBF0E4907681F0907680F0EFB40380 +:101AC00025907FFC7468F0907FFF74FCF090768F17 +:101AD000745FF0907697E054FDF04404F0E4907663 +:101AE00081F0907680F0303F09907697E054FEF0D8 +:101AF0008007907697E04401F0907697E09080021E +:041B0000F0D22E22CF +:101B0400302C38C22C907619E0FFB4010E90767C0C +:101B140074C0F0A37414F0A3740BF0EFB4020DE4DA +:101B240090767CF0A37410F0A3740CF0EFB4030B64 +:0C1B3400E490767CF0A37418F0A3F0227B +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:0E1EB000000000000000000000000000000024 +:101EBE000000000000000000000000000000000014 +:101ECE000000000000000000000000000000000004 +:101EDE0000000000000000000000000000000000F4 +:101EEE0000000000000000000000000000000000E4 +:101EFE0000000000000000000000000000000000D4 +:101F0E0000000000000000000000000000000000C3 +:101F1E0000000000000000000000000000000000B3 +:101F2E0000000000000000000000000000000000A3 +:021F3E000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:1020000000000000000000000000000000000000D0 +:1020100000000000000000000000000000000000C0 +:1020200000000000000000000000000000000000B0 +:1020300000000000000000000000000000000000A0 +:102040000000000000000000000000000000000090 +:102050000000000000000000000000000000000080 +:102060000000000000000000000000000000000070 +:102070000000000000000000000000000000000060 +:102080000000000000000000000000000000000050 +:102090000000000000000000000000000000000040 +:1020A0000000000000000000000000000000000030 +:1020B0000000000000000000000000000000000020 +:1020C0000000000000000000000000000000000010 +:1020D0000000000000000000000000000000000000 +:1020E00000000000000000000000000000000000F0 +:1020F00000000000000000000000000000000000E0 +:1021000000000000000000000000000000000000CF +:1021100000000000000000000000000000000000BF +:1021200000000000000000000000000000000000AF +:10213000000000000000000000000000000000009F +:10214000000000000000000000000000000000008F +:10215000000000000000000000000000000000007F +:10216000000000000000000000000000000000006F +:10217000000000000000000000000000000000005F +:10218000000000000000000000000000000000004F +:10219000000000000000000000000000000000003F +:1021A000000000000000000000000000000000002F +:1021B000000000000000000000000000000000001F +:1021C000000000000000000000000000000000000F +:1021D00000000000000000000000000000000000FF +:1021E00000000000000000000000000000000000EF +:1021F00000000000000000000000000000000000DF +:1022000000000000000000000000000000000000CE +:1022100000000000000000000000000000000000BE +:1022200000000000000000000000000000000000AE +:10223000000000000000000000000000000000009E +:10224000000000000000000000000000000000008E +:10225000000000000000000000000000000000007E +:10226000000000000000000000000000000000006E +:10227000000000000000000000000000000000005E +:10228000000000000000000000000000000000004E +:10229000000000000000000000000000000000003E +:1022A000000000000000000000000000000000002E +:1022B000000000000000000000000000000000001E +:1022C000000000000000000000000000000000000E +:1022D00000000000000000000000000000000000FE +:1022E00000000000000000000000000000000000EE +:1022F00000000000000000000000000000000000DE +:1023000000000000000000000000000000000000CD +:1023100000000000000000000000000000000000BD +:1023200000000000000000000000000000000000AD +:10233000000000000000000000000000000000009D +:10234000000000000000000000000000000000008D +:10235000000000000000000000000000000000007D +:10236000000000000000000000000000000000006D +:0E23700000000000000000000000000000005F +:10237E00000000000000000000000000000000004F +:10238E00000000000000000000000000000000003F +:10239E00000000000000000000000000000000002F +:1023AE00000000000000000000000000000000001F +:1023BE00000000000000000000000000000000000F +:1023CE0000000000000000000000000000000000FF +:1023DE0000000000000000000000000000000000EF +:1023EE0000000000000000000000000000000000DF +:1023FE0000000000000000000000000000000000CF +:10240E0000000000000000000000000000000000BE +:10241E0000000000000000000000000000000000AE +:10242E00000000000000000000000000000000009E +:10243E00000000000000000000000000000000008E +:10244E00000000000000000000000000000000007E +:10245E00000000000000000000000000000000006E +:10246E00000000000000000000000000000000005E +:10247E00000000000000000000000000000000004E +:10248E00000000000000000000000000000000003E +:10249E00000000000000000000000000000000002E +:1024AE00000000000000000000000000000000001E +:1024BE00000000000000000000000000000000000E +:1024CE0000000000000000000000000000000000FE +:1024DE0000000000000000000000000000000000EE +:1024EE0000000000000000000000000000000000DE +:1024FE0000000000000000000000000000000000CE +:10250E0000000000000000000000000000000000BD +:10251E0000000000000000000000000000000000AD +:10252E00000000000000000000000000000000009D +:10253E00000000000000000000000000000000008D +:10254E00000000000000000000000000000000007D +:10255E00000000000000000000000000000000006D +:10256E00000000000000000000000000000000005D +:10257E00000000000000000000000000000000004D +:10258E00000000000000000000000000000000003D +:10259E00000000000000000000000000000000002D +:1025AE00000000000000000000000000000000001D +:1025BE00000000000000000000000000000000000D +:1025CE0000000000000000000000000000000000FD +:1025DE0000000000000000000000000000000000ED +:1025EE0000000000000000000000000000000000DD +:1025FE0000000000000000000000000000000000CD +:10260E0000000000000000000000000000000000BC +:10261E0000000000000000000000000000000000AC +:10262E00000000000000000000000000000000009C +:10263E00000000000000000000000000000000008C +:10264E00000000000000000000000000000000007C +:10265E00000000000000000000000000000000006C +:10266E00000000000000000000000000000000005C +:10267E00000000000000000000000000000000004C +:10268E00000000000000000000000000000000003C +:10269E00000000000000000000000000000000002C +:1026AE00000000000000000000000000000000001C +:1026BE00000000000000000000000000000000000C +:1026CE0000000000000000000000000000000000FC +:1026DE0000000000000000000000000000000000EC +:0E26EE000000000000000000000000000000DE +:1026FC0000000000000000000000000000000000CE +:10270C0000000000000000000000000000000000BD +:10271C0000000000000000000000000000000000AD +:10272C00000000000000000000000000000000009D +:10273C00000000000000000000000000000000008D +:10274C00000000000000000000000000000000007D +:10275C00000000000000000000000000000000006D +:10276C00000000000000000000000000000000005D +:10277C00000000000000000000000000000000004D +:10278C00000000000000000000000000000000003D +:10279C00000000000000000000000000000000002D +:1027AC00000000000000000000000000000000001D +:1027BC00000000000000000000000000000000000D +:1027CC0000000000000000000000000000000000FD +:1027DC0000000000000000000000000000000000ED +:1027EC0000000000000000000000000000000000DD +:0527FC000000000022B6 +:10280100C220C221C22A907FE8E01237F9283000A5 +:10281100288C0128A2022A1F212A6A22293D802907 +:102821007D8129D1822A84A12ABAA200002ABF90DF +:102831007FE9E014601124FE602824FE603B24FC43 +:102841007040124BA041CB124DA7400241CB907F6B +:10285100EAE0B40104C22241CB907FB4E04401F02C +:1028610041CB124DA9907FEAE0B40104D22241CBC1 +:10287100907FB4E04401F041CB907FB4E04401F09B +:1028810041CB907FB4E04401F041CB907FE9E0245B +:10289100F5700512480041CB907FB4E04401F0414E +:1028A100CB907FE9E024FD605424026002213412C0 +:1028B1004DA7400241CB907FEAE07038907FECE079 +:1028C100F45480FFC4540FFFE054072F25E024B4D3 +:1028D100F582E4347FF583E4F0907FECE05480FFEF +:1028E100131313541FFFE054072F907FD7F0E044D8 +:1028F10020F041CB907FB4E04401F041CB124DA9CF +:10290100400241CB907FEAE07020907FECE0F454EC +:1029110080FFC4540FFFE054072F25E024B4F58253 +:10292100E4347FF5837401F041CB907FB4E044013E +:10293100F041CB907FB4E04401F041CB907FE9E0DE +:10294100601224F86009240270291243DB41CB1282 +:102951004D5C41CB124DA5A222E433FF25E0FFA23D +:1029610023E4334F907F00F0E4A3F0907FB574022D +:10297100F041CB907FB4E04401F041CB907FE9E09E +:10298100603324F6602A2404703D907FEBE024DE5E +:10299100600C047012907FB4E04401F041CB907F51 +:1029A100B4E04401F041CB907FB4E04401F041CB6D +:1029B10012468541CB124DA5E4907F00F0A3F09023 +:1029C1007FB57402F041CB907FB4E04401F041CB7C +:1029D100907FE9E024F46034240C7039124DA59005 +:1029E1007FECE0F45480FFC4540FFFE054072F251F +:1029F100E024B4F582E4347FF583E054FD907F0058 +:102A0100F0E4A3F0907FB57402F041CB907FB4E085 +:102A11004401F041CB907FB4E04401F041CB907F81 +:102A2100E9E024F6601214601A2402701DD220908D +:102A31007FB4E04401F08012D220907FB4E04401E1 +:102A4100F08007907FB4E04401F0202018907FEEE1 +:102A5100E07004A3E0600BD229D22712174AD22AD0 +:102A61008003120800C2208061907FEEE07004A311 +:102A7100E0600BD229D22812174AD22A804C123890 +:102A8100748047907FE9E024FE601214601A2402EA +:102A9100701DD221907FB4E04401F08012D22190C8 +:102AA1007FB4E04401F08007907FB4E04401F0205E +:102AB1002103121000C2218011122AD6800C124D5E +:102AC100AB5007907FB4E04401F0202A07907FB417 +:052AD100E04402F022C8 +:102AD600E4907627F0907627E0FF75F00FA4244265 +:102AE600F582E43475F583E0FE907FECE0FDEE6D53 +:102AF600600EEFC394065008907627E004F080D568 +:102B0600EFB40608907FB4E04401F022EF75F00FB1 +:102B1600A42441F582E43475F583E0907628F02408 +:102B26009F7002A17424216002A1A1907FE9E02494 +:102B36007E700261FC14700281B524026002A16CF1 +:102B4600EF75F00FA42443F582E43475F583E0FCB9 +:102B5600A3E0FDA3E0FEA3E0FF7B447AAC79007816 +:102B660000C31237AB7013907F007444F0A374ACAB +:102B7600F0E4A3F0907FB57403F0907627E075F04B +:102B86000FA42443F582E43475F583E0FCA3E0FD4D +:102B9600A3E0FEA3E0FF7B807ABB79007800C31236 +:102BA60037AB7013907F007480F0A374BBF0E4A37E +:102BB600F0907FB57403F0907627E075F00FA424AB +:102BC60043F582E43475F583E0FCA3E0FDA3E0FE63 +:102BD600A3E0FF7B007A7779017800C31237AB60F8 +:102BE60002A1A8907F00F0A37477F0A37401F0907F +:102BF6007FB57403F022907627E075F00FA4244782 +:102C0600F582E43475F583E0FCA3E0FDA3E0FEA3C2 +:102C1600E0FF7B447AAC79007800C31237AB7013BF +:102C2600907F007444F0A374ACF0E4A3F0907FB5F9 +:102C36007403F0907627E075F00FA42447F582E43C +:102C46003475F583E0FCA3E0FDA3E0FEA3E0FF7B83 +:102C5600807ABB79007800C31237AB7013907F007F +:102C66007480F0A374BBF0E4A3F0907FB57403F016 +:102C7600907627E075F00FA42447F582E43475F5C5 +:102C860083E0FCA3E0FDA3E0FEA3E0FF7B007A77F0 +:102C960079017800C31237AB6002A1A8907F00F0DB +:102CA600A37477F0A37401F0907FB57403F02290BB +:102CB6007627E075F00FA4244BF582E43475F5838E +:102CC600E0FCA3E0FDA3E0FEA3E0FF7B447AAC7941 +:102CD600007800C31237AB7013907F007444F0A3E2 +:102CE60074ACF0E4A3F0907FB57403F0907627E01F +:102CF60075F00FA4244BF582E43475F583E0FCA34C +:102D0600E0FDA3E0FEA3E0FF7B807ABB79007800BC +:102D1600C31237AB7013907F007480F0A374BBF0BE +:102D2600E4A3F0907FB57403F0907627E075F00F7A +:102D3600A4244BF582E43475F583E0FCA3E0FDA3FF +:102D4600E0FEA3E0FF7B007A7779017800C31237B3 +:102D5600AB704F907F00F0A37477F0A37401F090EE +:102D66007FB57403F022907FB4E04401F022907F97 +:102D7600E9E0247F701E907627E075F00FA4244FBB +:102D8600F582E43475F583E0907F00F0907FB574AA +:102D960001F08007907FB4E04401F0907FB4E044F6 +:032DA60001F02217 +:102DA900E4907636F0E0FF75F003A4240EF582E492 +:102DB9003475F5837401F0EF75F003A4240FF582DF +:102DC900E43475F5837401F0EF75F003A42410F56C +:102DD90082E43475F583E4F0907636E004F0E0FFA0 +:102DE90075F003A4240EF582E43475F5837410F0AC +:102DF900EF75F003A4240FF582E43475F5837405A7 +:102E0900F0EF75F003A42410F582E43475F583E43A +:102E1900F0907636E004F0E0FF75F003A4240EF597 +:102E290082E43475F5837402F0EF75F003A4240F7E +:102E3900F582E43475F5837402F0EF75F003A42488 +:102E490010F582E43475F583E4F0907636E004F009 +:102E5900E0FF75F003A4240EF582E43475F583745C +:102E690001F0EF75F003A4240FF582E43475F583BE +:102E79007403F0EF75F003A42410F582E43475F5BA +:102E890083E4F0907636E004F0E0FF75F003A424C3 +:102E99000EF582E43475F5837410F0EF75F003A430 +:102EA900240FF582E43475F5837406F0EF75F003A9 +:102EB900A42410F582E43475F583E4F0907636E0C5 +:102EC90004F0E0FF75F003A4240EF582E43475F5EF +:102ED900837402F0EF75F003A4240FF582E43475CE +:102EE900F5837404F0EF75F003A42410F582E4343B +:102EF90075F583E4F0907636E004F0E0FF75F003B1 +:102F0900A4240EF582E43475F5837402F0EF75F0AC +:102F190003A4240FF582E43475F5837408F0EF7582 +:102F2900F003A42410F582E43475F5837404F09059 +:102F39007636E004F0E0FF75F003A4240EF582E490 +:102F49003475F5837402F0EF75F003A4240FF5824C +:102F5900E43475F583740AF0EF75F003A42410F5D1 +:102F690082E43475F5837404F0907636E004F0E079 +:102F7900FF75F003A4240EF582E43475F583740219 +:102F8900F0EF75F003A4240FF582E43475F583742A +:102F990009F0EF75F003A42410F582E43475F58384 +:102FA9007404F0907636E004F0E0FF75F003A42491 +:102FB9000EF582E43475F5837402F0EF75F003A41D +:102FC900240FF582E43475F5837407F0EF75F00387 +:0E2FD900A42410F582E43475F5837404F0220C +:102FE700C0E0C083C082D2265391EF907FAB7401BB +:082FF700F0D082D083D0E0325B +:012FFF00329F +:10300000907FB6E020E102C23DD236203602416E0A +:10301000303D02416E908007E06004D2368002C2EB +:1030200036203602412ED235E4F51A908004E0F5C0 +:10303000197408250EF8A619851918E51820E70453 +:10304000D2388002C23830380221D4E4F516E519AE +:10305000B4F00CD2397508047509F0050E8002052C +:1030600016E51964F7703DC239E50E24FE601714A9 +:103070006022240370297508057509F7E4F50AF53F +:103080000B750E048020750806750AF7E4F50B75BC +:103090000E048012750807750BF7750E0480071271 +:1030A00048F380020516E51954F864F8703BC23500 +:1030B000E5192407600C24FC6008240524F8500658 +:1030C0008008D23A8006C23A8002D23A751A0120AC +:1030D0003A19907E80740FF0A3E519F0E4A3F0A3F1 +:1030E000F0907FB77404F08002051620396DE51961 +:1030F00064F76067E51A7063E51854F064F070597E +:10310000851819F50EE519240F601B24FE6017249D +:10311000FD602214601F2405702F750803050E85BD +:103120001809D2378028750802050E85180975140C +:1031300001D2378019750805050E851809E4F50ACE +:10314000F50B750E03D23780051248F3C2353035C2 +:103150000A85081385181280020516851819E516C8 +:1031600064047062F50EE51954F0F519F51585182B +:1031700019E5152470601824F0601424F060102400 +:10318000F0601E24F0601A24F0600424607027E5CB +:1031900015C4540FF519F508050E851809D23780A6 +:1031A0001AE515C4540FF519F508050E85180975AB +:1031B0001401D23780051248F3C23530350A85191B +:1031C0001385181280020516E516D3940540571290 +:1031D00048F38052303917E50E700A8508097508E2 +:1031E00004050E80417408250EF8A6198038203792 +:1031F0002AE50EB4010F85080A85090B8513088599 +:103200001209750E04E514B4011C85080AE4F50BD7 +:10321000851308851209750E04800BE514B40106A8 +:10322000E4F50B750E04E4F51A303502050EE50ED3 +:10323000D394035002010BC237E4F50EF510C236E9 +:10324000D23DF51474082510F8E6FF74802510F5BA +:1032500082E4347EF583EFF074082510F8E4F60577 +:0F32600010E510B404DE907FB77404F0010B2268 +:10326F00907618E0FF640570429075ABE0B40119D9 +:10327F009072377401F0E4908020F0908031F090DC +:10328F008028F0908039F08022E4907237F09075AA +:10329F00ADE090722BF0E02480F0E0908020F09071 +:1032AF008031F0908028F0908039F0EF6406600252 +:1032BF0081999072397404F0907239E0FF24FE9076 +:1032CF007204F0EF75F00AA424ABF582E43475F5BF +:1032DF0083E06401705490723604F0907204E0FF42 +:1032EF0024FD602824FE6024240324FB5004601C6A +:1032FF00818C74202FF582E43480F583E4F07428F8 +:10330F002FF582E43480F583E4F0818C907204E031 +:10331F00FF2430F582E43480F583E4F074382FF520 +:10332F0082E43480F583E4F0818CE4907236F0907F +:10333F007239E075F00AA424ADF582E43475F58393 +:10334F00E0FF7E0090750CEEF0A3EFF07006907228 +:10335F0002743BF090750CE0FEA3E0FF64804E70AA +:10336F0004907202F0EF4E70028135EF64804E7060 +:10337F00028135EFF8E490750DF0E890750CF09040 +:10338F007234E075F00AA424ACF582E43475F58349 +:10339F00E0FF907202F090750DE02FF090750CE049 +:1033AF003400F0E0FEA3E0FFE4FCFD7BD67AA5F944 +:1033BF00F8D3123795400A90750C74A5F0A374D604 +:1033CF00F090750DE0242AF090750CE0345AF0E07F +:1033DF00FEA3E07805CEA2E713CE13D8F8FF9075C1 +:1033EF000CEEF0A3EFF090722CEEF0A3EFF0D3946D +:1033FF00D2EE64809482400A90722C7402F0A3740F +:10340F00D2F0C390722CE0648094805004E4F0A357 +:10341F00F090722CE0FEA3E0243AF582EE3472F5C0 +:10342F0083E0907202F0907204E0FF24FD602D247F +:10343F00FE6029240324FB50046021804090720217 +:10344F00E0FE74202FF582E43480F583EEF07428CB +:10345F002FF582E43480F583EEF08021907202E044 +:10346F00FF907204E0FE2430F582E43480F583EFA0 +:10347F00F074382EF582E43480F583EFF0907239D2 +:0B348F00E004F0E0640A600241C72284 +:10349A00907618E0FFB40523907237E0701D90759E +:1034AA00ADE090722BF0E02480F0E0908020F09064 +:1034BA008031F0908028F0908039F0EF6406600245 +:1034CA00C191907236E06002C191907640E070310D +:1034DA009072037403F0907203E0FF75F00AA4245B +:1034EA00AAF582E43475F583E0FE907229E0FDEED8 +:1034FA006D600EEFC3940A5008907203E004F080E6 +:10350A00D59072397404F0907640E0700890720396 +:10351A00E0907239F0907239E0FD24FE90722AF040 +:10352A00ED75F00AA424ADF582E43475F583E0FF65 +:10353A007E0090750CEEF0A3EFF0700690720274A4 +:10354A0080F090750CE0FEA3E0FF64804E7004905A +:10355A007202F0EF4E7002C11BEF64804E7002C11E +:10356A001BEFF8E490750DF0E890750CF0ED75F02E +:10357A000AA424ACF582E43475F583E0FF90720264 +:10358A00F090750DE02FF090750CE03400F0E0FE3D +:10359A00A3E0FFE4FCFD7BD67AA5F9F8D3123795B0 +:1035AA00400A90750C74A5F0A374D6F090750DE0DE +:1035BA00242AF090750CE0345AF0E0FEA3E0780576 +:1035CA00CEA2E713CE13D8F8FF90750CEEF0A3EF56 +:1035DA00F090722CEEF0A3EFF0D394D2EE648094C4 +:1035EA0082400A90722C7402F0A374D2F0C39072D3 +:1035FA002CE0648094805004E4F0A3F090722CE0F4 +:10360A00FEA3E0243AF582EE3472F583E09072026A +:10361A00F090722AE0FF24FD602D24FE6029240325 +:10362A0024FB500460218040907202E0FE74202F37 +:10363A00F582E43480F583EEF074282FF582E434C1 +:10364A0080F583EEF08021907202E0FF90722AE00A +:10365A00FE2430F582E43480F583EFF074382EF5D9 +:10366A0082E43480F583EFF0907640E07006907241 +:10367A0039740AF0907239E004F0E0C3940A5002F7 +:08368A00A111E4907640F0224A +:10369200BB010689828A83E0225002E722BBFE0236 +:0936A200E32289828A83E4932269 +:1036AB00BB010CE58229F582E5833AF583E02250D4 +:1036BB0006E92582F8E622BBFE06E92582F8E2221E +:0D36CB00E58229F582E5833AF583E4932238 +:1036D800C2D5EC30E709B2D5E4C39DFDE49CFCEE0D +:1036E80030E715B2D5E4C39FFFE49EFE12381FC32E +:1036F800E49DFDE49CFC800312381F30D507C3E429 +:063708009FFFE49EFE227B +:10370E00BB0110E58229F582E5833AF583E0F5F0F9 +:10371E00A3E0225009E92582F886F008E622BBFED6 +:10372E000AE92582F8E2F5F008E222E5832AF5831C +:08373E00E993F5F0A3E99322E1 +:10374600E88FF0A4CC8BF0A42CFCE98EF0A42CFC22 +:103756008AF0EDA42CFCEA8EF0A4CDA8F08BF0A4A0 +:103766002DCC3825F0FDE98FF0A42CCD35F0FCEBFF +:103776008EF0A4FEA9F0EB8FF0A4CFC5F02ECD39C4 +:0F378600FEE43CFCEAA42DCE35F0FDE43CFC2231 +:10379500EB9FF5F0EA9E42F0E99D42F0EC6480C8AB +:0637A50064809845F0224B +:1037AB00EB9FF5F0EA9E42F0E99D42F0E89C45F074 +:0137BB0022EB +:0C37BC00ECF0A3EDF0A3EEF0A3EFF02280 +:1037C800A8828583F0D083D0821237DF1237DF12C8 +:1037D80037DF1237DFE473E493A3C583C5F0C583ED +:1037E800C8C582C8F0A3C583C5F0C583C8C582C84B +:0137F80022AE +:1037F900D083D082F8E4937012740193700DA3A35F +:1038090093F8740193F5828883E473740293686072 +:06381900EFA3A3A380DF72 +:10381F00BC000BBE0029EF8DF084FFADF022E4CC8D +:10382F00F875F008EF2FFFEE33FEEC33FCEE9DEC56 +:10383F00984005FCEE9DFE0FD5F0E9E4CEFD22ED9C +:10384F00F8F5F0EE8420D21CFEADF075F008EF2FE6 +:10385F00FFED33FD4007985006D5F0F222C398FDD7 +:05386F000FD5F0EA2274 +:10387400E4907629F0907629E0FF75F00FA42442B5 +:10388400F582E43475F583E0FE907FECE0FDEE6DA7 +:10389400600EEFC394065008907629E004F080D5BA +:1038A400EFB40608907FB4E04401F022EF75F00F06 +:1038B400A42441F582E43475F583E090762AF0245B +:1038C400BF7002414124E070024112242160024190 +:1038D4003A907FE9E024FE607D14700221B2240254 +:1038E4006002410A121751907642E0FCA3E0FDA366 +:1038F400E0FEA3E0FF907629E075F00FA42443F5E1 +:1039040082E43475F5831237BC907619E0FFB40174 +:103914001290767C7467F090767D7406F090767ED3 +:10392400740BF0EFB4020FE490767CF090767DF0A7 +:1039340090767E740CF0EFB4030FE490767CF090F4 +:10394400767DF090767E7418F090761A7401F012F9 +:103954003E8F12180022907EC2E0FFE4FCFDFEFBC5 +:10396400FA7901F8123746C8ECC8C9EDC9CAEECADB +:10397400CBEFCB907EC1E0FEE4FCFD2BFBEA3EFAEC +:10398400ED39F9EC38F8907EC0E0FFE4FEEB2FFF50 +:10399400EE3AFEED39FDEC38FC907629E075F00F37 +:1039A400A42447F582E43475F5831237BC22907E53 +:1039B400C2E0FFE4FCFDFEFBFA7901F8123746C8C9 +:1039C400ECC8C9EDC9CAEECACBEFCB907EC1E0FE0C +:1039D400E4FCFD2BFBEA3EFAED39F9EC38F8907E75 +:1039E400C0E0FFE4FEEB2FFFEE3AFEED39FDEC38CC +:1039F400FC907629E075F00FA4244BF582E434752D +:103A0400F5831237BC22907FB4E04401F022907F0A +:103A1400E9E0147019907EC0E0FF907629E075F01B +:103A24000FA4244FF582E43475F583EFF022907FE0 +:0E3A3400B4E04401F022907FB4E04401F0229F +:103A4200E4907635F0907635E0FFC394034002416E +:103A5200FFEF75F00AA424AAF582E43475F583EF2A +:103A6200F0EF75F00AA424ABF582E43475F583E433 +:103A7200F0EF75F00AA424ACF582E43475F5837492 +:103A8200F0F0EF75F00AA424ADF582E43475F58305 +:103A920074FFF0EF75F00AA424AEF582E43475F5F4 +:103AA20083E4F0EF75F00AA424AFF582E43475F5EF +:103AB200837480F0EF75F00AA424B0F582E43475C3 +:103AC200F583E4F0EF75F00AA424B1F582E43475CD +:103AD200F583E4F0EF75F00AA424B2F582E43475BC +:103AE200F583E4F0EF75F00AA424B3F582E43475AB +:103AF200F5837401F0907635E004F0414790763C0E +:103B0200740AF0E4A3F09076357403F090763CE00A +:103B1200FF907635E0FEC39F400261D290763DE091 +:103B2200FF04F0EE75F00AA424AAF582E43475F5D8 +:103B320083EFF0EE75F00AA424ABF582E43475F558 +:103B420083E4F0EE75F00AA424ACF582E43475F552 +:103B520083745EF0EE75F00AA424ADF582E4347548 +:103B6200F58374BAF0EE75F00AA424AEF582E4345B +:103B720075F5837405F0EE75F00AA424AFF582E4BE +:103B82003475F5837480F0EE75F00AA424B0F582E2 +:103B9200E43475F583E4F0EE75F00AA424B1F582FD +:103BA200E43475F583E4F0EE75F00AA424B2F582EC +:103BB200E43475F5837415F0EE75F00AA424B3F5B8 +:103BC20082E43475F583E4F0907635E004F0610E1A +:013BD20022D0 +:103BD300E4907636F0E0FB75F00FA42441F582E41F +:103BE3003475F5837440F0EB75F00FA42442F5822D +:103BF300E43475F583740AF0EB75F00FA42443F5F0 +:103C030082E43475F5831237C80000AC44EB75F0D9 +:103C13000FA42447F582E43475F5831237C80000F6 +:103C2300AC44EB75F00FA4244BF582E43475F583B3 +:103C33001237C800017700907636E004F0E0FB7598 +:103C4300F00FA42441F582E43475F5837440F0EB5E +:103C530075F00FA42442F582E43475F583748CF077 +:103C6300EB75F00FA42443F582E43475F583123722 +:103C7300C80000AC44EB75F00FA42447F582E4348C +:103C830075F5831237C80000AC44EB75F00FA4241C +:103C93004BF582E43475F5831237C8000177009041 +:103CA3007636E004F0E0FF75F00FA42441F582E4DA +:103CB3003475F5837440F0EF75F00FA42442F58258 +:103CC300E43475F583748FF0907636E004F0E0FF0A +:103CD30075F00FA42441F582E43475F5837441F043 +:103CE300EF75F00FA42442F582E43475F5837484F0 +:103CF300F0907636E004F0E0FF75F00FA42441F570 +:103D030082E43475F5837461F0EF75F00FA42442F7 +:103D1300F582E43475F5837481F0907636E004F02F +:103D2300E0FF75F00FA42441F582E43475F5837444 +:103D330061F0EF75F00FA42442F582E43475F58346 +:043D43007401F022F5 +:103D4700C0E0C0F0C083C082C0D0E8C0E0E9C0E0F6 +:103D5700EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFB1 +:103D6700C0E0907FA2E090767FF0907F74E090763D +:103D770087F0907F75E0907688F0907F98E0440216 +:103D8700F0907696E0FF20E10C4402F0908003F07B +:103D9700D232124AC490767FE020E250907687E0D4 +:103DA700FEA3E07C002400F534EC3EF533907698D2 +:103DB700E0FDAE33AF341236D8907687EFF0D22FCE +:103DC700303129203F26C231907F94E054CFF090C4 +:103DD7007F9AE030E404D22DC22C907F9AE020E550 +:103DE70004C22DD22C907F94E04430F0124A501236 +:103DF7001B04302F12124216C22F75E80112168AC1 +:103E070075E80DD22B800575E801C22B202B349065 +:103E17007619E0FFB4010E90767C7467F0A3740600 +:103E2700F0A3740BF0EFB4020B90767CE4F0A3F0F0 +:103E3700A3740CF0EFB4030B90767CE4F0A3F0A32B +:103E47007418F075CAD375CBFED2CA303404C234A5 +:103E57008002D2345391EF907FAB7402F0F0907FE1 +:103E670098E054FDF0D0E0FFD0E0FED0E0FDD0E0D8 +:103E7700FCD0E0FBD0E0FAD0E0F9D0E0F8D0D0D029 +:083E870082D083D0F0D0E032BC +:103E8F00907692E014601D147002E14424026002E7 +:103E9F00E1D49076947401F0908000F0E490768EE7 +:103EAF00F0D23122907619E0FFB4011BE4907FF23B +:103EBF00F0907FF37430F0907FFF74FCF090769762 +:103ECF00E054FDF054FBF0EFB4021BE4907FF2F0EE +:103EDF00907FF37434F0907FFF74FCF0907697E04E +:103EEF004402F054FBF0EFB40318E4907FF2F0902B +:103EFF007FF37464F0907FFF74FCF0907697E0444A +:103F0F0004F0907694E04401F0908000F0303F0987 +:103F1F00907697E054FEF08007907697E04401F09A +:103F2F00907697E0908002F09076987404F09076F7 +:103F3F008E7401F022907619E0FFB4011BE4907F9C +:103F4F00F2F0907FF37444F0907FFF74FCF0907662 +:103F5F0097E054FDF054FBF0EFB4021BE4907FF2B6 +:103F6F00F0907FF3744CF0907FFF74FCF090769795 +:103F7F00E04402F054FBF0EFB40318E4907FF2F04A +:103F8F00907FF37494F0907FFF74FCF0907697E03D +:103F9F004404F0907694E054FEF0908000F0303FAF +:103FAF0009907697E054FEF08007907697E04401F1 +:103FBF00F0907697E0908002F09076987406F090EB +:063FCF00768E7402F02260 +:103FD500C0E0C083C0825391EF907FAAE04402F015 +:103FE500907FC7E0F511750F00750D00D233D082B3 +:053FF500D083D0E03292 +:063FFA00124AC4C231228C +:10400000E511D3940050022106907689E0C394080C +:10401000400221067440250FF582E4347EF583E0EA +:10402000F517E50D600E908005E517F0907689E0B4 +:1040300004F001DAE5171237F940C1024067054084 +:104040007A0640980740C10C40C10D40C70F40CBD5 +:10405000F640CBF840CBFA40CBFB40CBFC40CBFE4C +:1040600040CBFF000040DA907E41E0908005F09068 +:104070007689E004F07511018060907E41E09080C7 +:1040800005F0907E42E0908005F0907689E004F0A3 +:10409000E004F07511018042907E41E0908005F0CF +:1040A000907E42E0908005F0907E43E0908005F0A5 +:1040B000907689E004F0E004F0E004F075110180EE +:1040C00019D23BD23C8013D23B800F908005E5177C +:1040D000F0907689E004F0751101203B04050D8015 +:1040E0001F303C1C907E41E0908005F0907E42E0C5 +:1040F000908005F0907689E004F0E004F0751101FD +:10410000050F15110100E5117010C233F50DF50F03 +:0B411000907FC77404F0C23BC23C2249 +:10411B0090768DE064017027302708C227120800C3 +:10412B0012174A302808C22812387412174A302A3C +:10413B000EE490768DF0C22A907FB4E04402F090AA +:10414B00763FE0B40105E4F012326F907641E0B4B3 +:10415B000105E4F012349A907640E0B40103123476 +:10416B009A907F9BE020E402C23F907F9BE030E47B +:10417B0002D23F907F9BE020E502C23E907F9BE006 +:10418B0030E502D23EA241303F01B3501FA23F9215 +:10419B0041303F09907697E054FEF0800790769778 +:1041AB00E04401F0907697E0908002F0303F34903D +:1041BB007619E0FFB4010E90767C7467F0A3740659 +:1041CB00F0A3740BF0EFB4020BE490767CF0A3F049 +:1041DB00A3740CF0EFB4030BE490767CF0A3F0A384 +:1041EB007418F0A240303E01B3501FA23E924030F3 +:1041FB003E09907695E04404F08007907695E05464 +:0B420B00FBF0907695E0908001F0221F +:10421600907619E064017035907687E0FFD3942D8F +:10422600402B9076867401F0907685E004F0E0D31A +:10423600940F4019E4F0EFD3943140089076197446 +:1042460003F080069076197402F0123E8F9076196C +:10425600E0B4022C907687E0FFC3942F5022EFD370 +:10426600942A401C9076867401F0907685E004F0DE +:10427600E0D3940F400AE4F090761904F0123E8FD2 +:10428600907619E0B40226907687E0D39431401DEB +:104296009076867401F0907685E004F0E0D3940F72 +:1042A600400BE4F09076197403F0123E8F90761965 +:1042B600E06403703F907687E0FFC3945F503590CB +:1042C60076867401F0907685E004F0E0D3940F4092 +:1042D60023E4F0EFC3942F500CEFD3942A400690BA +:1042E60076197401F0EFD3942F4006907619740274 +:1042F600F0123E8F907686E07005907685F022E487 +:05430600907686F02214 +:10430B00E4907696F0908003F0907FE07490F090BC +:10431B007FE17404F0E4907FDDF0907FA1F0538E89 +:10432B00F875880575B82075F801438E30F5C8759A +:10433B00CA7F75CBF843A82012074AC22CC22DC2E4 +:10434B002BC22F907FFC74DDF0907FFF74FFF090F9 +:10435B007F97E04401F09076197401F0E490768534 +:10436B00F0A3F0907681F0907680F0124958120FFE +:10437B00C6124A8D907F97E04408F0E054B9F0D212 +:10438B00302030181247B41230001240001242167F +:10439B00124A50121B04121661124216C22FC2315E +:1043AB00C232C234C233C229C227C228E4F51190EB +:1043BB007689F090763FF0907641F0907640F090D1 +:1043CB00768AF0A3F0A304F0E4A3F0907699F022A0 +:1043DB00124DA3400281A0907FEBE024FE601E14DF +:1043EB00604614606E1470028191240460028199FE +:1043FB007405907FD4F07400907FD5F022907FEA03 +:10440B00E0FF1249FF8B208A218922EA496011CEF5 +:10441B00EACEEE907FD4F0CFE9CFEF907FD5F022AC +:10442B00907FB4E04401F022907FEAE0FF1248B0A5 +:10443B008B208A218922EA496011CEEACEEE907F49 +:10444B00D4F0CFE9CFEF907FD5F022907FB4E0444A +:10445B0001F022907FEAE0FF907EC0E0FDA3E0FB3D +:10446B001217948B208A218922EA496011CEEACE59 +:10447B00EE907FD4F0CFE9CFEF907FD5F022907FF5 +:10448B00B4E04401F022907FB4E04401F022907F2D +:05449B00B4E04401F053 +:0144A00022F9 +:1044A100C2AFD224907F937430F0907F9C74BBF0A4 +:1044B100907F96E04430F0E05430F0907F94743077 +:1044C100F0907F9D74CFF0907F9774A0F0907F95CE +:1044D10074C0F0907F9E7403F0907F99E030E20900 +:1044E10090051974A0F0E4A3F0C225C222C223C230 +:1044F10026124AC4122DA9123BD3124559123A422F +:104501009076687401F0700F124BBB1207FE124DCA +:10451100A1121B4012149612430B907FAFE044018D +:10452100F0907FAEE0441FF0907FAC74FFF0907F7D +:10453100ADF0907FDEF0907FDFF0907FABF0907F69 +:10454100A9F0907FAAF05391EF43D820D2E843D845 +:084551002053A8A043A880221A +:10455900E4907636F0E0FF75F003A42432F582E4A6 +:104569003475F583E4F0EF75F003A42433F582E4A0 +:104579003475F5837401F0907636E004F0E0FF7548 +:10458900F003A42432F582E43475F583E4F0EF7581 +:10459900F003A42433F582E43475F5837402F090B2 +:1045A9007636E004F0E0FF75F003A42432F582E4E6 +:1045B9003475F583E4F0EF75F003A42433F582E450 +:1045C9003475F5837403F0907636E004F0E0FF75F6 +:1045D900F003A42432F582E43475F583E4F0EF7531 +:1045E900F003A42433F582E43475F5837404F022CE +:0C45F900787FE4F6D8FD7581380246405A +:1046050002475AE493A3F8E493A34003F68001F22A +:1046150008DFF48029E493A3F85407240CC8C333B6 +:10462500C4540F4420C8834004F456800146F6DF85 +:10463500E4800B0102040810204080900C8FE47E7A +:10464500019360BCA3FF543F30E509541FFEE4937A +:10465500A360010ECF54C025E060A840B8E493A341 +:10466500FAE493A3F8E493A3C8C582C8CAC583CA6C +:10467500F0A3C8C582C8CAC583CADFE9DEE780BE24 +:10468500907FECE0907683F0E014601D14602A14AE +:10469500603714604424047050907691E0907F0058 +:1046A500F0907FB57401F08047907692E0907F009E +:1046B500F0907FB57401F08037907690E0907F00A0 +:1046C500F0907FB57401F08027907684E0907F00AC +:1046D500F0907FB57401F08017907693E0907F009D +:1046E500F0907FB57401F08007907FB4E04401F04D +:0246F500D322CE +:1046F700C0E0C0F0C083C082C0D0E8C0E0E9C0E03D +:10470700EAC0E0EBC0E0ECC0E0EDC0E0EEC0E0EFF7 +:10471700C0E0C2CAC2CF907F98E04401F0302E03B8 +:104727001214A6907F98E054FEF053A8FA1216616F +:10473700D0E0FFD0E0FED0E0FDD0E0FCD0E0FBD041 +:10474700E0FAD0E0F9D0E0F8D0D0D082D083D0F032 +:03475700D0E0327D +:10475A00E4907666F01244A1202613907666E0C3B0 +:10476A009402500AE004F0D242124AF680EA302655 +:10477A0005122801C22630252B907696E054FCF0CB +:10478A00908003F0121496907696E04403F090809D +:10479A0003F0E4907667F0907667E004F0E0B44BBB +:0A47AA00F6123FFA12411B80C522EF +:1047B400E490769BF090769BE0FF04F0EF6008E0D5 +:1047C4002408F8E4F680EE907696E054FBF054F773 +:1047D400F0908003F0E4F518D235F50EF510D236DA +:1047E400751211751322C237C239C238F516F51481 +:0B47F400F51AF50DC23BC23CC23D228D +:10480000907FECE0907683F0E01460171460211440 +:10481000602B14603224047038907FEAE090769127 +:10482000F08035907FEAE0907692F0123E8F8028FB +:10483000907FEAE0907690F0121800801B907FEA5B +:10484000E0907684F08011907FEAE0907693F0809B +:0A48500007907FB4E04401F0D3228A +:10485A00E4907626F0907626E0FF75F003A42434DF +:10486A00F582E43475F583E0FE907FECE0FDEE6DB1 +:10487A00600EEFC394045008907626E004F080D5C9 +:10488A00EFB40408907FB4E04401F022EF75F0031E +:10489A00A42432F582E43475F583E0907F00F09029 +:0648AA007FB57401F0224D +:0248B0008F2E49 +:1048B200E4F52F7530FF7531067532BEAB30AA3183 +:1048C200A9329000011236ABB4031FAF2F052FEFB0 +:1048D200652E7001221236927E0029FFEE3AC9EF50 +:1048E200C97530FFF531893280D27B007A007900B8 +:0148F20022A3 +:0C48F300C237E4F50EF510C236F51422B1 +:10490000022FE700023D4700024D4600024BD50052 +:10491000024B6000022FFF00024BED00024B8100B2 +:10492000024C0400023FD500024C1B00024C320036 +:10493000024C4900024C6000024C7700024C8E0091 +:10494000024CA500024CBC00024CD300024CEA0011 +:08495000024D0100024D1800A8 +:104958009076467480F0E4A3F0A3F0A3F0A3F0A34C +:10496800F0A3F0A3F0A3F0A37480F0E4A3F0A3F005 +:10497800A3F0A3F0A3F0A3F0A37440F0E4A3F0A382 +:104988007440F0E4A3F0A3F0A3F0A3F0A3F0A3F025 +:10499800A37440F0E4A3F0A37440F0E4A3F0A3F000 +:0549A800A3F0A3F022C2 +:1049AD00E4907625F0907625E0FF75F003A424348D +:1049BD00F582E43475F583E0FE907FECE0FDEE6D5D +:1049CD00600EEFC394045008907625E004F080D576 +:1049DD00EFB40408907FB4E04401F022907EC0E073 +:1049ED00FEEF75F003A42432F582E43475F583EE01 +:0249FD00F022A6 +:1049FF00E4FE751DFF751E05751F12AB1DAA1EA9BE +:104A0F001F9000011236AB6402702FCDEECD0EED6C +:104A1F006F70012290000212370E85F01BF51C6299 +:104A2F001BE51B621CE51C621B29FDE51B3AC9ED4A +:104A3F00C9751DFFF51E891F80C17B007A007900A3 +:014A4F002244 +:104A5000302D39C22D907619E0FFB4010DE4907627 +:104A60007CF0A374F8F0A3740AF0EFB4020DE490A4 +:104A7000767CF0A374F0F0A3740BF0EFB4030DE4B4 +:0D4A800090767CF0A374F8F0A37417F02278 +:104A8D00E4FF74562FF582E43476F583E0FE742846 +:104A9D002FF582E43480F583EEF0745E2FF582E419 +:104AAD003476F583E0FE74382FF582E43480F58397 +:064ABD00EEF00FBF08CC73 +:014AC30022D0 +:104AC400E4907236F0A3F0907F97E054FBF0E4900A +:104AD4007233F0907232F090720104F0E490723309 +:104AE400F0907232F090720104F0907F97E04404E9 +:024AF400F022AE +:104AF600907FD6E054FBF0E04408F0304204E044F6 +:104B060002F07FDC7E05124D2F907FD6E054F7F041 +:054B1600E04404F02260 +:104B1B00907FEBE0147014907FE9E0247F70041217 +:104B2B00485A22907FB4E04401F022907FB4E044D5 +:034B3B0001F02264 +:104B3E00907FEBE0147013907FE9E014700412493B +:104B4E00AD22907FB4E04401F022907FB4E04401A6 +:024B5E00F02243 +:104B6000C0E0C083C0825391EF907FAB7410F0908F +:104B70007696E054FDF0908003F0D082D083D0E0B0 +:014B80003202 +:104B8100C0E0C083C0825391EF907FAAE04401F05E +:0F4B9100C22990768D7401F0D082D083D0E032AB +:104BA000907FEAE0907682F0E4907691F0907692B1 +:0B4BB000F0907690F0907693F0D32206 +:104BBB00907FD6E030E712E04401F07F147E0012C4 +:0A4BCB004D2F907FD6E054FEF0223B +:104BD500C0E0C083C082D2255391EF907FAB7408AB +:084BE500F0D082D083D0E03251 +:104BED00C0E0C083C0825391EF907FA9E04401F0F3 +:074BFD00D082D083D0E0322A +:104C0400C0E0C083C0825391EF907FA9E04402F0DA +:074C1400D082D083D0E03212 +:104C1B00C0E0C083C0825391EF907FA9E04404F0C1 +:074C2B00D082D083D0E032FB +:104C3200C0E0C083C0825391EF907FAAE04404F0A9 +:074C4200D082D083D0E032E4 +:104C4900C0E0C083C0825391EF907FA9E04408F08F +:074C5900D082D083D0E032CD +:104C6000C0E0C083C0825391EF907FAAE04408F077 +:074C7000D082D083D0E032B6 +:104C7700C0E0C083C0825391EF907FA9E04410F059 +:074C8700D082D083D0E0329F +:104C8E00C0E0C083C0825391EF907FAAE04410F041 +:074C9E00D082D083D0E03288 +:104CA500C0E0C083C0825391EF907FA9E04420F01B +:074CB500D082D083D0E03271 +:104CBC00C0E0C083C0825391EF907FAAE04420F003 +:074CCC00D082D083D0E0325A +:104CD300C0E0C083C0825391EF907FA9E04440F0CD +:074CE300D082D083D0E03243 +:104CEA00C0E0C083C0825391EF907FAAE04440F0B5 +:074CFA00D082D083D0E0322C +:104D0100C0E0C083C0825391EF907FA9E04480F05E +:074D1100D082D083D0E03214 +:104D1800C0E0C083C0825391EF907FAAE04480F046 +:074D2800D082D083D0E032FD +:104D2F008E358F36E5361536AE35700215354E6039 +:074D3F000512148580EE222D +:104D4600C0E0C083C0825391EF907FAB7404F0D073 +:064D560082D083D0E032A0 +:104D5C00907682E0907F00F0907FB57401F0D322C2 +:094D6C00C22553D8EF43D82032D0 +:074D75005398FE5398FD3234 +:074D7C0053C0FE53C0FD32DD +:064D83005391BFD22D3256 +:064D890053917FD22C3291 +:044D8F005391DF322B +:044D930053D8F732C8 +:044D9700121730229D +:034D9B00C28D3294 +:034D9E00C28F328F +:024DA100D3221B +:024DA300D32219 +:024DA500D32217 +:024DA700D32215 +:024DA900D32213 +:024DAB00C32221 +:00000001FF +/* +Source: EMI62SFW.HEX +VERSION=1.04.062 +DATE=16.10.2002 +*/ -- cgit v0.10.2 From 5f24e2d6b40f0c74ce5bfaddfdb89f9bfae4b594 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 30 May 2008 18:49:51 +0300 Subject: ti_usb_3410_5052: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/usb/serial/ti_fw_3410.h b/drivers/usb/serial/ti_fw_3410.h deleted file mode 100644 index 71e8857..0000000 --- a/drivers/usb/serial/ti_fw_3410.h +++ /dev/null @@ -1,885 +0,0 @@ -/* vi: ts=8 sw=8 - * - * TI 3410 USB Serial Driver Firmware Header - * - * Copyright (C) 2004 Texas Instruments - * - * 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 _TI_FW_3410_H_ -#define _TI_FW_3410_H_ - -/* firmware 9/10/04 FW3410_Special_StartWdogOnStartPort */ - -static unsigned char ti_fw_3410[] = { -0xC2, 0x35, /* firmware image length excluding header, little endian */ -0x00, /* placeholder for checksum */ - -0x02,0x00,0x1e,0x02,0x1a,0xdb,0xff,0xff,0xff,0xff,0xff,0x02,0x32,0xcb,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x33,0x76,0x75,0x81, -0xce,0x90,0xfd,0xe8,0x85,0x83,0xa0,0x12,0x34,0xea,0xec,0x4d,0x60,0x6a,0x78,0xab, -0x80,0x03,0x76,0x00,0x18,0xb8,0x9c,0xfa,0x78,0x7f,0x80,0x03,0x76,0x00,0x18,0xb8, -0x65,0xfa,0x78,0x20,0x80,0x03,0x76,0x00,0x18,0xb8,0x20,0xfa,0x90,0xfd,0xdd,0xae, -0x83,0xaf,0x82,0x90,0xfb,0xf8,0x12,0x00,0xa1,0x60,0x05,0xe4,0xf0,0xa3,0x80,0xf6, -0x90,0xfd,0xe8,0xa8,0x82,0x90,0xfd,0xe8,0xa9,0x82,0xe8,0xc3,0x99,0x50,0x05,0x76, -0x00,0x08,0x80,0xf6,0x90,0x00,0xff,0x12,0x00,0xaa,0x90,0x01,0x03,0x12,0x00,0xaa, -0x90,0x01,0x07,0x12,0x00,0xaa,0x90,0x01,0x0b,0x12,0x00,0xc8,0x90,0x01,0x11,0x12, -0x00,0xc8,0x90,0x01,0x17,0x12,0x00,0xc8,0x75,0xd0,0x00,0x12,0x33,0xc8,0x02,0x01, -0x1d,0xef,0x65,0x82,0x70,0x03,0xee,0x65,0x83,0x22,0xe4,0x93,0xf8,0x74,0x01,0x93, -0xf9,0x74,0x02,0x93,0xfe,0x74,0x03,0x93,0xf5,0x82,0x8e,0x83,0xe8,0x69,0x70,0x01, -0x22,0xe4,0x93,0xf6,0xa3,0x08,0x80,0xf4,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74, -0x02,0x93,0xfe,0x74,0x03,0x93,0xff,0x74,0x04,0x93,0xf8,0x74,0x05,0x93,0xf5,0x82, -0x88,0x83,0x12,0x00,0xa1,0x70,0x01,0x22,0xe4,0x93,0xa3,0xa8,0x83,0xa9,0x82,0x8c, -0x83,0x8d,0x82,0xf0,0xa3,0xac,0x83,0xad,0x82,0x88,0x83,0x89,0x82,0x80,0xe3,0x21, -0x21,0x04,0x92,0x80,0x80,0x04,0x92,0xac,0xae,0x04,0x92,0xfd,0xe8,0x04,0x94,0x04, -0x94,0xfb,0xf3,0x04,0x99,0x04,0x94,0xfb,0xf3,0x04,0xf9,0x04,0xf9,0x80,0xfe,0xd0, -0xf0,0x30,0xf0,0x09,0x20,0xf3,0x03,0xf6,0x80,0x10,0xf7,0x80,0x0d,0x30,0xf1,0x09, -0x20,0xf3,0x03,0xf2,0x80,0x04,0xf3,0x80,0x01,0xf0,0x20,0xf4,0x04,0xfc,0xd0,0xe0, -0xcc,0x22,0xcc,0xc0,0xe0,0x12,0x01,0x5a,0x02,0x01,0x4b,0xbc,0x00,0x05,0xd0,0xf0, -0xac,0xf0,0x22,0xc3,0x13,0xdc,0xfc,0x02,0x01,0x21,0xbf,0x00,0x09,0xed,0x25,0x82, -0x75,0xf0,0x01,0xf8,0xe6,0x22,0xbf,0x01,0x0f,0xed,0x25,0x82,0xf5,0x82,0xee,0x35, -0x83,0xf5,0x83,0x75,0xf0,0x04,0xe0,0x22,0xed,0x25,0x82,0x75,0xf0,0x02,0xf8,0xe2, -0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xc3,0xe4,0x93,0xa3,0xc5,0xf0,0x95,0xf0,0xc0, -0xe0,0xc3,0xd0,0xf0,0xe4,0x93,0xa3,0x95,0xf0,0x40,0x12,0xa3,0xa3,0xc3,0xe5,0xf0, -0x33,0x50,0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0x50,0x02,0x05,0x83,0x74,0x01,0x93, -0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xe4,0x93,0x70, -0x09,0x74,0x01,0x93,0x70,0x04,0xa3,0xa3,0x80,0x0c,0x74,0x02,0x93,0x65,0xf0,0x60, -0x05,0xa3,0xa3,0xa3,0x80,0xe7,0x74,0x01,0x93,0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22, -0x12,0x02,0x5b,0x02,0x01,0xf2,0x12,0x02,0xaf,0x02,0x01,0xf2,0x12,0x02,0xd3,0x02, -0x01,0xf2,0x30,0xe0,0x07,0x20,0xe3,0x02,0xe6,0x22,0xe7,0x22,0x30,0xe1,0x07,0x20, -0xe3,0x02,0xe2,0x22,0xe3,0x22,0x30,0xe2,0x02,0xe0,0x22,0xe4,0x93,0x22,0x12,0x02, -0xd3,0x02,0x02,0x1a,0x12,0x02,0xaf,0x02,0x02,0x1a,0xab,0xf0,0x12,0x02,0x24,0xcb, -0xc5,0xf0,0xcb,0x22,0x30,0xe0,0x10,0x20,0xe3,0x06,0xe6,0xf5,0xf0,0x08,0xe6,0x22, -0xe7,0xf5,0xf0,0x09,0xe7,0x19,0x22,0x30,0xe1,0x10,0x20,0xe3,0x06,0xe2,0xf5,0xf0, -0x08,0xe2,0x22,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x30,0xe2,0x06,0xe0,0xf5,0xf0, -0xa3,0xe0,0x22,0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x00,0x03,0x74,0x09, -0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x74,0x04,0x22,0xbb,0x02,0x07,0x89,0x82, -0x8a,0x83,0x74,0x10,0x22,0x74,0x0a,0x22,0x02,0x02,0x7b,0xbb,0x00,0x07,0xe9,0x25, -0x82,0xf8,0x74,0x01,0x22,0xbb,0x01,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83, -0xf5,0x83,0x74,0x04,0x22,0xbb,0x02,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83, -0xf5,0x83,0x74,0x10,0x22,0xe9,0x25,0x82,0xf8,0x74,0x02,0x22,0x02,0x02,0xaf,0xbf, -0x00,0x05,0xed,0xf8,0x74,0x01,0x22,0xbf,0x01,0x07,0x8d,0x82,0x8e,0x83,0x74,0x04, -0x22,0xbf,0x02,0x07,0x8d,0x82,0x8e,0x83,0x74,0x10,0x22,0xed,0xf8,0x74,0x02,0x22, -0x02,0x02,0xd3,0xbf,0x00,0x07,0xed,0x25,0x82,0xf8,0x74,0x01,0x22,0xbf,0x01,0x0d, -0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x04,0x22,0xbf,0x02,0x0d, -0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x10,0x22,0xed,0x25,0x82, -0xf8,0x74,0x02,0x22,0x02,0x03,0x07,0xc0,0xe0,0x12,0x02,0x5b,0x02,0x03,0x1f,0xc0, -0xe0,0x12,0x02,0xaf,0x02,0x03,0x1f,0xc0,0xe0,0x12,0x02,0xd3,0x02,0x03,0x1f,0x30, -0xe0,0x0b,0x20,0xe3,0x04,0xd0,0xe0,0xf6,0x22,0xd0,0xe0,0xf7,0x22,0x30,0xe1,0x0b, -0x20,0xe3,0x04,0xd0,0xe0,0xf2,0x22,0xd0,0xe0,0xf3,0x22,0xd0,0xe0,0xf0,0x22,0xc9, -0xcd,0xc9,0xca,0xce,0xca,0xcb,0xcf,0xcb,0x12,0x03,0x52,0xed,0xf9,0xee,0xfa,0xef, -0xfb,0x22,0xbb,0x00,0x2f,0xbf,0x00,0x0a,0xfa,0xed,0xf8,0xe7,0xf6,0x08,0x09,0xda, -0xfa,0x22,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x03,0x6f,0x09,0xa3,0xe7, -0xf0,0xd8,0xfa,0x22,0x02,0x03,0x7a,0xfa,0xed,0xf8,0xe7,0xf2,0x08,0x09,0xda,0xfa, -0x22,0x02,0x03,0x84,0xbb,0x01,0x4d,0xbf,0x00,0x14,0x89,0x82,0x8a,0x83,0xf9,0xed, -0xf8,0x02,0x03,0x96,0x08,0xa3,0xe0,0xf6,0xd9,0xfa,0x22,0x02,0x03,0xa7,0xbf,0x01, -0x22,0x8d,0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe0, -0xa3,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xea,0xd8,0xe8,0x22, -0x02,0x03,0xca,0x8d,0x82,0x8e,0x83,0xf9,0xed,0xf8,0xe0,0xf2,0x08,0xa3,0xd9,0xfa, -0x22,0x02,0x03,0xd4,0xbb,0x02,0x4d,0xbf,0x00,0x12,0x89,0x82,0x8a,0x83,0xf9,0xed, -0xf8,0x02,0x03,0xe6,0x08,0xa3,0xe4,0x93,0xf6,0xd9,0xf9,0x22,0xbf,0x01,0x23,0x8d, -0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe4,0x93,0xa3, -0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xe9,0xd8,0xe7,0x22,0x02, -0x04,0x19,0x89,0x82,0x8a,0x83,0xf9,0xed,0xf8,0xe4,0x93,0xf2,0x08,0xa3,0xd9,0xf9, -0x22,0x02,0x04,0x2a,0xbf,0x00,0x0d,0xfa,0xed,0xf8,0xe3,0xf6,0x08,0x09,0xda,0xfa, -0x22,0x02,0x04,0x34,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x04,0x41,0x09, -0xa3,0xe3,0xf0,0xd8,0xfa,0x22,0x02,0x04,0x4c,0xfa,0xed,0xf8,0xe3,0xf2,0x08,0x09, -0xda,0xfa,0x22,0x02,0x04,0x56,0xe6,0xfb,0x08,0xe6,0xfa,0x08,0xe6,0xf9,0x04,0xf6, -0x18,0x70,0x01,0x06,0x22,0xe6,0xff,0x08,0xe6,0xfe,0x08,0xe6,0xfd,0x22,0xef,0xf0, -0xa3,0xee,0xf0,0xa3,0xed,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22, -0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xfd,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0, -0xf9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xf9,0x00,0x61,0x05,0x68,0x00, -0x26,0x05,0x8f,0x00,0x33,0x0a,0x00,0x00,0x61,0x0a,0x6c,0x00,0x66,0x15,0x1d,0x00, -0x61,0x0c,0xf0,0x00,0x61,0x09,0xa0,0x00,0x61,0x09,0xd7,0x00,0x61,0x0d,0xb7,0x00, -0x61,0x0b,0xe8,0x00,0x61,0x0a,0x13,0x00,0x61,0x0a,0x48,0x00,0x61,0x17,0x15,0x00, -0x33,0x17,0x28,0x00,0x34,0x1d,0xf6,0x00,0x43,0x1e,0xa1,0x00,0x44,0x20,0x0e,0x00, -0x44,0x1f,0xfc,0x00,0x47,0x1e,0xc8,0x00,0x47,0x1f,0x6d,0x00,0x4d,0x1f,0xbe,0x00, -0x4f,0x1e,0xea,0x00,0x58,0x32,0x56,0x00,0x61,0x7c,0xcc,0x7d,0xff,0x12,0x1c,0xa7, -0x22,0x90,0xff,0xfc,0xe0,0x20,0xe7,0x2d,0xc2,0xaf,0xae,0x59,0xaf,0x58,0x75,0x5a, -0x20,0xe5,0x5a,0x14,0xc5,0x5a,0x60,0x19,0xe4,0xfe,0x7f,0x05,0xee,0x4f,0xce,0x24, -0xff,0xce,0xcf,0x34,0xff,0xcf,0x60,0x07,0xe4,0x90,0xff,0x92,0xf0,0x80,0xed,0x80, -0xe0,0x8e,0x59,0x8f,0x58,0x22,0x12,0x05,0x01,0x7d,0x07,0x7c,0xb7,0x12,0x32,0x72, -0x7d,0x0f,0x7c,0x6e,0x12,0x32,0x8c,0x78,0x9d,0x7a,0x06,0xe4,0xf6,0x08,0xda,0xfc, -0x7a,0x06,0x12,0x05,0xc4,0x7c,0x03,0x12,0x0e,0x4c,0x12,0x21,0x4a,0xe4,0xfe,0xff, -0x7c,0x0f,0x12,0x31,0xfb,0xd2,0xa8,0x22,0x12,0x30,0xe6,0xe4,0x90,0xfc,0x38,0xf0, -0x90,0xff,0xf0,0xe0,0x30,0xe4,0x08,0x74,0x01,0x90,0xfc,0x39,0xf0,0x80,0x05,0xe4, -0x90,0xfc,0x39,0xf0,0x7d,0x0a,0x7c,0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12, -0x30,0xe6,0x90,0xfc,0x39,0xe0,0x14,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x44,0x10,0xf0, -0x7c,0x00,0x12,0x25,0xbf,0x80,0x19,0x90,0xfc,0x39,0xe0,0x70,0x0e,0x90,0xff,0xf0, -0xe0,0x54,0xef,0xf0,0x7c,0x00,0x12,0x25,0xbf,0x80,0x05,0x7c,0x17,0x12,0x25,0xbf, -0x12,0x31,0x69,0x22,0x90,0xff,0xf0,0xe0,0x54,0xab,0xf0,0x90,0xff,0xf0,0xe0,0x44, -0x20,0xf0,0x22,0x8c,0x37,0x8d,0x36,0x78,0x82,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe, -0xec,0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x80,0xf6,0x78,0x82,0xe6, -0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec, -0x54,0x0f,0xfc,0x7d,0x80,0x12,0x17,0x46,0x78,0x80,0xe6,0x70,0x0d,0xad,0x3a,0xae, -0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe, -0xf0,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x1e,0x78,0x82,0xe6,0xfd,0x08,0xe6, -0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x44, -0x01,0x90,0xff,0xf3,0xf0,0x02,0x06,0xd0,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed, -0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3, -0xf0,0x80,0x2b,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01, -0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40, -0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x82, -0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02, -0x0e,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38, -0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe, -0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x44,0x01,0x90,0xff,0xf3,0xf0, -0x78,0x83,0xe6,0x24,0x03,0xf6,0x18,0xe6,0x34,0x00,0xf6,0x78,0x80,0xe6,0x24,0xfe, -0x50,0x09,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x07,0x90,0xff,0xf0,0xe0,0x44, -0x02,0xf0,0xe4,0x90,0xff,0xf1,0xf0,0x78,0x81,0x76,0x00,0x78,0x80,0xe6,0x24,0xff, -0xfc,0xe4,0x34,0xff,0xfd,0x78,0x81,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64, -0x80,0xcd,0x64,0x80,0x9d,0x40,0x2f,0x12,0x08,0xa4,0x40,0x0f,0x78,0x81,0xe6,0xad, -0x3a,0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc, -0x78,0x82,0x86,0x83,0x08,0x86,0x82,0xec,0xf0,0x78,0x81,0x06,0xa3,0x78,0x82,0xa6, -0x83,0x08,0xa6,0x82,0x80,0xb5,0x12,0x08,0xa4,0x40,0x0f,0x78,0x81,0xe6,0xad,0x3a, -0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78, -0x82,0x86,0x83,0x08,0x86,0x82,0xec,0xf0,0x78,0x80,0xe6,0xad,0x3a,0xae,0x39,0xaf, -0x38,0x12,0x03,0x0f,0x7c,0x00,0x22,0x8c,0x37,0x8d,0x36,0x78,0x82,0xed,0xf6,0x08, -0xec,0xf6,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x81, -0xf6,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00, -0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x81,0x12,0x17,0x46,0x78,0x81,0xe6,0x70, -0x03,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,0x54, -0xfd,0xf0,0x80,0x1b,0x78,0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f, -0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x90,0xff,0xf3,0xf0,0x80,0x5b,0x78, -0x82,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12, -0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,0xf0,0x80,0x21,0x78,0x82,0xe6,0xfd,0x08,0xe6, -0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90, -0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x82,0xe6,0xfd,0x08, -0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff, -0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x83,0xe6,0x24,0x0a,0xf6, -0x18,0xe6,0x34,0x00,0xf6,0x78,0x80,0x76,0x00,0x78,0x81,0xe6,0x24,0xff,0xfc,0xe4, -0x34,0xff,0xfd,0x78,0x80,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd, -0x64,0x80,0x9d,0x40,0x21,0x78,0x82,0x86,0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1, -0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18,0x22,0x78,0x80,0x06,0x78,0x83,0x06,0xe6, -0x18,0x70,0x01,0x06,0x80,0xc3,0x90,0xff,0xf0,0xe0,0x44,0x01,0xf0,0x78,0x82,0x86, -0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,0xf0,0x12,0x08,0xbf,0x40,0x03,0x7c,0x18, -0x22,0x7c,0x00,0x22,0x90,0xff,0xf0,0xe0,0x20,0xe7,0x12,0x90,0xff,0xf0,0xe0,0x30, -0xe5,0x09,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x90, -0xff,0xf0,0xe0,0x20,0xe3,0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0, -0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x8c,0x42,0x8d,0x41,0x7c,0x00, -0xed,0x54,0xf0,0xfd,0xec,0x70,0x03,0xed,0x64,0x30,0x70,0x05,0x75,0x3e,0x03,0x80, -0x03,0x75,0x3e,0x04,0xac,0x3e,0x12,0x0f,0x69,0x75,0x83,0x00,0x85,0x83,0x40,0xe5, -0x41,0x54,0x0f,0xf5,0x3f,0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x03,0x70,0x35,0xe5, -0x3e,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x02,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, -0xe0,0x30,0xe6,0x05,0x12,0x10,0x4b,0x80,0x19,0xe5,0x3e,0x24,0x9d,0xf8,0xc6,0x54, -0xfb,0xf6,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74, -0x0f,0xf0,0x80,0x59,0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x04,0x70,0x48,0xe5,0x3e, -0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x02,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0, -0x30,0xe5,0x07,0xac,0x42,0xad,0x41,0x12,0x1c,0x3c,0xe5,0x42,0x30,0xe2,0x15,0x78, -0xad,0xe6,0x30,0xe0,0x0f,0x78,0xad,0xe6,0x30,0xe1,0x09,0xe4,0xff,0x04,0xfe,0x7c, -0x04,0x12,0x31,0xfb,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0x74,0x0f,0xf0,0x80,0x07,0xe4,0xfc,0x7d,0xee,0x12,0x1c,0x3c,0xc2,0x03,0x22, -0x12,0x30,0xe6,0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x90,0xfc,0x38,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0xfc,0x39,0xf0,0xc2,0x03,0x7d,0x02,0x7c,0x00, -0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24, -0x9d,0xf8,0xe6,0x30,0xe1,0x07,0x7c,0x13,0x12,0x25,0xbf,0x80,0x0f,0x90,0xfc,0x39, -0xe0,0xfd,0x78,0x95,0xe6,0xfc,0x12,0x13,0xc8,0x12,0x25,0xbf,0x12,0x31,0x69,0x22, -0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x7d,0x00,0x12,0x0f,0x09,0x12,0x25,0xbf,0x12, -0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24,0x9d,0xf8,0xe6,0x30, -0xe2,0x07,0x7c,0x13,0x12,0x25,0xbf,0x80,0x1b,0x78,0x95,0xe6,0x24,0x9d,0xf8,0xe6, -0x20,0xe1,0x07,0x7c,0x12,0x12,0x25,0xbf,0x80,0x0a,0x78,0x95,0xe6,0xfc,0x12,0x13, -0xec,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec, -0x24,0x9d,0xf8,0xe6,0x20,0xe2,0x07,0x7c,0x11,0x12,0x25,0xbf,0x80,0x0a,0x78,0x95, -0xe6,0xfc,0x12,0x14,0xed,0x12,0x25,0xbf,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78, -0x95,0xec,0xf6,0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x90,0xfc,0x3f,0xf0,0x78,0xa9,0xe6,0x24,0x0a,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0xfc,0x40,0xf0,0x78,0xa9,0xe6,0x24,0x03,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x62,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x63,0x8c,0x61,0xe4,0xec,0x33,0x33,0x54, -0x01,0x78,0x95,0xf6,0x60,0x08,0xe5,0x62,0x30,0xe1,0x03,0x78,0x95,0x06,0x78,0x95, -0xe6,0x90,0xfc,0x41,0xf0,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0x54,0x0c,0xfc,0xed,0x54,0xe6,0x8c,0x65,0xf5,0x64, -0xe5,0x61,0x30,0xe5,0x03,0x43,0x65,0x01,0xe5,0x62,0x20,0xe5,0x0e,0xe5,0x61,0x54, -0x7f,0x70,0x08,0xe5,0x61,0x20,0xe7,0x03,0x43,0x65,0x02,0xe5,0x61,0x30,0xe3,0x03, -0x43,0x65,0x10,0xe5,0x61,0x30,0xe2,0x03,0x43,0x65,0x20,0xe5,0x61,0x54,0x03,0x60, -0x03,0x43,0x65,0x40,0xe5,0x61,0x30,0xe1,0x03,0x43,0x65,0x80,0xe5,0x61,0x30,0xe4, -0x03,0x43,0x64,0x01,0xe5,0x61,0x30,0xe6,0x03,0x43,0x64,0x08,0xe5,0x62,0x20,0xe4, -0x0e,0xe5,0x61,0x54,0x7f,0x70,0x08,0xe5,0x61,0x20,0xe7,0x03,0x43,0x64,0x10,0x53, -0x65,0xfb,0x53,0x64,0x79,0xad,0x64,0xe5,0x65,0x90,0xfc,0x3a,0xcd,0xf0,0xa3,0xcd, -0xf0,0xe5,0x63,0x30,0xe3,0x0d,0xe5,0x63,0x54,0x30,0xc4,0x54,0x0f,0x90,0xfc,0x3d, -0xf0,0x80,0x05,0xe4,0x90,0xfc,0x3d,0xf0,0xe5,0x63,0x54,0x03,0x90,0xfc,0x3c,0xf0, -0xe5,0x63,0x54,0x04,0xc3,0x13,0x90,0xfc,0x3e,0xf0,0x90,0xfc,0x3c,0xe0,0x70,0x0e, -0x7d,0x35,0x7e,0xfc,0x7f,0x01,0x74,0x01,0x90,0x00,0x09,0x12,0x01,0x42,0x78,0xa9, -0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7c,0x00,0xfd,0x78, -0xa9,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7f,0x00,0x4c, -0xfe,0xef,0x4d,0x90,0xfc,0x38,0xf0,0xa3,0xce,0xf0,0xce,0xc2,0x03,0x7d,0x0a,0x7c, -0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x78, -0x9a,0x76,0x01,0x08,0x76,0xfc,0x08,0x76,0x38,0x78,0x97,0x76,0x0c,0x78,0x9a,0x12, -0x04,0x65,0x12,0x02,0x14,0x78,0x98,0xcb,0xf6,0xcb,0x08,0xf6,0x7f,0x00,0xef,0x24, -0xea,0x40,0x1f,0xe4,0xef,0x25,0xe0,0x90,0x35,0x2c,0xfd,0x93,0xcd,0x04,0x93,0x78, -0x99,0x66,0x70,0x03,0xed,0x18,0x66,0x70,0x06,0x78,0x97,0x76,0x00,0x80,0x03,0x0f, -0x80,0xdc,0x78,0x96,0xef,0xf6,0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x02,0x12,0x02, -0x0e,0x78,0x98,0xcb,0xf6,0xcb,0x08,0xf6,0x54,0x04,0xcb,0x54,0x86,0x4b,0x60,0x04, -0x78,0x97,0x76,0x0b,0x78,0x99,0xe6,0x30,0xe3,0x13,0x78,0x9a,0x12,0x04,0x65,0x90, -0x00,0x05,0x12,0x01,0xec,0x24,0xfb,0x50,0x04,0x78,0x97,0x76,0x0d,0x78,0x99,0xe6, -0x54,0xc0,0x7d,0x00,0x64,0xc0,0x4d,0x70,0x04,0x78,0x97,0x76,0x0b,0x78,0x9a,0x12, -0x04,0x65,0x90,0x00,0x04,0x12,0x01,0xec,0x24,0xfc,0x50,0x04,0x78,0x97,0x76,0x0f, -0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x06,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78, -0x97,0x76,0x0e,0x78,0x9a,0x12,0x04,0x65,0x90,0x00,0x09,0x12,0x01,0xec,0x24,0xfd, -0x50,0x04,0x78,0x97,0x76,0x0a,0x78,0x97,0xe6,0x70,0x2a,0x78,0x95,0xe6,0xfc,0x12, -0x0f,0x69,0x78,0x9a,0x12,0x04,0x65,0x78,0xa7,0xe6,0xf9,0x78,0xa6,0xe6,0xfa,0x7b, -0x01,0x74,0x0a,0x78,0x00,0x12,0x03,0x3f,0xc2,0x03,0x78,0x95,0xe6,0xfc,0x12,0x11, -0x07,0x78,0x97,0xec,0xf6,0x78,0x97,0xe6,0xfc,0x12,0x25,0xbf,0x12,0x31,0x69,0x22, -0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0x12,0x0f,0x69,0x78,0x95,0xe6,0x24,0xfd,0x75, -0xf0,0x0a,0xa4,0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xac,0x82,0xad,0x83, -0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12, -0x03,0xa7,0xc2,0x03,0x78,0x95,0xe6,0xfc,0x12,0x11,0x07,0x12,0x31,0x69,0x22,0x8d, -0x2b,0x8c,0x2a,0xed,0x60,0x40,0x75,0x27,0x01,0x75,0x29,0x48,0x75,0x28,0xff,0xe5, -0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd, -0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae, -0x28,0xaf,0x27,0x74,0x80,0x90,0x00,0x06,0x12,0x03,0x17,0x74,0x80,0x90,0x00,0x02, -0x12,0x03,0x17,0x12,0x0f,0xb7,0xe5,0x2b,0x14,0x60,0x3b,0x75,0x27,0x01,0x75,0x29, -0x08,0x75,0x28,0xff,0xe5,0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03, -0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d, -0xf5,0x28,0xad,0x29,0xae,0x28,0xaf,0x27,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0xe4, -0x90,0x00,0x02,0x12,0x03,0x17,0x22,0x12,0x30,0xe6,0x78,0x95,0xec,0xf6,0xec,0x24, -0x9d,0xf8,0xe6,0x30,0xe2,0x09,0x78,0x95,0xe6,0xfc,0x12,0x14,0xed,0xd2,0x00,0x78, -0x95,0xe6,0xfc,0x12,0x0f,0x69,0x78,0x96,0x76,0x00,0x90,0xfc,0x39,0xe0,0x30,0xe7, -0x04,0x78,0x96,0x76,0x01,0x78,0x96,0xe6,0xfd,0x78,0x95,0xe6,0xfc,0x12,0x0d,0x2f, -0xc2,0x03,0x30,0x00,0x07,0x78,0x95,0xe6,0xfc,0x12,0x13,0xec,0x7c,0x00,0x12,0x25, -0xbf,0x12,0x31,0x69,0x22,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x44,0x01,0xf0,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x30,0xe0,0x02,0x80,0xed,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xf8,0xf0,0x78,0xa9,0xe6,0x24,0x02,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0xc2,0x03,0x8c,0x58, -0x12,0x0f,0x69,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x5d,0x7a,0x35,0x7b,0x0a, -0x78,0x01,0x12,0x03,0xf5,0x12,0x0e,0x05,0xac,0x58,0x7d,0x02,0x12,0x0d,0x2f,0xc2, -0x03,0xac,0x58,0x12,0x11,0x07,0x22,0x8d,0x53,0x8e,0x52,0x8f,0x51,0x8c,0x50,0x12, -0x0f,0x69,0x75,0x4f,0x00,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x20,0xe4,0x1f,0xe5,0x4f,0x24,0xf6,0x40,0x19,0x05,0x4f,0xc2,0x03, -0x7c,0x18,0x12,0x32,0xa9,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,0xac,0x50, -0x12,0x0f,0x69,0x80,0xd0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x20,0xe4,0x05,0xc2,0x03,0x7c,0x02,0x22,0x78,0xa9,0xe6,0x24,0x05, -0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0x60,0x16,0x78,0xa9,0xe6, -0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0xf0,0xc2,0x03, -0x7c,0x01,0x22,0x78,0xa8,0x86,0x83,0x08,0x86,0x82,0xe0,0xad,0x53,0xae,0x52,0xaf, -0x51,0x12,0x03,0x0f,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x31,0x8c,0x30,0x12,0x14,0xed, -0xe5,0x31,0x60,0x0f,0xe5,0x30,0xb4,0x03,0x0a,0x7c,0x01,0x12,0x24,0xee,0x7c,0x81, -0x12,0x24,0xee,0xac,0x30,0x12,0x0f,0x69,0xe5,0x31,0x60,0x1a,0x78,0xaa,0x86,0x83, -0x08,0x86,0x82,0xe0,0x54,0xe7,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0xe7,0xf0,0xac, -0x30,0x7d,0x02,0x12,0x0d,0x2f,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x67,0x7a, -0x35,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0xc2,0x03,0xe5,0x30,0x24,0x9d,0xf8,0xc6, -0x54,0xfd,0xf6,0xac,0x30,0x12,0x11,0x07,0x22,0x8c,0x26,0x30,0x03,0x05,0x12,0x32, -0x48,0x80,0xf8,0x7c,0x0a,0x12,0x31,0x5b,0xd2,0x03,0xe5,0x26,0x24,0xfd,0x78,0xa3, -0xf6,0x70,0x07,0x78,0xaa,0x76,0xff,0x08,0x76,0xe0,0x78,0xa3,0xe6,0x75,0xf0,0x10, -0xa4,0xad,0xf0,0xfc,0x24,0xa0,0x78,0xa9,0xf6,0xed,0x34,0xff,0x18,0xf6,0x78,0xa3, -0xe6,0x75,0xf0,0x0a,0xa4,0x24,0x00,0xfc,0xe4,0x34,0xfc,0xfd,0x78,0xa6,0xed,0xf6, -0x08,0xec,0xf6,0x12,0x31,0xf4,0x22,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x30,0xe7,0x22,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0x78,0xaa,0x86,0x83,0x08, -0x86,0x82,0xe0,0x54,0x7f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c, -0x82,0xf5,0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x54,0xf8,0xf0,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xab,0xe6,0x24,0x05,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x22,0x78,0xaa,0x86,0x83,0x08, -0x86,0x82,0xe0,0x54,0x3f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c, -0x82,0xf5,0x83,0xe0,0x54,0x3f,0xf0,0x78,0xa3,0xe6,0x24,0xa4,0xf8,0xe6,0xfc,0x78, -0xab,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa3, -0xe6,0x24,0xa4,0xf8,0xe6,0xfc,0x78,0xab,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x54,0xfb,0x44,0x02,0xf5,0x26,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe5,0x03,0x43,0x26,0x01,0x78,0xa9,0xe6, -0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,0x03,0x12,0x0f, -0xb7,0xe5,0x26,0xfc,0x78,0xa9,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0x74,0x0f,0xf0,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xe0,0x44,0x80,0xf0,0xa3,0xa3, -0xa3,0xa3,0xe0,0x44,0x80,0xf0,0x22,0x8c,0x2a,0x12,0x0f,0x69,0x78,0xa7,0xe6,0x24, -0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x0a, -0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa7,0xe6,0x24,0x07,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa9,0xe6,0x24,0x09,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0xe0, -0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0x78,0xa9,0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xee,0xf0,0xec,0xfe,0x78,0xa9,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xee,0xf0,0x8c,0x29,0x8d,0x28,0xc3,0xec,0x94,0x05,0xed,0x94, -0x0c,0x40,0x05,0x75,0x27,0x7c,0x80,0x33,0xd3,0xe5,0x29,0x94,0x01,0xe5,0x28,0x94, -0x03,0x40,0x05,0x75,0x27,0x3c,0x80,0x23,0xd3,0xe5,0x29,0x94,0x81,0xe5,0x28,0x94, -0x01,0x40,0x05,0x75,0x27,0x18,0x80,0x13,0xd3,0xe5,0x29,0x94,0x60,0xe5,0x28,0x94, -0x00,0x40,0x05,0x75,0x27,0x0c,0x80,0x03,0x75,0x27,0x08,0xaf,0x27,0xe4,0xef,0x54, -0x7c,0x44,0x83,0xff,0x8f,0x27,0xe5,0x27,0xfc,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xab,0xe6,0x24,0x05, -0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xa3,0xe6, -0x24,0xa4,0xf8,0xec,0xf6,0x78,0xa9,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xa3,0xe0,0x30,0xe3,0x17,0x53,0x27,0xc7,0x78,0xa7,0xe6,0x24,0x05,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90,0x35,0x58,0x93,0x42,0x27,0x53,0x27, -0xfb,0x78,0xa7,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x60, -0x03,0x43,0x27,0x04,0x53,0x27,0xfc,0x78,0xa7,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x42,0x27,0x43,0x27,0x80,0xe5,0x27,0xfc,0x78,0xa9,0xe6, -0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24, -0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24, -0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe1,0x05,0x53,0x27, -0xdf,0x80,0x03,0x43,0x27,0x20,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x30,0xe4,0x05,0x53,0x27,0xef,0x80,0x03,0x43,0x27,0x10,0x78, -0xa7,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xb4,0x02,0x03, -0x43,0x27,0x02,0xe5,0x27,0xfc,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xec,0xf0,0x78,0xa9,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa7,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x70,0x05,0x53,0x27,0x7f,0x80,0x03,0x43,0x27,0x80,0x78,0xa7,0xe6, -0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe0,0x05,0x43, -0x27,0x20,0x80,0x03,0x53,0x27,0xdf,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x30,0xe3,0x05,0x43,0x27,0x40,0x80,0x03,0x53,0x27,0xbf, -0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0, -0x05,0x43,0x27,0x10,0x80,0x03,0x53,0x27,0xef,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe4,0x05,0x43,0x27,0x08,0x80,0x03, -0x53,0x27,0xf7,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xa3,0xe0,0x30,0xe5,0x05,0x43,0x27,0x04,0x80,0x03,0x53,0x27,0xfb,0x78,0xa7,0xe6, -0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe6,0x05,0x43, -0x27,0x01,0x80,0x03,0x53,0x27,0xfe,0x78,0xa7,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe7,0x05,0x43,0x27,0x02,0x80,0x03,0x53,0x27, -0xfd,0xe5,0x27,0xfc,0x78,0xa9,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xec,0xf0,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x27,0x8c,0x26,0xed,0x54,0x03,0x14, -0x60,0x03,0x7c,0x10,0x22,0xe5,0x27,0x54,0x7c,0x24,0xfc,0x40,0x03,0x7c,0x0b,0x22, -0xe5,0x26,0x24,0x9d,0xf8,0xc6,0x44,0x02,0xf6,0x7c,0x00,0x22,0x8c,0x30,0x12,0x0f, -0x69,0xe5,0x30,0x24,0x9d,0xf8,0xe6,0x20,0xe2,0x4f,0xac,0x30,0x7d,0x02,0x12,0x0d, -0x2f,0xe5,0x30,0x24,0xfe,0x44,0x28,0xfc,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xec, -0xf0,0xaf,0x83,0xe5,0x82,0x24,0x04,0xfe,0xe4,0x3f,0xff,0xec,0x8e,0x82,0x8f,0x83, -0xf0,0x7c,0x03,0x8c,0x2c,0xe5,0x2c,0xfc,0x78,0xab,0xe6,0x24,0x01,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x2c,0xfc,0x78,0xab,0xe6,0x24,0x05,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x75,0x2d,0x01,0x75,0x2f,0x48,0x75, -0x2e,0xff,0xe5,0x30,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0, -0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x2f,0x2c,0xf5,0x2f,0xe5,0x2e,0x3d,0xf5,0x2e, -0x78,0xab,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xe7, -0xf5,0x2c,0xad,0x2f,0xae,0x2e,0xaf,0x2d,0xe4,0x90,0x00,0x02,0x12,0x03,0x17,0xe4, -0x90,0x00,0x06,0x12,0x03,0x17,0x12,0x01,0xe6,0x30,0xe5,0x03,0x43,0x2c,0x10,0xe5, -0x2c,0xfc,0x78,0xab,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec, -0xf0,0x12,0x10,0x4b,0x78,0xa9,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0xc2,0x03,0xfc,0xe5,0x30,0x24,0x9d,0xf8,0xc6,0x44,0x04,0xf6,0x8c,0x2c, -0xe5,0x30,0x54,0x0f,0xc4,0x54,0xf0,0x7e,0x00,0xff,0xee,0xef,0x44,0x04,0x7d,0x00, -0xff,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0x12,0x1c,0xa7,0x7c,0x00,0x22,0x8c,0x2f,0x12, -0x0f,0x69,0x12,0x0f,0xeb,0x78,0xaa,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,0x08,0xf0, -0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0x08,0xf0,0xac,0x2f,0x7d,0x02,0x12,0x0d,0x2f,0xc2, -0x03,0xe5,0x2f,0x24,0x9d,0xf8,0xc6,0x54,0xfb,0xf6,0x7c,0x00,0x22,0x12,0x30,0xe6, -0x78,0x96,0xec,0xf6,0xec,0x24,0x9d,0xf8,0xe6,0x30,0xe1,0x0a,0x7d,0x00,0x7c,0x13, -0x12,0x25,0x26,0x12,0x31,0x69,0x78,0x96,0xe6,0x24,0x9d,0xf8,0xc6,0x44,0x01,0xf6, -0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0x96,0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4, -0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0x78,0xa6,0xe6,0xfa,0x08,0xe6,0xf9, -0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0x78,0xa6,0x86,0x83,0x08,0x86,0x82,0x79,0x67, -0x7a,0x35,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0x12,0x0f,0xb7,0xc2,0x03,0x78,0x96, -0xe6,0xfc,0x12,0x11,0x07,0x78,0x95,0xec,0xf6,0xec,0x60,0x0a,0x7d,0x00,0x7c,0x08, -0x12,0x25,0x26,0x12,0x31,0x69,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0xa9,0xe6, -0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x10,0x54,0xdf,0xfc, -0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78, -0x95,0xec,0xf6,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f, -0x69,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54, -0xef,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69, -0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x10, -0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78, -0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x20,0xf0, -0xc2,0x03,0x7c,0xf0,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12,0x0f,0x69,0x78,0xa9, -0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x15,0xc2, -0x03,0x78,0x96,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,0x12,0x31,0xfb,0x12,0x31, -0x69,0x02,0x17,0x14,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0x54,0xcf,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc, -0x12,0x0f,0x69,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xe0,0x44,0x30,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0xa9,0x78,0x96,0xe6,0xfc,0x12, -0x0f,0x69,0x78,0xa9,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0, -0x30,0xe4,0x14,0xc2,0x03,0x78,0x96,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07,0x12, -0x31,0xfb,0x12,0x31,0x69,0x80,0x5d,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x78,0xa9,0xe6,0x24,0x04,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x78,0x96,0xe6,0x24,0xfd,0x75,0xf0, -0x0a,0xa4,0x24,0x14,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xac,0x82,0xad,0x83,0x78, -0xa6,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,0x03, -0xa7,0xc2,0x03,0x78,0x96,0xe6,0xfc,0x12,0x11,0x07,0x7d,0x00,0x7c,0x0b,0x12,0x25, -0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0xe4,0x90,0xfc,0x39,0xf0,0x7d,0x02,0x7c, -0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x7c,0x00,0x12,0x25,0xbf, -0x12,0x31,0x69,0x22,0x74,0x3c,0x90,0xfb,0xe0,0xf0,0x74,0x3e,0x90,0xfb,0xe0,0xf0, -0xe4,0x90,0xfc,0x28,0xf0,0x22,0x8d,0x35,0x8c,0x34,0xec,0xb4,0x01,0x02,0x80,0x03, -0xd3,0x40,0x02,0x80,0x28,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x08,0xa8,0x35,0xc6, -0x25,0xe0,0xf6,0x80,0x18,0xb4,0x04,0x02,0x80,0x03,0xd3,0x40,0x0a,0xa8,0x35,0xc6, -0x25,0xe0,0x25,0xe0,0xf6,0x80,0x06,0xa8,0x35,0x76,0x00,0x80,0x00,0x22,0x8c,0x3c, -0x8d,0x3b,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x75,0x66,0x06,0x75,0x67,0x00,0x90,0xfc, -0x29,0x12,0x04,0x6e,0x12,0x01,0xe6,0xb4,0x80,0x02,0x80,0x06,0xd3,0x50,0x03,0x02, -0x18,0x47,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x03,0x12,0x01,0xec,0x54,0xf0, -0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x5f,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00, -0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfc,0x2c,0x12,0x04,0x6e, -0xee,0xcd,0x90,0x35,0x71,0xfc,0xe4,0x93,0xff,0x74,0x01,0x93,0xfe,0xf9,0xef,0xfa, -0x7b,0x01,0xea,0xff,0xe9,0xfe,0xec,0xc3,0x9e,0xed,0x9f,0x40,0x25,0x90,0x35,0x73, -0xe4,0x93,0xfd,0x74,0x01,0x93,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0xee,0xcd,0xfc, -0x90,0xfc,0x2e,0xe0,0xd3,0x9c,0x90,0xfc,0x2d,0xe0,0x9d,0x50,0x05,0x75,0x66,0x80, -0x80,0x33,0x12,0x19,0x65,0x80,0x2e,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,0x0b,0xac, -0x3c,0xad,0x3b,0x12,0x07,0x77,0x8c,0x66,0x80,0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10, -0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,0xd3,0x40,0x00, -0x75,0x66,0x81,0x80,0x00,0x80,0x75,0xb4,0x81,0x02,0x80,0x03,0xd3,0x40,0x6b,0x90, -0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x03,0x12,0x01,0xec,0x54,0xf0,0xb4,0x30,0x02, -0x80,0x03,0xd3,0x40,0x1d,0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x08,0x12,0x02, -0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x12,0x18,0xcf, -0x80,0x36,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40,0x13,0x75,0x3a,0x67,0xe4,0xf5,0x39, -0xf5,0x38,0xac,0x3c,0xad,0x3b,0x12,0x05,0xd3,0x8c,0x66,0x80,0x1b,0xb4,0x10,0x03, -0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4,0x40,0x02,0x80,0x03, -0xd3,0x40,0x00,0x75,0x66,0x81,0x80,0x00,0x80,0x02,0x80,0x00,0xe5,0x66,0xfc,0x90, -0xfc,0x29,0x12,0x04,0x80,0xec,0x90,0x00,0x02,0x12,0x03,0x17,0xac,0x67,0x22,0x90, -0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x60,0x04,0x74,0x01,0x80, -0x01,0xe4,0xa2,0xe0,0x92,0x01,0x90,0xfc,0x29,0x12,0x04,0x80,0xed,0x24,0x03,0xfd, -0x50,0x01,0x0e,0x90,0xfc,0x2c,0x12,0x04,0x6e,0x90,0xfc,0x29,0x12,0x04,0x80,0x90, -0x00,0x05,0x12,0x01,0xec,0xf5,0x67,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xfc, -0x7d,0x67,0x12,0x17,0x46,0xe5,0x67,0x70,0x04,0x75,0x66,0x08,0x22,0x75,0x66,0x00, -0x78,0x84,0x76,0x00,0x78,0x84,0xe6,0xc3,0x95,0x67,0x50,0x38,0x90,0xfc,0x2f,0x12, -0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfc,0x2c,0x12,0x04,0x80,0xec,0x12,0x03,0x0f, -0x30,0x01,0x0e,0x90,0xfc,0x31,0xe0,0x04,0xf0,0x90,0xfc,0x30,0x70,0x03,0xe0,0x04, -0xf0,0x78,0x84,0x06,0x90,0xfc,0x2e,0xe0,0x04,0xf0,0x90,0xfc,0x2d,0x70,0x03,0xe0, -0x04,0xf0,0x80,0xc0,0x22,0x90,0xfc,0x2a,0xe0,0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0xec, -0xfd,0x7f,0x01,0xed,0x24,0x0a,0xfd,0x50,0x01,0x0e,0x90,0xfc,0x32,0x12,0x04,0x6e, -0x90,0xfc,0x29,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xb4,0x01, -0x02,0x80,0x03,0xd3,0x40,0x17,0x90,0xfc,0x32,0x12,0x04,0x80,0x0d,0xed,0x70,0x01, -0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x01,0x80,0x4e,0xb4,0x02,0x02, -0x80,0x03,0xd3,0x40,0x19,0x90,0xfc,0x32,0x12,0x04,0x80,0xed,0x24,0x02,0xfd,0x50, -0x01,0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x02,0x80,0x2d,0xb4,0x04, -0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfc,0x32,0x12,0x04,0x80,0xed,0x24,0x04,0xfd, -0x50,0x01,0x0e,0x90,0xfc,0x2f,0x12,0x04,0x6e,0x78,0x88,0x76,0x04,0x80,0x0c,0xb4, -0x00,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x66,0x08,0x22,0x90,0xfc,0x29,0x12,0x04, -0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x67,0x78,0x85,0x76,0x00,0x78,0x85,0xe6, -0xc3,0x95,0x67,0x40,0x03,0x02,0x1a,0xcd,0x78,0x86,0x76,0x00,0x78,0x86,0xe6,0xc3, -0x78,0x88,0x96,0x50,0x76,0x90,0xfc,0x2c,0x12,0x04,0x80,0x12,0x01,0xe6,0xfc,0x90, -0xfc,0x32,0x12,0x04,0x89,0x12,0x01,0xe0,0xf4,0x5c,0xfc,0x12,0x01,0xe0,0xf8,0x90, -0xfc,0x2f,0x12,0x04,0x80,0xe8,0xc0,0xe0,0x12,0x01,0xe6,0xc8,0xd0,0xe0,0xc8,0x58, -0x4c,0xfc,0x90,0xfc,0x2c,0x12,0x04,0x80,0xec,0x12,0x03,0x0f,0x78,0x87,0xec,0xf6, -0x90,0xfc,0x31,0xe0,0x04,0xf0,0x90,0xfc,0x30,0x70,0x03,0xe0,0x04,0xf0,0x09,0xe9, -0x70,0x01,0x0a,0x90,0xfc,0x32,0x12,0x04,0x77,0x90,0xfc,0x29,0x12,0x04,0x80,0x90, -0x00,0x04,0x12,0x01,0xec,0x30,0xe4,0x0e,0x90,0xfc,0x2e,0xe0,0x04,0xf0,0x90,0xfc, -0x2d,0x70,0x03,0xe0,0x04,0xf0,0x78,0x86,0x06,0x80,0x81,0x78,0x88,0xe6,0xfd,0xe4, -0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfc,0x31,0xe0,0x2c,0xf0,0x90,0xfc,0x30,0xe0,0x3d, -0xf0,0x78,0x88,0xe6,0xfd,0xe4,0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfc,0x34,0xe0,0x2c, -0xf0,0x90,0xfc,0x33,0xe0,0x3d,0xf0,0x78,0x85,0x06,0x02,0x1a,0x0d,0x75,0x66,0x00, -0x22,0xe5,0x3d,0x05,0x3d,0x04,0x70,0x02,0xb2,0xb0,0x22,0xc0,0xe0,0xc0,0xf0,0xc0, -0x82,0xc0,0x83,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9,0xc0,0xe0,0xea,0xc0,0xe0,0xeb,0xc0, -0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0,0xe0,0xef,0xc0,0xe0,0x90,0xff,0x92, -0xe0,0x12,0x01,0xb7,0x1b,0x29,0x30,0x1b,0x29,0x32,0x1b,0x38,0x38,0x1b,0x4a,0x3a, -0x1b,0x5c,0x3e,0x1b,0x74,0x44,0x1b,0x68,0x46,0x1b,0x80,0x50,0x1b,0xc2,0x52,0x1b, -0xa1,0x54,0x1b,0xe3,0x56,0x00,0x00,0x1c,0x04,0x90,0xff,0x92,0xe0,0x7f,0x00,0xfe, -0x7c,0x01,0x12,0x31,0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x03,0x12,0x31, -0xfb,0x74,0x20,0x90,0xff,0xfe,0xf0,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x02, -0x12,0x31,0xfb,0x74,0x40,0x90,0xff,0xfe,0xf0,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe, -0x7c,0x04,0x12,0x31,0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x05,0x12,0x31, -0xfb,0x02,0x1c,0x14,0xe4,0xff,0x04,0xfe,0x7c,0x06,0x12,0x31,0xfb,0x02,0x1c,0x14, -0x90,0xff,0xa5,0xe0,0x7d,0x00,0x90,0xfb,0xf8,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfb, -0xf9,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xf8,0xe0,0x44,0x33,0xfd,0x12,0x1c,0xa7,0x80, -0x73,0x90,0xff,0xb5,0xe0,0x7d,0x00,0x90,0xfb,0xfa,0xcd,0xf0,0xa3,0xcd,0xf0,0x90, -0xfb,0xfb,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfa,0xe0,0x44,0x43,0xfd,0x12,0x1c,0xa7, -0x80,0x52,0x90,0xff,0xa6,0xe0,0x7d,0x00,0x90,0xfb,0xfc,0xcd,0xf0,0xa3,0xcd,0xf0, -0x90,0xfb,0xfd,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfc,0xe0,0x44,0x34,0xfd,0x12,0x1c, -0xa7,0x80,0x31,0x90,0xff,0xb6,0xe0,0x7d,0x00,0x90,0xfb,0xfe,0xcd,0xf0,0xa3,0xcd, -0xf0,0x90,0xfb,0xff,0xe0,0xfc,0xf5,0x83,0x90,0xfb,0xfe,0xe0,0x44,0x44,0xfd,0x12, -0x1c,0xa7,0x80,0x10,0x90,0xff,0x92,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xaa,0xfd,0x12, -0x1c,0xa7,0x80,0x00,0xe4,0x90,0xff,0x92,0xf0,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0, -0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0,0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0, -0xf8,0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32,0x05,0x81,0x05,0x81, -0x05,0x81,0x05,0x81,0xa8,0x81,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0x90,0xff, -0x5a,0xe0,0x20,0xe7,0x02,0x80,0xf7,0x90,0xff,0x59,0xe0,0x7d,0x00,0xa8,0x81,0x18, -0xcd,0xf6,0xcd,0x08,0xf6,0x7d,0x03,0xa8,0x81,0xe6,0x18,0xfc,0xe6,0xcc,0x25,0xe0, -0xcc,0x33,0xcc,0xdd,0xf9,0xcc,0xf6,0xcc,0x08,0xf6,0xa8,0x81,0x18,0xe6,0x44,0xf8, -0xf6,0xa8,0x81,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0xa8,0x81,0x18,0x86,0x83, -0x08,0x86,0x82,0xed,0xf0,0xa3,0xec,0xf0,0x74,0x02,0x90,0xff,0x5a,0xf0,0x15,0x81, -0x15,0x81,0x15,0x81,0x15,0x81,0x22,0xe5,0x81,0x24,0x05,0xf5,0x81,0xe4,0xa8,0x81, -0x18,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0x90,0xfb,0xf5, -0xe0,0x24,0xf8,0x50,0x03,0x02,0x1d,0xc8,0xe4,0xa8,0x81,0x18,0x18,0xf6,0xa8,0x81, -0x18,0xe6,0xfe,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x7f,0x00, -0xef,0x24,0xf8,0x40,0x4d,0xe4,0xef,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc, -0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x6c,0x70,0x03,0xfa,0xeb,0x6d,0x70,0x09,0x74,0x01, -0xa8,0x81,0x18,0x18,0xf6,0x80,0x2b,0xe4,0xef,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4, -0x34,0xfc,0xf5,0x83,0x7a,0x00,0xe0,0x54,0xf0,0xcc,0xf8,0xcc,0xcd,0xf9,0xcd,0xfb, -0x78,0x00,0xe9,0x54,0xf0,0xf9,0xea,0x68,0x70,0x02,0xeb,0x69,0x70,0x01,0x0e,0x0f, -0x80,0xae,0xa8,0x81,0x18,0xee,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed,0xf6,0x08, -0xec,0xf6,0xa8,0x81,0xef,0xf6,0xa8,0x81,0x18,0x18,0xe6,0x70,0x79,0xa8,0x81,0x18, -0xe6,0x24,0xf7,0x40,0x71,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0x54,0x0f,0xa8,0x81, -0xf6,0x64,0x04,0x60,0x17,0xa8,0x81,0xe6,0x64,0x03,0x60,0x10,0xa8,0x81,0x18,0x18, -0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x1c,0x3c,0x80,0x4a,0x7c,0x0a,0x12,0x31, -0x5b,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x90,0xfb,0xf4,0xe0, -0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0, -0x90,0xfb,0xf4,0xe0,0xff,0xe4,0xef,0x04,0x54,0x07,0xff,0x90,0xfb,0xf4,0xf0,0x90, -0xfb,0xf5,0xe0,0x04,0xf0,0x12,0x31,0xf4,0x90,0xfb,0xf6,0xe0,0x70,0x08,0xe4,0xfe, -0xff,0x7c,0x0f,0x12,0x31,0xfb,0x80,0x27,0x90,0xfb,0xf7,0xe0,0x04,0xf0,0x54,0x3f, -0x70,0x1d,0x90,0xfb,0xf7,0xe0,0x44,0xfe,0x7d,0x00,0xfc,0x90,0xfb,0xf4,0xe0,0x25, -0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,0xe5, -0x81,0x24,0xfb,0xf5,0x81,0x22,0x78,0x8b,0x76,0x00,0x78,0x8c,0x76,0x00,0x74,0x01, -0x90,0xfb,0xf6,0xf0,0x12,0x30,0xe6,0x90,0xfb,0xf5,0xe0,0x60,0x57,0x7c,0x0a,0x12, -0x31,0x5b,0x90,0xfb,0xf3,0xe0,0x25,0xe0,0x24,0x7d,0xf5,0x82,0xe4,0x34,0xfc,0xf5, -0x83,0xe0,0xfd,0xa3,0xe0,0xfc,0x90,0xfb,0xf3,0xe0,0x25,0xe0,0x24,0x7d,0xf5,0x82, -0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0xfb,0xf3,0xe0,0xff,0xe4,0xef, -0x04,0x54,0x07,0xff,0x90,0xfb,0xf3,0xf0,0x90,0xfb,0xf5,0xe0,0x14,0xf0,0x78,0x89, -0xed,0xf6,0x08,0xec,0xf6,0x12,0x31,0xf4,0x78,0x89,0xe6,0xfd,0x08,0xe6,0xfc,0x12, -0x08,0xda,0x80,0xa3,0x12,0x32,0x48,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3, -0x78,0x8b,0x06,0xb6,0x00,0x11,0x78,0x8b,0x76,0x00,0x78,0x8c,0xe6,0xf4,0x04,0x04, -0xa2,0xe0,0x92,0xb4,0x78,0x8c,0xf6,0x02,0x1e,0x07,0xe4,0x90,0xfb,0xf6,0xf0,0x90, -0xfb,0xf5,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xcf,0xfd,0x12,0x1c,0x3c,0x12,0x31,0x69, -0x22,0x12,0x30,0xe6,0xe5,0x70,0x64,0x49,0x45,0x6f,0x60,0x15,0x90,0xff,0x83,0xe0, -0x54,0x0f,0x7d,0x00,0xd3,0x95,0x70,0xed,0x95,0x6f,0x50,0x05,0x12,0x2f,0x2f,0x80, -0x03,0x12,0x2f,0xff,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0xe5,0x70,0x64,0x49,0x45, -0x6f,0x60,0x05,0x12,0x30,0x39,0x80,0x0e,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x90, -0xff,0x83,0xe0,0x54,0x7f,0xf0,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x8c,0x54,0xec, -0x54,0xf0,0xb4,0x10,0x15,0x75,0x6a,0x35,0x75,0x69,0xfc,0x75,0x68,0x01,0xe5,0x6a, -0x24,0x03,0xf5,0x6a,0xe5,0x69,0x34,0x00,0xf5,0x69,0xe4,0xf5,0x57,0xf5,0x56,0xe5, -0x56,0xc3,0x94,0x01,0x50,0x27,0xe5,0x54,0x54,0x0f,0xfc,0xad,0x6a,0xae,0x69,0xaf, -0x68,0x12,0x0e,0x77,0x8c,0x55,0xec,0x60,0x02,0x80,0x12,0x05,0x6a,0xe5,0x6a,0x70, -0x02,0x05,0x69,0x05,0x57,0xe5,0x57,0x70,0x02,0x05,0x56,0x80,0xd2,0xe5,0x54,0x54, -0x0f,0x24,0x9d,0xf8,0xc6,0x54,0xfe,0xf6,0xe5,0x54,0x54,0x0f,0x7f,0x00,0xfe,0x7c, -0x12,0x12,0x31,0xfb,0xe5,0x55,0x14,0x70,0x09,0x7d,0x00,0x7c,0x09,0x12,0x25,0x26, -0x80,0x07,0xad,0x57,0x7c,0x00,0x12,0x25,0x26,0x12,0x31,0x69,0x22,0x12,0x30,0xe6, -0x90,0xff,0xfc,0xe0,0x44,0x02,0xf0,0x90,0xff,0x00,0xe0,0x30,0xe7,0x13,0x90,0xff, -0x83,0xe0,0x44,0x80,0xf0,0x43,0x6d,0x80,0x90,0xff,0xfc,0xe0,0x44,0x01,0xf0,0x80, -0x11,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x53,0x6d,0x7f,0x90,0xff,0xfc,0xe0,0x54, -0xfe,0xf0,0x90,0xff,0x81,0xe0,0x44,0x80,0xf0,0x12,0x25,0xd9,0x90,0xff,0xfe,0xe0, -0x44,0x05,0xf0,0x90,0xff,0xfc,0xe0,0x54,0xfd,0xf0,0x12,0x31,0x69,0x22,0x12,0x30, -0xe6,0x7c,0x01,0x12,0x32,0xa9,0x78,0xad,0xe6,0x44,0x02,0xf6,0x74,0xfe,0xfc,0x04, -0xfd,0x12,0x1c,0xa7,0x90,0xff,0x5a,0xe0,0x30,0xe7,0x02,0x80,0xf7,0xe4,0xf5,0x4e, -0x75,0x4d,0x10,0xac,0x4e,0xad,0x4d,0xe5,0x4e,0x15,0x4e,0x70,0x02,0x15,0x4d,0xec, -0x4d,0x60,0x02,0x80,0xee,0x43,0x87,0x01,0x12,0x31,0x69,0x22,0x12,0x30,0xe6,0x7c, -0x02,0x12,0x31,0x75,0x78,0xad,0xe6,0x54,0xfd,0xf6,0x12,0x31,0x69,0x22,0x12,0x30, -0xe6,0x78,0xad,0xe6,0x30,0xe0,0x2c,0x78,0xad,0xe6,0x30,0xe1,0x26,0x78,0xad,0xe6, -0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf0,0xfd,0x12,0x1c,0x3c,0x90,0xff,0xfc,0xe0,0x44, -0x20,0xf0,0x7c,0x02,0x12,0x32,0xa9,0x78,0xad,0xe6,0x54,0xfd,0xf6,0x74,0x1a,0x90, -0xff,0xfe,0xf0,0x78,0xad,0xe6,0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf1,0xfd,0x12,0x1c, -0x3c,0x12,0x31,0x69,0x22,0x75,0x6d,0x00,0x90,0xff,0xff,0xe0,0x60,0x03,0x43,0x6d, -0x01,0x75,0x6e,0x00,0xe4,0xf5,0x6c,0xf5,0x6b,0xe4,0xf5,0x6f,0x75,0x70,0x49,0x74, -0x84,0x90,0xff,0x82,0xf0,0x74,0x84,0x90,0xff,0x80,0xf0,0x74,0x80,0x90,0xff,0x58, -0xf0,0x74,0x80,0x90,0xff,0x5a,0xf0,0xad,0x46,0xaf,0x45,0x7e,0x00,0xee,0x24,0xfe, -0x50,0x03,0x02,0x21,0x24,0xe4,0xee,0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4, -0x34,0xf8,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,0x80,0xfd,0xe4,0xef,0x54,0x0f,0x14, -0xff,0xed,0x60,0x38,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82, -0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e, -0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0x80,0x34,0xe4,0xef,0x75,0xf0, -0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef, -0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4, -0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0, -0x0e,0x02,0x20,0x8d,0x8d,0x46,0x8e,0x44,0x8f,0x45,0x74,0x7f,0x90,0xff,0xfd,0xf0, -0x74,0x90,0x90,0xff,0xfc,0xf0,0x22,0x8c,0x58,0xec,0x24,0xf6,0x50,0x06,0xe5,0x58, -0x24,0x37,0xfc,0x22,0xe5,0x58,0x24,0x30,0xfc,0x22,0x12,0x25,0x23,0xec,0x70,0x03, -0x02,0x22,0x5e,0x75,0x5c,0x03,0xae,0x5b,0x7f,0x00,0xe5,0x5c,0x15,0x5c,0x64,0x80, -0x24,0x7f,0x50,0x35,0xef,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfe, -0x24,0xfe,0x50,0x1e,0xef,0x7d,0x00,0xfc,0xe4,0xfb,0x74,0x74,0xc3,0x9c,0xfa,0xeb, -0x9d,0xfb,0xee,0x7d,0x00,0xfc,0xea,0xc3,0x9c,0xed,0x64,0x80,0xcb,0x64,0x80,0x9b, -0x50,0x02,0x80,0x05,0xef,0x2e,0xff,0x80,0xc1,0x8e,0x5b,0x8f,0x5a,0xe5,0x5c,0x64, -0x80,0x24,0x7f,0x50,0x03,0x02,0x22,0x5e,0xe5,0x5a,0x24,0x8e,0x50,0x03,0x02,0x22, -0x5e,0x85,0x5a,0x5d,0x75,0x5b,0x00,0xae,0x5a,0xaf,0x5b,0x90,0x35,0x9c,0xe4,0x93, -0xf5,0x5c,0xe5,0x5c,0x15,0x5c,0x64,0x80,0x24,0x7f,0x50,0x18,0xee,0x24,0x00,0xf5, -0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfc,0xef,0x90,0x35,0x9c,0x93,0x6c,0x70,0x04, -0x0e,0x0f,0x80,0xde,0x8e,0x5a,0x8f,0x5b,0xe5,0x5c,0x64,0x80,0x24,0x7f,0x40,0x6e, -0x75,0x5e,0x01,0x75,0x60,0xe8,0x75,0x5f,0xff,0xe5,0x5d,0x24,0x02,0xf5,0x5a,0x75, -0x5c,0x07,0xe5,0x5c,0x33,0x40,0x57,0xad,0x60,0xae,0x5f,0xaf,0x5e,0xe5,0x5c,0xf5, -0x82,0x33,0x95,0xe0,0xf5,0x83,0x12,0x01,0xec,0xc4,0x54,0x0f,0xfc,0x12,0x21,0x37, -0xe5,0x5a,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xec,0xf0,0x05,0x5a,0x05, -0x5a,0xad,0x60,0xae,0x5f,0xaf,0x5e,0xe5,0x5c,0xf5,0x82,0x33,0x95,0xe0,0xf5,0x83, -0x12,0x01,0xec,0x54,0x0f,0xfc,0x12,0x21,0x37,0xe5,0x5a,0x24,0x00,0xf5,0x82,0xe4, -0x34,0xfb,0xf5,0x83,0xec,0xf0,0x05,0x5a,0x05,0x5a,0x15,0x5c,0x80,0xa4,0x74,0x02, -0x90,0xf8,0x51,0xf0,0x90,0xf8,0x6b,0x79,0x75,0x7a,0x35,0x7b,0x27,0x78,0x01,0x12, -0x03,0xf5,0x75,0x6a,0x35,0x75,0x69,0xfc,0x75,0x68,0x01,0xe4,0x90,0xff,0x83,0xf0, -0x74,0x80,0x90,0xff,0x81,0xf0,0x75,0x59,0x02,0xe5,0x59,0x75,0xf0,0x07,0xa4,0x24, -0x7f,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0x78,0x8f,0xf6,0xfc,0x54,0x0f,0x14, -0xfc,0x78,0x8f,0xec,0xf6,0xe5,0x59,0x75,0xf0,0x07,0xa4,0x24,0x81,0xf5,0x82,0xe4, -0x34,0xf8,0xf5,0x83,0xe0,0x78,0x92,0x76,0xfd,0x08,0x76,0xe8,0xfc,0x78,0x8f,0xe6, -0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78, -0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xec, -0xf0,0x78,0x92,0xe6,0xff,0x08,0xe6,0x7e,0x03,0xcf,0xc3,0x13,0xcf,0x13,0xde,0xf9, -0xfe,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5, -0x83,0xee,0xf0,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0x74,0x80,0xf0,0x78,0x90,0xec,0xf6,0x7d,0x00,0x78,0x93,0xe6,0x2c, -0xf6,0x18,0xe6,0x3d,0xf6,0x78,0x92,0xe6,0xfd,0x08,0xe6,0x7c,0x03,0xcd,0xc3,0x13, -0xcd,0x13,0xdc,0xf9,0xfc,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82, -0xe4,0x34,0xff,0xf5,0x83,0xec,0xf0,0x78,0x8f,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4e, -0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x92,0xe6,0xfd,0x08,0xe6,0xfc, -0x78,0x8f,0xe6,0xff,0x7e,0x00,0xee,0x24,0xfe,0x50,0x03,0x02,0x24,0xdd,0xe4,0xee, -0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0xff,0xe4, -0xef,0x54,0x80,0xfa,0xe4,0xef,0x54,0x0f,0x14,0xff,0xe4,0xee,0x75,0xf0,0x07,0xa4, -0x24,0x81,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe0,0x78,0x90,0xf6,0xe4,0xee,0x13, -0x13,0x54,0x80,0x24,0xf0,0xf8,0xe4,0x34,0xfd,0xf9,0xe8,0xfc,0xe9,0xfd,0x8a,0x5a, -0xea,0x70,0x03,0x02,0x24,0x4a,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82, -0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x90,0xe6,0xfa,0xe4,0xef,0x75,0xf0,0x08, -0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,0xec,0x7a, -0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24, -0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x90,0xe6,0x7b,0x00,0xfa, -0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda, -0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,0xff,0xf5, -0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff, -0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4, -0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0x02,0x24,0xd9,0xe4,0xef,0x75,0xf0,0x08,0xa4, -0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x90,0xe6,0xfa,0xe4, -0xef,0x75,0xf0,0x08,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0, -0xed,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75, -0xf0,0x08,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x90, -0xe6,0x7b,0x00,0xfa,0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3, -0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0d,0xf5,0x82, -0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5, -0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e, -0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x23,0x66,0x8e,0x59,0x78, -0x92,0xed,0xf6,0x08,0xec,0xf6,0x78,0x8f,0xef,0xf6,0x12,0x20,0x55,0x22,0x8c,0x26, -0xec,0x30,0xe7,0x18,0xe5,0x26,0x54,0x0f,0x14,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5, -0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x80,0x16,0xe5,0x26,0x54,0x0f, -0x14,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54, -0xdf,0xf0,0x22,0x7c,0x00,0x22,0xec,0x90,0xfc,0x37,0xf0,0x8c,0x24,0xed,0x24,0x03, -0xf5,0x25,0x7d,0x00,0xd3,0x95,0x72,0xed,0x95,0x71,0x40,0x03,0x85,0x72,0x25,0xe5, -0x25,0x24,0xb7,0x50,0x09,0x75,0x25,0x03,0x74,0x02,0x90,0xfc,0x37,0xf0,0xac,0x25, -0x12,0x30,0x24,0x22,0xe4,0xf5,0x6c,0xf5,0x6b,0x12,0x25,0x5d,0x22,0x90,0xfc,0x35, -0xe0,0x65,0x73,0x60,0x0e,0x74,0x04,0x90,0xfc,0x37,0xf0,0xe4,0xf5,0x6b,0x75,0x6c, -0x03,0x80,0x46,0x7d,0x73,0xe4,0xfe,0xff,0x79,0x35,0x7a,0xfc,0x7b,0x01,0x74,0x05, -0x78,0x00,0x12,0x03,0x3f,0xe5,0x6c,0x24,0x03,0xf5,0x6c,0xe5,0x6b,0x34,0x00,0xf5, -0x6b,0xe5,0x6c,0xd3,0x95,0x72,0xe5,0x6b,0x95,0x71,0x40,0x06,0x85,0x72,0x6c,0x85, -0x71,0x6b,0xd3,0xe5,0x6c,0x94,0x48,0xe5,0x6b,0x94,0x00,0x40,0x0c,0x74,0x02,0x90, -0xfc,0x37,0xf0,0xe4,0xf5,0x6b,0x75,0x6c,0x03,0xac,0x6c,0x12,0x30,0x24,0x22,0xec, -0x90,0xfc,0x37,0xf0,0xe4,0xf5,0x6c,0xf5,0x6b,0x8c,0x32,0xec,0x60,0x05,0x12,0x30, -0x15,0x80,0x05,0x7c,0x00,0x12,0x30,0x24,0x22,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0, -0xb2,0xb3,0x90,0xff,0x04,0xe0,0xf5,0x4a,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed, -0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff, -0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0xc3,0xec,0x94,0x48,0xed,0x94,0x00,0x50, -0x22,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90, -0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f, -0xfd,0x80,0x04,0xe4,0xfd,0x7c,0x48,0x8c,0x72,0x8d,0x71,0x90,0xff,0x02,0xe0,0xfd, -0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x02,0xe0,0xff,0xa3,0xe0, -0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xf5,0x4c,0xed,0x4f,0xf5,0x4b,0x75,0x6a,0x35, -0x75,0x69,0xfc,0x75,0x68,0x01,0x7d,0x35,0x7e,0xfc,0x7f,0x01,0x79,0x73,0xe4,0xfa, -0xfb,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,0x75,0x49,0x00,0xe5,0x49,0x24,0xfe,0x40, -0x19,0xad,0x6a,0xae,0x69,0xaf,0x68,0xe4,0x12,0x03,0x0f,0x05,0x49,0x0d,0xed,0x70, -0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,0x80,0xe1,0x75,0x6a,0x35,0x75,0x69,0xfc, -0x75,0x68,0x01,0x90,0xff,0x00,0xe0,0x54,0x60,0xb4,0x00,0x02,0x80,0x06,0xd3,0x50, -0x03,0x02,0x2c,0x6d,0xe5,0x4a,0x54,0x0f,0xf5,0x49,0xe5,0x4a,0x54,0x80,0xa2,0xe0, -0x92,0x02,0x90,0xff,0x01,0xe0,0x12,0x01,0x81,0x00,0x0b,0x2c,0x68,0x26,0xe5,0x28, -0x03,0x2c,0x68,0x29,0x0f,0x2c,0x68,0x29,0xf2,0x2a,0x26,0x2b,0x8d,0x2b,0x90,0x2b, -0xd0,0x2c,0x11,0x2c,0x3f,0xe5,0x6d,0x30,0xe7,0x0e,0xe5,0x4c,0x45,0x4b,0x70,0x08, -0xe5,0x72,0x64,0x02,0x45,0x71,0x60,0x03,0x02,0x2c,0x6a,0x90,0xff,0x00,0xe0,0x54, -0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x4a,0x60,0x03,0x02,0x28,0x00, -0xad,0x6a,0xae,0x69,0xaf,0x68,0x74,0x01,0x12,0x03,0x0f,0x78,0xad,0xe6,0x30,0xe0, -0x0b,0xad,0x6a,0xae,0x69,0xaf,0x68,0x74,0x02,0x12,0x03,0x0f,0x7c,0x02,0x12,0x30, -0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x1b,0xe5,0x6d,0x20,0xe1,0x07,0xe5, -0x4a,0x60,0x03,0x02,0x28,0x00,0xe5,0x4a,0x24,0xfe,0x50,0x03,0x02,0x28,0x00,0x7c, -0x02,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x27,0xfe, -0xe5,0x6d,0x20,0xe1,0x0d,0xe5,0x4a,0x60,0x09,0xe5,0x4a,0x64,0x80,0x60,0x03,0x02, -0x28,0x00,0xac,0x4a,0x12,0x30,0xab,0x40,0x03,0x02,0x28,0x00,0xe5,0x49,0x70,0x25, -0x30,0x02,0x11,0x90,0xff,0x80,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12, -0x03,0x0f,0x80,0x0f,0x90,0xff,0x82,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68, -0x12,0x03,0x0f,0x80,0x3d,0x15,0x49,0x30,0x02,0x1d,0xe5,0x49,0x75,0xf0,0x08,0xa4, -0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69, -0xaf,0x68,0x12,0x03,0x0f,0x80,0x1b,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5, -0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12, -0x03,0x0f,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12,0x01,0xe6,0x60,0x0b,0xad,0x6a,0xae, -0x69,0xaf,0x68,0x74,0x01,0x12,0x03,0x0f,0x7c,0x02,0x12,0x30,0x24,0x22,0x80,0x00, -0x02,0x2c,0x6a,0xe5,0x6d,0x20,0xe7,0x06,0xe5,0x72,0x45,0x71,0x60,0x03,0x02,0x2c, -0x6a,0x90,0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5, -0x4c,0x14,0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0x0c,0x78,0xad,0xe6, -0x54,0xfe,0xf6,0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40, -0x2a,0xe5,0x6d,0x20,0xe1,0x08,0xe5,0x6d,0x20,0xe0,0x03,0x02,0x29,0x0c,0xe5,0x6d, -0x30,0xe0,0x04,0xe5,0x4a,0x70,0x0b,0xe5,0x6d,0x30,0xe1,0x09,0xe5,0x4a,0x24,0xfe, -0x50,0x03,0x02,0x29,0x0c,0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x06, -0xd3,0x50,0x03,0x02,0x29,0x0a,0xe5,0x4c,0x45,0x4b,0x60,0x03,0x02,0x29,0x0c,0xac, -0x4a,0x12,0x30,0xab,0x40,0x03,0x02,0x29,0x0c,0xe5,0x6d,0x20,0xe1,0x07,0xe5,0x6d, -0x20,0xe0,0x02,0x80,0x77,0xe5,0x6d,0x30,0xe0,0x06,0xe5,0x49,0x60,0x02,0x80,0x6c, -0xe5,0x49,0x70,0x0f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x80,0xe0,0x54, -0xf7,0xf0,0x22,0xe5,0x49,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,0x01,0x7c, -0x03,0x12,0x0f,0x09,0x80,0x11,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d,0x01, -0x7c,0x04,0x12,0x0f,0x09,0x80,0x00,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,0x75,0xf0, -0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x80, -0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83, -0xe0,0x54,0xf7,0xf0,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x00,0x02,0x2c,0x6a,0xe5, -0x6d,0x20,0xe7,0x06,0xe5,0x72,0x45,0x71,0x60,0x03,0x02,0x2c,0x6a,0x90,0xff,0x00, -0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,0x4c,0x14,0x45,0x4b, -0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0xef,0x78,0xad,0xe6,0x44,0x01,0xf6,0x7c, -0x00,0x12,0x30,0x24,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x6d,0x20, -0xe1,0x08,0xe5,0x6d,0x20,0xe0,0x03,0x02,0x29,0xef,0xe5,0x6d,0x30,0xe0,0x04,0xe5, -0x49,0x70,0x0b,0xe5,0x6d,0x30,0xe1,0x08,0xe5,0x49,0x24,0xfe,0x50,0x02,0x80,0x7f, -0x7c,0x00,0x12,0x30,0x24,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x6f,0xe5,0x4c, -0x45,0x4b,0x60,0x02,0x80,0x69,0xac,0x4a,0x12,0x30,0xab,0x40,0x02,0x80,0x60,0xe5, -0x6d,0x20,0xe1,0x07,0xe5,0x6d,0x20,0xe0,0x02,0x80,0x54,0xe5,0x49,0x70,0x14,0x30, -0x02,0x09,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x80,0x07,0x90,0xff,0x82,0xe0,0x44, -0x08,0xf0,0x22,0xe5,0x6d,0x30,0xe1,0x33,0x15,0x49,0x30,0x02,0x15,0xe5,0x49,0x75, -0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x44,0x08,0xf0, -0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5, -0x83,0xe0,0x44,0x08,0xf0,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x02,0x80,0x00,0x02, -0x2c,0x6a,0xe5,0x6d,0x20,0xe7,0x12,0xe5,0x72,0x45,0x71,0x70,0x0c,0xe5,0x4a,0x70, -0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xe5,0x4c,0x90,0xff, -0xff,0xf0,0x90,0xff,0xff,0xe0,0x60,0x05,0x43,0x6d,0x01,0x80,0x03,0x53,0x6d,0xfe, -0x7c,0x00,0x12,0x30,0x24,0x22,0xe5,0x6d,0x30,0xe7,0x0e,0xe5,0x72,0x45,0x71,0x60, -0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xad,0x4b,0xe5,0x4c, -0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0xbd,0x00,0x02,0x80,0x03,0x02,0x2b,0x88,0xb4, -0x01,0x02,0x80,0x03,0xd3,0x40,0x32,0xe5,0x4a,0x70,0x05,0xe5,0x4c,0xfc,0x60,0x03, -0x02,0x2b,0x8a,0x75,0x6a,0x40,0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,0x94, -0x12,0xe5,0x71,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x12,0x80,0x04,0xac,0x72,0xad, -0x71,0x8c,0x70,0x8d,0x6f,0x12,0x30,0x39,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40, -0x59,0xe5,0x4a,0x60,0x03,0x02,0x2b,0x8a,0xe5,0x4c,0xfc,0x70,0x27,0x75,0x6a,0x52, -0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72,0x94,0x19,0xe5,0x71,0x94,0x00,0x40, -0x06,0xe4,0xfd,0x7c,0x19,0x80,0x04,0xac,0x72,0xad,0x71,0x8c,0x70,0x8d,0x6f,0x12, -0x30,0x39,0x80,0x25,0x75,0x6a,0x6b,0x75,0x69,0xf8,0x75,0x68,0x01,0xd3,0xe5,0x72, -0x94,0x27,0xe5,0x71,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x27,0x80,0x04,0xac,0x72, -0xad,0x71,0x8c,0x70,0x8d,0x6f,0x12,0x30,0x39,0x22,0xb4,0x03,0x02,0x80,0x06,0xd3, -0x50,0x03,0x02,0x2b,0x88,0xe5,0x4c,0xf5,0x49,0x70,0x0f,0x90,0xff,0x04,0xe0,0xfd, -0xa3,0xe0,0x4d,0x60,0x03,0x02,0x2b,0x8a,0x80,0x18,0x90,0xfb,0x02,0xe0,0xfd,0xa3, -0xe0,0xfc,0x90,0xff,0x05,0xe0,0x6c,0x70,0x07,0x90,0xff,0x04,0xe0,0x6d,0x60,0x02, -0x80,0x68,0xe4,0xf5,0x70,0xf5,0x6f,0x7f,0x00,0xe5,0x49,0x14,0xc5,0x49,0x60,0x0f, -0xef,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x2f,0xff,0x80,0xea,0x8f, -0x4a,0xe5,0x4a,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7d,0x00,0xd3, -0x95,0x72,0xed,0x95,0x71,0x40,0x06,0xac,0x72,0xad,0x71,0x80,0x0f,0xe5,0x4a,0x24, -0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7d,0x00,0xfc,0x8c,0x70,0x8d,0x6f, -0xe5,0x4a,0x24,0x00,0xfc,0xe4,0x34,0xfb,0xfd,0xfe,0xec,0xfd,0x7f,0x01,0x8d,0x6a, -0x8e,0x69,0x8f,0x68,0x12,0x30,0x39,0x22,0x80,0x00,0x02,0x2c,0x6a,0x02,0x2c,0x6a, -0xe5,0x6d,0x30,0xe7,0x19,0xe5,0x72,0x14,0x45,0x71,0x70,0x12,0xe5,0x4a,0x70,0x0e, -0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c, -0x6a,0xe5,0x6d,0x20,0xe0,0x08,0xe5,0x6d,0x20,0xe1,0x03,0x02,0x2c,0x6a,0x75,0x6a, -0x6e,0xe4,0xf5,0x69,0xf5,0x68,0xe4,0xf5,0x6f,0x04,0xf5,0x70,0x12,0x30,0x39,0x22, -0xe5,0x6d,0x20,0xe7,0x12,0xe5,0x72,0x45,0x71,0x70,0x0c,0xe5,0x4a,0x70,0x08,0x90, -0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x6a,0xe5,0x6d,0x20,0xe0,0x07,0xe5, -0x6d,0x20,0xe1,0x02,0x80,0x74,0x85,0x4c,0x6e,0xe5,0x6e,0x70,0x08,0x43,0x6d,0x01, -0x53,0x6d,0xfd,0x80,0x06,0x53,0x6d,0xfe,0x43,0x6d,0x02,0x7c,0x00,0x12,0x30,0x24, -0x22,0xe5,0x6d,0x30,0xe7,0x1a,0xe5,0x72,0x14,0x45,0x71,0x70,0x13,0xe5,0x4a,0x70, -0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02, -0x80,0x38,0xe5,0x6d,0x20,0xe1,0x02,0x80,0x31,0x7c,0x01,0x12,0x30,0x24,0x22,0xe5, -0x6d,0x20,0xe7,0x15,0xe5,0x72,0x45,0x71,0x70,0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09, -0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,0x80,0x0f,0xe5,0x6d,0x20,0xe1,0x02, -0x80,0x08,0x7c,0x00,0x12,0x30,0x24,0x22,0x80,0x00,0x02,0x2f,0x2b,0xb4,0x40,0x02, -0x80,0x06,0xd3,0x50,0x03,0x02,0x2f,0x21,0x90,0xff,0x01,0xe0,0x90,0xfc,0x35,0xf0, -0xe5,0x4a,0x90,0xfc,0x36,0xf0,0xe4,0x90,0xfc,0x37,0xf0,0xe5,0x6a,0x24,0x03,0xf5, -0x6a,0xe5,0x69,0x34,0x00,0xf5,0x69,0xad,0x4b,0xe5,0x4c,0x85,0x6a,0x82,0x85,0x69, -0x83,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xff,0x01,0xe0,0x12,0x01,0xb7,0x2c,0xd8,0x01, -0x2c,0xfe,0x02,0x2d,0x28,0x03,0x2d,0x52,0x04,0x2d,0xa0,0x05,0x2d,0xdd,0x06,0x2e, -0x03,0x07,0x2e,0x29,0x08,0x2e,0x55,0x09,0x2e,0x7b,0x0b,0x2e,0xa1,0x0c,0x2e,0xb0, -0x80,0x2e,0xb0,0x81,0x00,0x00,0x2f,0x0e,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12, -0x25,0xbf,0x22,0x7d,0x24,0x7e,0x35,0x7f,0x02,0x79,0x38,0x7a,0xfc,0x7b,0x01,0x74, -0x08,0x78,0x00,0x12,0x03,0x3f,0x7d,0x08,0x7c,0x00,0x12,0x25,0x26,0x22,0xe5,0x6d, -0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10, -0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x10,0x12,0x31,0xfb,0x22, -0x7d,0x00,0x7c,0x07,0x12,0x25,0x26,0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12, -0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5, -0x4a,0x7f,0x00,0xfe,0x7c,0x11,0x12,0x31,0xfb,0x22,0x7d,0x00,0x7c,0x07,0x12,0x25, -0x26,0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4, -0x05,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0a,0x12,0x31,0xfb, -0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x08,0x12, -0x31,0xfb,0x22,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f, -0x00,0xfe,0x7c,0x13,0x12,0x31,0xfb,0x22,0x7d,0x00,0x7c,0x07,0x12,0x25,0x26,0x22, -0xe5,0x6d,0x20,0xe7,0x34,0xd3,0xe5,0x72,0x94,0x48,0xe5,0x71,0x94,0x00,0x50,0x06, -0xe5,0x72,0x45,0x71,0x70,0x06,0x7c,0x02,0x12,0x25,0xbf,0x22,0xe5,0x4a,0xb4,0x01, -0x03,0xb3,0x40,0x0b,0xc3,0xb4,0x03,0x00,0x40,0x09,0xb4,0x06,0x00,0x50,0x04,0x12, -0x30,0xd1,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20, -0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a, -0x7f,0x00,0xfe,0x7c,0x16,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12, -0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4, -0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x19,0x12,0x31,0xfb,0x22,0x7c, -0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x23,0x74,0x81, -0x90,0xff,0x93,0xf0,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b, -0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x17,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf, -0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40, -0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x18,0x12,0x31,0xfb, -0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22,0xe5,0x6d,0x20,0xe7,0x1d, -0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00, -0xfe,0x7c,0x15,0x12,0x31,0xfb,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d, -0x22,0xe5,0x6d,0x20,0xe7,0x06,0x7c,0x07,0x12,0x25,0xbf,0x22,0x12,0x25,0x5d,0x22, -0xe5,0x6d,0x30,0xe7,0x20,0x90,0xff,0x00,0xe0,0x54,0x1f,0x70,0x10,0x90,0xff,0x01, -0xe0,0xb4,0x80,0x05,0x12,0x25,0x54,0x80,0x03,0x12,0x25,0x5d,0x22,0x7d,0x00,0x7c, -0x05,0x12,0x25,0x26,0x22,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x06,0x7c,0x05,0x12, -0x25,0xbf,0x22,0xd3,0xe5,0x72,0x94,0x48,0xe5,0x71,0x94,0x00,0x50,0x0b,0xc3,0xe5, -0x72,0x94,0x07,0xe5,0x71,0x94,0x00,0x50,0x06,0x7c,0x03,0x12,0x25,0xbf,0x22,0xe5, -0x4a,0xb4,0x05,0x04,0x12,0x30,0xd1,0x22,0x7c,0x07,0x12,0x25,0xbf,0x22,0xe5,0x6d, -0x30,0xe7,0x08,0x7d,0x00,0x7c,0x05,0x12,0x25,0x26,0x22,0x7c,0x05,0x12,0x25,0xbf, -0x22,0xb4,0x20,0x02,0x80,0x03,0xd3,0x40,0x00,0x80,0x00,0x12,0x2f,0xff,0x22,0x75, -0x43,0x00,0x90,0xff,0x83,0xe0,0x54,0x0f,0xd3,0x95,0x43,0x40,0x24,0xe5,0x43,0x24, -0xf0,0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,0xe0,0xad,0x6a,0xae,0x69,0xaf,0x68,0x12, -0x03,0x0f,0x05,0x43,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68,0x80, -0xd1,0xe5,0x43,0x7d,0x00,0xfc,0xc3,0xe5,0x70,0x9c,0xf5,0x70,0xe5,0x6f,0x9d,0xf5, -0x6f,0xe5,0x70,0x45,0x6f,0x60,0x06,0xe4,0x90,0xff,0x83,0xf0,0x22,0x90,0xff,0x82, -0xe0,0x44,0x08,0xf0,0xe4,0xf5,0x6f,0x75,0x70,0x49,0x90,0xfc,0x35,0xe0,0xb4,0x05, -0x02,0x80,0x03,0xd3,0x40,0x40,0x90,0xfc,0x36,0xe0,0xf5,0x43,0xb4,0x05,0x02,0x80, -0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0b,0x12,0x31,0xfb,0x22,0xb4,0x01, -0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x09,0x12,0x31,0xfb,0x22, -0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x43,0x7f,0x00,0xfe,0x7c, -0x14,0x12,0x31,0xfb,0x22,0x22,0xb4,0x80,0x00,0x40,0x23,0xb4,0x82,0x00,0x50,0x1e, -0x7c,0x35,0x7d,0xfc,0x12,0x17,0x7e,0x7d,0x00,0x8c,0x6c,0x8d,0x6b,0x90,0xfc,0x37, -0xe0,0x60,0x05,0x12,0x2f,0xff,0x80,0x05,0x7c,0x00,0x12,0x30,0x24,0x22,0x22,0x90, -0xff,0x83,0xe0,0x54,0x7f,0xf0,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80, -0xe0,0x44,0x08,0xf0,0x22,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0, -0x44,0x08,0xf0,0x22,0x8c,0x23,0x7d,0x00,0x8c,0x70,0x8d,0x6f,0x75,0x6a,0x35,0x75, -0x69,0xfc,0x75,0x68,0x01,0x12,0x30,0x39,0x22,0x90,0xff,0x83,0xe0,0x54,0x7f,0xf0, -0xe5,0x70,0x64,0x49,0x45,0x6f,0x70,0x01,0x22,0xc3,0xe5,0x70,0x94,0x08,0xe5,0x6f, -0x94,0x00,0x40,0x15,0x75,0x21,0x08,0xe5,0x21,0x7d,0x00,0xfc,0xc3,0xe5,0x70,0x9c, -0xf5,0x70,0xe5,0x6f,0x9d,0xf5,0x6f,0x80,0x09,0x85,0x70,0x21,0xe4,0xf5,0x6f,0x75, -0x70,0x49,0x75,0x22,0x00,0xe5,0x22,0xc3,0x95,0x21,0x50,0x26,0xad,0x6a,0xae,0x69, -0xaf,0x68,0x12,0x01,0xe6,0xfc,0xe5,0x22,0x24,0xf8,0xf5,0x82,0xe4,0x34,0xfe,0xf5, -0x83,0xec,0xf0,0x05,0x22,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x6a,0x8e,0x69,0x8f,0x68, -0x80,0xd3,0xe5,0x21,0x54,0x7f,0x90,0xff,0x81,0xf0,0x22,0x8c,0x48,0x7f,0x00,0xef, -0x24,0xfd,0x40,0x19,0xe4,0xef,0x75,0xf0,0x07,0xa4,0x24,0x7f,0xf5,0x82,0xe4,0x34, -0xf8,0xf5,0x83,0xe0,0x65,0x48,0x70,0x02,0xd3,0x22,0x0f,0x80,0xe2,0x8f,0x47,0xc3, -0x22,0x85,0x72,0x70,0x85,0x71,0x6f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff, -0x83,0xe0,0x54,0x7f,0xf0,0x22,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07, -0xe5,0x78,0x24,0x08,0xf8,0x86,0x06,0x53,0x06,0x7f,0x7c,0xff,0x12,0x31,0x5b,0x7c, -0x00,0x7d,0x00,0xe5,0x7b,0x60,0x46,0xff,0x90,0xfd,0x95,0xe0,0x54,0x7f,0x6e,0x70, -0x0f,0xc0,0x83,0xc0,0x82,0xa3,0xe0,0xfd,0xa3,0xe0,0xfc,0xa3,0x15,0x7b,0x80,0x07, -0xa3,0xa3,0xa3,0xdf,0xe6,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0x1e,0xe0, -0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0, -0xa3,0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x12,0x31,0xf4, -0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x22,0x85,0xa8,0x7a,0x75,0xa8, -0x88,0xec,0x70,0x02,0x7c,0x3f,0x8c,0x79,0x22,0xe5,0x78,0x24,0x08,0xf8,0x76,0x00, -0x12,0x32,0x48,0x80,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xae, -0x04,0x7c,0xff,0x12,0x31,0x5b,0xe5,0x7b,0x60,0x42,0xff,0x90,0xfd,0x95,0xe0,0x54, -0x7f,0x6e,0x70,0x0b,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x15,0x7b,0x80,0x07,0xa3, -0xa3,0xa3,0xdf,0xea,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0xd8,0xe0,0xf8, -0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3, -0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x78,0x08,0x08,0x79, -0x18,0x09,0x7c,0x01,0xe6,0x54,0x7f,0x6e,0x70,0x06,0x76,0x00,0x77,0x00,0x80,0x06, -0x08,0x09,0x0c,0xbc,0x08,0xee,0x12,0x31,0xf4,0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0, -0x01,0xd0,0x00,0x22,0x75,0x79,0x00,0x85,0x7a,0xa8,0x22,0xc0,0xf0,0xc0,0x82,0xc0, -0x83,0xc3,0xe5,0x7b,0x24,0xe8,0x50,0x05,0x12,0x32,0x48,0x80,0xf4,0xec,0x60,0x31, -0x90,0x35,0x23,0xe4,0x93,0xc3,0x9c,0x40,0x28,0xc0,0x04,0x7c,0xff,0x12,0x31,0x5b, -0xd0,0x04,0x43,0x04,0x80,0xe5,0x7b,0x75,0xf0,0x03,0xa4,0x24,0x95,0xf5,0x82,0xe4, -0x34,0xfd,0xf5,0x83,0xec,0xf0,0xef,0xa3,0xf0,0xee,0xa3,0xf0,0x05,0x7b,0x12,0x31, -0xf4,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0xc0,0x04,0x7c,0x20,0xd2,0x8c,0xd2,0x8d, -0xd5,0x04,0xfd,0xd0,0x04,0x22,0x75,0xa8,0x00,0x75,0x88,0x00,0x75,0xb8,0x00,0x75, -0xf0,0x00,0x75,0xd0,0x00,0xe4,0xf8,0x90,0x00,0x00,0xf6,0x08,0xb8,0x00,0xfb,0x02, -0x00,0x00,0xc3,0xed,0x94,0x02,0x50,0x04,0x7d,0x03,0x7c,0xe8,0xec,0xf4,0xfc,0xed, -0xf4,0xfd,0x0c,0xbc,0x00,0x01,0x0d,0x8c,0x7f,0x8d,0x7e,0x22,0xc3,0xec,0x94,0xbc, -0xed,0x94,0x02,0x50,0x04,0x7d,0x07,0x7c,0xd0,0xec,0xf4,0xfc,0xed,0xf4,0xfd,0x0c, -0xbc,0x00,0x01,0x0d,0x8c,0x7d,0x8d,0x7c,0x22,0xec,0x70,0x01,0x22,0xc0,0x00,0xe5, -0x78,0x24,0x18,0xf8,0xa6,0x04,0xe5,0x78,0x24,0x08,0xf8,0xc6,0x54,0x7f,0xf6,0xe6, -0x30,0xe7,0x03,0xd0,0x00,0x22,0x12,0x32,0x48,0x80,0xf4,0xc2,0x8c,0x85,0x7c,0x8c, -0x85,0x7d,0x8a,0xd2,0x8c,0xc0,0xe0,0xc0,0xd0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0, -0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x12, -0x1a,0xd1,0xe5,0x78,0x24,0x08,0xf8,0xe6,0x60,0x24,0xe5,0x78,0x24,0x10,0xf8,0xa6, -0x81,0xe5,0x78,0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, -0x78,0xae,0xe5,0x81,0x04,0xc3,0x98,0xf9,0xe6,0xf0,0x08,0xa3,0xd9,0xfa,0x74,0x08, -0x25,0x78,0xf8,0x05,0x78,0x08,0xe6,0x54,0x80,0x70,0x0c,0xe5,0x78,0xb4,0x07,0xf3, -0x78,0x08,0x75,0x78,0x00,0x80,0xef,0xe5,0x78,0x24,0x10,0xf8,0x86,0x81,0xe5,0x78, -0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0x78,0xae,0xe5, -0x81,0x04,0xc3,0x98,0xf9,0xe0,0xf6,0x08,0xa3,0xd9,0xfa,0xd0,0x07,0xd0,0x06,0xd0, -0x05,0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0, -0xf0,0xd0,0xd0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02, -0xc2,0x8e,0x85,0x7e,0x8d,0x85,0x7f,0x8b,0xd2,0x8e,0x78,0x19,0x79,0x09,0x7a,0x07, -0xe7,0x70,0x04,0xa6,0x00,0x80,0x0b,0xe6,0x60,0x08,0x16,0xe6,0x70,0x04,0xe7,0x44, -0x80,0xf7,0x08,0x09,0xda,0xea,0xe5,0x79,0x60,0x13,0x14,0xf5,0x79,0x70,0x0e,0xe5, -0x78,0x24,0x08,0xf8,0x76,0x00,0x12,0x31,0xf4,0xd2,0x8c,0xd2,0x8d,0xd0,0x02,0xd0, -0x01,0xd0,0x00,0xd0,0xd0,0xd0,0xe0,0x32,0x75,0x81,0xad,0x74,0x2a,0x90,0xff,0x93, -0xf0,0x75,0x7f,0x30,0x75,0x7e,0xf8,0x75,0x7d,0x60,0x75,0x7c,0xf0,0x12,0x05,0x36, -0x12,0x34,0x7c,0x12,0x17,0x34,0x90,0xff,0x93,0xe0,0x44,0x01,0xf0,0xb2,0xb3,0x12, -0x34,0xa6,0x12,0x32,0x56,0x80,0xda,0x22,0xc0,0x00,0x7c,0x01,0xec,0x24,0x08,0xf8, -0xe6,0x60,0x09,0x0c,0xbc,0x08,0xf5,0x12,0x32,0x48,0x80,0xee,0xd0,0x00,0x22,0xc0, -0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,0xc0,0x06,0xc0,0x07,0xed,0x24,0x10,0xf8,0x76, -0xbc,0xed,0x75,0xf0,0x21,0xa4,0x24,0x8d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xc0, -0x82,0xc0,0x83,0xa3,0xa3,0xe4,0x78,0x0d,0xf0,0xa3,0xd8,0xfc,0xec,0x54,0x7f,0x75, -0xf0,0x02,0xa4,0x24,0xef,0xf5,0x82,0xe5,0xf0,0x34,0x34,0xf5,0x83,0xe4,0x93,0xfe, -0x74,0x01,0x93,0xf5,0x82,0x8e,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xd0,0x83, -0xd0,0x82,0xef,0xf0,0xa3,0xee,0xf0,0xed,0x24,0x08,0xf8,0xec,0x44,0x80,0xf6,0xd0, -0x07,0xd0,0x06,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0x75,0x78,0x00,0x75, -0x7b,0x00,0x7a,0x08,0x79,0x18,0x78,0x08,0x76,0x00,0x77,0x00,0x08,0x09,0xda,0xf8, -0xe4,0x78,0x08,0x74,0x80,0x44,0x7f,0xf6,0x74,0x01,0x44,0x10,0xf5,0x89,0x75,0xb8, -0x08,0xd2,0xab,0xd2,0xa9,0x22,0x75,0x81,0xad,0xd2,0x8e,0xd2,0x8c,0xd2,0xaf,0xe5, -0x7b,0x60,0x32,0xff,0x90,0xfd,0x95,0xe0,0x54,0x80,0x60,0x24,0x78,0x08,0x79,0x08, -0xe0,0x54,0x7f,0xfa,0x7b,0x00,0xe6,0x54,0x7f,0xb5,0x02,0x02,0x7b,0xff,0x08,0xd9, -0xf5,0xeb,0x70,0x0c,0xea,0xf0,0x12,0x33,0xf8,0xad,0x04,0xac,0x02,0x12,0x34,0x0f, -0xa3,0xa3,0xa3,0xdf,0xd2,0x12,0x32,0x48,0x80,0xc5,0x7c,0x01,0x7d,0x00,0x22,0x04, -0xf5,0x04,0xe9,0x04,0xed,0x04,0xe1,0x04,0xdd,0x04,0xd9,0x04,0xe5,0x04,0xf1,0x04, -0x9d,0x04,0xa1,0x04,0xcd,0x04,0xd1,0x04,0x99,0x04,0x99,0x04,0x99,0x04,0xd5,0x04, -0xb5,0x04,0xad,0x04,0xb1,0x04,0xa9,0x04,0xc1,0x04,0xbd,0x04,0xb9,0x04,0xc5,0x04, -0xc9,0x04,0xa5,0x19,0x01,0x03,0x00,0x22,0x00,0x48,0x02,0x00,0x48,0x0e,0x30,0x14, -0x20,0xc8,0x1a,0xd0,0x18,0x0a,0x0c,0x05,0x06,0x02,0x03,0x01,0x02,0x00,0x01,0xce, -0x01,0x81,0x01,0x00,0x00,0xc0,0x00,0x80,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x10, -0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x08,0x18,0x38,0x28,0x0c,0x05,0x10, -0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x10,0x0a,0x02,0x00,0x00,0x00,0x00, -0x00,0xfb,0xe0,0xfb,0xf2,0x09,0x02,0x27,0x00,0x01,0x02,0x00,0xa0,0x32,0x09,0x04, -0x00,0x00,0x03,0xff,0x00,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00,0x00,0x07,0x05, -0x01,0x02,0x40,0x00,0x00,0x07,0x05,0x83,0x03,0x02,0x00,0x01,0x22,0x03,0x54,0x00, -0x55,0x00,0x53,0x00,0x42,0x00,0x33,0x00,0x34,0x00,0x31,0x00,0x30,0x00,0x20,0x00, -0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00, -0x00,0x00, -}; - -#endif /* ifndef _TI_FW_3410_H_ */ diff --git a/drivers/usb/serial/ti_fw_5052.h b/drivers/usb/serial/ti_fw_5052.h deleted file mode 100644 index 6ccf40a..0000000 --- a/drivers/usb/serial/ti_fw_5052.h +++ /dev/null @@ -1,885 +0,0 @@ -/* vi: ts=8 sw=8 - * - * TI 5052 USB Serial Driver Firmware Header - * - * Copyright (C) 2004 Texas Instruments - * - * 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 _TI_FW_5052_H_ -#define _TI_FW_5052_H_ - -/* firmware 9/18/04 */ - -static unsigned char ti_fw_5052[] = { -0xC1, 0x35, /* firmware image length excluding header, little endian */ -0x00, /* placeholder for checksum */ - -0x02,0x00,0x1e,0x02,0x1b,0x32,0xff,0xff,0xff,0xff,0xff,0x02,0x32,0x6a,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x33,0x15,0x75,0x81, -0xc8,0x90,0xfe,0xf0,0x85,0x83,0xa0,0x12,0x34,0x7d,0xec,0x4d,0x60,0x6a,0x78,0xa5, -0x80,0x03,0x76,0x00,0x18,0xb8,0x96,0xfa,0x78,0x79,0x80,0x03,0x76,0x00,0x18,0xb8, -0x5f,0xfa,0x78,0x20,0x80,0x03,0x76,0x00,0x18,0xb8,0x20,0xfa,0x90,0xfe,0xe5,0xae, -0x83,0xaf,0x82,0x90,0xfd,0x00,0x12,0x00,0xa1,0x60,0x05,0xe4,0xf0,0xa3,0x80,0xf6, -0x90,0xfe,0xf0,0xa8,0x82,0x90,0xfe,0xf0,0xa9,0x82,0xe8,0xc3,0x99,0x50,0x05,0x76, -0x00,0x08,0x80,0xf6,0x90,0x00,0xff,0x12,0x00,0xaa,0x90,0x01,0x03,0x12,0x00,0xaa, -0x90,0x01,0x07,0x12,0x00,0xaa,0x90,0x01,0x0b,0x12,0x00,0xc8,0x90,0x01,0x11,0x12, -0x00,0xc8,0x90,0x01,0x17,0x12,0x00,0xc8,0x75,0xd0,0x00,0x12,0x33,0x67,0x02,0x01, -0x1d,0xef,0x65,0x82,0x70,0x03,0xee,0x65,0x83,0x22,0xe4,0x93,0xf8,0x74,0x01,0x93, -0xf9,0x74,0x02,0x93,0xfe,0x74,0x03,0x93,0xf5,0x82,0x8e,0x83,0xe8,0x69,0x70,0x01, -0x22,0xe4,0x93,0xf6,0xa3,0x08,0x80,0xf4,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74, -0x02,0x93,0xfe,0x74,0x03,0x93,0xff,0x74,0x04,0x93,0xf8,0x74,0x05,0x93,0xf5,0x82, -0x88,0x83,0x12,0x00,0xa1,0x70,0x01,0x22,0xe4,0x93,0xa3,0xa8,0x83,0xa9,0x82,0x8c, -0x83,0x8d,0x82,0xf0,0xa3,0xac,0x83,0xad,0x82,0x88,0x83,0x89,0x82,0x80,0xe3,0x21, -0x21,0x04,0x92,0x7a,0x7a,0x04,0x92,0xa6,0xa8,0x04,0x92,0xfe,0xf0,0x04,0x94,0x04, -0x94,0xfb,0xfb,0x04,0x99,0x04,0x94,0xfb,0xfb,0x04,0xf9,0x04,0xf9,0x80,0xfe,0xd0, -0xf0,0x30,0xf0,0x09,0x20,0xf3,0x03,0xf6,0x80,0x10,0xf7,0x80,0x0d,0x30,0xf1,0x09, -0x20,0xf3,0x03,0xf2,0x80,0x04,0xf3,0x80,0x01,0xf0,0x20,0xf4,0x04,0xfc,0xd0,0xe0, -0xcc,0x22,0xcc,0xc0,0xe0,0x12,0x01,0x5a,0x02,0x01,0x4b,0xbc,0x00,0x05,0xd0,0xf0, -0xac,0xf0,0x22,0xc3,0x13,0xdc,0xfc,0x02,0x01,0x21,0xbf,0x00,0x09,0xed,0x25,0x82, -0x75,0xf0,0x01,0xf8,0xe6,0x22,0xbf,0x01,0x0f,0xed,0x25,0x82,0xf5,0x82,0xee,0x35, -0x83,0xf5,0x83,0x75,0xf0,0x04,0xe0,0x22,0xed,0x25,0x82,0x75,0xf0,0x02,0xf8,0xe2, -0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xc3,0xe4,0x93,0xa3,0xc5,0xf0,0x95,0xf0,0xc0, -0xe0,0xc3,0xd0,0xf0,0xe4,0x93,0xa3,0x95,0xf0,0x40,0x12,0xa3,0xa3,0xc3,0xe5,0xf0, -0x33,0x50,0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0x50,0x02,0x05,0x83,0x74,0x01,0x93, -0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22,0xd0,0x83,0xd0,0x82,0xf5,0xf0,0xe4,0x93,0x70, -0x09,0x74,0x01,0x93,0x70,0x04,0xa3,0xa3,0x80,0x0c,0x74,0x02,0x93,0x65,0xf0,0x60, -0x05,0xa3,0xa3,0xa3,0x80,0xe7,0x74,0x01,0x93,0xc0,0xe0,0xe4,0x93,0xc0,0xe0,0x22, -0x12,0x02,0x5b,0x02,0x01,0xf2,0x12,0x02,0xaf,0x02,0x01,0xf2,0x12,0x02,0xd3,0x02, -0x01,0xf2,0x30,0xe0,0x07,0x20,0xe3,0x02,0xe6,0x22,0xe7,0x22,0x30,0xe1,0x07,0x20, -0xe3,0x02,0xe2,0x22,0xe3,0x22,0x30,0xe2,0x02,0xe0,0x22,0xe4,0x93,0x22,0x12,0x02, -0xd3,0x02,0x02,0x1a,0x12,0x02,0xaf,0x02,0x02,0x1a,0xab,0xf0,0x12,0x02,0x24,0xcb, -0xc5,0xf0,0xcb,0x22,0x30,0xe0,0x10,0x20,0xe3,0x06,0xe6,0xf5,0xf0,0x08,0xe6,0x22, -0xe7,0xf5,0xf0,0x09,0xe7,0x19,0x22,0x30,0xe1,0x10,0x20,0xe3,0x06,0xe2,0xf5,0xf0, -0x08,0xe2,0x22,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x30,0xe2,0x06,0xe0,0xf5,0xf0, -0xa3,0xe0,0x22,0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x00,0x03,0x74,0x09, -0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x74,0x04,0x22,0xbb,0x02,0x07,0x89,0x82, -0x8a,0x83,0x74,0x10,0x22,0x74,0x0a,0x22,0x02,0x02,0x7b,0xbb,0x00,0x07,0xe9,0x25, -0x82,0xf8,0x74,0x01,0x22,0xbb,0x01,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83, -0xf5,0x83,0x74,0x04,0x22,0xbb,0x02,0x0d,0xe9,0x25,0x82,0xf5,0x82,0xea,0x35,0x83, -0xf5,0x83,0x74,0x10,0x22,0xe9,0x25,0x82,0xf8,0x74,0x02,0x22,0x02,0x02,0xaf,0xbf, -0x00,0x05,0xed,0xf8,0x74,0x01,0x22,0xbf,0x01,0x07,0x8d,0x82,0x8e,0x83,0x74,0x04, -0x22,0xbf,0x02,0x07,0x8d,0x82,0x8e,0x83,0x74,0x10,0x22,0xed,0xf8,0x74,0x02,0x22, -0x02,0x02,0xd3,0xbf,0x00,0x07,0xed,0x25,0x82,0xf8,0x74,0x01,0x22,0xbf,0x01,0x0d, -0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x04,0x22,0xbf,0x02,0x0d, -0xed,0x25,0x82,0xf5,0x82,0xee,0x35,0x83,0xf5,0x83,0x74,0x10,0x22,0xed,0x25,0x82, -0xf8,0x74,0x02,0x22,0x02,0x03,0x07,0xc0,0xe0,0x12,0x02,0x5b,0x02,0x03,0x1f,0xc0, -0xe0,0x12,0x02,0xaf,0x02,0x03,0x1f,0xc0,0xe0,0x12,0x02,0xd3,0x02,0x03,0x1f,0x30, -0xe0,0x0b,0x20,0xe3,0x04,0xd0,0xe0,0xf6,0x22,0xd0,0xe0,0xf7,0x22,0x30,0xe1,0x0b, -0x20,0xe3,0x04,0xd0,0xe0,0xf2,0x22,0xd0,0xe0,0xf3,0x22,0xd0,0xe0,0xf0,0x22,0xc9, -0xcd,0xc9,0xca,0xce,0xca,0xcb,0xcf,0xcb,0x12,0x03,0x52,0xed,0xf9,0xee,0xfa,0xef, -0xfb,0x22,0xbb,0x00,0x2f,0xbf,0x00,0x0a,0xfa,0xed,0xf8,0xe7,0xf6,0x08,0x09,0xda, -0xfa,0x22,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x03,0x6f,0x09,0xa3,0xe7, -0xf0,0xd8,0xfa,0x22,0x02,0x03,0x7a,0xfa,0xed,0xf8,0xe7,0xf2,0x08,0x09,0xda,0xfa, -0x22,0x02,0x03,0x84,0xbb,0x01,0x4d,0xbf,0x00,0x14,0x89,0x82,0x8a,0x83,0xf9,0xed, -0xf8,0x02,0x03,0x96,0x08,0xa3,0xe0,0xf6,0xd9,0xfa,0x22,0x02,0x03,0xa7,0xbf,0x01, -0x22,0x8d,0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe0, -0xa3,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xea,0xd8,0xe8,0x22, -0x02,0x03,0xca,0x8d,0x82,0x8e,0x83,0xf9,0xed,0xf8,0xe0,0xf2,0x08,0xa3,0xd9,0xfa, -0x22,0x02,0x03,0xd4,0xbb,0x02,0x4d,0xbf,0x00,0x12,0x89,0x82,0x8a,0x83,0xf9,0xed, -0xf8,0x02,0x03,0xe6,0x08,0xa3,0xe4,0x93,0xf6,0xd9,0xf9,0x22,0xbf,0x01,0x23,0x8d, -0x82,0x8e,0x83,0xfb,0x08,0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xe4,0x93,0xa3, -0xc9,0xc5,0x82,0xc9,0xca,0xc5,0x83,0xca,0xf0,0xa3,0xdb,0xe9,0xd8,0xe7,0x22,0x02, -0x04,0x19,0x89,0x82,0x8a,0x83,0xf9,0xed,0xf8,0xe4,0x93,0xf2,0x08,0xa3,0xd9,0xf9, -0x22,0x02,0x04,0x2a,0xbf,0x00,0x0d,0xfa,0xed,0xf8,0xe3,0xf6,0x08,0x09,0xda,0xfa, -0x22,0x02,0x04,0x34,0xbf,0x01,0x12,0x8d,0x82,0x8e,0x83,0xf8,0x02,0x04,0x41,0x09, -0xa3,0xe3,0xf0,0xd8,0xfa,0x22,0x02,0x04,0x4c,0xfa,0xed,0xf8,0xe3,0xf2,0x08,0x09, -0xda,0xfa,0x22,0x02,0x04,0x56,0xe6,0xfb,0x08,0xe6,0xfa,0x08,0xe6,0xf9,0x04,0xf6, -0x18,0x70,0x01,0x06,0x22,0xe6,0xff,0x08,0xe6,0xfe,0x08,0xe6,0xfd,0x22,0xef,0xf0, -0xa3,0xee,0xf0,0xa3,0xed,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22, -0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xfd,0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0, -0xf9,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xf9,0x00,0x5b,0x05,0x73,0x00, -0x26,0x05,0x9a,0x00,0x33,0x0a,0x0b,0x00,0x5b,0x0a,0x77,0x00,0x60,0x15,0x52,0x00, -0x5b,0x0c,0xfb,0x00,0x5b,0x09,0xab,0x00,0x5b,0x09,0xe2,0x00,0x5b,0x0d,0xc2,0x00, -0x5b,0x0b,0xf3,0x00,0x5b,0x0a,0x1e,0x00,0x5b,0x0a,0x53,0x00,0x5b,0x17,0x4a,0x00, -0x33,0x17,0x60,0x00,0x34,0x1e,0x4d,0x00,0x43,0x1e,0xf0,0x00,0x44,0x20,0x5d,0x00, -0x44,0x20,0x4b,0x00,0x47,0x1f,0x17,0x00,0x47,0x1f,0xbc,0x00,0x4d,0x20,0x0d,0x00, -0x4f,0x1f,0x39,0x00,0x58,0x31,0xf5,0x00,0x5b,0x7c,0xcc,0x7d,0xff,0x12,0x1c,0xfe, -0x22,0x74,0x90,0x90,0xff,0x91,0xf0,0x90,0xff,0xfc,0xe0,0x20,0xe7,0x2d,0xc2,0xaf, -0xae,0x59,0xaf,0x58,0x75,0x5a,0x20,0xe5,0x5a,0x14,0xc5,0x5a,0x60,0x19,0xe4,0xfe, -0x7f,0x05,0xee,0x4f,0xce,0x24,0xff,0xce,0xcf,0x34,0xff,0xcf,0x60,0x07,0xe4,0x90, -0xff,0x92,0xf0,0x80,0xed,0x80,0xe0,0x8e,0x59,0x8f,0x58,0x22,0x12,0x05,0x01,0x7d, -0x07,0x7c,0xb7,0x12,0x32,0x11,0x7d,0x0f,0x7c,0x6e,0x12,0x32,0x2b,0x78,0x97,0x7a, -0x06,0xe4,0xf6,0x08,0xda,0xfc,0x7a,0x06,0x12,0x05,0xcf,0x7c,0x03,0x12,0x0e,0x57, -0x7c,0x04,0x12,0x0e,0x57,0x12,0x21,0x8b,0xe4,0xfe,0xff,0x7c,0x0f,0x12,0x31,0x9a, -0xd2,0xa8,0x22,0x12,0x30,0x85,0xe4,0x90,0xfd,0x40,0xf0,0x90,0xff,0xf0,0xe0,0x30, -0xe4,0x08,0x74,0x01,0x90,0xfd,0x41,0xf0,0x80,0x05,0xe4,0x90,0xfd,0x41,0xf0,0x7d, -0x0a,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,0xfd,0x41, -0xe0,0x14,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x44,0x10,0xf0,0x7c,0x00,0x12,0x25,0x4a, -0x80,0x19,0x90,0xfd,0x41,0xe0,0x70,0x0e,0x90,0xff,0xf0,0xe0,0x54,0xef,0xf0,0x7c, -0x00,0x12,0x25,0x4a,0x80,0x05,0x7c,0x17,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x90, -0xff,0xf0,0xe0,0x54,0xab,0xf0,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0x22,0x8c,0x37, -0x8d,0x36,0x78,0x7c,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90, -0x00,0x05,0x12,0x01,0xec,0x78,0x7a,0xf6,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed, -0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x7a, -0x12,0x17,0x9d,0x78,0x7a,0xe6,0x70,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12, -0x03,0x0f,0x7c,0x08,0x22,0x90,0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0, -0x54,0xfd,0xf0,0x80,0x1e,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd, -0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x25,0xe0,0x44,0x01,0x90,0xff,0xf3,0xf0, -0x02,0x06,0xdb,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01, -0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90,0xff,0xf3,0xf0,0x80,0x2b,0x78,0x7c, -0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02, -0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,0x0d,0xad,0x3a,0xae,0x39, -0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c,0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc, -0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,0xf1,0xf0, -0x12,0x08,0xca,0x40,0x0d,0xad,0x3a,0xae,0x39,0xaf,0x38,0xe4,0x12,0x03,0x0f,0x7c, -0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90, -0x00,0x06,0x12,0x02,0x0e,0x44,0x01,0x90,0xff,0xf3,0xf0,0x78,0x7d,0xe6,0x24,0x03, -0xf6,0x18,0xe6,0x34,0x00,0xf6,0x78,0x7a,0xe6,0x24,0xfe,0x50,0x09,0x90,0xff,0xf0, -0xe0,0x54,0xfd,0xf0,0x80,0x07,0x90,0xff,0xf0,0xe0,0x44,0x02,0xf0,0xe4,0x90,0xff, -0xf1,0xf0,0x78,0x7b,0x76,0x00,0x78,0x7a,0xe6,0x24,0xff,0xfc,0xe4,0x34,0xff,0xfd, -0x78,0x7b,0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,0x64,0x80,0x9d, -0x40,0x2f,0x12,0x08,0xaf,0x40,0x0f,0x78,0x7b,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38, -0x12,0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,0x7c,0x86,0x83,0x08, -0x86,0x82,0xec,0xf0,0x78,0x7b,0x06,0xa3,0x78,0x7c,0xa6,0x83,0x08,0xa6,0x82,0x80, -0xb5,0x12,0x08,0xaf,0x40,0x0f,0x78,0x7b,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,0x12, -0x03,0x0f,0x7c,0x18,0x22,0x90,0xff,0xf2,0xe0,0xfc,0x78,0x7c,0x86,0x83,0x08,0x86, -0x82,0xec,0xf0,0x78,0x7a,0xe6,0xad,0x3a,0xae,0x39,0xaf,0x38,0x12,0x03,0x0f,0x7c, -0x00,0x22,0x8c,0x37,0x8d,0x36,0x78,0x7c,0xed,0xf6,0x08,0xec,0xf6,0xed,0xfe,0xec, -0xfd,0x7f,0x01,0x90,0x00,0x05,0x12,0x01,0xec,0x78,0x7b,0xf6,0x78,0x7c,0xe6,0xfd, -0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x04,0x12,0x01,0xec,0x54, -0x0f,0xfc,0x7d,0x7b,0x12,0x17,0x9d,0x78,0x7b,0xe6,0x70,0x03,0x7c,0x08,0x22,0x90, -0xff,0xf0,0xe0,0x54,0xfe,0xf0,0x90,0xff,0xf0,0xe0,0x54,0xfd,0xf0,0x80,0x1b,0x78, -0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x08,0x12, -0x02,0x0e,0x25,0xe0,0x90,0xff,0xf3,0xf0,0x80,0x5b,0x78,0x7c,0xe6,0xfd,0x08,0xe6, -0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x90,0x00,0x06,0x12,0x02,0x0e,0x54,0xfe,0x90, -0xff,0xf3,0xf0,0x80,0x21,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec,0xfd, -0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xeb,0x90,0xff,0xf1,0xf0,0x12,0x08, -0xca,0x40,0x03,0x7c,0x18,0x22,0x78,0x7c,0xe6,0xfd,0x08,0xe6,0xfc,0xed,0xfe,0xec, -0xfd,0x7f,0x01,0x90,0x00,0x08,0x12,0x02,0x0e,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca, -0x40,0x03,0x7c,0x18,0x22,0x78,0x7d,0xe6,0x24,0x0a,0xf6,0x18,0xe6,0x34,0x00,0xf6, -0x78,0x7a,0x76,0x00,0x78,0x7b,0xe6,0x24,0xff,0xfc,0xe4,0x34,0xff,0xfd,0x78,0x7a, -0xe6,0x7f,0x00,0xfe,0xec,0xd3,0x9e,0xef,0x64,0x80,0xcd,0x64,0x80,0x9d,0x40,0x21, -0x78,0x7c,0x86,0x83,0x08,0x86,0x82,0xe0,0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40, -0x03,0x7c,0x18,0x22,0x78,0x7a,0x06,0x78,0x7d,0x06,0xe6,0x18,0x70,0x01,0x06,0x80, -0xc3,0x90,0xff,0xf0,0xe0,0x44,0x01,0xf0,0x78,0x7c,0x86,0x83,0x08,0x86,0x82,0xe0, -0x90,0xff,0xf1,0xf0,0x12,0x08,0xca,0x40,0x03,0x7c,0x18,0x22,0x7c,0x00,0x22,0x90, -0xff,0xf0,0xe0,0x20,0xe7,0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0, -0xe0,0x44,0x20,0xf0,0xc3,0x22,0x80,0xe7,0xd3,0x22,0x90,0xff,0xf0,0xe0,0x20,0xe3, -0x12,0x90,0xff,0xf0,0xe0,0x30,0xe5,0x09,0x90,0xff,0xf0,0xe0,0x44,0x20,0xf0,0xc3, -0x22,0x80,0xe7,0xd3,0x22,0x8c,0x42,0x8d,0x41,0x7c,0x00,0xed,0x54,0xf0,0xfd,0xec, -0x70,0x03,0xed,0x64,0x30,0x70,0x05,0x75,0x3e,0x03,0x80,0x03,0x75,0x3e,0x04,0xac, -0x3e,0x12,0x0f,0x7c,0x75,0x83,0x00,0x85,0x83,0x40,0xe5,0x41,0x54,0x0f,0xf5,0x3f, -0xe5,0x40,0x70,0x04,0xe5,0x3f,0x64,0x03,0x70,0x35,0xe5,0x3e,0x24,0xfd,0x75,0xf0, -0x0a,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0x30,0xe6,0x05,0x12, -0x10,0x67,0x80,0x19,0xe5,0x3e,0x24,0x97,0xf8,0xc6,0x54,0xfb,0xf6,0x78,0xa3,0xe6, -0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x80,0x59,0xe5, -0x40,0x70,0x04,0xe5,0x3f,0x64,0x04,0x70,0x48,0xe5,0x3e,0x24,0xfd,0x75,0xf0,0x0a, -0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0x30,0xe5,0x07,0xac,0x42, -0xad,0x41,0x12,0x1c,0x93,0xe5,0x42,0x30,0xe2,0x15,0x78,0xa7,0xe6,0x30,0xe0,0x0f, -0x78,0xa7,0xe6,0x30,0xe1,0x09,0xe4,0xff,0x04,0xfe,0x7c,0x04,0x12,0x31,0x9a,0x78, -0xa3,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x80, -0x07,0xe4,0xfc,0x7d,0xee,0x12,0x1c,0x93,0xc2,0x03,0x22,0x12,0x30,0x85,0x12,0x0f, -0x7c,0x78,0xa3,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90, -0xfd,0x40,0xf0,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xe0,0x90,0xfd,0x41,0xf0,0xc2,0x03,0x7d,0x02,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31, -0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe1, -0x07,0x7c,0x13,0x12,0x25,0x4a,0x80,0x0f,0x90,0xfd,0x41,0xe0,0xfd,0x78,0x8f,0xe6, -0xfc,0x12,0x13,0xfd,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f, -0xec,0xf6,0x7d,0x00,0x12,0x0f,0x0b,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30, -0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe2,0x07,0x7c,0x13,0x12, -0x25,0x4a,0x80,0x1b,0x78,0x8f,0xe6,0x24,0x97,0xf8,0xe6,0x20,0xe1,0x07,0x7c,0x12, -0x12,0x25,0x4a,0x80,0x0a,0x78,0x8f,0xe6,0xfc,0x12,0x14,0x21,0x12,0x25,0x4a,0x12, -0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x20, -0xe2,0x07,0x7c,0x11,0x12,0x25,0x4a,0x80,0x0a,0x78,0x8f,0xe6,0xfc,0x12,0x15,0x22, -0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0x12,0x0f, -0x7c,0x78,0xa3,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x90, -0xfd,0x47,0xf0,0x78,0xa3,0xe6,0x24,0x0a,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xe0,0x90,0xfd,0x48,0xf0,0x78,0xa3,0xe6,0x24,0x03,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0xf5,0x5c,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0xf5,0x5d,0x8c,0x5b,0xe4,0xec,0x33,0x33,0x54,0x01,0x78,0x8f,0xf6,0x60, -0x08,0xe5,0x5c,0x30,0xe1,0x03,0x78,0x8f,0x06,0x78,0x8f,0xe6,0x90,0xfd,0x49,0xf0, -0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfd,0xa3, -0xe0,0x54,0x0c,0xfc,0xed,0x54,0xe6,0x8c,0x5f,0xf5,0x5e,0xe5,0x5b,0x30,0xe5,0x03, -0x43,0x5f,0x01,0xe5,0x5c,0x20,0xe5,0x0e,0xe5,0x5b,0x54,0x7f,0x70,0x08,0xe5,0x5b, -0x20,0xe7,0x03,0x43,0x5f,0x02,0xe5,0x5b,0x30,0xe3,0x03,0x43,0x5f,0x10,0xe5,0x5b, -0x30,0xe2,0x03,0x43,0x5f,0x20,0xe5,0x5b,0x54,0x03,0x60,0x03,0x43,0x5f,0x40,0xe5, -0x5b,0x30,0xe1,0x03,0x43,0x5f,0x80,0xe5,0x5b,0x30,0xe4,0x03,0x43,0x5e,0x01,0xe5, -0x5b,0x30,0xe6,0x03,0x43,0x5e,0x08,0xe5,0x5c,0x20,0xe4,0x0e,0xe5,0x5b,0x54,0x7f, -0x70,0x08,0xe5,0x5b,0x20,0xe7,0x03,0x43,0x5e,0x10,0x53,0x5f,0xfb,0x53,0x5e,0xf9, -0xad,0x5e,0xe5,0x5f,0x90,0xfd,0x42,0xcd,0xf0,0xa3,0xcd,0xf0,0xe5,0x5d,0x30,0xe3, -0x0d,0xe5,0x5d,0x54,0x30,0xc4,0x54,0x0f,0x90,0xfd,0x45,0xf0,0x80,0x05,0xe4,0x90, -0xfd,0x45,0xf0,0xe5,0x5d,0x54,0x03,0x90,0xfd,0x44,0xf0,0xe5,0x5d,0x54,0x04,0xc3, -0x13,0x90,0xfd,0x46,0xf0,0x90,0xfd,0x44,0xe0,0x70,0x0e,0x7d,0x3d,0x7e,0xfd,0x7f, -0x01,0x74,0x01,0x90,0x00,0x09,0x12,0x01,0x42,0x78,0xa3,0xe6,0x24,0x08,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7c,0x00,0xfd,0x78,0xa3,0xe6,0x24,0x07,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x7f,0x00,0x4c,0xfe,0xef,0x4d,0x90,0xfd, -0x40,0xf0,0xa3,0xce,0xf0,0xce,0xc2,0x03,0x7d,0x0a,0x7c,0x00,0x12,0x24,0xb1,0x12, -0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0x78,0x94,0x76,0x01,0x08,0x76, -0xfd,0x08,0x76,0x40,0x78,0x91,0x76,0x0c,0x78,0x94,0x12,0x04,0x65,0x12,0x02,0x14, -0x78,0x92,0xcb,0xf6,0xcb,0x08,0xf6,0x7f,0x00,0xef,0x24,0xeb,0x40,0x1f,0xe4,0xef, -0x25,0xe0,0x90,0x34,0xbf,0xfd,0x93,0xcd,0x04,0x93,0x78,0x93,0x66,0x70,0x03,0xed, -0x18,0x66,0x70,0x06,0x78,0x91,0x76,0x00,0x80,0x03,0x0f,0x80,0xdc,0x78,0x90,0xef, -0xf6,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x02,0x12,0x02,0x0e,0x78,0x92,0xcb,0xf6, -0xcb,0x08,0xf6,0x54,0x04,0xcb,0x54,0x06,0x4b,0x60,0x04,0x78,0x91,0x76,0x0b,0x78, -0x93,0xe6,0x30,0xe3,0x13,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x05,0x12,0x01,0xec, -0x24,0xfb,0x50,0x04,0x78,0x91,0x76,0x0d,0x78,0x93,0xe6,0x54,0xc0,0x7d,0x00,0x64, -0xc0,0x4d,0x70,0x04,0x78,0x91,0x76,0x0b,0x78,0x94,0x12,0x04,0x65,0x90,0x00,0x04, -0x12,0x01,0xec,0x24,0xfc,0x50,0x04,0x78,0x91,0x76,0x0f,0x78,0x94,0x12,0x04,0x65, -0x90,0x00,0x06,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,0x91,0x76,0x0e,0x78,0x94, -0x12,0x04,0x65,0x90,0x00,0x09,0x12,0x01,0xec,0x24,0xfd,0x50,0x04,0x78,0x91,0x76, -0x0a,0x78,0x91,0xe6,0x70,0x2a,0x78,0x8f,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0x94,0x12, -0x04,0x65,0x78,0xa1,0xe6,0xf9,0x78,0xa0,0xe6,0xfa,0x7b,0x01,0x74,0x0a,0x78,0x00, -0x12,0x03,0x3f,0xc2,0x03,0x78,0x8f,0xe6,0xfc,0x12,0x11,0x23,0x78,0x91,0xec,0xf6, -0x78,0x91,0xe6,0xfc,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x78,0x8f, -0xec,0xf6,0x12,0x0f,0x7c,0x78,0x8f,0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c, -0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xac,0x82,0xad,0x83,0x78,0xa0,0x86,0x83,0x08, -0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0xc2,0x03,0x78, -0x8f,0xe6,0xfc,0x12,0x11,0x23,0x12,0x31,0x08,0x22,0x8d,0x2b,0x8c,0x2a,0xed,0x60, -0x40,0x75,0x27,0x01,0x75,0x29,0x48,0x75,0x28,0xff,0xe5,0x2a,0x24,0xfd,0xfc,0xe4, -0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x29, -0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae,0x28,0xaf,0x27,0x74,0x80, -0x90,0x00,0x06,0x12,0x03,0x17,0x74,0x80,0x90,0x00,0x02,0x12,0x03,0x17,0x12,0x0f, -0xd3,0xe5,0x2b,0x14,0x60,0x3b,0x75,0x27,0x01,0x75,0x29,0x08,0x75,0x28,0xff,0xe5, -0x2a,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd,0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd, -0xdc,0xf9,0xfc,0xe5,0x29,0x2c,0xf5,0x29,0xe5,0x28,0x3d,0xf5,0x28,0xad,0x29,0xae, -0x28,0xaf,0x27,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0xe4,0x90,0x00,0x02,0x12,0x03, -0x17,0x22,0x12,0x30,0x85,0x78,0x8f,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe2, -0x09,0x78,0x8f,0xe6,0xfc,0x12,0x15,0x22,0xd2,0x00,0x78,0x8f,0xe6,0xfc,0x12,0x0f, -0x7c,0x78,0x90,0x76,0x00,0x90,0xfd,0x41,0xe0,0x30,0xe7,0x04,0x78,0x90,0x76,0x01, -0x78,0x90,0xe6,0xfd,0x78,0x8f,0xe6,0xfc,0x12,0x0d,0x3a,0xc2,0x03,0x30,0x00,0x07, -0x78,0x8f,0xe6,0xfc,0x12,0x14,0x21,0x7c,0x00,0x12,0x25,0x4a,0x12,0x31,0x08,0x22, -0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x01, -0xf0,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30, -0xe0,0x02,0x80,0xed,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0x54,0xf8,0xf0,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0xc2,0x03,0x8c,0x58,0x12,0x0f,0x7c,0x78,0xa0, -0x86,0x83,0x08,0x86,0x82,0x79,0xee,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5, -0x12,0x0e,0x10,0xac,0x58,0x7d,0x02,0x12,0x0d,0x3a,0xc2,0x03,0xac,0x58,0x12,0x11, -0x23,0x22,0x8d,0x53,0x8e,0x52,0x8f,0x51,0x8c,0x50,0x12,0x0f,0x7c,0x75,0x4f,0x00, -0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x20,0xe4, -0x16,0xe5,0x4f,0x24,0xf6,0x40,0x10,0x05,0x4f,0xc2,0x03,0x7c,0x18,0x12,0x32,0x48, -0xac,0x50,0x12,0x0f,0x7c,0x80,0xd9,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x20,0xe4,0x05,0xc2,0x03,0x7c,0x02,0x22,0x78,0xa3,0xe6, -0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0x60,0x16,0x78, -0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0x0f,0xf0, -0xc2,0x03,0x7c,0x01,0x22,0x78,0xa2,0x86,0x83,0x08,0x86,0x82,0xe0,0xad,0x53,0xae, -0x52,0xaf,0x51,0x12,0x03,0x0f,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x31,0x8c,0x30,0x12, -0x15,0x22,0xe5,0x31,0x60,0x20,0xe5,0x30,0xb4,0x03,0x0c,0x7c,0x01,0x12,0x24,0x7c, -0x7c,0x81,0x12,0x24,0x7c,0x80,0x0f,0xe5,0x30,0xb4,0x04,0x0a,0x7c,0x02,0x12,0x24, -0x7c,0x7c,0x82,0x12,0x24,0x7c,0xac,0x30,0x12,0x0f,0x7c,0xe5,0x31,0x60,0x1a,0x78, -0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54,0xe7,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54, -0xe7,0xf0,0xac,0x30,0x7d,0x02,0x12,0x0d,0x3a,0x78,0xa0,0x86,0x83,0x08,0x86,0x82, -0x79,0xf8,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0xc2,0x03,0xe5,0x30,0x24, -0x97,0xf8,0xc6,0x54,0xfd,0xf6,0xac,0x30,0x12,0x11,0x23,0x22,0x8c,0x26,0x30,0x03, -0x05,0x12,0x31,0xe7,0x80,0xf8,0x7c,0x0a,0x12,0x30,0xfa,0xd2,0x03,0xe5,0x26,0x24, -0xfd,0x78,0x9d,0xf6,0x70,0x09,0x78,0xa4,0x76,0xff,0x08,0x76,0xe0,0x80,0x07,0x78, -0xa4,0x76,0xff,0x08,0x76,0xe2,0x78,0x9d,0xe6,0x75,0xf0,0x10,0xa4,0xad,0xf0,0xfc, -0x24,0xa0,0x78,0xa3,0xf6,0xed,0x34,0xff,0x18,0xf6,0x78,0x9d,0xe6,0x75,0xf0,0x0a, -0xa4,0x24,0x08,0xfc,0xe4,0x34,0xfd,0xfd,0x78,0xa0,0xed,0xf6,0x08,0xec,0xf6,0x12, -0x31,0x93,0x22,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xe0,0x30,0xe7,0x22,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0x54,0x7f,0xf0,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x44,0x80,0xf0,0x22,0x78,0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54, -0x7f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,0x82,0xf5,0x83,0xe0, -0x54,0x7f,0xf0,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xe0,0x54,0xf8,0xf0,0x78,0xa5,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0x44,0x03,0xf0,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x44,0x03,0xf0,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0x74,0x0f,0xf0,0x22,0x78,0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x54, -0x3f,0xf0,0xad,0x83,0xe5,0x82,0x24,0x04,0xfc,0xe4,0x3d,0x8c,0x82,0xf5,0x83,0xe0, -0x54,0x3f,0xf0,0x78,0x9d,0xe6,0x24,0x9e,0xf8,0xe6,0xfc,0x78,0xa5,0xe6,0x24,0x01, -0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0x9d,0xe6,0x24,0x9e,0xf8, -0xe6,0xfc,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec, -0xf0,0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54, -0xfb,0x44,0x02,0xf5,0x26,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x30,0xe5,0x03,0x43,0x26,0x01,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe0,0x03,0x12,0x0f,0xd3,0xe5,0x26,0xfc, -0x78,0xa3,0xe6,0x24,0x0b,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78, -0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0x74,0x0f,0xf0,0x78, -0xa4,0x86,0x83,0x08,0x86,0x82,0xe0,0x44,0x80,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x44, -0x80,0xf0,0x22,0x8c,0x2a,0x12,0x0f,0x7c,0x78,0xa1,0xe6,0x24,0x08,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x0a,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa1,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0xfc,0x78,0xa3,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xec,0xf0,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,0xe0,0xfd,0xa3,0xe0,0xfc, -0xed,0xfe,0x78,0xa3,0xe6,0x24,0x08,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xee, -0xf0,0xec,0xfe,0x78,0xa3,0xe6,0x24,0x07,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xee,0xf0,0x8c,0x29,0x8d,0x28,0xc3,0xec,0x94,0x02,0xed,0x94,0x06,0x40,0x05,0x75, -0x27,0x7c,0x80,0x33,0xd3,0xe5,0x29,0x94,0x81,0xe5,0x28,0x94,0x01,0x40,0x05,0x75, -0x27,0x3c,0x80,0x23,0xd3,0xe5,0x29,0x94,0xc0,0xe5,0x28,0x94,0x00,0x40,0x05,0x75, -0x27,0x18,0x80,0x13,0xd3,0xe5,0x29,0x94,0x30,0xe5,0x28,0x94,0x00,0x40,0x05,0x75, -0x27,0x0c,0x80,0x03,0x75,0x27,0x08,0xaf,0x27,0xe4,0xef,0x54,0x7c,0x44,0x83,0xff, -0x8f,0x27,0xe5,0x27,0xfc,0x78,0xa5,0xe6,0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x27,0xfc,0x78,0x9d,0xe6,0x24,0x9e,0xf8,0xec, -0xf6,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5, -0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0, -0x30,0xe3,0x17,0x53,0x27,0xc7,0x78,0xa1,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x90,0x34,0xe9,0x93,0x42,0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe7,0x05,0x43,0x27,0x40,0x80,0x03, -0x53,0x27,0xbf,0x53,0x27,0xfb,0x78,0xa1,0xe6,0x24,0x06,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x60,0x03,0x43,0x27,0x04,0x53,0x27,0xfc,0x78,0xa1,0xe6,0x24, -0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x42,0x27,0x43,0x27,0x80,0xe5, -0x27,0xfc,0x78,0xa3,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec, -0xf0,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5, -0x27,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0, -0x30,0xe1,0x05,0x53,0x27,0xdf,0x80,0x03,0x43,0x27,0x20,0x78,0xa1,0xe6,0x24,0x02, -0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x05,0x53,0x27,0xef,0x80, -0x03,0x43,0x27,0x10,0x78,0xa1,0xe6,0x24,0x09,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0xb4,0x02,0x03,0x43,0x27,0x02,0xe5,0x27,0xfc,0x78,0xa3,0xe6,0x24,0x04, -0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x78,0xa3,0xe6,0x24,0x03,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xf5,0x27,0x78,0xa1,0xe6,0x24,0x09,0xf5, -0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x70,0x05,0x53,0x27,0x7f,0x80,0x03,0x43, -0x27,0x80,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3, -0xe0,0x30,0xe0,0x05,0x43,0x27,0x20,0x80,0x03,0x53,0x27,0xdf,0x78,0xa1,0xe6,0x24, -0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x30,0xe3,0x05,0x43,0x27,0x40, -0x80,0x03,0x53,0x27,0xbf,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x30,0xe0,0x05,0x43,0x27,0x10,0x80,0x03,0x53,0x27,0xef,0x78,0xa1, -0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe4,0x05, -0x43,0x27,0x08,0x80,0x03,0x53,0x27,0xf7,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe5,0x05,0x43,0x27,0x04,0x80,0x03,0x53, -0x27,0xfb,0x78,0xa1,0xe6,0x24,0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3, -0xe0,0x30,0xe6,0x05,0x43,0x27,0x01,0x80,0x03,0x53,0x27,0xfe,0x78,0xa1,0xe6,0x24, -0x02,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xa3,0xe0,0x30,0xe7,0x05,0x43,0x27, -0x02,0x80,0x03,0x53,0x27,0xfd,0xe5,0x27,0xfc,0x78,0xa3,0xe6,0x24,0x03,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xc2,0x03,0x7c,0x00,0x22,0x8d,0x27,0x8c, -0x26,0xed,0x54,0x03,0x14,0x60,0x03,0x7c,0x10,0x22,0xe5,0x27,0x54,0x7c,0x24,0xfc, -0x40,0x03,0x7c,0x0b,0x22,0xe5,0x26,0x24,0x97,0xf8,0xc6,0x44,0x02,0xf6,0x7c,0x00, -0x22,0x8c,0x30,0x12,0x0f,0x7c,0xe5,0x30,0x24,0x97,0xf8,0xe6,0x20,0xe2,0x4f,0xac, -0x30,0x7d,0x02,0x12,0x0d,0x3a,0xe5,0x30,0x24,0xfe,0x44,0x28,0xfc,0x78,0xa4,0x86, -0x83,0x08,0x86,0x82,0xec,0xf0,0xaf,0x83,0xe5,0x82,0x24,0x04,0xfe,0xe4,0x3f,0xff, -0xec,0x8e,0x82,0x8f,0x83,0xf0,0x7c,0x03,0x8c,0x2c,0xe5,0x2c,0xfc,0x78,0xa5,0xe6, -0x24,0x01,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0xe5,0x2c,0xfc,0x78, -0xa5,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xec,0xf0,0x75,0x2d, -0x01,0x75,0x2f,0x48,0x75,0x2e,0xff,0xe5,0x30,0x24,0xfd,0xfc,0xe4,0x34,0xff,0xfd, -0xec,0x7c,0x03,0x25,0xe0,0xcd,0x33,0xcd,0xdc,0xf9,0xfc,0xe5,0x2f,0x2c,0xf5,0x2f, -0xe5,0x2e,0x3d,0xf5,0x2e,0x78,0xa5,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x54,0xe7,0xf5,0x2c,0xad,0x2f,0xae,0x2e,0xaf,0x2d,0xe4,0x90,0x00, -0x02,0x12,0x03,0x17,0xe4,0x90,0x00,0x06,0x12,0x03,0x17,0x12,0x01,0xe6,0x30,0xe5, -0x03,0x43,0x2c,0x10,0xe5,0x2c,0xfc,0x78,0xa5,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xec,0xf0,0x12,0x10,0x67,0x78,0xa3,0xe6,0x24,0x06,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0xc2,0x03,0xfc,0xe5,0x30,0x24,0x97,0xf8,0xc6, -0x44,0x04,0xf6,0x8c,0x2c,0xe5,0x30,0x54,0x0f,0xc4,0x54,0xf0,0x7e,0x00,0xff,0xee, -0xef,0x44,0x04,0x7d,0x00,0xff,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0x12,0x1c,0xfe,0x7c, -0x00,0x22,0x8c,0x2f,0x12,0x0f,0x7c,0x12,0x10,0x07,0x78,0xa4,0x86,0x83,0x08,0x86, -0x82,0xe0,0x54,0x08,0xf0,0xa3,0xa3,0xa3,0xa3,0xe0,0x54,0x08,0xf0,0xac,0x2f,0x7d, -0x02,0x12,0x0d,0x3a,0xc2,0x03,0xe5,0x2f,0x24,0x97,0xf8,0xc6,0x54,0xfb,0xf6,0x7c, -0x00,0x22,0x12,0x30,0x85,0x78,0x90,0xec,0xf6,0xec,0x24,0x97,0xf8,0xe6,0x30,0xe1, -0x0a,0x7d,0x00,0x7c,0x13,0x12,0x24,0xb1,0x12,0x31,0x08,0x78,0x90,0xe6,0x24,0x97, -0xf8,0xc6,0x44,0x01,0xf6,0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0x90,0xe6,0x24, -0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,0xa0, -0xe6,0xfa,0x08,0xe6,0xf9,0x7b,0x0a,0x78,0x01,0x12,0x03,0xa7,0x78,0xa0,0x86,0x83, -0x08,0x86,0x82,0x79,0xf8,0x7a,0x34,0x7b,0x0a,0x78,0x01,0x12,0x03,0xf5,0x12,0x0f, -0xd3,0xc2,0x03,0x78,0x90,0xe6,0xfc,0x12,0x11,0x23,0x78,0x8f,0xec,0xf6,0xec,0x60, -0x0a,0x7d,0x00,0x7c,0x08,0x12,0x24,0xb1,0x12,0x31,0x08,0x78,0x90,0xe6,0xfc,0x12, -0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0, -0x44,0x10,0x54,0xdf,0xfc,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xec,0xf0,0x78,0x8f,0xec,0xf6,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78, -0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34, -0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,0x90, -0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00, -0xf5,0x83,0xe0,0x44,0x10,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32,0x48,0x78,0x90,0xe6, -0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5, -0x83,0xe0,0x44,0x20,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0x48,0x78,0x90,0xe6,0xfc, -0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83, -0xe0,0x30,0xe4,0x15,0xc2,0x03,0x78,0x90,0xe6,0x44,0x10,0x7f,0x00,0xfe,0x7c,0x07, -0x12,0x31,0x9a,0x12,0x31,0x08,0x02,0x17,0x49,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82, -0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xcf,0xf0,0xc2,0x03,0x7c,0xc8,0x12,0x32, -0x48,0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x04,0xf5,0x82,0x18, -0xe6,0x34,0x00,0xf5,0x83,0xe0,0x44,0x30,0xf0,0xc2,0x03,0x7c,0xf0,0x12,0x32,0x48, -0x78,0x90,0xe6,0xfc,0x12,0x0f,0x7c,0x78,0xa3,0xe6,0x24,0x05,0xf5,0x82,0x18,0xe6, -0x34,0x00,0xf5,0x83,0xe0,0x30,0xe4,0x14,0xc2,0x03,0x78,0x90,0xe6,0x44,0x10,0x7f, -0x00,0xfe,0x7c,0x07,0x12,0x31,0x9a,0x12,0x31,0x08,0x80,0x5d,0x78,0xa3,0xe6,0x24, -0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x78,0xa3,0xe6, -0x24,0x04,0xf5,0x82,0x18,0xe6,0x34,0x00,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x78,0x90, -0xe6,0x24,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x1c,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83, -0xac,0x82,0xad,0x83,0x78,0xa0,0x86,0x83,0x08,0x86,0x82,0xec,0xf9,0xed,0xfa,0x7b, -0x0a,0x78,0x01,0x12,0x03,0xa7,0xc2,0x03,0x78,0x90,0xe6,0xfc,0x12,0x11,0x23,0x7d, -0x00,0x7c,0x0b,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90,0xff,0x91, -0xe0,0x90,0xfd,0x41,0xf0,0x7d,0x02,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22, -0x12,0x30,0x85,0x90,0xfd,0x40,0xe0,0xf4,0xfc,0x90,0xff,0x91,0xe0,0x5c,0xf5,0x33, -0x90,0xfd,0x41,0xe0,0xfc,0x90,0xfd,0x40,0xe0,0x5c,0x42,0x33,0xe5,0x33,0x90,0xff, -0x91,0xf0,0x7c,0x00,0x12,0x25,0x4a,0x12,0x31,0x08,0x22,0x74,0x3c,0x90,0xfb,0xe8, -0xf0,0x74,0x3e,0x90,0xfb,0xe8,0xf0,0xe4,0x90,0xfd,0x30,0xf0,0x22,0x8d,0x35,0x8c, -0x34,0xec,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x02,0x80,0x28,0xb4,0x02,0x02,0x80, -0x03,0xd3,0x40,0x08,0xa8,0x35,0xc6,0x25,0xe0,0xf6,0x80,0x18,0xb4,0x04,0x02,0x80, -0x03,0xd3,0x40,0x0a,0xa8,0x35,0xc6,0x25,0xe0,0x25,0xe0,0xf6,0x80,0x06,0xa8,0x35, -0x76,0x00,0x80,0x00,0x22,0x8c,0x3c,0x8d,0x3b,0xed,0xfe,0xec,0xfd,0x7f,0x01,0x75, -0x60,0x06,0x75,0x61,0x00,0x90,0xfd,0x31,0x12,0x04,0x6e,0x12,0x01,0xe6,0xb4,0x80, -0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x18,0x9e,0x90,0xfd,0x31,0x12,0x04,0x80,0x90, -0x00,0x03,0x12,0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x5f,0x90, -0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f, -0x01,0x90,0xfd,0x34,0x12,0x04,0x6e,0xee,0xcd,0x90,0x35,0x02,0xfc,0xe4,0x93,0xff, -0x74,0x01,0x93,0xfe,0xf9,0xef,0xfa,0x7b,0x01,0xea,0xff,0xe9,0xfe,0xec,0xc3,0x9e, -0xed,0x9f,0x40,0x25,0x90,0x35,0x04,0xe4,0x93,0xfd,0x74,0x01,0x93,0xfc,0xed,0xfe, -0xec,0xfd,0x7f,0x01,0xee,0xcd,0xfc,0x90,0xfd,0x36,0xe0,0xd3,0x9c,0x90,0xfd,0x35, -0xe0,0x9d,0x50,0x05,0x75,0x60,0x80,0x80,0x33,0x12,0x19,0xbc,0x80,0x2e,0xb4,0x60, -0x02,0x80,0x03,0xd3,0x40,0x0b,0xac,0x3c,0xad,0x3b,0x12,0x07,0x82,0x8c,0x60,0x80, -0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40,0x09,0xc3,0xb4, -0x40,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,0x81,0x80,0x00,0x80,0x75,0xb4,0x81, -0x02,0x80,0x03,0xd3,0x40,0x6b,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x03,0x12, -0x01,0xec,0x54,0xf0,0xb4,0x30,0x02,0x80,0x03,0xd3,0x40,0x1d,0x90,0xfd,0x31,0x12, -0x04,0x80,0x90,0x00,0x08,0x12,0x02,0x0e,0xfa,0xfd,0xeb,0xfe,0x7f,0x01,0x90,0xfd, -0x37,0x12,0x04,0x6e,0x12,0x19,0x26,0x80,0x36,0xb4,0x60,0x02,0x80,0x03,0xd3,0x40, -0x13,0x75,0x3a,0x61,0xe4,0xf5,0x39,0xf5,0x38,0xac,0x3c,0xad,0x3b,0x12,0x05,0xde, -0x8c,0x60,0x80,0x1b,0xb4,0x10,0x03,0xb3,0x40,0x10,0xc3,0xb4,0x20,0x03,0xb3,0x40, -0x09,0xc3,0xb4,0x40,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60,0x81,0x80,0x00,0x80, -0x02,0x80,0x00,0xe5,0x60,0xfc,0x90,0xfd,0x31,0x12,0x04,0x80,0xec,0x90,0x00,0x02, -0x12,0x03,0x17,0xac,0x61,0x22,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,0x12, -0x01,0xec,0x60,0x04,0x74,0x01,0x80,0x01,0xe4,0xa2,0xe0,0x92,0x01,0x90,0xfd,0x31, -0x12,0x04,0x80,0xed,0x24,0x03,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x34,0x12,0x04,0x6e, -0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x61,0x90,0x00, -0x04,0x12,0x01,0xec,0x54,0x0f,0xfc,0x7d,0x61,0x12,0x17,0x9d,0xe5,0x61,0x70,0x04, -0x75,0x60,0x08,0x22,0x75,0x60,0x00,0x78,0x7e,0x76,0x00,0x78,0x7e,0xe6,0xc3,0x95, -0x61,0x50,0x38,0x90,0xfd,0x37,0x12,0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfd,0x34, -0x12,0x04,0x80,0xec,0x12,0x03,0x0f,0x30,0x01,0x0e,0x90,0xfd,0x39,0xe0,0x04,0xf0, -0x90,0xfd,0x38,0x70,0x03,0xe0,0x04,0xf0,0x78,0x7e,0x06,0x90,0xfd,0x36,0xe0,0x04, -0xf0,0x90,0xfd,0x35,0x70,0x03,0xe0,0x04,0xf0,0x80,0xc0,0x22,0x90,0xfd,0x32,0xe0, -0xfd,0xa3,0xe0,0xfc,0xed,0xfe,0xec,0xfd,0x7f,0x01,0xed,0x24,0x0a,0xfd,0x50,0x01, -0x0e,0x90,0xfd,0x3a,0x12,0x04,0x6e,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04, -0x12,0x01,0xec,0x54,0x0f,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x17,0x90,0xfd,0x3a, -0x12,0x04,0x80,0x0d,0xed,0x70,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,0x78,0x82, -0x76,0x01,0x80,0x4e,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfd,0x3a,0x12, -0x04,0x80,0xed,0x24,0x02,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e,0x78, -0x82,0x76,0x02,0x80,0x2d,0xb4,0x04,0x02,0x80,0x03,0xd3,0x40,0x19,0x90,0xfd,0x3a, -0x12,0x04,0x80,0xed,0x24,0x04,0xfd,0x50,0x01,0x0e,0x90,0xfd,0x37,0x12,0x04,0x6e, -0x78,0x82,0x76,0x04,0x80,0x0c,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x00,0x75,0x60, -0x08,0x22,0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x05,0x12,0x01,0xec,0xf5,0x61, -0x78,0x7f,0x76,0x00,0x78,0x7f,0xe6,0xc3,0x95,0x61,0x40,0x03,0x02,0x1b,0x24,0x78, -0x80,0x76,0x00,0x78,0x80,0xe6,0xc3,0x78,0x82,0x96,0x50,0x76,0x90,0xfd,0x34,0x12, -0x04,0x80,0x12,0x01,0xe6,0xfc,0x90,0xfd,0x3a,0x12,0x04,0x89,0x12,0x01,0xe0,0xf4, -0x5c,0xfc,0x12,0x01,0xe0,0xf8,0x90,0xfd,0x37,0x12,0x04,0x80,0xe8,0xc0,0xe0,0x12, -0x01,0xe6,0xc8,0xd0,0xe0,0xc8,0x58,0x4c,0xfc,0x90,0xfd,0x34,0x12,0x04,0x80,0xec, -0x12,0x03,0x0f,0x78,0x81,0xec,0xf6,0x90,0xfd,0x39,0xe0,0x04,0xf0,0x90,0xfd,0x38, -0x70,0x03,0xe0,0x04,0xf0,0x09,0xe9,0x70,0x01,0x0a,0x90,0xfd,0x3a,0x12,0x04,0x77, -0x90,0xfd,0x31,0x12,0x04,0x80,0x90,0x00,0x04,0x12,0x01,0xec,0x30,0xe4,0x0e,0x90, -0xfd,0x36,0xe0,0x04,0xf0,0x90,0xfd,0x35,0x70,0x03,0xe0,0x04,0xf0,0x78,0x80,0x06, -0x80,0x81,0x78,0x82,0xe6,0xfd,0xe4,0xfe,0xff,0xee,0xcd,0xfc,0x90,0xfd,0x39,0xe0, -0x2c,0xf0,0x90,0xfd,0x38,0xe0,0x3d,0xf0,0x78,0x82,0xe6,0xfd,0xe4,0xfe,0xff,0xee, -0xcd,0xfc,0x90,0xfd,0x3c,0xe0,0x2c,0xf0,0x90,0xfd,0x3b,0xe0,0x3d,0xf0,0x78,0x7f, -0x06,0x02,0x1a,0x64,0x75,0x60,0x00,0x22,0xe5,0x3d,0x05,0x3d,0x04,0x70,0x02,0xb2, -0xb0,0x22,0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0xe8,0xc0,0xe0,0xe9, -0xc0,0xe0,0xea,0xc0,0xe0,0xeb,0xc0,0xe0,0xec,0xc0,0xe0,0xed,0xc0,0xe0,0xee,0xc0, -0xe0,0xef,0xc0,0xe0,0x90,0xff,0x92,0xe0,0x12,0x01,0xb7,0x1b,0x80,0x30,0x1b,0x80, -0x32,0x1b,0x8f,0x38,0x1b,0xa1,0x3a,0x1b,0xb3,0x3e,0x1b,0xcb,0x44,0x1b,0xbf,0x46, -0x1b,0xd7,0x50,0x1c,0x19,0x52,0x1b,0xf8,0x54,0x1c,0x3a,0x56,0x00,0x00,0x1c,0x5b, -0x90,0xff,0x92,0xe0,0x7f,0x00,0xfe,0x7c,0x01,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4, -0xff,0x04,0xfe,0x7c,0x03,0x12,0x31,0x9a,0x74,0x20,0x90,0xff,0xfe,0xf0,0x02,0x1c, -0x6b,0xe4,0xff,0x04,0xfe,0x7c,0x02,0x12,0x31,0x9a,0x74,0x40,0x90,0xff,0xfe,0xf0, -0x02,0x1c,0x6b,0xe4,0xff,0x04,0xfe,0x7c,0x04,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4, -0xff,0x04,0xfe,0x7c,0x05,0x12,0x31,0x9a,0x02,0x1c,0x6b,0xe4,0xff,0x04,0xfe,0x7c, -0x06,0x12,0x31,0x9a,0x02,0x1c,0x6b,0x90,0xff,0xa5,0xe0,0x7d,0x00,0x90,0xfd,0x00, -0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x01,0xe0,0xfc,0xf5,0x83,0x90,0xfd,0x00,0xe0, -0x44,0x33,0xfd,0x12,0x1c,0xfe,0x80,0x73,0x90,0xff,0xb5,0xe0,0x7d,0x00,0x90,0xfd, -0x02,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x03,0xe0,0xfc,0xf5,0x83,0x90,0xfd,0x02, -0xe0,0x44,0x43,0xfd,0x12,0x1c,0xfe,0x80,0x52,0x90,0xff,0xa6,0xe0,0x7d,0x00,0x90, -0xfd,0x04,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x05,0xe0,0xfc,0xf5,0x83,0x90,0xfd, -0x04,0xe0,0x44,0x34,0xfd,0x12,0x1c,0xfe,0x80,0x31,0x90,0xff,0xb6,0xe0,0x7d,0x00, -0x90,0xfd,0x06,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xfd,0x07,0xe0,0xfc,0xf5,0x83,0x90, -0xfd,0x06,0xe0,0x44,0x44,0xfd,0x12,0x1c,0xfe,0x80,0x10,0x90,0xff,0x92,0xe0,0x7d, -0x00,0xfc,0xed,0x44,0xaa,0xfd,0x12,0x1c,0xfe,0x80,0x00,0xe4,0x90,0xff,0x92,0xf0, -0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xd0,0xe0,0xfc,0xd0,0xe0,0xfb,0xd0, -0xe0,0xfa,0xd0,0xe0,0xf9,0xd0,0xe0,0xf8,0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0, -0xd0,0xe0,0x32,0x05,0x81,0x05,0x81,0x05,0x81,0x05,0x81,0xa8,0x81,0x18,0x18,0x18, -0xed,0xf6,0x08,0xec,0xf6,0x90,0xff,0x6a,0xe0,0x20,0xe7,0x02,0x80,0xf7,0x90,0xff, -0x69,0xe0,0x7d,0x00,0xa8,0x81,0x18,0xcd,0xf6,0xcd,0x08,0xf6,0x7d,0x03,0xa8,0x81, -0xe6,0x18,0xfc,0xe6,0xcc,0x25,0xe0,0xcc,0x33,0xcc,0xdd,0xf9,0xcc,0xf6,0xcc,0x08, -0xf6,0xa8,0x81,0x18,0xe6,0x44,0xf8,0xf6,0xa8,0x81,0x18,0x18,0x18,0xe6,0xfd,0x08, -0xe6,0xfc,0xa8,0x81,0x18,0x86,0x83,0x08,0x86,0x82,0xed,0xf0,0xa3,0xec,0xf0,0x74, -0x02,0x90,0xff,0x6a,0xf0,0x15,0x81,0x15,0x81,0x15,0x81,0x15,0x81,0x22,0xe5,0x81, -0x24,0x05,0xf5,0x81,0xe4,0xa8,0x81,0x18,0xf6,0xa8,0x81,0x18,0x18,0x18,0x18,0xed, -0xf6,0x08,0xec,0xf6,0x90,0xfb,0xfd,0xe0,0x24,0xf8,0x50,0x03,0x02,0x1e,0x1f,0xe4, -0xa8,0x81,0x18,0x18,0xf6,0xa8,0x81,0x18,0xe6,0xfe,0xa8,0x81,0x18,0x18,0x18,0x18, -0xe6,0xfd,0x08,0xe6,0xfc,0x7f,0x00,0xef,0x24,0xf8,0x40,0x4d,0xe4,0xef,0x25,0xe0, -0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x6c,0x70,0x03, -0xfa,0xeb,0x6d,0x70,0x09,0x74,0x01,0xa8,0x81,0x18,0x18,0xf6,0x80,0x2b,0xe4,0xef, -0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x7a,0x00,0xe0,0x54,0xf0, -0xcc,0xf8,0xcc,0xcd,0xf9,0xcd,0xfb,0x78,0x00,0xe9,0x54,0xf0,0xf9,0xea,0x68,0x70, -0x02,0xeb,0x69,0x70,0x01,0x0e,0x0f,0x80,0xae,0xa8,0x81,0x18,0xee,0xf6,0xa8,0x81, -0x18,0x18,0x18,0x18,0xed,0xf6,0x08,0xec,0xf6,0xa8,0x81,0xef,0xf6,0xa8,0x81,0x18, -0x18,0xe6,0x70,0x79,0xa8,0x81,0x18,0xe6,0x24,0xf7,0x40,0x71,0xa8,0x81,0x18,0x18, -0x18,0x18,0xe6,0x54,0x0f,0xa8,0x81,0xf6,0x64,0x04,0x60,0x17,0xa8,0x81,0xe6,0x64, -0x03,0x60,0x10,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x1c, -0x93,0x80,0x4a,0x7c,0x0a,0x12,0x30,0xfa,0xa8,0x81,0x18,0x18,0x18,0x18,0xe6,0xfd, -0x08,0xe6,0xfc,0x90,0xfb,0xfc,0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd, -0xf5,0x83,0xed,0xf0,0xa3,0xec,0xf0,0x90,0xfb,0xfc,0xe0,0xff,0xe4,0xef,0x04,0x54, -0x07,0xff,0x90,0xfb,0xfc,0xf0,0x90,0xfb,0xfd,0xe0,0x04,0xf0,0x12,0x31,0x93,0x90, -0xfb,0xfe,0xe0,0x70,0x08,0xe4,0xfe,0xff,0x7c,0x0f,0x12,0x31,0x9a,0x80,0x27,0x90, -0xfb,0xff,0xe0,0x04,0xf0,0x54,0x3f,0x70,0x1d,0x90,0xfb,0xff,0xe0,0x44,0xfe,0x7d, -0x00,0xfc,0x90,0xfb,0xfc,0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5, -0x83,0xed,0xf0,0xa3,0xec,0xf0,0xe5,0x81,0x24,0xfb,0xf5,0x81,0x22,0x78,0x85,0x76, -0x00,0x78,0x86,0x76,0x00,0x74,0x01,0x90,0xfb,0xfe,0xf0,0x12,0x30,0x85,0x90,0xfb, -0xfd,0xe0,0x60,0x59,0x7c,0x0a,0x12,0x30,0xfa,0x90,0xfb,0xfb,0xe0,0x25,0xe0,0x24, -0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0xfc,0x90,0xfb,0xfb, -0xe0,0x25,0xe0,0x24,0x85,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, -0x90,0xfb,0xfb,0xe0,0xff,0xe4,0xef,0x04,0x54,0x07,0xff,0x90,0xfb,0xfb,0xf0,0x90, -0xfb,0xfd,0xe0,0x14,0xf0,0x78,0x83,0xed,0xf6,0x08,0xec,0xf6,0x12,0x31,0x93,0xb2, -0xb3,0x78,0x83,0xe6,0xfd,0x08,0xe6,0xfc,0x12,0x08,0xe5,0x80,0xa1,0x12,0x31,0xe7, -0x78,0x85,0x06,0xb6,0x00,0x11,0x78,0x85,0x76,0x00,0x78,0x86,0xe6,0xf4,0x04,0x04, -0xa2,0xe0,0x92,0xb4,0x78,0x86,0xf6,0x80,0x85,0xe4,0x90,0xfb,0xfe,0xf0,0x90,0xfb, -0xfd,0xe0,0x7d,0x00,0xfc,0xed,0x44,0xcf,0xfd,0x12,0x1c,0x93,0x12,0x31,0x08,0x22, -0x12,0x30,0x85,0xe5,0x6a,0x64,0x49,0x45,0x69,0x60,0x15,0x90,0xff,0x83,0xe0,0x54, -0x0f,0x7d,0x00,0xd3,0x95,0x6a,0xed,0x95,0x69,0x50,0x05,0x12,0x2e,0xce,0x80,0x03, -0x12,0x2f,0x9e,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0xe5,0x6a,0x64,0x49,0x45,0x69, -0x60,0x05,0x12,0x2f,0xd8,0x80,0x0e,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x90,0xff, -0x83,0xe0,0x54,0x7f,0xf0,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x8c,0x54,0xec,0x54, -0xf0,0xb4,0x10,0x15,0x75,0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0xe5,0x64,0x24, -0x03,0xf5,0x64,0xe5,0x63,0x34,0x00,0xf5,0x63,0xe4,0xf5,0x57,0xf5,0x56,0xe5,0x56, -0xc3,0x94,0x01,0x50,0x27,0xe5,0x54,0x54,0x0f,0xfc,0xad,0x64,0xae,0x63,0xaf,0x62, -0x12,0x0e,0x82,0x8c,0x55,0xec,0x60,0x02,0x80,0x12,0x05,0x64,0xe5,0x64,0x70,0x02, -0x05,0x63,0x05,0x57,0xe5,0x57,0x70,0x02,0x05,0x56,0x80,0xd2,0xe5,0x54,0x54,0x0f, -0x24,0x97,0xf8,0xc6,0x54,0xfe,0xf6,0xe5,0x54,0x54,0x0f,0x7f,0x00,0xfe,0x7c,0x12, -0x12,0x31,0x9a,0xe5,0x55,0x14,0x70,0x09,0x7d,0x00,0x7c,0x09,0x12,0x24,0xb1,0x80, -0x07,0xad,0x57,0x7c,0x00,0x12,0x24,0xb1,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x90, -0xff,0xfc,0xe0,0x44,0x02,0xf0,0x90,0xff,0x00,0xe0,0x30,0xe7,0x13,0x90,0xff,0x83, -0xe0,0x44,0x80,0xf0,0x43,0x67,0x80,0x90,0xff,0xfc,0xe0,0x44,0x01,0xf0,0x80,0x11, -0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x53,0x67,0x7f,0x90,0xff,0xfc,0xe0,0x54,0xfe, -0xf0,0x90,0xff,0x81,0xe0,0x44,0x80,0xf0,0x12,0x25,0x64,0x90,0xff,0xfe,0xe0,0x44, -0x05,0xf0,0x90,0xff,0xfc,0xe0,0x54,0xfd,0xf0,0x12,0x31,0x08,0x22,0x12,0x30,0x85, -0x7c,0x01,0x12,0x32,0x48,0x78,0xa7,0xe6,0x44,0x02,0xf6,0x74,0xfe,0xfc,0x04,0xfd, -0x12,0x1c,0xfe,0x90,0xff,0x6a,0xe0,0x30,0xe7,0x02,0x80,0xf7,0xe4,0xf5,0x4e,0x75, -0x4d,0x10,0xac,0x4e,0xad,0x4d,0xe5,0x4e,0x15,0x4e,0x70,0x02,0x15,0x4d,0xec,0x4d, -0x60,0x02,0x80,0xee,0x43,0x87,0x01,0x12,0x31,0x08,0x22,0x12,0x30,0x85,0x7c,0x02, -0x12,0x31,0x14,0x78,0xa7,0xe6,0x54,0xfd,0xf6,0x12,0x31,0x08,0x22,0x12,0x30,0x85, -0x78,0xa7,0xe6,0x30,0xe0,0x2c,0x78,0xa7,0xe6,0x30,0xe1,0x26,0x78,0xa7,0xe6,0xfc, -0xf5,0x83,0x18,0xe6,0x44,0xf0,0xfd,0x12,0x1c,0x93,0x90,0xff,0xfc,0xe0,0x44,0x20, -0xf0,0x7c,0x02,0x12,0x32,0x48,0x78,0xa7,0xe6,0x54,0xfd,0xf6,0x74,0x1a,0x90,0xff, -0xfe,0xf0,0x78,0xa7,0xe6,0xfc,0xf5,0x83,0x18,0xe6,0x44,0xf1,0xfd,0x12,0x1c,0x93, -0x12,0x31,0x08,0x22,0x75,0x67,0x00,0x75,0x68,0x00,0xe4,0xf5,0x66,0xf5,0x65,0xe4, -0xf5,0x69,0x75,0x6a,0x49,0x74,0x84,0x90,0xff,0x82,0xf0,0x74,0x84,0x90,0xff,0x80, -0xf0,0x74,0x80,0x90,0xff,0x68,0xf0,0x74,0x80,0x90,0xff,0x6a,0xf0,0xad,0x46,0xaf, -0x45,0x7e,0x00,0xee,0x24,0xfc,0x50,0x03,0x02,0x21,0x6a,0xe4,0xee,0x75,0xf0,0x07, -0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54,0x80, -0xfd,0xe4,0xef,0x54,0x0f,0x14,0xff,0xed,0x60,0x38,0xe4,0xef,0x75,0xf0,0x08,0xa4, -0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0, -0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0,0xe4,0xef, -0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0x74,0x80,0xf0, -0x80,0x34,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5, -0x83,0x74,0x90,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82,0xe4, -0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x20,0xd3,0x8d,0x46,0x8e,0x44,0x8f,0x45, -0x74,0x7f,0x90,0xff,0xfd,0xf0,0x74,0x90,0x90,0xff,0xfc,0xf0,0x90,0xfc,0x19,0xe0, -0x30,0xe6,0x07,0x90,0xff,0xfc,0xe0,0x44,0x04,0xf0,0x22,0x90,0xfc,0x0d,0xe0,0x14, -0x70,0x04,0x90,0xfc,0x0c,0xe0,0x70,0x39,0x90,0xfc,0x00,0x79,0x06,0x7a,0x35,0x7b, -0x12,0x78,0x01,0x12,0x03,0xf5,0x7f,0x00,0xef,0x33,0x40,0x15,0xef,0x90,0x35,0x4d, -0x93,0xfc,0xef,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xec,0xf0,0x0f,0x80, -0xe7,0x8f,0x59,0x90,0xfc,0x2b,0x79,0x18,0x7a,0x35,0x7b,0x35,0x78,0x01,0x12,0x03, -0xf5,0xe4,0x90,0xff,0xff,0xf0,0x74,0x51,0x90,0xff,0xfa,0xf0,0x74,0x04,0x90,0xff, -0xfb,0xf0,0x74,0x53,0x90,0xff,0xf8,0xf0,0x74,0x51,0x90,0xff,0xf9,0xf0,0x74,0x55, -0x90,0xff,0xf7,0xf0,0x74,0x93,0x90,0xff,0xf6,0xf0,0x74,0x32,0x90,0xff,0xf5,0xf0, -0x75,0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0xe4,0x90,0xff,0x83,0xf0,0x74,0x80, -0x90,0xff,0x81,0xf0,0x75,0x58,0x04,0xe5,0x58,0x75,0xf0,0x07,0xa4,0x24,0x3f,0xf5, -0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x78,0x89,0xf6,0xfc,0x54,0x0f,0x14,0xfc,0x78, -0x89,0xec,0xf6,0xe5,0x58,0x75,0xf0,0x07,0xa4,0x24,0x41,0xf5,0x82,0xe4,0x34,0xfc, -0xf5,0x83,0xe0,0x78,0x8c,0x76,0xf8,0x08,0x76,0x00,0xfc,0x78,0x89,0xe6,0x75,0xf0, -0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x89,0xe6, -0x75,0xf0,0x08,0xa4,0x24,0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xec,0xf0,0x78, -0x8c,0xe6,0xff,0x08,0xe6,0x7e,0x03,0xcf,0xc3,0x13,0xcf,0x13,0xde,0xf9,0xfe,0x78, -0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xee, -0xf0,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5, -0x83,0x74,0x80,0xf0,0x78,0x8a,0xec,0xf6,0x7d,0x00,0x78,0x8d,0xe6,0x2c,0xf6,0x18, -0xe6,0x3d,0xf6,0x78,0x8c,0xe6,0xfd,0x08,0xe6,0x7c,0x03,0xcd,0xc3,0x13,0xcd,0x13, -0xdc,0xf9,0xfc,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0xec,0xf0,0x78,0x89,0xe6,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82, -0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8c,0xe6,0xfd,0x08,0xe6,0xfc,0x78,0x89, -0xe6,0xff,0x7e,0x00,0xee,0x24,0xfc,0x50,0x03,0x02,0x24,0x6b,0xe4,0xee,0x75,0xf0, -0x07,0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xff,0xe4,0xef,0x54, -0x80,0xfa,0xe4,0xef,0x54,0x0f,0x14,0xff,0xe4,0xee,0x75,0xf0,0x07,0xa4,0x24,0x41, -0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x78,0x8a,0xf6,0xee,0x75,0xf0,0x80,0xa4, -0x24,0x08,0xf8,0xe5,0xf0,0x34,0xf8,0xf9,0xe8,0xfc,0xe9,0xfd,0x8a,0x59,0xea,0x70, -0x03,0x02,0x23,0xd8,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8a,0xe6,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24, -0x4f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb,0xec,0x7a,0x03,0xcb, -0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x49,0xf5, -0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x8a,0xe6,0x7b,0x00,0xfa,0xec,0x2a, -0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa, -0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4d,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea, -0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4a,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83, -0x74,0x80,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x4e,0xf5,0x82,0xe4,0x34,0xff, -0xf5,0x83,0x74,0x80,0xf0,0x02,0x24,0x67,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x08, -0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x78,0x8a,0xe6,0xfa,0xe4,0xef,0x75, -0xf0,0x08,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0xed,0xfb, -0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb,0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08, -0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xea,0xf0,0x78,0x8a,0xe6,0x7b, -0x00,0xfa,0xec,0x2a,0xfc,0xed,0x3b,0xfd,0xfb,0xec,0x7a,0x03,0xcb,0xc3,0x13,0xcb, -0x13,0xda,0xf9,0xfa,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0d,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0xea,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0a,0xf5,0x82,0xe4, -0x34,0xff,0xf5,0x83,0xe4,0xf0,0xe4,0xef,0x75,0xf0,0x08,0xa4,0x24,0x0e,0xf5,0x82, -0xe4,0x34,0xff,0xf5,0x83,0xe4,0xf0,0x0e,0x02,0x22,0xf4,0x8e,0x58,0x78,0x8c,0xed, -0xf6,0x08,0xec,0xf6,0x78,0x89,0xef,0xf6,0x12,0x20,0xa4,0x22,0x8c,0x26,0xec,0x30, -0xe7,0x18,0xe5,0x26,0x54,0x0f,0x14,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4, -0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0,0x80,0x16,0xe5,0x26,0x54,0x0f,0x14,0x75, -0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xdf,0xf0, -0x22,0xec,0x90,0xfd,0x3f,0xf0,0x8c,0x24,0xed,0x24,0x03,0xf5,0x25,0x7d,0x00,0xd3, -0x95,0x6c,0xed,0x95,0x6b,0x40,0x03,0x85,0x6c,0x25,0xe5,0x25,0x24,0xb7,0x50,0x09, -0x75,0x25,0x03,0x74,0x02,0x90,0xfd,0x3f,0xf0,0xac,0x25,0x12,0x2f,0xc3,0x22,0xe4, -0xf5,0x66,0xf5,0x65,0x12,0x24,0xe8,0x22,0x90,0xfd,0x3d,0xe0,0x65,0x6d,0x60,0x0e, -0x74,0x04,0x90,0xfd,0x3f,0xf0,0xe4,0xf5,0x65,0x75,0x66,0x03,0x80,0x46,0x7d,0x6d, -0xe4,0xfe,0xff,0x79,0x3d,0x7a,0xfd,0x7b,0x01,0x74,0x05,0x78,0x00,0x12,0x03,0x3f, -0xe5,0x66,0x24,0x03,0xf5,0x66,0xe5,0x65,0x34,0x00,0xf5,0x65,0xe5,0x66,0xd3,0x95, -0x6c,0xe5,0x65,0x95,0x6b,0x40,0x06,0x85,0x6c,0x66,0x85,0x6b,0x65,0xd3,0xe5,0x66, -0x94,0x48,0xe5,0x65,0x94,0x00,0x40,0x0c,0x74,0x02,0x90,0xfd,0x3f,0xf0,0xe4,0xf5, -0x65,0x75,0x66,0x03,0xac,0x66,0x12,0x2f,0xc3,0x22,0xec,0x90,0xfd,0x3f,0xf0,0xe4, -0xf5,0x66,0xf5,0x65,0x8c,0x32,0xec,0x60,0x05,0x12,0x2f,0xb4,0x80,0x05,0x7c,0x00, -0x12,0x2f,0xc3,0x22,0x90,0xff,0x04,0xe0,0xf5,0x4a,0x90,0xff,0x06,0xe0,0xfd,0xa3, -0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e, -0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc,0xed,0x4f,0xfd,0xc3,0xec,0x94,0x48,0xed,0x94, -0x00,0x50,0x22,0x90,0xff,0x06,0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00, -0xfc,0x90,0xff,0x06,0xe0,0xff,0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xfc, -0xed,0x4f,0xfd,0x80,0x04,0xe4,0xfd,0x7c,0x48,0x8c,0x6c,0x8d,0x6b,0x90,0xff,0x02, -0xe0,0xfd,0xa3,0xe0,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0x90,0xff,0x02,0xe0,0xff, -0xa3,0xe0,0x7e,0x00,0xff,0xe4,0xfe,0xec,0x4e,0xf5,0x4c,0xed,0x4f,0xf5,0x4b,0x75, -0x64,0x3d,0x75,0x63,0xfd,0x75,0x62,0x01,0x7d,0x3d,0x7e,0xfd,0x7f,0x01,0x79,0x6d, -0xe4,0xfa,0xfb,0x74,0x05,0x78,0x00,0x12,0x03,0x3f,0x75,0x49,0x00,0xe5,0x49,0x24, -0xfe,0x40,0x19,0xad,0x64,0xae,0x63,0xaf,0x62,0xe4,0x12,0x03,0x0f,0x05,0x49,0x0d, -0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,0xe1,0x75,0x64,0x3d,0x75, -0x63,0xfd,0x75,0x62,0x01,0x90,0xff,0x00,0xe0,0x54,0x60,0xb4,0x00,0x02,0x80,0x06, -0xd3,0x50,0x03,0x02,0x2c,0x12,0xe5,0x4a,0x54,0x0f,0xf5,0x49,0xe5,0x4a,0x54,0x80, -0xa2,0xe0,0x92,0x02,0x90,0xff,0x01,0xe0,0x12,0x01,0x81,0x00,0x0b,0x2c,0x0d,0x26, -0x67,0x27,0x85,0x2c,0x0d,0x28,0x91,0x2c,0x0d,0x29,0x74,0x29,0xa8,0x2b,0x0f,0x2b, -0x12,0x2b,0x52,0x2b,0xb6,0x2b,0xe4,0xe5,0x67,0x30,0xe7,0x0e,0xe5,0x4c,0x45,0x4b, -0x70,0x08,0xe5,0x6c,0x64,0x02,0x45,0x6b,0x60,0x03,0x02,0x2c,0x0f,0x90,0xff,0x00, -0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5,0x4a,0x60,0x03,0x02, -0x27,0x82,0xad,0x64,0xae,0x63,0xaf,0x62,0x74,0x01,0x12,0x03,0x0f,0x78,0xa7,0xe6, -0x30,0xe0,0x0b,0xad,0x64,0xae,0x63,0xaf,0x62,0x74,0x02,0x12,0x03,0x0f,0x7c,0x02, -0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x1b,0xe5,0x67,0x20,0xe1, -0x07,0xe5,0x4a,0x60,0x03,0x02,0x27,0x82,0xe5,0x4a,0x24,0xfe,0x50,0x03,0x02,0x27, -0x82,0x7c,0x02,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,0x80,0x06,0xd3,0x50,0x03,0x02, -0x27,0x80,0xe5,0x67,0x20,0xe1,0x0d,0xe5,0x4a,0x60,0x09,0xe5,0x4a,0x64,0x80,0x60, -0x03,0x02,0x27,0x82,0xac,0x4a,0x12,0x30,0x4a,0x40,0x03,0x02,0x27,0x82,0xe5,0x49, -0x70,0x25,0x30,0x02,0x11,0x90,0xff,0x80,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,0xaf, -0x62,0x12,0x03,0x0f,0x80,0x0f,0x90,0xff,0x82,0xe0,0x54,0x08,0xad,0x64,0xae,0x63, -0xaf,0x62,0x12,0x03,0x0f,0x80,0x3d,0x15,0x49,0x30,0x02,0x1d,0xe5,0x49,0x75,0xf0, -0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x64, -0xae,0x63,0xaf,0x62,0x12,0x03,0x0f,0x80,0x1b,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24, -0x08,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0x08,0xad,0x64,0xae,0x63,0xaf, -0x62,0x12,0x03,0x0f,0xad,0x64,0xae,0x63,0xaf,0x62,0x12,0x01,0xe6,0x60,0x0b,0xad, -0x64,0xae,0x63,0xaf,0x62,0x74,0x01,0x12,0x03,0x0f,0x7c,0x02,0x12,0x2f,0xc3,0x22, -0x80,0x00,0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe7,0x06,0xe5,0x6c,0x45,0x6b,0x60,0x03, -0x02,0x2c,0x0f,0x90,0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40, -0x1a,0xe5,0x4c,0x14,0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x28,0x8e,0x78, -0xa7,0xe6,0x54,0xfe,0xf6,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03, -0xd3,0x40,0x2a,0xe5,0x67,0x20,0xe1,0x08,0xe5,0x67,0x20,0xe0,0x03,0x02,0x28,0x8e, -0xe5,0x67,0x30,0xe0,0x04,0xe5,0x4a,0x70,0x0b,0xe5,0x67,0x30,0xe1,0x09,0xe5,0x4a, -0x24,0xfe,0x50,0x03,0x02,0x28,0x8e,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02, -0x80,0x06,0xd3,0x50,0x03,0x02,0x28,0x8c,0xe5,0x4c,0x45,0x4b,0x60,0x03,0x02,0x28, -0x8e,0xac,0x4a,0x12,0x30,0x4a,0x40,0x03,0x02,0x28,0x8e,0xe5,0x67,0x20,0xe1,0x07, -0xe5,0x67,0x20,0xe0,0x02,0x80,0x77,0xe5,0x67,0x30,0xe0,0x06,0xe5,0x49,0x60,0x02, -0x80,0x6c,0xe5,0x49,0x70,0x0f,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x80, -0xe0,0x54,0xf7,0xf0,0x22,0xe5,0x49,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x09,0x7d, -0x01,0x7c,0x03,0x12,0x0f,0x0b,0x80,0x11,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x09, -0x7d,0x01,0x7c,0x04,0x12,0x0f,0x0b,0x80,0x00,0x15,0x49,0x30,0x02,0x15,0xe5,0x49, -0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x54,0xf7, -0xf0,0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34,0xff, -0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x00,0x02,0x2c, -0x0f,0xe5,0x67,0x20,0xe7,0x06,0xe5,0x6c,0x45,0x6b,0x60,0x03,0x02,0x2c,0x0f,0x90, -0xff,0x00,0xe0,0x54,0x1f,0xb4,0x00,0x02,0x80,0x03,0xd3,0x40,0x1a,0xe5,0x4c,0x14, -0x45,0x4b,0x70,0x04,0xe5,0x4a,0x60,0x03,0x02,0x29,0x71,0x78,0xa7,0xe6,0x44,0x01, -0xf6,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x29,0xe5, -0x67,0x20,0xe1,0x08,0xe5,0x67,0x20,0xe0,0x03,0x02,0x29,0x71,0xe5,0x67,0x30,0xe0, -0x04,0xe5,0x49,0x70,0x0b,0xe5,0x67,0x30,0xe1,0x08,0xe5,0x49,0x24,0xfe,0x50,0x02, -0x80,0x7f,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xb4,0x02,0x02,0x80,0x03,0xd3,0x40,0x6f, -0xe5,0x4c,0x45,0x4b,0x60,0x02,0x80,0x69,0xac,0x4a,0x12,0x30,0x4a,0x40,0x02,0x80, -0x60,0xe5,0x67,0x20,0xe1,0x07,0xe5,0x67,0x20,0xe0,0x02,0x80,0x54,0xe5,0x49,0x70, -0x14,0x30,0x02,0x09,0x90,0xff,0x80,0xe0,0x44,0x08,0xf0,0x80,0x07,0x90,0xff,0x82, -0xe0,0x44,0x08,0xf0,0x22,0xe5,0x67,0x30,0xe1,0x33,0x15,0x49,0x30,0x02,0x15,0xe5, -0x49,0x75,0xf0,0x08,0xa4,0x24,0x48,0xf5,0x82,0xe4,0x34,0xff,0xf5,0x83,0xe0,0x44, -0x08,0xf0,0x80,0x13,0xe5,0x49,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,0x82,0xe4,0x34, -0xff,0xf5,0x83,0xe0,0x44,0x08,0xf0,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x02,0x80, -0x00,0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe7,0x12,0xe5,0x6c,0x45,0x6b,0x70,0x0c,0xe5, -0x4a,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x0f,0xe5,0x4c, -0x90,0xff,0xff,0xf0,0x90,0xff,0xff,0xe0,0x60,0x05,0x43,0x67,0x01,0x80,0x03,0x53, -0x67,0xfe,0x7c,0x00,0x12,0x2f,0xc3,0x22,0xe5,0x67,0x30,0xe7,0x0e,0xe5,0x6c,0x45, -0x6b,0x60,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c,0x0f,0xad,0x4b, -0xe5,0x4c,0xed,0x7d,0x00,0xfc,0x7d,0x00,0xfc,0xbd,0x00,0x02,0x80,0x03,0x02,0x2b, -0x0a,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x32,0xe5,0x4a,0x70,0x05,0xe5,0x4c,0xfc, -0x60,0x03,0x02,0x2b,0x0c,0x75,0x64,0x00,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,0xe5, -0x6c,0x94,0x12,0xe5,0x6b,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x12,0x80,0x04,0xac, -0x6c,0xad,0x6b,0x8c,0x6a,0x8d,0x69,0x12,0x2f,0xd8,0x22,0xb4,0x02,0x02,0x80,0x03, -0xd3,0x40,0x59,0xe5,0x4a,0x60,0x03,0x02,0x2b,0x0c,0xe5,0x4c,0xfc,0x70,0x27,0x75, -0x64,0x12,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3,0xe5,0x6c,0x94,0x19,0xe5,0x6b,0x94, -0x00,0x40,0x06,0xe4,0xfd,0x7c,0x19,0x80,0x04,0xac,0x6c,0xad,0x6b,0x8c,0x6a,0x8d, -0x69,0x12,0x2f,0xd8,0x80,0x25,0x75,0x64,0x2b,0x75,0x63,0xfc,0x75,0x62,0x01,0xd3, -0xe5,0x6c,0x94,0x35,0xe5,0x6b,0x94,0x00,0x40,0x06,0xe4,0xfd,0x7c,0x35,0x80,0x04, -0xac,0x6c,0xad,0x6b,0x8c,0x6a,0x8d,0x69,0x12,0x2f,0xd8,0x22,0xb4,0x03,0x02,0x80, -0x06,0xd3,0x50,0x03,0x02,0x2b,0x0a,0xe5,0x4c,0xf5,0x49,0x70,0x0f,0x90,0xff,0x04, -0xe0,0xfd,0xa3,0xe0,0x4d,0x60,0x03,0x02,0x2b,0x0c,0x80,0x18,0x90,0xfc,0x82,0xe0, -0xfd,0xa3,0xe0,0xfc,0x90,0xff,0x05,0xe0,0x6c,0x70,0x07,0x90,0xff,0x04,0xe0,0x6d, -0x60,0x02,0x80,0x68,0xe4,0xf5,0x6a,0xf5,0x69,0x7f,0x00,0xe5,0x49,0x14,0xc5,0x49, -0x60,0x0f,0xef,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x2f,0xff,0x80, -0xea,0x8f,0x4a,0xe5,0x4a,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x7d, -0x00,0xd3,0x95,0x6c,0xed,0x95,0x6b,0x40,0x06,0xac,0x6c,0xad,0x6b,0x80,0x0f,0xe5, -0x4a,0x24,0x80,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x7d,0x00,0xfc,0x8c,0x6a, -0x8d,0x69,0xe5,0x4a,0x24,0x80,0xfc,0xe4,0x34,0xfc,0xfd,0xfe,0xec,0xfd,0x7f,0x01, -0x8d,0x64,0x8e,0x63,0x8f,0x62,0x12,0x2f,0xd8,0x22,0x80,0x00,0x02,0x2c,0x0f,0x02, -0x2c,0x0f,0xe5,0x67,0x30,0xe7,0x19,0xe5,0x6c,0x14,0x45,0x6b,0x70,0x12,0xe5,0x4a, -0x70,0x0e,0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03, -0x02,0x2c,0x0f,0xe5,0x67,0x20,0xe0,0x08,0xe5,0x67,0x20,0xe1,0x03,0x02,0x2c,0x0f, -0x75,0x64,0x68,0xe4,0xf5,0x63,0xf5,0x62,0xe4,0xf5,0x69,0x04,0xf5,0x6a,0x12,0x2f, -0xd8,0x22,0xe5,0x67,0x20,0xe7,0x27,0xe5,0x6c,0x45,0x6b,0x70,0x21,0xe5,0x4a,0x70, -0x1d,0xe5,0x4c,0x64,0x02,0x45,0x4b,0x60,0x0d,0xe5,0x4c,0x14,0x45,0x4b,0x60,0x06, -0xe5,0x4c,0x45,0x4b,0x70,0x08,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x03,0x02,0x2c, -0x0f,0xe5,0x67,0x20,0xe0,0x08,0xe5,0x67,0x20,0xe1,0x03,0x02,0x2c,0x0f,0x85,0x4c, -0x68,0xe5,0x68,0x70,0x08,0x43,0x67,0x01,0x53,0x67,0xfd,0x80,0x13,0xe5,0x68,0x64, -0x02,0x60,0x07,0xe5,0x68,0x14,0x60,0x02,0x80,0x65,0x53,0x67,0xfe,0x43,0x67,0x02, -0x7c,0x00,0x12,0x2f,0xc3,0x22,0xe5,0x67,0x30,0xe7,0x1a,0xe5,0x6c,0x14,0x45,0x6b, -0x70,0x13,0xe5,0x4a,0x70,0x0f,0xe5,0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0, -0x54,0x1f,0x14,0x60,0x02,0x80,0x38,0xe5,0x67,0x20,0xe1,0x02,0x80,0x31,0x7c,0x01, -0x12,0x2f,0xc3,0x22,0xe5,0x67,0x20,0xe7,0x15,0xe5,0x6c,0x45,0x6b,0x70,0x0f,0xe5, -0x4c,0x45,0x4b,0x70,0x09,0x90,0xff,0x00,0xe0,0x54,0x1f,0x14,0x60,0x02,0x80,0x0f, -0xe5,0x67,0x20,0xe1,0x02,0x80,0x08,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x80,0x00,0x02, -0x2e,0xca,0xb4,0x40,0x02,0x80,0x06,0xd3,0x50,0x03,0x02,0x2e,0xc0,0x90,0xff,0x01, -0xe0,0x90,0xfd,0x3d,0xf0,0xe5,0x4a,0x90,0xfd,0x3e,0xf0,0xe4,0x90,0xfd,0x3f,0xf0, -0xe5,0x64,0x24,0x03,0xf5,0x64,0xe5,0x63,0x34,0x00,0xf5,0x63,0xad,0x4b,0xe5,0x4c, -0x85,0x64,0x82,0x85,0x63,0x83,0xcd,0xf0,0xa3,0xcd,0xf0,0x90,0xff,0x01,0xe0,0x12, -0x01,0xb7,0x2c,0x7d,0x01,0x2c,0xa3,0x02,0x2c,0xcd,0x03,0x2c,0xf7,0x04,0x2d,0x45, -0x05,0x2d,0x82,0x06,0x2d,0xa8,0x07,0x2d,0xce,0x08,0x2d,0xf4,0x09,0x2e,0x1a,0x0b, -0x2e,0x40,0x0c,0x2e,0x4f,0x80,0x2e,0x4f,0x81,0x00,0x00,0x2e,0xad,0xe5,0x67,0x20, -0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0x7d,0xb7,0x7e,0x34,0x7f,0x02,0x79,0x40, -0x7a,0xfd,0x7b,0x01,0x74,0x08,0x78,0x00,0x12,0x03,0x3f,0x7d,0x08,0x7c,0x00,0x12, -0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0xe5,0x4a, -0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c, -0x10,0x12,0x31,0x9a,0x22,0x7d,0x00,0x7c,0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20, -0xe7,0x06,0x7c,0x05,0x12,0x25,0x4a,0x22,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4, -0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x11,0x12,0x31,0x9a,0x22,0x7d, -0x00,0x7c,0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x06,0x7c,0x05,0x12,0x25, -0x4a,0x22,0xe5,0x4a,0xb4,0x05,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe, -0x7c,0x0a,0x12,0x31,0x9a,0x22,0xb4,0x01,0x02,0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff, -0x04,0xfe,0x7c,0x08,0x12,0x31,0x9a,0x22,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00, -0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x13,0x12,0x31,0x9a,0x22,0x7d,0x00,0x7c, -0x07,0x12,0x24,0xb1,0x22,0xe5,0x67,0x20,0xe7,0x34,0xd3,0xe5,0x6c,0x94,0x48,0xe5, -0x6b,0x94,0x00,0x50,0x06,0xe5,0x6c,0x45,0x6b,0x70,0x06,0x7c,0x02,0x12,0x25,0x4a, -0x22,0xe5,0x4a,0xb4,0x01,0x03,0xb3,0x40,0x0b,0xc3,0xb4,0x03,0x00,0x40,0x09,0xb4, -0x06,0x00,0x50,0x04,0x12,0x30,0x70,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24, -0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05, -0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x16,0x12,0x31,0x9a,0x22,0x7c,0x07, -0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4, -0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x19, -0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67, -0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5, -0x4a,0x7f,0x00,0xfe,0x7c,0x17,0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22, -0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5,0x4a,0xb4,0x03,0x00,0x40,0x10, -0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe,0x7c,0x18,0x12,0x31,0x9a,0x22, -0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5,0x67,0x20,0xe7,0x1d,0xe5, -0x4a,0xb4,0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x4a,0x7f,0x00,0xfe, -0x7c,0x15,0x12,0x31,0x9a,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22, -0xe5,0x67,0x20,0xe7,0x06,0x7c,0x07,0x12,0x25,0x4a,0x22,0x12,0x24,0xe8,0x22,0xe5, -0x67,0x30,0xe7,0x20,0x90,0xff,0x00,0xe0,0x54,0x1f,0x70,0x10,0x90,0xff,0x01,0xe0, -0xb4,0x80,0x05,0x12,0x24,0xdf,0x80,0x03,0x12,0x24,0xe8,0x22,0x7d,0x00,0x7c,0x05, -0x12,0x24,0xb1,0x22,0x90,0xff,0x00,0xe0,0x54,0x1f,0x60,0x06,0x7c,0x05,0x12,0x25, -0x4a,0x22,0xd3,0xe5,0x6c,0x94,0x48,0xe5,0x6b,0x94,0x00,0x50,0x0b,0xc3,0xe5,0x6c, -0x94,0x07,0xe5,0x6b,0x94,0x00,0x50,0x06,0x7c,0x03,0x12,0x25,0x4a,0x22,0xe5,0x4a, -0xb4,0x05,0x04,0x12,0x30,0x70,0x22,0x7c,0x07,0x12,0x25,0x4a,0x22,0xe5,0x67,0x30, -0xe7,0x08,0x7d,0x00,0x7c,0x05,0x12,0x24,0xb1,0x22,0x7c,0x05,0x12,0x25,0x4a,0x22, -0xb4,0x20,0x02,0x80,0x03,0xd3,0x40,0x00,0x80,0x00,0x12,0x2f,0x9e,0x22,0x75,0x43, -0x00,0x90,0xff,0x83,0xe0,0x54,0x0f,0xd3,0x95,0x43,0x40,0x24,0xe5,0x43,0x24,0xf0, -0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83,0xe0,0xad,0x64,0xae,0x63,0xaf,0x62,0x12,0x03, -0x0f,0x05,0x43,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80,0xd1, -0xe5,0x43,0x7d,0x00,0xfc,0xc3,0xe5,0x6a,0x9c,0xf5,0x6a,0xe5,0x69,0x9d,0xf5,0x69, -0xe5,0x6a,0x45,0x69,0x60,0x06,0xe4,0x90,0xff,0x83,0xf0,0x22,0x90,0xff,0x82,0xe0, -0x44,0x08,0xf0,0xe4,0xf5,0x69,0x75,0x6a,0x49,0x90,0xfd,0x3d,0xe0,0xb4,0x05,0x02, -0x80,0x03,0xd3,0x40,0x40,0x90,0xfd,0x3e,0xe0,0xf5,0x43,0xb4,0x05,0x02,0x80,0x03, -0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x0b,0x12,0x31,0x9a,0x22,0xb4,0x01,0x02, -0x80,0x03,0xd3,0x40,0x0a,0xe4,0xff,0x04,0xfe,0x7c,0x09,0x12,0x31,0x9a,0x22,0xb4, -0x03,0x00,0x40,0x10,0xb4,0x05,0x00,0x50,0x0b,0xe5,0x43,0x7f,0x00,0xfe,0x7c,0x14, -0x12,0x31,0x9a,0x22,0x22,0xb4,0x80,0x00,0x40,0x23,0xb4,0x82,0x00,0x50,0x1e,0x7c, -0x3d,0x7d,0xfd,0x12,0x17,0xd5,0x7d,0x00,0x8c,0x66,0x8d,0x65,0x90,0xfd,0x3f,0xe0, -0x60,0x05,0x12,0x2f,0x9e,0x80,0x05,0x7c,0x00,0x12,0x2f,0xc3,0x22,0x22,0x90,0xff, -0x83,0xe0,0x54,0x7f,0xf0,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0, -0x44,0x08,0xf0,0x22,0x90,0xff,0x82,0xe0,0x44,0x08,0xf0,0x90,0xff,0x80,0xe0,0x44, -0x08,0xf0,0x22,0x8c,0x23,0x7d,0x00,0x8c,0x6a,0x8d,0x69,0x75,0x64,0x3d,0x75,0x63, -0xfd,0x75,0x62,0x01,0x12,0x2f,0xd8,0x22,0x90,0xff,0x83,0xe0,0x54,0x7f,0xf0,0xe5, -0x6a,0x64,0x49,0x45,0x69,0x70,0x01,0x22,0xc3,0xe5,0x6a,0x94,0x08,0xe5,0x69,0x94, -0x00,0x40,0x15,0x75,0x21,0x08,0xe5,0x21,0x7d,0x00,0xfc,0xc3,0xe5,0x6a,0x9c,0xf5, -0x6a,0xe5,0x69,0x9d,0xf5,0x69,0x80,0x09,0x85,0x6a,0x21,0xe4,0xf5,0x69,0x75,0x6a, -0x49,0x75,0x22,0x00,0xe5,0x22,0xc3,0x95,0x21,0x50,0x26,0xad,0x64,0xae,0x63,0xaf, -0x62,0x12,0x01,0xe6,0xfc,0xe5,0x22,0x24,0xf8,0xf5,0x82,0xe4,0x34,0xfe,0xf5,0x83, -0xec,0xf0,0x05,0x22,0x0d,0xed,0x70,0x01,0x0e,0x8d,0x64,0x8e,0x63,0x8f,0x62,0x80, -0xd3,0xe5,0x21,0x54,0x7f,0x90,0xff,0x81,0xf0,0x22,0x8c,0x48,0x7f,0x00,0xef,0x24, -0xfb,0x40,0x19,0xe4,0xef,0x75,0xf0,0x07,0xa4,0x24,0x3f,0xf5,0x82,0xe4,0x34,0xfc, -0xf5,0x83,0xe0,0x65,0x48,0x70,0x02,0xd3,0x22,0x0f,0x80,0xe2,0x8f,0x47,0xc3,0x22, -0x85,0x6c,0x6a,0x85,0x6b,0x69,0x90,0xff,0x82,0xe0,0x54,0xf7,0xf0,0x90,0xff,0x83, -0xe0,0x54,0x7f,0xf0,0x22,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xe5, -0x72,0x24,0x08,0xf8,0x86,0x06,0x53,0x06,0x7f,0x7c,0xff,0x12,0x30,0xfa,0x7c,0x00, -0x7d,0x00,0xe5,0x75,0x60,0x46,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x7f,0x6e,0x70,0x0f, -0xc0,0x83,0xc0,0x82,0xa3,0xe0,0xfd,0xa3,0xe0,0xfc,0xa3,0x15,0x75,0x80,0x07,0xa3, -0xa3,0xa3,0xdf,0xe6,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0x1e,0xe0,0xf8, -0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3, -0xea,0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x12,0x31,0x93,0xd0, -0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x22,0x85,0xa8,0x74,0x75,0xa8,0x88, -0xec,0x70,0x02,0x7c,0x3f,0x8c,0x73,0x22,0xe5,0x72,0x24,0x08,0xf8,0x76,0x00,0x12, -0x31,0xe7,0x80,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x06,0xc0,0x07,0xae,0x04, -0x7c,0xff,0x12,0x30,0xfa,0xe5,0x75,0x60,0x42,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x7f, -0x6e,0x70,0x0b,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x15,0x75,0x80,0x07,0xa3,0xa3, -0xa3,0xdf,0xea,0x80,0x26,0xdf,0x06,0xd0,0x82,0xd0,0x83,0x80,0xd8,0xe0,0xf8,0xa3, -0xe0,0xf9,0xa3,0xe0,0xfa,0xd0,0x82,0xd0,0x83,0xe8,0xf0,0xa3,0xe9,0xf0,0xa3,0xea, -0xf0,0xa3,0xc0,0x83,0xc0,0x82,0xa3,0xa3,0xa3,0x80,0xda,0x78,0x08,0x08,0x79,0x18, -0x09,0x7c,0x01,0xe6,0x54,0x7f,0x6e,0x70,0x06,0x76,0x00,0x77,0x00,0x80,0x06,0x08, -0x09,0x0c,0xbc,0x08,0xee,0x12,0x31,0x93,0xd0,0x07,0xd0,0x06,0xd0,0x02,0xd0,0x01, -0xd0,0x00,0x22,0x75,0x73,0x00,0x85,0x74,0xa8,0x22,0xc0,0xf0,0xc0,0x82,0xc0,0x83, -0xc3,0xe5,0x75,0x24,0xe8,0x50,0x05,0x12,0x31,0xe7,0x80,0xf4,0xec,0x60,0x31,0x90, -0x34,0xb6,0xe4,0x93,0xc3,0x9c,0x40,0x28,0xc0,0x04,0x7c,0xff,0x12,0x30,0xfa,0xd0, -0x04,0x43,0x04,0x80,0xe5,0x75,0x75,0xf0,0x03,0xa4,0x24,0x9d,0xf5,0x82,0xe4,0x34, -0xfe,0xf5,0x83,0xec,0xf0,0xef,0xa3,0xf0,0xee,0xa3,0xf0,0x05,0x75,0x12,0x31,0x93, -0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0xc0,0x04,0x7c,0x20,0xd2,0x8c,0xd2,0x8d,0xd5, -0x04,0xfd,0xd0,0x04,0x22,0x75,0xa8,0x00,0x75,0x88,0x00,0x75,0xb8,0x00,0x75,0xf0, -0x00,0x75,0xd0,0x00,0xe4,0xf8,0x90,0x00,0x00,0xf6,0x08,0xb8,0x00,0xfb,0x02,0x00, -0x00,0xc3,0xed,0x94,0x02,0x50,0x04,0x7d,0x03,0x7c,0xe8,0xec,0xf4,0xfc,0xed,0xf4, -0xfd,0x0c,0xbc,0x00,0x01,0x0d,0x8c,0x79,0x8d,0x78,0x22,0xc3,0xec,0x94,0xbc,0xed, -0x94,0x02,0x50,0x04,0x7d,0x07,0x7c,0xd0,0xec,0xf4,0xfc,0xed,0xf4,0xfd,0x0c,0xbc, -0x00,0x01,0x0d,0x8c,0x77,0x8d,0x76,0x22,0xec,0x70,0x01,0x22,0xc0,0x00,0xe5,0x72, -0x24,0x18,0xf8,0xa6,0x04,0xe5,0x72,0x24,0x08,0xf8,0xc6,0x54,0x7f,0xf6,0xe6,0x30, -0xe7,0x03,0xd0,0x00,0x22,0x12,0x31,0xe7,0x80,0xf4,0xc2,0x8c,0x85,0x76,0x8c,0x85, -0x77,0x8a,0xd2,0x8c,0xc0,0xe0,0xc0,0xd0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00, -0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x12,0x1b, -0x28,0xe5,0x72,0x24,0x08,0xf8,0xe6,0x60,0x24,0xe5,0x72,0x24,0x10,0xf8,0xa6,0x81, -0xe5,0x72,0x75,0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78, -0xa8,0xe5,0x81,0x04,0xc3,0x98,0xf9,0xe6,0xf0,0x08,0xa3,0xd9,0xfa,0x74,0x08,0x25, -0x72,0xf8,0x05,0x72,0x08,0xe6,0x54,0x80,0x70,0x0c,0xe5,0x72,0xb4,0x07,0xf3,0x78, -0x08,0x75,0x72,0x00,0x80,0xef,0xe5,0x72,0x24,0x10,0xf8,0x86,0x81,0xe5,0x72,0x75, -0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd,0xf5,0x83,0x78,0xa8,0xe5,0x81, -0x04,0xc3,0x98,0xf9,0xe0,0xf6,0x08,0xa3,0xd9,0xfa,0xd0,0x07,0xd0,0x06,0xd0,0x05, -0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0, -0xd0,0xd0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc2, -0x8e,0x85,0x78,0x8d,0x85,0x79,0x8b,0xd2,0x8e,0x78,0x19,0x79,0x09,0x7a,0x07,0xe7, -0x70,0x04,0xa6,0x00,0x80,0x0b,0xe6,0x60,0x08,0x16,0xe6,0x70,0x04,0xe7,0x44,0x80, -0xf7,0x08,0x09,0xda,0xea,0xe5,0x73,0x60,0x13,0x14,0xf5,0x73,0x70,0x0e,0xe5,0x72, -0x24,0x08,0xf8,0x76,0x00,0x12,0x31,0x93,0xd2,0x8c,0xd2,0x8d,0xd0,0x02,0xd0,0x01, -0xd0,0x00,0xd0,0xd0,0xd0,0xe0,0x32,0x75,0x81,0xa7,0x75,0x90,0x00,0x75,0x79,0x30, -0x75,0x78,0xf8,0x75,0x77,0x60,0x75,0x76,0xf0,0x12,0x05,0x3c,0x12,0x34,0x0f,0x12, -0x17,0x8b,0x12,0x34,0x39,0x12,0x31,0xf5,0x80,0xe3,0x22,0xc0,0x00,0x7c,0x01,0xec, -0x24,0x08,0xf8,0xe6,0x60,0x09,0x0c,0xbc,0x08,0xf5,0x12,0x31,0xe7,0x80,0xee,0xd0, -0x00,0x22,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x00,0xc0,0x06,0xc0,0x07,0xed,0x24, -0x10,0xf8,0x76,0xb6,0xed,0x75,0xf0,0x21,0xa4,0x24,0x95,0xf5,0x82,0xe4,0x34,0xfd, -0xf5,0x83,0xc0,0x82,0xc0,0x83,0xa3,0xa3,0xe4,0x78,0x0d,0xf0,0xa3,0xd8,0xfc,0xec, -0x54,0x7f,0x75,0xf0,0x02,0xa4,0x24,0x82,0xf5,0x82,0xe5,0xf0,0x34,0x34,0xf5,0x83, -0xe4,0x93,0xfe,0x74,0x01,0x93,0xf5,0x82,0x8e,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93, -0xff,0xd0,0x83,0xd0,0x82,0xef,0xf0,0xa3,0xee,0xf0,0xed,0x24,0x08,0xf8,0xec,0x44, -0x80,0xf6,0xd0,0x07,0xd0,0x06,0xd0,0x00,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0x22,0x75, -0x72,0x00,0x75,0x75,0x00,0x7a,0x08,0x79,0x18,0x78,0x08,0x76,0x00,0x77,0x00,0x08, -0x09,0xda,0xf8,0xe4,0x78,0x08,0x74,0x80,0x44,0x7f,0xf6,0x74,0x01,0x44,0x10,0xf5, -0x89,0x75,0xb8,0x08,0xd2,0xab,0xd2,0xa9,0x22,0x75,0x81,0xa7,0xd2,0x8e,0xd2,0x8c, -0xd2,0xaf,0xe5,0x75,0x60,0x32,0xff,0x90,0xfe,0x9d,0xe0,0x54,0x80,0x60,0x24,0x78, -0x08,0x79,0x08,0xe0,0x54,0x7f,0xfa,0x7b,0x00,0xe6,0x54,0x7f,0xb5,0x02,0x02,0x7b, -0xff,0x08,0xd9,0xf5,0xeb,0x70,0x0c,0xea,0xf0,0x12,0x33,0x8b,0xad,0x04,0xac,0x02, -0x12,0x33,0xa2,0xa3,0xa3,0xa3,0xdf,0xd2,0x12,0x31,0xe7,0x80,0xc5,0x7c,0x01,0x7d, -0x00,0x22,0x04,0xf5,0x04,0xe9,0x04,0xed,0x04,0xe1,0x04,0xdd,0x04,0xd9,0x04,0xe5, -0x04,0xf1,0x04,0x9d,0x04,0xa1,0x04,0xcd,0x04,0xd1,0x04,0x99,0x04,0x99,0x04,0x99, -0x04,0xd5,0x04,0xb5,0x04,0xad,0x04,0xb1,0x04,0xa9,0x04,0xc1,0x04,0xbd,0x04,0xb9, -0x04,0xc5,0x04,0xc9,0x04,0xa5,0x19,0x01,0x03,0x00,0x22,0x00,0x48,0x02,0x00,0x24, -0x0f,0x18,0x0a,0x10,0x64,0x0d,0x68,0x0c,0x05,0x06,0x02,0x03,0x01,0x01,0x81,0x01, -0x00,0x00,0xe7,0x00,0xc0,0x00,0x80,0x00,0x60,0x00,0x40,0x00,0x30,0x00,0x18,0x00, -0x0c,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x08,0x18,0x38,0x28,0x06,0x02, -0x10,0x0a,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x10,0x0a,0x02,0x00,0x00,0x00, -0x00,0x00,0xfb,0xe8,0xfb,0xfa,0x12,0x01,0x10,0x01,0xff,0x00,0x00,0x08,0x51,0x04, -0x5f,0x50,0x16,0x01,0x01,0x02,0x00,0x02,0x09,0x02,0x35,0x00,0x01,0x02,0x00,0xe0, -0x00,0x09,0x04,0x00,0x00,0x05,0xff,0x00,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00, -0x00,0x07,0x05,0x01,0x02,0x40,0x00,0x00,0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07, -0x05,0x02,0x02,0x40,0x00,0x00,0x07,0x05,0x85,0x03,0x02,0x00,0x01,0x04,0x03,0x09, -0x04,0x24,0x03,0x54,0x00,0x65,0x00,0x78,0x00,0x61,0x00,0x73,0x00,0x20,0x00,0x49, -0x00,0x6e,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x75,0x00,0x6d,0x00,0x65,0x00,0x6e, -0x00,0x74,0x00,0x73,0x00,0x2a,0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x35, -0x00,0x30,0x00,0x35,0x00,0x32,0x00,0x20,0x00,0x53,0x00,0x65,0x00,0x72,0x00,0x69, -0x00,0x61,0x00,0x6c,0x00,0x20,0x00,0x50,0x00,0x6f,0x00,0x72,0x00,0x74,0x00,0x22, -0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x35,0x00,0x30,0x00,0x35,0x00,0x32, -0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20, -0x00, -}; - -#endif /* ifndef _TI_FW_5052_H_ */ diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a1c8aef..a26a629 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -84,11 +84,9 @@ #include #include #include +#include #include "ti_usb_3410_5052.h" -#include "ti_fw_3410.h" /* firmware image for 3410 */ -#include "ti_fw_5052.h" /* firmware image for 5052 */ - /* Defines */ @@ -194,8 +192,8 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command, static int ti_write_byte(struct ti_device *tdev, unsigned long addr, __u8 mask, __u8 byte); -static int ti_download_firmware(struct ti_device *tdev, - unsigned char *firmware, unsigned int firmware_size); +static int ti_download_firmware(struct ti_device *tdev, char *fw_name); + /* circular buffer */ static struct circ_buf *ti_buf_alloc(void); @@ -320,6 +318,9 @@ MODULE_DESCRIPTION(TI_DRIVER_DESC); MODULE_VERSION(TI_DRIVER_VERSION); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("ti_3410.fw"); +MODULE_FIRMWARE("ti_5052.fw"); + module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes"); @@ -431,11 +432,9 @@ static int ti_startup(struct usb_serial *serial) if (dev->descriptor.bNumConfigurations == 1) { if (tdev->td_is_3410) - status = ti_download_firmware(tdev, ti_fw_3410, - sizeof(ti_fw_3410)); + status = ti_download_firmware(tdev, "ti_3410.fw"); else - status = ti_download_firmware(tdev, ti_fw_5052, - sizeof(ti_fw_5052)); + status = ti_download_firmware(tdev, "ti_5052.fw"); if (status) goto free_tdev; @@ -1658,8 +1657,9 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr, static int ti_download_firmware(struct ti_device *tdev, - unsigned char *firmware, unsigned int firmware_size) + char *fw_name) { + const struct firmware *fw; int status = 0; int buffer_size; int pos; @@ -1672,16 +1672,29 @@ static int ti_download_firmware(struct ti_device *tdev, unsigned int pipe = usb_sndbulkpipe(dev, tdev->td_serial->port[0]->bulk_out_endpointAddress); - buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header); + + if (request_firmware(&fw, fw_name, &dev->dev)) { + dev_err(&dev->dev, "%s - failed to load firmware \"%s\"\n", + __func__, fw_name); + return -ENOENT; + } + if (fw->size > buffer_size) { + dev_err(&dev->dev, "%s - firmware \"%s\" is too large\n", + __func__, fw_name); + release_firmware(fw); + return -EINVAL; + } + buffer = kmalloc(buffer_size, GFP_KERNEL); if (!buffer) { dev_err(&dev->dev, "%s - out of memory\n", __func__); + release_firmware(fw); return -ENOMEM; } - memcpy(buffer, firmware, firmware_size); - memset(buffer+firmware_size, 0xff, buffer_size-firmware_size); + memcpy(buffer, fw->data, fw->size); + memset(buffer+fw->size, 0xff, buffer_size-fw->size); for(pos = sizeof(struct ti_firmware_header); pos < buffer_size; pos++) cs = (__u8)(cs + buffer[pos]); @@ -1699,6 +1712,7 @@ static int ti_download_firmware(struct ti_device *tdev, } kfree(buffer); + release_firmware(fw); if (status) { dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __func__, status); diff --git a/firmware/Makefile b/firmware/Makefile index 2b34074..28f975f 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -53,6 +53,7 @@ fw-shipped- := keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw endif +fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw diff --git a/firmware/WHENCE b/firmware/WHENCE index 8e35d7b..205be9f 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -190,3 +190,18 @@ Converted from Intel HEX files, used in our binary representation of ihex. Original licence information: None -------------------------------------------------------------------------- + +Driver: tu_usb_3410_5052 -- USB TI 3410/5052 serial device + +File: ti_3410.fw +Info: firmware 9/10/04 FW3410_Special_StartWdogOnStartPort + +File: ti_5052.fw +Info: firmware 9/18/04 + +Licence: Allegedly GPLv2+, but no source visible. Marked: + Copyright (C) 2004 Texas Instruments + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/ti_3410.fw.ihex b/firmware/ti_3410.fw.ihex new file mode 100644 index 0000000..b22c042 --- /dev/null +++ b/firmware/ti_3410.fw.ihex @@ -0,0 +1,862 @@ +:10000000C2350002001E021ADBFFFFFFFFFF0232B3 +:10001000CBFFFFFFFFFFFFFFFFFFFFFFFFFF0233ED +:10002000767581CE90FDE88583A01234EAEC4D60B0 +:100030006A78AB8003760018B89CFA787F800376E4 +:100040000018B865FA78208003760018B820FA9076 +:10005000FDDDAE83AF8290FBF81200A16005E4F0F5 +:10006000A380F690FDE8A88290FDE8A982E8C399F4 +:10007000500576000880F69000FF1200AA90010358 +:100080001200AA9001071200AA90010B1200C8905A +:1000900001111200C89001171200C875D000123368 +:1000A000C802011DEF65827003EE658322E493F8B8 +:1000B000740193F9740293FE740393F5828E83E8BE +:1000C00069700122E493F6A30880F4E493FC7401C0 +:1000D00093FD740293FE740393FF740493F8740504 +:1000E00093F58288831200A1700122E493A3A88370 +:1000F000A9828C838D82F0A3AC83AD8288838982B0 +:1001000080E32121049280800492ACAE0492FDE849 +:1001100004940494FBF304990494FBF304F904F9A4 +:1001200080FED0F030F00920F303F68010F7800D48 +:1001300030F10920F303F28004F38001F020F4048D +:10014000FCD0E0CC22CCC0E012015A02014BBC0032 +:1001500005D0F0ACF022C313DCFC020121BF000982 +:10016000ED258275F001F8E622BF010FED2582F53D +:1001700082EE3583F58375F004E022ED258275F07B +:1001800002F8E222D083D082F5F0C3E493A3C5F055 +:1001900095F0C0E0C3D0F0E493A395F04012A3A380 +:1001A000C3E5F033500205832582F58250020583B2 +:1001B000740193C0E0E493C0E022D083D082F5F0D4 +:1001C000E49370097401937004A3A3800C740293E8 +:1001D00065F06005A3A3A380E7740193C0E0E493F6 +:1001E000C0E02212025B0201F21202AF0201F2121F +:1001F00002D30201F230E00720E302E622E72230D8 +:10020000E10720E302E222E32230E202E022E4936B +:10021000221202D302021A1202AF02021AABF01229 +:100220000224CBC5F0CB2230E01020E306E6F5F047 +:1002300008E622E7F5F009E7192230E11020E3068D +:10024000E2F5F008E222E3F5F009E3192230E206D4 +:10025000E0F5F0A3E022E493F5F074019322BB00F3 +:1002600003740922BB010789828A83740422BB02BA +:100270000789828A83741022740A2202027BBB00DF +:1002800007E92582F8740122BB010DE92582F58278 +:10029000EA3583F583740422BB020DE92582F582D9 +:1002A000EA3583F583741022E92582F8740222026C +:1002B00002AFBF0005EDF8740122BF01078D828EE9 +:1002C00083740422BF02078D828E83741022EDF89E +:1002D0007402220202D3BF0007ED2582F8740122C6 +:1002E000BF010DED2582F582EE3583F5837404227E +:1002F000BF020DED2582F582EE3583F58374102261 +:10030000ED2582F8740222020307C0E012025B02AC +:10031000031FC0E01202AF02031FC0E01202D302AB +:10032000031F30E00B20E304D0E0F622D0E0F722F8 +:1003300030E10B20E304D0E0F222D0E0F322D0E061 +:10034000F022C9CDC9CACECACBCFCB120352EDF928 +:10035000EEFAEFFB22BB002FBF000AFAEDF8E7F63A +:100360000809DAFA22BF01128D828E83F802036F28 +:1003700009A3E7F0D8FA2202037AFAEDF8E7F208C7 +:1003800009DAFA22020384BB014DBF001489828A74 +:1003900083F9EDF802039608A3E0F6D9FA220203E6 +:1003A000A7BF01228D828E83FB08C9C582C9CAC539 +:1003B00083CAE0A3C9C582C9CAC583CAF0A3DBEA60 +:1003C000D8E8220203CA8D828E83F9EDF8E0F208A4 +:1003D000A3D9FA220203D4BB024DBF001289828A3C +:1003E00083F9EDF80203E608A3E493F6D9F922BFF6 +:1003F00001238D828E83FB08C9C582C9CAC583CA01 +:10040000E493A3C9C582C9CAC583CAF0A3DBE9D8EE +:10041000E72202041989828A83F9EDF8E493F2084D +:10042000A3D9F92202042ABF000DFAEDF8E3F60879 +:1004300009DAFA22020434BF01128D828E83F80297 +:10044000044109A3E3F0D8FA2202044CFAEDF8E3E0 +:10045000F20809DAFA22020456E6FB08E6FA08E690 +:10046000F904F61870010622E6FF08E6FE08E6FD2C +:1004700022EFF0A3EEF0A3EDF022EBF0A3EAF0A35D +:10048000E9F022E0FFA3E0FEA3E0FD22E0FBA3E011 +:10049000FAA3E0F9220000000000000004F9006166 +:1004A00005680026058F00330A0000610A6C0066AB +:1004B000151D00610CF0006109A0006109D7006101 +:1004C0000DB700610BE800610A1300610A48006182 +:1004D00017150033172800341DF600431EA10044F1 +:1004E000200E00441FFC00471EC800471F6D004D32 +:1004F0001FBE004F1EEA0058325600617CCC7DFFC3 +:10050000121CA72290FFFCE020E72DC2AFAE59AF2E +:1005100058755A20E55A14C55A6019E4FE7F05EE55 +:100520004FCE24FFCECF34FFCF6007E490FF92F090 +:1005300080ED80E08E598F58221205017D077CB72F +:100540001232727D0F7C6E12328C789D7A06E4F640 +:1005500008DAFC7A061205C47C03120E4C12214AFA +:10056000E4FEFF7C0F1231FBD2A8221230E6E490A9 +:10057000FC38F090FFF0E030E408740190FC39F0B2 +:100580008005E490FC39F07D0A7C001225261231AA +:1005900069221230E690FC39E014700E90FFF0E012 +:1005A0004410F07C001225BF801990FC39E0700ED9 +:1005B00090FFF0E054EFF07C001225BF80057C171F +:1005C0001225BF1231692290FFF0E054ABF090FF8A +:1005D000F0E04420F0228C378D367882EDF608EC7E +:1005E000F6EDFEECFD7F019000051201EC7880F63F +:1005F0007882E6FD08E6FCEDFEECFD7F019000044C +:100600001201EC540FFC7D801217467880E6700DC5 +:10061000AD3AAE39AF38E412030F7C082290FFF0F8 +:10062000E054FEF090FFF0E054FDF0801E7882E68A +:10063000FD08E6FCEDFEECFD7F0190000812020EC5 +:1006400025E0440190FFF3F00206D07882E6FD0831 +:10065000E6FCEDFEECFD7F0190000612020E54FE5A +:1006600090FFF3F0802B7882E6FD08E6FCEDFEECCF +:10067000FD7F0190000812020EFAEB90FFF1F012DC +:1006800008BF400DAD3AAE39AF38E412030F7C1805 +:10069000227882E6FD08E6FCEDFEECFD7F0190008D +:1006A0000812020E90FFF1F01208BF400DAD3AAEF5 +:1006B00039AF38E412030F7C18227882E6FD08E691 +:1006C000FCEDFEECFD7F0190000612020E4401904D +:1006D000FFF3F07883E62403F618E63400F678801A +:1006E000E624FE500990FFF0E054FDF0800790FFF3 +:1006F000F0E04402F0E490FFF1F078817600788039 +:10070000E624FFFCE434FFFD7881E67F00FEECD3B5 +:100710009EEF6480CD64809D402F1208A4400F7826 +:1007200081E6AD3AAE39AF3812030F7C182290FF44 +:10073000F2E0FC78828683088682ECF0788106A35A +:100740007882A68308A68280B51208A4400F78811B +:10075000E6AD3AAE39AF3812030F7C182290FFF2A3 +:10076000E0FC78828683088682ECF07880E6AD3AF9 +:10077000AE39AF3812030F7C00228C378D36788269 +:10078000EDF608ECF6EDFEECFD7F019000051201A0 +:10079000EC7881F67882E6FD08E6FCEDFEECFD7F64 +:1007A000019000041201EC540FFC7D811217467871 +:1007B00081E670037C082290FFF0E054FEF090FF89 +:1007C000F0E054FDF0801B7882E6FD08E6FCEDFECB +:1007D000ECFD7F0190000812020E25E090FFF3F07F +:1007E000805B7882E6FD08E6FCEDFEECFD7F019083 +:1007F000000612020E54FE90FFF3F080217882E68C +:10080000FD08E6FCEDFEECFD7F0190000812020EF3 +:10081000FAEB90FFF1F01208BF40037C18227882B7 +:10082000E6FD08E6FCEDFEECFD7F019000081202FB +:100830000E90FFF1F01208BF40037C18227883E687 +:10084000240AF618E63400F6788076007881E624EB +:10085000FFFCE434FFFD7880E67F00FEECD39EEFE2 +:100860006480CD64809D402178828683088682E002 +:1008700090FFF1F01208BF40037C182278800678C0 +:100880008306E61870010680C390FFF0E04401F093 +:1008900078828683088682E090FFF1F01208BF40DC +:1008A000037C18227C002290FFF0E020E71290FFEA +:1008B000F0E030E50990FFF0E04420F0C32280E74B +:1008C000D32290FFF0E020E31290FFF0E030E50942 +:1008D00090FFF0E04420F0C32280E7D3228C428DC9 +:1008E000417C00ED54F0FDEC7003ED643070057553 +:1008F0003E038003753E04AC3E120F69758300858C +:100900008340E541540FF53FE5407004E53F640343 +:100910007035E53E24FD75F00AA42402F582E43426 +:10092000FCF583E030E60512104B8019E53E249D6E +:10093000F8C654FBF678A9E62405F58218E63400DB +:10094000F583740FF08059E5407004E53F6404704E +:1009500048E53E24FD75F00AA42402F582E434FC47 +:10096000F583E030E507AC42AD41121C3CE5423076 +:10097000E21578ADE630E00F78ADE630E109E4FF4E +:1009800004FE7C041231FB78A9E62406F58218E601 +:100990003400F583740FF08007E4FC7DEE121C3CFC +:1009A000C203221230E6120F6978A9E62406F58206 +:1009B00018E63400F583E090FC38F078A9E62405C9 +:1009C000F58218E63400F583E090FC39F0C2037D2F +:1009D000027C00122526123169221230E67895EC4D +:1009E000F6EC249DF8E630E1077C131225BF800F5A +:1009F00090FC39E0FD7895E6FC1213C81225BF1271 +:100A00003169221230E67895ECF67D00120F09125A +:100A100025BF123169221230E67895ECF6EC249D60 +:100A2000F8E630E2077C131225BF801B7895E62498 +:100A30009DF8E620E1077C121225BF800A7895E632 +:100A4000FC1213EC1225BF123169221230E67895A0 +:100A5000ECF6EC249DF8E620E2077C111225BF801D +:100A60000A7895E6FC1214ED1225BF1231692212A4 +:100A700030E67895ECF6120F6978A9E62409F5823C +:100A800018E63400F583E090FC3FF078A9E6240AEC +:100A9000F58218E63400F583E090FC40F078A9E692 +:100AA0002403F58218E63400F583E0FC78A9E624F7 +:100AB00004F58218E63400F583E0F56278A9E624AF +:100AC00002F58218E63400F583E0F5638C61E4EC0E +:100AD000333354017895F66008E56230E103789588 +:100AE000067895E690FC41F078A7E62402F5821896 +:100AF000E63400F583E0FDA3E0540CFCED54E68CF5 +:100B000065F564E56130E503436501E56220E50EC6 +:100B1000E561547F7008E56120E703436502E56104 +:100B200030E303436510E56130E203436520E5618E +:100B300054036003436540E56130E103436580E5AC +:100B40006130E403436401E56130E603436408E592 +:100B50006220E40EE561547F7008E56120E70343FD +:100B600064105365FB536479AD64E56590FC3ACD40 +:100B7000F0A3CDF0E56330E30DE5635430C4540FCA +:100B800090FC3DF08005E490FC3DF0E5635403905B +:100B9000FC3CF0E5635404C31390FC3EF090FC3C35 +:100BA000E0700E7D357EFC7F01740190000912011A +:100BB0004278A9E62408F58218E63400F583E07C43 +:100BC00000FD78A9E62407F58218E63400F583E0F5 +:100BD0007F004CFEEF4D90FC38F0A3CEF0CEC20368 +:100BE0007D0A7C00122526123169221230E67895A2 +:100BF000ECF6789A76010876FC0876387897760CC9 +:100C0000789A1204651202147898CBF6CB08F67F16 +:100C100000EF24EA401FE4EF25E090352CFD93CD52 +:100C200004937899667003ED1866700678977600DD +:100C300080030F80DC7896EFF6789A1204659000B6 +:100C40000212020E7898CBF6CB08F65404CB5486E9 +:100C50004B60047897760B7899E630E313789A1214 +:100C600004659000051201EC24FB50047897760D82 +:100C70007899E654C07D0064C04D70047897760B77 +:100C8000789A1204659000041201EC24FC50047858 +:100C900097760F789A1204659000061201EC24FDF5 +:100CA00050047897760E789A120465900009120124 +:100CB000EC24FD50047897760A7897E6702A7895A8 +:100CC000E6FC120F69789A12046578A7E6F978A60F +:100CD000E6FA7B01740A780012033FC2037895E6B6 +:100CE000FC1211077897ECF67897E6FC1225BF12F4 +:100CF0003169221230E67895ECF6120F697895E6A4 +:100D000024FD75F00AA42414F582E434FCF583ACC8 +:100D100082AD8378A68683088682ECF9EDFA7B0A99 +:100D200078011203A7C2037895E6FC12110712316D +:100D300069228D2B8C2AED60407527017529487535 +:100D400028FFE52A24FDFCE434FFFDEC7C0325E0CC +:100D5000CD33CDDCF9FCE5292CF529E5283DF52836 +:100D6000AD29AE28AF277480900006120317748057 +:100D7000900002120317120FB7E52B14603B752782 +:100D8000017529087528FFE52A24FDFCE434FFFDE0 +:100D9000EC7C0325E0CD33CDDCF9FCE5292CF529ED +:100DA000E5283DF528AD29AE28AF27E490000612CE +:100DB0000317E4900002120317221230E67895EC34 +:100DC000F6EC249DF8E630E2097895E6FC1214ED85 +:100DD000D2007895E6FC120F697896760090FC397F +:100DE000E030E704789676017896E6FD7895E6FCA3 +:100DF000120D2FC2033000077895E6FC1213EC7C2D +:100E0000001225BF1231692278A9E62404F5821860 +:100E1000E63400F583E04401F078A9E62404F58285 +:100E200018E63400F583E030E00280ED78A9E6248E +:100E30000BF58218E63400F583E054F8F078A9E663 +:100E40002402F58218E63400F583E04480F022C2E3 +:100E5000038C58120F6978A68683088682795D7A9A +:100E6000357B0A78011203F5120E05AC587D02128B +:100E70000D2FC203AC58121107228D538E528F5181 +:100E80008C50120F69754F0078A9E62405F5821879 +:100E9000E63400F583E020E41FE54F24F640190511 +:100EA0004FC2037C181232A990FF93E04401F0B2C4 +:100EB000B3AC50120F6980D078A9E62405F58218EA +:100EC000E63400F583E020E405C2037C022278A921 +:100ED000E62405F58218E63400F583E0540F601629 +:100EE00078A9E62405F58218E63400F583E0540F6E +:100EF000F0C2037C012278A88683088682E0AD5385 +:100F0000AE52AF5112030FC2037C00228D318C30E0 +:100F10001214EDE531600FE530B4030A7C011224B0 +:100F2000EE7C811224EEAC30120F69E531601A7844 +:100F3000AA8683088682E054E7F0A3A3A3A3E05423 +:100F4000E7F0AC307D02120D2F78A68683088682EA +:100F500079677A357B0A78011203F5C203E53024FC +:100F60009DF8C654FDF6AC30121107228C263003D2 +:100F70000512324880F87C0A12315BD203E5262440 +:100F8000FD78A3F6700778AA76FF0876E078A3E6E6 +:100F900075F010A4ADF0FC24A078A9F6ED34FF188C +:100FA000F678A3E675F00AA42400FCE434FCFD788E +:100FB000A6EDF608ECF61231F42278A9E62402F543 +:100FC0008218E63400F583E030E72278A9E62402AF +:100FD000F58218E63400F583E0547FF078A9E62422 +:100FE00002F58218E63400F583E04480F02278AA06 +:100FF0008683088682E0547FF0AD83E5822404FC7A +:10100000E43D8C82F583E0547FF078A9E6240BF56B +:101010008218E63400F583E054F8F078ABE624015A +:10102000F58218E63400F583E04403F078ABE6245B +:1010300005F58218E63400F583E04403F078A9E66C +:101040002405F58218E63400F583740FF02278AA9F +:101050008683088682E0543FF0AD83E5822404FC59 +:10106000E43D8C82F583E0543FF078A3E624A4F8B5 +:10107000E6FC78ABE62401F58218E63400F583EC53 +:10108000F078A3E624A4F8E6FC78ABE62405F58224 +:1010900018E63400F583ECF078A9E6240BF5821805 +:1010A000E63400F583E054FB4402F52678A7E624F5 +:1010B00002F58218E63400F583E030E503432601AB +:1010C00078A9E62405F58218E63400F583E030E0DF +:1010D00003120FB7E526FC78A9E6240BF58218E683 +:1010E0003400F583ECF078A9E62405F58218E6349F +:1010F00000F583740FF078AA8683088682E0448026 +:10110000F0A3A3A3A3E04480F0228C2A120F6978F5 +:10111000A7E62408F58218E63400F583E0FC78A9F8 +:10112000E6240AF58218E63400F583ECF078A7E6A9 +:101130002407F58218E63400F583E0FC78A9E6245C +:1011400009F58218E63400F583ECF078A68683086A +:101150008682E0FDA3E0FCEDFE78A9E62408F58296 +:1011600018E63400F583EEF0ECFE78A9E62407F5E6 +:101170008218E63400F583EEF08C298D28C3EC94B8 +:1011800005ED940C400575277C8033D3E529940147 +:10119000E5289403400575273C8023D3E5299481F5 +:1011A000E528940140057527188013D3E52994603C +:1011B000E5289400400575270C8003752708AF27A4 +:1011C000E4EF547C4483FF8F27E527FC78ABE624CB +:1011D00001F58218E63400F583ECF0E527FC78ABE6 +:1011E000E62405F58218E63400F583ECF0E527FCEB +:1011F00078A3E624A4F8ECF678A9E62402F5821890 +:10120000E63400F583E0F52778A7E62402F5821896 +:10121000E63400F583A3E030E3175327C778A7E649 +:101220002405F58218E63400F583E09035589342A2 +:10123000275327FB78A7E62406F58218E63400F545 +:1012400083E060034327045327FC78A7E62404F5D2 +:101250008218E63400F583E04227432780E527FC27 +:1012600078A9E62402F58218E63400F583ECF078DC +:10127000A9E62404F58218E63400F583E0F5277822 +:10128000A7E62402F58218E63400F583A3E030E1F6 +:10129000055327DF800343272078A7E62402F58241 +:1012A00018E63400F583E030E4055327EF8003436C +:1012B000271078A7E62409F58218E63400F583E0C4 +:1012C000B40203432702E527FC78A9E62404F5824B +:1012D00018E63400F583ECF078A9E62403F58218CB +:1012E000E63400F583E0F52778A7E62409F58218AF +:1012F000E63400F583E0700553277F8003432780A1 +:1013000078A7E62402F58218E63400F583A3E030DE +:10131000E00543272080035327DF78A7E62402F562 +:101320008218E63400F583E030E30543274080036C +:101330005327BF78A7E62402F58218E63400F58328 +:10134000E030E00543271080035327EF78A7E62419 +:1013500002F58218E63400F583A3E030E405432764 +:101360000880035327F778A7E62402F58218E634AD +:1013700000F583A3E030E50543270480035327FBF2 +:1013800078A7E62402F58218E63400F583A3E0305E +:10139000E60543270180035327FE78A7E62402F5DC +:1013A0008218E63400F583A3E030E7054327028086 +:1013B000035327FDE527FC78A9E62403F58218E608 +:1013C0003400F583ECF0C2037C00228D278C26EDDF +:1013D00054031460037C1022E527547C24FC400352 +:1013E0007C0B22E526249DF8C64402F67C00228C64 +:1013F00030120F69E530249DF8E620E24FAC307DD5 +:1014000002120D2FE53024FE4428FC78AA868308BA +:101410008682ECF0AF83E5822404FEE43FFFEC8E8D +:10142000828F83F07C038C2CE52CFC78ABE62401C6 +:10143000F58218E63400F583ECF0E52CFC78ABE699 +:101440002405F58218E63400F583ECF0752D01755E +:101450002F48752EFFE53024FDFCE434FFFDEC7CC5 +:101460000325E0CD33CDDCF9FCE52F2CF52FE52E5F +:101470003DF52E78ABE62404F58218E63400F583BA +:10148000E054E7F52CAD2FAE2EAF2DE49000021204 +:101490000317E49000061203171201E630E5034338 +:1014A0002C10E52CFC78ABE62404F58218E6340019 +:1014B000F583ECF012104B78A9E62406F58218E6C5 +:1014C0003400F583E0C203FCE530249DF8C64404F3 +:1014D000F68C2CE530540FC454F07E00FFEEEF4440 +:1014E000047D00FFEC4EFCED4FFD121CA77C00229A +:1014F0008C2F120F69120FEB78AA8683088682E080 +:101500005408F0A3A3A3A3E05408F0AC2F7D02126B +:101510000D2FC203E52F249DF8C654FBF67C002254 +:101520001230E67896ECF6EC249DF8E630E10A7D80 +:10153000007C131225261231697896E6249DF8C6A0 +:101540004401F67896E6FC120F697896E624FD755C +:10155000F00AA42414F582E434FCF58378A6E6FAB4 +:1015600008E6F97B0A78011203A778A68683088625 +:101570008279677A357B0A78011203F5120FB7C2B8 +:10158000037896E6FC1211077895ECF6EC600A7D7C +:10159000007C081225261231697896E6FC120F6944 +:1015A00078A9E62404F58218E63400F583E04410B7 +:1015B00054DFFC78A9E62404F58218E63400F583AC +:1015C000ECF07895ECF6C2037CC81232A97896E666 +:1015D000FC120F6978A9E62404F58218E63400F5B8 +:1015E00083E054EFF0C2037CC81232A97896E6FC7F +:1015F000120F6978A9E62404F58218E63400F58311 +:10160000E04410F0C2037CC81232A97896E6FC12BE +:101610000F6978A9E62404F58218E63400F583E022 +:101620004420F0C2037CF01232A97896E6FC120F37 +:101630006978A9E62405F58218E63400F583E030E0 +:10164000E415C2037896E644107F00FE7C07123151 +:10165000FB12316902171478A9E62404F58218E612 +:101660003400F583E054CFF0C2037CC81232A9786D +:1016700096E6FC120F6978A9E62404F58218E63490 +:1016800000F583E04430F0C2037CF01232A9789672 +:10169000E6FC120F6978A9E62405F58218E6340005 +:1016A000F583E030E414C2037896E644107F00FE30 +:1016B0007C071231FB123169805D78A9E62404F5BC +:1016C0008218E63400F583E054EFF078A9E62404AC +:1016D000F58218E63400F583E054DFF07896E624CE +:1016E000FD75F00AA42414F582E434FCF583AC8281 +:1016F000AD8378A68683088682ECF9EDFA7B0A78BA +:10170000011203A7C2037896E6FC1211077D007C44 +:101710000B122526123169221230E6E490FC39F0D2 +:101720007D027C00122526123169221230E67C00EF +:101730001225BF12316922743C90FBE0F0743E9098 +:10174000FBE0F0E490FC28F0228D358C34ECB40101 +:10175000028003D340028028B402028003D34008F1 +:10176000A835C625E0F68018B404028003D3400AE9 +:10177000A835C625E025E0F68006A835760080006D +:10178000228C3C8D3BEDFEECFD7F01756606756796 +:101790000090FC2912046E1201E6B480028006D388 +:1017A000500302184790FC29120480900003120194 +:1017B000EC54F0B430028003D3405F90FC29120453 +:1017C0008090000812020EFAFDEBFE7F0190FC2CC7 +:1017D00012046EEECD903571FCE493FF740193FE1C +:1017E000F9EFFA7B01EAFFE9FEECC39EED9F40258D +:1017F000903573E493FD740193FCEDFEECFD7F01E5 +:10180000EECDFC90FC2EE0D39C90FC2DE09D50058D +:101810007566808033121965802EB460028003D310 +:10182000400BAC3CAD3B1207778C66801BB41003B9 +:10183000B34010C3B42003B34009C3B440028003D3 +:10184000D3400075668180008075B481028003D327 +:10185000406B90FC291204809000031201EC54F0BC +:10186000B430028003D3401D90FC29120480900004 +:101870000812020EFAFDEBFE7F0190FC2F12046E9F +:101880001218CF8036B460028003D34013753A67D4 +:10189000E4F539F538AC3CAD3B1205D38C66801BC2 +:1018A000B41003B34010C3B42003B34009C3B44021 +:1018B000028003D34000756681800080028000E5CD +:1018C00066FC90FC29120480EC900002120317AC15 +:1018D000672290FC291204809000041201EC60043D +:1018E00074018001E4A2E0920190FC29120480EDD1 +:1018F0002403FD50010E90FC2C12046E90FC291262 +:1019000004809000051201ECF5679000041201ECD0 +:10191000540FFC7D67121746E56770047566082250 +:10192000756600788476007884E6C39567503890B1 +:10193000FC2F1204801201E6FC90FC2C120480ECB7 +:1019400012030F30010E90FC31E004F090FC307077 +:1019500003E004F078840690FC2EE004F090FC2D67 +:101960007003E004F080C02290FC2AE0FDA3E0FCBC +:10197000EDFEECFD7F01ED240AFD50010E90FC32DE +:1019800012046E90FC291204809000041201EC54A1 +:101990000FB401028003D3401790FC321204800D73 +:1019A000ED70010E90FC2F12046E78887601804E47 +:1019B000B402028003D3401990FC32120480ED245B +:1019C00002FD50010E90FC2F12046E788876028082 +:1019D0002DB404028003D3401990FC32120480ED30 +:1019E0002404FD50010E90FC2F12046E78887604BA +:1019F000800CB400028003D340007566082290FC7E +:101A0000291204809000051201ECF56778857600B4 +:101A10007885E6C395674003021ACD78867600780C +:101A200086E6C3788896507690FC2C1204801201CA +:101A3000E6FC90FC321204891201E0F45CFC120115 +:101A4000E0F890FC2F120480E8C0E01201E6C8D054 +:101A5000E0C8584CFC90FC2C120480EC12030F7868 +:101A600087ECF690FC31E004F090FC307003E00469 +:101A7000F009E970010A90FC3212047790FC2912F7 +:101A800004809000041201EC30E40E90FC2EE0047F +:101A9000F090FC2D7003E004F07886068081788851 +:101AA000E6FDE4FEFFEECDFC90FC31E02CF090FC76 +:101AB00030E03DF07888E6FDE4FEFFEECDFC90FCE2 +:101AC00034E02CF090FC33E03DF0788506021A0DEE +:101AD00075660022E53D053D047002B2B022C0E00B +:101AE000C0F0C082C083C0D0E8C0E0E9C0E0EAC076 +:101AF000E0EBC0E0ECC0E0EDC0E0EEC0E0EFC0E045 +:101B000090FF92E01201B71B29301B29321B383895 +:101B10001B4A3A1B5C3E1B74441B68461B80501BCF +:101B2000C2521BA1541BE35600001C0490FF92E01C +:101B30007F00FE7C011231FB021C14E4FF04FE7CDA +:101B4000031231FB742090FFFEF0021C14E4FF042A +:101B5000FE7C021231FB744090FFFEF0021C14E484 +:101B6000FF04FE7C041231FB021C14E4FF04FE7C23 +:101B7000051231FB021C14E4FF04FE7C061231FB4B +:101B8000021C1490FFA5E07D0090FBF8CDF0A3CDE2 +:101B9000F090FBF9E0FCF58390FBF8E04433FD1294 +:101BA0001CA7807390FFB5E07D0090FBFACDF0A3F9 +:101BB000CDF090FBFBE0FCF58390FBFAE04443FDA5 +:101BC000121CA7805290FFA6E07D0090FBFCCDF098 +:101BD000A3CDF090FBFDE0FCF58390FBFCE04434EA +:101BE000FD121CA7803190FFB6E07D0090FBFECD7A +:101BF000F0A3CDF090FBFFE0FCF58390FBFEE0440A +:101C000044FD121CA7801090FF92E07D00FCED4483 +:101C1000AAFD121CA78000E490FF92F0D0E0FFD054 +:101C2000E0FED0E0FDD0E0FCD0E0FBD0E0FAD0E078 +:101C3000F9D0E0F8D0D0D083D082D0F0D0E0320517 +:101C400081058105810581A881181818EDF608EC39 +:101C5000F690FF5AE020E70280F790FF59E07D0000 +:101C6000A88118CDF6CD08F67D03A881E618FCE61C +:101C7000CC25E0CC33CCDDF9CCF6CC08F6A8811825 +:101C8000E644F8F6A881181818E6FD08E6FCA881D5 +:101C9000188683088682EDF0A3ECF0740290FF5A58 +:101CA000F0158115811581158122E5812405F581C5 +:101CB000E4A88118F6A88118181818EDF608ECF6B3 +:101CC00090FBF5E024F85003021DC8E4A881181821 +:101CD000F6A88118E6FEA88118181818E6FD08E68F +:101CE000FC7F00EF24F8404DE4EF25E0247DF582F1 +:101CF000E434FCF583E0FBA3E06C7003FAEB6D7059 +:101D0000097401A8811818F6802BE4EF25E0247DE2 +:101D1000F582E434FCF5837A00E054F0CCF8CCCDC5 +:101D2000F9CDFB7800E954F0F9EA687002EB6970CC +:101D3000010E0F80AEA88118EEF6A88118181818A9 +:101D4000EDF608ECF6A881EFF6A8811818E6707990 +:101D5000A88118E624F74071A88118181818E654CD +:101D60000FA881F664046017A881E664036010A8D8 +:101D70008118181818E6FD08E6FC121C3C804A7C05 +:101D80000A12315BA88118181818E6FD08E6FC90C5 +:101D9000FBF4E025E0247DF582E434FCF583EDF0EE +:101DA000A3ECF090FBF4E0FFE4EF045407FF90FB9A +:101DB000F4F090FBF5E004F01231F490FBF6E070E3 +:101DC00008E4FEFF7C0F1231FB802790FBF7E00454 +:101DD000F0543F701D90FBF7E044FE7D00FC90FB4B +:101DE000F4E025E0247DF582E434FCF583EDF0A3F6 +:101DF000ECF0E58124FBF58122788B7600788C76F7 +:101E000000740190FBF6F01230E690FBF5E06057AD +:101E10007C0A12315B90FBF3E025E0247DF582E43F +:101E200034FCF583E0FDA3E0FC90FBF3E025E02427 +:101E30007DF582E434FCF583E4F0A3F090FBF3E05D +:101E4000FFE4EF045407FF90FBF3F090FBF5E01480 +:101E5000F07889EDF608ECF61231F47889E6FD08A1 +:101E6000E6FC1208DA80A312324890FF93E04401A6 +:101E7000F0B2B3788B06B60011788B7600788CE6DA +:101E8000F40404A2E092B4788CF6021E07E490FBFE +:101E9000F6F090FBF5E07D00FCED44CFFD121C3C1C +:101EA000123169221230E6E5706449456F60159081 +:101EB000FF83E0540F7D00D39570ED956F500512B0 +:101EC0002F2F8003122FFF123169221230E6E570A6 +:101ED0006449456F6005123039800E90FF80E04400 +:101EE00008F090FF83E0547FF0123169221230E64F +:101EF0008C54EC54F0B41015756A357569FC75682E +:101F000001E56A2403F56AE5693400F569E4F557EB +:101F1000F556E556C394015027E554540FFCAD6ABD +:101F2000AE69AF68120E778C55EC60028012056ABC +:101F3000E56A700205690557E5577002055680D2BB +:101F4000E554540F249DF8C654FEF6E554540F7F13 +:101F500000FE7C121231FBE5551470097D007C09EE +:101F60001225268007AD577C0012252612316922E2 +:101F70001230E690FFFCE04402F090FF00E030E712 +:101F80001390FF83E04480F0436D8090FFFCE044B9 +:101F900001F0801190FF82E04408F0536D7F90FFC4 +:101FA000FCE054FEF090FF81E04480F01225D990CF +:101FB000FFFEE04405F090FFFCE054FDF0123169B3 +:101FC000221230E67C011232A978ADE64402F674A2 +:101FD000FEFC04FD121CA790FF5AE030E70280F7D8 +:101FE000E4F54E754D10AC4EAD4DE54E154E7002FC +:101FF000154DEC4D600280EE4387011231692212CB +:1020000030E67C0212317578ADE654FDF612316986 +:10201000221230E678ADE630E02C78ADE630E126ED +:1020200078ADE6FCF58318E644F0FD121C3C90FF09 +:10203000FCE04420F07C021232A978ADE654FDF6B3 +:10204000741A90FFFEF078ADE6FCF58318E644F1D3 +:10205000FD121C3C12316922756D0090FFFFE0609B +:1020600003436D01756E00E4F56CF56BE4F56F7577 +:102070007049748490FF82F0748490FF80F07480C3 +:1020800090FF58F0748090FF5AF0AD46AF457E0047 +:10209000EE24FE5003022124E4EE75F007A4247F11 +:1020A000F582E434F8F583E0FFE4EF5480FDE4EFDB +:1020B000540F14FFED6038E4EF75F008A42448F5E0 +:1020C00082E434FFF5837490F0E4EF75F008A42403 +:1020D0004AF582E434FFF5837480F0E4EF75F0088C +:1020E000A4244EF582E434FFF5837480F08034E458 +:1020F000EF75F008A42408F582E434FFF5837490AA +:10210000F0E4EF75F008A4240AF582E434FFF583C7 +:10211000E4F0E4EF75F008A4240EF582E434FFF552 +:1021200083E4F00E02208D8D468E448F45747F909F +:10213000FFFDF0749090FFFCF0228C58EC24F650D8 +:1021400006E5582437FC22E5582430FC22122523CA +:10215000EC700302225E755C03AE5B7F00E55C15EC +:102160005C6480247F5035EF2400F582E434FBF575 +:1021700083E0FE24FE501EEF7D00FCE4FB7474C37C +:102180009CFAEB9DFBEE7D00FCEAC39CED6480CBEA +:1021900064809B50028005EF2EFF80C18E5B8F5ABA +:1021A000E55C6480247F500302225EE55A248E5051 +:1021B0000302225E855A5D755B00AE5AAF5B9035B7 +:1021C0009CE493F55CE55C155C6480247F5018EE1C +:1021D0002400F582E434FBF583E0FCEF90359C931A +:1021E0006C70040E0F80DE8E5A8F5BE55C64802479 +:1021F0007F406E755E017560E8755FFFE55D2402E6 +:10220000F55A755C07E55C334057AD60AE5FAF5E75 +:10221000E55CF5823395E0F5831201ECC4540FFCC4 +:10222000122137E55A2400F582E434FBF583ECF003 +:10223000055A055AAD60AE5FAF5EE55CF582339539 +:10224000E0F5831201EC540FFC122137E55A24000B +:10225000F582E434FBF583ECF0055A055A155C80F1 +:10226000A4740290F851F090F86B79757A357B2759 +:1022700078011203F5756A357569FC756801E4909B +:10228000FF83F0748090FF81F0755902E55975F075 +:1022900007A4247FF582E434F8F583E0788FF6FC18 +:1022A000540F14FC788FECF6E55975F007A42481DF +:1022B000F582E434F8F583E0789276FD0876E8FC60 +:1022C000788FE675F008A42448F582E434FFF5839E +:1022D000E4F0788FE675F008A4244FF582E434FF2B +:1022E000F583ECF07892E6FF08E67E03CFC313CFC8 +:1022F00013DEF9FE788FE675F008A42449F582E430 +:1023000034FFF583EEF0788FE675F008A4244AF5E3 +:1023100082E434FFF5837480F07890ECF67D0078E9 +:1023200093E62CF618E63DF67892E6FD08E67C0387 +:10233000CDC313CD13DCF9FC788FE675F008A42427 +:102340004DF582E434FFF583ECF0788FE675F00804 +:10235000A4244EF582E434FFF583E4F07892E6FDA0 +:1023600008E6FC788FE6FF7E00EE24FE5003022490 +:10237000DDE4EE75F007A4247FF582E434F8F583FC +:10238000E0FFE4EF5480FAE4EF540F14FFE4EE753D +:10239000F007A42481F582E434F8F583E07890F620 +:1023A000E4EE1313548024F0F8E434FDF9E8FCE97A +:1023B000FD8A5AEA700302244AE4EF75F008A42467 +:1023C00048F582E434FFF583E4F07890E6FAE4EF30 +:1023D00075F008A4244FF582E434FFF583EAF0EDAC +:1023E000FBEC7A03CBC313CB13DAF9FAE4EF75F005 +:1023F00008A42449F582E434FFF583EAF07890E6F6 +:102400007B00FAEC2AFCED3BFDFBEC7A03CBC3131B +:10241000CB13DAF9FAE4EF75F008A4244DF582E461 +:1024200034FFF583EAF0E4EF75F008A4244AF5825E +:10243000E434FFF5837480F0E4EF75F008A4244ED3 +:10244000F582E434FFF5837480F00224D9E4EF755B +:10245000F008A42408F582E434FFF583E4F07890D2 +:10246000E6FAE4EF75F008A4240FF582E434FFF5F2 +:1024700083EAF0EDFBEC7A03CBC313CB13DAF9FA62 +:10248000E4EF75F008A42409F582E434FFF583EA4B +:10249000F07890E67B00FAEC2AFCED3BFDFBEC7A51 +:1024A00003CBC313CB13DAF9FAE4EF75F008A424D5 +:1024B0000DF582E434FFF583EAF0E4EF75F008A44B +:1024C000240AF582E434FFF583E4F0E4EF75F008C4 +:1024D000A4240EF582E434FFF583E4F00E022366B3 +:1024E0008E597892EDF608ECF6788FEFF6122055BB +:1024F000228C26EC30E718E526540F1475F008A45A +:102500002448F582E434FFF583E054DFF08016E5DB +:1025100026540F1475F008A42408F582E434FFF55E +:1025200083E054DFF0227C0022EC90FC37F08C2416 +:10253000ED2403F5257D00D39572ED95714003855B +:102540007225E52524B75009752503740290FC37E0 +:10255000F0AC2512302422E4F56CF56B12255D22D7 +:1025600090FC35E06573600E740490FC37F0E4F580 +:102570006B756C0380467D73E4FEFF79357AFC7BD6 +:10258000017405780012033FE56C2403F56CE56BDC +:102590003400F56BE56CD39572E56B95714006855B +:1025A000726C85716BD3E56C9448E56B9400400CBC +:1025B000740290FC37F0E4F56B756C03AC6C123070 +:1025C0002422EC90FC37F0E4F56CF56B8C32EC6077 +:1025D0000512301580057C001230242290FF93E014 +:1025E0004401F0B2B390FF04E0F54A90FF06E0FD2D +:1025F000A3E0ED7D00FC7D00FC90FF06E0FFA3E082 +:102600007E00FFE4FEEC4EFCED4FFDC3EC9448ED84 +:102610009400502290FF06E0FDA3E0ED7D00FC7DDC +:1026200000FC90FF06E0FFA3E07E00FFE4FEEC4E1E +:10263000FCED4FFD8004E4FD7C488C728D7190FFB1 +:1026400002E0FDA3E0ED7D00FC7D00FC90FF02E0D8 +:10265000FFA3E07E00FFE4FEEC4EF54CED4FF54BA2 +:10266000756A357569FC7568017D357EFC7F017979 +:1026700073E4FAFB7405780012033F754900E549DD +:1026800024FE4019AD6AAE69AF68E412030F054934 +:102690000DED70010E8D6A8E698F6880E1756A3567 +:1026A0007569FC75680190FF00E05460B400028019 +:1026B00006D35003022C6DE54A540FF549E54A5400 +:1026C00080A2E0920290FF01E0120181000B2C68D1 +:1026D00026E528032C68290F2C6829F22A262B8D41 +:1026E0002B902BD02C112C3FE56D30E70EE54C459F +:1026F0004B7008E572640245716003022C6A90FF1A +:1027000000E0541FB400028003D34029E54A60036F +:10271000022800AD6AAE69AF68740112030F78AD8C +:10272000E630E00BAD6AAE69AF68740212030F7C4D +:102730000212302422B401028003D3401BE56D2035 +:10274000E107E54A6003022800E54A24FE5003023F +:1027500028007C0212302422B402028006D35003E7 +:102760000227FEE56D20E10DE54A6009E54A648037 +:102770006003022800AC4A1230AB4003022800E597 +:1027800049702530021190FF80E05408AD6AAE69AF +:10279000AF6812030F800F90FF82E05408AD6AAE5D +:1027A00069AF6812030F803D154930021DE5497578 +:1027B000F008A42448F582E434FFF583E05408AD22 +:1027C0006AAE69AF6812030F801BE54975F008A473 +:1027D0002408F582E434FFF583E05408AD6AAE695D +:1027E000AF6812030FAD6AAE69AF681201E6600B05 +:1027F000AD6AAE69AF68740112030F7C0212302417 +:10280000228000022C6AE56D20E706E572457160C2 +:1028100003022C6A90FF00E0541FB400028003D32F +:10282000401AE54C14454B7004E54A600302290C3C +:1028300078ADE654FEF67C0012302422B40102800A +:1028400003D3402AE56D20E108E56D20E00302296D +:102850000CE56D30E004E54A700BE56D30E109E50B +:102860004A24FE500302290C7C0012302422B402B8 +:10287000028006D3500302290AE54C454B6003024F +:10288000290CAC4A1230AB400302290CE56D20E163 +:1028900007E56D20E0028077E56D30E006E54960F0 +:1028A00002806CE549700F90FF82E054F7F090FFD2 +:1028B00080E054F7F022E549B401028003D34009D7 +:1028C0007D017C03120F098011B402028003D34002 +:1028D000097D017C04120F0980001549300215E5BD +:1028E0004975F008A42448F582E434FFF583E054E8 +:1028F000F7F08013E54975F008A42408F582E43464 +:10290000FFF583E054F7F07C0012302422800002AF +:102910002C6AE56D20E706E57245716003022C6ABA +:1029200090FF00E0541FB400028003D3401AE54C2E +:1029300014454B7004E54A60030229EF78ADE64484 +:1029400001F67C0012302422B401028003D3402916 +:10295000E56D20E108E56D20E0030229EFE56D302B +:10296000E004E549700BE56D30E108E54924FE50CF +:1029700002807F7C0012302422B402028003D34004 +:102980006FE54C454B60028069AC4A1230AB4002A7 +:102990008060E56D20E107E56D20E0028054E549A7 +:1029A000701430020990FF80E04408F0800790FF27 +:1029B00082E04408F022E56D30E13315493002151C +:1029C000E54975F008A42448F582E434FFF583E076 +:1029D0004408F08013E54975F008A42408F582E462 +:1029E00034FFF583E04408F07C001230242280029A +:1029F0008000022C6AE56D20E712E5724571700CCB +:102A0000E54A700890FF00E0541F6003022C6AE55D +:102A10004C90FFFFF090FFFFE06005436D018003E5 +:102A2000536DFE7C0012302422E56D30E70EE57216 +:102A30004571600890FF00E0541F6003022C6AADEE +:102A40004BE54CED7D00FC7D00FCBD0002800302E7 +:102A50002B88B401028003D34032E54A7005E54C6F +:102A6000FC6003022B8A756A407569F8756801D3AA +:102A7000E5729412E57194004006E4FD7C12800436 +:102A8000AC72AD718C708D6F12303922B40202803D +:102A900003D34059E54A6003022B8AE54CFC7027BA +:102AA000756A527569F8756801D3E5729419E57114 +:102AB00094004006E4FD7C198004AC72AD718C700A +:102AC0008D6F1230398025756A6B7569F8756801EC +:102AD000D3E5729427E57194004006E4FD7C2780DD +:102AE00004AC72AD718C708D6F12303922B4030258 +:102AF0008006D35003022B88E54CF549700F90FFF8 +:102B000004E0FDA3E04D6003022B8A801890FB02D5 +:102B1000E0FDA3E0FC90FF05E06C700790FF04E08F +:102B20006D60028068E4F570F56F7F00E54914C5BB +:102B300049600FEF2400F582E434FBF583E02FFFBA +:102B400080EA8F4AE54A2400F582E434FBF583E00D +:102B50007D00D39572ED95714006AC72AD71800F1A +:102B6000E54A2400F582E434FBF583E07D00FC8C2B +:102B7000708D6FE54A2400FCE434FBFDFEECFD7F24 +:102B8000018D6A8E698F68123039228000022C6AAA +:102B9000022C6AE56D30E719E5721445717012E593 +:102BA0004A700EE54C454B700890FF00E0541F60E2 +:102BB00003022C6AE56D20E008E56D20E103022C9C +:102BC0006A756A6EE4F569F568E4F56F04F57012EC +:102BD000303922E56D20E712E5724571700CE54A47 +:102BE000700890FF00E0541F6003022C6AE56D201E +:102BF000E007E56D20E1028074854C6EE56E70089B +:102C0000436D01536DFD8006536DFE436D027C00E4 +:102C100012302422E56D30E71AE572144571701305 +:102C2000E54A700FE54C454B700990FF00E0541FDA +:102C30001460028038E56D20E10280317C011230A1 +:102C40002422E56D20E715E5724571700FE54C45CE +:102C50004B700990FF00E0541F146002800FE56D77 +:102C600020E10280087C00123024228000022F2BF9 +:102C7000B440028006D35003022F2190FF01E09060 +:102C8000FC35F0E54A90FC36F0E490FC37F0E56A5C +:102C90002403F56AE5693400F569AD4BE54C856AB6 +:102CA00082856983CDF0A3CDF090FF01E01201B7DA +:102CB0002CD8012CFE022D28032D52042DA0052D09 +:102CC000DD062E03072E29082E55092E7B0B2EA17B +:102CD0000C2EB0802EB08100002F0EE56D20E7068F +:102CE0007C051225BF227D247E357F0279387AFC4F +:102CF0007B017408780012033F7D087C00122526B2 +:102D000022E56D20E7067C051225BF22E54AB403C3 +:102D1000004010B40500500BE54A7F00FE7C101205 +:102D200031FB227D007C0712252622E56D20E70677 +:102D30007C051225BF22E54AB403004010B405000B +:102D4000500BE54A7F00FE7C111231FB227D007C96 +:102D50000712252622E56D20E7067C051225BF22F5 +:102D6000E54AB405028003D3400AE4FF04FE7C0A6E +:102D70001231FB22B401028003D3400AE4FF04FEB7 +:102D80007C081231FB22B403004010B40500500B44 +:102D9000E54A7F00FE7C131231FB227D007C071286 +:102DA000252622E56D20E734D3E5729448E5719439 +:102DB000005006E572457170067C021225BF22E5BF +:102DC0004AB40103B3400BC3B403004009B4060086 +:102DD00050041230D1227C071225BF2212255D2219 +:102DE000E56D20E71DE54AB403004010B40500502E +:102DF0000BE54A7F00FE7C161231FB227C07122570 +:102E0000BF2212255D22E56D20E71DE54AB40300CF +:102E10004010B40500500BE54A7F00FE7C191231CA +:102E2000FB227C071225BF2212255D22E56D20E7DB +:102E300023748190FF93F0E54AB403004010B40579 +:102E400000500BE54A7F00FE7C171231FB227C0705 +:102E50001225BF2212255D22E56D20E71DE54AB44B +:102E600003004010B40500500BE54A7F00FE7C18BB +:102E70001231FB227C071225BF2212255D22E56D4F +:102E800020E71DE54AB403004010B40500500BE5EF +:102E90004A7F00FE7C151231FB227C071225BF22DF +:102EA00012255D22E56D20E7067C071225BF221260 +:102EB000255D22E56D30E72090FF00E0541F701083 +:102EC00090FF01E0B48005122554800312255D2295 +:102ED0007D007C051225262290FF00E0541F60062D +:102EE0007C051225BF22D3E5729448E57194005009 +:102EF0000BC3E5729407E571940050067C0312251C +:102F0000BF22E54AB405041230D1227C071225BF46 +:102F100022E56D30E7087D007C05122526227C0520 +:102F20001225BF22B420028003D340008000122F5C +:102F3000FF2275430090FF83E0540FD39543402454 +:102F4000E54324F0F582E434FEF583E0AD6AAE6932 +:102F5000AF6812030F05430DED70010E8D6A8E6987 +:102F60008F6880D1E5437D00FCC3E5709CF570E57A +:102F70006F9DF56FE570456F6006E490FF83F0226A +:102F800090FF82E04408F0E4F56F75704990FC35DD +:102F9000E0B405028003D3404090FC36E0F543B432 +:102FA00005028003D3400AE4FF04FE7C0B1231FBD0 +:102FB00022B401028003D3400AE4FF04FE7C09121C +:102FC00031FB22B403004010B40500500BE5437FF1 +:102FD00000FE7C141231FB2222B480004023B48214 +:102FE00000501E7C357DFC12177E7D008C6C8D6B35 +:102FF00090FC37E06005122FFF80057C0012302422 +:10300000222290FF83E0547FF090FF82E04408F09A +:1030100090FF80E04408F02290FF82E04408F090A6 +:10302000FF80E04408F0228C237D008C708D6F754A +:103030006A357569FC7568011230392290FF83E0AA +:10304000547FF0E5706449456F700122C3E57094C8 +:1030500008E56F94004015752108E5217D00FCC34B +:10306000E5709CF570E56F9DF56F8009857021E432 +:10307000F56F757049752200E522C395215026AD84 +:103080006AAE69AF681201E6FCE52224F8F582E435 +:1030900034FEF583ECF005220DED70010E8D6A8E85 +:1030A000698F6880D3E521547F90FF81F0228C489E +:1030B0007F00EF24FD4019E4EF75F007A4247FF5AD +:1030C00082E434F8F583E065487002D3220F80E291 +:1030D0008F47C32285727085716F90FF82E054F72D +:1030E000F090FF83E0547FF022C000C001C002C016 +:1030F00006C007E5782408F8860653067F7CFF1291 +:10310000315B7C007D00E57B6046FF90FD95E054DF +:103110007F6E700FC083C082A3E0FDA3E0FCA31507 +:103120007B8007A3A3A3DFE68026DF06D082D083BF +:10313000801EE0F8A3E0F9A3E0FAD082D083E8F0A3 +:10314000A3E9F0A3EAF0A3C083C082A3A3A380DA1B +:103150001231F4D007D006D002D001D0002285A8C9 +:103160007A75A888EC70027C3F8C7922E578240877 +:10317000F8760012324880FBC000C001C002C006D1 +:10318000C007AE047CFF12315BE57B6042FF90FD1F +:1031900095E0547F6E700BC083C082A3A3A3157B00 +:1031A0008007A3A3A3DFEA8026DF06D082D0838036 +:1031B000D8E0F8A3E0F9A3E0FAD082D083E8F0A346 +:1031C000E9F0A3EAF0A3C083C082A3A3A380DA78C6 +:1031D00008087918097C01E6547F6E70067600773E +:1031E00000800608090CBC08EE1231F4D007D006A6 +:1031F000D002D001D00022757900857AA822C0F0D3 +:10320000C082C083C3E57B24E8500512324880F4B5 +:10321000EC6031903523E493C39C4028C0047CFFCC +:1032200012315BD004430480E57B75F003A4249540 +:10323000F582E434FDF583ECF0EFA3F0EEA3F005A6 +:103240007B1231F4D083D082D0F022C0047C20D213 +:103250008CD28DD504FDD0042275A8007588007528 +:10326000B80075F00075D000E4F8900000F608B8DA +:1032700000FB020000C3ED940250047D037CE8ECE7 +:10328000F4FCEDF4FD0CBC00010D8C7F8D7E22C39F +:10329000EC94BCED940250047D077CD0ECF4FCED82 +:1032A000F4FD0CBC00010D8C7D8D7C22EC700122A4 +:1032B000C000E5782418F8A604E5782408F8C65478 +:1032C0007FF6E630E703D0002212324880F4C28C49 +:1032D000857C8C857D8AD28CC0E0C0D0C0F0C08255 +:1032E000C083C000C001C002C003C004C005C00646 +:1032F000C007121AD1E5782408F8E66024E578249E +:1033000010F8A681E57875F021A4248DF582E434C7 +:10331000FCF58378AEE58104C398F9E6F008A3D9FB +:10332000FA74082578F8057808E65480700CE5787A +:10333000B407F3780875780080EFE5782410F886F4 +:1033400081E57875F021A4248DF582E434FCF583C1 +:1033500078AEE58104C398F9E0F608A3D9FAD0075E +:10336000D006D005D004D003D002D001D000D08345 +:10337000D082D0F0D0D0D0E032C0E0C0D0C000C009 +:1033800001C002C28E857E8D857F8BD28E781979A1 +:10339000097A07E77004A600800BE6600816E6705D +:1033A00004E74480F70809DAEAE579601314F5794F +:1033B000700EE5782408F876001231F4D28CD28DA4 +:1033C000D002D001D000D0D0D0E0327581AD742AC7 +:1033D00090FF93F0757F30757EF8757D60757CF099 +:1033E00012053612347C12173490FF93E04401F03A +:1033F000B2B31234A612325680DA22C0007C01EC3D +:103400002408F8E660090CBC08F512324880EED0BA +:103410000022C0F0C082C083C000C006C007ED24F7 +:1034200010F876BCED75F021A4248DF582E434FC0F +:10343000F583C082C083A3A3E4780DF0A3D8FCEC8D +:10344000547F75F002A424EFF582E5F03434F5835F +:10345000E493FE740193F5828E83E493FE740193EA +:10346000FFD083D082EFF0A3EEF0ED2408F8EC4417 +:1034700080F6D007D006D000D083D082D0F022755D +:103480007800757B007A087918780876007700084C +:1034900009DAF8E478087480447FF674014410F582 +:1034A0008975B808D2ABD2A9227581ADD28ED28CE3 +:1034B000D2AFE57B6032FF90FD95E05480602478C8 +:1034C000087908E0547FFA7B00E6547FB502027B5E +:1034D000FF08D9F5EB700CEAF01233F8AD04AC023A +:1034E00012340FA3A3A3DFD212324880C57C017D22 +:1034F000002204F504E904ED04E104DD04D904E547 +:1035000004F1049D04A104CD04D104990499049903 +:1035100004D504B504AD04B104A904C104BD04B9C3 +:1035200004C504C904A5190103002200480200488B +:103530000E301420C81AD0180A0C05060203010226 +:103540000001CE0181010000C00080006000300059 +:1035500018001000080004000200010008183828B4 +:103560000C05100A0200000000000301100A02000E +:1035700000000000FBE0FBF209022700010200A0AE +:10358000320904000003FF0000000705810240002B +:103590000007050102400000070583030200012225 +:1035A0000354005500530042003300340031003012 +:1035B000002000200020002000200020002000200B +:0535C000000000000006 +:00000001FF diff --git a/firmware/ti_5052.fw.ihex b/firmware/ti_5052.fw.ihex new file mode 100644 index 0000000..b529e07 --- /dev/null +++ b/firmware/ti_5052.fw.ihex @@ -0,0 +1,862 @@ +:10000000C1350002001E021B32FFFFFFFFFF02325C +:100010006AFFFFFFFFFFFFFFFFFFFFFFFFFF02334E +:10002000157581C890FEF08583A012347DEC4D607B +:100030006A78A58003760018B896FA7879800376F6 +:100040000018B85FFA78208003760018B820FA907C +:10005000FEE5AE83AF8290FD001200A16005E4F0E2 +:10006000A380F690FEF0A88290FEF0A982E8C399E2 +:10007000500576000880F69000FF1200AA90010358 +:100080001200AA9001071200AA90010B1200C8905A +:1000900001111200C89001171200C875D000123368 +:1000A0006702011DEF65827003EE658322E493F819 +:1000B000740193F9740293FE740393F5828E83E8BE +:1000C00069700122E493F6A30880F4E493FC7401C0 +:1000D00093FD740293FE740393FF740493F8740504 +:1000E00093F58288831200A1700122E493A3A88370 +:1000F000A9828C838D82F0A3AC83AD8288838982B0 +:1001000080E3212104927A7A0492A6A80492FEF058 +:1001100004940494FBFB04990494FBFB04F904F994 +:1001200080FED0F030F00920F303F68010F7800D48 +:1001300030F10920F303F28004F38001F020F4048D +:10014000FCD0E0CC22CCC0E012015A02014BBC0032 +:1001500005D0F0ACF022C313DCFC020121BF000982 +:10016000ED258275F001F8E622BF010FED2582F53D +:1001700082EE3583F58375F004E022ED258275F07B +:1001800002F8E222D083D082F5F0C3E493A3C5F055 +:1001900095F0C0E0C3D0F0E493A395F04012A3A380 +:1001A000C3E5F033500205832582F58250020583B2 +:1001B000740193C0E0E493C0E022D083D082F5F0D4 +:1001C000E49370097401937004A3A3800C740293E8 +:1001D00065F06005A3A3A380E7740193C0E0E493F6 +:1001E000C0E02212025B0201F21202AF0201F2121F +:1001F00002D30201F230E00720E302E622E72230D8 +:10020000E10720E302E222E32230E202E022E4936B +:10021000221202D302021A1202AF02021AABF01229 +:100220000224CBC5F0CB2230E01020E306E6F5F047 +:1002300008E622E7F5F009E7192230E11020E3068D +:10024000E2F5F008E222E3F5F009E3192230E206D4 +:10025000E0F5F0A3E022E493F5F074019322BB00F3 +:1002600003740922BB010789828A83740422BB02BA +:100270000789828A83741022740A2202027BBB00DF +:1002800007E92582F8740122BB010DE92582F58278 +:10029000EA3583F583740422BB020DE92582F582D9 +:1002A000EA3583F583741022E92582F8740222026C +:1002B00002AFBF0005EDF8740122BF01078D828EE9 +:1002C00083740422BF02078D828E83741022EDF89E +:1002D0007402220202D3BF0007ED2582F8740122C6 +:1002E000BF010DED2582F582EE3583F5837404227E +:1002F000BF020DED2582F582EE3583F58374102261 +:10030000ED2582F8740222020307C0E012025B02AC +:10031000031FC0E01202AF02031FC0E01202D302AB +:10032000031F30E00B20E304D0E0F622D0E0F722F8 +:1003300030E10B20E304D0E0F222D0E0F322D0E061 +:10034000F022C9CDC9CACECACBCFCB120352EDF928 +:10035000EEFAEFFB22BB002FBF000AFAEDF8E7F63A +:100360000809DAFA22BF01128D828E83F802036F28 +:1003700009A3E7F0D8FA2202037AFAEDF8E7F208C7 +:1003800009DAFA22020384BB014DBF001489828A74 +:1003900083F9EDF802039608A3E0F6D9FA220203E6 +:1003A000A7BF01228D828E83FB08C9C582C9CAC539 +:1003B00083CAE0A3C9C582C9CAC583CAF0A3DBEA60 +:1003C000D8E8220203CA8D828E83F9EDF8E0F208A4 +:1003D000A3D9FA220203D4BB024DBF001289828A3C +:1003E00083F9EDF80203E608A3E493F6D9F922BFF6 +:1003F00001238D828E83FB08C9C582C9CAC583CA01 +:10040000E493A3C9C582C9CAC583CAF0A3DBE9D8EE +:10041000E72202041989828A83F9EDF8E493F2084D +:10042000A3D9F92202042ABF000DFAEDF8E3F60879 +:1004300009DAFA22020434BF01128D828E83F80297 +:10044000044109A3E3F0D8FA2202044CFAEDF8E3E0 +:10045000F20809DAFA22020456E6FB08E6FA08E690 +:10046000F904F61870010622E6FF08E6FE08E6FD2C +:1004700022EFF0A3EEF0A3EDF022EBF0A3EAF0A35D +:10048000E9F022E0FFA3E0FEA3E0FD22E0FBA3E011 +:10049000FAA3E0F9220000000000000004F9005B6C +:1004A00005730026059A00330A0B005B0A7700608B +:1004B0001552005B0CFB005B09AB005B09E2005BC3 +:1004C0000DC2005B0BF3005B0A1E005B0A53005B6E +:1004D000174A0033176000341E4D00431EF00044DD +:1004E000205D0044204B00471F1700471FBC004DF4 +:1004F000200D004F1F39005831F5005B7CCC7DFF8B +:10050000121CFE22749090FF91F090FFFCE020E717 +:100510002DC2AFAE59AF58755A20E55A14C55A606E +:1005200019E4FE7F05EE4FCE24FFCECF34FFCF601F +:1005300007E490FF92F080ED80E08E598F582212F0 +:1005400005017D077CB71232117D0F7C6E12322BB4 +:1005500078977A06E4F608DAFC7A061205CF7C036F +:10056000120E577C04120E5712218BE4FEFF7C0FF3 +:1005700012319AD2A822123085E490FD40F090FF0B +:10058000F0E030E408740190FD41F08005E490FD56 +:1005900041F07D0A7C001224B1123108221230850C +:1005A00090FD41E014700E90FFF0E04410F07C00EC +:1005B00012254A801990FD41E0700E90FFF0E05442 +:1005C000EFF07C0012254A80057C1712254A123173 +:1005D000082290FFF0E054ABF090FFF0E04420F0F0 +:1005E000228C378D36787CEDF608ECF6EDFEECFDCE +:1005F0007F019000051201EC787AF6787CE6FD0820 +:10060000E6FCEDFEECFD7F019000041201EC540FBE +:10061000FC7D7A12179D787AE6700DAD3AAE39AF4F +:1006200038E412030F7C082290FFF0E054FEF090B3 +:10063000FFF0E054FDF0801E787CE6FD08E6FCED5E +:10064000FEECFD7F0190000812020E25E0440190AF +:10065000FFF3F00206DB787CE6FD08E6FCEDFEEC3D +:10066000FD7F0190000612020E54FE90FFF3F08011 +:100670002B787CE6FD08E6FCEDFEECFD7F019000AA +:100680000812020EFAEB90FFF1F01208CA400DAD0D +:100690003AAE39AF38E412030F7C1822787CE6FDBD +:1006A00008E6FCEDFEECFD7F0190000812020E90C2 +:1006B000FFF1F01208CA400DAD3AAE39AF38E4127E +:1006C000030F7C1822787CE6FD08E6FCEDFEECFDCD +:1006D0007F0190000612020E440190FFF3F0787D36 +:1006E000E62403F618E63400F6787AE624FE50098C +:1006F00090FFF0E054FDF0800790FFF0E04402F03E +:10070000E490FFF1F0787B7600787AE624FFFCE451 +:1007100034FFFD787BE67F00FEECD39EEF6480CD56 +:1007200064809D402F1208AF400F787BE6AD3AAE53 +:1007300039AF3812030F7C182290FFF2E0FC787C6E +:100740008683088682ECF0787B06A3787CA68308F3 +:10075000A68280B51208AF400F787BE6AD3AAE397D +:10076000AF3812030F7C182290FFF2E0FC787C86F1 +:1007700083088682ECF0787AE6AD3AAE39AF38126B +:10078000030F7C00228C378D36787CEDF608ECF672 +:10079000EDFEECFD7F019000051201EC787BF67810 +:1007A0007CE6FD08E6FCEDFEECFD7F019000041206 +:1007B00001EC540FFC7D7B12179D787BE670037C67 +:1007C000082290FFF0E054FEF090FFF0E054FDF0BE +:1007D000801B787CE6FD08E6FCEDFEECFD7F0190D9 +:1007E000000812020E25E090FFF3F0805B787CE6B3 +:1007F000FD08E6FCEDFEECFD7F0190000612020E06 +:1008000054FE90FFF3F08021787CE6FD08E6FCEDD5 +:10081000FEECFD7F0190000812020EFAEB90FFF152 +:10082000F01208CA40037C1822787CE6FD08E6FC3A +:10083000EDFEECFD7F0190000812020E90FFF1F03A +:100840001208CA40037C1822787DE6240AF618E6CE +:100850003400F6787A7600787BE624FFFCE434FFF7 +:10086000FD787AE67F00FEECD39EEF6480CD648055 +:100870009D4021787C8683088682E090FFF1F0120B +:1008800008CA40037C1822787A06787D06E618703C +:10089000010680C390FFF0E04401F0787C86830875 +:1008A0008682E090FFF1F01208CA40037C18227C97 +:1008B000002290FFF0E020E71290FFF0E030E50921 +:1008C00090FFF0E04420F0C32280E7D32290FFF0B5 +:1008D000E020E31290FFF0E030E50990FFF0E04403 +:1008E00020F0C32280E7D3228C428D417C00ED545E +:1008F000F0FDEC7003ED64307005753E0380037508 +:100900003E04AC3E120F7C758300858340E5415464 +:100910000FF53FE5407004E53F64037035E53E2484 +:10092000FD75F00AA4240AF582E434FDF583E03075 +:10093000E6051210678019E53E2497F8C654FBF6C9 +:1009400078A3E62405F58218E63400F583740FF0E9 +:100950008059E5407004E53F64047048E53E24FD9D +:1009600075F00AA4240AF582E434FDF583E030E54D +:1009700007AC42AD41121C93E54230E21578A7E680 +:1009800030E00F78A7E630E109E4FF04FE7C0412B2 +:10099000319A78A3E62406F58218E63400F58374CC +:1009A0000FF08007E4FC7DEE121C93C2032212308C +:1009B00085120F7C78A3E62406F58218E63400F54C +:1009C00083E090FD40F078A3E62405F58218E63434 +:1009D00000F583E090FD41F0C2037D027C0012240B +:1009E000B112310822123085788FECF6EC2497F89A +:1009F000E630E1077C1312254A800F90FD41E0FDAF +:100A0000788FE6FC1213FD12254A123108221230AB +:100A100085788FECF67D00120F0B12254A123108F3 +:100A200022123085788FECF6EC2497F8E630E20756 +:100A30007C1312254A801B788FE62497F8E620E184 +:100A4000077C1212254A800A788FE6FC12142112C4 +:100A5000254A12310822123085788FECF6EC249763 +:100A6000F8E620E2077C1112254A800A788FE6FC1E +:100A700012152212254A12310822123085788FEC85 +:100A8000F6120F7C78A3E62409F58218E63400F507 +:100A900083E090FD47F078A3E6240AF58218E63457 +:100AA00000F583E090FD48F078A3E62403F5821872 +:100AB000E63400F583E0FC78A3E62404F58218E62A +:100AC0003400F583E0F55C78A3E62402F58218E6AD +:100AD0003400F583E0F55D8C5BE4EC33335401784E +:100AE0008FF66008E55C30E103788F06788FE6903A +:100AF000FD49F078A1E62402F58218E63400F5837A +:100B0000E0FDA3E0540CFCED54E68C5FF55EE55B84 +:100B100030E503435F01E55C20E50EE55B547F7043 +:100B200008E55B20E703435F02E55B30E303435FD7 +:100B300010E55B30E203435F20E55B540360034351 +:100B40005F40E55B30E103435F80E55B30E40343F6 +:100B50005E01E55B30E603435E08E55C20E40EE5FC +:100B60005B547F7008E55B20E703435E10535FFB37 +:100B7000535EF9AD5EE55F90FD42CDF0A3CDF0E5AB +:100B80005D30E30DE55D5430C4540F90FD45F080B9 +:100B900005E490FD45F0E55D540390FD44F0E55D0E +:100BA0005404C31390FD46F090FD44E0700E7D3D6B +:100BB0007EFD7F01740190000912014278A3E624B2 +:100BC00008F58218E63400F583E07C00FD78A3E6A2 +:100BD0002407F58218E63400F583E07F004CFEEF31 +:100BE0004D90FD40F0A3CEF0CEC2037D0A7C0012F2 +:100BF00024B112310822123085788FECF678947681 +:100C0000010876FD0876407891760C789412046598 +:100C10001202147892CBF6CB08F67F00EF24EB405B +:100C20001FE4EF25E09034BFFD93CD0493789366E5 +:100C30007003ED186670067891760080030F80DCF3 +:100C40007890EFF6789412046590000212020E7804 +:100C500092CBF6CB08F65404CB54064B6004789143 +:100C6000760B7893E630E3137894120465900005D0 +:100C70001201EC24FB50047891760D7893E654C071 +:100C80007D0064C04D70047891760B7894120465F1 +:100C90009000041201EC24FC50047891760F7894B3 +:100CA0001204659000061201EC24FD500478917640 +:100CB0000E78941204659000091201EC24FD500492 +:100CC0007891760A7891E6702A788FE6FC120F7C8C +:100CD000789412046578A1E6F978A0E6FA7B0174AD +:100CE0000A780012033FC203788FE6FC12112378C2 +:100CF00091ECF67891E6FC12254A12310822123066 +:100D000085788FECF6120F7C788FE624FD75F00A5B +:100D1000A4241CF582E434FDF583AC82AD8378A075 +:100D20008683088682ECF9EDFA7B0A78011203A724 +:100D3000C203788FE6FC121123123108228D2B8C0E +:100D40002AED60407527017529487528FFE52A249A +:100D5000FDFCE434FFFDEC7C0325E0CD33CDDCF974 +:100D6000FCE5292CF529E5283DF528AD29AE28AF6D +:100D700027748090000612031774809000021203FB +:100D800017120FD3E52B14603B75270175290875E1 +:100D900028FFE52A24FDFCE434FFFDEC7C0325E07C +:100DA000CD33CDDCF9FCE5292CF529E5283DF528E6 +:100DB000AD29AE28AF27E4900006120317E4900097 +:100DC0000212031722123085788FECF6EC2497F884 +:100DD000E630E209788FE6FC121522D200788FE621 +:100DE000FC120F7C7890760090FD41E030E70478AB +:100DF0009076017890E6FD788FE6FC120D3AC203FA +:100E0000300007788FE6FC1214217C0012254A126C +:100E100031082278A3E62404F58218E63400F5832D +:100E2000E04401F078A3E62404F58218E63400F5E6 +:100E300083E030E00280ED78A3E6240BF58218E62B +:100E40003400F583E054F8F078A3E62402F5821824 +:100E5000E63400F583E04480F022C2038C58120F80 +:100E60007C78A0868308868279EE7A347B0A7801C2 +:100E70001203F5120E10AC587D02120D3AC203ACEB +:100E800058121123228D538E528F518C50120F7C89 +:100E9000754F0078A3E62405F58218E63400F58343 +:100EA000E020E416E54F24F64010054FC2037C18FD +:100EB000123248AC50120F7C80D978A3E62405F595 +:100EC0008218E63400F583E020E405C2037C0222A8 +:100ED00078A3E62405F58218E63400F583E0540F84 +:100EE000601678A3E62405F58218E63400F583E061 +:100EF000540FF0C2037C012278A28683088682E028 +:100F0000AD53AE52AF5112030FC2037C00228D319C +:100F10008C30121522E5316020E530B4030C7C01E1 +:100F200012247C7C8112247C800FE530B4040A7C7E +:100F30000212247C7C8212247CAC30120F7CE531BE +:100F4000601A78A48683088682E054E7F0A3A3A3FE +:100F5000A3E054E7F0AC307D02120D3A78A086830E +:100F600008868279F87A347B0A78011203F5C20385 +:100F7000E5302497F8C654FDF6AC30121123228CCC +:100F8000263003051231E780F87C0A1230FAD203CA +:100F9000E52624FD789DF6700978A476FF0876E0B2 +:100FA000800778A476FF0876E2789DE675F010A4B5 +:100FB000ADF0FC24A078A3F6ED34FF18F6789DE69A +:100FC00075F00AA42408FCE434FDFD78A0EDF608D1 +:100FD000ECF61231932278A3E62402F58218E63467 +:100FE00000F583E030E72278A3E62402F58218E6D4 +:100FF0003400F583E0547FF078A3E62402F58218EC +:10100000E63400F583E04480F02278A486830886E5 +:1010100082E0547FF0AD83E5822404FCE43D8C82C1 +:10102000F583E0547FF078A3E6240BF58218E634CC +:1010300000F583E054F8F078A5E62401F58218E67F +:101040003400F583E04403F078A5E62405F5821822 +:10105000E63400F583E04403F078A3E62405F58246 +:1010600018E63400F583740FF02278A4868308868E +:1010700082E0543FF0AD83E5822404FCE43D8C82A1 +:10108000F583E0543FF0789DE6249EF8E6FC78A5D1 +:10109000E62401F58218E63400F583ECF0789DE64D +:1010A000249EF8E6FC78A5E62405F58218E63400CF +:1010B000F583ECF078A3E6240BF58218E63400F50E +:1010C00083E054FB4402F52678A1E62402F5821859 +:1010D000E63400F583E030E50343260178A3E624F7 +:1010E00005F58218E63400F583E030E003120FD3F3 +:1010F000E526FC78A3E6240BF58218E63400F58398 +:10110000ECF078A3E62405F58218E63400F5837444 +:101110000FF078A48683088682E04480F0A3A3A31E +:10112000A3E04480F0228C2A120F7C78A1E62408E8 +:10113000F58218E63400F583E0FC78A3E6240AF58E +:101140008218E63400F583ECF078A1E62407F582F6 +:1011500018E63400F583E0FC78A3E62409F582184C +:10116000E63400F583ECF078A08683088682E0FD03 +:10117000A3E0FCEDFE78A3E62408F58218E634002F +:10118000F583EEF0ECFE78A3E62407F58218E6344A +:1011900000F583EEF08C298D28C3EC9402ED9406C3 +:1011A000400575277C8033D3E5299481E528940197 +:1011B000400575273C8023D3E52994C0E528940099 +:1011C00040057527188013D3E5299430E52894004D +:1011D000400575270C8003752708AF27E4EF547C82 +:1011E0004483FF8F27E527FC78A5E62401F58218C4 +:1011F000E63400F583ECF0E527FC78A5E62405F558 +:101200008218E63400F583ECF0E527FC789DE624AF +:101210009EF8ECF678A3E62402F58218E63400F591 +:1012200083E0F52778A1E62402F58218E63400F57C +:1012300083A3E030E3175327C778A1E62405F5829E +:1012400018E63400F583E09034E993422778A1E66C +:101250002402F58218E63400F583E030E7054327E1 +:101260004080035327BF5327FB78A1E62406F5826D +:1012700018E63400F583E060034327045327FC7825 +:10128000A1E62404F58218E63400F583E042274302 +:101290002780E527FC78A3E62402F58218E63400CF +:1012A000F583ECF078A3E62404F58218E63400F523 +:1012B00083E0F52778A1E62402F58218E63400F5EC +:1012C00083A3E030E1055327DF800343272078A183 +:1012D000E62402F58218E63400F583E030E4055395 +:1012E00027EF800343271078A1E62409F58218E64A +:1012F0003400F583E0B40203432702E527FC78A31A +:10130000E62404F58218E63400F583ECF078A3E6D1 +:101310002403F58218E63400F583E0F52778A1E68A +:101320002409F58218E63400F583E0700553277F21 +:10133000800343278078A1E62402F58218E6340072 +:10134000F583A3E030E00543272080035327DF78AF +:10135000A1E62402F58218E63400F583E030E305C7 +:1013600043274080035327BF78A1E62402F5821863 +:10137000E63400F583E030E005432710800353276F +:10138000EF78A1E62402F58218E63400F583A3E0A5 +:1013900030E40543270880035327F778A1E62402A9 +:1013A000F58218E63400F583A3E030E50543270411 +:1013B00080035327FB78A1E62402F58218E6340067 +:1013C000F583A3E030E60543270180035327FE7829 +:1013D000A1E62402F58218E63400F583A3E030E7A5 +:1013E0000543270280035327FDE527FC78A3E62465 +:1013F00003F58218E63400F583ECF0C2037C00228A +:101400008D278C26ED54031460037C1022E52754AD +:101410007C24FC40037C0B22E5262497F8C644027A +:10142000F67C00228C30120F7CE5302497F8E62001 +:10143000E24FAC307D02120D3AE53024FE4428FC28 +:1014400078A48683088682ECF0AF83E5822404FECC +:10145000E43FFFEC8E828F83F07C038C2CE52CFC28 +:1014600078A5E62401F58218E63400F583ECF0E572 +:101470002CFC78A5E62405F58218E63400F583EC0B +:10148000F0752D01752F48752EFFE53024FDFCE425 +:1014900034FFFDEC7C0325E0CD33CDDCF9FCE52FFA +:1014A0002CF52FE52E3DF52E78A5E62404F58218BF +:1014B000E63400F583E054E7F52CAD2FAE2EAF2DCA +:1014C000E4900002120317E49000061203171201C1 +:1014D000E630E503432C10E52CFC78A5E62404F562 +:1014E0008218E63400F583ECF012106778A3E62446 +:1014F00006F58218E63400F583E0C203FCE53024EB +:1015000097F8C64404F68C2CE530540FC454F07E92 +:1015100000FFEEEF44047D00FFEC4EFCED4FFD12AA +:101520001CFE7C00228C2F120F7C12100778A486E0 +:1015300083088682E05408F0A3A3A3A3E05408F034 +:10154000AC2F7D02120D3AC203E52F2497F8C65442 +:10155000FBF67C00221230857890ECF6EC2497F8AC +:10156000E630E10A7D007C131224B1123108789034 +:10157000E62497F8C64401F67890E6FC120F7C78D2 +:1015800090E624FD75F00AA4241CF582E434FDF5F0 +:101590008378A0E6FA08E6F97B0A78011203A778B7 +:1015A000A0868308868279F87A347B0A7801120350 +:1015B000F5120FD3C2037890E6FC121123788FEC5A +:1015C000F6EC600A7D007C081224B1123108789094 +:1015D000E6FC120F7C78A3E62404F58218E63400BA +:1015E000F583E0441054DFFC78A3E62404F5821868 +:1015F000E63400F583ECF0788FECF6C2037CC81279 +:1016000032487890E6FC120F7C78A3E62404F58239 +:1016100018E63400F583E054EFF0C2037CC81232C0 +:10162000487890E6FC120F7C78A3E62404F5821833 +:10163000E63400F583E04410F0C2037CC81232485F +:101640007890E6FC120F7C78A3E62404F58218E675 +:101650003400F583E04420F0C2037CF01232487875 +:1016600090E6FC120F7C78A3E62405F58218E63498 +:1016700000F583E030E415C2037890E644107F0063 +:10168000FE7C0712319A12310802174978A3E6242A +:1016900004F58218E63400F583E054CFF0C2037CF1 +:1016A000C81232487890E6FC120F7C78A3E6240436 +:1016B000F58218E63400F583E04430F0C2037CF094 +:1016C0001232487890E6FC120F7C78A3E62405F5E8 +:1016D0008218E63400F583E030E414C2037890E623 +:1016E00044107F00FE7C0712319A123108805D7829 +:1016F000A3E62404F58218E63400F583E054EFF005 +:1017000078A3E62404F58218E63400F583E054DF7C +:10171000F07890E624FD75F00AA4241CF582E434E8 +:10172000FDF583AC82AD8378A08683088682ECF9D0 +:10173000EDFA7B0A78011203A7C2037890E6FC1247 +:1017400011237D007C0B1224B11231082212308546 +:1017500090FF91E090FD41F07D027C001224B112D7 +:1017600031082212308590FD40E0F4FC90FF91E0BA +:101770005CF53390FD41E0FC90FD40E05C4233E5D8 +:101780003390FF91F07C0012254A12310822743CFC +:1017900090FBE8F0743E90FBE8F0E490FD30F0221E +:1017A0008D358C34ECB401028003D340028028B420 +:1017B00002028003D34008A835C625E0F68018B49D +:1017C00004028003D3400AA835C625E025E0F68050 +:1017D00006A83576008000228C3C8D3BEDFEECFDAA +:1017E0007F0175600675610090FD3112046E120173 +:1017F000E6B480028006D3500302189E90FD311299 +:1018000004809000031201EC54F0B430028003D342 +:10181000405F90FD3112048090000812020EFAFD24 +:10182000EBFE7F0190FD3412046EEECD903502FC8C +:10183000E493FF740193FEF9EFFA7B01EAFFE9FEFE +:10184000ECC39EED9F4025903504E493FD74019315 +:10185000FCEDFEECFD7F01EECDFC90FD36E0D39C6F +:1018600090FD35E09D500575608080331219BC8075 +:101870002EB460028003D3400BAC3CAD3B12078218 +:101880008C60801BB41003B34010C3B42003B3407A +:1018900009C3B440028003D340007560818000809A +:1018A00075B481028003D3406B90FD3112048090A7 +:1018B00000031201EC54F0B430028003D3401D90B9 +:1018C000FD3112048090000812020EFAFDEBFE7F3B +:1018D0000190FD3712046E1219268036B460028022 +:1018E00003D34013753A61E4F539F538AC3CAD3BB0 +:1018F0001205DE8C60801BB41003B34010C3B4200B +:1019000003B34009C3B440028003D3400075608133 +:10191000800080028000E560FC90FD31120480ECC4 +:10192000900002120317AC612290FD3112048090E6 +:1019300000041201EC600474018001E4A2E0920151 +:1019400090FD31120480ED2403FD50010E90FD3412 +:1019500012046E90FD311204809000051201ECF526 +:10196000619000041201EC540FFC7D6112179DE59B +:1019700061700475600822756000787E7600787E5C +:10198000E6C39561503890FD371204801201E6FCE1 +:1019900090FD34120480EC12030F30010E90FD39DB +:1019A000E004F090FD387003E004F0787E0690FDCE +:1019B00036E004F090FD357003E004F080C0229022 +:1019C000FD32E0FDA3E0FCEDFEECFD7F01ED240A1D +:1019D000FD50010E90FD3A12046E90FD311204800C +:1019E0009000041201EC540FB401028003D340179D +:1019F00090FD3A1204800DED70010E90FD37120437 +:101A00006E78827601804EB402028003D340199032 +:101A1000FD3A120480ED2402FD50010E90FD3712B4 +:101A2000046E78827602802DB404028003D34019BC +:101A300090FD3A120480ED2404FD50010E90FD3714 +:101A400012046E78827604800CB400028003D340C6 +:101A5000007560082290FD3112048090000512018B +:101A6000ECF561787F7600787FE6C39561400302EC +:101A70001B24788076007880E6C378829650769032 +:101A8000FD341204801201E6FC90FD3A1204891222 +:101A900001E0F45CFC1201E0F890FD37120480E8EC +:101AA000C0E01201E6C8D0E0C8584CFC90FD3412EA +:101AB0000480EC12030F7881ECF690FD39E004F01D +:101AC00090FD387003E004F009E970010A90FD3AD6 +:101AD00012047790FD311204809000041201EC3062 +:101AE000E40E90FD36E004F090FD357003E004F064 +:101AF00078800680817882E6FDE4FEFFEECDFC90E2 +:101B0000FD39E02CF090FD38E03DF07882E6FDE410 +:101B1000FEFFEECDFC90FD3CE02CF090FD3BE03D67 +:101B2000F0787F06021A6475600022E53D053D04E9 +:101B30007002B2B022C0E0C0F0C082C083C0D0E862 +:101B4000C0E0E9C0E0EAC0E0EBC0E0ECC0E0EDC01E +:101B5000E0EEC0E0EFC0E090FF92E01201B71B8022 +:101B6000301B80321B8F381BA13A1BB33E1BCB446A +:101B70001BBF461BD7501C19521BF8541C3A560069 +:101B8000001C5B90FF92E07F00FE7C0112319A0204 +:101B90001C6BE4FF04FE7C0312319A742090FFFE5C +:101BA000F0021C6BE4FF04FE7C0212319A74409038 +:101BB000FFFEF0021C6BE4FF04FE7C0412319A026B +:101BC0001C6BE4FF04FE7C0512319A021C6BE4FFDF +:101BD00004FE7C0612319A021C6B90FFA5E07D008A +:101BE00090FD00CDF0A3CDF090FD01E0FCF58390D9 +:101BF000FD00E04433FD121CFE807390FFB5E07DD4 +:101C00000090FD02CDF0A3CDF090FD03E0FCF58344 +:101C100090FD02E04443FD121CFE805290FFA6E0BE +:101C20007D0090FD04CDF0A3CDF090FD05E0FCF526 +:101C30008390FD04E04434FD121CFE803190FFB619 +:101C4000E07D0090FD06CDF0A3CDF090FD07E0FC17 +:101C5000F58390FD06E04444FD121CFE801090FFC9 +:101C600092E07D00FCED44AAFD121CFE8000E49091 +:101C7000FF92F0D0E0FFD0E0FED0E0FDD0E0FCD05D +:101C8000E0FBD0E0FAD0E0F9D0E0F8D0D0D083D0BB +:101C900082D0F0D0E0320581058105810581A881DF +:101CA000181818EDF608ECF690FF6AE020E70280BD +:101CB000F790FF69E07D00A88118CDF6CD08F67D8C +:101CC00003A881E618FCE6CC25E0CC33CCDDF9CCCA +:101CD000F6CC08F6A88118E644F8F6A8811818187A +:101CE000E6FD08E6FCA881188683088682EDF0A34D +:101CF000ECF0740290FF6AF0158115811581158151 +:101D000022E5812405F581E4A88118F6A881181838 +:101D10001818EDF608ECF690FBFDE024F8500302ED +:101D20001E1FE4A8811818F6A88118E6FEA88118DD +:101D3000181818E6FD08E6FC7F00EF24F8404DE493 +:101D4000EF25E02485F582E434FDF583E0FBA3E094 +:101D50006C7003FAEB6D70097401A8811818F68095 +:101D60002BE4EF25E02485F582E434FDF5837A0049 +:101D7000E054F0CCF8CCCDF9CDFB7800E954F0F983 +:101D8000EA687002EB6970010E0F80AEA88118EE50 +:101D9000F6A88118181818EDF608ECF6A881EFF6E9 +:101DA000A8811818E67079A88118E624F74071A870 +:101DB0008118181818E6540FA881F664046017A853 +:101DC00081E664036010A88118181818E6FD08E67B +:101DD000FC121C93804A7C0A1230FAA88118181849 +:101DE00018E6FD08E6FC90FBFCE025E02485F58282 +:101DF000E434FDF583EDF0A3ECF090FBFCE0FFE4B0 +:101E0000EF045407FF90FBFCF090FBFDE004F012A0 +:101E1000319390FBFEE07008E4FEFF7C0F12319AD4 +:101E2000802790FBFFE004F0543F701D90FBFFE023 +:101E300044FE7D00FC90FBFCE025E02485F582E477 +:101E400034FDF583EDF0A3ECF0E58124FBF5812270 +:101E50007885760078867600740190FBFEF012306B +:101E60008590FBFDE060597C0A1230FA90FBFBE0A4 +:101E700025E02485F582E434FDF583E0FDA3E0FC54 +:101E800090FBFBE025E02485F582E434FDF583E456 +:101E9000F0A3F090FBFBE0FFE4EF045407FF90FB9E +:101EA000FBF090FBFDE014F07883EDF608ECF61201 +:101EB0003193B2B37883E6FD08E6FC1208E580A111 +:101EC0001231E7788506B60011788576007886E6C7 +:101ED000F40404A2E092B47886F68085E490FBFED8 +:101EE000F090FBFDE07D00FCED44CFFD121C931251 +:101EF000310822123085E56A64494569601590FF12 +:101F000083E0540F7D00D3956AED95695005122E3C +:101F1000CE8003122F9E12310822123085E56A64AA +:101F20004945696005122FD8800E90FF80E0440873 +:101F3000F090FF83E0547FF0123108221230858C3C +:101F400054EC54F0B4101575643D7563FD75620171 +:101F5000E5642403F564E5633400F563E4F557F5BF +:101F600056E556C394015027E554540FFCAD64AEBA +:101F700063AF62120E828C55EC600280120564E53C +:101F800064700205630557E5577002055680D2E577 +:101F900054540F2497F8C654FEF6E554540F7F00AE +:101FA000FE7C1212319AE5551470097D007C0912ED +:101FB00024B18007AD577C001224B11231082212DF +:101FC000308590FFFCE04402F090FF00E030E71322 +:101FD00090FF83E04480F043678090FFFCE0440181 +:101FE000F0801190FF82E04408F053677F90FFFC7F +:101FF000E054FEF090FF81E04480F012256490FFF1 +:10200000FEE04405F090FFFCE054FDF012310822A0 +:102010001230857C0112324878A7E64402F674FE3D +:10202000FC04FD121CFE90FF6AE030E70280F7E43A +:10203000F54E754D10AC4EAD4DE54E154E7002157A +:102040004DEC4D600280EE438701123108221230C0 +:10205000857C0212311478A7E654FDF6123108226D +:1020600012308578A7E630E02C78A7E630E12678B4 +:10207000A7E6FCF58318E644F0FD121C9390FFFCE4 +:10208000E04420F07C0212324878A7E654FDF67452 +:102090001A90FFFEF078A7E6FCF58318E644F1FD00 +:1020A000121C9312310822756700756800E4F5660A +:1020B000F565E4F569756A49748490FF82F074846B +:1020C00090FF80F0748090FF68F0748090FF6AF059 +:1020D000AD46AF457E00EE24FC500302216AE4EEDB +:1020E00075F007A4243FF582E434FCF583E0FFE4B7 +:1020F000EF5480FDE4EF540F14FFED6038E4EF750A +:10210000F008A42448F582E434FFF5837490F0E4E9 +:10211000EF75F008A4244AF582E434FFF583748057 +:10212000F0E4EF75F008A4244EF582E434FFF58363 +:102130007480F08034E4EF75F008A42408F582E49C +:1021400034FFF5837490F0E4EF75F008A4240AF5E9 +:1021500082E434FFF583E4F0E4EF75F008A4240E84 +:10216000F582E434FFF583E4F00E0220D38D468E31 +:10217000448F45747F90FFFDF0749090FFFCF090C9 +:10218000FC19E030E60790FFFCE04404F02290FCEC +:102190000DE014700490FC0CE0703990FC0079069E +:1021A0007A357B1278011203F57F00EF334015EF8B +:1021B00090354D93FCEF2480F582E434FCF583ECFC +:1021C000F00F80E78F5990FC2B79187A357B3578A2 +:1021D000011203F5E490FFFFF0745190FFFAF074E0 +:1021E0000490FFFBF0745390FFF8F0745190FFF9E6 +:1021F000F0745590FFF7F0749390FFF6F0743290FE +:10220000FFF5F075643D7563FD756201E490FF8331 +:10221000F0748090FF81F0755804E55875F007A4BC +:10222000243FF582E434FCF583E07889F6FC540F12 +:1022300014FC7889ECF6E55875F007A42441F58282 +:10224000E434FCF583E0788C76F8087600FC788935 +:10225000E675F008A42448F582E434FFF583E4F041 +:102260007889E675F008A4244FF582E434FFF583FD +:10227000ECF0788CE6FF08E67E03CFC313CF13DEC5 +:10228000F9FE7889E675F008A42449F582E434FF64 +:10229000F583EEF07889E675F008A4244AF582E427 +:1022A00034FFF5837480F0788AECF67D00788DE653 +:1022B0002CF618E63DF6788CE6FD08E67C03CDC3E7 +:1022C00013CD13DCF9FC7889E675F008A4244DF5EC +:1022D00082E434FFF583ECF07889E675F008A424F5 +:1022E0004EF582E434FFF583E4F0788CE6FD08E6F1 +:1022F000FC7889E6FF7E00EE24FC500302246BE4A8 +:10230000EE75F007A4243FF582E434FCF583E0FF8A +:10231000E4EF5480FAE4EF540F14FFE4EE75F00795 +:10232000A42441F582E434FCF583E0788AF6EE7566 +:10233000F080A42408F8E5F034F8F9E8FCE9FD8A17 +:1023400059EA70030223D8E4EF75F008A42448F595 +:1023500082E434FFF583E4F0788AE6FAE4EF75F07E +:1023600008A4244FF582E434FFF583EAF0EDFBEC9A +:102370007A03CBC313CB13DAF9FAE4EF75F008A4B0 +:102380002449F582E434FFF583EAF0788AE67B009D +:10239000FAEC2AFCED3BFDFBEC7A03CBC313CB1329 +:1023A000DAF9FAE4EF75F008A4244DF582E434FF7D +:1023B000F583EAF0E4EF75F008A4244AF582E434EA +:1023C000FFF5837480F0E4EF75F008A4244EF582E5 +:1023D000E434FFF5837480F0022467E4EF75F008BD +:1023E000A42408F582E434FFF583E4F0788AE6FA61 +:1023F000E4EF75F008A4240FF582E434FFF583EAD6 +:10240000F0EDFBEC7A03CBC313CB13DAF9FAE4EF6C +:1024100075F008A42409F582E434FFF583EAF07826 +:102420008AE67B00FAEC2AFCED3BFDFBEC7A03CB61 +:10243000C313CB13DAF9FAE4EF75F008A4240DF511 +:1024400082E434FFF583EAF0E4EF75F008A4240A8F +:10245000F582E434FFF583E4F0E4EF75F008A4249A +:102460000EF582E434FFF583E4F00E0222F48E5878 +:10247000788CEDF608ECF67889EFF61220A4228C21 +:1024800026EC30E718E526540F1475F008A424480C +:10249000F582E434FFF583E054DFF08016E526543E +:1024A0000F1475F008A42408F582E434FFF583E0E6 +:1024B00054DFF022EC90FD3FF08C24ED2403F52551 +:1024C0007D00D3956CED956B4003856C25E5252447 +:1024D000B75009752503740290FD3FF0AC25122F0B +:1024E000C322E4F566F5651224E82290FD3DE0651F +:1024F0006D600E740490FD3FF0E4F5657566038031 +:10250000467D6DE4FEFF793D7AFD7B017405780020 +:1025100012033FE5662403F566E5653400F565E5DD +:1025200066D3956CE565956B4006856C66856B6535 +:10253000D3E5669448E5659400400C740290FD3F35 +:10254000F0E4F565756603AC66122FC322EC90FDCE +:102550003FF0E4F566F5658C32EC6005122FB4802F +:10256000057C00122FC32290FF04E0F54A90FF067D +:10257000E0FDA3E0ED7D00FC7D00FC90FF06E0FFA8 +:10258000A3E07E00FFE4FEEC4EFCED4FFDC3EC94B7 +:1025900048ED9400502290FF06E0FDA3E0ED7D00A1 +:1025A000FC7D00FC90FF06E0FFA3E07E00FFE4FE60 +:1025B000EC4EFCED4FFD8004E4FD7C488C6C8D6B93 +:1025C00090FF02E0FDA3E0ED7D00FC7D00FC90FFAC +:1025D00002E0FFA3E07E00FFE4FEEC4EF54CED4F81 +:1025E000F54B75643D7563FD7562017D3D7EFD7F34 +:1025F00001796DE4FAFB7405780012033F75490018 +:10260000E54924FE4019AD64AE63AF62E412030FE6 +:1026100005490DED70010E8D648E638F6280E1754A +:10262000643D7563FD75620190FF00E05460B40085 +:10263000028006D35003022C12E54A540FF549E5F7 +:102640004A5480A2E0920290FF01E0120181000B47 +:102650002C0D266727852C0D28912C0D297429A86F +:102660002B0F2B122B522BB62BE4E56730E70EE530 +:102670004C454B7008E56C6402456B6003022C0FFF +:1026800090FF00E0541FB400028003D34029E54AC4 +:102690006003022782AD64AE63AF62740112030F60 +:1026A00078A7E630E00BAD64AE63AF62740212034C +:1026B0000F7C02122FC322B401028003D3401BE51A +:1026C0006720E107E54A6003022782E54A24FE50BD +:1026D000030227827C02122FC322B402028006D397 +:1026E0005003022780E56720E10DE54A6009E54ACD +:1026F00064806003022782AC4A12304A40030227FA +:1027000082E549702530021190FF80E05408AD64E5 +:10271000AE63AF6212030F800F90FF82E05408ADEA +:1027200064AE63AF6212030F803D154930021DE5B0 +:102730004975F008A42448F582E434FFF583E05499 +:1027400008AD64AE63AF6212030F801BE54975F0FC +:1027500008A42408F582E434FFF583E05408AD644E +:10276000AE63AF6212030FAD64AE63AF621201E6F7 +:10277000600BAD64AE63AF62740112030F7C021292 +:102780002FC3228000022C0FE56720E706E56C4589 +:102790006B6003022C0F90FF00E0541FB400028016 +:1027A00003D3401AE54C14454B7004E54A6003021C +:1027B000288E78A7E654FEF67C00122FC322B401BF +:1027C000028003D3402AE56720E108E56720E003A3 +:1027D00002288EE56730E004E54A700BE56730E1DA +:1027E00009E54A24FE500302288E7C00122FC322E2 +:1027F000B402028006D3500302288CE54C454B609E +:102800000302288EAC4A12304A400302288EE56744 +:1028100020E107E56720E0028077E56730E006E524 +:10282000496002806CE549700F90FF82E054F7F038 +:1028300090FF80E054F7F022E549B401028003D311 +:1028400040097D017C03120F0B8011B4020280034A +:10285000D340097D017C04120F0B80001549300222 +:1028600015E54975F008A42448F582E434FFF583A2 +:10287000E054F7F08013E54975F008A42408F582C8 +:10288000E434FFF583E054F7F07C00122FC322807C +:1028900000022C0FE56720E706E56C456B6003023C +:1028A0002C0F90FF00E0541FB400028003D3401AA5 +:1028B000E54C14454B7004E54A600302297178A782 +:1028C000E64401F67C00122FC322B401028003D338 +:1028D0004029E56720E108E56720E003022971E56A +:1028E0006730E004E549700BE56730E108E549240D +:1028F000FE5002807F7C00122FC322B402028003AC +:10290000D3406FE54C454B60028069AC4A12304AB7 +:1029100040028060E56720E107E56720E00280541F +:10292000E549701430020990FF80E04408F0800708 +:1029300090FF82E04408F022E56730E1331549302A +:102940000215E54975F008A42448F582E434FFF542 +:1029500083E04408F08013E54975F008A42408F5E5 +:1029600082E434FFF583E04408F07C00122FC32298 +:1029700080028000022C0FE56720E712E56C456BB2 +:10298000700CE54A700890FF00E0541F6003022CB1 +:102990000FE54C90FFFFF090FFFFE06005436701FB +:1029A00080035367FE7C00122FC322E56730E70ED9 +:1029B000E56C456B600890FF00E0541F6003022C3B +:1029C0000FAD4BE54CED7D00FC7D00FCBD000280B1 +:1029D00003022B0AB401028003D34032E54A70059A +:1029E000E54CFC6003022B0C7564007563FC75629A +:1029F00001D3E56C9412E56B94004006E4FD7C1273 +:102A00008004AC6CAD6B8C6A8D69122FD822B40235 +:102A1000028003D34059E54A6003022B0CE54CFCCD +:102A200070277564127563FC756201D3E56C9419A7 +:102A3000E56B94004006E4FD7C198004AC6CAD6B42 +:102A40008C6A8D69122FD8802575642B7563FC758F +:102A50006201D3E56C9435E56B94004006E4FD7C9F +:102A6000358004AC6CAD6B8C6A8D69122FD822B4A2 +:102A700003028006D35003022B0AE54CF549700F80 +:102A800090FF04E0FDA3E04D6003022B0C80189042 +:102A9000FC82E0FDA3E0FC90FF05E06C700790FF76 +:102AA00004E06D60028068E4F56AF5697F00E5493D +:102AB00014C549600FEF2480F582E434FCF583E00F +:102AC0002FFF80EA8F4AE54A2480F582E434FCF542 +:102AD00083E07D00D3956CED956B4006AC6CAD6BDF +:102AE000800FE54A2480F582E434FCF583E07D0024 +:102AF000FC8C6A8D69E54A2480FCE434FCFDFEEC24 +:102B0000FD7F018D648E638F62122FD822800002B8 +:102B10002C0F022C0FE56730E719E56C14456B703C +:102B200012E54A700EE54C454B700890FF00E054EA +:102B30001F6003022C0FE56720E008E56720E10332 +:102B4000022C0F756468E4F563F562E4F56904F539 +:102B50006A122FD822E56720E727E56C456B7021C4 +:102B6000E54A701DE54C6402454B600DE54C14458B +:102B70004B6006E54C454B700890FF00E0541F6029 +:102B800003022C0FE56720E008E56720E103022C33 +:102B90000F854C68E56870084367015367FD801333 +:102BA000E56864026007E56814600280655367FEAB +:102BB0004367027C00122FC322E56730E71AE56CF9 +:102BC00014456B7013E54A700FE54C454B70099046 +:102BD000FF00E0541F1460028038E56720E10280A6 +:102BE000317C01122FC322E56720E715E56C456BA8 +:102BF000700FE54C454B700990FF00E0541F1460C6 +:102C000002800FE56720E10280087C00122FC322BA +:102C10008000022ECAB440028006D35003022EC0A8 +:102C200090FF01E090FD3DF0E54A90FD3EF0E4901C +:102C3000FD3FF0E5642403F564E5633400F563AD1E +:102C40004BE54C856482856383CDF0A3CDF090FF86 +:102C500001E01201B72C7D012CA3022CCD032CF72F +:102C6000042D45052D82062DA8072DCE082DF4092B +:102C70002E1A0B2E400C2E4F802E4F8100002EADB1 +:102C8000E56720E7067C0512254A227DB77E347F62 +:102C90000279407AFD7B017408780012033F7D08B9 +:102CA0007C001224B122E56720E7067C0512254A44 +:102CB00022E54AB403004010B40500500BE54A7FFA +:102CC00000FE7C1012319A227D007C071224B12272 +:102CD000E56720E7067C0512254A22E54AB4030091 +:102CE0004010B40500500BE54A7F00FE7C11123104 +:102CF0009A227D007C071224B122E56720E7067C3A +:102D00000512254A22E54AB405028003D3400AE4AD +:102D1000FF04FE7C0A12319A22B401028003D340E0 +:102D20000AE4FF04FE7C0812319A22B4030040102A +:102D3000B40500500BE54A7F00FE7C1312319A2245 +:102D40007D007C071224B122E56720E734D3E56CCF +:102D50009448E56B94005006E56C456B70067C0268 +:102D600012254A22E54AB40103B3400BC3B4030061 +:102D70004009B406005004123070227C0712254A24 +:102D8000221224E822E56720E71DE54AB40300404B +:102D900010B40500500BE54A7F00FE7C1612319AF4 +:102DA000227C0712254A221224E822E56720E71D2B +:102DB000E54AB403004010B40500500BE54A7F001B +:102DC000FE7C1912319A227C0712254A221224E82D +:102DD00022E56720E71DE54AB403004010B4050072 +:102DE000500BE54A7F00FE7C1712319A227C0712B5 +:102DF000254A221224E822E56720E71DE54AB403AC +:102E0000004010B40500500BE54A7F00FE7C18120C +:102E1000319A227C0712254A221224E822E56720F3 +:102E2000E71DE54AB403004010B40500500BE54A25 +:102E30007F00FE7C1512319A227C0712254A22124D +:102E400024E822E56720E7067C0712254A2212249F +:102E5000E822E56730E72090FF00E0541F701090F3 +:102E6000FF01E0B480051224DF80031224E8227DF4 +:102E7000007C051224B12290FF00E0541F60067C04 +:102E80000512254A22D3E56C9448E56B9400500B5B +:102E9000C3E56C9407E56B940050067C0312254A49 +:102EA00022E54AB40504123070227C0712254A221A +:102EB000E56730E7087D007C051224B1227C05120D +:102EC000254A22B420028003D340008000122F9EA6 +:102ED0002275430090FF83E0540FD395434024E5CF +:102EE0004324F0F582E434FEF583E0AD64AE63AFD5 +:102EF0006212030F05430DED70010E8D648E638F1A +:102F00006280D1E5437D00FCC3E56A9CF56AE56912 +:102F10009DF569E56A45696006E490FF83F02290BB +:102F2000FF82E04408F0E4F569756A4990FD3DE0F0 +:102F3000B405028003D3404090FD3EE0F543B40564 +:102F4000028003D3400AE4FF04FE7C0B12319A2274 +:102F5000B401028003D3400AE4FF04FE7C0912316D +:102F60009A22B403004010B40500500BE5437F00E3 +:102F7000FE7C1412319A2222B480004023B48200D5 +:102F8000501E7C3D7DFD1217D57D008C668D6590B1 +:102F9000FD3FE06005122F9E80057C00122FC322AA +:102FA0002290FF83E0547FF090FF82E04408F0908D +:102FB000FF80E04408F02290FF82E04408F090FF98 +:102FC00080E04408F0228C237D008C6A8D69756452 +:102FD0003D7563FD756201122FD82290FF83E05486 +:102FE0007FF0E56A64494569700122C3E56A940887 +:102FF000E56994004015752108E5217D00FCC3E5D5 +:103000006A9CF56AE5699DF5698009856A21E4F5A0 +:1030100069756A49752200E522C395215026AD6481 +:10302000AE63AF621201E6FCE52224F8F582E434D7 +:10303000FEF583ECF005220DED70010E8D648E63BC +:103040008F6280D3E521547F90FF81F0228C487FEE +:1030500000EF24FB4019E4EF75F007A4243FF5824C +:10306000E434FCF583E065487002D3220F80E28FE0 +:1030700047C322856C6A856B6990FF82E054F7F044 +:1030800090FF83E0547FF022C000C001C002C00660 +:10309000C007E5722408F8860653067F7CFF1230CD +:1030A000FA7C007D00E5756046FF90FE9DE0547F50 +:1030B0006E700FC083C082A3E0FDA3E0FCA3157572 +:1030C0008007A3A3A3DFE68026DF06D082D083801B +:1030D0001EE0F8A3E0F9A3E0FAD082D083E8F0A3E1 +:1030E000E9F0A3EAF0A3C083C082A3A3A380DA120D +:1030F0003193D007D006D002D001D0002285A87429 +:1031000075A888EC70027C3F8C7322E5722408F865 +:1031100076001231E780FBC000C001C002C006C0CB +:1031200007AE047CFF1230FAE5756042FF90FE9D09 +:10313000E0547F6E700BC083C082A3A3A31575807B +:1031400007A3A3A3DFEA8026DF06D082D08380D83E +:10315000E0F8A3E0F9A3E0FAD082D083E8F0A3E995 +:10316000F0A3EAF0A3C083C082A3A3A380DA780807 +:10317000087918097C01E6547F6E700676007700A6 +:10318000800608090CBC08EE123193D007D006D097 +:1031900002D001D000227573008574A822C0F0C04F +:1031A00082C083C3E57524E850051231E780F4EC52 +:1031B00060319034B6E493C39C4028C0047CFF1275 +:1031C00030FAD004430480E57575F003A4249DF51E +:1031D00082E434FEF583ECF0EFA3F0EEA3F0057586 +:1031E000123193D083D082D0F022C0047C20D28CC4 +:1031F000D28DD504FDD0042275A80075880075B85D +:103200000075F00075D000E4F8900000F608B800F2 +:10321000FB020000C3ED940250047D037CE8ECF453 +:10322000FCEDF4FD0CBC00010D8C798D7822C3EC13 +:1032300094BCED940250047D077CD0ECF4FCEDF4DA +:10324000FD0CBC00010D8C778D7622EC700122C044 +:1032500000E5722418F8A604E5722408F8C6547F25 +:10326000F6E630E703D000221231E780F4C28C8505 +:10327000768C85778AD28CC0E0C0D0C0F0C082C086 +:1032800083C000C001C002C003C004C005C006C0A6 +:1032900007121B28E5722408F8E66024E572241062 +:1032A000F8A681E57275F021A42495F582E434FD39 +:1032B000F58378A8E58104C398F9E6F008A3D9FA64 +:1032C00074082572F8057208E65480700CE572B433 +:1032D00007F3780875720080EFE5722410F8868194 +:1032E000E57275F021A42495F582E434FDF5837828 +:1032F000A8E58104C398F9E0F608A3D9FAD007D06D +:1033000006D005D004D003D002D001D000D083D0A5 +:1033100082D0F0D0D0D0E032C0E0C0D0C000C00138 +:10332000C002C28E85788D85798BD28E7819790905 +:103330007A07E77004A600800BE6600816E67004C2 +:10334000E74480F70809DAEAE573601314F573704F +:103350000EE5722408F87600123193D28CD28DD00B +:1033600002D001D000D0D0D0E0327581A775900096 +:103370007579307578F87577607576F012053C12BE +:10338000340F12178B1234391231F580E322C0004A +:103390007C01EC2408F8E660090CBC08F51231E762 +:1033A00080EED00022C0F0C082C083C000C006C042 +:1033B00007ED2410F876B6ED75F021A42495F5827A +:1033C000E434FDF583C082C083A3A3E4780DF0A3A9 +:1033D000D8FCEC547F75F002A42482F582E5F03429 +:1033E00034F583E493FE740193F5828E83E493FEB7 +:1033F000740193FFD083D082EFF0A3EEF0ED2408A8 +:10340000F8EC4480F6D007D006D000D083D082D02C +:10341000F0227572007575007A08791878087600C0 +:1034200077000809DAF8E478087480447FF67401BC +:103430004410F58975B808D2ABD2A9227581A7D2FC +:103440008ED28CD2AFE5756032FF90FE9DE0548045 +:10345000602478087908E0547FFA7B00E6547FB551 +:1034600002027BFF08D9F5EB700CEAF012338BAD4A +:1034700004AC021233A2A3A3A3DFD21231E780C5AA +:103480007C017D002204F504E904ED04E104DD047F +:10349000D904E504F1049D04A104CD04D1049904E8 +:1034A00099049904D504B504AD04B104A904C10478 +:1034B000BD04B904C504C904A519010300220048CC +:1034C0000200240F180A10640D680C05060203019F +:1034D0000181010000E700C0008000600040003072 +:1034E0000018000C00080004000200010008183851 +:1034F000280602100A0200000000000181100A02E2 +:103500000000000000FBE8FBFA12011001FF0000C0 +:103510000851045F50160101020002090235000142 +:103520000200E0000904000005FF0000000705811B +:10353000024000000705010240000007058202402A +:103540000000070502024000000705850302000194 +:10355000040309042403540065007800610073002B +:10356000200049006E0073007400720075006D0049 +:1035700065006E00740073002A0354005500530068 +:103580004200350030003500320020005300650055 +:103590007200690061006C00200050006F00720032 +:1035A00074002203540055005300420035003000DF +:1035B00035003200200020002000200020002000E4 +:0435C00020002000C7 +:00000001FF -- cgit v0.10.2 From ec6752f5afce659025962e25fb2f42b3911254a1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 31 May 2008 01:35:29 +0300 Subject: whiteheat: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index f07e8a4..665aa77 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -81,7 +81,8 @@ #include #include #include -#include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */ +#include +#include #include "whiteheat.h" /* WhiteHEAT specific commands */ static int debug; @@ -279,37 +280,52 @@ static int firm_report_tx_done(struct usb_serial_port *port); */ static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id) { - int response; - const struct whiteheat_hex_record *record; - + int response, ret = -ENOENT; + const struct firmware *loader_fw = NULL, *firmware_fw = NULL; + const struct ihex_binrec *record; + dbg("%s", __func__); - + + if (request_ihex_firmware(&firmware_fw, "whiteheat.fw", + &serial->dev->dev)) { + err("%s - request \"whiteheat.fw\" failed", __func__); + goto out; + } + if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw", + &serial->dev->dev)) { + err("%s - request \"whiteheat_loader.fw\" failed", __func__); + goto out; + } + ret = 0; response = ezusb_set_reset (serial, 1); - record = &whiteheat_loader[0]; - while (record->address != 0xffff) { - response = ezusb_writememory (serial, record->address, - (unsigned char *)record->data, record->data_size, 0xa0); + record = (const struct ihex_binrec *)loader_fw->data; + while (record) { + response = ezusb_writememory (serial, be32_to_cpu(record->addr), + (unsigned char *)record->data, + be16_to_cpu(record->len), 0xa0); if (response < 0) { err("%s - ezusb_writememory failed for loader (%d %04X %p %d)", - __func__, response, record->address, record->data, record->data_size); + __func__, response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } - ++record; + record = ihex_next_binrec(record); } response = ezusb_set_reset (serial, 0); - record = &whiteheat_firmware[0]; - while (record->address < 0x1b40) { - ++record; - } - while (record->address != 0xffff) { - response = ezusb_writememory (serial, record->address, - (unsigned char *)record->data, record->data_size, 0xa3); + record = (const struct ihex_binrec *)firmware_fw->data; + while (record && be32_to_cpu(record->addr) < 0x1b40) + record = ihex_next_binrec(record); + while (record) { + response = ezusb_writememory (serial, be32_to_cpu(record->addr), + (unsigned char *)record->data, + be16_to_cpu(record->len), 0xa3); if (response < 0) { err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)", - __func__, response, record->address, record->data, record->data_size); + __func__, response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } ++record; @@ -317,21 +333,25 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct response = ezusb_set_reset (serial, 1); - record = &whiteheat_firmware[0]; - while (record->address < 0x1b40) { - response = ezusb_writememory (serial, record->address, - (unsigned char *)record->data, record->data_size, 0xa0); + record = (const struct ihex_binrec *)firmware_fw->data; + while (record && be32_to_cpu(record->addr) < 0x1b40) { + response = ezusb_writememory (serial, be32_to_cpu(record->addr), + (unsigned char *)record->data, + be16_to_cpu(record->len), 0xa0); if (response < 0) { err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)", - __func__, response, record->address, record->data, record->data_size); + __func__, response, be32_to_cpu(record->addr), + record->data, be16_to_cpu(record->len)); break; } ++record; } - + ret = 0; response = ezusb_set_reset (serial, 0); - - return 0; + out: + release_firmware(loader_fw); + release_firmware(firmware_fw); + return ret; } @@ -1503,6 +1523,9 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("whiteheat.fw"); +MODULE_FIRMWARE("whiteheat_loader.fw"); + module_param(urb_pool_size, int, 0); MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering"); diff --git a/drivers/usb/serial/whiteheat_fw.h b/drivers/usb/serial/whiteheat_fw.h deleted file mode 100644 index 8e0bdc7..0000000 --- a/drivers/usb/serial/whiteheat_fw.h +++ /dev/null @@ -1,1669 +0,0 @@ -/***************************************************************************** - * - * whiteheat.h -- ConnectTech WhiteHEAT Firmware. - * - * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * (10/09/2002) Stuart MacDonald - * Firmware 4.06 - * - * (04/09/2000) gkh - * Updated the firmware with the latest provided by ConnectTech. - * - * (01/16/2000) gkh - * Fixed my intel hex processing tool, so now the firmware actually - * matches the original file (this was causing a few problems...) - * - * (01/15/2000) gkh - * Added debug loader firmware if DEBUG is #defined: - * Port 1 LED flashes when the vend_ax program is running - * Port 2 LED flashes when any SETUP command arrives - * Port 3 LED flashes when any valid VENDOR request occurs - * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs - * - * version 1.0 (01/09/2000) gkh - * Original firmware from ConnectTech massaged a little to be program - * readable. - * - *****************************************************************************/ - -#define whiteheat_DATE "20000106" - -struct whiteheat_hex_record { - __u16 address; - __u8 data_size; - __u8 data[16]; -}; - -static const struct whiteheat_hex_record whiteheat_firmware[] = { -{ 0x0000, 3, {0x02, 0x97, 0xe3} }, -{ 0x0003, 3, {0x02, 0x13, 0x12} }, -{ 0x000b, 3, {0x02, 0x0b, 0xb5} }, -{ 0x0033, 3, {0x02, 0x08, 0x1c} }, -{ 0x0043, 3, {0x02, 0x0a, 0x00} }, -{ 0x005b, 3, {0x02, 0x83, 0x3b} }, -{ 0x0370, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} }, -{ 0x0380, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} }, -{ 0x0390, 16, {0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} }, -{ 0x03a0, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x9e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} }, -{ 0x03b0, 16, {0x36, 0x24, 0x02, 0x70, 0x7b, 0x74, 0x12, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} }, -{ 0x03c0, 16, {0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x99, 0xea, 0x49, 0x60, 0x0d} }, -{ 0x03d0, 16, {0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} }, -{ 0x03e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x58, 0xea} }, -{ 0x03f0, 16, {0x49, 0x60, 0x33, 0x12, 0xa2, 0x3b, 0xf5, 0x4e, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4e, 0xd3} }, -{ 0x0400, 16, {0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4e, 0xe5, 0x4e, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4e, 0x40} }, -{ 0x0410, 16, {0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4e, 0x12, 0x91, 0x37, 0x90, 0x7f, 0xb5} }, -{ 0x0420, 16, {0xe5, 0x4e, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} }, -{ 0x0430, 16, {0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} }, -{ 0x0440, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} }, -{ 0x0450, 16, {0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x35, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} }, -{ 0x0460, 16, {0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x35, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} }, -{ 0x0470, 16, {0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} }, -{ 0x0480, 16, {0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} }, -{ 0x0490, 16, {0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} }, -{ 0x04a0, 16, {0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0x90} }, -{ 0x04b0, 16, {0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25} }, -{ 0x04c0, 16, {0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0x01, 0x90, 0x7f, 0x00} }, -{ 0x04d0, 16, {0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} }, -{ 0x04e0, 16, {0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} }, -{ 0x04f0, 16, {0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} }, -{ 0x0500, 16, {0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x0510, 16, {0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4e, 0xef, 0x30, 0xe7, 0x03} }, -{ 0x0520, 16, {0x43, 0x4e, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4e, 0xf0, 0xe5, 0x4e, 0x44, 0x20, 0xf0, 0xef, 0xf4} }, -{ 0x0530, 16, {0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} }, -{ 0x0540, 16, {0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} }, -{ 0x0550, 16, {0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} }, -{ 0x0560, 16, {0x01, 0x04, 0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90} }, -{ 0x0570, 16, {0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f} }, -{ 0x0580, 16, {0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, -{ 0x0590, 16, {0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} }, -{ 0x05a0, 12, {0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} }, -{ 0x05ac, 1, {0x22} }, -{ 0x05ad, 16, {0x75, 0x4a, 0xff, 0x75, 0x49, 0xff, 0x75, 0x48, 0x0f, 0x75, 0x47, 0x00, 0xd2, 0x03, 0xc2, 0x06} }, -{ 0x05bd, 16, {0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} }, -{ 0x05cd, 16, {0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} }, -{ 0x05dd, 16, {0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3} }, -{ 0x05ed, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3} }, -{ 0x05fd, 16, {0x74, 0x08, 0xf0, 0x7e, 0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4c, 0x12, 0x75, 0x4d, 0x0a} }, -{ 0x060d, 16, {0x90, 0x01, 0x0b, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14} }, -{ 0x061d, 16, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4d, 0xe5} }, -{ 0x062d, 16, {0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01} }, -{ 0x063d, 16, {0x0d, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82} }, -{ 0x064d, 16, {0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70} }, -{ 0x065d, 16, {0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff} }, -{ 0x066d, 16, {0x74, 0x01, 0x93, 0x90, 0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff} }, -{ 0x067d, 16, {0xa3, 0xe0, 0xfe, 0xef, 0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90} }, -{ 0x068d, 16, {0x01, 0x1c, 0xe0, 0x6f, 0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x52, 0x10} }, -{ 0x069d, 16, {0x75, 0x53, 0x02, 0x75, 0x54, 0x12, 0x75, 0x55, 0xac, 0x12, 0x94, 0x26, 0x75, 0x4c, 0x12, 0x75} }, -{ 0x06ad, 16, {0x4d, 0xb2, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05} }, -{ 0x06bd, 16, {0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4d, 0xe5} }, -{ 0x06cd, 16, {0x4d, 0xac, 0x4c, 0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f} }, -{ 0x06dd, 16, {0x92, 0xe0, 0xff, 0xc4, 0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4d, 0xe5, 0x4d, 0xac, 0x4c, 0x70} }, -{ 0x06ed, 16, {0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4d, 0xe5, 0x4d, 0xae, 0x4c} }, -{ 0x06fd, 16, {0x70, 0x02, 0x05, 0x4c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83} }, -{ 0x070d, 16, {0x01, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12} }, -{ 0x071d, 16, {0xa3, 0xee, 0x7e, 0x01, 0x7f, 0x18, 0x12, 0x86, 0xbe, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x072d, 16, {0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x75, 0x52, 0x0a, 0x75, 0x53, 0x06, 0x75, 0x54, 0x12} }, -{ 0x073d, 16, {0x75, 0x55, 0xb8, 0x12, 0x94, 0x26, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff} }, -{ 0x074d, 16, {0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44} }, -{ 0x075d, 16, {0x1f, 0xf0, 0xd2, 0xaf, 0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09} }, -{ 0x076d, 16, {0xc5, 0x75, 0x46, 0x50, 0x75, 0x45, 0x6d, 0x75, 0x44, 0x33, 0x75, 0x43, 0x00, 0x20, 0x01, 0xe4} }, -{ 0x077d, 16, {0x7f, 0xff, 0x7e, 0xff, 0x7d, 0xff, 0x7c, 0xff, 0x78, 0x43, 0x12, 0xa3, 0xd7, 0xec, 0x4d, 0x4e} }, -{ 0x078d, 16, {0x4f, 0x60, 0xd1, 0x80, 0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a} }, -{ 0x079d, 16, {0x12, 0x09, 0xfb, 0x50, 0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x96, 0x5e, 0x90, 0x01, 0xbd} }, -{ 0x07ad, 16, {0xe0, 0x60, 0x0c, 0x12, 0x92, 0x01, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90} }, -{ 0x07bd, 16, {0x02, 0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x99, 0xb9, 0x12, 0xa0, 0x95, 0xe4, 0xff, 0x74, 0x01} }, -{ 0x07cd, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60} }, -{ 0x07dd, 16, {0x14, 0x74, 0x28, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e} }, -{ 0x07ed, 16, {0x00, 0x8e, 0x4b, 0x80, 0x03, 0x75, 0x4b, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20} }, -{ 0x07fd, 16, {0xf5, 0x83, 0xe5, 0x4b, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2c, 0xd3, 0x94, 0x0a, 0x40, 0x04} }, -{ 0x080d, 14, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x92} }, -{ 0x081b, 1, {0x22} }, -{ 0x081c, 4, {0x53, 0xd8, 0xef, 0x32} }, -{ 0x0820, 16, {0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} }, -{ 0x0830, 16, {0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0} }, -{ 0x0840, 16, {0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} }, -{ 0x0850, 16, {0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} }, -{ 0x0860, 16, {0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} }, -{ 0x0870, 16, {0xff, 0x12, 0x82, 0xea, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44} }, -{ 0x0880, 16, {0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96} }, -{ 0x0890, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54} }, -{ 0x08a0, 16, {0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} }, -{ 0x08b0, 8, {0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x22} }, -{ 0x08b8, 16, {0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} }, -{ 0x08c8, 16, {0x09, 0xae, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xea} }, -{ 0x08d8, 16, {0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} }, -{ 0x08e8, 16, {0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} }, -{ 0x08f8, 16, {0x12, 0x09, 0xae, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} }, -{ 0x0908, 16, {0xae, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0xe5} }, -{ 0x0918, 16, {0x33, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} }, -{ 0x0928, 8, {0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} }, -{ 0x0930, 16, {0x90, 0x0a, 0xf4, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} }, -{ 0x0940, 16, {0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xae} }, -{ 0x0950, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} }, -{ 0x0960, 16, {0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} }, -{ 0x0970, 16, {0xf5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} }, -{ 0x0980, 16, {0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x0b} }, -{ 0x0990, 16, {0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} }, -{ 0x09a0, 14, {0xf0, 0x12, 0x08, 0x20, 0x75, 0x82, 0xf4, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} }, -{ 0x09ae, 16, {0x8e, 0x5d, 0x8f, 0x5e, 0xe5, 0x5e, 0x15, 0x5e, 0xae, 0x5d, 0x70, 0x02, 0x15, 0x5d, 0x4e, 0x60} }, -{ 0x09be, 7, {0x05, 0x12, 0x09, 0xea, 0x80, 0xee, 0x22} }, -{ 0x09c5, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} }, -{ 0x09d5, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xae, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, -{ 0x09e5, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, -{ 0x09ea, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, -{ 0x09fa, 1, {0x22} }, -{ 0x09fb, 5, {0x12, 0x08, 0xb8, 0xd3, 0x22} }, -{ 0x0a00, 16, {0x02, 0x0c, 0x4e, 0x00, 0x02, 0x0c, 0x81, 0x00, 0x02, 0x0c, 0x66, 0x00, 0x02, 0x0c, 0xc0, 0x00} }, -{ 0x0a10, 16, {0x02, 0x0c, 0xaa, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xef, 0x00} }, -{ 0x0a20, 16, {0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x2b, 0x00} }, -{ 0x0a30, 16, {0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x8b, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xeb, 0x00} }, -{ 0x0a40, 16, {0x02, 0x0a, 0xf0, 0x00, 0x02, 0x0a, 0xf2, 0x00, 0x02, 0x0a, 0xf1, 0x00, 0x02, 0x0a, 0xf3, 0x00} }, -{ 0x0a50, 8, {0x02, 0x0f, 0x4b, 0x00, 0x02, 0x0f, 0x61, 0x00} }, -{ 0x0a58, 2, {0x8f, 0x4f} }, -{ 0x0a5a, 16, {0xe4, 0xf5, 0x50, 0x75, 0x51, 0xff, 0x75, 0x52, 0x12, 0x75, 0x53, 0x6a, 0xab, 0x51, 0xaa, 0x52} }, -{ 0x0a6a, 16, {0xa9, 0x53, 0x90, 0x00, 0x01, 0x12, 0xa2, 0x54, 0xb4, 0x03, 0x1d, 0xaf, 0x50, 0x05, 0x50, 0xef} }, -{ 0x0a7a, 16, {0xb5, 0x4f, 0x01, 0x22, 0x12, 0xa2, 0x3b, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, -{ 0x0a8a, 14, {0x51, 0xff, 0xf5, 0x52, 0x89, 0x53, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x0a98, 1, {0x22} }, -{ 0x0a99, 16, {0xe4, 0xfe, 0x75, 0x51, 0xff, 0x75, 0x52, 0x12, 0x75, 0x53, 0x12, 0xab, 0x51, 0xaa, 0x52, 0xa9} }, -{ 0x0aa9, 16, {0x53, 0x90, 0x00, 0x01, 0x12, 0xa2, 0x54, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, -{ 0x0ab9, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa2, 0xad, 0x85, 0xf0, 0x4f, 0xf5, 0x50, 0x62, 0x4f} }, -{ 0x0ac9, 16, {0xe5, 0x4f, 0x62, 0x50, 0xe5, 0x50, 0x62, 0x4f, 0x29, 0xfd, 0xe5, 0x4f, 0x3a, 0xa9, 0x05, 0x75} }, -{ 0x0ad9, 14, {0x51, 0xff, 0xf5, 0x52, 0x89, 0x53, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x0ae7, 1, {0x22} }, -{ 0x0ae8, 5, {0x12, 0x08, 0x20, 0xd3, 0x22} }, -{ 0x0aed, 1, {0x32} }, -{ 0x0aee, 1, {0x32} }, -{ 0x0aef, 1, {0x32} }, -{ 0x0af0, 1, {0x32} }, -{ 0x0af1, 1, {0x32} }, -{ 0x0af2, 1, {0x32} }, -{ 0x0af3, 1, {0x32} }, -{ 0x0af4, 3, {0x00, 0x04, 0x07} }, -{ 0x0b00, 9, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} }, -{ 0x0b7d, 16, {0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} }, -{ 0x0b8d, 16, {0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} }, -{ 0x0b9d, 16, {0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} }, -{ 0x0bad, 7, {0x78, 0x28, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} }, -{ 0x0bb4, 1, {0x22} }, -{ 0x0bb5, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} }, -{ 0x0bc5, 1, {0x07} }, -{ 0x0bc6, 16, {0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} }, -{ 0x0bd6, 16, {0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x28, 0xef, 0xd3} }, -{ 0x0be6, 16, {0x94, 0x2c, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} }, -{ 0x0bf6, 16, {0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} }, -{ 0x0c06, 13, {0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} }, -{ 0x0c13, 15, {0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c22, 16, {0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x30, 0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} }, -{ 0x0c32, 16, {0x7f, 0x92, 0x74, 0x02, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12} }, -{ 0x0c42, 12, {0x0f, 0x7d, 0x12, 0x94, 0xf7, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} }, -{ 0x0c4e, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} }, -{ 0x0c5e, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c66, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0c76, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0c81, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} }, -{ 0x0c91, 16, {0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2c, 0x70, 0x03, 0x75} }, -{ 0x0ca1, 9, {0x2c, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0caa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} }, -{ 0x0cba, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0cc0, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0cd0, 11, {0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0cdb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0ceb, 16, {0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x34, 0x30, 0xe0, 0x13, 0xe5, 0x32, 0x30, 0xe0, 0x07, 0x90, 0x20} }, -{ 0x0cfb, 16, {0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} }, -{ 0x0d0b, 12, {0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d17, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0d27, 16, {0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x34, 0x30, 0xe1, 0x13, 0xe5, 0x32, 0x30, 0xe1, 0x07, 0x90, 0x20} }, -{ 0x0d37, 16, {0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} }, -{ 0x0d47, 12, {0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d53, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0d63, 16, {0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x34, 0x30, 0xe2, 0x13, 0xe5, 0x32, 0x30, 0xe2, 0x07, 0x90, 0x20} }, -{ 0x0d73, 16, {0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} }, -{ 0x0d83, 12, {0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d8f, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0d9f, 16, {0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x34, 0x30, 0xe3, 0x13, 0xe5, 0x32, 0x30, 0xe3, 0x07, 0x90, 0x20} }, -{ 0x0daf, 16, {0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2c, 0x70, 0x03} }, -{ 0x0dbf, 12, {0x75, 0x2c, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dcb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0ddb, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x34, 0x20} }, -{ 0x0deb, 16, {0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} }, -{ 0x0dfb, 16, {0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe0, 0x07, 0x90, 0x20, 0x04, 0xe0} }, -{ 0x0e0b, 16, {0x44, 0x02, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} }, -{ 0x0e1b, 16, {0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e2b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0e3b, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x34, 0x20} }, -{ 0x0e4b, 16, {0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} }, -{ 0x0e5b, 16, {0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe1, 0x07, 0x90, 0x20, 0x0c, 0xe0} }, -{ 0x0e6b, 16, {0x44, 0x02, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} }, -{ 0x0e7b, 16, {0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e8b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0e9b, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x34, 0x20} }, -{ 0x0eab, 16, {0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} }, -{ 0x0ebb, 16, {0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe2, 0x07, 0x90, 0x20, 0x14, 0xe0} }, -{ 0x0ecb, 16, {0x44, 0x02, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} }, -{ 0x0edb, 16, {0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0eeb, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x0efb, 16, {0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x34, 0x20} }, -{ 0x0f0b, 16, {0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x22, 0xe5, 0x31, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} }, -{ 0x0f1b, 16, {0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x13, 0xe5, 0x22, 0x30, 0xe3, 0x07, 0x90, 0x20, 0x1c, 0xe0} }, -{ 0x0f2b, 16, {0x44, 0x02, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2c, 0x70, 0x03, 0x75, 0x2c} }, -{ 0x0f3b, 16, {0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0f4b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} }, -{ 0x0f5b, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0f61, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} }, -{ 0x0f71, 12, {0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0f7d, 16, {0x90, 0x01, 0x20, 0x12, 0xa3, 0xfa, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} }, -{ 0x0f8d, 16, {0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} }, -{ 0x0f9d, 16, {0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, -{ 0x0fad, 16, {0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} }, -{ 0x0fbd, 16, {0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa2} }, -{ 0x0fcd, 16, {0x12, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x87, 0xa6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} }, -{ 0x0fdd, 16, {0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x27, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} }, -{ 0x0fed, 16, {0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} }, -{ 0x0ffd, 16, {0xf0, 0x74, 0x23, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} }, -{ 0x100d, 16, {0xf5, 0x34, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} }, -{ 0x101d, 16, {0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} }, -{ 0x102d, 16, {0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x34, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x41, 0x90, 0x01, 0x1e} }, -{ 0x103d, 16, {0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3e, 0xf5, 0x22, 0xf5, 0x31, 0xf5, 0x32, 0x90, 0x01} }, -{ 0x104d, 16, {0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4} }, -{ 0x105d, 16, {0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54, 0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01} }, -{ 0x106d, 16, {0xf5, 0x83, 0xee, 0xf0, 0x74, 0x3a, 0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x36, 0x2f, 0xf8, 0xe4, 0xf6} }, -{ 0x107d, 16, {0x74, 0x2d, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} }, -{ 0x108d, 16, {0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0} }, -{ 0x109d, 4, {0x54, 0x0f, 0xf5, 0x4e} }, -{ 0x10a1, 16, {0x70, 0x03, 0x02, 0x11, 0x26, 0xe4, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3} }, -{ 0x10b1, 16, {0x94, 0x04, 0x50, 0xe4, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55} }, -{ 0x10c1, 16, {0x4e, 0x60, 0x5a, 0x90, 0x01, 0x1e, 0xe0, 0xfe, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82} }, -{ 0x10d1, 16, {0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xff, 0xee, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82} }, -{ 0x10e1, 16, {0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xee, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4} }, -{ 0x10f1, 16, {0x34, 0x20, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x06, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5} }, -{ 0x1101, 16, {0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0} }, -{ 0x1111, 16, {0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0x12, 0x83, 0xdf, 0x90, 0x01, 0x1e} }, -{ 0x1121, 6, {0xe0, 0x04, 0xf0, 0x80, 0x85, 0x22} }, -{ 0x1127, 2, {0xac, 0x07} }, -{ 0x1129, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xec, 0x25, 0xe0, 0x44, 0x41, 0x90, 0x7f, 0xa6, 0xf0} }, -{ 0x1139, 16, {0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90} }, -{ 0x1149, 16, {0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0xd4, 0x80, 0xf8, 0x90, 0x7f} }, -{ 0x1159, 16, {0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xdc, 0x20, 0xe1, 0x09, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} }, -{ 0x1169, 16, {0xf9, 0x22, 0xed, 0x30, 0xe2, 0x0c, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f} }, -{ 0x1179, 16, {0xfa, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7b, 0x1e} }, -{ 0x1189, 16, {0xaf, 0x03, 0x1b, 0xef, 0x70, 0x16, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6} }, -{ 0x1199, 16, {0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x60, 0x86, 0x80, 0xf8, 0x90, 0x7f, 0xa5, 0xe0} }, -{ 0x11a9, 16, {0xfd, 0x20, 0xe0, 0xdc, 0x7b, 0x3c, 0xaf, 0x03, 0x1b, 0xef, 0x70, 0x19, 0x90, 0x7f, 0xa5, 0xe0} }, -{ 0x11b9, 16, {0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0x7d, 0x32, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03} }, -{ 0x11c9, 16, {0x02, 0x11, 0x29, 0x80, 0xf5, 0x90, 0x7f, 0xa5, 0xe0, 0xfd, 0x30, 0xe0, 0xd9, 0x30, 0xe2, 0x09} }, -{ 0x11d9, 16, {0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x11e9, 12, {0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} }, -{ 0x11f5, 1, {0x22} }, -{ 0x1200, 16, {0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} }, -{ 0x1210, 16, {0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} }, -{ 0x1220, 16, {0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} }, -{ 0x1230, 16, {0x00, 0x00, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00} }, -{ 0x1240, 16, {0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} }, -{ 0x1250, 16, {0x84, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x87, 0x02} }, -{ 0x1260, 16, {0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x24, 0x03} }, -{ 0x1270, 16, {0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00} }, -{ 0x1280, 16, {0x54, 0x00, 0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} }, -{ 0x1290, 16, {0x2e, 0x00, 0x18, 0x03, 0x57, 0x00, 0x68, 0x00, 0x69, 0x00, 0x74, 0x00, 0x65, 0x00, 0x48, 0x00} }, -{ 0x12a0, 16, {0x45, 0x00, 0x41, 0x00, 0x54, 0x00, 0x2d, 0x00, 0x34, 0x00, 0x1a, 0x03, 0x58, 0x00, 0x58, 0x00} }, -{ 0x12b0, 16, {0x2d, 0x00, 0x58, 0x00, 0x58, 0x00, 0x2d, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00} }, -{ 0x12c0, 16, {0x58, 0x00, 0x58, 0x00, 0x2a, 0x03, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x69, 0x00} }, -{ 0x12d0, 16, {0x67, 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00} }, -{ 0x12e0, 16, {0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x22, 0x03} }, -{ 0x12f0, 16, {0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00} }, -{ 0x1300, 16, {0x65, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00} }, -{ 0x1310, 2, {0x00, 0x00} }, -{ 0x1312, 16, {0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0xc0, 0xd0} }, -{ 0x1322, 16, {0x75, 0x86, 0x00, 0x75, 0xd0, 0x18, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0xf0, 0x70, 0x11} }, -{ 0x1332, 16, {0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0} }, -{ 0x1342, 16, {0x32, 0x75, 0x86, 0x00, 0x10, 0xf0, 0x0b, 0x10, 0xf1, 0x12, 0x10, 0xf2, 0x19, 0x10, 0xf3, 0x20} }, -{ 0x1352, 16, {0x80, 0xd4, 0xe5, 0x28, 0x70, 0x03, 0x75, 0x28, 0x14, 0x02, 0x13, 0x7c, 0xe5, 0x29, 0x70, 0x03} }, -{ 0x1362, 16, {0x75, 0x29, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x16, 0x9e} }, -{ 0x1372, 16, {0xe5, 0x2b, 0x70, 0x03, 0x75, 0x2b, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} }, -{ 0x1382, 16, {0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02, 0x13} }, -{ 0x1392, 16, {0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x3a, 0x02, 0x13, 0x43} }, -{ 0x13a2, 16, {0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} }, -{ 0x13b2, 16, {0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} }, -{ 0x13c2, 16, {0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} }, -{ 0x13d2, 16, {0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x00, 0xf0, 0x90, 0x20} }, -{ 0x13e2, 16, {0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86} }, -{ 0x13f2, 16, {0x90, 0x7e, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f} }, -{ 0x1402, 16, {0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} }, -{ 0x1412, 16, {0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90} }, -{ 0x1422, 16, {0x7f, 0xb7, 0xed, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f, 0x40} }, -{ 0x1432, 16, {0x90, 0x7e, 0x80, 0x05, 0x86, 0x90, 0x20, 0x00, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d, 0x84} }, -{ 0x1442, 16, {0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xef, 0x05} }, -{ 0x1452, 16, {0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xb7, 0xf0, 0x05, 0x86, 0xa3, 0xe0, 0x54, 0xfe, 0xf0} }, -{ 0x1462, 16, {0x02, 0x13, 0x43, 0x53, 0x2d, 0xfa, 0xe5, 0x23, 0x60, 0x08, 0x75, 0x23, 0x00, 0xd2, 0xe7, 0xfe} }, -{ 0x1472, 16, {0x80, 0x0a, 0x90, 0x7f, 0xc7, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x14, 0xff, 0x90, 0x20, 0x50, 0x74} }, -{ 0x1482, 16, {0x00, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} }, -{ 0x1492, 16, {0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7e, 0x40, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} }, -{ 0x14a2, 16, {0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86, 0xe0, 0x24, 0x38, 0xf0, 0x05} }, -{ 0x14b2, 16, {0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78, 0x60, 0x30, 0x03, 0x03, 0x03} }, -{ 0x14c2, 16, {0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0} }, -{ 0x14d2, 16, {0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11, 0x8b, 0x23, 0x90, 0x7f} }, -{ 0x14e2, 16, {0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80, 0x1b, 0xe0, 0xde, 0xfd} }, -{ 0x14f2, 16, {0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90, 0x20, 0x01} }, -{ 0x1502, 16, {0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20, 0x0a, 0xe0, 0x54} }, -{ 0x1512, 16, {0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02} }, -{ 0x1522, 16, {0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x3b, 0x02, 0x13} }, -{ 0x1532, 16, {0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} }, -{ 0x1542, 16, {0x05, 0xe0, 0x42, 0x37, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} }, -{ 0x1552, 16, {0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} }, -{ 0x1562, 16, {0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x01, 0xf0, 0x90} }, -{ 0x1572, 16, {0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05} }, -{ 0x1582, 16, {0x86, 0x90, 0x7e, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90} }, -{ 0x1592, 16, {0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} }, -{ 0x15a2, 16, {0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} }, -{ 0x15b2, 16, {0x90, 0x7f, 0xb9, 0xed, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f} }, -{ 0x15c2, 16, {0x40, 0x90, 0x7e, 0x00, 0x05, 0x86, 0x90, 0x20, 0x08, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d} }, -{ 0x15d2, 16, {0x84, 0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xef} }, -{ 0x15e2, 16, {0x05, 0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xb9, 0xf0, 0x05, 0x86, 0xa3, 0xe0, 0x54, 0xfe} }, -{ 0x15f2, 16, {0xf0, 0x02, 0x13, 0x43, 0x53, 0x2e, 0xfa, 0xe5, 0x24, 0x60, 0x08, 0x75, 0x24, 0x00, 0xd2, 0xe7} }, -{ 0x1602, 16, {0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xc9, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x16, 0x90, 0x90, 0x20, 0x50} }, -{ 0x1612, 16, {0x74, 0x01, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} }, -{ 0x1622, 16, {0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0xc0, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} }, -{ 0x1632, 16, {0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86, 0xe0, 0x24, 0x38, 0xf0} }, -{ 0x1642, 16, {0x05, 0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78, 0x60, 0x30, 0x03, 0x03} }, -{ 0x1652, 16, {0x03, 0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0} }, -{ 0x1662, 16, {0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11, 0x8b, 0x24, 0x90} }, -{ 0x1672, 16, {0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80, 0x1b, 0xe0, 0xde} }, -{ 0x1682, 14, {0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} }, -{ 0x1690, 16, {0x90, 0x20, 0x09, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20} }, -{ 0x16a0, 16, {0x12, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14} }, -{ 0x16b0, 16, {0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x17, 0x87, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5} }, -{ 0x16c0, 16, {0x3c, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} }, -{ 0x16d0, 16, {0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x38, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} }, -{ 0x16e0, 16, {0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} }, -{ 0x16f0, 16, {0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74} }, -{ 0x1700, 16, {0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} }, -{ 0x1710, 16, {0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} }, -{ 0x1720, 16, {0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x41, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} }, -{ 0x1730, 16, {0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58} }, -{ 0x1740, 16, {0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbb, 0xed, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfe, 0xf0, 0x02} }, -{ 0x1750, 16, {0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x80, 0x05, 0x86, 0x90, 0x20, 0x10, 0xe5, 0x84, 0xfe, 0x24} }, -{ 0x1760, 16, {0x05, 0xfd, 0x8d, 0x84, 0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05} }, -{ 0x1770, 16, {0x86, 0xdf, 0xef, 0x05, 0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xbb, 0xf0, 0x05, 0x86, 0xa3} }, -{ 0x1780, 16, {0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x53, 0x2f, 0xfa, 0xe5, 0x25, 0x60, 0x08, 0x75, 0x25} }, -{ 0x1790, 16, {0x00, 0xd2, 0xe7, 0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x18, 0x21} }, -{ 0x17a0, 16, {0x90, 0x20, 0x50, 0x74, 0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0} }, -{ 0x17b0, 16, {0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x40, 0x05, 0x86, 0xe5, 0x85, 0xf0} }, -{ 0x17c0, 16, {0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86, 0xe0} }, -{ 0x17d0, 16, {0x24, 0x38, 0xf0, 0x05, 0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78, 0x60} }, -{ 0x17e0, 16, {0x30, 0x03, 0x03, 0x03, 0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0, 0xe0} }, -{ 0x17f0, 16, {0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70, 0x11} }, -{ 0x1800, 16, {0x8b, 0x25, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x80} }, -{ 0x1810, 16, {0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00} }, -{ 0x1820, 16, {0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x02, 0x13, 0x43, 0x90} }, -{ 0x1830, 16, {0x20, 0x1a, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5} }, -{ 0x1840, 16, {0x14, 0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x19, 0x18, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0} }, -{ 0x1850, 16, {0xf5, 0x3d, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x30, 0x01, 0x02, 0x13, 0x43, 0x53} }, -{ 0x1860, 16, {0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x39, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} }, -{ 0x1870, 16, {0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x32, 0x30, 0xe3, 0x0a, 0x53, 0x82} }, -{ 0x1880, 16, {0xf8, 0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50} }, -{ 0x1890, 16, {0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} }, -{ 0x18a0, 16, {0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} }, -{ 0x18b0, 16, {0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x42, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} }, -{ 0x18c0, 16, {0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20} }, -{ 0x18d0, 16, {0x58, 0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbd, 0xed, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfe, 0xf0} }, -{ 0x18e0, 16, {0x02, 0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x00, 0x05, 0x86, 0x90, 0x20, 0x18, 0xe5, 0x84, 0xfe} }, -{ 0x18f0, 16, {0x24, 0x05, 0xfd, 0x8d, 0x84, 0xe0, 0x8e, 0x84, 0x30, 0xe0, 0x09, 0xe0, 0x05, 0x86, 0xf0, 0xa3} }, -{ 0x1900, 16, {0x05, 0x86, 0xdf, 0xef, 0x05, 0x86, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0x7f, 0xbd, 0xf0, 0x05, 0x86} }, -{ 0x1910, 16, {0xa3, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x53, 0x30, 0xfa, 0xe5, 0x26, 0x60, 0x08, 0x75} }, -{ 0x1920, 16, {0x26, 0x00, 0xd2, 0xe7, 0xfe, 0x80, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xfe, 0x70, 0x03, 0x02, 0x19} }, -{ 0x1930, 16, {0xb2, 0x90, 0x20, 0x50, 0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2} }, -{ 0x1940, 16, {0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7c, 0xc0, 0x05, 0x86, 0xe5, 0x85} }, -{ 0x1950, 16, {0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xee, 0x30, 0xe7, 0x08, 0x05, 0x86} }, -{ 0x1960, 16, {0xe0, 0x24, 0x38, 0xf0, 0x05, 0x86, 0xee, 0x54, 0x7f, 0xfe, 0x54, 0x07, 0xfb, 0xee, 0x54, 0x78} }, -{ 0x1970, 16, {0x60, 0x30, 0x03, 0x03, 0x03, 0x30, 0xe3, 0x04, 0x74, 0x07, 0x7b, 0x08, 0xfd, 0xfc, 0xe0, 0xe0} }, -{ 0x1980, 16, {0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdd, 0xf6, 0xeb, 0xfe, 0x60, 0x19, 0xec, 0x64, 0x07, 0x70} }, -{ 0x1990, 16, {0x11, 0x8b, 0x26, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} }, -{ 0x19a0, 16, {0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} }, -{ 0x19b0, 16, {0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} }, -{ 0x19c0, 1, {0x32} }, -{ 0x19c1, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x19c5, 16, {0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} }, -{ 0x19d5, 16, {0x4a, 0x70, 0x03, 0x02, 0x1b, 0x09, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x1a, 0xdb, 0x90} }, -{ 0x19e5, 16, {0x19, 0xeb, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x1a, 0xb9, 0x02, 0x1a, 0x71, 0x02, 0x1a, 0x5a, 0x02} }, -{ 0x19f5, 16, {0x1a, 0x40, 0x02, 0x1a, 0x2f, 0x02, 0x1a, 0x1a, 0x02, 0x1a, 0x00, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1a05, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} }, -{ 0x1a15, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} }, -{ 0x1a25, 16, {0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x1a, 0xdb, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, -{ 0x1a35, 16, {0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1a45, 16, {0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} }, -{ 0x1a55, 16, {0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x1a65, 16, {0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x59, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} }, -{ 0x1a75, 16, {0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} }, -{ 0x1a85, 16, {0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} }, -{ 0x1a95, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5, 0x83} }, -{ 0x1aa5, 16, {0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} }, -{ 0x1ab5, 16, {0xa2, 0x81, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} }, -{ 0x1ac5, 16, {0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} }, -{ 0x1ad5, 16, {0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x59, 0x30, 0xe0, 0xf7, 0x30} }, -{ 0x1ae5, 16, {0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} }, -{ 0x1af5, 16, {0x19, 0xc7, 0xe5, 0x59, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} }, -{ 0x1b05, 6, {0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} }, -{ 0x1b0b, 1, {0x22} }, -{ 0x1b0c, 16, {0xe5, 0x33, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x7f, 0x02} }, -{ 0x1b1c, 16, {0x7d, 0xff, 0x12, 0x82, 0xea, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x7f, 0x03, 0x7d, 0xff} }, -{ 0x1b2c, 4, {0x12, 0x82, 0xea, 0x22} }, -{ 0x8000, 16, {0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa2, 0x54, 0xfd, 0x8b, 0x50, 0x75} }, -{ 0x8010, 16, {0x51, 0x12, 0x75, 0x52, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4e} }, -{ 0x8020, 16, {0xf5, 0x4f, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} }, -{ 0x8030, 16, {0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} }, -{ 0x8040, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} }, -{ 0x8050, 16, {0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x50, 0xaa, 0x51, 0xa9, 0x52} }, -{ 0x8060, 16, {0x90, 0x00, 0x01, 0x12, 0xa2, 0x54, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} }, -{ 0x8070, 16, {0x12, 0xa2, 0x54, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa2, 0x54} }, -{ 0x8080, 16, {0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} }, -{ 0x8090, 16, {0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4f, 0xae, 0x4e, 0x78, 0x02, 0xce} }, -{ 0x80a0, 16, {0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, -{ 0x80b0, 16, {0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} }, -{ 0x80c0, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} }, -{ 0x80d0, 16, {0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4f, 0xae, 0x4e, 0x78} }, -{ 0x80e0, 16, {0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x80f0, 16, {0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} }, -{ 0x8100, 16, {0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} }, -{ 0x8110, 16, {0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa2, 0x54, 0x25} }, -{ 0x8120, 16, {0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x90, 0x00, 0x05, 0x12, 0xa2, 0x54, 0xfe, 0xe4} }, -{ 0x8130, 16, {0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5, 0x4e, 0x02, 0x81, 0xb8, 0xab, 0x50, 0xaa, 0x51} }, -{ 0x8140, 16, {0xa9, 0x52, 0x90, 0x00, 0x03, 0x12, 0xa2, 0x54, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} }, -{ 0x8150, 16, {0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa2, 0x54, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} }, -{ 0x8160, 16, {0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} }, -{ 0x8170, 16, {0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} }, -{ 0x8180, 16, {0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} }, -{ 0x8190, 16, {0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} }, -{ 0x81a0, 16, {0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} }, -{ 0x81b0, 16, {0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35} }, -{ 0x81c0, 16, {0x51, 0xf5, 0x51, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} }, -{ 0x81d0, 8, {0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} }, -{ 0x81d8, 1, {0x22} }, -{ 0x81d9, 4, {0x8e, 0x59, 0x8f, 0x5a} }, -{ 0x81dd, 16, {0x75, 0x5b, 0x03, 0xe5, 0x5a, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x59, 0xf5, 0x83, 0xe0, 0xfe} }, -{ 0x81ed, 16, {0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x82, 0xe7, 0xe5, 0x5b, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} }, -{ 0x81fd, 16, {0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x82, 0x8b, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} }, -{ 0x820d, 16, {0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} }, -{ 0x821d, 16, {0x80, 0x6c, 0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} }, -{ 0x822d, 16, {0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x5b, 0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3} }, -{ 0x823d, 16, {0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x5a, 0x24, 0x06, 0xf5, 0x82} }, -{ 0x824d, 16, {0xe4, 0x35, 0x59, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5} }, -{ 0x825d, 16, {0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x5a, 0x24} }, -{ 0x826d, 16, {0x04, 0xf5, 0x82, 0xe4, 0x35, 0x59, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa2, 0x81, 0x85} }, -{ 0x827d, 16, {0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x81, 0x90, 0x7f} }, -{ 0x828d, 16, {0xa5, 0xe0, 0xf5, 0x5c, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} }, -{ 0x829d, 16, {0x22, 0xe5, 0x5c, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} }, -{ 0x82ad, 16, {0xe5, 0x5b, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xae, 0x90, 0x7f, 0xa5, 0xe0, 0x44} }, -{ 0x82bd, 16, {0x80, 0xf0, 0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} }, -{ 0x82cd, 16, {0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5c, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} }, -{ 0x82dd, 12, {0x5b, 0x03, 0x02, 0x81, 0xe0, 0x15, 0x5b, 0x02, 0x81, 0xe0, 0x7f, 0x08} }, -{ 0x82e9, 1, {0x22} }, -{ 0x82ea, 2, {0xae, 0x07} }, -{ 0x82ec, 16, {0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} }, -{ 0x82fc, 16, {0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} }, -{ 0x830c, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} }, -{ 0x831c, 16, {0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} }, -{ 0x832c, 14, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} }, -{ 0x833a, 1, {0x22} }, -{ 0x833b, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} }, -{ 0x834b, 15, {0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x835a, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} }, -{ 0x836a, 16, {0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x61, 0x74, 0xbf} }, -{ 0x837a, 16, {0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, -{ 0x838a, 16, {0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} }, -{ 0x839a, 16, {0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} }, -{ 0x83aa, 16, {0xef, 0x55, 0x31, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} }, -{ 0x83ba, 16, {0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} }, -{ 0x83ca, 16, {0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x61, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} }, -{ 0x83da, 4, {0x83, 0xa3, 0xe9, 0xf0} }, -{ 0x83de, 1, {0x22} }, -{ 0x83df, 4, {0x8f, 0x61, 0x8d, 0x62} }, -{ 0x83e3, 16, {0xe4, 0xf5, 0x67, 0x74, 0x3f, 0x2f, 0xf8, 0x76, 0x08, 0x7f, 0x80, 0x7e, 0x25, 0x7d, 0x00, 0x7c} }, -{ 0x83f3, 16, {0x00, 0xab, 0x66, 0xaa, 0x65, 0xa9, 0x64, 0xa8, 0x63, 0xd3, 0x12, 0xa3, 0xb3, 0x40, 0x26, 0x7f} }, -{ 0x8403, 16, {0x00, 0x7e, 0x96, 0x7d, 0x00, 0x7c, 0x00, 0xa8, 0x63, 0xd3, 0x12, 0xa3, 0xb3, 0x50, 0x0c, 0x75} }, -{ 0x8413, 16, {0x67, 0x40, 0x74, 0x3f, 0x25, 0x61, 0xf8, 0x76, 0x10, 0x80, 0x0a, 0x75, 0x67, 0x80, 0x74, 0x3f} }, -{ 0x8423, 16, {0x25, 0x61, 0xf8, 0x76, 0x38, 0xe5, 0x67, 0x45, 0x62, 0x44, 0x01, 0xff, 0xe5, 0x61, 0x75, 0xf0} }, -{ 0x8433, 13, {0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xef, 0xf0} }, -{ 0x8440, 1, {0x22} }, -{ 0x8441, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x8451, 16, {0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, -{ 0x8461, 16, {0x58, 0x8f, 0x59, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, -{ 0x8471, 16, {0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} }, -{ 0x8481, 16, {0x83, 0xe4, 0xf0, 0x74, 0x23, 0x25, 0x57, 0xf8, 0xe4, 0xf6, 0xe5, 0x59, 0x24, 0x04, 0xf5, 0x82} }, -{ 0x8491, 16, {0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, -{ 0x84a1, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x84b1, 16, {0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0xaf, 0x57, 0x12, 0x83} }, -{ 0x84c1, 16, {0xdf, 0xaf, 0x57, 0x7d, 0x01, 0x12, 0x83, 0x5a, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0xa3, 0xa3} }, -{ 0x84d1, 16, {0xe0, 0x20, 0xe0, 0x43, 0xe0, 0xff, 0xe5, 0x59, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5} }, -{ 0x84e1, 16, {0x83, 0xe0, 0xe5, 0x59, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0xff, 0xe5} }, -{ 0x84f1, 16, {0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc} }, -{ 0x8501, 16, {0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63} }, -{ 0x8511, 16, {0x7d, 0x06, 0xaf, 0x57, 0x12, 0x83, 0xdf, 0x74, 0xf8, 0x25, 0x57, 0xf5, 0x82, 0xe4, 0x34, 0x02} }, -{ 0x8521, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40} }, -{ 0x8531, 16, {0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x57, 0x25, 0xe0} }, -{ 0x8541, 16, {0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x57} }, -{ 0x8551, 15, {0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x34, 0x7f, 0x00} }, -{ 0x8560, 1, {0x22} }, -{ 0x8561, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x8571, 16, {0xaf, 0x57, 0xe4, 0xfd, 0x12, 0x83, 0x5a, 0x74, 0xf8, 0x25, 0x57, 0xf5, 0x82, 0xe4, 0x34, 0x02} }, -{ 0x8581, 16, {0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x8591, 16, {0x20, 0xaf, 0x82, 0xf5, 0x59, 0x8f, 0x5a, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} }, -{ 0x85a1, 16, {0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x0c} }, -{ 0x85b1, 16, {0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x57, 0x75, 0xf0, 0x0d, 0xa4, 0x24} }, -{ 0x85c1, 16, {0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x85d1, 16, {0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0xaf, 0x57, 0x12, 0x83} }, -{ 0x85e1, 16, {0xdf, 0xe5, 0x5a, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x59, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09} }, -{ 0x85f1, 16, {0x85, 0x5a, 0x82, 0x85, 0x59, 0x83, 0xe0, 0xf5, 0x58, 0xaf, 0x57, 0x74, 0x01, 0xa8, 0x07, 0x08} }, -{ 0x8601, 16, {0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x34, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc6, 0xf5} }, -{ 0x8611, 16, {0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xc7} }, -{ 0x8621, 11, {0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} }, -{ 0x862c, 1, {0x22} }, -{ 0x862d, 4, {0x8e, 0x57, 0x8f, 0x58} }, -{ 0x8631, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x59, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x8641, 16, {0xe5, 0x59, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} }, -{ 0x8651, 16, {0x54, 0x03, 0x70, 0x66, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x28, 0xe5} }, -{ 0x8661, 16, {0x59, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc} }, -{ 0x8671, 16, {0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63} }, -{ 0x8681, 16, {0x7d, 0x02, 0xaf, 0x59, 0x12, 0x83, 0xdf, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0x30} }, -{ 0x8691, 16, {0xe1, 0x28, 0xe5, 0x59, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5} }, -{ 0x86a1, 16, {0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d} }, -{ 0x86b1, 12, {0x64, 0x8c, 0x63, 0x7d, 0x04, 0xaf, 0x59, 0x12, 0x83, 0xdf, 0x7f, 0x00} }, -{ 0x86bd, 1, {0x22} }, -{ 0x86be, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} }, -{ 0x86ce, 16, {0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} }, -{ 0x86de, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} }, -{ 0x86ee, 16, {0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} }, -{ 0x86fe, 16, {0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} }, -{ 0x870e, 16, {0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} }, -{ 0x871e, 16, {0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} }, -{ 0x872e, 16, {0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} }, -{ 0x873e, 16, {0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} }, -{ 0x874e, 3, {0x83, 0xf0, 0x22} }, -{ 0x8751, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x8755, 16, {0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} }, -{ 0x8765, 16, {0x22, 0x8c, 0x57, 0x8d, 0x58, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x8775, 16, {0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} }, -{ 0x8785, 16, {0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02} }, -{ 0x8795, 16, {0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x87a5, 1, {0x22} }, -{ 0x87a6, 4, {0x8e, 0x57, 0x8f, 0x58} }, -{ 0x87aa, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5e, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} }, -{ 0x87ba, 16, {0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} }, -{ 0x87ca, 16, {0x5f, 0x8f, 0x60, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, -{ 0x87da, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa3} }, -{ 0x87ea, 16, {0xb3, 0x40, 0x10, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0x12, 0xa3, 0xfa, 0x00, 0x00, 0x00} }, -{ 0x87fa, 16, {0x08, 0x80, 0x2e, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} }, -{ 0x880a, 16, {0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa3} }, -{ 0x881a, 16, {0xb3, 0x50, 0x0e, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0x12, 0xa3, 0xfa, 0x00, 0x07, 0x08} }, -{ 0x882a, 16, {0x00, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} }, -{ 0x883a, 16, {0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa3, 0x21, 0x8f, 0x5c} }, -{ 0x884a, 16, {0x8e, 0x5b, 0x8d, 0x5a, 0x8c, 0x59, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa3} }, -{ 0x885a, 16, {0x21, 0xaf, 0x03, 0x8f, 0x5d, 0xaf, 0x5c, 0xae, 0x5b, 0xad, 0x5a, 0xac, 0x59, 0x7b, 0x0a, 0x7a} }, -{ 0x886a, 16, {0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa3, 0x21, 0x8f, 0x5c, 0x8e, 0x5b, 0x8d, 0x5a, 0x8c, 0x59} }, -{ 0x887a, 16, {0xe5, 0x5d, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5c, 0x24, 0x01, 0xf5, 0x5c, 0xe4, 0x35, 0x5b} }, -{ 0x888a, 16, {0xf5, 0x5b, 0xe4, 0x35, 0x5a, 0xf5, 0x5a, 0xe4, 0x35, 0x59, 0xf5, 0x59, 0x85, 0x60, 0x82, 0x85} }, -{ 0x889a, 16, {0x5f, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} }, -{ 0x88aa, 16, {0x80, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xe5, 0x5c, 0xf0, 0xaf, 0x5c, 0xae, 0x5b, 0xad} }, -{ 0x88ba, 16, {0x5a, 0xac, 0x59, 0x78, 0x08, 0x12, 0xa3, 0xc4, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xef} }, -{ 0x88ca, 16, {0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} }, -{ 0x88da, 16, {0x5d, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe0} }, -{ 0x88ea, 16, {0x23, 0x54, 0x01, 0xf0, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0} }, -{ 0x88fa, 16, {0x54, 0xfd, 0xf0, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc} }, -{ 0x890a, 16, {0x42, 0x22, 0x80, 0x36, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x5e, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} }, -{ 0x891a, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x22, 0x60, 0x1f, 0xe5, 0x60, 0x24, 0x04, 0xf5} }, -{ 0x892a, 16, {0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07} }, -{ 0x893a, 16, {0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x22, 0xe5, 0x58, 0x24, 0x08, 0xf5, 0x82} }, -{ 0x894a, 16, {0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62, 0x05, 0x43, 0x5d, 0x0a, 0x80, 0x1a, 0xef} }, -{ 0x895a, 16, {0xb4, 0x72, 0x05, 0x43, 0x5d, 0x08, 0x80, 0x11, 0xef, 0xb4, 0x74, 0x05, 0x43, 0x5d, 0x02, 0x80} }, -{ 0x896a, 16, {0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82, 0xe4} }, -{ 0x897a, 16, {0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03, 0x43, 0x5d, 0x80, 0xef, 0x30, 0xe7, 0x12} }, -{ 0x898a, 16, {0x43, 0x5d, 0x40, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0, 0x44} }, -{ 0x899a, 16, {0x02, 0xf0, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe1} }, -{ 0x89aa, 16, {0x20, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x32} }, -{ 0x89ba, 16, {0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x80} }, -{ 0x89ca, 16, {0x10, 0xaf, 0x5e, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52} }, -{ 0x89da, 16, {0x32, 0xe5, 0x58, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe4} }, -{ 0x89ea, 16, {0x11, 0xae, 0x5e, 0x74, 0x01, 0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31} }, -{ 0x89fa, 16, {0x80, 0x10, 0xae, 0x5e, 0x74, 0x01, 0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4} }, -{ 0x8a0a, 16, {0x52, 0x31, 0xef, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x03, 0xe4, 0xf5, 0x5d, 0x85, 0x60, 0x82, 0x85} }, -{ 0x8a1a, 16, {0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3} }, -{ 0x8a2a, 16, {0xe4, 0xf0, 0xe5, 0x5d, 0xf0, 0xe5, 0x58, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83} }, -{ 0x8a3a, 16, {0xe0, 0xff, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xef, 0xf0, 0xe5} }, -{ 0x8a4a, 16, {0x58, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x60, 0x24, 0x05} }, -{ 0x8a5a, 16, {0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x58, 0x24, 0x09, 0xf5, 0x82, 0xe4} }, -{ 0x8a6a, 16, {0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x60, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5} }, -{ 0x8a7a, 16, {0x83, 0xef, 0xf0, 0xe5, 0x58, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xff} }, -{ 0x8a8a, 16, {0xe5, 0x60, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83, 0xef, 0xf0, 0x85, 0x60, 0x82} }, -{ 0x8a9a, 16, {0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3} }, -{ 0x8aaa, 16, {0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} }, -{ 0x8aba, 16, {0xa3, 0xe0, 0xf5, 0x66, 0x8e, 0x65, 0x8d, 0x64, 0x8c, 0x63, 0x7d, 0x06, 0xaf, 0x5e, 0x12, 0x83} }, -{ 0x8aca, 16, {0xdf, 0x75, 0x5d, 0x08, 0xe5, 0x58, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0} }, -{ 0x8ada, 16, {0x60, 0x03, 0x43, 0x5d, 0x10, 0xe5, 0x60, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5f, 0xf5, 0x83} }, -{ 0x8aea, 16, {0xe0, 0x54, 0x03, 0x45, 0x5d, 0xf0, 0xe5, 0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5} }, -{ 0x8afa, 16, {0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05, 0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff} }, -{ 0x8b0a, 16, {0x22, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94} }, -{ 0x8b1a, 16, {0x01, 0x40, 0x06, 0xed, 0xd3, 0x94, 0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25} }, -{ 0x8b2a, 16, {0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24, 0xfb, 0x4f, 0xf5, 0x5d, 0xe5, 0x58, 0x24, 0x07, 0xf5, 0x82} }, -{ 0x8b3a, 16, {0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60} }, -{ 0x8b4a, 16, {0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a, 0x70, 0x14, 0x43, 0x5d, 0x18, 0x80, 0x12, 0x43, 0x5d, 0x08} }, -{ 0x8b5a, 16, {0x80, 0x0d, 0x43, 0x5d, 0x38, 0x80, 0x08, 0x43, 0x5d, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85} }, -{ 0x8b6a, 16, {0x60, 0x82, 0x85, 0x5f, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5d, 0xf0, 0x74, 0x01, 0x7e, 0x00, 0xa8} }, -{ 0x8b7a, 16, {0x5e, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x34} }, -{ 0x8b8a, 16, {0x60, 0x07, 0xaf, 0x5e, 0x7d, 0x01, 0x12, 0x83, 0x5a, 0xaa, 0x57, 0xa9, 0x58, 0x7b, 0x01, 0xc0} }, -{ 0x8b9a, 16, {0x03, 0xc0, 0x01, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0} }, -{ 0x8baa, 16, {0xa8, 0x01, 0xfc, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa2, 0x12} }, -{ 0x8bba, 2, {0x7f, 0x00} }, -{ 0x8bbc, 1, {0x22} }, -{ 0x8bbd, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8bcd, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} }, -{ 0x8bdd, 16, {0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} }, -{ 0x8bed, 16, {0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} }, -{ 0x8bfd, 16, {0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} }, -{ 0x8c0d, 16, {0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2d, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} }, -{ 0x8c1d, 16, {0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x57, 0xe5, 0x33, 0xc3, 0x94, 0x01} }, -{ 0x8c2d, 16, {0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x58, 0x00, 0xf5, 0x59, 0x80, 0x09, 0x7f} }, -{ 0x8c3d, 16, {0x02, 0x12, 0x11, 0x27, 0x8e, 0x58, 0x8f, 0x59, 0xc3, 0xe5, 0x58, 0x64, 0x80, 0x94, 0x80, 0x40} }, -{ 0x8c4d, 16, {0xda, 0xe5, 0x57, 0x55, 0x59, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} }, -{ 0x8c5d, 4, {0x91, 0x6a, 0x7f, 0x00} }, -{ 0x8c61, 1, {0x22} }, -{ 0x8c62, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8c72, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} }, -{ 0x8c82, 16, {0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} }, -{ 0x8c92, 16, {0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x91} }, -{ 0x8ca2, 3, {0x6a, 0x7f, 0x00} }, -{ 0x8ca5, 1, {0x22} }, -{ 0x8ca6, 4, {0x8e, 0x57, 0x8f, 0x58} }, -{ 0x8caa, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8cba, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x85, 0x58} }, -{ 0x8cca, 16, {0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5} }, -{ 0x8cda, 16, {0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x43, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x0c, 0xf5, 0x82} }, -{ 0x8cea, 16, {0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x20, 0xee, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82} }, -{ 0x8cfa, 16, {0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x30, 0xe1, 0xf0, 0x7f, 0x60, 0xed, 0x24, 0x05, 0xf5, 0x82} }, -{ 0x8d0a, 16, {0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0x5f, 0xb5, 0x07, 0xf2, 0xae, 0x04, 0xaf, 0x05, 0xef, 0x24, 0x04} }, -{ 0x8d1a, 12, {0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x7f, 0x00} }, -{ 0x8d26, 1, {0x22} }, -{ 0x8d27, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x8d2b, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8d3b, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, -{ 0x8d4b, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} }, -{ 0x8d5b, 16, {0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} }, -{ 0x8d6b, 4, {0xfe, 0xf0, 0x7f, 0x00} }, -{ 0x8d6f, 1, {0x22} }, -{ 0x8d70, 4, {0xad, 0x07, 0xac, 0x06} }, -{ 0x8d74, 16, {0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} }, -{ 0x8d84, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} }, -{ 0x8d94, 16, {0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} }, -{ 0x8da4, 16, {0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} }, -{ 0x8db4, 1, {0x22} }, -{ 0x8db5, 16, {0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} }, -{ 0x8dc5, 16, {0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3e, 0x7f, 0x00} }, -{ 0x8dd5, 1, {0x22} }, -{ 0x8dd6, 4, {0x8e, 0x57, 0x8f, 0x58} }, -{ 0x8dda, 16, {0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5c, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x59, 0xd3} }, -{ 0x8dea, 16, {0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x59, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} }, -{ 0x8dfa, 16, {0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x5a, 0x7e, 0x75, 0x5b} }, -{ 0x8e0a, 16, {0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x5a, 0x7e, 0x75, 0x5b, 0x00, 0x80, 0x16, 0x7e} }, -{ 0x8e1a, 16, {0x7d, 0x7f, 0x80, 0x75, 0x5a, 0x7d, 0x75, 0x5b, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} }, -{ 0x8e2a, 16, {0x5a, 0x7d, 0x75, 0x5b, 0x00, 0xe5, 0x5c, 0x70, 0x1b, 0x85, 0x5b, 0x82, 0x85, 0x5a, 0x83, 0x74} }, -{ 0x8e3a, 16, {0xff, 0xf0, 0xe5, 0x59, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} }, -{ 0x8e4a, 16, {0x01, 0xf0, 0x80, 0x48, 0xe5, 0x58, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x57, 0xfe, 0xe5, 0x5c, 0x60} }, -{ 0x8e5a, 16, {0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} }, -{ 0x8e6a, 16, {0x5b, 0xe5, 0x5b, 0xaa, 0x5a, 0x70, 0x02, 0x05, 0x5a, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} }, -{ 0x8e7a, 16, {0x15, 0x5c, 0x80, 0xd9, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x59, 0x25} }, -{ 0x8e8a, 14, {0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} }, -{ 0x8e98, 1, {0x22} }, -{ 0x8e99, 16, {0xef, 0x24, 0x05, 0xf5, 0x58, 0xe4, 0x3e, 0xf5, 0x57, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} }, -{ 0x8ea9, 16, {0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} }, -{ 0x8eb9, 16, {0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x59, 0xf5, 0x5a, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} }, -{ 0x8ec9, 16, {0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8f, 0x7a} }, -{ 0x8ed9, 16, {0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0xc8, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe} }, -{ 0x8ee9, 16, {0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5c, 0x74, 0x01, 0x9e, 0xf5, 0x5b, 0xd3, 0xe5, 0x5c} }, -{ 0x8ef9, 16, {0x94, 0x3f, 0xe5, 0x5b, 0x94, 0x00, 0x40, 0x06, 0x75, 0x5b, 0x00, 0x75, 0x5c, 0x3f, 0xd3, 0xe5} }, -{ 0x8f09, 16, {0x5a, 0x95, 0x5c, 0xe5, 0x59, 0x95, 0x5b, 0x50, 0x03, 0x02, 0x8f, 0xcb, 0xae, 0x5b, 0xaf, 0x5c} }, -{ 0x8f19, 16, {0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} }, -{ 0x8f29, 16, {0x59, 0xf5, 0x5a, 0x02, 0x8f, 0xcb, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} }, -{ 0x8f39, 16, {0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5c, 0xe4, 0x9e, 0xf5, 0x5b, 0xd3, 0xe5, 0x5c, 0x94} }, -{ 0x8f49, 16, {0x10, 0xe5, 0x5b, 0x94, 0x00, 0x40, 0x06, 0x75, 0x5b, 0x00, 0x75, 0x5c, 0x10, 0xd3, 0xe5, 0x5a} }, -{ 0x8f59, 16, {0x95, 0x5c, 0xe5, 0x59, 0x95, 0x5b, 0x40, 0x6a, 0xae, 0x5b, 0xaf, 0x5c, 0x85, 0x58, 0x82, 0x85} }, -{ 0x8f69, 16, {0x57, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x59, 0xf5, 0x5a, 0x80} }, -{ 0x8f79, 16, {0x51, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} }, -{ 0x8f89, 16, {0xf5, 0x5c, 0xe4, 0x9e, 0xf5, 0x5b, 0x45, 0x5c, 0x60, 0x0b, 0xd3, 0xe5, 0x5c, 0x94, 0x3f, 0xe5} }, -{ 0x8f99, 16, {0x5b, 0x94, 0x00, 0x40, 0x06, 0x75, 0x5b, 0x00, 0x75, 0x5c, 0x3f, 0xd3, 0xe5, 0x5a, 0x95, 0x5c} }, -{ 0x8fa9, 16, {0xe5, 0x59, 0x95, 0x5b, 0x40, 0x1c, 0xae, 0x5b, 0xaf, 0x5c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} }, -{ 0x8fb9, 16, {0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x59, 0xf5, 0x5a, 0x80, 0x03, 0x7f} }, -{ 0x8fc9, 16, {0x01, 0x22, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x90, 0x8b} }, -{ 0x8fd9, 16, {0x24, 0xf9, 0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x90, 0xdb, 0x24, 0x14, 0x60, 0x03, 0x02} }, -{ 0x8fe9, 16, {0x91, 0x1f, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94} }, -{ 0x8ff9, 16, {0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x91, 0x1f, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x5a} }, -{ 0x9009, 16, {0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15, 0x59, 0x4e, 0x70, 0x03, 0x02, 0x91, 0x1f, 0x90, 0x01} }, -{ 0x9019, 16, {0x75, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01} }, -{ 0x9029, 16, {0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x58, 0x82, 0x85} }, -{ 0x9039, 16, {0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03} }, -{ 0x9049, 16, {0x02, 0x91, 0x1f, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x91, 0x1f, 0x90} }, -{ 0x9059, 16, {0x01, 0x76, 0xef, 0xf0, 0xe5, 0x5a, 0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15, 0x59, 0x4e, 0x70} }, -{ 0x9069, 16, {0x03, 0x02, 0x91, 0x1f, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90} }, -{ 0x9079, 16, {0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0} }, -{ 0x9089, 16, {0x80, 0xd2, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94} }, -{ 0x9099, 16, {0x20, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x91, 0x1f, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00} }, -{ 0x90a9, 16, {0x50, 0x74, 0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x5a, 0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15} }, -{ 0x90b9, 16, {0x59, 0x4e, 0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90} }, -{ 0x90c9, 16, {0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0} }, -{ 0x90d9, 16, {0x80, 0xd5, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78} }, -{ 0x90e9, 16, {0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x5a, 0x15, 0x5a, 0xae, 0x59, 0x70, 0x02, 0x15, 0x59, 0x4e} }, -{ 0x90f9, 16, {0x60, 0x24, 0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5} }, -{ 0x9109, 16, {0x83, 0xe0, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82} }, -{ 0x9119, 16, {0xf5, 0x83, 0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83} }, -{ 0x9129, 13, {0xa3, 0xa3, 0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x91, 0x6a, 0x7f, 0x00} }, -{ 0x9136, 1, {0x22} }, -{ 0x9137, 16, {0x8e, 0x62, 0x8f, 0x63, 0x8c, 0x64, 0x8d, 0x65, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x63} }, -{ 0x9147, 16, {0xe5, 0x63, 0xae, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} }, -{ 0x9157, 16, {0x65, 0xe5, 0x65, 0xac, 0x64, 0x70, 0x02, 0x05, 0x64, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, -{ 0x9167, 3, {0x80, 0xd6, 0x22} }, -{ 0x916a, 6, {0x8d, 0x5d, 0xab, 0x07, 0xaa, 0x06} }, -{ 0x9170, 16, {0x75, 0x61, 0x40, 0x75, 0x60, 0x0d, 0x75, 0x5f, 0x03, 0x75, 0x5e, 0x00, 0x90, 0x7f, 0xc2, 0xe0} }, -{ 0x9180, 16, {0x20, 0xe1, 0xf9, 0xaf, 0x61, 0xae, 0x60, 0xad, 0x5f, 0xac, 0x5e, 0xec, 0x4d, 0x4e, 0x4f, 0x70} }, -{ 0x9190, 16, {0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} }, -{ 0x91a0, 16, {0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5d, 0x12, 0x91, 0x37, 0x90, 0x7f, 0xc3} }, -{ 0x91b0, 8, {0xe5, 0x5d, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x91b8, 1, {0x22} }, -{ 0x91b9, 16, {0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x33, 0xf0, 0x90, 0x0a, 0xf5, 0xe4, 0x93, 0x90} }, -{ 0x91c9, 16, {0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf6, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} }, -{ 0x91d9, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} }, -{ 0x91e9, 16, {0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} }, -{ 0x91f9, 7, {0x7d, 0x14, 0x12, 0x91, 0x6a, 0x7f, 0x00} }, -{ 0x9200, 1, {0x22} }, -{ 0x9201, 16, {0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4e, 0x7b, 0x75, 0x4f, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} }, -{ 0x9211, 16, {0x4e, 0x51, 0x85, 0x4f, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xf5, 0x56, 0xe4, 0x35, 0x51, 0xf5, 0x55} }, -{ 0x9221, 16, {0xe4, 0xf5, 0x50, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} }, -{ 0x9231, 16, {0x5b, 0x90, 0x92, 0x39, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x92, 0x5d, 0x02, 0x92, 0x5d, 0x02, 0x92} }, -{ 0x9241, 16, {0x67, 0x02, 0x92, 0x71, 0x02, 0x92, 0x71, 0x02, 0x92, 0x71, 0x02, 0x92, 0x85, 0x02, 0x92, 0x5d} }, -{ 0x9251, 16, {0x02, 0x92, 0x7b, 0x02, 0x92, 0x5d, 0x02, 0x92, 0x8d, 0x02, 0x92, 0x5d, 0xef, 0x64, 0x02, 0x60} }, -{ 0x9261, 16, {0x2b, 0x75, 0x50, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x50, 0xff, 0x80, 0x1c} }, -{ 0x9271, 16, {0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x50, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} }, -{ 0x9281, 16, {0x50, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x50, 0xff, 0xe5, 0x50, 0x60, 0x15} }, -{ 0x9291, 16, {0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} }, -{ 0x92a1, 16, {0x91, 0x6a, 0xaf, 0x50, 0x22, 0xe4, 0xf5, 0x50, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x14} }, -{ 0x92b1, 16, {0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x93, 0xcf, 0x90, 0x92, 0xc0, 0xf8, 0x28, 0x28, 0x73, 0x02} }, -{ 0x92c1, 16, {0x92, 0xed, 0x02, 0x92, 0xf9, 0x02, 0x93, 0x05, 0x02, 0x93, 0x53, 0x02, 0x93, 0x5e, 0x02, 0x93} }, -{ 0x92d1, 16, {0x69, 0x02, 0x93, 0x74, 0x02, 0x93, 0x7f, 0x02, 0x93, 0x8a, 0x02, 0x93, 0x95, 0x02, 0x93, 0xa0} }, -{ 0x92e1, 16, {0x02, 0x93, 0xa7, 0x02, 0x93, 0xcf, 0x02, 0x93, 0xb2, 0x02, 0x93, 0xbd, 0xaf, 0x56, 0xae, 0x55} }, -{ 0x92f1, 16, {0x12, 0x84, 0x41, 0x8f, 0x50, 0x02, 0x93, 0xd2, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x85, 0x61, 0x8f} }, -{ 0x9301, 16, {0x50, 0x02, 0x93, 0xd2, 0x85, 0x55, 0x53, 0x85, 0x56, 0x54, 0xe5, 0x54, 0x24, 0x01, 0xff, 0xe4} }, -{ 0x9311, 16, {0x35, 0x53, 0xfe, 0x12, 0x86, 0xbe, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x87, 0x51, 0x8f, 0x50, 0xef} }, -{ 0x9321, 16, {0x64, 0x01, 0x60, 0x03, 0x02, 0x93, 0xd2, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x87, 0xa6, 0x8f, 0x50} }, -{ 0x9331, 16, {0xe5, 0x50, 0x70, 0x03, 0x02, 0x93, 0xd2, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x75, 0xf0} }, -{ 0x9341, 16, {0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x87, 0xa6, 0x02} }, -{ 0x9351, 16, {0x93, 0xd2, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8c, 0xa6, 0x8f, 0x50, 0x80, 0x74, 0xaf, 0x56, 0xae} }, -{ 0x9361, 16, {0x55, 0x12, 0x8d, 0x27, 0x8f, 0x50, 0x80, 0x69, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8d, 0x70, 0x8f} }, -{ 0x9371, 16, {0x50, 0x80, 0x5e, 0xaf, 0x4f, 0xae, 0x4e, 0x12, 0x8e, 0x99, 0x8f, 0x50, 0x80, 0x53, 0xaf, 0x56} }, -{ 0x9381, 16, {0xae, 0x55, 0x12, 0x8b, 0xbd, 0x8f, 0x50, 0x80, 0x48, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x86, 0x2d} }, -{ 0x9391, 16, {0x8f, 0x50, 0x80, 0x3d, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8c, 0x62, 0x8f, 0x50, 0x80, 0x32, 0x12} }, -{ 0x93a1, 16, {0x91, 0xb9, 0x8f, 0x50, 0x80, 0x2b, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8d, 0xb5, 0x8f, 0x50, 0x80} }, -{ 0x93b1, 16, {0x20, 0xaf, 0x56, 0xae, 0x55, 0x12, 0x8d, 0xd6, 0x8f, 0x50, 0x80, 0x15, 0xaf, 0x4f, 0xae, 0x4e} }, -{ 0x93c1, 16, {0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x91, 0x37, 0xe4, 0xf5, 0x50, 0x80, 0x03, 0x75, 0x50} }, -{ 0x93d1, 16, {0xff, 0xe5, 0x50, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51} }, -{ 0x93e1, 16, {0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x91, 0x6a, 0xaf} }, -{ 0x93f1, 16, {0x50, 0x22, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} }, -{ 0x9401, 16, {0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x56, 0x82, 0x85} }, -{ 0x9411, 16, {0x55, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x91, 0x6a} }, -{ 0x9421, 4, {0x8f, 0x50, 0xaf, 0x50} }, -{ 0x9425, 1, {0x22} }, -{ 0x9426, 8, {0x8f, 0x51, 0x8e, 0x50, 0x8d, 0x4f, 0x8c, 0x4e} }, -{ 0x942e, 16, {0x75, 0x58, 0x01, 0x75, 0x59, 0x9c, 0xe4, 0xf5, 0x57, 0xaf, 0x53, 0x15, 0x53, 0xef, 0x70, 0x03} }, -{ 0x943e, 16, {0x02, 0x94, 0xc4, 0xaf, 0x52, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x51} }, -{ 0x944e, 16, {0xae, 0x50, 0xad, 0x4f, 0xac, 0x4e, 0x12, 0xa3, 0x21, 0xaf, 0x03, 0x8f, 0x56, 0xaf, 0x51, 0xae} }, -{ 0x945e, 16, {0x50, 0xad, 0x4f, 0xac, 0x4e, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x52, 0xe4} }, -{ 0x946e, 16, {0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} }, -{ 0x947e, 16, {0x12, 0xa3, 0x21, 0x8f, 0x51, 0x8e, 0x50, 0x8d, 0x4f, 0x8c, 0x4e, 0xe5, 0x56, 0x24, 0x30, 0xf5} }, -{ 0x948e, 16, {0x56, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x56, 0xf5, 0x56, 0x05, 0x59, 0xe5, 0x59} }, -{ 0x949e, 16, {0xae, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x59, 0xe5} }, -{ 0x94ae, 16, {0x59, 0xae, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x56, 0xf0, 0x05} }, -{ 0x94be, 16, {0x57, 0x05, 0x57, 0x02, 0x94, 0x37, 0xe5, 0x59, 0x15, 0x59, 0x70, 0x02, 0x15, 0x58, 0xaf, 0x57} }, -{ 0x94ce, 16, {0x15, 0x57, 0xef, 0x60, 0x23, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0xf5} }, -{ 0x94de, 16, {0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x55, 0xe5, 0x55, 0xac, 0x54, 0x70, 0x02, 0x05, 0x54, 0x14} }, -{ 0x94ee, 8, {0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} }, -{ 0x94f6, 1, {0x22} }, -{ 0x94f7, 16, {0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} }, -{ 0x9507, 10, {0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, -{ 0x9511, 16, {0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} }, -{ 0x9521, 16, {0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} }, -{ 0x9531, 16, {0xe4, 0xef, 0x55, 0x34, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x9541, 16, {0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} }, -{ 0x9551, 16, {0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa2, 0x81, 0xfc, 0xd3, 0xe5, 0xf0} }, -{ 0x9561, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, -{ 0x9571, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x9581, 1, {0x22} }, -{ 0x9582, 16, {0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} }, -{ 0x9592, 16, {0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} }, -{ 0x95a2, 16, {0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} }, -{ 0x95b2, 16, {0xa2, 0x12, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa2, 0x81, 0xfc, 0xd3, 0xe5, 0xf0} }, -{ 0x95c2, 16, {0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} }, -{ 0x95d2, 16, {0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} }, -{ 0x95e2, 1, {0x22} }, -{ 0x95e3, 16, {0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x53, 0x7b, 0x75, 0x54} }, -{ 0x95f3, 16, {0x80, 0xe5, 0x54, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x53, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x55, 0xf5} }, -{ 0x9603, 16, {0x56, 0x89, 0x57, 0xfe, 0x12, 0x95, 0x82, 0xef, 0x60, 0x50, 0xab, 0x55, 0xaa, 0x56, 0xa9, 0x57} }, -{ 0x9613, 16, {0x12, 0xa2, 0x3b, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa2, 0x54, 0xb4, 0x02, 0x16, 0xc2, 0xaf} }, -{ 0x9623, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} }, -{ 0x9633, 16, {0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} }, -{ 0x9643, 16, {0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x34, 0x60, 0x0f, 0x85, 0x54, 0x82, 0x85, 0x53} }, -{ 0x9653, 10, {0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} }, -{ 0x965d, 1, {0x22} }, -{ 0x965e, 16, {0x12, 0x95, 0xe3, 0xe4, 0xf5, 0x4e, 0x74, 0x3a, 0x25, 0x4e, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4f} }, -{ 0x966e, 16, {0x74, 0xc5, 0x25, 0x4e, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4f, 0xff, 0xc4} }, -{ 0x967e, 16, {0x54, 0x0f, 0xf5, 0x50, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4e, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} }, -{ 0x968e, 16, {0x83, 0xe5, 0x4f, 0xf0, 0xaf, 0x4e, 0x7d, 0x01, 0xe5, 0x4f, 0x45, 0x50, 0xfb, 0x12, 0x95, 0x11} }, -{ 0x969e, 16, {0xef, 0x70, 0x05, 0x12, 0x95, 0xe3, 0x80, 0xec, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04, 0x40} }, -{ 0x96ae, 16, {0xb5, 0x12, 0x95, 0xe3, 0xe5, 0x3e, 0x60, 0x48, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e, 0x74, 0x01, 0xa8} }, -{ 0x96be, 16, {0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4f, 0x55, 0x3e, 0x60, 0x29, 0xe5, 0x4e} }, -{ 0x96ce, 16, {0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, -{ 0x96de, 16, {0x16, 0xaf, 0x4e, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x95, 0x11, 0xef, 0x70, 0x05, 0x12, 0x95, 0xe3} }, -{ 0x96ee, 16, {0x80, 0xef, 0xe5, 0x4f, 0xf4, 0x52, 0x3e, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04, 0x40, 0xbb} }, -{ 0x96fe, 16, {0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x97, 0xdf, 0x74, 0x19, 0xf0, 0xe5, 0x33, 0xc3, 0x94} }, -{ 0x970e, 16, {0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x51, 0x00, 0xf5, 0x52, 0x80, 0x09} }, -{ 0x971e, 16, {0x7f, 0x02, 0x12, 0x11, 0x27, 0x8e, 0x51, 0x8f, 0x52, 0xc3, 0xe5, 0x51, 0x64, 0x80, 0x94, 0x80} }, -{ 0x972e, 16, {0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x52, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e} }, -{ 0x973e, 16, {0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4f, 0x90, 0x01, 0xbc} }, -{ 0x974e, 16, {0xe0, 0x55, 0x4f, 0x60, 0x14, 0xaf, 0x4e, 0x7d, 0x08, 0xe5, 0x4f, 0x55, 0x52, 0xfb, 0x12, 0x95} }, -{ 0x975e, 16, {0x11, 0xef, 0x70, 0x05, 0x12, 0x95, 0xe3, 0x80, 0xec, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04} }, -{ 0x976e, 16, {0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x52, 0xf0, 0xe4, 0xf5, 0x4e, 0xc2, 0xaf, 0x74, 0x36, 0x25} }, -{ 0x977e, 16, {0x4e, 0xf8, 0xe6, 0xf5, 0x4f, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4f, 0x1e, 0xe5, 0x4f, 0x60, 0x11} }, -{ 0x978e, 16, {0xaf, 0x4e, 0x7d, 0x02, 0xab, 0x4f, 0x12, 0x95, 0x11, 0xef, 0x70, 0x05, 0x12, 0x95, 0xe3, 0x80} }, -{ 0x979e, 16, {0xef, 0x74, 0x2d, 0x25, 0x4e, 0xf8, 0xe6, 0xf5, 0x4f, 0x74, 0xfc, 0x25, 0x4e, 0xf5, 0x82, 0xe4} }, -{ 0x97ae, 16, {0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4f, 0x60, 0x11, 0xaf, 0x4e, 0x7d, 0x04, 0xab, 0x4f, 0x12} }, -{ 0x97be, 16, {0x95, 0x11, 0xef, 0x70, 0x05, 0x12, 0x95, 0xe3, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4e, 0xf5, 0x82} }, -{ 0x97ce, 16, {0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4f, 0xf0, 0x05, 0x4e, 0xe5, 0x4e, 0xc3, 0x94, 0x04, 0x40} }, -{ 0x97de, 4, {0x9a, 0x12, 0x95, 0xe3} }, -{ 0x97e2, 1, {0x22} }, -{ 0x97e3, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x67, 0x02, 0x98, 0x2a} }, -{ 0x97ef, 16, {0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, -{ 0x97ff, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, -{ 0x980f, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, -{ 0x981f, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x98, 0x6f, 0xe4, 0x7e} }, -{ 0x982f, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, -{ 0x983f, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, -{ 0x984f, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, -{ 0x985f, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, -{ 0x986f, 16, {0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} }, -{ 0x987f, 16, {0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} }, -{ 0x988f, 8, {0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} }, -{ 0x9897, 1, {0x00} }, -{ 0x9898, 8, {0x8b, 0x59, 0x8a, 0x5a, 0x89, 0x5b, 0x8d, 0x5c} }, -{ 0x98a0, 16, {0xe4, 0xf5, 0x5d, 0xf5, 0x5e, 0xaf, 0x5c, 0x15, 0x5c, 0xef, 0x60, 0x36, 0xab, 0x59, 0x05, 0x5b} }, -{ 0x98b0, 16, {0xe5, 0x5b, 0xaa, 0x5a, 0x70, 0x02, 0x05, 0x5a, 0x14, 0xf9, 0x12, 0xa2, 0x3b, 0xff, 0xe5, 0x5d} }, -{ 0x98c0, 16, {0xe5, 0x5e, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x95, 0x2f, 0xf5, 0x82, 0xee, 0x34} }, -{ 0x98d0, 16, {0x9e, 0xf5, 0x83, 0xe5, 0x5d, 0xff, 0xe4, 0x93, 0xf5, 0x5d, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5e} }, -{ 0x98e0, 6, {0x80, 0xc3, 0xae, 0x5d, 0xaf, 0x5e} }, -{ 0x98e6, 1, {0x22} }, -{ 0x98e7, 11, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} }, -{ 0x98f2, 16, {0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} }, -{ 0x9902, 16, {0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} }, -{ 0x9912, 16, {0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} }, -{ 0x9922, 10, {0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} }, -{ 0x992c, 9, {0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x9935, 2, {0xa9, 0x03} }, -{ 0x9937, 16, {0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} }, -{ 0x9947, 16, {0x5c, 0x45, 0x5d, 0xf5, 0x5e, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} }, -{ 0x9957, 16, {0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} }, -{ 0x9967, 16, {0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5e, 0xeb} }, -{ 0x9977, 16, {0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5e, 0xfc, 0xb5, 0x06, 0x03, 0xaf} }, -{ 0x9987, 16, {0x05, 0x22, 0xe5, 0x5c, 0x5c, 0xfe, 0xe5, 0x5d, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} }, -{ 0x9997, 16, {0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, -{ 0x99a7, 16, {0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5c, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5d, 0x22, 0x7f} }, -{ 0x99b7, 1, {0x00} }, -{ 0x99b8, 1, {0x22} }, -{ 0x99b9, 16, {0x75, 0x55, 0x02, 0x75, 0x56, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x56, 0x82, 0x85} }, -{ 0x99c9, 16, {0x55, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0} }, -{ 0x99d9, 16, {0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x57, 0x03, 0x75, 0x58, 0x39} }, -{ 0x99e9, 16, {0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9e, 0x5d, 0x90, 0x99, 0xfa, 0xf8, 0x28, 0x28} }, -{ 0x99f9, 16, {0x73, 0x02, 0x9a, 0x1b, 0x02, 0x9a, 0xba, 0x02, 0x9b, 0xbf, 0x02, 0x9b, 0xde, 0x02, 0x9b, 0xde} }, -{ 0x9a09, 16, {0x02, 0x9c, 0x94, 0x02, 0x9c, 0xcf, 0x02, 0x9c, 0xf4, 0x02, 0x9d, 0xb2, 0x02, 0x9d, 0xe2, 0x02} }, -{ 0x9a19, 16, {0x9e, 0x0e, 0xe4, 0xf5, 0x4e, 0xe5, 0x4e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} }, -{ 0x9a29, 16, {0x34, 0x20, 0xaf, 0x82, 0xf5, 0x53, 0x8f, 0x54, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} }, -{ 0x9a39, 16, {0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4f, 0x80, 0x0d, 0x74} }, -{ 0x9a49, 16, {0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4f, 0xe5, 0x54, 0x24, 0x07} }, -{ 0x9a59, 16, {0xf5, 0x82, 0xe4, 0x35, 0x53, 0xf5, 0x83, 0xe5, 0x4f, 0xf0, 0xe0, 0xf5, 0x50, 0x65, 0x4f, 0x60} }, -{ 0x9a69, 16, {0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xfd, 0x05, 0x58, 0xe5, 0x58, 0xaa, 0x57} }, -{ 0x9a79, 16, {0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x58, 0xe5, 0x58, 0xac} }, -{ 0x9a89, 16, {0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4f, 0xf0, 0x85, 0x58, 0x82} }, -{ 0x9a99, 16, {0x85, 0x57, 0x83, 0xe5, 0x50, 0xf0, 0x02, 0x9e, 0x63, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} }, -{ 0x9aa9, 16, {0x02, 0x70, 0x87, 0x05, 0x4e, 0xe5, 0x4e, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9a, 0x1e, 0x02, 0x9e} }, -{ 0x9ab9, 16, {0x63, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e, 0xe4, 0xfd, 0x12, 0x83, 0x5a, 0x05, 0x4e, 0xe5, 0x4e, 0xd3} }, -{ 0x9ac9, 16, {0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x98, 0xf0, 0xa3, 0x74, 0xe7, 0xf0, 0xe4, 0xf5} }, -{ 0x9ad9, 16, {0x50, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x53, 0x20, 0x75, 0x54, 0x00, 0xf5, 0x4e, 0xaf, 0x4e, 0x74} }, -{ 0x9ae9, 16, {0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4f, 0x90, 0x01, 0xc4, 0xf0} }, -{ 0x9af9, 16, {0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xa3} }, -{ 0x9b09, 16, {0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4f, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} }, -{ 0x9b19, 16, {0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xff, 0x05, 0x58, 0xe5, 0x58} }, -{ 0x9b29, 16, {0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x58, 0x82} }, -{ 0x9b39, 16, {0x85, 0x57, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x50, 0xff, 0x90, 0x01} }, -{ 0x9b49, 16, {0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xfe, 0x05, 0x58} }, -{ 0x9b59, 16, {0xe5, 0x58, 0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} }, -{ 0x9b69, 16, {0x58, 0xe5, 0x58, 0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} }, -{ 0x9b79, 16, {0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe5, 0x4f, 0xf0, 0x75, 0x50, 0xff, 0xe5, 0x50, 0x70, 0x16} }, -{ 0x9b89, 16, {0x74, 0x08, 0x25, 0x54, 0xf5, 0x54, 0xe4, 0x35, 0x53, 0xf5, 0x53, 0x05, 0x4e, 0xe5, 0x4e, 0x64} }, -{ 0x9b99, 16, {0x04, 0x60, 0x03, 0x02, 0x9a, 0xe6, 0xe4, 0xf5, 0x4e, 0xaf, 0x4e, 0x7d, 0x01, 0x12, 0x83, 0x5a} }, -{ 0x9ba9, 16, {0x05, 0x4e, 0xe5, 0x4e, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} }, -{ 0x9bb9, 16, {0x74, 0x12, 0xf0, 0x02, 0x9e, 0x63, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x14, 0xff, 0x74} }, -{ 0x9bc9, 16, {0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} }, -{ 0x9bd9, 16, {0xc4, 0xf0, 0x02, 0x9e, 0x63, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} }, -{ 0x9be9, 16, {0xf5, 0x50, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} }, -{ 0x9bf9, 16, {0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x58, 0x82, 0x85} }, -{ 0x9c09, 16, {0x57, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x50, 0xe5, 0x50, 0x60, 0x03, 0x02, 0x9e, 0x63, 0x90, 0x01} }, -{ 0x9c19, 16, {0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} }, -{ 0x9c29, 16, {0xe5, 0x33, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x51, 0x00} }, -{ 0x9c39, 16, {0xf5, 0x52, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x11, 0x27, 0x8e, 0x51, 0x8f, 0x52, 0xc3, 0xe5, 0x51} }, -{ 0x9c49, 16, {0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x52, 0x54, 0x0f, 0xf5, 0x50, 0x90, 0x02, 0xf7, 0xe0} }, -{ 0x9c59, 16, {0x55, 0x50, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4f, 0x85, 0x56, 0x82, 0x85} }, -{ 0x9c69, 16, {0x55, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4f, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} }, -{ 0x9c79, 16, {0x00, 0x8f, 0x4f, 0xe5, 0x4f, 0x70, 0x03, 0x02, 0x9e, 0x63, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} }, -{ 0x9c89, 16, {0x58, 0x82, 0x85, 0x57, 0x83, 0xe5, 0x50, 0xf0, 0x02, 0x9e, 0x63, 0xe4, 0xff, 0xfd, 0x12, 0x83} }, -{ 0x9c99, 16, {0x5a, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x53, 0x20, 0x75, 0x54, 0x00, 0x85, 0x54, 0x82, 0x85, 0x53} }, -{ 0x9ca9, 16, {0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0x74, 0x01} }, -{ 0x9cb9, 16, {0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} }, -{ 0x9cc9, 16, {0xf0, 0xd2, 0x04, 0x02, 0x9e, 0x63, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x53, 0x20, 0x75} }, -{ 0x9cd9, 16, {0x54, 0x00, 0xe5, 0x54, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x53, 0xf5, 0x83, 0xe0, 0x30, 0xe6} }, -{ 0x9ce9, 16, {0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x83, 0x5a, 0x02, 0x9e, 0x63, 0xe4, 0xf5, 0x50, 0xf5, 0x4e} }, -{ 0x9cf9, 16, {0xaf, 0x4e, 0xe4, 0xfd, 0x12, 0x83, 0x5a, 0xe5, 0x4e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} }, -{ 0x9d09, 16, {0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x53, 0x8f, 0x54, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} }, -{ 0x9d19, 16, {0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4e, 0x7d, 0x01, 0x7b} }, -{ 0x9d29, 16, {0x01, 0x75, 0x5c, 0x80, 0x75, 0x5d, 0x40, 0x12, 0x99, 0x35, 0x8f, 0x50, 0xe5, 0x50, 0x70, 0x11} }, -{ 0x9d39, 16, {0xaf, 0x4e, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5c, 0x10, 0x75, 0x5d, 0x20, 0x12, 0x99, 0x35, 0x8f} }, -{ 0x9d49, 16, {0x50, 0xe5, 0x50, 0x70, 0x10, 0xaf, 0x4e, 0x7d, 0x01, 0xfb, 0x75, 0x5c, 0x80, 0x75, 0x5d, 0x40} }, -{ 0x9d59, 16, {0x12, 0x99, 0x35, 0x8f, 0x50, 0xe5, 0x50, 0x70, 0x10, 0xaf, 0x4e, 0x7d, 0x02, 0xfb, 0x75, 0x5c} }, -{ 0x9d69, 16, {0x10, 0x75, 0x5d, 0x20, 0x12, 0x99, 0x35, 0x8f, 0x50, 0xaf, 0x4e, 0x7d, 0x01, 0x12, 0x83, 0x5a} }, -{ 0x9d79, 16, {0xe5, 0x50, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4e, 0x04, 0xff, 0x05, 0x58, 0xe5} }, -{ 0x9d89, 16, {0x58, 0xac, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x58} }, -{ 0x9d99, 16, {0x82, 0x85, 0x57, 0x83, 0xe5, 0x50, 0xf0, 0x02, 0x9e, 0x63, 0x05, 0x4e, 0xe5, 0x4e, 0xd3, 0x94} }, -{ 0x9da9, 16, {0x03, 0x50, 0x03, 0x02, 0x9c, 0xf9, 0x02, 0x9e, 0x63, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} }, -{ 0x9db9, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9e, 0xf0, 0xa3, 0x74} }, -{ 0x9dc9, 16, {0x85, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x81, 0xd9, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9e} }, -{ 0x9dd9, 16, {0x63, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9e, 0x63, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} }, -{ 0x9de9, 16, {0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x57, 0xf0, 0xa3, 0xe5} }, -{ 0x9df9, 16, {0x58, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} }, -{ 0x9e09, 16, {0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfa, 0xa9, 0x07} }, -{ 0x9e19, 16, {0x7b, 0x01, 0x7d, 0x10, 0x12, 0x98, 0x98, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} }, -{ 0x9e29, 16, {0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x56, 0x24, 0x02, 0x90} }, -{ 0x9e39, 16, {0x03, 0x60, 0xf0, 0xe4, 0x35, 0x55, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x81} }, -{ 0x9e49, 16, {0xd9, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} }, -{ 0x9e59, 16, {0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} }, -{ 0x9e69, 16, {0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} }, -{ 0x9e79, 11, {0x35, 0x7d, 0x24, 0x12, 0x91, 0x6a, 0xe4, 0x90, 0x02, 0xaf, 0xf0} }, -{ 0x9e84, 1, {0x22} }, -{ 0x9e85, 16, {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} }, -{ 0x9e95, 16, {0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} }, -{ 0x9ea5, 16, {0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} }, -{ 0x9eb5, 16, {0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} }, -{ 0x9ec5, 16, {0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} }, -{ 0x9ed5, 16, {0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} }, -{ 0x9ee5, 16, {0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} }, -{ 0x9ef5, 16, {0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} }, -{ 0x9f05, 16, {0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} }, -{ 0x9f15, 16, {0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} }, -{ 0x9f25, 16, {0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} }, -{ 0x9f35, 16, {0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} }, -{ 0x9f45, 16, {0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} }, -{ 0x9f55, 16, {0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} }, -{ 0x9f65, 16, {0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} }, -{ 0x9f75, 16, {0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} }, -{ 0x9f85, 16, {0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} }, -{ 0x9f95, 16, {0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} }, -{ 0x9fa5, 16, {0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} }, -{ 0x9fb5, 16, {0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} }, -{ 0x9fc5, 16, {0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} }, -{ 0x9fd5, 16, {0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} }, -{ 0x9fe5, 16, {0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} }, -{ 0x9ff5, 16, {0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} }, -{ 0xa005, 16, {0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} }, -{ 0xa015, 16, {0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} }, -{ 0xa025, 16, {0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} }, -{ 0xa035, 16, {0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} }, -{ 0xa045, 16, {0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} }, -{ 0xa055, 16, {0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} }, -{ 0xa065, 16, {0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} }, -{ 0xa075, 16, {0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} }, -{ 0xa085, 16, {0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} }, -{ 0xa095, 16, {0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} }, -{ 0xa0a5, 16, {0xa1, 0x38, 0x74, 0x3a, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0xa1, 0x38, 0xef, 0x75, 0xf0} }, -{ 0xa0b5, 16, {0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} }, -{ 0xa0c5, 16, {0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} }, -{ 0xa0d5, 16, {0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} }, -{ 0xa0e5, 16, {0x12, 0xa2, 0x97, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} }, -{ 0xa0f5, 16, {0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} }, -{ 0xa105, 16, {0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} }, -{ 0xa115, 16, {0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} }, -{ 0xa125, 16, {0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} }, -{ 0xa135, 12, {0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0xa0, 0x97} }, -{ 0xa141, 1, {0x22} }, -{ 0xa142, 16, {0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} }, -{ 0xa152, 16, {0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} }, -{ 0xa162, 16, {0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} }, -{ 0xa172, 16, {0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} }, -{ 0xa182, 16, {0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} }, -{ 0xa192, 16, {0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} }, -{ 0xa1a2, 16, {0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} }, -{ 0xa1b2, 16, {0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} }, -{ 0xa1c2, 16, {0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} }, -{ 0xa1d2, 16, {0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} }, -{ 0xa1e2, 16, {0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} }, -{ 0xa1f2, 16, {0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} }, -{ 0xa202, 16, {0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} }, -{ 0xa212, 16, {0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} }, -{ 0xa222, 16, {0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} }, -{ 0xa232, 9, {0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0xa1, 0x92, 0x73} }, -{ 0xa23b, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, -{ 0xa24b, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, -{ 0xa254, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, -{ 0xa264, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, -{ 0xa274, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, -{ 0xa281, 16, {0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} }, -{ 0xa291, 6, {0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} }, -{ 0xa297, 16, {0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} }, -{ 0xa2a7, 6, {0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} }, -{ 0xa2ad, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, -{ 0xa2bd, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, -{ 0xa2cd, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, -{ 0xa2dd, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, -{ 0xa2e5, 16, {0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} }, -{ 0xa2f5, 16, {0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} }, -{ 0xa305, 16, {0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} }, -{ 0xa315, 16, {0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} }, -{ 0xa325, 16, {0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} }, -{ 0xa335, 16, {0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} }, -{ 0xa345, 16, {0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} }, -{ 0xa355, 16, {0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} }, -{ 0xa365, 16, {0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} }, -{ 0xa375, 16, {0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} }, -{ 0xa385, 16, {0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} }, -{ 0xa395, 16, {0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} }, -{ 0xa3a5, 14, {0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} }, -{ 0xa3b3, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, -{ 0xa3c3, 1, {0x22} }, -{ 0xa3c4, 16, {0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} }, -{ 0xa3d4, 3, {0xd8, 0xf1, 0x22} }, -{ 0xa3d7, 16, {0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} }, -{ 0xa3e7, 7, {0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} }, -{ 0xa3ee, 12, {0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} }, -{ 0xa3fa, 16, {0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa4, 0x11, 0x12, 0xa4, 0x11, 0x12} }, -{ 0xa40a, 16, {0xa4, 0x11, 0x12, 0xa4, 0x11, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} }, -{ 0xa41a, 16, {0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} }, -{ 0xa42a, 1, {0x22} }, -{ 0xffff, 0, {0x00} } -}; - -#ifdef DEBUG -static const struct whiteheat_hex_record whiteheat_loader[] = { -{ 0x0000, 3, {0x02, 0x09, 0x8d} }, -{ 0x0033, 3, {0x02, 0x0e, 0x70} }, -{ 0x0043, 3, {0x02, 0x0b, 0x00} }, -{ 0x004b, 3, {0x02, 0x05, 0xb3} }, -{ 0x0100, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x54, 0x10, 0xff, 0xc4, 0x54, 0x0f, 0x44, 0x50, 0xf5, 0x0f, 0x13, 0xe4} }, -{ 0x0110, 16, {0x33, 0xf5, 0x11, 0x90, 0x7f, 0xe9, 0xe0, 0x24, 0x5e, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x03} }, -{ 0x0120, 16, {0x7c, 0x90, 0x01, 0x28, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x01, 0xbc, 0x02, 0x01, 0xbc, 0x02, 0x01} }, -{ 0x0130, 16, {0x91, 0x02, 0x01, 0x3d, 0x02, 0x01, 0x53, 0x02, 0x01, 0x6f, 0x02, 0x01, 0x9a, 0x90, 0x7f, 0x00} }, -{ 0x0140, 16, {0xe5, 0x11, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} }, -{ 0x0150, 16, {0x02, 0x03, 0x7c, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4, 0x54, 0x0f, 0x90, 0x7f, 0x00, 0xf0, 0x90} }, -{ 0x0160, 16, {0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x03, 0x7c, 0x12} }, -{ 0x0170, 16, {0x0a, 0x89, 0x50, 0x07, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0x80, 0x06, 0x90, 0x7f, 0x00, 0x74, 0x0f} }, -{ 0x0180, 16, {0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x03} }, -{ 0x0190, 16, {0x7c, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0f, 0x02, 0x03, 0x7c, 0x90, 0x7f, 0x00, 0x74, 0x07, 0xf0} }, -{ 0x01a0, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xe8, 0x7e} }, -{ 0x01b0, 16, {0x03, 0x12, 0x0d, 0xd5, 0xd2, 0x06, 0x12, 0x0d, 0x0d, 0x02, 0x03, 0x7c, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x01c0, 16, {0x75, 0x29, 0x00, 0xf5, 0x2a, 0xa3, 0xe0, 0xfe, 0xe4, 0xee, 0x42, 0x29, 0x90, 0x7f, 0xee, 0xe0} }, -{ 0x01d0, 16, {0x75, 0x2b, 0x00, 0xf5, 0x2c, 0xa3, 0xe0, 0xfe, 0xe4, 0xee, 0x42, 0x2b, 0x90, 0x7f, 0xe8, 0xe0} }, -{ 0x01e0, 16, {0x64, 0xc0, 0x60, 0x03, 0x02, 0x02, 0xc9, 0xe5, 0x2c, 0x45, 0x2b, 0x70, 0x03, 0x02, 0x03, 0x7c} }, -{ 0x01f0, 16, {0xc3, 0xe5, 0x2c, 0x94, 0x40, 0xe5, 0x2b, 0x94, 0x00, 0x50, 0x08, 0x85, 0x2b, 0x2d, 0x85, 0x2c} }, -{ 0x0200, 16, {0x2e, 0x80, 0x06, 0x75, 0x2d, 0x00, 0x75, 0x2e, 0x40, 0x90, 0x7f, 0xe9, 0xe0, 0x64, 0xa3, 0x70} }, -{ 0x0210, 16, {0x34, 0xf5, 0x31, 0xf5, 0x32, 0xc3, 0xe5, 0x32, 0x95, 0x2e, 0xe5, 0x31, 0x95, 0x2d, 0x50, 0x5c} }, -{ 0x0220, 16, {0xe5, 0x2a, 0x25, 0x32, 0xf5, 0x82, 0xe5, 0x31, 0x35, 0x29, 0xf5, 0x83, 0xe0, 0xff, 0x74, 0x00} }, -{ 0x0230, 16, {0x25, 0x32, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x32, 0xe5, 0x32, 0x70} }, -{ 0x0240, 16, {0x02, 0x05, 0x31, 0x80, 0xd0, 0xe4, 0xf5, 0x31, 0xf5, 0x32, 0xc3, 0xe5, 0x32, 0x95, 0x2e, 0xe5} }, -{ 0x0250, 16, {0x31, 0x95, 0x2d, 0x50, 0x18, 0x74, 0x00, 0x25, 0x32, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, -{ 0x0260, 16, {0x74, 0xcd, 0xf0, 0x05, 0x32, 0xe5, 0x32, 0x70, 0x02, 0x05, 0x31, 0x80, 0xdd, 0xaf, 0x2a, 0xae} }, -{ 0x0270, 16, {0x29, 0xad, 0x2e, 0x7a, 0x7f, 0x79, 0x00, 0x7b, 0x00, 0x12, 0x0b, 0xf4, 0x90, 0x7f, 0xb5, 0xe5} }, -{ 0x0280, 16, {0x2e, 0xf0, 0xe5, 0x2e, 0x25, 0x2a, 0xf5, 0x2a, 0xe5, 0x2d, 0x35, 0x29, 0xf5, 0x29, 0xc3, 0xe5} }, -{ 0x0290, 16, {0x2c, 0x95, 0x2e, 0xf5, 0x2c, 0xe5, 0x2b, 0x95, 0x2d, 0xf5, 0x2b, 0x90, 0x7f, 0x92, 0xe0, 0xff} }, -{ 0x02a0, 16, {0xc4, 0x54, 0x0f, 0x75, 0x2f, 0x00, 0xf5, 0x30, 0xd3, 0x94, 0x00, 0xe5, 0x2f, 0x94, 0x00, 0x50} }, -{ 0x02b0, 16, {0x0c, 0x90, 0x7f, 0xb4, 0xe0, 0x20, 0xe1, 0x03, 0x02, 0x01, 0xe7, 0x80, 0xf4, 0x90, 0x7f, 0xb4} }, -{ 0x02c0, 16, {0xe0, 0x20, 0xe2, 0x03, 0x02, 0x01, 0xe7, 0x80, 0xf4, 0x90, 0x7f, 0xe8, 0xe0, 0x64, 0x40, 0x60} }, -{ 0x02d0, 16, {0x03, 0x02, 0x03, 0x7c, 0xe5, 0x2c, 0x45, 0x2b, 0x70, 0x03, 0x02, 0x03, 0x7c, 0xe4, 0x90, 0x7f} }, -{ 0x02e0, 16, {0xc5, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4, 0x54, 0x0f, 0x75, 0x2f, 0x00, 0xf5, 0x30, 0xd3} }, -{ 0x02f0, 16, {0x94, 0x00, 0xe5, 0x2f, 0x94, 0x00, 0x50, 0x09, 0x90, 0x7f, 0xc4, 0xe0, 0x30, 0xe1, 0x09, 0x80} }, -{ 0x0300, 16, {0xf7, 0x90, 0x7f, 0xb4, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x7f, 0xc5, 0xe0, 0x75, 0x2d, 0x00, 0xf5} }, -{ 0x0310, 16, {0x2e, 0x90, 0x7f, 0xe9, 0xe0, 0x64, 0xa3, 0x70, 0x38, 0x90, 0x20, 0x6b, 0xf0, 0xf5, 0x31, 0xf5} }, -{ 0x0320, 16, {0x32, 0xc3, 0xe5, 0x32, 0x95, 0x2e, 0xe5, 0x31, 0x95, 0x2d, 0x50, 0x34, 0x74, 0xc0, 0x25, 0x32} }, -{ 0x0330, 16, {0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x2a, 0x25, 0x32, 0xf5, 0x82, 0xe5} }, -{ 0x0340, 16, {0x31, 0x35, 0x29, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x32, 0xe5, 0x32, 0x70, 0x02, 0x05, 0x31, 0x80} }, -{ 0x0350, 16, {0xd0, 0xaf, 0x2a, 0xae, 0x29, 0xad, 0x2e, 0x7a, 0x7e, 0x79, 0xc0, 0x7b, 0xc0, 0x12, 0x0c, 0x80} }, -{ 0x0360, 16, {0xe5, 0x2e, 0x25, 0x2a, 0xf5, 0x2a, 0xe5, 0x2d, 0x35, 0x29, 0xf5, 0x29, 0xc3, 0xe5, 0x2c, 0x95} }, -{ 0x0370, 13, {0x2e, 0xf5, 0x2c, 0xe5, 0x2b, 0x95, 0x2d, 0xf5, 0x2b, 0x02, 0x02, 0xd4, 0xc3} }, -{ 0x037d, 1, {0x22} }, -{ 0x037e, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x56, 0x14, 0x70, 0x03, 0x02, 0x04, 0xd2, 0x24} }, -{ 0x038e, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x46, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x50, 0x14, 0x70, 0x03} }, -{ 0x039e, 16, {0x02, 0x04, 0x4a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3e, 0x14, 0x70, 0x03, 0x02, 0x04, 0x44, 0x24} }, -{ 0x03ae, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x9a, 0x12, 0x0e, 0x7b, 0x40, 0x03, 0x02, 0x05, 0xab, 0x90, 0x7f} }, -{ 0x03be, 16, {0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02, 0x70, 0x69, 0x74, 0x11, 0x90} }, -{ 0x03ce, 16, {0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x03de, 16, {0xff, 0x12, 0x0b, 0x58, 0x8b, 0x26, 0x8a, 0x27, 0x89, 0x28, 0xea, 0x49, 0x60, 0x11, 0xae, 0x02} }, -{ 0x03ee, 16, {0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xab, 0x90} }, -{ 0x03fe, 16, {0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0c} }, -{ 0x040e, 16, {0x3f, 0x8b, 0x26, 0x8a, 0x27, 0x89, 0x28, 0xea, 0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f} }, -{ 0x041e, 16, {0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xb4, 0xe0} }, -{ 0x042e, 16, {0x44, 0x01, 0xf0, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xab} }, -{ 0x043e, 16, {0x12, 0x0e, 0x52, 0x02, 0x05, 0xab, 0x12, 0x0e, 0x60, 0x02, 0x05, 0xab, 0x12, 0x0a, 0xf7, 0x02} }, -{ 0x044e, 16, {0x05, 0xab, 0x12, 0x08, 0xf1, 0x02, 0x05, 0xab, 0x12, 0x0e, 0x7d, 0x40, 0x03, 0x02, 0x05, 0xab} }, -{ 0x045e, 16, {0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2} }, -{ 0x046e, 16, {0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x02, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0} }, -{ 0x047e, 16, {0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xab, 0xe4, 0x90, 0x7f, 0x00} }, -{ 0x048e, 16, {0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xec, 0xe0} }, -{ 0x049e, 16, {0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} }, -{ 0x04ae, 16, {0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3} }, -{ 0x04be, 16, {0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} }, -{ 0x04ce, 16, {0xf0, 0x02, 0x05, 0xab, 0x12, 0x0e, 0x7f, 0x40, 0x03, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xe8, 0xe0} }, -{ 0x04de, 16, {0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xea, 0xe0, 0xb4} }, -{ 0x04ee, 16, {0x01, 0x05, 0xc2, 0x00, 0x02, 0x05, 0xab, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05} }, -{ 0x04fe, 16, {0xab, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4} }, -{ 0x050e, 16, {0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} }, -{ 0x051e, 16, {0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f} }, -{ 0x052e, 16, {0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x6e, 0x90} }, -{ 0x053e, 16, {0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x65, 0x12, 0x0e, 0x81, 0x50, 0x60, 0x90, 0x7f, 0xe8} }, -{ 0x054e, 16, {0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x54, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04} }, -{ 0x055e, 16, {0xd2, 0x00, 0x80, 0x49, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x40, 0x90, 0x7f, 0xea} }, -{ 0x056e, 16, {0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0} }, -{ 0x057e, 16, {0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01} }, -{ 0x058e, 16, {0xf0, 0x80, 0x1a, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x11, 0xe4, 0x90, 0x20, 0x6a} }, -{ 0x059e, 16, {0xf0, 0x12, 0x01, 0x00, 0x50, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4} }, -{ 0x05ae, 4, {0xe0, 0x44, 0x02, 0xf0} }, -{ 0x05b2, 1, {0x22} }, -{ 0x05b3, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x05c3, 16, {0xd0, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x06, 0xc0, 0x07, 0x90, 0x7f, 0xa5} }, -{ 0x05d3, 16, {0xe0, 0x30, 0xe2, 0x06, 0x75, 0x0d, 0x06, 0x02, 0x06, 0x7f, 0x90, 0x7f, 0xa5, 0xe0, 0x20, 0xe1} }, -{ 0x05e3, 16, {0x0c, 0xe5, 0x0d, 0x64, 0x02, 0x60, 0x06, 0x75, 0x0d, 0x07, 0x02, 0x06, 0x7f, 0xaf, 0x0d, 0xef} }, -{ 0x05f3, 16, {0x24, 0xfe, 0x60, 0x48, 0x14, 0x60, 0x2c, 0x24, 0xfe, 0x60, 0x77, 0x24, 0x04, 0x60, 0x03, 0x02} }, -{ 0x0603, 16, {0x06, 0x7f, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0xaf, 0x0c, 0x05, 0x0c, 0x8f, 0x82, 0x75, 0x83} }, -{ 0x0613, 16, {0x00, 0x12, 0x07, 0x85, 0x90, 0x7f, 0xa6, 0xf0, 0xe5, 0x0c, 0x65, 0x08, 0x70, 0x5e, 0x75, 0x0d} }, -{ 0x0623, 16, {0x05, 0x80, 0x59, 0x90, 0x7f, 0xa6, 0xe0, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0xae, 0x0c, 0x8e} }, -{ 0x0633, 16, {0x82, 0x75, 0x83, 0x00, 0x12, 0x07, 0xb2, 0x75, 0x0d, 0x02, 0x80, 0x40, 0xe5, 0x08, 0x24, 0xfe} }, -{ 0x0643, 16, {0xb5, 0x0c, 0x07, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0xe5, 0x08, 0x14, 0xb5, 0x0c, 0x0a} }, -{ 0x0653, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe4, 0xf5, 0x0d, 0x90, 0x7f, 0xa6, 0xe0, 0xab, 0x09} }, -{ 0x0663, 16, {0xaa, 0x0a, 0xa9, 0x0b, 0xae, 0x0c, 0x8e, 0x82, 0x75, 0x83, 0x00, 0x12, 0x07, 0xb2, 0x05, 0x0c} }, -{ 0x0673, 16, {0x80, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe4, 0xf5, 0x0d, 0x53, 0x91, 0xdf, 0xd0} }, -{ 0x0683, 16, {0x07, 0xd0, 0x06, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x86, 0xd0} }, -{ 0x0693, 10, {0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x069d, 16, {0xc2, 0x04, 0xd2, 0x05, 0xe4, 0xf5, 0x25, 0xc2, 0x03, 0xc2, 0x00, 0xc2, 0x02, 0xc2, 0x01, 0x12} }, -{ 0x06ad, 16, {0x0e, 0x74, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9} }, -{ 0x06bd, 16, {0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x90} }, -{ 0x06cd, 16, {0x7f, 0x93, 0x74, 0x30, 0xf0, 0x12, 0x0a, 0x19, 0x75, 0x24, 0x48, 0x75, 0x23, 0x92, 0x75, 0x22} }, -{ 0x06dd, 16, {0x00, 0x75, 0x21, 0x00, 0xe4, 0xff, 0xfe, 0x7e, 0x05, 0x90, 0x20, 0x68, 0x74, 0x01, 0xf0, 0xa3} }, -{ 0x06ed, 16, {0xde, 0xfc, 0x7e, 0x00, 0x7f, 0x05, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae} }, -{ 0x06fd, 16, {0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0x12, 0x0e, 0x68, 0x30, 0x01, 0x0a, 0xe4, 0x90, 0x20, 0x69} }, -{ 0x070d, 16, {0xf0, 0x12, 0x03, 0x7e, 0xc2, 0x01, 0x30, 0x04, 0x1a, 0x12, 0x0e, 0x77, 0x50, 0x13, 0x12, 0x09} }, -{ 0x071d, 16, {0x00, 0x30, 0x00, 0x07, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0xf3, 0x12, 0x0d, 0x8b, 0x12, 0x0e} }, -{ 0x072d, 16, {0x79, 0xc2, 0x03, 0x7f, 0xff, 0x7e, 0xff, 0x7d, 0xff, 0x7c, 0xff, 0x78, 0x21, 0x12, 0x08, 0x1d} }, -{ 0x073d, 16, {0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0x08, 0x0c, 0x70, 0x1b, 0x75, 0x24} }, -{ 0x074d, 16, {0x48, 0x75, 0x23, 0x92, 0xf5, 0x22, 0xf5, 0x21, 0x63, 0x25, 0xff, 0x90, 0x20, 0x68, 0xe5, 0x25} }, -{ 0x075d, 14, {0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0x12, 0x08, 0xff, 0x80, 0x9b} }, -{ 0x076b, 1, {0x22} }, -{ 0x076c, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, -{ 0x077c, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x0785, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, -{ 0x0795, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, -{ 0x07a5, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x07b2, 16, {0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 0xf0} }, -{ 0x07c2, 16, {0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xc8, 0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 0xc8} }, -{ 0x07d2, 2, {0xf2, 0x22} }, -{ 0x07d4, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, -{ 0x07e4, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, -{ 0x07f4, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, -{ 0x0804, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, -{ 0x080c, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, -{ 0x081c, 1, {0x22} }, -{ 0x081d, 16, {0x08, 0x08, 0x08, 0xe6, 0x2f, 0xff, 0xf6, 0x18, 0xe6, 0x3e, 0xfe, 0xf6, 0x18, 0xe6, 0x3d, 0xfd} }, -{ 0x082d, 7, {0xf6, 0x18, 0xe6, 0x3c, 0xfc, 0xf6, 0x22} }, -{ 0x0834, 4, {0x8c, 0x34, 0x8d, 0x35} }, -{ 0x0838, 16, {0x90, 0x7f, 0x95, 0xe0, 0x44, 0xc0, 0xf0, 0xe4, 0xf5, 0x36, 0xf5, 0x37, 0xc3, 0xe5, 0x37, 0x95} }, -{ 0x0848, 16, {0x35, 0xe5, 0x36, 0x95, 0x34, 0x50, 0x69, 0xef, 0x25, 0x37, 0xf5, 0x82, 0xe5, 0x36, 0x3e, 0xf5} }, -{ 0x0858, 16, {0x83, 0x74, 0xff, 0xf0, 0xf4, 0x60, 0x02, 0xc3, 0x22, 0xef, 0x25, 0x37, 0xf5, 0x82, 0xe5, 0x36} }, -{ 0x0868, 16, {0x3e, 0xf5, 0x83, 0xe4, 0xf0, 0x60, 0x02, 0xc3, 0x22, 0xef, 0x25, 0x37, 0xf5, 0x82, 0xe5, 0x36} }, -{ 0x0878, 16, {0x3e, 0xf5, 0x83, 0x74, 0xaa, 0xf0, 0x64, 0xaa, 0x60, 0x02, 0xc3, 0x22, 0xef, 0x25, 0x37, 0xf5} }, -{ 0x0888, 16, {0x82, 0xe5, 0x36, 0x3e, 0xf5, 0x83, 0x74, 0x55, 0xf0, 0x64, 0x55, 0x60, 0x02, 0xc3, 0x22, 0xad} }, -{ 0x0898, 16, {0x37, 0xe5, 0x37, 0x2f, 0xf5, 0x82, 0xe5, 0x36, 0x3e, 0xf5, 0x83, 0xed, 0xf0, 0xfc, 0xac, 0x05} }, -{ 0x08a8, 16, {0xed, 0x6c, 0x60, 0x02, 0xc3, 0x22, 0x05, 0x37, 0xe5, 0x37, 0x70, 0x02, 0x05, 0x36, 0x80, 0x8c} }, -{ 0x08b8, 16, {0xe4, 0xf5, 0x36, 0xf5, 0x37, 0xc3, 0xe5, 0x37, 0x95, 0x35, 0xe5, 0x36, 0x95, 0x34, 0x50, 0x27} }, -{ 0x08c8, 16, {0xef, 0x25, 0x37, 0xf5, 0x82, 0xe5, 0x36, 0x3e, 0xf5, 0x83, 0xe0, 0x65, 0x37, 0x60, 0x02, 0xc3} }, -{ 0x08d8, 16, {0x22, 0xef, 0x25, 0x37, 0xf5, 0x82, 0xe5, 0x36, 0x3e, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x37, 0xe5} }, -{ 0x08e8, 8, {0x37, 0x70, 0x02, 0x05, 0x36, 0x80, 0xce, 0xd3} }, -{ 0x08f0, 1, {0x22} }, -{ 0x08f1, 14, {0x90, 0x7f, 0x00, 0xe5, 0x10, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0xd3, 0x22} }, -{ 0x08ff, 1, {0x22} }, -{ 0x0900, 9, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} }, -{ 0x097d, 16, {0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} }, -{ 0x098d, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x3a, 0x02, 0x09, 0xd4} }, -{ 0x0999, 16, {0x02, 0x06, 0x9d, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, -{ 0x09a9, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, -{ 0x09b9, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, -{ 0x09c9, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x0e, 0x2d, 0xe4, 0x7e} }, -{ 0x09d9, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, -{ 0x09e9, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, -{ 0x09f9, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, -{ 0x0a09, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, -{ 0x0a19, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x0d, 0xd5, 0x90, 0x7f, 0x96, 0x74, 0x89} }, -{ 0x0a29, 16, {0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x0d, 0xd5, 0x90, 0x7f} }, -{ 0x0a39, 16, {0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x0d, 0xd5, 0x7f, 0x05, 0x7e, 0x00} }, -{ 0x0a49, 16, {0x12, 0x0d, 0xd5, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05} }, -{ 0x0a59, 16, {0x7e, 0x00, 0x12, 0x0d, 0xd5, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00} }, -{ 0x0a69, 16, {0x12, 0x0d, 0xd5, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x0d} }, -{ 0x0a79, 16, {0xd5, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x0d, 0xd5, 0x22} }, -{ 0x0a89, 16, {0x75, 0x33, 0x01, 0xe5, 0x33, 0x60, 0x1b, 0x7f, 0x01, 0x12, 0x0e, 0x18, 0x7f, 0x00, 0x7e, 0x0e} }, -{ 0x0a99, 16, {0x7d, 0x00, 0x7c, 0x01, 0x12, 0x08, 0x34, 0xe4, 0x33, 0xf5, 0x33, 0x70, 0x05, 0x7f, 0x0f, 0x12} }, -{ 0x0aa9, 16, {0x0e, 0x18, 0xe5, 0x33, 0x60, 0x1b, 0x7f, 0x02, 0x12, 0x0e, 0x18, 0x7f, 0x00, 0x7e, 0x80, 0x7d} }, -{ 0x0ab9, 16, {0x00, 0x7c, 0x80, 0x12, 0x08, 0x34, 0xe4, 0x33, 0xf5, 0x33, 0x70, 0x05, 0x7f, 0x0f, 0x12, 0x0e} }, -{ 0x0ac9, 16, {0x18, 0xe5, 0x33, 0x60, 0x1b, 0x7f, 0x03, 0x12, 0x0e, 0x18, 0x7f, 0x00, 0x7e, 0x20, 0x7d, 0x40} }, -{ 0x0ad9, 16, {0x7c, 0x5b, 0x12, 0x08, 0x34, 0xe4, 0x33, 0xf5, 0x33, 0x70, 0x05, 0x7f, 0x0f, 0x12, 0x0e, 0x18} }, -{ 0x0ae9, 13, {0xe5, 0x33, 0x60, 0x05, 0xe4, 0xff, 0x12, 0x0e, 0x18, 0xe5, 0x33, 0x24, 0xff} }, -{ 0x0af6, 1, {0x22} }, -{ 0x0af7, 8, {0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x10, 0xd3, 0x22} }, -{ 0x0aff, 1, {0x32} }, -{ 0x0b00, 16, {0x02, 0x0d, 0xa5, 0x00, 0x02, 0x0d, 0xec, 0x00, 0x02, 0x0d, 0x70, 0x00, 0x02, 0x0d, 0xbd, 0x00} }, -{ 0x0b10, 16, {0x02, 0x0e, 0x02, 0x00, 0x02, 0x0a, 0xff, 0x00, 0x02, 0x0e, 0x83, 0x00, 0x02, 0x0e, 0x84, 0x00} }, -{ 0x0b20, 16, {0x02, 0x0e, 0x85, 0x00, 0x02, 0x0e, 0x86, 0x00, 0x02, 0x0e, 0x87, 0x00, 0x02, 0x0e, 0x88, 0x00} }, -{ 0x0b30, 16, {0x02, 0x0e, 0x89, 0x00, 0x02, 0x0e, 0x8a, 0x00, 0x02, 0x0e, 0x8b, 0x00, 0x02, 0x0e, 0x8c, 0x00} }, -{ 0x0b40, 16, {0x02, 0x0e, 0x8d, 0x00, 0x02, 0x0e, 0x8e, 0x00, 0x02, 0x0e, 0x8f, 0x00, 0x02, 0x0e, 0x90, 0x00} }, -{ 0x0b50, 8, {0x02, 0x0e, 0x91, 0x00, 0x02, 0x0e, 0x92, 0x00} }, -{ 0x0b58, 16, {0xe4, 0xfe, 0x75, 0x2b, 0xff, 0x75, 0x2c, 0x11, 0x75, 0x2d, 0x12, 0xab, 0x2b, 0xaa, 0x2c, 0xa9} }, -{ 0x0b68, 16, {0x2d, 0x90, 0x00, 0x01, 0x12, 0x07, 0x85, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, -{ 0x0b78, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x07, 0xd4, 0x85, 0xf0, 0x29, 0xf5, 0x2a, 0x62, 0x29} }, -{ 0x0b88, 16, {0xe5, 0x29, 0x62, 0x2a, 0xe5, 0x2a, 0x62, 0x29, 0x29, 0xfd, 0xe5, 0x29, 0x3a, 0xa9, 0x05, 0x75} }, -{ 0x0b98, 14, {0x2b, 0xff, 0xf5, 0x2c, 0x89, 0x2d, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x0ba6, 1, {0x22} }, -{ 0x0ba7, 6, {0xab, 0x07, 0xaa, 0x06, 0xac, 0x05} }, -{ 0x0bad, 16, {0xe4, 0xfd, 0xe5, 0x11, 0x60, 0x11, 0xea, 0xff, 0xae, 0x05, 0x0d, 0xee, 0x24, 0x10, 0xf5, 0x82} }, -{ 0x0bbd, 16, {0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xef, 0xf0, 0xeb, 0xae, 0x05, 0x0d, 0x74, 0x10, 0x2e, 0xf5, 0x82} }, -{ 0x0bcd, 16, {0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xeb, 0xf0, 0xaf, 0x05, 0x0d, 0x74, 0x10, 0x2f, 0xf5, 0x82, 0xe4} }, -{ 0x0bdd, 16, {0x34, 0x0f, 0xf5, 0x83, 0xec, 0xf0, 0xaf, 0x0f, 0x7a, 0x0f, 0x7b, 0x10, 0x12, 0x0d, 0x51, 0x7f} }, -{ 0x0bed, 6, {0x0a, 0x7e, 0x00, 0x12, 0x0d, 0xd5} }, -{ 0x0bf3, 1, {0x22} }, -{ 0x0bf4, 10, {0x8e, 0x33, 0x8f, 0x34, 0x8d, 0x35, 0x8a, 0x36, 0x8b, 0x37} }, -{ 0x0bfe, 16, {0xe4, 0xfd, 0xf5, 0x38, 0xe5, 0x11, 0x60, 0x12, 0xe5, 0x33, 0xff, 0xae, 0x05, 0x0d, 0xee, 0x24} }, -{ 0x0c0e, 16, {0x13, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x34, 0xae, 0x05, 0x0d, 0x74} }, -{ 0x0c1e, 16, {0x13, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xe5, 0x34, 0xf0, 0xaf, 0x0f, 0x7a, 0x0f} }, -{ 0x0c2e, 16, {0x7b, 0x13, 0x12, 0x0d, 0x51, 0xaf, 0x0f, 0xad, 0x35, 0xab, 0x37, 0xaa, 0x36, 0x12, 0x0d, 0x32} }, -{ 0x0c3e, 1, {0x22} }, -{ 0x0c3f, 2, {0x8f, 0x29} }, -{ 0x0c41, 16, {0xe4, 0xf5, 0x2a, 0x75, 0x2b, 0xff, 0x75, 0x2c, 0x11, 0x75, 0x2d, 0x32, 0xab, 0x2b, 0xaa, 0x2c} }, -{ 0x0c51, 16, {0xa9, 0x2d, 0x90, 0x00, 0x01, 0x12, 0x07, 0x85, 0xb4, 0x03, 0x1d, 0xaf, 0x2a, 0x05, 0x2a, 0xef} }, -{ 0x0c61, 16, {0xb5, 0x29, 0x01, 0x22, 0x12, 0x07, 0x6c, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, -{ 0x0c71, 14, {0x2b, 0xff, 0xf5, 0x2c, 0x89, 0x2d, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x0c7f, 1, {0x22} }, -{ 0x0c80, 10, {0x8e, 0x33, 0x8f, 0x34, 0x8d, 0x35, 0x8a, 0x36, 0x8b, 0x37} }, -{ 0x0c8a, 16, {0xe4, 0xf5, 0x38, 0xe5, 0x38, 0xc3, 0x95, 0x35, 0x50, 0x20, 0x05, 0x34, 0xe5, 0x34, 0xae, 0x33} }, -{ 0x0c9a, 16, {0x70, 0x02, 0x05, 0x33, 0x14, 0xff, 0xe5, 0x37, 0x25, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x36, 0xf5} }, -{ 0x0caa, 10, {0x83, 0xe0, 0xfd, 0x12, 0x0b, 0xa7, 0x05, 0x38, 0x80, 0xd9} }, -{ 0x0cb4, 1, {0x22} }, -{ 0x0cb5, 16, {0xa9, 0x07, 0xe5, 0x0d, 0x70, 0x25, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xe9, 0x25, 0xe0} }, -{ 0x0cc5, 16, {0x44, 0x01, 0x90, 0x7f, 0xa6, 0xf0, 0x8d, 0x08, 0xaf, 0x03, 0xa9, 0x07, 0x75, 0x09, 0x01, 0x8a} }, -{ 0x0cd5, 13, {0x0a, 0x89, 0x0b, 0xe4, 0xf5, 0x0c, 0x75, 0x0d, 0x03, 0xd3, 0x22, 0xc3, 0x22} }, -{ 0x0ce2, 16, {0xa9, 0x07, 0xe5, 0x0d, 0x70, 0x23, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xe9, 0x25, 0xe0} }, -{ 0x0cf2, 16, {0x90, 0x7f, 0xa6, 0xf0, 0x8d, 0x08, 0xaf, 0x03, 0xa9, 0x07, 0x75, 0x09, 0x01, 0x8a, 0x0a, 0x89} }, -{ 0x0d02, 11, {0x0b, 0xe4, 0xf5, 0x0c, 0x75, 0x0d, 0x01, 0xd3, 0x22, 0xc3, 0x22} }, -{ 0x0d0d, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x06, 0x04, 0xe0, 0x44} }, -{ 0x0d1d, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x0d, 0xd5, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, -{ 0x0d2d, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, -{ 0x0d32, 16, {0x12, 0x0c, 0xb5, 0xe5, 0x0d, 0x24, 0xfa, 0x60, 0x10, 0x14, 0x60, 0x07, 0x24, 0x07, 0x70, 0xf3} }, -{ 0x0d42, 15, {0x7f, 0x08, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x07, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x06, 0x22} }, -{ 0x0d51, 16, {0x12, 0x0c, 0xe2, 0xe5, 0x0d, 0x24, 0xfa, 0x60, 0x10, 0x14, 0x60, 0x07, 0x24, 0x07, 0x70, 0xf3} }, -{ 0x0d61, 15, {0x7f, 0x08, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x07, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x06, 0x22} }, -{ 0x0d70, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0d80, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d8b, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x12, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x14, 0x7e, 0x00, 0x12} }, -{ 0x0d9b, 10, {0x0d, 0xd5, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22} }, -{ 0x0da5, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} }, -{ 0x0db5, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dbd, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x03, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} }, -{ 0x0dcd, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dd5, 16, {0x8e, 0x39, 0x8f, 0x3a, 0xe5, 0x3a, 0x15, 0x3a, 0xae, 0x39, 0x70, 0x02, 0x15, 0x39, 0x4e, 0x60} }, -{ 0x0de5, 7, {0x05, 0x12, 0x0e, 0x41, 0x80, 0xee, 0x22} }, -{ 0x0dec, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0} }, -{ 0x0dfc, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e02, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} }, -{ 0x0e12, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0e18, 16, {0xae, 0x07, 0x7f, 0x21, 0x7d, 0x01, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xab, 0x82} }, -{ 0x0e28, 5, {0xfa, 0x12, 0x0d, 0x51, 0x22} }, -{ 0x0e2d, 16, {0x50, 0x0f, 0x00, 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, 0x88, 0x83, 0xc6} }, -{ 0x0e3d, 3, {0xa1, 0x86, 0x8e} }, -{ 0x0e40, 1, {0x00} }, -{ 0x0e41, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, -{ 0x0e51, 1, {0x22} }, -{ 0x0e52, 14, {0x90, 0x7f, 0x00, 0xe5, 0x0e, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0xd3, 0x22} }, -{ 0x0e60, 8, {0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0e, 0xd3, 0x22} }, -{ 0x0e68, 8, {0xe4, 0xf5, 0x0d, 0xd2, 0xe9, 0xd2, 0xaf, 0x22} }, -{ 0x0e70, 4, {0x53, 0xd8, 0xef, 0x32} }, -{ 0x0e74, 3, {0xd2, 0x00, 0x22} }, -{ 0x0e77, 2, {0xd3, 0x22} }, -{ 0x0e79, 2, {0xd3, 0x22} }, -{ 0x0e7b, 2, {0xd3, 0x22} }, -{ 0x0e7d, 2, {0xd3, 0x22} }, -{ 0x0e7f, 2, {0xd3, 0x22} }, -{ 0x0e81, 2, {0xd3, 0x22} }, -{ 0x0e83, 1, {0x32} }, -{ 0x0e84, 1, {0x32} }, -{ 0x0e85, 1, {0x32} }, -{ 0x0e86, 1, {0x32} }, -{ 0x0e87, 1, {0x32} }, -{ 0x0e88, 1, {0x32} }, -{ 0x0e89, 1, {0x32} }, -{ 0x0e8a, 1, {0x32} }, -{ 0x0e8b, 1, {0x32} }, -{ 0x0e8c, 1, {0x32} }, -{ 0x0e8d, 1, {0x32} }, -{ 0x0e8e, 1, {0x32} }, -{ 0x0e8f, 1, {0x32} }, -{ 0x0e90, 1, {0x32} }, -{ 0x0e91, 1, {0x32} }, -{ 0x0e92, 1, {0x32} }, -{ 0x1100, 16, {0x12, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x47, 0x05, 0x10, 0x27, 0x01, 0x00, 0x01, 0x02} }, -{ 0x1110, 16, {0x00, 0x01, 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x03, 0xa0, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02} }, -{ 0x1120, 16, {0xff, 0x00, 0x00, 0x04, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} }, -{ 0x1130, 16, {0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x26, 0x03, 0x41, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x68, 0x00} }, -{ 0x1140, 16, {0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x43, 0x00, 0x68, 0x00, 0x69, 0x00, 0x70, 0x00, 0x73, 0x00} }, -{ 0x1150, 16, {0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x28, 0x03, 0x46, 0x00} }, -{ 0x1160, 16, {0x69, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00} }, -{ 0x1170, 16, {0x46, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x57, 0x00, 0x6f, 0x00, 0x72, 0x00} }, -{ 0x1180, 16, {0x6b, 0x00, 0x73, 0x00, 0x2a, 0x03, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x69, 0x00} }, -{ 0x1190, 16, {0x67, 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00} }, -{ 0x11a0, 16, {0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x22, 0x03} }, -{ 0x11b0, 16, {0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00} }, -{ 0x11c0, 16, {0x65, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00} }, -{ 0x11d0, 2, {0x00, 0x00} }, -{ 0xffff, 0, {0x00} } -}; - -#else - -static const struct whiteheat_hex_record whiteheat_loader[] = { -{ 0x0000, 3, {0x02, 0x09, 0x8d} }, -{ 0x0033, 3, {0x02, 0x08, 0xfb} }, -{ 0x0043, 3, {0x02, 0x0b, 0x00} }, -{ 0x004b, 3, {0x02, 0x05, 0xaa} }, -{ 0x0100, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x54, 0x10, 0xff, 0xc4, 0x54, 0x0f, 0x44, 0x50, 0xf5, 0x0f, 0x13, 0xe4} }, -{ 0x0110, 16, {0x33, 0xf5, 0x11, 0x90, 0x7f, 0xe9, 0xe0, 0x24, 0x5e, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x03} }, -{ 0x0120, 16, {0x78, 0x90, 0x01, 0x28, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x01, 0xbc, 0x02, 0x01, 0xbc, 0x02, 0x01} }, -{ 0x0130, 16, {0x91, 0x02, 0x01, 0x3d, 0x02, 0x01, 0x53, 0x02, 0x01, 0x6f, 0x02, 0x01, 0x9a, 0x90, 0x7f, 0x00} }, -{ 0x0140, 16, {0xe5, 0x11, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} }, -{ 0x0150, 16, {0x02, 0x03, 0x78, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4, 0x54, 0x0f, 0x90, 0x7f, 0x00, 0xf0, 0x90} }, -{ 0x0160, 16, {0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x03, 0x78, 0x12} }, -{ 0x0170, 16, {0x0a, 0x89, 0x50, 0x07, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0x80, 0x06, 0x90, 0x7f, 0x00, 0x74, 0x0f} }, -{ 0x0180, 16, {0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x03} }, -{ 0x0190, 16, {0x78, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0f, 0x02, 0x03, 0x78, 0x90, 0x7f, 0x00, 0x74, 0x07, 0xf0} }, -{ 0x01a0, 16, {0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xe8, 0x7e} }, -{ 0x01b0, 16, {0x03, 0x12, 0x0d, 0x94, 0xd2, 0x06, 0x12, 0x0c, 0xcc, 0x02, 0x03, 0x78, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x01c0, 16, {0x75, 0x28, 0x00, 0xf5, 0x29, 0xa3, 0xe0, 0xfe, 0xe4, 0xee, 0x42, 0x28, 0x90, 0x7f, 0xee, 0xe0} }, -{ 0x01d0, 16, {0x75, 0x2a, 0x00, 0xf5, 0x2b, 0xa3, 0xe0, 0xfe, 0xe4, 0xee, 0x42, 0x2a, 0x90, 0x7f, 0xe8, 0xe0} }, -{ 0x01e0, 16, {0x64, 0xc0, 0x60, 0x03, 0x02, 0x02, 0xc9, 0xe5, 0x2b, 0x45, 0x2a, 0x70, 0x03, 0x02, 0x03, 0x78} }, -{ 0x01f0, 16, {0xc3, 0xe5, 0x2b, 0x94, 0x40, 0xe5, 0x2a, 0x94, 0x00, 0x50, 0x08, 0x85, 0x2a, 0x2c, 0x85, 0x2b} }, -{ 0x0200, 16, {0x2d, 0x80, 0x06, 0x75, 0x2c, 0x00, 0x75, 0x2d, 0x40, 0x90, 0x7f, 0xe9, 0xe0, 0x64, 0xa3, 0x70} }, -{ 0x0210, 16, {0x34, 0xf5, 0x30, 0xf5, 0x31, 0xc3, 0xe5, 0x31, 0x95, 0x2d, 0xe5, 0x30, 0x95, 0x2c, 0x50, 0x5c} }, -{ 0x0220, 16, {0xe5, 0x29, 0x25, 0x31, 0xf5, 0x82, 0xe5, 0x30, 0x35, 0x28, 0xf5, 0x83, 0xe0, 0xff, 0x74, 0x00} }, -{ 0x0230, 16, {0x25, 0x31, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x31, 0xe5, 0x31, 0x70} }, -{ 0x0240, 16, {0x02, 0x05, 0x30, 0x80, 0xd0, 0xe4, 0xf5, 0x30, 0xf5, 0x31, 0xc3, 0xe5, 0x31, 0x95, 0x2d, 0xe5} }, -{ 0x0250, 16, {0x30, 0x95, 0x2c, 0x50, 0x18, 0x74, 0x00, 0x25, 0x31, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} }, -{ 0x0260, 16, {0x74, 0xcd, 0xf0, 0x05, 0x31, 0xe5, 0x31, 0x70, 0x02, 0x05, 0x30, 0x80, 0xdd, 0xaf, 0x29, 0xae} }, -{ 0x0270, 16, {0x28, 0xad, 0x2d, 0x7a, 0x7f, 0x79, 0x00, 0x7b, 0x00, 0x12, 0x0b, 0xf4, 0x90, 0x7f, 0xb5, 0xe5} }, -{ 0x0280, 16, {0x2d, 0xf0, 0xe5, 0x2d, 0x25, 0x29, 0xf5, 0x29, 0xe5, 0x2c, 0x35, 0x28, 0xf5, 0x28, 0xc3, 0xe5} }, -{ 0x0290, 16, {0x2b, 0x95, 0x2d, 0xf5, 0x2b, 0xe5, 0x2a, 0x95, 0x2c, 0xf5, 0x2a, 0x90, 0x7f, 0x92, 0xe0, 0xff} }, -{ 0x02a0, 16, {0xc4, 0x54, 0x0f, 0x75, 0x2e, 0x00, 0xf5, 0x2f, 0xd3, 0x94, 0x00, 0xe5, 0x2e, 0x94, 0x00, 0x50} }, -{ 0x02b0, 16, {0x0c, 0x90, 0x7f, 0xb4, 0xe0, 0x20, 0xe1, 0x03, 0x02, 0x01, 0xe7, 0x80, 0xf4, 0x90, 0x7f, 0xb4} }, -{ 0x02c0, 16, {0xe0, 0x20, 0xe2, 0x03, 0x02, 0x01, 0xe7, 0x80, 0xf4, 0x90, 0x7f, 0xe8, 0xe0, 0x64, 0x40, 0x60} }, -{ 0x02d0, 16, {0x03, 0x02, 0x03, 0x78, 0xe5, 0x2b, 0x45, 0x2a, 0x70, 0x03, 0x02, 0x03, 0x78, 0xe4, 0x90, 0x7f} }, -{ 0x02e0, 16, {0xc5, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4, 0x54, 0x0f, 0x75, 0x2e, 0x00, 0xf5, 0x2f, 0xd3} }, -{ 0x02f0, 16, {0x94, 0x00, 0xe5, 0x2e, 0x94, 0x00, 0x50, 0x09, 0x90, 0x7f, 0xc4, 0xe0, 0x30, 0xe1, 0x09, 0x80} }, -{ 0x0300, 16, {0xf7, 0x90, 0x7f, 0xb4, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x7f, 0xc5, 0xe0, 0x75, 0x2c, 0x00, 0xf5} }, -{ 0x0310, 16, {0x2d, 0x90, 0x7f, 0xe9, 0xe0, 0x64, 0xa3, 0x70, 0x34, 0xf5, 0x30, 0xf5, 0x31, 0xc3, 0xe5, 0x31} }, -{ 0x0320, 16, {0x95, 0x2d, 0xe5, 0x30, 0x95, 0x2c, 0x50, 0x34, 0x74, 0xc0, 0x25, 0x31, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x0330, 1, {0x7e} }, -{ 0x0331, 16, {0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x29, 0x25, 0x31, 0xf5, 0x82, 0xe5, 0x30, 0x35, 0x28, 0xf5, 0x83} }, -{ 0x0341, 16, {0xef, 0xf0, 0x05, 0x31, 0xe5, 0x31, 0x70, 0x02, 0x05, 0x30, 0x80, 0xd0, 0xaf, 0x29, 0xae, 0x28} }, -{ 0x0351, 16, {0xad, 0x2d, 0x7a, 0x7e, 0x79, 0xc0, 0x7b, 0xc0, 0x12, 0x0c, 0x3f, 0xe5, 0x2d, 0x25, 0x29, 0xf5} }, -{ 0x0361, 16, {0x29, 0xe5, 0x2c, 0x35, 0x28, 0xf5, 0x28, 0xc3, 0xe5, 0x2b, 0x95, 0x2d, 0xf5, 0x2b, 0xe5, 0x2a} }, -{ 0x0371, 9, {0x95, 0x2c, 0xf5, 0x2a, 0x02, 0x02, 0xd4, 0xc3, 0x22} }, -{ 0x037a, 16, {0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0xce, 0x24} }, -{ 0x038a, 16, {0xfe, 0x70, 0x03, 0x02, 0x05, 0x42, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x4c, 0x14, 0x70, 0x03} }, -{ 0x039a, 16, {0x02, 0x04, 0x46, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x40, 0x24} }, -{ 0x03aa, 16, {0x05, 0x60, 0x03, 0x02, 0x05, 0x96, 0x12, 0x0e, 0x44, 0x40, 0x03, 0x02, 0x05, 0xa2, 0x90, 0x7f} }, -{ 0x03ba, 16, {0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02, 0x70, 0x69, 0x74, 0x11, 0x90} }, -{ 0x03ca, 16, {0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xea, 0xe0} }, -{ 0x03da, 16, {0xff, 0x12, 0x0b, 0x58, 0x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0xea, 0x49, 0x60, 0x11, 0xae, 0x02} }, -{ 0x03ea, 16, {0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa2, 0x90} }, -{ 0x03fa, 16, {0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x08} }, -{ 0x040a, 16, {0xba, 0x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0xea, 0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f} }, -{ 0x041a, 16, {0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xb4, 0xe0} }, -{ 0x042a, 16, {0x44, 0x01, 0xf0, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa2} }, -{ 0x043a, 16, {0x12, 0x0e, 0x1f, 0x02, 0x05, 0xa2, 0x12, 0x0e, 0x2d, 0x02, 0x05, 0xa2, 0x12, 0x0a, 0xf7, 0x02} }, -{ 0x044a, 16, {0x05, 0xa2, 0x12, 0x0e, 0x11, 0x02, 0x05, 0xa2, 0x12, 0x0e, 0x46, 0x40, 0x03, 0x02, 0x05, 0xa2} }, -{ 0x045a, 16, {0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2} }, -{ 0x046a, 16, {0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x02, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0} }, -{ 0x047a, 16, {0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa2, 0xe4, 0x90, 0x7f, 0x00} }, -{ 0x048a, 16, {0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xec, 0xe0} }, -{ 0x049a, 16, {0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} }, -{ 0x04aa, 16, {0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3} }, -{ 0x04ba, 16, {0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} }, -{ 0x04ca, 16, {0xf0, 0x02, 0x05, 0xa2, 0x12, 0x0e, 0x48, 0x40, 0x03, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xe8, 0xe0} }, -{ 0x04da, 16, {0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xea, 0xe0, 0xb4} }, -{ 0x04ea, 16, {0x01, 0x05, 0xc2, 0x00, 0x02, 0x05, 0xa2, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05} }, -{ 0x04fa, 16, {0xa2, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4} }, -{ 0x050a, 16, {0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} }, -{ 0x051a, 16, {0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f} }, -{ 0x052a, 16, {0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x69, 0x90} }, -{ 0x053a, 16, {0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x60, 0x12, 0x0e, 0x4a, 0x50, 0x5b, 0x90, 0x7f, 0xe8} }, -{ 0x054a, 16, {0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4f, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04} }, -{ 0x055a, 16, {0xd2, 0x00, 0x80, 0x44, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x3b, 0x90, 0x7f, 0xea} }, -{ 0x056a, 16, {0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0} }, -{ 0x057a, 16, {0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01} }, -{ 0x058a, 16, {0xf0, 0x80, 0x15, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x0c, 0x12, 0x01, 0x00, 0x50} }, -{ 0x059a, 16, {0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22} }, -{ 0x05aa, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} }, -{ 0x05ba, 16, {0xd0, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x06, 0xc0, 0x07, 0x90, 0x7f, 0xa5} }, -{ 0x05ca, 16, {0xe0, 0x30, 0xe2, 0x06, 0x75, 0x0d, 0x06, 0x02, 0x06, 0x76, 0x90, 0x7f, 0xa5, 0xe0, 0x20, 0xe1} }, -{ 0x05da, 16, {0x0c, 0xe5, 0x0d, 0x64, 0x02, 0x60, 0x06, 0x75, 0x0d, 0x07, 0x02, 0x06, 0x76, 0xaf, 0x0d, 0xef} }, -{ 0x05ea, 16, {0x24, 0xfe, 0x60, 0x48, 0x14, 0x60, 0x2c, 0x24, 0xfe, 0x60, 0x77, 0x24, 0x04, 0x60, 0x03, 0x02} }, -{ 0x05fa, 16, {0x06, 0x76, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0xaf, 0x0c, 0x05, 0x0c, 0x8f, 0x82, 0x75, 0x83} }, -{ 0x060a, 16, {0x00, 0x12, 0x08, 0x22, 0x90, 0x7f, 0xa6, 0xf0, 0xe5, 0x0c, 0x65, 0x08, 0x70, 0x5e, 0x75, 0x0d} }, -{ 0x061a, 16, {0x05, 0x80, 0x59, 0x90, 0x7f, 0xa6, 0xe0, 0xab, 0x09, 0xaa, 0x0a, 0xa9, 0x0b, 0xae, 0x0c, 0x8e} }, -{ 0x062a, 16, {0x82, 0x75, 0x83, 0x00, 0x12, 0x08, 0x4f, 0x75, 0x0d, 0x02, 0x80, 0x40, 0xe5, 0x08, 0x24, 0xfe} }, -{ 0x063a, 16, {0xb5, 0x0c, 0x07, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x20, 0xf0, 0xe5, 0x08, 0x14, 0xb5, 0x0c, 0x0a} }, -{ 0x064a, 16, {0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe4, 0xf5, 0x0d, 0x90, 0x7f, 0xa6, 0xe0, 0xab, 0x09} }, -{ 0x065a, 16, {0xaa, 0x0a, 0xa9, 0x0b, 0xae, 0x0c, 0x8e, 0x82, 0x75, 0x83, 0x00, 0x12, 0x08, 0x4f, 0x05, 0x0c} }, -{ 0x066a, 16, {0x80, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe4, 0xf5, 0x0d, 0x53, 0x91, 0xdf, 0xd0} }, -{ 0x067a, 16, {0x07, 0xd0, 0x06, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x86, 0xd0} }, -{ 0x068a, 10, {0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0694, 16, {0x8c, 0x33, 0x8d, 0x34, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0xc0, 0xf0, 0xe4, 0xf5, 0x35, 0xf5, 0x36} }, -{ 0x06a4, 16, {0xc3, 0xe5, 0x36, 0x95, 0x34, 0xe5, 0x35, 0x95, 0x33, 0x50, 0x69, 0xef, 0x25, 0x36, 0xf5, 0x82} }, -{ 0x06b4, 16, {0xe5, 0x35, 0x3e, 0xf5, 0x83, 0x74, 0xff, 0xf0, 0xf4, 0x60, 0x02, 0xc3, 0x22, 0xef, 0x25, 0x36} }, -{ 0x06c4, 16, {0xf5, 0x82, 0xe5, 0x35, 0x3e, 0xf5, 0x83, 0xe4, 0xf0, 0x60, 0x02, 0xc3, 0x22, 0xef, 0x25, 0x36} }, -{ 0x06d4, 16, {0xf5, 0x82, 0xe5, 0x35, 0x3e, 0xf5, 0x83, 0x74, 0xaa, 0xf0, 0x64, 0xaa, 0x60, 0x02, 0xc3, 0x22} }, -{ 0x06e4, 16, {0xef, 0x25, 0x36, 0xf5, 0x82, 0xe5, 0x35, 0x3e, 0xf5, 0x83, 0x74, 0x55, 0xf0, 0x64, 0x55, 0x60} }, -{ 0x06f4, 16, {0x02, 0xc3, 0x22, 0xad, 0x36, 0xe5, 0x36, 0x2f, 0xf5, 0x82, 0xe5, 0x35, 0x3e, 0xf5, 0x83, 0xed} }, -{ 0x0704, 16, {0xf0, 0xfc, 0xac, 0x05, 0xed, 0x6c, 0x60, 0x02, 0xc3, 0x22, 0x05, 0x36, 0xe5, 0x36, 0x70, 0x02} }, -{ 0x0714, 16, {0x05, 0x35, 0x80, 0x8c, 0xe4, 0xf5, 0x35, 0xf5, 0x36, 0xc3, 0xe5, 0x36, 0x95, 0x34, 0xe5, 0x35} }, -{ 0x0724, 16, {0x95, 0x33, 0x50, 0x27, 0xef, 0x25, 0x36, 0xf5, 0x82, 0xe5, 0x35, 0x3e, 0xf5, 0x83, 0xe0, 0x65} }, -{ 0x0734, 16, {0x36, 0x60, 0x02, 0xc3, 0x22, 0xef, 0x25, 0x36, 0xf5, 0x82, 0xe5, 0x35, 0x3e, 0xf5, 0x83, 0xe4} }, -{ 0x0744, 13, {0xf0, 0x05, 0x36, 0xe5, 0x36, 0x70, 0x02, 0x05, 0x35, 0x80, 0xce, 0xd3, 0x22} }, -{ 0x0751, 16, {0xc2, 0x04, 0xd2, 0x05, 0xc2, 0x03, 0xc2, 0x00, 0xc2, 0x02, 0xc2, 0x01, 0x12, 0x0e, 0x3d, 0xd2} }, -{ 0x0761, 16, {0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f} }, -{ 0x0771, 16, {0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x7f, 0x93, 0x74} }, -{ 0x0781, 16, {0x30, 0xf0, 0x12, 0x0a, 0x19, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0} }, -{ 0x0791, 16, {0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0x12, 0x0e, 0x35, 0x20, 0x01, 0x42, 0x75, 0x24, 0x00, 0x75, 0x23} }, -{ 0x07a1, 16, {0x00, 0x75, 0x22, 0x00, 0x75, 0x21, 0x00, 0x7f, 0x48, 0x7e, 0x92, 0x7d, 0x00, 0x7c, 0x00, 0xab} }, -{ 0x07b1, 16, {0x24, 0xaa, 0x23, 0xa9, 0x22, 0xa8, 0x21, 0xc3, 0x12, 0x08, 0xa9, 0x50, 0xdb, 0x20, 0x01, 0xd8} }, -{ 0x07c1, 16, {0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xe5, 0x24, 0x24, 0x01, 0xf5, 0x24, 0xea, 0x35, 0x23, 0xf5} }, -{ 0x07d1, 16, {0x23, 0xe9, 0x35, 0x22, 0xf5, 0x22, 0xe8, 0x35, 0x21, 0xf5, 0x21, 0x80, 0xca, 0x30, 0x01, 0x05} }, -{ 0x07e1, 16, {0x12, 0x03, 0x7a, 0xc2, 0x01, 0x30, 0x04, 0x1a, 0x12, 0x0e, 0x40, 0x50, 0x13, 0x12, 0x09, 0x00} }, -{ 0x07f1, 16, {0x30, 0x00, 0x07, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0xf3, 0x12, 0x0d, 0x4a, 0x12, 0x0e, 0x42} }, -{ 0x0801, 8, {0xc2, 0x03, 0x12, 0x08, 0xff, 0x80, 0xd6, 0x22} }, -{ 0x0809, 16, {0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} }, -{ 0x0819, 9, {0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x0822, 16, {0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} }, -{ 0x0832, 16, {0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} }, -{ 0x0842, 13, {0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} }, -{ 0x084f, 16, {0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 0xf0} }, -{ 0x085f, 16, {0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xc8, 0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 0xc8} }, -{ 0x086f, 2, {0xf2, 0x22} }, -{ 0x0871, 16, {0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} }, -{ 0x0881, 16, {0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} }, -{ 0x0891, 16, {0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} }, -{ 0x08a1, 8, {0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} }, -{ 0x08a9, 16, {0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} }, -{ 0x08b9, 1, {0x22} }, -{ 0x08ba, 2, {0x8f, 0x28} }, -{ 0x08bc, 16, {0xe4, 0xf5, 0x29, 0x75, 0x2a, 0xff, 0x75, 0x2b, 0x11, 0x75, 0x2c, 0x32, 0xab, 0x2a, 0xaa, 0x2b} }, -{ 0x08cc, 16, {0xa9, 0x2c, 0x90, 0x00, 0x01, 0x12, 0x08, 0x22, 0xb4, 0x03, 0x1d, 0xaf, 0x29, 0x05, 0x29, 0xef} }, -{ 0x08dc, 16, {0xb5, 0x28, 0x01, 0x22, 0x12, 0x08, 0x09, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} }, -{ 0x08ec, 14, {0x2a, 0xff, 0xf5, 0x2b, 0x89, 0x2c, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x08fa, 1, {0x22} }, -{ 0x08fb, 4, {0x53, 0xd8, 0xef, 0x32} }, -{ 0x08ff, 1, {0x22} }, -{ 0x0900, 9, {0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} }, -{ 0x097d, 16, {0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} }, -{ 0x098d, 12, {0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x39, 0x02, 0x09, 0xd4} }, -{ 0x0999, 16, {0x02, 0x07, 0x51, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} }, -{ 0x09a9, 16, {0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} }, -{ 0x09b9, 16, {0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} }, -{ 0x09c9, 16, {0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x0d, 0xec, 0xe4, 0x7e} }, -{ 0x09d9, 16, {0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} }, -{ 0x09e9, 16, {0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} }, -{ 0x09f9, 16, {0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} }, -{ 0x0a09, 16, {0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} }, -{ 0x0a19, 16, {0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x0d, 0x94, 0x90, 0x7f, 0x96, 0x74, 0x89} }, -{ 0x0a29, 16, {0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x0d, 0x94, 0x90, 0x7f} }, -{ 0x0a39, 16, {0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x0d, 0x94, 0x7f, 0x05, 0x7e, 0x00} }, -{ 0x0a49, 16, {0x12, 0x0d, 0x94, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05} }, -{ 0x0a59, 16, {0x7e, 0x00, 0x12, 0x0d, 0x94, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00} }, -{ 0x0a69, 16, {0x12, 0x0d, 0x94, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x0d} }, -{ 0x0a79, 16, {0x94, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x0d, 0x94, 0x22} }, -{ 0x0a89, 16, {0x75, 0x32, 0x01, 0xe5, 0x32, 0x60, 0x1b, 0x7f, 0x01, 0x12, 0x0d, 0xd7, 0x7f, 0x00, 0x7e, 0x0e} }, -{ 0x0a99, 16, {0x7d, 0x00, 0x7c, 0x01, 0x12, 0x06, 0x94, 0xe4, 0x33, 0xf5, 0x32, 0x70, 0x05, 0x7f, 0x0f, 0x12} }, -{ 0x0aa9, 16, {0x0d, 0xd7, 0xe5, 0x32, 0x60, 0x1b, 0x7f, 0x02, 0x12, 0x0d, 0xd7, 0x7f, 0x00, 0x7e, 0x80, 0x7d} }, -{ 0x0ab9, 16, {0x00, 0x7c, 0x80, 0x12, 0x06, 0x94, 0xe4, 0x33, 0xf5, 0x32, 0x70, 0x05, 0x7f, 0x0f, 0x12, 0x0d} }, -{ 0x0ac9, 16, {0xd7, 0xe5, 0x32, 0x60, 0x1b, 0x7f, 0x03, 0x12, 0x0d, 0xd7, 0x7f, 0x00, 0x7e, 0x20, 0x7d, 0x40} }, -{ 0x0ad9, 16, {0x7c, 0x5b, 0x12, 0x06, 0x94, 0xe4, 0x33, 0xf5, 0x32, 0x70, 0x05, 0x7f, 0x0f, 0x12, 0x0d, 0xd7} }, -{ 0x0ae9, 14, {0xe5, 0x32, 0x60, 0x05, 0xe4, 0xff, 0x12, 0x0d, 0xd7, 0xe5, 0x32, 0x24, 0xff, 0x22} }, -{ 0x0af7, 8, {0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x10, 0xd3, 0x22} }, -{ 0x0aff, 1, {0x32} }, -{ 0x0b00, 16, {0x02, 0x0d, 0x64, 0x00, 0x02, 0x0d, 0xab, 0x00, 0x02, 0x0d, 0x2f, 0x00, 0x02, 0x0d, 0x7c, 0x00} }, -{ 0x0b10, 16, {0x02, 0x0d, 0xc1, 0x00, 0x02, 0x0a, 0xff, 0x00, 0x02, 0x0e, 0x4c, 0x00, 0x02, 0x0e, 0x4d, 0x00} }, -{ 0x0b20, 16, {0x02, 0x0e, 0x4e, 0x00, 0x02, 0x0e, 0x4f, 0x00, 0x02, 0x0e, 0x50, 0x00, 0x02, 0x0e, 0x51, 0x00} }, -{ 0x0b30, 16, {0x02, 0x0e, 0x52, 0x00, 0x02, 0x0e, 0x53, 0x00, 0x02, 0x0e, 0x54, 0x00, 0x02, 0x0e, 0x55, 0x00} }, -{ 0x0b40, 16, {0x02, 0x0e, 0x56, 0x00, 0x02, 0x0e, 0x57, 0x00, 0x02, 0x0e, 0x58, 0x00, 0x02, 0x0e, 0x59, 0x00} }, -{ 0x0b50, 8, {0x02, 0x0e, 0x5a, 0x00, 0x02, 0x0e, 0x5b, 0x00} }, -{ 0x0b58, 16, {0xe4, 0xfe, 0x75, 0x2a, 0xff, 0x75, 0x2b, 0x11, 0x75, 0x2c, 0x12, 0xab, 0x2a, 0xaa, 0x2b, 0xa9} }, -{ 0x0b68, 16, {0x2c, 0x90, 0x00, 0x01, 0x12, 0x08, 0x22, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} }, -{ 0x0b78, 16, {0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x08, 0x71, 0x85, 0xf0, 0x28, 0xf5, 0x29, 0x62, 0x28} }, -{ 0x0b88, 16, {0xe5, 0x28, 0x62, 0x29, 0xe5, 0x29, 0x62, 0x28, 0x29, 0xfd, 0xe5, 0x28, 0x3a, 0xa9, 0x05, 0x75} }, -{ 0x0b98, 14, {0x2a, 0xff, 0xf5, 0x2b, 0x89, 0x2c, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} }, -{ 0x0ba6, 1, {0x22} }, -{ 0x0ba7, 16, {0xab, 0x07, 0xaa, 0x06, 0xac, 0x05, 0xe4, 0xfd, 0xe5, 0x11, 0x60, 0x11, 0xea, 0xff, 0xae, 0x05} }, -{ 0x0bb7, 16, {0x0d, 0xee, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xef, 0xf0, 0xeb, 0xae, 0x05} }, -{ 0x0bc7, 16, {0x0d, 0x74, 0x10, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xeb, 0xf0, 0xaf, 0x05, 0x0d} }, -{ 0x0bd7, 16, {0x74, 0x10, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xf5, 0x83, 0xec, 0xf0, 0xaf, 0x0f, 0x7a, 0x0f} }, -{ 0x0be7, 13, {0x7b, 0x10, 0x12, 0x0d, 0x10, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x0d, 0x94, 0x22} }, -{ 0x0bf4, 16, {0x8e, 0x32, 0x8f, 0x33, 0x8d, 0x34, 0x8a, 0x35, 0x8b, 0x36, 0xe4, 0xfd, 0xf5, 0x37, 0xe5, 0x11} }, -{ 0x0c04, 16, {0x60, 0x12, 0xe5, 0x32, 0xff, 0xae, 0x05, 0x0d, 0xee, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x34, 0x0f} }, -{ 0x0c14, 16, {0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x33, 0xae, 0x05, 0x0d, 0x74, 0x13, 0x2e, 0xf5, 0x82, 0xe4, 0x34} }, -{ 0x0c24, 16, {0x0f, 0xf5, 0x83, 0xe5, 0x33, 0xf0, 0xaf, 0x0f, 0x7a, 0x0f, 0x7b, 0x13, 0x12, 0x0d, 0x10, 0xaf} }, -{ 0x0c34, 11, {0x0f, 0xad, 0x34, 0xab, 0x36, 0xaa, 0x35, 0x12, 0x0c, 0xf1, 0x22} }, -{ 0x0c3f, 16, {0x8e, 0x32, 0x8f, 0x33, 0x8d, 0x34, 0x8a, 0x35, 0x8b, 0x36, 0xe4, 0xf5, 0x37, 0xe5, 0x37, 0xc3} }, -{ 0x0c4f, 16, {0x95, 0x34, 0x50, 0x20, 0x05, 0x33, 0xe5, 0x33, 0xae, 0x32, 0x70, 0x02, 0x05, 0x32, 0x14, 0xff} }, -{ 0x0c5f, 16, {0xe5, 0x36, 0x25, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x35, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x0b, 0xa7} }, -{ 0x0c6f, 5, {0x05, 0x37, 0x80, 0xd9, 0x22} }, -{ 0x0c74, 16, {0xa9, 0x07, 0xe5, 0x0d, 0x70, 0x25, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xe9, 0x25, 0xe0} }, -{ 0x0c84, 16, {0x44, 0x01, 0x90, 0x7f, 0xa6, 0xf0, 0x8d, 0x08, 0xaf, 0x03, 0xa9, 0x07, 0x75, 0x09, 0x01, 0x8a} }, -{ 0x0c94, 13, {0x0a, 0x89, 0x0b, 0xe4, 0xf5, 0x0c, 0x75, 0x0d, 0x03, 0xd3, 0x22, 0xc3, 0x22} }, -{ 0x0ca1, 16, {0xa9, 0x07, 0xe5, 0x0d, 0x70, 0x23, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0xe9, 0x25, 0xe0} }, -{ 0x0cb1, 16, {0x90, 0x7f, 0xa6, 0xf0, 0x8d, 0x08, 0xaf, 0x03, 0xa9, 0x07, 0x75, 0x09, 0x01, 0x8a, 0x0a, 0x89} }, -{ 0x0cc1, 11, {0x0b, 0xe4, 0xf5, 0x0c, 0x75, 0x0d, 0x01, 0xd3, 0x22, 0xc3, 0x22} }, -{ 0x0ccc, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x06, 0x04, 0xe0, 0x44} }, -{ 0x0cdc, 16, {0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x0d, 0x94, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} }, -{ 0x0cec, 5, {0xe0, 0x44, 0x04, 0xf0, 0x22} }, -{ 0x0cf1, 16, {0x12, 0x0c, 0x74, 0xe5, 0x0d, 0x24, 0xfa, 0x60, 0x10, 0x14, 0x60, 0x07, 0x24, 0x07, 0x70, 0xf3} }, -{ 0x0d01, 15, {0x7f, 0x08, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x07, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x06, 0x22} }, -{ 0x0d10, 16, {0x12, 0x0c, 0xa1, 0xe5, 0x0d, 0x24, 0xfa, 0x60, 0x10, 0x14, 0x60, 0x07, 0x24, 0x07, 0x70, 0xf3} }, -{ 0x0d20, 15, {0x7f, 0x08, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x07, 0x22, 0xe4, 0xf5, 0x0d, 0x7f, 0x06, 0x22} }, -{ 0x0d2f, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} }, -{ 0x0d3f, 11, {0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d4a, 16, {0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x12, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x14, 0x7e, 0x00, 0x12} }, -{ 0x0d5a, 10, {0x0d, 0x94, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22} }, -{ 0x0d64, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} }, -{ 0x0d74, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d7c, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x03, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} }, -{ 0x0d8c, 8, {0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0d94, 16, {0x8e, 0x38, 0x8f, 0x39, 0xe5, 0x39, 0x15, 0x39, 0xae, 0x38, 0x70, 0x02, 0x15, 0x38, 0x4e, 0x60} }, -{ 0x0da4, 7, {0x05, 0x12, 0x0e, 0x00, 0x80, 0xee, 0x22} }, -{ 0x0dab, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0} }, -{ 0x0dbb, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dc1, 16, {0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} }, -{ 0x0dd1, 6, {0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} }, -{ 0x0dd7, 16, {0xae, 0x07, 0x7f, 0x21, 0x7d, 0x01, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x0f, 0xab, 0x82} }, -{ 0x0de7, 5, {0xfa, 0x12, 0x0d, 0x10, 0x22} }, -{ 0x0dec, 16, {0x50, 0x0f, 0x00, 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, 0x88, 0x83, 0xc6} }, -{ 0x0dfc, 3, {0xa1, 0x86, 0x8e} }, -{ 0x0dff, 1, {0x00} }, -{ 0x0e00, 16, {0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} }, -{ 0x0e10, 1, {0x22} }, -{ 0x0e11, 14, {0x90, 0x7f, 0x00, 0xe5, 0x10, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0xd3, 0x22} }, -{ 0x0e1f, 14, {0x90, 0x7f, 0x00, 0xe5, 0x0e, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0xd3, 0x22} }, -{ 0x0e2d, 8, {0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0e, 0xd3, 0x22} }, -{ 0x0e35, 8, {0xe4, 0xf5, 0x0d, 0xd2, 0xe9, 0xd2, 0xaf, 0x22} }, -{ 0x0e3d, 3, {0xd2, 0x00, 0x22} }, -{ 0x0e40, 2, {0xd3, 0x22} }, -{ 0x0e42, 2, {0xd3, 0x22} }, -{ 0x0e44, 2, {0xd3, 0x22} }, -{ 0x0e46, 2, {0xd3, 0x22} }, -{ 0x0e48, 2, {0xd3, 0x22} }, -{ 0x0e4a, 2, {0xd3, 0x22} }, -{ 0x0e4c, 1, {0x32} }, -{ 0x0e4d, 1, {0x32} }, -{ 0x0e4e, 1, {0x32} }, -{ 0x0e4f, 1, {0x32} }, -{ 0x0e50, 1, {0x32} }, -{ 0x0e51, 1, {0x32} }, -{ 0x0e52, 1, {0x32} }, -{ 0x0e53, 1, {0x32} }, -{ 0x0e54, 1, {0x32} }, -{ 0x0e55, 1, {0x32} }, -{ 0x0e56, 1, {0x32} }, -{ 0x0e57, 1, {0x32} }, -{ 0x0e58, 1, {0x32} }, -{ 0x0e59, 1, {0x32} }, -{ 0x0e5a, 1, {0x32} }, -{ 0x0e5b, 1, {0x32} }, -{ 0x1100, 16, {0x12, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x47, 0x05, 0x10, 0x27, 0x01, 0x00, 0x01, 0x02} }, -{ 0x1110, 16, {0x00, 0x01, 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x03, 0xa0, 0x00, 0x09, 0x04, 0x00, 0x00, 0x02} }, -{ 0x1120, 16, {0xff, 0x00, 0x00, 0x04, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} }, -{ 0x1130, 16, {0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x26, 0x03, 0x41, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x68, 0x00} }, -{ 0x1140, 16, {0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x43, 0x00, 0x68, 0x00, 0x69, 0x00, 0x70, 0x00, 0x73, 0x00} }, -{ 0x1150, 16, {0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x28, 0x03, 0x46, 0x00} }, -{ 0x1160, 16, {0x69, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00} }, -{ 0x1170, 16, {0x46, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x57, 0x00, 0x6f, 0x00, 0x72, 0x00} }, -{ 0x1180, 16, {0x6b, 0x00, 0x73, 0x00, 0x2a, 0x03, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x69, 0x00} }, -{ 0x1190, 16, {0x67, 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00} }, -{ 0x11a0, 16, {0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x22, 0x03} }, -{ 0x11b0, 16, {0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00} }, -{ 0x11c0, 16, {0x65, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00} }, -{ 0x11d0, 2, {0x00, 0x00} }, -{ 0xffff, 0, {0x00} } -}; -#endif diff --git a/firmware/Makefile b/firmware/Makefile index 28f975f..f937648 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -54,6 +54,8 @@ fw-shipped- := keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw endif fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw +fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ + # whiteheat_loader_debug.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw diff --git a/firmware/WHENCE b/firmware/WHENCE index 205be9f..47ab241 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -205,3 +205,24 @@ Licence: Allegedly GPLv2+, but no source visible. Marked: Found in hex form in kernel source. -------------------------------------------------------------------------- + +Driver: whiteheat -- USB ConnectTech WhiteHEAT serial device + +File: whiteheat.fw +Version: 4.06 + +File: whiteheat_loader.fw +File: whiteheat_loader_debug.fw + +Licence: Allegedly GPLv2, but no source visible. Marked: + Copyright (C) 2000-2002 ConnectTech Inc + +Debug loader claims the following behaviour: + Port 1 LED flashes when the vend_ax program is running + Port 2 LED flashes when any SETUP command arrives + Port 3 LED flashes when any valid VENDOR request occurs + Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs + +Converted from Intel HEX files, used in our binary representation of ihex. + +-------------------------------------------------------------------------- diff --git a/firmware/whiteheat.HEX b/firmware/whiteheat.HEX new file mode 100644 index 0000000..8dae602 --- /dev/null +++ b/firmware/whiteheat.HEX @@ -0,0 +1,1097 @@ +:030000000297E381 +:03000300021312D3 +:03000B00020BB530 +:0300330002081CA4 +:03004300020A00AE +:03005B0002833BE2 +:10037000907FE9E070030204731470030204E72421 +:10038000FE700302054F24FB700302046414700323 +:1003900002045214700302043A1470030204492444 +:1003A00005600302059E907FEBE024FE601614605A +:1003B000362402707B7412907FD4F07400907FD545 +:1003C000F00205A5907FEAE0FF120A99EA49600D64 +:1003D000EA907FD4F0E9907FD5F00205A5907FB434 +:1003E000E04401F00205A5907FEAE0FF120A58EA16 +:1003F00049603312A23BF54E907FEEE0FFE54ED30D +:100400009F4003E0F54EE54ED394404003754E40C7 +:10041000AE02AF017C7F7D00AB4E129137907FB56D +:10042000E54EF00205A5907FB4E04401F00205A579 +:10043000907FB4E04401F00205A5907F00E521F033 +:10044000907FB57401F00205A5907FEAE0F52102E6 +:1004500005A5907FEAE0F535D202438810D2EBD2B1 +:10046000A80205A5907F00E535F0907FB57401F0F6 +:100470000205A5907FE8E0247F6024146031240207 +:10048000705BA200E433FF25E0FFA205E4334F9048 +:100490007F00F0E4A3F0907FB57402F00205A5E4BC +:1004A000907F00F0A3F0907FB57402F00205A59054 +:1004B0007FECE0F45480FFC4540FFFE054072F2575 +:1004C000E024B4F582E4347FF583E05401907F00AA +:1004D000F0E4A3F0907FB57402F00205A5907FB41C +:1004E000E04401F00205A5907FE8E024FE601D24B1 +:1004F0000260030205A5907FEAE0B40105C2000294 +:1005000005A5907FB4E04401F00205A5907FEAE0E4 +:100510007034907FECE0FF5407FEF54EEF30E703B8 +:10052000434E10907FD7E54EF0E54E4420F0EFF4B7 +:100530005480FDC4540F2E25E024B4F582E4347FAA +:10054000F583E4F0805F907FB4E04401F080569042 +:100550007FE8E024FE60182402704A907FEAE0B44D +:100560000104D200803F907FB4E04401F0803690D7 +:100570007FEAE07020907FECE0F45480FFC4540FD9 +:10058000FFE054072F25E024B4F582E4347FF5839F +:100590007401F08010907FB4E04401F08007907FF8 +:0C05A000B4E04401F0907FB4E04402F0AD +:0105AC00222C +:1005AD00754AFF7549FF75480F754700D203C2069E +:1005BD00C202C200C205C2019003007419F0E4909A +:1005CD0001BCF0C2049001C0F0A3F0C2AFC2A812EA +:1005DD000C22E49002AFF09001BDF0900100F0A369 +:1005ED00F0A3F0A3F0A3F0A37410F0A37401F0A393 +:1005FD007408F07E017F001219C1754C12754D0AF9 +:10060D0090010BE0FF054DE54DAC4C7002054C140F +:10061D00F5828C83EFF090010CE04480FF054DE5F1 +:10062D004DAC4C7002054C14F5828C83EFF09001AB +:10063D000DE0FF054DE54DAC4C7002054C14F582F7 +:10064D008C83EFF090010EE0FF054DE54DAC4C7045 +:10065D0002054C14F5828C83EFF090120AE493FF9F +:10066D0074019390011CCFF0A3EFF090011CE0FFFB +:10067D00A3E0FEEF6EFF90011CF0A3E06FFFF09082 +:10068D00011CE06FF0E0FEA3E0FFE4FCFD755210ED +:10069D007553027554127555AC129426754C12751E +:1006AD004DB290010DE0FF054DE54DAC4C700205CE +:1006BD004C14F5828C83EFF090010EE0FF054DE5B3 +:1006CD004DAC4C7002054C14F5828C83EFF0907F8D +:1006DD0092E0FFC4540F2441FF054DE54DAC4C7025 +:1006ED0002054C14F5828C83EFF0054DE54DAE4CB3 +:1006FD007002054C14F5828E83E4F07582107583BB +:10070D0001E0FCA3E0FDA3E0FEA3E0FF90011812C1 +:10071D00A3EE7E017F181286BE900118E0FCA3E0C7 +:10072D00FDA3E0FEA3E0FF75520A75530675541242 +:10073D007555B8129426D2E843D820907FAB74FF3C +:10074D00F05391EF907FAFE04401F0907FAEE04425 +:10075D001FF0D2AF20012E20012BA2039207120908 +:10076D00C575465075456D7544337543002001E4DC +:10077D007FFF7EFF7DFF7CFF784312A3D7EC4D4EAC +:10078D004F60D180E8300105120370C20130060AB6 +:10079D001209FB5003120AE8C20612965E9001BDC3 +:1007AD00E0600C129201E49001BDF0907FD3F090C7 +:1007BD0002AFE0B40F031299B912A095E4FF7401D2 +:1007CD00A807088002C333D8FCFE9001BCE05E6030 +:1007DD001474282FF8E6D3940A40047E0180027E1B +:1007ED00008E4B8003754B0174682FF582E4342025 +:1007FD00F583E54BF00FBF04C5E52CD3940A4004F7 +:0E080D007F0180027F0090206CEFF0020792C6 +:01081B0022BA +:04081C0053D8EF328C +:10082000E533C39401400E907F93E04430F0907F15 +:1008300095E044C0F07FF47E011209AE907F96E00F +:1008400054FEF07F0A7E001209AE907F96E04408C5 +:10085000F07F057E001209AE907F96E054FBF07F9A +:10086000057E001209AEE533C39401500E7F027D70 +:10087000FF1282EA7F057E001209AE907F96E04467 +:1008800002F0E0547FF07F057E001209AE907F9663 +:10089000E04440F07F057E001209AE907F96E05460 +:1008A000BFF07F327E001209AE907F96E04440F0A8 +:0808B0007F327E001209AE2226 +:1008B800907F96E054FDF0E04480F07F0A7E0012BD +:1008C80009AEE533C39401500E7F02E4FD1282EABB +:1008D8007F057E001209AE907F96E054BFF07F0539 +:1008E8007E001209AE907F96E04404F07F057E00FA +:1008F8001209AE907F96E054F7F07F057E0012094A +:10090800AE907F96E04401F07F057E001209AEE5C7 +:1009180033C39401400E907F93E054CFF0907F95BD +:08092800E0543FF0120B002225 +:10093000900AF4E4937076907F937430F0907F94F3 +:10094000743CF0907F9574C6F07F0A7E001209AE69 +:10095000E4907F9CF0907F967408F0907F9C74CF19 +:10096000F07F0A7E001209AE902070E0FFC4540FA1 +:10097000F533C394015007907F96E04480F0E490F3 +:100980007F97F0907F9D7402F0E533C39401400B94 +:10099000E4907F98F0907F9E74C0F0907FE2741294 +:0E09A000F01208207582F475830A74FFF022AD +:1009AE008E5D8F5EE55E155EAE5D7002155D4E600E +:0709BE00051209EA80EE2298 +:1009C500907FD6E054FBF0E04408F0300704E044A3 +:1009D50002F07FD07E071209AE907FD6E054F7F083 +:0509E500E04404F022D3 +:1009EA007400F58690FDA57C05A3E582458370F920 +:0109FA0022DA +:0509FB001208B8D32230 +:100A0000020C4E00020C8100020C6600020CC000B9 +:100A1000020CAA00020AED00020AEE00020AEF0030 +:100A2000020CDB00020DCB00020D1700020E2B00A2 +:100A3000020D5300020E8B00020D8F00020EEB0020 +:100A4000020AF000020AF200020AF100020AF300B0 +:080A5000020F4B00020F6100D0 +:020A58008F4FBE +:100A5A00E4F5507551FF75521275536AAB51AA529B +:100A6A00A95390000112A254B4031DAF500550EFD0 +:100A7A00B54F012212A23B7E0029FFEE3AA9077563 +:0E0A8A0051FFF552895380D47B007A00790029 +:010A9800223B +:100A9900E4FE7551FF755212755312AB51AA52A952 +:100AA9005390000112A2546402702DAD060EEDB5EB +:100AB90007012290000212A2AD85F04FF550624F56 +:100AC900E54F6250E550624F29FDE54F3AA905759A +:0E0AD90051FFF552895380C37B007A007900EB +:010AE70022EC +:050AE800120820D322DA +:010AED0032D6 +:010AEE0032D5 +:010AEF0032D4 +:010AF00032D3 +:010AF10032D2 +:010AF20032D1 +:010AF30032D0 +:030AF400000407F4 +:090B0000907FD6E04480F080747F +:100B7D00438701000000000000000000000000227B +:100B8D00538EF7E58954F14401F589758CB1D2A9DD +:100B9D0075984075CBFF75CAF375C834E4FF7F05B2 +:070BAD007828E4F608DFFCE4 +:010BB400221E +:100BB500C0E0C083C082C0D075D000C000C006C0F0 +:010BC5000728 +:100BC600300416758CF8758A307F2FAE071FEE60DD +:100BD6003C9020007455F080F2758CB17F28EFD3DD +:100BE600942C5009A807E66001160F80F1900300C7 +:100BF600E0600214F09001C0E07002A3E0600E9085 +:0D0C060001C1E024FFF09001C0E034FFF0D8 +:0F0C1300D007D006D000D0D0D082D083D0E0322E +:100C2200D200758E10120930E533C394014008904A +:100C32007F927402F08005E4907F92F0128000129D +:0C0C42000F7D1294F7121B0C120B8D2278 +:100C4E00C0E0C083C082D2015391EF907FAB74019C +:080C5E00F0D082D083D0E03217 +:100C6600C0E0C083C082907FC4E4F05391EF907FD0 +:0B0C7600AB7404F0D082D083D0E032D9 +:100C8100C0E0C083C0825391EF907FAB7402F090BB +:100C91007FD8E0700D907FD9E07007E52C70037567 +:090CA1002C14D082D083D0E03283 +:100CAA00C0E0C083C0825391EF907FAB7410F0D044 +:060CBA0082D083D0E0327D +:100CC000C0E0C083C082300202D2065391EF907F11 +:0B0CD000AB7408F0D082D083D0E0327B +:100CDB00C0E0C083C082C0D075D0105391EF907F1D +:100CEB00A97402F0E53430E013E53230E0079020D0 +:100CFB0004E04401F0902001E04401F0E52C700386 +:0C0D0B00752C14D0D0D082D083D0E03200 +:100D1700C0E0C083C082C0D075D0105391EF907FE0 +:100D2700A97404F0E53430E113E53230E10790208F +:100D37000CE04401F0902009E04401F0E52C700339 +:0C0D4700752C14D0D0D082D083D0E032C4 +:100D5300C0E0C083C082C0D075D0105391EF907FA4 +:100D6300A97408F0E53430E213E53230E20790204D +:100D730014E04401F0902011E04401F0E52C7003ED +:0C0D8300752C14D0D0D082D083D0E03288 +:100D8F00C0E0C083C082C0D075D0105391EF907F68 +:100D9F00A97410F0E53430E313E53230E307902007 +:100DAF001CE04401F0902019E04401F0E52C7003A1 +:0C0DBF00752C14D0D0D082D083D0E0324C +:100DCB00C0E0C083C082C085C084C086758600C069 +:100DDB00D075D0105391EF907FAA7402F0E53420B8 +:100DEB00E006907FC7F08022E53130E00A907FC7A4 +:100DFB00E09002F8F08013E52230E007902004E049 +:100E0B004402F0902001E04402F0E52C7003752CB5 +:100E1B0014D0D0D086D084D085D082D083D0E0328D +:100E2B00C0E0C083C082C085C084C086758600C008 +:100E3B00D075D0105391EF907FAA7404F0E5342055 +:100E4B00E106907FC9F08022E53130E10A907FC93D +:100E5B00E09002F9F08013E52230E10790200CE0DE +:100E6B004402F0902009E04402F0E52C7003752C4D +:100E7B0014D0D0D086D084D085D082D083D0E0322D +:100E8B00C0E0C083C082C085C084C086758600C0A8 +:100E9B00D075D0105391EF907FAA7408F0E53420F1 +:100EAB00E206907FCBF08022E53130E20A907FCBD7 +:100EBB00E09002FAF08013E52230E207902014E074 +:100ECB004402F0902011E04402F0E52C7003752CE5 +:100EDB0014D0D0D086D084D085D082D083D0E032CD +:100EEB00C0E0C083C082C085C084C086758600C048 +:100EFB00D075D0105391EF907FAA7410F0E5342089 +:100F0B00E306907FCDF08022E53130E30A907FCD70 +:100F1B00E09002FBF08013E52230E30790201CE009 +:100F2B004402F0902019E04402F0E52C7003752C7C +:100F3B0014D0D0D086D084D085D082D083D0E0326C +:100F4B00C0E0C083C0825391EF907FA97480F0D032 +:060F5B0082D083D0E032D9 +:100F6100C0E0C083C0825391EF907FAA7480F0905B +:0C0F710001BD74FFF0D082D083D0E032CC +:100F7D0090012012A3FA000025809001247408F03E +:100F8D00A37401F0A3746EF0A3F0A37413F0A37413 +:100F9D0011F0E4A3F0A3F090011EF090011EE0FF0C +:100FAD0004A3F0EF75F00DA42401F9740335F0A836 +:100FBD0001FC7D017B017A01791F7E007F0D12A25C +:100FCD00127E017F1F1287A690011EE004F0E0C380 +:100FDD00940440C7E4F52790011EF090011EE0FF38 +:100FED00C39404501A74F82FF582E43402F583E4A7 +:100FFD00F074232FF8E4F690011EE004F080DCE499 +:10100D00F534E5C0602F90011E7401F090011EE0D3 +:10101D00FFD39404501FEF14FF7401A8070880023A +:10102D00C333D8FC42347E017F1E12844190011ED1 +:10103D00E004F080D7E4F53EF522F531F53290016C +:10104D001EF090011EE0FF75F008A42406F582E461 +:10105D003420F583E054F0FE74C52FF582E434019D +:10106D00F583EEF0743A2FF8A60674362FF8E4F6F1 +:10107D00742D2FF8E4F674FC2FF582E43402F58319 +:10108D00E4F090011EE004F0E0B404B6902060E0BE +:04109D00540FF54EA9 +:1010A1007003021126E490011EF090011EE0FFC3BF +:1010B100940450E47401A807088002C333D8FC5596 +:1010C1004E605A90011EE0FE75F008A42402F582DC +:1010D100E43420F583E0FFEE75F008A42405F582E1 +:1010E100E43420F583E0EE75F008A42406F582E4EB +:1010F1003420F583E0FFAF06EE75F00DA42402F570 +:1011010082E43403F583E0FCA3E0FDA3E0FEA3E069 +:10111100F5668E658D648C637D061283DF90011EFA +:06112100E004F0808522CD +:02112700AC0713 +:10112900907FA5E04480F0EC25E04441907FA6F053 +:101139007B3CAF031BEF7016907FA5E04440F09015 +:101149007FA6E0FD7D32AF051DEF60D480F8907F6A +:10115900A5E0FD30E0DC20E109E04440F07EFF7FBE +:10116900F922ED30E20C907FA5E04440F07EFF7F4C +:10117900FA22907FA5E04420F0907FA6E0FD7B1E37 +:10118900AF031BEF7016907FA5E04440F0907FA657 +:10119900E0FD7D32AF051DEF608680F8907FA5E008 +:1011A900FD20E0DC7B3CAF031BEF7019907FA5E0CD +:1011B9004440F0907FA6E0FD7D32AF051DEF70033E +:1011C90002112980F5907FA5E0FD30E0D930E209D0 +:1011D900E04440F07EFF7FFA22C2AF907FA5E04451 +:0C11E90040F0907FA6E0FDD2AFFF7E003A +:0111F50022D7 +:1012000012010001FFFFFF401007018042000102B0 +:10121000030109025800010104803C090400000A8E +:10122000FFFFFF050705810240000007050102409E +:10123000000007058202400000070502024000008E +:101240000705830240000007050302400000070570 +:1012500084024000000705040240000007058702E1 +:1012600040000007050702400000040309042403AE +:1012700043006F006E006E00650063007400200084 +:101280005400650063006800200049006E006300A0 +:101290002E001803570068006900740065004800BC +:1012A0004500410054002D0034001A035800580036 +:1012B0002D00580058002D005800580058005800C4 +:1012C000580058002A0343006F006E006600690052 +:1012D0006700750072006100740069006F006E00A5 +:1012E000200053007400720069006E006700220342 +:1012F00049006E00740065007200660061006300C2 +:101300006500200053007400720069006E006700E1 +:021310000000DB +:10131200C0E0C0F0C083C082C085C084C086C0D097 +:1013220075860075D018902060E0540FF5F07011AA +:10133200D0D0D086D084D085D082D083D0F0D0E0F7 +:101342003275860010F00B10F11210F21910F32012 +:1013520080D4E528700375281402137CE5297003F4 +:1013620075291402150DE52A7003752A1402169EBA +:10137200E52B7003752B1402182F902002E0543FC6 +:1013820020E23A20E10B20E40B20E514600902136D +:1013920043021465021343438204E0F53A02134305 +:1013A200438204E0432D010213435382F843820532 +:1013B200E042365382FBE054FBF002134330E10279 +:1013C20080E8F585E53230E00A5382F8438204E092 +:1013D20054FEF0E58520E3569020507400F09020F2 +:1013E200587401F0907FE2E04440F0907FE305867C +:1013F200907E800586E585F0A3E584F00586907FE2 +:10140200E5E53FFD030303FEF0F0F0F0F0F0F0F04D +:10141200DEF6907FE2E054BFF09020587400F09026 +:101422007FB7EDF0902001E054FEF00213437F40BD +:10143200907E800586902000E584FE2405FD8D8443 +:10144200E08E8430E009E00586F0A30586DFEF0533 +:1014520086C374409F907FB7F00586A3E054FEF0E8 +:10146200021343532DFAE5236008752300D2E7FEE9 +:10147200800A907FC7E0FE70030214FF9020507430 +:1014820000F09020587401F0907FE2E04440F09028 +:101492007FE30586907E400586E585F0A3E584F02E +:1014A2000586907FE5EE30E7080586E02438F005F2 +:1014B20086EE547FFE5407FBEE547860300303033C +:1014C20030E30474077B08FDFCE0E0E0E0E0E0E0EC +:1014D200E0DDF6EBFE6019EC640770118B23907F60 +:1014E200E2E054BFF09020587400F0801BE0DEFD73 +:1014F200907FE2E054BFF09020587400F0902001F9 +:10150200E054FDF0907FC7F002134390200AE054AC +:101512003F20E23A20E10B20E40B20E514600902AF +:1015220013430215F6021343438204E0F53B021310 +:1015320043438204E0432E010213435382F8438261 +:1015420005E042375382FBE054FBF002134330E1E3 +:101552000280E8F585E53230E10A5382F8438204DD +:10156200E054FEF0E58520E3569020507401F0909F +:1015720020587401F0907FE2E04440F0907FE30550 +:1015820086907E000586E585F0A3E584F0058690C9 +:101592007FE5E540FD030303FEF0F0F0F0F0F0F02C +:1015A200F0DEF6907FE2E054BFF09020587400F035 +:1015B200907FB9EDF0902009E054FEF00213437FD2 +:1015C20040907E000586902008E584FE2405FD8D6E +:1015D20084E08E8430E009E00586F0A30586DFEF23 +:1015E2000586C374409F907FB9F00586A3E054FE40 +:1015F200F0021343532EFAE5246008752400D2E763 +:10160200FE800A907FC9E0FE70030216909020507F +:101612007401F09020587401F0907FE2E04440F0B1 +:10162200907FE30586907DC00586E585F0A3E5847D +:10163200F00586907FE5EE30E7080586E02438F075 +:101642000586EE547FFE5407FBEE547860300303A8 +:101652000330E30474077B08FDFCE0E0E0E0E0E037 +:10166200E0E0DDF6EBFE6019EC640770118B24906C +:101672007FE2E054BFF09020587400F0801BE0DE5F +:0E168200FD907FE2E054BFF09020587400F01D +:10169000902009E054FDF0907FC9F00213439020A0 +:1016A00012E0543F20E23A20E10B20E40B20E51445 +:1016B0006009021343021787021343438204E0F5D3 +:1016C0003C021343438204E0432F0102134353823D +:1016D000F8438205E042385382FBE054FBF00213EA +:1016E0004330E10280E8F585E53230E20A5382F8C2 +:1016F000438204E054FEF0E58520E35690205074C8 +:1017000002F09020587401F0907FE2E04440F090A5 +:101710007FE30586907D800586E585F0A3E584F06E +:101720000586907FE5E541FD030303FEF0F0F0F050 +:10173000F0F0F0F0DEF6907FE2E054BFF090205839 +:101740007400F0907FBBEDF0902011E054FEF002A9 +:1017500013437F40907D800586902010E584FE2411 +:1017600005FD8D84E08E8430E009E00586F0A30558 +:1017700086DFEF0586C374409F907FBBF00586A38C +:10178000E054FEF0021343532FFAE5256008752557 +:1017900000D2E7FE800A907FCBE0FE7003021821A2 +:1017A0009020507402F09020587401F0907FE2E095 +:1017B0004440F0907FE30586907D400586E585F006 +:1017C000A3E584F00586907FE5EE30E7080586E026 +:1017D0002438F00586EE547FFE5407FBEE54786003 +:1017E0003003030330E30474077B08FDFCE0E0E012 +:1017F000E0E0E0E0E0DDF6EBFE6019EC640770117C +:101800008B25907FE2E054BFF09020587400F08068 +:101810001BE0DEFD907FE2E054BFF09020587400A2 +:10182000F0902011E054FDF0907FCBF00213439034 +:10183000201AE0543F20E23A20E10B20E40B20E59F +:10184000146009021343021918021343438204E08F +:10185000F53D021343438204E04330010213435336 +:1018600082F8438205E042395382FBE054FBF002E8 +:10187000134330E10280E8F585E53230E30A538214 +:10188000F8438204E054FEF0E58520E356902050B2 +:101890007403F09020587401F0907FE2E04440F02F +:1018A000907FE30586907D000586E585F0A3E584BD +:1018B000F00586907FE5E542FD030303FEF0F0F0BE +:1018C000F0F0F0F0F0DEF6907FE2E054BFF0902010 +:1018D000587400F0907FBDEDF0902019E054FEF0B8 +:1018E0000213437F40907D000586902018E584FE1A +:1018F0002405FD8D84E08E8430E009E00586F0A3A8 +:101900000586DFEF0586C374409F907FBDF0058696 +:10191000A3E054FEF00213435330FAE52660087545 +:101920002600D2E7FE800A907FCDE0FE7003021908 +:10193000B29020507403F09020587401F0907FE230 +:10194000E04440F0907FE30586907CC00586E58505 +:10195000F0A3E584F00586907FE5EE30E708058684 +:10196000E02438F00586EE547FFE5407FBEE5478F1 +:10197000603003030330E30474077B08FDFCE0E000 +:10198000E0E0E0E0E0E0DDF6EBFE6019EC6407701B +:10199000118B26907FE2E054BFF09020587400F045 +:1019A000801BE0DEFD907FE2E054BFF09020587491 +:1019B00000F0902019E054FDF0907FCDF002134329 +:0119C00032F4 +:0419C100AD07AC06BC +:1019C5007906ED2404F582E43CF583E0FAA3E0FB17 +:1019D5004A7003021B09E9B407004003021ADB90B1 +:1019E50019EBF8282873021AB9021A71021A5A0259 +:1019F5001A40021A2F021A1A021A00907FA5E04413 +:101A050080F08D828C83A3E0FF25E044A0907FA623 +:101A1500F019021ADB198D828C83E0C39420400AE9 +:101A2500A3A3E0907FA6F0021ADB8D828C83A3A38B +:101A3500E0A3E0907FA6F019021ADB907FA5E044B1 +:101A450080F08D828C83A3E0FF25E044A1907FA6E2 +:101A5500F019021ADBEB64014A7008907FA5E04497 +:101A650020F019907FA6E0F55919806AED2404F558 +:101A750082E43CF583E0FEA3E064024E7008907FAB +:101A8500A5E04420F019907FA6E0FFED2406F5823D +:101A9500E43CF583E475F00112A29785F082F583A5 +:101AA500EFF0ED2404F582E43CF58374FFF5F012C4 +:101AB500A2818022907FA5E04440F0907FA6E0FFC0 +:101AC500ED2406F582E43CF583E0FAA3E0F5828A8D +:101AD50083EFF07F0822907FA5E0F55930E0F730DD +:101AE500E207E04440F07F0622E9D3940250030266 +:101AF50019C7E55930E1030219C7907FA5E04440B5 +:061B0500F07F07227F08BB +:011B0B0022B7 +:101B0C00E533C39401501C7F057E001209AE7F02A1 +:101B1C007DFF1282EA7F057E001209AE7F037DFFF6 +:041B2C001282EA2215 +:108000007BFF7A12791B90000412A254FD8B5075ED +:108010005112755224E4907FE1F0907FE0F0F54E2C +:10802000F54F9002AEF0907FDFF0907FDEF0907F12 +:10803000A974FFF0907FAAF0E4FCEC25E024B4F5ED +:1080400082E4347FF583E4F00CBC10EEE4907FDD35 +:10805000F0AF051DEF70030281C6AB50AA51A952C3 +:1080600090000112A254640560030281B5900003E0 +:1080700012A2546401600302813C90000212A254D7 +:10808000FF547FFCD394075003028116ECC3941075 +:108090004003028116EF30E742E54FAE4E7802CE44 +:1080A000C313CE13D8F9FF74F02CF582E4347FF5B6 +:1080B00083EFF0907FE0E0FFEC24F8FE7401A80667 +:1080C000088002C333D8FC4F907FE0F09002AEE00E +:1080D00004F0907FDDE04480F0803EE54FAE4E78C6 +:1080E00002CEC313CE13D8F9FF74E82CF582E43422 +:1080F0007FF583EFF0907FE1E0FFEC24F8FE740160 +:10810000A806088002C333D8FC4F907FE1F09002AC +:10811000AEE004F080037FFF2290000412A25425F9 +:108120004FF54FE4354EF54E90000512A254FEE493 +:10813000254FF54FEE354EF54E0281B8AB50AA51A2 +:10814000A95290000312A254FF64026005EF640379 +:10815000706090000212A254FF547FFCD394075029 +:108160004EEF30E71E907FDEE0FF7401A804088028 +:1081700002C333D8FCFE4F907FDEF0907FACE04E20 +:10818000F08035907FDFE0FF7401A804088002C30F +:1081900033D8FCFE4F907FDFF0907FADE04EF0ECE7 +:1081A00025E024C5F582E4347FF583ECF080097F77 +:1081B000FF227FFF227FFF2274072552F552E4350C +:1081C00051F55102805120030D9002AEE0600790FE +:0881D0007FAEE04402F07F00E5 +:0181D8002284 +:0481D9008E598F5AD2 +:1081DD00755B03E55A2404F582E43559F583E0FE19 +:1081ED00A3E04E70030282E7E55B604E1460381425 +:1081FD00602014600302828B907FA5E04480F0859F +:10820D005A82855983A3E0FF25E044A0907FA6F014 +:10821D00806C855A82855983E0C394204009A3A3BD +:10822D00E0907FA6F08057155B855A82855983A310 +:10823D00A3E0A3E0907FA6F08044E55A2406F582E2 +:10824D00E43559F583E475F00112A29785F082F5B6 +:10825D0083E0907FA6F0907FA5E04440F0E55A249E +:10826D0004F582E43559F58374FFF5F012A281858A +:10827D005A82855983A3A3E475F00112A281907FE0 +:10828D00A5E0F55C30E0F730E207E04440F07F0612 +:10829D0022E55C20E10A907FA5E04440F07F0722B3 +:1082AD00E55B70317F017E001209AE907FA5E04441 +:1082BD0080F0855A82855983A3E0FF25E044A09084 +:1082CD007FA6F0907FA5E0F55C30E0F730E1D57545 +:0C82DD005B030281E0155B0281E07F087A +:0182E9002272 +:0282EA00AE07DD +:1082EC007C02EC14601514701E907FA5E04480F0A5 +:1082FC00EE25E04440907FA6F0800C907FA6EDF038 +:10830C00907FA5E04440F0907FA5E0FB30E0F8BC06 +:10831C00020A20E107E04440F07F0722EB30E20A3A +:0E832C00907FA5E04440F07F0622DCB67F087B +:01833A002220 +:10833B00C0E0C083C082C2A99003007419F0D2A917 +:0F834B0053917F9001C4E4F0D082D083D0E03210 +:10835A00EF75F008A42400F582E43420AB82FAF524 +:10836A0083A3E4F08B828A83A3A3A3E0F56174BF9D +:10837A00F08B828A83A3A3E04410F08B828A83A3C2 +:10838A00A3A3E4F08B828A83A3F0F9ED601D740144 +:10839A007E00A807088005C333CE33CED8F9FFE4A0 +:1083AA00EF5531600479098002790D8B828A83A3A3 +:1083BA00A3A374BFF08B828A83A3A3E054EFF08B4C +:1083CA00828A83A3A3A3E561F0AE02AF038F828EF4 +:0483DA0083A3E9F0A0 +:0183DE00227C +:0483DF008F618D62BB +:1083E300E4F567743F2FF876087F807E257D007C57 +:1083F30000AB66AA65A964A863D312A3B340267F22 +:10840300007E967D007C00A863D312A3B3500C7545 +:108413006740743F2561F87610800A756780743F62 +:108423002561F87638E56745624401FFE56175F03B +:0D84330008A42402F582E43420F583EFF064 +:018440002219 +:108441008F828E83E014F557C3940440037FFF228B +:10845100E55775F008A42400F582E43420AF82F5D5 +:10846100588F59E55725E024C6F582E4347FF5831A +:10847100E020E10FE55725E024C7F582E4347FF5DC +:1084810083E4F074232557F8E4F6E5592404F582D2 +:10849100E43558F583E04403F0E55775F00DA42465 +:1084A10002F582E43403F583E0FCA3E0FDA3E0FEE2 +:1084B100A3E0F5668E658D648C637D06AF571283EC +:1084C100DFAF577D0112835A855982855883A3A353 +:1084D100E020E043E0FFE5592405F582E43558F555 +:1084E10083E0E5592406F582E43558F583E0FFE59C +:1084F1005775F00DA42402F582E43403F583E0FC02 +:10850100A3E0FDA3E0FEA3E0F5668E658D648C63B8 +:108511007D06AF571283DF74F82557F582E43402E4 +:10852100F583E4F0E55725E0FFC3740C9F75F04037 +:10853100A42440F582E5F0347BAF82FEE55725E0C7 +:1085410024EFF582E43402F583EEF0A3EFF0AF57A8 +:0F8551007401A807088002C333D8FC42347F00AE +:0185600022F8 +:108561008F828E83E014F557C3940440037FFF226A +:10857100AF57E4FD12835A74F82557F582E43402AB +:10858100F583E4F0E55775F008A42400F582E4349E +:1085910020AF82F5598F5AF583E5822404F582E4F0 +:1085A1003583F583E054FCF0E55775F00DA4240CF8 +:1085B100F582E43403F583E4F0E55775F00DA42466 +:1085C10002F582E43403F583E0FCA3E0FDA3E0FEC1 +:1085D100A3E0F5668E658D648C637D06AF571283CB +:1085E100DFE55A2405F582E43559F583E030E009E9 +:1085F100855A82855983E0F558AF577401A8070859 +:108601008002C333D8FCF45234E55725E024C6F583 +:1086110082E4347FF583E020E10FE55725E024C7AC +:0B862100F582E4347FF583E4F07F0075 +:01862C00222B +:04862D008E578F587D +:108631008F828E83E014F559C3940440037FFF2297 +:10864100E55975F008A42401F582E43420F583E0AE +:1086510054037066855882855783A3E030E028E58E +:108661005975F00DA42402F582E43403F583E0FC8E +:10867100A3E0FDA3E0FEA3E0F5668E658D648C6347 +:108681007D02AF591283DF855882855783A3E0307D +:10869100E128E55975F00DA42402F582E43403F5CF +:1086A10083E0FCA3E0FDA3E0FEA3E0F5668E658D0B +:0C86B100648C637D04AF591283DF7F00EE +:0186BD00229A +:1086BE008F828E83C083C082E0FDA3A3A3E0FCED76 +:1086CE006CD082D083F08F828E83A3A3A3C083C08D +:1086DE0082E0FD8F828E83E0FCED6CD082D083F041 +:1086EE008F828E83C083C082A3A3A3E0FDEC6DD0E6 +:1086FE0082D083F08F828E83A3C083C082E0FD8FF1 +:10870E00828E83A3A3E0FCED6CD082D083F08F82A7 +:10871E008E83A3A3C083C082E0FD8F828E83A3E0ED +:10872E00FCED6CD082D083F08F828E83A3C083C089 +:10873E0082E0FD8F828E83A3A3E0FFED6FD082D007 +:03874E0083F02293 +:04875100AD07AC06BE +:10875500790D8D828C83E014FEC3940440037FFF62 +:10876500228C578D58EE75F00DA42401F582E43462 +:1087750003AF82FEAD0119ED60240FEFAC06700169 +:108785000E14F5828C83E0FD0558E558AA57700252 +:10879500055714F5828A83E06D60D97F01227F0039 +:0187A50022B1 +:0487A6008E578F5803 +:1087AA008F828E83E014F55EC3940440037FFF2218 +:1087BA00E55E75F008A42400F582E43420AF82F562 +:1087CA005F8F60855882855783A3E0FCA3E0FDA3F1 +:1087DA00E0FEA3E0FF7B087A0079007800D312A3B9 +:1087EA00B34010855882855783A312A3FA0000006C +:1087FA0008802E855882855783A3E0FCA3E0FDA359 +:10880A00E0FEA3E0FF7B007A0879077800C312A391 +:10881A00B3500E855882855783A312A3FA0007081E +:10882A0000855882855783A3E0F8A3E0F9A3E0FA0C +:10883A00A3E0FB7F007E507D467C0012A3218F5C63 +:10884A008E5B8D5A8C597B0A7A007900780012A3C4 +:10885A0021AF038F5DAF5CAE5BAD5AAC597B0A7A30 +:10886A00007900780012A3218F5C8E5B8D5A8C5997 +:10887A00E55DC394054015E55C2401F55CE4355BD0 +:10888A00F55BE4355AF55AE43559F5598560828520 +:10889A005F83A3E4F0856082855F83A3A3A3E0449A +:1088AA0080F0856082855F83E55CF0AF5CAE5BAD8E +:1088BA005AAC59780812A3C4856082855F83A3EFF6 +:1088CA00F0856082855F83A3A3A3E0547FF0E4F57B +:1088DA005DE558240BF582E43557F583E0FF30E077 +:1088EA00235401F0E5602404F582E4355FF583E062 +:1088FA0054FDF0AF5E7401A807088002C333D8FCA8 +:10890A004222803674017E00A85E088005C333CEF9 +:10891A0033CED8F9FFE4EF5522601FE5602404F551 +:10892A0082E4355FF583E04402F0AF5E7401A80784 +:10893A00088002C333D8FCF45222E5582408F58291 +:10894A00E43557F583E0FFB46205435D0A801AEF08 +:10895A00B47205435D088011EFB47405435D02806B +:10896A0008EF646E60037FFF22E558240BF582E46A +:10897A003557F583E0FF30E303435D80EF30E712BC +:10898A00435D40E5602404F582E4355FF583E04405 +:10899A0002F0E558240BF582E43557F583E030E11F +:1089AA0020AF5E7401A807088002C333D8FC4232A4 +:1089BA00E5602404F582E4355FF583E04401F08044 +:1089CA0010AF5E7401A807088002C333D8FCF452C2 +:1089DA0032E558240BF582E43557F583E0FF30E49D +:1089EA0011AE5E7401A806088002C333D8FC423176 +:1089FA008010AE5E7401A806088002C333D8FCF466 +:108A0A005231EF20E10330E403E4F55D85608285AD +:108A1A005F83A3A3A374BFF0856082855F83A3A34A +:108A2A00E4F0E55DF0E558240AF582E43557F5836C +:108A3A00E0FFE5602404F582E4355FF583EFF0E5B5 +:108A4A0058240AF582E43557F583E0FFE5602405EA +:108A5A00F582E4355FF583EFF0E5582409F582E401 +:108A6A003557F583E0FFE5602406F582E4355FF5C6 +:108A7A0083EFF0E5582409F582E43557F583E0FFE2 +:108A8A00E5602407F582E4355FF583EFF0856082BF +:108A9A00855F83A3A3A3E4F0856082855F83A3A394 +:108AAA00F0855882855783A3E0FCA3E0FDA3E0FE8E +:108ABA00A3E0F5668E658D648C637D06AF5E1283D6 +:108ACA00DF755D08E558240CF582E43557F583E037 +:108ADA006003435D10E5602404F582E4355FF583A5 +:108AEA00E05403455DF0E5582405F582E43557F571 +:108AFA0083E0FEC394054006EED3940840037FFF4B +:108B0A0022E5582406F582E43557F583E0FDC3943F +:108B1A00014006EDD3940240037FFF22ED14FF25A6 +:108B2A00E025E0FFEE24FB4FF55DE5582407F582CA +:108B3A00E43557F583E024D0601814601A24C36022 +:108B4A001E146009240A7014435D188012435D08DC +:108B5A00800D435D388008435D2880037FFF2285AE +:108B6A006082855F83A3A3A3E55DF074017E00A8FC +:108B7A005E088005C333CE33CED8F9FFE4EF55340F +:108B8A006007AF5E7D0112835AAA57A9587B01C0BC +:108B9A0003C001E55E75F00DA42401F9740335F0F4 +:108BAA00A801FCAD03D001D0037E007F0D12A212F2 +:028BBA007F003A +:018BBC002296 +:108BBD008F828E83E014FEC3940440037FFF22EE68 +:108BCD0075F008A42400F582E43420AD82FC9001F8 +:108BDD002C7408F0EE04A3F0E4A3F08D828C83E5F1 +:108BED00822406F582E43583F583E090012FF08D24 +:108BFD00828C83E5822405F582E43583F583E05488 +:108C0D001E900130F0742D2EF8E6A3F0AF0674011E +:108C1D00A807088002C333D8FCF557E533C3940188 +:108C2D00400D902078E0540F755800F55980097F5C +:108C3D00021211278E588F59C3E5586480948040D5 +:108C4D00DAE5575559900132F07E017F2C7D0712E0 +:048C5D00916A7F0099 +:018C610022F0 +:108C62008F828E83E014FEC3940440037FFF22EEC2 +:108C720075F008A42400F582E43420AF82FE90014E +:108C820033740AF08F828E83E5822404F582E43500 +:108C920083F583E0900134F07E017F337D021291EF +:038CA2006A7F00E6 +:018CA50022AC +:048CA6008E578F58FE +:108CAA008F828E83E014FEC3940440037FFF22EE7A +:108CBA0075F008A42400F582E43420AD82FC8558BE +:108CCA0082855783A3E0600FED2404F582E43CF526 +:108CDA0083E04402F08043EE75F00DA4240CF58283 +:108CEA00E43403F583E030E020EE25E024C6F58283 +:108CFA00E4347FF583E030E1F07F60ED2405F5820E +:108D0A00E43CF583E05FB507F2AE04AF05EF240457 +:0C8D1A00F582E43EF583E054FDF07F009C +:018D2600222A +:048D2700AD07AC06E2 +:108D2B008D828C83E014FEC3940440037FFF22EEFC +:108D3B0075F008A42400F582E43420AF82FE8D8206 +:108D4B008C83A3E0600FEF2404F582E43EF583E00F +:108D5B004401F0800DEF2404F582E43EF583E054EA +:048D6B00FEF07F0097 +:018D6F0022E1 +:048D7000AD07AC0699 +:108D74008D828C83E014FEC3940440037FFF22EEB3 +:108D840075F008A42400F582E43420AF82FE8D82BD +:108D94008C83A3E0600D8F828E83A3A3A3E0444061 +:108DA400F0800B8F828E83A3A3A3E054BFF07F00D7 +:018DB400229C +:108DB5008F828E83E014FEC3940440037FFF22AFAD +:108DC500067401A807088002C333D8FC423E7F0021 +:018DD500227B +:048DD6008E578F58CD +:108DDA008F828E83A3E0F55C8F828E83E0F559D370 +:108DEA00940440037FFF22E55924FE601614601F95 +:108DFA001460282403702E7E7E7F80755A7E755BF0 +:108E0A008080227E7E7F00755A7E755B0080167E8A +:108E1A007D7F80755A7D755B80800A7E7D7F0075B7 +:108E2A005A7D755B00E55C701B855B82855A83748D +:108E3A00FFF0E55925E024B5F582E4347FF5837423 +:108E4A0001F08048E5582402FFE43557FEE55C60EE +:108E5A00230FEFAC0670010E14F5828C83E0FD053A +:108E6A005BE55BAA5A7002055A14F5828A83EDF013 +:108E7A00155C80D9855882855783A3E0FFE559257B +:0E8E8A00E024B5F582E4347FF583EFF07F003D +:018E980022B7 +:108E9900EF2405F558E43EF5579001357407F09035 +:108EA900017A7401F0A37436F0855882855783A33B +:108EB900A3A3E0FEA3E08E59F55A8558828557830E +:108EC900E0249E606124F9600E24F17003028F7A18 +:108ED90024146003028FC8855882855783A3E0FE56 +:108EE900A3E0FFC3E49FF55C74019EF55BD3E55CE9 +:108EF900943FE55B94004006755B00755C3FD3E5E4 +:108F09005A955CE559955B5003028FCBAE5BAF5C1C +:108F1900855882855783A3A3A3EEF0FEA3EFF08EB5 +:108F290059F55A028FCB855882855783A3E0FEA352 +:108F3900E0FFC374309FF55CE49EF55BD3E55C9478 +:108F490010E55B94004006755B00755C10D3E55A2B +:108F5900955CE559955B406AAE5BAF5C8558828547 +:108F69005783A3A3A3EEF0FEA3EFF08E59F55A8021 +:108F790051855882855783A3E0FEA3E0FFC3E49F90 +:108F8900F55CE49EF55B455C600BD3E55C943FE5DD +:108F99005B94004006755B00755C3FD3E55A955CB0 +:108FA900E559955B401CAE5BAF5C8558828557835C +:108FB900A3A3A3EEF0FEA3EFF08E59F55A80037F29 +:108FC9000122855882855783E0249E700302908B85 +:108FD90024F9605824F170030290DB241460030221 +:108FE900911F855882855783A3E0FEA3E0FFD394A0 +:108FF900FFEE9400400302911F900175EFF0E55ACE +:10900900155AAE59700215594E700302911F9001FD +:1090190075E0FF04F0A807E6FF90017AE475F00116 +:1090290012A29785F082F583EFF080D28558828568 +:109039005783A3E0FEA3E0FFC39480EE940050039E +:1090490002911FD3EF94FFEE9400400302911F9009 +:109059000176EFF0E55A155AAE59700215594E705E +:109069000302911F900176E0FF04F0A807E6FF9044 +:10907900017AE475F00112A29785F082F583EFF089 +:1090890080D2855882855783A3E0FEA3E0FFC3946D +:1090990020EE9400500302911FD3EF942FEE940019 +:1090A9005074900177EFF0E55A155AAE59700215D0 +:1090B900594E6062900177E0FF04F0A807E6FF903F +:1090C900017AE475F00112A29785F082F583EFF039 +:1090D90080D5855882855783A3E0FFA3E090017866 +:1090E900CFF0A3EFF0E55A155AAE59700215594E53 +:1090F9006024900178E475F00112A29785F082F559 +:1091090083E0FF90017AE475F00112A29785F0825D +:10911900F583EFF080CF7E017F35855882855783AF +:0D912900A3A3A3E0A3E004FD12916A7F0060 +:019136002216 +:109137008E628F638C648D65AF031BEF60240563BC +:10914700E563AE627002056214F5828E83E0FF0567 +:1091570065E565AC647002056414F5828C83EFF0F5 +:0391670080D6228D +:06916A008D5DAB07AA06B3 +:1091700075614075600D755F03755E00907FC2E09C +:1091800020E1F9AF61AE60AD5FAC5EEC4D4E4F706B +:1091900008907FC27402F080D7907FC2E020E11671 +:1091A000AF03AE027C7B7D80AB5D129137907FC3B5 +:0891B000E55DF07F01227F0064 +:0191B8002294 +:1091B900900184740BF0A3E533F0900AF5E49390E1 +:1091C9000186F0900AF6E493900187F0E490017C1F +:1091D900F0A3F0A3F0A3F0A3F0A37410F0A374011B +:1091E900F0A37488F07E017F7C1219C17E017F840F +:0791F9007D1412916A7F0052 +:01920000224B +:109201007E7B7F40754E7B754F40907FD3E0FF851D +:109211004E51854F52E5522401F556E43551F5552D +:10922100E4F550855282855183E0FE14B40C005060 +:109231005B909239F828287302925D02925D029246 +:109241006702927102927102927102928502925D9D +:1092510002927B02925D02928D02925DEF64026046 +:109261002B7550FF8026EF640E60217550FF801C26 +:10927100EF640360177550FF8012EF6403600D7592 +:1092810050FF8008EF640660037550FFE5506015DC +:109291009001987411F0A3EEF07E017F987D021287 +:1092A100916AAF5022E4F550855282855183E014D2 +:1092B100B40F0040030293CF9092C0F828287302A4 +:1092C10092ED0292F902930502935302935E029387 +:1092D1006902937402937F02938A0293950293A089 +:1092E1000293A70293CF0293B20293BDAF56AE553C +:1092F1001284418F500293D2AF56AE551285618FC1 +:10930100500293D2855553855654E5542401FFE408 +:109311003553FE1286BEAF54AE531287518F50EFB4 +:10932100640160030293D2AF54AE531287A68F50EB +:10933100E55070030293D2855482855383E075F022 +:109341000DA424F4F582E43402AF82FE1287A60252 +:1093510093D2AF56AE55128CA68F508074AF56AED5 +:1093610055128D278F508069AF56AE55128D708F73 +:1093710050805EAF4FAE4E128E998F508053AF56D4 +:10938100AE55128BBD8F508048AF56AE5512862D0B +:109391008F50803DAF56AE55128C628F5080321285 +:1093A10091B98F50802BAF56AE55128DB58F50802D +:1093B10020AF56AE55128DD68F508015AF4FAE4EA1 +:1093C1007C027DAF7B40129137E4F55080037550EC +:1093D100FFE550601D9001987411F085528285510E +:1093E10083E0900199F07E017F987D0212916AAF2E +:1093F1005022855282855183E0FF1424FA500424BF +:10940100FE701F9001987410F0A3EFF085568285CD +:109411005583E090019AF07E017F987D0312916A55 +:049421008F50AF5069 +:019425002224 +:089426008F518E508D4F8C4ECA +:10942E0075580175599CE4F557AF531553EF7003FA +:10943E000294C4AF52E4FCFDFEF8F9FAAB07AF514B +:10944E00AE50AD4FAC4E12A321AF038F56AF51AEFF +:10945E0050AD4FAC4EC004C005C006C007AF52E4BD +:10946E00FCFDFEF8F9FAAB07D007D006D005D00404 +:10947E0012A3218F518E508D4F8C4EE5562430F510 +:10948E0056D39439400674072556F5560559E559B5 +:10949E00AE587002055814F5828E83E4F00559E536 +:1094AE0059AE587002055814F5828E83E556F005B4 +:1094BE00570557029437E559155970021558AF578D +:1094CE001557EF6023E5591559AE5870021558F52A +:1094DE00828E83E0FF0555E555AC54700205541499 +:0894EE00F5828C83EFF080D6BB +:0194F6002253 +:1094F700E49001C9F07E017FCA9001BEEEF0A3EFB0 +:0A950700F09001C2EEF0A3EFF02295 +:10951100AA07A9059001C9E0C394405061AC027447 +:10952100017E00A804088005C333CE33CED8F9FFED +:10953100E4EF55346045EA04FF9001C2E0FCA3E08A +:10954100FDF5828C83EFF0A3E9F08D828C83A3A3D8 +:10955100EBF09001C2E475F00312A281FCD3E5F0B7 +:109561009487EC9402400A9001C27401F0A374CA7A +:10957100F0C2AF9001C9E004F0D2AF7F01227F00B9 +:0195810022C7 +:109582009001C9E0D3940040559001BEE0FCA3E0F5 +:10959200AA04F97B01C003C002C001AA06A907A858 +:1095A20001AC02AD03D001D002D0037E007F0312D2 +:1095B200A2129001BEE475F00312A281FCD3E5F081 +:1095C2009487EC9402400A9001BE7401F0A374CA1D +:1095D200F0C2AF9001C9E014F0D2AF7F01227F0048 +:0195E2002266 +:1095E300907FC2E020E1737E7B7F8075537B75544F +:1095F30080E5542401FFE43553A9077B018B55F51E +:10960300568957FE129582EF6050AB55AA56A9575B +:1096130012A23B14FF90000112A254B40216C2AF6F +:10962300EF75F008A42401F582E43420F583E044C7 +:1096330004F0D2AF74017E00A807088005C333CEBF +:1096430033CED8F9FFE4EF5534600F855482855348 +:0A96530083740DF0907FC37404F0DF +:01965D0022EA +:10965E001295E3E4F54E743A254EF8E654F0F54FC4 +:10966E0074C5254EF582E43401F583E0654FFFC4E1 +:10967E00540FF550602274C5254EF582E43401F581 +:10968E0083E54FF0AF4E7D01E54F4550FB1295112E +:10969E00EF70051295E380EC054EE54EC394044041 +:1096AE00B51295E3E53E6048E4F54EAF4E7401A861 +:1096BE0007088002C333D8FCF54F553E6029E54EAE +:1096CE0075F008A42405F582E43420F583E030E635 +:1096DE0016AF4E7D047B80129511EF70051295E347 +:1096EE0080EFE54FF4523E054EE54EC3940440BB69 +:1096FE00900300E060030297DF7419F0E533C39422 +:10970E0001400D902078E0540F755100F5528009FC +:10971E007F021211278E518F52C3E55164809480BF +:10972E0040DA9001BCE06552F06037E4F54EAF4E82 +:10973E007401A807088002C333D8FCF54F9001BC12 +:10974E00E0554F6014AF4E7D08E54F5552FB129514 +:10975E0011EF70051295E380EC054EE54EC39404AF +:10976E0040CC9001BCE552F0E4F54EC2AF74362504 +:10977E004EF8E6F54FE4F6D2AF534F1EE54F6011AB +:10978E00AF4E7D02AB4F129511EF70051295E3802F +:10979E00EF742D254EF8E6F54F74FC254EF582E458 +:1097AE003402F583E0654F6011AF4E7D04AB4F126E +:1097BE009511EF70051295E380EF74FC254EF5823E +:1097CE00E43402F583E54FF0054EE54EC3940440B4 +:0497DE009A1295E363 +:0197E2002264 +:0C97E300787FE4F6D8FD75816702982AB3 +:1097EF000205ADE493A3F8E493A34003F68001F2DE +:1097FF0008DFF48029E493A3F85407240CC8C3337B +:10980F00C4540F4420C8834004F456800146F6DF49 +:10981F00E4800B010204081020408090986FE47ED2 +:10982F00019360BCA3FF543F30E509541FFEE4933E +:10983F00A360010ECF54C025E060A840B8E493A305 +:10984F00FAE493A3F8E493A3C8C582C8CAC583CA30 +:10985F00F0A3C8C582C8CAC583CADFE9DEE780BEE8 +:10986F006024028A010204081020408081828488CB +:10987F0090A0C0C1C2C4C8D0E0E1E2E4E8F0F1F2C8 +:08988F00F4F8F9FAFCFDFEFFFC +:0198970000D0 +:089898008B598A5A895B8D5C33 +:1098A000E4F55DF55EAF5C155CEF6036AB59055BCA +:1098B000E55BAA5A7002055A14F912A23BFFE55D56 +:1098C000E55E6F25E0FFE433FE74952FF582EE34FC +:1098D0009EF583E55DFFE493F55D7401936FF55E9E +:0698E00080C3AE5DAF5E27 +:0198E600225F +:0B98E700C0E0C083C082C0D075D01864 +:1098F200902060E0540FFE30E005902002E0FFEE81 +:1099020030E10590200AE0FFEE30E205902012E0FF +:10991200FFEE30E30590201AE0FF9001C4E0B51E8F +:0A99220004E4F080059001C4EEF0AB +:09992C00D0D0D082D083D0E0320B +:02993500A90384 +:10993700EF75F008A42400F582E43420AB82FAE541 +:109947005C455DF55EE960148A83E5822404F5824F +:10995700E43583F583E04DF0E4FE8013EB2404F552 +:1099670082E43AF583E0FFEDF4FCEF5CF0AE5EEBEA +:109977002406F582E43AF583E0555EFCB50603AFAD +:109987000522E55C5CFEE55D5CFDE96016EE7004B2 +:109997007F0180027F00AE07ED70047F0180027FA8 +:1099A70000AD07EE6003AF5C22ED6003AF5D227F81 +:0199B70000AF +:0199B800228C +:1099B9007555027556B0900335740FF0855682853A +:1099C9005583A3E0FF900337F0855682855583E0E0 +:1099D900900336F090033874FFF0755703755839C2 +:1099E900EF14B40B004003029E5D9099FAF8282801 +:1099F90073029A1B029ABA029BBF029BDE029BDE8C +:109A0900029C94029CCF029CF4029DB2029DE20248 +:109A19009E0EE4F54EE54E75F008A42400F582E4A7 +:109A29003420AF82F5538F54E4FFE4FEEF601074E5 +:109A39008A2EF582E43402F583E0F4F54F800D7443 +:109A49008A2EF582E43402F583E0F54FE5542407C4 +:109A5900F582E43553F583E54FF0E0F550654F6045 +:109A690038E4900338F0E54E04FD0558E558AA5747 +:109A79007002055714F5828A83EDF00558E558AC54 +:109A8900577002055714F5828C83E54FF08558828B +:109A9900855783E550F0029E630EBE248F0FEF6455 +:109AA900027087054EE54E64046003029A1E029E09 +:109AB90063E4F54EAF4EE4FD12835A054EE54ED3ED +:109AC900940340F09000047498F0A374E7F0E4F56F +:109AD900507E207F00755320755400F54EAF4E74AB +:109AE90001A807088002C333D8FCF54F9001C4F0E0 +:109AF9009001C0E4F0A3740AF0855482855383A3CE +:109B09007402F09001C4E0B54F349001C0E07002D6 +:109B1900A3E070EF900338F0E54E04FF0558E558CF +:109B2900AC577002055714F5828C83EFF085588283 +:109B390085578374FFF0E49001C4F07550FF9001DC +:109B4900C4E0FF6037E4900338F0E54E04FE0558A1 +:109B5900E558AC577002055714F5828C83EEF00571 +:109B690058E558AC577002055714F5828C83EFF00D +:109B7900855882855783E54FF07550FFE55070167B +:109B890074082554F554E43553F553054EE54E64F0 +:109B9900046003029AE6E4F54EAF4E7D0112835A42 +:109BA900054EE54ED3940340F09000047413F0A3DE +:109BB9007412F0029E63855682855583E014FF7402 +:109BC90001A807088002C333D8FC9002F7F090017E +:109BD900C4F0029E639001C07403F0A374E8F0E43A +:109BE900F5509002F7E0FF9001C4E0B50719900124 +:109BF900C0E07002A3E070EA900338F085588285CE +:109C0900578374FFF0F550E5506003029E6390019D +:109C1900C0F0A37496F09001C0E07002A3E070F662 +:109C2900E533C39401400D902078E0540F7551003D +:109C3900F55280097F021211278E518F52C3E551C7 +:109C49006480948040DAE552540FF5509002F7E0B1 +:109C5900555070047F0180027F008F4F85568285A1 +:109C69005583A3E0B4050CE54F70047F0180027FA2 +:109C7900008F4FE54F7003029E63E4900338F0852F +:109C89005882855783E550F0029E63E4FFFD1283F5 +:109C99005A7E207F00755320755400855482855360 +:109CA90083A3A3A3E04480F0855482855383740180 +:109CB900F0A3E4F0855482855383A3A3A3E0547FE2 +:109CC900F0D204029E63C2047E207F007553207582 +:109CD9005400E5542405F582E43553F583E030E674 +:109CE900F1E4FF7D0112835A029E63E4F550F54EBB +:109CF900AF4EE4FD12835AE54E75F008A42400F531 +:109D090082E43420AF82F5538F54F583E58224042D +:109D1900F582E43583F583E054FCF0AF4E7D017B99 +:109D290001755C80755D401299358F50E550701151 +:109D3900AF4E7D027B01755C10755D201299358FE0 +:109D490050E5507010AF4E7D01FB755C80755D402C +:109D59001299358F50E5507010AF4E7D02FB755C3E +:109D690010755D201299358F50AF4E7D0112835ABF +:109D7900E5506026E4900338F0E54E04FF0558E508 +:109D890058AC577002055714F5828C83EFF085584B +:109D990082855783E550F0029E63054EE54ED394C4 +:109DA900035003029CF9029E63E4900359F0A3F067 +:109DB900A3F0A3F0A3F0A37410F0A3749EF0A3740E +:109DC90085F07E037F591281D9EF64087003029EE2 +:109DD90063E4900338F0029E63E4900359F0A3F022 +:109DE900A3F0A3F0A3F0A37410F0A3E557F0A3E543 +:109DF90058F07E037F591219C1EF6408605CE49042 +:109E09000338F08055E5562402FFE43555FAA907D1 +:109E19007B017D10129898EF4E7032900359F0A390 +:109E2900F0A3F0A3F0A3F0A37410F0E55624029078 +:109E39000360F0E4355590035FF07E037F5912818A +:109E4900D9EF64086014E4900338F0800DE49003BE +:109E590038F080069003387401F09001C0E4F0A353 +:109E6900740AF09001C0E07002A3E070F67E037FEF +:0B9E7900357D2412916AE49002AFF0E6 +:019E840022BB +:109E8500FFFEFCF8F0E0C080000103070F1F3F7FD5 +:109E95000000C0C1C1810140C30103C00280C241AD +:109EA500C60106C00780C7410500C5C1C48104407D +:109EB500CC010CC00D80CD410F00CFC1CE810E402D +:109EC5000A00CAC1CB810B40C90109C00880C8413D +:109ED500D80118C01980D9411B00DBC1DA811A40AD +:109EE5001E00DEC1DF811F40DD011DC01C80DC417D +:109EF5001400D4C1D5811540D70117C01680D641AD +:109F0500D20112C01380D3411100D1C1D0811040BC +:109F1500F00130C03180F1413300F3C1F2813240AC +:109F25003600F6C1F7813740F50135C03480F4417C +:109F35003C00FCC1FD813D40FF013FC03E80FE412C +:109F4500FA013AC03B80FB413900F9C1F88138403C +:109F55002800E8C1E9812940EB012BC02A80EA41AC +:109F6500EE012EC02F80EF412D00EDC1EC812C407C +:109F7500E40124C02580E5412700E7C1E6812640AC +:109F85002200E2C1E3812340E10121C02080E041BC +:109F9500A00160C06180A1416300A3C1A2816240AC +:109FA5006600A6C1A7816740A50165C06480A4417C +:109FB5006C00ACC1AD816D40AF016FC06E80AE412C +:109FC500AA016AC06B80AB416900A9C1A88168403C +:109FD5007800B8C1B9817940BB017BC07A80BA41AC +:109FE500BE017EC07F80BF417D00BDC1BC817C407C +:109FF500B40174C07580B5417700B7C1B6817640AC +:10A005007200B2C1B3817340B10171C07080B041BB +:10A01500500090C191815140930153C052809241AB +:10A02500960156C057809741550095C1948154407B +:10A035009C015CC05D809D415F009FC19E815E402B +:10A045005A009AC19B815B40990159C0588098413B +:10A05500880148C0498089414B008BC18A814A40AB +:10A065004E008EC18F814F408D014DC04C808C417B +:10A07500440084C185814540870147C046808641AB +:10A08500820142C043808341410081C180814040BB +:10A09500E4FF74F82FF582E43402F583E0700302DF +:10A0A500A138743A2FF8E620E50302A138EF75F0E0 +:10A0B50008A42400F582E43420AD82FCF583E58212 +:10A0C5002405F582E43583F583E0546064607063AC +:10A0D500EF25E024EFF582E43402F583E475F00121 +:10A0E50012A29785F082F583E08D828C83F074F857 +:10A0F5002FF582E43402F583E014F07036EF25E0A5 +:10A1050024C7F582E4347FF583E4F0EF25E0FEC350 +:10A11500740C9E75F040A42440F582E5F0347BADC7 +:10A1250082FCEF25E024EFF582E43402F583ECF0C0 +:0CA13500A3EDF00FEF6404600302A0979C +:01A1410022FB +:10A14200E709F608DFFA8046E709F208DFFA803EFF +:10A1520088828C83E709F0A3DFFA8032E309F608EC +:10A16200DFFA8078E309F208DFFA807088828C8354 +:10A17200E309F0A3DFFA806489828A83E0A3F60808 +:10A18200DFFA805889828A83E0A3F208DFFA804CE2 +:10A1920080D280FA80C680D4806980F280338010B9 +:10A1A20080A680EA809A80A880DA80E280CA803322 +:10A1B20089828A83ECFAE493A3C8C582C8CCC5839A +:10A1C200CCF0A3C8C582C8CCC583CCDFE9DEE7806A +:10A1D2000D89828A83E493A3F608DFF9ECFAA9F0E9 +:10A1E200EDFB2289828A83ECFAE0A3C8C582C8CC3F +:10A1F200C583CCF0A3C8C582C8CCC583CCDFEADE58 +:10A20200E880DB89828A83E493A3F208DFF980CCB9 +:10A2120088F0ED2402B4040050C2F582EB2402B4AB +:10A22200040050B823234582F582EF4E60AEEF6002 +:09A23200010EE5822390A1927354 +:10A23B00BB010689828A83E0225002E722BBFE0221 +:09A24B00E32289828A83E4932254 +:10A25400BB010CE58229F582E5833AF583E02250BF +:10A2640006E92582F8E622BBFE06E92582F8E22209 +:0DA27400E58229F582E5833AF583E4932223 +:10A28100C5F0F8A3E028F0C5F0F8E5821582700268 +:06A291001583E038F02205 +:10A29700A3F8E0C5F025F0F0E5821582700215837A +:06A2A700E0C838F0E822D7 +:10A2AD00BB0110E58229F582E5833AF583E0F5F0EF +:10A2BD00A3E0225009E92582F886F008E622BBFECC +:10A2CD000AE92582F8E2F5F008E222E5832AF58312 +:08A2DD00E993F5F0A3E99322D7 +:10A2E50075F008758200EF2FFFEE33FECD33CDCC30 +:10A2F50033CCC58233C5829BED9AEC99E5829840B3 +:10A305000CF582EE9BFEED9AFDEC99FC0FD5F0D68F +:10A31500E4CEFBE4CDFAE4CCF9A88222B800C1B9B9 +:10A325000059BA002DEC8BF084CFCECDFCE5F0CBF7 +:10A33500F97818EF2FFFEE33FEED33FDEC33FCEB30 +:10A3450033FB10D703994004EB99FB0FD8E5E4F9EB +:10A35500FA227818EF2FFFEE33FEED33FDEC33FCD8 +:10A36500C933C910D7059BE99A4007EC9BFCE99ACC +:10A37500F90FD8E0E4C9FAE4CCFB2275F010EF2F11 +:10A38500FFEE33FEED33FDCC33CCC833C810D70711 +:10A395009BEC9AE899400AED9BFDEC9AFCE899F84C +:0EA3A5000FD5F0DAE4CDFBE4CCFAE4C8F922DF +:10A3B300EB9FF5F0EA9E42F0E99D42F0E89C45F000 +:01A3C3002277 +:10A3C400E8600FECC313FCED13FDEE13FEEF13FF77 +:03A3D400D8F1229B +:10A3D700080808E6CF2FF618E6CE3EF618E6CD3D7C +:07A3E700F618E6CC3CF6225B +:0CA3EE00ECF0A3EDF0A3EEF0A3EFF022E2 +:10A3FA00A8828583F0D083D08212A41112A41112EC +:10A40A00A41112A411E473E493A3C583C5F0C58310 +:10A41A00C8C582C8F0A3C583C5F0C583C8C582C8AC +:01A42A00220F +:00000001FF +/***************************************************************************** + * + * whiteheat.h -- ConnectTech WhiteHEAT Firmware. + * + * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * (10/09/2002) Stuart MacDonald + * Firmware 4.06 + * + * (04/09/2000) gkh + * Updated the firmware with the latest provided by ConnectTech. + * + * (01/16/2000) gkh + * Fixed my intel hex processing tool, so now the firmware actually + * matches the original file (this was causing a few problems...) + * + * (01/15/2000) gkh + * Added debug loader firmware if DEBUG is #defined: + * Port 1 LED flashes when the vend_ax program is running + * Port 2 LED flashes when any SETUP command arrives + * Port 3 LED flashes when any valid VENDOR request occurs + * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs + * + * version 1.0 (01/09/2000) gkh + * Original firmware from ConnectTech massaged a little to be program + * readable. + * + *****************************************************************************/ + +#define whiteheat_DATE "20000106" diff --git a/firmware/whiteheat_loader.HEX b/firmware/whiteheat_loader.HEX new file mode 100644 index 0000000..5f663f6 --- /dev/null +++ b/firmware/whiteheat_loader.HEX @@ -0,0 +1,314 @@ +:0300000002098D65 +:030033000208FBC5 +:03004300020B00AD +:03004B000205AA01 +:10010000907FA5E05410FFC4540F4450F50F13E442 +:1001100033F511907FE9E0245EB407004003020349 +:1001200078900128F82828730201BC0201BC020162 +:100130009102013D02015302016F02019A907F007A +:10014000E511F0907FB57401F0907FB4E04402F0C7 +:10015000020378907F92E0FFC4540F907F00F090EC +:100160007FB57401F0907FB4E04402F0020378128E +:100170000A895007E4907F00F08006907F00740F9A +:10018000F0907FB57401F0907FB4E04402F0020378 +:1001900078907FEAE0F50F020378907F007407F013 +:1001A000907FB57401F0907FB4E04402F07FE87E68 +:1001B00003120D94D206120CCC020378907FEAE071 +:1001C000752800F529A3E0FEE4EE4228907FEEE0DA +:1001D000752A00F52BA3E0FEE4EE422A907FE8E0CA +:1001E00064C060030202C9E52B452A70030203784C +:1001F000C3E52B9440E52A94005008852A2C852BD2 +:100200002D8006752C00752D40907FE9E064A37069 +:1002100034F530F531C3E531952DE530952C505C42 +:10022000E5292531F582E5303528F583E0FF7400B6 +:100230002531F582E4347FF583EFF00531E5317047 +:1002400002053080D0E4F530F531C3E531952DE578 +:1002500030952C501874002531F582E4347FF583F5 +:1002600074CDF00531E5317002053080DDAF29AE87 +:1002700028AD2D7A7F79007B00120BF4907FB5E5D5 +:100280002DF0E52D2529F529E52C3528F528C3E5A0 +:100290002B952DF52BE52A952CF52A907F92E0FFE2 +:1002A000C4540F752E00F52FD39400E52E94005002 +:1002B0000C907FB4E020E1030201E780F4907FB46A +:1002C000E020E2030201E780F4907FE8E064406010 +:1002D00003020378E52B452A7003020378E4907F3C +:1002E000C5F0907F92E0FFC4540F752E00F52FD318 +:1002F0009400E52E94005009907FC4E030E109801D +:10030000F7907FB4E020E3F9907FC5E0752C00F50D +:100310002D907FE9E064A37034F530F531C3E53109 +:10032000952DE530952C503474C02531F582E43498 +:010330007E4E +:10033100F583E0FFE5292531F582E5303528F583A0 +:10034100EFF00531E5317002053080D0AF29AE28DC +:10035100AD2D7A7E79C07BC0120C3FE52D2529F5A4 +:1003610029E52C3528F528C3E52B952DF52BE52A14 +:09037100952CF52A0202D4C322E6 +:10037A00907FE9E070030204521470030204CE2451 +:10038A00FE700302054224FB700302044C1470033E +:10039A0002044614700302043A147003020440244F +:1003AA00056003020596120E4440030205A2907FDF +:1003BA00EBE024FE60161460402402706974119008 +:1003CA007FD4F07400907FD5F00205A2907FEAE016 +:1003DA00FF120B588B258A268927EA496011AE023B +:1003EA00EE907FD4F0AF01EF907FD5F00205A29096 +:1003FA007FB4E04401F00205A2907FEAE0FF120810 +:10040A00BA8B258A268927EA496011AE02EE907FC7 +:10041A00D4F0AF01EF907FD5F00205A2907FB4E04F +:10042A004401F00205A2907FB4E04401F00205A263 +:10043A00120E1F0205A2120E2D0205A2120AF702BF +:10044A0005A2120E110205A2120E4640030205A2CF +:10045A00907FE8E0247F60241460312402705BA25C +:10046A0000E433FF25E0FFA202E4334F907F00F05F +:10047A00E4A3F0907FB57402F00205A2E4907F0035 +:10048A00F0A3F0907FB57402F00205A2907FECE031 +:10049A00F45480FFC4540FFFE054072F25E024B41E +:1004AA00F582E4347FF583E054FD907F00F0E4A305 +:1004BA00F0907FB57402F00205A2907FB4E0440187 +:1004CA00F00205A2120E4840030205A2907FE8E05E +:1004DA0024FE601D240260030205A2907FEAE0B4B4 +:1004EA000105C2000205A2907FB4E04401F00205B2 +:1004FA00A2907FEAE07038907FECE0F45480FFC469 +:10050A00540FFFE054072F25E024B4F582E4347F2A +:10051A00F583E4F0907FECE05480FF131313541F2B +:10052A00FFE054072F907FD7F0E04420F0806990D5 +:10053A007FB4E04401F08060120E4A505B907FE87D +:10054A00E024FE60182402704F907FEAE0B40104B0 +:10055A00D2008044907FB4E04401F0803B907FEA6F +:10056A00E07020907FECE0F45480FFC4540FFFE069 +:10057A0054072F25E024B4F582E4347FF58374010F +:10058A00F08015907FB4E04401F0800C1201005015 +:10059A0007907FB4E04401F0907FB4E04402F02277 +:1005AA00C0E0C083C082C085C084C086758600C092 +:1005BA00D0C000C001C002C003C006C007907FA51A +:1005CA00E030E206750D06020676907FA5E020E18E +:1005DA000CE50D64026006750D07020676AF0DEF95 +:1005EA0024FE604814602C24FE6077240460030211 +:1005FA000676AB09AA0AA90BAF0C050C8F82758384 +:10060A0000120822907FA6F0E50C6508705E750D51 +:10061A00058059907FA6E0AB09AA0AA90BAE0C8EF9 +:10062A008275830012084F750D028040E50824FE8A +:10063A00B50C07907FA5E04420F0E50814B50C0A34 +:10064A00907FA5E04440F0E4F50D907FA6E0AB0969 +:10065A00AA0AA90BAE0C8E8275830012084F050CEC +:10066A00800A907FA5E04440F0E4F50D5391DFD075 +:10067A0007D006D003D002D001D000D0D0D086D087 +:0A068A0084D085D082D083D0E03206 +:100694008C338D34907F95E044C0F0E4F535F53625 +:1006A400C3E5369534E53595335069EF2536F58243 +:1006B400E5353EF58374FFF0F46002C322EF25367E +:1006C400F582E5353EF583E4F06002C322EF25367A +:1006D400F582E5353EF58374AAF064AA6002C3226C +:1006E400EF2536F582E5353EF5837455F0645560A3 +:1006F40002C322AD36E5362FF582E5353EF583EDAE +:10070400F0FCAC05ED6C6002C3220536E5367002E0 +:100714000535808CE4F535F536C3E5369534E53595 +:1007240095335027EF2536F582E5353EF583E065B0 +:10073400366002C322EF2536F582E5353EF583E4C3 +:0D074400F00536E5367002053580CED32273 +:10075100C204D205C203C200C202C201120E3DD2BE +:10076100E843D820907FAB74FFF0907FA9F0907F91 +:10077100AAF05391EF907F95E044C0F0907F93747D +:1007810030F0120A19907FAFE04401F0907FAEE0A3 +:10079100440DF0D2AF120E352001427524007523AD +:1007A100007522007521007F487E927D007C00ABA0 +:1007B10024AA23A922A821C31208A950DB2001D809 +:1007C1007A0079007800E5242401F524EA3523F53F +:1007D10023E93522F522E83521F52180CA300105CA +:1007E10012037AC20130041A120E4050131209008A +:1007F100300007907FD6E030E7F3120D4A120E4227 +:08080100C2031208FF80D62299 +:10080900BB010689828A83E0225002E722BBFE02ED +:09081900E32289828A83E4932220 +:10082200BB010CE58229F582E5833AF583E022508B +:1008320006E92582F8E622BBFE06E92582F8E222D5 +:0D084200E58229F582E5833AF583E49322EF +:10084F00F8BB010DE58229F582E5833AF583E8F0DF +:10085F00225006E92582C8F622BBFE05E92582C88B +:02086F00F22273 +:10087100BB0110E58229F582E5833AF583E0F5F0C5 +:10088100A3E0225009E92582F886F008E622BBFEA2 +:100891000AE92582F8E2F5F008E222E5832AF583E8 +:0808A100E993F5F0A3E99322AD +:1008A900EB9FF5F0EA9E42F0E99D42F0E89C45F0A5 +:0108B900221C +:0208BA008F2885 +:1008BC00E4F529752AFF752B11752C32AB2AAA2B5E +:1008CC00A92C900001120822B4031DAF290529EFB1 +:1008DC00B52801221208097E0029FFEE3AA90775F6 +:0E08EC002AFFF52B892C80D47B007A0079003E +:0108FA0022DB +:0408FB0053D8EF32AD +:0108FF0022D6 +:09090000907FD6E04480F0807481 +:10097D00438701000000000000000000000000227D +:0C098D00787FE4F6D8FD7581390209D4AA +:10099900020751E493A3F8E493A34003F68001F21C +:1009A90008DFF48029E493A3F85407240CC8C3335F +:1009B900C4540F4420C8834004F456800146F6DF2E +:1009C900E4800B0102040810204080900DECE47EC5 +:1009D900019360BCA3FF543F30E509541FFEE49323 +:1009E900A360010ECF54C025E060A840B8E493A3EA +:1009F900FAE493A3F8E493A3C8C582C8CAC583CA15 +:100A0900F0A3C8C582C8CAC583CADFE9DEE780BECC +:100A1900E4907F9CF07F0AFE120D94907F96748972 +:100A2900F0907F9C74CFF07FF47E01120D94907F3B +:100A390096E054FEF07F0A7E00120D947F057E0039 +:100A4900120D94907F96E04402F0E0547FF07F0508 +:100A59007E00120D94907F96E04440F07F057E0061 +:100A6900120D94907F96E054BFF07F327E00120DF4 +:100A790094907F96E04440F07F327E00120D9422DC +:100A8900753201E532601B7F01120DD77F007E0EA2 +:100A99007D007C01120694E433F53270057F0F1254 +:100AA9000DD7E532601B7F02120DD77F007E807D56 +:100AB900007C80120694E433F53270057F0F120D25 +:100AC900D7E532601B7F03120DD77F007E207D4062 +:100AD9007C5B120694E433F53270057F0F120DD753 +:0E0AE900E5326005E4FF120DD7E53224FF224E +:080AF700907FEAE0F510D32224 +:010AFF0032C4 +:100B0000020D6400020DAB00020D2F00020D7C00EF +:100B1000020DC100020AFF00020E4C00020E4D0041 +:100B2000020E4E00020E4F00020E5000020E510047 +:100B3000020E5200020E5300020E5400020E550027 +:100B4000020E5600020E5700020E5800020E590007 +:080B5000020E5A00020E5B00C8 +:100B5800E4FE752AFF752B11752C12AB2AAA2BA956 +:100B68002C9000011208226402702DAD060EEDB51E +:100B780007012290000212087185F028F5296228E1 +:100B8800E5286229E529622829FDE5283AA905759D +:0E0B98002AFFF52B892C80C37B007A007900A0 +:010BA600222C +:100BA700AB07AA06AC05E4FDE5116011EAFFAE0547 +:100BB7000DEE2410F582E4340FF583EFF0EBAE056C +:100BC7000D74102EF582E4340FF583EBF0AF050DAD +:100BD70074102FF582E4340FF583ECF0AF0F7A0F22 +:0D0BE7007B10120D107F0A7E00120D94226B +:100BF4008E328F338D348A358B36E4FDF537E5112B +:100C04006012E532FFAE050DEE2413F582E4340FD5 +:100C1400F583EFF0E533AE050D74132EF582E4345D +:100C24000FF583E533F0AF0F7A0F7B13120D10AF7E +:0B0C34000FAD34AB36AA35120CF122D4 +:100C3F008E328F338D348A358B36E4F537E537C3F3 +:100C4F00953450200533E533AE327002053214FF70 +:100C5F00E5362537F582E43535F583E0FD120BA730 +:050C6F00053780D922C9 +:100C7400A907E50D7025907FA5E04480F0E925E003 +:100C84004401907FA6F08D08AF03A9077509018A76 +:0D0C94000A890BE4F50C750D03D322C32271 +:100CA100A907E50D7023907FA5E04480F0E925E0D8 +:100CB100907FA6F08D08AF03A9077509018A0A89FB +:0B0CC1000BE4F50C750D01D322C322DB +:100CCC00907FD6E054FBF0E04408F0300604E0449A +:100CDC0002F07FD07E07120D94907FD6E054F7F08F +:050CEC00E04404F022C9 +:100CF100120C74E50D24FA6010146007240770F3D8 +:0F0D01007F0822E4F50D7F0722E4F50D7F06221F +:100D1000120CA1E50D24FA6010146007240770F38B +:0F0D20007F0822E4F50D7F0722E4F50D7F062200 +:100D2F00C0E0C083C082907FC4E4F05391EF907F06 +:0B0D3F00AB7404F0D082D083D0E0320F +:100D4A00907FD6E030E712E04401F07F147E001273 +:0A0D5A000D94907FD6E054FEF022C5 +:100D6400C0E0C083C082D2015391EF907FAB740185 +:080D7400F0D082D083D0E03200 +:100D7C00C0E0C083C082D2035391EF907FAB740864 +:080D8C00F0D082D083D0E032E8 +:100D94008E388F39E5391539AE38700215384E6002 +:070DA40005120E0080EE2293 +:100DAB00C0E0C083C0825391EF907FAB7402F0D050 +:060DBB0082D083D0E0327B +:100DC100C0E0C083C0825391EF907FAB7410F0D02C +:060DD10082D083D0E03265 +:100DD700AE077F217D0174002EF582E4340FAB82CC +:050DE700FA120D1022BC +:100DEC00500F00C0F9A4B0999282F880988883C6FD +:030DFC00A1868E3F +:010DFF0000F3 +:100E00007400F58690FDA57C05A3E582458370F905 +:010E100022BF +:0E0E1100907F00E510F0907FB57401F0D322C1 +:0E0E1F00907F00E50EF0907FB57401F0D322B5 +:080E2D00907FEAE0F50ED322EC +:080E3500E4F50DD2E9D2AF2271 +:030E3D00D20022BE +:020E4000D322BB +:020E4200D322B9 +:020E4400D322B7 +:020E4600D322B5 +:020E4800D322B3 +:020E4A00D322B1 +:010E4C003273 +:010E4D003272 +:010E4E003271 +:010E4F003270 +:010E5000326F +:010E5100326E +:010E5200326D +:010E5300326C +:010E5400326B +:010E5500326A +:010E56003269 +:010E57003268 +:010E58003267 +:010E59003266 +:010E5A003265 +:010E5B003264 +:101100001201000100000040470510270100010204 +:10111000000109022000010103A0000904000002EF +:10112000FF0000040705820240000007050202409C +:10113000000004030904260341006E0063006800F8 +:101140006F007200200043006800690070007300A7 +:101150002C00200049006E0063002E00280346008A +:10116000690072006D007700610072006500200068 +:101170004600720061006D00650057006F0072004C +:101180006B0073002A0343006F006E006600690065 +:101190006700750072006100740069006F006E00E6 +:1011A000200053007400720069006E006700220383 +:1011B00049006E0074006500720066006100630003 +:1011C0006500200053007400720069006E00670023 +:0211D00000001D +:00000001FF +/***************************************************************************** + * + * whiteheat.h -- ConnectTech WhiteHEAT Firmware. + * + * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * (10/09/2002) Stuart MacDonald + * Firmware 4.06 + * + * (04/09/2000) gkh + * Updated the firmware with the latest provided by ConnectTech. + * + * (01/16/2000) gkh + * Fixed my intel hex processing tool, so now the firmware actually + * matches the original file (this was causing a few problems...) + * + * (01/15/2000) gkh + * Added debug loader firmware if DEBUG is #defined: + * Port 1 LED flashes when the vend_ax program is running + * Port 2 LED flashes when any SETUP command arrives + * Port 3 LED flashes when any valid VENDOR request occurs + * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs + * + * version 1.0 (01/09/2000) gkh + * Original firmware from ConnectTech massaged a little to be program + * readable. + * + *****************************************************************************/ + +#define whiteheat_DATE "20000106" diff --git a/firmware/whiteheat_loader_debug.HEX b/firmware/whiteheat_loader_debug.HEX new file mode 100644 index 0000000..5633d58 --- /dev/null +++ b/firmware/whiteheat_loader_debug.HEX @@ -0,0 +1,403 @@ +:10000000000000000302098D0000003303020E709F +:100010000000004303020B000000004B030205B385 +:100020000000010010907FA5E05410FFC4540F445D +:1000300050F50F13E4000110000001101033F5110A +:10004000907FE9E0245EB407004003020300012032 +:1000500000000120107C900128F82828730201BCC0 +:100060000201BC02010001300000013010910201C8 +:100070003D02015302016F02019A907F000001408E +:100080000000014010E511F0907FB57401F0907F01 +:10009000B4E04402F0000150000001501002037C63 +:1000A000907F92E0FFC4540F907F00F090000160B9 +:1000B00000000160107FB57401F0907FB4E044024D +:1000C000F002037C1200017000000170100A8950D8 +:1000D00007E4907F00F08006907F00740F0001809D +:1000E0000000018010F0907FB57401F0907FB4E0C3 +:1000F0004402F0020300019000000190107C907F08 +:10010000EAE0F50F02037C907F007407F00001A085 +:10011000000001A010907FB57401F0907FB4E0441E +:1001200002F07FE87E0001B0000001B01003120D64 +:10013000D5D206120D0D02037C907FEAE00001C0CB +:10014000000001C010752900F52AA3E0FEE4EE428C +:1001500029907FEEE00001D0000001D010752B0047 +:10016000F52CA3E0FEE4EE422B907FE8E00001E0F6 +:10017000000001E01064C060030202C9E52C452BB9 +:10018000700302037C0001F0000001F010C3E52CB5 +:100190009440E52B94005008852B2D852C000200FF +:1001A00000000200102E8006752D00752E40907FF5 +:1001B000E9E064A370000210000002101034F53171 +:1001C000F532C3E532952EE531952D505C000220C5 +:1001D0000000022010E52A2532F582E5313529F5A7 +:1001E00083E0FF740000023000000230102532F579 +:1001F00082E4347FF583EFF00532E532700002408F +:10020000000002401002053180D0E4F531F532C320 +:10021000E532952EE5000250000002501031952D78 +:10022000501874002532F582E4347FF583000260B3 +:10023000000002601074CDF00532E5327002053125 +:1002400080DDAF2AAE000270000002701029AD2ED2 +:100250007A7F79007B00120BF4907FB5E500028075 +:1002600000000280102EF0E52E252AF52AE52D3516 +:1002700029F529C3E500029000000290102C952E6C +:10028000F52CE52B952DF52B907F92E0FF0002A039 +:10029000000002A010C4540F752F00F530D3940055 +:1002A000E52F9400500002B0000002B0100C907FC7 +:1002B000B4E020E1030201E780F4907FB40002C0C3 +:1002C000000002C010E020E2030201E780F4907F0A +:1002D000E8E06440600002D0000002D01003020396 +:1002E0007CE52C452B700302037CE4907F0002E048 +:1002F000000002E010C5F0907F92E0FFC4540F753B +:100300002F00F530D30002F0000002F0109400E559 +:100310002F94005009907FC4E030E1098000030071 +:100320000000030010F7907FB4E020E3F9907FC550 +:10033000E0752D00F500031000000310102E907FD3 +:10034000E9E064A3703890206BF0F531F5000320EC +:10035000000003201032C3E532952EE531952D5073 +:100360003474C025320003300000033010F582E4FD +:10037000347EF583E0FFE52A2532F582E50003406F +:100380000000034010313529F583EFF00532E532E6 +:1003900070020531800003500000035010D0AF2AD6 +:1003A000AE29AD2E7A7E79C07BC0120C800003602E +:1003B0000000036010E52E252AF52AE52D3529F5E4 +:1003C00029C3E52C95000370000003700D2EF52C59 +:1003D000E52B952DF52B0202D4C300000000037D10 +:1003E000012200000000037E10907FE9E07003020C +:1003F00004561470030204D22400038E0000038EFE +:1004000010FE700302054624FB70030204501470B2 +:100410000300039E0000039E1002044A14700302AE +:10042000043E147003020444240003AE000003AE33 +:100430001005600302059A120E7B40030205AB9083 +:100440007F0003BE000003BE10EBE024FE60161424 +:100450006040240270697411900003CE000003CE46 +:10046000107FD4F07400907FD5F00205AB907FEA46 +:10047000E00003DE000003DE10FF120B588B268A1B +:10048000278928EA496011AE020003EE000003EE5E +:1004900010EE907FD4F0AF01EF907FD5F00205AB66 +:1004A000900003FE000003FE107FB4E04401F00260 +:1004B00005AB907FEAE0FF120C00040E0000040E72 +:1004C000103F8B268A278928EA496011AE02EE90F8 +:1004D0007F00041E0000041E10D4F0AF01EF907FD7 +:1004E000D5F00205AB907FB4E000042E0000042E8E +:1004F000104401F00205AB907FB4E04401F0020526 +:10050000AB00043E0000043E10120E520205AB1276 +:100510000E600205AB120AF70200044E0000044E02 +:100520001005AB1208F10205AB120E7D4003020567 +:10053000AB00045E0000045E10907FE8E0247F6062 +:10054000241460312402705BA200046E0000046E6B +:100550001000E433FF25E0FFA202E4334F907F0058 +:10056000F000047E0000047E10E4A3F0907FB574D8 +:1005700002F00205ABE4907F0000048E0000048EC0 +:1005800010F0A3F0907FB57402F00205AB907FEC01 +:10059000E000049E0000049E10F45480FFC4540F39 +:1005A000FFE054072F25E024B40004AE000004AEA1 +:1005B00010F582E4347FF583E054FD907F00F0E491 +:1005C000A30004BE000004BE10F0907FB57402F0DA +:1005D0000205AB907FB4E044010004CE000004CEDD +:1005E00010F00205AB120E7F40030205AB907FE8CE +:1005F000E00004DE000004DE1024FE601D24026022 +:10060000030205AB907FEAE0B40004EE000004EEC4 +:10061000100105C2000205AB907FB4E04401F00276 +:10062000050004FE000004FE10AB907FEAE0703885 +:10063000907FECE0F45480FFC400050E0000050E2E +:1006400010540FFFE054072F25E024B4F582E43462 +:100650007F00051E0000051E10F583E4F0907FEC7E +:10066000E05480FF131313541F00052E0000052EC5 +:1006700010FFE054072F907FD7F0E04420F0806E09 +:100680009000053E0000053E107FB4E04401F0807C +:1006900065120E815060907FE800054E0000054E07 +:1006A00010E024FE601824027054907FEAE0B40148 +:1006B0000400055E0000055E10D2008049907FB402 +:1006C000E04401F08040907FEA00056E0000056E76 +:1006D00010E07020907FECE0F45480FFC4540FFFD2 +:1006E000E000057E0000057E1054072F25E024B4AD +:1006F000F582E4347FF583740100058E0000058ED9 +:1007000010F0801A907FB4E04401F08011E4902052 +:100710006A00059E0000059E10F01201005007902F +:100720007FB4E04401F0907FB40005AE000005AE58 +:1007300004E04402F0000000000005B201220000C5 +:10074000000005B310C0E0C083C082C085C084C073 +:1007500086758600C00005C3000005C310D0C00028 +:10076000C001C002C003C006C007907FA50005D32A +:10077000000005D310E030E206750D0602067F90FA +:100780007FA5E020E10005E3000005E3100CE50D86 +:1007900064026006750D0702067FAF0DEF0005F3DA +:1007A000000005F31024FE604814602C24FE6077DE +:1007B00024046003020006030000060310067FAB5A +:1007C00009AA0AA90BAF0C050C8F827583000613CA +:1007D000000006131000120785907FA6F0E50C6557 +:1007E00008705E750D000623000006231005805971 +:1007F000907FA6E0AB09AA0AA90BAE0C8E000633C7 +:100800000000063310827583001207B2750D028056 +:1008100040E50824FE0006430000064310B50C071F +:10082000907FA5E04420F0E50814B50C0A000653BB +:100830000000065310907FA5E04440F0E4F50D90D1 +:100840007FA6E0AB090006630000066310AA0AA9B0 +:100850000BAE0C8E827583001207B2050C00067376 +:100860000000067310800A907FA5E04440F0E4F594 +:100870000D5391DFD0000683000006831007D006D9 +:10088000D003D002D001D000D0D0D086D0000693C3 +:10089000000006930A84D085D082D083D0E0320055 +:1008A0000000069D10C204D205E4F525C203C20073 +:1008B000C202C201120006AD000006AD100E74D2D5 +:1008C000E843D820907FAB74FFF0907FA90006BD6D +:1008D000000006BD10F0907FAAF05391EF907F9535 +:1008E000E044C0F0900006CD000006CD107F937468 +:1008F00030F0120A1975244875239275220006DD1E +:10090000000006DD1000752100E4FFFE7E0590204A +:10091000687401F0A30006ED000006ED10DEFC7E19 +:10092000007F05907FAFE04401F0907FAE0006FDB0 +:10093000000006FD10E0440DF0D2AF120E68300149 +:100940000AE490206900070D0000070D10F0120363 +:100950007EC20130041A120E775013120900071DCF +:100960000000071D1000300007907FD6E030E7F34D +:10097000120D8B120E00072D0000072D1079C203F7 +:100980007FFF7EFF7DFF7CFF782112081D00073D61 +:100990000000073D107B007A0079007800C3120840 +:1009A0000C701B752400074D0000074D104875237F +:1009B00092F522F5216325FF902068E52500075D6B +:1009C0000000075D0EF0A37401F0A3F0A3F012087D +:1009D000FF809B000000076B012200000000076CF5 +:1009E00010BB010689828A83E0225002E722BBFE07 +:1009F0000200077C0000077C09E32289828A83E4E5 +:100A0000932200000000078510BB010CE58229F548 +:100A100082E5833AF583E0225000079500000795B0 +:100A20001006E92582F8E622BBFE06E92582F8E2F7 +:100A3000220007A5000007A50DE58229F582E583C0 +:100A40003AF583E493220000000007B210F8BB01DE +:100A50000DE58229F582E5833AF583E8F00007C2C7 +:100A6000000007C210225006E92582C8F622BBFE0C +:100A700005E92582C80007D2000007D202F2220051 +:100A8000000007D410BB0110E58229F582E5833A06 +:100A9000F583E0F5F00007E4000007E410A3E0228E +:100AA0005009E92582F886F008E622BBFE0007F42B +:100AB000000007F4100AE92582F8E2F5F008E222C6 +:100AC000E5832AF5830008040000080408E993F58B +:100AD000F0A3E993220000000000080C10EB9FF542 +:100AE000F0EA9E42F0E99D42F0E89C45F000081CC7 +:100AF0000000081C012200000000081D1008080862 +:100B0000E62FFFF618E63EFEF618E63DFD00082D3E +:100B10000000082D07F618E63CFCF6220000083419 +:100B2000048C348D350000000000083810907F954B +:100B3000E044C0F0E4F536F537C3E53795000848E2 +:100B4000000008481035E53695345069EF2537F533 +:100B500082E5363EF500085800000858108374FFFF +:100B6000F0F46002C322EF2537F582E5360008680D +:100B700000000868103EF583E4F06002C322EF2510 +:100B800037F582E53600087800000878103EF583D6 +:100B900074AAF064AA6002C322EF2537F500088822 +:100BA000000008881082E5363EF5837455F06455E0 +:100BB0006002C322AD000898000008981037E5379E +:100BC0002FF582E5363EF583EDF0FCAC050008A874 +:100BD000000008A810ED6C6002C3220537E53770ED +:100BE000020536808C0008B8000008B810E4F5361D +:100BF000F537C3E5379535E536953450270008C8F5 +:100C0000000008C810EF2537F582E5363EF583E091 +:100C100065376002C30008D8000008D81022EF250D +:100C200037F582E5363EF583E4F00537E50008E860 +:100C3000000008E808377002053680CED3000000B7 +:100C4000000008F001220000000008F10E907F0073 +:100C5000E510F0907FB57401F0D32200000008FF8A +:100C6000012200000000090009907FD6E04480F0D6 +:100C7000807400000000097D10438701000000001F +:100C800000000000000000002200098D0000098D16 +:100C90000C787FE4F6D8FD75813A0209D400000093 +:100CA000000009991002069DE493A3F8E493A34081 +:100CB00003F68001F20009A9000009A91008DFF479 +:100CC0008029E493A3F85407240CC8C3330009B95E +:100CD000000009B910C4540F4420C8834004F456DE +:100CE000800146F6DF0009C9000009C910E4800B45 +:100CF0000102040810204080900E2DE47E0009D9E6 +:100D0000000009D910019360BCA3FF543F30E509EE +:100D1000541FFEE4930009E9000009E910A36001F3 +:100D20000ECF54C025E060A840B8E493A30009F9B1 +:100D3000000009F910FAE493A3F8E493A3C8C5826C +:100D4000C8CAC583CA000A0900000A0910F0A3C86E +:100D5000C582C8CAC583CADFE9DEE780BE000A19BA +:100D600000000A1910E4907F9CF07F0AFE120DD556 +:100D7000907F967489000A2900000A2910F0907F5C +:100D80009C74CFF07FF47E01120DD5907F000A395C +:100D900000000A391096E054FEF07F0A7E00120D22 +:100DA000D57F057E00000A4900000A4910120DD5C2 +:100DB000907F96E04402F0E0547FF07F05000A59EE +:100DC00000000A59107E00120DD5907F96E0444035 +:100DD000F07F057E00000A6900000A6910120DD537 +:100DE000907F96E054BFF07F327E00120D000A79AA +:100DF00000000A7910D5907F96E04440F07F327E63 +:100E000000120DD522000A8900000A8910753301ED +:100E1000E533601B7F01120E187F007E0E000A99D9 +:100E200000000A99107D007C01120834E433F53388 +:100E300070057F0F12000AA900000AA9100E18E51C +:100E400033601B7F02120E187F007E807D000AB97E +:100E500000000AB910007C80120834E433F53370C6 +:100E6000057F0F120E000AC900000AC91018E533E9 +:100E7000601B7F03120E187F007E207D40000AD980 +:100E800000000AD9107C5B120834E433F533700596 +:100E90007F0F120E18000AE900000AE90DE5336021 +:100EA00005E4FF120E18E53324FF000000000AF6E7 +:100EB0000122000000000AF708907FEAE0F510D355 +:100EC0002200000000000AFF0132000000000B00B9 +:100ED00010020DA500020DEC00020D7000020DBD08 +:100EE00000000B1000000B1010020E0200020AFF9F +:100EF00000020E8300020E8400000B2000000B2075 +:100F000010020E8500020E8600020E8700020E8877 +:100F100000000B3000000B3010020E8900020E8A18 +:100F200000020E8B00020E8C00000B4000000B40F4 +:100F300010020E8D00020E8E00020E8F00020E9027 +:100F400000000B5000000B5008020E9100020E92A0 +:100F50000000000000000B5810E4FE752BFF752CFC +:100F600011752D12AB2BAA2CA9000B6800000B6881 +:100F7000102D9000011207856402702DAD060EED54 +:100F8000B5000B7800000B781007012290000212C8 +:100F900007D485F029F52A6229000B8800000B8808 +:100FA00010E529622AE52A622929FDE5293AA905E1 +:100FB00075000B9800000B980E2BFFF52C892D80E7 +:100FC000C37B007A0079000000000BA6012200001C +:100FD00000000BA706AB07AA06AC050000000BAD8E +:100FE00010E4FDE5116011EAFFAE050DEE2410F5E9 +:100FF00082000BBD00000BBD10E4340FF583EFF051 +:10100000EBAE050D74102EF582000BCD00000BCD5C +:1010100010E4340FF583EBF0AF050D74102FF5825B +:10102000E4000BDD00000BDD10340FF583ECF0AFB6 +:101030000F7A0F7B10120D517F000BED00000BEDAE +:10104000060A7E00120DD50000000BF301220000FD +:1010500000000BF40A8E338F348D358A368B3700BF +:1010600000000BFE10E4FDF538E5116012E533FFDA +:10107000AE050DEE24000C0E00000C0E1013F582D0 +:10108000E4340FF583EFF0E534AE050D74000C1E6B +:1010900000000C1E10132EF582E4340FF583E534A6 +:1010A000F0AF0F7A0F000C2E00000C2E107B1312E5 +:1010B0000D51AF0FAD35AB37AA36120D32000C3ED5 +:1010C00000000C3E0122000000000C3F028F2900AE +:1010D00000000C4110E4F52A752BFF752C11752DBD +:1010E00032AB2BAA2C000C5100000C5110A92D90F2 +:1010F0000001120785B4031DAF2A052AEF000C6119 +:1011000000000C6110B529012212076C7E0029FF36 +:10111000EE3AA90775000C7100000C710E2BFFF55B +:101120002C892D80D47B007A0079000000000C7F90 +:101130000122000000000C800A8E338F348D358A26 +:10114000368B370000000C8A10E4F538E538C3957B +:101150003550200534E534AE33000C9A00000C9A6B +:10116000107002053314FFE5372538F582E4353673 +:10117000F5000CAA00000CAA0A83E0FD120BA705DB +:101180003880D90000000CB40122000000000CB52A +:1011900010A907E50D7025907FA5E04480F0E925B2 +:1011A000E0000CC500000CC5104401907FA6F08D36 +:1011B00008AF03A9077509018A000CD500000CD5FA +:1011C0000D0A890BE4F50C750D03D322C322000030 +:1011D00000000CE210A907E50D7023907FA5E04404 +:1011E00080F0E925E0000CF200000CF210907FA6E0 +:1011F000F08D08AF03A9077509018A0A89000D025D +:1012000000000D020B0BE4F50C750D01D322C32277 +:1012100000000D0D10907FD6E054FBF0E04408F084 +:10122000300604E044000D1D00000D1D1002F07F8B +:10123000D07E07120DD5907FD6E054F7F0000D2D2B +:1012400000000D2D05E04404F022000000000D32E6 +:1012500010120CB5E50D24FA601014600724077015 +:10126000F3000D4200000D420F7F0822E4F50D7FD0 +:101270000722E4F50D7F062200000D5110120CE24A +:10128000E50D24FA6010146007240770F3000D6167 +:1012900000000D610F7F0822E4F50D7F0722E4F5C1 +:1012A0000D7F062200000D7010C0E0C083C0829048 +:1012B0007FC4E4F05391EF907F000D8000000D801B +:1012C0000BAB7404F0D082D083D0E03200000D8BE1 +:1012D00010907FD6E030E712E04401F07F147E00EA +:1012E00012000D9B00000D9B0A0DD5907FD6E05497 +:1012F000FEF0220000000DA510C0E0C083C082D225 +:10130000015391EF907FAB7401000DB500000DB556 +:1013100008F0D082D083D0E03200000000000DBD84 +:1013200010C0E0C083C082D2035391EF907FAB74B2 +:1013300008000DCD00000DCD08F0D082D083D0E0A4 +:101340003200000000000DD5108E398F3AE53A15B5 +:101350003AAE39700215394E60000DE500000DE51A +:101360000705120E4180EE2200000DEC10C0E0C017 +:1013700083C0825391EF907FAB7402F0D0000DFCDC +:1013800000000DFC0682D083D0E0320000000E0287 +:1013900010C0E0C083C0825391EF907FAB7410F017 +:1013A000D0000E1200000E120682D083D0E0320070 +:1013B00000000E1810AE077F217D0174002EF5820B +:1013C000E4340FAB82000E2800000E2805FA120D3F +:1013D0005122000000000E2D10500F00C0F9A4B0E3 +:1013E000999282F880988883C6000E3D00000E3DD9 +:1013F00003A1868E00000E400100000000000E4197 +:10140000107400F58690FDA57C05A3E582458370E8 +:10141000F9000E5100000E510122000000000E5292 +:101420000E907F00E50EF0907FB57401F0D322009E +:1014300000000E6008907FEAE0F50ED32200000065 +:1014400000000E6808E4F50DD2E9D2AF22000000DA +:1014500000000E700453D8EF3200000000000E743C +:1014600003D2002200000E7702D3220000000E7982 +:1014700002D3220000000E7B02D3220000000E7D6A +:1014800002D3220000000E7F02D3220000000E8152 +:1014900002D3220000000E830132000000000E84FF +:1014A0000132000000000E850132000000000E86AF +:1014B0000132000000000E870132000000000E889B +:1014C0000132000000000E890132000000000E8A87 +:1014D0000132000000000E8B0132000000000E8C73 +:1014E0000132000000000E8D0132000000000E8E5F +:1014F0000132000000000E8F0132000000000E904B +:101500000132000000000E910132000000000E9236 +:101510000132000000001100101201000100000063 +:1015200040470510270100010200111000001110B2 +:1015300010000109022000010103A00009040000BD +:10154000020011200000112010FF00000407058296 +:101550000240000007050202400011300000113077 +:1015600010000004030904260341006E00630068B4 +:101570000000114000001140106F00720020004375 +:1015800000680069007000730000115000001150E5 +:10159000102C00200049006E0063002E0028034636 +:1015A000000011600000116010690072006D00778A +:1015B00000610072006500200000117000001170D1 +:1015C000104600720061006D00650057006F0072E8 +:1015D0000000118000001180106B0073002A03438B +:1015E000006F006E0066006900001190000011900D +:1015F000106700750072006100740069006F006E72 +:10160000000011A0000011A010200053007400720F +:101610000069006E00670022030011B0000011B0E5 +:101620001049006E0074006500720066006100637E +:10163000000011C0000011C01065002000530074AC +:1016400000720069006E0067000011D0000011D028 +:091650000200000000000000008F +:00000001FF +/***************************************************************************** + * + * whiteheat.h -- ConnectTech WhiteHEAT Firmware. + * + * Copyright (C) 2000-2002 ConnectTech Inc (http://www.connecttech.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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * (10/09/2002) Stuart MacDonald + * Firmware 4.06 + * + * (04/09/2000) gkh + * Updated the firmware with the latest provided by ConnectTech. + * + * (01/16/2000) gkh + * Fixed my intel hex processing tool, so now the firmware actually + * matches the original file (this was causing a few problems...) + * + * (01/15/2000) gkh + * Added debug loader firmware if DEBUG is #defined: + * Port 1 LED flashes when the vend_ax program is running + * Port 2 LED flashes when any SETUP command arrives + * Port 3 LED flashes when any valid VENDOR request occurs + * Port 4 LED flashes when the EXTERNAL RAM DOWNLOAD request occurs + * + * version 1.0 (01/09/2000) gkh + * Original firmware from ConnectTech massaged a little to be program + * readable. + * + *****************************************************************************/ + +#define whiteheat_DATE "20000106" -- cgit v0.10.2 From 27d202fff1555f5b0eb16a5aedc452566f9ab8bb Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 5 Jun 2008 12:59:51 +0100 Subject: firmware: convert Ambassador ATM driver to request_firmware() Since it had various regions to be loaded to separate addresses, and it wanted to do them in fairly small chunks anyway, switch it to use the new ihex code. Encode the start address in the first record. Signed-off-by: David Woodhouse Acked-by: Chas Williams diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index e4fa996..749266e 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -6,9 +6,9 @@ fore_200e-objs := fore200e.o hostprogs-y := fore200e_mkfirm # Files generated that shall be removed upon make clean -clean-files := atmsar11.bin atmsar11.bin1 atmsar11.bin2 pca200e.bin \ - pca200e.bin1 pca200e.bin2 pca200e_ecd.bin pca200e_ecd.bin1 \ - pca200e_ecd.bin2 sba200e_ecd.bin sba200e_ecd.bin1 sba200e_ecd.bin2 +clean-files := pca200e.bin pca200e.bin1 pca200e.bin2 pca200e_ecd.bin \ + pca200e_ecd.bin1 pca200e_ecd.bin2 sba200e_ecd.bin sba200e_ecd.bin1 \ + sba200e_ecd.bin2 # Firmware generated that shall be removed upon make clean clean-files += fore200e_pca_fw.c fore200e_sba_fw.c diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 6adb72a..703364b 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include @@ -290,29 +292,6 @@ static inline void __init show_version (void) { */ -/********** microcode **********/ - -#ifdef AMB_NEW_MICROCODE -#define UCODE(x) UCODE2(atmsar12.x) -#else -#define UCODE(x) UCODE2(atmsar11.x) -#endif -#define UCODE2(x) #x - -static u32 __devinitdata ucode_start = -#include UCODE(start) -; - -static region __devinitdata ucode_regions[] = { -#include UCODE(regions) - { 0, 0 } -}; - -static u32 __devinitdata ucode_data[] = { -#include UCODE(data) - 0xdeadbeef -}; - static void do_housekeeping (unsigned long arg); /********** globals **********/ @@ -1841,45 +1820,34 @@ static int __devinit get_loader_version (loader_block * lb, /* loader: write memory data blocks */ -static int __devinit loader_write (loader_block * lb, - const amb_dev * dev, const u32 * data, - u32 address, unsigned int count) { - unsigned int i; +static int __devinit loader_write (loader_block* lb, + const amb_dev *dev, + const struct ihex_binrec *rec) { transfer_block * tb = &lb->payload.transfer; PRINTD (DBG_FLOW|DBG_LOAD, "loader_write"); - - if (count > MAX_TRANSFER_DATA) - return -EINVAL; - tb->address = cpu_to_be32 (address); - tb->count = cpu_to_be32 (count); - for (i = 0; i < count; ++i) - tb->data[i] = cpu_to_be32 (data[i]); + + tb->address = rec->addr; + tb->count = cpu_to_be32(be16_to_cpu(rec->len) / 4); + memcpy(tb->data, rec->data, be16_to_cpu(rec->len)); return do_loader_command (lb, dev, write_adapter_memory); } /* loader: verify memory data blocks */ static int __devinit loader_verify (loader_block * lb, - const amb_dev * dev, const u32 * data, - u32 address, unsigned int count) { - unsigned int i; + const amb_dev *dev, + const struct ihex_binrec *rec) { transfer_block * tb = &lb->payload.transfer; int res; PRINTD (DBG_FLOW|DBG_LOAD, "loader_verify"); - if (count > MAX_TRANSFER_DATA) - return -EINVAL; - tb->address = cpu_to_be32 (address); - tb->count = cpu_to_be32 (count); + tb->address = rec->addr; + tb->count = cpu_to_be32(be16_to_cpu(rec->len) / 4); res = do_loader_command (lb, dev, read_adapter_memory); - if (!res) - for (i = 0; i < count; ++i) - if (tb->data[i] != cpu_to_be32 (data[i])) { - res = -EINVAL; - break; - } + if (!res && memcmp(tb->data, rec->data, be16_to_cpu(rec->len))) + res = -EINVAL; return res; } @@ -1962,47 +1930,53 @@ static int amb_reset (amb_dev * dev, int diags) { /********** transfer and start the microcode **********/ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { - unsigned int i = 0; - unsigned int total = 0; - const u32 * pointer = ucode_data; - u32 address; - unsigned int count; + const struct firmware *fw; + unsigned long start_address; + const struct ihex_binrec *rec; int res; + res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); + if (res) { + PRINTK (KERN_ERR, "Cannot load microcode data"); + return res; + } + + /* First record contains just the start address */ + rec = (const struct ihex_binrec *)fw->data; + if (be16_to_cpu(rec->len) != sizeof(__be32) || be32_to_cpu(rec->addr)) { + PRINTK (KERN_ERR, "Bad microcode data (no start record)"); + return -EINVAL; + } + start_address = be32_to_cpup((__be32 *)rec->data); + + rec = ihex_next_binrec(rec); + PRINTD (DBG_FLOW|DBG_LOAD, "ucode_init"); - - while (address = ucode_regions[i].start, - count = ucode_regions[i].count) { - PRINTD (DBG_LOAD, "starting region (%x, %u)", address, count); - while (count) { - unsigned int words; - if (count <= MAX_TRANSFER_DATA) - words = count; - else - words = MAX_TRANSFER_DATA; - total += words; - res = loader_write (lb, dev, pointer, address, words); - if (res) - return res; - res = loader_verify (lb, dev, pointer, address, words); - if (res) - return res; - count -= words; - address += sizeof(u32) * words; - pointer += words; + + while (rec) { + PRINTD (DBG_LOAD, "starting region (%x, %u)", be32_to_cpu(rec->addr), + be16_to_cpu(rec->len)); + if (be16_to_cpu(rec->len) > 4 * MAX_TRANSFER_DATA) { + PRINTK (KERN_ERR, "Bad microcode data (record too long)"); + return -EINVAL; } - i += 1; - } - if (*pointer == ATM_POISON) { - return loader_start (lb, dev, ucode_start); - } else { - // cast needed as there is no %? for pointer differnces - PRINTD (DBG_LOAD|DBG_ERR, - "offset=%li, *pointer=%x, address=%x, total=%u", - (long) (pointer - ucode_data), *pointer, address, total); - PRINTK (KERN_ERR, "incorrect microcode data"); - return -ENOMEM; + if (be16_to_cpu(rec->len) & 3) { + PRINTK (KERN_ERR, "Bad microcode data (odd number of bytes)"); + return -EINVAL; + } + res = loader_write(lb, dev, rec); + if (res) + break; + + res = loader_verify(lb, dev, rec); + if (res) + break; } + release_firmware(fw); + if (!res) + res = loader_start(lb, dev, start_address); + + return res; } /********** give adapter parameters **********/ diff --git a/drivers/atm/ambassador.h b/drivers/atm/ambassador.h index df55fa8..bd1c46a 100644 --- a/drivers/atm/ambassador.h +++ b/drivers/atm/ambassador.h @@ -656,17 +656,6 @@ typedef struct amb_dev amb_dev; #define AMB_DEV(atm_dev) ((amb_dev *) (atm_dev)->dev_data) #define AMB_VCC(atm_vcc) ((amb_vcc *) (atm_vcc)->dev_data) -/* the microcode */ - -typedef struct { - u32 start; - unsigned int count; -} region; - -static region ucode_regions[]; -static u32 ucode_data[]; -static u32 ucode_start; - /* rate rounding */ typedef enum { diff --git a/drivers/atm/atmsar11.data b/drivers/atm/atmsar11.data deleted file mode 100644 index 5dc8a76..0000000 --- a/drivers/atm/atmsar11.data +++ /dev/null @@ -1,2063 +0,0 @@ -/* - Madge Ambassador ATM Adapter microcode. - Copyright (C) 1995-1999 Madge Networks Ltd. - - This microcode data is placed under the terms of the GNU General - Public License. The GPL is contained in /usr/doc/copyright/GPL on a - Debian system and in the file COPYING in the Linux kernel source. - - We would prefer you not to distribute modified versions without - consultation and not to ask for assembly/other microcode source. -*/ - - 0x401a6800, - 0x00000000, - 0x335b007c, - 0x13600005, - 0x335b1000, - 0x3c1aa0c0, - 0x375a0180, - 0x03400008, - 0x00000000, - 0x1760fffb, - 0x335b4000, - 0x401a7000, - 0x13600003, - 0x241b0fc0, - 0xaf9b4500, - 0x25080008, - 0x03400008, - 0x42000010, - 0x8f810c90, - 0x32220002, - 0x10400003, - 0x3c03a0d1, - 0x2463f810, - 0x0060f809, - 0x24210001, - 0x1000001a, - 0xaf810c90, - 0x82020011, - 0xaf900c48, - 0x0441000a, - 0x34420080, - 0x967d0002, - 0x96020012, - 0x00000000, - 0x105d0011, - 0x00000000, - 0x04110161, - 0xa6620002, - 0x1000000d, - 0xae62000c, - 0x34848000, - 0xa2020011, - 0x4d01ffff, - 0x00000000, - 0x8f834c00, - 0x00000000, - 0xaf830fec, - 0x00e0f809, - 0x03e03821, - 0x00041400, - 0x0440fff7, - 0x00000000, - 0xaf80460c, - 0x8e100008, - 0x4d01ffff, - 0x00000000, - 0x8f834c00, - 0x4900001d, - 0xaf830fec, - 0x8f820cbc, - 0x8f9d0c4c, - 0x24420001, - 0x97be0000, - 0xaf820cbc, - 0x13c00009, - 0xaca200d8, - 0xa7a00000, - 0x3c0100d1, - 0x003e0825, - 0x9422002c, - 0x0411013f, - 0xa4220002, - 0xac22000c, - 0xac200010, - 0x8f9e0c54, - 0x27bd0002, - 0x17be0002, - 0x8ca200c0, - 0x8f9d0c50, - 0x8f970fc8, - 0xaf9d0c4c, - 0x12e20005, - 0x87804002, - 0x3c02a0d1, - 0x2442f94c, - 0x0040f809, - 0x00000000, - 0x00e0f809, - 0x03e03821, - 0x4500ffdc, - 0x8e11000c, - 0x3c1300d1, - 0x00111102, - 0x2c430400, - 0x1060ffb9, - 0x00021180, - 0x02629821, - 0x8e76003c, - 0x32220008, - 0x1440ffb7, - 0x8e770034, - 0x8e750030, - 0x3c03cfb0, - 0x16c00003, - 0x02d5102b, - 0x041100be, - 0x00000000, - 0x1040ffa6, - 0x00701826, - 0x4d01ffff, - 0x00000000, - 0x8f824c00, - 0xaf974c00, - 0xaf820fec, - 0xac760010, - 0x02609021, - 0x32220002, - 0x10400007, - 0x8f944a00, - 0x9602003a, - 0x34840004, - 0x14400003, - 0xaf820fbc, - 0x3c029000, - 0xaf820fbc, - 0x8e100008, - 0x32943f00, - 0x8e11000c, - 0x2694ff00, - 0x12800073, - 0x3c1300d1, - 0x49010071, - 0x32370008, - 0x16e0006f, - 0x00111102, - 0x2c430400, - 0x1060006c, - 0x0002b980, - 0x00041740, - 0x0440003a, - 0x02779821, - 0x12720023, - 0x26d60030, - 0xae56003c, - 0x8e76003c, - 0x8e770034, - 0x8e750030, - 0x3c03cfb0, - 0x16c00003, - 0x02d5102b, - 0x04110091, - 0x00000000, - 0x10400060, - 0x2e821000, - 0x14400009, - 0x00701826, - 0x4d01ffff, - 0x00000000, - 0x8f824c00, - 0xaf974c00, - 0xac760010, - 0xae420034, - 0x1000ffd0, - 0xaf80460c, - 0x00e0f809, - 0x03e03821, - 0x3c03cfb0, - 0x00701826, - 0xae460034, - 0x4d01ffff, - 0x00000000, - 0x8f824c00, - 0xaf974c00, - 0xaf820fec, - 0xac760010, - 0x1000ffc3, - 0xaf80460c, - 0x02d5102b, - 0x10400042, - 0x3c17cfb0, - 0x2e821000, - 0x14400006, - 0x02f0b826, - 0x4d01ffff, - 0x00000000, - 0xaef60010, - 0x1000ffb8, - 0xaf80460c, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0x8f824c00, - 0xaf864c00, - 0xaef60010, - 0xaf820fec, - 0x1000ffae, - 0xaf80460c, - 0x3084fffb, - 0x8e570038, - 0x3242ffc0, - 0x00021182, - 0xa7820fb8, - 0xaf970fb4, - 0x865d002a, - 0x865e0008, - 0xa79d0fba, - 0x279d0f18, - 0x33de0060, - 0x03bee821, - 0x001ef0c2, - 0x03bee821, - 0x8f970c58, - 0x4d01ffff, - 0x00000000, - 0x8f834c00, - 0x8fa2001c, - 0x12e30003, - 0x3c030c40, - 0x3c1ec000, - 0xaf9e0fbc, - 0xac620fb4, - 0x8fa30018, - 0x2442000c, - 0x14430002, - 0xaf80460c, - 0x8fa20014, - 0xae40003c, - 0xafa2001c, - 0x8e76003c, - 0x8e770034, - 0x8e750030, - 0x3c03cfb0, - 0x16c00003, - 0x02d5102b, - 0x0411003c, - 0x00000000, - 0x00701826, - 0x4d01ffff, - 0x00000000, - 0xaca500e4, - 0x10400032, - 0xaf974c00, - 0x1000ff7f, - 0xac760010, - 0x00041740, - 0x04400007, - 0x26d60030, - 0xae56003c, - 0x00e0f809, - 0x03e03821, - 0xaf80460c, - 0x1000ff39, - 0xae460034, - 0x8e570038, - 0x3242ffc0, - 0x00021182, - 0xa7820fb8, - 0xaf970fb4, - 0x8f970c58, - 0x00e0f809, - 0x03e03821, - 0x12e60003, - 0x3c030c40, - 0x3c02c000, - 0xaf820fbc, - 0x865d002a, - 0x865e0008, - 0xa79d0fba, - 0x279d0f18, - 0x33de0060, - 0x03bee821, - 0x001ef0c2, - 0x03bee821, - 0x8fa2001c, - 0x4d01ffff, - 0x00000000, - 0x8f974c00, - 0xac620fb4, - 0x3084fffb, - 0x8fa30018, - 0x2442000c, - 0x14430002, - 0xaf80460c, - 0x8fa20014, - 0xae40003c, - 0xafa2001c, - 0x4d01ffff, - 0x00000000, - 0xaca500e4, - 0x1000ff13, - 0xaf974c00, - 0x00e0f809, - 0x03e03821, - 0x1000ff0f, - 0x00000000, - 0x1040005b, - 0x867e0008, - 0x279d0f18, - 0x33de0060, - 0x03bee821, - 0x001e10c2, - 0x03a2e821, - 0x8fb70008, - 0x8fa2000c, - 0x8ef60004, - 0x12e20028, - 0x86620008, - 0x82030010, - 0x00021740, - 0x04410019, - 0x24630001, - 0x10600017, - 0x3c02d1b0, - 0x00501026, - 0x4d01ffff, - 0x00000000, - 0x8f9e4c00, - 0xac560010, - 0x26d6fffe, - 0x86020010, - 0x3c03cfb0, - 0x34632000, - 0xa662002a, - 0x8ee20000, - 0x26f70008, - 0xae620038, - 0x8fa20020, - 0xafb70008, - 0x2417ffff, - 0x02c2a821, - 0x4d01ffff, - 0x00000000, - 0xaf9e4c00, - 0x03e00008, - 0xae750030, - 0x8ee20000, - 0x26f70008, - 0xae620038, - 0x8fa20020, - 0xafb70008, - 0x2417ffff, - 0xa677002a, - 0x02c2a821, - 0x3c03cfb0, - 0x03e00008, - 0xae750030, - 0x001e18c2, - 0x00651821, - 0x8c6300c8, - 0x8fa20010, - 0x00000000, - 0x0062b023, - 0x1ec00003, - 0x8fa10004, - 0x12c0001b, - 0x0022b023, - 0x2ec30041, - 0x14600002, - 0x3c150040, - 0x24160040, - 0x00161e80, - 0x00031882, - 0x00751825, - 0x4d01ffff, - 0x00000000, - 0x8f954c00, - 0x001eb840, - 0x00771821, - 0xac624d00, - 0x00561021, - 0x14410002, - 0x27830d00, - 0x8fa20000, - 0x02e3b821, - 0xafa20010, - 0x02d71821, - 0xafa3000c, - 0x4d01ffff, - 0x00000000, - 0x8ef60004, - 0x1000ffb5, - 0xaf954c00, - 0x3c16dead, - 0xae76003c, - 0xae600038, - 0x26d5ffff, - 0x00001021, - 0x03e00008, - 0xae750030, - 0x2c430ab2, - 0x10600005, - 0x2c4324b2, - 0x10000004, - 0x24020ab2, - 0x10000002, - 0x240224b1, - 0x1060fffd, - 0x304301ff, - 0x00031840, - 0x3c1da0d1, - 0x27bdd6cc, - 0x007d1821, - 0x94630000, - 0x0002ea42, - 0x00031c00, - 0x27bdfffb, - 0x03e00008, - 0x03a31006, - 0x24030fc0, - 0xaf834500, - 0x10000002, - 0x01206021, - 0x3c0ccfb0, - 0x11e00056, - 0x01896026, - 0x85fe0000, - 0x00000000, - 0x13c00047, - 0x3c02cfb0, - 0x07c0002d, - 0x001e1f80, - 0x04610034, - 0x001e1fc0, - 0x04600009, - 0x3c02d3b0, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0x8f864c00, - 0x8f990fec, - 0x1000000b, - 0xaf994c00, - 0x01e27826, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0x8f864c00, - 0xaf994c00, - 0xadef2010, - 0x3c02d3b0, - 0x01e27826, - 0x8f820fc0, - 0x8f830fc4, - 0xaf824d00, - 0x8de20004, - 0xa5e00000, - 0xac620000, - 0x8c620000, - 0x24020380, - 0xaf824d00, - 0x8f824d00, - 0x8f820f14, - 0x24630004, - 0x14620002, - 0x2419ffff, - 0x8f830f10, - 0xaca500e4, - 0xaf830fc4, - 0x4d01ffff, - 0x00000000, - 0x8f824c80, - 0x1000001f, - 0xade2003c, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0xa5e00000, - 0x8f864c00, - 0x15800022, - 0xaf8f4540, - 0x10000017, - 0x01e27826, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0x8f864c00, - 0xaf994c00, - 0xadef2010, - 0x3c02cfb0, - 0x01e27826, - 0xa5e00000, - 0x4d01ffff, - 0x00000000, - 0x10000007, - 0x8f994c00, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0x8f864c00, - 0x8f990fec, - 0x1580000a, - 0xaf8f4500, - 0x00007821, - 0x10000014, - 0xaf190014, - 0x00e0f809, - 0x03e03821, - 0x4d01ffff, - 0x00000000, - 0x1180fff8, - 0x8f864c00, - 0x85220000, - 0x01207821, - 0x0440000a, - 0x8d290008, - 0x130b0004, - 0x000c1602, - 0xaf190014, - 0x8d790014, - 0x0160c021, - 0xaf994c00, - 0xad8e4010, - 0x3042003f, - 0x01c27021, - 0x00041780, - 0x0440018b, - 0x8f824a00, - 0x30818000, - 0x30420004, - 0x1440ff8d, - 0x8d4b0000, - 0x1020000c, - 0x30847fff, - 0x8f820c48, - 0x0120f021, - 0x24430034, - 0x8c5d000c, - 0x24420004, - 0xafdd000c, - 0x1462fffc, - 0x27de0004, - 0xa5210000, - 0x1000ff82, - 0x25080008, - 0x11600058, - 0x00000000, - 0x857d0008, - 0x8d63000c, - 0x9562000a, - 0x8d410004, - 0x07a10026, - 0x00621821, - 0xa563000a, - 0x00031c02, - 0x041101a0, - 0x000318c0, - 0x001d16c0, - 0x0441001f, - 0x27a20080, - 0x00021cc0, - 0x0461000e, - 0x0040e821, - 0x27bd0080, - 0x95620000, - 0x95630002, - 0x3442000c, - 0xad22000c, - 0x24020100, - 0xa5220010, - 0x9562002c, - 0xa5230014, - 0xa5220012, - 0xa5200016, - 0x34028000, - 0xa5220000, - 0xa57d0008, - 0x07a0000c, - 0x8f820c4c, - 0x8f830c50, - 0x2441ffe8, - 0x0023f02b, - 0x13c00002, - 0x00201021, - 0x24420400, - 0x945e0000, - 0x2441fffe, - 0x17c0fff9, - 0xad620010, - 0xa44b0000, - 0x142b001c, - 0xad400000, - 0xad400004, - 0x254a0008, - 0x3142007f, - 0x1440000e, - 0x00041780, - 0x04410003, - 0x8f820fe0, - 0x10000006, - 0x34840001, - 0x34840002, - 0x24420008, - 0x34421000, - 0x38421000, - 0xaf820fe0, - 0x354a0100, - 0x394a0100, - 0x39420080, - 0xaf820fe4, - 0x001d14c0, - 0x04410003, - 0x33a2efff, - 0x1000ff3c, - 0xa5620008, - 0x07a0009f, - 0x33a2fffe, - 0x10000021, - 0xa5620008, - 0x8d620024, - 0x001d1cc0, - 0x04610004, - 0xad420000, - 0x33a3efff, - 0x1000ff31, - 0xa5630008, - 0x07a00005, - 0x33a3fffe, - 0xa5630008, - 0x8d4b0000, - 0x1000ffaa, - 0x00000000, - 0x1000008e, - 0x25080008, - 0x254a0008, - 0x3142007f, - 0x1440000e, - 0x00041780, - 0x04410003, - 0x8f820fe0, - 0x10000006, - 0x34840001, - 0x34840002, - 0x24420008, - 0x34421000, - 0x38421000, - 0xaf820fe0, - 0x354a0100, - 0x394a0100, - 0x39420080, - 0xaf820fe4, - 0x11000003, - 0x8d4b0000, - 0x1000ff93, - 0x2508fff8, - 0x8f820fd8, - 0x8f830fdc, - 0x8f810fd4, - 0x1062001d, - 0x24620008, - 0x4d01ffff, - 0x00000000, - 0x8f8c4c00, - 0x847f0000, - 0x3c1e00d1, - 0x33fd03ff, - 0x001d5980, - 0x017e5821, - 0x857e0008, - 0x001de900, - 0x001e0f00, - 0x03e1f825, - 0x07e00003, - 0xaf820fdc, - 0x879e0ca0, - 0x278b0c98, - 0x07c10042, - 0x3c020840, - 0x3c01f7b0, - 0x8d620020, - 0x00230826, - 0xac220000, - 0x8c620004, - 0x94630002, - 0x2442fff8, - 0x00431021, - 0x1000004e, - 0xad620020, - 0x8f820fd0, - 0x87830ca0, - 0x14220007, - 0x278b0c98, - 0x41000051, - 0x3c018000, - 0xaca100e0, - 0x8ca100c4, - 0x00000000, - 0x1022004c, - 0x0022e823, - 0x8f9f0f0c, - 0x07a10002, - 0xaf810fd4, - 0x03e2e823, - 0x2fa30041, - 0x14600002, - 0x3c1e0040, - 0x241d0040, - 0x001d1e80, - 0x00031882, - 0x007e1825, - 0x4d01ffff, - 0x00000000, - 0x8f8c4c00, - 0xac624cc0, - 0x005d1021, - 0x145f0002, - 0x27830cc0, - 0x8f820f08, - 0x03a3f021, - 0xaf820fd0, - 0xaf9e0fd8, - 0x4d01ffff, - 0x00000000, - 0x1000ffc3, - 0x24620008, - 0x8d63000c, - 0x8d7d0010, - 0xa563000a, - 0x13a00002, - 0x00031c02, - 0xa7a00000, - 0x000318c0, - 0x041100ef, - 0x00681821, - 0x4d01ffff, - 0x00000000, - 0x8f820c44, - 0x8f830c40, - 0xad620010, - 0xa5630004, - 0xa5630006, - 0x10000021, - 0xaf8c4c00, - 0xa57d0000, - 0x8c7d0004, - 0x94630002, - 0xac5d4c40, - 0x27a20008, - 0xad620018, - 0x03a3e821, - 0x27bdfff4, - 0xad7d001c, - 0x27bd0004, - 0xad7d0020, - 0x37c18001, - 0x001e17c0, - 0x0441ffe0, - 0xa5610008, - 0x4d01ffff, - 0x00000000, - 0x8f820c44, - 0x8f830c40, - 0xad620010, - 0xa5630004, - 0xa5630006, - 0x8f820fd8, - 0x8f830fdc, - 0x4d01ffff, - 0x00000000, - 0x1462ff95, - 0x24620008, - 0xaf8c4c00, - 0x87830ca0, - 0x278b0c98, - 0x0461fe97, - 0x00041700, - 0x04400005, - 0x95620000, - 0x11780006, - 0x00000000, - 0xaf0e0010, - 0xa70d0004, - 0x3084fff7, - 0x956d0004, - 0x8d6e0010, - 0x25adffd0, - 0x05a1fe8f, - 0xad22000c, - 0x3c0cffb0, - 0x01896026, - 0x000d1822, - 0x25ad0030, - 0x8d7e0018, - 0x8d61001c, - 0x4d01ffff, - 0x00000000, - 0x103e0036, - 0x8f9d4c00, - 0x3c010840, - 0xac3e4c40, - 0x27de0008, - 0x11a00017, - 0xad7e0018, - 0x000df600, - 0x019e6025, - 0x4d01ffff, - 0x00000000, - 0xad8e4010, - 0x8f8d0c40, - 0x957e0006, - 0x8f8e0c44, - 0x03cdf021, - 0xa57e0006, - 0x000cf782, - 0x000c0e02, - 0x03c1f021, - 0x001e0f80, - 0x000c6200, - 0x000c6202, - 0x01816025, - 0x33de003c, - 0x019e6021, - 0x34010001, - 0x10000008, - 0xa5210000, - 0x957e0006, - 0x4d01ffff, - 0x00000000, - 0x8f8d0c40, - 0x8f8e0c44, - 0x03cdf021, - 0xa57e0006, - 0x4d01ffff, - 0x00000000, - 0x01a3f02b, - 0x17c00008, - 0x0003f600, - 0x01a36823, - 0x019e6025, - 0x01896026, - 0x4d01fff7, - 0x00000000, - 0x1000fe58, - 0xaf9d4c00, - 0x8d7e0018, - 0x8d61001c, - 0x00000000, - 0x143effce, - 0x006d1823, - 0x4d01ffff, - 0x00000000, - 0x2c610008, - 0x10200017, - 0x95610008, - 0x00000000, - 0x0001ff80, - 0x07e0000b, - 0x34210002, - 0x006d1821, - 0x00031e00, - 0x01836025, - 0x01896026, - 0x240d002c, - 0xa5610008, - 0x4d01ffff, - 0x00000000, - 0x1000fe40, - 0xaf9d4c00, - 0x3c1f0c40, - 0xaffe4fa8, - 0x3021fffd, - 0xa5610008, - 0x3c0cd3cf, - 0x358ce000, - 0x10000008, - 0x34030002, - 0x3c1f0c40, - 0xaffe4fa8, - 0x11a0fff9, - 0x000df600, - 0x34030003, - 0x019e6025, - 0x01896026, - 0x34840008, - 0x34420002, - 0xad22000c, - 0x95620006, - 0xa5230000, - 0xad220038, - 0x4d01ffff, - 0x00000000, - 0x857e0008, - 0x8f820fa8, - 0x97830fac, - 0xad220004, - 0x33c17fff, - 0xad600010, - 0xa5610008, - 0x1060fe20, - 0xaf9d4c00, - 0xa57e0008, - 0x00031900, - 0x30633ff0, - 0xa5630000, - 0x8f820fb0, - 0x3c030840, - 0xac624c40, - 0x24430008, - 0xad630018, - 0x97830fae, - 0x2442fff4, - 0x00621821, - 0xad63001c, - 0x4d01ffff, - 0x00000000, - 0x8f8d0c40, - 0x8f830c44, - 0xa56d0004, - 0xa56d0006, - 0xad630010, - 0x1000fe0a, - 0xaf9d4c00, - 0x8f820fe0, - 0x00040fc0, - 0x8c430000, - 0x0421001b, - 0x8f9f0fe4, - 0x8c5d0004, - 0xac400004, - 0x1060000e, - 0xac400000, - 0x00000000, - 0x94620028, - 0x00000000, - 0x005f1020, - 0x8c410004, - 0x00000000, - 0x10200003, - 0xac430004, - 0x10000002, - 0xac230024, - 0xac430000, - 0x17a3fff4, - 0x8c630024, - 0x8f820fe0, - 0x3bff0080, - 0x24420008, - 0x34421000, - 0x38421000, - 0xaf820fe0, - 0xaf9f0fe4, - 0x1000fe57, - 0x3084fffe, - 0x10600010, - 0x00000000, - 0x947d0028, - 0x00000000, - 0x03bfe820, - 0x8fa10004, - 0xafa30004, - 0x10200003, - 0x8c5e0004, - 0x10000002, - 0xac230024, - 0xafa30000, - 0x8c610024, - 0x17c3fe48, - 0xac410000, - 0xac400004, - 0xac400000, - 0x1000fe44, - 0x3084fffd, - 0x2c620100, - 0x1440000e, - 0x006a1021, - 0x3143007f, - 0x01431823, - 0x00431823, - 0x3062007f, - 0xa5620028, - 0x00621823, - 0x00031902, - 0x8f820fe0, - 0x2463fff8, - 0x00621821, - 0x34631000, - 0x10000003, - 0x38631000, - 0x34430100, - 0x38630100, - 0x8c620004, - 0x00000000, - 0x10400003, - 0xac6b0004, - 0x03e00008, - 0xac4b0024, - 0x03e00008, - 0xac6b0000, - 0x00000002, - 0xa0d0e000, - 0x00000000, - 0x00001000, - 0x00000006, - 0x00000008, - 0x00000000, - 0x00000008, - 0x00000002, - 0xa0d0d648, - 0x00000000, - 0x00000888, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x24313200, - 0x24313200, - 0x24313200, - 0x00000000, - 0x244d4352, - 0x2420436f, - 0x70797269, - 0x67687420, - 0x28632920, - 0x4d616467, - 0x65204e65, - 0x74776f72, - 0x6b73204c, - 0x74642031, - 0x3939352e, - 0x20416c6c, - 0x20726967, - 0x68747320, - 0x72657365, - 0x72766564, - 0x2e004d61, - 0x64676520, - 0x416d6261, - 0x73736164, - 0x6f722076, - 0x312e3031, - 0x00000000, - 0x00000001, - 0x00000001, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xfff04000, - 0x00000000, - 0x0c343e2d, - 0x00000000, - 0x3c1ca0d1, - 0x279c5638, - 0x3c1da0d1, - 0x27bddfd0, - 0x3c08a0d1, - 0x2508dfd0, - 0xaf878008, - 0x0c343c13, - 0x00000000, - 0x24040003, - 0x0097000d, - 0x3c08bfc0, - 0x35080230, - 0x8d080000, - 0x00000000, - 0x01000008, - 0x00000000, - 0x27bdffd0, - 0xafbf001c, - 0xafb10018, - 0xafb00014, - 0x3c11fff0, - 0x00008021, - 0x3c180056, - 0x37183b79, - 0x26190200, - 0x17200002, - 0x0319001a, - 0x0007000d, - 0x2401ffff, - 0x17210005, - 0x00000000, - 0x3c018000, - 0x17010002, - 0x00000000, - 0x0006000d, - 0x00001012, - 0x00101840, - 0x3c05a0d1, - 0x24a5d6cc, - 0x00a32021, - 0xa4820000, - 0x26100001, - 0x2a010200, - 0x1420ffea, - 0x00000000, - 0x3c06a0d1, - 0x24c6f9e4, - 0x3c07a0d1, - 0x24e7d648, - 0xace60000, - 0x3c08a0d1, - 0x2508fb14, - 0xace80004, - 0x3c09a0d1, - 0x2529fc94, - 0xace90008, - 0x3c0aa0d1, - 0x254afcd4, - 0xacea000c, - 0x3c0ba0d1, - 0x256bfba8, - 0xaceb0010, - 0x3c0ca0d1, - 0x258cfbc4, - 0xacec0014, - 0x3c0da0d1, - 0x25adfbe0, - 0xaced0018, - 0x3c0ea0d1, - 0x25cefbfc, - 0xacee001c, - 0x3c0fa0d1, - 0x25effc18, - 0xacef0020, - 0x3c18a0d1, - 0x2718fc34, - 0xacf80024, - 0x3c19a0d1, - 0x2739fc50, - 0xacf90028, - 0x3c02a0d1, - 0x2442fc60, - 0xace2002c, - 0x3c03a0d1, - 0x2463fc70, - 0xace30030, - 0x3c04a0d1, - 0x2484fc80, - 0xace40034, - 0x3c05a0d1, - 0x24a5fcb4, - 0xace50038, - 0x3c06a0d1, - 0x24c6fe08, - 0xace6003c, - 0x3c08a0d1, - 0x2508fe90, - 0xace80040, - 0x3c09a0d1, - 0x2529fa38, - 0xace90044, - 0x3c0aa0d1, - 0x254afa74, - 0xacea0048, - 0x24100013, - 0x3c0ba0d1, - 0x256bf9d8, - 0x00106080, - 0x3c0ea0d1, - 0x25ced648, - 0x01cc6821, - 0xadab0000, - 0x26100001, - 0x2a010020, - 0x1420fff6, - 0x00000000, - 0x8f988000, - 0x00000000, - 0xaf000100, - 0x8f828000, - 0x241903ff, - 0xa4590202, - 0x00008021, - 0x8f868000, - 0x24030fff, - 0x00102040, - 0x24c70380, - 0x00e42821, - 0xa4a30000, - 0x26100001, - 0x2a010008, - 0x1420fff7, - 0x00000000, - 0x8f898000, - 0x34089c40, - 0xad2803a0, - 0x8f8b8000, - 0x3c0a00ff, - 0x354affff, - 0xad6a03a4, - 0x00008021, - 0x8f8f8000, - 0x240c0fff, - 0x00106840, - 0x25f80300, - 0x030d7021, - 0xa5cc0000, - 0x26100001, - 0x2a010008, - 0x1420fff7, - 0x00000000, - 0x8f828000, - 0x34199c40, - 0xac590320, - 0x8f848000, - 0x3c0300ff, - 0x3463ffff, - 0xac830324, - 0x8f868000, - 0x240502ff, - 0xa4c50202, - 0x3c08a0c0, - 0x35080180, - 0x3c09a0d1, - 0x2529d5b8, - 0x250a0028, - 0x8d0b0000, - 0x8d0c0004, - 0xad2b0000, - 0xad2c0004, - 0x25080008, - 0x150afffa, - 0x25290008, - 0x40026000, - 0x00000000, - 0xafa20028, - 0x24030022, - 0x3c04a0e0, - 0x34840014, - 0xac830000, - 0x8fa50028, - 0x00000000, - 0x34a61001, - 0x00c01021, - 0xafa60028, - 0x3c07ffbf, - 0x34e7ffff, - 0x00c73824, - 0x00e01021, - 0xafa70028, - 0x40876000, - 0x00000000, - 0x3c080002, - 0x3508d890, - 0x3c09fffe, - 0x35290130, - 0xad280000, - 0x8faa0028, - 0x3c0bf000, - 0x014b5825, - 0x01601021, - 0xafab0028, - 0x01606021, - 0x408c6000, - 0x00000000, - 0x00008021, - 0x00107080, - 0x022e7821, - 0xade00000, - 0x26100001, - 0x2a010400, - 0x1420fffa, - 0x00000000, - 0x24180001, - 0x3c19a0e8, - 0xaf380000, - 0x24020011, - 0x3c03a0f0, - 0x34630017, - 0xa0620000, - 0x3c04f0eb, - 0x34840070, - 0x3c05fff0, - 0x34a54a00, - 0xaca40000, - 0x3c06fceb, - 0x34c60070, - 0xaca60000, - 0x3c07fff0, - 0x34e74700, - 0xace00000, - 0x00008021, - 0x3c08fff0, - 0x35080fc0, - 0x3c09fff0, - 0x35294500, - 0xad280000, - 0x26100001, - 0x2a010004, - 0x1420fff8, - 0x00000000, - 0x00008021, - 0x3c0adead, - 0x00105980, - 0x3c0100d1, - 0x002b0821, - 0xac2a003c, - 0x3c0100d1, - 0x002b0821, - 0xac200030, - 0x3c0100d1, - 0x002b0821, - 0xac200038, - 0x240dffff, - 0x3c0100d1, - 0x002b0821, - 0xac2d0014, - 0x00107100, - 0x3c0100d1, - 0x002b0821, - 0xa42e0000, - 0x3c0100d1, - 0x002b0821, - 0xa4200004, - 0x24180020, - 0x3c0100d1, - 0x002b0821, - 0xa4380008, - 0x3c0100d1, - 0x002b0821, - 0xac200010, - 0x26100001, - 0x2a010400, - 0x1420ffe0, - 0x00000000, - 0x00008021, - 0x001018c0, - 0x3c05a0d1, - 0x24a5e000, - 0x00a32021, - 0xac800000, - 0x3c07a0d1, - 0x24e7e000, - 0x24e80004, - 0x01033021, - 0xacc00000, - 0x26100001, - 0x2a010009, - 0x1420fff3, - 0x00000000, - 0x24090380, - 0x3c0afff0, - 0x354a4d00, - 0xad490000, - 0x3c0ca080, - 0x358c009c, - 0xad800000, - 0x3c0da080, - 0x35ad00a0, - 0xada00000, - 0x3c0e1100, - 0x3c0fa080, - 0x35ef00a8, - 0xadee0000, - 0x41010003, - 0x00000000, - 0x4100ffff, - 0x00000000, - 0x3c18a080, - 0x371800e0, - 0x8f190000, - 0x3c01a0d1, - 0xac39d6c8, - 0x0c343d43, - 0x03202021, - 0x8fb00014, - 0x8fbf001c, - 0x8fb10018, - 0x03e00008, - 0x27bd0030, - 0x0080b821, - 0x3c1cfff0, - 0xa3800c84, - 0xa3800c88, - 0x8f904400, - 0x00002021, - 0xaf800cbc, - 0x240200a8, - 0x27830f00, - 0x2c5d0040, - 0x17a0000c, - 0x3c1dffb0, - 0x03a3e826, - 0xafb74000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4d01ffff, - 0x00000000, - 0x2442ffc0, - 0x24630040, - 0x1000fff3, - 0x26f70040, - 0x1040000d, - 0x00000000, - 0x0002ee00, - 0x3c010040, - 0x03a1e825, - 0x3c01fff0, - 0x03a1e826, - 0x03a3e826, - 0xafb74000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4d01ffff, - 0x00000000, - 0x3c05a080, - 0x8f820f08, - 0x00000000, - 0xaf820fd4, - 0xaf820fd0, - 0xaca200c4, - 0x8f820f10, - 0x00000000, - 0x00021d82, - 0xaf830fc0, - 0x00031d80, - 0x00431023, - 0x3c01a080, - 0x00411025, - 0xaf820fc4, - 0xaf820f10, - 0x8f820f14, - 0x00000000, - 0x00431023, - 0x3c01a080, - 0x00411025, - 0xaf820f14, - 0x24030003, - 0x279d0f18, - 0x24be00c8, - 0x27810d00, - 0x8fa20000, - 0x00000000, - 0xafa20010, - 0xafc20000, - 0xafa10008, - 0xafa1000c, - 0x8fa20014, - 0x00000000, - 0xafa2001c, - 0x27bd0024, - 0x27de0004, - 0x24210040, - 0x1460fff3, - 0x2463ffff, - 0x8f820f00, - 0x00000000, - 0xaf820fc8, - 0xaca200c0, - 0x27820800, - 0x2403000f, - 0xac400000, - 0x24420004, - 0x1460fffd, - 0x2463ffff, - 0x8f830fc0, - 0x00000000, - 0xaf834d00, - 0x8f834d00, - 0x8f830f14, - 0x8f820f10, - 0x2463fffc, - 0xac400000, - 0x1443fffe, - 0x24420004, - 0x24020380, - 0xaf824d00, - 0x279d0f18, - 0x27a10090, - 0x8fa20014, - 0x8fa30018, - 0x00000000, - 0x00621823, - 0x2c7f0040, - 0x17e00009, - 0x3c1f0040, - 0x37ff0800, - 0x03a0f021, - 0x4d01ffff, - 0x00000000, - 0xafe20000, - 0x24420040, - 0x1000fff6, - 0x2463ffc0, - 0x10600006, - 0x37ff0800, - 0x00031e00, - 0x03e3f825, - 0x4d01ffff, - 0x00000000, - 0xafe20000, - 0x27bd0024, - 0x17a1ffe8, - 0x00000000, - 0x00003821, - 0x8fc20014, - 0x8fc30018, - 0x00000000, - 0x00621823, - 0x2c7f0040, - 0x13e00004, - 0x3c1f0040, - 0x00030e00, - 0x10000002, - 0x03e1f825, - 0x24030040, - 0x37ff0800, - 0x241e03e7, - 0x00000821, - 0x4d01ffff, - 0x00000000, - 0xafe20000, - 0x00230821, - 0x4900fffb, - 0x00000000, - 0x87804002, - 0x17c0fff8, - 0x27deffff, - 0x14e00004, - 0x34e74000, - 0x03e7f825, - 0x1000fff0, - 0xaf810c60, - 0xaf810c5c, - 0x3c01a0d1, - 0x8c22d6c8, - 0x00000000, - 0x3c01a080, - 0xac2200e0, - 0x3c01a080, - 0x8c2000e0, - 0xaf800fb4, - 0xa7800fb8, - 0xa7800fba, - 0xa7800fbc, - 0xa7800fbe, - 0x27820cc0, - 0xaf820fdc, - 0xaf820fd8, - 0x3c02a0d1, - 0x2442dacc, - 0xaf820c4c, - 0xaf820c50, - 0x24420400, - 0xaf820c54, - 0x2402001e, - 0x3c03fff0, - 0x247d0040, - 0xac7d0008, - 0x03a01821, - 0x1440fffc, - 0x2442ffff, - 0x3c1dfff0, - 0xac7d0008, - 0x3c02c704, - 0x3442dd7b, - 0xaf820c58, - 0x3c070000, - 0x24e70158, - 0x08343fa9, - 0x00000000, - 0x8e620038, - 0x00000000, - 0x14400005, - 0x8f830c94, - 0x12a00022, - 0x24630001, - 0x10000020, - 0xaf830c94, - 0xaf820fb4, - 0x3262ffc0, - 0x00021182, - 0x8663002a, - 0xa7820fb8, - 0x3c02a000, - 0xaf820fbc, - 0xa7830fba, - 0x867e0008, - 0x279d0f18, - 0x33de0060, - 0x03bee821, - 0x001ef0c2, - 0x03bee821, - 0x8fa2001c, - 0x3c030c40, - 0x4d01ffff, - 0x00000000, - 0x8f974c00, - 0xac620fb4, - 0x8fa30018, - 0x2442000c, - 0x14430003, - 0x00000000, - 0x8fa20014, - 0x00000000, - 0xafa2001c, - 0x4d01ffff, - 0x00000000, - 0xaca500e4, - 0xaf974c00, - 0x03e00008, - 0xae60003c, - 0x3c0da0d1, - 0x25add500, - 0x11a00021, - 0x00000000, - 0x8da90000, - 0x00000000, - 0x1120001d, - 0x00000000, - 0x8daa0004, - 0x8dab0008, - 0x8dac000c, - 0x00094740, - 0x05010004, - 0x00000000, - 0x3c08a0d1, - 0x2508d638, - 0x01485021, - 0x00094780, - 0x05010007, - 0x00000000, - 0x1180000d, - 0x00000000, - 0xad400000, - 0x254a0004, - 0x1000fffb, - 0x258cfffc, - 0x11800007, - 0x00000000, - 0x8d6e0000, - 0x256b0004, - 0xad4e0000, - 0x254a0004, - 0x1000fff9, - 0x258cfffc, - 0x1000ffe1, - 0x25ad0010, - 0x03e00008, - 0x00000000, - 0x3c021040, - 0xac574ff0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4d01ffff, - 0x00000000, - 0x8f820ffc, - 0x00000000, - 0x3042001f, - 0x00021080, - 0x3c17a0d1, - 0x02e2b821, - 0x26f7d648, - 0x8ef70000, - 0x00000000, - 0x02e00008, - 0x00000000, - 0x2402ffff, - 0xaf820ffc, - 0x8f970fc8, - 0x3c021040, - 0xac570ff0, - 0x8f820f04, - 0x26f70010, - 0x16e20004, - 0xaf970fc8, - 0x8f970f00, - 0x00000000, - 0xaf970fc8, - 0x4d01ffff, - 0x00000000, - 0x03e00008, - 0x00000000, - 0x3c1fa0d1, - 0x27fff02c, - 0x1000ffed, - 0x8f970ff0, - 0x3c0200d1, - 0x32f703ff, - 0x0017b980, - 0x02e2b825, - 0xaee0003c, - 0x2402ffff, - 0xaee20030, - 0xaee20014, - 0x97830ff4, - 0x97820ff8, - 0x3c1d0000, - 0x27bd0698, - 0xa6e30008, - 0xa6e20002, - 0xaf9f0fe8, - 0x03a0f809, - 0xa6e2002c, - 0x8f9f0fe8, - 0x1000ffd9, - 0xaee2000c, - 0x8f970ff0, - 0x3c0200d1, - 0x32f703ff, - 0x0017b980, - 0x02e2b825, - 0x97820ff4, - 0x3c030000, - 0x24630698, - 0xa6e20002, - 0xaf9f0fe8, - 0x0060f809, - 0xa6e2002c, - 0x8f9f0fe8, - 0x1000ffca, - 0xaee2000c, - 0x8f970ff0, - 0x3c0200d1, - 0x32f703ff, - 0x0017b980, - 0x02e2b825, - 0x97820ff4, - 0x00000000, - 0x96e30008, - 0xa6e20008, - 0x00431026, - 0x30420060, - 0x1040ffbd, - 0x8ee2003c, - 0xaee0003c, - 0x1040ffba, - 0x3c028800, - 0xaf820fbc, - 0x8ee20038, - 0xaee00038, - 0x30630060, - 0x279d0f18, - 0x03a3e821, - 0x000318c2, - 0x03a3e821, - 0x8fa3001c, - 0x1040ffaf, - 0xaf820fb4, - 0x3c020c40, - 0xac430fb4, - 0x8fa20018, - 0x2463000c, - 0x14430003, - 0x00000000, - 0x8fa30014, - 0x00000000, - 0xafa3001c, - 0x4d01ffff, - 0x00000000, - 0x1000ffa2, - 0x00000000, - 0x8f970ff0, - 0x3c0200d1, - 0xa7970fb8, - 0x0017b980, - 0x32f7ffc0, - 0x02e2b821, - 0xaee00030, - 0x3c02dead, - 0x8ee3003c, - 0xaee2003c, - 0x8ee20038, - 0x1060ff95, - 0xaee00038, - 0x3c038800, - 0xaf830fbc, - 0x86e30008, - 0x27970f18, - 0x30630060, - 0x02e3b821, - 0x000318c2, - 0x02e3b821, - 0x8ee3001c, - 0x1040ff8a, - 0xaf820fb4, - 0x3c020c40, - 0xac430fb4, - 0x8ee20018, - 0x2463000c, - 0x14430003, - 0x00000000, - 0x8ee30014, - 0x00000000, - 0xaee3001c, - 0x4d01ffff, - 0x00000000, - 0x1000ff7d, - 0x00000000, - 0x8f820ff0, - 0x8f970ff4, - 0x90410000, - 0x00000000, - 0x00370825, - 0x1000ff76, - 0xa0410000, - 0x8f820ff0, - 0x8f970ff4, - 0x94410000, - 0x00000000, - 0x00370825, - 0x1000ff6f, - 0xa4410000, - 0x8f820ff0, - 0x8f970ff4, - 0x8c410000, - 0x00000000, - 0x00370825, - 0x1000ff68, - 0xac410000, - 0x8f820ff0, - 0x8f970ff4, - 0x90410000, - 0x02e0b827, - 0x00370824, - 0x1000ff61, - 0xa0410000, - 0x8f820ff0, - 0x8f970ff4, - 0x94410000, - 0x02e0b827, - 0x00370824, - 0x1000ff5a, - 0xa4410000, - 0x8f820ff0, - 0x8f970ff4, - 0x8c410000, - 0x02e0b827, - 0x00370824, - 0x1000ff53, - 0xac410000, - 0x8f820ff0, - 0x8f970ff4, - 0x1000ff4f, - 0xa0570000, - 0x8f820ff0, - 0x8f970ff4, - 0x1000ff4b, - 0xa4570000, - 0x8f820ff0, - 0x8f970ff4, - 0x1000ff47, - 0xac570000, - 0x8f820ff0, - 0x00000000, - 0x8c420000, - 0x1000ff42, - 0xaf820ff4, - 0x3c01a0c2, - 0x8c22c000, - 0x00000000, - 0xaf820ff0, - 0x3c01a0c2, - 0x8c22c004, - 0x1000ff3a, - 0xaf820ff4, - 0x3c01a0d1, - 0x8c22d5ac, - 0x00000000, - 0xaf820ff0, - 0x3c01a0d1, - 0x8c22d5b0, - 0x1000ff32, - 0xaf820ff4, - 0x3c02a0f0, - 0xac400000, - 0x90570153, - 0x00000000, - 0xa3970c80, - 0x90570157, - 0x00000000, - 0xa3970c81, - 0x9057015b, - 0x00000000, - 0xa3970c87, - 0x9057015f, - 0x00000000, - 0xa3970c86, - 0x90570163, - 0x00000000, - 0x32f70007, - 0xa3970c85, - 0x90570193, - 0x00000000, - 0xa3970c8b, - 0x90570197, - 0x00000000, - 0xa3970c8a, - 0x9057019b, - 0x00000000, - 0x32f70007, - 0xa3970c89, - 0x9057000b, - 0x00000000, - 0x32f700e0, - 0x00170942, - 0x90570047, - 0x00000000, - 0x32f70078, - 0x00370825, - 0x90570067, - 0x00000000, - 0x32f7000f, - 0x0017b9c0, - 0x00370825, - 0x905700c7, - 0x00000000, - 0x32f7002f, - 0x0017bac0, - 0x00370825, - 0x90570147, - 0x00000000, - 0x32f7001e, - 0x0017bc00, - 0x00370825, - 0x90570183, - 0x00000000, - 0x32f70060, - 0x0017bc00, - 0x00370825, - 0xaf810c8c, - 0x3c021840, - 0x8f970fc8, - 0x00000000, - 0x8f970ff0, - 0x00000000, - 0xac570c80, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4d01ffff, - 0x00000000, - 0x3c02a0d1, - 0x2442f998, - 0xaf800c90, - 0xaf800c94, - 0x00400008, - 0x00000000, - 0x87970ff0, - 0x3c1300d1, - 0xa6770008, - 0x3c030000, - 0x24630520, - 0xaf9f0fe8, - 0x0060f809, - 0x24020001, - 0x8f9f0fe8, - 0x1040feda, - 0x97970ff0, - 0x27830f18, - 0x00771821, - 0x0017b8c2, - 0x02e3b821, - 0x3c028800, - 0xaf820fbc, - 0x8e620038, - 0xa7800fb8, - 0xaf820fb4, - 0x8ee3001c, - 0x3c020c40, - 0xac430fb4, - 0x8ee20018, - 0x2463000c, - 0x14430004, - 0xaee3001c, - 0x8ee30014, - 0x00000000, - 0xaee3001c, - 0x4d01ffff, - 0x00000000, - 0x1000ffdf, - 0x00000000, - 0x8f820c5c, - 0x8f830c60, - 0xaf820ff0, - 0x1000febe, - 0xaf830ff4, - 0x23890800, - 0x01201821, - 0x2402000f, - 0x206c0040, - 0xac6c0008, - 0x01801821, - 0x1440fffc, - 0x2042ffff, - 0xac690008, - 0x278b0c98, - 0xa5600000, - 0x2403ffff, - 0xad630014, - 0x34020001, - 0x34420020, - 0xa5620008, - 0x278a0e00, - 0x01401021, - 0x00001821, - 0xac400000, - 0x24630004, - 0x2c6c0100, - 0x1580fffc, - 0x24420004, - 0x3c02a0d1, - 0x2442e000, - 0xaf820fe0, - 0x3c1800d1, - 0x01206021, - 0x00006821, - 0x00007821, - 0x00005821, - 0x00004021, - 0x40026000, - 0x00000000, - 0x34424001, - 0x40826000, - 0x3c020000, - 0x244206f8, - 0x00400008, - 0x00000000, diff --git a/drivers/atm/atmsar11.regions b/drivers/atm/atmsar11.regions deleted file mode 100644 index 42252b7..0000000 --- a/drivers/atm/atmsar11.regions +++ /dev/null @@ -1,6 +0,0 @@ -/* - See copyright and licensing conditions in ambassador.* files. -*/ - { 0x00000080, 993, }, - { 0xa0d0d500, 80, }, - { 0xa0d0f000, 978, }, diff --git a/drivers/atm/atmsar11.start b/drivers/atm/atmsar11.start deleted file mode 100644 index dba55e7..0000000 --- a/drivers/atm/atmsar11.start +++ /dev/null @@ -1,4 +0,0 @@ -/* - See copyright and licensing conditions in ambassador.* files. -*/ - 0xa0d0f000 diff --git a/firmware/Makefile b/firmware/Makefile index f937648..a561bdf 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -20,6 +20,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). # But be aware that the config file might not be included at all. +fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp diff --git a/firmware/atmsar11.HEX b/firmware/atmsar11.HEX new file mode 100644 index 0000000..dfddc19 --- /dev/null +++ b/firmware/atmsar11.HEX @@ -0,0 +1,204 @@ +:04000000A0D0F0009C +:2C008000401A680000000000335B007C13600005335B10003C1AA0C0375A018003400008000000001760FFFB335B400020 +:2C00AC00401A700013600003241B0FC0AF9B45002508000803400008420000108F810C9032220002104000033C03A0D174 +:2C00D8002463F8100060F809242100011000001AAF810C9082020011AF900C480441000A34420080967D000296020012A4 +:2C01040000000000105D00110000000004110161A66200021000000DAE62000C34848000A20200114D01FFFF000000005E +:2C0130008F834C0000000000AF830FEC00E0F80903E03821000414000440FFF700000000AF80460C8E1000084D01FFFF36 +:2C015C00000000008F834C004900001DAF830FEC8F820CBC8F9D0C4C2442000197BE0000AF820CBC13C00009ACA200D872 +:2C018800A7A000003C0100D1003E08259422002C0411013FA4220002AC22000CAC2000108F9E0C5427BD000217BE00028C +:2C01B4008CA200C08F9D0C508F970FC8AF9D0C4C12E20005878040023C02A0D12442F94C0040F8090000000000E0F8094A +:2C01E00003E038214500FFDC8E11000C3C1300D1001111022C4304001060FFB900021180026298218E76003C32220008C1 +:2C020C001440FFB78E7700348E7500303C03CFB016C0000302D5102B041100BE000000001040FFA6007018264D01FFFFE5 +:2C023800000000008F824C00AF974C00AF820FECAC7600100260902132220002104000078F944A009602003A3484000492 +:2C02640014400003AF820FBC3C029000AF820FBC8E10000832943F008E11000C2694FF00128000733C1300D14901007162 +:2C0290003237000816E0006F001111022C4304001060006C0002B980000417400440003A027798211272002326D60030E0 +:2C02BC00AE56003C8E76003C8E7700348E7500303C03CFB016C0000302D5102B0411009100000000104000602E8210006B +:2C02E80014400009007018264D01FFFF000000008F824C00AF974C00AC760010AE4200341000FFD0AF80460C00E0F8090D +:2C03140003E038213C03CFB000701826AE4600344D01FFFF000000008F824C00AF974C00AF820FECAC7600101000FFC382 +:2C034000AF80460C02D5102B104000423C17CFB02E8210001440000602F0B8264D01FFFF00000000AEF600101000FFB8E9 +:2C036C00AF80460C00E0F80903E038214D01FFFF000000008F824C00AF864C00AEF60010AF820FEC1000FFAEAF80460C7F +:2C0398003084FFFB8E5700383242FFC000021182A7820FB8AF970FB4865D002A865E0008A79D0FBA279D0F1833DE00604B +:2C03C40003BEE821001EF0C203BEE8218F970C584D01FFFF000000008F834C008FA2001C12E300033C030C403C1EC0008B +:2C03F000AF9E0FBCAC620FB48FA300182442000C14430002AF80460C8FA20014AE40003CAFA2001C8E76003C8E7700340D +:2C041C008E7500303C03CFB016C0000302D5102B0411003C00000000007018264D01FFFF00000000ACA500E410400032D6 +:2C044800AF974C001000FF7FAC760010000417400440000726D60030AE56003C00E0F80903E03821AF80460C1000FF393E +:2C047400AE4600348E5700383242FFC000021182A7820FB8AF970FB48F970C5800E0F80903E0382112E600033C030C4029 +:2C04A0003C02C000AF820FBC865D002A865E0008A79D0FBA279D0F1833DE006003BEE821001EF0C203BEE8218FA2001C23 +:2C04CC004D01FFFF000000008F974C00AC620FB43084FFFB8FA300182442000C14430002AF80460C8FA20014AE40003CC2 +:2C04F800AFA2001C4D01FFFF00000000ACA500E41000FF13AF974C0000E0F80903E038211000FF0F000000001040005B50 +:2C052400867E0008279D0F1833DE006003BEE821001E10C203A2E8218FB700088FA2000C8EF6000412E2002886620008BC +:2C05500082030010000217400441001924630001106000173C02D1B0005010264D01FFFF000000008F9E4C00AC56001008 +:2C057C0026D6FFFE860200103C03CFB034632000A662002A8EE2000026F70008AE6200388FA20020AFB700082417FFFF46 +:2C05A80002C2A8214D01FFFF00000000AF9E4C0003E00008AE7500308EE2000026F70008AE6200388FA20020AFB70008DB +:2C05D4002417FFFFA677002A02C2A8213C03CFB003E00008AE750030001E18C2006518218C6300C88FA200100000000064 +:2C0600000062B0231EC000038FA1000412C0001B0022B0232EC30041146000023C1500402416004000161E80000318829E +:2C062C00007518254D01FFFF000000008F954C00001EB84000771821AC624D00005610211441000227830D008FA200004D +:2C06580002E3B821AFA2001002D71821AFA3000C4D01FFFF000000008EF600041000FFB5AF954C003C16DEADAE76003C82 +:2C068400AE60003826D5FFFF0000102103E00008AE7500302C430AB2106000052C4324B21000000424020AB210000002AF +:2C06B000240224B11060FFFD304301FF000318403C1DA0D127BDD6CC007D1821946300000002EA4200031C0027BDFFFBC1 +:2C06DC0003E0000803A3100624030FC0AF83450010000002012060213C0CCFB011E000560189602685FE00000000000089 +:2C07080013C000473C02CFB007C0002D001E1F8004610034001E1FC0046000093C02D3B000E0F80903E038214D01FFFF10 +:2C073400000000008F864C008F990FEC1000000BAF994C0001E2782600E0F80903E038214D01FFFF000000008F864C001B +:2C076000AF994C00ADEF20103C02D3B001E278268F820FC08F830FC4AF824D008DE20004A5E00000AC6200008C62000094 +:2C078C0024020380AF824D008F824D008F820F1424630004146200022419FFFF8F830F10ACA500E4AF830FC44D01FFFF93 +:2C07B800000000008F824C801000001FADE2003C00E0F80903E038214D01FFFF00000000A5E000008F864C001580002238 +:2C07E400AF8F45401000001701E2782600E0F80903E038214D01FFFF000000008F864C00AF994C00ADEF20103C02CFB097 +:2C08100001E27826A5E000004D01FFFF00000000100000078F994C0000E0F80903E038214D01FFFF000000008F864C0015 +:2C083C008F990FEC1580000AAF8F45000000782110000014AF19001400E0F80903E038214D01FFFF000000001180FFF8C1 +:2C0868008F864C0085220000012078210440000A8D290008130B0004000C1602AF1900148D7900140160C021AF994C0084 +:2C089400AD8E40103042003F01C27021000417800440018B8F824A0030818000304200041440FF8D8D4B00001020000C47 +:2C08C00030847FFF8F820C480120F021244300348C5D000C24420004AFDD000C1462FFFC27DE0004A52100001000FF82E0 +:2C08EC00250800081160005800000000857D00088D63000C9562000A8D41000407A1002600621821A563000A00031C026D +:2C091800041101A0000318C0001D16C00441001F27A2008000021CC00461000E0040E82127BD0080956200009563000293 +:2C0944003442000CAD22000C24020100A52200109562002CA5230014A5220012A520001634028000A5220000A57D0008D2 +:2C09700007A0000C8F820C4C8F830C502441FFE80023F02B13C000020020102124420400945E00002441FFFE17C0FFF994 +:2C099C00AD620010A44B0000142B001CAD400000AD400004254A00083142007F1440000E00041780044100038F820FE03A +:2C09C800100000063484000134840002244200083442100038421000AF820FE0354A0100394A010039420080AF820FE4B9 +:2C09F400001D14C00441000333A2EFFF1000FF3CA562000807A0009F33A2FFFE10000021A56200088D620024001D1CC01D +:2C0A200004610004AD42000033A3EFFF1000FF31A563000807A0000533A3FFFEA56300088D4B00001000FFAA000000001E +:2C0A4C001000008E25080008254A00083142007F1440000E00041780044100038F820FE010000006348400013484000274 +:2C0A7800244200083442100038421000AF820FE0354A0100394A010039420080AF820FE4110000038D4B00001000FF9303 +:2C0AA4002508FFF88F820FD88F830FDC8F810FD41062001D246200084D01FFFF000000008F8C4C00847F00003C1E00D11C +:2C0AD00033FD03FF001D5980017E5821857E0008001DE900001E0F0003E1F82507E00003AF820FDC879E0CA0278B0C986E +:2C0AFC0007C100423C0208403C01F7B08D62002000230826AC2200008C620004946300022442FFF8004310211000004E12 +:2C0B2800AD6200208F820FD087830CA014220007278B0C98410000513C018000ACA100E08CA100C4000000001022004C4E +:2C0B54000022E8238F9F0F0C07A10002AF810FD403E2E8232FA30041146000023C1E0040241D0040001D1E800003188256 +:2C0B8000007E18254D01FFFF000000008F8C4C00AC624CC0005D1021145F000227830CC08F820F0803A3F021AF820FD059 +:2C0BAC00AF9E0FD84D01FFFF000000001000FFC3246200088D63000C8D7D0010A563000A13A0000200031C02A7A00000F8 +:2C0BD800000318C0041100EF006818214D01FFFF000000008F820C448F830C40AD620010A5630004A563000610000021FC +:2C0C0400AF8C4C00A57D00008C7D000494630002AC5D4C4027A20008AD62001803A3E82127BDFFF4AD7D001C27BD0004D4 +:2C0C3000AD7D002037C18001001E17C00441FFE0A56100084D01FFFF000000008F820C448F830C40AD620010A563000478 +:2C0C5C00A56300068F820FD88F830FDC4D01FFFF000000001462FF9524620008AF8C4C0087830CA0278B0C980461FE97F8 +:2C0C88000004170004400005956200001178000600000000AF0E0010A70D00043084FFF7956D00048D6E001025ADFFD075 +:2C0CB40005A1FE8FAD22000C3C0CFFB001896026000D182225AD00308D7E00188D61001C4D01FFFF00000000103E0036B9 +:2C0CE0008F9D4C003C010840AC3E4C4027DE000811A00017AD7E0018000DF600019E60254D01FFFF00000000AD8E40105F +:2C0D0C008F8D0C40957E00068F8E0C4403CDF021A57E0006000CF782000C0E0203C1F021001E0F80000C6200000C6202C2 +:2C0D38000181602533DE003C019E60213401000110000008A5210000957E00064D01FFFF000000008F8D0C408F8E0C44CD +:2C0D640003CDF021A57E00064D01FFFF0000000001A3F02B17C000080003F60001A36823019E6025018960264D01FFF7CF +:2C0D9000000000001000FE58AF9D4C008D7E00188D61001C00000000143EFFCE006D18234D01FFFF000000002C61000864 +:2C0DBC001020001795610008000000000001FF8007E0000B34210002006D182100031E000183602501896026240D002CC0 +:2C0DE800A56100084D01FFFF000000001000FE40AF9D4C003C1F0C40AFFE4FA83021FFFDA56100083C0CD3CF358CE0006E +:2C0E140010000008340300023C1F0C40AFFE4FA811A0FFF9000DF60034030003019E6025018960263484000834420002C4 +:2C0E4000AD22000C95620006A5230000AD2200384D01FFFF00000000857E00088F820FA897830FACAD22000433C17FFFA6 +:2C0E6C00AD600010A56100081060FE20AF9D4C00A57E00080003190030633FF0A56300008F820FB03C030840AC624C4007 +:2C0E980024430008AD63001897830FAE2442FFF400621821AD63001C4D01FFFF000000008F8D0C408F830C44A56D000474 +:2C0EC400A56D0006AD6300101000FE0AAF9D4C008F820FE000040FC08C4300000421001B8F9F0FE48C5D0004AC4000043A +:2C0EF0001060000EAC400000000000009462002800000000005F10208C4100040000000010200003AC43000410000002B6 +:2C0F1C00AC230024AC43000017A3FFF48C6300248F820FE03BFF0080244200083442100038421000AF820FE0AF9F0FE46E +:2C0F48001000FE573084FFFE1060001000000000947D00280000000003BFE8208FA10004AFA30004102000038C5E000439 +:2C0F740010000002AC230024AFA300008C61002417C3FE48AC410000AC400004AC4000001000FE443084FFFD2C6201006F +:2C0FA0001440000E006A10213143007F01431823004318233062007FA562002800621823000319028F820FE02463FFF8BF +:2C0FCC000062182134631000100000033863100034430100386301008C6200040000000010400003AC6B000403E000089A +:0C0FF800AC4B002403E00008AC6B0000D0 +:02000004A0D08A +:2CD5000000000002A0D0E00000000000000010000000000600000008000000000000000800000002A0D0D64800000000F7 +:2CD52C00000008880000000000000000000000000000000024313200243132002431320000000000244D43522420436FB2 +:2CD558007079726967687420286329204D61646765204E6574776F726B73204C746420313939352E20416C6C207269674C +:2CD584006874732072657365727665642E004D6164676520416D6261737361646F722076312E303100000000000000012C +:2CD5B00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000004E +:2CD5DC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023 +:2CD608000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6 +:0CD6340000000000FFF0400000000000BB +:2CF000000C343E2D000000003C1CA0D1279C56383C1DA0D127BDDFD03C08A0D12508DFD0AF8780080C343C1300000000E4 +:2CF02C00240400030097000D3C08BFC0350802308D08000000000000010000080000000027BDFFD0AFBF001CAFB1001864 +:2CF05800AFB000143C11FFF0000080213C18005637183B7926190200172000020319001A0007000D2401FFFF172100056B +:2CF08400000000003C01800017010002000000000006000D00001012001018403C05A0D124A5D6CC00A32021A4820000C5 +:2CF0B000261000012A0102001420FFEA000000003C06A0D124C6F9E43C07A0D124E7D648ACE600003C08A0D12508FB14D9 +:2CF0DC00ACE800043C09A0D12529FC94ACE900083C0AA0D1254AFCD4ACEA000C3C0BA0D1256BFBA8ACEB00103C0CA0D15C +:2CF10800258CFBC4ACEC00143C0DA0D125ADFBE0ACED00183C0EA0D125CEFBFCACEE001C3C0FA0D125EFFC18ACEF0020AD +:2CF134003C18A0D12718FC34ACF800243C19A0D12739FC50ACF900283C02A0D12442FC60ACE2002C3C03A0D12463FC70A6 +:2CF16000ACE300303C04A0D12484FC80ACE400343C05A0D124A5FCB4ACE500383C06A0D124C6FE08ACE6003C3C08A0D111 +:2CF18C002508FE90ACE800403C09A0D12529FA38ACE900443C0AA0D1254AFA74ACEA0048241000133C0BA0D1256BF9D8E7 +:2CF1B800001060803C0EA0D125CED64801CC6821ADAB0000261000012A0100201420FFF6000000008F988000000000006F +:2CF1E400AF0001008F828000241903FFA4590202000080218F86800024030FFF0010204024C7038000E42821A4A30000C1 +:2CF21000261000012A0100081420FFF7000000008F89800034089C40AD2803A08F8B80003C0A00FF354AFFFFAD6A03A4FC +:2CF23C00000080218F8F8000240C0FFF0010684025F80300030D7021A5CC0000261000012A0100081420FFF700000000AB +:2CF268008F82800034199C40AC5903208F8480003C0300FF3463FFFFAC8303248F868000240502FFA4C502023C08A0C00C +:2CF29400350801803C09A0D12529D5B8250A00288D0B00008D0C0004AD2B0000AD2C000425080008150AFFFA252900081B +:2CF2C0004002600000000000AFA20028240300223C04A0E034840014AC8300008FA500280000000034A6100100C01021CB +:2CF2EC00AFA600283C07FFBF34E7FFFF00C7382400E01021AFA7002840876000000000003C0800023508D8903C09FFFE59 +:2CF3180035290130AD2800008FAA00283C0BF000014B582501601021AFAB002801606021408C6000000000000000802141 +:2CF3440000107080022E7821ADE00000261000012A0104001420FFFA00000000241800013C19A0E8AF380000240200117C +:2CF370003C03A0F034630017A06200003C04F0EB348400703C05FFF034A54A00ACA400003C06FCEB34C60070ACA6000027 +:2CF39C003C07FFF034E74700ACE00000000080213C08FFF035080FC03C09FFF035294500AD280000261000012A01000433 +:2CF3C8001420FFF800000000000080213C0ADEAD001059803C0100D1002B0821AC2A003C3C0100D1002B0821AC200030C1 +:2CF3F4003C0100D1002B0821AC200038240DFFFF3C0100D1002B0821AC2D0014001071003C0100D1002B0821A42E000054 +:2CF420003C0100D1002B0821A4200004241800203C0100D1002B0821A43800083C0100D1002B0821AC200010261000017F +:2CF44C002A0104001420FFE00000000000008021001018C03C05A0D124A5E00000A32021AC8000003C07A0D124E7E000BF +:2CF4780024E8000401033021ACC00000261000012A0100091420FFF300000000240903803C0AFFF0354A4D00AD4900005F +:2CF4A4003C0CA080358C009CAD8000003C0DA08035AD00A0ADA000003C0E11003C0FA08035EF00A8ADEE000041010003A0 +:2CF4D000000000004100FFFF000000003C18A080371800E08F1900003C01A0D1AC39D6C80C343D43032020218FB00014DE +:2CF4FC008FBF001C8FB1001803E0000827BD00300080B8213C1CFFF0A3800C84A3800C888F90440000002021AF800CBC7E +:2CF52800240200A827830F002C5D004017A0000C3C1DFFB003A3E826AFB740000000000000000000000000004D01FFFFF6 +:2CF55400000000002442FFC0246300401000FFF326F700401040000D000000000002EE003C01004003A1E8253C01FFF099 +:2CF5800003A1E82603A3E826AFB740000000000000000000000000004D01FFFF000000003C05A0808F820F08000000007E +:2CF5AC00AF820FD4AF820FD0ACA200C48F820F100000000000021D82AF830FC000031D80004310233C01A0800041102542 +:2CF5D800AF820FC4AF820F108F820F1400000000004310233C01A08000411025AF820F1424030003279D0F1824BE00C823 +:2CF6040027810D008FA2000000000000AFA20010AFC20000AFA10008AFA1000C8FA2001400000000AFA2001C27BD0024B4 +:2CF6300027DE0004242100401460FFF32463FFFF8F820F0000000000AF820FC8ACA200C0278208002403000FAC4000002C +:2CF65C00244200041460FFFD2463FFFF8F830FC000000000AF834D008F834D008F830F148F820F102463FFFCAC40000091 +:2CF688001443FFFE2442000424020380AF824D00279D0F1827A100908FA200148FA3001800000000006218232C7F004017 +:2CF6B40017E000093C1F004037FF080003A0F0214D01FFFF00000000AFE20000244200401000FFF62463FFC01060000659 +:2CF6E00037FF080000031E0003E3F8254D01FFFF00000000AFE2000027BD002417A1FFE800000000000038218FC200145A +:2CF70C008FC3001800000000006218232C7F004013E000043C1F004000030E001000000203E1F8252403004037FF080084 +:2CF73800241E03E7000008214D01FFFF00000000AFE20000002308214900FFFB000000008780400217C0FFF827DEFFFFCA +:2CF7640014E0000434E7400003E7F8251000FFF0AF810C60AF810C5C3C01A0D18C22D6C8000000003C01A080AC2200E0E7 +:2CF790003C01A0808C2000E0AF800FB4A7800FB8A7800FBAA7800FBCA7800FBE27820CC0AF820FDCAF820FD83C02A0D156 +:2CF7BC002442DACCAF820C4CAF820C5024420400AF820C542402001E3C03FFF0247D0040AC7D000803A018211440FFFC55 +:2CF7E8002442FFFF3C1DFFF0AC7D00083C02C7043442DD7BAF820C583C07000024E7015808343FA9000000008E620038B9 +:2CF8140000000000144000058F830C9412A000222463000110000020AF830C94AF820FB43262FFC0000211828663002A70 +:2CF84000A7820FB83C02A000AF820FBCA7830FBA867E0008279D0F1833DE006003BEE821001EF0C203BEE8218FA2001CC6 +:2CF86C003C030C404D01FFFF000000008F974C00AC620FB48FA300182442000C14430003000000008FA2001400000000FB +:2CF89800AFA2001C4D01FFFF00000000ACA500E4AF974C0003E00008AE60003C3C0DA0D125ADD50011A00021000000005C +:2CF8C4008DA90000000000001120001D000000008DAA00048DAB00088DAC000C0009474005010004000000003C08A0D185 +:2CF8F0002508D638014850210009478005010007000000001180000D00000000AD400000254A00041000FFFB258CFFFC66 +:2CF91C0011800007000000008D6E0000256B0004AD4E0000254A00041000FFF9258CFFFC1000FFE125AD001003E00008B9 +:2CF94800000000003C021040AC574FF0000000000000000000000000000000004D01FFFF000000008F820FFC000000005B +:2CF974003042001F000210803C17A0D102E2B82126F7D6488EF700000000000002E00008000000002402FFFFAF820FFCB9 +:2CF9A0008F970FC83C021040AC570FF08F820F0426F7001016E20004AF970FC88F970F0000000000AF970FC84D01FFFFA6 +:2CF9CC000000000003E00008000000003C1FA0D127FFF02C1000FFED8F970FF03C0200D132F703FF0017B98002E2B825AA +:2CF9F800AEE0003C2402FFFFAEE20030AEE2001497830FF497820FF83C1D000027BD0698A6E30008A6E20002AF9F0FE819 +:2CFA240003A0F809A6E2002C8F9F0FE81000FFD9AEE2000C8F970FF03C0200D132F703FF0017B98002E2B82597820FF429 +:2CFA50003C03000024630698A6E20002AF9F0FE80060F809A6E2002C8F9F0FE81000FFCAAEE2000C8F970FF03C0200D174 +:2CFA7C0032F703FF0017B98002E2B82597820FF40000000096E30008A6E2000800431026304200601040FFBD8EE2003CF2 +:2CFAA800AEE0003C1040FFBA3C028800AF820FBC8EE20038AEE0003830630060279D0F1803A3E821000318C203A3E82116 +:2CFAD4008FA3001C1040FFAFAF820FB43C020C40AC430FB48FA200182463000C14430003000000008FA30014000000000E +:2CFB0000AFA3001C4D01FFFF000000001000FFA2000000008F970FF03C0200D1A7970FB80017B98032F7FFC002E2B82140 +:2CFB2C00AEE000303C02DEAD8EE3003CAEE2003C8EE200381060FF95AEE000383C038800AF830FBC86E3000827970F1821 +:2CFB58003063006002E3B821000318C202E3B8218EE3001C1040FF8AAF820FB43C020C40AC430FB48EE200182463000C84 +:2CFB840014430003000000008EE3001400000000AEE3001C4D01FFFF000000001000FF7D000000008F820FF08F970FF4B8 +:2CFBB0009041000000000000003708251000FF76A04100008F820FF08F970FF49441000000000000003708251000FF6F9E +:2CFBDC00A44100008F820FF08F970FF48C41000000000000003708251000FF68AC4100008F820FF08F970FF49041000040 +:2CFC080002E0B827003708241000FF61A04100008F820FF08F970FF49441000002E0B827003708241000FF5AA4410000DB +:2CFC34008F820FF08F970FF48C41000002E0B827003708241000FF53AC4100008F820FF08F970FF41000FF4FA05700009D +:2CFC60008F820FF08F970FF41000FF4BA45700008F820FF08F970FF41000FF47AC5700008F820FF0000000008C4200007A +:2CFC8C001000FF42AF820FF43C01A0C28C22C00000000000AF820FF03C01A0C28C22C0041000FF3AAF820FF43C01A0D14E +:2CFCB8008C22D5AC00000000AF820FF03C01A0D18C22D5B01000FF32AF820FF43C02A0F0AC400000905701530000000076 +:2CFCE400A3970C809057015700000000A3970C819057015B00000000A3970C879057015F00000000A3970C8690570163BA +:2CFD10000000000032F70007A3970C859057019300000000A3970C8B9057019700000000A3970C8A9057019B00000000AE +:2CFD3C0032F70007A3970C899057000B0000000032F700E000170942905700470000000032F700780037082590570067BE +:2CFD68000000000032F7000F0017B9C000370825905700C70000000032F7002F0017BAC000370825905701470000000019 +:2CFD940032F7001E0017BC0000370825905701830000000032F700600017BC0000370825AF810C8C3C0218408F970FC83F +:2CFDC000000000008F970FF000000000AC570C800000000000000000000000000000000000000000000000004D01FFFF17 +:2CFDEC00000000003C02A0D12442F998AF800C90AF800C94004000080000000087970FF03C1300D1A67700083C030000C2 +:2CFE180024630520AF9F0FE80060F809240200018F9F0FE81040FEDA97970FF027830F18007718210017B8C202E3B821FB +:2CFE44003C028800AF820FBC8E620038A7800FB8AF820FB48EE3001C3C020C40AC430FB48EE200182463000C1443000487 +:2CFE7000AEE3001C8EE3001400000000AEE3001C4D01FFFF000000001000FFDF000000008F820C5C8F830C60AF820FF026 +:2CFE9C001000FEBEAF830FF423890800012018212402000F206C0040AC6C0008018018211440FFFC2042FFFFAC69000884 +:2CFEC800278B0C98A56000002403FFFFAD6300143402000134420020A5620008278A0E000140102100001821AC40000038 +:2CFEF400246300042C6C01001580FFFC244200043C02A0D12442E000AF820FE03C1800D1012060210000682100007821C6 +:28FF20000000582100004021400260000000000034424001408260003C020000244206F800400008000000007A +:00000001FF +/* + Madge Ambassador ATM Adapter microcode. + Copyright (C) 1995-1999 Madge Networks Ltd. + + This microcode data is placed under the terms of the GNU General + Public License. The GPL is contained in /usr/doc/copyright/GPL on a + Debian system and in the file COPYING in the Linux kernel source. + + We would prefer you not to distribute modified versions without + consultation and not to ask for assembly/other microcode source. +*/ + +First record is start address in a __be32. -- cgit v0.10.2 From 547d8bb7ddf7f5d9f53741086a394c8318e15f16 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 11 Jun 2008 16:57:21 +0100 Subject: ip2: use request_firmware() Converted with help from Jaswinder Singh Signed-off-by: David Woodhouse Acked-by: Alan Cox diff --git a/drivers/char/ip2/fip_firm.h b/drivers/char/ip2/fip_firm.h deleted file mode 100644 index 4c525fa..0000000 --- a/drivers/char/ip2/fip_firm.h +++ /dev/null @@ -1,2149 +0,0 @@ -/* fip_firm.h - Intelliport II loadware */ -/* -31232 bytes read from ff.lod */ - -static unsigned char fip_firm[] __initdata = { -0x3C,0x42,0x37,0x18,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x57,0x65,0x64,0x20,0x44,0x65,0x63,0x20,0x30,0x31,0x20,0x31,0x32,0x3A,0x32,0x34, -0x3A,0x33,0x30,0x20,0x31,0x39,0x39,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0xE9,0x6C,0x0F,0x42,0x65,0x47,0x69,0x4E,0x6E,0x49,0x6E,0x47,0x20,0x6F,0x46,0x20, -0x63,0x4F,0x64,0x45,0xCC,0x13,0x5A,0x15,0xE8,0x16,0x76,0x18,0x04,0x1A,0x92,0x1B, -0x20,0x1D,0xAE,0x1E,0x3C,0x20,0xCA,0x21,0x58,0x23,0xE6,0x24,0x74,0x26,0x02,0x28, -0x90,0x29,0x1E,0x2B,0xAC,0x2C,0x3A,0x2E,0xC8,0x2F,0x56,0x31,0xE4,0x32,0x72,0x34, -0x00,0x36,0x8E,0x37,0x1C,0x39,0xAA,0x3A,0x38,0x3C,0xC6,0x3D,0x54,0x3F,0xE2,0x40, -0x70,0x42,0xFE,0x43,0x8C,0x45,0x1A,0x47,0xA8,0x48,0x36,0x4A,0xC4,0x4B,0x52,0x4D, -0xE0,0x4E,0x6E,0x50,0xFC,0x51,0x8A,0x53,0x18,0x55,0xA6,0x56,0x34,0x58,0xC2,0x59, -0x50,0x5B,0xDE,0x5C,0x6C,0x5E,0xFA,0x5F,0x88,0x61,0x16,0x63,0xA4,0x64,0x32,0x66, -0xC0,0x67,0x4E,0x69,0xDC,0x6A,0x6A,0x6C,0xF8,0x6D,0x86,0x6F,0x14,0x71,0xA2,0x72, -0x30,0x74,0xBE,0x75,0x4C,0x77,0x6C,0x77,0x8C,0x77,0xAC,0x77,0x33,0xDB,0x8A,0xDC, -0x53,0x33,0xDB,0x25,0x07,0x00,0x75,0x0A,0x8A,0x1E,0x08,0x01,0x83,0xE3,0x0C,0xEB, -0x20,0x90,0x3C,0x01,0x75,0x0A,0x8A,0x1E,0x08,0x01,0x80,0xE3,0xC0,0xEB,0x12,0x90, -0x8A,0x1E,0x0D,0x01,0x3C,0x02,0x75,0x06,0x80,0xE3,0x0C,0xEB,0x04,0x90,0x80,0xE3, -0xC0,0x53,0x50,0x8B,0x1E,0xBA,0x13,0x8E,0xDB,0xE8,0x6A,0x65,0x55,0x8B,0xEC,0x53, -0x1E,0x2B,0xC0,0x8E,0xD8,0x8B,0x5E,0x04,0xC1,0xE3,0x04,0x03,0x5E,0x06,0xD1,0xE3, -0x2E,0x8B,0x9F,0x44,0x00,0x8D,0x47,0x2A,0x1E,0x5A,0x1F,0x5B,0x5D,0xC3,0x55,0x8B, -0xEC,0x53,0x1E,0x2B,0xC0,0x8E,0xD8,0x8B,0x5E,0x04,0xC1,0xE3,0x04,0x03,0x5E,0x06, -0xD1,0xE3,0x2E,0x8B,0x9F,0x44,0x00,0x8D,0x47,0x34,0x1E,0x5A,0x1F,0x5B,0x5D,0xC3, -0xFB,0x55,0x8B,0xEC,0x53,0x51,0x52,0x56,0x57,0x1E,0x06,0x1E,0x07,0x33,0xC0,0x8E, -0xD8,0x8B,0x5E,0x04,0x26,0x8A,0x47,0x59,0x25,0x03,0x00,0x8B,0xF0,0xD1,0xE6,0x2E, -0x8B,0xB4,0xC4,0x00,0xC1,0xE0,0x04,0x26,0x02,0x47,0x1A,0xD1,0xE0,0x8B,0xE8,0x2E, -0x8B,0xAE,0x44,0x00,0x89,0x2C,0x26,0x8A,0x47,0x1C,0x88,0x44,0x0F,0x26,0x8A,0x47, -0x1D,0x88,0x44,0x10,0x26,0x8A,0x47,0x1E,0x88,0x44,0x11,0x26,0x8A,0x47,0x1F,0x88, -0x44,0x12,0x26,0x8A,0x47,0x20,0x88,0x44,0x13,0x26,0x8A,0x47,0x23,0x88,0x44,0x14, -0x26,0x8A,0x47,0x24,0x88,0x44,0x15,0x26,0x8A,0x47,0x5A,0x88,0x44,0x0E,0x33,0xC0, -0x89,0x44,0x06,0x89,0x44,0x08,0x88,0x44,0x0B,0x88,0x44,0x0A,0xB0,0x21,0xB4,0x64, -0x89,0x44,0x04,0x89,0x44,0x02,0xB0,0x55,0x88,0x44,0x0D,0x88,0x44,0x0C,0xE8,0x6A, -0x00,0x72,0x5B,0xE8,0xC9,0x00,0xE8,0xC1,0x10,0x89,0x44,0x08,0x80,0x7C,0x0F,0x01, -0x74,0x29,0xE8,0x2B,0x02,0xE8,0x7F,0x02,0x80,0x7C,0x0F,0x03,0x74,0x1D,0xE8,0xA9, -0x10,0x8B,0xF8,0x2B,0x44,0x08,0x3D,0xA0,0x0F,0x72,0x10,0x89,0x7C,0x08,0x33,0xC0, -0x87,0x44,0x06,0x85,0xC0,0x75,0x04,0xC6,0x44,0x0A,0xFF,0x8A,0x44,0x0A,0x84,0xC0, -0x75,0x0B,0xB8,0x08,0x00,0xE8,0x6A,0x4A,0xE8,0xA9,0x01,0x73,0xBF,0xE8,0x4F,0x01, -0x81,0x66,0x48,0x7F,0xFF,0x83,0x66,0x7A,0xBF,0xB0,0x02,0xE8,0x04,0x0E,0x8A,0x44, -0x0A,0x98,0x07,0x1F,0x5F,0x5E,0x5A,0x59,0x5B,0x5D,0xC3,0x81,0x4E,0x48,0x80,0x00, -0xB0,0x40,0xE8,0x3D,0x4A,0xE8,0x89,0x40,0x73,0x2A,0xE8,0x4D,0x10,0x8B,0xD8,0xB0, -0x05,0xE8,0x2E,0x4A,0xF6,0x46,0x27,0x02,0x75,0x1A,0xE8,0x3D,0x10,0x2B,0xC3,0x3D, -0x58,0x1B,0x72,0xEB,0x81,0x66,0x48,0x7F,0xFF,0xB0,0x02,0xE8,0xC4,0x0D,0xC6,0x44, -0x0A,0x01,0xF9,0xC3,0x83,0x4E,0x7A,0x40,0xF8,0xC3,0xFB,0xB0,0x01,0xE8,0x02,0x4A, -0xFA,0xE8,0x99,0x1E,0xE4,0x0A,0x84,0xC0,0x75,0xF0,0xB0,0x4E,0xE6,0x0A,0xFB,0xB0, -0x01,0xE8,0xEE,0x49,0xFA,0xE8,0x85,0x1E,0xE4,0x0A,0x84,0xC0,0x75,0xF0,0xC3,0xFA, -0xE8,0x7A,0x1E,0xE4,0xEC,0x88,0x44,0x16,0xE4,0xE4,0x88,0x44,0x17,0xE4,0xF8,0x88, -0x44,0x18,0xE4,0xF0,0x88,0x44,0x19,0xE4,0x10,0x88,0x44,0x1A,0xE4,0x12,0x88,0x44, -0x1B,0xE4,0x14,0x88,0x44,0x1C,0xE4,0x34,0x88,0x44,0x1D,0xE4,0x36,0x88,0x44,0x1E, -0xE4,0xD8,0x24,0x01,0x8A,0xE0,0xE4,0xDA,0x24,0x02,0x0A,0xC4,0x88,0x44,0x1F,0x8A, -0x44,0x10,0xE8,0xCD,0x1F,0x8A,0x44,0x11,0xE8,0x35,0x21,0x8A,0x44,0x12,0xE8,0x89, -0x21,0x8A,0x44,0x13,0xE8,0x43,0x21,0xC6,0x86,0xA1,0x00,0x00,0xE4,0x14,0x24,0x10, -0xE6,0x14,0xE4,0x12,0x24,0x3D,0xE6,0x12,0x8A,0x44,0x15,0x3C,0x01,0x72,0x1E,0x77, -0x16,0xB0,0x11,0xE6,0x34,0xB0,0x13,0xE6,0x36,0xE4,0x14,0x0C,0x10,0xE6,0x14,0xE4, -0x12,0x0C,0x40,0xE6,0x12,0xEB,0x06,0xE4,0x12,0x0C,0x02,0xE6,0x12,0x8A,0x44,0x0F, -0x3C,0x01,0x74,0x06,0x3C,0x02,0x74,0x0A,0xEB,0x0E,0xE4,0x12,0x0C,0x08,0xE6,0x12, -0xEB,0x06,0xE4,0x12,0x0C,0x10,0xE6,0x12,0xE8,0x2F,0xFF,0x8A,0x44,0x14,0x3C,0x02, -0x75,0x08,0xB0,0x55,0x88,0x44,0x0C,0x88,0x44,0x0D,0xB0,0x21,0xB4,0x64,0x89,0x44, -0x04,0x89,0x44,0x02,0xE4,0x0C,0x0C,0x10,0xE6,0x0C,0xE8,0xED,0x39,0xFB,0xC3,0xE8, -0x5F,0x3F,0x73,0x08,0xFB,0xB0,0x0A,0xE8,0x08,0x49,0xEB,0xF3,0xFA,0xE8,0x9D,0x1D, -0x8A,0x64,0x16,0x8A,0x44,0x17,0x89,0x86,0x94,0x00,0xE6,0xE4,0x8A,0xC4,0xE6,0xEC, -0x8A,0x64,0x18,0x8A,0x44,0x19,0x89,0x86,0x96,0x00,0xE6,0xF0,0x8A,0xC4,0xE6,0xF8, -0x8A,0x44,0x1A,0xE6,0x10,0x8A,0x44,0x1B,0xE6,0x12,0x8A,0x44,0x1C,0xE6,0x14,0x8A, -0x44,0x1D,0xE6,0x34,0x8A,0x44,0x1E,0xE6,0x36,0x8A,0x44,0x1F,0xE6,0xD8,0xE6,0xDA, -0xE9,0xB7,0xFE,0x90,0xFA,0x8A,0x44,0x0E,0xE6,0xFE,0xE4,0x02,0xA8,0x01,0x75,0x05, -0x33,0xC0,0xFB,0xF8,0xC3,0x33,0xC0,0xE4,0x00,0xFB,0xF9,0xC3,0x8A,0x64,0x14,0x80, -0xFC,0x02,0x74,0x2B,0xFE,0xC0,0xFE,0xC7,0x80,0xFF,0x4E,0x72,0x1C,0x74,0x09,0x80, -0xFF,0x50,0x73,0x08,0xB0,0x0A,0xEB,0x17,0xB0,0x0D,0xEB,0x13,0x02,0xDC,0x32,0xFF, -0x80,0xFB,0x7F,0x7C,0x02,0xB3,0x21,0x8A,0xC3,0x3C,0x7F,0x7C,0x02,0xB0,0x21,0xC3, -0xFA,0x80,0x7C,0x0B,0x04,0x76,0x02,0xFB,0xC3,0x8B,0x46,0x24,0x3D,0x08,0x00,0x72, -0xF6,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x8A,0x44,0x0C,0x8B,0x5C,0x02,0xAA,0xE8,0xAB, -0xFF,0xAA,0xE8,0xA7,0xFF,0xAA,0xE8,0xA3,0xFF,0xAA,0xE8,0x9F,0xFF,0x88,0x44,0x0C, -0x89,0x5C,0x02,0x80,0x44,0x0B,0x04,0x89,0x7E,0x22,0x83,0x6E,0x24,0x04,0x83,0x46, -0x1A,0x04,0x80,0x7E,0x26,0x02,0x74,0x06,0x80,0x66,0x26,0xFD,0xFB,0xC3,0x60,0xB0, -0xFD,0xE8,0x02,0x3F,0x61,0xFB,0xC3,0xFA,0x80,0x7C,0x0F,0x03,0x75,0x09,0xC6,0x44, -0x0B,0x00,0xE8,0xE5,0x38,0xFB,0xC3,0xC4,0x7E,0x14,0x8B,0x4E,0x3A,0x85,0xC9,0x75, -0x35,0x26,0x8B,0x0D,0x47,0x47,0xE3,0xEA,0x3B,0x7E,0x04,0x76,0x22,0xB8,0x02,0x00, -0x39,0x46,0x2E,0x77,0x07,0xC7,0x46,0x2E,0x00,0x00,0xEB,0x13,0x8B,0x5E,0x2C,0x89, -0x5E,0x04,0x26,0xC7,0x07,0x00,0x00,0x43,0x43,0x89,0x5E,0x2C,0x29,0x46,0x2E,0x85, -0xC9,0x78,0xCE,0x89,0x4E,0x3A,0x8A,0x44,0x0D,0x8B,0x5C,0x04,0x26,0x8A,0x25,0x47, -0x3A,0xC4,0x75,0x16,0xFE,0x4C,0x0B,0xFF,0x44,0x06,0xE8,0x0F,0xFF,0xE2,0xED,0x88, -0x44,0x0D,0x89,0x5C,0x04,0x89,0x4E,0x3A,0xEB,0xA7,0xC6,0x44,0x0A,0xFE,0xE8,0x79, -0x38,0xFB,0xC3,0x90,0xE8,0xB3,0x0D,0x8A,0xE8,0x8A,0x0E,0xCB,0x13,0xB3,0x07,0x8A, -0xC1,0xEE,0xEB,0x00,0xEC,0x3A,0xC1,0x75,0x09,0x02,0xCD,0xFE,0xCB,0x75,0xF0,0xEB, -0x0C,0x90,0x88,0x0E,0xCB,0x13,0x8A,0xE8,0xBB,0xFF,0xFF,0xF9,0xC3,0x88,0x0E,0xCB, -0x13,0xF8,0xC3,0x90,0xBB,0x3F,0x3F,0x8A,0x8E,0x9E,0x00,0xBA,0xFE,0x00,0xEC,0x8A, -0xE8,0x32,0xC1,0x22,0xC3,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x90,0xE8,0xE5,0xFF,0x73, -0x01,0xC3,0xBA,0xD0,0x00,0xBB,0x03,0x03,0x8A,0x8E,0x9F,0x00,0xEC,0x8A,0xE8,0x32, -0xC1,0x22,0xC3,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x90,0x33,0xC0,0x8E,0xD8,0x8E,0xC0, -0x80,0x3E,0xC8,0x13,0x00,0x75,0x07,0xB0,0x0A,0xE8,0x26,0x47,0xEB,0xF2,0xFB,0x33, -0xDB,0x8A,0x1E,0xC9,0x13,0x43,0x43,0x83,0xFB,0x7E,0x76,0x07,0x33,0xDB,0xB0,0x02, -0xE8,0x0F,0x47,0x2E,0x8B,0xAF,0x44,0x00,0x83,0x7E,0x08,0x00,0x74,0xE7,0x88,0x1E, -0xC9,0x13,0xB0,0x02,0xE8,0xFB,0x46,0xFA,0xF7,0x46,0x38,0x40,0x00,0x74,0x14,0xE8, -0x96,0x1B,0xE8,0x7F,0xFF,0x72,0x1C,0x33,0xD2,0x8A,0x96,0x9F,0x00,0x83,0xC2,0x0E, -0xEB,0x0C,0x90,0xE8,0x77,0x1B,0xE8,0x83,0xFF,0x72,0x08,0xBA,0x48,0x00,0xE8,0x33, -0xFF,0x73,0xAB,0x23,0xCB,0x89,0x8E,0x9A,0x00,0x89,0x96,0x9C,0x00,0xFE,0x86,0xB5, -0x00,0xC6,0x06,0xC8,0x13,0x00,0xB0,0x0A,0xE8,0x67,0x0A,0xFB,0xEB,0x89,0x10,0x18, -0x08,0x28,0x33,0xC0,0xA0,0x05,0x01,0x8A,0xC8,0x24,0x40,0x75,0x24,0xC7,0x06,0x7C, -0x12,0x8E,0x45,0xC7,0x06,0x42,0x12,0x01,0x00,0xC6,0x06,0x54,0x12,0x02,0xB0,0x08, -0xF6,0xC1,0x01,0x74,0x02,0xB0,0x04,0xA3,0x46,0x12,0xA2,0x4C,0x12,0xA2,0x94,0x12, -0xC3,0xC7,0x06,0x7C,0x12,0xB6,0x45,0xA0,0x0F,0x01,0x84,0xC0,0x75,0x0E,0x6A,0x00, -0x1F,0xC6,0x06,0x93,0x12,0x1E,0x9C,0x0E,0xE8,0xB1,0x0C,0x90,0xC7,0x06,0x44,0x12, -0x01,0x00,0xA3,0x42,0x12,0x8B,0xD8,0xC1,0xE3,0x04,0x88,0x1E,0x94,0x12,0xBE,0xE2, -0x05,0x2B,0xF0,0x8B,0xC8,0x33,0xDB,0x8B,0xFB,0x2E,0xAC,0x88,0x85,0x48,0x12,0x8A, -0xD8,0x0C,0x05,0xE6,0xFE,0x8A,0xE0,0xEB,0x00,0xE4,0xFE,0x32,0xC4,0xA8,0x3F,0x74, -0x03,0xE9,0x9E,0x00,0xE4,0x00,0x88,0x85,0x50,0x12,0x8A,0xE0,0x24,0x30,0xBA,0x10, -0xFF,0x3C,0x30,0x74,0x12,0x80,0xFC,0x04,0x74,0x0A,0xBA,0x04,0x03,0xF6,0x06,0x08, -0x01,0xFE,0x74,0x03,0xBA,0x08,0x0F,0x88,0x95,0x4C,0x12,0x02,0xFA,0x32,0xC0,0xF6, -0xC4,0x08,0x74,0x02,0xB0,0x01,0x88,0x85,0x58,0x12,0x8A,0xC4,0x3C,0x35,0x74,0x5B, -0x3C,0x36,0x74,0x57,0x3C,0x34,0x74,0x53,0x3C,0x04,0x74,0x4F,0x3C,0x14,0x74,0x4B, -0x3C,0x15,0x74,0x47,0xA8,0x40,0x74,0x25,0xC6,0x85,0x54,0x12,0x04,0xD1,0xE7,0xB4, -0x03,0x8A,0xC3,0x89,0x85,0x5C,0x12,0x8A,0xC3,0x8A,0xE3,0x80,0xCC,0x01,0x89,0x85, -0x64,0x12,0xD1,0xEF,0x47,0xE2,0x03,0xEB,0x1A,0x90,0xE9,0x6C,0xFF,0xC6,0x85,0x54, -0x12,0x02,0xD1,0xE7,0x8A,0xE6,0x8A,0xC3,0x0C,0x04,0x89,0x85,0x5C,0x12,0xD1,0xEF, -0x47,0xE2,0xE7,0x33,0xC0,0x8A,0xC7,0xA3,0x46,0x12,0xC3,0xC6,0x85,0x54,0x12,0x06, -0xEB,0xBB,0xC6,0x85,0x54,0x12,0x00,0x33,0xC0,0x88,0x85,0x50,0x12,0x88,0x85,0x4C, -0x12,0x88,0x85,0x58,0x12,0xEB,0xA6,0xC7,0x46,0x26,0x02,0x12,0x8B,0x46,0x1E,0x89, -0x46,0x00,0x89,0x46,0x22,0x8B,0x46,0x20,0x89,0x46,0x24,0xC7,0x46,0x1A,0x00,0x00, -0xC3,0xC7,0x46,0x3C,0x80,0x00,0xC7,0x46,0x38,0x01,0x00,0x1E,0x56,0x8B,0x76,0x30, -0x89,0x76,0x04,0x89,0x76,0x14,0x8E,0x5E,0x06,0x33,0xC0,0x89,0x04,0x46,0x46,0x89, -0x76,0x2C,0x89,0x46,0x3A,0x8B,0x46,0x32,0x48,0x48,0x89,0x46,0x2E,0x5E,0x1F,0xC3, -0x33,0xC0,0x89,0x46,0x48,0x89,0x46,0x4A,0xC7,0x46,0x46,0xAE,0x01,0x89,0x46,0x4E, -0x8B,0x46,0x44,0x89,0x46,0x50,0x8B,0x46,0x42,0x89,0x46,0x40,0x89,0x46,0x08,0xC3, -0x33,0xC0,0x89,0x46,0x76,0x89,0x46,0x78,0xC7,0x46,0x7A,0x10,0x00,0x56,0x1E,0x8B, -0x76,0x70,0x89,0x76,0x10,0x89,0x76,0x0C,0x8E,0x5E,0x12,0xC7,0x04,0x00,0x00,0x8B, -0x46,0x72,0x89,0x46,0x74,0x1F,0x5E,0xC3,0x89,0x56,0x18,0x89,0x56,0x02,0x89,0x56, -0x06,0x89,0x56,0x0A,0x89,0x56,0x0E,0x89,0x56,0x12,0x89,0x56,0x16,0x8B,0xD8,0x4B, -0x4B,0xC1,0xE3,0x02,0xBF,0x02,0x00,0x89,0x7E,0x1E,0x03,0xFB,0x89,0x7E,0x30,0x03, -0xFB,0x89,0x7E,0x42,0x03,0xFB,0x89,0x7E,0x70,0x83,0xEB,0x08,0x89,0x5E,0x20,0x89, -0x5E,0x32,0x89,0x5E,0x44,0x89,0x5E,0x72,0x50,0xE8,0x2B,0xFF,0xE8,0x71,0xFF,0xE8, -0x3F,0xFF,0xE8,0x8B,0xFF,0x58,0xC3,0xB8,0x30,0x75,0xC1,0xE8,0x04,0x0E,0x5B,0x03, -0xC3,0xA3,0xBA,0x13,0x83,0x3E,0x42,0x12,0x00,0x74,0x07,0x80,0x3E,0x94,0x12,0x00, -0x75,0x0E,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x1E,0x9C,0x0E,0xE8,0xBD,0x0A,0x90, -0xB8,0x30,0x7A,0xC1,0xE8,0x04,0x40,0xA3,0xC0,0x13,0x2B,0x06,0x12,0x01,0xF7,0xD8, -0x33,0xD2,0x8B,0xCA,0x8A,0x0E,0x94,0x12,0xF7,0xF1,0x3D,0x80,0x00,0x77,0x0E,0x6A, -0x00,0x1F,0xC6,0x06,0x93,0x12,0x25,0x9C,0x0E,0xE8,0x90,0x0A,0x90,0x48,0x3D,0xFF, -0x07,0x72,0x03,0xB8,0xFF,0x07,0xA3,0xC2,0x13,0x33,0xC9,0x8A,0x0E,0x94,0x12,0x33, -0xF6,0xB8,0x00,0x09,0x2E,0x8B,0xAC,0x44,0x00,0x89,0x46,0x4C,0x40,0x46,0x46,0xE2, -0xF3,0x8A,0x0E,0x94,0x12,0x33,0xF6,0x8B,0x16,0xC0,0x13,0xA1,0xC2,0x13,0x2E,0x8B, -0xAC,0x44,0x00,0xE8,0x22,0xFF,0x03,0xD0,0x46,0x46,0xE2,0xF2,0xC3,0x33,0xC0,0x2E, -0x8B,0xAD,0x44,0x00,0x89,0x46,0x08,0x47,0x47,0xE2,0xF4,0xC3,0x51,0x33,0xC0,0x0A, -0xC2,0x2E,0x8B,0xAD,0x44,0x00,0x89,0x86,0x9E,0x00,0x81,0x4E,0x38,0x00,0x20,0x47, -0x47,0xFE,0xC4,0x80,0xFC,0x04,0x72,0x04,0x32,0xE4,0xFE,0xC0,0xE2,0xE3,0x59,0x83, -0xE9,0x10,0x74,0x05,0xF7,0xD9,0xE8,0xC4,0xFF,0xC3,0x51,0x33,0xC0,0x0A,0xC2,0x2E, -0x8B,0xAD,0x44,0x00,0x89,0x86,0x9E,0x00,0x83,0x4E,0x38,0x40,0x47,0x47,0x80,0xC4, -0x10,0x79,0x04,0x32,0xE4,0xFE,0xC0,0xE2,0xE6,0x59,0x83,0xE9,0x10,0x74,0x05,0xF7, -0xD9,0xE8,0x99,0xFF,0xC3,0xE8,0xD2,0xFF,0xC3,0x8D,0x08,0x9C,0x08,0xCA,0x08,0xF5, -0x08,0x8B,0x0E,0x42,0x12,0x33,0xF6,0x51,0x56,0x33,0xDB,0x8B,0xCB,0x8A,0x94,0x48, -0x12,0x8A,0x8C,0x4C,0x12,0x8A,0x9C,0x54,0x12,0x8B,0xFE,0xC1,0xE7,0x05,0x85,0xDB, -0x75,0x02,0xB1,0x10,0x2E,0xFF,0x97,0xF9,0x08,0x5E,0x59,0x46,0xE2,0xD9,0xC3,0x01, -0xCC,0x03,0xD0,0x00,0xE8,0x02,0xD0,0x00,0xE8,0x01,0xD0,0x00,0xE8,0x00,0xD0,0x00, -0xE8,0x04,0xD0,0xA8,0xDA,0x00,0xDC,0x00,0xDE,0x01,0xD8,0x03,0xCC,0x03,0xCC,0x03, -0xCC,0x04,0xD0,0xA8,0xDA,0x20,0xDC,0x00,0xDE,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x00, -0xD8,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03, -0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03, -0xCC,0x04,0xD0,0x00,0xDA,0x20,0xDC,0x03,0xDE,0x01,0xD8,0x03,0xCC,0x03,0xCC,0x03, -0xCC,0x03,0xCC,0x00,0xD8,0x00,0xCC,0x00,0xD0,0x00,0x00,0x56,0x52,0x1E,0x0E,0x1F, -0xBE,0x2F,0x09,0x33,0xD2,0xFC,0xAD,0x85,0xC0,0x74,0x0D,0x8A,0xD4,0xEE,0xAD,0x85, -0xC0,0x74,0x05,0x8A,0xD4,0xEE,0xEB,0xEE,0x1F,0x5A,0x5E,0xC3,0xE4,0x80,0x84,0xC0, -0x74,0x16,0x78,0x14,0xB0,0x27,0xE6,0xFC,0xB0,0x11,0xE6,0x34,0xE4,0xFC,0x3C,0x27, -0x75,0x06,0xE4,0x11,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x83,0xC2,0x06,0xB0,0xBF,0xEE, -0x83,0xEA,0x02,0xB0,0x10,0xEE,0x88,0x86,0xAF,0x00,0xB0,0x11,0x83,0xC2,0x04,0xEE, -0x83,0xC2,0x02,0xEE,0xB0,0x13,0x83,0xC2,0x02,0xEE,0x83,0xC2,0x02,0xEE,0x2E,0xA1, -0x4C,0x2D,0x89,0x86,0x94,0x00,0x83,0xEA,0x0E,0xEE,0x83,0xC2,0x02,0x8A,0xC4,0xEE, -0x83,0xC2,0x04,0xB0,0x03,0xEE,0x88,0x86,0xA8,0x00,0x83,0xEA,0x04,0x32,0xC0,0xEE, -0x83,0xC2,0x02,0xB0,0x89,0xEE,0x88,0x86,0xA6,0x00,0x0C,0x06,0xEE,0xB0,0x40,0xB4, -0x38,0x89,0x46,0x1C,0xC7,0x46,0x36,0x38,0x00,0x83,0xC2,0x04,0x32,0xC0,0xEE,0x88, -0x86,0xA7,0x00,0xC3,0x83,0xC2,0x06,0xB0,0xBF,0xEE,0x83,0xEA,0x02,0xEC,0x3A,0x86, -0xAF,0x00,0x75,0x24,0x83,0xC2,0x04,0xEC,0x3C,0x11,0x75,0x1C,0x83,0xC2,0x06,0xEC, -0x3C,0x13,0x75,0x14,0x83,0xEA,0x08,0x8A,0x86,0xA8,0x00,0xEE,0x83,0xEA,0x02,0xEC, -0x24,0xC0,0x3C,0xC0,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x33,0xC9,0x8B,0xD1,0x8B,0xF1, -0x8A,0x0E,0x94,0x12,0xC1,0xE9,0x02,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x00, -0x20,0x74,0x0E,0x8A,0x86,0x9E,0x00,0xE6,0xFE,0x32,0xC0,0xE6,0x80,0x42,0xE8,0xFA, -0xFE,0x83,0xC6,0x08,0xE2,0xE1,0x85,0xD2,0x74,0x03,0xE8,0x05,0x08,0xC3,0x33,0xC9, -0x8B,0xF1,0x8A,0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x40,0x00, -0x74,0x06,0xE8,0x73,0x16,0xE8,0x12,0xFF,0x46,0x46,0xE2,0xEA,0xC3,0x33,0xC9,0x8B, -0xF1,0x8A,0x0E,0x94,0x12,0xC1,0xE9,0x02,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38, -0x00,0x20,0x74,0x16,0xE8,0x46,0x16,0xE8,0xD2,0xFE,0x73,0x0E,0x6A,0x00,0x1F,0xC6, -0x06,0x93,0x12,0x1C,0x9C,0x0E,0xE8,0xE3,0x07,0x90,0x83,0xC6,0x08,0xE2,0xD9,0xC3, -0x33,0xC9,0x8B,0xF1,0x8A,0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38, -0x40,0x00,0x74,0x16,0xE8,0x21,0x16,0xE8,0x2A,0xFF,0x73,0x0E,0x6A,0x00,0x1F,0xC6, -0x06,0x93,0x12,0x1C,0x9C,0x0E,0xE8,0xB3,0x07,0x90,0x46,0x46,0xE2,0xDA,0xC3,0x0C, -0x00,0x00,0x10,0x00,0x13,0x12,0x00,0x00,0x14,0x00,0x28,0x3C,0x00,0x1B,0x3E,0x00, -0x00,0x2A,0x00,0x00,0x2C,0x00,0x00,0x42,0x00,0x14,0xD8,0x00,0x00,0xDA,0x00,0x00, -0x34,0x00,0x11,0x36,0x00,0x13,0x38,0x00,0x11,0x3A,0x00,0x13,0x00,0x00,0x56,0x50, -0x52,0xBE,0x2F,0x0B,0x2E,0xAD,0x85,0xC0,0x74,0x06,0x92,0x2E,0xAC,0xEE,0xEB,0xF4, -0x5A,0x58,0x5E,0xC3,0x53,0x2E,0xA1,0x60,0x22,0xE6,0xE4,0xE6,0xF0,0x8A,0xC4,0xE6, -0xEC,0xE6,0xF8,0xE8,0xD8,0xFF,0xB0,0x4B,0xE6,0x10,0xB0,0x50,0xE6,0x12,0xB0,0x38, -0xE6,0x14,0xE8,0xAE,0x15,0xB0,0x46,0xE6,0x0A,0xE8,0xA7,0x15,0xB0,0x1A,0xE6,0x0A, -0xE8,0xA0,0x15,0xB0,0x22,0xE6,0x0A,0xE8,0x99,0x15,0xE8,0xFD,0x06,0x8B,0xD8,0xE4, -0x16,0xA8,0x04,0x75,0x18,0xE8,0xF2,0x06,0x2B,0xC3,0x3D,0x32,0x00,0x72,0xF0,0x6A, -0x00,0x1F,0xC6,0x06,0x93,0x12,0x23,0x9C,0x0E,0xE8,0x10,0x07,0x90,0xE8,0xDA,0x06, -0x2B,0xC3,0x3D,0x24,0x00,0x77,0x1B,0xB0,0x31,0xE6,0xFC,0x56,0x51,0x55,0xB9,0x10, -0x00,0x2E,0x8B,0xAC,0x44,0x00,0x81,0x4E,0x38,0x80,0x00,0x46,0x46,0xE2,0xF2,0x5D, -0x59,0x5E,0xE8,0x69,0xFF,0xE8,0x4B,0x15,0xB0,0x46,0xE6,0x0A,0xE8,0x44,0x15,0x5B, -0xC3,0x33,0xF6,0x8B,0x0E,0x42,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x00, -0x20,0x74,0x06,0xE8,0x17,0x15,0xE8,0x5B,0xFF,0x83,0xC6,0x20,0xE2,0xE9,0xC3,0x8B, -0xC2,0x05,0x04,0x00,0x89,0x46,0x28,0x2E,0xA1,0x4C,0x2D,0x89,0x86,0x8E,0x00,0x89, -0x86,0x90,0x00,0x89,0x86,0x92,0x00,0xC6,0x86,0xA3,0x00,0x0A,0xC6,0x86,0xC3,0x00, -0x03,0x52,0x83,0xC2,0x04,0x8A,0x86,0xA6,0x00,0x0C,0x06,0xEE,0x5A,0x83,0xC2,0x02, -0xB0,0x05,0xEE,0x88,0x86,0xA5,0x00,0xC3,0xE8,0x03,0xFF,0xE8,0xE5,0x14,0xB0,0x42, -0xE6,0x0A,0xF7,0x46,0x38,0x80,0x00,0x74,0x06,0x2E,0xA1,0x9C,0x22,0xEB,0x04,0x2E, -0xA1,0x6C,0x22,0xC7,0x46,0x1C,0x0C,0x00,0x89,0x86,0x94,0x00,0x89,0x86,0x96,0x00, -0x89,0x86,0x8E,0x00,0x89,0x86,0x90,0x00,0x89,0x86,0x92,0x00,0xE6,0xF0,0xE6,0xE4, -0x8A,0xC4,0xE6,0xF8,0xE6,0xEC,0xC6,0x86,0xC3,0x00,0x03,0xE8,0xA5,0x14,0xB0,0x1A, -0xE6,0x0A,0xB0,0x10,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0x33,0xC9,0x8B,0xF1,0x8A, -0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x40,0x00,0x74,0x06,0xE8, -0x76,0x14,0xE8,0x5A,0xFF,0x46,0x46,0xE2,0xEA,0xC3,0x33,0xC9,0x8B,0xF1,0x8A,0x0E, -0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x00,0x20,0x74,0x06,0xE8,0x4C, -0x14,0xE8,0x74,0xFF,0x46,0x46,0xE2,0xEA,0xC3,0x90,0x83,0x3E,0x44,0x12,0x00,0x75, -0x14,0xB0,0x01,0xBA,0x06,0x01,0xEE,0x2A,0xC0,0xEE,0xB0,0x02,0xEE,0xB0,0x04,0xEE, -0xB8,0x00,0x02,0xEB,0x0F,0xBA,0x06,0x01,0xB0,0x40,0xEE,0xB8,0x01,0x00,0x8A,0x0E, -0x0E,0x01,0xD3,0xE0,0xA3,0x88,0x12,0xC3,0xA1,0x88,0x12,0xA3,0x84,0x12,0x2D,0x20, -0x00,0xA3,0x8A,0x12,0x2D,0x20,0x00,0xA3,0x82,0x12,0xC7,0x06,0x86,0x12,0x20,0x00, -0xC7,0x06,0x80,0x12,0x32,0x00,0xC3,0x83,0x3E,0x44,0x12,0x00,0x74,0x76,0x8B,0x0E, -0x42,0x12,0x33,0xF6,0x8A,0xA4,0x54,0x12,0x84,0xE4,0x74,0x5F,0x8A,0x84,0x48,0x12, -0x0C,0x04,0xE6,0xFE,0xF6,0xC4,0x04,0x74,0x25,0xB0,0x1B,0xBA,0x00,0x00,0xEE,0xEB, -0x00,0x2A,0xC0,0xBA,0x02,0x00,0xEE,0xEB,0x00,0xB0,0x03,0xEE,0xEB,0x00,0x32,0xC0, -0xBA,0x02,0x00,0xEE,0xEB,0x00,0xBA,0x00,0x00,0xB0,0x00,0xEE,0xEB,0x2D,0xB0,0x1F, -0xBA,0x00,0x00,0xEE,0xEB,0x00,0x2A,0xC0,0xBA,0x02,0x00,0xEE,0xEB,0x00,0xB0,0x03, -0xEE,0xEB,0x00,0xD1,0xE6,0x8A,0x84,0x5D,0x12,0xD1,0xEE,0xF6,0xD0,0xBA,0x02,0x00, -0xEE,0xEB,0x00,0xBA,0x00,0x00,0xB0,0x0A,0xEE,0xEB,0x00,0xE4,0x04,0xEB,0x00,0xE4, -0x04,0x46,0xE2,0x90,0xC3,0x90,0xB8,0x14,0x00,0xBA,0x3E,0xFF,0xEF,0xB8,0x06,0x00, -0xBA,0x32,0xFF,0xEF,0xB8,0x0F,0x00,0xBA,0x34,0xFF,0xEF,0xBA,0x36,0xFF,0xEF,0x83, -0x3E,0x44,0x12,0x00,0x75,0x16,0xB8,0x11,0x00,0xBA,0x38,0xFF,0xEF,0xB8,0x12,0x00, -0xBA,0x3A,0xFF,0xEF,0xB8,0x1B,0x00,0xBA,0x3C,0xFF,0xEF,0xC3,0xB8,0x11,0x00,0xBA, -0x38,0xFF,0xEF,0xB8,0x12,0x00,0xBA,0x3A,0xFF,0xEF,0xB8,0x1B,0x00,0xBA,0x3C,0xFF, -0xEF,0xC3,0xB8,0xFC,0x00,0xBA,0x28,0xFF,0xEF,0xFB,0x83,0x3E,0x44,0x12,0x00,0x74, -0x07,0xB8,0xCC,0x00,0xBA,0x28,0xFF,0xEF,0xC3,0x00,0xFF,0xFF,0x20,0x24,0x28,0xFF, -0x2C,0xFF,0xFF,0x30,0x34,0x38,0xFF,0xFF,0x3C,0x90,0x3C,0x0F,0x77,0x0E,0xBB,0x19, -0x0E,0x2E,0xD7,0x3C,0xFF,0x74,0x05,0x8A,0xD8,0xF8,0xC3,0x90,0x2A,0xDB,0xF9,0xC3, -0x83,0x3E,0x44,0x12,0x00,0x74,0x27,0xA0,0x06,0x01,0x80,0x26,0x06,0x01,0x30,0x80, -0x3E,0x06,0x01,0x30,0x75,0x18,0xB9,0x02,0x00,0xBF,0xC4,0x13,0xBA,0x06,0x01,0xEC, -0xA8,0x20,0x75,0xF8,0xBA,0x04,0x01,0xED,0xAB,0xE2,0xF1,0xEB,0x16,0x90,0xB9,0x04, -0x00,0xBF,0xC4,0x13,0xBA,0x06,0x01,0xEC,0xA8,0x20,0x75,0xF8,0xBA,0x04,0x01,0xEC, -0xAA,0xE2,0xF1,0xFA,0x90,0xBE,0xC4,0x13,0xAD,0x80,0xE4,0x3F,0x80,0xFC,0x02,0x74, -0x0E,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x0A,0x9C,0x0E,0xE8,0x3E,0x04,0x90,0xAD, -0x3C,0x0F,0x75,0xED,0x8A,0xC4,0xE8,0x81,0xFF,0x72,0xE6,0x88,0x1E,0x1A,0x01,0xC6, -0x06,0x8E,0x12,0x00,0xB0,0x00,0x0A,0x06,0x1A,0x01,0xBA,0x00,0x01,0xEE,0xC6,0x06, -0x8F,0x12,0x40,0x83,0x3E,0x44,0x12,0x00,0x75,0x06,0xB8,0x0C,0x00,0xEB,0x04,0x90, -0xB8,0x4C,0x00,0xBA,0x28,0xFF,0xEF,0xC3,0x83,0x3E,0x44,0x12,0x00,0x75,0x01,0xC3, -0xA1,0x50,0x12,0x0B,0x06,0x52,0x12,0x0A,0xC4,0xA8,0x08,0x74,0xF2,0xA0,0x0F,0x01, -0x2A,0xE4,0x50,0xFF,0x36,0xBA,0x13,0x1F,0xE8,0x50,0x56,0x83,0xC4,0x02,0x6A,0x00, -0x1F,0x33,0xC0,0xA3,0xBC,0x13,0xA0,0x0F,0x01,0xA3,0xBE,0x13,0x8B,0x1E,0xBC,0x13, -0x8A,0x87,0x50,0x12,0xF6,0x87,0x50,0x12,0x08,0x74,0x0D,0x24,0x07,0x8A,0xE0,0xBE, -0xCC,0x00,0xA0,0xBC,0x13,0xE8,0x94,0x3D,0xFF,0x06,0xBC,0x13,0xFF,0x0E,0xBE,0x13, -0x75,0xDA,0xC3,0x90,0x1E,0x33,0xC0,0x8E,0xD8,0xB0,0x01,0xE8,0x54,0x3D,0x1F,0xC3, -0x33,0xC9,0x8B,0xF1,0x8A,0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xC7,0x46,0x62, -0x38,0x44,0xC7,0x46,0x7C,0xFC,0x3B,0xC7,0x46,0x7E,0xE2,0x3B,0xC7,0x86,0x80,0x00, -0xEC,0x3C,0xE8,0xAB,0x16,0xC6,0x86,0xC0,0x00,0x11,0x83,0x7E,0x08,0x00,0x74,0x07, -0x51,0x56,0xE8,0x33,0x33,0x5E,0x59,0x46,0x46,0xE2,0xCD,0xC3,0x33,0xC9,0x8B,0xF1, -0x8B,0xF9,0x8A,0x0E,0x94,0x12,0xC1,0xE9,0x02,0xE3,0x13,0x2E,0x8B,0xAC,0x44,0x00, -0x8A,0x86,0x9E,0x00,0x88,0x85,0x6C,0x12,0x83,0xC6,0x08,0x47,0xE2,0xED,0xC3,0xFA, -0xFC,0xB0,0xC0,0xBA,0x00,0x01,0xEE,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,0x8E,0xD0,0xBF, -0x16,0x01,0xB9,0xCC,0x77,0x2B,0xCF,0xD1,0xE9,0xF3,0xAB,0xBC,0x40,0x12,0xE8,0xD9, -0x02,0xE8,0x70,0x3C,0xBE,0xCC,0x0F,0xE8,0xF2,0x3C,0xF4,0x90,0x33,0xC0,0x8E,0xD8, -0x8E,0xC0,0x8E,0xD0,0xF6,0x06,0x0A,0x01,0x80,0x74,0x0B,0xBE,0x35,0x55,0xE8,0xDB, -0x3C,0xB0,0x01,0xE8,0xAC,0x3C,0xE8,0xB3,0x00,0xE8,0xF6,0xF5,0xE8,0x08,0xF8,0xE8, -0x0F,0xF9,0xE8,0x85,0xFA,0xE8,0xB6,0xFA,0xE8,0xEF,0xFC,0xE8,0xC2,0x10,0xE8,0x03, -0x3C,0xE8,0xB2,0xFD,0xE8,0x30,0xFD,0xE8,0x54,0x02,0xC6,0x06,0x8F,0x12,0xC0,0xE8, -0xBB,0xFA,0xE8,0xEB,0xFA,0xE8,0xE9,0xFB,0xE8,0xAF,0xFC,0xE8,0x8D,0xFC,0xE8,0x1F, -0xFF,0xE8,0x58,0xFF,0xE8,0xDB,0xFD,0xE8,0x16,0xFE,0x33,0xC0,0xBE,0x5A,0x05,0xE8, -0x8A,0x3C,0xE8,0xA3,0xFE,0xE8,0xE0,0xFC,0xFB,0xBE,0xA4,0x44,0xE8,0x7D,0x3C,0xE9, -0xCA,0x2D,0x56,0x98,0x8B,0xF0,0x8B,0x42,0x52,0x85,0xC0,0x75,0x27,0xC7,0x42,0x52, -0x01,0x00,0x53,0x36,0x8B,0x9C,0x2C,0x01,0xF6,0xC3,0x01,0x75,0x0C,0x36,0x89,0x68, -0x52,0x36,0x89,0xAC,0x2C,0x01,0x5B,0x5E,0xC3,0x36,0x89,0xAC,0x2C,0x01,0x36,0x89, -0xAC,0x1C,0x01,0x5B,0x5E,0xC3,0x56,0x98,0x8B,0xF0,0x33,0xED,0x36,0x8B,0x84,0x1C, -0x01,0xA8,0x01,0x75,0x15,0x8B,0xE8,0x33,0xC0,0x87,0x42,0x52,0x36,0x89,0x84,0x1C, -0x01,0xA8,0x01,0x74,0x05,0x36,0x89,0x84,0x2C,0x01,0x5E,0xC3,0x56,0x51,0x33,0xF6, -0xB8,0x01,0x00,0xB9,0x08,0x00,0x89,0x84,0x1C,0x01,0x89,0x84,0x2C,0x01,0x46,0x46, -0xE2,0xF4,0x59,0x5E,0xC3,0x90,0xBB,0x01,0x00,0x8B,0xE8,0xFF,0x4E,0x6E,0x74,0x0A, -0x8B,0xDD,0x8B,0x46,0x58,0xA8,0x01,0x74,0xF0,0xC3,0x8B,0x46,0x48,0xA9,0x08,0x00, -0x74,0x45,0xF7,0x46,0x38,0x40,0x00,0x74,0x27,0xE8,0x5C,0x10,0x80,0xC2,0x06,0x8A, -0x86,0xA8,0x00,0x24,0xBF,0x88,0x86,0xA8,0x00,0xEE,0x60,0xB0,0xFE,0xE8,0x86,0x32, -0x61,0xB0,0x02,0xE8,0x4C,0xFF,0x8B,0x46,0x48,0x24,0xF7,0x89,0x46,0x48,0xEB,0x17, -0xE8,0x2A,0x10,0x81,0x4E,0x26,0x00,0x40,0x8A,0x86,0xA5,0x00,0x0C,0x02,0x88,0x86, -0xA5,0x00,0xE6,0x0C,0x8B,0x46,0x48,0xA9,0x04,0x00,0x74,0x14,0xB0,0x02,0xE8,0x21, -0xFF,0x8B,0x46,0x48,0x24,0xFB,0x89,0x46,0x48,0x60,0xB0,0xDF,0xE8,0x47,0x32,0x61, -0x33,0xC0,0x87,0x46,0x58,0xF6,0xC3,0x01,0x75,0x0B,0x36,0x89,0x47,0x58,0xA8,0x01, -0x75,0x0D,0xE9,0x74,0xFF,0xA3,0x22,0x01,0xA8,0x01,0x75,0x03,0xE9,0x6A,0xFF,0x89, -0x1E,0x32,0x01,0xC3,0xBB,0x01,0x00,0x8B,0xE8,0xF7,0x46,0x38,0x40,0x00,0x74,0x15, -0xE8,0xD5,0x0F,0x80,0xC2,0x0A,0xEC,0xA8,0x40,0x75,0x0A,0x8B,0xDD,0x8B,0x46,0x56, -0xA8,0x01,0x74,0xE3,0xC3,0x8B,0x46,0x26,0x80,0xE4,0xFE,0x80,0xCC,0x02,0x89,0x46, -0x26,0xB0,0x02,0xE8,0xBC,0xFE,0x33,0xC0,0x87,0x46,0x56,0xF6,0xC3,0x01,0x75,0x0A, -0x36,0x89,0x47,0x56,0xA8,0x01,0x75,0x0B,0xEB,0xBD,0xA3,0x20,0x01,0xA8,0x01,0x75, -0x02,0xEB,0xB4,0x89,0x1E,0x30,0x01,0xC3,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA0, -0x90,0x12,0x84,0xC0,0x75,0x49,0xA1,0x22,0x01,0xA8,0x01,0x75,0x03,0xE8,0xF6,0xFE, -0xA1,0x20,0x01,0xA8,0x01,0x75,0x03,0xE8,0x8A,0xFF,0xA1,0xAC,0x13,0x48,0x78,0x05, -0x74,0x45,0xA3,0xAC,0x13,0xA1,0xAE,0x13,0x48,0x78,0x05,0x74,0x51,0xA3,0xAE,0x13, -0xA1,0xB0,0x13,0x48,0x78,0x05,0x74,0x63,0xA3,0xB0,0x13,0xA1,0x7E,0x12,0x40,0x78, -0x03,0xA3,0x7E,0x12,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0xA0, -0x91,0x12,0x40,0x3C,0x02,0x72,0x0B,0x33,0xC0,0xA2,0x91,0x12,0xFF,0x16,0x7C,0x12, -0xEB,0xA4,0xA2,0x91,0x12,0xEB,0x9F,0xA0,0x8E,0x12,0x32,0x06,0x8F,0x12,0xA2,0x8E, -0x12,0x0A,0x06,0x1A,0x01,0xBA,0x00,0x01,0xEE,0xB8,0x2C,0x01,0xEB,0xA4,0x83,0x3E, -0x84,0x12,0x10,0x72,0x11,0xBA,0x28,0xFF,0xED,0x0C,0x81,0xEF,0xE8,0x53,0x37,0xBA, -0x28,0xFF,0xED,0x24,0x7E,0xEF,0xB8,0x04,0x00,0xEB,0x92,0xC6,0x06,0x8D,0x12,0x01, -0xE8,0x3F,0x37,0xC6,0x06,0x8D,0x12,0x00,0xA1,0xB2,0x13,0xEB,0x8B,0x90,0x8A,0x1E, -0x0B,0x01,0x2A,0xFF,0x6B,0xC3,0x19,0xBA,0x62,0xFF,0xEF,0xB8,0x0A,0x00,0xBA,0x60, -0xFF,0xEF,0xB8,0x01,0xE0,0xBA,0x66,0xFF,0xEF,0xB8,0xFF,0xFF,0xBA,0x52,0xFF,0xEF, -0xB8,0x09,0xC0,0xBA,0x56,0xFF,0xEF,0xC7,0x06,0xAC,0x13,0x2C,0x01,0xC7,0x06,0xAE, -0x13,0x04,0x00,0xC6,0x06,0x91,0x12,0x00,0xC3,0x90,0x8A,0x1E,0x0B,0x01,0x2A,0xFF, -0x6B,0xC3,0x05,0xD1,0xE8,0xA3,0x18,0x01,0xC3,0x90,0x52,0xBA,0x50,0xFF,0xED,0x5A, -0xC3,0x90,0x53,0x51,0x8B,0x1E,0x18,0x01,0xB9,0x32,0x05,0x90,0xE2,0xFE,0x4B,0x75, -0xF7,0x59,0x5B,0xC3,0xB0,0x80,0xBA,0x00,0x01,0x0A,0x06,0x1A,0x01,0xEE,0xC3,0x90, -0xB0,0x40,0xEB,0xF2,0xB0,0xC0,0xEB,0xEE,0xB0,0x00,0xEB,0xEA,0xFA,0x60,0x06,0x1E, -0x16,0x2B,0xDB,0x8E,0xDB,0x2E,0xA1,0xBA,0x4C,0x2E,0xA3,0x92,0x4C,0xA0,0x93,0x12, -0x98,0x8B,0xE8,0x89,0x26,0x2D,0x7A,0x80,0x3E,0xCA,0x13,0x00,0x74,0x03,0xE9,0x6B, -0x42,0xE8,0xC0,0xFF,0xE8,0xAB,0xFF,0xE8,0xA8,0xFF,0xB0,0x20,0xC6,0x06,0x90,0x12, -0x00,0xFF,0x16,0x7C,0x12,0x8B,0xFD,0x83,0xFF,0x0A,0x72,0x11,0xE8,0xB9,0xFF,0xE8, -0x90,0xFF,0xE8,0xAB,0xFF,0xE8,0x8A,0xFF,0x83,0xEF,0x0A,0xEB,0xEA,0x0B,0xFF,0x74, -0x0F,0xE8,0xA4,0xFF,0xE8,0x7B,0xFF,0xE8,0x9A,0xFF,0xE8,0x75,0xFF,0x4F,0x75,0xF1, -0xE8,0x95,0xFF,0xE8,0x6C,0xFF,0xEB,0xB9,0x8A,0x86,0xA5,0x00,0x24,0xFD,0xEE,0x88, -0x86,0xA5,0x00,0xC3,0x8A,0x86,0xA6,0x00,0x0C,0x02,0xEE,0xC3,0x8B,0x76,0x38,0xF7, -0xC6,0x01,0x00,0x74,0xEF,0x8B,0x4E,0x36,0x8B,0x46,0x2E,0x3B,0xC1,0x73,0x02,0x8B, -0xC8,0x2B,0xC1,0x89,0x46,0x2E,0x01,0x4E,0x34,0xC4,0x7E,0x04,0x26,0x01,0x0D,0x8B, -0x7E,0x2C,0x83,0xEA,0x04,0xF3,0x6C,0x8E,0xC1,0x89,0x7E,0x2C,0x3B,0x46,0x3C,0x72, -0x12,0xF7,0xC6,0x20,0x00,0x75,0x0B,0x83,0xCE,0x20,0x89,0x76,0x38,0xB0,0x00,0xE8, -0xA0,0xFC,0xC3,0xF7,0xC6,0x04,0x00,0x74,0x1B,0x8B,0xD8,0x83,0xCE,0x10,0x89,0x76, -0x38,0x8A,0x86,0xA7,0x00,0x24,0xFE,0x88,0x86,0xA7,0x00,0x83,0xC2,0x08,0xEE,0x83, -0xEA,0x08,0x8B,0xC3,0x3D,0x40,0x00,0x72,0x01,0xC3,0x81,0x4E,0x38,0x00,0x04,0x83, -0xC2,0x02,0x8A,0x86,0xA5,0x00,0x24,0xFA,0x88,0x86,0xA5,0x00,0xEE,0xC3,0x8A,0x86, -0xA6,0x00,0x0C,0x02,0xEE,0xC3,0xF7,0x46,0x38,0x01,0x00,0x74,0xF1,0x8B,0x4E,0x2E, -0x32,0xDB,0x8A,0xBE,0xA3,0x00,0x83,0xC2,0x06,0xC4,0x76,0x04,0x8B,0x7E,0x2C,0x83, -0xF9,0x08,0x72,0x2C,0xEC,0xA8,0x01,0x74,0x16,0x8A,0xE0,0x83,0xEA,0x0A,0xEC,0x83, -0xC2,0x0A,0x84,0xE7,0x75,0x51,0xAA,0xFE,0xC3,0x49,0x83,0xF9,0x08,0x73,0xE5,0x32, -0xFF,0x26,0x01,0x1C,0x01,0x5E,0x34,0x89,0x76,0x04,0x89,0x4E,0x2E,0x89,0x7E,0x2C, -0x3B,0x4E,0x3C,0x72,0x11,0xF6,0x46,0x38,0x20,0x74,0x01,0xC3,0x83,0x4E,0x38,0x20, -0xB0,0x00,0xE8,0xFD,0xFB,0xC3,0xF6,0x46,0x38,0x04,0x74,0x15,0x83,0x4E,0x38,0x10, -0x8A,0x86,0xA7,0x00,0x24,0xFE,0x88,0x86,0xA7,0x00,0x83,0xEA,0x02,0xEE,0x83,0xC2, -0x02,0x3D,0x40,0x00,0x72,0x5D,0xC3,0x32,0xFF,0x26,0x03,0x1C,0x85,0xDB,0x74,0x09, -0x26,0x89,0x1C,0x8B,0xF7,0x47,0x47,0x49,0x49,0x80,0xE4,0x1E,0x80,0xCC,0xC0,0x26, -0x89,0x04,0xF6,0xC4,0x10,0x74,0x27,0x8B,0x76,0x38,0xF7,0xC6,0x00,0x10,0x74,0x0B, -0x50,0xFE,0x86,0xB2,0x00,0xB0,0x0A,0xE8,0xA8,0xFB,0x58,0xF7,0xC6,0x00,0x01,0x74, -0x0D,0xE8,0x82,0x26,0x8B,0x76,0x38,0x8B,0x4E,0x2E,0x8B,0x7E,0x04,0xAB,0x8B,0xF7, -0x33,0xC0,0xAB,0x32,0xDB,0x8A,0xBE,0xA3,0x00,0x49,0x49,0x83,0xF9,0x08,0x72,0x17, -0xE9,0x41,0xFF,0x81,0x4E,0x38,0x00,0x04,0x83,0xC2,0xF8,0x8A,0x86,0xA5,0x00,0x24, -0xFA,0x88,0x86,0xA5,0x00,0xEE,0xC3,0xE9,0x45,0xFF,0x83,0xC2,0x08,0xEC,0x88,0x86, -0xAA,0x00,0xC0,0xE8,0x04,0x8A,0xE0,0x8A,0xC8,0x86,0x86,0xA9,0x00,0x32,0xE0,0x8B, -0x5E,0x3E,0x84,0xE3,0x74,0x4F,0x8A,0xC1,0x8B,0x4E,0x26,0xF6,0xC5,0x04,0x74,0x0C, -0xA8,0x08,0x74,0x05,0x80,0xE1,0xBF,0xEB,0x03,0x80,0xC9,0x40,0xF6,0xC5,0x08,0x74, -0x0C,0xA8,0x02,0x74,0x05,0x80,0xE1,0x7F,0xEB,0x03,0x80,0xC9,0x80,0x88,0x4E,0x26, -0x8B,0xF0,0x8A,0x86,0xA5,0x00,0x84,0xC9,0x74,0x08,0xA8,0x02,0x74,0x15,0x24,0xFD, -0xEB,0x06,0xA8,0x02,0x75,0x0D,0x0C,0x02,0x88,0x86,0xA5,0x00,0x83,0xEA,0x0A,0xEE, -0x83,0xC2,0x0A,0x8B,0xC6,0x84,0xE7,0x75,0x01,0xC3,0xC6,0x86,0xBA,0x00,0x01,0xB0, -0x0E,0xE8,0xEE,0xFA,0xF7,0x46,0x38,0x00,0x02,0x74,0xEE,0x83,0x7E,0x2E,0x06,0x72, -0xE8,0x8A,0xA6,0xAA,0x00,0xC4,0x5E,0x04,0x8B,0x7E,0x2C,0xB0,0xFF,0xAA,0xB0,0x02, -0xAB,0x26,0x83,0x07,0x03,0x83,0x6E,0x2E,0x03,0x89,0x7E,0x2C,0xF6,0x46,0x38,0x20, -0x74,0x01,0xC3,0x83,0x4E,0x38,0x20,0xB0,0x00,0xE8,0xB6,0xFA,0xC3,0x90,0x83,0xEA, -0x08,0xE9,0xB4,0xFD,0x83,0xC2,0x06,0x8B,0x5E,0x26,0xF6,0xC3,0xC0,0x75,0xEF,0x8B, -0x4E,0x1C,0xEC,0x88,0x86,0xA4,0x00,0x83,0xEA,0x0A,0xA8,0x20,0x75,0x02,0x8A,0xCD, -0x32,0xED,0x8B,0x46,0x1A,0x3B,0xC8,0x73,0x18,0x01,0x4E,0x2A,0x2B,0xC1,0x89,0x46, -0x1A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,0xD9,0x89,0x76,0x00,0x3D,0x20,0x00,0x72,0x30, -0xC3,0x85,0xC0,0x74,0x31,0x8B,0xC8,0x01,0x46,0x2A,0xC5,0x76,0x00,0xF3,0x6E,0x8E, -0xD9,0x80,0xCB,0x02,0x89,0x5E,0x26,0xE8,0x32,0xF1,0xF6,0xC7,0x01,0x75,0x16,0x83, -0xC2,0x02,0xE8,0x53,0xFD,0xF6,0xC7,0x10,0x75,0x0B,0xB0,0x02,0xE8,0x43,0xFA,0xC3, -0xF6,0xC7,0x01,0x74,0xF0,0xC3,0x80,0xCB,0x02,0x89,0x5E,0x26,0xF6,0xC7,0x01,0x74, -0xDE,0x83,0xC2,0x02,0xE8,0x31,0xFD,0xF6,0x86,0xA4,0x00,0x40,0x74,0x0B,0x80,0xE7, -0xFE,0x80,0xCF,0x02,0x89,0x5E,0x26,0xEB,0xCC,0xB0,0x04,0xE8,0x14,0xFA,0xC3,0xC0, -0xC2,0xC8,0xCA,0xC4,0xC6,0xCC,0xCE,0xD0,0xD2,0xD8,0xDA,0xD4,0xD6,0xDC,0xDE,0x90, -0xE9,0x0E,0x01,0xE4,0xC4,0x8A,0xE0,0xE4,0xC4,0x8B,0xD0,0x83,0xF9,0x08,0x72,0xF0, -0x26,0x83,0x3F,0x00,0x74,0x04,0x8B,0xDF,0x49,0x49,0x8B,0xFB,0x8A,0xDE,0x83,0xE3, -0x0F,0x2E,0x8A,0xA7,0x2F,0x16,0xAB,0xF6,0xC4,0x10,0x74,0x24,0xF7,0xC6,0x00,0x10, -0x74,0x0B,0x50,0xFE,0x86,0xB2,0x00,0xB0,0x0A,0xE8,0xC6,0xF9,0x58,0xF7,0xC6,0x00, -0x01,0x74,0x0D,0xE8,0xA0,0x24,0x8B,0x76,0x38,0x8B,0x4E,0x2E,0x8B,0x7E,0x04,0xAB, -0x89,0x7E,0x04,0x33,0xC0,0xAB,0x49,0x49,0x89,0x4E,0x2E,0x89,0x7E,0x2C,0x8B,0xC1, -0xEB,0x4E,0x90,0xEB,0x9E,0x90,0xE4,0xD6,0x84,0xC0,0x79,0x63,0xE6,0xD0,0x8A,0xC8, -0x25,0x03,0x00,0x03,0xD8,0xD1,0xE3,0x2E,0x8B,0xAF,0x44,0x00,0x88,0x8E,0xAE,0x00, -0x8B,0x4E,0x2E,0xC4,0x5E,0x04,0x8B,0x7E,0x2C,0x8B,0x76,0x38,0xE4,0x86,0x24,0x07, -0x3C,0x03,0x75,0xCF,0xE4,0x1C,0x91,0x3B,0xC1,0x73,0x02,0x8B,0xC8,0x2B,0xC1,0x89, -0x46,0x2E,0x01,0x4E,0x34,0x26,0x01,0x0F,0xBA,0xC4,0x00,0xF3,0x6C,0x89,0x7E,0x2C, -0x3B,0x46,0x3C,0x72,0x1C,0xF7,0xC6,0x20,0x00,0x75,0x0B,0x83,0xCE,0x20,0x89,0x76, -0x38,0xB0,0x00,0xE8,0x3C,0xF9,0x8A,0x86,0xAE,0x00,0x24,0x3F,0xE6,0xD6,0xC3,0xF9, -0xC3,0xF7,0xC6,0x0A,0x00,0x74,0x35,0xF7,0xC6,0x10,0x00,0x75,0x2F,0x83,0xCE,0x10, -0x89,0x76,0x38,0xF7,0xC6,0x02,0x00,0x74,0x0E,0x50,0xE4,0xD8,0x24,0xFE,0xE6,0xD8, -0x58,0xF7,0xC6,0x08,0x00,0x74,0x15,0x50,0x51,0xB9,0xE8,0x03,0xE4,0x0A,0x84,0xC0, -0xE0,0xFA,0x84,0xC0,0x75,0x04,0xB0,0x24,0xE6,0x0A,0x59,0x58,0x3D,0x40,0x00,0x73, -0xB5,0x8A,0x86,0xA5,0x00,0x24,0xEF,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x81,0xCE,0x10, -0x04,0x89,0x76,0x38,0xEB,0xA0,0x00,0x08,0x04,0x0C,0x01,0x09,0x05,0x0D,0x02,0x0A, -0x06,0x0E,0x03,0x0B,0x07,0x0F,0x00,0x40,0x80,0xC0,0x20,0x60,0xA0,0xE0,0x10,0x50, -0x90,0xD0,0x30,0x70,0xB0,0xF0,0xE4,0xD2,0xE6,0xD0,0x8A,0xC8,0x25,0x03,0x00,0x03, -0xD8,0xD1,0xE3,0x2E,0x8B,0xAF,0x44,0x00,0x88,0x8E,0xAE,0x00,0xE4,0xD8,0xC0,0xE8, -0x04,0x8B,0xD8,0x2E,0x8A,0x87,0x66,0x17,0x8A,0xE0,0x8A,0xC8,0x86,0x86,0xA9,0x00, -0x32,0xE0,0xE4,0x98,0x8B,0x5E,0x3E,0x84,0xE3,0x74,0x54,0x8A,0xC1,0x8B,0x4E,0x26, -0xF6,0xC5,0x04,0x74,0x0C,0xA8,0x08,0x74,0x05,0x80,0xE1,0xBF,0xEB,0x03,0x80,0xC9, -0x40,0xF6,0xC5,0x08,0x74,0x0C,0xA8,0x02,0x74,0x05,0x80,0xE1,0x7F,0xEB,0x03,0x80, -0xC9,0x80,0x88,0x4E,0x26,0x8B,0xF0,0x8A,0x86,0xA5,0x00,0xF6,0xC1,0xFD,0x74,0x08, -0xA8,0x06,0x74,0x19,0x24,0xF9,0xEB,0x0F,0xA8,0x06,0x75,0x11,0xF6,0xC5,0x01,0x75, -0x04,0x0C,0x04,0xEB,0x02,0x0C,0x02,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x8B,0xC6,0x84, -0xE7,0x75,0x09,0x8A,0x86,0xAE,0x00,0x24,0x3F,0xE6,0xD2,0xC3,0xC6,0x86,0xBA,0x00, -0x01,0xB0,0x0E,0xE8,0x1C,0xF8,0xF7,0x46,0x38,0x00,0x02,0x74,0xE6,0x83,0x7E,0x2E, -0x06,0x72,0xE0,0x8A,0x86,0xA9,0x00,0x8A,0xE0,0x86,0x86,0xAA,0x00,0x8A,0xC8,0x32, -0xC4,0x80,0xC9,0x0B,0x22,0xC1,0xC0,0xE4,0x04,0x0A,0xE0,0xC4,0x5E,0x04,0x8B,0x7E, -0x2C,0xB0,0xFF,0xAA,0xB0,0x02,0xAB,0x26,0x83,0x07,0x03,0x83,0x6E,0x2E,0x03,0x89, -0x7E,0x2C,0xF6,0x46,0x38,0x20,0x75,0xAB,0x83,0x4E,0x38,0x20,0xB0,0x00,0xE8,0xD1, -0xF7,0xEB,0xA0,0x90,0xE4,0x12,0x24,0xDF,0xE6,0x12,0x81,0xE3,0xFE,0x9F,0x89,0x5E, -0x26,0x83,0x66,0x48,0xF7,0xEB,0x73,0x90,0xF6,0xC7,0x20,0x75,0xE7,0xE4,0x12,0x0C, -0x20,0xE6,0x12,0x32,0xC0,0xE6,0xC6,0xB0,0x83,0xE6,0xC6,0x80,0xCF,0x20,0x89,0x5E, -0x26,0x8A,0x86,0xA5,0x00,0x0C,0x02,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xEB,0x74,0x90, -0xF6,0xC7,0x40,0x75,0xD3,0xE4,0x12,0x0C,0x20,0xE6,0x12,0x32,0xC0,0xE6,0xC6,0xB0, -0x81,0xE6,0xC6,0x80,0xE7,0xDF,0x80,0xCB,0x01,0x89,0x5E,0x26,0xB0,0x06,0xE8,0x71, -0xF7,0x90,0x8A,0x86,0xA5,0x00,0x24,0xF9,0xE6,0x0C,0x88,0x86,0xA5,0x00,0xEB,0x43, -0xE4,0xD4,0xE6,0xD0,0x8B,0xF8,0x25,0x03,0x00,0x03,0xD8,0xD1,0xE3,0x2E,0x8B,0xAF, -0x44,0x00,0x8B,0x5E,0x26,0xF6,0xC7,0x60,0x75,0xB6,0xF6,0xC3,0xC0,0x75,0xD3,0xBA, -0xC6,0x00,0x8B,0x4E,0x1C,0x8B,0x46,0x1A,0x3B,0xC8,0x73,0x1E,0x01,0x4E,0x2A,0x2B, -0xC1,0x89,0x46,0x1A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,0xD9,0x89,0x76,0x00,0x3D,0x20, -0x00,0x72,0x3D,0x8B,0xC7,0x24,0x3F,0xE6,0xD4,0xC3,0x85,0xC0,0x74,0x39,0x8B,0xC8, -0x01,0x46,0x2A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,0xD9,0x83,0xCB,0x02,0x89,0x5E,0x26, -0xE8,0xD9,0xED,0xF6,0xC7,0x01,0x75,0x39,0x8A,0x86,0xA5,0x00,0x24,0xF9,0xE6,0x0C, -0x88,0x86,0xA5,0x00,0xF6,0xC7,0x10,0x75,0xCA,0xB0,0x02,0xE8,0xE4,0xF6,0xEB,0xC3, -0xF6,0xC7,0x01,0x74,0xEF,0xEB,0xBC,0xF6,0xC7,0x01,0x74,0xDC,0x8A,0x86,0xA5,0x00, -0xA8,0x02,0x74,0x11,0x81,0xE3,0xFF,0xFE,0x81,0xCB,0x00,0x02,0x89,0x5E,0x26,0xEB, -0xC7,0x8A,0x86,0xA5,0x00,0x24,0xFB,0x0C,0x02,0xE6,0x0C,0x88,0x86,0xA5,0x00,0xEB, -0x92,0x90,0xFD,0xF7,0xDF,0x7F,0xFE,0xFB,0xEF,0xBF,0x00,0x04,0x00,0x04,0x05,0x04, -0x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x02,0x04,0x00,0x04,0x05,0x04, -0x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04, -0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04, -0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x03,0x04,0x00,0x04,0x05,0x04, -0x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x02,0x04,0x00,0x04,0x05,0x04, -0x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04, -0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04, -0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04, -0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x33,0xDB,0x8A,0xD8,0x8A,0x87, -0x6C,0x12,0xE6,0xFE,0xC1,0xE3,0x02,0xE4,0xCE,0xA8,0x04,0x75,0x09,0xA8,0x02,0x74, -0x03,0xE9,0x2C,0xFE,0xF9,0xC3,0x50,0x53,0xE8,0xCB,0xFC,0x5B,0x58,0xA8,0x02,0x74, -0x03,0xE9,0x1C,0xFE,0xF8,0xC3,0x33,0xDB,0x8A,0xD8,0x8A,0x87,0x6C,0x12,0xE6,0xFE, -0xC1,0xE3,0x02,0xE9,0xD0,0xFB,0x9A,0x1A,0xC6,0x1A,0x00,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0C,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0E,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0C,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00, -0x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0xC3,0x90,0xDA,0x14,0x94,0x15, -0x5C,0x13,0xE6,0x13,0xDA,0x1B,0xDA,0x1B,0xE6,0x13,0xDA,0x1B,0x8B,0x94,0x64,0x12, -0xC1,0xE6,0x04,0xA8,0x01,0x74,0x35,0x50,0x33,0xC0,0x8A,0xC2,0xE6,0xFE,0xE4,0xA0, -0x85,0xC0,0x74,0x27,0x8B,0xD8,0x2E,0x8A,0x9F,0xDA,0x1A,0x52,0x56,0x2E,0x8B,0xA8, -0x44,0x00,0x8B,0x56,0x28,0xEC,0xA8,0x01,0x75,0x0D,0x88,0x86,0xAD,0x00,0x24,0x0E, -0x8A,0xD8,0x2E,0xFF,0x97,0xDC,0x1B,0x5E,0x5A,0xEB,0xCD,0x58,0xA8,0x02,0x74,0x36, -0x83,0xC6,0x10,0x33,0xC0,0x8A,0xC6,0xE6,0xFE,0xE4,0xA0,0x85,0xC0,0x74,0x27,0x8B, -0xD8,0x2E,0x8A,0x9F,0xDA,0x1A,0x52,0x56,0x2E,0x8B,0xA8,0x44,0x00,0x8B,0x56,0x28, -0xEC,0xA8,0x01,0x75,0x0D,0x88,0x86,0xAD,0x00,0x24,0x0E,0x8A,0xD8,0x2E,0xFF,0x97, -0xDC,0x1B,0x5E,0x5A,0xEB,0xCD,0xC3,0x90,0x32,0xE4,0x8B,0xD8,0x8B,0xD0,0x2E,0x8A, -0x9F,0x9A,0x19,0x2E,0x22,0x97,0x92,0x19,0x56,0x52,0x8A,0xC3,0x24,0x03,0x03,0xC6, -0x80,0xE3,0x04,0xD0,0xEB,0x2E,0xFF,0x97,0xD6,0x1A,0x58,0x5E,0xA9,0x55,0x00,0x75, -0xD9,0xC3,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x00, -0x22,0xC4,0x74,0x08,0x33,0xF6,0xE8,0xBF,0xFF,0xEB,0xEE,0x90,0xE4,0x04,0x07,0xE4, -0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B, -0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0x08,0xBE,0x04, -0x00,0xE8,0x94,0xFF,0xEB,0xED,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA, -0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12, -0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0x18,0x33,0xF6,0xE8,0x6B,0xFF,0xA1,0x60,0x12, -0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0xE5,0xBE,0x08,0x00,0xE8,0x5A,0xFF,0xEB,0xDD, -0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04, -0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x04,0x1F,0xE4,0x04,0xB8,0x00,0x80,0xBA,0x22,0xFF, -0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE, -0xE4,0x00,0x22,0xC4,0x74,0x19,0xBE,0x04,0x00,0xE8,0x1C,0xFF,0xA1,0x62,0x12,0xE6, -0xFE,0xE4,0x00,0x22,0xC4,0x74,0xE4,0xBE,0x0C,0x00,0xE8,0x0B,0xFF,0xEB,0xDC,0xA1, -0x62,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,0xA1, -0x5E,0x12,0xE6,0xFE,0xE4,0x04,0x1F,0xE4,0x04,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF, -0x61,0xCF,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x80, -0x84,0xC4,0x74,0x08,0x33,0xF6,0xE8,0x53,0xFE,0xEB,0xEE,0x90,0xB8,0x00,0x80,0xBA, -0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1, -0x5E,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x08,0xBE,0x02,0x00,0xE8,0x2C,0xFE, -0xEB,0xED,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x60,0x1E, -0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x08, -0xBE,0x04,0x00,0xE8,0x06,0xFE,0xEB,0xED,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07, -0x1F,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x62,0x12,0xE6,0xFE, -0xE4,0x80,0x84,0xC4,0x74,0x08,0xBE,0x06,0x00,0xE8,0xE0,0xFD,0xEB,0xED,0xB8,0x00, -0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E, -0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0x18,0x33,0xF6,0xE8,0x37, -0xFE,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE5,0xBE,0x04,0x00,0xE8, -0xAA,0xFD,0xEB,0xDD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0xA1, -0x5C,0x12,0xE6,0xFE,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF, -0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE, -0xE4,0x00,0x22,0xC4,0x74,0x19,0xBE,0x04,0x00,0xE8,0xEC,0xFD,0xA1,0x62,0x12,0xE6, -0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE4,0xBE,0x06,0x00,0xE8,0x5F,0xFD,0xEB,0xDC,0xA1, -0x62,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0xA1,0x5E,0x12,0xE6,0xFE,0xE4, -0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x60,0x1E, -0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x18, -0x33,0xF6,0xE8,0x27,0xFD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0xE5, -0xBE,0x08,0x00,0xE8,0x92,0xFD,0xEB,0xDD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x00,0x22, -0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF, -0x61,0xCF,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE,0xE4,0x80, -0x84,0xC4,0x74,0x19,0xBE,0x02,0x00,0xE8,0xE2,0xFC,0xA1,0x62,0x12,0xE6,0xFE,0xE4, -0x00,0x22,0xC4,0x74,0xE4,0xBE,0x0C,0x00,0xE8,0x4D,0xFD,0xEB,0xDC,0xA1,0x62,0x12, -0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00, -0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1, -0x5C,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x18,0x33,0xF6,0xE8,0x9D,0xFC,0xA1, -0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE5,0xBE,0x04,0x00,0xE8,0x8C,0xFC, -0xEB,0xDD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0x07,0x1F,0xB8, -0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1, -0x5E,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x19,0xBE,0x02,0x00,0xE8,0x5C,0xFC, -0xA1,0x62,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE4,0xBE,0x06,0x00,0xE8,0x4B, -0xFC,0xEB,0xDC,0xA1,0x62,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0x07,0x1F, -0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E, -0xD8,0x90,0x2A,0xC0,0xE6,0xFE,0xE4,0xCE,0xA8,0x01,0x74,0x14,0x33,0xDB,0xE8,0xD5, -0xF6,0xEB,0xEF,0x90,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90, -0xF6,0x06,0x05,0x01,0x01,0x75,0xED,0xB0,0x01,0xE6,0xFE,0xE4,0xCE,0xA8,0x01,0x74, -0xE3,0xBB,0x04,0x00,0xE8,0xAF,0xF6,0xEB,0xC9,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E, -0xD8,0x90,0xFB,0x90,0xFA,0x2A,0xC0,0xE6,0xFE,0xE4,0xCE,0xA8,0x02,0x74,0x13,0x33, -0xDB,0xE8,0xCC,0xF8,0xEB,0xEC,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61, -0xCF,0x90,0xA8,0x04,0x74,0xF0,0x33,0xDB,0xE8,0x5B,0xF7,0xEB,0xD5,0x90,0x60,0x1E, -0x06,0x2B,0xC0,0x8E,0xD8,0x90,0xFB,0x90,0xFA,0xB0,0x01,0xE6,0xFE,0xE4,0xCE,0xA8, -0x02,0x74,0x15,0xBB,0x04,0x00,0xE8,0x97,0xF8,0xEB,0xEB,0x90,0xB8,0x00,0x80,0xBA, -0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0xA8,0x04,0x74,0xF0,0xBB,0x04,0x00,0xE8, -0x24,0xF7,0xEB,0xD2,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x09,0x9C,0x0E,0xE8,0x6B, -0xF2,0x90,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x29,0x9C,0x0E,0xE8,0x5D,0xF2,0x90, -0x72,0x20,0x72,0x20,0x72,0x20,0xCE,0x1D,0x92,0x1C,0xE6,0x1C,0x1A,0x1E,0x72,0x20, -0x82,0x1D,0xAE,0x1E,0x38,0x1F,0x72,0x20,0x82,0x1D,0x72,0x20,0x72,0x20,0x38,0x1F, -0x72,0x20,0x72,0x20,0x72,0x20,0xF4,0x1D,0xBC,0x1C,0x34,0x1D,0x64,0x1E,0x72,0x20, -0xA8,0x1D,0xF2,0x1E,0x78,0x1F,0x72,0x20,0xA8,0x1D,0x72,0x20,0x72,0x20,0x78,0x1F, -0xFC,0xB9,0x40,0x00,0x8C,0xCB,0xB8,0x64,0x20,0x2B,0xFF,0xAB,0x93,0xAB,0x93,0xE2, -0xFA,0xC7,0x06,0x4C,0x00,0xA8,0x11,0x83,0x3E,0x44,0x12,0x00,0x75,0x20,0xC7,0x06, -0x3C,0x00,0x08,0x4B,0xC7,0x06,0x30,0x00,0xBA,0x1F,0xC7,0x06,0x34,0x00,0xFA,0x1F, -0xF6,0x06,0x05,0x01,0x01,0x75,0x06,0xC7,0x06,0x38,0x00,0x2E,0x20,0xC3,0xC7,0x06, -0x3C,0x00,0x56,0x4B,0x33,0xDB,0x8A,0x1E,0x54,0x12,0xC1,0xE3,0x02,0x02,0x1E,0x56, -0x12,0x2E,0x8B,0x87,0x80,0x20,0xA3,0x30,0x00,0x8A,0x1E,0x55,0x12,0xC1,0xE3,0x02, -0x02,0x1E,0x57,0x12,0x2E,0x8B,0x87,0xA0,0x20,0xA3,0x34,0x00,0xC3,0x8B,0x86,0x9E, -0x00,0xE6,0xFE,0x86,0xC4,0xE6,0xD0,0xC3,0x8B,0x86,0x9E,0x00,0xE6,0xFE,0x33,0xD2, -0x8A,0xD4,0xC3,0x51,0xB9,0x10,0x27,0xE4,0x0A,0x90,0x90,0x84,0xC0,0x74,0x05,0xE2, -0xF6,0x59,0xF9,0xC3,0x59,0xF8,0xC3,0x84,0xC0,0x78,0x1E,0x51,0x8A,0xE8,0x8A,0xC8, -0xB8,0x01,0x00,0xD3,0xE0,0x09,0x86,0x98,0x00,0x3A,0xAE,0xA0,0x00,0x59,0x75,0x10, -0xE8,0xA9,0xE5,0x83,0x4E,0x26,0x02,0xF9,0xC3,0x98,0x89,0x86,0x98,0x00,0xEB,0xF0, -0xF8,0xC3,0x84,0xC0,0x78,0x12,0x51,0x8A,0xE0,0x8A,0xC8,0xB8,0x01,0x00,0xD3,0xE0, -0x59,0xF7,0xD0,0x21,0x86,0x98,0x00,0xC3,0xC7,0x86,0x98,0x00,0x00,0x00,0xC3,0x83, -0xC2,0x04,0x8A,0x86,0xA6,0x00,0x0C,0x04,0xEE,0x83,0xEA,0x04,0xC3,0xE8,0x93,0xFF, -0x72,0x04,0xB0,0x82,0xE6,0x0A,0xC3,0x8B,0x46,0x26,0xA8,0xFD,0x74,0x11,0x8A,0x86, -0xA5,0x00,0xA8,0x06,0x74,0x08,0x24,0xF9,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0xF6, -0xC4,0x01,0x74,0x0A,0x8A,0x86,0xA5,0x00,0x24,0xFB,0x0C,0x02,0xEB,0x0C,0xA8,0x02, -0x75,0x0F,0x8A,0x86,0xA5,0x00,0x24,0xFD,0x0C,0x04,0x3A,0x86,0xA5,0x00,0x75,0xD8, -0xC3,0x8A,0x86,0xA5,0x00,0xEB,0xCF,0xE4,0xD8,0x33,0xDB,0x8A,0xD8,0xC0,0xEB,0x04, -0x2E,0x8A,0x9F,0x66,0x17,0x88,0x9E,0xA9,0x00,0x8B,0x5E,0x26,0x80,0xE3,0x3F,0xF6, -0xC7,0x04,0x74,0x07,0xA8,0x10,0x75,0x03,0x80,0xCB,0x40,0xF6,0xC7,0x08,0x74,0x07, -0xA8,0x80,0x75,0x03,0x80,0xCB,0x40,0x88,0x5E,0x26,0x8A,0x86,0xA5,0x00,0xF6,0xC3, -0xFD,0x74,0x0D,0xA8,0x06,0x74,0x08,0x24,0xF9,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3, -0xF6,0xC7,0x01,0x74,0x04,0x0C,0x02,0xEB,0xF0,0xF6,0xC3,0x02,0x75,0xE9,0x0C,0x04, -0xEB,0xE7,0xC4,0x04,0xC4,0x04,0x85,0x04,0x59,0x04,0x48,0x04,0x41,0x04,0xC3,0x03, -0x82,0x03,0x41,0x03,0x82,0x02,0x57,0x02,0x41,0x02,0x82,0x01,0x41,0x01,0x82,0x00, -0x41,0x00,0x4E,0x02,0xAD,0x01,0x57,0x01,0x2D,0x00,0x2B,0x00,0x27,0x00,0x21,0x00, -0x16,0x00,0xF4,0x04,0xF4,0x04,0xA3,0x04,0x6F,0x04,0x5B,0x04,0x51,0x04,0xF4,0x03, -0xA3,0x03,0x51,0x03,0xA3,0x02,0x6D,0x02,0x51,0x02,0xA3,0x01,0x51,0x01,0xA3,0x00, -0x51,0x00,0x62,0x02,0xD9,0x01,0x6D,0x01,0x38,0x00,0x36,0x00,0x31,0x00,0x29,0x00, -0x1B,0x00,0x51,0x57,0xBF,0x02,0x00,0xEB,0x0F,0x90,0x51,0x56,0xBF,0x01,0x00,0xEB, -0x07,0x90,0x51,0x56,0xBF,0x03,0x00,0x90,0x3C,0x19,0x76,0x02,0xB0,0x17,0x98,0x8B, -0xF0,0x8A,0x82,0xC4,0x00,0x2A,0xE4,0x8B,0xF0,0x83,0xFE,0x18,0x73,0x46,0xD1,0xE6, -0x2E,0x8B,0x8C,0x52,0x22,0xF7,0x46,0x38,0x80,0x00,0x74,0x05,0x2E,0x8B,0x8C,0x82, -0x22,0xF7,0xC7,0x02,0x00,0x74,0x12,0x3B,0x8E,0x94,0x00,0x74,0x0C,0x89,0x8E,0x94, -0x00,0x8A,0xC5,0xE6,0xEC,0x8A,0xC1,0xE6,0xE4,0xF7,0xC7,0x01,0x00,0x74,0x12,0x3B, -0x8E,0x96,0x00,0x74,0x0C,0x89,0x8E,0x96,0x00,0x8A,0xC5,0xE6,0xF8,0x8A,0xC1,0xE6, -0xF0,0x5E,0x59,0xC3,0x77,0x06,0x8B,0x8E,0x8E,0x00,0xEB,0xC5,0x8B,0x8E,0x90,0x00, -0xEB,0xBF,0xD5,0x03,0xF6,0x00,0x3E,0x00,0x10,0x00,0x04,0x00,0xCA,0x04,0x33,0x01, -0x4D,0x00,0x14,0x00,0x05,0x00,0x01,0x03,0x05,0x07,0x09,0x00,0x01,0x02,0x03,0x04, -0x80,0x84,0x1E,0x00,0xA0,0x25,0x26,0x00,0x00,0x00,0x60,0x8B,0xF0,0x33,0xFF,0x2E, -0xA1,0x50,0x23,0x2E,0x8B,0x16,0x52,0x23,0xBB,0x32,0x23,0xF7,0x46,0x38,0x80,0x00, -0x74,0x0C,0x2E,0xA1,0x54,0x23,0x2E,0x8B,0x16,0x56,0x23,0xBB,0x3C,0x23,0xB9,0x05, -0x00,0x2E,0x3B,0x31,0x73,0x0A,0x47,0x47,0xE2,0xF7,0xB8,0xFF,0xFF,0xEB,0x1D,0x90, -0xD1,0xEF,0x2E,0x8A,0x8D,0x46,0x23,0x2A,0xED,0xD1,0xEA,0xD1,0xD8,0xE2,0xFA,0xF7, -0xF6,0x05,0x02,0x00,0xC1,0xE8,0x02,0x2E,0x8A,0xA5,0x4B,0x23,0x2E,0xA3,0x58,0x23, -0x61,0x2E,0xA1,0x58,0x23,0xC3,0x08,0x00,0x20,0x00,0x80,0x00,0x00,0x02,0x60,0x09, -0x08,0x00,0x20,0x00,0x80,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x01,0x00,0x02,0x00, -0x03,0x00,0x04,0x00,0x52,0x56,0x57,0x85,0xC0,0x74,0x05,0x3D,0x01,0x09,0x76,0x03, -0xB8,0x01,0x09,0xBF,0x5B,0x01,0xF7,0x46,0x38,0x80,0x00,0x74,0x03,0xBF,0xB2,0x01, -0x33,0xF6,0x2E,0x3B,0x84,0xB6,0x23,0x76,0x04,0x46,0x46,0xEB,0xF5,0xF7,0xE7,0x2E, -0x8B,0xBC,0xC0,0x23,0x03,0xC7,0x83,0xD2,0x00,0xD1,0xE7,0xF7,0xF7,0x2E,0x8A,0xA4, -0xCA,0x23,0x5F,0x5E,0x5A,0xC3,0xE4,0x3E,0x80,0xBE,0xC3,0x00,0x03,0x75,0x0C,0xF7, -0x46,0x7A,0x20,0x00,0x74,0x05,0x0C,0x80,0xE6,0x3E,0xC3,0x24,0x7F,0xE6,0x3E,0xC3, -0x24,0x03,0x88,0x86,0xC3,0x00,0x8A,0xE0,0xE4,0x10,0x24,0xFC,0x0A,0xC4,0xE6,0x10, -0x80,0x8E,0xA1,0x00,0x42,0xE8,0xCE,0xFF,0xC3,0x90,0x56,0x8B,0xF0,0x83,0xE6,0x07, -0xD1,0xE6,0x2E,0xFF,0xA4,0x58,0x24,0x90,0x68,0x24,0x6C,0x24,0x70,0x24,0x74,0x24, -0x78,0x24,0x87,0x24,0x87,0x24,0x87,0x24,0xB4,0x00,0xEB,0x0E,0xB4,0xC0,0xEB,0x0A, -0xB4,0x40,0xEB,0x06,0xB4,0x20,0xEB,0x02,0xB4,0xA0,0xE4,0x10,0x24,0x1F,0x0A,0xC4, -0xE6,0x10,0x80,0x8E,0xA1,0x00,0x42,0x5E,0xC3,0x90,0x3C,0x02,0x77,0x12,0x8A,0xE0, -0xE4,0x10,0x24,0xF3,0xC0,0xE4,0x02,0x0A,0xC4,0xE6,0x10,0x80,0x8E,0xA1,0x00,0x42, -0xC3,0x90,0x8B,0x5E,0x38,0x84,0xC0,0x74,0x1F,0x3C,0x02,0x74,0x20,0x83,0xCB,0x08, -0x8B,0x46,0x2E,0x3B,0x46,0x3C,0x77,0x0C,0xE8,0x88,0xFC,0x72,0x07,0xB0,0x24,0xE6, -0x0A,0x83,0xCB,0x10,0x89,0x5E,0x38,0xC3,0x83,0xE3,0xF7,0xEB,0xF7,0xF7,0xC3,0x10, -0x00,0x74,0xF5,0xE8,0x6D,0xFC,0x72,0xEC,0x8A,0x86,0xC0,0x00,0xE6,0x38,0xB0,0x23, -0xE6,0x0A,0xEB,0xE0,0x8B,0x5E,0x38,0x8B,0x46,0x2E,0x3B,0x46,0x3C,0xE4,0xD8,0x77, -0x0B,0x24,0xFE,0x80,0xCB,0x12,0xE6,0xD8,0x89,0x5E,0x38,0xC3,0x0C,0x01,0x80,0xCB, -0x02,0xEB,0xF3,0x50,0x33,0xDB,0xC1,0xE8,0x04,0x25,0x0F,0x0F,0x8A,0xD8,0x2E,0x8A, -0x87,0x66,0x17,0x8A,0xDC,0x2E,0x8A,0xA7,0x66,0x17,0x09,0x46,0x3E,0x58,0xC3,0x50, -0x33,0xDB,0xC1,0xE8,0x04,0x25,0x0F,0x0F,0x8A,0xD8,0x2E,0x8A,0x87,0x66,0x17,0x8A, -0xDC,0x2E,0x8A,0xA7,0x66,0x17,0xF7,0xD0,0x21,0x46,0x3E,0x58,0xC3,0x8B,0x46,0x3E, -0x33,0xDB,0x8A,0xD8,0x0A,0xDC,0x2E,0x8A,0x87,0x76,0x17,0xE6,0x2C,0x8A,0xE0,0xE4, -0x2A,0x24,0x0F,0x0A,0xC4,0xE6,0x2A,0x8A,0x86,0xA5,0x00,0x84,0xE4,0x75,0x0D,0xA8, -0x80,0x74,0x11,0x24,0x7F,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0xA8,0x80,0x75,0x04, -0x0C,0x80,0xEB,0xF1,0xC3,0x1E,0x60,0x33,0xC9,0x33,0xD2,0x33,0xF6,0x8E,0xD9,0x8D, -0xBE,0xFD,0x00,0x57,0x8B,0x05,0x84,0xC0,0x74,0x16,0x8B,0xD1,0x42,0x8B,0xFE,0x4F, -0x78,0x09,0x38,0xA3,0xE4,0x00,0x74,0x08,0x4F,0x79,0xF7,0x88,0xA2,0xE4,0x00,0x46, -0x5F,0x83,0xC7,0x09,0x41,0x83,0xF9,0x10,0x72,0xD9,0x89,0xB6,0x86,0x00,0x89,0x96, -0x84,0x00,0x61,0x1F,0xC3,0x53,0xC7,0x46,0x66,0x00,0x00,0x8B,0x46,0x64,0xA9,0x40, -0x00,0x74,0x0D,0xB3,0x00,0xA9,0x80,0x00,0x74,0x02,0xB3,0x7F,0x88,0x9E,0xC1,0x00, -0x32,0xDB,0xA9,0x02,0x00,0x74,0x03,0x80,0xCB,0x40,0xA9,0x00,0x40,0x74,0x03,0x80, -0xCB,0x02,0xA9,0x00,0x80,0x74,0x03,0x80,0xCB,0x01,0xA9,0x30,0x1E,0x74,0x03,0x80, -0xCB,0xBC,0xA9,0x00,0x20,0x74,0x03,0x80,0xCB,0x08,0xA9,0x04,0x01,0x74,0x03,0x80, -0xCB,0x10,0xA9,0x08,0x00,0x74,0x03,0x80,0xCB,0x20,0x88,0x9E,0xC2,0x00,0x5B,0xC3, -0x06,0x51,0x57,0x50,0x16,0x07,0x8D,0xBE,0xC4,0x00,0xB9,0x1F,0x00,0x33,0xC0,0xAA, -0x40,0xE2,0xFC,0x8B,0x86,0x92,0x00,0x89,0x86,0x8E,0x00,0x89,0x86,0x90,0x00,0x58, -0x5F,0x59,0x07,0xC3,0xE4,0xD8,0xC0,0xE8,0x04,0x53,0x25,0x0F,0x00,0x8B,0xD8,0x2E, -0x8A,0x87,0x66,0x17,0x88,0x86,0xA9,0x00,0x5A,0xC3,0x08,0x86,0xAC,0x00,0xC6,0x86, -0xBA,0x00,0x01,0xB0,0x0E,0xE8,0xEA,0xE9,0xC3,0xAD,0x36,0xA3,0xB4,0x13,0xAD,0x36, -0xA3,0xB6,0x13,0xAD,0x36,0xA3,0xB8,0x13,0x83,0xE9,0x06,0x36,0xF7,0x06,0xB6,0x13, -0x0F,0x00,0xC3,0x8A,0x46,0x26,0xF7,0x46,0x48,0x80,0x00,0x74,0x02,0x0C,0x10,0x88, -0x86,0xBD,0x00,0x32,0xC0,0x83,0x7E,0x1A,0x00,0x75,0x0E,0x8B,0x5E,0x40,0x43,0x80, -0xE3,0xFE,0x3B,0x5E,0x08,0x75,0x02,0x0C,0x01,0x83,0x7E,0x3A,0x00,0x75,0x0D,0x1E, -0xC5,0x5E,0x14,0x8B,0x1F,0x1F,0x85,0xDB,0x75,0x02,0x0C,0x02,0xF7,0x46,0x38,0x10, -0x00,0x74,0x02,0x0C,0x04,0x8B,0x5E,0x7A,0xF7,0xC3,0x02,0x00,0x74,0x02,0x0C,0x08, -0xF7,0xC3,0x04,0x00,0x74,0x02,0x0C,0x10,0xF7,0xC3,0x08,0x00,0x74,0x02,0x0C,0x20, -0xF7,0xC3,0x40,0x00,0x74,0x02,0x0C,0x40,0x88,0x86,0xBF,0x00,0xC3,0x90,0x6A,0x00, -0x1F,0xC6,0x06,0x93,0x12,0x0D,0x9C,0x0E,0xE8,0xF1,0xEB,0x90,0xB0,0x02,0xE6,0xDA, -0xF8,0xC3,0x33,0xC0,0xE6,0xDA,0xF8,0xC3,0xB0,0x01,0xE6,0xD8,0xF8,0xC3,0x33,0xC0, -0xE6,0xD8,0xF8,0xC3,0xB0,0xFF,0xE8,0x4E,0xFA,0xE8,0xA1,0xFA,0xF8,0xC3,0xAC,0x49, -0xE8,0xAF,0xFB,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x15,0xFD,0xF8,0xC3,0x90,0xAC,0x49, -0xE8,0x67,0xFD,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x1F,0xFD,0xF8,0xC3,0x90,0xAC,0x49, -0xE6,0x34,0xF8,0xC3,0xAC,0x49,0xE6,0x36,0xF8,0xC3,0xAC,0x49,0x3C,0x02,0x77,0x1F, -0x84,0xC0,0x75,0x1D,0xE4,0x14,0x24,0xEF,0xE6,0x14,0xE4,0x12,0x24,0x3F,0xE6,0x12, -0xE4,0x16,0xA8,0x04,0x74,0x09,0xE8,0xEA,0xF9,0x72,0x04,0xB0,0x18,0xE6,0x0A,0xF8, -0xC3,0x8A,0xE0,0xE4,0x14,0x0C,0x10,0xE6,0x14,0xE4,0x12,0x0C,0xC0,0xF6,0xC4,0x01, -0x74,0x02,0x24,0x7F,0xE6,0x12,0xF8,0xC3,0xAC,0x49,0xE8,0x25,0xFD,0xF8,0xC3,0x90, -0xB8,0x00,0x40,0xE8,0x7D,0xFD,0xE8,0xB4,0xFD,0xE8,0xA8,0xFE,0xB0,0x01,0xE8,0xB9, -0xFE,0xF8,0xC3,0x90,0xB8,0x00,0x40,0xE8,0x85,0xFD,0xE8,0xA0,0xFD,0xF8,0xC3,0x90, -0xB8,0x00,0x10,0xE8,0x5D,0xFD,0xE8,0x94,0xFD,0xE8,0x88,0xFE,0xB0,0x08,0xE8,0x99, -0xFE,0xF8,0xC3,0x90,0xB8,0x00,0x10,0xE8,0x65,0xFD,0xE8,0x80,0xFD,0xF8,0xC3,0x90, -0xB8,0x00,0x80,0xE8,0x3D,0xFD,0xE8,0x74,0xFD,0xE8,0x68,0xFE,0xB0,0x02,0xE8,0x79, -0xFE,0xF8,0xC3,0x90,0xB8,0x00,0x80,0xE8,0x45,0xFD,0xE8,0x60,0xFD,0xF8,0xC3,0x90, -0xB8,0x00,0x20,0xE8,0x1D,0xFD,0xE8,0x54,0xFD,0xE8,0x48,0xFE,0xB0,0x04,0xE8,0x59, -0xFE,0xF8,0xC3,0x90,0xB8,0x00,0x20,0xE8,0x25,0xFD,0xE8,0x40,0xFD,0xF8,0xC3,0x90, -0xAC,0x49,0xE8,0x48,0x14,0xE4,0x3C,0x24,0xE7,0x0A,0xC4,0xE6,0x3C,0xF8,0xC3,0x90, -0xB8,0xFC,0x3B,0x89,0x46,0x7C,0xE4,0x3C,0x0C,0x18,0xE6,0x3C,0xF8,0xC3,0xE4,0x12, -0x0C,0x02,0xE6,0x12,0xF8,0xC3,0xE4,0x12,0x24,0xFD,0xEB,0xF6,0xE8,0xB5,0xFC,0xF8, -0xC3,0x90,0x83,0x66,0x38,0xFD,0xF8,0xC3,0xAC,0x49,0xA8,0x01,0x74,0x06,0x83,0x4E, -0x7A,0x20,0xEB,0x04,0x83,0x66,0x7A,0xDF,0xE8,0xCB,0xFB,0xF8,0xC3,0x90,0x8A,0x86, -0xA5,0x00,0x0C,0x02,0x24,0xFB,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x81,0x4E,0x26,0x01, -0x20,0xAC,0x49,0x32,0xE4,0x89,0x46,0x6E,0x83,0x4E,0x48,0x08,0x49,0x46,0xF9,0xC3, -0x8A,0x86,0xA5,0x00,0x0C,0x02,0x24,0xFB,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x81,0x4E, -0x26,0x01,0x20,0xAC,0xB4,0x0A,0xF6,0xE4,0xEB,0xD8,0xE8,0xFA,0x13,0xE4,0x3C,0x24, -0xF8,0x0A,0xC4,0xE6,0x3C,0xF8,0xC3,0x90,0xAD,0x49,0x49,0x89,0x46,0x64,0xA9,0x01, -0x00,0x74,0x1B,0x8B,0xD8,0x83,0xE3,0xFA,0x75,0x1A,0xA9,0x04,0x00,0x74,0x0F,0xE4, -0x3E,0x0C,0x02,0xE6,0x3E,0xB8,0x38,0x44,0x89,0x46,0x62,0xF8,0xC3,0x90,0xE4,0x3E, -0x24,0xFC,0xEB,0xEF,0xE4,0x3E,0x24,0xFC,0xE6,0x3E,0xE8,0xE8,0xFC,0xB8,0xAA,0x40, -0xEB,0xE6,0xE8,0x6E,0xF8,0x72,0x05,0xB0,0x18,0xE6,0x0A,0xF8,0xC3,0x90,0xAC,0x49, -0xE8,0xCF,0xF9,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0xCF,0xF9,0xF8,0xC3,0x90,0xE8,0x68, -0xFD,0x75,0x06,0x32,0xC0,0xE6,0xDA,0xF8,0xC3,0xB0,0x02,0xE6,0xDA,0x36,0xA0,0xB4, -0x13,0x24,0x10,0x34,0x10,0xE8,0x16,0x01,0x36,0xA1,0xB4,0x13,0xA9,0x01,0x00,0x74, -0x05,0xE8,0xFC,0xFE,0xEB,0x0E,0xA9,0x02,0x00,0x74,0x04,0x32,0xC0,0xEB,0x02,0xB0, -0x01,0xE8,0xDE,0xFE,0x36,0xA1,0xB4,0x13,0xE8,0xB5,0x13,0xE4,0x3C,0x24,0xF8,0x0A, -0xC4,0xE6,0x3C,0x36,0xA1,0xB4,0x13,0xC1,0xE8,0x05,0x25,0x01,0x00,0xE8,0xFA,0xFE, -0x36,0xA0,0xB5,0x13,0x24,0x10,0xE8,0x59,0xFB,0x32,0xC0,0x36,0x8A,0x26,0xB5,0x13, -0xF6,0xC4,0x04,0x74,0x09,0xFE,0xC0,0xF6,0xC4,0x08,0x74,0x02,0xFE,0xC0,0xE8,0xDB, -0xFD,0x36,0xA1,0xB6,0x13,0x25,0x0F,0x00,0xE8,0x57,0xF9,0x36,0xA1,0xB6,0x13,0xC1, -0xE8,0x04,0x25,0x03,0x00,0xE8,0xB8,0xFA,0x36,0xA1,0xB6,0x13,0xC1,0xE8,0x05,0x25, -0x02,0x00,0xE8,0x05,0xFB,0x36,0xA1,0xB6,0x13,0xF6,0xC4,0x01,0x75,0x04,0x32,0xC0, -0xEB,0x09,0x80,0xE4,0x02,0xD0,0xEC,0xB0,0x02,0x2A,0xC4,0xE8,0xAC,0xFA,0x36,0xF6, -0x06,0xB7,0x13,0x40,0x74,0x05,0xE8,0x83,0xFE,0xEB,0x03,0xE8,0x84,0xFE,0x36,0xF6, -0x06,0xB7,0x13,0x20,0x74,0x05,0xE8,0x65,0xFE,0xEB,0x03,0xE8,0x68,0xFE,0xF8,0xC3, -0xE4,0x12,0x0C,0x01,0xE6,0x12,0xF8,0xC3,0xE4,0x12,0x24,0xFE,0xEB,0xF6,0xE4,0x14, -0x24,0xF0,0x0C,0x05,0xE6,0x14,0xE4,0x2A,0x24,0xF0,0x0C,0x06,0xE6,0x2A,0xF8,0xC3, -0xE4,0x2A,0x24,0xF0,0xE6,0x2A,0xE4,0x14,0x24,0xF0,0x0C,0x07,0xE6,0x14,0xF8,0xC3, -0xAD,0x49,0x49,0xE8,0x64,0xF9,0x89,0x86,0x8E,0x00,0xF8,0xC3,0xAD,0x49,0x49,0xE8, -0x58,0xF9,0x89,0x86,0x90,0x00,0xF8,0xC3,0x83,0x4E,0x26,0x04,0xE8,0xA8,0xF7,0xF8, -0xC3,0x90,0x83,0x66,0x26,0xFB,0xE8,0x9E,0xF7,0xF8,0xC3,0x90,0xAC,0x49,0x84,0xC0, -0x75,0x0D,0xE4,0x10,0x24,0xEF,0xE6,0x10,0x80,0x8E,0xA1,0x00,0x42,0xF8,0xC3,0xE4, -0x10,0x0C,0x10,0xEB,0xF1,0x90,0xAC,0x49,0x3C,0x02,0x76,0x02,0x32,0xC0,0xC0,0xE0, -0x04,0xA8,0x20,0x74,0x02,0x0C,0x08,0x24,0x18,0x8A,0xE0,0xE4,0x12,0x24,0xE7,0x0A, -0xC4,0xE6,0x12,0x80,0x8E,0xA1,0x00,0x44,0xF8,0xC3,0xAC,0x49,0x88,0x86,0xC0,0x00, -0xF8,0xC3,0xAC,0x49,0xE6,0x3A,0xF8,0xC3,0xAC,0x49,0x84,0xC0,0x74,0x08,0xE4,0x12, -0x0C,0x04,0xE6,0x12,0xF8,0xC3,0xE4,0x12,0x24,0xFB,0xEB,0xF6,0xAC,0x49,0xE8,0xD6, -0xF6,0x73,0x03,0xE8,0x27,0xF7,0xF8,0xC3,0xE4,0x12,0xA8,0x02,0x74,0x04,0x24,0xFD, -0xE6,0x12,0xB8,0xF0,0x00,0xE8,0x87,0xFA,0x81,0x66,0x26,0xFF,0xF3,0xE8,0x57,0xF7, -0xE8,0x9A,0xFA,0xF8,0xC3,0x90,0xB8,0x80,0x00,0xE8,0x57,0xFA,0x80,0x4E,0x27,0x08, -0xE8,0x44,0xF7,0xE8,0x87,0xFA,0xF8,0xC3,0xB8,0x80,0x00,0xE8,0x61,0xFA,0x81,0x66, -0x26,0xFF,0xF7,0xE8,0x31,0xF7,0xE8,0x74,0xFA,0xF8,0xC3,0x90,0xB8,0x10,0x00,0xE8, -0x31,0xFA,0x80,0x4E,0x27,0x04,0xE8,0x1E,0xF7,0xE8,0x61,0xFA,0xF8,0xC3,0xB8,0x10, -0x00,0xE8,0x3B,0xFA,0x81,0x66,0x26,0xFF,0xFB,0xE8,0x0B,0xF7,0xE8,0x4E,0xFA,0xF8, -0xC3,0x90,0x33,0xC0,0xAC,0x49,0x3C,0x01,0x73,0x04,0xB0,0x01,0xEB,0x06,0x3C,0x0C, -0x76,0x02,0xB0,0x0C,0x89,0x46,0x1C,0xF8,0xC3,0x90,0x81,0x4E,0x26,0x00,0x20,0x8A, -0x86,0xA5,0x00,0x0C,0x02,0x24,0xFB,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x83,0x4E,0x26, -0x01,0xF8,0xC3,0x90,0x81,0x4E,0x26,0x00,0x40,0x8A,0x86,0xA5,0x00,0x0C,0x02,0x88, -0x86,0xA5,0x00,0xE6,0x0C,0xF8,0xC3,0x90,0xAC,0x49,0x50,0xE8,0x05,0xF6,0x58,0x72, -0x08,0xE6,0x38,0xB0,0x23,0xE6,0x0A,0xF8,0xC3,0xF9,0xC3,0x90,0xAC,0x50,0xAD,0xE8, -0x82,0xF8,0x5A,0xF6,0xC2,0x01,0x74,0x12,0x39,0x86,0x96,0x00,0x74,0x0C,0x89,0x86, -0x96,0x00,0xE6,0xF0,0x86,0xE0,0xE6,0xF8,0x86,0xE0,0xF6,0xC2,0x02,0x74,0x10,0x39, -0x86,0x94,0x00,0x74,0x0A,0x89,0x86,0x94,0x00,0xE6,0xE4,0x86,0xE0,0xE6,0xEC,0x83, -0xE9,0x03,0xC3,0x90,0xE4,0x16,0x88,0x86,0xBC,0x00,0xE8,0xE6,0xFA,0x33,0xDB,0xE4, -0x0C,0xA8,0x06,0x74,0x03,0x80,0xCB,0x01,0xA8,0x10,0x74,0x03,0x80,0xCB,0x02,0xA8, -0x80,0x74,0x03,0x80,0xCB,0x04,0xE4,0x12,0x8A,0xE0,0x24,0x18,0x0A,0xD8,0xE4,0xDA, -0xF6,0xC4,0x02,0x74,0x07,0xA8,0x40,0x75,0x03,0x80,0xCB,0x20,0xA8,0x02,0x75,0x09, -0xE4,0x2A,0xA8,0x0F,0x74,0x03,0x80,0xCB,0x40,0xF7,0x46,0x38,0x02,0x00,0x74,0x09, -0xE4,0xD8,0xA8,0x01,0x75,0x03,0x80,0xCB,0x80,0x88,0x9E,0xBE,0x00,0xFE,0x86,0xB4, -0x00,0xB0,0x0A,0xE8,0x5C,0xE4,0xF8,0xC3,0xAC,0x49,0x3C,0x02,0x74,0x41,0x77,0x1F, -0x50,0xE8,0x4F,0xF5,0x58,0x72,0x0C,0x84,0xC0,0x74,0x0A,0xB0,0x12,0xE6,0x0A,0x80, -0x4E,0x38,0x01,0xF8,0xC3,0xB0,0x11,0xE6,0x0A,0x80,0x66,0x38,0xFE,0xF8,0xC3,0x8B, -0x46,0x38,0x25,0xFF,0xF7,0x89,0x46,0x38,0xA9,0x00,0x04,0x75,0xE6,0x8A,0x86,0xA5, -0x00,0xA8,0x10,0x75,0xDE,0x0C,0x10,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xF8,0xC3,0x81, -0x4E,0x38,0x00,0x08,0x8A,0x86,0xA5,0x00,0xA8,0x10,0x74,0xC7,0x24,0xEF,0xEB,0xE7, -0xAD,0x49,0x49,0x3C,0x01,0x72,0x11,0x3C,0x0C,0x77,0x0D,0x50,0x8A,0xE0,0xE4,0x14, -0x25,0xF0,0x0F,0x0A,0xC4,0xE6,0x14,0x58,0x8A,0xC4,0x84,0xC0,0x74,0x02,0xE6,0x42, -0xF8,0xC3,0xE8,0xCF,0xF9,0xFE,0x86,0xB9,0x00,0xB0,0x0E,0xE8,0xD4,0xE3,0xF8,0xC3, -0x3A,0x86,0xAF,0x00,0x74,0x1F,0x88,0x86,0xAF,0x00,0x8A,0xE0,0x80,0xC2,0x06,0xB0, -0xBF,0xEE,0x80,0xEA,0x02,0x8A,0xC4,0xEE,0x8A,0x86,0xA8,0x00,0x80,0xC2,0x02,0xEE, -0x80,0xEA,0x06,0x8A,0xC4,0xC3,0x8B,0x46,0x3E,0x85,0xC0,0x8A,0x86,0xA5,0x00,0x74, -0x12,0xA8,0x08,0x75,0x0D,0x0C,0x08,0x88,0x86,0xA5,0x00,0x80,0xC2,0x02,0xEE,0x80, -0xEA,0x02,0xC3,0xA8,0x08,0x74,0xFB,0x24,0xF7,0xEB,0xEC,0x8B,0x46,0x26,0x84,0xC0, -0x74,0x16,0x8A,0x86,0xA5,0x00,0xA8,0x02,0x74,0x0D,0x24,0xFD,0x88,0x86,0xA5,0x00, -0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xC3,0x8A,0x86,0xA5,0x00,0xA8,0x02,0x75,0xF7, -0x0C,0x02,0xEB,0xE8,0x52,0x83,0xC2,0x0C,0xEC,0xC0,0xE8,0x04,0x88,0x86,0xA9,0x00, -0x8B,0x5E,0x26,0x80,0xE3,0x3F,0xF6,0xC7,0x04,0x74,0x07,0xA8,0x08,0x75,0x03,0x80, -0xCB,0x40,0xF6,0xC7,0x08,0x74,0x07,0xA8,0x02,0x75,0x03,0x80,0xCB,0x80,0x88,0x5E, -0x26,0x8A,0x86,0xA5,0x00,0x84,0xDB,0x74,0x10,0xA8,0x02,0x74,0x0A,0x24,0xFD,0x88, -0x86,0xA5,0x00,0x83,0xEA,0x0A,0xEE,0x5A,0xC3,0xA8,0x02,0x75,0xFA,0x0C,0x02,0xEB, -0xEE,0x90,0xFF,0xFF,0x00,0x48,0x00,0x30,0xBA,0x20,0xC4,0x1A,0x00,0x18,0x00,0x12, -0x00,0x0C,0x00,0x06,0x00,0x03,0x00,0x02,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00, -0x18,0x00,0xCD,0x01,0x00,0x01,0x80,0x00,0x10,0x00,0x10,0x00,0x0E,0x00,0x0C,0x00, -0x08,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x04,0x00,0x03,0x00,0x02,0x00,0x01,0x00, -0x52,0x51,0x56,0x3C,0x1E,0x77,0x47,0x98,0x8B,0xF0,0x8A,0x82,0xC4,0x00,0x32,0xE4, -0x83,0xFE,0x18,0x74,0x3D,0x83,0xFE,0x19,0x74,0x3E,0x83,0xFE,0x1E,0x77,0x2F,0xD1, -0xE6,0x2E,0x8B,0x8C,0x32,0x2D,0x3B,0x8E,0x94,0x00,0x74,0x22,0x89,0x8E,0x94,0x00, -0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x8A,0xE0,0x0C,0x80,0xEE,0x83,0xEA,0x06,0x8A, -0xC1,0xEE,0x83,0xC2,0x02,0x8A,0xC5,0xEE,0x83,0xC2,0x04,0x8A,0xC4,0xEE,0x5E,0x59, -0x5A,0xC3,0x8B,0x8E,0x8E,0x00,0xEB,0xCE,0x8B,0x8E,0x90,0x00,0xEB,0xC8,0x52,0x51, -0x3D,0x05,0x00,0x77,0x03,0xB8,0x05,0x00,0x8B,0xC8,0xBA,0x02,0x00,0xB8,0x00,0xD0, -0xF7,0xF1,0x05,0x01,0x00,0xD1,0xE8,0x59,0x5A,0xC3,0x8B,0x46,0x7A,0xA8,0x20,0x74, -0x0B,0x80,0xBE,0xC3,0x00,0x03,0x75,0x04,0x0C,0x01,0xEB,0x02,0x24,0xFE,0x89,0x46, -0x7A,0xC3,0x24,0x03,0x88,0x86,0xC3,0x00,0x8A,0xA6,0xA8,0x00,0x8A,0xDC,0x80,0xE4, -0xFC,0x0A,0xC4,0x3A,0xC3,0x74,0x0B,0x88,0x86,0xA8,0x00,0x83,0xC2,0x06,0xEE,0x83, -0xEA,0x06,0xE8,0xC5,0xFF,0xC3,0x00,0x08,0x18,0x38,0x28,0x90,0x3C,0x04,0x77,0x23, -0x32,0xE4,0x8B,0xD8,0x2E,0x8A,0x87,0x26,0x2E,0x8A,0xA6,0xA8,0x00,0x8A,0xDC,0x80, -0xE4,0xC7,0x0A,0xC4,0x3A,0xC3,0x74,0x0B,0x88,0x86,0xA8,0x00,0x83,0xC2,0x06,0xEE, -0x83,0xEA,0x06,0xC3,0x84,0xC0,0x74,0x02,0xB0,0x04,0x8A,0xA6,0xA8,0x00,0x8A,0xDC, -0x80,0xE4,0xFB,0x0A,0xC4,0x3A,0xC3,0x74,0x0B,0x88,0x86,0xA8,0x00,0x83,0xC2,0x06, -0xEE,0x83,0xEA,0x06,0xC3,0x90,0x8B,0x5E,0x38,0x84,0xC0,0x74,0x34,0x3C,0x02,0x74, -0x3B,0x8A,0x86,0xAF,0x00,0x0C,0x04,0xE8,0xE6,0xFD,0x8B,0x46,0x2E,0x3B,0x46,0x3C, -0x77,0x1B,0xF7,0xC3,0x00,0x04,0x75,0x15,0x81,0xCB,0x00,0x04,0x83,0xC2,0x02,0x8A, -0x86,0xA5,0x00,0x24,0xFA,0x88,0x86,0xA5,0x00,0xEE,0x83,0xEA,0x02,0x89,0x5E,0x38, -0xC3,0x8A,0x86,0xAF,0x00,0x24,0xFB,0xE8,0xB6,0xFD,0xEB,0xF1,0xF7,0xC3,0x10,0x00, -0x74,0xEF,0xEB,0xED,0x83,0xC2,0x0C,0xEC,0x83,0xEA,0x0C,0xC0,0xE8,0x04,0x88,0x86, -0xA9,0x00,0xC3,0x90,0x8A,0x86,0xA7,0x00,0x0C,0x01,0x88,0x86,0xA7,0x00,0x8B,0xDA, -0x80,0xC2,0x08,0xEE,0x8B,0xD3,0xF8,0xC3,0x8A,0x86,0xA7,0x00,0x24,0xFE,0xEB,0xEA, -0x8A,0x86,0xA7,0x00,0x0C,0x02,0xEB,0xE2,0x8A,0x86,0xA7,0x00,0x24,0xFD,0xEB,0xDA, -0xB0,0xFF,0xE8,0x52,0xF2,0xE8,0x97,0xF2,0xF8,0xC3,0xAC,0x49,0xE8,0x61,0xFE,0xF8, -0xC3,0x90,0xAC,0x49,0xE8,0xEB,0xFE,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x35,0xFF,0xF8, -0xC3,0x90,0xAC,0x49,0xE8,0x05,0xFF,0xF8,0xC3,0x90,0x52,0x83,0xC2,0x06,0xB0,0xBF, -0xEE,0x52,0x83,0xC2,0x02,0xAC,0x49,0xEE,0x5A,0x8A,0x86,0xA8,0x00,0xEE,0x5A,0xF8, -0xC3,0x90,0x52,0x83,0xC2,0x06,0xB0,0xBF,0xEE,0x52,0x83,0xC2,0x06,0xEB,0xE6,0x90, -0xAC,0x49,0x3C,0x02,0x77,0x0D,0x84,0xC0,0x75,0x0B,0x8A,0x86,0xAF,0x00,0x24,0xFD, -0xE8,0x0D,0xFD,0xF8,0xC3,0x50,0x8A,0x86,0xAF,0x00,0x0C,0x02,0xE8,0x01,0xFD,0x5B, -0x83,0xC2,0x08,0x8A,0x86,0xA7,0x00,0xF6,0xC3,0x01,0x74,0x0C,0x24,0xDF,0x88,0x86, -0xA7,0x00,0xEE,0x83,0xEA,0x08,0xF8,0xC3,0x0C,0x20,0xEB,0xF2,0xAC,0x49,0xE8,0xE5, -0xFE,0xF8,0xC3,0x90,0xB8,0x00,0x40,0xE8,0x69,0xF5,0xE8,0xF9,0xFC,0xE8,0x24,0xFF, -0xB0,0x01,0xE8,0xA5,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x40,0xE8,0x71,0xF5,0xE8,0xE5, -0xFC,0xF8,0xC3,0x90,0xB8,0x00,0x10,0xE8,0x49,0xF5,0xE8,0xD9,0xFC,0xE8,0x04,0xFF, -0xB0,0x08,0xE8,0x85,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x10,0xE8,0x51,0xF5,0xE8,0xC5, -0xFC,0xF8,0xC3,0x90,0xB8,0x00,0x80,0xE8,0x29,0xF5,0xE8,0xB9,0xFC,0xE8,0xE4,0xFE, -0xB0,0x02,0xE8,0x65,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x80,0xE8,0x31,0xF5,0xE8,0xA5, -0xFC,0xF8,0xC3,0x90,0xB8,0x00,0x20,0xE8,0x09,0xF5,0xE8,0x99,0xFC,0xE8,0xC4,0xFE, -0xB0,0x04,0xE8,0x45,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x20,0xE8,0x11,0xF5,0xE8,0x85, -0xFC,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x34,0x0C,0xF8,0xC3,0x90,0xB8,0xFC,0x3B,0x89, -0x46,0x7C,0xF8,0xC3,0x8A,0x86,0xAF,0x00,0x0C,0x80,0xE8,0x43,0xFC,0xF8,0xC3,0x90, -0x8A,0x86,0xAF,0x00,0x24,0x7F,0xEB,0xF2,0x8A,0x86,0xAF,0x00,0x0C,0x40,0xE8,0x2F, -0xFC,0xF8,0xC3,0x90,0x8A,0x86,0xAF,0x00,0x24,0xBF,0xEB,0xF2,0xAC,0x49,0xA8,0x01, -0x74,0x07,0x83,0x4E,0x7A,0x20,0xEB,0x05,0x90,0x83,0x66,0x7A,0xDF,0xE8,0x8A,0xFD, -0xF8,0xC3,0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x0C,0x40,0x88,0x86,0xA8,0x00,0xEE, -0x83,0xEA,0x06,0xAC,0x49,0x32,0xE4,0x89,0x46,0x6E,0x83,0x4E,0x26,0x01,0x83,0x4E, -0x48,0x08,0xB0,0x06,0xE8,0xBB,0xDF,0x49,0x46,0xF9,0xC3,0x90,0x83,0xC2,0x06,0x8A, -0x86,0xA8,0x00,0x0C,0x40,0x88,0x86,0xA8,0x00,0xEE,0x83,0xEA,0x06,0xAC,0xB4,0x0A, -0xF6,0xE4,0xEB,0xD0,0xE8,0xE0,0x0B,0xF8,0xC3,0x90,0xAD,0x49,0x49,0x89,0x46,0x64, -0xA9,0x01,0x00,0x74,0x19,0x8B,0xD8,0x83,0xE3,0xFA,0x75,0x0A,0xA9,0x04,0x00,0x74, -0x0D,0xB8,0xE2,0x3F,0xEB,0x0B,0xE8,0xEC,0xF4,0xB8,0xAA,0x40,0xEB,0x03,0xB8,0x38, -0x44,0x89,0x46,0x62,0xF8,0xC3,0x8A,0x86,0xAF,0x00,0xA8,0x02,0x74,0x0A,0x24,0xFD, -0xE8,0x8D,0xFB,0x0C,0x02,0xE8,0x88,0xFB,0xF8,0xC3,0xAC,0x49,0xE8,0x81,0xFC,0xF8, -0xC3,0x90,0xAC,0x49,0xE8,0x79,0xFC,0xF8,0xC3,0x90,0xE8,0x5C,0xF5,0x75,0x05,0xE8, -0xE6,0xFD,0xF8,0xC3,0xE8,0xCD,0xFD,0x36,0xA0,0xB4,0x13,0x24,0x10,0x34,0x10,0xE8, -0x26,0x01,0x36,0xA1,0xB4,0x13,0xA9,0x01,0x00,0x74,0x05,0xE8,0xFE,0xFE,0xEB,0x0E, -0xA9,0x02,0x00,0x74,0x04,0x32,0xC0,0xEB,0x02,0xB0,0x01,0xE8,0xE8,0xFE,0x36,0xA1, -0xB4,0x13,0xE8,0xAB,0x0B,0x36,0xA1,0xB4,0x13,0xC1,0xE8,0x05,0x25,0x01,0x00,0xE8, -0x0C,0xFF,0x36,0xA0,0xB5,0x13,0x24,0x10,0xE8,0x2B,0xFD,0x32,0xC0,0x36,0x8A,0x26, -0xB5,0x13,0xF6,0xC4,0x04,0x74,0x09,0xFE,0xC0,0xF6,0xC4,0x08,0x74,0x02,0xFE,0xC0, -0xE8,0xEF,0xFD,0x36,0xA1,0xB6,0x13,0x25,0x0F,0x00,0xE8,0x03,0xFC,0x36,0xA1,0xB6, -0x13,0xC1,0xE8,0x04,0x25,0x03,0x00,0xE8,0x88,0xFC,0x36,0xA1,0xB6,0x13,0xC1,0xE8, -0x05,0x25,0x02,0x00,0xE8,0xCD,0xFC,0x36,0xA1,0xB6,0x13,0xF6,0xC4,0x01,0x75,0x04, -0x32,0xC0,0xEB,0x09,0x80,0xE4,0x02,0xD0,0xEC,0xB0,0x02,0x2A,0xC4,0xE8,0x8C,0xFC, -0x36,0xF6,0x06,0xB7,0x13,0x40,0x74,0x05,0xE8,0x8D,0xFE,0xEB,0x03,0xE8,0x94,0xFE, -0x36,0xF6,0x06,0xB7,0x13,0x20,0x74,0x05,0xE8,0x69,0xFE,0xEB,0x03,0xE8,0x70,0xFE, -0xF8,0xC3,0xF8,0xC3,0x8B,0x46,0x38,0xA9,0x04,0x00,0x75,0x23,0x0D,0x04,0x00,0x89, -0x46,0x38,0x83,0xC2,0x08,0x8B,0x46,0x2E,0x3B,0x46,0x3C,0x73,0x14,0x83,0x4E,0x38, -0x10,0x8A,0x86,0xA7,0x00,0x24,0xFE,0x88,0x86,0xA7,0x00,0xEE,0x83,0xEA,0x08,0xF8, -0xC3,0x8A,0x86,0xA7,0x00,0x0C,0x01,0xEB,0xEE,0x90,0x8B,0x46,0x38,0xA9,0x04,0x00, -0x74,0x06,0x25,0xFB,0xFF,0x89,0x46,0x38,0xF8,0xC3,0xAD,0x49,0x49,0xE8,0xBE,0xFB, -0x89,0x86,0x8E,0x00,0xF8,0xC3,0xAD,0x49,0x49,0xE8,0xB2,0xFB,0x89,0x86,0x90,0x00, -0xF8,0xC3,0x83,0x4E,0x26,0x04,0xE8,0x92,0xFA,0xF8,0xC3,0x90,0x83,0x66,0x26,0xFB, -0xE8,0x88,0xFA,0xF8,0xC3,0x90,0xAC,0x49,0x84,0xC0,0x75,0x07,0x80,0x8E,0xA3,0x00, -0x04,0xF8,0xC3,0x80,0xA6,0xA3,0x00,0xFB,0xF8,0xC3,0xAC,0x49,0x83,0xC2,0x08,0x3C, -0x02,0x76,0x02,0x32,0xC0,0x3C,0x01,0x74,0x12,0x77,0x0B,0x8A,0x86,0xA7,0x00,0x24, -0xEF,0x88,0x86,0xA7,0x00,0xEE,0x83,0xEA,0x08,0xF8,0xC3,0x8A,0x86,0xA7,0x00,0x0C, -0x10,0xEB,0xEE,0x90,0x52,0x83,0xC2,0x06,0xB0,0xBF,0xEE,0x52,0x83,0xC2,0x04,0xAC, -0x49,0xEE,0x5A,0x8A,0x86,0xA8,0x00,0xEE,0x5A,0xF8,0xC3,0x90,0x52,0x83,0xC2,0x06, -0xB0,0xBF,0xEE,0x52,0x83,0xC2,0x08,0xEB,0xE6,0x90,0xAC,0x49,0xF8,0xC3,0xAC,0x49, -0xE8,0xB4,0xEE,0x73,0x03,0xE8,0xF7,0xEE,0xF8,0xC3,0x8A,0x86,0xAF,0x00,0x24,0x7F, -0xE8,0xBD,0xF9,0xB8,0xF0,0x00,0xE8,0x66,0xF2,0x81,0x66,0x26,0xFF,0xF3,0xE8,0x23, -0xFA,0xE8,0xD2,0xF9,0xF8,0xC3,0xB8,0x80,0x00,0xE8,0x37,0xF2,0x80,0x4E,0x27,0x08, -0xE8,0x11,0xFA,0xE8,0xC0,0xF9,0xF8,0xC3,0xB8,0x80,0x00,0xE8,0x41,0xF2,0x81,0x66, -0x26,0xFF,0xF7,0xE8,0xFE,0xF9,0xE8,0xAD,0xF9,0xF8,0xC3,0x90,0xB8,0x10,0x00,0xE8, -0x11,0xF2,0x80,0x4E,0x27,0x04,0xE8,0xEB,0xF9,0xE8,0x9A,0xF9,0xF8,0xC3,0xB8,0x10, -0x00,0xE8,0xFF,0xF1,0x81,0x66,0x26,0xFF,0xFB,0xE8,0xD8,0xF9,0xF8,0xC3,0xAC,0x49, -0xF8,0xC3,0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x0C,0x40,0x88,0x86,0xA8,0x00,0xEE, -0x83,0xEA,0x06,0xF8,0xC3,0x90,0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x24,0xBF,0xEB, -0xEA,0x90,0xAC,0x49,0x8A,0xE0,0x80,0xC2,0x0A,0xEC,0x80,0xEA,0x0A,0xA8,0x20,0x74, -0x05,0x8A,0xC4,0xEE,0xF8,0xC3,0x06,0x51,0x57,0x8B,0x4E,0x24,0xE3,0x34,0x49,0x89, -0x4E,0x24,0xFF,0x46,0x1A,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x8A,0xC4,0xAA,0x89,0x7E, -0x22,0x8B,0x46,0x26,0x24,0xFD,0x89,0x46,0x26,0x75,0x29,0x8A,0x86,0xA5,0x00,0xA8, -0x02,0x75,0x21,0x80,0xC2,0x02,0x0C,0x02,0x88,0x86,0xA5,0x00,0xEE,0x80,0xEA,0x02, -0xEB,0x12,0xC4,0x7E,0x00,0x3B,0x7E,0x1E,0x76,0x0A,0x4F,0x26,0x88,0x25,0x89,0x7E, -0x00,0xFF,0x46,0x1A,0x5F,0x59,0x07,0xF8,0xC3,0x90,0xAC,0xAD,0x83,0xE9,0x03,0x85, -0xC0,0x74,0x05,0x3D,0x00,0x20,0x72,0x05,0xB8,0xFF,0xFF,0xEB,0x03,0xC1,0xE0,0x03, -0x3B,0x86,0x94,0x00,0x74,0x26,0x89,0x86,0x94,0x00,0x8B,0xD8,0x52,0x83,0xC2,0x06, -0x8A,0x86,0xA8,0x00,0x8A,0xE0,0x0C,0x80,0xEE,0x83,0xEA,0x06,0x8A,0xC3,0xEE,0x83, -0xC2,0x02,0x8A,0xC7,0xEE,0x83,0xC2,0x04,0x8A,0xC4,0xEE,0x5A,0xF8,0xC3,0xB0,0x88, -0x88,0x86,0xBC,0x00,0xE8,0x8C,0xF2,0x33,0xDB,0x8A,0x86,0xA5,0x00,0xA8,0x02,0x74, -0x03,0x80,0xCB,0x01,0xA8,0x05,0x74,0x03,0x80,0xCB,0x02,0xA8,0x08,0x74,0x03,0x80, -0xCB,0x04,0xF6,0x86,0xA7,0x00,0x10,0x74,0x03,0x80,0xCB,0x10,0x8A,0x86,0xA9,0x00, -0xF6,0xC3,0x04,0x75,0x0A,0x83,0xC2,0x0C,0xEC,0x83,0xEA,0x0C,0xC0,0xE8,0x04,0x8A, -0xE0,0x8A,0x86,0xAF,0x00,0xA8,0x80,0x74,0x08,0xF6,0xC4,0x01,0x75,0x03,0x80,0xCB, -0x20,0xF6,0x86,0xA7,0x00,0x02,0x75,0x0A,0xF7,0x46,0x38,0x04,0x00,0x74,0x03,0x80, -0xCB,0x40,0x88,0x9E,0xBE,0x00,0xFE,0x86,0xB4,0x00,0xB0,0x0A,0xE8,0xF3,0xDB,0xF8, -0xC3,0xFE,0x86,0xB4,0x00,0xB0,0x0A,0xE8,0xE8,0xDB,0xF8,0xC3,0xAC,0x49,0x3C,0x02, -0x74,0x37,0x77,0x10,0x84,0xC0,0x74,0x06,0x80,0x4E,0x38,0x01,0xF8,0xC3,0x80,0x66, -0x38,0xFE,0xF8,0xC3,0x8B,0x46,0x38,0x25,0xFF,0xF7,0x89,0x46,0x38,0xA9,0x00,0x04, -0x75,0xEA,0x8A,0x86,0xA5,0x00,0xA8,0x01,0x75,0xE2,0x0C,0x05,0x83,0xC2,0x02,0x88, -0x86,0xA5,0x00,0xEE,0x83,0xEA,0x02,0xF8,0xC3,0x81,0x4E,0x38,0x00,0x08,0x8A,0x86, -0xA5,0x00,0xA8,0x01,0x74,0xC6,0x24,0xFA,0xEB,0xE2,0xAD,0x49,0x49,0xF8,0xC3,0x90, -0xE8,0x11,0xFA,0xFE,0x86,0xB9,0x00,0xB0,0x0E,0xE8,0x86,0xDB,0xF8,0xC3,0xB0,0xFF, -0xE8,0xBF,0xEC,0xF8,0xC3,0x90,0x83,0x66,0x7A,0xFB,0xB0,0x00,0xE8,0x73,0xDB,0xF8, -0xC3,0x90,0xAC,0x49,0xE8,0x53,0xD9,0x72,0x11,0x36,0x88,0x1E,0x1A,0x01,0x36,0xA0, -0x8E,0x12,0x0A,0xC3,0x52,0xBA,0x00,0x01,0xEE,0x5A,0xF8,0xC3,0xAC,0x49,0x32,0xE4, -0x36,0xA3,0x86,0x12,0x05,0x06,0x00,0x36,0x8B,0x1E,0x88,0x12,0x2B,0xD8,0x36,0x89, -0x1E,0x8A,0x12,0xF8,0xC3,0x90,0xAD,0x8B,0xD8,0xAD,0x83,0xE9,0x04,0x03,0xC3,0x2B, -0x46,0x76,0x89,0x46,0x78,0xF7,0x46,0x7A,0x02,0x00,0x74,0x0A,0x83,0x66,0x7A,0xFD, -0xB8,0x00,0x00,0xE8,0x1C,0xDB,0xF8,0xC3,0x06,0x16,0x07,0xAC,0x49,0x25,0x0F,0x00, -0x6B,0xC0,0x09,0x8D,0xBE,0xFD,0x00,0x03,0xF8,0xAC,0x49,0x25,0x0F,0x00,0xAA,0x85, -0xC0,0x74,0x08,0x2B,0xC8,0x51,0x8B,0xC8,0xF3,0xA4,0x59,0xE8,0x27,0xF0,0xE8,0x44, -0x03,0x07,0xF8,0xC3,0x33,0xC0,0xAC,0x49,0x36,0xA3,0xB2,0x13,0x36,0xA3,0xB0,0x13, -0xF8,0xC3,0x83,0x66,0x7A,0xEF,0xE8,0x2C,0x03,0xF8,0xC3,0x90,0x83,0x4E,0x7A,0x10, -0xEB,0xF4,0xE8,0x9B,0xF0,0xF8,0xC3,0x90,0xAD,0x3C,0x19,0x77,0x0E,0x3C,0x19,0x77, -0x0A,0x8B,0xF8,0x81,0xE7,0xFF,0x00,0x88,0xA6,0xC4,0x00,0xF8,0xC3,0x90,0x83,0x4E, -0x26,0x20,0xAC,0x49,0x32,0xE4,0xD1,0xE0,0x8B,0xD8,0xC1,0xE3,0x02,0x03,0xC3,0x89, -0x46,0x6E,0x83,0x4E,0x48,0x04,0xB0,0x06,0xE8,0x97,0xDA,0x49,0x46,0xF9,0xC3,0x90, -0xFE,0x86,0xB3,0x00,0xB0,0x0A,0xE8,0x89,0xDA,0xF8,0xC3,0x90,0x33,0xC0,0xAC,0x49, -0x6B,0xC0,0x0A,0x89,0x86,0x8A,0x00,0xF8,0xC3,0x90,0xAC,0x49,0x32,0xE4,0x3D,0x0A, -0x00,0x77,0x05,0xB8,0x0A,0x00,0xEB,0x08,0x3D,0x5A,0x00,0x72,0x03,0xB8,0x5A,0x00, -0x51,0xF7,0xD8,0x05,0x64,0x00,0x8B,0xC8,0x8B,0x46,0x44,0xF7,0xE1,0xB9,0x64,0x00, -0xF7,0xF1,0x89,0x46,0x46,0x59,0xF8,0xC3,0xAC,0x49,0xE8,0x85,0xEB,0xF8,0xC3,0x90, -0xAC,0x49,0x84,0xC0,0x75,0x07,0x81,0x66,0x38,0xFF,0xFD,0xF8,0xC3,0x81,0x4E,0x38, -0x00,0x02,0xF7,0x46,0x38,0x40,0x00,0x75,0x08,0x8A,0x86,0xA9,0x00,0x88,0x86,0xAA, -0x00,0xF8,0xC3,0x90,0x51,0x56,0xE8,0x7F,0x0C,0x5E,0x59,0xF8,0xC3,0x90,0xFE,0x86, -0xB6,0x00,0xB0,0x0A,0xE8,0x0B,0xDA,0xF8,0xC3,0x90,0xFE,0x86,0xB7,0x00,0xB0,0x0A, -0xE8,0xFF,0xD9,0xF8,0xC3,0x90,0xFE,0x86,0xB8,0x00,0xB0,0x0A,0xE8,0xF3,0xD9,0xF8, -0xC3,0x90,0x00,0x90,0x51,0x55,0xAC,0x2E,0xA2,0x52,0x36,0x33,0xC9,0xAD,0x8B,0xF9, -0xC1,0xE7,0x05,0xA9,0x01,0x00,0x74,0x23,0x2E,0x8B,0xAD,0x44,0x00,0x83,0x7E,0x08, -0x00,0x74,0x18,0x2E,0x80,0x3E,0x52,0x36,0x01,0x74,0x09,0x60,0xB0,0x04,0xE8,0xBB, -0x0C,0x61,0xEB,0x07,0x60,0xB0,0xFB,0xE8,0xEC,0x0C,0x61,0x47,0x47,0xD1,0xE8,0x75, -0xD2,0x41,0x83,0xF9,0x04,0x72,0xC6,0x5D,0x59,0x83,0xE9,0x05,0xF7,0x46,0x38,0x40, -0x00,0x74,0x05,0xE8,0x87,0xEA,0xF8,0xC3,0xE8,0x8D,0xEA,0xF8,0xC3,0x90,0x36,0xC6, -0x06,0xC8,0x13,0x01,0xF8,0xC3,0x33,0xC0,0xAC,0x49,0x36,0xA3,0x80,0x12,0xAC,0x49, -0x36,0x2B,0x06,0x88,0x12,0xF7,0xD8,0x36,0xA3,0x82,0x12,0xF8,0xC3,0x90,0xDE,0x26, -0xDE,0x26,0xEC,0x26,0xF2,0x26,0xF8,0x26,0xFE,0x26,0x04,0x27,0x0E,0x27,0x16,0x27, -0x1E,0x27,0x26,0x27,0x2E,0x27,0x34,0x27,0xBE,0x34,0xC6,0x34,0xD2,0x34,0x3A,0x27, -0x78,0x27,0x80,0x27,0x94,0x27,0xA0,0x27,0xB4,0x27,0xC0,0x27,0xD4,0x27,0xE0,0x27, -0xF4,0x27,0x00,0x28,0x10,0x28,0xEC,0x34,0xDE,0x26,0x1E,0x28,0x26,0x28,0x2C,0x28, -0x32,0x28,0x38,0x28,0x4E,0x28,0x8A,0x28,0x06,0x35,0x28,0x35,0x98,0x28,0xBE,0x28, -0xD2,0x28,0xDE,0x28,0xE6,0x28,0x54,0x35,0x62,0x35,0x6C,0x35,0xEE,0x28,0xC0,0x29, -0xC8,0x29,0xCE,0x29,0xE0,0x29,0x72,0x35,0x78,0x35,0xF0,0x29,0xFC,0x29,0x8E,0x35, -0x08,0x2A,0x12,0x2A,0x1C,0x2A,0xB0,0x35,0x36,0x2A,0xBC,0x35,0x5A,0x2A,0x62,0x2A, -0x68,0x2A,0xCA,0x35,0x7C,0x2A,0xF8,0x35,0x88,0x2A,0xA6,0x2A,0xB8,0x2A,0xCC,0x2A, -0xDE,0x2A,0xF2,0x2A,0x00,0x36,0x0A,0x2B,0x24,0x2B,0x24,0x36,0x38,0x2B,0x4C,0x2B, -0x84,0x2B,0x2E,0x36,0x3A,0x36,0x46,0x36,0x54,0x36,0xE8,0x2B,0xAE,0x36,0x40,0x2C, -0x62,0x2C,0xB6,0x36,0x70,0x28,0xDE,0x26,0xDE,0x26,0xD4,0x2E,0xE8,0x2E,0xF0,0x2E, -0xF8,0x2E,0x00,0x2F,0x0A,0x2F,0x12,0x2F,0x1A,0x2F,0x22,0x2F,0x2A,0x2F,0x42,0x2F, -0xBE,0x34,0xC6,0x34,0xD2,0x34,0x50,0x2F,0x8C,0x2F,0x94,0x2F,0xA8,0x2F,0xB4,0x2F, -0xC8,0x2F,0xD4,0x2F,0xE8,0x2F,0xF4,0x2F,0x08,0x30,0x14,0x30,0x1C,0x30,0xEC,0x34, -0xDE,0x26,0x24,0x30,0x30,0x30,0x38,0x30,0x44,0x30,0x4C,0x30,0x62,0x30,0xA4,0x30, -0x06,0x35,0x28,0x35,0xAA,0x30,0xCE,0x30,0xD6,0x30,0xEA,0x30,0xF2,0x30,0x54,0x35, -0x62,0x35,0x6C,0x35,0xFA,0x30,0xC2,0x31,0xC2,0x31,0xC4,0x31,0xFA,0x31,0x72,0x35, -0x78,0x35,0x0A,0x32,0x16,0x32,0x8E,0x35,0x22,0x32,0x2C,0x32,0x36,0x32,0xB0,0x35, -0x4A,0x32,0xBC,0x35,0x74,0x32,0x8C,0x32,0x9A,0x32,0xCA,0x35,0x9E,0x32,0xF8,0x35, -0xAA,0x32,0xC6,0x32,0xD8,0x32,0xEC,0x32,0xFE,0x32,0x0E,0x33,0x00,0x36,0x12,0x33, -0x26,0x33,0x24,0x36,0x32,0x33,0x9A,0x33,0xDE,0x33,0x2E,0x36,0x3A,0x36,0x46,0x36, -0x54,0x36,0x5C,0x34,0xAE,0x36,0xAA,0x34,0xB0,0x34,0xB6,0x36,0x8C,0x30,0xE3,0x28, -0xF7,0x46,0x38,0x40,0x00,0x75,0x32,0xE8,0xE3,0xE8,0x33,0xC0,0xAC,0x49,0x3D,0x5B, -0x00,0x77,0x19,0x8B,0xD8,0xD1,0xE3,0x2E,0xFF,0x97,0xCE,0x36,0x72,0x0B,0x85,0xC9, -0x75,0xE8,0x8B,0x46,0x48,0xE8,0x1A,0x0C,0xC3,0x4E,0x41,0xC3,0x6A,0x00,0x1F,0xC6, -0x06,0x93,0x12,0x0C,0x9C,0x0E,0xE8,0x63,0xDA,0xE8,0xBC,0xE8,0x33,0xC0,0xAC,0x49, -0x3D,0x5B,0x00,0x77,0xE7,0x8B,0xD8,0xD1,0xE3,0x2E,0xFF,0x97,0x86,0x37,0x72,0xD9, -0x85,0xC9,0x75,0xE8,0xC3,0xF7,0x46,0x7A,0x10,0x00,0x75,0x0F,0x83,0xBE,0x84,0x00, -0x00,0x74,0x08,0xB8,0x48,0x3A,0x89,0x86,0x80,0x00,0xC3,0x81,0xBE,0x80,0x00,0xEC, -0x3C,0x74,0xF7,0x83,0xBE,0x88,0x00,0x00,0x75,0x05,0xB8,0xEC,0x3C,0xEB,0xE7,0xF7, -0x46,0x7A,0x08,0x00,0x75,0x40,0x1E,0x60,0x8B,0x8E,0x88,0x00,0x3B,0x4E,0x74,0x77, -0x33,0x3B,0x4E,0x78,0x77,0x2E,0xC4,0x7E,0x10,0x8B,0xDF,0x26,0x03,0x3D,0x47,0x47, -0x33,0xC0,0x8E,0xD8,0x8D,0xB6,0xF4,0x00,0x8B,0xC1,0xF7,0x46,0x7A,0x01,0x00,0x75, -0x1D,0xF3,0xA4,0x26,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xB0, -0x0C,0xE8,0x3E,0xD7,0x61,0x1F,0xC7,0x86,0x88,0x00,0x00,0x00,0xEB,0xAC,0xE3,0xE3, -0x50,0x90,0xAC,0x24,0x7F,0xAA,0xE2,0xFA,0x58,0xEB,0xD8,0x90,0x8B,0x8E,0x88,0x00, -0xE3,0x46,0x8B,0x9E,0x8A,0x00,0x85,0xDB,0x74,0x3E,0xBA,0x50,0xFF,0xED,0x2B,0x86, -0x82,0x00,0x3B,0xC3,0x72,0x37,0x8D,0xB6,0xF4,0x00,0xC4,0x7E,0x10,0x8B,0xDF,0x26, -0x03,0x3D,0x47,0x47,0x8B,0xC1,0x16,0x1F,0xF7,0x46,0x7A,0x01,0x00,0x75,0x24,0xF3, -0xA4,0x26,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xC7,0x86,0x88, -0x00,0x00,0x00,0xB0,0x0C,0xE8,0xDA,0xD6,0x83,0x66,0x7A,0xF7,0xC3,0xB0,0x00,0xE8, -0xD0,0xD6,0xC3,0xE3,0xDC,0x50,0xAC,0x24,0x7F,0xAA,0xE2,0xFA,0x58,0xEB,0xD2,0x90, -0x1E,0x60,0x33,0xC0,0x8E,0xD8,0x8D,0xB6,0xFD,0x00,0x8B,0x86,0x88,0x00,0x8B,0x96, -0x84,0x00,0x3A,0x04,0x75,0x10,0x8B,0xDE,0x46,0x8B,0xC8,0x8D,0xBE,0xF4,0x00,0xF3, -0xA6,0x74,0x66,0x8B,0xF3,0x90,0x83,0xC6,0x09,0x4A,0x75,0xE6,0x8D,0xB6,0xFD,0x00, -0x8B,0x96,0x84,0x00,0x3A,0x04,0x73,0x10,0x8B,0xDE,0x46,0x8B,0xC8,0x8D,0xBE,0xF4, -0x00,0xF3,0xA6,0x74,0x76,0x8B,0xF3,0x90,0x83,0xC6,0x09,0x4A,0x75,0xE6,0x8D,0xB6, -0xF4,0x00,0xAC,0xF7,0x46,0x7A,0x01,0x00,0x74,0x02,0x24,0x7F,0x1E,0xC5,0x5E,0x10, -0x8B,0x37,0x88,0x40,0x02,0x46,0x89,0x37,0xFF,0x4E,0x78,0xFF,0x46,0x76,0xFF,0x4E, -0x74,0x1F,0x8B,0x8E,0x88,0x00,0x49,0x89,0x8E,0x88,0x00,0xE3,0x43,0x8D,0xB6,0xF4, -0x00,0x8B,0xFE,0x46,0xF3,0xA4,0xE9,0x7D,0xFF,0xC5,0x76,0x10,0x8B,0x1C,0x85,0xDB, -0x74,0x08,0x03,0xF3,0x83,0xC6,0x03,0x83,0xE6,0xFE,0x8B,0x86,0x84,0x00,0x2B,0xC2, -0xB4,0x80,0x89,0x04,0x46,0x46,0xC7,0x04,0x00,0x00,0x89,0x76,0x10,0x83,0x4E,0x7A, -0x04,0xC7,0x86,0x88,0x00,0x00,0x00,0x61,0x1F,0xF9,0xC3,0x33,0xC0,0x61,0x1F,0xC3, -0xB0,0x80,0x84,0xC0,0x61,0x1F,0xC3,0x90,0x8B,0x4E,0x78,0x2B,0x8E,0x88,0x00,0x76, -0x27,0x89,0xB6,0x8C,0x00,0x8B,0x5E,0x74,0x3B,0xCB,0x72,0x02,0x8B,0xCB,0x3B,0xC8, -0x72,0x02,0x8B,0xC8,0x8B,0xC1,0xE3,0x44,0x33,0xD2,0x8E,0xC2,0x8B,0xD1,0x83,0xBE, -0x88,0x00,0x00,0x74,0x06,0xE9,0x8E,0x00,0x33,0xC0,0xC3,0x8B,0x5E,0x10,0x03,0x1F, -0x43,0x43,0x52,0xF7,0x46,0x7A,0x01,0x00,0x75,0x2A,0xAC,0x8D,0xBE,0xE4,0x00,0x8B, -0x8E,0x86,0x00,0xF2,0xAE,0x74,0x34,0x88,0x07,0x43,0x4A,0x75,0xED,0x58,0x8B,0x5E, -0x10,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0x8B,0xC6,0x2B,0x86, -0x8C,0x00,0xC3,0x90,0xAC,0x8D,0xBE,0xE4,0x00,0x8B,0x8E,0x86,0x00,0xF2,0xAE,0x74, -0x0A,0x24,0x7F,0x88,0x07,0x43,0x4A,0x75,0xEB,0xEB,0xD2,0x88,0x86,0xF4,0x00,0xC7, -0x86,0x88,0x00,0x01,0x00,0x58,0x2B,0xC2,0x74,0x0E,0x8B,0x5E,0x10,0x01,0x07,0x29, -0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0x40,0xE8,0x94,0xFE,0x72,0xBE,0x4A,0x75, -0x15,0x83,0xBE,0x8A,0x00,0x00,0x74,0xB4,0xBA,0x50,0xFF,0xED,0x89,0x86,0x82,0x00, -0x83,0x4E,0x7A,0x08,0xEB,0xA6,0x8D,0xBE,0xF4,0x00,0x03,0xBE,0x88,0x00,0xA4,0xFF, -0x86,0x88,0x00,0xE8,0x6A,0xFE,0x72,0x94,0x79,0x06,0x4A,0x74,0x8F,0xE9,0x5B,0xFF, -0x4A,0x74,0xCE,0xEB,0xE1,0x90,0x50,0xE8,0x11,0xCC,0x8B,0x46,0x74,0x39,0x46,0x72, -0x74,0x27,0x1E,0x56,0x51,0x33,0xC9,0xC5,0x76,0x0C,0xAD,0x74,0x10,0x78,0x09,0x03, -0xC8,0x05,0x01,0x00,0x24,0xFE,0x03,0xF0,0x3B,0x76,0x10,0x76,0xED,0x29,0x4E,0x76, -0x01,0x4E,0x78,0xE8,0x37,0xCC,0x59,0x5E,0x1F,0x58,0xC3,0x90,0xC4,0x7E,0x10,0x26, -0x8B,0x1D,0x83,0xC3,0x03,0x26,0x89,0x1D,0x4B,0x03,0xFB,0xAB,0x91,0xAA,0xB8,0x03, -0x00,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xC3,0x90,0xC4,0x7E,0x10,0x26, -0x8B,0x1D,0x43,0x26,0x89,0x1D,0x43,0x03,0xFB,0xAA,0xFF,0x4E,0x78,0xFF,0x46,0x76, -0xFF,0x4E,0x74,0xC3,0xE8,0xE5,0xFF,0xC3,0x80,0x81,0x84,0x85,0x82,0x83,0x86,0x87, -0x50,0x53,0x8A,0xDC,0x83,0xE3,0x0E,0xD1,0xEB,0x2E,0x8A,0x87,0x98,0x3B,0x08,0x86, -0xB0,0x00,0xFE,0x86,0xB1,0x00,0xB0,0x0A,0xE8,0x87,0xD4,0x5B,0x58,0xC3,0x50,0x8A, -0xC8,0xB8,0xFF,0x00,0xE8,0x95,0xFF,0x58,0xC3,0x90,0x8A,0x86,0xBB,0x00,0xE8,0xAB, -0xFF,0xC3,0xE8,0xCB,0xFF,0xE8,0xF2,0xFF,0xC3,0x90,0xE8,0xC3,0xFF,0xE8,0xB4,0xFF, -0xC3,0x90,0x33,0xC0,0xE8,0x95,0xFF,0xC3,0xB8,0xFF,0x00,0x33,0xC9,0xE8,0x6C,0xFF, -0xC3,0x90,0xB8,0xFF,0x01,0xB1,0x10,0xE8,0x62,0xFF,0xC3,0x90,0xC3,0xFC,0x3B,0xE2, -0x3B,0xF2,0x3B,0xF2,0x3B,0xFC,0x3B,0xE2,0x3B,0xE8,0x3B,0xE8,0x3B,0xFC,0x3B,0xE2, -0x3B,0xE8,0x3B,0xE8,0x3B,0xFC,0x3B,0xE2,0x3B,0xE2,0x3B,0xE2,0x3B,0x00,0x10,0x00, -0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00, -0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00, -0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x51,0x53,0x8B, -0x4E,0x38,0x81,0xE1,0xFF,0xEE,0xA8,0x04,0x74,0x04,0x81,0xC9,0x00,0x01,0x8A,0xE0, -0x80,0xE4,0x03,0x24,0x18,0xD0,0xE4,0x0A,0xC4,0x33,0xDB,0x8A,0xD8,0x2E,0x8B,0x87, -0xFD,0x3B,0x89,0x46,0x7C,0x2E,0x0B,0x8F,0x1D,0x3C,0x89,0x4E,0x38,0xD1,0xEB,0x2E, -0x8A,0xA7,0x3D,0x3C,0x5B,0x59,0xC3,0xAC,0x49,0x3C,0x01,0x72,0x1D,0x74,0x20,0x3C, -0x03,0x72,0x23,0x74,0x28,0x3C,0x08,0x72,0x2B,0x74,0x30,0x3C,0x20,0x72,0x37,0x74, -0x3A,0xBB,0xDA,0x3B,0x32,0xE4,0x89,0x5E,0x7E,0xC3,0xBB,0xA0,0x3B,0xEB,0xF5,0xBB, -0x94,0x3B,0xB4,0x01,0xEB,0xF0,0xBB,0xFC,0x3B,0xB4,0x02,0xEB,0xE9,0xBB,0xE2,0x3B, -0xB4,0x03,0xEB,0xE2,0xBB,0xBE,0x3B,0xB4,0x04,0xEB,0xDB,0xBB,0xCA,0x3B,0xAC,0x49, -0x88,0x86,0xBB,0x00,0xEB,0xCE,0xBB,0xD2,0x3B,0xEB,0xF3,0xBB,0xFC,0x3B,0xEB,0xC4, -0xA9,0x04,0x00,0x75,0xD1,0xA9,0x08,0x00,0x75,0xDA,0xEB,0xD1,0x8B,0x5E,0x74,0x8B, -0x4E,0x78,0x3B,0xCB,0x72,0x02,0x8B,0xCB,0x3B,0xC8,0x72,0x02,0x8B,0xC8,0x8B,0xC1, -0xE3,0x2C,0xC4,0x7E,0x10,0x8B,0xDF,0x26,0x03,0x3D,0x47,0x47,0xF7,0x46,0x7A,0x01, -0x00,0x75,0x1C,0xF7,0xC7,0x01,0x00,0x74,0x02,0x49,0xA4,0xD1,0xE9,0xF3,0xA5,0x73, -0x01,0xA4,0x26,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xC3,0x50, -0x53,0xBB,0x7F,0x7F,0xF7,0xC7,0x01,0x00,0x74,0x05,0x49,0xAC,0x22,0xC3,0xAA,0xD1, -0xE9,0xE3,0x1D,0x9C,0xAD,0x23,0xC3,0xAB,0x49,0x74,0x14,0xAD,0x23,0xC3,0xAB,0x49, -0x74,0x0D,0xAD,0x23,0xC3,0xAB,0x49,0x74,0x06,0xAD,0x23,0xC3,0xAB,0xE2,0xE5,0x9D, -0x73,0x04,0xAC,0x22,0xC3,0xAB,0x5B,0x58,0xEB,0xB8,0xE8,0xCE,0xC9,0x8B,0x5E,0x38, -0xF7,0xC3,0x10,0x04,0x75,0x01,0xC3,0xF7,0xC3,0x40,0x00,0x74,0x05,0xE8,0xB8,0xE3, -0xEB,0x03,0xE8,0xA8,0xE3,0x81,0x66,0x38,0xEF,0xFB,0xF6,0xC3,0x10,0x74,0x3C,0xF6, -0xC3,0x02,0x74,0x06,0xE4,0xD8,0x0C,0x01,0xE6,0xD8,0xF6,0xC3,0x04,0x74,0x11,0x83, -0xC2,0x08,0x8A,0x86,0xA7,0x00,0x0C,0x01,0xEE,0x88,0x86,0xA7,0x00,0x83,0xEA,0x08, -0xF6,0xC3,0x08,0x74,0x0F,0xE8,0x8B,0xE3,0x72,0x0A,0x8A,0x86,0xC0,0x00,0xE6,0x38, -0xB0,0x23,0xE6,0x0A,0xF7,0xC3,0x00,0x04,0x75,0x01,0xC3,0xF7,0xC3,0x00,0x08,0x75, -0xF9,0x8A,0x86,0xA5,0x00,0xF6,0xC3,0x40,0x75,0x0D,0xA8,0x10,0x75,0xEC,0x0C,0x10, -0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0xA8,0x01,0x75,0xDF,0x83,0xC2,0x02,0x0C,0x05, -0xEE,0x88,0x86,0xA5,0x00,0xC3,0xB0,0x00,0xE8,0x47,0xD2,0xEB,0x0F,0xB0,0x02,0xE8, -0x90,0x0E,0xEB,0x08,0x83,0x66,0x38,0xDF,0x83,0x4E,0x7A,0x02,0x33,0xC0,0x8E,0xD8, -0xFA,0xA0,0x92,0x12,0x40,0xA2,0x92,0x12,0x3C,0x05,0x72,0x1E,0xC6,0x06,0x92,0x12, -0x00,0xFB,0xB0,0x01,0xE8,0x6B,0x0E,0xFA,0xA1,0x26,0x01,0x23,0x06,0x2A,0x01,0xA8, -0x01,0x75,0x07,0xE8,0xE2,0x07,0xE8,0x61,0x09,0x90,0xB0,0x00,0xE8,0x37,0xD2,0xFB, -0x85,0xED,0x74,0xB9,0xFA,0xF7,0x46,0x7A,0x46,0x00,0x75,0xC0,0x8B,0x46,0x78,0x3D, -0x0A,0x00,0x72,0xB0,0x8B,0x4E,0x74,0x83,0xF9,0x50,0x72,0x9A,0x83,0x66,0x38,0xDF, -0xC5,0x76,0x14,0x8B,0x46,0x3A,0x85,0xC0,0x75,0x58,0xAD,0x85,0xC0,0x75,0x0F,0xE8, -0xF8,0xFE,0xF7,0x46,0x7A,0x08,0x00,0x74,0x93,0xE8,0xA0,0xFA,0xEB,0x8E,0x3B,0x76, -0x04,0x76,0x21,0xB9,0x02,0x00,0x39,0x4E,0x2E,0x77,0x05,0xC7,0x46,0x2E,0x00,0x00, -0x56,0x8B,0x76,0x2C,0x89,0x76,0x04,0xC7,0x04,0x00,0x00,0x46,0x46,0x89,0x76,0x2C, -0x29,0x4E,0x2E,0x5E,0x85,0xC0,0x79,0x17,0xF6,0xC4,0x10,0x74,0x05,0xFF,0x56,0x7C, -0xEB,0x03,0xFF,0x56,0x7E,0x89,0x76,0x14,0xB0,0x0C,0xE8,0x85,0xD1,0xEB,0x86,0x89, -0x46,0x3A,0xFF,0x96,0x80,0x00,0x29,0x46,0x3A,0x89,0x76,0x14,0xB0,0x0C,0xE8,0x71, -0xD1,0xE9,0x71,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x10,0x02, -0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0, -0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80, -0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, -0x80,0x80,0x80,0x80,0x4E,0x41,0x78,0x41,0xD0,0x41,0xF4,0x41,0x06,0x42,0x18,0x42, -0xC3,0x90,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x89,0x7E,0x6C,0x80,0x66,0x27,0xFD,0x8B, -0x56,0x24,0x83,0xFA,0x04,0x72,0xE9,0x83,0xEA,0x02,0x8B,0xD9,0x3B,0xCA,0x76,0x02, -0x8B,0xCA,0xB0,0x0A,0x57,0x51,0x8B,0xFE,0xF2,0xAE,0x8B,0xC1,0x59,0x5F,0x75,0x1E, -0x50,0x40,0x2B,0xC8,0x74,0x06,0x2B,0xD1,0x2B,0xD9,0xF3,0xA4,0x59,0x4B,0x4A,0x4A, -0xB0,0x0D,0xAA,0xA4,0x3B,0xCA,0x76,0x02,0x8B,0xCA,0xE3,0x13,0xEB,0xD4,0x2B,0xD9, -0xF7,0xC6,0x01,0x00,0x74,0x02,0xA4,0x49,0xD1,0xE9,0xF3,0xA5,0x73,0x01,0xA4,0x89, -0x7E,0x22,0x2B,0x7E,0x6C,0x29,0x7E,0x24,0x01,0x7E,0x1A,0x8B,0xCB,0x80,0x7E,0x26, -0x02,0x74,0x05,0x80,0x66,0x26,0xFD,0xC3,0x60,0xB0,0xFD,0xE8,0x18,0x03,0x61,0xC3, -0xC3,0x90,0xE8,0x7C,0x02,0x72,0xF9,0x90,0x83,0x4E,0x26,0x20,0x8B,0x46,0x6A,0x89, -0x46,0x6E,0x8B,0x46,0x48,0x0D,0x04,0x00,0x25,0xBF,0xFF,0x89,0x46,0x48,0xB0,0x06, -0xE8,0xBF,0xCF,0xC3,0x89,0x7E,0x22,0x2B,0x7E,0x6C,0x01,0x7E,0x1A,0x29,0x7E,0x24, -0x80,0x7E,0x26,0x02,0x74,0x05,0x83,0x66,0x26,0xFD,0xC3,0x60,0xB0,0xFD,0xE8,0xD5, -0x02,0x61,0xC3,0x90,0x8A,0xBE,0xC2,0x00,0xEB,0x24,0xF7,0x46,0x48,0x40,0x00,0x75, -0xB1,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x89,0x7E,0x6C,0x8B,0x56,0x24,0x83,0xEA,0x0A, -0x78,0x9E,0x03,0xD7,0x80,0x66,0x27,0xFD,0x33,0xC0,0x8A,0xBE,0xC2,0x00,0xE3,0xB4, -0x3B,0xFA,0x77,0xB0,0xAC,0x49,0x93,0x2E,0x8A,0x87,0xD4,0x3E,0x93,0x22,0xDF,0x75, -0x17,0xAA,0xE3,0xA0,0x3B,0xFA,0x77,0x9C,0xAC,0x49,0x93,0x2E,0x8A,0x87,0xD4,0x3E, -0x93,0x22,0xDF,0x75,0x03,0xAA,0xEB,0xD6,0xF6,0xC3,0x7F,0x75,0x05,0xFF,0x46,0x66, -0xEB,0xDF,0xF6,0xC3,0x40,0x75,0x0C,0x8B,0xD8,0x83,0xEB,0x08,0xD1,0xE3,0x2E,0xFF, -0xA7,0xD4,0x3F,0xFF,0x46,0x66,0x2C,0x20,0xEB,0xC7,0x85,0xC0,0x74,0x2C,0x89,0x46, -0x6A,0x83,0x4E,0x48,0x40,0x89,0x7E,0x22,0x2B,0x7E,0x6C,0x01,0x7E,0x1A,0x29,0x7E, -0x24,0x80,0x7E,0x26,0x02,0x74,0x08,0x83,0x66,0x26,0xFD,0xE8,0xA3,0x01,0xC3,0x60, -0xB0,0xFD,0xE8,0x31,0x02,0x61,0xE8,0x98,0x01,0xC3,0xE9,0x57,0xFF,0x90,0x8B,0x5E, -0x66,0x4B,0x78,0x03,0x89,0x5E,0x66,0xAA,0x8B,0x5E,0x64,0xF7,0xC3,0x00,0x20,0x75, -0x03,0xE9,0x40,0xFF,0xF7,0xC3,0x40,0x00,0x74,0x08,0x8A,0x86,0xC1,0x00,0xAA,0xE9, -0x32,0xFF,0xB8,0x32,0x00,0xEB,0xA3,0x90,0x8B,0x5E,0x66,0x89,0x5E,0x68,0x83,0xC3, -0x08,0x80,0xE3,0xF8,0x89,0x5E,0x66,0x8B,0x5E,0x64,0x81,0xE3,0x00,0x18,0x81,0xFB, -0x00,0x18,0x74,0x2D,0xAA,0x85,0xDB,0x74,0x25,0xF7,0x46,0x64,0x40,0x00,0x75,0x18, -0x81,0xFB,0x00,0x10,0x74,0x0C,0x8B,0x46,0x66,0x2B,0x46,0x68,0xC1,0xE0,0x04,0xE9, -0x68,0xFF,0xB8,0x64,0x00,0xE9,0x62,0xFF,0x8A,0x86,0xC1,0x00,0xAA,0xAA,0xE9,0xE3, -0xFE,0x51,0x8B,0x4E,0x66,0x2B,0x4E,0x68,0xB0,0x20,0xF3,0xAA,0x59,0xE9,0xD4,0xFE, -0x8B,0x5E,0x66,0x89,0x5E,0x68,0x8B,0x5E,0x64,0xF7,0xC3,0x24,0x00,0x74,0x10,0xC7, -0x46,0x66,0x00,0x00,0xF7,0xC3,0x04,0x00,0x74,0x05,0xB0,0x0D,0xAA,0xB0,0x0A,0xAA, -0xEB,0x48,0x90,0x90,0xAA,0xF7,0x46,0x64,0x00,0x40,0x74,0x06,0xB8,0xD0,0x07,0xE9, -0x18,0xFF,0xE9,0x9F,0xFE,0x90,0xAA,0xF7,0x46,0x64,0x00,0x80,0x74,0x06,0xB8,0xD0, -0x07,0xE9,0x06,0xFF,0xE9,0x8D,0xFE,0x90,0x8B,0x5E,0x66,0x89,0x5E,0x68,0x85,0xDB, -0x75,0x0C,0x8B,0x5E,0x64,0xF7,0xC3,0x10,0x00,0x74,0x06,0xE9,0x76,0xFE,0x8B,0x5E, -0x64,0xF7,0xC3,0x08,0x00,0x74,0x27,0xB0,0x0A,0xAA,0xF7,0xC3,0x20,0x00,0x75,0x1F, -0xF7,0xC3,0x00,0x01,0x75,0x03,0xE9,0x5B,0xFE,0xF7,0xC3,0x40,0x00,0x75,0x06,0xB8, -0x64,0x00,0xE9,0xC5,0xFE,0x8A,0x86,0xC1,0x00,0xAA,0xAA,0xE9,0x46,0xFE,0xAA,0xC7, -0x46,0x66,0x00,0x00,0xF7,0xC3,0x00,0x06,0x74,0xF1,0xF7,0xC3,0x40,0x00,0x74,0x19, -0x8A,0x86,0xC1,0x00,0x81,0xE3,0x00,0x06,0x81,0xFB,0x00,0x04,0x72,0x06,0x76,0x02, -0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xE9,0x1B,0xFE,0x81,0xE3,0x00,0x06,0x81,0xFB,0x00, -0x04,0x72,0x0E,0x76,0x06,0xB8,0x96,0x00,0xE9,0x7F,0xFE,0xB8,0x64,0x00,0xE9,0x79, -0xFE,0x8B,0x46,0x68,0xE9,0x73,0xFE,0x90,0x36,0x8B,0x0E,0xDA,0x12,0x83,0xF9,0x32, -0x73,0x1D,0x1E,0x06,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,0x8D,0x76,0x4C,0xBF,0xDC,0x12, -0x03,0xF9,0xA5,0xA5,0xA5,0x83,0xC1,0x06,0x89,0x0E,0xDA,0x12,0x07,0x1F,0xC3,0xB0, -0x08,0xE8,0x6E,0xCD,0xC3,0x90,0x83,0x66,0x48,0xFE,0xE8,0x93,0xC4,0xE8,0xC8,0xFF, -0xC3,0xF6,0x46,0x27,0x02,0x75,0x0F,0x9C,0xFA,0x83,0x7E,0x1A,0x00,0x74,0x09,0x80, -0x4E,0x27,0x01,0x9D,0xF9,0xC3,0xF8,0xC3,0x50,0x52,0xF7,0x46,0x38,0x40,0x00,0x74, -0x1D,0xE8,0x34,0xDE,0x83,0xC2,0x0A,0xEC,0xA8,0x40,0x75,0x27,0x83,0xEA,0x08,0x8A, -0x86,0xA5,0x00,0x0C,0x02,0x88,0x86,0xA5,0x00,0xEE,0x5A,0x58,0xEB,0xD1,0xE8,0x0C, -0xDE,0x8A,0x86,0xA5,0x00,0x24,0xFB,0x0C,0x02,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x5A, -0x58,0xEB,0xBC,0x80,0x4E,0x27,0x02,0x5A,0x58,0x9D,0xF8,0xC3,0x08,0x46,0x26,0x9C, -0xFA,0x8A,0x8E,0xA5,0x00,0xF7,0x46,0x38,0x40,0x00,0x75,0x14,0xF6,0xC1,0x06,0x74, -0x23,0xE8,0xD9,0xDD,0x8A,0xC1,0x24,0xF9,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x9D,0xC3, -0xF6,0xC1,0x02,0x74,0x0F,0xE8,0xD0,0xDD,0x83,0xC2,0x02,0x8A,0xC1,0x24,0xFD,0x88, -0x86,0xA5,0x00,0xEE,0x9D,0xC3,0x8B,0x5E,0x26,0x22,0xC3,0x88,0x46,0x26,0x74,0x01, -0xC3,0x80,0x66,0x27,0xFD,0x9C,0xFA,0x8A,0x8E,0xA5,0x00,0xF7,0x46,0x38,0x40,0x00, -0x75,0x16,0xF6,0xC1,0x04,0x75,0x0F,0xE8,0x93,0xDD,0x8A,0xC1,0x24,0xFD,0x0C,0x04, -0x88,0x86,0xA5,0x00,0xE6,0x0C,0x9D,0xC3,0xF6,0xC1,0x02,0x75,0xF9,0xE8,0x88,0xDD, -0x83,0xC2,0x0A,0xEC,0xA8,0x20,0x75,0x0E,0x83,0xEA,0x08,0x8A,0xC1,0x0C,0x02,0x88, -0x86,0xA5,0x00,0xEE,0x9D,0xC3,0x83,0xEA,0x0A,0x33,0xC9,0x8A,0x4E,0x1C,0x8B,0x46, -0x1A,0x3B,0xC8,0x73,0x1B,0x01,0x4E,0x2A,0x2B,0xC1,0x89,0x46,0x1A,0x1E,0xC5,0x76, -0x00,0xF3,0x6E,0x1F,0x89,0x76,0x00,0x83,0xC2,0x02,0x8A,0x86,0xA5,0x00,0xEB,0xCD, -0x85,0xC0,0x74,0x12,0x01,0x46,0x2A,0x8B,0xC8,0x1E,0xC5,0x76,0x00,0xF3,0x6E,0x1F, -0x89,0x76,0x00,0x89,0x4E,0x1A,0xF6,0xC7,0x01,0x75,0x23,0x80,0xCB,0x02,0x89,0x5E, -0x26,0xE8,0x08,0xC3,0x83,0xC2,0x02,0x8A,0x86,0xA5,0x00,0x24,0xFD,0xEE,0x88,0x86, -0xA5,0x00,0xF6,0xC7,0x10,0x75,0x05,0xB0,0x02,0xE8,0x16,0xCC,0x9D,0xC3,0x83,0xC2, -0x02,0x8A,0x86,0xA5,0x00,0xEB,0x86,0x90,0x8B,0xD1,0x8B,0x46,0x24,0x3B,0xC8,0x76, -0x02,0x8B,0xC8,0x2B,0xD1,0x2B,0xC1,0x8B,0xD9,0xE3,0x22,0x80,0x66,0x27,0xFD,0x8E, -0x46,0x02,0x8B,0x7E,0x22,0xF7,0xC6,0x01,0x00,0x74,0x02,0xA4,0x49,0xD1,0xE9,0xF3, -0xA5,0x73,0x01,0xA4,0x89,0x7E,0x22,0x89,0x46,0x24,0x01,0x5E,0x1A,0x8B,0xCA,0x80, -0x7E,0x26,0x02,0x74,0x05,0x80,0x66,0x26,0xFD,0xC3,0x60,0xB0,0xFD,0xE8,0xF6,0xFE, -0x61,0xC3,0x50,0xE4,0x0A,0x84,0xC0,0x75,0x0A,0x86,0x86,0xA1,0x00,0x84,0xC0,0x74, -0x0A,0xE6,0x0A,0x58,0x0C,0x20,0x89,0x46,0x48,0xF9,0xC3,0x58,0x24,0xDF,0x89,0x46, -0x48,0xF8,0xC3,0x90,0xFB,0xB0,0x02,0xE8,0xE8,0x07,0xFA,0xE8,0x2E,0x01,0xFB,0xB0, -0x01,0xE8,0xDE,0x07,0xFA,0xB0,0x02,0xE8,0xBC,0xCB,0xFB,0x85,0xED,0x74,0xE5,0xFA, -0x8E,0x5E,0x0A,0xFB,0x90,0xFA,0x8B,0x46,0x48,0x8B,0x76,0x40,0xA8,0x8C,0x75,0xDE, -0xA8,0x20,0x74,0x1A,0x50,0xE8,0x55,0xDC,0x58,0xE8,0xA6,0xFF,0x73,0x10,0xB0,0x02, -0xE8,0x5F,0xCB,0xEB,0xC9,0x90,0x25,0xFF,0x00,0x8B,0xC8,0xEB,0x36,0x90,0xA8,0x01, -0x75,0x22,0x46,0x83,0xE6,0xFE,0x3B,0x76,0x08,0x74,0x79,0xAD,0x8A,0xFC,0xB3,0xF0, -0x22,0xFB,0x3A,0xFB,0x74,0xE0,0x3A,0xBE,0xA0,0x00,0x74,0x2E,0xE8,0xD2,0xFD,0x73, -0x77,0xEB,0x9B,0x90,0x8A,0xE0,0x24,0xFC,0x88,0x46,0x48,0x8B,0x4E,0x4A,0xF6,0xC4, -0x02,0x74,0x1D,0xE8,0xBB,0xFD,0x72,0x86,0xE8,0x13,0xF3,0x89,0x76,0x40,0xE3,0x93, -0x83,0x4E,0x48,0x03,0x89,0x4E,0x4A,0xE9,0x74,0xFF,0x25,0xFF,0x0F,0x8B,0xC8,0x90, -0x8B,0x86,0x98,0x00,0x85,0xC0,0x74,0x1A,0x51,0x8A,0x8E,0xA0,0x00,0xC0,0xE9,0x04, -0xBA,0x01,0x00,0xD3,0xE2,0x59,0x23,0xC2,0x74,0x08,0x03,0xF1,0x89,0x76,0x40,0xE9, -0x61,0xFF,0xFF,0x56,0x62,0xE3,0xF5,0x83,0x4E,0x48,0x01,0x89,0x4E,0x4A,0x89,0x76, -0x40,0xE9,0x3A,0xFF,0x81,0x4E,0x26,0x00,0x10,0x8B,0x46,0x50,0x3B,0x46,0x46,0x77, -0x03,0xE8,0x52,0xFD,0xE9,0x27,0xFF,0x90,0x88,0xBE,0xA0,0x00,0xEB,0xAC,0x0A,0x06, -0x90,0x12,0x8A,0xE0,0xBA,0x06,0x01,0xB0,0x04,0xEE,0xEC,0x84,0xC0,0x75,0x12,0xB0, -0x04,0xEE,0x8A,0xC4,0xEE,0x32,0xE4,0xA8,0x80,0x74,0x06,0xC7,0x06,0x84,0x12,0x00, -0x00,0x88,0x26,0x90,0x12,0xC3,0x0A,0x06,0x90,0x12,0x8A,0xE0,0xBA,0x06,0x01,0xEC, -0xA8,0x01,0x75,0xED,0xBA,0x08,0x01,0x8A,0xC4,0xEE,0x32,0xE4,0xA8,0x80,0x74,0xE1, -0xC7,0x06,0x84,0x12,0x00,0x00,0x88,0x26,0x90,0x12,0xC3,0x90,0x36,0xF7,0x06,0x24, -0x01,0x01,0x00,0x75,0x30,0x36,0x8B,0x0E,0xDA,0x12,0x80,0xF9,0x36,0x73,0x26,0x33, -0xC0,0x8E,0xC0,0x8E,0xD8,0xBF,0xDC,0x12,0x03,0xF9,0xB0,0x08,0xE8,0x77,0xCA,0x85, -0xED,0x74,0x0E,0x8D,0x76,0x4C,0xA5,0xA5,0xA5,0x80,0xC1,0x06,0x80,0xF9,0x36,0x72, -0xE9,0x89,0x0E,0xDA,0x12,0xC3,0xC3,0x90,0xF7,0x06,0x26,0x01,0x01,0x00,0x75,0xF6, -0x8B,0x0E,0x20,0x13,0x85,0xC9,0x75,0xEE,0x33,0xC0,0x8E,0xC0,0x8E,0xD8,0xBF,0x24, -0x13,0xB9,0x36,0x00,0xB0,0x0A,0xE8,0x3D,0xCA,0x85,0xED,0x75,0x06,0xE9,0x12,0x01, -0xE9,0x0A,0x01,0x33,0xDB,0x8A,0x46,0x4C,0x8A,0xA6,0xB3,0x00,0xFE,0xCC,0x78,0x0E, -0x88,0xA6,0xB3,0x00,0x0A,0xDC,0xB4,0x0A,0xAB,0x83,0xE9,0x02,0x76,0xE2,0x8A,0xA6, -0xB2,0x00,0xFE,0xCC,0x78,0x0E,0x88,0xA6,0xB2,0x00,0x0A,0xDC,0xB4,0x08,0xAB,0x83, -0xE9,0x02,0x76,0xCC,0x8A,0xA6,0xB1,0x00,0xFE,0xCC,0x78,0x18,0x8A,0xBE,0xB0,0x00, -0x75,0x04,0x88,0xA6,0xB0,0x00,0x88,0xA6,0xB1,0x00,0x0A,0xDC,0x8A,0xE7,0xAB,0x83, -0xE9,0x02,0x76,0xAC,0x8A,0xA6,0xB4,0x00,0xFE,0xCC,0x78,0x1F,0x88,0xA6,0xB4,0x00, -0x0A,0xDC,0xB4,0x0B,0xAB,0x8A,0x86,0xBC,0x00,0x8A,0xA6,0xBD,0x00,0xAB,0x8B,0x86, -0xBE,0x00,0xAB,0x83,0xE9,0x06,0x76,0x88,0x8A,0x46,0x4C,0x8A,0xA6,0xB6,0x00,0xFE, -0xCC,0x78,0x19,0x88,0xA6,0xB6,0x00,0x0A,0xDC,0xB4,0x0C,0xAB,0xE8,0xDB,0xCB,0xAB, -0x8B,0x46,0x2A,0xAB,0x83,0xE9,0x06,0x76,0x74,0x8A,0x46,0x4C,0x8A,0xA6,0xB7,0x00, -0xFE,0xCC,0x78,0x19,0x88,0xA6,0xB7,0x00,0x0A,0xDC,0xB4,0x0D,0xAB,0xE8,0xBA,0xCB, -0xAB,0x8B,0x46,0x34,0xAB,0x83,0xE9,0x06,0x76,0x53,0x8A,0x46,0x4C,0x8A,0xA6,0xB8, -0x00,0xFE,0xCC,0x78,0x19,0x88,0xA6,0xB8,0x00,0x0A,0xDC,0xB4,0x0E,0xAB,0xA1,0x50, -0x12,0xAB,0xA1,0x52,0x12,0xAB,0x83,0xE9,0x06,0x76,0x32,0x8A,0x46,0x4C,0x8A,0xA6, -0xB5,0x00,0xFE,0xCC,0x78,0x18,0x88,0xA6,0xB5,0x00,0x0A,0xDC,0xB4,0x0F,0xAB,0x8B, -0x86,0x9A,0x00,0xAB,0x8B,0x86,0x9C,0x00,0xAB,0x83,0xE9,0x06,0x76,0x0F,0x84,0xDB, -0x75,0x03,0xE9,0xEF,0xFE,0xB0,0x0A,0xE8,0xF8,0xC8,0xE9,0xE7,0xFE,0xB0,0x0A,0xE8, -0xF0,0xC8,0xF7,0xD9,0x83,0xC1,0x36,0x8B,0xC1,0x0D,0x80,0x00,0x86,0xC4,0xA3,0x22, -0x13,0x41,0x41,0x89,0x0E,0x20,0x13,0xC3,0xA1,0x84,0x12,0x2B,0xC1,0x72,0x11,0xA3, -0x84,0x12,0xBE,0x22,0x13,0xD1,0xE9,0xF3,0x6F,0x90,0x89,0x0E,0x20,0x13,0xF8,0xC3, -0xF9,0xC3,0xC3,0x81,0xEF,0x6A,0x13,0x74,0xF9,0x8B,0xC7,0x0D,0x80,0x00,0x86,0xC4, -0xA3,0x68,0x13,0x47,0x47,0x89,0x3E,0x66,0x13,0xC3,0xF7,0x06,0x2A,0x01,0x01,0x00, -0x75,0xE0,0x8B,0x0E,0x66,0x13,0xE3,0x07,0x80,0xF9,0x20,0x77,0xD5,0x49,0x49,0x33, -0xC0,0x8E,0xC0,0x8E,0xD8,0xBF,0x6A,0x13,0x8B,0xF7,0x03,0xF9,0x83,0xC6,0x34,0x3B, -0xFE,0x77,0xC0,0xB0,0x0E,0xE8,0xAE,0xC8,0x85,0xED,0x74,0xB7,0x8A,0x46,0x4C,0x8A, -0xB6,0xB9,0x00,0xFE,0xCE,0x78,0x15,0x88,0xB6,0xB9,0x00,0x8A,0xA6,0xA9,0x00,0x80, -0xCC,0xC0,0xAB,0x84,0xF6,0x74,0x05,0xB0,0x0E,0xE8,0x56,0xC8,0x8A,0xB6,0xBA,0x00, -0xFE,0xCE,0x78,0xCB,0x8A,0x9E,0xA9,0x00,0x8A,0xBE,0xAB,0x00,0x8A,0x56,0x3F,0x8A, -0xF3,0x32,0xF7,0x0A,0xB6,0xAC,0x00,0xC6,0x86,0xAC,0x00,0x00,0x22,0xF2,0x74,0x4B, -0xF6,0xC6,0x08,0x74,0x0F,0xB4,0x02,0xF6,0xC3,0x08,0x75,0x02,0xB4,0x03,0xAB,0x80, -0xE6,0xF7,0x74,0x37,0xF6,0xC6,0x01,0x74,0x0F,0xB4,0x00,0xF6,0xC3,0x01,0x75,0x02, -0xB4,0x01,0xAB,0x80,0xE6,0xFE,0x74,0x23,0xF6,0xC6,0x02,0x74,0x0F,0xB4,0x04,0xF6, -0xC3,0x02,0x75,0x02,0xB4,0x05,0xAB,0x80,0xE6,0xFD,0x74,0x0F,0xF6,0xC6,0x04,0x74, -0x0A,0xB4,0x06,0xF6,0xC3,0x04,0x75,0x02,0xB4,0x07,0xAB,0xC6,0x86,0xBA,0x00,0x00, -0x88,0x9E,0xAB,0x00,0xE9,0x58,0xFF,0x90,0xA1,0x84,0x12,0x2B,0xC1,0x72,0x11,0xA3, -0x84,0x12,0xBE,0x68,0x13,0xD1,0xE9,0xF3,0x6F,0x90,0x89,0x0E,0x66,0x13,0xF8,0xC3, -0xF9,0xC3,0xA1,0x84,0x12,0x41,0x41,0x2B,0xC1,0x72,0x23,0xA3,0x84,0x12,0x8B,0xC1, -0x48,0x48,0x32,0xE4,0x0C,0x80,0x86,0xC4,0xEF,0x90,0x90,0x90,0x90,0x90,0xBE,0xDC, -0x12,0x49,0x49,0xD1,0xE9,0xF3,0x6F,0x90,0x89,0x0E,0xDA,0x12,0xF8,0xC3,0xF9,0xC3, -0x8A,0xC8,0x8A,0x46,0x4C,0xB4,0x01,0x83,0xEB,0x06,0xEF,0x90,0x90,0x90,0x90,0x90, -0xB8,0x01,0x00,0xEF,0x90,0x90,0x90,0x90,0x90,0x8A,0xC1,0xEF,0x90,0x90,0x90,0x90, -0x90,0xE9,0x97,0x00,0xE9,0xAC,0x00,0x33,0xC0,0x8E,0xD8,0x89,0x1E,0x84,0x12,0xC3, -0x36,0x8B,0x1E,0x84,0x12,0xFB,0x90,0xFA,0xB0,0x0C,0xE8,0x89,0xC7,0x85,0xED,0x74, -0xE6,0xC5,0x76,0x0C,0x83,0xFB,0x14,0x72,0xDB,0xFB,0x90,0xFA,0xAD,0x85,0xC0,0x78, -0xAF,0x74,0xE2,0x8B,0xFE,0x03,0xF8,0x36,0x8B,0x0E,0x86,0x12,0x3B,0xC1,0x77,0x02, -0x8B,0xC8,0x83,0xEB,0x04,0x3B,0xD9,0x77,0x02,0x8B,0xCB,0x33,0xC0,0x8A,0x46,0x4C, -0xEF,0x90,0x90,0x90,0x90,0x90,0x8B,0xC1,0xEF,0x90,0x90,0x90,0x90,0x90,0x41,0x80, -0xE1,0xFE,0x2B,0xD9,0x51,0xD1,0xE9,0xF3,0x6F,0x90,0x59,0x8B,0xC7,0x40,0x24,0xFE, -0x3B,0xC6,0x74,0x27,0x2B,0xFE,0x4E,0x4E,0x53,0x8B,0x5E,0x10,0x3B,0xF3,0x72,0x13, -0x03,0x1F,0x83,0xC3,0x03,0x80,0xE3,0xFE,0xC7,0x07,0x00,0x00,0x83,0x6E,0x74,0x02, -0x89,0x5E,0x10,0x5B,0x89,0x3C,0x89,0x76,0x0C,0xEB,0x89,0x89,0x76,0x0C,0x39,0x76, -0x10,0x77,0x81,0x72,0x08,0x83,0x3C,0x00,0x74,0x03,0xE9,0x77,0xFF,0xE8,0x0D,0xBE, -0xE9,0x62,0xFF,0x36,0x89,0x1E,0x84,0x12,0xB0,0x0C,0xE8,0xB5,0xC6,0x33,0xC0,0x8E, -0xD8,0xC3,0xA1,0x84,0x12,0x3D,0x10,0x00,0x72,0x77,0xBA,0x04,0x01,0x3B,0x06,0x88, -0x12,0x75,0x06,0xC7,0x06,0x7E,0x12,0x00,0x00,0x8B,0x0E,0xDA,0x12,0xE3,0x0B,0xE8, -0xD0,0xFE,0x72,0x57,0xC7,0x06,0x7E,0x12,0xFF,0x7F,0x8B,0x0E,0x20,0x13,0xE3,0x0B, -0xE8,0xA5,0xFD,0x72,0x46,0xC7,0x06,0x7E,0x12,0xFF,0x7F,0x8B,0x0E,0x66,0x13,0xE3, -0x0B,0xE8,0x94,0xFE,0x72,0x35,0xC7,0x06,0x7E,0x12,0xFF,0x7F,0xA1,0x28,0x01,0xA9, -0x01,0x00,0x75,0x03,0xE8,0xF9,0xFE,0x80,0x3E,0x8D,0x12,0x00,0x75,0x1D,0xA1,0x84, -0x12,0x3D,0x20,0x00,0x76,0x15,0x3B,0x06,0x82,0x12,0x76,0x09,0xA1,0x7E,0x12,0x3B, -0x06,0x80,0x12,0x72,0x0C,0x80,0x0E,0x90,0x12,0x80,0xC3,0xB0,0x80,0xFF,0x16,0x7C, -0x12,0xC3,0x80,0x0E,0x90,0x12,0x40,0xC3,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x17, -0x9C,0x0E,0xE8,0xB7,0xC8,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x20,0x9C,0x0E,0xE8, -0xAA,0xC8,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x16,0x9C,0x0E,0xE8,0x9D,0xC8,0x90, -0xBA,0x06,0x01,0xEC,0xA8,0x20,0x75,0xCA,0xFB,0x90,0xFA,0xBA,0x04,0x01,0xED,0x90, -0x90,0x90,0x90,0x90,0x3A,0x06,0x94,0x12,0x77,0xBE,0x33,0xDB,0x8A,0xD8,0xD1,0xE3, -0x2E,0x8B,0xAF,0x44,0x00,0xC4,0x7E,0x08,0x85,0xFF,0x74,0xB9,0xF6,0xC4,0xC0,0x75, -0x55,0x32,0xC0,0xC1,0xE0,0x02,0x80,0xE4,0xF0,0x8B,0xF0,0xED,0x90,0x90,0x90,0x90, -0x90,0x85,0xC0,0x74,0xBB,0x8B,0xC8,0x41,0x80,0xE1,0xFE,0x0B,0xC6,0x8B,0x5E,0x50, -0x4B,0x4B,0x2B,0xD9,0x78,0x9C,0xAB,0x8B,0xC1,0x40,0x40,0x01,0x46,0x4E,0xD1,0xE9, -0xF3,0x6D,0x90,0x89,0x5E,0x50,0x89,0x7E,0x08,0x8B,0x46,0x26,0x80,0xE4,0xEF,0x89, -0x46,0x26,0xF6,0xC4,0x01,0x75,0x0C,0xF7,0x46,0x48,0x0C,0x00,0x75,0x05,0xB0,0x02, -0xE8,0x7F,0xC5,0xE9,0x7A,0xFF,0x86,0xC4,0x8B,0xC8,0x83,0xE1,0x3F,0x41,0x80,0xE1, -0xFE,0xE3,0x0A,0x3C,0x80,0x72,0x09,0x24,0x3F,0xB4,0xF0,0xEB,0xB0,0xE9,0x60,0xFF, -0x25,0x3F,0x00,0x33,0xFF,0x8E,0xC7,0xBF,0x96,0x12,0x8B,0xF7,0xD1,0xE9,0xF3,0x6D, -0x90,0x8B,0xC8,0xE8,0x48,0xED,0xE9,0x47,0xFF,0x90,0x6A,0x00,0x1F,0xC6,0x06,0x93, -0x12,0x1B,0x9C,0x0E,0xE8,0xD5,0xC7,0x90,0x60,0x1E,0x06,0x33,0xC0,0x8E,0xD8,0x8E, -0xC0,0xBA,0x06,0x01,0xEC,0xA8,0x04,0x74,0xE1,0xB0,0x06,0xEE,0xEC,0xA2,0x8C,0x12, -0xA8,0x40,0x74,0x11,0xA1,0x88,0x12,0xA3,0x84,0x12,0xC6,0x06,0x8D,0x12,0x00,0xE8, -0x60,0xFE,0xA0,0x8C,0x12,0xA8,0x80,0x74,0x03,0xE8,0x04,0xFF,0xB8,0x00,0x80,0xBA, -0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x1B, -0x9C,0x0E,0xE8,0x87,0xC7,0x90,0x60,0x1E,0x06,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,0xBA, -0x06,0x01,0xEC,0xA8,0x04,0x74,0xE1,0xBA,0x08,0x01,0xEC,0xA2,0x8C,0x12,0xA8,0x40, -0x74,0x11,0xA1,0x88,0x12,0xA3,0x84,0x12,0xC6,0x06,0x8D,0x12,0x00,0xE8,0x12,0xFE, -0xA0,0x8C,0x12,0xA8,0x80,0x74,0x03,0xE8,0xB6,0xFE,0xB8,0x00,0x80,0xBA,0x22,0xFF, -0xEF,0x07,0x1F,0x61,0xCF,0x90,0xEE,0x86,0xE0,0xEE,0x86,0xE0,0xEC,0x86,0xE0,0xEC, -0x86,0xE0,0x80,0xE1,0xFE,0xF3,0x6C,0x90,0x80,0xE1,0xFE,0xF3,0x6E,0x90,0x05,0x00, -0x75,0x47,0xA8,0x4B,0x05,0x00,0x75,0x48,0xA8,0x4B,0x05,0x00,0xA3,0x48,0xA8,0x4B, -0x05,0x00,0x35,0x49,0xA8,0x4B,0x06,0x00,0x98,0x48,0x96,0x4B,0x06,0x00,0xBA,0x48, -0x96,0x4B,0x06,0x00,0xC3,0x48,0x96,0x4B,0x06,0x00,0xCB,0x48,0x96,0x4B,0x06,0x00, -0x20,0x49,0x96,0x4B,0x06,0x00,0x28,0x49,0x96,0x4B,0x06,0x00,0x4E,0x4A,0x9C,0x4B, -0x06,0x00,0x7B,0x4A,0x9C,0x4B,0x05,0x00,0x9E,0x4A,0xA2,0x4B,0x05,0x00,0xEC,0x4A, -0xA2,0x4B,0x00,0x00,0x1E,0x06,0x83,0x3E,0x44,0x12,0x00,0x74,0x09,0xA0,0x06,0x01, -0x24,0x30,0x3C,0x30,0x74,0x1A,0x8C,0xC8,0x8E,0xD8,0x8E,0xC0,0xBB,0xAE,0x4B,0x8B, -0x0F,0xE3,0x0D,0x8B,0x7F,0x02,0x8B,0x77,0x04,0xF3,0xA4,0x83,0xC3,0x06,0xEB,0xEF, -0x07,0x1F,0xC3,0x90,0x33,0xC0,0xA3,0x3E,0x01,0xB9,0x0C,0x01,0xBE,0x40,0x01,0x8B, -0xFE,0x81,0xC6,0xB4,0x0F,0x89,0x04,0x8B,0xC6,0x2B,0xF1,0x3B,0xC7,0x77,0xF6,0xA3, -0x3C,0x01,0xC3,0x90,0x1E,0x06,0x60,0x36,0x8B,0x2E,0x3E,0x01,0x8B,0x5E,0x00,0x3B, -0xEB,0x74,0x2B,0x8B,0x76,0x02,0x89,0x1C,0x89,0x77,0x02,0x36,0xA1,0x3C,0x01,0x89, -0x46,0x00,0x36,0x89,0x2E,0x3C,0x01,0x8B,0xEB,0xFF,0x4E,0x06,0x74,0x08,0x8B,0x6E, -0x00,0xFF,0x4E,0x06,0x75,0xF8,0x36,0x89,0x2E,0x3E,0x01,0x8B,0x66,0x04,0x61,0x07, -0x1F,0xC3,0x1E,0x06,0x60,0x36,0x8B,0x2E,0x3E,0x01,0x98,0x89,0x46,0x06,0x89,0x66, -0x04,0x3B,0x6E,0x00,0x74,0x10,0x8B,0x6E,0x00,0xFF,0x4E,0x06,0x75,0xF8,0x36,0x89, -0x2E,0x3E,0x01,0x8B,0x66,0x04,0x61,0x07,0x1F,0xC3,0xC3,0x90,0x1E,0x06,0x60,0x9C, -0xFA,0x33,0xED,0x8E,0xDD,0x8B,0x2E,0x3C,0x01,0x85,0xED,0x74,0x3D,0x8B,0x4E,0x00, -0x89,0x0E,0x3C,0x01,0x8B,0xCC,0x8D,0xA6,0x0A,0x01,0x56,0x1E,0x06,0x60,0x89,0x66, -0x04,0xC7,0x46,0x08,0x0F,0x1A,0xC7,0x46,0x06,0x01,0x00,0x8B,0x1E,0x3E,0x01,0x85, -0xDB,0x74,0x1D,0x8B,0xC5,0x87,0x07,0x89,0x46,0x00,0x89,0x5E,0x02,0x8B,0xD8,0x89, -0x6F,0x02,0x8B,0xE1,0x9D,0x61,0x07,0x1F,0xF8,0xC3,0x9D,0x61,0x07,0x1F,0xF9,0xC3, -0x89,0x2E,0x3E,0x01,0x89,0x6E,0x00,0x89,0x6E,0x02,0x87,0xE1,0x9D,0x8B,0xE1,0xEB, -0xE4,0x00,0x0D,0x0A,0x54,0x65,0x72,0x6D,0x69,0x6E,0x61,0x6C,0x73,0x20,0x73,0x75, -0x70,0x70,0x6F,0x72,0x74,0x65,0x64,0x3A,0x0D,0x0A,0x31,0x29,0x20,0x41,0x4E,0x53, -0x49,0x20,0x63,0x6F,0x6D,0x70,0x61,0x74,0x69,0x62,0x6C,0x65,0x0D,0x0A,0x32,0x29, -0x20,0x57,0x79,0x73,0x65,0x20,0x33,0x30,0x0D,0x0A,0x50,0x6C,0x65,0x61,0x73,0x65, -0x20,0x73,0x65,0x6C,0x65,0x63,0x74,0x3A,0x20,0x00,0x0D,0x0A,0x63,0x6F,0x64,0x65, -0x20,0x73,0x65,0x67,0x6D,0x65,0x6E,0x74,0x3D,0x00,0x0D,0x0A,0x4D,0x6F,0x6E,0x69, -0x74,0x6F,0x72,0x20,0x76,0x32,0x2E,0x35,0x0A,0x0D,0x0A,0x3E,0x00,0x0D,0x0A,0x50, -0x61,0x72,0x64,0x6F,0x6E,0x3F,0x00,0x0D,0x0A,0x4E,0x6F,0x20,0x61,0x64,0x64,0x72, -0x65,0x73,0x73,0x20,0x73,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x00,0x0D,0x0A, -0x3A,0x00,0x0D,0x0A,0x00,0x4C,0x6F,0x63,0x3D,0x00,0x0D,0x0A,0x46,0x41,0x54,0x41, -0x4C,0x20,0x45,0x52,0x52,0x4F,0x52,0x3D,0x00,0x0D,0x0A,0x4D,0x6F,0x6E,0x69,0x74, -0x6F,0x72,0x20,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x73,0x3A,0x2D,0x0D,0x0A,0x20, -0x20,0x20,0x44,0x2C,0x64,0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78, -0x78,0x5D,0x20,0x2D,0x20,0x64,0x75,0x6D,0x70,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79, -0x0D,0x0A,0x20,0x20,0x20,0x4C,0x2C,0x6C,0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D, -0x78,0x78,0x78,0x78,0x5D,0x20,0x2D,0x20,0x64,0x75,0x6D,0x70,0x20,0x73,0x69,0x6E, -0x67,0x6C,0x65,0x20,0x6C,0x69,0x6E,0x65,0x0D,0x0A,0x20,0x20,0x20,0x45,0x2C,0x65, -0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,0x78,0x5D,0x20,0x2D,0x20, -0x65,0x64,0x69,0x74,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x0D,0x0A,0x20,0x20,0x20, -0x46,0x2C,0x66,0x5B,0x5B,0x78,0x78,0x78,0x78,0x20,0x5D,0x78,0x78,0x78,0x78,0x5D, -0x20,0x2D,0x20,0x66,0x69,0x6C,0x6C,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x20,0x70, -0x61,0x72,0x61,0x67,0x72,0x61,0x70,0x68,0x73,0x0D,0x0A,0x20,0x20,0x20,0x49,0x5B, -0x78,0x78,0x78,0x78,0x5D,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D, -0x20,0x77,0x6F,0x72,0x64,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x66,0x72,0x6F,0x6D, -0x20,0x70,0x6F,0x72,0x74,0x0D,0x0A,0x20,0x20,0x20,0x69,0x5B,0x78,0x78,0x78,0x78, -0x5D,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x62,0x79,0x74, -0x65,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x66,0x72,0x6F,0x6D,0x20,0x70,0x6F,0x72, -0x74,0x0D,0x0A,0x20,0x20,0x20,0x4F,0x78,0x78,0x78,0x78,0x20,0x78,0x78,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x6F,0x75,0x74,0x70,0x75,0x74,0x20, -0x77,0x6F,0x72,0x64,0x20,0x74,0x6F,0x20,0x70,0x6F,0x72,0x74,0x0D,0x0A,0x20,0x20, -0x20,0x6F,0x78,0x78,0x78,0x78,0x20,0x78,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x2D,0x20,0x6F,0x75,0x74,0x70,0x75,0x74,0x20,0x62,0x79,0x74,0x65,0x20, -0x74,0x6F,0x20,0x70,0x6F,0x72,0x74,0x0D,0x0A,0x20,0x20,0x20,0x47,0x5B,0x5B,0x78, -0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,0x78,0x5D,0x20,0x20,0x20,0x2D,0x20,0x67, -0x6F,0x74,0x6F,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x0D,0x0A,0x20,0x20,0x20, -0x57,0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,0x78,0x5D,0x20,0x20, -0x20,0x2D,0x20,0x77,0x61,0x74,0x63,0x68,0x20,0x61,0x20,0x77,0x6F,0x72,0x64,0x0D, -0x0A,0x20,0x20,0x20,0x43,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x69,0x6E,0x74,0x65,0x72,0x72,0x75,0x70,0x74, -0x73,0x20,0x6F,0x66,0x66,0x0D,0x0A,0x20,0x20,0x20,0x53,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x69,0x6E,0x74, -0x65,0x72,0x72,0x75,0x70,0x74,0x73,0x20,0x6F,0x6E,0x0D,0x0A,0x20,0x20,0x20,0x73, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x2D,0x20,0x73,0x69,0x6E,0x67,0x6C,0x65,0x20,0x73,0x74,0x65,0x70,0x0D,0x0A,0x20, -0x20,0x20,0x42,0x78,0x78,0x78,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x2D,0x20,0x62,0x72,0x65,0x61,0x6B,0x70,0x6F,0x69,0x6E,0x74,0x20, -0x73,0x65,0x74,0x0D,0x0A,0x20,0x20,0x20,0x62,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x62,0x72,0x65,0x61,0x6B, -0x70,0x6F,0x69,0x6E,0x74,0x20,0x63,0x6C,0x65,0x61,0x72,0x0D,0x0A,0x20,0x20,0x20, -0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x2D,0x20,0x72,0x65,0x73,0x74,0x61,0x72,0x74,0x20,0x62,0x72,0x65,0x61,0x6B, -0x70,0x6F,0x69,0x6E,0x74,0x0D,0x0A,0x20,0x20,0x20,0x72,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x72,0x65,0x67, -0x69,0x73,0x74,0x65,0x72,0x73,0x20,0x61,0x74,0x20,0x62,0x72,0x6B,0x70,0x74,0x0D, -0x0A,0x20,0x20,0x20,0x58,0x2C,0x78,0x20,0x6E,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x65,0x78,0x61,0x6D,0x69,0x6E,0x65,0x20,0x63, -0x68,0x61,0x6E,0x6E,0x65,0x6C,0x20,0x6E,0x0D,0x0A,0x20,0x20,0x20,0x48,0x2C,0x3F, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20, -0x74,0x68,0x69,0x73,0x20,0x6D,0x65,0x73,0x73,0x61,0x67,0x65,0x00,0x1B,0x5B,0x32, -0x4A,0x1B,0x5B,0x31,0x3B,0x31,0x48,0x41,0x4E,0x53,0x49,0x20,0x54,0x65,0x72,0x6D, -0x69,0x6E,0x61,0x6C,0x0D,0x0A,0x0A,0x00,0x1B,0x5B,0x4B,0x00,0x1B,0x5B,0x4A,0x00, -0x1B,0x5B,0x32,0x4A,0x1B,0x5B,0x31,0x3B,0x31,0x48,0x00,0x1B,0x5B,0x44,0x20,0x1B, -0x5B,0x44,0x00,0x1B,0x5B,0x31,0x3B,0x37,0x32,0x48,0x00,0x1B,0x5B,0x00,0x3B,0x00, -0x48,0x00,0x1B,0x5B,0x73,0x00,0x1B,0x5B,0x75,0x00,0x1B,0x7A,0x2B,0x0B,0x7F,0x1B, -0x7A,0x2E,0x0C,0x7F,0x1B,0x7A,0x2D,0x08,0x7F,0x1B,0x7A,0x2C,0x0A,0x7F,0x1B,0x7A, -0x22,0x08,0x7F,0x1A,0x57,0x79,0x73,0x65,0x20,0x33,0x30,0x20,0x54,0x65,0x72,0x6D, -0x69,0x6E,0x61,0x6C,0x0D,0x0A,0x00,0x1B,0x54,0x00,0x1B,0x59,0x00,0x1A,0x00,0x1E, -0x00,0x08,0x20,0x08,0x00,0x00,0x1B,0x3D,0x00,0x00,0x00,0x1B,0x46,0x00,0x0D,0x00, -0x3F,0x44,0x64,0x45,0x65,0x46,0x66,0x47,0x67,0x48,0x68,0x49,0x69,0x4F,0x6F,0x43, -0x63,0x53,0x73,0x42,0x62,0x52,0x72,0x57,0x77,0x58,0x78,0x4C,0x6C,0x3C,0x60,0xD4, -0x57,0xD4,0x57,0x50,0x58,0x50,0x58,0xD6,0x59,0xD6,0x59,0xB4,0x59,0xB4,0x59,0x3C, -0x60,0x3C,0x60,0x6C,0x57,0x48,0x57,0x26,0x57,0x06,0x57,0x90,0x57,0x90,0x57,0x98, -0x57,0x48,0x5F,0x0C,0x5F,0x58,0x5F,0x33,0x5F,0x40,0x5F,0xA0,0x57,0xA0,0x57,0xFE, -0x59,0xFE,0x59,0xDC,0x57,0xDC,0x57,0x88,0x61,0x98,0x61,0xC0,0x61,0xCC,0x61,0xD8, -0x61,0xF6,0x61,0x02,0x62,0x22,0x62,0xF8,0x56,0x4A,0x62,0x58,0x62,0x60,0x59,0x20, -0x20,0x66,0x6C,0x61,0x67,0x73,0x3D,0x00,0x20,0x20,0x61,0x78,0x3D,0x00,0x20,0x20, -0x62,0x78,0x3D,0x00,0x20,0x20,0x63,0x78,0x3D,0x00,0x20,0x20,0x64,0x78,0x3D,0x00, -0x20,0x20,0x63,0x73,0x3D,0x00,0x20,0x20,0x64,0x73,0x3D,0x00,0x20,0x20,0x65,0x73, -0x3D,0x00,0x20,0x20,0x73,0x73,0x3D,0x00,0x20,0x20,0x64,0x69,0x3D,0x00,0x20,0x20, -0x73,0x69,0x3D,0x00,0x20,0x20,0x62,0x70,0x3D,0x00,0x20,0x20,0x73,0x70,0x3D,0x00, -0x20,0x20,0x69,0x70,0x3D,0x00,0x20,0x63,0x68,0x61,0x6E,0x65,0x6C,0x3D,0x00,0x20, -0x20,0x20,0x20,0x73,0x65,0x67,0x3D,0x00,0x20,0x74,0x69,0x5F,0x73,0x74,0x72,0x3D, -0x00,0x20,0x74,0x69,0x5F,0x74,0x6F,0x73,0x3D,0x00,0x20,0x74,0x69,0x5F,0x6D,0x61, -0x78,0x3D,0x00,0x20,0x74,0x69,0x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x74,0x69,0x5F, -0x73,0x69,0x7A,0x3D,0x00,0x20,0x74,0x69,0x5F,0x73,0x74,0x66,0x3D,0x00,0x20,0x74, -0x69,0x5F,0x72,0x6F,0x6F,0x3D,0x00,0x20,0x74,0x69,0x5F,0x66,0x6C,0x67,0x3D,0x00, -0x20,0x74,0x69,0x5F,0x74,0x6F,0x74,0x3D,0x00,0x20,0x72,0x69,0x5F,0x70,0x63,0x6E, -0x3D,0x00,0x20,0x72,0x69,0x5F,0x73,0x74,0x72,0x3D,0x00,0x20,0x72,0x69,0x5F,0x73, -0x74,0x66,0x3D,0x00,0x20,0x72,0x69,0x5F,0x72,0x6F,0x6F,0x3D,0x00,0x20,0x72,0x69, -0x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x72,0x69,0x5F,0x73,0x69,0x7A,0x3D,0x00,0x20, -0x72,0x69,0x5F,0x74,0x6F,0x74,0x3D,0x00,0x20,0x72,0x69,0x5F,0x6D,0x69,0x6E,0x3D, -0x00,0x20,0x72,0x69,0x5F,0x66,0x6C,0x67,0x3D,0x00,0x20,0x72,0x69,0x5F,0x74,0x6F, -0x73,0x3D,0x00,0x20,0x72,0x69,0x5F,0x74,0x68,0x72,0x3D,0x00,0x20,0x74,0x68,0x5F, -0x73,0x74,0x66,0x3D,0x00,0x20,0x74,0x68,0x5F,0x73,0x74,0x72,0x3D,0x00,0x20,0x74, -0x68,0x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x74,0x68,0x5F,0x73,0x69,0x7A,0x3D,0x00, -0x20,0x74,0x68,0x5F,0x74,0x72,0x67,0x3D,0x00,0x20,0x74,0x68,0x5F,0x66,0x6C,0x67, -0x3D,0x00,0x20,0x74,0x68,0x5F,0x63,0x6E,0x74,0x3D,0x00,0x20,0x72,0x68,0x5F,0x73, -0x74,0x72,0x3D,0x00,0x20,0x72,0x68,0x5F,0x73,0x74,0x66,0x3D,0x00,0x20,0x72,0x68, -0x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x72,0x68,0x5F,0x73,0x69,0x7A,0x3D,0x00,0x20, -0x72,0x68,0x5F,0x73,0x70,0x61,0x3D,0x00,0x20,0x72,0x68,0x5F,0x61,0x73,0x6F,0x3D, -0x00,0x20,0x72,0x68,0x5F,0x72,0x6F,0x6F,0x3D,0x00,0x20,0x72,0x68,0x5F,0x66,0x6C, -0x67,0x3D,0x00,0x20,0x6D,0x5F,0x63,0x61,0x72,0x65,0x3D,0x00,0x20,0x70,0x74,0x5F, -0x66,0x6C,0x6F,0x3D,0x00,0x20,0x61,0x73,0x5F,0x66,0x6C,0x6F,0x3D,0x00,0x20,0x72, -0x6D,0x5F,0x66,0x6C,0x6F,0x3D,0x00,0x20,0x20,0x20,0x71,0x5F,0x69,0x6E,0x3D,0x00, -0x20,0x20,0x71,0x5F,0x6F,0x75,0x74,0x3D,0x00,0x20,0x71,0x5F,0x64,0x72,0x61,0x6E, -0x3D,0x00,0x20,0x20,0x71,0x5F,0x74,0x69,0x6D,0x3D,0x00,0x20,0x20,0x20,0x71,0x5F, -0x66,0x63,0x3D,0x00,0x20,0x71,0x5F,0x73,0x74,0x61,0x74,0x3D,0x00,0x20,0x71,0x5F, -0x64,0x61,0x74,0x61,0x3D,0x00,0x20,0x71,0x5F,0x6D,0x6F,0x64,0x6D,0x3D,0x00,0x20, -0x68,0x61,0x6E,0x64,0x5F,0x6F,0x3D,0x00,0x20,0x68,0x61,0x6E,0x64,0x5F,0x62,0x3D, -0x00,0x20,0x68,0x61,0x6E,0x64,0x5F,0x65,0x3D,0x00,0x20,0x68,0x61,0x6E,0x64,0x5F, -0x69,0x3D,0x00,0x20,0x20,0x6F,0x70,0x6F,0x73,0x74,0x3D,0x00,0x20,0x20,0x74,0x69, -0x6D,0x65,0x6F,0x3D,0x00,0x20,0x63,0x75,0x73,0x74,0x6D,0x31,0x3D,0x00,0x20,0x63, -0x75,0x73,0x74,0x6D,0x32,0x3D,0x00,0x20,0x63,0x75,0x73,0x74,0x6D,0x64,0x3D,0x00, -0x20,0x74,0x78,0x72,0x61,0x74,0x65,0x3D,0x00,0x20,0x72,0x78,0x72,0x61,0x74,0x65, -0x3D,0x00,0x20,0x20,0x63,0x5F,0x6D,0x61,0x70,0x3D,0x00,0x20,0x63,0x5F,0x61,0x64, -0x64,0x72,0x3D,0x00,0x20,0x63,0x5F,0x61,0x69,0x73,0x72,0x3D,0x00,0x20,0x63,0x5F, -0x78,0x74,0x61,0x67,0x3D,0x00,0x20,0x63,0x5F,0x64,0x65,0x66,0x72,0x3D,0x00,0x20, -0x63,0x5F,0x66,0x6C,0x73,0x68,0x3D,0x00,0x20,0x74,0x78,0x6D,0x61,0x78,0x73,0x3D, -0x00,0x20,0x72,0x69,0x5F,0x65,0x6D,0x73,0x3D,0x00,0x20,0x20,0x63,0x5F,0x6C,0x73, -0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x69,0x65,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F, -0x66,0x63,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x6D,0x63,0x72,0x3D,0x00,0x20,0x20, -0x63,0x5F,0x6C,0x63,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x64,0x73,0x73,0x3D,0x00, -0x20,0x63,0x5F,0x64,0x73,0x73,0x69,0x3D,0x00,0x20,0x63,0x5F,0x64,0x73,0x73,0x72, -0x3D,0x00,0x20,0x20,0x63,0x5F,0x69,0x73,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x63, -0x61,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x65,0x66,0x72,0x3D,0x00,0x20,0x63,0x5F, -0x65,0x72,0x73,0x74,0x3D,0x00,0x20,0x63,0x5F,0x65,0x63,0x6E,0x74,0x3D,0x00,0x20, -0x63,0x5F,0x62,0x72,0x6B,0x63,0x3D,0x00,0x20,0x63,0x5F,0x62,0x6F,0x6B,0x63,0x3D, -0x00,0x20,0x63,0x5F,0x72,0x65,0x70,0x6C,0x3D,0x00,0x20,0x63,0x5F,0x63,0x63,0x73, -0x72,0x3D,0x00,0x20,0x63,0x5F,0x73,0x74,0x74,0x31,0x3D,0x00,0x20,0x63,0x5F,0x73, -0x74,0x74,0x32,0x3D,0x00,0x2B,0xC0,0x8E,0xD8,0x8E,0xC0,0xE8,0xC2,0x00,0xE8,0xE5, -0x00,0xFA,0xBF,0x84,0x00,0xC7,0x05,0xDC,0x56,0x8C,0x4D,0x02,0xBF,0x0C,0x00,0xC7, -0x05,0x6E,0x5E,0x8C,0x4D,0x02,0xBF,0x04,0x00,0xC7,0x05,0xBA,0x5E,0x8C,0x4D,0x02, -0xE8,0xF1,0x00,0x90,0xE8,0x49,0x01,0xE8,0x16,0x00,0xF4,0x90,0xE8,0xE5,0x00,0xBE, -0xBA,0x4D,0xE8,0x09,0x0C,0xA0,0x93,0x12,0xE8,0x5D,0x0C,0xE8,0xC2,0x09,0xEB,0xE4, -0xE8,0xD5,0x0C,0xE8,0xC4,0x0C,0x0A,0xC0,0x74,0xF6,0x8B,0x1E,0xF8,0x79,0x3C,0x0D, -0x74,0x2E,0x3C,0x08,0x74,0x17,0x3C,0x7F,0x74,0x13,0x83,0xFB,0x20,0x7F,0xE1,0x88, -0x87,0xD6,0x79,0x43,0x89,0x1E,0xF8,0x79,0xE8,0x77,0x0C,0xEB,0xD3,0x0B,0xDB,0x74, -0xCF,0x4B,0x89,0x1E,0xF8,0x79,0x8B,0x36,0x16,0x7A,0xE8,0xC1,0x0B,0xEB,0xC1,0x90, -0xE8,0x02,0x00,0xEB,0xBB,0xC6,0x87,0xD6,0x79,0x00,0x0B,0xDB,0x74,0x1E,0xA0,0xD6, -0x79,0xBF,0x60,0x51,0xB9,0x1D,0x00,0x8B,0xD9,0x06,0x0E,0x07,0xF2,0xAE,0x07,0x75, -0x17,0x41,0x2B,0xD9,0xD1,0xE3,0x2E,0xFF,0x97,0x7D,0x51,0x90,0x33,0xC0,0xA3,0xF8, -0x79,0xBE,0x89,0x4D,0xE8,0x87,0x0B,0xC3,0xBE,0x8D,0x4D,0xE8,0x80,0x0B,0xEB,0xEC, -0xBA,0x00,0x02,0xB0,0x93,0xEE,0xB0,0x55,0xEE,0xBA,0x10,0x02,0xB0,0x93,0xEE,0xB0, -0xAA,0xEE,0xBA,0x00,0x02,0xEC,0x3C,0x55,0x75,0x08,0xBA,0x10,0x02,0xEC,0x3C,0xAA, -0x74,0x03,0xE8,0x2F,0xF6,0xC3,0xBA,0x04,0x02,0xB0,0x1A,0xEE,0xB0,0x20,0xEE,0xB0, -0x30,0xEE,0xB0,0x40,0xEE,0xB0,0x80,0xEE,0xBA,0x00,0x02,0xB0,0x13,0xEE,0xB0,0x07, -0xEE,0xBA,0x08,0x02,0xB0,0x80,0xEE,0xBA,0x02,0x02,0xB0,0xBB,0xEE,0xBA,0x04,0x02, -0xB0,0x05,0xEE,0xC3,0xC6,0x06,0xCA,0x13,0x01,0xC7,0x06,0xF8,0x79,0x00,0x00,0xC6, -0x06,0xF6,0x79,0x01,0xC7,0x06,0xD0,0x79,0x00,0x00,0xC7,0x06,0xD2,0x79,0x00,0x00, -0xC7,0x06,0xD4,0x79,0x00,0x00,0xC7,0x06,0xFA,0x79,0x00,0x00,0xC7,0x06,0xFC,0x79, -0x00,0x00,0xC7,0x06,0xFE,0x79,0x00,0x00,0xC7,0x06,0x00,0x7A,0x00,0x00,0xC7,0x06, -0x02,0x7A,0xCE,0x59,0x8C,0x0E,0x04,0x7A,0xC7,0x06,0x06,0x7A,0x00,0x00,0xC7,0x06, -0x27,0x7A,0x00,0x00,0xC6,0x06,0x29,0x7A,0x00,0xC6,0x06,0x2A,0x7A,0x00,0xC3,0x90, -0xBE,0x22,0x4D,0xE8,0xC8,0x0A,0xE8,0x3F,0x00,0x2C,0x31,0x3C,0x01,0x77,0xF7,0xE8, -0x81,0x09,0x8B,0x36,0x0C,0x7A,0xE8,0xB5,0x0A,0xBE,0x6A,0x4D,0xE8,0xAF,0x0A,0x0E, -0x58,0xE8,0xF8,0x0A,0xBE,0x7A,0x4D,0xE8,0xA4,0x0A,0xC3,0x90,0x60,0xD1,0xE3,0x83, -0xFB,0x18,0x73,0x11,0x1E,0xBA,0x00,0x00,0x8E,0xDA,0x2E,0xFF,0x97,0xB7,0x51,0x8B, -0xEC,0x89,0x46,0x10,0x1F,0x61,0xCF,0x90,0xE8,0x4F,0x0B,0x0A,0xC0,0x75,0x05,0xE8, -0x56,0x0B,0xEB,0xF4,0xC3,0x90,0x83,0x3E,0xF8,0x79,0x01,0x74,0x16,0xBE,0xD7,0x79, -0xE8,0x31,0x0A,0x8B,0xD0,0xAC,0x3C,0x2C,0x74,0x04,0x3C,0x20,0x75,0x05,0xE8,0x23, -0x0A,0xEE,0xC3,0xE9,0xD2,0xFE,0x83,0x3E,0xF8,0x79,0x01,0x74,0xF6,0xBE,0xD7,0x79, -0xE8,0x11,0x0A,0x8B,0xD0,0xAC,0x3C,0x2C,0x74,0x08,0x3C,0x20,0x74,0x04,0xE9,0xB7, -0xFE,0x90,0xE8,0xFF,0x09,0xEF,0xC3,0x90,0x8B,0x16,0x06,0x7A,0x83,0x3E,0xF8,0x79, -0x01,0x74,0x0B,0xBE,0xD7,0x79,0xE8,0xEB,0x09,0x8B,0xD0,0xA3,0x06,0x7A,0xB0,0x20, -0xE8,0x57,0x0B,0x8B,0x16,0x06,0x7A,0xEC,0xE8,0x6F,0x0B,0xC3,0x8B,0x16,0x06,0x7A, -0x83,0x3E,0xF8,0x79,0x01,0x74,0x0B,0xBE,0xD7,0x79,0xE8,0xC7,0x09,0x8B,0xD0,0xA3, -0x06,0x7A,0xB0,0x20,0xE8,0x33,0x0B,0x8B,0x16,0x06,0x7A,0xED,0xE8,0x67,0x0B,0xC3, -0xFA,0xC6,0x06,0xF6,0x79,0x00,0xC3,0x90,0xC6,0x06,0xF6,0x79,0x01,0xFB,0xC3,0x90, -0x06,0xE8,0x58,0x09,0xB0,0x20,0xE8,0x11,0x0B,0x26,0x8B,0x05,0xE8,0x47,0x0B,0xB0, -0x08,0xE8,0x06,0x0B,0xE8,0x03,0x0B,0xE8,0x00,0x0B,0xE8,0xFD,0x0A,0xB8,0x01,0x00, -0xE8,0xCF,0xF4,0xBA,0x02,0x02,0xEC,0x24,0x01,0x75,0x02,0xEB,0xDC,0xBA,0x06,0x02, -0xEC,0x07,0xC3,0x90,0xC7,0x06,0x08,0x7A,0x10,0x00,0xEB,0x06,0xC7,0x06,0x08,0x7A, -0x01,0x00,0x06,0x8E,0x06,0xFC,0x79,0x8B,0x3E,0xFA,0x79,0xE8,0x0E,0x09,0xE8,0x0B, -0x00,0x89,0x3E,0xFA,0x79,0x8C,0x06,0xFC,0x79,0x07,0xC3,0x90,0xBE,0xB2,0x4D,0xE8, -0x7C,0x09,0x8B,0x16,0x08,0x7A,0x52,0xE8,0x2A,0x09,0xE8,0x0F,0x0A,0xE8,0x0C,0x0A, -0x33,0xDB,0xB9,0x10,0x00,0x90,0x26,0x8A,0x01,0xE8,0xBC,0x09,0xE8,0xFD,0x09,0x43, -0xE2,0xF4,0xE8,0xF7,0x09,0xE8,0xF4,0x09,0x33,0xDB,0xB9,0x10,0x00,0x90,0x26,0x8A, -0x01,0x3C,0x20,0x72,0x05,0x3C,0x7E,0x76,0x03,0x90,0xB0,0x2E,0xE8,0xE3,0x09,0x43, -0xE2,0xEC,0xBE,0xB2,0x4D,0xE8,0x36,0x09,0x83,0xC7,0x10,0x5A,0x4A,0x75,0xB7,0xC3, -0x06,0x8E,0x06,0x00,0x7A,0x8B,0x3E,0xFE,0x79,0xE8,0xA0,0x08,0x89,0x3E,0xFE,0x79, -0x8C,0x06,0x00,0x7A,0x57,0x8B,0x36,0x0E,0x7A,0xE8,0x12,0x09,0xC7,0x06,0x08,0x7A, -0x10,0x00,0xBA,0x00,0x02,0xE8,0xE8,0x00,0xE8,0x81,0xFF,0x5F,0xBA,0x00,0x00,0xE8, -0xDE,0x00,0xBE,0xB5,0x4D,0xE8,0xF6,0x08,0x8C,0xC0,0xE8,0x3F,0x09,0xB0,0x3A,0xE8, -0x90,0x09,0x8B,0xC7,0xE8,0x35,0x09,0xE8,0x7E,0x08,0xE8,0xC3,0x00,0x90,0xE8,0xB7, -0x09,0xE8,0xA6,0x09,0x0A,0xC0,0x74,0xF6,0x3C,0x0B,0x75,0x06,0x83,0xEF,0x10,0xEB, -0x19,0x90,0x3C,0x0A,0x75,0x06,0x83,0xC7,0x10,0xEB,0x0F,0x90,0x3C,0x0C,0x75,0x04, -0x47,0xEB,0x07,0x90,0x3C,0x08,0x75,0x24,0x4F,0x90,0x8B,0x36,0xFE,0x79,0x8B,0xC7, -0x2B,0xC6,0x3D,0x00,0x01,0x72,0xA5,0x3D,0x10,0x01,0x72,0x04,0x83,0xEE,0x20,0x90, -0x83,0xC6,0x10,0x89,0x36,0xFE,0x79,0x57,0x8B,0xFE,0xEB,0x80,0x3C,0x2E,0x75,0x08, -0xBA,0x01,0x13,0xE8,0x6A,0x00,0x07,0xC3,0xC6,0x06,0x0A,0x7A,0x02,0x32,0xC9,0x90, -0x3C,0x30,0x72,0x4C,0x3C,0x39,0x76,0x0C,0x24,0x5F,0x3C,0x41,0x72,0x42,0x3C,0x46, -0x77,0x3E,0x2C,0x07,0x2C,0x30,0x50,0xE8,0xCC,0x08,0x58,0x02,0xC8,0xFE,0x0E,0x0A, -0x7A,0x74,0x0F,0xC0,0xE1,0x04,0xE8,0x2F,0x09,0xE8,0x1E,0x09,0x0A,0xC0,0x74,0xF6, -0xEB,0xCE,0x26,0x88,0x0D,0xE8,0xE0,0x07,0x8A,0xD0,0xE8,0x23,0x00,0x8A,0xC1,0x3C, -0x20,0x72,0x05,0x3C,0x7E,0x76,0x03,0x90,0xB0,0x2E,0xE8,0xD5,0x08,0xE9,0x70,0xFF, -0xE8,0xC5,0x07,0xE8,0x0A,0x00,0x26,0x8A,0x05,0xE8,0x7C,0x08,0xE9,0x1D,0xFF,0x90, -0xF6,0x06,0x26,0x7A,0x02,0x75,0x02,0x86,0xF2,0x52,0x8B,0x36,0x1A,0x7A,0xE8,0x0D, -0x08,0x5A,0x52,0x8A,0xC6,0x02,0x06,0x24,0x7A,0xF6,0x06,0x26,0x7A,0x01,0x75,0x06, -0xE8,0x9F,0x08,0xEB,0x0D,0x90,0x32,0xE4,0xE8,0x0D,0x08,0x8B,0x36,0x1C,0x7A,0xE8, -0xEC,0x07,0x5A,0x8A,0xC2,0x02,0x06,0x25,0x7A,0xF6,0x06,0x26,0x7A,0x01,0x75,0x06, -0xE8,0x7F,0x08,0xEB,0x06,0x90,0x32,0xE4,0xE8,0xED,0x07,0x8B,0x36,0x1E,0x7A,0xE8, -0xCC,0x07,0xC3,0x90,0x06,0x8E,0x06,0x04,0x7A,0x8B,0x3E,0x02,0x7A,0xE8,0x3C,0x07, -0x89,0x3E,0x02,0x7A,0x8C,0x06,0x04,0x7A,0x07,0xFF,0x1E,0x02,0x7A,0xC3,0xBE,0x97, -0x4D,0xE8,0xAA,0x07,0xCB,0x90,0x06,0x57,0xBE,0xD7,0x79,0xE8,0x66,0x07,0x8B,0xD8, -0xE8,0x61,0x07,0x8B,0xC8,0x2B,0xCB,0x78,0x11,0x8E,0xC3,0xBF,0x00,0x00,0xB8,0xFF, -0xFF,0x51,0xB9,0x08,0x00,0xF3,0xAB,0x59,0xE2,0xF7,0x5F,0x07,0xC3,0x90,0x06,0xBE, -0xD7,0x79,0xE8,0x3F,0x07,0x8B,0xD8,0xD1,0xE3,0x2E,0x8B,0x9F,0x44,0x00,0xBE,0x26, -0x52,0xE8,0xF1,0x08,0x8B,0xC3,0xE8,0xDD,0x08,0xB8,0x01,0x00,0xE8,0x73,0xF2,0xE8, -0xE0,0x08,0xBE,0x2F,0x52,0xE8,0xDD,0x08,0x8B,0x47,0x18,0xE8,0xC8,0x08,0xBE,0x77, -0x52,0xE8,0xD1,0x08,0x8B,0x47,0x26,0xE8,0xBC,0x08,0xBE,0x53,0x52,0xE8,0xC5,0x08, -0x8B,0x47,0x1E,0xE8,0xB0,0x08,0xBE,0x5C,0x52,0xE8,0xB9,0x08,0x8B,0x47,0x20,0xE8, -0xA4,0x08,0xBE,0x6E,0x52,0xE8,0xAD,0x08,0x8B,0x47,0x24,0xE8,0x98,0x08,0xBE,0x80, -0x52,0xE8,0xA1,0x08,0x8B,0x47,0x2A,0xE8,0x8C,0x08,0xE8,0x95,0x08,0xBE,0x38,0x52, -0xE8,0x92,0x08,0x8B,0x07,0xE8,0x7E,0x08,0xBE,0x41,0x52,0xE8,0x87,0x08,0x8B,0x47, -0x1A,0xE8,0x72,0x08,0xBE,0x4A,0x52,0xE8,0x7B,0x08,0x8B,0x47,0x1C,0xE8,0x66,0x08, -0xBE,0x65,0x52,0xE8,0x6F,0x08,0x8B,0x47,0x22,0xE8,0x5A,0x08,0xE8,0x63,0x08,0xBE, -0xD1,0x52,0xE8,0x60,0x08,0x8B,0x47,0x38,0xE8,0x4B,0x08,0xBE,0xAD,0x52,0xE8,0x54, -0x08,0x8B,0x47,0x30,0xE8,0x3F,0x08,0xBE,0xB6,0x52,0xE8,0x48,0x08,0x8B,0x47,0x32, -0xE8,0x33,0x08,0xBE,0xA4,0x52,0xE8,0x3C,0x08,0x8B,0x47,0x2E,0xE8,0x27,0x08,0xBE, -0xBF,0x52,0xE8,0x30,0x08,0x8B,0x47,0x34,0xE8,0x1B,0x08,0xE8,0x24,0x08,0xBE,0x89, -0x52,0xE8,0x21,0x08,0x8B,0x47,0x04,0xE8,0x0C,0x08,0xBE,0x92,0x52,0xE8,0x15,0x08, -0x8B,0x47,0x14,0xE8,0x00,0x08,0xBE,0x9B,0x52,0xE8,0x09,0x08,0x8B,0x47,0x2C,0xE8, -0xF4,0x07,0xBE,0xC8,0x52,0xE8,0xFD,0x07,0x8B,0x47,0x36,0xE8,0xE8,0x07,0xBE,0xDA, -0x52,0xE8,0xF1,0x07,0x8B,0x47,0x3A,0xE8,0xDC,0x07,0xBE,0xE3,0x52,0xE8,0xE5,0x07, -0x8B,0x47,0x3C,0xE8,0xD0,0x07,0xE8,0xD9,0x07,0xBE,0x19,0x53,0xE8,0xD6,0x07,0x8B, -0x47,0x48,0xE8,0xC1,0x07,0xBE,0xFE,0x52,0xE8,0xCA,0x07,0x8B,0x47,0x42,0xE8,0xB5, -0x07,0xBE,0x07,0x53,0xE8,0xBE,0x07,0x8B,0x47,0x44,0xE8,0xA9,0x07,0xBE,0x7C,0x53, -0xE8,0xB2,0x07,0x8B,0x47,0x4C,0xE8,0x9D,0x07,0xBE,0x85,0x53,0xE8,0xA6,0x07,0x8B, -0x47,0x4E,0xE8,0x91,0x07,0xBE,0x8E,0x53,0xE8,0x9A,0x07,0x8B,0x47,0x50,0xE8,0x85, -0x07,0xE8,0x8E,0x07,0xBE,0x22,0x53,0xE8,0x8B,0x07,0x8B,0x47,0x4A,0xE8,0x76,0x07, -0xBE,0xEC,0x52,0xE8,0x7F,0x07,0x8B,0x47,0x08,0xE8,0x6A,0x07,0xBE,0xF5,0x52,0xE8, -0x73,0x07,0x8B,0x47,0x40,0xE8,0x5E,0x07,0xBE,0x10,0x53,0xE8,0x67,0x07,0x8B,0x47, -0x46,0xE8,0x52,0x07,0xE8,0x5B,0x07,0xBE,0x6A,0x53,0xE8,0x58,0x07,0x8B,0x47,0x7A, -0xE8,0x43,0x07,0xBE,0x3D,0x53,0xE8,0x4C,0x07,0x8B,0x47,0x70,0xE8,0x37,0x07,0xBE, -0x46,0x53,0xE8,0x40,0x07,0x8B,0x47,0x72,0xE8,0x2B,0x07,0xBE,0x4F,0x53,0xE8,0x34, -0x07,0x8B,0x47,0x74,0xE8,0x1F,0x07,0xE8,0x28,0x07,0xBE,0x2B,0x53,0xE8,0x25,0x07, -0x8B,0x47,0x0C,0xE8,0x10,0x07,0xBE,0x34,0x53,0xE8,0x19,0x07,0x8B,0x47,0x10,0xE8, -0x04,0x07,0xBE,0x58,0x53,0xE8,0x0D,0x07,0x8B,0x47,0x76,0xE8,0xF8,0x06,0xBE,0x61, -0x53,0xE8,0x01,0x07,0x8B,0x47,0x78,0xE8,0xEC,0x06,0xBE,0x73,0x53,0xE8,0xF5,0x06, -0x8B,0x47,0x3E,0xE8,0xE0,0x06,0xE8,0xE9,0x06,0xBE,0x97,0x53,0xE8,0xE6,0x06,0x8B, -0x47,0x52,0xE8,0xD1,0x06,0xBE,0xA0,0x53,0xE8,0xDA,0x06,0x8B,0x47,0x54,0xE8,0xC5, -0x06,0xBE,0xA9,0x53,0xE8,0xCE,0x06,0x8B,0x47,0x56,0xE8,0xB9,0x06,0xBE,0xB2,0x53, -0xE8,0xC2,0x06,0x8B,0x47,0x58,0xE8,0xAD,0x06,0xBE,0xBB,0x53,0xE8,0xB6,0x06,0x8B, -0x47,0x5A,0xE8,0xA1,0x06,0xBE,0xC4,0x53,0xE8,0xAA,0x06,0x8B,0x47,0x5C,0xE8,0x95, -0x06,0xE8,0x9E,0x06,0xBE,0xCD,0x53,0xE8,0x9B,0x06,0x8B,0x47,0x5E,0xE8,0x86,0x06, -0xBE,0xD6,0x53,0xE8,0x8F,0x06,0x8B,0x47,0x60,0xE8,0x7A,0x06,0xBE,0xDF,0x53,0xE8, -0x83,0x06,0x8B,0x47,0x62,0xE8,0x6E,0x06,0xBE,0xE8,0x53,0xE8,0x77,0x06,0x8B,0x47, -0x7C,0xE8,0x62,0x06,0xBE,0xF1,0x53,0xE8,0x6B,0x06,0x8B,0x47,0x7E,0xE8,0x56,0x06, -0xBE,0xFA,0x53,0xE8,0x5F,0x06,0x8B,0x87,0x80,0x00,0xE8,0x49,0x06,0xE8,0x52,0x06, -0xBE,0x42,0x54,0xE8,0x4F,0x06,0x8B,0x87,0x9E,0x00,0xE8,0x39,0x06,0xBE,0x03,0x54, -0xE8,0x42,0x06,0x8B,0x47,0x64,0xE8,0x2D,0x06,0xBE,0x0C,0x54,0xE8,0x36,0x06,0x8B, -0x47,0x6E,0xE8,0x21,0x06,0xBE,0x15,0x54,0xE8,0x2A,0x06,0x8B,0x87,0x8E,0x00,0xE8, -0x14,0x06,0xBE,0x1E,0x54,0xE8,0x1D,0x06,0x8B,0x87,0x90,0x00,0xE8,0x07,0x06,0xBE, -0x27,0x54,0xE8,0x10,0x06,0x8B,0x87,0x92,0x00,0xE8,0xFA,0x05,0xE8,0x03,0x06,0xBE, -0x30,0x54,0xE8,0x00,0x06,0x8B,0x87,0x94,0x00,0xE8,0xEA,0x05,0xBE,0x39,0x54,0xE8, -0xF3,0x05,0x8B,0x87,0x96,0x00,0xE8,0xDD,0x05,0xBE,0x6F,0x54,0xE8,0xE6,0x05,0x8B, -0x87,0x98,0x00,0xE8,0xD0,0x05,0xBE,0x5D,0x54,0xE8,0xD9,0x05,0x8A,0x87,0xA0,0x00, -0xE8,0xA7,0x05,0xBE,0x54,0x54,0xE8,0xCC,0x05,0x8A,0x47,0x28,0xE8,0x9B,0x05,0xBE, -0x66,0x54,0xE8,0xC0,0x05,0x8A,0x87,0xA1,0x00,0xE8,0x8E,0x05,0xE8,0xB3,0x05,0xBE, -0x78,0x54,0xE8,0xB0,0x05,0x8A,0x87,0xA2,0x00,0xE8,0x7E,0x05,0xBE,0x81,0x54,0xE8, -0xA3,0x05,0x8A,0x87,0xA3,0x00,0xE8,0x71,0x05,0xBE,0x8A,0x54,0xE8,0x96,0x05,0x8A, -0x87,0xA4,0x00,0xE8,0x64,0x05,0xBE,0x93,0x54,0xE8,0x89,0x05,0x8A,0x87,0xA5,0x00, -0xE8,0x57,0x05,0xBE,0x9C,0x54,0xE8,0x7C,0x05,0x8A,0x87,0xA6,0x00,0xE8,0x4A,0x05, -0xBE,0xA5,0x54,0xE8,0x6F,0x05,0x8A,0x87,0xA7,0x00,0xE8,0x3D,0x05,0xBE,0xAE,0x54, -0xE8,0x62,0x05,0x8A,0x87,0xA8,0x00,0xE8,0x30,0x05,0xE8,0x55,0x05,0xBE,0xB7,0x54, -0xE8,0x52,0x05,0x8A,0x87,0xA9,0x00,0xE8,0x20,0x05,0xBE,0xC0,0x54,0xE8,0x45,0x05, -0x8A,0x87,0xAA,0x00,0xE8,0x13,0x05,0xBE,0xC9,0x54,0xE8,0x38,0x05,0x8A,0x87,0xAB, -0x00,0xE8,0x06,0x05,0xBE,0xD2,0x54,0xE8,0x2B,0x05,0x8A,0x87,0xAD,0x00,0xE8,0xF9, -0x04,0xBE,0xDB,0x54,0xE8,0x1E,0x05,0x8A,0x87,0xAE,0x00,0xE8,0xEC,0x04,0xBE,0xE4, -0x54,0xE8,0x11,0x05,0x8A,0x87,0xAF,0x00,0xE8,0xDF,0x04,0xBE,0xED,0x54,0xE8,0x04, -0x05,0x8A,0x87,0xB0,0x00,0xE8,0xD2,0x04,0xE8,0xF7,0x04,0xBE,0xF6,0x54,0xE8,0xF4, -0x04,0x8A,0x87,0xB1,0x00,0xE8,0xC2,0x04,0xBE,0xFF,0x54,0xE8,0xE7,0x04,0x8A,0x87, -0xB2,0x00,0xE8,0xB5,0x04,0xBE,0x08,0x55,0xE8,0xDA,0x04,0x8A,0x87,0xB3,0x00,0xE8, -0xA8,0x04,0xBE,0x11,0x55,0xE8,0xCD,0x04,0x8A,0x87,0xBB,0x00,0xE8,0x9B,0x04,0xE8, -0xC0,0x04,0xBE,0x1A,0x55,0xE8,0xBD,0x04,0x8A,0x87,0xBC,0x00,0xE8,0x8B,0x04,0xBE, -0x23,0x55,0xE8,0xB0,0x04,0x8A,0x87,0xBE,0x00,0xE8,0x7E,0x04,0xBE,0x2C,0x55,0xE8, -0xA3,0x04,0x8A,0x87,0xBF,0x00,0xE8,0x71,0x04,0xE8,0x96,0x04,0x07,0xC3,0x60,0x06, -0x1E,0x16,0x8B,0xEC,0xFF,0x4E,0x16,0xF7,0x46,0x1A,0x00,0x02,0x74,0x01,0xFB,0xB8, -0x00,0x00,0x8E,0xD8,0x8E,0xC0,0x89,0x2E,0x2D,0x7A,0xE8,0xCB,0x00,0x81,0x66,0x1A, -0xFF,0xFE,0xC6,0x06,0x2A,0x7A,0x00,0xE8,0xD8,0x00,0xB8,0x00,0x5F,0xA3,0x2B,0x7A, -0xE8,0x5D,0x00,0x80,0x3E,0x2A,0x7A,0x00,0x74,0x0A,0x81,0x4E,0x1A,0x00,0x01,0xC6, -0x06,0x2A,0x7A,0x00,0x17,0x1F,0x07,0x61,0xCF,0x90,0x60,0x06,0x1E,0x16,0x8B,0xEC, -0xF7,0x46,0x1A,0x00,0x02,0x74,0x01,0xFB,0xB8,0x00,0x00,0x8E,0xD8,0x8E,0xC0,0x89, -0x2E,0x2D,0x7A,0x81,0x66,0x1A,0xFF,0xFE,0xC6,0x06,0x2A,0x7A,0x00,0xE8,0x92,0x00, -0xB8,0x00,0x5F,0xA3,0x2B,0x7A,0xE8,0x17,0x00,0x80,0x3E,0x2A,0x7A,0x00,0x74,0x0A, -0x81,0x4E,0x1A,0x00,0x01,0xC6,0x06,0x2A,0x7A,0x00,0x17,0x1F,0x07,0x61,0xCF,0x90, -0xB8,0xF0,0x00,0xE8,0x8C,0xED,0xFF,0x26,0x2B,0x7A,0xC3,0x90,0x06,0x53,0x56,0x80, -0x3E,0x29,0x7A,0x00,0x74,0x03,0xE8,0x3F,0x00,0xBE,0xD7,0x79,0xE8,0x25,0x02,0x8B, -0xD8,0xA3,0x27,0x7A,0x2E,0x8A,0x07,0xA2,0x29,0x7A,0xB0,0xCC,0x2E,0x88,0x07,0x5E, -0x5B,0x07,0xC3,0xC6,0x06,0x2A,0x7A,0x00,0xB8,0x0A,0x5F,0xA3,0x2B,0x7A,0xC3,0x90, -0x8B,0x2E,0x2D,0x7A,0xE8,0x2B,0x00,0xC3,0xC6,0x06,0x2A,0x7A,0x01,0xE8,0x08,0x00, -0xB8,0x0A,0x5F,0xA3,0x2B,0x7A,0xC3,0x90,0x57,0x80,0x3E,0x29,0x7A,0x00,0x74,0x0F, -0x8B,0x3E,0x27,0x7A,0xA0,0x29,0x7A,0x2E,0x88,0x05,0xC6,0x06,0x29,0x7A,0x00,0x5F, -0xC3,0x90,0xBE,0xB2,0x4D,0xE8,0x06,0x02,0xBE,0xD8,0x51,0xE8,0x00,0x02,0xFF,0x76, -0x14,0x58,0xE8,0x47,0x02,0xBE,0xDE,0x51,0xE8,0xF3,0x01,0xFF,0x76,0x0E,0x58,0xE8, -0x3A,0x02,0xBE,0xE4,0x51,0xE8,0xE6,0x01,0xFF,0x76,0x12,0x58,0xE8,0x2D,0x02,0xBE, -0xEA,0x51,0xE8,0xD9,0x01,0xFF,0x76,0x10,0x58,0xE8,0x20,0x02,0xBE,0x14,0x52,0xE8, -0xCC,0x01,0xFF,0x76,0x0A,0x58,0xE8,0x13,0x02,0xBE,0x1A,0x52,0xE8,0xBF,0x01,0xFF, -0x76,0x0C,0x58,0xE8,0x06,0x02,0xBE,0xCF,0x51,0xE8,0xB2,0x01,0xFF,0x76,0x1A,0x58, -0xE8,0xF9,0x01,0xBE,0xB2,0x4D,0xE8,0xA5,0x01,0xBE,0xF0,0x51,0xE8,0x9F,0x01,0xFF, -0x76,0x18,0x58,0xE8,0xE6,0x01,0xBE,0xF6,0x51,0xE8,0x92,0x01,0xFF,0x76,0x02,0x58, -0xE8,0xD9,0x01,0xBE,0xFC,0x51,0xE8,0x85,0x01,0xFF,0x76,0x04,0x58,0xE8,0xCC,0x01, -0xBE,0x02,0x52,0xE8,0x78,0x01,0xFF,0x76,0x00,0x58,0xE8,0xBF,0x01,0xBE,0x08,0x52, -0xE8,0x6B,0x01,0xFF,0x76,0x06,0x58,0xE8,0xB2,0x01,0xBE,0x0E,0x52,0xE8,0x5E,0x01, -0xFF,0x76,0x08,0x58,0xE8,0xA5,0x01,0xBE,0x20,0x52,0xE8,0x51,0x01,0xFF,0x76,0x16, -0x58,0xE8,0x98,0x01,0xBE,0x89,0x4D,0xE8,0x44,0x01,0xC3,0x90,0xBE,0xC9,0x4D,0xE8, -0x3C,0x01,0xC3,0x3C,0x00,0x74,0x05,0x3C,0x01,0x74,0x59,0xC3,0xC7,0x06,0x0C,0x7A, -0xCD,0x50,0xC7,0x06,0x0E,0x7A,0xF0,0x50,0xC7,0x06,0x10,0x7A,0xE8,0x50,0xC7,0x06, -0x12,0x7A,0xEC,0x50,0xC7,0x06,0x14,0x7A,0xF4,0x50,0xC7,0x06,0x16,0x7A,0xFB,0x50, -0xC7,0x06,0x18,0x7A,0x03,0x51,0xC7,0x06,0x1A,0x7A,0x0B,0x51,0xC7,0x06,0x1C,0x7A, -0x0E,0x51,0xC7,0x06,0x1E,0x7A,0x10,0x51,0xC7,0x06,0x20,0x7A,0x12,0x51,0xC7,0x06, -0x22,0x7A,0x16,0x51,0xC6,0x06,0x24,0x7A,0x01,0xC6,0x06,0x25,0x7A,0x01,0xC6,0x06, -0x26,0x7A,0x03,0xC3,0xC7,0x06,0x0C,0x7A,0x1A,0x51,0xC7,0x06,0x0E,0x7A,0x4D,0x51, -0xC7,0x06,0x10,0x7A,0x47,0x51,0xC7,0x06,0x12,0x7A,0x4A,0x51,0xC7,0x06,0x14,0x7A, -0x4F,0x51,0xC7,0x06,0x16,0x7A,0x51,0x51,0xC7,0x06,0x18,0x7A,0x55,0x51,0xC7,0x06, -0x1A,0x7A,0x56,0x51,0xC7,0x06,0x1C,0x7A,0x59,0x51,0xC7,0x06,0x1E,0x7A,0x5A,0x51, -0xC7,0x06,0x20,0x7A,0x5B,0x51,0xC7,0x06,0x22,0x7A,0x5E,0x51,0xC6,0x06,0x24,0x7A, -0x20,0xC6,0x06,0x25,0x7A,0x20,0xC6,0x06,0x26,0x7A,0x02,0xC3,0xA1,0xF8,0x79,0x48, -0x74,0x14,0xBE,0xD7,0x79,0xE8,0x3C,0x00,0x8B,0xF8,0xAC,0x3C,0x3A,0x75,0x07,0x8E, -0xC7,0xE8,0x30,0x00,0x8B,0xF8,0xC3,0x90,0x8B,0xC7,0x2B,0x06,0xFE,0x79,0x8A,0xF0, -0x24,0x0F,0x8A,0xD0,0x02,0xD0,0x02,0xD0,0x80,0xC2,0x0B,0xC0,0xEE,0x04,0x80,0xC6, -0x03,0x04,0x3D,0xC3,0x8C,0xC0,0xE8,0x93,0x00,0xB0,0x3A,0xE8,0xE4,0x00,0x8B,0xC7, -0xE8,0x89,0x00,0xC3,0x51,0x33,0xC9,0x90,0xAC,0x3C,0x20,0x74,0xFB,0x90,0x0A,0xC0, -0x74,0x26,0x2C,0x30,0x72,0x22,0x3C,0x09,0x76,0x14,0x3C,0x11,0x72,0x1A,0x2C,0x07, -0x3C,0x0F,0x76,0x0A,0x3C,0x2A,0x72,0x10,0x2C,0x20,0x3C,0x0F,0x77,0x0A,0x98,0xC1, -0xE1,0x04,0x03,0xC8,0xAC,0xEB,0xD7,0x90,0x4E,0x8B,0xC1,0x59,0xC3,0x90,0x06,0x8C, -0xC8,0x8E,0xC0,0xE8,0x02,0x00,0x07,0xC3,0x26,0x8A,0x04,0x46,0x0A,0xC0,0x74,0x06, -0xE8,0x8F,0x00,0xEB,0xF3,0x90,0xC3,0x90,0x0B,0xC0,0x74,0x7A,0x51,0x33,0xD2,0xB9, -0xE8,0x03,0xF7,0xF1,0x8B,0xCA,0xE8,0x03,0x00,0x8B,0xC1,0x59,0xBA,0x64,0x00,0xF6, -0xF2,0xE8,0x0C,0x00,0x8A,0xC4,0x98,0xB2,0x0A,0xF6,0xF2,0xE8,0x02,0x00,0x8A,0xC4, -0x50,0x0A,0xF0,0x74,0x05,0x04,0x30,0xE8,0x58,0x00,0x58,0xC3,0x86,0xC4,0xE8,0x07, -0x00,0x86,0xC4,0xE8,0x02,0x00,0xC3,0x90,0xC1,0xC8,0x04,0xE8,0x08,0x00,0xC1,0xC0, -0x04,0xE8,0x02,0x00,0xC3,0x90,0x53,0x50,0x24,0x0F,0xBB,0xCA,0x62,0x2E,0xD7,0xE8, -0x30,0x00,0x58,0x5B,0xC3,0x90,0x86,0xC4,0xE8,0x07,0x00,0x86,0xC4,0xE8,0x02,0x00, -0xC3,0x90,0x50,0xB9,0x08,0x00,0x8A,0xE0,0x32,0xC0,0xD1,0xC0,0x04,0x30,0xE8,0x11, -0x00,0xE2,0xF5,0x58,0xC3,0x90,0xB0,0x30,0xE8,0x07,0x00,0xC3,0xB0,0x20,0xE8,0x01, -0x00,0xC3,0x56,0x8B,0x36,0xD0,0x79,0x88,0x84,0xD0,0x77,0x46,0x81,0xE6,0xFF,0x01, -0xFF,0x06,0xD4,0x79,0x89,0x36,0xD0,0x79,0x81,0x3E,0xD4,0x79,0xFE,0x01,0x75,0x08, -0x56,0xE8,0x14,0x00,0x5E,0xEB,0xF1,0x90,0x5E,0xC3,0xBA,0x02,0x02,0xEC,0x24,0x01, -0x74,0x04,0xBA,0x06,0x02,0xEC,0xC3,0x90,0x80,0x3E,0xF6,0x79,0x00,0x74,0x09,0x60, -0xB8,0x01,0x00,0xE8,0x2C,0xEA,0x61,0x90,0xBA,0x02,0x02,0xEC,0xA8,0x04,0x74,0x28, -0x8B,0x36,0xD2,0x79,0x83,0x3E,0xD4,0x79,0x00,0x74,0x1D,0x8A,0x84,0xD0,0x77,0x46, -0x81,0xE6,0xFF,0x01,0x89,0x36,0xD2,0x79,0xFF,0x0E,0xD4,0x79,0xBA,0x06,0x02,0xEE, -0xBA,0x02,0x02,0xEC,0xA8,0x04,0x75,0xDC,0xA1,0xD4,0x79,0xC3,0x52,0xBA,0x06,0x02, -0xEE,0x5A,0xC3,0x90,0x52,0x50,0xBA,0x02,0x02,0xEC,0xA8,0x04,0x74,0x08,0x58,0x5A, -0xE8,0xE9,0xFF,0xF9,0xC3,0x90,0x58,0x5A,0xF8,0xC3,0x52,0x50,0xBA,0x02,0x02,0xEC, -0xA8,0x04,0x74,0xFB,0x58,0x5A,0xE8,0xD3,0xFF,0xC3,0x30,0x31,0x32,0x33,0x34,0x35, -0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x53,0x50,0x8A,0xE0,0x80,0xE4, -0x0F,0xBB,0xCA,0x62,0xC0,0xE8,0x04,0x2E,0xD7,0xE8,0xCE,0xFF,0x8A,0xC4,0x2E,0xD7, -0xE8,0xC7,0xFF,0x58,0x5B,0xC3,0x86,0xE0,0xE8,0xDF,0xFF,0x86,0xE0,0xE8,0xDA,0xFF, -0xC3,0x90,0xBE,0xB2,0x4D,0x50,0x2E,0xAC,0x3C,0x00,0x74,0x05,0xE8,0xAB,0xFF,0xEB, -0xF5,0x58,0xC3,0x90,0xC8,0x08,0x00,0x00,0x56,0x57,0x8B,0x76,0x04,0xBF,0x04,0x00, -0xC7,0x46,0xFC,0x00,0x00,0xC7,0x46,0xFA,0x00,0x00,0xC7,0x46,0xF8,0x00,0x00,0x83, -0x7E,0x06,0x00,0x75,0x0E,0x56,0xE8,0xB6,0x0E,0x59,0x0B,0xC0,0x75,0x05,0x8B,0xC7, -0xE9,0x5B,0x01,0x8B,0x46,0xFC,0x89,0x46,0xFE,0x0B,0xFF,0x75,0x05,0xB8,0x01,0x00, -0xEB,0x02,0x33,0xC0,0x50,0x56,0xE8,0xA4,0x0D,0x59,0x59,0xB4,0x00,0x89,0x46,0xFC, -0x8B,0x5E,0xFC,0x83,0xFB,0x08,0x76,0x03,0xE9,0x2B,0x01,0xD1,0xE3,0x2E,0xFF,0xA7, -0xB2,0x64,0xB8,0x03,0x00,0xE9,0x26,0x01,0x83,0x7E,0xFA,0x00,0x74,0x14,0xC7,0x46, -0xFA,0x00,0x00,0x8A,0x44,0x58,0x98,0x50,0x8A,0x44,0x59,0x98,0x50,0xE8,0xC2,0x0F, -0x59,0x59,0x83,0x7E,0xF8,0x00,0x74,0x0A,0xC7,0x46,0xF8,0x00,0x00,0x56,0xE8,0x9B, -0x08,0x59,0x83,0x7E,0x06,0x00,0x75,0x05,0x8B,0xC7,0xE9,0xF1,0x00,0x83,0xFF,0x04, -0x75,0x03,0xE9,0xE6,0x00,0x8B,0xC7,0xE9,0xE4,0x00,0x83,0x7E,0xFE,0x00,0x75,0x03, -0xBF,0x02,0x00,0xE9,0xD5,0x00,0x83,0x7E,0xFE,0x00,0x75,0x03,0xBF,0x01,0x00,0xE9, -0xC9,0x00,0x8B,0x5E,0xFE,0x83,0xFB,0x07,0x76,0x03,0xE9,0x86,0x00,0xD1,0xE3,0x2E, -0xFF,0xA7,0xA2,0x64,0x33,0xFF,0xE9,0x7F,0x00,0xBF,0x04,0x00,0x80,0x7C,0x58,0x0F, -0x74,0x22,0x83,0x7E,0xF8,0x00,0x75,0x1C,0xFE,0x44,0x58,0x6A,0x08,0x56,0xE8,0x7E, -0x0C,0x59,0x59,0x8A,0x44,0x58,0x04,0x80,0x50,0x56,0xE8,0x72,0x0C,0x59,0x59,0xC7, -0x46,0xFA,0x01,0x00,0x83,0x7E,0xF8,0x00,0x74,0x0A,0xC7,0x46,0xF8,0x00,0x00,0x56, -0xE8,0x19,0x08,0x59,0xEB,0x42,0xBF,0x04,0x00,0x80,0x7C,0x58,0x00,0x74,0x22,0x83, -0x7E,0xF8,0x00,0x75,0x1C,0xFE,0x4C,0x58,0x6A,0x08,0x56,0xE8,0x41,0x0C,0x59,0x59, -0x8A,0x44,0x58,0x04,0x80,0x50,0x56,0xE8,0x35,0x0C,0x59,0x59,0xC7,0x46,0xFA,0x01, -0x00,0x83,0x7E,0xF8,0x00,0x74,0x0A,0xC7,0x46,0xF8,0x00,0x00,0x56,0xE8,0xDC,0x07, -0x59,0xEB,0x05,0xBF,0x04,0x00,0xEB,0x00,0xEB,0x31,0xBF,0x04,0x00,0xEB,0x2C,0xC7, -0x46,0xF8,0x01,0x00,0x6A,0x08,0x56,0xE8,0x05,0x0C,0x59,0x59,0x80,0x7C,0x58,0x09, -0x7D,0x04,0xB0,0x0F,0xEB,0x02,0xB0,0x00,0x04,0x80,0x50,0x56,0xE8,0xF0,0x0B,0x59, -0x59,0xBF,0x04,0x00,0xEB,0x05,0xBF,0x04,0x00,0xEB,0x00,0xE9,0xA5,0xFE,0x5F,0x5E, -0xC9,0xC3,0xE4,0x63,0x63,0x64,0x63,0x64,0x63,0x64,0x63,0x64,0xE9,0x63,0x26,0x64, -0x51,0x64,0x78,0x63,0xBA,0x63,0xC6,0x63,0x96,0x64,0xD2,0x63,0x6A,0x64,0x6A,0x64, -0x6F,0x64,0x72,0x63,0xC8,0x08,0x00,0x00,0x56,0x57,0x8B,0x76,0x04,0x8B,0x7E,0x08, -0x6A,0x01,0x56,0xE8,0xA9,0x0B,0x59,0x59,0x8A,0x46,0x06,0xC0,0xE0,0x06,0x04,0x80, -0x50,0x56,0xE8,0x9A,0x0B,0x59,0x59,0xC7,0x46,0xFE,0x00,0x00,0x89,0x7E,0xF8,0xEB, -0x03,0xFF,0x46,0xFE,0x8B,0x5E,0xF8,0xFF,0x46,0xF8,0x80,0x3F,0x00,0x75,0xF2,0x83, -0x7E,0xFE,0x10,0x7D,0x25,0xB8,0x10,0x00,0x2B,0x46,0xFE,0xD1,0xF8,0x89,0x46,0xFC, -0xC7,0x46,0xFA,0x00,0x00,0xEB,0x0B,0x6A,0x20,0x56,0xE8,0x62,0x0B,0x59,0x59,0xFF, -0x46,0xFA,0x8B,0x46,0xFA,0x3B,0x46,0xFC,0x7C,0xED,0xEB,0x0C,0x8B,0xDF,0x47,0x8A, -0x07,0x50,0x56,0xE8,0x49,0x0B,0x59,0x59,0x80,0x3D,0x00,0x75,0xEF,0x6A,0x02,0x56, -0xE8,0x3C,0x0B,0x59,0x59,0xEB,0x00,0x5F,0x5E,0xC9,0xC3,0xC8,0x04,0x00,0x00,0x56, -0x57,0x8B,0x7E,0x04,0xC7,0x46,0xFE,0x00,0x00,0xBE,0x14,0x00,0xE9,0x09,0x01,0x8B, -0x5E,0xFE,0x83,0xC3,0x04,0x2B,0xDF,0x8A,0x87,0xAC,0x0B,0x88,0x44,0x5A,0xC6,0x44, -0x58,0x08,0x8A,0x46,0xFE,0x88,0x44,0x59,0xC7,0x44,0x06,0x00,0x00,0xC6,0x44,0x19, -0x00,0xC6,0x44,0x1A,0x00,0xC6,0x44,0x1B,0x00,0xC6,0x44,0x1D,0x0D,0xC6,0x44,0x1E, -0x03,0xC6,0x44,0x1F,0x00,0xC6,0x44,0x20,0x00,0xC6,0x44,0x21,0x00,0xC6,0x44,0x5B, -0x00,0xC6,0x44,0x5D,0x00,0xC6,0x44,0x5E,0x00,0xC6,0x44,0x5F,0x00,0xC6,0x44,0x60, -0x00,0xC7,0x46,0xFC,0x00,0x00,0xEB,0x0D,0x8B,0x5E,0xFC,0xD1,0xE3,0xC7,0x40,0x30, -0x00,0x00,0xFF,0x46,0xFC,0x83,0x7E,0xFC,0x10,0x7C,0xED,0xC7,0x46,0xFC,0x00,0x00, -0xEB,0x0A,0x8B,0x5E,0xFC,0xC6,0x40,0x50,0x00,0xFF,0x46,0xFC,0x83,0x7E,0xFC,0x04, -0x7C,0xF0,0xC7,0x44,0x54,0x00,0x00,0xC7,0x44,0x56,0x00,0x00,0x8A,0x44,0x5A,0x98, -0xBA,0xF8,0x00,0x23,0xD0,0xB8,0x05,0x00,0x0B,0xC2,0x89,0x46,0xFC,0x9C,0xFA,0x8A, -0x46,0xFC,0xBA,0xFE,0x00,0xEE,0xBA,0x00,0x00,0xEC,0x9D,0x24,0x08,0x88,0x46,0xFC, -0x83,0x7E,0xFC,0x00,0x75,0x02,0xEB,0x4A,0xFF,0x76,0xFE,0xE8,0x7A,0x0C,0x59,0x68, -0x35,0x02,0x56,0xE8,0x32,0x0A,0x59,0x59,0x0B,0xC0,0x75,0x34,0x68,0x38,0x02,0x56, -0xE8,0x25,0x0A,0x59,0x59,0x0B,0xC0,0x75,0x27,0x68,0x42,0x02,0x56,0xE8,0x18,0x0A, -0x59,0x59,0x0B,0xC0,0x75,0x1A,0x68,0x4C,0x02,0x56,0xE8,0x0B,0x0A,0x59,0x59,0x0B, -0xC0,0x75,0x0D,0x68,0x56,0x02,0x56,0xE8,0xFE,0x09,0x59,0x59,0x0B,0xC0,0x74,0x02, -0xEB,0x00,0xFF,0x46,0xFE,0x83,0xC6,0x62,0x39,0x7E,0xFE,0x7D,0x03,0xE9,0xEF,0xFE, -0xEB,0x00,0x5F,0x5E,0xC9,0xC3,0xC8,0x08,0x00,0x00,0x56,0x57,0x8B,0x46,0x04,0xBA, -0x62,0x00,0xF7,0xEA,0x05,0x14,0x00,0x8B,0xF0,0x83,0x7E,0x06,0x00,0x74,0x05,0xB8, -0x10,0x00,0xEB,0x03,0xB8,0x08,0x00,0x89,0x44,0x04,0x8A,0x46,0x08,0x88,0x44,0x5C, -0x56,0xE8,0x59,0x04,0x59,0x8B,0xF8,0x8B,0xC7,0x89,0x44,0x56,0x89,0x44,0x54,0x8A, -0x44,0x5D,0x88,0x44,0x2F,0x0B,0xFF,0x75,0x1D,0x68,0xC2,0x0F,0x6A,0x01,0x56,0xE8, -0x02,0xFE,0x83,0xC4,0x06,0xEB,0x00,0x6A,0x01,0x56,0xE8,0x47,0xFC,0x59,0x59,0x0B, -0xC0,0x75,0xF4,0xBF,0x01,0x00,0x89,0x7E,0xFA,0xB9,0x05,0x00,0xBB,0xE9,0x6A,0x2E, -0x8B,0x07,0x3B,0x46,0xFA,0x74,0x07,0x43,0x43,0xE2,0xF4,0xE9,0xA4,0x03,0x2E,0xFF, -0x67,0x0A,0xC7,0x44,0x06,0x02,0x00,0xC7,0x44,0x08,0xF4,0x08,0x8B,0x5E,0x04,0xD1, -0xE3,0x8B,0x87,0xFC,0x08,0x89,0x44,0x0A,0x33,0xC0,0x8B,0xF8,0x89,0x44,0x54,0xE9, -0x80,0x03,0x56,0xE8,0xBB,0x05,0x59,0xBF,0x01,0x00,0x8A,0x44,0x5D,0x88,0x44,0x60, -0xE9,0x6F,0x03,0x83,0x7C,0x04,0x08,0x75,0x30,0x80,0x7C,0x5C,0x01,0x75,0x15,0x8A, -0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xE4,0x08,0x56,0xE8,0xF7,0x08, -0x59,0x59,0xEB,0x13,0x8A,0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xC4, -0x08,0x56,0xE8,0xE2,0x08,0x59,0x59,0xEB,0x2E,0x80,0x7C,0x5C,0x01,0x75,0x15,0x8A, -0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xD4,0x08,0x56,0xE8,0xC7,0x08, -0x59,0x59,0xEB,0x13,0x8A,0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xB4, -0x08,0x56,0xE8,0xB2,0x08,0x59,0x59,0x6A,0x01,0x56,0xE8,0x87,0xFB,0x59,0x59,0x8B, -0xD8,0x83,0xFB,0x03,0x77,0x2A,0xD1,0xE3,0x2E,0xFF,0xA7,0xE1,0x6A,0xBF,0x01,0x00, -0x8A,0x44,0x5D,0x88,0x44,0x5E,0xEB,0x18,0x8A,0x44,0x5D,0x04,0xFF,0x24,0x07,0x88, -0x44,0x5D,0xEB,0x0C,0x8A,0x44,0x5D,0xFE,0xC0,0x24,0x07,0x88,0x44,0x5D,0xEB,0x00, -0xE9,0xCF,0x02,0x8A,0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xFD,0x02, -0x56,0xE8,0x63,0x08,0x59,0x59,0x68,0x1D,0x03,0x56,0xE8,0x5A,0x08,0x59,0x59,0x6A, -0x01,0x56,0xE8,0x2F,0xFB,0x59,0x59,0x8B,0xD8,0x83,0xFB,0x03,0x77,0x36,0xD1,0xE3, -0x2E,0xFF,0xA7,0xD9,0x6A,0xBF,0x01,0x00,0x8A,0x44,0x5D,0x88,0x44,0x5F,0xEB,0x24, -0x8A,0x44,0x5D,0x04,0xFF,0x8A,0x54,0x04,0x80,0xC2,0xFF,0x22,0xC2,0x88,0x44,0x5D, -0xEB,0x12,0x8A,0x44,0x5D,0xFE,0xC0,0x8A,0x54,0x04,0x80,0xC2,0xFF,0x22,0xC2,0x88, -0x44,0x5D,0xEB,0x00,0xE9,0x6B,0x02,0x8B,0x5C,0x06,0x83,0xC3,0xFE,0xD1,0xE3,0x8B, -0x40,0x08,0x89,0x04,0x8B,0x1C,0xFF,0x77,0x06,0x6A,0x00,0x56,0xE8,0x85,0xFC,0x83, -0xC4,0x06,0x8B,0x5C,0x06,0x4B,0xD1,0xE3,0x8B,0x40,0x08,0x89,0x44,0x02,0x8B,0x5C, -0x02,0xFF,0x77,0x06,0x6A,0x01,0x56,0xE8,0x6A,0xFC,0x83,0xC4,0x06,0x6A,0x01,0x56, -0xE8,0xB1,0xFA,0x59,0x59,0x8B,0xD8,0x83,0xFB,0x03,0x76,0x03,0xE9,0x1F,0x02,0xD1, -0xE3,0x2E,0xFF,0xA7,0xD1,0x6A,0x8B,0x5C,0x02,0x8B,0x47,0x04,0x89,0x44,0x02,0x8B, -0x5C,0x02,0x80,0x3F,0x44,0x75,0x0D,0x8B,0x5C,0x02,0x8A,0x47,0x01,0xB4,0x00,0x3B, -0x44,0x04,0x7D,0xE2,0x8B,0x46,0x04,0xD1,0xE0,0x8B,0x1C,0x03,0xD8,0x8B,0x44,0x02, -0x89,0x47,0x08,0x8B,0x5C,0x06,0x4B,0xD1,0xE3,0x8B,0x44,0x02,0x89,0x40,0x08,0xE9, -0xDE,0x01,0x8B,0x5C,0x02,0x8B,0x47,0x02,0x89,0x44,0x02,0x8B,0x5C,0x02,0x80,0x3F, -0x44,0x75,0x0D,0x8B,0x5C,0x02,0x8A,0x47,0x01,0xB4,0x00,0x3B,0x44,0x04,0x7D,0xE2, -0x8B,0x46,0x04,0xD1,0xE0,0x8B,0x1C,0x03,0xD8,0x8B,0x44,0x02,0x89,0x47,0x08,0x8B, -0x5C,0x06,0x4B,0xD1,0xE3,0x8B,0x44,0x02,0x89,0x40,0x08,0xE9,0xA2,0x01,0xBF,0x01, -0x00,0xE9,0x9C,0x01,0x8B,0x5C,0x02,0x8A,0x07,0xB4,0x00,0x89,0x46,0xF8,0xB9,0x0C, -0x00,0xBB,0xA1,0x6A,0x2E,0x8B,0x07,0x3B,0x46,0xF8,0x74,0x07,0x43,0x43,0xE2,0xF4, -0xE9,0x77,0x01,0x2E,0xFF,0x67,0x18,0x8B,0x46,0x04,0xD1,0xE0,0x8B,0x5C,0x02,0x03, -0xD8,0x8B,0x47,0x08,0x8B,0x5C,0x06,0xFF,0x44,0x06,0xD1,0xE3,0x89,0x40,0x08,0x8B, -0x1C,0x80,0x7F,0x01,0x00,0x74,0x12,0x8B,0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A, -0x57,0x01,0xB6,0x00,0x8B,0xDA,0x88,0x40,0x18,0xE9,0x40,0x01,0xFF,0x4C,0x06,0xE9, -0x3A,0x01,0x8B,0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A,0x57,0x01,0xB6,0x00,0x8B, -0xDA,0x88,0x40,0x18,0xE9,0x25,0x01,0x8B,0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A, -0x57,0x01,0xB6,0x00,0x8B,0xDA,0x88,0x40,0x18,0xFF,0x4C,0x06,0xE9,0x0D,0x01,0x8B, -0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A,0x57,0x01,0xB6,0x00,0x8B,0xDA,0x30,0x40, -0x18,0xE9,0xF8,0x00,0xB8,0xF0,0x10,0x8B,0xF8,0x89,0x44,0x54,0x8A,0x44,0x5F,0x88, -0x44,0x5D,0xE9,0xE7,0x00,0x8A,0x44,0x1C,0x98,0x3D,0x02,0x00,0x74,0x07,0x3D,0x03, -0x00,0x74,0x02,0xEB,0x07,0xC7,0x46,0xFE,0x00,0x00,0xEB,0x2B,0x8A,0x44,0x1C,0x98, -0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0x69,0x02,0x56,0xE8,0x6B,0x06,0x59,0x59,0x6A,0x01, -0x56,0xE8,0x40,0xF9,0x59,0x59,0x89,0x46,0xFE,0x83,0x7E,0xFE,0x00,0x74,0x06,0x83, -0x7E,0xFE,0x03,0x75,0xE9,0xEB,0x00,0x83,0x7E,0xFE,0x03,0x74,0x62,0x8A,0x44,0x1C, -0x98,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0x6D,0x02,0x56,0xE8,0x3A,0x06,0x59,0x59,0x56, -0xE8,0x4D,0x97,0x59,0x89,0x46,0xFC,0x8B,0x5E,0xFC,0x83,0xEB,0xFE,0x83,0xFB,0x03, -0x77,0x33,0xD1,0xE3,0x2E,0xFF,0xA7,0x99,0x6A,0x68,0xAC,0x02,0x56,0xE8,0x17,0x06, -0x59,0x59,0xEB,0x23,0x68,0x8F,0x02,0x56,0xE8,0x0C,0x06,0x59,0x59,0xEB,0x18,0x68, -0x75,0x02,0x56,0xE8,0x01,0x06,0x59,0x59,0xEB,0x0D,0x68,0xC6,0x02,0x56,0xE8,0xF6, -0x05,0x59,0x59,0xEB,0x02,0xEB,0x00,0x6A,0x01,0x56,0xE8,0xC7,0xF8,0x59,0x59,0xBF, -0x01,0x00,0xEB,0x38,0x68,0xDD,0x02,0x56,0xE8,0xDC,0x05,0x59,0x59,0x6A,0x01,0x56, -0xE8,0xB1,0xF8,0x59,0x59,0xBF,0x01,0x00,0xEB,0x22,0xB8,0xD0,0x30,0x8B,0xF8,0x89, -0x44,0x54,0x8A,0x44,0x60,0x88,0x44,0x5D,0xEB,0x12,0xB8,0xE0,0x20,0x8B,0xF8,0x89, -0x44,0x54,0x8A,0x44,0x5E,0x88,0x44,0x5D,0xEB,0x02,0xEB,0x00,0xEB,0x02,0xEB,0x00, -0xEB,0x00,0xE9,0x41,0xFC,0x5F,0x5E,0xC9,0xC3,0x19,0x6A,0x24,0x6A,0x2F,0x6A,0x3A, -0x6A,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44, -0x00,0x80,0x00,0x81,0x00,0x82,0x00,0xFF,0x00,0x17,0x69,0x54,0x6A,0x7A,0x6A,0xA5, -0x69,0x52,0x69,0x94,0x69,0x6A,0x6A,0x67,0x69,0x52,0x69,0x7F,0x69,0x67,0x69,0x4C, -0x69,0xF4,0x68,0x76,0x68,0xB2,0x68,0xEE,0x68,0xF5,0x67,0x00,0x68,0x12,0x68,0xF5, -0x67,0x9D,0x67,0xA8,0x67,0xB4,0x67,0x9D,0x67,0x00,0x00,0x01,0x00,0xF0,0x10,0xE0, -0x20,0xD0,0x30,0x27,0x68,0xF2,0x66,0xC3,0x67,0x23,0x67,0x12,0x67,0xC8,0x04,0x00, -0x00,0x56,0x57,0x8B,0x76,0x04,0x8A,0x44,0x59,0x98,0x89,0x46,0xFC,0x6A,0x09,0x8B, -0x46,0xFC,0x05,0x84,0x01,0x50,0xE8,0x93,0x08,0x59,0x59,0x8B,0xF8,0x8B,0xC7,0x25, -0x00,0xF0,0x3D,0x00,0x10,0x75,0x55,0x8B,0xC7,0x25,0xF0,0x00,0x3D,0xF0,0x00,0x75, -0x4B,0x8B,0xC7,0x25,0x00,0x0F,0xC1,0xF8,0x08,0x89,0x46,0xFE,0x8B,0x44,0x04,0x3B, -0x46,0xFE,0x7D,0x05,0x33,0xC0,0xE9,0xEF,0x00,0x8B,0xC7,0x25,0x0F,0x00,0xBA,0x0F, -0x00,0x2B,0xD0,0x3B,0x56,0xFE,0x74,0x05,0x33,0xC0,0xE9,0xDB,0x00,0xC7,0x44,0x02, -0x04,0x09,0x8A,0x46,0xFE,0x88,0x44,0x5F,0x88,0x44,0x5D,0x8B,0x5E,0xFC,0xD1,0xE3, -0xC7,0x87,0xFC,0x08,0x04,0x09,0xB8,0xF0,0x10,0xE9,0xBC,0x00,0x8B,0xC7,0x25,0x00, -0xF0,0x3D,0x00,0x20,0x75,0x52,0x8B,0xC7,0x25,0xF0,0x00,0x3D,0xE0,0x00,0x75,0x48, -0x8B,0xC7,0x25,0x00,0x0F,0xC1,0xF8,0x08,0x89,0x46,0xFE,0x83,0x7E,0xFE,0x08,0x7E, -0x05,0x33,0xC0,0xE9,0x92,0x00,0x8B,0xC7,0x25,0x0F,0x00,0xBA,0x0F,0x00,0x2B,0xD0, -0x3B,0x56,0xFE,0x74,0x05,0x33,0xC0,0xEB,0x7F,0x90,0xC7,0x44,0x02,0x0C,0x09,0x8A, -0x46,0xFE,0x88,0x44,0x5E,0x88,0x44,0x5D,0x8B,0x5E,0xFC,0xD1,0xE3,0xC7,0x87,0xFC, -0x08,0x0C,0x09,0xB8,0xE0,0x20,0xEB,0x60,0x8B,0xC7,0x25,0x00,0xF0,0x3D,0x00,0x30, -0x75,0x52,0x8B,0xC7,0x25,0xF0,0x00,0x3D,0xD0,0x00,0x75,0x48,0x8B,0xC7,0x25,0x00, -0x0F,0xC1,0xF8,0x08,0x89,0x46,0xFE,0x8B,0x44,0x04,0x3B,0x46,0xFE,0x7D,0x04,0x33, -0xC0,0xEB,0x35,0x8B,0xC7,0x25,0x0F,0x00,0xBA,0x0F,0x00,0x2B,0xD0,0x3B,0x56,0xFE, -0x74,0x04,0x33,0xC0,0xEB,0x22,0xC7,0x44,0x02,0x14,0x09,0x8A,0x46,0xFE,0x88,0x44, -0x60,0x88,0x44,0x5D,0x8B,0x5E,0xFC,0xD1,0xE3,0xC7,0x87,0xFC,0x08,0x14,0x09,0xB8, -0xD0,0x30,0xEB,0x04,0x33,0xC0,0xEB,0x00,0x5F,0x5E,0xC9,0xC3,0xC8,0x06,0x00,0x00, -0x56,0x8B,0x76,0x04,0x6A,0x08,0x56,0xE8,0x35,0x04,0x59,0x59,0x8A,0x44,0x58,0x04, -0x80,0x50,0x56,0xE8,0x29,0x04,0x59,0x59,0x8B,0x44,0x54,0x3B,0x44,0x56,0x75,0x0A, -0x8A,0x44,0x5D,0x3A,0x44,0x2F,0x75,0x02,0xEB,0x64,0x8B,0x44,0x54,0x89,0x44,0x56, -0x8B,0x5C,0x02,0x8A,0x47,0x01,0x88,0x44,0x2F,0x8A,0x44,0x5D,0xB4,0x00,0xC1,0xE0, -0x08,0x8B,0x54,0x54,0x0B,0xD0,0x8A,0x44,0x5D,0xB4,0x00,0xBB,0x0F,0x00,0x2B,0xD8, -0x0B,0xD3,0x89,0x56,0xFE,0x6A,0x10,0x8A,0x44,0x59,0x98,0x05,0x04,0x00,0x99,0x05, -0x40,0x01,0x83,0xD2,0x00,0x52,0x50,0xE8,0x54,0x08,0x83,0xC4,0x06,0x89,0x56,0xFC, -0x89,0x46,0xFA,0x8B,0x46,0xFE,0x09,0x46,0xFA,0x83,0x4E,0xFC,0x00,0x6A,0x19,0xFF, -0x76,0xFC,0xFF,0x76,0xFA,0xE8,0x73,0x07,0x83,0xC4,0x06,0xE8,0xFE,0x07,0x5E,0xC9, -0xC3,0xC8,0x1C,0x00,0x00,0x56,0x57,0x8B,0x5E,0x04,0x8A,0x47,0x59,0x98,0x8B,0xF0, -0x8B,0x5E,0x04,0x8A,0x47,0x5D,0xB4,0x00,0x89,0x46,0xE6,0x83,0x7E,0xE6,0x00,0x7D, -0x0A,0x8B,0x5E,0x04,0x8B,0x47,0x04,0x48,0x89,0x46,0xE6,0x8B,0x5E,0x04,0x8B,0x47, -0x04,0x3B,0x46,0xE6,0x7F,0x05,0xC7,0x46,0xE6,0x00,0x00,0x8B,0x5E,0x04,0x8A,0x46, -0xE6,0x88,0x47,0x5D,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,0x47,0x02,0x20, -0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,0x47,0x03,0x30,0x8B,0xDE,0xD1,0xE3, -0x8B,0x9F,0x61,0x02,0xC6,0x47,0x02,0x20,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02, -0xC6,0x47,0x03,0x30,0x8B,0x46,0xE6,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18, -0x8B,0x46,0xFA,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1, -0xE3,0x8B,0x9F,0x59,0x02,0x88,0x57,0x03,0xBB,0x0A,0x00,0x8B,0x46,0xFA,0x33,0xD2, -0xF7,0xF3,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,0x8B,0x46,0xFA,0xBB,0x0A, -0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02, -0x88,0x57,0x02,0x8B,0x46,0xE6,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,0x8B, -0x46,0xFA,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,0xE3, -0x8B,0x9F,0x61,0x02,0x88,0x57,0x03,0xBB,0x0A,0x00,0x8B,0x46,0xFA,0x33,0xD2,0xF7, -0xF3,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,0x8B,0x46,0xFA,0xBB,0x0A,0x00, -0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,0x88, -0x57,0x02,0x8B,0x5E,0xE6,0xD1,0xE3,0xFF,0xB7,0x12,0x02,0x6A,0x00,0xFF,0x76,0x04, -0xE8,0xD1,0xF6,0x83,0xC4,0x06,0x68,0xD3,0x0F,0x6A,0x01,0xFF,0x76,0x04,0xE8,0xC3, -0xF6,0x83,0xC4,0x06,0xFF,0x76,0xE6,0x56,0xE8,0x01,0x93,0x59,0x59,0x89,0x56,0xF2, -0x89,0x46,0xF0,0xFF,0x76,0xE6,0x56,0xE8,0x14,0x93,0x59,0x59,0x89,0x56,0xEE,0x89, -0x46,0xEC,0x9C,0xFA,0xC4,0x5E,0xF0,0x26,0x8B,0x07,0x89,0x46,0xEA,0xC4,0x5E,0xEC, -0x26,0x8B,0x07,0x89,0x46,0xE8,0xBA,0x50,0xFF,0xED,0x89,0x46,0xFE,0x9D,0xC7,0x46, -0xE4,0x01,0x00,0xE8,0xEE,0xA0,0xBA,0x50,0xFF,0xED,0x89,0x46,0xFC,0x8B,0x46,0xFC, -0x2B,0x46,0xFE,0x3D,0xE8,0x03,0x73,0x03,0xE9,0x80,0x01,0x9C,0xFA,0xBA,0x50,0xFF, -0xED,0x89,0x46,0xFC,0x8B,0x46,0xFC,0x2B,0x46,0xFE,0x89,0x46,0xF8,0xC4,0x5E,0xF0, -0x26,0x8B,0x07,0x2B,0x46,0xEA,0x89,0x46,0xF6,0xC4,0x5E,0xF0,0x26,0x8B,0x07,0x89, -0x46,0xEA,0xC4,0x5E,0xEC,0x26,0x8B,0x07,0x2B,0x46,0xE8,0x89,0x46,0xF4,0xC4,0x5E, -0xEC,0x26,0x8B,0x07,0x89,0x46,0xE8,0xBA,0x50,0xFF,0xED,0x89,0x46,0xFE,0x9D,0x81, -0x7E,0xF8,0xE8,0x03,0x76,0x1C,0xFF,0x76,0xF8,0xFF,0x76,0xF6,0xE8,0x76,0x01,0x59, -0x59,0x89,0x46,0xF6,0xFF,0x76,0xF8,0xFF,0x76,0xF4,0xE8,0x68,0x01,0x59,0x59,0x89, -0x46,0xF4,0xBF,0x0E,0x00,0xEB,0x17,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6, -0x01,0x20,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,0xC6,0x01,0x20,0x47,0x83,0xFF, -0x11,0x76,0xE4,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,0x47,0x0D,0x30,0x8B, -0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,0xC6,0x47,0x0D,0x30,0x83,0x7E,0xF6,0x09,0x77, -0x05,0xB8,0x0D,0x00,0xEB,0x26,0x83,0x7E,0xF6,0x63,0x77,0x05,0xB8,0x0E,0x00,0xEB, -0x1B,0x81,0x7E,0xF6,0xE7,0x03,0x77,0x05,0xB8,0x0F,0x00,0xEB,0x0F,0x81,0x7E,0xF6, -0x0F,0x27,0x77,0x05,0xB8,0x10,0x00,0xEB,0x03,0xB8,0x11,0x00,0x8B,0xF8,0xEB,0x25, -0x8B,0x46,0xF6,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1, -0xE3,0x8B,0x9F,0x59,0x02,0x88,0x11,0x4F,0xBB,0x0A,0x00,0x8B,0x46,0xF6,0x33,0xD2, -0xF7,0xF3,0x89,0x46,0xF6,0x83,0x7E,0xF6,0x00,0x75,0xD5,0x83,0x7E,0xF4,0x09,0x77, -0x05,0xB8,0x0D,0x00,0xEB,0x26,0x83,0x7E,0xF4,0x63,0x77,0x05,0xB8,0x0E,0x00,0xEB, -0x1B,0x81,0x7E,0xF4,0xE7,0x03,0x77,0x05,0xB8,0x0F,0x00,0xEB,0x0F,0x81,0x7E,0xF4, -0x0F,0x27,0x77,0x05,0xB8,0x10,0x00,0xEB,0x03,0xB8,0x11,0x00,0x8B,0xF8,0xEB,0x25, -0x8B,0x46,0xF4,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1, -0xE3,0x8B,0x9F,0x61,0x02,0x88,0x11,0x4F,0xBB,0x0A,0x00,0x8B,0x46,0xF4,0x33,0xD2, -0xF7,0xF3,0x89,0x46,0xF4,0x83,0x7E,0xF4,0x00,0x75,0xD5,0x8B,0xDE,0xD1,0xE3,0xFF, -0xB7,0x59,0x02,0xFF,0x76,0x04,0xE8,0x6E,0x00,0x59,0x59,0x8B,0xDE,0xD1,0xE3,0xFF, -0xB7,0x61,0x02,0xFF,0x76,0x04,0xE8,0x5E,0x00,0x59,0x59,0x6A,0x00,0xFF,0x76,0x04, -0xE8,0x31,0xF3,0x59,0x59,0x8B,0xD8,0x83,0xFB,0x04,0x77,0x1F,0xD1,0xE3,0x2E,0xFF, -0xA7,0x1B,0x70,0xEB,0x22,0xC7,0x46,0xE4,0x00,0x00,0xFF,0x4E,0xE6,0xEB,0x0C,0xC7, -0x46,0xE4,0x00,0x00,0xFF,0x46,0xE6,0xEB,0x02,0xEB,0x00,0x83,0x7E,0xE4,0x00,0x74, -0x03,0xE9,0x2A,0xFE,0xE9,0xD4,0xFC,0x5F,0x5E,0xC9,0xC3,0xF3,0x6F,0xF5,0x6F,0xFF, -0x6F,0xF3,0x6F,0x09,0x70,0x55,0x8B,0xEC,0x8B,0x46,0x04,0xB9,0xE8,0x03,0xF7,0xE1, -0x8B,0x4E,0x06,0xF7,0xF1,0x5D,0xC3,0x55,0x8B,0xEC,0x56,0x8B,0x76,0x06,0xEB,0x0E, -0x8B,0xDE,0x46,0x8A,0x07,0x50,0xFF,0x76,0x04,0xE8,0x33,0x00,0x59,0x59,0x80,0x3C, -0x00,0x75,0xED,0xEB,0x00,0x5E,0x5D,0xC3,0x55,0x8B,0xEC,0x56,0x8B,0x76,0x06,0xEB, -0x14,0x8B,0xDE,0x46,0x8A,0x07,0x50,0xFF,0x76,0x04,0xE8,0x45,0x00,0x59,0x59,0x0B, -0xC0,0x74,0x02,0xEB,0x07,0x80,0x3C,0x00,0x75,0xE7,0xEB,0x00,0x5E,0x5D,0xC3,0xC8, -0x02,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,0x46,0xFE,0x9C,0xFA, -0x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE,0xBA,0x02,0x00,0xEC,0xA8,0x02,0x74,0x06,0x9D, -0xE8,0x91,0x9E,0xEB,0xE9,0xBA,0x00,0x00,0x8A,0x46,0x06,0xEE,0x9D,0xEB,0x00,0x5E, -0xC9,0xC3,0xC8,0x04,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,0x46, -0xFE,0xE8,0xE6,0xA1,0x89,0x46,0xFC,0xE8,0xE0,0xA1,0x2B,0x46,0xFC,0x3D,0xB8,0x0B, -0x76,0x05,0xB8,0x01,0x00,0xEB,0x23,0x9C,0xFA,0x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE, -0xBA,0x02,0x00,0xEC,0xA8,0x02,0x74,0x06,0x9D,0xE8,0x48,0x9E,0xEB,0xD9,0xBA,0x00, -0x00,0x8A,0x46,0x06,0xEE,0x9D,0x33,0xC0,0xEB,0x00,0x5E,0xC9,0xC3,0xC8,0x04,0x00, -0x00,0x56,0x57,0x8B,0x76,0x04,0x83,0x7E,0x06,0x00,0x74,0x07,0x56,0xE8,0x03,0x01, -0x59,0xEB,0x05,0x56,0xE8,0xA2,0x00,0x59,0x88,0x46,0xFF,0x80,0x7E,0xFF,0x08,0x77, -0x06,0x8A,0x46,0xFF,0xE9,0x84,0x00,0x80,0x7E,0xFF,0x0F,0x76,0x03,0xEB,0x79,0x90, -0x8A,0x46,0xFF,0xB4,0x00,0x2D,0x0A,0x00,0x8B,0xD8,0x83,0xFB,0x04,0x77,0x67,0xD1, -0xE3,0x2E,0xFF,0xA7,0xAF,0x71,0xB0,0x00,0xEB,0x61,0x56,0xE8,0x6B,0x00,0x59,0xB4, -0x00,0x25,0x0F,0x00,0x89,0x46,0xFC,0x56,0xE8,0x5E,0x00,0x59,0xB4,0x00,0x8B,0xF8, -0x56,0xE8,0x55,0x00,0x59,0xB4,0x00,0xC1,0xE0,0x08,0x8B,0xD7,0x03,0xD0,0x8B,0xFA, -0x8B,0x5E,0xFC,0xD1,0xE3,0x89,0x78,0x30,0xEB,0x2E,0x56,0xE8,0x3B,0x00,0x59,0x88, -0x44,0x5B,0xEB,0x24,0x56,0xE8,0x31,0x00,0x59,0x88,0x44,0x50,0x56,0xE8,0x29,0x00, -0x59,0x88,0x44,0x51,0x56,0xE8,0x21,0x00,0x59,0x88,0x44,0x52,0x56,0xE8,0x19,0x00, -0x59,0x88,0x44,0x53,0xEB,0x02,0xEB,0x00,0xE9,0x5B,0xFF,0x5F,0x5E,0xC9,0xC3,0x46, -0x71,0xA6,0x71,0x4A,0x71,0x7A,0x71,0x84,0x71,0xC8,0x04,0x00,0x00,0x56,0x8B,0x76, -0x04,0x8A,0x44,0x5A,0x98,0x89,0x46,0xFE,0x9C,0xFA,0x8A,0x46,0xFE,0xBA,0xFE,0x00, -0xEE,0xBA,0x02,0x00,0xEC,0xA8,0x01,0x75,0x06,0x9D,0xE8,0x57,0x9D,0xEB,0xE9,0xBA, -0x00,0x00,0xEC,0x88,0x46,0xFD,0x9D,0x8A,0x46,0xFD,0xEB,0x00,0x5E,0xC9,0xC3,0xC8, -0x02,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,0x46,0xFE,0x9C,0xFA, -0x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE,0xBA,0x02,0x00,0xEC,0x32,0xE4,0x24,0x01,0x9D, -0x5E,0xC9,0xC3,0xC8,0x06,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89, -0x46,0xFE,0xE8,0x85,0xA0,0x89,0x46,0xFA,0xE8,0x7F,0xA0,0x2B,0x46,0xFA,0x3D,0xB8, -0x0B,0x76,0x04,0xB0,0x08,0xEB,0x24,0x9C,0xFA,0x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE, -0xBA,0x02,0x00,0xEC,0xA8,0x01,0x75,0x06,0x9D,0xE8,0xE8,0x9C,0xEB,0xDA,0xBA,0x00, -0x00,0xEC,0x88,0x46,0xFD,0x9D,0x8A,0x46,0xFD,0xEB,0x00,0x5E,0xC9,0xC3,0x55,0x8B, -0xEC,0x56,0x8B,0x56,0x04,0x8A,0x46,0x06,0xEE,0x33,0xF6,0xEB,0x03,0x50,0x58,0x46, -0x83,0xFE,0x14,0x7C,0xF8,0x5E,0x5D,0xC3,0xC8,0x02,0x00,0x00,0x56,0x8B,0x56,0x04, -0xEC,0x88,0x46,0xFF,0x33,0xF6,0xEB,0x03,0x50,0x58,0x46,0x83,0xFE,0x14,0x7C,0xF8, -0x8A,0x46,0xFF,0xEB,0x00,0x5E,0xC9,0xC3,0xC8,0x02,0x00,0x00,0x56,0x57,0x8B,0x76, -0x04,0x83,0x3E,0xB0,0x0B,0x00,0x75,0x1F,0xBA,0x88,0x01,0xB0,0x00,0xEE,0xBA,0x86, -0x01,0xB0,0x00,0xEE,0x6A,0x09,0x6A,0x00,0x68,0x30,0x01,0xE8,0x7D,0x01,0x83,0xC4, -0x06,0xC7,0x06,0xB0,0x0B,0x01,0x00,0x6A,0x09,0x8B,0xC6,0x05,0x80,0x01,0x50,0xE8, -0xDA,0x00,0x59,0x59,0x8B,0xF8,0x8B,0xC7,0xC1,0xE8,0x0C,0x25,0x0F,0x00,0x89,0x46, -0xFE,0x8B,0xC7,0xC1,0xE8,0x08,0x25,0x0F,0x00,0x8B,0x56,0xFE,0x83,0xF2,0x0C,0x3B, -0xC2,0x75,0x21,0x8B,0xC7,0xC1,0xE8,0x04,0x25,0x0F,0x00,0x8B,0x56,0xFE,0x83,0xF2, -0x06,0x3B,0xC2,0x75,0x0F,0x8B,0xC7,0x25,0x0F,0x00,0x8B,0x56,0xFE,0x83,0xF2,0x09, -0x3B,0xC2,0x74,0x0D,0x6A,0x07,0x56,0xE8,0x38,0x00,0x59,0x59,0xC7,0x46,0xFE,0x07, -0x00,0x8A,0x46,0xFE,0x04,0x80,0xA2,0x33,0x02,0x8B,0xC6,0xBA,0x62,0x00,0xF7,0xEA, -0x8A,0x56,0xFE,0x8B,0xD8,0x88,0x97,0x6C,0x00,0x68,0x32,0x02,0x8B,0xC6,0xBA,0x62, -0x00,0xF7,0xEA,0x05,0x14,0x00,0x50,0xE8,0x0E,0xFD,0x59,0x59,0xEB,0x00,0x5F,0x5E, -0xC9,0xC3,0xC8,0x02,0x00,0x00,0x56,0x8B,0x76,0x06,0x83,0xE6,0x0F,0x8B,0xC6,0xC1, -0xE0,0x0C,0x8B,0xD6,0x83,0xF2,0x0C,0xC1,0xE2,0x08,0x0B,0xC2,0x8B,0xD6,0x83,0xF2, -0x06,0xC1,0xE2,0x04,0x0B,0xC2,0x8B,0xD6,0x83,0xF2,0x09,0x0B,0xC2,0x89,0x46,0xFE, -0x6A,0x19,0x6A,0x10,0x8B,0x46,0x04,0x99,0x05,0x40,0x01,0x83,0xD2,0x00,0x52,0x50, -0xE8,0x6B,0x01,0x83,0xC4,0x06,0x0B,0x46,0xFE,0x83,0xCA,0x00,0x52,0x50,0xE8,0x9A, -0x00,0x83,0xC4,0x06,0xE8,0x25,0x01,0xEB,0x00,0x5E,0xC9,0xC3,0x55,0x8B,0xEC,0x56, -0x57,0x33,0xFF,0x6A,0x01,0x68,0x86,0x01,0xE8,0xA3,0xFE,0x59,0x59,0xB1,0x10,0x2A, -0x4E,0x06,0xD3,0x66,0x04,0x33,0xF6,0xEB,0x2E,0x81,0x7E,0x04,0x00,0x80,0x72,0x04, -0xB0,0x01,0xEB,0x02,0xB0,0x00,0x50,0x68,0x88,0x01,0xE8,0x81,0xFE,0x59,0x59,0x6A, -0x03,0x68,0x86,0x01,0xE8,0x77,0xFE,0x59,0x59,0x6A,0x01,0x68,0x86,0x01,0xE8,0x6D, -0xFE,0x59,0x59,0xD1,0x66,0x04,0x46,0x3B,0x76,0x06,0x7C,0xCD,0x33,0xF6,0xEB,0x24, -0xD1,0xE7,0x6A,0x03,0x68,0x86,0x01,0xE8,0x54,0xFE,0x59,0x59,0x6A,0x01,0x68,0x86, -0x01,0xE8,0x4A,0xFE,0x59,0x59,0x68,0x88,0x01,0xE8,0x5C,0xFE,0x59,0x98,0x25,0x01, -0x00,0x0B,0xF8,0x46,0x83,0xFE,0x10,0x7C,0xD7,0x6A,0x00,0x68,0x86,0x01,0xE8,0x2D, -0xFE,0x59,0x59,0x8B,0xC7,0xEB,0x00,0x5F,0x5E,0x5D,0xC3,0x55,0x8B,0xEC,0x56,0x57, -0x8B,0x7E,0x08,0x6A,0x01,0x68,0x86,0x01,0xE8,0x13,0xFE,0x59,0x59,0xB8,0x20,0x00, -0x2B,0xC7,0x50,0xFF,0x76,0x06,0xFF,0x76,0x04,0xE8,0xA2,0x00,0x83,0xC4,0x06,0x89, -0x56,0x06,0x89,0x46,0x04,0x33,0xF6,0xEB,0x47,0x81,0x7E,0x06,0x00,0x80,0x72,0x0C, -0x75,0x06,0x83,0x7E,0x04,0x00,0x72,0x04,0xB0,0x01,0xEB,0x02,0xB0,0x00,0x50,0x68, -0x88,0x01,0xE8,0xD9,0xFD,0x59,0x59,0x6A,0x03,0x68,0x86,0x01,0xE8,0xCF,0xFD,0x59, -0x59,0x6A,0x01,0x68,0x86,0x01,0xE8,0xC5,0xFD,0x59,0x59,0x6A,0x01,0xFF,0x76,0x06, -0xFF,0x76,0x04,0xE8,0x58,0x00,0x83,0xC4,0x06,0x89,0x56,0x06,0x89,0x46,0x04,0x46, -0x3B,0xF7,0x7C,0xB5,0x6A,0x00,0x68,0x86,0x01,0xE8,0xA2,0xFD,0x59,0x59,0x6A,0x00, -0x68,0x86,0x01,0xE8,0x98,0xFD,0x59,0x59,0x5F,0x5E,0x5D,0xC3,0x55,0x8B,0xEC,0x56, -0x6A,0x01,0x68,0x86,0x01,0xE8,0x86,0xFD,0x59,0x59,0x33,0xF6,0xEB,0x00,0x68,0x88, -0x01,0xE8,0x94,0xFD,0x59,0xA8,0x01,0x75,0x08,0x8B,0xC6,0x46,0x3D,0x64,0x00,0x7C, -0xED,0x6A,0x00,0x68,0x86,0x01,0xE8,0x65,0xFD,0x59,0x59,0x5E,0x5D,0xC3,0xC8,0x04, -0x00,0x00,0x8B,0x46,0x04,0x8B,0x56,0x06,0x8B,0x4E,0x08,0xE3,0x06,0xD1,0xE0,0xD1, -0xD2,0xE2,0xFA,0x89,0x46,0xFC,0x89,0x56,0xFE,0x8B,0x56,0xFE,0x8B,0x46,0xFC,0xEB, -0x00,0xC9,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x50,0x72,0x65,0x76,0x69,0x6F,0x75,0x73,0x20,0x4D,0x65,0x6E,0x75,0x00,0x42,0x65, -0x67,0x69,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x6F,0x72,0x74, -0x20,0x30,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x00,0x50,0x6F,0x72,0x74,0x20,0x32, -0x00,0x50,0x6F,0x72,0x74,0x20,0x33,0x00,0x50,0x6F,0x72,0x74,0x20,0x34,0x00,0x50, -0x6F,0x72,0x74,0x20,0x35,0x00,0x50,0x6F,0x72,0x74,0x20,0x36,0x00,0x50,0x6F,0x72, -0x74,0x20,0x37,0x00,0x50,0x6F,0x72,0x74,0x20,0x38,0x00,0x50,0x6F,0x72,0x74,0x20, -0x39,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x30,0x00,0x50,0x6F,0x72,0x74,0x20,0x31, -0x31,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x32,0x00,0x50,0x6F,0x72,0x74,0x20,0x31, -0x33,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x34,0x00,0x50,0x6F,0x72,0x74,0x20,0x31, -0x35,0x00,0x9C,0x01,0xA3,0x01,0xAA,0x01,0xB1,0x01,0xB8,0x01,0xBF,0x01,0xC6,0x01, -0xCD,0x01,0xD4,0x01,0xDB,0x01,0xE2,0x01,0xEA,0x01,0xF2,0x01,0xFA,0x01,0x02,0x02, -0x0A,0x02,0x08,0x00,0x00,0x07,0x81,0x00,0x03,0x80,0x80,0x80,0x9F,0x91,0x95,0x91, -0x9F,0x00,0x03,0x81,0x84,0x8E,0x95,0x84,0x84,0x84,0x84,0x00,0x03,0x82,0x84,0x84, -0x84,0x84,0x95,0x8E,0x84,0x00,0x04,0x88,0x00,0xB2,0x0B,0xC6,0x0B,0xDA,0x0B,0xEE, -0x0B,0x02,0x0C,0x16,0x0C,0x2A,0x0C,0x3E,0x0C,0x52,0x0C,0x77,0x0C,0x9C,0x0C,0xBE, -0x0C,0xE0,0x0C,0x02,0x0D,0x01,0x80,0x20,0x54,0x65,0x73,0x74,0x20,0x50,0x61,0x73, -0x73,0x65,0x64,0x20,0x1F,0x20,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x02,0x00,0x01, -0x80,0x20,0x4D,0x69,0x73,0x73,0x69,0x6E,0x67,0x20,0x52,0x78,0x20,0x44,0x61,0x74, -0x61,0x1F,0x20,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x02,0x00,0x01,0x80,0x20,0x42, -0x61,0x64,0x20,0x52,0x78,0x20,0x44,0x61,0x74,0x61,0x20,0x1F,0x20,0x50,0x72,0x65, -0x73,0x73,0x20,0x80,0x02,0x00,0x01,0x80,0x20,0x58,0x6D,0x74,0x72,0x20,0x42,0x75, -0x73,0x79,0x1F,0x20,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x02,0x00,0x01,0x80,0x20, -0x6E,0x6F,0x74,0x20,0x63,0x75,0x72,0x72,0x65,0x6E,0x74,0x6C,0x79,0x1F,0x20,0x20, -0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x65,0x64,0x02,0x00,0x24,0x0D,0x2F, -0x0D,0x3A,0x0D,0x45,0x0D,0x50,0x0D,0x5B,0x0D,0x66,0x0D,0x71,0x0D,0x7C,0x0D,0x87, -0x0D,0x92,0x0D,0x9D,0x0D,0xA8,0x0D,0xB3,0x0D,0xBE,0x0D,0xC9,0x0D,0x53,0x80,0x2C, -0x32,0x54,0x44,0x20,0x53,0x86,0x2C,0x33,0x44,0x54,0x52,0x20,0x53,0x82,0x2C,0x33, -0x52,0x54,0x53,0x20,0x1F,0x53,0x81,0x2C,0x32,0x52,0x44,0x20,0x53,0x85,0x2C,0x32, -0x43,0x44,0x20,0x53,0x83,0x2C,0x33,0x43,0x54,0x53,0x20,0x53,0x84,0x2C,0x33,0x44, -0x53,0x52,0x20,0x53,0x87,0x2C,0x32,0x52,0x49,0x27,0x02,0x00,0x01,0x80,0x20,0x20, -0x44,0x43,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x30,0x1F,0x27,0x53,0x85, -0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89, -0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x53,0x52, -0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x31,0x31,0x1F,0x27,0x53,0x84,0x2E,0x31,0x81, -0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C, -0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x43,0x54,0x53,0x20,0x2D,0x20, -0x70,0x69,0x6E,0x20,0x34,0x1F,0x27,0x53,0x83,0x2E,0x31,0x81,0x82,0x63,0x90,0x80, -0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27, -0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32, -0x32,0x1F,0x27,0x53,0x87,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84, -0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80, -0x20,0x20,0x44,0x54,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x2F,0x38,0x1F, -0x27,0x53,0x86,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86, -0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20, -0x52,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,0x27,0x53,0x82,0x2E, -0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A, -0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x78,0x44,0x20, -0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x1F,0x27,0x53,0x81,0x2E,0x30,0x53,0x4D,0x81, -0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C, -0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78,0x44,0x20,0x2D,0x20, -0x70,0x69,0x6E,0x20,0x33,0x1F,0x27,0x53,0x80,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63, -0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E, -0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x43,0x44,0x20,0x2D,0x20,0x70,0x69, -0x6E,0x20,0x35,0x1F,0x27,0x53,0x85,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82, -0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00, -0x01,0x80,0x20,0x20,0x44,0x53,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F, -0x27,0x53,0x84,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86, -0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20, -0x43,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x31,0x1F,0x27,0x53,0x83,0x2E, -0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A, -0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D, -0x20,0x28,0x6E,0x2E,0x63,0x2E,0x29,0x1F,0x27,0x53,0x87,0x2E,0x31,0x81,0x82,0x63, -0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E, -0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x54,0x52,0x20,0x2D,0x20,0x70,0x69, -0x6E,0x20,0x32,0x1F,0x27,0x53,0x86,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82, -0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00, -0x01,0x80,0x20,0x20,0x52,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x37,0x1F, -0x27,0x53,0x82,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86, -0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20, -0x52,0x78,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x1F,0x27,0x53,0x81,0x2E, -0x30,0x53,0x4D,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88, -0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78, -0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x33,0x1F,0x27,0x53,0x80,0x2E,0x30,0x53, -0x4D,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A, -0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x43,0x44,0x20, -0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x85,0x2E, -0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00, -0x01,0x80,0x20,0x20,0x44,0x53,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F, -0x20,0x20,0x20,0x20,0x27,0x53,0x84,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82, -0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x43,0x54,0x53,0x20, -0x2D,0x20,0x70,0x69,0x6E,0x20,0x31,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x83,0x2E, -0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00, -0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,0x20,0x28,0x6E,0x2E,0x63,0x2E,0x29,0x1F, -0x20,0x20,0x20,0x20,0x27,0x53,0x87,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82, -0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x54,0x52,0x20, -0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x86,0x2E, -0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00, -0x01,0x80,0x20,0x20,0x52,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x37,0x1F, -0x20,0x20,0x20,0x20,0x27,0x53,0x82,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82, -0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x78,0x44,0x20, -0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x81,0x2E, -0x30,0x53,0x4D,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27, -0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20, -0x33,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x80,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63, -0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20, -0x44,0x43,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x30,0x1F,0x20,0x20,0x20, -0x20,0x27,0x53,0x85,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85, -0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x53,0x52,0x20,0x2D,0x20,0x70, -0x69,0x6E,0x20,0x31,0x31,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x84,0x2E,0x31,0x81, -0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80, -0x20,0x20,0x43,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x34,0x1F,0x20,0x20, -0x20,0x20,0x27,0x53,0x83,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84, -0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,0x20,0x70, -0x69,0x6E,0x20,0x32,0x32,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x87,0x2E,0x31,0x81, -0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80, -0x20,0x20,0x44,0x54,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x2F,0x38,0x1F, -0x20,0x20,0x20,0x20,0x27,0x53,0x86,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82, -0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x54,0x53,0x20, -0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x82,0x2E, -0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00, -0x01,0x80,0x20,0x20,0x52,0x78,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x1F, -0x20,0x20,0x20,0x20,0x27,0x53,0x81,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63,0x88,0x80, -0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78, -0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x33,0x1F,0x20,0x20,0x20,0x20,0x27,0x53, -0x80,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86, -0x87,0x27,0x02,0x00,0x68,0x04,0x96,0x04,0xB6,0x03,0x3C,0x04,0x0E,0x04,0x89,0x03, -0x5C,0x03,0xE2,0x03,0x60,0x08,0x8A,0x08,0xBE,0x07,0x38,0x08,0x0E,0x08,0x95,0x07, -0x6C,0x07,0xE6,0x07,0x1C,0x05,0x74,0x05,0xFA,0x05,0xC4,0x04,0xF0,0x04,0xCC,0x05, -0xA0,0x05,0x48,0x05,0x78,0x06,0xC8,0x06,0x42,0x07,0x28,0x06,0x50,0x06,0x18,0x07, -0xF0,0x06,0xA0,0x06,0x00,0x00,0xF4,0x08,0xF4,0x08,0xD4,0x0D,0x04,0x09,0x04,0x09, -0x04,0x09,0x04,0x09,0x42,0x00,0x0C,0x09,0x1C,0x09,0xE5,0x0D,0x02,0x00,0x14,0x09, -0x04,0x09,0xF4,0x0D,0x43,0x00,0x1C,0x09,0x0C,0x09,0x05,0x0E,0x00,0x04,0x04,0x09, -0x14,0x09,0x12,0x0E,0x2C,0x09,0x2C,0x09,0x2C,0x09,0x2C,0x09,0x00,0x00,0x3C,0x09, -0x6C,0x09,0x1E,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0x00,0x01,0x4C,0x09, -0x2C,0x09,0x2D,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0x00,0x02,0x5C,0x09, -0x3C,0x09,0x3D,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0x00,0x03,0x6C,0x09, -0x4C,0x09,0x4D,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0xFF,0x00,0x2C,0x09, -0x5C,0x09,0x00,0x00,0x00,0x05,0x84,0x09,0xEC,0x09,0x5E,0x0E,0xF4,0x09,0xF4,0x09, -0xF4,0x09,0xF4,0x09,0x00,0x06,0x94,0x09,0x74,0x09,0x68,0x0E,0xAC,0x0A,0xAC,0x0A, -0xAC,0x0A,0xAC,0x0A,0x00,0x07,0xA4,0x09,0x84,0x09,0x72,0x0E,0xBC,0x0A,0xBC,0x0A, -0xBC,0x0A,0xBC,0x0A,0x00,0x08,0xB4,0x09,0x94,0x09,0x7C,0x0E,0xD4,0x0A,0xD4,0x0A, -0xD4,0x0A,0xD4,0x0A,0x00,0x0B,0xC4,0x09,0xA4,0x09,0x83,0x0E,0xFC,0x0A,0xFC,0x0A, -0xFC,0x0A,0xFC,0x0A,0x00,0x0C,0xD4,0x09,0xB4,0x09,0x90,0x0E,0x14,0x0B,0x14,0x0B, -0x14,0x0B,0x14,0x0B,0x00,0x02,0xE4,0x09,0xC4,0x09,0xA0,0x0E,0x2C,0x0B,0x2C,0x0B, -0x2C,0x0B,0x2C,0x0B,0x04,0x00,0xEC,0x09,0xD4,0x09,0x0E,0x00,0xFF,0x00,0x74,0x09, -0xE4,0x09,0x00,0x00,0x82,0x01,0xFC,0x09,0xA4,0x0A,0xAC,0x0E,0x82,0x02,0x04,0x0A, -0xF4,0x09,0xAF,0x0E,0x82,0x03,0x0C,0x0A,0xFC,0x09,0xB2,0x0E,0x82,0x04,0x14,0x0A, -0x04,0x0A,0xB6,0x0E,0x82,0x05,0x1C,0x0A,0x0C,0x0A,0xBC,0x0E,0x82,0x06,0x24,0x0A, -0x14,0x0A,0xC0,0x0E,0x82,0x07,0x2C,0x0A,0x1C,0x0A,0xC4,0x0E,0x82,0x08,0x34,0x0A, -0x24,0x0A,0xC8,0x0E,0x82,0x09,0x3C,0x0A,0x2C,0x0A,0xCC,0x0E,0x82,0x0A,0x44,0x0A, -0x34,0x0A,0xD1,0x0E,0x82,0x10,0x4C,0x0A,0x3C,0x0A,0xD6,0x0E,0x82,0x0B,0x54,0x0A, -0x44,0x0A,0xDB,0x0E,0x82,0x11,0x5C,0x0A,0x4C,0x0A,0xE0,0x0E,0x82,0x0C,0x64,0x0A, -0x54,0x0A,0xE5,0x0E,0x82,0x12,0x6C,0x0A,0x5C,0x0A,0xEA,0x0E,0x82,0x0D,0x74,0x0A, -0x64,0x0A,0xEF,0x0E,0x82,0x0E,0x7C,0x0A,0x6C,0x0A,0xF4,0x0E,0x82,0x0F,0x84,0x0A, -0x74,0x0A,0xFB,0x0E,0x82,0x13,0x8C,0x0A,0x7C,0x0A,0x02,0x0F,0x82,0x14,0x94,0x0A, -0x84,0x0A,0x09,0x0F,0x82,0x15,0x9C,0x0A,0x8C,0x0A,0x10,0x0F,0x82,0x16,0xA4,0x0A, -0x94,0x0A,0x17,0x0F,0x82,0x17,0xF4,0x09,0x9C,0x0A,0x1E,0x0F,0x82,0x02,0xB4,0x0A, -0xB4,0x0A,0x26,0x0F,0x82,0x03,0xAC,0x0A,0xAC,0x0A,0x2D,0x0F,0x82,0x00,0xC4,0x0A, -0xCC,0x0A,0x34,0x0F,0x82,0x01,0xCC,0x0A,0xBC,0x0A,0x3F,0x0F,0x82,0x02,0xBC,0x0A, -0xC4,0x0A,0x4D,0x0F,0x82,0x00,0xDC,0x0A,0xF4,0x0A,0x59,0x0F,0x82,0x01,0xE4,0x0A, -0xD4,0x0A,0x63,0x0F,0x82,0x02,0xEC,0x0A,0xDC,0x0A,0x6E,0x0F,0x82,0x03,0xF4,0x0A, -0xE4,0x0A,0x7A,0x0F,0x82,0x04,0xD4,0x0A,0xEC,0x0A,0x87,0x0F,0x82,0x00,0x04,0x0B, -0x0C,0x0B,0x93,0x0F,0x82,0x01,0x0C,0x0B,0xFC,0x0A,0x9B,0x0F,0x82,0x02,0xFC,0x0A, -0x04,0x0B,0xA7,0x0F,0x82,0x00,0x1C,0x0B,0x24,0x0B,0xB0,0x0F,0x82,0x01,0x24,0x0B, -0x14,0x0B,0xB5,0x0F,0x82,0x02,0x14,0x0B,0x1C,0x0B,0xBE,0x0F,0x44,0x00,0x34,0x0B, -0xA4,0x0B,0x9C,0x01,0x44,0x01,0x3C,0x0B,0x2C,0x0B,0xA3,0x01,0x44,0x02,0x44,0x0B, -0x34,0x0B,0xAA,0x01,0x44,0x03,0x4C,0x0B,0x3C,0x0B,0xB1,0x01,0x44,0x04,0x54,0x0B, -0x44,0x0B,0xB8,0x01,0x44,0x05,0x5C,0x0B,0x4C,0x0B,0xBF,0x01,0x44,0x06,0x64,0x0B, -0x54,0x0B,0xC6,0x01,0x44,0x07,0x6C,0x0B,0x5C,0x0B,0xCD,0x01,0x44,0x08,0x74,0x0B, -0x64,0x0B,0xD4,0x01,0x44,0x09,0x7C,0x0B,0x6C,0x0B,0xDB,0x01,0x44,0x0A,0x84,0x0B, -0x74,0x0B,0xE2,0x01,0x44,0x0B,0x8C,0x0B,0x7C,0x0B,0xEA,0x01,0x44,0x0C,0x94,0x0B, -0x84,0x0B,0xF2,0x01,0x44,0x0D,0x9C,0x0B,0x8C,0x0B,0xFA,0x01,0x44,0x0E,0xA4,0x0B, -0x94,0x0B,0x02,0x02,0x44,0x0F,0x2C,0x0B,0x9C,0x0B,0x0A,0x02,0x17,0x1F,0x0F,0x2F, -0x00,0x00,0x01,0x80,0x78,0x78,0x3A,0x20,0x74,0x78,0x20,0x63,0x70,0x73,0x20,0x2A, -0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0x80,0x78,0x78,0x3A,0x20,0x74,0x78,0x20,0x63, -0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0x80,0x78,0x78,0x3A,0x20, -0x74,0x78,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0x80, -0x78,0x78,0x3A,0x20,0x74,0x78,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A, -0x02,0x00,0x01,0xC0,0x78,0x78,0x3A,0x20,0x72,0x63,0x20,0x63,0x70,0x73,0x20,0x2A, -0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0xC0,0x78,0x78,0x3A,0x20,0x72,0x63,0x20,0x63, -0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0xC0,0x78,0x78,0x3A,0x20, -0x72,0x63,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0xC0, -0x78,0x78,0x3A,0x20,0x72,0x63,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A, -0x02,0x00,0x01,0x80,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x20,0x4C,0x6F,0x6F,0x70, -0x62,0x61,0x63,0x6B,0x1F,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x20,0x74,0x6F,0x20, -0x73,0x74,0x61,0x72,0x74,0x02,0x00,0x01,0x80,0x20,0x43,0x61,0x62,0x6C,0x65,0x20, -0x74,0x6F,0x20,0x52,0x65,0x6D,0x6F,0x74,0x65,0x1F,0x50,0x72,0x65,0x73,0x73,0x20, -0x80,0x20,0x74,0x6F,0x20,0x73,0x74,0x61,0x72,0x74,0x02,0x00,0x01,0x80,0x20,0x4C, -0x6F,0x63,0x61,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x20,0x1F,0x20, -0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,0x2E,0x2E,0x02,0x00,0x01,0x80, -0x52,0x65,0x6D,0x6F,0x74,0x65,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x20, -0x1F,0x20,0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,0x2E,0x2E,0x02,0x00, -0x01,0x80,0x20,0x49,0x6E,0x74,0x72,0x6E,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61, -0x63,0x6B,0x1F,0x20,0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,0x2E,0x2E, -0x02,0x00,0x01,0x80,0x54,0x72,0x61,0x6E,0x73,0x6D,0x69,0x74,0x20,0x50,0x61,0x74, -0x74,0x65,0x72,0x6E,0x1F,0x20,0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E, -0x2E,0x2E,0x02,0x00,0x01,0x80,0x20,0x20,0x30,0x3A,0x20,0x27,0x43,0x80,0x00,0x01, -0x80,0x20,0x20,0x31,0x3A,0x20,0x27,0x43,0x81,0x00,0x01,0x80,0x20,0x20,0x32,0x3A, -0x20,0x27,0x43,0x82,0x00,0x01,0x80,0x20,0x20,0x33,0x3A,0x20,0x27,0x43,0x83,0x00, -0x01,0x80,0x20,0x20,0x34,0x3A,0x20,0x27,0x43,0x84,0x00,0x01,0x80,0x20,0x20,0x35, -0x3A,0x20,0x27,0x43,0x85,0x00,0x01,0x80,0x20,0x20,0x36,0x3A,0x20,0x27,0x43,0x86, -0x00,0x01,0x80,0x20,0x20,0x37,0x3A,0x20,0x27,0x43,0x87,0x00,0x01,0x80,0x20,0x20, -0x38,0x3A,0x20,0x27,0x43,0x88,0x00,0x01,0x80,0x20,0x20,0x39,0x3A,0x20,0x27,0x43, -0x89,0x00,0x01,0x80,0x20,0x31,0x30,0x3A,0x20,0x27,0x43,0x8A,0x00,0x01,0x80,0x20, -0x31,0x31,0x3A,0x20,0x27,0x43,0x8B,0x00,0x01,0x80,0x20,0x31,0x32,0x3A,0x20,0x27, -0x43,0x8C,0x00,0x01,0x80,0x20,0x31,0x33,0x3A,0x20,0x27,0x43,0x8D,0x00,0x01,0x80, -0x20,0x31,0x34,0x3A,0x20,0x27,0x43,0x8E,0x00,0x01,0x80,0x20,0x31,0x35,0x3A,0x20, -0x27,0x43,0x8F,0x00,0x2A,0x2A,0x20,0x4D,0x61,0x69,0x6E,0x20,0x20,0x4D,0x65,0x6E, -0x75,0x20,0x2A,0x2A,0x00,0x4D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x20,0x50, -0x6F,0x72,0x74,0x00,0x4D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x20,0x53,0x69, -0x67,0x6E,0x61,0x6C,0x00,0x45,0x73,0x74,0x69,0x6D,0x61,0x74,0x65,0x20,0x43,0x50, -0x53,0x00,0x44,0x69,0x61,0x67,0x6E,0x6F,0x73,0x74,0x69,0x63,0x73,0x00,0x4C,0x6F, -0x63,0x61,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x00,0x52,0x65,0x6D, -0x6F,0x74,0x65,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x00,0x49,0x6E,0x74, -0x72,0x6E,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x00,0x54,0x72,0x61, -0x6E,0x73,0x6D,0x69,0x74,0x20,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x00,0x42,0x61, -0x75,0x64,0x20,0x52,0x61,0x74,0x65,0x00,0x44,0x61,0x74,0x61,0x20,0x42,0x69,0x74, -0x73,0x00,0x53,0x74,0x6F,0x70,0x20,0x42,0x69,0x74,0x73,0x00,0x50,0x61,0x72,0x69, -0x74,0x79,0x00,0x44,0x61,0x74,0x61,0x20,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x00, -0x54,0x78,0x20,0x46,0x6C,0x6F,0x77,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x00, -0x50,0x6F,0x72,0x74,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x00,0x35,0x30,0x00,0x37, -0x35,0x00,0x31,0x31,0x30,0x00,0x31,0x33,0x34,0x2E,0x35,0x00,0x31,0x35,0x30,0x00, -0x32,0x30,0x30,0x00,0x33,0x30,0x30,0x00,0x36,0x30,0x30,0x00,0x31,0x32,0x30,0x30, -0x00,0x31,0x38,0x30,0x30,0x00,0x32,0x30,0x30,0x30,0x00,0x32,0x34,0x30,0x30,0x00, -0x33,0x36,0x30,0x30,0x00,0x34,0x38,0x30,0x30,0x00,0x37,0x32,0x30,0x30,0x00,0x39, -0x36,0x30,0x30,0x00,0x31,0x39,0x2C,0x32,0x30,0x30,0x00,0x33,0x38,0x2C,0x34,0x30, -0x30,0x00,0x35,0x36,0x2C,0x30,0x30,0x30,0x00,0x35,0x37,0x2C,0x36,0x30,0x30,0x00, -0x36,0x34,0x2C,0x30,0x30,0x30,0x00,0x37,0x36,0x2C,0x38,0x30,0x30,0x00,0x31,0x31, -0x35,0x2C,0x32,0x30,0x30,0x00,0x37,0x20,0x62,0x69,0x74,0x73,0x00,0x38,0x20,0x62, -0x69,0x74,0x73,0x00,0x31,0x20,0x73,0x74,0x6F,0x70,0x20,0x62,0x69,0x74,0x00,0x31, -0x2E,0x35,0x20,0x73,0x74,0x6F,0x70,0x20,0x62,0x69,0x74,0x73,0x00,0x32,0x20,0x73, -0x74,0x6F,0x70,0x20,0x62,0x69,0x74,0x73,0x00,0x6E,0x6F,0x20,0x70,0x61,0x72,0x69, -0x74,0x79,0x00,0x6F,0x64,0x64,0x20,0x70,0x61,0x72,0x69,0x74,0x79,0x00,0x65,0x76, -0x65,0x6E,0x20,0x70,0x61,0x72,0x69,0x74,0x79,0x00,0x73,0x70,0x61,0x63,0x65,0x20, -0x70,0x61,0x72,0x69,0x74,0x79,0x00,0x6D,0x61,0x72,0x6B,0x20,0x70,0x61,0x72,0x69, -0x74,0x79,0x00,0x43,0x6F,0x6C,0x75,0x6D,0x6E,0x73,0x00,0x42,0x61,0x72,0x62,0x65, -0x72,0x20,0x50,0x6F,0x6C,0x65,0x00,0x55,0x55,0x55,0x55,0x55,0x2E,0x2E,0x2E,0x00, -0x4E,0x6F,0x6E,0x65,0x00,0x58,0x6F,0x6E,0x2F,0x58,0x6F,0x66,0x66,0x00,0x43,0x54, -0x53,0x00,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x20,0x66,0x6F,0x72,0x20,0x6D,0x65, -0x6E,0x75,0x00,0x28,0x63,0x6F,0x75,0x6E,0x74,0x69,0x6E,0x67,0x2E,0x2E,0x2E,0x29, -0x00,0x00,0x65,0x4E,0x64,0x20,0x4F,0x66,0x20,0x43,0x6F,0x44,0x65,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}; diff --git a/drivers/char/ip2/ip2base.c b/drivers/char/ip2/ip2base.c index 435ccfc..8155e24 100644 --- a/drivers/char/ip2/ip2base.c +++ b/drivers/char/ip2/ip2base.c @@ -21,10 +21,9 @@ #endif #include "ip2types.h" -#include "fip_firm.h" // the meat int -ip2_loadmain(int *, int *, unsigned char *, int ); // ref into ip2main.c +ip2_loadmain(int *, int *); // ref into ip2main.c /* Note: Add compiled in defaults to these arrays, not to the structure in ip2.h any longer. That structure WILL get overridden @@ -52,7 +51,7 @@ static int __init ip2_init(void) irq[0] = irq[1] = irq[2] = irq[3] = 0; } - return ip2_loadmain(io,irq,(unsigned char *)fip_firm,sizeof(fip_firm)); + return ip2_loadmain(io, irq); } module_init(ip2_init); diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index c12cf8f..e19df02 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -98,6 +98,8 @@ #include #include #include +#include +#include #include #include @@ -155,9 +157,7 @@ static char *pcDriver_name = "ip2"; static char *pcIpl = "ip2ipl"; // cheezy kludge or genius - you decide? -int ip2_loadmain(int *, int *, unsigned char *, int); -static unsigned char *Fip_firmware; -static int Fip_firmware_size; +int ip2_loadmain(int *, int *); /***********************/ /* Function Prototypes */ @@ -208,7 +208,7 @@ static int ip2_ipl_open(struct inode *, struct file *); static int DumpTraceBuffer(char __user *, int); static int DumpFifoBuffer( char __user *, int); -static void ip2_init_board(int); +static void ip2_init_board(int, const struct firmware *); static unsigned short find_eisa_board(int); /***************/ @@ -474,8 +474,27 @@ static const struct tty_operations ip2_ops = { /* SA_RANDOM - can be source for cert. random number generators */ #define IP2_SA_FLAGS 0 + +static const struct firmware *ip2_request_firmware(void) +{ + struct platform_device *pdev; + const struct firmware *fw; + + pdev = platform_device_register_simple("ip2", 0, NULL, 0); + if (IS_ERR(pdev)) { + printk(KERN_ERR "Failed to register platform device for ip2\n"); + return NULL; + } + if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { + printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); + fw = NULL; + } + platform_device_unregister(pdev); + return fw; +} + int -ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) +ip2_loadmain(int *iop, int *irqp) { int i, j, box; int err = 0; @@ -483,6 +502,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) i2eBordStrPtr pB = NULL; int rc = -1; static struct pci_dev *pci_dev_i = NULL; + const struct firmware *fw = NULL; ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); @@ -516,9 +536,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } poll_only = !poll_only; - Fip_firmware = firmware; - Fip_firmware_size = firmsize; - /* Announce our presence */ printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); @@ -638,10 +655,18 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } } for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + /* We don't want to request the firmware unless we have at + least one board */ if ( i2BoardPtrTable[i] != NULL ) { - ip2_init_board( i ); + if (!fw) + fw = ip2_request_firmware(); + if (!fw) + break; + ip2_init_board(i, fw); } } + if (fw) + release_firmware(fw); ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); @@ -769,7 +794,7 @@ out: /* are reported on the console. */ /******************************************************************************/ static void -ip2_init_board( int boardnum ) +ip2_init_board(int boardnum, const struct firmware *fw) { int i; int nports = 0, nboxes = 0; @@ -789,7 +814,7 @@ ip2_init_board( int boardnum ) goto err_initialize; } - if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size ) + if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) != II_DOWN_GOOD ) { printk ( KERN_ERR "IP2: failed to download loadware\n" ); goto err_release_region; diff --git a/firmware/Makefile b/firmware/Makefile index a561bdf..2f81089 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -21,6 +21,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # But be aware that the config file might not be included at all. fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw +fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp diff --git a/firmware/WHENCE b/firmware/WHENCE index 47ab241..6c7b0b4 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -226,3 +226,13 @@ Debug loader claims the following behaviour: Converted from Intel HEX files, used in our binary representation of ihex. -------------------------------------------------------------------------- + +Driver: ip2 -- Computone IntelliPort Plus serial device + +File: intelliport2.bin + +Licence: Unknown + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/intelliport2.bin.ihex b/firmware/intelliport2.bin.ihex new file mode 100644 index 0000000..e9cfe8c --- /dev/null +++ b/firmware/intelliport2.bin.ihex @@ -0,0 +1,2147 @@ +:100000003C4237180201030000000000000000001D +:10001000576564204465632030312031323A3234F0 +:100020003A33302031393939000000000000000037 +:10003000E96C0F426547694E6E496E47206F462056 +:10004000634F6445CC135A15E8167618041A921BB0 +:10005000201DAE1E3C20CA215823E6247426022807 +:1000600090291E2BAC2C3A2EC82F5631E432723414 +:1000700000368E371C39AA3A383CC63D543FE24020 +:100080007042FE438C451A47A848364AC44B524D2D +:10009000E04E6E50FC518A531855A6563458C2593A +:1000A000505BDE5C6C5EFA5F88611663A464326646 +:1000B000C0674E69DC6A6A6CF86D866F1471A27253 +:1000C0003074BE754C776C778C77AC7733DB8ADC19 +:1000D0005333DB250700750A8A1E080183E30CEB06 +:1000E00020903C01750A8A1E080180E3C0EB129043 +:1000F0008A1E0D013C02750680E30CEB049080E340 +:10010000C053508B1EBA138EDBE86A65558BEC53D7 +:100110001E2BC08ED88B5E04C1E304035E06D1E3C0 +:100120002E8B9F44008D472A1E5A1F5B5DC3558B43 +:10013000EC531E2BC08ED88B5E04C1E304035E0615 +:10014000D1E32E8B9F44008D47341E5A1F5B5DC345 +:10015000FB558BEC53515256571E061E0733C08E6B +:10016000D88B5E04268A47592503008BF0D1E62EF2 +:100170008BB4C400C1E0042602471AD1E08BE82EFC +:100180008BAE4400892C268A471C88440F268A4758 +:100190001D884410268A471E884411268A471F88D6 +:1001A0004412268A4720884413268A472388441409 +:1001B000268A4724884415268A475A88440E33C025 +:1001C00089440689440888440B88440AB021B464F1 +:1001D000894404894402B05588440D88440CE86A77 +:1001E00000725BE8C900E8C110894408807C0F01F7 +:1001F0007429E82B02E87F02807C0F03741DE8A9B4 +:10020000108BF82B44083DA00F7210897C0833C076 +:1002100087440685C07504C6440AFF8A440A84C020 +:10022000750BB80800E86A4AE8A90173BFE84F01F6 +:100230008166487FFF83667ABFB002E8040E8A4475 +:100240000A98071F5F5E5A595B5DC3814E48800064 +:10025000B040E83D4AE88940732AE84D108BD8B099 +:1002600005E82E4AF6462702751AE83D102BC33DD5 +:10027000581B72EB8166487FFFB002E8C40DC6448C +:100280000A01F9C3834E7A40F8C3FBB001E8024A81 +:10029000FAE8991EE40A84C075F0B04EE60AFBB095 +:1002A00001E8EE49FAE8851EE40A84C075F0C3FA55 +:1002B000E87A1EE4EC884416E4E4884417E4F888FD +:1002C0004418E4F0884419E41088441AE41288447D +:1002D0001BE41488441CE43488441DE43688441E1E +:1002E000E4D824018AE0E4DA24020AC488441F8A9C +:1002F0004410E8CD1F8A4411E835218A4412E88968 +:10030000218A4413E84321C686A10000E414241086 +:10031000E614E412243DE6128A44153C01721E776D +:1003200016B011E634B013E636E4140C10E614E40B +:10033000120C40E612EB06E4120C02E6128A440F9D +:100340003C0174063C02740AEB0EE4120C08E6123F +:10035000EB06E4120C10E612E82FFF8A44143C026C +:100360007508B05588440C88440DB021B4648944A4 +:1003700004894402E40C0C10E60CE8ED39FBC3E8F8 +:100380005F3F7308FBB00AE80849EBF3FAE89D1DEC +:100390008A64168A441789869400E6E48AC4E6ECE7 +:1003A0008A64188A441989869600E6F08AC4E6F8B9 +:1003B0008A441AE6108A441BE6128A441CE6148A10 +:1003C000441DE6348A441EE6368A441FE6D8E6DA3F +:1003D000E9B7FE90FA8A440EE6FEE402A80175052C +:1003E00033C0FBF8C333C0E400FBF9C38A64148054 +:1003F000FC02742BFEC0FEC780FF4E721C74098085 +:10040000FF507308B00AEB17B00DEB1302DC32FF9C +:1004100080FB7F7C02B3218AC33C7F7C02B021C376 +:10042000FA807C0B047602FBC38B46243D080072E5 +:10043000F68E46028B7E228A440C8B5C02AAE8ABC5 +:10044000FFAAE8A7FFAAE8A3FFAAE89FFF88440C39 +:10045000895C0280440B04897E22836E24048346D7 +:100460001A04807E26027406806626FDFBC360B0F7 +:10047000FDE8023F61FBC3FA807C0F037509C644A7 +:100480000B00E8E538FBC3C47E148B4E3A85C97572 +:1004900035268B0D4747E3EA3B7E047622B80200FF +:1004A00039462E7707C7462E0000EB138B5E2C894A +:1004B0005E0426C70700004343895E2C29462E852B +:1004C000C978CE894E3A8A440D8B5C04268A25472A +:1004D0003AC47516FE4C0BFF4406E80FFFE2ED88A8 +:1004E000440D895C04894E3AEBA7C6440AFEE879BC +:1004F00038FBC390E8B30D8AE88A0ECB13B3078AA2 +:10050000C1EEEB00EC3AC1750902CDFECB75F0EB04 +:100510000C90880ECB138AE8BBFFFFF9C3880ECB83 +:1005200013F8C390BB3F3F8A8E9E00BAFE00EC8A50 +:10053000E832C122C37502F8C3F9C390E8E5FF733E +:1005400001C3BAD000BB03038A8E9F00EC8AE83255 +:10055000C122C37502F8C3F9C39033C08ED88EC0D0 +:10056000803EC813007507B00AE82647EBF2FB335C +:10057000DB8A1EC913434383FB7E760733DBB0025D +:10058000E80F472E8BAF4400837E080074E7881E77 +:10059000C913B002E8FB46FAF7463840007414E885 +:1005A000961BE87FFF721C33D28A969F0083C20E8F +:1005B000EB0C90E8771BE883FF7208BA4800E83339 +:1005C000FF73AB23CB898E9A0089969C00FE86B57B +:1005D00000C606C81300B00AE8670AFBEB891018CA +:1005E000082833C0A005018AC824407524C7067CAA +:1005F000128E45C70642120100C606541202B00808 +:10060000F6C1017402B004A34612A24C12A29412C5 +:10061000C3C7067C12B645A00F0184C0750E6A00E0 +:100620001FC60693121E9C0EE8B10C90C70644121A +:100630000100A342128BD8C1E304881E9412BEE2CB +:10064000052BF08BC833DB8BFB2EAC888548128AD8 +:10065000D80C05E6FE8AE0EB00E4FE32C4A83F7445 +:1006600003E99E00E400888550128AE02430BA1025 +:10067000FF3C30741280FC04740ABA0403F60608C6 +:1006800001FE7403BA080F88954C1202FA32C0F6C4 +:10069000C4087402B001888558128AC43C35745B62 +:1006A0003C3674573C3474533C04744F3C14744BC4 +:1006B0003C157447A8407425C685541204D1E7B48C +:1006C000038AC389855C128AC38AE380CC01898549 +:1006D0006412D1EF47E203EB1A90E96CFFC6855430 +:1006E0001202D1E78AE68AC30C0489855C12D1EF35 +:1006F00047E2E733C08AC7A34612C3C68554120631 +:10070000EBBBC68554120033C08885501288854CD7 +:100710001288855812EBA6C7462602128B461E8900 +:1007200046008946228B4620894624C7461A000087 +:10073000C3C7463C8000C7463801001E568B763042 +:100740008976048976148E5E0633C089044646890C +:10075000762C89463A8B4632484889462E5E1FC31E +:1007600033C089464889464AC74646AE0189464E47 +:100770008B46448946508B4642894640894608C389 +:1007800033C0894676894678C7467A1000561E8B54 +:10079000767089761089760C8E5E12C70400008B05 +:1007A00046728946741F5EC3895618895602895657 +:1007B0000689560A89560E8956128956168BD84BC9 +:1007C0004BC1E302BF0200897E1E03FB897E30031A +:1007D000FB897E4203FB897E7083EB08895E20895A +:1007E0005E32895E44895E7250E82BFFE871FFE853 +:1007F0003FFFE88BFF58C3B83075C1E8040E5B03B8 +:10080000C3A3BA13833E4212007407803E941200C1 +:10081000750E6A001FC60693121E9C0EE8BD0A9054 +:10082000B8307AC1E80440A3C0132B061201F7D8F0 +:1008300033D28BCA8A0E9412F7F13D8000770E6A8C +:10084000001FC6069312259C0EE8900A90483DFFB3 +:10085000077203B8FF07A3C21333C98A0E94123379 +:10086000F6B800092E8BAC440089464C404646E25F +:10087000F38A0E941233F68B16C013A1C2132E8B7B +:10088000AC4400E822FF03D04646E2F2C333C02E58 +:100890008BAD44008946084747E2F4C35133C00A90 +:1008A000C22E8BAD440089869E00814E38002047C1 +:1008B00047FEC480FC04720432E4FEC0E2E35983C4 +:1008C000E9107405F7D9E8C4FFC35133C00AC22E3A +:1008D0008BAD440089869E00834E3840474780C4D4 +:1008E00010790432E4FEC0E2E65983E9107405F79A +:1008F000D9E899FFC3E8D2FFC38D089C08CA08F560 +:10090000088B0E421233F6515633DB8BCB8A944858 +:10091000128A8C4C128A9C54128BFEC1E70585DB2F +:100920007502B1102EFF97F9085E5946E2D9C3014E +:10093000CC03D000E802D000E801D000E800D000ED +:10094000E804D0A8DA00DC00DE01D803CC03CC0335 +:10095000CC04D0A8DA20DC00DE03CC03CC03CC002E +:10096000D803CC03CC03CC03CC03CC03CC03CC0303 +:10097000CC03CC03CC03CC03CC03CC03CC03CC03FF +:10098000CC04D000DA20DC03DE01D803CC03CC0396 +:10099000CC03CC00D800CC00D0000056521E0E1F55 +:1009A000BE2F0933D2FCAD85C0740D8AD4EEAD855F +:1009B000C074058AD4EEEBEE1F5A5EC3E48084C097 +:1009C00074167814B027E6FCB011E634E4FC3C273A +:1009D0007506E4117502F8C3F9C383C206B0BFEE11 +:1009E00083EA02B010EE8886AF00B01183C204EE35 +:1009F00083C202EEB01383C202EE83C202EE2EA1C6 +:100A00004C2D8986940083EA0EEE83C2028AC4EEDE +:100A100083C204B003EE8886A80083EA0432C0EEE5 +:100A200083C202B089EE8886A6000C06EEB040B400 +:100A30003889461CC74636380083C20432C0EE8867 +:100A400086A700C383C206B0BFEE83EA02EC3A86F3 +:100A5000AF00752483C204EC3C11751C83C206EC04 +:100A60003C13751483EA088A86A800EE83EA02EC38 +:100A700024C03CC07502F8C3F9C333C98BD18BF1D4 +:100A80008A0E9412C1E9022E8BAC4400F74638005E +:100A900020740E8A869E00E6FE32C0E68042E8FAA6 +:100AA000FE83C608E2E185D27403E80508C333C9B2 +:100AB0008BF18A0E94122E8BAC4400F7463840001E +:100AC0007406E87316E812FF4646E2EAC333C98BA0 +:100AD000F18A0E9412C1E9022E8BAC4400F746381D +:100AE00000207416E84616E8D2FE730E6A001FC690 +:100AF0000693121C9C0EE8E3079083C608E2D9C354 +:100B000033C98BF18A0E94122E8BAC4400F7463811 +:100B100040007416E82116E82AFF730E6A001FC60B +:100B20000693121C9C0EE8B307904646E2DAC30C0B +:100B300000001000131200001400283C001B3E00AF +:100B4000002A00002C0000420014D80000DA000047 +:100B50003400113600133800113A001300005650CB +:100B600052BE2F0B2EAD85C07406922EACEEEBF468 +:100B70005A585EC3532EA16022E6E4E6F08AC4E62A +:100B8000ECE6F8E8D8FFB04BE610B050E612B0380B +:100B9000E614E8AE15B046E60AE8A715B01AE60A6C +:100BA000E8A015B022E60AE89915E8FD068BD8E41E +:100BB00016A8047518E8F2062BC33D320072F06ADD +:100BC000001FC6069312239C0EE8100790E8DA0671 +:100BD0002BC33D2400771BB031E6FC565155B910AC +:100BE000002E8BAC4400814E3880004646E2F25D18 +:100BF000595EE869FFE84B15B046E60AE844155B24 +:100C0000C333F68B0E42122E8BAC4400F7463800ED +:100C1000207406E81715E85BFF83C620E2E9C38B62 +:100C2000C20504008946282EA14C2D89868E008994 +:100C300086900089869200C686A3000AC686C300F5 +:100C4000035283C2048A86A6000C06EE5A83C202AF +:100C5000B005EE8886A500C3E803FFE8E514B042BE +:100C6000E60AF74638800074062EA19C22EB042E7B +:100C7000A16C22C7461C0C008986940089869600C8 +:100C800089868E008986900089869200E6F0E6E4E7 +:100C90008AC4E6F8E6ECC686C30003E8A514B01AD9 +:100CA000E60AB0108886A500E60CC333C98BF18A2A +:100CB0000E94122E8BAC4400F7463840007406E8C0 +:100CC0007614E85AFF4646E2EAC333C98BF18A0E2E +:100CD00094122E8BAC4400F7463800207406E84C82 +:100CE00014E874FF4646E2EAC390833E441200755E +:100CF00014B001BA0601EE2AC0EEB002EEB004EE66 +:100D0000B80002EB0FBA0601B040EEB801008A0E3F +:100D10000E01D3E0A38812C3A18812A384122D2050 +:100D200000A38A122D2000A38212C706861220007B +:100D3000C70680123200C3833E44120074768B0EC5 +:100D4000421233F68AA4541284E4745F8A844812EF +:100D50000C04E6FEF6C4047425B01BBA0000EEEBEA +:100D6000002AC0BA0200EEEB00B003EEEB0032C086 +:100D7000BA0200EEEB00BA0000B000EEEB2DB01F9F +:100D8000BA0000EEEB002AC0BA0200EEEB00B0039E +:100D9000EEEB00D1E68A845D12D1EEF6D0BA020005 +:100DA000EEEB00BA0000B00AEEEB00E404EB00E466 +:100DB0000446E290C390B81400BA3EFFEFB80600B4 +:100DC000BA32FFEFB80F00BA34FFEFBA36FFEF8345 +:100DD0003E4412007516B81100BA38FFEFB8120081 +:100DE000BA3AFFEFB81B00BA3CFFEFC3B81100BA24 +:100DF00038FFEFB81200BA3AFFEFB81B00BA3CFF59 +:100E0000EFC3B8FC00BA28FFEFFB833E4412007426 +:100E100007B8CC00BA28FFEFC300FFFF202428FF4B +:100E20002CFFFF303438FFFF3C903C0F770EBB198E +:100E30000E2ED73CFF74058AD8F8C3902ADBF9C37D +:100E4000833E4412007427A00601802606013080EC +:100E50003E0601307518B90200BFC413BA0601EC92 +:100E6000A82075F8BA0401EDABE2F1EB1690B904D5 +:100E700000BFC413BA0601ECA82075F8BA0401EC4F +:100E8000AAE2F1FA90BEC413AD80E43F80FC027484 +:100E90000E6A001FC60693120A9C0EE83E0490AD2F +:100EA0003C0F75ED8AC4E881FF72E6881E1A01C600 +:100EB000068E1200B0000A061A01BA0001EEC6063C +:100EC0008F1240833E4412007506B80C00EB04906C +:100ED000B84C00BA28FFEFC3833E4412007501C32B +:100EE000A150120B0652120AC4A80874F2A00F01F6 +:100EF0002AE450FF36BA131FE8505683C4026A0032 +:100F00001F33C0A3BC13A00F01A3BE138B1EBC13C1 +:100F10008A875012F687501208740D24078AE0BEA3 +:100F2000CC00A0BC13E8943DFF06BC13FF0EBE131B +:100F300075DAC3901E33C08ED8B001E8543D1FC38C +:100F400033C98BF18A0E94122E8BAC4400C74662D3 +:100F50003844C7467CFC3BC7467EE23BC7868000E0 +:100F6000EC3CE8AB16C686C00011837E080074070F +:100F70005156E833335E594646E2CDC333C98BF14F +:100F80008BF98A0E9412C1E902E3132E8BAC440054 +:100F90008A869E0088856C1283C60847E2EDC3FAF4 +:100FA000FCB0C0BA0001EE33C08ED88EC08ED0BF68 +:100FB0001601B9CC772BCFD1E9F3ABBC4012E8D9FD +:100FC00002E8703CBECC0FE8F23CF49033C08ED8FF +:100FD0008EC08ED0F6060A0180740BBE3555E8DB54 +:100FE0003CB001E8AC3CE8B300E8F6F5E808F8E806 +:100FF0000FF9E885FAE8B6FAE8EFFCE8C210E80372 +:101000003CE8B2FDE830FDE85402C6068F12C0E8A5 +:10101000BBFAE8EBFAE8E9FBE8AFFCE88DFCE81F77 +:10102000FFE858FFE8DBFDE816FE33C0BE5A05E8CE +:101030008A3CE8A3FEE8E0FCFBBEA444E87D3CE972 +:10104000CA2D56988BF08B425285C07527C74252E5 +:10105000010053368B9C2C01F6C301750C36896850 +:10106000523689AC2C015B5EC33689AC2C013689C3 +:10107000AC1C015B5EC356988BF033ED368B841C41 +:1010800001A80175158BE833C08742523689841C4C +:1010900001A80174053689842C015EC3565133F6CC +:1010A000B80100B9080089841C0189842C014646D6 +:1010B000E2F4595EC390BB01008BE8FF4E6E740AE8 +:1010C0008BDD8B4658A80174F0C38B4648A90800F5 +:1010D0007445F7463840007427E85C1080C2068AE1 +:1010E00086A80024BF8886A800EE60B0FEE886329D +:1010F00061B002E84CFF8B464824F7894648EB175D +:10110000E82A10814E2600408A86A5000C028886B7 +:10111000A500E60C8B4648A904007414B002E8212F +:10112000FF8B464824FB89464860B0DFE8473261C0 +:1011300033C0874658F6C301750B36894758A80156 +:10114000750DE974FFA32201A8017503E96AFF89FF +:101150001E3201C3BB01008BE8F74638400074150E +:10116000E8D50F80C20AECA840750A8BDD8B465685 +:10117000A80174E3C38B462680E4FE80CC02894636 +:1011800026B002E8BCFE33C0874656F6C301750A96 +:1011900036894756A801750BEBBDA32001A8017540 +:1011A00002EBB4891E3001C3601E062BC08ED8A08E +:1011B000901284C07549A12201A8017503E8F6FECA +:1011C000A12001A8017503E88AFFA1AC13487805A6 +:1011D0007445A3AC13A1AE134878057451A3AE13A4 +:1011E000A1B0134878057463A3B013A17E124078B0 +:1011F00003A37E12B80080BA22FFEF071F61CFA0C1 +:101200009112403C02720B33C0A29112FF167C1265 +:10121000EBA4A29112EB9FA08E1232068F12A28E27 +:10122000120A061A01BA0001EEB82C01EBA4833EA3 +:101230008412107211BA28FFED0C81EFE85337BA0F +:1012400028FFED247EEFB80400EB92C6068D120154 +:10125000E83F37C6068D1200A1B213EB8B908A1EB1 +:101260000B012AFF6BC319BA62FFEFB80A00BA601C +:10127000FFEFB801E0BA66FFEFB8FFFFBA52FFEF29 +:10128000B809C0BA56FFEFC706AC132C01C706AEAB +:10129000130400C606911200C3908A1E0B012AFF98 +:1012A0006BC305D1E8A31801C39052BA50FFED5AA1 +:1012B000C39053518B1E1801B9320590E2FE4B7555 +:1012C000F7595BC3B080BA00010A061A01EEC39059 +:1012D000B040EBF2B0C0EBEEB000EBEAFA60061EF5 +:1012E000162BDB8EDB2EA1BA4C2EA3924CA09312B0 +:1012F000988BE889262D7A803ECA13007403E96B27 +:1013000042E8C0FFE8ABFFE8A8FFB020C606901295 +:1013100000FF167C128BFD83FF0A7211E8B9FFE80B +:1013200090FFE8ABFFE88AFF83EF0AEBEA0BFF745C +:101330000FE8A4FFE87BFFE89AFFE875FF4F75F11F +:10134000E895FFE86CFFEBB98A86A50024FDEE88DE +:1013500086A500C38A86A6000C02EEC38B7638F7FA +:10136000C6010074EF8B4E368B462E3BC173028B49 +:10137000C82BC189462E014E34C47E0426010D8B34 +:101380007E2C83EA04F36C8EC1897E2C3B463C7232 +:1013900012F7C62000750B83CE20897638B000E89E +:1013A000A0FCC3F7C60400741B8BD883CE108976CB +:1013B000388A86A70024FE8886A70083C208EE83A9 +:1013C000EA088BC33D40007201C3814E380004839C +:1013D000C2028A86A50024FA8886A500EEC38A8602 +:1013E000A6000C02EEC3F74638010074F18B4E2EB6 +:1013F00032DB8ABEA30083C206C476048B7E2C83B4 +:10140000F908722CECA80174168AE083EA0AEC83CE +:10141000C20A84E77551AAFEC34983F90873E5320D +:10142000FF26011C015E34897604894E2E897E2CAC +:101430003B4E3C7211F64638207401C3834E38206F +:10144000B000E8FDFBC3F64638047415834E38102F +:101450008A86A70024FE8886A70083EA02EE83C25C +:10146000023D4000725DC332FF26031C85DB740918 +:1014700026891C8BF74747494980E41E80CCC0264B +:101480008904F6C41074278B7638F7C60010740BE5 +:1014900050FE86B200B00AE8A8FB58F7C6000174F7 +:1014A0000DE882268B76388B4E2E8B7E04AB8BF725 +:1014B00033C0AB32DB8ABEA300494983F9087217F7 +:1014C000E941FF814E38000483C2F88A86A50024D2 +:1014D000FA8886A500EEC3E945FF83C208EC88863A +:1014E000AA00C0E8048AE08AC88686A90032E08B98 +:1014F0005E3E84E3744F8AC18B4E26F6C504740C9D +:10150000A808740580E1BFEB0380C940F6C50874E4 +:101510000CA802740580E17FEB0380C980884E2609 +:101520008BF08A86A50084C97408A802741524FD6E +:10153000EB06A802750D0C028886A50083EA0AEE68 +:1015400083C20A8BC684E77501C3C686BA0001B0A0 +:101550000EE8EEFAF74638000274EE837E2E06722D +:10156000E88AA6AA00C45E048B7E2CB0FFAAB00253 +:10157000AB26830703836E2E03897E2CF646382024 +:101580007401C3834E3820B000E8B6FAC39083EAF2 +:1015900008E9B4FD83C2068B5E26F6C3C075EF8BE7 +:1015A0004E1CEC8886A40083EA0AA82075028ACD26 +:1015B00032ED8B461A3BC87318014E2A2BC189465F +:1015C0001AC57600F36E8ED98976003D2000723000 +:1015D000C385C074318BC801462AC57600F36E8E70 +:1015E000D980CB02895E26E832F1F6C701751683F1 +:1015F000C202E853FDF6C710750BB002E843FAC308 +:10160000F6C70174F0C380CB02895E26F6C7017469 +:10161000DE83C202E831FDF686A40040740B80E749 +:10162000FE80CF02895E26EBCCB004E814FAC3C07A +:10163000C2C8CAC4C6CCCED0D2D8DAD4D6DCDE90EA +:10164000E90E01E4C48AE0E4C48BD083F90872F0A7 +:1016500026833F0074048BDF49498BFB8ADE83E3DA +:101660000F2E8AA72F16ABF6C4107424F7C60010ED +:10167000740B50FE86B200B00AE8C6F958F7C600EF +:1016800001740DE8A0248B76388B4E2E8B7E04AB34 +:10169000897E0433C0AB4949894E2E897E2C8BC18B +:1016A000EB4E90EB9E90E4D684C07963E6D08AC876 +:1016B00025030003D8D1E32E8BAF4400888EAE0003 +:1016C0008B4E2EC45E048B7E2C8B7638E4862407EA +:1016D0003C0375CFE41C913BC173028BC82BC189BD +:1016E000462E014E3426010FBAC400F36C897E2CBD +:1016F0003B463C721CF7C62000750B83CE208976D2 +:1017000038B000E83CF98A86AE00243FE6D6C3F93B +:10171000C3F7C60A007435F7C61000752F83CE10C4 +:10172000897638F7C60200740E50E4D824FEE6D855 +:1017300058F7C6080074155051B9E803E40A84C08C +:10174000E0FA84C07504B024E60A59583D4000739D +:10175000B58A86A50024EF8886A500E60C81CE1008 +:1017600004897638EBA00008040C0109050D020A73 +:10177000060E030B070F004080C02060A0E0105051 +:1017800090D03070B0F0E4D2E6D08AC825030003D0 +:10179000D8D1E32E8BAF4400888EAE00E4D8C0E8E9 +:1017A000048BD82E8A8766178AE08AC88686A900A5 +:1017B00032E0E4988B5E3E84E374548AC18B4E26FB +:1017C000F6C504740CA808740580E1BFEB0380C95A +:1017D00040F6C508740CA802740580E17FEB038015 +:1017E000C980884E268BF08A86A500F6C1FD740854 +:1017F000A806741924F9EB0FA8067511F6C5017532 +:10180000040C04EB020C028886A500E60C8BC6844F +:10181000E775098A86AE00243FE6D2C3C686BA00C1 +:1018200001B00EE81CF8F74638000274E6837E2EFD +:101830000672E08A86A9008AE08686AA008AC832F3 +:10184000C480C90B22C1C0E4040AE0C45E048B7EDC +:101850002CB0FFAAB002AB26830703836E2E038948 +:101860007E2CF646382075AB834E3820B000E8D188 +:10187000F7EBA090E41224DFE61281E3FE9F895E7D +:1018800026836648F7EB7390F6C72075E7E4120CE1 +:1018900020E61232C0E6C6B083E6C680CF20895E5D +:1018A000268A86A5000C028886A500E60CEB7490BB +:1018B000F6C74075D3E4120C20E61232C0E6C6B07B +:1018C00081E6C680E7DF80CB01895E26B006E8713D +:1018D000F7908A86A50024F9E60C8886A500EB43DC +:1018E000E4D4E6D08BF825030003D8D1E32E8BAFE8 +:1018F00044008B5E26F6C76075B6F6C3C075D3BAD2 +:10190000C6008B4E1C8B461A3BC8731E014E2A2BF9 +:10191000C189461AC57600F36E8ED98976003D20BE +:1019200000723D8BC7243FE6D4C385C074398BC891 +:1019300001462AC57600F36E8ED983CB02895E26D6 +:10194000E8D9EDF6C70175398A86A50024F9E60CB9 +:101950008886A500F6C71075CAB002E8E4F6EBC3A6 +:10196000F6C70174EFEBBCF6C70174DC8A86A500EC +:10197000A802741181E3FFFE81CB0002895E26EB91 +:10198000C78A86A50024FB0C02E60C8886A500EB1E +:101990009290FDF7DF7FFEFBEFBF0004000405041B +:1019A00005040104000405040504060406040504F6 +:1019B00005040604060405040504020400040504E5 +:1019C00005040104000405040504060406040504D6 +:1019D00005040604060405040504070407040504B9 +:1019E00005040704070405040504060406040504A9 +:1019F0000504060406040504050407040704050499 +:101A00000504070407040504050406040604050488 +:101A10000504060406040504050403040004050483 +:101A20000504010400040504050406040604050475 +:101A30000504060406040504050402040004050464 +:101A40000504010400040504050406040604050455 +:101A50000504060406040504050407040704050438 +:101A60000504070407040504050406040604050428 +:101A70000504060406040504050407040704050418 +:101A80000504070407040504050406040604050408 +:101A90000504060406040504050433DB8AD88A8796 +:101AA0006C12E6FEC1E302E4CEA8047509A8027434 +:101AB00003E92CFEF9C35053E8CBFC5B58A8027431 +:101AC00003E91CFEF8C333DB8AD88A876C12E6FE72 +:101AD000C1E302E9D0FB9A1AC61A00000200040012 +:101AE00002000600020004000200080002000400D8 +:101AF000020006000200040002000A0002000400C6 +:101B000002000600020004000200080002000400B7 +:101B1000020006000200040002000C0002000400A3 +:101B20000200060002000400020008000200040097 +:101B3000020006000200040002000A000200040085 +:101B40000200060002000400020008000200040077 +:101B5000020006000200040002000E000200040061 +:101B60000200060002000400020008000200040057 +:101B7000020006000200040002000A000200040045 +:101B80000200060002000400020008000200040037 +:101B9000020006000200040002000C000200040023 +:101BA0000200060002000400020008000200040017 +:101BB000020006000200040002000A000200040005 +:101BC00002000600020004000200080002000400F7 +:101BD00002000600020004000200C390DA1494150B +:101BE0005C13E613DA1BDA1BE613DA1B8B94641220 +:101BF000C1E604A80174355033C08AC2E6FEE4A0F1 +:101C000085C074278BD82E8A9FDA1A52562E8BA83D +:101C100044008B5628ECA801750D8886AD00240E73 +:101C20008AD82EFF97DC1B5E5AEBCD58A80274367B +:101C300083C61033C08AC6E6FEE4A085C074278B35 +:101C4000D82E8A9FDA1A52562E8BA844008B56281B +:101C5000ECA801750D8886AD00240E8AD82EFF975A +:101C6000DC1B5E5AEBCDC39032E48BD88BD02E8A2E +:101C70009F9A192E2297921956528AC3240303C69B +:101C800080E304D0EB2EFF97D61A585EA955007555 +:101C9000D9C3601E062BC08ED8A15C12E6FEE400FC +:101CA00022C4740833F6E8BFFFEBEE90E40407E4C7 +:101CB000041FB80080BA22FFEF61CF90601E062B90 +:101CC000C08ED8A15E12E6FEE40022C47408BE04F1 +:101CD00000E894FFEBEDE40407E4041FB80080BAC9 +:101CE00022FFEF61CF90601E062BC08ED8A15C1240 +:101CF000E6FEE40022C4741833F6E86BFFA160121C +:101D0000E6FEE40022C474E5BE0800E85AFFEBDDFD +:101D1000A16012E6FEE40022C475EDE40407E404C9 +:101D2000A15C12E6FEE4041FE404B80080BA22FFBE +:101D3000EF61CF90601E062BC08ED8A15E12E6FE2A +:101D4000E40022C47419BE0400E81CFFA16212E67C +:101D5000FEE40022C474E4BE0C00E80BFFEBDCA13F +:101D60006212E6FEE40022C475EDE40407E404A177 +:101D70005E12E6FEE4041FE404B80080BA22FFEF1E +:101D800061CF601E062BC08ED8A15C12E6FEE480F7 +:101D900084C4740833F6E853FEEBEE90B80080BAC2 +:101DA00022FFEF071F61CF90601E062BC08ED8A1C7 +:101DB0005E12E6FEE48084C47408BE0200E82CFED5 +:101DC000EBEDB80080BA22FFEF071F61CF90601ED5 +:101DD000062BC08ED8A16012E6FEE48084C474088D +:101DE000BE0400E806FEEBEDB80080BA22FFEF0764 +:101DF0001F61CF90601E062BC08ED8A16212E6FE36 +:101E0000E48084C47408BE0600E8E0FDEBEDB80091 +:101E100080BA22FFEF071F61CF90601E062BC08E95 +:101E2000D8A15C12E6FEE40022C4741833F6E83749 +:101E3000FEA16012E6FEE48084C474E5BE0400E8FE +:101E4000AAFDEBDDA16012E6FEE48084C475EDA17D +:101E50005C12E6FEE40407E4041FB80080BA22FF27 +:101E6000EF61CF90601E062BC08ED8A15E12E6FEF9 +:101E7000E40022C47419BE0400E8ECFDA16212E67D +:101E8000FEE48084C474E4BE0600E85FFDEBDCA1E0 +:101E90006212E6FEE48084C475EDA15E12E6FEE403 +:101EA0000407E4041FB80080BA22FFEF61CF601E70 +:101EB000062BC08ED8A15C12E6FEE48084C47418A0 +:101EC00033F6E827FDA16012E6FEE40022C474E5C3 +:101ED000BE0800E892FDEBDDA16012E6FEE4002200 +:101EE000C475EDE40407E4041FB80080BA22FFEFD4 +:101EF00061CF601E062BC08ED8A15E12E6FEE48084 +:101F000084C47419BE0200E8E2FCA16212E6FEE499 +:101F10000022C474E4BE0C00E84DFDEBDCA16212AB +:101F2000E6FEE40022C475EDE40407E4041FB800F3 +:101F300080BA22FFEF61CF90601E062BC08ED8A121 +:101F40005C12E6FEE48084C4741833F6E89DFCA1BC +:101F50006012E6FEE48084C474E5BE0400E88CFCF4 +:101F6000EBDDA16012E6FEE48084C475ED071FB8C6 +:101F70000080BA22FFEF61CF601E062BC08ED8A171 +:101F80005E12E6FEE48084C47419BE0200E85CFCC4 +:101F9000A16212E6FEE48084C474E4BE0600E84B4D +:101FA000FCEBDCA16212E6FEE48084C475ED071F41 +:101FB000B80080BA22FFEF61CF90601E062BC08E62 +:101FC000D8902AC0E6FEE4CEA801741433DBE8D52D +:101FD000F6EBEF90B80080BA22FFEF071F61CF90B9 +:101FE000F60605010175EDB001E6FEE4CEA8017428 +:101FF000E3BB0400E8AFF6EBC990601E062BC08E71 +:10200000D890FB90FA2AC0E6FEE4CEA802741333FF +:10201000DBE8CCF8EBECB80080BA22FFEF071F61D9 +:10202000CF90A80474F033DBE85BF7EBD590601E2B +:10203000062BC08ED890FB90FAB001E6FEE4CEA845 +:10204000027415BB0400E897F8EBEB90B80080BA77 +:1020500022FFEF071F61CF90A80474F0BB0400E8D3 +:1020600024F7EBD26A001FC6069312099C0EE86B98 +:10207000F2906A001FC6069312299C0EE85DF2904A +:10208000722072207220CE1D921CE61C1A1E722035 +:10209000821DAE1E381F7220821D72207220381FD2 +:1020A000722072207220F41DBC1C341D641E72202C +:1020B000A81DF21E781F7220A81D72207220781FA2 +:1020C000FCB940008CCBB864202BFFAB93AB93E200 +:1020D000FAC7064C00A811833E4412007520C706BB +:1020E0003C00084BC7063000BA1FC7063400FA1F71 +:1020F000F6060501017506C70638002E20C3C7067F +:102100003C00564B33DB8A1E5412C1E302021E56BA +:10211000122E8B878020A330008A1E5512C1E30245 +:10212000021E57122E8B87A020A33400C38B869EDD +:1021300000E6FE86C4E6D0C38B869E00E6FE33D260 +:102140008AD4C351B91027E40A909084C07405E280 +:10215000F659F9C359F8C384C0781E518AE88AC871 +:10216000B80100D3E0098698003AAEA00059751076 +:10217000E8A9E5834E2602F9C39889869800EBF01A +:10218000F8C384C07812518AE08AC8B80100D3E04D +:1021900059F7D021869800C3C78698000000C383F2 +:1021A000C2048A86A6000C04EE83EA04C3E893FF07 +:1021B0007204B082E60AC38B4626A8FD74118A8693 +:1021C000A500A806740824F98886A500E60CC3F6C5 +:1021D000C401740A8A86A50024FB0C02EB0CA80239 +:1021E000750F8A86A50024FD0C043A86A50075D8D3 +:1021F000C38A86A500EBCFE4D833DB8AD8C0EB04D2 +:102200002E8A9F6617889EA9008B5E2680E33FF684 +:10221000C7047407A810750380CB40F6C70874077D +:10222000A880750380CB40885E268A86A500F6C309 +:10223000FD740DA806740824F98886A500E60CC371 +:10224000F6C70174040C02EBF0F6C30275E90C0446 +:10225000EBE7C404C4048504590448044104C303DF +:10226000820341038202570241028201410182003E +:1022700041004E02AD0157012D002B002700210027 +:102280001600F404F404A3046F045B045104F40383 +:10229000A3035103A3026D025102A3015101A30044 +:1022A00051006202D9016D01380036003100290069 +:1022B0001B005157BF0200EB0F905156BF0100EBBE +:1022C00007905156BF0300903C197602B017988BC7 +:1022D000F08A82C4002AE48BF083FE187346D1E6AC +:1022E0002E8B8C5222F74638800074052E8B8C8200 +:1022F00022F7C7020074123B8E9400740C898E94EE +:10230000008AC5E6EC8AC1E6E4F7C7010074123B17 +:102310008E9600740C898E96008AC5E6F88AC1E60E +:10232000F05E59C377068B8E8E00EBC58B8E9000C6 +:10233000EBBFD503F6003E0010000400CA043301D1 +:102340004D00140005000103050709000102030404 +:1023500080841E00A02526000000608BF033FF2E35 +:10236000A150232E8B165223BB3223F74638800010 +:10237000740C2EA154232E8B165623BB3C23B90577 +:10238000002E3B31730A4747E2F7B8FFFFEB1D9081 +:10239000D1EF2E8A8D46232AEDD1EAD1D8E2FAF781 +:1023A000F6050200C1E8022E8AA54B232EA358236E +:1023B000612EA15823C3080020008000000260099C +:1023C0000800200080000002000800000100020058 +:1023D0000300040052565785C074053D0109760379 +:1023E000B80109BF5B01F7463880007403BFB20132 +:1023F00033F62E3B84B62376044646EBF5F7E72EFC +:102400008BBCC02303C783D200D1E7F7F72E8AA481 +:10241000CA235F5E5AC3E43E80BEC30003750CF757 +:10242000467A200074050C80E63EC3247FE63EC356 +:1024300024038886C3008AE0E41024FC0AC4E61062 +:10244000808EA10042E8CEFFC390568BF083E60752 +:10245000D1E62EFFA458249068246C2470247424A0 +:102460007824872487248724B400EB0EB4C0EB0AB9 +:10247000B440EB06B420EB02B4A0E410241F0AC45D +:10248000E610808EA100425EC3903C0277128AE083 +:10249000E41024F3C0E4020AC4E610808EA10042D6 +:1024A000C3908B5E3884C0741F3C02742083CB08B9 +:1024B0008B462E3B463C770CE888FC7207B024E63E +:1024C0000A83CB10895E38C383E3F7EBF7F7C310B9 +:1024D0000074F5E86DFC72EC8A86C000E638B02323 +:1024E000E60AEBE08B5E388B462E3B463CE4D87721 +:1024F0000B24FE80CB12E6D8895E38C30C0180CB5A +:1025000002EBF35033DBC1E804250F0F8AD82E8A83 +:102510008766178ADC2E8AA7661709463E58C3507D +:1025200033DBC1E804250F0F8AD82E8A8766178A05 +:10253000DC2E8AA76617F7D021463E58C38B463E4D +:1025400033DB8AD80ADC2E8A877617E62C8AE0E409 +:102550002A240F0AC4E62A8A86A50084E4750DA8F9 +:10256000807411247F8886A500E60CC3A8807504BA +:102570000C80EBF1C31E6033C933D233F68ED98D94 +:10258000BEFD00578B0584C074168BD1428BFE4F65 +:10259000780938A3E40074084F79F788A2E400466C +:1025A0005F83C7094183F91072D989B6860089967D +:1025B0008400611FC353C7466600008B4664A94070 +:1025C00000740DB300A980007402B37F889EC1001F +:1025D00032DBA90200740380CB40A9004074038061 +:1025E000CB02A90080740380CB01A9301E74038044 +:1025F000CBBCA90020740380CB08A904017403801C +:10260000CB10A90800740380CB20889EC2005BC356 +:102610000651575016078DBEC400B91F0033C0AA1B +:1026200040E2FC8B86920089868E00898690005855 +:102630005F5907C3E4D8C0E80453250F008BD82E98 +:102640008A8766178886A9005AC30886AC00C686A2 +:10265000BA0001B00EE8EAE9C3AD36A3B413AD3653 +:10266000A3B613AD36A3B81383E90636F706B6133F +:102670000F00C38A4626F74648800074020C108873 +:1026800086BD0032C0837E1A00750E8B5E4043808B +:10269000E3FE3B5E0875020C01837E3A00750D1E59 +:1026A000C55E148B1F1F85DB75020C02F7463810C0 +:1026B0000074020C048B5E7AF7C3020074020C08EB +:1026C000F7C3040074020C10F7C3080074020C2056 +:1026D000F7C3400074020C408886BF00C3906A00B4 +:1026E0001FC60693120D9C0EE8F1EB90B002E6DADD +:1026F000F8C333C0E6DAF8C3B001E6D8F8C333C094 +:10270000E6D8F8C3B0FFE84EFAE8A1FAF8C3AC493E +:10271000E8AFFBF8C390AC49E815FDF8C390AC49AD +:10272000E867FDF8C390AC49E81FFDF8C390AC49D9 +:10273000E634F8C3AC49E636F8C3AC493C02771F2F +:1027400084C0751DE41424EFE614E412243FE6125D +:10275000E416A8047409E8EAF97204B018E60AF865 +:10276000C38AE0E4140C10E614E4120CC0F6C401B1 +:102770007402247FE612F8C3AC49E825FDF8C39043 +:10278000B80040E87DFDE8B4FDE8A8FEB001E8B976 +:10279000FEF8C390B80040E885FDE8A0FDF8C390BE +:1027A000B80010E85DFDE894FDE888FEB008E899FF +:1027B000FEF8C390B80010E865FDE880FDF8C3900E +:1027C000B80080E83DFDE874FDE868FEB002E879F5 +:1027D000FEF8C390B80080E845FDE860FDF8C390BE +:1027E000B80020E81DFDE854FDE848FEB004E859B3 +:1027F000FEF8C390B80020E825FDE840FDF8C3903E +:10280000AC49E84814E43C24E70AC4E63CF8C39029 +:10281000B8FC3B89467CE43C0C18E63CF8C3E41267 +:102820000C02E612F8C3E41224FDEBF6E8B5FCF85E +:10283000C390836638FDF8C3AC49A8017406834E83 +:102840007A20EB0483667ADFE8CBFBF8C3908A86B4 +:10285000A5000C0224FB8886A500E60C814E26010B +:1028600020AC4932E489466E834E48084946F9C394 +:102870008A86A5000C0224FB8886A500E60C814E02 +:10288000260120ACB40AF6E4EBD8E8FA13E43C24C1 +:10289000F80AC4E63CF8C390AD4949894664A901E9 +:1028A00000741B8BD883E3FA751AA90400740FE433 +:1028B0003E0C02E63EB83844894662F8C390E43ED6 +:1028C00024FCEBEFE43E24FCE63EE8E8FCB8AA403A +:1028D000EBE6E86EF87205B018E60AF8C390AC496A +:1028E000E8CFF9F8C390AC49E8CFF9F8C390E868AD +:1028F000FD750632C0E6DAF8C3B002E6DA36A0B4F7 +:102900001324103410E8160136A1B413A901007481 +:1029100005E8FCFEEB0EA90200740432C0EB02B025 +:1029200001E8DEFE36A1B413E8B513E43C24F80A4E +:10293000C4E63C36A1B413C1E805250100E8FAFE5F +:1029400036A0B5132410E859FB32C0368A26B513D9 +:10295000F6C4047409FEC0F6C4087402FEC0E8DBC5 +:10296000FD36A1B613250F00E857F936A1B613C1FD +:10297000E804250300E8B8FA36A1B613C1E8052536 +:102980000200E805FB36A1B613F6C401750432C097 +:10299000EB0980E402D0ECB0022AC4E8ACFA36F6C7 +:1029A00006B713407405E883FEEB03E884FE36F6B1 +:1029B00006B713207405E865FEEB03E868FEF8C36C +:1029C000E4120C01E612F8C3E41224FEEBF6E41460 +:1029D00024F00C05E614E42A24F00C06E62AF8C3D9 +:1029E000E42A24F0E62AE41424F00C07E614F8C3E1 +:1029F000AD4949E864F989868E00F8C3AD4949E8D4 +:102A000058F989869000F8C3834E2604E8A8F7F8A1 +:102A1000C390836626FBE89EF7F8C390AC4984C058 +:102A2000750DE41024EFE610808EA10042F8C3E497 +:102A3000100C10EBF190AC493C02760232C0C0E0C1 +:102A400004A82074020C0824188AE0E41224E70A7F +:102A5000C4E612808EA10044F8C3AC498886C00049 +:102A6000F8C3AC49E63AF8C3AC4984C07408E41230 +:102A70000C04E612F8C3E41224FBEBF6AC49E8D6EA +:102A8000F67303E827F7F8C3E412A802740424FDE0 +:102A9000E612B8F000E887FA816626FFF3E857F7F8 +:102AA000E89AFAF8C390B88000E857FA804E2708F1 +:102AB000E844F7E887FAF8C3B88000E861FA81666D +:102AC00026FFF7E831F7E874FAF8C390B81000E889 +:102AD00031FA804E2704E81EF7E861FAF8C3B8100F +:102AE00000E83BFA816626FFFBE80BF7E84EFAF8B0 +:102AF000C39033C0AC493C017304B001EB063C0CFD +:102B00007602B00C89461CF8C390814E2600208ABC +:102B100086A5000C0224FB8886A500E60C834E26C1 +:102B200001F8C390814E2600408A86A5000C0288D9 +:102B300086A500E60CF8C390AC4950E805F658723B +:102B400008E638B023E60AF8C3F9C390AC50ADE804 +:102B500082F85AF6C201741239869600740C89867E +:102B60009600E6F086E0E6F886E0F6C202741039D8 +:102B7000869400740A89869400E6E486E0E6EC8395 +:102B8000E903C390E4168886BC00E8E6FA33DBE488 +:102B90000CA806740380CB01A810740380CB02A894 +:102BA00080740380CB04E4128AE024180AD8E4DAA3 +:102BB000F6C4027407A840750380CB20A8027509EB +:102BC000E42AA80F740380CB40F74638020074094A +:102BD000E4D8A801750380CB80889EBE00FE86B431 +:102BE00000B00AE85CE4F8C3AC493C027441771FCA +:102BF00050E84FF558720C84C0740AB012E60A808F +:102C00004E3801F8C3B011E60A806638FEF8C38B6F +:102C1000463825FFF7894638A9000475E68A86A557 +:102C200000A81075DE0C108886A500E60CF8C3819C +:102C30004E3800088A86A500A81074C724EFEBE779 +:102C4000AD49493C0172113C0C770D508AE0E41407 +:102C500025F00F0AC4E614588AC484C07402E64200 +:102C6000F8C3E8CFF9FE86B900B00EE8D4E3F8C3A4 +:102C70003A86AF00741F8886AF008AE080C206B033 +:102C8000BFEE80EA028AC4EE8A86A80080C202EE05 +:102C900080EA068AC4C38B463E85C08A86A5007436 +:102CA00012A808750D0C088886A50080C202EE8067 +:102CB000EA02C3A80874FB24F7EBEC8B462684C019 +:102CC00074168A86A500A802740D24FD8886A500C6 +:102CD00083C202EE83EA02C38A86A500A80275F7C2 +:102CE0000C02EBE85283C20CECC0E8048886A90011 +:102CF0008B5E2680E33FF6C7047407A8087503803F +:102D0000CB40F6C7087407A802750380CB80885EA5 +:102D1000268A86A50084DB7410A802740A24FD8824 +:102D200086A50083EA0AEE5AC3A80275FA0C02EBE4 +:102D3000EE90FFFF00480030BA20C41A00180012BD +:102D4000000C0006000300028001C000600030009B +:102D50001800CD0100018000100010000E000C00D2 +:102D6000080000000000060004000300020001004B +:102D70005251563C1E7747988BF08A82C40032E449 +:102D800083FE18743D83FE19743E83FE1E772FD197 +:102D9000E62E8B8C322D3B8E94007422898E94000B +:102DA00083C2068A86A8008AE00C80EE83EA068A3F +:102DB000C1EE83C2028AC5EE83C2048AC4EE5E59A4 +:102DC0005AC38B8E8E00EBCE8B8E9000EBC8525187 +:102DD0003D05007703B805008BC8BA0200B800D0E3 +:102DE000F7F1050100D1E8595AC38B467AA820743F +:102DF0000B80BEC3000375040C01EB0224FE894660 +:102E00007AC324038886C3008AA6A8008ADC80E4EB +:102E1000FC0AC43AC3740B8886A80083C206EE83FA +:102E2000EA06E8C5FFC30008183828903C04772359 +:102E300032E48BD82E8A87262E8AA6A8008ADC80C8 +:102E4000E4C70AC43AC3740B8886A80083C206EE9E +:102E500083EA06C384C07402B0048AA6A8008ADC90 +:102E600080E4FB0AC43AC3740B8886A80083C206B8 +:102E7000EE83EA06C3908B5E3884C074343C0274DF +:102E80003B8A86AF000C04E8E6FD8B462E3B463CB1 +:102E9000771BF7C30004751581CB000483C2028A37 +:102EA00086A50024FA8886A500EE83EA02895E38AA +:102EB000C38A86AF0024FBE8B6FDEBF1F7C3100030 +:102EC00074EFEBED83C20CEC83EA0CC0E804888657 +:102ED000A900C3908A86A7000C018886A7008BDA18 +:102EE00080C208EE8BD3F8C38A86A70024FEEBEAE3 +:102EF0008A86A7000C02EBE28A86A70024FDEBDAA3 +:102F0000B0FFE852F2E897F2F8C3AC49E861FEF886 +:102F1000C390AC49E8EBFEF8C390AC49E835FFF844 +:102F2000C390AC49E805FFF8C3905283C206B0BF16 +:102F3000EE5283C202AC49EE5A8A86A800EE5AF8D5 +:102F4000C3905283C206B0BFEE5283C206EBE69036 +:102F5000AC493C02770D84C0750B8A86AF0024FD16 +:102F6000E80DFDF8C3508A86AF000C02E801FD5B56 +:102F700083C2088A86A700F6C301740C24DF888602 +:102F8000A700EE83EA08F8C30C20EBF2AC49E8E5B1 +:102F9000FEF8C390B80040E869F5E8F9FCE824FFC2 +:102FA000B001E8A5F6F8C390B80040E871F5E8E58F +:102FB000FCF8C390B80010E849F5E8D9FCE804FF34 +:102FC000B008E885F6F8C390B80010E851F5E8C5F8 +:102FD000FCF8C390B80080E829F5E8B9FCE8E4FE05 +:102FE000B002E865F6F8C390B80080E831F5E8A5CE +:102FF000FCF8C390B80020E809F5E899FCE8C4FEA5 +:10300000B004E845F6F8C390B80020E811F5E8856B +:10301000FCF8C390AC49E8340CF8C390B8FC3B8989 +:10302000467CF8C38A86AF000C80E843FCF8C39066 +:103030008A86AF00247FEBF28A86AF000C40E82F2F +:10304000FCF8C3908A86AF0024BFEBF2AC49A8011C +:103050007407834E7A20EB059083667ADFE88AFD59 +:10306000F8C383C2068A86A8000C408886A800EEB2 +:1030700083EA06AC4932E489466E834E2601834ECC +:103080004808B006E8BBDF4946F9C39083C2068A08 +:1030900086A8000C408886A800EE83EA06ACB40A35 +:1030A000F6E4EBD0E8E00BF8C390AD4949894664FB +:1030B000A9010074198BD883E3FA750AA904007476 +:1030C0000DB8E23FEB0BE8ECF4B8AA40EB03B838DC +:1030D00044894662F8C38A86AF00A802740A24FDB8 +:1030E000E88DFB0C02E888FBF8C3AC49E881FCF8EA +:1030F000C390AC49E879FCF8C390E85CF57505E845 +:10310000E6FDF8C3E8CDFD36A0B41324103410E872 +:10311000260136A1B413A901007405E8FEFEEB0EEA +:10312000A90200740432C0EB02B001E8E8FE36A147 +:10313000B413E8AB0B36A1B413C1E805250100E8D0 +:103140000CFF36A0B5132410E82BFD32C0368A26BA +:10315000B513F6C4047409FEC0F6C4087402FEC0B8 +:10316000E8EFFD36A1B613250F00E803FC36A1B643 +:1031700013C1E804250300E888FC36A1B613C1E8B2 +:1031800005250200E8CDFC36A1B613F6C40175048E +:1031900032C0EB0980E402D0ECB0022AC4E88CFC17 +:1031A00036F606B713407405E88DFEEB03E894FE8F +:1031B00036F606B713207405E869FEEB03E870FEE7 +:1031C000F8C3F8C38B4638A9040075230D040089A1 +:1031D000463883C2088B462E3B463C7314834E38D8 +:1031E000108A86A70024FE8886A700EE83EA08F8E6 +:1031F000C38A86A7000C01EBEE908B4638A9040029 +:10320000740625FBFF894638F8C3AD4949E8BEFB83 +:1032100089868E00F8C3AD4949E8B2FB89869000E3 +:10322000F8C3834E2604E892FAF8C390836626FB1F +:10323000E888FAF8C390AC4984C07507808EA30073 +:1032400004F8C380A6A300FBF8C3AC4983C2083CC2 +:1032500002760232C03C017412770B8A86A70024E2 +:10326000EF8886A700EE83EA08F8C38A86A7000CD9 +:1032700010EBEE905283C206B0BFEE5283C204AC94 +:1032800049EE5A8A86A800EE5AF8C3905283C206C5 +:10329000B0BFEE5283C208EBE690AC49F8C3AC492C +:1032A000E8B4EE7303E8F7EEF8C38A86AF00247F34 +:1032B000E8BDF9B8F000E866F2816626FFF3E8237E +:1032C000FAE8D2F9F8C3B88000E837F2804E270850 +:1032D000E811FAE8C0F9F8C3B88000E841F2816665 +:1032E00026FFF7E8FEF9E8ADF9F8C390B81000E85A +:1032F00011F2804E2704E8EBF9E89AF9F8C3B81008 +:1033000000E8FFF1816626FFFBE8D8F9F8C3AC4975 +:10331000F8C383C2068A86A8000C408886A800EEFF +:1033200083EA06F8C39083C2068A86A80024BFEB0E +:10333000EA90AC498AE080C20AEC80EA0AA82074CC +:10334000058AC4EEF8C30651578B4E24E3344989ED +:103350004E24FF461A8E46028B7E228AC4AA897E9C +:10336000228B462624FD89462675298A86A500A833 +:1033700002752180C2020C028886A500EE80EA0256 +:10338000EB12C47E003B7E1E760A4F268825897E7E +:1033900000FF461A5F5907F8C390ACAD83E9038577 +:1033A000C074053D00207205B8FFFFEB03C1E003C8 +:1033B0003B8694007426898694008BD85283C2067B +:1033C0008A86A8008AE00C80EE83EA068AC3EE8330 +:1033D000C2028AC7EE83C2048AC4EE5AF8C3B08818 +:1033E0008886BC00E88CF233DB8A86A500A80274CC +:1033F0000380CB01A805740380CB02A80874038066 +:10340000CB04F686A70010740380CB108A86A9002F +:10341000F6C304750A83C20CEC83EA0CC0E8048A84 +:10342000E08A86AF00A8807408F6C401750380CBDB +:1034300020F686A70002750AF74638040074038058 +:10344000CB40889EBE00FE86B400B00AE8F3DBF8ED +:10345000C3FE86B400B00AE8E8DBF8C3AC493C021E +:103460007437771084C07406804E3801F8C38066C4 +:1034700038FEF8C38B463825FFF7894638A9000483 +:1034800075EA8A86A500A80175E20C0583C2028848 +:1034900086A500EE83EA02F8C3814E3800088A86CA +:1034A000A500A80174C624FAEBE2AD4949F8C3901F +:1034B000E811FAFE86B900B00EE886DBF8C3B0FF6B +:1034C000E8BFECF8C39083667AFBB000E873DBF8E2 +:1034D000C390AC49E853D9721136881E1A0136A040 +:1034E0008E120AC352BA0001EE5AF8C3AC4932E454 +:1034F00036A38612050600368B1E88122BD8368915 +:103500001E8A12F8C390AD8BD8AD83E90403C32B98 +:103510004676894678F7467A0200740A83667AFD11 +:10352000B80000E81CDBF8C3061607AC49250F00FD +:103530006BC0098DBEFD0003F8AC49250F00AA85BC +:10354000C074082BC8518BC8F3A459E827F0E8448D +:103550000307F8C333C0AC4936A3B21336A3B01384 +:10356000F8C383667AEFE82C03F8C390834E7A1091 +:10357000EBF4E89BF0F8C390AD3C19770E3C19775B +:103580000A8BF881E7FF0088A6C400F8C390834E39 +:103590002620AC4932E4D1E08BD8C1E30203C389D1 +:1035A000466E834E4804B006E897DA4946F9C39060 +:1035B000FE86B300B00AE889DAF8C39033C0AC499C +:1035C0006BC00A89868A00F8C390AC4932E43D0A90 +:1035D000007705B80A00EB083D5A007203B85A009C +:1035E00051F7D80564008BC88B4644F7E1B96400F5 +:1035F000F7F189464659F8C3AC49E885EBF8C39022 +:10360000AC4984C07507816638FFFDF8C3814E3828 +:103610000002F74638400075088A86A9008886AA05 +:1036200000F8C3905156E87F0C5E59F8C390FE86AF +:10363000B600B00AE80BDAF8C390FE86B700B00A0D +:10364000E8FFD9F8C390FE86B800B00AE8F3D9F8CD +:10365000C39000905155AC2EA2523633C9AD8BF9B0 +:10366000C1E705A9010074232E8BAD4400837E08B9 +:103670000074182E803E523601740960B004E8BB15 +:103680000C61EB0760B0FBE8EC0C614747D1E875D3 +:10369000D24183F90472C65D5983E905F746384083 +:1036A000007405E887EAF8C3E88DEAF8C39036C6E7 +:1036B00006C81301F8C333C0AC4936A38012AC4925 +:1036C000362B068812F7D836A38212F8C390DE266E +:1036D000DE26EC26F226F826FE2604270E271627DD +:1036E0001E2726272E273427BE34C634D2343A2745 +:1036F000782780279427A027B427C027D427E0273E +:10370000F42700281028EC34DE261E2826282C2832 +:10371000322838284E288A28063528359828BE2889 +:10372000D228DE28E628543562356C35EE28C029CB +:10373000C829CE29E02972357835F029FC298E3543 +:10374000082A122A1C2AB035362ABC355A2A622A7F +:10375000682ACA357C2AF835882AA62AB82ACC2AAB +:10376000DE2AF22A00360A2B242B2436382B4C2B47 +:10377000842B2E363A3646365436E82BAE36402C5D +:10378000622CB6367028DE26DE26D42EE82EF02EE9 +:10379000F82E002F0A2F122F1A2F222F2A2F422FF6 +:1037A000BE34C634D234502F8C2F942FA82FB42F70 +:1037B000C82FD42FE82FF42F083014301C30EC34ED +:1037C000DE2624303030383044304C306230A43083 +:1037D00006352835AA30CE30D630EA30F2305435AE +:1037E00062356C35FA30C231C231C431FA317235CA +:1037F00078350A3216328E3522322C323632B035D6 +:103800004A32BC3574328C329A32CA359E32F8351F +:10381000AA32C632D832EC32FE320E3300361233C0 +:103820002633243632339A33DE332E363A36463652 +:1038300054365C34AE36AA34B034B6368C30E32815 +:10384000F7463840007532E8E3E833C0AC493D5BE9 +:103850000077198BD8D1E32EFF97CE36720B85C92E +:1038600075E88B4648E81A0CC34E41C36A001FC670 +:103870000693120C9C0EE863DAE8BCE833C0AC494E +:103880003D5B0077E78BD8D1E32EFF97863772D95F +:1038900085C975E8C3F7467A1000750F83BE8400AA +:1038A000007408B8483A89868000C381BE8000EC65 +:1038B0003C74F783BE8800007505B8EC3CEBE7F775 +:1038C000467A080075401E608B8E88003B4E7477E8 +:1038D000333B4E78772EC47E108BDF26033D47475F +:1038E00033C08ED88DB6F4008BC1F7467A010075CF +:1038F0001DF3A4260107294678014676294674B0AF +:103900000CE83ED7611FC78688000000EBACE3E3FC +:103910005090AC247FAAE2FA58EBD8908B8E8800A6 +:10392000E3468B9E8A0085DB743EBA50FFED2B8602 +:1039300082003BC372378DB6F400C47E108BDF2645 +:10394000033D47478BC1161FF7467A01007524F3E4 +:10395000A4260107294678014676294674C7868839 +:10396000000000B00CE8DAD683667AF7C3B000E84E +:10397000D0D6C3E3DC50AC247FAAE2FA58EBD29055 +:103980001E6033C08ED88DB6FD008B8688008B9666 +:1039900084003A0475108BDE468BC88DBEF400F3AC +:1039A000A674668BF39083C6094A75E68DB6FD0052 +:1039B0008B9684003A0473108BDE468BC88DBEF460 +:1039C00000F3A674768BF39083C6094A75E68DB62C +:1039D000F400ACF7467A01007402247F1EC55E1025 +:1039E0008B37884002468937FF4E78FF4676FF4E78 +:1039F000741F8B8E880049898E8800E3438DB6F44E +:103A0000008BFE46F3A4E97DFFC576108B1C85DB99 +:103A1000740803F383C60383E6FE8B8684002BC2FF +:103A2000B48089044646C7040000897610834E7A24 +:103A300004C78688000000611FF9C333C0611FC33B +:103A4000B08084C0611FC3908B4E782B8E88007627 +:103A50002789B68C008B5E743BCB72028BCB3BC844 +:103A600072028BC88BC1E34433D28EC28BD183BE2A +:103A70008800007406E98E0033C0C38B5E10031FFC +:103A8000434352F7467A0100752AAC8DBEE4008BA1 +:103A90008E8600F2AE74348807434A75ED588B5E0B +:103AA0001001072946780146762946748BC62B8675 +:103AB0008C00C390AC8DBEE4008B8E8600F2AE7499 +:103AC0000A247F8807434A75EBEBD28886F400C747 +:103AD0008688000100582BC2740E8B5E10010729E6 +:103AE000467801467629467440E894FE72BE4A75CF +:103AF0001583BE8A000074B4BA50FFED8986820037 +:103B0000834E7A08EBA68DBEF40003BE8800A4FFA6 +:103B1000868800E86AFE729479064A748FE95BFF32 +:103B20004A74CEEBE19050E811CC8B467439467262 +:103B300074271E565133C9C5760CAD74107809032D +:103B4000C805010024FE03F03B761076ED294E7681 +:103B5000014E78E837CC595E1F58C390C47E1026BA +:103B60008B1D83C30326891D4B03FBAB91AAB803AE +:103B700000294678014676294674C390C47E1026F3 +:103B80008B1D4326891D4303FBAAFF4E78FF467613 +:103B9000FF4E74C3E8E5FFC38081848582838687F6 +:103BA00050538ADC83E30ED1EB2E8A87983B08863C +:103BB000B000FE86B100B00AE887D45B58C3508AD3 +:103BC000C8B8FF00E895FF58C3908A86BB00E8ABF1 +:103BD000FFC3E8CBFFE8F2FFC390E8C3FFE8B4FF00 +:103BE000C39033C0E895FFC3B8FF0033C9E86CFF4A +:103BF000C390B8FF01B110E862FFC390C3FC3BE281 +:103C00003BF23BF23BFC3BE23BE83BE83BFC3BE26C +:103C10003BE83BE83BFC3BE23BE23BE23B00100085 +:103C20000000100000001000000010000000100054 +:103C3000000010000000100000001000000008004C +:103C40000000080000000800000008000051538B2D +:103C50004E3881E1FFEEA804740481C900018AE0B6 +:103C600080E4032418D0E40AC433DB8AD82E8B877F +:103C7000FD3B89467C2E0B8F1D3C894E38D1EB2EA7 +:103C80008AA73D3C5B59C3AC493C01721D74203C82 +:103C900003722374283C08722B74303C20723774F2 +:103CA0003ABBDA3B32E4895E7EC3BBA03BEBF5BB9B +:103CB000943BB401EBF0BBFC3BB402EBE9BBE23B51 +:103CC000B403EBE2BBBE3BB404EBDBBBCA3BAC4989 +:103CD0008886BB00EBCEBBD23BEBF3BBFC3BEBC41B +:103CE000A9040075D1A9080075DAEBD18B5E748B3D +:103CF0004E783BCB72028BCB3BC872028BC88BC118 +:103D0000E32CC47E108BDF26033D4747F7467A013C +:103D100000751CF7C70100740249A4D1E9F3A5732B +:103D200001A4260107294678014676294674C35026 +:103D300053BB7F7FF7C70100740549AC22C3AAD1EA +:103D4000E9E31D9CAD23C3AB497414AD23C3AB4958 +:103D5000740DAD23C3AB497406AD23C3ABE2E59D3F +:103D60007304AC22C3AB5B58EBB8E8CEC98B5E38AA +:103D7000F7C310047501C3F7C340007405E8B8E346 +:103D8000EB03E8A8E3816638EFFBF6C310743CF65A +:103D9000C3027406E4D80C01E6D8F6C30474118398 +:103DA000C2088A86A7000C01EE8886A70083EA086D +:103DB000F6C308740FE88BE3720A8A86C000E638FF +:103DC000B023E60AF7C300047501C3F7C300087502 +:103DD000F98A86A500F6C340750DA81075EC0C1085 +:103DE0008886A500E60CC3A80175DF83C2020C0516 +:103DF000EE8886A500C3B000E847D2EB0FB002E81A +:103E0000900EEB08836638DF834E7A0233C08ED87B +:103E1000FAA0921240A292123C05721EC60692129D +:103E200000FBB001E86B0EFAA1260123062A01A8C7 +:103E3000017507E8E207E8610990B000E837D2FBB6 +:103E400085ED74B9FAF7467A460075C08B46783D21 +:103E50000A0072B08B4E7483F950729A836638DF11 +:103E6000C576148B463A85C07558AD85C0750FE888 +:103E7000F8FEF7467A08007493E8A0FAEB8E3B76DA +:103E8000047621B90200394E2E7705C7462E000070 +:103E9000568B762C897604C7040000464689762C1A +:103EA000294E2E5E85C07917F6C4107405FF567C26 +:103EB000EB03FF567E897614B00CE885D1EB86893A +:103EC000463AFF96800029463A897614B00CE8718C +:103ED000D1E971FF0000000000000000080410029A +:103EE00001200000000000000000000000000000B1 +:103EF00000000000808080808080808080808080C2 +:103F000080808080808080808080808080808080B1 +:103F100080808080808080808080808080808080A1 +:103F20008080808080808080808080808080808091 +:103F30008080808080C0C0C0C0C0C0C0C0C0C0C0C1 +:103F4000C0C0C0C0C0C0C0C0C0C0C0C0C0C0C080B1 +:103F500080808000808080808080808080808080E1 +:103F60008080808080808080808080808080808051 +:103F70008080808080808080808080808080808041 +:103F80008080808080808080808080808080808031 +:103F90008080808080808080808080808080808021 +:103FA0008080808080808080808080808080808011 +:103FB0008080808080808080808080808080808001 +:103FC00080808080808080808080808080808080F1 +:103FD000808080804E417841D041F44106421842B1 +:103FE000C3908E46028B7E22897E6C806627FD8B75 +:103FF000562483FA0472E983EA028BD93BCA76021B +:104000008BCAB00A57518BFEF2AE8BC1595F751E39 +:1040100050402BC874062BD12BD9F3A4594B4A4AD4 +:10402000B00DAAA43BCA76028BCAE313EBD42BD9FA +:10403000F7C601007402A449D1E9F3A57301A4896C +:104040007E222B7E6C297E24017E1A8BCB807E26DD +:10405000027405806626FDC360B0FDE8180361C3E5 +:10406000C390E87C0272F990834E26208B466A89C1 +:10407000466E8B46480D040025BFFF894648B006B2 +:10408000E8BFCFC3897E222B7E6C017E1A297E2455 +:10409000807E26027405836626FDC360B0FDE8D5E8 +:1040A0000261C3908ABEC200EB24F7464840007507 +:1040B000B18E46028B7E22897E6C8B562483EA0A5F +:1040C000789E03D7806627FD33C08ABEC200E3B462 +:1040D0003BFA77B0AC49932E8A87D43E9322DF75A2 +:1040E00017AAE3A03BFA779CAC49932E8A87D43E6B +:1040F0009322DF7503AAEBD6F6C37F7505FF4666EC +:10410000EBDFF6C340750C8BD883EB08D1E32EFFB1 +:10411000A7D43FFF46662C20EBC785C0742C894688 +:104120006A834E4840897E222B7E6C017E1A297E4E +:1041300024807E26027408836626FDE8A301C360FE +:10414000B0FDE8310261E89801C3E957FF908B5E4A +:10415000664B7803895E66AA8B5E64F7C3002075A0 +:1041600003E940FFF7C3400074088A86C100AAE94A +:1041700032FFB83200EBA3908B5E66895E6883C322 +:104180000880E3F8895E668B5E6481E3001881FB3A +:104190000018742DAA85DB7425F746644000751855 +:1041A00081FB0010740C8B46662B4668C1E004E965 +:1041B00068FFB86400E962FF8A86C100AAAAE9E341 +:1041C000FE518B4E662B4E68B020F3AA59E9D4FEFF +:1041D0008B5E66895E688B5E64F7C324007410C7CB +:1041E00046660000F7C304007405B00DAAB00AAA21 +:1041F000EB489090AAF7466400407406B8D007E9EF +:1042000018FFE99FFE90AAF7466400807406B8D0B4 +:1042100007E906FFE98DFE908B5E66895E6885DBA7 +:10422000750C8B5E64F7C310007406E976FE8B5E36 +:1042300064F7C308007427B00AAAF7C32000751FEB +:10424000F7C300017503E95BFEF7C340007506B8CC +:104250006400E9C5FE8A86C100AAAAE946FEAAC78B +:1042600046660000F7C3000674F1F7C340007419F6 +:104270008A86C10081E3000681FB00047206760293 +:10428000AAAAAAAAAAAAE91BFE81E3000681FB004A +:1042900004720E7606B89600E97FFEB86400E979EC +:1042A000FE8B4668E973FE90368B0EDA1283F93284 +:1042B000731D1E0633C08ED88EC08D764CBFDC12A7 +:1042C00003F9A5A5A583C106890EDA12071FC3B09D +:1042D00008E86ECDC390836648FEE893C4E8C8FF43 +:1042E000C3F6462702750F9CFA837E1A0074098074 +:1042F0004E27019DF9C3F8C35052F7463840007469 +:104300001DE834DE83C20AECA840752783EA088AD8 +:1043100086A5000C028886A500EE5A58EBD1E80C61 +:10432000DE8A86A50024FB0C028886A500E60C5ACE +:1043300058EBBC804E27025A589DF8C30846269C6D +:10434000FA8A8EA500F7463840007514F6C1067447 +:1043500023E8D9DD8AC124F98886A500E60C9DC32F +:10436000F6C102740FE8D0DD83C2028AC124FD8841 +:1043700086A500EE9DC38B5E2622C3884626740167 +:10438000C3806627FD9CFA8A8EA500F74638400058 +:104390007516F6C104750FE893DD8AC124FD0C047F +:1043A0008886A500E60C9DC3F6C10275F9E888DD94 +:1043B00083C20AECA820750E83EA088AC10C028821 +:1043C00086A500EE9DC383EA0A33C98A4E1C8B463C +:1043D0001A3BC8731B014E2A2BC189461A1EC5768B +:1043E00000F36E1F89760083C2028A86A500EBCD9A +:1043F00085C0741201462A8BC81EC57600F36E1F55 +:10440000897600894E1AF6C701752380CB02895E32 +:1044100026E808C383C2028A86A50024FDEE8886AA +:10442000A500F6C7107505B002E816CC9DC383C27F +:10443000028A86A500EB86908BD18B46243BC876FA +:10444000028BC82BD12BC18BD9E322806627FD8E2E +:1044500046028B7E22F7C601007402A449D1E9F31B +:10446000A57301A4897E22894624015E1A8BCA8025 +:104470007E26027405806626FDC360B0FDE8F6FE68 +:1044800061C350E40A84C0750A8686A10084C074A2 +:104490000AE60A580C20894648F9C35824DF8946A1 +:1044A00048F8C390FBB002E8E807FAE82E01FBB039 +:1044B00001E8DE07FAB002E8BCCBFB85ED74E5FA53 +:1044C0008E5E0AFB90FA8B46488B7640A88C75DE90 +:1044D000A820741A50E855DC58E8A6FF7310B00203 +:1044E000E85FCBEBC99025FF008BC8EB3690A801A5 +:1044F00075224683E6FE3B76087479AD8AFCB3F0FC +:1045000022FB3AFB74E03ABEA000742EE8D2FD73A1 +:1045100077EB9B908AE024FC8846488B4E4AF6C491 +:1045200002741DE8BBFD7286E813F3897640E393BD +:10453000834E4803894E4AE974FF25FF0F8BC890CC +:104540008B86980085C0741A518A8EA000C0E90439 +:10455000BA0100D3E25923C2740803F1897640E915 +:1045600061FFFF5662E3F5834E4801894E4A897622 +:1045700040E93AFF814E2600108B46503B46467775 +:1045800003E852FDE927FF9088BEA000EBAC0A06C5 +:1045900090128AE0BA0601B004EEEC84C07512B045 +:1045A00004EE8AC4EE32E4A8807406C706841200C2 +:1045B0000088269012C30A0690128AE0BA0601EC1F +:1045C000A80175EDBA08018AC4EE32E4A88074E14E +:1045D000C7068412000088269012C39036F706247E +:1045E0000101007530368B0EDA1280F936732633EE +:1045F000C08EC08ED8BFDC1203F9B008E877CA8538 +:10460000ED740E8D764CA5A5A580C10680F9367295 +:10461000E9890EDA12C3C390F7062601010075F688 +:104620008B0E201385C975EE33C08EC08ED8BF2483 +:1046300013B93600B00AE83DCA85ED7506E91201E6 +:10464000E90A0133DB8A464C8AA6B300FECC780E19 +:1046500088A6B3000ADCB40AAB83E90276E28AA634 +:10466000B200FECC780E88A6B2000ADCB408AB8398 +:10467000E90276CC8AA6B100FECC78188ABEB000DA +:10468000750488A6B00088A6B1000ADC8AE7AB836F +:10469000E90276AC8AA6B400FECC781F88A6B400E6 +:1046A0000ADCB40BAB8A86BC008AA6BD00AB8B8645 +:1046B000BE00AB83E90676888A464C8AA6B600FE21 +:1046C000CC781988A6B6000ADCB40CABE8DBCBAB1F +:1046D0008B462AAB83E90676748A464C8AA6B700D5 +:1046E000FECC781988A6B7000ADCB40DABE8BACBCB +:1046F000AB8B4634AB83E90676538A464C8AA6B820 +:1047000000FECC781988A6B8000ADCB40EABA15024 +:1047100012ABA15212AB83E90676328A464C8AA6C6 +:10472000B500FECC781888A6B5000ADCB40FAB8BB8 +:10473000869A00AB8B869C00AB83E906760F84DB00 +:104740007503E9EFFEB00AE8F8C8E9E7FEB00AE849 +:10475000F0C8F7D983C1368BC10D800086C4A3226F +:10476000134141890E2013C3A184122BC17211A3DE +:104770008412BE2213D1E9F36F90890E2013F8C37F +:10478000F9C3C381EF6A1374F98BC70D800086C427 +:10479000A368134747893E6613C3F7062A01010041 +:1047A00075E08B0E6613E30780F92077D54949330E +:1047B000C08EC08ED8BF6A138BF703F983C6343B13 +:1047C000FE77C0B00EE8AEC885ED74B78A464C8A55 +:1047D000B6B900FECE781588B6B9008AA6A90080C1 +:1047E000CCC0AB84F67405B00EE856C88AB6BA00E1 +:1047F000FECE78CB8A9EA9008ABEAB008A563F8A3D +:10480000F332F70AB6AC00C686AC000022F2744B55 +:10481000F6C608740FB402F6C3087502B403AB8081 +:10482000E6F77437F6C601740FB400F6C3017502DB +:10483000B401AB80E6FE7423F6C602740FB404F62E +:10484000C3027502B405AB80E6FD740FF6C60474AE +:104850000AB406F6C3047502B407ABC686BA0000F4 +:10486000889EAB00E958FF90A184122BC17211A35E +:104870008412BE6813D1E9F36F90890E6613F8C3F2 +:10488000F9C3A1841241412BC17223A384128BC1AD +:10489000484832E40C8086C4EF9090909090BEDC43 +:1048A000124949D1E9F36F90890EDA12F8C3F9C3BE +:1048B0008AC88A464CB40183EB06EF9090909090A2 +:1048C000B80100EF90909090908AC1EF90909090F6 +:1048D00090E99700E9AC0033C08ED8891E8412C3DA +:1048E000368B1E8412FB90FAB00CE889C785ED74F4 +:1048F000E6C5760C83FB1472DBFB90FAAD85C078BD +:10490000AF74E28BFE03F8368B0E86123BC1770242 +:104910008BC883EB043BD977028BCB33C08A464CE0 +:10492000EF90909090908BC1EF90909090904180FC +:10493000E1FE2BD951D1E9F36F90598BC74024FE8A +:104940003BC674272BFE4E4E538B5E103BF3721307 +:10495000031F83C30380E3FEC7070000836E740256 +:10496000895E105B893C89760CEB8989760C3976F7 +:104970001077817208833C007403E977FFE80DBE6D +:10498000E962FF36891E8412B00CE8B5C633C08ECA +:10499000D8C3A184123D10007277BA04013B068887 +:1049A000127506C7067E1200008B0EDA12E30BE8C2 +:1049B000D0FE7257C7067E12FF7F8B0E2013E30BCB +:1049C000E8A5FD7246C7067E12FF7F8B0E6613E3D5 +:1049D0000BE894FE7235C7067E12FF7FA12801A95D +:1049E00001007503E8F9FE803E8D1200751DA1845B +:1049F000123D200076153B0682127609A17E123BFD +:104A0000068012720C800E901280C3B080FF167C5C +:104A100012C3800E901240C36A001FC6069312177D +:104A20009C0EE8B7C86A001FC6069312209C0EE8C9 +:104A3000AAC86A001FC6069312169C0EE89DC8906D +:104A4000BA0601ECA82075CAFB90FABA0401ED90F1 +:104A5000909090903A06941277BE33DB8AD8D1E3D7 +:104A60002E8BAF4400C47E0885FF74B9F6C4C075B0 +:104A70005532C0C1E00280E4F08BF0ED9090909050 +:104A80009085C074BB8BC84180E1FE0BC68B5E5025 +:104A90004B4B2BD9789CAB8BC1404001464ED1E9A2 +:104AA000F36D90895E50897E088B462680E4EF89FD +:104AB0004626F6C401750CF746480C007505B00291 +:104AC000E87FC5E97AFF86C48BC883E13F4180E176 +:104AD000FEE30A3C807209243FB4F0EBB0E960FFCA +:104AE000253F0033FF8EC7BF96128BF7D1E9F36DD8 +:104AF000908BC8E848EDE947FF906A001FC606930F +:104B0000121B9C0EE8D5C790601E0633C08ED88E4F +:104B1000C0BA0601ECA80474E1B006EEECA28C1257 +:104B2000A8407411A18812A38412C6068D1200E851 +:104B300060FEA08C12A8807403E804FFB80080BA5D +:104B400022FFEF071F61CF906A001FC60693121B5A +:104B50009C0EE887C790601E0633C08ED88EC0BA00 +:104B60000601ECA80474E1BA0801ECA28C12A8407A +:104B70007411A18812A38412C6068D1200E812FED9 +:104B8000A08C12A8807403E8B6FEB80080BA22FF99 +:104B9000EF071F61CF90EE86E0EE86E0EC86E0EC5A +:104BA00086E080E1FEF36C9080E1FEF36E900500FC +:104BB0007547A84B05007548A84B0500A348A84BAE +:104BC00005003549A84B06009848964B0600BA48A0 +:104BD000964B0600C348964B0600CB48964B060002 +:104BE0002049964B06002849964B06004E4A9C4B9E +:104BF00006007B4A9C4B05009E4AA24B0500EC4AEE +:104C0000A24B00001E06833E4412007409A0060158 +:104C100024303C30741A8CC88ED88EC0BBAE4B8BFF +:104C20000FE30D8B7F028B7704F3A483C306EBEFB6 +:104C3000071FC39033C0A33E01B90C01BE40018BD6 +:104C4000FE81C6B40F89048BC62BF13BC777F6A350 +:104C50003C01C3901E0660368B2E3E018B5E003BEE +:104C6000EB742B8B7602891C89770236A13C018973 +:104C7000460036892E3C018BEBFF4E0674088B6E86 +:104C800000FF4E0675F836892E3E018B66046107DB +:104C90001FC31E0660368B2E3E0198894606896624 +:104CA000043B6E0074108B6E00FF4E0675F836895B +:104CB0002E3E018B660461071FC3C3901E06609CD5 +:104CC000FA33ED8EDD8B2E3C0185ED743D8B4E006D +:104CD000890E3C018BCC8DA60A01561E06608966A2 +:104CE00004C746080F1AC7460601008B1E3E018501 +:104CF000DB741D8BC58707894600895E028BD889C6 +:104D00006F028BE19D61071FF8C39D61071FF9C307 +:104D1000892E3E01896E00896E0287E19D8BE1EB51 +:104D2000E4000D0A5465726D696E616C73207375D1 +:104D300070706F727465643A0D0A312920414E53C8 +:104D40004920636F6D70617469626C650D0A322968 +:104D500020577973652033300D0A506C6561736597 +:104D60002073656C6563743A20000D0A636F646597 +:104D7000207365676D656E743D000D0A4D6F6E6939 +:104D8000746F722076322E350A0D0A3E000D0A50DD +:104D90006172646F6E3F000D0A4E6F206164647231 +:104DA00065737320737065636966696564000D0AD5 +:104DB0003A000D0A004C6F633D000D0A4641544114 +:104DC0004C204552524F523D000D0A4D6F6E697492 +:104DD0006F7220636F6D6D616E64733A2D0D0A20E2 +:104DE0002020442C645B5B787878783A5D7878781A +:104DF000785D202D2064756D70206D656D6F727902 +:104E00000D0A2020204C2C6C5B5B787878783A5D1A +:104E1000787878785D202D2064756D702073696EC8 +:104E2000676C65206C696E650D0A202020452C6535 +:104E30005B5B787878783A5D787878785D202D209B +:104E400065646974206D656D6F72790D0A2020208C +:104E5000462C665B5B78787878205D787878785D2A +:104E6000202D2066696C6C206D656D6F72792070E5 +:104E70006172616772617068730D0A202020495B5E +:104E8000787878785D202020202020202020202D78 +:104E900020776F726420696E7075742066726F6D12 +:104EA00020706F72740D0A202020695B7878787802 +:104EB0005D202020202020202020202D20627974B9 +:104EC0006520696E7075742066726F6D20706F72E8 +:104ED000740D0A2020204F78787878207878202068 +:104EE000202020202020202D206F757470757420C4 +:104EF000776F726420746F20706F72740D0A2020B7 +:104F0000206F787878782078782020202020202042 +:104F100020202D206F75747075742062797465205F +:104F2000746F20706F72740D0A202020475B5B78CD +:104F30007878783A5D787878785D2020202D206721 +:104F40006F746F20616464726573730D0A20202092 +:104F5000575B5B787878783A5D787878785D202050 +:104F6000202D207761746368206120776F72640D53 +:104F70000A20202043202020202020202020202024 +:104F800020202020202D20696E7465727275707447 +:104F900073206F66660D0A202020532020202020D9 +:104FA00020202020202020202020202D20696E7409 +:104FB00065727275707473206F6E0D0A20202073F5 +:104FC00020202020202020202020202020202020E1 +:104FD0002D2073696E676C6520737465700D0A20EF +:104FE000202042787878782020202020202020203F +:104FF0002020202D20627265616B706F696E7420B5 +:105000007365740D0A20202062202020202020209B +:105010002020202020202020202D20627265616B1E +:10502000706F696E7420636C6561720D0A202020B8 +:10503000522020202020202020202020202020203E +:10504000202D207265737461727420627265616BC9 +:10505000706F696E740D0A2020207220202020209D +:1050600020202020202020202020202D2072656755 +:105070006973746572732061742062726B70740D51 +:105080000A202020582C78206E202020202020204C +:1050900020202020202D206578616D696E652063B9 +:1050A00068616E6E656C206E0D0A202020482C3FD2 +:1050B00020202020202020202020202020202D20E3 +:1050C00074686973206D657373616765001B5B327B +:1050D0004A1B5B313B3148414E5349205465726D48 +:1050E000696E616C0D0A0A001B5B4B001B5B4A007A +:1050F0001B5B324A1B5B313B3148001B5B44201B6E +:105100005B44001B5B313B373248001B5B003B00BC +:1051100048001B5B73001B5B75001B7A2B0B7F1B0E +:105120007A2E0C7F1B7A2D087F1B7A2C0A7F1B7A24 +:1051300022087F1A57797365203330205465726DC9 +:10514000696E616C0D0A001B54001B59001A001E89 +:105150000008200800001B3D0000001B46000D0059 +:105160003F4464456546664767486849694F6F43F1 +:1051700063537342625272577758784C6C3C60D4D8 +:1051800057D45750585058D659D659B459B4593C99 +:10519000603C606C57485726570657905790579871 +:1051A00057485F0C5F585F335F405FA057A057FEC2 +:1051B00059FE59DC57DC5788619861C061CC61D8D1 +:1051C00061F66102622262F8564A625862605920B2 +:1051D00020666C6167733D00202061783D002020CF +:1051E00062783D00202063783D00202064783D00F7 +:1051F000202063733D00202064733D0020206573F0 +:105200003D00202073733D00202064693D00202074 +:1052100073693D00202062703D00202073703D00C6 +:10522000202069703D00206368616E656C3D002040 +:105230002020207365673D002074695F7374723DA0 +:10524000002074695F746F733D002074695F6D6145 +:10525000783D002074695F6261733D002074695F6E +:1052600073697A3D002074695F7374663D00207431 +:10527000695F726F6F3D002074695F666C673D0007 +:105280002074695F746F743D002072695F70636E93 +:105290003D002072695F7374723D002072695F7314 +:1052A00074663D002072695F726F6F3D0020726905 +:1052B0005F6261733D002072695F73697A3D00200F +:1052C00072695F746F743D002072695F6D696E3D35 +:1052D000002072695F666C673D002072695F746FC1 +:1052E000733D002072695F7468723D002074685FCE +:1052F0007374663D002074685F7374723D0020749F +:10530000685F6261733D002074685F73697A3D0075 +:105310002074685F7472673D002074685F666C6714 +:105320003D002074685F636E743D002072685F7397 +:1053300074723D002072685F7374663D002072686D +:105340005F6261733D002072685F73697A3D00207F +:1053500072685F7370613D002072685F61736F3DBA +:10536000002072685F726F6F3D002072685F666C2C +:10537000673D00206D5F636172653D002070745F62 +:10538000666C6F3D002061735F666C6F3D0020723C +:105390006D5F666C6F3D00202020715F696E3D007F +:1053A0002020715F6F75743D0020715F6472616EC3 +:1053B0003D002020715F74696D3D00202020715FE9 +:1053C00066633D0020715F737461743D0020715FFE +:1053D000646174613D0020715F6D6F646D3D0020FC +:1053E00068616E645F6F3D002068616E645F623D5E +:1053F000002068616E645F653D002068616E645FD7 +:10540000693D0020206F706F73743D002020746927 +:105410006D656F3D0020637573746D313D002063D1 +:105420007573746D323D0020637573746D643D0057 +:10543000207478726174653D0020727872617465C1 +:105440003D002020635F6D61703D0020635F6164FB +:1054500064723D0020635F616973723D0020635F89 +:10546000787461673D0020635F646566723D00206B +:10547000635F666C73683D002074786D6178733D7E +:10548000002072695F656D733D002020635F6C735F +:10549000723D002020635F6965723D002020635FDC +:1054A0006663723D002020635F6D63723D002020C3 +:1054B000635F6C63723D002020635F6473733D0023 +:1054C00020635F647373693D0020635F647373726C +:1054D0003D002020635F6973723D002020635F639D +:1054E00061723D002020635F6566723D0020635F4E +:1054F000657273743D0020635F65636E743D0020C8 +:10550000635F62726B633D0020635F626F6B633D3C +:105510000020635F7265706C3D0020635F6363739E +:10552000723D0020635F737474313D0020635F73CC +:105530007474323D002BC08ED88EC0E8C200E8E5FE +:1055400000FABF8400C705DC568C4D02BF0C00C7B3 +:10555000056E5E8C4D02BF0400C705BA5E8C4D021D +:10556000E8F10090E84901E81600F490E8E500BE93 +:10557000BA4DE8090CA09312E85D0CE8C209EBE40F +:10558000E8D50CE8C40C0AC074F68B1EF8793C0D03 +:10559000742E3C0874173C7F741383FB207FE188D2 +:1055A00087D67943891EF879E8770CEBD30BDB7447 +:1055B000CF4B891EF8798B36167AE8C10BEBC19078 +:1055C000E80200EBBBC687D679000BDB741EA0D6C1 +:1055D00079BF6051B91D008BD9060E07F2AE077571 +:1055E00017412BD9D1E32EFF977D519033C0A3F8FB +:1055F00079BE894DE8870BC3BE8D4DE8800BEBEC7F +:10560000BA0002B093EEB055EEBA1002B093EEB00D +:10561000AAEEBA0002EC3C557508BA1002EC3CAA9E +:105620007403E82FF6C3BA0402B01AEEB020EEB04D +:1056300030EEB040EEB080EEBA0002B013EEB0072C +:10564000EEBA0802B080EEBA0202B0BBEEBA0402B3 +:10565000B005EEC3C606CA1301C706F8790000C636 +:1056600006F67901C706D0790000C706D279000096 +:10567000C706D4790000C706FA790000C706FC798E +:105680000000C706FE790000C706007A0000C706C2 +:10569000027ACE598C0E047AC706067A0000C70635 +:1056A000277A0000C606297A00C6062A7A00C39027 +:1056B000BE224DE8C80AE83F002C313C0177F7E8EC +:1056C00081098B360C7AE8B50ABE6A4DE8AF0A0E3E +:1056D00058E8F80ABE7A4DE8A40AC39060D1E38383 +:1056E000FB1873111EBA00008EDA2EFF97B7518B8C +:1056F000EC8946101F61CF90E84F0B0AC07505E892 +:10570000560BEBF4C390833EF879017416BED7793B +:10571000E8310A8BD0AC3C2C74043C207505E8239E +:105720000AEEC3E9D2FE833EF8790174F6BED7795A +:10573000E8110A8BD0AC3C2C74083C207404E9B707 +:10574000FE90E8FF09EFC3908B16067A833EF87946 +:1057500001740BBED779E8EB098BD0A3067AB02091 +:10576000E8570B8B16067AECE86F0BC38B16067A9C +:10577000833EF87901740BBED779E8C7098BD0A3B3 +:10578000067AB020E8330B8B16067AEDE8670BC378 +:10579000FAC606F67900C390C606F67901FBC390F7 +:1057A00006E85809B020E8110B268B05E8470BB036 +:1057B00008E8060BE8030BE8000BE8FD0AB8010057 +:1057C000E8CFF4BA0202EC24017502EBDCBA06025F +:1057D000EC07C390C706087A1000EB06C706087AE4 +:1057E0000100068E06FC798B3EFA79E80E09E80B7B +:1057F00000893EFA798C06FC7907C390BEB24DE869 +:105800007C098B16087A52E82A09E80F0AE80C0A84 +:1058100033DBB9100090268A01E8BC09E8FD094392 +:10582000E2F4E8F709E8F40933DBB9100090268ABE +:10583000013C2072053C7E760390B02EE8E30943DC +:10584000E2ECBEB24DE8360983C7105A4A75B7C3B9 +:10585000068E06007A8B3EFE79E8A008893EFE7926 +:105860008C06007A578B360E7AE81209C706087A3A +:105870001000BA0002E8E800E881FF5FBA0000E823 +:10588000DE00BEB54DE8F6088CC0E83F09B03AE846 +:1058900090098BC7E83509E87E08E8C30090E8B7AF +:1058A00009E8A6090AC074F63C0B750683EF10EBF5 +:1058B00019903C0A750683C710EB0F903C0C7504D9 +:1058C00047EB07903C0875244F908B36FE798BC7C9 +:1058D0002BC63D000172A53D1001720483EE20909D +:1058E00083C6108936FE79578BFEEB803C2E7508F7 +:1058F000BA0113E86A0007C3C6060A7A0232C990E1 +:105900003C30724C3C39760C245F3C4172423C4640 +:10591000773E2C072C3050E8CC085802C8FE0E0AFF +:105920007A740FC0E104E82F09E81E090AC074F672 +:10593000EBCE26880DE8E0078AD0E823008AC13C38 +:105940002072053C7E760390B02EE8D508E970FF02 +:10595000E8C507E80A00268A05E87C08E91DFF90EB +:10596000F606267A02750286F2528B361A7AE80D0E +:10597000085A528AC60206247AF606267A01750665 +:10598000E89F08EB0D9032E4E80D088B361C7AE8AE +:10599000EC075A8AC20206257AF606267A017506AF +:1059A000E87F08EB069032E4E8ED078B361E7AE8D4 +:1059B000CC07C390068E06047A8B3E027AE83C0739 +:1059C000893E027A8C06047A07FF1E027AC3BE97CC +:1059D0004DE8AA07CB900657BED779E866078BD863 +:1059E000E861078BC82BCB78118EC3BF0000B8FFCE +:1059F000FF51B90800F3AB59E2F75F07C39006BE49 +:105A0000D779E83F078BD8D1E32E8B9F4400BE2681 +:105A100052E8F1088BC3E8DD08B80100E873F2E84A +:105A2000E008BE2F52E8DD088B4718E8C808BE77AB +:105A300052E8D1088B4726E8BC08BE5352E8C50897 +:105A40008B471EE8B008BE5C52E8B9088B4720E8D7 +:105A5000A408BE6E52E8AD088B4724E89808BE80C3 +:105A600052E8A1088B472AE88C08E89508BE38520E +:105A7000E892088B07E87E08BE4152E887088B470A +:105A80001AE87208BE4A52E87B088B471CE8660891 +:105A9000BE6552E86F088B4722E85A08E86308BEE3 +:105AA000D152E860088B4738E84B08BEAD52E85445 +:105AB000088B4730E83F08BEB652E848088B4732AB +:105AC000E83308BEA452E83C088B472EE82708BEFE +:105AD000BF52E830088B4734E81B08E82408BE8929 +:105AE00052E821088B4704E80C08BE9252E81508DA +:105AF0008B4714E80008BE9B52E809088B472CE846 +:105B0000F407BEC852E8FD078B4736E8E807BEDA5F +:105B100052E8F1078B473AE8DC07BEE352E8E507B5 +:105B20008B473CE8D007E8D907BE1953E8D6078B66 +:105B30004748E8C107BEFE52E8CA078B4742E8B5AE +:105B400007BE0753E8BE078B4744E8A907BE7C534E +:105B5000E8B2078B474CE89D07BE8553E8A6078B44 +:105B6000474EE89107BE8E53E89A078B4750E88569 +:105B700007E88E07BE2253E88B078B474AE8760773 +:105B8000BEEC52E87F078B4708E86A07BEF552E88B +:105B900073078B4740E85E07BE1053E867078B47E3 +:105BA00046E85207E85B07BE6A53E858078B477A16 +:105BB000E84307BE3D53E84C078B4770E83707BE04 +:105BC0004653E840078B4772E82B07BE4F53E83433 +:105BD000078B4774E81F07E82807BE2B53E8250703 +:105BE0008B470CE81007BE3453E819078B4710E8C1 +:105BF0000407BE5853E80D078B4776E8F806BE61E8 +:105C000053E801078B4778E8EC06BE7353E8F506C6 +:105C10008B473EE8E006E8E906BE9753E8E6068BC8 +:105C20004752E8D106BEA053E8DA068B4754E8C5D0 +:105C300006BEA953E8CE068B4756E8B906BEB25356 +:105C4000E8C2068B4758E8AD06BEBB53E8B6068BE4 +:105C5000475AE8A106BEC453E8AA068B475CE895FC +:105C600006E89E06BECD53E89B068B475EE8860697 +:105C7000BED653E88F068B4760E87A06BEDF53E84E +:105C800083068B4762E86E06BEE853E877068B47CB +:105C90007CE86206BEF153E86B068B477EE8560649 +:105CA000BEFA53E85F068B878000E84906E8520693 +:105CB000BE4254E84F068B879E00E83906BE035467 +:105CC000E842068B4764E82D06BE0C54E836068B86 +:105CD000476EE82106BE1554E82A068B878E00E839 +:105CE0001406BE1E54E81D068B879000E80706BE0A +:105CF0002754E810068B879200E8FA05E80306BEF1 +:105D00003054E800068B879400E8EA05BE3954E871 +:105D1000F3058B879600E8DD05BE6F54E8E6058B3A +:105D2000879800E8D005BE5D54E8D9058A87A000B1 +:105D3000E8A705BE5454E8CC058A4728E89B05BE71 +:105D40006654E8C0058A87A100E88E05E8B305BE61 +:105D50007854E8B0058A87A200E87E05BE8154E841 +:105D6000A3058A87A300E87105BE8A54E896058AD0 +:105D700087A400E86405BE9354E889058A87A500D6 +:105D8000E85705BE9C54E87C058A87A600E84A05CA +:105D9000BEA554E86F058A87A700E83D05BEAE544E +:105DA000E862058A87A800E83005E85505BEB754C3 +:105DB000E852058A87A900E82005BEC054E84505D9 +:105DC0008A87AA00E81305BEC954E838058A87AB5C +:105DD00000E80605BED254E82B058A87AD00E8F935 +:105DE00004BEDB54E81E058A87AE00E8EC04BEE47E +:105DF00054E811058A87AF00E8DF04BEED54E804DB +:105E0000058A87B000E8D204E8F704BEF654E8F447 +:105E1000048A87B100E8C204BEFF54E8E7048A8719 +:105E2000B200E8B504BE0855E8DA048A87B300E892 +:105E3000A804BE1155E8CD048A87BB00E89B04E89E +:105E4000C004BE1A55E8BD048A87BC00E88B04BEB6 +:105E50002355E8B0048A87BE00E87E04BE2C55E8CE +:105E6000A3048A87BF00E87104E8960407C36006AC +:105E70001E168BECFF4E16F7461A00027401FBB893 +:105E800000008ED88EC0892E2D7AE8CB0081661A4C +:105E9000FFFEC6062A7A00E8D800B8005FA32B7A76 +:105EA000E85D00803E2A7A00740A814E1A0001C61D +:105EB000062A7A00171F0761CF9060061E168BEC2A +:105EC000F7461A00027401FBB800008ED88EC08914 +:105ED0002E2D7A81661AFFFEC6062A7A00E8920005 +:105EE000B8005FA32B7AE81700803E2A7A00740A74 +:105EF000814E1A0001C6062A7A00171F0761CF904B +:105F0000B8F000E88CEDFF262B7AC390065356803C +:105F10003E297A007403E83F00BED779E825028B5A +:105F2000D8A3277A2E8A07A2297AB0CC2E88075EBA +:105F30005B07C3C6062A7A00B80A5FA32B7AC39010 +:105F40008B2E2D7AE82B00C3C6062A7A01E80800BA +:105F5000B80A5FA32B7AC39057803E297A00740F4A +:105F60008B3E277AA0297A2E8805C606297A005FFB +:105F7000C390BEB24DE80602BED851E80002FF76DB +:105F80001458E84702BEDE51E8F301FF760E58E8E8 +:105F90003A02BEE451E8E601FF761258E82D02BE4F +:105FA000EA51E8D901FF761058E82002BE1452E801 +:105FB000CC01FF760A58E81302BE1A52E8BF01FF6F +:105FC000760C58E80602BECF51E8B201FF761A58A7 +:105FD000E8F901BEB24DE8A501BEF051E89F01FF0E +:105FE000761858E8E601BEF651E89201FF760258AD +:105FF000E8D901BEFC51E88501FF760458E8CC01E0 +:10600000BE0252E87801FF760058E8BF01BE085290 +:10601000E86B01FF760658E8B201BE0E52E85E0159 +:10602000FF760858E8A501BE2052E85101FF761618 +:1060300058E89801BE894DE84401C390BEC94DE8B7 +:106040003C01C33C0074053C017459C3C7060C7A7B +:10605000CD50C7060E7AF050C706107AE850C70632 +:10606000127AEC50C706147AF450C706167AFB5021 +:10607000C706187A0351C7061A7A0B51C7061C7A4D +:106080000E51C7061E7A1051C706207A1251C70654 +:10609000227A1651C606247A01C606257A01C6065A +:1060A000267A03C3C7060C7A1A51C7060E7A4D51D9 +:1060B000C706107A4751C706127A4A51C706147AA2 +:1060C0004F51C706167A5151C706187A5551C7065F +:1060D0001A7A5651C7061C7A5951C7061E7A5A5168 +:1060E000C706207A5B51C706227A5E51C606247A1B +:1060F00020C606257A20C606267A02C3A1F879486A +:106100007414BED779E83C008BF8AC3C3A75078E26 +:10611000C7E830008BF8C3908BC72B06FE798AF056 +:10612000240F8AD002D002D080C20BC0EE0480C6F9 +:1061300003043DC38CC0E89300B03AE8E4008BC789 +:10614000E88900C35133C990AC3C2074FB900AC06D +:1061500074262C3072223C0976143C11721A2C07DA +:106160003C0F760A3C2A72102C203C0F770A98C10B +:10617000E10403C8ACEBD7904E8BC159C390068C99 +:10618000C88EC0E8020007C3268A04460AC0740607 +:10619000E88F00EBF390C3900BC0747A5133D2B9FF +:1061A000E803F7F18BCAE803008BC159BA6400F623 +:1061B000F2E80C008AC498B20AF6F2E802008AC437 +:1061C000500AF074050430E8580058C386C4E80744 +:1061D0000086C4E80200C390C1C804E80800C1C03A +:1061E00004E80200C3905350240FBBCA622ED7E8C4 +:1061F0003000585BC39086C4E8070086C4E80200FC +:10620000C39050B908008AE032C0D1C00430E81110 +:1062100000E2F558C390B030E80700C3B020E801B1 +:1062200000C3568B36D0798884D0774681E6FF014B +:10623000FF06D4798936D079813ED479FE0175087C +:1062400056E814005EEBF1905EC3BA0202EC240142 +:106250007404BA0602ECC390803EF67900740960BB +:10626000B80100E82CEA6190BA0202ECA804742894 +:106270008B36D279833ED47900741D8A84D07746D8 +:1062800081E6FF018936D279FF0ED479BA0602EE93 +:10629000BA0202ECA80475DCA1D479C352BA060292 +:1062A000EE5AC3905250BA0202ECA8047408585A2D +:1062B000E8E9FFF9C390585AF8C35250BA0202EC09 +:1062C000A80474FB585AE8D3FFC330313233343555 +:1062D0003637383941424344454653508AE080E4DA +:1062E0000FBBCA62C0E8042ED7E8CEFF8AC42ED7FF +:1062F000E8C7FF585BC386E0E8DFFF86E0E8DAFF27 +:10630000C390BEB24D502EAC3C007405E8ABFFEB21 +:10631000F558C390C808000056578B7604BF040098 +:10632000C746FC0000C746FA0000C746F8000083D5 +:106330007E0600750E56E8B60E590BC075058BC764 +:10634000E95B018B46FC8946FE0BFF7505B8010031 +:10635000EB0233C05056E8A40D5959B4008946FCED +:106360008B5EFC83FB087603E92B01D1E32EFFA7AC +:10637000B264B80300E92601837EFA007414C746AC +:10638000FA00008A445898508A44599850E8C20F3D +:106390005959837EF800740AC746F8000056E89BF6 +:1063A0000859837E060075058BC7E9F10083FF0459 +:1063B0007503E9E6008BC7E9E400837EFE00750300 +:1063C000BF0200E9D500837EFE007503BF0100E92E +:1063D000C9008B5EFE83FB077603E98600D1E32EBE +:1063E000FFA7A26433FFE97F00BF0400807C580F41 +:1063F0007422837EF800751CFE44586A0856E87EB5 +:106400000C59598A445804805056E8720C5959C79F +:1064100046FA0100837EF800740AC746F800005669 +:10642000E8190859EB42BF0400807C5800742283AD +:106430007EF800751CFE4C586A0856E8410C595904 +:106440008A445804805056E8350C5959C746FA0119 +:1064500000837EF800740AC746F8000056E8DC079F +:1064600059EB05BF0400EB00EB31BF0400EB2CC778 +:1064700046F801006A0856E8050C5959807C58090D +:106480007D04B00FEB02B00004805056E8F00B59C9 +:1064900059BF0400EB05BF0400EB00E9A5FE5F5EF9 +:1064A000C9C3E4636364636463646364E963266427 +:1064B00051647863BA63C6639664D2636A646A643B +:1064C0006F647263C808000056578B76048B7E0891 +:1064D0006A0156E8A90B59598A4606C0E0060480AD +:1064E0005056E89A0B5959C746FE0000897EF8EBD2 +:1064F00003FF46FE8B5EF8FF46F8803F0075F2838F +:106500007EFE107D25B810002B46FED1F88946FC92 +:10651000C746FA0000EB0B6A2056E8620B5959FF98 +:1065200046FA8B46FA3B46FC7CEDEB0C8BDF478A48 +:10653000075056E8490B5959803D0075EF6A0256DD +:10654000E83C0B5959EB005F5EC9C3C80400005614 +:10655000578B7E04C746FE0000BE1400E909018B7C +:106560005EFE83C3042BDF8A87AC0B88445AC64483 +:1065700058088A46FE884459C744060000C6441994 +:1065800000C6441A00C6441B00C6441D0DC6441E66 +:1065900003C6441F00C6442000C6442100C6445B15 +:1065A00000C6445D00C6445E00C6445F00C6446049 +:1065B00000C746FC0000EB0D8B5EFCD1E3C740300A +:1065C0000000FF46FC837EFC107CEDC746FC00000B +:1065D000EB0A8B5EFCC6405000FF46FC837EFC0449 +:1065E0007CF0C744540000C7445600008A445A98BF +:1065F000BAF80023D0B805000BC28946FC9CFA8A81 +:1066000046FCBAFE00EEBA0000EC9D24088846FC69 +:10661000837EFC007502EB4AFF76FEE87A0C59682F +:10662000350256E8320A59590BC07534683802569B +:10663000E8250A59590BC0752768420256E8180A1E +:1066400059590BC0751A684C0256E80B0A59590B78 +:10665000C0750D68560256E8FE0959590BC0740200 +:10666000EB00FF46FE83C662397EFE7D03E9EFFE46 +:10667000EB005F5EC9C3C808000056578B4604BADA +:106680006200F7EA0514008BF0837E06007405B8FB +:106690001000EB03B808008944048A460888445C6B +:1066A00056E85904598BF88BC78944568944548A53 +:1066B000445D88442F0BFF751D68C20F6A0156E8C0 +:1066C00002FE83C406EB006A0156E847FC59590BE9 +:1066D000C075F4BF0100897EFAB90500BBE96A2ED6 +:1066E0008B073B46FA74074343E2F4E9A4032EFF09 +:1066F000670AC744060200C74408F4088B5E04D149 +:10670000E38B87FC0889440A33C08BF8894454E939 +:10671000800356E8BB0559BF01008A445D88446088 +:10672000E96F03837C04087530807C5C0175158AF1 +:10673000445DB400D1E08BD8FFB7E40856E8F70811 +:106740005959EB138A445DB400D1E08BD8FFB7C42C +:106750000856E8E2085959EB2E807C5C0175158AD1 +:10676000445DB400D1E08BD8FFB7D40856E8C70821 +:106770005959EB138A445DB400D1E08BD8FFB7B40C +:106780000856E8B20859596A0156E887FB59598BEF +:10679000D883FB03772AD1E32EFFA7E16ABF01006C +:1067A0008A445D88445EEB188A445D04FF240788B0 +:1067B000445DEB0C8A445DFEC0240788445DEB0019 +:1067C000E9CF028A445DB400D1E08BD8FFB7FD0267 +:1067D00056E863085959681D0356E85A0859596A1A +:1067E0000156E82FFB59598BD883FB037736D1E349 +:1067F0002EFFA7D96ABF01008A445D88445FEB245D +:106800008A445D04FF8A540480C2FF22C288445D2A +:10681000EB128A445DFEC08A540480C2FF22C28803 +:10682000445DEB00E96B028B5C0683C3FED1E38B16 +:10683000400889048B1CFF77066A0056E885FC83B4 +:10684000C4068B5C064BD1E38B40088944028B5C09 +:1068500002FF77066A0156E86AFC83C4066A01569D +:10686000E8B1FA59598BD883FB037603E91F02D1AB +:10687000E32EFFA7D16A8B5C028B47048944028B0D +:106880005C02803F44750D8B5C028A4701B4003B7B +:1068900044047DE28B4604D1E08B1C03D88B440278 +:1068A0008947088B5C064BD1E38B4402894008E999 +:1068B000DE018B5C028B47028944028B5C02803FC5 +:1068C00044750D8B5C028A4701B4003B44047DE2B1 +:1068D0008B4604D1E08B1C03D88B44028947088B7C +:1068E0005C064BD1E38B4402894008E9A201BF0159 +:1068F00000E99C018B5C028A07B4008946F8B90C58 +:1069000000BBA16A2E8B073B46F874074343E2F4B1 +:10691000E977012EFF67188B4604D1E08B5C0203F8 +:10692000D88B47088B5C06FF4406D1E38940088B6F +:106930001C807F010074128B5C028A47018B1C8AC9 +:106940005701B6008BDA884018E94001FF4C06E990 +:106950003A018B5C028A47018B1C8A5701B6008B77 +:10696000DA884018E925018B5C028A47018B1C8A72 +:106970005701B6008BDA884018FF4C06E90D018BF1 +:106980005C028A47018B1C8A5701B6008BDA3040C3 +:1069900018E9F800B8F0108BF88944548A445F88ED +:1069A000445DE9E7008A441C983D020074073D03FA +:1069B000007402EB07C746FE0000EB2B8A441C98CC +:1069C000D1E08BD8FFB7690256E86B0659596A01C6 +:1069D00056E840F959598946FE837EFE00740683C5 +:1069E0007EFE0375E9EB00837EFE0374628A441C1D +:1069F00098D1E08BD8FFB76D0256E83A0659595640 +:106A0000E84D97598946FC8B5EFC83EBFE83FB03C4 +:106A10007733D1E32EFFA7996A68AC0256E81706D0 +:106A20005959EB23688F0256E80C065959EB186840 +:106A3000750256E801065959EB0D68C60256E8F68C +:106A4000055959EB02EB006A0156E8C7F85959BFDE +:106A50000100EB3868DD0256E8DC0559596A015639 +:106A6000E8B1F85959BF0100EB22B8D0308BF88952 +:106A700044548A446088445DEB12B8E0208BF88966 +:106A800044548A445E88445DEB02EB00EB02EB0069 +:106A9000EB00E941FC5F5EC9C3196A246A2F6A3AB8 +:106AA0006A0000010002000400410042004300446B +:106AB00000800081008200FF001769546A7A6AA58D +:106AC00069526994696A6A676952697F6967694C42 +:106AD00069F4687668B268EE68F56700681268F570 +:106AE000679D67A867B4679D6700000100F010E02C +:106AF00020D0302768F266C36723671267C8040096 +:106B00000056578B76048A4459988946FC6A098B4B +:106B100046FC05840150E8930859598BF88BC7252A +:106B200000F03D001075558BC725F0003DF0007555 +:106B30004B8BC725000FC1F8088946FE8B44043BE8 +:106B400046FE7D0533C0E9EF008BC7250F00BA0F65 +:106B5000002BD03B56FE740533C0E9DB00C744026E +:106B600004098A46FE88445F88445D8B5EFCD1E35D +:106B7000C787FC080409B8F010E9BC008BC72500E2 +:106B8000F03D002075528BC725F0003DE0007548B0 +:106B90008BC725000FC1F8088946FE837EFE087E5C +:106BA0000533C0E992008BC7250F00BA0F002BD028 +:106BB0003B56FE740533C0EB7F90C744020C098A34 +:106BC00046FE88445E88445D8B5EFCD1E3C787FC4B +:106BD000080C09B8E020EB608BC72500F03D0030C1 +:106BE00075528BC725F0003DD00075488BC7250036 +:106BF0000FC1F8088946FE8B44043B46FE7D0433F2 +:106C0000C0EB358BC7250F00BA0F002BD03B56FECB +:106C1000740433C0EB22C7440214098A46FE884438 +:106C20006088445D8B5EFCD1E3C787FC081409B81B +:106C3000D030EB0433C0EB005F5EC9C3C806000070 +:106C4000568B76046A0856E8350459598A44580424 +:106C5000805056E8290459598B44543B4456750AD0 +:106C60008A445D3A442F7502EB648B445489445640 +:106C70008B5C028A470188442F8A445DB400C1E0DE +:106C8000088B54540BD08A445DB400BB0F002BD842 +:106C90000BD38956FE6A108A445998050400990559 +:106CA000400183D2005250E8540883C4068956FC40 +:106CB0008946FA8B46FE0946FA834EFC006A19FFA4 +:106CC00076FCFF76FAE8730783C406E8FE075EC920 +:106CD000C3C81C000056578B5E048A4759988BF036 +:106CE0008B5E048A475DB4008946E6837EE6007DBC +:106CF0000A8B5E048B4704488946E68B5E048B470B +:106D0000043B46E67F05C746E600008B5E048A46E4 +:106D1000E688475D8BDED1E38B9F5902C647022090 +:106D20008BDED1E38B9F5902C64703308BDED1E364 +:106D30008B9F6102C64702208BDED1E38B9F6102ED +:106D4000C64703308B46E68946FA837EFA007418FC +:106D50008B46FABB0A0033D2F7F380C2308BDED108 +:106D6000E38B9F5902885703BB0A008B46FA33D244 +:106D7000F7F38946FA837EFA0074188B46FABB0A49 +:106D80000033D2F7F380C2308BDED1E38B9F590200 +:106D90008857028B46E68946FA837EFA0074188B80 +:106DA00046FABB0A0033D2F7F380C2308BDED1E360 +:106DB0008B9F6102885703BB0A008B46FA33D2F7D8 +:106DC000F38946FA837EFA0074188B46FABB0A00F0 +:106DD00033D2F7F380C2308BDED1E38B9F61028820 +:106DE00057028B5EE6D1E3FFB712026A00FF76041A +:106DF000E8D1F683C40668D30F6A01FF7604E8C3BE +:106E0000F683C406FF76E656E8019359598956F28F +:106E10008946F0FF76E656E8149359598956EE896B +:106E200046EC9CFAC45EF0268B078946EAC45EEC09 +:106E3000268B078946E8BA50FFED8946FE9DC74676 +:106E4000E40100E8EEA0BA50FFED8946FC8B46FC59 +:106E50002B46FE3DE8037303E980019CFABA50FF1C +:106E6000ED8946FC8B46FC2B46FE8946F8C45EF055 +:106E7000268B072B46EA8946F6C45EF0268B0789E7 +:106E800046EAC45EEC268B072B46E88946F4C45ECE +:106E9000EC268B078946E8BA50FFED8946FE9D81B6 +:106EA0007EF8E803761CFF76F8FF76F6E87601595F +:106EB000598946F6FF76F8FF76F4E8680159598952 +:106EC00046F4BF0E00EB178BDED1E38B9F5902C651 +:106ED00001208BDED1E38B9F6102C601204783FF37 +:106EE0001176E48BDED1E38B9F5902C6470D308BC0 +:106EF000DED1E38B9F6102C6470D30837EF60977B2 +:106F000005B80D00EB26837EF6637705B80E00EB1F +:106F10001B817EF6E7037705B80F00EB0F817EF645 +:106F20000F277705B81000EB03B811008BF8EB259D +:106F30008B46F6BB0A0033D2F7F380C2308BDED12A +:106F4000E38B9F590288114FBB0A008B46F633D260 +:106F5000F7F38946F6837EF60075D5837EF40977CC +:106F600005B80D00EB26837EF4637705B80E00EBC1 +:106F70001B817EF4E7037705B80F00EB0F817EF4E9 +:106F80000F277705B81000EB03B811008BF8EB253D +:106F90008B46F4BB0A0033D2F7F380C2308BDED1CC +:106FA000E38B9F610288114FBB0A008B46F433D2FA +:106FB000F7F38946F4837EF40075D58BDED1E3FFC9 +:106FC000B75902FF7604E86E0059598BDED1E3FF12 +:106FD000B76102FF7604E85E0059596A00FF760443 +:106FE000E831F359598BD883FB04771FD1E32EFF87 +:106FF000A71B70EB22C746E40000FF4EE6EB0CC770 +:1070000046E40000FF46E6EB02EB00837EE40074FA +:1070100003E92AFEE9D4FC5F5EC9C3F36FF56FFF95 +:107020006FF36F0970558BEC8B4604B9E803F7E1F9 +:107030008B4E06F7F15DC3558BEC568B7606EB0E47 +:107040008BDE468A0750FF7604E833005959803CAE +:107050000075EDEB005E5DC3558BEC568B7606EB51 +:10706000148BDE468A0750FF7604E8450059590B19 +:10707000C07402EB07803C0075E7EB005E5DC3C89F +:10708000020000568B76048A445A988946FE9CFA80 +:107090008A46FEBAFE00EEBA0200ECA80274069D13 +:1070A000E8919EEBE9BA00008A4606EE9DEB005E91 +:1070B000C9C3C8040000568B76048A445A9889468E +:1070C000FEE8E6A18946FCE8E0A12B46FC3DB80BB2 +:1070D0007605B80100EB239CFA8A46FEBAFE00EE64 +:1070E000BA0200ECA80274069DE8489EEBD9BA00EB +:1070F000008A4606EE9D33C0EB005EC9C3C804009B +:107100000056578B7604837E0600740756E8030109 +:1071100059EB0556E8A200598846FF807EFF0877A4 +:10712000068A46FFE98400807EFF0F7603EB7990A4 +:107130008A46FFB4002D0A008BD883FB047767D101 +:10714000E32EFFA7AF71B000EB6156E86B0059B4B6 +:1071500000250F008946FC56E85E0059B4008BF804 +:1071600056E8550059B400C1E0088BD703D08BFA1C +:107170008B5EFCD1E3897830EB2E56E83B005988D2 +:10718000445BEB2456E831005988445056E8290006 +:107190005988445156E821005988445256E819004C +:1071A00059884453EB02EB00E95BFF5F5EC9C346BD +:1071B00071A6714A717A718471C8040000568B7689 +:1071C000048A445A988946FE9CFA8A46FEBAFE0012 +:1071D000EEBA0200ECA80175069DE8579DEBE9BAEE +:1071E0000000EC8846FD9D8A46FDEB005EC9C3C8E1 +:1071F000020000568B76048A445A988946FE9CFA0F +:107200008A46FEBAFE00EEBA0200EC32E424019D8A +:107210005EC9C3C8060000568B76048A445A988912 +:1072200046FEE885A08946FAE87FA02B46FA3DB8DD +:107230000B7604B008EB249CFA8A46FEBAFE00EEF8 +:10724000BA0200ECA80175069DE8E89CEBDABA00EA +:1072500000EC8846FD9D8A46FDEB005EC9C3558B58 +:10726000EC568B56048A4606EE33F6EB035058462E +:1072700083FE147CF85E5DC3C8020000568B560482 +:10728000EC8846FF33F6EB0350584683FE147CF837 +:107290008A46FFEB005EC9C3C802000056578B76D2 +:1072A00004833EB00B00751FBA8801B000EEBA86A9 +:1072B00001B000EE6A096A00683001E87D0183C40C +:1072C00006C706B00B01006A098BC605800150E8AD +:1072D000DA0059598BF88BC7C1E80C250F00894695 +:1072E000FE8BC7C1E808250F008B56FE83F20C3BCE +:1072F000C275218BC7C1E804250F008B56FE83F2AF +:10730000063BC2750F8BC7250F008B56FE83F20913 +:107310003BC2740D6A0756E838005959C746FE0744 +:10732000008A46FE0480A233028BC6BA6200F7EAE6 +:107330008A56FE8BD888976C006832028BC6BA6278 +:1073400000F7EA05140050E80EFD5959EB005F5EA6 +:10735000C9C3C8020000568B760683E60F8BC6C1F0 +:10736000E00C8BD683F20CC1E2080BC28BD683F201 +:1073700006C1E2040BC28BD683F2090BC28946FE1A +:107380006A196A108B46049905400183D200525055 +:10739000E86B0183C4060B46FE83CA005250E89A8C +:1073A0000083C406E82501EB005EC9C3558BEC568B +:1073B0005733FF6A01688601E8A3FE5959B1102AC4 +:1073C0004E06D3660433F6EB2E817E0400807204F1 +:1073D000B001EB02B00050688801E881FE59596A9B +:1073E00003688601E877FE59596A01688601E86DED +:1073F000FE5959D16604463B76067CCD33F6EB2424 +:10740000D1E76A03688601E854FE59596A01688623 +:1074100001E84AFE5959688801E85CFE599825013F +:10742000000BF84683FE107CD76A00688601E82DC1 +:10743000FE59598BC7EB005F5E5DC3558BEC565709 +:107440008B7E086A01688601E813FE5959B820004E +:107450002BC750FF7606FF7604E8A20083C4068996 +:10746000560689460433F6EB47817E060080720C8F +:107470007506837E04007204B001EB02B000506810 +:107480008801E8D9FD59596A03688601E8CFFD599A +:10749000596A01688601E8C5FD59596A01FF7606F7 +:1074A000FF7604E8580083C40689560689460446D8 +:1074B0003BF77CB56A00688601E8A2FD59596A006D +:1074C000688601E898FD59595F5E5DC3558BEC569F +:1074D0006A01688601E886FD595933F6EB00688831 +:1074E00001E894FD59A80175088BC6463D64007CEF +:1074F000ED6A00688601E865FD59595E5DC3C80400 +:1075000000008B46048B56068B4E08E306D1E0D173 +:10751000D2E2FA8946FC8956FE8B56FE8B46FCEB7E +:1075200000C9C300000000000000000000000000CF +:1075300050726576696F7573204D656E7500426592 +:1075400067696E00000000000000000000000000FD +:10755000000000000000000000000000000000002B +:10756000000000000000000000000000000000001B +:10757000000000000000000000000000000000000B +:1075800000000000000000000000000000000000FB +:1075900000000000000000000000000000000000EB +:1075A00000000000000000000000000000000000DB +:1075B00000000000000000000000000000000000CB +:1075C00000000000000000000000000000000000BB +:1075D00000000000000000000000000000000000AB +:1075E000000000000000000000000000000000009B +:1075F000000000000000000000000000000000008B +:10760000000000000000000000000000000000007A +:10761000000000000000000000000000000000006A +:10762000000000000000000000000000000000005A +:10763000000000000000000000000000000000004A +:10764000000000000000000000000000000000003A +:10765000000000000000000000000000000000002A +:10766000000000000000000000000000000000001A +:10767000000000000000000000000000000000000A +:1076800000000000000000000000000000000000FA +:1076900000000000000000000000000000000000EA +:1076A00000000000000000000000000000000000DA +:1076B00000000000000000000000000000000000CA +:1076C000000000000000000000000000506F727415 +:1076D000203000506F7274203100506F727420326D +:1076E00000506F7274203300506F72742034005059 +:1076F0006F7274203500506F7274203600506F72B4 +:1077000074203700506F7274203800506F727420EC +:107710003900506F727420313000506F7274203114 +:107720003100506F727420313200506F727420310A +:107730003300506F727420313400506F72742031F6 +:1077400035009C01A301AA01B101B801BF01C60126 +:10775000CD01D401DB01E201EA01F201FA010202EA +:107760000A02080000078100038080809F919591A4 +:107770009F000381848E95848484840003828484A2 +:107780008484958E8400048800B20BC60BDA0BEE5D +:107790000B020C160C2A0C3E0C520C770C9C0CBEE7 +:1077A0000CE00C020D01802054657374205061734D +:1077B000736564201F20507265737320800200017E +:1077C00080204D697373696E67205278204461741C +:1077D000611F205072657373208002000180204277 +:1077E00061642052782044617461201F20507265CA +:1077F000737320800200018020586D7472204275DE +:1078000073791F20507265737320800200018020FD +:107810006E6F742063757272656E746C791F2020B0 +:10782000696D706C656D656E7465640200240D2F62 +:107830000D3A0D450D500D5B0D660D710D7C0D87DC +:107840000D920D9D0DA80DB30DBE0DC90D53802CCD +:107850003254442053862C334454522053822C33C8 +:10786000525453201F53812C3252442053852C32C2 +:1078700043442053832C334354532053842C3344A8 +:1078800053522053872C3252492702000180202076 +:10789000444344202D2070696E2032301F275385C9 +:1078A0002E31818263908081828384858687888956 +:1078B0008A8B8C8D8E8F27020001802020445352AA +:1078C000202D2070696E2031311F2753842E318185 +:1078D000826390808182838485868788898A8B8C65 +:1078E0008D8E8F27020001802020435453202D20AD +:1078F00070696E20341F2753832E318182639080FC +:107900008182838485868788898A8B8C8D8E8F2758 +:107910000200018020205249202D2070696E203203 +:10792000321F2753872E3181826390808182838426 +:1079300085868788898A8B8C8D8E8F2702000180AF +:107940002020445452202D2070696E20362F381F7D +:107950002753862E3181826390808182838485863D +:107960008788898A8B8C8D8E8F270200018020204A +:10797000525453202D2070696E20351F2753822EBC +:107980003181826390808182838485868788898A19 +:107990008B8C8D8E8F27020001802020527844200E +:1079A0002D2070696E20321F2753812E30534D8158 +:1079B000826390808182838485868788898A8B8C84 +:1079C0008D8E8F27020001802020547844202D20A6 +:1079D00070696E20331F2753802E30534D81826390 +:1079E00090808182838485868788898A8B8C8D8E1E +:1079F0008F27020001802020444344202D207069FD +:107A00006E20351F2753852E3181826390808182BD +:107A1000838485868788898A8B8C8D8E8F27020048 +:107A200001802020445352202D2070696E20351F84 +:107A30002753842E3181826390808182838485865E +:107A40008788898A8B8C8D8E8F2702000180202069 +:107A5000435453202D2070696E20311F2753832EED +:107A60003181826390808182838485868788898A38 +:107A70008B8C8D8E8F270200018020205249202D73 +:107A800020286E2E632E291F2753872E3181826373 +:107A900090808182838485868788898A8B8C8D8E6D +:107AA0008F27020001802020445452202D2070692D +:107AB0006E20321F2753862E31818263908081820F +:107AC000838485868788898A8B8C8D8E8F27020098 +:107AD00001802020525453202D2070696E20371FC2 +:107AE0002753822E318182639080818283848586B0 +:107AF0008788898A8B8C8D8E8F27020001802020B9 +:107B0000527844202D2070696E20361F2753812E15 +:107B100030534D81826390808182838485868788FB +:107B2000898A8B8C8D8E8F270200018020205478CB +:107B300044202D2070696E20331F2753802E305330 +:107B40004D81826390808182838485868788898A3B +:107B50008B8C8D8E8F27020001802020444344208F +:107B60002D2070696E20351F202020202753852E60 +:107B700031818263888081828384858687270200A1 +:107B800001802020445352202D2070696E20351F23 +:107B9000202020202753842E318182638880818297 +:107BA0008384858687270200018020204354532048 +:107BB0002D2070696E20311F202020202753832E16 +:107BC0003181826388808182838485868727020051 +:107BD000018020205249202D20286E2E632E291F3F +:107BE000202020202753872E318182638880818244 +:107BF00083848586872702000180202044545220F8 +:107C00002D2070696E20321F202020202753862EC1 +:107C10003181826388808182838485868727020000 +:107C200001802020525453202D2070696E20371F70 +:107C3000202020202753822E3181826388808182F8 +:107C40008384858687270200018020205278442083 +:107C50002D2070696E20361F202020202753812E72 +:107C600030534D8182638880818283848586872713 +:107C7000020001802020547844202D2070696E205D +:107C8000331F202020202753802E30534D818263C4 +:107C90008880818283848586872702000180202056 +:107CA000444344202D2070696E2032301F20202054 +:107CB000202753852E318182638880818283848549 +:107CC000868727020001802020445352202D2070F7 +:107CD000696E2031311F202020202753842E3181CE +:107CE0008263888081828384858687270200018061 +:107CF0002020435453202D2070696E20341F2020F3 +:107D000020202753832E318182638880818283845F +:107D1000858687270200018020205249202D20706F +:107D2000696E2032321F202020202753872E318178 +:107D30008263888081828384858687270200018010 +:107D40002020445452202D2070696E20362F381F79 +:107D5000202020202753862E3181826388808182D3 +:107D60008384858687270200018020205254532077 +:107D70002D2070696E20351F202020202753822E51 +:107D8000318182638880818283848586872702008F +:107D900001802020527844202D2070696E20321FEF +:107DA000202020202753812E30534D8182638880EC +:107DB0008182838485868727020001802020547871 +:107DC00044202D2070696E20331F2020202027534F +:107DD000802E30534D8182638880818283848586A2 +:107DE0008727020068049604B6033C040E04890346 +:107DF0005C03E20360088A08BE0738080E0895078E +:107E00006C07E6071C057405FA05C404F004CC05EC +:107E1000A00548057806C806420728065006180738 +:107E2000F006A0060000F408F408D40D04090409C3 +:107E30000409040942000C091C09E50D020014099B +:107E40000409F40D43001C090C09050E0004040983 +:107E50001409120E2C092C092C092C0900003C09CC +:107E60006C091E0E740974097409740900014C0927 +:107E70002C092D0E740974097409740900025C0937 +:107E80003C093D0E740974097409740900036C09F6 +:107E90004C094D0E7409740974097409FF002C090A +:107EA0005C09000000058409EC095E0EF409F40980 +:107EB000F409F409000694097409680EAC0AAC0AC6 +:107EC000AC0AAC0A0007A4098409720EBC0ABC0AF9 +:107ED000BC0ABC0A0008B40994097C0ED40AD40A6E +:107EE000D40AD40A000BC409A409830EFC0AFC0AB4 +:107EF000FC0AFC0A000CD409B409900E140B140BF4 +:107F0000140B140B0002E409C409A00E2C0B2C0B5B +:107F10002C0B2C0B0400EC09D4090E00FF00740993 +:107F2000E40900008201FC09A40AAC0E8202040AE2 +:107F3000F409AF0E82030C0AFC09B20E8204140A83 +:107F4000040AB60E82051C0A0C0ABC0E8206240A1C +:107F5000140AC00E82072C0A1C0AC40E8208340AB6 +:107F6000240AC80E82093C0A2C0ACC0E820A440A52 +:107F7000340AD10E82104C0A3C0AD60E820B540AE7 +:107F8000440ADB0E82115C0A4C0AE00E820C640A81 +:107F9000540AE50E82126C0A5C0AEA0E820D740A1B +:107FA000640AEF0E820E7C0A6C0AF40E820F840AB9 +:107FB000740AFB0E82138C0A7C0A020F8214940A44 +:107FC000840A090F82159C0A8C0A100F8216A40AD3 +:107FD000940A170F8217F4099C0A1E0F8202B40A32 +:107FE000B40A260F8203AC0AAC0A2D0F8200C40A21 +:107FF000CC0A340F8201CC0ABC0A3F0F8202BC0AB1 +:10800000C40A4D0F8200DC0AF40A590F8201E40A07 +:10801000D40A630F8202EC0ADC0A6E0F8203F40AB0 +:10802000E40A7A0F8204D40AEC0A870F8200040B58 +:108030000C0B930F82010C0BFC0A9B0F8202FC0AB3 +:10804000040BA70F82001C0B240BB00F8201240B22 +:10805000140BB50F8202140B1C0BBE0F4400340B23 +:10806000A40B9C0144013C0B2C0BA3014402440BC8 +:10807000340BAA0144034C0B3C0BB1014404540BD8 +:10808000440BB80144055C0B4C0BBF014406640B68 +:10809000540BC60144076C0B5C0BCD014408740BF8 +:1080A000640BD40144097C0B6C0BDB01440A840B88 +:1080B000740BE201440B8C0B7C0BEA01440C940B17 +:1080C000840BF201440D9C0B8C0BFA01440EA40BA3 +:1080D000940B0202440F2C0B9C0B0A02171F0F2F4C +:1080E0000000018078783A20747820637073202A29 +:1080F0002A2A2A2A0200018078783A20747820639C +:108100007073202A2A2A2A2A0200018078783A20CD +:10811000747820637073202A2A2A2A2A0200018098 +:1081200078783A20747820637073202A2A2A2A2AC1 +:10813000020001C078783A20726320637073202AAD +:108140002A2A2A2A020001C078783A207263206322 +:108150007073202A2A2A2A2A020001C078783A203D +:10816000726320637073202A2A2A2A2A020001C01F +:1081700078783A20726320637073202A2A2A2A2A88 +:1081800002000180496E7374616C6C204C6F6F70DB +:108190006261636B1F5072657373208020746F205F +:1081A000737461727402000180204361626C652007 +:1081B000746F2052656D6F74651F50726573732004 +:1081C0008020746F20737461727402000180204CEF +:1081D0006F63616C204C6F6F706261636B201F2056 +:1081E0002052756E6E696E67202E2E2E0200018061 +:1081F00052656D6F7465204C6F6F706261636B20A8 +:108200001F202052756E6E696E67202E2E2E020082 +:10821000018020496E74726E6C204C6F6F706261C9 +:10822000636B1F202052756E6E696E67202E2E2E96 +:10823000020001805472616E736D69742050617424 +:108240007465726E1F202052756E6E696E67202EE7 +:108250002E2E020001802020303A2027438000018A +:10826000802020313A202743810001802020323AAB +:10827000202743820001802020333A2027438300B7 +:1082800001802020343A20274384000180202035BB +:108290003A202743850001802020363A2027438654 +:1082A0000001802020373A202743870001802020CA +:1082B000383A202743880001802020393A2027437C +:1082C000890001802031303A2027438A0001802034 +:1082D00031313A2027438B0001802031323A202768 +:1082E000438C0001802031333A2027438D000180E8 +:1082F0002031343A2027438E0001802031353A2046 +:1083000027438F002A2A204D61696E20204D656E1B +:1083100075202A2A004D6F6E69746F72206120509B +:108320006F7274004D6F6E69746F722061205369B3 +:10833000676E616C00457374696D617465204350AC +:108340005300446961676E6F7374696373004C6FA7 +:1083500063616C204C6F6F706261636B0052656D7E +:108360006F7465204C6F6F706261636B00496E744F +:10837000726E6C204C6F6F706261636B005472613F +:108380006E736D6974205061747465726E00426121 +:10839000756420526174650044617461204269749F +:1083A000730053746F702042697473005061726976 +:1083B00074790044617461205061747465726E0058 +:1083C000547820466C6F7720436F6E74726F6C0028 +:1083D000506F7274204E756D6265720035300037D3 +:1083E0003500313130003133342E35003135300035 +:1083F00032303000333030003630300031323030FF +:10840000003138303000323030300032343030001B +:1084100033363030003438303000373230300039C5 +:108420003630300031392C3230300033382C343093 +:10843000300035362C3030300035372C36303000B7 +:1084400036342C3030300037362C38303000313173 +:10845000352C323030003720626974730038206266 +:1084600069747300312073746F7020626974003115 +:108470002E352073746F702062697473003220731C +:10848000746F702062697473006E6F20706172691E +:108490007479006F64642070617269747900657624 +:1084A000656E207061726974790073706163652014 +:1084B000706172697479006D61726B2070617269AC +:1084C000747900436F6C756D6E7300426172626502 +:1084D0007220506F6C650055555555552E2E2E0047 +:1084E0004E6F6E6500586F6E2F586F66660043546E +:1084F00053005072657373208020666F72206D6523 +:108500006E750028636F756E74696E672E2E2E2946 +:108510000000654E64204F6620436F4465000000F4 +:10852000000000000000000000000000000000004B +:10853000000000000000000000000000000000003B +:10854000000000000000000000000000000000002B +:10855000000000000000000000000000000000001B +:10856000000000000000000000000000000000000B +:1085700000000000000000000000000000000000FB +:1085800000000000000000000000000000000000EB +:1085900000000000000000000000000000000000DB +:1085A00000000000000000000000000000000000CB +:1085B00000000000000000000000000000000000BB +:1085C00000000000000000000000000000000000AB +:1085D000000000000000000000000000000000009B +:1085E000000000000000000000000000000000008B +:1085F000000000000000000000000000000000007B +:00000001FF +/* Intelliport II loadware */ +/* -31232 bytes read from ff.lod */ -- cgit v0.10.2 From 0c5d5b70449eddb7e2c8a5fdaf71b6108c1a9afc Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 10 Jul 2008 14:44:23 +0100 Subject: [ARM] 5171/1: ep93xx: fix compilation of modules using clocks Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 9d7515c..f62c355 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -74,6 +74,7 @@ struct clk *clk_get(struct device *dev, const char *id) return ERR_PTR(-ENOENT); } +EXPORT_SYMBOL(clk_get); int clk_enable(struct clk *clk) { @@ -86,6 +87,7 @@ int clk_enable(struct clk *clk) return 0; } +EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { @@ -96,15 +98,18 @@ void clk_disable(struct clk *clk) __raw_writel(value & ~clk->enable_mask, clk->enable_reg); } } +EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { return clk->rate; } +EXPORT_SYMBOL(clk_get_rate); void clk_put(struct clk *clk) { } +EXPORT_SYMBOL(clk_put); -- cgit v0.10.2 From 9cabcdbd4638cf884839ee4cd15780800c223b90 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 10 Jul 2008 15:54:12 +0100 Subject: [GFS2] Replace rgrp "recent list" with mru list This patch removes the "recent list" which is used during allocation and replaces it with the (already existing) mru list used during deletion. The "recent list" was not a true mru list leading to a number of inefficiencies including a "next" function which made scanning the list an order N^2 operation wrt to the number of list elements. This should increase allocation performance with large numbers of rgrps. Its also a useful preparation and cleanup before some further changes which are planned in this area. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 4b734c6..4ab3c3a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -77,7 +77,6 @@ struct gfs2_rgrp_host { struct gfs2_rgrpd { struct list_head rd_list; /* Link with superblock */ struct list_head rd_list_mru; - struct list_head rd_recent; /* Recently used rgrps */ struct gfs2_glock *rd_gl; /* Glock for this rgrp */ u64 rd_addr; /* grp block disk address */ u64 rd_data0; /* first data location */ @@ -529,7 +528,6 @@ struct gfs2_sbd { struct mutex sd_rindex_mutex; struct list_head sd_rindex_list; struct list_head sd_rindex_mru_list; - struct list_head sd_rindex_recent_list; struct gfs2_rgrpd *sd_rindex_forward; unsigned int sd_rgrps; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 6ba69dd..b4d1d64 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -64,7 +64,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) mutex_init(&sdp->sd_rindex_mutex); INIT_LIST_HEAD(&sdp->sd_rindex_list); INIT_LIST_HEAD(&sdp->sd_rindex_mru_list); - INIT_LIST_HEAD(&sdp->sd_rindex_recent_list); INIT_LIST_HEAD(&sdp->sd_jindex_list); spin_lock_init(&sdp->sd_jindex_spin); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 3401628..2d90fb2 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -371,11 +371,6 @@ static void clear_rgrpdi(struct gfs2_sbd *sdp) spin_lock(&sdp->sd_rindex_spin); sdp->sd_rindex_forward = NULL; - head = &sdp->sd_rindex_recent_list; - while (!list_empty(head)) { - rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent); - list_del(&rgd->rd_recent); - } spin_unlock(&sdp->sd_rindex_spin); head = &sdp->sd_rindex_list; @@ -945,107 +940,30 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) } /** - * recent_rgrp_first - get first RG from "recent" list - * @sdp: The GFS2 superblock - * @rglast: address of the rgrp used last - * - * Returns: The first rgrp in the recent list - */ - -static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, - u64 rglast) -{ - struct gfs2_rgrpd *rgd; - - spin_lock(&sdp->sd_rindex_spin); - - if (rglast) { - list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { - if (rgrp_contains_block(rgd, rglast)) - goto out; - } - } - rgd = NULL; - if (!list_empty(&sdp->sd_rindex_recent_list)) - rgd = list_entry(sdp->sd_rindex_recent_list.next, - struct gfs2_rgrpd, rd_recent); -out: - spin_unlock(&sdp->sd_rindex_spin); - return rgd; -} - -/** * recent_rgrp_next - get next RG from "recent" list * @cur_rgd: current rgrp - * @remove: * * Returns: The next rgrp in the recent list */ -static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd, - int remove) +static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd) { struct gfs2_sbd *sdp = cur_rgd->rd_sbd; struct list_head *head; struct gfs2_rgrpd *rgd; spin_lock(&sdp->sd_rindex_spin); - - head = &sdp->sd_rindex_recent_list; - - list_for_each_entry(rgd, head, rd_recent) { - if (rgd == cur_rgd) { - if (cur_rgd->rd_recent.next != head) - rgd = list_entry(cur_rgd->rd_recent.next, - struct gfs2_rgrpd, rd_recent); - else - rgd = NULL; - - if (remove) - list_del(&cur_rgd->rd_recent); - - goto out; - } + head = &sdp->sd_rindex_mru_list; + if (unlikely(cur_rgd->rd_list_mru.next == head)) { + spin_unlock(&sdp->sd_rindex_spin); + return NULL; } - - rgd = NULL; - if (!list_empty(head)) - rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent); - -out: + rgd = list_entry(cur_rgd->rd_list_mru.next, struct gfs2_rgrpd, rd_list_mru); spin_unlock(&sdp->sd_rindex_spin); return rgd; } /** - * recent_rgrp_add - add an RG to tail of "recent" list - * @new_rgd: The rgrp to add - * - */ - -static void recent_rgrp_add(struct gfs2_rgrpd *new_rgd) -{ - struct gfs2_sbd *sdp = new_rgd->rd_sbd; - struct gfs2_rgrpd *rgd; - unsigned int count = 0; - unsigned int max = sdp->sd_rgrps / gfs2_jindex_size(sdp); - - spin_lock(&sdp->sd_rindex_spin); - - list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { - if (rgd == new_rgd) - goto out; - - if (++count >= max) - goto out; - } - list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list); - -out: - spin_unlock(&sdp->sd_rindex_spin); -} - -/** * forward_rgrp_get - get an rgrp to try next from full list * @sdp: The GFS2 superblock * @@ -1112,9 +1030,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) int loops = 0; int error, rg_locked; - /* Try recently successful rgrps */ - - rgd = recent_rgrp_first(sdp, ip->i_goal); + rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); while (rgd) { rg_locked = 0; @@ -1136,11 +1052,9 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) gfs2_glock_dq_uninit(&al->al_rgd_gh); if (inode) return inode; - rgd = recent_rgrp_next(rgd, 1); - break; - + /* fall through */ case GLR_TRYFAILED: - rgd = recent_rgrp_next(rgd, 0); + rgd = recent_rgrp_next(rgd); break; default: @@ -1199,7 +1113,9 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) out: if (begin) { - recent_rgrp_add(rgd); + spin_lock(&sdp->sd_rindex_spin); + list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); + spin_unlock(&sdp->sd_rindex_spin); rgd = gfs2_rgrpd_get_next(rgd); if (!rgd) rgd = gfs2_rgrpd_get_first(sdp); -- cgit v0.10.2 From c9f6a6bbc284ba87337876086f7e2e6e0b0d50dd Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 10 Jul 2008 16:09:29 +0100 Subject: [GFS2] Remove support for unused and pointless flag The ability to mark files for direct i/o access when opened normally is both unused and pointless, so this patch removes support for that feature. Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 4ab3c3a..448697a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -421,7 +421,6 @@ struct gfs2_tune { unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ unsigned int gt_atime_quantum; /* Min secs between atime updates */ unsigned int gt_new_files_jdata; - unsigned int gt_new_files_directio; unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ unsigned int gt_stall_secs; /* Detects trouble! */ unsigned int gt_complain_secs; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index caf4090..6da0ab3 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -789,13 +789,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || gfs2_tune_get(sdp, gt_new_files_jdata)) di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); - if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_DIRECTIO) || - gfs2_tune_get(sdp, gt_new_files_directio)) - di->di_flags |= cpu_to_be32(GFS2_DIF_DIRECTIO); } else if (S_ISDIR(mode)) { di->di_flags |= cpu_to_be32(dip->i_di.di_flags & - GFS2_DIF_INHERIT_DIRECTIO); - di->di_flags |= cpu_to_be32(dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA); } diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 1737af9..21b397d 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c @@ -134,7 +134,6 @@ static const u32 fsflags_to_gfs2[32] = { [7] = GFS2_DIF_NOATIME, [12] = GFS2_DIF_EXHASH, [14] = GFS2_DIF_INHERIT_JDATA, - [20] = GFS2_DIF_INHERIT_DIRECTIO, }; static const u32 gfs2_to_fsflags[32] = { @@ -143,7 +142,6 @@ static const u32 gfs2_to_fsflags[32] = { [gfs2fl_AppendOnly] = FS_APPEND_FL, [gfs2fl_NoAtime] = FS_NOATIME_FL, [gfs2fl_ExHash] = FS_INDEX_FL, - [gfs2fl_InheritDirectio] = FS_DIRECTIO_FL, [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, }; @@ -161,12 +159,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) return error; fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); - if (!S_ISDIR(inode->i_mode)) { - if (ip->i_di.di_flags & GFS2_DIF_JDATA) - fsflags |= FS_JOURNAL_DATA_FL; - if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) - fsflags |= FS_DIRECTIO_FL; - } + if (!S_ISDIR(inode->i_mode) && ip->i_di.di_flags & GFS2_DIF_JDATA) + fsflags |= FS_JOURNAL_DATA_FL; if (put_user(fsflags, ptr)) error = -EFAULT; @@ -195,13 +189,11 @@ void gfs2_set_inode_flags(struct inode *inode) /* Flags that can be set by user space */ #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ - GFS2_DIF_DIRECTIO| \ GFS2_DIF_IMMUTABLE| \ GFS2_DIF_APPENDONLY| \ GFS2_DIF_NOATIME| \ GFS2_DIF_SYNC| \ GFS2_DIF_SYSTEM| \ - GFS2_DIF_INHERIT_DIRECTIO| \ GFS2_DIF_INHERIT_JDATA) /** @@ -292,8 +284,6 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) if (!S_ISDIR(inode->i_mode)) { if (gfsflags & GFS2_DIF_INHERIT_JDATA) gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); - if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO) - gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO); return do_gfs2_set_flags(filp, gfsflags, ~0); } return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); @@ -494,11 +484,6 @@ static int gfs2_open(struct inode *inode, struct file *file) goto fail_gunlock; } - /* Listen to the Direct I/O flag */ - - if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) - file->f_flags |= O_DIRECT; - gfs2_glock_dq_uninit(&i_gh); } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 12fe38f..63a8a90 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -65,7 +65,6 @@ void gfs2_tune_init(struct gfs2_tune *gt) gt->gt_quota_quantum = 60; gt->gt_atime_quantum = 3600; gt->gt_new_files_jdata = 0; - gt->gt_new_files_directio = 0; gt->gt_max_readahead = 1 << 18; gt->gt_stall_secs = 600; gt->gt_complain_secs = 10; diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 6f7e2e5..7484655 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -412,7 +412,6 @@ TUNE_ATTR(max_readahead, 0); TUNE_ATTR(complain_secs, 0); TUNE_ATTR(statfs_slow, 0); TUNE_ATTR(new_files_jdata, 0); -TUNE_ATTR(new_files_directio, 0); TUNE_ATTR(quota_simul_sync, 1); TUNE_ATTR(quota_cache_secs, 1); TUNE_ATTR(stall_secs, 1); @@ -441,7 +440,6 @@ static struct attribute *tune_attrs[] = { &tune_attr_quotad_secs.attr, &tune_attr_quota_scale.attr, &tune_attr_new_files_jdata.attr, - &tune_attr_new_files_directio.attr, NULL, }; -- cgit v0.10.2 From a93a6ce24215c69126c88f9c488afa50a168e0ca Mon Sep 17 00:00:00 2001 From: Li Xiaodong Date: Mon, 7 Jul 2008 18:04:09 +0800 Subject: [GFS2] Remove unused declaration The implementation of gfs2_inode_attr_in is removed. So remove its declaration. Signed-off-by: Li Xiaodong Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 04e9fef..6074c25 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -72,7 +72,6 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, } -void gfs2_inode_attr_in(struct gfs2_inode *ip); void gfs2_set_iop(struct inode *inode); struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, u64 no_addr, u64 no_formal_ino, -- cgit v0.10.2 From 3b33553badcde952adcf3b3ba5faae38d7d85071 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 17:30:40 +0200 Subject: x86: add early quirk support Add early quirks support. In preparation of enabling the generic architecture to boot on a VISWS. This will allow us to remove the VISWS subarch and all its complications. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 9836a07..269d367 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1297,6 +1297,11 @@ void __init e820_reserve_resources(void) } } +/* + * Non-standard memory setup can be specified via this quirk: + */ +char * (*arch_memory_setup_quirk)(void); + char *__init default_machine_specific_memory_setup(void) { char *who = "BIOS-e820"; @@ -1337,6 +1342,12 @@ char *__init default_machine_specific_memory_setup(void) char *__init __attribute__((weak)) machine_specific_memory_setup(void) { + if (arch_memory_setup_quirk) { + char *who = arch_memory_setup_quirk(); + + if (who) + return who; + } return default_machine_specific_memory_setup(); } diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 8b6b1e0..3b25e49 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -726,12 +726,22 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) static struct intel_mp_floating *mpf_found; /* + * Machine specific quirk for finding the SMP config before other setup + * activities destroy the table: + */ +int (*mach_get_smp_config_quirk)(unsigned int early); + +/* * Scan the memory blocks for an SMP configuration block. */ -static void __init __get_smp_config(unsigned early) +static void __init __get_smp_config(unsigned int early) { struct intel_mp_floating *mpf = mpf_found; + if (mach_get_smp_config_quirk) { + if (mach_get_smp_config_quirk(early)) + return; + } if (acpi_lapic && early) return; /* @@ -889,10 +899,16 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, return 0; } -static void __init __find_smp_config(unsigned reserve) +int (*mach_find_smp_config_quirk)(unsigned int reserve); + +static void __init __find_smp_config(unsigned int reserve) { unsigned int address; + if (mach_find_smp_config_quirk) { + if (mach_find_smp_config_quirk(reserve)) + return; + } /* * FIXME: Linux assumes you have 640K of base ram.. * this continues the error... diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a7c3471..cb3db40 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -596,6 +596,7 @@ void __init setup_arch(char **cmdline_p) { #ifdef CONFIG_X86_32 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); + visws_early_detect(); pre_setup_arch_hook(); early_cpu_init(); #else diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h index 1d121c6..1ad7eae 100644 --- a/include/asm-x86/setup.h +++ b/include/asm-x86/setup.h @@ -8,6 +8,23 @@ /* Interrupt control for vSMPowered x86_64 systems */ void vsmp_init(void); +#ifdef CONFIG_X86_VISWS +extern void visws_early_detect(void); +#else +static inline void visws_early_detect(void) { } +#endif + +/* + * Any setup quirks to be performed? + */ +extern int (*arch_time_init_quirk)(void); +extern int (*arch_pre_intr_init_quirk)(void); +extern int (*arch_intr_init_quirk)(void); +extern int (*arch_trap_init_quirk)(void); +extern char * (*arch_memory_setup_quirk)(void); +extern int (*mach_get_smp_config_quirk)(unsigned int early); +extern int (*mach_find_smp_config_quirk)(unsigned int reserve); + #ifndef CONFIG_PARAVIRT #define paravirt_post_allocator_init() do {} while (0) #endif -- cgit v0.10.2 From 22d5c67c5b0476e463ce4b632ba9ec3953d33a5f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:29:28 +0200 Subject: x86, VisWS: turn into generic arch, make VisWS boot on a regular PC first step: make the VISWS subarch boot on a regular PC. We take various shortcuts for that. We copy the generic arch setup file over into the VISWS setup file. This is the only step that is not expected to boot on a real VISWS. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 3e94720..3e58b67 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c @@ -974,7 +974,7 @@ void __cpuinit setup_local_APIC(void) * Double-check whether this APIC is really registered. */ if (!apic_id_registered()) - BUG(); + WARN_ON_ONCE(1); /* * Intel recommends to set DFR, LDR and TPR before enabling diff --git a/arch/x86/mach-visws/reboot.c b/arch/x86/mach-visws/reboot.c index 99332ab..79c26ea 100644 --- a/arch/x86/mach-visws/reboot.c +++ b/arch/x86/mach-visws/reboot.c @@ -33,7 +33,7 @@ void machine_restart(char * __unused) void machine_power_off(void) { unsigned short pm_status; - extern unsigned int pci_bus0; +/* extern unsigned int pci_bus0; */ while ((pm_status = inw(PMSTS_PORT)) & 0x100) outw(pm_status, PMSTS_PORT); @@ -45,7 +45,7 @@ void machine_power_off(void) #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) - outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); +/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ outl(PIIX_SPECIAL_STOP, 0xCFC); } diff --git a/arch/x86/mach-visws/setup.c b/arch/x86/mach-visws/setup.c index d67868e..2f5e277 100644 --- a/arch/x86/mach-visws/setup.c +++ b/arch/x86/mach-visws/setup.c @@ -1,183 +1,144 @@ /* - * Unmaintained SGI Visual Workstation support. - * Split out from setup.c by davej@suse.de + * Machine specific setup for generic */ #include #include #include -#include - -#include +#include #include -#include #include #include -#include "cobalt.h" -#include "piix4.h" - -int no_broadcast; - -char visws_board_type = -1; -char visws_board_rev = -1; - -void __init visws_get_board_type_and_rev(void) -{ - int raw; - - visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) - >> PIIX_GPI_BD_SHIFT; - /* - * Get Board rev. - * First, we have to initialize the 307 part to allow us access - * to the GPIO registers. Let's map them at 0x0fc0 which is right - * after the PIIX4 PM section. - */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ - - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ - - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ - - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable GPIO registers. */ - - /* - * Now, we have to map the power management section to write - * a bit which enables access to the GPIO registers. - * What lunatic came up with this shit? - */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ - - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ - - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable PM registers. */ - - /* - * Now, write the PM register which enables the GPIO registers. - */ - outb_p(SIO_PM_FER2, SIO_PM_INDEX); - outb_p(SIO_PM_GP_EN, SIO_PM_DATA); - - /* - * Now, initialize the GPIO registers. - * We want them all to be inputs which is the - * power on default, so let's leave them alone. - * So, let's just read the board rev! - */ - raw = inb_p(SIO_GP_DATA1); - raw &= 0x7f; /* 7 bits of valid board revision ID. */ - - if (visws_board_type == VISWS_320) { - if (raw < 0x6) { - visws_board_rev = 4; - } else if (raw < 0xc) { - visws_board_rev = 5; - } else { - visws_board_rev = 6; - } - } else if (visws_board_type == VISWS_540) { - visws_board_rev = 2; - } else { - visws_board_rev = raw; - } - - printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", - (visws_board_type == VISWS_320 ? "320" : - (visws_board_type == VISWS_540 ? "540" : - "unknown")), visws_board_rev); -} +#ifdef CONFIG_HOTPLUG_CPU +#define DEFAULT_SEND_IPI (1) +#else +#define DEFAULT_SEND_IPI (0) +#endif +int no_broadcast=DEFAULT_SEND_IPI; + +/** + * pre_intr_init_hook - initialisation prior to setting up interrupt vectors + * + * Description: + * Perform any necessary interrupt initialisation prior to setting up + * the "ordinary" interrupt call gates. For legacy reasons, the ISA + * interrupts should be initialised here if the machine emulates a PC + * in any way. + **/ void __init pre_intr_init_hook(void) { - init_VISWS_APIC_irqs(); + 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 + * + * Description: + * Fill in any interrupts that may have been left out by the general + * init_IRQ() routine. interrupts having to do with the machine rather + * than the devices on the I/O bus (like APIC interrupts in intel MP + * systems) are started here. + **/ void __init intr_init_hook(void) { #ifdef CONFIG_X86_LOCAL_APIC apic_intr_init(); #endif + + if (!acpi_ioapic) + setup_irq(2, &irq2); +} + +/** + * pre_setup_arch_hook - hook called prior to any setup_arch() execution + * + * Description: + * generally used to activate any machine specific identification + * routines that may be needed before setup_arch() runs. On VISWS + * this is used to get the board revision and type. + **/ +void __init pre_setup_arch_hook(void) +{ } -void __init pre_setup_arch_hook() +/** + * trap_init_hook - initialise system specific traps + * + * Description: + * Called as the final act of trap_init(). Used in VISWS to initialise + * the various board specific APIC traps. + **/ +void __init trap_init_hook(void) { - visws_get_board_type_and_rev(); } -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL, - .name = "timer", +static struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, + .name = "timer" }; +/** + * time_init_hook - do any specific initialisations for the system timer. + * + * Description: + * Must plug the system timer interrupt source at HZ into the IRQ listed + * in irq_vectors.h:TIMER_IRQ + **/ void __init time_init_hook(void) { - printk(KERN_INFO "Starting Cobalt Timer system clock\n"); - - /* Set the countdown value */ - co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); - - /* Start the timer */ - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); - - /* Enable (unmask) the timer interrupt */ - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); - - /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */ + irq0.mask = cpumask_of_cpu(0); setup_irq(0, &irq0); } -/* Hook for machine specific memory setup. */ - -#define MB (1024 * 1024) - -unsigned long sgivwfb_mem_phys; -unsigned long sgivwfb_mem_size; -EXPORT_SYMBOL(sgivwfb_mem_phys); -EXPORT_SYMBOL(sgivwfb_mem_size); - -long long mem_size __initdata = 0; - -char * __init machine_specific_memory_setup(void) +#ifdef CONFIG_MCA +/** + * mca_nmi_hook - hook into MCA specific NMI chain + * + * Description: + * The MCA (Microchannel Architecture) has an NMI chain for NMI sources + * along the MCA bus. Use this to hook into that chain if you will need + * it. + **/ +void mca_nmi_hook(void) { - long long gfx_mem_size = 8 * MB; + /* If I recall correctly, there's a whole bunch of other things that + * we can do to check for NMI problems, but that's all I know about + * at the moment. + */ - mem_size = boot_params.alt_mem_k; + printk("NMI generated from unknown source!\n"); +} +#endif - if (!mem_size) { - printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); - mem_size = 128 * MB; - } +static __init int no_ipi_broadcast(char *str) +{ + get_option(&str, &no_broadcast); + printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : + "IPI Broadcast"); + return 1; +} - /* - * this hardcodes the graphics memory to 8 MB - * it really should be sized dynamically (or at least - * set as a boot param) - */ - if (!sgivwfb_mem_size) { - printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); - sgivwfb_mem_size = 8 * MB; - } +__setup("no_ipi_broadcast=", no_ipi_broadcast); - /* - * Trim to nearest MB - */ - sgivwfb_mem_size &= ~((1 << 20) - 1); - sgivwfb_mem_phys = mem_size - gfx_mem_size; +static int __init print_ipi_mode(void) +{ + printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : + "Shortcut"); + return 0; +} - e820_add_region(0, LOWMEMSIZE(), E820_RAM); - e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); - e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); +late_initcall(print_ipi_mode); - return "PROM"; -} diff --git a/arch/x86/mach-visws/traps.c b/arch/x86/mach-visws/traps.c index bfac6ba..dd1f5fa 100644 --- a/arch/x86/mach-visws/traps.c +++ b/arch/x86/mach-visws/traps.c @@ -25,13 +25,13 @@ static __init void lithium_init(void) if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); - panic("This machine is not SGI Visual Workstation 320/540"); +/* panic("This machine is not SGI Visual Workstation 320/540"); */ } if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); - panic("This machine is not SGI Visual Workstation 320/540"); +/* panic("This machine is not SGI Visual Workstation 320/540"); */ } li_pcia_write16(LI_PCI_INTEN, ALLDEVS); @@ -62,7 +62,7 @@ static __init void cobalt_init(void) co_apic_read(CO_APIC_ID)); } -void __init trap_init_hook(void) +void __init trap_init_hook_dontuse(void) { lithium_init(); cobalt_init(); diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c index d8b2cfd..8b1cd8e 100644 --- a/arch/x86/mach-visws/visws_apic.c +++ b/arch/x86/mach-visws/visws_apic.c @@ -25,6 +25,9 @@ #include "cobalt.h" +char visws_board_type = -1; +char visws_board_rev = -1; + static DEFINE_SPINLOCK(cobalt_lock); /* diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 99d9f09..fa0164d 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -11,7 +11,7 @@ pci-y += legacy.o irq.o # Careful: VISWS overrule the pci-y above. The colons are # therefor correct. This needs a proper fix by distangling the code. -pci-$(CONFIG_X86_VISWS) := visws.o fixup.o +#pci-$(CONFIG_X86_VISWS) := visws.o irq.o fixup.o pci-$(CONFIG_X86_NUMAQ) += numa.o diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 16e5206..343ccf6 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -16,10 +16,10 @@ static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } static void pci_visws_disable_irq(struct pci_dev *dev) { } -int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; -void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; +/* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */ +/* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */ -void __init pcibios_penalize_isa_irq(int irq, int active) {} +/* void __init pcibios_penalize_isa_irq(int irq, int active) {} */ unsigned int pci_bus0, pci_bus1; diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 4d1ce2e..3452cf5 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_PPC) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o -obj-$(CONFIG_X86_VISWS) += setup-irq.o +#obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o # -- cgit v0.10.2 From 31ac409a7921da39cc998f2432afa13e77fd8705 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 13:31:04 +0200 Subject: x86, VisWS: turn into generic arch, add early init quirks add early init quirks for VisWS. This gradually turns the VISWS subarch into a generic PC architecture. Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3b1b1da..5198a08 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -186,7 +186,7 @@ config X86_HT config X86_BIOS_REBOOT bool - depends on !X86_VISWS && !X86_VOYAGER + depends on !X86_VOYAGER default y config X86_TRAMPOLINE diff --git a/arch/x86/mach-visws/Makefile b/arch/x86/mach-visws/Makefile index 835fd96..35a4c10 100644 --- a/arch/x86/mach-visws/Makefile +++ b/arch/x86/mach-visws/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := setup.o traps.o reboot.o +obj-y := setup.o setup_visws.o traps.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o diff --git a/arch/x86/mach-visws/reboot.c b/arch/x86/mach-visws/reboot.c deleted file mode 100644 index 79c26ea..0000000 --- a/arch/x86/mach-visws/reboot.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include - -#include -#include "piix4.h" - -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - -void machine_shutdown(void) -{ -#ifdef CONFIG_SMP - smp_send_stop(); -#endif -} - -void machine_emergency_restart(void) -{ - /* - * Visual Workstations restart after this - * register is poked on the PIIX4 - */ - outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); -} - -void machine_restart(char * __unused) -{ - machine_shutdown(); - machine_emergency_restart(); -} - -void machine_power_off(void) -{ - unsigned short pm_status; -/* extern unsigned int pci_bus0; */ - - while ((pm_status = inw(PMSTS_PORT)) & 0x100) - outw(pm_status, PMSTS_PORT); - - outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); - - mdelay(10); - -#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ - (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) - -/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ - outl(PIIX_SPECIAL_STOP, 0xCFC); -} - -void machine_halt(void) -{ -} - diff --git a/arch/x86/mach-visws/setup.c b/arch/x86/mach-visws/setup.c index 2f5e277..b8054c3 100644 --- a/arch/x86/mach-visws/setup.c +++ b/arch/x86/mach-visws/setup.c @@ -10,6 +10,14 @@ #include #include +/* + * Any quirks to be performed to initialize timers/irqs/etc? + */ +int (*arch_time_init_quirk)(void); +int (*arch_pre_intr_init_quirk)(void); +int (*arch_intr_init_quirk)(void); +int (*arch_trap_init_quirk)(void); + #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) #else @@ -29,6 +37,10 @@ int no_broadcast=DEFAULT_SEND_IPI; **/ void __init pre_intr_init_hook(void) { + if (arch_pre_intr_init_quirk) { + if (arch_pre_intr_init_quirk()) + return; + } init_ISA_irqs(); } @@ -52,6 +64,10 @@ static struct irqaction irq2 = { **/ void __init intr_init_hook(void) { + if (arch_intr_init_quirk) { + if (arch_intr_init_quirk()) + return; + } #ifdef CONFIG_X86_LOCAL_APIC apic_intr_init(); #endif @@ -81,6 +97,10 @@ void __init pre_setup_arch_hook(void) **/ void __init trap_init_hook(void) { + if (arch_trap_init_quirk) { + if (arch_trap_init_quirk()) + return; + } } static struct irqaction irq0 = { @@ -99,6 +119,16 @@ static struct irqaction irq0 = { **/ void __init time_init_hook(void) { + if (arch_time_init_quirk) { + /* + * A nonzero return code does not mean failure, it means + * that the architecture quirk does not want any + * generic (timer) setup to be performed after this: + */ + if (arch_time_init_quirk()) + return; + } + irq0.mask = cpumask_of_cpu(0); setup_irq(0, &irq0); } diff --git a/arch/x86/mach-visws/setup_visws.c b/arch/x86/mach-visws/setup_visws.c new file mode 100644 index 0000000..659777f --- /dev/null +++ b/arch/x86/mach-visws/setup_visws.c @@ -0,0 +1,233 @@ +/* + * Unmaintained SGI Visual Workstation support. + * Split out from setup.c by davej@suse.de + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "cobalt.h" +#include "piix4.h" + +char visws_board_type = -1; +char visws_board_rev = -1; + +static int __init visws_time_init_quirk(void) +{ + printk(KERN_INFO "Starting Cobalt Timer system clock\n"); + + /* Set the countdown value */ + co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); + + /* Start the timer */ + co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); + + /* Enable (unmask) the timer interrupt */ + co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); + + /* + * Zero return means the generic timer setup code will set up + * the standard vector: + */ + return 0; +} + +static int __init visws_pre_intr_init_quirk(void) +{ + init_VISWS_APIC_irqs(); + + /* + * We dont want ISA irqs to be set up by the generic code: + */ + return 1; +} + +/* Quirk for machine specific memory setup. */ + +#define MB (1024 * 1024) + +unsigned long sgivwfb_mem_phys; +unsigned long sgivwfb_mem_size; +EXPORT_SYMBOL(sgivwfb_mem_phys); +EXPORT_SYMBOL(sgivwfb_mem_size); + +long long mem_size __initdata = 0; + +static char * __init visws_memory_setup_quirk(void) +{ + long long gfx_mem_size = 8 * MB; + + mem_size = boot_params.alt_mem_k; + + if (!mem_size) { + printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); + mem_size = 128 * MB; + } + + /* + * this hardcodes the graphics memory to 8 MB + * it really should be sized dynamically (or at least + * set as a boot param) + */ + if (!sgivwfb_mem_size) { + printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); + sgivwfb_mem_size = 8 * MB; + } + + /* + * Trim to nearest MB + */ + sgivwfb_mem_size &= ~((1 << 20) - 1); + sgivwfb_mem_phys = mem_size - gfx_mem_size; + + e820_add_region(0, LOWMEMSIZE(), E820_RAM); + e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); + e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); + + return "PROM"; +} + +static void visws_machine_emergency_restart(void) +{ + /* + * Visual Workstations restart after this + * register is poked on the PIIX4 + */ + outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); +} + +static void visws_machine_power_off(void) +{ + unsigned short pm_status; +/* extern unsigned int pci_bus0; */ + + while ((pm_status = inw(PMSTS_PORT)) & 0x100) + outw(pm_status, PMSTS_PORT); + + outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); + + mdelay(10); + +#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ + (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) + +/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ + outl(PIIX_SPECIAL_STOP, 0xCFC); +} + +extern int visws_trap_init_quirk(void); + +void __init visws_early_detect(void) +{ + int raw; + + visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) + >> PIIX_GPI_BD_SHIFT; + + if (visws_board_type < 0) + return; + + /* + * Install special quirks for timer, interrupt and memory setup: + */ + arch_time_init_quirk = visws_time_init_quirk; + arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; + arch_memory_setup_quirk = visws_memory_setup_quirk; + + /* + * Fall back to generic behavior for traps: + */ + arch_intr_init_quirk = NULL; + arch_trap_init_quirk = visws_trap_init_quirk; + + /* + * Install reboot quirks: + */ + pm_power_off = visws_machine_power_off; + machine_ops.emergency_restart = visws_machine_emergency_restart; + + /* + * Do not use broadcast IPIs: + */ + no_broadcast = 0; + + /* + * Get Board rev. + * First, we have to initialize the 307 part to allow us access + * to the GPIO registers. Let's map them at 0x0fc0 which is right + * after the PIIX4 PM section. + */ + outb_p(SIO_DEV_SEL, SIO_INDEX); + outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ + + outb_p(SIO_DEV_MSB, SIO_INDEX); + outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ + + outb_p(SIO_DEV_LSB, SIO_INDEX); + outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ + + outb_p(SIO_DEV_ENB, SIO_INDEX); + outb_p(1, SIO_DATA); /* Enable GPIO registers. */ + + /* + * Now, we have to map the power management section to write + * a bit which enables access to the GPIO registers. + * What lunatic came up with this shit? + */ + outb_p(SIO_DEV_SEL, SIO_INDEX); + outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ + + outb_p(SIO_DEV_MSB, SIO_INDEX); + outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ + + outb_p(SIO_DEV_LSB, SIO_INDEX); + outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ + + outb_p(SIO_DEV_ENB, SIO_INDEX); + outb_p(1, SIO_DATA); /* Enable PM registers. */ + + /* + * Now, write the PM register which enables the GPIO registers. + */ + outb_p(SIO_PM_FER2, SIO_PM_INDEX); + outb_p(SIO_PM_GP_EN, SIO_PM_DATA); + + /* + * Now, initialize the GPIO registers. + * We want them all to be inputs which is the + * power on default, so let's leave them alone. + * So, let's just read the board rev! + */ + raw = inb_p(SIO_GP_DATA1); + raw &= 0x7f; /* 7 bits of valid board revision ID. */ + + if (visws_board_type == VISWS_320) { + if (raw < 0x6) { + visws_board_rev = 4; + } else if (raw < 0xc) { + visws_board_rev = 5; + } else { + visws_board_rev = 6; + } + } else if (visws_board_type == VISWS_540) { + visws_board_rev = 2; + } else { + visws_board_rev = raw; + } + + printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", + (visws_board_type == VISWS_320 ? "320" : + (visws_board_type == VISWS_540 ? "540" : + "unknown")), visws_board_rev); +} diff --git a/arch/x86/mach-visws/traps.c b/arch/x86/mach-visws/traps.c index dd1f5fa..8a160ec 100644 --- a/arch/x86/mach-visws/traps.c +++ b/arch/x86/mach-visws/traps.c @@ -62,8 +62,10 @@ static __init void cobalt_init(void) co_apic_read(CO_APIC_ID)); } -void __init trap_init_hook_dontuse(void) +int __init visws_trap_init_quirk(void) { lithium_init(); cobalt_init(); + + return 1; } diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c index 8b1cd8e..d8b2cfd 100644 --- a/arch/x86/mach-visws/visws_apic.c +++ b/arch/x86/mach-visws/visws_apic.c @@ -25,9 +25,6 @@ #include "cobalt.h" -char visws_board_type = -1; -char visws_board_rev = -1; - static DEFINE_SPINLOCK(cobalt_lock); /* diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index fa0164d..c03c209 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -11,7 +11,7 @@ pci-y += legacy.o irq.o # Careful: VISWS overrule the pci-y above. The colons are # therefor correct. This needs a proper fix by distangling the code. -#pci-$(CONFIG_X86_VISWS) := visws.o irq.o fixup.o +pci-$(CONFIG_X86_VISWS) += visws.o pci-$(CONFIG_X86_NUMAQ) += numa.o diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 343ccf6..2e02221 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -107,7 +107,11 @@ static int __init pci_visws_init(void) static __init int pci_subsys_init(void) { + return -1; + pci_visws_init(); pcibios_init(); + + return 0; } subsys_initcall(pci_subsys_init); diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 3452cf5..4d1ce2e 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_PPC) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o -#obj-$(CONFIG_X86_VISWS) += setup-irq.o +obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o # -- cgit v0.10.2 From 5ab74722a4656612d1f3b087b1afd91133ec0eeb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 14:42:03 +0200 Subject: x86, VisWS: turn into generic arch, use generic mpparse code Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5198a08..c8cb800 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -238,7 +238,7 @@ if ACPI config X86_MPPARSE def_bool y bool "Enable MPS table" - depends on X86_LOCAL_APIC && !X86_VISWS + depends on X86_LOCAL_APIC help For old smp systems that do not have proper acpi support. Newer systems (esp with 64bit cpus) with acpi support, MADT and DSDT will override it @@ -247,7 +247,7 @@ endif if !ACPI config X86_MPPARSE def_bool y - depends on X86_LOCAL_APIC && !X86_VISWS + depends on X86_LOCAL_APIC endif choice diff --git a/arch/x86/mach-visws/Makefile b/arch/x86/mach-visws/Makefile index 35a4c10..7469df1 100644 --- a/arch/x86/mach-visws/Makefile +++ b/arch/x86/mach-visws/Makefile @@ -5,4 +5,3 @@ obj-y := setup.o setup_visws.o traps.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o -obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o diff --git a/arch/x86/mach-visws/mpparse.c b/arch/x86/mach-visws/mpparse.c deleted file mode 100644 index a2fb78c..0000000 --- a/arch/x86/mach-visws/mpparse.c +++ /dev/null @@ -1,85 +0,0 @@ - -#include -#include - -#include -#include - -#include "cobalt.h" -#include "mach_apic.h" - -extern unsigned int __cpuinitdata maxcpus; - -/* - * The Visual Workstation is Intel MP compliant in the hardware - * sense, but it doesn't have a BIOS(-configuration table). - * No problem for Linux. - */ - -static void __init MP_processor_info (struct mpc_config_processor *m) -{ - int ver, logical_apicid; - physid_mask_t apic_cpus; - - if (!(m->mpc_cpuflag & CPU_ENABLED)) - return; - - logical_apicid = m->mpc_apicid; - printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", - m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); - - if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) - boot_cpu_physical_apicid = m->mpc_apicid; - - ver = m->mpc_apicver; - if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { - printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", - m->mpc_apicid, MAX_APICS); - return; - } - - apic_cpus = apicid_to_cpu_present(m->mpc_apicid); - physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); - /* - * Validate version - */ - if (ver == 0x0) { - printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " - "fixing up to 0x10. (tell your hw vendor)\n", - m->mpc_apicid); - ver = 0x10; - } - apic_version[m->mpc_apicid] = ver; -} - -void __init find_smp_config(void) -{ - struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); - unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); - - if (ncpus > CO_CPU_MAX) { - printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", - ncpus, mp); - - ncpus = CO_CPU_MAX; - } - - if (ncpus > maxcpus) - ncpus = maxcpus; - -#ifdef CONFIG_X86_LOCAL_APIC - smp_found_config = 1; -#endif - while (ncpus--) - MP_processor_info(mp++); - - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; -} - -void __init get_smp_config (void) -{ -} diff --git a/arch/x86/mach-visws/setup_visws.c b/arch/x86/mach-visws/setup_visws.c index 659777f..8401208 100644 --- a/arch/x86/mach-visws/setup_visws.c +++ b/arch/x86/mach-visws/setup_visws.c @@ -13,12 +13,17 @@ #include #include #include +#include #include #include #include "cobalt.h" #include "piix4.h" +#include "mach_apic.h" + +#include +#include char visws_board_type = -1; char visws_board_rev = -1; @@ -126,6 +131,88 @@ static void visws_machine_power_off(void) outl(PIIX_SPECIAL_STOP, 0xCFC); } +static int __init visws_get_smp_config_quirk(unsigned int early) +{ + /* + * Prevent MP-table parsing by the generic code: + */ + return 1; +} + +extern unsigned int __cpuinitdata maxcpus; + +/* + * The Visual Workstation is Intel MP compliant in the hardware + * sense, but it doesn't have a BIOS(-configuration table). + * No problem for Linux. + */ + +static void __init MP_processor_info (struct mpc_config_processor *m) +{ + int ver, logical_apicid; + physid_mask_t apic_cpus; + + if (!(m->mpc_cpuflag & CPU_ENABLED)) + return; + + logical_apicid = m->mpc_apicid; + printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", + m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) + boot_cpu_physical_apicid = m->mpc_apicid; + + ver = m->mpc_apicver; + if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { + printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", + m->mpc_apicid, MAX_APICS); + return; + } + + apic_cpus = apicid_to_cpu_present(m->mpc_apicid); + physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); + /* + * Validate version + */ + if (ver == 0x0) { + printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " + "fixing up to 0x10. (tell your hw vendor)\n", + m->mpc_apicid); + ver = 0x10; + } + apic_version[m->mpc_apicid] = ver; +} + +int __init visws_find_smp_config_quirk(unsigned int reserve) +{ + struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); + unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); + + if (ncpus > CO_CPU_MAX) { + printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", + ncpus, mp); + + ncpus = CO_CPU_MAX; + } + + if (ncpus > maxcpus) + ncpus = maxcpus; + +#ifdef CONFIG_X86_LOCAL_APIC + smp_found_config = 1; +#endif + while (ncpus--) + MP_processor_info(mp++); + + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; + + return 1; +} + extern int visws_trap_init_quirk(void); void __init visws_early_detect(void) @@ -141,21 +228,21 @@ void __init visws_early_detect(void) /* * Install special quirks for timer, interrupt and memory setup: */ - arch_time_init_quirk = visws_time_init_quirk; - arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; - arch_memory_setup_quirk = visws_memory_setup_quirk; + arch_time_init_quirk = visws_time_init_quirk; + arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; + arch_memory_setup_quirk = visws_memory_setup_quirk; /* * Fall back to generic behavior for traps: */ - arch_intr_init_quirk = NULL; - arch_trap_init_quirk = visws_trap_init_quirk; + arch_intr_init_quirk = NULL; + arch_trap_init_quirk = visws_trap_init_quirk; /* * Install reboot quirks: */ - pm_power_off = visws_machine_power_off; - machine_ops.emergency_restart = visws_machine_emergency_restart; + pm_power_off = visws_machine_power_off; + machine_ops.emergency_restart = visws_machine_emergency_restart; /* * Do not use broadcast IPIs: @@ -163,6 +250,12 @@ void __init visws_early_detect(void) no_broadcast = 0; /* + * Override generic MP-table parsing: + */ + mach_get_smp_config_quirk = visws_get_smp_config_quirk; + mach_find_smp_config_quirk = visws_find_smp_config_quirk; + + /* * Get Board rev. * First, we have to initialize the 307 part to allow us access * to the GPIO registers. Let's map them at 0x0fc0 which is right -- cgit v0.10.2 From 5548ed1135842d1993a4ba699377a8a3c65dd568 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:53:21 +0200 Subject: x86, VisWS: turn into generic arch, install proper PCI quirk Signed-off-by: Ingo Molnar diff --git a/arch/x86/mach-visws/setup_visws.c b/arch/x86/mach-visws/setup_visws.c index 8401208..bbc149f 100644 --- a/arch/x86/mach-visws/setup_visws.c +++ b/arch/x86/mach-visws/setup_visws.c @@ -28,6 +28,11 @@ char visws_board_type = -1; char visws_board_rev = -1; +int is_visws_box(void) +{ + return visws_board_type >= 0; +} + static int __init visws_time_init_quirk(void) { printk(KERN_INFO "Starting Cobalt Timer system clock\n"); diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 2e02221..9b88389 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -8,6 +8,7 @@ #include #include +#include #include "cobalt.h" #include "lithium.h" @@ -107,7 +108,11 @@ static int __init pci_visws_init(void) static __init int pci_subsys_init(void) { - return -1; + if (!is_visws_box()) + return -1; + + pcibios_enable_irq = &pci_visws_enable_irq; + pcibios_disable_irq = &pci_visws_disable_irq; pci_visws_init(); pcibios_init(); diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h index 1ad7eae..90ab222 100644 --- a/include/asm-x86/setup.h +++ b/include/asm-x86/setup.h @@ -10,8 +10,10 @@ void vsmp_init(void); #ifdef CONFIG_X86_VISWS extern void visws_early_detect(void); +extern int is_visws_box(void); #else static inline void visws_early_detect(void) { } +static inline int is_visws_box(void) { return 0; } #endif /* -- cgit v0.10.2 From 808fc878d373c338f138529c284df5f86ab3cc55 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:01:54 +0200 Subject: x86, VisWS: turn into generic arch, update asm-x86/mach-visws/mach_apic.h update asm-x86/mach-visws/mach_apic.h to the generic version. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/mach_apic.h b/include/asm-x86/mach-visws/mach_apic.h index a9ef33a..0b2cde5 100644 --- a/include/asm-x86/mach-visws/mach_apic.h +++ b/include/asm-x86/mach-visws/mach_apic.h @@ -1,31 +1,40 @@ #ifndef __ASM_MACH_APIC_H #define __ASM_MACH_APIC_H +#ifdef CONFIG_X86_LOCAL_APIC + #include #include #define APIC_DFR_VALUE (APIC_DFR_FLAT) -#define no_balance_irq (0) -#define esr_disable (0) - -#define INT_DELIVERY_MODE dest_LowestPrio -#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ - +static inline cpumask_t target_cpus(void) +{ #ifdef CONFIG_SMP - #define TARGET_CPUS cpu_online_map + return cpu_online_map; #else - #define TARGET_CPUS cpumask_of_cpu(0) + return cpumask_of_cpu(0); #endif +} -#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap) -#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map) - -static inline int apic_id_registered(void) -{ - return physid_isset(GET_APIC_ID(read_apic_id()), phys_cpu_present_map); -} +#define NO_BALANCE_IRQ (0) +#define esr_disable (0) +#ifdef CONFIG_X86_64 +#include +#define INT_DELIVERY_MODE (genapic->int_delivery_mode) +#define INT_DEST_MODE (genapic->int_dest_mode) +#define TARGET_CPUS (genapic->target_cpus()) +#define apic_id_registered (genapic->apic_id_registered) +#define init_apic_ldr (genapic->init_apic_ldr) +#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid) +#define phys_pkg_id (genapic->phys_pkg_id) +#define vector_allocation_domain (genapic->vector_allocation_domain) +extern void setup_apic_routing(void); +#else +#define INT_DELIVERY_MODE dest_LowestPrio +#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ +#define TARGET_CPUS (target_cpus()) /* * Set up the logical destination ID. * @@ -43,16 +52,56 @@ static inline void init_apic_ldr(void) apic_write_around(APIC_LDR, val); } -static inline void summit_check(char *oem, char *productid) +static inline int apic_id_registered(void) +{ + return physid_isset(GET_APIC_ID(read_apic_id()), phys_cpu_present_map); +} + +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) +{ + return cpus_addr(cpumask)[0]; +} + +static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) { + return cpuid_apic >> index_msb; } static inline void setup_apic_routing(void) { +#ifdef CONFIG_X86_IO_APIC + printk("Enabling APIC mode: %s. Using %d I/O APICs\n", + "Flat", nr_ioapics); +#endif } static inline int apicid_to_node(int logical_apicid) { +#ifdef CONFIG_SMP + return apicid_2_node[hard_smp_processor_id()]; +#else + return 0; +#endif +} +#endif + +static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return physid_isset(apicid, bitmap); +} + +static inline unsigned long check_apicid_present(int bit) +{ + return physid_isset(bit, phys_cpu_present_map); +} + +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) +{ + return phys_map; +} + +static inline int multi_timer_check(int apic, int irq) +{ return 0; } @@ -64,40 +113,29 @@ static inline int cpu_to_logical_apicid(int cpu) static inline int cpu_present_to_apicid(int mps_cpu) { - if (mps_cpu < get_physical_broadcast()) - return mps_cpu; + if (mps_cpu < NR_CPUS && cpu_present(mps_cpu)) + return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); else return BAD_APICID; } -static inline physid_mask_t apicid_to_cpu_present(int apicid) +static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) { - return physid_mask_of_physid(apicid); + return physid_mask_of_physid(phys_apicid); } -#define WAKE_SECONDARY_VIA_INIT - static inline void setup_portio_remap(void) { } -static inline void enable_apic_mode(void) -{ -} - static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) { return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); } -static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) -{ - return cpus_addr(cpumask)[0]; -} - -static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) +static inline void enable_apic_mode(void) { - return cpuid_apic >> index_msb; } +#endif /* CONFIG_X86_LOCAL_APIC */ #endif /* __ASM_MACH_APIC_H */ -- cgit v0.10.2 From d8d1bc73f0ccb60f4d6056333b8fcb3140772c21 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:04:13 +0200 Subject: x86, VisWS: turn into generic arch, eliminate include/asm-x86/mach-visws/mach_apic.h now that include/asm-x86/mach-visws/mach_apic.h equals to include/asm-x86/mach-default/mach_apic.h, simply start using the generic one. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/mach_apic.h b/include/asm-x86/mach-visws/mach_apic.h index 0b2cde5..6943e7a 100644 --- a/include/asm-x86/mach-visws/mach_apic.h +++ b/include/asm-x86/mach-visws/mach_apic.h @@ -1,141 +1 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H - -#ifdef CONFIG_X86_LOCAL_APIC - -#include -#include - -#define APIC_DFR_VALUE (APIC_DFR_FLAT) - -static inline cpumask_t target_cpus(void) -{ -#ifdef CONFIG_SMP - return cpu_online_map; -#else - return cpumask_of_cpu(0); -#endif -} - -#define NO_BALANCE_IRQ (0) -#define esr_disable (0) - -#ifdef CONFIG_X86_64 -#include -#define INT_DELIVERY_MODE (genapic->int_delivery_mode) -#define INT_DEST_MODE (genapic->int_dest_mode) -#define TARGET_CPUS (genapic->target_cpus()) -#define apic_id_registered (genapic->apic_id_registered) -#define init_apic_ldr (genapic->init_apic_ldr) -#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid) -#define phys_pkg_id (genapic->phys_pkg_id) -#define vector_allocation_domain (genapic->vector_allocation_domain) -extern void setup_apic_routing(void); -#else -#define INT_DELIVERY_MODE dest_LowestPrio -#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ -#define TARGET_CPUS (target_cpus()) -/* - * Set up the logical destination ID. - * - * Intel recommends to set DFR, LDR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ -static inline void init_apic_ldr(void) -{ - unsigned long val; - - apic_write_around(APIC_DFR, APIC_DFR_VALUE); - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); - apic_write_around(APIC_LDR, val); -} - -static inline int apic_id_registered(void) -{ - return physid_isset(GET_APIC_ID(read_apic_id()), phys_cpu_present_map); -} - -static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) -{ - return cpus_addr(cpumask)[0]; -} - -static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) -{ - return cpuid_apic >> index_msb; -} - -static inline void setup_apic_routing(void) -{ -#ifdef CONFIG_X86_IO_APIC - printk("Enabling APIC mode: %s. Using %d I/O APICs\n", - "Flat", nr_ioapics); -#endif -} - -static inline int apicid_to_node(int logical_apicid) -{ -#ifdef CONFIG_SMP - return apicid_2_node[hard_smp_processor_id()]; -#else - return 0; -#endif -} -#endif - -static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) -{ - return physid_isset(apicid, bitmap); -} - -static inline unsigned long check_apicid_present(int bit) -{ - return physid_isset(bit, phys_cpu_present_map); -} - -static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) -{ - return phys_map; -} - -static inline int multi_timer_check(int apic, int irq) -{ - return 0; -} - -/* Mapping from cpu number to logical apicid */ -static inline int cpu_to_logical_apicid(int cpu) -{ - return 1 << cpu; -} - -static inline int cpu_present_to_apicid(int mps_cpu) -{ - if (mps_cpu < NR_CPUS && cpu_present(mps_cpu)) - return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); - else - return BAD_APICID; -} - -static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) -{ - return physid_mask_of_physid(phys_apicid); -} - -static inline void setup_portio_remap(void) -{ -} - -static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) -{ - return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); -} - -static inline void enable_apic_mode(void) -{ -} - -#endif /* CONFIG_X86_LOCAL_APIC */ -#endif /* __ASM_MACH_APIC_H */ +#include "../mach-default/mach_apic.h" -- cgit v0.10.2 From 6a64b5da9bbe561fd189361812f5ed205bb55345 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:09:04 +0200 Subject: x86, VisWS: turn into generic arch, enhance include/asm-x86/mach-default/smpboot_hooks.h Allow the generic smpboot quirks code to be built with ONFIG_X86_IO_APIC disabled. This way VISWS will be able to use it as-is. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-default/smpboot_hooks.h b/include/asm-x86/mach-default/smpboot_hooks.h index b63c521..56d001b 100644 --- a/include/asm-x86/mach-default/smpboot_hooks.h +++ b/include/asm-x86/mach-default/smpboot_hooks.h @@ -3,7 +3,9 @@ static inline void smpboot_clear_io_apic_irqs(void) { +#ifdef CONFIG_X86_IO_APIC io_apic_irqs = 0; +#endif } static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) @@ -35,6 +37,7 @@ static inline void smpboot_restore_warm_reset_vector(void) static inline void __init smpboot_setup_io_apic(void) { +#ifdef CONFIG_X86_IO_APIC /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: @@ -45,9 +48,12 @@ static inline void __init smpboot_setup_io_apic(void) nr_ioapics = 0; localise_nmi_watchdog(); } +#endif } static inline void smpboot_clear_io_apic(void) { +#ifdef CONFIG_X86_IO_APIC nr_ioapics = 0; +#endif } -- cgit v0.10.2 From 244a5e2ee0ba204d66dfe4273df91c6bc65a310a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:06:07 +0200 Subject: x86, VisWS: turn into generic arch, update include/asm-x86/mach-visws/smpboot_hooks.h update include/asm-x86/mach-visws/smpboot_hooks.h to include/asm-x86/mach-default/smpboot_hooks.h (the generic version). this _should_ work, because VISWS sets skip_ioapic_setup, but it should be tested on a real VISWS to make sure. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/smpboot_hooks.h b/include/asm-x86/mach-visws/smpboot_hooks.h index c9b83e3..56d001b 100644 --- a/include/asm-x86/mach-visws/smpboot_hooks.h +++ b/include/asm-x86/mach-visws/smpboot_hooks.h @@ -1,3 +1,13 @@ +/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws + * which needs to alter them. */ + +static inline void smpboot_clear_io_apic_irqs(void) +{ +#ifdef CONFIG_X86_IO_APIC + io_apic_irqs = 0; +#endif +} + static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) { CMOS_WRITE(0xa, 0xf); @@ -9,20 +19,41 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) Dprintk("3.\n"); } -/* for visws do nothing for any of these */ - -static inline void smpboot_clear_io_apic_irqs(void) -{ -} - static inline void smpboot_restore_warm_reset_vector(void) { + /* + * Install writable page 0 entry to set BIOS data area. + */ + local_flush_tlb(); + + /* + * Paranoid: Set warm reset code and vector here back + * to default values. + */ + CMOS_WRITE(0, 0xf); + + *((volatile long *) phys_to_virt(0x467)) = 0; } -static inline void smpboot_setup_io_apic(void) +static inline void __init smpboot_setup_io_apic(void) { +#ifdef CONFIG_X86_IO_APIC + /* + * Here we can be sure that there is an IO-APIC in the system. Let's + * go and set it up: + */ + if (!skip_ioapic_setup && nr_ioapics) + setup_IO_APIC(); + else { + nr_ioapics = 0; + localise_nmi_watchdog(); + } +#endif } static inline void smpboot_clear_io_apic(void) { +#ifdef CONFIG_X86_IO_APIC + nr_ioapics = 0; +#endif } -- cgit v0.10.2 From 6649ababd52014afaca62a12aed37d797f9f865c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:10:29 +0200 Subject: x86, VisWS: turn into generic arch, eliminate include/asm-x86/mach-visws/smpboot_hooks.h now that include/asm-x86/mach-visws/smpboot_hooks.h equals to the default file in ../mach-default/smpboot_hooks.h, simply include it instead of maintaining a copy. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/smpboot_hooks.h b/include/asm-x86/mach-visws/smpboot_hooks.h index 56d001b..e4433ca 100644 --- a/include/asm-x86/mach-visws/smpboot_hooks.h +++ b/include/asm-x86/mach-visws/smpboot_hooks.h @@ -1,59 +1 @@ -/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws - * which needs to alter them. */ - -static inline void smpboot_clear_io_apic_irqs(void) -{ -#ifdef CONFIG_X86_IO_APIC - io_apic_irqs = 0; -#endif -} - -static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) -{ - CMOS_WRITE(0xa, 0xf); - local_flush_tlb(); - Dprintk("1.\n"); - *((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4; - Dprintk("2.\n"); - *((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf; - Dprintk("3.\n"); -} - -static inline void smpboot_restore_warm_reset_vector(void) -{ - /* - * Install writable page 0 entry to set BIOS data area. - */ - local_flush_tlb(); - - /* - * Paranoid: Set warm reset code and vector here back - * to default values. - */ - CMOS_WRITE(0, 0xf); - - *((volatile long *) phys_to_virt(0x467)) = 0; -} - -static inline void __init smpboot_setup_io_apic(void) -{ -#ifdef CONFIG_X86_IO_APIC - /* - * Here we can be sure that there is an IO-APIC in the system. Let's - * go and set it up: - */ - if (!skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); - else { - nr_ioapics = 0; - localise_nmi_watchdog(); - } -#endif -} - -static inline void smpboot_clear_io_apic(void) -{ -#ifdef CONFIG_X86_IO_APIC - nr_ioapics = 0; -#endif -} +#include "../mach-default/smpboot_hooks.h" -- cgit v0.10.2 From b70d9c2473ffbe327f5d7364bfbf67e94c440af8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:12:05 +0200 Subject: x86, VisWS: turn into generic arch, update asm-x86/mach-visws/mach_apicdef.h update asm-x86/mach-visws/mach_apicdef.h to the generic version. This should work fine as VISWS has a standard local APIC and thus its mach_apicdef.h copy is just an ancient version of the generic code. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/mach_apicdef.h b/include/asm-x86/mach-visws/mach_apicdef.h index 826cfa9..e4b29ba 100644 --- a/include/asm-x86/mach-visws/mach_apicdef.h +++ b/include/asm-x86/mach-visws/mach_apicdef.h @@ -1,12 +1,24 @@ #ifndef __ASM_MACH_APICDEF_H #define __ASM_MACH_APICDEF_H -#define APIC_ID_MASK (0xF<<24) +#include -static inline unsigned get_apic_id(unsigned long x) +#ifdef CONFIG_X86_64 +#define APIC_ID_MASK (0xFFu<<24) +#define GET_APIC_ID(x) (((x)>>24)&0xFFu) +#define SET_APIC_ID(x) (((x)<<24)) +#else +#define APIC_ID_MASK (0xF<<24) +static inline unsigned get_apic_id(unsigned long x) { - return (((x)>>24)&0xF); -} -#define GET_APIC_ID(x) get_apic_id(x) + unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); + if (APIC_XAPIC(ver)) + return (((x)>>24)&0xFF); + else + return (((x)>>24)&0xF); +} + +#define GET_APIC_ID(x) get_apic_id(x) +#endif #endif -- cgit v0.10.2 From 18c413e27e1585358cedc22e450847e3240006ff Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:13:41 +0200 Subject: x86, VisWS: turn into generic arch, eliminate asm-x86/mach-visws/mach_apicdef.h Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/mach_apicdef.h b/include/asm-x86/mach-visws/mach_apicdef.h index e4b29ba..42711d1 100644 --- a/include/asm-x86/mach-visws/mach_apicdef.h +++ b/include/asm-x86/mach-visws/mach_apicdef.h @@ -1,24 +1 @@ -#ifndef __ASM_MACH_APICDEF_H -#define __ASM_MACH_APICDEF_H - -#include - -#ifdef CONFIG_X86_64 -#define APIC_ID_MASK (0xFFu<<24) -#define GET_APIC_ID(x) (((x)>>24)&0xFFu) -#define SET_APIC_ID(x) (((x)<<24)) -#else -#define APIC_ID_MASK (0xF<<24) -static inline unsigned get_apic_id(unsigned long x) -{ - unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); - if (APIC_XAPIC(ver)) - return (((x)>>24)&0xFF); - else - return (((x)>>24)&0xF); -} - -#define GET_APIC_ID(x) get_apic_id(x) -#endif - -#endif +#include "../mach-default/mach_apicdef.h" -- cgit v0.10.2 From b4b86416712d79a77cdc53756751b3b91fbb7a3d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:25:21 +0200 Subject: x86, VisWS: turn into generic arch, create include/asm-x86/visws/ move the include/asm-x86/mach-visws/ VISWS specific hardware details include files into include/asm-x86/visws, to be used from generic code. No code changed. Signed-off-by: Ingo Molnar diff --git a/arch/x86/mach-visws/setup_visws.c b/arch/x86/mach-visws/setup_visws.c index bbc149f..e95e949 100644 --- a/arch/x86/mach-visws/setup_visws.c +++ b/arch/x86/mach-visws/setup_visws.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include #include @@ -18,8 +20,6 @@ #include -#include "cobalt.h" -#include "piix4.h" #include "mach_apic.h" #include diff --git a/arch/x86/mach-visws/traps.c b/arch/x86/mach-visws/traps.c index 8a160ec..e5e6492 100644 --- a/arch/x86/mach-visws/traps.c +++ b/arch/x86/mach-visws/traps.c @@ -7,10 +7,10 @@ #include #include -#include #include -#include "cobalt.h" -#include "lithium.h" +#include +#include +#include #define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4) diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c index d8b2cfd..6c02c8d 100644 --- a/arch/x86/mach-visws/visws_apic.c +++ b/arch/x86/mach-visws/visws_apic.c @@ -22,8 +22,7 @@ #include #include #include - -#include "cobalt.h" +#include static DEFINE_SPINLOCK(cobalt_lock); diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 9b88389..1a7bed4 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c @@ -9,8 +9,8 @@ #include #include -#include "cobalt.h" -#include "lithium.h" +#include +#include #include "pci.h" diff --git a/include/asm-x86/mach-visws/cobalt.h b/include/asm-x86/mach-visws/cobalt.h deleted file mode 100644 index 9952588..0000000 --- a/include/asm-x86/mach-visws/cobalt.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef __I386_SGI_COBALT_H -#define __I386_SGI_COBALT_H - -#include - -/* - * Cobalt SGI Visual Workstation system ASIC - */ - -#define CO_CPU_NUM_PHYS 0x1e00 -#define CO_CPU_TAB_PHYS (CO_CPU_NUM_PHYS + 2) - -#define CO_CPU_MAX 4 - -#define CO_CPU_PHYS 0xc2000000 -#define CO_APIC_PHYS 0xc4000000 - -/* see set_fixmap() and asm/fixmap.h */ -#define CO_CPU_VADDR (fix_to_virt(FIX_CO_CPU)) -#define CO_APIC_VADDR (fix_to_virt(FIX_CO_APIC)) - -/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */ -#define CO_CPU_REV 0x08 -#define CO_CPU_CTRL 0x10 -#define CO_CPU_STAT 0x20 -#define CO_CPU_TIMEVAL 0x30 - -/* CO_CPU_CTRL bits */ -#define CO_CTRL_TIMERUN 0x04 /* 0 == disabled */ -#define CO_CTRL_TIMEMASK 0x08 /* 0 == unmasked */ - -/* CO_CPU_STATUS bits */ -#define CO_STAT_TIMEINTR 0x02 /* (r) 1 == int pend, (w) 0 == clear */ - -/* CO_CPU_TIMEVAL value */ -#define CO_TIME_HZ 100000000 /* Cobalt core rate */ - -/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */ -#define CO_APIC_HI(n) (((n) * 0x10) + 4) -#define CO_APIC_LO(n) ((n) * 0x10) -#define CO_APIC_ID 0x0ffc - -/* CO_APIC_ID bits */ -#define CO_APIC_ENABLE 0x00000100 - -/* CO_APIC_LO bits */ -#define CO_APIC_MASK 0x00010000 /* 0 = enabled */ -#define CO_APIC_LEVEL 0x00008000 /* 0 = edge */ - -/* - * Where things are physically wired to Cobalt - * #defines with no board ___ are common to all (thus far) - */ -#define CO_APIC_IDE0 4 -#define CO_APIC_IDE1 2 /* Only on 320 */ - -#define CO_APIC_8259 12 /* serial, floppy, par-l-l */ - -/* Lithium PCI Bridge A -- "the one with 82557 Ethernet" */ -#define CO_APIC_PCIA_BASE0 0 /* and 1 */ /* slot 0, line 0 */ -#define CO_APIC_PCIA_BASE123 5 /* and 6 */ /* slot 0, line 1 */ - -#define CO_APIC_PIIX4_USB 7 /* this one is weird */ - -/* Lithium PCI Bridge B -- "the one with PIIX4" */ -#define CO_APIC_PCIB_BASE0 8 /* and 9-12 *//* slot 0, line 0 */ -#define CO_APIC_PCIB_BASE123 13 /* 14.15 */ /* slot 0, line 1 */ - -#define CO_APIC_VIDOUT0 16 -#define CO_APIC_VIDOUT1 17 -#define CO_APIC_VIDIN0 18 -#define CO_APIC_VIDIN1 19 - -#define CO_APIC_LI_AUDIO 22 - -#define CO_APIC_AS 24 -#define CO_APIC_RE 25 - -#define CO_APIC_CPU 28 /* Timer and Cache interrupt */ -#define CO_APIC_NMI 29 -#define CO_APIC_LAST CO_APIC_NMI - -/* - * This is how irqs are assigned on the Visual Workstation. - * Legacy devices get irq's 1-15 (system clock is 0 and is CO_APIC_CPU). - * All other devices (including PCI) go to Cobalt and are irq's 16 on up. - */ -#define CO_IRQ_APIC0 16 /* irq of apic entry 0 */ -#define IS_CO_APIC(irq) ((irq) >= CO_IRQ_APIC0) -#define CO_IRQ(apic) (CO_IRQ_APIC0 + (apic)) /* apic ent to irq */ -#define CO_APIC(irq) ((irq) - CO_IRQ_APIC0) /* irq to apic ent */ -#define CO_IRQ_IDE0 14 /* knowledge of... */ -#define CO_IRQ_IDE1 15 /* ... ide driver defaults! */ -#define CO_IRQ_8259 CO_IRQ(CO_APIC_8259) - -#ifdef CONFIG_X86_VISWS_APIC -static inline void co_cpu_write(unsigned long reg, unsigned long v) -{ - *((volatile unsigned long *)(CO_CPU_VADDR+reg))=v; -} - -static inline unsigned long co_cpu_read(unsigned long reg) -{ - return *((volatile unsigned long *)(CO_CPU_VADDR+reg)); -} - -static inline void co_apic_write(unsigned long reg, unsigned long v) -{ - *((volatile unsigned long *)(CO_APIC_VADDR+reg))=v; -} - -static inline unsigned long co_apic_read(unsigned long reg) -{ - return *((volatile unsigned long *)(CO_APIC_VADDR+reg)); -} -#endif - -extern char visws_board_type; - -#define VISWS_320 0 -#define VISWS_540 1 - -extern char visws_board_rev; - -#endif /* __I386_SGI_COBALT_H */ diff --git a/include/asm-x86/mach-visws/lithium.h b/include/asm-x86/mach-visws/lithium.h deleted file mode 100644 index dfcd4f0..0000000 --- a/include/asm-x86/mach-visws/lithium.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __I386_SGI_LITHIUM_H -#define __I386_SGI_LITHIUM_H - -#include - -/* - * Lithium is the SGI Visual Workstation I/O ASIC - */ - -#define LI_PCI_A_PHYS 0xfc000000 /* Enet is dev 3 */ -#define LI_PCI_B_PHYS 0xfd000000 /* PIIX4 is here */ - -/* see set_fixmap() and asm/fixmap.h */ -#define LI_PCIA_VADDR (fix_to_virt(FIX_LI_PCIA)) -#define LI_PCIB_VADDR (fix_to_virt(FIX_LI_PCIB)) - -/* Not a standard PCI? (not in linux/pci.h) */ -#define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */ -#define LI_PCI_INTEN 0x46 - -/* LI_PCI_INTENT bits */ -#define LI_INTA_0 0x0001 -#define LI_INTA_1 0x0002 -#define LI_INTA_2 0x0004 -#define LI_INTA_3 0x0008 -#define LI_INTA_4 0x0010 -#define LI_INTB 0x0020 -#define LI_INTC 0x0040 -#define LI_INTD 0x0080 - -/* More special purpose macros... */ -static inline void li_pcia_write16(unsigned long reg, unsigned short v) -{ - *((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v; -} - -static inline unsigned short li_pcia_read16(unsigned long reg) -{ - return *((volatile unsigned short *)(LI_PCIA_VADDR+reg)); -} - -static inline void li_pcib_write16(unsigned long reg, unsigned short v) -{ - *((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v; -} - -static inline unsigned short li_pcib_read16(unsigned long reg) -{ - return *((volatile unsigned short *)(LI_PCIB_VADDR+reg)); -} - -#endif - diff --git a/include/asm-x86/mach-visws/piix4.h b/include/asm-x86/mach-visws/piix4.h deleted file mode 100644 index 83ea4f4..0000000 --- a/include/asm-x86/mach-visws/piix4.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef __I386_SGI_PIIX_H -#define __I386_SGI_PIIX_H - -/* - * PIIX4 as used on SGI Visual Workstations - */ - -#define PIIX_PM_START 0x0F80 - -#define SIO_GPIO_START 0x0FC0 - -#define SIO_PM_START 0x0FC8 - -#define PMBASE PIIX_PM_START -#define GPIREG0 (PMBASE+0x30) -#define GPIREG(x) (GPIREG0+((x)/8)) -#define GPIBIT(x) (1 << ((x)%8)) - -#define PIIX_GPI_BD_ID1 18 -#define PIIX_GPI_BD_ID2 19 -#define PIIX_GPI_BD_ID3 20 -#define PIIX_GPI_BD_ID4 21 -#define PIIX_GPI_BD_REG GPIREG(PIIX_GPI_BD_ID1) -#define PIIX_GPI_BD_MASK (GPIBIT(PIIX_GPI_BD_ID1) | \ - GPIBIT(PIIX_GPI_BD_ID2) | \ - GPIBIT(PIIX_GPI_BD_ID3) | \ - GPIBIT(PIIX_GPI_BD_ID4) ) - -#define PIIX_GPI_BD_SHIFT (PIIX_GPI_BD_ID1 % 8) - -#define SIO_INDEX 0x2e -#define SIO_DATA 0x2f - -#define SIO_DEV_SEL 0x7 -#define SIO_DEV_ENB 0x30 -#define SIO_DEV_MSB 0x60 -#define SIO_DEV_LSB 0x61 - -#define SIO_GP_DEV 0x7 - -#define SIO_GP_BASE SIO_GPIO_START -#define SIO_GP_MSB (SIO_GP_BASE>>8) -#define SIO_GP_LSB (SIO_GP_BASE&0xff) - -#define SIO_GP_DATA1 (SIO_GP_BASE+0) - -#define SIO_PM_DEV 0x8 - -#define SIO_PM_BASE SIO_PM_START -#define SIO_PM_MSB (SIO_PM_BASE>>8) -#define SIO_PM_LSB (SIO_PM_BASE&0xff) -#define SIO_PM_INDEX (SIO_PM_BASE+0) -#define SIO_PM_DATA (SIO_PM_BASE+1) - -#define SIO_PM_FER2 0x1 - -#define SIO_PM_GP_EN 0x80 - - - -/* - * This is the dev/reg where generating a config cycle will - * result in a PCI special cycle. - */ -#define SPECIAL_DEV 0xff -#define SPECIAL_REG 0x00 - -/* - * PIIX4 needs to see a special cycle with the following data - * to be convinced the processor has gone into the stop grant - * state. PIIX4 insists on seeing this before it will power - * down a system. - */ -#define PIIX_SPECIAL_STOP 0x00120002 - -#define PIIX4_RESET_PORT 0xcf9 -#define PIIX4_RESET_VAL 0x6 - -#define PMSTS_PORT 0xf80 // 2 bytes PM Status -#define PMEN_PORT 0xf82 // 2 bytes PM Enable -#define PMCNTRL_PORT 0xf84 // 2 bytes PM Control - -#define PM_SUSPEND_ENABLE 0x2000 // start sequence to suspend state - -/* - * PMSTS and PMEN I/O bit definitions. - * (Bits are the same in both registers) - */ -#define PM_STS_RSM (1<<15) // Resume Status -#define PM_STS_PWRBTNOR (1<<11) // Power Button Override -#define PM_STS_RTC (1<<10) // RTC status -#define PM_STS_PWRBTN (1<<8) // Power Button Pressed? -#define PM_STS_GBL (1<<5) // Global Status -#define PM_STS_BM (1<<4) // Bus Master Status -#define PM_STS_TMROF (1<<0) // Timer Overflow Status. - -/* - * Stop clock GPI register - */ -#define PIIX_GPIREG0 (0xf80 + 0x30) - -/* - * Stop clock GPI bit in GPIREG0 - */ -#define PIIX_GPI_STPCLK 0x4 // STPCLK signal routed back in - -#endif diff --git a/include/asm-x86/visws/cobalt.h b/include/asm-x86/visws/cobalt.h new file mode 100644 index 0000000..9952588 --- /dev/null +++ b/include/asm-x86/visws/cobalt.h @@ -0,0 +1,125 @@ +#ifndef __I386_SGI_COBALT_H +#define __I386_SGI_COBALT_H + +#include + +/* + * Cobalt SGI Visual Workstation system ASIC + */ + +#define CO_CPU_NUM_PHYS 0x1e00 +#define CO_CPU_TAB_PHYS (CO_CPU_NUM_PHYS + 2) + +#define CO_CPU_MAX 4 + +#define CO_CPU_PHYS 0xc2000000 +#define CO_APIC_PHYS 0xc4000000 + +/* see set_fixmap() and asm/fixmap.h */ +#define CO_CPU_VADDR (fix_to_virt(FIX_CO_CPU)) +#define CO_APIC_VADDR (fix_to_virt(FIX_CO_APIC)) + +/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */ +#define CO_CPU_REV 0x08 +#define CO_CPU_CTRL 0x10 +#define CO_CPU_STAT 0x20 +#define CO_CPU_TIMEVAL 0x30 + +/* CO_CPU_CTRL bits */ +#define CO_CTRL_TIMERUN 0x04 /* 0 == disabled */ +#define CO_CTRL_TIMEMASK 0x08 /* 0 == unmasked */ + +/* CO_CPU_STATUS bits */ +#define CO_STAT_TIMEINTR 0x02 /* (r) 1 == int pend, (w) 0 == clear */ + +/* CO_CPU_TIMEVAL value */ +#define CO_TIME_HZ 100000000 /* Cobalt core rate */ + +/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */ +#define CO_APIC_HI(n) (((n) * 0x10) + 4) +#define CO_APIC_LO(n) ((n) * 0x10) +#define CO_APIC_ID 0x0ffc + +/* CO_APIC_ID bits */ +#define CO_APIC_ENABLE 0x00000100 + +/* CO_APIC_LO bits */ +#define CO_APIC_MASK 0x00010000 /* 0 = enabled */ +#define CO_APIC_LEVEL 0x00008000 /* 0 = edge */ + +/* + * Where things are physically wired to Cobalt + * #defines with no board ___ are common to all (thus far) + */ +#define CO_APIC_IDE0 4 +#define CO_APIC_IDE1 2 /* Only on 320 */ + +#define CO_APIC_8259 12 /* serial, floppy, par-l-l */ + +/* Lithium PCI Bridge A -- "the one with 82557 Ethernet" */ +#define CO_APIC_PCIA_BASE0 0 /* and 1 */ /* slot 0, line 0 */ +#define CO_APIC_PCIA_BASE123 5 /* and 6 */ /* slot 0, line 1 */ + +#define CO_APIC_PIIX4_USB 7 /* this one is weird */ + +/* Lithium PCI Bridge B -- "the one with PIIX4" */ +#define CO_APIC_PCIB_BASE0 8 /* and 9-12 *//* slot 0, line 0 */ +#define CO_APIC_PCIB_BASE123 13 /* 14.15 */ /* slot 0, line 1 */ + +#define CO_APIC_VIDOUT0 16 +#define CO_APIC_VIDOUT1 17 +#define CO_APIC_VIDIN0 18 +#define CO_APIC_VIDIN1 19 + +#define CO_APIC_LI_AUDIO 22 + +#define CO_APIC_AS 24 +#define CO_APIC_RE 25 + +#define CO_APIC_CPU 28 /* Timer and Cache interrupt */ +#define CO_APIC_NMI 29 +#define CO_APIC_LAST CO_APIC_NMI + +/* + * This is how irqs are assigned on the Visual Workstation. + * Legacy devices get irq's 1-15 (system clock is 0 and is CO_APIC_CPU). + * All other devices (including PCI) go to Cobalt and are irq's 16 on up. + */ +#define CO_IRQ_APIC0 16 /* irq of apic entry 0 */ +#define IS_CO_APIC(irq) ((irq) >= CO_IRQ_APIC0) +#define CO_IRQ(apic) (CO_IRQ_APIC0 + (apic)) /* apic ent to irq */ +#define CO_APIC(irq) ((irq) - CO_IRQ_APIC0) /* irq to apic ent */ +#define CO_IRQ_IDE0 14 /* knowledge of... */ +#define CO_IRQ_IDE1 15 /* ... ide driver defaults! */ +#define CO_IRQ_8259 CO_IRQ(CO_APIC_8259) + +#ifdef CONFIG_X86_VISWS_APIC +static inline void co_cpu_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(CO_CPU_VADDR+reg))=v; +} + +static inline unsigned long co_cpu_read(unsigned long reg) +{ + return *((volatile unsigned long *)(CO_CPU_VADDR+reg)); +} + +static inline void co_apic_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(CO_APIC_VADDR+reg))=v; +} + +static inline unsigned long co_apic_read(unsigned long reg) +{ + return *((volatile unsigned long *)(CO_APIC_VADDR+reg)); +} +#endif + +extern char visws_board_type; + +#define VISWS_320 0 +#define VISWS_540 1 + +extern char visws_board_rev; + +#endif /* __I386_SGI_COBALT_H */ diff --git a/include/asm-x86/visws/lithium.h b/include/asm-x86/visws/lithium.h new file mode 100644 index 0000000..dfcd4f0 --- /dev/null +++ b/include/asm-x86/visws/lithium.h @@ -0,0 +1,53 @@ +#ifndef __I386_SGI_LITHIUM_H +#define __I386_SGI_LITHIUM_H + +#include + +/* + * Lithium is the SGI Visual Workstation I/O ASIC + */ + +#define LI_PCI_A_PHYS 0xfc000000 /* Enet is dev 3 */ +#define LI_PCI_B_PHYS 0xfd000000 /* PIIX4 is here */ + +/* see set_fixmap() and asm/fixmap.h */ +#define LI_PCIA_VADDR (fix_to_virt(FIX_LI_PCIA)) +#define LI_PCIB_VADDR (fix_to_virt(FIX_LI_PCIB)) + +/* Not a standard PCI? (not in linux/pci.h) */ +#define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */ +#define LI_PCI_INTEN 0x46 + +/* LI_PCI_INTENT bits */ +#define LI_INTA_0 0x0001 +#define LI_INTA_1 0x0002 +#define LI_INTA_2 0x0004 +#define LI_INTA_3 0x0008 +#define LI_INTA_4 0x0010 +#define LI_INTB 0x0020 +#define LI_INTC 0x0040 +#define LI_INTD 0x0080 + +/* More special purpose macros... */ +static inline void li_pcia_write16(unsigned long reg, unsigned short v) +{ + *((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v; +} + +static inline unsigned short li_pcia_read16(unsigned long reg) +{ + return *((volatile unsigned short *)(LI_PCIA_VADDR+reg)); +} + +static inline void li_pcib_write16(unsigned long reg, unsigned short v) +{ + *((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v; +} + +static inline unsigned short li_pcib_read16(unsigned long reg) +{ + return *((volatile unsigned short *)(LI_PCIB_VADDR+reg)); +} + +#endif + diff --git a/include/asm-x86/visws/piix4.h b/include/asm-x86/visws/piix4.h new file mode 100644 index 0000000..83ea4f4 --- /dev/null +++ b/include/asm-x86/visws/piix4.h @@ -0,0 +1,107 @@ +#ifndef __I386_SGI_PIIX_H +#define __I386_SGI_PIIX_H + +/* + * PIIX4 as used on SGI Visual Workstations + */ + +#define PIIX_PM_START 0x0F80 + +#define SIO_GPIO_START 0x0FC0 + +#define SIO_PM_START 0x0FC8 + +#define PMBASE PIIX_PM_START +#define GPIREG0 (PMBASE+0x30) +#define GPIREG(x) (GPIREG0+((x)/8)) +#define GPIBIT(x) (1 << ((x)%8)) + +#define PIIX_GPI_BD_ID1 18 +#define PIIX_GPI_BD_ID2 19 +#define PIIX_GPI_BD_ID3 20 +#define PIIX_GPI_BD_ID4 21 +#define PIIX_GPI_BD_REG GPIREG(PIIX_GPI_BD_ID1) +#define PIIX_GPI_BD_MASK (GPIBIT(PIIX_GPI_BD_ID1) | \ + GPIBIT(PIIX_GPI_BD_ID2) | \ + GPIBIT(PIIX_GPI_BD_ID3) | \ + GPIBIT(PIIX_GPI_BD_ID4) ) + +#define PIIX_GPI_BD_SHIFT (PIIX_GPI_BD_ID1 % 8) + +#define SIO_INDEX 0x2e +#define SIO_DATA 0x2f + +#define SIO_DEV_SEL 0x7 +#define SIO_DEV_ENB 0x30 +#define SIO_DEV_MSB 0x60 +#define SIO_DEV_LSB 0x61 + +#define SIO_GP_DEV 0x7 + +#define SIO_GP_BASE SIO_GPIO_START +#define SIO_GP_MSB (SIO_GP_BASE>>8) +#define SIO_GP_LSB (SIO_GP_BASE&0xff) + +#define SIO_GP_DATA1 (SIO_GP_BASE+0) + +#define SIO_PM_DEV 0x8 + +#define SIO_PM_BASE SIO_PM_START +#define SIO_PM_MSB (SIO_PM_BASE>>8) +#define SIO_PM_LSB (SIO_PM_BASE&0xff) +#define SIO_PM_INDEX (SIO_PM_BASE+0) +#define SIO_PM_DATA (SIO_PM_BASE+1) + +#define SIO_PM_FER2 0x1 + +#define SIO_PM_GP_EN 0x80 + + + +/* + * This is the dev/reg where generating a config cycle will + * result in a PCI special cycle. + */ +#define SPECIAL_DEV 0xff +#define SPECIAL_REG 0x00 + +/* + * PIIX4 needs to see a special cycle with the following data + * to be convinced the processor has gone into the stop grant + * state. PIIX4 insists on seeing this before it will power + * down a system. + */ +#define PIIX_SPECIAL_STOP 0x00120002 + +#define PIIX4_RESET_PORT 0xcf9 +#define PIIX4_RESET_VAL 0x6 + +#define PMSTS_PORT 0xf80 // 2 bytes PM Status +#define PMEN_PORT 0xf82 // 2 bytes PM Enable +#define PMCNTRL_PORT 0xf84 // 2 bytes PM Control + +#define PM_SUSPEND_ENABLE 0x2000 // start sequence to suspend state + +/* + * PMSTS and PMEN I/O bit definitions. + * (Bits are the same in both registers) + */ +#define PM_STS_RSM (1<<15) // Resume Status +#define PM_STS_PWRBTNOR (1<<11) // Power Button Override +#define PM_STS_RTC (1<<10) // RTC status +#define PM_STS_PWRBTN (1<<8) // Power Button Pressed? +#define PM_STS_GBL (1<<5) // Global Status +#define PM_STS_BM (1<<4) // Bus Master Status +#define PM_STS_TMROF (1<<0) // Timer Overflow Status. + +/* + * Stop clock GPI register + */ +#define PIIX_GPIREG0 (0xf80 + 0x30) + +/* + * Stop clock GPI bit in GPIREG0 + */ +#define PIIX_GPI_STPCLK 0x4 // STPCLK signal routed back in + +#endif -- cgit v0.10.2 From efd746b8892d1d40c43c3d518b3bde9e56238ce8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:31:35 +0200 Subject: x86, VisWS: turn into generic arch, move definitions move the SGIVW definitions from setup_arch.h into its own header file. preparation for turning VISWS into a generic PC architecture. Signed-off-by: Ingo Molnar diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 4fb1624..f5252c2 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -21,8 +21,7 @@ #include #include - -#include +#include #define INCLUDE_TIMING_TABLE_DATA #define DBE_REG_BASE par->regs diff --git a/include/asm-x86/mach-visws/setup_arch.h b/include/asm-x86/mach-visws/setup_arch.h index b8f5dd8..ba70471 100644 --- a/include/asm-x86/mach-visws/setup_arch.h +++ b/include/asm-x86/mach-visws/setup_arch.h @@ -1,6 +1,3 @@ /* Hook to call BIOS initialisation function */ -extern unsigned long sgivwfb_mem_phys; -extern unsigned long sgivwfb_mem_size; - /* no action for visws */ diff --git a/include/asm-x86/visws/sgivw.h b/include/asm-x86/visws/sgivw.h new file mode 100644 index 0000000..5fbf63e --- /dev/null +++ b/include/asm-x86/visws/sgivw.h @@ -0,0 +1,5 @@ +/* + * Frame buffer position and size: + */ +extern unsigned long sgivwfb_mem_phys; +extern unsigned long sgivwfb_mem_size; -- cgit v0.10.2 From 4191894b68a85bd8da935fb9ac4c882a1fa8651c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:33:49 +0200 Subject: x86, VisWS: turn into generic arch, eliminate include/asm-x86/mach-visws/setup_arch.h use the generic version of setup_arch.h - it's the same. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/mach-visws/setup_arch.h b/include/asm-x86/mach-visws/setup_arch.h index ba70471..fa4766c 100644 --- a/include/asm-x86/mach-visws/setup_arch.h +++ b/include/asm-x86/mach-visws/setup_arch.h @@ -1,3 +1 @@ -/* Hook to call BIOS initialisation function */ - -/* no action for visws */ +#include "../mach-default/setup_arch.h" -- cgit v0.10.2 From 8bfaba873f0cc81c1747d6787f2721926192a3dc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:42:50 +0200 Subject: x86, VisWS: turn into generic arch, add NR_IRQS quirk NR_IRQS: let VISWS be just a sub-case of the generic code. This can create a somewhat larger irq_desc[] array if NR_CPUS is high but that should not worry VisWS which has 4 CPUs at most. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/irq_vectors.h b/include/asm-x86/irq_vectors.h index b58581e..0ac864e 100644 --- a/include/asm-x86/irq_vectors.h +++ b/include/asm-x86/irq_vectors.h @@ -107,9 +107,9 @@ #define LAST_VM86_IRQ 15 #define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15) -#if !defined(CONFIG_X86_VISWS) && !defined(CONFIG_X86_VOYAGER) +#if !defined(CONFIG_X86_VOYAGER) -# if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) +# if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS) # define NR_IRQS 224 -- cgit v0.10.2 From 078c0bba55b3dc751881d40cf170c002eafc048d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:48:48 +0200 Subject: x86, VisWS: turn into generic arch, add early quirks to default architectures add early quirk support to the generic architecture code. this allows VISWS to be supported by the generic code and allows us to remove the VISWS subarch. Signed-off-by: Ingo Molnar diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c index 2f5e277..b8054c3 100644 --- a/arch/x86/mach-default/setup.c +++ b/arch/x86/mach-default/setup.c @@ -10,6 +10,14 @@ #include #include +/* + * Any quirks to be performed to initialize timers/irqs/etc? + */ +int (*arch_time_init_quirk)(void); +int (*arch_pre_intr_init_quirk)(void); +int (*arch_intr_init_quirk)(void); +int (*arch_trap_init_quirk)(void); + #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) #else @@ -29,6 +37,10 @@ int no_broadcast=DEFAULT_SEND_IPI; **/ void __init pre_intr_init_hook(void) { + if (arch_pre_intr_init_quirk) { + if (arch_pre_intr_init_quirk()) + return; + } init_ISA_irqs(); } @@ -52,6 +64,10 @@ static struct irqaction irq2 = { **/ void __init intr_init_hook(void) { + if (arch_intr_init_quirk) { + if (arch_intr_init_quirk()) + return; + } #ifdef CONFIG_X86_LOCAL_APIC apic_intr_init(); #endif @@ -81,6 +97,10 @@ void __init pre_setup_arch_hook(void) **/ void __init trap_init_hook(void) { + if (arch_trap_init_quirk) { + if (arch_trap_init_quirk()) + return; + } } static struct irqaction irq0 = { @@ -99,6 +119,16 @@ static struct irqaction irq0 = { **/ void __init time_init_hook(void) { + if (arch_time_init_quirk) { + /* + * A nonzero return code does not mean failure, it means + * that the architecture quirk does not want any + * generic (timer) setup to be performed after this: + */ + if (arch_time_init_quirk()) + return; + } + irq0.mask = cpumask_of_cpu(0); setup_irq(0, &irq0); } -- cgit v0.10.2 From 652536367b727251bfeba72189a17a040accbc2d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:50:37 +0200 Subject: x86, VisWS: turn into generic arch, copy visws files copy arch/x86/mach-visws/setup_visws.c, apic_visws.c and traps_visws.c files to arch/x86/kernel/, in preparation of the switchover to a non-subarch setup for VISWS. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/apic_visws.c b/arch/x86/kernel/apic_visws.c new file mode 100644 index 0000000..6c02c8d --- /dev/null +++ b/arch/x86/kernel/apic_visws.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 1999 Bent Hagemark, Ingo Molnar + * + * SGI Visual Workstation interrupt controller + * + * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC + * which serves as the main interrupt controller in the system. Non-legacy + * hardware in the system uses this controller directly. Legacy devices + * are connected to the PIIX4 which in turn has its 8259(s) connected to + * a of the Cobalt APIC entry. + * + * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com + * + * 25/11/2002 - Updated for 2.5 by Andrey Panin + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(cobalt_lock); + +/* + * Set the given Cobalt APIC Redirection Table entry to point + * to the given IDT vector/index. + */ +static inline void co_apic_set(int entry, int irq) +{ + co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR)); + co_apic_write(CO_APIC_HI(entry), 0); +} + +/* + * Cobalt (IO)-APIC functions to handle PCI devices. + */ +static inline int co_apic_ide0_hack(void) +{ + extern char visws_board_type; + extern char visws_board_rev; + + if (visws_board_type == VISWS_320 && visws_board_rev == 5) + return 5; + return CO_APIC_IDE0; +} + +static int is_co_apic(unsigned int irq) +{ + if (IS_CO_APIC(irq)) + return CO_APIC(irq); + + switch (irq) { + case 0: return CO_APIC_CPU; + case CO_IRQ_IDE0: return co_apic_ide0_hack(); + case CO_IRQ_IDE1: return CO_APIC_IDE1; + default: return -1; + } +} + + +/* + * This is the SGI Cobalt (IO-)APIC: + */ + +static void enable_cobalt_irq(unsigned int irq) +{ + co_apic_set(is_co_apic(irq), irq); +} + +static void disable_cobalt_irq(unsigned int irq) +{ + int entry = is_co_apic(irq); + + co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK); + co_apic_read(CO_APIC_LO(entry)); +} + +/* + * "irq" really just serves to identify the device. Here is where we + * map this to the Cobalt APIC entry where it's physically wired. + * This is called via request_irq -> setup_irq -> irq_desc->startup() + */ +static unsigned int startup_cobalt_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) + irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); + enable_cobalt_irq(irq); + spin_unlock_irqrestore(&cobalt_lock, flags); + return 0; +} + +static void ack_cobalt_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + disable_cobalt_irq(irq); + apic_write(APIC_EOI, APIC_EIO_ACK); + spin_unlock_irqrestore(&cobalt_lock, flags); +} + +static void end_cobalt_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_cobalt_irq(irq); + spin_unlock_irqrestore(&cobalt_lock, flags); +} + +static struct irq_chip cobalt_irq_type = { + .typename = "Cobalt-APIC", + .startup = startup_cobalt_irq, + .shutdown = disable_cobalt_irq, + .enable = enable_cobalt_irq, + .disable = disable_cobalt_irq, + .ack = ack_cobalt_irq, + .end = end_cobalt_irq, +}; + + +/* + * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt + * -- not the manner expected by the code in i8259.c. + * + * there is a 'master' physical interrupt source that gets sent to + * the CPU. But in the chipset there are various 'virtual' interrupts + * waiting to be handled. We represent this to Linux through a 'master' + * interrupt controller type, and through a special virtual interrupt- + * controller. Device drivers only see the virtual interrupt sources. + */ +static unsigned int startup_piix4_master_irq(unsigned int irq) +{ + init_8259A(0); + + return startup_cobalt_irq(irq); +} + +static void end_piix4_master_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + enable_cobalt_irq(irq); + spin_unlock_irqrestore(&cobalt_lock, flags); +} + +static struct irq_chip piix4_master_irq_type = { + .typename = "PIIX4-master", + .startup = startup_piix4_master_irq, + .ack = ack_cobalt_irq, + .end = end_piix4_master_irq, +}; + + +static struct irq_chip piix4_virtual_irq_type = { + .typename = "PIIX4-virtual", + .shutdown = disable_8259A_irq, + .enable = enable_8259A_irq, + .disable = disable_8259A_irq, +}; + + +/* + * PIIX4-8259 master/virtual functions to handle interrupt requests + * from legacy devices: floppy, parallel, serial, rtc. + * + * None of these get Cobalt APIC entries, neither do they have IDT + * entries. These interrupts are purely virtual and distributed from + * the 'master' interrupt source: CO_IRQ_8259. + * + * When the 8259 interrupts its handler figures out which of these + * devices is interrupting and dispatches to its handler. + * + * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/ + * enable_irq gets the right irq. This 'master' irq is never directly + * manipulated by any driver. + */ +static irqreturn_t piix4_master_intr(int irq, void *dev_id) +{ + int realirq; + irq_desc_t *desc; + unsigned long flags; + + spin_lock_irqsave(&i8259A_lock, flags); + + /* Find out what's interrupting in the PIIX4 master 8259 */ + outb(0x0c, 0x20); /* OCW3 Poll command */ + realirq = inb(0x20); + + /* + * Bit 7 == 0 means invalid/spurious + */ + if (unlikely(!(realirq & 0x80))) + goto out_unlock; + + realirq &= 7; + + if (unlikely(realirq == 2)) { + outb(0x0c, 0xa0); + realirq = inb(0xa0); + + if (unlikely(!(realirq & 0x80))) + goto out_unlock; + + realirq = (realirq & 7) + 8; + } + + /* mask and ack interrupt */ + cached_irq_mask |= 1 << realirq; + if (unlikely(realirq > 7)) { + inb(0xa1); + outb(cached_slave_mask, 0xa1); + outb(0x60 + (realirq & 7), 0xa0); + outb(0x60 + 2, 0x20); + } else { + inb(0x21); + outb(cached_master_mask, 0x21); + outb(0x60 + realirq, 0x20); + } + + spin_unlock_irqrestore(&i8259A_lock, flags); + + desc = irq_desc + realirq; + + /* + * handle this 'virtual interrupt' as a Cobalt one now. + */ + kstat_cpu(smp_processor_id()).irqs[realirq]++; + + if (likely(desc->action != NULL)) + handle_IRQ_event(realirq, desc->action); + + if (!(desc->status & IRQ_DISABLED)) + enable_8259A_irq(realirq); + + return IRQ_HANDLED; + +out_unlock: + spin_unlock_irqrestore(&i8259A_lock, flags); + return IRQ_NONE; +} + +static struct irqaction master_action = { + .handler = piix4_master_intr, + .name = "PIIX4-8259", +}; + +static struct irqaction cascade_action = { + .handler = no_action, + .name = "cascade", +}; + + +void init_VISWS_APIC_irqs(void) +{ + int i; + + for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + + if (i == 0) { + irq_desc[i].chip = &cobalt_irq_type; + } + else if (i == CO_IRQ_IDE0) { + irq_desc[i].chip = &cobalt_irq_type; + } + else if (i == CO_IRQ_IDE1) { + irq_desc[i].chip = &cobalt_irq_type; + } + else if (i == CO_IRQ_8259) { + irq_desc[i].chip = &piix4_master_irq_type; + } + else if (i < CO_IRQ_APIC0) { + irq_desc[i].chip = &piix4_virtual_irq_type; + } + else if (IS_CO_APIC(i)) { + irq_desc[i].chip = &cobalt_irq_type; + } + } + + setup_irq(CO_IRQ_8259, &master_action); + setup_irq(2, &cascade_action); +} diff --git a/arch/x86/kernel/setup_visws.c b/arch/x86/kernel/setup_visws.c new file mode 100644 index 0000000..e95e949 --- /dev/null +++ b/arch/x86/kernel/setup_visws.c @@ -0,0 +1,331 @@ +/* + * Unmaintained SGI Visual Workstation support. + * Split out from setup.c by davej@suse.de + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mach_apic.h" + +#include +#include + +char visws_board_type = -1; +char visws_board_rev = -1; + +int is_visws_box(void) +{ + return visws_board_type >= 0; +} + +static int __init visws_time_init_quirk(void) +{ + printk(KERN_INFO "Starting Cobalt Timer system clock\n"); + + /* Set the countdown value */ + co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); + + /* Start the timer */ + co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); + + /* Enable (unmask) the timer interrupt */ + co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); + + /* + * Zero return means the generic timer setup code will set up + * the standard vector: + */ + return 0; +} + +static int __init visws_pre_intr_init_quirk(void) +{ + init_VISWS_APIC_irqs(); + + /* + * We dont want ISA irqs to be set up by the generic code: + */ + return 1; +} + +/* Quirk for machine specific memory setup. */ + +#define MB (1024 * 1024) + +unsigned long sgivwfb_mem_phys; +unsigned long sgivwfb_mem_size; +EXPORT_SYMBOL(sgivwfb_mem_phys); +EXPORT_SYMBOL(sgivwfb_mem_size); + +long long mem_size __initdata = 0; + +static char * __init visws_memory_setup_quirk(void) +{ + long long gfx_mem_size = 8 * MB; + + mem_size = boot_params.alt_mem_k; + + if (!mem_size) { + printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); + mem_size = 128 * MB; + } + + /* + * this hardcodes the graphics memory to 8 MB + * it really should be sized dynamically (or at least + * set as a boot param) + */ + if (!sgivwfb_mem_size) { + printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); + sgivwfb_mem_size = 8 * MB; + } + + /* + * Trim to nearest MB + */ + sgivwfb_mem_size &= ~((1 << 20) - 1); + sgivwfb_mem_phys = mem_size - gfx_mem_size; + + e820_add_region(0, LOWMEMSIZE(), E820_RAM); + e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); + e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); + + return "PROM"; +} + +static void visws_machine_emergency_restart(void) +{ + /* + * Visual Workstations restart after this + * register is poked on the PIIX4 + */ + outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); +} + +static void visws_machine_power_off(void) +{ + unsigned short pm_status; +/* extern unsigned int pci_bus0; */ + + while ((pm_status = inw(PMSTS_PORT)) & 0x100) + outw(pm_status, PMSTS_PORT); + + outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); + + mdelay(10); + +#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ + (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) + +/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ + outl(PIIX_SPECIAL_STOP, 0xCFC); +} + +static int __init visws_get_smp_config_quirk(unsigned int early) +{ + /* + * Prevent MP-table parsing by the generic code: + */ + return 1; +} + +extern unsigned int __cpuinitdata maxcpus; + +/* + * The Visual Workstation is Intel MP compliant in the hardware + * sense, but it doesn't have a BIOS(-configuration table). + * No problem for Linux. + */ + +static void __init MP_processor_info (struct mpc_config_processor *m) +{ + int ver, logical_apicid; + physid_mask_t apic_cpus; + + if (!(m->mpc_cpuflag & CPU_ENABLED)) + return; + + logical_apicid = m->mpc_apicid; + printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", + m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) + boot_cpu_physical_apicid = m->mpc_apicid; + + ver = m->mpc_apicver; + if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { + printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", + m->mpc_apicid, MAX_APICS); + return; + } + + apic_cpus = apicid_to_cpu_present(m->mpc_apicid); + physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); + /* + * Validate version + */ + if (ver == 0x0) { + printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " + "fixing up to 0x10. (tell your hw vendor)\n", + m->mpc_apicid); + ver = 0x10; + } + apic_version[m->mpc_apicid] = ver; +} + +int __init visws_find_smp_config_quirk(unsigned int reserve) +{ + struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); + unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); + + if (ncpus > CO_CPU_MAX) { + printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", + ncpus, mp); + + ncpus = CO_CPU_MAX; + } + + if (ncpus > maxcpus) + ncpus = maxcpus; + +#ifdef CONFIG_X86_LOCAL_APIC + smp_found_config = 1; +#endif + while (ncpus--) + MP_processor_info(mp++); + + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; + + return 1; +} + +extern int visws_trap_init_quirk(void); + +void __init visws_early_detect(void) +{ + int raw; + + visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) + >> PIIX_GPI_BD_SHIFT; + + if (visws_board_type < 0) + return; + + /* + * Install special quirks for timer, interrupt and memory setup: + */ + arch_time_init_quirk = visws_time_init_quirk; + arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; + arch_memory_setup_quirk = visws_memory_setup_quirk; + + /* + * Fall back to generic behavior for traps: + */ + arch_intr_init_quirk = NULL; + arch_trap_init_quirk = visws_trap_init_quirk; + + /* + * Install reboot quirks: + */ + pm_power_off = visws_machine_power_off; + machine_ops.emergency_restart = visws_machine_emergency_restart; + + /* + * Do not use broadcast IPIs: + */ + no_broadcast = 0; + + /* + * Override generic MP-table parsing: + */ + mach_get_smp_config_quirk = visws_get_smp_config_quirk; + mach_find_smp_config_quirk = visws_find_smp_config_quirk; + + /* + * Get Board rev. + * First, we have to initialize the 307 part to allow us access + * to the GPIO registers. Let's map them at 0x0fc0 which is right + * after the PIIX4 PM section. + */ + outb_p(SIO_DEV_SEL, SIO_INDEX); + outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ + + outb_p(SIO_DEV_MSB, SIO_INDEX); + outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ + + outb_p(SIO_DEV_LSB, SIO_INDEX); + outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ + + outb_p(SIO_DEV_ENB, SIO_INDEX); + outb_p(1, SIO_DATA); /* Enable GPIO registers. */ + + /* + * Now, we have to map the power management section to write + * a bit which enables access to the GPIO registers. + * What lunatic came up with this shit? + */ + outb_p(SIO_DEV_SEL, SIO_INDEX); + outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ + + outb_p(SIO_DEV_MSB, SIO_INDEX); + outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ + + outb_p(SIO_DEV_LSB, SIO_INDEX); + outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ + + outb_p(SIO_DEV_ENB, SIO_INDEX); + outb_p(1, SIO_DATA); /* Enable PM registers. */ + + /* + * Now, write the PM register which enables the GPIO registers. + */ + outb_p(SIO_PM_FER2, SIO_PM_INDEX); + outb_p(SIO_PM_GP_EN, SIO_PM_DATA); + + /* + * Now, initialize the GPIO registers. + * We want them all to be inputs which is the + * power on default, so let's leave them alone. + * So, let's just read the board rev! + */ + raw = inb_p(SIO_GP_DATA1); + raw &= 0x7f; /* 7 bits of valid board revision ID. */ + + if (visws_board_type == VISWS_320) { + if (raw < 0x6) { + visws_board_rev = 4; + } else if (raw < 0xc) { + visws_board_rev = 5; + } else { + visws_board_rev = 6; + } + } else if (visws_board_type == VISWS_540) { + visws_board_rev = 2; + } else { + visws_board_rev = raw; + } + + printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", + (visws_board_type == VISWS_320 ? "320" : + (visws_board_type == VISWS_540 ? "540" : + "unknown")), visws_board_rev); +} diff --git a/arch/x86/kernel/traps_visws.c b/arch/x86/kernel/traps_visws.c new file mode 100644 index 0000000..e5e6492 --- /dev/null +++ b/arch/x86/kernel/traps_visws.c @@ -0,0 +1,71 @@ +/* VISWS traps */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4) +#define BCD (LI_INTB | LI_INTC | LI_INTD) +#define ALLDEVS (A01234 | BCD) + +static __init void lithium_init(void) +{ + set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS); + set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS); + + if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || + (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { + printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); +/* panic("This machine is not SGI Visual Workstation 320/540"); */ + } + + if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || + (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { + printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); +/* panic("This machine is not SGI Visual Workstation 320/540"); */ + } + + li_pcia_write16(LI_PCI_INTEN, ALLDEVS); + li_pcib_write16(LI_PCI_INTEN, ALLDEVS); +} + +static __init void cobalt_init(void) +{ + /* + * On normal SMP PC this is used only with SMP, but we have to + * use it and set it up here to start the Cobalt clock + */ + set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); + setup_local_APIC(); + printk(KERN_INFO "Local APIC Version %#x, ID %#x\n", + (unsigned int)apic_read(APIC_LVR), + (unsigned int)apic_read(APIC_ID)); + + set_fixmap(FIX_CO_CPU, CO_CPU_PHYS); + set_fixmap(FIX_CO_APIC, CO_APIC_PHYS); + printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n", + co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID)); + + /* Enable Cobalt APIC being careful to NOT change the ID! */ + co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE); + + printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n", + co_apic_read(CO_APIC_ID)); +} + +int __init visws_trap_init_quirk(void) +{ + lithium_init(); + cobalt_init(); + + return 1; +} -- cgit v0.10.2 From 1b84e1c81f56e13c7d81b47c85eda15d94624e43 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 15:55:27 +0200 Subject: x86, VisWS: turn into generic arch, flip over VISWS to generic arch this is the big move: flip over VISWS to generic arch support. From this commit on CONFIG_X86_VISWS is just another (default-disabled) option that turns on certain quirks - no other complications. Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c8cb800..1805b24 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -232,7 +232,7 @@ config SMP config X86_FIND_SMP_CONFIG def_bool y - depends on X86_MPPARSE || X86_VOYAGER || X86_VISWS + depends on X86_MPPARSE || X86_VOYAGER if ACPI config X86_MPPARSE @@ -281,18 +281,6 @@ config X86_VOYAGER If you do not specifically know you have a Voyager based machine, say N here, otherwise the kernel you build will not be bootable. -config X86_VISWS - bool "SGI 320/540 (Visual Workstation)" - depends on X86_32 && PCI - help - The SGI Visual Workstation series is an IA32-based workstation - based on SGI systems chips with some legacy PC hardware attached. - - Say Y here to create a kernel to run on the SGI 320 or 540. - - A kernel compiled for the Visual Workstation will not run on PCs - and vice versa. See for details. - config X86_GENERICARCH bool "Generic architecture" depends on X86_32 @@ -363,6 +351,18 @@ config X86_VSMP endchoice +config X86_VISWS + bool "SGI 320/540 (Visual Workstation)" + depends on X86_32 && PCI + help + The SGI Visual Workstation series is an IA32-based workstation + based on SGI systems chips with some legacy PC hardware attached. + + Say Y here to create a kernel to run on the SGI 320 or 540. + + A kernel compiled for the Visual Workstation will run on general + PCs as well. See for details. + config SCHED_NO_NO_OMIT_FRAME_POINTER def_bool y prompt "Single-depth WCHAN output" diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b03d24b..ce04b03 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -114,8 +114,8 @@ mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/ # VISWS subarch support -mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws -mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/ +#mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws +#mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/ # generic subarchitecture mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 59b14c9..08b7561 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -19,6 +19,7 @@ obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o +obj-$(CONFIG_X86_VISWS) += setup_visws.o traps_visws.o apic_visws.o obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o -- cgit v0.10.2 From efefa6f63fe6f08c16fa28dc9391bd1b89df5274 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:09:50 +0200 Subject: x86, VisWS: turn into generic arch, clean up remove VISWS Kconfig complications, now that it's supported by the generic architecture. Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1805b24..24ff43a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -181,7 +181,7 @@ config X86_64_SMP config X86_HT bool depends on SMP - depends on (X86_32 && !(X86_VISWS || X86_VOYAGER)) || X86_64 + depends on (X86_32 && !X86_VOYAGER) || X86_64 default y config X86_BIOS_REBOOT @@ -391,7 +391,7 @@ config VMI bool "VMI Guest support" select PARAVIRT depends on X86_32 - depends on !(X86_VISWS || X86_VOYAGER) + depends on !X86_VOYAGER help VMI provides a paravirtualized interface to the VMware ESX server (it could be used by other hypervisors in theory too, but is not @@ -402,7 +402,7 @@ config KVM_CLOCK bool "KVM paravirtualized clock" select PARAVIRT select PARAVIRT_CLOCK - depends on !(X86_VISWS || X86_VOYAGER) + depends on !X86_VOYAGER help Turning on this option will allow you to run a paravirtualized clock when running over the KVM hypervisor. Instead of relying on a PIT @@ -413,7 +413,7 @@ config KVM_CLOCK config KVM_GUEST bool "KVM Guest support" select PARAVIRT - depends on !(X86_VISWS || X86_VOYAGER) + depends on !X86_VOYAGER help This option enables various optimizations for running under the KVM hypervisor. @@ -422,7 +422,7 @@ source "arch/x86/lguest/Kconfig" config PARAVIRT bool "Enable paravirtualization code" - depends on !(X86_VISWS || X86_VOYAGER) + depends on !X86_VOYAGER help This changes the kernel so it can modify itself when it is run under a hypervisor, potentially improving performance significantly @@ -628,7 +628,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on X86_32 && !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) + depends on X86_32 && !SMP && !(X86_VOYAGER || X86_GENERICARCH) help A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -653,11 +653,11 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC def_bool y - depends on X86_64 || (X86_32 && (X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH)) + depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH)) config X86_IO_APIC def_bool y - depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH)) + depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH)) config X86_VISWS_APIC def_bool y @@ -711,7 +711,7 @@ config X86_MCE_NONFATAL config X86_MCE_P4THERMAL bool "check for P4 thermal throttling interrupt." - depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP) && !X86_VISWS + depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP) help Enabling this feature will cause a message to be printed when the P4 enters thermal throttling. @@ -1414,7 +1414,7 @@ config X86_APM_BOOT menuconfig APM tristate "APM (Advanced Power Management) BIOS support" - depends on X86_32 && PM_SLEEP && !X86_VISWS + depends on X86_32 && PM_SLEEP ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with @@ -1561,7 +1561,7 @@ config PCI choice prompt "PCI access mode" - depends on X86_32 && PCI && !X86_VISWS + depends on X86_32 && PCI default PCI_GOANY ---help--- On PCI systems, the BIOS can be used to detect the PCI devices and @@ -1598,12 +1598,12 @@ endchoice config PCI_BIOS def_bool y - depends on X86_32 && !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) + depends on X86_32 && PCI && (PCI_GOBIOS || PCI_GOANY) # x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT def_bool y - depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC) || X86_VISWS) + depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC)) config PCI_MMCONFIG def_bool y @@ -1663,7 +1663,7 @@ if X86_32 config ISA bool "ISA support" - depends on !(X86_VOYAGER || X86_VISWS) + depends on !X86_VOYAGER help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -1690,7 +1690,7 @@ config EISA source "drivers/eisa/Kconfig" config MCA - bool "MCA support" if !(X86_VISWS || X86_VOYAGER) + bool "MCA support" if !X86_VOYAGER default y if X86_VOYAGER help MicroChannel Architecture is found in some IBM PS/2 machines and -- cgit v0.10.2 From 54ce7f99065cadcbb627f47f2321b76f099fda28 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:14:56 +0200 Subject: x86, VisWS: turn into generic arch, IO-APIC setup fix skip IO-APIC setup on a VISWS if it's enabled. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/setup_visws.c b/arch/x86/kernel/setup_visws.c index e95e949..e19b91c 100644 --- a/arch/x86/kernel/setup_visws.c +++ b/arch/x86/kernel/setup_visws.c @@ -260,6 +260,13 @@ void __init visws_early_detect(void) mach_get_smp_config_quirk = visws_get_smp_config_quirk; mach_find_smp_config_quirk = visws_find_smp_config_quirk; +#ifdef CONFIG_X86_IO_APIC + /* + * Turn off IO-APIC detection and initialization: + */ + skip_ioapic_setup = 1; +#endif + /* * Get Board rev. * First, we have to initialize the 307 part to allow us access -- cgit v0.10.2 From 0cecf92db84694cfed08329271e8ae6316e811eb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:20:32 +0200 Subject: x86, VisWS: turn into generic arch, clean up rename setup_visws.c to visws_quirks.c. Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 08b7561..2ef0fbd 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -19,7 +19,7 @@ obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o -obj-$(CONFIG_X86_VISWS) += setup_visws.o traps_visws.o apic_visws.o +obj-$(CONFIG_X86_VISWS) += visws_quirks.o traps_visws.o apic_visws.o obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o diff --git a/arch/x86/kernel/setup_visws.c b/arch/x86/kernel/setup_visws.c deleted file mode 100644 index e19b91c..0000000 --- a/arch/x86/kernel/setup_visws.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Unmaintained SGI Visual Workstation support. - * Split out from setup.c by davej@suse.de - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "mach_apic.h" - -#include -#include - -char visws_board_type = -1; -char visws_board_rev = -1; - -int is_visws_box(void) -{ - return visws_board_type >= 0; -} - -static int __init visws_time_init_quirk(void) -{ - printk(KERN_INFO "Starting Cobalt Timer system clock\n"); - - /* Set the countdown value */ - co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); - - /* Start the timer */ - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); - - /* Enable (unmask) the timer interrupt */ - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); - - /* - * Zero return means the generic timer setup code will set up - * the standard vector: - */ - return 0; -} - -static int __init visws_pre_intr_init_quirk(void) -{ - init_VISWS_APIC_irqs(); - - /* - * We dont want ISA irqs to be set up by the generic code: - */ - return 1; -} - -/* Quirk for machine specific memory setup. */ - -#define MB (1024 * 1024) - -unsigned long sgivwfb_mem_phys; -unsigned long sgivwfb_mem_size; -EXPORT_SYMBOL(sgivwfb_mem_phys); -EXPORT_SYMBOL(sgivwfb_mem_size); - -long long mem_size __initdata = 0; - -static char * __init visws_memory_setup_quirk(void) -{ - long long gfx_mem_size = 8 * MB; - - mem_size = boot_params.alt_mem_k; - - if (!mem_size) { - printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); - mem_size = 128 * MB; - } - - /* - * this hardcodes the graphics memory to 8 MB - * it really should be sized dynamically (or at least - * set as a boot param) - */ - if (!sgivwfb_mem_size) { - printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); - sgivwfb_mem_size = 8 * MB; - } - - /* - * Trim to nearest MB - */ - sgivwfb_mem_size &= ~((1 << 20) - 1); - sgivwfb_mem_phys = mem_size - gfx_mem_size; - - e820_add_region(0, LOWMEMSIZE(), E820_RAM); - e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); - e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); - - return "PROM"; -} - -static void visws_machine_emergency_restart(void) -{ - /* - * Visual Workstations restart after this - * register is poked on the PIIX4 - */ - outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); -} - -static void visws_machine_power_off(void) -{ - unsigned short pm_status; -/* extern unsigned int pci_bus0; */ - - while ((pm_status = inw(PMSTS_PORT)) & 0x100) - outw(pm_status, PMSTS_PORT); - - outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); - - mdelay(10); - -#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ - (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) - -/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ - outl(PIIX_SPECIAL_STOP, 0xCFC); -} - -static int __init visws_get_smp_config_quirk(unsigned int early) -{ - /* - * Prevent MP-table parsing by the generic code: - */ - return 1; -} - -extern unsigned int __cpuinitdata maxcpus; - -/* - * The Visual Workstation is Intel MP compliant in the hardware - * sense, but it doesn't have a BIOS(-configuration table). - * No problem for Linux. - */ - -static void __init MP_processor_info (struct mpc_config_processor *m) -{ - int ver, logical_apicid; - physid_mask_t apic_cpus; - - if (!(m->mpc_cpuflag & CPU_ENABLED)) - return; - - logical_apicid = m->mpc_apicid; - printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", - m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); - - if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) - boot_cpu_physical_apicid = m->mpc_apicid; - - ver = m->mpc_apicver; - if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { - printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", - m->mpc_apicid, MAX_APICS); - return; - } - - apic_cpus = apicid_to_cpu_present(m->mpc_apicid); - physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); - /* - * Validate version - */ - if (ver == 0x0) { - printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " - "fixing up to 0x10. (tell your hw vendor)\n", - m->mpc_apicid); - ver = 0x10; - } - apic_version[m->mpc_apicid] = ver; -} - -int __init visws_find_smp_config_quirk(unsigned int reserve) -{ - struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); - unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); - - if (ncpus > CO_CPU_MAX) { - printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", - ncpus, mp); - - ncpus = CO_CPU_MAX; - } - - if (ncpus > maxcpus) - ncpus = maxcpus; - -#ifdef CONFIG_X86_LOCAL_APIC - smp_found_config = 1; -#endif - while (ncpus--) - MP_processor_info(mp++); - - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - - return 1; -} - -extern int visws_trap_init_quirk(void); - -void __init visws_early_detect(void) -{ - int raw; - - visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) - >> PIIX_GPI_BD_SHIFT; - - if (visws_board_type < 0) - return; - - /* - * Install special quirks for timer, interrupt and memory setup: - */ - arch_time_init_quirk = visws_time_init_quirk; - arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; - arch_memory_setup_quirk = visws_memory_setup_quirk; - - /* - * Fall back to generic behavior for traps: - */ - arch_intr_init_quirk = NULL; - arch_trap_init_quirk = visws_trap_init_quirk; - - /* - * Install reboot quirks: - */ - pm_power_off = visws_machine_power_off; - machine_ops.emergency_restart = visws_machine_emergency_restart; - - /* - * Do not use broadcast IPIs: - */ - no_broadcast = 0; - - /* - * Override generic MP-table parsing: - */ - mach_get_smp_config_quirk = visws_get_smp_config_quirk; - mach_find_smp_config_quirk = visws_find_smp_config_quirk; - -#ifdef CONFIG_X86_IO_APIC - /* - * Turn off IO-APIC detection and initialization: - */ - skip_ioapic_setup = 1; -#endif - - /* - * Get Board rev. - * First, we have to initialize the 307 part to allow us access - * to the GPIO registers. Let's map them at 0x0fc0 which is right - * after the PIIX4 PM section. - */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ - - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ - - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ - - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable GPIO registers. */ - - /* - * Now, we have to map the power management section to write - * a bit which enables access to the GPIO registers. - * What lunatic came up with this shit? - */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ - - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ - - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ - - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable PM registers. */ - - /* - * Now, write the PM register which enables the GPIO registers. - */ - outb_p(SIO_PM_FER2, SIO_PM_INDEX); - outb_p(SIO_PM_GP_EN, SIO_PM_DATA); - - /* - * Now, initialize the GPIO registers. - * We want them all to be inputs which is the - * power on default, so let's leave them alone. - * So, let's just read the board rev! - */ - raw = inb_p(SIO_GP_DATA1); - raw &= 0x7f; /* 7 bits of valid board revision ID. */ - - if (visws_board_type == VISWS_320) { - if (raw < 0x6) { - visws_board_rev = 4; - } else if (raw < 0xc) { - visws_board_rev = 5; - } else { - visws_board_rev = 6; - } - } else if (visws_board_type == VISWS_540) { - visws_board_rev = 2; - } else { - visws_board_rev = raw; - } - - printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", - (visws_board_type == VISWS_320 ? "320" : - (visws_board_type == VISWS_540 ? "540" : - "unknown")), visws_board_rev); -} diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c new file mode 100644 index 0000000..e19b91c --- /dev/null +++ b/arch/x86/kernel/visws_quirks.c @@ -0,0 +1,338 @@ +/* + * Unmaintained SGI Visual Workstation support. + * Split out from setup.c by davej@suse.de + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mach_apic.h" + +#include +#include + +char visws_board_type = -1; +char visws_board_rev = -1; + +int is_visws_box(void) +{ + return visws_board_type >= 0; +} + +static int __init visws_time_init_quirk(void) +{ + printk(KERN_INFO "Starting Cobalt Timer system clock\n"); + + /* Set the countdown value */ + co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); + + /* Start the timer */ + co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); + + /* Enable (unmask) the timer interrupt */ + co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); + + /* + * Zero return means the generic timer setup code will set up + * the standard vector: + */ + return 0; +} + +static int __init visws_pre_intr_init_quirk(void) +{ + init_VISWS_APIC_irqs(); + + /* + * We dont want ISA irqs to be set up by the generic code: + */ + return 1; +} + +/* Quirk for machine specific memory setup. */ + +#define MB (1024 * 1024) + +unsigned long sgivwfb_mem_phys; +unsigned long sgivwfb_mem_size; +EXPORT_SYMBOL(sgivwfb_mem_phys); +EXPORT_SYMBOL(sgivwfb_mem_size); + +long long mem_size __initdata = 0; + +static char * __init visws_memory_setup_quirk(void) +{ + long long gfx_mem_size = 8 * MB; + + mem_size = boot_params.alt_mem_k; + + if (!mem_size) { + printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); + mem_size = 128 * MB; + } + + /* + * this hardcodes the graphics memory to 8 MB + * it really should be sized dynamically (or at least + * set as a boot param) + */ + if (!sgivwfb_mem_size) { + printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); + sgivwfb_mem_size = 8 * MB; + } + + /* + * Trim to nearest MB + */ + sgivwfb_mem_size &= ~((1 << 20) - 1); + sgivwfb_mem_phys = mem_size - gfx_mem_size; + + e820_add_region(0, LOWMEMSIZE(), E820_RAM); + e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); + e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); + + return "PROM"; +} + +static void visws_machine_emergency_restart(void) +{ + /* + * Visual Workstations restart after this + * register is poked on the PIIX4 + */ + outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); +} + +static void visws_machine_power_off(void) +{ + unsigned short pm_status; +/* extern unsigned int pci_bus0; */ + + while ((pm_status = inw(PMSTS_PORT)) & 0x100) + outw(pm_status, PMSTS_PORT); + + outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); + + mdelay(10); + +#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ + (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) + +/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ + outl(PIIX_SPECIAL_STOP, 0xCFC); +} + +static int __init visws_get_smp_config_quirk(unsigned int early) +{ + /* + * Prevent MP-table parsing by the generic code: + */ + return 1; +} + +extern unsigned int __cpuinitdata maxcpus; + +/* + * The Visual Workstation is Intel MP compliant in the hardware + * sense, but it doesn't have a BIOS(-configuration table). + * No problem for Linux. + */ + +static void __init MP_processor_info (struct mpc_config_processor *m) +{ + int ver, logical_apicid; + physid_mask_t apic_cpus; + + if (!(m->mpc_cpuflag & CPU_ENABLED)) + return; + + logical_apicid = m->mpc_apicid; + printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", + m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) + boot_cpu_physical_apicid = m->mpc_apicid; + + ver = m->mpc_apicver; + if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { + printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", + m->mpc_apicid, MAX_APICS); + return; + } + + apic_cpus = apicid_to_cpu_present(m->mpc_apicid); + physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); + /* + * Validate version + */ + if (ver == 0x0) { + printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " + "fixing up to 0x10. (tell your hw vendor)\n", + m->mpc_apicid); + ver = 0x10; + } + apic_version[m->mpc_apicid] = ver; +} + +int __init visws_find_smp_config_quirk(unsigned int reserve) +{ + struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); + unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); + + if (ncpus > CO_CPU_MAX) { + printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", + ncpus, mp); + + ncpus = CO_CPU_MAX; + } + + if (ncpus > maxcpus) + ncpus = maxcpus; + +#ifdef CONFIG_X86_LOCAL_APIC + smp_found_config = 1; +#endif + while (ncpus--) + MP_processor_info(mp++); + + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; + + return 1; +} + +extern int visws_trap_init_quirk(void); + +void __init visws_early_detect(void) +{ + int raw; + + visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) + >> PIIX_GPI_BD_SHIFT; + + if (visws_board_type < 0) + return; + + /* + * Install special quirks for timer, interrupt and memory setup: + */ + arch_time_init_quirk = visws_time_init_quirk; + arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; + arch_memory_setup_quirk = visws_memory_setup_quirk; + + /* + * Fall back to generic behavior for traps: + */ + arch_intr_init_quirk = NULL; + arch_trap_init_quirk = visws_trap_init_quirk; + + /* + * Install reboot quirks: + */ + pm_power_off = visws_machine_power_off; + machine_ops.emergency_restart = visws_machine_emergency_restart; + + /* + * Do not use broadcast IPIs: + */ + no_broadcast = 0; + + /* + * Override generic MP-table parsing: + */ + mach_get_smp_config_quirk = visws_get_smp_config_quirk; + mach_find_smp_config_quirk = visws_find_smp_config_quirk; + +#ifdef CONFIG_X86_IO_APIC + /* + * Turn off IO-APIC detection and initialization: + */ + skip_ioapic_setup = 1; +#endif + + /* + * Get Board rev. + * First, we have to initialize the 307 part to allow us access + * to the GPIO registers. Let's map them at 0x0fc0 which is right + * after the PIIX4 PM section. + */ + outb_p(SIO_DEV_SEL, SIO_INDEX); + outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ + + outb_p(SIO_DEV_MSB, SIO_INDEX); + outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ + + outb_p(SIO_DEV_LSB, SIO_INDEX); + outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ + + outb_p(SIO_DEV_ENB, SIO_INDEX); + outb_p(1, SIO_DATA); /* Enable GPIO registers. */ + + /* + * Now, we have to map the power management section to write + * a bit which enables access to the GPIO registers. + * What lunatic came up with this shit? + */ + outb_p(SIO_DEV_SEL, SIO_INDEX); + outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ + + outb_p(SIO_DEV_MSB, SIO_INDEX); + outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ + + outb_p(SIO_DEV_LSB, SIO_INDEX); + outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ + + outb_p(SIO_DEV_ENB, SIO_INDEX); + outb_p(1, SIO_DATA); /* Enable PM registers. */ + + /* + * Now, write the PM register which enables the GPIO registers. + */ + outb_p(SIO_PM_FER2, SIO_PM_INDEX); + outb_p(SIO_PM_GP_EN, SIO_PM_DATA); + + /* + * Now, initialize the GPIO registers. + * We want them all to be inputs which is the + * power on default, so let's leave them alone. + * So, let's just read the board rev! + */ + raw = inb_p(SIO_GP_DATA1); + raw &= 0x7f; /* 7 bits of valid board revision ID. */ + + if (visws_board_type == VISWS_320) { + if (raw < 0x6) { + visws_board_rev = 4; + } else if (raw < 0xc) { + visws_board_rev = 5; + } else { + visws_board_rev = 6; + } + } else if (visws_board_type == VISWS_540) { + visws_board_rev = 2; + } else { + visws_board_rev = raw; + } + + printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", + (visws_board_type == VISWS_320 ? "320" : + (visws_board_type == VISWS_540 ? "540" : + "unknown")), visws_board_rev); +} -- cgit v0.10.2 From 26dd9fcfc2abc298e3c60597bbe6405826aabf91 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:21:38 +0200 Subject: x86, VisWS: turn into generic arch, clean up merge traps_visws.c and apic_visws.c into visws_quirks.c. (no code changed) Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 2ef0fbd..f77dd67 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -19,7 +19,7 @@ obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o -obj-$(CONFIG_X86_VISWS) += visws_quirks.o traps_visws.o apic_visws.o +obj-$(CONFIG_X86_VISWS) += visws_quirks.o obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o diff --git a/arch/x86/kernel/apic_visws.c b/arch/x86/kernel/apic_visws.c deleted file mode 100644 index 6c02c8d..0000000 --- a/arch/x86/kernel/apic_visws.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 1999 Bent Hagemark, Ingo Molnar - * - * SGI Visual Workstation interrupt controller - * - * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC - * which serves as the main interrupt controller in the system. Non-legacy - * hardware in the system uses this controller directly. Legacy devices - * are connected to the PIIX4 which in turn has its 8259(s) connected to - * a of the Cobalt APIC entry. - * - * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com - * - * 25/11/2002 - Updated for 2.5 by Andrey Panin - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -static DEFINE_SPINLOCK(cobalt_lock); - -/* - * Set the given Cobalt APIC Redirection Table entry to point - * to the given IDT vector/index. - */ -static inline void co_apic_set(int entry, int irq) -{ - co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR)); - co_apic_write(CO_APIC_HI(entry), 0); -} - -/* - * Cobalt (IO)-APIC functions to handle PCI devices. - */ -static inline int co_apic_ide0_hack(void) -{ - extern char visws_board_type; - extern char visws_board_rev; - - if (visws_board_type == VISWS_320 && visws_board_rev == 5) - return 5; - return CO_APIC_IDE0; -} - -static int is_co_apic(unsigned int irq) -{ - if (IS_CO_APIC(irq)) - return CO_APIC(irq); - - switch (irq) { - case 0: return CO_APIC_CPU; - case CO_IRQ_IDE0: return co_apic_ide0_hack(); - case CO_IRQ_IDE1: return CO_APIC_IDE1; - default: return -1; - } -} - - -/* - * This is the SGI Cobalt (IO-)APIC: - */ - -static void enable_cobalt_irq(unsigned int irq) -{ - co_apic_set(is_co_apic(irq), irq); -} - -static void disable_cobalt_irq(unsigned int irq) -{ - int entry = is_co_apic(irq); - - co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK); - co_apic_read(CO_APIC_LO(entry)); -} - -/* - * "irq" really just serves to identify the device. Here is where we - * map this to the Cobalt APIC entry where it's physically wired. - * This is called via request_irq -> setup_irq -> irq_desc->startup() - */ -static unsigned int startup_cobalt_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) - irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); - enable_cobalt_irq(irq); - spin_unlock_irqrestore(&cobalt_lock, flags); - return 0; -} - -static void ack_cobalt_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - disable_cobalt_irq(irq); - apic_write(APIC_EOI, APIC_EIO_ACK); - spin_unlock_irqrestore(&cobalt_lock, flags); -} - -static void end_cobalt_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_cobalt_irq(irq); - spin_unlock_irqrestore(&cobalt_lock, flags); -} - -static struct irq_chip cobalt_irq_type = { - .typename = "Cobalt-APIC", - .startup = startup_cobalt_irq, - .shutdown = disable_cobalt_irq, - .enable = enable_cobalt_irq, - .disable = disable_cobalt_irq, - .ack = ack_cobalt_irq, - .end = end_cobalt_irq, -}; - - -/* - * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt - * -- not the manner expected by the code in i8259.c. - * - * there is a 'master' physical interrupt source that gets sent to - * the CPU. But in the chipset there are various 'virtual' interrupts - * waiting to be handled. We represent this to Linux through a 'master' - * interrupt controller type, and through a special virtual interrupt- - * controller. Device drivers only see the virtual interrupt sources. - */ -static unsigned int startup_piix4_master_irq(unsigned int irq) -{ - init_8259A(0); - - return startup_cobalt_irq(irq); -} - -static void end_piix4_master_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - enable_cobalt_irq(irq); - spin_unlock_irqrestore(&cobalt_lock, flags); -} - -static struct irq_chip piix4_master_irq_type = { - .typename = "PIIX4-master", - .startup = startup_piix4_master_irq, - .ack = ack_cobalt_irq, - .end = end_piix4_master_irq, -}; - - -static struct irq_chip piix4_virtual_irq_type = { - .typename = "PIIX4-virtual", - .shutdown = disable_8259A_irq, - .enable = enable_8259A_irq, - .disable = disable_8259A_irq, -}; - - -/* - * PIIX4-8259 master/virtual functions to handle interrupt requests - * from legacy devices: floppy, parallel, serial, rtc. - * - * None of these get Cobalt APIC entries, neither do they have IDT - * entries. These interrupts are purely virtual and distributed from - * the 'master' interrupt source: CO_IRQ_8259. - * - * When the 8259 interrupts its handler figures out which of these - * devices is interrupting and dispatches to its handler. - * - * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/ - * enable_irq gets the right irq. This 'master' irq is never directly - * manipulated by any driver. - */ -static irqreturn_t piix4_master_intr(int irq, void *dev_id) -{ - int realirq; - irq_desc_t *desc; - unsigned long flags; - - spin_lock_irqsave(&i8259A_lock, flags); - - /* Find out what's interrupting in the PIIX4 master 8259 */ - outb(0x0c, 0x20); /* OCW3 Poll command */ - realirq = inb(0x20); - - /* - * Bit 7 == 0 means invalid/spurious - */ - if (unlikely(!(realirq & 0x80))) - goto out_unlock; - - realirq &= 7; - - if (unlikely(realirq == 2)) { - outb(0x0c, 0xa0); - realirq = inb(0xa0); - - if (unlikely(!(realirq & 0x80))) - goto out_unlock; - - realirq = (realirq & 7) + 8; - } - - /* mask and ack interrupt */ - cached_irq_mask |= 1 << realirq; - if (unlikely(realirq > 7)) { - inb(0xa1); - outb(cached_slave_mask, 0xa1); - outb(0x60 + (realirq & 7), 0xa0); - outb(0x60 + 2, 0x20); - } else { - inb(0x21); - outb(cached_master_mask, 0x21); - outb(0x60 + realirq, 0x20); - } - - spin_unlock_irqrestore(&i8259A_lock, flags); - - desc = irq_desc + realirq; - - /* - * handle this 'virtual interrupt' as a Cobalt one now. - */ - kstat_cpu(smp_processor_id()).irqs[realirq]++; - - if (likely(desc->action != NULL)) - handle_IRQ_event(realirq, desc->action); - - if (!(desc->status & IRQ_DISABLED)) - enable_8259A_irq(realirq); - - return IRQ_HANDLED; - -out_unlock: - spin_unlock_irqrestore(&i8259A_lock, flags); - return IRQ_NONE; -} - -static struct irqaction master_action = { - .handler = piix4_master_intr, - .name = "PIIX4-8259", -}; - -static struct irqaction cascade_action = { - .handler = no_action, - .name = "cascade", -}; - - -void init_VISWS_APIC_irqs(void) -{ - int i; - - for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - - if (i == 0) { - irq_desc[i].chip = &cobalt_irq_type; - } - else if (i == CO_IRQ_IDE0) { - irq_desc[i].chip = &cobalt_irq_type; - } - else if (i == CO_IRQ_IDE1) { - irq_desc[i].chip = &cobalt_irq_type; - } - else if (i == CO_IRQ_8259) { - irq_desc[i].chip = &piix4_master_irq_type; - } - else if (i < CO_IRQ_APIC0) { - irq_desc[i].chip = &piix4_virtual_irq_type; - } - else if (IS_CO_APIC(i)) { - irq_desc[i].chip = &cobalt_irq_type; - } - } - - setup_irq(CO_IRQ_8259, &master_action); - setup_irq(2, &cascade_action); -} diff --git a/arch/x86/kernel/traps_visws.c b/arch/x86/kernel/traps_visws.c deleted file mode 100644 index e5e6492..0000000 --- a/arch/x86/kernel/traps_visws.c +++ /dev/null @@ -1,71 +0,0 @@ -/* VISWS traps */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4) -#define BCD (LI_INTB | LI_INTC | LI_INTD) -#define ALLDEVS (A01234 | BCD) - -static __init void lithium_init(void) -{ - set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS); - set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS); - - if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || - (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { - printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); -/* panic("This machine is not SGI Visual Workstation 320/540"); */ - } - - if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || - (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { - printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); -/* panic("This machine is not SGI Visual Workstation 320/540"); */ - } - - li_pcia_write16(LI_PCI_INTEN, ALLDEVS); - li_pcib_write16(LI_PCI_INTEN, ALLDEVS); -} - -static __init void cobalt_init(void) -{ - /* - * On normal SMP PC this is used only with SMP, but we have to - * use it and set it up here to start the Cobalt clock - */ - set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); - setup_local_APIC(); - printk(KERN_INFO "Local APIC Version %#x, ID %#x\n", - (unsigned int)apic_read(APIC_LVR), - (unsigned int)apic_read(APIC_ID)); - - set_fixmap(FIX_CO_CPU, CO_CPU_PHYS); - set_fixmap(FIX_CO_APIC, CO_APIC_PHYS); - printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n", - co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID)); - - /* Enable Cobalt APIC being careful to NOT change the ID! */ - co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE); - - printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n", - co_apic_read(CO_APIC_ID)); -} - -int __init visws_trap_init_quirk(void) -{ - lithium_init(); - cobalt_init(); - - return 1; -} diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index e19b91c..5c715c2 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c @@ -1,8 +1,22 @@ /* - * Unmaintained SGI Visual Workstation support. + * SGI Visual Workstation support and quirks, unmaintained. + * * Split out from setup.c by davej@suse.de + * + * Copyright (C) 1999 Bent Hagemark, Ingo Molnar + * + * SGI Visual Workstation interrupt controller + * + * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC + * which serves as the main interrupt controller in the system. Non-legacy + * hardware in the system uses this controller directly. Legacy devices + * are connected to the PIIX4 which in turn has its 8259(s) connected to + * a of the Cobalt APIC entry. + * + * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com + * + * 25/11/2002 - Updated for 2.5 by Andrey Panin */ - #include #include #include @@ -25,6 +39,30 @@ #include #include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + char visws_board_type = -1; char visws_board_rev = -1; @@ -336,3 +374,334 @@ void __init visws_early_detect(void) (visws_board_type == VISWS_540 ? "540" : "unknown")), visws_board_rev); } + +#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4) +#define BCD (LI_INTB | LI_INTC | LI_INTD) +#define ALLDEVS (A01234 | BCD) + +static __init void lithium_init(void) +{ + set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS); + set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS); + + if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || + (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { + printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); +/* panic("This machine is not SGI Visual Workstation 320/540"); */ + } + + if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || + (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { + printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); +/* panic("This machine is not SGI Visual Workstation 320/540"); */ + } + + li_pcia_write16(LI_PCI_INTEN, ALLDEVS); + li_pcib_write16(LI_PCI_INTEN, ALLDEVS); +} + +static __init void cobalt_init(void) +{ + /* + * On normal SMP PC this is used only with SMP, but we have to + * use it and set it up here to start the Cobalt clock + */ + set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); + setup_local_APIC(); + printk(KERN_INFO "Local APIC Version %#x, ID %#x\n", + (unsigned int)apic_read(APIC_LVR), + (unsigned int)apic_read(APIC_ID)); + + set_fixmap(FIX_CO_CPU, CO_CPU_PHYS); + set_fixmap(FIX_CO_APIC, CO_APIC_PHYS); + printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n", + co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID)); + + /* Enable Cobalt APIC being careful to NOT change the ID! */ + co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE); + + printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n", + co_apic_read(CO_APIC_ID)); +} + +int __init visws_trap_init_quirk(void) +{ + lithium_init(); + cobalt_init(); + + return 1; +} + +/* + * IRQ controller / APIC support: + */ + +static DEFINE_SPINLOCK(cobalt_lock); + +/* + * Set the given Cobalt APIC Redirection Table entry to point + * to the given IDT vector/index. + */ +static inline void co_apic_set(int entry, int irq) +{ + co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR)); + co_apic_write(CO_APIC_HI(entry), 0); +} + +/* + * Cobalt (IO)-APIC functions to handle PCI devices. + */ +static inline int co_apic_ide0_hack(void) +{ + extern char visws_board_type; + extern char visws_board_rev; + + if (visws_board_type == VISWS_320 && visws_board_rev == 5) + return 5; + return CO_APIC_IDE0; +} + +static int is_co_apic(unsigned int irq) +{ + if (IS_CO_APIC(irq)) + return CO_APIC(irq); + + switch (irq) { + case 0: return CO_APIC_CPU; + case CO_IRQ_IDE0: return co_apic_ide0_hack(); + case CO_IRQ_IDE1: return CO_APIC_IDE1; + default: return -1; + } +} + + +/* + * This is the SGI Cobalt (IO-)APIC: + */ + +static void enable_cobalt_irq(unsigned int irq) +{ + co_apic_set(is_co_apic(irq), irq); +} + +static void disable_cobalt_irq(unsigned int irq) +{ + int entry = is_co_apic(irq); + + co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK); + co_apic_read(CO_APIC_LO(entry)); +} + +/* + * "irq" really just serves to identify the device. Here is where we + * map this to the Cobalt APIC entry where it's physically wired. + * This is called via request_irq -> setup_irq -> irq_desc->startup() + */ +static unsigned int startup_cobalt_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) + irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); + enable_cobalt_irq(irq); + spin_unlock_irqrestore(&cobalt_lock, flags); + return 0; +} + +static void ack_cobalt_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + disable_cobalt_irq(irq); + apic_write(APIC_EOI, APIC_EIO_ACK); + spin_unlock_irqrestore(&cobalt_lock, flags); +} + +static void end_cobalt_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_cobalt_irq(irq); + spin_unlock_irqrestore(&cobalt_lock, flags); +} + +static struct irq_chip cobalt_irq_type = { + .typename = "Cobalt-APIC", + .startup = startup_cobalt_irq, + .shutdown = disable_cobalt_irq, + .enable = enable_cobalt_irq, + .disable = disable_cobalt_irq, + .ack = ack_cobalt_irq, + .end = end_cobalt_irq, +}; + + +/* + * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt + * -- not the manner expected by the code in i8259.c. + * + * there is a 'master' physical interrupt source that gets sent to + * the CPU. But in the chipset there are various 'virtual' interrupts + * waiting to be handled. We represent this to Linux through a 'master' + * interrupt controller type, and through a special virtual interrupt- + * controller. Device drivers only see the virtual interrupt sources. + */ +static unsigned int startup_piix4_master_irq(unsigned int irq) +{ + init_8259A(0); + + return startup_cobalt_irq(irq); +} + +static void end_piix4_master_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&cobalt_lock, flags); + enable_cobalt_irq(irq); + spin_unlock_irqrestore(&cobalt_lock, flags); +} + +static struct irq_chip piix4_master_irq_type = { + .typename = "PIIX4-master", + .startup = startup_piix4_master_irq, + .ack = ack_cobalt_irq, + .end = end_piix4_master_irq, +}; + + +static struct irq_chip piix4_virtual_irq_type = { + .typename = "PIIX4-virtual", + .shutdown = disable_8259A_irq, + .enable = enable_8259A_irq, + .disable = disable_8259A_irq, +}; + + +/* + * PIIX4-8259 master/virtual functions to handle interrupt requests + * from legacy devices: floppy, parallel, serial, rtc. + * + * None of these get Cobalt APIC entries, neither do they have IDT + * entries. These interrupts are purely virtual and distributed from + * the 'master' interrupt source: CO_IRQ_8259. + * + * When the 8259 interrupts its handler figures out which of these + * devices is interrupting and dispatches to its handler. + * + * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/ + * enable_irq gets the right irq. This 'master' irq is never directly + * manipulated by any driver. + */ +static irqreturn_t piix4_master_intr(int irq, void *dev_id) +{ + int realirq; + irq_desc_t *desc; + unsigned long flags; + + spin_lock_irqsave(&i8259A_lock, flags); + + /* Find out what's interrupting in the PIIX4 master 8259 */ + outb(0x0c, 0x20); /* OCW3 Poll command */ + realirq = inb(0x20); + + /* + * Bit 7 == 0 means invalid/spurious + */ + if (unlikely(!(realirq & 0x80))) + goto out_unlock; + + realirq &= 7; + + if (unlikely(realirq == 2)) { + outb(0x0c, 0xa0); + realirq = inb(0xa0); + + if (unlikely(!(realirq & 0x80))) + goto out_unlock; + + realirq = (realirq & 7) + 8; + } + + /* mask and ack interrupt */ + cached_irq_mask |= 1 << realirq; + if (unlikely(realirq > 7)) { + inb(0xa1); + outb(cached_slave_mask, 0xa1); + outb(0x60 + (realirq & 7), 0xa0); + outb(0x60 + 2, 0x20); + } else { + inb(0x21); + outb(cached_master_mask, 0x21); + outb(0x60 + realirq, 0x20); + } + + spin_unlock_irqrestore(&i8259A_lock, flags); + + desc = irq_desc + realirq; + + /* + * handle this 'virtual interrupt' as a Cobalt one now. + */ + kstat_cpu(smp_processor_id()).irqs[realirq]++; + + if (likely(desc->action != NULL)) + handle_IRQ_event(realirq, desc->action); + + if (!(desc->status & IRQ_DISABLED)) + enable_8259A_irq(realirq); + + return IRQ_HANDLED; + +out_unlock: + spin_unlock_irqrestore(&i8259A_lock, flags); + return IRQ_NONE; +} + +static struct irqaction master_action = { + .handler = piix4_master_intr, + .name = "PIIX4-8259", +}; + +static struct irqaction cascade_action = { + .handler = no_action, + .name = "cascade", +}; + + +void init_VISWS_APIC_irqs(void) +{ + int i; + + for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + + if (i == 0) { + irq_desc[i].chip = &cobalt_irq_type; + } + else if (i == CO_IRQ_IDE0) { + irq_desc[i].chip = &cobalt_irq_type; + } + else if (i == CO_IRQ_IDE1) { + irq_desc[i].chip = &cobalt_irq_type; + } + else if (i == CO_IRQ_8259) { + irq_desc[i].chip = &piix4_master_irq_type; + } + else if (i < CO_IRQ_APIC0) { + irq_desc[i].chip = &piix4_virtual_irq_type; + } + else if (IS_CO_APIC(i)) { + irq_desc[i].chip = &cobalt_irq_type; + } + } + + setup_irq(CO_IRQ_8259, &master_action); + setup_irq(2, &cascade_action); +} -- cgit v0.10.2 From 62fa572f6933038b3d79558812de88702bda176f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 16:45:50 +0200 Subject: x86, VisWS: turn into generic arch, remove leftover files remove leftover arch/x86/mach-visws/* files. Signed-off-by: Ingo Molnar diff --git a/arch/x86/Makefile b/arch/x86/Makefile index ce04b03..919ce21 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -113,10 +113,6 @@ mcore-y := arch/x86/mach-default/ mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/ -# VISWS subarch support -#mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws -#mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/ - # generic subarchitecture mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/ diff --git a/arch/x86/mach-visws/Makefile b/arch/x86/mach-visws/Makefile deleted file mode 100644 index 7469df1..0000000 --- a/arch/x86/mach-visws/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-y := setup.o setup_visws.o traps.o - -obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o diff --git a/arch/x86/mach-visws/setup.c b/arch/x86/mach-visws/setup.c deleted file mode 100644 index b8054c3..0000000 --- a/arch/x86/mach-visws/setup.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Machine specific setup for generic - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * Any quirks to be performed to initialize timers/irqs/etc? - */ -int (*arch_time_init_quirk)(void); -int (*arch_pre_intr_init_quirk)(void); -int (*arch_intr_init_quirk)(void); -int (*arch_trap_init_quirk)(void); - -#ifdef CONFIG_HOTPLUG_CPU -#define DEFAULT_SEND_IPI (1) -#else -#define DEFAULT_SEND_IPI (0) -#endif - -int no_broadcast=DEFAULT_SEND_IPI; - -/** - * pre_intr_init_hook - initialisation prior to setting up interrupt vectors - * - * Description: - * Perform any necessary interrupt initialisation prior to setting up - * the "ordinary" interrupt call gates. For legacy reasons, the ISA - * interrupts should be initialised here if the machine emulates a PC - * in any way. - **/ -void __init pre_intr_init_hook(void) -{ - if (arch_pre_intr_init_quirk) { - if (arch_pre_intr_init_quirk()) - return; - } - 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 - * - * Description: - * Fill in any interrupts that may have been left out by the general - * init_IRQ() routine. interrupts having to do with the machine rather - * than the devices on the I/O bus (like APIC interrupts in intel MP - * systems) are started here. - **/ -void __init intr_init_hook(void) -{ - if (arch_intr_init_quirk) { - if (arch_intr_init_quirk()) - return; - } -#ifdef CONFIG_X86_LOCAL_APIC - apic_intr_init(); -#endif - - if (!acpi_ioapic) - setup_irq(2, &irq2); -} - -/** - * pre_setup_arch_hook - hook called prior to any setup_arch() execution - * - * Description: - * generally used to activate any machine specific identification - * routines that may be needed before setup_arch() runs. On VISWS - * this is used to get the board revision and type. - **/ -void __init pre_setup_arch_hook(void) -{ -} - -/** - * trap_init_hook - initialise system specific traps - * - * Description: - * Called as the final act of trap_init(). Used in VISWS to initialise - * the various board specific APIC traps. - **/ -void __init trap_init_hook(void) -{ - if (arch_trap_init_quirk) { - if (arch_trap_init_quirk()) - return; - } -} - -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, - .mask = CPU_MASK_NONE, - .name = "timer" -}; - -/** - * time_init_hook - do any specific initialisations for the system timer. - * - * Description: - * Must plug the system timer interrupt source at HZ into the IRQ listed - * in irq_vectors.h:TIMER_IRQ - **/ -void __init time_init_hook(void) -{ - if (arch_time_init_quirk) { - /* - * A nonzero return code does not mean failure, it means - * that the architecture quirk does not want any - * generic (timer) setup to be performed after this: - */ - if (arch_time_init_quirk()) - return; - } - - irq0.mask = cpumask_of_cpu(0); - setup_irq(0, &irq0); -} - -#ifdef CONFIG_MCA -/** - * mca_nmi_hook - hook into MCA specific NMI chain - * - * Description: - * The MCA (Microchannel Architecture) has an NMI chain for NMI sources - * along the MCA bus. Use this to hook into that chain if you will need - * it. - **/ -void mca_nmi_hook(void) -{ - /* If I recall correctly, there's a whole bunch of other things that - * we can do to check for NMI problems, but that's all I know about - * at the moment. - */ - - printk("NMI generated from unknown source!\n"); -} -#endif - -static __init int no_ipi_broadcast(char *str) -{ - get_option(&str, &no_broadcast); - printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : - "IPI Broadcast"); - return 1; -} - -__setup("no_ipi_broadcast=", no_ipi_broadcast); - -static int __init print_ipi_mode(void) -{ - printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : - "Shortcut"); - return 0; -} - -late_initcall(print_ipi_mode); - diff --git a/arch/x86/mach-visws/setup_visws.c b/arch/x86/mach-visws/setup_visws.c deleted file mode 100644 index e95e949..0000000 --- a/arch/x86/mach-visws/setup_visws.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Unmaintained SGI Visual Workstation support. - * Split out from setup.c by davej@suse.de - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "mach_apic.h" - -#include -#include - -char visws_board_type = -1; -char visws_board_rev = -1; - -int is_visws_box(void) -{ - return visws_board_type >= 0; -} - -static int __init visws_time_init_quirk(void) -{ - printk(KERN_INFO "Starting Cobalt Timer system clock\n"); - - /* Set the countdown value */ - co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); - - /* Start the timer */ - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); - - /* Enable (unmask) the timer interrupt */ - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); - - /* - * Zero return means the generic timer setup code will set up - * the standard vector: - */ - return 0; -} - -static int __init visws_pre_intr_init_quirk(void) -{ - init_VISWS_APIC_irqs(); - - /* - * We dont want ISA irqs to be set up by the generic code: - */ - return 1; -} - -/* Quirk for machine specific memory setup. */ - -#define MB (1024 * 1024) - -unsigned long sgivwfb_mem_phys; -unsigned long sgivwfb_mem_size; -EXPORT_SYMBOL(sgivwfb_mem_phys); -EXPORT_SYMBOL(sgivwfb_mem_size); - -long long mem_size __initdata = 0; - -static char * __init visws_memory_setup_quirk(void) -{ - long long gfx_mem_size = 8 * MB; - - mem_size = boot_params.alt_mem_k; - - if (!mem_size) { - printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); - mem_size = 128 * MB; - } - - /* - * this hardcodes the graphics memory to 8 MB - * it really should be sized dynamically (or at least - * set as a boot param) - */ - if (!sgivwfb_mem_size) { - printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); - sgivwfb_mem_size = 8 * MB; - } - - /* - * Trim to nearest MB - */ - sgivwfb_mem_size &= ~((1 << 20) - 1); - sgivwfb_mem_phys = mem_size - gfx_mem_size; - - e820_add_region(0, LOWMEMSIZE(), E820_RAM); - e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); - e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); - - return "PROM"; -} - -static void visws_machine_emergency_restart(void) -{ - /* - * Visual Workstations restart after this - * register is poked on the PIIX4 - */ - outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); -} - -static void visws_machine_power_off(void) -{ - unsigned short pm_status; -/* extern unsigned int pci_bus0; */ - - while ((pm_status = inw(PMSTS_PORT)) & 0x100) - outw(pm_status, PMSTS_PORT); - - outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); - - mdelay(10); - -#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ - (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) - -/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ - outl(PIIX_SPECIAL_STOP, 0xCFC); -} - -static int __init visws_get_smp_config_quirk(unsigned int early) -{ - /* - * Prevent MP-table parsing by the generic code: - */ - return 1; -} - -extern unsigned int __cpuinitdata maxcpus; - -/* - * The Visual Workstation is Intel MP compliant in the hardware - * sense, but it doesn't have a BIOS(-configuration table). - * No problem for Linux. - */ - -static void __init MP_processor_info (struct mpc_config_processor *m) -{ - int ver, logical_apicid; - physid_mask_t apic_cpus; - - if (!(m->mpc_cpuflag & CPU_ENABLED)) - return; - - logical_apicid = m->mpc_apicid; - printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", - m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", - m->mpc_apicid, - (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, - (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, - m->mpc_apicver); - - if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) - boot_cpu_physical_apicid = m->mpc_apicid; - - ver = m->mpc_apicver; - if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { - printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", - m->mpc_apicid, MAX_APICS); - return; - } - - apic_cpus = apicid_to_cpu_present(m->mpc_apicid); - physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); - /* - * Validate version - */ - if (ver == 0x0) { - printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " - "fixing up to 0x10. (tell your hw vendor)\n", - m->mpc_apicid); - ver = 0x10; - } - apic_version[m->mpc_apicid] = ver; -} - -int __init visws_find_smp_config_quirk(unsigned int reserve) -{ - struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); - unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); - - if (ncpus > CO_CPU_MAX) { - printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", - ncpus, mp); - - ncpus = CO_CPU_MAX; - } - - if (ncpus > maxcpus) - ncpus = maxcpus; - -#ifdef CONFIG_X86_LOCAL_APIC - smp_found_config = 1; -#endif - while (ncpus--) - MP_processor_info(mp++); - - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - - return 1; -} - -extern int visws_trap_init_quirk(void); - -void __init visws_early_detect(void) -{ - int raw; - - visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) - >> PIIX_GPI_BD_SHIFT; - - if (visws_board_type < 0) - return; - - /* - * Install special quirks for timer, interrupt and memory setup: - */ - arch_time_init_quirk = visws_time_init_quirk; - arch_pre_intr_init_quirk = visws_pre_intr_init_quirk; - arch_memory_setup_quirk = visws_memory_setup_quirk; - - /* - * Fall back to generic behavior for traps: - */ - arch_intr_init_quirk = NULL; - arch_trap_init_quirk = visws_trap_init_quirk; - - /* - * Install reboot quirks: - */ - pm_power_off = visws_machine_power_off; - machine_ops.emergency_restart = visws_machine_emergency_restart; - - /* - * Do not use broadcast IPIs: - */ - no_broadcast = 0; - - /* - * Override generic MP-table parsing: - */ - mach_get_smp_config_quirk = visws_get_smp_config_quirk; - mach_find_smp_config_quirk = visws_find_smp_config_quirk; - - /* - * Get Board rev. - * First, we have to initialize the 307 part to allow us access - * to the GPIO registers. Let's map them at 0x0fc0 which is right - * after the PIIX4 PM section. - */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ - - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ - - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ - - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable GPIO registers. */ - - /* - * Now, we have to map the power management section to write - * a bit which enables access to the GPIO registers. - * What lunatic came up with this shit? - */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ - - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ - - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ - - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable PM registers. */ - - /* - * Now, write the PM register which enables the GPIO registers. - */ - outb_p(SIO_PM_FER2, SIO_PM_INDEX); - outb_p(SIO_PM_GP_EN, SIO_PM_DATA); - - /* - * Now, initialize the GPIO registers. - * We want them all to be inputs which is the - * power on default, so let's leave them alone. - * So, let's just read the board rev! - */ - raw = inb_p(SIO_GP_DATA1); - raw &= 0x7f; /* 7 bits of valid board revision ID. */ - - if (visws_board_type == VISWS_320) { - if (raw < 0x6) { - visws_board_rev = 4; - } else if (raw < 0xc) { - visws_board_rev = 5; - } else { - visws_board_rev = 6; - } - } else if (visws_board_type == VISWS_540) { - visws_board_rev = 2; - } else { - visws_board_rev = raw; - } - - printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", - (visws_board_type == VISWS_320 ? "320" : - (visws_board_type == VISWS_540 ? "540" : - "unknown")), visws_board_rev); -} diff --git a/arch/x86/mach-visws/traps.c b/arch/x86/mach-visws/traps.c deleted file mode 100644 index e5e6492..0000000 --- a/arch/x86/mach-visws/traps.c +++ /dev/null @@ -1,71 +0,0 @@ -/* VISWS traps */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4) -#define BCD (LI_INTB | LI_INTC | LI_INTD) -#define ALLDEVS (A01234 | BCD) - -static __init void lithium_init(void) -{ - set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS); - set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS); - - if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || - (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { - printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); -/* panic("This machine is not SGI Visual Workstation 320/540"); */ - } - - if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || - (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { - printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); -/* panic("This machine is not SGI Visual Workstation 320/540"); */ - } - - li_pcia_write16(LI_PCI_INTEN, ALLDEVS); - li_pcib_write16(LI_PCI_INTEN, ALLDEVS); -} - -static __init void cobalt_init(void) -{ - /* - * On normal SMP PC this is used only with SMP, but we have to - * use it and set it up here to start the Cobalt clock - */ - set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); - setup_local_APIC(); - printk(KERN_INFO "Local APIC Version %#x, ID %#x\n", - (unsigned int)apic_read(APIC_LVR), - (unsigned int)apic_read(APIC_ID)); - - set_fixmap(FIX_CO_CPU, CO_CPU_PHYS); - set_fixmap(FIX_CO_APIC, CO_APIC_PHYS); - printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n", - co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID)); - - /* Enable Cobalt APIC being careful to NOT change the ID! */ - co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE); - - printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n", - co_apic_read(CO_APIC_ID)); -} - -int __init visws_trap_init_quirk(void) -{ - lithium_init(); - cobalt_init(); - - return 1; -} diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c deleted file mode 100644 index 6c02c8d..0000000 --- a/arch/x86/mach-visws/visws_apic.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 1999 Bent Hagemark, Ingo Molnar - * - * SGI Visual Workstation interrupt controller - * - * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC - * which serves as the main interrupt controller in the system. Non-legacy - * hardware in the system uses this controller directly. Legacy devices - * are connected to the PIIX4 which in turn has its 8259(s) connected to - * a of the Cobalt APIC entry. - * - * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com - * - * 25/11/2002 - Updated for 2.5 by Andrey Panin - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -static DEFINE_SPINLOCK(cobalt_lock); - -/* - * Set the given Cobalt APIC Redirection Table entry to point - * to the given IDT vector/index. - */ -static inline void co_apic_set(int entry, int irq) -{ - co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR)); - co_apic_write(CO_APIC_HI(entry), 0); -} - -/* - * Cobalt (IO)-APIC functions to handle PCI devices. - */ -static inline int co_apic_ide0_hack(void) -{ - extern char visws_board_type; - extern char visws_board_rev; - - if (visws_board_type == VISWS_320 && visws_board_rev == 5) - return 5; - return CO_APIC_IDE0; -} - -static int is_co_apic(unsigned int irq) -{ - if (IS_CO_APIC(irq)) - return CO_APIC(irq); - - switch (irq) { - case 0: return CO_APIC_CPU; - case CO_IRQ_IDE0: return co_apic_ide0_hack(); - case CO_IRQ_IDE1: return CO_APIC_IDE1; - default: return -1; - } -} - - -/* - * This is the SGI Cobalt (IO-)APIC: - */ - -static void enable_cobalt_irq(unsigned int irq) -{ - co_apic_set(is_co_apic(irq), irq); -} - -static void disable_cobalt_irq(unsigned int irq) -{ - int entry = is_co_apic(irq); - - co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK); - co_apic_read(CO_APIC_LO(entry)); -} - -/* - * "irq" really just serves to identify the device. Here is where we - * map this to the Cobalt APIC entry where it's physically wired. - * This is called via request_irq -> setup_irq -> irq_desc->startup() - */ -static unsigned int startup_cobalt_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING))) - irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING); - enable_cobalt_irq(irq); - spin_unlock_irqrestore(&cobalt_lock, flags); - return 0; -} - -static void ack_cobalt_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - disable_cobalt_irq(irq); - apic_write(APIC_EOI, APIC_EIO_ACK); - spin_unlock_irqrestore(&cobalt_lock, flags); -} - -static void end_cobalt_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_cobalt_irq(irq); - spin_unlock_irqrestore(&cobalt_lock, flags); -} - -static struct irq_chip cobalt_irq_type = { - .typename = "Cobalt-APIC", - .startup = startup_cobalt_irq, - .shutdown = disable_cobalt_irq, - .enable = enable_cobalt_irq, - .disable = disable_cobalt_irq, - .ack = ack_cobalt_irq, - .end = end_cobalt_irq, -}; - - -/* - * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt - * -- not the manner expected by the code in i8259.c. - * - * there is a 'master' physical interrupt source that gets sent to - * the CPU. But in the chipset there are various 'virtual' interrupts - * waiting to be handled. We represent this to Linux through a 'master' - * interrupt controller type, and through a special virtual interrupt- - * controller. Device drivers only see the virtual interrupt sources. - */ -static unsigned int startup_piix4_master_irq(unsigned int irq) -{ - init_8259A(0); - - return startup_cobalt_irq(irq); -} - -static void end_piix4_master_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&cobalt_lock, flags); - enable_cobalt_irq(irq); - spin_unlock_irqrestore(&cobalt_lock, flags); -} - -static struct irq_chip piix4_master_irq_type = { - .typename = "PIIX4-master", - .startup = startup_piix4_master_irq, - .ack = ack_cobalt_irq, - .end = end_piix4_master_irq, -}; - - -static struct irq_chip piix4_virtual_irq_type = { - .typename = "PIIX4-virtual", - .shutdown = disable_8259A_irq, - .enable = enable_8259A_irq, - .disable = disable_8259A_irq, -}; - - -/* - * PIIX4-8259 master/virtual functions to handle interrupt requests - * from legacy devices: floppy, parallel, serial, rtc. - * - * None of these get Cobalt APIC entries, neither do they have IDT - * entries. These interrupts are purely virtual and distributed from - * the 'master' interrupt source: CO_IRQ_8259. - * - * When the 8259 interrupts its handler figures out which of these - * devices is interrupting and dispatches to its handler. - * - * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/ - * enable_irq gets the right irq. This 'master' irq is never directly - * manipulated by any driver. - */ -static irqreturn_t piix4_master_intr(int irq, void *dev_id) -{ - int realirq; - irq_desc_t *desc; - unsigned long flags; - - spin_lock_irqsave(&i8259A_lock, flags); - - /* Find out what's interrupting in the PIIX4 master 8259 */ - outb(0x0c, 0x20); /* OCW3 Poll command */ - realirq = inb(0x20); - - /* - * Bit 7 == 0 means invalid/spurious - */ - if (unlikely(!(realirq & 0x80))) - goto out_unlock; - - realirq &= 7; - - if (unlikely(realirq == 2)) { - outb(0x0c, 0xa0); - realirq = inb(0xa0); - - if (unlikely(!(realirq & 0x80))) - goto out_unlock; - - realirq = (realirq & 7) + 8; - } - - /* mask and ack interrupt */ - cached_irq_mask |= 1 << realirq; - if (unlikely(realirq > 7)) { - inb(0xa1); - outb(cached_slave_mask, 0xa1); - outb(0x60 + (realirq & 7), 0xa0); - outb(0x60 + 2, 0x20); - } else { - inb(0x21); - outb(cached_master_mask, 0x21); - outb(0x60 + realirq, 0x20); - } - - spin_unlock_irqrestore(&i8259A_lock, flags); - - desc = irq_desc + realirq; - - /* - * handle this 'virtual interrupt' as a Cobalt one now. - */ - kstat_cpu(smp_processor_id()).irqs[realirq]++; - - if (likely(desc->action != NULL)) - handle_IRQ_event(realirq, desc->action); - - if (!(desc->status & IRQ_DISABLED)) - enable_8259A_irq(realirq); - - return IRQ_HANDLED; - -out_unlock: - spin_unlock_irqrestore(&i8259A_lock, flags); - return IRQ_NONE; -} - -static struct irqaction master_action = { - .handler = piix4_master_intr, - .name = "PIIX4-8259", -}; - -static struct irqaction cascade_action = { - .handler = no_action, - .name = "cascade", -}; - - -void init_VISWS_APIC_irqs(void) -{ - int i; - - for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - - if (i == 0) { - irq_desc[i].chip = &cobalt_irq_type; - } - else if (i == CO_IRQ_IDE0) { - irq_desc[i].chip = &cobalt_irq_type; - } - else if (i == CO_IRQ_IDE1) { - irq_desc[i].chip = &cobalt_irq_type; - } - else if (i == CO_IRQ_8259) { - irq_desc[i].chip = &piix4_master_irq_type; - } - else if (i < CO_IRQ_APIC0) { - irq_desc[i].chip = &piix4_virtual_irq_type; - } - else if (IS_CO_APIC(i)) { - irq_desc[i].chip = &cobalt_irq_type; - } - } - - setup_irq(CO_IRQ_8259, &master_action); - setup_irq(2, &cascade_action); -} diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index c03c209..e515e8d 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile @@ -9,8 +9,6 @@ pci-y := fixup.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o -# Careful: VISWS overrule the pci-y above. The colons are -# therefor correct. This needs a proper fix by distangling the code. pci-$(CONFIG_X86_VISWS) += visws.o pci-$(CONFIG_X86_NUMAQ) += numa.o -- cgit v0.10.2 From 15e551d25e5a600c76cb92171357d4cbe2d1bf7a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 17:02:10 +0200 Subject: x86, VisWS: turn into generic arch, eliminate Kconfig specials remove leftover traces of various VISWS related Kconfig specials. Signed-off-by: Ingo Molnar diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 964dfa3..c70e12b 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig @@ -3,7 +3,7 @@ config LGUEST_GUEST select PARAVIRT depends on X86_32 depends on !X86_PAE - depends on !(X86_VISWS || X86_VOYAGER) + depends on !X86_VOYAGER select VIRTIO select VIRTIO_RING select VIRTIO_CONSOLE diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c index b8054c3..48278fa 100644 --- a/arch/x86/mach-default/setup.c +++ b/arch/x86/mach-default/setup.c @@ -81,7 +81,7 @@ void __init intr_init_hook(void) * * Description: * generally used to activate any machine specific identification - * routines that may be needed before setup_arch() runs. On VISWS + * routines that may be needed before setup_arch() runs. On Voyager * this is used to get the board revision and type. **/ void __init pre_setup_arch_hook(void) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 860f15f..bba8673 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -4,7 +4,6 @@ menuconfig ACPI bool "ACPI (Advanced Configuration and Power Interface) Support" - depends on !X86_VISWS depends on !IA64_HP_SIM depends on IA64 || X86 depends on PCI diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 6b8dbb9..76f2b36 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -1,6 +1,6 @@ config LGUEST tristate "Linux hypervisor example code" - depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !(X86_VISWS || X86_VOYAGER) + depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !X86_VOYAGER select HVC_DRIVER ---help--- This is a very simple module which allows you to run -- cgit v0.10.2 From 3f68f7d945e37e4d4bf1da445a285c59a6185815 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 10 Jul 2008 18:58:24 +0200 Subject: x86/pci merge: fixing numaq initialization Patch d49c4288 (tip/x86/mpparse) introduced some changes in calling subsys_init calls if CONFIG_X86_NUMAQ option is set. This patch updates subsystem initalization according to this changes. Signed-off-by: Robert Richter Cc: Robert Richter Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index 3c1d795..d8b6e92 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c @@ -62,6 +62,9 @@ int __init pci_subsys_init(void) #endif pci_legacy_init(); pcibios_irq_init(); +#ifdef CONFIG_X86_NUMAQ + pci_numa_init(); +#endif pcibios_init(); } subsys_initcall(pci_subsys_init); diff --git a/arch/x86/pci/numa.c b/arch/x86/pci/numa.c index e1620dc..8b5ca19 100644 --- a/arch/x86/pci/numa.c +++ b/arch/x86/pci/numa.c @@ -151,7 +151,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); -static int __init pci_numa_init(void) +int __init pci_numa_init(void) { int quad; @@ -176,11 +176,3 @@ static int __init pci_numa_init(void) } return 0; } - -static __init int pci_subsys_init(void) -{ - pci_numa_init(); - pcibios_irq_init(); - pcibios_init(); -} -subsys_initcall(pci_subsys_init); diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 5824174..b2270a5 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h @@ -107,6 +107,7 @@ extern void __init dmi_check_skip_isa_align(void); /* some common used subsys_initcalls */ extern int __init pci_acpi_init(void); extern int __init pcibios_irq_init(void); +extern int __init pci_numa_init(void); extern int __init pcibios_init(void); /* pci-mmconfig.c */ -- cgit v0.10.2 From 3a62ed73ccb76b3d573c2ceb52ee01081fa89f3d Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 10 Jul 2008 18:58:25 +0200 Subject: x86/pci: fix warnings in subsys_initcall functions Signed-off-by: Robert Richter Cc: Robert Richter Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index d8b6e92..132876c 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c @@ -66,5 +66,7 @@ int __init pci_subsys_init(void) pci_numa_init(); #endif pcibios_init(); + + return 0; } subsys_initcall(pci_subsys_init); -- cgit v0.10.2 From 8a55a00aad9f5c4e9bb97729b42a7ceea2a3b6fb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 19:35:33 +0200 Subject: x86, VisWS: turn into generic arch, update include file change Signed-off-by: Ingo Molnar diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index 2c5aaa5..dcbb3f7 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -150,7 +150,7 @@ #include #include -#include +#include #include "sound_config.h" -- cgit v0.10.2 From b6770c83b4b88dd832cc77916b1935b0311c64e0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 19:37:44 +0200 Subject: x86, VisWS: do not allow VisWS for Voyager Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 24ff43a..1765714 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -353,7 +353,7 @@ endchoice config X86_VISWS bool "SGI 320/540 (Visual Workstation)" - depends on X86_32 && PCI + depends on X86_32 && PCI && !X86_VOYAGER help The SGI Visual Workstation series is an IA32-based workstation based on SGI systems chips with some legacy PC hardware attached. -- cgit v0.10.2 From f78cb9b1cfe618e8b4cc0c118f187f54ed102f45 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 19:39:55 +0200 Subject: x86, VisWS: build fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: arch/x86/kernel/visws_quirks.c: In function ‘visws_early_detect’: arch/x86/kernel/visws_quirks.c:293: error: ‘no_broadcast’ undeclared (first use in this function) arch/x86/kernel/visws_quirks.c:293: error: (Each undeclared identifier is reported only once arch/x86/kernel/visws_quirks.c:293: error: for each function it appears in.) make[1]: *** [arch/x86/kernel/visws_quirks.o] Error 1 make: *** [arch/x86/kernel/visws_quirks.o] Error 2 Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 5c715c2..e94bdb6 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c @@ -57,6 +57,8 @@ #include #include +extern int no_broadcast; + #include #include #include -- cgit v0.10.2 From e54afe38630e3b577968428f48ed8ef1e13a2a15 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 10 Jul 2008 14:01:47 -0300 Subject: x86: remove duplicate call to use_tsc_delay Integration generated a duplicate call to use_tsc_delay. Particularly, the one that is done before we check for general tsc usability seems wrong. Signed-off-by: Glauber Costa Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 4a775d0..3c36f92 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -513,7 +513,6 @@ void __init tsc_init(void) */ for_each_possible_cpu(cpu) set_cyc2ns_scale(cpu_khz, cpu); - use_tsc_delay(); if (tsc_disabled > 0) return; -- cgit v0.10.2 From c47277d2f842d6c50d1991579307625540b26eac Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 19:47:49 +0200 Subject: x86, VisWS: build fix fix: arch/x86/kernel/built-in.o: In function `visws_early_detect': : undefined reference to `mach_get_smp_config_quirk' arch/x86/kernel/built-in.o: In function `visws_early_detect': : undefined reference to `mach_find_smp_config_quirk' Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1765714..b030186 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -353,7 +353,7 @@ endchoice config X86_VISWS bool "SGI 320/540 (Visual Workstation)" - depends on X86_32 && PCI && !X86_VOYAGER + depends on X86_32 && PCI && !X86_VOYAGER && X86_MPPARSE help The SGI Visual Workstation series is an IA32-based workstation based on SGI systems chips with some legacy PC hardware attached. -- cgit v0.10.2 From 39415a440ecceb0a5bd3c23686f18f83bb8368c6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 10 Jul 2008 20:06:30 +0200 Subject: x86, VisWS: fix pci_direct_conf1 dependency fix: arch/x86/pci/built-in.o: In function `pci_subsys_init': visws.c:(.init.text+0xfc5): undefined reference to `pci_direct_conf1' Signed-off-by: Ingo Molnar diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b030186..2cfccc9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -353,7 +353,7 @@ endchoice config X86_VISWS bool "SGI 320/540 (Visual Workstation)" - depends on X86_32 && PCI && !X86_VOYAGER && X86_MPPARSE + depends on X86_32 && PCI && !X86_VOYAGER && X86_MPPARSE && PCI_GODIRECT help The SGI Visual Workstation series is an IA32-based workstation based on SGI systems chips with some legacy PC hardware attached. -- cgit v0.10.2 From 27cb0a75ba252ea7294d67232c4bbbac3f2b2656 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 10 Jul 2008 12:52:52 -0700 Subject: x86: fix compile error in current tip.git Gas 2.15 complains about 32-bit registers being used in lea. AS arch/x86/lib/copy_user_64.o /local/scratch-2/jeremy/hg/xen/paravirt/linux/arch/x86/lib/copy_user_64.S: Assembler messages: /local/scratch-2/jeremy/hg/xen/paravirt/linux/arch/x86/lib/copy_user_64.S:188: Error: `(%edx,%ecx,8)' is not a valid 64 bit base/index expression /local/scratch-2/jeremy/hg/xen/paravirt/linux/arch/x86/lib/copy_user_64.S:257: Error: `(%edx,%ecx,8)' is not a valid 64 bit base/index expression AS arch/x86/lib/copy_user_nocache_64.o /local/scratch-2/jeremy/hg/xen/paravirt/linux/arch/x86/lib/copy_user_nocache_64.S: Assembler messages: /local/scratch-2/jeremy/hg/xen/paravirt/linux/arch/x86/lib/copy_user_nocache_64.S:107: Error: `(%edx,%ecx,8)' is not a valid 64 bit base/index expression Signed-off-by: Jeremy Fitzhardinge Cc: Vitaly Mayatskikh Signed-off-by: Ingo Molnar diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index e5afb4a..dfdf428 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -185,7 +185,7 @@ ENTRY(copy_user_generic_unrolled) 30: shll $6,%ecx addl %ecx,%edx jmp 60f -40: leal (%edx,%ecx,8),%edx +40: lea (%rdx,%rcx,8),%rdx jmp 60f 50: movl %ecx,%edx 60: jmp copy_user_handle_tail /* ecx is zerorest also */ @@ -254,7 +254,7 @@ ENTRY(copy_user_generic_string) ret .section .fixup,"ax" -11: leal (%edx,%ecx,8),%ecx +11: lea (%rdx,%rcx,8),%rcx 12: movl %ecx,%edx /* ecx is zerorest also */ jmp copy_user_handle_tail .previous diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S index 93353d6..40e0e30 100644 --- a/arch/x86/lib/copy_user_nocache_64.S +++ b/arch/x86/lib/copy_user_nocache_64.S @@ -104,7 +104,7 @@ ENTRY(__copy_user_nocache) 30: shll $6,%ecx addl %ecx,%edx jmp 60f -40: leal (%edx,%ecx,8),%edx +40: lea (%rdx,%rcx,8),%rdx jmp 60f 50: movl %ecx,%edx 60: sfence -- cgit v0.10.2 From 69a7704d7a80b2563278a0c55c2ca6d6202280dc Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 10 Jul 2008 04:17:00 -0700 Subject: x86: e820: user-defined memory maps: remove the range instead of update it to reserved also let mem= to print out modified e820 map too Signed-off-by: Yinghai Lu Cc: Bernhard Walle Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 9836a07..3451e0b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1165,6 +1165,8 @@ static void early_panic(char *msg) panic(msg); } +static int userdef __initdata; + /* "mem=nopentium" disables the 4MB page tables. */ static int __init parse_memopt(char *p) { @@ -1180,17 +1182,15 @@ static int __init parse_memopt(char *p) } #endif + userdef = 1; mem_size = memparse(p, &p); end_user_pfn = mem_size>>PAGE_SHIFT; - e820_update_range(mem_size, ULLONG_MAX - mem_size, - E820_RAM, E820_RESERVED); + e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); return 0; } early_param("mem", parse_memopt); -static int userdef __initdata; - static int __init parse_memmap_opt(char *p) { char *oldp; @@ -1230,8 +1230,7 @@ static int __init parse_memmap_opt(char *p) e820_add_region(start_at, mem_size, E820_RESERVED); } else { end_user_pfn = (mem_size >> PAGE_SHIFT); - e820_update_range(mem_size, ULLONG_MAX - mem_size, - E820_RAM, E820_RESERVED); + e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); } return *p == '\0' ? 0 : -EINVAL; } -- cgit v0.10.2 From f302a5bbe5eb95f3d4227d5bd0e9b92b1b125f4f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 10 Jul 2008 20:36:37 -0700 Subject: x86: reserve SLIT save the SLIT, in case we are using fixmap to read it, and that fixmap could be cleared by others. Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 0fd67b8..1b4763e 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -100,7 +100,19 @@ static __init inline int srat_disabled(void) /* Callback for SLIT parsing */ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) { - acpi_slit = slit; + unsigned length; + unsigned long phys; + + length = slit->header.length; + phys = find_e820_area(0, max_pfn_mapped< LAPIC mapping */ -- cgit v0.10.2 From f361a450bf1ad14e2b003217dbf3958638631265 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 10 Jul 2008 20:38:26 -0700 Subject: x86: introduce max_low_pfn_mapped for 64-bit when more than 4g memory is installed, don't map the big hole below 4g. Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a31a579..9c981c4 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -130,7 +130,7 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) if (!phys || !size) return NULL; - if (phys+size <= (max_pfn_mapped << PAGE_SHIFT)) + if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT)) return __va(phys); offset = phys & (PAGE_SIZE - 1); diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c index 958526d..bd182b76 100644 --- a/arch/x86/kernel/cpu/amd_64.c +++ b/arch/x86/kernel/cpu/amd_64.c @@ -199,10 +199,14 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) * Don't do it for gbpages because there seems very little * benefit in doing so. */ - if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg) && - (tseg >> PMD_SHIFT) < - (max_pfn_mapped >> (PMD_SHIFT-PAGE_SHIFT))) + if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { + if ((tseg>>PMD_SHIFT) < + (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) || + ((tseg>>PMD_SHIFT) < + (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) && + (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT)))) set_memory_4k((unsigned long)__va(tseg), 1); + } } } diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 3451e0b..9f5002e 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1056,7 +1056,7 @@ unsigned long __initdata end_user_pfn = MAX_ARCH_PFN; /* * Find the highest page frame number we have available */ -unsigned long __init e820_end(void) +static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) { int i; unsigned long last_pfn = 0; @@ -1064,12 +1064,21 @@ unsigned long __init e820_end(void) for (i = 0; i < e820.nr_map; i++) { struct e820entry *ei = &e820.map[i]; + unsigned long start_pfn; unsigned long end_pfn; - if (ei->type != E820_RAM) + if (ei->type != type) continue; + start_pfn = ei->addr >> PAGE_SHIFT; end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; + + if (start_pfn >= limit_pfn) + continue; + if (end_pfn > limit_pfn) { + last_pfn = limit_pfn; + break; + } if (end_pfn > last_pfn) last_pfn = end_pfn; } @@ -1083,7 +1092,15 @@ unsigned long __init e820_end(void) last_pfn, max_arch_pfn); return last_pfn; } +unsigned long __init e820_end_of_ram_pfn(void) +{ + return e820_end_pfn(MAX_ARCH_PFN, E820_RAM); +} +unsigned long __init e820_end_of_low_ram_pfn(void) +{ + return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM); +} /* * Finds an active region in the address range from start_pfn to last_pfn and * returns its range in ei_startpfn and ei_endpfn for the e820 entry. @@ -1206,7 +1223,7 @@ static int __init parse_memmap_opt(char *p) * the real mem size before original memory map is * reset. */ - saved_max_pfn = e820_end(); + saved_max_pfn = e820_end_of_ram_pfn(); #endif e820.nr_map = 0; userdef = 1; diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 94382fa..06cc8d4 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c @@ -473,7 +473,7 @@ void __init efi_enter_virtual_mode(void) size = md->num_pages << EFI_PAGE_SHIFT; end = md->phys_addr + size; - if (PFN_UP(end) <= 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 --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a7c3471..86fc2d6 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -713,14 +713,14 @@ void __init setup_arch(char **cmdline_p) * partially used pages are not usable - thus * we are rounding upwards: */ - max_pfn = e820_end(); + max_pfn = e820_end_of_ram_pfn(); /* preallocate 4k for mptable mpc */ early_reserve_e820_mpc_new(); /* update e820 for memory not covered by WB MTRRs */ mtrr_bp_init(); if (mtrr_trim_uncached_memory(max_pfn)) - max_pfn = e820_end(); + max_pfn = e820_end_of_ram_pfn(); #ifdef CONFIG_X86_32 /* max_low_pfn get updated here */ @@ -732,12 +732,26 @@ void __init setup_arch(char **cmdline_p) /* How many end-of-memory variables you have, grandma! */ /* need this before calling reserve_initrd */ - max_low_pfn = max_pfn; + if (max_pfn > (1UL<<(32 - PAGE_SHIFT))) + max_low_pfn = e820_end_of_low_ram_pfn(); + else + max_low_pfn = max_pfn; + high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1; #endif /* max_pfn_mapped is updated here */ - max_pfn_mapped = init_memory_mapping(0, (max_low_pfn << PAGE_SHIFT)); + max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn< max_low_pfn) { + max_pfn_mapped = init_memory_mapping(1UL<<32, + max_pfn<= (unsigned long)__va(0) && + address < (unsigned long)__va(max_low_pfn_mapped << PAGE_SHIFT)) + split_page_count(level); + +#ifdef CONFIG_X86_64 + if (address >= (unsigned long)__va(1UL<<32) && address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) split_page_count(level); +#endif /* * Install the new, split up pagetable. Important details here: @@ -655,12 +661,21 @@ static int cpa_process_alias(struct cpa_data *cpa) if (cpa->pfn > max_pfn_mapped) return 0; +#ifdef CONFIG_X86_64 + if (cpa->pfn > max_low_pfn_mapped && cpa->pfn < (1UL<<(32-PAGE_SHIFT))) + return 0; +#endif /* * No need to redo, when the primary call touched the direct * mapping already: */ - if (!within(cpa->vaddr, PAGE_OFFSET, - PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) { + if (!(within(cpa->vaddr, PAGE_OFFSET, + PAGE_OFFSET + (max_low_pfn_mapped << PAGE_SHIFT)) +#ifdef CONFIG_X86_64 + || within(cpa->vaddr, PAGE_OFFSET + (1UL<<32), + PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)) +#endif + )) { alias_cpa = *cpa; alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index a885a10..749766c 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -449,7 +449,8 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, if (retval < 0) return 0; - if (pfn <= max_pfn_mapped && + if (((pfn <= max_low_pfn_mapped) || + (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn <= max_pfn_mapped)) && ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { free_memtype(offset, offset + size); printk(KERN_INFO diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 6ccd7a1..5281e34 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -334,7 +334,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, flags = new_flags; } - if (vma->vm_pgoff <= max_pfn_mapped && + if (((vma->vm_pgoff <= max_low_pfn_mapped) || + (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) && + vma->vm_pgoff <= max_pfn_mapped)) && ioremap_change_attr((unsigned long)__va(addr), len, flags)) { free_memtype(addr, addr + len); return -EINVAL; diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 78c03d7..33e793e 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -99,7 +99,8 @@ extern void free_early(u64 start, u64 end); extern void early_res_to_bootmem(u64 start, u64 end); extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); -extern unsigned long e820_end(void); +extern unsigned long e820_end_of_ram_pfn(void); +extern unsigned long e820_end_of_low_ram_pfn(void); extern int e820_find_active_region(const struct e820entry *ei, unsigned long start_pfn, unsigned long last_pfn, diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index b52ed85..28d7b45 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -61,6 +61,7 @@ extern void map_devmem(unsigned long pfn, unsigned long size, extern void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot); +extern unsigned long max_low_pfn_mapped; extern unsigned long max_pfn_mapped; struct page; -- cgit v0.10.2 From 857f3fd7a496ddf4329345af65a4a2b16dd25fe8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Jul 2008 11:09:22 +0200 Subject: nohz: don't stop idle tick if softirqs are pending. In case a cpu goes idle but softirqs are pending only an error message is printed to the console. It may take a very long time until the pending softirqs will finally be executed. Worst case would be a hanging system. With this patch the timer tick just continues and the softirqs will be executed after the next interrupt. Still a delay but better than a hanging system. Currently we have at least two device drivers on s390 which under certain circumstances schedule a tasklet from process context. This is a reason why we can end up with pending softirqs when going idle. Fixing these drivers seems to be non-trivial. However there is no question that the drivers should be fixed. This patch shouldn't be considered as a bug fix. It just is intended to keep a system running even if device drivers are buggy. Signed-off-by: Heiko Carstens Cc: Jan Glauber Cc: Stefan Weinhuber Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index cb75394..86baa4f 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -235,6 +235,7 @@ void tick_nohz_stop_sched_tick(void) local_softirq_pending()); ratelimit++; } + goto end; } ts->idle_calls++; -- cgit v0.10.2 From 3d0decc4f49e8645cd6369b02ed076bebd3d61ad Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 11 Jul 2008 15:09:15 +0200 Subject: x86: fix tsc unification buglet with ftrace and stackprotector Yinghai Lu reported crashes on 64-bit x86: BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 IP: [] hrtick_start_fair+0x89/0x173 [...] And with a long session of debugging and a lot of difficulty, tracked it down to this commit: ---------------> 8fbbc4b45ce3e4c0eeb15004c79c72b6896a79c2 is first bad commit commit 8fbbc4b45ce3e4c0eeb15004c79c72b6896a79c2 Author: Alok Kataria Date: Tue Jul 1 11:43:34 2008 -0700 x86: merge tsc_init and clocksource code <-------------- The problem is that the TSC unification missed these Makefile rules in arch/x86/kernel/Makefile: # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_tsc_64.o = -pg CFLAGS_REMOVE_tsc_32.o = -pg ... CFLAGS_tsc_64.o := $(nostackp) ... which rules make sure that various instrumentation and debugging facilities are disabled for code that might end up in a VDSO - such as the TSC code. Reported-and-bisected-by: Yinghai Lu Signed-off-by: Ingo Molnar Conflicts: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 59b14c9..4033d8d 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -13,7 +13,7 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) CFLAGS_hpet.o := $(nostackp) -CFLAGS_tsc_64.o := $(nostackp) +CFLAGS_tsc.o := $(nostackp) obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o -- cgit v0.10.2 From 4abaca17e758e3326c96ced88b2cd9b7b84922f6 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Jul 2008 14:39:56 +0100 Subject: [GFS2] Fix GFS2's use of do_div() in its quota calculations Fix GFS2's need_sync()'s use of do_div() on an s64 by using div_s64() instead. This does assume that gt_quota_scale_den can be cast to an s32. This was introduced by patch b3b94faa5fe5968827ba0640ee9fba4b3e7f736e. Signed-off-by: David Howells Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 56aaf91..3e073f5 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -904,7 +904,7 @@ static int need_sync(struct gfs2_quota_data *qd) do_sync = 0; else { value *= gfs2_jindex_size(sdp) * num; - do_div(value, den); + value = div_s64(value, den); value += (s64)be64_to_cpu(qd->qd_qb.qb_value); if (value < (s64)be64_to_cpu(qd->qd_qb.qb_limit)) do_sync = 0; -- cgit v0.10.2 From 8d28aab59fe939be40efae870ced0b05caa259fb Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 10 Jul 2008 16:22:56 -0700 Subject: x86_64: add pseudo-features for 32-bit compat syscall Add pseudo-feature bits to describe whether the CPU supports sysenter and/or syscall from ia32-compat userspace. This removes a hardcoded test in vdso32-setup. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/centaur_64.c b/arch/x86/kernel/cpu/centaur_64.c index 13526fd..2026d21 100644 --- a/arch/x86/kernel/cpu/centaur_64.c +++ b/arch/x86/kernel/cpu/centaur_64.c @@ -10,6 +10,8 @@ static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) { if (c->x86 == 0x6 && c->x86_model >= 0xf) set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); + + set_cpu_cap(c, X86_FEATURE_SYSENTER32); } static void __cpuinit init_centaur(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index 7518502..36537ab 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c @@ -314,6 +314,9 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) if (c->extended_cpuid_level >= 0x80000007) c->x86_power = cpuid_edx(0x80000007); + /* Assume all 64-bit CPUs support 32-bit syscall */ + set_cpu_cap(c, X86_FEATURE_SYSCALL32); + if (c->x86_vendor != X86_VENDOR_UNKNOWN && cpu_devs[c->x86_vendor]->c_early_init) cpu_devs[c->x86_vendor]->c_early_init(c); diff --git a/arch/x86/kernel/cpu/intel_64.c b/arch/x86/kernel/cpu/intel_64.c index fcb1cc9..02f7733 100644 --- a/arch/x86/kernel/cpu/intel_64.c +++ b/arch/x86/kernel/cpu/intel_64.c @@ -12,6 +12,8 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); + + set_cpu_cap(c, X86_FEATURE_SYSENTER32); } /* diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 84a56da..75ef959 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -74,8 +74,8 @@ #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */ #define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ -/* 14 free */ -/* 15 free */ +#define X86_FEATURE_SYSCALL32 (3*32+14) /* syscall in ia32 userspace */ +#define X86_FEATURE_SYSENTER32 (3*32+15) /* sysenter in ia32 userspace */ #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ -- cgit v0.10.2 From b6ad92d4faade38619e89acc509ca1416b81a0bd Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 10 Jul 2008 18:13:36 -0700 Subject: x86_64: vdso32 cleanup using feature flags Use the X86_FEATURE_SYSENTER32 to remove hard-coded CPU vendor check. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index cf058fe..0bce542 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c @@ -203,20 +203,11 @@ static struct page *vdso32_pages[1]; #ifdef CONFIG_X86_64 -static int use_sysenter __read_mostly = -1; - -#define vdso32_sysenter() (use_sysenter > 0) +#define vdso32_sysenter() (boot_cpu_has(X86_FEATURE_SYSENTER32)) /* May not be __init: called during resume */ void syscall32_cpu_init(void) { - if (use_sysenter < 0) { - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - use_sysenter = 1; - if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) - use_sysenter = 1; - } - /* Load these always in case some future AMD CPU supports SYSENTER from compat mode too. */ checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); -- cgit v0.10.2 From 007c05d4d2ce42fabd58cb54ed98e0a1714d9d86 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:09 -0400 Subject: ftrace: move sched_switch enable after markers We have two markers now that are enabled on sched_switch. One that records the context switching and the other that records task wake ups. Currently we enable the tracing first and then set the markers. This causes some confusing traces: # tracer: sched_switch # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | trace-cmd-3973 [00] 115.834817: 3973:120:R + 3: 0:S trace-cmd-3973 [01] 115.834910: 3973:120:R + 6: 0:S trace-cmd-3973 [02] 115.834910: 3973:120:R + 9: 0:S trace-cmd-3973 [03] 115.834910: 3973:120:R + 12: 0:S trace-cmd-3973 [02] 115.834910: 3973:120:R + 9: 0:S -0 [02] 115.834910: 0:140:R ==> 3973:120:R Here we see that trace-cmd with PID 3973 wakes up task 9 but the next line shows the idle task doing a context switch to task 3973. Enabling the tracing to _after_ the markers are set creates a much saner output: # tracer: sched_switch # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | -0 [02] 7922.634225: 0:140:R ==> 4790:120:R trace-cmd-4789 [03] 7922.634225: 0:140:R + 4790:120:R Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 93a6620..cb817a2 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -227,14 +227,14 @@ void tracing_stop_cmdline_record(void) static void start_sched_trace(struct trace_array *tr) { sched_switch_reset(tr); - tracer_enabled = 1; tracing_start_cmdline_record(); + tracer_enabled = 1; } static void stop_sched_trace(struct trace_array *tr) { - tracing_stop_cmdline_record(); tracer_enabled = 0; + tracing_stop_cmdline_record(); } static void sched_switch_trace_init(struct trace_array *tr) -- cgit v0.10.2 From 001b6767b1d0c89e458e5ddb039245b268f569fb Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:10 -0400 Subject: ftrace: define function trace nop When CONFIG_FTRACE is not enabled, the tracing_start_functon_trace and tracing_stop_function_trace should be nops. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6b8bd88..df840f4 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -216,8 +216,6 @@ void trace_function(struct trace_array *tr, unsigned long parent_ip, unsigned long flags); -void tracing_start_function_trace(void); -void tracing_stop_function_trace(void); void tracing_start_cmdline_record(void); void tracing_stop_cmdline_record(void); int register_tracer(struct tracer *type); @@ -234,6 +232,14 @@ void update_max_tr_single(struct trace_array *tr, extern cycle_t ftrace_now(int cpu); +#ifdef CONFIG_FTRACE +void tracing_start_function_trace(void); +void tracing_stop_function_trace(void); +#else +# define tracing_start_function_trace() do { } while (0) +# define tracing_stop_function_trace() do { } while (0) +#endif + #ifdef CONFIG_CONTEXT_SWITCH_TRACER typedef void (*tracer_switch_func_t)(void *private, -- cgit v0.10.2 From 1e16c0a081f6c93f04c6af784d6a160955269f91 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:11 -0400 Subject: ftrace: trace schedule After the sched_clock code has been removed from sched.c we can now trace the scheduler. The scheduler has a lot of functions that would be worth tracing. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/Makefile b/kernel/Makefile index ca2433e..4809762 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -11,7 +11,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o -CFLAGS_REMOVE_sched.o = -pg -mno-spe +CFLAGS_REMOVE_sched.o = -mno-spe ifdef CONFIG_FTRACE # Do not trace debug files and internal ftrace files -- cgit v0.10.2 From b5c21b4514b38f450848feb432f7120376d01ffe Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:12 -0400 Subject: ftrace: check proper config for preempt type There is no CONFIG_PREEMPT_DESKTOP. Use the proper entry CONFIG_PREEMPT. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9ade793..f8fdb9c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1341,7 +1341,7 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) "server", #elif defined(CONFIG_PREEMPT_VOLUNTARY) "desktop", -#elif defined(CONFIG_PREEMPT_DESKTOP) +#elif defined(CONFIG_PREEMPT) "preempt", #else "unknown", -- cgit v0.10.2 From ad591240ceadcaf41b2a88855ca5f1c77c5a0298 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:13 -0400 Subject: ftrace: start wakeup tracing after setting function tracer Enabling the wakeup tracer before enabling the function tracing causes some strange results due to the dynamic enabling of the functions. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index bf7e91c..3c8d61d 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -352,9 +352,10 @@ static void start_wakeup_tracer(struct trace_array *tr) */ smp_wmb(); - tracer_enabled = 1; register_ftrace_function(&trace_ops); + tracer_enabled = 1; + return; fail_deprobe_wake_new: marker_probe_unregister("kernel_sched_wakeup_new", -- cgit v0.10.2 From 26bc83f4cb911a0b4dabfe23b700aaf3235f2955 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:14 -0400 Subject: ftrace: use current CPU for function startup This is more of a clean up. Currently the function tracer initializes the tracer with which ever CPU was last used for tracing. This value isn't realy useful for function tracing, but at least it should be something other than a random number. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 7ee7dcd..3121448 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -28,7 +28,10 @@ static void function_reset(struct trace_array *tr) static void start_function_trace(struct trace_array *tr) { + tr->cpu = get_cpu(); function_reset(tr); + put_cpu(); + tracing_start_cmdline_record(); tracing_start_function_trace(); } -- cgit v0.10.2 From a2bb6a3d85ef3124cd336403a95abc0540d3fbe2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:15 -0400 Subject: ftrace: add ftrace_kill_atomic It has been suggested that I add a way to disable the function tracer on an oops. This code adds a ftrace_kill_atomic. It is not meant to be used in normal situations. It will disable the ftrace tracer, but will not perform the nice shutdown that requires scheduling. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 3121b95..f368d04 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -89,6 +89,7 @@ void ftrace_enable_daemon(void); /* totally disable ftrace - can not re-enable after this */ void ftrace_kill(void); +void ftrace_kill_atomic(void); static inline void tracer_disable(void) { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 0f271c4..1359632 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1602,6 +1602,21 @@ core_initcall(ftrace_dynamic_init); #endif /* CONFIG_DYNAMIC_FTRACE */ /** + * ftrace_kill_atomic - kill ftrace from critical sections + * + * This function should be used by panic code. It stops ftrace + * but in a not so nice way. If you need to simply kill ftrace + * from a non-atomic section, use ftrace_kill. + */ +void ftrace_kill_atomic(void) +{ + ftrace_disabled = 1; + ftrace_enabled = 0; + ftraced_suspend = -1; + clear_ftrace_function(); +} + +/** * ftrace_kill - totally shutdown ftrace * * This is a safety measure. If something was detected that seems -- cgit v0.10.2 From 60bc080090e3bf6afa29c62cb25f913706551010 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Jul 2008 20:58:16 -0400 Subject: ftrace: separate out the function enabled variable Currently the function tracer uses the global tracer_enabled variable that is used to keep track if the tracer is enabled or not. The function tracing startup needs to be separated out, otherwise the internal happenings of the tracer startup is also recorded. This patch creates a ftrace_function_enabled variable to all the starting of the function traces to happen after everything has been started. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f8fdb9c..2e37857 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -96,6 +96,9 @@ static DEFINE_PER_CPU(struct trace_array_cpu, max_data); /* tracer_enabled is used to toggle activation of a tracer */ static int tracer_enabled = 1; +/* function tracing enabled */ +int ftrace_function_enabled; + /* * trace_nr_entries is the number of entries that is allocated * for a buffer. Note, the number of entries is always rounded @@ -134,6 +137,7 @@ static notrace void no_trace_init(struct trace_array *tr) { int cpu; + ftrace_function_enabled = 0; if(tr->ctrl) for_each_online_cpu(cpu) tracing_reset(tr->data[cpu]); @@ -985,7 +989,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip) long disabled; int cpu; - if (unlikely(!tracer_enabled)) + if (unlikely(!ftrace_function_enabled)) return; if (skip_trace(ip)) @@ -1010,11 +1014,15 @@ static struct ftrace_ops trace_ops __read_mostly = void tracing_start_function_trace(void) { + ftrace_function_enabled = 0; register_ftrace_function(&trace_ops); + if (tracer_enabled) + ftrace_function_enabled = 1; } void tracing_stop_function_trace(void) { + ftrace_function_enabled = 0; unregister_ftrace_function(&trace_ops); } #endif @@ -1850,8 +1858,10 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) m->private = iter; /* stop the trace while dumping */ - if (iter->tr->ctrl) + if (iter->tr->ctrl) { tracer_enabled = 0; + ftrace_function_enabled = 0; + } if (iter->trace && iter->trace->open) iter->trace->open(iter); @@ -1884,8 +1894,14 @@ int tracing_release(struct inode *inode, struct file *file) iter->trace->close(iter); /* reenable tracing if it was previously enabled */ - if (iter->tr->ctrl) + if (iter->tr->ctrl) { tracer_enabled = 1; + /* + * It is safe to enable function tracing even if it + * isn't used + */ + ftrace_function_enabled = 1; + } mutex_unlock(&trace_types_lock); seq_release(inode, file); -- cgit v0.10.2 From 62c43dd9864dbd52ff158922d1d08c75f20335af Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 14:16:50 -0400 Subject: sched_clock: record from last tick The sched_clock code tries to keep within the gtod time by one tick (jiffy). The current code mistakenly keeps track of the delta jiffies between updates of the clock, where the the delta is used to compare with the number of jiffies that have past since an update of the gtod. The gtod is updated at each schedule tick not each sched_clock update. After one jiffy passes the clock is updated fine. But the delta is taken from the last update so if the next update happens before the next tick the delta jiffies used will be incorrect. This patch changes the code to check the delta of jiffies between ticks and not updates to match the comparison of the updates with the gtod. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index ce05271..e383bc7 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -40,7 +40,7 @@ struct sched_clock_data { */ raw_spinlock_t lock; - unsigned long prev_jiffies; + unsigned long tick_jiffies; u64 prev_raw; u64 tick_raw; u64 tick_gtod; @@ -71,7 +71,7 @@ void sched_clock_init(void) struct sched_clock_data *scd = cpu_sdc(cpu); scd->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; - scd->prev_jiffies = now_jiffies; + scd->tick_jiffies = now_jiffies; scd->prev_raw = 0; scd->tick_raw = 0; scd->tick_gtod = ktime_now; @@ -90,7 +90,7 @@ void sched_clock_init(void) static void __update_sched_clock(struct sched_clock_data *scd, u64 now) { unsigned long now_jiffies = jiffies; - long delta_jiffies = now_jiffies - scd->prev_jiffies; + long delta_jiffies = now_jiffies - scd->tick_jiffies; u64 clock = scd->clock; u64 min_clock, max_clock; s64 delta = now - scd->prev_raw; @@ -119,7 +119,6 @@ static void __update_sched_clock(struct sched_clock_data *scd, u64 now) clock = min_clock; scd->prev_raw = now; - scd->prev_jiffies = now_jiffies; scd->clock = clock; } @@ -179,6 +178,7 @@ u64 sched_clock_cpu(int cpu) void sched_clock_tick(void) { struct sched_clock_data *scd = this_scd(); + unsigned long now_jiffies = jiffies; u64 now, now_gtod; if (unlikely(!sched_clock_running)) @@ -196,6 +196,7 @@ void sched_clock_tick(void) * already observe 1 new jiffy; adding a new tick_gtod to that would * increase the clock 2 jiffies. */ + scd->tick_jiffies = now_jiffies; scd->tick_raw = now; scd->tick_gtod = now_gtod; __raw_spin_unlock(&scd->lock); -- cgit v0.10.2 From f7cce27f5605b9e137b829a47949cb2d3c7e1cab Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 14:16:51 -0400 Subject: sched_clock: widen the max and min time With keeping the max and min sched time within one jiffy of the gtod clock was too tight. Just before a schedule tick the max could easily be hit, as well as just after a schedule_tick the min could be hit. This caused the clock to jump around by a jiffy. This patch widens the minimum to last gtod + (delta_jiffies ? delta_jiffies - 1 : 0) * TICK_NSECS and the maximum to last gtod + (2 + delta_jiffies) * TICK_NSECS This keeps the minum to gtod or if one jiffy less than delta jiffies and the maxim 2 jiffies ahead of gtod. This may cause unstable TSCs to be a bit more sporadic, but it helps keep a clock with a stable TSC working well. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index e383bc7..42b81fa 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -96,14 +96,21 @@ static void __update_sched_clock(struct sched_clock_data *scd, u64 now) s64 delta = now - scd->prev_raw; WARN_ON_ONCE(!irqs_disabled()); - min_clock = scd->tick_gtod + delta_jiffies * TICK_NSEC; + + min_clock = scd->tick_gtod + + (delta_jiffies ? delta_jiffies - 1 : 0) * TICK_NSEC; if (unlikely(delta < 0)) { clock++; goto out; } - max_clock = min_clock + TICK_NSEC; + /* + * The clock must stay within a jiffie of the gtod. + * But since we may be at the start of a jiffy or the end of one + * we add another jiffy buffer. + */ + max_clock = scd->tick_gtod + (2 + delta_jiffies) * TICK_NSEC; if (unlikely(clock + delta > max_clock)) { if (clock < max_clock) -- cgit v0.10.2 From af52a90a14cdaa54ecbfb6e6982abb13466a4b56 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 14:16:52 -0400 Subject: sched_clock: stop maximum check on NO HZ Working with ftrace I would get large jumps of 11 millisecs or more with the clock tracer. This killed the latencing timings of ftrace and also caused the irqoff self tests to fail. What was happening is with NO_HZ the idle would stop the jiffy counter and before the jiffy counter was updated the sched_clock would have a bad delta jiffies to compare with the gtod with the maximum. The jiffies would stop and the last sched_tick would record the last gtod. On wakeup, the sched clock update would compare the gtod + delta jiffies (which would be zero) and compare it to the TSC. The TSC would have correctly (with a stable TSC) moved forward several jiffies. But because the jiffies has not been updated yet the clock would be prevented from moving forward because it would appear that the TSC jumped too far ahead. The clock would then virtually stop, until the jiffies are updated. Then the next sched clock update would see that the clock was very much behind since the delta jiffies is now correct. This would then jump the clock forward by several jiffies. This caused ftrace to report several milliseconds of interrupts off latency at every resume from NO_HZ idle. This patch adds hooks into the nohz code to disable the checking of the maximum clock update when nohz is in effect. It resumes the max check when nohz has updated the jiffies again. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Signed-off-by: Ingo Molnar diff --git a/include/linux/sched.h b/include/linux/sched.h index c5d3f84..33a8f42 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1573,13 +1573,28 @@ static inline void sched_clock_idle_sleep_event(void) static inline void sched_clock_idle_wakeup_event(u64 delta_ns) { } -#else + +#ifdef CONFIG_NO_HZ +static inline void sched_clock_tick_stop(int cpu) +{ +} + +static inline void sched_clock_tick_start(int cpu) +{ +} +#endif + +#else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ extern void sched_clock_init(void); extern u64 sched_clock_cpu(int cpu); extern void sched_clock_tick(void); extern void sched_clock_idle_sleep_event(void); extern void sched_clock_idle_wakeup_event(u64 delta_ns); +#ifdef CONFIG_NO_HZ +extern void sched_clock_tick_stop(int cpu); +extern void sched_clock_tick_start(int cpu); #endif +#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ /* * For kernel-internal use: high-speed (but slightly incorrect) per-cpu diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 42b81fa..97159e2 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -45,6 +45,9 @@ struct sched_clock_data { u64 tick_raw; u64 tick_gtod; u64 clock; +#ifdef CONFIG_NO_HZ + int check_max; +#endif }; static DEFINE_PER_CPU_SHARED_ALIGNED(struct sched_clock_data, sched_clock_data); @@ -76,11 +79,45 @@ void sched_clock_init(void) scd->tick_raw = 0; scd->tick_gtod = ktime_now; scd->clock = ktime_now; +#ifdef CONFIG_NO_HZ + scd->check_max = 1; +#endif } sched_clock_running = 1; } +#ifdef CONFIG_NO_HZ +/* + * The dynamic ticks makes the delta jiffies inaccurate. This + * prevents us from checking the maximum time update. + * Disable the maximum check during stopped ticks. + */ +void sched_clock_tick_stop(int cpu) +{ + struct sched_clock_data *scd = cpu_sdc(cpu); + + scd->check_max = 0; +} + +void sched_clock_tick_start(int cpu) +{ + struct sched_clock_data *scd = cpu_sdc(cpu); + + scd->check_max = 1; +} + +static int check_max(struct sched_clock_data *scd) +{ + return scd->check_max; +} +#else +static int check_max(struct sched_clock_data *scd) +{ + return 1; +} +#endif /* CONFIG_NO_HZ */ + /* * update the percpu scd from the raw @now value * @@ -112,7 +149,7 @@ static void __update_sched_clock(struct sched_clock_data *scd, u64 now) */ max_clock = scd->tick_gtod + (2 + delta_jiffies) * TICK_NSEC; - if (unlikely(clock + delta > max_clock)) { + if (unlikely(clock + delta > max_clock) && check_max(scd)) { if (clock < max_clock) clock = max_clock; else diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index b854a89..d63008b 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -276,6 +276,7 @@ void tick_nohz_stop_sched_tick(void) ts->tick_stopped = 1; ts->idle_jiffies = last_jiffies; rcu_enter_nohz(); + sched_clock_tick_stop(cpu); } /* @@ -375,6 +376,7 @@ void tick_nohz_restart_sched_tick(void) select_nohz_load_balancer(0); now = ktime_get(); tick_do_update_jiffies64(now); + sched_clock_tick_start(cpu); cpu_clear(cpu, nohz_cpu_mask); /* -- cgit v0.10.2 From 2b8a0cf4890d7537a77b51caa8f508e4a05a0e67 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 7 Jul 2008 19:49:41 -0400 Subject: sched_clock: fix calculation of other CPU The algorithm to calculate the 'now' of another CPU is not correct. At each scheduler tick, each CPU records the last sched_clock and gtod (tick_raw and tick_gtod respectively). If the TSC is somewhat the same in speed between two clocks the algorithm would be: tick_gtod1 + (now1 - tick_raw1) = tick_gtod2 + (now2 - tick_raw2) To calculate now2 we would have: now2 = (tick_gtod1 - tick_gtod2) + (tick_raw2 - tick_raw1) + now1 Currently the algorithm is: now2 = (tick_gtod1 - tick_gtod2) + (tick_raw1 - tick_raw2) + now1 This solves most of the rest of the issues I've had with timestamps in ftace. Signed-off-by: Steven Rostedt Cc: Andrew Morton Cc: john stultz Cc: Peter Zijlstra Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 97159e2..55fca1e 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -203,8 +203,8 @@ u64 sched_clock_cpu(int cpu) now -= my_scd->tick_raw; now += scd->tick_raw; - now -= my_scd->tick_gtod; - now += scd->tick_gtod; + now += my_scd->tick_gtod; + now -= scd->tick_gtod; __raw_spin_unlock(&my_scd->lock); } else { -- cgit v0.10.2 From c0c87734f125d2fa8ebc70310f3257fa6209f2b6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 9 Jul 2008 00:15:31 -0400 Subject: sched_clock: only update deltas with local reads. Reading the CPU clock should try to stay accurate within the CPU. By reading the CPU clock from another CPU and updating the deltas can cause unneeded jumps when reading from the local CPU. This patch changes the code to update the last read TSC only when read from the local CPU. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Cc: john stultz Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 55fca1e..ee7cce5 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -124,7 +124,7 @@ static int check_max(struct sched_clock_data *scd) * - filter out backward motion * - use jiffies to generate a min,max window to clip the raw values */ -static void __update_sched_clock(struct sched_clock_data *scd, u64 now) +static void __update_sched_clock(struct sched_clock_data *scd, u64 now, u64 *time) { unsigned long now_jiffies = jiffies; long delta_jiffies = now_jiffies - scd->tick_jiffies; @@ -162,8 +162,12 @@ static void __update_sched_clock(struct sched_clock_data *scd, u64 now) if (unlikely(clock < min_clock)) clock = min_clock; - scd->prev_raw = now; - scd->clock = clock; + if (time) + *time = clock; + else { + scd->prev_raw = now; + scd->clock = clock; + } } static void lock_double_clock(struct sched_clock_data *data1, @@ -207,15 +211,18 @@ u64 sched_clock_cpu(int cpu) now -= scd->tick_gtod; __raw_spin_unlock(&my_scd->lock); + + __update_sched_clock(scd, now, &clock); + + __raw_spin_unlock(&scd->lock); + } else { __raw_spin_lock(&scd->lock); + __update_sched_clock(scd, now, NULL); + clock = scd->clock; + __raw_spin_unlock(&scd->lock); } - __update_sched_clock(scd, now); - clock = scd->clock; - - __raw_spin_unlock(&scd->lock); - return clock; } @@ -234,7 +241,7 @@ void sched_clock_tick(void) now_gtod = ktime_to_ns(ktime_get()); __raw_spin_lock(&scd->lock); - __update_sched_clock(scd, now); + __update_sched_clock(scd, now, NULL); /* * update tick_gtod after __update_sched_clock() because that will * already observe 1 new jiffy; adding a new tick_gtod to that would -- cgit v0.10.2 From a83bc47c33ab182f1e48977fd5a04024d713c75e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 9 Jul 2008 00:15:32 -0400 Subject: sched_clock: record TSC after gtod To read the gtod we need to grab the xtime lock for read. Reading the gtod before the TSC can cause a bigger gab if the xtime lock is contended. This patch simply reverses the order to read the TSC after the gtod. The locking in the reading of the gtod handles any barriers one might think is needed. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Cc: john stultz Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index ee7cce5..28ff6bf 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -237,8 +237,8 @@ void sched_clock_tick(void) WARN_ON_ONCE(!irqs_disabled()); - now = sched_clock(); now_gtod = ktime_to_ns(ktime_get()); + now = sched_clock(); __raw_spin_lock(&scd->lock); __update_sched_clock(scd, now, NULL); -- cgit v0.10.2 From c300ba252829e9325e08f0af60687add94445b25 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 9 Jul 2008 00:15:33 -0400 Subject: sched_clock: and multiplier for TSC to gtod drift The sched_clock code currently tries to keep all CPU clocks of all CPUS somewhat in sync. At every clock tick it records the gtod clock and uses that and jiffies and the TSC to calculate a CPU clock that tries to stay in sync with all the other CPUs. ftrace depends heavily on this timer and it detects when this timer "jumps". One problem is that the TSC and the gtod also drift. When the TSC is 0.1% faster or slower than the gtod it is very noticeable in ftrace. To help compensate for this, I've added a multiplier that tries to keep the CPU clock updating at the same rate as the gtod. I've tried various ways to get it to be in sync and this ended up being the most reliable. At every scheduler tick we calculate the new multiplier: multi = delta_gtod / delta_TSC This means we perform a 64 bit divide at the tick (once a HZ). A shift is used to handle the accuracy. Other methods that failed due to dynamic HZ are: (not used) multi += (gtod - tsc) / delta_gtod (not used) multi += (gtod - (last_tsc + delta_tsc)) / delta_gtod as well as other variants. This code still allows for a slight drift between TSC and gtod, but it keeps the damage down to a minimum. Signed-off-by: Steven Rostedt Cc: Steven Rostedt Cc: Peter Zijlstra Cc: Andrew Morton Cc: john stultz Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 28ff6bf..8affbfd 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -3,6 +3,9 @@ * * Copyright (C) 2008 Red Hat, Inc., Peter Zijlstra * + * Updates and enhancements: + * Copyright (C) 2008 Red Hat, Inc. Steven Rostedt + * * Based on code by: * Ingo Molnar * Guillaume Chazarain @@ -32,6 +35,11 @@ #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK +#define MULTI_SHIFT 15 +/* Max is double, Min is 1/2 */ +#define MAX_MULTI (2LL << MULTI_SHIFT) +#define MIN_MULTI (1LL << (MULTI_SHIFT-1)) + struct sched_clock_data { /* * Raw spinlock - this is a special case: this might be called @@ -45,6 +53,7 @@ struct sched_clock_data { u64 tick_raw; u64 tick_gtod; u64 clock; + s64 multi; #ifdef CONFIG_NO_HZ int check_max; #endif @@ -79,6 +88,7 @@ void sched_clock_init(void) scd->tick_raw = 0; scd->tick_gtod = ktime_now; scd->clock = ktime_now; + scd->multi = 1 << MULTI_SHIFT; #ifdef CONFIG_NO_HZ scd->check_max = 1; #endif @@ -134,8 +144,13 @@ static void __update_sched_clock(struct sched_clock_data *scd, u64 now, u64 *tim WARN_ON_ONCE(!irqs_disabled()); - min_clock = scd->tick_gtod + - (delta_jiffies ? delta_jiffies - 1 : 0) * TICK_NSEC; + /* + * At schedule tick the clock can be just under the gtod. We don't + * want to push it too prematurely. + */ + min_clock = scd->tick_gtod + (delta_jiffies * TICK_NSEC); + if (min_clock > TICK_NSEC) + min_clock -= TICK_NSEC / 2; if (unlikely(delta < 0)) { clock++; @@ -149,6 +164,9 @@ static void __update_sched_clock(struct sched_clock_data *scd, u64 now, u64 *tim */ max_clock = scd->tick_gtod + (2 + delta_jiffies) * TICK_NSEC; + delta *= scd->multi; + delta >>= MULTI_SHIFT; + if (unlikely(clock + delta > max_clock) && check_max(scd)) { if (clock < max_clock) clock = max_clock; @@ -230,6 +248,7 @@ void sched_clock_tick(void) { struct sched_clock_data *scd = this_scd(); unsigned long now_jiffies = jiffies; + s64 mult, delta_gtod, delta_raw; u64 now, now_gtod; if (unlikely(!sched_clock_running)) @@ -247,9 +266,23 @@ void sched_clock_tick(void) * already observe 1 new jiffy; adding a new tick_gtod to that would * increase the clock 2 jiffies. */ - scd->tick_jiffies = now_jiffies; + delta_gtod = now_gtod - scd->tick_gtod; + delta_raw = now - scd->tick_raw; + + if ((long)delta_raw > 0) { + mult = delta_gtod << MULTI_SHIFT; + do_div(mult, delta_raw); + scd->multi = mult; + if (scd->multi > MAX_MULTI) + scd->multi = MAX_MULTI; + else if (scd->multi < MIN_MULTI) + scd->multi = MIN_MULTI; + } else + scd->multi = 1 << MULTI_SHIFT; + scd->tick_raw = now; scd->tick_gtod = now_gtod; + scd->tick_jiffies = now_jiffies; __raw_spin_unlock(&scd->lock); } @@ -279,6 +312,7 @@ void sched_clock_idle_wakeup_event(u64 delta_ns) __raw_spin_lock(&scd->lock); scd->prev_raw = now; scd->clock += delta_ns; + scd->multi = 1 << MULTI_SHIFT; __raw_spin_unlock(&scd->lock); touch_softlockup_watchdog(); -- cgit v0.10.2 From b2613e370dbeb69edbff989382fa54f2395aa471 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 11 Jul 2008 16:44:27 +0200 Subject: ftrace: build fix for ftraced_suspend fix: kernel/trace/ftrace.c:1615: error: 'ftraced_suspend' undeclared (first use in this function) kernel/trace/ftrace.c:1615: error: (Each undeclared identifier is reported only once kernel/trace/ftrace.c:1615: error: for each function it appears in.) Signed-off-by: Ingo Molnar diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 1359632..4231a3d 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1612,7 +1612,9 @@ void ftrace_kill_atomic(void) { ftrace_disabled = 1; ftrace_enabled = 0; +#ifdef CONFIG_DYNAMIC_FTRACE ftraced_suspend = -1; +#endif clear_ftrace_function(); } -- cgit v0.10.2 From d9fc3fd3fab186447b5d2e7db3c2ee149064cc7c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 11 Jul 2008 19:41:19 +0200 Subject: x86: fix savesegment() bug causing crashes on 64-bit i spent a fair amount of time chasing a 64-bit bootup crash that manifested itself as bootup segfaults: S10network[1825]: segfault at 7f3e2b5d16b8 ip 00000031108748c9 sp 00007fffb9c14c70 error 4 in libc-2.7.so[3110800000+14d000] eventually causing init to die and panic the system: Kernel panic - not syncing: Attempted to kill init! Pid: 1, comm: init Not tainted 2.6.26-rc9-tip #13878 after a maratonic bisection session, the bad commit turned out to be: | b7675791859075418199c7af86a116ea34eaf5bd is first bad commit | commit b7675791859075418199c7af86a116ea34eaf5bd | Author: Jeremy Fitzhardinge | Date: Wed Jun 25 00:19:00 2008 -0400 | | x86: remove open-coded save/load segment operations | | This removes a pile of buggy open-coded implementations of savesegment | and loadsegment. after some more bisection of this patch itself, it turns out that what makes the difference are the savesegment() changes to __switch_to(). Taking a look at this portion of arch/x86/kernel/process_64.o revealed this crutial difference: | good: 99c: 8c e0 mov %fs,%eax | 99e: 89 45 cc mov %eax,-0x34(%rbp) | | bad: 99c: 8c 65 cc mov %fs,-0x34(%rbp) which is due to: | unsigned fsindex; | - asm volatile("movl %%fs,%0" : "=r" (fsindex)); | + savesegment(fs, fsindex); savesegment() is implemented as: #define savesegment(seg, value) \ asm("mov %%" #seg ",%0":"=rm" (value) : : "memory") note the "m" modifier - it allows GCC to generate the segment move into a memory operand as well. But regarding segment operands there's a subtle detail in the x86 instruction set: the above 16-bit moves are zero-extend, but only if it goes to a register. If it goes to a memory operand, -0x34(%rbp) in the above case, there's no zero-extend to 32-bit and the instruction will only save 16 bits instead of the intended 32-bit. The other 16 bits is random data - which can cause problems when that value is used later on. The solution is to only allow segment operands to go to registers. This fix allows my test-system to boot up without crashing. Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index c4946c5..983ce37 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -160,7 +160,7 @@ extern void native_load_gs_index(unsigned); * Save a segment register away */ #define savesegment(seg, value) \ - asm("mov %%" #seg ",%0":"=rm" (value) : : "memory") + asm("mov %%" #seg ",%0":"=r" (value) : : "memory") static inline unsigned long get_limit(unsigned long segment) { -- cgit v0.10.2 From 557d7d4e294ee6fb1db0cb6c1ec97a1c908b880d Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 10 Jul 2008 15:09:20 -0300 Subject: x86: use matching CFI_ENDPROC The RING0_INT_FRAME macro defines a CFI_STARTPROC. So we should really be using CFI_ENDPROC after it. Signed-off-by: Glauber Costa Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 53393c3..cfe28a7 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1024,6 +1024,7 @@ ENTRY(xen_sysenter_target) RING0_INT_FRAME addl $5*4, %esp /* remove xen-provided frame */ jmp sysenter_past_esp + CFI_ENDPROC ENTRY(xen_hypervisor_callback) CFI_STARTPROC -- cgit v0.10.2 From 70f1bba4c8ff88d7fd9e06f1b2cb2b3c58e8e5f9 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 10 Jul 2008 15:14:57 -0300 Subject: x86: use ignore macro instead of hash comment In dwarf_64.h header, use the "ignore" macro the way i386 does. Signed-off-by: Glauber Costa Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/dwarf2_64.h b/include/asm-x86/dwarf2_64.h index c950519..47776f4 100644 --- a/include/asm-x86/dwarf2_64.h +++ b/include/asm-x86/dwarf2_64.h @@ -35,21 +35,23 @@ #else -/* use assembler line comment character # to ignore the arguments. */ -#define CFI_STARTPROC # -#define CFI_ENDPROC # -#define CFI_DEF_CFA # -#define CFI_DEF_CFA_REGISTER # -#define CFI_DEF_CFA_OFFSET # -#define CFI_ADJUST_CFA_OFFSET # -#define CFI_OFFSET # -#define CFI_REL_OFFSET # -#define CFI_REGISTER # -#define CFI_RESTORE # -#define CFI_REMEMBER_STATE # -#define CFI_RESTORE_STATE # -#define CFI_UNDEFINED # -#define CFI_SIGNAL_FRAME # +.macro ignore a=0, b=0, c=0, d=0 +.endm + +#define CFI_STARTPROC ignore +#define CFI_ENDPROC ignore +#define CFI_DEF_CFA ignore +#define CFI_DEF_CFA_REGISTER ignore +#define CFI_DEF_CFA_OFFSET ignore +#define CFI_ADJUST_CFA_OFFSET ignore +#define CFI_OFFSET ignore +#define CFI_REL_OFFSET ignore +#define CFI_REGISTER ignore +#define CFI_RESTORE ignore +#define CFI_REMEMBER_STATE ignore +#define CFI_RESTORE_STATE ignore +#define CFI_UNDEFINED ignore +#define CFI_SIGNAL_FRAME ignore #endif -- cgit v0.10.2 From d73a731abe2a77fb54c5de4f72036b60ce3a048e Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 10 Jul 2008 15:17:53 -0300 Subject: x86: use AS_CFI instead of UNWIND_INFO In dwarf2_32.h, test for CONFIG_AS_CFI instead of CONFIG_UNWIND_INFO. Turns out that searching for UNWIND_INFO returns no match in any Kconfig or Makefile, so we're really just throwing everything away regarding dwarf frames for i386. The test that generates CONFIG_AS_CFI does not have anything x86_64-specific, and right now, checking V=1 builds shows me that the flags is there anyway, although unused. Signed-off-by: Glauber Costa Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/dwarf2_32.h b/include/asm-x86/dwarf2_32.h index 6d66398..0bfe250 100644 --- a/include/asm-x86/dwarf2_32.h +++ b/include/asm-x86/dwarf2_32.h @@ -12,7 +12,7 @@ away for older version. */ -#ifdef CONFIG_UNWIND_INFO +#ifdef CONFIG_AS_CFI #define CFI_STARTPROC .cfi_startproc #define CFI_ENDPROC .cfi_endproc -- cgit v0.10.2 From 392a0fc96bd059b38564f5f8fb58327460cb5a9d Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 11 Jul 2008 12:36:52 -0300 Subject: x86: merge dwarf2 headers Merge dwarf2_32.h and dwarf2_64.h into dwarf2.h. Signed-off-by: Glauber Costa Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h index b3cbb0c..0bfe250 100644 --- a/include/asm-x86/dwarf2.h +++ b/include/asm-x86/dwarf2.h @@ -1,5 +1,61 @@ -#ifdef CONFIG_X86_32 -# include "dwarf2_32.h" +#ifndef _DWARF2_H +#define _DWARF2_H + +#ifndef __ASSEMBLY__ +#warning "asm/dwarf2.h should be only included in pure assembly files" +#endif + +/* + Macros for dwarf2 CFI unwind table entries. + See "as.info" for details on these pseudo ops. Unfortunately + they are only supported in very new binutils, so define them + away for older version. + */ + +#ifdef CONFIG_AS_CFI + +#define CFI_STARTPROC .cfi_startproc +#define CFI_ENDPROC .cfi_endproc +#define CFI_DEF_CFA .cfi_def_cfa +#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register +#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset +#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset +#define CFI_OFFSET .cfi_offset +#define CFI_REL_OFFSET .cfi_rel_offset +#define CFI_REGISTER .cfi_register +#define CFI_RESTORE .cfi_restore +#define CFI_REMEMBER_STATE .cfi_remember_state +#define CFI_RESTORE_STATE .cfi_restore_state +#define CFI_UNDEFINED .cfi_undefined + +#ifdef CONFIG_AS_CFI_SIGNAL_FRAME +#define CFI_SIGNAL_FRAME .cfi_signal_frame +#else +#define CFI_SIGNAL_FRAME +#endif + #else -# include "dwarf2_64.h" + +/* Due to the structure of pre-exisiting code, don't use assembler line + comment character # to ignore the arguments. Instead, use a dummy macro. */ +.macro ignore a=0, b=0, c=0, d=0 +.endm + +#define CFI_STARTPROC ignore +#define CFI_ENDPROC ignore +#define CFI_DEF_CFA ignore +#define CFI_DEF_CFA_REGISTER ignore +#define CFI_DEF_CFA_OFFSET ignore +#define CFI_ADJUST_CFA_OFFSET ignore +#define CFI_OFFSET ignore +#define CFI_REL_OFFSET ignore +#define CFI_REGISTER ignore +#define CFI_RESTORE ignore +#define CFI_REMEMBER_STATE ignore +#define CFI_RESTORE_STATE ignore +#define CFI_UNDEFINED ignore +#define CFI_SIGNAL_FRAME ignore + +#endif + #endif diff --git a/include/asm-x86/dwarf2_32.h b/include/asm-x86/dwarf2_32.h deleted file mode 100644 index 0bfe250..0000000 --- a/include/asm-x86/dwarf2_32.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _DWARF2_H -#define _DWARF2_H - -#ifndef __ASSEMBLY__ -#warning "asm/dwarf2.h should be only included in pure assembly files" -#endif - -/* - Macros for dwarf2 CFI unwind table entries. - See "as.info" for details on these pseudo ops. Unfortunately - they are only supported in very new binutils, so define them - away for older version. - */ - -#ifdef CONFIG_AS_CFI - -#define CFI_STARTPROC .cfi_startproc -#define CFI_ENDPROC .cfi_endproc -#define CFI_DEF_CFA .cfi_def_cfa -#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register -#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset -#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset -#define CFI_OFFSET .cfi_offset -#define CFI_REL_OFFSET .cfi_rel_offset -#define CFI_REGISTER .cfi_register -#define CFI_RESTORE .cfi_restore -#define CFI_REMEMBER_STATE .cfi_remember_state -#define CFI_RESTORE_STATE .cfi_restore_state -#define CFI_UNDEFINED .cfi_undefined - -#ifdef CONFIG_AS_CFI_SIGNAL_FRAME -#define CFI_SIGNAL_FRAME .cfi_signal_frame -#else -#define CFI_SIGNAL_FRAME -#endif - -#else - -/* Due to the structure of pre-exisiting code, don't use assembler line - comment character # to ignore the arguments. Instead, use a dummy macro. */ -.macro ignore a=0, b=0, c=0, d=0 -.endm - -#define CFI_STARTPROC ignore -#define CFI_ENDPROC ignore -#define CFI_DEF_CFA ignore -#define CFI_DEF_CFA_REGISTER ignore -#define CFI_DEF_CFA_OFFSET ignore -#define CFI_ADJUST_CFA_OFFSET ignore -#define CFI_OFFSET ignore -#define CFI_REL_OFFSET ignore -#define CFI_REGISTER ignore -#define CFI_RESTORE ignore -#define CFI_REMEMBER_STATE ignore -#define CFI_RESTORE_STATE ignore -#define CFI_UNDEFINED ignore -#define CFI_SIGNAL_FRAME ignore - -#endif - -#endif diff --git a/include/asm-x86/dwarf2_64.h b/include/asm-x86/dwarf2_64.h deleted file mode 100644 index 47776f4..0000000 --- a/include/asm-x86/dwarf2_64.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _DWARF2_H -#define _DWARF2_H 1 - -#ifndef __ASSEMBLY__ -#warning "asm/dwarf2.h should be only included in pure assembly files" -#endif - -/* - Macros for dwarf2 CFI unwind table entries. - See "as.info" for details on these pseudo ops. Unfortunately - they are only supported in very new binutils, so define them - away for older version. - */ - -#ifdef CONFIG_AS_CFI - -#define CFI_STARTPROC .cfi_startproc -#define CFI_ENDPROC .cfi_endproc -#define CFI_DEF_CFA .cfi_def_cfa -#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register -#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset -#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset -#define CFI_OFFSET .cfi_offset -#define CFI_REL_OFFSET .cfi_rel_offset -#define CFI_REGISTER .cfi_register -#define CFI_RESTORE .cfi_restore -#define CFI_REMEMBER_STATE .cfi_remember_state -#define CFI_RESTORE_STATE .cfi_restore_state -#define CFI_UNDEFINED .cfi_undefined -#ifdef CONFIG_AS_CFI_SIGNAL_FRAME -#define CFI_SIGNAL_FRAME .cfi_signal_frame -#else -#define CFI_SIGNAL_FRAME -#endif - -#else - -.macro ignore a=0, b=0, c=0, d=0 -.endm - -#define CFI_STARTPROC ignore -#define CFI_ENDPROC ignore -#define CFI_DEF_CFA ignore -#define CFI_DEF_CFA_REGISTER ignore -#define CFI_DEF_CFA_OFFSET ignore -#define CFI_ADJUST_CFA_OFFSET ignore -#define CFI_OFFSET ignore -#define CFI_REL_OFFSET ignore -#define CFI_REGISTER ignore -#define CFI_RESTORE ignore -#define CFI_REMEMBER_STATE ignore -#define CFI_RESTORE_STATE ignore -#define CFI_UNDEFINED ignore -#define CFI_SIGNAL_FRAME ignore - -#endif - -#endif -- cgit v0.10.2 From 1baea6e2fea6f235b21f32a322cb6cb43ffdb704 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 11 Jul 2008 19:34:36 +0100 Subject: x86: L-APIC: Set IRQ0 as edge-triggered IRQ0 is edge-triggered, but the "8259A Virtual Wire" through the local APIC configuration in the 32-bit version uses the "fasteoi" handler suitable for level-triggered APIC interrupt. Rewrite code so that the "edge" handler is used. The 64-bit version uses different code and is unaffected. Signed-off-by: Maciej W. Rozycki Cc: "Rafael J. Wysocki" Cc: Matthew Garrett Cc: Andreas Herrmann Cc: Stephen Rothwell Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 6b220b9..50e1131 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -2052,7 +2052,7 @@ static struct irq_chip lapic_chip __read_mostly = { .name = "local-APIC", .mask = mask_lapic_irq, .unmask = unmask_lapic_irq, - .eoi = ack_apic, + .ack = ack_apic, }; static void __init setup_nmi(void) @@ -2257,8 +2257,8 @@ static inline void __init check_timer(void) printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); - set_irq_chip_and_handler_name(0, &lapic_chip, handle_fasteoi_irq, - "fasteoi"); + set_irq_chip_and_handler_name(0, &lapic_chip, handle_edge_irq, + "edge"); apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(0); -- cgit v0.10.2 From c88ac1df4885ce0d762cfeff0e7d5b83725c1e5c Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 11 Jul 2008 19:35:17 +0100 Subject: x86: L-APIC: Always fully configure IRQ0 Unlike the 32-bit one, the 64-bit variation of the LVT0 setup code for the "8259A Virtual Wire" through the local APIC timer configuration does not fully configure the relevant irq_chip structure. Instead it relies on the preceding I/O APIC code to have set it up, which does not happen if the I/O APIC variants have not been tried. The patch includes corresponding changes to the 32-bit variation too which make them both the same, barring a small syntactic difference involving sequence of functions in the source. That should work as an aid with the upcoming merge. Signed-off-by: Maciej W. Rozycki Cc: "Rafael J. Wysocki" Cc: Matthew Garrett Cc: Andreas Herrmann Cc: Stephen Rothwell Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 50e1131..74d49e0 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -2027,7 +2027,7 @@ static inline void init_IO_APIC_traps(void) * The local APIC irq-chip implementation: */ -static void ack_apic(unsigned int irq) +static void ack_lapic_irq(unsigned int irq) { ack_APIC_irq(); } @@ -2052,9 +2052,17 @@ static struct irq_chip lapic_chip __read_mostly = { .name = "local-APIC", .mask = mask_lapic_irq, .unmask = unmask_lapic_irq, - .ack = ack_apic, + .ack = ack_lapic_irq, }; +static void lapic_register_intr(int irq, int vector) +{ + irq_desc[irq].status &= ~IRQ_LEVEL; + set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, + "edge"); + set_intr_gate(vector, interrupt[irq]); +} + static void __init setup_nmi(void) { /* @@ -2257,8 +2265,7 @@ static inline void __init check_timer(void) printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); - set_irq_chip_and_handler_name(0, &lapic_chip, handle_edge_irq, - "edge"); + lapic_register_intr(0, vector); apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(0); diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 8484117..07ebcd3 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -1561,7 +1561,7 @@ static inline void init_IO_APIC_traps(void) } } -static void enable_lapic_irq (unsigned int irq) +static void unmask_lapic_irq(unsigned int irq) { unsigned long v; @@ -1569,7 +1569,7 @@ static void enable_lapic_irq (unsigned int irq) apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); } -static void disable_lapic_irq (unsigned int irq) +static void mask_lapic_irq(unsigned int irq) { unsigned long v; @@ -1582,19 +1582,20 @@ static void ack_lapic_irq (unsigned int irq) ack_APIC_irq(); } -static void end_lapic_irq (unsigned int i) { /* nothing */ } - -static struct hw_interrupt_type lapic_irq_type __read_mostly = { - .name = "local-APIC", - .typename = "local-APIC-edge", - .startup = NULL, /* startup_irq() not used for IRQ0 */ - .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ - .enable = enable_lapic_irq, - .disable = disable_lapic_irq, - .ack = ack_lapic_irq, - .end = end_lapic_irq, +static struct irq_chip lapic_chip __read_mostly = { + .name = "local-APIC", + .mask = mask_lapic_irq, + .unmask = unmask_lapic_irq, + .ack = ack_lapic_irq, }; +static void lapic_register_intr(int irq) +{ + irq_desc[irq].status &= ~IRQ_LEVEL; + set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, + "edge"); +} + static void __init setup_nmi(void) { /* @@ -1784,7 +1785,7 @@ static inline void __init check_timer(void) apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); - irq_desc[0].chip = &lapic_irq_type; + lapic_register_intr(0); apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ enable_8259A_irq(0); -- cgit v0.10.2 From af174783b9251f0afd4bb78927221bcaaa65d3ac Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 11 Jul 2008 19:35:23 +0100 Subject: x86: I/O APIC: Never configure IRQ2 There is no such entity as ISA IRQ2. The ACPI spec does not make it explicitly clear, but does not preclude it either -- all it says is ISA legacy interrupts are identity mapped by default (subject to overrides), but it does not state whether IRQ2 exists or not. As a result if there is no IRQ0 override, then IRQ2 is normally initialised as an ISA interrupt, which implies an edge-triggered line, which is unmasked by default as this is what we do for edge-triggered I/O APIC interrupts so as not to miss an edge. To the best of my knowledge it is useless, as IRQ2 has not been in use since the PC/AT as back then it was taken by the 8259A cascade interrupt to the slave, with the line position in the slot rerouted to newly-created IRQ9. No device could thus make use of this line with the pair of 8259A chips. Now in theory INTIN2 of the I/O APIC may be usable, but the interrupt of the device wired to it would not be available in the PIC mode at all, so I seriously doubt if anybody decided to reuse it for a regular device. However there are two common uses of INTIN2. One is for IRQ0, with an ACPI interrupt override (or its equivalent in the MP table). But in this case IRQ2 is gone entirely with INTIN0 left vacant. The other one is for an 8959A ExtINTA cascade. In this case IRQ0 goes to INTIN0 and if ACPI is used INTIN2 is assumed to be IRQ2 (there is no override and ACPI has no way to report ExtINTA interrupts). This is where a problem happens. The problem is INTIN2 is configured as a native APIC interrupt, with a vector assigned and the mask cleared. And the line may indeed get active and inject interrupts if the master 8959A has its timer interrupt enabled (it might happen for other interrupts too, but they are normally masked in the process of rerouting them to the I/O APIC). There are two cases where it will happen: * When the I/O APIC NMI watchdog is enabled. This is actually a misnomer as the watchdog pulses are delivered through the 8259A to the LINT0 inputs of all the local APICs in the system. The implication is the output of the master 8259A goes high and low repeatedly, signalling interrupts to INTIN2 which is enabled too! [The origin of the name is I think for a brief period during the development we had a capability in our code to configure the watchdog to use an I/O APIC input; that would be INTIN2 in this scenario.] * When the native route of IRQ0 via INTIN0 fails for whatever reason -- as it happens with the system considered here. In this scenario the timer pulse is delivered through the 8259A to LINT0 input of the local APIC of the bootstrap processor, quite similarly to how is done for the watchdog described above. The result is, again, INTIN2 receives these pulses too. Rafael's system used to escape this scenario, because an incorrect IRQ0 override would occupy INTIN2 and prevent it from being unmasked. My conclusion is IRQ2 should be excluded from configuration in all the cases and the current exception for ACPI systems should be lifted. The reason being the exception not only being useless, but harmful as well. Signed-off-by: Maciej W. Rozycki Cc: "Rafael J. Wysocki" Cc: Matthew Garrett Cc: Andreas Herrmann Cc: Stephen Rothwell Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 74d49e0..c50adb8 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -2297,11 +2297,21 @@ out: } /* - * - * IRQ's that are handled by the PIC in the MPS IOAPIC case. - * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ. - * Linux doesn't really care, as it's not actually used - * for any interrupt handling anyway. + * Traditionally ISA IRQ2 is the cascade IRQ, and is not available + * to devices. However there may be an I/O APIC pin available for + * this interrupt regardless. The pin may be left unconnected, but + * typically it will be reused as an ExtINT cascade interrupt for + * the master 8259A. In the MPS case such a pin will normally be + * reported as an ExtINT interrupt in the MP table. With ACPI + * there is no provision for ExtINT interrupts, and in the absence + * of an override it would be treated as an ordinary ISA I/O APIC + * interrupt, that is edge-triggered and unmasked by default. We + * used to do this, but it caused problems on some systems because + * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using + * the same ExtINT cascade interrupt to drive the local APIC of the + * bootstrap processor. Therefore we refrain from routing IRQ2 to + * the I/O APIC in all cases now. No actual device should request + * it anyway. --macro */ #define PIC_IRQS (1 << PIC_CASCADE_IR) @@ -2315,10 +2325,7 @@ void __init setup_IO_APIC(void) enable_IO_APIC(); - if (acpi_ioapic) - io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ - else - io_apic_irqs = ~PIC_IRQS; + io_apic_irqs = ~PIC_IRQS; printk("ENABLING IO-APIC IRQs\n"); diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 07ebcd3..9e645cb 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -1823,11 +1823,21 @@ static int __init notimercheck(char *s) __setup("no_timer_check", notimercheck); /* - * - * IRQs that are handled by the PIC in the MPS IOAPIC case. - * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ. - * Linux doesn't really care, as it's not actually used - * for any interrupt handling anyway. + * Traditionally ISA IRQ2 is the cascade IRQ, and is not available + * to devices. However there may be an I/O APIC pin available for + * this interrupt regardless. The pin may be left unconnected, but + * typically it will be reused as an ExtINT cascade interrupt for + * the master 8259A. In the MPS case such a pin will normally be + * reported as an ExtINT interrupt in the MP table. With ACPI + * there is no provision for ExtINT interrupts, and in the absence + * of an override it would be treated as an ordinary ISA I/O APIC + * interrupt, that is edge-triggered and unmasked by default. We + * used to do this, but it caused problems on some systems because + * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using + * the same ExtINT cascade interrupt to drive the local APIC of the + * bootstrap processor. Therefore we refrain from routing IRQ2 to + * the I/O APIC in all cases now. No actual device should request + * it anyway. --macro */ #define PIC_IRQS (1<<2) @@ -1838,10 +1848,7 @@ void __init setup_IO_APIC(void) * calling enable_IO_APIC() is moved to setup_local_APIC for BP */ - if (acpi_ioapic) - io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ - else - io_apic_irqs = ~PIC_IRQS; + io_apic_irqs = ~PIC_IRQS; apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); -- cgit v0.10.2 From 5b4d2386c23e5de553fce002892c7691a989b350 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 11 Jul 2008 19:47:15 +0100 Subject: x86: Recover timer_ack lost in the merge of the NMI watchdog In the course of the recent unification of the NMI watchdog an assignment to timer_ack to switch off unnecesary POLL commands to the 8259A in the case of a watchdog failure has been accidentally removed. The statement used to be limited to the 32-bit variation as since the rewrite of the timer code it has been relevant for the 82489DX only. This change brings it back. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 8dfe9db..716b892 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -171,6 +171,9 @@ int __init check_nmi_watchdog(void) error: if (nmi_watchdog == NMI_IO_APIC && !timer_through_8259) disable_8259A_irq(0); +#ifdef CONFIG_X86_32 + timer_ack = 0; +#endif return -1; } -- cgit v0.10.2 From feae1ef116ed381625d3731c5ae4f4ebcb3fa302 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 11 Jul 2008 13:54:40 -0700 Subject: IB/umad: BKL is not needed for ib_umad_open() Remove explicit lock_kernel() calls and document why the code is safe. Signed-off-by: Roland Dreier Signed-off-by: Jonathan Corbet diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 1fc1794..ef6dd82 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -47,7 +47,6 @@ #include #include #include -#include #include @@ -778,23 +777,33 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd, } #endif +/* + * ib_umad_open() does not need the BKL: + * + * - umad_port[] accesses are protected by port_lock, the + * ib_umad_port structures are properly reference counted, and + * everything else is purely local to the file being created, so + * races against other open calls are not a problem; + * - the ioctl method does not affect any global state outside of the + * file structure being operated on; + * - the port is added to umad_port[] as the last part of module + * initialization so the open method will either immediately run + * -ENXIO, or all required initialization will be done. + */ static int ib_umad_open(struct inode *inode, struct file *filp) { struct ib_umad_port *port; struct ib_umad_file *file; int ret = 0; - lock_kernel(); spin_lock(&port_lock); port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; if (port) kref_get(&port->umad_dev->ref); spin_unlock(&port_lock); - if (!port) { - unlock_kernel(); + if (!port) return -ENXIO; - } mutex_lock(&port->file_mutex); @@ -823,7 +832,6 @@ static int ib_umad_open(struct inode *inode, struct file *filp) out: mutex_unlock(&port->file_mutex); - unlock_kernel(); return ret; } -- cgit v0.10.2 From 91ef4caf800030fa6e5224b8a41f8c74787b303d Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: handle corrupted orphan list at mount If the orphan node list includes valid, untruncatable nodes with nlink > 0 the ext4_orphan_cleanup loop which attempts to delete them will not do so, causing it to loop forever. Fix by checking for such nodes in the ext4_orphan_get function. This patch fixes the second case (image hdb.20000009.softlockup.gz) reported in http://bugzilla.kernel.org/show_bug.cgi?id=10882. Signed-off-by: Duane Griffin Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8158083..f7a0758 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1039,6 +1039,7 @@ extern void ext4_discard_reservation (struct inode *); extern void ext4_dirty_inode(struct inode *); extern int ext4_change_inode_journal_flag(struct inode *, int); extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); +extern int ext4_can_truncate(struct inode *inode); extern void ext4_truncate (struct inode *); extern void ext4_set_inode_flags(struct inode *); extern void ext4_get_inode_flags(struct ext4_inode_info *); diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index c6efbab..11cafe1 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -817,6 +817,14 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) if (IS_ERR(inode)) goto iget_failed; + /* + * If the orphans has i_nlinks > 0 then it should be able to be + * truncated, otherwise it won't be removed from the orphan list + * during processing and an infinite loop will result. + */ + if (inode->i_nlink && !ext4_can_truncate(inode)) + goto bad_orphan; + if (NEXT_ORPHAN(inode) > max_ino) goto bad_orphan; brelse(bitmap_bh); @@ -838,6 +846,7 @@ bad_orphan: printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", NEXT_ORPHAN(inode)); printk(KERN_NOTICE "max_ino=%lu\n", max_ino); + printk(KERN_NOTICE "i_nlink=%u\n", inode->i_nlink); /* Avoid freeing blocks if we got a bad deleted inode */ if (inode->i_nlink == 0) inode->i_blocks = 0; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8d97077..269763b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2305,6 +2305,19 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode, } } +int ext4_can_truncate(struct inode *inode) +{ + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + return 0; + if (S_ISREG(inode->i_mode)) + return 1; + if (S_ISDIR(inode->i_mode)) + return 1; + if (S_ISLNK(inode->i_mode)) + return !ext4_inode_is_fast_symlink(inode); + return 0; +} + /* * ext4_truncate() * @@ -2349,12 +2362,7 @@ void ext4_truncate(struct inode *inode) unsigned blocksize = inode->i_sb->s_blocksize; struct page *page; - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; - if (ext4_inode_is_fast_symlink(inode)) - return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + if (!ext4_can_truncate(inode)) return; /* -- cgit v0.10.2 From 71dc8fbcf5f6363342bd636a646eeac7cfef25c3 Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: handle deleting corrupted indirect blocks While freeing indirect blocks we attach a journal head to the parent buffer head, free the blocks, then journal the parent. If the indirect block list is corrupted and points to the parent the journal head will be detached when the block is cleared, causing an OOPS. Check for that explicitly and handle it gracefully. This patch fixes the third case (image hdb.20000057.nullderef.gz) reported in http://bugzilla.kernel.org/show_bug.cgi?id=10882. Signed-off-by: Duane Griffin Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 269763b..7cce96a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2179,7 +2179,21 @@ static void ext4_free_data(handle_t *handle, struct inode *inode, if (this_bh) { BUFFER_TRACE(this_bh, "call ext4_journal_dirty_metadata"); - ext4_journal_dirty_metadata(handle, this_bh); + + /* + * The buffer head should have an attached journal head at this + * point. However, if the data is corrupted and an indirect + * block pointed to itself, it would have been detached when + * the block was cleared. Check for this instead of OOPSing. + */ + if (bh2jh(this_bh)) + ext4_journal_dirty_metadata(handle, this_bh); + else + ext4_error(inode->i_sb, __func__, + "circular indirect block detected, " + "inode=%lu, block=%llu", + inode->i_ino, + (unsigned long long) this_bh->b_blocknr); } } -- cgit v0.10.2 From f3b35f063e9a795495fe2f7a2fe55fab11f8ab12 Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: validate directory entry data before use ext4_dx_find_entry uses ext4_next_entry without verifying that the entry is valid. If its rec_len == 0 this causes an infinite loop. Refactor the loop to check the validity of entries before checking whether they match and moving onto the next one. There are other uses of ext4_next_entry in this file which also look problematic. They should be reviewed and fixed if/when we have a test-case that triggers them. This patch fixes the first case (image hdb.25.softlockup.gz) reported in http://bugzilla.kernel.org/show_bug.cgi?id=10882. Signed-off-by: Duane Griffin Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index ab16bea..384f122 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -993,19 +993,21 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, de = (struct ext4_dir_entry_2 *) bh->b_data; top = (struct ext4_dir_entry_2 *) ((char *) de + sb->s_blocksize - EXT4_DIR_REC_LEN(0)); - for (; de < top; de = ext4_next_entry(de)) - if (ext4_match (namelen, name, de)) { - if (!ext4_check_dir_entry("ext4_find_entry", - dir, de, bh, - (block<b_data))) { - brelse (bh); + for (; de < top; de = ext4_next_entry(de)) { + int off = (block << EXT4_BLOCK_SIZE_BITS(sb)) + + ((char *) de - bh->b_data); + + if (!ext4_check_dir_entry(__func__, dir, de, bh, off)) { + brelse(bh); *err = ERR_BAD_DX_DIR; goto errout; } - *res_dir = de; - dx_release (frames); - return bh; + + if (ext4_match(namelen, name, de)) { + *res_dir = de; + dx_release(frames); + return bh; + } } brelse (bh); /* Check to see if we should continue to search */ -- cgit v0.10.2 From e7dfb2463e3c1b10c38372023e0186d25dec1fa6 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Fix mb_find_next_bit not to return larger than max Some architectures implement ext4_find_next_bit and ext4_find_next_zero_bit in such a way that they return greater than max for some input values. Make sure mb_find_next_bit and mb_find_next_zero_bit return the right values. On 2.6.25 we have include/asm-x86/bitops_32.h static inline unsigned find_first_bit(const unsigned long *addr, unsigned size) { unsigned x = 0; while (x < size) { unsigned long val = *addr++; if (val) return __ffs(val) + x; x += (sizeof(*addr)<<3); } return x; } This can return value greater than size. Reported and fixed here for lustre https://bugzilla.lustre.org/show_bug.cgi?id=15932 https://bugzilla.lustre.org/attachment.cgi?id=17205 Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index c9900aa..ba3aad2 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -381,22 +381,28 @@ static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) static inline int mb_find_next_zero_bit(void *addr, int max, int start) { - int fix = 0; + int fix = 0, ret, tmpmax; addr = mb_correct_addr_and_bit(&fix, addr); - max += fix; + tmpmax = max + fix; start += fix; - return ext4_find_next_zero_bit(addr, max, start) - fix; + ret = ext4_find_next_zero_bit(addr, tmpmax, start) - fix; + if (ret > max) + return max; + return ret; } static inline int mb_find_next_bit(void *addr, int max, int start) { - int fix = 0; + int fix = 0, ret, tmpmax; addr = mb_correct_addr_and_bit(&fix, addr); - max += fix; + tmpmax = max + fix; start += fix; - return ext4_find_next_bit(addr, max, start) - fix; + ret = ext4_find_next_bit(addr, tmpmax, start) - fix; + if (ret > max) + return max; + return ret; } static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) @@ -3473,8 +3479,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, if (bit >= end) break; next = mb_find_next_bit(bitmap_bh->b_data, end, bit); - if (next > end) - next = end; start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + le32_to_cpu(sbi->s_es->s_first_data_block); mb_debug(" free preallocated %u/%u in group %u\n", -- cgit v0.10.2 From 8a35694e1181a5c6d6496dca09407fc7fa4c86c2 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: fix comments to say "ext4" Change second/third to fourth. Signed-off-by: Shen Feng Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f7a0758..ea8e4bc 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -22,7 +22,7 @@ #include "ext4_i.h" /* - * The second extended filesystem constants/structures + * The fourth extended filesystem constants/structures */ /* diff --git a/fs/ext4/ext4_i.h b/fs/ext4/ext4_i.h index 26a4ae2..abf2744 100644 --- a/fs/ext4/ext4_i.h +++ b/fs/ext4/ext4_i.h @@ -79,7 +79,7 @@ struct ext4_ext_cache { }; /* - * third extended file system inode data in memory + * fourth extended file system inode data in memory */ struct ext4_inode_info { __le32 i_data[15]; /* unconverted */ diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h index 5802e69..4de9a75 100644 --- a/fs/ext4/ext4_sb.h +++ b/fs/ext4/ext4_sb.h @@ -25,7 +25,7 @@ #include /* - * third extended-fs super-block data in memory + * fourth extended-fs super-block data in memory */ struct ext4_sb_info { unsigned long s_desc_size; /* Size of a group descriptor in bytes */ -- cgit v0.10.2 From ed8f9c751feb3aebf7c0dd25e61481a16412bd6e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: start searching for the right extent from the goal group. With mballoc we search for the best extent using different criteria. We should always use the goal group when we are starting with a new criteria. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index ba3aad2..bdb9f29 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1736,10 +1736,6 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) ac->ac_g_ex.fe_start = sbi->s_mb_last_start; spin_unlock(&sbi->s_md_lock); } - - /* searching for the right group start from the goal value specified */ - group = ac->ac_g_ex.fe_group; - /* Let's just scan groups to find more-less suitable blocks */ cr = ac->ac_2order ? 0 : 1; /* @@ -1749,6 +1745,12 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) repeat: for (; cr < 4 && ac->ac_status == AC_STATUS_CONTINUE; cr++) { ac->ac_criteria = cr; + /* + * searching for the right group start + * from the goal value specified + */ + group = ac->ac_g_ex.fe_group; + for (i = 0; i < EXT4_SB(sb)->s_groups_count; group++, i++) { struct ext4_group_info *grp; struct ext4_group_desc *desc; -- cgit v0.10.2 From 07d45f126712fea3a9f44068bf65e0a26a162286 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Use BUG_ON() instead of BUG() if (...) BUG(); should be replaced with BUG_ON(...) when the test has no side-effects to allow a definition of BUG_ON that drops the code completely. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @ disable unlikely @ expression E,f; @@ ( if (<... f(...) ...>) { BUG(); } | - if (unlikely(E)) { BUG(); } + BUG_ON(E); ) @@ expression E,f; @@ ( if (<... f(...) ...>) { BUG(); } | - if (E) { BUG(); } + BUG_ON(E); ) // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 9cc80b9..c29d774 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -409,8 +409,7 @@ restart: prev = rsv; } printk("Window map complete.\n"); - if (bad) - BUG(); + BUG_ON(bad); } #define rsv_window_dump(root, verbose) \ __rsv_window_dump((root), (verbose), __func__) -- cgit v0.10.2 From 91d99827791fdd5f9424458ad5ae870f89dbcadf Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: switch to seq_files Signed-off-by: Alexey Dobriyan Cc: Mingming Cao Signed-off-by: "Theodore Ts'o" Signed-off-by: Andrew Morton diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index bdb9f29..6280ad3 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2583,25 +2583,24 @@ ext4_mb_free_committed_blocks(struct super_block *sb) -#define MB_PROC_VALUE_READ(name) \ -static int ext4_mb_read_##name(char *page, char **start, \ - off_t off, int count, int *eof, void *data) \ +#define MB_PROC_FOPS(name) \ +static int ext4_mb_##name##_proc_show(struct seq_file *m, void *v) \ { \ - struct ext4_sb_info *sbi = data; \ - int len; \ - *eof = 1; \ - if (off != 0) \ - return 0; \ - len = sprintf(page, "%ld\n", sbi->s_mb_##name); \ - *start = page; \ - return len; \ -} - -#define MB_PROC_VALUE_WRITE(name) \ -static int ext4_mb_write_##name(struct file *file, \ - const char __user *buf, unsigned long cnt, void *data) \ + struct ext4_sb_info *sbi = m->private; \ + \ + seq_printf(m, "%ld\n", sbi->s_mb_##name); \ + return 0; \ +} \ + \ +static int ext4_mb_##name##_proc_open(struct inode *inode, struct file *file)\ +{ \ + return single_open(file, ext4_mb_##name##_proc_show, PDE(inode)->data);\ +} \ + \ +static ssize_t ext4_mb_##name##_proc_write(struct file *file, \ + const char __user *buf, size_t cnt, loff_t *ppos) \ { \ - struct ext4_sb_info *sbi = data; \ + struct ext4_sb_info *sbi = PDE(file->f_path.dentry->d_inode)->data;\ char str[32]; \ long value; \ if (cnt >= sizeof(str)) \ @@ -2613,31 +2612,32 @@ static int ext4_mb_write_##name(struct file *file, \ return -ERANGE; \ sbi->s_mb_##name = value; \ return cnt; \ -} +} \ + \ +static const struct file_operations ext4_mb_##name##_proc_fops = { \ + .owner = THIS_MODULE, \ + .open = ext4_mb_##name##_proc_open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + .write = ext4_mb_##name##_proc_write, \ +}; -MB_PROC_VALUE_READ(stats); -MB_PROC_VALUE_WRITE(stats); -MB_PROC_VALUE_READ(max_to_scan); -MB_PROC_VALUE_WRITE(max_to_scan); -MB_PROC_VALUE_READ(min_to_scan); -MB_PROC_VALUE_WRITE(min_to_scan); -MB_PROC_VALUE_READ(order2_reqs); -MB_PROC_VALUE_WRITE(order2_reqs); -MB_PROC_VALUE_READ(stream_request); -MB_PROC_VALUE_WRITE(stream_request); -MB_PROC_VALUE_READ(group_prealloc); -MB_PROC_VALUE_WRITE(group_prealloc); +MB_PROC_FOPS(stats); +MB_PROC_FOPS(max_to_scan); +MB_PROC_FOPS(min_to_scan); +MB_PROC_FOPS(order2_reqs); +MB_PROC_FOPS(stream_request); +MB_PROC_FOPS(group_prealloc); #define MB_PROC_HANDLER(name, var) \ do { \ - proc = create_proc_entry(name, mode, sbi->s_mb_proc); \ + proc = proc_create_data(name, mode, sbi->s_mb_proc, \ + &ext4_mb_##var##_proc_fops, sbi); \ if (proc == NULL) { \ printk(KERN_ERR "EXT4-fs: can't to create %s\n", name); \ goto err_out; \ } \ - proc->data = sbi; \ - proc->read_proc = ext4_mb_read_##var ; \ - proc->write_proc = ext4_mb_write_##var; \ } while (0) static int ext4_mb_init_per_dev_proc(struct super_block *sb) -- cgit v0.10.2 From 69baee062a044ef1588e423e52131710e7584d1a Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: improve some code in rb tree part of dir.c * remove unnecessary code in free_rb_tree_fname * rename free_rb_tree_fname to ext4_htree_create_dir_info since it and ext4_htree_free_dir_info are a pair * replace kmalloc with kzalloc in ext4_htree_free_dir_info All these make the code more readable and simple. PS: this patch is also suitable for ext3. Signed-off-by: Shen Feng Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 2bf0331..5ed5108 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -272,7 +272,7 @@ static void free_rb_tree_fname(struct rb_root *root) while (n) { /* Do the node's children first */ - if ((n)->rb_left) { + if (n->rb_left) { n = n->rb_left; continue; } @@ -301,24 +301,18 @@ static void free_rb_tree_fname(struct rb_root *root) parent->rb_right = NULL; n = parent; } - root->rb_node = NULL; } -static struct dir_private_info *create_dir_info(loff_t pos) +static struct dir_private_info *ext4_htree_create_dir_info(loff_t pos) { struct dir_private_info *p; - p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL); + p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL); if (!p) return NULL; - p->root.rb_node = NULL; - p->curr_node = NULL; - p->extra_fname = NULL; - p->last_pos = 0; p->curr_hash = pos2maj_hash(pos); p->curr_minor_hash = pos2min_hash(pos); - p->next_hash = 0; return p; } @@ -433,7 +427,7 @@ static int ext4_dx_readdir(struct file * filp, int ret; if (!info) { - info = create_dir_info(filp->f_pos); + info = ext4_htree_create_dir_info(filp->f_pos); if (!info) return -ENOMEM; filp->private_data = info; -- cgit v0.10.2 From 31b481dc7c249eac0a108ec5dfc0d4aef2217e39 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Fix ext4_mb_init_cache return error ext4_mb_init_cache() incorrectly always return EIO on success. This causes the caller of ext4_mb_init_cache() fail when it checks the return value. Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6280ad3..d429014 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -809,6 +809,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) if (!buffer_uptodate(bh[i])) goto out; + err = 0; first_block = page->index * blocks_per_page; for (i = 0; i < blocks_per_page; i++) { int group; -- cgit v0.10.2 From fdf6c7a7683c6272e953a33358920e98a4d93cf0 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: add error processing when calling ext4_mb_init_cache in mballoc Add error processing for ext4_mb_load_buddy when it calls ext4_mb_init_cache. Signed-off-by: Shen Feng Reviewed-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index d429014..b64600b 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -890,6 +890,7 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, int pnum; int poff; struct page *page; + int ret; mb_debug("load group %lu\n", group); @@ -921,15 +922,21 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, if (page) { BUG_ON(page->mapping != inode->i_mapping); if (!PageUptodate(page)) { - ext4_mb_init_cache(page, NULL); + ret = ext4_mb_init_cache(page, NULL); + if (ret) { + unlock_page(page); + goto err; + } mb_cmp_bitmaps(e4b, page_address(page) + (poff * sb->s_blocksize)); } unlock_page(page); } } - if (page == NULL || !PageUptodate(page)) + if (page == NULL || !PageUptodate(page)) { + ret = -EIO; goto err; + } e4b->bd_bitmap_page = page; e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize); mark_page_accessed(page); @@ -945,14 +952,20 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); if (page) { BUG_ON(page->mapping != inode->i_mapping); - if (!PageUptodate(page)) - ext4_mb_init_cache(page, e4b->bd_bitmap); - + if (!PageUptodate(page)) { + ret = ext4_mb_init_cache(page, e4b->bd_bitmap); + if (ret) { + unlock_page(page); + goto err; + } + } unlock_page(page); } } - if (page == NULL || !PageUptodate(page)) + if (page == NULL || !PageUptodate(page)) { + ret = -EIO; goto err; + } e4b->bd_buddy_page = page; e4b->bd_buddy = page_address(page) + (poff * sb->s_blocksize); mark_page_accessed(page); @@ -969,7 +982,7 @@ err: page_cache_release(e4b->bd_buddy_page); e4b->bd_buddy = NULL; e4b->bd_bitmap = NULL; - return -EIO; + return ret; } static void ext4_mb_release_desc(struct ext4_buddy *e4b) -- cgit v0.10.2 From 74767c5a2dca0a60676d60d36377a41f60ca42ba Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: miscellaneous error checks and coding cleanups for mballoc ext4_mb_seq_history_open(): check if sbi->s_mb_history is NULL ext4_mb_history_init(): replace kmalloc and memset with kzalloc ext4_mb_init_backend(): remove memset since kzalloc is used ext4_mb_init(): the return value of ext4_mb_init_backend is int, but i is unsigned, replace it with a new int variable. Signed-off-by: Shen Feng Reviewed-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b64600b..6d69dd9 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1985,6 +1985,8 @@ static int ext4_mb_seq_history_open(struct inode *inode, struct file *file) int rc; int size; + if (unlikely(sbi->s_mb_history == NULL)) + return -ENOMEM; s = kmalloc(sizeof(*s), GFP_KERNEL); if (s == NULL) return -ENOMEM; @@ -2187,9 +2189,7 @@ static void ext4_mb_history_init(struct super_block *sb) sbi->s_mb_history_cur = 0; spin_lock_init(&sbi->s_mb_history_lock); i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); - sbi->s_mb_history = kmalloc(i, GFP_KERNEL); - if (likely(sbi->s_mb_history != NULL)) - memset(sbi->s_mb_history, 0, i); + sbi->s_mb_history = kzalloc(i, GFP_KERNEL); /* if we can't allocate history, then we simple won't use it */ } @@ -2303,7 +2303,6 @@ static int ext4_mb_init_backend(struct super_block *sb) i++; goto err_freebuddy; } - memset(meta_group_info[j], 0, len); set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(meta_group_info[j]->bb_state)); @@ -2358,6 +2357,7 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) unsigned i; unsigned offset; unsigned max; + int ret; if (!test_opt(sb, MBALLOC)) return 0; @@ -2392,12 +2392,12 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) } while (i <= sb->s_blocksize_bits + 1); /* init file for buddy data */ - i = ext4_mb_init_backend(sb); - if (i) { + ret = ext4_mb_init_backend(sb); + if (ret != 0) { clear_opt(sbi->s_mount_opt, MBALLOC); kfree(sbi->s_mb_offsets); kfree(sbi->s_mb_maxs); - return i; + return ret; } spin_lock_init(&sbi->s_md_lock); -- cgit v0.10.2 From 3537576a707c6df98e883b77b854c6083f844602 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: remove double definitions of xattr macros remove the definitions of macros XATTR_TRUSTED_PREFIX and XATTR_USER_PREFIX since they are defined in linux/xattr.h Signed-off-by: Shen Feng Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index fff3338..ac1a52c 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c @@ -13,13 +13,11 @@ #include "ext4.h" #include "xattr.h" -#define XATTR_TRUSTED_PREFIX "trusted." - static size_t ext4_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, const char *name, size_t name_len) { - const size_t prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1; + const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; const size_t total_len = prefix_len + name_len + 1; if (!capable(CAP_SYS_ADMIN)) diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index 67be723..d91aa61 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c @@ -12,13 +12,11 @@ #include "ext4.h" #include "xattr.h" -#define XATTR_USER_PREFIX "user." - static size_t ext4_xattr_user_list(struct inode *inode, char *list, size_t list_size, const char *name, size_t name_len) { - const size_t prefix_len = sizeof(XATTR_USER_PREFIX)-1; + const size_t prefix_len = XATTR_USER_PREFIX_LEN; const size_t total_len = prefix_len + name_len + 1; if (!test_opt(inode->i_sb, XATTR_USER)) -- cgit v0.10.2 From 574ca174c97f790086e3e6f2251381420ad38fd0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Rename read_block_bitmap() to ext4_read_block_bitmap() Since this a non-static function, make it be ext4 specific to avoid conflicts with potentially other filesystems. Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index c29d774..ba41123 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -295,7 +295,7 @@ err_out: return 0; } /** - * read_block_bitmap() + * ext4_read_block_bitmap() * @sb: super block * @block_group: given block group * @@ -305,7 +305,7 @@ err_out: * Return buffer_head on success or NULL in case of failure. */ struct buffer_head * -read_block_bitmap(struct super_block *sb, ext4_group_t block_group) +ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) { struct ext4_group_desc * desc; struct buffer_head * bh = NULL; @@ -693,7 +693,7 @@ do_more: count -= overflow; } brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, block_group); + bitmap_bh = ext4_read_block_bitmap(sb, block_group); if (!bitmap_bh) goto error_return; desc = ext4_get_group_desc (sb, block_group, &gd_bh); @@ -1733,7 +1733,7 @@ retry_alloc: my_rsv = NULL; if (free_blocks > 0) { - bitmap_bh = read_block_bitmap(sb, group_no); + bitmap_bh = ext4_read_block_bitmap(sb, group_no); if (!bitmap_bh) goto io_error; grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle, @@ -1769,7 +1769,7 @@ retry_alloc: continue; brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, group_no); + bitmap_bh = ext4_read_block_bitmap(sb, group_no); if (!bitmap_bh) goto io_error; /* @@ -1985,7 +1985,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) continue; desc_count += le16_to_cpu(gdp->bg_free_blocks_count); brelse(bitmap_bh); - bitmap_bh = read_block_bitmap(sb, i); + bitmap_bh = ext4_read_block_bitmap(sb, i); if (bitmap_bh == NULL) continue; diff --git a/fs/ext4/group.h b/fs/ext4/group.h index 7eb0604..c2c0a8d 100644 --- a/fs/ext4/group.h +++ b/fs/ext4/group.h @@ -13,7 +13,7 @@ extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group, struct ext4_group_desc *gdp); extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group, struct ext4_group_desc *gdp); -struct buffer_head *read_block_bitmap(struct super_block *sb, +struct buffer_head *ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group); extern unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 11cafe1..b30cc79b 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -600,7 +600,7 @@ got: /* We may have to initialize the block bitmap if it isn't already */ if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - struct buffer_head *block_bh = read_block_bitmap(sb, group); + struct buffer_head *block_bh = ext4_read_block_bitmap(sb, group); BUFFER_TRACE(block_bh, "get block bitmap access"); err = ext4_journal_get_write_access(handle, block_bh); diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6d69dd9..21ee6d4 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2326,7 +2326,7 @@ static int ext4_mb_init_backend(struct super_block *sb) meta_group_info[j]->bb_bitmap = kmalloc(sb->s_blocksize, GFP_KERNEL); BUG_ON(meta_group_info[j]->bb_bitmap == NULL); - bh = read_block_bitmap(sb, i); + bh = ext4_read_block_bitmap(sb, i); BUG_ON(bh == NULL); memcpy(meta_group_info[j]->bb_bitmap, bh->b_data, sb->s_blocksize); @@ -2769,7 +2769,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, err = -EIO; - bitmap_bh = read_block_bitmap(sb, ac->ac_b_ex.fe_group); + bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group); if (!bitmap_bh) goto out_err; @@ -3589,7 +3589,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, if (list_empty(&grp->bb_prealloc_list)) return 0; - bitmap_bh = read_block_bitmap(sb, group); + bitmap_bh = ext4_read_block_bitmap(sb, group); if (bitmap_bh == NULL) { /* error handling here */ ext4_mb_release_desc(&e4b); @@ -3763,7 +3763,7 @@ repeat: err = ext4_mb_load_buddy(sb, group, &e4b); BUG_ON(err != 0); /* error handling here */ - bitmap_bh = read_block_bitmap(sb, group); + bitmap_bh = ext4_read_block_bitmap(sb, group); if (bitmap_bh == NULL) { /* error handling here */ ext4_mb_release_desc(&e4b); @@ -4262,7 +4262,7 @@ do_more: overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb); count -= overflow; } - bitmap_bh = read_block_bitmap(sb, block_group); + bitmap_bh = ext4_read_block_bitmap(sb, block_group); if (!bitmap_bh) goto error_return; gdp = ext4_get_group_desc(sb, block_group, &gd_bh); -- cgit v0.10.2 From 7ad72ca60b6be3c79f90a81ce5883e12a2c6e667 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Remove unused variable from ext4_show_options Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 02bf243..588cfb4 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -671,7 +671,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) unsigned long def_mount_opts; struct super_block *sb = vfs->mnt_sb; struct ext4_sb_info *sbi = EXT4_SB(sb); - journal_t *journal = sbi->s_journal; struct ext4_super_block *es = sbi->s_es; def_mount_opts = le32_to_cpu(es->s_default_mount_opts); -- cgit v0.10.2 From f795e1407343ebe6597653f4a6a7f770676e84c5 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: fix build failure if DX_DEBUG is enabled ext4_next_entry() is used by the debugging function dx_show_leaf(), so it must be defined before that function. Signed-off-by: Li Zefan Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 384f122..c7bf012 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -183,6 +183,16 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, struct inode *inode); /* + * p is at least 6 bytes before the end of page + */ +static inline struct ext4_dir_entry_2 * +ext4_next_entry(struct ext4_dir_entry_2 *p) +{ + return (struct ext4_dir_entry_2 *)((char *)p + + ext4_rec_len_from_disk(p->rec_len)); +} + +/* * Future: use high four bits of block for coalesce-on-delete flags * Mask them off for now. */ @@ -554,15 +564,6 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash, /* - * p is at least 6 bytes before the end of page - */ -static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p) -{ - return (struct ext4_dir_entry_2 *)((char *)p + - ext4_rec_len_from_disk(p->rec_len)); -} - -/* * This function fills a red-black tree with information from a * directory block. It returns the number directory entries loaded * into the tree. If there is an error it is returned in err. -- cgit v0.10.2 From cfbe7e4f5e4a0e1fc2ff23b167bfb3fa992f623d Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Sun, 13 Jul 2008 21:03:31 -0400 Subject: ext4: error proc entry creation when the fs/ext4 is not correctly created When the directory fs/ext4 is not correctly created under proc, the entry under this directory should not be created. Signed-off-by: Shen Feng Signed-off-by: Andrew Morton Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 21ee6d4..771a1d6 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2661,6 +2661,10 @@ static int ext4_mb_init_per_dev_proc(struct super_block *sb) struct proc_dir_entry *proc; char devname[64]; + if (proc_root_ext4 == NULL) { + sbi->s_mb_proc = NULL; + return -EINVAL; + } bdevname(sb->s_bdev, devname); sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4); -- cgit v0.10.2 From 7e5a8cdd843b7af8d6d38a9bf96306145edb66e0 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Sun, 13 Jul 2008 21:03:31 -0400 Subject: ext4: fix error processing in mb_free_blocks The error processing of the return value of mb_free_blocks is meanless because it only returns 0. This fix includes - make mb_free_blocks return void - remove the error processing part in callers - unlock group before calling ext4_error in mb_free_blocks Signed-off-by: Shen Feng Cc: Mingming Cao Cc: Theodore Ts'o Signed-off-by: Andrew Morton Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 771a1d6..b882868 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1051,7 +1051,7 @@ static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len) } } -static int mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, +static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, int first, int count) { int block = 0; @@ -1091,11 +1091,12 @@ static int mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, blocknr += block; blocknr += le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); - + ext4_unlock_group(sb, e4b->bd_group); ext4_error(sb, __func__, "double-free of inode" " %lu's block %llu(bit %u in group %lu)\n", inode ? inode->i_ino : 0, blocknr, block, e4b->bd_group); + ext4_lock_group(sb, e4b->bd_group); } mb_clear_bit(block, EXT4_MB_BITMAP(e4b)); e4b->bd_info->bb_counters[order]++; @@ -1133,8 +1134,6 @@ static int mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, } while (1); } mb_check_buddy(e4b); - - return 0; } static int mb_find_extent(struct ext4_buddy *e4b, int order, int block, @@ -2570,8 +2569,7 @@ ext4_mb_free_committed_blocks(struct super_block *sb) ext4_lock_group(sb, md->group); for (i = 0; i < md->num; i++) { mb_debug(" %u", md->blocks[i]); - err = mb_free_blocks(NULL, &e4b, md->blocks[i], 1); - BUG_ON(err != 0); + mb_free_blocks(NULL, &e4b, md->blocks[i], 1); } mb_debug("\n"); ext4_unlock_group(sb, md->group); @@ -4333,10 +4331,9 @@ do_more: ext4_mb_free_metadata(handle, &e4b, block_group, bit, count); } else { ext4_lock_group(sb, block_group); - err = mb_free_blocks(inode, &e4b, bit, count); + mb_free_blocks(inode, &e4b, bit, count); ext4_mb_return_to_preallocation(inode, &e4b, block, count); ext4_unlock_group(sb, block_group); - BUG_ON(err != 0); } spin_lock(sb_bgl_lock(sbi, block_group)); -- cgit v0.10.2 From 4db9c54a53135b7c1c1f403f1aeaf9fc0d7738b8 Mon Sep 17 00:00:00 2001 From: Stoyan Gaydarov Date: Sun, 13 Jul 2008 21:03:29 -0400 Subject: ext4: replace __FUNCTION__ occurrences __FUNCTION__ is gcc-specific, use __func__ instead Signed-off-by: Stoyan Gaydarov Cc: Theodore Ts'o Cc: Mingming Cao Signed-off-by: Andrew Morton Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ea8e4bc..109c7d4 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -45,7 +45,7 @@ #define ext4_debug(f, a...) \ do { \ printk (KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ + __FILE__, __LINE__, __func__); \ printk (KERN_DEBUG f, ## a); \ } while (0) #else @@ -1163,7 +1163,7 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb, #define ext4_std_error(sb, errno) \ do { \ if ((errno)) \ - __ext4_std_error((sb), __FUNCTION__, (errno)); \ + __ext4_std_error((sb), __func__, (errno)); \ } while (0) /* diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index 9255a7d2..d0aa9ee 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h @@ -142,17 +142,17 @@ int __ext4_journal_dirty_metadata(const char *where, handle_t *handle, struct buffer_head *bh); #define ext4_journal_get_undo_access(handle, bh) \ - __ext4_journal_get_undo_access(__FUNCTION__, (handle), (bh)) + __ext4_journal_get_undo_access(__func__, (handle), (bh)) #define ext4_journal_get_write_access(handle, bh) \ - __ext4_journal_get_write_access(__FUNCTION__, (handle), (bh)) + __ext4_journal_get_write_access(__func__, (handle), (bh)) #define ext4_journal_revoke(handle, blocknr, bh) \ - __ext4_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh)) + __ext4_journal_revoke(__func__, (handle), (blocknr), (bh)) #define ext4_journal_get_create_access(handle, bh) \ - __ext4_journal_get_create_access(__FUNCTION__, (handle), (bh)) + __ext4_journal_get_create_access(__func__, (handle), (bh)) #define ext4_journal_dirty_metadata(handle, bh) \ - __ext4_journal_dirty_metadata(__FUNCTION__, (handle), (bh)) + __ext4_journal_dirty_metadata(__func__, (handle), (bh)) #define ext4_journal_forget(handle, bh) \ - __ext4_journal_forget(__FUNCTION__, (handle), (bh)) + __ext4_journal_forget(__func__, (handle), (bh)) int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh); @@ -165,7 +165,7 @@ static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks) } #define ext4_journal_stop(handle) \ - __ext4_journal_stop(__FUNCTION__, (handle)) + __ext4_journal_stop(__func__, (handle)) static inline handle_t *ext4_journal_current_handle(void) { -- cgit v0.10.2 From 736603ab297506f4396cb5af592004499950fcfd Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: jbd2: Add commit time into the commit block Carlo Wood has demonstrated that it's possible to recover deleted files from the journal. Something that will make this easier is if we can put the time of the commit into commit block. Signed-off-by: "Theodore Ts'o" diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index a2ed72f..92b6ac3 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -112,6 +112,7 @@ static int journal_submit_commit_record(journal_t *journal, struct buffer_head *bh; int ret; int barrier_done = 0; + struct timespec now = current_kernel_time(); if (is_journal_aborted(journal)) return 0; @@ -126,6 +127,8 @@ static int journal_submit_commit_record(journal_t *journal, tmp->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); tmp->h_blocktype = cpu_to_be32(JBD2_COMMIT_BLOCK); tmp->h_sequence = cpu_to_be32(commit_transaction->t_tid); + tmp->h_commit_sec = cpu_to_be64(now.tv_sec); + tmp->h_commit_nsec = cpu_to_be32(now.tv_nsec); if (JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) { diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index d147f0f..ec9cadf 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -168,6 +168,8 @@ struct commit_header { unsigned char h_chksum_size; unsigned char h_padding[2]; __be32 h_chksum[JBD2_CHECKSUM_BYTES]; + __be64 h_commit_sec; + __be32 h_commit_nsec; }; /* -- cgit v0.10.2 From 772cb7c83ba256a11c7bf99a11bef3858d23767c Mon Sep 17 00:00:00 2001 From: "Jose R. Santos" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: New inode allocation for FLEX_BG meta-data groups. This patch mostly controls the way inode are allocated in order to make ialloc aware of flex_bg block group grouping. It achieves this by bypassing the Orlov allocator when block group meta-data are packed toghether through mke2fs. Since the impact on the block allocator is minimal, this patch should have little or no effect on other block allocation algorithms. By controlling the inode allocation, it can basically control where the initial search for new block begins and thus indirectly manipulate the block allocator. This allocator favors data and meta-data locality so the disk will gradually be filled from block group zero upward. This helps improve performance by reducing seek time. Since the group of inode tables within one flex_bg are treated as one giant inode table, uninitialized block groups would not need to partially initialize as many inode table as with Orlov which would help fsck time as the filesystem usage goes up. Signed-off-by: Jose R. Santos Signed-off-by: Valerie Clement Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index ba41123..0b2b754 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -809,6 +809,13 @@ do_more: spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_add(&sbi->s_freeblocks_counter, count); + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); + spin_lock(sb_bgl_lock(sbi, flex_group)); + sbi->s_flex_groups[flex_group].free_blocks += count; + spin_unlock(sb_bgl_lock(sbi, flex_group)); + } + /* We dirtied the bitmap block */ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); err = ext4_journal_dirty_metadata(handle, bitmap_bh); @@ -1883,6 +1890,13 @@ allocated: spin_unlock(sb_bgl_lock(sbi, group_no)); percpu_counter_sub(&sbi->s_freeblocks_counter, num); + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, group_no); + spin_lock(sb_bgl_lock(sbi, flex_group)); + sbi->s_flex_groups[flex_group].free_blocks -= num; + spin_unlock(sb_bgl_lock(sbi, flex_group)); + } + BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor"); err = ext4_journal_dirty_metadata(handle, gdp_bh); if (!fatal) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 109c7d4..0bfeae1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -170,6 +170,15 @@ struct ext4_group_desc __u32 bg_reserved2[3]; }; +/* + * Structure of a flex block group info + */ + +struct flex_groups { + __u32 free_inodes; + __u32 free_blocks; +}; + #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ #define EXT4_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */ #define EXT4_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */ @@ -647,7 +656,10 @@ struct ext4_super_block { __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ __le64 s_mmp_block; /* Block for multi-mount protection */ __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ - __u32 s_reserved[163]; /* Padding to the end of the block */ + __u8 s_log_groups_per_flex; /* FLEX_BG group size */ + __u8 s_reserved_char_pad2; + __le16 s_reserved_pad; + __u32 s_reserved[162]; /* Padding to the end of the block */ }; #ifdef __KERNEL__ @@ -1160,6 +1172,17 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb, } +static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi, + ext4_group_t block_group) +{ + return block_group >> sbi->s_log_groups_per_flex; +} + +static inline unsigned int ext4_flex_bg_size(struct ext4_sb_info *sbi) +{ + return 1 << sbi->s_log_groups_per_flex; +} + #define ext4_std_error(sb, errno) \ do { \ if ((errno)) \ diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h index 4de9a75..6300226 100644 --- a/fs/ext4/ext4_sb.h +++ b/fs/ext4/ext4_sb.h @@ -143,6 +143,9 @@ struct ext4_sb_info { /* locality groups */ struct ext4_locality_group *s_locality_groups; + + unsigned int s_log_groups_per_flex; + struct flex_groups *s_flex_groups; }; #endif /* _EXT4_SB */ diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index b30cc79b..8b0a10a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -157,6 +157,7 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) struct ext4_super_block * es; struct ext4_sb_info *sbi; int fatal = 0, err; + ext4_group_t flex_group; if (atomic_read(&inode->i_count) > 1) { printk ("ext4_free_inode: inode has count=%d\n", @@ -232,6 +233,12 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) if (is_directory) percpu_counter_dec(&sbi->s_dirs_counter); + if (sbi->s_log_groups_per_flex) { + flex_group = ext4_flex_group(sbi, block_group); + spin_lock(sb_bgl_lock(sbi, flex_group)); + sbi->s_flex_groups[flex_group].free_inodes++; + spin_unlock(sb_bgl_lock(sbi, flex_group)); + } } BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); err = ext4_journal_dirty_metadata(handle, bh2); @@ -286,6 +293,80 @@ static int find_group_dir(struct super_block *sb, struct inode *parent, return ret; } +#define free_block_ratio 10 + +static int find_group_flex(struct super_block *sb, struct inode *parent, + ext4_group_t *best_group) +{ + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_group_desc *desc; + struct buffer_head *bh; + struct flex_groups *flex_group = sbi->s_flex_groups; + ext4_group_t parent_group = EXT4_I(parent)->i_block_group; + ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group); + ext4_group_t ngroups = sbi->s_groups_count; + int flex_size = ext4_flex_bg_size(sbi); + ext4_group_t best_flex = parent_fbg_group; + int blocks_per_flex = sbi->s_blocks_per_group * flex_size; + int flexbg_free_blocks; + int flex_freeb_ratio; + ext4_group_t n_fbg_groups; + ext4_group_t i; + + n_fbg_groups = (sbi->s_groups_count + flex_size - 1) >> + sbi->s_log_groups_per_flex; + +find_close_to_parent: + flexbg_free_blocks = flex_group[best_flex].free_blocks; + flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; + if (flex_group[best_flex].free_inodes && + flex_freeb_ratio > free_block_ratio) + goto found_flexbg; + + if (best_flex && best_flex == parent_fbg_group) { + best_flex--; + goto find_close_to_parent; + } + + for (i = 0; i < n_fbg_groups; i++) { + if (i == parent_fbg_group || i == parent_fbg_group - 1) + continue; + + flexbg_free_blocks = flex_group[i].free_blocks; + flex_freeb_ratio = flexbg_free_blocks * 100 / blocks_per_flex; + + if (flex_freeb_ratio > free_block_ratio && + flex_group[i].free_inodes) { + best_flex = i; + goto found_flexbg; + } + + if (best_flex < 0 || + (flex_group[i].free_blocks > + flex_group[best_flex].free_blocks && + flex_group[i].free_inodes)) + best_flex = i; + } + + if (!flex_group[best_flex].free_inodes || + !flex_group[best_flex].free_blocks) + return -1; + +found_flexbg: + for (i = best_flex * flex_size; i < ngroups && + i < (best_flex + 1) * flex_size; i++) { + desc = ext4_get_group_desc(sb, i, &bh); + if (le16_to_cpu(desc->bg_free_inodes_count)) { + *best_group = i; + goto out; + } + } + + return -1; +out: + return 0; +} + /* * Orlov's allocator for directories. * @@ -501,6 +582,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) struct inode *ret; ext4_group_t i; int free = 0; + ext4_group_t flex_group; /* Cannot create files in a deleted directory */ if (!dir || !dir->i_nlink) @@ -514,6 +596,12 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) sbi = EXT4_SB(sb); es = sbi->s_es; + + if (sbi->s_log_groups_per_flex) { + ret2 = find_group_flex(sb, dir, &group); + goto got_group; + } + if (S_ISDIR(mode)) { if (test_opt (sb, OLDALLOC)) ret2 = find_group_dir(sb, dir, &group); @@ -522,6 +610,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) } else ret2 = find_group_other(sb, dir, &group); +got_group: err = -ENOSPC; if (ret2 == -1) goto out; @@ -676,6 +765,13 @@ got: percpu_counter_inc(&sbi->s_dirs_counter); sb->s_dirt = 1; + if (sbi->s_log_groups_per_flex) { + flex_group = ext4_flex_group(sbi, group); + spin_lock(sb_bgl_lock(sbi, flex_group)); + sbi->s_flex_groups[flex_group].free_inodes--; + spin_unlock(sb_bgl_lock(sbi, flex_group)); + } + inode->i_uid = current->fsuid; if (test_opt (sb, GRPID)) inode->i_gid = dir->i_gid; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b882868..5dcb826 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2842,6 +2842,14 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, + ac->ac_b_ex.fe_group); + spin_lock(sb_bgl_lock(sbi, flex_group)); + sbi->s_flex_groups[flex_group].free_blocks -= ac->ac_b_ex.fe_len; + spin_unlock(sb_bgl_lock(sbi, flex_group)); + } + err = ext4_journal_dirty_metadata(handle, bitmap_bh); if (err) goto out_err; @@ -4342,6 +4350,13 @@ do_more: spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_add(&sbi->s_freeblocks_counter, count); + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); + spin_lock(sb_bgl_lock(sbi, flex_group)); + sbi->s_flex_groups[flex_group].free_blocks += count; + spin_unlock(sb_bgl_lock(sbi, flex_group)); + } + ext4_mb_release_desc(&e4b); *freed += count; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 588cfb4..b9ad3d85 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -517,6 +517,7 @@ static void ext4_put_super (struct super_block * sb) for (i = 0; i < sbi->s_gdb_count; i++) brelse(sbi->s_group_desc[i]); kfree(sbi->s_group_desc); + kfree(sbi->s_flex_groups); percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); @@ -1442,6 +1443,54 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, return res; } +static int ext4_fill_flex_info(struct super_block *sb) +{ + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_group_desc *gdp = NULL; + struct buffer_head *bh; + ext4_group_t flex_group_count; + ext4_group_t flex_group; + int groups_per_flex = 0; + __u64 block_bitmap = 0; + int i; + + if (!sbi->s_es->s_log_groups_per_flex) { + sbi->s_log_groups_per_flex = 0; + return 1; + } + + sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; + groups_per_flex = 1 << sbi->s_log_groups_per_flex; + + flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) / + groups_per_flex; + sbi->s_flex_groups = kmalloc(flex_group_count * + sizeof(struct flex_groups), GFP_KERNEL); + if (sbi->s_flex_groups == NULL) { + printk(KERN_ERR "EXT4-fs: not enough memory\n"); + goto failed; + } + memset(sbi->s_flex_groups, 0, flex_group_count * + sizeof(struct flex_groups)); + + gdp = ext4_get_group_desc(sb, 1, &bh); + block_bitmap = ext4_block_bitmap(sb, gdp) - 1; + + for (i = 0; i < sbi->s_groups_count; i++) { + gdp = ext4_get_group_desc(sb, i, &bh); + + flex_group = ext4_flex_group(sbi, i); + sbi->s_flex_groups[flex_group].free_inodes += + le16_to_cpu(gdp->bg_free_inodes_count); + sbi->s_flex_groups[flex_group].free_blocks += + le16_to_cpu(gdp->bg_free_blocks_count); + } + + return 1; +failed: + return 0; +} + __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp) { @@ -2137,6 +2186,14 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n"); goto failed_mount2; } + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) + if (!ext4_fill_flex_info(sb)) { + printk(KERN_ERR + "EXT4-fs: unable to initialize " + "flex_bg meta info!\n"); + goto failed_mount2; + } + sbi->s_gdb_count = db_count; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); -- cgit v0.10.2 From 530576bbf379fc45cfb34f246257d8526db44567 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Sun, 13 Jul 2008 21:06:39 -0400 Subject: jbd2: fix race between jbd2_journal_try_to_free_buffers() and jbd2 commit transaction journal_try_to_free_buffers() could race with jbd commit transaction when the later is holding the buffer reference while waiting for the data buffer to flush to disk. If the caller of journal_try_to_free_buffers() request tries hard to release the buffers, it will treat the failure as error and return back to the caller. We have seen the directo IO failed due to this race. Some of the caller of releasepage() also expecting the buffer to be dropped when passed with GFP_KERNEL mask to the releasepage()->journal_try_to_free_buffers(). With this patch, if the caller is passing the GFP_KERNEL to indicating this call could wait, in case of try_to_free_buffers() failed, let's waiting for journal_commit_transaction() to finish commit the current committing transaction , then try to free those buffers again with journal locked. Signed-off-by: Mingming Cao Reviewed-by: Badari Pulavarty Signed-off-by: "Theodore Ts'o" diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index d6e006e..ba620c4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -41,7 +41,6 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); * new transaction and we can't block without protecting against other * processes trying to touch the journal while it is in transition. * - * Called under j_state_lock */ static transaction_t * @@ -1656,12 +1655,43 @@ out: return; } +/* + * jbd2_journal_try_to_free_buffers() could race with + * jbd2_journal_commit_transaction(). The later might still hold the + * reference count to the buffers when inspecting them on + * t_syncdata_list or t_locked_list. + * + * jbd2_journal_try_to_free_buffers() will call this function to + * wait for the current transaction to finish syncing data buffers, before + * try to free that buffer. + * + * Called with journal->j_state_lock hold. + */ +static void jbd2_journal_wait_for_transaction_sync_data(journal_t *journal) +{ + transaction_t *transaction; + tid_t tid; + + spin_lock(&journal->j_state_lock); + transaction = journal->j_committing_transaction; + + if (!transaction) { + spin_unlock(&journal->j_state_lock); + return; + } + + tid = transaction->t_tid; + spin_unlock(&journal->j_state_lock); + jbd2_log_wait_commit(journal, tid); +} /** * int jbd2_journal_try_to_free_buffers() - try to free page buffers. * @journal: journal for operation * @page: to try and free - * @unused_gfp_mask: unused + * @gfp_mask: we use the mask to detect how hard should we try to release + * buffers. If __GFP_WAIT and __GFP_FS is set, we wait for commit code to + * release the buffers. * * * For all the buffers on this page, @@ -1690,9 +1720,11 @@ out: * journal_try_to_free_buffer() is changing its state. But that * cannot happen because we never reallocate freed data as metadata * while the data is part of a transaction. Yes? + * + * Return 0 on failure, 1 on success */ int jbd2_journal_try_to_free_buffers(journal_t *journal, - struct page *page, gfp_t unused_gfp_mask) + struct page *page, gfp_t gfp_mask) { struct buffer_head *head; struct buffer_head *bh; @@ -1708,7 +1740,8 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, /* * We take our own ref against the journal_head here to avoid * having to add tons of locking around each instance of - * jbd2_journal_remove_journal_head() and jbd2_journal_put_journal_head(). + * jbd2_journal_remove_journal_head() and + * jbd2_journal_put_journal_head(). */ jh = jbd2_journal_grab_journal_head(bh); if (!jh) @@ -1721,7 +1754,28 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal, if (buffer_jbd(bh)) goto busy; } while ((bh = bh->b_this_page) != head); + ret = try_to_free_buffers(page); + + /* + * There are a number of places where jbd2_journal_try_to_free_buffers() + * could race with jbd2_journal_commit_transaction(), the later still + * holds the reference to the buffers to free while processing them. + * try_to_free_buffers() failed to free those buffers. Some of the + * caller of releasepage() request page buffers to be dropped, otherwise + * treat the fail-to-free as errors (such as generic_file_direct_IO()) + * + * So, if the caller of try_to_release_page() wants the synchronous + * behaviour(i.e make sure buffers are dropped upon return), + * let's wait for the current transaction to finish flush of + * dirty data buffers, then try to free those buffers again, + * with the journal locked. + */ + if (ret == 0 && (gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS)) { + jbd2_journal_wait_for_transaction_sync_data(journal); + ret = try_to_free_buffers(page); + } + busy: return ret; } -- cgit v0.10.2 From f9a8ac99fd79eb961a8573ccf058439bc17b4d3a Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: remove redundant code in ext4_fill_super() The previous sb_min_blocksize() has already set the block size. Signed-off-by: Li Zefan Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b9ad3d85..6c80f37 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1899,11 +1899,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) goto out_fail; } - if (!sb_set_blocksize(sb, blocksize)) { - printk(KERN_ERR "EXT4-fs: bad blocksize %d.\n", blocksize); - goto out_fail; - } - /* * The ext4 superblock will not be buffer aligned for other than 1kB * block sizes. We need to calculate the offset from buffer start. -- cgit v0.10.2 From 363d4251d4bd984c304e0989789f6494343660fd Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: remove quota allocation when ext4_mb_new_blocks fails Quota allocation is not removed when ext4_mb_new_blocks calls kmem_cache_alloc failed. Also make sure the allocation context is freed on the error path. Signed-off-by: Shen Feng Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 5dcb826..cde232b 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4058,8 +4058,9 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); if (!ac) { + ar->len = 0; *errp = -ENOMEM; - return 0; + goto out1; } ext4_mb_poll_new_transaction(sb, handle); @@ -4067,7 +4068,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, *errp = ext4_mb_initialize_context(ac, ar); if (*errp) { ar->len = 0; - goto out; + goto out2; } ac->ac_op = EXT4_MB_HISTORY_PREALLOC; @@ -4115,11 +4116,12 @@ repeat: ext4_mb_release_context(ac); -out: +out2: + kmem_cache_free(ext4_ac_cachep, ac); +out1: if (ar->len < inquota) DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len); - kmem_cache_free(ext4_ac_cachep, ac); return block; } static void ext4_mb_poll_new_transaction(struct super_block *sb, -- cgit v0.10.2 From a379cd1d6bb00f9f5d2759d4a5621a884df5914e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Update i_disksize properly when allocating from fallocate area. When allocating unitialized space at the end of file which had been preallocated with the FALLOC_FL_KEEP_SIZE option, the file size is not updated at that time. But the later we are not updating the file size when writing to that preallocated space. These changes are for code correctness. This patch allows us to update the i_disksize at the write_end() callback of filesystem properly. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 47929c4..f7a746b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2716,13 +2716,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, goto out2; } - if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = inode->i_size; - /* previous routine could use block we allocated */ newblock = ext_pblock(&newex); allocated = ext4_ext_get_actual_len(&newex); outnew: + if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize) + EXT4_I(inode)->i_disksize = inode->i_size; + __set_bit(BH_New, &bh_result->b_state); /* Cache only when it is _not_ an uninitialized extent */ -- cgit v0.10.2 From 787e0981fad97a5ca3d07c7afe115a7e345b2861 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: return error when calling ext4_ext_split failed ext4_ext_create_new_leaf must return error when its calling to ext4_ext_split failed. Signed-off-by: Shen Feng Signed-off-by: Mingming Cao Reviewed-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f7a746b..bc17ed7 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -981,6 +981,8 @@ repeat: /* if we found index with free entry, then use that * entry: create all needed subtree and add new leaf */ err = ext4_ext_split(handle, inode, path, newext, i); + if (err) + goto out; /* refill path */ ext4_ext_drop_refs(path); -- cgit v0.10.2 From 1973adcba570c226de840299056e055a3614185e Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Make ext4_ext_find_extent fills ext_path completely When pos=0 or depth, the fields of ext4_ext_path is are not completely filled. This patch also removes some unnecessary code. Signed-off-by: Shen Feng Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bc17ed7..3e966da 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -524,6 +524,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, alloc = 1; } path[0].p_hdr = eh; + path[0].p_bh = NULL; i = depth; /* walk through the tree */ @@ -552,12 +553,14 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, } path[ppos].p_depth = i; - path[ppos].p_hdr = eh; path[ppos].p_ext = NULL; path[ppos].p_idx = NULL; /* find extent */ ext4_ext_binsearch(inode, path + ppos, block); + /* if not an empty leaf */ + if (path[ppos].p_ext) + path[ppos].p_block = ext_pblock(path[ppos].p_ext); ext4_ext_show_path(inode, path); -- cgit v0.10.2 From 9102e4fa8016af8bf1a263df913ee8fdafd4dfb0 Mon Sep 17 00:00:00 2001 From: Shen Feng Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Fix ext4_ext_journal_restart() to reflect errors up to the caller Fix ext4_ext_journal_restart() so it returns any errors reported by ext4_journal_extend() and ext4_journal_restart(). Signed-off-by: Shen Feng Reviewed-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3e966da..17ea8bb 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -92,17 +92,16 @@ static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); } -static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed) +static int ext4_ext_journal_restart(handle_t *handle, int needed) { int err; if (handle->h_buffer_credits > needed) - return handle; - if (!ext4_journal_extend(handle, needed)) - return handle; - err = ext4_journal_restart(handle, needed); - - return handle; + return 0; + err = ext4_journal_extend(handle, needed); + if (err) + return err; + return ext4_journal_restart(handle, needed); } /* @@ -1888,11 +1887,9 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb); #endif - handle = ext4_ext_journal_restart(handle, credits); - if (IS_ERR(handle)) { - err = PTR_ERR(handle); + err = ext4_ext_journal_restart(handle, credits); + if (err) goto out; - } err = ext4_ext_get_access(handle, inode, path + depth); if (err) -- cgit v0.10.2 From d9c769b769a8bcd70371c71797fc4e407b37ba75 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: cleanup never-used magic numbers from htree code dx_root_limit() will had some dead code which forced it to always return 20, and dx_node_limit to always return 22 for debugging purposes. Remove it. Acked-by: Andreas Dilger Signed-off-by: Li Zefan Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index c7bf012..387ad98 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -241,13 +241,13 @@ static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) { unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) - EXT4_DIR_REC_LEN(2) - infosize; - return 0? 20: entry_space / sizeof(struct dx_entry); + return entry_space / sizeof(struct dx_entry); } static inline unsigned dx_node_limit (struct inode *dir) { unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0); - return 0? 22: entry_space / sizeof(struct dx_entry); + return entry_space / sizeof(struct dx_entry); } /* -- cgit v0.10.2 From 7477827f6686ce29b6216d9eb26f6b9027742dcc Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Fix sparse warning Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 0b2b754..6dcbec9 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -47,7 +47,7 @@ static int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block, ext4_group_t block_group) { ext4_group_t actual_group; - ext4_get_group_no_and_offset(sb, block, &actual_group, 0); + ext4_get_group_no_and_offset(sb, block, &actual_group, NULL); if (actual_group == block_group) return 1; return 0; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6c80f37..80f0615 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1858,8 +1858,8 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi) } static int ext4_fill_super (struct super_block *sb, void *data, int silent) - __releases(kernel_sem) - __acquires(kernel_sem) + __releases(kernel_lock) + __acquires(kernel_lock) { struct buffer_head * bh; -- cgit v0.10.2 From 6afd670713c9e7d5c5550e379dfedca8ffab4c90 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: fix ext4_init_block_bitmap() for metablock block group When meta_bg feature is enabled and s_first_meta_bg != 0, ext4_init_block_bitmap() miscalculates the number of block used by the group descriptor table (0 or 1 for metablock block group) This patch fixes this by using ext4_bg_num_gdb() Signed-off-by: Akinobu Mita Cc: Andrew Morton Cc: Stephen Tweedie Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" Acked-by: Andreas Dilger diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 6dcbec9..1327ac3 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -121,12 +121,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks); } } else { /* For META_BG_BLOCK_GROUPS */ - int group_rel = (block_group - - le32_to_cpu(sbi->s_es->s_first_meta_bg)) % - EXT4_DESC_PER_BLOCK(sb); - if (group_rel == 0 || group_rel == 1 || - (group_rel == EXT4_DESC_PER_BLOCK(sb) - 1)) - bit_max += 1; + bit_max += ext4_bg_num_gdb(sb, block_group); } if (block_group == sbi->s_groups_count - 1) { -- cgit v0.10.2 From 7061eba75ceb0835ba61e7cbd757a6f9c1e4af92 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Use inode preallocation with -o noextents When mballoc is enabled, block allocation for old block-based files are allocated using mballoc allocator instead of old block-based allocator. The old ext3 block reservation is turned off when mballoc is turned on. However, the in-core preallocation is not enabled for block-based/ non-extent based file block allocation. This result in performance regression, as now we don't have "reservation" ore in-core preallocation to prevent interleaved fragmentation in multiple writes workload. This patch fix this by enable per inode in-core preallocation for non extent files when mballoc is used. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 1327ac3..816f1db 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -1923,7 +1923,7 @@ out: return 0; } -ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode, +ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, int *errp) { struct ext4_allocation_request ar; @@ -1942,9 +1942,29 @@ ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode, ret = ext4_mb_new_blocks(handle, &ar, errp); return ret; } +ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, + ext4_fsblk_t goal, unsigned long *count, int *errp) +{ + struct ext4_allocation_request ar; + ext4_fsblk_t ret; + + if (!test_opt(inode->i_sb, MBALLOC)) { + ret = ext4_new_blocks_old(handle, inode, goal, count, errp); + return ret; + } + + memset(&ar, 0, sizeof(ar)); + ar.inode = inode; + ar.goal = goal; + ar.len = *count; + ret = ext4_mb_new_blocks(handle, &ar, errp); + *count = ar.len; + return ret; +} ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp) + ext4_lblk_t iblock, ext4_fsblk_t goal, + unsigned long *count, int *errp) { struct ext4_allocation_request ar; ext4_fsblk_t ret; @@ -1955,9 +1975,21 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, } memset(&ar, 0, sizeof(ar)); + /* Fill with neighbour allocated blocks */ + ar.lleft = 0; + ar.pleft = 0; + ar.lright = 0; + ar.pright = 0; + ar.inode = inode; ar.goal = goal; ar.len = *count; + ar.logical = iblock; + if (S_ISREG(inode->i_mode)) + ar.flags = EXT4_MB_HINT_DATA; + else + /* disable in-core preallocation for non-regular files */ + ar.flags = 0; ret = ext4_mb_new_blocks(handle, &ar, errp); *count = ar.len; return ret; diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0bfeae1..d44a7fb 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -970,10 +970,13 @@ extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb, extern int ext4_bg_has_super(struct super_block *sb, ext4_group_t group); extern unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group); -extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, +extern ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, int *errp); -extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode, +extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp); +extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, + ext4_lblk_t iblock, ext4_fsblk_t goal, + unsigned long *count, int *errp); extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp); extern void ext4_free_blocks (handle_t *handle, struct inode *inode, diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 17ea8bb..c729b35 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -187,7 +187,7 @@ ext4_ext_new_block(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, newblock; goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block)); - newblock = ext4_new_block(handle, inode, goal, err); + newblock = ext4_new_meta_block(handle, inode, goal, err); return newblock; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7cce96a..bc95056 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -508,11 +508,12 @@ static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned long blks, * direct blocks */ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int indirect_blks, int blks, - ext4_fsblk_t new_blocks[4], int *err) + ext4_lblk_t iblock, ext4_fsblk_t goal, + int indirect_blks, int blks, + ext4_fsblk_t new_blocks[4], int *err) { int target, i; - unsigned long count = 0; + unsigned long count = 0, blk_allocated = 0; int index = 0; ext4_fsblk_t current_block = 0; int ret = 0; @@ -525,12 +526,13 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, * the first direct block of this branch. That's the * minimum number of blocks need to allocate(required) */ - target = blks + indirect_blks; - - while (1) { + /* first we try to allocate the indirect blocks */ + target = indirect_blks; + while (target > 0) { count = target; /* allocating blocks for indirect blocks and direct blocks */ - current_block = ext4_new_blocks(handle,inode,goal,&count,err); + current_block = ext4_new_meta_blocks(handle, inode, + goal, &count, err); if (*err) goto failed_out; @@ -540,16 +542,48 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, new_blocks[index++] = current_block++; count--; } - - if (count > 0) + if (count > 0) { + /* + * save the new block number + * for the first direct block + */ + new_blocks[index] = current_block; + printk(KERN_INFO "%s returned more blocks than " + "requested\n", __func__); + WARN_ON(1); break; + } } - /* save the new block number for the first direct block */ - new_blocks[index] = current_block; - + target = blks - count ; + blk_allocated = count; + if (!target) + goto allocated; + /* Now allocate data blocks */ + count = target; + /* allocating blocks for indirect blocks and direct blocks */ + current_block = ext4_new_blocks(handle, inode, iblock, + goal, &count, err); + if (*err && (target == blks)) { + /* + * if the allocation failed and we didn't allocate + * any blocks before + */ + goto failed_out; + } + if (!*err) { + if (target == blks) { + /* + * save the new block number + * for the first direct block + */ + new_blocks[index] = current_block; + } + blk_allocated += count; + } +allocated: /* total number of blocks allocated for direct blocks */ - ret = count; + ret = blk_allocated; *err = 0; return ret; failed_out: @@ -584,8 +618,9 @@ failed_out: * as described above and return 0. */ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, - int indirect_blks, int *blks, ext4_fsblk_t goal, - ext4_lblk_t *offsets, Indirect *branch) + ext4_lblk_t iblock, int indirect_blks, + int *blks, ext4_fsblk_t goal, + ext4_lblk_t *offsets, Indirect *branch) { int blocksize = inode->i_sb->s_blocksize; int i, n = 0; @@ -595,7 +630,7 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, ext4_fsblk_t new_blocks[4]; ext4_fsblk_t current_block; - num = ext4_alloc_blocks(handle, inode, goal, indirect_blks, + num = ext4_alloc_blocks(handle, inode, iblock, goal, indirect_blks, *blks, new_blocks, &err); if (err) return err; @@ -855,8 +890,9 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, /* * Block out ext4_truncate while we alter the tree */ - err = ext4_alloc_branch(handle, inode, indirect_blks, &count, goal, - offsets + (partial - chain), partial); + err = ext4_alloc_branch(handle, inode, iblock, indirect_blks, + &count, goal, + offsets + (partial - chain), partial); /* * The ext4_splice_branch call will free and forget any buffers diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index ff08633..93c5fdc 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -810,7 +810,7 @@ inserted: /* We need to allocate a new block */ ext4_fsblk_t goal = ext4_group_first_block_no(sb, EXT4_I(inode)->i_block_group); - ext4_fsblk_t block = ext4_new_block(handle, inode, + ext4_fsblk_t block = ext4_new_meta_block(handle, inode, goal, &error); if (error) goto cleanup; -- cgit v0.10.2 From 654b4908bc17a6318d18f3036fecc5155de92f55 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: cleanup block allocator Move the code related to block allocation to a single function and add helper funtions to differient allocation for data and meta data blocks Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 816f1db..48787e8 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -1640,20 +1640,24 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries) } /** - * ext4_new_blocks_old() -- core block(s) allocation function + * ext4_old_new_blocks() -- core block bitmap based block allocation function + * * @handle: handle to this transaction * @inode: file inode * @goal: given target block(filesystem wide) * @count: target number of blocks to allocate * @errp: error code * - * ext4_new_blocks uses a goal block to assist allocation. It tries to - * allocate block(s) from the block group contains the goal block first. If that - * fails, it will try to allocate block(s) from other block groups without - * any specific goal block. + * ext4_old_new_blocks uses a goal block to assist allocation and look up + * the block bitmap directly to do block allocation. It tries to + * allocate block(s) from the block group contains the goal block first. If + * that fails, it will try to allocate block(s) from other block groups + * without any specific goal block. + * + * This function is called when -o nomballoc mount option is enabled * */ -ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, +ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp) { struct buffer_head *bitmap_bh = NULL; @@ -1923,78 +1927,95 @@ out: return 0; } -ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int *errp) -{ - struct ext4_allocation_request ar; - ext4_fsblk_t ret; - - if (!test_opt(inode->i_sb, MBALLOC)) { - unsigned long count = 1; - ret = ext4_new_blocks_old(handle, inode, goal, &count, errp); - return ret; - } +#define EXT4_META_BLOCK 0x1 - memset(&ar, 0, sizeof(ar)); - ar.inode = inode; - ar.goal = goal; - ar.len = 1; - ret = ext4_mb_new_blocks(handle, &ar, errp); - return ret; -} -ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp) -{ - struct ext4_allocation_request ar; - ext4_fsblk_t ret; - - if (!test_opt(inode->i_sb, MBALLOC)) { - ret = ext4_new_blocks_old(handle, inode, goal, count, errp); - return ret; - } - - memset(&ar, 0, sizeof(ar)); - ar.inode = inode; - ar.goal = goal; - ar.len = *count; - ret = ext4_mb_new_blocks(handle, &ar, errp); - *count = ar.len; - return ret; -} - -ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, +static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, ext4_fsblk_t goal, - unsigned long *count, int *errp) + unsigned long *count, int *errp, int flags) { struct ext4_allocation_request ar; ext4_fsblk_t ret; if (!test_opt(inode->i_sb, MBALLOC)) { - ret = ext4_new_blocks_old(handle, inode, goal, count, errp); - return ret; + return ext4_old_new_blocks(handle, inode, goal, count, errp); } memset(&ar, 0, sizeof(ar)); /* Fill with neighbour allocated blocks */ - ar.lleft = 0; - ar.pleft = 0; - ar.lright = 0; - ar.pright = 0; ar.inode = inode; ar.goal = goal; ar.len = *count; ar.logical = iblock; - if (S_ISREG(inode->i_mode)) + + if (S_ISREG(inode->i_mode) && !(flags & EXT4_META_BLOCK)) + /* enable in-core preallocation for data block allocation */ ar.flags = EXT4_MB_HINT_DATA; else /* disable in-core preallocation for non-regular files */ ar.flags = 0; + ret = ext4_mb_new_blocks(handle, &ar, errp); *count = ar.len; return ret; } +/* + * ext4_new_meta_block() -- allocate block for meta data (indexing) blocks + * + * @handle: handle to this transaction + * @inode: file inode + * @goal: given target block(filesystem wide) + * @errp: error code + * + * Return allocated block number on success + */ +ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, + ext4_fsblk_t goal, int *errp) +{ + unsigned long count = 1; + return do_blk_alloc(handle, inode, 0, goal, + &count, errp, EXT4_META_BLOCK); +} + +/* + * ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks + * + * @handle: handle to this transaction + * @inode: file inode + * @goal: given target block(filesystem wide) + * @count: total number of blocks need + * @errp: error code + * + * Return 1st allocated block numberon success, *count stores total account + * error stores in errp pointer + */ +ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, + ext4_fsblk_t goal, unsigned long *count, int *errp) +{ + return do_blk_alloc(handle, inode, 0, goal, + count, errp, EXT4_META_BLOCK); +} + +/* + * ext4_new_blocks() -- allocate data blocks + * + * @handle: handle to this transaction + * @inode: file inode + * @goal: given target block(filesystem wide) + * @count: total number of blocks need + * @errp: error code + * + * Return 1st allocated block numberon success, *count stores total account + * error stores in errp pointer + */ + +ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, + ext4_lblk_t iblock, ext4_fsblk_t goal, + unsigned long *count, int *errp) +{ + return do_blk_alloc(handle, inode, iblock, goal, count, errp, 0); +} /** * ext4_count_free_blocks() -- count filesystem free blocks diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d44a7fb..e622ade 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -977,7 +977,7 @@ extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, ext4_fsblk_t goal, unsigned long *count, int *errp); -extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, +extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp); extern void ext4_free_blocks (handle_t *handle, struct inode *inode, ext4_fsblk_t block, unsigned long count, int metadata); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c729b35..555155d 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -179,8 +179,11 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, return bg_start + colour + block; } +/* + * Allocation for a meta data block + */ static ext4_fsblk_t -ext4_ext_new_block(handle_t *handle, struct inode *inode, +ext4_ext_new_meta_block(handle_t *handle, struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex, int *err) { @@ -690,7 +693,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, /* allocate all needed blocks */ ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); for (a = 0; a < depth - at; a++) { - newblock = ext4_ext_new_block(handle, inode, path, newext, &err); + newblock = ext4_ext_new_meta_block(handle, inode, path, + newext, &err); if (newblock == 0) goto cleanup; ablocks[a] = newblock; @@ -886,7 +890,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, ext4_fsblk_t newblock; int err = 0; - newblock = ext4_ext_new_block(handle, inode, path, newext, &err); + newblock = ext4_ext_new_meta_block(handle, inode, path, newext, &err); if (newblock == 0) return err; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bc95056..c5d506d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -561,7 +561,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, goto allocated; /* Now allocate data blocks */ count = target; - /* allocating blocks for indirect blocks and direct blocks */ + /* allocating blocks for data blocks */ current_block = ext4_new_blocks(handle, inode, iblock, goal, &count, err); if (*err && (target == blks)) { diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index cde232b..816ba8c 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4041,7 +4041,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, sbi = EXT4_SB(sb); if (!test_opt(sb, MBALLOC)) { - block = ext4_new_blocks_old(handle, ar->inode, ar->goal, + block = ext4_old_new_blocks(handle, ar->inode, ar->goal, &(ar->len), errp); return block; } -- cgit v0.10.2 From d755fb384250d6bd7fd18a0930e71965acc8e72e Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: call blkdev_issue_flush on fsync To ensure that bits are truly on-disk after an fsync, we should call blkdev_issue_flush if barriers are supported. Inspired by an old thread on barriers, by reiserfs & xfs which do the same, and by a patch SuSE ships with their kernel Signed-off-by: Eric Sandeen Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 1c8ba48..a45c373 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "ext4.h" #include "ext4_jbd2.h" @@ -45,6 +46,7 @@ int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; + journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; int ret = 0; J_ASSERT(ext4_journal_current_handle() == NULL); @@ -85,6 +87,8 @@ int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync) .nr_to_write = 0, /* sys_fsync did this */ }; ret = sync_inode(inode, &wbc); + if (journal && (journal->j_flags & JBD2_BARRIER)) + blkdev_issue_flush(inode->i_sb->s_bdev, NULL); } out: return ret; -- cgit v0.10.2 From 07031431072ece801d53d2c03d5e5bb21f4f64a4 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: mballoc avoid use root reserved blocks for non root allocation mballoc allocation missed check for blocks reserved for root users. Add ext4_has_free_blocks() check before allocation. Also modified ext4_has_free_blocks() to support multiple block allocation request. Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 48787e8..25f63d8 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -1599,23 +1599,35 @@ out: /** * ext4_has_free_blocks() - * @sbi: in-core super block structure. + * @sbi: in-core super block structure. + * @nblocks: number of neeed blocks * - * Check if filesystem has at least 1 free block available for allocation. + * Check if filesystem has free blocks available for allocation. + * Return the number of blocks avaible for allocation for this request + * On success, return nblocks */ -static int ext4_has_free_blocks(struct ext4_sb_info *sbi) +ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, + ext4_fsblk_t nblocks) { - ext4_fsblk_t free_blocks, root_blocks; + ext4_fsblk_t free_blocks; + ext4_fsblk_t root_blocks = 0; free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); - root_blocks = ext4_r_blocks_count(sbi->s_es); - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && + + if (!capable(CAP_SYS_RESOURCE) && sbi->s_resuid != current->fsuid && - (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { - return 0; - } - return 1; -} + (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid))) + root_blocks = ext4_r_blocks_count(sbi->s_es); +#ifdef CONFIG_SMP + if (free_blocks - root_blocks < FBC_BATCH) + free_blocks = + percpu_counter_sum_positive(&sbi->s_freeblocks_counter); +#endif + if (free_blocks - root_blocks < nblocks) + return free_blocks - root_blocks; + return nblocks; + } + /** * ext4_should_retry_alloc() @@ -1631,7 +1643,7 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi) */ int ext4_should_retry_alloc(struct super_block *sb, int *retries) { - if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3) + 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); @@ -1681,13 +1693,21 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, ext4_group_t ngroups; unsigned long num = *count; - *errp = -ENOSPC; sb = inode->i_sb; if (!sb) { + *errp = -ENODEV; printk("ext4_new_block: nonexistent device"); return 0; } + sbi = EXT4_SB(sb); + *count = ext4_has_free_blocks(sbi, *count); + if (*count == 0) { + *errp = -ENOSPC; + return 0; /*return with ENOSPC error */ + } + num = *count; + /* * Check quota for allocation of this block. */ @@ -1711,11 +1731,6 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0)) my_rsv = &block_i->rsv_window_node; - if (!ext4_has_free_blocks(sbi)) { - *errp = -ENOSPC; - goto out; - } - /* * First, test whether the goal block is free. */ diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e622ade..2c4b485 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -979,6 +979,8 @@ extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, unsigned long *count, int *errp); extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp); +extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, + ext4_fsblk_t nblocks); extern void ext4_free_blocks (handle_t *handle, struct inode *inode, ext4_fsblk_t block, unsigned long count, int metadata); extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb, diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 816ba8c..1666ac1 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4045,6 +4045,12 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, &(ar->len), errp); return block; } + ar->len = ext4_has_free_blocks(sbi, ar->len); + + if (ar->len == 0) { + *errp = -ENOSPC; + return 0; + } while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) { ar->flags |= EXT4_MB_HINT_NOPREALLOC; @@ -4073,7 +4079,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, ac->ac_op = EXT4_MB_HISTORY_PREALLOC; if (!ext4_mb_use_preallocated(ac)) { - ac->ac_op = EXT4_MB_HISTORY_ALLOC; ext4_mb_normalize_request(ac, ar); repeat: -- cgit v0.10.2 From 47b4a50bebfd34b5e1fa2a9c673c8f31fa231cc1 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Set journal pointer to NULL when journal is released Set sbi->s_journal to NULL after we call journal_destroy(). This will be later needed because after journal_destroy() is called, ext4_clear_inode() can still be called for some inodes (e.g. root inode) and we'll need to detect there that journal doesn't exists anymore. Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 80f0615..1b330cd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -506,6 +506,7 @@ static void ext4_put_super (struct super_block * sb) ext4_ext_release(sb); ext4_xattr_put_super(sb); jbd2_journal_destroy(sbi->s_journal); + sbi->s_journal = NULL; if (!(sb->s_flags & MS_RDONLY)) { EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); es->s_state = cpu_to_le16(sbi->s_mount_state); @@ -2423,6 +2424,7 @@ cantfind_ext4: failed_mount4: jbd2_journal_destroy(sbi->s_journal); + sbi->s_journal = NULL; failed_mount3: percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); -- cgit v0.10.2 From 953e622b601f58b7cc0f29fe644457fa40a18456 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: use atomic functions to set bh_state Use the BUFFER_FNS functions (set_buffer_foo) to set buffer head state atomically instead of nonatomic __set_bit(). Signed-off-by: Eric Sandeen Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 555155d..bb36a28 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2622,8 +2622,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, */ if (allocated > max_blocks) allocated = max_blocks; - /* mark the buffer unwritten */ - __set_bit(BH_Unwritten, &bh_result->b_state); + set_buffer_unwritten(bh_result); goto out2; } @@ -2729,7 +2728,7 @@ outnew: if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize) EXT4_I(inode)->i_disksize = inode->i_size; - __set_bit(BH_New, &bh_result->b_state); + set_buffer_new(bh_result); /* Cache only when it is _not_ an uninitialized extent */ if (create != EXT4_CREATE_UNINITIALIZED_EXT) @@ -2739,7 +2738,7 @@ out: if (allocated > max_blocks) allocated = max_blocks; ext4_ext_show_leaf(inode, path); - __set_bit(BH_Mapped, &bh_result->b_state); + set_buffer_mapped(bh_result); bh_result->b_bdev = inode->i_sb->s_bdev; bh_result->b_blocknr = newblock; out2: -- cgit v0.10.2 From 5f21b0e642d7bf6fe4434c9ba12bc9cb96b17cf7 Mon Sep 17 00:00:00 2001 From: Frederic Bohe Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: fix online resize with mballoc Update group infos when updating a group's descriptor. Add group infos when adding a group's descriptor. Refresh cache pages used by mb_alloc when changes occur. This will probably need modifications when META_BG resizing will be allowed. Signed-off-by: Frederic Bohe Signed-off-by: Mingming Cao diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 2c4b485..64edb09 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1033,6 +1033,10 @@ extern int __init init_ext4_mballoc(void); extern void exit_ext4_mballoc(void); extern void ext4_mb_free_blocks(handle_t *, struct inode *, unsigned long, unsigned long, int, unsigned long *); +extern int ext4_mb_add_more_groupinfo(struct super_block *sb, + ext4_group_t i, struct ext4_group_desc *desc); +extern void ext4_mb_update_group_info(struct ext4_group_info *grp, + ext4_grpblk_t add); /* inode.c */ diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 1666ac1..8d254ca 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2236,21 +2236,192 @@ ext4_mb_store_history(struct ext4_allocation_context *ac) #define ext4_mb_history_init(sb) #endif + +/* Create and initialize ext4_group_info data for the given group. */ +int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, + struct ext4_group_desc *desc) +{ + int i, len; + int metalen = 0; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_group_info **meta_group_info; + + /* + * First check if this group is the first of a reserved block. + * If it's true, we have to allocate a new table of pointers + * to ext4_group_info structures + */ + if (group % EXT4_DESC_PER_BLOCK(sb) == 0) { + metalen = sizeof(*meta_group_info) << + EXT4_DESC_PER_BLOCK_BITS(sb); + meta_group_info = kmalloc(metalen, GFP_KERNEL); + if (meta_group_info == NULL) { + printk(KERN_ERR "EXT4-fs: can't allocate mem for a " + "buddy group\n"); + goto exit_meta_group_info; + } + sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)] = + meta_group_info; + } + + /* + * calculate needed size. if change bb_counters size, + * don't forget about ext4_mb_generate_buddy() + */ + len = offsetof(typeof(**meta_group_info), + bb_counters[sb->s_blocksize_bits + 2]); + + meta_group_info = + sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)]; + i = group & (EXT4_DESC_PER_BLOCK(sb) - 1); + + meta_group_info[i] = kzalloc(len, GFP_KERNEL); + if (meta_group_info[i] == NULL) { + printk(KERN_ERR "EXT4-fs: can't allocate buddy mem\n"); + goto exit_group_info; + } + set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, + &(meta_group_info[i]->bb_state)); + + /* + * initialize bb_free to be able to skip + * empty groups without initialization + */ + if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + meta_group_info[i]->bb_free = + ext4_free_blocks_after_init(sb, group, desc); + } else { + meta_group_info[i]->bb_free = + le16_to_cpu(desc->bg_free_blocks_count); + } + + INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); + +#ifdef DOUBLE_CHECK + { + struct buffer_head *bh; + meta_group_info[i]->bb_bitmap = + kmalloc(sb->s_blocksize, GFP_KERNEL); + BUG_ON(meta_group_info[i]->bb_bitmap == NULL); + bh = ext4_read_block_bitmap(sb, group); + BUG_ON(bh == NULL); + memcpy(meta_group_info[i]->bb_bitmap, bh->b_data, + sb->s_blocksize); + put_bh(bh); + } +#endif + + return 0; + +exit_group_info: + /* If a meta_group_info table has been allocated, release it now */ + if (group % EXT4_DESC_PER_BLOCK(sb) == 0) + kfree(sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)]); +exit_meta_group_info: + return -ENOMEM; +} /* ext4_mb_add_groupinfo */ + +/* + * Add a group to the existing groups. + * This function is used for online resize + */ +int ext4_mb_add_more_groupinfo(struct super_block *sb, ext4_group_t group, + struct ext4_group_desc *desc) +{ + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct inode *inode = sbi->s_buddy_cache; + int blocks_per_page; + int block; + int pnum; + struct page *page; + int err; + + /* Add group based on group descriptor*/ + err = ext4_mb_add_groupinfo(sb, group, desc); + if (err) + return err; + + /* + * Cache pages containing dynamic mb_alloc datas (buddy and bitmap + * datas) are set not up to date so that they will be re-initilaized + * during the next call to ext4_mb_load_buddy + */ + + /* Set buddy page as not up to date */ + blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; + block = group * 2; + pnum = block / blocks_per_page; + page = find_get_page(inode->i_mapping, pnum); + if (page != NULL) { + ClearPageUptodate(page); + page_cache_release(page); + } + + /* Set bitmap page as not up to date */ + block++; + pnum = block / blocks_per_page; + page = find_get_page(inode->i_mapping, pnum); + if (page != NULL) { + ClearPageUptodate(page); + page_cache_release(page); + } + + return 0; +} + +/* + * Update an existing group. + * This function is used for online resize + */ +void ext4_mb_update_group_info(struct ext4_group_info *grp, ext4_grpblk_t add) +{ + grp->bb_free += add; +} + static int ext4_mb_init_backend(struct super_block *sb) { ext4_group_t i; - int j, len, metalen; + int metalen; struct ext4_sb_info *sbi = EXT4_SB(sb); - int num_meta_group_infos = - (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) >> - EXT4_DESC_PER_BLOCK_BITS(sb); + struct ext4_super_block *es = sbi->s_es; + int num_meta_group_infos; + int num_meta_group_infos_max; + int array_size; struct ext4_group_info **meta_group_info; + struct ext4_group_desc *desc; + + /* This is the number of blocks used by GDT */ + num_meta_group_infos = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - + 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); + /* + * This is the total number of blocks used by GDT including + * the number of reserved blocks for GDT. + * The s_group_info array is allocated with this value + * to allow a clean online resize without a complex + * manipulation of pointer. + * The drawback is the unused memory when no resize + * occurs but it's very low in terms of pages + * (see comments below) + * Need to handle this properly when META_BG resizing is allowed + */ + num_meta_group_infos_max = num_meta_group_infos + + le16_to_cpu(es->s_reserved_gdt_blocks); + + /* + * array_size is the size of s_group_info array. We round it + * to the next power of two because this approximation is done + * internally by kmalloc so we can have some more memory + * for free here (e.g. may be used for META_BG resize). + */ + array_size = 1; + while (array_size < sizeof(*sbi->s_group_info) * + num_meta_group_infos_max) + array_size = array_size << 1; /* An 8TB filesystem with 64-bit pointers requires a 4096 byte * kmalloc. A 128kb malloc should suffice for a 256TB filesystem. * So a two level scheme suffices for now. */ - sbi->s_group_info = kmalloc(sizeof(*sbi->s_group_info) * - num_meta_group_infos, GFP_KERNEL); + sbi->s_group_info = kmalloc(array_size, GFP_KERNEL); if (sbi->s_group_info == NULL) { printk(KERN_ERR "EXT4-fs: can't allocate buddy meta group\n"); return -ENOMEM; @@ -2277,62 +2448,15 @@ static int ext4_mb_init_backend(struct super_block *sb) sbi->s_group_info[i] = meta_group_info; } - /* - * calculate needed size. if change bb_counters size, - * don't forget about ext4_mb_generate_buddy() - */ - len = sizeof(struct ext4_group_info); - len += sizeof(unsigned short) * (sb->s_blocksize_bits + 2); for (i = 0; i < sbi->s_groups_count; i++) { - struct ext4_group_desc *desc; - - meta_group_info = - sbi->s_group_info[i >> EXT4_DESC_PER_BLOCK_BITS(sb)]; - j = i & (EXT4_DESC_PER_BLOCK(sb) - 1); - - meta_group_info[j] = kzalloc(len, GFP_KERNEL); - if (meta_group_info[j] == NULL) { - printk(KERN_ERR "EXT4-fs: can't allocate buddy mem\n"); - goto err_freebuddy; - } desc = ext4_get_group_desc(sb, i, NULL); if (desc == NULL) { printk(KERN_ERR "EXT4-fs: can't read descriptor %lu\n", i); - i++; goto err_freebuddy; } - set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, - &(meta_group_info[j]->bb_state)); - - /* - * initialize bb_free to be able to skip - * empty groups without initialization - */ - if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - meta_group_info[j]->bb_free = - ext4_free_blocks_after_init(sb, i, desc); - } else { - meta_group_info[j]->bb_free = - le16_to_cpu(desc->bg_free_blocks_count); - } - - INIT_LIST_HEAD(&meta_group_info[j]->bb_prealloc_list); - -#ifdef DOUBLE_CHECK - { - struct buffer_head *bh; - meta_group_info[j]->bb_bitmap = - kmalloc(sb->s_blocksize, GFP_KERNEL); - BUG_ON(meta_group_info[j]->bb_bitmap == NULL); - bh = ext4_read_block_bitmap(sb, i); - BUG_ON(bh == NULL); - memcpy(meta_group_info[j]->bb_bitmap, bh->b_data, - sb->s_blocksize); - put_bh(bh); - } -#endif - + if (ext4_mb_add_groupinfo(sb, i, desc) != 0) + goto err_freebuddy; } return 0; diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9ff7b1c..f000fbe 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -866,6 +866,15 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); /* + * We can allocate memory for mb_alloc based on the new group + * descriptor + */ + if (test_opt(sb, MBALLOC)) { + err = ext4_mb_add_more_groupinfo(sb, input->group, gdp); + if (err) + goto exit_journal; + } + /* * Make the new blocks and inodes valid next. We do this before * increasing the group count so that once the group is enabled, * all of its blocks and inodes are already valid. @@ -957,6 +966,8 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, handle_t *handle; int err; unsigned long freed_blocks; + ext4_group_t group; + struct ext4_group_info *grp; /* We don't need to worry about locking wrt other resizers just * yet: we're going to revalidate es->s_blocks_count after @@ -988,7 +999,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, } /* Handle the remaining blocks in the last group only. */ - ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last); + ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last); if (last == 0) { ext4_warning(sb, __func__, @@ -1060,6 +1071,45 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, o_blocks_count + add); if ((err = ext4_journal_stop(handle))) goto exit_put; + + /* + * Mark mballoc pages as not up to date so that they will be updated + * next time they are loaded by ext4_mb_load_buddy. + */ + if (test_opt(sb, MBALLOC)) { + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct inode *inode = sbi->s_buddy_cache; + int blocks_per_page; + int block; + int pnum; + struct page *page; + + /* Set buddy page as not up to date */ + blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; + block = group * 2; + pnum = block / blocks_per_page; + page = find_get_page(inode->i_mapping, pnum); + if (page != NULL) { + ClearPageUptodate(page); + page_cache_release(page); + } + + /* Set bitmap page as not up to date */ + block++; + pnum = block / blocks_per_page; + page = find_get_page(inode->i_mapping, pnum); + if (page != NULL) { + ClearPageUptodate(page); + page_cache_release(page); + } + + /* Get the info on the last group */ + grp = ext4_get_group_info(sb, group); + + /* Update free blocks in group info */ + ext4_mb_update_group_info(grp, add); + } + if (test_opt(sb, DEBUG)) printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n", ext4_blocks_count(es)); -- cgit v0.10.2 From 93e3270c87549dc531a0b0e5d06362d998d810cb Mon Sep 17 00:00:00 2001 From: "Jose R. Santos" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Documentation updates. Some of the information in Documentation/filesystems/ext4.txt is out of date and in need of an update. Signed-off-by: Jose R. Santos Signed-off-by: "Theodore Ts'o" diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index 0c5086d..7e940c6 100644 --- a/Documentation/filesystems/ext4.txt +++ b/Documentation/filesystems/ext4.txt @@ -13,72 +13,89 @@ Mailing list: linux-ext4@vger.kernel.org 1. Quick usage instructions: =========================== - - Grab updated e2fsprogs from - ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs-interim/ - This is a patchset on top of e2fsprogs-1.39, which can be found at + - Compile and install the latest version of e2fsprogs (as of this + writing version 1.41) from: + + http://sourceforge.net/project/showfiles.php?group_id=2406 + + or + ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/ - - It's still mke2fs -j /dev/hda1 + or grab the latest git repository from: + + git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git + + - Create a new filesystem using the ext4dev filesystem type: + + # mke2fs -t ext4dev /dev/hda1 + + Or configure an existing ext3 filesystem to support extents and set + the test_fs flag to indicate that it's ok for an in-development + filesystem to touch this filesystem: - - mount /dev/hda1 /wherever -t ext4dev + # tune2fs -O extents -E test_fs /dev/hda1 - - To enable extents, + If the filesystem was created with 128 byte inodes, it can be + converted to use 256 byte for greater efficiency via: - mount /dev/hda1 /wherever -t ext4dev -o extents + # tune2fs -I 256 /dev/hda1 - - The filesystem is compatible with the ext3 driver until you add a file - which has extents (ie: `mount -o extents', then create a file). + (Note: we currently do not have tools to convert an ext4dev + filesystem back to ext3; so please do not do try this on production + filesystems.) - NOTE: The "extents" mount flag is temporary. It will soon go away and - extents will be enabled by the "-o extents" flag to mke2fs or tune2fs + - Mounting: + + # mount -t ext4dev /dev/hda1 /wherever - When comparing performance with other filesystems, remember that - ext3/4 by default offers higher data integrity guarantees than most. So - when comparing with a metadata-only journalling filesystem, use `mount -o - data=writeback'. And you might as well use `mount -o nobh' too along - with it. Making the journal larger than the mke2fs default often helps - performance with metadata-intensive workloads. + ext3/4 by default offers higher data integrity guarantees than most. + So when comparing with a metadata-only journalling filesystem, such + as ext3, use `mount -o data=writeback'. And you might as well use + `mount -o nobh' too along with it. Making the journal larger than + the mke2fs default often helps performance with metadata-intensive + workloads. 2. Features =========== 2.1 Currently available -* ability to use filesystems > 16TB +* ability to use filesystems > 16TB (e2fsprogs support not available yet) * extent format reduces metadata overhead (RAM, IO for access, transactions) * extent format more robust in face of on-disk corruption due to magics, * internal redunancy in tree - -2.1 Previously available, soon to be enabled by default by "mkefs.ext4": - -* dir_index and resize inode will be on by default -* large inodes will be used by default for fast EAs, nsec timestamps, etc +* improved file allocation (multi-block alloc, delayed alloc) +* fix 32000 subdirectory limit +* nsec timestamps for mtime, atime, ctime, create time +* inode version field on disk (NFSv4, Lustre) +* reduced e2fsck time via uninit_bg feature +* journal checksumming for robustness, performance +* persistent file preallocation (e.g for streaming media, databases) +* ability to pack bitmaps and inode tables into larger virtual groups via the + flex_bg feature +* large file support +* Inode allocation using large virtual block groups via flex_bg 2.2 Candidate features for future inclusion -There are several under discussion, whether they all make it in is -partly a function of how much time everyone has to work on them: +* Online defrag (patches available but not well tested) +* reduced mke2fs time via lazy itable initialization in conjuction with + the uninit_bg feature (capability to do this is available in e2fsprogs + but a kernel thread to do lazy zeroing of unused inode table blocks + after filesystem is first mounted is required for safety) -* improved file allocation (multi-block alloc, delayed alloc; basically done) -* fix 32000 subdirectory limit (patch exists, needs some e2fsck work) -* nsec timestamps for mtime, atime, ctime, create time (patch exists, - needs some e2fsck work) -* inode version field on disk (NFSv4, Lustre; prototype exists) -* reduced mke2fs/e2fsck time via uninitialized groups (prototype exists) -* journal checksumming for robustness, performance (prototype exists) -* persistent file preallocation (e.g for streaming media, databases) +There are several others under discussion, whether they all make it in is +partly a function of how much time everyone has to work on them. Features like +metadata checksumming have been discussed and planned for a bit but no patches +exist yet so I'm not sure they're in the near-term roadmap. -Features like metadata checksumming have been discussed and planned for -a bit but no patches exist yet so I'm not sure they're in the near-term -roadmap. +The big performance win will come with mballoc, delalloc and flex_bg +grouping of bitmaps and inode tables. Some test results available here: -The big performance win will come with mballoc and delalloc. CFS has -been using mballoc for a few years already with Lustre, and IBM + Bull -did a lot of benchmarking on it. The reason it isn't in the first set of -patches is partly a manageability issue, and partly because it doesn't -directly affect the on-disk format (outside of much better allocation) -so it isn't critical to get into the first round of changes. I believe -Alex is working on a new set of patches right now. + - http://www.bullopensource.org/ext4/20080530/ffsb-write-2.6.26-rc2.html + - http://www.bullopensource.org/ext4/20080530/ffsb-readwrite-2.6.26-rc2.html 3. Options ========== @@ -224,7 +241,7 @@ stripe=n Number of filesystem blocks that mballoc will try disks * RAID chunk size in file system blocks. Data Mode ---------- +========= There are 3 different data modes: * writeback mode @@ -256,7 +273,8 @@ kernel source: programs: http://e2fsprogs.sourceforge.net/ - http://ext2resize.sourceforge.net useful links: http://fedoraproject.org/wiki/ext3-devel http://www.bullopensource.org/ext4/ + http://ext4.wiki.kernel.org/index.php/Main_Page + http://fedoraproject.org/wiki/Features/Ext4 -- cgit v0.10.2 From 2e9ee850355593e311d9a26542290fe51e152f74 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Use page_mkwrite vma_operations to get mmap write notification. We would like to get notified when we are doing a write on mmap section. This is needed with respect to preallocated area. We split the preallocated area into initialzed extent and uninitialzed extent in the call back. This let us handle ENOSPC better. Otherwise we get ENOSPC in the writepage and that would result in data loss. The changes are also needed to handle ENOSPC when writing to an mmap section of files with holes. Acked-by: Jan Kara Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 64edb09..98760d1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1068,6 +1068,7 @@ extern void ext4_set_aops(struct inode *inode); extern int ext4_writepage_trans_blocks(struct inode *); extern int ext4_block_truncate_page(handle_t *handle, struct page *page, struct address_space *mapping, loff_t from); +extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); /* ioctl.c */ extern long ext4_ioctl(struct file *, unsigned int, unsigned long); diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 4159be6..b9510ba 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -123,6 +123,23 @@ force_commit: return ret; } +static struct vm_operations_struct ext4_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = ext4_page_mkwrite, +}; + +static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct address_space *mapping = file->f_mapping; + + if (!mapping->a_ops->readpage) + return -ENOEXEC; + file_accessed(file); + vma->vm_ops = &ext4_file_vm_ops; + vma->vm_flags |= VM_CAN_NONLINEAR; + return 0; +} + const struct file_operations ext4_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, @@ -133,7 +150,7 @@ const struct file_operations ext4_file_operations = { #ifdef CONFIG_COMPAT .compat_ioctl = ext4_compat_ioctl, #endif - .mmap = generic_file_mmap, + .mmap = ext4_file_mmap, .open = generic_file_open, .release = ext4_release_file, .fsync = ext4_sync_file, diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c5d506d..034fc54 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3564,3 +3564,64 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val) return err; } + +static int ext4_bh_unmapped(handle_t *handle, struct buffer_head *bh) +{ + return !buffer_mapped(bh); +} + +int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page) +{ + loff_t size; + unsigned long len; + int ret = -EINVAL; + struct file *file = vma->vm_file; + struct inode *inode = file->f_path.dentry->d_inode; + struct address_space *mapping = inode->i_mapping; + + /* + * Get i_alloc_sem to stop truncates messing with the inode. We cannot + * get i_mutex because we are already holding mmap_sem. + */ + down_read(&inode->i_alloc_sem); + size = i_size_read(inode); + if (page->mapping != mapping || size <= page_offset(page) + || !PageUptodate(page)) { + /* page got truncated from under us? */ + goto out_unlock; + } + ret = 0; + if (PageMappedToDisk(page)) + goto out_unlock; + + if (page->index == size >> PAGE_CACHE_SHIFT) + len = size & ~PAGE_CACHE_MASK; + else + len = PAGE_CACHE_SIZE; + + if (page_has_buffers(page)) { + /* return if we have all the buffers mapped */ + if (!walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, + ext4_bh_unmapped)) + goto out_unlock; + } + /* + * OK, we need to fill the hole... Do write_begin write_end + * to do block allocation/reservation.We are not holding + * inode.i__mutex here. That allow * parallel write_begin, + * write_end call. lock_page prevent this from happening + * on the same page though + */ + ret = mapping->a_ops->write_begin(file, mapping, page_offset(page), + len, AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); + if (ret < 0) + goto out_unlock; + ret = mapping->a_ops->write_end(file, mapping, page_offset(page), + len, len, page, NULL); + if (ret < 0) + goto out_unlock; + ret = 0; +out_unlock: + up_read(&inode->i_alloc_sem); + return ret; +} -- cgit v0.10.2 From c7d206b3379f7d6462e778b74f475c470ee3dcaf Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: vfs: Move mark_inode_dirty() from under page lock in generic_write_end() There's no need to call mark_inode_dirty() under page lock in generic_write_end(). It unnecessarily makes hold time of page lock longer and more importantly it forces locking order of page lock and transaction start for journaling filesystems. Signed-off-by: Jan Kara Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" diff --git a/fs/buffer.c b/fs/buffer.c index 0f51c0f..f4b0332 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2061,6 +2061,7 @@ int generic_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) { struct inode *inode = mapping->host; + int i_size_changed = 0; copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); @@ -2073,12 +2074,21 @@ int generic_write_end(struct file *file, struct address_space *mapping, */ if (pos+copied > inode->i_size) { i_size_write(inode, pos+copied); - mark_inode_dirty(inode); + i_size_changed = 1; } unlock_page(page); page_cache_release(page); + /* + * Don't mark the inode dirty under page lock. First, it unnecessarily + * makes the holding time of page lock longer. Second, it forces lock + * ordering of page lock and transaction start for journaling + * filesystems. + */ + if (i_size_changed) + mark_inode_dirty(inode); + return copied; } EXPORT_SYMBOL(generic_write_end); -- cgit v0.10.2 From cf108bca465dde0c015f32dd453b99457d31c7c7 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Invert the locking order of page_lock and transaction start This changes are needed to support data=ordered mode handling via inodes. This enables us to get rid of the journal heads and buffer heads for data buffers in the ordered mode. With the changes, during tranasaction commit we writeout the inode pages using the writepages()/writepage(). That implies we take page lock during transaction commit. This can cause a deadlock with the locking order page_lock -> jbd2_journal_start, since the jbd2_journal_start can wait for the journal_commit to happen and the journal_commit now needs to take the page lock. To avoid this dead lock reverse the locking order. Signed-off-by: Jan Kara Signed-off-by: Mingming Cao Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 98760d1..f65829b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1066,7 +1066,7 @@ extern void ext4_set_inode_flags(struct inode *); extern void ext4_get_inode_flags(struct ext4_inode_info *); extern void ext4_set_aops(struct inode *inode); extern int ext4_writepage_trans_blocks(struct inode *); -extern int ext4_block_truncate_page(handle_t *handle, struct page *page, +extern int ext4_block_truncate_page(handle_t *handle, struct address_space *mapping, loff_t from); extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); @@ -1225,7 +1225,7 @@ extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, unsigned long max_blocks, struct buffer_head *bh_result, int create, int extend_disksize); -extern void ext4_ext_truncate(struct inode *, struct page *); +extern void ext4_ext_truncate(struct inode *); extern void ext4_ext_init(struct super_block *); extern void ext4_ext_release(struct super_block *); extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bb36a28..b722bce 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2749,7 +2749,7 @@ out2: return err ? err : allocated; } -void ext4_ext_truncate(struct inode * inode, struct page *page) +void ext4_ext_truncate(struct inode *inode) { struct address_space *mapping = inode->i_mapping; struct super_block *sb = inode->i_sb; @@ -2762,18 +2762,11 @@ void ext4_ext_truncate(struct inode * inode, struct page *page) */ err = ext4_writepage_trans_blocks(inode) + 3; handle = ext4_journal_start(inode, err); - if (IS_ERR(handle)) { - if (page) { - clear_highpage(page); - flush_dcache_page(page); - unlock_page(page); - page_cache_release(page); - } + if (IS_ERR(handle)) return; - } - if (page) - ext4_block_truncate_page(handle, page, mapping, inode->i_size); + if (inode->i_size & (sb->s_blocksize - 1)) + ext4_block_truncate_page(handle, mapping, inode->i_size); down_write(&EXT4_I(inode)->i_data_sem); ext4_ext_invalidate_cache(inode); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 034fc54..320acb6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1239,19 +1239,20 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, to = from + len; retry: - page = __grab_cache_page(mapping, index); - if (!page) - return -ENOMEM; - *pagep = page; - handle = ext4_journal_start(inode, needed_blocks); if (IS_ERR(handle)) { - unlock_page(page); - page_cache_release(page); ret = PTR_ERR(handle); goto out; } + page = __grab_cache_page(mapping, index); + if (!page) { + ext4_journal_stop(handle); + ret = -ENOMEM; + goto out; + } + *pagep = page; + ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, ext4_get_block); @@ -1261,8 +1262,8 @@ retry: } if (ret) { - ext4_journal_stop(handle); unlock_page(page); + ext4_journal_stop(handle); page_cache_release(page); } @@ -1291,29 +1292,6 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh) } /* - * Generic write_end handler for ordered and writeback ext4 journal modes. - * We can't use generic_write_end, because that unlocks the page and we need to - * unlock the page after ext4_journal_stop, but ext4_journal_stop must run - * after block_write_end. - */ -static int ext4_generic_write_end(struct file *file, - struct address_space *mapping, - loff_t pos, unsigned len, unsigned copied, - struct page *page, void *fsdata) -{ - struct inode *inode = file->f_mapping->host; - - copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); - - if (pos+copied > inode->i_size) { - i_size_write(inode, pos+copied); - mark_inode_dirty(inode); - } - - return copied; -} - -/* * We need to pick up the new inode size which generic_commit_write gave us * `file' can be NULL - eg, when called from page_symlink(). * @@ -1326,7 +1304,7 @@ static int ext4_ordered_write_end(struct file *file, struct page *page, void *fsdata) { handle_t *handle = ext4_journal_current_handle(); - struct inode *inode = file->f_mapping->host; + struct inode *inode = mapping->host; unsigned from, to; int ret = 0, ret2; @@ -1347,7 +1325,7 @@ static int ext4_ordered_write_end(struct file *file, new_i_size = pos + copied; if (new_i_size > EXT4_I(inode)->i_disksize) EXT4_I(inode)->i_disksize = new_i_size; - ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, + ret2 = generic_write_end(file, mapping, pos, len, copied, page, fsdata); copied = ret2; if (ret2 < 0) @@ -1356,8 +1334,6 @@ static int ext4_ordered_write_end(struct file *file, ret2 = ext4_journal_stop(handle); if (!ret) ret = ret2; - unlock_page(page); - page_cache_release(page); return ret ? ret : copied; } @@ -1368,7 +1344,7 @@ static int ext4_writeback_write_end(struct file *file, struct page *page, void *fsdata) { handle_t *handle = ext4_journal_current_handle(); - struct inode *inode = file->f_mapping->host; + struct inode *inode = mapping->host; int ret = 0, ret2; loff_t new_i_size; @@ -1376,7 +1352,7 @@ static int ext4_writeback_write_end(struct file *file, if (new_i_size > EXT4_I(inode)->i_disksize) EXT4_I(inode)->i_disksize = new_i_size; - ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, + ret2 = generic_write_end(file, mapping, pos, len, copied, page, fsdata); copied = ret2; if (ret2 < 0) @@ -1385,8 +1361,6 @@ static int ext4_writeback_write_end(struct file *file, ret2 = ext4_journal_stop(handle); if (!ret) ret = ret2; - unlock_page(page); - page_cache_release(page); return ret ? ret : copied; } @@ -1425,10 +1399,10 @@ static int ext4_journalled_write_end(struct file *file, ret = ret2; } + unlock_page(page); ret2 = ext4_journal_stop(handle); if (!ret) ret = ret2; - unlock_page(page); page_cache_release(page); return ret ? ret : copied; @@ -1505,12 +1479,16 @@ static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh) return 0; } +static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) +{ + return !buffer_mapped(bh) || buffer_delay(bh); +} + /* - * Note that we always start a transaction even if we're not journalling - * data. This is to preserve ordering: any hole instantiation within - * __block_write_full_page -> ext4_get_block() should be journalled - * along with the data so we don't crash and then get metadata which - * refers to old data. + * Note that we don't need to start a transaction unless we're journaling + * data because we should have holes filled from ext4_page_mkwrite(). If + * we are journaling data, we cannot start transaction directly because + * transaction start ranks above page lock so we have to do some magic... * * In all journalling modes block_write_full_page() will start the I/O. * @@ -1554,10 +1532,8 @@ static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh) * disastrous. Any write() or metadata operation will sync the fs for * us. * - * AKPM2: if all the page's buffers are mapped to disk and !data=journal, - * we don't need to open a transaction here. */ -static int ext4_ordered_writepage(struct page *page, +static int __ext4_ordered_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; @@ -1566,22 +1542,6 @@ static int ext4_ordered_writepage(struct page *page, int ret = 0; int err; - J_ASSERT(PageLocked(page)); - - /* - * We give up here if we're reentered, because it might be for a - * different filesystem. - */ - if (ext4_journal_current_handle()) - goto out_fail; - - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); - - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out_fail; - } - if (!page_has_buffers(page)) { create_empty_buffers(page, inode->i_sb->s_blocksize, (1 << BH_Dirty)|(1 << BH_Uptodate)); @@ -1605,54 +1565,135 @@ static int ext4_ordered_writepage(struct page *page, * and generally junk. */ if (ret == 0) { - err = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, + handle = ext4_journal_start(inode, + ext4_writepage_trans_blocks(inode)); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out_put; + } + + ret = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL, jbd2_journal_dirty_data_fn); + err = ext4_journal_stop(handle); if (!ret) ret = err; } - walk_page_buffers(handle, page_bufs, 0, - PAGE_CACHE_SIZE, NULL, bput_one); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; +out_put: + walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL, + bput_one); return ret; +} + +static int ext4_ordered_writepage(struct page *page, + struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + loff_t size = i_size_read(inode); + loff_t len; + + J_ASSERT(PageLocked(page)); + J_ASSERT(page_has_buffers(page)); + if (page->index == size >> PAGE_CACHE_SHIFT) + len = size & ~PAGE_CACHE_MASK; + else + len = PAGE_CACHE_SIZE; + BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, + ext4_bh_unmapped_or_delay)); + + /* + * We give up here if we're reentered, because it might be for a + * different filesystem. + */ + if (!ext4_journal_current_handle()) + return __ext4_ordered_writepage(page, wbc); -out_fail: redirty_page_for_writepage(wbc, page); unlock_page(page); - return ret; + return 0; } +static int __ext4_writeback_writepage(struct page *page, + struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + + if (test_opt(inode->i_sb, NOBH)) + return nobh_writepage(page, ext4_get_block, wbc); + else + return block_write_full_page(page, ext4_get_block, wbc); +} + + static int ext4_writeback_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; + loff_t size = i_size_read(inode); + loff_t len; + + J_ASSERT(PageLocked(page)); + J_ASSERT(page_has_buffers(page)); + if (page->index == size >> PAGE_CACHE_SHIFT) + len = size & ~PAGE_CACHE_MASK; + else + len = PAGE_CACHE_SIZE; + BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, + ext4_bh_unmapped_or_delay)); + + if (!ext4_journal_current_handle()) + return __ext4_writeback_writepage(page, wbc); + + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return 0; +} + +static int __ext4_journalled_writepage(struct page *page, + struct writeback_control *wbc) +{ + struct address_space *mapping = page->mapping; + struct inode *inode = mapping->host; + struct buffer_head *page_bufs; handle_t *handle = NULL; int ret = 0; int err; - if (ext4_journal_current_handle()) - goto out_fail; + ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, ext4_get_block); + if (ret != 0) + goto out_unlock; + + page_bufs = page_buffers(page); + walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL, + bget_one); + /* As soon as we unlock the page, it can go away, but we have + * references to buffers so we are safe */ + unlock_page(page); handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); if (IS_ERR(handle)) { ret = PTR_ERR(handle); - goto out_fail; + goto out; } - if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) - ret = nobh_writepage(page, ext4_get_block, wbc); - else - ret = block_write_full_page(page, ext4_get_block, wbc); + ret = walk_page_buffers(handle, page_bufs, 0, + PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); + err = walk_page_buffers(handle, page_bufs, 0, + PAGE_CACHE_SIZE, NULL, write_end_fn); + if (ret == 0) + ret = err; err = ext4_journal_stop(handle); if (!ret) ret = err; - return ret; -out_fail: - redirty_page_for_writepage(wbc, page); + walk_page_buffers(handle, page_bufs, 0, + PAGE_CACHE_SIZE, NULL, bput_one); + EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; + goto out; + +out_unlock: unlock_page(page); +out: return ret; } @@ -1660,59 +1701,40 @@ static int ext4_journalled_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; - handle_t *handle = NULL; - int ret = 0; - int err; + loff_t size = i_size_read(inode); + loff_t len; - if (ext4_journal_current_handle()) - goto no_write; + J_ASSERT(PageLocked(page)); + J_ASSERT(page_has_buffers(page)); + if (page->index == size >> PAGE_CACHE_SHIFT) + len = size & ~PAGE_CACHE_MASK; + else + len = PAGE_CACHE_SIZE; + BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, + ext4_bh_unmapped_or_delay)); - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); + if (ext4_journal_current_handle()) goto no_write; - } - if (!page_has_buffers(page) || PageChecked(page)) { + if (PageChecked(page)) { /* * It's mmapped pagecache. Add buffers and journal it. There * doesn't seem much point in redirtying the page here. */ ClearPageChecked(page); - ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, - ext4_get_block); - if (ret != 0) { - ext4_journal_stop(handle); - goto out_unlock; - } - ret = walk_page_buffers(handle, page_buffers(page), 0, - PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); - - err = walk_page_buffers(handle, page_buffers(page), 0, - PAGE_CACHE_SIZE, NULL, write_end_fn); - if (ret == 0) - ret = err; - EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; - unlock_page(page); + return __ext4_journalled_writepage(page, wbc); } else { /* * It may be a page full of checkpoint-mode buffers. We don't * really know unless we go poke around in the buffer_heads. * But block_write_full_page will do the right thing. */ - ret = block_write_full_page(page, ext4_get_block, wbc); + return block_write_full_page(page, ext4_get_block, wbc); } - err = ext4_journal_stop(handle); - if (!ret) - ret = err; -out: - return ret; - no_write: redirty_page_for_writepage(wbc, page); -out_unlock: unlock_page(page); - goto out; + return 0; } static int ext4_readpage(struct file *file, struct page *page) @@ -1909,7 +1931,7 @@ void ext4_set_aops(struct inode *inode) * This required during truncate. We need to physically zero the tail end * of that block so it doesn't yield old data if the file is later grown. */ -int ext4_block_truncate_page(handle_t *handle, struct page *page, +int ext4_block_truncate_page(handle_t *handle, struct address_space *mapping, loff_t from) { ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; @@ -1918,8 +1940,13 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, ext4_lblk_t iblock; struct inode *inode = mapping->host; struct buffer_head *bh; + struct page *page; int err = 0; + page = grab_cache_page(mapping, from >> PAGE_CACHE_SHIFT); + if (!page) + return -EINVAL; + blocksize = inode->i_sb->s_blocksize; length = blocksize - (offset & (blocksize - 1)); iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); @@ -2410,46 +2437,25 @@ void ext4_truncate(struct inode *inode) int n; ext4_lblk_t last_block; unsigned blocksize = inode->i_sb->s_blocksize; - struct page *page; if (!ext4_can_truncate(inode)) return; - /* - * We have to lock the EOF page here, because lock_page() nests - * outside jbd2_journal_start(). - */ - if ((inode->i_size & (blocksize - 1)) == 0) { - /* Block boundary? Nothing to do */ - page = NULL; - } else { - page = grab_cache_page(mapping, - inode->i_size >> PAGE_CACHE_SHIFT); - if (!page) - return; - } - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { - ext4_ext_truncate(inode, page); + ext4_ext_truncate(inode); return; } handle = start_transaction(inode); - if (IS_ERR(handle)) { - if (page) { - clear_highpage(page); - flush_dcache_page(page); - unlock_page(page); - page_cache_release(page); - } + if (IS_ERR(handle)) return; /* AKPM: return what? */ - } last_block = (inode->i_size + blocksize-1) >> EXT4_BLOCK_SIZE_BITS(inode->i_sb); - if (page) - ext4_block_truncate_page(handle, page, mapping, inode->i_size); + if (inode->i_size & (blocksize - 1)) + if (ext4_block_truncate_page(handle, mapping, inode->i_size)) + goto out_stop; n = ext4_block_to_path(inode, last_block, offsets, NULL); if (n == 0) -- cgit v0.10.2 From 9ddfc3dc75b5cc55ff3cfa586e962d252f1db9d3 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Fix lock inversion in ext4_ext_truncate() We cannot call ext4_orphan_add() from under i_data_sem because that causes a lock ordering violation between i_data_sem and and the superblock lock. Updated with Aneesh's locking order fix Signed-off-by: Jan Kara Signed-off-by: Mingming Cao Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b722bce..7844bbb 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2768,6 +2768,9 @@ void ext4_ext_truncate(struct inode *inode) if (inode->i_size & (sb->s_blocksize - 1)) ext4_block_truncate_page(handle, mapping, inode->i_size); + if (ext4_orphan_add(handle, inode)) + goto out_stop; + down_write(&EXT4_I(inode)->i_data_sem); ext4_ext_invalidate_cache(inode); @@ -2778,8 +2781,6 @@ void ext4_ext_truncate(struct inode *inode) * Probably we need not scan at all, * because page truncation is enough. */ - if (ext4_orphan_add(handle, inode)) - goto out_stop; /* we have to know where to truncate from in crash case */ EXT4_I(inode)->i_disksize = inode->i_size; @@ -2796,6 +2797,7 @@ void ext4_ext_truncate(struct inode *inode) handle->h_sync = 1; out_stop: + up_write(&EXT4_I(inode)->i_data_sem); /* * If this was a simple ftruncate() and the file will remain alive, * then we need to clear up the orphan record which we created above. @@ -2806,7 +2808,6 @@ out_stop: if (inode->i_nlink) ext4_orphan_del(handle, inode); - up_write(&EXT4_I(inode)->i_data_sem); inode->i_mtime = inode->i_ctime = ext4_current_time(inode); ext4_mark_inode_dirty(handle, inode); ext4_journal_stop(handle); -- cgit v0.10.2 From f4c0a0fdfae708f7aa438c27a380ed4071294e11 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: vfs: export filemap_fdatawrite_range() Make filemap_fdatawrite_range() function public, so that it can later be used in ordered mode rewrite by JBD/JBD2. Signed-off-by: Jan Kara diff --git a/include/linux/fs.h b/include/linux/fs.h index d8e2762..97f992a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1740,6 +1740,8 @@ extern int wait_on_page_writeback_range(struct address_space *mapping, pgoff_t start, pgoff_t end); extern int __filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end, int sync_mode); +extern int filemap_fdatawrite_range(struct address_space *mapping, + loff_t start, loff_t end); extern long do_fsync(struct file *file, int datasync); extern void sync_supers(void); diff --git a/mm/filemap.c b/mm/filemap.c index 1e6a7d3..65d9d9e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -236,11 +236,12 @@ int filemap_fdatawrite(struct address_space *mapping) } EXPORT_SYMBOL(filemap_fdatawrite); -static int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, +int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end) { return __filemap_fdatawrite_range(mapping, start, end, WB_SYNC_ALL); } +EXPORT_SYMBOL(filemap_fdatawrite_range); /** * filemap_flush - mostly a non-blocking flush -- cgit v0.10.2 From c851ed540173736e60d48b53b91a16ea5c903896 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: jbd2: Implement data=ordered mode handling via inodes This patch adds necessary framework into JBD2 to be able to track inodes with each transaction and write-out their dirty data during transaction commit time. This new ordered mode brings all sorts of advantages such as possibility to get rid of journal heads and buffer heads for data buffers in ordered mode, better ordering of writes on transaction commit, simplification of some JBD code, no more anonymous pages when truncate of data being committed happens. Also with this new ordered mode, delayed allocation on ordered mode is much simpler. Signed-off-by: Jan Kara diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 92b6ac3..3ca107b 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -355,6 +355,81 @@ write_out_data: journal_do_submit_data(wbuf, bufs); } +/* + * Submit all the data buffers of inode associated with the transaction to + * disk. + * + * We are in a committing transaction. Therefore no new inode can be added to + * our inode list. We use JI_COMMIT_RUNNING flag to protect inode we currently + * operate on from being released while we write out pages. + */ +static int journal_submit_inode_data_buffers(journal_t *journal, + transaction_t *commit_transaction) +{ + struct jbd2_inode *jinode; + int err, ret = 0; + struct address_space *mapping; + + spin_lock(&journal->j_list_lock); + list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { + mapping = jinode->i_vfs_inode->i_mapping; + jinode->i_flags |= JI_COMMIT_RUNNING; + spin_unlock(&journal->j_list_lock); + err = filemap_fdatawrite_range(mapping, 0, + i_size_read(jinode->i_vfs_inode)); + if (!ret) + ret = err; + spin_lock(&journal->j_list_lock); + J_ASSERT(jinode->i_transaction == commit_transaction); + jinode->i_flags &= ~JI_COMMIT_RUNNING; + wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); + } + spin_unlock(&journal->j_list_lock); + return ret; +} + +/* + * Wait for data submitted for writeout, refile inodes to proper + * transaction if needed. + * + */ +static int journal_finish_inode_data_buffers(journal_t *journal, + transaction_t *commit_transaction) +{ + struct jbd2_inode *jinode, *next_i; + int err, ret = 0; + + /* For locking, see the comment in journal_submit_inode_data_buffers() */ + spin_lock(&journal->j_list_lock); + list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { + jinode->i_flags |= JI_COMMIT_RUNNING; + spin_unlock(&journal->j_list_lock); + err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping); + if (!ret) + ret = err; + spin_lock(&journal->j_list_lock); + jinode->i_flags &= ~JI_COMMIT_RUNNING; + wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); + } + + /* Now refile inode to proper lists */ + list_for_each_entry_safe(jinode, next_i, + &commit_transaction->t_inode_list, i_list) { + list_del(&jinode->i_list); + if (jinode->i_next_transaction) { + jinode->i_transaction = jinode->i_next_transaction; + jinode->i_next_transaction = NULL; + list_add(&jinode->i_list, + &jinode->i_transaction->t_inode_list); + } else { + jinode->i_transaction = NULL; + } + } + spin_unlock(&journal->j_list_lock); + + return ret; +} + static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) { struct page *page = bh->b_page; @@ -529,6 +604,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) */ err = 0; journal_submit_data_buffers(journal, commit_transaction); + err = journal_submit_inode_data_buffers(journal, commit_transaction); + if (err) + jbd2_journal_abort(journal, err); /* * Wait for all previously submitted IO to complete if commit @@ -760,6 +838,17 @@ start_journal_io: __jbd2_journal_abort_hard(journal); } + /* + * This is the right place to wait for data buffers both for ASYNC + * and !ASYNC commit. If commit is ASYNC, we need to wait only after + * the commit block went to disk (which happens above). If commit is + * SYNC, we need to wait for data buffers before we start writing + * commit block, which happens below in such setting. + */ + err = journal_finish_inode_data_buffers(journal, commit_transaction); + if (err) + jbd2_journal_abort(journal, err); + /* Lo and behold: we have just managed to send a transaction to the log. Before we can commit it, wait for the IO so far to complete. Control buffers being written are on the @@ -880,6 +969,7 @@ wait_for_iobuf: jbd_debug(3, "JBD: commit phase 7\n"); J_ASSERT(commit_transaction->t_sync_datalist == NULL); + J_ASSERT(list_empty(&commit_transaction->t_inode_list)); J_ASSERT(commit_transaction->t_buffers == NULL); J_ASSERT(commit_transaction->t_checkpoint_list == NULL); J_ASSERT(commit_transaction->t_iobuf_list == NULL); diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 2e24567..78cf7bd 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -82,6 +82,10 @@ EXPORT_SYMBOL(jbd2_journal_blocks_per_page); EXPORT_SYMBOL(jbd2_journal_invalidatepage); EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); EXPORT_SYMBOL(jbd2_journal_force_commit); +EXPORT_SYMBOL(jbd2_journal_file_inode); +EXPORT_SYMBOL(jbd2_journal_init_jbd_inode); +EXPORT_SYMBOL(jbd2_journal_release_jbd_inode); +EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); static void __journal_abort_soft (journal_t *journal, int errno); @@ -2195,6 +2199,54 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) } /* + * Initialize jbd inode head + */ +void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode) +{ + jinode->i_transaction = NULL; + jinode->i_next_transaction = NULL; + jinode->i_vfs_inode = inode; + jinode->i_flags = 0; + INIT_LIST_HEAD(&jinode->i_list); +} + +/* + * Function to be called before we start removing inode from memory (i.e., + * clear_inode() is a fine place to be called from). It removes inode from + * transaction's lists. + */ +void jbd2_journal_release_jbd_inode(journal_t *journal, + struct jbd2_inode *jinode) +{ + int writeout = 0; + + if (!journal) + return; +restart: + spin_lock(&journal->j_list_lock); + /* Is commit writing out inode - we have to wait */ + if (jinode->i_flags & JI_COMMIT_RUNNING) { + wait_queue_head_t *wq; + DEFINE_WAIT_BIT(wait, &jinode->i_flags, __JI_COMMIT_RUNNING); + wq = bit_waitqueue(&jinode->i_flags, __JI_COMMIT_RUNNING); + prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); + spin_unlock(&journal->j_list_lock); + schedule(); + finish_wait(wq, &wait.wait); + goto restart; + } + + /* Do we need to wait for data writeback? */ + if (journal->j_committing_transaction == jinode->i_transaction) + writeout = 1; + if (jinode->i_transaction) { + list_del(&jinode->i_list); + jinode->i_transaction = NULL; + } + spin_unlock(&journal->j_list_lock); +} + +/* * debugfs tunables */ #ifdef CONFIG_JBD2_DEBUG diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index ba620c4..98b596d 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -51,6 +51,7 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) transaction->t_tid = journal->j_transaction_sequence++; transaction->t_expires = jiffies + journal->j_commit_interval; spin_lock_init(&transaction->t_handle_lock); + INIT_LIST_HEAD(&transaction->t_inode_list); /* Set up the commit timer for the new transaction. */ journal->j_commit_timer.expires = round_jiffies(transaction->t_expires); @@ -2195,3 +2196,88 @@ void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh) spin_unlock(&journal->j_list_lock); __brelse(bh); } + +/* + * File inode in the inode list of the handle's transaction + */ +int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) +{ + transaction_t *transaction = handle->h_transaction; + journal_t *journal = transaction->t_journal; + + if (is_handle_aborted(handle)) + return -EIO; + + jbd_debug(4, "Adding inode %lu, tid:%d\n", jinode->i_vfs_inode->i_ino, + transaction->t_tid); + + /* + * First check whether inode isn't already on the transaction's + * lists without taking the lock. Note that this check is safe + * without the lock as we cannot race with somebody removing inode + * from the transaction. The reason is that we remove inode from the + * transaction only in journal_release_jbd_inode() and when we commit + * the transaction. We are guarded from the first case by holding + * a reference to the inode. We are safe against the second case + * because if jinode->i_transaction == transaction, commit code + * cannot touch the transaction because we hold reference to it, + * and if jinode->i_next_transaction == transaction, commit code + * will only file the inode where we want it. + */ + if (jinode->i_transaction == transaction || + jinode->i_next_transaction == transaction) + return 0; + + spin_lock(&journal->j_list_lock); + + if (jinode->i_transaction == transaction || + jinode->i_next_transaction == transaction) + goto done; + + /* On some different transaction's list - should be + * the committing one */ + if (jinode->i_transaction) { + J_ASSERT(jinode->i_next_transaction == NULL); + J_ASSERT(jinode->i_transaction == + journal->j_committing_transaction); + jinode->i_next_transaction = transaction; + goto done; + } + /* Not on any transaction list... */ + J_ASSERT(!jinode->i_next_transaction); + jinode->i_transaction = transaction; + list_add(&jinode->i_list, &transaction->t_inode_list); +done: + spin_unlock(&journal->j_list_lock); + + return 0; +} + +/* + * 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(struct jbd2_inode *inode, + loff_t new_size) +{ + journal_t *journal; + transaction_t *commit_trans; + int ret = 0; + + if (!inode->i_transaction && !inode->i_next_transaction) + goto out; + journal = inode->i_transaction->t_journal; + spin_lock(&journal->j_state_lock); + commit_trans = journal->j_committing_transaction; + spin_unlock(&journal->j_state_lock); + 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); + } +out: + return ret; +} diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index ec9cadf..622c3d8 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -381,6 +381,38 @@ static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) bit_spin_unlock(BH_JournalHead, &bh->b_state); } +/* Flags in jbd_inode->i_flags */ +#define __JI_COMMIT_RUNNING 0 +/* Commit of the inode data in progress. We use this flag to protect us from + * concurrent deletion of inode. We cannot use reference to inode for this + * since we cannot afford doing last iput() on behalf of kjournald + */ +#define JI_COMMIT_RUNNING (1 << __JI_COMMIT_RUNNING) + +/** + * struct jbd_inode is the structure linking inodes in ordered mode + * present in a transaction so that we can sync them during commit. + */ +struct jbd2_inode { + /* Which transaction does this inode belong to? Either the running + * transaction or the committing one. [j_list_lock] */ + transaction_t *i_transaction; + + /* Pointer to the running transaction modifying inode's data in case + * there is already a committing transaction touching it. [j_list_lock] */ + transaction_t *i_next_transaction; + + /* List of inodes in the i_transaction [j_list_lock] */ + struct list_head i_list; + + /* VFS inode this inode belongs to [constant during the lifetime + * of the structure] */ + struct inode *i_vfs_inode; + + /* Flags of inode [j_list_lock] */ + unsigned int i_flags; +}; + struct jbd2_revoke_table_s; /** @@ -567,6 +599,12 @@ struct transaction_s struct journal_head *t_log_list; /* + * List of inodes whose data we've modified in data=ordered mode. + * [j_list_lock] + */ + struct list_head t_inode_list; + + /* * Protects info related to handles */ spinlock_t t_handle_lock; @@ -1046,6 +1084,10 @@ extern void jbd2_journal_ack_err (journal_t *); extern int jbd2_journal_clear_err (journal_t *); 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(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); /* * journal_head management -- cgit v0.10.2 From 678aaf481496b01473b778685eca231d6784098b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Use new framework for data=ordered mode in JBD2 This patch makes ext4 use inode-based implementation of data=ordered mode in JBD2. It allows us to unify some data=ordered and data=writeback paths (especially writepage since we don't have to start a transaction anymore) and remove some buffer walking. Updated fix from Aneesh Kumar K.V to fix file system hang due to corrupt jinode values. Signed-off-by: Jan Kara Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ext4_i.h b/fs/ext4/ext4_i.h index abf2744..c2903ef 100644 --- a/fs/ext4/ext4_i.h +++ b/fs/ext4/ext4_i.h @@ -150,6 +150,7 @@ struct ext4_inode_info { */ struct rw_semaphore i_data_sem; struct inode vfs_inode; + struct jbd2_inode jinode; unsigned long i_ext_generation; struct ext4_ext_cache i_cached_extent; diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index d0aa9ee..eb8bc3a 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h @@ -154,8 +154,6 @@ int __ext4_journal_dirty_metadata(const char *where, #define ext4_journal_forget(handle, bh) \ __ext4_journal_forget(__func__, (handle), (bh)) -int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh); - handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); int __ext4_journal_stop(const char *where, handle_t *handle); @@ -192,6 +190,11 @@ static inline int ext4_journal_force_commit(journal_t *journal) return jbd2_journal_force_commit(journal); } +static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode) +{ + return jbd2_journal_file_inode(handle, &EXT4_I(inode)->jinode); +} + /* super.c */ int ext4_force_commit(struct super_block *sb); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 320acb6..7b95691 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -39,6 +39,13 @@ #include "xattr.h" #include "acl.h" +static inline int ext4_begin_ordered_truncate(struct inode *inode, + loff_t new_size) +{ + return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, + new_size); +} + /* * Test whether an inode is a fast symlink. */ @@ -181,6 +188,8 @@ void ext4_delete_inode (struct inode * inode) { handle_t *handle; + if (ext4_should_order_data(inode)) + ext4_begin_ordered_truncate(inode, 0); truncate_inode_pages(&inode->i_data, 0); if (is_bad_inode(inode)) @@ -1273,15 +1282,6 @@ out: return ret; } -int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh) -{ - int err = jbd2_journal_dirty_data(handle, bh); - if (err) - ext4_journal_abort_handle(__func__, __func__, - bh, handle, err); - return err; -} - /* For write_end() in data=journal mode */ static int write_end_fn(handle_t *handle, struct buffer_head *bh) { @@ -1311,8 +1311,7 @@ static int ext4_ordered_write_end(struct file *file, from = pos & (PAGE_CACHE_SIZE - 1); to = from + len; - ret = walk_page_buffers(handle, page_buffers(page), - from, to, NULL, ext4_journal_dirty_data); + ret = ext4_jbd2_file_inode(handle, inode); if (ret == 0) { /* @@ -1472,25 +1471,22 @@ static int bput_one(handle_t *handle, struct buffer_head *bh) return 0; } -static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh) -{ - if (buffer_mapped(bh)) - return ext4_journal_dirty_data(handle, bh); - return 0; -} - static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) { return !buffer_mapped(bh) || buffer_delay(bh); } /* - * Note that we don't need to start a transaction unless we're journaling - * data because we should have holes filled from ext4_page_mkwrite(). If - * we are journaling data, we cannot start transaction directly because - * transaction start ranks above page lock so we have to do some magic... + * Note that we don't need to start a transaction unless we're journaling data + * because we should have holes filled from ext4_page_mkwrite(). We even don't + * need to file the inode to the transaction's list in ordered mode because if + * we are writing back data added by write(), the inode is already there and if + * we are writing back data modified via mmap(), noone guarantees in which + * transaction the data will hit the disk. In case we are journaling data, we + * cannot start transaction directly because transaction start ranks above page + * lock so we have to do some magic. * - * In all journalling modes block_write_full_page() will start the I/O. + * In all journaling modes block_write_full_page() will start the I/O. * * Problem: * @@ -1533,86 +1529,7 @@ static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) * us. * */ -static int __ext4_ordered_writepage(struct page *page, - struct writeback_control *wbc) -{ - struct inode *inode = page->mapping->host; - struct buffer_head *page_bufs; - handle_t *handle = NULL; - int ret = 0; - int err; - - if (!page_has_buffers(page)) { - create_empty_buffers(page, inode->i_sb->s_blocksize, - (1 << BH_Dirty)|(1 << BH_Uptodate)); - } - page_bufs = page_buffers(page); - walk_page_buffers(handle, page_bufs, 0, - PAGE_CACHE_SIZE, NULL, bget_one); - - ret = block_write_full_page(page, ext4_get_block, wbc); - - /* - * The page can become unlocked at any point now, and - * truncate can then come in and change things. So we - * can't touch *page from now on. But *page_bufs is - * safe due to elevated refcount. - */ - - /* - * And attach them to the current transaction. But only if - * block_write_full_page() succeeded. Otherwise they are unmapped, - * and generally junk. - */ - if (ret == 0) { - handle = ext4_journal_start(inode, - ext4_writepage_trans_blocks(inode)); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out_put; - } - - ret = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, - NULL, jbd2_journal_dirty_data_fn); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - } -out_put: - walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL, - bput_one); - return ret; -} - -static int ext4_ordered_writepage(struct page *page, - struct writeback_control *wbc) -{ - struct inode *inode = page->mapping->host; - loff_t size = i_size_read(inode); - loff_t len; - - J_ASSERT(PageLocked(page)); - J_ASSERT(page_has_buffers(page)); - if (page->index == size >> PAGE_CACHE_SHIFT) - len = size & ~PAGE_CACHE_MASK; - else - len = PAGE_CACHE_SIZE; - BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, - ext4_bh_unmapped_or_delay)); - - /* - * We give up here if we're reentered, because it might be for a - * different filesystem. - */ - if (!ext4_journal_current_handle()) - return __ext4_ordered_writepage(page, wbc); - - redirty_page_for_writepage(wbc, page); - unlock_page(page); - return 0; -} - -static int __ext4_writeback_writepage(struct page *page, +static int __ext4_normal_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; @@ -1624,7 +1541,7 @@ static int __ext4_writeback_writepage(struct page *page, } -static int ext4_writeback_writepage(struct page *page, +static int ext4_normal_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; @@ -1641,7 +1558,7 @@ static int ext4_writeback_writepage(struct page *page, ext4_bh_unmapped_or_delay)); if (!ext4_journal_current_handle()) - return __ext4_writeback_writepage(page, wbc); + return __ext4_normal_writepage(page, wbc); redirty_page_for_writepage(wbc, page); unlock_page(page); @@ -1877,7 +1794,7 @@ static int ext4_journalled_set_page_dirty(struct page *page) static const struct address_space_operations ext4_ordered_aops = { .readpage = ext4_readpage, .readpages = ext4_readpages, - .writepage = ext4_ordered_writepage, + .writepage = ext4_normal_writepage, .sync_page = block_sync_page, .write_begin = ext4_write_begin, .write_end = ext4_ordered_write_end, @@ -1891,7 +1808,7 @@ static const struct address_space_operations ext4_ordered_aops = { static const struct address_space_operations ext4_writeback_aops = { .readpage = ext4_readpage, .readpages = ext4_readpages, - .writepage = ext4_writeback_writepage, + .writepage = ext4_normal_writepage, .sync_page = block_sync_page, .write_begin = ext4_write_begin, .write_end = ext4_writeback_write_end, @@ -2019,7 +1936,7 @@ int ext4_block_truncate_page(handle_t *handle, err = ext4_journal_dirty_metadata(handle, bh); } else { if (ext4_should_order_data(inode)) - err = ext4_journal_dirty_data(handle, bh); + err = ext4_jbd2_file_inode(handle, inode); mark_buffer_dirty(bh); } @@ -3171,7 +3088,14 @@ int ext4_write_inode(struct inode *inode, int wait) * be freed, so we have a strong guarantee that no future commit will * leave these blocks visible to the user.) * - * Called with inode->sem down. + * Another thing we have to assure is that if we are in ordered mode + * and inode is still attached to the committing transaction, we must + * we start writeout of all the dirty pages which are being truncated. + * This way we are sure that all the data written in the previous + * transaction are already on disk (truncate waits for pages under + * writeback). + * + * Called with inode->i_mutex down. */ int ext4_setattr(struct dentry *dentry, struct iattr *attr) { @@ -3237,6 +3161,22 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) if (!error) error = rc; ext4_journal_stop(handle); + + if (ext4_should_order_data(inode)) { + error = ext4_begin_ordered_truncate(inode, + attr->ia_size); + if (error) { + /* Do as much error cleanup as possible */ + handle = ext4_journal_start(inode, 3); + if (IS_ERR(handle)) { + ext4_orphan_del(NULL, inode); + goto err_out; + } + ext4_orphan_del(handle, inode); + ext4_journal_stop(handle); + goto err_out; + } + } } rc = inode_setattr(inode, attr); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1b330cd..629d0fa2 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -573,6 +573,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); INIT_LIST_HEAD(&ei->i_prealloc_list); spin_lock_init(&ei->i_prealloc_lock); + jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode); return &ei->vfs_inode; } @@ -637,6 +638,8 @@ static void ext4_clear_inode(struct inode *inode) EXT4_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) kfree(rsv); + jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, + &EXT4_I(inode)->jinode); } static inline void ext4_show_quota_options(struct seq_file *seq, struct super_block *sb) @@ -3378,7 +3381,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, err = ext4_journal_dirty_metadata(handle, bh); else { /* Always do at least ordered writes for quotas */ - err = ext4_journal_dirty_data(handle, bh); + err = ext4_jbd2_file_inode(handle, inode); mark_buffer_dirty(bh); } brelse(bh); -- cgit v0.10.2 From 87c89c232c8f7b3820c33c3b9bc803e9358027da Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: jbd2: Remove data=ordered mode support using jbd buffer heads Signed-off-by: Jan Kara diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 6914598..91389c8 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -688,7 +688,6 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transact J_ASSERT(transaction->t_state == T_FINISHED); J_ASSERT(transaction->t_buffers == NULL); - J_ASSERT(transaction->t_sync_datalist == NULL); J_ASSERT(transaction->t_forget == NULL); J_ASSERT(transaction->t_iobuf_list == NULL); J_ASSERT(transaction->t_shadow_list == NULL); diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 3ca107b..483183d 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -37,8 +37,8 @@ static void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate) } /* - * When an ext3-ordered file is truncated, it is possible that many pages are - * not sucessfully freed, because they are attached to a committing transaction. + * When an ext4 file is truncated, it is possible that some pages are not + * successfully freed, because they are attached to a committing transaction. * After the transaction commits, these pages are left on the LRU, with no * ->mapping, and with attached buffers. These pages are trivially reclaimable * by the VM, but their apparent absence upsets the VM accounting, and it makes @@ -80,21 +80,6 @@ nope: } /* - * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_lock is - * held. For ranking reasons we must trylock. If we lose, schedule away and - * return 0. j_list_lock is dropped in this case. - */ -static int inverted_lock(journal_t *journal, struct buffer_head *bh) -{ - if (!jbd_trylock_bh_state(bh)) { - spin_unlock(&journal->j_list_lock); - schedule(); - return 0; - } - return 1; -} - -/* * Done it all: now submit the commit record. We should have * cleaned up our previous buffers by now, so if we are in abort * mode we can now just skip the rest of the journal write @@ -200,162 +185,6 @@ static int journal_wait_on_commit_record(struct buffer_head *bh) } /* - * Wait for all submitted IO to complete. - */ -static int journal_wait_on_locked_list(journal_t *journal, - transaction_t *commit_transaction) -{ - int ret = 0; - struct journal_head *jh; - - while (commit_transaction->t_locked_list) { - struct buffer_head *bh; - - jh = commit_transaction->t_locked_list->b_tprev; - bh = jh2bh(jh); - get_bh(bh); - if (buffer_locked(bh)) { - spin_unlock(&journal->j_list_lock); - wait_on_buffer(bh); - if (unlikely(!buffer_uptodate(bh))) - ret = -EIO; - spin_lock(&journal->j_list_lock); - } - if (!inverted_lock(journal, bh)) { - put_bh(bh); - spin_lock(&journal->j_list_lock); - continue; - } - if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) { - __jbd2_journal_unfile_buffer(jh); - jbd_unlock_bh_state(bh); - jbd2_journal_remove_journal_head(bh); - put_bh(bh); - } else { - jbd_unlock_bh_state(bh); - } - put_bh(bh); - cond_resched_lock(&journal->j_list_lock); - } - return ret; - } - -static void journal_do_submit_data(struct buffer_head **wbuf, int bufs) -{ - int i; - - for (i = 0; i < bufs; i++) { - wbuf[i]->b_end_io = end_buffer_write_sync; - /* We use-up our safety reference in submit_bh() */ - submit_bh(WRITE, wbuf[i]); - } -} - -/* - * Submit all the data buffers to disk - */ -static void journal_submit_data_buffers(journal_t *journal, - transaction_t *commit_transaction) -{ - struct journal_head *jh; - struct buffer_head *bh; - int locked; - int bufs = 0; - struct buffer_head **wbuf = journal->j_wbuf; - - /* - * Whenever we unlock the journal and sleep, things can get added - * onto ->t_sync_datalist, so we have to keep looping back to - * write_out_data until we *know* that the list is empty. - * - * Cleanup any flushed data buffers from the data list. Even in - * abort mode, we want to flush this out as soon as possible. - */ -write_out_data: - cond_resched(); - spin_lock(&journal->j_list_lock); - - while (commit_transaction->t_sync_datalist) { - jh = commit_transaction->t_sync_datalist; - bh = jh2bh(jh); - locked = 0; - - /* Get reference just to make sure buffer does not disappear - * when we are forced to drop various locks */ - get_bh(bh); - /* If the buffer is dirty, we need to submit IO and hence - * we need the buffer lock. We try to lock the buffer without - * blocking. If we fail, we need to drop j_list_lock and do - * blocking lock_buffer(). - */ - if (buffer_dirty(bh)) { - if (test_set_buffer_locked(bh)) { - BUFFER_TRACE(bh, "needs blocking lock"); - spin_unlock(&journal->j_list_lock); - /* Write out all data to prevent deadlocks */ - journal_do_submit_data(wbuf, bufs); - bufs = 0; - lock_buffer(bh); - spin_lock(&journal->j_list_lock); - } - locked = 1; - } - /* We have to get bh_state lock. Again out of order, sigh. */ - if (!inverted_lock(journal, bh)) { - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - } - /* Someone already cleaned up the buffer? */ - if (!buffer_jbd(bh) - || jh->b_transaction != commit_transaction - || jh->b_jlist != BJ_SyncData) { - jbd_unlock_bh_state(bh); - if (locked) - unlock_buffer(bh); - BUFFER_TRACE(bh, "already cleaned up"); - put_bh(bh); - continue; - } - if (locked && test_clear_buffer_dirty(bh)) { - BUFFER_TRACE(bh, "needs writeout, adding to array"); - wbuf[bufs++] = bh; - __jbd2_journal_file_buffer(jh, commit_transaction, - BJ_Locked); - jbd_unlock_bh_state(bh); - if (bufs == journal->j_wbufsize) { - spin_unlock(&journal->j_list_lock); - journal_do_submit_data(wbuf, bufs); - bufs = 0; - goto write_out_data; - } - } else if (!locked && buffer_locked(bh)) { - __jbd2_journal_file_buffer(jh, commit_transaction, - BJ_Locked); - jbd_unlock_bh_state(bh); - put_bh(bh); - } else { - BUFFER_TRACE(bh, "writeout complete: unfile"); - __jbd2_journal_unfile_buffer(jh); - jbd_unlock_bh_state(bh); - if (locked) - unlock_buffer(bh); - jbd2_journal_remove_journal_head(bh); - /* Once for our safety reference, once for - * jbd2_journal_remove_journal_head() */ - put_bh(bh); - put_bh(bh); - } - - if (need_resched() || spin_needbreak(&journal->j_list_lock)) { - spin_unlock(&journal->j_list_lock); - goto write_out_data; - } - } - spin_unlock(&journal->j_list_lock); - journal_do_submit_data(wbuf, bufs); -} - -/* * Submit all the data buffers of inode associated with the transaction to * disk. * @@ -602,42 +431,15 @@ void jbd2_journal_commit_transaction(journal_t *journal) * Now start flushing things to disk, in the order they appear * on the transaction lists. Data blocks go first. */ - err = 0; - journal_submit_data_buffers(journal, commit_transaction); err = journal_submit_inode_data_buffers(journal, commit_transaction); if (err) jbd2_journal_abort(journal, err); - /* - * Wait for all previously submitted IO to complete if commit - * record is to be written synchronously. - */ - spin_lock(&journal->j_list_lock); - if (!JBD2_HAS_INCOMPAT_FEATURE(journal, - JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) - err = journal_wait_on_locked_list(journal, - commit_transaction); - - spin_unlock(&journal->j_list_lock); - - if (err) - jbd2_journal_abort(journal, err); - jbd2_journal_write_revoke_records(journal, commit_transaction); jbd_debug(3, "JBD: commit phase 2\n"); /* - * If we found any dirty or locked buffers, then we should have - * looped back up to the write_out_data label. If there weren't - * any then journal_clean_data_list should have wiped the list - * clean by now, so check that it is in fact empty. - */ - J_ASSERT (commit_transaction->t_sync_datalist == NULL); - - jbd_debug (3, "JBD: commit phase 3\n"); - - /* * Way to go: we have now written out all of the data for a * transaction! Now comes the tricky part: we need to write out * metadata. Loop over the transaction's entire buffer list: @@ -655,6 +457,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) J_ASSERT(commit_transaction->t_nr_buffers <= commit_transaction->t_outstanding_credits); + err = 0; descriptor = NULL; bufs = 0; while (commit_transaction->t_buffers) { @@ -829,13 +632,6 @@ start_journal_io: &cbh, crc32_sum); if (err) __jbd2_journal_abort_hard(journal); - - spin_lock(&journal->j_list_lock); - err = journal_wait_on_locked_list(journal, - commit_transaction); - spin_unlock(&journal->j_list_lock); - if (err) - __jbd2_journal_abort_hard(journal); } /* @@ -860,7 +656,7 @@ start_journal_io: so we incur less scheduling load. */ - jbd_debug(3, "JBD: commit phase 4\n"); + jbd_debug(3, "JBD: commit phase 3\n"); /* * akpm: these are BJ_IO, and j_list_lock is not needed. @@ -919,7 +715,7 @@ wait_for_iobuf: J_ASSERT (commit_transaction->t_shadow_list == NULL); - jbd_debug(3, "JBD: commit phase 5\n"); + jbd_debug(3, "JBD: commit phase 4\n"); /* Here we wait for the revoke record and descriptor record buffers */ wait_for_ctlbuf: @@ -946,7 +742,7 @@ wait_for_iobuf: /* AKPM: bforget here */ } - jbd_debug(3, "JBD: commit phase 6\n"); + jbd_debug(3, "JBD: commit phase 5\n"); if (!JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { @@ -966,9 +762,8 @@ wait_for_iobuf: transaction can be removed from any checkpoint list it was on before. */ - jbd_debug(3, "JBD: commit phase 7\n"); + jbd_debug(3, "JBD: commit phase 6\n"); - J_ASSERT(commit_transaction->t_sync_datalist == NULL); J_ASSERT(list_empty(&commit_transaction->t_inode_list)); J_ASSERT(commit_transaction->t_buffers == NULL); J_ASSERT(commit_transaction->t_checkpoint_list == NULL); @@ -1090,7 +885,7 @@ restart_loop: /* Done with this transaction! */ - jbd_debug(3, "JBD: commit phase 8\n"); + jbd_debug(3, "JBD: commit phase 7\n"); J_ASSERT(commit_transaction->t_state == T_COMMIT); diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 78cf7bd..b26c6d9 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -50,7 +50,6 @@ EXPORT_SYMBOL(jbd2_journal_unlock_updates); EXPORT_SYMBOL(jbd2_journal_get_write_access); EXPORT_SYMBOL(jbd2_journal_get_create_access); EXPORT_SYMBOL(jbd2_journal_get_undo_access); -EXPORT_SYMBOL(jbd2_journal_dirty_data); EXPORT_SYMBOL(jbd2_journal_dirty_metadata); EXPORT_SYMBOL(jbd2_journal_release_buffer); EXPORT_SYMBOL(jbd2_journal_forget); diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 98b596d..4f7cadb 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -943,183 +943,6 @@ out: } /** - * int jbd2_journal_dirty_data() - mark a buffer as containing dirty data which - * needs to be flushed before we can commit the - * current transaction. - * @handle: transaction - * @bh: bufferhead to mark - * - * The buffer is placed on the transaction's data list and is marked as - * belonging to the transaction. - * - * Returns error number or 0 on success. - * - * jbd2_journal_dirty_data() can be called via page_launder->ext3_writepage - * by kswapd. - */ -int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh) -{ - journal_t *journal = handle->h_transaction->t_journal; - int need_brelse = 0; - struct journal_head *jh; - - if (is_handle_aborted(handle)) - return 0; - - jh = jbd2_journal_add_journal_head(bh); - JBUFFER_TRACE(jh, "entry"); - - /* - * The buffer could *already* be dirty. Writeout can start - * at any time. - */ - jbd_debug(4, "jh: %p, tid:%d\n", jh, handle->h_transaction->t_tid); - - /* - * What if the buffer is already part of a running transaction? - * - * There are two cases: - * 1) It is part of the current running transaction. Refile it, - * just in case we have allocated it as metadata, deallocated - * it, then reallocated it as data. - * 2) It is part of the previous, still-committing transaction. - * If all we want to do is to guarantee that the buffer will be - * written to disk before this new transaction commits, then - * being sure that the *previous* transaction has this same - * property is sufficient for us! Just leave it on its old - * transaction. - * - * In case (2), the buffer must not already exist as metadata - * --- that would violate write ordering (a transaction is free - * to write its data at any point, even before the previous - * committing transaction has committed). The caller must - * never, ever allow this to happen: there's nothing we can do - * about it in this layer. - */ - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - - /* Now that we have bh_state locked, are we really still mapped? */ - if (!buffer_mapped(bh)) { - JBUFFER_TRACE(jh, "unmapped buffer, bailing out"); - goto no_journal; - } - - if (jh->b_transaction) { - JBUFFER_TRACE(jh, "has transaction"); - if (jh->b_transaction != handle->h_transaction) { - JBUFFER_TRACE(jh, "belongs to older transaction"); - J_ASSERT_JH(jh, jh->b_transaction == - journal->j_committing_transaction); - - /* @@@ IS THIS TRUE ? */ - /* - * Not any more. Scenario: someone does a write() - * in data=journal mode. The buffer's transaction has - * moved into commit. Then someone does another - * write() to the file. We do the frozen data copyout - * and set b_next_transaction to point to j_running_t. - * And while we're in that state, someone does a - * writepage() in an attempt to pageout the same area - * of the file via a shared mapping. At present that - * calls jbd2_journal_dirty_data(), and we get right here. - * It may be too late to journal the data. Simply - * falling through to the next test will suffice: the - * data will be dirty and wil be checkpointed. The - * ordering comments in the next comment block still - * apply. - */ - //J_ASSERT_JH(jh, jh->b_next_transaction == NULL); - - /* - * If we're journalling data, and this buffer was - * subject to a write(), it could be metadata, forget - * or shadow against the committing transaction. Now, - * someone has dirtied the same darn page via a mapping - * and it is being writepage()'d. - * We *could* just steal the page from commit, with some - * fancy locking there. Instead, we just skip it - - * don't tie the page's buffers to the new transaction - * at all. - * Implication: if we crash before the writepage() data - * is written into the filesystem, recovery will replay - * the write() data. - */ - if (jh->b_jlist != BJ_None && - jh->b_jlist != BJ_SyncData && - jh->b_jlist != BJ_Locked) { - JBUFFER_TRACE(jh, "Not stealing"); - goto no_journal; - } - - /* - * This buffer may be undergoing writeout in commit. We - * can't return from here and let the caller dirty it - * again because that can cause the write-out loop in - * commit to never terminate. - */ - if (buffer_dirty(bh)) { - get_bh(bh); - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - need_brelse = 1; - sync_dirty_buffer(bh); - jbd_lock_bh_state(bh); - spin_lock(&journal->j_list_lock); - /* Since we dropped the lock... */ - if (!buffer_mapped(bh)) { - JBUFFER_TRACE(jh, "buffer got unmapped"); - goto no_journal; - } - /* The buffer may become locked again at any - time if it is redirtied */ - } - - /* journal_clean_data_list() may have got there first */ - if (jh->b_transaction != NULL) { - JBUFFER_TRACE(jh, "unfile from commit"); - __jbd2_journal_temp_unlink_buffer(jh); - /* It still points to the committing - * transaction; move it to this one so - * that the refile assert checks are - * happy. */ - jh->b_transaction = handle->h_transaction; - } - /* The buffer will be refiled below */ - - } - /* - * Special case --- the buffer might actually have been - * allocated and then immediately deallocated in the previous, - * committing transaction, so might still be left on that - * transaction's metadata lists. - */ - if (jh->b_jlist != BJ_SyncData && jh->b_jlist != BJ_Locked) { - JBUFFER_TRACE(jh, "not on correct data list: unfile"); - J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow); - __jbd2_journal_temp_unlink_buffer(jh); - jh->b_transaction = handle->h_transaction; - JBUFFER_TRACE(jh, "file as data"); - __jbd2_journal_file_buffer(jh, handle->h_transaction, - BJ_SyncData); - } - } else { - JBUFFER_TRACE(jh, "not on a transaction"); - __jbd2_journal_file_buffer(jh, handle->h_transaction, BJ_SyncData); - } -no_journal: - spin_unlock(&journal->j_list_lock); - jbd_unlock_bh_state(bh); - if (need_brelse) { - BUFFER_TRACE(bh, "brelse"); - __brelse(bh); - } - JBUFFER_TRACE(jh, "exit"); - jbd2_journal_put_journal_head(jh); - return 0; -} - -/** * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata * @handle: transaction to add buffer to. * @bh: buffer to mark @@ -1541,10 +1364,10 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh) * Remove a buffer from the appropriate transaction list. * * Note that this function can *change* the value of - * bh->b_transaction->t_sync_datalist, t_buffers, t_forget, - * t_iobuf_list, t_shadow_list, t_log_list or t_reserved_list. If the caller - * is holding onto a copy of one of thee pointers, it could go bad. - * Generally the caller needs to re-read the pointer from the transaction_t. + * bh->b_transaction->t_buffers, t_forget, t_iobuf_list, t_shadow_list, + * t_log_list or t_reserved_list. If the caller is holding onto a copy of one + * of these pointers, it could go bad. Generally the caller needs to re-read + * the pointer from the transaction_t. * * Called under j_list_lock. The journal may not be locked. */ @@ -1566,9 +1389,6 @@ void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) switch (jh->b_jlist) { case BJ_None: return; - case BJ_SyncData: - list = &transaction->t_sync_datalist; - break; case BJ_Metadata: transaction->t_nr_buffers--; J_ASSERT_JH(jh, transaction->t_nr_buffers >= 0); @@ -1589,9 +1409,6 @@ void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh) case BJ_Reserved: list = &transaction->t_reserved_list; break; - case BJ_Locked: - list = &transaction->t_locked_list; - break; } __blist_del_buffer(list, jh); @@ -1634,15 +1451,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) goto out; spin_lock(&journal->j_list_lock); - if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) { - if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) { - /* A written-back ordered data buffer */ - JBUFFER_TRACE(jh, "release data"); - __jbd2_journal_unfile_buffer(jh); - jbd2_journal_remove_journal_head(bh); - __brelse(bh); - } - } else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { + if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { /* written-back checkpointed metadata buffer */ if (jh->b_jlist == BJ_None) { JBUFFER_TRACE(jh, "remove from checkpoint list"); @@ -1878,6 +1687,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) if (!buffer_jbd(bh)) goto zap_buffer_unlocked; + /* OK, we have data buffer in journaled mode */ spin_lock(&journal->j_state_lock); jbd_lock_bh_state(bh); spin_lock(&journal->j_list_lock); @@ -1941,15 +1751,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) } } else if (transaction == journal->j_committing_transaction) { JBUFFER_TRACE(jh, "on committing transaction"); - if (jh->b_jlist == BJ_Locked) { - /* - * The buffer is on the committing transaction's locked - * list. We have the buffer locked, so I/O has - * completed. So we can nail the buffer now. - */ - may_free = __dispose_buffer(jh, transaction); - goto zap_buffer; - } /* * If it is committing, we simply cannot touch it. We * can remove it's next_transaction pointer from the @@ -2082,9 +1883,6 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, J_ASSERT_JH(jh, !jh->b_committed_data); J_ASSERT_JH(jh, !jh->b_frozen_data); return; - case BJ_SyncData: - list = &transaction->t_sync_datalist; - break; case BJ_Metadata: transaction->t_nr_buffers++; list = &transaction->t_buffers; @@ -2104,9 +1902,6 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, case BJ_Reserved: list = &transaction->t_reserved_list; break; - case BJ_Locked: - list = &transaction->t_locked_list; - break; } __blist_add_buffer(list, jh); diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 622c3d8..3dd2090 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -543,24 +543,12 @@ struct transaction_s struct journal_head *t_reserved_list; /* - * Doubly-linked circular list of all buffers under writeout during - * commit [j_list_lock] - */ - struct journal_head *t_locked_list; - - /* * Doubly-linked circular list of all metadata buffers owned by this * transaction [j_list_lock] */ struct journal_head *t_buffers; /* - * Doubly-linked circular list of all data buffers still to be - * flushed before this transaction can be committed [j_list_lock] - */ - struct journal_head *t_sync_datalist; - - /* * Doubly-linked circular list of all forget buffers (superseded * buffers which we can un-checkpoint once this transaction commits) * [j_list_lock] @@ -1044,7 +1032,6 @@ extern int jbd2_journal_extend (handle_t *, int nblocks); extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *); extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *); extern int jbd2_journal_get_undo_access(handle_t *, struct buffer_head *); -extern int jbd2_journal_dirty_data (handle_t *, struct buffer_head *); extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *); extern void jbd2_journal_release_buffer (handle_t *, struct buffer_head *); extern int jbd2_journal_forget (handle_t *, struct buffer_head *); @@ -1223,15 +1210,13 @@ static inline int jbd_space_needed(journal_t *journal) /* journaling buffer types */ #define BJ_None 0 /* Not journaled */ -#define BJ_SyncData 1 /* Normal data: flush before commit */ -#define BJ_Metadata 2 /* Normal journaled metadata */ -#define BJ_Forget 3 /* Buffer superseded by this transaction */ -#define BJ_IO 4 /* Buffer is for temporary IO use */ -#define BJ_Shadow 5 /* Buffer contents being shadowed to the log */ -#define BJ_LogCtl 6 /* Buffer contains log descriptors */ -#define BJ_Reserved 7 /* Buffer is reserved for access by journal */ -#define BJ_Locked 8 /* Locked for I/O during commit */ -#define BJ_Types 9 +#define BJ_Metadata 1 /* Normal journaled metadata */ +#define BJ_Forget 2 /* Buffer superseded by this transaction */ +#define BJ_IO 3 /* Buffer is for temporary IO use */ +#define BJ_Shadow 4 /* Buffer contents being shadowed to the log */ +#define BJ_LogCtl 5 /* Buffer contains log descriptors */ +#define BJ_Reserved 6 /* Buffer is reserved for access by journal */ +#define BJ_Types 7 extern int jbd_blocks_per_page(struct inode *inode); -- cgit v0.10.2 From 29a814d2ee0e43c2980f33f91c1311ec06c0aa35 Mon Sep 17 00:00:00 2001 From: Alex Tomas Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: vfs: add hooks for ext4's delayed allocation support Export mpage_bio_submit() and __mpage_writepage() for the benefit of ext4's delayed allocation support. Also change __block_write_full_page so that if buffers that have the BH_Delay flag set it will call get_block() to get the physical block allocated, just as in the !BH_Mapped case. Signed-off-by: Alex Tomas Signed-off-by: "Theodore Ts'o" diff --git a/fs/buffer.c b/fs/buffer.c index f4b0332..5fa1512 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1691,11 +1691,13 @@ static int __block_write_full_page(struct inode *inode, struct page *page, */ clear_buffer_dirty(bh); set_buffer_uptodate(bh); - } else if (!buffer_mapped(bh) && buffer_dirty(bh)) { + } else if ((!buffer_mapped(bh) || buffer_delay(bh)) && + buffer_dirty(bh)) { WARN_ON(bh->b_size != blocksize); err = get_block(inode, block, bh, 1); if (err) goto recover; + clear_buffer_delay(bh); if (buffer_new(bh)) { /* blockdev mappings never come here */ clear_buffer_new(bh); @@ -1774,7 +1776,8 @@ recover: bh = head; /* Recovery: lock and submit the mapped buffers */ do { - if (buffer_mapped(bh) && buffer_dirty(bh)) { + if (buffer_mapped(bh) && buffer_dirty(bh) && + !buffer_delay(bh)) { lock_buffer(bh); mark_buffer_async_write(bh); } else { diff --git a/fs/mpage.c b/fs/mpage.c index 235e4d3..dbcc7af 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -82,7 +82,7 @@ static void mpage_end_io_write(struct bio *bio, int err) bio_put(bio); } -static struct bio *mpage_bio_submit(int rw, struct bio *bio) +struct bio *mpage_bio_submit(int rw, struct bio *bio) { bio->bi_end_io = mpage_end_io_read; if (rw == WRITE) @@ -90,6 +90,7 @@ static struct bio *mpage_bio_submit(int rw, struct bio *bio) submit_bio(rw, bio); return NULL; } +EXPORT_SYMBOL(mpage_bio_submit); static struct bio * mpage_alloc(struct block_device *bdev, @@ -435,15 +436,9 @@ EXPORT_SYMBOL(mpage_readpage); * written, so it can intelligently allocate a suitably-sized BIO. For now, * just allocate full-size (16-page) BIOs. */ -struct mpage_data { - struct bio *bio; - sector_t last_block_in_bio; - get_block_t *get_block; - unsigned use_writepage; -}; -static int __mpage_writepage(struct page *page, struct writeback_control *wbc, - void *data) +int __mpage_writepage(struct page *page, struct writeback_control *wbc, + void *data) { struct mpage_data *mpd = data; struct bio *bio = mpd->bio; @@ -651,6 +646,7 @@ out: mpd->bio = bio; return ret; } +EXPORT_SYMBOL(__mpage_writepage); /** * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them diff --git a/include/linux/mpage.h b/include/linux/mpage.h index 068a0c9..5c42821 100644 --- a/include/linux/mpage.h +++ b/include/linux/mpage.h @@ -11,11 +11,21 @@ */ #ifdef CONFIG_BLOCK +struct mpage_data { + struct bio *bio; + sector_t last_block_in_bio; + get_block_t *get_block; + unsigned use_writepage; +}; + struct writeback_control; +struct bio *mpage_bio_submit(int rw, struct bio *bio); int mpage_readpages(struct address_space *mapping, struct list_head *pages, unsigned nr_pages, get_block_t get_block); int mpage_readpage(struct page *page, get_block_t get_block); +int __mpage_writepage(struct page *page, struct writeback_control *wbc, + void *data); int mpage_writepages(struct address_space *mapping, struct writeback_control *wbc, get_block_t get_block); int mpage_writepage(struct page *page, get_block_t *get_block, -- cgit v0.10.2 From 64769240bd07f446f83660bb143bb609d8ab4910 Mon Sep 17 00:00:00 2001 From: Alex Tomas Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Add delayed allocation support in data=writeback mode Updated with fixes from Mingming Cao to unlock and release the page from page cache if the delalloc write_begin failed, and properly handle preallocated blocks. Also added a fix to clear buffer_delay in block_write_full_page() after allocating a delayed buffer. Updated with fixes from Aneesh Kumar K.V to update i_disksize properly and to add bmap support for delayed allocation. Updated with a fix from Valerie Clement to avoid filesystem corruption when the filesystem is mounted with the delalloc option and blocksize < pagesize. Signed-off-by: Alex Tomas Signed-off-by: Mingming Cao Signed-off-by: Dave Kleikamp Signed-off-by: "Theodore Ts'o" Signed-off-by: Aneesh Kumar K.V diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f65829b..ee9576d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -536,6 +536,7 @@ do { \ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ #define EXT4_MOUNT_MBALLOC 0x4000000 /* Buddy allocation support */ +#define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7b95691..2bef4f8 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,8 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode, new_size); } +static void ext4_invalidatepage(struct page *page, unsigned long offset); + /* * Test whether an inode is a fast symlink. */ @@ -1408,6 +1411,669 @@ static int ext4_journalled_write_end(struct file *file, } /* + * Delayed allocation stuff + */ + +struct mpage_da_data { + struct inode *inode; + struct buffer_head lbh; /* extent of blocks */ + unsigned long first_page, next_page; /* extent of pages */ + get_block_t *get_block; + struct writeback_control *wbc; +}; + +/* + * mpage_da_submit_io - walks through extent of pages and try to write + * them with __mpage_writepage() + * + * @mpd->inode: inode + * @mpd->first_page: first page of the extent + * @mpd->next_page: page after the last page of the extent + * @mpd->get_block: the filesystem's block mapper function + * + * By the time mpage_da_submit_io() is called we expect all blocks + * to be allocated. this may be wrong if allocation failed. + * + * As pages are already locked by write_cache_pages(), we can't use it + */ +static int mpage_da_submit_io(struct mpage_da_data *mpd) +{ + struct address_space *mapping = mpd->inode->i_mapping; + struct mpage_data mpd_pp = { + .bio = NULL, + .last_block_in_bio = 0, + .get_block = mpd->get_block, + .use_writepage = 1, + }; + int ret = 0, err, nr_pages, i; + unsigned long index, end; + struct pagevec pvec; + + BUG_ON(mpd->next_page <= mpd->first_page); + + pagevec_init(&pvec, 0); + index = mpd->first_page; + end = mpd->next_page - 1; + + while (index <= end) { + /* XXX: optimize tail */ + nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); + if (nr_pages == 0) + break; + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + index = page->index; + if (index > end) + break; + index++; + + err = __mpage_writepage(page, mpd->wbc, &mpd_pp); + + /* + * In error case, we have to continue because + * remaining pages are still locked + * XXX: unlock and re-dirty them? + */ + if (ret == 0) + ret = err; + } + pagevec_release(&pvec); + } + if (mpd_pp.bio) + mpage_bio_submit(WRITE, mpd_pp.bio); + + return ret; +} + +/* + * mpage_put_bnr_to_bhs - walk blocks and assign them actual numbers + * + * @mpd->inode - inode to walk through + * @exbh->b_blocknr - first block on a disk + * @exbh->b_size - amount of space in bytes + * @logical - first logical block to start assignment with + * + * the function goes through all passed space and put actual disk + * block numbers into buffer heads, dropping BH_Delay + */ +static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, + struct buffer_head *exbh) +{ + struct inode *inode = mpd->inode; + struct address_space *mapping = inode->i_mapping; + int blocks = exbh->b_size >> inode->i_blkbits; + sector_t pblock = exbh->b_blocknr, cur_logical; + struct buffer_head *head, *bh; + unsigned long index, end; + struct pagevec pvec; + int nr_pages, i; + + index = logical >> (PAGE_CACHE_SHIFT - inode->i_blkbits); + end = (logical + blocks - 1) >> (PAGE_CACHE_SHIFT - inode->i_blkbits); + cur_logical = index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + + pagevec_init(&pvec, 0); + + while (index <= end) { + /* XXX: optimize tail */ + nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); + if (nr_pages == 0) + break; + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + index = page->index; + if (index > end) + break; + index++; + + BUG_ON(!PageLocked(page)); + BUG_ON(PageWriteback(page)); + BUG_ON(!page_has_buffers(page)); + + bh = page_buffers(page); + head = bh; + + /* skip blocks out of the range */ + do { + if (cur_logical >= logical) + break; + cur_logical++; + } while ((bh = bh->b_this_page) != head); + + do { + if (cur_logical >= logical + blocks) + break; + + if (buffer_delay(bh)) { + bh->b_blocknr = pblock; + clear_buffer_delay(bh); + } else if (buffer_mapped(bh)) { + BUG_ON(bh->b_blocknr != pblock); + } + + cur_logical++; + pblock++; + } while ((bh = bh->b_this_page) != head); + } + pagevec_release(&pvec); + } +} + + +/* + * __unmap_underlying_blocks - just a helper function to unmap + * set of blocks described by @bh + */ +static inline void __unmap_underlying_blocks(struct inode *inode, + struct buffer_head *bh) +{ + struct block_device *bdev = inode->i_sb->s_bdev; + int blocks, i; + + blocks = bh->b_size >> inode->i_blkbits; + for (i = 0; i < blocks; i++) + unmap_underlying_metadata(bdev, bh->b_blocknr + i); +} + +/* + * mpage_da_map_blocks - go through given space + * + * @mpd->lbh - bh describing space + * @mpd->get_block - the filesystem's block mapper function + * + * The function skips space we know is already mapped to disk blocks. + * + * The function ignores errors ->get_block() returns, thus real + * error handling is postponed to __mpage_writepage() + */ +static void mpage_da_map_blocks(struct mpage_da_data *mpd) +{ + struct buffer_head *lbh = &mpd->lbh; + int err = 0, remain = lbh->b_size; + sector_t next = lbh->b_blocknr; + struct buffer_head new; + + /* + * We consider only non-mapped and non-allocated blocks + */ + if (buffer_mapped(lbh) && !buffer_delay(lbh)) + return; + + while (remain) { + new.b_state = lbh->b_state; + new.b_blocknr = 0; + new.b_size = remain; + err = mpd->get_block(mpd->inode, next, &new, 1); + if (err) { + /* + * Rather than implement own error handling + * here, we just leave remaining blocks + * unallocated and try again with ->writepage() + */ + break; + } + BUG_ON(new.b_size == 0); + + if (buffer_new(&new)) + __unmap_underlying_blocks(mpd->inode, &new); + + /* + * If blocks are delayed marked, we need to + * put actual blocknr and drop delayed bit + */ + if (buffer_delay(lbh)) + mpage_put_bnr_to_bhs(mpd, next, &new); + + /* go for the remaining blocks */ + next += new.b_size >> mpd->inode->i_blkbits; + remain -= new.b_size; + } +} + +#define BH_FLAGS ((1 << BH_Uptodate) | (1 << BH_Mapped) | (1 << BH_Delay)) + +/* + * mpage_add_bh_to_extent - try to add one more block to extent of blocks + * + * @mpd->lbh - extent of blocks + * @logical - logical number of the block in the file + * @bh - bh of the block (used to access block's state) + * + * the function is used to collect contig. blocks in same state + */ +static void mpage_add_bh_to_extent(struct mpage_da_data *mpd, + sector_t logical, struct buffer_head *bh) +{ + struct buffer_head *lbh = &mpd->lbh; + sector_t next; + + next = lbh->b_blocknr + (lbh->b_size >> mpd->inode->i_blkbits); + + /* + * First block in the extent + */ + if (lbh->b_size == 0) { + lbh->b_blocknr = logical; + lbh->b_size = bh->b_size; + lbh->b_state = bh->b_state & BH_FLAGS; + return; + } + + /* + * Can we merge the block to our big extent? + */ + if (logical == next && (bh->b_state & BH_FLAGS) == lbh->b_state) { + lbh->b_size += bh->b_size; + return; + } + + /* + * We couldn't merge the block to our extent, so we + * need to flush current extent and start new one + */ + mpage_da_map_blocks(mpd); + + /* + * Now start a new extent + */ + lbh->b_size = bh->b_size; + lbh->b_state = bh->b_state & BH_FLAGS; + lbh->b_blocknr = logical; +} + +/* + * __mpage_da_writepage - finds extent of pages and blocks + * + * @page: page to consider + * @wbc: not used, we just follow rules + * @data: context + * + * The function finds extents of pages and scan them for all blocks. + */ +static int __mpage_da_writepage(struct page *page, + struct writeback_control *wbc, void *data) +{ + struct mpage_da_data *mpd = data; + struct inode *inode = mpd->inode; + struct buffer_head *bh, *head, fake; + sector_t logical; + + /* + * Can we merge this page to current extent? + */ + if (mpd->next_page != page->index) { + /* + * Nope, we can't. So, we map non-allocated blocks + * and start IO on them using __mpage_writepage() + */ + if (mpd->next_page != mpd->first_page) { + mpage_da_map_blocks(mpd); + mpage_da_submit_io(mpd); + } + + /* + * Start next extent of pages ... + */ + mpd->first_page = page->index; + + /* + * ... and blocks + */ + mpd->lbh.b_size = 0; + mpd->lbh.b_state = 0; + mpd->lbh.b_blocknr = 0; + } + + mpd->next_page = page->index + 1; + logical = (sector_t) page->index << + (PAGE_CACHE_SHIFT - inode->i_blkbits); + + if (!page_has_buffers(page)) { + /* + * There is no attached buffer heads yet (mmap?) + * we treat the page asfull of dirty blocks + */ + bh = &fake; + bh->b_size = PAGE_CACHE_SIZE; + bh->b_state = 0; + set_buffer_dirty(bh); + set_buffer_uptodate(bh); + mpage_add_bh_to_extent(mpd, logical, bh); + } else { + /* + * Page with regular buffer heads, just add all dirty ones + */ + head = page_buffers(page); + bh = head; + do { + BUG_ON(buffer_locked(bh)); + if (buffer_dirty(bh)) + mpage_add_bh_to_extent(mpd, logical, bh); + logical++; + } while ((bh = bh->b_this_page) != head); + } + + return 0; +} + +/* + * mpage_da_writepages - walk the list of dirty pages of the given + * address space, allocates non-allocated blocks, maps newly-allocated + * blocks to existing bhs and issue IO them + * + * @mapping: address space structure to write + * @wbc: subtract the number of written pages from *@wbc->nr_to_write + * @get_block: the filesystem's block mapper function. + * + * This is a library function, which implements the writepages() + * address_space_operation. + * + * In order to avoid duplication of logic that deals with partial pages, + * multiple bio per page, etc, we find non-allocated blocks, allocate + * them with minimal calls to ->get_block() and re-use __mpage_writepage() + * + * It's important that we call __mpage_writepage() only once for each + * involved page, otherwise we'd have to implement more complicated logic + * to deal with pages w/o PG_lock or w/ PG_writeback and so on. + * + * See comments to mpage_writepages() + */ +static int mpage_da_writepages(struct address_space *mapping, + struct writeback_control *wbc, + get_block_t get_block) +{ + struct mpage_da_data mpd; + int ret; + + if (!get_block) + return generic_writepages(mapping, wbc); + + mpd.wbc = wbc; + mpd.inode = mapping->host; + mpd.lbh.b_size = 0; + mpd.lbh.b_state = 0; + mpd.lbh.b_blocknr = 0; + mpd.first_page = 0; + mpd.next_page = 0; + mpd.get_block = get_block; + + ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, &mpd); + + /* + * Handle last extent of pages + */ + if (mpd.next_page != mpd.first_page) { + mpage_da_map_blocks(&mpd); + mpage_da_submit_io(&mpd); + } + + return ret; +} + +/* + * this is a special callback for ->write_begin() only + * it's intention is to return mapped block or reserve space + */ +static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + int ret = 0; + + BUG_ON(create == 0); + BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize); + + /* + * first, we need to know whether the block is allocated already + * preallocated blocks are unmapped but should treated + * the same as allocated blocks. + */ + ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0, 0); + if (ret == 0) { + /* the block isn't allocated yet, let's reserve space */ + /* XXX: call reservation here */ + /* + * XXX: __block_prepare_write() unmaps passed block, + * is it OK? + */ + map_bh(bh_result, inode->i_sb, 0); + set_buffer_new(bh_result); + set_buffer_delay(bh_result); + } else if (ret > 0) { + bh_result->b_size = (ret << inode->i_blkbits); + ret = 0; + } + + return ret; +} + +static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + int ret, needed_blocks = ext4_writepage_trans_blocks(inode); + unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; + loff_t disksize = EXT4_I(inode)->i_disksize; + handle_t *handle = NULL; + + if (create) { + handle = ext4_journal_start(inode, needed_blocks); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out; + } + } + + ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, + bh_result, create, 0); + if (ret > 0) { + bh_result->b_size = (ret << inode->i_blkbits); + + /* + * Update on-disk size along with block allocation + * we don't use 'extend_disksize' as size may change + * within already allocated block -bzzz + */ + disksize = ((loff_t) iblock + ret) << inode->i_blkbits; + if (disksize > i_size_read(inode)) + disksize = i_size_read(inode); + if (disksize > EXT4_I(inode)->i_disksize) { + /* + * XXX: replace with spinlock if seen contended -bzzz + */ + down_write(&EXT4_I(inode)->i_data_sem); + if (disksize > EXT4_I(inode)->i_disksize) + EXT4_I(inode)->i_disksize = disksize; + up_write(&EXT4_I(inode)->i_data_sem); + + if (EXT4_I(inode)->i_disksize == disksize) { + if (handle == NULL) + handle = ext4_journal_start(inode, 1); + if (!IS_ERR(handle)) + ext4_mark_inode_dirty(handle, inode); + } + } + + ret = 0; + } + +out: + if (handle && !IS_ERR(handle)) + ext4_journal_stop(handle); + + return ret; +} +/* FIXME!! only support data=writeback mode */ +static int ext4_da_writepage(struct page *page, + struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + handle_t *handle = NULL; + int ret = 0; + int err; + + if (ext4_journal_current_handle()) + goto out_fail; + + handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out_fail; + } + + if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) + ret = nobh_writepage(page, ext4_get_block, wbc); + else + ret = block_write_full_page(page, ext4_get_block, wbc); + + if (!ret && inode->i_size > EXT4_I(inode)->i_disksize) { + EXT4_I(inode)->i_disksize = inode->i_size; + ext4_mark_inode_dirty(handle, inode); + } + + err = ext4_journal_stop(handle); + if (!ret) + ret = err; + return ret; + +out_fail: + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return ret; +} + +static int ext4_da_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + return mpage_da_writepages(mapping, wbc, ext4_da_get_block_write); +} + +static int ext4_da_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + int ret; + struct page *page; + pgoff_t index; + unsigned from, to; + struct inode *inode = mapping->host; + handle_t *handle; + + index = pos >> PAGE_CACHE_SHIFT; + from = pos & (PAGE_CACHE_SIZE - 1); + to = from + len; + + /* + * With delayed allocation, we don't log the i_disksize update + * if there is delayed block allocation. But we still need + * to journalling the i_disksize update if writes to the end + * of file which has an already mapped buffer. + */ + handle = ext4_journal_start(inode, 1); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out; + } + + page = __grab_cache_page(mapping, index); + if (!page) + return -ENOMEM; + *pagep = page; + + ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + ext4_da_get_block_prep); + if (ret < 0) { + unlock_page(page); + ext4_journal_stop(handle); + page_cache_release(page); + } + +out: + return ret; +} + +static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) +{ + return !buffer_mapped(bh) || buffer_delay(bh); +} + +static int ext4_da_write_end(struct file *file, + struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ + struct inode *inode = mapping->host; + int ret = 0, ret2; + handle_t *handle = ext4_journal_current_handle(); + loff_t new_i_size; + + /* + * generic_write_end() will run mark_inode_dirty() if i_size + * changes. So let's piggyback the i_disksize mark_inode_dirty + * into that. + */ + + new_i_size = pos + copied; + if (new_i_size > EXT4_I(inode)->i_disksize) + if (!walk_page_buffers(NULL, page_buffers(page), + 0, len, NULL, ext4_bh_unmapped_or_delay)){ + /* + * Updating i_disksize when extending file without + * needing block allocation + */ + if (ext4_should_order_data(inode)) + ret = ext4_jbd2_file_inode(handle, inode); + + EXT4_I(inode)->i_disksize = new_i_size; + } + ret2 = generic_write_end(file, mapping, pos, len, copied, + page, fsdata); + copied = ret2; + if (ret2 < 0) + ret = ret2; + ret2 = ext4_journal_stop(handle); + if (!ret) + ret = ret2; + + return ret ? ret : copied; +} + +static void ext4_da_invalidatepage(struct page *page, unsigned long offset) +{ + struct buffer_head *head, *bh; + unsigned int curr_off = 0; + + /* + * Drop reserved blocks + */ + BUG_ON(!PageLocked(page)); + if (!page_has_buffers(page)) + goto out; + + head = page_buffers(page); + bh = head; + do { + unsigned int next_off = curr_off + bh->b_size; + + /* + * is this block fully invalidated? + */ + if (offset <= curr_off && buffer_delay(bh)) { + clear_buffer_delay(bh); + /* XXX: add real stuff here */ + } + curr_off = next_off; + bh = bh->b_this_page; + } while (bh != head); + +out: + ext4_invalidatepage(page, offset); + + return; +} + + +/* * bmap() is special. It gets used by applications such as lilo and by * the swapper to find the on-disk block of a specific piece of data. * @@ -1427,6 +2093,16 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) journal_t *journal; int err; + if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) && + test_opt(inode->i_sb, DELALLOC)) { + /* + * With delalloc we want to sync the file + * so that we can make sure we allocate + * blocks for file + */ + filemap_write_and_wait(mapping); + } + if (EXT4_I(inode)->i_state & EXT4_STATE_JDATA) { /* * This is a REALLY heavyweight approach, but the use of @@ -1471,11 +2147,6 @@ static int bput_one(handle_t *handle, struct buffer_head *bh) return 0; } -static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) -{ - return !buffer_mapped(bh) || buffer_delay(bh); -} - /* * Note that we don't need to start a transaction unless we're journaling data * because we should have holes filled from ext4_page_mkwrite(). We even don't @@ -1832,10 +2503,28 @@ static const struct address_space_operations ext4_journalled_aops = { .releasepage = ext4_releasepage, }; +static const struct address_space_operations ext4_da_aops = { + .readpage = ext4_readpage, + .readpages = ext4_readpages, + .writepage = ext4_da_writepage, + .writepages = ext4_da_writepages, + .sync_page = block_sync_page, + .write_begin = ext4_da_write_begin, + .write_end = ext4_da_write_end, + .bmap = ext4_bmap, + .invalidatepage = ext4_da_invalidatepage, + .releasepage = ext4_releasepage, + .direct_IO = ext4_direct_IO, + .migratepage = buffer_migrate_page, +}; + void ext4_set_aops(struct inode *inode) { if (ext4_should_order_data(inode)) inode->i_mapping->a_ops = &ext4_ordered_aops; + else if (ext4_should_writeback_data(inode) && + test_opt(inode->i_sb, DELALLOC)) + inode->i_mapping->a_ops = &ext4_da_aops; else if (ext4_should_writeback_data(inode)) inode->i_mapping->a_ops = &ext4_writeback_aops; else diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 629d0fa2..de9d3d0 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -898,7 +898,7 @@ enum { Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, - Opt_mballoc, Opt_nomballoc, Opt_stripe, + Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, }; static match_table_t tokens = { @@ -957,6 +957,7 @@ static match_table_t tokens = { {Opt_nomballoc, "nomballoc"}, {Opt_stripe, "stripe=%u"}, {Opt_resize, "resize"}, + {Opt_delalloc, "delalloc"}, {Opt_err, NULL}, }; @@ -1335,6 +1336,9 @@ set_qf_format: return 0; sbi->s_stripe = option; break; + case Opt_delalloc: + set_opt(sbi->s_mount_opt, DELALLOC); + break; default: printk (KERN_ERR "EXT4-fs: Unrecognized mount option \"%s\" " -- cgit v0.10.2 From e8ced39d5e8911c662d4d69a342b9d053eaaac4e Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: percpu_counter: new function percpu_counter_sum_and_set Delayed allocation need to check free blocks at every write time. percpu_counter_read_positive() is not quit accurate. delayed allocation need a more accurate accounting, but using percpu_counter_sum_positive() is frequently is quite expensive. This patch added a new function to update center counter when sum per-cpu counter, to increase the accurate rate for next percpu_counter_read() and require less calling expensive percpu_counter_sum(). Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 25f63d8..6369bac 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -1621,7 +1621,7 @@ ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, #ifdef CONFIG_SMP if (free_blocks - root_blocks < FBC_BATCH) free_blocks = - percpu_counter_sum_positive(&sbi->s_freeblocks_counter); + percpu_counter_sum_and_set(&sbi->s_freeblocks_counter); #endif if (free_blocks - root_blocks < nblocks) return free_blocks - root_blocks; diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 9007ccd..2083888 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -35,7 +35,7 @@ int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount); void percpu_counter_destroy(struct percpu_counter *fbc); void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); -s64 __percpu_counter_sum(struct percpu_counter *fbc); +s64 __percpu_counter_sum(struct percpu_counter *fbc, int set); static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { @@ -44,13 +44,19 @@ static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc) { - s64 ret = __percpu_counter_sum(fbc); + s64 ret = __percpu_counter_sum(fbc, 0); return ret < 0 ? 0 : ret; } +static inline s64 percpu_counter_sum_and_set(struct percpu_counter *fbc) +{ + return __percpu_counter_sum(fbc, 1); +} + + static inline s64 percpu_counter_sum(struct percpu_counter *fbc) { - return __percpu_counter_sum(fbc); + return __percpu_counter_sum(fbc, 0); } static inline s64 percpu_counter_read(struct percpu_counter *fbc) diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 1191744..4a8ba4b 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -52,7 +52,7 @@ EXPORT_SYMBOL(__percpu_counter_add); * Add up all the per-cpu counts, return the result. This is a more accurate * but much slower version of percpu_counter_read_positive() */ -s64 __percpu_counter_sum(struct percpu_counter *fbc) +s64 __percpu_counter_sum(struct percpu_counter *fbc, int set) { s64 ret; int cpu; @@ -62,7 +62,12 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc) for_each_online_cpu(cpu) { s32 *pcount = per_cpu_ptr(fbc->counters, cpu); ret += *pcount; + if (set) + *pcount = 0; } + if (set) + fbc->count = ret; + spin_unlock(&fbc->lock); return ret; } -- cgit v0.10.2 From d2a1763791a634e315ec926b62829c1e88842c86 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Mon, 14 Jul 2008 17:52:37 -0400 Subject: ext4: delayed allocation ENOSPC handling This patch does block reservation for delayed allocation, to avoid ENOSPC later at page flush time. Blocks(data and metadata) are reserved at da_write_begin() time, the freeblocks counter is updated by then, and the number of reserved blocks is store in per inode counter. At the writepage time, the unused reserved meta blocks are returned back. At unlink/truncate time, reserved blocks are properly released. Updated fix from Aneesh Kumar K.V to fix the oldallocator block reservation accounting with delalloc, added lock to guard the counters and also fix the reservation for meta blocks. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: Theodore Ts'o diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 6369bac..495ab21 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -1701,7 +1701,12 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, } sbi = EXT4_SB(sb); - *count = ext4_has_free_blocks(sbi, *count); + if (!EXT4_I(inode)->i_delalloc_reserved_flag) { + /* + * With delalloc we already reserved the blocks + */ + *count = ext4_has_free_blocks(sbi, *count); + } if (*count == 0) { *errp = -ENOSPC; return 0; /*return with ENOSPC error */ @@ -1902,7 +1907,8 @@ allocated: le16_add_cpu(&gdp->bg_free_blocks_count, -num); gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp); spin_unlock(sb_bgl_lock(sbi, group_no)); - percpu_counter_sub(&sbi->s_freeblocks_counter, num); + if (!EXT4_I(inode)->i_delalloc_reserved_flag) + percpu_counter_sub(&sbi->s_freeblocks_counter, num); if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, group_no); @@ -1976,40 +1982,49 @@ static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode, } /* - * ext4_new_meta_block() -- allocate block for meta data (indexing) blocks + * ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks * * @handle: handle to this transaction * @inode: file inode * @goal: given target block(filesystem wide) + * @count: total number of blocks need * @errp: error code * - * Return allocated block number on success + * Return 1st allocated block numberon success, *count stores total account + * error stores in errp pointer */ -ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int *errp) +ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, + ext4_fsblk_t goal, unsigned long *count, int *errp) { - unsigned long count = 1; - return do_blk_alloc(handle, inode, 0, goal, - &count, errp, EXT4_META_BLOCK); + ext4_fsblk_t ret; + ret = do_blk_alloc(handle, inode, 0, goal, + count, errp, EXT4_META_BLOCK); + /* + * Account for the allocated meta blocks + */ + if (!(*errp)) { + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); + EXT4_I(inode)->i_allocated_meta_blocks += *count; + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + } + return ret; } /* - * ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks + * ext4_new_meta_block() -- allocate block for meta data (indexing) blocks * * @handle: handle to this transaction * @inode: file inode * @goal: given target block(filesystem wide) - * @count: total number of blocks need * @errp: error code * - * Return 1st allocated block numberon success, *count stores total account - * error stores in errp pointer + * Return allocated block number on success */ -ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp) +ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, + ext4_fsblk_t goal, int *errp) { - return do_blk_alloc(handle, inode, 0, goal, - count, errp, EXT4_META_BLOCK); + unsigned long count = 1; + return ext4_new_meta_blocks(handle, inode, goal, &count, errp); } /* diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 5ed5108..d3d23d7 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -129,7 +129,8 @@ static int ext4_readdir(struct file * filp, struct buffer_head *bh = NULL; map_bh.b_state = 0; - err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, 0, 0); + err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, + 0, 0, 0); if (err > 0) { pgoff_t index = map_bh.b_blocknr >> (PAGE_CACHE_SHIFT - inode->i_blkbits); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ee9576d..0962f4e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -74,6 +74,9 @@ #define EXT4_MB_HINT_GOAL_ONLY 256 /* goal is meaningful */ #define EXT4_MB_HINT_TRY_GOAL 512 +/* blocks already pre-reserved by delayed allocation */ +#define EXT4_MB_DELALLOC_RESERVED 1024 + struct ext4_allocation_request { /* target inode for block we're allocating */ @@ -1041,6 +1044,7 @@ extern void ext4_mb_update_group_info(struct ext4_group_info *grp, /* inode.c */ +void ext4_da_release_space(struct inode *inode, int used, int to_free); int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, struct buffer_head *bh, ext4_fsblk_t blocknr); struct buffer_head *ext4_getblk(handle_t *, struct inode *, @@ -1234,7 +1238,7 @@ extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, unsigned long max_blocks, struct buffer_head *bh, int create, - int extend_disksize); + int extend_disksize, int flag); #endif /* __KERNEL__ */ #endif /* _EXT4_H */ diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h index 75333b5..6c166c0 100644 --- a/fs/ext4/ext4_extents.h +++ b/fs/ext4/ext4_extents.h @@ -212,6 +212,7 @@ static inline int ext4_ext_get_actual_len(struct ext4_extent *ext) (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN)); } +extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks); extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t); extern int ext4_extent_tree_init(handle_t *, struct inode *); diff --git a/fs/ext4/ext4_i.h b/fs/ext4/ext4_i.h index c2903ef..ef7409f 100644 --- a/fs/ext4/ext4_i.h +++ b/fs/ext4/ext4_i.h @@ -163,6 +163,13 @@ struct ext4_inode_info { /* mballoc */ struct list_head i_prealloc_list; spinlock_t i_prealloc_lock; + + /* allocation reservation info for delalloc */ + unsigned long i_reserved_data_blocks; + unsigned long i_reserved_meta_blocks; + unsigned long i_allocated_meta_blocks; + unsigned short i_delalloc_reserved_flag; + spinlock_t i_block_reservation_lock; }; #endif /* _EXT4_I */ diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7844bbb..dabc3b6 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -248,6 +248,36 @@ static int ext4_ext_space_root_idx(struct inode *inode) return size; } +/* + * Calculate the number of metadata blocks needed + * to allocate @blocks + * Worse case is one block per extent + */ +int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks) +{ + int lcap, icap, rcap, leafs, idxs, num; + int newextents = blocks; + + rcap = ext4_ext_space_root_idx(inode); + lcap = ext4_ext_space_block(inode); + icap = ext4_ext_space_block_idx(inode); + + /* number of new leaf blocks needed */ + num = leafs = (newextents + lcap - 1) / lcap; + + /* + * Worse case, we need separate index block(s) + * to link all new leaf blocks + */ + idxs = (leafs + icap - 1) / icap; + do { + num += idxs; + idxs = (idxs + icap - 1) / icap; + } while (idxs > rcap); + + return num; +} + static int ext4_ext_max_entries(struct inode *inode, int depth) { @@ -2910,7 +2940,7 @@ retry: } ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, - EXT4_CREATE_UNINITIALIZED_EXT, 0); + EXT4_CREATE_UNINITIALIZED_EXT, 0, 0); if (ret <= 0) { #ifdef EXT4FS_DEBUG WARN_ON(ret <= 0); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2bef4f8..a6b800c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -39,6 +39,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "ext4_extents.h" static inline int ext4_begin_ordered_truncate(struct inode *inode, loff_t new_size) @@ -982,7 +983,7 @@ out: */ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, unsigned long max_blocks, struct buffer_head *bh, - int create, int extend_disksize) + int create, int extend_disksize, int flag) { int retval; @@ -1023,6 +1024,15 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, * with create == 1 flag. */ down_write((&EXT4_I(inode)->i_data_sem)); + + /* + * if the caller is from delayed allocation writeout path + * we have already reserved fs blocks for allocation + * let the underlying get_block() function know to + * avoid double accounting + */ + if (flag) + EXT4_I(inode)->i_delalloc_reserved_flag = 1; /* * We need to check for EXT4 here because migrate * could have changed the inode type in between @@ -1044,6 +1054,18 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, ~EXT4_EXT_MIGRATE; } } + + if (flag) { + EXT4_I(inode)->i_delalloc_reserved_flag = 0; + /* + * Update reserved blocks/metadata blocks + * after successful block allocation + * which were deferred till now + */ + if ((retval > 0) && buffer_delay(bh)) + ext4_da_release_space(inode, retval, 0); + } + up_write((&EXT4_I(inode)->i_data_sem)); return retval; } @@ -1069,7 +1091,7 @@ static int ext4_get_block(struct inode *inode, sector_t iblock, } ret = ext4_get_blocks_wrap(handle, inode, iblock, - max_blocks, bh_result, create, 0); + max_blocks, bh_result, create, 0, 0); if (ret > 0) { bh_result->b_size = (ret << inode->i_blkbits); ret = 0; @@ -1095,7 +1117,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, dummy.b_blocknr = -1000; buffer_trace_init(&dummy.b_history); err = ext4_get_blocks_wrap(handle, inode, block, 1, - &dummy, create, 1); + &dummy, create, 1, 0); /* * ext4_get_blocks_handle() returns number of blocks * mapped. 0 in case of a HOLE. @@ -1409,6 +1431,122 @@ static int ext4_journalled_write_end(struct file *file, return ret ? ret : copied; } +/* + * Calculate the number of metadata blocks need to reserve + * to allocate @blocks for non extent file based file + */ +static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks) +{ + int icap = EXT4_ADDR_PER_BLOCK(inode->i_sb); + int ind_blks, dind_blks, tind_blks; + + /* number of new indirect blocks needed */ + ind_blks = (blocks + icap - 1) / icap; + + dind_blks = (ind_blks + icap - 1) / icap; + + tind_blks = 1; + + return ind_blks + dind_blks + tind_blks; +} + +/* + * Calculate the number of metadata blocks need to reserve + * to allocate given number of blocks + */ +static int ext4_calc_metadata_amount(struct inode *inode, int blocks) +{ + if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) + return ext4_ext_calc_metadata_amount(inode, blocks); + + return ext4_indirect_calc_metadata_amount(inode, blocks); +} + +static int ext4_da_reserve_space(struct inode *inode, int nrblocks) +{ + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + unsigned long md_needed, mdblocks, total = 0; + + /* + * recalculate the amount of metadata blocks to reserve + * in order to allocate nrblocks + * worse case is one extent per block + */ + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); + total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; + mdblocks = ext4_calc_metadata_amount(inode, total); + BUG_ON(mdblocks < EXT4_I(inode)->i_reserved_meta_blocks); + + md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; + total = md_needed + nrblocks; + + if (ext4_has_free_blocks(sbi, total) < total) { + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + return -ENOSPC; + } + + /* reduce fs free blocks counter */ + percpu_counter_sub(&sbi->s_freeblocks_counter, total); + + EXT4_I(inode)->i_reserved_data_blocks += nrblocks; + EXT4_I(inode)->i_reserved_meta_blocks = mdblocks; + + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + return 0; /* success */ +} + +void ext4_da_release_space(struct inode *inode, int used, int to_free) +{ + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + int total, mdb, mdb_free, release; + + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); + /* recalculate the number of metablocks still need to be reserved */ + total = EXT4_I(inode)->i_reserved_data_blocks - used - to_free; + mdb = ext4_calc_metadata_amount(inode, total); + + /* figure out how many metablocks to release */ + BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); + mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; + + /* Account for allocated meta_blocks */ + mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; + + release = to_free + mdb_free; + + /* update fs free blocks counter for truncate case */ + percpu_counter_add(&sbi->s_freeblocks_counter, release); + + /* update per-inode reservations */ + BUG_ON(used + to_free > EXT4_I(inode)->i_reserved_data_blocks); + EXT4_I(inode)->i_reserved_data_blocks -= (used + to_free); + + BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); + EXT4_I(inode)->i_reserved_meta_blocks = mdb; + EXT4_I(inode)->i_allocated_meta_blocks = 0; + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); +} + +static void ext4_da_page_release_reservation(struct page *page, + unsigned long offset) +{ + int to_release = 0; + struct buffer_head *head, *bh; + unsigned int curr_off = 0; + + head = page_buffers(page); + bh = head; + do { + unsigned int next_off = curr_off + bh->b_size; + + if ((offset <= curr_off) && (buffer_delay(bh))) { + to_release++; + clear_buffer_delay(bh); + } + curr_off = next_off; + } while ((bh = bh->b_this_page) != head); + ext4_da_release_space(page->mapping->host, 0, to_release); +} /* * Delayed allocation stuff @@ -1829,14 +1967,18 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, * preallocated blocks are unmapped but should treated * the same as allocated blocks. */ - ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0, 0); - if (ret == 0) { - /* the block isn't allocated yet, let's reserve space */ - /* XXX: call reservation here */ + ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0, 0, 0); + if ((ret == 0) && !buffer_delay(bh_result)) { + /* the block isn't (pre)allocated yet, let's reserve space */ /* * XXX: __block_prepare_write() unmaps passed block, * is it OK? */ + ret = ext4_da_reserve_space(inode, 1); + if (ret) + /* not enough space to reserve */ + return ret; + map_bh(bh_result, inode->i_sb, 0); set_buffer_new(bh_result); set_buffer_delay(bh_result); @@ -1847,7 +1989,7 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, return ret; } - +#define EXT4_DELALLOC_RSVED 1 static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { @@ -1865,7 +2007,7 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, } ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, - bh_result, create, 0); + bh_result, create, 0, EXT4_DELALLOC_RSVED); if (ret > 0) { bh_result->b_size = (ret << inode->i_blkbits); @@ -1952,7 +2094,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { - int ret; + int ret, retries = 0; struct page *page; pgoff_t index; unsigned from, to; @@ -1963,6 +2105,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, from = pos & (PAGE_CACHE_SIZE - 1); to = from + len; +retry: /* * With delayed allocation, we don't log the i_disksize update * if there is delayed block allocation. But we still need @@ -1988,6 +2131,8 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, page_cache_release(page); } + if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; out: return ret; } @@ -2040,9 +2185,6 @@ static int ext4_da_write_end(struct file *file, static void ext4_da_invalidatepage(struct page *page, unsigned long offset) { - struct buffer_head *head, *bh; - unsigned int curr_off = 0; - /* * Drop reserved blocks */ @@ -2050,21 +2192,7 @@ static void ext4_da_invalidatepage(struct page *page, unsigned long offset) if (!page_has_buffers(page)) goto out; - head = page_buffers(page); - bh = head; - do { - unsigned int next_off = curr_off + bh->b_size; - - /* - * is this block fully invalidated? - */ - if (offset <= curr_off && buffer_delay(bh)) { - clear_buffer_delay(bh); - /* XXX: add real stuff here */ - } - curr_off = next_off; - bh = bh->b_this_page; - } while (bh != head); + ext4_da_page_release_reservation(page, offset); out: ext4_invalidatepage(page, offset); diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 8d254ca..8d141a2 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2964,7 +2964,15 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len); gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); - percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); + + /* + * free blocks account has already be reduced/reserved + * at write_begin() time for delayed allocation + * do not double accounting + */ + if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) + percpu_counter_sub(&sbi->s_freeblocks_counter, + ac->ac_b_ex.fe_len); if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi, @@ -4169,7 +4177,12 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, &(ar->len), errp); return block; } - ar->len = ext4_has_free_blocks(sbi, ar->len); + if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) { + /* + * With delalloc we already reserved the blocks + */ + ar->len = ext4_has_free_blocks(sbi, ar->len); + } if (ar->len == 0) { *errp = -ENOSPC; @@ -4186,6 +4199,9 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, } inquota = ar->len; + if (EXT4_I(ar->inode)->i_delalloc_reserved_flag) + ar->flags |= EXT4_MB_DELALLOC_RESERVED; + ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); if (!ac) { ar->len = 0; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index de9d3d0..25e2f24 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -574,6 +574,11 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) INIT_LIST_HEAD(&ei->i_prealloc_list); spin_lock_init(&ei->i_prealloc_lock); jbd2_journal_init_jbd_inode(&ei->jinode, &ei->vfs_inode); + ei->i_reserved_data_blocks = 0; + ei->i_reserved_meta_blocks = 0; + ei->i_allocated_meta_blocks = 0; + ei->i_delalloc_reserved_flag = 0; + spin_lock_init(&(ei->i_block_reservation_lock)); return &ei->vfs_inode; } -- cgit v0.10.2 From 06d6cf6959d22037fcec598f4f954db5db3d7356 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: mm: Add range_cont mode for writeback Filesystems like ext4 needs to start a new transaction in the writepages for block allocation. This happens with delayed allocation and there is limit to how many credits we can request from the journal layer. So we call write_cache_pages multiple times with wbc->nr_to_write set to the maximum possible value limitted by the max journal credits available. Add a new mode to writeback that enables us to handle this behaviour. In the new mode we update the wbc->range_start to point to the new offset to be written. Next call to call to write_cache_pages will start writeout from specified range_start offset. In the new mode we also limit writing to the specified wbc->range_end. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Acked-by: Jan Kara Signed-off-by: "Theodore Ts'o" diff --git a/include/linux/writeback.h b/include/linux/writeback.h index f462439..0d8573e 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -63,6 +63,7 @@ struct writeback_control { unsigned for_writepages:1; /* This is a writepages() call */ unsigned range_cyclic:1; /* range_start is cyclic */ unsigned more_io:1; /* more io to be dispatched */ + unsigned range_cont:1; }; /* diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 789b6ad..ded57d5 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -956,6 +956,9 @@ retry: } if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) mapping->writeback_index = index; + + if (wbc->range_cont) + wbc->range_start = index << PAGE_CACHE_SHIFT; return ret; } EXPORT_SYMBOL(write_cache_pages); -- cgit v0.10.2 From 61628a3f3a37af2bf25daf8e26fd6b76a78c4f76 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Invert lock ordering of page_lock and transaction start in delalloc With the reverse locking, we need to start a transation before taking the page lock, so in ext4_da_writepages() we need to break the write-out into chunks, and restart the journal for each chunck to ensure the write-out fits in a single transaction. Updated patch from Aneesh Kumar K.V which fixes delalloc sync hang with journal lock inversion, and address the performance regression issue. Signed-off-by: Mingming Cao Signed-off-by: Aneesh Kumar K.V Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index dabc3b6..42c4c0c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2565,6 +2565,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, int err = 0, depth, ret; unsigned long allocated = 0; struct ext4_allocation_request ar; + loff_t disksize; __clear_bit(BH_New, &bh_result->b_state); ext_debug("blocks %u/%lu requested for inode %u\n", @@ -2755,8 +2756,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, newblock = ext_pblock(&newex); allocated = ext4_ext_get_actual_len(&newex); outnew: - if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = inode->i_size; + if (extend_disksize) { + disksize = ((loff_t) iblock + ar.len) << inode->i_blkbits; + if (disksize > i_size_read(inode)) + disksize = i_size_read(inode); + if (disksize > EXT4_I(inode)->i_disksize) + EXT4_I(inode)->i_disksize = disksize; + } set_buffer_new(bh_result); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a6b800c..7923336 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -847,6 +847,7 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, struct ext4_inode_info *ei = EXT4_I(inode); int count = 0; ext4_fsblk_t first_block = 0; + loff_t disksize; J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); @@ -922,8 +923,13 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, * protect it if you're about to implement concurrent * ext4_get_block() -bzzz */ - if (!err && extend_disksize && inode->i_size > ei->i_disksize) - ei->i_disksize = inode->i_size; + if (!err && extend_disksize) { + disksize = ((loff_t) iblock + count) << inode->i_blkbits; + if (disksize > i_size_read(inode)) + disksize = i_size_read(inode); + if (disksize > ei->i_disksize) + ei->i_disksize = disksize; + } if (err) goto cleanup; @@ -1683,13 +1689,11 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, do { if (cur_logical >= logical + blocks) break; - if (buffer_delay(bh)) { bh->b_blocknr = pblock; clear_buffer_delay(bh); - } else if (buffer_mapped(bh)) { + } else if (buffer_mapped(bh)) BUG_ON(bh->b_blocknr != pblock); - } cur_logical++; pblock++; @@ -1764,10 +1768,10 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd) if (buffer_delay(lbh)) mpage_put_bnr_to_bhs(mpd, next, &new); - /* go for the remaining blocks */ - next += new.b_size >> mpd->inode->i_blkbits; - remain -= new.b_size; - } + /* go for the remaining blocks */ + next += new.b_size >> mpd->inode->i_blkbits; + remain -= new.b_size; + } } #define BH_FLAGS ((1 << BH_Uptodate) | (1 << BH_Mapped) | (1 << BH_Delay)) @@ -1993,18 +1997,14 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { - int ret, needed_blocks = ext4_writepage_trans_blocks(inode); + int ret; unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; loff_t disksize = EXT4_I(inode)->i_disksize; handle_t *handle = NULL; - if (create) { - handle = ext4_journal_start(inode, needed_blocks); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out; - } - } + handle = ext4_journal_current_handle(); + BUG_ON(handle == NULL); + BUG_ON(create == 0); ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, bh_result, create, 0, EXT4_DELALLOC_RSVED); @@ -2029,65 +2029,157 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, up_write(&EXT4_I(inode)->i_data_sem); if (EXT4_I(inode)->i_disksize == disksize) { - if (handle == NULL) - handle = ext4_journal_start(inode, 1); - if (!IS_ERR(handle)) - ext4_mark_inode_dirty(handle, inode); + ret = ext4_mark_inode_dirty(handle, inode); + return ret; } } - ret = 0; } - -out: - if (handle && !IS_ERR(handle)) - ext4_journal_stop(handle); - return ret; } + +static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) +{ + return !buffer_mapped(bh) || buffer_delay(bh); +} + /* FIXME!! only support data=writeback mode */ +/* + * get called vi ext4_da_writepages after taking page lock + * We may end up doing block allocation here in case + * mpage_da_map_blocks failed to allocate blocks. + */ static int ext4_da_writepage(struct page *page, struct writeback_control *wbc) { - struct inode *inode = page->mapping->host; - handle_t *handle = NULL; int ret = 0; - int err; + loff_t size; + unsigned long len; + handle_t *handle = NULL; + struct buffer_head *page_bufs; + struct inode *inode = page->mapping->host; - if (ext4_journal_current_handle()) - goto out_fail; + handle = ext4_journal_current_handle(); + if (!handle) { + /* + * This can happen when we aren't called via + * ext4_da_writepages() but directly (shrink_page_list). + * We cannot easily start a transaction here so we just skip + * writing the page in case we would have to do so. + */ + size = i_size_read(inode); - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out_fail; + page_bufs = page_buffers(page); + if (page->index == size >> PAGE_CACHE_SHIFT) + len = size & ~PAGE_CACHE_MASK; + else + len = PAGE_CACHE_SIZE; + + if (walk_page_buffers(NULL, page_bufs, 0, + len, NULL, ext4_bh_unmapped_or_delay)) { + /* + * We can't do block allocation under + * page lock without a handle . So redirty + * the page and return + */ + BUG_ON(wbc->sync_mode != WB_SYNC_NONE); + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return 0; + } } if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) - ret = nobh_writepage(page, ext4_get_block, wbc); + ret = nobh_writepage(page, ext4_da_get_block_write, wbc); else - ret = block_write_full_page(page, ext4_get_block, wbc); - - if (!ret && inode->i_size > EXT4_I(inode)->i_disksize) { - EXT4_I(inode)->i_disksize = inode->i_size; - ext4_mark_inode_dirty(handle, inode); - } + ret = block_write_full_page(page, ext4_da_get_block_write, wbc); - err = ext4_journal_stop(handle); - if (!ret) - ret = err; - return ret; - -out_fail: - redirty_page_for_writepage(wbc, page); - unlock_page(page); return ret; } + +/* + * For now just follow the DIO way to estimate the max credits + * needed to write out EXT4_MAX_WRITEBACK_PAGES. + * todo: need to calculate the max credits need for + * extent based files, currently the DIO credits is based on + * indirect-blocks mapping way. + * + * Probably should have a generic way to calculate credits + * for DIO, writepages, and truncate + */ +#define EXT4_MAX_WRITEBACK_PAGES DIO_MAX_BLOCKS +#define EXT4_MAX_WRITEBACK_CREDITS DIO_CREDITS + static int ext4_da_writepages(struct address_space *mapping, struct writeback_control *wbc) { - return mpage_da_writepages(mapping, wbc, ext4_da_get_block_write); + struct inode *inode = mapping->host; + handle_t *handle = NULL; + int needed_blocks; + int ret = 0; + long to_write; + loff_t range_start = 0; + + /* + * No pages to write? This is mainly a kludge to avoid starting + * a transaction for special inodes like journal inode on last iput() + * because that could violate lock ordering on umount + */ + if (!mapping->nrpages) + return 0; + + /* + * Estimate the worse case needed credits to write out + * EXT4_MAX_BUF_BLOCKS pages + */ + needed_blocks = EXT4_MAX_WRITEBACK_CREDITS; + + to_write = wbc->nr_to_write; + if (!wbc->range_cyclic) { + /* + * If range_cyclic is not set force range_cont + * and save the old writeback_index + */ + wbc->range_cont = 1; + range_start = wbc->range_start; + } + + while (!ret && to_write) { + /* start a new transaction*/ + handle = ext4_journal_start(inode, needed_blocks); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out_writepages; + } + /* + * set the max dirty pages could be write at a time + * to fit into the reserved transaction credits + */ + if (wbc->nr_to_write > EXT4_MAX_WRITEBACK_PAGES) + wbc->nr_to_write = EXT4_MAX_WRITEBACK_PAGES; + + to_write -= wbc->nr_to_write; + ret = mpage_da_writepages(mapping, wbc, + ext4_da_get_block_write); + ext4_journal_stop(handle); + if (wbc->nr_to_write) { + /* + * There is no more writeout needed + * or we requested for a noblocking writeout + * and we found the device congested + */ + to_write += wbc->nr_to_write; + break; + } + wbc->nr_to_write = to_write; + } + +out_writepages: + wbc->nr_to_write = to_write; + if (range_start) + wbc->range_start = range_start; + return ret; } static int ext4_da_write_begin(struct file *file, struct address_space *mapping, @@ -2137,11 +2229,6 @@ out: return ret; } -static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) -{ - return !buffer_mapped(bh) || buffer_delay(bh); -} - static int ext4_da_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, -- cgit v0.10.2 From cd1aac32923a9c8adcc0ae85e33c1ca0c5855838 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Add ordered mode support for delalloc This provides a new ordered mode implementation which gets rid of using buffer heads to enforce the ordering between metadata change with the related data chage. Instead, in the new ordering mode, it keeps track of all of the inodes touched by each transaction on a list, and when that transaction is committed, it flushes all of the dirty pages for those inodes. In addition, the new ordered mode reverses the lock ordering of the page lock and transaction lock, which provides easier support for delayed allocation. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7923336..24518b5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2043,11 +2043,12 @@ static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) return !buffer_mapped(bh) || buffer_delay(bh); } -/* FIXME!! only support data=writeback mode */ /* * get called vi ext4_da_writepages after taking page lock * We may end up doing block allocation here in case * mpage_da_map_blocks failed to allocate blocks. + * + * We also get called via journal_submit_inode_data_buffers */ static int ext4_da_writepage(struct page *page, struct writeback_control *wbc) @@ -2066,6 +2067,7 @@ static int ext4_da_writepage(struct page *page, * ext4_da_writepages() but directly (shrink_page_list). * We cannot easily start a transaction here so we just skip * writing the page in case we would have to do so. + * We reach here also via journal_submit_inode_data_buffers */ size = i_size_read(inode); @@ -2081,8 +2083,11 @@ static int ext4_da_writepage(struct page *page, * We can't do block allocation under * page lock without a handle . So redirty * the page and return + * We may reach here when we do a journal commit + * via journal_submit_inode_data_buffers. + * If we don't have mapping block we just ignore + * them */ - BUG_ON(wbc->sync_mode != WB_SYNC_NONE); redirty_page_for_writepage(wbc, page); unlock_page(page); return 0; @@ -2097,7 +2102,6 @@ static int ext4_da_writepage(struct page *page, return ret; } - /* * For now just follow the DIO way to estimate the max credits * needed to write out EXT4_MAX_WRITEBACK_PAGES. @@ -2130,7 +2134,7 @@ static int ext4_da_writepages(struct address_space *mapping, return 0; /* - * Estimate the worse case needed credits to write out + * Estimate the worse case needed credits to write out * EXT4_MAX_BUF_BLOCKS pages */ needed_blocks = EXT4_MAX_WRITEBACK_CREDITS; @@ -2152,6 +2156,19 @@ static int ext4_da_writepages(struct address_space *mapping, ret = PTR_ERR(handle); goto out_writepages; } + if (ext4_should_order_data(inode)) { + /* + * With ordered mode we need to add + * the inode to the journal handle + * when we do block allocation. + */ + ret = ext4_jbd2_file_inode(handle, inode); + if (ret) { + ext4_journal_stop(handle); + goto out_writepages; + } + + } /* * set the max dirty pages could be write at a time * to fit into the reserved transaction credits @@ -2735,7 +2752,10 @@ static const struct address_space_operations ext4_da_aops = { void ext4_set_aops(struct inode *inode) { - if (ext4_should_order_data(inode)) + if (ext4_should_order_data(inode) && + test_opt(inode->i_sb, DELALLOC)) + inode->i_mapping->a_ops = &ext4_da_aops; + else if (ext4_should_order_data(inode)) inode->i_mapping->a_ops = &ext4_ordered_aops; else if (ext4_should_writeback_data(inode) && test_opt(inode->i_sb, DELALLOC)) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 483183d..f8b3be8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include /* * Default IO end handler for temporary BJ_IO buffer_heads. @@ -185,6 +187,27 @@ static int journal_wait_on_commit_record(struct buffer_head *bh) } /* + * write the filemap data using writepage() address_space_operations. + * We don't do block allocation here even for delalloc. We don't + * use writepages() because with dealyed allocation we may be doing + * block allocation in writepages(). + */ +static int journal_submit_inode_data_buffers(struct address_space *mapping) +{ + int ret; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL, + .nr_to_write = mapping->nrpages * 2, + .range_start = 0, + .range_end = i_size_read(mapping->host), + .for_writepages = 1, + }; + + ret = generic_writepages(mapping, &wbc); + return ret; +} + +/* * Submit all the data buffers of inode associated with the transaction to * disk. * @@ -192,7 +215,7 @@ static int journal_wait_on_commit_record(struct buffer_head *bh) * our inode list. We use JI_COMMIT_RUNNING flag to protect inode we currently * operate on from being released while we write out pages. */ -static int journal_submit_inode_data_buffers(journal_t *journal, +static int journal_submit_data_buffers(journal_t *journal, transaction_t *commit_transaction) { struct jbd2_inode *jinode; @@ -204,8 +227,13 @@ static int journal_submit_inode_data_buffers(journal_t *journal, mapping = jinode->i_vfs_inode->i_mapping; jinode->i_flags |= JI_COMMIT_RUNNING; spin_unlock(&journal->j_list_lock); - err = filemap_fdatawrite_range(mapping, 0, - i_size_read(jinode->i_vfs_inode)); + /* + * submit the inode data buffers. We use writepage + * instead of writepages. Because writepages can do + * block allocation with delalloc. We need to write + * only allocated blocks here. + */ + err = journal_submit_inode_data_buffers(mapping); if (!ret) ret = err; spin_lock(&journal->j_list_lock); @@ -228,7 +256,7 @@ static int journal_finish_inode_data_buffers(journal_t *journal, struct jbd2_inode *jinode, *next_i; int err, ret = 0; - /* For locking, see the comment in journal_submit_inode_data_buffers() */ + /* For locking, see the comment in journal_submit_data_buffers() */ spin_lock(&journal->j_list_lock); list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { jinode->i_flags |= JI_COMMIT_RUNNING; @@ -431,7 +459,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) * Now start flushing things to disk, in the order they appear * on the transaction lists. Data blocks go first. */ - err = journal_submit_inode_data_buffers(journal, commit_transaction); + err = journal_submit_data_buffers(journal, commit_transaction); if (err) jbd2_journal_abort(journal, err); -- cgit v0.10.2 From f0e6c98593eb8a77edb7dd0edb22bb9f9368c567 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Handle page without buffers in ext4_*_writepage() It can happen that buffers are removed from the page before it gets marked dirty and then is passed to writepage(). In writepage() we just initialize the buffers and check whether they are mapped and non delay. If they are mapped and non delay we write the page. Otherwise we mark them dirty. With this change we don't do block allocation at all in ext4_*_write_page. writepage() can get called under many condition and with a locking order of journal_start -> lock_page, we should not try to allocate blocks in writepage() which get called after taking page lock. writepage() can get called via shrink_page_list even with a journal handle which was created for doing inode update. For example when doing ext4_da_write_begin we create a journal handle with credit 1 expecting a i_disksize update for the inode. But ext4_da_write_begin can cause shrink_page_list via _grab_page_cache. So having a valid handle via ext4_journal_current_handle is not a guarantee that we can use the handle for block allocation in writepage, since we shouldn't be using credits that had been reserved for other updates. That it could result in we running out of credits when we update inodes. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 24518b5..ce47847 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2003,11 +2003,15 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, handle_t *handle = NULL; handle = ext4_journal_current_handle(); - BUG_ON(handle == NULL); - BUG_ON(create == 0); - - ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, + if (!handle) { + ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, + bh_result, 0, 0, 0); + BUG_ON(!ret); + } else { + ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, bh_result, create, 0, EXT4_DELALLOC_RSVED); + } + if (ret > 0) { bh_result->b_size = (ret << inode->i_blkbits); @@ -2040,15 +2044,37 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) { - return !buffer_mapped(bh) || buffer_delay(bh); + /* + * unmapped buffer is possible for holes. + * delay buffer is possible with delayed allocation + */ + return ((!buffer_mapped(bh) || buffer_delay(bh)) && buffer_dirty(bh)); +} + +static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + int ret = 0; + unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; + + /* + * we don't want to do block allocation in writepage + * so call get_block_wrap with create = 0 + */ + ret = ext4_get_blocks_wrap(NULL, inode, iblock, max_blocks, + bh_result, 0, 0, 0); + if (ret > 0) { + bh_result->b_size = (ret << inode->i_blkbits); + ret = 0; + } + return ret; } /* - * get called vi ext4_da_writepages after taking page lock - * We may end up doing block allocation here in case - * mpage_da_map_blocks failed to allocate blocks. - * - * We also get called via journal_submit_inode_data_buffers + * get called vi ext4_da_writepages after taking page lock (have journal handle) + * get called via journal_submit_inode_data_buffers (no journal handle) + * get called via shrink_page_list via pdflush (no journal handle) + * or grab_page_cache when doing write_begin (have journal handle) */ static int ext4_da_writepage(struct page *page, struct writeback_control *wbc) @@ -2056,37 +2082,61 @@ static int ext4_da_writepage(struct page *page, int ret = 0; loff_t size; unsigned long len; - handle_t *handle = NULL; struct buffer_head *page_bufs; struct inode *inode = page->mapping->host; - handle = ext4_journal_current_handle(); - if (!handle) { - /* - * This can happen when we aren't called via - * ext4_da_writepages() but directly (shrink_page_list). - * We cannot easily start a transaction here so we just skip - * writing the page in case we would have to do so. - * We reach here also via journal_submit_inode_data_buffers - */ - size = i_size_read(inode); + size = i_size_read(inode); + if (page->index == size >> PAGE_CACHE_SHIFT) + len = size & ~PAGE_CACHE_MASK; + else + len = PAGE_CACHE_SIZE; + if (page_has_buffers(page)) { page_bufs = page_buffers(page); - if (page->index == size >> PAGE_CACHE_SHIFT) - len = size & ~PAGE_CACHE_MASK; - else - len = PAGE_CACHE_SIZE; - - if (walk_page_buffers(NULL, page_bufs, 0, - len, NULL, ext4_bh_unmapped_or_delay)) { + if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, + ext4_bh_unmapped_or_delay)) { /* - * We can't do block allocation under - * page lock without a handle . So redirty - * the page and return + * We don't want to do block allocation + * So redirty the page and return * We may reach here when we do a journal commit * via journal_submit_inode_data_buffers. * If we don't have mapping block we just ignore - * them + * them. We can also reach here via shrink_page_list + */ + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return 0; + } + } else { + /* + * The test for page_has_buffers() is subtle: + * We know the page is dirty but it lost buffers. That means + * that at some moment in time after write_begin()/write_end() + * has been called all buffers have been clean and thus they + * must have been written at least once. So they are all + * mapped and we can happily proceed with mapping them + * and writing the page. + * + * Try to initialize the buffer_heads and check whether + * all are mapped and non delay. We don't want to + * do block allocation here. + */ + ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, + ext4_normal_get_block_write); + if (!ret) { + page_bufs = page_buffers(page); + /* check whether all are mapped and non delay */ + if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, + ext4_bh_unmapped_or_delay)) { + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return 0; + } + } else { + /* + * We can't do block allocation here + * so just redity the page and unlock + * and return */ redirty_page_for_writepage(wbc, page); unlock_page(page); @@ -2095,9 +2145,11 @@ static int ext4_da_writepage(struct page *page, } if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) - ret = nobh_writepage(page, ext4_da_get_block_write, wbc); + ret = nobh_writepage(page, ext4_normal_get_block_write, wbc); else - ret = block_write_full_page(page, ext4_da_get_block_write, wbc); + ret = block_write_full_page(page, + ext4_normal_get_block_write, + wbc); return ret; } @@ -2438,12 +2490,14 @@ static int __ext4_normal_writepage(struct page *page, struct inode *inode = page->mapping->host; if (test_opt(inode->i_sb, NOBH)) - return nobh_writepage(page, ext4_get_block, wbc); + return nobh_writepage(page, + ext4_normal_get_block_write, wbc); else - return block_write_full_page(page, ext4_get_block, wbc); + return block_write_full_page(page, + ext4_normal_get_block_write, + wbc); } - static int ext4_normal_writepage(struct page *page, struct writeback_control *wbc) { @@ -2452,13 +2506,24 @@ static int ext4_normal_writepage(struct page *page, loff_t len; J_ASSERT(PageLocked(page)); - J_ASSERT(page_has_buffers(page)); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; else len = PAGE_CACHE_SIZE; - BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, - ext4_bh_unmapped_or_delay)); + + if (page_has_buffers(page)) { + /* if page has buffers it should all be mapped + * and allocated. If there are not buffers attached + * to the page we know the page is dirty but it lost + * buffers. That means that at some moment in time + * after write_begin() / write_end() has been called + * all buffers have been clean and thus they must have been + * written at least once. So they are all mapped and we can + * happily proceed with mapping them and writing the page. + */ + BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, + ext4_bh_unmapped_or_delay)); + } if (!ext4_journal_current_handle()) return __ext4_normal_writepage(page, wbc); @@ -2478,7 +2543,8 @@ static int __ext4_journalled_writepage(struct page *page, int ret = 0; int err; - ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, ext4_get_block); + ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, + ext4_normal_get_block_write); if (ret != 0) goto out_unlock; @@ -2525,13 +2591,24 @@ static int ext4_journalled_writepage(struct page *page, loff_t len; J_ASSERT(PageLocked(page)); - J_ASSERT(page_has_buffers(page)); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; else len = PAGE_CACHE_SIZE; - BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, - ext4_bh_unmapped_or_delay)); + + if (page_has_buffers(page)) { + /* if page has buffers it should all be mapped + * and allocated. If there are not buffers attached + * to the page we know the page is dirty but it lost + * buffers. That means that at some moment in time + * after write_begin() / write_end() has been called + * all buffers have been clean and thus they must have been + * written at least once. So they are all mapped and we can + * happily proceed with mapping them and writing the page. + */ + BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, + ext4_bh_unmapped_or_delay)); + } if (ext4_journal_current_handle()) goto no_write; @@ -2549,7 +2626,9 @@ static int ext4_journalled_writepage(struct page *page, * really know unless we go poke around in the buffer_heads. * But block_write_full_page will do the right thing. */ - return block_write_full_page(page, ext4_get_block, wbc); + return block_write_full_page(page, + ext4_normal_get_block_write, + wbc); } no_write: redirty_page_for_writepage(wbc, page); -- cgit v0.10.2 From 632eaeab1feb5d78c1e2bfb1d2dfc0ebb8ac187f Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: fix delalloc i_disksize early update issue Ext4_da_write_end() used walk_page_buffers() with a callback function of ext4_bh_unmapped_or_delay() to check if it extended the file size without allocating any blocks (since in this case i_disksize needs to be updated). However, this is didn't work proprely because the buffer head has not been marked dirty yet --- this is done later in block_commit_write() --- which caused ext4_bh_unmapped_or_delay() to always return false. In addition, walk_page_buffers() checks all of the buffer heads covering the page, and the only buffer_head that should be checked is the one covering the end of the write. Otherwise, given a 1k blocksize filesystem and a 4k page size, the buffer head covering the first 1k stripe of the file could be unmapped (because it was a sparse file), and the second or third buffer_head covering that page could be mapped, and using walk_page_buffers() would fail in this case since it would stop at the first unmapped buffer_head and return true. The core problem is that walk_page_buffers() was intended to do work in a callback function, and a non-zero return value indicated a failure, which termined the walk of the buffer heads covering the page. It was not intended to be used with a boolean function, such as ext4_bh_unmapped_or_delay(). Add addtional fix from Aneesh to protect i_disksize update rave with truncate. Signed-off-by: Mingming Cao Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ce47847..0fbe678 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2298,6 +2298,29 @@ out: return ret; } +/* + * Check if we should update i_disksize + * when write to the end of file but not require block allocation + */ +static int ext4_da_should_update_i_disksize(struct page *page, + unsigned long offset) +{ + struct buffer_head *bh; + struct inode *inode = page->mapping->host; + unsigned int idx; + int i; + + bh = page_buffers(page); + idx = offset >> inode->i_blkbits; + + for (i=0; i < idx; i++) + bh = bh->b_this_page; + + if (!buffer_mapped(bh) || (buffer_delay(bh))) + return 0; + return 1; +} + static int ext4_da_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, @@ -2307,6 +2330,10 @@ static int ext4_da_write_end(struct file *file, int ret = 0, ret2; handle_t *handle = ext4_journal_current_handle(); loff_t new_i_size; + unsigned long start, end; + + start = pos & (PAGE_CACHE_SIZE - 1); + end = start + copied -1; /* * generic_write_end() will run mark_inode_dirty() if i_size @@ -2315,18 +2342,23 @@ static int ext4_da_write_end(struct file *file, */ new_i_size = pos + copied; - if (new_i_size > EXT4_I(inode)->i_disksize) - if (!walk_page_buffers(NULL, page_buffers(page), - 0, len, NULL, ext4_bh_unmapped_or_delay)){ - /* - * Updating i_disksize when extending file without - * needing block allocation - */ - if (ext4_should_order_data(inode)) - ret = ext4_jbd2_file_inode(handle, inode); + if (new_i_size > EXT4_I(inode)->i_disksize) { + if (ext4_da_should_update_i_disksize(page, end)) { + down_write(&EXT4_I(inode)->i_data_sem); + if (new_i_size > EXT4_I(inode)->i_disksize) { + /* + * Updating i_disksize when extending file + * without needing block allocation + */ + if (ext4_should_order_data(inode)) + ret = ext4_jbd2_file_inode(handle, + inode); - EXT4_I(inode)->i_disksize = new_i_size; + EXT4_I(inode)->i_disksize = new_i_size; + } + up_write(&EXT4_I(inode)->i_data_sem); } + } ret2 = generic_write_end(file, mapping, pos, len, copied, page, fsdata); copied = ret2; @@ -3394,6 +3426,11 @@ void ext4_truncate(struct inode *inode) goto out_stop; /* + * From here we block out all ext4_get_block() callers who want to + * modify the block allocation tree. + */ + down_write(&ei->i_data_sem); + /* * The orphan list entry will now protect us from any crash which * occurs before the truncate completes, so it is now safe to propagate * the new, shorter inode size (held for now in i_size) into the @@ -3402,12 +3439,6 @@ void ext4_truncate(struct inode *inode) */ ei->i_disksize = inode->i_size; - /* - * From here we block out all ext4_get_block() callers who want to - * modify the block allocation tree. - */ - down_write(&ei->i_data_sem); - if (n == 1) { /* direct blocks */ ext4_free_data(handle, inode, NULL, i_data+offsets[0], i_data + EXT4_NDIR_BLOCKS); -- cgit v0.10.2 From 3e3398a08d6e516675d5af853d625dc7dd90eab1 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: delayed allocation i_blocks fix for stat Right now i_blocks is not getting updated until the blocks are actually allocaed on disk. This means with delayed allocation, right after files are copied, "ls -sF" shoes the file as taking 0 blocks on disk. "du" also shows the files taking zero space, which is highly confusing to the user. Since delayed allocation already keeps track of per-inode total number of blocks that are subject to delayed allocation, this patch fix this by using that to adjust the value returned by stat(2). When real block allocation is done, the i_blocks will get updated. Since the reserved blocks for delayed allocation will be decreased, this will be keep value returned by stat(2) consistent. Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0962f4e..303e41c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1059,6 +1059,8 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, extern struct inode *ext4_iget(struct super_block *, unsigned long); extern int ext4_write_inode (struct inode *, int); extern int ext4_setattr (struct dentry *, struct iattr *); +extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat); extern void ext4_delete_inode (struct inode *); extern int ext4_sync_inode (handle_t *, struct inode *); extern void ext4_discard_reservation (struct inode *); diff --git a/fs/ext4/file.c b/fs/ext4/file.c index b9510ba..430eb79 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -161,6 +161,7 @@ const struct file_operations ext4_file_operations = { const struct inode_operations ext4_file_inode_operations = { .truncate = ext4_truncate, .setattr = ext4_setattr, + .getattr = ext4_getattr, #ifdef CONFIG_EXT4DEV_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0fbe678..8ca2763 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4231,6 +4231,32 @@ err_out: return error; } +int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) +{ + struct inode *inode; + unsigned long delalloc_blocks; + + inode = dentry->d_inode; + generic_fillattr(inode, stat); + + /* + * We can't update i_blocks if the block allocation is delayed + * otherwise in the case of system crash before the real block + * allocation is done, we will have i_blocks inconsistent with + * on-disk file blocks. + * We always keep i_blocks updated together with real + * allocation. But to not confuse with user, stat + * will return the blocks that include the delayed allocation + * blocks for this file. + */ + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); + delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); + + stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; + return 0; +} /* * How many blocks doth make a writepage()? -- cgit v0.10.2 From dd919b9822c5fd9fd72f95a602440130297c3857 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Enable delalloc by default. Enable delalloc by default to ensure it gets sufficient testing and because it makes the filesystem much more efficient. Add a nodealalloc option to disable delayed allocation, and update ext4_show_options to show delayed allocation off if it is disabled. If the data=journal mount option is used, disable delayed allocation since the delalloc code doesn't support data=journal yet. Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" Signed-off-by: Mingming Cao diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 25e2f24..4e104dd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -756,6 +756,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_puts(seq, ",nomballoc"); if (test_opt(sb, I_VERSION)) seq_puts(seq, ",i_version"); + if (!test_opt(sb, DELALLOC)) + seq_puts(seq, ",nodelalloc"); + if (sbi->s_stripe) seq_printf(seq, ",stripe=%lu", sbi->s_stripe); @@ -903,7 +906,7 @@ enum { Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, - Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, + Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc, }; static match_table_t tokens = { @@ -963,6 +966,7 @@ static match_table_t tokens = { {Opt_stripe, "stripe=%u"}, {Opt_resize, "resize"}, {Opt_delalloc, "delalloc"}, + {Opt_nodelalloc, "nodelalloc"}, {Opt_err, NULL}, }; @@ -1328,6 +1332,9 @@ set_qf_format: set_opt(sbi->s_mount_opt, I_VERSION); sb->s_flags |= MS_I_VERSION; break; + case Opt_nodelalloc: + clear_opt(sbi->s_mount_opt, DELALLOC); + break; case Opt_mballoc: set_opt(sbi->s_mount_opt, MBALLOC); break; @@ -1984,6 +1991,13 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) */ set_opt(sbi->s_mount_opt, MBALLOC); + /* + * enable delayed allocation by default + * Use -o nodelalloc to turn it off + */ + set_opt(sbi->s_mount_opt, DELALLOC); + + if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, NULL, 0)) goto failed_mount; @@ -2422,6 +2436,13 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": "writeback"); + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { + printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " + "requested data journaling mode\n"); + clear_opt(sbi->s_mount_opt, DELALLOC); + } else if (test_opt(sb, DELALLOC)) + printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); + ext4_ext_init(sb); ext4_mb_init(sb, needs_recovery); -- cgit v0.10.2 From c07651b556323e0e763c452587fe29d2b034b314 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Don't allow nonextenst mount option for large filesystem The block mapped inode format can address only blocks within 2**32. This causes a number of issues, the biggest of which is that the block allocator needs to be taught that certain inodes can not utilize block numbers > 2**32. So until this is fixed, it is simplest to fail mounting of file systems with more than 2**32 blocks if the -o noextents option is given. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4e104dd..2bf9cdd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1004,6 +1004,7 @@ static int parse_options (char *options, struct super_block *sb, int qtype, qfmt; char *qname; #endif + ext4_fsblk_t last_block; if (!options) return 1; @@ -1326,6 +1327,20 @@ set_qf_format: set_opt (sbi->s_mount_opt, EXTENTS); break; case Opt_noextents: + /* + * When e2fsprogs support resizing an already existing + * ext3 file system to greater than 2**32 we need to + * add support to block allocator to handle growing + * already existing block mapped inode so that blocks + * allocated for them fall within 2**32 + */ + last_block = ext4_blocks_count(sbi->s_es) - 1; + if (last_block > 0xffffffffULL) { + printk(KERN_ERR "EXT4-fs: Filesystem too " + "large to mount with " + "-o noextents options\n"); + return 0; + } clear_opt (sbi->s_mount_opt, EXTENTS); break; case Opt_i_version: -- cgit v0.10.2 From e4079a11f5ed966b7d972cc69e8d337a0f095e32 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: do not set extents feature from the kernel We've talked for a while about getting rid of any feature- setting from the kernel; this gets rid of the code which would set the INCOMPAT_EXTENTS flag on the first file write when mounted as ext4[dev]. With this patch, if the extents feature is not already set on disk, then mounting as ext4 will fall back to noextents with a warning, and if -o extents is explicitly requested, the mount will fail, also with warning. Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 8b0a10a..a92eb30 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -836,14 +836,10 @@ got: goto fail_free_drop; if (test_opt(sb, EXTENTS)) { - /* set extent flag only for diretory, file and normal symlink*/ + /* set extent flag only for directory, file and normal symlink*/ if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) { EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; ext4_ext_tree_init(handle, inode); - err = ext4_update_incompat_feature(handle, sb, - EXT4_FEATURE_INCOMPAT_EXTENTS); - if (err) - goto fail_free_drop; } } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2bf9cdd..1cb371d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1324,6 +1324,13 @@ set_qf_format: clear_opt(sbi->s_mount_opt, NOBH); break; case Opt_extents: + if (!EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_EXTENTS)) { + ext4_warning(sb, __func__, + "extents feature not enabled " + "on this filesystem, use tune2fs\n"); + return 0; + } set_opt (sbi->s_mount_opt, EXTENTS); break; case Opt_noextents: @@ -1997,12 +2004,18 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) /* * turn on extents feature by default in ext4 filesystem - * User -o noextents to turn it off + * only if feature flag already set by mkfs or tune2fs. + * Use -o noextents to turn it off */ - set_opt(sbi->s_mount_opt, EXTENTS); + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) + set_opt(sbi->s_mount_opt, EXTENTS); + else + ext4_warning(sb, __func__, + "extents feature not enabled on this filesystem, " + "use tune2fs.\n"); /* - * turn on mballoc feature by default in ext4 filesystem - * User -o nomballoc to turn it off + * turn on mballoc code by default in ext4 filesystem + * Use -o nomballoc to turn it off */ set_opt(sbi->s_mount_opt, MBALLOC); -- cgit v0.10.2 From 49f1487b2e41bd8439ea39a4f15b4064e823cc54 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 11 Jul 2008 19:27:31 -0400 Subject: ext4: Documention update for new ordered mode and delayed allocation Adding some documentations for delayed allocation and new ordered mode. Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index 7e940c6..80e193d 100644 --- a/Documentation/filesystems/ext4.txt +++ b/Documentation/filesystems/ext4.txt @@ -66,7 +66,7 @@ Mailing list: linux-ext4@vger.kernel.org * extent format reduces metadata overhead (RAM, IO for access, transactions) * extent format more robust in face of on-disk corruption due to magics, * internal redunancy in tree -* improved file allocation (multi-block alloc, delayed alloc) +* improved file allocation (multi-block alloc) * fix 32000 subdirectory limit * nsec timestamps for mtime, atime, ctime, create time * inode version field on disk (NFSv4, Lustre) @@ -77,6 +77,10 @@ Mailing list: linux-ext4@vger.kernel.org flex_bg feature * large file support * Inode allocation using large virtual block groups via flex_bg +* delayed allocation +* large block (up to pagesize) support +* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force + the ordering) 2.2 Candidate features for future inclusion @@ -239,7 +243,9 @@ stripe=n Number of filesystem blocks that mballoc will try to use for allocation size and alignment. For RAID5/6 systems this should be the number of data disks * RAID chunk size in file system blocks. - +delalloc (*) Deferring block allocation until write-out time. +nodelalloc Disable delayed allocation. Blocks are allocation + when data is copied from user to page cache. Data Mode ========= There are 3 different data modes: @@ -253,10 +259,10 @@ typically provide the best ext4 performance. * ordered mode In data=ordered mode, ext4 only officially journals metadata, but it logically -groups metadata and data blocks into a single unit called a transaction. When -it's time to write the new metadata out to disk, the associated data blocks -are written first. In general, this mode performs slightly slower than -writeback but significantly faster than journal mode. +groups metadata information related to data changes with the data blocks into a +single unit called a transaction. When it's time to write the new metadata +out to disk, the associated data blocks are written first. In general, +this mode performs slightly slower than writeback but significantly faster than journal mode. * journal mode data=journal mode provides full data and metadata journaling. All new data is @@ -264,7 +270,8 @@ written to the journal first, and then to its final location. In the event of a crash, the journal can be replayed, bringing both data and metadata into a consistent state. This mode is the slowest except when data needs to be read from and written to disk at the same time where it -outperforms all others modes. +outperforms all others modes. Curently ext4 does not have delayed +allocation support if this data journalling mode is selected. References ========== -- cgit v0.10.2 From 38032f72601deac7aab00691c79e83d09b204e2a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 11 Jul 2008 12:57:31 -0700 Subject: acpi_pm clccksource: fix printk format warning Fix printk format warning in acpi_pm clocksource: linux-next-20080711/drivers/clocksource/acpi_pm.c:231: warning: format '%04lx' expects type 'long unsigned int', but argument 2 has type 'u32' Signed-off-by: Randy Dunlap Cc: akpm Signed-off-by: Thomas Gleixner diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 3baee02..bcd7d0e 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -227,8 +227,8 @@ static int __init parse_pmtmr(char *arg) if (strict_strtoul(arg, 16, &base)) return -EINVAL; - printk(KERN_INFO "PMTMR IOPort override: 0x%04lx -> 0x%04lx\n", - pmtmr_ioport, base); + printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04x\n", + (unsigned int)pmtmr_ioport, base); pmtmr_ioport = base; return 1; -- cgit v0.10.2 From de32a2434f7ce4600da90ecb44abcdc365ada1d0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 12 Jul 2008 05:33:30 +0200 Subject: kernel-paramaters: document pmtmr= command line option Signed-off-by: Thomas Gleixner diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e07c432..356b64b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1571,6 +1571,10 @@ and is between 256 and 4096 characters. It is defined in the file Format: { parport | timid | 0 } See also Documentation/parport.txt. + pmtmr= [X86] Manual setup of pmtmr I/O Port. + Override pmtimer IOPort with a hex value. + e.g. pmtmr=0x508 + pnpacpi= [ACPI] { off } -- cgit v0.10.2 From da1f29f5dfcc8641f9ff6f3deaa9f03b57e63229 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 12 Jul 2008 02:50:15 +0200 Subject: x86: remove conflicting nx6325 and nx6125 quirks We have two conflicting DMA-based quirks in there for the same set of boxes (HP nx6325 and nx6125) and one of them actually breaks my box. So remove the extra code. Signed-off-by: Rafael J. Wysocki Cc: Stephen Rothwell Cc: =?iso-8859-1?q?T=F6r=F6k_Edwin?= Cc: Vegard Nossum Cc: Andreas Herrmann Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 9c981c4..785700a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -84,8 +84,6 @@ int acpi_lapic; int acpi_ioapic; int acpi_strict; -static int disable_irq0_through_ioapic __initdata; - u8 acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; @@ -982,10 +980,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) int pin; struct mp_config_intsrc mp_irq; - /* Skip the 8254 timer interrupt (IRQ 0) if requested. */ - if (bus_irq == 0 && disable_irq0_through_ioapic) - return; - /* * Convert 'gsi' to 'ioapic.pin'. */ @@ -1052,10 +1046,6 @@ void __init mp_config_acpi_legacy_irqs(void) for (i = 0; i < 16; i++) { int idx; - /* Skip the 8254 timer interrupt (IRQ 0) if requested. */ - if (i == 0 && disable_irq0_through_ioapic) - continue; - for (idx = 0; idx < mp_irq_entries; idx++) { struct mp_config_intsrc *irq = mp_irqs + idx; @@ -1413,17 +1403,6 @@ static int __init force_acpi_ht(const struct dmi_system_id *d) } /* - * Don't register any I/O APIC entries for the 8254 timer IRQ. - */ -static int __init -dmi_disable_irq0_through_ioapic(const struct dmi_system_id *d) -{ - pr_notice("%s detected: disabling IRQ 0 through I/O APIC\n", d->ident); - disable_irq0_through_ioapic = 1; - return 0; -} - -/* * Force ignoring BIOS IRQ0 pin2 override */ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) @@ -1608,32 +1587,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { * is enabled. This input is incorrectly designated the * ISA IRQ 0 via an interrupt source override even though * it is wired to the output of the master 8259A and INTIN0 - * is not connected at all. Abandon any attempts to route - * IRQ 0 through the I/O APIC therefore. - */ - { - .callback = dmi_disable_irq0_through_ioapic, - .ident = "HP NX6125 laptop", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"), - }, - }, - { - .callback = dmi_disable_irq0_through_ioapic, - .ident = "HP NX6325 laptop", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), - }, - }, - /* - * HP laptops which use a DSDT reporting as HP/SB400/10000, - * which includes some code which overrides all temperature - * trip points to 16C if the INTIN2 input of the I/O APIC - * is enabled. This input is incorrectly designated the - * ISA IRQ 0 via an interrupt source override even though - * it is wired to the output of the master 8259A and INTIN0 * is not connected at all. Force ignoring BIOS IRQ0 pin2 * override in that cases. */ -- cgit v0.10.2 From eca91e7838ec92e8c12122849ec7539c4765b689 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 10 Jul 2008 14:50:39 -0700 Subject: x86_64: fix delayed signals On three of the several paths in entry_64.S that call do_notify_resume() on the way back to user mode, we fail to properly check again for newly-arrived work that requires another call to do_notify_resume() before going to user mode. These paths set the mask to check only _TIF_NEED_RESCHED, but this is wrong. The other paths that lead to do_notify_resume() do this correctly already, and entry_32.S does it correctly in all cases. All paths back to user mode have to check all the _TIF_WORK_MASK flags at the last possible stage, with interrupts disabled. Otherwise, we miss any flags (TIF_SIGPENDING for example) that were set any time after we entered do_notify_resume(). More work flags can be set (or left set) synchronously inside do_notify_resume(), as TIF_SIGPENDING can be, or asynchronously by interrupts or other CPUs (which then send an asynchronous interrupt). There are many different scenarios that could hit this bug, most of them races. The simplest one to demonstrate does not require any race: when one signal has done handler setup at the check before returning from a syscall, and there is another signal pending that should be handled. The second signal's handler should interrupt the first signal handler before it actually starts (so the interrupted PC is still at the handler's entry point). Instead, it runs away until the next kernel entry (next syscall, tick, etc). This test behaves correctly on 32-bit kernels, and fails on 64-bit (either 32-bit or 64-bit test binary). With this fix, it works. #define _GNU_SOURCE #include #include #include #include #ifndef REG_RIP #define REG_RIP REG_EIP #endif static sig_atomic_t hit1, hit2; static void handler (int sig, siginfo_t *info, void *ctx) { ucontext_t *uc = ctx; if ((void *) uc->uc_mcontext.gregs[REG_RIP] == &handler) { if (sig == SIGUSR1) hit1 = 1; else hit2 = 1; } printf ("%s at %#lx\n", strsignal (sig), uc->uc_mcontext.gregs[REG_RIP]); } int main (void) { struct sigaction sa; sigset_t set; sigemptyset (&sa.sa_mask); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = &handler; if (sigaction (SIGUSR1, &sa, NULL) || sigaction (SIGUSR2, &sa, NULL)) return 2; sigemptyset (&set); sigaddset (&set, SIGUSR1); sigaddset (&set, SIGUSR2); if (sigprocmask (SIG_BLOCK, &set, NULL)) return 3; printf ("main at %p, handler at %p\n", &main, &handler); raise (SIGUSR1); raise (SIGUSR2); if (sigprocmask (SIG_UNBLOCK, &set, NULL)) return 4; if (hit1 + hit2 == 1) { puts ("PASS"); return 0; } puts ("FAIL"); return 1; } Signed-off-by: Roland McGrath Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 466b928..bb4e22f 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -306,7 +306,7 @@ sysret_signal: leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 xorl %esi,%esi # oldset -> arg2 call ptregscall_common -1: movl $_TIF_NEED_RESCHED,%edi +1: movl $_TIF_WORK_MASK,%edi /* Use IRET because user could have changed frame. This works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ DISABLE_INTERRUPTS(CLBR_NONE) @@ -394,7 +394,7 @@ int_signal: movq %rsp,%rdi # &ptregs -> arg1 xorl %esi,%esi # oldset -> arg2 call do_notify_resume -1: movl $_TIF_NEED_RESCHED,%edi +1: movl $_TIF_WORK_MASK,%edi int_restore_rest: RESTORE_REST DISABLE_INTERRUPTS(CLBR_NONE) @@ -647,9 +647,8 @@ retint_signal: RESTORE_REST DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - movl $_TIF_NEED_RESCHED,%edi GET_THREAD_INFO(%rcx) - jmp retint_check + jmp retint_with_reschedule #ifdef CONFIG_PREEMPT /* Returning to kernel space. Check if we need preemption */ -- cgit v0.10.2 From a72f0dbfd93159acdf2467e5a022b28f763061f6 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Sat, 12 Jul 2008 15:42:11 +0800 Subject: crypto: s390 - Respect STFL bit Bevore issuing any s390 crypto operation check whether the CPACF facility is enabled in the facility list. That way a virtualization layer can prevent usage of the CPACF facility regardless of the availability of the crypto instructions. Signed-off-by: Jan Glauber Signed-off-by: Herbert Xu diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 9992f95..0ef9829 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h @@ -296,6 +296,10 @@ static inline int crypt_s390_func_available(int func) unsigned char status[16]; int ret; + /* check if CPACF facility (bit 17) is available */ + if (!(stfl() & 1ULL << (31 - 17))) + return 0; + switch (func & CRYPT_S390_OP_MASK) { case CRYPT_S390_KM: ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); -- cgit v0.10.2 From cc4724492ddf920475ad7f12bfcb81ffca16f777 Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Wed, 21 May 2008 01:01:11 +0530 Subject: [SCSI] mpt fusion : Setting intial period to 0xFF instead of 0xA The initial period is set to 0xFF Signed-off-by: Sathya Prakash Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 1cdea1a..9b49516 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -447,6 +447,7 @@ static int mptspi_target_alloc(struct scsi_target *starget) spi_max_offset(starget) = ioc->spi_data.maxSyncOffset; spi_offset(starget) = 0; + spi_period(starget) = 0xFF; mptspi_write_width(starget, 0); return 0; -- cgit v0.10.2 From d54d48b80fb523ce1b1a644e4876b08835ad757f Mon Sep 17 00:00:00 2001 From: "Prakash, Sathya" Date: Wed, 21 May 2008 01:02:18 +0530 Subject: [SCSI] mpt fusion : Adding FAULT Reset polling work When the firmware is in Fault state it will be identifed only when the next time the driver access the IOC state. This patch includes a polling function in the driver which will be executed in regular interval to check the status of the firmware and if it is in Fault state, then the firmware will be reset by the driver. Signed-off-by: Sathya Prakash Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 30a800e..9bc35617 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -253,6 +253,55 @@ mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) return 0; } +/** + * mpt_fault_reset_work - work performed on workq after ioc fault + * @work: input argument, used to derive ioc + * +**/ +static void +mpt_fault_reset_work(struct work_struct *work) +{ + MPT_ADAPTER *ioc = + container_of(work, MPT_ADAPTER, fault_reset_work.work); + u32 ioc_raw_state; + int rc; + unsigned long flags; + + if (ioc->diagPending || !ioc->active) + goto out; + + ioc_raw_state = mpt_GetIocState(ioc, 0); + if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { + printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", + ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); + printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", + ioc->name, __FUNCTION__); + rc = mpt_HardResetHandler(ioc, CAN_SLEEP); + printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, + __FUNCTION__, (rc == 0) ? "success" : "failed"); + ioc_raw_state = mpt_GetIocState(ioc, 0); + if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) + printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " + "reset (%04xh)\n", ioc->name, ioc_raw_state & + MPI_DOORBELL_DATA_MASK); + } + + out: + /* + * Take turns polling alternate controller + */ + if (ioc->alt_ioc) + ioc = ioc->alt_ioc; + + /* rearm the timer */ + spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); + if (ioc->reset_work_q) + queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, + msecs_to_jiffies(MPT_POLLING_INTERVAL)); + spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); +} + + /* * Process turbo (context) reply... */ @@ -1616,6 +1665,22 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) /* Find lookup slot. */ INIT_LIST_HEAD(&ioc->list); + + /* Initialize workqueue */ + INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); + spin_lock_init(&ioc->fault_reset_work_lock); + + snprintf(ioc->reset_work_q_name, KOBJ_NAME_LEN, "mpt_poll_%d", ioc->id); + ioc->reset_work_q = + create_singlethread_workqueue(ioc->reset_work_q_name); + if (!ioc->reset_work_q) { + printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", + ioc->name); + pci_release_selected_regions(pdev, ioc->bars); + kfree(ioc); + return -ENOMEM; + } + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", ioc->name, &ioc->facts, &ioc->pfacts[0])); @@ -1722,6 +1787,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) iounmap(ioc->memmap); if (r != -5) pci_release_selected_regions(pdev, ioc->bars); + + destroy_workqueue(ioc->reset_work_q); + ioc->reset_work_q = NULL; + kfree(ioc); pci_set_drvdata(pdev, NULL); return r; @@ -1754,6 +1823,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) } #endif + if (!ioc->alt_ioc) + queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, + msecs_to_jiffies(MPT_POLLING_INTERVAL)); + return 0; } @@ -1769,6 +1842,19 @@ mpt_detach(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); char pname[32]; u8 cb_idx; + unsigned long flags; + struct workqueue_struct *wq; + + /* + * Stop polling ioc for fault condition + */ + spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); + wq = ioc->reset_work_q; + ioc->reset_work_q = NULL; + spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); + cancel_delayed_work(&ioc->fault_reset_work); + destroy_workqueue(wq); + sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); remove_proc_entry(pname, NULL); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 7496793..6adab64 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -176,6 +176,8 @@ /* debug print string length used for events and iocstatus */ # define EVENT_DESCR_STR_SZ 100 +#define MPT_POLLING_INTERVAL 1000 /* in milliseconds */ + #ifdef __KERNEL__ /* { */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -709,6 +711,12 @@ typedef struct _MPT_ADAPTER struct workqueue_struct *fc_rescan_work_q; struct scsi_cmnd **ScsiLookup; spinlock_t scsi_lookup_lock; + + char reset_work_q_name[KOBJ_NAME_LEN]; + struct workqueue_struct *reset_work_q; + struct delayed_work fault_reset_work; + spinlock_t fault_reset_work_lock; + } MPT_ADAPTER; /* -- cgit v0.10.2 From 40753caa364bfba60ebd5e2a8bdf366ef175d03c Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:56 -0500 Subject: [SCSI] iscsi class, iscsi_tcp/iser: add host arg to session creation iscsi offload (bnx2i and qla4xx) allocate a scsi host per hba, so the session creation path needs a shost/host_no argument. Software iscsi/iser will follow the same behabior as before where it allcoates a host per session, but in the future iser will probably look more like bnx2i where the host's parent is the hardware (rnic for iser and for bnx2i it is the nic), because it does not use a socket layer like how iscsi_tcp does. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index aeb58ca..efc1219 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -368,6 +368,7 @@ static struct iscsi_transport iscsi_iser_transport; static struct iscsi_cls_session * iscsi_iser_session_create(struct iscsi_transport *iscsit, struct scsi_transport_template *scsit, + struct Scsi_Host *shost, uint16_t cmds_max, uint16_t qdepth, uint32_t initial_cmdsn, uint32_t *hostno) { diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 72b9b2a..81c421a 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1871,8 +1871,9 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) static struct iscsi_cls_session * iscsi_tcp_session_create(struct iscsi_transport *iscsit, struct scsi_transport_template *scsit, - uint16_t cmds_max, uint16_t qdepth, - uint32_t initial_cmdsn, uint32_t *hostno) + struct Scsi_Host *shost, uint16_t cmds_max, + uint16_t qdepth, uint32_t initial_cmdsn, + uint32_t *hostno) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 65d1737..2a6669d 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1017,21 +1017,38 @@ int iscsi_session_event(struct iscsi_cls_session *session, EXPORT_SYMBOL_GPL(iscsi_session_event); static int -iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) +iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev, + uint32_t host_no, uint32_t initial_cmdsn, + uint16_t cmds_max, uint16_t queue_depth) { struct iscsi_transport *transport = priv->iscsi_transport; struct iscsi_cls_session *session; - uint32_t hostno; + struct Scsi_Host *shost = NULL; - session = transport->create_session(transport, &priv->t, - ev->u.c_session.cmds_max, - ev->u.c_session.queue_depth, - ev->u.c_session.initial_cmdsn, - &hostno); + /* + * Software iscsi allocates a host per session, but + * offload drivers (and possibly iser one day) allocate a host per + * hba/nic/rnic. Offload will match a host here, but software will + * return a new hostno after the create_session callback has returned. + */ + if (host_no != UINT_MAX) { + shost = scsi_host_lookup(host_no); + if (IS_ERR(shost)) { + printk(KERN_ERR "Could not find host no %u to " + "create session\n", host_no); + return -ENODEV; + } + } + + session = transport->create_session(transport, &priv->t, shost, + cmds_max, queue_depth, + initial_cmdsn, &host_no); + if (shost) + scsi_host_put(shost); if (!session) return -ENOMEM; - ev->r.c_session_ret.host_no = hostno; + ev->r.c_session_ret.host_no = host_no; ev->r.c_session_ret.sid = session->sid; return 0; } @@ -1190,6 +1207,7 @@ static int iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int err = 0; + uint32_t host_no = UINT_MAX; struct iscsi_uevent *ev = NLMSG_DATA(nlh); struct iscsi_transport *transport = NULL; struct iscsi_internal *priv; @@ -1208,7 +1226,17 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) switch (nlh->nlmsg_type) { case ISCSI_UEVENT_CREATE_SESSION: - err = iscsi_if_create_session(priv, ev); + err = iscsi_if_create_session(priv, ev, host_no, + ev->u.c_session.initial_cmdsn, + ev->u.c_session.cmds_max, + ev->u.c_session.queue_depth); + break; + case ISCSI_UEVENT_CREATE_BOUND_SESSION: + err = iscsi_if_create_session(priv, ev, + ev->u.c_bound_session.host_no, + ev->u.c_bound_session.initial_cmdsn, + ev->u.c_bound_session.cmds_max, + ev->u.c_bound_session.queue_depth); break; case ISCSI_UEVENT_DESTROY_SESSION: session = iscsi_session_lookup(ev->u.d_session.sid); diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index e19e584..1883c85 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -50,6 +50,7 @@ enum iscsi_uevent_e { ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15, ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16, ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17, + ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18, /* up events */ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, @@ -78,6 +79,12 @@ struct iscsi_uevent { uint16_t cmds_max; uint16_t queue_depth; } c_session; + struct msg_create_bound_session { + uint32_t host_no; + uint32_t initial_cmdsn; + uint16_t cmds_max; + uint16_t queue_depth; + } c_bound_session; struct msg_destroy_session { uint32_t sid; } d_session; diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index cd3ca63..f24cf02 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -24,6 +24,7 @@ #define LIBISCSI_H #include +#include #include #include #include diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index aab1eae..02a8520 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -92,8 +92,8 @@ struct iscsi_transport { unsigned int max_conn; unsigned int max_cmd_len; struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it, - struct scsi_transport_template *t, uint16_t, uint16_t, - uint32_t sn, uint32_t *hn); + struct scsi_transport_template *t, struct Scsi_Host *shost, + uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn); void (*destroy_session) (struct iscsi_cls_session *session); struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, uint32_t cid); -- cgit v0.10.2 From d3826721b198001c55353b1c54e10843068aae63 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:57 -0500 Subject: [SCSI] iscsi class, iscsi drivers: remove unused iscsi_transport attrs max_cmd_len and max_conn are not really used. max_cmd_len is always 16 and can be set by the LLD. max_conn is always one since we do not support MCS. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index efc1219..32f5d5e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -592,7 +592,6 @@ static struct iscsi_transport iscsi_iser_transport = { .host_template = &iscsi_iser_sht, .conndata_size = sizeof(struct iscsi_conn), .max_lun = ISCSI_ISER_MAX_LUN, - .max_cmd_len = ISCSI_ISER_MAX_CMD_LEN, /* session management */ .create_session = iscsi_iser_session_create, .destroy_session = iscsi_session_teardown, diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index a8c1b30..66a2f30 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -96,7 +96,6 @@ /* support upto 512KB in one RDMA */ #define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K) #define ISCSI_ISER_MAX_LUN 256 -#define ISCSI_ISER_MAX_CMD_LEN 16 /* QP settings */ /* Maximal bounds on received asynchronous PDUs */ diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 81c421a..aecadbd 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1978,8 +1978,6 @@ static struct iscsi_transport iscsi_tcp_transport = { ISCSI_HOST_NETDEV_NAME, .host_template = &iscsi_sht, .conndata_size = sizeof(struct iscsi_conn), - .max_conn = 1, - .max_cmd_len = 16, /* session management */ .create_session = iscsi_tcp_session_create, .destroy_session = iscsi_tcp_session_destroy, diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index b43bf1d..01a1a4d 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1830,7 +1830,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, shost->max_id = 1; shost->max_channel = 0; shost->max_lun = iscsit->max_lun; - shost->max_cmd_len = iscsit->max_cmd_len; + shost->max_cmd_len = 16; shost->transportt = scsit; shost->transportt->create_work_queue = 1; shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 2a6669d..e6a090e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -102,15 +102,11 @@ static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); show_transport_attr(caps, "0x%x"); show_transport_attr(max_lun, "%d"); -show_transport_attr(max_conn, "%d"); -show_transport_attr(max_cmd_len, "%d"); static struct attribute *iscsi_transport_attrs[] = { &dev_attr_handle.attr, &dev_attr_caps.attr, &dev_attr_max_lun.attr, - &dev_attr_max_conn.attr, - &dev_attr_max_cmd_len.attr, NULL, }; diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 02a8520..afed70e 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -89,8 +89,6 @@ struct iscsi_transport { /* LLD session data size */ int sessiondata_size; int max_lun; - unsigned int max_conn; - unsigned int max_cmd_len; struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it, struct scsi_transport_template *t, struct Scsi_Host *shost, uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn); -- cgit v0.10.2 From 32c6e1b9a2e27076b7070a9ec56a9e5437ebd725 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:58 -0500 Subject: [SCSI] iscsi class: rename iscsi_host to iscsi_cls_host This renames the iscsi_host to iscsi_cls_host to match the other structs, because libiscsi wants to use the iscsi_host name in the future. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index e6a090e..5577a60 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -114,13 +114,11 @@ static struct attribute_group iscsi_transport_group = { .attrs = iscsi_transport_attrs, }; - - static int iscsi_setup_host(struct transport_container *tc, struct device *dev, struct device *cdev) { struct Scsi_Host *shost = dev_to_shost(dev); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; memset(ihost, 0, sizeof(*ihost)); INIT_LIST_HEAD(&ihost->sessions); @@ -140,7 +138,7 @@ static int iscsi_remove_host(struct transport_container *tc, struct device *dev, struct device *cdev) { struct Scsi_Host *shost = dev_to_shost(dev); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; destroy_workqueue(ihost->scan_workq); return 0; @@ -293,7 +291,7 @@ static int iscsi_is_session_dev(const struct device *dev) */ int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time) { - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; /* * qla4xxx will have kicked off some session unblocks before calling * scsi_scan_host, so just wait for them to complete. @@ -305,7 +303,7 @@ EXPORT_SYMBOL_GPL(iscsi_scan_finished); static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, uint id, uint lun) { - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; struct iscsi_cls_session *session; mutex_lock(&ihost->mutex); @@ -325,7 +323,7 @@ static void iscsi_scan_session(struct work_struct *work) struct iscsi_cls_session *session = container_of(work, struct iscsi_cls_session, scan_work); struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; unsigned long flags; spin_lock_irqsave(&session->lock, flags); @@ -377,7 +375,7 @@ static void __iscsi_unblock_session(struct work_struct *work) container_of(work, struct iscsi_cls_session, unblock_work); struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; unsigned long flags; /* @@ -445,7 +443,7 @@ static void __iscsi_unbind_session(struct work_struct *work) container_of(work, struct iscsi_cls_session, unbind_work); struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; /* Prevent new scans and make sure scanning is not in progress */ mutex_lock(&ihost->mutex); @@ -463,7 +461,7 @@ static void __iscsi_unbind_session(struct work_struct *work) static int iscsi_unbind_session(struct iscsi_cls_session *session) { struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; return queue_work(ihost->scan_workq, &session->unbind_work); } @@ -505,7 +503,7 @@ EXPORT_SYMBOL_GPL(iscsi_alloc_session); int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) { struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost; + struct iscsi_cls_host *ihost; unsigned long flags; int err; @@ -591,7 +589,7 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data) void iscsi_remove_session(struct iscsi_cls_session *session) { struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost->shost_data; unsigned long flags; int err; @@ -1619,7 +1617,7 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->t.host_attrs.ac.attrs = &priv->host_attrs[0]; priv->t.host_attrs.ac.class = &iscsi_host_class.class; priv->t.host_attrs.ac.match = iscsi_host_match; - priv->t.host_size = sizeof(struct iscsi_host); + priv->t.host_size = sizeof(struct iscsi_cls_host); transport_container_register(&priv->t.host_attrs); SETUP_HOST_RD_ATTR(netdev, ISCSI_HOST_NETDEV_NAME); diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index afed70e..7287022 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -201,7 +201,7 @@ struct iscsi_cls_session { #define starget_to_session(_stgt) \ iscsi_dev_to_session(_stgt->dev.parent) -struct iscsi_host { +struct iscsi_cls_host { struct list_head sessions; atomic_t nr_scans; struct mutex mutex; -- cgit v0.10.2 From 756135215ec743be6fdce2bdebe8cdb9f8a231f6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:53:59 -0500 Subject: [SCSI] iscsi: remove session and host binding in libiscsi bnx2i allocates a host per netdevice but will use libiscsi, so this unbinds the session from the host in that code. This will also be useful for the iser parent device dma settings fixes. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 32f5d5e..5a75004 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -74,6 +74,10 @@ #include "iscsi_iser.h" +static struct scsi_host_template iscsi_iser_sht; +static struct iscsi_transport iscsi_iser_transport; +static struct scsi_transport_template *iscsi_iser_scsi_transport; + static unsigned int iscsi_max_lun = 512; module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); @@ -363,40 +367,64 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) return iscsi_conn_start(cls_conn); } -static struct iscsi_transport iscsi_iser_transport; +static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) +{ + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + + iscsi_session_teardown(cls_session); + scsi_remove_host(shost); + iscsi_host_teardown(shost); + scsi_host_put(shost); +} static struct iscsi_cls_session * -iscsi_iser_session_create(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - struct Scsi_Host *shost, - uint16_t cmds_max, uint16_t qdepth, - uint32_t initial_cmdsn, uint32_t *hostno) +iscsi_iser_session_create(struct Scsi_Host *shost, + uint16_t cmds_max, uint16_t qdepth, + uint32_t initial_cmdsn, uint32_t *hostno) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; int i; - uint32_t hn; struct iscsi_cmd_task *ctask; struct iscsi_mgmt_task *mtask; struct iscsi_iser_cmd_task *iser_ctask; struct iser_desc *desc; + if (shost) { + printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", + shost->host_no); + return NULL; + } + + shost = scsi_host_alloc(&iscsi_iser_sht, 0); + if (!shost) + return NULL; + shost->transportt = iscsi_iser_scsi_transport; + shost->max_lun = iscsi_max_lun; + shost->max_id = 0; + shost->max_channel = 0; + shost->max_cmd_len = 16; + + iscsi_host_setup(shost, qdepth); + + if (scsi_add_host(shost, NULL)) + goto free_host; + *hostno = shost->host_no; + /* * we do not support setting can_queue cmd_per_lun from userspace yet * because we preallocate so many resources */ - cls_session = iscsi_session_setup(iscsit, scsit, + cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, ISCSI_DEF_XMIT_CMDS_MAX, - ISCSI_MAX_CMD_PER_LUN, sizeof(struct iscsi_iser_cmd_task), sizeof(struct iser_desc), - initial_cmdsn, &hn); + initial_cmdsn); if (!cls_session) - return NULL; - - *hostno = hn; - session = class_to_transport_session(cls_session); + goto remove_host; + session = cls_session->dd_data; + shost->can_queue = session->cmds_max; /* libiscsi setup itts, data and pool so just set desc fields */ for (i = 0; i < session->cmds_max; i++) { ctask = session->cmds[i]; @@ -413,6 +441,13 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit, } return cls_session; + +remove_host: + scsi_remove_host(shost); +free_host: + iscsi_host_teardown(shost); + scsi_host_put(shost); + return NULL; } static int @@ -589,12 +624,11 @@ static struct iscsi_transport iscsi_iser_transport = { .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME | ISCSI_HOST_INITIATOR_NAME, - .host_template = &iscsi_iser_sht, .conndata_size = sizeof(struct iscsi_conn), - .max_lun = ISCSI_ISER_MAX_LUN, + .sessiondata_size = sizeof(struct iscsi_session), /* session management */ .create_session = iscsi_iser_session_create, - .destroy_session = iscsi_session_teardown, + .destroy_session = iscsi_iser_session_destroy, /* connection management */ .create_conn = iscsi_iser_conn_create, .bind_conn = iscsi_iser_conn_bind, @@ -633,8 +667,6 @@ static int __init iser_init(void) return -EINVAL; } - iscsi_iser_transport.max_lun = iscsi_max_lun; - memset(&ig, 0, sizeof(struct iser_global)); ig.desc_cache = kmem_cache_create("iser_descriptors", @@ -650,7 +682,9 @@ static int __init iser_init(void) mutex_init(&ig.connlist_mutex); INIT_LIST_HEAD(&ig.connlist); - if (!iscsi_register_transport(&iscsi_iser_transport)) { + iscsi_iser_scsi_transport = iscsi_register_transport( + &iscsi_iser_transport); + if (!iscsi_iser_scsi_transport) { iser_err("iscsi_register_transport failed\n"); err = -EINVAL; goto register_transport_failure; diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index aecadbd..8cdcaf3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -64,6 +64,10 @@ MODULE_LICENSE("GPL"); #define BUG_ON(expr) #endif +static struct scsi_transport_template *iscsi_tcp_scsi_transport; +static struct scsi_host_template iscsi_sht; +static struct iscsi_transport iscsi_tcp_transport; + static unsigned int iscsi_max_lun = 512; module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); @@ -1623,6 +1627,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, int is_leading) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_host *ihost = shost_priv(shost); struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct sock *sk; @@ -1646,8 +1652,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, if (err) goto free_socket; - err = iscsi_tcp_get_addr(conn, sock, conn->local_address, - &conn->local_port, kernel_getsockname); + err = iscsi_tcp_get_addr(conn, sock, ihost->local_address, + &ihost->local_port, kernel_getsockname); if (err) goto free_socket; @@ -1821,29 +1827,6 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, return len; } -static int -iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, - char *buf) -{ - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); - int len; - - switch (param) { - case ISCSI_HOST_PARAM_IPADDRESS: - spin_lock_bh(&session->lock); - if (!session->leadconn) - len = -ENODEV; - else - len = sprintf(buf, "%s\n", - session->leadconn->local_address); - spin_unlock_bh(&session->lock); - break; - default: - return iscsi_host_get_param(shost, param, buf); - } - return len; -} - static void iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) { @@ -1869,26 +1852,44 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) } static struct iscsi_cls_session * -iscsi_tcp_session_create(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - struct Scsi_Host *shost, uint16_t cmds_max, +iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, uint16_t qdepth, uint32_t initial_cmdsn, uint32_t *hostno) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; - uint32_t hn; int cmd_i; - cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth, - sizeof(struct iscsi_tcp_cmd_task), - sizeof(struct iscsi_tcp_mgmt_task), - initial_cmdsn, &hn); - if (!cls_session) + if (shost) { + printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", + shost->host_no); + return NULL; + } + + shost = scsi_host_alloc(&iscsi_sht, sizeof(struct iscsi_host)); + if (!shost) return NULL; - *hostno = hn; + shost->transportt = iscsi_tcp_scsi_transport; + shost->max_lun = iscsi_max_lun; + shost->max_id = 0; + shost->max_channel = 0; + shost->max_cmd_len = 16; + + iscsi_host_setup(shost, qdepth); + + if (scsi_add_host(shost, NULL)) + goto free_host; + *hostno = shost->host_no; + + cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max, + sizeof(struct iscsi_tcp_cmd_task), + sizeof(struct iscsi_tcp_mgmt_task), + initial_cmdsn); + if (!cls_session) + goto remove_host; + session = cls_session->dd_data; - session = class_to_transport_session(cls_session); + shost->can_queue = session->cmds_max; for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; @@ -1904,20 +1905,30 @@ iscsi_tcp_session_create(struct iscsi_transport *iscsit, mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr; } - if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session))) - goto r2tpool_alloc_fail; - + if (iscsi_r2tpool_alloc(session)) + goto remove_session; return cls_session; -r2tpool_alloc_fail: +remove_session: iscsi_session_teardown(cls_session); +remove_host: + scsi_remove_host(shost); +free_host: + iscsi_host_teardown(shost); + scsi_host_put(shost); return NULL; } static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) { - iscsi_r2tpool_free(class_to_transport_session(cls_session)); + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + + iscsi_r2tpool_free(cls_session->dd_data); iscsi_session_teardown(cls_session); + + scsi_remove_host(shost); + iscsi_host_teardown(shost); + scsi_host_put(shost); } static int iscsi_tcp_slave_configure(struct scsi_device *sdev) @@ -1976,8 +1987,8 @@ static struct iscsi_transport iscsi_tcp_transport = { .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | ISCSI_HOST_INITIATOR_NAME | ISCSI_HOST_NETDEV_NAME, - .host_template = &iscsi_sht, .conndata_size = sizeof(struct iscsi_conn), + .sessiondata_size = sizeof(struct iscsi_session), /* session management */ .create_session = iscsi_tcp_session_create, .destroy_session = iscsi_tcp_session_destroy, @@ -1991,7 +2002,7 @@ static struct iscsi_transport iscsi_tcp_transport = { .start_conn = iscsi_conn_start, .stop_conn = iscsi_tcp_conn_stop, /* iscsi host params */ - .get_host_param = iscsi_tcp_host_get_param, + .get_host_param = iscsi_host_get_param, .set_host_param = iscsi_host_set_param, /* IO */ .send_pdu = iscsi_conn_send_pdu, @@ -2013,9 +2024,10 @@ iscsi_tcp_init(void) iscsi_max_lun); return -EINVAL; } - iscsi_tcp_transport.max_lun = iscsi_max_lun; - if (!iscsi_register_transport(&iscsi_tcp_transport)) + iscsi_tcp_scsi_transport = iscsi_register_transport( + &iscsi_tcp_transport); + if (!iscsi_tcp_scsi_transport) return -ENODEV; return 0; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 01a1a4d..64b1dd8 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -38,14 +38,6 @@ #include #include -struct iscsi_session * -class_to_transport_session(struct iscsi_cls_session *cls_session) -{ - struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - return iscsi_hostdata(shost->hostdata); -} -EXPORT_SYMBOL_GPL(class_to_transport_session); - /* Serial Number Arithmetic, 32 bits, less than, RFC1982 */ #define SNA32_CHECK 2147483648UL @@ -1096,6 +1088,7 @@ enum { int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) { + struct iscsi_cls_session *cls_session; struct Scsi_Host *host; int reason = 0; struct iscsi_session *session; @@ -1109,10 +1102,11 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) host = sc->device->host; spin_unlock(host->host_lock); - session = iscsi_hostdata(host->hostdata); + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; spin_lock(&session->lock); - reason = iscsi_session_chkready(session_to_cls(session)); + reason = iscsi_session_chkready(cls_session); if (reason) { sc->result = reason; goto fault; @@ -1222,7 +1216,7 @@ EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) { - struct iscsi_session *session = class_to_transport_session(cls_session); + struct iscsi_session *session = cls_session->dd_data; spin_lock_bh(&session->lock); if (session->state != ISCSI_STATE_LOGGED_IN) { @@ -1236,9 +1230,13 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); int iscsi_eh_host_reset(struct scsi_cmnd *sc) { - struct Scsi_Host *host = sc->device->host; - struct iscsi_session *session = iscsi_hostdata(host->hostdata); - struct iscsi_conn *conn = session->leadconn; + struct iscsi_cls_session *cls_session; + struct iscsi_session *session; + struct iscsi_conn *conn; + + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + conn = session->leadconn; mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); @@ -1405,7 +1403,7 @@ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) enum scsi_eh_timer_return rc = EH_NOT_HANDLED; cls_session = starget_to_session(scsi_target(scmd->device)); - session = class_to_transport_session(cls_session); + session = cls_session->dd_data; debug_scsi("scsi cmd %p timedout\n", scmd); @@ -1507,13 +1505,16 @@ static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask, int iscsi_eh_abort(struct scsi_cmnd *sc) { - struct Scsi_Host *host = sc->device->host; - struct iscsi_session *session = iscsi_hostdata(host->hostdata); + struct iscsi_cls_session *cls_session; + struct iscsi_session *session; struct iscsi_conn *conn; struct iscsi_cmd_task *ctask; struct iscsi_tm *hdr; int rc, age; + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); /* @@ -1630,12 +1631,15 @@ static void iscsi_prep_lun_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) int iscsi_eh_device_reset(struct scsi_cmnd *sc) { - struct Scsi_Host *host = sc->device->host; - struct iscsi_session *session = iscsi_hostdata(host->hostdata); + struct iscsi_cls_session *cls_session; + struct iscsi_session *session; struct iscsi_conn *conn; struct iscsi_tm *hdr; int rc = FAILED; + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun); mutex_lock(&session->eh_mutex); @@ -1760,55 +1764,53 @@ void iscsi_pool_free(struct iscsi_pool *q) } EXPORT_SYMBOL_GPL(iscsi_pool_free); -/* - * iSCSI Session's hostdata organization: - * - * *------------------* <== hostdata_session(host->hostdata) - * | ptr to class sess| - * |------------------| <== iscsi_hostdata(host->hostdata) - * | iscsi_session | - * *------------------* - */ +void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth) +{ + if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) { + if (qdepth != 0) + printk(KERN_ERR "iscsi: invalid queue depth of %d. " + "Queue depth must be between 1 and %d.\n", + qdepth, ISCSI_MAX_CMD_PER_LUN); + qdepth = ISCSI_DEF_CMD_PER_LUN; + } + + shost->transportt->create_work_queue = 1; + shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; + shost->cmd_per_lun = qdepth; +} +EXPORT_SYMBOL_GPL(iscsi_host_setup); -#define hostdata_privsize(_sz) (sizeof(unsigned long) + _sz + \ - _sz % sizeof(unsigned long)) +void iscsi_host_teardown(struct Scsi_Host *shost) +{ + struct iscsi_host *ihost = shost_priv(shost); -#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata)) + kfree(ihost->netdev); + kfree(ihost->hwaddress); + kfree(ihost->initiatorname); +} +EXPORT_SYMBOL_GPL(iscsi_host_teardown); /** * iscsi_session_setup - create iscsi cls session and host and session - * @scsit: scsi transport template * @iscsit: iscsi transport template - * @cmds_max: scsi host can queue - * @qdepth: scsi host cmds per lun + * @shost: scsi host + * @cmds_max: session can queue * @cmd_task_size: LLD ctask private data size * @mgmt_task_size: LLD mtask private data size * @initial_cmdsn: initial CmdSN - * @hostno: host no allocated * * This can be used by software iscsi_transports that allocate * a session per scsi host. - **/ + */ struct iscsi_cls_session * -iscsi_session_setup(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - uint16_t cmds_max, uint16_t qdepth, - int cmd_task_size, int mgmt_task_size, - uint32_t initial_cmdsn, uint32_t *hostno) +iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, + uint16_t cmds_max, int cmd_task_size, int mgmt_task_size, + uint32_t initial_cmdsn) { - struct Scsi_Host *shost; struct iscsi_session *session; struct iscsi_cls_session *cls_session; int cmd_i; - if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) { - if (qdepth != 0) - printk(KERN_ERR "iscsi: invalid queue depth of %d. " - "Queue depth must be between 1 and %d.\n", - qdepth, ISCSI_MAX_CMD_PER_LUN); - qdepth = ISCSI_DEF_CMD_PER_LUN; - } - if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET || cmds_max < 2) { if (cmds_max != 0) @@ -1819,25 +1821,11 @@ iscsi_session_setup(struct iscsi_transport *iscsit, cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; } - shost = scsi_host_alloc(iscsit->host_template, - hostdata_privsize(sizeof(*session))); - if (!shost) + cls_session = iscsi_alloc_session(shost, iscsit); + if (!cls_session) return NULL; - - /* the iscsi layer takes one task for reserve */ - shost->can_queue = cmds_max - 1; - shost->cmd_per_lun = qdepth; - shost->max_id = 1; - shost->max_channel = 0; - shost->max_lun = iscsit->max_lun; - shost->max_cmd_len = 16; - shost->transportt = scsit; - shost->transportt->create_work_queue = 1; - shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; - *hostno = shost->host_no; - - session = iscsi_hostdata(shost->hostdata); - memset(session, 0, sizeof(struct iscsi_session)); + session = cls_session->dd_data; + session->cls_session = cls_session; session->host = shost; session->state = ISCSI_STATE_FREE; session->fast_abort = 1; @@ -1851,6 +1839,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, session->max_r2t = 1; session->tt = iscsit; mutex_init(&session->eh_mutex); + spin_lock_init(&session->lock); /* initialize SCSI PDU commands pool */ if (iscsi_pool_init(&session->cmdpool, session->cmds_max, @@ -1868,8 +1857,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, INIT_LIST_HEAD(&ctask->running); } - spin_lock_init(&session->lock); - /* initialize immediate command pool */ if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, (void***)&session->mgmt_cmds, @@ -1887,49 +1874,37 @@ iscsi_session_setup(struct iscsi_transport *iscsit, INIT_LIST_HEAD(&mtask->running); } - if (scsi_add_host(shost, NULL)) - goto add_host_fail; - if (!try_module_get(iscsit->owner)) - goto cls_session_fail; - - cls_session = iscsi_create_session(shost, iscsit, 0); - if (!cls_session) - goto module_put; - *(unsigned long*)shost->hostdata = (unsigned long)cls_session; + goto module_get_fail; + if (iscsi_add_session(cls_session, 0)) + goto cls_session_fail; return cls_session; -module_put: - module_put(iscsit->owner); cls_session_fail: - scsi_remove_host(shost); -add_host_fail: + module_put(iscsit->owner); +module_get_fail: iscsi_pool_free(&session->mgmtpool); mgmtpool_alloc_fail: iscsi_pool_free(&session->cmdpool); cmdpool_alloc_fail: - scsi_host_put(shost); + iscsi_free_session(cls_session); return NULL; } EXPORT_SYMBOL_GPL(iscsi_session_setup); /** * iscsi_session_teardown - destroy session, host, and cls_session - * shost: scsi host + * @cls_session: iscsi session * - * This can be used by software iscsi_transports that allocate - * a session per scsi host. - **/ + * The driver must have called iscsi_remove_session before + * calling this. + */ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) { - struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_session *session = cls_session->dd_data; struct module *owner = cls_session->transport->owner; - iscsi_remove_session(cls_session); - scsi_remove_host(shost); - iscsi_pool_free(&session->mgmtpool); iscsi_pool_free(&session->cmdpool); @@ -1938,12 +1913,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) kfree(session->username); kfree(session->username_in); kfree(session->targetname); - kfree(session->netdev); - kfree(session->hwaddress); - kfree(session->initiatorname); - iscsi_free_session(cls_session); - scsi_host_put(shost); + iscsi_destroy_session(cls_session); module_put(owner); } EXPORT_SYMBOL_GPL(iscsi_session_teardown); @@ -1956,7 +1927,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_teardown); struct iscsi_cls_conn * iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) { - struct iscsi_session *session = class_to_transport_session(cls_session); + struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn; struct iscsi_cls_conn *cls_conn; char *data; @@ -2140,7 +2111,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) } spin_unlock_bh(&session->lock); - iscsi_unblock_session(session_to_cls(session)); + iscsi_unblock_session(session->cls_session); wake_up(&conn->ehwait); return 0; } @@ -2225,7 +2196,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, if (session->state == ISCSI_STATE_IN_RECOVERY && old_stop_stage != STOP_CONN_RECOVER) { debug_scsi("blocking session\n"); - iscsi_block_session(session_to_cls(session)); + iscsi_block_session(session->cls_session); } } @@ -2260,7 +2231,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_stop); int iscsi_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, int is_leading) { - struct iscsi_session *session = class_to_transport_session(cls_session); + struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn = cls_conn->dd_data; spin_lock_bh(&session->lock); @@ -2410,8 +2381,7 @@ EXPORT_SYMBOL_GPL(iscsi_set_param); int iscsi_session_get_param(struct iscsi_cls_session *cls_session, enum iscsi_param param, char *buf) { - struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_session *session = cls_session->dd_data; int len; switch(param) { @@ -2525,29 +2495,34 @@ EXPORT_SYMBOL_GPL(iscsi_conn_get_param); int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf) { - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_host *ihost = shost_priv(shost); int len; switch (param) { case ISCSI_HOST_PARAM_NETDEV_NAME: - if (!session->netdev) + if (!ihost->netdev) len = sprintf(buf, "%s\n", "default"); else - len = sprintf(buf, "%s\n", session->netdev); + len = sprintf(buf, "%s\n", ihost->netdev); break; case ISCSI_HOST_PARAM_HWADDRESS: - if (!session->hwaddress) + if (!ihost->hwaddress) len = sprintf(buf, "%s\n", "default"); else - len = sprintf(buf, "%s\n", session->hwaddress); + len = sprintf(buf, "%s\n", ihost->hwaddress); break; case ISCSI_HOST_PARAM_INITIATOR_NAME: - if (!session->initiatorname) + if (!ihost->initiatorname) len = sprintf(buf, "%s\n", "unknown"); else - len = sprintf(buf, "%s\n", session->initiatorname); + len = sprintf(buf, "%s\n", ihost->initiatorname); break; - + case ISCSI_HOST_PARAM_IPADDRESS: + if (!strlen(ihost->local_address)) + len = sprintf(buf, "%s\n", "unknown"); + else + len = sprintf(buf, "%s\n", + ihost->local_address); default: return -ENOSYS; } @@ -2559,20 +2534,20 @@ EXPORT_SYMBOL_GPL(iscsi_host_get_param); int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf, int buflen) { - struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_host *ihost = shost_priv(shost); switch (param) { case ISCSI_HOST_PARAM_NETDEV_NAME: - if (!session->netdev) - session->netdev = kstrdup(buf, GFP_KERNEL); + if (!ihost->netdev) + ihost->netdev = kstrdup(buf, GFP_KERNEL); break; case ISCSI_HOST_PARAM_HWADDRESS: - if (!session->hwaddress) - session->hwaddress = kstrdup(buf, GFP_KERNEL); + if (!ihost->hwaddress) + ihost->hwaddress = kstrdup(buf, GFP_KERNEL); break; case ISCSI_HOST_PARAM_INITIATOR_NAME: - if (!session->initiatorname) - session->initiatorname = kstrdup(buf, GFP_KERNEL); + if (!ihost->initiatorname) + ihost->initiatorname = kstrdup(buf, GFP_KERNEL); break; default: return -ENOSYS; diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 0c78694..6c6ee0f 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -114,7 +114,6 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { ISCSI_HOST_IPADDRESS | ISCSI_HOST_INITIATOR_NAME, .sessiondata_size = sizeof(struct ddb_entry), - .host_template = &qla4xxx_driver_template, .tgt_dscvr = qla4xxx_tgt_dscvr, .get_conn_param = qla4xxx_conn_get_param, diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 5577a60..9c00a15 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -101,12 +101,10 @@ show_transport_##name(struct device *dev, \ static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); show_transport_attr(caps, "0x%x"); -show_transport_attr(max_lun, "%d"); static struct attribute *iscsi_transport_attrs[] = { &dev_attr_handle.attr, &dev_attr_caps.attr, - &dev_attr_max_lun.attr, NULL, }; @@ -1034,8 +1032,7 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev, } } - session = transport->create_session(transport, &priv->t, shost, - cmds_max, queue_depth, + session = transport->create_session(shost, cmds_max, queue_depth, initial_cmdsn, &host_no); if (shost) scsi_host_put(shost); diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 1883c85..801a677 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -310,13 +310,6 @@ enum iscsi_host_param { #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) -#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata)) - -/** - * iscsi_hostdata - get LLD hostdata from scsi_host - * @_hostdata: pointer to scsi host's hostdata - **/ -#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long)) /* * These flags presents iSCSI Data-Path capabilities. diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index f24cf02..8a6271c 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -209,9 +209,6 @@ struct iscsi_conn { /* remote portal currently connected to */ int portal_port; char portal_address[ISCSI_ADDRESS_BUF_LEN]; - /* local address */ - int local_port; - char local_address[ISCSI_ADDRESS_BUF_LEN]; /* MIB-statistics */ uint64_t txdata_octets; @@ -247,6 +244,7 @@ enum { }; struct iscsi_session { + struct iscsi_cls_session *cls_session; /* * Syncs up the scsi eh thread with the iscsi eh thread when sending * task management functions. This must be taken before the session @@ -282,10 +280,6 @@ struct iscsi_session { char *password; char *password_in; char *targetname; - char *initiatorname; - /* hw address or netdev iscsi connection is bound to */ - char *hwaddress; - char *netdev; /* control data */ struct iscsi_transport *tt; struct Scsi_Host *host; @@ -307,6 +301,16 @@ struct iscsi_session { struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */ }; +struct iscsi_host { + char *initiatorname; + /* hw address or netdev iscsi connection is bound to */ + char *hwaddress; + char *netdev; + /* local address */ + int local_port; + char local_address[ISCSI_ADDRESS_BUF_LEN]; +}; + /* * scsi host template */ @@ -326,27 +330,24 @@ extern int iscsi_host_set_param(struct Scsi_Host *shost, int buflen); extern int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf); +extern void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth); +extern void iscsi_host_teardown(struct Scsi_Host *shost); /* * session management */ extern struct iscsi_cls_session * -iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *, - uint16_t, uint16_t, int, int, uint32_t, uint32_t *); +iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, + uint16_t, int, int, uint32_t); extern void iscsi_session_teardown(struct iscsi_cls_session *); -extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf, int buflen); extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, enum iscsi_param param, char *buf); -#define session_to_cls(_sess) \ - hostdata_session(_sess->host->hostdata) - #define iscsi_session_printk(prefix, _sess, fmt, a...) \ - iscsi_cls_session_printk(prefix, \ - (struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a) + iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a) /* * connection management diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 7287022..702eda2 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -83,15 +83,13 @@ struct iscsi_transport { /* LLD sets this to indicate what values it can export to sysfs */ uint64_t param_mask; uint64_t host_param_mask; - struct scsi_host_template *host_template; /* LLD connection data size */ int conndata_size; /* LLD session data size */ int sessiondata_size; - int max_lun; - struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it, - struct scsi_transport_template *t, struct Scsi_Host *shost, - uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn); + struct iscsi_cls_session *(*create_session) (struct Scsi_Host *shost, + uint16_t cmds_max, uint16_t qdepth, + uint32_t sn, uint32_t *hn); void (*destroy_session) (struct iscsi_cls_session *session); struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, uint32_t cid); -- cgit v0.10.2 From a4804cd6eb19318ae8d08ea967cfeaaf5c5b68a6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:00 -0500 Subject: [SCSI] iscsi: add iscsi host helpers This finishes the host/session unbinding, by adding some helpers to add and remove hosts and the session they manage. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 5a75004..62e35e5 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -371,10 +371,8 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) { struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); - iscsi_session_teardown(cls_session); - scsi_remove_host(shost); - iscsi_host_teardown(shost); - scsi_host_put(shost); + iscsi_host_remove(shost); + iscsi_host_free(shost); } static struct iscsi_cls_session * @@ -396,7 +394,7 @@ iscsi_iser_session_create(struct Scsi_Host *shost, return NULL; } - shost = scsi_host_alloc(&iscsi_iser_sht, 0); + shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN); if (!shost) return NULL; shost->transportt = iscsi_iser_scsi_transport; @@ -405,9 +403,7 @@ iscsi_iser_session_create(struct Scsi_Host *shost, shost->max_channel = 0; shost->max_cmd_len = 16; - iscsi_host_setup(shost, qdepth); - - if (scsi_add_host(shost, NULL)) + if (iscsi_host_add(shost, NULL)) goto free_host; *hostno = shost->host_no; @@ -443,10 +439,9 @@ iscsi_iser_session_create(struct Scsi_Host *shost, return cls_session; remove_host: - scsi_remove_host(shost); + iscsi_host_remove(shost); free_host: - iscsi_host_teardown(shost); - scsi_host_put(shost); + iscsi_host_free(shost); return NULL; } diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8cdcaf3..e19d92f2 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1866,7 +1866,7 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, return NULL; } - shost = scsi_host_alloc(&iscsi_sht, sizeof(struct iscsi_host)); + shost = iscsi_host_alloc(&iscsi_sht, 0, qdepth); if (!shost) return NULL; shost->transportt = iscsi_tcp_scsi_transport; @@ -1874,10 +1874,9 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, shost->max_id = 0; shost->max_channel = 0; shost->max_cmd_len = 16; + shost->can_queue = cmds_max; - iscsi_host_setup(shost, qdepth); - - if (scsi_add_host(shost, NULL)) + if (iscsi_host_add(shost, NULL)) goto free_host; *hostno = shost->host_no; @@ -1912,10 +1911,9 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, remove_session: iscsi_session_teardown(cls_session); remove_host: - scsi_remove_host(shost); + iscsi_host_remove(shost); free_host: - iscsi_host_teardown(shost); - scsi_host_put(shost); + iscsi_host_free(shost); return NULL; } @@ -1924,11 +1922,9 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); iscsi_r2tpool_free(cls_session->dd_data); - iscsi_session_teardown(cls_session); - scsi_remove_host(shost); - iscsi_host_teardown(shost); - scsi_host_put(shost); + iscsi_host_remove(shost); + iscsi_host_free(shost); } static int iscsi_tcp_slave_configure(struct scsi_device *sdev) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 64b1dd8..73c37c0 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1764,8 +1764,39 @@ void iscsi_pool_free(struct iscsi_pool *q) } EXPORT_SYMBOL_GPL(iscsi_pool_free); -void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth) +/** + * iscsi_host_add - add host to system + * @shost: scsi host + * @pdev: parent device + * + * This should be called by partial offload and software iscsi drivers + * to add a host to the system. + */ +int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev) +{ + return scsi_add_host(shost, pdev); +} +EXPORT_SYMBOL_GPL(iscsi_host_add); + +/** + * iscsi_host_alloc - allocate a host and driver data + * @sht: scsi host template + * @dd_data_size: driver host data size + * @qdepth: default device queue depth + * + * This should be called by partial offload and software iscsi drivers. + * To access the driver specific memory use the iscsi_host_priv() macro. + */ +struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, + int dd_data_size, uint16_t qdepth) { + struct Scsi_Host *shost; + + 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) printk(KERN_ERR "iscsi: invalid queue depth of %d. " @@ -1773,22 +1804,37 @@ void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth) qdepth, ISCSI_MAX_CMD_PER_LUN); qdepth = ISCSI_DEF_CMD_PER_LUN; } - - shost->transportt->create_work_queue = 1; - shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; shost->cmd_per_lun = qdepth; + return shost; +} +EXPORT_SYMBOL_GPL(iscsi_host_alloc); + +/** + * iscsi_host_remove - remove host and sessions + * @shost: scsi host + * + * This will also remove any sessions attached to the host, but if userspace + * is managing the session at the same time this will break. TODO: add + * refcounting to the netlink iscsi interface so a rmmod or host hot unplug + * does not remove the memory from under us. + */ +void iscsi_host_remove(struct Scsi_Host *shost) +{ + iscsi_host_for_each_session(shost, iscsi_session_teardown); + scsi_remove_host(shost); } -EXPORT_SYMBOL_GPL(iscsi_host_setup); +EXPORT_SYMBOL_GPL(iscsi_host_remove); -void iscsi_host_teardown(struct Scsi_Host *shost) +void iscsi_host_free(struct Scsi_Host *shost) { struct iscsi_host *ihost = shost_priv(shost); kfree(ihost->netdev); kfree(ihost->hwaddress); kfree(ihost->initiatorname); + scsi_host_put(shost); } -EXPORT_SYMBOL_GPL(iscsi_host_teardown); +EXPORT_SYMBOL_GPL(iscsi_host_free); /** * iscsi_session_setup - create iscsi cls session and host and session diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 9c00a15..6fdaa2e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -279,6 +279,24 @@ static int iscsi_is_session_dev(const struct device *dev) return dev->release == iscsi_session_release; } +static int iscsi_iter_session_fn(struct device *dev, void *data) +{ + void (* fn) (struct iscsi_cls_session *) = data; + + if (!iscsi_is_session_dev(dev)) + return 0; + fn(iscsi_dev_to_session(dev)); + return 0; +} + +void iscsi_host_for_each_session(struct Scsi_Host *shost, + void (*fn)(struct iscsi_cls_session *)) +{ + device_for_each_child(&shost->shost_gendev, fn, + iscsi_iter_session_fn); +} +EXPORT_SYMBOL_GPL(iscsi_host_for_each_session); + /** * iscsi_scan_finished - helper to report when running scans are done * @shost: scsi host @@ -1599,6 +1617,8 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->daemon_pid = -1; priv->iscsi_transport = tt; priv->t.user_scan = iscsi_user_scan; + if (!(tt->caps & CAP_DATA_PATH_OFFLOAD)) + priv->t.create_work_queue = 1; priv->dev.class = &iscsi_transport_class; snprintf(priv->dev.bus_id, BUS_ID_SIZE, "%s", tt->name); diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 8a6271c..9a26d71 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -32,6 +32,7 @@ #include struct scsi_transport_template; +struct scsi_host_template; struct scsi_device; struct Scsi_Host; struct scsi_cmnd; @@ -41,6 +42,7 @@ struct iscsi_cls_session; struct iscsi_cls_conn; struct iscsi_session; struct iscsi_nopin; +struct device; /* #define DEBUG_SCSI */ #ifdef DEBUG_SCSI @@ -311,6 +313,8 @@ struct iscsi_host { char local_address[ISCSI_ADDRESS_BUF_LEN]; }; +#define iscsi_host_priv(_shost) \ + (shost_priv(_shost) + sizeof(struct iscsi_host)) /* * scsi host template */ @@ -330,8 +334,11 @@ extern int iscsi_host_set_param(struct Scsi_Host *shost, int buflen); extern int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf); -extern void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth); -extern void iscsi_host_teardown(struct Scsi_Host *shost); +extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); +extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, + int dd_data_size, uint16_t qdepth); +extern void iscsi_host_remove(struct Scsi_Host *shost); +extern void iscsi_host_free(struct Scsi_Host *shost); /* * session management diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 702eda2..761f62d 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -207,6 +207,10 @@ struct iscsi_cls_host { char scan_workq_name[KOBJ_NAME_LEN]; }; +extern void iscsi_host_for_each_session(struct Scsi_Host *shost, + void (*fn)(struct iscsi_cls_session *)); + + /* * session and connection functions that can be used by HW iSCSI LLDs */ -- cgit v0.10.2 From 5d91e209fb21fb9cc765729d4c6a85a9fb6c9187 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:01 -0500 Subject: [SCSI] iscsi: remove session/conn_data_size from iscsi_transport This removes the session and conn data_size fields from the iscsi_transport. Just pass in the value like with host allocation. This patch also makes it so the LLD iscsi_conn data is allocated with the iscsi_cls_conn. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 62e35e5..9b34946 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -279,7 +279,7 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) struct iscsi_cls_conn *cls_conn; struct iscsi_iser_conn *iser_conn; - cls_conn = iscsi_conn_setup(cls_session, conn_idx); + cls_conn = iscsi_conn_setup(cls_session, sizeof(*iser_conn), conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; @@ -290,10 +290,7 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) */ conn->max_recv_dlength = 128; - iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL); - if (!iser_conn) - goto conn_alloc_fail; - + iser_conn = conn->dd_data; /* currently this is the only field which need to be initiated */ rwlock_init(&iser_conn->lock); @@ -301,10 +298,6 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) iser_conn->iscsi_conn = conn; return cls_conn; - -conn_alloc_fail: - iscsi_conn_teardown(cls_conn); - return NULL; } static void @@ -313,10 +306,9 @@ iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn) struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_iser_conn *iser_conn = conn->dd_data; - iscsi_conn_teardown(cls_conn); if (iser_conn->ib_conn) iser_conn->ib_conn->iser_conn = NULL; - kfree(iser_conn); + iscsi_conn_teardown(cls_conn); } static int @@ -619,8 +611,6 @@ static struct iscsi_transport iscsi_iser_transport = { .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME | ISCSI_HOST_INITIATOR_NAME, - .conndata_size = sizeof(struct iscsi_conn), - .sessiondata_size = sizeof(struct iscsi_session), /* session management */ .create_session = iscsi_iser_session_create, .destroy_session = iscsi_iser_session_destroy, diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index e19d92f2..dfaf9fa 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1490,7 +1490,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) struct iscsi_cls_conn *cls_conn; struct iscsi_tcp_conn *tcp_conn; - cls_conn = iscsi_conn_setup(cls_session, conn_idx); + cls_conn = iscsi_conn_setup(cls_session, sizeof(*tcp_conn), conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; @@ -1500,18 +1500,14 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) */ conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; - tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL); - if (!tcp_conn) - goto tcp_conn_alloc_fail; - - conn->dd_data = tcp_conn; + tcp_conn = conn->dd_data; tcp_conn->iscsi_conn = conn; tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->tx_hash.flags = 0; if (IS_ERR(tcp_conn->tx_hash.tfm)) - goto free_tcp_conn; + goto free_conn; tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); @@ -1523,14 +1519,12 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) free_tx_tfm: crypto_free_hash(tcp_conn->tx_hash.tfm); -free_tcp_conn: +free_conn: iscsi_conn_printk(KERN_ERR, conn, "Could not create connection due to crc32c " "loading error. Make sure the crc32c " "module is built as a module or into the " "kernel\n"); - kfree(tcp_conn); -tcp_conn_alloc_fail: iscsi_conn_teardown(cls_conn); return NULL; } @@ -1563,14 +1557,13 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) struct iscsi_tcp_conn *tcp_conn = conn->dd_data; iscsi_tcp_release_conn(conn); - iscsi_conn_teardown(cls_conn); if (tcp_conn->tx_hash.tfm) crypto_free_hash(tcp_conn->tx_hash.tfm); if (tcp_conn->rx_hash.tfm) crypto_free_hash(tcp_conn->rx_hash.tfm); - kfree(tcp_conn); + iscsi_conn_teardown(cls_conn); } static void @@ -1983,8 +1976,6 @@ static struct iscsi_transport iscsi_tcp_transport = { .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | ISCSI_HOST_INITIATOR_NAME | ISCSI_HOST_NETDEV_NAME, - .conndata_size = sizeof(struct iscsi_conn), - .sessiondata_size = sizeof(struct iscsi_session), /* session management */ .create_session = iscsi_tcp_session_create, .destroy_session = iscsi_tcp_session_destroy, diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 73c37c0..784a935 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1867,7 +1867,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; } - cls_session = iscsi_alloc_session(shost, iscsit); + cls_session = iscsi_alloc_session(shost, iscsit, + sizeof(struct iscsi_session)); if (!cls_session) return NULL; session = cls_session->dd_data; @@ -1968,22 +1969,26 @@ EXPORT_SYMBOL_GPL(iscsi_session_teardown); /** * iscsi_conn_setup - create iscsi_cls_conn and iscsi_conn * @cls_session: iscsi_cls_session + * @dd_size: private driver data size * @conn_idx: cid - **/ + */ struct iscsi_cls_conn * -iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) +iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, + uint32_t conn_idx) { struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn; struct iscsi_cls_conn *cls_conn; char *data; - cls_conn = iscsi_create_conn(cls_session, conn_idx); + cls_conn = iscsi_create_conn(cls_session, sizeof(*conn) + dd_size, + conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; - memset(conn, 0, sizeof(*conn)); + memset(conn, 0, sizeof(*conn) + dd_size); + conn->dd_data = cls_conn->dd_data + sizeof(*conn); conn->session = session; conn->cls_conn = cls_conn; conn->c_stage = ISCSI_CONN_INITIAL_STAGE; diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 6c6ee0f..5822dd5 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -113,8 +113,6 @@ static struct iscsi_transport qla4xxx_iscsi_transport = { .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | ISCSI_HOST_INITIATOR_NAME, - .sessiondata_size = sizeof(struct ddb_entry), - .tgt_dscvr = qla4xxx_tgt_dscvr, .get_conn_param = qla4xxx_conn_get_param, .get_session_param = qla4xxx_sess_get_param, @@ -274,7 +272,7 @@ int qla4xxx_add_sess(struct ddb_entry *ddb_entry) return err; } - ddb_entry->conn = iscsi_create_conn(ddb_entry->sess, 0); + ddb_entry->conn = iscsi_create_conn(ddb_entry->sess, 0, 0); if (!ddb_entry->conn) { iscsi_remove_session(ddb_entry->sess); DEBUG2(printk(KERN_ERR "Could not add connection.\n")); @@ -291,7 +289,8 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha) struct ddb_entry *ddb_entry; struct iscsi_cls_session *sess; - sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport); + sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport, + sizeof(struct ddb_entry)); if (!sess) return NULL; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 6fdaa2e..6b8516a 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -483,12 +483,12 @@ static int iscsi_unbind_session(struct iscsi_cls_session *session) } struct iscsi_cls_session * -iscsi_alloc_session(struct Scsi_Host *shost, - struct iscsi_transport *transport) +iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, + int dd_size) { struct iscsi_cls_session *session; - session = kzalloc(sizeof(*session) + transport->sessiondata_size, + session = kzalloc(sizeof(*session) + dd_size, GFP_KERNEL); if (!session) return NULL; @@ -510,7 +510,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, session->dev.parent = &shost->shost_gendev; session->dev.release = iscsi_session_release; device_initialize(&session->dev); - if (transport->sessiondata_size) + if (dd_size) session->dd_data = &session[1]; return session; } @@ -558,18 +558,18 @@ EXPORT_SYMBOL_GPL(iscsi_add_session); * iscsi_create_session - create iscsi class session * @shost: scsi host * @transport: iscsi transport + * @dd_size: private driver data size * @target_id: which target * * This can be called from a LLD or iscsi_transport. */ struct iscsi_cls_session * -iscsi_create_session(struct Scsi_Host *shost, - struct iscsi_transport *transport, - unsigned int target_id) +iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport, + int dd_size, unsigned int target_id) { struct iscsi_cls_session *session; - session = iscsi_alloc_session(shost, transport); + session = iscsi_alloc_session(shost, transport, dd_size); if (!session) return NULL; @@ -671,6 +671,7 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_session); /** * iscsi_create_conn - create iscsi class connection * @session: iscsi cls session + * @dd_size: private driver data size * @cid: connection id * * This can be called from a LLD or iscsi_transport. The connection @@ -683,18 +684,17 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_session); * non-zero. */ struct iscsi_cls_conn * -iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) +iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid) { struct iscsi_transport *transport = session->transport; struct iscsi_cls_conn *conn; unsigned long flags; int err; - conn = kzalloc(sizeof(*conn) + transport->conndata_size, GFP_KERNEL); + conn = kzalloc(sizeof(*conn) + dd_size, GFP_KERNEL); if (!conn) return NULL; - - if (transport->conndata_size) + if (dd_size) conn->dd_data = &conn[1]; INIT_LIST_HEAD(&conn->conn_list); diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 9a26d71..4e1c14f 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -313,8 +313,6 @@ struct iscsi_host { char local_address[ISCSI_ADDRESS_BUF_LEN]; }; -#define iscsi_host_priv(_shost) \ - (shost_priv(_shost) + sizeof(struct iscsi_host)) /* * scsi host template */ @@ -325,10 +323,12 @@ extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); extern int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)); - /* * iSCSI host helpers. */ +#define iscsi_host_priv(_shost) \ + (shost_priv(_shost) + sizeof(struct iscsi_host)) + extern int iscsi_host_set_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf, int buflen); @@ -360,7 +360,7 @@ extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, * connection management */ extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *, - uint32_t); + int, uint32_t); extern void iscsi_conn_teardown(struct iscsi_cls_conn *); extern int iscsi_conn_start(struct iscsi_cls_conn *); extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 761f62d..4028f12 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -83,10 +83,6 @@ struct iscsi_transport { /* LLD sets this to indicate what values it can export to sysfs */ uint64_t param_mask; uint64_t host_param_mask; - /* LLD connection data size */ - int conndata_size; - /* LLD session data size */ - int sessiondata_size; struct iscsi_cls_session *(*create_session) (struct Scsi_Host *shost, uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn); @@ -222,19 +218,20 @@ extern void iscsi_host_for_each_session(struct Scsi_Host *shost, extern int iscsi_session_chkready(struct iscsi_cls_session *session); extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, - struct iscsi_transport *transport); + struct iscsi_transport *transport, int dd_size); extern int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id); extern int iscsi_session_event(struct iscsi_cls_session *session, enum iscsi_uevent_e event); extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *t, + int dd_size, unsigned int target_id); extern void iscsi_remove_session(struct iscsi_cls_session *session); extern void iscsi_free_session(struct iscsi_cls_session *session); extern int iscsi_destroy_session(struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, - uint32_t cid); + int dd_size, uint32_t cid); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); extern void iscsi_unblock_session(struct iscsi_cls_session *session); extern void iscsi_block_session(struct iscsi_cls_session *session); -- cgit v0.10.2 From 5af3e91d232b7e022f258202f72ebb79b8b0c706 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:02 -0500 Subject: [SCSI] iscsi: modify iscsi printk so it can take driver data pointers Some drivers want to be able to just pass in the driver data pointers to the iscsi objects. To enable this we need the iscsi printk macro to cast the object. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 4e1c14f..f54aeb1 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -369,9 +369,11 @@ extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf); +extern void iscsi_suspend_tx(struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ - iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a) + iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ + fmt, ##a) /* * pdu and task processing -- cgit v0.10.2 From b40977d95fb3a1898ace6a7d97e4ed1a33a440a4 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:03 -0500 Subject: [SCSI] iser: fix handling of scsi cmnds during recovery. After the stop_conn callback has returned the LLD should not touch the scsi cmds. iscsi_tcp and libiscsi use the conn->recv_lock and suspend_rx field to halt recv path processing, but iser does not have any protection. This patch modifies iser so that userspace can just call the ep_disconnect callback, which will halt all recv IO, before calling the stop_conn callback so we do not have to worry about the conn->recv_lock and suspend rx field. iser just needs to stop the send side from accessing the ib conn. Fixup to handle when the ep poll fails and ep disconnect is called from Erez. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 9b34946..8a1bfb7 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -305,10 +305,18 @@ iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn) { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_iser_conn *iser_conn = conn->dd_data; + struct iser_conn *ib_conn = iser_conn->ib_conn; - if (iser_conn->ib_conn) - iser_conn->ib_conn->iser_conn = NULL; iscsi_conn_teardown(cls_conn); + /* + * Userspace will normally call the stop callback and + * already have freed the ib_conn, but if it goofed up then + * we free it here. + */ + if (ib_conn) { + ib_conn->iser_conn = NULL; + iser_conn_put(ib_conn); + } } static int @@ -340,12 +348,29 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, iser_conn = conn->dd_data; ib_conn->iser_conn = iser_conn; iser_conn->ib_conn = ib_conn; + iser_conn_get(ib_conn); conn->recv_lock = &iser_conn->lock; return 0; } +static void +iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) +{ + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_iser_conn *iser_conn = conn->dd_data; + struct iser_conn *ib_conn = iser_conn->ib_conn; + + iscsi_conn_stop(cls_conn, flag); + /* + * There is no unbind event so the stop callback + * must release the ref from the bind. + */ + iser_conn_put(ib_conn); + iser_conn->ib_conn = NULL; +} + static int iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) { @@ -564,6 +589,17 @@ iscsi_iser_ep_disconnect(__u64 ep_handle) if (!ib_conn) return; + if (ib_conn->iser_conn) + /* + * Must suspend xmit path if the ep is bound to the + * iscsi_conn, so we know we are not accessing the ib_conn + * when we free it. + * + * This may not be bound if the ep poll failed. + */ + iscsi_suspend_tx(ib_conn->iser_conn->iscsi_conn); + + iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state); iser_conn_terminate(ib_conn); } @@ -622,7 +658,7 @@ static struct iscsi_transport iscsi_iser_transport = { .get_conn_param = iscsi_conn_get_param, .get_session_param = iscsi_session_get_param, .start_conn = iscsi_iser_conn_start, - .stop_conn = iscsi_conn_stop, + .stop_conn = iscsi_iser_conn_stop, /* iscsi host params */ .get_host_param = iscsi_host_get_param, .set_host_param = iscsi_host_set_param, diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 66a2f30..bd5c1a5 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -242,6 +242,7 @@ struct iser_device { struct iser_conn { struct iscsi_iser_conn *iser_conn; /* iser conn for upcalls */ enum iser_ib_conn_state state; /* rdma connection state */ + atomic_t refcount; spinlock_t lock; /* used for state changes */ struct iser_device *device; /* device context */ struct rdma_cm_id *cma_id; /* CMA ID */ @@ -314,6 +315,10 @@ void iscsi_iser_recv(struct iscsi_conn *conn, int iser_conn_init(struct iser_conn **ib_conn); +void iser_conn_get(struct iser_conn *ib_conn); + +void iser_conn_put(struct iser_conn *ib_conn); + void iser_conn_terminate(struct iser_conn *ib_conn); void iser_rcv_completion(struct iser_desc *desc, diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index d19cfe6..5daed2b 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -328,6 +328,17 @@ static void iser_conn_release(struct iser_conn *ib_conn) kfree(ib_conn); } +void iser_conn_get(struct iser_conn *ib_conn) +{ + atomic_inc(&ib_conn->refcount); +} + +void iser_conn_put(struct iser_conn *ib_conn) +{ + if (atomic_dec_and_test(&ib_conn->refcount)) + iser_conn_release(ib_conn); +} + /** * triggers start of the disconnect procedures and wait for them to be done */ @@ -349,7 +360,7 @@ void iser_conn_terminate(struct iser_conn *ib_conn) wait_event_interruptible(ib_conn->wait, ib_conn->state == ISER_CONN_DOWN); - iser_conn_release(ib_conn); + iser_conn_put(ib_conn); } static void iser_connect_error(struct rdma_cm_id *cma_id) @@ -496,6 +507,7 @@ int iser_conn_init(struct iser_conn **ibconn) init_waitqueue_head(&ib_conn->wait); atomic_set(&ib_conn->post_recv_buf_count, 0); atomic_set(&ib_conn->post_send_buf_count, 0); + atomic_set(&ib_conn->refcount, 1); INIT_LIST_HEAD(&ib_conn->conn_list); spin_lock_init(&ib_conn->lock); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 784a935..79bc49f 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1383,11 +1383,12 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun, } } -static void iscsi_suspend_tx(struct iscsi_conn *conn) +void iscsi_suspend_tx(struct iscsi_conn *conn) { set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); scsi_flush_work(conn->session->host); } +EXPORT_SYMBOL_GPL(iscsi_suspend_tx); static void iscsi_start_tx(struct iscsi_conn *conn) { -- cgit v0.10.2 From 0af967f5d4f2dd1e00618d34ac988037d37a6c3b Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:04 -0500 Subject: [SCSI] libiscsi, iscsi_tcp, iser: add session cmds array accessor Currently to get a ctask from the session cmd array, you have to know to use the itt modifier. To make this easier on LLDs and so in the future we can easilly kill the session array and use the host shared map instead, this patch adds a nice wrapper to strip the itt into a session->cmds index and return a ctask. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 8a1bfb7..7b14688 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -98,7 +98,6 @@ iscsi_iser_recv(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *rx_data, int rx_data_len) { int rc = 0; - uint32_t ret_itt; int datalen; int ahslen; @@ -114,12 +113,7 @@ iscsi_iser_recv(struct iscsi_conn *conn, /* read AHS */ ahslen = hdr->hlength * 4; - /* verify itt (itt encoding: age+cid+itt) */ - rc = iscsi_verify_itt(conn, hdr, &ret_itt); - - if (!rc) - rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len); - + rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len); if (rc && rc != ISCSI_ERR_NO_SCSI_CMD) goto error; diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 08dc81c..b82a5f2 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -537,13 +537,11 @@ void iser_rcv_completion(struct iser_desc *rx_desc, { struct iser_dto *dto = &rx_desc->dto; struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn; - struct iscsi_session *session = conn->iscsi_conn->session; struct iscsi_cmd_task *ctask; struct iscsi_iser_cmd_task *iser_ctask; struct iscsi_hdr *hdr; char *rx_data = NULL; int rx_data_len = 0; - unsigned int itt; unsigned char opcode; hdr = &rx_desc->iscsi_header; @@ -559,19 +557,18 @@ void iser_rcv_completion(struct iser_desc *rx_desc, opcode = hdr->opcode & ISCSI_OPCODE_MASK; if (opcode == ISCSI_OP_SCSI_CMD_RSP) { - itt = get_itt(hdr->itt); /* mask out cid and age bits */ - if (!(itt < session->cmds_max)) + ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt); + if (!ctask) iser_err("itt can't be matched to task!!! " - "conn %p opcode %d cmds_max %d itt %d\n", - conn->iscsi_conn,opcode,session->cmds_max,itt); - /* use the mapping given with the cmds array indexed by itt */ - ctask = (struct iscsi_cmd_task *)session->cmds[itt]; - iser_ctask = ctask->dd_data; - iser_dbg("itt %d ctask %p\n",itt,ctask); - iser_ctask->status = ISER_TASK_STATUS_COMPLETED; - iser_ctask_rdma_finalize(iser_ctask); + "conn %p opcode %d itt %d\n", + conn->iscsi_conn, opcode, hdr->itt); + else { + iser_ctask = ctask->dd_data; + iser_dbg("itt %d ctask %p\n",hdr->itt, ctask); + iser_ctask->status = ISER_TASK_STATUS_COMPLETED; + iser_ctask_rdma_finalize(iser_ctask); + } } - iser_dto_buffs_release(dto); iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len); diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index dfaf9fa..f2a08f7 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) struct iscsi_session *session = conn->session; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_cmd_task *ctask; - uint32_t itt; /* verify PDU length */ tcp_conn->in.datalen = ntoh24(hdr->dlength); @@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) opcode = hdr->opcode & ISCSI_OPCODE_MASK; /* verify itt (itt encoding: age+cid+itt) */ - rc = iscsi_verify_itt(conn, hdr, &itt); + rc = iscsi_verify_itt(conn, hdr->itt); if (rc) return rc; @@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) switch(opcode) { case ISCSI_OP_SCSI_DATA_IN: - ctask = session->cmds[itt]; + ctask = iscsi_itt_to_ctask(conn, hdr->itt); + if (!ctask) + return ISCSI_ERR_BAD_ITT; + spin_lock(&conn->session->lock); rc = iscsi_data_rsp(conn, ctask); spin_unlock(&conn->session->lock); @@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) rc = iscsi_complete_pdu(conn, hdr, NULL, 0); break; case ISCSI_OP_R2T: - ctask = session->cmds[itt]; + ctask = iscsi_itt_to_ctask(conn, hdr->itt); + if (!ctask) + return ISCSI_ERR_BAD_ITT; + if (ahslen) rc = ISCSI_ERR_AHSLEN; else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 79bc49f..4bc63c4 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, uint32_t itt; conn->last_recv = jiffies; + rc = iscsi_verify_itt(conn, hdr->itt); + if (rc) + return rc; + if (hdr->itt != RESERVED_ITT) itt = get_itt(hdr->itt); else @@ -776,27 +780,22 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } EXPORT_SYMBOL_GPL(iscsi_complete_pdu); -/* verify itt (itt encoding: age+cid+itt) */ -int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - uint32_t *ret_itt) +int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) { struct iscsi_session *session = conn->session; struct iscsi_cmd_task *ctask; - uint32_t itt; - if (hdr->itt != RESERVED_ITT) { - if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != - (session->age << ISCSI_AGE_SHIFT)) { - iscsi_conn_printk(KERN_ERR, conn, - "received itt %x expected session " - "age (%x)\n", (__force u32)hdr->itt, - session->age & ISCSI_AGE_MASK); - return ISCSI_ERR_BAD_ITT; - } + if (itt == RESERVED_ITT) + return 0; - itt = get_itt(hdr->itt); - } else - itt = ~0U; + if (((__force u32)itt & ISCSI_AGE_MASK) != + (session->age << ISCSI_AGE_SHIFT)) { + iscsi_conn_printk(KERN_ERR, conn, + "received itt %x expected session age (%x)\n", + (__force u32)itt, + session->age & ISCSI_AGE_MASK); + return ISCSI_ERR_BAD_ITT; + } if (itt < session->cmds_max) { ctask = session->cmds[itt]; @@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } } - *ret_itt = itt; return 0; } EXPORT_SYMBOL_GPL(iscsi_verify_itt); +struct iscsi_cmd_task * +iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) +{ + struct iscsi_session *session = conn->session; + struct iscsi_cmd_task *ctask; + uint32_t i; + + if (iscsi_verify_itt(conn, itt)) + return NULL; + + if (itt == RESERVED_ITT) + return NULL; + + i = get_itt(itt); + if (i >= session->cmds_max) + return NULL; + + ctask = session->cmds[i]; + if (!ctask->sc) + return NULL; + + if (ctask->sc->SCp.phase != session->age) + return NULL; + + return ctask; +} +EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); + void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) { struct iscsi_session *session = conn->session; diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index f54aeb1..9be6a70 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -385,8 +385,8 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, char *, int); -extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, - uint32_t *); +extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); +extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask); -- cgit v0.10.2 From 052d014485d2ce5bb7fa8dd0df875dafd1db77df Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:05 -0500 Subject: [SCSI] libiscsi: modify libiscsi so it supports offloaded data paths This patch modifies libiscsi, so drivers like bnx2i and iser can execute a command from queuecommand/send_pdu instead of having to be queued to be run in a workq. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4bc63c4..1e605de 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -79,9 +79,11 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) * xmit thread */ if (!list_empty(&session->leadconn->xmitqueue) || - !list_empty(&session->leadconn->mgmtqueue)) - scsi_queue_work(session->host, - &session->leadconn->xmitwork); + !list_empty(&session->leadconn->mgmtqueue)) { + if (!(session->tt->caps & CAP_DATA_PATH_OFFLOAD)) + scsi_queue_work(session->host, + &session->leadconn->xmitwork); + } } } EXPORT_SYMBOL_GPL(iscsi_update_cmdsn); @@ -298,8 +300,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) WARN_ON(hdrlength >= 256); hdr->hlength = hdrlength & 0xFF; - if (conn->session->tt->init_cmd_task(conn->ctask)) - return EIO; + if (conn->session->tt->init_cmd_task && + conn->session->tt->init_cmd_task(ctask)) + return -EIO; + + ctask->state = ISCSI_TASK_RUNNING; + list_move_tail(&ctask->running, &conn->run_list); conn->scsicmd_pdus_cnt++; debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x " @@ -334,7 +340,9 @@ static void iscsi_complete_command(struct iscsi_cmd_task *ctask) conn->ctask = NULL; list_del_init(&ctask->running); __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); - sc->scsi_done(sc); + + if (sc->scsi_done) + sc->scsi_done(sc); } static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask) @@ -403,6 +411,50 @@ void iscsi_free_mgmt_task(struct iscsi_conn *conn, } EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task); +static int iscsi_prep_mtask(struct iscsi_conn *conn, + struct iscsi_mgmt_task *mtask) +{ + struct iscsi_session *session = conn->session; + struct iscsi_hdr *hdr = mtask->hdr; + struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; + + if (conn->session->state == ISCSI_STATE_LOGGING_OUT) + return -ENOTCONN; + + if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) && + hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) + nop->exp_statsn = cpu_to_be32(conn->exp_statsn); + /* + * pre-format CmdSN for outgoing PDU. + */ + nop->cmdsn = cpu_to_be32(session->cmdsn); + if (hdr->itt != RESERVED_ITT) { + hdr->itt = build_itt(mtask->itt, session->age); + /* + * TODO: We always use immediate, so we never hit this. + * If we start to send tmfs or nops as non-immediate then + * we should start checking the cmdsn numbers for mgmt tasks. + */ + if (conn->c_stage == ISCSI_CONN_STARTED && + !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { + session->queued_cmdsn++; + session->cmdsn++; + } + } + + if (session->tt->init_mgmt_task) + session->tt->init_mgmt_task(conn, mtask); + + if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) + session->state = ISCSI_STATE_LOGGING_OUT; + + list_move_tail(&mtask->running, &conn->mgmt_run_list); + debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", + hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, + mtask->data_count); + return 0; +} + static struct iscsi_mgmt_task * __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size) @@ -429,6 +481,12 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (!__kfifo_get(session->mgmtpool.queue, (void*)&mtask, sizeof(void*))) return NULL; + + if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) && + hdr->ttt == RESERVED_ITT) { + conn->ping_mtask = mtask; + conn->last_ping = jiffies; + } } if (data_size) { @@ -440,6 +498,19 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); INIT_LIST_HEAD(&mtask->running); list_add_tail(&mtask->running, &conn->mgmtqueue); + + if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { + if (iscsi_prep_mtask(conn, mtask)) { + iscsi_free_mgmt_task(conn, mtask); + return NULL; + } + + if (session->tt->xmit_mgmt_task(conn, mtask)) + mtask = NULL; + + } else + scsi_queue_work(conn->session->host, &conn->xmitwork); + return mtask; } @@ -454,7 +525,6 @@ int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size)) err = -EPERM; spin_unlock_bh(&session->lock); - scsi_queue_work(session->host, &conn->xmitwork); return err; } EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); @@ -581,17 +651,8 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) hdr.ttt = RESERVED_ITT; mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); - if (!mtask) { + if (!mtask) iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); - return; - } - - /* only track our nops */ - if (!rhdr) { - conn->ping_mtask = mtask; - conn->last_ping = jiffies; - } - scsi_queue_work(conn->session->host, &conn->xmitwork); } static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, @@ -868,56 +929,15 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); -static void iscsi_prep_mtask(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) -{ - struct iscsi_session *session = conn->session; - struct iscsi_hdr *hdr = mtask->hdr; - struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; - - if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) && - hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) - nop->exp_statsn = cpu_to_be32(conn->exp_statsn); - /* - * pre-format CmdSN for outgoing PDU. - */ - nop->cmdsn = cpu_to_be32(session->cmdsn); - if (hdr->itt != RESERVED_ITT) { - hdr->itt = build_itt(mtask->itt, session->age); - /* - * TODO: We always use immediate, so we never hit this. - * If we start to send tmfs or nops as non-immediate then - * we should start checking the cmdsn numbers for mgmt tasks. - */ - if (conn->c_stage == ISCSI_CONN_STARTED && - !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { - session->queued_cmdsn++; - session->cmdsn++; - } - } - - if (session->tt->init_mgmt_task) - session->tt->init_mgmt_task(conn, mtask); - - debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", - hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, - mtask->data_count); -} - static int iscsi_xmit_mtask(struct iscsi_conn *conn) { - struct iscsi_hdr *hdr = conn->mtask->hdr; int rc; - if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) - conn->session->state = ISCSI_STATE_LOGGING_OUT; spin_unlock_bh(&conn->session->lock); - rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); spin_lock_bh(&conn->session->lock); if (rc) return rc; - /* done with this in-progress mtask */ conn->mtask = NULL; return 0; @@ -961,7 +981,8 @@ static int iscsi_xmit_ctask(struct iscsi_conn *conn) * @ctask: ctask to requeue * * LLDs that need to run a ctask from the session workqueue should call - * this. The session lock must be held. + * this. The session lock must be held. This should only be called + * by software drivers. */ void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask) { @@ -1013,14 +1034,11 @@ check_mgmt: while (!list_empty(&conn->mgmtqueue)) { conn->mtask = list_entry(conn->mgmtqueue.next, struct iscsi_mgmt_task, running); - if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { + if (iscsi_prep_mtask(conn, conn->mtask)) { iscsi_free_mgmt_task(conn, conn->mtask); conn->mtask = NULL; continue; } - - iscsi_prep_mtask(conn, conn->mtask); - list_move_tail(conn->mgmtqueue.next, &conn->mgmt_run_list); rc = iscsi_xmit_mtask(conn); if (rc) goto again; @@ -1041,9 +1059,6 @@ check_mgmt: fail_command(conn, conn->ctask, DID_ABORT << 16); continue; } - - conn->ctask->state = ISCSI_TASK_RUNNING; - list_move_tail(conn->xmitqueue.next, &conn->run_list); rc = iscsi_xmit_ctask(conn); if (rc) goto again; @@ -1192,8 +1207,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) reason = FAILURE_OOM; goto reject; } - session->queued_cmdsn++; - sc->SCp.phase = session->age; sc->SCp.ptr = (char *)ctask; @@ -1202,11 +1215,26 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ctask->conn = conn; ctask->sc = sc; INIT_LIST_HEAD(&ctask->running); - list_add_tail(&ctask->running, &conn->xmitqueue); - spin_unlock(&session->lock); - scsi_queue_work(host, &conn->xmitwork); + if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { + if (iscsi_prep_scsi_cmd_pdu(ctask)) { + sc->result = DID_ABORT << 16; + sc->scsi_done = NULL; + iscsi_complete_command(ctask); + goto fault; + } + if (session->tt->xmit_cmd_task(conn, ctask)) { + sc->scsi_done = NULL; + iscsi_complete_command(ctask); + reason = FAILURE_SESSION_NOT_READY; + goto reject; + } + } else + scsi_queue_work(session->host, &conn->xmitwork); + + session->queued_cmdsn++; + spin_unlock(&session->lock); spin_lock(host->host_lock); return 0; @@ -1225,7 +1253,7 @@ fault: scsi_out(sc)->resid = scsi_out(sc)->length; scsi_in(sc)->resid = scsi_in(sc)->length; } - sc->scsi_done(sc); + done(sc); spin_lock(host->host_lock); return 0; } @@ -1344,7 +1372,6 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); - scsi_queue_work(session->host, &conn->xmitwork); /* * block eh thread until: @@ -1412,14 +1439,16 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun, void iscsi_suspend_tx(struct iscsi_conn *conn) { set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - scsi_flush_work(conn->session->host); + if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD)) + scsi_flush_work(conn->session->host); } EXPORT_SYMBOL_GPL(iscsi_suspend_tx); static void iscsi_start_tx(struct iscsi_conn *conn) { clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); - scsi_queue_work(conn->session->host, &conn->xmitwork); + if (!(conn->session->tt->caps & CAP_DATA_PATH_OFFLOAD)) + scsi_queue_work(conn->session->host, &conn->xmitwork); } static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) -- cgit v0.10.2 From 3e5c28ad0391389959ccae81c938c7533efb3490 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:06 -0500 Subject: [SCSI] libiscsi: merge iscsi_mgmt_task and iscsi_cmd_task There is no need to have the mgmt and cmd tasks separate structs. It used to save a lot of memory when we overprealocated memory for tasks, but the next patches will set up the driver so in the future they can use a mempool or some other common scsi command allocator and common tagging. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 1e605de..ef92b1b 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -197,7 +197,7 @@ static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask) /** * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu - * @ctask: iscsi cmd task + * @ctask: iscsi task * * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set * fields like dlength or final based on how much data it sends @@ -300,31 +300,31 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) WARN_ON(hdrlength >= 256); hdr->hlength = hdrlength & 0xFF; - if (conn->session->tt->init_cmd_task && - conn->session->tt->init_cmd_task(ctask)) + if (conn->session->tt->init_task && + conn->session->tt->init_task(ctask)) return -EIO; ctask->state = ISCSI_TASK_RUNNING; list_move_tail(&ctask->running, &conn->run_list); conn->scsicmd_pdus_cnt++; - debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x " - "len %d bidi_len %d cmdsn %d win %d]\n", - scsi_bidi_cmnd(sc) ? "bidirectional" : - sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", - conn->id, sc, sc->cmnd[0], ctask->itt, - scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, - session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); + debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " + "bidi_len %d cmdsn %d win %d]\n", scsi_bidi_cmnd(sc) ? + "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ? + "write" : "read", conn->id, sc, sc->cmnd[0], ctask->itt, + scsi_bufflen(sc), + scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, + session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); return 0; } /** - * iscsi_complete_command - return command back to scsi-ml + * iscsi_complete_command - finish a task * @ctask: iscsi cmd task * * Must be called with session lock. - * This function returns the scsi command to scsi-ml and returns - * the cmd task to the pool of available cmd tasks. + * This function returns the scsi command to scsi-ml or cleans + * up mgmt tasks then returns the task to the pool. */ static void iscsi_complete_command(struct iscsi_cmd_task *ctask) { @@ -332,17 +332,34 @@ static void iscsi_complete_command(struct iscsi_cmd_task *ctask) struct iscsi_session *session = conn->session; struct scsi_cmnd *sc = ctask->sc; + list_del_init(&ctask->running); ctask->state = ISCSI_TASK_COMPLETED; ctask->sc = NULL; - /* SCSI eh reuses commands to verify us */ - sc->SCp.ptr = NULL; + if (conn->ctask == ctask) conn->ctask = NULL; - list_del_init(&ctask->running); + /* + * login ctask is preallocated so do not free + */ + if (conn->login_ctask == ctask) + return; + __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); - if (sc->scsi_done) - sc->scsi_done(sc); + if (conn->ping_ctask == ctask) + conn->ping_ctask = NULL; + + if (sc) { + ctask->sc = NULL; + /* SCSI eh reuses commands to verify us */ + sc->SCp.ptr = NULL; + /* + * queue command may call this to free the task, but + * not have setup the sc callback + */ + if (sc->scsi_done) + sc->scsi_done(sc); + } } static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask) @@ -356,6 +373,16 @@ static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask) iscsi_complete_command(ctask); } +void iscsi_put_ctask(struct iscsi_cmd_task *ctask) +{ + struct iscsi_session *session = ctask->conn->session; + + spin_lock_bh(&session->lock); + __iscsi_put_ctask(ctask); + spin_unlock_bh(&session->lock); +} +EXPORT_SYMBOL_GPL(iscsi_put_ctask); + /* * session lock must be held */ @@ -375,47 +402,28 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, */ conn->session->queued_cmdsn--; else - conn->session->tt->cleanup_cmd_task(conn, ctask); + conn->session->tt->cleanup_task(conn, ctask); sc->result = err; + if (!scsi_bidi_cmnd(sc)) scsi_set_resid(sc, scsi_bufflen(sc)); else { scsi_out(sc)->resid = scsi_out(sc)->length; scsi_in(sc)->resid = scsi_in(sc)->length; } + if (conn->ctask == ctask) conn->ctask = NULL; /* release ref from queuecommand */ __iscsi_put_ctask(ctask); } -/** - * iscsi_free_mgmt_task - return mgmt task back to pool - * @conn: iscsi connection - * @mtask: mtask - * - * Must be called with session lock. - */ -void iscsi_free_mgmt_task(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) -{ - list_del_init(&mtask->running); - if (conn->login_mtask == mtask) - return; - - if (conn->ping_mtask == mtask) - conn->ping_mtask = NULL; - __kfifo_put(conn->session->mgmtpool.queue, - (void*)&mtask, sizeof(void*)); -} -EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task); - -static int iscsi_prep_mtask(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) +static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, + struct iscsi_cmd_task *ctask) { struct iscsi_session *session = conn->session; - struct iscsi_hdr *hdr = mtask->hdr; + struct iscsi_hdr *hdr = (struct iscsi_hdr *)ctask->hdr; struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; if (conn->session->state == ISCSI_STATE_LOGGING_OUT) @@ -429,7 +437,7 @@ static int iscsi_prep_mtask(struct iscsi_conn *conn, */ nop->cmdsn = cpu_to_be32(session->cmdsn); if (hdr->itt != RESERVED_ITT) { - hdr->itt = build_itt(mtask->itt, session->age); + hdr->itt = build_itt(ctask->itt, session->age); /* * TODO: We always use immediate, so we never hit this. * If we start to send tmfs or nops as non-immediate then @@ -442,25 +450,25 @@ static int iscsi_prep_mtask(struct iscsi_conn *conn, } } - if (session->tt->init_mgmt_task) - session->tt->init_mgmt_task(conn, mtask); + if (session->tt->init_task) + session->tt->init_task(ctask); if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) session->state = ISCSI_STATE_LOGGING_OUT; - list_move_tail(&mtask->running, &conn->mgmt_run_list); + list_move_tail(&ctask->running, &conn->mgmt_run_list); debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, - mtask->data_count); + ctask->data_count); return 0; } -static struct iscsi_mgmt_task * +static struct iscsi_cmd_task * __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size) { struct iscsi_session *session = conn->session; - struct iscsi_mgmt_task *mtask; + struct iscsi_cmd_task *ctask; if (session->state == ISCSI_STATE_TERMINATE) return NULL; @@ -470,48 +478,56 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, /* * Login and Text are sent serially, in * request-followed-by-response sequence. - * Same mtask can be used. Same ITT must be used. - * Note that login_mtask is preallocated at conn_create(). + * Same task can be used. Same ITT must be used. + * Note that login_task is preallocated at conn_create(). */ - mtask = conn->login_mtask; + ctask = conn->login_ctask; else { BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); - if (!__kfifo_get(session->mgmtpool.queue, - (void*)&mtask, sizeof(void*))) + if (!__kfifo_get(session->cmdpool.queue, + (void*)&ctask, sizeof(void*))) return NULL; if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) && hdr->ttt == RESERVED_ITT) { - conn->ping_mtask = mtask; + conn->ping_ctask = ctask; conn->last_ping = jiffies; } } + /* + * released in complete pdu for task we expect a response for, and + * released by the lld when it has transmitted the task for + * pdus we do not expect a response for. + */ + atomic_set(&ctask->refcount, 1); + ctask->conn = conn; + ctask->sc = NULL; if (data_size) { - memcpy(mtask->data, data, data_size); - mtask->data_count = data_size; + memcpy(ctask->data, data, data_size); + ctask->data_count = data_size; } else - mtask->data_count = 0; + ctask->data_count = 0; - memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); - INIT_LIST_HEAD(&mtask->running); - list_add_tail(&mtask->running, &conn->mgmtqueue); + memcpy(ctask->hdr, hdr, sizeof(struct iscsi_hdr)); + INIT_LIST_HEAD(&ctask->running); + list_add_tail(&ctask->running, &conn->mgmtqueue); if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { - if (iscsi_prep_mtask(conn, mtask)) { - iscsi_free_mgmt_task(conn, mtask); + if (iscsi_prep_mgmt_task(conn, ctask)) { + __iscsi_put_ctask(ctask); return NULL; } - if (session->tt->xmit_mgmt_task(conn, mtask)) - mtask = NULL; + if (session->tt->xmit_task(ctask)) + ctask = NULL; } else scsi_queue_work(conn->session->host, &conn->xmitwork); - return mtask; + return ctask; } int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, @@ -538,7 +554,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); * @datalen: len of buffer * * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and - * then completes the command and task. + * then completes the command and ctask. **/ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_cmd_task *ctask, char *data, @@ -634,9 +650,9 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) { struct iscsi_nopout hdr; - struct iscsi_mgmt_task *mtask; + struct iscsi_cmd_task *ctask; - if (!rhdr && conn->ping_mtask) + if (!rhdr && conn->ping_ctask) return; memset(&hdr, 0, sizeof(struct iscsi_nopout)); @@ -650,8 +666,8 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) } else hdr.ttt = RESERVED_ITT; - mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); - if (!mtask) + ctask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); + if (!ctask) iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); } @@ -697,7 +713,6 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_session *session = conn->session; int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; struct iscsi_cmd_task *ctask; - struct iscsi_mgmt_task *mtask; uint32_t itt; conn->last_recv = jiffies; @@ -710,93 +725,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, else itt = ~0U; - if (itt < session->cmds_max) { - ctask = session->cmds[itt]; - - debug_scsi("cmdrsp [op 0x%x cid %d itt 0x%x len %d]\n", - opcode, conn->id, ctask->itt, datalen); - - switch(opcode) { - case ISCSI_OP_SCSI_CMD_RSP: - BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - iscsi_scsi_cmd_rsp(conn, hdr, ctask, data, - datalen); - break; - case ISCSI_OP_SCSI_DATA_IN: - BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { - conn->scsirsp_pdus_cnt++; - __iscsi_put_ctask(ctask); - } - break; - case ISCSI_OP_R2T: - /* LLD handles this for now */ - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } - } else if (itt >= ISCSI_MGMT_ITT_OFFSET && - itt < ISCSI_MGMT_ITT_OFFSET + session->mgmtpool_max) { - mtask = session->mgmt_cmds[itt - ISCSI_MGMT_ITT_OFFSET]; - - debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", - opcode, conn->id, mtask->itt, datalen); + debug_scsi("[op 0x%x cid %d itt 0x%x len %d]\n", + opcode, conn->id, itt, datalen); - iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); - switch(opcode) { - case ISCSI_OP_LOGOUT_RSP: - if (datalen) { - rc = ISCSI_ERR_PROTO; - break; - } - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - /* fall through */ - case ISCSI_OP_LOGIN_RSP: - case ISCSI_OP_TEXT_RSP: - /* - * login related PDU's exp_statsn is handled in - * userspace - */ - if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) - rc = ISCSI_ERR_CONN_FAILED; - iscsi_free_mgmt_task(conn, mtask); - break; - case ISCSI_OP_SCSI_TMFUNC_RSP: - if (datalen) { - rc = ISCSI_ERR_PROTO; - break; - } - - iscsi_tmf_rsp(conn, hdr); - iscsi_free_mgmt_task(conn, mtask); - break; - case ISCSI_OP_NOOP_IN: - if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || - datalen) { - rc = ISCSI_ERR_PROTO; - break; - } - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - - if (conn->ping_mtask != mtask) { - /* - * If this is not in response to one of our - * nops then it must be from userspace. - */ - if (iscsi_recv_pdu(conn->cls_conn, hdr, data, - datalen)) - rc = ISCSI_ERR_CONN_FAILED; - } else - mod_timer(&conn->transport_timer, - jiffies + conn->recv_timeout); - iscsi_free_mgmt_task(conn, mtask); - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } - } else if (itt == ~0U) { + if (itt == ~0U) { iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); switch(opcode) { @@ -823,9 +755,88 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, rc = ISCSI_ERR_BAD_OPCODE; break; } - } else - rc = ISCSI_ERR_BAD_ITT; + goto out; + } + + ctask = session->cmds[itt]; + switch(opcode) { + case ISCSI_OP_SCSI_CMD_RSP: + if (!ctask->sc) { + rc = ISCSI_ERR_NO_SCSI_CMD; + break; + } + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + iscsi_scsi_cmd_rsp(conn, hdr, ctask, data, datalen); + break; + case ISCSI_OP_SCSI_DATA_IN: + if (!ctask->sc) { + rc = ISCSI_ERR_NO_SCSI_CMD; + break; + } + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { + conn->scsirsp_pdus_cnt++; + iscsi_update_cmdsn(session, + (struct iscsi_nopin*) hdr); + __iscsi_put_ctask(ctask); + } + break; + case ISCSI_OP_R2T: + /* LLD handles this for now */ + break; + case ISCSI_OP_LOGOUT_RSP: + iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); + if (datalen) { + rc = ISCSI_ERR_PROTO; + break; + } + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + goto recv_pdu; + case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_TEXT_RSP: + iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); + /* + * login related PDU's exp_statsn is handled in + * userspace + */ + goto recv_pdu; + case ISCSI_OP_SCSI_TMFUNC_RSP: + iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); + if (datalen) { + rc = ISCSI_ERR_PROTO; + break; + } + + iscsi_tmf_rsp(conn, hdr); + __iscsi_put_ctask(ctask); + break; + case ISCSI_OP_NOOP_IN: + iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); + if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) { + rc = ISCSI_ERR_PROTO; + break; + } + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + + if (conn->ping_ctask != ctask) + /* + * If this is not in response to one of our + * nops then it must be from userspace. + */ + goto recv_pdu; + __iscsi_put_ctask(ctask); + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } +out: + return rc; +recv_pdu: + if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) + rc = ISCSI_ERR_CONN_FAILED; + __iscsi_put_ctask(ctask); return rc; } @@ -845,6 +856,7 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) { struct iscsi_session *session = conn->session; struct iscsi_cmd_task *ctask; + uint32_t i; if (itt == RESERVED_ITT) return 0; @@ -858,25 +870,22 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) return ISCSI_ERR_BAD_ITT; } - if (itt < session->cmds_max) { - ctask = session->cmds[itt]; - - if (!ctask->sc) { - iscsi_conn_printk(KERN_INFO, conn, "dropping ctask " - "with itt 0x%x\n", ctask->itt); - /* force drop */ - return ISCSI_ERR_NO_SCSI_CMD; - } - - if (ctask->sc->SCp.phase != session->age) { - iscsi_conn_printk(KERN_ERR, conn, - "iscsi: ctask's session age %d, " - "expected %d\n", ctask->sc->SCp.phase, - session->age); - return ISCSI_ERR_SESSION_FAILED; - } + i = get_itt(itt); + if (i >= session->cmds_max) { + iscsi_conn_printk(KERN_ERR, conn, + "received invalid itt index %u (max cmds " + "%u.\n", i, session->cmds_max); + return ISCSI_ERR_BAD_ITT; } + ctask = session->cmds[i]; + if (ctask->sc && ctask->sc->SCp.phase != session->age) { + iscsi_conn_printk(KERN_ERR, conn, + "iscsi: ctask's session age %d, " + "expected %d\n", ctask->sc->SCp.phase, + session->age); + return ISCSI_ERR_SESSION_FAILED; + } return 0; } EXPORT_SYMBOL_GPL(iscsi_verify_itt); @@ -929,20 +938,6 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); -static int iscsi_xmit_mtask(struct iscsi_conn *conn) -{ - int rc; - - spin_unlock_bh(&conn->session->lock); - rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); - spin_lock_bh(&conn->session->lock); - if (rc) - return rc; - /* done with this in-progress mtask */ - conn->mtask = NULL; - return 0; -} - static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) { struct iscsi_session *session = conn->session; @@ -967,7 +962,7 @@ static int iscsi_xmit_ctask(struct iscsi_conn *conn) __iscsi_get_ctask(ctask); spin_unlock_bh(&conn->session->lock); - rc = conn->session->tt->xmit_cmd_task(conn, ctask); + rc = conn->session->tt->xmit_task(ctask); spin_lock_bh(&conn->session->lock); __iscsi_put_ctask(ctask); if (!rc) @@ -1015,12 +1010,6 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) if (conn->ctask) { rc = iscsi_xmit_ctask(conn); - if (rc) - goto again; - } - - if (conn->mtask) { - rc = iscsi_xmit_mtask(conn); if (rc) goto again; } @@ -1032,14 +1021,14 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) */ check_mgmt: while (!list_empty(&conn->mgmtqueue)) { - conn->mtask = list_entry(conn->mgmtqueue.next, - struct iscsi_mgmt_task, running); - if (iscsi_prep_mtask(conn, conn->mtask)) { - iscsi_free_mgmt_task(conn, conn->mtask); - conn->mtask = NULL; + conn->ctask = list_entry(conn->mgmtqueue.next, + struct iscsi_cmd_task, running); + if (iscsi_prep_mgmt_task(conn, conn->ctask)) { + __iscsi_put_ctask(conn->ctask); + conn->ctask = NULL; continue; } - rc = iscsi_xmit_mtask(conn); + rc = iscsi_xmit_ctask(conn); if (rc) goto again; } @@ -1224,7 +1213,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) iscsi_complete_command(ctask); goto fault; } - if (session->tt->xmit_cmd_task(conn, ctask)) { + if (session->tt->xmit_task(ctask)) { sc->scsi_done = NULL; iscsi_complete_command(ctask); reason = FAILURE_SESSION_NOT_READY; @@ -1347,16 +1336,16 @@ static void iscsi_tmf_timedout(unsigned long data) spin_unlock(&session->lock); } -static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, +static int iscsi_exec_ctask_mgmt_fn(struct iscsi_conn *conn, struct iscsi_tm *hdr, int age, int timeout) { struct iscsi_session *session = conn->session; - struct iscsi_mgmt_task *mtask; + struct iscsi_cmd_task *ctask; - mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, + ctask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); - if (!mtask) { + if (!ctask) { spin_unlock_bh(&session->lock); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); spin_lock_bh(&session->lock); @@ -1390,7 +1379,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); - /* if the session drops it will clean up the mtask */ + /* if the session drops it will clean up the ctask */ if (age != session->age || session->state != ISCSI_STATE_LOGGED_IN) return -ENOTCONN; @@ -1497,7 +1486,7 @@ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) jiffies)) rc = EH_RESET_TIMER; /* if in the middle of checking the transport then give us more time */ - if (conn->ping_mtask) + if (conn->ping_ctask) rc = EH_RESET_TIMER; done: spin_unlock(&session->lock); @@ -1521,7 +1510,7 @@ static void iscsi_check_transport_timeouts(unsigned long data) recv_timeout *= HZ; last_recv = conn->last_recv; - if (conn->ping_mtask && + if (conn->ping_ctask && time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), jiffies)) { iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " @@ -1547,7 +1536,7 @@ done: spin_unlock(&session->lock); } -static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask, +static void iscsi_prep_abort_ctask_pdu(struct iscsi_cmd_task *ctask, struct iscsi_tm *hdr) { memset(hdr, 0, sizeof(*hdr)); @@ -1619,9 +1608,9 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) conn->tmf_state = TMF_QUEUED; hdr = &conn->tmhdr; - iscsi_prep_abort_task_pdu(ctask, hdr); + iscsi_prep_abort_ctask_pdu(ctask, hdr); - if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) { + if (iscsi_exec_ctask_mgmt_fn(conn, hdr, age, session->abort_timeout)) { rc = FAILED; goto failed; } @@ -1631,7 +1620,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) spin_unlock_bh(&session->lock); iscsi_suspend_tx(conn); /* - * clean up task if aborted. grab the recv lock as a writer + * clean up ctask if aborted. grab the recv lock as a writer */ write_lock_bh(conn->recv_lock); spin_lock(&session->lock); @@ -1716,7 +1705,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) hdr = &conn->tmhdr; iscsi_prep_lun_reset_pdu(sc, hdr); - if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, + if (iscsi_exec_ctask_mgmt_fn(conn, hdr, session->age, session->lu_reset_timeout)) { rc = FAILED; goto unlock; @@ -1897,8 +1886,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); * @iscsit: iscsi transport template * @shost: scsi host * @cmds_max: session can queue - * @cmd_task_size: LLD ctask private data size - * @mgmt_task_size: LLD mtask private data size + * @cmd_ctask_size: LLD ctask private data size * @initial_cmdsn: initial CmdSN * * This can be used by software iscsi_transports that allocate @@ -1906,22 +1894,26 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); */ struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, - uint16_t cmds_max, int cmd_task_size, int mgmt_task_size, + uint16_t scsi_cmds_max, int cmd_ctask_size, uint32_t initial_cmdsn) { struct iscsi_session *session; struct iscsi_cls_session *cls_session; - int cmd_i; + int cmd_i, cmds_max; - if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET || - cmds_max < 2) { - if (cmds_max != 0) - printk(KERN_ERR "iscsi: invalid can_queue of %d. " - "can_queue must be a power of 2 and between " - "2 and %d - setting to %d.\n", cmds_max, - ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX); - cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; + /* + * The iscsi layer needs some ctasks for nop handling and tmfs. + */ + if (scsi_cmds_max < 1) + scsi_cmds_max = ISCSI_MGMT_CMDS_MAX; + if ((scsi_cmds_max + ISCSI_MGMT_CMDS_MAX) >= ISCSI_MGMT_ITT_OFFSET) { + printk(KERN_ERR "iscsi: invalid can_queue of %d. " + "can_queue must be less than %d.\n", + scsi_cmds_max, + ISCSI_MGMT_ITT_OFFSET - ISCSI_MGMT_CMDS_MAX); + scsi_cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; } + cmds_max = roundup_pow_of_two(scsi_cmds_max + ISCSI_MGMT_CMDS_MAX); cls_session = iscsi_alloc_session(shost, iscsit, sizeof(struct iscsi_session)); @@ -1934,7 +1926,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, session->fast_abort = 1; session->lu_reset_timeout = 15; session->abort_timeout = 10; - session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; + session->scsi_cmds_max = scsi_cmds_max; session->cmds_max = cmds_max; session->queued_cmdsn = session->cmdsn = initial_cmdsn; session->exp_cmdsn = initial_cmdsn + 1; @@ -1947,36 +1939,19 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, /* initialize SCSI PDU commands pool */ if (iscsi_pool_init(&session->cmdpool, session->cmds_max, (void***)&session->cmds, - cmd_task_size + sizeof(struct iscsi_cmd_task))) + cmd_ctask_size + sizeof(struct iscsi_cmd_task))) goto cmdpool_alloc_fail; /* pre-format cmds pool with ITT */ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - if (cmd_task_size) + if (cmd_ctask_size) ctask->dd_data = &ctask[1]; ctask->itt = cmd_i; INIT_LIST_HEAD(&ctask->running); } - /* initialize immediate command pool */ - if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, - (void***)&session->mgmt_cmds, - mgmt_task_size + sizeof(struct iscsi_mgmt_task))) - goto mgmtpool_alloc_fail; - - - /* pre-format immediate cmds pool with ITT */ - for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { - struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i]; - - if (mgmt_task_size) - mtask->dd_data = &mtask[1]; - mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; - INIT_LIST_HEAD(&mtask->running); - } - if (!try_module_get(iscsit->owner)) goto module_get_fail; @@ -1987,8 +1962,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, cls_session_fail: module_put(iscsit->owner); module_get_fail: - iscsi_pool_free(&session->mgmtpool); -mgmtpool_alloc_fail: iscsi_pool_free(&session->cmdpool); cmdpool_alloc_fail: iscsi_free_session(cls_session); @@ -2008,7 +1981,6 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) struct iscsi_session *session = cls_session->dd_data; struct module *owner = cls_session->transport->owner; - iscsi_pool_free(&session->mgmtpool); iscsi_pool_free(&session->cmdpool); kfree(session->password); @@ -2063,30 +2035,30 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, INIT_LIST_HEAD(&conn->requeue); INIT_WORK(&conn->xmitwork, iscsi_xmitworker); - /* allocate login_mtask used for the login/text sequences */ + /* allocate login_ctask used for the login/text sequences */ spin_lock_bh(&session->lock); - if (!__kfifo_get(session->mgmtpool.queue, - (void*)&conn->login_mtask, + if (!__kfifo_get(session->cmdpool.queue, + (void*)&conn->login_ctask, sizeof(void*))) { spin_unlock_bh(&session->lock); - goto login_mtask_alloc_fail; + goto login_ctask_alloc_fail; } spin_unlock_bh(&session->lock); data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); if (!data) - goto login_mtask_data_alloc_fail; - conn->login_mtask->data = conn->data = data; + goto login_ctask_data_alloc_fail; + conn->login_ctask->data = conn->data = data; init_timer(&conn->tmf_timer); init_waitqueue_head(&conn->ehwait); return cls_conn; -login_mtask_data_alloc_fail: - __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, +login_ctask_data_alloc_fail: + __kfifo_put(session->cmdpool.queue, (void*)&conn->login_ctask, sizeof(void*)); -login_mtask_alloc_fail: +login_ctask_alloc_fail: iscsi_destroy_conn(cls_conn); return NULL; } @@ -2146,7 +2118,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) spin_lock_bh(&session->lock); kfree(conn->data); kfree(conn->persistent_address); - __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + __kfifo_put(session->cmdpool.queue, (void*)&conn->login_ctask, sizeof(void*)); if (session->leadconn == conn) session->leadconn = NULL; @@ -2227,21 +2199,23 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start); static void flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn) { - struct iscsi_mgmt_task *mtask, *tmp; + struct iscsi_cmd_task *ctask, *tmp; /* handle pending */ - list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) { - debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt); - iscsi_free_mgmt_task(conn, mtask); + list_for_each_entry_safe(ctask, tmp, &conn->mgmtqueue, running) { + debug_scsi("flushing pending mgmt ctask itt 0x%x\n", ctask->itt); + /* release ref from prep ctask */ + __iscsi_put_ctask(ctask); } /* handle running */ - list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) { - debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt); - iscsi_free_mgmt_task(conn, mtask); + list_for_each_entry_safe(ctask, tmp, &conn->mgmt_run_list, running) { + debug_scsi("flushing running mgmt ctask itt 0x%x\n", ctask->itt); + /* release ref from prep ctask */ + __iscsi_put_ctask(ctask); } - conn->mtask = NULL; + conn->ctask = NULL; } static void iscsi_start_session_recovery(struct iscsi_session *session, @@ -2272,7 +2246,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, /* * When this is called for the in_login state, we only want to clean - * up the login task and connection. We do not need to block and set + * up the login ctask and connection. We do not need to block and set * the recovery state again */ if (flag == STOP_CONN_TERM) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 9be6a70..d1c3675 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -85,18 +85,6 @@ enum { ISCSI_DIGEST_SIZE = sizeof(__u32), }; -struct iscsi_mgmt_task { - /* - * Becuae LLDs allocate their hdr differently, this is a pointer to - * that storage. It must be setup at session creation time. - */ - struct iscsi_hdr *hdr; - char *data; /* mgmt payload */ - unsigned data_count; /* counts data to be sent */ - uint32_t itt; /* this ITT */ - void *dd_data; /* driver/transport data */ - struct list_head running; -}; enum { ISCSI_TASK_COMPLETED, @@ -121,6 +109,7 @@ struct iscsi_cmd_task { /* offset in unsolicited stream (bytes); */ unsigned unsol_offset; unsigned data_count; /* remaining Data-Out */ + char *data; /* mgmt payload */ struct scsi_cmnd *sc; /* associated SCSI cmd*/ struct iscsi_conn *conn; /* used connection */ @@ -162,7 +151,7 @@ struct iscsi_conn { unsigned long last_ping; int ping_timeout; int recv_timeout; - struct iscsi_mgmt_task *ping_mtask; + struct iscsi_cmd_task *ping_ctask; /* iSCSI connection-wide sequencing */ uint32_t exp_statsn; @@ -178,9 +167,8 @@ struct iscsi_conn { * should always fit in this buffer */ char *data; - struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ - struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ - struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ + struct iscsi_cmd_task *login_ctask; /* mtask used for login/text */ + struct iscsi_cmd_task *ctask; /* xmit task in progress */ /* xmit */ struct list_head mgmtqueue; /* mgmt (control) xmit queue */ @@ -295,12 +283,10 @@ struct iscsi_session { int state; /* session state */ int age; /* counts session re-opens */ + int scsi_cmds_max; /* max scsi commands */ int cmds_max; /* size of cmds array */ struct iscsi_cmd_task **cmds; /* Original Cmds arr */ struct iscsi_pool cmdpool; /* PDU's pool */ - int mgmtpool_max; /* size of mgmt array */ - struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ - struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */ }; struct iscsi_host { @@ -345,7 +331,7 @@ extern void iscsi_host_free(struct Scsi_Host *shost); */ extern struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, - uint16_t, int, int, uint32_t); + uint16_t, int, uint32_t); extern void iscsi_session_teardown(struct iscsi_cls_session *); extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, @@ -388,8 +374,7 @@ extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); -extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask); +extern void iscsi_put_ctask(struct iscsi_cmd_task *ctask); /* * generic helpers diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 4028f12..3f24503 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -34,7 +34,6 @@ struct Scsi_Host; struct iscsi_cls_conn; struct iscsi_conn; struct iscsi_cmd_task; -struct iscsi_mgmt_task; struct sockaddr; /** @@ -58,19 +57,22 @@ struct sockaddr; * @stop_conn: suspend/recover/terminate connection * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. * @session_recovery_timedout: notify LLD a block during recovery timed out - * @init_cmd_task: Initialize a iscsi_cmd_task and any internal structs. - * Called from queuecommand with session lock held. - * @init_mgmt_task: Initialize a iscsi_mgmt_task and any internal structs. - * Called from iscsi_conn_send_generic with xmitmutex. - * @xmit_cmd_task: Requests LLD to transfer cmd task. Returns 0 or the + * @init_task: Initialize a iscsi_task and any internal structs. + * When offloading the data path, this is called from + * queuecommand with the session lock, or from the + * iscsi_conn_send_pdu context with the session lock. + * When not offloading the data path, this is called + * from the scsi work queue without the session lock. + * @xmit_task Requests LLD to transfer cmd task. Returns 0 or the * the number of bytes transferred on success, and -Exyz - * value on error. - * @xmit_mgmt_task: Requests LLD to transfer mgmt task. Returns 0 or the - * the number of bytes transferred on success, and -Exyz - * value on error. - * @cleanup_cmd_task: requests LLD to fail cmd task. Called with xmitmutex - * and session->lock after the connection has been - * suspended and terminated during recovery. If called + * value on error. When offloading the data path, this + * is called from queuecommand with the session lock, or + * from the iscsi_conn_send_pdu context with the session + * lock. When not offloading the data path, this is called + * from the scsi work queue without the session lock. + * @cleanup_task: requests LLD to fail task. Called with session lock + * and after the connection has been suspended and + * terminated during recovery. If called * from abort task then connection is not suspended * or terminated but sk_callback_lock is held * @@ -110,15 +112,10 @@ struct iscsi_transport { char *data, uint32_t data_size); void (*get_stats) (struct iscsi_cls_conn *conn, struct iscsi_stats *stats); - int (*init_cmd_task) (struct iscsi_cmd_task *ctask); - void (*init_mgmt_task) (struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask); - int (*xmit_cmd_task) (struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); - void (*cleanup_cmd_task) (struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); - int (*xmit_mgmt_task) (struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask); + int (*init_task) (struct iscsi_cmd_task *task); + int (*xmit_task) (struct iscsi_cmd_task *task); + void (*cleanup_task) (struct iscsi_conn *conn, + struct iscsi_cmd_task *task); void (*session_recovery_timedout) (struct iscsi_cls_session *session); int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking, uint64_t *ep_handle); -- cgit v0.10.2 From fbc514b4e262bc0596faae8640ebc0b9142a1cdd Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:07 -0500 Subject: [SCSI] iscsi_tcp: convert iscsi_tcp to support merged tasks Convert iscsi_tcp to support merged tasks. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index f2a08f7..517bad1 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -498,11 +498,15 @@ iscsi_tcp_data_recv_prep(struct iscsi_tcp_conn *tcp_conn) * must be called with session lock */ static void -iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_r2t_info *r2t; + /* nothing to do for mgmt ctasks */ + if (!ctask->sc) + return; + /* flush ctask's r2t queues */ while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, @@ -521,7 +525,7 @@ iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) /** * iscsi_data_rsp - SCSI Data-In Response processing * @conn: iscsi connection - * @ctask: scsi command task + * @ctask: scsi command ctask **/ static int iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) @@ -578,7 +582,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) /** * iscsi_solicit_data_init - initialize first Data-Out * @conn: iscsi connection - * @ctask: scsi command task + * @ctask: scsi command ctask * @r2t: R2T info * * Notes: @@ -620,7 +624,7 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, /** * iscsi_r2t_rsp - iSCSI R2T Response processing * @conn: iscsi connection - * @ctask: scsi command task + * @ctask: scsi command ctask **/ static int iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) @@ -646,7 +650,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) return ISCSI_ERR_R2TSN; } - /* fill-in new R2T associated with the task */ + /* fill-in new R2T associated with the ctask */ iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) { @@ -769,6 +773,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) ctask = iscsi_itt_to_ctask(conn, hdr->itt); if (!ctask) return ISCSI_ERR_BAD_ITT; + if (!ctask->sc) + return ISCSI_ERR_NO_SCSI_CMD; spin_lock(&conn->session->lock); rc = iscsi_data_rsp(conn, ctask); @@ -815,6 +821,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) ctask = iscsi_itt_to_ctask(conn, hdr->itt); if (!ctask) return ISCSI_ERR_BAD_ITT; + if (!ctask->sc) + return ISCSI_ERR_NO_SCSI_CMD; if (ahslen) rc = ISCSI_ERR_AHSLEN; @@ -1194,7 +1202,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr, size_t hdrlen) /* If header digest is enabled, compute the CRC and * place the digest into the same buffer. We make - * sure that both iscsi_tcp_ctask and mtask have + * sure that both iscsi_tcp_cmd_task and mctask have * sufficient room. */ if (conn->hdrdgst_en) { @@ -1269,7 +1277,7 @@ iscsi_tcp_send_linear_data_prepare(struct iscsi_conn *conn, void *data, /** * iscsi_solicit_data_cont - initialize next Data-Out * @conn: iscsi connection - * @ctask: scsi command task + * @ctask: scsi command ctask * @r2t: R2T info * @left: bytes left to transfer * @@ -1316,19 +1324,37 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, } /** - * iscsi_tcp_ctask - Initialize iSCSI SCSI_READ or SCSI_WRITE commands + * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands * @conn: iscsi connection - * @ctask: scsi command task + * @ctask: scsi command ctask * @sc: scsi command **/ static int -iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask) +iscsi_tcp_task_init(struct iscsi_cmd_task *ctask) { struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_conn *conn = ctask->conn; struct scsi_cmnd *sc = ctask->sc; int err; + if (!sc) { + /* + * mgmt ctasks do not have a scatterlist since they come + * in from the iscsi interface. + */ + debug_scsi("mctask deq [cid %d itt 0x%x]\n", conn->id, + ctask->itt); + + /* Prepare PDU, optionally w/ immediate data */ + iscsi_tcp_send_hdr_prep(conn, ctask->hdr, sizeof(*ctask->hdr)); + + /* If we have immediate data, attach a payload */ + if (ctask->data_count) + iscsi_tcp_send_linear_data_prepare(conn, ctask->data, + ctask->data_count); + return 0; + } + BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); tcp_ctask->sent = 0; tcp_ctask->exp_datasn = 0; @@ -1353,52 +1379,21 @@ iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask) return 0; } -/** - * iscsi_tcp_mtask_xmit - xmit management(immediate) task - * @conn: iscsi connection - * @mtask: task management task - * - * Notes: - * The function can return -EAGAIN in which case caller must - * call it again later, or recover. '0' return code means successful - * xmit. - **/ -static int -iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) -{ - int rc; - - /* Flush any pending data first. */ - rc = iscsi_tcp_flush(conn); - if (rc < 0) - return rc; - - if (mtask->hdr->itt == RESERVED_ITT) { - struct iscsi_session *session = conn->session; - - spin_lock_bh(&session->lock); - iscsi_free_mgmt_task(conn, mtask); - spin_unlock_bh(&session->lock); - } - - return 0; -} - /* - * iscsi_tcp_ctask_xmit - xmit normal PDU task - * @conn: iscsi connection - * @ctask: iscsi command task + * iscsi_tcp_task_xmit - xmit normal PDU ctask + * @ctask: iscsi command ctask * * We're expected to return 0 when everything was transmitted succesfully, * -EAGAIN if there's still data in the queue, or != 0 for any other kind * of error. */ static int -iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_tcp_task_xmit(struct iscsi_cmd_task *ctask) { + struct iscsi_conn *conn = ctask->conn; struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct scsi_cmnd *sc = ctask->sc; - struct scsi_data_buffer *sdb = scsi_out(sc); + struct scsi_data_buffer *sdb; int rc = 0; flush: @@ -1407,10 +1402,18 @@ flush: if (rc < 0) return rc; + /* mgmt command */ + if (!sc) { + if (ctask->hdr->itt == RESERVED_ITT) + iscsi_put_ctask(ctask); + return 0; + } + /* Are we done already? */ if (sc->sc_data_direction != DMA_TO_DEVICE) return 0; + sdb = scsi_out(sc); if (ctask->unsol_count != 0) { struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr; @@ -1688,21 +1691,6 @@ free_socket: return err; } -/* called with host lock */ -static void -iscsi_tcp_mtask_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) -{ - debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt); - - /* Prepare PDU, optionally w/ immediate data */ - iscsi_tcp_send_hdr_prep(conn, mtask->hdr, sizeof(*mtask->hdr)); - - /* If we have immediate data, attach a payload */ - if (mtask->data_count) - iscsi_tcp_send_linear_data_prepare(conn, mtask->data, - mtask->data_count); -} - static int iscsi_r2tpool_alloc(struct iscsi_session *session) { @@ -1710,7 +1698,7 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) int cmd_i; /* - * initialize per-task: R2T pool and xmit queue + * initialize per-ctask: R2T pool and xmit queue */ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; @@ -1880,13 +1868,12 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max, sizeof(struct iscsi_tcp_cmd_task), - sizeof(struct iscsi_tcp_mgmt_task), initial_cmdsn); if (!cls_session) goto remove_host; session = cls_session->dd_data; - shost->can_queue = session->cmds_max; + shost->can_queue = session->scsi_cmds_max; for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; @@ -1895,13 +1882,6 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE; } - for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { - struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i]; - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; - - mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr; - } - if (iscsi_r2tpool_alloc(session)) goto remove_session; return cls_session; @@ -1999,11 +1979,9 @@ static struct iscsi_transport iscsi_tcp_transport = { /* IO */ .send_pdu = iscsi_conn_send_pdu, .get_stats = iscsi_conn_get_stats, - .init_cmd_task = iscsi_tcp_ctask_init, - .init_mgmt_task = iscsi_tcp_mtask_init, - .xmit_cmd_task = iscsi_tcp_ctask_xmit, - .xmit_mgmt_task = iscsi_tcp_mtask_xmit, - .cleanup_cmd_task = iscsi_tcp_cleanup_ctask, + .init_task = iscsi_tcp_task_init, + .xmit_task = iscsi_tcp_task_xmit, + .cleanup_task = iscsi_tcp_cleanup_task, /* recovery */ .session_recovery_timedout = iscsi_session_recovery_timedout, }; diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index ed0b991..c9c8633 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -103,11 +103,6 @@ struct iscsi_data_task { char hdrext[ISCSI_DIGEST_SIZE];/* Header-Digest */ }; -struct iscsi_tcp_mgmt_task { - struct iscsi_hdr hdr; - char hdrext[ISCSI_DIGEST_SIZE]; /* Header-Digest */ -}; - struct iscsi_r2t_info { __be32 ttt; /* copied from R2T */ __be32 exp_statsn; /* copied from R2T */ -- cgit v0.10.2 From 2747fdb25726caa1a89229f43d99ca50af72576a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:08 -0500 Subject: [SCSI] iser: convert ib_iser to support merged tasks Convert ib_iser to support merged tasks. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 7b14688..baecca1 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -124,15 +124,23 @@ error: /** - * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands + * iscsi_iser_task_init - Initialize ctask + * @ctask: iscsi ctask * - **/ + * Initialize the ctask for the scsi command or mgmt command. + */ static int -iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) +iscsi_iser_task_init(struct iscsi_cmd_task *ctask) { - struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; + struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + /* mgmt ctask */ + if (!ctask->sc) { + iser_ctask->desc.data = ctask->data; + return 0; + } + iser_ctask->command_sent = 0; iser_ctask->iser_conn = iser_conn; iser_ctask_rdma_init(iser_ctask); @@ -140,9 +148,9 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) } /** - * iscsi_mtask_xmit - xmit management(immediate) task + * iscsi_iser_mtask_xmit - xmit management(immediate) ctask * @conn: iscsi connection - * @mtask: task management task + * @ctask: ctask management ctask * * Notes: * The function can return -EAGAIN in which case caller must @@ -151,20 +159,19 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask) * **/ static int -iscsi_iser_mtask_xmit(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) +iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { int error = 0; - debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt); + debug_scsi("ctask deq [cid %d itt 0x%x]\n", conn->id, ctask->itt); - error = iser_send_control(conn, mtask); + error = iser_send_control(conn, ctask); - /* since iser xmits control with zero copy, mtasks can not be recycled + /* since iser xmits control with zero copy, ctasks can not be recycled * right after sending them. * The recycling scheme is based on whether a response is expected - * - if yes, the mtask is recycled at iscsi_complete_pdu - * - if no, the mtask is recycled at iser_snd_completion + * - if yes, the ctask is recycled at iscsi_complete_pdu + * - if no, the ctask is recycled at iser_snd_completion */ if (error && error != -ENOBUFS) iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); @@ -173,7 +180,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn, } static int -iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn, +iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_data hdr; @@ -190,24 +197,27 @@ iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn, error = iser_send_data_out(conn, ctask, &hdr); if (error) { ctask->unsol_datasn--; - goto iscsi_iser_ctask_xmit_unsol_data_exit; + goto iscsi_iser_task_xmit_unsol_data_exit; } ctask->unsol_count -= ctask->data_count; debug_scsi("Need to send %d more as data-out PDUs\n", ctask->unsol_count); } -iscsi_iser_ctask_xmit_unsol_data_exit: +iscsi_iser_task_xmit_unsol_data_exit: return error; } static int -iscsi_iser_ctask_xmit(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) +iscsi_iser_task_xmit(struct iscsi_cmd_task *ctask) { + struct iscsi_conn *conn = ctask->conn; struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; int error = 0; + if (!ctask->sc) + return iscsi_iser_mtask_xmit(conn, ctask); + if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { BUG_ON(scsi_bufflen(ctask->sc) == 0); @@ -223,25 +233,29 @@ iscsi_iser_ctask_xmit(struct iscsi_conn *conn, if (!iser_ctask->command_sent) { error = iser_send_command(conn, ctask); if (error) - goto iscsi_iser_ctask_xmit_exit; + goto iscsi_iser_task_xmit_exit; iser_ctask->command_sent = 1; } /* Send unsolicited data-out PDU(s) if necessary */ if (ctask->unsol_count) - error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask); + error = iscsi_iser_task_xmit_unsol_data(conn, ctask); - iscsi_iser_ctask_xmit_exit: + iscsi_iser_task_xmit_exit: if (error && error != -ENOBUFS) iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); return error; } static void -iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + /* mgmt tasks do not need special cleanup */ + if (!ctask->sc) + return; + if (iser_ctask->status == ISER_TASK_STATUS_STARTED) { iser_ctask->status = ISER_TASK_STATUS_COMPLETED; iser_ctask_rdma_finalize(iser_ctask); @@ -394,10 +408,8 @@ iscsi_iser_session_create(struct Scsi_Host *shost, struct iscsi_cls_session *cls_session; struct iscsi_session *session; int i; - struct iscsi_cmd_task *ctask; - struct iscsi_mgmt_task *mtask; + struct iscsi_cmd_task *ctask; struct iscsi_iser_cmd_task *iser_ctask; - struct iser_desc *desc; if (shost) { printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", @@ -425,28 +437,19 @@ iscsi_iser_session_create(struct Scsi_Host *shost, cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, ISCSI_DEF_XMIT_CMDS_MAX, sizeof(struct iscsi_iser_cmd_task), - sizeof(struct iser_desc), initial_cmdsn); if (!cls_session) goto remove_host; session = cls_session->dd_data; - shost->can_queue = session->cmds_max; + shost->can_queue = session->scsi_cmds_max; /* libiscsi setup itts, data and pool so just set desc fields */ for (i = 0; i < session->cmds_max; i++) { - ctask = session->cmds[i]; + ctask = session->cmds[i]; iser_ctask = ctask->dd_data; ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header; ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header); } - - for (i = 0; i < session->mgmtpool_max; i++) { - mtask = session->mgmt_cmds[i]; - desc = mtask->dd_data; - mtask->hdr = &desc->iscsi_header; - desc->data = mtask->data; - } - return cls_session; remove_host: @@ -659,10 +662,9 @@ static struct iscsi_transport iscsi_iser_transport = { /* IO */ .send_pdu = iscsi_conn_send_pdu, .get_stats = iscsi_iser_conn_get_stats, - .init_cmd_task = iscsi_iser_cmd_init, - .xmit_cmd_task = iscsi_iser_ctask_xmit, - .xmit_mgmt_task = iscsi_iser_mtask_xmit, - .cleanup_cmd_task = iscsi_iser_cleanup_ctask, + .init_task = iscsi_iser_task_init, + .xmit_task = iscsi_iser_task_xmit, + .cleanup_task = iscsi_iser_cleanup_task, /* recovery */ .session_recovery_timedout = iscsi_session_recovery_timedout, diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index bd5c1a5..96a600f 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -298,15 +298,15 @@ extern int iser_debug_level; /* allocate connection resources needed for rdma functionality */ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn); -int iser_send_control(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask); +int iser_send_control(struct iscsi_conn *conn, + struct iscsi_cmd_task *ctask); -int iser_send_command(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); +int iser_send_command(struct iscsi_conn *conn, + struct iscsi_cmd_task *ctask); -int iser_send_data_out(struct iscsi_conn *conn, +int iser_send_data_out(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, - struct iscsi_data *hdr); + struct iscsi_data *hdr); void iscsi_iser_recv(struct iscsi_conn *conn, struct iscsi_hdr *hdr, @@ -326,7 +326,7 @@ void iser_rcv_completion(struct iser_desc *desc, void iser_snd_completion(struct iser_desc *desc); -void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *ctask); +void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *ctask); void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask); diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index b82a5f2..4ea78fb 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -300,13 +300,13 @@ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn) } static int -iser_check_xmit(struct iscsi_conn *conn, void *task) +iser_check_xmit(struct iscsi_conn *conn, void *ctask) { struct iscsi_iser_conn *iser_conn = conn->dd_data; if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == ISER_QP_MAX_REQ_DTOS) { - iser_dbg("%ld can't xmit task %p\n",jiffies,task); + iser_dbg("%ld can't xmit ctask %p\n",jiffies,ctask); return -ENOBUFS; } return 0; @@ -316,7 +316,7 @@ iser_check_xmit(struct iscsi_conn *conn, void *task) /** * iser_send_command - send command PDU */ -int iser_send_command(struct iscsi_conn *conn, +int iser_send_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_iser_conn *iser_conn = conn->dd_data; @@ -395,7 +395,7 @@ send_command_error: /** * iser_send_data_out - send data out PDU */ -int iser_send_data_out(struct iscsi_conn *conn, +int iser_send_data_out(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_data *hdr) { @@ -470,10 +470,11 @@ send_data_out_error: } int iser_send_control(struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask) + struct iscsi_cmd_task *ctask) { struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iser_desc *mdesc = mtask->dd_data; + struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iser_desc *mdesc = &iser_ctask->desc; struct iser_dto *send_dto = NULL; unsigned long data_seg_len; int err = 0; @@ -485,7 +486,7 @@ int iser_send_control(struct iscsi_conn *conn, return -EPERM; } - if (iser_check_xmit(conn,mtask)) + if (iser_check_xmit(conn, ctask)) return -ENOBUFS; /* build the tx desc regd header and add it to the tx desc dto */ @@ -498,14 +499,14 @@ int iser_send_control(struct iscsi_conn *conn, iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE); - data_seg_len = ntoh24(mtask->hdr->dlength); + data_seg_len = ntoh24(ctask->hdr->dlength); if (data_seg_len > 0) { regd_buf = &mdesc->data_regd_buf; memset(regd_buf, 0, sizeof(struct iser_regd_buf)); regd_buf->device = device; - regd_buf->virt_addr = mtask->data; - regd_buf->data_size = mtask->data_count; + regd_buf->virt_addr = ctask->data; + regd_buf->data_size = ctask->data_count; iser_reg_single(device, regd_buf, DMA_TO_DEVICE); iser_dto_add_regd_buff(send_dto, regd_buf, @@ -535,7 +536,7 @@ send_control_error: void iser_rcv_completion(struct iser_desc *rx_desc, unsigned long dto_xfer_len) { - struct iser_dto *dto = &rx_desc->dto; + struct iser_dto *dto = &rx_desc->dto; struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn; struct iscsi_cmd_task *ctask; struct iscsi_iser_cmd_task *iser_ctask; @@ -559,7 +560,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, if (opcode == ISCSI_OP_SCSI_CMD_RSP) { ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt); if (!ctask) - iser_err("itt can't be matched to task!!! " + iser_err("itt can't be matched to ctask!!! " "conn %p opcode %d itt %d\n", conn->iscsi_conn, opcode, hdr->itt); else { @@ -577,7 +578,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, kmem_cache_free(ig.desc_cache, rx_desc); /* decrementing conn->post_recv_buf_count only --after-- freeing the * - * task eliminates the need to worry on tasks which are completed in * + * ctask eliminates the need to worry on ctasks which are completed in * * parallel to the execution of iser_conn_term. So the code that waits * * for the posted rx bufs refcount to become zero handles everything */ atomic_dec(&conn->ib_conn->post_recv_buf_count); @@ -589,7 +590,7 @@ void iser_snd_completion(struct iser_desc *tx_desc) struct iser_conn *ib_conn = dto->ib_conn; struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn; struct iscsi_conn *conn = iser_conn->iscsi_conn; - struct iscsi_mgmt_task *mtask; + struct iscsi_cmd_task *ctask; int resume_tx = 0; iser_dbg("Initiator, Data sent dto=0x%p\n", dto); @@ -612,15 +613,10 @@ void iser_snd_completion(struct iser_desc *tx_desc) if (tx_desc->type == ISCSI_TX_CONTROL) { /* this arithmetic is legal by libiscsi dd_data allocation */ - mtask = (void *) ((long)(void *)tx_desc - - sizeof(struct iscsi_mgmt_task)); - if (mtask->hdr->itt == RESERVED_ITT) { - struct iscsi_session *session = conn->session; - - spin_lock(&conn->session->lock); - iscsi_free_mgmt_task(conn, mtask); - spin_unlock(&session->lock); - } + ctask = (void *) ((long)(void *)tx_desc - + sizeof(struct iscsi_cmd_task)); + if (ctask->hdr->itt == RESERVED_ITT) + iscsi_put_ctask(ctask); } } -- cgit v0.10.2 From 9c19a7d0387124a508d2cdb38ebf8cd484631ad0 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:09 -0500 Subject: [SCSI] libiscsi: rename iscsi_cmd_task to iscsi_task This is the second part of the iscsi task merging, and all it does it rename iscsi_cmd_task to iscsi_task and mtask/ctask to just task. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index ef92b1b..92ee6d9 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -88,61 +88,61 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) } EXPORT_SYMBOL_GPL(iscsi_update_cmdsn); -void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, +void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *task, struct iscsi_data *hdr) { - struct iscsi_conn *conn = ctask->conn; + struct iscsi_conn *conn = task->conn; memset(hdr, 0, sizeof(struct iscsi_data)); hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); - hdr->datasn = cpu_to_be32(ctask->unsol_datasn); - ctask->unsol_datasn++; + hdr->datasn = cpu_to_be32(task->unsol_datasn); + task->unsol_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); + memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + hdr->itt = task->hdr->itt; hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); - hdr->offset = cpu_to_be32(ctask->unsol_offset); + hdr->offset = cpu_to_be32(task->unsol_offset); - if (ctask->unsol_count > conn->max_xmit_dlength) { + if (task->unsol_count > conn->max_xmit_dlength) { hton24(hdr->dlength, conn->max_xmit_dlength); - ctask->data_count = conn->max_xmit_dlength; - ctask->unsol_offset += ctask->data_count; + task->data_count = conn->max_xmit_dlength; + task->unsol_offset += task->data_count; hdr->flags = 0; } else { - hton24(hdr->dlength, ctask->unsol_count); - ctask->data_count = ctask->unsol_count; + hton24(hdr->dlength, task->unsol_count); + task->data_count = task->unsol_count; hdr->flags = ISCSI_FLAG_CMD_FINAL; } } EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu); -static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len) +static int iscsi_add_hdr(struct iscsi_task *task, unsigned len) { - unsigned exp_len = ctask->hdr_len + len; + unsigned exp_len = task->hdr_len + len; - if (exp_len > ctask->hdr_max) { + if (exp_len > task->hdr_max) { WARN_ON(1); return -EINVAL; } WARN_ON(len & (ISCSI_PAD_LEN - 1)); /* caller must pad the AHS */ - ctask->hdr_len = exp_len; + task->hdr_len = exp_len; return 0; } /* * make an extended cdb AHS */ -static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask) +static int iscsi_prep_ecdb_ahs(struct iscsi_task *task) { - struct scsi_cmnd *cmd = ctask->sc; + struct scsi_cmnd *cmd = task->sc; unsigned rlen, pad_len; unsigned short ahslength; struct iscsi_ecdb_ahdr *ecdb_ahdr; int rc; - ecdb_ahdr = iscsi_next_hdr(ctask); + ecdb_ahdr = iscsi_next_hdr(task); rlen = cmd->cmd_len - ISCSI_CDB_SIZE; BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb)); @@ -150,7 +150,7 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask) pad_len = iscsi_padding(rlen); - rc = iscsi_add_hdr(ctask, sizeof(ecdb_ahdr->ahslength) + + rc = iscsi_add_hdr(task, sizeof(ecdb_ahdr->ahslength) + sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len); if (rc) return rc; @@ -165,19 +165,19 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask) debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d " "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n", - cmd->cmd_len, rlen, pad_len, ahslength, ctask->hdr_len); + cmd->cmd_len, rlen, pad_len, ahslength, task->hdr_len); return 0; } -static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask) +static int iscsi_prep_bidi_ahs(struct iscsi_task *task) { - struct scsi_cmnd *sc = ctask->sc; + struct scsi_cmnd *sc = task->sc; struct iscsi_rlength_ahdr *rlen_ahdr; int rc; - rlen_ahdr = iscsi_next_hdr(ctask); - rc = iscsi_add_hdr(ctask, sizeof(*rlen_ahdr)); + rlen_ahdr = iscsi_next_hdr(task); + rc = iscsi_add_hdr(task, sizeof(*rlen_ahdr)); if (rc) return rc; @@ -197,28 +197,28 @@ static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask) /** * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu - * @ctask: iscsi task + * @task: iscsi task * * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set * fields like dlength or final based on how much data it sends */ -static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) +static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) { - struct iscsi_conn *conn = ctask->conn; + struct iscsi_conn *conn = task->conn; struct iscsi_session *session = conn->session; - struct iscsi_cmd *hdr = ctask->hdr; - struct scsi_cmnd *sc = ctask->sc; + struct iscsi_cmd *hdr = task->hdr; + struct scsi_cmnd *sc = task->sc; unsigned hdrlength, cmd_len; int rc; - ctask->hdr_len = 0; - rc = iscsi_add_hdr(ctask, sizeof(*hdr)); + task->hdr_len = 0; + rc = iscsi_add_hdr(task, sizeof(*hdr)); if (rc) return rc; hdr->opcode = ISCSI_OP_SCSI_CMD; hdr->flags = ISCSI_ATTR_SIMPLE; int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); - hdr->itt = build_itt(ctask->itt, session->age); + hdr->itt = build_itt(task->itt, session->age); hdr->cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); @@ -226,17 +226,17 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) if (cmd_len < ISCSI_CDB_SIZE) memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len); else if (cmd_len > ISCSI_CDB_SIZE) { - rc = iscsi_prep_ecdb_ahs(ctask); + rc = iscsi_prep_ecdb_ahs(task); if (rc) return rc; cmd_len = ISCSI_CDB_SIZE; } memcpy(hdr->cdb, sc->cmnd, cmd_len); - ctask->imm_count = 0; + task->imm_count = 0; if (scsi_bidi_cmnd(sc)) { hdr->flags |= ISCSI_FLAG_CMD_READ; - rc = iscsi_prep_bidi_ahs(ctask); + rc = iscsi_prep_bidi_ahs(task); if (rc) return rc; } @@ -258,28 +258,28 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) * * pad_count bytes to be sent as zero-padding */ - ctask->unsol_count = 0; - ctask->unsol_offset = 0; - ctask->unsol_datasn = 0; + task->unsol_count = 0; + task->unsol_offset = 0; + task->unsol_datasn = 0; if (session->imm_data_en) { if (out_len >= session->first_burst) - ctask->imm_count = min(session->first_burst, + task->imm_count = min(session->first_burst, conn->max_xmit_dlength); else - ctask->imm_count = min(out_len, + task->imm_count = min(out_len, conn->max_xmit_dlength); - hton24(hdr->dlength, ctask->imm_count); + hton24(hdr->dlength, task->imm_count); } else zero_data(hdr->dlength); if (!session->initial_r2t_en) { - ctask->unsol_count = min(session->first_burst, out_len) - - ctask->imm_count; - ctask->unsol_offset = ctask->imm_count; + task->unsol_count = min(session->first_burst, out_len) + - task->imm_count; + task->unsol_offset = task->imm_count; } - if (!ctask->unsol_count) + if (!task->unsol_count) /* No unsolicit Data-Out's */ hdr->flags |= ISCSI_FLAG_CMD_FINAL; } else { @@ -292,7 +292,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) } /* calculate size of additional header segments (AHSs) */ - hdrlength = ctask->hdr_len - sizeof(*hdr); + hdrlength = task->hdr_len - sizeof(*hdr); WARN_ON(hdrlength & (ISCSI_PAD_LEN-1)); hdrlength /= ISCSI_PAD_LEN; @@ -301,17 +301,17 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) hdr->hlength = hdrlength & 0xFF; if (conn->session->tt->init_task && - conn->session->tt->init_task(ctask)) + conn->session->tt->init_task(task)) return -EIO; - ctask->state = ISCSI_TASK_RUNNING; - list_move_tail(&ctask->running, &conn->run_list); + task->state = ISCSI_TASK_RUNNING; + list_move_tail(&task->running, &conn->run_list); conn->scsicmd_pdus_cnt++; debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " "bidi_len %d cmdsn %d win %d]\n", scsi_bidi_cmnd(sc) ? "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ? - "write" : "read", conn->id, sc, sc->cmnd[0], ctask->itt, + "write" : "read", conn->id, sc, sc->cmnd[0], task->itt, scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); @@ -320,37 +320,37 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) /** * iscsi_complete_command - finish a task - * @ctask: iscsi cmd task + * @task: iscsi cmd task * * Must be called with session lock. * This function returns the scsi command to scsi-ml or cleans * up mgmt tasks then returns the task to the pool. */ -static void iscsi_complete_command(struct iscsi_cmd_task *ctask) +static void iscsi_complete_command(struct iscsi_task *task) { - struct iscsi_conn *conn = ctask->conn; + struct iscsi_conn *conn = task->conn; struct iscsi_session *session = conn->session; - struct scsi_cmnd *sc = ctask->sc; + struct scsi_cmnd *sc = task->sc; - list_del_init(&ctask->running); - ctask->state = ISCSI_TASK_COMPLETED; - ctask->sc = NULL; + list_del_init(&task->running); + task->state = ISCSI_TASK_COMPLETED; + task->sc = NULL; - if (conn->ctask == ctask) - conn->ctask = NULL; + if (conn->task == task) + conn->task = NULL; /* - * login ctask is preallocated so do not free + * login task is preallocated so do not free */ - if (conn->login_ctask == ctask) + if (conn->login_task == task) return; - __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + __kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*)); - if (conn->ping_ctask == ctask) - conn->ping_ctask = NULL; + if (conn->ping_task == task) + conn->ping_task = NULL; if (sc) { - ctask->sc = NULL; + task->sc = NULL; /* SCSI eh reuses commands to verify us */ sc->SCp.ptr = NULL; /* @@ -362,47 +362,47 @@ static void iscsi_complete_command(struct iscsi_cmd_task *ctask) } } -static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask) +static void __iscsi_get_task(struct iscsi_task *task) { - atomic_inc(&ctask->refcount); + atomic_inc(&task->refcount); } -static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask) +static void __iscsi_put_task(struct iscsi_task *task) { - if (atomic_dec_and_test(&ctask->refcount)) - iscsi_complete_command(ctask); + if (atomic_dec_and_test(&task->refcount)) + iscsi_complete_command(task); } -void iscsi_put_ctask(struct iscsi_cmd_task *ctask) +void iscsi_put_task(struct iscsi_task *task) { - struct iscsi_session *session = ctask->conn->session; + struct iscsi_session *session = task->conn->session; spin_lock_bh(&session->lock); - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); spin_unlock_bh(&session->lock); } -EXPORT_SYMBOL_GPL(iscsi_put_ctask); +EXPORT_SYMBOL_GPL(iscsi_put_task); /* * session lock must be held */ -static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, +static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task, int err) { struct scsi_cmnd *sc; - sc = ctask->sc; + sc = task->sc; if (!sc) return; - if (ctask->state == ISCSI_TASK_PENDING) + if (task->state == ISCSI_TASK_PENDING) /* * cmd never made it to the xmit thread, so we should not count * the cmd in the sequencing */ conn->session->queued_cmdsn--; else - conn->session->tt->cleanup_task(conn, ctask); + conn->session->tt->cleanup_task(conn, task); sc->result = err; @@ -413,17 +413,17 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, scsi_in(sc)->resid = scsi_in(sc)->length; } - if (conn->ctask == ctask) - conn->ctask = NULL; + if (conn->task == task) + conn->task = NULL; /* release ref from queuecommand */ - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); } static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) + struct iscsi_task *task) { struct iscsi_session *session = conn->session; - struct iscsi_hdr *hdr = (struct iscsi_hdr *)ctask->hdr; + struct iscsi_hdr *hdr = (struct iscsi_hdr *)task->hdr; struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; if (conn->session->state == ISCSI_STATE_LOGGING_OUT) @@ -437,7 +437,7 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, */ nop->cmdsn = cpu_to_be32(session->cmdsn); if (hdr->itt != RESERVED_ITT) { - hdr->itt = build_itt(ctask->itt, session->age); + hdr->itt = build_itt(task->itt, session->age); /* * TODO: We always use immediate, so we never hit this. * If we start to send tmfs or nops as non-immediate then @@ -451,24 +451,24 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, } if (session->tt->init_task) - session->tt->init_task(ctask); + session->tt->init_task(task); if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) session->state = ISCSI_STATE_LOGGING_OUT; - list_move_tail(&ctask->running, &conn->mgmt_run_list); + list_move_tail(&task->running, &conn->mgmt_run_list); debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, - ctask->data_count); + task->data_count); return 0; } -static struct iscsi_cmd_task * +static struct iscsi_task * __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size) { struct iscsi_session *session = conn->session; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; if (session->state == ISCSI_STATE_TERMINATE) return NULL; @@ -481,18 +481,18 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * Same task can be used. Same ITT must be used. * Note that login_task is preallocated at conn_create(). */ - ctask = conn->login_ctask; + task = conn->login_task; else { BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); if (!__kfifo_get(session->cmdpool.queue, - (void*)&ctask, sizeof(void*))) + (void*)&task, sizeof(void*))) return NULL; if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) && hdr->ttt == RESERVED_ITT) { - conn->ping_ctask = ctask; + conn->ping_task = task; conn->last_ping = jiffies; } } @@ -501,33 +501,33 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * released by the lld when it has transmitted the task for * pdus we do not expect a response for. */ - atomic_set(&ctask->refcount, 1); - ctask->conn = conn; - ctask->sc = NULL; + atomic_set(&task->refcount, 1); + task->conn = conn; + task->sc = NULL; if (data_size) { - memcpy(ctask->data, data, data_size); - ctask->data_count = data_size; + memcpy(task->data, data, data_size); + task->data_count = data_size; } else - ctask->data_count = 0; + task->data_count = 0; - memcpy(ctask->hdr, hdr, sizeof(struct iscsi_hdr)); - INIT_LIST_HEAD(&ctask->running); - list_add_tail(&ctask->running, &conn->mgmtqueue); + memcpy(task->hdr, hdr, sizeof(struct iscsi_hdr)); + INIT_LIST_HEAD(&task->running); + list_add_tail(&task->running, &conn->mgmtqueue); if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { - if (iscsi_prep_mgmt_task(conn, ctask)) { - __iscsi_put_ctask(ctask); + if (iscsi_prep_mgmt_task(conn, task)) { + __iscsi_put_task(task); return NULL; } - if (session->tt->xmit_task(ctask)) - ctask = NULL; + if (session->tt->xmit_task(task)) + task = NULL; } else scsi_queue_work(conn->session->host, &conn->xmitwork); - return ctask; + return task; } int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, @@ -549,20 +549,20 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); * iscsi_cmd_rsp - SCSI Command Response processing * @conn: iscsi connection * @hdr: iscsi header - * @ctask: scsi command task + * @task: scsi command task * @data: cmd data buffer * @datalen: len of buffer * * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and - * then completes the command and ctask. + * then completes the command and task. **/ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - struct iscsi_cmd_task *ctask, char *data, + struct iscsi_task *task, char *data, int datalen) { struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)hdr; struct iscsi_session *session = conn->session; - struct scsi_cmnd *sc = ctask->sc; + struct scsi_cmnd *sc = task->sc; iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; @@ -622,10 +622,10 @@ invalid_datalen: } out: debug_scsi("done [sc %lx res %d itt 0x%x]\n", - (long)sc, sc->result, ctask->itt); + (long)sc, sc->result, task->itt); conn->scsirsp_pdus_cnt++; - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); } static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) @@ -650,9 +650,9 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) { struct iscsi_nopout hdr; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; - if (!rhdr && conn->ping_ctask) + if (!rhdr && conn->ping_task) return; memset(&hdr, 0, sizeof(struct iscsi_nopout)); @@ -666,8 +666,8 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) } else hdr.ttt = RESERVED_ITT; - ctask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); - if (!ctask) + task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); + if (!task) iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); } @@ -712,7 +712,7 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, { struct iscsi_session *session = conn->session; int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; uint32_t itt; conn->last_recv = jiffies; @@ -758,27 +758,27 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto out; } - ctask = session->cmds[itt]; + task = session->cmds[itt]; switch(opcode) { case ISCSI_OP_SCSI_CMD_RSP: - if (!ctask->sc) { + if (!task->sc) { rc = ISCSI_ERR_NO_SCSI_CMD; break; } - BUG_ON((void*)ctask != ctask->sc->SCp.ptr); - iscsi_scsi_cmd_rsp(conn, hdr, ctask, data, datalen); + BUG_ON((void*)task != task->sc->SCp.ptr); + iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); break; case ISCSI_OP_SCSI_DATA_IN: - if (!ctask->sc) { + if (!task->sc) { rc = ISCSI_ERR_NO_SCSI_CMD; break; } - BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + BUG_ON((void*)task != task->sc->SCp.ptr); if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { conn->scsirsp_pdus_cnt++; iscsi_update_cmdsn(session, (struct iscsi_nopin*) hdr); - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); } break; case ISCSI_OP_R2T: @@ -808,7 +808,7 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } iscsi_tmf_rsp(conn, hdr); - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); break; case ISCSI_OP_NOOP_IN: iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); @@ -818,13 +818,15 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - if (conn->ping_ctask != ctask) + if (conn->ping_task != task) /* * If this is not in response to one of our * nops then it must be from userspace. */ goto recv_pdu; - __iscsi_put_ctask(ctask); + + mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout); + __iscsi_put_task(task); break; default: rc = ISCSI_ERR_BAD_OPCODE; @@ -836,7 +838,7 @@ out: recv_pdu: if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) rc = ISCSI_ERR_CONN_FAILED; - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); return rc; } @@ -855,7 +857,7 @@ EXPORT_SYMBOL_GPL(iscsi_complete_pdu); int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) { struct iscsi_session *session = conn->session; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; uint32_t i; if (itt == RESERVED_ITT) @@ -878,11 +880,11 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) return ISCSI_ERR_BAD_ITT; } - ctask = session->cmds[i]; - if (ctask->sc && ctask->sc->SCp.phase != session->age) { + task = session->cmds[i]; + if (task->sc && task->sc->SCp.phase != session->age) { iscsi_conn_printk(KERN_ERR, conn, - "iscsi: ctask's session age %d, " - "expected %d\n", ctask->sc->SCp.phase, + "iscsi: task's session age %d, " + "expected %d\n", task->sc->SCp.phase, session->age); return ISCSI_ERR_SESSION_FAILED; } @@ -890,11 +892,11 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) } EXPORT_SYMBOL_GPL(iscsi_verify_itt); -struct iscsi_cmd_task * +struct iscsi_task * iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) { struct iscsi_session *session = conn->session; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; uint32_t i; if (iscsi_verify_itt(conn, itt)) @@ -907,14 +909,14 @@ iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) if (i >= session->cmds_max) return NULL; - ctask = session->cmds[i]; - if (!ctask->sc) + task = session->cmds[i]; + if (!task->sc) return NULL; - if (ctask->sc->SCp.phase != session->age) + if (task->sc->SCp.phase != session->age) return NULL; - return ctask; + return task; } EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); @@ -955,38 +957,38 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) return 0; } -static int iscsi_xmit_ctask(struct iscsi_conn *conn) +static int iscsi_xmit_task(struct iscsi_conn *conn) { - struct iscsi_cmd_task *ctask = conn->ctask; + struct iscsi_task *task = conn->task; int rc; - __iscsi_get_ctask(ctask); + __iscsi_get_task(task); spin_unlock_bh(&conn->session->lock); - rc = conn->session->tt->xmit_task(ctask); + rc = conn->session->tt->xmit_task(task); spin_lock_bh(&conn->session->lock); - __iscsi_put_ctask(ctask); + __iscsi_put_task(task); if (!rc) - /* done with this ctask */ - conn->ctask = NULL; + /* done with this task */ + conn->task = NULL; return rc; } /** - * iscsi_requeue_ctask - requeue ctask to run from session workqueue - * @ctask: ctask to requeue + * iscsi_requeue_task - requeue task to run from session workqueue + * @task: task to requeue * - * LLDs that need to run a ctask from the session workqueue should call + * LLDs that need to run a task from the session workqueue should call * this. The session lock must be held. This should only be called * by software drivers. */ -void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask) +void iscsi_requeue_task(struct iscsi_task *task) { - struct iscsi_conn *conn = ctask->conn; + struct iscsi_conn *conn = task->conn; - list_move_tail(&ctask->running, &conn->requeue); + list_move_tail(&task->running, &conn->requeue); scsi_queue_work(conn->session->host, &conn->xmitwork); } -EXPORT_SYMBOL_GPL(iscsi_requeue_ctask); +EXPORT_SYMBOL_GPL(iscsi_requeue_task); /** * iscsi_data_xmit - xmit any command into the scheduled connection @@ -1008,8 +1010,8 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) return -ENODATA; } - if (conn->ctask) { - rc = iscsi_xmit_ctask(conn); + if (conn->task) { + rc = iscsi_xmit_task(conn); if (rc) goto again; } @@ -1021,14 +1023,14 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) */ check_mgmt: while (!list_empty(&conn->mgmtqueue)) { - conn->ctask = list_entry(conn->mgmtqueue.next, - struct iscsi_cmd_task, running); - if (iscsi_prep_mgmt_task(conn, conn->ctask)) { - __iscsi_put_ctask(conn->ctask); - conn->ctask = NULL; + conn->task = list_entry(conn->mgmtqueue.next, + struct iscsi_task, running); + if (iscsi_prep_mgmt_task(conn, conn->task)) { + __iscsi_put_task(conn->task); + conn->task = NULL; continue; } - rc = iscsi_xmit_ctask(conn); + rc = iscsi_xmit_task(conn); if (rc) goto again; } @@ -1038,21 +1040,21 @@ check_mgmt: if (conn->tmf_state == TMF_QUEUED) break; - conn->ctask = list_entry(conn->xmitqueue.next, - struct iscsi_cmd_task, running); + conn->task = list_entry(conn->xmitqueue.next, + struct iscsi_task, running); if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { - fail_command(conn, conn->ctask, DID_IMM_RETRY << 16); + fail_command(conn, conn->task, DID_IMM_RETRY << 16); continue; } - if (iscsi_prep_scsi_cmd_pdu(conn->ctask)) { - fail_command(conn, conn->ctask, DID_ABORT << 16); + if (iscsi_prep_scsi_cmd_pdu(conn->task)) { + fail_command(conn, conn->task, DID_ABORT << 16); continue; } - rc = iscsi_xmit_ctask(conn); + rc = iscsi_xmit_task(conn); if (rc) goto again; /* - * we could continuously get new ctask requests so + * we could continuously get new task requests so * we need to check the mgmt queue for nops that need to * be sent to aviod starvation */ @@ -1070,11 +1072,11 @@ check_mgmt: if (conn->session->state == ISCSI_STATE_LOGGING_OUT) break; - conn->ctask = list_entry(conn->requeue.next, - struct iscsi_cmd_task, running); - conn->ctask->state = ISCSI_TASK_RUNNING; + conn->task = list_entry(conn->requeue.next, + struct iscsi_task, running); + conn->task->state = ISCSI_TASK_RUNNING; list_move_tail(conn->requeue.next, &conn->run_list); - rc = iscsi_xmit_ctask(conn); + rc = iscsi_xmit_task(conn); if (rc) goto again; if (!list_empty(&conn->mgmtqueue)) @@ -1123,7 +1125,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) int reason = 0; struct iscsi_session *session; struct iscsi_conn *conn; - struct iscsi_cmd_task *ctask = NULL; + struct iscsi_task *task = NULL; sc->scsi_done = done; sc->result = 0; @@ -1191,31 +1193,31 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) goto reject; } - if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, + if (!__kfifo_get(session->cmdpool.queue, (void*)&task, sizeof(void*))) { reason = FAILURE_OOM; goto reject; } sc->SCp.phase = session->age; - sc->SCp.ptr = (char *)ctask; + sc->SCp.ptr = (char *)task; - atomic_set(&ctask->refcount, 1); - ctask->state = ISCSI_TASK_PENDING; - ctask->conn = conn; - ctask->sc = sc; - INIT_LIST_HEAD(&ctask->running); - list_add_tail(&ctask->running, &conn->xmitqueue); + atomic_set(&task->refcount, 1); + task->state = ISCSI_TASK_PENDING; + task->conn = conn; + task->sc = sc; + INIT_LIST_HEAD(&task->running); + list_add_tail(&task->running, &conn->xmitqueue); if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { - if (iscsi_prep_scsi_cmd_pdu(ctask)) { + if (iscsi_prep_scsi_cmd_pdu(task)) { sc->result = DID_ABORT << 16; sc->scsi_done = NULL; - iscsi_complete_command(ctask); + iscsi_complete_command(task); goto fault; } - if (session->tt->xmit_task(ctask)) { + if (session->tt->xmit_task(task)) { sc->scsi_done = NULL; - iscsi_complete_command(ctask); + iscsi_complete_command(task); reason = FAILURE_SESSION_NOT_READY; goto reject; } @@ -1336,16 +1338,16 @@ static void iscsi_tmf_timedout(unsigned long data) spin_unlock(&session->lock); } -static int iscsi_exec_ctask_mgmt_fn(struct iscsi_conn *conn, +static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, struct iscsi_tm *hdr, int age, int timeout) { struct iscsi_session *session = conn->session; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; - ctask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, + task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); - if (!ctask) { + if (!task) { spin_unlock_bh(&session->lock); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); spin_lock_bh(&session->lock); @@ -1379,7 +1381,7 @@ static int iscsi_exec_ctask_mgmt_fn(struct iscsi_conn *conn, mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); - /* if the session drops it will clean up the ctask */ + /* if the session drops it will clean up the task */ if (age != session->age || session->state != ISCSI_STATE_LOGGED_IN) return -ENOTCONN; @@ -1393,34 +1395,34 @@ static int iscsi_exec_ctask_mgmt_fn(struct iscsi_conn *conn, static void fail_all_commands(struct iscsi_conn *conn, unsigned lun, int error) { - struct iscsi_cmd_task *ctask, *tmp; + struct iscsi_task *task, *tmp; - if (conn->ctask && (conn->ctask->sc->device->lun == lun || lun == -1)) - conn->ctask = NULL; + if (conn->task && (conn->task->sc->device->lun == lun || lun == -1)) + conn->task = NULL; /* flush pending */ - list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) { - if (lun == ctask->sc->device->lun || lun == -1) { + list_for_each_entry_safe(task, tmp, &conn->xmitqueue, running) { + if (lun == task->sc->device->lun || lun == -1) { debug_scsi("failing pending sc %p itt 0x%x\n", - ctask->sc, ctask->itt); - fail_command(conn, ctask, error << 16); + task->sc, task->itt); + fail_command(conn, task, error << 16); } } - list_for_each_entry_safe(ctask, tmp, &conn->requeue, running) { - if (lun == ctask->sc->device->lun || lun == -1) { + list_for_each_entry_safe(task, tmp, &conn->requeue, running) { + if (lun == task->sc->device->lun || lun == -1) { debug_scsi("failing requeued sc %p itt 0x%x\n", - ctask->sc, ctask->itt); - fail_command(conn, ctask, error << 16); + task->sc, task->itt); + fail_command(conn, task, error << 16); } } /* fail all other running */ - list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) { - if (lun == ctask->sc->device->lun || lun == -1) { + list_for_each_entry_safe(task, tmp, &conn->run_list, running) { + if (lun == task->sc->device->lun || lun == -1) { debug_scsi("failing in progress sc %p itt 0x%x\n", - ctask->sc, ctask->itt); - fail_command(conn, ctask, DID_BUS_BUSY << 16); + task->sc, task->itt); + fail_command(conn, task, DID_BUS_BUSY << 16); } } } @@ -1486,7 +1488,7 @@ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) jiffies)) rc = EH_RESET_TIMER; /* if in the middle of checking the transport then give us more time */ - if (conn->ping_ctask) + if (conn->ping_task) rc = EH_RESET_TIMER; done: spin_unlock(&session->lock); @@ -1510,7 +1512,7 @@ static void iscsi_check_transport_timeouts(unsigned long data) recv_timeout *= HZ; last_recv = conn->last_recv; - if (conn->ping_ctask && + if (conn->ping_task && time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), jiffies)) { iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " @@ -1536,16 +1538,16 @@ done: spin_unlock(&session->lock); } -static void iscsi_prep_abort_ctask_pdu(struct iscsi_cmd_task *ctask, +static void iscsi_prep_abort_task_pdu(struct iscsi_task *task, struct iscsi_tm *hdr) { memset(hdr, 0, sizeof(*hdr)); hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; hdr->flags = ISCSI_TM_FUNC_ABORT_TASK & ISCSI_FLAG_TM_FUNC_MASK; hdr->flags |= ISCSI_FLAG_CMD_FINAL; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->rtt = ctask->hdr->itt; - hdr->refcmdsn = ctask->hdr->cmdsn; + memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun)); + hdr->rtt = task->hdr->itt; + hdr->refcmdsn = task->hdr->cmdsn; } int iscsi_eh_abort(struct scsi_cmnd *sc) @@ -1553,7 +1555,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) struct iscsi_cls_session *cls_session; struct iscsi_session *session; struct iscsi_conn *conn; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; struct iscsi_tm *hdr; int rc, age; @@ -1588,17 +1590,17 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) conn->eh_abort_cnt++; age = session->age; - ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; - debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); + task = (struct iscsi_task *)sc->SCp.ptr; + debug_scsi("aborting [sc %p itt 0x%x]\n", sc, task->itt); - /* ctask completed before time out */ - if (!ctask->sc) { + /* task completed before time out */ + if (!task->sc) { debug_scsi("sc completed while abort in progress\n"); goto success; } - if (ctask->state == ISCSI_TASK_PENDING) { - fail_command(conn, ctask, DID_ABORT << 16); + if (task->state == ISCSI_TASK_PENDING) { + fail_command(conn, task, DID_ABORT << 16); goto success; } @@ -1608,9 +1610,9 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) conn->tmf_state = TMF_QUEUED; hdr = &conn->tmhdr; - iscsi_prep_abort_ctask_pdu(ctask, hdr); + iscsi_prep_abort_task_pdu(task, hdr); - if (iscsi_exec_ctask_mgmt_fn(conn, hdr, age, session->abort_timeout)) { + if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) { rc = FAILED; goto failed; } @@ -1620,11 +1622,11 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) spin_unlock_bh(&session->lock); iscsi_suspend_tx(conn); /* - * clean up ctask if aborted. grab the recv lock as a writer + * clean up task if aborted. grab the recv lock as a writer */ write_lock_bh(conn->recv_lock); spin_lock(&session->lock); - fail_command(conn, ctask, DID_ABORT << 16); + fail_command(conn, task, DID_ABORT << 16); conn->tmf_state = TMF_INITIAL; spin_unlock(&session->lock); write_unlock_bh(conn->recv_lock); @@ -1637,7 +1639,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) case TMF_NOT_FOUND: if (!sc->SCp.ptr) { conn->tmf_state = TMF_INITIAL; - /* ctask completed before tmf abort response */ + /* task completed before tmf abort response */ debug_scsi("sc completed while abort in progress\n"); goto success; } @@ -1650,7 +1652,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) success: spin_unlock_bh(&session->lock); success_unlocked: - debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, task->itt); mutex_unlock(&session->eh_mutex); return SUCCESS; @@ -1658,7 +1660,7 @@ failed: spin_unlock_bh(&session->lock); failed_unlocked: debug_scsi("abort failed [sc %p itt 0x%x]\n", sc, - ctask ? ctask->itt : 0); + task ? task->itt : 0); mutex_unlock(&session->eh_mutex); return FAILED; } @@ -1705,7 +1707,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) hdr = &conn->tmhdr; iscsi_prep_lun_reset_pdu(sc, hdr); - if (iscsi_exec_ctask_mgmt_fn(conn, hdr, session->age, + if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, session->lu_reset_timeout)) { rc = FAILED; goto unlock; @@ -1886,7 +1888,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); * @iscsit: iscsi transport template * @shost: scsi host * @cmds_max: session can queue - * @cmd_ctask_size: LLD ctask private data size + * @cmd_task_size: LLD task private data size * @initial_cmdsn: initial CmdSN * * This can be used by software iscsi_transports that allocate @@ -1894,7 +1896,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); */ struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, - uint16_t scsi_cmds_max, int cmd_ctask_size, + uint16_t scsi_cmds_max, int cmd_task_size, uint32_t initial_cmdsn) { struct iscsi_session *session; @@ -1902,7 +1904,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, int cmd_i, cmds_max; /* - * The iscsi layer needs some ctasks for nop handling and tmfs. + * The iscsi layer needs some tasks for nop handling and tmfs. */ if (scsi_cmds_max < 1) scsi_cmds_max = ISCSI_MGMT_CMDS_MAX; @@ -1939,17 +1941,17 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, /* initialize SCSI PDU commands pool */ if (iscsi_pool_init(&session->cmdpool, session->cmds_max, (void***)&session->cmds, - cmd_ctask_size + sizeof(struct iscsi_cmd_task))) + cmd_task_size + sizeof(struct iscsi_task))) goto cmdpool_alloc_fail; /* pre-format cmds pool with ITT */ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; + struct iscsi_task *task = session->cmds[cmd_i]; - if (cmd_ctask_size) - ctask->dd_data = &ctask[1]; - ctask->itt = cmd_i; - INIT_LIST_HEAD(&ctask->running); + if (cmd_task_size) + task->dd_data = &task[1]; + task->itt = cmd_i; + INIT_LIST_HEAD(&task->running); } if (!try_module_get(iscsit->owner)) @@ -2035,30 +2037,30 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, INIT_LIST_HEAD(&conn->requeue); INIT_WORK(&conn->xmitwork, iscsi_xmitworker); - /* allocate login_ctask used for the login/text sequences */ + /* allocate login_task used for the login/text sequences */ spin_lock_bh(&session->lock); if (!__kfifo_get(session->cmdpool.queue, - (void*)&conn->login_ctask, + (void*)&conn->login_task, sizeof(void*))) { spin_unlock_bh(&session->lock); - goto login_ctask_alloc_fail; + goto login_task_alloc_fail; } spin_unlock_bh(&session->lock); data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); if (!data) - goto login_ctask_data_alloc_fail; - conn->login_ctask->data = conn->data = data; + goto login_task_data_alloc_fail; + conn->login_task->data = conn->data = data; init_timer(&conn->tmf_timer); init_waitqueue_head(&conn->ehwait); return cls_conn; -login_ctask_data_alloc_fail: - __kfifo_put(session->cmdpool.queue, (void*)&conn->login_ctask, +login_task_data_alloc_fail: + __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); -login_ctask_alloc_fail: +login_task_alloc_fail: iscsi_destroy_conn(cls_conn); return NULL; } @@ -2118,7 +2120,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) spin_lock_bh(&session->lock); kfree(conn->data); kfree(conn->persistent_address); - __kfifo_put(session->cmdpool.queue, (void*)&conn->login_ctask, + __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, sizeof(void*)); if (session->leadconn == conn) session->leadconn = NULL; @@ -2199,23 +2201,23 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start); static void flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn) { - struct iscsi_cmd_task *ctask, *tmp; + struct iscsi_task *task, *tmp; /* handle pending */ - list_for_each_entry_safe(ctask, tmp, &conn->mgmtqueue, running) { - debug_scsi("flushing pending mgmt ctask itt 0x%x\n", ctask->itt); - /* release ref from prep ctask */ - __iscsi_put_ctask(ctask); + list_for_each_entry_safe(task, tmp, &conn->mgmtqueue, running) { + debug_scsi("flushing pending mgmt task itt 0x%x\n", task->itt); + /* release ref from prep task */ + __iscsi_put_task(task); } /* handle running */ - list_for_each_entry_safe(ctask, tmp, &conn->mgmt_run_list, running) { - debug_scsi("flushing running mgmt ctask itt 0x%x\n", ctask->itt); - /* release ref from prep ctask */ - __iscsi_put_ctask(ctask); + list_for_each_entry_safe(task, tmp, &conn->mgmt_run_list, running) { + debug_scsi("flushing running mgmt task itt 0x%x\n", task->itt); + /* release ref from prep task */ + __iscsi_put_task(task); } - conn->ctask = NULL; + conn->task = NULL; } static void iscsi_start_session_recovery(struct iscsi_session *session, @@ -2246,7 +2248,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, /* * When this is called for the in_login state, we only want to clean - * up the login ctask and connection. We do not need to block and set + * up the login task and connection. We do not need to block and set * the recovery state again */ if (flag == STOP_CONN_TERM) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index d1c3675..176353c 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -92,7 +92,7 @@ enum { ISCSI_TASK_RUNNING, }; -struct iscsi_cmd_task { +struct iscsi_task { /* * Because LLDs allocate their hdr differently, this is a pointer * and length to that storage. It must be setup at session @@ -120,9 +120,9 @@ struct iscsi_cmd_task { void *dd_data; /* driver/transport data */ }; -static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask) +static inline void* iscsi_next_hdr(struct iscsi_task *task) { - return (void*)ctask->hdr + ctask->hdr_len; + return (void*)task->hdr + task->hdr_len; } /* Connection's states */ @@ -151,7 +151,7 @@ struct iscsi_conn { unsigned long last_ping; int ping_timeout; int recv_timeout; - struct iscsi_cmd_task *ping_ctask; + struct iscsi_task *ping_task; /* iSCSI connection-wide sequencing */ uint32_t exp_statsn; @@ -167,8 +167,8 @@ struct iscsi_conn { * should always fit in this buffer */ char *data; - struct iscsi_cmd_task *login_ctask; /* mtask used for login/text */ - struct iscsi_cmd_task *ctask; /* xmit task in progress */ + struct iscsi_task *login_task; /* mtask used for login/text */ + struct iscsi_task *task; /* xmit task in progress */ /* xmit */ struct list_head mgmtqueue; /* mgmt (control) xmit queue */ @@ -285,7 +285,7 @@ struct iscsi_session { int scsi_cmds_max; /* max scsi commands */ int cmds_max; /* size of cmds array */ - struct iscsi_cmd_task **cmds; /* Original Cmds arr */ + struct iscsi_task **cmds; /* Original Cmds arr */ struct iscsi_pool cmdpool; /* PDU's pool */ }; @@ -365,16 +365,16 @@ extern void iscsi_suspend_tx(struct iscsi_conn *conn); * pdu and task processing */ extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); -extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *, +extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *, struct iscsi_data *hdr); extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, char *, int); extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); -extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); -extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); -extern void iscsi_put_ctask(struct iscsi_cmd_task *ctask); +extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); +extern void iscsi_requeue_task(struct iscsi_task *task); +extern void iscsi_put_task(struct iscsi_task *task); /* * generic helpers diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 3f24503..0553240 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -33,7 +33,7 @@ struct iscsi_transport; struct Scsi_Host; struct iscsi_cls_conn; struct iscsi_conn; -struct iscsi_cmd_task; +struct iscsi_task; struct sockaddr; /** @@ -112,10 +112,10 @@ struct iscsi_transport { char *data, uint32_t data_size); void (*get_stats) (struct iscsi_cls_conn *conn, struct iscsi_stats *stats); - int (*init_task) (struct iscsi_cmd_task *task); - int (*xmit_task) (struct iscsi_cmd_task *task); + int (*init_task) (struct iscsi_task *task); + int (*xmit_task) (struct iscsi_task *task); void (*cleanup_task) (struct iscsi_conn *conn, - struct iscsi_cmd_task *task); + struct iscsi_task *task); void (*session_recovery_timedout) (struct iscsi_cls_session *session); int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking, uint64_t *ep_handle); -- cgit v0.10.2 From 135a8ad4e09309d36dcb8b5c7f55db0b6a15b2d6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:10 -0500 Subject: [SCSI] iscsi_tcp: handle iscsi_cmd_task rename This converts iscsi_tcp to use the iscsi_task name. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 517bad1..33cd0ca 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -498,43 +498,43 @@ iscsi_tcp_data_recv_prep(struct iscsi_tcp_conn *tcp_conn) * must be called with session lock */ static void -iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_r2t_info *r2t; - /* nothing to do for mgmt ctasks */ - if (!ctask->sc) + /* nothing to do for mgmt tasks */ + if (!task->sc) return; - /* flush ctask's r2t queues */ - while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, + /* flush task's r2t queues */ + while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { + __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); - debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n"); + debug_scsi("iscsi_tcp_cleanup_task pending r2t dropped\n"); } - r2t = tcp_ctask->r2t; + r2t = tcp_task->r2t; if (r2t != NULL) { - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, + __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); - tcp_ctask->r2t = NULL; + tcp_task->r2t = NULL; } } /** * iscsi_data_rsp - SCSI Data-In Response processing * @conn: iscsi connection - * @ctask: scsi command ctask + * @task: scsi command task **/ static int -iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr; struct iscsi_session *session = conn->session; - struct scsi_cmnd *sc = ctask->sc; + struct scsi_cmnd *sc = task->sc; int datasn = be32_to_cpu(rhdr->datasn); unsigned total_in_length = scsi_in(sc)->length; @@ -542,18 +542,18 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) if (tcp_conn->in.datalen == 0) return 0; - if (tcp_ctask->exp_datasn != datasn) { - debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n", - __FUNCTION__, tcp_ctask->exp_datasn, datasn); + if (tcp_task->exp_datasn != datasn) { + debug_tcp("%s: task->exp_datasn(%d) != rhdr->datasn(%d)\n", + __FUNCTION__, tcp_task->exp_datasn, datasn); return ISCSI_ERR_DATASN; } - tcp_ctask->exp_datasn++; + tcp_task->exp_datasn++; - tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); - if (tcp_ctask->data_offset + tcp_conn->in.datalen > total_in_length) { + tcp_task->data_offset = be32_to_cpu(rhdr->offset); + if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) { debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", - __FUNCTION__, tcp_ctask->data_offset, + __FUNCTION__, tcp_task->data_offset, tcp_conn->in.datalen, total_in_length); return ISCSI_ERR_DATA_OFFSET; } @@ -582,7 +582,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) /** * iscsi_solicit_data_init - initialize first Data-Out * @conn: iscsi connection - * @ctask: scsi command ctask + * @task: scsi command task * @r2t: R2T info * * Notes: @@ -592,7 +592,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) * This function is called with connection lock taken. **/ static void -iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, +iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_task *task, struct iscsi_r2t_info *r2t) { struct iscsi_data *hdr; @@ -603,8 +603,8 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, hdr->datasn = cpu_to_be32(r2t->solicit_datasn); r2t->solicit_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun)); + hdr->itt = task->hdr->itt; hdr->exp_statsn = r2t->exp_statsn; hdr->offset = cpu_to_be32(r2t->data_offset); if (r2t->data_length > conn->max_xmit_dlength) { @@ -624,14 +624,14 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, /** * iscsi_r2t_rsp - iSCSI R2T Response processing * @conn: iscsi connection - * @ctask: scsi command ctask + * @task: scsi command task **/ static int -iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) { struct iscsi_r2t_info *r2t; struct iscsi_session *session = conn->session; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr; int r2tsn = be32_to_cpu(rhdr->r2tsn); @@ -644,23 +644,23 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) return ISCSI_ERR_DATALEN; } - if (tcp_ctask->exp_datasn != r2tsn){ - debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n", - __FUNCTION__, tcp_ctask->exp_datasn, r2tsn); + if (tcp_task->exp_datasn != r2tsn){ + debug_tcp("%s: task->exp_datasn(%d) != rhdr->r2tsn(%d)\n", + __FUNCTION__, tcp_task->exp_datasn, r2tsn); return ISCSI_ERR_R2TSN; } - /* fill-in new R2T associated with the ctask */ + /* fill-in new R2T associated with the task */ iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); - if (!ctask->sc || session->state != ISCSI_STATE_LOGGED_IN) { + if (!task->sc || session->state != ISCSI_STATE_LOGGED_IN) { iscsi_conn_printk(KERN_INFO, conn, "dropping R2T itt %d in recovery.\n", - ctask->itt); + task->itt); return 0; } - rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); + rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); BUG_ON(!rc); r2t->exp_statsn = rhdr->statsn; @@ -668,7 +668,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) if (r2t->data_length == 0) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with zero data len\n"); - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, + __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -679,12 +679,12 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) r2t->data_length, session->max_burst); r2t->data_offset = be32_to_cpu(rhdr->data_offset); - if (r2t->data_offset + r2t->data_length > scsi_out(ctask->sc)->length) { + if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with data len %u at offset %u " "and total length %d\n", r2t->data_length, - r2t->data_offset, scsi_out(ctask->sc)->length); - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, + r2t->data_offset, scsi_out(task->sc)->length); + __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; } @@ -692,13 +692,13 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) r2t->ttt = rhdr->ttt; /* no flip */ r2t->solicit_datasn = 0; - iscsi_solicit_data_init(conn, ctask, r2t); + iscsi_solicit_data_init(conn, task, r2t); - tcp_ctask->exp_datasn = r2tsn + 1; - __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); + tcp_task->exp_datasn = r2tsn + 1; + __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); conn->r2t_pdus_cnt++; - iscsi_requeue_ctask(ctask); + iscsi_requeue_task(task); return 0; } @@ -743,7 +743,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) int rc = 0, opcode, ahslen; struct iscsi_session *session = conn->session; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; /* verify PDU length */ tcp_conn->in.datalen = ntoh24(hdr->dlength); @@ -770,21 +770,21 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) switch(opcode) { case ISCSI_OP_SCSI_DATA_IN: - ctask = iscsi_itt_to_ctask(conn, hdr->itt); - if (!ctask) + task = iscsi_itt_to_ctask(conn, hdr->itt); + if (!task) return ISCSI_ERR_BAD_ITT; - if (!ctask->sc) + if (!task->sc) return ISCSI_ERR_NO_SCSI_CMD; spin_lock(&conn->session->lock); - rc = iscsi_data_rsp(conn, ctask); + rc = iscsi_data_rsp(conn, task); spin_unlock(&conn->session->lock); if (rc) return rc; if (tcp_conn->in.datalen) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_tcp_task *tcp_task = task->dd_data; struct hash_desc *rx_hash = NULL; - struct scsi_data_buffer *sdb = scsi_in(ctask->sc); + struct scsi_data_buffer *sdb = scsi_in(task->sc); /* * Setup copy of Data-In into the Scsi_Cmnd @@ -799,12 +799,12 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) debug_tcp("iscsi_tcp_begin_data_in(%p, offset=%d, " "datalen=%d)\n", tcp_conn, - tcp_ctask->data_offset, + tcp_task->data_offset, tcp_conn->in.datalen); return iscsi_segment_seek_sg(&tcp_conn->in.segment, sdb->table.sgl, sdb->table.nents, - tcp_ctask->data_offset, + tcp_task->data_offset, tcp_conn->in.datalen, iscsi_tcp_process_data_in, rx_hash); @@ -818,17 +818,17 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) rc = iscsi_complete_pdu(conn, hdr, NULL, 0); break; case ISCSI_OP_R2T: - ctask = iscsi_itt_to_ctask(conn, hdr->itt); - if (!ctask) + task = iscsi_itt_to_ctask(conn, hdr->itt); + if (!task) return ISCSI_ERR_BAD_ITT; - if (!ctask->sc) + if (!task->sc) return ISCSI_ERR_NO_SCSI_CMD; if (ahslen) rc = ISCSI_ERR_AHSLEN; - else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { + else if (task->sc->sc_data_direction == DMA_TO_DEVICE) { spin_lock(&session->lock); - rc = iscsi_r2t_rsp(conn, ctask); + rc = iscsi_r2t_rsp(conn, task); spin_unlock(&session->lock); } else rc = ISCSI_ERR_PROTO; @@ -1202,7 +1202,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr, size_t hdrlen) /* If header digest is enabled, compute the CRC and * place the digest into the same buffer. We make - * sure that both iscsi_tcp_cmd_task and mctask have + * sure that both iscsi_tcp_task and mtask have * sufficient room. */ if (conn->hdrdgst_en) { @@ -1277,7 +1277,7 @@ iscsi_tcp_send_linear_data_prepare(struct iscsi_conn *conn, void *data, /** * iscsi_solicit_data_cont - initialize next Data-Out * @conn: iscsi connection - * @ctask: scsi command ctask + * @task: scsi command task * @r2t: R2T info * @left: bytes left to transfer * @@ -1288,7 +1288,7 @@ iscsi_tcp_send_linear_data_prepare(struct iscsi_conn *conn, void *data, * Called under connection lock. **/ static int -iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, +iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_task *task, struct iscsi_r2t_info *r2t) { struct iscsi_data *hdr; @@ -1305,8 +1305,8 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, hdr->datasn = cpu_to_be32(r2t->solicit_datasn); r2t->solicit_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + memcpy(hdr->lun, task->hdr->lun, sizeof(hdr->lun)); + hdr->itt = task->hdr->itt; hdr->exp_statsn = r2t->exp_statsn; new_offset = r2t->data_offset + r2t->sent; hdr->offset = cpu_to_be32(new_offset); @@ -1326,73 +1326,73 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, /** * iscsi_tcp_task - Initialize iSCSI SCSI_READ or SCSI_WRITE commands * @conn: iscsi connection - * @ctask: scsi command ctask + * @task: scsi command task * @sc: scsi command **/ static int -iscsi_tcp_task_init(struct iscsi_cmd_task *ctask) +iscsi_tcp_task_init(struct iscsi_task *task) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_conn *conn = ctask->conn; - struct scsi_cmnd *sc = ctask->sc; + struct iscsi_tcp_task *tcp_task = task->dd_data; + struct iscsi_conn *conn = task->conn; + struct scsi_cmnd *sc = task->sc; int err; if (!sc) { /* - * mgmt ctasks do not have a scatterlist since they come + * mgmt tasks do not have a scatterlist since they come * in from the iscsi interface. */ - debug_scsi("mctask deq [cid %d itt 0x%x]\n", conn->id, - ctask->itt); + debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, + task->itt); /* Prepare PDU, optionally w/ immediate data */ - iscsi_tcp_send_hdr_prep(conn, ctask->hdr, sizeof(*ctask->hdr)); + iscsi_tcp_send_hdr_prep(conn, task->hdr, sizeof(*task->hdr)); /* If we have immediate data, attach a payload */ - if (ctask->data_count) - iscsi_tcp_send_linear_data_prepare(conn, ctask->data, - ctask->data_count); + if (task->data_count) + iscsi_tcp_send_linear_data_prepare(conn, task->data, + task->data_count); return 0; } - BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); - tcp_ctask->sent = 0; - tcp_ctask->exp_datasn = 0; + BUG_ON(__kfifo_len(tcp_task->r2tqueue)); + tcp_task->sent = 0; + tcp_task->exp_datasn = 0; /* Prepare PDU, optionally w/ immediate data */ - debug_scsi("ctask deq [cid %d itt 0x%x imm %d unsol %d]\n", - conn->id, ctask->itt, ctask->imm_count, - ctask->unsol_count); - iscsi_tcp_send_hdr_prep(conn, ctask->hdr, ctask->hdr_len); + debug_scsi("task deq [cid %d itt 0x%x imm %d unsol %d]\n", + conn->id, task->itt, task->imm_count, + task->unsol_count); + iscsi_tcp_send_hdr_prep(conn, task->hdr, task->hdr_len); - if (!ctask->imm_count) + if (!task->imm_count) return 0; /* If we have immediate data, attach a payload */ err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl, scsi_out(sc)->table.nents, - 0, ctask->imm_count); + 0, task->imm_count); if (err) return err; - tcp_ctask->sent += ctask->imm_count; - ctask->imm_count = 0; + tcp_task->sent += task->imm_count; + task->imm_count = 0; return 0; } /* - * iscsi_tcp_task_xmit - xmit normal PDU ctask - * @ctask: iscsi command ctask + * iscsi_tcp_task_xmit - xmit normal PDU task + * @task: iscsi command task * * We're expected to return 0 when everything was transmitted succesfully, * -EAGAIN if there's still data in the queue, or != 0 for any other kind * of error. */ static int -iscsi_tcp_task_xmit(struct iscsi_cmd_task *ctask) +iscsi_tcp_task_xmit(struct iscsi_task *task) { - struct iscsi_conn *conn = ctask->conn; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct scsi_cmnd *sc = ctask->sc; + struct iscsi_conn *conn = task->conn; + struct iscsi_tcp_task *tcp_task = task->dd_data; + struct scsi_cmnd *sc = task->sc; struct scsi_data_buffer *sdb; int rc = 0; @@ -1404,8 +1404,8 @@ flush: /* mgmt command */ if (!sc) { - if (ctask->hdr->itt == RESERVED_ITT) - iscsi_put_ctask(ctask); + if (task->hdr->itt == RESERVED_ITT) + iscsi_put_task(task); return 0; } @@ -1414,27 +1414,27 @@ flush: return 0; sdb = scsi_out(sc); - if (ctask->unsol_count != 0) { - struct iscsi_data *hdr = &tcp_ctask->unsol_dtask.hdr; + if (task->unsol_count != 0) { + struct iscsi_data *hdr = &tcp_task->unsol_dtask.hdr; /* Prepare a header for the unsolicited PDU. * The amount of data we want to send will be - * in ctask->data_count. + * in task->data_count. * FIXME: return the data count instead. */ - iscsi_prep_unsolicit_data_pdu(ctask, hdr); + iscsi_prep_unsolicit_data_pdu(task, hdr); debug_tcp("unsol dout [itt 0x%x doff %d dlen %d]\n", - ctask->itt, tcp_ctask->sent, ctask->data_count); + task->itt, tcp_task->sent, task->data_count); iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr)); rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl, - sdb->table.nents, tcp_ctask->sent, - ctask->data_count); + sdb->table.nents, tcp_task->sent, + task->data_count); if (rc) goto fail; - tcp_ctask->sent += ctask->data_count; - ctask->unsol_count -= ctask->data_count; + tcp_task->sent += task->data_count; + task->unsol_count -= task->data_count; goto flush; } else { struct iscsi_session *session = conn->session; @@ -1443,22 +1443,22 @@ flush: /* All unsolicited PDUs sent. Check for solicited PDUs. */ spin_lock_bh(&session->lock); - r2t = tcp_ctask->r2t; + r2t = tcp_task->r2t; if (r2t != NULL) { /* Continue with this R2T? */ - if (!iscsi_solicit_data_cont(conn, ctask, r2t)) { + if (!iscsi_solicit_data_cont(conn, task, r2t)) { debug_scsi(" done with r2t %p\n", r2t); - __kfifo_put(tcp_ctask->r2tpool.queue, + __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); - tcp_ctask->r2t = r2t = NULL; + tcp_task->r2t = r2t = NULL; } } if (r2t == NULL) { - __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, + __kfifo_get(tcp_task->r2tqueue, (void*)&tcp_task->r2t, sizeof(void*)); - r2t = tcp_ctask->r2t; + r2t = tcp_task->r2t; } spin_unlock_bh(&session->lock); @@ -1469,7 +1469,7 @@ flush: } debug_scsi("sol dout %p [dsn %d itt 0x%x doff %d dlen %d]\n", - r2t, r2t->solicit_datasn - 1, ctask->itt, + r2t, r2t->solicit_datasn - 1, task->itt, r2t->data_offset + r2t->sent, r2t->data_count); iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr, @@ -1481,7 +1481,7 @@ flush: r2t->data_count); if (rc) goto fail; - tcp_ctask->sent += r2t->data_count; + tcp_task->sent += r2t->data_count; r2t->sent += r2t->data_count; goto flush; } @@ -1698,11 +1698,11 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) int cmd_i; /* - * initialize per-ctask: R2T pool and xmit queue + * initialize per-task: R2T pool and xmit queue */ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_task *task = session->cmds[cmd_i]; + struct iscsi_tcp_task *tcp_task = task->dd_data; /* * pre-allocated x4 as much r2ts to handle race when @@ -1711,16 +1711,16 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) */ /* R2T pool */ - if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, NULL, + if (iscsi_pool_init(&tcp_task->r2tpool, session->max_r2t * 4, NULL, sizeof(struct iscsi_r2t_info))) { goto r2t_alloc_fail; } /* R2T xmit queue */ - tcp_ctask->r2tqueue = kfifo_alloc( + tcp_task->r2tqueue = kfifo_alloc( session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); - if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) { - iscsi_pool_free(&tcp_ctask->r2tpool); + if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) { + iscsi_pool_free(&tcp_task->r2tpool); goto r2t_alloc_fail; } } @@ -1729,11 +1729,11 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) r2t_alloc_fail: for (i = 0; i < cmd_i; i++) { - struct iscsi_cmd_task *ctask = session->cmds[i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_task *task = session->cmds[i]; + struct iscsi_tcp_task *tcp_task = task->dd_data; - kfifo_free(tcp_ctask->r2tqueue); - iscsi_pool_free(&tcp_ctask->r2tpool); + kfifo_free(tcp_task->r2tqueue); + iscsi_pool_free(&tcp_task->r2tpool); } return -ENOMEM; } @@ -1744,11 +1744,11 @@ iscsi_r2tpool_free(struct iscsi_session *session) int i; for (i = 0; i < session->cmds_max; i++) { - struct iscsi_cmd_task *ctask = session->cmds[i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_task *task = session->cmds[i]; + struct iscsi_tcp_task *tcp_task = task->dd_data; - kfifo_free(tcp_ctask->r2tqueue); - iscsi_pool_free(&tcp_ctask->r2tpool); + kfifo_free(tcp_task->r2tqueue); + iscsi_pool_free(&tcp_task->r2tpool); } } @@ -1867,7 +1867,7 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, *hostno = shost->host_no; cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max, - sizeof(struct iscsi_tcp_cmd_task), + sizeof(struct iscsi_tcp_task), initial_cmdsn); if (!cls_session) goto remove_host; @@ -1875,11 +1875,11 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, shost->can_queue = session->scsi_cmds_max; for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_task *task = session->cmds[cmd_i]; + struct iscsi_tcp_task *tcp_task = task->dd_data; - ctask->hdr = &tcp_ctask->hdr.cmd_hdr; - ctask->hdr_max = sizeof(tcp_ctask->hdr) - ISCSI_DIGEST_SIZE; + task->hdr = &tcp_task->hdr.cmd_hdr; + task->hdr_max = sizeof(tcp_task->hdr) - ISCSI_DIGEST_SIZE; } if (iscsi_r2tpool_alloc(session)) diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index c9c8633..498d8ca 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -114,7 +114,7 @@ struct iscsi_r2t_info { struct iscsi_data_task dtask; /* Data-Out header buf */ }; -struct iscsi_tcp_cmd_task { +struct iscsi_tcp_task { struct iscsi_hdr_buff { struct iscsi_cmd cmd_hdr; char hdrextbuf[ISCSI_MAX_AHS_SIZE + -- cgit v0.10.2 From 2261ec3d686e35c1a6088ab7f00a1d02b528b994 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:11 -0500 Subject: [SCSI] iser: handle iscsi_cmd_task rename This handles the iscsi_cmd_task rename and renames the iser cmd task to iser task. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index baecca1..86d9c42 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -124,33 +124,33 @@ error: /** - * iscsi_iser_task_init - Initialize ctask - * @ctask: iscsi ctask + * iscsi_iser_task_init - Initialize task + * @task: iscsi task * - * Initialize the ctask for the scsi command or mgmt command. + * Initialize the task for the scsi command or mgmt command. */ static int -iscsi_iser_task_init(struct iscsi_cmd_task *ctask) +iscsi_iser_task_init(struct iscsi_task *task) { - struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_iser_conn *iser_conn = task->conn->dd_data; + struct iscsi_iser_task *iser_task = task->dd_data; - /* mgmt ctask */ - if (!ctask->sc) { - iser_ctask->desc.data = ctask->data; + /* mgmt task */ + if (!task->sc) { + iser_task->desc.data = task->data; return 0; } - iser_ctask->command_sent = 0; - iser_ctask->iser_conn = iser_conn; - iser_ctask_rdma_init(iser_ctask); + iser_task->command_sent = 0; + iser_task->iser_conn = iser_conn; + iser_task_rdma_init(iser_task); return 0; } /** - * iscsi_iser_mtask_xmit - xmit management(immediate) ctask + * iscsi_iser_mtask_xmit - xmit management(immediate) task * @conn: iscsi connection - * @ctask: ctask management ctask + * @task: task management task * * Notes: * The function can return -EAGAIN in which case caller must @@ -159,19 +159,19 @@ iscsi_iser_task_init(struct iscsi_cmd_task *ctask) * **/ static int -iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) { int error = 0; - debug_scsi("ctask deq [cid %d itt 0x%x]\n", conn->id, ctask->itt); + debug_scsi("task deq [cid %d itt 0x%x]\n", conn->id, task->itt); - error = iser_send_control(conn, ctask); + error = iser_send_control(conn, task); - /* since iser xmits control with zero copy, ctasks can not be recycled + /* since iser xmits control with zero copy, tasks can not be recycled * right after sending them. * The recycling scheme is based on whether a response is expected - * - if yes, the ctask is recycled at iscsi_complete_pdu - * - if no, the ctask is recycled at iser_snd_completion + * - if yes, the task is recycled at iscsi_complete_pdu + * - if no, the task is recycled at iser_snd_completion */ if (error && error != -ENOBUFS) iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); @@ -181,27 +181,27 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) static int iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) + struct iscsi_task *task) { struct iscsi_data hdr; int error = 0; /* Send data-out PDUs while there's still unsolicited data to send */ - while (ctask->unsol_count > 0) { - iscsi_prep_unsolicit_data_pdu(ctask, &hdr); + while (task->unsol_count > 0) { + iscsi_prep_unsolicit_data_pdu(task, &hdr); debug_scsi("Sending data-out: itt 0x%x, data count %d\n", - hdr.itt, ctask->data_count); + hdr.itt, task->data_count); /* the buffer description has been passed with the command */ /* Send the command */ - error = iser_send_data_out(conn, ctask, &hdr); + error = iser_send_data_out(conn, task, &hdr); if (error) { - ctask->unsol_datasn--; + task->unsol_datasn--; goto iscsi_iser_task_xmit_unsol_data_exit; } - ctask->unsol_count -= ctask->data_count; + task->unsol_count -= task->data_count; debug_scsi("Need to send %d more as data-out PDUs\n", - ctask->unsol_count); + task->unsol_count); } iscsi_iser_task_xmit_unsol_data_exit: @@ -209,37 +209,37 @@ iscsi_iser_task_xmit_unsol_data_exit: } static int -iscsi_iser_task_xmit(struct iscsi_cmd_task *ctask) +iscsi_iser_task_xmit(struct iscsi_task *task) { - struct iscsi_conn *conn = ctask->conn; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_conn *conn = task->conn; + struct iscsi_iser_task *iser_task = task->dd_data; int error = 0; - if (!ctask->sc) - return iscsi_iser_mtask_xmit(conn, ctask); + if (!task->sc) + return iscsi_iser_mtask_xmit(conn, task); - if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { - BUG_ON(scsi_bufflen(ctask->sc) == 0); + if (task->sc->sc_data_direction == DMA_TO_DEVICE) { + BUG_ON(scsi_bufflen(task->sc) == 0); debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n", - ctask->itt, scsi_bufflen(ctask->sc), - ctask->imm_count, ctask->unsol_count); + task->itt, scsi_bufflen(task->sc), + task->imm_count, task->unsol_count); } - debug_scsi("ctask deq [cid %d itt 0x%x]\n", - conn->id, ctask->itt); + debug_scsi("task deq [cid %d itt 0x%x]\n", + conn->id, task->itt); /* Send the cmd PDU */ - if (!iser_ctask->command_sent) { - error = iser_send_command(conn, ctask); + if (!iser_task->command_sent) { + error = iser_send_command(conn, task); if (error) goto iscsi_iser_task_xmit_exit; - iser_ctask->command_sent = 1; + iser_task->command_sent = 1; } /* Send unsolicited data-out PDU(s) if necessary */ - if (ctask->unsol_count) - error = iscsi_iser_task_xmit_unsol_data(conn, ctask); + if (task->unsol_count) + error = iscsi_iser_task_xmit_unsol_data(conn, task); iscsi_iser_task_xmit_exit: if (error && error != -ENOBUFS) @@ -248,17 +248,17 @@ iscsi_iser_task_xmit(struct iscsi_cmd_task *ctask) } static void -iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task) { - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_iser_task *iser_task = task->dd_data; /* mgmt tasks do not need special cleanup */ - if (!ctask->sc) + if (!task->sc) return; - if (iser_ctask->status == ISER_TASK_STATUS_STARTED) { - iser_ctask->status = ISER_TASK_STATUS_COMPLETED; - iser_ctask_rdma_finalize(iser_ctask); + if (iser_task->status == ISER_TASK_STATUS_STARTED) { + iser_task->status = ISER_TASK_STATUS_COMPLETED; + iser_task_rdma_finalize(iser_task); } } @@ -408,8 +408,8 @@ iscsi_iser_session_create(struct Scsi_Host *shost, struct iscsi_cls_session *cls_session; struct iscsi_session *session; int i; - struct iscsi_cmd_task *ctask; - struct iscsi_iser_cmd_task *iser_ctask; + struct iscsi_task *task; + struct iscsi_iser_task *iser_task; if (shost) { printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", @@ -436,7 +436,7 @@ iscsi_iser_session_create(struct Scsi_Host *shost, */ cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, ISCSI_DEF_XMIT_CMDS_MAX, - sizeof(struct iscsi_iser_cmd_task), + sizeof(struct iscsi_iser_task), initial_cmdsn); if (!cls_session) goto remove_host; @@ -445,10 +445,10 @@ iscsi_iser_session_create(struct Scsi_Host *shost, shost->can_queue = session->scsi_cmds_max; /* libiscsi setup itts, data and pool so just set desc fields */ for (i = 0; i < session->cmds_max; i++) { - ctask = session->cmds[i]; - iser_ctask = ctask->dd_data; - ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header; - ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header); + task = session->cmds[i]; + iser_task = task->dd_data; + task->hdr = (struct iscsi_cmd *)&iser_task->desc.iscsi_header; + task->hdr_max = sizeof(iser_task->desc.iscsi_header); } return cls_session; diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 96a600f..05431f2 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -173,7 +173,7 @@ struct iser_data_buf { /* fwd declarations */ struct iser_device; struct iscsi_iser_conn; -struct iscsi_iser_cmd_task; +struct iscsi_iser_task; struct iser_mem_reg { u32 lkey; @@ -197,7 +197,7 @@ struct iser_regd_buf { #define MAX_REGD_BUF_VECTOR_LEN 2 struct iser_dto { - struct iscsi_iser_cmd_task *ctask; + struct iscsi_iser_task *task; struct iser_conn *ib_conn; int notify_enable; @@ -265,7 +265,7 @@ struct iscsi_iser_conn { rwlock_t lock; }; -struct iscsi_iser_cmd_task { +struct iscsi_iser_task { struct iser_desc desc; struct iscsi_iser_conn *iser_conn; enum iser_task_status status; @@ -299,13 +299,13 @@ extern int iser_debug_level; int iser_conn_set_full_featured_mode(struct iscsi_conn *conn); int iser_send_control(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); + struct iscsi_task *task); int iser_send_command(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); + struct iscsi_task *task); int iser_send_data_out(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask, + struct iscsi_task *task, struct iscsi_data *hdr); void iscsi_iser_recv(struct iscsi_conn *conn, @@ -326,9 +326,9 @@ void iser_rcv_completion(struct iser_desc *desc, void iser_snd_completion(struct iser_desc *desc); -void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *ctask); +void iser_task_rdma_init(struct iscsi_iser_task *task); -void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask); +void iser_task_rdma_finalize(struct iscsi_iser_task *task); void iser_dto_buffs_release(struct iser_dto *dto); @@ -338,10 +338,10 @@ void iser_reg_single(struct iser_device *device, struct iser_regd_buf *regd_buf, enum dma_data_direction direction); -void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask, +void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task, enum iser_data_dir cmd_dir); -int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *ctask, +int iser_reg_rdma_mem(struct iscsi_iser_task *task, enum iser_data_dir cmd_dir); int iser_connect(struct iser_conn *ib_conn, @@ -361,10 +361,10 @@ int iser_post_send(struct iser_desc *tx_desc); int iser_conn_state_comp(struct iser_conn *ib_conn, enum iser_ib_conn_state comp); -int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask, +int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, struct iser_data_buf *data, enum iser_data_dir iser_dir, enum dma_data_direction dma_dir); -void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask); +void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); #endif diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 4ea78fb..35af60a 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -66,46 +66,46 @@ static void iser_dto_add_regd_buff(struct iser_dto *dto, /* Register user buffer memory and initialize passive rdma * dto descriptor. Total data size is stored in - * iser_ctask->data[ISER_DIR_IN].data_len + * iser_task->data[ISER_DIR_IN].data_len */ -static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask, +static int iser_prepare_read_cmd(struct iscsi_task *task, unsigned int edtl) { - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_iser_task *iser_task = task->dd_data; struct iser_regd_buf *regd_buf; int err; - struct iser_hdr *hdr = &iser_ctask->desc.iser_header; - struct iser_data_buf *buf_in = &iser_ctask->data[ISER_DIR_IN]; + struct iser_hdr *hdr = &iser_task->desc.iser_header; + struct iser_data_buf *buf_in = &iser_task->data[ISER_DIR_IN]; - err = iser_dma_map_task_data(iser_ctask, + err = iser_dma_map_task_data(iser_task, buf_in, ISER_DIR_IN, DMA_FROM_DEVICE); if (err) return err; - if (edtl > iser_ctask->data[ISER_DIR_IN].data_len) { + if (edtl > iser_task->data[ISER_DIR_IN].data_len) { iser_err("Total data length: %ld, less than EDTL: " "%d, in READ cmd BHS itt: %d, conn: 0x%p\n", - iser_ctask->data[ISER_DIR_IN].data_len, edtl, - ctask->itt, iser_ctask->iser_conn); + iser_task->data[ISER_DIR_IN].data_len, edtl, + task->itt, iser_task->iser_conn); return -EINVAL; } - err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_IN); + err = iser_reg_rdma_mem(iser_task,ISER_DIR_IN); if (err) { iser_err("Failed to set up Data-IN RDMA\n"); return err; } - regd_buf = &iser_ctask->rdma_regd[ISER_DIR_IN]; + regd_buf = &iser_task->rdma_regd[ISER_DIR_IN]; hdr->flags |= ISER_RSV; hdr->read_stag = cpu_to_be32(regd_buf->reg.rkey); hdr->read_va = cpu_to_be64(regd_buf->reg.va); iser_dbg("Cmd itt:%d READ tags RKEY:%#.4X VA:%#llX\n", - ctask->itt, regd_buf->reg.rkey, + task->itt, regd_buf->reg.rkey, (unsigned long long)regd_buf->reg.va); return 0; @@ -113,43 +113,43 @@ static int iser_prepare_read_cmd(struct iscsi_cmd_task *ctask, /* Register user buffer memory and initialize passive rdma * dto descriptor. Total data size is stored in - * ctask->data[ISER_DIR_OUT].data_len + * task->data[ISER_DIR_OUT].data_len */ static int -iser_prepare_write_cmd(struct iscsi_cmd_task *ctask, +iser_prepare_write_cmd(struct iscsi_task *task, unsigned int imm_sz, unsigned int unsol_sz, unsigned int edtl) { - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_iser_task *iser_task = task->dd_data; struct iser_regd_buf *regd_buf; int err; - struct iser_dto *send_dto = &iser_ctask->desc.dto; - struct iser_hdr *hdr = &iser_ctask->desc.iser_header; - struct iser_data_buf *buf_out = &iser_ctask->data[ISER_DIR_OUT]; + struct iser_dto *send_dto = &iser_task->desc.dto; + struct iser_hdr *hdr = &iser_task->desc.iser_header; + struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT]; - err = iser_dma_map_task_data(iser_ctask, + err = iser_dma_map_task_data(iser_task, buf_out, ISER_DIR_OUT, DMA_TO_DEVICE); if (err) return err; - if (edtl > iser_ctask->data[ISER_DIR_OUT].data_len) { + if (edtl > iser_task->data[ISER_DIR_OUT].data_len) { iser_err("Total data length: %ld, less than EDTL: %d, " "in WRITE cmd BHS itt: %d, conn: 0x%p\n", - iser_ctask->data[ISER_DIR_OUT].data_len, - edtl, ctask->itt, ctask->conn); + iser_task->data[ISER_DIR_OUT].data_len, + edtl, task->itt, task->conn); return -EINVAL; } - err = iser_reg_rdma_mem(iser_ctask,ISER_DIR_OUT); + err = iser_reg_rdma_mem(iser_task,ISER_DIR_OUT); if (err != 0) { iser_err("Failed to register write cmd RDMA mem\n"); return err; } - regd_buf = &iser_ctask->rdma_regd[ISER_DIR_OUT]; + regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT]; if (unsol_sz < edtl) { hdr->flags |= ISER_WSV; @@ -158,13 +158,13 @@ iser_prepare_write_cmd(struct iscsi_cmd_task *ctask, iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X " "VA:%#llX + unsol:%d\n", - ctask->itt, regd_buf->reg.rkey, + task->itt, regd_buf->reg.rkey, (unsigned long long)regd_buf->reg.va, unsol_sz); } if (imm_sz > 0) { iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n", - ctask->itt, imm_sz); + task->itt, imm_sz); iser_dto_add_regd_buff(send_dto, regd_buf, 0, @@ -300,13 +300,13 @@ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn) } static int -iser_check_xmit(struct iscsi_conn *conn, void *ctask) +iser_check_xmit(struct iscsi_conn *conn, void *task) { struct iscsi_iser_conn *iser_conn = conn->dd_data; if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) == ISER_QP_MAX_REQ_DTOS) { - iser_dbg("%ld can't xmit ctask %p\n",jiffies,ctask); + iser_dbg("%ld can't xmit task %p\n",jiffies,task); return -ENOBUFS; } return 0; @@ -317,37 +317,37 @@ iser_check_xmit(struct iscsi_conn *conn, void *ctask) * iser_send_command - send command PDU */ int iser_send_command(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) + struct iscsi_task *task) { struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_iser_task *iser_task = task->dd_data; struct iser_dto *send_dto = NULL; unsigned long edtl; int err = 0; struct iser_data_buf *data_buf; - struct iscsi_cmd *hdr = ctask->hdr; - struct scsi_cmnd *sc = ctask->sc; + struct iscsi_cmd *hdr = task->hdr; + struct scsi_cmnd *sc = task->sc; if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); return -EPERM; } - if (iser_check_xmit(conn, ctask)) + if (iser_check_xmit(conn, task)) return -ENOBUFS; edtl = ntohl(hdr->data_length); /* build the tx desc regd header and add it to the tx desc dto */ - iser_ctask->desc.type = ISCSI_TX_SCSI_COMMAND; - send_dto = &iser_ctask->desc.dto; - send_dto->ctask = iser_ctask; - iser_create_send_desc(iser_conn, &iser_ctask->desc); + iser_task->desc.type = ISCSI_TX_SCSI_COMMAND; + send_dto = &iser_task->desc.dto; + send_dto->task = iser_task; + iser_create_send_desc(iser_conn, &iser_task->desc); if (hdr->flags & ISCSI_FLAG_CMD_READ) - data_buf = &iser_ctask->data[ISER_DIR_IN]; + data_buf = &iser_task->data[ISER_DIR_IN]; else - data_buf = &iser_ctask->data[ISER_DIR_OUT]; + data_buf = &iser_task->data[ISER_DIR_OUT]; if (scsi_sg_count(sc)) { /* using a scatter list */ data_buf->buf = scsi_sglist(sc); @@ -357,15 +357,15 @@ int iser_send_command(struct iscsi_conn *conn, data_buf->data_len = scsi_bufflen(sc); if (hdr->flags & ISCSI_FLAG_CMD_READ) { - err = iser_prepare_read_cmd(ctask, edtl); + err = iser_prepare_read_cmd(task, edtl); if (err) goto send_command_error; } if (hdr->flags & ISCSI_FLAG_CMD_WRITE) { - err = iser_prepare_write_cmd(ctask, - ctask->imm_count, - ctask->imm_count + - ctask->unsol_count, + err = iser_prepare_write_cmd(task, + task->imm_count, + task->imm_count + + task->unsol_count, edtl); if (err) goto send_command_error; @@ -380,15 +380,15 @@ int iser_send_command(struct iscsi_conn *conn, goto send_command_error; } - iser_ctask->status = ISER_TASK_STATUS_STARTED; + iser_task->status = ISER_TASK_STATUS_STARTED; - err = iser_post_send(&iser_ctask->desc); + err = iser_post_send(&iser_task->desc); if (!err) return 0; send_command_error: iser_dto_buffs_release(send_dto); - iser_err("conn %p failed ctask->itt %d err %d\n",conn, ctask->itt, err); + iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err); return err; } @@ -396,11 +396,11 @@ send_command_error: * iser_send_data_out - send data out PDU */ int iser_send_data_out(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask, + struct iscsi_task *task, struct iscsi_data *hdr) { struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; + struct iscsi_iser_task *iser_task = task->dd_data; struct iser_desc *tx_desc = NULL; struct iser_dto *send_dto = NULL; unsigned long buf_offset; @@ -413,7 +413,7 @@ int iser_send_data_out(struct iscsi_conn *conn, return -EPERM; } - if (iser_check_xmit(conn, ctask)) + if (iser_check_xmit(conn, task)) return -ENOBUFS; itt = (__force uint32_t)hdr->itt; @@ -434,7 +434,7 @@ int iser_send_data_out(struct iscsi_conn *conn, /* build the tx desc regd header and add it to the tx desc dto */ send_dto = &tx_desc->dto; - send_dto->ctask = iser_ctask; + send_dto->task = iser_task; iser_create_send_desc(iser_conn, tx_desc); iser_reg_single(iser_conn->ib_conn->device, @@ -442,15 +442,15 @@ int iser_send_data_out(struct iscsi_conn *conn, /* all data was registered for RDMA, we can use the lkey */ iser_dto_add_regd_buff(send_dto, - &iser_ctask->rdma_regd[ISER_DIR_OUT], + &iser_task->rdma_regd[ISER_DIR_OUT], buf_offset, data_seg_len); - if (buf_offset + data_seg_len > iser_ctask->data[ISER_DIR_OUT].data_len) { + if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) { iser_err("Offset:%ld & DSL:%ld in Data-Out " "inconsistent with total len:%ld, itt:%d\n", buf_offset, data_seg_len, - iser_ctask->data[ISER_DIR_OUT].data_len, itt); + iser_task->data[ISER_DIR_OUT].data_len, itt); err = -EINVAL; goto send_data_out_error; } @@ -470,11 +470,11 @@ send_data_out_error: } int iser_send_control(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) + struct iscsi_task *task) { struct iscsi_iser_conn *iser_conn = conn->dd_data; - struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; - struct iser_desc *mdesc = &iser_ctask->desc; + struct iscsi_iser_task *iser_task = task->dd_data; + struct iser_desc *mdesc = &iser_task->desc; struct iser_dto *send_dto = NULL; unsigned long data_seg_len; int err = 0; @@ -486,27 +486,27 @@ int iser_send_control(struct iscsi_conn *conn, return -EPERM; } - if (iser_check_xmit(conn, ctask)) + if (iser_check_xmit(conn, task)) return -ENOBUFS; /* build the tx desc regd header and add it to the tx desc dto */ mdesc->type = ISCSI_TX_CONTROL; send_dto = &mdesc->dto; - send_dto->ctask = NULL; + send_dto->task = NULL; iser_create_send_desc(iser_conn, mdesc); device = iser_conn->ib_conn->device; iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE); - data_seg_len = ntoh24(ctask->hdr->dlength); + data_seg_len = ntoh24(task->hdr->dlength); if (data_seg_len > 0) { regd_buf = &mdesc->data_regd_buf; memset(regd_buf, 0, sizeof(struct iser_regd_buf)); regd_buf->device = device; - regd_buf->virt_addr = ctask->data; - regd_buf->data_size = ctask->data_count; + regd_buf->virt_addr = task->data; + regd_buf->data_size = task->data_count; iser_reg_single(device, regd_buf, DMA_TO_DEVICE); iser_dto_add_regd_buff(send_dto, regd_buf, @@ -538,8 +538,8 @@ void iser_rcv_completion(struct iser_desc *rx_desc, { struct iser_dto *dto = &rx_desc->dto; struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn; - struct iscsi_cmd_task *ctask; - struct iscsi_iser_cmd_task *iser_ctask; + struct iscsi_task *task; + struct iscsi_iser_task *iser_task; struct iscsi_hdr *hdr; char *rx_data = NULL; int rx_data_len = 0; @@ -558,16 +558,16 @@ void iser_rcv_completion(struct iser_desc *rx_desc, opcode = hdr->opcode & ISCSI_OPCODE_MASK; if (opcode == ISCSI_OP_SCSI_CMD_RSP) { - ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt); - if (!ctask) - iser_err("itt can't be matched to ctask!!! " + task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt); + if (!task) + iser_err("itt can't be matched to task!!! " "conn %p opcode %d itt %d\n", conn->iscsi_conn, opcode, hdr->itt); else { - iser_ctask = ctask->dd_data; - iser_dbg("itt %d ctask %p\n",hdr->itt, ctask); - iser_ctask->status = ISER_TASK_STATUS_COMPLETED; - iser_ctask_rdma_finalize(iser_ctask); + iser_task = task->dd_data; + iser_dbg("itt %d task %p\n",hdr->itt, task); + iser_task->status = ISER_TASK_STATUS_COMPLETED; + iser_task_rdma_finalize(iser_task); } } iser_dto_buffs_release(dto); @@ -578,7 +578,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, kmem_cache_free(ig.desc_cache, rx_desc); /* decrementing conn->post_recv_buf_count only --after-- freeing the * - * ctask eliminates the need to worry on ctasks which are completed in * + * task eliminates the need to worry on tasks which are completed in * * parallel to the execution of iser_conn_term. So the code that waits * * for the posted rx bufs refcount to become zero handles everything */ atomic_dec(&conn->ib_conn->post_recv_buf_count); @@ -590,7 +590,7 @@ void iser_snd_completion(struct iser_desc *tx_desc) struct iser_conn *ib_conn = dto->ib_conn; struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn; struct iscsi_conn *conn = iser_conn->iscsi_conn; - struct iscsi_cmd_task *ctask; + struct iscsi_task *task; int resume_tx = 0; iser_dbg("Initiator, Data sent dto=0x%p\n", dto); @@ -613,31 +613,31 @@ void iser_snd_completion(struct iser_desc *tx_desc) if (tx_desc->type == ISCSI_TX_CONTROL) { /* this arithmetic is legal by libiscsi dd_data allocation */ - ctask = (void *) ((long)(void *)tx_desc - - sizeof(struct iscsi_cmd_task)); - if (ctask->hdr->itt == RESERVED_ITT) - iscsi_put_ctask(ctask); + task = (void *) ((long)(void *)tx_desc - + sizeof(struct iscsi_task)); + if (task->hdr->itt == RESERVED_ITT) + iscsi_put_task(task); } } -void iser_ctask_rdma_init(struct iscsi_iser_cmd_task *iser_ctask) +void iser_task_rdma_init(struct iscsi_iser_task *iser_task) { - iser_ctask->status = ISER_TASK_STATUS_INIT; + iser_task->status = ISER_TASK_STATUS_INIT; - iser_ctask->dir[ISER_DIR_IN] = 0; - iser_ctask->dir[ISER_DIR_OUT] = 0; + iser_task->dir[ISER_DIR_IN] = 0; + iser_task->dir[ISER_DIR_OUT] = 0; - iser_ctask->data[ISER_DIR_IN].data_len = 0; - iser_ctask->data[ISER_DIR_OUT].data_len = 0; + iser_task->data[ISER_DIR_IN].data_len = 0; + iser_task->data[ISER_DIR_OUT].data_len = 0; - memset(&iser_ctask->rdma_regd[ISER_DIR_IN], 0, + memset(&iser_task->rdma_regd[ISER_DIR_IN], 0, sizeof(struct iser_regd_buf)); - memset(&iser_ctask->rdma_regd[ISER_DIR_OUT], 0, + memset(&iser_task->rdma_regd[ISER_DIR_OUT], 0, sizeof(struct iser_regd_buf)); } -void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask) +void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task) { int deferred; int is_rdma_aligned = 1; @@ -646,17 +646,17 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask) /* if we were reading, copy back to unaligned sglist, * anyway dma_unmap and free the copy */ - if (iser_ctask->data_copy[ISER_DIR_IN].copy_buf != NULL) { + if (iser_task->data_copy[ISER_DIR_IN].copy_buf != NULL) { is_rdma_aligned = 0; - iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_IN); + iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_IN); } - if (iser_ctask->data_copy[ISER_DIR_OUT].copy_buf != NULL) { + if (iser_task->data_copy[ISER_DIR_OUT].copy_buf != NULL) { is_rdma_aligned = 0; - iser_finalize_rdma_unaligned_sg(iser_ctask, ISER_DIR_OUT); + iser_finalize_rdma_unaligned_sg(iser_task, ISER_DIR_OUT); } - if (iser_ctask->dir[ISER_DIR_IN]) { - regd = &iser_ctask->rdma_regd[ISER_DIR_IN]; + if (iser_task->dir[ISER_DIR_IN]) { + regd = &iser_task->rdma_regd[ISER_DIR_IN]; deferred = iser_regd_buff_release(regd); if (deferred) { iser_err("%d references remain for BUF-IN rdma reg\n", @@ -664,8 +664,8 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask) } } - if (iser_ctask->dir[ISER_DIR_OUT]) { - regd = &iser_ctask->rdma_regd[ISER_DIR_OUT]; + if (iser_task->dir[ISER_DIR_OUT]) { + regd = &iser_task->rdma_regd[ISER_DIR_OUT]; deferred = iser_regd_buff_release(regd); if (deferred) { iser_err("%d references remain for BUF-OUT rdma reg\n", @@ -675,7 +675,7 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask) /* if the data was unaligned, it was already unmapped and then copied */ if (is_rdma_aligned) - iser_dma_unmap_task_data(iser_ctask); + iser_dma_unmap_task_data(iser_task); } void iser_dto_buffs_release(struct iser_dto *dto) diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index cac50c4..48f2a60 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -101,13 +101,13 @@ void iser_reg_single(struct iser_device *device, /** * iser_start_rdma_unaligned_sg */ -static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, +static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, enum iser_data_dir cmd_dir) { int dma_nents; struct ib_device *dev; char *mem = NULL; - struct iser_data_buf *data = &iser_ctask->data[cmd_dir]; + struct iser_data_buf *data = &iser_task->data[cmd_dir]; unsigned long cmd_data_len = data->data_len; if (cmd_data_len > ISER_KMALLOC_THRESHOLD) @@ -140,37 +140,37 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, } } - sg_init_one(&iser_ctask->data_copy[cmd_dir].sg_single, mem, cmd_data_len); - iser_ctask->data_copy[cmd_dir].buf = - &iser_ctask->data_copy[cmd_dir].sg_single; - iser_ctask->data_copy[cmd_dir].size = 1; + sg_init_one(&iser_task->data_copy[cmd_dir].sg_single, mem, cmd_data_len); + iser_task->data_copy[cmd_dir].buf = + &iser_task->data_copy[cmd_dir].sg_single; + iser_task->data_copy[cmd_dir].size = 1; - iser_ctask->data_copy[cmd_dir].copy_buf = mem; + iser_task->data_copy[cmd_dir].copy_buf = mem; - dev = iser_ctask->iser_conn->ib_conn->device->ib_device; + dev = iser_task->iser_conn->ib_conn->device->ib_device; dma_nents = ib_dma_map_sg(dev, - &iser_ctask->data_copy[cmd_dir].sg_single, + &iser_task->data_copy[cmd_dir].sg_single, 1, (cmd_dir == ISER_DIR_OUT) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); BUG_ON(dma_nents == 0); - iser_ctask->data_copy[cmd_dir].dma_nents = dma_nents; + iser_task->data_copy[cmd_dir].dma_nents = dma_nents; return 0; } /** * iser_finalize_rdma_unaligned_sg */ -void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, +void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, enum iser_data_dir cmd_dir) { struct ib_device *dev; struct iser_data_buf *mem_copy; unsigned long cmd_data_len; - dev = iser_ctask->iser_conn->ib_conn->device->ib_device; - mem_copy = &iser_ctask->data_copy[cmd_dir]; + dev = iser_task->iser_conn->ib_conn->device->ib_device; + mem_copy = &iser_task->data_copy[cmd_dir]; ib_dma_unmap_sg(dev, &mem_copy->sg_single, 1, (cmd_dir == ISER_DIR_OUT) ? @@ -186,8 +186,8 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, /* copy back read RDMA to unaligned sg */ mem = mem_copy->copy_buf; - sgl = (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf; - sg_size = iser_ctask->data[ISER_DIR_IN].size; + sgl = (struct scatterlist *)iser_task->data[ISER_DIR_IN].buf; + sg_size = iser_task->data[ISER_DIR_IN].size; p = mem; for_each_sg(sgl, sg, sg_size, i) { @@ -200,7 +200,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask, } } - cmd_data_len = iser_ctask->data[cmd_dir].data_len; + cmd_data_len = iser_task->data[cmd_dir].data_len; if (cmd_data_len > ISER_KMALLOC_THRESHOLD) free_pages((unsigned long)mem_copy->copy_buf, @@ -378,15 +378,15 @@ static void iser_page_vec_build(struct iser_data_buf *data, } } -int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask, - struct iser_data_buf *data, - enum iser_data_dir iser_dir, - enum dma_data_direction dma_dir) +int iser_dma_map_task_data(struct iscsi_iser_task *iser_task, + struct iser_data_buf *data, + enum iser_data_dir iser_dir, + enum dma_data_direction dma_dir) { struct ib_device *dev; - iser_ctask->dir[iser_dir] = 1; - dev = iser_ctask->iser_conn->ib_conn->device->ib_device; + iser_task->dir[iser_dir] = 1; + dev = iser_task->iser_conn->ib_conn->device->ib_device; data->dma_nents = ib_dma_map_sg(dev, data->buf, data->size, dma_dir); if (data->dma_nents == 0) { @@ -396,20 +396,20 @@ int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask, return 0; } -void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask) +void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task) { struct ib_device *dev; struct iser_data_buf *data; - dev = iser_ctask->iser_conn->ib_conn->device->ib_device; + dev = iser_task->iser_conn->ib_conn->device->ib_device; - if (iser_ctask->dir[ISER_DIR_IN]) { - data = &iser_ctask->data[ISER_DIR_IN]; + if (iser_task->dir[ISER_DIR_IN]) { + data = &iser_task->data[ISER_DIR_IN]; ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE); } - if (iser_ctask->dir[ISER_DIR_OUT]) { - data = &iser_ctask->data[ISER_DIR_OUT]; + if (iser_task->dir[ISER_DIR_OUT]) { + data = &iser_task->data[ISER_DIR_OUT]; ib_dma_unmap_sg(dev, data->buf, data->size, DMA_TO_DEVICE); } } @@ -420,21 +420,21 @@ void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask) * * returns 0 on success, errno code on failure */ -int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, +int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task, enum iser_data_dir cmd_dir) { - struct iscsi_conn *iscsi_conn = iser_ctask->iser_conn->iscsi_conn; - struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; + struct iscsi_conn *iscsi_conn = iser_task->iser_conn->iscsi_conn; + struct iser_conn *ib_conn = iser_task->iser_conn->ib_conn; struct iser_device *device = ib_conn->device; struct ib_device *ibdev = device->ib_device; - struct iser_data_buf *mem = &iser_ctask->data[cmd_dir]; + struct iser_data_buf *mem = &iser_task->data[cmd_dir]; struct iser_regd_buf *regd_buf; int aligned_len; int err; int i; struct scatterlist *sg; - regd_buf = &iser_ctask->rdma_regd[cmd_dir]; + regd_buf = &iser_task->rdma_regd[cmd_dir]; aligned_len = iser_data_buf_aligned_len(mem, ibdev); if (aligned_len != mem->dma_nents) { @@ -444,13 +444,13 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, iser_data_buf_dump(mem, ibdev); /* unmap the command data before accessing it */ - iser_dma_unmap_task_data(iser_ctask); + iser_dma_unmap_task_data(iser_task); /* allocate copy buf, if we are writing, copy the */ /* unaligned scatterlist, dma map the copy */ - if (iser_start_rdma_unaligned_sg(iser_ctask, cmd_dir) != 0) + if (iser_start_rdma_unaligned_sg(iser_task, cmd_dir) != 0) return -ENOMEM; - mem = &iser_ctask->data_copy[cmd_dir]; + mem = &iser_task->data_copy[cmd_dir]; } /* if there a single dma entry, FMR is not needed */ @@ -474,8 +474,9 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, ®d_buf->reg); if (err) { iser_data_buf_dump(mem, ibdev); - iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", mem->dma_nents, - ntoh24(iser_ctask->desc.iscsi_header.dlength)); + iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", + mem->dma_nents, + ntoh24(iser_task->desc.iscsi_header.dlength)); iser_err("page_vec: data_size = 0x%x, length = %d, offset = 0x%x\n", ib_conn->page_vec->data_size, ib_conn->page_vec->length, ib_conn->page_vec->offset); -- cgit v0.10.2 From 7970634b81a6e3561954517bca42615542c4535b Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:12 -0500 Subject: [SCSI] iscsi class: user device_for_each_child instead of duplicating session list Currently we duplicate the list of sessions, because we were using the test for if a session was on the host list to indicate if the session was bound or unbound. We can instead use the target_id and fix up the class so that drivers like bnx2i do not have to manage the target id space. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 86d9c42..3a89039 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -437,7 +437,7 @@ iscsi_iser_session_create(struct Scsi_Host *shost, cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, ISCSI_DEF_XMIT_CMDS_MAX, sizeof(struct iscsi_iser_task), - initial_cmdsn); + initial_cmdsn, 0); if (!cls_session) goto remove_host; session = cls_session->dd_data; diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 33cd0ca..aa3c7f0 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1868,7 +1868,7 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max, sizeof(struct iscsi_tcp_task), - initial_cmdsn); + initial_cmdsn, 0); if (!cls_session) goto remove_host; session = cls_session->dd_data; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 92ee6d9..e88b726 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1897,7 +1897,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, uint16_t scsi_cmds_max, int cmd_task_size, - uint32_t initial_cmdsn) + uint32_t initial_cmdsn, unsigned int id) { struct iscsi_session *session; struct iscsi_cls_session *cls_session; @@ -1957,7 +1957,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, if (!try_module_get(iscsit->owner)) goto module_get_fail; - if (iscsi_add_session(cls_session, 0)) + if (iscsi_add_session(cls_session, id)) goto cls_session_fail; return cls_session; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 6b8516a..ac9d298 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -119,9 +119,8 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev, struct iscsi_cls_host *ihost = shost->shost_data; memset(ihost, 0, sizeof(*ihost)); - INIT_LIST_HEAD(&ihost->sessions); - mutex_init(&ihost->mutex); atomic_set(&ihost->nr_scans, 0); + mutex_init(&ihost->mutex); snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d", shost->host_no); @@ -316,42 +315,76 @@ int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time) } EXPORT_SYMBOL_GPL(iscsi_scan_finished); -static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, - uint id, uint lun) +struct iscsi_scan_data { + unsigned int channel; + unsigned int id; + unsigned int lun; +}; + +static int iscsi_user_scan_session(struct device *dev, void *data) { - struct iscsi_cls_host *ihost = shost->shost_data; + struct iscsi_scan_data *scan_data = data; struct iscsi_cls_session *session; + struct Scsi_Host *shost; + struct iscsi_cls_host *ihost; + unsigned long flags; + unsigned int id; + + if (!iscsi_is_session_dev(dev)) + return 0; + + session = iscsi_dev_to_session(dev); + shost = iscsi_session_to_shost(session); + ihost = shost->shost_data; mutex_lock(&ihost->mutex); - list_for_each_entry(session, &ihost->sessions, host_list) { - if ((channel == SCAN_WILD_CARD || channel == 0) && - (id == SCAN_WILD_CARD || id == session->target_id)) - scsi_scan_target(&session->dev, 0, - session->target_id, lun, 1); + spin_lock_irqsave(&session->lock, flags); + if (session->state != ISCSI_SESSION_LOGGED_IN) { + spin_unlock_irqrestore(&session->lock, flags); + mutex_unlock(&ihost->mutex); + return 0; } - mutex_unlock(&ihost->mutex); + id = session->target_id; + spin_unlock_irqrestore(&session->lock, flags); + if (id != ISCSI_MAX_TARGET) { + if ((scan_data->channel == SCAN_WILD_CARD || + scan_data->channel == 0) && + (scan_data->id == SCAN_WILD_CARD || + scan_data->id == id)) + scsi_scan_target(&session->dev, 0, id, + scan_data->lun, 1); + } + mutex_unlock(&ihost->mutex); return 0; } +static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, + uint id, uint lun) +{ + struct iscsi_scan_data scan_data; + + scan_data.channel = channel; + scan_data.id = id; + scan_data.lun = lun; + + return device_for_each_child(&shost->shost_gendev, &scan_data, + iscsi_user_scan_session); +} + static void iscsi_scan_session(struct work_struct *work) { struct iscsi_cls_session *session = container_of(work, struct iscsi_cls_session, scan_work); struct Scsi_Host *shost = iscsi_session_to_shost(session); struct iscsi_cls_host *ihost = shost->shost_data; - unsigned long flags; + struct iscsi_scan_data scan_data; - spin_lock_irqsave(&session->lock, flags); - if (session->state != ISCSI_SESSION_LOGGED_IN) { - spin_unlock_irqrestore(&session->lock, flags); - goto done; - } - spin_unlock_irqrestore(&session->lock, flags); + scan_data.channel = 0; + scan_data.id = SCAN_WILD_CARD; + scan_data.lun = SCAN_WILD_CARD; - scsi_scan_target(&session->dev, 0, session->target_id, - SCAN_WILD_CARD, 1); -done: + iscsi_user_scan_session(&session->dev, &scan_data); atomic_dec(&ihost->nr_scans); } @@ -460,14 +493,18 @@ static void __iscsi_unbind_session(struct work_struct *work) unbind_work); struct Scsi_Host *shost = iscsi_session_to_shost(session); struct iscsi_cls_host *ihost = shost->shost_data; + unsigned long flags; /* Prevent new scans and make sure scanning is not in progress */ mutex_lock(&ihost->mutex); - if (list_empty(&session->host_list)) { + spin_lock_irqsave(&session->lock, flags); + if (session->target_id == ISCSI_MAX_TARGET) { + spin_unlock_irqrestore(&session->lock, flags); mutex_unlock(&ihost->mutex); return; } - list_del_init(&session->host_list); + session->target_id = ISCSI_MAX_TARGET; + spin_unlock_irqrestore(&session->lock, flags); mutex_unlock(&ihost->mutex); scsi_remove_target(&session->dev); @@ -497,7 +534,6 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, session->recovery_tmo = 120; session->state = ISCSI_SESSION_FREE; INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout); - INIT_LIST_HEAD(&session->host_list); INIT_LIST_HEAD(&session->sess_list); INIT_WORK(&session->unblock_work, __iscsi_unblock_session); INIT_WORK(&session->block_work, __iscsi_block_session); @@ -516,16 +552,51 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, } EXPORT_SYMBOL_GPL(iscsi_alloc_session); +static int iscsi_get_next_target_id(struct device *dev, void *data) +{ + struct iscsi_cls_session *session; + unsigned long flags; + int err = 0; + + if (!iscsi_is_session_dev(dev)) + return 0; + + session = iscsi_dev_to_session(dev); + spin_lock_irqsave(&session->lock, flags); + if (*((unsigned int *) data) == session->target_id) + err = -EEXIST; + spin_unlock_irqrestore(&session->lock, flags); + return err; +} + int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) { struct Scsi_Host *shost = iscsi_session_to_shost(session); struct iscsi_cls_host *ihost; unsigned long flags; + unsigned int id = target_id; int err; ihost = shost->shost_data; session->sid = atomic_add_return(1, &iscsi_session_nr); - session->target_id = target_id; + + if (id == ISCSI_MAX_TARGET) { + for (id = 0; id < ISCSI_MAX_TARGET; id++) { + err = device_for_each_child(&shost->shost_gendev, &id, + iscsi_get_next_target_id); + if (!err) + break; + } + + if (id == ISCSI_MAX_TARGET) { + iscsi_cls_session_printk(KERN_ERR, session, + "Too many iscsi targets. Max " + "number of targets is %d.\n", + ISCSI_MAX_TARGET - 1); + goto release_host; + } + } + session->target_id = id; snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", session->sid); @@ -541,10 +612,6 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) list_add(&session->sess_list, &sesslist); spin_unlock_irqrestore(&sesslock, flags); - mutex_lock(&ihost->mutex); - list_add(&session->host_list, &ihost->sessions); - mutex_unlock(&ihost->mutex); - iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION); return 0; diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 176353c..13c92d7 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -331,7 +331,7 @@ extern void iscsi_host_free(struct Scsi_Host *shost); */ extern struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, - uint16_t, int, uint32_t); + uint16_t, int, uint32_t, unsigned int); extern void iscsi_session_teardown(struct iscsi_cls_session *); extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 0553240..d6b8231 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -161,9 +161,10 @@ enum { ISCSI_SESSION_FREE, }; +#define ISCSI_MAX_TARGET -1 + struct iscsi_cls_session { struct list_head sess_list; /* item in session_list */ - struct list_head host_list; struct iscsi_transport *transport; spinlock_t lock; struct work_struct block_work; @@ -175,7 +176,7 @@ struct iscsi_cls_session { int recovery_tmo; struct delayed_work recovery_work; - int target_id; + unsigned int target_id; int state; int sid; /* session id */ @@ -193,7 +194,6 @@ struct iscsi_cls_session { iscsi_dev_to_session(_stgt->dev.parent) struct iscsi_cls_host { - struct list_head sessions; atomic_t nr_scans; struct mutex mutex; struct workqueue_struct *scan_workq; -- cgit v0.10.2 From d82ff9be733a2e6da4f6c2ab4e9216f3f536503d Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:13 -0500 Subject: [SCSI] iscsi class: add endpoint class Add sysfs representation for the endpoint, so userspace can match the host and session to the endpoint. This will allow us to set the host's parent correctly at host creation time. The next patches will convert tcp and iser, and fix iser's dma_mask bug. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index ac9d298..c3c07cc 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -33,6 +33,7 @@ #define ISCSI_SESSION_ATTRS 19 #define ISCSI_CONN_ATTRS 13 #define ISCSI_HOST_ATTRS 4 + #define ISCSI_TRANSPORT_VERSION "2.0-869" struct iscsi_internal { @@ -112,6 +113,123 @@ static struct attribute_group iscsi_transport_group = { .attrs = iscsi_transport_attrs, }; +/* + * iSCSI endpoint attrs + */ +#define iscsi_dev_to_endpoint(_dev) \ + container_of(_dev, struct iscsi_endpoint, dev) + +#define ISCSI_ATTR(_prefix,_name,_mode,_show,_store) \ +struct device_attribute dev_attr_##_prefix##_##_name = \ + __ATTR(_name,_mode,_show,_store) + +static void iscsi_endpoint_release(struct device *dev) +{ + struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); + kfree(ep); +} + +static struct class iscsi_endpoint_class = { + .name = "iscsi_endpoint", + .dev_release = iscsi_endpoint_release, +}; + +static ssize_t +show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); + return sprintf(buf, "%u\n", ep->id); +} +static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL); + +static struct attribute *iscsi_endpoint_attrs[] = { + &dev_attr_ep_handle.attr, + NULL, +}; + +static struct attribute_group iscsi_endpoint_group = { + .attrs = iscsi_endpoint_attrs, +}; + +#define ISCSI_MAX_EPID -1 + +static int iscsi_match_epid(struct device *dev, void *data) +{ + struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); + unsigned int *epid = (unsigned int *) data; + + return *epid == ep->id; +} + +struct iscsi_endpoint * +iscsi_create_endpoint(int dd_size) +{ + struct device *dev; + struct iscsi_endpoint *ep; + unsigned int id; + int err; + + for (id = 1; id < ISCSI_MAX_EPID; id++) { + dev = class_find_device(&iscsi_endpoint_class, &id, + iscsi_match_epid); + if (!dev) + break; + } + if (id == ISCSI_MAX_EPID) { + printk(KERN_ERR "Too many connections. Max supported %u\n", + ISCSI_MAX_EPID - 1); + return NULL; + } + + ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL); + if (!ep) + return NULL; + + ep->id = id; + ep->dev.class = &iscsi_endpoint_class; + snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%u", id); + err = device_register(&ep->dev); + if (err) + goto free_ep; + + err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group); + if (err) + goto unregister_dev; + + if (dd_size) + ep->dd_data = &ep[1]; + return ep; + +unregister_dev: + device_unregister(&ep->dev); + return NULL; + +free_ep: + kfree(ep); + return NULL; +} +EXPORT_SYMBOL_GPL(iscsi_create_endpoint); + +void iscsi_destroy_endpoint(struct iscsi_endpoint *ep) +{ + sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group); + device_unregister(&ep->dev); +} +EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint); + +struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) +{ + struct device *dev; + + dev = class_find_device(&iscsi_endpoint_class, &handle, + iscsi_match_epid); + if (!dev) + return NULL; + + return iscsi_dev_to_endpoint(dev); +} +EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); + static int iscsi_setup_host(struct transport_container *tc, struct device *dev, struct device *cdev) { @@ -1094,33 +1212,16 @@ int iscsi_session_event(struct iscsi_cls_session *session, EXPORT_SYMBOL_GPL(iscsi_session_event); static int -iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev, - uint32_t host_no, uint32_t initial_cmdsn, +iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep, + struct iscsi_uevent *ev, uint32_t initial_cmdsn, uint16_t cmds_max, uint16_t queue_depth) { struct iscsi_transport *transport = priv->iscsi_transport; struct iscsi_cls_session *session; - struct Scsi_Host *shost = NULL; + uint32_t host_no; - /* - * Software iscsi allocates a host per session, but - * offload drivers (and possibly iser one day) allocate a host per - * hba/nic/rnic. Offload will match a host here, but software will - * return a new hostno after the create_session callback has returned. - */ - if (host_no != UINT_MAX) { - shost = scsi_host_lookup(host_no); - if (IS_ERR(shost)) { - printk(KERN_ERR "Could not find host no %u to " - "create session\n", host_no); - return -ENODEV; - } - } - - session = transport->create_session(shost, cmds_max, queue_depth, + session = transport->create_session(ep, cmds_max, queue_depth, initial_cmdsn, &host_no); - if (shost) - scsi_host_put(shost); if (!session) return -ENOMEM; @@ -1199,6 +1300,7 @@ static int iscsi_if_transport_ep(struct iscsi_transport *transport, struct iscsi_uevent *ev, int msg_type) { + struct iscsi_endpoint *ep; struct sockaddr *dst_addr; int rc = 0; @@ -1208,22 +1310,33 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, return -EINVAL; dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); - rc = transport->ep_connect(dst_addr, - ev->u.ep_connect.non_blocking, - &ev->r.ep_connect_ret.handle); + ep = transport->ep_connect(dst_addr, + ev->u.ep_connect.non_blocking); + if (IS_ERR(ep)) + return PTR_ERR(ep); + + ev->r.ep_connect_ret.handle = ep->id; break; case ISCSI_UEVENT_TRANSPORT_EP_POLL: if (!transport->ep_poll) return -EINVAL; - ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle, + ep = iscsi_lookup_endpoint(ev->u.ep_poll.ep_handle); + if (!ep) + return -EINVAL; + + ev->r.retcode = transport->ep_poll(ep, ev->u.ep_poll.timeout_ms); break; case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: if (!transport->ep_disconnect) return -EINVAL; - transport->ep_disconnect(ev->u.ep_disconnect.ep_handle); + ep = iscsi_lookup_endpoint(ev->u.ep_disconnect.ep_handle); + if (!ep) + return -EINVAL; + + transport->ep_disconnect(ep); break; } return rc; @@ -1283,12 +1396,12 @@ static int iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int err = 0; - uint32_t host_no = UINT_MAX; struct iscsi_uevent *ev = NLMSG_DATA(nlh); struct iscsi_transport *transport = NULL; struct iscsi_internal *priv; struct iscsi_cls_session *session; struct iscsi_cls_conn *conn; + struct iscsi_endpoint *ep = NULL; priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); if (!priv) @@ -1302,14 +1415,17 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) switch (nlh->nlmsg_type) { case ISCSI_UEVENT_CREATE_SESSION: - err = iscsi_if_create_session(priv, ev, host_no, + err = iscsi_if_create_session(priv, ep, ev, ev->u.c_session.initial_cmdsn, ev->u.c_session.cmds_max, ev->u.c_session.queue_depth); break; case ISCSI_UEVENT_CREATE_BOUND_SESSION: - err = iscsi_if_create_session(priv, ev, - ev->u.c_bound_session.host_no, + ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle); + if (!ep) + return -EINVAL; + + err = iscsi_if_create_session(priv, ep, ev, ev->u.c_bound_session.initial_cmdsn, ev->u.c_bound_session.cmds_max, ev->u.c_bound_session.queue_depth); @@ -1774,6 +1890,7 @@ iscsi_register_transport(struct iscsi_transport *tt) unregister_dev: device_unregister(&priv->dev); + return NULL; free_priv: kfree(priv); return NULL; @@ -1821,10 +1938,14 @@ static __init int iscsi_transport_init(void) if (err) return err; - err = transport_class_register(&iscsi_host_class); + err = class_register(&iscsi_endpoint_class); if (err) goto unregister_transport_class; + err = transport_class_register(&iscsi_host_class); + if (err) + goto unregister_endpoint_class; + err = transport_class_register(&iscsi_connection_class); if (err) goto unregister_host_class; @@ -1833,8 +1954,8 @@ static __init int iscsi_transport_init(void) if (err) goto unregister_conn_class; - nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL, - THIS_MODULE); + nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, + NULL, THIS_MODULE); if (!nls) { err = -ENOBUFS; goto unregister_session_class; @@ -1854,6 +1975,8 @@ unregister_conn_class: transport_class_unregister(&iscsi_connection_class); unregister_host_class: transport_class_unregister(&iscsi_host_class); +unregister_endpoint_class: + class_unregister(&iscsi_endpoint_class); unregister_transport_class: class_unregister(&iscsi_transport_class); return err; @@ -1866,6 +1989,7 @@ static void __exit iscsi_transport_exit(void) transport_class_unregister(&iscsi_connection_class); transport_class_unregister(&iscsi_session_class); transport_class_unregister(&iscsi_host_class); + class_unregister(&iscsi_endpoint_class); class_unregister(&iscsi_transport_class); } diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 801a677..a0f13a2 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -80,7 +80,7 @@ struct iscsi_uevent { uint16_t queue_depth; } c_session; struct msg_create_bound_session { - uint32_t host_no; + uint64_t ep_handle; uint32_t initial_cmdsn; uint16_t cmds_max; uint16_t queue_depth; diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index d6b8231..f5444e0 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -30,6 +30,7 @@ struct scsi_transport_template; struct iscsi_transport; +struct iscsi_endpoint; struct Scsi_Host; struct iscsi_cls_conn; struct iscsi_conn; @@ -85,7 +86,7 @@ struct iscsi_transport { /* LLD sets this to indicate what values it can export to sysfs */ uint64_t param_mask; uint64_t host_param_mask; - struct iscsi_cls_session *(*create_session) (struct Scsi_Host *shost, + struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep, uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn); void (*destroy_session) (struct iscsi_cls_session *session); @@ -117,10 +118,10 @@ struct iscsi_transport { void (*cleanup_task) (struct iscsi_conn *conn, struct iscsi_task *task); void (*session_recovery_timedout) (struct iscsi_cls_session *session); - int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking, - uint64_t *ep_handle); - int (*ep_poll) (uint64_t ep_handle, int timeout_ms); - void (*ep_disconnect) (uint64_t ep_handle); + struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr, + int non_blocking); + int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms); + void (*ep_disconnect) (struct iscsi_endpoint *ep); int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type, uint32_t enable, struct sockaddr *dst_addr); }; @@ -203,6 +204,11 @@ struct iscsi_cls_host { extern void iscsi_host_for_each_session(struct Scsi_Host *shost, void (*fn)(struct iscsi_cls_session *)); +struct iscsi_endpoint { + void *dd_data; /* LLD private data */ + struct device dev; + unsigned int id; +}; /* * session and connection functions that can be used by HW iSCSI LLDs @@ -233,5 +239,8 @@ extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); extern void iscsi_unblock_session(struct iscsi_cls_session *session); extern void iscsi_block_session(struct iscsi_cls_session *session); extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time); +extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size); +extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep); +extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle); #endif -- cgit v0.10.2 From 412eeafa0a51a8d86545d0be637bf84e4374fccf Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:14 -0500 Subject: [SCSI] iser: Modify iser to take a iscsi_endpoint struct in ep callouts and session setup This hooks iser into the iscsi endpoint code. Previously it handled the lookup and allocation. This has been made generic so bnx2i and iser can share it. It also allows us to pass iser the leading conn's ep, so we know the ib_deivce being used and can set it as the scsi_host's parent. And that allows scsi-ml to set the dma_mask based on those values. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 3a89039..42e95b8 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -262,24 +262,6 @@ iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task) } } -static struct iser_conn * -iscsi_iser_ib_conn_lookup(__u64 ep_handle) -{ - struct iser_conn *ib_conn; - struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle; - - mutex_lock(&ig.connlist_mutex); - list_for_each_entry(ib_conn, &ig.connlist, conn_list) { - if (ib_conn == uib_conn) { - mutex_unlock(&ig.connlist_mutex); - return ib_conn; - } - } - mutex_unlock(&ig.connlist_mutex); - iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle); - return NULL; -} - static struct iscsi_cls_conn * iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) { @@ -335,6 +317,7 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_iser_conn *iser_conn; struct iser_conn *ib_conn; + struct iscsi_endpoint *ep; int error; error = iscsi_conn_bind(cls_session, cls_conn, is_leading); @@ -343,12 +326,14 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, /* the transport ep handle comes from user space so it must be * verified against the global ib connections list */ - ib_conn = iscsi_iser_ib_conn_lookup(transport_eph); - if (!ib_conn) { + ep = iscsi_lookup_endpoint(transport_eph); + if (!ep) { iser_err("can't bind eph %llx\n", (unsigned long long)transport_eph); return -EINVAL; } + ib_conn = ep->dd_data; + /* binds the iSER connection retrieved from the previously * connected ep_handle to the iSCSI layer connection. exchanges * connection pointers */ @@ -401,21 +386,17 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) } static struct iscsi_cls_session * -iscsi_iser_session_create(struct Scsi_Host *shost, +iscsi_iser_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, uint16_t qdepth, uint32_t initial_cmdsn, uint32_t *hostno) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; + struct Scsi_Host *shost; int i; struct iscsi_task *task; struct iscsi_iser_task *iser_task; - - if (shost) { - printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", - shost->host_no); - return NULL; - } + struct iser_conn *ib_conn; shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN); if (!shost) @@ -426,7 +407,15 @@ iscsi_iser_session_create(struct Scsi_Host *shost, shost->max_channel = 0; shost->max_cmd_len = 16; - if (iscsi_host_add(shost, NULL)) + /* + * older userspace tools (before 2.0-870) did not pass us + * the leading conn's ep so this will be NULL; + */ + if (ep) + ib_conn = ep->dd_data; + + if (iscsi_host_add(shost, + ep ? ib_conn->device->ib_device->dma_device : NULL)) goto free_host; *hostno = shost->host_no; @@ -529,34 +518,37 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s stats->custom[3].value = conn->fmr_unalign_cnt; } -static int -iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking, - __u64 *ep_handle) +static struct iscsi_endpoint * +iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking) { int err; struct iser_conn *ib_conn; + struct iscsi_endpoint *ep; - err = iser_conn_init(&ib_conn); - if (err) - goto out; + ep = iscsi_create_endpoint(sizeof(*ib_conn)); + if (!ep) + return ERR_PTR(-ENOMEM); - err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking); - if (!err) - *ep_handle = (__u64)(unsigned long)ib_conn; + ib_conn = ep->dd_data; + ib_conn->ep = ep; + iser_conn_init(ib_conn); -out: - return err; + err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, + non_blocking); + if (err) { + iscsi_destroy_endpoint(ep); + return ERR_PTR(err); + } + return ep; } static int -iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms) +iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) { - struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); + struct iser_conn *ib_conn; int rc; - if (!ib_conn) - return -EINVAL; - + ib_conn = ep->dd_data; rc = wait_event_interruptible_timeout(ib_conn->wait, ib_conn->state == ISER_CONN_UP, msecs_to_jiffies(timeout_ms)); @@ -578,14 +570,11 @@ iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms) } static void -iscsi_iser_ep_disconnect(__u64 ep_handle) +iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep) { struct iser_conn *ib_conn; - ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); - if (!ib_conn) - return; - + ib_conn = ep->dd_data; if (ib_conn->iser_conn) /* * Must suspend xmit path if the ep is bound to the diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 05431f2..cdf4876 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -174,6 +174,7 @@ struct iser_data_buf { struct iser_device; struct iscsi_iser_conn; struct iscsi_iser_task; +struct iscsi_endpoint; struct iser_mem_reg { u32 lkey; @@ -241,6 +242,7 @@ struct iser_device { struct iser_conn { struct iscsi_iser_conn *iser_conn; /* iser conn for upcalls */ + struct iscsi_endpoint *ep; enum iser_ib_conn_state state; /* rdma connection state */ atomic_t refcount; spinlock_t lock; /* used for state changes */ @@ -313,7 +315,7 @@ void iscsi_iser_recv(struct iscsi_conn *conn, char *rx_data, int rx_data_len); -int iser_conn_init(struct iser_conn **ib_conn); +void iser_conn_init(struct iser_conn *ib_conn); void iser_conn_get(struct iser_conn *ib_conn); diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 5daed2b..81b45d4 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -325,7 +325,7 @@ static void iser_conn_release(struct iser_conn *ib_conn) iser_device_try_release(device); if (ib_conn->iser_conn) ib_conn->iser_conn->ib_conn = NULL; - kfree(ib_conn); + iscsi_destroy_endpoint(ib_conn->ep); } void iser_conn_get(struct iser_conn *ib_conn) @@ -494,15 +494,8 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve return ret; } -int iser_conn_init(struct iser_conn **ibconn) +void iser_conn_init(struct iser_conn *ib_conn) { - struct iser_conn *ib_conn; - - ib_conn = kzalloc(sizeof *ib_conn, GFP_KERNEL); - if (!ib_conn) { - iser_err("can't alloc memory for struct iser_conn\n"); - return -ENOMEM; - } ib_conn->state = ISER_CONN_INIT; init_waitqueue_head(&ib_conn->wait); atomic_set(&ib_conn->post_recv_buf_count, 0); @@ -510,9 +503,6 @@ int iser_conn_init(struct iser_conn **ibconn) atomic_set(&ib_conn->refcount, 1); INIT_LIST_HEAD(&ib_conn->conn_list); spin_lock_init(&ib_conn->lock); - - *ibconn = ib_conn; - return 0; } /** -- cgit v0.10.2 From 06520edea0fc7007985fa4cd51560149feb3f442 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:15 -0500 Subject: [SCSI] iscsi_tcp: hook iscsi_tcp into iscsi_endpoint code iscsi_tcp creates its ep in userspace using sockets because it is virtual, so we just check if we are sent a ep and fail if we are. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index aa3c7f0..92d0319 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1838,17 +1838,17 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) } static struct iscsi_cls_session * -iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max, +iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, uint16_t qdepth, uint32_t initial_cmdsn, uint32_t *hostno) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; + struct Scsi_Host *shost; int cmd_i; - if (shost) { - printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", - shost->host_no); + if (ep) { + printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep); return NULL; } -- cgit v0.10.2 From 88dfd340b9dece8fcaa1a2d4c782338926c017f7 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:16 -0500 Subject: [SCSI] iscsi class: Add session initiatorname and ifacename sysfs attrs. This adds two new attrs used for creating initiator ports and binding sessions to hardware. The session level initiatorname: Since bnx2i does a scsi_host per host device, we need to add the iface initiator port settings on the session, so we can create multiple initiator ports (each with different inames) per device/scsi_host. The current iname reflects that qla4xxx can have one iname per hba, and we are allocating a host per session for software. The iname on the host will remain so we can export and set the hba level qla4xxx setting. The ifacename attr: To bind a session to a some peice of hardware in userspace we maintain some mappings, but during boot or iscsid restart (iscsid contains the user space part of the driver) we need to be able to figure out which of those host mappings abstractions maps to certain sessions. This patch adds a ifacename attr, which userspace can set to id the host side of the endpoint across pivot_roots and iscsid restarts. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 42e95b8..08edbaf 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -629,7 +629,8 @@ static struct iscsi_transport iscsi_iser_transport = { ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | - ISCSI_PING_TMO | ISCSI_RECV_TMO, + ISCSI_PING_TMO | ISCSI_RECV_TMO | + ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME | ISCSI_HOST_INITIATOR_NAME, diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 92d0319..7552dd8 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1957,7 +1957,8 @@ static struct iscsi_transport iscsi_tcp_transport = { ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | ISCSI_LU_RESET_TMO | - ISCSI_PING_TMO | ISCSI_RECV_TMO, + ISCSI_PING_TMO | ISCSI_RECV_TMO | + ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | ISCSI_HOST_INITIATOR_NAME | ISCSI_HOST_NETDEV_NAME, diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index e88b726..c1af2aa 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1990,6 +1990,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) kfree(session->username); kfree(session->username_in); kfree(session->targetname); + kfree(session->initiatorname); + kfree(session->ifacename); iscsi_destroy_session(cls_session); module_put(owner); @@ -2453,6 +2455,14 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn, if (!conn->persistent_address) return -ENOMEM; break; + case ISCSI_PARAM_IFACE_NAME: + if (!session->ifacename) + session->ifacename = kstrdup(buf, GFP_KERNEL); + break; + case ISCSI_PARAM_INITIATOR_NAME: + if (!session->initiatorname) + session->initiatorname = kstrdup(buf, GFP_KERNEL); + break; default: return -ENOSYS; } @@ -2519,6 +2529,15 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session, case ISCSI_PARAM_PASSWORD_IN: len = sprintf(buf, "%s\n", session->password_in); break; + case ISCSI_PARAM_IFACE_NAME: + len = sprintf(buf, "%s\n", session->ifacename); + break; + case ISCSI_PARAM_INITIATOR_NAME: + if (!session->initiatorname) + len = sprintf(buf, "%s\n", "unknown"); + else + len = sprintf(buf, "%s\n", session->initiatorname); + break; default: return -ENOSYS; } @@ -2606,6 +2625,7 @@ int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, else len = sprintf(buf, "%s\n", ihost->local_address); + break; default: return -ENOSYS; } diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index c3c07cc..9fd5c6d 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -30,7 +30,7 @@ #include #include -#define ISCSI_SESSION_ATTRS 19 +#define ISCSI_SESSION_ATTRS 21 #define ISCSI_CONN_ATTRS 13 #define ISCSI_HOST_ATTRS 4 @@ -1634,6 +1634,8 @@ iscsi_session_attr(password_in, ISCSI_PARAM_PASSWORD_IN, 1); iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0); iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0); iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0); +iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0); +iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0) static ssize_t show_priv_session_state(struct device *dev, struct device_attribute *attr, @@ -1875,6 +1877,8 @@ iscsi_register_transport(struct iscsi_transport *tt) SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT); SETUP_SESSION_RD_ATTR(abort_tmo, ISCSI_ABORT_TMO); SETUP_SESSION_RD_ATTR(lu_reset_tmo,ISCSI_LU_RESET_TMO); + SETUP_SESSION_RD_ATTR(ifacename, ISCSI_IFACE_NAME); + SETUP_SESSION_RD_ATTR(initiatorname, ISCSI_INITIATOR_NAME); SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); SETUP_PRIV_SESSION_RD_ATTR(state); diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index a0f13a2..16be12f 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -257,42 +257,49 @@ enum iscsi_param { ISCSI_PARAM_PING_TMO, ISCSI_PARAM_RECV_TMO, + + ISCSI_PARAM_IFACE_NAME, + ISCSI_PARAM_ISID, + ISCSI_PARAM_INITIATOR_NAME, /* must always be last */ ISCSI_PARAM_MAX, }; -#define ISCSI_MAX_RECV_DLENGTH (1 << ISCSI_PARAM_MAX_RECV_DLENGTH) -#define ISCSI_MAX_XMIT_DLENGTH (1 << ISCSI_PARAM_MAX_XMIT_DLENGTH) -#define ISCSI_HDRDGST_EN (1 << ISCSI_PARAM_HDRDGST_EN) -#define ISCSI_DATADGST_EN (1 << ISCSI_PARAM_DATADGST_EN) -#define ISCSI_INITIAL_R2T_EN (1 << ISCSI_PARAM_INITIAL_R2T_EN) -#define ISCSI_MAX_R2T (1 << ISCSI_PARAM_MAX_R2T) -#define ISCSI_IMM_DATA_EN (1 << ISCSI_PARAM_IMM_DATA_EN) -#define ISCSI_FIRST_BURST (1 << ISCSI_PARAM_FIRST_BURST) -#define ISCSI_MAX_BURST (1 << ISCSI_PARAM_MAX_BURST) -#define ISCSI_PDU_INORDER_EN (1 << ISCSI_PARAM_PDU_INORDER_EN) -#define ISCSI_DATASEQ_INORDER_EN (1 << ISCSI_PARAM_DATASEQ_INORDER_EN) -#define ISCSI_ERL (1 << ISCSI_PARAM_ERL) -#define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN) -#define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN) -#define ISCSI_EXP_STATSN (1 << ISCSI_PARAM_EXP_STATSN) -#define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME) -#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT) -#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS) -#define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT) -#define ISCSI_SESS_RECOVERY_TMO (1 << ISCSI_PARAM_SESS_RECOVERY_TMO) -#define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT) -#define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS) -#define ISCSI_USERNAME (1 << ISCSI_PARAM_USERNAME) -#define ISCSI_USERNAME_IN (1 << ISCSI_PARAM_USERNAME_IN) -#define ISCSI_PASSWORD (1 << ISCSI_PARAM_PASSWORD) -#define ISCSI_PASSWORD_IN (1 << ISCSI_PARAM_PASSWORD_IN) -#define ISCSI_FAST_ABORT (1 << ISCSI_PARAM_FAST_ABORT) -#define ISCSI_ABORT_TMO (1 << ISCSI_PARAM_ABORT_TMO) -#define ISCSI_LU_RESET_TMO (1 << ISCSI_PARAM_LU_RESET_TMO) -#define ISCSI_HOST_RESET_TMO (1 << ISCSI_PARAM_HOST_RESET_TMO) -#define ISCSI_PING_TMO (1 << ISCSI_PARAM_PING_TMO) -#define ISCSI_RECV_TMO (1 << ISCSI_PARAM_RECV_TMO) +#define ISCSI_MAX_RECV_DLENGTH (1ULL << ISCSI_PARAM_MAX_RECV_DLENGTH) +#define ISCSI_MAX_XMIT_DLENGTH (1ULL << ISCSI_PARAM_MAX_XMIT_DLENGTH) +#define ISCSI_HDRDGST_EN (1ULL << ISCSI_PARAM_HDRDGST_EN) +#define ISCSI_DATADGST_EN (1ULL << ISCSI_PARAM_DATADGST_EN) +#define ISCSI_INITIAL_R2T_EN (1ULL << ISCSI_PARAM_INITIAL_R2T_EN) +#define ISCSI_MAX_R2T (1ULL << ISCSI_PARAM_MAX_R2T) +#define ISCSI_IMM_DATA_EN (1ULL << ISCSI_PARAM_IMM_DATA_EN) +#define ISCSI_FIRST_BURST (1ULL << ISCSI_PARAM_FIRST_BURST) +#define ISCSI_MAX_BURST (1ULL << ISCSI_PARAM_MAX_BURST) +#define ISCSI_PDU_INORDER_EN (1ULL << ISCSI_PARAM_PDU_INORDER_EN) +#define ISCSI_DATASEQ_INORDER_EN (1ULL << ISCSI_PARAM_DATASEQ_INORDER_EN) +#define ISCSI_ERL (1ULL << ISCSI_PARAM_ERL) +#define ISCSI_IFMARKER_EN (1ULL << ISCSI_PARAM_IFMARKER_EN) +#define ISCSI_OFMARKER_EN (1ULL << ISCSI_PARAM_OFMARKER_EN) +#define ISCSI_EXP_STATSN (1ULL << ISCSI_PARAM_EXP_STATSN) +#define ISCSI_TARGET_NAME (1ULL << ISCSI_PARAM_TARGET_NAME) +#define ISCSI_TPGT (1ULL << ISCSI_PARAM_TPGT) +#define ISCSI_PERSISTENT_ADDRESS (1ULL << ISCSI_PARAM_PERSISTENT_ADDRESS) +#define ISCSI_PERSISTENT_PORT (1ULL << ISCSI_PARAM_PERSISTENT_PORT) +#define ISCSI_SESS_RECOVERY_TMO (1ULL << ISCSI_PARAM_SESS_RECOVERY_TMO) +#define ISCSI_CONN_PORT (1ULL << ISCSI_PARAM_CONN_PORT) +#define ISCSI_CONN_ADDRESS (1ULL << ISCSI_PARAM_CONN_ADDRESS) +#define ISCSI_USERNAME (1ULL << ISCSI_PARAM_USERNAME) +#define ISCSI_USERNAME_IN (1ULL << ISCSI_PARAM_USERNAME_IN) +#define ISCSI_PASSWORD (1ULL << ISCSI_PARAM_PASSWORD) +#define ISCSI_PASSWORD_IN (1ULL << ISCSI_PARAM_PASSWORD_IN) +#define ISCSI_FAST_ABORT (1ULL << ISCSI_PARAM_FAST_ABORT) +#define ISCSI_ABORT_TMO (1ULL << ISCSI_PARAM_ABORT_TMO) +#define ISCSI_LU_RESET_TMO (1ULL << ISCSI_PARAM_LU_RESET_TMO) +#define ISCSI_HOST_RESET_TMO (1ULL << ISCSI_PARAM_HOST_RESET_TMO) +#define ISCSI_PING_TMO (1ULL << ISCSI_PARAM_PING_TMO) +#define ISCSI_RECV_TMO (1ULL << ISCSI_PARAM_RECV_TMO) +#define ISCSI_IFACE_NAME (1ULL << ISCSI_PARAM_IFACE_NAME) +#define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID) +#define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME) /* iSCSI HBA params */ enum iscsi_host_param { @@ -303,10 +310,10 @@ enum iscsi_host_param { ISCSI_HOST_PARAM_MAX, }; -#define ISCSI_HOST_HWADDRESS (1 << ISCSI_HOST_PARAM_HWADDRESS) -#define ISCSI_HOST_INITIATOR_NAME (1 << ISCSI_HOST_PARAM_INITIATOR_NAME) -#define ISCSI_HOST_NETDEV_NAME (1 << ISCSI_HOST_PARAM_NETDEV_NAME) -#define ISCSI_HOST_IPADDRESS (1 << ISCSI_HOST_PARAM_IPADDRESS) +#define ISCSI_HOST_HWADDRESS (1ULL << ISCSI_HOST_PARAM_HWADDRESS) +#define ISCSI_HOST_INITIATOR_NAME (1ULL << ISCSI_HOST_PARAM_INITIATOR_NAME) +#define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME) +#define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS) #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 13c92d7..21cfb1d 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -270,6 +270,8 @@ struct iscsi_session { char *password; char *password_in; char *targetname; + char *ifacename; + char *initiatorname; /* control data */ struct iscsi_transport *tt; struct Scsi_Host *host; -- cgit v0.10.2 From 3cf7b233ffc45d4fc381221f74d24f10e692c4ea Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:17 -0500 Subject: [SCSI] libiscsi: fix cmds_max setting Drivers expect that the cmds_max value they pass to the iscsi layer is the max scsi commands + mgmt tasks. This patch implements that and fixes some checks for nr cmd limits. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c1af2aa..c723e60 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1893,29 +1893,48 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); * * This can be used by software iscsi_transports that allocate * a session per scsi host. + * + * Callers should set cmds_max to the largest total numer (mgmt + scsi) of + * tasks they support. The iscsi layer reserves ISCSI_MGMT_CMDS_MAX tasks + * for nop handling and login/logout requests. */ struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, - uint16_t scsi_cmds_max, int cmd_task_size, + uint16_t cmds_max, int cmd_task_size, uint32_t initial_cmdsn, unsigned int id) { struct iscsi_session *session; struct iscsi_cls_session *cls_session; - int cmd_i, cmds_max; - + int cmd_i, scsi_cmds, total_cmds = cmds_max; /* - * The iscsi layer needs some tasks for nop handling and tmfs. + * The iscsi layer needs some tasks for nop handling and tmfs, + * so the cmds_max must at least be greater than ISCSI_MGMT_CMDS_MAX + * + 1 command for scsi IO. */ - if (scsi_cmds_max < 1) - scsi_cmds_max = ISCSI_MGMT_CMDS_MAX; - if ((scsi_cmds_max + ISCSI_MGMT_CMDS_MAX) >= ISCSI_MGMT_ITT_OFFSET) { - printk(KERN_ERR "iscsi: invalid can_queue of %d. " - "can_queue must be less than %d.\n", - scsi_cmds_max, - ISCSI_MGMT_ITT_OFFSET - ISCSI_MGMT_CMDS_MAX); - scsi_cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; + if (total_cmds < ISCSI_TOTAL_CMDS_MIN) { + printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue " + "must be a power of two that is at least %d.\n", + total_cmds, ISCSI_TOTAL_CMDS_MIN); + return NULL; + } + + if (total_cmds > ISCSI_TOTAL_CMDS_MAX) { + printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue " + "must be a power of 2 less than or equal to %d.\n", + cmds_max, ISCSI_TOTAL_CMDS_MAX); + total_cmds = ISCSI_TOTAL_CMDS_MAX; + } + + if (!is_power_of_2(total_cmds)) { + printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue " + "must be a power of 2.\n", total_cmds); + total_cmds = rounddown_pow_of_two(total_cmds); + if (total_cmds < ISCSI_TOTAL_CMDS_MIN) + return NULL; + printk(KERN_INFO "iscsi: Rounding can_queue to %d.\n", + total_cmds); } - cmds_max = roundup_pow_of_two(scsi_cmds_max + ISCSI_MGMT_CMDS_MAX); + scsi_cmds = total_cmds - ISCSI_MGMT_CMDS_MAX; cls_session = iscsi_alloc_session(shost, iscsit, sizeof(struct iscsi_session)); @@ -1928,8 +1947,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, session->fast_abort = 1; session->lu_reset_timeout = 15; session->abort_timeout = 10; - session->scsi_cmds_max = scsi_cmds_max; - session->cmds_max = cmds_max; + session->scsi_cmds_max = scsi_cmds; + session->cmds_max = total_cmds; session->queued_cmdsn = session->cmdsn = initial_cmdsn; session->exp_cmdsn = initial_cmdsn + 1; session->max_cmdsn = initial_cmdsn + 1; diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 21cfb1d..5bf0187 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -52,9 +52,7 @@ struct device; #endif #define ISCSI_DEF_XMIT_CMDS_MAX 128 /* must be power of 2 */ -#define ISCSI_MGMT_CMDS_MAX 16 /* must be power of 2 */ - -#define ISCSI_MGMT_ITT_OFFSET 0xa00 +#define ISCSI_MGMT_CMDS_MAX 15 #define ISCSI_DEF_CMD_PER_LUN 32 #define ISCSI_MAX_CMD_PER_LUN 128 @@ -72,7 +70,10 @@ enum { /* Connection suspend "bit" */ #define ISCSI_SUSPEND_BIT 1 -#define ISCSI_ITT_MASK (0xfff) +#define ISCSI_ITT_MASK (0x1fff) +#define ISCSI_TOTAL_CMDS_MAX 4096 +/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ +#define ISCSI_TOTAL_CMDS_MIN 16 #define ISCSI_AGE_SHIFT 28 #define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) -- cgit v0.10.2 From 913e5bf435617aa529919a4f7567f849f9f35f9f Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 21 May 2008 15:54:18 -0500 Subject: [SCSI] libiscsi, iser, tcp: remove recv_lock The recv lock was defined so the iscsi layer could block the recv path from processing IO during recovery. It turns out iser just set a lock to that pointer which was pointless. We now disconnect the transport connection before doing recovery so we do not need the recv lock. For iscsi_tcp we still stop the recv path incase older tools are being used. This patch also has iscsi_itt_to_ctask user grab the session lock and has the caller access the task with the lock or get a ref to it in case the target is broken and sends a tmf success response then sends data or a response for the command that was supposed to be affected bty the tmf. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 08edbaf..c02eabd 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -281,9 +281,6 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) conn->max_recv_dlength = 128; iser_conn = conn->dd_data; - /* currently this is the only field which need to be initiated */ - rwlock_init(&iser_conn->lock); - conn->dd_data = iser_conn; iser_conn->iscsi_conn = conn; @@ -342,9 +339,6 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, ib_conn->iser_conn = iser_conn; iser_conn->ib_conn = ib_conn; iser_conn_get(ib_conn); - - conn->recv_lock = &iser_conn->lock; - return 0; } @@ -355,12 +349,18 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) struct iscsi_iser_conn *iser_conn = conn->dd_data; struct iser_conn *ib_conn = iser_conn->ib_conn; - iscsi_conn_stop(cls_conn, flag); /* - * There is no unbind event so the stop callback - * must release the ref from the bind. + * Userspace may have goofed up and not bound the connection or + * might have only partially setup the connection. */ - iser_conn_put(ib_conn); + if (ib_conn) { + iscsi_conn_stop(cls_conn, flag); + /* + * There is no unbind event so the stop callback + * must release the ref from the bind. + */ + iser_conn_put(ib_conn); + } iser_conn->ib_conn = NULL; } diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index cdf4876..a547ede 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -263,8 +263,6 @@ struct iser_conn { struct iscsi_iser_conn { struct iscsi_conn *iscsi_conn;/* ptr to iscsi conn */ struct iser_conn *ib_conn; /* iSER IB conn */ - - rwlock_t lock; }; struct iscsi_iser_task { diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 35af60a..c360839 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -558,7 +558,12 @@ void iser_rcv_completion(struct iser_desc *rx_desc, opcode = hdr->opcode & ISCSI_OPCODE_MASK; if (opcode == ISCSI_OP_SCSI_CMD_RSP) { + spin_lock(&conn->iscsi_conn->session->lock); task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt); + if (task) + __iscsi_get_task(task); + spin_unlock(&conn->iscsi_conn->session->lock); + if (!task) iser_err("itt can't be matched to task!!! " "conn %p opcode %d itt %d\n", @@ -568,6 +573,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, iser_dbg("itt %d task %p\n",hdr->itt, task); iser_task->status = ISER_TASK_STATUS_COMPLETED; iser_task_rdma_finalize(iser_task); + iscsi_put_task(task); } } iser_dto_buffs_release(dto); diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 7552dd8..91cb1fd 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -741,7 +741,6 @@ static int iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) { int rc = 0, opcode, ahslen; - struct iscsi_session *session = conn->session; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_task *task; @@ -770,17 +769,17 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) switch(opcode) { case ISCSI_OP_SCSI_DATA_IN: + spin_lock(&conn->session->lock); task = iscsi_itt_to_ctask(conn, hdr->itt); if (!task) - return ISCSI_ERR_BAD_ITT; - if (!task->sc) - return ISCSI_ERR_NO_SCSI_CMD; + rc = ISCSI_ERR_BAD_ITT; + else + rc = iscsi_data_rsp(conn, task); + if (rc) { + spin_unlock(&conn->session->lock); + break; + } - spin_lock(&conn->session->lock); - rc = iscsi_data_rsp(conn, task); - spin_unlock(&conn->session->lock); - if (rc) - return rc; if (tcp_conn->in.datalen) { struct iscsi_tcp_task *tcp_task = task->dd_data; struct hash_desc *rx_hash = NULL; @@ -801,15 +800,19 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) "datalen=%d)\n", tcp_conn, tcp_task->data_offset, tcp_conn->in.datalen); - return iscsi_segment_seek_sg(&tcp_conn->in.segment, - sdb->table.sgl, - sdb->table.nents, - tcp_task->data_offset, - tcp_conn->in.datalen, - iscsi_tcp_process_data_in, - rx_hash); + rc = iscsi_segment_seek_sg(&tcp_conn->in.segment, + sdb->table.sgl, + sdb->table.nents, + tcp_task->data_offset, + tcp_conn->in.datalen, + iscsi_tcp_process_data_in, + rx_hash); + spin_unlock(&conn->session->lock); + return rc; } - /* fall through */ + rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); + spin_unlock(&conn->session->lock); + break; case ISCSI_OP_SCSI_CMD_RSP: if (tcp_conn->in.datalen) { iscsi_tcp_data_recv_prep(tcp_conn); @@ -818,20 +821,17 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) rc = iscsi_complete_pdu(conn, hdr, NULL, 0); break; case ISCSI_OP_R2T: + spin_lock(&conn->session->lock); task = iscsi_itt_to_ctask(conn, hdr->itt); if (!task) - return ISCSI_ERR_BAD_ITT; - if (!task->sc) - return ISCSI_ERR_NO_SCSI_CMD; - - if (ahslen) + rc = ISCSI_ERR_BAD_ITT; + else if (ahslen) rc = ISCSI_ERR_AHSLEN; - else if (task->sc->sc_data_direction == DMA_TO_DEVICE) { - spin_lock(&session->lock); + else if (task->sc->sc_data_direction == DMA_TO_DEVICE) rc = iscsi_r2t_rsp(conn, task); - spin_unlock(&session->lock); - } else + else rc = ISCSI_ERR_PROTO; + spin_unlock(&conn->session->lock); break; case ISCSI_OP_LOGIN_RSP: case ISCSI_OP_TEXT_RSP: @@ -1553,7 +1553,6 @@ iscsi_tcp_release_conn(struct iscsi_conn *conn) spin_lock_bh(&session->lock); tcp_conn->sock = NULL; - conn->recv_lock = NULL; spin_unlock_bh(&session->lock); sockfd_put(sock); } @@ -1578,6 +1577,19 @@ static void iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) { struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + + /* userspace may have goofed up and not bound us */ + if (!tcp_conn->sock) + return; + /* + * Make sure our recv side is stopped. + * Older tools called conn stop before ep_disconnect + * so IO could still be coming in. + */ + write_lock_bh(&tcp_conn->sock->sk->sk_callback_lock); + set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&tcp_conn->sock->sk->sk_callback_lock); iscsi_conn_stop(cls_conn, flag); iscsi_tcp_release_conn(conn); @@ -1671,13 +1683,6 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ sk->sk_allocation = GFP_ATOMIC; - /* FIXME: disable Nagle's algorithm */ - - /* - * Intercept TCP callbacks for sendfile like receive - * processing. - */ - conn->recv_lock = &sk->sk_callback_lock; iscsi_conn_set_callbacks(conn); tcp_conn->sendpage = tcp_conn->sock->ops->sendpage; /* diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c723e60..9c267b4 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -362,10 +362,11 @@ static void iscsi_complete_command(struct iscsi_task *task) } } -static void __iscsi_get_task(struct iscsi_task *task) +void __iscsi_get_task(struct iscsi_task *task) { atomic_inc(&task->refcount); } +EXPORT_SYMBOL_GPL(__iscsi_get_task); static void __iscsi_put_task(struct iscsi_task *task) { @@ -403,9 +404,13 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task, conn->session->queued_cmdsn--; else conn->session->tt->cleanup_task(conn, task); + /* + * Check if cleanup_task dropped the lock and the command completed, + */ + if (!task->sc) + return; sc->result = err; - if (!scsi_bidi_cmnd(sc)) scsi_set_resid(sc, scsi_bufflen(sc)); else { @@ -697,6 +702,31 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } /** + * iscsi_itt_to_task - look up task by itt + * @conn: iscsi connection + * @itt: itt + * + * This should be used for mgmt tasks like login and nops, or if + * the LDD's itt space does not include the session age. + * + * The session lock must be held. + */ +static struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt) +{ + struct iscsi_session *session = conn->session; + uint32_t i; + + if (itt == RESERVED_ITT) + return NULL; + + i = get_itt(itt); + if (i >= session->cmds_max) + return NULL; + + return session->cmds[i]; +} + +/** * __iscsi_complete_pdu - complete pdu * @conn: iscsi conn * @hdr: iscsi header @@ -707,8 +737,8 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * queuecommand or send generic. session lock must be held and verify * itt must have been called. */ -static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - char *data, int datalen) +int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, + char *data, int datalen) { struct iscsi_session *session = conn->session; int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; @@ -758,22 +788,36 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto out; } - task = session->cmds[itt]; switch(opcode) { case ISCSI_OP_SCSI_CMD_RSP: - if (!task->sc) { - rc = ISCSI_ERR_NO_SCSI_CMD; - break; - } - BUG_ON((void*)task != task->sc->SCp.ptr); + case ISCSI_OP_SCSI_DATA_IN: + task = iscsi_itt_to_ctask(conn, hdr->itt); + if (!task) + return ISCSI_ERR_BAD_ITT; + break; + case ISCSI_OP_R2T: + /* + * LLD handles R2Ts if they need to. + */ + return 0; + case ISCSI_OP_LOGOUT_RSP: + case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_SCSI_TMFUNC_RSP: + case ISCSI_OP_NOOP_IN: + task = iscsi_itt_to_task(conn, hdr->itt); + if (!task) + return ISCSI_ERR_BAD_ITT; + break; + default: + return ISCSI_ERR_BAD_OPCODE; + } + + switch(opcode) { + case ISCSI_OP_SCSI_CMD_RSP: iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); break; case ISCSI_OP_SCSI_DATA_IN: - if (!task->sc) { - rc = ISCSI_ERR_NO_SCSI_CMD; - break; - } - BUG_ON((void*)task != task->sc->SCp.ptr); if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { conn->scsirsp_pdus_cnt++; iscsi_update_cmdsn(session, @@ -781,9 +825,6 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, __iscsi_put_task(task); } break; - case ISCSI_OP_R2T: - /* LLD handles this for now */ - break; case ISCSI_OP_LOGOUT_RSP: iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); if (datalen) { @@ -841,6 +882,7 @@ recv_pdu: __iscsi_put_task(task); return rc; } +EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, int datalen) @@ -857,7 +899,6 @@ EXPORT_SYMBOL_GPL(iscsi_complete_pdu); int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) { struct iscsi_session *session = conn->session; - struct iscsi_task *task; uint32_t i; if (itt == RESERVED_ITT) @@ -867,8 +908,7 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) (session->age << ISCSI_AGE_SHIFT)) { iscsi_conn_printk(KERN_ERR, conn, "received itt %x expected session age (%x)\n", - (__force u32)itt, - session->age & ISCSI_AGE_MASK); + (__force u32)itt, session->age); return ISCSI_ERR_BAD_ITT; } @@ -879,42 +919,36 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) "%u.\n", i, session->cmds_max); return ISCSI_ERR_BAD_ITT; } - - task = session->cmds[i]; - if (task->sc && task->sc->SCp.phase != session->age) { - iscsi_conn_printk(KERN_ERR, conn, - "iscsi: task's session age %d, " - "expected %d\n", task->sc->SCp.phase, - session->age); - return ISCSI_ERR_SESSION_FAILED; - } return 0; } EXPORT_SYMBOL_GPL(iscsi_verify_itt); -struct iscsi_task * -iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) +/** + * iscsi_itt_to_ctask - look up ctask by itt + * @conn: iscsi connection + * @itt: itt + * + * This should be used for cmd tasks. + * + * The session lock must be held. + */ +struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) { - struct iscsi_session *session = conn->session; struct iscsi_task *task; - uint32_t i; if (iscsi_verify_itt(conn, itt)) return NULL; - if (itt == RESERVED_ITT) + task = iscsi_itt_to_task(conn, itt); + if (!task || !task->sc) return NULL; - i = get_itt(itt); - if (i >= session->cmds_max) - return NULL; - - task = session->cmds[i]; - if (!task->sc) - return NULL; - - if (task->sc->SCp.phase != session->age) + if (task->sc->SCp.phase != conn->session->age) { + iscsi_session_printk(KERN_ERR, conn->session, + "task's session age %d, expected %d\n", + task->sc->SCp.phase, conn->session->age); return NULL; + } return task; } @@ -1620,16 +1654,20 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) switch (conn->tmf_state) { case TMF_SUCCESS: spin_unlock_bh(&session->lock); + /* + * stop tx side incase the target had sent a abort rsp but + * the initiator was still writing out data. + */ iscsi_suspend_tx(conn); /* - * clean up task if aborted. grab the recv lock as a writer + * we do not stop the recv side because targets have been + * good and have never sent us a successful tmf response + * then sent more data for the cmd. */ - write_lock_bh(conn->recv_lock); spin_lock(&session->lock); fail_command(conn, task, DID_ABORT << 16); conn->tmf_state = TMF_INITIAL; spin_unlock(&session->lock); - write_unlock_bh(conn->recv_lock); iscsi_start_tx(conn); goto success_unlocked; case TMF_TIMEDOUT: @@ -1729,13 +1767,11 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) spin_unlock_bh(&session->lock); iscsi_suspend_tx(conn); - /* need to grab the recv lock then session lock */ - write_lock_bh(conn->recv_lock); + spin_lock(&session->lock); fail_all_commands(conn, sc->device->lun, DID_ERROR); conn->tmf_state = TMF_INITIAL; spin_unlock(&session->lock); - write_unlock_bh(conn->recv_lock); iscsi_start_tx(conn); goto done; @@ -2257,17 +2293,6 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, } /* - * The LLD either freed/unset the lock on us, or userspace called - * stop but did not create a proper connection (connection was never - * bound or it was unbound then stop was called). - */ - if (!conn->recv_lock) { - spin_unlock_bh(&session->lock); - mutex_unlock(&session->eh_mutex); - return; - } - - /* * When this is called for the in_login state, we only want to clean * up the login task and connection. We do not need to block and set * the recovery state again @@ -2283,11 +2308,6 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, spin_unlock_bh(&session->lock); iscsi_suspend_tx(conn); - - write_lock_bh(conn->recv_lock); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); - write_unlock_bh(conn->recv_lock); - /* * for connection level recovery we should not calculate * header digest. conn->hdr_size used for optimization diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 5bf0187..5e75bb7 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -139,11 +139,6 @@ struct iscsi_conn { void *dd_data; /* iscsi_transport data */ struct iscsi_session *session; /* parent session */ /* - * LLDs should set this lock. It protects the transport recv - * code - */ - rwlock_t *recv_lock; - /* * conn_stop() flag: stop to recover, stop to terminate */ int stop_stage; @@ -374,10 +369,13 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, char *, int); +extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, + char *, int); extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); extern void iscsi_requeue_task(struct iscsi_task *task); extern void iscsi_put_task(struct iscsi_task *task); +extern void __iscsi_get_task(struct iscsi_task *task); /* * generic helpers -- cgit v0.10.2 From 3a12b199fc820a52b8321c2b35172a1b3651120d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 21 May 2008 15:54:19 -0500 Subject: [SCSI] Replace __FUNCTION__ with __func__ in iscsi_tcp. __FUNCTION__ is gcc-specific, use __func__ (Update diff by Mike Christie) Signed-off-by: Harvey Harrison Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 91cb1fd..7c4ee39 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -544,7 +544,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task) if (tcp_task->exp_datasn != datasn) { debug_tcp("%s: task->exp_datasn(%d) != rhdr->datasn(%d)\n", - __FUNCTION__, tcp_task->exp_datasn, datasn); + __func__, tcp_task->exp_datasn, datasn); return ISCSI_ERR_DATASN; } @@ -553,7 +553,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task) tcp_task->data_offset = be32_to_cpu(rhdr->offset); if (tcp_task->data_offset + tcp_conn->in.datalen > total_in_length) { debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", - __FUNCTION__, tcp_task->data_offset, + __func__, tcp_task->data_offset, tcp_conn->in.datalen, total_in_length); return ISCSI_ERR_DATA_OFFSET; } @@ -646,7 +646,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) if (tcp_task->exp_datasn != r2tsn){ debug_tcp("%s: task->exp_datasn(%d) != rhdr->r2tsn(%d)\n", - __FUNCTION__, tcp_task->exp_datasn, r2tsn); + __func__, tcp_task->exp_datasn, r2tsn); return ISCSI_ERR_R2TSN; } @@ -1193,7 +1193,7 @@ iscsi_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr, size_t hdrlen) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - debug_tcp("%s(%p%s)\n", __FUNCTION__, tcp_conn, + debug_tcp("%s(%p%s)\n", __func__, tcp_conn, conn->hdrdgst_en? ", digest enabled" : ""); /* Clear the data segment - needs to be filled in by the @@ -1234,7 +1234,7 @@ iscsi_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg, struct hash_desc *tx_hash = NULL; unsigned int hdr_spec_len; - debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __FUNCTION__, + debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __func__, tcp_conn, offset, len, conn->datadgst_en? ", digest enabled" : ""); @@ -1259,7 +1259,7 @@ iscsi_tcp_send_linear_data_prepare(struct iscsi_conn *conn, void *data, struct hash_desc *tx_hash = NULL; unsigned int hdr_spec_len; - debug_tcp("%s(%p, datalen=%d%s)\n", __FUNCTION__, tcp_conn, len, + debug_tcp("%s(%p, datalen=%d%s)\n", __func__, tcp_conn, len, conn->datadgst_en? ", digest enabled" : ""); /* Make sure the datalen matches what the caller -- cgit v0.10.2 From 8f333991ba8479fe8a9d72aea978db415e3c2f2a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 21 May 2008 15:54:20 -0500 Subject: [SCSI] scsi: use get_unaligned_* helpers Signed-off-by: Harvey Harrison Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 9c267b4..8b4e412 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -591,7 +591,7 @@ invalid_datalen: goto out; } - senselen = be16_to_cpu(get_unaligned((__be16 *) data)); + senselen = get_unaligned_be16(data); if (datalen < senselen) goto invalid_datalen; -- cgit v0.10.2 From 30e9ba9f2001f45960507f1963551311a67d0209 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Mon, 26 May 2008 11:31:19 +0300 Subject: [SCSI] iscsi_tcp: Enable any size command Let through upto the largest command of 260 defined by the scsi standard. iscsi core supports this already. Now that the scsi-ml supports it we can start using large commands. [jejb:rejections fixed up] Signed-off-by: Boaz Harrosh Acked-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 7c4ee39..0bd8b3d 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1864,7 +1864,7 @@ iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, shost->max_lun = iscsi_max_lun; shost->max_id = 0; shost->max_channel = 0; - shost->max_cmd_len = 16; + shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE; shost->can_queue = cmds_max; if (iscsi_host_add(shost, NULL)) diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index e0593bf..f2a2c11 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -22,6 +22,7 @@ #define ISCSI_PROTO_H #include +#include #define ISCSI_DRAFT20_VERSION 0x00 @@ -156,7 +157,7 @@ struct iscsi_ecdb_ahdr { uint8_t ahstype; uint8_t reserved; /* 4-byte aligned extended CDB spillover */ - uint8_t ecdb[260 - ISCSI_CDB_SIZE]; + uint8_t ecdb[SCSI_MAX_VARLEN_CDB_SIZE - ISCSI_CDB_SIZE]; }; /* SCSI Response Header */ -- cgit v0.10.2 From 3f27e3ed11e67c5ee19d560a50eafd93cf8c6682 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 29 May 2008 07:56:55 +0900 Subject: [SCSI] bsg: fix bsg_mutex hang with device removal We don't need to hold bsg_mutex during bsg_complete_all_commands(). It leads to a problem that we block bsg_unregister_queue during bsg_complete_all_commands (untill all the outstanding commands complete). Thanks to Pete Wyckoff for finding the bug and testing the patch. The detailed bug report is: http://marc.info/?l=linux-scsi&m=121182137132145&w=2 Tested-by: Pete Wyckoff Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley diff --git a/block/bsg.c b/block/bsg.c index f0b7cd3..7cdec32 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -724,8 +724,13 @@ static int bsg_put_device(struct bsg_device *bd) mutex_lock(&bsg_mutex); do_free = atomic_dec_and_test(&bd->ref_count); - if (!do_free) + if (!do_free) { + mutex_unlock(&bsg_mutex); goto out; + } + + hlist_del(&bd->dev_list); + mutex_unlock(&bsg_mutex); dprintk("%s: tearing down\n", bd->name); @@ -741,10 +746,8 @@ static int bsg_put_device(struct bsg_device *bd) */ ret = bsg_complete_all_commands(bd); - hlist_del(&bd->dev_list); kfree(bd); out: - mutex_unlock(&bsg_mutex); kref_put(&q->bsg_dev.ref, bsg_kref_release_function); if (do_free) blk_put_queue(q); -- cgit v0.10.2 From 597136ab70a6dccba5c40ee6eed88e881412429b Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 5 Jun 2008 00:12:59 -0400 Subject: [SCSI] scsi_debug: Runtime-configurable sector size Make scsi_debug sector size configurable at load time instead of being a #define. Handy for testing 4KB sectors. Signed-off-by: Martin K. Petersen Acked-by: Douglas Gilbert Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index f6600bf..3901125 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -94,6 +94,7 @@ static const char * scsi_debug_version_date = "20070104"; #define DEF_VIRTUAL_GB 0 #define DEF_FAKE_RW 0 #define DEF_VPD_USE_HOSTNO 1 +#define DEF_SECTOR_SIZE 512 /* bit mask values for scsi_debug_opts */ #define SCSI_DEBUG_OPT_NOISE 1 @@ -142,6 +143,7 @@ static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB; static int scsi_debug_fake_rw = DEF_FAKE_RW; static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO; +static int scsi_debug_sector_size = DEF_SECTOR_SIZE; static int scsi_debug_cmnd_count = 0; @@ -157,11 +159,6 @@ static int sdebug_heads; /* heads per disk */ static int sdebug_cylinders_per; /* cylinders per surface */ static int sdebug_sectors_per; /* sectors per cylinder */ -/* default sector size is 512 bytes, 2**9 bytes */ -#define POW2_SECT_SIZE 9 -#define SECT_SIZE (1 << POW2_SECT_SIZE) -#define SECT_SIZE_PER(TGT) SECT_SIZE - #define SDEBUG_MAX_PARTS 4 #define SDEBUG_SENSE_LEN 32 @@ -878,8 +875,8 @@ static int resp_readcap(struct scsi_cmnd * scp, arr[2] = 0xff; arr[3] = 0xff; } - arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; - arr[7] = SECT_SIZE_PER(target) & 0xff; + arr[6] = (scsi_debug_sector_size >> 8) & 0xff; + arr[7] = scsi_debug_sector_size & 0xff; return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); } @@ -902,10 +899,10 @@ static int resp_readcap16(struct scsi_cmnd * scp, capac = sdebug_capacity - 1; for (k = 0; k < 8; ++k, capac >>= 8) arr[7 - k] = capac & 0xff; - arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff; - arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff; - arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff; - arr[11] = SECT_SIZE_PER(target) & 0xff; + arr[8] = (scsi_debug_sector_size >> 24) & 0xff; + arr[9] = (scsi_debug_sector_size >> 16) & 0xff; + arr[10] = (scsi_debug_sector_size >> 8) & 0xff; + arr[11] = scsi_debug_sector_size & 0xff; return fill_from_dev_buffer(scp, arr, min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); } @@ -1019,20 +1016,20 @@ static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target) static int resp_format_pg(unsigned char * p, int pcontrol, int target) { /* Format device page for mode_sense */ - unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0x40, 0, 0, 0}; - - memcpy(p, format_pg, sizeof(format_pg)); - p[10] = (sdebug_sectors_per >> 8) & 0xff; - p[11] = sdebug_sectors_per & 0xff; - p[12] = (SECT_SIZE >> 8) & 0xff; - p[13] = SECT_SIZE & 0xff; - if (DEV_REMOVEABLE(target)) - p[20] |= 0x20; /* should agree with INQUIRY */ - if (1 == pcontrol) - memset(p + 2, 0, sizeof(format_pg) - 2); - return sizeof(format_pg); + unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x40, 0, 0, 0}; + + memcpy(p, format_pg, sizeof(format_pg)); + p[10] = (sdebug_sectors_per >> 8) & 0xff; + p[11] = sdebug_sectors_per & 0xff; + p[12] = (scsi_debug_sector_size >> 8) & 0xff; + p[13] = scsi_debug_sector_size & 0xff; + if (DEV_REMOVEABLE(target)) + p[20] |= 0x20; /* should agree with INQUIRY */ + if (1 == pcontrol) + memset(p + 2, 0, sizeof(format_pg) - 2); + return sizeof(format_pg); } static int resp_caching_pg(unsigned char * p, int pcontrol, int target) @@ -1206,8 +1203,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, ap[2] = (sdebug_capacity >> 8) & 0xff; ap[3] = sdebug_capacity & 0xff; } - ap[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; - ap[7] = SECT_SIZE_PER(target) & 0xff; + ap[6] = (scsi_debug_sector_size >> 8) & 0xff; + ap[7] = scsi_debug_sector_size & 0xff; offset += bd_len; ap = arr + offset; } else if (16 == bd_len) { @@ -1215,10 +1212,10 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, for (k = 0; k < 8; ++k, capac >>= 8) ap[7 - k] = capac & 0xff; - ap[12] = (SECT_SIZE_PER(target) >> 24) & 0xff; - ap[13] = (SECT_SIZE_PER(target) >> 16) & 0xff; - ap[14] = (SECT_SIZE_PER(target) >> 8) & 0xff; - ap[15] = SECT_SIZE_PER(target) & 0xff; + ap[12] = (scsi_debug_sector_size >> 24) & 0xff; + ap[13] = (scsi_debug_sector_size >> 16) & 0xff; + ap[14] = (scsi_debug_sector_size >> 8) & 0xff; + ap[15] = scsi_debug_sector_size & 0xff; offset += bd_len; ap = arr + offset; } @@ -1519,10 +1516,10 @@ static int do_device_access(struct scsi_cmnd *scmd, if (block + num > sdebug_store_sectors) rest = block + num - sdebug_store_sectors; - ret = func(scmd, fake_storep + (block * SECT_SIZE), - (num - rest) * SECT_SIZE); + ret = func(scmd, fake_storep + (block * scsi_debug_sector_size), + (num - rest) * scsi_debug_sector_size); if (!ret && rest) - ret = func(scmd, fake_storep, rest * SECT_SIZE); + ret = func(scmd, fake_storep, rest * scsi_debug_sector_size); return ret; } @@ -1575,10 +1572,10 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, write_unlock_irqrestore(&atomic_rw, iflags); if (-1 == ret) return (DID_ERROR << 16); - else if ((ret < (num * SECT_SIZE)) && + else if ((ret < (num * scsi_debug_sector_size)) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " - " IO sent=%d bytes\n", num * SECT_SIZE, ret); + " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret); return 0; } @@ -2085,6 +2082,7 @@ module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO); module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR); module_param_named(vpd_use_hostno, scsi_debug_vpd_use_hostno, int, S_IRUGO | S_IWUSR); +module_param_named(sector_size, scsi_debug_sector_size, int, S_IRUGO); MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); MODULE_DESCRIPTION("SCSI debug adapter driver"); @@ -2106,6 +2104,7 @@ MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)"); +MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)"); static char sdebug_info[256]; @@ -2158,8 +2157,9 @@ static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **sta scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth, scsi_debug_cmnd_count, scsi_debug_delay, scsi_debug_max_luns, scsi_debug_scsi_level, - SECT_SIZE, sdebug_cylinders_per, sdebug_heads, sdebug_sectors_per, - num_aborts, num_dev_resets, num_bus_resets, num_host_resets); + scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads, + sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets, + num_host_resets); if (pos < offset) { len = 0; begin = pos; @@ -2434,6 +2434,12 @@ static ssize_t sdebug_vpd_use_hostno_store(struct device_driver * ddp, DRIVER_ATTR(vpd_use_hostno, S_IRUGO | S_IWUSR, sdebug_vpd_use_hostno_show, sdebug_vpd_use_hostno_store); +static ssize_t sdebug_sector_size_show(struct device_driver * ddp, char * buf) +{ + return scnprintf(buf, PAGE_SIZE, "%u\n", scsi_debug_sector_size); +} +DRIVER_ATTR(sector_size, S_IRUGO, sdebug_sector_size_show, NULL); + /* Note: The following function creates attribute files in the /sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these files (over those found in the /sys/module/scsi_debug/parameters @@ -2459,11 +2465,13 @@ static int do_create_driverfs_files(void) ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb); ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno); + ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_sector_size); return ret; } static void do_remove_driverfs_files(void) { + driver_remove_file(&sdebug_driverfs_driver, &driver_attr_sector_size); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); @@ -2499,10 +2507,22 @@ static int __init scsi_debug_init(void) int k; int ret; + switch (scsi_debug_sector_size) { + case 512: + case 1024: + case 2048: + case 4096: + break; + default: + printk(KERN_ERR "scsi_debug_init: invalid sector_size %u\n", + scsi_debug_sector_size); + return -EINVAL; + } + if (scsi_debug_dev_size_mb < 1) scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ sz = (unsigned long)scsi_debug_dev_size_mb * 1048576; - sdebug_store_sectors = sz / SECT_SIZE; + sdebug_store_sectors = sz / scsi_debug_sector_size; sdebug_capacity = get_sdebug_capacity(); /* play around with geometry, don't waste too much on track 0 */ -- cgit v0.10.2 From 090507157f3bc43dd925fda50f8aca7d03b616b6 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 28 May 2008 15:32:55 -0400 Subject: [SCSI] aacraid: prevent copy_from_user() BUG! Seen: kernel BUG at arch/i386/lib/usercopy.c:872 under a 2.6.18-8.el5 kernel. Traced it to a garbage-in/garbage-out ioctl condition in the aacraid driver. Adaptec's special ioctl scb passthrough needs to check the validity of the individual scatter gather count fields to the maximum the adapter supports. Doing so will have the side effect of preventing copy_from_user() from bugging out while populating the dma buffers. This is a hardening effort, issue was triggered by an errant version of the management tools and thus the BUG should not be seen in the field. [jejb: fixed up compile failure] Signed-off-by: Mark Salyzyn Signed-off-by: James Bottomley diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 5fd83de..a735526 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "aacraid.h" @@ -581,6 +582,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) for (i = 0; i < upsg->count; i++) { u64 addr; void* p; + if (upsg->sg[i].count > + (dev->adapter_info.options & + AAC_OPT_NEW_COMM) ? + (dev->scsi_host_ptr->max_sectors << 9) : + 65536) { + rcode = -EINVAL; + goto cleanup; + } /* Does this really need to be GFP_DMA? */ p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); if(!p) { @@ -625,6 +634,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) for (i = 0; i < usg->count; i++) { u64 addr; void* p; + if (usg->sg[i].count > + (dev->adapter_info.options & + AAC_OPT_NEW_COMM) ? + (dev->scsi_host_ptr->max_sectors << 9) : + 65536) { + rcode = -EINVAL; + goto cleanup; + } /* Does this really need to be GFP_DMA? */ p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); if(!p) { @@ -667,6 +684,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) for (i = 0; i < upsg->count; i++) { uintptr_t addr; void* p; + if (usg->sg[i].count > + (dev->adapter_info.options & + AAC_OPT_NEW_COMM) ? + (dev->scsi_host_ptr->max_sectors << 9) : + 65536) { + rcode = -EINVAL; + goto cleanup; + } /* Does this really need to be GFP_DMA? */ p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); if(!p) { @@ -698,6 +723,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) for (i = 0; i < upsg->count; i++) { dma_addr_t addr; void* p; + if (upsg->sg[i].count > + (dev->adapter_info.options & + AAC_OPT_NEW_COMM) ? + (dev->scsi_host_ptr->max_sectors << 9) : + 65536) { + rcode = -EINVAL; + goto cleanup; + } p = kmalloc(upsg->sg[i].count, GFP_KERNEL); if (!p) { dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", -- cgit v0.10.2 From 6362abd3e00d3161affad996fa53cc69a01fc6d1 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 5 Jun 2008 23:30:03 -0400 Subject: [SCSI] Rename scsi_bidi_sdb_cache The data integrity changes need to dynamically allocate scsi_data_buffers too. Rename scsi_bidi_sdb_cache for clarity. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 033c58a..aa8d5de 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -65,7 +65,7 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = { }; #undef SP -static struct kmem_cache *scsi_bidi_sdb_cache; +static struct kmem_cache *scsi_sdb_cache; static void scsi_run_queue(struct request_queue *q); @@ -775,7 +775,7 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special; scsi_free_sgtable(bidi_sdb); - kmem_cache_free(scsi_bidi_sdb_cache, bidi_sdb); + kmem_cache_free(scsi_sdb_cache, bidi_sdb); cmd->request->next_rq->special = NULL; } } @@ -1050,7 +1050,7 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) if (blk_bidi_rq(cmd->request)) { struct scsi_data_buffer *bidi_sdb = kmem_cache_zalloc( - scsi_bidi_sdb_cache, GFP_ATOMIC); + scsi_sdb_cache, GFP_ATOMIC); if (!bidi_sdb) { error = BLKPREP_DEFER; goto err_exit; @@ -1692,11 +1692,11 @@ int __init scsi_init_queue(void) return -ENOMEM; } - scsi_bidi_sdb_cache = kmem_cache_create("scsi_bidi_sdb", - sizeof(struct scsi_data_buffer), - 0, 0, NULL); - if (!scsi_bidi_sdb_cache) { - printk(KERN_ERR "SCSI: can't init scsi bidi sdb cache\n"); + scsi_sdb_cache = kmem_cache_create("scsi_data_buffer", + sizeof(struct scsi_data_buffer), + 0, 0, NULL); + if (!scsi_sdb_cache) { + printk(KERN_ERR "SCSI: can't init scsi sdb cache\n"); goto cleanup_io_context; } @@ -1709,7 +1709,7 @@ int __init scsi_init_queue(void) if (!sgp->slab) { printk(KERN_ERR "SCSI: can't init sg slab %s\n", sgp->name); - goto cleanup_bidi_sdb; + goto cleanup_sdb; } sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE, @@ -1717,13 +1717,13 @@ int __init scsi_init_queue(void) if (!sgp->pool) { printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name); - goto cleanup_bidi_sdb; + goto cleanup_sdb; } } return 0; -cleanup_bidi_sdb: +cleanup_sdb: for (i = 0; i < SG_MEMPOOL_NR; i++) { struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; if (sgp->pool) @@ -1731,7 +1731,7 @@ cleanup_bidi_sdb: if (sgp->slab) kmem_cache_destroy(sgp->slab); } - kmem_cache_destroy(scsi_bidi_sdb_cache); + kmem_cache_destroy(scsi_sdb_cache); cleanup_io_context: kmem_cache_destroy(scsi_io_context_cache); @@ -1743,7 +1743,7 @@ void scsi_exit_queue(void) int i; kmem_cache_destroy(scsi_io_context_cache); - kmem_cache_destroy(scsi_bidi_sdb_cache); + kmem_cache_destroy(scsi_sdb_cache); for (i = 0; i < SG_MEMPOOL_NR; i++) { struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; -- cgit v0.10.2 From 24073b475d6d2bad8880434a16343ee1da816ea5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:54 +0200 Subject: [SCSI] zfcp: Move FC code to new file Move all Fibre Channel related code to new file and cleanup the code while doing so. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index d6a78f1..f775f9e 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -4,6 +4,6 @@ zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \ - zfcp_sysfs_unit.o zfcp_sysfs_driver.o + zfcp_sysfs_unit.o zfcp_sysfs_driver.o zfcp_fc.o obj-$(CONFIG_ZFCP) += zfcp.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 9a3c138..9eb8827 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -43,9 +43,6 @@ static char *device; /* written against the module interface */ static int __init zfcp_module_init(void); -/* FCP related */ -static void zfcp_ns_gid_pn_handler(unsigned long); - /* miscellaneous */ static int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t); static void zfcp_sg_list_free(struct zfcp_sg_list *); @@ -1349,518 +1346,3 @@ zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) } #undef ZFCP_LOG_AREA - -/****************************************************************/ -/******* Fibre Channel Standard related Functions **************/ -/****************************************************************/ - -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FC - -static void zfcp_fsf_incoming_els_rscn(struct zfcp_fsf_req *fsf_req) -{ - struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fcp_rscn_head *fcp_rscn_head; - struct fcp_rscn_element *fcp_rscn_element; - struct zfcp_port *port; - u16 i; - u16 no_entries; - u32 range_mask; - unsigned long flags; - - fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload; - fcp_rscn_element = (struct fcp_rscn_element *) status_buffer->payload; - - /* see FC-FS */ - no_entries = (fcp_rscn_head->payload_len / 4); - - for (i = 1; i < no_entries; i++) { - /* skip head and start with 1st element */ - fcp_rscn_element++; - switch (fcp_rscn_element->addr_format) { - case ZFCP_PORT_ADDRESS: - range_mask = ZFCP_PORTS_RANGE_PORT; - break; - case ZFCP_AREA_ADDRESS: - range_mask = ZFCP_PORTS_RANGE_AREA; - break; - case ZFCP_DOMAIN_ADDRESS: - range_mask = ZFCP_PORTS_RANGE_DOMAIN; - break; - case ZFCP_FABRIC_ADDRESS: - range_mask = ZFCP_PORTS_RANGE_FABRIC; - break; - default: - ZFCP_LOG_INFO("incoming RSCN with unknown " - "address format\n"); - continue; - } - read_lock_irqsave(&zfcp_data.config_lock, flags); - list_for_each_entry(port, &adapter->port_list_head, list) { - if (atomic_test_mask - (ZFCP_STATUS_PORT_WKA, &port->status)) - continue; - /* Do we know this port? If not skip it. */ - if (!atomic_test_mask - (ZFCP_STATUS_PORT_DID_DID, &port->status)) { - ZFCP_LOG_INFO("incoming RSCN, trying to open " - "port 0x%016Lx\n", port->wwpn); - zfcp_erp_port_reopen(port, - ZFCP_STATUS_COMMON_ERP_FAILED, - 82, fsf_req); - continue; - } - - /* - * FIXME: race: d_id might being invalidated - * (...DID_DID reset) - */ - if ((port->d_id & range_mask) - == (fcp_rscn_element->nport_did & range_mask)) { - ZFCP_LOG_TRACE("reopen did 0x%08x\n", - fcp_rscn_element->nport_did); - /* - * Unfortunately, an RSCN does not specify the - * type of change a target underwent. We assume - * that it makes sense to reopen the link. - * FIXME: Shall we try to find out more about - * the target and link state before closing it? - * How to accomplish this? (nameserver?) - * Where would such code be put in? - * (inside or outside erp) - */ - ZFCP_LOG_INFO("incoming RSCN, trying to open " - "port 0x%016Lx\n", port->wwpn); - zfcp_test_link(port); - } - } - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - } -} - -static void zfcp_fsf_incoming_els_plogi(struct zfcp_fsf_req *fsf_req) -{ - struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fsf_plogi *els_plogi; - struct zfcp_port *port; - unsigned long flags; - - els_plogi = (struct fsf_plogi *) status_buffer->payload; - read_lock_irqsave(&zfcp_data.config_lock, flags); - list_for_each_entry(port, &adapter->port_list_head, list) { - if (port->wwpn == (*(wwn_t *) &els_plogi->serv_param.wwpn)) - break; - } - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - - if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) { - ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port " - "with d_id 0x%06x on adapter %s\n", - status_buffer->d_id, - zfcp_get_busid_by_adapter(adapter)); - } else { - zfcp_erp_port_forced_reopen(port, 0, 83, fsf_req); - } -} - -static void zfcp_fsf_incoming_els_logo(struct zfcp_fsf_req *fsf_req) -{ - struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload; - struct zfcp_port *port; - unsigned long flags; - - read_lock_irqsave(&zfcp_data.config_lock, flags); - list_for_each_entry(port, &adapter->port_list_head, list) { - if (port->wwpn == els_logo->nport_wwpn) - break; - } - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - - if (!port || (port->wwpn != els_logo->nport_wwpn)) { - ZFCP_LOG_DEBUG("ignored incoming LOGO for nonexisting port " - "with d_id 0x%06x on adapter %s\n", - status_buffer->d_id, - zfcp_get_busid_by_adapter(adapter)); - } else { - zfcp_erp_port_forced_reopen(port, 0, 84, fsf_req); - } -} - -static void -zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter, - struct fsf_status_read_buffer *status_buffer) -{ - ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x " - "for adapter %s\n", *(u32 *) (status_buffer->payload), - zfcp_get_busid_by_adapter(adapter)); - -} - -void -zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req) -{ - struct fsf_status_read_buffer *status_buffer; - u32 els_type; - struct zfcp_adapter *adapter; - - status_buffer = (struct fsf_status_read_buffer *) fsf_req->data; - els_type = *(u32 *) (status_buffer->payload); - adapter = fsf_req->adapter; - - zfcp_san_dbf_event_incoming_els(fsf_req); - if (els_type == LS_PLOGI) - zfcp_fsf_incoming_els_plogi(fsf_req); - else if (els_type == LS_LOGO) - zfcp_fsf_incoming_els_logo(fsf_req); - else if ((els_type & 0xffff0000) == LS_RSCN) - /* we are only concerned with the command, not the length */ - zfcp_fsf_incoming_els_rscn(fsf_req); - else - zfcp_fsf_incoming_els_unknown(adapter, status_buffer); -} - - -/** - * zfcp_gid_pn_buffers_alloc - allocate buffers for GID_PN nameserver request - * @gid_pn: pointer to return pointer to struct zfcp_gid_pn_data - * @pool: pointer to mempool_t if non-null memory pool is used for allocation - */ -static int -zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool) -{ - struct zfcp_gid_pn_data *data; - - if (pool) - data = mempool_alloc(pool, GFP_ATOMIC); - else - data = kmem_cache_alloc(zfcp_data.gid_pn_cache, GFP_ATOMIC); - - if (NULL == data) - return -ENOMEM; - - memset(data, 0, sizeof(*data)); - data->ct.pool = pool; - sg_init_table(&data->req , 1); - sg_init_table(&data->resp , 1); - data->ct.req = &data->req; - data->ct.resp = &data->resp; - data->ct.req_count = data->ct.resp_count = 1; - zfcp_address_to_sg(&data->ct_iu_req, &data->req, sizeof(struct ct_iu_gid_pn_req)); - zfcp_address_to_sg(&data->ct_iu_resp, &data->resp, sizeof(struct ct_iu_gid_pn_resp)); - - *gid_pn = data; - return 0; -} - -/** - * zfcp_gid_pn_buffers_free - free buffers for GID_PN nameserver request - * @gid_pn: pointer to struct zfcp_gid_pn_data which has to be freed - */ -static void zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn) -{ - if (gid_pn->ct.pool) - mempool_free(gid_pn, gid_pn->ct.pool); - else - kmem_cache_free(zfcp_data.gid_pn_cache, gid_pn); -} - -/** - * zfcp_ns_gid_pn_request - initiate GID_PN nameserver request - * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed - */ -int -zfcp_ns_gid_pn_request(struct zfcp_erp_action *erp_action) -{ - int ret; - struct ct_iu_gid_pn_req *ct_iu_req; - struct zfcp_gid_pn_data *gid_pn; - struct zfcp_adapter *adapter = erp_action->adapter; - - ret = zfcp_gid_pn_buffers_alloc(&gid_pn, adapter->pool.data_gid_pn); - if (ret < 0) { - ZFCP_LOG_INFO("error: buffer allocation for gid_pn nameserver " - "request failed for adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - goto out; - } - - /* setup nameserver request */ - ct_iu_req = zfcp_sg_to_address(gid_pn->ct.req); - ct_iu_req->header.revision = ZFCP_CT_REVISION; - ct_iu_req->header.gs_type = ZFCP_CT_DIRECTORY_SERVICE; - ct_iu_req->header.gs_subtype = ZFCP_CT_NAME_SERVER; - ct_iu_req->header.options = ZFCP_CT_SYNCHRONOUS; - ct_iu_req->header.cmd_rsp_code = ZFCP_CT_GID_PN; - ct_iu_req->header.max_res_size = ZFCP_CT_MAX_SIZE; - ct_iu_req->wwpn = erp_action->port->wwpn; - - /* setup parameters for send generic command */ - gid_pn->ct.port = adapter->nameserver_port; - gid_pn->ct.handler = zfcp_ns_gid_pn_handler; - gid_pn->ct.handler_data = (unsigned long) gid_pn; - gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; - gid_pn->port = erp_action->port; - - ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, - erp_action); - if (ret) { - ZFCP_LOG_INFO("error: initiation of gid_pn nameserver request " - "failed for adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - - zfcp_gid_pn_buffers_free(gid_pn); - } - - out: - return ret; -} - -/** - * zfcp_ns_gid_pn_handler - handler for GID_PN nameserver request - * @data: unsigned long, contains pointer to struct zfcp_gid_pn_data - */ -static void zfcp_ns_gid_pn_handler(unsigned long data) -{ - struct zfcp_port *port; - struct zfcp_send_ct *ct; - struct ct_iu_gid_pn_req *ct_iu_req; - struct ct_iu_gid_pn_resp *ct_iu_resp; - struct zfcp_gid_pn_data *gid_pn; - - - gid_pn = (struct zfcp_gid_pn_data *) data; - port = gid_pn->port; - ct = &gid_pn->ct; - ct_iu_req = zfcp_sg_to_address(ct->req); - ct_iu_resp = zfcp_sg_to_address(ct->resp); - - if (ct->status != 0) - goto failed; - - if (zfcp_check_ct_response(&ct_iu_resp->header)) { - /* FIXME: do we need some specific erp entry points */ - atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); - goto failed; - } - /* paranoia */ - if (ct_iu_req->wwpn != port->wwpn) { - ZFCP_LOG_NORMAL("bug: wwpn 0x%016Lx returned by nameserver " - "lookup does not match expected wwpn 0x%016Lx " - "for adapter %s\n", ct_iu_req->wwpn, port->wwpn, - zfcp_get_busid_by_port(port)); - goto mismatch; - } - - /* looks like a valid d_id */ - port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; - atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); - ZFCP_LOG_DEBUG("adapter %s: wwpn=0x%016Lx ---> d_id=0x%06x\n", - zfcp_get_busid_by_port(port), port->wwpn, port->d_id); - goto out; - - mismatch: - ZFCP_LOG_DEBUG("CT IUs do not match:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, (char *) ct_iu_req, - sizeof(struct ct_iu_gid_pn_req)); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, (char *) ct_iu_resp, - sizeof(struct ct_iu_gid_pn_resp)); - - failed: - ZFCP_LOG_NORMAL("warning: failed gid_pn nameserver request for wwpn " - "0x%016Lx for adapter %s\n", - port->wwpn, zfcp_get_busid_by_port(port)); - out: - zfcp_gid_pn_buffers_free(gid_pn); - return; -} - -/* reject CT_IU reason codes acc. to FC-GS-4 */ -static const struct zfcp_rc_entry zfcp_ct_rc[] = { - {0x01, "invalid command code"}, - {0x02, "invalid version level"}, - {0x03, "logical error"}, - {0x04, "invalid CT_IU size"}, - {0x05, "logical busy"}, - {0x07, "protocol error"}, - {0x09, "unable to perform command request"}, - {0x0b, "command not supported"}, - {0x0d, "server not available"}, - {0x0e, "session could not be established"}, - {0xff, "vendor specific error"}, - {0, NULL}, -}; - -/* LS_RJT reason codes acc. to FC-FS */ -static const struct zfcp_rc_entry zfcp_ls_rjt_rc[] = { - {0x01, "invalid LS_Command code"}, - {0x03, "logical error"}, - {0x05, "logical busy"}, - {0x07, "protocol error"}, - {0x09, "unable to perform command request"}, - {0x0b, "command not supported"}, - {0x0e, "command already in progress"}, - {0xff, "vendor specific error"}, - {0, NULL}, -}; - -/* reject reason codes according to FC-PH/FC-FS */ -static const struct zfcp_rc_entry zfcp_p_rjt_rc[] = { - {0x01, "invalid D_ID"}, - {0x02, "invalid S_ID"}, - {0x03, "Nx_Port not available, temporary"}, - {0x04, "Nx_Port not available, permament"}, - {0x05, "class not supported"}, - {0x06, "delimiter usage error"}, - {0x07, "TYPE not supported"}, - {0x08, "invalid Link_Control"}, - {0x09, "invalid R_CTL field"}, - {0x0a, "invalid F_CTL field"}, - {0x0b, "invalid OX_ID"}, - {0x0c, "invalid RX_ID"}, - {0x0d, "invalid SEQ_ID"}, - {0x0e, "invalid DF_CTL"}, - {0x0f, "invalid SEQ_CNT"}, - {0x10, "invalid parameter field"}, - {0x11, "exchange error"}, - {0x12, "protocol error"}, - {0x13, "incorrect length"}, - {0x14, "unsupported ACK"}, - {0x15, "class of service not supported by entity at FFFFFE"}, - {0x16, "login required"}, - {0x17, "excessive sequences attempted"}, - {0x18, "unable to establish exchange"}, - {0x1a, "fabric path not available"}, - {0x1b, "invalid VC_ID (class 4)"}, - {0x1c, "invalid CS_CTL field"}, - {0x1d, "insufficient resources for VC (class 4)"}, - {0x1f, "invalid class of service"}, - {0x20, "preemption request rejected"}, - {0x21, "preemption not enabled"}, - {0x22, "multicast error"}, - {0x23, "multicast error terminate"}, - {0x24, "process login required"}, - {0xff, "vendor specific reject"}, - {0, NULL}, -}; - -/** - * zfcp_rc_description - return description for given reaon code - * @code: reason code - * @rc_table: table of reason codes and descriptions - */ -static const char * -zfcp_rc_description(u8 code, const struct zfcp_rc_entry *rc_table) -{ - const char *descr = "unknown reason code"; - - do { - if (code == rc_table->code) { - descr = rc_table->description; - break; - } - rc_table++; - } while (rc_table->code && rc_table->description); - - return descr; -} - -/** - * zfcp_check_ct_response - evaluate reason code for CT_IU - * @rjt: response payload to an CT_IU request - * Return: 0 for accept CT_IU, 1 for reject CT_IU or invlid response code - */ -int -zfcp_check_ct_response(struct ct_hdr *rjt) -{ - if (rjt->cmd_rsp_code == ZFCP_CT_ACCEPT) - return 0; - - if (rjt->cmd_rsp_code != ZFCP_CT_REJECT) { - ZFCP_LOG_NORMAL("error: invalid Generic Service command/" - "response code (0x%04hx)\n", - rjt->cmd_rsp_code); - return 1; - } - - ZFCP_LOG_INFO("Generic Service command rejected\n"); - ZFCP_LOG_INFO("%s (0x%02x, 0x%02x, 0x%02x)\n", - zfcp_rc_description(rjt->reason_code, zfcp_ct_rc), - (u32) rjt->reason_code, (u32) rjt->reason_code_expl, - (u32) rjt->vendor_unique); - - return 1; -} - -/** - * zfcp_print_els_rjt - print reject parameter and description for ELS reject - * @rjt_par: reject parameter acc. to FC-PH/FC-FS - * @rc_table: table of reason codes and descriptions - */ -static void -zfcp_print_els_rjt(struct zfcp_ls_rjt_par *rjt_par, - const struct zfcp_rc_entry *rc_table) -{ - ZFCP_LOG_INFO("%s (%02x %02x %02x %02x)\n", - zfcp_rc_description(rjt_par->reason_code, rc_table), - (u32) rjt_par->action, (u32) rjt_par->reason_code, - (u32) rjt_par->reason_expl, (u32) rjt_par->vendor_unique); -} - -/** - * zfcp_fsf_handle_els_rjt - evaluate status qualifier/reason code on ELS reject - * @sq: status qualifier word - * @rjt_par: reject parameter as described in FC-PH and FC-FS - * Return: -EROMTEIO for LS_RJT, -EREMCHG for invalid D_ID, -EIO else - */ -int -zfcp_handle_els_rjt(u32 sq, struct zfcp_ls_rjt_par *rjt_par) -{ - int ret = -EIO; - - if (sq == FSF_IOSTAT_NPORT_RJT) { - ZFCP_LOG_INFO("ELS rejected (P_RJT)\n"); - zfcp_print_els_rjt(rjt_par, zfcp_p_rjt_rc); - /* invalid d_id */ - if (rjt_par->reason_code == 0x01) - ret = -EREMCHG; - } else if (sq == FSF_IOSTAT_FABRIC_RJT) { - ZFCP_LOG_INFO("ELS rejected (F_RJT)\n"); - zfcp_print_els_rjt(rjt_par, zfcp_p_rjt_rc); - /* invalid d_id */ - if (rjt_par->reason_code == 0x01) - ret = -EREMCHG; - } else if (sq == FSF_IOSTAT_LS_RJT) { - ZFCP_LOG_INFO("ELS rejected (LS_RJT)\n"); - zfcp_print_els_rjt(rjt_par, zfcp_ls_rjt_rc); - ret = -EREMOTEIO; - } else - ZFCP_LOG_INFO("unexpected SQ: 0x%02x\n", sq); - - return ret; -} - -/** - * zfcp_plogi_evaluate - evaluate PLOGI playload and copy important fields - * into zfcp_port structure - * @port: zfcp_port structure - * @plogi: plogi payload - */ -void -zfcp_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi) -{ - port->maxframe_size = plogi->serv_param.common_serv_param[7] | - ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8); - if (plogi->serv_param.class1_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS1; - if (plogi->serv_param.class2_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS2; - if (plogi->serv_param.class3_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS3; - if (plogi->serv_param.class4_serv_param[0] & 0x80) - port->supported_classes |= FC_COS_CLASS4; -} - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 558dae9..01e817a 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -546,8 +546,8 @@ static const char *zfcp_rec_dbf_ids[] = { [80] = "exclusive read-only unit access unsupported", [81] = "shared read-write unit access unsupported", [82] = "incoming rscn", - [83] = "incoming plogi", - [84] = "incoming logo", + [83] = "incoming wwpn", + [84] = "", [85] = "online", [86] = "offline", [87] = "ccw device gone", diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index fc61a8e..d23c3b9 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -223,9 +223,9 @@ struct fcp_rsp_iu { #define RSP_CODE_TASKMAN_FAILED 5 /* see fc-fs */ -#define LS_RSCN 0x61040000 -#define LS_LOGO 0x05000000 -#define LS_PLOGI 0x03000000 +#define LS_RSCN 0x61 +#define LS_LOGO 0x05 +#define LS_PLOGI 0x03 struct fcp_rscn_head { u8 command; @@ -622,7 +622,6 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long); * @resp_count: number of elements in response scatter-gather list * @handler: handler function (called for response to the request) * @handler_data: data passed to handler function - * @pool: pointer to memory pool for ct request structure * @timeout: FSF timeout for this request * @completion: completion for synchronization purposes * @status: used to pass error status to calling function @@ -635,7 +634,6 @@ struct zfcp_send_ct { unsigned int resp_count; zfcp_send_ct_handler_t handler; unsigned long handler_data; - mempool_t *pool; int timeout; struct completion *completion; int status; diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d05b370..ee19be1 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -23,9 +23,6 @@ #include "zfcp_ext.h" -static int zfcp_erp_adisc(struct zfcp_port *); -static void zfcp_erp_adisc_handler(unsigned long); - static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int, u8, void *); static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int, u8, @@ -292,189 +289,6 @@ int zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask, u8 id, return retval; } - -/** - * zfcp_erp_adisc - send ADISC ELS command - * @port: port structure - */ -static int -zfcp_erp_adisc(struct zfcp_port *port) -{ - struct zfcp_adapter *adapter = port->adapter; - struct zfcp_send_els *send_els; - struct zfcp_ls_adisc *adisc; - void *address = NULL; - int retval = 0; - - send_els = kzalloc(sizeof(struct zfcp_send_els), GFP_ATOMIC); - if (send_els == NULL) - goto nomem; - - send_els->req = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC); - if (send_els->req == NULL) - goto nomem; - sg_init_table(send_els->req, 1); - - send_els->resp = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC); - if (send_els->resp == NULL) - goto nomem; - sg_init_table(send_els->resp, 1); - - address = (void *) get_zeroed_page(GFP_ATOMIC); - if (address == NULL) - goto nomem; - - zfcp_address_to_sg(address, send_els->req, sizeof(struct zfcp_ls_adisc)); - address += PAGE_SIZE >> 1; - zfcp_address_to_sg(address, send_els->resp, sizeof(struct zfcp_ls_adisc_acc)); - send_els->req_count = send_els->resp_count = 1; - - send_els->adapter = adapter; - send_els->port = port; - send_els->d_id = port->d_id; - send_els->handler = zfcp_erp_adisc_handler; - send_els->handler_data = (unsigned long) send_els; - - adisc = zfcp_sg_to_address(send_els->req); - send_els->ls_code = adisc->code = ZFCP_LS_ADISC; - - /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports - without FC-AL-2 capability, so we don't set it */ - adisc->wwpn = fc_host_port_name(adapter->scsi_host); - adisc->wwnn = fc_host_node_name(adapter->scsi_host); - adisc->nport_id = fc_host_port_id(adapter->scsi_host); - ZFCP_LOG_INFO("ADISC request from s_id 0x%06x to d_id 0x%06x " - "(wwpn=0x%016Lx, wwnn=0x%016Lx, " - "hard_nport_id=0x%06x, nport_id=0x%06x)\n", - adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn, - (wwn_t) adisc->wwnn, adisc->hard_nport_id, - adisc->nport_id); - - retval = zfcp_fsf_send_els(send_els); - if (retval != 0) { - ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port " - "0x%06x on adapter %s\n", send_els->d_id, - zfcp_get_busid_by_adapter(adapter)); - goto freemem; - } - - goto out; - - nomem: - retval = -ENOMEM; - freemem: - if (address != NULL) - __free_pages(sg_page(send_els->req), 0); - if (send_els != NULL) { - kfree(send_els->req); - kfree(send_els->resp); - kfree(send_els); - } - out: - return retval; -} - - -/** - * zfcp_erp_adisc_handler - handler for ADISC ELS command - * @data: pointer to struct zfcp_send_els - * - * If ADISC failed (LS_RJT or timed out) forced reopen of the port is triggered. - */ -static void -zfcp_erp_adisc_handler(unsigned long data) -{ - struct zfcp_send_els *send_els; - struct zfcp_port *port; - struct zfcp_adapter *adapter; - u32 d_id; - struct zfcp_ls_adisc_acc *adisc; - - send_els = (struct zfcp_send_els *) data; - adapter = send_els->adapter; - port = send_els->port; - d_id = send_els->d_id; - - /* request rejected or timed out */ - if (send_els->status != 0) { - ZFCP_LOG_NORMAL("ELS request rejected/timed out, " - "force physical port reopen " - "(adapter %s, port d_id=0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); - if (zfcp_erp_port_forced_reopen(port, 0, 63, NULL)) - ZFCP_LOG_NORMAL("failed reopen of port " - "(adapter %s, wwpn=0x%016Lx)\n", - zfcp_get_busid_by_port(port), - port->wwpn); - goto out; - } - - adisc = zfcp_sg_to_address(send_els->resp); - - ZFCP_LOG_INFO("ADISC response from d_id 0x%06x to s_id " - "0x%06x (wwpn=0x%016Lx, wwnn=0x%016Lx, " - "hard_nport_id=0x%06x, nport_id=0x%06x)\n", - d_id, fc_host_port_id(adapter->scsi_host), - (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn, - adisc->hard_nport_id, adisc->nport_id); - - /* set wwnn for port */ - if (port->wwnn == 0) - port->wwnn = adisc->wwnn; - - if (port->wwpn != adisc->wwpn) { - ZFCP_LOG_NORMAL("d_id assignment changed, reopening " - "port (adapter %s, wwpn=0x%016Lx, " - "adisc_resp_wwpn=0x%016Lx)\n", - zfcp_get_busid_by_port(port), - port->wwpn, (wwn_t) adisc->wwpn); - if (zfcp_erp_port_reopen(port, 0, 64, NULL)) - ZFCP_LOG_NORMAL("failed reopen of port " - "(adapter %s, wwpn=0x%016Lx)\n", - zfcp_get_busid_by_port(port), - port->wwpn); - } - - out: - zfcp_port_put(port); - __free_pages(sg_page(send_els->req), 0); - kfree(send_els->req); - kfree(send_els->resp); - kfree(send_els); -} - - -/** - * zfcp_test_link - lightweight link test procedure - * @port: port to be tested - * - * Test status of a link to a remote port using the ELS command ADISC. - */ -int -zfcp_test_link(struct zfcp_port *port) -{ - int retval; - - zfcp_port_get(port); - retval = zfcp_erp_adisc(port); - if (retval != 0 && retval != -EBUSY) { - zfcp_port_put(port); - ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx " - "on adapter %s\n ", port->wwpn, - zfcp_get_busid_by_port(port)); - retval = zfcp_erp_port_forced_reopen(port, 0, 65, NULL); - if (retval != 0) { - ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx " - "on adapter %s failed\n", port->wwpn, - zfcp_get_busid_by_port(port)); - retval = -EPERM; - } - } - - return retval; -} - - /* * function: * @@ -2564,7 +2378,7 @@ zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action) { int retval; - retval = zfcp_ns_gid_pn_request(erp_action); + retval = zfcp_fc_ns_gid_pn_request(erp_action); if (retval == -ENOMEM) { retval = ZFCP_ERP_NOMEM; goto out; diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index e47ab8d..91d5884 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -103,7 +103,6 @@ extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *, struct zfcp_unit *, struct scsi_cmnd *, int, int); extern int zfcp_fsf_req_complete(struct zfcp_fsf_req *); -extern void zfcp_fsf_incoming_els(struct zfcp_fsf_req *); extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_command_task_management( struct zfcp_adapter *, struct zfcp_unit *, u8, int); @@ -111,11 +110,12 @@ extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command( unsigned long, struct zfcp_adapter *, struct zfcp_unit *, int); /******************************* FC/FCP **************************************/ +extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); +extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *); +extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); +extern void zfcp_test_link(struct zfcp_port *); + extern int zfcp_nameserver_enqueue(struct zfcp_adapter *); -extern int zfcp_ns_gid_pn_request(struct zfcp_erp_action *); -extern int zfcp_check_ct_response(struct ct_hdr *); -extern int zfcp_handle_els_rjt(u32, struct zfcp_ls_rjt_par *); -extern void zfcp_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); /******************************* SCSI ****************************************/ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); @@ -158,8 +158,6 @@ extern int zfcp_erp_thread_kill(struct zfcp_adapter *); extern int zfcp_erp_wait(struct zfcp_adapter *); extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long); -extern int zfcp_test_link(struct zfcp_port *); - extern void zfcp_erp_port_boxed(struct zfcp_port *, u8 id, void *ref); extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8 id, void *ref); extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8 id, void *ref); diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c new file mode 100644 index 0000000..bb07c3b --- /dev/null +++ b/drivers/s390/scsi/zfcp_fc.c @@ -0,0 +1,305 @@ +/* + * zfcp device driver + * + * Fibre Channel related functions for the zfcp device driver. + * + * Copyright IBM Corporation 2008 + */ + +#include "zfcp_ext.h" + +static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, + struct fcp_rscn_element *elem) +{ + unsigned long flags; + struct zfcp_port *port; + + read_lock_irqsave(&zfcp_data.config_lock, flags); + list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { + if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) + continue; + /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ + if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) + /* Try to connect to unused ports anyway. */ + zfcp_erp_port_reopen(port, + ZFCP_STATUS_COMMON_ERP_FAILED, + 82, fsf_req); + else if ((port->d_id & range) == (elem->nport_did & range)) + /* Check connection status for connected ports */ + zfcp_test_link(port); + } + read_unlock_irqrestore(&zfcp_data.config_lock, flags); +} + +static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) +{ + struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data; + struct fcp_rscn_head *fcp_rscn_head; + struct fcp_rscn_element *fcp_rscn_element; + u16 i; + u16 no_entries; + u32 range_mask; + + fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload; + fcp_rscn_element = (struct fcp_rscn_element *) status_buffer->payload; + + /* see FC-FS */ + no_entries = fcp_rscn_head->payload_len / + sizeof(struct fcp_rscn_element); + + for (i = 1; i < no_entries; i++) { + /* skip head and start with 1st element */ + fcp_rscn_element++; + switch (fcp_rscn_element->addr_format) { + case ZFCP_PORT_ADDRESS: + range_mask = ZFCP_PORTS_RANGE_PORT; + break; + case ZFCP_AREA_ADDRESS: + range_mask = ZFCP_PORTS_RANGE_AREA; + break; + case ZFCP_DOMAIN_ADDRESS: + range_mask = ZFCP_PORTS_RANGE_DOMAIN; + break; + case ZFCP_FABRIC_ADDRESS: + range_mask = ZFCP_PORTS_RANGE_FABRIC; + break; + default: + continue; + } + _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element); + } +} + +static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn) +{ + struct zfcp_adapter *adapter = req->adapter; + struct zfcp_port *port; + unsigned long flags; + + read_lock_irqsave(&zfcp_data.config_lock, flags); + list_for_each_entry(port, &adapter->port_list_head, list) + if (port->wwpn == wwpn) + break; + read_unlock_irqrestore(&zfcp_data.config_lock, flags); + + if (port && (port->wwpn == wwpn)) + zfcp_erp_port_forced_reopen(port, 0, 83, req); +} + +static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) +{ + struct fsf_status_read_buffer *status_buffer = + (struct fsf_status_read_buffer *)req->data; + struct fsf_plogi *els_plogi = + (struct fsf_plogi *) status_buffer->payload; + + zfcp_fc_incoming_wwpn(req, els_plogi->serv_param.wwpn); +} + +static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req) +{ + struct fsf_status_read_buffer *status_buffer = + (struct fsf_status_read_buffer *)req->data; + struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload; + + zfcp_fc_incoming_wwpn(req, els_logo->nport_wwpn); +} + +/** + * zfcp_fc_incoming_els - handle incoming ELS + * @fsf_req - request which contains incoming ELS + */ +void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) +{ + struct fsf_status_read_buffer *status_buffer = + (struct fsf_status_read_buffer *) fsf_req->data; + unsigned int els_type = status_buffer->payload[0]; + + zfcp_san_dbf_event_incoming_els(fsf_req); + if (els_type == LS_PLOGI) + zfcp_fc_incoming_plogi(fsf_req); + else if (els_type == LS_LOGO) + zfcp_fc_incoming_logo(fsf_req); + else if (els_type == LS_RSCN) + zfcp_fc_incoming_rscn(fsf_req); +} + +static void zfcp_ns_gid_pn_handler(unsigned long data) +{ + struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; + struct zfcp_send_ct *ct = &gid_pn->ct; + struct ct_iu_gid_pn_req *ct_iu_req = sg_virt(ct->req); + struct ct_iu_gid_pn_resp *ct_iu_resp = sg_virt(ct->resp); + struct zfcp_port *port = gid_pn->port; + + if (ct->status) + goto out; + if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { + atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); + goto out; + } + /* paranoia */ + if (ct_iu_req->wwpn != port->wwpn) + goto out; + /* looks like a valid d_id */ + port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; + atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); +out: + mempool_free(gid_pn, port->adapter->pool.data_gid_pn); +} + +/** + * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request + * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed + * return: -ENOMEM on error, 0 otherwise + */ +int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) +{ + int ret; + struct zfcp_gid_pn_data *gid_pn; + struct zfcp_adapter *adapter = erp_action->adapter; + + gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); + if (!gid_pn) + return -ENOMEM; + + memset(gid_pn, 0, sizeof(*gid_pn)); + + /* setup parameters for send generic command */ + gid_pn->port = erp_action->port; + gid_pn->ct.port = adapter->nameserver_port; + gid_pn->ct.handler = zfcp_ns_gid_pn_handler; + gid_pn->ct.handler_data = (unsigned long) gid_pn; + gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; + gid_pn->ct.req = &gid_pn->req; + gid_pn->ct.resp = &gid_pn->resp; + gid_pn->ct.req_count = 1; + gid_pn->ct.resp_count = 1; + sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req, + sizeof(struct ct_iu_gid_pn_req)); + sg_init_one(&gid_pn->resp, &gid_pn->ct_iu_resp, + sizeof(struct ct_iu_gid_pn_resp)); + + /* setup nameserver request */ + gid_pn->ct_iu_req.header.revision = ZFCP_CT_REVISION; + gid_pn->ct_iu_req.header.gs_type = ZFCP_CT_DIRECTORY_SERVICE; + gid_pn->ct_iu_req.header.gs_subtype = ZFCP_CT_NAME_SERVER; + gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; + gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; + gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; + gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; + + ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, + erp_action); + if (ret) + mempool_free(gid_pn, adapter->pool.data_gid_pn); + return ret; +} + +/** + * zfcp_fc_plogi_evaluate - evaluate PLOGI playload + * @port: zfcp_port structure + * @plogi: plogi payload + * + * Evaluate PLOGI playload and copy important fields into zfcp_port structure + */ +void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi) +{ + port->maxframe_size = plogi->serv_param.common_serv_param[7] | + ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8); + if (plogi->serv_param.class1_serv_param[0] & 0x80) + port->supported_classes |= FC_COS_CLASS1; + if (plogi->serv_param.class2_serv_param[0] & 0x80) + port->supported_classes |= FC_COS_CLASS2; + if (plogi->serv_param.class3_serv_param[0] & 0x80) + port->supported_classes |= FC_COS_CLASS3; + if (plogi->serv_param.class4_serv_param[0] & 0x80) + port->supported_classes |= FC_COS_CLASS4; +} + +struct zfcp_els_adisc { + struct zfcp_send_els els; + struct scatterlist req; + struct scatterlist resp; + struct zfcp_ls_adisc ls_adisc; + struct zfcp_ls_adisc_acc ls_adisc_acc; +}; + +static void zfcp_fc_adisc_handler(unsigned long data) +{ + struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data; + struct zfcp_port *port = adisc->els.port; + struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc; + + if (!adisc->els.status) { + /* request rejected or timed out */ + zfcp_erp_port_forced_reopen(port, 0, 63, NULL); + goto out; + } + + if (!port->wwnn) + port->wwnn = ls_adisc->wwnn; + + if (port->wwpn != ls_adisc->wwpn) + zfcp_erp_port_reopen(port, 0, 64, NULL); + + out: + zfcp_port_put(port); + kfree(adisc); +} + +static int zfcp_fc_adisc(struct zfcp_port *port) +{ + struct zfcp_els_adisc *adisc; + struct zfcp_adapter *adapter = port->adapter; + + adisc = kzalloc(sizeof(struct zfcp_els_adisc), GFP_ATOMIC); + if (!adisc) + return -ENOMEM; + + adisc->els.req = &adisc->req; + adisc->els.resp = &adisc->resp; + sg_init_one(adisc->els.req, &adisc->ls_adisc, + sizeof(struct zfcp_ls_adisc)); + sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, + sizeof(struct zfcp_ls_adisc_acc)); + + adisc->els.req_count = 1; + adisc->els.resp_count = 1; + adisc->els.adapter = adapter; + adisc->els.port = port; + adisc->els.d_id = port->d_id; + adisc->els.handler = zfcp_fc_adisc_handler; + adisc->els.handler_data = (unsigned long) adisc; + adisc->els.ls_code = adisc->ls_adisc.code = ZFCP_LS_ADISC; + + /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports + without FC-AL-2 capability, so we don't set it */ + adisc->ls_adisc.wwpn = fc_host_port_name(adapter->scsi_host); + adisc->ls_adisc.wwnn = fc_host_node_name(adapter->scsi_host); + adisc->ls_adisc.nport_id = fc_host_port_id(adapter->scsi_host); + + return zfcp_fsf_send_els(&adisc->els); +} + +/** + * zfcp_test_link - lightweight link test procedure + * @port: port to be tested + * + * Test status of a link to a remote port using the ELS command ADISC. + * If there is a problem with the remote port, error recovery steps + * will be triggered. + */ +void zfcp_test_link(struct zfcp_port *port) +{ + int retval; + + zfcp_port_get(port); + retval = zfcp_fc_adisc(port); + if (retval == 0 || retval == -EBUSY) + return; + + /* send of ADISC was not possible */ + zfcp_port_put(port); + zfcp_erp_port_forced_reopen(port, 0, 65, NULL); +} diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 01f9b27..8568b6f 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -848,7 +848,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_STATUS_READ_INCOMING_ELS: - zfcp_fsf_incoming_els(fsf_req); + zfcp_fc_incoming_els(fsf_req); break; case FSF_STATUS_READ_SENSE_DATA_AVAIL: @@ -1742,10 +1742,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = - zfcp_handle_els_rjt(header->fsf_status_qual.word[1], - (struct zfcp_ls_rjt_par *) - &header->fsf_status_qual.word[2]); break; case FSF_SQ_RETRY_IF_POSSIBLE: fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -2534,7 +2530,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) &port->status); } else { port->wwnn = plogi->serv_param.wwnn; - zfcp_plogi_evaluate(port, plogi); + zfcp_fc_plogi_evaluate(port, plogi); } } } -- cgit v0.10.2 From 45633fdc9615f9fd2a0ae18e301562298b15abf3 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:55 +0200 Subject: [SCSI] zfcp: Move CFDC code to new file. zfcp implements a device file to allow Linux guests changing the Access Control Tables stored in the adapter. The code for the device file has nothing to do with the other parts of the driver, so move it to a new file and cleanup the code while doing so. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index f775f9e..c0fa8ff 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -4,6 +4,6 @@ zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \ - zfcp_sysfs_unit.o zfcp_sysfs_driver.o zfcp_fc.o + zfcp_sysfs_unit.o zfcp_sysfs_driver.o zfcp_fc.o zfcp_cfdc.o obj-$(CONFIG_ZFCP) += zfcp.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 9eb8827..735f7af 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -33,6 +33,7 @@ * Ralph Wuerthner */ +#include #include "zfcp_ext.h" /* accumulated log level (module parameter) */ @@ -43,33 +44,6 @@ static char *device; /* written against the module interface */ static int __init zfcp_module_init(void); -/* miscellaneous */ -static int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t); -static void zfcp_sg_list_free(struct zfcp_sg_list *); -static int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *, - void __user *, size_t); -static int zfcp_sg_list_copy_to_user(void __user *, - struct zfcp_sg_list *, size_t); -static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long); - -#define ZFCP_CFDC_IOC_MAGIC 0xDD -#define ZFCP_CFDC_IOC \ - _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_sense_data) - - -static const struct file_operations zfcp_cfdc_fops = { - .unlocked_ioctl = zfcp_cfdc_dev_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = zfcp_cfdc_dev_ioctl -#endif -}; - -static struct miscdevice zfcp_cfdc_misc = { - .minor = ZFCP_CFDC_DEV_MINOR, - .name = ZFCP_CFDC_DEV_NAME, - .fops = &zfcp_cfdc_fops -}; - /*********************** KERNEL/MODULE PARAMETERS ***************************/ /* declare driver module init/cleanup functions */ @@ -294,9 +268,6 @@ zfcp_module_init(void) goto out_misc; } - ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n", - ZFCP_CFDC_DEV_MAJOR, zfcp_cfdc_misc.minor); - /* Initialise proc semaphores */ sema_init(&zfcp_data.config_sema, 1); @@ -329,372 +300,6 @@ zfcp_module_init(void) return retval; } -/* - * function: zfcp_cfdc_dev_ioctl - * - * purpose: Handle control file upload/download transaction via IOCTL - * interface - * - * returns: 0 - Operation completed successfuly - * -ENOTTY - Unknown IOCTL command - * -EINVAL - Invalid sense data record - * -ENXIO - The FCP adapter is not available - * -EOPNOTSUPP - The FCP adapter does not have CFDC support - * -ENOMEM - Insufficient memory - * -EFAULT - User space memory I/O operation fault - * -EPERM - Cannot create or queue FSF request or create SBALs - * -ERESTARTSYS- Received signal (is mapped to EAGAIN by VFS) - */ -static long -zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, - unsigned long buffer) -{ - struct zfcp_cfdc_sense_data *sense_data, __user *sense_data_user; - struct zfcp_adapter *adapter = NULL; - struct zfcp_fsf_req *fsf_req = NULL; - struct zfcp_sg_list *sg_list = NULL; - u32 fsf_command, option; - char *bus_id = NULL; - int retval = 0; - - sense_data = kmalloc(sizeof(struct zfcp_cfdc_sense_data), GFP_KERNEL); - if (sense_data == NULL) { - retval = -ENOMEM; - goto out; - } - - sg_list = kzalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL); - if (sg_list == NULL) { - retval = -ENOMEM; - goto out; - } - - if (command != ZFCP_CFDC_IOC) { - ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command); - retval = -ENOTTY; - goto out; - } - - if ((sense_data_user = (void __user *) buffer) == NULL) { - ZFCP_LOG_INFO("sense data record is required\n"); - retval = -EINVAL; - goto out; - } - - retval = copy_from_user(sense_data, sense_data_user, - sizeof(struct zfcp_cfdc_sense_data)); - if (retval) { - retval = -EFAULT; - goto out; - } - - if (sense_data->signature != ZFCP_CFDC_SIGNATURE) { - ZFCP_LOG_INFO("invalid sense data request signature 0x%08x\n", - ZFCP_CFDC_SIGNATURE); - retval = -EINVAL; - goto out; - } - - switch (sense_data->command) { - - case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL: - fsf_command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - option = FSF_CFDC_OPTION_NORMAL_MODE; - break; - - case ZFCP_CFDC_CMND_DOWNLOAD_FORCE: - fsf_command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - option = FSF_CFDC_OPTION_FORCE; - break; - - case ZFCP_CFDC_CMND_FULL_ACCESS: - fsf_command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - option = FSF_CFDC_OPTION_FULL_ACCESS; - break; - - case ZFCP_CFDC_CMND_RESTRICTED_ACCESS: - fsf_command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - option = FSF_CFDC_OPTION_RESTRICTED_ACCESS; - break; - - case ZFCP_CFDC_CMND_UPLOAD: - fsf_command = FSF_QTCB_UPLOAD_CONTROL_FILE; - option = 0; - break; - - default: - ZFCP_LOG_INFO("invalid command code 0x%08x\n", - sense_data->command); - retval = -EINVAL; - goto out; - } - - bus_id = kmalloc(BUS_ID_SIZE, GFP_KERNEL); - if (bus_id == NULL) { - retval = -ENOMEM; - goto out; - } - snprintf(bus_id, BUS_ID_SIZE, "%d.%d.%04x", - (sense_data->devno >> 24), - (sense_data->devno >> 16) & 0xFF, - (sense_data->devno & 0xFFFF)); - - read_lock_irq(&zfcp_data.config_lock); - adapter = zfcp_get_adapter_by_busid(bus_id); - if (adapter) - zfcp_adapter_get(adapter); - read_unlock_irq(&zfcp_data.config_lock); - - kfree(bus_id); - - if (adapter == NULL) { - ZFCP_LOG_INFO("invalid adapter\n"); - retval = -ENXIO; - goto out; - } - - if (sense_data->command & ZFCP_CFDC_WITH_CONTROL_FILE) { - retval = zfcp_sg_list_alloc(sg_list, - ZFCP_CFDC_MAX_CONTROL_FILE_SIZE); - if (retval) { - retval = -ENOMEM; - goto out; - } - } - - if ((sense_data->command & ZFCP_CFDC_DOWNLOAD) && - (sense_data->command & ZFCP_CFDC_WITH_CONTROL_FILE)) { - retval = zfcp_sg_list_copy_from_user( - sg_list, &sense_data_user->control_file, - ZFCP_CFDC_MAX_CONTROL_FILE_SIZE); - if (retval) { - retval = -EFAULT; - goto out; - } - } - - retval = zfcp_fsf_control_file(adapter, &fsf_req, fsf_command, - option, sg_list); - if (retval) - goto out; - - if ((fsf_req->qtcb->prefix.prot_status != FSF_PROT_GOOD) && - (fsf_req->qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { - retval = -ENXIO; - goto out; - } - - sense_data->fsf_status = fsf_req->qtcb->header.fsf_status; - memcpy(&sense_data->fsf_status_qual, - &fsf_req->qtcb->header.fsf_status_qual, - sizeof(union fsf_status_qual)); - memcpy(&sense_data->payloads, &fsf_req->qtcb->bottom.support.els, 256); - - retval = copy_to_user(sense_data_user, sense_data, - sizeof(struct zfcp_cfdc_sense_data)); - if (retval) { - retval = -EFAULT; - goto out; - } - - if (sense_data->command & ZFCP_CFDC_UPLOAD) { - retval = zfcp_sg_list_copy_to_user( - &sense_data_user->control_file, sg_list, - ZFCP_CFDC_MAX_CONTROL_FILE_SIZE); - if (retval) { - retval = -EFAULT; - goto out; - } - } - - out: - if (fsf_req != NULL) - zfcp_fsf_req_free(fsf_req); - - if ((adapter != NULL) && (retval != -ENXIO)) - zfcp_adapter_put(adapter); - - if (sg_list != NULL) { - zfcp_sg_list_free(sg_list); - kfree(sg_list); - } - - kfree(sense_data); - - return retval; -} - - -/** - * zfcp_sg_list_alloc - create a scatter-gather list of the specified size - * @sg_list: structure describing a scatter gather list - * @size: size of scatter-gather list - * Return: 0 on success, else -ENOMEM - * - * In sg_list->sg a pointer to the created scatter-gather list is returned, - * or NULL if we run out of memory. sg_list->count specifies the number of - * elements of the scatter-gather list. The maximum size of a single element - * in the scatter-gather list is PAGE_SIZE. - */ -static int -zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) -{ - struct scatterlist *sg; - unsigned int i; - int retval = 0; - void *address; - - BUG_ON(sg_list == NULL); - - sg_list->count = size >> PAGE_SHIFT; - if (size & ~PAGE_MASK) - sg_list->count++; - sg_list->sg = kcalloc(sg_list->count, sizeof(struct scatterlist), - GFP_KERNEL); - if (sg_list->sg == NULL) { - sg_list->count = 0; - retval = -ENOMEM; - goto out; - } - sg_init_table(sg_list->sg, sg_list->count); - - for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) { - address = (void *) get_zeroed_page(GFP_KERNEL); - if (address == NULL) { - sg_list->count = i; - zfcp_sg_list_free(sg_list); - retval = -ENOMEM; - goto out; - } - zfcp_address_to_sg(address, sg, min(size, PAGE_SIZE)); - size -= sg->length; - } - - out: - return retval; -} - - -/** - * zfcp_sg_list_free - free memory of a scatter-gather list - * @sg_list: structure describing a scatter-gather list - * - * Memory for each element in the scatter-gather list is freed. - * Finally sg_list->sg is freed itself and sg_list->count is reset. - */ -static void -zfcp_sg_list_free(struct zfcp_sg_list *sg_list) -{ - struct scatterlist *sg; - unsigned int i; - - BUG_ON(sg_list == NULL); - - for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) - free_page((unsigned long) zfcp_sg_to_address(sg)); - - sg_list->count = 0; - kfree(sg_list->sg); -} - -/** - * zfcp_sg_size - determine size of a scatter-gather list - * @sg: array of (struct scatterlist) - * @sg_count: elements in array - * Return: size of entire scatter-gather list - */ -static size_t zfcp_sg_size(struct scatterlist *sg, unsigned int sg_count) -{ - unsigned int i; - struct scatterlist *p; - size_t size; - - size = 0; - for (i = 0, p = sg; i < sg_count; i++, p++) { - BUG_ON(p == NULL); - size += p->length; - } - - return size; -} - - -/** - * zfcp_sg_list_copy_from_user -copy data from user space to scatter-gather list - * @sg_list: structure describing a scatter-gather list - * @user_buffer: pointer to buffer in user space - * @size: number of bytes to be copied - * Return: 0 on success, -EFAULT if copy_from_user fails. - */ -static int -zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list, - void __user *user_buffer, - size_t size) -{ - struct scatterlist *sg; - unsigned int length; - void *zfcp_buffer; - int retval = 0; - - BUG_ON(sg_list == NULL); - - if (zfcp_sg_size(sg_list->sg, sg_list->count) < size) - return -EFAULT; - - for (sg = sg_list->sg; size > 0; sg++) { - length = min((unsigned int)size, sg->length); - zfcp_buffer = zfcp_sg_to_address(sg); - if (copy_from_user(zfcp_buffer, user_buffer, length)) { - retval = -EFAULT; - goto out; - } - user_buffer += length; - size -= length; - } - - out: - return retval; -} - - -/** - * zfcp_sg_list_copy_to_user - copy data from scatter-gather list to user space - * @user_buffer: pointer to buffer in user space - * @sg_list: structure describing a scatter-gather list - * @size: number of bytes to be copied - * Return: 0 on success, -EFAULT if copy_to_user fails - */ -static int -zfcp_sg_list_copy_to_user(void __user *user_buffer, - struct zfcp_sg_list *sg_list, - size_t size) -{ - struct scatterlist *sg; - unsigned int length; - void *zfcp_buffer; - int retval = 0; - - BUG_ON(sg_list == NULL); - - if (zfcp_sg_size(sg_list->sg, sg_list->count) < size) - return -EFAULT; - - for (sg = sg_list->sg; size > 0; sg++) { - length = min((unsigned int) size, sg->length); - zfcp_buffer = zfcp_sg_to_address(sg); - if (copy_to_user(user_buffer, zfcp_buffer, length)) { - retval = -EFAULT; - goto out; - } - user_buffer += length; - size -= length; - } - - out: - return retval; -} - - #undef ZFCP_LOG_AREA /****************************************************************/ @@ -1345,4 +950,32 @@ zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) return 0; } +void zfcp_sg_free_table(struct scatterlist *sg, int count) +{ + int i; + + for (i = 0; i < count; i++, sg++) + if (sg) + free_page((unsigned long) sg_virt(sg)); + else + break; +} + +int zfcp_sg_setup_table(struct scatterlist *sg, int count) +{ + void *addr; + int i; + + sg_init_table(sg, count); + for (i = 0; i < count; i++, sg++) { + addr = (void *) get_zeroed_page(GFP_KERNEL); + if (!addr) { + zfcp_sg_free_table(sg, i); + return -ENOMEM; + } + sg_set_buf(sg, addr, PAGE_SIZE); + } + return 0; +} + #undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c new file mode 100644 index 0000000..ec2abce --- /dev/null +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -0,0 +1,259 @@ +/* + * zfcp device driver + * + * Userspace interface for accessing the + * Access Control Lists / Control File Data Channel + * + * Copyright IBM Corporation 2008 + */ + +#include +#include +#include +#include "zfcp_def.h" +#include "zfcp_ext.h" +#include "zfcp_fsf.h" + +#define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL 0x00010001 +#define ZFCP_CFDC_CMND_DOWNLOAD_FORCE 0x00010101 +#define ZFCP_CFDC_CMND_FULL_ACCESS 0x00000201 +#define ZFCP_CFDC_CMND_RESTRICTED_ACCESS 0x00000401 +#define ZFCP_CFDC_CMND_UPLOAD 0x00010002 + +#define ZFCP_CFDC_DOWNLOAD 0x00000001 +#define ZFCP_CFDC_UPLOAD 0x00000002 +#define ZFCP_CFDC_WITH_CONTROL_FILE 0x00010000 + +#define ZFCP_CFDC_IOC_MAGIC 0xDD +#define ZFCP_CFDC_IOC \ + _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_data) + +/** + * struct zfcp_cfdc_data - data for ioctl cfdc interface + * @signature: request signature + * @devno: FCP adapter device number + * @command: command code + * @fsf_status: returns status of FSF command to userspace + * @fsf_status_qual: returned to userspace + * @payloads: access conflicts list + * @control_file: access control table + */ +struct zfcp_cfdc_data { + u32 signature; + u32 devno; + u32 command; + u32 fsf_status; + u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; + u8 payloads[256]; + u8 control_file[0]; +}; + +static int zfcp_cfdc_copy_from_user(struct scatterlist *sg, + void __user *user_buffer) +{ + unsigned int length; + unsigned int size = ZFCP_CFDC_MAX_SIZE; + + while (size) { + length = min((unsigned int)size, sg->length); + if (copy_from_user(sg_virt(sg++), user_buffer, length)) + return -EFAULT; + user_buffer += length; + size -= length; + } + return 0; +} + +static int zfcp_cfdc_copy_to_user(void __user *user_buffer, + struct scatterlist *sg) +{ + unsigned int length; + unsigned int size = ZFCP_CFDC_MAX_SIZE; + + while (size) { + length = min((unsigned int) size, sg->length); + if (copy_to_user(user_buffer, sg_virt(sg++), length)) + return -EFAULT; + user_buffer += length; + size -= length; + } + return 0; +} + +static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) +{ + struct zfcp_adapter *adapter = NULL, *cur_adapter; + struct ccw_dev_id dev_id; + + read_lock_irq(&zfcp_data.config_lock); + list_for_each_entry(cur_adapter, &zfcp_data.adapter_list_head, list) { + ccw_device_get_id(cur_adapter->ccw_device, &dev_id); + if (dev_id.devno == devno) { + adapter = cur_adapter; + zfcp_adapter_get(adapter); + break; + } + } + read_unlock_irq(&zfcp_data.config_lock); + return adapter; +} + +static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) +{ + switch (command) { + case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL: + fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; + fsf_cfdc->option = FSF_CFDC_OPTION_NORMAL_MODE; + break; + case ZFCP_CFDC_CMND_DOWNLOAD_FORCE: + fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; + fsf_cfdc->option = FSF_CFDC_OPTION_FORCE; + break; + case ZFCP_CFDC_CMND_FULL_ACCESS: + fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; + fsf_cfdc->option = FSF_CFDC_OPTION_FULL_ACCESS; + break; + case ZFCP_CFDC_CMND_RESTRICTED_ACCESS: + fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; + fsf_cfdc->option = FSF_CFDC_OPTION_RESTRICTED_ACCESS; + break; + case ZFCP_CFDC_CMND_UPLOAD: + fsf_cfdc->command = FSF_QTCB_UPLOAD_CONTROL_FILE; + fsf_cfdc->option = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int zfcp_cfdc_sg_setup(int command, struct scatterlist *sg, + u8 __user *control_file) +{ + int retval; + retval = zfcp_sg_setup_table(sg, ZFCP_CFDC_PAGES); + if (retval) + return retval; + + sg[ZFCP_CFDC_PAGES - 1].length = ZFCP_CFDC_MAX_SIZE % PAGE_SIZE; + + if (command & ZFCP_CFDC_WITH_CONTROL_FILE && + command & ZFCP_CFDC_DOWNLOAD) { + retval = zfcp_cfdc_copy_from_user(sg, control_file); + if (retval) { + zfcp_sg_free_table(sg, ZFCP_CFDC_PAGES); + return -EFAULT; + } + } + + return 0; +} + +static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data, + struct zfcp_fsf_req *req) +{ + data->fsf_status = req->qtcb->header.fsf_status; + memcpy(&data->fsf_status_qual, &req->qtcb->header.fsf_status_qual, + sizeof(union fsf_status_qual)); + memcpy(&data->payloads, &req->qtcb->bottom.support.els, + sizeof(req->qtcb->bottom.support.els)); +} + +static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, + unsigned long buffer) +{ + struct zfcp_cfdc_data *data; + struct zfcp_cfdc_data __user *data_user; + struct zfcp_adapter *adapter; + struct zfcp_fsf_req *req; + struct zfcp_fsf_cfdc *fsf_cfdc; + int retval; + + if (command != ZFCP_CFDC_IOC) + return -ENOTTY; + + data_user = (void __user *) buffer; + if (!data_user) + return -EINVAL; + + fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL); + if (!fsf_cfdc) + return -ENOMEM; + + data = kmalloc(sizeof(struct zfcp_cfdc_data), GFP_KERNEL); + if (!data) { + retval = -ENOMEM; + goto no_mem_sense; + } + + retval = copy_from_user(data, data_user, sizeof(*data)); + if (retval) { + retval = -EFAULT; + goto free_buffer; + } + + if (data->signature != 0xCFDCACDF) { + retval = -EINVAL; + goto free_buffer; + } + + retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command); + + adapter = zfcp_cfdc_get_adapter(data->devno); + if (!adapter) { + retval = -ENXIO; + goto free_buffer; + } + + retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg, + data_user->control_file); + if (retval) + goto adapter_put; + req = zfcp_fsf_control_file(adapter, fsf_cfdc); + if (IS_ERR(req)) { + retval = PTR_ERR(req); + goto free_sg; + } + + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { + retval = -ENXIO; + goto free_fsf; + } + + zfcp_cfdc_req_to_sense(data, req); + retval = copy_to_user(data_user, data, sizeof(*data_user)); + if (retval) { + retval = -EFAULT; + goto free_fsf; + } + + if (data->command & ZFCP_CFDC_UPLOAD) + retval = zfcp_cfdc_copy_to_user(&data_user->control_file, + fsf_cfdc->sg); + + free_fsf: + zfcp_fsf_req_free(req); + free_sg: + zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES); + adapter_put: + zfcp_adapter_put(adapter); + free_buffer: + kfree(data); + no_mem_sense: + kfree(fsf_cfdc); + return retval; +} + +static const struct file_operations zfcp_cfdc_fops = { + .unlocked_ioctl = zfcp_cfdc_dev_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = zfcp_cfdc_dev_ioctl +#endif +}; + +struct miscdevice zfcp_cfdc_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "zfcp_cfdc", + .fops = &zfcp_cfdc_fops, +}; diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index d23c3b9..72f2258 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -534,38 +533,6 @@ do { \ #define ZFCP_ERP_DISMISSED 0x4 #define ZFCP_ERP_NOMEM 0x5 - -/******************** CFDC SPECIFIC STUFF *****************************/ - -/* Firewall data channel sense data record */ -struct zfcp_cfdc_sense_data { - u32 signature; /* Request signature */ - u32 devno; /* FCP adapter device number */ - u32 command; /* Command code */ - u32 fsf_status; /* FSF request status and status qualifier */ - u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; - u8 payloads[256]; /* Access conflicts list */ - u8 control_file[0]; /* Access control table */ -}; - -#define ZFCP_CFDC_SIGNATURE 0xCFDCACDF - -#define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL 0x00010001 -#define ZFCP_CFDC_CMND_DOWNLOAD_FORCE 0x00010101 -#define ZFCP_CFDC_CMND_FULL_ACCESS 0x00000201 -#define ZFCP_CFDC_CMND_RESTRICTED_ACCESS 0x00000401 -#define ZFCP_CFDC_CMND_UPLOAD 0x00010002 - -#define ZFCP_CFDC_DOWNLOAD 0x00000001 -#define ZFCP_CFDC_UPLOAD 0x00000002 -#define ZFCP_CFDC_WITH_CONTROL_FILE 0x00010000 - -#define ZFCP_CFDC_DEV_NAME "zfcp_cfdc" -#define ZFCP_CFDC_DEV_MAJOR MISC_MAJOR -#define ZFCP_CFDC_DEV_MINOR MISC_DYNAMIC_MINOR - -#define ZFCP_CFDC_MAX_CONTROL_FILE_SIZE 127 * 1024 - /************************* STRUCTURE DEFINITIONS *****************************/ struct zfcp_fsf_req; @@ -897,16 +864,6 @@ struct zfcp_data { struct kmem_cache *gid_pn_cache; }; -/** - * struct zfcp_sg_list - struct describing a scatter-gather list - * @sg: pointer to array of (struct scatterlist) - * @count: number of elements in scatter-gather list - */ -struct zfcp_sg_list { - struct scatterlist *sg; - unsigned int count; -}; - /* number of elements for various memory pools */ #define ZFCP_POOL_FSF_REQ_ERP_NR 1 #define ZFCP_POOL_FSF_REQ_SCSI_NR 1 diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 91d5884..8679728 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -86,8 +86,8 @@ extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *, extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *, struct fsf_qtcb_bottom_port *); -extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, - u32, u32, struct zfcp_sg_list *); +extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, + struct zfcp_fsf_cfdc *fsf_cfdc); extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); @@ -167,6 +167,8 @@ extern void zfcp_erp_port_access_changed(struct zfcp_port *, u8, void *); extern void zfcp_erp_unit_access_changed(struct zfcp_unit *, u8, void *); /******************************** AUX ****************************************/ +extern void zfcp_sg_free_table(struct scatterlist *sg, int count); +extern int zfcp_sg_setup_table(struct scatterlist *sg, int count); extern void zfcp_rec_dbf_event_thread(u8 id, struct zfcp_adapter *adapter); extern void zfcp_rec_dbf_event_thread_lock(u8 id, struct zfcp_adapter *adapter); extern void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *); @@ -200,4 +202,6 @@ extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, struct scsi_cmnd *); extern int zfcp_reqlist_isempty(struct zfcp_adapter *); +extern struct miscdevice zfcp_cfdc_misc; + #endif /* ZFCP_EXT_H */ diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 8568b6f..de42a01 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -36,7 +36,7 @@ static int zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *); static int zfcp_fsf_status_read_handler(struct zfcp_fsf_req *); static int zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *); static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_control_file_handler(struct zfcp_fsf_req *); +static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *); static inline int zfcp_fsf_req_sbal_check( unsigned long *, struct zfcp_qdio_queue *, int); static inline int zfcp_use_one_sbal( @@ -4183,53 +4183,35 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) * -ENOMEM - Insufficient memory * -EPERM - Cannot create FSF request or place it in QDIO queue */ -int -zfcp_fsf_control_file(struct zfcp_adapter *adapter, - struct zfcp_fsf_req **fsf_req_ptr, - u32 fsf_command, - u32 option, - struct zfcp_sg_list *sg_list) +struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, + struct zfcp_fsf_cfdc *fsf_cfdc) { struct zfcp_fsf_req *fsf_req; struct fsf_qtcb_bottom_support *bottom; volatile struct qdio_buffer_element *sbale; unsigned long lock_flags; - int req_flags = 0; int direction; - int retval = 0; - - if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) { - ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n", - zfcp_get_busid_by_adapter(adapter)); - retval = -EOPNOTSUPP; - goto out; - } + int retval; + int bytes; - switch (fsf_command) { + if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) + return ERR_PTR(-EOPNOTSUPP); + switch (fsf_cfdc->command) { case FSF_QTCB_DOWNLOAD_CONTROL_FILE: direction = SBAL_FLAGS0_TYPE_WRITE; - if ((option != FSF_CFDC_OPTION_FULL_ACCESS) && - (option != FSF_CFDC_OPTION_RESTRICTED_ACCESS)) - req_flags = ZFCP_WAIT_FOR_SBAL; break; - case FSF_QTCB_UPLOAD_CONTROL_FILE: direction = SBAL_FLAGS0_TYPE_READ; break; - default: - ZFCP_LOG_INFO("Invalid FSF command code 0x%08x\n", fsf_command); - retval = -EINVAL; - goto out; + return ERR_PTR(-EINVAL); } - retval = zfcp_fsf_req_create(adapter, fsf_command, req_flags, + retval = zfcp_fsf_req_create(adapter, fsf_cfdc->command, + ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags, &fsf_req); if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create FSF request for the " - "adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); retval = -EPERM; goto unlock_queue_lock; } @@ -4239,220 +4221,40 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter, bottom = &fsf_req->qtcb->bottom.support; bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; - bottom->option = option; - - if (sg_list->count > 0) { - int bytes; - - bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction, - sg_list->sg, sg_list->count, - ZFCP_MAX_SBALS_PER_REQ); - if (bytes != ZFCP_CFDC_MAX_CONTROL_FILE_SIZE) { - ZFCP_LOG_INFO( - "error: Could not create sufficient number of " - "SBALS for an FSF request to the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - retval = -ENOMEM; - goto free_fsf_req; - } - } else - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + bottom->option = fsf_cfdc->option; + + bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction, + fsf_cfdc->sg, ZFCP_CFDC_PAGES, + ZFCP_MAX_SBALS_PER_REQ); + if (bytes != ZFCP_CFDC_MAX_SIZE) { + retval = -ENOMEM; + goto free_fsf_req; + } zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(fsf_req); if (retval < 0) { - ZFCP_LOG_INFO("initiation of cfdc up/download failed" - "(adapter %s)\n", - zfcp_get_busid_by_adapter(adapter)); retval = -EPERM; goto free_fsf_req; } write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); - ZFCP_LOG_NORMAL("Control file %s FSF request has been sent to the " - "adapter %s\n", - fsf_command == FSF_QTCB_DOWNLOAD_CONTROL_FILE ? - "download" : "upload", - zfcp_get_busid_by_adapter(adapter)); - wait_event(fsf_req->completion_wq, fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); - *fsf_req_ptr = fsf_req; - goto out; + return fsf_req; free_fsf_req: zfcp_fsf_req_free(fsf_req); unlock_queue_lock: write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); - out: - return retval; + return ERR_PTR(retval); } - -/* - * function: zfcp_fsf_control_file_handler - * - * purpose: Handler of the control file upload/download FSF requests - * - * returns: 0 - FSF request successfuly processed - * -EAGAIN - Operation has to be repeated because of a temporary problem - * -EACCES - There is no permission to execute an operation - * -EPERM - The control file is not in a right format - * -EIO - There is a problem with the FCP adapter - * -EINVAL - Invalid operation - * -EFAULT - User space memory I/O operation fault - */ -static int -zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req) { - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fsf_qtcb_header *header = &fsf_req->qtcb->header; - struct fsf_qtcb_bottom_support *bottom = &fsf_req->qtcb->bottom.support; - int retval = 0; - - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - retval = -EINVAL; - goto skip_fsfstatus; - } - - switch (header->fsf_status) { - - case FSF_GOOD: - ZFCP_LOG_NORMAL( - "The FSF request has been successfully completed " - "on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - break; - - case FSF_OPERATION_PARTIALLY_SUCCESSFUL: - if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) { - switch (header->fsf_status_qual.word[0]) { - - case FSF_SQ_CFDC_HARDENED_ON_SE: - ZFCP_LOG_NORMAL( - "CFDC on the adapter %s has being " - "hardened on primary and secondary SE\n", - zfcp_get_busid_by_adapter(adapter)); - break; - - case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE: - ZFCP_LOG_NORMAL( - "CFDC of the adapter %s could not " - "be saved on the SE\n", - zfcp_get_busid_by_adapter(adapter)); - break; - - case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2: - ZFCP_LOG_NORMAL( - "CFDC of the adapter %s could not " - "be copied to the secondary SE\n", - zfcp_get_busid_by_adapter(adapter)); - break; - - default: - ZFCP_LOG_NORMAL( - "CFDC could not be hardened " - "on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - } - } - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EAGAIN; - break; - - case FSF_AUTHORIZATION_FAILURE: - ZFCP_LOG_NORMAL( - "Adapter %s does not accept privileged commands\n", - zfcp_get_busid_by_adapter(adapter)); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EACCES; - break; - - case FSF_CFDC_ERROR_DETECTED: - ZFCP_LOG_NORMAL( - "Error at position %d in the CFDC, " - "CFDC is discarded by the adapter %s\n", - header->fsf_status_qual.word[0], - zfcp_get_busid_by_adapter(adapter)); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EPERM; - break; - - case FSF_CONTROL_FILE_UPDATE_ERROR: - ZFCP_LOG_NORMAL( - "Adapter %s cannot harden the control file, " - "file is discarded\n", - zfcp_get_busid_by_adapter(adapter)); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EIO; - break; - - case FSF_CONTROL_FILE_TOO_LARGE: - ZFCP_LOG_NORMAL( - "Control file is too large, file is discarded " - "by the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EIO; - break; - - case FSF_ACCESS_CONFLICT_DETECTED: - if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) - ZFCP_LOG_NORMAL( - "CFDC has been discarded by the adapter %s, " - "because activation would impact " - "%d active connection(s)\n", - zfcp_get_busid_by_adapter(adapter), - header->fsf_status_qual.word[0]); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EIO; - break; - - case FSF_CONFLICTS_OVERRULED: - if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) - ZFCP_LOG_NORMAL( - "CFDC has been activated on the adapter %s, " - "but activation has impacted " - "%d active connection(s)\n", - zfcp_get_busid_by_adapter(adapter), - header->fsf_status_qual.word[0]); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EIO; - break; - - case FSF_UNKNOWN_OP_SUBTYPE: - ZFCP_LOG_NORMAL("unknown operation subtype (adapter: %s, " - "op_subtype=0x%x)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->operation_subtype); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EINVAL; - break; - - case FSF_INVALID_COMMAND_OPTION: - ZFCP_LOG_NORMAL( - "Invalid option 0x%x has been specified " - "in QTCB bottom sent to the adapter %s\n", - bottom->option, - zfcp_get_busid_by_adapter(adapter)); + if (fsf_req->qtcb->header.fsf_status != FSF_GOOD) fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EINVAL; - break; - - default: - ZFCP_LOG_NORMAL( - "bug: An unknown/unexpected FSF status 0x%08x " - "was presented on the adapter %s\n", - header->fsf_status, - zfcp_get_busid_by_adapter(adapter)); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EINVAL; - break; - } - -skip_fsfstatus: - return retval; } static inline int diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 8b1a7d9..598eba9 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -22,6 +22,8 @@ #ifndef FSF_H #define FSF_H +#include + #define FSF_QTCB_CURRENT_VERSION 0x00000001 /* FSF commands */ @@ -258,6 +260,16 @@ #define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000 #define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000 +/* FSF interface for CFDC */ +#define ZFCP_CFDC_MAX_SIZE 127 * 1024 +#define ZFCP_CFDC_PAGES PFN_UP(ZFCP_CFDC_MAX_SIZE) + +struct zfcp_fsf_cfdc { + struct scatterlist sg[ZFCP_CFDC_PAGES]; + u32 command; + u32 option; +}; + struct fsf_queue_designator { u8 cssid; u8 chpid; -- cgit v0.10.2 From fa04c2816883a49ec518514f6c19767d54be20b5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:56 +0200 Subject: [SCSI] zfcp: Cleanup code in zfcp_ccw Overall cleanup in file zfcp_ccw.c. Fix coding style issues, remove useless macros and messages and convert remaining messages to standard macros. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 66d3b88..da472e8 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -1,64 +1,13 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Registration and callback for the s390 common I/O layer. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, 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. + * Copyright IBM Corporation 2002, 2008 */ #include "zfcp_ext.h" -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG - -static int zfcp_ccw_probe(struct ccw_device *); -static void zfcp_ccw_remove(struct ccw_device *); -static int zfcp_ccw_set_online(struct ccw_device *); -static int zfcp_ccw_set_offline(struct ccw_device *); -static int zfcp_ccw_notify(struct ccw_device *, int); -static void zfcp_ccw_shutdown(struct ccw_device *); - -static struct ccw_device_id zfcp_ccw_device_id[] = { - {CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE, - ZFCP_CONTROL_UNIT_MODEL, - ZFCP_DEVICE_TYPE, - ZFCP_DEVICE_MODEL)}, - {CCW_DEVICE_DEVTYPE(ZFCP_CONTROL_UNIT_TYPE, - ZFCP_CONTROL_UNIT_MODEL, - ZFCP_DEVICE_TYPE, - ZFCP_DEVICE_MODEL_PRIV)}, - {}, -}; - -static struct ccw_driver zfcp_ccw_driver = { - .owner = THIS_MODULE, - .name = ZFCP_NAME, - .ids = zfcp_ccw_device_id, - .probe = zfcp_ccw_probe, - .remove = zfcp_ccw_remove, - .set_online = zfcp_ccw_set_online, - .set_offline = zfcp_ccw_set_offline, - .notify = zfcp_ccw_notify, - .shutdown = zfcp_ccw_shutdown, - .driver = { - .groups = zfcp_driver_attr_groups, - }, -}; - -MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); - /** * zfcp_ccw_probe - probe function of zfcp driver * @ccw_device: pointer to belonging ccw device @@ -69,19 +18,18 @@ MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); * In addition the nameserver port will be added to the ports of the adapter * and its sysfs representation will be created too. */ -static int -zfcp_ccw_probe(struct ccw_device *ccw_device) +static int zfcp_ccw_probe(struct ccw_device *ccw_device) { struct zfcp_adapter *adapter; int retval = 0; down(&zfcp_data.config_sema); adapter = zfcp_adapter_enqueue(ccw_device); - if (!adapter) + if (!adapter) { + dev_err(&ccw_device->dev, + "Setup of data structures failed.\n"); retval = -EINVAL; - else - ZFCP_LOG_DEBUG("Probed adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + } up(&zfcp_data.config_sema); return retval; } @@ -95,8 +43,7 @@ zfcp_ccw_probe(struct ccw_device *ccw_device) * ports that belong to this adapter. And in addition all resources of this * adapter will be freed too. */ -static void -zfcp_ccw_remove(struct ccw_device *ccw_device) +static void zfcp_ccw_remove(struct ccw_device *ccw_device) { struct zfcp_adapter *adapter; struct zfcp_port *port, *p; @@ -106,8 +53,6 @@ zfcp_ccw_remove(struct ccw_device *ccw_device) down(&zfcp_data.config_sema); adapter = dev_get_drvdata(&ccw_device->dev); - ZFCP_LOG_DEBUG("Removing adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); write_lock_irq(&zfcp_data.config_lock); list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { @@ -145,8 +90,7 @@ zfcp_ccw_remove(struct ccw_device *ccw_device) * registered with the SCSI stack, that the QDIO queues will be set up * and that the adapter will be opened (asynchronously). */ -static int -zfcp_ccw_set_online(struct ccw_device *ccw_device) +static int zfcp_ccw_set_online(struct ccw_device *ccw_device) { struct zfcp_adapter *adapter; int retval; @@ -155,12 +99,8 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) adapter = dev_get_drvdata(&ccw_device->dev); retval = zfcp_erp_thread_setup(adapter); - if (retval) { - ZFCP_LOG_INFO("error: start of error recovery thread for " - "adapter %s failed\n", - zfcp_get_busid_by_adapter(adapter)); + if (retval) goto out; - } retval = zfcp_adapter_scsi_register(adapter); if (retval) @@ -191,8 +131,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) * This function gets called by the common i/o layer and sets an adapter * into state offline. */ -static int -zfcp_ccw_set_offline(struct ccw_device *ccw_device) +static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) { struct zfcp_adapter *adapter; @@ -206,15 +145,14 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device) } /** - * zfcp_ccw_notify + * zfcp_ccw_notify - ccw notify function * @ccw_device: pointer to belonging ccw device * @event: indicates if adapter was detached or attached * * This function gets called by the common i/o layer if an adapter has gone * or reappeared. */ -static int -zfcp_ccw_notify(struct ccw_device *ccw_device, int event) +static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) { struct zfcp_adapter *adapter; @@ -222,18 +160,15 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event) adapter = dev_get_drvdata(&ccw_device->dev); switch (event) { case CIO_GONE: - ZFCP_LOG_NORMAL("adapter %s: device gone\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&adapter->ccw_device->dev, "device gone\n"); zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); break; case CIO_NO_PATH: - ZFCP_LOG_NORMAL("adapter %s: no path\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&adapter->ccw_device->dev, "no path\n"); zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); break; case CIO_OPER: - ZFCP_LOG_NORMAL("adapter %s: operational again\n", - zfcp_get_busid_by_adapter(adapter)); + dev_info(&adapter->ccw_device->dev, "operational again\n"); zfcp_erp_modify_adapter_status(adapter, 11, NULL, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); @@ -247,24 +182,10 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event) } /** - * zfcp_ccw_register - ccw register function - * - * Registers the driver at the common i/o layer. This function will be called - * at module load time/system start. + * zfcp_ccw_shutdown - handle shutdown from cio + * @cdev: device for adapter to shutdown. */ -int __init -zfcp_ccw_register(void) -{ - return ccw_driver_register(&zfcp_ccw_driver); -} - -/** - * zfcp_ccw_shutdown - gets called on reboot/shutdown - * - * Makes sure that QDIO queues are down when the system gets stopped. - */ -static void -zfcp_ccw_shutdown(struct ccw_device *cdev) +static void zfcp_ccw_shutdown(struct ccw_device *cdev) { struct zfcp_adapter *adapter; @@ -275,4 +196,33 @@ zfcp_ccw_shutdown(struct ccw_device *cdev) up(&zfcp_data.config_sema); } -#undef ZFCP_LOG_AREA +static struct ccw_device_id zfcp_ccw_device_id[] = { + { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, + { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x4) }, /* priv. */ + {}, +}; + +MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); + +static struct ccw_driver zfcp_ccw_driver = { + .owner = THIS_MODULE, + .name = "zfcp", + .ids = zfcp_ccw_device_id, + .probe = zfcp_ccw_probe, + .remove = zfcp_ccw_remove, + .set_online = zfcp_ccw_set_online, + .set_offline = zfcp_ccw_set_offline, + .notify = zfcp_ccw_notify, + .shutdown = zfcp_ccw_shutdown, +}; + +/** + * zfcp_ccw_register - ccw register function + * + * Registers the driver at the common i/o layer. This function will be called + * at module load time/system start. + */ +int __init zfcp_ccw_register(void) +{ + return ccw_driver_register(&zfcp_ccw_driver); +} -- cgit v0.10.2 From 00bab91066a49468bfa4f6d5c8ad5e9ec53b7ea3 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Tue, 10 Jun 2008 18:20:57 +0200 Subject: [SCSI] zfcp: Cleanup qdio code Cleanup the interface code from zfcp to qdio. Also move code that belongs to the qdio interface from the erp to the qdio file. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 735f7af..7084a6a 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -606,7 +606,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) struct zfcp_adapter * zfcp_adapter_enqueue(struct ccw_device *ccw_device) { - int retval = 0; struct zfcp_adapter *adapter; /* @@ -627,19 +626,11 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* save ccw_device pointer */ adapter->ccw_device = ccw_device; - retval = zfcp_qdio_allocate_queues(adapter); - if (retval) - goto queues_alloc_failed; - - retval = zfcp_qdio_allocate(adapter); - if (retval) + if (zfcp_qdio_allocate(adapter)) goto qdio_allocate_failed; - retval = zfcp_allocate_low_mem_buffers(adapter); - if (retval) { - ZFCP_LOG_INFO("error: pool allocation failed\n"); + if (zfcp_allocate_low_mem_buffers(adapter)) goto failed_low_mem_buffers; - } /* initialise reference count stuff */ atomic_set(&adapter->refcount, 0); @@ -653,11 +644,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* initialize list of fsf requests */ spin_lock_init(&adapter->req_list_lock); - retval = zfcp_reqlist_alloc(adapter); - if (retval) { - ZFCP_LOG_INFO("request list initialization failed\n"); + if (zfcp_reqlist_alloc(adapter)) goto failed_low_mem_buffers; - } /* initialize debug locks */ @@ -666,8 +654,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) spin_lock_init(&adapter->scsi_dbf_lock); spin_lock_init(&adapter->rec_dbf_lock); - retval = zfcp_adapter_debug_register(adapter); - if (retval) + if (zfcp_adapter_debug_register(adapter)) goto debug_register_failed; /* initialize error recovery stuff */ @@ -685,7 +672,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) init_waitqueue_head(&adapter->erp_done_wqh); /* initialize lock of associated request queue */ - rwlock_init(&adapter->request_queue.queue_lock); + rwlock_init(&adapter->req_q.lock); INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); /* mark adapter unusable as long as sysfs registration is not complete */ @@ -723,12 +710,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) zfcp_reqlist_free(adapter); failed_low_mem_buffers: zfcp_free_low_mem_buffers(adapter); - if (qdio_free(ccw_device) != 0) - ZFCP_LOG_NORMAL("bug: qdio_free for adapter %s failed\n", - zfcp_get_busid_by_adapter(adapter)); qdio_allocate_failed: - zfcp_qdio_free_queues(adapter); - queues_alloc_failed: + zfcp_qdio_free(adapter); kfree(adapter); adapter = NULL; out: @@ -757,10 +740,6 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) retval = zfcp_reqlist_isempty(adapter); spin_unlock_irqrestore(&adapter->req_list_lock, flags); if (!retval) { - ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, " - "%i requests outstanding\n", - zfcp_get_busid_by_adapter(adapter), adapter, - atomic_read(&adapter->reqs_active)); retval = -EBUSY; goto out; } @@ -775,19 +754,9 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) /* decrease number of adapters in list */ zfcp_data.adapters--; - ZFCP_LOG_TRACE("adapter %s (%p) removed from list, " - "%i adapters still in list\n", - zfcp_get_busid_by_adapter(adapter), - adapter, zfcp_data.adapters); - - retval = qdio_free(adapter->ccw_device); - if (retval) - ZFCP_LOG_NORMAL("bug: qdio_free for adapter %s failed\n", - zfcp_get_busid_by_adapter(adapter)); + zfcp_qdio_free(adapter); zfcp_free_low_mem_buffers(adapter); - /* free memory of adapter data structure and queues */ - zfcp_qdio_free_queues(adapter); zfcp_reqlist_free(adapter); kfree(adapter->fc_stats); kfree(adapter->stats_reset_data); diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 01e817a..c47c23a 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -603,13 +603,14 @@ static const char *zfcp_rec_dbf_ids[] = { [137] = "hbaapi port open", [138] = "hbaapi unit open", [139] = "hbaapi unit shutdown", - [140] = "qdio error", + [140] = "qdio error outbound", [141] = "scsi host reset", [142] = "dismissing fsf request for recovery action", [143] = "recovery action timed out", [144] = "recovery action gone", [145] = "recovery action being processed", [146] = "recovery action ready for next step", + [147] = "qdio error inbound", }; static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view, diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 72f2258..5fcb555 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -112,21 +112,10 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) /* max. number of (data buffer) SBALEs in largest SBAL chain multiplied with number of sectors per 4k block */ -/* FIXME(tune): free space should be one max. SBAL chain plus what? */ -#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ - - (ZFCP_MAX_SBALS_PER_REQ + 4)) - #define ZFCP_SBAL_TIMEOUT (5*HZ) #define ZFCP_TYPE2_RECOVERY_TIME 8 /* seconds */ -/* queue polling (values in microseconds) */ -#define ZFCP_MAX_INPUT_THRESHOLD 5000 /* FIXME: tune */ -#define ZFCP_MAX_OUTPUT_THRESHOLD 1000 /* FIXME: tune */ -#define ZFCP_MIN_INPUT_THRESHOLD 1 /* ignored by QDIO layer */ -#define ZFCP_MIN_OUTPUT_THRESHOLD 1 /* ignored by QDIO layer */ - -#define QDIO_SCSI_QFMT 1 /* 1 for FSF */ #define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) /********************* FSF SPECIFIC DEFINES *********************************/ @@ -649,13 +638,13 @@ struct zfcp_send_els { }; struct zfcp_qdio_queue { - struct qdio_buffer *buffer[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */ - u8 free_index; /* index of next free bfr + struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */ + u8 first; /* index of next free bfr in queue (free_count>0) */ - atomic_t free_count; /* number of free buffers + atomic_t count; /* number of free buffers in queue */ - rwlock_t queue_lock; /* lock for operations on queue */ - int distance_from_int; /* SBALs used since PCI indication + rwlock_t lock; /* lock for operations on queue */ + int pci_batch; /* SBALs since PCI indication was last set */ }; @@ -711,15 +700,14 @@ struct zfcp_adapter { struct list_head port_remove_lh; /* head of ports to be removed */ u32 ports; /* number of remote ports */ - atomic_t reqs_active; /* # active FSF reqs */ unsigned long req_no; /* unique FSF req number */ struct list_head *req_list; /* list of pending reqs */ spinlock_t req_list_lock; /* request list lock */ - struct zfcp_qdio_queue request_queue; /* request queue */ + struct zfcp_qdio_queue req_q; /* request queue */ u32 fsf_req_seq_no; /* FSF cmnd seq number */ wait_queue_head_t request_wq; /* can be used to wait for more avaliable SBALs */ - struct zfcp_qdio_queue response_queue; /* response queue */ + struct zfcp_qdio_queue resp_q; /* response queue */ rwlock_t abort_lock; /* Protects against SCSI stack abort/command completion races */ diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index ee19be1..4a6d083 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -114,41 +114,6 @@ static void zfcp_erp_action_to_running(struct zfcp_erp_action *); static void zfcp_erp_memwait_handler(unsigned long); /** - * zfcp_close_qdio - close qdio queues for an adapter - */ -static void zfcp_close_qdio(struct zfcp_adapter *adapter) -{ - struct zfcp_qdio_queue *req_queue; - int first, count; - - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) - return; - - /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ - req_queue = &adapter->request_queue; - write_lock_irq(&req_queue->queue_lock); - atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); - write_unlock_irq(&req_queue->queue_lock); - - while (qdio_shutdown(adapter->ccw_device, - QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) - ssleep(1); - - /* cleanup used outbound sbals */ - count = atomic_read(&req_queue->free_count); - if (count < QDIO_MAX_BUFFERS_PER_Q) { - first = (req_queue->free_index+count) % QDIO_MAX_BUFFERS_PER_Q; - count = QDIO_MAX_BUFFERS_PER_Q - count; - zfcp_qdio_zero_sbals(req_queue->buffer, first, count); - } - req_queue->free_index = 0; - atomic_set(&req_queue->free_count, 0); - req_queue->distance_from_int = 0; - adapter->response_queue.free_index = 0; - atomic_set(&adapter->response_queue.free_count, 0); -} - -/** * zfcp_close_fsf - stop FSF operations for an adapter * * Dismiss and cleanup all pending fsf_reqs (this wakes up all initiators of @@ -158,7 +123,7 @@ static void zfcp_close_qdio(struct zfcp_adapter *adapter) static void zfcp_close_fsf(struct zfcp_adapter *adapter) { /* close queues to ensure that buffers are not accessed by adapter */ - zfcp_close_qdio(adapter); + zfcp_qdio_close(adapter); zfcp_fsf_req_dismiss_all(adapter); /* reset FSF request sequence number */ adapter->fsf_req_seq_no = 0; @@ -1735,88 +1700,17 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close) static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) { - int retval; - int i; - volatile struct qdio_buffer_element *sbale; struct zfcp_adapter *adapter = erp_action->adapter; - if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) { - ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on " - "adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - goto failed_sanity; - } - - if (qdio_establish(&adapter->qdio_init_data) != 0) { - ZFCP_LOG_INFO("error: establishment of QDIO queues failed " - "on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - goto failed_qdio_establish; - } - - if (qdio_activate(adapter->ccw_device, 0) != 0) { - ZFCP_LOG_INFO("error: activation of QDIO queues failed " - "on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - goto failed_qdio_activate; - } - - /* - * put buffers into response queue, - */ - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) { - sbale = &(adapter->response_queue.buffer[i]->element[0]); - sbale->length = 0; - sbale->flags = SBAL_FLAGS_LAST_ENTRY; - sbale->addr = NULL; - } - - ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, " - "queue_no=%i, index_in_queue=%i, count=%i)\n", - zfcp_get_busid_by_adapter(adapter), - QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q); - - retval = do_QDIO(adapter->ccw_device, - QDIO_FLAG_SYNC_INPUT, - 0, 0, QDIO_MAX_BUFFERS_PER_Q, NULL); - - if (retval) { - ZFCP_LOG_NORMAL("bug: setup of QDIO failed (retval=%d)\n", - retval); - goto failed_do_qdio; - } else { - adapter->response_queue.free_index = 0; - atomic_set(&adapter->response_queue.free_count, 0); - ZFCP_LOG_DEBUG("%i buffers successfully enqueued to " - "response queue\n", QDIO_MAX_BUFFERS_PER_Q); - } - /* set index of first avalable SBALS / number of available SBALS */ - adapter->request_queue.free_index = 0; - atomic_set(&adapter->request_queue.free_count, QDIO_MAX_BUFFERS_PER_Q); - adapter->request_queue.distance_from_int = 0; + if (zfcp_qdio_open(adapter)) + return ZFCP_ERP_FAILED; /* initialize waitqueue used to wait for free SBALs in requests queue */ init_waitqueue_head(&adapter->request_wq); /* ok, we did it - skip all cleanups for different failures */ atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); - retval = ZFCP_ERP_SUCCEEDED; - goto out; - - failed_do_qdio: - /* NOP */ - - failed_qdio_activate: - while (qdio_shutdown(adapter->ccw_device, - QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) - ssleep(1); - - failed_qdio_establish: - failed_sanity: - retval = ZFCP_ERP_FAILED; - - out: - return retval; + return ZFCP_ERP_SUCCEEDED; } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 8679728..6ffe206 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -57,21 +57,17 @@ extern int zfcp_ccw_register(void); extern void zfcp_qdio_zero_sbals(struct qdio_buffer **, int, int); extern int zfcp_qdio_allocate(struct zfcp_adapter *); -extern int zfcp_qdio_allocate_queues(struct zfcp_adapter *); -extern void zfcp_qdio_free_queues(struct zfcp_adapter *); -extern int zfcp_qdio_determine_pci(struct zfcp_qdio_queue *, - struct zfcp_fsf_req *); +extern void zfcp_qdio_free(struct zfcp_adapter *); +extern int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req); extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req - (struct zfcp_fsf_req *, int, int); + (struct zfcp_fsf_req *); extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_curr (struct zfcp_fsf_req *); extern int zfcp_qdio_sbals_from_sg - (struct zfcp_fsf_req *, unsigned long, struct scatterlist *, int, int); -extern int zfcp_qdio_sbals_from_scsicmnd - (struct zfcp_fsf_req *, unsigned long, struct scsi_cmnd *); - - + (struct zfcp_fsf_req *, unsigned long, struct scatterlist *, int); +extern int zfcp_qdio_open(struct zfcp_adapter *adapter); +extern void zfcp_qdio_close(struct zfcp_adapter *adapter); /******************************** FSF ****************************************/ extern int zfcp_fsf_open_port(struct zfcp_erp_action *); extern int zfcp_fsf_close_port(struct zfcp_erp_action *); @@ -95,7 +91,7 @@ extern int zfcp_fsf_status_read(struct zfcp_adapter *, int); extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *, unsigned long *, struct zfcp_fsf_req **) - __acquires(adapter->request_queue.queue_lock); + __acquires(adapter->req_q.lock); extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, struct zfcp_erp_action *); extern int zfcp_fsf_send_els(struct zfcp_send_els *); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index de42a01..cc48a64 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -171,7 +171,6 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)); spin_lock_irqsave(&adapter->req_list_lock, flags); - atomic_set(&adapter->reqs_active, 0); for (i = 0; i < REQUEST_LIST_SIZE; i++) list_splice_init(&adapter->req_list[i], &remove_queue); spin_unlock_irqrestore(&adapter->req_list_lock, flags); @@ -726,7 +725,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) goto failed_req_create; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS; sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; fsf_req->sbale_curr = 2; @@ -763,7 +762,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) failed_req_create: zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); out: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } @@ -1075,7 +1074,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, &unit->status))) goto unit_blocked; - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -1098,7 +1097,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, fsf_req = NULL; out: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return fsf_req; } @@ -1295,7 +1294,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, goto failed_req; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); if (zfcp_use_one_sbal(ct->req, ct->req_count, ct->resp, ct->resp_count)){ /* both request buffer and response buffer @@ -1311,7 +1310,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, /* try to use chained SBALs */ bytes = zfcp_qdio_sbals_from_sg(fsf_req, SBAL_FLAGS0_TYPE_WRITE_READ, - ct->req, ct->req_count, + ct->req, ZFCP_MAX_SBALS_PER_CT_REQ); if (bytes <= 0) { ZFCP_LOG_INFO("error: creation of CT request failed " @@ -1328,7 +1327,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, fsf_req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; bytes = zfcp_qdio_sbals_from_sg(fsf_req, SBAL_FLAGS0_TYPE_WRITE_READ, - ct->resp, ct->resp_count, + ct->resp, ZFCP_MAX_SBALS_PER_CT_REQ); if (bytes <= 0) { ZFCP_LOG_INFO("error: creation of CT request failed " @@ -1387,8 +1386,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, } failed_req: out: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return ret; } @@ -1593,7 +1591,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) goto port_blocked; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); if (zfcp_use_one_sbal(els->req, els->req_count, els->resp, els->resp_count)){ /* both request buffer and response buffer @@ -1609,7 +1607,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) /* try to use chained SBALs */ bytes = zfcp_qdio_sbals_from_sg(fsf_req, SBAL_FLAGS0_TYPE_WRITE_READ, - els->req, els->req_count, + els->req, ZFCP_MAX_SBALS_PER_ELS_REQ); if (bytes <= 0) { ZFCP_LOG_INFO("error: creation of ELS request failed " @@ -1626,7 +1624,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) fsf_req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; bytes = zfcp_qdio_sbals_from_sg(fsf_req, SBAL_FLAGS0_TYPE_WRITE_READ, - els->resp, els->resp_count, + els->resp, ZFCP_MAX_SBALS_PER_ELS_REQ); if (bytes <= 0) { ZFCP_LOG_INFO("error: creation of ELS request failed " @@ -1657,7 +1655,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT; fsf_req->data = (unsigned long) els; - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); zfcp_san_dbf_event_els_request(fsf_req); @@ -1680,8 +1678,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) failed_req: out: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return ret; } @@ -1863,12 +1860,11 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ZFCP_LOG_INFO("error: Could not create exchange configuration " "data request for adapter %s.\n", zfcp_get_busid_by_adapter(adapter)); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -1882,8 +1878,7 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); if (retval) { ZFCP_LOG_INFO("error: Could not send exchange configuration " "data command on the adapter %s\n", @@ -1916,12 +1911,11 @@ zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, ZFCP_LOG_INFO("error: Could not create exchange configuration " "data request for adapter %s.\n", zfcp_get_busid_by_adapter(adapter)); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -1936,8 +1930,7 @@ zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); if (retval) ZFCP_LOG_INFO("error: Could not send exchange configuration " "data command on the adapter %s\n", @@ -2178,12 +2171,11 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) "exchange port data request for " "the adapter %s.\n", zfcp_get_busid_by_adapter(adapter)); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -2192,7 +2184,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); if (retval) { ZFCP_LOG_INFO("error: Could not send an exchange port data " @@ -2237,21 +2229,20 @@ zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, "exchange port data request for " "the adapter %s.\n", zfcp_get_busid_by_adapter(adapter)); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } if (data) fsf_req->data = (unsigned long) data; - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); if (retval) ZFCP_LOG_INFO("error: Could not send an exchange port data " @@ -2355,7 +2346,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -2382,8 +2373,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) zfcp_get_busid_by_adapter(erp_action->adapter), erp_action->port->wwpn); out: - write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; } @@ -2587,7 +2577,7 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -2615,8 +2605,7 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) zfcp_get_busid_by_adapter(erp_action->adapter), erp_action->port->wwpn); out: - write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; } @@ -2716,7 +2705,7 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -2746,8 +2735,7 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) zfcp_get_busid_by_adapter(erp_action->adapter), erp_action->port->wwpn); out: - write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; } @@ -2911,7 +2899,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -2944,8 +2932,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) zfcp_get_busid_by_adapter(erp_action->adapter), erp_action->port->wwpn, erp_action->unit->fcp_lun); out: - write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; } @@ -3226,7 +3213,7 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -3255,8 +3242,7 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) zfcp_get_busid_by_adapter(erp_action->adapter), erp_action->port->wwpn, erp_action->unit->fcp_lun); out: - write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, - lock_flags); + write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; } @@ -3498,7 +3484,9 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, fcp_cmnd_iu->add_fcp_cdb_length + sizeof (fcp_dl_t); /* generate SBALEs from data buffer */ - real_bytes = zfcp_qdio_sbals_from_scsicmnd(fsf_req, sbtype, scsi_cmnd); + real_bytes = zfcp_qdio_sbals_from_sg(fsf_req, sbtype, + scsi_sglist(scsi_cmnd), + ZFCP_MAX_SBALS_PER_REQ); if (unlikely(real_bytes < 0)) { if (fsf_req->sbal_number < ZFCP_MAX_SBALS_PER_REQ) { ZFCP_LOG_DEBUG( @@ -3556,7 +3544,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, scsi_cmnd->host_scribble = NULL; success: failed_req_create: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } @@ -3609,7 +3597,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, fsf_req->qtcb->bottom.io.fcp_cmnd_length = sizeof (struct fcp_cmnd_iu) + sizeof (fcp_dl_t); - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; @@ -3629,7 +3617,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, fsf_req = NULL; out: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return fsf_req; } @@ -4216,7 +4204,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, goto unlock_queue_lock; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= direction; bottom = &fsf_req->qtcb->bottom.support; @@ -4224,7 +4212,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, bottom->option = fsf_cfdc->option; bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction, - fsf_cfdc->sg, ZFCP_CFDC_PAGES, + fsf_cfdc->sg, ZFCP_MAX_SBALS_PER_REQ); if (bytes != ZFCP_CFDC_MAX_SIZE) { retval = -ENOMEM; @@ -4237,7 +4225,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, retval = -EPERM; goto free_fsf_req; } - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); wait_event(fsf_req->completion_wq, fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); @@ -4247,7 +4235,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, free_fsf_req: zfcp_fsf_req_free(fsf_req); unlock_queue_lock: - write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); + write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return ERR_PTR(retval); } @@ -4261,10 +4249,10 @@ static inline int zfcp_fsf_req_sbal_check(unsigned long *flags, struct zfcp_qdio_queue *queue, int needed) { - write_lock_irqsave(&queue->queue_lock, *flags); - if (likely(atomic_read(&queue->free_count) >= needed)) + write_lock_irqsave(&queue->lock, *flags); + if (likely(atomic_read(&queue->count) >= needed)) return 1; - write_unlock_irqrestore(&queue->queue_lock, *flags); + write_unlock_irqrestore(&queue->lock, *flags); return 0; } @@ -4293,24 +4281,24 @@ zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) * @req_flags: flags indicating whether to wait for needed SBAL or not * @lock_flags: lock_flags if queue_lock is taken * Return: 0 on success, otherwise -EIO, or -ERESTARTSYS - * Locks: lock adapter->request_queue->queue_lock on success + * Locks: lock adapter->req_q->lock on success */ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter, int req_flags, unsigned long *lock_flags) { long ret; - struct zfcp_qdio_queue *req_queue = &adapter->request_queue; + struct zfcp_qdio_queue *req_q = &adapter->req_q; if (unlikely(req_flags & ZFCP_WAIT_FOR_SBAL)) { ret = wait_event_interruptible_timeout(adapter->request_wq, - zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1), + zfcp_fsf_req_sbal_check(lock_flags, req_q, 1), ZFCP_SBAL_TIMEOUT); if (ret < 0) return ret; if (!ret) return -EIO; - } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1)) + } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_q, 1)) return -EIO; return 0; @@ -4340,7 +4328,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, volatile struct qdio_buffer_element *sbale; struct zfcp_fsf_req *fsf_req = NULL; int ret = 0; - struct zfcp_qdio_queue *req_queue = &adapter->request_queue; + struct zfcp_qdio_queue *req_q = &adapter->req_q; /* allocate new FSF request */ fsf_req = zfcp_fsf_req_alloc(pool, req_flags); @@ -4377,7 +4365,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, */ if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) { - write_unlock_irqrestore(&req_queue->queue_lock, *lock_flags); + write_unlock_irqrestore(&req_q->lock, *lock_flags); ret = -EIO; goto failed_sbals; } @@ -4387,15 +4375,15 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; } fsf_req->sbal_number = 1; - fsf_req->sbal_first = req_queue->free_index; - fsf_req->sbal_last = req_queue->free_index; + fsf_req->sbal_first = req_q->first; + fsf_req->sbal_last = req_q->first; fsf_req->sbale_curr = 1; if (likely(req_flags & ZFCP_REQ_AUTO_CLEANUP)) { fsf_req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; } - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); /* setup common SBALE fields */ sbale[0].addr = (void *) fsf_req->req_id; @@ -4416,7 +4404,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, fsf_req = NULL; failed_fsf_req: - write_lock_irqsave(&req_queue->queue_lock, *lock_flags); + write_lock_irqsave(&req_q->lock, *lock_flags); success: *fsf_req_p = fsf_req; return ret; @@ -4433,18 +4421,17 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) { struct zfcp_adapter *adapter; - struct zfcp_qdio_queue *req_queue; + struct zfcp_qdio_queue *req_q; volatile struct qdio_buffer_element *sbale; int inc_seq_no; - int new_distance_from_int; int retval = 0; adapter = fsf_req->adapter; - req_queue = &adapter->request_queue, + req_q = &adapter->req_q; /* FIXME(debug): remove it later */ - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_first, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); ZFCP_LOG_DEBUG("SBALE0 flags=0x%x\n", sbale[0].flags); ZFCP_LOG_TRACE("HEX DUMP OF SBALE1 PAYLOAD:\n"); ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, @@ -4457,52 +4444,24 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) inc_seq_no = (fsf_req->qtcb != NULL); - ZFCP_LOG_TRACE("request queue of adapter %s: " - "next free SBAL is %i, %i free SBALs\n", - zfcp_get_busid_by_adapter(adapter), - req_queue->free_index, - atomic_read(&req_queue->free_count)); - - ZFCP_LOG_DEBUG("calling do_QDIO adapter %s, flags=0x%x, queue_no=%i, " - "index_in_queue=%i, count=%i, buffers=%p\n", - zfcp_get_busid_by_adapter(adapter), - QDIO_FLAG_SYNC_OUTPUT, - 0, fsf_req->sbal_first, fsf_req->sbal_number, - &req_queue->buffer[fsf_req->sbal_first]); - - /* - * adjust the number of free SBALs in request queue as well as - * position of first one - */ - atomic_sub(fsf_req->sbal_number, &req_queue->free_count); - ZFCP_LOG_TRACE("free_count=%d\n", atomic_read(&req_queue->free_count)); - req_queue->free_index += fsf_req->sbal_number; /* increase */ - req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */ - new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req); - fsf_req->issued = get_clock(); - retval = do_QDIO(adapter->ccw_device, - QDIO_FLAG_SYNC_OUTPUT, - 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); + retval = zfcp_qdio_send(fsf_req); if (unlikely(retval)) { /* Queues are down..... */ - retval = -EIO; del_timer(&fsf_req->timer); spin_lock(&adapter->req_list_lock); zfcp_reqlist_remove(adapter, fsf_req); spin_unlock(&adapter->req_list_lock); /* undo changes in request queue made for this request */ - zfcp_qdio_zero_sbals(req_queue->buffer, - fsf_req->sbal_first, fsf_req->sbal_number); - atomic_add(fsf_req->sbal_number, &req_queue->free_count); - req_queue->free_index -= fsf_req->sbal_number; - req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q; - req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ + atomic_add(fsf_req->sbal_number, &req_q->count); + req_q->first -= fsf_req->sbal_number; + req_q->first += QDIO_MAX_BUFFERS_PER_Q; + req_q->first %= QDIO_MAX_BUFFERS_PER_Q; zfcp_erp_adapter_reopen(adapter, 0, 116, fsf_req); + retval = -EIO; } else { - req_queue->distance_from_int = new_distance_from_int; /* * increase FSF sequence counter - * this must only be done for request successfully enqueued to @@ -4514,9 +4473,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) /* Don't increase for unsolicited status */ if (inc_seq_no) adapter->fsf_req_seq_no++; - - /* count FSF requests pending */ - atomic_inc(&adapter->reqs_active); } return retval; } diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index e715473..bd6561d 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -1,241 +1,92 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Setup and helper functions to access QDIO. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #include "zfcp_ext.h" -static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int); -static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_get - (struct zfcp_qdio_queue *, int, int); -static inline volatile struct qdio_buffer_element *zfcp_qdio_sbale_resp - (struct zfcp_fsf_req *, int, int); -static volatile struct qdio_buffer_element *zfcp_qdio_sbal_chain - (struct zfcp_fsf_req *, unsigned long); -static volatile struct qdio_buffer_element *zfcp_qdio_sbale_next - (struct zfcp_fsf_req *, unsigned long); -static int zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *, int, int); -static inline int zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *); -static void zfcp_qdio_sbale_fill - (struct zfcp_fsf_req *, unsigned long, void *, int); -static int zfcp_qdio_sbals_from_segment - (struct zfcp_fsf_req *, unsigned long, void *, unsigned long); - -static qdio_handler_t zfcp_qdio_request_handler; -static qdio_handler_t zfcp_qdio_response_handler; -static int zfcp_qdio_handler_error_check(struct zfcp_adapter *, - unsigned int, unsigned int, unsigned int, int, int); - -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO +/* FIXME(tune): free space should be one max. SBAL chain plus what? */ +#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ + - (ZFCP_MAX_SBALS_PER_REQ + 4)) -/* - * Frees BUFFER memory for each of the pointers of the struct qdio_buffer array - * in the adapter struct sbuf is the pointer array. - * - * locks: must only be called with zfcp_data.config_sema taken - */ -static void -zfcp_qdio_buffers_dequeue(struct qdio_buffer **sbuf) -{ - int pos; - - for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) - free_page((unsigned long) sbuf[pos]); -} - -/* - * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t - * array in the adapter struct. - * Cur_buf is the pointer array - * - * returns: zero on success else -ENOMEM - * locks: must only be called with zfcp_data.config_sema taken - */ -static int -zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbuf) +static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) { int pos; for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) { - sbuf[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL); - if (!sbuf[pos]) { - zfcp_qdio_buffers_dequeue(sbuf); + sbal[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL); + if (!sbal[pos]) return -ENOMEM; - } } for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos++) if (pos % QBUFF_PER_PAGE) - sbuf[pos] = sbuf[pos - 1] + 1; + sbal[pos] = sbal[pos - 1] + 1; return 0; } -/* locks: must only be called with zfcp_data.config_sema taken */ -int -zfcp_qdio_allocate_queues(struct zfcp_adapter *adapter) +static volatile struct qdio_buffer_element * +zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx) { - int ret; - - ret = zfcp_qdio_buffers_enqueue(adapter->request_queue.buffer); - if (ret) - return ret; - return zfcp_qdio_buffers_enqueue(adapter->response_queue.buffer); + return &q->sbal[sbal_idx]->element[sbale_idx]; } -/* locks: must only be called with zfcp_data.config_sema taken */ -void -zfcp_qdio_free_queues(struct zfcp_adapter *adapter) +/** + * zfcp_qdio_free - free memory used by request- and resposne queue + * @adapter: pointer to the zfcp_adapter structure + */ +void zfcp_qdio_free(struct zfcp_adapter *adapter) { - ZFCP_LOG_TRACE("freeing request_queue buffers\n"); - zfcp_qdio_buffers_dequeue(adapter->request_queue.buffer); - - ZFCP_LOG_TRACE("freeing response_queue buffers\n"); - zfcp_qdio_buffers_dequeue(adapter->response_queue.buffer); -} + struct qdio_buffer **sbal_req, **sbal_resp; + int p; -int -zfcp_qdio_allocate(struct zfcp_adapter *adapter) -{ - struct qdio_initialize *init_data; + if (adapter->ccw_device) + qdio_free(adapter->ccw_device); - init_data = &adapter->qdio_init_data; + sbal_req = adapter->req_q.sbal; + sbal_resp = adapter->resp_q.sbal; - init_data->cdev = adapter->ccw_device; - init_data->q_format = QDIO_SCSI_QFMT; - memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8); - ASCEBC(init_data->adapter_name, 8); - init_data->qib_param_field_format = 0; - init_data->qib_param_field = NULL; - init_data->input_slib_elements = NULL; - init_data->output_slib_elements = NULL; - init_data->min_input_threshold = ZFCP_MIN_INPUT_THRESHOLD; - init_data->max_input_threshold = ZFCP_MAX_INPUT_THRESHOLD; - init_data->min_output_threshold = ZFCP_MIN_OUTPUT_THRESHOLD; - init_data->max_output_threshold = ZFCP_MAX_OUTPUT_THRESHOLD; - init_data->no_input_qs = 1; - init_data->no_output_qs = 1; - init_data->input_handler = zfcp_qdio_response_handler; - init_data->output_handler = zfcp_qdio_request_handler; - init_data->int_parm = (unsigned long) adapter; - init_data->flags = QDIO_INBOUND_0COPY_SBALS | - QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS; - init_data->input_sbal_addr_array = - (void **) (adapter->response_queue.buffer); - init_data->output_sbal_addr_array = - (void **) (adapter->request_queue.buffer); - - return qdio_allocate(init_data); + for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) { + free_page((unsigned long) sbal_req[p]); + free_page((unsigned long) sbal_resp[p]); + } } -/* - * function: zfcp_qdio_handler_error_check - * - * purpose: called by the response handler to determine error condition - * - * returns: error flag - * - */ -static int -zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, - unsigned int qdio_error, unsigned int siga_error, - int first_element, int elements_processed) +static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id) { - int retval = 0; + dev_warn(&adapter->ccw_device->dev, "QDIO problem occurred.\n"); - if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { - retval = -EIO; - - ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, " - "qdio_error=0x%x, siga_error=0x%x)\n", - status, qdio_error, siga_error); - - zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error, - first_element, elements_processed); - /* - * Restarting IO on the failed adapter from scratch. - * Since we have been using this adapter, it is save to assume - * that it is not failed but recoverable. The card seems to - * report link-up events by self-initiated queue shutdown. - * That is why we need to clear the link-down flag - * which is set again in case we have missed by a mile. - */ - zfcp_erp_adapter_reopen(adapter, - ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | - ZFCP_STATUS_COMMON_ERP_FAILED, 140, - NULL); - } - return retval; + zfcp_erp_adapter_reopen(adapter, + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | + ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL); } -/* - * function: zfcp_qdio_request_handler - * - * purpose: is called by QDIO layer for completed SBALs in request queue - * - * returns: (void) - */ -static void -zfcp_qdio_request_handler(struct ccw_device *ccw_device, - unsigned int status, - unsigned int qdio_error, - unsigned int siga_error, - unsigned int queue_number, - int first_element, - int elements_processed, - unsigned long int_parm) +static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int status, + unsigned int qdio_err, unsigned int siga_err, + unsigned int queue_no, int first, int count, + unsigned long parm) { - struct zfcp_adapter *adapter; - struct zfcp_qdio_queue *queue; - - adapter = (struct zfcp_adapter *) int_parm; - queue = &adapter->request_queue; + struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; + struct zfcp_qdio_queue *queue = &adapter->req_q; - ZFCP_LOG_DEBUG("adapter %s, first=%d, elements_processed=%d\n", - zfcp_get_busid_by_adapter(adapter), - first_element, elements_processed); - - if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error, - siga_error, first_element, - elements_processed))) - goto out; - /* - * we stored address of struct zfcp_adapter data structure - * associated with irq in int_parm - */ + if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { + zfcp_hba_dbf_event_qdio(adapter, status, qdio_err, siga_err, + first, count); + zfcp_qdio_handler_error(adapter, 140); + return; + } /* cleanup all SBALs being program-owned now */ - zfcp_qdio_zero_sbals(queue->buffer, first_element, elements_processed); + zfcp_qdio_zero_sbals(queue->sbal, first, count); - /* increase free space in outbound queue */ - atomic_add(elements_processed, &queue->free_count); - ZFCP_LOG_DEBUG("free_count=%d\n", atomic_read(&queue->free_count)); + atomic_add(count, &queue->count); wake_up(&adapter->request_wq); - ZFCP_LOG_DEBUG("elements_processed=%d, free count=%d\n", - elements_processed, atomic_read(&queue->free_count)); - out: - return; } -/** - * zfcp_qdio_reqid_check - checks for valid reqids. - */ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, - unsigned long req_id, int sbal) + unsigned long req_id, int sbal_idx) { struct zfcp_fsf_req *fsf_req; unsigned long flags; @@ -248,204 +99,117 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, * Unknown request means that we have potentially memory * corruption and must stop the machine immediatly. */ - panic("error: unknown request id (%ld) on adapter %s.\n", + panic("error: unknown request id (%lx) on adapter %s.\n", req_id, zfcp_get_busid_by_adapter(adapter)); zfcp_reqlist_remove(adapter, fsf_req); - atomic_dec(&adapter->reqs_active); spin_unlock_irqrestore(&adapter->req_list_lock, flags); - fsf_req->sbal_response = sbal; - /* finish the FSF request */ + fsf_req->sbal_response = sbal_idx; zfcp_fsf_req_complete(fsf_req); } -/* - * function: zfcp_qdio_response_handler - * - * purpose: is called by QDIO layer for completed SBALs in response queue - * - * returns: (void) - */ -static void -zfcp_qdio_response_handler(struct ccw_device *ccw_device, - unsigned int status, - unsigned int qdio_error, - unsigned int siga_error, - unsigned int queue_number, - int first_element, - int elements_processed, - unsigned long int_parm) +static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed) { - struct zfcp_adapter *adapter; - struct zfcp_qdio_queue *queue; - int buffer_index; - int i; - struct qdio_buffer *buffer; - int retval = 0; - u8 count; - u8 start; - volatile struct qdio_buffer_element *buffere = NULL; - int buffere_index; - - adapter = (struct zfcp_adapter *) int_parm; - queue = &adapter->response_queue; - - if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error, - siga_error, first_element, - elements_processed))) - goto out; + struct zfcp_qdio_queue *queue = &adapter->resp_q; + struct ccw_device *cdev = adapter->ccw_device; + u8 count, start = queue->first; + unsigned int retval; - /* - * we stored address of struct zfcp_adapter data structure - * associated with irq in int_parm - */ + count = atomic_read(&queue->count) + processed; + + retval = do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, + 0, start, count, NULL); + + if (unlikely(retval)) { + atomic_set(&queue->count, count); + /* FIXME: Recover this with an adapter reopen? */ + } else { + queue->first += count; + queue->first %= QDIO_MAX_BUFFERS_PER_Q; + atomic_set(&queue->count, 0); + } +} + +static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int status, + unsigned int qdio_err, unsigned int siga_err, + unsigned int queue_no, int first, int count, + unsigned long parm) +{ + struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; + struct zfcp_qdio_queue *queue = &adapter->resp_q; + volatile struct qdio_buffer_element *sbale; + int sbal_idx, sbale_idx, sbal_no; + + if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { + zfcp_hba_dbf_event_qdio(adapter, status, qdio_err, siga_err, + first, count); + zfcp_qdio_handler_error(adapter, 147); + return; + } - buffere = &(queue->buffer[first_element]->element[0]); - ZFCP_LOG_DEBUG("first BUFFERE flags=0x%x\n", buffere->flags); /* * go through all SBALs from input queue currently * returned by QDIO layer */ - - for (i = 0; i < elements_processed; i++) { - - buffer_index = first_element + i; - buffer_index %= QDIO_MAX_BUFFERS_PER_Q; - buffer = queue->buffer[buffer_index]; + for (sbal_no = 0; sbal_no < count; sbal_no++) { + sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q; /* go through all SBALEs of SBAL */ - for (buffere_index = 0; - buffere_index < QDIO_MAX_ELEMENTS_PER_BUFFER; - buffere_index++) { - - /* look for QDIO request identifiers in SB */ - buffere = &buffer->element[buffere_index]; + for (sbale_idx = 0; sbale_idx < QDIO_MAX_ELEMENTS_PER_BUFFER; + sbale_idx++) { + sbale = zfcp_qdio_sbale(queue, sbal_idx, sbale_idx); zfcp_qdio_reqid_check(adapter, - (unsigned long) buffere->addr, i); - - /* - * A single used SBALE per inbound SBALE has been - * implemented by QDIO so far. Hope they will - * do some optimisation. Will need to change to - * unlikely() then. - */ - if (likely(buffere->flags & SBAL_FLAGS_LAST_ENTRY)) + (unsigned long) sbale->addr, + sbal_idx); + if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY)) break; }; - if (unlikely(!(buffere->flags & SBAL_FLAGS_LAST_ENTRY))) { - ZFCP_LOG_NORMAL("bug: End of inbound data " - "not marked!\n"); - } + if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY))) + dev_warn(&adapter->ccw_device->dev, + "Protocol violation by adapter. " + "Continuing operations.\n"); } /* * put range of SBALs back to response queue * (including SBALs which have already been free before) */ - count = atomic_read(&queue->free_count) + elements_processed; - start = queue->free_index; - - ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, " - "queue_no=%i, index_in_queue=%i, count=%i, " - "buffers=0x%lx\n", - zfcp_get_busid_by_adapter(adapter), - QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, - 0, start, count, (unsigned long) &queue->buffer[start]); - - retval = do_QDIO(ccw_device, - QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, - 0, start, count, NULL); - - if (unlikely(retval)) { - atomic_set(&queue->free_count, count); - ZFCP_LOG_DEBUG("clearing of inbound data regions failed, " - "queues may be down " - "(count=%d, start=%d, retval=%d)\n", - count, start, retval); - } else { - queue->free_index += count; - queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; - atomic_set(&queue->free_count, 0); - ZFCP_LOG_TRACE("%i buffers enqueued to response " - "queue at position %i\n", count, start); - } - out: - return; + zfcp_qdio_resp_put_back(adapter, count); } /** - * zfcp_qdio_sbale_get - return pointer to SBALE of qdio_queue - * @queue: queue from which SBALE should be returned - * @sbal: specifies number of SBAL in queue - * @sbale: specifes number of SBALE in SBAL - */ -static inline volatile struct qdio_buffer_element * -zfcp_qdio_sbale_get(struct zfcp_qdio_queue *queue, int sbal, int sbale) -{ - return &queue->buffer[sbal]->element[sbale]; -} - -/** - * zfcp_qdio_sbale_req - return pointer to SBALE of request_queue for - * a struct zfcp_fsf_req + * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req + * @fsf_req: pointer to struct fsf_req + * Returns: pointer to qdio_buffer_element (SBALE) structure */ volatile struct qdio_buffer_element * -zfcp_qdio_sbale_req(struct zfcp_fsf_req *fsf_req, int sbal, int sbale) -{ - return zfcp_qdio_sbale_get(&fsf_req->adapter->request_queue, - sbal, sbale); -} - -/** - * zfcp_qdio_sbale_resp - return pointer to SBALE of response_queue for - * a struct zfcp_fsf_req - */ -static inline volatile struct qdio_buffer_element * -zfcp_qdio_sbale_resp(struct zfcp_fsf_req *fsf_req, int sbal, int sbale) +zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) { - return zfcp_qdio_sbale_get(&fsf_req->adapter->response_queue, - sbal, sbale); + return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0); } /** - * zfcp_qdio_sbale_curr - return current SBALE on request_queue for - * a struct zfcp_fsf_req + * zfcp_qdio_sbale_curr - return curr SBALE on req_q for a struct zfcp_fsf_req + * @fsf_req: pointer to struct fsf_req + * Returns: pointer to qdio_buffer_element (SBALE) structure */ volatile struct qdio_buffer_element * -zfcp_qdio_sbale_curr(struct zfcp_fsf_req *fsf_req) +zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req) { - return zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, - fsf_req->sbale_curr); + return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, + req->sbale_curr); } -/** - * zfcp_qdio_sbal_limit - determine maximum number of SBALs that can be used - * on the request_queue for a struct zfcp_fsf_req - * @fsf_req: the number of the last SBAL that can be used is stored herein - * @max_sbals: used to pass an upper limit for the number of SBALs - * - * Note: We can assume at least one free SBAL in the request_queue when called. - */ -static void -zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals) +static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals) { - int count = atomic_read(&fsf_req->adapter->request_queue.free_count); + int count = atomic_read(&fsf_req->adapter->req_q.count); count = min(count, max_sbals); - fsf_req->sbal_limit = fsf_req->sbal_first; - fsf_req->sbal_limit += (count - 1); - fsf_req->sbal_limit %= QDIO_MAX_BUFFERS_PER_Q; + fsf_req->sbal_limit = (fsf_req->sbal_first + count - 1) + % QDIO_MAX_BUFFERS_PER_Q; } -/** - * zfcp_qdio_sbal_chain - chain SBALs if more than one SBAL is needed for a - * request - * @fsf_req: zfcp_fsf_req to be processed - * @sbtype: SBAL flags which have to be set in first SBALE of new SBAL - * - * This function changes sbal_last, sbale_curr, sbal_number of fsf_req. - */ static volatile struct qdio_buffer_element * zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) { @@ -460,7 +224,7 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) return NULL; /* set chaining flag in first SBALE of current SBAL */ - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + sbale = zfcp_qdio_sbale_req(fsf_req); sbale->flags |= SBAL_FLAGS0_MORE_SBALS; /* calculate index of next SBAL */ @@ -480,214 +244,271 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) return sbale; } -/** - * zfcp_qdio_sbale_next - switch to next SBALE, chain SBALs if needed - */ static volatile struct qdio_buffer_element * zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) { if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) return zfcp_qdio_sbal_chain(fsf_req, sbtype); - fsf_req->sbale_curr++; - return zfcp_qdio_sbale_curr(fsf_req); } -/** - * zfcp_qdio_sbals_zero - initialize SBALs between first and last in queue - * with zero from - */ -static int -zfcp_qdio_sbals_zero(struct zfcp_qdio_queue *queue, int first, int last) +static void zfcp_qdio_undo_sbals(struct zfcp_fsf_req *fsf_req) { - struct qdio_buffer **buf = queue->buffer; - int curr = first; - int count = 0; - - for(;;) { - curr %= QDIO_MAX_BUFFERS_PER_Q; - count++; - memset(buf[curr], 0, sizeof(struct qdio_buffer)); - if (curr == last) - break; - curr++; - } - return count; + struct qdio_buffer **sbal = fsf_req->adapter->req_q.sbal; + int first = fsf_req->sbal_first; + int last = fsf_req->sbal_last; + int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % + QDIO_MAX_BUFFERS_PER_Q + 1; + zfcp_qdio_zero_sbals(sbal, first, count); } - -/** - * zfcp_qdio_sbals_wipe - reset all changes in SBALs for an fsf_req - */ -static inline int -zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *fsf_req) -{ - return zfcp_qdio_sbals_zero(&fsf_req->adapter->request_queue, - fsf_req->sbal_first, fsf_req->sbal_last); -} - - -/** - * zfcp_qdio_sbale_fill - set address and length in current SBALE - * on request_queue - */ -static void -zfcp_qdio_sbale_fill(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, - void *addr, int length) +static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, + unsigned int sbtype, void *start_addr, + unsigned int total_length) { volatile struct qdio_buffer_element *sbale; - - sbale = zfcp_qdio_sbale_curr(fsf_req); - sbale->addr = addr; - sbale->length = length; -} - -/** - * zfcp_qdio_sbals_from_segment - map memory segment to SBALE(s) - * @fsf_req: request to be processed - * @sbtype: SBALE flags - * @start_addr: address of memory segment - * @total_length: length of memory segment - * - * Alignment and length of the segment determine how many SBALEs are needed - * for the memory segment. - */ -static int -zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, - void *start_addr, unsigned long total_length) -{ unsigned long remaining, length; void *addr; - /* split segment up heeding page boundaries */ + /* split segment up */ for (addr = start_addr, remaining = total_length; remaining > 0; addr += length, remaining -= length) { - /* get next free SBALE for new piece */ - if (NULL == zfcp_qdio_sbale_next(fsf_req, sbtype)) { - /* no SBALE left, clean up and leave */ - zfcp_qdio_sbals_wipe(fsf_req); + sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); + if (!sbale) { + zfcp_qdio_undo_sbals(fsf_req); return -EINVAL; } - /* calculate length of new piece */ + + /* new piece must not exceed next page boundary */ length = min(remaining, - (PAGE_SIZE - ((unsigned long) addr & + (PAGE_SIZE - ((unsigned long)addr & (PAGE_SIZE - 1)))); - /* fill current SBALE with calculated piece */ - zfcp_qdio_sbale_fill(fsf_req, sbtype, addr, length); + sbale->addr = addr; + sbale->length = length; } - return total_length; + return 0; } - /** * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list * @fsf_req: request to be processed * @sbtype: SBALE flags * @sg: scatter-gather list - * @sg_count: number of elements in scatter-gather list * @max_sbals: upper bound for number of SBALs to be used + * Returns: number of bytes, or error (negativ) */ -int -zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, - struct scatterlist *sgl, int sg_count, int max_sbals) +int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, + struct scatterlist *sg, int max_sbals) { - int sg_index; - struct scatterlist *sg_segment; - int retval; volatile struct qdio_buffer_element *sbale; - int bytes = 0; + int retval, bytes = 0; /* figure out last allowed SBAL */ zfcp_qdio_sbal_limit(fsf_req, max_sbals); - /* set storage-block type for current SBAL */ - sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_last, 0); + /* set storage-block type for this request */ + sbale = zfcp_qdio_sbale_req(fsf_req); sbale->flags |= sbtype; - /* process all segements of scatter-gather list */ - for_each_sg(sgl, sg_segment, sg_count, sg_index) { - retval = zfcp_qdio_sbals_from_segment( - fsf_req, - sbtype, - zfcp_sg_to_address(sg_segment), - sg_segment->length); - if (retval < 0) { - bytes = retval; - goto out; - } else - bytes += retval; + for (; sg; sg = sg_next(sg)) { + retval = zfcp_qdio_fill_sbals(fsf_req, sbtype, sg_virt(sg), + sg->length); + if (retval < 0) + return retval; + bytes += sg->length; } + /* assume that no other SBALEs are to follow in the same SBAL */ sbale = zfcp_qdio_sbale_curr(fsf_req); sbale->flags |= SBAL_FLAGS_LAST_ENTRY; -out: + return bytes; } - /** - * zfcp_qdio_sbals_from_scsicmnd - fill SBALs from scsi command - * @fsf_req: request to be processed - * @sbtype: SBALE flags - * @scsi_cmnd: either scatter-gather list or buffer contained herein is used - * to fill SBALs + * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO + * @fsf_req: pointer to struct zfcp_fsf_req + * Returns: 0 on success, error otherwise */ -int -zfcp_qdio_sbals_from_scsicmnd(struct zfcp_fsf_req *fsf_req, - unsigned long sbtype, struct scsi_cmnd *scsi_cmnd) +int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) { - return zfcp_qdio_sbals_from_sg(fsf_req, sbtype, scsi_sglist(scsi_cmnd), - scsi_sg_count(scsi_cmnd), - ZFCP_MAX_SBALS_PER_REQ); + struct zfcp_adapter *adapter = fsf_req->adapter; + struct zfcp_qdio_queue *req_q = &adapter->req_q; + int first = fsf_req->sbal_first; + int count = fsf_req->sbal_number; + int retval, pci, pci_batch; + volatile struct qdio_buffer_element *sbale; + + /* acknowledgements for transferred buffers */ + pci_batch = req_q->pci_batch + count; + if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) { + pci_batch %= ZFCP_QDIO_PCI_INTERVAL; + pci = first + count - (pci_batch + 1); + pci %= QDIO_MAX_BUFFERS_PER_Q; + sbale = zfcp_qdio_sbale(req_q, pci, 0); + sbale->flags |= SBAL_FLAGS0_PCI; + } + + retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first, + count, NULL); + if (unlikely(retval)) { + zfcp_qdio_zero_sbals(req_q->sbal, first, count); + return retval; + } + + /* account for transferred buffers */ + atomic_sub(count, &req_q->count); + req_q->first += count; + req_q->first %= QDIO_MAX_BUFFERS_PER_Q; + req_q->pci_batch = pci_batch; + return 0; } /** - * zfcp_qdio_determine_pci - set PCI flag in first SBALE on qdio queue if needed + * zfcp_qdio_zero_sbals - zero all sbals of the specified area and queue + * @buf: pointer to array of SBALS + * @first: integer specifying the SBAL number to start + * @count: integer specifying the number of SBALS to process */ -int -zfcp_qdio_determine_pci(struct zfcp_qdio_queue *req_queue, - struct zfcp_fsf_req *fsf_req) +void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int count) { - int new_distance_from_int; - int pci_pos; - volatile struct qdio_buffer_element *sbale; + int i, sbal_idx; - new_distance_from_int = req_queue->distance_from_int + - fsf_req->sbal_number; - - if (unlikely(new_distance_from_int >= ZFCP_QDIO_PCI_INTERVAL)) { - new_distance_from_int %= ZFCP_QDIO_PCI_INTERVAL; - pci_pos = fsf_req->sbal_first; - pci_pos += fsf_req->sbal_number; - pci_pos -= new_distance_from_int; - pci_pos -= 1; - pci_pos %= QDIO_MAX_BUFFERS_PER_Q; - sbale = zfcp_qdio_sbale_req(fsf_req, pci_pos, 0); - sbale->flags |= SBAL_FLAGS0_PCI; + for (i = first; i < first + count; i++) { + sbal_idx = i % QDIO_MAX_BUFFERS_PER_Q; + memset(sbal[sbal_idx], 0, sizeof(struct qdio_buffer)); } - return new_distance_from_int; } -/* - * function: zfcp_zero_sbals - * - * purpose: zeros specified range of SBALs - * - * returns: +/** + * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data + * @adapter: pointer to struct zfcp_adapter + * Returns: -ENOMEM on memory allocation error or return value from + * qdio_allocate + */ +int zfcp_qdio_allocate(struct zfcp_adapter *adapter) +{ + struct qdio_initialize *init_data; + + if (zfcp_qdio_buffers_enqueue(adapter->req_q.sbal) || + zfcp_qdio_buffers_enqueue(adapter->resp_q.sbal)) + return -ENOMEM; + + init_data = &adapter->qdio_init_data; + + init_data->cdev = adapter->ccw_device; + init_data->q_format = QDIO_ZFCP_QFMT; + memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8); + ASCEBC(init_data->adapter_name, 8); + init_data->qib_param_field_format = 0; + init_data->qib_param_field = NULL; + init_data->input_slib_elements = NULL; + init_data->output_slib_elements = NULL; + init_data->min_input_threshold = 1; + init_data->max_input_threshold = 5000; + init_data->min_output_threshold = 1; + init_data->max_output_threshold = 1000; + init_data->no_input_qs = 1; + init_data->no_output_qs = 1; + init_data->input_handler = zfcp_qdio_int_resp; + init_data->output_handler = zfcp_qdio_int_req; + init_data->int_parm = (unsigned long) adapter; + init_data->flags = QDIO_INBOUND_0COPY_SBALS | + QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS; + init_data->input_sbal_addr_array = + (void **) (adapter->resp_q.sbal); + init_data->output_sbal_addr_array = + (void **) (adapter->req_q.sbal); + + return qdio_allocate(init_data); +} + +/** + * zfcp_close_qdio - close qdio queues for an adapter */ -void -zfcp_qdio_zero_sbals(struct qdio_buffer *buf[], int first, int clean_count) +void zfcp_qdio_close(struct zfcp_adapter *adapter) { - int cur_pos; - int index; - - for (cur_pos = first; cur_pos < (first + clean_count); cur_pos++) { - index = cur_pos % QDIO_MAX_BUFFERS_PER_Q; - memset(buf[index], 0, sizeof (struct qdio_buffer)); - ZFCP_LOG_TRACE("zeroing BUFFER %d at address %p\n", - index, buf[index]); + struct zfcp_qdio_queue *req_q; + int first, count; + + if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) + return; + + /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ + req_q = &adapter->req_q; + write_lock_irq(&req_q->lock); + atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); + write_unlock_irq(&req_q->lock); + + while (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR) + == -EINPROGRESS) + ssleep(1); + + /* cleanup used outbound sbals */ + count = atomic_read(&req_q->count); + if (count < QDIO_MAX_BUFFERS_PER_Q) { + first = (req_q->first + count) % QDIO_MAX_BUFFERS_PER_Q; + count = QDIO_MAX_BUFFERS_PER_Q - count; + zfcp_qdio_zero_sbals(req_q->sbal, first, count); } + req_q->first = 0; + atomic_set(&req_q->count, 0); + req_q->pci_batch = 0; + adapter->resp_q.first = 0; + atomic_set(&adapter->resp_q.count, 0); } -#undef ZFCP_LOG_AREA +/** + * zfcp_qdio_open - prepare and initialize response queue + * @adapter: pointer to struct zfcp_adapter + * Returns: 0 on success, otherwise -EIO + */ +int zfcp_qdio_open(struct zfcp_adapter *adapter) +{ + volatile struct qdio_buffer_element *sbale; + int cc; + + if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) + return -EIO; + + if (qdio_establish(&adapter->qdio_init_data)) { + dev_err(&adapter->ccw_device->dev, + "Establish of QDIO queues failed.\n"); + return -EIO; + } + + if (qdio_activate(adapter->ccw_device, 0)) { + dev_err(&adapter->ccw_device->dev, + "Activate of QDIO queues failed.\n"); + goto failed_qdio; + } + + for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { + sbale = &(adapter->resp_q.sbal[cc]->element[0]); + sbale->length = 0; + sbale->flags = SBAL_FLAGS_LAST_ENTRY; + sbale->addr = NULL; + } + + if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0, + QDIO_MAX_BUFFERS_PER_Q, NULL)) { + dev_err(&adapter->ccw_device->dev, + "Init of QDIO response queue failed.\n"); + goto failed_qdio; + } + + /* set index of first avalable SBALS / number of available SBALS */ + adapter->req_q.first = 0; + atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q); + adapter->req_q.pci_batch = 0; + + return 0; + +failed_qdio: + while (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR) + == -EINPROGRESS) + ssleep(1); + + return -EIO; +} -- cgit v0.10.2 From 553448f6c4838a1e4bed2bc9301c748278d7d9ce Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 10 Jun 2008 18:20:58 +0200 Subject: [SCSI] zfcp: Message cleanup Cleanup the messages used in the zfcp driver: Remove unnecessary debug and trace message and convert the remaining messages to standard kernel macros. Remove the zfcp message macros and while updating the whole flie also update the copyright headers. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index c0fa8ff..1aa4650 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -4,6 +4,6 @@ zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \ - zfcp_sysfs_unit.o zfcp_sysfs_driver.o zfcp_fc.o zfcp_cfdc.o + zfcp_sysfs_unit.o zfcp_fc.o zfcp_cfdc.o obj-$(CONFIG_ZFCP) += zfcp.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 7084a6a..47739f4 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -1,22 +1,9 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Module interface and handling of zfcp data structures. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ /* @@ -31,13 +18,16 @@ * Maxim Shchetynin * Volker Sameske * Ralph Wuerthner + * Michael Loehr + * Swen Schillig + * Christof Schmitt + * Martin Petermann + * Sven Schuetz */ #include #include "zfcp_ext.h" -/* accumulated log level (module parameter) */ -static u32 loglevel = ZFCP_LOG_LEVEL_DEFAULTS; static char *device; /*********************** FUNCTION PROTOTYPES *********************************/ @@ -57,12 +47,6 @@ MODULE_LICENSE("GPL"); module_param(device, charp, 0400); MODULE_PARM_DESC(device, "specify initial device"); -module_param(loglevel, uint, 0400); -MODULE_PARM_DESC(loglevel, - "log levels, 8 nibbles: " - "FC ERP QDIO CIO Config FSF SCSI Other, " - "levels: 0=none 1=normal 2=devel 3=trace"); - /****************************************************************/ /************** Functions without logging ***********************/ /****************************************************************/ @@ -87,8 +71,6 @@ _zfcp_hex_dump(char *addr, int count) /****** Functions to handle the request ID hash table ********/ /****************************************************************/ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF - static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) { int idx; @@ -118,14 +100,10 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) return 1; } -#undef ZFCP_LOG_AREA - /****************************************************************/ /************** Uncategorised Functions *************************/ /****************************************************************/ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER - /** * zfcp_device_setup - setup function * @str: pointer to parameter string @@ -143,8 +121,11 @@ zfcp_device_setup(char *devstr) len = strlen(devstr) + 1; str = kmalloc(len, GFP_KERNEL); - if (!str) - goto err_out; + if (!str) { + pr_err("zfcp: Could not allocate memory for " + "device parameter string, device not attached.\n"); + return 0; + } memcpy(str, devstr, len); tmp = strchr(str, ','); @@ -167,7 +148,8 @@ zfcp_device_setup(char *devstr) return 1; err_out: - ZFCP_LOG_NORMAL("Parse error for device parameter string %s\n", str); + pr_err("zfcp: Parse error for device parameter string %s, " + "device not attached.\n", str); kfree(str); return 0; } @@ -248,8 +230,6 @@ zfcp_module_init(void) if (!zfcp_data.gid_pn_cache) goto out_gid_cache; - atomic_set(&zfcp_data.loglevel, loglevel); - /* initialize adapter list */ INIT_LIST_HEAD(&zfcp_data.adapter_list_head); @@ -263,8 +243,7 @@ zfcp_module_init(void) retval = misc_register(&zfcp_cfdc_misc); if (retval != 0) { - ZFCP_LOG_INFO("registration of misc device " - "zfcp_cfdc failed\n"); + pr_err("zfcp: registration of misc device zfcp_cfdc failed\n"); goto out_misc; } @@ -277,7 +256,7 @@ zfcp_module_init(void) /* setup dynamic I/O */ retval = zfcp_ccw_register(); if (retval) { - ZFCP_LOG_NORMAL("registration with common I/O layer failed\n"); + pr_err("zfcp: Registration with common I/O layer failed.\n"); goto out_ccw_register; } @@ -300,14 +279,10 @@ zfcp_module_init(void) return retval; } -#undef ZFCP_LOG_AREA - /****************************************************************/ /****** Functions for configuration/set-up of structures ********/ /****************************************************************/ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG - /** * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN * @port: pointer to port to search for unit @@ -598,6 +573,8 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) * All adapter internal structures are set up. * Proc-fs entries are also created. * + * FIXME: Use -ENOMEM as return code for allocation failures + * * returns: 0 if a new adapter was successfully enqueued * ZFCP_KNOWN if an adapter with this devno was already present * -ENOMEM if alloc failed @@ -615,11 +592,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* try to allocate new adapter data structure (zeroed) */ adapter = kzalloc(sizeof (struct zfcp_adapter), GFP_KERNEL); - if (!adapter) { - ZFCP_LOG_INFO("error: allocation of base adapter " - "structure failed\n"); + if (!adapter) goto out; - } ccw_device->handler = NULL; @@ -760,7 +734,6 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) zfcp_reqlist_free(adapter); kfree(adapter->fc_stats); kfree(adapter->stats_reset_data); - ZFCP_LOG_TRACE("freeing adapter structure\n"); kfree(adapter); out: return; @@ -908,12 +881,8 @@ zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, ZFCP_DID_DIRECTORY_SERVICE); - if (!port) { - ZFCP_LOG_INFO("error: enqueue of nameserver port for " - "adapter %s failed\n", - zfcp_get_busid_by_adapter(adapter)); + if (!port) return -ENXIO; - } zfcp_port_put(port); return 0; @@ -946,5 +915,3 @@ int zfcp_sg_setup_table(struct scatterlist *sg, int count) } return 0; } - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index c47c23a..7c72f50 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -1,22 +1,9 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Debug traces for zfcp. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #include @@ -29,8 +16,6 @@ module_param(dbfsize, uint, 0400); MODULE_PARM_DESC(dbfsize, "number of pages for each debug feature area (default 4)"); -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER - static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len, int level, char *from, int from_len) { @@ -515,13 +500,13 @@ static const char *zfcp_rec_dbf_ids[] = { [52] = "port boxed close unit", [53] = "port boxed fcp", [54] = "unit boxed fcp", - [55] = "port access denied ct", - [56] = "port access denied els", - [57] = "port access denied open port", - [58] = "port access denied close physical", - [59] = "unit access denied open unit", + [55] = "port access denied", + [56] = "", + [57] = "", + [58] = "", + [59] = "unit access denied", [60] = "shared unit access denied open unit", - [61] = "unit access denied fcp", + [61] = "", [62] = "request timeout", [63] = "adisc link test reject or timeout", [64] = "adisc link test d_id changed", @@ -586,8 +571,8 @@ static const char *zfcp_rec_dbf_ids[] = { [120] = "unknown fsf command", [121] = "no recommendation for status qualifier", [122] = "status read physical port closed in error", - [123] = "fc service class not supported ct", - [124] = "fc service class not supported els", + [123] = "fc service class not supported", + [124] = "", [125] = "need newer zfcp", [126] = "need newer microcode", [127] = "arbitrated loop not supported", @@ -595,7 +580,7 @@ static const char *zfcp_rec_dbf_ids[] = { [129] = "qtcb size mismatch", [130] = "unknown fsf status ecd", [131] = "fcp request too big", - [132] = "fc service class not supported fcp", + [132] = "", [133] = "data direction not valid fcp", [134] = "command length not valid fcp", [135] = "status read act update", @@ -1291,5 +1276,3 @@ void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) adapter->hba_dbf = NULL; adapter->rec_dbf = NULL; } - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 5fcb555..73425db 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -1,22 +1,9 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Global definitions for the zfcp device 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #ifndef ZFCP_DEF_H @@ -52,9 +39,6 @@ /********************* GENERAL DEFINES *********************************/ -/* zfcp version number, it consists of major, minor, and patch-level number */ -#define ZFCP_VERSION "4.8.0" - /** * zfcp_sg_to_address - determine kernel address from struct scatterlist * @list: struct scatterlist @@ -308,107 +292,6 @@ struct zfcp_rc_entry { */ #define ZFCP_CT_TIMEOUT (3 * R_A_TOV) -/******************** LOGGING MACROS AND DEFINES *****************************/ - -/* - * Logging may be applied on certain kinds of driver operations - * independently. Additionally, different log-levels are supported for - * each of these areas. - */ - -#define ZFCP_NAME "zfcp" - -/* independent log areas */ -#define ZFCP_LOG_AREA_OTHER 0 -#define ZFCP_LOG_AREA_SCSI 1 -#define ZFCP_LOG_AREA_FSF 2 -#define ZFCP_LOG_AREA_CONFIG 3 -#define ZFCP_LOG_AREA_CIO 4 -#define ZFCP_LOG_AREA_QDIO 5 -#define ZFCP_LOG_AREA_ERP 6 -#define ZFCP_LOG_AREA_FC 7 - -/* log level values*/ -#define ZFCP_LOG_LEVEL_NORMAL 0 -#define ZFCP_LOG_LEVEL_INFO 1 -#define ZFCP_LOG_LEVEL_DEBUG 2 -#define ZFCP_LOG_LEVEL_TRACE 3 - -/* - * this allows removal of logging code by the preprocessor - * (the most detailed log level still to be compiled in is specified, - * higher log levels are removed) - */ -#define ZFCP_LOG_LEVEL_LIMIT ZFCP_LOG_LEVEL_TRACE - -/* get "loglevel" nibble assignment */ -#define ZFCP_GET_LOG_VALUE(zfcp_lognibble) \ - ((atomic_read(&zfcp_data.loglevel) >> (zfcp_lognibble<<2)) & 0xF) - -/* set "loglevel" nibble */ -#define ZFCP_SET_LOG_NIBBLE(value, zfcp_lognibble) \ - (value << (zfcp_lognibble << 2)) - -/* all log-level defaults are combined to generate initial log-level */ -#define ZFCP_LOG_LEVEL_DEFAULTS \ - (ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_OTHER) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_SCSI) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FSF) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CONFIG) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CIO) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_QDIO) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_ERP) | \ - ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FC)) - -/* check whether we have the right level for logging */ -#define ZFCP_LOG_CHECK(level) \ - ((ZFCP_GET_LOG_VALUE(ZFCP_LOG_AREA)) >= level) - -/* logging routine for zfcp */ -#define _ZFCP_LOG(fmt, args...) \ - printk(KERN_ERR ZFCP_NAME": %s(%d): " fmt, __func__, \ - __LINE__ , ##args) - -#define ZFCP_LOG(level, fmt, args...) \ -do { \ - if (ZFCP_LOG_CHECK(level)) \ - _ZFCP_LOG(fmt, ##args); \ -} while (0) - -#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL -# define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0) -#else -# define ZFCP_LOG_NORMAL(fmt, args...) \ -do { \ - if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_NORMAL)) \ - printk(KERN_ERR ZFCP_NAME": " fmt, ##args); \ -} while (0) -#endif - -#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_INFO -# define ZFCP_LOG_INFO(fmt, args...) do { } while (0) -#else -# define ZFCP_LOG_INFO(fmt, args...) \ -do { \ - if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_INFO)) \ - printk(KERN_ERR ZFCP_NAME": " fmt, ##args); \ -} while (0) -#endif - -#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_DEBUG -# define ZFCP_LOG_DEBUG(fmt, args...) do { } while (0) -#else -# define ZFCP_LOG_DEBUG(fmt, args...) \ - ZFCP_LOG(ZFCP_LOG_LEVEL_DEBUG, fmt , ##args) -#endif - -#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_TRACE -# define ZFCP_LOG_TRACE(fmt, args...) do { } while (0) -#else -# define ZFCP_LOG_TRACE(fmt, args...) \ - ZFCP_LOG(ZFCP_LOG_LEVEL_TRACE, fmt , ##args) -#endif - /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ /* @@ -846,7 +729,6 @@ struct zfcp_data { char init_busid[BUS_ID_SIZE]; wwn_t init_wwpn; fcp_lun_t init_fcp_lun; - char *driver_version; struct kmem_cache *fsf_req_qtcb_cache; struct kmem_cache *sr_buffer_cache; struct kmem_cache *gid_pn_cache; diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 4a6d083..c06156b 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -1,26 +1,11 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Error Recovery Procedures (ERP). * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP - #include "zfcp_ext.h" static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int, u8, @@ -171,14 +156,9 @@ static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, { int retval; - ZFCP_LOG_DEBUG("reopen adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - zfcp_erp_adapter_block(adapter, clear_mask); if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) { - ZFCP_LOG_DEBUG("skipped reopen of failed adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); /* ensure propagation of failed status to new devices */ zfcp_erp_adapter_failed(adapter, 13, NULL); retval = -EIO; @@ -270,15 +250,9 @@ static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, { int retval; - ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n", - port->wwpn, zfcp_get_busid_by_port(port)); - zfcp_erp_port_block(port, clear_mask); if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) { - ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx " - "on adapter %s\n", port->wwpn, - zfcp_get_busid_by_port(port)); retval = -EIO; goto out; } @@ -332,15 +306,9 @@ static int zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask, { int retval; - ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n", - port->wwpn, zfcp_get_busid_by_port(port)); - zfcp_erp_port_block(port, clear_mask); if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) { - ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx " - "on adapter %s\n", port->wwpn, - zfcp_get_busid_by_port(port)); /* ensure propagation of failed status to new devices */ zfcp_erp_port_failed(port, 14, NULL); retval = -EIO; @@ -396,17 +364,9 @@ static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask, int retval; struct zfcp_adapter *adapter = unit->port->adapter; - ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx " - "on adapter %s\n", unit->fcp_lun, - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); - zfcp_erp_unit_block(unit, clear_mask); if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) { - ZFCP_LOG_DEBUG("skipped reopen of failed unit 0x%016Lx " - "on port 0x%016Lx on adapter %s\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); retval = -EIO; goto out; } @@ -631,13 +591,8 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) ZFCP_STATUS_FSFREQ_DISMISSED; zfcp_rec_dbf_event_action(142, erp_action); } - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { + if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) zfcp_rec_dbf_event_action(143, erp_action); - ZFCP_LOG_NORMAL("error: erp step timed out " - "(action=%d, fsf_req=%p)\n ", - erp_action->action, - erp_action->fsf_req); - } /* * If fsf_req is neither dismissed nor completed * then keep it running asynchronously and don't mess @@ -740,11 +695,10 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter) atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); - if (retval < 0) { - ZFCP_LOG_NORMAL("error: creation of erp thread failed for " - "adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - } else { + if (retval < 0) + dev_err(&adapter->ccw_device->dev, + "Creation of ERP thread failed.\n"); + else { wait_event(adapter->erp_thread_wqh, atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status)); @@ -919,15 +873,10 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) This might happen if an erp_action that used a memory pool element was timed out. */ - if (adapter->erp_total_count == adapter->erp_low_mem_count) { - ZFCP_LOG_NORMAL("error: no mempool elements available, " - "restarting I/O on adapter %s " - "to free mempool\n", - zfcp_get_busid_by_adapter(adapter)); + if (adapter->erp_total_count == adapter->erp_low_mem_count) zfcp_erp_adapter_reopen_internal(adapter, 0, 66, NULL); - } else { - retval = zfcp_erp_strategy_memwait(erp_action); - } + else + retval = zfcp_erp_strategy_memwait(erp_action); goto unlock; case ZFCP_ERP_CONTINUES: /* leave since this action runs asynchronously */ @@ -1039,12 +988,6 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) case ZFCP_ERP_ACTION_REOPEN_UNIT: retval = zfcp_erp_unit_strategy(erp_action); break; - - default: - ZFCP_LOG_NORMAL("bug: unknown erp action requested on " - "adapter %s (action=%d)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->action); } return retval; @@ -1083,8 +1026,7 @@ zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref) { zfcp_erp_modify_adapter_status(adapter, id, ref, ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); - ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, "Adapter ERP failed.\n"); } /* @@ -1100,12 +1042,13 @@ zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref) ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) - ZFCP_LOG_NORMAL("port erp failed (adapter %s, " - "port d_id=0x%06x)\n", - zfcp_get_busid_by_port(port), port->d_id); + dev_err(&port->adapter->ccw_device->dev, + "Port ERP failed for WKA port d_id=0x%06x.\n", + port->d_id); else - ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n", - zfcp_get_busid_by_port(port), port->wwpn); + dev_err(&port->adapter->ccw_device->dev, + "Port ERP failed for port wwpn=0x%016Lx.\n", + port->wwpn); } /* @@ -1120,9 +1063,9 @@ zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref) zfcp_erp_modify_unit_status(unit, id, ref, ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); - ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx " - " on adapter %s\n", unit->fcp_lun, - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); + dev_err(&unit->port->adapter->ccw_device->dev, + "Unit ERP failed for unit 0x%016Lx on port 0x%016Lx.\n", + unit->fcp_lun, unit->port->wwpn); } /* @@ -1336,13 +1279,10 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit) p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) { - ZFCP_LOG_NORMAL("error: Out of resources. Could not register " - "the FCP-LUN 0x%Lx connected to " - "the port with WWPN 0x%Lx connected to " - "the adapter %s with the SCSI stack.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); + dev_err(&unit->port->adapter->ccw_device->dev, + "Out of resources. Could not register unit 0x%016Lx " + "on port 0x%016Lx with SCSI stack.\n", + unit->fcp_lun, unit->port->wwpn); return; } @@ -1585,7 +1525,6 @@ static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action) { int retval; - struct zfcp_adapter *adapter = erp_action->adapter; retval = zfcp_erp_adapter_strategy_close(erp_action); if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) @@ -1593,12 +1532,8 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action) else retval = zfcp_erp_adapter_strategy_open(erp_action); - if (retval == ZFCP_ERP_FAILED) { - ZFCP_LOG_INFO("Waiting to allow the adapter %s " - "to recover itself\n", - zfcp_get_busid_by_adapter(adapter)); + if (retval == ZFCP_ERP_FAILED) ssleep(ZFCP_TYPE2_RECOVERY_TIME); - } return retval; } @@ -1743,19 +1678,13 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) { atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, &adapter->status); - ZFCP_LOG_DEBUG("Doing exchange config data\n"); write_lock_irq(&adapter->erp_lock); zfcp_erp_action_to_running(erp_action); write_unlock_irq(&adapter->erp_lock); if (zfcp_fsf_exchange_config_data(erp_action)) { retval = ZFCP_ERP_FAILED; - ZFCP_LOG_INFO("error: initiation of exchange of " - "configuration data failed for " - "adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); break; } - ZFCP_LOG_DEBUG("Xchange underway\n"); /* * Why this works: @@ -1773,19 +1702,13 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) zfcp_rec_dbf_event_thread_lock(6, adapter); down(&adapter->erp_ready_sem); zfcp_rec_dbf_event_thread_lock(7, adapter); - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { - ZFCP_LOG_INFO("error: exchange of configuration data " - "for adapter %s timed out\n", - zfcp_get_busid_by_adapter(adapter)); + if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) break; - } if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, &adapter->status)) break; - ZFCP_LOG_DEBUG("host connection still initialising... " - "waiting and retrying...\n"); /* sleep a little bit before retry */ ssleep(sleep); sleep *= 2; @@ -1795,12 +1718,8 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) &adapter->status); if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, - &adapter->status)) { - ZFCP_LOG_INFO("error: exchange of configuration data for " - "adapter %s failed\n", - zfcp_get_busid_by_adapter(adapter)); + &adapter->status)) retval = ZFCP_ERP_FAILED; - } return retval; } @@ -1829,16 +1748,8 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) zfcp_rec_dbf_event_thread_lock(8, adapter); down(&adapter->erp_ready_sem); zfcp_rec_dbf_event_thread_lock(9, adapter); - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { - ZFCP_LOG_INFO("error: exchange port data timed out (adapter " - "%s)\n", zfcp_get_busid_by_adapter(adapter)); + if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) ret = ZFCP_ERP_FAILED; - } - - /* don't treat as error for the sake of compatibility */ - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) - ZFCP_LOG_INFO("warning: exchange port data failed (adapter " - "%s\n", zfcp_get_busid_by_adapter(adapter)); return ret; } @@ -1884,8 +1795,6 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) if (atomic_test_mask((ZFCP_STATUS_PORT_PHYS_OPEN | ZFCP_STATUS_COMMON_OPEN), &port->status)) { - ZFCP_LOG_DEBUG("port 0x%016Lx is open -> trying " - "close physical\n", port->wwpn); retval = zfcp_erp_port_forced_strategy_close(erp_action); } else @@ -1895,8 +1804,6 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: if (atomic_test_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status)) { - ZFCP_LOG_DEBUG("close physical failed for port " - "0x%016Lx\n", port->wwpn); retval = ZFCP_ERP_FAILED; } else retval = ZFCP_ERP_SUCCEEDED; @@ -1930,8 +1837,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_UNINITIALIZED: zfcp_erp_port_strategy_clearstati(port); if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) { - ZFCP_LOG_DEBUG("port 0x%016Lx is open -> trying " - "close\n", port->wwpn); retval = zfcp_erp_port_strategy_close(erp_action); goto out; } /* else it's already closed, open it */ @@ -1939,8 +1844,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_PORT_CLOSING: if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) { - ZFCP_LOG_DEBUG("close failed for port 0x%016Lx\n", - port->wwpn); retval = ZFCP_ERP_FAILED; goto out; } /* else it's closed now, open it */ @@ -1983,12 +1886,10 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_PORT_CLOSING: if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) { if (port->wwpn != adapter->peer_wwpn) { - ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx " - "on adapter %s.\nPeer WWPN " - "0x%016Lx does not match\n", - port->wwpn, - zfcp_get_busid_by_adapter(adapter), - adapter->peer_wwpn); + dev_err(&adapter->ccw_device->dev, + "Failed to open port 0x%016Lx, " + "Peer WWPN 0x%016Lx does not match.\n", + port->wwpn, adapter->peer_wwpn); zfcp_erp_port_failed(port, 25, NULL); retval = ZFCP_ERP_FAILED; break; @@ -2001,17 +1902,14 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) if (!(adapter->nameserver_port)) { retval = zfcp_nameserver_enqueue(adapter); if (retval != 0) { - ZFCP_LOG_NORMAL("error: nameserver port " - "unavailable for adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "Nameserver port unavailable.\n"); retval = ZFCP_ERP_FAILED; break; } } if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->nameserver_port->status)) { - ZFCP_LOG_DEBUG("nameserver port is not open -> open " - "nameserver port\n"); /* nameserver port may live again */ atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &adapter->nameserver_port->status); @@ -2027,57 +1925,37 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) /* else nameserver port is already open, fall through */ case ZFCP_ERP_STEP_NAMESERVER_OPEN: if (!atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, - &adapter->nameserver_port->status)) { - ZFCP_LOG_DEBUG("open failed for nameserver port\n"); + &adapter->nameserver_port->status)) retval = ZFCP_ERP_FAILED; - } else { - ZFCP_LOG_DEBUG("nameserver port is open -> " - "nameserver look-up for port 0x%016Lx\n", - port->wwpn); + else retval = zfcp_erp_port_strategy_open_common_lookup (erp_action); - } break; case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) { if (atomic_test_mask (ZFCP_STATUS_PORT_INVALID_WWPN, &port->status)) { - ZFCP_LOG_DEBUG("nameserver look-up failed " - "for port 0x%016Lx " - "(misconfigured WWPN?)\n", - port->wwpn); zfcp_erp_port_failed(port, 26, NULL); retval = ZFCP_ERP_EXIT; - } else { - ZFCP_LOG_DEBUG("nameserver look-up failed for " - "port 0x%016Lx\n", port->wwpn); + } else retval = ZFCP_ERP_FAILED; - } - } else { - ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> " - "trying open\n", port->wwpn, port->d_id); + } else retval = zfcp_erp_port_strategy_open_port(erp_action); - } break; case ZFCP_ERP_STEP_PORT_OPENING: /* D_ID might have changed during open */ if (atomic_test_mask((ZFCP_STATUS_COMMON_OPEN | ZFCP_STATUS_PORT_DID_DID), - &port->status)) { - ZFCP_LOG_DEBUG("port 0x%016Lx is open\n", port->wwpn); + &port->status)) retval = ZFCP_ERP_SUCCEEDED; - } else { - ZFCP_LOG_DEBUG("open failed for port 0x%016Lx\n", - port->wwpn); + else retval = ZFCP_ERP_FAILED; - } break; default: - ZFCP_LOG_NORMAL("bug: unknown erp step 0x%08x\n", - erp_action->step); + /* unknown erp step */ retval = ZFCP_ERP_FAILED; } @@ -2095,27 +1973,20 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_UNINITIALIZED: case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: case ZFCP_ERP_STEP_PORT_CLOSING: - ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> trying open\n", - port->wwpn, port->d_id); retval = zfcp_erp_port_strategy_open_port(erp_action); break; case ZFCP_ERP_STEP_PORT_OPENING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) { - ZFCP_LOG_DEBUG("WKA port is open\n"); + if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) retval = ZFCP_ERP_SUCCEEDED; - } else { - ZFCP_LOG_DEBUG("open failed for WKA port\n"); + else retval = ZFCP_ERP_FAILED; - } /* this is needed anyway (dont care for retval of wakeup) */ - ZFCP_LOG_DEBUG("continue other open port operations\n"); zfcp_erp_port_strategy_open_nameserver_wakeup(erp_action); break; default: - ZFCP_LOG_NORMAL("bug: unknown erp step 0x%08x\n", - erp_action->step); + /* unknown erp step */ retval = ZFCP_ERP_FAILED; } @@ -2313,39 +2184,26 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_UNINITIALIZED: zfcp_erp_unit_strategy_clearstati(unit); if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) { - ZFCP_LOG_DEBUG("unit 0x%016Lx is open -> " - "trying close\n", unit->fcp_lun); retval = zfcp_erp_unit_strategy_close(erp_action); break; } /* else it's already closed, fall through */ case ZFCP_ERP_STEP_UNIT_CLOSING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) { - ZFCP_LOG_DEBUG("close failed for unit 0x%016Lx\n", - unit->fcp_lun); + if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) retval = ZFCP_ERP_FAILED; - } else { + else if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) retval = ZFCP_ERP_EXIT; - else { - ZFCP_LOG_DEBUG("unit 0x%016Lx is not open -> " - "trying open\n", unit->fcp_lun); + else retval = zfcp_erp_unit_strategy_open(erp_action); - } - } break; case ZFCP_ERP_STEP_UNIT_OPENING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) { - ZFCP_LOG_DEBUG("unit 0x%016Lx is open\n", - unit->fcp_lun); + if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) retval = ZFCP_ERP_SUCCEEDED; - } else { - ZFCP_LOG_DEBUG("open failed for unit 0x%016Lx\n", - unit->fcp_lun); + else retval = ZFCP_ERP_FAILED; - } break; } @@ -2493,16 +2351,8 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, - &port->status)) { - if (port->erp_action.action != - ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) { - ZFCP_LOG_INFO("dropped erp action %i (port " - "0x%016Lx, action in use: %i)\n", - want, port->wwpn, - port->erp_action.action); - } + &port->status)) goto out; - } if (!atomic_test_mask (ZFCP_STATUS_COMMON_RUNNING, &adapter->status) || atomic_test_mask @@ -2522,19 +2372,10 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, break; default: - ZFCP_LOG_NORMAL("bug: unknown erp action requested " - "on adapter %s (action=%d)\n", - zfcp_get_busid_by_adapter(adapter), want); + /* unknown erp action */ goto out; } - /* check whether we need something stronger first */ - if (need) { - ZFCP_LOG_DEBUG("stronger erp action %d needed before " - "erp action %d on adapter %s\n", - need, want, zfcp_get_busid_by_adapter(adapter)); - } - /* mark adapter to have some error recovery pending */ atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); @@ -2672,10 +2513,9 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, port->rport = fc_remote_port_add(adapter->scsi_host, 0, &ids); if (!port->rport) - ZFCP_LOG_NORMAL("failed registration of rport" - "(adapter %s, wwpn=0x%016Lx)\n", - zfcp_get_busid_by_port(port), - port->wwpn); + dev_err(&adapter->ccw_device->dev, + "Failed registration of rport " + "0x%016Lx.\n", port->wwpn); else { scsi_target_unblock(&port->rport->dev); port->rport->maxframe_size = port->maxframe_size; @@ -2803,7 +2643,6 @@ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id, void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, void *ref) { - struct zfcp_adapter *adapter = port->adapter; struct zfcp_unit *unit; if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, @@ -2816,34 +2655,16 @@ void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, void *ref) return; } - ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s " - "(due to ACT update)\n", - port->wwpn, zfcp_get_busid_by_adapter(adapter)); - if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref)) - ZFCP_LOG_NORMAL("failed reopen of port" - "(adapter %s, wwpn=0x%016Lx)\n", - zfcp_get_busid_by_adapter(adapter), port->wwpn); + zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id, void *ref) { - struct zfcp_adapter *adapter = unit->port->adapter; - if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &unit->status) && !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, &unit->status)) return; - ZFCP_LOG_NORMAL("reopen of unit 0x%016Lx on port 0x%016Lx " - " on adapter %s (due to ACT update)\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_adapter(adapter)); - if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref)) - ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, " - "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n", - zfcp_get_busid_by_adapter(adapter), - unit->port->wwpn, unit->fcp_lun); + zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 6ffe206..9aa412b 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -1,22 +1,9 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * External function declarations. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #ifndef ZFCP_EXT_H @@ -27,7 +14,6 @@ extern struct zfcp_data zfcp_data; /******************************** SYSFS *************************************/ -extern struct attribute_group *zfcp_driver_attr_groups[]; extern int zfcp_sysfs_adapter_create_files(struct device *); extern void zfcp_sysfs_adapter_remove_files(struct device *); extern int zfcp_sysfs_port_create_files(struct device *, u32); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index cc48a64..01ed5fb 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1,22 +1,9 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Implementation of FSF commands. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #include "zfcp_ext.h" @@ -71,12 +58,58 @@ static const char zfcp_act_subtable_type[5][8] = { "unknown", "OS", "WWPN", "DID", "LUN" }; +static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) +{ + u16 subtable = (table & 0xffff0000) >> 16; + u16 rule = table & 0xffff; + + if (subtable > 0 && + subtable < ARRAY_SIZE(zfcp_act_subtable_type)) { + dev_warn(&adapter->ccw_device->dev, + "Access denied in subtable %s, rule %d.\n", + zfcp_act_subtable_type[subtable], rule); + } +} + +static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, + struct zfcp_port *port) +{ + struct fsf_qtcb_header *header = &req->qtcb->header; + dev_warn(&req->adapter->ccw_device->dev, + "Access denied, cannot send command to port 0x%016Lx.\n", + port->wwpn); + zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); + zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); + zfcp_erp_port_access_denied(port, 55, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; +} + +static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req, + struct zfcp_unit *unit) +{ + struct fsf_qtcb_header *header = &req->qtcb->header; + dev_warn(&req->adapter->ccw_device->dev, + "Access denied for unit 0x%016Lx on port 0x%016Lx.\n", + unit->fcp_lun, unit->port->wwpn); + zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); + zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); + zfcp_erp_unit_access_denied(unit, 59, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; +} + +static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) +{ + dev_err(&req->adapter->ccw_device->dev, + "Required FC class not supported by adapter, " + "shutting down adapter.\n"); + zfcp_erp_adapter_shutdown(req->adapter, 0, 123, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; +} + /****************************************************************/ /*************** FSF related Functions *************************/ /****************************************************************/ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF - /* * function: zfcp_fsf_req_alloc * @@ -200,7 +233,6 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) int cleanup; if (unlikely(fsf_req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) { - ZFCP_LOG_DEBUG("Status read response received\n"); /* * Note: all cleanup handling is done in the callchain of * the function call-chain below. @@ -225,7 +257,6 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) /* cleanup request if requested by initiator */ if (likely(cleanup)) { - ZFCP_LOG_TRACE("removing FSF request %p\n", fsf_req); /* * lock must not be held here since it will be * grabed by the called routine, too @@ -233,7 +264,6 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) zfcp_fsf_req_free(fsf_req); } else { /* notify initiator waiting for the requests completion */ - ZFCP_LOG_TRACE("waking initiator of FSF request %p\n",fsf_req); /* * FIXME: Race! We must not access fsf_req here as it might have been * cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED @@ -276,8 +306,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) zfcp_hba_dbf_event_fsf_response(fsf_req); if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { - ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n", - (unsigned long) fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ goto skip_protstatus; @@ -291,34 +319,26 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) break; case FSF_PROT_QTCB_VERSION_ERROR: - ZFCP_LOG_NORMAL("error: The adapter %s contains " - "microcode of version 0x%x, the device driver " - "only supports 0x%x. Aborting.\n", - zfcp_get_busid_by_adapter(adapter), - prot_status_qual->version_error.fsf_version, - ZFCP_QTCB_VERSION); + dev_err(&adapter->ccw_device->dev, + "The QTCB version requested by zfcp (0x%x) is not " + "supported by the FCP adapter (lowest supported 0x%x, " + "highest supported 0x%x).\n", + ZFCP_QTCB_VERSION, prot_status_qual->word[0], + prot_status_qual->word[1]); zfcp_erp_adapter_shutdown(adapter, 0, 117, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PROT_SEQ_NUMB_ERROR: - ZFCP_LOG_NORMAL("bug: Sequence number mismatch between " - "driver (0x%x) and adapter %s (0x%x). " - "Restarting all operations on this adapter.\n", - qtcb->prefix.req_seq_no, - zfcp_get_busid_by_adapter(adapter), - prot_status_qual->sequence_error.exp_req_seq_no); zfcp_erp_adapter_reopen(adapter, 0, 98, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PROT_UNSUPP_QTCB_TYPE: - ZFCP_LOG_NORMAL("error: Packet header type used by the " - "device driver is incompatible with " - "that used on adapter %s. " - "Stopping all operations on this adapter.\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "Packet header type used by the device driver is " + "incompatible with that used on the adapter.\n"); zfcp_erp_adapter_shutdown(adapter, 0, 118, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -330,12 +350,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) break; case FSF_PROT_DUPLICATE_REQUEST_ID: - ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx " - "to the adapter %s is ambiguous. " - "Stopping all operations on this adapter.\n", - *(unsigned long long*) - (&qtcb->bottom.support.req_handle), - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "The request identifier 0x%Lx is ambiguous.\n", + (unsigned long long)qtcb->bottom.support.req_handle); zfcp_erp_adapter_shutdown(adapter, 0, 78, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -349,10 +366,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) break; case FSF_PROT_REEST_QUEUE: - ZFCP_LOG_NORMAL("The local link to adapter with " - "%s was re-plugged. " - "Re-starting operations on this adapter.\n", - zfcp_get_busid_by_adapter(adapter)); /* All ports should be marked as ready to run again */ zfcp_erp_modify_adapter_status(adapter, 28, NULL, ZFCP_STATUS_COMMON_RUNNING, @@ -365,24 +378,17 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) break; case FSF_PROT_ERROR_STATE: - ZFCP_LOG_NORMAL("error: The adapter %s " - "has entered the error state. " - "Restarting all operations on this " - "adapter.\n", - zfcp_get_busid_by_adapter(adapter)); zfcp_erp_adapter_reopen(adapter, 0, 100, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; default: - ZFCP_LOG_NORMAL("bug: Transfer protocol status information " - "provided by the adapter %s " - "is not compatible with the device driver. " - "Stopping all operations on this adapter. " - "(debug info 0x%x).\n", - zfcp_get_busid_by_adapter(adapter), - qtcb->prefix.prot_status); + dev_err(&adapter->ccw_device->dev, + "Transfer protocol status information" + "provided by the adapter (0x%x) " + "is not compatible with the device driver.\n", + qtcb->prefix.prot_status); zfcp_erp_adapter_shutdown(adapter, 0, 119, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; } @@ -416,21 +422,14 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req) /* evaluate FSF Status */ switch (fsf_req->qtcb->header.fsf_status) { case FSF_UNKNOWN_COMMAND: - ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " - "not known by the adapter %s " - "Stopping all operations on this adapter. " - "(debug info 0x%x).\n", - zfcp_get_busid_by_adapter(fsf_req->adapter), - fsf_req->qtcb->header.fsf_command); + dev_err(&fsf_req->adapter->ccw_device->dev, + "Command issued by the device driver (0x%x) is " + "not known by the adapter.\n", + fsf_req->qtcb->header.fsf_command); zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 120, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_FCP_RSP_AVAILABLE: - ZFCP_LOG_DEBUG("FCP Sense data will be presented to the " - "SCSI stack.\n"); - break; - case FSF_ADAPTER_STATUS_AVAILABLE: zfcp_fsf_fsfstatus_qual_eval(fsf_req); break; @@ -472,17 +471,13 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_NO_RECOM: - ZFCP_LOG_NORMAL("bug: No recommendation could be given for a " - "problem on the adapter %s " - "Stopping all operations on this adapter. ", - zfcp_get_busid_by_adapter(fsf_req->adapter)); + dev_err(&fsf_req->adapter->ccw_device->dev, + "No recommendation could be given for a " + "problem on the adapter.\n"); zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 121, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_ULP_PROGRAMMING_ERROR: - ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer " - "(adapter %s)\n", - zfcp_get_busid_by_adapter(fsf_req->adapter)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: @@ -491,11 +486,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) /* dealt with in the respective functions */ break; default: - ZFCP_LOG_NORMAL("bug: Additional status info could " - "not be interpreted properly.\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, - (char *) &fsf_req->qtcb->header.fsf_status_qual, - sizeof (union fsf_status_qual)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } @@ -523,84 +513,67 @@ zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *fsf_req, u8 id, switch (link_down->error_code) { case FSF_PSQ_LINK_NO_LIGHT: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(no light detected)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "no light detected.\n"); break; case FSF_PSQ_LINK_WRAP_PLUG: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(wrap plug detected)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "wrap plug detected.\n"); break; case FSF_PSQ_LINK_NO_FCP: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(adjacent node on link does not support FCP)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "adjacent node on link does not support FCP.\n"); break; case FSF_PSQ_LINK_FIRMWARE_UPDATE: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(firmware update in progress)\n", - zfcp_get_busid_by_adapter(adapter)); - break; + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "firmware update in progress.\n"); + break; case FSF_PSQ_LINK_INVALID_WWPN: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(duplicate or invalid WWPN detected)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "duplicate or invalid WWPN detected.\n"); break; case FSF_PSQ_LINK_NO_NPIV_SUPPORT: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(no support for NPIV by Fabric)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "no support for NPIV by Fabric.\n"); break; case FSF_PSQ_LINK_NO_FCP_RESOURCES: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(out of resource in FCP daughtercard)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "out of resource in FCP daughtercard.\n"); break; case FSF_PSQ_LINK_NO_FABRIC_RESOURCES: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(out of resource in Fabric)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "out of resource in Fabric.\n"); break; case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(unable to Fabric login)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link is down: " + "unable to login to Fabric.\n"); break; case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED: - ZFCP_LOG_NORMAL("WWPN assignment file corrupted on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "WWPN assignment file corrupted on adapter.\n"); break; case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED: - ZFCP_LOG_NORMAL("Mode table corrupted on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "Mode table corrupted on adapter.\n"); break; case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT: - ZFCP_LOG_NORMAL("No WWPN for assignment table on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "No WWPN for assignment table on adapter.\n"); break; default: - ZFCP_LOG_NORMAL("The local link to adapter %s is down " - "(warning: unknown reason code %d)\n", - zfcp_get_busid_by_adapter(adapter), - link_down->error_code); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The local link to adapter is down.\n"); } - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) - ZFCP_LOG_DEBUG("Debug information to link down: " - "primary_status=0x%02x " - "ioerr_code=0x%02x " - "action_code=0x%02x " - "reason_code=0x%02x " - "explanation_code=0x%02x " - "vendor_specific_code=0x%02x\n", - link_down->primary_status, - link_down->ioerr_code, - link_down->action_code, - link_down->reason_code, - link_down->explanation_code, - link_down->vendor_specific_code); - out: zfcp_erp_adapter_failed(adapter, id, fsf_req); } @@ -616,7 +589,6 @@ static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) { struct zfcp_erp_action *erp_action = fsf_req->erp_action; - struct zfcp_adapter *adapter = fsf_req->adapter; int retval = 0; @@ -673,20 +645,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) case FSF_QTCB_UPLOAD_CONTROL_FILE: zfcp_fsf_control_file_handler(fsf_req); break; - - default: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " - "not supported by the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command) - ZFCP_LOG_NORMAL - ("bug: Command issued by the device driver differs " - "from the command returned by the adapter %s " - "(debug info 0x%x, 0x%x).\n", - zfcp_get_busid_by_adapter(adapter), - fsf_req->fsf_command, - fsf_req->qtcb->header.fsf_command); } if (!erp_action) @@ -718,12 +676,8 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) req_flags | ZFCP_REQ_NO_QTCB, adapter->pool.fsf_req_status_read, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create unsolicited status " - "buffer for adapter %s.\n", - zfcp_get_busid_by_adapter(adapter)); + if (retval < 0) goto failed_req_create; - } sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS; @@ -744,14 +698,9 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) sbale->length = sizeof(struct fsf_status_read_buffer); retval = zfcp_fsf_req_send(fsf_req); - if (retval) { - ZFCP_LOG_DEBUG("error: Could not set-up unsolicited status " - "environment.\n"); + if (retval) goto failed_req_send; - } - ZFCP_LOG_TRACE("Status Read request initiated (adapter%s)\n", - zfcp_get_busid_by_adapter(adapter)); goto out; failed_req_send: @@ -783,14 +732,8 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) break; read_unlock_irqrestore(&zfcp_data.config_lock, flags); - if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) { - ZFCP_LOG_NORMAL("bug: Reopen port indication received for " - "nonexisting port with d_id 0x%06x on " - "adapter %s. Ignored.\n", - status_buffer->d_id & ZFCP_DID_MASK, - zfcp_get_busid_by_adapter(adapter)); + if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) goto out; - } switch (status_buffer->status_subtype) { @@ -801,20 +744,48 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) case FSF_STATUS_READ_SUB_ERROR_PORT: zfcp_erp_port_shutdown(port, 0, 122, fsf_req); break; - - default: - ZFCP_LOG_NORMAL("bug: Undefined status subtype received " - "for a reopen indication on port with " - "d_id 0x%06x on the adapter %s. " - "Ignored. (debug info 0x%x)\n", - status_buffer->d_id, - zfcp_get_busid_by_adapter(adapter), - status_buffer->status_subtype); } out: return 0; } +static void zfcp_fsf_bit_error_threshold(struct zfcp_fsf_req *req) +{ + struct zfcp_adapter *adapter = req->adapter; + struct fsf_status_read_buffer *buf = + (struct fsf_status_read_buffer *) req->data; + struct fsf_bit_error_payload *err = + (struct fsf_bit_error_payload *) buf->payload; + dev_warn(&adapter->ccw_device->dev, + "Warning: bit error threshold data " + "received for the adapter: " + "link failures = %i, loss of sync errors = %i, " + "loss of signal errors = %i, " + "primitive sequence errors = %i, " + "invalid transmission word errors = %i, " + "CRC errors = %i).\n", + err->link_failure_error_count, + err->loss_of_sync_error_count, + err->loss_of_signal_error_count, + err->primitive_sequence_error_count, + err->invalid_transmission_word_error_count, + err->crc_error_count); + dev_warn(&adapter->ccw_device->dev, + "Additional bit error threshold data of the adapter: " + "primitive sequence event time-outs = %i, " + "elastic buffer overrun errors = %i, " + "advertised receive buffer-to-buffer credit = %i, " + "current receice buffer-to-buffer credit = %i, " + "advertised transmit buffer-to-buffer credit = %i, " + "current transmit buffer-to-buffer credit = %i).\n", + err->primitive_sequence_event_timeout_count, + err->elastic_buffer_overrun_error_count, + err->advertised_receive_b2b_credit, + err->current_receive_b2b_credit, + err->advertised_transmit_b2b_credit, + err->current_transmit_b2b_credit); +} + /* * function: zfcp_fsf_status_read_handler * @@ -829,7 +800,6 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) struct zfcp_adapter *adapter = fsf_req->adapter; struct fsf_status_read_buffer *status_buffer = (struct fsf_status_read_buffer *) fsf_req->data; - struct fsf_bit_error_payload *fsf_bit_error; if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer); @@ -851,79 +821,45 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_STATUS_READ_SENSE_DATA_AVAIL: - ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n", - zfcp_get_busid_by_adapter(adapter)); break; case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: - fsf_bit_error = (struct fsf_bit_error_payload *) - status_buffer->payload; - ZFCP_LOG_NORMAL("Warning: bit error threshold data " - "received (adapter %s, " - "link failures = %i, loss of sync errors = %i, " - "loss of signal errors = %i, " - "primitive sequence errors = %i, " - "invalid transmission word errors = %i, " - "CRC errors = %i)\n", - zfcp_get_busid_by_adapter(adapter), - fsf_bit_error->link_failure_error_count, - fsf_bit_error->loss_of_sync_error_count, - fsf_bit_error->loss_of_signal_error_count, - fsf_bit_error->primitive_sequence_error_count, - fsf_bit_error->invalid_transmission_word_error_count, - fsf_bit_error->crc_error_count); - ZFCP_LOG_INFO("Additional bit error threshold data " - "(adapter %s, " - "primitive sequence event time-outs = %i, " - "elastic buffer overrun errors = %i, " - "advertised receive buffer-to-buffer credit = %i, " - "current receice buffer-to-buffer credit = %i, " - "advertised transmit buffer-to-buffer credit = %i, " - "current transmit buffer-to-buffer credit = %i)\n", - zfcp_get_busid_by_adapter(adapter), - fsf_bit_error->primitive_sequence_event_timeout_count, - fsf_bit_error->elastic_buffer_overrun_error_count, - fsf_bit_error->advertised_receive_b2b_credit, - fsf_bit_error->current_receive_b2b_credit, - fsf_bit_error->advertised_transmit_b2b_credit, - fsf_bit_error->current_transmit_b2b_credit); + zfcp_fsf_bit_error_threshold(fsf_req); break; case FSF_STATUS_READ_LINK_DOWN: switch (status_buffer->status_subtype) { case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: - ZFCP_LOG_INFO("Physical link to adapter %s is down\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&adapter->ccw_device->dev, + "Physical link is down.\n"); zfcp_fsf_link_down_info_eval(fsf_req, 38, (struct fsf_link_down_info *) &status_buffer->payload); break; case FSF_STATUS_READ_SUB_FDISC_FAILED: - ZFCP_LOG_INFO("Local link to adapter %s is down " - "due to failed FDISC login\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&adapter->ccw_device->dev, + "Local link is down " + "due to failed FDISC login.\n"); zfcp_fsf_link_down_info_eval(fsf_req, 39, (struct fsf_link_down_info *) &status_buffer->payload); break; case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: - ZFCP_LOG_INFO("Local link to adapter %s is down " - "due to firmware update on adapter\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&adapter->ccw_device->dev, + "Local link is down " + "due to firmware update on adapter.\n"); zfcp_fsf_link_down_info_eval(fsf_req, 40, NULL); break; default: - ZFCP_LOG_INFO("Local link to adapter %s is down " - "due to unknown reason\n", - zfcp_get_busid_by_adapter(adapter)); + dev_warn(&adapter->ccw_device->dev, + "Local link is down.\n"); zfcp_fsf_link_down_info_eval(fsf_req, 41, NULL); }; break; case FSF_STATUS_READ_LINK_UP: - ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. " - "Restarting operations on this adapter\n", - zfcp_get_busid_by_adapter(adapter)); + dev_info(&adapter->ccw_device->dev, + "Local link was replugged.\n"); /* All ports should be marked as ready to run again */ zfcp_erp_modify_adapter_status(adapter, 30, NULL, ZFCP_STATUS_COMMON_RUNNING, @@ -935,81 +871,18 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_STATUS_READ_NOTIFICATION_LOST: - ZFCP_LOG_NORMAL("Unsolicited status notification(s) lost: " - "adapter %s%s%s%s%s%s%s%s%s\n", - zfcp_get_busid_by_adapter(adapter), - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_INCOMING_ELS) ? - ", incoming ELS" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_SENSE_DATA) ? - ", sense data" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_LINK_STATUS) ? - ", link status change" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_PORT_CLOSED) ? - ", port close" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD) ? - ", bit error exception" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_ACT_UPDATED) ? - ", ACT update" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_ACT_HARDENED) ? - ", ACT hardening" : "", - (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT) ? - ", adapter feature change" : ""); - if (status_buffer->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) zfcp_erp_adapter_access_changed(adapter, 135, fsf_req); break; case FSF_STATUS_READ_CFDC_UPDATED: - ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); zfcp_erp_adapter_access_changed(adapter, 136, fsf_req); break; - case FSF_STATUS_READ_CFDC_HARDENED: - switch (status_buffer->status_subtype) { - case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE: - ZFCP_LOG_NORMAL("CFDC of adapter %s saved on SE\n", - zfcp_get_busid_by_adapter(adapter)); - break; - case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2: - ZFCP_LOG_NORMAL("CFDC of adapter %s has been copied " - "to the secondary SE\n", - zfcp_get_busid_by_adapter(adapter)); - break; - default: - ZFCP_LOG_NORMAL("CFDC of adapter %s has been hardened\n", - zfcp_get_busid_by_adapter(adapter)); - } - break; - case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: - ZFCP_LOG_INFO("List of supported features on adapter %s has " - "been changed from 0x%08X to 0x%08X\n", - zfcp_get_busid_by_adapter(adapter), - *(u32*) (status_buffer->payload + 4), - *(u32*) (status_buffer->payload)); adapter->adapter_features = *(u32*) status_buffer->payload; break; - - default: - ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown " - "type was received (debug info 0x%x)\n", - status_buffer->status_type); - ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n", - status_buffer); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) status_buffer, - sizeof (struct fsf_status_read_buffer)); - break; } mempool_free(status_buffer, adapter->pool.data_status_read); zfcp_fsf_req_free(fsf_req); @@ -1060,15 +933,8 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, retval = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, req_flags, adapter->pool.fsf_req_abort, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Failed to create an abort command " - "request for lun 0x%016Lx on port 0x%016Lx " - "on adapter %s.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_adapter(adapter)); + if (retval < 0) goto out; - } if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))) @@ -1134,17 +1000,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) * fine. */ } else { - ZFCP_LOG_INFO("Temporary port identifier 0x%x for " - "port 0x%016Lx on adapter %s invalid. " - "This may happen occasionally.\n", - unit->port->handle, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - ZFCP_LOG_INFO("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, - (char *) &new_fsf_req->qtcb->header. - fsf_status_qual, - sizeof (union fsf_status_qual)); /* Let's hope this sorts out the mess */ zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104, new_fsf_req); @@ -1160,20 +1015,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) * This is fine. */ } else { - ZFCP_LOG_INFO - ("Warning: Temporary LUN identifier 0x%x of LUN " - "0x%016Lx on port 0x%016Lx on adapter %s is " - "invalid. This may happen in rare cases. " - "Trying to re-establish link.\n", - unit->handle, - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - ZFCP_LOG_DEBUG("Status qualifier data:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &new_fsf_req->qtcb->header. - fsf_status_qual, - sizeof (union fsf_status_qual)); /* Let's hope this sorts out the mess */ zfcp_erp_port_reopen(unit->port, 0, 105, new_fsf_req); new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1186,20 +1027,12 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) break; case FSF_PORT_BOXED: - ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to " - "be reopened\n", unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); zfcp_erp_port_boxed(unit->port, 47, new_fsf_req); new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; break; case FSF_LUN_BOXED: - ZFCP_LOG_INFO( - "unit 0x%016Lx on port 0x%016Lx on adapter %s needs " - "to be reopened\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); zfcp_erp_unit_boxed(unit, 48, new_fsf_req); new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; @@ -1215,11 +1048,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) /* SCSI stack will escalate */ new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - default: - ZFCP_LOG_NORMAL - ("bug: Wrong status qualifier 0x%x arrived.\n", - new_fsf_req->qtcb->header.fsf_status_qual.word[0]); - break; } break; @@ -1227,12 +1055,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) retval = 0; new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED; break; - - default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", - new_fsf_req->qtcb->header.fsf_status); - break; } skip_fsfstatus: return retval; @@ -1287,12 +1109,8 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, ret = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC, ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, pool, &lock_flags, &fsf_req); - if (ret < 0) { - ZFCP_LOG_INFO("error: Could not create CT request (FC-GS) for " - "adapter: %s\n", - zfcp_get_busid_by_adapter(adapter)); + if (ret < 0) goto failed_req; - } sbale = zfcp_qdio_sbale_req(fsf_req); if (zfcp_use_one_sbal(ct->req, ct->req_count, @@ -1313,9 +1131,6 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, ct->req, ZFCP_MAX_SBALS_PER_CT_REQ); if (bytes <= 0) { - ZFCP_LOG_INFO("error: creation of CT request failed " - "on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); if (bytes == 0) ret = -ENOMEM; else @@ -1330,9 +1145,6 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, ct->resp, ZFCP_MAX_SBALS_PER_CT_REQ); if (bytes <= 0) { - ZFCP_LOG_INFO("error: creation of CT request failed " - "on adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); if (bytes == 0) ret = -ENOMEM; else @@ -1343,10 +1155,6 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, fsf_req->qtcb->bottom.support.resp_buf_length = bytes; } else { /* reject send generic request */ - ZFCP_LOG_INFO( - "error: microcode does not support chained SBALs," - "CT request too big (adapter %s)\n", - zfcp_get_busid_by_adapter(adapter)); ret = -EOPNOTSUPP; goto failed_send; } @@ -1368,15 +1176,9 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); ret = zfcp_fsf_req_send(fsf_req); - if (ret) { - ZFCP_LOG_DEBUG("error: initiation of CT request failed " - "(adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(adapter), port->wwpn); + if (ret) goto failed_send; - } - ZFCP_LOG_DEBUG("CT request initiated (adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(adapter), port->wwpn); goto out; failed_send: @@ -1408,7 +1210,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) struct fsf_qtcb_header *header; struct fsf_qtcb_bottom_support *bottom; int retval = -EINVAL; - u16 subtable, rule, counter; adapter = fsf_req->adapter; send_ct = (struct zfcp_send_ct *) fsf_req->data; @@ -1428,13 +1229,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: - ZFCP_LOG_INFO("error: adapter %s does not support fc " - "class %d.\n", - zfcp_get_busid_by_port(port), - ZFCP_FC_SERVICE_CLASS_DEFAULT); - /* stop operation for this adapter */ - zfcp_erp_adapter_shutdown(adapter, 0, 123, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_class_not_supp(fsf_req); break; case FSF_ADAPTER_STATUS_AVAILABLE: @@ -1448,63 +1243,23 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) /* ERP strategy will escalate */ fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - default: - ZFCP_LOG_INFO("bug: Wrong status qualifier 0x%x " - "arrived.\n", - header->fsf_status_qual.word[0]); - break; } break; case FSF_ACCESS_DENIED: - ZFCP_LOG_NORMAL("access denied, cannot send generic service " - "command (adapter %s, port d_id=0x%06x)\n", - zfcp_get_busid_by_port(port), port->d_id); - for (counter = 0; counter < 2; counter++) { - subtable = header->fsf_status_qual.halfword[counter * 2]; - rule = header->fsf_status_qual.halfword[counter * 2 + 1]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_INFO("Access denied (%s rule %d)\n", - zfcp_act_subtable_type[subtable], rule); - break; - } - } - zfcp_erp_port_access_denied(port, 55, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_access_denied_port(fsf_req, port); break; case FSF_GENERIC_COMMAND_REJECTED: - ZFCP_LOG_INFO("generic service command rejected " - "(adapter %s, port d_id=0x%06x)\n", - zfcp_get_busid_by_port(port), port->d_id); - ZFCP_LOG_INFO("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_HANDLE_NOT_VALID: - ZFCP_LOG_DEBUG("Temporary port identifier 0x%x for port " - "0x%016Lx on adapter %s invalid. This may " - "happen occasionally.\n", port->handle, - port->wwpn, zfcp_get_busid_by_port(port)); - ZFCP_LOG_INFO("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(adapter, 0, 106, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - ZFCP_LOG_INFO("port needs to be reopened " - "(adapter %s, port d_id=0x%06x)\n", - zfcp_get_busid_by_port(port), port->d_id); zfcp_erp_port_boxed(port, 49, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; @@ -1513,37 +1268,13 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) /* following states should never occure, all cases avoided in zfcp_fsf_send_ct - but who knows ... */ case FSF_PAYLOAD_SIZE_MISMATCH: - ZFCP_LOG_INFO("payload size mismatch (adapter: %s, " - "req_buf_length=%d, resp_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->req_buf_length, bottom->resp_buf_length); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_REQUEST_SIZE_TOO_LARGE: - ZFCP_LOG_INFO("request size too large (adapter: %s, " - "req_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->req_buf_length); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_RESPONSE_SIZE_TOO_LARGE: - ZFCP_LOG_INFO("response size too large (adapter: %s, " - "resp_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->resp_buf_length); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_SBAL_MISMATCH: - ZFCP_LOG_INFO("SBAL mismatch (adapter: %s, req_buf_length=%d, " - "resp_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->req_buf_length, bottom->resp_buf_length); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", header->fsf_status); break; } @@ -1578,12 +1309,8 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) ret = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, ZFCP_REQ_AUTO_CLEANUP, NULL, &lock_flags, &fsf_req); - if (ret < 0) { - ZFCP_LOG_INFO("error: creation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); + if (ret < 0) goto failed_req; - } if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &els->port->status))) { @@ -1610,9 +1337,6 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) els->req, ZFCP_MAX_SBALS_PER_ELS_REQ); if (bytes <= 0) { - ZFCP_LOG_INFO("error: creation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); if (bytes == 0) { ret = -ENOMEM; } else { @@ -1627,9 +1351,6 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) els->resp, ZFCP_MAX_SBALS_PER_ELS_REQ); if (bytes <= 0) { - ZFCP_LOG_INFO("error: creation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); if (bytes == 0) { ret = -ENOMEM; } else { @@ -1640,10 +1361,6 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) fsf_req->qtcb->bottom.support.resp_buf_length = bytes; } else { /* reject request */ - ZFCP_LOG_INFO("error: microcode does not support chained SBALs" - ", ELS request too big (adapter %s, " - "port d_id: 0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); ret = -EOPNOTSUPP; goto failed_send; } @@ -1661,15 +1378,9 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); ret = zfcp_fsf_req_send(fsf_req); - if (ret) { - ZFCP_LOG_DEBUG("error: initiation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); + if (ret) goto failed_send; - } - ZFCP_LOG_DEBUG("ELS request initiated (adapter %s, port d_id: " - "0x%06x)\n", zfcp_get_busid_by_adapter(adapter), d_id); goto out; port_blocked: @@ -1701,7 +1412,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) struct fsf_qtcb_bottom_support *bottom; struct zfcp_send_els *send_els; int retval = -EINVAL; - u16 subtable, rule, counter; send_els = (struct zfcp_send_els *) fsf_req->data; adapter = send_els->adapter; @@ -1721,13 +1431,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: - ZFCP_LOG_INFO("error: adapter %s does not support fc " - "class %d.\n", - zfcp_get_busid_by_adapter(adapter), - ZFCP_FC_SERVICE_CLASS_DEFAULT); - /* stop operation for this adapter */ - zfcp_erp_adapter_shutdown(adapter, 0, 124, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_class_not_supp(fsf_req); break; case FSF_ADAPTER_STATUS_AVAILABLE: @@ -1743,91 +1447,25 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) case FSF_SQ_RETRY_IF_POSSIBLE: fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - default: - ZFCP_LOG_INFO("bug: Wrong status qualifier 0x%x\n", - header->fsf_status_qual.word[0]); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, - (char*)header->fsf_status_qual.word, 16); } break; case FSF_ELS_COMMAND_REJECTED: - ZFCP_LOG_INFO("ELS has been rejected because command filter " - "prohibited sending " - "(adapter: %s, port d_id: 0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); - - break; - case FSF_PAYLOAD_SIZE_MISMATCH: - ZFCP_LOG_INFO( - "ELS request size and ELS response size must be either " - "both 0, or both greater than 0 " - "(adapter: %s, req_buf_length=%d resp_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->req_buf_length, - bottom->resp_buf_length); - break; - case FSF_REQUEST_SIZE_TOO_LARGE: - ZFCP_LOG_INFO( - "Length of the ELS request buffer, " - "specified in QTCB bottom, " - "exceeds the size of the buffers " - "that have been allocated for ELS request data " - "(adapter: %s, req_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->req_buf_length); - break; - case FSF_RESPONSE_SIZE_TOO_LARGE: - ZFCP_LOG_INFO( - "Length of the ELS response buffer, " - "specified in QTCB bottom, " - "exceeds the size of the buffers " - "that have been allocated for ELS response data " - "(adapter: %s, resp_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->resp_buf_length); break; case FSF_SBAL_MISMATCH: /* should never occure, avoided in zfcp_fsf_send_els */ - ZFCP_LOG_INFO("SBAL mismatch (adapter: %s, req_buf_length=%d, " - "resp_buf_length=%d)\n", - zfcp_get_busid_by_adapter(adapter), - bottom->req_buf_length, bottom->resp_buf_length); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ACCESS_DENIED: - ZFCP_LOG_NORMAL("access denied, cannot send ELS command " - "(adapter %s, port d_id=0x%06x)\n", - zfcp_get_busid_by_adapter(adapter), d_id); - for (counter = 0; counter < 2; counter++) { - subtable = header->fsf_status_qual.halfword[counter * 2]; - rule = header->fsf_status_qual.halfword[counter * 2 + 1]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_INFO("Access denied (%s rule %d)\n", - zfcp_act_subtable_type[subtable], rule); - break; - } - } - if (port != NULL) - zfcp_erp_port_access_denied(port, 56, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_access_denied_port(fsf_req, port); break; default: - ZFCP_LOG_NORMAL( - "bug: An unknown FSF Status was presented " - "(adapter: %s, fsf_status=0x%08x)\n", - zfcp_get_busid_by_adapter(adapter), - header->fsf_status); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } @@ -1857,9 +1495,6 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not create exchange configuration " - "data request for adapter %s.\n", - zfcp_get_busid_by_adapter(adapter)); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } @@ -1880,16 +1515,9 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) retval = zfcp_fsf_req_send(fsf_req); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); if (retval) { - ZFCP_LOG_INFO("error: Could not send exchange configuration " - "data command on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; } - else - ZFCP_LOG_DEBUG("exchange configuration data request initiated " - "(adapter %s)\n", - zfcp_get_busid_by_adapter(adapter)); return retval; } @@ -1908,9 +1536,6 @@ zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags, &fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not create exchange configuration " - "data request for adapter %s.\n", - zfcp_get_busid_by_adapter(adapter)); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } @@ -1931,11 +1556,7 @@ zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(fsf_req); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - if (retval) - ZFCP_LOG_INFO("error: Could not send exchange configuration " - "data command on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - else + if (!retval) wait_event(fsf_req->completion_wq, fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); @@ -1959,8 +1580,6 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) struct Scsi_Host *shost = adapter->scsi_host; bottom = &fsf_req->qtcb->bottom.config; - ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n", - bottom->low_qtcb_version, bottom->high_qtcb_version); adapter->fsf_lic_version = bottom->lic_version; adapter->adapter_features = bottom->adapter_features; adapter->connection_features = bottom->connection_features; @@ -2013,36 +1632,17 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) min(FC_SERIAL_NUMBER_SIZE, 17)); } - if (fsf_req->erp_action) - ZFCP_LOG_NORMAL("The adapter %s reported the following " - "characteristics:\n" - "WWNN 0x%016Lx, WWPN 0x%016Lx, " - "S_ID 0x%06x,\n" - "adapter version 0x%x, " - "LIC version 0x%x, " - "FC link speed %d Gb/s\n", - zfcp_get_busid_by_adapter(adapter), - (wwn_t) fc_host_node_name(shost), - (wwn_t) fc_host_port_name(shost), - fc_host_port_id(shost), - adapter->hydra_version, - adapter->fsf_lic_version, - fc_host_speed(shost)); if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) { - ZFCP_LOG_NORMAL("error: the adapter %s " - "only supports newer control block " - "versions in comparison to this device " - "driver (try updated device driver)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "The adapter only supports newer control block " + "versions, try updated device driver.\n"); zfcp_erp_adapter_shutdown(adapter, 0, 125, fsf_req); return -EIO; } if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) { - ZFCP_LOG_NORMAL("error: the adapter %s " - "only supports older control block " - "versions than this device driver uses" - "(consider a microcode upgrade)\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "The adapter only supports older control block " + "versions, consider a microcode upgrade.\n"); zfcp_erp_adapter_shutdown(adapter, 0, 126, fsf_req); return -EIO; } @@ -2074,50 +1674,38 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) switch (fc_host_port_type(adapter->scsi_host)) { case FC_PORTTYPE_PTP: - ZFCP_LOG_NORMAL("Point-to-Point fibrechannel " - "configuration detected at adapter %s\n" - "Peer WWNN 0x%016llx, " - "peer WWPN 0x%016llx, " - "peer d_id 0x%06x\n", - zfcp_get_busid_by_adapter(adapter), - adapter->peer_wwnn, - adapter->peer_wwpn, - adapter->peer_d_id); + if (fsf_req->erp_action) + dev_info(&adapter->ccw_device->dev, + "Point-to-Point fibrechannel " + "configuration detected.\n"); break; case FC_PORTTYPE_NLPORT: - ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " - "topology detected at adapter %s " - "unsupported, shutting down adapter\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "Unsupported arbitrated loop fibrechannel " + "topology detected, shutting down adapter\n"); zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req); return -EIO; case FC_PORTTYPE_NPORT: if (fsf_req->erp_action) - ZFCP_LOG_NORMAL("Switched fabric fibrechannel " - "network detected at adapter " - "%s.\n", - zfcp_get_busid_by_adapter(adapter)); + dev_info(&adapter->ccw_device->dev, + "Switched fabric fibrechannel " + "network detected.\n"); break; default: - ZFCP_LOG_NORMAL("bug: The fibrechannel topology " - "reported by the exchange " - "configuration command for " - "the adapter %s is not " - "of a type known to the zfcp " - "driver, shutting down adapter\n", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "The fibrechannel topology reported by the " + "adapter is not known by the zfcp driver, " + "shutting down adapter.\n"); zfcp_erp_adapter_shutdown(adapter, 0, 128, fsf_req); return -EIO; } bottom = &qtcb->bottom.config; if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { - ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) " - "allowed by the adapter %s " - "is lower than the minimum " - "required by the driver (%ld bytes).\n", - bottom->max_qtcb_size, - zfcp_get_busid_by_adapter(adapter), - sizeof(struct fsf_qtcb)); + dev_err(&adapter->ccw_device->dev, + "Maximum QTCB size (%d bytes) allowed by " + "the adapter is lower than the minimum " + "required by the driver (%ld bytes).\n", + bottom->max_qtcb_size, sizeof(struct fsf_qtcb)); zfcp_erp_adapter_shutdown(adapter, 0, 129, fsf_req); return -EIO; } @@ -2154,12 +1742,8 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) unsigned long lock_flags; int retval; - if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { - ZFCP_LOG_INFO("error: exchange port data " - "command not supported by adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - } /* setup new FSF request */ retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, @@ -2167,10 +1751,6 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Out of resources. Could not create an " - "exchange port data request for " - "the adapter %s.\n", - zfcp_get_busid_by_adapter(adapter)); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } @@ -2187,16 +1767,9 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); if (retval) { - ZFCP_LOG_INFO("error: Could not send an exchange port data " - "command on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; } - else - ZFCP_LOG_DEBUG("exchange port data request initiated " - "(adapter %s)\n", - zfcp_get_busid_by_adapter(adapter)); return retval; } @@ -2214,21 +1787,13 @@ zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, unsigned long lock_flags; int retval; - if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { - ZFCP_LOG_INFO("error: exchange port data " - "command not supported by adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); + if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - } /* setup new FSF request */ retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, NULL, &lock_flags, &fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Out of resources. Could not create an " - "exchange port data request for " - "the adapter %s.\n", - zfcp_get_busid_by_adapter(adapter)); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); return retval; } @@ -2244,11 +1809,7 @@ zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, retval = zfcp_fsf_req_send(fsf_req); write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - if (retval) - ZFCP_LOG_INFO("error: Could not send an exchange port data " - "command on the adapter %s\n", - zfcp_get_busid_by_adapter(adapter)); - else + if (!retval) wait_event(fsf_req->completion_wq, fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); @@ -2338,13 +1899,8 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, erp_action->adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create open port request " - "for port 0x%016Lx on adapter %s.\n", - erp_action->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); + if (retval < 0) goto out; - } sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; @@ -2359,19 +1915,11 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not send open port request for " - "port 0x%016Lx on adapter %s.\n", - erp_action->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; goto out; } - ZFCP_LOG_DEBUG("open port request initiated " - "(adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn); out: write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; @@ -2391,7 +1939,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) struct zfcp_port *port; struct fsf_plogi *plogi; struct fsf_qtcb_header *header; - u16 subtable, rule, counter; port = (struct zfcp_port *) fsf_req->data; header = &fsf_req->qtcb->header; @@ -2405,9 +1952,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) switch (header->fsf_status) { case FSF_PORT_ALREADY_OPEN: - ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s " - "is already open.\n", - port->wwpn, zfcp_get_busid_by_port(port)); /* * This is a bug, however operation should continue normally * if it is simply ignored @@ -2415,31 +1959,14 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_ACCESS_DENIED: - ZFCP_LOG_NORMAL("Access denied, cannot open port 0x%016Lx " - "on adapter %s\n", - port->wwpn, zfcp_get_busid_by_port(port)); - for (counter = 0; counter < 2; counter++) { - subtable = header->fsf_status_qual.halfword[counter * 2]; - rule = header->fsf_status_qual.halfword[counter * 2 + 1]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_INFO("Access denied (%s rule %d)\n", - zfcp_act_subtable_type[subtable], rule); - break; - } - } - zfcp_erp_port_access_denied(port, 57, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_access_denied_port(fsf_req, port); break; case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: - ZFCP_LOG_INFO("error: The FSF adapter is out of resources. " - "The remote port 0x%016Lx on adapter %s " - "could not be opened. Disabling it.\n", - port->wwpn, zfcp_get_busid_by_port(port)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The adapter is out of resources. The remote port " + "0x%016Lx could not be opened, disabling it.\n", + port->wwpn); zfcp_erp_port_failed(port, 31, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -2455,18 +1982,13 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_NO_RETRY_POSSIBLE: - ZFCP_LOG_NORMAL("The remote port 0x%016Lx on " - "adapter %s could not be opened. " - "Disabling it.\n", - port->wwpn, - zfcp_get_busid_by_port(port)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The remote port 0x%016Lx could not be " + "opened. Disabling it.\n", port->wwpn); zfcp_erp_port_failed(port, 32, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; default: - ZFCP_LOG_NORMAL - ("bug: Wrong status qualifier 0x%x arrived.\n", - header->fsf_status_qual.word[0]); break; } break; @@ -2474,10 +1996,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) case FSF_GOOD: /* save port handle assigned by FSF */ port->handle = header->port_handle; - ZFCP_LOG_INFO("The remote port 0x%016Lx via adapter %s " - "was opened, it's port handle is 0x%x\n", - port->wwpn, zfcp_get_busid_by_port(port), - port->handle); /* mark port as open */ atomic_set_mask(ZFCP_STATUS_COMMON_OPEN | ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); @@ -2505,16 +2023,9 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) { if (fsf_req->qtcb->bottom.support.els1_length < sizeof (struct fsf_plogi)) { - ZFCP_LOG_INFO( - "warning: insufficient length of " - "PLOGI payload (%i)\n", - fsf_req->qtcb->bottom.support.els1_length); /* skip sanity check and assume wwpn is ok */ } else { if (plogi->serv_param.wwpn != port->wwpn) { - ZFCP_LOG_INFO("warning: d_id of port " - "0x%016Lx changed during " - "open\n", port->wwpn); atomic_clear_mask( ZFCP_STATUS_PORT_DID_DID, &port->status); @@ -2528,17 +2039,10 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) case FSF_UNKNOWN_OP_SUBTYPE: /* should never occure, subtype not set in zfcp_fsf_open_port */ - ZFCP_LOG_INFO("unknown operation subtype (adapter: %s, " - "op_subtype=0x%x)\n", - zfcp_get_busid_by_port(port), - fsf_req->qtcb->bottom.support.operation_subtype); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", - header->fsf_status); break; } @@ -2569,13 +2073,8 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, erp_action->adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create a close port request " - "for port 0x%016Lx on adapter %s.\n", - erp_action->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); + if (retval < 0) goto out; - } sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; @@ -2591,19 +2090,11 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not send a close port request for " - "port 0x%016Lx on adapter %s.\n", - erp_action->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; goto out; } - ZFCP_LOG_TRACE("close port request initiated " - "(adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn); out: write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; @@ -2633,14 +2124,6 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) switch (fsf_req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary port identifier 0x%x for port " - "0x%016Lx on adapter %s invalid. This may happen " - "occasionally.\n", port->handle, - port->wwpn, zfcp_get_busid_by_port(port)); - ZFCP_LOG_DEBUG("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb->header.fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(port->adapter, 0, 107, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -2653,20 +2136,11 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_GOOD: - ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, " - "port handle 0x%x\n", port->wwpn, - zfcp_get_busid_by_port(port), port->handle); zfcp_erp_modify_port_status(port, 33, fsf_req, ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); retval = 0; break; - - default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", - fsf_req->qtcb->header.fsf_status); - break; } skip_fsfstatus: @@ -2696,14 +2170,8 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, erp_action->adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create close physical port " - "request (adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn); - + if (retval < 0) goto out; - } sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; @@ -2721,19 +2189,11 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not send close physical port " - "request (adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; goto out; } - ZFCP_LOG_TRACE("close physical port request initiated " - "(adapter %s, port 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn); out: write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; @@ -2753,7 +2213,6 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) struct zfcp_port *port; struct zfcp_unit *unit; struct fsf_qtcb_header *header; - u16 subtable, rule, counter; port = (struct zfcp_port *) fsf_req->data; header = &fsf_req->qtcb->header; @@ -2767,47 +2226,15 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) switch (header->fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary port identifier 0x%x invalid" - "(adapter %s, port 0x%016Lx). " - "This may happen occasionally.\n", - port->handle, - zfcp_get_busid_by_port(port), - port->wwpn); - ZFCP_LOG_DEBUG("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(port->adapter, 0, 108, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ACCESS_DENIED: - ZFCP_LOG_NORMAL("Access denied, cannot close " - "physical port 0x%016Lx on adapter %s\n", - port->wwpn, zfcp_get_busid_by_port(port)); - for (counter = 0; counter < 2; counter++) { - subtable = header->fsf_status_qual.halfword[counter * 2]; - rule = header->fsf_status_qual.halfword[counter * 2 + 1]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_INFO("Access denied (%s rule %d)\n", - zfcp_act_subtable_type[subtable], rule); - break; - } - } - zfcp_erp_port_access_denied(port, 58, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_access_denied_port(fsf_req, port); break; case FSF_PORT_BOXED: - ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter " - "%s needs to be reopened but it was attempted " - "to close it physically.\n", - port->wwpn, - zfcp_get_busid_by_port(port)); zfcp_erp_port_boxed(port, 50, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; @@ -2830,19 +2257,10 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) /* ERP strategy will escalate */ fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - default: - ZFCP_LOG_NORMAL - ("bug: Wrong status qualifier 0x%x arrived.\n", - header->fsf_status_qual.word[0]); - break; } break; case FSF_GOOD: - ZFCP_LOG_DEBUG("Remote port 0x%016Lx via adapter %s " - "physically closed, port handle 0x%x\n", - port->wwpn, - zfcp_get_busid_by_port(port), port->handle); /* can't use generic zfcp_erp_modify_port_status because * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ @@ -2851,12 +2269,6 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); retval = 0; break; - - default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", - header->fsf_status); - break; } skip_fsfstatus: @@ -2890,14 +2302,8 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, erp_action->adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create open unit request for " - "unit 0x%016Lx on port 0x%016Lx on adapter %s.\n", - erp_action->unit->fcp_lun, - erp_action->unit->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); + if (retval < 0) goto out; - } sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; @@ -2916,21 +2322,10 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(erp_action->fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not send an open unit request " - "on the adapter %s, port 0x%016Lx for " - "unit 0x%016Lx\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn, - erp_action->unit->fcp_lun); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; goto out; } - - ZFCP_LOG_TRACE("Open LUN request initiated (adapter %s, " - "port 0x%016Lx, unit 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn, erp_action->unit->fcp_lun); out: write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; @@ -2952,7 +2347,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) struct fsf_qtcb_header *header; struct fsf_qtcb_bottom_support *bottom; struct fsf_queue_designator *queue_designator; - u16 subtable, rule, counter; int exclusive, readwrite; unit = (struct zfcp_unit *) fsf_req->data; @@ -2977,55 +2371,21 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) switch (header->fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary port identifier 0x%x " - "for port 0x%016Lx on adapter %s invalid " - "This may happen occasionally\n", - unit->port->handle, - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); - ZFCP_LOG_DEBUG("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_ALREADY_OPEN: - ZFCP_LOG_NORMAL("bug: Attempted to open unit 0x%016Lx on " - "remote port 0x%016Lx on adapter %s twice.\n", - unit->fcp_lun, - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ACCESS_DENIED: - ZFCP_LOG_NORMAL("Access denied, cannot open unit 0x%016Lx on " - "remote port 0x%016Lx on adapter %s\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - for (counter = 0; counter < 2; counter++) { - subtable = header->fsf_status_qual.halfword[counter * 2]; - rule = header->fsf_status_qual.halfword[counter * 2 + 1]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_INFO("Access denied (%s rule %d)\n", - zfcp_act_subtable_type[subtable], rule); - break; - } - } - zfcp_erp_unit_access_denied(unit, 59, fsf_req); + zfcp_fsf_access_denied_unit(fsf_req, unit); atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); - atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); break; case FSF_PORT_BOXED: - ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " - "needs to be reopened\n", - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); zfcp_erp_port_boxed(unit->port, 51, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; @@ -3033,39 +2393,18 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) case FSF_LUN_SHARING_VIOLATION: if (header->fsf_status_qual.word[0] != 0) { - ZFCP_LOG_NORMAL("FCP-LUN 0x%Lx at the remote port " - "with WWPN 0x%Lx " - "connected to the adapter %s " - "is already in use in LPAR%d, CSS%d\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - queue_designator->hla, - queue_designator->cssid); - } else { - subtable = header->fsf_status_qual.halfword[4]; - rule = header->fsf_status_qual.halfword[5]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_NORMAL("Access to FCP-LUN 0x%Lx at the " - "remote port with WWPN 0x%Lx " - "connected to the adapter %s " - "is denied (%s rule %d)\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - zfcp_act_subtable_type[subtable], - rule); - break; - } - } - ZFCP_LOG_DEBUG("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); + dev_warn(&adapter->ccw_device->dev, + "FCP-LUN 0x%Lx at the remote port " + "with WWPN 0x%Lx " + "connected to the adapter " + "is already in use in LPAR%d, CSS%d.\n", + unit->fcp_lun, + unit->port->wwpn, + queue_designator->hla, + queue_designator->cssid); + } else + zfcp_act_eval_err(adapter, + header->fsf_status_qual.word[2]); zfcp_erp_unit_access_denied(unit, 60, fsf_req); atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); @@ -3073,13 +2412,10 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) break; case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: - ZFCP_LOG_INFO("error: The adapter ran out of resources. " - "There is no handle (temporary port identifier) " - "available for unit 0x%016Lx on port 0x%016Lx " - "on adapter %s\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); + dev_warn(&fsf_req->adapter->ccw_device->dev, + "The adapter ran out of resources. There is no " + "handle available for unit 0x%016Lx on port 0x%016Lx.", + unit->fcp_lun, unit->port->wwpn); zfcp_erp_unit_failed(unit, 34, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -3095,19 +2431,10 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) /* ERP strategy will escalate */ fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - default: - ZFCP_LOG_NORMAL - ("bug: Wrong status qualifier 0x%x arrived.\n", - header->fsf_status_qual.word[0]); } break; case FSF_INVALID_COMMAND_OPTION: - ZFCP_LOG_NORMAL( - "Invalid option 0x%x has been specified " - "in QTCB bottom sent to the adapter %s\n", - bottom->option, - zfcp_get_busid_by_adapter(adapter)); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; retval = -EINVAL; break; @@ -3115,12 +2442,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) case FSF_GOOD: /* save LUN handle assigned by FSF */ unit->handle = header->lun_handle; - ZFCP_LOG_TRACE("unit 0x%016Lx on remote port 0x%016Lx on " - "adapter %s opened, port handle 0x%x\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - unit->handle); /* mark unit as open */ atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); @@ -3139,23 +2460,27 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) if (!readwrite) { atomic_set_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); - ZFCP_LOG_NORMAL("read-only access for unit " - "(adapter %s, wwpn=0x%016Lx, " - "fcp_lun=0x%016Lx)\n", - zfcp_get_busid_by_unit(unit), - unit->port->wwpn, - unit->fcp_lun); + dev_info(&fsf_req->adapter->ccw_device->dev, + "Read-only access for unit 0x%016Lx " + "on port 0x%016Lx.\n", + unit->fcp_lun, unit->port->wwpn); } if (exclusive && !readwrite) { - ZFCP_LOG_NORMAL("exclusive access of read-only " - "unit not supported\n"); + dev_err(&fsf_req->adapter->ccw_device->dev, + "Exclusive access of read-only unit " + "0x%016Lx on port 0x%016Lx not " + "supported, disabling unit.\n", + unit->fcp_lun, unit->port->wwpn); zfcp_erp_unit_failed(unit, 35, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; zfcp_erp_unit_shutdown(unit, 0, 80, fsf_req); } else if (!exclusive && readwrite) { - ZFCP_LOG_NORMAL("shared access of read-write " - "unit not supported\n"); + dev_err(&fsf_req->adapter->ccw_device->dev, + "Shared access of read-write unit " + "0x%016Lx on port 0x%016Lx not " + "supported, disabling unit.\n", + unit->fcp_lun, unit->port->wwpn); zfcp_erp_unit_failed(unit, 36, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; zfcp_erp_unit_shutdown(unit, 0, 81, fsf_req); @@ -3164,12 +2489,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) retval = 0; break; - - default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", - header->fsf_status); - break; } skip_fsfstatus: @@ -3204,14 +2523,8 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, erp_action->adapter->pool.fsf_req_erp, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create close unit request for " - "unit 0x%016Lx on port 0x%016Lx on adapter %s.\n", - erp_action->unit->fcp_lun, - erp_action->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); + if (retval < 0) goto out; - } sbale = zfcp_qdio_sbale_req(fsf_req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; @@ -3227,20 +2540,11 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) zfcp_erp_start_timer(fsf_req); retval = zfcp_fsf_req_send(erp_action->fsf_req); if (retval) { - ZFCP_LOG_INFO("error: Could not send a close unit request for " - "unit 0x%016Lx on port 0x%016Lx onadapter %s.\n", - erp_action->unit->fcp_lun, - erp_action->port->wwpn, - zfcp_get_busid_by_adapter(erp_action->adapter)); zfcp_fsf_req_free(fsf_req); erp_action->fsf_req = NULL; goto out; } - ZFCP_LOG_TRACE("Close LUN request initiated (adapter %s, " - "port 0x%016Lx, unit 0x%016Lx)\n", - zfcp_get_busid_by_adapter(erp_action->adapter), - erp_action->port->wwpn, erp_action->unit->fcp_lun); out: write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; @@ -3270,41 +2574,16 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) switch (fsf_req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary port identifier 0x%x for port " - "0x%016Lx on adapter %s invalid. This may " - "happen in rare circumstances\n", - unit->port->handle, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - ZFCP_LOG_DEBUG("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb->header.fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary LUN identifier 0x%x of unit " - "0x%016Lx on port 0x%016Lx on adapter %s is " - "invalid. This may happen occasionally.\n", - unit->handle, - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - ZFCP_LOG_DEBUG("Status qualifier data:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb->header.fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_port_reopen(unit->port, 0, 111, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " - "needs to be reopened\n", - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); zfcp_erp_port_boxed(unit->port, 52, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; @@ -3322,30 +2601,15 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; default: - ZFCP_LOG_NORMAL - ("bug: Wrong status qualifier 0x%x arrived.\n", - fsf_req->qtcb->header.fsf_status_qual.word[0]); break; } break; case FSF_GOOD: - ZFCP_LOG_TRACE("unit 0x%016Lx on port 0x%016Lx on adapter %s " - "closed, port handle 0x%x\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - unit->handle); /* mark unit as closed */ atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); retval = 0; break; - - default: - ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " - "(debug info 0x%x)\n", - fsf_req->qtcb->header.fsf_status); - break; } skip_fsfstatus: @@ -3379,15 +2643,8 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, adapter->pool.fsf_req_scsi, &lock_flags, &fsf_req); - if (unlikely(retval < 0)) { - ZFCP_LOG_DEBUG("error: Could not create FCP command request " - "for unit 0x%016Lx on port 0x%016Lx on " - "adapter %s\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_adapter(adapter)); + if (unlikely(retval < 0)) goto failed_req_create; - } if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))) { @@ -3463,15 +2720,9 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, fcp_cmnd_iu->task_attribute = UNTAGGED; /* set additional length of FCP_CDB in FCP_CMND IU in QTCB, if needed */ - if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) { + if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) fcp_cmnd_iu->add_fcp_cdb_length = (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2; - ZFCP_LOG_TRACE("SCSI CDB length is 0x%x, " - "additional FCP_CDB length is 0x%x " - "(shifted right 2 bits)\n", - scsi_cmnd->cmd_len, - fcp_cmnd_iu->add_fcp_cdb_length); - } /* * copy SCSI CDB (including additional length, if any) to * FCP_CDB in FCP_CMND IU in QTCB @@ -3488,19 +2739,14 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, scsi_sglist(scsi_cmnd), ZFCP_MAX_SBALS_PER_REQ); if (unlikely(real_bytes < 0)) { - if (fsf_req->sbal_number < ZFCP_MAX_SBALS_PER_REQ) { - ZFCP_LOG_DEBUG( - "Data did not fit into available buffer(s), " - "waiting for more...\n"); + if (fsf_req->sbal_number < ZFCP_MAX_SBALS_PER_REQ) retval = -EIO; - } else { - ZFCP_LOG_NORMAL("error: No truncation implemented but " - "required. Shutting down unit " - "(adapter %s, port 0x%016Lx, " - "unit 0x%016Lx)\n", - zfcp_get_busid_by_unit(unit), - unit->port->wwpn, - unit->fcp_lun); + else { + dev_err(&adapter->ccw_device->dev, + "SCSI request too large. " + "Shutting down unit 0x%016Lx on port " + "0x%016Lx.\n", unit->fcp_lun, + unit->port->wwpn); zfcp_erp_unit_shutdown(unit, 0, 131, fsf_req); retval = -EINVAL; } @@ -3510,28 +2756,13 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, /* set length of FCP data length in FCP_CMND IU in QTCB */ zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes); - ZFCP_LOG_DEBUG("Sending SCSI command:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) scsi_cmnd->cmnd, scsi_cmnd->cmd_len); - if (use_timer) zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(fsf_req); - if (unlikely(retval < 0)) { - ZFCP_LOG_INFO("error: Could not send FCP command request " - "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n", - zfcp_get_busid_by_adapter(adapter), - unit->port->wwpn, - unit->fcp_lun); + if (unlikely(retval < 0)) goto send_failed; - } - ZFCP_LOG_TRACE("Send FCP Command initiated (adapter %s, " - "port 0x%016Lx, unit 0x%016Lx)\n", - zfcp_get_busid_by_adapter(adapter), - unit->port->wwpn, - unit->fcp_lun); goto success; send_failed: @@ -3563,14 +2794,8 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, adapter->pool.fsf_req_scsi, &lock_flags, &fsf_req); - if (retval < 0) { - ZFCP_LOG_INFO("error: Could not create FCP command (task " - "management) request for adapter %s, port " - " 0x%016Lx, unit 0x%016Lx.\n", - zfcp_get_busid_by_adapter(adapter), - unit->port->wwpn, unit->fcp_lun); + if (retval < 0) goto out; - } if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))) @@ -3674,7 +2899,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) int retval = -EINVAL; struct zfcp_unit *unit; struct fsf_qtcb_header *header; - u16 subtable, rule, counter; header = &fsf_req->qtcb->header; @@ -3692,137 +2916,61 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) switch (header->fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary port identifier 0x%x for port " - "0x%016Lx on adapter %s invalid\n", - unit->port->handle, - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_HANDLE_NOT_VALID: - ZFCP_LOG_INFO("Temporary LUN identifier 0x%x for unit " - "0x%016Lx on port 0x%016Lx on adapter %s is " - "invalid. This may happen occasionally.\n", - unit->handle, - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - ZFCP_LOG_NORMAL("Status qualifier data:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_port_reopen(unit->port, 0, 113, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_HANDLE_MISMATCH: - ZFCP_LOG_NORMAL("bug: The port handle 0x%x has changed " - "unexpectedly. (adapter %s, port 0x%016Lx, " - "unit 0x%016Lx)\n", - unit->port->handle, - zfcp_get_busid_by_unit(unit), - unit->port->wwpn, - unit->fcp_lun); - ZFCP_LOG_NORMAL("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_adapter_reopen(unit->port->adapter, 0, 114, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: - ZFCP_LOG_INFO("error: adapter %s does not support fc " - "class %d.\n", - zfcp_get_busid_by_unit(unit), - ZFCP_FC_SERVICE_CLASS_DEFAULT); - /* stop operation for this adapter */ - zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 132, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_class_not_supp(fsf_req); break; case FSF_FCPLUN_NOT_VALID: - ZFCP_LOG_NORMAL("bug: unit 0x%016Lx on port 0x%016Lx on " - "adapter %s does not have correct unit " - "handle 0x%x\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - unit->handle); - ZFCP_LOG_DEBUG("status qualifier:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &header->fsf_status_qual, - sizeof (union fsf_status_qual)); zfcp_erp_port_reopen(unit->port, 0, 115, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ACCESS_DENIED: - ZFCP_LOG_NORMAL("Access denied, cannot send FCP command to " - "unit 0x%016Lx on port 0x%016Lx on " - "adapter %s\n", unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - for (counter = 0; counter < 2; counter++) { - subtable = header->fsf_status_qual.halfword[counter * 2]; - rule = header->fsf_status_qual.halfword[counter * 2 + 1]; - switch (subtable) { - case FSF_SQ_CFDC_SUBTABLE_OS: - case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN: - case FSF_SQ_CFDC_SUBTABLE_PORT_DID: - case FSF_SQ_CFDC_SUBTABLE_LUN: - ZFCP_LOG_INFO("Access denied (%s rule %d)\n", - zfcp_act_subtable_type[subtable], rule); - break; - } - } - zfcp_erp_unit_access_denied(unit, 61, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_access_denied_unit(fsf_req, unit); break; case FSF_DIRECTION_INDICATOR_NOT_VALID: - ZFCP_LOG_INFO("bug: Invalid data direction given for unit " - "0x%016Lx on port 0x%016Lx on adapter %s " - "(debug info %d)\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - fsf_req->qtcb->bottom.io.data_direction); - /* stop operation for this adapter */ + dev_err(&fsf_req->adapter->ccw_device->dev, + "Invalid data direction (%d) given for unit 0x%016Lx " + "on port 0x%016Lx, shutting down adapter.\n", + fsf_req->qtcb->bottom.io.data_direction, + unit->fcp_lun, unit->port->wwpn); zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_CMND_LENGTH_NOT_VALID: - ZFCP_LOG_NORMAL - ("bug: An invalid control-data-block length field " - "was found in a command for unit 0x%016Lx on port " - "0x%016Lx on adapter %s " "(debug info %d)\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - fsf_req->qtcb->bottom.io.fcp_cmnd_length); - /* stop operation for this adapter */ + dev_err(&fsf_req->adapter->ccw_device->dev, + "An invalid control-data-block length field (%d) " + "was found in a command for unit 0x%016Lx on port " + "0x%016Lx. Shutting down adapter.\n", + fsf_req->qtcb->bottom.io.fcp_cmnd_length, + unit->fcp_lun, unit->port->wwpn); zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " - "needs to be reopened\n", - unit->port->wwpn, zfcp_get_busid_by_unit(unit)); zfcp_erp_port_boxed(unit->port, 53, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; break; case FSF_LUN_BOXED: - ZFCP_LOG_NORMAL("unit needs to be reopened (adapter %s, " - "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n", - zfcp_get_busid_by_unit(unit), - unit->port->wwpn, unit->fcp_lun); zfcp_erp_unit_boxed(unit, 54, fsf_req); fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_RETRY; @@ -3838,11 +2986,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) /* FIXME(hw) need proper specs for proper action */ /* let scsi stack deal with retries and escalation */ break; - default: - ZFCP_LOG_NORMAL - ("Unknown status qualifier 0x%x arrived.\n", - header->fsf_status_qual.word[0]); - break; } fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -3880,34 +3023,26 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) struct scsi_cmnd *scpnt; struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) &(fsf_req->qtcb->bottom.io.fcp_rsp); - struct fcp_cmnd_iu *fcp_cmnd_iu = (struct fcp_cmnd_iu *) - &(fsf_req->qtcb->bottom.io.fcp_cmnd); u32 sns_len; char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); unsigned long flags; - struct zfcp_unit *unit = fsf_req->unit; read_lock_irqsave(&fsf_req->adapter->abort_lock, flags); scpnt = (struct scsi_cmnd *) fsf_req->data; - if (unlikely(!scpnt)) { - ZFCP_LOG_DEBUG - ("Command with fsf_req %p is not associated to " - "a scsi command anymore. Aborted?\n", fsf_req); + if (unlikely(!scpnt)) goto out; - } + if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { /* FIXME: (design) mid-layer should handle DID_ABORT like * DID_SOFT_ERROR by retrying the request for devices * that allow retries. */ - ZFCP_LOG_DEBUG("Setting DID_SOFT_ERROR and SUGGEST_RETRY\n"); set_host_byte(&scpnt->result, DID_SOFT_ERROR); set_driver_byte(&scpnt->result, SUGGEST_RETRY); goto skip_fsfstatus; } if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { - ZFCP_LOG_DEBUG("Setting DID_ERROR\n"); set_host_byte(&scpnt->result, DID_ERROR); goto skip_fsfstatus; } @@ -3920,97 +3055,31 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) * of result in SCSI command */ scpnt->result |= fcp_rsp_iu->scsi_status; - if (unlikely(fcp_rsp_iu->scsi_status)) { - /* DEBUG */ - ZFCP_LOG_DEBUG("status for SCSI Command:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - scpnt->cmnd, scpnt->cmd_len); - ZFCP_LOG_DEBUG("SCSI status code 0x%x\n", - fcp_rsp_iu->scsi_status); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (void *) fcp_rsp_iu, sizeof (struct fcp_rsp_iu)); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), - fcp_rsp_iu->fcp_sns_len); - } if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) zfcp_fsf_req_latency(fsf_req); /* check FCP_RSP_INFO */ if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { - ZFCP_LOG_DEBUG("rsp_len is valid\n"); switch (fcp_rsp_info[3]) { case RSP_CODE_GOOD: /* ok, continue */ - ZFCP_LOG_TRACE("no failure or Task Management " - "Function complete\n"); set_host_byte(&scpnt->result, DID_OK); break; case RSP_CODE_LENGTH_MISMATCH: /* hardware bug */ - ZFCP_LOG_NORMAL("bug: FCP response code indictates " - "that the fibrechannel protocol data " - "length differs from the burst length. " - "The problem occured on unit 0x%016Lx " - "on port 0x%016Lx on adapter %s", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - /* dump SCSI CDB as prepared by zfcp */ - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb-> - bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); set_host_byte(&scpnt->result, DID_ERROR); goto skip_fsfstatus; case RSP_CODE_FIELD_INVALID: /* driver or hardware bug */ - ZFCP_LOG_NORMAL("bug: FCP response code indictates " - "that the fibrechannel protocol data " - "fields were incorrectly set up. " - "The problem occured on the unit " - "0x%016Lx on port 0x%016Lx on " - "adapter %s", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - /* dump SCSI CDB as prepared by zfcp */ - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb-> - bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); set_host_byte(&scpnt->result, DID_ERROR); goto skip_fsfstatus; case RSP_CODE_RO_MISMATCH: /* hardware bug */ - ZFCP_LOG_NORMAL("bug: The FCP response code indicates " - "that conflicting values for the " - "fibrechannel payload offset from the " - "header were found. " - "The problem occured on unit 0x%016Lx " - "on port 0x%016Lx on adapter %s.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - /* dump SCSI CDB as prepared by zfcp */ - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb-> - bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); set_host_byte(&scpnt->result, DID_ERROR); goto skip_fsfstatus; default: - ZFCP_LOG_NORMAL("bug: An invalid FCP response " - "code was detected for a command. " - "The problem occured on the unit " - "0x%016Lx on port 0x%016Lx on " - "adapter %s (debug info 0x%x)\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - fcp_rsp_info[3]); - /* dump SCSI CDB as prepared by zfcp */ - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, - (char *) &fsf_req->qtcb-> - bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); + /* invalid FCP response code */ set_host_byte(&scpnt->result, DID_ERROR); goto skip_fsfstatus; } @@ -4020,50 +3089,15 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) { sns_len = FSF_FCP_RSP_SIZE - sizeof (struct fcp_rsp_iu) + fcp_rsp_iu->fcp_rsp_len; - ZFCP_LOG_TRACE("room for %i bytes sense data in QTCB\n", - sns_len); sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE); - ZFCP_LOG_TRACE("room for %i bytes sense data in SCSI command\n", - SCSI_SENSE_BUFFERSIZE); sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len); - ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n", - scpnt->result); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, - scpnt->cmnd, scpnt->cmd_len); - ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n", - fcp_rsp_iu->fcp_sns_len); memcpy(scpnt->sense_buffer, zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, - (void *)scpnt->sense_buffer, sns_len); - } - - /* check for overrun */ - if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_over)) { - ZFCP_LOG_INFO("A data overrun was detected for a command. " - "unit 0x%016Lx, port 0x%016Lx, adapter %s. " - "The response data length is " - "%d, the original length was %d.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - fcp_rsp_iu->fcp_resid, - (int) zfcp_get_fcp_dl(fcp_cmnd_iu)); } /* check for underrun */ if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) { - ZFCP_LOG_INFO("A data underrun was detected for a command. " - "unit 0x%016Lx, port 0x%016Lx, adapter %s. " - "The response data length is " - "%d, the original length was %d.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - fcp_rsp_iu->fcp_resid, - (int) zfcp_get_fcp_dl(fcp_cmnd_iu)); - scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid); if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) < scpnt->underflow) @@ -4071,8 +3105,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) } skip_fsfstatus: - ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); - if (scpnt->result != 0) zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req); else if (scpnt->retries > 0) @@ -4111,7 +3143,6 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) &(fsf_req->qtcb->bottom.io.fcp_rsp); char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); - struct zfcp_unit *unit = (struct zfcp_unit *) fsf_req->data; if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; @@ -4122,36 +3153,15 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) switch (fcp_rsp_info[3]) { case RSP_CODE_GOOD: /* ok, continue */ - ZFCP_LOG_DEBUG("no failure or Task Management " - "Function complete\n"); break; case RSP_CODE_TASKMAN_UNSUPP: - ZFCP_LOG_NORMAL("bug: A reuested task management function " - "is not supported on the target device " - "unit 0x%016Lx, port 0x%016Lx, adapter %s\n ", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP; break; case RSP_CODE_TASKMAN_FAILED: - ZFCP_LOG_NORMAL("bug: A reuested task management function " - "failed to complete successfully. " - "unit 0x%016Lx, port 0x%016Lx, adapter %s.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; break; default: - ZFCP_LOG_NORMAL("bug: An invalid FCP response " - "code was detected for a command. " - "unit 0x%016Lx, port 0x%016Lx, adapter %s " - "(debug info 0x%x)\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit), - fcp_rsp_info[3]); + /* invalid FCP response code */ fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; } @@ -4332,9 +3342,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, /* allocate new FSF request */ fsf_req = zfcp_fsf_req_alloc(pool, req_flags); - if (unlikely(NULL == fsf_req)) { - ZFCP_LOG_DEBUG("error: Could not put an FSF request into " - "the outbound (send) queue.\n"); + if (unlikely(!fsf_req)) { ret = -ENOMEM; goto failed_fsf_req; } @@ -4393,9 +3401,6 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, sbale[1].length = sizeof(struct fsf_qtcb); } - ZFCP_LOG_TRACE("got %i free BUFFERs starting at index %i\n", - fsf_req->sbal_number, fsf_req->sbal_first); - goto success; failed_sbals: @@ -4429,13 +3434,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) adapter = fsf_req->adapter; req_q = &adapter->req_q; - - /* FIXME(debug): remove it later */ sbale = zfcp_qdio_sbale_req(fsf_req); - ZFCP_LOG_DEBUG("SBALE0 flags=0x%x\n", sbale[0].flags); - ZFCP_LOG_TRACE("HEX DUMP OF SBALE1 PAYLOAD:\n"); - ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, - sbale[1].length); /* put allocated FSF request into hash table */ spin_lock(&adapter->req_list_lock); @@ -4476,5 +3475,3 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) } return retval; } - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 598eba9..6ce2f1e 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -1,22 +1,9 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Interface to the FSF support functions. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #ifndef FSF_H @@ -342,6 +329,7 @@ struct fsf_qual_latency_info { } __attribute__ ((packed)); union fsf_prot_status_qual { + u32 word[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u32)]; u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)]; struct fsf_qual_version_error version_error; struct fsf_qual_sequence_error sequence_error; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 4b0c85a..a96e5c3 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -1,26 +1,11 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * Interface to Linux SCSI midlayer. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI - #include "zfcp_ext.h" #include @@ -44,7 +29,7 @@ static struct device_attribute *zfcp_a_stats_attrs[]; struct zfcp_data zfcp_data = { .scsi_host_template = { - .name = ZFCP_NAME, + .name = "zfcp", .module = THIS_MODULE, .proc_name = "zfcp", .slave_alloc = zfcp_scsi_slave_alloc, @@ -64,7 +49,6 @@ struct zfcp_data zfcp_data = { .max_sectors = ZFCP_MAX_SECTORS, .shost_attrs = zfcp_a_stats_attrs, }, - .driver_version = ZFCP_VERSION, }; /* Find start of Response Information in FCP response unit*/ @@ -181,16 +165,14 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp) static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) { struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; - + WARN_ON(!unit); if (unit) { atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); sdpnt->hostdata = NULL; unit->device = NULL; zfcp_erp_unit_failed(unit, 12, NULL); zfcp_unit_put(unit); - } else - ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " - "address %p\n", sdpnt); + } } /* @@ -253,10 +235,6 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, if (unlikely( atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status) || !atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status))) { - ZFCP_LOG_DEBUG("stopping SCSI I/O on unit 0x%016Lx on port " - "0x%016Lx on adapter %s\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_adapter(adapter)); zfcp_scsi_command_fail(scpnt, DID_ERROR); goto out; } @@ -264,18 +242,12 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, tmp = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, use_timer, ZFCP_REQ_AUTO_CLEANUP); if (unlikely(tmp == -EBUSY)) { - ZFCP_LOG_DEBUG("adapter %s not ready or unit 0x%016Lx " - "on port 0x%016Lx in recovery\n", - zfcp_get_busid_by_unit(unit), - unit->fcp_lun, unit->port->wwpn); zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); goto out; } - if (unlikely(tmp < 0)) { - ZFCP_LOG_DEBUG("error: initiation of Send FCP Cmnd failed\n"); + if (unlikely(tmp < 0)) retval = SCSI_MLQUEUE_HOST_BUSY; - } out: return retval; @@ -394,9 +366,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; unit = (struct zfcp_unit *) scpnt->device->hostdata; - ZFCP_LOG_INFO("aborting scsi_cmnd=%p on adapter %s\n", - scpnt, zfcp_get_busid_by_adapter(adapter)); - /* avoid race condition between late normal completion and abort */ write_lock_irqsave(&adapter->abort_lock, flags); @@ -420,7 +389,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) fsf_req = zfcp_fsf_abort_fcp_command(old_req_id, adapter, unit, 0); if (!fsf_req) { - ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, old_req_id); retval = FAILED; @@ -485,10 +453,6 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags, fsf_req = zfcp_fsf_send_fcp_command_task_management (adapter, unit, tm_flags, 0); if (!fsf_req) { - ZFCP_LOG_INFO("error: creation of task management request " - "failed for unit 0x%016Lx on port 0x%016Lx on " - "adapter %s\n", unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_adapter(adapter)); zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt); retval = -ENOMEM; goto out; @@ -524,12 +488,6 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) unit = (struct zfcp_unit*) scpnt->device->hostdata; adapter = unit->port->adapter; - - ZFCP_LOG_NORMAL("host reset because of problems with " - "unit 0x%016Lx on port 0x%016Lx, adapter %s\n", - unit->fcp_lun, unit->port->wwpn, - zfcp_get_busid_by_adapter(unit->port->adapter)); - zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt); zfcp_erp_wait(adapter); @@ -549,13 +507,11 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template, sizeof (struct zfcp_adapter *)); if (!adapter->scsi_host) { - ZFCP_LOG_NORMAL("error: registration with SCSI stack failed " - "for adapter %s ", - zfcp_get_busid_by_adapter(adapter)); + dev_err(&adapter->ccw_device->dev, + "registration with SCSI stack failed."); retval = -EIO; goto out; } - ZFCP_LOG_DEBUG("host registered, scsi_host=%p\n", adapter->scsi_host); /* tell the SCSI stack some characteristics of this adapter */ adapter->scsi_host->max_id = 1; @@ -987,5 +943,3 @@ static struct device_attribute *zfcp_a_stats_attrs[] = { &dev_attr_seconds_active, NULL }; - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index ccbba4d..1f2a8c2 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -1,28 +1,13 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * sysfs attributes for CCW device. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #include "zfcp_ext.h" -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG - /** * ZFCP_DEFINE_ADAPTER_ATTR * @_name: name of show attribute @@ -266,5 +251,3 @@ zfcp_sysfs_adapter_remove_files(struct device *dev) { sysfs_remove_group(&dev->kobj, &zfcp_adapter_attr_group); } - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_sysfs_driver.c b/drivers/s390/scsi/zfcp_sysfs_driver.c deleted file mode 100644 index 651edd5..0000000 --- a/drivers/s390/scsi/zfcp_sysfs_driver.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. - * - * (C) Copyright IBM Corp. 2002, 2006 - * - * 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, 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 "zfcp_ext.h" - -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG - -/** - * ZFCP_DEFINE_DRIVER_ATTR - define for all loglevels sysfs attributes - * @_name: name of attribute - * @_define: name of ZFCP loglevel define - * - * Generates store function for a sysfs loglevel attribute of zfcp driver. - */ -#define ZFCP_DEFINE_DRIVER_ATTR(_name, _define) \ -static ssize_t zfcp_sysfs_loglevel_##_name##_store(struct device_driver *drv, \ - const char *buf, \ - size_t count) \ -{ \ - unsigned int loglevel; \ - unsigned int new_loglevel; \ - char *endp; \ - \ - new_loglevel = simple_strtoul(buf, &endp, 0); \ - if ((endp + 1) < (buf + count)) \ - return -EINVAL; \ - if (new_loglevel > 3) \ - return -EINVAL; \ - down(&zfcp_data.config_sema); \ - loglevel = atomic_read(&zfcp_data.loglevel); \ - loglevel &= ~((unsigned int) 0xf << (ZFCP_LOG_AREA_##_define << 2)); \ - loglevel |= new_loglevel << (ZFCP_LOG_AREA_##_define << 2); \ - atomic_set(&zfcp_data.loglevel, loglevel); \ - up(&zfcp_data.config_sema); \ - return count; \ -} \ - \ -static ssize_t zfcp_sysfs_loglevel_##_name##_show(struct device_driver *dev, \ - char *buf) \ -{ \ - return sprintf(buf,"%d\n", (unsigned int) \ - ZFCP_GET_LOG_VALUE(ZFCP_LOG_AREA_##_define)); \ -} \ - \ -static DRIVER_ATTR(loglevel_##_name, S_IWUSR | S_IRUGO, \ - zfcp_sysfs_loglevel_##_name##_show, \ - zfcp_sysfs_loglevel_##_name##_store); - -ZFCP_DEFINE_DRIVER_ATTR(other, OTHER); -ZFCP_DEFINE_DRIVER_ATTR(scsi, SCSI); -ZFCP_DEFINE_DRIVER_ATTR(fsf, FSF); -ZFCP_DEFINE_DRIVER_ATTR(config, CONFIG); -ZFCP_DEFINE_DRIVER_ATTR(cio, CIO); -ZFCP_DEFINE_DRIVER_ATTR(qdio, QDIO); -ZFCP_DEFINE_DRIVER_ATTR(erp, ERP); -ZFCP_DEFINE_DRIVER_ATTR(fc, FC); - -static ssize_t zfcp_sysfs_version_show(struct device_driver *dev, - char *buf) -{ - return sprintf(buf, "%s\n", zfcp_data.driver_version); -} - -static DRIVER_ATTR(version, S_IRUGO, zfcp_sysfs_version_show, NULL); - -static struct attribute *zfcp_driver_attrs[] = { - &driver_attr_loglevel_other.attr, - &driver_attr_loglevel_scsi.attr, - &driver_attr_loglevel_fsf.attr, - &driver_attr_loglevel_config.attr, - &driver_attr_loglevel_cio.attr, - &driver_attr_loglevel_qdio.attr, - &driver_attr_loglevel_erp.attr, - &driver_attr_loglevel_fc.attr, - &driver_attr_version.attr, - NULL -}; - -static struct attribute_group zfcp_driver_attr_group = { - .attrs = zfcp_driver_attrs, -}; - -struct attribute_group *zfcp_driver_attr_groups[] = { - &zfcp_driver_attr_group, - NULL, -}; - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c index 703c1b5..438675f 100644 --- a/drivers/s390/scsi/zfcp_sysfs_port.c +++ b/drivers/s390/scsi/zfcp_sysfs_port.c @@ -1,28 +1,13 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * sysfs attributes for zfcp port. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #include "zfcp_ext.h" -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG - /** * zfcp_sysfs_port_release - gets called when a struct device port is released * @dev: pointer to belonging device @@ -291,5 +276,3 @@ zfcp_sysfs_port_remove_files(struct device *dev, u32 flags) if (!(flags & ZFCP_STATUS_PORT_WKA)) sysfs_remove_group(&dev->kobj, &zfcp_port_no_ns_attr_group); } - -#undef ZFCP_LOG_AREA diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c index 80fb2c2..587d9e3 100644 --- a/drivers/s390/scsi/zfcp_sysfs_unit.c +++ b/drivers/s390/scsi/zfcp_sysfs_unit.c @@ -1,28 +1,13 @@ /* - * This file is part of the zfcp device driver for - * FCP adapters for IBM System z9 and zSeries. + * zfcp device driver * - * (C) Copyright IBM Corp. 2002, 2006 + * sysfs interface for zfcp unit. * - * 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, 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. + * Copyright IBM Corporation 2002, 2008 */ #include "zfcp_ext.h" -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG - /** * zfcp_sysfs_unit_release - gets called when a struct device unit is released * @dev: pointer to belonging device @@ -163,5 +148,3 @@ zfcp_sysfs_unit_remove_files(struct device *dev) { sysfs_remove_group(&dev->kobj, &zfcp_unit_attr_group); } - -#undef ZFCP_LOG_AREA -- cgit v0.10.2 From 85a82392fe6fe7620d8fe0eb694f926cefe62e1f Mon Sep 17 00:00:00 2001 From: Sven Schuetz Date: Tue, 10 Jun 2008 18:20:59 +0200 Subject: [SCSI] zfcp: Add port_state attribute to sysfs The sysfs attribute /sys/class/fc_host/hostX/port_state was not set by zfcp so far. Now, the appropriate members of the fc_function_template struct are set during its initialziation. The first is a boolean to show the port state. The second is a function pointer to the function zfcp_get_host_port_state, which reads the port state from our adapter status bits and calls fc_host_port_state with the approriate port state afterwards. Signed-off-by: Sven Schuetz Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index a96e5c3..446fb1d 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -704,6 +704,23 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) } } +static void zfcp_get_host_port_state(struct Scsi_Host *shost) +{ + struct zfcp_adapter *adapter = + (struct zfcp_adapter *)shost->hostdata[0]; + int status = atomic_read(&adapter->status); + + if ((status & ZFCP_STATUS_COMMON_RUNNING) && + !(status & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED)) + fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; + else if (status & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED) + fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; + else if (status & ZFCP_STATUS_COMMON_ERP_FAILED) + fc_host_port_state(shost) = FC_PORTSTATE_ERROR; + else + fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; +} + static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) { rport->dev_loss_tmo = timeout; @@ -726,6 +743,8 @@ struct fc_function_template zfcp_transport_functions = { .get_fc_host_stats = zfcp_get_fc_host_stats, .reset_fc_host_stats = zfcp_reset_fc_host_stats, .set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo, + .get_host_port_state = zfcp_get_host_port_state, + .show_host_port_state = 1, /* no functions registered for following dynamic attributes but directly set by LLDD */ .show_host_port_type = 1, -- cgit v0.10.2 From cc8c282963bd258a5bf49d3aa52675a4ae6d31f6 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Tue, 10 Jun 2008 18:21:00 +0200 Subject: [SCSI] zfcp: Automatically attach remote ports Automatically attach the remote ports in zfcp when the adapter is set online. This is done by querying all available ports from the FC namesever. The scan for remote ports is also triggered by RSCNs and can be triggered manually with the sysfs attribute 'port_rescan'. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 47739f4..2bd80fd 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -568,6 +568,19 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) stat_work)); } +static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) +{ + struct zfcp_port *port; + + port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, + ZFCP_DID_DIRECTORY_SERVICE); + if (!port) + return -ENXIO; + zfcp_port_put(port); + + return 0; +} + /* * Enqueues an adapter at the end of the adapter list in the driver data. * All adapter internal structures are set up. @@ -648,6 +661,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* initialize lock of associated request queue */ rwlock_init(&adapter->req_q.lock); INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); + INIT_WORK(&adapter->scan_work, _zfcp_scan_ports_later); /* mark adapter unusable as long as sysfs registration is not complete */ atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); @@ -673,6 +687,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) zfcp_data.adapters++; + zfcp_nameserver_enqueue(adapter); + goto out; generic_services_failed: @@ -704,6 +720,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) int retval = 0; unsigned long flags; + cancel_work_sync(&adapter->scan_work); cancel_work_sync(&adapter->stat_work); zfcp_adapter_scsi_unregister(adapter); device_unregister(&adapter->generic_services); @@ -816,13 +833,15 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, kfree(port); return NULL; } - port->d_id = d_id; port->sysfs_device.parent = &adapter->generic_services; } else { snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", wwpn); port->sysfs_device.parent = &adapter->ccw_device->dev; } + + port->d_id = d_id; + port->sysfs_device.release = zfcp_sysfs_port_release; dev_set_drvdata(&port->sysfs_device, port); @@ -873,21 +892,6 @@ zfcp_port_dequeue(struct zfcp_port *port) device_unregister(&port->sysfs_device); } -/* Enqueues a nameserver port */ -int -zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) -{ - struct zfcp_port *port; - - port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, - ZFCP_DID_DIRECTORY_SERVICE); - if (!port) - return -ENXIO; - zfcp_port_put(port); - - return 0; -} - void zfcp_sg_free_table(struct scatterlist *sg, int count) { int i; diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 7c72f50..3e9f0ab 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -596,6 +596,10 @@ static const char *zfcp_rec_dbf_ids[] = { [145] = "recovery action being processed", [146] = "recovery action ready for next step", [147] = "qdio error inbound", + [148] = "nameserver needed for port scan", + [149] = "port scan", + [150] = "ptp attach", + [151] = "port validation failed", }; static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view, diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 73425db..1e837d4 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -282,7 +282,10 @@ struct zfcp_rc_entry { #define ZFCP_CT_DIRECTORY_SERVICE 0xFC #define ZFCP_CT_NAME_SERVER 0x02 #define ZFCP_CT_SYNCHRONOUS 0x00 +#define ZFCP_CT_SCSI_FCP 0x08 +#define ZFCP_CT_UNABLE_TO_PERFORM_CMD 0x09 #define ZFCP_CT_GID_PN 0x0121 +#define ZFCP_CT_GPN_FT 0x0172 #define ZFCP_CT_MAX_SIZE 0x1020 #define ZFCP_CT_ACCEPT 0x8002 #define ZFCP_CT_REJECT 0x8001 @@ -311,6 +314,7 @@ struct zfcp_rc_entry { #define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000 #define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000 #define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000 +#define ZFCP_STATUS_COMMON_NOESC 0x00200000 /* adapter status */ #define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 @@ -629,6 +633,7 @@ struct zfcp_adapter { struct fc_host_statistics *fc_stats; struct fsf_qtcb_bottom_port *stats_reset_data; unsigned long stats_reset; + struct work_struct scan_work; }; /* diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index c06156b..9b9c999 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -1199,6 +1199,10 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) zfcp_erp_port_unblock(port); break; case ZFCP_ERP_FAILED : + if (atomic_test_mask(ZFCP_STATUS_COMMON_NOESC, &port->status)) { + zfcp_erp_port_block(port, 0); + result = ZFCP_ERP_EXIT; + } atomic_inc(&port->erp_counter); if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) zfcp_erp_port_failed(port, 22, NULL); @@ -1607,6 +1611,7 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close) goto failed_openfcp; atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status); + schedule_work(&erp_action->adapter->scan_work); goto out; close_only: @@ -1665,10 +1670,19 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); } +static void zfcp_erp_open_ptp_port(struct zfcp_adapter *adapter) +{ + struct zfcp_port *port; + port = zfcp_port_enqueue(adapter, adapter->peer_wwpn, 0, + adapter->peer_d_id); + if (!port) /* error or port already attached */ + return; + zfcp_erp_port_reopen_internal(port, 0, 150, NULL); +} + static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) { - int retval = ZFCP_ERP_SUCCEEDED; int retries; int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP; struct zfcp_adapter *adapter = erp_action->adapter; @@ -1682,8 +1696,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) zfcp_erp_action_to_running(erp_action); write_unlock_irq(&adapter->erp_lock); if (zfcp_fsf_exchange_config_data(erp_action)) { - retval = ZFCP_ERP_FAILED; - break; + atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, + &adapter->status); + return ZFCP_ERP_FAILED; } /* @@ -1719,9 +1734,12 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status)) - retval = ZFCP_ERP_FAILED; + return ZFCP_ERP_FAILED; - return retval; + if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) + zfcp_erp_open_ptp_port(adapter); + + return ZFCP_ERP_SUCCEEDED; } static int @@ -1899,14 +1917,12 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) retval = zfcp_erp_port_strategy_open_port(erp_action); break; } - if (!(adapter->nameserver_port)) { - retval = zfcp_nameserver_enqueue(adapter); - if (retval != 0) { - dev_err(&adapter->ccw_device->dev, - "Nameserver port unavailable.\n"); - retval = ZFCP_ERP_FAILED; - break; - } + + if (!adapter->nameserver_port) { + dev_err(&adapter->ccw_device->dev, + "Nameserver port unavailable.\n"); + retval = ZFCP_ERP_FAILED; + break; } if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->nameserver_port->status)) { diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 9aa412b..c3b5133 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -37,6 +37,8 @@ extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, extern void zfcp_port_dequeue(struct zfcp_port *); extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t); extern void zfcp_unit_dequeue(struct zfcp_unit *); +extern int zfcp_scan_ports(struct zfcp_adapter *); +extern void _zfcp_scan_ports_later(struct work_struct *work); /******************************* S/390 IO ************************************/ extern int zfcp_ccw_register(void); @@ -97,8 +99,6 @@ extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *); extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); extern void zfcp_test_link(struct zfcp_port *); -extern int zfcp_nameserver_enqueue(struct zfcp_adapter *); - /******************************* SCSI ****************************************/ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index bb07c3b..aa2d9a6 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -8,6 +8,37 @@ #include "zfcp_ext.h" +struct ct_iu_gpn_ft_req { + struct ct_hdr header; + u8 flags; + u8 domain_id_scope; + u8 area_id_scope; + u8 fc4_type; +} __attribute__ ((packed)); + +struct gpn_ft_resp_acc { + u8 control; + u8 port_id[3]; + u8 reserved[4]; + u64 wwpn; +} __attribute__ ((packed)); + +#define ZFCP_GPN_FT_ENTRIES ((PAGE_SIZE - sizeof(struct ct_hdr)) \ + / sizeof(struct gpn_ft_resp_acc)) +#define ZFCP_GPN_FT_BUFFERS 4 +#define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1) + +struct ct_iu_gpn_ft_resp { + struct ct_hdr header; + struct gpn_ft_resp_acc accept[ZFCP_GPN_FT_ENTRIES]; +} __attribute__ ((packed)); + +struct zfcp_gpn_ft { + struct zfcp_send_ct ct; + struct scatterlist sg_req; + struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; +}; + static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, struct fcp_rscn_element *elem) { @@ -68,6 +99,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) } _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element); } + schedule_work(&fsf_req->adapter->scan_work); } static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn) @@ -303,3 +335,219 @@ void zfcp_test_link(struct zfcp_port *port) zfcp_port_put(port); zfcp_erp_port_forced_reopen(port, 0, 65, NULL); } + +static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) +{ + int ret; + + if (!adapter->nameserver_port) + return -EINTR; + + if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, + &adapter->nameserver_port->status)) { + ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148, + NULL); + if (ret) + return ret; + zfcp_erp_wait(adapter); + zfcp_port_put(adapter->nameserver_port); + } + return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, + &adapter->nameserver_port->status); +} + +static void zfcp_gpn_ft_handler(unsigned long _done) +{ + complete((struct completion *)_done); +} + +static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) +{ + struct scatterlist *sg = &gpn_ft->sg_req; + + kfree(sg_virt(sg)); /* free request buffer */ + zfcp_sg_free_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS); + + kfree(gpn_ft); +} + +static struct zfcp_gpn_ft *zfcp_alloc_sg_env(void) +{ + struct zfcp_gpn_ft *gpn_ft; + struct ct_iu_gpn_ft_req *req; + + gpn_ft = kzalloc(sizeof(*gpn_ft), GFP_KERNEL); + if (!gpn_ft) + return NULL; + + req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL); + if (!req) { + kfree(gpn_ft); + gpn_ft = NULL; + goto out; + } + sg_init_one(&gpn_ft->sg_req, req, sizeof(*req)); + + if (zfcp_sg_setup_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS)) { + zfcp_free_sg_env(gpn_ft); + gpn_ft = NULL; + } +out: + return gpn_ft; +} + + +static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, + struct zfcp_adapter *adapter) +{ + struct zfcp_send_ct *ct = &gpn_ft->ct; + struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); + struct completion done; + int ret; + + /* prepare CT IU for GPN_FT */ + req->header.revision = ZFCP_CT_REVISION; + req->header.gs_type = ZFCP_CT_DIRECTORY_SERVICE; + req->header.gs_subtype = ZFCP_CT_NAME_SERVER; + req->header.options = ZFCP_CT_SYNCHRONOUS; + req->header.cmd_rsp_code = ZFCP_CT_GPN_FT; + req->header.max_res_size = (sizeof(struct gpn_ft_resp_acc) * + (ZFCP_GPN_FT_MAX_ENTRIES - 1)) >> 2; + req->flags = 0; + req->domain_id_scope = 0; + req->area_id_scope = 0; + req->fc4_type = ZFCP_CT_SCSI_FCP; + + /* prepare zfcp_send_ct */ + ct->port = adapter->nameserver_port; + ct->handler = zfcp_gpn_ft_handler; + ct->handler_data = (unsigned long)&done; + ct->timeout = 10; + ct->req = &gpn_ft->sg_req; + ct->resp = gpn_ft->sg_resp; + ct->req_count = 1; + ct->resp_count = ZFCP_GPN_FT_BUFFERS; + + init_completion(&done); + ret = zfcp_fsf_send_ct(ct, NULL, NULL); + if (!ret) + wait_for_completion(&done); + return ret; +} + +static void zfcp_validate_port(struct zfcp_port *port) +{ + struct zfcp_adapter *adapter = port->adapter; + + atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); + + if (port == adapter->nameserver_port) + return; + if ((port->supported_classes != 0) || (port->units != 0)) { + zfcp_port_put(port); + return; + } + zfcp_erp_port_shutdown(port, 0, 151, NULL); + zfcp_erp_wait(adapter); + zfcp_port_put(port); + zfcp_port_dequeue(port); +} + +static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) +{ + struct zfcp_send_ct *ct = &gpn_ft->ct; + struct scatterlist *sg = gpn_ft->sg_resp; + struct ct_hdr *hdr = sg_virt(sg); + struct gpn_ft_resp_acc *acc = sg_virt(sg); + struct zfcp_adapter *adapter = ct->port->adapter; + struct zfcp_port *port, *tmp; + u32 d_id; + int ret = 0, x; + + if (ct->status) + return -EIO; + + if (hdr->cmd_rsp_code != ZFCP_CT_ACCEPT) { + if (hdr->reason_code == ZFCP_CT_UNABLE_TO_PERFORM_CMD) + return -EAGAIN; /* might be a temporary condition */ + return -EIO; + } + + if (hdr->max_res_size) + return -E2BIG; + + down(&zfcp_data.config_sema); + + /* first entry is the header */ + for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) { + if (x % (ZFCP_GPN_FT_ENTRIES + 1)) + acc++; + else + acc = sg_virt(++sg); + + d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | + acc->port_id[2]; + + /* skip the adapter's port and known remote ports */ + if (acc->wwpn == fc_host_port_name(adapter->scsi_host) || + zfcp_get_port_by_did(adapter, d_id)) + continue; + + port = zfcp_port_enqueue(adapter, acc->wwpn, + ZFCP_STATUS_PORT_DID_DID | + ZFCP_STATUS_COMMON_NOESC, d_id); + if (port) + zfcp_erp_port_reopen(port, 0, 149, NULL); + else + ret = -ENOMEM; + if (acc->control & 0x80) /* last entry */ + break; + } + + zfcp_erp_wait(adapter); + list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list) + zfcp_validate_port(port); + up(&zfcp_data.config_sema); + return ret; +} + +/** + * zfcp_scan_ports - scan remote ports and attach new ports + * @adapter: pointer to struct zfcp_adapter + */ +int zfcp_scan_ports(struct zfcp_adapter *adapter) +{ + int ret, i; + struct zfcp_gpn_ft *gpn_ft; + + if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) + return 0; + + ret = zfcp_scan_get_nameserver(adapter); + if (ret) + return ret; + + gpn_ft = zfcp_alloc_sg_env(); + if (!gpn_ft) + return -ENOMEM; + + for (i = 0; i < 3; i++) { + ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); + if (!ret) { + ret = zfcp_scan_eval_gpn_ft(gpn_ft); + if (ret == -EAGAIN) + ssleep(1); + else + break; + } + } + zfcp_free_sg_env(gpn_ft); + + return ret; +} + + +void _zfcp_scan_ports_later(struct work_struct *work) +{ + zfcp_scan_ports(container_of(work, struct zfcp_adapter, scan_work)); +} diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 01ed5fb..243e792 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -874,6 +874,9 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) if (status_buffer->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) zfcp_erp_adapter_access_changed(adapter, 135, fsf_req); + if (status_buffer->status_subtype & + FSF_STATUS_READ_SUB_INCOMING_ELS) + schedule_work(&adapter->scan_work); break; case FSF_STATUS_READ_CFDC_UPDATED: diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index 1f2a8c2..a4cae60 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -85,6 +85,30 @@ zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, con static DEVICE_ATTR(port_add, S_IWUSR, NULL, zfcp_sysfs_port_add_store); /** + * zfcp_sysfs_port_rescan - trigger manual port rescan + * @dev: pointer to belonging device + * @attr: pointer to struct device_attribute + * @buf: pointer to input buffer + * @count: number of bytes in buffer + */ +static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_adapter *adapter; + int ret; + + adapter = dev_get_drvdata(dev); + if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status)) + return -EBUSY; + + ret = zfcp_scan_ports(adapter); + + return ret ? ret : (ssize_t) count; +} +static DEVICE_ATTR(port_rescan, S_IWUSR, NULL, zfcp_sysfs_port_rescan_store); + +/** * zfcp_sysfs_port_remove_store - remove a port from sysfs tree * @dev: pointer to belonging device * @buf: pointer to input buffer @@ -214,6 +238,7 @@ static struct attribute *zfcp_adapter_attrs[] = { &dev_attr_in_recovery.attr, &dev_attr_port_remove.attr, &dev_attr_port_add.attr, + &dev_attr_port_rescan.attr, &dev_attr_peer_wwnn.attr, &dev_attr_peer_wwpn.attr, &dev_attr_peer_d_id.attr, -- cgit v0.10.2 From 235f7f25f4928f5075dbebdfb9ca2c5d90db882c Mon Sep 17 00:00:00 2001 From: Martin Peschke Date: Tue, 10 Jun 2008 18:21:01 +0200 Subject: [SCSI] zfcp: Remove sysfs attribute port_add With the automatic scanning of remote ports in place, there is no need to add remote ports manually. So, remove the port_add attribute. Signed-off-by: Martin Peschke Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index a4cae60..3985f1f 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c @@ -40,51 +40,6 @@ ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)); /** - * zfcp_sysfs_port_add_store - add a port to sysfs tree - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - * - * Store function of the "port_add" attribute of an adapter. - */ -static ssize_t -zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - wwn_t wwpn; - char *endp; - struct zfcp_adapter *adapter; - struct zfcp_port *port; - int retval = -EINVAL; - - down(&zfcp_data.config_sema); - - adapter = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status)) { - retval = -EBUSY; - goto out; - } - - wwpn = simple_strtoull(buf, &endp, 0); - if ((endp + 1) < (buf + count)) - goto out; - - port = zfcp_port_enqueue(adapter, wwpn, 0, 0); - if (!port) - goto out; - - retval = 0; - - zfcp_erp_port_reopen(port, 0, 91, NULL); - zfcp_erp_wait(port->adapter); - zfcp_port_put(port); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -static DEVICE_ATTR(port_add, S_IWUSR, NULL, zfcp_sysfs_port_add_store); - -/** * zfcp_sysfs_port_rescan - trigger manual port rescan * @dev: pointer to belonging device * @attr: pointer to struct device_attribute @@ -237,7 +192,6 @@ static struct attribute *zfcp_adapter_attrs[] = { &dev_attr_failed.attr, &dev_attr_in_recovery.attr, &dev_attr_port_remove.attr, - &dev_attr_port_add.attr, &dev_attr_port_rescan.attr, &dev_attr_peer_wwnn.attr, &dev_attr_peer_wwpn.attr, -- cgit v0.10.2 From 915caaaf622172bd3451e7b76ba9cfcea80e87c7 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:38 -0400 Subject: [SCSI] lpfc 8.2.7 : Change device reset behavior Prior handler was only waiting for I/O on one lun to finish before returning completion. Now, wait for all LUNs on the target. Also performed some rudimentary cleanup while in this code. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 0910a9a..3926aff 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -849,14 +849,15 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, struct lpfc_iocbq *iocbq; struct lpfc_iocbq *iocbqrsp; int ret; + int status; if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) return FAILED; lpfc_cmd->rdata = rdata; - ret = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun, + status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun, FCP_TARGET_RESET); - if (!ret) + if (!status) return FAILED; iocbq = &lpfc_cmd->cur_iocbq; @@ -869,12 +870,15 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, "0702 Issue Target Reset to TGT %d Data: x%x x%x\n", tgt_id, rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag); - ret = lpfc_sli_issue_iocb_wait(phba, + status = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); - if (ret != IOCB_SUCCESS) { - if (ret == IOCB_TIMEDOUT) + if (status != IOCB_SUCCESS) { + if (status == IOCB_TIMEDOUT) { iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; + ret = TIMEOUT_ERROR; + } else + ret = FAILED; lpfc_cmd->status = IOSTAT_DRIVER_REJECT; } else { ret = SUCCESS; @@ -1142,121 +1146,96 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) struct lpfc_iocbq *iocbq, *iocbqrsp; struct lpfc_rport_data *rdata = cmnd->device->hostdata; struct lpfc_nodelist *pnode = rdata->pnode; - uint32_t cmd_result = 0, cmd_status = 0; - int ret = FAILED; - int iocb_status = IOCB_SUCCESS; - int cnt, loopcnt; + unsigned long later; + int ret = SUCCESS; + int status; + int cnt; lpfc_block_error_handler(cmnd); - loopcnt = 0; /* * If target is not in a MAPPED state, delay the reset until * target is rediscovered or devloss timeout expires. */ - while (1) { + later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; + while (time_after(later, jiffies)) { if (!pnode || !NLP_CHK_NODE_ACT(pnode)) - goto out; - - if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { - schedule_timeout_uninterruptible(msecs_to_jiffies(500)); - loopcnt++; - rdata = cmnd->device->hostdata; - if (!rdata || - (loopcnt > ((vport->cfg_devloss_tmo * 2) + 1))){ - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0721 LUN Reset rport " - "failure: cnt x%x rdata x%p\n", - loopcnt, rdata); - goto out; - } - pnode = rdata->pnode; - if (!pnode || !NLP_CHK_NODE_ACT(pnode)) - goto out; - } + return FAILED; if (pnode->nlp_state == NLP_STE_MAPPED_NODE) break; + schedule_timeout_uninterruptible(msecs_to_jiffies(500)); + rdata = cmnd->device->hostdata; + if (!rdata) + break; + pnode = rdata->pnode; + } + if (!rdata || pnode->nlp_state != NLP_STE_MAPPED_NODE) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0721 LUN Reset rport " + "failure: msec x%x rdata x%p\n", + jiffies_to_msecs(jiffies - later), rdata); + return FAILED; } - lpfc_cmd = lpfc_get_scsi_buf(phba); if (lpfc_cmd == NULL) - goto out; - + return FAILED; lpfc_cmd->timeout = 60; lpfc_cmd->rdata = rdata; - ret = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, cmnd->device->lun, - FCP_TARGET_RESET); - if (!ret) - goto out_free_scsi_buf; - + status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, + cmnd->device->lun, + FCP_TARGET_RESET); + if (!status) { + lpfc_release_scsi_buf(phba, lpfc_cmd); + return FAILED; + } iocbq = &lpfc_cmd->cur_iocbq; /* get a buffer for this IOCB command response */ iocbqrsp = lpfc_sli_get_iocbq(phba); - if (iocbqrsp == NULL) - goto out_free_scsi_buf; - + if (iocbqrsp == NULL) { + lpfc_release_scsi_buf(phba, lpfc_cmd); + return FAILED; + } lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, "0703 Issue target reset to TGT %d LUN %d " "rpi x%x nlp_flag x%x\n", cmnd->device->id, cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); - iocb_status = lpfc_sli_issue_iocb_wait(phba, - &phba->sli.ring[phba->sli.fcp_ring], - iocbq, iocbqrsp, lpfc_cmd->timeout); - - if (iocb_status == IOCB_TIMEDOUT) + status = lpfc_sli_issue_iocb_wait(phba, + &phba->sli.ring[phba->sli.fcp_ring], + iocbq, iocbqrsp, lpfc_cmd->timeout); + if (status == IOCB_TIMEDOUT) { iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; - - if (iocb_status == IOCB_SUCCESS) - ret = SUCCESS; - else - ret = iocb_status; - - cmd_result = iocbqrsp->iocb.un.ulpWord[4]; - cmd_status = iocbqrsp->iocb.ulpStatus; - + ret = TIMEOUT_ERROR; + } else { + if (status != IOCB_SUCCESS) + ret = FAILED; + lpfc_release_scsi_buf(phba, lpfc_cmd); + } + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "0713 SCSI layer issued device reset (%d, %d) " + "return x%x status x%x result x%x\n", + cmnd->device->id, cmnd->device->lun, ret, + iocbqrsp->iocb.ulpStatus, + iocbqrsp->iocb.un.ulpWord[4]); lpfc_sli_release_iocbq(phba, iocbqrsp); - - /* - * All outstanding txcmplq I/Os should have been aborted by the device. - * Unfortunately, some targets do not abide by this forcing the driver - * to double check. - */ cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, cmnd->device->lun, - LPFC_CTX_LUN); + LPFC_CTX_TGT); if (cnt) lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], cmnd->device->id, cmnd->device->lun, - LPFC_CTX_LUN); - loopcnt = 0; - while(cnt) { - schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); - - if (++loopcnt - > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT) - break; - + LPFC_CTX_TGT); + later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; + while (time_after(later, jiffies) && cnt) { + schedule_timeout_uninterruptible(msecs_to_jiffies(20)); cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, - cmnd->device->lun, LPFC_CTX_LUN); + cmnd->device->lun, LPFC_CTX_TGT); } - if (cnt) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "0719 device reset I/O flush failure: " "cnt x%x\n", cnt); ret = FAILED; } - -out_free_scsi_buf: - if (iocb_status != IOCB_TIMEDOUT) { - lpfc_release_scsi_buf(phba, lpfc_cmd); - } - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0713 SCSI layer issued device reset (%d, %d) " - "return x%x status x%x result x%x\n", - cmnd->device->id, cmnd->device->lun, ret, - cmd_status, cmd_result); -out: return ret; } @@ -1268,19 +1247,12 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp = NULL; int match; - int ret = FAILED, i, err_count = 0; - int cnt, loopcnt; + int ret = SUCCESS, status, i; + int cnt; struct lpfc_scsi_buf * lpfc_cmd; + unsigned long later; lpfc_block_error_handler(cmnd); - - lpfc_cmd = lpfc_get_scsi_buf(phba); - if (lpfc_cmd == NULL) - goto out; - - /* The lpfc_cmd storage is reused. Set all loop invariants. */ - lpfc_cmd->timeout = 60; - /* * Since the driver manages a single bus device, reset all * targets known to the driver. Should any target reset @@ -1294,7 +1266,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) if (!NLP_CHK_NODE_ACT(ndlp)) continue; if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && - i == ndlp->nlp_sid && + ndlp->nlp_sid == i && ndlp->rport) { match = 1; break; @@ -1303,27 +1275,22 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) spin_unlock_irq(shost->host_lock); if (!match) continue; - - ret = lpfc_scsi_tgt_reset(lpfc_cmd, vport, i, - cmnd->device->lun, - ndlp->rport->dd_data); - if (ret != SUCCESS) { + lpfc_cmd = lpfc_get_scsi_buf(phba); + if (lpfc_cmd) { + lpfc_cmd->timeout = 60; + status = lpfc_scsi_tgt_reset(lpfc_cmd, vport, i, + cmnd->device->lun, + ndlp->rport->dd_data); + if (status != TIMEOUT_ERROR) + lpfc_release_scsi_buf(phba, lpfc_cmd); + } + if (!lpfc_cmd || status != SUCCESS) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "0700 Bus Reset on target %d failed\n", i); - err_count++; - break; + ret = FAILED; } } - - if (ret != IOCB_TIMEDOUT) - lpfc_release_scsi_buf(phba, lpfc_cmd); - - if (err_count == 0) - ret = SUCCESS; - else - ret = FAILED; - /* * All outstanding txcmplq I/Os should have been aborted by * the targets. Unfortunately, some targets do not abide by @@ -1333,27 +1300,19 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) if (cnt) lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], 0, 0, LPFC_CTX_HOST); - loopcnt = 0; - while(cnt) { - schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); - - if (++loopcnt - > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT) - break; - + later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; + while (time_after(later, jiffies) && cnt) { + schedule_timeout_uninterruptible(msecs_to_jiffies(20)); cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST); } - if (cnt) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "0715 Bus Reset I/O flush failure: " "cnt x%x left x%x\n", cnt, i); ret = FAILED; } - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "0714 SCSI layer issued Bus Reset Data: x%x\n", ret); -out: return ret; } -- cgit v0.10.2 From 0d2b6b83030d6a88cbf7db57f84f2daf0e0b251b Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:47 -0400 Subject: [SCSI] lpfc 8.2.7 : Discovery Fixes - Fix ADISC timeout on initiators causing devloss timeout on targets - Correct FAN processing : port state vs unreg rpi's wasn't consistent - Correct mismatches between ASICs and PLOGI that would skip PLOGI Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 886c5f1..d418c7c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1754,29 +1754,34 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_work_evt *evtp; + if (!(nlp->nlp_flag & NLP_DELAY_TMO)) + return; spin_lock_irq(shost->host_lock); nlp->nlp_flag &= ~NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); del_timer_sync(&nlp->nlp_delayfunc); nlp->nlp_last_elscmd = 0; - if (!list_empty(&nlp->els_retry_evt.evt_listp)) { list_del_init(&nlp->els_retry_evt.evt_listp); /* Decrement nlp reference count held for the delayed retry */ evtp = &nlp->els_retry_evt; lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1); } - if (nlp->nlp_flag & NLP_NPR_2B_DISC) { spin_lock_irq(shost->host_lock); nlp->nlp_flag &= ~NLP_NPR_2B_DISC; spin_unlock_irq(shost->host_lock); if (vport->num_disc_nodes) { - /* Check to see if there are more - * PLOGIs to be sent - */ - lpfc_more_plogi(vport); - + if (vport->port_state < LPFC_VPORT_READY) { + /* Check if there are more ADISCs to be sent */ + lpfc_more_adisc(vport); + if ((vport->num_disc_nodes == 0) && + (vport->fc_npr_cnt)) + lpfc_els_disc_plogi(vport); + } else { + /* Check if there are more PLOGIs to be sent */ + lpfc_more_plogi(vport); + } if (vport->num_disc_nodes == 0) { spin_lock_irq(shost->host_lock); vport->fc_flag &= ~FC_NDISC_ACTIVE; @@ -1798,10 +1803,6 @@ lpfc_els_retry_delay(unsigned long ptr) unsigned long flags; struct lpfc_work_evt *evtp = &ndlp->els_retry_evt; - ndlp = (struct lpfc_nodelist *) ptr; - phba = ndlp->vport->phba; - evtp = &ndlp->els_retry_evt; - spin_lock_irqsave(&phba->hbalock, flags); if (!list_empty(&evtp->evt_listp)) { spin_unlock_irqrestore(&phba->hbalock, flags); @@ -2761,10 +2762,11 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, npr = (PRLI *) pcmd; vpd = &phba->vpd; /* - * If our firmware version is 3.20 or later, - * set the following bits for FC-TAPE support. + * If the remote port is a target and our firmware version is 3.20 or + * later, set the following bits for FC-TAPE support. */ - if (vpd->rev.feaLevelHigh >= 0x02) { + if ((ndlp->nlp_type & NLP_FCP_TARGET) && + (vpd->rev.feaLevelHigh >= 0x02)) { npr->ConfmComplAllowed = 1; npr->Retry = 1; npr->TaskRetryIdReq = 1; @@ -3056,27 +3058,16 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) { struct lpfc_nodelist *ndlp = NULL; - /* Look at all nodes effected by pending RSCNs and move - * them to NPR state. - */ - + /* Move all affected nodes by pending RSCNs to NPR state. */ list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { if (!NLP_CHK_NODE_ACT(ndlp) || - ndlp->nlp_state == NLP_STE_UNUSED_NODE || - lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0) + (ndlp->nlp_state == NLP_STE_UNUSED_NODE) || + !lpfc_rscn_payload_check(vport, ndlp->nlp_DID)) continue; - lpfc_disc_state_machine(vport, ndlp, NULL, - NLP_EVT_DEVICE_RECOVERY); - - /* - * Make sure NLP_DELAY_TMO is NOT running after a device - * recovery event. - */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(vport, ndlp); + NLP_EVT_DEVICE_RECOVERY); + lpfc_cancel_retry_delay_tmo(vport, ndlp); } - return 0; } @@ -3781,91 +3772,27 @@ static int lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *fan_ndlp) { - struct lpfc_dmabuf *pcmd; + struct lpfc_hba *phba = vport->phba; uint32_t *lp; - IOCB_t *icmd; - uint32_t cmd, did; FAN *fp; - struct lpfc_nodelist *ndlp, *next_ndlp; - struct lpfc_hba *phba = vport->phba; - - /* FAN received */ - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0265 FAN received\n"); - icmd = &cmdiocb->iocb; - did = icmd->un.elsreq64.remoteID; - pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; - lp = (uint32_t *)pcmd->virt; - - cmd = *lp++; - fp = (FAN *) lp; + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0265 FAN received\n"); + lp = (uint32_t *)((struct lpfc_dmabuf *)cmdiocb->context2)->virt; + fp = (FAN *) ++lp; /* FAN received; Fan does not have a reply sequence */ - - if (phba->pport->port_state == LPFC_LOCAL_CFG_LINK) { + if ((vport == phba->pport) && + (vport->port_state == LPFC_LOCAL_CFG_LINK)) { if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, - sizeof(struct lpfc_name)) != 0) || + sizeof(struct lpfc_name))) || (memcmp(&phba->fc_fabparam.portName, &fp->FportName, - sizeof(struct lpfc_name)) != 0)) { - /* - * This node has switched fabrics. FLOGI is required - * Clean up the old rpi's - */ - - list_for_each_entry_safe(ndlp, next_ndlp, - &vport->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - if (ndlp->nlp_state != NLP_STE_NPR_NODE) - continue; - if (ndlp->nlp_type & NLP_FABRIC) { - /* - * Clean up old Fabric, Nameserver and - * other NLP_FABRIC logins - */ - lpfc_drop_node(vport, ndlp); - - } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { - /* Fail outstanding I/O now since this - * device is marked for PLOGI - */ - lpfc_unreg_rpi(vport, ndlp); - } - } - + sizeof(struct lpfc_name)))) { + /* This port has switched fabrics. FLOGI is required */ lpfc_initial_flogi(vport); - return 0; - } - /* Discovery not needed, - * move the nodes to their original state. - */ - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, - nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - if (ndlp->nlp_state != NLP_STE_NPR_NODE) - continue; - - switch (ndlp->nlp_prev_state) { - case NLP_STE_UNMAPPED_NODE: - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(vport, ndlp, - NLP_STE_UNMAPPED_NODE); - break; - - case NLP_STE_MAPPED_NODE: - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(vport, ndlp, - NLP_STE_MAPPED_NODE); - break; - - default: - break; - } + } else { + /* FAN verified - skip FLOGI */ + vport->fc_myDID = vport->fc_prevDID; + lpfc_issue_fabric_reglogin(vport); } - - /* Start discovery - this should just do CLEAR_LA */ - lpfc_disc_start(vport); } return 0; } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 7cb68fe..f3dc19d 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1087,6 +1087,8 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) MAILBOX_t *mb = &pmb->mb; struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); + /* Unblock ELS traffic */ + phba->sli.ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT; /* Check for error */ if (mb->mbxStatus) { lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, @@ -1650,7 +1652,6 @@ lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_DID, old_state, state); if (old_state == NLP_STE_NPR_NODE && - (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && state != NLP_STE_NPR_NODE) lpfc_cancel_retry_delay_tmo(vport, ndlp); if (old_state == NLP_STE_UNMAPPED_NODE) { @@ -1687,8 +1688,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) - lpfc_cancel_retry_delay_tmo(vport, ndlp); + lpfc_cancel_retry_delay_tmo(vport, ndlp); if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) lpfc_nlp_counters(vport, ndlp->nlp_state, -1); spin_lock_irq(shost->host_lock); @@ -1701,8 +1701,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) static void lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { - if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) - lpfc_cancel_retry_delay_tmo(vport, ndlp); + lpfc_cancel_retry_delay_tmo(vport, ndlp); if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) lpfc_nlp_counters(vport, ndlp->nlp_state, -1); lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, @@ -2121,10 +2120,8 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ndlp->nlp_last_elscmd = 0; del_timer_sync(&ndlp->nlp_delayfunc); - if (!list_empty(&ndlp->els_retry_evt.evt_listp)) - list_del_init(&ndlp->els_retry_evt.evt_listp); - if (!list_empty(&ndlp->dev_loss_evt.evt_listp)) - list_del_init(&ndlp->dev_loss_evt.evt_listp); + list_del_init(&ndlp->els_retry_evt.evt_listp); + list_del_init(&ndlp->dev_loss_evt.evt_listp); lpfc_unreg_rpi(vport, ndlp); @@ -2144,10 +2141,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) LPFC_MBOXQ_t *mbox; int rc; - if (ndlp->nlp_flag & NLP_DELAY_TMO) { - lpfc_cancel_retry_delay_tmo(vport, ndlp); - } - + lpfc_cancel_retry_delay_tmo(vport, ndlp); if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) { /* For this case we need to cleanup the default rpi * allocated by the firmware. @@ -2317,8 +2311,7 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) /* Since this node is marked for discovery, * delay timeout is not needed. */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(vport, ndlp); + lpfc_cancel_retry_delay_tmo(vport, ndlp); } else ndlp = NULL; } else { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fa757b2..6fcddda 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -851,6 +851,8 @@ lpfc_handle_latt(struct lpfc_hba *phba) lpfc_read_la(phba, pmb, mp); pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; pmb->vport = vport; + /* Block ELS IOCBs until we have processed this mbox command */ + phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT; rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { rc = 4; @@ -866,6 +868,7 @@ lpfc_handle_latt(struct lpfc_hba *phba) return; lpfc_handle_latt_free_mbuf: + phba->sli.ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT; lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_handle_latt_free_mp: kfree(mp); diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d08c4c8..6688a86 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -235,10 +235,7 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) (iocb->iocb_cmpl) (phba, iocb, iocb); } } - - /* If we are delaying issuing an ELS command, cancel it */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); + lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); return 0; } @@ -249,7 +246,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; struct lpfc_dmabuf *pcmd; - struct lpfc_work_evt *evtp; uint32_t *lp; IOCB_t *icmd; struct serv_parm *sp; @@ -425,73 +421,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp, mbox); return 1; } - - /* If the remote NPort logs into us, before we can initiate - * discovery to them, cleanup the NPort from discovery accordingly. - */ - if (ndlp->nlp_state == NLP_STE_NPR_NODE) { - spin_lock_irq(shost->host_lock); - ndlp->nlp_flag &= ~NLP_DELAY_TMO; - spin_unlock_irq(shost->host_lock); - del_timer_sync(&ndlp->nlp_delayfunc); - ndlp->nlp_last_elscmd = 0; - - if (!list_empty(&ndlp->els_retry_evt.evt_listp)) { - list_del_init(&ndlp->els_retry_evt.evt_listp); - /* Decrement ndlp reference count held for the - * delayed retry - */ - evtp = &ndlp->els_retry_evt; - lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1); - } - - if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { - spin_lock_irq(shost->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; - spin_unlock_irq(shost->host_lock); - - if ((ndlp->nlp_flag & NLP_ADISC_SND) && - (vport->num_disc_nodes)) { - /* Check to see if there are more - * ADISCs to be sent - */ - lpfc_more_adisc(vport); - - if ((vport->num_disc_nodes == 0) && - (vport->fc_npr_cnt)) - lpfc_els_disc_plogi(vport); - - if (vport->num_disc_nodes == 0) { - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_NDISC_ACTIVE; - spin_unlock_irq(shost->host_lock); - lpfc_can_disctmo(vport); - lpfc_end_rscn(vport); - } - } - } - } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) && - (ndlp->nlp_flag & NLP_NPR_2B_DISC) && - (vport->num_disc_nodes)) { - spin_lock_irq(shost->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; - spin_unlock_irq(shost->host_lock); - /* Check to see if there are more - * PLOGIs to be sent - */ - lpfc_more_plogi(vport); - if (vport->num_disc_nodes == 0) { - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_NDISC_ACTIVE; - spin_unlock_irq(shost->host_lock); - lpfc_can_disctmo(vport); - lpfc_end_rscn(vport); - } - } - lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); return 1; - out: stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; @@ -574,7 +505,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, else lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); - if (!(ndlp->nlp_type & NLP_FABRIC) || + if ((!(ndlp->nlp_type & NLP_FABRIC) && + ((ndlp->nlp_type & NLP_FCP_TARGET) || + !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { /* Only try to re-login if this is NOT a Fabric Node */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); @@ -751,6 +684,7 @@ static uint32_t lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb = arg; struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; @@ -776,7 +710,22 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); } else { - lpfc_rcv_plogi(vport, ndlp, cmdiocb); + if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) && + (ndlp->nlp_flag & NLP_NPR_2B_DISC) && + (vport->num_disc_nodes)) { + spin_lock_irq(shost->host_lock); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + spin_unlock_irq(shost->host_lock); + /* Check if there are more PLOGIs to be sent */ + lpfc_more_plogi(vport); + if (vport->num_disc_nodes == 0) { + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_NDISC_ACTIVE; + spin_unlock_irq(shost->host_lock); + lpfc_can_disctmo(vport); + lpfc_end_rscn(vport); + } + } } /* If our portname was less */ return ndlp->nlp_state; @@ -1040,6 +989,7 @@ static uint32_t lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb; @@ -1048,9 +998,28 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, cmdiocb = (struct lpfc_iocbq *) arg; - if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) - return ndlp->nlp_state; + if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { + if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { + spin_lock_irq(shost->host_lock); + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + spin_unlock_irq(shost->host_lock); + if (vport->num_disc_nodes) { + lpfc_more_adisc(vport); + if ((vport->num_disc_nodes == 0) && + (vport->fc_npr_cnt)) + lpfc_els_disc_plogi(vport); + if (vport->num_disc_nodes == 0) { + spin_lock_irq(shost->host_lock); + vport->fc_flag &= ~FC_NDISC_ACTIVE; + spin_unlock_irq(shost->host_lock); + lpfc_can_disctmo(vport); + lpfc_end_rscn(vport); + } + } + } + return ndlp->nlp_state; + } ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); @@ -1742,24 +1711,21 @@ lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; /* Ignore PLOGI if we have an outstanding LOGO */ - if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC)) { + if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC)) return ndlp->nlp_state; - } - if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { + lpfc_cancel_retry_delay_tmo(vport, ndlp); spin_lock_irq(shost->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; + ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC); spin_unlock_irq(shost->host_lock); - return ndlp->nlp_state; - } - - /* send PLOGI immediately, move to PLOGI issue state */ - if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); - lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); + } else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) { + /* send PLOGI immediately, move to PLOGI issue state */ + if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { + ndlp->nlp_prev_state = NLP_STE_NPR_NODE; + lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); + lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); + } } - return ndlp->nlp_state; } @@ -1810,7 +1776,6 @@ lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; lpfc_rcv_padisc(vport, ndlp, cmdiocb); - /* * Do not start discovery if discovery is about to start * or discovery in progress for this node. Starting discovery @@ -1973,9 +1938,7 @@ lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); spin_unlock_irq(shost->host_lock); - if (ndlp->nlp_flag & NLP_DELAY_TMO) { - lpfc_cancel_retry_delay_tmo(vport, ndlp); - } + lpfc_cancel_retry_delay_tmo(vport, ndlp); return ndlp->nlp_state; } -- cgit v0.10.2 From 5e9d9b8276980fc5dfa88ce34f6ec88ce3026232 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:53 -0400 Subject: [SCSI] lpfc 8.2.7 : Rework the worker thread Rework of the worker thread to make it more efficient. Make a finer-grain notfication of pending work so less time is spent checking conditions. Also made other general cleanups. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ec0b0f6..e3e5b54 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -59,6 +59,9 @@ struct lpfc_sli2_slim; #define MAX_HBAEVT 32 +/* lpfc wait event data ready flag */ +#define LPFC_DATA_READY (1<<0) + enum lpfc_polling_flags { ENABLE_FCP_RING_POLLING = 0x1, DISABLE_FCP_RING_INT = 0x2 @@ -425,9 +428,6 @@ struct lpfc_hba { uint16_t pci_cfg_value; - uint8_t work_found; -#define LPFC_MAX_WORKER_ITERATION 4 - uint8_t fc_linkspeed; /* Link speed after last READ_LA */ uint32_t fc_eventTag; /* event tag for link attention */ @@ -489,8 +489,9 @@ struct lpfc_hba { uint32_t work_hs; /* HS stored in case of ERRAT */ uint32_t work_status[2]; /* Extra status from SLIM */ - wait_queue_head_t *work_wait; + wait_queue_head_t work_waitq; struct task_struct *worker_thread; + long data_flags; uint32_t hbq_in_use; /* HBQs in use flag */ struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */ @@ -637,6 +638,17 @@ lpfc_is_link_up(struct lpfc_hba *phba) phba->link_state == LPFC_HBA_READY; } +static inline void +lpfc_worker_wake_up(struct lpfc_hba *phba) +{ + /* Set the lpfc data pending flag */ + set_bit(LPFC_DATA_READY, &phba->data_flags); + + /* Wake up worker thread */ + wake_up(&phba->work_waitq); + return; +} + #define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ #define FC_REG_TEMPERATURE_EVENT 0x20 /* Register for temperature event */ diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 153afae..5442ce3 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1679,20 +1679,18 @@ lpfc_fdmi_tmo(unsigned long ptr) { struct lpfc_vport *vport = (struct lpfc_vport *)ptr; struct lpfc_hba *phba = vport->phba; + uint32_t tmo_posted; unsigned long iflag; spin_lock_irqsave(&vport->work_port_lock, iflag); - if (!(vport->work_port_events & WORKER_FDMI_TMO)) { + tmo_posted = vport->work_port_events & WORKER_FDMI_TMO; + if (!tmo_posted) vport->work_port_events |= WORKER_FDMI_TMO; - spin_unlock_irqrestore(&vport->work_port_lock, iflag); + spin_unlock_irqrestore(&vport->work_port_lock, iflag); - spin_lock_irqsave(&phba->hbalock, iflag); - if (phba->work_wait) - lpfc_worker_wake_up(phba); - spin_unlock_irqrestore(&phba->hbalock, iflag); - } - else - spin_unlock_irqrestore(&vport->work_port_lock, iflag); + if (!tmo_posted) + lpfc_worker_wake_up(phba); + return; } void diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index d418c7c..5d69dee 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1813,11 +1813,11 @@ lpfc_els_retry_delay(unsigned long ptr) * count until the queued work is done */ evtp->evt_arg1 = lpfc_nlp_get(ndlp); - evtp->evt = LPFC_EVT_ELS_RETRY; - list_add_tail(&evtp->evt_listp, &phba->work_list); - if (phba->work_wait) + if (evtp->evt_arg1) { + evtp->evt = LPFC_EVT_ELS_RETRY; + list_add_tail(&evtp->evt_listp, &phba->work_list); lpfc_worker_wake_up(phba); - + } spin_unlock_irqrestore(&phba->hbalock, flags); return; } @@ -3802,20 +3802,17 @@ lpfc_els_timeout(unsigned long ptr) { struct lpfc_vport *vport = (struct lpfc_vport *) ptr; struct lpfc_hba *phba = vport->phba; + uint32_t tmo_posted; unsigned long iflag; spin_lock_irqsave(&vport->work_port_lock, iflag); - if ((vport->work_port_events & WORKER_ELS_TMO) == 0) { + tmo_posted = vport->work_port_events & WORKER_ELS_TMO; + if (!tmo_posted) vport->work_port_events |= WORKER_ELS_TMO; - spin_unlock_irqrestore(&vport->work_port_lock, iflag); + spin_unlock_irqrestore(&vport->work_port_lock, iflag); - spin_lock_irqsave(&phba->hbalock, iflag); - if (phba->work_wait) - lpfc_worker_wake_up(phba); - spin_unlock_irqrestore(&phba->hbalock, iflag); - } - else - spin_unlock_irqrestore(&vport->work_port_lock, iflag); + if (!tmo_posted) + lpfc_worker_wake_up(phba); return; } @@ -4769,18 +4766,16 @@ lpfc_fabric_block_timeout(unsigned long ptr) struct lpfc_hba *phba = (struct lpfc_hba *) ptr; unsigned long iflags; uint32_t tmo_posted; + spin_lock_irqsave(&phba->pport->work_port_lock, iflags); tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO; if (!tmo_posted) phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO; spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags); - if (!tmo_posted) { - spin_lock_irqsave(&phba->hbalock, iflags); - if (phba->work_wait) - lpfc_worker_wake_up(phba); - spin_unlock_irqrestore(&phba->hbalock, iflags); - } + if (!tmo_posted) + lpfc_worker_wake_up(phba); + return; } static void diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f3dc19d..ba4873c 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -153,11 +153,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) * count until this queued work is done */ evtp->evt_arg1 = lpfc_nlp_get(ndlp); - evtp->evt = LPFC_EVT_DEV_LOSS; - list_add_tail(&evtp->evt_listp, &phba->work_list); - if (phba->work_wait) - wake_up(phba->work_wait); - + if (evtp->evt_arg1) { + evtp->evt = LPFC_EVT_DEV_LOSS; + list_add_tail(&evtp->evt_listp, &phba->work_list); + lpfc_worker_wake_up(phba); + } spin_unlock_irq(&phba->hbalock); return; @@ -276,14 +276,6 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); } - -void -lpfc_worker_wake_up(struct lpfc_hba *phba) -{ - wake_up(phba->work_wait); - return; -} - static void lpfc_work_list_done(struct lpfc_hba *phba) { @@ -429,6 +421,8 @@ lpfc_work_done(struct lpfc_hba *phba) || (pring->flag & LPFC_DEFERRED_RING_EVENT)) { if (pring->flag & LPFC_STOP_IOCB_EVENT) { pring->flag |= LPFC_DEFERRED_RING_EVENT; + /* Set the lpfc data pending flag */ + set_bit(LPFC_DATA_READY, &phba->data_flags); } else { pring->flag &= ~LPFC_DEFERRED_RING_EVENT; lpfc_sli_handle_slow_ring_event(phba, pring, @@ -459,69 +453,29 @@ lpfc_work_done(struct lpfc_hba *phba) lpfc_work_list_done(phba); } -static int -check_work_wait_done(struct lpfc_hba *phba) -{ - struct lpfc_vport *vport; - struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; - int rc = 0; - - spin_lock_irq(&phba->hbalock); - list_for_each_entry(vport, &phba->port_list, listentry) { - if (vport->work_port_events) { - rc = 1; - break; - } - } - if (rc || phba->work_ha || (!list_empty(&phba->work_list)) || - kthread_should_stop() || pring->flag & LPFC_DEFERRED_RING_EVENT) { - rc = 1; - phba->work_found++; - } else - phba->work_found = 0; - spin_unlock_irq(&phba->hbalock); - return rc; -} - - int lpfc_do_work(void *p) { struct lpfc_hba *phba = p; int rc; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq); set_user_nice(current, -20); - phba->work_wait = &work_waitq; - phba->work_found = 0; + phba->data_flags = 0; while (1) { - - rc = wait_event_interruptible(work_waitq, - check_work_wait_done(phba)); - + /* wait and check worker queue activities */ + rc = wait_event_interruptible(phba->work_waitq, + (test_and_clear_bit(LPFC_DATA_READY, + &phba->data_flags) + || kthread_should_stop())); BUG_ON(rc); if (kthread_should_stop()) break; + /* Attend pending lpfc data processing */ lpfc_work_done(phba); - - /* If there is alot of slow ring work, like during link up - * check_work_wait_done() may cause this thread to not give - * up the CPU for very long periods of time. This may cause - * soft lockups or other problems. To avoid these situations - * give up the CPU here after LPFC_MAX_WORKER_ITERATION - * consecutive iterations. - */ - if (phba->work_found >= LPFC_MAX_WORKER_ITERATION) { - phba->work_found = 0; - schedule(); - } } - spin_lock_irq(&phba->hbalock); - phba->work_wait = NULL; - spin_unlock_irq(&phba->hbalock); return 0; } @@ -551,10 +505,10 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, spin_lock_irqsave(&phba->hbalock, flags); list_add_tail(&evtp->evt_listp, &phba->work_list); - if (phba->work_wait) - lpfc_worker_wake_up(phba); spin_unlock_irqrestore(&phba->hbalock, flags); + lpfc_worker_wake_up(phba); + return 1; } @@ -2636,21 +2590,20 @@ lpfc_disc_timeout(unsigned long ptr) { struct lpfc_vport *vport = (struct lpfc_vport *) ptr; struct lpfc_hba *phba = vport->phba; + uint32_t tmo_posted; unsigned long flags = 0; if (unlikely(!phba)) return; - if ((vport->work_port_events & WORKER_DISC_TMO) == 0) { - spin_lock_irqsave(&vport->work_port_lock, flags); + spin_lock_irqsave(&vport->work_port_lock, flags); + tmo_posted = vport->work_port_events & WORKER_DISC_TMO; + if (!tmo_posted) vport->work_port_events |= WORKER_DISC_TMO; - spin_unlock_irqrestore(&vport->work_port_lock, flags); + spin_unlock_irqrestore(&vport->work_port_lock, flags); - spin_lock_irqsave(&phba->hbalock, flags); - if (phba->work_wait) - lpfc_worker_wake_up(phba); - spin_unlock_irqrestore(&phba->hbalock, flags); - } + if (!tmo_posted) + lpfc_worker_wake_up(phba); return; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 6fcddda..53cedba 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -551,18 +551,18 @@ static void lpfc_hb_timeout(unsigned long ptr) { struct lpfc_hba *phba; + uint32_t tmo_posted; unsigned long iflag; phba = (struct lpfc_hba *)ptr; spin_lock_irqsave(&phba->pport->work_port_lock, iflag); - if (!(phba->pport->work_port_events & WORKER_HB_TMO)) + tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO; + if (!tmo_posted) phba->pport->work_port_events |= WORKER_HB_TMO; spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); - spin_lock_irqsave(&phba->hbalock, iflag); - if (phba->work_wait) - wake_up(phba->work_wait); - spin_unlock_irqrestore(&phba->hbalock, iflag); + if (!tmo_posted) + lpfc_worker_wake_up(phba); return; } @@ -2104,6 +2104,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT); phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4)); + /* Initialize the wait queue head for the kernel thread */ + init_waitqueue_head(&phba->work_waitq); + /* Startup the kernel thread for this host adapter. */ phba->worker_thread = kthread_run(lpfc_do_work, phba, "lpfc_worker_%d", phba->brd_no); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 3926aff..1e88b7a 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -50,6 +50,7 @@ void lpfc_adjust_queue_depth(struct lpfc_hba *phba) { unsigned long flags; + uint32_t evt_posted; spin_lock_irqsave(&phba->hbalock, flags); atomic_inc(&phba->num_rsrc_err); @@ -65,17 +66,13 @@ lpfc_adjust_queue_depth(struct lpfc_hba *phba) spin_unlock_irqrestore(&phba->hbalock, flags); spin_lock_irqsave(&phba->pport->work_port_lock, flags); - if ((phba->pport->work_port_events & - WORKER_RAMP_DOWN_QUEUE) == 0) { + evt_posted = phba->pport->work_port_events & WORKER_RAMP_DOWN_QUEUE; + if (!evt_posted) phba->pport->work_port_events |= WORKER_RAMP_DOWN_QUEUE; - } spin_unlock_irqrestore(&phba->pport->work_port_lock, flags); - spin_lock_irqsave(&phba->hbalock, flags); - if (phba->work_wait) - wake_up(phba->work_wait); - spin_unlock_irqrestore(&phba->hbalock, flags); - + if (!evt_posted) + lpfc_worker_wake_up(phba); return; } @@ -89,6 +86,7 @@ lpfc_rampup_queue_depth(struct lpfc_vport *vport, { unsigned long flags; struct lpfc_hba *phba = vport->phba; + uint32_t evt_posted; atomic_inc(&phba->num_cmd_success); if (vport->cfg_lun_queue_depth <= sdev->queue_depth) @@ -103,16 +101,14 @@ lpfc_rampup_queue_depth(struct lpfc_vport *vport, spin_unlock_irqrestore(&phba->hbalock, flags); spin_lock_irqsave(&phba->pport->work_port_lock, flags); - if ((phba->pport->work_port_events & - WORKER_RAMP_UP_QUEUE) == 0) { + evt_posted = phba->pport->work_port_events & WORKER_RAMP_UP_QUEUE; + if (!evt_posted) phba->pport->work_port_events |= WORKER_RAMP_UP_QUEUE; - } spin_unlock_irqrestore(&phba->pport->work_port_lock, flags); - spin_lock_irqsave(&phba->hbalock, flags); - if (phba->work_wait) - wake_up(phba->work_wait); - spin_unlock_irqrestore(&phba->hbalock, flags); + if (!evt_posted) + lpfc_worker_wake_up(phba); + return; } void diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 70a0a9e..3dba3a9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -324,9 +324,7 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring) phba->work_ha |= HA_ERATT; phba->work_hs = HS_FFER3; - /* hbalock should already be held */ - if (phba->work_wait) - lpfc_worker_wake_up(phba); + lpfc_worker_wake_up(phba); return NULL; } @@ -1309,9 +1307,7 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) phba->work_ha |= HA_ERATT; phba->work_hs = HS_FFER3; - /* hbalock should already be held */ - if (phba->work_wait) - lpfc_worker_wake_up(phba); + lpfc_worker_wake_up(phba); return; } @@ -2611,12 +2607,9 @@ lpfc_mbox_timeout(unsigned long ptr) phba->pport->work_port_events |= WORKER_MBOX_TMO; spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); - if (!tmo_posted) { - spin_lock_irqsave(&phba->hbalock, iflag); - if (phba->work_wait) - lpfc_worker_wake_up(phba); - spin_unlock_irqrestore(&phba->hbalock, iflag); - } + if (!tmo_posted) + lpfc_worker_wake_up(phba); + return; } void @@ -3374,8 +3367,12 @@ lpfc_sli_host_down(struct lpfc_vport *vport) for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; prev_pring_flag = pring->flag; - if (pring->ringno == LPFC_ELS_RING) /* Only slow rings */ + /* Only slow rings */ + if (pring->ringno == LPFC_ELS_RING) { pring->flag |= LPFC_DEFERRED_RING_EVENT; + /* Set the lpfc data pending flag */ + set_bit(LPFC_DATA_READY, &phba->data_flags); + } /* * Error everything on the txq since these iocbs have not been * given to the FW yet. @@ -3434,8 +3431,12 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) spin_lock_irqsave(&phba->hbalock, flags); for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; - if (pring->ringno == LPFC_ELS_RING) /* Only slow rings */ + /* Only slow rings */ + if (pring->ringno == LPFC_ELS_RING) { pring->flag |= LPFC_DEFERRED_RING_EVENT; + /* Set the lpfc data pending flag */ + set_bit(LPFC_DATA_READY, &phba->data_flags); + } /* * Error everything on the txq since these iocbs have not been @@ -4159,7 +4160,7 @@ lpfc_intr_handler(int irq, void *dev_id) "pwork:x%x hawork:x%x wait:x%x", phba->work_ha, work_ha_copy, (uint32_t)((unsigned long) - phba->work_wait)); + &phba->work_waitq)); control &= ~(HC_R0INT_ENA << LPFC_ELS_RING); @@ -4172,7 +4173,7 @@ lpfc_intr_handler(int irq, void *dev_id) "x%x hawork:x%x wait:x%x", phba->work_ha, work_ha_copy, (uint32_t)((unsigned long) - phba->work_wait)); + &phba->work_waitq)); } spin_unlock(&phba->hbalock); } @@ -4297,9 +4298,8 @@ send_current_mbox: spin_lock(&phba->hbalock); phba->work_ha |= work_ha_copy; - if (phba->work_wait) - lpfc_worker_wake_up(phba); spin_unlock(&phba->hbalock); + lpfc_worker_wake_up(phba); } ha_copy &= ~(phba->work_ha_mask); -- cgit v0.10.2 From 495a714c50e2c6ca6357129812f983b3ac0a32f2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:52:59 -0400 Subject: [SCSI] lpfc 8.2.7 : Miscellaneous Fixes Miscellaneous Fixes: - Fix bug in mbox sysfs interface that locked in EAGAIN if discovery stalled. - Fix missing error message when npiv and loop are true when link up occurs. - Fix panic in lpfc_scsi_cmd_iocb_cmpl: scsi_buf was NULL, but created race conditions with other code paths. - Fix error in sysfs mailbox structure that didn't rezero on next use. - Add missing mempool_free() to attachment failure path - Fix missing put of ndlp structure during driver unload. - Fix applications unable to send mailbox commands during discovery. - Remove unused argument (type) from function lpfc_post_buffer() API - Fix vport name is not shown after hbacmd vportcreate. - Remove repeated code statements. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index e3e5b54..e0e018d 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -33,6 +33,7 @@ struct lpfc_sli2_slim; #define LPFC_MAX_SG_SEG_CNT 256 /* sg element count per scsi cmnd */ #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ +#define LPFC_VNAME_LEN 100 /* vport symbolic name length */ /* * Following time intervals are used of adjusting SCSI device diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 960baaf..37bfa0b 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1995,8 +1995,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, /* Don't allow mailbox commands to be sent when blocked * or when in the middle of discovery */ - if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO || - vport->fc_flag & FC_NDISC_ACTIVE) { + if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { sysfs_mbox_idle(phba); spin_unlock_irq(&phba->hbalock); return -EAGAIN; diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 7c9f831..1b82452 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -142,7 +142,7 @@ int lpfc_config_port_post(struct lpfc_hba *); int lpfc_hba_down_prep(struct lpfc_hba *); int lpfc_hba_down_post(struct lpfc_hba *); void lpfc_hba_init(struct lpfc_hba *, uint32_t *); -int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); +int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int); void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); int lpfc_online(struct lpfc_hba *); void lpfc_unblock_mgmt_io(struct lpfc_hba *); @@ -263,6 +263,7 @@ extern int lpfc_sli_mode; extern int lpfc_enable_npiv; int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); +int lpfc_vport_symbolic_port_name(struct lpfc_vport *, char *, size_t); void lpfc_terminate_rport_io(struct fc_rport *); void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 5442ce3..7fc74cf 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -101,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* Not enough posted buffers; Try posting more buffers */ phba->fc_stat.NoRcvBuf++; if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) - lpfc_post_buffer(phba, pring, 2, 1); + lpfc_post_buffer(phba, pring, 2); return; } @@ -151,7 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } list_del(&iocbq->list); lpfc_sli_release_iocbq(phba, iocbq); - lpfc_post_buffer(phba, pring, i, 1); + lpfc_post_buffer(phba, pring, i); } } } @@ -990,7 +990,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; } -static int +int lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol, size_t size) { diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 5d69dee..f54e0f7 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3857,9 +3857,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) els_command == ELS_CMD_FDISC) continue; - if (vport != piocb->vport) - continue; - if (piocb->drvrTimeout > 0) { if (piocb->drvrTimeout >= timeout) piocb->drvrTimeout -= timeout; @@ -4013,7 +4010,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt; cmd = *payload; if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0) - lpfc_post_buffer(phba, pring, 1, 1); + lpfc_post_buffer(phba, pring, 1); did = icmd->un.rcvels.remoteID; if (icmd->ulpStatus) { @@ -4322,7 +4319,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, phba->fc_stat.NoRcvBuf++; /* Not enough posted buffers; Try posting more buffers */ if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) - lpfc_post_buffer(phba, pring, 0, 1); + lpfc_post_buffer(phba, pring, 0); return; } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index ba4873c..a98d11b 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -917,6 +917,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) if (phba->fc_topology == TOPOLOGY_LOOP) { phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; + if (phba->cfg_enable_npiv) + lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, + "1309 Link Up Event npiv not supported in loop " + "topology\n"); /* Get Loop Map information */ if (la->il) vport->fc_flag |= FC_LBIT; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 53cedba..5b6e539 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -145,8 +145,10 @@ lpfc_config_port_prep(struct lpfc_hba *phba) return -ERESTART; } - if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp) + if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp) { + mempool_free(pmb, phba->mbox_mem_pool); return -EINVAL; + } /* Save information as VPD data */ vp->rev.rBit = 1; @@ -1197,8 +1199,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) /* Returns the number of buffers NOT posted. */ /**************************************************/ int -lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, - int type) +lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt) { IOCB_t *icmd; struct lpfc_iocbq *iocb; @@ -1298,7 +1299,7 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba) struct lpfc_sli *psli = &phba->sli; /* Ring 0, ELS / CT buffers */ - lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0, 1); + lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0); /* Ring 2 - FCP no buffers needed */ return 0; @@ -1457,6 +1458,15 @@ lpfc_cleanup(struct lpfc_vport *vport) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); + + /* nlp_type zero is not defined, nlp_flag zero also not defined, + * nlp_state is unused, this happens when + * an initiator has logged + * into us so cleanup this ndlp. + */ + if ((ndlp->nlp_type == 0) && (ndlp->nlp_flag == 0) && + (ndlp->nlp_state == 0)) + lpfc_nlp_put(ndlp); } /* At this point, ALL ndlp's should be gone diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 1e88b7a..c94da4f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -605,9 +605,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, result = cmd->result; sdev = cmd->device; lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); - spin_lock_irqsave(sdev->host->host_lock, flags); - lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */ - spin_unlock_irqrestore(sdev->host->host_lock, flags); cmd->scsi_done(cmd); if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { @@ -616,6 +613,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * wake up the thread. */ spin_lock_irqsave(sdev->host->host_lock, flags); + lpfc_cmd->pCmd = NULL; if (lpfc_cmd->waitq) wake_up(lpfc_cmd->waitq); spin_unlock_irqrestore(sdev->host->host_lock, flags); @@ -686,6 +684,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * wake up the thread. */ spin_lock_irqsave(sdev->host->host_lock, flags); + lpfc_cmd->pCmd = NULL; if (lpfc_cmd->waitq) wake_up(lpfc_cmd->waitq); spin_unlock_irqrestore(sdev->host->host_lock, flags); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 3dba3a9..f40aa7b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -3763,7 +3763,6 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, lpfc_ctx_cmd ctx_cmd) { struct lpfc_scsi_buf *lpfc_cmd; - struct scsi_cmnd *cmnd; int rc = 1; if (!(iocbq->iocb_flag & LPFC_IO_FCP)) @@ -3773,19 +3772,20 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, return rc; lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); - cmnd = lpfc_cmd->pCmd; - if (cmnd == NULL) + if (lpfc_cmd->pCmd == NULL) return rc; switch (ctx_cmd) { case LPFC_CTX_LUN: - if ((cmnd->device->id == tgt_id) && - (cmnd->device->lun == lun_id)) + if ((lpfc_cmd->rdata->pnode) && + (lpfc_cmd->rdata->pnode->nlp_sid == tgt_id) && + (scsilun_to_int(&lpfc_cmd->fcp_cmnd->fcp_lun) == lun_id)) rc = 0; break; case LPFC_CTX_TGT: - if (cmnd->device->id == tgt_id) + if ((lpfc_cmd->rdata->pnode) && + (lpfc_cmd->rdata->pnode->nlp_sid == tgt_id)) rc = 0; break; case LPFC_CTX_HOST: @@ -3995,6 +3995,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, if (pmboxq->context1) return MBX_NOT_FINISHED; + pmboxq->mbox_flag &= ~LPFC_MBX_WAKE; /* setup wake call as IOCB callback */ pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait; /* setup context field to pass wait_queue pointer to wake function */ diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 6feaf59..109f89d 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -216,6 +216,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) int vpi; int rc = VPORT_ERROR; int status; + int size; if ((phba->sli_rev < 3) || !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { @@ -278,7 +279,20 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8); memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8); - + size = strnlen(fc_vport->symbolic_name, LPFC_VNAME_LEN); + if (size) { + vport->vname = kzalloc(size+1, GFP_KERNEL); + if (!vport->vname) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, + "1814 Create VPORT failed. " + "vname allocation failed.\n"); + rc = VPORT_ERROR; + lpfc_free_vpi(phba, vpi); + destroy_port(vport); + goto error_out; + } + memcpy(vport->vname, fc_vport->symbolic_name, size+1); + } if (fc_vport->node_name != 0) u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn); if (fc_vport->port_name != 0) -- cgit v0.10.2 From ff0f4cb5ea322dcc32d08bab2d758c050ba1ab07 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sat, 14 Jun 2008 22:53:02 -0400 Subject: [SCSI] lpfc 8.2.7 : Update version to 8.2.7 Update lpfc driver version to 8.2.7 Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index b22b893..ad24cac 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.2.6" +#define LPFC_DRIVER_VERSION "8.2.7" #define LPFC_DRIVER_NAME "lpfc" -- cgit v0.10.2 From c95fddc729fafb43f420747027eeb998c2e5e798 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:32 -0500 Subject: [SCSI] iscsi class: fix refcount leak Must do a module_out if the endpoint lookup fails. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 9fd5c6d..bc0f74d4 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1422,8 +1422,10 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) break; case ISCSI_UEVENT_CREATE_BOUND_SESSION: ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle); - if (!ep) - return -EINVAL; + if (!ep) { + err = -EINVAL; + break; + } err = iscsi_if_create_session(priv, ep, ev, ev->u.c_bound_session.initial_cmdsn, -- cgit v0.10.2 From 8e9a20cee4511be4560f9c858d9994eb6913731e Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:33 -0500 Subject: [SCSI] libiscsi, iscsi_tcp, ib_iser: fix setting of can_queue with old tools. This patch fixes two bugs that are related. 1. Old tools did not set can_queue/cmds_max. This patch modifies libiscsi so that when we add the host we catch this and set it to the default. 2. iscsi_tcp thought that the scsi command that was passed to the eh functions needed a iscsi_cmd_task allocated for it. It only needed a mgmt task, and now it does not matter since it all comes from the same pool and libiscsi handles this for the drivers. ib_iser had copied iscsi_tcp's code and set can_queue to its max - 1 to handle this. So this patch removes the max -1, and just sets it to the max. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index c02eabd..a56931e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -595,7 +595,6 @@ static struct scsi_host_template iscsi_iser_sht = { .name = "iSCSI Initiator over iSER, v." DRV_VER, .queuecommand = iscsi_queuecommand, .change_queue_depth = iscsi_change_queue_depth, - .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1, .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, .max_sectors = 1024, .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN, diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 0bd8b3d..2a2f009 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -1865,7 +1865,6 @@ iscsi_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, shost->max_id = 0; shost->max_channel = 0; shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE; - shost->can_queue = cmds_max; if (iscsi_host_add(shost, NULL)) goto free_host; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 8b4e412..299e075 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1857,6 +1857,9 @@ EXPORT_SYMBOL_GPL(iscsi_pool_free); */ int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev) { + if (!shost->can_queue) + shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX; + return scsi_add_host(shost, pdev); } EXPORT_SYMBOL_GPL(iscsi_host_add); @@ -1942,6 +1945,9 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, struct iscsi_session *session; struct iscsi_cls_session *cls_session; int cmd_i, scsi_cmds, total_cmds = cmds_max; + + if (!total_cmds) + total_cmds = ISCSI_DEF_XMIT_CMDS_MAX; /* * The iscsi layer needs some tasks for nop handling and tmfs, * so the cmds_max must at least be greater than ISCSI_MGMT_CMDS_MAX -- cgit v0.10.2 From 4c2133c82385c31dd3eed76b07da1e986eb00294 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:34 -0500 Subject: [SCSI] iscsi class: update version number Update iscsi class version number. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index bc0f74d4..8e34f3c 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -34,7 +34,7 @@ #define ISCSI_CONN_ATTRS 13 #define ISCSI_HOST_ATTRS 4 -#define ISCSI_TRANSPORT_VERSION "2.0-869" +#define ISCSI_TRANSPORT_VERSION "2.0-870" struct iscsi_internal { int daemon_pid; -- cgit v0.10.2 From f80f868ec463b0463b332cdb704fe5438f013f98 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Jun 2008 10:11:35 -0500 Subject: [SCSI] iscsi class: fix endpoint leak class_find_device gets a ref to the device so we must release it. The class will serialize access to the ep so we do not have to worry about a remove racing with the callers access, so we can simplify the use and drop the ref right away. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 8e34f3c..3af7cbc 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -219,6 +219,7 @@ EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint); struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) { + struct iscsi_endpoint *ep; struct device *dev; dev = class_find_device(&iscsi_endpoint_class, &handle, @@ -226,7 +227,13 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) if (!dev) return NULL; - return iscsi_dev_to_endpoint(dev); + ep = iscsi_dev_to_endpoint(dev); + /* + * we can drop this now because the interface will prevent + * removals and lookups from racing. + */ + put_device(dev); + return ep; } EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); -- cgit v0.10.2 From eac6e8e449647cbb9efee53977c8bfee0aa7d69e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 19 Jun 2008 10:02:58 -0600 Subject: [SCSI] scsi_debug: add support for rotation speed Add support for VPD page b1 to scsi_debug SCSI VPD page b1 reports the nominal rotation speed of the device. Since scsi_debug is ram-based, claim to be a non-rotating medium. Signed-off-by: Matthew Wilcox Acked-by: Douglas Gilbert Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3901125..01d11a0 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -643,6 +643,14 @@ static int inquiry_evpd_b0(unsigned char * arr) return sizeof(vpdb0_data); } +static int inquiry_evpd_b1(unsigned char *arr) +{ + memset(arr, 0, 0x3c); + arr[0] = 0; + arr[1] = 1; + + return 0x3c; +} #define SDEBUG_LONG_INQ_SZ 96 #define SDEBUG_MAX_INQ_ARR_SZ 584 @@ -698,6 +706,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, arr[n++] = 0x88; /* SCSI ports */ arr[n++] = 0x89; /* ATA information */ arr[n++] = 0xb0; /* Block limits (SBC) */ + arr[n++] = 0xb1; /* Block characteristics (SBC) */ arr[3] = n - 4; /* number of supported VPD pages */ } else if (0x80 == cmd[2]) { /* unit serial number */ arr[1] = cmd[2]; /*sanity */ @@ -737,6 +746,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, } else if (0xb0 == cmd[2]) { /* Block limits (SBC) */ arr[1] = cmd[2]; /*sanity */ arr[3] = inquiry_evpd_b0(&arr[4]); + } else if (0xb1 == cmd[2]) { /* Block characteristics (SBC) */ + arr[1] = cmd[2]; /*sanity */ + arr[3] = inquiry_evpd_b1(&arr[4]); } else { /* Illegal request, invalid field in cdb */ mk_sense_buffer(devip, ILLEGAL_REQUEST, -- cgit v0.10.2 From a793804f25fb2c0fe2b784450092699ea3475332 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 30 Sep 2007 17:10:42 -0700 Subject: [SCSI] esp: Correct chip ID probing sequence. The features enable bit has to be set in the config2 register before we can be absolutely sure we will probe a correct part unique ID and family code from the transfer-count-high register. Also, reload the CFACT, STP, SOFF, and TIMEO near the end of esp_reset_esp(). From a patch by Maciej W. Rozycki. Signed-off-by: David S. Miller Signed-off-by: James Bottomley diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index a0b6d41..3d5ad24 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -219,19 +219,10 @@ static void esp_reset_esp(struct esp *esp) /* Now reset the ESP chip */ scsi_esp_cmd(esp, ESP_CMD_RC); scsi_esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA); + if (esp->rev == FAST) + esp_write8(ESP_CONFIG2_FENAB, ESP_CFG2); scsi_esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA); - /* Reload the configuration registers */ - esp_write8(esp->cfact, ESP_CFACT); - - esp->prev_stp = 0; - esp_write8(esp->prev_stp, ESP_STP); - - esp->prev_soff = 0; - esp_write8(esp->prev_soff, ESP_SOFF); - - esp_write8(esp->neg_defp, ESP_TIMEO); - /* This is the only point at which it is reliable to read * the ID-code for a fast ESP chip variants. */ @@ -316,6 +307,17 @@ static void esp_reset_esp(struct esp *esp) break; } + /* Reload the configuration registers */ + esp_write8(esp->cfact, ESP_CFACT); + + esp->prev_stp = 0; + esp_write8(esp->prev_stp, ESP_STP); + + esp->prev_soff = 0; + esp_write8(esp->prev_soff, ESP_SOFF); + + esp_write8(esp->neg_defp, ESP_TIMEO); + /* Eat any bitrot in the chip */ esp_read8(ESP_INTRPT); udelay(100); -- cgit v0.10.2 From dbfe54a9c9a9e31cdf71704e4e70d10d22a57264 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Thu, 19 Jun 2008 20:20:12 -0700 Subject: [SCSI] esp: correct module name in Kconfig help for SCSI_SUNESP The module name was changed from esp to sun_esp some time ago. Also correct the list of chips supported by the driver. Signed-off-by: Frans Pop Signed-off-by: David S. Miller Signed-off-by: James Bottomley diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 7886ec6..994943f 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1738,10 +1738,12 @@ config SCSI_SUNESP select SCSI_SPI_ATTRS help This is the driver for the Sun ESP SCSI host adapter. The ESP - chipset is present in most SPARC SBUS-based computers. + chipset is present in most SPARC SBUS-based computers and + supports the Emulex family of ESP SCSI chips (esp100, esp100A, + esp236, fas101, fas236) as well as the Qlogic fas366 SCSI chip. To compile this driver as a module, choose M here: the - module will be called esp. + module will be called sun_esp. config ZFCP tristate "FCP host bus adapter driver for IBM eServer zSeries" -- cgit v0.10.2 From aa91696e56a0870db5754610e9f9b937e77507e0 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 17 Jun 2008 12:47:32 -0400 Subject: [SCSI] sd: Move sd.h header file Christoph objected to having sd.h in include/scsi since it is internal to the sd driver. Move it to drivers/scsi/sd.h. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 01cefbb..e19691f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -58,8 +58,8 @@ #include #include #include -#include +#include "sd.h" #include "scsi_logging.h" MODULE_AUTHOR("Eric Youngdale"); diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h new file mode 100644 index 0000000..4f032d4 --- /dev/null +++ b/drivers/scsi/sd.h @@ -0,0 +1,57 @@ +#ifndef _SCSI_DISK_H +#define _SCSI_DISK_H + +/* + * More than enough for everybody ;) The huge number of majors + * is a leftover from 16bit dev_t days, we don't really need that + * much numberspace. + */ +#define SD_MAJORS 16 + +/* + * This is limited by the naming scheme enforced in sd_probe, + * add another character to it if you really need more disks. + */ +#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) + +/* + * Time out in seconds for disks and Magneto-opticals (which are slower). + */ +#define SD_TIMEOUT (30 * HZ) +#define SD_MOD_TIMEOUT (75 * HZ) + +/* + * Number of allowed retries + */ +#define SD_MAX_RETRIES 5 +#define SD_PASSTHROUGH_RETRIES 1 + +/* + * Size of the initial data buffer for mode and read capacity data + */ +#define SD_BUF_SIZE 512 + +struct scsi_disk { + struct scsi_driver *driver; /* always &sd_template */ + struct scsi_device *device; + struct device dev; + struct gendisk *disk; + unsigned int openers; /* protected by BKL for now, yuck */ + sector_t capacity; /* size in 512-byte sectors */ + u32 index; + u8 media_present; + u8 write_prot; + unsigned previous_state : 1; + unsigned WCE : 1; /* state of disk WCE bit */ + unsigned RCD : 1; /* state of disk RCD bit, unused */ + unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ +}; +#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) + +#define sd_printk(prefix, sdsk, fmt, a...) \ + (sdsk)->disk ? \ + sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ + (sdsk)->disk->disk_name, ##a) : \ + sdev_printk(prefix, (sdsk)->device, fmt, ##a) + +#endif /* _SCSI_DISK_H */ diff --git a/include/scsi/sd.h b/include/scsi/sd.h deleted file mode 100644 index 4f032d4..0000000 --- a/include/scsi/sd.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _SCSI_DISK_H -#define _SCSI_DISK_H - -/* - * More than enough for everybody ;) The huge number of majors - * is a leftover from 16bit dev_t days, we don't really need that - * much numberspace. - */ -#define SD_MAJORS 16 - -/* - * This is limited by the naming scheme enforced in sd_probe, - * add another character to it if you really need more disks. - */ -#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) - -/* - * Time out in seconds for disks and Magneto-opticals (which are slower). - */ -#define SD_TIMEOUT (30 * HZ) -#define SD_MOD_TIMEOUT (75 * HZ) - -/* - * Number of allowed retries - */ -#define SD_MAX_RETRIES 5 -#define SD_PASSTHROUGH_RETRIES 1 - -/* - * Size of the initial data buffer for mode and read capacity data - */ -#define SD_BUF_SIZE 512 - -struct scsi_disk { - struct scsi_driver *driver; /* always &sd_template */ - struct scsi_device *device; - struct device dev; - struct gendisk *disk; - unsigned int openers; /* protected by BKL for now, yuck */ - sector_t capacity; /* size in 512-byte sectors */ - u32 index; - u8 media_present; - u8 write_prot; - unsigned previous_state : 1; - unsigned WCE : 1; /* state of disk WCE bit */ - unsigned RCD : 1; /* state of disk RCD bit, unused */ - unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ -}; -#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) - -#define sd_printk(prefix, sdsk, fmt, a...) \ - (sdsk)->disk ? \ - sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ - (sdsk)->disk->disk_name, ##a) : \ - sdev_printk(prefix, (sdsk)->device, fmt, ##a) - -#endif /* _SCSI_DISK_H */ -- cgit v0.10.2 From 5b635da11e3a6387172abd651d26d8ef54b1fbc7 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 25 Jun 2008 11:22:41 -0400 Subject: [SCSI] sd: Move scsi_disk() accessor function to sd.h Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e19691f..71069d9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -295,11 +295,6 @@ static int sd_major(int major_idx) } } -static inline struct scsi_disk *scsi_disk(struct gendisk *disk) -{ - return container_of(disk->private_data, struct scsi_disk, driver); -} - static struct scsi_disk *__scsi_disk_get(struct gendisk *disk) { struct scsi_disk *sdkp = NULL; diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 4f032d4..03a3d45 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -48,6 +48,11 @@ struct scsi_disk { }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) +static inline struct scsi_disk *scsi_disk(struct gendisk *disk) +{ + return container_of(disk->private_data, struct scsi_disk, driver); +} + #define sd_printk(prefix, sdsk, fmt, a...) \ (sdsk)->disk ? \ sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ -- cgit v0.10.2 From f11f594edba7f689af9792a5673ed59d660ad371 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 25 Jun 2008 11:22:42 -0400 Subject: [SCSI] lib: Add support for the T10 (SCSI) Data Integrity Field CRC The SCSI Block Protocol uses this 16-bit CRC to verify the integrity of each data sector. crc_t10dif() is used by sd_dif.c when performing I/O to or from disks formatted with protection information. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/include/linux/crc-t10dif.h b/include/linux/crc-t10dif.h new file mode 100644 index 0000000..a9c96d8 --- /dev/null +++ b/include/linux/crc-t10dif.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_CRC_T10DIF_H +#define _LINUX_CRC_T10DIF_H + +#include + +__u16 crc_t10dif(unsigned char const *, size_t); + +#endif diff --git a/lib/Kconfig b/lib/Kconfig index 8cc8e87..c7ad7a5 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -29,6 +29,13 @@ config CRC16 the kernel tree does. Such modules that use library CRC16 functions require M here. +config CRC_T10DIF + tristate "CRC calculation for the T10 Data Integrity Field" + help + This option is only needed if a module that's not in the + kernel tree needs to calculate CRC checks for use with the + SCSI data integrity subsystem. + config CRC_ITU_T tristate "CRC ITU-T V.41 functions" help diff --git a/lib/Makefile b/lib/Makefile index 74b0cfb..237a829 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -45,6 +45,7 @@ endif obj-$(CONFIG_BITREVERSE) += bitrev.o obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o obj-$(CONFIG_CRC16) += crc16.o +obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o obj-$(CONFIG_CRC32) += crc32.o obj-$(CONFIG_CRC7) += crc7.o diff --git a/lib/crc-t10dif.c b/lib/crc-t10dif.c new file mode 100644 index 0000000..fbbd66e --- /dev/null +++ b/lib/crc-t10dif.c @@ -0,0 +1,67 @@ +/* + * T10 Data Integrity Field CRC16 calculation + * + * Copyright (c) 2007 Oracle Corporation. All rights reserved. + * Written by Martin K. Petersen + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include + +/* Table generated using the following polynomium: + * x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + * gt: 0x8bb7 + */ +static const __u16 t10_dif_crc_table[256] = { + 0x0000, 0x8BB7, 0x9CD9, 0x176E, 0xB205, 0x39B2, 0x2EDC, 0xA56B, + 0xEFBD, 0x640A, 0x7364, 0xF8D3, 0x5DB8, 0xD60F, 0xC161, 0x4AD6, + 0x54CD, 0xDF7A, 0xC814, 0x43A3, 0xE6C8, 0x6D7F, 0x7A11, 0xF1A6, + 0xBB70, 0x30C7, 0x27A9, 0xAC1E, 0x0975, 0x82C2, 0x95AC, 0x1E1B, + 0xA99A, 0x222D, 0x3543, 0xBEF4, 0x1B9F, 0x9028, 0x8746, 0x0CF1, + 0x4627, 0xCD90, 0xDAFE, 0x5149, 0xF422, 0x7F95, 0x68FB, 0xE34C, + 0xFD57, 0x76E0, 0x618E, 0xEA39, 0x4F52, 0xC4E5, 0xD38B, 0x583C, + 0x12EA, 0x995D, 0x8E33, 0x0584, 0xA0EF, 0x2B58, 0x3C36, 0xB781, + 0xD883, 0x5334, 0x445A, 0xCFED, 0x6A86, 0xE131, 0xF65F, 0x7DE8, + 0x373E, 0xBC89, 0xABE7, 0x2050, 0x853B, 0x0E8C, 0x19E2, 0x9255, + 0x8C4E, 0x07F9, 0x1097, 0x9B20, 0x3E4B, 0xB5FC, 0xA292, 0x2925, + 0x63F3, 0xE844, 0xFF2A, 0x749D, 0xD1F6, 0x5A41, 0x4D2F, 0xC698, + 0x7119, 0xFAAE, 0xEDC0, 0x6677, 0xC31C, 0x48AB, 0x5FC5, 0xD472, + 0x9EA4, 0x1513, 0x027D, 0x89CA, 0x2CA1, 0xA716, 0xB078, 0x3BCF, + 0x25D4, 0xAE63, 0xB90D, 0x32BA, 0x97D1, 0x1C66, 0x0B08, 0x80BF, + 0xCA69, 0x41DE, 0x56B0, 0xDD07, 0x786C, 0xF3DB, 0xE4B5, 0x6F02, + 0x3AB1, 0xB106, 0xA668, 0x2DDF, 0x88B4, 0x0303, 0x146D, 0x9FDA, + 0xD50C, 0x5EBB, 0x49D5, 0xC262, 0x6709, 0xECBE, 0xFBD0, 0x7067, + 0x6E7C, 0xE5CB, 0xF2A5, 0x7912, 0xDC79, 0x57CE, 0x40A0, 0xCB17, + 0x81C1, 0x0A76, 0x1D18, 0x96AF, 0x33C4, 0xB873, 0xAF1D, 0x24AA, + 0x932B, 0x189C, 0x0FF2, 0x8445, 0x212E, 0xAA99, 0xBDF7, 0x3640, + 0x7C96, 0xF721, 0xE04F, 0x6BF8, 0xCE93, 0x4524, 0x524A, 0xD9FD, + 0xC7E6, 0x4C51, 0x5B3F, 0xD088, 0x75E3, 0xFE54, 0xE93A, 0x628D, + 0x285B, 0xA3EC, 0xB482, 0x3F35, 0x9A5E, 0x11E9, 0x0687, 0x8D30, + 0xE232, 0x6985, 0x7EEB, 0xF55C, 0x5037, 0xDB80, 0xCCEE, 0x4759, + 0x0D8F, 0x8638, 0x9156, 0x1AE1, 0xBF8A, 0x343D, 0x2353, 0xA8E4, + 0xB6FF, 0x3D48, 0x2A26, 0xA191, 0x04FA, 0x8F4D, 0x9823, 0x1394, + 0x5942, 0xD2F5, 0xC59B, 0x4E2C, 0xEB47, 0x60F0, 0x779E, 0xFC29, + 0x4BA8, 0xC01F, 0xD771, 0x5CC6, 0xF9AD, 0x721A, 0x6574, 0xEEC3, + 0xA415, 0x2FA2, 0x38CC, 0xB37B, 0x1610, 0x9DA7, 0x8AC9, 0x017E, + 0x1F65, 0x94D2, 0x83BC, 0x080B, 0xAD60, 0x26D7, 0x31B9, 0xBA0E, + 0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3 +}; + +__u16 crc_t10dif(const unsigned char *buffer, size_t len) +{ + __u16 crc = 0; + unsigned int i; + + for (i = 0 ; i < len ; i++) + crc = (crc << 8) ^ t10_dif_crc_table[((crc >> 8) ^ buffer[i]) & 0xff]; + + return crc; +} +EXPORT_SYMBOL(crc_t10dif); + +MODULE_DESCRIPTION("T10 DIF CRC calculation"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 39120e11705782c77d3a47d7d2927676fd8e3aaa Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 1 Jul 2008 13:03:19 -0500 Subject: [SCSI] sg: Add target reset support Adds support for target reset to SG_SCSI_RESET. Signed-off-by: Brian King Acked-by: Douglas Gilbert Signed-off-by: James Bottomley diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ea0edd1..2010fa0 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1026,6 +1026,9 @@ sg_ioctl(struct inode *inode, struct file *filp, case SG_SCSI_RESET_DEVICE: val = SCSI_TRY_RESET_DEVICE; break; + case SG_SCSI_RESET_TARGET: + val = SCSI_TRY_RESET_TARGET; + break; case SG_SCSI_RESET_BUS: val = SCSI_TRY_RESET_BUS; break; diff --git a/include/scsi/sg.h b/include/scsi/sg.h index 519c49a..934ae38 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -206,6 +206,7 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ #define SG_SCSI_RESET_DEVICE 1 #define SG_SCSI_RESET_BUS 2 #define SG_SCSI_RESET_HOST 3 +#define SG_SCSI_RESET_TARGET 4 /* synchronous SCSI command ioctl, (only in version 3 interface) */ #define SG_IO 0x2285 /* similar effect as write() followed by read() */ -- cgit v0.10.2 From 072b91f9c6510d0ec4a49d07dbc318760c7da7b3 Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 1 Jul 2008 13:14:30 -0500 Subject: [SCSI] ibmvfc: IBM Power Virtual Fibre Channel Adapter Client Driver This patch adds a new device driver to support the Virtual Fibre Channel interface on IBM Power based servers. The Virtual I/O Server on IBM Power servers utilizes N-Port ID Virtualization to export a Virtual Fibre Channel adapter to the client. This driver is the client device driver. Signed-off-by: Brian King Signed-off-by: James Bottomley diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 994943f..26be540 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -888,6 +888,25 @@ config SCSI_IBMVSCSIS To compile this driver as a module, choose M here: the module will be called ibmvstgt. +config SCSI_IBMVFC + tristate "IBM Virtual FC support" + depends on PPC_PSERIES && SCSI + select SCSI_FC_ATTRS + help + This is the IBM POWER Virtual FC Client + + To compile this driver as a module, choose M here: the + module will be called ibmvfc. + +config SCSI_IBMVFC_TRACE + bool "enable driver internal trace" + depends on SCSI_IBMVFC + default y + help + If you say Y here, the driver will trace all commands issued + to the adapter. Performance impact is minimal. Trace can be + dumped using /sys/class/scsi_host/hostXX/trace. + config SCSI_INITIO tristate "Initio 9100U(W) support" depends on PCI && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index aa8272e..a814967 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -119,6 +119,7 @@ obj-$(CONFIG_SCSI_IPR) += ipr.o obj-$(CONFIG_SCSI_SRP) += libsrp.o obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ +obj-$(CONFIG_SCSI_IBMVFC) += ibmvscsi/ obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_SCSI_STEX) += stex.o obj-$(CONFIG_SCSI_MVSAS) += mvsas.o diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index 6ac0633..a423d96 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile @@ -5,3 +5,4 @@ ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o +obj-$(CONFIG_SCSI_IBMVFC) += ibmvfc.o diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c new file mode 100644 index 0000000..eb702b9 --- /dev/null +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -0,0 +1,3910 @@ +/* + * ibmvfc.c -- driver for IBM Power Virtual Fibre Channel Adapter + * + * Written By: Brian King , IBM Corporation + * + * Copyright (C) IBM Corporation, 2008 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ibmvfc.h" + +static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT; +static unsigned int default_timeout = IBMVFC_DEFAULT_TIMEOUT; +static unsigned int max_lun = IBMVFC_MAX_LUN; +static unsigned int max_targets = IBMVFC_MAX_TARGETS; +static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT; +static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS; +static unsigned int dev_loss_tmo = IBMVFC_DEV_LOSS_TMO; +static unsigned int ibmvfc_debug = IBMVFC_DEBUG; +static unsigned int log_level = IBMVFC_DEFAULT_LOG_LEVEL; +static LIST_HEAD(ibmvfc_head); +static DEFINE_SPINLOCK(ibmvfc_driver_lock); +static struct scsi_transport_template *ibmvfc_transport_template; + +MODULE_DESCRIPTION("IBM Virtual Fibre Channel Driver"); +MODULE_AUTHOR("Brian King "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(IBMVFC_DRIVER_VERSION); + +module_param_named(init_timeout, init_timeout, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(init_timeout, "Initialization timeout in seconds. " + "[Default=" __stringify(IBMVFC_INIT_TIMEOUT) "]"); +module_param_named(default_timeout, default_timeout, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(default_timeout, + "Default timeout in seconds for initialization and EH commands. " + "[Default=" __stringify(IBMVFC_DEFAULT_TIMEOUT) "]"); +module_param_named(max_requests, max_requests, uint, S_IRUGO); +MODULE_PARM_DESC(max_requests, "Maximum requests for this adapter. " + "[Default=" __stringify(IBMVFC_MAX_REQUESTS_DEFAULT) "]"); +module_param_named(max_lun, max_lun, uint, S_IRUGO); +MODULE_PARM_DESC(max_lun, "Maximum allowed LUN. " + "[Default=" __stringify(IBMVFC_MAX_LUN) "]"); +module_param_named(max_targets, max_targets, uint, S_IRUGO); +MODULE_PARM_DESC(max_targets, "Maximum allowed targets. " + "[Default=" __stringify(IBMVFC_MAX_TARGETS) "]"); +module_param_named(disc_threads, disc_threads, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. " + "[Default=" __stringify(IBMVFC_MAX_DISC_THREADS) "]"); +module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable driver debug information. " + "[Default=" __stringify(IBMVFC_DEBUG) "]"); +module_param_named(dev_loss_tmo, dev_loss_tmo, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(dev_loss_tmo, "Maximum number of seconds that the FC " + "transport should insulate the loss of a remote port. Once this " + "value is exceeded, the scsi target is removed. " + "[Default=" __stringify(IBMVFC_DEV_LOSS_TMO) "]"); +module_param_named(log_level, log_level, uint, 0); +MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver. " + "[Default=" __stringify(IBMVFC_DEFAULT_LOG_LEVEL) "]"); + +static const struct { + u16 status; + u16 error; + u8 result; + u8 retry; + int log; + char *name; +} cmd_status [] = { + { IBMVFC_FABRIC_MAPPED, IBMVFC_UNABLE_TO_ESTABLISH, DID_ERROR, 1, 1, "unable to establish" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_FAULT, DID_OK, 1, 0, "transport fault" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_CMD_TIMEOUT, DID_TIME_OUT, 1, 1, "command timeout" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_ENETDOWN, DID_NO_CONNECT, 1, 1, "network down" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_HW_FAILURE, DID_ERROR, 1, 1, "hardware failure" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_DOWN_ERR, DID_REQUEUE, 0, 0, "link down" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_DEAD_ERR, DID_ERROR, 0, 0, "link dead" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_UNABLE_TO_REGISTER, DID_ERROR, 1, 1, "unable to register" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_BUSY, DID_BUS_BUSY, 1, 0, "transport busy" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_DEAD, DID_ERROR, 0, 1, "transport dead" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_CONFIG_ERROR, DID_ERROR, 1, 1, "configuration error" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_NAME_SERVER_FAIL, DID_ERROR, 1, 1, "name server failure" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_HALTED, DID_REQUEUE, 0, 0, "link halted" }, + { IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_GENERAL, DID_OK, 1, 0, "general transport error" }, + + { IBMVFC_VIOS_FAILURE, IBMVFC_CRQ_FAILURE, DID_REQUEUE, 1, 1, "CRQ failure" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_SW_FAILURE, DID_ERROR, 0, 1, "software failure" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_INVALID_PARAMETER, DID_ABORT, 0, 1, "invalid parameter" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_MISSING_PARAMETER, DID_ABORT, 0, 1, "missing parameter" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_HOST_IO_BUS, DID_ERROR, 1, 1, "host I/O bus failure" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_TRANS_CANCELLED, DID_ABORT, 0, 1, "transaction cancelled" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_TRANS_CANCELLED_IMPLICIT, DID_ABORT, 0, 1, "transaction cancelled implicit" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_INSUFFICIENT_RESOURCE, DID_REQUEUE, 1, 1, "insufficient resources" }, + { IBMVFC_VIOS_FAILURE, IBMVFC_COMMAND_FAILED, DID_ERROR, 1, 1, "command failed" }, + + { IBMVFC_FC_FAILURE, IBMVFC_INVALID_ELS_CMD_CODE, DID_ERROR, 0, 1, "invalid ELS command code" }, + { IBMVFC_FC_FAILURE, IBMVFC_INVALID_VERSION, DID_ERROR, 0, 1, "invalid version level" }, + { IBMVFC_FC_FAILURE, IBMVFC_LOGICAL_ERROR, DID_ERROR, 1, 1, "logical error" }, + { IBMVFC_FC_FAILURE, IBMVFC_INVALID_CT_IU_SIZE, DID_ERROR, 0, 1, "invalid CT_IU size" }, + { IBMVFC_FC_FAILURE, IBMVFC_LOGICAL_BUSY, DID_REQUEUE, 1, 0, "logical busy" }, + { IBMVFC_FC_FAILURE, IBMVFC_PROTOCOL_ERROR, DID_ERROR, 1, 1, "protocol error" }, + { IBMVFC_FC_FAILURE, IBMVFC_UNABLE_TO_PERFORM_REQ, DID_ERROR, 1, 1, "unable to perform request" }, + { IBMVFC_FC_FAILURE, IBMVFC_CMD_NOT_SUPPORTED, DID_ERROR, 0, 0, "command not supported" }, + { IBMVFC_FC_FAILURE, IBMVFC_SERVER_NOT_AVAIL, DID_ERROR, 0, 1, "server not available" }, + { IBMVFC_FC_FAILURE, IBMVFC_CMD_IN_PROGRESS, DID_ERROR, 0, 1, "command already in progress" }, + { IBMVFC_FC_FAILURE, IBMVFC_VENDOR_SPECIFIC, DID_ERROR, 1, 1, "vendor specific" }, + + { IBMVFC_FC_SCSI_ERROR, 0, DID_OK, 1, 0, "SCSI error" }, +}; + +static void ibmvfc_npiv_login(struct ibmvfc_host *); +static void ibmvfc_tgt_send_prli(struct ibmvfc_target *); +static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *); +static void ibmvfc_tgt_query_target(struct ibmvfc_target *); + +static const char *unknown_error = "unknown error"; + +#ifdef CONFIG_SCSI_IBMVFC_TRACE +/** + * ibmvfc_trc_start - Log a start trace entry + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_trc_start(struct ibmvfc_event *evt) +{ + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd; + struct ibmvfc_mad_common *mad = &evt->iu.mad_common; + struct ibmvfc_trace_entry *entry; + + entry = &vhost->trace[vhost->trace_index++]; + entry->evt = evt; + entry->time = jiffies; + entry->fmt = evt->crq.format; + entry->type = IBMVFC_TRC_START; + + switch (entry->fmt) { + case IBMVFC_CMD_FORMAT: + entry->op_code = vfc_cmd->iu.cdb[0]; + entry->scsi_id = vfc_cmd->tgt_scsi_id; + entry->lun = scsilun_to_int(&vfc_cmd->iu.lun); + entry->tmf_flags = vfc_cmd->iu.tmf_flags; + entry->u.start.xfer_len = vfc_cmd->iu.xfer_len; + break; + case IBMVFC_MAD_FORMAT: + entry->op_code = mad->opcode; + break; + default: + break; + }; +} + +/** + * ibmvfc_trc_end - Log an end trace entry + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_trc_end(struct ibmvfc_event *evt) +{ + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; + struct ibmvfc_mad_common *mad = &evt->xfer_iu->mad_common; + struct ibmvfc_trace_entry *entry = &vhost->trace[vhost->trace_index++]; + + entry->evt = evt; + entry->time = jiffies; + entry->fmt = evt->crq.format; + entry->type = IBMVFC_TRC_END; + + switch (entry->fmt) { + case IBMVFC_CMD_FORMAT: + entry->op_code = vfc_cmd->iu.cdb[0]; + entry->scsi_id = vfc_cmd->tgt_scsi_id; + entry->lun = scsilun_to_int(&vfc_cmd->iu.lun); + entry->tmf_flags = vfc_cmd->iu.tmf_flags; + entry->u.end.status = vfc_cmd->status; + entry->u.end.error = vfc_cmd->error; + entry->u.end.fcp_rsp_flags = vfc_cmd->rsp.flags; + entry->u.end.rsp_code = vfc_cmd->rsp.data.info.rsp_code; + entry->u.end.scsi_status = vfc_cmd->rsp.scsi_status; + break; + case IBMVFC_MAD_FORMAT: + entry->op_code = mad->opcode; + entry->u.end.status = mad->status; + break; + default: + break; + + }; +} + +#else +#define ibmvfc_trc_start(evt) do { } while (0) +#define ibmvfc_trc_end(evt) do { } while (0) +#endif + +/** + * ibmvfc_get_err_index - Find the index into cmd_status for the fcp response + * @status: status / error class + * @error: error + * + * Return value: + * index into cmd_status / -EINVAL on failure + **/ +static int ibmvfc_get_err_index(u16 status, u16 error) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cmd_status); i++) + if ((cmd_status[i].status & status) == cmd_status[i].status && + cmd_status[i].error == error) + return i; + + return -EINVAL; +} + +/** + * ibmvfc_get_cmd_error - Find the error description for the fcp response + * @status: status / error class + * @error: error + * + * Return value: + * error description string + **/ +static const char *ibmvfc_get_cmd_error(u16 status, u16 error) +{ + int rc = ibmvfc_get_err_index(status, error); + if (rc >= 0) + return cmd_status[rc].name; + return unknown_error; +} + +/** + * ibmvfc_get_err_result - Find the scsi status to return for the fcp response + * @vfc_cmd: ibmvfc command struct + * + * Return value: + * SCSI result value to return for completed command + **/ +static int ibmvfc_get_err_result(struct ibmvfc_cmd *vfc_cmd) +{ + int err; + struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp; + int fc_rsp_len = rsp->fcp_rsp_len; + + if ((rsp->flags & FCP_RSP_LEN_VALID) && + ((!fc_rsp_len && fc_rsp_len != 4 && fc_rsp_len != 8) || + rsp->data.info.rsp_code)) + return DID_ERROR << 16; + + if (!vfc_cmd->status) { + if (rsp->flags & FCP_RESID_OVER) + return rsp->scsi_status | (DID_ERROR << 16); + else + return rsp->scsi_status | (DID_OK << 16); + } + + err = ibmvfc_get_err_index(vfc_cmd->status, vfc_cmd->error); + if (err >= 0) + return rsp->scsi_status | (cmd_status[err].result << 16); + return rsp->scsi_status | (DID_ERROR << 16); +} + +/** + * ibmvfc_retry_cmd - Determine if error status is retryable + * @status: status / error class + * @error: error + * + * Return value: + * 1 if error should be retried / 0 if it should not + **/ +static int ibmvfc_retry_cmd(u16 status, u16 error) +{ + int rc = ibmvfc_get_err_index(status, error); + + if (rc >= 0) + return cmd_status[rc].retry; + return 1; +} + +static const char *unknown_fc_explain = "unknown fc explain"; + +static const struct { + u16 fc_explain; + char *name; +} ls_explain [] = { + { 0x00, "no additional explanation" }, + { 0x01, "service parameter error - options" }, + { 0x03, "service parameter error - initiator control" }, + { 0x05, "service parameter error - recipient control" }, + { 0x07, "service parameter error - received data field size" }, + { 0x09, "service parameter error - concurrent seq" }, + { 0x0B, "service parameter error - credit" }, + { 0x0D, "invalid N_Port/F_Port_Name" }, + { 0x0E, "invalid node/Fabric Name" }, + { 0x0F, "invalid common service parameters" }, + { 0x11, "invalid association header" }, + { 0x13, "association header required" }, + { 0x15, "invalid originator S_ID" }, + { 0x17, "invalid OX_ID-RX-ID combination" }, + { 0x19, "command (request) already in progress" }, + { 0x1E, "N_Port Login requested" }, + { 0x1F, "Invalid N_Port_ID" }, +}; + +static const struct { + u16 fc_explain; + char *name; +} gs_explain [] = { + { 0x00, "no additional explanation" }, + { 0x01, "port identifier not registered" }, + { 0x02, "port name not registered" }, + { 0x03, "node name not registered" }, + { 0x04, "class of service not registered" }, + { 0x06, "initial process associator not registered" }, + { 0x07, "FC-4 TYPEs not registered" }, + { 0x08, "symbolic port name not registered" }, + { 0x09, "symbolic node name not registered" }, + { 0x0A, "port type not registered" }, + { 0xF0, "authorization exception" }, + { 0xF1, "authentication exception" }, + { 0xF2, "data base full" }, + { 0xF3, "data base empty" }, + { 0xF4, "processing request" }, + { 0xF5, "unable to verify connection" }, + { 0xF6, "devices not in a common zone" }, +}; + +/** + * ibmvfc_get_ls_explain - Return the FC Explain description text + * @status: FC Explain status + * + * Returns: + * error string + **/ +static const char *ibmvfc_get_ls_explain(u16 status) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ls_explain); i++) + if (ls_explain[i].fc_explain == status) + return ls_explain[i].name; + + return unknown_fc_explain; +} + +/** + * ibmvfc_get_gs_explain - Return the FC Explain description text + * @status: FC Explain status + * + * Returns: + * error string + **/ +static const char *ibmvfc_get_gs_explain(u16 status) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(gs_explain); i++) + if (gs_explain[i].fc_explain == status) + return gs_explain[i].name; + + return unknown_fc_explain; +} + +static const struct { + enum ibmvfc_fc_type fc_type; + char *name; +} fc_type [] = { + { IBMVFC_FABRIC_REJECT, "fabric reject" }, + { IBMVFC_PORT_REJECT, "port reject" }, + { IBMVFC_LS_REJECT, "ELS reject" }, + { IBMVFC_FABRIC_BUSY, "fabric busy" }, + { IBMVFC_PORT_BUSY, "port busy" }, + { IBMVFC_BASIC_REJECT, "basic reject" }, +}; + +static const char *unknown_fc_type = "unknown fc type"; + +/** + * ibmvfc_get_fc_type - Return the FC Type description text + * @status: FC Type error status + * + * Returns: + * error string + **/ +static const char *ibmvfc_get_fc_type(u16 status) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fc_type); i++) + if (fc_type[i].fc_type == status) + return fc_type[i].name; + + return unknown_fc_type; +} + +/** + * ibmvfc_set_tgt_action - Set the next init action for the target + * @tgt: ibmvfc target struct + * @action: action to perform + * + **/ +static void ibmvfc_set_tgt_action(struct ibmvfc_target *tgt, + enum ibmvfc_target_action action) +{ + switch (tgt->action) { + case IBMVFC_TGT_ACTION_DEL_RPORT: + break; + default: + tgt->action = action; + break; + } +} + +/** + * ibmvfc_set_host_state - Set the state for the host + * @vhost: ibmvfc host struct + * @state: state to set host to + * + * Returns: + * 0 if state changed / non-zero if not changed + **/ +static int ibmvfc_set_host_state(struct ibmvfc_host *vhost, + enum ibmvfc_host_state state) +{ + int rc = 0; + + switch (vhost->state) { + case IBMVFC_HOST_OFFLINE: + rc = -EINVAL; + break; + default: + vhost->state = state; + break; + }; + + return rc; +} + +/** + * ibmvfc_set_host_action - Set the next init action for the host + * @vhost: ibmvfc host struct + * @action: action to perform + * + **/ +static void ibmvfc_set_host_action(struct ibmvfc_host *vhost, + enum ibmvfc_host_action action) +{ + switch (action) { + case IBMVFC_HOST_ACTION_ALLOC_TGTS: + if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) + vhost->action = action; + break; + case IBMVFC_HOST_ACTION_INIT_WAIT: + if (vhost->action == IBMVFC_HOST_ACTION_INIT) + vhost->action = action; + break; + case IBMVFC_HOST_ACTION_QUERY: + switch (vhost->action) { + case IBMVFC_HOST_ACTION_INIT_WAIT: + case IBMVFC_HOST_ACTION_NONE: + case IBMVFC_HOST_ACTION_TGT_ADD: + vhost->action = action; + break; + default: + break; + }; + break; + case IBMVFC_HOST_ACTION_TGT_INIT: + if (vhost->action == IBMVFC_HOST_ACTION_ALLOC_TGTS) + vhost->action = action; + break; + case IBMVFC_HOST_ACTION_INIT: + case IBMVFC_HOST_ACTION_TGT_DEL: + case IBMVFC_HOST_ACTION_QUERY_TGTS: + case IBMVFC_HOST_ACTION_TGT_ADD: + case IBMVFC_HOST_ACTION_NONE: + default: + vhost->action = action; + break; + }; +} + +/** + * ibmvfc_reinit_host - Re-start host initialization (no NPIV Login) + * @vhost: ibmvfc host struct + * + * Return value: + * nothing + **/ +static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) +{ + if (vhost->action == IBMVFC_HOST_ACTION_NONE) { + scsi_block_requests(vhost->host); + ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); + } else + vhost->reinit = 1; + + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_link_down - Handle a link down event from the adapter + * @vhost: ibmvfc host struct + * @state: ibmvfc host state to enter + * + **/ +static void ibmvfc_link_down(struct ibmvfc_host *vhost, + enum ibmvfc_host_state state) +{ + struct ibmvfc_target *tgt; + + ENTER; + scsi_block_requests(vhost->host); + list_for_each_entry(tgt, &vhost->targets, queue) + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); + ibmvfc_set_host_state(vhost, state); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL); + vhost->events_to_log |= IBMVFC_AE_LINKDOWN; + wake_up(&vhost->work_wait_q); + LEAVE; +} + +/** + * ibmvfc_init_host - Start host initialization + * @vhost: ibmvfc host struct + * + * Return value: + * nothing + **/ +static void ibmvfc_init_host(struct ibmvfc_host *vhost) +{ + struct ibmvfc_target *tgt; + + if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) { + if (++vhost->init_retries > IBMVFC_MAX_INIT_RETRIES) { + dev_err(vhost->dev, + "Host initialization retries exceeded. Taking adapter offline\n"); + ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); + return; + } + } + + if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { + list_for_each_entry(tgt, &vhost->targets, queue) + tgt->need_login = 1; + scsi_block_requests(vhost->host); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT); + vhost->job_step = ibmvfc_npiv_login; + wake_up(&vhost->work_wait_q); + } +} + +/** + * ibmvfc_send_crq - Send a CRQ + * @vhost: ibmvfc host struct + * @word1: the first 64 bits of the data + * @word2: the second 64 bits of the data + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_send_crq(struct ibmvfc_host *vhost, u64 word1, u64 word2) +{ + struct vio_dev *vdev = to_vio_dev(vhost->dev); + return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); +} + +/** + * ibmvfc_send_crq_init - Send a CRQ init message + * @vhost: ibmvfc host struct + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_send_crq_init(struct ibmvfc_host *vhost) +{ + ibmvfc_dbg(vhost, "Sending CRQ init\n"); + return ibmvfc_send_crq(vhost, 0xC001000000000000LL, 0); +} + +/** + * ibmvfc_send_crq_init_complete - Send a CRQ init complete message + * @vhost: ibmvfc host struct + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_send_crq_init_complete(struct ibmvfc_host *vhost) +{ + ibmvfc_dbg(vhost, "Sending CRQ init complete\n"); + return ibmvfc_send_crq(vhost, 0xC002000000000000LL, 0); +} + +/** + * ibmvfc_release_crq_queue - Deallocates data and unregisters CRQ + * @vhost: ibmvfc host struct + * + * Frees irq, deallocates a page for messages, unmaps dma, and unregisters + * the crq with the hypervisor. + **/ +static void ibmvfc_release_crq_queue(struct ibmvfc_host *vhost) +{ + long rc; + struct vio_dev *vdev = to_vio_dev(vhost->dev); + struct ibmvfc_crq_queue *crq = &vhost->crq; + + ibmvfc_dbg(vhost, "Releasing CRQ\n"); + free_irq(vdev->irq, vhost); + do { + rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); + } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); + + vhost->state = IBMVFC_NO_CRQ; + dma_unmap_single(vhost->dev, crq->msg_token, PAGE_SIZE, DMA_BIDIRECTIONAL); + free_page((unsigned long)crq->msgs); +} + +/** + * ibmvfc_reenable_crq_queue - reenables the CRQ + * @vhost: ibmvfc host struct + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) +{ + int rc; + struct vio_dev *vdev = to_vio_dev(vhost->dev); + + /* Re-enable the CRQ */ + do { + rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address); + } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc)); + + if (rc) + dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc); + + return rc; +} + +/** + * ibmvfc_reset_crq - resets a crq after a failure + * @vhost: ibmvfc host struct + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) +{ + int rc; + struct vio_dev *vdev = to_vio_dev(vhost->dev); + struct ibmvfc_crq_queue *crq = &vhost->crq; + + /* Close the CRQ */ + do { + rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); + } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); + + vhost->state = IBMVFC_NO_CRQ; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); + + /* Clean out the queue */ + memset(crq->msgs, 0, PAGE_SIZE); + crq->cur = 0; + + /* And re-open it again */ + rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, + crq->msg_token, PAGE_SIZE); + + if (rc == H_CLOSED) + /* Adapter is good, but other end is not ready */ + dev_warn(vhost->dev, "Partner adapter not ready\n"); + else if (rc != 0) + dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc); + + return rc; +} + +/** + * ibmvfc_valid_event - Determines if event is valid. + * @pool: event_pool that contains the event + * @evt: ibmvfc event to be checked for validity + * + * Return value: + * 1 if event is valid / 0 if event is not valid + **/ +static int ibmvfc_valid_event(struct ibmvfc_event_pool *pool, + struct ibmvfc_event *evt) +{ + int index = evt - pool->events; + if (index < 0 || index >= pool->size) /* outside of bounds */ + return 0; + if (evt != pool->events + index) /* unaligned */ + return 0; + return 1; +} + +/** + * ibmvfc_free_event - Free the specified event + * @evt: ibmvfc_event to be freed + * + **/ +static void ibmvfc_free_event(struct ibmvfc_event *evt) +{ + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_event_pool *pool = &vhost->pool; + + BUG_ON(!ibmvfc_valid_event(pool, evt)); + BUG_ON(atomic_inc_return(&evt->free) != 1); + list_add_tail(&evt->queue, &vhost->free); +} + +/** + * ibmvfc_scsi_eh_done - EH done function for queuecommand commands + * @evt: ibmvfc event struct + * + * This function does not setup any error status, that must be done + * before this function gets called. + **/ +static void ibmvfc_scsi_eh_done(struct ibmvfc_event *evt) +{ + struct scsi_cmnd *cmnd = evt->cmnd; + + if (cmnd) { + scsi_dma_unmap(cmnd); + cmnd->scsi_done(cmnd); + } + + ibmvfc_free_event(evt); +} + +/** + * ibmvfc_fail_request - Fail request with specified error code + * @evt: ibmvfc event struct + * @error_code: error code to fail request with + * + * Return value: + * none + **/ +static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code) +{ + if (evt->cmnd) { + evt->cmnd->result = (error_code << 16); + evt->done = ibmvfc_scsi_eh_done; + } else + evt->xfer_iu->mad_common.status = IBMVFC_MAD_DRIVER_FAILED; + + list_del(&evt->queue); + del_timer(&evt->timer); + ibmvfc_trc_end(evt); + evt->done(evt); +} + +/** + * ibmvfc_purge_requests - Our virtual adapter just shut down. Purge any sent requests + * @vhost: ibmvfc host struct + * @error_code: error code to fail requests with + * + * Return value: + * none + **/ +static void ibmvfc_purge_requests(struct ibmvfc_host *vhost, int error_code) +{ + struct ibmvfc_event *evt, *pos; + + ibmvfc_dbg(vhost, "Purging all requests\n"); + list_for_each_entry_safe(evt, pos, &vhost->sent, queue) + ibmvfc_fail_request(evt, error_code); +} + +/** + * __ibmvfc_reset_host - Reset the connection to the server (no locking) + * @vhost: struct ibmvfc host to reset + **/ +static void __ibmvfc_reset_host(struct ibmvfc_host *vhost) +{ + int rc; + + scsi_block_requests(vhost->host); + ibmvfc_purge_requests(vhost, DID_ERROR); + if ((rc = ibmvfc_reset_crq(vhost)) || + (rc = ibmvfc_send_crq_init(vhost)) || + (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { + dev_err(vhost->dev, "Error after reset rc=%d\n", rc); + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + } else + ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN); +} + +/** + * ibmvfc_reset_host - Reset the connection to the server + * @vhost: struct ibmvfc host to reset + **/ +static void ibmvfc_reset_host(struct ibmvfc_host *vhost) +{ + unsigned long flags; + + spin_lock_irqsave(vhost->host->host_lock, flags); + __ibmvfc_reset_host(vhost); + spin_unlock_irqrestore(vhost->host->host_lock, flags); +} + +/** + * ibmvfc_retry_host_init - Retry host initialization if allowed + * @vhost: ibmvfc host struct + * + **/ +static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost) +{ + if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) { + if (++vhost->init_retries > IBMVFC_MAX_INIT_RETRIES) { + dev_err(vhost->dev, + "Host initialization retries exceeded. Taking adapter offline\n"); + ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); + } else if (vhost->init_retries == IBMVFC_MAX_INIT_RETRIES) + __ibmvfc_reset_host(vhost); + else + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT); + } + + wake_up(&vhost->work_wait_q); +} + +/** + * __ibmvfc_find_target - Find the specified scsi_target (no locking) + * @starget: scsi target struct + * + * Return value: + * ibmvfc_target struct / NULL if not found + **/ +static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct ibmvfc_host *vhost = shost_priv(shost); + struct ibmvfc_target *tgt; + + list_for_each_entry(tgt, &vhost->targets, queue) + if (tgt->target_id == starget->id) + return tgt; + return NULL; +} + +/** + * ibmvfc_find_target - Find the specified scsi_target + * @starget: scsi target struct + * + * Return value: + * ibmvfc_target struct / NULL if not found + **/ +static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct ibmvfc_target *tgt; + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + tgt = __ibmvfc_find_target(starget); + spin_unlock_irqrestore(shost->host_lock, flags); + return tgt; +} + +/** + * ibmvfc_get_host_speed - Get host port speed + * @shost: scsi host struct + * + * Return value: + * none + **/ +static void ibmvfc_get_host_speed(struct Scsi_Host *shost) +{ + struct ibmvfc_host *vhost = shost_priv(shost); + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + if (vhost->state == IBMVFC_ACTIVE) { + switch (vhost->login_buf->resp.link_speed / 100) { + case 1: + fc_host_speed(shost) = FC_PORTSPEED_1GBIT; + break; + case 2: + fc_host_speed(shost) = FC_PORTSPEED_2GBIT; + break; + case 4: + fc_host_speed(shost) = FC_PORTSPEED_4GBIT; + break; + case 8: + fc_host_speed(shost) = FC_PORTSPEED_8GBIT; + break; + case 10: + fc_host_speed(shost) = FC_PORTSPEED_10GBIT; + break; + case 16: + fc_host_speed(shost) = FC_PORTSPEED_16GBIT; + break; + default: + ibmvfc_log(vhost, 3, "Unknown port speed: %ld Gbit\n", + vhost->login_buf->resp.link_speed / 100); + fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; + break; + } + } else + fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; + spin_unlock_irqrestore(shost->host_lock, flags); +} + +/** + * ibmvfc_get_host_port_state - Get host port state + * @shost: scsi host struct + * + * Return value: + * none + **/ +static void ibmvfc_get_host_port_state(struct Scsi_Host *shost) +{ + struct ibmvfc_host *vhost = shost_priv(shost); + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + switch (vhost->state) { + case IBMVFC_INITIALIZING: + case IBMVFC_ACTIVE: + fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; + break; + case IBMVFC_LINK_DOWN: + fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; + break; + case IBMVFC_LINK_DEAD: + case IBMVFC_HOST_OFFLINE: + fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; + break; + case IBMVFC_HALTED: + fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED; + break; + default: + ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state); + fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; + break; + } + spin_unlock_irqrestore(shost->host_lock, flags); +} + +/** + * ibmvfc_set_rport_dev_loss_tmo - Set rport's device loss timeout + * @rport: rport struct + * @timeout: timeout value + * + * Return value: + * none + **/ +static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) +{ + if (timeout) + rport->dev_loss_tmo = timeout; + else + rport->dev_loss_tmo = 1; +} + +/** + * ibmvfc_get_starget_node_name - Get SCSI target's node name + * @starget: scsi target struct + * + * Return value: + * none + **/ +static void ibmvfc_get_starget_node_name(struct scsi_target *starget) +{ + struct ibmvfc_target *tgt = ibmvfc_find_target(starget); + fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0; +} + +/** + * ibmvfc_get_starget_port_name - Get SCSI target's port name + * @starget: scsi target struct + * + * Return value: + * none + **/ +static void ibmvfc_get_starget_port_name(struct scsi_target *starget) +{ + struct ibmvfc_target *tgt = ibmvfc_find_target(starget); + fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0; +} + +/** + * ibmvfc_get_starget_port_id - Get SCSI target's port ID + * @starget: scsi target struct + * + * Return value: + * none + **/ +static void ibmvfc_get_starget_port_id(struct scsi_target *starget) +{ + struct ibmvfc_target *tgt = ibmvfc_find_target(starget); + fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1; +} + +/** + * ibmvfc_wait_while_resetting - Wait while the host resets + * @vhost: ibmvfc host struct + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_wait_while_resetting(struct ibmvfc_host *vhost) +{ + long timeout = wait_event_timeout(vhost->init_wait_q, + (vhost->state == IBMVFC_ACTIVE || + vhost->state == IBMVFC_HOST_OFFLINE || + vhost->state == IBMVFC_LINK_DEAD), + (init_timeout * HZ)); + + return timeout ? 0 : -EIO; +} + +/** + * ibmvfc_issue_fc_host_lip - Re-initiate link initialization + * @shost: scsi host struct + * + * Return value: + * 0 on success / other on failure + **/ +static int ibmvfc_issue_fc_host_lip(struct Scsi_Host *shost) +{ + struct ibmvfc_host *vhost = shost_priv(shost); + + dev_err(vhost->dev, "Initiating host LIP. Resetting connection\n"); + ibmvfc_reset_host(vhost); + return ibmvfc_wait_while_resetting(vhost); +} + +/** + * ibmvfc_gather_partition_info - Gather info about the LPAR + * + * Return value: + * none + **/ +static void ibmvfc_gather_partition_info(struct ibmvfc_host *vhost) +{ + struct device_node *rootdn; + const char *name; + const unsigned int *num; + + rootdn = of_find_node_by_path("/"); + if (!rootdn) + return; + + name = of_get_property(rootdn, "ibm,partition-name", NULL); + if (name) + strncpy(vhost->partition_name, name, sizeof(vhost->partition_name)); + num = of_get_property(rootdn, "ibm,partition-no", NULL); + if (num) + vhost->partition_number = *num; + of_node_put(rootdn); +} + +/** + * ibmvfc_set_login_info - Setup info for NPIV login + * @vhost: ibmvfc host struct + * + * Return value: + * none + **/ +static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) +{ + struct ibmvfc_npiv_login *login_info = &vhost->login_info; + struct device_node *of_node = vhost->dev->archdata.of_node; + const char *location; + + memset(login_info, 0, sizeof(*login_info)); + + login_info->ostype = IBMVFC_OS_LINUX; + login_info->max_dma_len = IBMVFC_MAX_SECTORS << 9; + login_info->max_payload = sizeof(struct ibmvfc_fcp_cmd_iu); + login_info->max_response = sizeof(struct ibmvfc_fcp_rsp); + login_info->partition_num = vhost->partition_number; + login_info->vfc_frame_version = 1; + login_info->fcp_version = 3; + if (vhost->client_migrated) + login_info->flags = IBMVFC_CLIENT_MIGRATED; + + login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ; + login_info->capabilities = IBMVFC_CAN_MIGRATE; + login_info->async.va = vhost->async_crq.msg_token; + login_info->async.len = vhost->async_crq.size; + strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME); + strncpy(login_info->device_name, + vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME); + + location = of_get_property(of_node, "ibm,loc-code", NULL); + location = location ? location : vhost->dev->bus_id; + strncpy(login_info->drc_name, location, IBMVFC_MAX_NAME); +} + +/** + * ibmvfc_init_event_pool - Allocates and initializes the event pool for a host + * @vhost: ibmvfc host who owns the event pool + * + * Returns zero on success. + **/ +static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost) +{ + int i; + struct ibmvfc_event_pool *pool = &vhost->pool; + + ENTER; + pool->size = max_requests + IBMVFC_NUM_INTERNAL_REQ; + pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL); + if (!pool->events) + return -ENOMEM; + + pool->iu_storage = dma_alloc_coherent(vhost->dev, + pool->size * sizeof(*pool->iu_storage), + &pool->iu_token, 0); + + if (!pool->iu_storage) { + kfree(pool->events); + return -ENOMEM; + } + + for (i = 0; i < pool->size; ++i) { + struct ibmvfc_event *evt = &pool->events[i]; + atomic_set(&evt->free, 1); + evt->crq.valid = 0x80; + evt->crq.ioba = pool->iu_token + (sizeof(*evt->xfer_iu) * i); + evt->xfer_iu = pool->iu_storage + i; + evt->vhost = vhost; + evt->ext_list = NULL; + list_add_tail(&evt->queue, &vhost->free); + } + + LEAVE; + return 0; +} + +/** + * ibmvfc_free_event_pool - Frees memory of the event pool of a host + * @vhost: ibmvfc host who owns the event pool + * + **/ +static void ibmvfc_free_event_pool(struct ibmvfc_host *vhost) +{ + int i; + struct ibmvfc_event_pool *pool = &vhost->pool; + + ENTER; + for (i = 0; i < pool->size; ++i) { + list_del(&pool->events[i].queue); + BUG_ON(atomic_read(&pool->events[i].free) != 1); + if (pool->events[i].ext_list) + dma_pool_free(vhost->sg_pool, + pool->events[i].ext_list, + pool->events[i].ext_list_token); + } + + kfree(pool->events); + dma_free_coherent(vhost->dev, + pool->size * sizeof(*pool->iu_storage), + pool->iu_storage, pool->iu_token); + LEAVE; +} + +/** + * ibmvfc_get_event - Gets the next free event in pool + * @vhost: ibmvfc host struct + * + * Returns a free event from the pool. + **/ +static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_host *vhost) +{ + struct ibmvfc_event *evt; + + BUG_ON(list_empty(&vhost->free)); + evt = list_entry(vhost->free.next, struct ibmvfc_event, queue); + atomic_set(&evt->free, 0); + list_del(&evt->queue); + return evt; +} + +/** + * ibmvfc_init_event - Initialize fields in an event struct that are always + * required. + * @evt: The event + * @done: Routine to call when the event is responded to + * @format: SRP or MAD format + **/ +static void ibmvfc_init_event(struct ibmvfc_event *evt, + void (*done) (struct ibmvfc_event *), u8 format) +{ + evt->cmnd = NULL; + evt->sync_iu = NULL; + evt->crq.format = format; + evt->done = done; +} + +/** + * ibmvfc_map_sg_list - Initialize scatterlist + * @scmd: scsi command struct + * @nseg: number of scatterlist segments + * @md: memory descriptor list to initialize + **/ +static void ibmvfc_map_sg_list(struct scsi_cmnd *scmd, int nseg, + struct srp_direct_buf *md) +{ + int i; + struct scatterlist *sg; + + scsi_for_each_sg(scmd, sg, nseg, i) { + md[i].va = sg_dma_address(sg); + md[i].len = sg_dma_len(sg); + md[i].key = 0; + } +} + +/** + * ibmvfc_map_sg_data - Maps dma for a scatterlist and initializes decriptor fields + * @scmd: Scsi_Cmnd with the scatterlist + * @evt: ibmvfc event struct + * @vfc_cmd: vfc_cmd that contains the memory descriptor + * @dev: device for which to map dma memory + * + * Returns: + * 0 on success / non-zero on failure + **/ +static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd, + struct ibmvfc_event *evt, + struct ibmvfc_cmd *vfc_cmd, struct device *dev) +{ + + int sg_mapped; + struct srp_direct_buf *data = &vfc_cmd->ioba; + struct ibmvfc_host *vhost = dev_get_drvdata(dev); + + sg_mapped = scsi_dma_map(scmd); + if (!sg_mapped) { + vfc_cmd->flags |= IBMVFC_NO_MEM_DESC; + return 0; + } else if (unlikely(sg_mapped < 0)) { + if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) + scmd_printk(KERN_ERR, scmd, "Failed to map DMA buffer for command\n"); + return sg_mapped; + } + + if (scmd->sc_data_direction == DMA_TO_DEVICE) { + vfc_cmd->flags |= IBMVFC_WRITE; + vfc_cmd->iu.add_cdb_len |= IBMVFC_WRDATA; + } else { + vfc_cmd->flags |= IBMVFC_READ; + vfc_cmd->iu.add_cdb_len |= IBMVFC_RDDATA; + } + + if (sg_mapped == 1) { + ibmvfc_map_sg_list(scmd, sg_mapped, data); + return 0; + } + + vfc_cmd->flags |= IBMVFC_SCATTERLIST; + + if (!evt->ext_list) { + evt->ext_list = dma_pool_alloc(vhost->sg_pool, GFP_ATOMIC, + &evt->ext_list_token); + + if (!evt->ext_list) { + scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n"); + return -ENOMEM; + } + } + + ibmvfc_map_sg_list(scmd, sg_mapped, evt->ext_list); + + data->va = evt->ext_list_token; + data->len = sg_mapped * sizeof(struct srp_direct_buf); + data->key = 0; + return 0; +} + +/** + * ibmvfc_timeout - Internal command timeout handler + * @evt: struct ibmvfc_event that timed out + * + * Called when an internally generated command times out + **/ +static void ibmvfc_timeout(struct ibmvfc_event *evt) +{ + struct ibmvfc_host *vhost = evt->vhost; + dev_err(vhost->dev, "Command timed out (%p). Resetting connection\n", evt); + ibmvfc_reset_host(vhost); +} + +/** + * ibmvfc_send_event - Transforms event to u64 array and calls send_crq() + * @evt: event to be sent + * @vhost: ibmvfc host struct + * @timeout: timeout in seconds - 0 means do not time command + * + * Returns the value returned from ibmvfc_send_crq(). (Zero for success) + **/ +static int ibmvfc_send_event(struct ibmvfc_event *evt, + struct ibmvfc_host *vhost, unsigned long timeout) +{ + u64 *crq_as_u64 = (u64 *) &evt->crq; + int rc; + + /* Copy the IU into the transfer area */ + *evt->xfer_iu = evt->iu; + if (evt->crq.format == IBMVFC_CMD_FORMAT) + evt->xfer_iu->cmd.tag = (u64)evt; + else if (evt->crq.format == IBMVFC_MAD_FORMAT) + evt->xfer_iu->mad_common.tag = (u64)evt; + else + BUG(); + + list_add_tail(&evt->queue, &vhost->sent); + init_timer(&evt->timer); + + if (timeout) { + evt->timer.data = (unsigned long) evt; + evt->timer.expires = jiffies + (timeout * HZ); + evt->timer.function = (void (*)(unsigned long))ibmvfc_timeout; + add_timer(&evt->timer); + } + + if ((rc = ibmvfc_send_crq(vhost, crq_as_u64[0], crq_as_u64[1]))) { + list_del(&evt->queue); + del_timer(&evt->timer); + + /* If send_crq returns H_CLOSED, return SCSI_MLQUEUE_HOST_BUSY. + * Firmware will send a CRQ with a transport event (0xFF) to + * tell this client what has happened to the transport. This + * will be handled in ibmvfc_handle_crq() + */ + if (rc == H_CLOSED) { + if (printk_ratelimit()) + dev_warn(vhost->dev, "Send warning. Receive queue closed, will retry.\n"); + if (evt->cmnd) + scsi_dma_unmap(evt->cmnd); + ibmvfc_free_event(evt); + return SCSI_MLQUEUE_HOST_BUSY; + } + + dev_err(vhost->dev, "Send error (rc=%d)\n", rc); + if (evt->cmnd) { + evt->cmnd->result = DID_ERROR << 16; + evt->done = ibmvfc_scsi_eh_done; + } else + evt->xfer_iu->mad_common.status = IBMVFC_MAD_CRQ_ERROR; + + evt->done(evt); + } else + ibmvfc_trc_start(evt); + + return 0; +} + +/** + * ibmvfc_log_error - Log an error for the failed command if appropriate + * @evt: ibmvfc event to log + * + **/ +static void ibmvfc_log_error(struct ibmvfc_event *evt) +{ + struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp; + struct scsi_cmnd *cmnd = evt->cmnd; + const char *err = unknown_error; + int index = ibmvfc_get_err_index(vfc_cmd->status, vfc_cmd->error); + int logerr = 0; + int rsp_code = 0; + + if (index >= 0) { + logerr = cmd_status[index].log; + err = cmd_status[index].name; + } + + if (!logerr && (vhost->log_level <= IBMVFC_DEFAULT_LOG_LEVEL)) + return; + + if (rsp->flags & FCP_RSP_LEN_VALID) + rsp_code = rsp->data.info.rsp_code; + + scmd_printk(KERN_ERR, cmnd, "Command (%02X) failed: %s (%x:%x) " + "flags: %x fcp_rsp: %x, resid=%d, scsi_status: %x\n", + cmnd->cmnd[0], err, vfc_cmd->status, vfc_cmd->error, + rsp->flags, rsp_code, scsi_get_resid(cmnd), rsp->scsi_status); +} + +/** + * ibmvfc_scsi_done - Handle responses from commands + * @evt: ibmvfc event to be handled + * + * Used as a callback when sending scsi cmds. + **/ +static void ibmvfc_scsi_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; + struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp; + struct scsi_cmnd *cmnd = evt->cmnd; + int rsp_len = 0; + int sense_len = rsp->fcp_sense_len; + + if (cmnd) { + if (vfc_cmd->response_flags & IBMVFC_ADAPTER_RESID_VALID) + scsi_set_resid(cmnd, vfc_cmd->adapter_resid); + else if (rsp->flags & FCP_RESID_UNDER) + scsi_set_resid(cmnd, rsp->fcp_resid); + else + scsi_set_resid(cmnd, 0); + + if (vfc_cmd->status) { + cmnd->result = ibmvfc_get_err_result(vfc_cmd); + + if (rsp->flags & FCP_RSP_LEN_VALID) + rsp_len = rsp->fcp_rsp_len; + if ((sense_len + rsp_len) > SCSI_SENSE_BUFFERSIZE) + sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len; + if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len) + memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len); + + ibmvfc_log_error(evt); + } + + if (!cmnd->result && + (scsi_bufflen(cmnd) - scsi_get_resid(cmnd) < cmnd->underflow)) + cmnd->result = (DID_ERROR << 16); + + scsi_dma_unmap(cmnd); + cmnd->scsi_done(cmnd); + } + + ibmvfc_free_event(evt); +} + +/** + * ibmvfc_host_chkready - Check if the host can accept commands + * @vhost: struct ibmvfc host + * + * Returns: + * 1 if host can accept command / 0 if not + **/ +static inline int ibmvfc_host_chkready(struct ibmvfc_host *vhost) +{ + int result = 0; + + switch (vhost->state) { + case IBMVFC_LINK_DEAD: + case IBMVFC_HOST_OFFLINE: + result = DID_NO_CONNECT << 16; + break; + case IBMVFC_NO_CRQ: + case IBMVFC_INITIALIZING: + case IBMVFC_HALTED: + case IBMVFC_LINK_DOWN: + result = DID_REQUEUE << 16; + break; + case IBMVFC_ACTIVE: + result = 0; + break; + }; + + return result; +} + +/** + * ibmvfc_queuecommand - The queuecommand function of the scsi template + * @cmnd: struct scsi_cmnd to be executed + * @done: Callback function to be called when cmnd is completed + * + * Returns: + * 0 on success / other on failure + **/ +static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd, + void (*done) (struct scsi_cmnd *)) +{ + struct ibmvfc_host *vhost = shost_priv(cmnd->device->host); + struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); + struct ibmvfc_cmd *vfc_cmd; + struct ibmvfc_event *evt; + u8 tag[2]; + int rc; + + if (unlikely((rc = fc_remote_port_chkready(rport))) || + unlikely((rc = ibmvfc_host_chkready(vhost)))) { + cmnd->result = rc; + done(cmnd); + return 0; + } + + cmnd->result = (DID_OK << 16); + evt = ibmvfc_get_event(vhost); + ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT); + evt->cmnd = cmnd; + cmnd->scsi_done = done; + vfc_cmd = &evt->iu.cmd; + memset(vfc_cmd, 0, sizeof(*vfc_cmd)); + vfc_cmd->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp); + vfc_cmd->resp.len = sizeof(vfc_cmd->rsp); + vfc_cmd->frame_type = IBMVFC_SCSI_FCP_TYPE; + vfc_cmd->payload_len = sizeof(vfc_cmd->iu); + 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); + + if (scsi_populate_tag_msg(cmnd, tag)) { + vfc_cmd->task_tag = tag[1]; + switch (tag[0]) { + case MSG_SIMPLE_TAG: + vfc_cmd->iu.pri_task_attr = IBMVFC_SIMPLE_TASK; + break; + case MSG_HEAD_TAG: + vfc_cmd->iu.pri_task_attr = IBMVFC_HEAD_OF_QUEUE; + break; + case MSG_ORDERED_TAG: + vfc_cmd->iu.pri_task_attr = IBMVFC_ORDERED_TASK; + break; + }; + } + + if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev)))) + return ibmvfc_send_event(evt, vhost, 0); + + ibmvfc_free_event(evt); + if (rc == -ENOMEM) + return SCSI_MLQUEUE_HOST_BUSY; + + if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) + scmd_printk(KERN_ERR, cmnd, + "Failed to map DMA buffer for command. rc=%d\n", rc); + + cmnd->result = DID_ERROR << 16; + done(cmnd); + return 0; +} + +/** + * ibmvfc_sync_completion - Signal that a synchronous command has completed + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_sync_completion(struct ibmvfc_event *evt) +{ + /* copy the response back */ + if (evt->sync_iu) + *evt->sync_iu = *evt->xfer_iu; + + complete(&evt->comp); +} + +/** + * ibmvfc_reset_device - Reset the device with the specified reset type + * @sdev: scsi device to reset + * @type: reset type + * @desc: reset type description for log messages + * + * Returns: + * 0 on success / other on failure + **/ +static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) +{ + struct ibmvfc_host *vhost = shost_priv(sdev->host); + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); + struct ibmvfc_cmd *tmf; + struct ibmvfc_event *evt; + union ibmvfc_iu rsp_iu; + struct ibmvfc_fcp_rsp *fc_rsp = &rsp_iu.cmd.rsp; + int rsp_rc = -EBUSY; + unsigned long flags; + int rsp_code = 0; + + spin_lock_irqsave(vhost->host->host_lock, flags); + if (vhost->state == IBMVFC_ACTIVE) { + evt = ibmvfc_get_event(vhost); + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); + + tmf = &evt->iu.cmd; + memset(tmf, 0, sizeof(*tmf)); + tmf->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp); + tmf->resp.len = sizeof(tmf->rsp); + tmf->frame_type = IBMVFC_SCSI_FCP_TYPE; + tmf->payload_len = sizeof(tmf->iu); + tmf->resp_len = sizeof(tmf->rsp); + tmf->cancel_key = (unsigned long)sdev->hostdata; + tmf->tgt_scsi_id = rport->port_id; + int_to_scsilun(sdev->lun, &tmf->iu.lun); + tmf->flags = (IBMVFC_NO_MEM_DESC | IBMVFC_TMF); + tmf->iu.tmf_flags = type; + evt->sync_iu = &rsp_iu; + + init_completion(&evt->comp); + rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); + } + spin_unlock_irqrestore(vhost->host->host_lock, flags); + + if (rsp_rc != 0) { + sdev_printk(KERN_ERR, sdev, "Failed to send %s reset event. rc=%d\n", + desc, rsp_rc); + return -EIO; + } + + sdev_printk(KERN_INFO, sdev, "Resetting %s\n", desc); + wait_for_completion(&evt->comp); + + if (rsp_iu.cmd.status) { + if (fc_rsp->flags & FCP_RSP_LEN_VALID) + rsp_code = fc_rsp->data.info.rsp_code; + + sdev_printk(KERN_ERR, sdev, "%s reset failed: %s (%x:%x) " + "flags: %x fcp_rsp: %x, scsi_status: %x\n", + desc, ibmvfc_get_cmd_error(rsp_iu.cmd.status, rsp_iu.cmd.error), + rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code, + fc_rsp->scsi_status); + rsp_rc = -EIO; + } else + sdev_printk(KERN_INFO, sdev, "%s reset successful\n", desc); + + spin_lock_irqsave(vhost->host->host_lock, flags); + ibmvfc_free_event(evt); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return rsp_rc; +} + +/** + * ibmvfc_abort_task_set - Abort outstanding commands to the device + * @sdev: scsi device to abort commands + * + * This sends an Abort Task Set to the VIOS for the specified device. This does + * NOT send any cancel to the VIOS. That must be done separately. + * + * Returns: + * 0 on success / other on failure + **/ +static int ibmvfc_abort_task_set(struct scsi_device *sdev) +{ + struct ibmvfc_host *vhost = shost_priv(sdev->host); + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); + struct ibmvfc_cmd *tmf; + struct ibmvfc_event *evt, *found_evt; + union ibmvfc_iu rsp_iu; + struct ibmvfc_fcp_rsp *fc_rsp = &rsp_iu.cmd.rsp; + int rsp_rc = -EBUSY; + unsigned long flags; + int rsp_code = 0; + + spin_lock_irqsave(vhost->host->host_lock, flags); + found_evt = NULL; + list_for_each_entry(evt, &vhost->sent, queue) { + if (evt->cmnd && evt->cmnd->device == sdev) { + found_evt = evt; + break; + } + } + + if (!found_evt) { + if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) + sdev_printk(KERN_INFO, sdev, "No events found to abort\n"); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return 0; + } + + if (vhost->state == IBMVFC_ACTIVE) { + evt = ibmvfc_get_event(vhost); + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); + + tmf = &evt->iu.cmd; + memset(tmf, 0, sizeof(*tmf)); + tmf->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp); + tmf->resp.len = sizeof(tmf->rsp); + tmf->frame_type = IBMVFC_SCSI_FCP_TYPE; + tmf->payload_len = sizeof(tmf->iu); + tmf->resp_len = sizeof(tmf->rsp); + tmf->cancel_key = (unsigned long)sdev->hostdata; + tmf->tgt_scsi_id = rport->port_id; + int_to_scsilun(sdev->lun, &tmf->iu.lun); + tmf->flags = (IBMVFC_NO_MEM_DESC | IBMVFC_TMF); + tmf->iu.tmf_flags = IBMVFC_ABORT_TASK_SET; + evt->sync_iu = &rsp_iu; + + init_completion(&evt->comp); + rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); + } + + spin_unlock_irqrestore(vhost->host->host_lock, flags); + + if (rsp_rc != 0) { + sdev_printk(KERN_ERR, sdev, "Failed to send abort. rc=%d\n", rsp_rc); + return -EIO; + } + + sdev_printk(KERN_INFO, sdev, "Aborting outstanding commands\n"); + wait_for_completion(&evt->comp); + + if (rsp_iu.cmd.status) { + if (fc_rsp->flags & FCP_RSP_LEN_VALID) + rsp_code = fc_rsp->data.info.rsp_code; + + sdev_printk(KERN_ERR, sdev, "Abort failed: %s (%x:%x) " + "flags: %x fcp_rsp: %x, scsi_status: %x\n", + ibmvfc_get_cmd_error(rsp_iu.cmd.status, rsp_iu.cmd.error), + rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code, + fc_rsp->scsi_status); + rsp_rc = -EIO; + } else + sdev_printk(KERN_INFO, sdev, "Abort successful\n"); + + spin_lock_irqsave(vhost->host->host_lock, flags); + ibmvfc_free_event(evt); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return rsp_rc; +} + +/** + * ibmvfc_cancel_all - Cancel all outstanding commands to the device + * @sdev: scsi device to cancel commands + * @type: type of error recovery being performed + * + * This sends a cancel to the VIOS for the specified device. This does + * NOT send any abort to the actual device. That must be done separately. + * + * Returns: + * 0 on success / other on failure + **/ +static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) +{ + struct ibmvfc_host *vhost = shost_priv(sdev->host); + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); + struct ibmvfc_tmf *tmf; + struct ibmvfc_event *evt, *found_evt; + union ibmvfc_iu rsp; + int rsp_rc = -EBUSY; + unsigned long flags; + u16 status; + + ENTER; + spin_lock_irqsave(vhost->host->host_lock, flags); + found_evt = NULL; + list_for_each_entry(evt, &vhost->sent, queue) { + if (evt->cmnd && evt->cmnd->device == sdev) { + found_evt = evt; + break; + } + } + + if (!found_evt) { + if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) + sdev_printk(KERN_INFO, sdev, "No events found to cancel\n"); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return 0; + } + + if (vhost->state == IBMVFC_ACTIVE) { + evt = ibmvfc_get_event(vhost); + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + + tmf = &evt->iu.tmf; + memset(tmf, 0, sizeof(*tmf)); + tmf->common.version = 1; + tmf->common.opcode = IBMVFC_TMF_MAD; + tmf->common.length = sizeof(*tmf); + tmf->scsi_id = rport->port_id; + int_to_scsilun(sdev->lun, &tmf->lun); + tmf->flags = (type | IBMVFC_TMF_LUA_VALID); + tmf->cancel_key = (unsigned long)sdev->hostdata; + tmf->my_cancel_key = (IBMVFC_TMF_CANCEL_KEY | (unsigned long)sdev->hostdata); + + evt->sync_iu = &rsp; + init_completion(&evt->comp); + rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); + } + + spin_unlock_irqrestore(vhost->host->host_lock, flags); + + if (rsp_rc != 0) { + sdev_printk(KERN_ERR, sdev, "Failed to send cancel event. rc=%d\n", rsp_rc); + return -EIO; + } + + sdev_printk(KERN_INFO, sdev, "Cancelling outstanding commands.\n"); + + wait_for_completion(&evt->comp); + status = rsp.mad_common.status; + spin_lock_irqsave(vhost->host->host_lock, flags); + ibmvfc_free_event(evt); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + + if (status != IBMVFC_MAD_SUCCESS) { + sdev_printk(KERN_WARNING, sdev, "Cancel failed with rc=%x\n", status); + return -EIO; + } + + sdev_printk(KERN_INFO, sdev, "Successfully cancelled outstanding commands\n"); + return 0; +} + +/** + * ibmvfc_eh_abort_handler - Abort a command + * @cmd: scsi command to abort + * + * Returns: + * SUCCESS / FAILED + **/ +static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) +{ + struct ibmvfc_host *vhost = shost_priv(cmd->device->host); + struct ibmvfc_event *evt, *pos; + int cancel_rc, abort_rc; + unsigned long flags; + + ENTER; + ibmvfc_wait_while_resetting(vhost); + cancel_rc = ibmvfc_cancel_all(cmd->device, IBMVFC_TMF_ABORT_TASK_SET); + abort_rc = ibmvfc_abort_task_set(cmd->device); + + if (!cancel_rc && !abort_rc) { + spin_lock_irqsave(vhost->host->host_lock, flags); + list_for_each_entry_safe(evt, pos, &vhost->sent, queue) { + if (evt->cmnd && evt->cmnd->device == cmd->device) + ibmvfc_fail_request(evt, DID_ABORT); + } + spin_unlock_irqrestore(vhost->host->host_lock, flags); + LEAVE; + return SUCCESS; + } + + LEAVE; + return FAILED; +} + +/** + * ibmvfc_eh_device_reset_handler - Reset a single LUN + * @cmd: scsi command struct + * + * Returns: + * SUCCESS / FAILED + **/ +static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd) +{ + struct ibmvfc_host *vhost = shost_priv(cmd->device->host); + struct ibmvfc_event *evt, *pos; + int cancel_rc, reset_rc; + unsigned long flags; + + ENTER; + ibmvfc_wait_while_resetting(vhost); + cancel_rc = ibmvfc_cancel_all(cmd->device, IBMVFC_TMF_LUN_RESET); + reset_rc = ibmvfc_reset_device(cmd->device, IBMVFC_LUN_RESET, "LUN"); + + if (!cancel_rc && !reset_rc) { + spin_lock_irqsave(vhost->host->host_lock, flags); + list_for_each_entry_safe(evt, pos, &vhost->sent, queue) { + if (evt->cmnd && evt->cmnd->device == cmd->device) + ibmvfc_fail_request(evt, DID_ABORT); + } + spin_unlock_irqrestore(vhost->host->host_lock, flags); + LEAVE; + return SUCCESS; + } + + LEAVE; + return FAILED; +} + +/** + * ibmvfc_dev_cancel_all - Device iterated cancel all function + * @sdev: scsi device struct + * @data: return code + * + **/ +static void ibmvfc_dev_cancel_all(struct scsi_device *sdev, void *data) +{ + unsigned long *rc = data; + *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET); +} + +/** + * ibmvfc_dev_abort_all - Device iterated abort task set function + * @sdev: scsi device struct + * @data: return code + * + **/ +static void ibmvfc_dev_abort_all(struct scsi_device *sdev, void *data) +{ + unsigned long *rc = data; + *rc |= ibmvfc_abort_task_set(sdev); +} + +/** + * ibmvfc_eh_target_reset_handler - Reset the target + * @cmd: scsi command struct + * + * Returns: + * SUCCESS / FAILED + **/ +static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd) +{ + struct ibmvfc_host *vhost = shost_priv(cmd->device->host); + struct scsi_target *starget = scsi_target(cmd->device); + struct ibmvfc_event *evt, *pos; + int reset_rc; + unsigned long cancel_rc = 0; + unsigned long flags; + + ENTER; + ibmvfc_wait_while_resetting(vhost); + starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all); + reset_rc = ibmvfc_reset_device(cmd->device, IBMVFC_TARGET_RESET, "target"); + + if (!cancel_rc && !reset_rc) { + spin_lock_irqsave(vhost->host->host_lock, flags); + list_for_each_entry_safe(evt, pos, &vhost->sent, queue) { + if (evt->cmnd && scsi_target(evt->cmnd->device) == starget) + ibmvfc_fail_request(evt, DID_ABORT); + } + spin_unlock_irqrestore(vhost->host->host_lock, flags); + LEAVE; + return SUCCESS; + } + + LEAVE; + return FAILED; +} + +/** + * ibmvfc_eh_host_reset_handler - Reset the connection to the server + * @cmd: struct scsi_cmnd having problems + * + **/ +static int ibmvfc_eh_host_reset_handler(struct scsi_cmnd *cmd) +{ + int rc; + struct ibmvfc_host *vhost = shost_priv(cmd->device->host); + + dev_err(vhost->dev, "Resetting connection due to error recovery\n"); + rc = ibmvfc_issue_fc_host_lip(vhost->host); + return rc ? FAILED : SUCCESS; +} + +/** + * ibmvfc_terminate_rport_io - Terminate all pending I/O to the rport. + * @rport: rport struct + * + * Return value: + * none + **/ +static void ibmvfc_terminate_rport_io(struct fc_rport *rport) +{ + struct scsi_target *starget = to_scsi_target(&rport->dev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct ibmvfc_host *vhost = shost_priv(shost); + struct ibmvfc_event *evt, *pos; + unsigned long cancel_rc = 0; + unsigned long abort_rc = 0; + unsigned long flags; + + ENTER; + starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all); + starget_for_each_device(starget, &abort_rc, ibmvfc_dev_abort_all); + + if (!cancel_rc && !abort_rc) { + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry_safe(evt, pos, &vhost->sent, queue) { + if (evt->cmnd && scsi_target(evt->cmnd->device) == starget) + ibmvfc_fail_request(evt, DID_ABORT); + } + spin_unlock_irqrestore(shost->host_lock, flags); + } else + ibmvfc_issue_fc_host_lip(shost); + + scsi_target_unblock(&rport->dev); + LEAVE; +} + +static const struct { + enum ibmvfc_async_event ae; + const char *desc; +} ae_desc [] = { + { IBMVFC_AE_ELS_PLOGI, "PLOGI" }, + { IBMVFC_AE_ELS_LOGO, "LOGO" }, + { IBMVFC_AE_ELS_PRLO, "PRLO" }, + { IBMVFC_AE_SCN_NPORT, "N-Port SCN" }, + { IBMVFC_AE_SCN_GROUP, "Group SCN" }, + { IBMVFC_AE_SCN_DOMAIN, "Domain SCN" }, + { IBMVFC_AE_SCN_FABRIC, "Fabric SCN" }, + { IBMVFC_AE_LINK_UP, "Link Up" }, + { IBMVFC_AE_LINK_DOWN, "Link Down" }, + { IBMVFC_AE_LINK_DEAD, "Link Dead" }, + { IBMVFC_AE_HALT, "Halt" }, + { IBMVFC_AE_RESUME, "Resume" }, + { IBMVFC_AE_ADAPTER_FAILED, "Adapter Failed" }, +}; + +static const char *unknown_ae = "Unknown async"; + +/** + * ibmvfc_get_ae_desc - Get text description for async event + * @ae: async event + * + **/ +static const char *ibmvfc_get_ae_desc(u64 ae) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ae_desc); i++) + if (ae_desc[i].ae == ae) + return ae_desc[i].desc; + + return unknown_ae; +} + +/** + * ibmvfc_handle_async - Handle an async event from the adapter + * @crq: crq to process + * @vhost: ibmvfc host struct + * + **/ +static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, + struct ibmvfc_host *vhost) +{ + const char *desc = ibmvfc_get_ae_desc(crq->event); + + ibmvfc_log(vhost, 2, "%s event received\n", desc); + + switch (crq->event) { + case IBMVFC_AE_LINK_UP: + case IBMVFC_AE_RESUME: + vhost->events_to_log |= IBMVFC_AE_LINKUP; + ibmvfc_init_host(vhost); + break; + case IBMVFC_AE_SCN_FABRIC: + vhost->events_to_log |= IBMVFC_AE_RSCN; + ibmvfc_init_host(vhost); + break; + case IBMVFC_AE_SCN_NPORT: + case IBMVFC_AE_SCN_GROUP: + case IBMVFC_AE_SCN_DOMAIN: + vhost->events_to_log |= IBMVFC_AE_RSCN; + case IBMVFC_AE_ELS_LOGO: + case IBMVFC_AE_ELS_PRLO: + case IBMVFC_AE_ELS_PLOGI: + ibmvfc_reinit_host(vhost); + break; + case IBMVFC_AE_LINK_DOWN: + case IBMVFC_AE_ADAPTER_FAILED: + ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN); + break; + case IBMVFC_AE_LINK_DEAD: + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + break; + case IBMVFC_AE_HALT: + ibmvfc_link_down(vhost, IBMVFC_HALTED); + break; + default: + dev_err(vhost->dev, "Unknown async event received: %ld\n", crq->event); + break; + }; +} + +/** + * ibmvfc_handle_crq - Handles and frees received events in the CRQ + * @crq: Command/Response queue + * @vhost: ibmvfc host struct + * + **/ +static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) +{ + long rc; + struct ibmvfc_event *evt = (struct ibmvfc_event *)crq->ioba; + + switch (crq->valid) { + case IBMVFC_CRQ_INIT_RSP: + switch (crq->format) { + case IBMVFC_CRQ_INIT: + dev_info(vhost->dev, "Partner initialized\n"); + /* Send back a response */ + rc = ibmvfc_send_crq_init_complete(vhost); + if (rc == 0) + ibmvfc_init_host(vhost); + else + dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc); + break; + case IBMVFC_CRQ_INIT_COMPLETE: + dev_info(vhost->dev, "Partner initialization complete\n"); + ibmvfc_init_host(vhost); + break; + default: + dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format); + } + return; + case IBMVFC_CRQ_XPORT_EVENT: + vhost->state = IBMVFC_NO_CRQ; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); + if (crq->format == IBMVFC_PARTITION_MIGRATED) { + /* We need to re-setup the interpartition connection */ + dev_info(vhost->dev, "Re-enabling adapter\n"); + vhost->client_migrated = 1; + ibmvfc_purge_requests(vhost, DID_REQUEUE); + if ((rc = ibmvfc_reenable_crq_queue(vhost)) || + (rc = ibmvfc_send_crq_init(vhost))) { + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + dev_err(vhost->dev, "Error after enable (rc=%ld)\n", rc); + } else + ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN); + } else { + dev_err(vhost->dev, "Virtual adapter failed (rc=%d)\n", crq->format); + + ibmvfc_purge_requests(vhost, DID_ERROR); + if ((rc = ibmvfc_reset_crq(vhost)) || + (rc = ibmvfc_send_crq_init(vhost))) { + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + dev_err(vhost->dev, "Error after reset (rc=%ld)\n", rc); + } else + ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN); + } + return; + case IBMVFC_CRQ_CMD_RSP: + break; + default: + dev_err(vhost->dev, "Got an invalid message type 0x%02x\n", crq->valid); + return; + } + + if (crq->format == IBMVFC_ASYNC_EVENT) + return; + + /* The only kind of payload CRQs we should get are responses to + * things we send. Make sure this response is to something we + * actually sent + */ + if (unlikely(!ibmvfc_valid_event(&vhost->pool, evt))) { + dev_err(vhost->dev, "Returned correlation_token 0x%08lx is invalid!\n", + crq->ioba); + return; + } + + if (unlikely(atomic_read(&evt->free))) { + dev_err(vhost->dev, "Received duplicate correlation_token 0x%08lx!\n", + crq->ioba); + return; + } + + del_timer(&evt->timer); + list_del(&evt->queue); + ibmvfc_trc_end(evt); + evt->done(evt); +} + +/** + * ibmvfc_scan_finished - Check if the device scan is done. + * @shost: scsi host struct + * @time: current elapsed time + * + * Returns: + * 0 if scan is not done / 1 if scan is done + **/ +static int ibmvfc_scan_finished(struct Scsi_Host *shost, unsigned long time) +{ + unsigned long flags; + struct ibmvfc_host *vhost = shost_priv(shost); + int done = 0; + + spin_lock_irqsave(shost->host_lock, flags); + if (time >= (init_timeout * HZ)) { + dev_info(vhost->dev, "Scan taking longer than %d seconds, " + "continuing initialization\n", init_timeout); + done = 1; + } + + if (vhost->state != IBMVFC_NO_CRQ && vhost->action == IBMVFC_HOST_ACTION_NONE) + done = 1; + spin_unlock_irqrestore(shost->host_lock, flags); + return done; +} + +/** + * ibmvfc_slave_alloc - Setup the device's task set value + * @sdev: struct scsi_device device to configure + * + * Set the device's task set value so that error handling works as + * expected. + * + * Returns: + * 0 on success / -ENXIO if device does not exist + **/ +static int ibmvfc_slave_alloc(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); + struct ibmvfc_host *vhost = shost_priv(shost); + unsigned long flags = 0; + + if (!rport || fc_remote_port_chkready(rport)) + return -ENXIO; + + spin_lock_irqsave(shost->host_lock, flags); + sdev->hostdata = (void *)(unsigned long)vhost->task_set++; + spin_unlock_irqrestore(shost->host_lock, flags); + return 0; +} + +/** + * ibmvfc_slave_configure - Configure the device + * @sdev: struct scsi_device device to configure + * + * Enable allow_restart for a device if it is a disk. Adjust the + * queue_depth here also. + * + * Returns: + * 0 + **/ +static int ibmvfc_slave_configure(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + struct fc_rport *rport = starget_to_rport(sdev->sdev_target); + unsigned long flags = 0; + + spin_lock_irqsave(shost->host_lock, flags); + if (sdev->type == TYPE_DISK) + sdev->allow_restart = 1; + + if (sdev->tagged_supported) { + scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); + scsi_activate_tcq(sdev, sdev->queue_depth); + } else + scsi_deactivate_tcq(sdev, sdev->queue_depth); + + rport->dev_loss_tmo = dev_loss_tmo; + spin_unlock_irqrestore(shost->host_lock, flags); + return 0; +} + +/** + * ibmvfc_change_queue_depth - Change the device's queue depth + * @sdev: scsi device struct + * @qdepth: depth to set + * + * Return value: + * actual depth set + **/ +static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth) +{ + if (qdepth > IBMVFC_MAX_CMDS_PER_LUN) + qdepth = IBMVFC_MAX_CMDS_PER_LUN; + + scsi_adjust_queue_depth(sdev, 0, qdepth); + return sdev->queue_depth; +} + +/** + * ibmvfc_change_queue_type - Change the device's queue type + * @sdev: scsi device struct + * @tag_type: type of tags to use + * + * Return value: + * actual queue type set + **/ +static int ibmvfc_change_queue_type(struct scsi_device *sdev, int tag_type) +{ + if (sdev->tagged_supported) { + scsi_set_tag_type(sdev, tag_type); + + if (tag_type) + scsi_activate_tcq(sdev, sdev->queue_depth); + else + scsi_deactivate_tcq(sdev, sdev->queue_depth); + } else + tag_type = 0; + + return tag_type; +} + +static ssize_t ibmvfc_show_host_partition_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + + return snprintf(buf, PAGE_SIZE, "%s\n", + vhost->login_buf->resp.partition_name); +} + +static struct device_attribute ibmvfc_host_partition_name = { + .attr = { + .name = "partition_name", + .mode = S_IRUGO, + }, + .show = ibmvfc_show_host_partition_name, +}; + +static ssize_t ibmvfc_show_host_device_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + + return snprintf(buf, PAGE_SIZE, "%s\n", + vhost->login_buf->resp.device_name); +} + +static struct device_attribute ibmvfc_host_device_name = { + .attr = { + .name = "device_name", + .mode = S_IRUGO, + }, + .show = ibmvfc_show_host_device_name, +}; + +static ssize_t ibmvfc_show_host_loc_code(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + + return snprintf(buf, PAGE_SIZE, "%s\n", + vhost->login_buf->resp.port_loc_code); +} + +static struct device_attribute ibmvfc_host_loc_code = { + .attr = { + .name = "port_loc_code", + .mode = S_IRUGO, + }, + .show = ibmvfc_show_host_loc_code, +}; + +static ssize_t ibmvfc_show_host_drc_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + + return snprintf(buf, PAGE_SIZE, "%s\n", + vhost->login_buf->resp.drc_name); +} + +static struct device_attribute ibmvfc_host_drc_name = { + .attr = { + .name = "drc_name", + .mode = S_IRUGO, + }, + .show = ibmvfc_show_host_drc_name, +}; + +static ssize_t ibmvfc_show_host_npiv_version(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + return snprintf(buf, PAGE_SIZE, "%d\n", vhost->login_buf->resp.version); +} + +static struct device_attribute ibmvfc_host_npiv_version = { + .attr = { + .name = "npiv_version", + .mode = S_IRUGO, + }, + .show = ibmvfc_show_host_npiv_version, +}; + +/** + * ibmvfc_show_log_level - Show the adapter's error logging level + * @dev: class device struct + * @buf: buffer + * + * Return value: + * number of bytes printed to buffer + **/ +static ssize_t ibmvfc_show_log_level(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + unsigned long flags = 0; + int len; + + spin_lock_irqsave(shost->host_lock, flags); + len = snprintf(buf, PAGE_SIZE, "%d\n", vhost->log_level); + spin_unlock_irqrestore(shost->host_lock, flags); + return len; +} + +/** + * ibmvfc_store_log_level - Change the adapter's error logging level + * @dev: class device struct + * @buf: buffer + * + * Return value: + * number of bytes printed to buffer + **/ +static ssize_t ibmvfc_store_log_level(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + unsigned long flags = 0; + + spin_lock_irqsave(shost->host_lock, flags); + vhost->log_level = simple_strtoul(buf, NULL, 10); + spin_unlock_irqrestore(shost->host_lock, flags); + return strlen(buf); +} + +static struct device_attribute ibmvfc_log_level_attr = { + .attr = { + .name = "log_level", + .mode = S_IRUGO | S_IWUSR, + }, + .show = ibmvfc_show_log_level, + .store = ibmvfc_store_log_level +}; + +#ifdef CONFIG_SCSI_IBMVFC_TRACE +/** + * ibmvfc_read_trace - Dump the adapter trace + * @kobj: kobject struct + * @bin_attr: bin_attribute struct + * @buf: buffer + * @off: offset + * @count: buffer size + * + * Return value: + * number of bytes printed to buffer + **/ +static ssize_t ibmvfc_read_trace(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct Scsi_Host *shost = class_to_shost(dev); + struct ibmvfc_host *vhost = shost_priv(shost); + unsigned long flags = 0; + int size = IBMVFC_TRACE_SIZE; + char *src = (char *)vhost->trace; + + if (off > size) + return 0; + if (off + count > size) { + size -= off; + count = size; + } + + spin_lock_irqsave(shost->host_lock, flags); + memcpy(buf, &src[off], count); + spin_unlock_irqrestore(shost->host_lock, flags); + return count; +} + +static struct bin_attribute ibmvfc_trace_attr = { + .attr = { + .name = "trace", + .mode = S_IRUGO, + }, + .size = 0, + .read = ibmvfc_read_trace, +}; +#endif + +static struct device_attribute *ibmvfc_attrs[] = { + &ibmvfc_host_partition_name, + &ibmvfc_host_device_name, + &ibmvfc_host_loc_code, + &ibmvfc_host_drc_name, + &ibmvfc_host_npiv_version, + &ibmvfc_log_level_attr, + NULL +}; + +static struct scsi_host_template driver_template = { + .module = THIS_MODULE, + .name = "IBM POWER Virtual FC Adapter", + .proc_name = IBMVFC_NAME, + .queuecommand = ibmvfc_queuecommand, + .eh_abort_handler = ibmvfc_eh_abort_handler, + .eh_device_reset_handler = ibmvfc_eh_device_reset_handler, + .eh_target_reset_handler = ibmvfc_eh_target_reset_handler, + .eh_host_reset_handler = ibmvfc_eh_host_reset_handler, + .slave_alloc = ibmvfc_slave_alloc, + .slave_configure = ibmvfc_slave_configure, + .scan_finished = ibmvfc_scan_finished, + .change_queue_depth = ibmvfc_change_queue_depth, + .change_queue_type = ibmvfc_change_queue_type, + .cmd_per_lun = 16, + .can_queue = IBMVFC_MAX_REQUESTS_DEFAULT, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = IBMVFC_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = ibmvfc_attrs, +}; + +/** + * ibmvfc_next_async_crq - Returns the next entry in async queue + * @vhost: ibmvfc host struct + * + * Returns: + * Pointer to next entry in queue / NULL if empty + **/ +static struct ibmvfc_async_crq *ibmvfc_next_async_crq(struct ibmvfc_host *vhost) +{ + struct ibmvfc_async_crq_queue *async_crq = &vhost->async_crq; + struct ibmvfc_async_crq *crq; + + crq = &async_crq->msgs[async_crq->cur]; + if (crq->valid & 0x80) { + if (++async_crq->cur == async_crq->size) + async_crq->cur = 0; + } else + crq = NULL; + + return crq; +} + +/** + * ibmvfc_next_crq - Returns the next entry in message queue + * @vhost: ibmvfc host struct + * + * Returns: + * Pointer to next entry in queue / NULL if empty + **/ +static struct ibmvfc_crq *ibmvfc_next_crq(struct ibmvfc_host *vhost) +{ + struct ibmvfc_crq_queue *queue = &vhost->crq; + struct ibmvfc_crq *crq; + + crq = &queue->msgs[queue->cur]; + if (crq->valid & 0x80) { + if (++queue->cur == queue->size) + queue->cur = 0; + } else + crq = NULL; + + return crq; +} + +/** + * ibmvfc_interrupt - Interrupt handler + * @irq: number of irq to handle, not used + * @dev_instance: ibmvfc_host that received interrupt + * + * Returns: + * IRQ_HANDLED + **/ +static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance) +{ + struct ibmvfc_host *vhost = (struct ibmvfc_host *)dev_instance; + struct vio_dev *vdev = to_vio_dev(vhost->dev); + struct ibmvfc_crq *crq; + struct ibmvfc_async_crq *async; + unsigned long flags; + int done = 0; + + spin_lock_irqsave(vhost->host->host_lock, flags); + vio_disable_interrupts(to_vio_dev(vhost->dev)); + while (!done) { + /* Pull all the valid messages off the CRQ */ + while ((crq = ibmvfc_next_crq(vhost)) != NULL) { + ibmvfc_handle_crq(crq, vhost); + crq->valid = 0; + } + + /* Pull all the valid messages off the async CRQ */ + while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { + ibmvfc_handle_async(async, vhost); + async->valid = 0; + } + + vio_enable_interrupts(vdev); + if ((crq = ibmvfc_next_crq(vhost)) != NULL) { + vio_disable_interrupts(vdev); + ibmvfc_handle_crq(crq, vhost); + crq->valid = 0; + } else if ((async = ibmvfc_next_async_crq(vhost)) != NULL) { + vio_disable_interrupts(vdev); + ibmvfc_handle_async(async, vhost); + crq->valid = 0; + } else + done = 1; + } + + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return IRQ_HANDLED; +} + +/** + * ibmvfc_init_tgt - Set the next init job step for the target + * @tgt: ibmvfc target struct + * @job_step: job step to perform + * + **/ +static void ibmvfc_init_tgt(struct ibmvfc_target *tgt, + void (*job_step) (struct ibmvfc_target *)) +{ + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT); + tgt->job_step = job_step; + wake_up(&tgt->vhost->work_wait_q); +} + +/** + * ibmvfc_retry_tgt_init - Attempt to retry a step in target initialization + * @tgt: ibmvfc target struct + * @job_step: initialization job step + * + **/ +static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt, + void (*job_step) (struct ibmvfc_target *)) +{ + if (++tgt->init_retries > IBMVFC_MAX_INIT_RETRIES) { + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); + wake_up(&tgt->vhost->work_wait_q); + } else + ibmvfc_init_tgt(tgt, job_step); +} + +/** + * ibmvfc_release_tgt - Free memory allocated for a target + * @kref: kref struct + * + **/ +static void ibmvfc_release_tgt(struct kref *kref) +{ + struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref); + kfree(tgt); +} + +/** + * ibmvfc_tgt_prli_done - Completion handler for Process Login + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_target *tgt = evt->tgt; + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli; + u32 status = rsp->common.status; + + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + switch (status) { + case IBMVFC_MAD_SUCCESS: + tgt_dbg(tgt, "Process Login succeeded\n"); + tgt->need_login = 0; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT); + break; + case IBMVFC_MAD_DRIVER_FAILED: + break; + case IBMVFC_MAD_CRQ_ERROR: + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); + break; + case IBMVFC_MAD_FAILED: + default: + tgt_err(tgt, "Process Login failed: %s (%x:%x) rc=0x%02X\n", + ibmvfc_get_cmd_error(rsp->status, rsp->error), + rsp->status, rsp->error, status); + if (ibmvfc_retry_cmd(rsp->status, rsp->error)) + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); + break; + }; + + kref_put(&tgt->kref, ibmvfc_release_tgt); + ibmvfc_free_event(evt); + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_tgt_send_prli - Send a process login + * @tgt: ibmvfc target struct + * + **/ +static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt) +{ + struct ibmvfc_process_login *prli; + struct ibmvfc_host *vhost = tgt->vhost; + struct ibmvfc_event *evt; + + if (vhost->discovery_threads >= disc_threads) + return; + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(vhost); + vhost->discovery_threads++; + ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; + prli = &evt->iu.prli; + memset(prli, 0, sizeof(*prli)); + prli->common.version = 1; + prli->common.opcode = IBMVFC_PROCESS_LOGIN; + prli->common.length = sizeof(*prli); + prli->scsi_id = tgt->scsi_id; + + prli->parms.type = IBMVFC_SCSI_FCP_TYPE; + prli->parms.flags = IBMVFC_PRLI_EST_IMG_PAIR; + prli->parms.service_parms = IBMVFC_PRLI_INITIATOR_FUNC; + + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + if (ibmvfc_send_event(evt, vhost, default_timeout)) { + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + kref_put(&tgt->kref, ibmvfc_release_tgt); + } else + tgt_dbg(tgt, "Sent process login\n"); +} + +/** + * ibmvfc_tgt_plogi_done - Completion handler for Port Login + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_target *tgt = evt->tgt; + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_port_login *rsp = &evt->xfer_iu->plogi; + u32 status = rsp->common.status; + + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + switch (status) { + case IBMVFC_MAD_SUCCESS: + tgt_dbg(tgt, "Port Login succeeded\n"); + if (tgt->ids.port_name && + tgt->ids.port_name != wwn_to_u64(rsp->service_parms.port_name)) { + vhost->reinit = 1; + tgt_dbg(tgt, "Port re-init required\n"); + break; + } + tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name); + tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name); + tgt->ids.port_id = tgt->scsi_id; + tgt->ids.roles = FC_PORT_ROLE_FCP_TARGET; + memcpy(&tgt->service_parms, &rsp->service_parms, + sizeof(tgt->service_parms)); + memcpy(&tgt->service_parms_change, &rsp->service_parms_change, + sizeof(tgt->service_parms_change)); + ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_prli); + break; + case IBMVFC_MAD_DRIVER_FAILED: + break; + case IBMVFC_MAD_CRQ_ERROR: + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); + break; + case IBMVFC_MAD_FAILED: + default: + tgt_err(tgt, "Port Login failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n", + ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error, + ibmvfc_get_fc_type(rsp->fc_type), rsp->fc_type, + ibmvfc_get_ls_explain(rsp->fc_explain), rsp->fc_explain, status); + + if (ibmvfc_retry_cmd(rsp->status, rsp->error)) + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); + break; + }; + + kref_put(&tgt->kref, ibmvfc_release_tgt); + ibmvfc_free_event(evt); + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_tgt_send_plogi - Send PLOGI to the specified target + * @tgt: ibmvfc target struct + * + **/ +static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) +{ + struct ibmvfc_port_login *plogi; + struct ibmvfc_host *vhost = tgt->vhost; + struct ibmvfc_event *evt; + + if (vhost->discovery_threads >= disc_threads) + return; + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(vhost); + vhost->discovery_threads++; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; + plogi = &evt->iu.plogi; + memset(plogi, 0, sizeof(*plogi)); + plogi->common.version = 1; + plogi->common.opcode = IBMVFC_PORT_LOGIN; + plogi->common.length = sizeof(*plogi); + plogi->scsi_id = tgt->scsi_id; + + if (ibmvfc_send_event(evt, vhost, default_timeout)) { + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + kref_put(&tgt->kref, ibmvfc_release_tgt); + } else + tgt_dbg(tgt, "Sent port login\n"); +} + +/** + * ibmvfc_tgt_implicit_logout_done - Completion handler for Implicit Logout MAD + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_tgt_implicit_logout_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_target *tgt = evt->tgt; + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_implicit_logout *rsp = &evt->xfer_iu->implicit_logout; + u32 status = rsp->common.status; + + vhost->discovery_threads--; + ibmvfc_free_event(evt); + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + + switch (status) { + case IBMVFC_MAD_SUCCESS: + tgt_dbg(tgt, "Implicit Logout succeeded\n"); + break; + case IBMVFC_MAD_DRIVER_FAILED: + kref_put(&tgt->kref, ibmvfc_release_tgt); + wake_up(&vhost->work_wait_q); + return; + case IBMVFC_MAD_FAILED: + default: + tgt_err(tgt, "Implicit Logout failed: rc=0x%02X\n", status); + break; + }; + + if (vhost->action == IBMVFC_HOST_ACTION_TGT_INIT) + ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_plogi); + else if (vhost->action == IBMVFC_HOST_ACTION_QUERY_TGTS && + tgt->scsi_id != tgt->new_scsi_id) + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); + kref_put(&tgt->kref, ibmvfc_release_tgt); + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_tgt_implicit_logout - Initiate an Implicit Logout for specified target + * @tgt: ibmvfc target struct + * + **/ +static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) +{ + struct ibmvfc_implicit_logout *mad; + struct ibmvfc_host *vhost = tgt->vhost; + struct ibmvfc_event *evt; + + if (vhost->discovery_threads >= disc_threads) + return; + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(vhost); + vhost->discovery_threads++; + ibmvfc_init_event(evt, ibmvfc_tgt_implicit_logout_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; + mad = &evt->iu.implicit_logout; + memset(mad, 0, sizeof(*mad)); + mad->common.version = 1; + mad->common.opcode = IBMVFC_IMPLICIT_LOGOUT; + mad->common.length = sizeof(*mad); + mad->old_scsi_id = tgt->scsi_id; + + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + if (ibmvfc_send_event(evt, vhost, default_timeout)) { + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + kref_put(&tgt->kref, ibmvfc_release_tgt); + } else + tgt_dbg(tgt, "Sent Implicit Logout\n"); +} + +/** + * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_target *tgt = evt->tgt; + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_query_tgt *rsp = &evt->xfer_iu->query_tgt; + u32 status = rsp->common.status; + + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + switch (status) { + case IBMVFC_MAD_SUCCESS: + tgt_dbg(tgt, "Query Target succeeded\n"); + tgt->new_scsi_id = rsp->scsi_id; + if (rsp->scsi_id != tgt->scsi_id) + ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); + break; + case IBMVFC_MAD_DRIVER_FAILED: + break; + case IBMVFC_MAD_CRQ_ERROR: + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target); + break; + case IBMVFC_MAD_FAILED: + default: + tgt_err(tgt, "Query Target failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n", + ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error, + ibmvfc_get_fc_type(rsp->fc_type), rsp->fc_type, + ibmvfc_get_gs_explain(rsp->fc_explain), rsp->fc_explain, status); + + if ((rsp->status & IBMVFC_FABRIC_MAPPED) == IBMVFC_FABRIC_MAPPED && + rsp->error == IBMVFC_UNABLE_TO_PERFORM_REQ && + rsp->fc_explain == IBMVFC_PORT_NAME_NOT_REG) + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); + else if (ibmvfc_retry_cmd(rsp->status, rsp->error)) + ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target); + break; + }; + + kref_put(&tgt->kref, ibmvfc_release_tgt); + ibmvfc_free_event(evt); + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_tgt_query_target - Initiate a Query Target for specified target + * @tgt: ibmvfc target struct + * + **/ +static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt) +{ + struct ibmvfc_query_tgt *query_tgt; + struct ibmvfc_host *vhost = tgt->vhost; + struct ibmvfc_event *evt; + + if (vhost->discovery_threads >= disc_threads) + return; + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(vhost); + vhost->discovery_threads++; + evt->tgt = tgt; + ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT); + query_tgt = &evt->iu.query_tgt; + memset(query_tgt, 0, sizeof(*query_tgt)); + query_tgt->common.version = 1; + query_tgt->common.opcode = IBMVFC_QUERY_TARGET; + query_tgt->common.length = sizeof(*query_tgt); + query_tgt->wwpn = tgt->ids.port_name; + + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + if (ibmvfc_send_event(evt, vhost, default_timeout)) { + vhost->discovery_threads--; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + kref_put(&tgt->kref, ibmvfc_release_tgt); + } else + tgt_dbg(tgt, "Sent Query Target\n"); +} + +/** + * ibmvfc_alloc_target - Allocate and initialize an ibmvfc target + * @vhost: ibmvfc host struct + * @scsi_id: SCSI ID to allocate target for + * + * Returns: + * 0 on success / other on failure + **/ +static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id) +{ + struct ibmvfc_target *tgt; + unsigned long flags; + + spin_lock_irqsave(vhost->host->host_lock, flags); + list_for_each_entry(tgt, &vhost->targets, queue) { + if (tgt->scsi_id == scsi_id) { + if (tgt->need_login) + ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); + goto unlock_out; + } + } + spin_unlock_irqrestore(vhost->host->host_lock, flags); + + tgt = mempool_alloc(vhost->tgt_pool, GFP_KERNEL); + if (!tgt) { + dev_err(vhost->dev, "Target allocation failure for scsi id %08lx\n", + scsi_id); + return -ENOMEM; + } + + tgt->scsi_id = scsi_id; + tgt->new_scsi_id = scsi_id; + tgt->vhost = vhost; + tgt->need_login = 1; + kref_init(&tgt->kref); + ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); + spin_lock_irqsave(vhost->host->host_lock, flags); + list_add_tail(&tgt->queue, &vhost->targets); + +unlock_out: + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return 0; +} + +/** + * ibmvfc_alloc_targets - Allocate and initialize ibmvfc targets + * @vhost: ibmvfc host struct + * + * Returns: + * 0 on success / other on failure + **/ +static int ibmvfc_alloc_targets(struct ibmvfc_host *vhost) +{ + int i, rc; + + for (i = 0, rc = 0; !rc && i < vhost->num_targets; i++) + rc = ibmvfc_alloc_target(vhost, + vhost->disc_buf->scsi_id[i] & IBMVFC_DISC_TGT_SCSI_ID_MASK); + + return rc; +} + +/** + * ibmvfc_discover_targets_done - Completion handler for discover targets MAD + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_discover_targets_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_host *vhost = evt->vhost; + struct ibmvfc_discover_targets *rsp = &evt->xfer_iu->discover_targets; + u32 mad_status = rsp->common.status; + + switch (mad_status) { + case IBMVFC_MAD_SUCCESS: + ibmvfc_dbg(vhost, "Discover Targets succeeded\n"); + vhost->num_targets = rsp->num_written; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_ALLOC_TGTS); + break; + case IBMVFC_MAD_FAILED: + dev_err(vhost->dev, "Discover Targets failed: %s (%x:%x)\n", + ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error); + ibmvfc_retry_host_init(vhost); + break; + case IBMVFC_MAD_DRIVER_FAILED: + break; + default: + dev_err(vhost->dev, "Invalid Discover Targets response: 0x%x\n", mad_status); + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + break; + } + + ibmvfc_free_event(evt); + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_discover_targets - Send Discover Targets MAD + * @vhost: ibmvfc host struct + * + **/ +static void ibmvfc_discover_targets(struct ibmvfc_host *vhost) +{ + struct ibmvfc_discover_targets *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(vhost); + + ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT); + mad = &evt->iu.discover_targets; + memset(mad, 0, sizeof(*mad)); + mad->common.version = 1; + mad->common.opcode = IBMVFC_DISC_TARGETS; + mad->common.length = sizeof(*mad); + mad->bufflen = vhost->disc_buf_sz; + mad->buffer.va = vhost->disc_buf_dma; + mad->buffer.len = vhost->disc_buf_sz; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT); + + if (!ibmvfc_send_event(evt, vhost, default_timeout)) + ibmvfc_dbg(vhost, "Sent discover targets\n"); + else + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); +} + +/** + * ibmvfc_npiv_login_done - Completion handler for NPIV Login + * @evt: ibmvfc event struct + * + **/ +static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt) +{ + struct ibmvfc_host *vhost = evt->vhost; + u32 mad_status = evt->xfer_iu->npiv_login.common.status; + struct ibmvfc_npiv_login_resp *rsp = &vhost->login_buf->resp; + unsigned int npiv_max_sectors; + + switch (mad_status) { + case IBMVFC_MAD_SUCCESS: + ibmvfc_free_event(evt); + break; + case IBMVFC_MAD_FAILED: + dev_err(vhost->dev, "NPIV Login failed: %s (%x:%x)\n", + ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error); + if (ibmvfc_retry_cmd(rsp->status, rsp->error)) + ibmvfc_retry_host_init(vhost); + else + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + ibmvfc_free_event(evt); + return; + case IBMVFC_MAD_CRQ_ERROR: + ibmvfc_retry_host_init(vhost); + case IBMVFC_MAD_DRIVER_FAILED: + ibmvfc_free_event(evt); + return; + default: + dev_err(vhost->dev, "Invalid NPIV Login response: 0x%x\n", mad_status); + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + ibmvfc_free_event(evt); + return; + } + + vhost->client_migrated = 0; + + if (!(rsp->flags & IBMVFC_NATIVE_FC)) { + dev_err(vhost->dev, "Virtual adapter does not support FC. %x\n", + rsp->flags); + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + wake_up(&vhost->work_wait_q); + return; + } + + if (rsp->max_cmds <= IBMVFC_NUM_INTERNAL_REQ) { + dev_err(vhost->dev, "Virtual adapter supported queue depth too small: %d\n", + rsp->max_cmds); + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + wake_up(&vhost->work_wait_q); + return; + } + + npiv_max_sectors = min((uint)(rsp->max_dma_len >> 9), IBMVFC_MAX_SECTORS); + dev_info(vhost->dev, "Host partition: %s, device: %s %s %s max sectors %u\n", + rsp->partition_name, rsp->device_name, rsp->port_loc_code, + rsp->drc_name, npiv_max_sectors); + + fc_host_fabric_name(vhost->host) = rsp->node_name; + fc_host_node_name(vhost->host) = rsp->node_name; + fc_host_port_name(vhost->host) = rsp->port_name; + fc_host_port_id(vhost->host) = rsp->scsi_id; + fc_host_port_type(vhost->host) = FC_PORTTYPE_NPIV; + fc_host_supported_classes(vhost->host) = 0; + if (rsp->service_parms.class1_parms[0] & 0x80000000) + fc_host_supported_classes(vhost->host) |= FC_COS_CLASS1; + if (rsp->service_parms.class2_parms[0] & 0x80000000) + fc_host_supported_classes(vhost->host) |= FC_COS_CLASS2; + if (rsp->service_parms.class3_parms[0] & 0x80000000) + fc_host_supported_classes(vhost->host) |= FC_COS_CLASS3; + fc_host_maxframe_size(vhost->host) = + rsp->service_parms.common.bb_rcv_sz & 0x0fff; + + vhost->host->can_queue = rsp->max_cmds - IBMVFC_NUM_INTERNAL_REQ; + vhost->host->max_sectors = npiv_max_sectors; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); + wake_up(&vhost->work_wait_q); +} + +/** + * ibmvfc_npiv_login - Sends NPIV login + * @vhost: ibmvfc host struct + * + **/ +static void ibmvfc_npiv_login(struct ibmvfc_host *vhost) +{ + struct ibmvfc_npiv_login_mad *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(vhost); + + ibmvfc_gather_partition_info(vhost); + ibmvfc_set_login_info(vhost); + ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT); + + memcpy(vhost->login_buf, &vhost->login_info, sizeof(vhost->login_info)); + mad = &evt->iu.npiv_login; + memset(mad, 0, sizeof(struct ibmvfc_npiv_login_mad)); + mad->common.version = 1; + mad->common.opcode = IBMVFC_NPIV_LOGIN; + mad->common.length = sizeof(struct ibmvfc_npiv_login_mad); + mad->buffer.va = vhost->login_buf_dma; + mad->buffer.len = sizeof(*vhost->login_buf); + + memset(vhost->async_crq.msgs, 0, PAGE_SIZE); + vhost->async_crq.cur = 0; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT); + + if (!ibmvfc_send_event(evt, vhost, default_timeout)) + ibmvfc_dbg(vhost, "Sent NPIV login\n"); + else + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); +}; + +/** + * ibmvfc_dev_init_to_do - Is there target initialization work to do? + * @vhost: ibmvfc host struct + * + * Returns: + * 1 if work to do / 0 if not + **/ +static int ibmvfc_dev_init_to_do(struct ibmvfc_host *vhost) +{ + struct ibmvfc_target *tgt; + + list_for_each_entry(tgt, &vhost->targets, queue) { + if (tgt->action == IBMVFC_TGT_ACTION_INIT || + tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT) + return 1; + } + + return 0; +} + +/** + * __ibmvfc_work_to_do - Is there task level work to do? (no locking) + * @vhost: ibmvfc host struct + * + * Returns: + * 1 if work to do / 0 if not + **/ +static int __ibmvfc_work_to_do(struct ibmvfc_host *vhost) +{ + struct ibmvfc_target *tgt; + + if (kthread_should_stop()) + return 1; + switch (vhost->action) { + case IBMVFC_HOST_ACTION_NONE: + case IBMVFC_HOST_ACTION_INIT_WAIT: + return 0; + case IBMVFC_HOST_ACTION_TGT_INIT: + case IBMVFC_HOST_ACTION_QUERY_TGTS: + if (vhost->discovery_threads == disc_threads) + return 0; + list_for_each_entry(tgt, &vhost->targets, queue) + if (tgt->action == IBMVFC_TGT_ACTION_INIT) + return 1; + list_for_each_entry(tgt, &vhost->targets, queue) + if (tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT) + return 0; + return 1; + case IBMVFC_HOST_ACTION_INIT: + case IBMVFC_HOST_ACTION_ALLOC_TGTS: + case IBMVFC_HOST_ACTION_TGT_ADD: + case IBMVFC_HOST_ACTION_TGT_DEL: + case IBMVFC_HOST_ACTION_QUERY: + default: + break; + }; + + return 1; +} + +/** + * ibmvfc_work_to_do - Is there task level work to do? + * @vhost: ibmvfc host struct + * + * Returns: + * 1 if work to do / 0 if not + **/ +static int ibmvfc_work_to_do(struct ibmvfc_host *vhost) +{ + unsigned long flags; + int rc; + + spin_lock_irqsave(vhost->host->host_lock, flags); + rc = __ibmvfc_work_to_do(vhost); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return rc; +} + +/** + * ibmvfc_log_ae - Log async events if necessary + * @vhost: ibmvfc host struct + * @events: events to log + * + **/ +static void ibmvfc_log_ae(struct ibmvfc_host *vhost, int events) +{ + if (events & IBMVFC_AE_RSCN) + fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_RSCN, 0); + if ((events & IBMVFC_AE_LINKDOWN) && + vhost->state >= IBMVFC_HALTED) + fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_LINKDOWN, 0); + if ((events & IBMVFC_AE_LINKUP) && + vhost->state == IBMVFC_INITIALIZING) + fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_LINKUP, 0); +} + +/** + * ibmvfc_tgt_add_rport - Tell the FC transport about a new remote port + * @tgt: ibmvfc target struct + * + **/ +static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) +{ + struct ibmvfc_host *vhost = tgt->vhost; + struct fc_rport *rport; + unsigned long flags; + + tgt_dbg(tgt, "Adding rport\n"); + rport = fc_remote_port_add(vhost->host, 0, &tgt->ids); + spin_lock_irqsave(vhost->host->host_lock, flags); + tgt->rport = rport; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); + if (rport) { + tgt_dbg(tgt, "rport add succeeded\n"); + rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff; + rport->supported_classes = 0; + if (tgt->service_parms.class1_parms[0] & 0x80000000) + rport->supported_classes |= FC_COS_CLASS1; + if (tgt->service_parms.class2_parms[0] & 0x80000000) + rport->supported_classes |= FC_COS_CLASS2; + if (tgt->service_parms.class3_parms[0] & 0x80000000) + rport->supported_classes |= FC_COS_CLASS3; + } else + tgt_dbg(tgt, "rport add failed\n"); + spin_unlock_irqrestore(vhost->host->host_lock, flags); +} + +/** + * ibmvfc_do_work - Do task level work + * @vhost: ibmvfc host struct + * + **/ +static void ibmvfc_do_work(struct ibmvfc_host *vhost) +{ + struct ibmvfc_target *tgt; + unsigned long flags; + struct fc_rport *rport; + + ibmvfc_log_ae(vhost, vhost->events_to_log); + spin_lock_irqsave(vhost->host->host_lock, flags); + vhost->events_to_log = 0; + switch (vhost->action) { + case IBMVFC_HOST_ACTION_NONE: + case IBMVFC_HOST_ACTION_INIT_WAIT: + break; + case IBMVFC_HOST_ACTION_INIT: + BUG_ON(vhost->state != IBMVFC_INITIALIZING); + vhost->job_step(vhost); + break; + case IBMVFC_HOST_ACTION_QUERY: + list_for_each_entry(tgt, &vhost->targets, queue) + ibmvfc_init_tgt(tgt, ibmvfc_tgt_query_target); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY_TGTS); + break; + case IBMVFC_HOST_ACTION_QUERY_TGTS: + list_for_each_entry(tgt, &vhost->targets, queue) { + if (tgt->action == IBMVFC_TGT_ACTION_INIT) { + tgt->job_step(tgt); + break; + } + } + + if (!ibmvfc_dev_init_to_do(vhost)) + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL); + break; + case IBMVFC_HOST_ACTION_TGT_DEL: + list_for_each_entry(tgt, &vhost->targets, queue) { + if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { + tgt_dbg(tgt, "Deleting rport\n"); + rport = tgt->rport; + tgt->rport = NULL; + list_del(&tgt->queue); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + if (rport) + fc_remote_port_delete(rport); + kref_put(&tgt->kref, ibmvfc_release_tgt); + return; + } + } + + if (vhost->state == IBMVFC_INITIALIZING) { + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT); + vhost->job_step = ibmvfc_discover_targets; + } else { + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + scsi_unblock_requests(vhost->host); + wake_up(&vhost->init_wait_q); + return; + } + break; + case IBMVFC_HOST_ACTION_ALLOC_TGTS: + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_INIT); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + ibmvfc_alloc_targets(vhost); + spin_lock_irqsave(vhost->host->host_lock, flags); + break; + case IBMVFC_HOST_ACTION_TGT_INIT: + list_for_each_entry(tgt, &vhost->targets, queue) { + if (tgt->action == IBMVFC_TGT_ACTION_INIT) { + tgt->job_step(tgt); + break; + } + } + + if (!ibmvfc_dev_init_to_do(vhost)) { + ibmvfc_set_host_state(vhost, IBMVFC_ACTIVE); + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_ADD); + vhost->init_retries = 0; + spin_unlock_irqrestore(vhost->host->host_lock, flags); + scsi_unblock_requests(vhost->host); + return; + } + break; + case IBMVFC_HOST_ACTION_TGT_ADD: + list_for_each_entry(tgt, &vhost->targets, queue) { + if (tgt->action == IBMVFC_TGT_ACTION_ADD_RPORT) { + spin_unlock_irqrestore(vhost->host->host_lock, flags); + ibmvfc_tgt_add_rport(tgt); + return; + } else if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { + tgt_dbg(tgt, "Deleting rport\n"); + rport = tgt->rport; + tgt->rport = NULL; + list_del(&tgt->queue); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + if (rport) + fc_remote_port_delete(rport); + kref_put(&tgt->kref, ibmvfc_release_tgt); + return; + } + } + + if (vhost->reinit) { + vhost->reinit = 0; + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); + } else { + ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); + wake_up(&vhost->init_wait_q); + } + break; + default: + break; + }; + + spin_unlock_irqrestore(vhost->host->host_lock, flags); +} + +/** + * ibmvfc_work - Do task level work + * @data: ibmvfc host struct + * + * Returns: + * zero + **/ +static int ibmvfc_work(void *data) +{ + struct ibmvfc_host *vhost = data; + int rc; + + set_user_nice(current, -20); + + while (1) { + rc = wait_event_interruptible(vhost->work_wait_q, + ibmvfc_work_to_do(vhost)); + + BUG_ON(rc); + + if (kthread_should_stop()) + break; + + ibmvfc_do_work(vhost); + } + + ibmvfc_dbg(vhost, "ibmvfc kthread exiting...\n"); + return 0; +} + +/** + * ibmvfc_init_crq - Initializes and registers CRQ with hypervisor + * @vhost: ibmvfc host struct + * + * Allocates a page for messages, maps it for dma, and registers + * the crq with the hypervisor. + * + * Return value: + * zero on success / other on failure + **/ +static int ibmvfc_init_crq(struct ibmvfc_host *vhost) +{ + int rc, retrc = -ENOMEM; + struct device *dev = vhost->dev; + struct vio_dev *vdev = to_vio_dev(dev); + struct ibmvfc_crq_queue *crq = &vhost->crq; + + ENTER; + crq->msgs = (struct ibmvfc_crq *)get_zeroed_page(GFP_KERNEL); + + if (!crq->msgs) + return -ENOMEM; + + crq->size = PAGE_SIZE / sizeof(*crq->msgs); + crq->msg_token = dma_map_single(dev, crq->msgs, + PAGE_SIZE, DMA_BIDIRECTIONAL); + + if (dma_mapping_error(crq->msg_token)) + goto map_failed; + + retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, + crq->msg_token, PAGE_SIZE); + + if (rc == H_RESOURCE) + /* maybe kexecing and resource is busy. try a reset */ + retrc = rc = ibmvfc_reset_crq(vhost); + + if (rc == H_CLOSED) + dev_warn(dev, "Partner adapter not ready\n"); + else if (rc) { + dev_warn(dev, "Error %d opening adapter\n", rc); + goto reg_crq_failed; + } + + retrc = 0; + + if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) { + dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc); + goto req_irq_failed; + } + + if ((rc = vio_enable_interrupts(vdev))) { + dev_err(dev, "Error %d enabling interrupts\n", rc); + goto req_irq_failed; + } + + crq->cur = 0; + LEAVE; + return retrc; + +req_irq_failed: + do { + rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); + } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); +reg_crq_failed: + dma_unmap_single(dev, crq->msg_token, PAGE_SIZE, DMA_BIDIRECTIONAL); +map_failed: + free_page((unsigned long)crq->msgs); + return retrc; +} + +/** + * ibmvfc_free_mem - Free memory for vhost + * @vhost: ibmvfc host struct + * + * Return value: + * none + **/ +static void ibmvfc_free_mem(struct ibmvfc_host *vhost) +{ + struct ibmvfc_async_crq_queue *async_q = &vhost->async_crq; + + ENTER; + mempool_destroy(vhost->tgt_pool); + kfree(vhost->trace); + dma_free_coherent(vhost->dev, vhost->disc_buf_sz, vhost->disc_buf, + vhost->disc_buf_dma); + dma_free_coherent(vhost->dev, sizeof(*vhost->login_buf), + vhost->login_buf, vhost->login_buf_dma); + dma_pool_destroy(vhost->sg_pool); + dma_unmap_single(vhost->dev, async_q->msg_token, + async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL); + free_page((unsigned long)async_q->msgs); + LEAVE; +} + +/** + * ibmvfc_alloc_mem - Allocate memory for vhost + * @vhost: ibmvfc host struct + * + * Return value: + * 0 on success / non-zero on failure + **/ +static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) +{ + struct ibmvfc_async_crq_queue *async_q = &vhost->async_crq; + struct device *dev = vhost->dev; + + ENTER; + async_q->msgs = (struct ibmvfc_async_crq *)get_zeroed_page(GFP_KERNEL); + if (!async_q->msgs) { + dev_err(dev, "Couldn't allocate async queue.\n"); + goto nomem; + } + + async_q->size = PAGE_SIZE / sizeof(struct ibmvfc_async_crq); + async_q->msg_token = dma_map_single(dev, async_q->msgs, + async_q->size * sizeof(*async_q->msgs), + DMA_BIDIRECTIONAL); + + if (dma_mapping_error(async_q->msg_token)) { + dev_err(dev, "Failed to map async queue\n"); + goto free_async_crq; + } + + vhost->sg_pool = dma_pool_create(IBMVFC_NAME, dev, + SG_ALL * sizeof(struct srp_direct_buf), + sizeof(struct srp_direct_buf), 0); + + if (!vhost->sg_pool) { + dev_err(dev, "Failed to allocate sg pool\n"); + goto unmap_async_crq; + } + + vhost->login_buf = dma_alloc_coherent(dev, sizeof(*vhost->login_buf), + &vhost->login_buf_dma, GFP_KERNEL); + + if (!vhost->login_buf) { + dev_err(dev, "Couldn't allocate NPIV login buffer\n"); + goto free_sg_pool; + } + + vhost->disc_buf_sz = sizeof(vhost->disc_buf->scsi_id[0]) * max_targets; + vhost->disc_buf = dma_alloc_coherent(dev, vhost->disc_buf_sz, + &vhost->disc_buf_dma, GFP_KERNEL); + + if (!vhost->disc_buf) { + dev_err(dev, "Couldn't allocate Discover Targets buffer\n"); + goto free_login_buffer; + } + + vhost->trace = kcalloc(IBMVFC_NUM_TRACE_ENTRIES, + sizeof(struct ibmvfc_trace_entry), GFP_KERNEL); + + if (!vhost->trace) + goto free_disc_buffer; + + vhost->tgt_pool = mempool_create_kzalloc_pool(IBMVFC_TGT_MEMPOOL_SZ, + sizeof(struct ibmvfc_target)); + + if (!vhost->tgt_pool) { + dev_err(dev, "Couldn't allocate target memory pool\n"); + goto free_trace; + } + + LEAVE; + return 0; + +free_trace: + kfree(vhost->trace); +free_disc_buffer: + dma_free_coherent(dev, vhost->disc_buf_sz, vhost->disc_buf, + vhost->disc_buf_dma); +free_login_buffer: + dma_free_coherent(dev, sizeof(*vhost->login_buf), + vhost->login_buf, vhost->login_buf_dma); +free_sg_pool: + dma_pool_destroy(vhost->sg_pool); +unmap_async_crq: + dma_unmap_single(dev, async_q->msg_token, + async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL); +free_async_crq: + free_page((unsigned long)async_q->msgs); +nomem: + LEAVE; + return -ENOMEM; +} + +/** + * ibmvfc_probe - Adapter hot plug add entry point + * @vdev: vio device struct + * @id: vio device id struct + * + * Return value: + * 0 on success / non-zero on failure + **/ +static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id) +{ + struct ibmvfc_host *vhost; + struct Scsi_Host *shost; + struct device *dev = &vdev->dev; + int rc = -ENOMEM; + + ENTER; + shost = scsi_host_alloc(&driver_template, sizeof(*vhost)); + if (!shost) { + dev_err(dev, "Couldn't allocate host data\n"); + goto out; + } + + shost->transportt = ibmvfc_transport_template; + shost->can_queue = max_requests; + shost->max_lun = max_lun; + shost->max_id = max_targets; + shost->max_sectors = IBMVFC_MAX_SECTORS; + shost->max_cmd_len = IBMVFC_MAX_CDB_LEN; + shost->unique_id = shost->host_no; + + vhost = shost_priv(shost); + INIT_LIST_HEAD(&vhost->sent); + INIT_LIST_HEAD(&vhost->free); + INIT_LIST_HEAD(&vhost->targets); + sprintf(vhost->name, IBMVFC_NAME); + vhost->host = shost; + vhost->dev = dev; + vhost->partition_number = -1; + vhost->log_level = log_level; + strcpy(vhost->partition_name, "UNKNOWN"); + init_waitqueue_head(&vhost->work_wait_q); + init_waitqueue_head(&vhost->init_wait_q); + + if ((rc = ibmvfc_alloc_mem(vhost))) + goto free_scsi_host; + + vhost->work_thread = kthread_run(ibmvfc_work, vhost, "%s_%d", IBMVFC_NAME, + shost->host_no); + + if (IS_ERR(vhost->work_thread)) { + dev_err(dev, "Couldn't create kernel thread: %ld\n", + PTR_ERR(vhost->work_thread)); + goto free_host_mem; + } + + if ((rc = ibmvfc_init_crq(vhost))) { + dev_err(dev, "Couldn't initialize crq. rc=%d\n", rc); + goto kill_kthread; + } + + if ((rc = ibmvfc_init_event_pool(vhost))) { + dev_err(dev, "Couldn't initialize event pool. rc=%d\n", rc); + goto release_crq; + } + + if ((rc = scsi_add_host(shost, dev))) + goto release_event_pool; + + if ((rc = ibmvfc_create_trace_file(&shost->shost_dev.kobj, + &ibmvfc_trace_attr))) { + dev_err(dev, "Failed to create trace file. rc=%d\n", rc); + goto remove_shost; + } + + dev_set_drvdata(dev, vhost); + spin_lock(&ibmvfc_driver_lock); + list_add_tail(&vhost->queue, &ibmvfc_head); + spin_unlock(&ibmvfc_driver_lock); + + ibmvfc_send_crq_init(vhost); + scsi_scan_host(shost); + return 0; + +remove_shost: + scsi_remove_host(shost); +release_event_pool: + ibmvfc_free_event_pool(vhost); +release_crq: + ibmvfc_release_crq_queue(vhost); +kill_kthread: + kthread_stop(vhost->work_thread); +free_host_mem: + ibmvfc_free_mem(vhost); +free_scsi_host: + scsi_host_put(shost); +out: + LEAVE; + return rc; +} + +/** + * ibmvfc_remove - Adapter hot plug remove entry point + * @vdev: vio device struct + * + * Return value: + * 0 + **/ +static int ibmvfc_remove(struct vio_dev *vdev) +{ + struct ibmvfc_host *vhost = dev_get_drvdata(&vdev->dev); + unsigned long flags; + + ENTER; + ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); + kthread_stop(vhost->work_thread); + fc_remove_host(vhost->host); + scsi_remove_host(vhost->host); + ibmvfc_release_crq_queue(vhost); + + spin_lock_irqsave(vhost->host->host_lock, flags); + ibmvfc_purge_requests(vhost, DID_ERROR); + ibmvfc_free_event_pool(vhost); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + + ibmvfc_free_mem(vhost); + spin_lock(&ibmvfc_driver_lock); + list_del(&vhost->queue); + spin_unlock(&ibmvfc_driver_lock); + scsi_host_put(vhost->host); + LEAVE; + return 0; +} + +static struct vio_device_id ibmvfc_device_table[] __devinitdata = { + {"fcp", "IBM,vfc-client"}, + { "", "" } +}; +MODULE_DEVICE_TABLE(vio, ibmvfc_device_table); + +static struct vio_driver ibmvfc_driver = { + .id_table = ibmvfc_device_table, + .probe = ibmvfc_probe, + .remove = ibmvfc_remove, + .driver = { + .name = IBMVFC_NAME, + .owner = THIS_MODULE, + } +}; + +static struct fc_function_template ibmvfc_transport_functions = { + .show_host_fabric_name = 1, + .show_host_node_name = 1, + .show_host_port_name = 1, + .show_host_supported_classes = 1, + .show_host_port_type = 1, + .show_host_port_id = 1, + + .get_host_port_state = ibmvfc_get_host_port_state, + .show_host_port_state = 1, + + .get_host_speed = ibmvfc_get_host_speed, + .show_host_speed = 1, + + .issue_fc_host_lip = ibmvfc_issue_fc_host_lip, + .terminate_rport_io = ibmvfc_terminate_rport_io, + + .show_rport_maxframe_size = 1, + .show_rport_supported_classes = 1, + + .set_rport_dev_loss_tmo = ibmvfc_set_rport_dev_loss_tmo, + .show_rport_dev_loss_tmo = 1, + + .get_starget_node_name = ibmvfc_get_starget_node_name, + .show_starget_node_name = 1, + + .get_starget_port_name = ibmvfc_get_starget_port_name, + .show_starget_port_name = 1, + + .get_starget_port_id = ibmvfc_get_starget_port_id, + .show_starget_port_id = 1, +}; + +/** + * ibmvfc_module_init - Initialize the ibmvfc module + * + * Return value: + * 0 on success / other on failure + **/ +static int __init ibmvfc_module_init(void) +{ + int rc; + + if (!firmware_has_feature(FW_FEATURE_VIO)) + return -ENODEV; + + printk(KERN_INFO IBMVFC_NAME": IBM Virtual Fibre Channel Driver version: %s %s\n", + IBMVFC_DRIVER_VERSION, IBMVFC_DRIVER_DATE); + + ibmvfc_transport_template = fc_attach_transport(&ibmvfc_transport_functions); + if (!ibmvfc_transport_template) + return -ENOMEM; + + rc = vio_register_driver(&ibmvfc_driver); + if (rc) + fc_release_transport(ibmvfc_transport_template); + return rc; +} + +/** + * ibmvfc_module_exit - Teardown the ibmvfc module + * + * Return value: + * nothing + **/ +static void __exit ibmvfc_module_exit(void) +{ + vio_unregister_driver(&ibmvfc_driver); + fc_release_transport(ibmvfc_transport_template); +} + +module_init(ibmvfc_module_init); +module_exit(ibmvfc_module_exit); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h new file mode 100644 index 0000000..057f3c0 --- /dev/null +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -0,0 +1,682 @@ +/* + * ibmvfc.h -- driver for IBM Power Virtual Fibre Channel Adapter + * + * Written By: Brian King , IBM Corporation + * + * Copyright (C) IBM Corporation, 2008 + * + * 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 _IBMVFC_H +#define _IBMVFC_H + +#include +#include +#include "viosrp.h" + +#define IBMVFC_NAME "ibmvfc" +#define IBMVFC_DRIVER_VERSION "1.0.0" +#define IBMVFC_DRIVER_DATE "(July 1, 2008)" + +#define IBMVFC_DEFAULT_TIMEOUT 15 +#define IBMVFC_INIT_TIMEOUT 30 +#define IBMVFC_MAX_REQUESTS_DEFAULT 100 + +#define IBMVFC_DEBUG 0 +#define IBMVFC_MAX_TARGETS 1024 +#define IBMVFC_MAX_LUN 0xffffffff +#define IBMVFC_MAX_SECTORS 0xffffu +#define IBMVFC_MAX_DISC_THREADS 4 +#define IBMVFC_TGT_MEMPOOL_SZ 64 +#define IBMVFC_MAX_CMDS_PER_LUN 64 +#define IBMVFC_MAX_INIT_RETRIES 3 +#define IBMVFC_DEV_LOSS_TMO (5 * 60) +#define IBMVFC_DEFAULT_LOG_LEVEL 2 +#define IBMVFC_MAX_CDB_LEN 16 + +/* + * Ensure we have resources for ERP and initialization: + * 1 for ERP + * 1 for initialization + * 1 for each discovery thread + */ +#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + disc_threads) + +#define IBMVFC_MAD_SUCCESS 0x00 +#define IBMVFC_MAD_NOT_SUPPORTED 0xF1 +#define IBMVFC_MAD_FAILED 0xF7 +#define IBMVFC_MAD_DRIVER_FAILED 0xEE +#define IBMVFC_MAD_CRQ_ERROR 0xEF + +enum ibmvfc_crq_valid { + IBMVFC_CRQ_CMD_RSP = 0x80, + IBMVFC_CRQ_INIT_RSP = 0xC0, + IBMVFC_CRQ_XPORT_EVENT = 0xFF, +}; + +enum ibmvfc_crq_format { + IBMVFC_CRQ_INIT = 0x01, + IBMVFC_CRQ_INIT_COMPLETE = 0x02, + IBMVFC_PARTITION_MIGRATED = 0x06, +}; + +enum ibmvfc_cmd_status_flags { + IBMVFC_FABRIC_MAPPED = 0x0001, + IBMVFC_VIOS_FAILURE = 0x0002, + IBMVFC_FC_FAILURE = 0x0004, + IBMVFC_FC_SCSI_ERROR = 0x0008, + IBMVFC_HW_EVENT_LOGGED = 0x0010, + IBMVFC_VIOS_LOGGED = 0x0020, +}; + +enum ibmvfc_fabric_mapped_errors { + IBMVFC_UNABLE_TO_ESTABLISH = 0x0001, + IBMVFC_XPORT_FAULT = 0x0002, + IBMVFC_CMD_TIMEOUT = 0x0003, + IBMVFC_ENETDOWN = 0x0004, + IBMVFC_HW_FAILURE = 0x0005, + IBMVFC_LINK_DOWN_ERR = 0x0006, + IBMVFC_LINK_DEAD_ERR = 0x0007, + IBMVFC_UNABLE_TO_REGISTER = 0x0008, + IBMVFC_XPORT_BUSY = 0x000A, + IBMVFC_XPORT_DEAD = 0x000B, + IBMVFC_CONFIG_ERROR = 0x000C, + IBMVFC_NAME_SERVER_FAIL = 0x000D, + IBMVFC_LINK_HALTED = 0x000E, + IBMVFC_XPORT_GENERAL = 0x8000, +}; + +enum ibmvfc_vios_errors { + IBMVFC_CRQ_FAILURE = 0x0001, + IBMVFC_SW_FAILURE = 0x0002, + IBMVFC_INVALID_PARAMETER = 0x0003, + IBMVFC_MISSING_PARAMETER = 0x0004, + IBMVFC_HOST_IO_BUS = 0x0005, + IBMVFC_TRANS_CANCELLED = 0x0006, + IBMVFC_TRANS_CANCELLED_IMPLICIT = 0x0007, + IBMVFC_INSUFFICIENT_RESOURCE = 0x0008, + IBMVFC_COMMAND_FAILED = 0x8000, +}; + +enum ibmvfc_mad_types { + IBMVFC_NPIV_LOGIN = 0x0001, + IBMVFC_DISC_TARGETS = 0x0002, + IBMVFC_PORT_LOGIN = 0x0004, + IBMVFC_PROCESS_LOGIN = 0x0008, + IBMVFC_QUERY_TARGET = 0x0010, + IBMVFC_IMPLICIT_LOGOUT = 0x0040, + IBMVFC_TMF_MAD = 0x0100, +}; + +struct ibmvfc_mad_common { + u32 version; + u32 reserved; + u32 opcode; + u16 status; + u16 length; + u64 tag; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_npiv_login_mad { + struct ibmvfc_mad_common common; + struct srp_direct_buf buffer; +}__attribute__((packed, aligned (8))); + +#define IBMVFC_MAX_NAME 256 + +struct ibmvfc_npiv_login { + u32 ostype; +#define IBMVFC_OS_LINUX 0x02 + u32 pad; + u64 max_dma_len; + u32 max_payload; + u32 max_response; + u32 partition_num; + u32 vfc_frame_version; + u16 fcp_version; + u16 flags; +#define IBMVFC_CLIENT_MIGRATED 0x01 +#define IBMVFC_FLUSH_ON_HALT 0x02 + u32 max_cmds; + u64 capabilities; +#define IBMVFC_CAN_MIGRATE 0x01 + u64 node_name; + struct srp_direct_buf async; + u8 partition_name[IBMVFC_MAX_NAME]; + u8 device_name[IBMVFC_MAX_NAME]; + u8 drc_name[IBMVFC_MAX_NAME]; + u64 reserved2[2]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_common_svc_parms { + u16 fcph_version; + u16 b2b_credit; + u16 features; + u16 bb_rcv_sz; /* upper nibble is BB_SC_N */ + u32 ratov; + u32 edtov; +}__attribute__((packed, aligned (4))); + +struct ibmvfc_service_parms { + struct ibmvfc_common_svc_parms common; + u8 port_name[8]; + u8 node_name[8]; + u32 class1_parms[4]; + u32 class2_parms[4]; + u32 class3_parms[4]; + u32 obsolete[4]; + u32 vendor_version[4]; + u32 services_avail[2]; + u32 ext_len; + u32 reserved[30]; + u32 clk_sync_qos[2]; +}__attribute__((packed, aligned (4))); + +struct ibmvfc_npiv_login_resp { + u32 version; + u16 status; + u16 error; + u32 flags; +#define IBMVFC_NATIVE_FC 0x01 +#define IBMVFC_CAN_FLUSH_ON_HALT 0x08 + u32 reserved; + u64 capabilites; + u32 max_cmds; + u32 scsi_id_sz; + u64 max_dma_len; + u64 scsi_id; + u64 port_name; + u64 node_name; + u64 link_speed; + u8 partition_name[IBMVFC_MAX_NAME]; + u8 device_name[IBMVFC_MAX_NAME]; + u8 port_loc_code[IBMVFC_MAX_NAME]; + u8 drc_name[IBMVFC_MAX_NAME]; + struct ibmvfc_service_parms service_parms; + u64 reserved2; +}__attribute__((packed, aligned (8))); + +union ibmvfc_npiv_login_data { + struct ibmvfc_npiv_login login; + struct ibmvfc_npiv_login_resp resp; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_discover_targets_buf { + u32 scsi_id[1]; +#define IBMVFC_DISC_TGT_SCSI_ID_MASK 0x00ffffff +}; + +struct ibmvfc_discover_targets { + struct ibmvfc_mad_common common; + struct srp_direct_buf buffer; + u32 flags; + u16 status; + u16 error; + u32 bufflen; + u32 num_avail; + u32 num_written; + u64 reserved[2]; +}__attribute__((packed, aligned (8))); + +enum ibmvfc_fc_reason { + IBMVFC_INVALID_ELS_CMD_CODE = 0x01, + IBMVFC_INVALID_VERSION = 0x02, + IBMVFC_LOGICAL_ERROR = 0x03, + IBMVFC_INVALID_CT_IU_SIZE = 0x04, + IBMVFC_LOGICAL_BUSY = 0x05, + IBMVFC_PROTOCOL_ERROR = 0x07, + IBMVFC_UNABLE_TO_PERFORM_REQ = 0x09, + IBMVFC_CMD_NOT_SUPPORTED = 0x0B, + IBMVFC_SERVER_NOT_AVAIL = 0x0D, + IBMVFC_CMD_IN_PROGRESS = 0x0E, + IBMVFC_VENDOR_SPECIFIC = 0xFF, +}; + +enum ibmvfc_fc_type { + IBMVFC_FABRIC_REJECT = 0x01, + IBMVFC_PORT_REJECT = 0x02, + IBMVFC_LS_REJECT = 0x03, + IBMVFC_FABRIC_BUSY = 0x04, + IBMVFC_PORT_BUSY = 0x05, + IBMVFC_BASIC_REJECT = 0x06, +}; + +enum ibmvfc_gs_explain { + IBMVFC_PORT_NAME_NOT_REG = 0x02, +}; + +struct ibmvfc_port_login { + struct ibmvfc_mad_common common; + u64 scsi_id; + u16 reserved; + u16 fc_service_class; + u32 blksz; + u32 hdr_per_blk; + u16 status; + u16 error; /* also fc_reason */ + u16 fc_explain; + u16 fc_type; + u32 reserved2; + struct ibmvfc_service_parms service_parms; + struct ibmvfc_service_parms service_parms_change; + u64 reserved3[2]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_prli_svc_parms { + u8 type; +#define IBMVFC_SCSI_FCP_TYPE 0x08 + u8 type_ext; + u16 flags; +#define IBMVFC_PRLI_ORIG_PA_VALID 0x8000 +#define IBMVFC_PRLI_RESP_PA_VALID 0x4000 +#define IBMVFC_PRLI_EST_IMG_PAIR 0x2000 + u32 orig_pa; + u32 resp_pa; + u32 service_parms; +#define IBMVFC_PRLI_TASK_RETRY 0x00000200 +#define IBMVFC_PRLI_RETRY 0x00000100 +#define IBMVFC_PRLI_DATA_OVERLAY 0x00000040 +#define IBMVFC_PRLI_INITIATOR_FUNC 0x00000020 +#define IBMVFC_PRLI_TARGET_FUNC 0x00000010 +#define IBMVFC_PRLI_READ_FCP_XFER_RDY_DISABLED 0x00000002 +#define IBMVFC_PRLI_WR_FCP_XFER_RDY_DISABLED 0x00000001 +}__attribute__((packed, aligned (4))); + +struct ibmvfc_process_login { + struct ibmvfc_mad_common common; + u64 scsi_id; + struct ibmvfc_prli_svc_parms parms; + u8 reserved[48]; + u16 status; + u16 error; /* also fc_reason */ + u32 reserved2; + u64 reserved3[2]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_query_tgt { + struct ibmvfc_mad_common common; + u64 wwpn; + u64 scsi_id; + u16 status; + u16 error; + u16 fc_explain; + u16 fc_type; + u64 reserved[2]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_implicit_logout { + struct ibmvfc_mad_common common; + u64 old_scsi_id; + u64 reserved[2]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_tmf { + struct ibmvfc_mad_common common; + u64 scsi_id; + struct scsi_lun lun; + u32 flags; +#define IBMVFC_TMF_ABORT_TASK 0x02 +#define IBMVFC_TMF_ABORT_TASK_SET 0x04 +#define IBMVFC_TMF_LUN_RESET 0x10 +#define IBMVFC_TMF_TGT_RESET 0x20 +#define IBMVFC_TMF_LUA_VALID 0x40 + u32 cancel_key; + u32 my_cancel_key; +#define IBMVFC_TMF_CANCEL_KEY 0x80000000 + u32 pad; + u64 reserved[2]; +}__attribute__((packed, aligned (8))); + +enum ibmvfc_fcp_rsp_info_codes { + RSP_NO_FAILURE = 0x00, + RSP_TMF_REJECTED = 0x04, + RSP_TMF_FAILED = 0x05, + RSP_TMF_INVALID_LUN = 0x09, +}; + +struct ibmvfc_fcp_rsp_info { + u16 reserved; + u8 rsp_code; + u8 reserved2[4]; +}__attribute__((packed, aligned (2))); + +enum ibmvfc_fcp_rsp_flags { + FCP_BIDI_RSP = 0x80, + FCP_BIDI_READ_RESID_UNDER = 0x40, + FCP_BIDI_READ_RESID_OVER = 0x20, + FCP_CONF_REQ = 0x10, + FCP_RESID_UNDER = 0x08, + FCP_RESID_OVER = 0x04, + FCP_SNS_LEN_VALID = 0x02, + FCP_RSP_LEN_VALID = 0x01, +}; + +union ibmvfc_fcp_rsp_data { + struct ibmvfc_fcp_rsp_info info; + u8 sense[SCSI_SENSE_BUFFERSIZE + sizeof(struct ibmvfc_fcp_rsp_info)]; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_fcp_rsp { + u64 reserved; + u16 retry_delay_timer; + u8 flags; + u8 scsi_status; + u32 fcp_resid; + u32 fcp_sense_len; + u32 fcp_rsp_len; + union ibmvfc_fcp_rsp_data data; +}__attribute__((packed, aligned (8))); + +enum ibmvfc_cmd_flags { + IBMVFC_SCATTERLIST = 0x0001, + IBMVFC_NO_MEM_DESC = 0x0002, + IBMVFC_READ = 0x0004, + IBMVFC_WRITE = 0x0008, + IBMVFC_TMF = 0x0080, + IBMVFC_CLASS_3_ERR = 0x0100, +}; + +enum ibmvfc_fc_task_attr { + IBMVFC_SIMPLE_TASK = 0x00, + IBMVFC_HEAD_OF_QUEUE = 0x01, + IBMVFC_ORDERED_TASK = 0x02, + IBMVFC_ACA_TASK = 0x04, +}; + +enum ibmvfc_fc_tmf_flags { + IBMVFC_ABORT_TASK_SET = 0x02, + IBMVFC_LUN_RESET = 0x10, + IBMVFC_TARGET_RESET = 0x20, +}; + +struct ibmvfc_fcp_cmd_iu { + struct scsi_lun lun; + u8 crn; + u8 pri_task_attr; + u8 tmf_flags; + u8 add_cdb_len; +#define IBMVFC_RDDATA 0x02 +#define IBMVFC_WRDATA 0x01 + u8 cdb[IBMVFC_MAX_CDB_LEN]; + u32 xfer_len; +}__attribute__((packed, aligned (4))); + +struct ibmvfc_cmd { + u64 task_tag; + u32 frame_type; + u32 payload_len; + u32 resp_len; + u32 adapter_resid; + u16 status; + u16 error; + u16 flags; + u16 response_flags; +#define IBMVFC_ADAPTER_RESID_VALID 0x01 + u32 cancel_key; + u32 exchange_id; + struct srp_direct_buf ext_func; + struct srp_direct_buf ioba; + struct srp_direct_buf resp; + u64 correlation; + u64 tgt_scsi_id; + u64 tag; + u64 reserved3[2]; + struct ibmvfc_fcp_cmd_iu iu; + struct ibmvfc_fcp_rsp rsp; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_trace_start_entry { + u32 xfer_len; +}__attribute__((packed)); + +struct ibmvfc_trace_end_entry { + u16 status; + u16 error; + u8 fcp_rsp_flags; + u8 rsp_code; + u8 scsi_status; + u8 reserved; +}__attribute__((packed)); + +struct ibmvfc_trace_entry { + struct ibmvfc_event *evt; + u32 time; + u32 scsi_id; + u32 lun; + u8 fmt; + u8 op_code; + u8 tmf_flags; + u8 type; +#define IBMVFC_TRC_START 0x00 +#define IBMVFC_TRC_END 0xff + union { + struct ibmvfc_trace_start_entry start; + struct ibmvfc_trace_end_entry end; + } u; +}__attribute__((packed, aligned (8))); + +enum ibmvfc_crq_formats { + IBMVFC_CMD_FORMAT = 0x01, + IBMVFC_ASYNC_EVENT = 0x02, + IBMVFC_MAD_FORMAT = 0x04, +}; + +enum ibmvfc_async_event { + IBMVFC_AE_ELS_PLOGI = 0x0001, + IBMVFC_AE_ELS_LOGO = 0x0002, + IBMVFC_AE_ELS_PRLO = 0x0004, + IBMVFC_AE_SCN_NPORT = 0x0008, + IBMVFC_AE_SCN_GROUP = 0x0010, + IBMVFC_AE_SCN_DOMAIN = 0x0020, + IBMVFC_AE_SCN_FABRIC = 0x0040, + IBMVFC_AE_LINK_UP = 0x0080, + IBMVFC_AE_LINK_DOWN = 0x0100, + IBMVFC_AE_LINK_DEAD = 0x0200, + IBMVFC_AE_HALT = 0x0400, + IBMVFC_AE_RESUME = 0x0800, + IBMVFC_AE_ADAPTER_FAILED = 0x1000, +}; + +struct ibmvfc_crq { + u8 valid; + u8 format; + u8 reserved[6]; + u64 ioba; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_crq_queue { + struct ibmvfc_crq *msgs; + int size, cur; + dma_addr_t msg_token; +}; + +struct ibmvfc_async_crq { + u8 valid; + u8 pad[3]; + u32 pad2; + u64 event; + u64 scsi_id; + u64 wwpn; + u64 node_name; + u64 reserved; +}__attribute__((packed, aligned (8))); + +struct ibmvfc_async_crq_queue { + struct ibmvfc_async_crq *msgs; + int size, cur; + dma_addr_t msg_token; +}; + +union ibmvfc_iu { + struct ibmvfc_mad_common mad_common; + struct ibmvfc_npiv_login_mad npiv_login; + struct ibmvfc_discover_targets discover_targets; + struct ibmvfc_port_login plogi; + struct ibmvfc_process_login prli; + struct ibmvfc_query_tgt query_tgt; + struct ibmvfc_implicit_logout implicit_logout; + struct ibmvfc_tmf tmf; + struct ibmvfc_cmd cmd; +}__attribute__((packed, aligned (8))); + +enum ibmvfc_target_action { + IBMVFC_TGT_ACTION_NONE = 0, + IBMVFC_TGT_ACTION_INIT, + IBMVFC_TGT_ACTION_INIT_WAIT, + IBMVFC_TGT_ACTION_ADD_RPORT, + IBMVFC_TGT_ACTION_DEL_RPORT, +}; + +struct ibmvfc_target { + struct list_head queue; + struct ibmvfc_host *vhost; + u64 scsi_id; + u64 new_scsi_id; + struct fc_rport *rport; + int target_id; + enum ibmvfc_target_action action; + int need_login; + int init_retries; + struct ibmvfc_service_parms service_parms; + struct ibmvfc_service_parms service_parms_change; + struct fc_rport_identifiers ids; + void (*job_step) (struct ibmvfc_target *); + struct kref kref; +}; + +/* a unit of work for the hosting partition */ +struct ibmvfc_event { + struct list_head queue; + struct ibmvfc_host *vhost; + struct ibmvfc_target *tgt; + struct scsi_cmnd *cmnd; + atomic_t free; + union ibmvfc_iu *xfer_iu; + void (*done) (struct ibmvfc_event *); + struct ibmvfc_crq crq; + union ibmvfc_iu iu; + union ibmvfc_iu *sync_iu; + struct srp_direct_buf *ext_list; + dma_addr_t ext_list_token; + struct completion comp; + struct timer_list timer; +}; + +/* a pool of event structs for use */ +struct ibmvfc_event_pool { + struct ibmvfc_event *events; + u32 size; + union ibmvfc_iu *iu_storage; + dma_addr_t iu_token; +}; + +enum ibmvfc_host_action { + IBMVFC_HOST_ACTION_NONE = 0, + IBMVFC_HOST_ACTION_INIT, + IBMVFC_HOST_ACTION_INIT_WAIT, + IBMVFC_HOST_ACTION_QUERY, + IBMVFC_HOST_ACTION_QUERY_TGTS, + IBMVFC_HOST_ACTION_TGT_DEL, + IBMVFC_HOST_ACTION_ALLOC_TGTS, + IBMVFC_HOST_ACTION_TGT_INIT, + IBMVFC_HOST_ACTION_TGT_ADD, +}; + +enum ibmvfc_host_state { + IBMVFC_NO_CRQ = 0, + IBMVFC_INITIALIZING, + IBMVFC_ACTIVE, + IBMVFC_HALTED, + IBMVFC_LINK_DOWN, + IBMVFC_LINK_DEAD, + IBMVFC_HOST_OFFLINE, +}; + +struct ibmvfc_host { + char name[8]; + struct list_head queue; + struct Scsi_Host *host; + enum ibmvfc_host_state state; + enum ibmvfc_host_action action; +#define IBMVFC_NUM_TRACE_INDEX_BITS 8 +#define IBMVFC_NUM_TRACE_ENTRIES (1 << IBMVFC_NUM_TRACE_INDEX_BITS) +#define IBMVFC_TRACE_SIZE (sizeof(struct ibmvfc_trace_entry) * IBMVFC_NUM_TRACE_ENTRIES) + struct ibmvfc_trace_entry *trace; + u32 trace_index:IBMVFC_NUM_TRACE_INDEX_BITS; + int num_targets; + struct list_head targets; + struct list_head sent; + struct list_head free; + struct device *dev; + struct ibmvfc_event_pool pool; + struct dma_pool *sg_pool; + mempool_t *tgt_pool; + struct ibmvfc_crq_queue crq; + struct ibmvfc_async_crq_queue async_crq; + struct ibmvfc_npiv_login login_info; + union ibmvfc_npiv_login_data *login_buf; + dma_addr_t login_buf_dma; + int disc_buf_sz; + int log_level; + struct ibmvfc_discover_targets_buf *disc_buf; + int task_set; + int init_retries; + int discovery_threads; + int client_migrated; + int reinit; + int events_to_log; +#define IBMVFC_AE_LINKUP 0x0001 +#define IBMVFC_AE_LINKDOWN 0x0002 +#define IBMVFC_AE_RSCN 0x0004 + dma_addr_t disc_buf_dma; + unsigned int partition_number; + char partition_name[97]; + void (*job_step) (struct ibmvfc_host *); + struct task_struct *work_thread; + wait_queue_head_t init_wait_q; + wait_queue_head_t work_wait_q; +}; + +#define DBG_CMD(CMD) do { if (ibmvfc_debug) CMD; } while (0) + +#define tgt_dbg(t, fmt, ...) \ + DBG_CMD(dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)) + +#define tgt_err(t, fmt, ...) \ + dev_err((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) + +#define ibmvfc_dbg(vhost, ...) \ + DBG_CMD(dev_info((vhost)->dev, ##__VA_ARGS__)) + +#define ibmvfc_log(vhost, level, ...) \ + do { \ + if (level >= (vhost)->log_level) \ + dev_err((vhost)->dev, ##__VA_ARGS__); \ + } while (0) + +#define ENTER DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Entering %s\n", __FUNCTION__)) +#define LEAVE DBG_CMD(printk(KERN_INFO IBMVFC_NAME": Leaving %s\n", __FUNCTION__)) + +#ifdef CONFIG_SCSI_IBMVFC_TRACE +#define ibmvfc_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr) +#define ibmvfc_remove_trace_file(kobj, attr) sysfs_remove_bin_file(kobj, attr) +#else +#define ibmvfc_create_trace_file(kobj, attr) 0 +#define ibmvfc_remove_trace_file(kobj, attr) do { } while (0) +#endif + +#endif -- cgit v0.10.2 From c57a39a45a76bc8ecdd2c8a9bc7cf7be3ed73fe1 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:31 +0200 Subject: [SCSI] zfcp: wait until adapter is finished with ERP during auto-port In some situations the auto port attachment task is started before the ERP is finished. To prevent this unwanted situation we wait until the adapter is up and running before we start our work. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index aa2d9a6..34c9b20 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -520,6 +520,7 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) int ret, i; struct zfcp_gpn_ft *gpn_ft; + zfcp_erp_wait(adapter); /* wait until adapter is finished with ERP */ if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) return 0; -- cgit v0.10.2 From 3968ce800f45d8795ceb6f186c1efe420c98e1b0 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:32 +0200 Subject: [SCSI] zfcp: Fix error checking for ELS ADISC requests Correctly check the status for ELS ADISC requests. 0 means success. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 34c9b20..5d9367d 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -263,7 +263,7 @@ static void zfcp_fc_adisc_handler(unsigned long data) struct zfcp_port *port = adisc->els.port; struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc; - if (!adisc->els.status) { + if (adisc->els.status) { /* request rejected or timed out */ zfcp_erp_port_forced_reopen(port, 0, 63, NULL); goto out; -- cgit v0.10.2 From 7afe29f7dd6dccbe454d7fd6cd6a5a7f7bcbc530 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:33 +0200 Subject: [SCSI] zfcp: Adapter reopen for large number of unsolicited status When zfcp receives 16 unsolicited status messages, this could trigger an adapter reopen. In this case, first try to send a new status read, and only if this fails, go through the recovery. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 2bd80fd..bfcd1ba 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -550,15 +550,14 @@ static void zfcp_dummy_release(struct device *dev) int zfcp_status_read_refill(struct zfcp_adapter *adapter) { while (atomic_read(&adapter->stat_miss) > 0) - if (zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL)) + if (zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL)) { + if (atomic_read(&adapter->stat_miss) >= 16) { + zfcp_erp_adapter_reopen(adapter, 0, 103, NULL); + return 1; + } break; - else - atomic_dec(&adapter->stat_miss); - - if (ZFCP_STATUS_READS_RECOM <= atomic_read(&adapter->stat_miss)) { - zfcp_erp_adapter_reopen(adapter, 0, 103, NULL); - return 1; - } + } else + atomic_dec(&adapter->stat_miss); return 0; } diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 1e837d4..202f7e6 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -108,7 +108,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) #define ZFCP_QTCB_VERSION FSF_QTCB_CURRENT_VERSION /* ATTENTION: value must not be used by hardware */ #define FSF_QTCB_UNSOLICITED_STATUS 0x6305 -#define ZFCP_STATUS_READS_RECOM FSF_STATUS_READS_RECOM /* Do 1st retry in 1 second, then double the timeout for each following retry */ #define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 1 @@ -743,7 +742,7 @@ struct zfcp_data { #define ZFCP_POOL_FSF_REQ_ERP_NR 1 #define ZFCP_POOL_FSF_REQ_SCSI_NR 1 #define ZFCP_POOL_FSF_REQ_ABORT_NR 1 -#define ZFCP_POOL_STATUS_READ_NR ZFCP_STATUS_READS_RECOM +#define ZFCP_POOL_STATUS_READ_NR FSF_STATUS_READS_RECOM #define ZFCP_POOL_DATA_GID_PN_NR 1 /* struct used by memory pools for fsf_requests */ -- cgit v0.10.2 From 5d4e226246331087799a01c267ec72e5931ff190 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:34 +0200 Subject: [SCSI] zfcp: Small QDIO cleanups QBUFF_PER_PAGE is only used inside the qdio module, so move it to zfcp_qdio.c zfcp_qdio_zero_sbals is now only used in the qdio module, so make it static. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 202f7e6..e8383b7 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -100,8 +100,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) #define ZFCP_TYPE2_RECOVERY_TIME 8 /* seconds */ -#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) - /********************* FSF SPECIFIC DEFINES *********************************/ #define ZFCP_ULP_INFO_VERSION 26 diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index c3b5133..368b304 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -43,7 +43,6 @@ extern void _zfcp_scan_ports_later(struct work_struct *work); /******************************* S/390 IO ************************************/ extern int zfcp_ccw_register(void); -extern void zfcp_qdio_zero_sbals(struct qdio_buffer **, int, int); extern int zfcp_qdio_allocate(struct zfcp_adapter *); extern void zfcp_qdio_free(struct zfcp_adapter *); extern int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req); diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index bd6561d..b8ed42b 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -11,6 +11,7 @@ /* FIXME(tune): free space should be one max. SBAL chain plus what? */ #define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ - (ZFCP_MAX_SBALS_PER_REQ + 4)) +#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) { @@ -63,6 +64,16 @@ static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id) ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL); } +static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) +{ + int i, sbal_idx; + + for (i = first; i < first + cnt; i++) { + sbal_idx = i % QDIO_MAX_BUFFERS_PER_Q; + memset(sbal[sbal_idx], 0, sizeof(struct qdio_buffer)); + } +} + static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int status, unsigned int qdio_err, unsigned int siga_err, unsigned int queue_no, int first, int count, @@ -366,22 +377,6 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) } /** - * zfcp_qdio_zero_sbals - zero all sbals of the specified area and queue - * @buf: pointer to array of SBALS - * @first: integer specifying the SBAL number to start - * @count: integer specifying the number of SBALS to process - */ -void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int count) -{ - int i, sbal_idx; - - for (i = first; i < first + count; i++) { - sbal_idx = i % QDIO_MAX_BUFFERS_PER_Q; - memset(sbal[sbal_idx], 0, sizeof(struct qdio_buffer)); - } -} - -/** * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data * @adapter: pointer to struct zfcp_adapter * Returns: -ENOMEM on memory allocation error or return value from -- cgit v0.10.2 From feac6a07c4a3578bffd6769bb4927e8a7e1f3ffe Mon Sep 17 00:00:00 2001 From: Martin Petermann Date: Wed, 2 Jul 2008 10:56:35 +0200 Subject: [SCSI] zfcp: Move status accessors from zfcp to SCSI include file. Move the accessor functions for the scsi_cmnd status from zfcp to the SCSI include file. Change the interface to the functions to pass the scsi_cmnd pointer instead of the status pointer. Signed-off-by: Martin Petermann Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 368b304..f95dc99 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -103,8 +103,6 @@ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t); extern char *zfcp_get_fcp_rsp_info_ptr(struct fcp_rsp_iu *); -extern void set_host_byte(int *, char); -extern void set_driver_byte(int *, char); extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); extern fcp_dl_t zfcp_get_fcp_dl(struct fcp_cmnd_iu *); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 243e792..150e78d 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3040,18 +3040,18 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) * DID_SOFT_ERROR by retrying the request for devices * that allow retries. */ - set_host_byte(&scpnt->result, DID_SOFT_ERROR); - set_driver_byte(&scpnt->result, SUGGEST_RETRY); + set_host_byte(scpnt, DID_SOFT_ERROR); + set_driver_byte(scpnt, SUGGEST_RETRY); goto skip_fsfstatus; } if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { - set_host_byte(&scpnt->result, DID_ERROR); + set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; } /* set message byte of result in SCSI command */ - scpnt->result |= COMMAND_COMPLETE << 8; + set_msg_byte(scpnt, COMMAND_COMPLETE); /* * copy SCSI status code of FCP_STATUS of FCP_RSP IU to status byte @@ -3067,23 +3067,23 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) switch (fcp_rsp_info[3]) { case RSP_CODE_GOOD: /* ok, continue */ - set_host_byte(&scpnt->result, DID_OK); + set_host_byte(scpnt, DID_OK); break; case RSP_CODE_LENGTH_MISMATCH: /* hardware bug */ - set_host_byte(&scpnt->result, DID_ERROR); + set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; case RSP_CODE_FIELD_INVALID: /* driver or hardware bug */ - set_host_byte(&scpnt->result, DID_ERROR); + set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; case RSP_CODE_RO_MISMATCH: /* hardware bug */ - set_host_byte(&scpnt->result, DID_ERROR); + set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; default: /* invalid FCP response code */ - set_host_byte(&scpnt->result, DID_ERROR); + set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; } } @@ -3104,7 +3104,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid); if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) < scpnt->underflow) - set_host_byte(&scpnt->result, DID_ERROR); + set_host_byte(scpnt, DID_ERROR); } skip_fsfstatus: diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 446fb1d..1603073 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -107,28 +107,6 @@ zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl) *zfcp_get_fcp_dl_ptr(fcp_cmd) = fcp_dl; } -/* - * note: it's a bit-or operation not an assignment - * regarding the specified byte - */ -static inline void -set_byte(int *result, char status, char pos) -{ - *result |= status << (pos * 8); -} - -void -set_host_byte(int *result, char status) -{ - set_byte(result, status, 2); -} - -void -set_driver_byte(int *result, char status) -{ - set_byte(result, status, 3); -} - static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) { @@ -196,7 +174,7 @@ zfcp_scsi_slave_configure(struct scsi_device *sdp) static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) { - set_host_byte(&scpnt->result, result); + set_host_byte(scpnt, result); if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) zfcp_scsi_dbf_event_result("fail", 4, (struct zfcp_adapter*) scpnt->device->host->hostdata[0], diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 2b5b935..00137a7 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -9,6 +9,7 @@ #define _SCSI_SCSI_H #include +#include /* * The maximum number of SG segments that we will put inside a @@ -425,6 +426,22 @@ struct scsi_lun { #define driver_byte(result) (((result) >> 24) & 0xff) #define suggestion(result) (driver_byte(result) & SUGGEST_MASK) +static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 8; +} + +static inline void set_host_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 16; +} + +static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) +{ + cmd->result |= status << 24; +} + + #define sense_class(sense) (((sense) >> 4) & 0x7) #define sense_error(sense) ((sense) & 0xf) #define sense_valid(sense) ((sense) & 0x80); -- cgit v0.10.2 From f76af7d7e36373179be7a9e09f6b0aae330549b7 Mon Sep 17 00:00:00 2001 From: Martin Petermann Date: Wed, 2 Jul 2008 10:56:36 +0200 Subject: [SCSI] zfcp: Cleanup of code in zfcp_scsi.c Cleanup code in zfcp_scsi.c, fix coding style issues and simplify the code. Signed-off-by: Martin Petermann Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 3e9f0ab..566627f 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -1065,8 +1065,7 @@ static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level, if (fsf_req != NULL) { fcp_rsp = (struct fcp_rsp_iu *) &(fsf_req->qtcb->bottom.io.fcp_rsp); - fcp_rsp_info = - zfcp_get_fcp_rsp_info_ptr(fcp_rsp); + fcp_rsp_info = (unsigned char *) &fcp_rsp[1]; fcp_sns_info = zfcp_get_fcp_sns_info_ptr(fcp_rsp); diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index e8383b7..7ac830c 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -126,12 +126,6 @@ typedef unsigned int fcp_dl_t; /* timeout for name-server lookup (in seconds) */ #define ZFCP_NS_GID_PN_TIMEOUT 10 -/* largest SCSI command we can process */ -/* FCP-2 (FCP_CMND IU) allows up to (255-3+16) */ -#define ZFCP_MAX_SCSI_CMND_LENGTH 255 -/* maximum number of commands in LUN queue (tagged queueing) */ -#define ZFCP_CMND_PER_LUN 32 - /* task attribute values in FCP-2 FCP_CMND IU */ #define SIMPLE_Q 0 #define HEAD_OF_Q 1 diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index f95dc99..892476c 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -102,13 +102,8 @@ extern void zfcp_test_link(struct zfcp_port *); extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t); -extern char *zfcp_get_fcp_rsp_info_ptr(struct fcp_rsp_iu *); extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); -extern fcp_dl_t zfcp_get_fcp_dl(struct fcp_cmnd_iu *); -extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *, - struct scsi_cmnd *, int); -extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, int); extern struct fc_function_template zfcp_transport_functions; /******************************** ERP ****************************************/ diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 150e78d..22e3aa6 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3027,7 +3027,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) &(fsf_req->qtcb->bottom.io.fcp_rsp); u32 sns_len; - char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); + char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; unsigned long flags; read_lock_irqsave(&fsf_req->adapter->abort_lock, flags); @@ -3145,7 +3145,7 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) int retval = 0; struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) &(fsf_req->qtcb->bottom.io.fcp_rsp); - char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); + char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 1603073..f8594a2 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -9,137 +9,32 @@ #include "zfcp_ext.h" #include -static void zfcp_scsi_slave_destroy(struct scsi_device *sdp); -static int zfcp_scsi_slave_alloc(struct scsi_device *sdp); -static int zfcp_scsi_slave_configure(struct scsi_device *sdp); -static int zfcp_scsi_queuecommand(struct scsi_cmnd *, - void (*done) (struct scsi_cmnd *)); -static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); -static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); -static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *); -static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); -static int zfcp_task_management_function(struct zfcp_unit *, u8, - struct scsi_cmnd *); - -static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, - unsigned int, unsigned int); - -static struct device_attribute *zfcp_sysfs_sdev_attrs[]; -static struct device_attribute *zfcp_a_stats_attrs[]; - -struct zfcp_data zfcp_data = { - .scsi_host_template = { - .name = "zfcp", - .module = THIS_MODULE, - .proc_name = "zfcp", - .slave_alloc = zfcp_scsi_slave_alloc, - .slave_configure = zfcp_scsi_slave_configure, - .slave_destroy = zfcp_scsi_slave_destroy, - .queuecommand = zfcp_scsi_queuecommand, - .eh_abort_handler = zfcp_scsi_eh_abort_handler, - .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, - .eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler, - .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, - .can_queue = 4096, - .this_id = -1, - .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ, - .cmd_per_lun = 1, - .use_clustering = 1, - .sdev_attrs = zfcp_sysfs_sdev_attrs, - .max_sectors = ZFCP_MAX_SECTORS, - .shost_attrs = zfcp_a_stats_attrs, - }, -}; - -/* Find start of Response Information in FCP response unit*/ -char * -zfcp_get_fcp_rsp_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu) -{ - char *fcp_rsp_info_ptr; - - fcp_rsp_info_ptr = - (unsigned char *) fcp_rsp_iu + (sizeof (struct fcp_rsp_iu)); - - return fcp_rsp_info_ptr; -} - /* Find start of Sense Information in FCP response unit*/ -char * -zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu) +char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu) { char *fcp_sns_info_ptr; - fcp_sns_info_ptr = - (unsigned char *) fcp_rsp_iu + (sizeof (struct fcp_rsp_iu)); + fcp_sns_info_ptr = (unsigned char *) &fcp_rsp_iu[1]; if (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid) - fcp_sns_info_ptr = (char *) fcp_sns_info_ptr + - fcp_rsp_iu->fcp_rsp_len; + fcp_sns_info_ptr += fcp_rsp_iu->fcp_rsp_len; return fcp_sns_info_ptr; } -static fcp_dl_t * -zfcp_get_fcp_dl_ptr(struct fcp_cmnd_iu * fcp_cmd) +void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl) { - int additional_length = fcp_cmd->add_fcp_cdb_length << 2; - fcp_dl_t *fcp_dl_addr; + fcp_dl_t *fcp_dl_ptr; - fcp_dl_addr = (fcp_dl_t *) - ((unsigned char *) fcp_cmd + - sizeof (struct fcp_cmnd_iu) + additional_length); /* * fcp_dl_addr = start address of fcp_cmnd structure + * size of fixed part + size of dynamically sized add_dcp_cdb field * SEE FCP-2 documentation */ - return fcp_dl_addr; -} - -fcp_dl_t -zfcp_get_fcp_dl(struct fcp_cmnd_iu * fcp_cmd) -{ - return *zfcp_get_fcp_dl_ptr(fcp_cmd); -} - -void -zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl) -{ - *zfcp_get_fcp_dl_ptr(fcp_cmd) = fcp_dl; -} - -static int -zfcp_scsi_slave_alloc(struct scsi_device *sdp) -{ - struct zfcp_adapter *adapter; - struct zfcp_unit *unit; - unsigned long flags; - int retval = -ENXIO; - - adapter = (struct zfcp_adapter *) sdp->host->hostdata[0]; - if (!adapter) - goto out; - - read_lock_irqsave(&zfcp_data.config_lock, flags); - unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun); - if (unit && atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED, - &unit->status)) { - sdp->hostdata = unit; - unit->device = sdp; - zfcp_unit_get(unit); - retval = 0; - } - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - out: - return retval; + fcp_dl_ptr = (fcp_dl_t *) ((unsigned char *) &fcp_cmd[1] + + (fcp_cmd->add_fcp_cdb_length << 2)); + *fcp_dl_ptr = fcp_dl; } -/** - * zfcp_scsi_slave_destroy - called when scsi device is removed - * - * Remove reference to associated scsi device for an zfcp_unit. - * Mark zfcp_unit as failed. The scsi device might be deleted via sysfs - * or a scan for this device might have failed. - */ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) { struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; @@ -153,26 +48,16 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) } } -/* - * called from scsi midlayer to allow finetuning of a device. - */ -static int -zfcp_scsi_slave_configure(struct scsi_device *sdp) +static int zfcp_scsi_slave_configure(struct scsi_device *sdp) { if (sdp->tagged_supported) - scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, ZFCP_CMND_PER_LUN); + scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, 32); else scsi_adjust_queue_depth(sdp, 0, 1); return 0; } -/** - * zfcp_scsi_command_fail - set result in scsi_cmnd and call scsi_done function - * @scpnt: pointer to struct scsi_cmnd where result is set - * @result: result to be set in scpnt (e.g. DID_ERROR) - */ -static void -zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) +static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) { set_host_byte(scpnt, result); if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) @@ -183,104 +68,13 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) scpnt->scsi_done(scpnt); } -/** - * zfcp_scsi_command_async - worker for zfcp_scsi_queuecommand and - * zfcp_scsi_command_sync - * @adapter: adapter where scsi command is issued - * @unit: unit to which scsi command is sent - * @scpnt: scsi command to be sent - * @timer: timer to be started if request is successfully initiated - * - * Note: In scsi_done function must be set in scpnt. - */ -int -zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, - struct scsi_cmnd *scpnt, int use_timer) -{ - int tmp; - int retval; - - retval = 0; - - BUG_ON((adapter == NULL) || (adapter != unit->port->adapter)); - BUG_ON(scpnt->scsi_done == NULL); - - if (unlikely(NULL == unit)) { - zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); - goto out; - } - - if (unlikely( - atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status) || - !atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status))) { - zfcp_scsi_command_fail(scpnt, DID_ERROR); - goto out; - } - - tmp = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, use_timer, - ZFCP_REQ_AUTO_CLEANUP); - if (unlikely(tmp == -EBUSY)) { - zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); - goto out; - } - - if (unlikely(tmp < 0)) - retval = SCSI_MLQUEUE_HOST_BUSY; - -out: - return retval; -} - -static void -zfcp_scsi_command_sync_handler(struct scsi_cmnd *scpnt) -{ - struct completion *wait = (struct completion *) scpnt->SCp.ptr; - complete(wait); -} - - -/** - * zfcp_scsi_command_sync - send a SCSI command and wait for completion - * @unit: unit where command is sent to - * @scpnt: scsi command to be sent - * @use_timer: indicates whether timer should be setup or not - * Return: 0 - * - * Errors are indicated in scpnt->result - */ -int -zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt, - int use_timer) -{ - int ret; - DECLARE_COMPLETION_ONSTACK(wait); - - scpnt->SCp.ptr = (void *) &wait; /* silent re-use */ - scpnt->scsi_done = zfcp_scsi_command_sync_handler; - ret = zfcp_scsi_command_async(unit->port->adapter, unit, scpnt, - use_timer); - if (ret == 0) - wait_for_completion(&wait); - - scpnt->SCp.ptr = NULL; - - return 0; -} - -/* - * function: zfcp_scsi_queuecommand - * - * purpose: enqueues a SCSI command to the specified target device - * - * returns: 0 - success, SCSI command enqueued - * !0 - failure - */ -static int -zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, - void (*done) (struct scsi_cmnd *)) +static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, + void (*done) (struct scsi_cmnd *)) { struct zfcp_unit *unit; struct zfcp_adapter *adapter; + int status; + int ret; /* reset the status for this request */ scpnt->result = 0; @@ -292,44 +86,76 @@ zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, * (stored there by zfcp_scsi_slave_alloc) */ adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0]; - unit = (struct zfcp_unit *) scpnt->device->hostdata; + unit = scpnt->device->hostdata; + + BUG_ON(!adapter || (adapter != unit->port->adapter)); + BUG_ON(!scpnt->scsi_done); + + if (unlikely(!unit)) { + zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); + return 0; + } + + status = atomic_read(&unit->status); + if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) || + !(status & ZFCP_STATUS_COMMON_RUNNING))) { + zfcp_scsi_command_fail(scpnt, DID_ERROR); + return 0;; + } + + ret = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, 0, + ZFCP_REQ_AUTO_CLEANUP); + if (unlikely(ret == -EBUSY)) + zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); + else if (unlikely(ret < 0)) + return SCSI_MLQUEUE_HOST_BUSY; - return zfcp_scsi_command_async(adapter, unit, scpnt, 0); + return ret; } -static struct zfcp_unit * -zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id, - unsigned int lun) +static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, + int channel, unsigned int id, + unsigned int lun) { struct zfcp_port *port; - struct zfcp_unit *unit, *retval = NULL; + struct zfcp_unit *unit; list_for_each_entry(port, &adapter->port_list_head, list) { if (!port->rport || (id != port->rport->scsi_target_id)) continue; list_for_each_entry(unit, &port->unit_list_head, list) - if (lun == unit->scsi_lun) { - retval = unit; - goto out; - } + if (lun == unit->scsi_lun) + return unit; } - out: + + return NULL; +} + +static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) +{ + struct zfcp_adapter *adapter; + struct zfcp_unit *unit; + unsigned long flags; + int retval = -ENXIO; + + adapter = (struct zfcp_adapter *) sdp->host->hostdata[0]; + if (!adapter) + goto out; + + read_lock_irqsave(&zfcp_data.config_lock, flags); + unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun); + if (unit && + (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_REGISTERED)) { + sdp->hostdata = unit; + unit->device = sdp; + zfcp_unit_get(unit); + retval = 0; + } + read_unlock_irqrestore(&zfcp_data.config_lock, flags); +out: return retval; } -/** - * zfcp_scsi_eh_abort_handler - abort the specified SCSI command - * @scpnt: pointer to scsi_cmnd to be aborted - * Return: SUCCESS - command has been aborted and cleaned up in internal - * bookkeeping, SCSI stack won't be called for aborted command - * FAILED - otherwise - * - * We do not need to care for a SCSI command which completes normally - * but late during this abort routine runs. We are allowed to return - * late commands to the SCSI stack. It tracks the state of commands and - * will handle late commands. (Usually, the normal completion of late - * commands is ignored with respect to the running abort operation.) - */ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) { struct Scsi_Host *scsi_host; @@ -337,30 +163,27 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) struct zfcp_unit *unit; struct zfcp_fsf_req *fsf_req; unsigned long flags; - unsigned long old_req_id; + unsigned long old_req_id = (unsigned long) scpnt->host_scribble; int retval = SUCCESS; scsi_host = scpnt->device->host; adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; - unit = (struct zfcp_unit *) scpnt->device->hostdata; + unit = scpnt->device->hostdata; /* avoid race condition between late normal completion and abort */ write_lock_irqsave(&adapter->abort_lock, flags); /* Check whether corresponding fsf_req is still pending */ spin_lock(&adapter->req_list_lock); - fsf_req = zfcp_reqlist_find(adapter, - (unsigned long) scpnt->host_scribble); + fsf_req = zfcp_reqlist_find(adapter, old_req_id); spin_unlock(&adapter->req_list_lock); if (!fsf_req) { write_unlock_irqrestore(&adapter->abort_lock, flags); zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0); - retval = SUCCESS; - goto out; + return retval; } fsf_req->data = 0; fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING; - old_req_id = fsf_req->req_id; /* don't access old fsf_req after releasing the abort_lock */ write_unlock_irqrestore(&adapter->abort_lock, flags); @@ -370,7 +193,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, old_req_id); retval = FAILED; - goto out; + return retval; } __wait_event(fsf_req->completion_wq, @@ -378,62 +201,30 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, fsf_req, 0); - retval = SUCCESS; } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, fsf_req, 0); - retval = SUCCESS; } else { zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, fsf_req, 0); retval = FAILED; } zfcp_fsf_req_free(fsf_req); - out: - return retval; -} - -static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) -{ - int retval; - struct zfcp_unit *unit = scpnt->device->hostdata; - if (!unit) { - WARN_ON(1); - return SUCCESS; - } - retval = zfcp_task_management_function(unit, - FCP_LOGICAL_UNIT_RESET, - scpnt); - return retval ? FAILED : SUCCESS; -} - -static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) -{ - int retval; - struct zfcp_unit *unit = scpnt->device->hostdata; - - if (!unit) { - WARN_ON(1); - return SUCCESS; - } - retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt); - return retval ? FAILED : SUCCESS; + return retval; } -static int -zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags, - struct scsi_cmnd *scpnt) +static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags, + struct scsi_cmnd *scpnt) { struct zfcp_adapter *adapter = unit->port->adapter; struct zfcp_fsf_req *fsf_req; - int retval = 0; + int retval = SUCCESS; /* issue task management function */ fsf_req = zfcp_fsf_send_fcp_command_task_management (adapter, unit, tm_flags, 0); if (!fsf_req) { zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt); - retval = -ENOMEM; - goto out; + return FAILED; } __wait_event(fsf_req->completion_wq, @@ -444,27 +235,46 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags, */ if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt); - retval = -EIO; + retval = FAILED; } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) { zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt); - retval = -ENOTSUPP; + retval = FAILED; } else zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt); zfcp_fsf_req_free(fsf_req); - out: + return retval; } -/** - * zfcp_scsi_eh_host_reset_handler - handler for host reset - */ +static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) +{ + struct zfcp_unit *unit = scpnt->device->hostdata; + + if (!unit) { + WARN_ON(1); + return SUCCESS; + } + return zfcp_task_mgmt_function(unit, FCP_LOGICAL_UNIT_RESET, scpnt); +} + +static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) +{ + struct zfcp_unit *unit = scpnt->device->hostdata; + + if (!unit) { + WARN_ON(1); + return SUCCESS; + } + return zfcp_task_mgmt_function(unit, FCP_TARGET_RESET, scpnt); +} + static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) { struct zfcp_unit *unit; struct zfcp_adapter *adapter; - unit = (struct zfcp_unit*) scpnt->device->hostdata; + unit = scpnt->device->hostdata; adapter = unit->port->adapter; zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt); zfcp_erp_wait(adapter); @@ -472,51 +282,43 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) return SUCCESS; } -int -zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) +int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) { - int retval = 0; - static unsigned int unique_id = 0; + struct ccw_dev_id dev_id; if (adapter->scsi_host) - goto out; + return 0; + ccw_device_get_id(adapter->ccw_device, &dev_id); /* register adapter as SCSI host with mid layer of SCSI stack */ adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template, sizeof (struct zfcp_adapter *)); if (!adapter->scsi_host) { dev_err(&adapter->ccw_device->dev, "registration with SCSI stack failed."); - retval = -EIO; - goto out; + return -EIO; } /* tell the SCSI stack some characteristics of this adapter */ adapter->scsi_host->max_id = 1; adapter->scsi_host->max_lun = 1; adapter->scsi_host->max_channel = 0; - adapter->scsi_host->unique_id = unique_id++; /* FIXME */ - adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH; + adapter->scsi_host->unique_id = dev_id.devno; + adapter->scsi_host->max_cmd_len = 255; adapter->scsi_host->transportt = zfcp_data.scsi_transport_template; - /* - * save a pointer to our own adapter data structure within - * hostdata field of SCSI host data structure - */ adapter->scsi_host->hostdata[0] = (unsigned long) adapter; if (scsi_add_host(adapter->scsi_host, &adapter->ccw_device->dev)) { scsi_host_put(adapter->scsi_host); - retval = -EIO; - goto out; + return -EIO; } atomic_set_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status); - out: - return retval; + + return 0; } -void -zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) +void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) { struct Scsi_Host *shost; struct zfcp_port *port; @@ -524,10 +326,12 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) shost = adapter->scsi_host; if (!shost) return; + read_lock_irq(&zfcp_data.config_lock); list_for_each_entry(port, &adapter->port_list_head, list) if (port->rport) port->rport = NULL; + read_unlock_irq(&zfcp_data.config_lock); fc_remove_host(shost); scsi_remove_host(shost); @@ -538,9 +342,6 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) return; } -/* - * Support functions for FC transport class - */ static struct fc_host_statistics* zfcp_init_fc_host_stats(struct zfcp_adapter *adapter) { @@ -556,13 +357,12 @@ zfcp_init_fc_host_stats(struct zfcp_adapter *adapter) return adapter->fc_stats; } -static void -zfcp_adjust_fc_host_stats(struct fc_host_statistics *fc_stats, - struct fsf_qtcb_bottom_port *data, - struct fsf_qtcb_bottom_port *old) +static void zfcp_adjust_fc_host_stats(struct fc_host_statistics *fc_stats, + struct fsf_qtcb_bottom_port *data, + struct fsf_qtcb_bottom_port *old) { - fc_stats->seconds_since_last_reset = data->seconds_since_last_reset - - old->seconds_since_last_reset; + fc_stats->seconds_since_last_reset = + data->seconds_since_last_reset - old->seconds_since_last_reset; fc_stats->tx_frames = data->tx_frames - old->tx_frames; fc_stats->tx_words = data->tx_words - old->tx_words; fc_stats->rx_frames = data->rx_frames - old->rx_frames; @@ -573,26 +373,25 @@ zfcp_adjust_fc_host_stats(struct fc_host_statistics *fc_stats, fc_stats->dumped_frames = data->dumped_frames - old->dumped_frames; fc_stats->link_failure_count = data->link_failure - old->link_failure; fc_stats->loss_of_sync_count = data->loss_of_sync - old->loss_of_sync; - fc_stats->loss_of_signal_count = data->loss_of_signal - - old->loss_of_signal; - fc_stats->prim_seq_protocol_err_count = data->psp_error_counts - - old->psp_error_counts; - fc_stats->invalid_tx_word_count = data->invalid_tx_words - - old->invalid_tx_words; + fc_stats->loss_of_signal_count = + data->loss_of_signal - old->loss_of_signal; + fc_stats->prim_seq_protocol_err_count = + data->psp_error_counts - old->psp_error_counts; + fc_stats->invalid_tx_word_count = + data->invalid_tx_words - old->invalid_tx_words; fc_stats->invalid_crc_count = data->invalid_crcs - old->invalid_crcs; - fc_stats->fcp_input_requests = data->input_requests - - old->input_requests; - fc_stats->fcp_output_requests = data->output_requests - - old->output_requests; - fc_stats->fcp_control_requests = data->control_requests - - old->control_requests; + fc_stats->fcp_input_requests = + data->input_requests - old->input_requests; + fc_stats->fcp_output_requests = + data->output_requests - old->output_requests; + fc_stats->fcp_control_requests = + data->control_requests - old->control_requests; fc_stats->fcp_input_megabytes = data->input_mb - old->input_mb; fc_stats->fcp_output_megabytes = data->output_mb - old->output_mb; } -static void -zfcp_set_fc_host_stats(struct fc_host_statistics *fc_stats, - struct fsf_qtcb_bottom_port *data) +static void zfcp_set_fc_host_stats(struct fc_host_statistics *fc_stats, + struct fsf_qtcb_bottom_port *data) { fc_stats->seconds_since_last_reset = data->seconds_since_last_reset; fc_stats->tx_frames = data->tx_frames; @@ -616,22 +415,14 @@ zfcp_set_fc_host_stats(struct fc_host_statistics *fc_stats, fc_stats->fcp_output_megabytes = data->output_mb; } -/** - * zfcp_get_fc_host_stats - provide fc_host_statistics for scsi_transport_fc - * - * assumption: scsi_transport_fc synchronizes calls of - * get_fc_host_stats and reset_fc_host_stats - * (XXX to be checked otherwise introduce locking) - */ -static struct fc_host_statistics * -zfcp_get_fc_host_stats(struct Scsi_Host *shost) +static struct fc_host_statistics *zfcp_get_fc_host_stats(struct Scsi_Host *host) { struct zfcp_adapter *adapter; struct fc_host_statistics *fc_stats; struct fsf_qtcb_bottom_port *data; int ret; - adapter = (struct zfcp_adapter *)shost->hostdata[0]; + adapter = (struct zfcp_adapter *)host->hostdata[0]; fc_stats = zfcp_init_fc_host_stats(adapter); if (!fc_stats) return NULL; @@ -643,26 +434,25 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost) ret = zfcp_fsf_exchange_port_data_sync(adapter, data); if (ret) { kfree(data); - return NULL; /* XXX return zeroed fc_stats? */ + return NULL; } if (adapter->stats_reset && ((jiffies/HZ - adapter->stats_reset) < - data->seconds_since_last_reset)) { + data->seconds_since_last_reset)) zfcp_adjust_fc_host_stats(fc_stats, data, adapter->stats_reset_data); - } else + else zfcp_set_fc_host_stats(fc_stats, data); kfree(data); return fc_stats; } -static void -zfcp_reset_fc_host_stats(struct Scsi_Host *shost) +static void zfcp_reset_fc_host_stats(struct Scsi_Host *shost) { struct zfcp_adapter *adapter; - struct fsf_qtcb_bottom_port *data, *old_data; + struct fsf_qtcb_bottom_port *data; int ret; adapter = (struct zfcp_adapter *)shost->hostdata[0]; @@ -671,14 +461,13 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost) return; ret = zfcp_fsf_exchange_port_data_sync(adapter, data); - if (ret) { + if (ret) kfree(data); - } else { + else { adapter->stats_reset = jiffies/HZ; - old_data = adapter->stats_reset_data; + kfree(adapter->stats_reset_data); adapter->stats_reset_data = data; /* finally freed in - adater_dequeue */ - kfree(old_data); + adapter_dequeue */ } } @@ -793,14 +582,6 @@ ZFCP_DEFINE_LATENCY_ATTR(read); ZFCP_DEFINE_LATENCY_ATTR(write); ZFCP_DEFINE_LATENCY_ATTR(cmd); -/** - * ZFCP_DEFINE_SCSI_ATTR - * @_name: name of show attribute - * @_format: format string - * @_value: value to print - * - * Generates attribute for a unit. - */ #define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \ static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, struct device_attribute *attr, \ char *buf) \ @@ -815,7 +596,8 @@ static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, struct device_ \ static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); -ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", zfcp_get_busid_by_unit(unit)); +ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", + unit->port->adapter->ccw_device->dev.bus_id); ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn); ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun); @@ -835,8 +617,8 @@ static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, { struct Scsi_Host *scsi_host = dev_to_shost(dev); struct fsf_qtcb_bottom_port *qtcb_port; - int retval; struct zfcp_adapter *adapter; + int retval; adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) @@ -857,17 +639,17 @@ static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, static int zfcp_sysfs_adapter_ex_config(struct device *dev, struct fsf_statistics_info *stat_inf) { - int retval; - struct fsf_qtcb_bottom_config *qtcb_config; struct Scsi_Host *scsi_host = dev_to_shost(dev); + struct fsf_qtcb_bottom_config *qtcb_config; struct zfcp_adapter *adapter; + int retval; adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) return -EOPNOTSUPP; qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config), - GFP_KERNEL); + GFP_KERNEL); if (!qtcb_config) return -ENOMEM; @@ -940,3 +722,28 @@ static struct device_attribute *zfcp_a_stats_attrs[] = { &dev_attr_seconds_active, NULL }; + +struct zfcp_data zfcp_data = { + .scsi_host_template = { + .name = "zfcp", + .module = THIS_MODULE, + .proc_name = "zfcp", + .slave_alloc = zfcp_scsi_slave_alloc, + .slave_configure = zfcp_scsi_slave_configure, + .slave_destroy = zfcp_scsi_slave_destroy, + .queuecommand = zfcp_scsi_queuecommand, + .eh_abort_handler = zfcp_scsi_eh_abort_handler, + .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, + .eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler, + .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, + .can_queue = 4096, + .this_id = -1, + .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ, + .cmd_per_lun = 1, + .use_clustering = 1, + .sdev_attrs = zfcp_sysfs_sdev_attrs, + .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), + .shost_attrs = zfcp_a_stats_attrs, + }, +}; + -- cgit v0.10.2 From 317e6b6519b5a34263a33f150ed57ad468b26a64 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:37 +0200 Subject: [SCSI] zfcp: Cleanup of code in zfcp_aux.c Overall cleanup of zfcp_aux.c to simplify code and follow kernel coding style. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index bfcd1ba..7777729 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -29,48 +29,14 @@ #include "zfcp_ext.h" static char *device; -/*********************** FUNCTION PROTOTYPES *********************************/ - -/* written against the module interface */ -static int __init zfcp_module_init(void); - -/*********************** KERNEL/MODULE PARAMETERS ***************************/ - -/* declare driver module init/cleanup functions */ -module_init(zfcp_module_init); MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com"); -MODULE_DESCRIPTION - ("FCP (SCSI over Fibre Channel) HBA driver for IBM System z9 and zSeries"); +MODULE_DESCRIPTION("FCP HBA driver"); MODULE_LICENSE("GPL"); module_param(device, charp, 0400); MODULE_PARM_DESC(device, "specify initial device"); -/****************************************************************/ -/************** Functions without logging ***********************/ -/****************************************************************/ - -void -_zfcp_hex_dump(char *addr, int count) -{ - int i; - for (i = 0; i < count; i++) { - printk("%02x", addr[i]); - if ((i % 4) == 3) - printk(" "); - if ((i % 32) == 31) - printk("\n"); - } - if (((i-1) % 32) != 31) - printk("\n"); -} - - -/****************************************************************/ -/****** Functions to handle the request ID hash table ********/ -/****************************************************************/ - static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) { int idx; @@ -85,11 +51,12 @@ static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) return 0; } -static void zfcp_reqlist_free(struct zfcp_adapter *adapter) -{ - kfree(adapter->req_list); -} - +/** + * zfcp_reqlist_isempty - is the request list empty + * @adapter: pointer to struct zfcp_adapter + * + * Returns: true if list is empty, false otherwise + */ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) { unsigned int idx; @@ -100,62 +67,58 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) return 1; } -/****************************************************************/ -/************** Uncategorised Functions *************************/ -/****************************************************************/ - -/** - * zfcp_device_setup - setup function - * @str: pointer to parameter string - * - * Parse "device=..." parameter string. - */ -static int __init -zfcp_device_setup(char *devstr) +static int __init zfcp_device_setup(char *devstr) { - char *tmp, *str; - size_t len; + char *token; + char *str; if (!devstr) return 0; - len = strlen(devstr) + 1; - str = kmalloc(len, GFP_KERNEL); - if (!str) { - pr_err("zfcp: Could not allocate memory for " - "device parameter string, device not attached.\n"); + /* duplicate devstr and keep the original for sysfs presentation*/ + str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); + if (!str) return 0; - } - memcpy(str, devstr, len); - tmp = strchr(str, ','); - if (!tmp) - goto err_out; - *tmp++ = '\0'; - strncpy(zfcp_data.init_busid, str, BUS_ID_SIZE); - zfcp_data.init_busid[BUS_ID_SIZE-1] = '\0'; + strcpy(str, devstr); - zfcp_data.init_wwpn = simple_strtoull(tmp, &tmp, 0); - if (*tmp++ != ',') + token = strsep(&str, ","); + if (!token || strlen(token) >= BUS_ID_SIZE) goto err_out; - if (*tmp == '\0') + strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE); + + token = strsep(&str, ","); + if (!token || strict_strtoull(token, 0, &zfcp_data.init_wwpn)) goto err_out; - zfcp_data.init_fcp_lun = simple_strtoull(tmp, &tmp, 0); - if (*tmp != '\0') + token = strsep(&str, ","); + if (!token || strict_strtoull(token, 0, &zfcp_data.init_fcp_lun)) goto err_out; + kfree(str); return 1; err_out: - pr_err("zfcp: Parse error for device parameter string %s, " - "device not attached.\n", str); kfree(str); + pr_err("zfcp: Parse error for device parameter string %s, " + "device not attached.\n", devstr); return 0; } -static void __init -zfcp_init_device_configure(void) +static struct zfcp_adapter *zfcp_get_adapter_by_busid(char *bus_id) +{ + struct zfcp_adapter *adapter; + + list_for_each_entry(adapter, &zfcp_data.adapter_list_head, list) + if ((strncmp(bus_id, adapter->ccw_device->dev.bus_id, + BUS_ID_SIZE) == 0) && + !(atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_REMOVE)) + return adapter; + return NULL; +} + +static void __init zfcp_init_device_configure(void) { struct zfcp_adapter *adapter; struct zfcp_port *port; @@ -168,92 +131,72 @@ zfcp_init_device_configure(void) zfcp_adapter_get(adapter); read_unlock_irq(&zfcp_data.config_lock); - if (adapter == NULL) + if (!adapter) goto out_adapter; port = zfcp_port_enqueue(adapter, zfcp_data.init_wwpn, 0, 0); - if (!port) + if (IS_ERR(port)) goto out_port; unit = zfcp_unit_enqueue(port, zfcp_data.init_fcp_lun); - if (!unit) + if (IS_ERR(unit)) goto out_unit; up(&zfcp_data.config_sema); ccw_device_set_online(adapter->ccw_device); zfcp_erp_wait(adapter); down(&zfcp_data.config_sema); zfcp_unit_put(unit); - out_unit: +out_unit: zfcp_port_put(port); - out_port: +out_port: zfcp_adapter_put(adapter); - out_adapter: +out_adapter: up(&zfcp_data.config_sema); return; } -static int calc_alignment(int size) +static struct kmem_cache *zfcp_cache_create(int size, char *name) { int align = 1; - - if (!size) - return 0; - while ((size - align) > 0) align <<= 1; - - return align; + return kmem_cache_create(name , size, align, 0, NULL); } -static int __init -zfcp_module_init(void) +static int __init zfcp_module_init(void) { int retval = -ENOMEM; - int size, align; - size = sizeof(struct zfcp_fsf_req_qtcb); - align = calc_alignment(size); - zfcp_data.fsf_req_qtcb_cache = - kmem_cache_create("zfcp_fsf", size, align, 0, NULL); + zfcp_data.fsf_req_qtcb_cache = zfcp_cache_create( + sizeof(struct zfcp_fsf_req_qtcb), "zfcp_fsf"); if (!zfcp_data.fsf_req_qtcb_cache) goto out; - size = sizeof(struct fsf_status_read_buffer); - align = calc_alignment(size); - zfcp_data.sr_buffer_cache = - kmem_cache_create("zfcp_sr", size, align, 0, NULL); + zfcp_data.sr_buffer_cache = zfcp_cache_create( + sizeof(struct fsf_status_read_buffer), "zfcp_sr"); if (!zfcp_data.sr_buffer_cache) goto out_sr_cache; - size = sizeof(struct zfcp_gid_pn_data); - align = calc_alignment(size); - zfcp_data.gid_pn_cache = - kmem_cache_create("zfcp_gid", size, align, 0, NULL); + zfcp_data.gid_pn_cache = zfcp_cache_create( + sizeof(struct zfcp_gid_pn_data), "zfcp_gid"); if (!zfcp_data.gid_pn_cache) goto out_gid_cache; - /* initialize adapter list */ INIT_LIST_HEAD(&zfcp_data.adapter_list_head); - - /* initialize adapters to be removed list head */ INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh); + sema_init(&zfcp_data.config_sema, 1); + rwlock_init(&zfcp_data.config_lock); + zfcp_data.scsi_transport_template = fc_attach_transport(&zfcp_transport_functions); if (!zfcp_data.scsi_transport_template) goto out_transport; retval = misc_register(&zfcp_cfdc_misc); - if (retval != 0) { + if (retval) { pr_err("zfcp: registration of misc device zfcp_cfdc failed\n"); goto out_misc; } - /* Initialise proc semaphores */ - sema_init(&zfcp_data.config_sema, 1); - - /* initialise configuration rw lock */ - rwlock_init(&zfcp_data.config_lock); - - /* setup dynamic I/O */ retval = zfcp_ccw_register(); if (retval) { pr_err("zfcp: Registration with common I/O layer failed.\n"); @@ -265,157 +208,83 @@ zfcp_module_init(void) goto out; - out_ccw_register: +out_ccw_register: misc_deregister(&zfcp_cfdc_misc); - out_misc: +out_misc: fc_release_transport(zfcp_data.scsi_transport_template); - out_transport: +out_transport: kmem_cache_destroy(zfcp_data.gid_pn_cache); - out_gid_cache: +out_gid_cache: kmem_cache_destroy(zfcp_data.sr_buffer_cache); - out_sr_cache: +out_sr_cache: kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache); - out: +out: return retval; } -/****************************************************************/ -/****** Functions for configuration/set-up of structures ********/ -/****************************************************************/ +module_init(zfcp_module_init); /** * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN * @port: pointer to port to search for unit * @fcp_lun: FCP LUN to search for - * Traverse list of all units of a port and return pointer to a unit - * with the given FCP LUN. + * + * Returns: pointer to zfcp_unit or NULL */ -struct zfcp_unit * -zfcp_get_unit_by_lun(struct zfcp_port *port, fcp_lun_t fcp_lun) +struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, + fcp_lun_t fcp_lun) { struct zfcp_unit *unit; - int found = 0; - list_for_each_entry(unit, &port->unit_list_head, list) { + list_for_each_entry(unit, &port->unit_list_head, list) if ((unit->fcp_lun == fcp_lun) && - !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status)) - { - found = 1; - break; - } - } - return found ? unit : NULL; + !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) + return unit; + return NULL; } /** * zfcp_get_port_by_wwpn - find port in port list of adapter by wwpn * @adapter: pointer to adapter to search for port * @wwpn: wwpn to search for - * Traverse list of all ports of an adapter and return pointer to a port - * with the given wwpn. + * + * Returns: pointer to zfcp_port or NULL */ -struct zfcp_port * -zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, wwn_t wwpn) +struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, + wwn_t wwpn) { struct zfcp_port *port; - int found = 0; - list_for_each_entry(port, &adapter->port_list_head, list) { - if ((port->wwpn == wwpn) && - !(atomic_read(&port->status) & - (ZFCP_STATUS_PORT_NO_WWPN | ZFCP_STATUS_COMMON_REMOVE))) { - found = 1; - break; - } - } - return found ? port : NULL; -} - -/** - * zfcp_get_port_by_did - find port in port list of adapter by d_id - * @adapter: pointer to adapter to search for port - * @d_id: d_id to search for - * Traverse list of all ports of an adapter and return pointer to a port - * with the given d_id. - */ -struct zfcp_port * -zfcp_get_port_by_did(struct zfcp_adapter *adapter, u32 d_id) -{ - struct zfcp_port *port; - int found = 0; - - list_for_each_entry(port, &adapter->port_list_head, list) { - if ((port->d_id == d_id) && - !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) - { - found = 1; - break; - } - } - return found ? port : NULL; -} - -/** - * zfcp_get_adapter_by_busid - find adpater in adapter list by bus_id - * @bus_id: bus_id to search for - * Traverse list of all adapters and return pointer to an adapter - * with the given bus_id. - */ -struct zfcp_adapter * -zfcp_get_adapter_by_busid(char *bus_id) -{ - struct zfcp_adapter *adapter; - int found = 0; - - list_for_each_entry(adapter, &zfcp_data.adapter_list_head, list) { - if ((strncmp(bus_id, zfcp_get_busid_by_adapter(adapter), - BUS_ID_SIZE) == 0) && - !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, - &adapter->status)){ - found = 1; - break; - } - } - return found ? adapter : NULL; + list_for_each_entry(port, &adapter->port_list_head, list) + if ((port->wwpn == wwpn) && !(atomic_read(&port->status) & + (ZFCP_STATUS_PORT_NO_WWPN | ZFCP_STATUS_COMMON_REMOVE))) + return port; + return NULL; } /** * zfcp_unit_enqueue - enqueue unit to unit list of a port. * @port: pointer to port where unit is added * @fcp_lun: FCP LUN of unit to be enqueued - * Return: pointer to enqueued unit on success, NULL on error + * Returns: pointer to enqueued unit on success, ERR_PTR on error * Locks: config_sema must be held to serialize changes to the unit list * * Sets up some unit internal structures and creates sysfs entry. */ -struct zfcp_unit * -zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) +struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) { struct zfcp_unit *unit; - /* - * check that there is no unit with this FCP_LUN already in list - * and enqueue it. - * Note: Unlike for the adapter and the port, this is an error - */ - read_lock_irq(&zfcp_data.config_lock); - unit = zfcp_get_unit_by_lun(port, fcp_lun); - read_unlock_irq(&zfcp_data.config_lock); - if (unit) - return NULL; - - unit = kzalloc(sizeof (struct zfcp_unit), GFP_KERNEL); + unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); if (!unit) - return NULL; + return ERR_PTR(-ENOMEM); - /* initialise reference count stuff */ atomic_set(&unit->refcount, 0); init_waitqueue_head(&unit->remove_wq); unit->port = port; unit->fcp_lun = fcp_lun; - /* setup for sysfs registration */ snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", fcp_lun); unit->sysfs_device.parent = &port->sysfs_device; unit->sysfs_device.release = zfcp_sysfs_unit_release; @@ -432,14 +301,19 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) unit->latencies.cmd.channel.min = 0xFFFFFFFF; unit->latencies.cmd.fabric.min = 0xFFFFFFFF; - if (device_register(&unit->sysfs_device)) { - kfree(unit); - return NULL; + read_lock_irq(&zfcp_data.config_lock); + if (zfcp_get_unit_by_lun(port, fcp_lun)) { + read_unlock_irq(&zfcp_data.config_lock); + goto err_out_free; } + read_unlock_irq(&zfcp_data.config_lock); + + if (device_register(&unit->sysfs_device)) + goto err_out_free; if (zfcp_sysfs_unit_create_files(&unit->sysfs_device)) { device_unregister(&unit->sysfs_device); - return NULL; + return ERR_PTR(-EIO); } zfcp_unit_get(unit); @@ -449,16 +323,27 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) list_add_tail(&unit->list, &port->unit_list_head); atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); + write_unlock_irq(&zfcp_data.config_lock); port->units++; zfcp_port_get(port); return unit; + +err_out_free: + kfree(unit); + return ERR_PTR(-EINVAL); } -void -zfcp_unit_dequeue(struct zfcp_unit *unit) +/** + * zfcp_unit_dequeue - dequeue unit + * @unit: pointer to zfcp_unit + * + * waits until all work is done on unit and removes it then from the unit->list + * of the associated port. + */ +void zfcp_unit_dequeue(struct zfcp_unit *unit) { zfcp_unit_wait(unit); write_lock_irq(&zfcp_data.config_lock); @@ -470,64 +355,47 @@ zfcp_unit_dequeue(struct zfcp_unit *unit) device_unregister(&unit->sysfs_device); } -/* - * Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI - * commands. - * It also genrates fcp-nameserver request/response buffer and unsolicited - * status read fsf_req buffers. - * - * locks: must only be called with zfcp_data.config_sema taken - */ -static int -zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) +static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) { + /* must only be called with zfcp_data.config_sema taken */ adapter->pool.fsf_req_erp = - mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ERP_NR, - zfcp_data.fsf_req_qtcb_cache); + mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache); if (!adapter->pool.fsf_req_erp) return -ENOMEM; adapter->pool.fsf_req_scsi = - mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_SCSI_NR, - zfcp_data.fsf_req_qtcb_cache); + mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache); if (!adapter->pool.fsf_req_scsi) return -ENOMEM; adapter->pool.fsf_req_abort = - mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ABORT_NR, - zfcp_data.fsf_req_qtcb_cache); + mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache); if (!adapter->pool.fsf_req_abort) return -ENOMEM; adapter->pool.fsf_req_status_read = - mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR, + mempool_create_kmalloc_pool(FSF_STATUS_READS_RECOM, sizeof(struct zfcp_fsf_req)); if (!adapter->pool.fsf_req_status_read) return -ENOMEM; adapter->pool.data_status_read = - mempool_create_slab_pool(ZFCP_POOL_STATUS_READ_NR, + mempool_create_slab_pool(FSF_STATUS_READS_RECOM, zfcp_data.sr_buffer_cache); if (!adapter->pool.data_status_read) return -ENOMEM; adapter->pool.data_gid_pn = - mempool_create_slab_pool(ZFCP_POOL_DATA_GID_PN_NR, - zfcp_data.gid_pn_cache); + mempool_create_slab_pool(1, zfcp_data.gid_pn_cache); if (!adapter->pool.data_gid_pn) return -ENOMEM; return 0; } -/** - * zfcp_free_low_mem_buffers - free memory pools of an adapter - * @adapter: pointer to zfcp_adapter for which memory pools should be freed - * locking: zfcp_data.config_sema must be held - */ -static void -zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) +static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) { + /* zfcp_data.config_sema must be held */ if (adapter->pool.fsf_req_erp) mempool_destroy(adapter->pool.fsf_req_erp); if (adapter->pool.fsf_req_scsi) @@ -547,6 +415,15 @@ static void zfcp_dummy_release(struct device *dev) return; } +/** + * zfcp_status_read_refill - refill the long running status_read_requests + * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled + * + * Returns: 0 on success, 1 otherwise + * + * if there are 16 or more status_read requests missing an adapter_reopen + * is triggered + */ int zfcp_status_read_refill(struct zfcp_adapter *adapter) { while (atomic_read(&adapter->stat_miss) > 0) @@ -573,27 +450,25 @@ static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, ZFCP_DID_DIRECTORY_SERVICE); - if (!port) - return -ENXIO; + if (IS_ERR(port)) + return PTR_ERR(port); zfcp_port_put(port); return 0; } -/* +/** + * zfcp_adapter_enqueue - enqueue a new adapter to the list + * @ccw_device: pointer to the struct cc_device + * + * Returns: 0 if a new adapter was successfully enqueued + * -ENOMEM if alloc failed * Enqueues an adapter at the end of the adapter list in the driver data. * All adapter internal structures are set up. * Proc-fs entries are also created. - * - * FIXME: Use -ENOMEM as return code for allocation failures - * - * returns: 0 if a new adapter was successfully enqueued - * ZFCP_KNOWN if an adapter with this devno was already present - * -ENOMEM if alloc failed * locks: config_sema must be held to serialise changes to the adapter list */ -struct zfcp_adapter * -zfcp_adapter_enqueue(struct ccw_device *ccw_device) +int zfcp_adapter_enqueue(struct ccw_device *ccw_device) { struct zfcp_adapter *adapter; @@ -602,15 +477,13 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) * are protected by the config_sema, which must be held to get here */ - /* try to allocate new adapter data structure (zeroed) */ - adapter = kzalloc(sizeof (struct zfcp_adapter), GFP_KERNEL); + adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL); if (!adapter) - goto out; + return -ENOMEM; ccw_device->handler = NULL; - - /* save ccw_device pointer */ adapter->ccw_device = ccw_device; + atomic_set(&adapter->refcount, 0); if (zfcp_qdio_allocate(adapter)) goto qdio_allocate_failed; @@ -618,47 +491,34 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) if (zfcp_allocate_low_mem_buffers(adapter)) goto failed_low_mem_buffers; - /* initialise reference count stuff */ - atomic_set(&adapter->refcount, 0); + if (zfcp_reqlist_alloc(adapter)) + goto failed_low_mem_buffers; + + if (zfcp_adapter_debug_register(adapter)) + goto debug_register_failed; + init_waitqueue_head(&adapter->remove_wq); + init_waitqueue_head(&adapter->erp_thread_wqh); + init_waitqueue_head(&adapter->erp_done_wqh); - /* initialise list of ports */ INIT_LIST_HEAD(&adapter->port_list_head); - - /* initialise list of ports to be removed */ INIT_LIST_HEAD(&adapter->port_remove_lh); + INIT_LIST_HEAD(&adapter->erp_ready_head); + INIT_LIST_HEAD(&adapter->erp_running_head); - /* initialize list of fsf requests */ spin_lock_init(&adapter->req_list_lock); - if (zfcp_reqlist_alloc(adapter)) - goto failed_low_mem_buffers; - - /* initialize debug locks */ spin_lock_init(&adapter->hba_dbf_lock); spin_lock_init(&adapter->san_dbf_lock); spin_lock_init(&adapter->scsi_dbf_lock); spin_lock_init(&adapter->rec_dbf_lock); - if (zfcp_adapter_debug_register(adapter)) - goto debug_register_failed; - - /* initialize error recovery stuff */ - rwlock_init(&adapter->erp_lock); - sema_init(&adapter->erp_ready_sem, 0); - INIT_LIST_HEAD(&adapter->erp_ready_head); - INIT_LIST_HEAD(&adapter->erp_running_head); - - /* initialize abort lock */ rwlock_init(&adapter->abort_lock); + rwlock_init(&adapter->req_q.lock); - /* initialise some erp stuff */ - init_waitqueue_head(&adapter->erp_thread_wqh); - init_waitqueue_head(&adapter->erp_done_wqh); + sema_init(&adapter->erp_ready_sem, 0); - /* initialize lock of associated request queue */ - rwlock_init(&adapter->req_q.lock); INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); INIT_WORK(&adapter->scan_work, _zfcp_scan_ports_later); @@ -678,7 +538,6 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) if (device_register(&adapter->generic_services)) goto generic_services_failed; - /* put allocated adapter at list tail */ write_lock_irq(&zfcp_data.config_lock); atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); list_add_tail(&adapter->list, &zfcp_data.adapter_list_head); @@ -688,33 +547,29 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) zfcp_nameserver_enqueue(adapter); - goto out; + return 0; - generic_services_failed: +generic_services_failed: zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); - sysfs_failed: +sysfs_failed: zfcp_adapter_debug_unregister(adapter); - debug_register_failed: +debug_register_failed: dev_set_drvdata(&ccw_device->dev, NULL); - zfcp_reqlist_free(adapter); - failed_low_mem_buffers: + kfree(adapter->req_list); +failed_low_mem_buffers: zfcp_free_low_mem_buffers(adapter); - qdio_allocate_failed: +qdio_allocate_failed: zfcp_qdio_free(adapter); kfree(adapter); - adapter = NULL; - out: - return adapter; + return -ENOMEM; } -/* - * returns: 0 - struct zfcp_adapter data structure successfully removed - * !0 - struct zfcp_adapter data structure could not be removed - * (e.g. still used) +/** + * zfcp_adapter_dequeue - remove the adapter from the resource list + * @adapter: pointer to struct zfcp_adapter which should be removed * locks: adapter list write lock is assumed to be held by caller */ -void -zfcp_adapter_dequeue(struct zfcp_adapter *adapter) +void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) { int retval = 0; unsigned long flags; @@ -729,10 +584,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) spin_lock_irqsave(&adapter->req_list_lock, flags); retval = zfcp_reqlist_isempty(adapter); spin_unlock_irqrestore(&adapter->req_list_lock, flags); - if (!retval) { - retval = -EBUSY; - goto out; - } + if (!retval) + return; zfcp_adapter_debug_unregister(adapter); @@ -747,12 +600,10 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) zfcp_qdio_free(adapter); zfcp_free_low_mem_buffers(adapter); - zfcp_reqlist_free(adapter); + kfree(adapter->req_list); kfree(adapter->fc_stats); kfree(adapter->stats_reset_data); kfree(adapter); - out: - return; } /** @@ -761,77 +612,58 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) * @wwpn: WWPN of the remote port to be enqueued * @status: initial status for the port * @d_id: destination id of the remote port to be enqueued - * Return: pointer to enqueued port on success, NULL on error + * Returns: pointer to enqueued port on success, ERR_PTR on error * Locks: config_sema must be held to serialize changes to the port list * * All port internal structures are set up and the sysfs entry is generated. * d_id is used to enqueue ports with a well known address like the Directory * Service for nameserver lookup. */ -struct zfcp_port * -zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, - u32 d_id) +struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, + u32 status, u32 d_id) { struct zfcp_port *port; - int check_wwpn; + char *bus_id; - check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN); - /* - * check that there is no port with this WWPN already in list - */ - if (check_wwpn) { - read_lock_irq(&zfcp_data.config_lock); - port = zfcp_get_port_by_wwpn(adapter, wwpn); - read_unlock_irq(&zfcp_data.config_lock); - if (port) - return NULL; - } - - port = kzalloc(sizeof (struct zfcp_port), GFP_KERNEL); + port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); if (!port) - return NULL; + return ERR_PTR(-ENOMEM); - /* initialise reference count stuff */ - atomic_set(&port->refcount, 0); init_waitqueue_head(&port->remove_wq); INIT_LIST_HEAD(&port->unit_list_head); INIT_LIST_HEAD(&port->unit_remove_lh); port->adapter = adapter; + port->d_id = d_id; + port->wwpn = wwpn; - if (check_wwpn) - port->wwpn = wwpn; - - atomic_set_mask(status, &port->status); + /* mark port unusable as long as sysfs registration is not complete */ + atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); + atomic_set(&port->refcount, 0); - /* setup for sysfs registration */ if (status & ZFCP_STATUS_PORT_WKA) { switch (d_id) { case ZFCP_DID_DIRECTORY_SERVICE: - snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, - "directory"); + bus_id = "directory"; break; case ZFCP_DID_MANAGEMENT_SERVICE: - snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, - "management"); + bus_id = "management"; break; case ZFCP_DID_KEY_DISTRIBUTION_SERVICE: - snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, - "key_distribution"); + bus_id = "key_distribution"; break; case ZFCP_DID_ALIAS_SERVICE: - snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, - "alias"); + bus_id = "alias"; break; case ZFCP_DID_TIME_SERVICE: - snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, - "time"); + bus_id = "time"; break; default: kfree(port); - return NULL; + return ERR_PTR(-EINVAL); } + snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id); port->sysfs_device.parent = &adapter->generic_services; } else { snprintf(port->sysfs_device.bus_id, @@ -839,22 +671,23 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, port->sysfs_device.parent = &adapter->ccw_device->dev; } - port->d_id = d_id; - port->sysfs_device.release = zfcp_sysfs_port_release; dev_set_drvdata(&port->sysfs_device, port); - /* mark port unusable as long as sysfs registration is not complete */ - atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); + read_lock_irq(&zfcp_data.config_lock); + if (!(status & ZFCP_STATUS_PORT_NO_WWPN)) + if (zfcp_get_port_by_wwpn(adapter, wwpn)) { + read_unlock_irq(&zfcp_data.config_lock); + goto err_out_free; + } + read_unlock_irq(&zfcp_data.config_lock); - if (device_register(&port->sysfs_device)) { - kfree(port); - return NULL; - } + if (device_register(&port->sysfs_device)) + goto err_out_free; if (zfcp_sysfs_port_create_files(&port->sysfs_device, status)) { device_unregister(&port->sysfs_device); - return NULL; + goto err_out; } zfcp_port_get(port); @@ -867,15 +700,23 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, if (!adapter->nameserver_port) adapter->nameserver_port = port; adapter->ports++; + write_unlock_irq(&zfcp_data.config_lock); zfcp_adapter_get(adapter); - return port; + +err_out_free: + kfree(port); +err_out: + return ERR_PTR(-EINVAL); } -void -zfcp_port_dequeue(struct zfcp_port *port) +/** + * zfcp_port_dequeue - dequeues a port from the port list of the adapter + * @port: pointer to struct zfcp_port which should be removed + */ +void zfcp_port_dequeue(struct zfcp_port *port) { zfcp_port_wait(port); write_lock_irq(&zfcp_data.config_lock); @@ -891,6 +732,12 @@ zfcp_port_dequeue(struct zfcp_port *port) device_unregister(&port->sysfs_device); } +/** + * zfcp_sg_free_table - free memory used by scatterlists + * @sg: pointer to scatterlist + * @count: number of scatterlist which are to be free'ed + * the scatterlist are expected to reference pages always + */ void zfcp_sg_free_table(struct scatterlist *sg, int count) { int i; @@ -902,6 +749,14 @@ void zfcp_sg_free_table(struct scatterlist *sg, int count) break; } +/** + * zfcp_sg_setup_table - init scatterlist and allocate, assign buffers + * @sg: pointer to struct scatterlist + * @count: number of scatterlists which should be assigned with buffers + * of size page + * + * Returns: 0 on success, -ENOMEM otherwise + */ int zfcp_sg_setup_table(struct scatterlist *sg, int count) { void *addr; diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index da472e8..391dd29 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -20,12 +20,10 @@ */ static int zfcp_ccw_probe(struct ccw_device *ccw_device) { - struct zfcp_adapter *adapter; int retval = 0; down(&zfcp_data.config_sema); - adapter = zfcp_adapter_enqueue(ccw_device); - if (!adapter) { + if (zfcp_adapter_enqueue(ccw_device)) { dev_err(&ccw_device->dev, "Setup of data structures failed.\n"); retval = -EINVAL; diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 7ac830c..d69d280 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -730,13 +730,6 @@ struct zfcp_data { struct kmem_cache *gid_pn_cache; }; -/* number of elements for various memory pools */ -#define ZFCP_POOL_FSF_REQ_ERP_NR 1 -#define ZFCP_POOL_FSF_REQ_SCSI_NR 1 -#define ZFCP_POOL_FSF_REQ_ABORT_NR 1 -#define ZFCP_POOL_STATUS_READ_NR FSF_STATUS_READS_RECOM -#define ZFCP_POOL_DATA_GID_PN_NR 1 - /* struct used by memory pools for fsf_requests */ struct zfcp_fsf_req_qtcb { struct zfcp_fsf_req fsf_req; @@ -757,12 +750,6 @@ struct zfcp_fsf_req_qtcb { ((atomic_read(target) & mask) == mask) #endif -extern void _zfcp_hex_dump(char *, int); -#define ZFCP_HEX_DUMP(level, addr, count) \ - if (ZFCP_LOG_CHECK(level)) { \ - _zfcp_hex_dump(addr, count); \ - } - #define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id) #define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter)) #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 9b9c999..4d797e5 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -1675,7 +1675,7 @@ static void zfcp_erp_open_ptp_port(struct zfcp_adapter *adapter) struct zfcp_port *port; port = zfcp_port_enqueue(adapter, adapter->peer_wwpn, 0, adapter->peer_d_id); - if (!port) /* error or port already attached */ + if (IS_ERR(port)) /* error or port already attached */ return; zfcp_erp_port_reopen_internal(port, 0, 150, NULL); } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 892476c..9caa081 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -26,9 +26,7 @@ extern void zfcp_sysfs_unit_release(struct device *); /**************************** CONFIGURATION *********************************/ extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, fcp_lun_t); extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, wwn_t); -extern struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *, u32); -struct zfcp_adapter *zfcp_get_adapter_by_busid(char *); -extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *); +extern int zfcp_adapter_enqueue(struct ccw_device *); extern int zfcp_adapter_debug_register(struct zfcp_adapter *); extern void zfcp_adapter_dequeue(struct zfcp_adapter *); extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *); diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 5d9367d..fbe2c76 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -39,6 +39,18 @@ struct zfcp_gpn_ft { struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; }; +static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter, + u32 d_id) +{ + struct zfcp_port *port; + + list_for_each_entry(port, &adapter->port_list_head, list) + if ((port->d_id == d_id) && + !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) + return port; + return NULL; +} + static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, struct fcp_rscn_element *elem) { @@ -496,10 +508,10 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) port = zfcp_port_enqueue(adapter, acc->wwpn, ZFCP_STATUS_PORT_DID_DID | ZFCP_STATUS_COMMON_NOESC, d_id); - if (port) - zfcp_erp_port_reopen(port, 0, 149, NULL); + if (IS_ERR(port)) + ret = PTR_ERR(port); else - ret = -ENOMEM; + zfcp_erp_port_reopen(port, 0, 149, NULL); if (acc->control & 0x80) /* last entry */ break; } diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c index 438675f..e183ff8 100644 --- a/drivers/s390/scsi/zfcp_sysfs_port.c +++ b/drivers/s390/scsi/zfcp_sysfs_port.c @@ -74,7 +74,7 @@ zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, con goto out; unit = zfcp_unit_enqueue(port, fcp_lun); - if (!unit) + if (IS_ERR(unit)) goto out; retval = 0; -- cgit v0.10.2 From 60221920706a01bef89af2577f9a90a8eeb4e662 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:38 +0200 Subject: [SCSI] zfcp: consolidate sysfs things into one file. zfcp was using three files to deal with sysfs representation for adapters, ports and units. The consolidation into one file prevents code-duplication and eases maintainability. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index 1aa4650..cb301cc 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -3,7 +3,6 @@ # zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ - zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \ - zfcp_sysfs_unit.o zfcp_fc.o zfcp_cfdc.o + zfcp_fsf.o zfcp_dbf.o zfcp_sysfs.o zfcp_fc.o zfcp_cfdc.o obj-$(CONFIG_ZFCP) += zfcp.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 7777729..5b9ca3c 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -262,6 +262,11 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, return NULL; } +static void zfcp_sysfs_unit_release(struct device *dev) +{ + kfree(container_of(dev, struct zfcp_unit, sysfs_device)); +} + /** * zfcp_unit_enqueue - enqueue unit to unit list of a port. * @port: pointer to port where unit is added @@ -311,7 +316,8 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) if (device_register(&unit->sysfs_device)) goto err_out_free; - if (zfcp_sysfs_unit_create_files(&unit->sysfs_device)) { + if (sysfs_create_group(&unit->sysfs_device.kobj, + &zfcp_sysfs_unit_attrs)) { device_unregister(&unit->sysfs_device); return ERR_PTR(-EIO); } @@ -351,7 +357,7 @@ void zfcp_unit_dequeue(struct zfcp_unit *unit) write_unlock_irq(&zfcp_data.config_lock); unit->port->units--; zfcp_port_put(unit->port); - zfcp_sysfs_unit_remove_files(&unit->sysfs_device); + sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs); device_unregister(&unit->sysfs_device); } @@ -527,7 +533,8 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) dev_set_drvdata(&ccw_device->dev, adapter); - if (zfcp_sysfs_adapter_create_files(&ccw_device->dev)) + if (sysfs_create_group(&ccw_device->dev.kobj, + &zfcp_sysfs_adapter_attrs)) goto sysfs_failed; adapter->generic_services.parent = &adapter->ccw_device->dev; @@ -550,7 +557,8 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) return 0; generic_services_failed: - zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); + sysfs_remove_group(&ccw_device->dev.kobj, + &zfcp_sysfs_adapter_attrs); sysfs_failed: zfcp_adapter_debug_unregister(adapter); debug_register_failed: @@ -578,7 +586,8 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) cancel_work_sync(&adapter->stat_work); zfcp_adapter_scsi_unregister(adapter); device_unregister(&adapter->generic_services); - zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); + sysfs_remove_group(&adapter->ccw_device->dev.kobj, + &zfcp_sysfs_adapter_attrs); dev_set_drvdata(&adapter->ccw_device->dev, NULL); /* sanity check: no pending FSF requests */ spin_lock_irqsave(&adapter->req_list_lock, flags); @@ -606,6 +615,11 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) kfree(adapter); } +static void zfcp_sysfs_port_release(struct device *dev) +{ + kfree(container_of(dev, struct zfcp_port, sysfs_device)); +} + /** * zfcp_port_enqueue - enqueue port to port list of adapter * @adapter: adapter where remote port is added @@ -623,6 +637,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, u32 d_id) { struct zfcp_port *port; + int retval; char *bus_id; port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); @@ -685,7 +700,14 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, if (device_register(&port->sysfs_device)) goto err_out_free; - if (zfcp_sysfs_port_create_files(&port->sysfs_device, status)) { + if (status & ZFCP_STATUS_PORT_WKA) + retval = sysfs_create_group(&port->sysfs_device.kobj, + &zfcp_sysfs_ns_port_attrs); + else + retval = sysfs_create_group(&port->sysfs_device.kobj, + &zfcp_sysfs_port_attrs); + + if (retval) { device_unregister(&port->sysfs_device); goto err_out; } @@ -727,8 +749,12 @@ void zfcp_port_dequeue(struct zfcp_port *port) fc_remote_port_delete(port->rport); port->rport = NULL; zfcp_adapter_put(port->adapter); - zfcp_sysfs_port_remove_files(&port->sysfs_device, - atomic_read(&port->status)); + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) + sysfs_remove_group(&port->sysfs_device.kobj, + &zfcp_sysfs_ns_port_attrs); + else + sysfs_remove_group(&port->sysfs_device.kobj, + &zfcp_sysfs_port_attrs); device_unregister(&port->sysfs_device); } diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index d69d280..2af043a 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -627,11 +627,6 @@ struct zfcp_adapter { struct work_struct scan_work; }; -/* - * the struct device sysfs_device must be at the beginning of this structure. - * pointer to struct device is used to free port structure in release function - * of the device. don't change! - */ struct zfcp_port { struct device sysfs_device; /* sysfs device */ struct fc_rport *rport; /* rport of fc transport class */ @@ -655,10 +650,6 @@ struct zfcp_port { u32 supported_classes; }; -/* the struct device sysfs_device must be at the beginning of this structure. - * pointer to struct device is used to free unit structure in release function - * of the device. don't change! - */ struct zfcp_unit { struct device sysfs_device; /* sysfs device */ struct list_head list; /* list of logical units */ diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 9caa081..f0d6947 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -13,15 +13,13 @@ extern struct zfcp_data zfcp_data; -/******************************** SYSFS *************************************/ -extern int zfcp_sysfs_adapter_create_files(struct device *); -extern void zfcp_sysfs_adapter_remove_files(struct device *); -extern int zfcp_sysfs_port_create_files(struct device *, u32); -extern void zfcp_sysfs_port_remove_files(struct device *, u32); -extern int zfcp_sysfs_unit_create_files(struct device *); -extern void zfcp_sysfs_unit_remove_files(struct device *); -extern void zfcp_sysfs_port_release(struct device *); -extern void zfcp_sysfs_unit_release(struct device *); +/* zfcp_sysfs.c */ +extern struct attribute_group zfcp_sysfs_unit_attrs; +extern struct attribute_group zfcp_sysfs_adapter_attrs; +extern struct attribute_group zfcp_sysfs_ns_port_attrs; +extern struct attribute_group zfcp_sysfs_port_attrs; +extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; +extern struct device_attribute *zfcp_sysfs_shost_attrs[]; /**************************** CONFIGURATION *********************************/ extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, fcp_lun_t); diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index f8594a2..e6d8ea8 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -520,209 +520,6 @@ struct fc_function_template zfcp_transport_functions = { .disable_target_scan = 1, }; -#define ZFCP_DEFINE_LATENCY_ATTR(_name) \ -static ssize_t \ -zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) { \ - struct scsi_device *sdev = to_scsi_device(dev); \ - struct zfcp_unit *unit = sdev->hostdata; \ - struct zfcp_latencies *lat = &unit->latencies; \ - struct zfcp_adapter *adapter = unit->port->adapter; \ - unsigned long flags; \ - unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \ - \ - spin_lock_irqsave(&lat->lock, flags); \ - fsum = lat->_name.fabric.sum * adapter->timer_ticks; \ - fmin = lat->_name.fabric.min * adapter->timer_ticks; \ - fmax = lat->_name.fabric.max * adapter->timer_ticks; \ - csum = lat->_name.channel.sum * adapter->timer_ticks; \ - cmin = lat->_name.channel.min * adapter->timer_ticks; \ - cmax = lat->_name.channel.max * adapter->timer_ticks; \ - cc = lat->_name.counter; \ - spin_unlock_irqrestore(&lat->lock, flags); \ - \ - do_div(fsum, 1000); \ - do_div(fmin, 1000); \ - do_div(fmax, 1000); \ - do_div(csum, 1000); \ - do_div(cmin, 1000); \ - do_div(cmax, 1000); \ - \ - return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n", \ - fmin, fmax, fsum, cmin, cmax, csum, cc); \ -} \ -static ssize_t \ -zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct scsi_device *sdev = to_scsi_device(dev); \ - struct zfcp_unit *unit = sdev->hostdata; \ - struct zfcp_latencies *lat = &unit->latencies; \ - unsigned long flags; \ - \ - spin_lock_irqsave(&lat->lock, flags); \ - lat->_name.fabric.sum = 0; \ - lat->_name.fabric.min = 0xFFFFFFFF; \ - lat->_name.fabric.max = 0; \ - lat->_name.channel.sum = 0; \ - lat->_name.channel.min = 0xFFFFFFFF; \ - lat->_name.channel.max = 0; \ - lat->_name.counter = 0; \ - spin_unlock_irqrestore(&lat->lock, flags); \ - \ - return (ssize_t) count; \ -} \ -static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO, \ - zfcp_sysfs_unit_##_name##_latency_show, \ - zfcp_sysfs_unit_##_name##_latency_store); - -ZFCP_DEFINE_LATENCY_ATTR(read); -ZFCP_DEFINE_LATENCY_ATTR(write); -ZFCP_DEFINE_LATENCY_ATTR(cmd); - -#define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \ -static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct scsi_device *sdev; \ - struct zfcp_unit *unit; \ - \ - sdev = to_scsi_device(dev); \ - unit = sdev->hostdata; \ - return sprintf(buf, _format, _value); \ -} \ - \ -static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); - -ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", - unit->port->adapter->ccw_device->dev.bus_id); -ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn); -ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun); - -static struct device_attribute *zfcp_sysfs_sdev_attrs[] = { - &dev_attr_fcp_lun, - &dev_attr_wwpn, - &dev_attr_hba_id, - &dev_attr_read_latency, - &dev_attr_write_latency, - &dev_attr_cmd_latency, - NULL -}; - -static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *scsi_host = dev_to_shost(dev); - struct fsf_qtcb_bottom_port *qtcb_port; - struct zfcp_adapter *adapter; - int retval; - - adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; - if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) - return -EOPNOTSUPP; - - qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL); - if (!qtcb_port) - return -ENOMEM; - - retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port); - if (!retval) - retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util, - qtcb_port->cb_util, qtcb_port->a_util); - kfree(qtcb_port); - return retval; -} - -static int zfcp_sysfs_adapter_ex_config(struct device *dev, - struct fsf_statistics_info *stat_inf) -{ - struct Scsi_Host *scsi_host = dev_to_shost(dev); - struct fsf_qtcb_bottom_config *qtcb_config; - struct zfcp_adapter *adapter; - int retval; - - adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; - if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) - return -EOPNOTSUPP; - - qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config), - GFP_KERNEL); - if (!qtcb_config) - return -ENOMEM; - - retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config); - if (!retval) - *stat_inf = qtcb_config->stat_info; - - kfree(qtcb_config); - return retval; -} - -static ssize_t zfcp_sysfs_adapter_request_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct fsf_statistics_info stat_info; - int retval; - - retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); - if (retval) - return retval; - - return sprintf(buf, "%llu %llu %llu\n", - (unsigned long long) stat_info.input_req, - (unsigned long long) stat_info.output_req, - (unsigned long long) stat_info.control_req); -} - -static ssize_t zfcp_sysfs_adapter_mb_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct fsf_statistics_info stat_info; - int retval; - - retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); - if (retval) - return retval; - - return sprintf(buf, "%llu %llu\n", - (unsigned long long) stat_info.input_mb, - (unsigned long long) stat_info.output_mb); -} - -static ssize_t zfcp_sysfs_adapter_sec_active_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct fsf_statistics_info stat_info; - int retval; - - retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); - if (retval) - return retval; - - return sprintf(buf, "%llu\n", - (unsigned long long) stat_info.seconds_act); -} - -static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL); -static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL); -static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL); -static DEVICE_ATTR(seconds_active, S_IRUGO, - zfcp_sysfs_adapter_sec_active_show, NULL); - -static struct device_attribute *zfcp_a_stats_attrs[] = { - &dev_attr_utilization, - &dev_attr_requests, - &dev_attr_megabytes, - &dev_attr_seconds_active, - NULL -}; - struct zfcp_data zfcp_data = { .scsi_host_template = { .name = "zfcp", @@ -743,7 +540,6 @@ struct zfcp_data zfcp_data = { .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), - .shost_attrs = zfcp_a_stats_attrs, + .shost_attrs = zfcp_sysfs_shost_attrs, }, }; - diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c new file mode 100644 index 0000000..2e85c6c --- /dev/null +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -0,0 +1,496 @@ +/* + * zfcp device driver + * + * sysfs attributes. + * + * Copyright IBM Corporation 2008 + */ + +#include "zfcp_ext.h" + +#define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \ +struct device_attribute dev_attr_##_feat##_##_name = __ATTR(_name, _mode,\ + _show, _store) +#define ZFCP_DEFINE_ATTR(_feat_def, _feat, _name, _format, _value) \ +static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev, \ + struct device_attribute *at,\ + char *buf) \ +{ \ + struct _feat_def *_feat = dev_get_drvdata(dev); \ + \ + return sprintf(buf, _format, _value); \ +} \ +static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO, \ + zfcp_sysfs_##_feat##_##_name##_show, NULL); + +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n", + atomic_read(&adapter->status)); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n", + adapter->peer_wwnn); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n", + adapter->peer_wwpn); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n", + adapter->peer_d_id); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n", + adapter->hydra_version); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, lic_version, "0x%08x\n", + adapter->fsf_lic_version); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, hardware_version, "0x%08x\n", + adapter->hardware_version); +ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, in_recovery, "%d\n", + (atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_ERP_INUSE) != 0); + +ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n", + atomic_read(&port->status)); +ZFCP_DEFINE_ATTR(zfcp_port, port, in_recovery, "%d\n", + (atomic_read(&port->status) & + ZFCP_STATUS_COMMON_ERP_INUSE) != 0); +ZFCP_DEFINE_ATTR(zfcp_port, port, access_denied, "%d\n", + (atomic_read(&port->status) & + ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); + +ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n", + atomic_read(&unit->status)); +ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n", + (atomic_read(&unit->status) & + ZFCP_STATUS_COMMON_ERP_INUSE) != 0); +ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n", + (atomic_read(&unit->status) & + ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); +ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_shared, "%d\n", + (atomic_read(&unit->status) & + ZFCP_STATUS_UNIT_SHARED) != 0); +ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n", + (atomic_read(&unit->status) & + ZFCP_STATUS_UNIT_READONLY) != 0); + +#define ZFCP_SYSFS_FAILED(_feat_def, _feat, _adapter, _mod_id, _reopen_id) \ +static ssize_t zfcp_sysfs_##_feat##_failed_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct _feat_def *_feat = dev_get_drvdata(dev); \ + \ + if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED) \ + return sprintf(buf, "1\n"); \ + else \ + return sprintf(buf, "0\n"); \ +} \ +static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \ + struct device_attribute *attr,\ + const char *buf, size_t count)\ +{ \ + struct _feat_def *_feat = dev_get_drvdata(dev); \ + unsigned long val; \ + int retval = 0; \ + \ + down(&zfcp_data.config_sema); \ + if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) { \ + retval = -EBUSY; \ + goto out; \ + } \ + \ + if (strict_strtoul(buf, 0, &val) || val != 0) { \ + retval = -EINVAL; \ + goto out; \ + } \ + \ + zfcp_erp_modify_##_feat##_status(_feat, _mod_id, NULL, \ + ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);\ + zfcp_erp_##_feat##_reopen(_feat, ZFCP_STATUS_COMMON_ERP_FAILED, \ + _reopen_id, NULL); \ + zfcp_erp_wait(_adapter); \ +out: \ + up(&zfcp_data.config_sema); \ + return retval ? retval : (ssize_t) count; \ +} \ +static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \ + zfcp_sysfs_##_feat##_failed_show, \ + zfcp_sysfs_##_feat##_failed_store); + +ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, 44, 93); +ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, 45, 96); +ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, 46, 97); + +static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_adapter *adapter = dev_get_drvdata(dev); + int ret; + + if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) + return -EBUSY; + + ret = zfcp_scan_ports(adapter); + return ret ? ret : (ssize_t) count; +} +static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, + zfcp_sysfs_port_rescan_store); + +static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_adapter *adapter = dev_get_drvdata(dev); + struct zfcp_port *port; + wwn_t wwpn; + int retval = 0; + + down(&zfcp_data.config_sema); + if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { + retval = -EBUSY; + goto out; + } + + if (strict_strtoull(buf, 0, &wwpn)) { + retval = -EINVAL; + goto out; + } + + write_lock_irq(&zfcp_data.config_lock); + port = zfcp_get_port_by_wwpn(adapter, wwpn); + if (port && (atomic_read(&port->refcount) == 0)) { + zfcp_port_get(port); + atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); + list_move(&port->list, &adapter->port_remove_lh); + } else + port = NULL; + write_unlock_irq(&zfcp_data.config_lock); + + if (!port) { + retval = -ENXIO; + goto out; + } + + zfcp_erp_port_shutdown(port, 0, 92, NULL); + zfcp_erp_wait(adapter); + zfcp_port_put(port); + zfcp_port_dequeue(port); + out: + up(&zfcp_data.config_sema); + return retval ? retval : (ssize_t) count; +} +static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL, + zfcp_sysfs_port_remove_store); + +static struct attribute *zfcp_adapter_attrs[] = { + &dev_attr_adapter_failed.attr, + &dev_attr_adapter_in_recovery.attr, + &dev_attr_adapter_port_remove.attr, + &dev_attr_adapter_port_rescan.attr, + &dev_attr_adapter_peer_wwnn.attr, + &dev_attr_adapter_peer_wwpn.attr, + &dev_attr_adapter_peer_d_id.attr, + &dev_attr_adapter_card_version.attr, + &dev_attr_adapter_lic_version.attr, + &dev_attr_adapter_status.attr, + &dev_attr_adapter_hardware_version.attr, + NULL +}; + +struct attribute_group zfcp_sysfs_adapter_attrs = { + .attrs = zfcp_adapter_attrs, +}; + +static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_port *port = dev_get_drvdata(dev); + struct zfcp_unit *unit; + fcp_lun_t fcp_lun; + int retval = -EINVAL; + + down(&zfcp_data.config_sema); + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { + retval = -EBUSY; + goto out; + } + + if (strict_strtoull(buf, 0, &fcp_lun)) + goto out; + + unit = zfcp_unit_enqueue(port, fcp_lun); + if (IS_ERR(unit)) + goto out; + + retval = 0; + + zfcp_erp_unit_reopen(unit, 0, 94, NULL); + zfcp_erp_wait(unit->port->adapter); + zfcp_unit_put(unit); +out: + up(&zfcp_data.config_sema); + return retval ? retval : (ssize_t) count; +} +static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); + +static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_port *port = dev_get_drvdata(dev); + struct zfcp_unit *unit; + fcp_lun_t fcp_lun; + int retval = 0; + + down(&zfcp_data.config_sema); + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { + retval = -EBUSY; + goto out; + } + + if (strict_strtoull(buf, 0, &fcp_lun)) { + retval = -EINVAL; + goto out; + } + + write_lock_irq(&zfcp_data.config_lock); + unit = zfcp_get_unit_by_lun(port, fcp_lun); + if (unit && (atomic_read(&unit->refcount) == 0)) { + zfcp_unit_get(unit); + atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); + list_move(&unit->list, &port->unit_remove_lh); + } else + unit = NULL; + + write_unlock_irq(&zfcp_data.config_lock); + + if (!unit) { + retval = -ENXIO; + goto out; + } + + zfcp_erp_unit_shutdown(unit, 0, 95, NULL); + zfcp_erp_wait(unit->port->adapter); + zfcp_unit_put(unit); + zfcp_unit_dequeue(unit); +out: + up(&zfcp_data.config_sema); + return retval ? retval : (ssize_t) count; +} +static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); + +static struct attribute *zfcp_port_ns_attrs[] = { + &dev_attr_port_failed.attr, + &dev_attr_port_in_recovery.attr, + &dev_attr_port_status.attr, + &dev_attr_port_access_denied.attr, + NULL +}; + +/** + * zfcp_sysfs_ns_port_attrs - sysfs attributes for nameserver + */ +struct attribute_group zfcp_sysfs_ns_port_attrs = { + .attrs = zfcp_port_ns_attrs, +}; + +static struct attribute *zfcp_port_no_ns_attrs[] = { + &dev_attr_unit_add.attr, + &dev_attr_unit_remove.attr, + &dev_attr_port_failed.attr, + &dev_attr_port_in_recovery.attr, + &dev_attr_port_status.attr, + &dev_attr_port_access_denied.attr, + NULL +}; + +/** + * zfcp_sysfs_port_attrs - sysfs attributes for all other ports + */ +struct attribute_group zfcp_sysfs_port_attrs = { + .attrs = zfcp_port_no_ns_attrs, +}; + +static struct attribute *zfcp_unit_attrs[] = { + &dev_attr_unit_failed.attr, + &dev_attr_unit_in_recovery.attr, + &dev_attr_unit_status.attr, + &dev_attr_unit_access_denied.attr, + &dev_attr_unit_access_shared.attr, + &dev_attr_unit_access_readonly.attr, + NULL +}; + +struct attribute_group zfcp_sysfs_unit_attrs = { + .attrs = zfcp_unit_attrs, +}; + +#define ZFCP_DEFINE_LATENCY_ATTR(_name) \ +static ssize_t \ +zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) { \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct zfcp_unit *unit = sdev->hostdata; \ + struct zfcp_latencies *lat = &unit->latencies; \ + struct zfcp_adapter *adapter = unit->port->adapter; \ + unsigned long flags; \ + unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \ + \ + spin_lock_irqsave(&lat->lock, flags); \ + fsum = lat->_name.fabric.sum * adapter->timer_ticks; \ + fmin = lat->_name.fabric.min * adapter->timer_ticks; \ + fmax = lat->_name.fabric.max * adapter->timer_ticks; \ + csum = lat->_name.channel.sum * adapter->timer_ticks; \ + cmin = lat->_name.channel.min * adapter->timer_ticks; \ + cmax = lat->_name.channel.max * adapter->timer_ticks; \ + cc = lat->_name.counter; \ + spin_unlock_irqrestore(&lat->lock, flags); \ + \ + do_div(fsum, 1000); \ + do_div(fmin, 1000); \ + do_div(fmax, 1000); \ + do_div(csum, 1000); \ + do_div(cmin, 1000); \ + do_div(cmax, 1000); \ + \ + return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n", \ + fmin, fmax, fsum, cmin, cmax, csum, cc); \ +} \ +static ssize_t \ +zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct zfcp_unit *unit = sdev->hostdata; \ + struct zfcp_latencies *lat = &unit->latencies; \ + unsigned long flags; \ + \ + spin_lock_irqsave(&lat->lock, flags); \ + lat->_name.fabric.sum = 0; \ + lat->_name.fabric.min = 0xFFFFFFFF; \ + lat->_name.fabric.max = 0; \ + lat->_name.channel.sum = 0; \ + lat->_name.channel.min = 0xFFFFFFFF; \ + lat->_name.channel.max = 0; \ + lat->_name.counter = 0; \ + spin_unlock_irqrestore(&lat->lock, flags); \ + \ + return (ssize_t) count; \ +} \ +static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO, \ + zfcp_sysfs_unit_##_name##_latency_show, \ + zfcp_sysfs_unit_##_name##_latency_store); + +ZFCP_DEFINE_LATENCY_ATTR(read); +ZFCP_DEFINE_LATENCY_ATTR(write); +ZFCP_DEFINE_LATENCY_ATTR(cmd); + +#define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \ +static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \ + struct device_attribute *attr,\ + char *buf) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct zfcp_unit *unit = sdev->hostdata; \ + \ + return sprintf(buf, _format, _value); \ +} \ +static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); + +ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", + unit->port->adapter->ccw_device->dev.bus_id); +ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn); +ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun); + +struct device_attribute *zfcp_sysfs_sdev_attrs[] = { + &dev_attr_fcp_lun, + &dev_attr_wwpn, + &dev_attr_hba_id, + &dev_attr_read_latency, + &dev_attr_write_latency, + &dev_attr_cmd_latency, + NULL +}; + +static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *scsi_host = dev_to_shost(dev); + struct fsf_qtcb_bottom_port *qtcb_port; + struct zfcp_adapter *adapter; + int retval; + + adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; + if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) + return -EOPNOTSUPP; + + qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL); + if (!qtcb_port) + return -ENOMEM; + + retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port); + if (!retval) + retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util, + qtcb_port->cb_util, qtcb_port->a_util); + kfree(qtcb_port); + return retval; +} +static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL); + +static int zfcp_sysfs_adapter_ex_config(struct device *dev, + struct fsf_statistics_info *stat_inf) +{ + struct Scsi_Host *scsi_host = dev_to_shost(dev); + struct fsf_qtcb_bottom_config *qtcb_config; + struct zfcp_adapter *adapter; + int retval; + + adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; + if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) + return -EOPNOTSUPP; + + qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config), + GFP_KERNEL); + if (!qtcb_config) + return -ENOMEM; + + retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config); + if (!retval) + *stat_inf = qtcb_config->stat_info; + + kfree(qtcb_config); + return retval; +} + +#define ZFCP_SHOST_ATTR(_name, _format, _arg...) \ +static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, \ + struct device_attribute *attr,\ + char *buf) \ +{ \ + struct fsf_statistics_info stat_info; \ + int retval; \ + \ + retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info); \ + if (retval) \ + return retval; \ + \ + return sprintf(buf, _format, ## _arg); \ +} \ +static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL); + +ZFCP_SHOST_ATTR(requests, "%llu %llu %llu\n", + (unsigned long long) stat_info.input_req, + (unsigned long long) stat_info.output_req, + (unsigned long long) stat_info.control_req); + +ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n", + (unsigned long long) stat_info.input_mb, + (unsigned long long) stat_info.output_mb); + +ZFCP_SHOST_ATTR(seconds_active, "%llu\n", + (unsigned long long) stat_info.seconds_act); + +struct device_attribute *zfcp_sysfs_shost_attrs[] = { + &dev_attr_utilization, + &dev_attr_requests, + &dev_attr_megabytes, + &dev_attr_seconds_active, + NULL +}; diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c deleted file mode 100644 index 3985f1f..0000000 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * zfcp device driver - * - * sysfs attributes for CCW device. - * - * Copyright IBM Corporation 2002, 2008 - */ - -#include "zfcp_ext.h" - -/** - * ZFCP_DEFINE_ADAPTER_ATTR - * @_name: name of show attribute - * @_format: format string - * @_value: value to print - * - * Generates attributes for an adapter. - */ -#define ZFCP_DEFINE_ADAPTER_ATTR(_name, _format, _value) \ -static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct zfcp_adapter *adapter; \ - \ - adapter = dev_get_drvdata(dev); \ - return sprintf(buf, _format, _value); \ -} \ - \ -static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL); - -ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status)); -ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn); -ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn); -ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id); -ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version); -ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version); -ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n", - adapter->hardware_version); -ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)); - -/** - * zfcp_sysfs_port_rescan - trigger manual port rescan - * @dev: pointer to belonging device - * @attr: pointer to struct device_attribute - * @buf: pointer to input buffer - * @count: number of bytes in buffer - */ -static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct zfcp_adapter *adapter; - int ret; - - adapter = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status)) - return -EBUSY; - - ret = zfcp_scan_ports(adapter); - - return ret ? ret : (ssize_t) count; -} -static DEVICE_ATTR(port_rescan, S_IWUSR, NULL, zfcp_sysfs_port_rescan_store); - -/** - * zfcp_sysfs_port_remove_store - remove a port from sysfs tree - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - * - * Store function of the "port_remove" attribute of an adapter. - */ -static ssize_t -zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct zfcp_adapter *adapter; - struct zfcp_port *port; - wwn_t wwpn; - char *endp; - int retval = 0; - - down(&zfcp_data.config_sema); - - adapter = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status)) { - retval = -EBUSY; - goto out; - } - - wwpn = simple_strtoull(buf, &endp, 0); - if ((endp + 1) < (buf + count)) { - retval = -EINVAL; - goto out; - } - - write_lock_irq(&zfcp_data.config_lock); - port = zfcp_get_port_by_wwpn(adapter, wwpn); - if (port && (atomic_read(&port->refcount) == 0)) { - zfcp_port_get(port); - atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); - list_move(&port->list, &adapter->port_remove_lh); - } - else { - port = NULL; - } - write_unlock_irq(&zfcp_data.config_lock); - - if (!port) { - retval = -ENXIO; - goto out; - } - - zfcp_erp_port_shutdown(port, 0, 92, NULL); - zfcp_erp_wait(adapter); - zfcp_port_put(port); - zfcp_port_dequeue(port); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -static DEVICE_ATTR(port_remove, S_IWUSR, NULL, zfcp_sysfs_port_remove_store); - -/** - * zfcp_sysfs_adapter_failed_store - failed state of adapter - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - * - * Store function of the "failed" attribute of an adapter. - * If a "0" gets written to "failed", error recovery will be - * started for the belonging adapter. - */ -static ssize_t -zfcp_sysfs_adapter_failed_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct zfcp_adapter *adapter; - unsigned int val; - char *endp; - int retval = 0; - - down(&zfcp_data.config_sema); - - adapter = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status)) { - retval = -EBUSY; - goto out; - } - - val = simple_strtoul(buf, &endp, 0); - if (((endp + 1) < (buf + count)) || (val != 0)) { - retval = -EINVAL; - goto out; - } - - zfcp_erp_modify_adapter_status(adapter, 44, NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); - zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 93, - NULL); - zfcp_erp_wait(adapter); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -/** - * zfcp_sysfs_adapter_failed_show - failed state of adapter - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * - * Show function of "failed" attribute of adapter. Will be - * "0" if adapter is working, otherwise "1". - */ -static ssize_t -zfcp_sysfs_adapter_failed_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct zfcp_adapter *adapter; - - adapter = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_adapter_failed_show, - zfcp_sysfs_adapter_failed_store); - -static struct attribute *zfcp_adapter_attrs[] = { - &dev_attr_failed.attr, - &dev_attr_in_recovery.attr, - &dev_attr_port_remove.attr, - &dev_attr_port_rescan.attr, - &dev_attr_peer_wwnn.attr, - &dev_attr_peer_wwpn.attr, - &dev_attr_peer_d_id.attr, - &dev_attr_card_version.attr, - &dev_attr_lic_version.attr, - &dev_attr_status.attr, - &dev_attr_hardware_version.attr, - NULL -}; - -static struct attribute_group zfcp_adapter_attr_group = { - .attrs = zfcp_adapter_attrs, -}; - -/** - * zfcp_sysfs_create_adapter_files - create sysfs adapter files - * @dev: pointer to belonging device - * - * Create all attributes of the sysfs representation of an adapter. - */ -int -zfcp_sysfs_adapter_create_files(struct device *dev) -{ - return sysfs_create_group(&dev->kobj, &zfcp_adapter_attr_group); -} - -/** - * zfcp_sysfs_remove_adapter_files - remove sysfs adapter files - * @dev: pointer to belonging device - * - * Remove all attributes of the sysfs representation of an adapter. - */ -void -zfcp_sysfs_adapter_remove_files(struct device *dev) -{ - sysfs_remove_group(&dev->kobj, &zfcp_adapter_attr_group); -} diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c deleted file mode 100644 index e183ff8..0000000 --- a/drivers/s390/scsi/zfcp_sysfs_port.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * zfcp device driver - * - * sysfs attributes for zfcp port. - * - * Copyright IBM Corporation 2002, 2008 - */ - -#include "zfcp_ext.h" - -/** - * zfcp_sysfs_port_release - gets called when a struct device port is released - * @dev: pointer to belonging device - */ -void -zfcp_sysfs_port_release(struct device *dev) -{ - kfree(dev); -} - -/** - * ZFCP_DEFINE_PORT_ATTR - * @_name: name of show attribute - * @_format: format string - * @_value: value to print - * - * Generates attributes for a port. - */ -#define ZFCP_DEFINE_PORT_ATTR(_name, _format, _value) \ -static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct zfcp_port *port; \ - \ - port = dev_get_drvdata(dev); \ - return sprintf(buf, _format, _value); \ -} \ - \ -static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_port_##_name##_show, NULL); - -ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status)); -ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)); -ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask - (ZFCP_STATUS_COMMON_ACCESS_DENIED, &port->status)); - -/** - * zfcp_sysfs_unit_add_store - add a unit to sysfs tree - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - * - * Store function of the "unit_add" attribute of a port. - */ -static ssize_t -zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - fcp_lun_t fcp_lun; - char *endp; - struct zfcp_port *port; - struct zfcp_unit *unit; - int retval = -EINVAL; - - down(&zfcp_data.config_sema); - - port = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) { - retval = -EBUSY; - goto out; - } - - fcp_lun = simple_strtoull(buf, &endp, 0); - if ((endp + 1) < (buf + count)) - goto out; - - unit = zfcp_unit_enqueue(port, fcp_lun); - if (IS_ERR(unit)) - goto out; - - retval = 0; - - zfcp_erp_unit_reopen(unit, 0, 94, NULL); - zfcp_erp_wait(unit->port->adapter); - zfcp_unit_put(unit); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); - -/** - * zfcp_sysfs_unit_remove_store - remove a unit from sysfs tree - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - */ -static ssize_t -zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct zfcp_port *port; - struct zfcp_unit *unit; - fcp_lun_t fcp_lun; - char *endp; - int retval = 0; - - down(&zfcp_data.config_sema); - - port = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) { - retval = -EBUSY; - goto out; - } - - fcp_lun = simple_strtoull(buf, &endp, 0); - if ((endp + 1) < (buf + count)) { - retval = -EINVAL; - goto out; - } - - write_lock_irq(&zfcp_data.config_lock); - unit = zfcp_get_unit_by_lun(port, fcp_lun); - if (unit && (atomic_read(&unit->refcount) == 0)) { - zfcp_unit_get(unit); - atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); - list_move(&unit->list, &port->unit_remove_lh); - } - else { - unit = NULL; - } - write_unlock_irq(&zfcp_data.config_lock); - - if (!unit) { - retval = -ENXIO; - goto out; - } - - zfcp_erp_unit_shutdown(unit, 0, 95, NULL); - zfcp_erp_wait(unit->port->adapter); - zfcp_unit_put(unit); - zfcp_unit_dequeue(unit); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); - -/** - * zfcp_sysfs_port_failed_store - failed state of port - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - * - * Store function of the "failed" attribute of a port. - * If a "0" gets written to "failed", error recovery will be - * started for the belonging port. - */ -static ssize_t -zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct zfcp_port *port; - unsigned int val; - char *endp; - int retval = 0; - - down(&zfcp_data.config_sema); - - port = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) { - retval = -EBUSY; - goto out; - } - - val = simple_strtoul(buf, &endp, 0); - if (((endp + 1) < (buf + count)) || (val != 0)) { - retval = -EINVAL; - goto out; - } - - zfcp_erp_modify_port_status(port, 45, NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); - zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 96, NULL); - zfcp_erp_wait(port->adapter); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -/** - * zfcp_sysfs_port_failed_show - failed state of port - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * - * Show function of "failed" attribute of port. Will be - * "0" if port is working, otherwise "1". - */ -static ssize_t -zfcp_sysfs_port_failed_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct zfcp_port *port; - - port = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_port_failed_show, - zfcp_sysfs_port_failed_store); - -/** - * zfcp_port_common_attrs - * sysfs attributes that are common for all kind of fc ports. - */ -static struct attribute *zfcp_port_common_attrs[] = { - &dev_attr_failed.attr, - &dev_attr_in_recovery.attr, - &dev_attr_status.attr, - &dev_attr_access_denied.attr, - NULL -}; - -static struct attribute_group zfcp_port_common_attr_group = { - .attrs = zfcp_port_common_attrs, -}; - -/** - * zfcp_port_no_ns_attrs - * sysfs attributes not to be used for nameserver ports. - */ -static struct attribute *zfcp_port_no_ns_attrs[] = { - &dev_attr_unit_add.attr, - &dev_attr_unit_remove.attr, - NULL -}; - -static struct attribute_group zfcp_port_no_ns_attr_group = { - .attrs = zfcp_port_no_ns_attrs, -}; - -/** - * zfcp_sysfs_port_create_files - create sysfs port files - * @dev: pointer to belonging device - * - * Create all attributes of the sysfs representation of a port. - */ -int -zfcp_sysfs_port_create_files(struct device *dev, u32 flags) -{ - int retval; - - retval = sysfs_create_group(&dev->kobj, &zfcp_port_common_attr_group); - - if ((flags & ZFCP_STATUS_PORT_WKA) || retval) - return retval; - - retval = sysfs_create_group(&dev->kobj, &zfcp_port_no_ns_attr_group); - if (retval) - sysfs_remove_group(&dev->kobj, &zfcp_port_common_attr_group); - - return retval; -} - -/** - * zfcp_sysfs_port_remove_files - remove sysfs port files - * @dev: pointer to belonging device - * - * Remove all attributes of the sysfs representation of a port. - */ -void -zfcp_sysfs_port_remove_files(struct device *dev, u32 flags) -{ - sysfs_remove_group(&dev->kobj, &zfcp_port_common_attr_group); - if (!(flags & ZFCP_STATUS_PORT_WKA)) - sysfs_remove_group(&dev->kobj, &zfcp_port_no_ns_attr_group); -} diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c deleted file mode 100644 index 587d9e3..0000000 --- a/drivers/s390/scsi/zfcp_sysfs_unit.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * zfcp device driver - * - * sysfs interface for zfcp unit. - * - * Copyright IBM Corporation 2002, 2008 - */ - -#include "zfcp_ext.h" - -/** - * zfcp_sysfs_unit_release - gets called when a struct device unit is released - * @dev: pointer to belonging device - */ -void -zfcp_sysfs_unit_release(struct device *dev) -{ - kfree(dev); -} - -/** - * ZFCP_DEFINE_UNIT_ATTR - * @_name: name of show attribute - * @_format: format string - * @_value: value to print - * - * Generates attribute for a unit. - */ -#define ZFCP_DEFINE_UNIT_ATTR(_name, _format, _value) \ -static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct zfcp_unit *unit; \ - \ - unit = dev_get_drvdata(dev); \ - return sprintf(buf, _format, _value); \ -} \ - \ -static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_unit_##_name##_show, NULL); - -ZFCP_DEFINE_UNIT_ATTR(status, "0x%08x\n", atomic_read(&unit->status)); -ZFCP_DEFINE_UNIT_ATTR(in_recovery, "%d\n", atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)); -ZFCP_DEFINE_UNIT_ATTR(access_denied, "%d\n", atomic_test_mask - (ZFCP_STATUS_COMMON_ACCESS_DENIED, &unit->status)); -ZFCP_DEFINE_UNIT_ATTR(access_shared, "%d\n", atomic_test_mask - (ZFCP_STATUS_UNIT_SHARED, &unit->status)); -ZFCP_DEFINE_UNIT_ATTR(access_readonly, "%d\n", atomic_test_mask - (ZFCP_STATUS_UNIT_READONLY, &unit->status)); - -/** - * zfcp_sysfs_unit_failed_store - failed state of unit - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * @count: number of bytes in buffer - * - * Store function of the "failed" attribute of a unit. - * If a "0" gets written to "failed", error recovery will be - * started for the belonging unit. - */ -static ssize_t -zfcp_sysfs_unit_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct zfcp_unit *unit; - unsigned int val; - char *endp; - int retval = 0; - - down(&zfcp_data.config_sema); - unit = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status)) { - retval = -EBUSY; - goto out; - } - - val = simple_strtoul(buf, &endp, 0); - if (((endp + 1) < (buf + count)) || (val != 0)) { - retval = -EINVAL; - goto out; - } - - zfcp_erp_modify_unit_status(unit, 46, NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); - zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, 97, NULL); - zfcp_erp_wait(unit->port->adapter); - out: - up(&zfcp_data.config_sema); - return retval ? retval : (ssize_t) count; -} - -/** - * zfcp_sysfs_unit_failed_show - failed state of unit - * @dev: pointer to belonging device - * @buf: pointer to input buffer - * - * Show function of "failed" attribute of unit. Will be - * "0" if unit is working, otherwise "1". - */ -static ssize_t -zfcp_sysfs_unit_failed_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct zfcp_unit *unit; - - unit = dev_get_drvdata(dev); - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "0\n"); -} - -static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_unit_failed_show, - zfcp_sysfs_unit_failed_store); - -static struct attribute *zfcp_unit_attrs[] = { - &dev_attr_failed.attr, - &dev_attr_in_recovery.attr, - &dev_attr_status.attr, - &dev_attr_access_denied.attr, - &dev_attr_access_shared.attr, - &dev_attr_access_readonly.attr, - NULL -}; - -static struct attribute_group zfcp_unit_attr_group = { - .attrs = zfcp_unit_attrs, -}; - -/** - * zfcp_sysfs_create_unit_files - create sysfs unit files - * @dev: pointer to belonging device - * - * Create all attributes of the sysfs representation of a unit. - */ -int -zfcp_sysfs_unit_create_files(struct device *dev) -{ - return sysfs_create_group(&dev->kobj, &zfcp_unit_attr_group); -} - -/** - * zfcp_sysfs_remove_unit_files - remove sysfs unit files - * @dev: pointer to belonging device - * - * Remove all attributes of the sysfs representation of a unit. - */ -void -zfcp_sysfs_unit_remove_files(struct device *dev) -{ - sysfs_remove_group(&dev->kobj, &zfcp_unit_attr_group); -} -- cgit v0.10.2 From c41f8cbddd4e0e72951e0575165dea8ea26f1c4b Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 2 Jul 2008 10:56:39 +0200 Subject: [SCSI] zfcp: zfcp_fsf cleanup. Code cleanup for the zfcp_fsf.c file. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 5b9ca3c..90abfd0 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -433,7 +433,7 @@ static void zfcp_dummy_release(struct device *dev) int zfcp_status_read_refill(struct zfcp_adapter *adapter) { while (atomic_read(&adapter->stat_miss) > 0) - if (zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL)) { + if (zfcp_fsf_status_read(adapter)) { if (atomic_read(&adapter->stat_miss) >= 16) { zfcp_erp_adapter_reopen(adapter, 0, 103, NULL); return 1; @@ -518,10 +518,10 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) spin_lock_init(&adapter->san_dbf_lock); spin_lock_init(&adapter->scsi_dbf_lock); spin_lock_init(&adapter->rec_dbf_lock); + spin_lock_init(&adapter->req_q.lock); rwlock_init(&adapter->erp_lock); rwlock_init(&adapter->abort_lock); - rwlock_init(&adapter->req_q.lock); sema_init(&adapter->erp_ready_sem, 0); diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 566627f..36169c6 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -961,7 +961,7 @@ void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) zfcp_san_dbf_event_els("iels", 1, fsf_req, buf->d_id, fc_host_port_id(adapter->scsi_host), - *(u8 *)buf->payload, (void *)buf->payload, + buf->payload.data[0], (void *)buf->payload.data, length); } diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 2af043a..206b6e7 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -76,11 +76,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) #define ZFCP_DEVICE_MODEL 0x03 #define ZFCP_DEVICE_MODEL_PRIV 0x04 -/* allow as many chained SBALs as are supported by hardware */ -#define ZFCP_MAX_SBALS_PER_REQ FSF_MAX_SBALS_PER_REQ -#define ZFCP_MAX_SBALS_PER_CT_REQ FSF_MAX_SBALS_PER_REQ -#define ZFCP_MAX_SBALS_PER_ELS_REQ FSF_MAX_SBALS_PER_ELS_REQ - /* DMQ bug workaround: don't use last SBALE */ #define ZFCP_MAX_SBALES_PER_SBAL (QDIO_MAX_ELEMENTS_PER_BUFFER - 1) @@ -89,21 +84,17 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) /* max. number of (data buffer) SBALEs in largest SBAL chain */ #define ZFCP_MAX_SBALES_PER_REQ \ - (ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) + (FSF_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ #define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8) /* max. number of (data buffer) SBALEs in largest SBAL chain multiplied with number of sectors per 4k block */ -#define ZFCP_SBAL_TIMEOUT (5*HZ) - #define ZFCP_TYPE2_RECOVERY_TIME 8 /* seconds */ /********************* FSF SPECIFIC DEFINES *********************************/ -#define ZFCP_ULP_INFO_VERSION 26 -#define ZFCP_QTCB_VERSION FSF_QTCB_CURRENT_VERSION /* ATTENTION: value must not be used by hardware */ #define FSF_QTCB_UNSOLICITED_STATUS 0x6305 @@ -121,8 +112,6 @@ typedef unsigned long long fcp_lun_t; /* data length field may be at variable position in FCP-2 FCP_CMND IU */ typedef unsigned int fcp_dl_t; -#define ZFCP_FC_SERVICE_CLASS_DEFAULT FSF_CLASS_3 - /* timeout for name-server lookup (in seconds) */ #define ZFCP_NS_GID_PN_TIMEOUT 10 @@ -228,7 +217,6 @@ struct fcp_logo { * FC-FS stuff */ #define R_A_TOV 10 /* seconds */ -#define ZFCP_ELS_TIMEOUT (2 * R_A_TOV) #define ZFCP_LS_RLS 0x0f #define ZFCP_LS_ADISC 0x52 @@ -521,7 +509,7 @@ struct zfcp_qdio_queue { in queue (free_count>0) */ atomic_t count; /* number of free buffers in queue */ - rwlock_t lock; /* lock for operations on queue */ + spinlock_t lock; /* lock for operations on queue */ int pci_batch; /* SBALs since PCI indication was last set */ }; @@ -686,7 +674,7 @@ struct zfcp_fsf_req { u32 fsf_command; /* FSF Command copy */ struct fsf_qtcb *qtcb; /* address of associated QTCB */ u32 seq_no; /* Sequence number of request */ - unsigned long data; /* private data of request */ + void *data; /* private data of request */ struct timer_list timer; /* used for erp or scsi er */ struct zfcp_erp_action *erp_action; /* used if this request is issued on behalf of erp */ @@ -694,10 +682,9 @@ struct zfcp_fsf_req { from emergency pool */ unsigned long long issued; /* request sent time (STCK) */ struct zfcp_unit *unit; + void (*handler)(struct zfcp_fsf_req *); }; -typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*); - /* driver data */ struct zfcp_data { struct scsi_host_template scsi_host_template; @@ -730,7 +717,6 @@ struct zfcp_fsf_req_qtcb { /********************** ZFCP SPECIFIC DEFINES ********************************/ #define ZFCP_REQ_AUTO_CLEANUP 0x00000002 -#define ZFCP_WAIT_FOR_SBAL 0x00000004 #define ZFCP_REQ_NO_QTCB 0x00000008 #define ZFCP_SET 0x00000100 @@ -753,15 +739,6 @@ static inline int zfcp_reqlist_hash(unsigned long req_id) return req_id % REQUEST_LIST_SIZE; } -static inline void zfcp_reqlist_add(struct zfcp_adapter *adapter, - struct zfcp_fsf_req *fsf_req) -{ - unsigned int idx; - - idx = zfcp_reqlist_hash(fsf_req->req_id); - list_add_tail(&fsf_req->list, &adapter->req_list[idx]); -} - static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter, struct zfcp_fsf_req *fsf_req) { diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index f0d6947..2845693 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -70,21 +70,19 @@ extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); -extern int zfcp_fsf_status_read(struct zfcp_adapter *, int); +extern int zfcp_fsf_status_read(struct zfcp_adapter *); extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); -extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *, - unsigned long *, struct zfcp_fsf_req **) - __acquires(adapter->req_q.lock); extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, struct zfcp_erp_action *); extern int zfcp_fsf_send_els(struct zfcp_send_els *); extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *, struct zfcp_unit *, struct scsi_cmnd *, int, int); -extern int zfcp_fsf_req_complete(struct zfcp_fsf_req *); +extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *); extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); -extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_command_task_management( - struct zfcp_adapter *, struct zfcp_unit *, u8, int); +extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *, + struct zfcp_unit *, u8, + int); extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command( unsigned long, struct zfcp_adapter *, struct zfcp_unit *, int); diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index fbe2c76..e984469 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -83,8 +83,8 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) u16 no_entries; u32 range_mask; - fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload; - fcp_rscn_element = (struct fcp_rscn_element *) status_buffer->payload; + fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload.data; + fcp_rscn_element = (struct fcp_rscn_element *) fcp_rscn_head; /* see FC-FS */ no_entries = fcp_rscn_head->payload_len / @@ -135,7 +135,7 @@ static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) struct fsf_status_read_buffer *status_buffer = (struct fsf_status_read_buffer *)req->data; struct fsf_plogi *els_plogi = - (struct fsf_plogi *) status_buffer->payload; + (struct fsf_plogi *) status_buffer->payload.data; zfcp_fc_incoming_wwpn(req, els_plogi->serv_param.wwpn); } @@ -144,7 +144,8 @@ static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req) { struct fsf_status_read_buffer *status_buffer = (struct fsf_status_read_buffer *)req->data; - struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload; + struct fcp_logo *els_logo = + (struct fcp_logo *) status_buffer->payload.data; zfcp_fc_incoming_wwpn(req, els_logo->nport_wwpn); } @@ -157,7 +158,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) { struct fsf_status_read_buffer *status_buffer = (struct fsf_status_read_buffer *) fsf_req->data; - unsigned int els_type = status_buffer->payload[0]; + unsigned int els_type = status_buffer->payload.data[0]; zfcp_san_dbf_event_incoming_els(fsf_req); if (els_type == LS_PLOGI) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 22e3aa6..e6d8155 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -8,35 +8,6 @@ #include "zfcp_ext.h" -static int zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *); -static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_open_port_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_close_port_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_send_fcp_command_task_management_handler( - struct zfcp_fsf_req *); -static int zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_status_read_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *); -static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *); -static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *); -static inline int zfcp_fsf_req_sbal_check( - unsigned long *, struct zfcp_qdio_queue *, int); -static inline int zfcp_use_one_sbal( - struct scatterlist *, int, struct scatterlist *, int); -static struct zfcp_fsf_req *zfcp_fsf_req_alloc(mempool_t *, int); -static int zfcp_fsf_req_send(struct zfcp_fsf_req *); -static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *); -static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *); -static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *); -static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *, u8, - struct fsf_link_down_info *); -static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); - /* association between FSF command and FSF QTCB type */ static u32 fsf_qtcb_type[] = { [FSF_QTCB_FCP_CMND] = FSF_IO_COMMAND, @@ -54,21 +25,19 @@ static u32 fsf_qtcb_type[] = { [FSF_QTCB_UPLOAD_CONTROL_FILE] = FSF_SUPPORT_COMMAND }; -static const char zfcp_act_subtable_type[5][8] = { +static const char *zfcp_act_subtable_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" }; static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) { - u16 subtable = (table & 0xffff0000) >> 16; + u16 subtable = table >> 16; u16 rule = table & 0xffff; - if (subtable > 0 && - subtable < ARRAY_SIZE(zfcp_act_subtable_type)) { + if (subtable && subtable < ARRAY_SIZE(zfcp_act_subtable_type)) dev_warn(&adapter->ccw_device->dev, "Access denied in subtable %s, rule %d.\n", zfcp_act_subtable_type[subtable], rule); - } } static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, @@ -106,90 +75,27 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; } -/****************************************************************/ -/*************** FSF related Functions *************************/ -/****************************************************************/ - -/* - * function: zfcp_fsf_req_alloc - * - * purpose: Obtains an fsf_req and potentially a qtcb (for all but - * unsolicited requests) via helper functions - * Does some initial fsf request set-up. - * - * returns: pointer to allocated fsf_req if successfull - * NULL otherwise - * - * locks: none - * - */ -static struct zfcp_fsf_req * -zfcp_fsf_req_alloc(mempool_t *pool, int req_flags) -{ - size_t size; - void *ptr; - struct zfcp_fsf_req *fsf_req = NULL; - - if (req_flags & ZFCP_REQ_NO_QTCB) - size = sizeof(struct zfcp_fsf_req); - else - size = sizeof(struct zfcp_fsf_req_qtcb); - - if (likely(pool)) - ptr = mempool_alloc(pool, GFP_ATOMIC); - else { - if (req_flags & ZFCP_REQ_NO_QTCB) - ptr = kmalloc(size, GFP_ATOMIC); - else - ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache, - GFP_ATOMIC); - } - - if (unlikely(!ptr)) - goto out; - - memset(ptr, 0, size); - - if (req_flags & ZFCP_REQ_NO_QTCB) { - fsf_req = (struct zfcp_fsf_req *) ptr; - } else { - fsf_req = &((struct zfcp_fsf_req_qtcb *) ptr)->fsf_req; - fsf_req->qtcb = &((struct zfcp_fsf_req_qtcb *) ptr)->qtcb; - } - - fsf_req->pool = pool; - - out: - return fsf_req; -} - -/* - * function: zfcp_fsf_req_free - * - * purpose: Frees the memory of an fsf_req (and potentially a qtcb) or - * returns it into the pool via helper functions. - * - * returns: sod all - * - * locks: none +/** + * zfcp_fsf_req_free - free memory used by fsf request + * @fsf_req: pointer to struct zfcp_fsf_req */ -void -zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) +void zfcp_fsf_req_free(struct zfcp_fsf_req *req) { - if (likely(fsf_req->pool)) { - mempool_free(fsf_req, fsf_req->pool); + if (likely(req->pool)) { + mempool_free(req, req->pool); return; } - if (fsf_req->qtcb) { - kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, fsf_req); + if (req->qtcb) { + kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, req); return; } - - kfree(fsf_req); } -/* +/** + * zfcp_fsf_req_dismiss_all - dismiss all fsf requests + * @adapter: pointer to struct zfcp_adapter + * * Never ever call this without shutting down the adapter first. * Otherwise the adapter would continue using and corrupting s390 storage. * Included BUG_ON() call to ensure this is done. @@ -197,1815 +103,1359 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) */ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) { - struct zfcp_fsf_req *fsf_req, *tmp; + struct zfcp_fsf_req *req, *tmp; unsigned long flags; LIST_HEAD(remove_queue); unsigned int i; - BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)); + BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP); spin_lock_irqsave(&adapter->req_list_lock, flags); for (i = 0; i < REQUEST_LIST_SIZE; i++) list_splice_init(&adapter->req_list[i], &remove_queue); spin_unlock_irqrestore(&adapter->req_list_lock, flags); - list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) { - list_del(&fsf_req->list); - fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; - zfcp_fsf_req_complete(fsf_req); - } -} - -/* - * function: zfcp_fsf_req_complete - * - * purpose: Updates active counts and timers for openfcp-reqs - * May cleanup request after req_eval returns - * - * returns: 0 - success - * !0 - failure - * - * context: - */ -int -zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) -{ - int retval = 0; - int cleanup; - - if (unlikely(fsf_req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) { - /* - * Note: all cleanup handling is done in the callchain of - * the function call-chain below. - */ - zfcp_fsf_status_read_handler(fsf_req); - goto out; - } else { - del_timer(&fsf_req->timer); - zfcp_fsf_protstatus_eval(fsf_req); - } - - /* - * fsf_req may be deleted due to waking up functions, so - * cleanup is saved here and used later - */ - if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) - cleanup = 1; - else - cleanup = 0; - - fsf_req->status |= ZFCP_STATUS_FSFREQ_COMPLETED; - - /* cleanup request if requested by initiator */ - if (likely(cleanup)) { - /* - * lock must not be held here since it will be - * grabed by the called routine, too - */ - zfcp_fsf_req_free(fsf_req); - } else { - /* notify initiator waiting for the requests completion */ - /* - * FIXME: Race! We must not access fsf_req here as it might have been - * cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED - * flag. It's an improbable case. But, we have the same paranoia for - * the cleanup flag already. - * Might better be handled using complete()? - * (setting the flag and doing wakeup ought to be atomic - * with regard to checking the flag as long as waitqueue is - * part of the to be released structure) - */ - wake_up(&fsf_req->completion_wq); - } - - out: - return retval; -} - -/* - * function: zfcp_fsf_protstatus_eval - * - * purpose: evaluates the QTCB of the finished FSF request - * and initiates appropriate actions - * (usually calling FSF command specific handlers) - * - * returns: - * - * context: - * - * locks: - */ -static int -zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) -{ - int retval = 0; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fsf_qtcb *qtcb = fsf_req->qtcb; - union fsf_prot_status_qual *prot_status_qual = - &qtcb->prefix.prot_status_qual; - - zfcp_hba_dbf_event_fsf_response(fsf_req); - - if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | - ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ - goto skip_protstatus; - } - - /* evaluate FSF Protocol Status */ - switch (qtcb->prefix.prot_status) { - - case FSF_PROT_GOOD: - case FSF_PROT_FSF_STATUS_PRESENTED: - break; - - case FSF_PROT_QTCB_VERSION_ERROR: - dev_err(&adapter->ccw_device->dev, - "The QTCB version requested by zfcp (0x%x) is not " - "supported by the FCP adapter (lowest supported 0x%x, " - "highest supported 0x%x).\n", - ZFCP_QTCB_VERSION, prot_status_qual->word[0], - prot_status_qual->word[1]); - zfcp_erp_adapter_shutdown(adapter, 0, 117, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PROT_SEQ_NUMB_ERROR: - zfcp_erp_adapter_reopen(adapter, 0, 98, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PROT_UNSUPP_QTCB_TYPE: - dev_err(&adapter->ccw_device->dev, - "Packet header type used by the device driver is " - "incompatible with that used on the adapter.\n"); - zfcp_erp_adapter_shutdown(adapter, 0, 118, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PROT_HOST_CONNECTION_INITIALIZING: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, - &(adapter->status)); - break; - - case FSF_PROT_DUPLICATE_REQUEST_ID: - dev_err(&adapter->ccw_device->dev, - "The request identifier 0x%Lx is ambiguous.\n", - (unsigned long long)qtcb->bottom.support.req_handle); - zfcp_erp_adapter_shutdown(adapter, 0, 78, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PROT_LINK_DOWN: - zfcp_fsf_link_down_info_eval(fsf_req, 37, - &prot_status_qual->link_down_info); - /* FIXME: reopening adapter now? better wait for link up */ - zfcp_erp_adapter_reopen(adapter, 0, 79, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PROT_REEST_QUEUE: - /* All ports should be marked as ready to run again */ - zfcp_erp_modify_adapter_status(adapter, 28, NULL, - ZFCP_STATUS_COMMON_RUNNING, - ZFCP_SET); - zfcp_erp_adapter_reopen(adapter, - ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED - | ZFCP_STATUS_COMMON_ERP_FAILED, - 99, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PROT_ERROR_STATE: - zfcp_erp_adapter_reopen(adapter, 0, 100, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - default: - dev_err(&adapter->ccw_device->dev, - "Transfer protocol status information" - "provided by the adapter (0x%x) " - "is not compatible with the device driver.\n", - qtcb->prefix.prot_status); - zfcp_erp_adapter_shutdown(adapter, 0, 119, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + list_for_each_entry_safe(req, tmp, &remove_queue, list) { + list_del(&req->list); + req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; + zfcp_fsf_req_complete(req); } - - skip_protstatus: - /* - * always call specific handlers to give them a chance to do - * something meaningful even in error cases - */ - zfcp_fsf_fsfstatus_eval(fsf_req); - return retval; } -/* - * function: zfcp_fsf_fsfstatus_eval - * - * purpose: evaluates FSF status of completed FSF request - * and acts accordingly - * - * returns: - */ -static int -zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) { - int retval = 0; - - if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { - goto skip_fsfstatus; - } - - /* evaluate FSF Status */ - switch (fsf_req->qtcb->header.fsf_status) { - case FSF_UNKNOWN_COMMAND: - dev_err(&fsf_req->adapter->ccw_device->dev, - "Command issued by the device driver (0x%x) is " - "not known by the adapter.\n", - fsf_req->qtcb->header.fsf_command); - zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 120, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_ADAPTER_STATUS_AVAILABLE: - zfcp_fsf_fsfstatus_qual_eval(fsf_req); - break; - } - - skip_fsfstatus: - /* - * always call specific handlers to give them a chance to do - * something meaningful even in error cases - */ - zfcp_fsf_req_dispatch(fsf_req); + struct fsf_status_read_buffer *sr_buf = req->data; + struct zfcp_adapter *adapter = req->adapter; + struct zfcp_port *port; + int d_id = sr_buf->d_id & ZFCP_DID_MASK; + unsigned long flags; - return retval; + read_lock_irqsave(&zfcp_data.config_lock, flags); + list_for_each_entry(port, &adapter->port_list_head, list) + if (port->d_id == d_id) { + read_unlock_irqrestore(&zfcp_data.config_lock, flags); + switch (sr_buf->status_subtype) { + case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT: + zfcp_erp_port_reopen(port, 0, 101, req); + break; + case FSF_STATUS_READ_SUB_ERROR_PORT: + zfcp_erp_port_shutdown(port, 0, 122, req); + break; + } + return; + } + read_unlock_irqrestore(&zfcp_data.config_lock, flags); } -/* - * function: zfcp_fsf_fsfstatus_qual_eval - * - * purpose: evaluates FSF status-qualifier of completed FSF request - * and acts accordingly - * - * returns: - */ -static int -zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_bit_error_threshold(struct zfcp_fsf_req *req) { - int retval = 0; - - switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { - case FSF_SQ_FCP_RSP_AVAILABLE: - break; - case FSF_SQ_RETRY_IF_POSSIBLE: - /* The SCSI-stack may now issue retries or escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - case FSF_SQ_COMMAND_ABORTED: - /* Carry the aborted state on to upper layer */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED; - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - case FSF_SQ_NO_RECOM: - dev_err(&fsf_req->adapter->ccw_device->dev, - "No recommendation could be given for a " - "problem on the adapter.\n"); - zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 121, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - case FSF_SQ_ULP_PROGRAMMING_ERROR: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - case FSF_SQ_NO_RETRY_POSSIBLE: - case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* dealt with in the respective functions */ - break; - default: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - } + struct zfcp_adapter *adapter = req->adapter; + struct fsf_status_read_buffer *sr_buf = req->data; + struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error; - return retval; + dev_warn(&adapter->ccw_device->dev, + "Warning: bit error threshold data " + "received for the adapter: " + "link failures = %i, loss of sync errors = %i, " + "loss of signal errors = %i, " + "primitive sequence errors = %i, " + "invalid transmission word errors = %i, " + "CRC errors = %i).\n", + err->link_failure_error_count, + err->loss_of_sync_error_count, + err->loss_of_signal_error_count, + err->primitive_sequence_error_count, + err->invalid_transmission_word_error_count, + err->crc_error_count); + dev_warn(&adapter->ccw_device->dev, + "Additional bit error threshold data of the adapter: " + "primitive sequence event time-outs = %i, " + "elastic buffer overrun errors = %i, " + "advertised receive buffer-to-buffer credit = %i, " + "current receice buffer-to-buffer credit = %i, " + "advertised transmit buffer-to-buffer credit = %i, " + "current transmit buffer-to-buffer credit = %i).\n", + err->primitive_sequence_event_timeout_count, + err->elastic_buffer_overrun_error_count, + err->advertised_receive_b2b_credit, + err->current_receive_b2b_credit, + err->advertised_transmit_b2b_credit, + err->current_transmit_b2b_credit); } -/** - * zfcp_fsf_link_down_info_eval - evaluate link down information block - */ -static void -zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *fsf_req, u8 id, - struct fsf_link_down_info *link_down) +static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id, + struct fsf_link_down_info *link_down) { - struct zfcp_adapter *adapter = fsf_req->adapter; + struct zfcp_adapter *adapter = req->adapter; - if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, - &adapter->status)) + if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED) return; atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); - if (link_down == NULL) + if (!link_down) goto out; switch (link_down->error_code) { case FSF_PSQ_LINK_NO_LIGHT: - dev_warn(&fsf_req->adapter->ccw_device->dev, - "The local link is down: " - "no light detected.\n"); + dev_warn(&req->adapter->ccw_device->dev, + "The local link is down: no light detected.\n"); break; case FSF_PSQ_LINK_WRAP_PLUG: - dev_warn(&fsf_req->adapter->ccw_device->dev, - "The local link is down: " - "wrap plug detected.\n"); + dev_warn(&req->adapter->ccw_device->dev, + "The local link is down: wrap plug detected.\n"); break; case FSF_PSQ_LINK_NO_FCP: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "adjacent node on link does not support FCP.\n"); break; case FSF_PSQ_LINK_FIRMWARE_UPDATE: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "firmware update in progress.\n"); break; case FSF_PSQ_LINK_INVALID_WWPN: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "duplicate or invalid WWPN detected.\n"); break; case FSF_PSQ_LINK_NO_NPIV_SUPPORT: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "no support for NPIV by Fabric.\n"); break; case FSF_PSQ_LINK_NO_FCP_RESOURCES: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "out of resource in FCP daughtercard.\n"); break; case FSF_PSQ_LINK_NO_FABRIC_RESOURCES: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "out of resource in Fabric.\n"); break; case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link is down: " "unable to login to Fabric.\n"); break; case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "WWPN assignment file corrupted on adapter.\n"); break; case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "Mode table corrupted on adapter.\n"); break; case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "No WWPN for assignment table on adapter.\n"); break; default: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The local link to adapter is down.\n"); } - - out: - zfcp_erp_adapter_failed(adapter, id, fsf_req); +out: + zfcp_erp_adapter_failed(adapter, id, req); } -/* - * function: zfcp_fsf_req_dispatch - * - * purpose: calls the appropriate command specific handler - * - * returns: - */ -static int -zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req) { - struct zfcp_erp_action *erp_action = fsf_req->erp_action; - int retval = 0; - - - switch (fsf_req->fsf_command) { - - case FSF_QTCB_FCP_CMND: - zfcp_fsf_send_fcp_command_handler(fsf_req); - break; - - case FSF_QTCB_ABORT_FCP_CMND: - zfcp_fsf_abort_fcp_command_handler(fsf_req); - break; - - case FSF_QTCB_SEND_GENERIC: - zfcp_fsf_send_ct_handler(fsf_req); - break; + struct zfcp_adapter *adapter = req->adapter; + struct fsf_status_read_buffer *sr_buf = req->data; + struct fsf_link_down_info *ldi = + (struct fsf_link_down_info *) &sr_buf->payload; - case FSF_QTCB_OPEN_PORT_WITH_DID: - zfcp_fsf_open_port_handler(fsf_req); + switch (sr_buf->status_subtype) { + case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: + dev_warn(&adapter->ccw_device->dev, + "Physical link is down.\n"); + zfcp_fsf_link_down_info_eval(req, 38, ldi); break; - - case FSF_QTCB_OPEN_LUN: - zfcp_fsf_open_unit_handler(fsf_req); + case FSF_STATUS_READ_SUB_FDISC_FAILED: + dev_warn(&adapter->ccw_device->dev, + "Local link is down " + "due to failed FDISC login.\n"); + zfcp_fsf_link_down_info_eval(req, 39, ldi); break; + case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: + dev_warn(&adapter->ccw_device->dev, + "Local link is down " + "due to firmware update on adapter.\n"); + zfcp_fsf_link_down_info_eval(req, 40, NULL); + }; +} - case FSF_QTCB_CLOSE_LUN: - zfcp_fsf_close_unit_handler(fsf_req); - break; +static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) +{ + struct zfcp_adapter *adapter = req->adapter; + struct fsf_status_read_buffer *sr_buf = req->data; - case FSF_QTCB_CLOSE_PORT: - zfcp_fsf_close_port_handler(fsf_req); - break; + if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { + zfcp_hba_dbf_event_fsf_unsol("dism", adapter, sr_buf); + mempool_free(sr_buf, adapter->pool.data_status_read); + zfcp_fsf_req_free(req); + return; + } - case FSF_QTCB_CLOSE_PHYSICAL_PORT: - zfcp_fsf_close_physical_port_handler(fsf_req); - break; + zfcp_hba_dbf_event_fsf_unsol("read", adapter, sr_buf); - case FSF_QTCB_EXCHANGE_CONFIG_DATA: - zfcp_fsf_exchange_config_data_handler(fsf_req); + switch (sr_buf->status_type) { + case FSF_STATUS_READ_PORT_CLOSED: + zfcp_fsf_status_read_port_closed(req); break; - - case FSF_QTCB_EXCHANGE_PORT_DATA: - zfcp_fsf_exchange_port_data_handler(fsf_req); + case FSF_STATUS_READ_INCOMING_ELS: + zfcp_fc_incoming_els(req); break; - - case FSF_QTCB_SEND_ELS: - zfcp_fsf_send_els_handler(fsf_req); + case FSF_STATUS_READ_SENSE_DATA_AVAIL: break; - - case FSF_QTCB_DOWNLOAD_CONTROL_FILE: - zfcp_fsf_control_file_handler(fsf_req); + case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: + zfcp_fsf_bit_error_threshold(req); break; - - case FSF_QTCB_UPLOAD_CONTROL_FILE: - zfcp_fsf_control_file_handler(fsf_req); + case FSF_STATUS_READ_LINK_DOWN: + zfcp_fsf_status_read_link_down(req); + break; + case FSF_STATUS_READ_LINK_UP: + dev_info(&adapter->ccw_device->dev, + "Local link was replugged.\n"); + /* All ports should be marked as ready to run again */ + zfcp_erp_modify_adapter_status(adapter, 30, NULL, + ZFCP_STATUS_COMMON_RUNNING, + ZFCP_SET); + zfcp_erp_adapter_reopen(adapter, + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | + ZFCP_STATUS_COMMON_ERP_FAILED, + 102, req); + break; + case FSF_STATUS_READ_NOTIFICATION_LOST: + if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) + zfcp_erp_adapter_access_changed(adapter, 135, req); + if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) + schedule_work(&adapter->scan_work); + break; + case FSF_STATUS_READ_CFDC_UPDATED: + zfcp_erp_adapter_access_changed(adapter, 136, req); + break; + case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: + adapter->adapter_features = sr_buf->payload.word[0]; break; } - if (!erp_action) - return retval; + mempool_free(sr_buf, adapter->pool.data_status_read); + zfcp_fsf_req_free(req); - zfcp_erp_async_handler(erp_action, 0); + atomic_inc(&adapter->stat_miss); + schedule_work(&adapter->stat_work); +} - return retval; +static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req) +{ + switch (req->qtcb->header.fsf_status_qual.word[0]) { + case FSF_SQ_FCP_RSP_AVAILABLE: + case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: + case FSF_SQ_NO_RETRY_POSSIBLE: + case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: + return; + case FSF_SQ_COMMAND_ABORTED: + req->status |= ZFCP_STATUS_FSFREQ_ABORTED; + break; + case FSF_SQ_NO_RECOM: + dev_err(&req->adapter->ccw_device->dev, + "No recommendation could be given for a " + "problem on the adapter.\n"); + zfcp_erp_adapter_shutdown(req->adapter, 0, 121, req); + break; + } + /* all non-return stats set FSFREQ_ERROR*/ + req->status |= ZFCP_STATUS_FSFREQ_ERROR; } -/* - * function: zfcp_fsf_status_read - * - * purpose: initiates a Status Read command at the specified adapter - * - * returns: - */ -int -zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) +static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req) { - struct zfcp_fsf_req *fsf_req; - struct fsf_status_read_buffer *status_buffer; - unsigned long lock_flags; - volatile struct qdio_buffer_element *sbale; - int retval; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, - req_flags | ZFCP_REQ_NO_QTCB, - adapter->pool.fsf_req_status_read, - &lock_flags, &fsf_req); - if (retval < 0) - goto failed_req_create; - - sbale = zfcp_qdio_sbale_req(fsf_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS; - sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; - fsf_req->sbale_curr = 2; - - retval = -ENOMEM; - status_buffer = - mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC); - if (!status_buffer) - goto failed_buf; - memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer)); - fsf_req->data = (unsigned long) status_buffer; + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) + return; - /* insert pointer to respective buffer */ - sbale = zfcp_qdio_sbale_curr(fsf_req); - sbale->addr = (void *) status_buffer; - sbale->length = sizeof(struct fsf_status_read_buffer); + switch (req->qtcb->header.fsf_status) { + case FSF_UNKNOWN_COMMAND: + dev_err(&req->adapter->ccw_device->dev, + "Command issued by the device driver (0x%x) is " + "not known by the adapter.\n", + req->qtcb->header.fsf_command); + zfcp_erp_adapter_shutdown(req->adapter, 0, 120, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + break; + case FSF_ADAPTER_STATUS_AVAILABLE: + zfcp_fsf_fsfstatus_qual_eval(req); + break; + } +} - retval = zfcp_fsf_req_send(fsf_req); - if (retval) - goto failed_req_send; +static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) +{ + struct zfcp_adapter *adapter = req->adapter; + struct fsf_qtcb *qtcb = req->qtcb; + union fsf_prot_status_qual *psq = &qtcb->prefix.prot_status_qual; - goto out; + zfcp_hba_dbf_event_fsf_response(req); - failed_req_send: - mempool_free(status_buffer, adapter->pool.data_status_read); + if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ + return; + } - failed_buf: - zfcp_fsf_req_free(fsf_req); - failed_req_create: - zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); - out: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return retval; + switch (qtcb->prefix.prot_status) { + case FSF_PROT_GOOD: + case FSF_PROT_FSF_STATUS_PRESENTED: + return; + case FSF_PROT_QTCB_VERSION_ERROR: + dev_err(&adapter->ccw_device->dev, + "The QTCB version requested by zfcp (0x%x) is not " + "supported by the FCP adapter (lowest supported " + "0x%x, highest supported 0x%x).\n", + FSF_QTCB_CURRENT_VERSION, psq->word[0], + psq->word[1]); + zfcp_erp_adapter_shutdown(adapter, 0, 117, req); + break; + case FSF_PROT_ERROR_STATE: + case FSF_PROT_SEQ_NUMB_ERROR: + zfcp_erp_adapter_reopen(adapter, 0, 98, req); + req->status |= ZFCP_STATUS_FSFREQ_RETRY; + break; + case FSF_PROT_UNSUPP_QTCB_TYPE: + dev_err(&adapter->ccw_device->dev, + "Packet header type used by the device driver is " + "incompatible with that used on the adapter.\n"); + zfcp_erp_adapter_shutdown(adapter, 0, 118, req); + break; + case FSF_PROT_HOST_CONNECTION_INITIALIZING: + atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, + &adapter->status); + break; + case FSF_PROT_DUPLICATE_REQUEST_ID: + dev_err(&adapter->ccw_device->dev, + "The request identifier 0x%Lx is ambiguous.\n", + (unsigned long long)qtcb->bottom.support.req_handle); + zfcp_erp_adapter_shutdown(adapter, 0, 78, req); + break; + case FSF_PROT_LINK_DOWN: + zfcp_fsf_link_down_info_eval(req, 37, &psq->link_down_info); + /* FIXME: reopening adapter now? better wait for link up */ + zfcp_erp_adapter_reopen(adapter, 0, 79, req); + break; + case FSF_PROT_REEST_QUEUE: + /* All ports should be marked as ready to run again */ + zfcp_erp_modify_adapter_status(adapter, 28, NULL, + ZFCP_STATUS_COMMON_RUNNING, + ZFCP_SET); + zfcp_erp_adapter_reopen(adapter, + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | + ZFCP_STATUS_COMMON_ERP_FAILED, 99, req); + break; + default: + dev_err(&adapter->ccw_device->dev, + "Transfer protocol status information" + "provided by the adapter (0x%x) " + "is not compatible with the device driver.\n", + qtcb->prefix.prot_status); + zfcp_erp_adapter_shutdown(adapter, 0, 119, req); + } + req->status |= ZFCP_STATUS_FSFREQ_ERROR; } -static int -zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) +/** + * zfcp_fsf_req_complete - process completion of a FSF request + * @fsf_req: The FSF request that has been completed. + * + * When a request has been completed either from the FCP adapter, + * or it has been dismissed due to a queue shutdown, this function + * is called to process the completion status and trigger further + * events related to the FSF request. + */ +void zfcp_fsf_req_complete(struct zfcp_fsf_req *req) { - struct fsf_status_read_buffer *status_buffer; - struct zfcp_adapter *adapter; - struct zfcp_port *port; - unsigned long flags; + if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) { + zfcp_fsf_status_read_handler(req); + return; + } - status_buffer = (struct fsf_status_read_buffer *) fsf_req->data; - adapter = fsf_req->adapter; + del_timer(&req->timer); + zfcp_fsf_protstatus_eval(req); + zfcp_fsf_fsfstatus_eval(req); + req->handler(req); - read_lock_irqsave(&zfcp_data.config_lock, flags); - list_for_each_entry(port, &adapter->port_list_head, list) - if (port->d_id == (status_buffer->d_id & ZFCP_DID_MASK)) - break; - read_unlock_irqrestore(&zfcp_data.config_lock, flags); + if (req->erp_action) + zfcp_erp_async_handler(req->erp_action, 0); + req->status |= ZFCP_STATUS_FSFREQ_COMPLETED; - if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) - goto out; + if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) + zfcp_fsf_req_free(req); + else + /* notify initiator waiting for the requests completion */ + /* + * FIXME: Race! We must not access fsf_req here as it might have been + * cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED + * flag. It's an improbable case. But, we have the same paranoia for + * the cleanup flag already. + * Might better be handled using complete()? + * (setting the flag and doing wakeup ought to be atomic + * with regard to checking the flag as long as waitqueue is + * part of the to be released structure) + */ + wake_up(&req->completion_wq); +} - switch (status_buffer->status_subtype) { +static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) +{ + struct fsf_qtcb_bottom_config *bottom; + struct zfcp_adapter *adapter = req->adapter; + struct Scsi_Host *shost = adapter->scsi_host; - case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT: - zfcp_erp_port_reopen(port, 0, 101, fsf_req); - break; + bottom = &req->qtcb->bottom.config; - case FSF_STATUS_READ_SUB_ERROR_PORT: - zfcp_erp_port_shutdown(port, 0, 122, fsf_req); - break; + if (req->data) + memcpy(req->data, bottom, sizeof(*bottom)); + + fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; + fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; + fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; + fc_host_speed(shost) = bottom->fc_link_speed; + fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; + + adapter->hydra_version = bottom->adapter_type; + adapter->timer_ticks = bottom->timer_interval; + + if (fc_host_permanent_port_name(shost) == -1) + fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + + switch (bottom->fc_topology) { + case FSF_TOPO_P2P: + adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK; + adapter->peer_wwpn = bottom->plogi_payload.wwpn; + adapter->peer_wwnn = bottom->plogi_payload.wwnn; + fc_host_port_type(shost) = FC_PORTTYPE_PTP; + if (req->erp_action) + dev_info(&adapter->ccw_device->dev, + "Point-to-Point fibrechannel " + "configuration detected.\n"); + break; + case FSF_TOPO_FABRIC: + fc_host_port_type(shost) = FC_PORTTYPE_NPORT; + if (req->erp_action) + dev_info(&adapter->ccw_device->dev, + "Switched fabric fibrechannel " + "network detected.\n"); + break; + case FSF_TOPO_AL: + fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; + dev_err(&adapter->ccw_device->dev, + "Unsupported arbitrated loop fibrechannel " + "topology detected, shutting down " + "adapter.\n"); + zfcp_erp_adapter_shutdown(adapter, 0, 127, req); + return -EIO; + default: + fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; + dev_err(&adapter->ccw_device->dev, + "The fibrechannel topology reported by the" + " adapter is not known by the zfcp driver," + " shutting down adapter.\n"); + zfcp_erp_adapter_shutdown(adapter, 0, 128, req); + return -EIO; } - out: + return 0; } -static void zfcp_fsf_bit_error_threshold(struct zfcp_fsf_req *req) +static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) { struct zfcp_adapter *adapter = req->adapter; - struct fsf_status_read_buffer *buf = - (struct fsf_status_read_buffer *) req->data; - struct fsf_bit_error_payload *err = - (struct fsf_bit_error_payload *) buf->payload; - dev_warn(&adapter->ccw_device->dev, - "Warning: bit error threshold data " - "received for the adapter: " - "link failures = %i, loss of sync errors = %i, " - "loss of signal errors = %i, " - "primitive sequence errors = %i, " - "invalid transmission word errors = %i, " - "CRC errors = %i).\n", - err->link_failure_error_count, - err->loss_of_sync_error_count, - err->loss_of_signal_error_count, - err->primitive_sequence_error_count, - err->invalid_transmission_word_error_count, - err->crc_error_count); - dev_warn(&adapter->ccw_device->dev, - "Additional bit error threshold data of the adapter: " - "primitive sequence event time-outs = %i, " - "elastic buffer overrun errors = %i, " - "advertised receive buffer-to-buffer credit = %i, " - "current receice buffer-to-buffer credit = %i, " - "advertised transmit buffer-to-buffer credit = %i, " - "current transmit buffer-to-buffer credit = %i).\n", - err->primitive_sequence_event_timeout_count, - err->elastic_buffer_overrun_error_count, - err->advertised_receive_b2b_credit, - err->current_receive_b2b_credit, - err->advertised_transmit_b2b_credit, - err->current_transmit_b2b_credit); -} + struct fsf_qtcb *qtcb = req->qtcb; + struct fsf_qtcb_bottom_config *bottom = &qtcb->bottom.config; + struct Scsi_Host *shost = adapter->scsi_host; -/* - * function: zfcp_fsf_status_read_handler - * - * purpose: is called for finished Open Port command - * - * returns: - */ -static int -zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) -{ - int retval = 0; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fsf_status_read_buffer *status_buffer = - (struct fsf_status_read_buffer *) fsf_req->data; - - if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { - zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer); - mempool_free(status_buffer, adapter->pool.data_status_read); - zfcp_fsf_req_free(fsf_req); - goto out; - } + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) + return; - zfcp_hba_dbf_event_fsf_unsol("read", adapter, status_buffer); + adapter->fsf_lic_version = bottom->lic_version; + adapter->adapter_features = bottom->adapter_features; + adapter->connection_features = bottom->connection_features; + adapter->peer_wwpn = 0; + adapter->peer_wwnn = 0; + adapter->peer_d_id = 0; - switch (status_buffer->status_type) { + switch (qtcb->header.fsf_status) { + case FSF_GOOD: + if (zfcp_fsf_exchange_config_evaluate(req)) + return; - case FSF_STATUS_READ_PORT_CLOSED: - zfcp_fsf_status_read_port_closed(fsf_req); + if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { + dev_err(&adapter->ccw_device->dev, + "Maximum QTCB size (%d bytes) allowed by " + "the adapter is lower than the minimum " + "required by the driver (%ld bytes).\n", + bottom->max_qtcb_size, + sizeof(struct fsf_qtcb)); + zfcp_erp_adapter_shutdown(adapter, 0, 129, req); + return; + } + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, + &adapter->status); break; + case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: + fc_host_node_name(shost) = 0; + fc_host_port_name(shost) = 0; + fc_host_port_id(shost) = 0; + fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; + fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; + adapter->hydra_version = 0; - case FSF_STATUS_READ_INCOMING_ELS: - zfcp_fc_incoming_els(fsf_req); - break; + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, + &adapter->status); - case FSF_STATUS_READ_SENSE_DATA_AVAIL: + zfcp_fsf_link_down_info_eval(req, 42, + &qtcb->header.fsf_status_qual.link_down_info); break; + default: + zfcp_erp_adapter_shutdown(adapter, 0, 130, req); + return; + } - case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: - zfcp_fsf_bit_error_threshold(fsf_req); - break; + if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { + adapter->hardware_version = bottom->hardware_version; + memcpy(fc_host_serial_number(shost), bottom->serial_number, + min(FC_SERIAL_NUMBER_SIZE, 17)); + EBCASC(fc_host_serial_number(shost), + min(FC_SERIAL_NUMBER_SIZE, 17)); + } - case FSF_STATUS_READ_LINK_DOWN: - switch (status_buffer->status_subtype) { - case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: - dev_warn(&adapter->ccw_device->dev, - "Physical link is down.\n"); - zfcp_fsf_link_down_info_eval(fsf_req, 38, - (struct fsf_link_down_info *) - &status_buffer->payload); - break; - case FSF_STATUS_READ_SUB_FDISC_FAILED: - dev_warn(&adapter->ccw_device->dev, - "Local link is down " - "due to failed FDISC login.\n"); - zfcp_fsf_link_down_info_eval(fsf_req, 39, - (struct fsf_link_down_info *) - &status_buffer->payload); - break; - case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: - dev_warn(&adapter->ccw_device->dev, - "Local link is down " - "due to firmware update on adapter.\n"); - zfcp_fsf_link_down_info_eval(fsf_req, 40, NULL); - break; - default: - dev_warn(&adapter->ccw_device->dev, - "Local link is down.\n"); - zfcp_fsf_link_down_info_eval(fsf_req, 41, NULL); - }; - break; + if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) { + dev_err(&adapter->ccw_device->dev, + "The adapter only supports newer control block " + "versions, try updated device driver.\n"); + zfcp_erp_adapter_shutdown(adapter, 0, 125, req); + return; + } + if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) { + dev_err(&adapter->ccw_device->dev, + "The adapter only supports older control block " + "versions, consider a microcode upgrade.\n"); + zfcp_erp_adapter_shutdown(adapter, 0, 126, req); + } +} - case FSF_STATUS_READ_LINK_UP: - dev_info(&adapter->ccw_device->dev, - "Local link was replugged.\n"); - /* All ports should be marked as ready to run again */ - zfcp_erp_modify_adapter_status(adapter, 30, NULL, - ZFCP_STATUS_COMMON_RUNNING, - ZFCP_SET); - zfcp_erp_adapter_reopen(adapter, - ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED - | ZFCP_STATUS_COMMON_ERP_FAILED, - 102, fsf_req); - break; +static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req) +{ + struct zfcp_adapter *adapter = req->adapter; + struct fsf_qtcb_bottom_port *bottom = &req->qtcb->bottom.port; + struct Scsi_Host *shost = adapter->scsi_host; - case FSF_STATUS_READ_NOTIFICATION_LOST: - if (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_ACT_UPDATED) - zfcp_erp_adapter_access_changed(adapter, 135, fsf_req); - if (status_buffer->status_subtype & - FSF_STATUS_READ_SUB_INCOMING_ELS) - schedule_work(&adapter->scan_work); - break; + if (req->data) + memcpy(req->data, bottom, sizeof(*bottom)); - case FSF_STATUS_READ_CFDC_UPDATED: - zfcp_erp_adapter_access_changed(adapter, 136, fsf_req); - break; + if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) + fc_host_permanent_port_name(shost) = bottom->wwpn; + else + fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + fc_host_maxframe_size(shost) = bottom->maximum_frame_size; + fc_host_supported_speeds(shost) = bottom->supported_speed; +} - case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: - adapter->adapter_features = *(u32*) status_buffer->payload; +static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) +{ + struct zfcp_adapter *adapter = req->adapter; + struct fsf_qtcb *qtcb = req->qtcb; + + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) + return; + + switch (qtcb->header.fsf_status) { + case FSF_GOOD: + zfcp_fsf_exchange_port_evaluate(req); + atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); + break; + case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: + zfcp_fsf_exchange_port_evaluate(req); + atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); + zfcp_fsf_link_down_info_eval(req, 43, + &qtcb->header.fsf_status_qual.link_down_info); break; } - mempool_free(status_buffer, adapter->pool.data_status_read); - zfcp_fsf_req_free(fsf_req); - /* - * recycle buffer and start new request repeat until outbound - * queue is empty or adapter shutdown is requested - */ - /* - * FIXME(qdio): - * we may wait in the req_create for 5s during shutdown, so - * qdio_cleanup will have to wait at least that long before returning - * with failure to allow us a proper cleanup under all circumstances - */ - /* - * FIXME: - * allocation failure possible? (Is this code needed?) - */ +} - atomic_inc(&adapter->stat_miss); - schedule_work(&adapter->stat_work); - out: - return retval; +static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue) +{ + spin_lock(&queue->lock); + if (atomic_read(&queue->count)) + return 1; + spin_unlock(&queue->lock); + return 0; } -/* - * function: zfcp_fsf_abort_fcp_command - * - * purpose: tells FSF to abort a running SCSI command - * - * returns: address of initiated FSF request - * NULL - request could not be initiated - * - * FIXME(design): should be watched by a timeout !!! - * FIXME(design) shouldn't this be modified to return an int - * also...don't know how though - */ -struct zfcp_fsf_req * -zfcp_fsf_abort_fcp_command(unsigned long old_req_id, - struct zfcp_adapter *adapter, - struct zfcp_unit *unit, int req_flags) +static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) +{ + long ret; + struct zfcp_qdio_queue *req_q = &adapter->req_q; + + spin_unlock(&req_q->lock); + ret = wait_event_interruptible_timeout(adapter->request_wq, + zfcp_fsf_sbal_check(req_q), 5 * HZ); + if (ret > 0) + return 0; + + spin_lock(&req_q->lock); + return -EIO; +} + +static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool) +{ + struct zfcp_fsf_req *req; + req = mempool_alloc(pool, GFP_ATOMIC); + if (!req) + return NULL; + memset(req, 0, sizeof(*req)); + return req; +} + +static struct zfcp_fsf_req *zfcp_fsf_alloc_qtcb(mempool_t *pool) +{ + struct zfcp_fsf_req_qtcb *qtcb; + + if (likely(pool)) + qtcb = mempool_alloc(pool, GFP_ATOMIC); + else + qtcb = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache, + GFP_ATOMIC); + if (unlikely(!qtcb)) + return NULL; + + memset(qtcb, 0, sizeof(*qtcb)); + qtcb->fsf_req.qtcb = &qtcb->qtcb; + qtcb->fsf_req.pool = pool; + + return &qtcb->fsf_req; +} + +static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, + u32 fsf_cmd, int req_flags, + mempool_t *pool) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req = NULL; - unsigned long lock_flags; - int retval = 0; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, - req_flags, adapter->pool.fsf_req_abort, - &lock_flags, &fsf_req); - if (retval < 0) - goto out; - if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &unit->status))) - goto unit_blocked; + struct zfcp_fsf_req *req; + struct zfcp_qdio_queue *req_q = &adapter->req_q; - sbale = zfcp_qdio_sbale_req(fsf_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + if (req_flags & ZFCP_REQ_NO_QTCB) + req = zfcp_fsf_alloc_noqtcb(pool); + else + req = zfcp_fsf_alloc_qtcb(pool); - fsf_req->data = (unsigned long) unit; + if (unlikely(!req)) + return ERR_PTR(-EIO); - /* set handles of unit and its parent port in QTCB */ - fsf_req->qtcb->header.lun_handle = unit->handle; - fsf_req->qtcb->header.port_handle = unit->port->handle; + if (adapter->req_no == 0) + adapter->req_no++; - /* set handle of request which should be aborted */ - fsf_req->qtcb->bottom.support.req_handle = (u64) old_req_id; + INIT_LIST_HEAD(&req->list); + init_timer(&req->timer); + init_waitqueue_head(&req->completion_wq); - zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT); - retval = zfcp_fsf_req_send(fsf_req); - if (!retval) - goto out; + req->adapter = adapter; + req->fsf_command = fsf_cmd; + req->req_id = adapter->req_no++; + req->sbal_number = 1; + req->sbal_first = req_q->first; + req->sbal_last = req_q->first; + req->sbale_curr = 1; + + sbale = zfcp_qdio_sbale_req(req); + sbale[0].addr = (void *) req->req_id; + sbale[0].flags |= SBAL_FLAGS0_COMMAND; + + if (likely(req->qtcb)) { + req->qtcb->prefix.req_seq_no = req->adapter->fsf_req_seq_no; + req->qtcb->prefix.req_id = req->req_id; + req->qtcb->prefix.ulp_info = 26; + req->qtcb->prefix.qtcb_type = fsf_qtcb_type[req->fsf_command]; + req->qtcb->prefix.qtcb_version = FSF_QTCB_CURRENT_VERSION; + req->qtcb->header.req_handle = req->req_id; + req->qtcb->header.fsf_command = req->fsf_command; + req->seq_no = adapter->fsf_req_seq_no; + req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; + sbale[1].addr = (void *) req->qtcb; + sbale[1].length = sizeof(struct fsf_qtcb); + } + + if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) { + zfcp_fsf_req_free(req); + return ERR_PTR(-EIO); + } - unit_blocked: - zfcp_fsf_req_free(fsf_req); - fsf_req = NULL; + if (likely(req_flags & ZFCP_REQ_AUTO_CLEANUP)) + req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - out: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return fsf_req; + return req; } -/* - * function: zfcp_fsf_abort_fcp_command_handler - * - * purpose: is called for finished Abort FCP Command request - * - * returns: +static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) +{ + struct zfcp_adapter *adapter = req->adapter; + struct zfcp_qdio_queue *req_q = &adapter->req_q; + int idx; + + /* put allocated FSF request into hash table */ + spin_lock(&adapter->req_list_lock); + idx = zfcp_reqlist_hash(req->req_id); + list_add_tail(&req->list, &adapter->req_list[idx]); + spin_unlock(&adapter->req_list_lock); + + req->issued = get_clock(); + if (zfcp_qdio_send(req)) { + /* Queues are down..... */ + del_timer(&req->timer); + spin_lock(&adapter->req_list_lock); + zfcp_reqlist_remove(adapter, req); + spin_unlock(&adapter->req_list_lock); + /* undo changes in request queue made for this request */ + atomic_add(req->sbal_number, &req_q->count); + req_q->first -= req->sbal_number; + req_q->first += QDIO_MAX_BUFFERS_PER_Q; + req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ + zfcp_erp_adapter_reopen(adapter, 0, 116, req); + return -EIO; + } + + /* Don't increase for unsolicited status */ + if (req->qtcb) + adapter->fsf_req_seq_no++; + + return 0; +} + +/** + * zfcp_fsf_status_read - send status read request + * @adapter: pointer to struct zfcp_adapter + * @req_flags: request flags + * Returns: 0 on success, ERROR otherwise */ -static int -zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) +int zfcp_fsf_status_read(struct zfcp_adapter *adapter) { - int retval = -EINVAL; - struct zfcp_unit *unit; - union fsf_status_qual *fsf_stat_qual = - &new_fsf_req->qtcb->header.fsf_status_qual; + struct zfcp_fsf_req *req; + struct fsf_status_read_buffer *sr_buf; + volatile struct qdio_buffer_element *sbale; + int retval = -EIO; - if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - /* do not set ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED */ - goto skip_fsfstatus; + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) + goto out; + + req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, + ZFCP_REQ_NO_QTCB, + adapter->pool.fsf_req_status_read); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; } - unit = (struct zfcp_unit *) new_fsf_req->data; + sbale = zfcp_qdio_sbale_req(req); + sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS; + sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; + req->sbale_curr = 2; + + sr_buf = mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC); + if (!sr_buf) { + retval = -ENOMEM; + goto failed_buf; + } + memset(sr_buf, 0, sizeof(*sr_buf)); + req->data = sr_buf; + sbale = zfcp_qdio_sbale_curr(req); + sbale->addr = (void *) sr_buf; + sbale->length = sizeof(*sr_buf); - /* evaluate FSF status in QTCB */ - switch (new_fsf_req->qtcb->header.fsf_status) { + retval = zfcp_fsf_req_send(req); + if (retval) + goto failed_req_send; + goto out; + +failed_req_send: + mempool_free(sr_buf, adapter->pool.data_status_read); +failed_buf: + zfcp_fsf_req_free(req); + zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); +out: + spin_unlock(&adapter->req_q.lock); + return retval; +} + +static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) +{ + struct zfcp_unit *unit = req->data; + union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual; + + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) + return; + + switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) { - /* - * In this case a command that was sent prior to a port - * reopen was aborted (handles are different). This is - * fine. - */ - } else { - /* Let's hope this sorts out the mess */ + if (fsq->word[0] == fsq->word[1]) { zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104, - new_fsf_req); - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; } break; - case FSF_LUN_HANDLE_NOT_VALID: - if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) { - /* - * In this case a command that was sent prior to a unit - * reopen was aborted (handles are different). - * This is fine. - */ - } else { - /* Let's hope this sorts out the mess */ - zfcp_erp_port_reopen(unit->port, 0, 105, new_fsf_req); - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + if (fsq->word[0] == fsq->word[1]) { + zfcp_erp_port_reopen(unit->port, 0, 105, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; } break; - case FSF_FCP_COMMAND_DOES_NOT_EXIST: - retval = 0; - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED; + req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED; break; - case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, 47, new_fsf_req); - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR - | ZFCP_STATUS_FSFREQ_RETRY; + zfcp_erp_port_boxed(unit->port, 47, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; break; - case FSF_LUN_BOXED: - zfcp_erp_unit_boxed(unit, 48, new_fsf_req); - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR - | ZFCP_STATUS_FSFREQ_RETRY; + zfcp_erp_unit_boxed(unit, 48, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; break; - case FSF_ADAPTER_STATUS_AVAILABLE: - switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) { + switch (fsq->word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: zfcp_test_link(unit->port); - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* SCSI stack will escalate */ - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_GOOD: - retval = 0; - new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED; + req->status |= ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED; break; } - skip_fsfstatus: - return retval; } /** - * zfcp_use_one_sbal - checks whether req buffer and resp bother each fit into - * one SBALE - * Two scatter-gather lists are passed, one for the reqeust and one for the - * response. + * zfcp_fsf_abort_fcp_command - abort running SCSI command + * @old_req_id: unsigned long + * @adapter: pointer to struct zfcp_adapter + * @unit: pointer to struct zfcp_unit + * @req_flags: integer specifying the request flags + * Returns: pointer to struct zfcp_fsf_req + * + * FIXME(design): should be watched by a timeout !!! */ -static inline int -zfcp_use_one_sbal(struct scatterlist *req, int req_count, - struct scatterlist *resp, int resp_count) -{ - return ((req_count == 1) && - (resp_count == 1) && - (((unsigned long) zfcp_sg_to_address(&req[0]) & - PAGE_MASK) == - ((unsigned long) (zfcp_sg_to_address(&req[0]) + - req[0].length - 1) & PAGE_MASK)) && - (((unsigned long) zfcp_sg_to_address(&resp[0]) & - PAGE_MASK) == - ((unsigned long) (zfcp_sg_to_address(&resp[0]) + - resp[0].length - 1) & PAGE_MASK))); -} -/** - * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS) - * @ct: pointer to struct zfcp_send_ct which conatins all needed data for - * the request - * @pool: pointer to memory pool, if non-null this pool is used to allocate - * a struct zfcp_fsf_req - * @erp_action: pointer to erp_action, if non-null the Generic Service request - * is sent within error recovery - */ -int -zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, - struct zfcp_erp_action *erp_action) +struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, + struct zfcp_adapter *adapter, + struct zfcp_unit *unit, + int req_flags) { volatile struct qdio_buffer_element *sbale; - struct zfcp_port *port; - struct zfcp_adapter *adapter; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int bytes; - int ret = 0; - - port = ct->port; - adapter = port->adapter; - - ret = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC, - ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, - pool, &lock_flags, &fsf_req); - if (ret < 0) - goto failed_req; - - sbale = zfcp_qdio_sbale_req(fsf_req); - if (zfcp_use_one_sbal(ct->req, ct->req_count, - ct->resp, ct->resp_count)){ - /* both request buffer and response buffer - fit into one sbale each */ - sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ; - sbale[2].addr = zfcp_sg_to_address(&ct->req[0]); - sbale[2].length = ct->req[0].length; - sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]); - sbale[3].length = ct->resp[0].length; - sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; - } else if (adapter->adapter_features & - FSF_FEATURE_ELS_CT_CHAINED_SBALS) { - /* try to use chained SBALs */ - bytes = zfcp_qdio_sbals_from_sg(fsf_req, - SBAL_FLAGS0_TYPE_WRITE_READ, - ct->req, - ZFCP_MAX_SBALS_PER_CT_REQ); - if (bytes <= 0) { - if (bytes == 0) - ret = -ENOMEM; - else - ret = bytes; - - goto failed_send; - } - fsf_req->qtcb->bottom.support.req_buf_length = bytes; - fsf_req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; - bytes = zfcp_qdio_sbals_from_sg(fsf_req, - SBAL_FLAGS0_TYPE_WRITE_READ, - ct->resp, - ZFCP_MAX_SBALS_PER_CT_REQ); - if (bytes <= 0) { - if (bytes == 0) - ret = -ENOMEM; - else - ret = bytes; - - goto failed_send; - } - fsf_req->qtcb->bottom.support.resp_buf_length = bytes; - } else { - /* reject send generic request */ - ret = -EOPNOTSUPP; - goto failed_send; - } - - /* settings in QTCB */ - fsf_req->qtcb->header.port_handle = port->handle; - fsf_req->qtcb->bottom.support.service_class = - ZFCP_FC_SERVICE_CLASS_DEFAULT; - fsf_req->qtcb->bottom.support.timeout = ct->timeout; - fsf_req->data = (unsigned long) ct; - - zfcp_san_dbf_event_ct_request(fsf_req); + struct zfcp_fsf_req *req = NULL; - if (erp_action) { - erp_action->fsf_req = fsf_req; - fsf_req->erp_action = erp_action; - zfcp_erp_start_timer(fsf_req); - } else - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, + req_flags, adapter->pool.fsf_req_abort); + if (unlikely(IS_ERR(req))) + goto out; - ret = zfcp_fsf_req_send(fsf_req); - if (ret) - goto failed_send; + if (unlikely(!(atomic_read(&unit->status) & + ZFCP_STATUS_COMMON_UNBLOCKED))) + goto out_error_free; - goto out; + sbale = zfcp_qdio_sbale_req(req); + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - failed_send: - zfcp_fsf_req_free(fsf_req); - if (erp_action != NULL) { - erp_action->fsf_req = NULL; - } - failed_req: - out: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return ret; + req->data = unit; + req->handler = zfcp_fsf_abort_fcp_command_handler; + req->qtcb->header.lun_handle = unit->handle; + req->qtcb->header.port_handle = unit->port->handle; + req->qtcb->bottom.support.req_handle = (u64) old_req_id; + + zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); + if (!zfcp_fsf_req_send(req)) + goto out; + +out_error_free: + zfcp_fsf_req_free(req); + req = NULL; +out: + spin_unlock(&adapter->req_q.lock); + return req; } -/** - * zfcp_fsf_send_ct_handler - handler for Generic Service requests - * @fsf_req: pointer to struct zfcp_fsf_req - * - * Data specific for the Generic Service request is passed using - * fsf_req->data. There we find the pointer to struct zfcp_send_ct. - * Usually a specific handler for the CT request is called which is - * found in this structure. - */ -static int -zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) { - struct zfcp_port *port; - struct zfcp_adapter *adapter; - struct zfcp_send_ct *send_ct; - struct fsf_qtcb_header *header; - struct fsf_qtcb_bottom_support *bottom; - int retval = -EINVAL; + struct zfcp_adapter *adapter = req->adapter; + struct zfcp_send_ct *send_ct = req->data; + struct zfcp_port *port = send_ct->port; + struct fsf_qtcb_header *header = &req->qtcb->header; - adapter = fsf_req->adapter; - send_ct = (struct zfcp_send_ct *) fsf_req->data; - port = send_ct->port; - header = &fsf_req->qtcb->header; - bottom = &fsf_req->qtcb->bottom.support; + send_ct->status = -EINVAL; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; - /* evaluate FSF status in QTCB */ switch (header->fsf_status) { - case FSF_GOOD: - zfcp_san_dbf_event_ct_response(fsf_req); - retval = 0; + zfcp_san_dbf_event_ct_response(req); + send_ct->status = 0; break; - case FSF_SERVICE_CLASS_NOT_SUPPORTED: - zfcp_fsf_class_not_supp(fsf_req); + zfcp_fsf_class_not_supp(req); break; - case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]){ case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* reopening link to port */ zfcp_test_link(port); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* ERP strategy will escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_port(fsf_req, port); - break; - - case FSF_GENERIC_COMMAND_REJECTED: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_fsf_access_denied_port(req, port); break; - - case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(adapter, 0, 106, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - case FSF_PORT_BOXED: - zfcp_erp_port_boxed(port, 49, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR - | ZFCP_STATUS_FSFREQ_RETRY; + zfcp_erp_port_boxed(port, 49, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; break; - - /* following states should never occure, all cases avoided - in zfcp_fsf_send_ct - but who knows ... */ + case FSF_PORT_HANDLE_NOT_VALID: + zfcp_erp_adapter_reopen(adapter, 0, 106, req); + case FSF_GENERIC_COMMAND_REJECTED: case FSF_PAYLOAD_SIZE_MISMATCH: case FSF_REQUEST_SIZE_TOO_LARGE: case FSF_RESPONSE_SIZE_TOO_LARGE: case FSF_SBAL_MISMATCH: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - default: + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } skip_fsfstatus: - send_ct->status = retval; - - if (send_ct->handler != NULL) + if (send_ct->handler) send_ct->handler(send_ct->handler_data); +} - return retval; +static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, + struct scatterlist *sg_req, + struct scatterlist *sg_resp, int max_sbals) +{ + int bytes; + + bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, + sg_req, max_sbals); + if (bytes <= 0) + return -ENOMEM; + req->qtcb->bottom.support.req_buf_length = bytes; + req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; + + bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, + sg_resp, max_sbals); + if (bytes <= 0) + return -ENOMEM; + req->qtcb->bottom.support.resp_buf_length = bytes; + + return 0; } /** - * zfcp_fsf_send_els - initiate an ELS command (FC-FS) - * @els: pointer to struct zfcp_send_els which contains all needed data for - * the command. + * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS) + * @ct: pointer to struct zfcp_send_ct with data for request + * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req + * @erp_action: if non-null the Generic Service request sent within ERP */ -int -zfcp_fsf_send_els(struct zfcp_send_els *els) +int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, + struct zfcp_erp_action *erp_action) { - volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - u32 d_id; - struct zfcp_adapter *adapter; - unsigned long lock_flags; - int bytes; - int ret = 0; + struct zfcp_port *port = ct->port; + struct zfcp_adapter *adapter = port->adapter; + struct zfcp_fsf_req *req; + int ret = -EIO; - d_id = els->d_id; - adapter = els->adapter; + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) + goto out; - ret = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, - ZFCP_REQ_AUTO_CLEANUP, - NULL, &lock_flags, &fsf_req); - if (ret < 0) - goto failed_req; - - if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &els->port->status))) { - ret = -EBUSY; - goto port_blocked; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC, + ZFCP_REQ_AUTO_CLEANUP, pool); + if (unlikely(IS_ERR(req))) { + ret = PTR_ERR(req); + goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req); - if (zfcp_use_one_sbal(els->req, els->req_count, - els->resp, els->resp_count)){ - /* both request buffer and response buffer - fit into one sbale each */ - sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ; - sbale[2].addr = zfcp_sg_to_address(&els->req[0]); - sbale[2].length = els->req[0].length; - sbale[3].addr = zfcp_sg_to_address(&els->resp[0]); - sbale[3].length = els->resp[0].length; - sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; - } else if (adapter->adapter_features & - FSF_FEATURE_ELS_CT_CHAINED_SBALS) { - /* try to use chained SBALs */ - bytes = zfcp_qdio_sbals_from_sg(fsf_req, - SBAL_FLAGS0_TYPE_WRITE_READ, - els->req, - ZFCP_MAX_SBALS_PER_ELS_REQ); - if (bytes <= 0) { - if (bytes == 0) { - ret = -ENOMEM; - } else { - ret = bytes; - } - goto failed_send; - } - fsf_req->qtcb->bottom.support.req_buf_length = bytes; - fsf_req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; - bytes = zfcp_qdio_sbals_from_sg(fsf_req, - SBAL_FLAGS0_TYPE_WRITE_READ, - els->resp, - ZFCP_MAX_SBALS_PER_ELS_REQ); - if (bytes <= 0) { - if (bytes == 0) { - ret = -ENOMEM; - } else { - ret = bytes; - } - goto failed_send; - } - fsf_req->qtcb->bottom.support.resp_buf_length = bytes; - } else { - /* reject request */ - ret = -EOPNOTSUPP; - goto failed_send; - } - - /* settings in QTCB */ - fsf_req->qtcb->bottom.support.d_id = d_id; - fsf_req->qtcb->bottom.support.service_class = - ZFCP_FC_SERVICE_CLASS_DEFAULT; - fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT; - fsf_req->data = (unsigned long) els; - - sbale = zfcp_qdio_sbale_req(fsf_req); - - zfcp_san_dbf_event_els_request(fsf_req); - - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); - ret = zfcp_fsf_req_send(fsf_req); + ret = zfcp_fsf_setup_sbals(req, ct->req, ct->resp, + FSF_MAX_SBALS_PER_REQ); if (ret) goto failed_send; - goto out; + req->handler = zfcp_fsf_send_ct_handler; + req->qtcb->header.port_handle = port->handle; + req->qtcb->bottom.support.service_class = FSF_CLASS_3; + req->qtcb->bottom.support.timeout = ct->timeout; + req->data = ct; + + zfcp_san_dbf_event_ct_request(req); + + if (erp_action) { + erp_action->fsf_req = req; + req->erp_action = erp_action; + zfcp_erp_start_timer(req); + } else + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); - port_blocked: - failed_send: - zfcp_fsf_req_free(fsf_req); + ret = zfcp_fsf_req_send(req); + if (ret) + goto failed_send; - failed_req: - out: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); + goto out; - return ret; +failed_send: + zfcp_fsf_req_free(req); + if (erp_action) + erp_action->fsf_req = NULL; +out: + spin_unlock(&adapter->req_q.lock); + return ret; } -/** - * zfcp_fsf_send_els_handler - handler for ELS commands - * @fsf_req: pointer to struct zfcp_fsf_req - * - * Data specific for the ELS command is passed using - * fsf_req->data. There we find the pointer to struct zfcp_send_els. - * Usually a specific handler for the ELS command is called which is - * found in this structure. - */ -static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) { - struct zfcp_adapter *adapter; - struct zfcp_port *port; - u32 d_id; - struct fsf_qtcb_header *header; - struct fsf_qtcb_bottom_support *bottom; - struct zfcp_send_els *send_els; - int retval = -EINVAL; + struct zfcp_send_els *send_els = req->data; + struct zfcp_port *port = send_els->port; + struct fsf_qtcb_header *header = &req->qtcb->header; - send_els = (struct zfcp_send_els *) fsf_req->data; - adapter = send_els->adapter; - port = send_els->port; - d_id = send_els->d_id; - header = &fsf_req->qtcb->header; - bottom = &fsf_req->qtcb->bottom.support; + send_els->status = -EINVAL; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; switch (header->fsf_status) { - case FSF_GOOD: - zfcp_san_dbf_event_els_response(fsf_req); - retval = 0; + zfcp_san_dbf_event_els_response(req); + send_els->status = 0; break; - case FSF_SERVICE_CLASS_NOT_SUPPORTED: - zfcp_fsf_class_not_supp(fsf_req); + zfcp_fsf_class_not_supp(req); break; - case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]){ case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: if (port && (send_els->ls_code != ZFCP_LS_ADISC)) zfcp_test_link(port); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; + /*fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_SQ_RETRY_IF_POSSIBLE: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_ELS_COMMAND_REJECTED: case FSF_PAYLOAD_SIZE_MISMATCH: case FSF_REQUEST_SIZE_TOO_LARGE: case FSF_RESPONSE_SIZE_TOO_LARGE: break; - - case FSF_SBAL_MISMATCH: - /* should never occure, avoided in zfcp_fsf_send_els */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_port(fsf_req, port); + zfcp_fsf_access_denied_port(req, port); break; - + case FSF_SBAL_MISMATCH: + /* should never occure, avoided in zfcp_fsf_send_els */ + /* fall through */ default: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } - skip_fsfstatus: - send_els->status = retval; - if (send_els->handler) send_els->handler(send_els->handler_data); +} - return retval; +/** + * zfcp_fsf_send_els - initiate an ELS command (FC-FS) + * @els: pointer to struct zfcp_send_els with data for the command + */ +int zfcp_fsf_send_els(struct zfcp_send_els *els) +{ + struct zfcp_fsf_req *req; + struct zfcp_adapter *adapter = els->adapter; + struct fsf_qtcb_bottom_support *bottom; + int ret = -EIO; + + if (unlikely(!(atomic_read(&els->port->status) & + ZFCP_STATUS_COMMON_UNBLOCKED))) + return -EBUSY; + + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, + ZFCP_REQ_AUTO_CLEANUP, NULL); + if (unlikely(IS_ERR(req))) { + ret = PTR_ERR(req); + goto out; + } + + ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, + FSF_MAX_SBALS_PER_ELS_REQ); + if (ret) + goto failed_send; + + bottom = &req->qtcb->bottom.support; + req->handler = zfcp_fsf_send_els_handler; + bottom->d_id = els->d_id; + bottom->service_class = FSF_CLASS_3; + bottom->timeout = 2 * R_A_TOV; + req->data = els; + + zfcp_san_dbf_event_els_request(req); + + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); + ret = zfcp_fsf_req_send(req); + if (ret) + goto failed_send; + + goto out; + +failed_send: + zfcp_fsf_req_free(req); +out: + spin_unlock(&adapter->req_q.lock); + return ret; } -int -zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) +int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; + struct zfcp_fsf_req *req; struct zfcp_adapter *adapter = erp_action->adapter; - unsigned long lock_flags; - int retval; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, - FSF_QTCB_EXCHANGE_CONFIG_DATA, - ZFCP_REQ_AUTO_CLEANUP, - adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval) { - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return retval; + int retval = -EIO; + + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + req = zfcp_fsf_req_create(adapter, + FSF_QTCB_EXCHANGE_CONFIG_DATA, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req); + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - fsf_req->qtcb->bottom.config.feature_selection = + req->qtcb->bottom.config.feature_selection = FSF_FEATURE_CFDC | FSF_FEATURE_LUN_SHARING | FSF_FEATURE_NOTIFICATION_LOST | FSF_FEATURE_UPDATE_ALERT; - fsf_req->erp_action = erp_action; - erp_action->fsf_req = fsf_req; + req->erp_action = erp_action; + req->handler = zfcp_fsf_exchange_config_data_handler; + erp_action->fsf_req = req; - zfcp_erp_start_timer(fsf_req); - retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); if (retval) { - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); erp_action->fsf_req = NULL; } - +out: + spin_unlock(&adapter->req_q.lock); return retval; } -int -zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, - struct fsf_qtcb_bottom_config *data) +int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, + struct fsf_qtcb_bottom_config *data) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, - ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags, - &fsf_req); - if (retval) { - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return retval; + struct zfcp_fsf_req *req = NULL; + int retval = -EIO; + + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) + goto out; + + req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, + 0, NULL); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req); + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + req->handler = zfcp_fsf_exchange_config_data_handler; - fsf_req->qtcb->bottom.config.feature_selection = + req->qtcb->bottom.config.feature_selection = FSF_FEATURE_CFDC | FSF_FEATURE_LUN_SHARING | FSF_FEATURE_NOTIFICATION_LOST | FSF_FEATURE_UPDATE_ALERT; if (data) - fsf_req->data = (unsigned long) data; + req->data = data; - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); - retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); + retval = zfcp_fsf_req_send(req); +out: + spin_unlock(&adapter->req_q.lock); if (!retval) - wait_event(fsf_req->completion_wq, - fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); + wait_event(req->completion_wq, + req->status & ZFCP_STATUS_FSFREQ_COMPLETED); - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); return retval; } /** - * zfcp_fsf_exchange_config_evaluate - * @fsf_req: fsf_req which belongs to xchg config data request - * @xchg_ok: specifies if xchg config data was incomplete or complete (0/1) - * - * returns: -EIO on error, 0 otherwise - */ -static int -zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) -{ - struct fsf_qtcb_bottom_config *bottom; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct Scsi_Host *shost = adapter->scsi_host; - - bottom = &fsf_req->qtcb->bottom.config; - adapter->fsf_lic_version = bottom->lic_version; - adapter->adapter_features = bottom->adapter_features; - adapter->connection_features = bottom->connection_features; - adapter->peer_wwpn = 0; - adapter->peer_wwnn = 0; - adapter->peer_d_id = 0; - - if (xchg_ok) { - - if (fsf_req->data) - memcpy((struct fsf_qtcb_bottom_config *) fsf_req->data, - bottom, sizeof (struct fsf_qtcb_bottom_config)); - - fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; - fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; - fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; - fc_host_speed(shost) = bottom->fc_link_speed; - fc_host_supported_classes(shost) = - FC_COS_CLASS2 | FC_COS_CLASS3; - adapter->hydra_version = bottom->adapter_type; - adapter->timer_ticks = bottom->timer_interval; - if (fc_host_permanent_port_name(shost) == -1) - fc_host_permanent_port_name(shost) = - fc_host_port_name(shost); - if (bottom->fc_topology == FSF_TOPO_P2P) { - adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK; - adapter->peer_wwpn = bottom->plogi_payload.wwpn; - adapter->peer_wwnn = bottom->plogi_payload.wwnn; - fc_host_port_type(shost) = FC_PORTTYPE_PTP; - } else if (bottom->fc_topology == FSF_TOPO_FABRIC) - fc_host_port_type(shost) = FC_PORTTYPE_NPORT; - else if (bottom->fc_topology == FSF_TOPO_AL) - fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; - else - fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; - } else { - fc_host_node_name(shost) = 0; - fc_host_port_name(shost) = 0; - fc_host_port_id(shost) = 0; - fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; - fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; - adapter->hydra_version = 0; - } - - if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { - adapter->hardware_version = bottom->hardware_version; - memcpy(fc_host_serial_number(shost), bottom->serial_number, - min(FC_SERIAL_NUMBER_SIZE, 17)); - EBCASC(fc_host_serial_number(shost), - min(FC_SERIAL_NUMBER_SIZE, 17)); - } - - if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) { - dev_err(&adapter->ccw_device->dev, - "The adapter only supports newer control block " - "versions, try updated device driver.\n"); - zfcp_erp_adapter_shutdown(adapter, 0, 125, fsf_req); - return -EIO; - } - if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) { - dev_err(&adapter->ccw_device->dev, - "The adapter only supports older control block " - "versions, consider a microcode upgrade.\n"); - zfcp_erp_adapter_shutdown(adapter, 0, 126, fsf_req); - return -EIO; - } - return 0; -} - -/** - * function: zfcp_fsf_exchange_config_data_handler - * - * purpose: is called for finished Exchange Configuration Data command - * - * returns: - */ -static int -zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) -{ - struct fsf_qtcb_bottom_config *bottom; - struct zfcp_adapter *adapter = fsf_req->adapter; - struct fsf_qtcb *qtcb = fsf_req->qtcb; - - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) - return -EIO; - - switch (qtcb->header.fsf_status) { - - case FSF_GOOD: - if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) - return -EIO; - - switch (fc_host_port_type(adapter->scsi_host)) { - case FC_PORTTYPE_PTP: - if (fsf_req->erp_action) - dev_info(&adapter->ccw_device->dev, - "Point-to-Point fibrechannel " - "configuration detected.\n"); - break; - case FC_PORTTYPE_NLPORT: - dev_err(&adapter->ccw_device->dev, - "Unsupported arbitrated loop fibrechannel " - "topology detected, shutting down adapter\n"); - zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req); - return -EIO; - case FC_PORTTYPE_NPORT: - if (fsf_req->erp_action) - dev_info(&adapter->ccw_device->dev, - "Switched fabric fibrechannel " - "network detected.\n"); - break; - default: - dev_err(&adapter->ccw_device->dev, - "The fibrechannel topology reported by the " - "adapter is not known by the zfcp driver, " - "shutting down adapter.\n"); - zfcp_erp_adapter_shutdown(adapter, 0, 128, fsf_req); - return -EIO; - } - bottom = &qtcb->bottom.config; - if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { - dev_err(&adapter->ccw_device->dev, - "Maximum QTCB size (%d bytes) allowed by " - "the adapter is lower than the minimum " - "required by the driver (%ld bytes).\n", - bottom->max_qtcb_size, sizeof(struct fsf_qtcb)); - zfcp_erp_adapter_shutdown(adapter, 0, 129, fsf_req); - return -EIO; - } - atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, - &adapter->status); - break; - case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: - if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) - return -EIO; - - atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, - &adapter->status); - - zfcp_fsf_link_down_info_eval(fsf_req, 42, - &qtcb->header.fsf_status_qual.link_down_info); - break; - default: - zfcp_erp_adapter_shutdown(adapter, 0, 130, fsf_req); - return -EIO; - } - return 0; -} - -/** * zfcp_fsf_exchange_port_data - request information about local port * @erp_action: ERP action for the adapter for which port data is requested + * Returns: 0 on success, error otherwise */ -int -zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) +int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; + struct zfcp_fsf_req *req; struct zfcp_adapter *adapter = erp_action->adapter; - unsigned long lock_flags; - int retval; + int retval = -EIO; if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, - ZFCP_REQ_AUTO_CLEANUP, - adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval) { - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return retval; + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; } - sbale = zfcp_qdio_sbale_req(fsf_req); + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - erp_action->fsf_req = fsf_req; - fsf_req->erp_action = erp_action; - zfcp_erp_start_timer(fsf_req); - - retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); + req->handler = zfcp_fsf_exchange_port_data_handler; + req->erp_action = erp_action; + erp_action->fsf_req = req; + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); if (retval) { - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); erp_action->fsf_req = NULL; } +out: + spin_unlock(&adapter->req_q.lock); return retval; } - /** * zfcp_fsf_exchange_port_data_sync - request information about local port - * and wait until information is ready + * @adapter: pointer to struct zfcp_adapter + * @data: pointer to struct fsf_qtcb_bottom_port + * Returns: 0 on success, error otherwise */ -int -zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, - struct fsf_qtcb_bottom_port *data) +int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, + struct fsf_qtcb_bottom_port *data) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval; + struct zfcp_fsf_req *req = NULL; + int retval = -EIO; if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, - 0, NULL, &lock_flags, &fsf_req); - if (retval) { - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return retval; + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + + req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, + NULL); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; } if (data) - fsf_req->data = (unsigned long) data; + req->data = data; - sbale = zfcp_qdio_sbale_req(fsf_req); + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); - retval = zfcp_fsf_req_send(fsf_req); - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - + req->handler = zfcp_fsf_exchange_port_data_handler; + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); + retval = zfcp_fsf_req_send(req); +out: + spin_unlock(&adapter->req_q.lock); if (!retval) - wait_event(fsf_req->completion_wq, - fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); - - zfcp_fsf_req_free(fsf_req); - - return retval; -} - -/** - * zfcp_fsf_exchange_port_evaluate - * @fsf_req: fsf_req which belongs to xchg port data request - * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1) - */ -static void -zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) -{ - struct zfcp_adapter *adapter; - struct fsf_qtcb_bottom_port *bottom; - struct Scsi_Host *shost; - - adapter = fsf_req->adapter; - bottom = &fsf_req->qtcb->bottom.port; - shost = adapter->scsi_host; - - if (fsf_req->data) - memcpy((struct fsf_qtcb_bottom_port*) fsf_req->data, bottom, - sizeof(struct fsf_qtcb_bottom_port)); - - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) - fc_host_permanent_port_name(shost) = bottom->wwpn; - else - fc_host_permanent_port_name(shost) = fc_host_port_name(shost); - fc_host_maxframe_size(shost) = bottom->maximum_frame_size; - fc_host_supported_speeds(shost) = bottom->supported_speed; -} - -/** - * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request - * @fsf_req: pointer to struct zfcp_fsf_req - */ -static void -zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) -{ - struct zfcp_adapter *adapter; - struct fsf_qtcb *qtcb; - - adapter = fsf_req->adapter; - qtcb = fsf_req->qtcb; + wait_event(req->completion_wq, + req->status & ZFCP_STATUS_FSFREQ_COMPLETED); + zfcp_fsf_req_free(req); - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) - return; - - switch (qtcb->header.fsf_status) { - case FSF_GOOD: - zfcp_fsf_exchange_port_evaluate(fsf_req, 1); - atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - break; - case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: - zfcp_fsf_exchange_port_evaluate(fsf_req, 0); - atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - zfcp_fsf_link_down_info_eval(fsf_req, 43, - &qtcb->header.fsf_status_qual.link_down_info); - break; - } -} - - -/* - * function: zfcp_fsf_open_port - * - * purpose: - * - * returns: address of initiated FSF request - * NULL - request could not be initiated - */ -int -zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) -{ - volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval = 0; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(erp_action->adapter, - FSF_QTCB_OPEN_PORT_WITH_DID, - ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, - erp_action->adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval < 0) - goto out; - - sbale = zfcp_qdio_sbale_req(fsf_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - - fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id; - atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status); - fsf_req->data = (unsigned long) erp_action->port; - fsf_req->erp_action = erp_action; - erp_action->fsf_req = fsf_req; - - zfcp_erp_start_timer(fsf_req); - retval = zfcp_fsf_req_send(fsf_req); - if (retval) { - zfcp_fsf_req_free(fsf_req); - erp_action->fsf_req = NULL; - goto out; - } - - out: - write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); return retval; } -/* - * function: zfcp_fsf_open_port_handler - * - * purpose: is called for finished Open Port command - * - * returns: - */ -static int -zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) { - int retval = -EINVAL; - struct zfcp_port *port; + struct zfcp_port *port = req->data; + struct fsf_qtcb_header *header = &req->qtcb->header; struct fsf_plogi *plogi; - struct fsf_qtcb_header *header; - port = (struct zfcp_port *) fsf_req->data; - header = &fsf_req->qtcb->header; - - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - /* don't change port status in our bookkeeping */ + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; - } - /* evaluate FSF status in QTCB */ switch (header->fsf_status) { - case FSF_PORT_ALREADY_OPEN: - /* - * This is a bug, however operation should continue normally - * if it is simply ignored - */ break; - case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_port(fsf_req, port); + zfcp_fsf_access_denied_port(req, port); break; - case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The adapter is out of resources. The remote port " "0x%016Lx could not be opened, disabling it.\n", port->wwpn); - zfcp_erp_port_failed(port, 31, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_port_failed(port, 31, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* ERP strategy will escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* ERP strategy will escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SQ_NO_RETRY_POSSIBLE: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&req->adapter->ccw_device->dev, "The remote port 0x%016Lx could not be " "opened. Disabling it.\n", port->wwpn); - zfcp_erp_port_failed(port, 32, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - default: + zfcp_erp_port_failed(port, 32, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_GOOD: - /* save port handle assigned by FSF */ port->handle = header->port_handle; - /* mark port as open */ atomic_set_mask(ZFCP_STATUS_COMMON_OPEN | ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | ZFCP_STATUS_COMMON_ACCESS_BOXED, &port->status); - retval = 0; /* check whether D_ID has changed during open */ /* * FIXME: This check is not airtight, as the FCP channel does @@ -2021,227 +1471,168 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) * another GID_PN straight after a port has been opened. * Alternately, an ADISC/PDISC ELS should suffice, as well. */ - plogi = (struct fsf_plogi *) fsf_req->qtcb->bottom.support.els; - if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status)) - { - if (fsf_req->qtcb->bottom.support.els1_length < - sizeof (struct fsf_plogi)) { - /* skip sanity check and assume wwpn is ok */ - } else { - if (plogi->serv_param.wwpn != port->wwpn) { - atomic_clear_mask( - ZFCP_STATUS_PORT_DID_DID, - &port->status); - } else { - port->wwnn = plogi->serv_param.wwnn; - zfcp_fc_plogi_evaluate(port, plogi); - } + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN) + break; + + plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; + if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { + if (plogi->serv_param.wwpn != port->wwpn) + atomic_clear_mask(ZFCP_STATUS_PORT_DID_DID, + &port->status); + else { + port->wwnn = plogi->serv_param.wwnn; + zfcp_fc_plogi_evaluate(port, plogi); } } break; - case FSF_UNKNOWN_OP_SUBTYPE: - /* should never occure, subtype not set in zfcp_fsf_open_port */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - default: + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } - skip_fsfstatus: +skip_fsfstatus: atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &port->status); - return retval; } -/* - * function: zfcp_fsf_close_port - * - * purpose: submit FSF command "close port" - * - * returns: address of initiated FSF request - * NULL - request could not be initiated +/** + * zfcp_fsf_open_port - create and send open port request + * @erp_action: pointer to struct zfcp_erp_action + * Returns: 0 on success, error otherwise */ -int -zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) +int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval = 0; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(erp_action->adapter, - FSF_QTCB_CLOSE_PORT, - ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, - erp_action->adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval < 0) + struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_fsf_req *req; + int retval = -EIO; + + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) + goto out; + + req = zfcp_fsf_req_create(adapter, + FSF_QTCB_OPEN_PORT_WITH_DID, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); goto out; + } - sbale = zfcp_qdio_sbale_req(fsf_req); + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status); - fsf_req->data = (unsigned long) erp_action->port; - fsf_req->erp_action = erp_action; - fsf_req->qtcb->header.port_handle = erp_action->port->handle; - fsf_req->erp_action = erp_action; - erp_action->fsf_req = fsf_req; - - zfcp_erp_start_timer(fsf_req); - retval = zfcp_fsf_req_send(fsf_req); + req->handler = zfcp_fsf_open_port_handler; + req->qtcb->bottom.support.d_id = erp_action->port->d_id; + req->data = erp_action->port; + req->erp_action = erp_action; + erp_action->fsf_req = req; + atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status); + + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); if (retval) { - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); erp_action->fsf_req = NULL; - goto out; } - - out: - write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); +out: + spin_unlock(&adapter->req_q.lock); return retval; } -/* - * function: zfcp_fsf_close_port_handler - * - * purpose: is called for finished Close Port FSF command - * - * returns: - */ -static int -zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req) { - int retval = -EINVAL; - struct zfcp_port *port; - - port = (struct zfcp_port *) fsf_req->data; + struct zfcp_port *port = req->data; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - /* don't change port status in our bookkeeping */ + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; - } - - /* evaluate FSF status in QTCB */ - switch (fsf_req->qtcb->header.fsf_status) { + switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(port->adapter, 0, 107, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_adapter_reopen(port->adapter, 0, 107, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ADAPTER_STATUS_AVAILABLE: - /* Note: FSF has actually closed the port in this case. - * The status code is just daft. Fingers crossed for a change - */ - retval = 0; break; - case FSF_GOOD: - zfcp_erp_modify_port_status(port, 33, fsf_req, + zfcp_erp_modify_port_status(port, 33, req, ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); - retval = 0; break; } - skip_fsfstatus: +skip_fsfstatus: atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &port->status); - return retval; } -/* - * function: zfcp_fsf_close_physical_port - * - * purpose: submit FSF command "close physical port" - * - * returns: address of initiated FSF request - * NULL - request could not be initiated +/** + * zfcp_fsf_close_port - create and send close port request + * @erp_action: pointer to struct zfcp_erp_action + * Returns: 0 on success, error otherwise */ -int -zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) +int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval = 0; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(erp_action->adapter, - FSF_QTCB_CLOSE_PHYSICAL_PORT, - ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, - erp_action->adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval < 0) + struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_fsf_req *req; + int retval = -EIO; + + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) + goto out; + + req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); goto out; + } - sbale = zfcp_qdio_sbale_req(fsf_req); + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - /* mark port as being closed */ - atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, - &erp_action->port->status); - /* save a pointer to this port */ - fsf_req->data = (unsigned long) erp_action->port; - fsf_req->qtcb->header.port_handle = erp_action->port->handle; - fsf_req->erp_action = erp_action; - erp_action->fsf_req = fsf_req; - - zfcp_erp_start_timer(fsf_req); - retval = zfcp_fsf_req_send(fsf_req); + req->handler = zfcp_fsf_close_port_handler; + req->data = erp_action->port; + req->erp_action = erp_action; + req->qtcb->header.port_handle = erp_action->port->handle; + erp_action->fsf_req = req; + atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status); + + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); if (retval) { - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); erp_action->fsf_req = NULL; - goto out; } - - out: - write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); +out: + spin_unlock(&adapter->req_q.lock); return retval; } -/* - * function: zfcp_fsf_close_physical_port_handler - * - * purpose: is called for finished Close Physical Port FSF command - * - * returns: - */ -static int -zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) { - int retval = -EINVAL; - struct zfcp_port *port; + struct zfcp_port *port = req->data; + struct fsf_qtcb_header *header = &req->qtcb->header; struct zfcp_unit *unit; - struct fsf_qtcb_header *header; - - port = (struct zfcp_port *) fsf_req->data; - header = &fsf_req->qtcb->header; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - /* don't change port status in our bookkeeping */ + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; - } - /* evaluate FSF status in QTCB */ switch (header->fsf_status) { - case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(port->adapter, 0, 108, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_adapter_reopen(port->adapter, 0, 108, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_port(fsf_req, port); + zfcp_fsf_access_denied_port(req, port); break; - case FSF_PORT_BOXED: - zfcp_erp_port_boxed(port, 50, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | - ZFCP_STATUS_FSFREQ_RETRY; - + zfcp_erp_port_boxed(port, 50, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; /* can't use generic zfcp_erp_modify_port_status because * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); @@ -2249,120 +1640,88 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); break; - case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* This will now be escalated by ERP */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; + /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* ERP strategy will escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_GOOD: /* can't use generic zfcp_erp_modify_port_status because * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); list_for_each_entry(unit, &port->unit_list_head, list) - atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); - retval = 0; + atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, + &unit->status); break; } - - skip_fsfstatus: +skip_fsfstatus: atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, &port->status); - return retval; } -/* - * function: zfcp_fsf_open_unit - * - * purpose: - * - * returns: - * - * assumptions: This routine does not check whether the associated - * remote port has already been opened. This should be - * done by calling routines. Otherwise some status - * may be presented by FSF +/** + * zfcp_fsf_close_physical_port - close physical port + * @erp_action: pointer to struct zfcp_erp_action + * Returns: 0 on success */ -int -zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) +int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval = 0; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(erp_action->adapter, - FSF_QTCB_OPEN_LUN, - ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, - erp_action->adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval < 0) + struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_fsf_req *req; + int retval = -EIO; + + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) goto out; - sbale = zfcp_qdio_sbale_req(fsf_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; + } - fsf_req->qtcb->header.port_handle = erp_action->port->handle; - fsf_req->qtcb->bottom.support.fcp_lun = erp_action->unit->fcp_lun; - if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE)) - fsf_req->qtcb->bottom.support.option = - FSF_OPEN_LUN_SUPPRESS_BOXING; - atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); - fsf_req->data = (unsigned long) erp_action->unit; - fsf_req->erp_action = erp_action; - erp_action->fsf_req = fsf_req; + sbale = zfcp_qdio_sbale_req(req); + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - zfcp_erp_start_timer(fsf_req); - retval = zfcp_fsf_req_send(erp_action->fsf_req); + req->data = erp_action->port; + req->qtcb->header.port_handle = erp_action->port->handle; + req->erp_action = erp_action; + req->handler = zfcp_fsf_close_physical_port_handler; + erp_action->fsf_req = req; + atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, + &erp_action->port->status); + + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); if (retval) { - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); erp_action->fsf_req = NULL; - goto out; } - out: - write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); +out: + spin_unlock(&adapter->req_q.lock); return retval; } -/* - * function: zfcp_fsf_open_unit_handler - * - * purpose: is called for finished Open LUN command - * - * returns: - */ -static int -zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) { - int retval = -EINVAL; - struct zfcp_adapter *adapter; - struct zfcp_unit *unit; - struct fsf_qtcb_header *header; - struct fsf_qtcb_bottom_support *bottom; - struct fsf_queue_designator *queue_designator; + struct zfcp_adapter *adapter = req->adapter; + struct zfcp_unit *unit = req->data; + struct fsf_qtcb_header *header = &req->qtcb->header; + struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support; + struct fsf_queue_designator *queue_designator = + &header->fsf_status_qual.fsf_queue_designator; int exclusive, readwrite; - unit = (struct zfcp_unit *) fsf_req->data; - - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - /* don't change unit status in our bookkeeping */ + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; - } - - adapter = fsf_req->adapter; - header = &fsf_req->qtcb->header; - bottom = &fsf_req->qtcb->bottom.support; - queue_designator = &header->fsf_status_qual.fsf_queue_designator; atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | ZFCP_STATUS_COMMON_ACCESS_BOXED | @@ -2370,32 +1729,25 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) ZFCP_STATUS_UNIT_READONLY, &unit->status); - /* evaluate FSF status in QTCB */ switch (header->fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - + zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, req); + /* fall through */ case FSF_LUN_ALREADY_OPEN: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_unit(fsf_req, unit); + zfcp_fsf_access_denied_unit(req, unit); atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); break; - case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, 51, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | - ZFCP_STATUS_FSFREQ_RETRY; + zfcp_erp_port_boxed(unit->port, 51, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; break; - case FSF_LUN_SHARING_VIOLATION: - if (header->fsf_status_qual.word[0] != 0) { + if (header->fsf_status_qual.word[0]) dev_warn(&adapter->ccw_device->dev, "FCP-LUN 0x%Lx at the remote port " "with WWPN 0x%Lx " @@ -2405,47 +1757,37 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) unit->port->wwpn, queue_designator->hla, queue_designator->cssid); - } else + else zfcp_act_eval_err(adapter, header->fsf_status_qual.word[2]); - zfcp_erp_unit_access_denied(unit, 60, fsf_req); + zfcp_erp_unit_access_denied(unit, 60, req); atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: - dev_warn(&fsf_req->adapter->ccw_device->dev, + dev_warn(&adapter->ccw_device->dev, "The adapter ran out of resources. There is no " "handle available for unit 0x%016Lx on port 0x%016Lx.", unit->fcp_lun, unit->port->wwpn); - zfcp_erp_unit_failed(unit, 34, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_unit_failed(unit, 34, req); + /* fall through */ + case FSF_INVALID_COMMAND_OPTION: + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* Re-establish link to port */ zfcp_test_link(unit->port); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; + /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* ERP strategy will escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_INVALID_COMMAND_OPTION: - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - retval = -EINVAL; - break; - case FSF_GOOD: - /* save LUN handle assigned by FSF */ unit->handle = header->lun_handle; - /* mark unit as open */ atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) && @@ -2463,412 +1805,192 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) if (!readwrite) { atomic_set_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); - dev_info(&fsf_req->adapter->ccw_device->dev, + dev_info(&adapter->ccw_device->dev, "Read-only access for unit 0x%016Lx " "on port 0x%016Lx.\n", unit->fcp_lun, unit->port->wwpn); } if (exclusive && !readwrite) { - dev_err(&fsf_req->adapter->ccw_device->dev, + dev_err(&adapter->ccw_device->dev, "Exclusive access of read-only unit " "0x%016Lx on port 0x%016Lx not " "supported, disabling unit.\n", unit->fcp_lun, unit->port->wwpn); - zfcp_erp_unit_failed(unit, 35, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - zfcp_erp_unit_shutdown(unit, 0, 80, fsf_req); + zfcp_erp_unit_failed(unit, 35, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_unit_shutdown(unit, 0, 80, req); } else if (!exclusive && readwrite) { - dev_err(&fsf_req->adapter->ccw_device->dev, + dev_err(&adapter->ccw_device->dev, "Shared access of read-write unit " "0x%016Lx on port 0x%016Lx not " "supported, disabling unit.\n", unit->fcp_lun, unit->port->wwpn); - zfcp_erp_unit_failed(unit, 36, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - zfcp_erp_unit_shutdown(unit, 0, 81, fsf_req); + zfcp_erp_unit_failed(unit, 36, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_unit_shutdown(unit, 0, 81, req); } } - - retval = 0; break; } - skip_fsfstatus: +skip_fsfstatus: atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &unit->status); - return retval; } -/* - * function: zfcp_fsf_close_unit - * - * purpose: - * - * returns: address of fsf_req - request successfully initiated - * NULL - - * - * assumptions: This routine does not check whether the associated - * remote port/lun has already been opened. This should be - * done by calling routines. Otherwise some status - * may be presented by FSF +/** + * zfcp_fsf_open_unit - open unit + * @erp_action: pointer to struct zfcp_erp_action + * Returns: 0 on success, error otherwise */ -int -zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) +int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req; - unsigned long lock_flags; - int retval = 0; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(erp_action->adapter, - FSF_QTCB_CLOSE_LUN, - ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP, - erp_action->adapter->pool.fsf_req_erp, - &lock_flags, &fsf_req); - if (retval < 0) + struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_fsf_req *req; + int retval = -EIO; + + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) goto out; - sbale = zfcp_qdio_sbale_req(fsf_req); + req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; + } + + sbale = zfcp_qdio_sbale_req(req); sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - fsf_req->qtcb->header.port_handle = erp_action->port->handle; - fsf_req->qtcb->header.lun_handle = erp_action->unit->handle; - atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status); - fsf_req->data = (unsigned long) erp_action->unit; - fsf_req->erp_action = erp_action; - erp_action->fsf_req = fsf_req; + req->qtcb->header.port_handle = erp_action->port->handle; + req->qtcb->bottom.support.fcp_lun = erp_action->unit->fcp_lun; + req->handler = zfcp_fsf_open_unit_handler; + req->data = erp_action->unit; + req->erp_action = erp_action; + erp_action->fsf_req = req; + + if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) + req->qtcb->bottom.support.option = FSF_OPEN_LUN_SUPPRESS_BOXING; + + atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); - zfcp_erp_start_timer(fsf_req); - retval = zfcp_fsf_req_send(erp_action->fsf_req); + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); if (retval) { - zfcp_fsf_req_free(fsf_req); + zfcp_fsf_req_free(req); erp_action->fsf_req = NULL; - goto out; } - - out: - write_unlock_irqrestore(&erp_action->adapter->req_q.lock, lock_flags); +out: + spin_unlock(&adapter->req_q.lock); return retval; } -/* - * function: zfcp_fsf_close_unit_handler - * - * purpose: is called for finished Close LUN FSF command - * - * returns: - */ -static int -zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) { - int retval = -EINVAL; - struct zfcp_unit *unit; - - unit = (struct zfcp_unit *) fsf_req->data; + struct zfcp_unit *unit = req->data; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - /* don't change unit status in our bookkeeping */ + if (req->status & ZFCP_STATUS_FSFREQ_ERROR) goto skip_fsfstatus; - } - - /* evaluate FSF status in QTCB */ - switch (fsf_req->qtcb->header.fsf_status) { + switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_LUN_HANDLE_NOT_VALID: - zfcp_erp_port_reopen(unit->port, 0, 111, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; + zfcp_erp_port_reopen(unit->port, 0, 111, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, 52, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | - ZFCP_STATUS_FSFREQ_RETRY; + zfcp_erp_port_boxed(unit->port, 52, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; break; - case FSF_ADAPTER_STATUS_AVAILABLE: - switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { + switch (req->qtcb->header.fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* re-establish link to port */ zfcp_test_link(unit->port); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; + /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* ERP strategy will escalate */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - default: + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } break; - case FSF_GOOD: - /* mark unit as closed */ atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); - retval = 0; break; } - - skip_fsfstatus: +skip_fsfstatus: atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &unit->status); - return retval; } /** - * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) - * @adapter: adapter where scsi command is issued - * @unit: unit where command is sent to - * @scsi_cmnd: scsi command to be sent - * @timer: timer to be started when request is initiated - * @req_flags: flags for fsf_request + * zfcp_fsf_close_unit - close zfcp unit + * @erp_action: pointer to struct zfcp_unit + * Returns: 0 on success, error otherwise */ -int -zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, - struct zfcp_unit *unit, - struct scsi_cmnd * scsi_cmnd, - int use_timer, int req_flags) -{ - struct zfcp_fsf_req *fsf_req = NULL; - struct fcp_cmnd_iu *fcp_cmnd_iu; - unsigned int sbtype; - unsigned long lock_flags; - int real_bytes = 0; - int retval = 0; - int mask; - - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, - adapter->pool.fsf_req_scsi, - &lock_flags, &fsf_req); - if (unlikely(retval < 0)) - goto failed_req_create; - - if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &unit->status))) { - retval = -EBUSY; - goto unit_blocked; - } - - zfcp_unit_get(unit); - fsf_req->unit = unit; - - /* associate FSF request with SCSI request (for look up on abort) */ - scsi_cmnd->host_scribble = (unsigned char *) fsf_req->req_id; - - /* associate SCSI command with FSF request */ - fsf_req->data = (unsigned long) scsi_cmnd; - - /* set handles of unit and its parent port in QTCB */ - fsf_req->qtcb->header.lun_handle = unit->handle; - fsf_req->qtcb->header.port_handle = unit->port->handle; - - /* FSF does not define the structure of the FCP_CMND IU */ - fcp_cmnd_iu = (struct fcp_cmnd_iu *) - &(fsf_req->qtcb->bottom.io.fcp_cmnd); - - /* - * set depending on data direction: - * data direction bits in SBALE (SB Type) - * data direction bits in QTCB - * data direction bits in FCP_CMND IU - */ - switch (scsi_cmnd->sc_data_direction) { - case DMA_NONE: - fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; - /* - * FIXME(qdio): - * what is the correct type for commands - * without 'real' data buffers? - */ - sbtype = SBAL_FLAGS0_TYPE_READ; - break; - case DMA_FROM_DEVICE: - fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; - sbtype = SBAL_FLAGS0_TYPE_READ; - fcp_cmnd_iu->rddata = 1; - break; - case DMA_TO_DEVICE: - fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; - sbtype = SBAL_FLAGS0_TYPE_WRITE; - fcp_cmnd_iu->wddata = 1; - break; - case DMA_BIDIRECTIONAL: - default: - /* - * dummy, catch this condition earlier - * in zfcp_scsi_queuecommand - */ - goto failed_scsi_cmnd; - } - - /* set FC service class in QTCB (3 per default) */ - fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT; - - /* set FCP_LUN in FCP_CMND IU in QTCB */ - fcp_cmnd_iu->fcp_lun = unit->fcp_lun; - - mask = ZFCP_STATUS_UNIT_READONLY | ZFCP_STATUS_UNIT_SHARED; - - /* set task attributes in FCP_CMND IU in QTCB */ - if (likely((scsi_cmnd->device->simple_tags) || - (atomic_test_mask(mask, &unit->status)))) - fcp_cmnd_iu->task_attribute = SIMPLE_Q; - else - fcp_cmnd_iu->task_attribute = UNTAGGED; - - /* set additional length of FCP_CDB in FCP_CMND IU in QTCB, if needed */ - if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) - fcp_cmnd_iu->add_fcp_cdb_length - = (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2; - /* - * copy SCSI CDB (including additional length, if any) to - * FCP_CDB in FCP_CMND IU in QTCB - */ - memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); - - /* FCP CMND IU length in QTCB */ - fsf_req->qtcb->bottom.io.fcp_cmnd_length = - sizeof (struct fcp_cmnd_iu) + - fcp_cmnd_iu->add_fcp_cdb_length + sizeof (fcp_dl_t); - - /* generate SBALEs from data buffer */ - real_bytes = zfcp_qdio_sbals_from_sg(fsf_req, sbtype, - scsi_sglist(scsi_cmnd), - ZFCP_MAX_SBALS_PER_REQ); - if (unlikely(real_bytes < 0)) { - if (fsf_req->sbal_number < ZFCP_MAX_SBALS_PER_REQ) - retval = -EIO; - else { - dev_err(&adapter->ccw_device->dev, - "SCSI request too large. " - "Shutting down unit 0x%016Lx on port " - "0x%016Lx.\n", unit->fcp_lun, - unit->port->wwpn); - zfcp_erp_unit_shutdown(unit, 0, 131, fsf_req); - retval = -EINVAL; - } - goto no_fit; - } - - /* set length of FCP data length in FCP_CMND IU in QTCB */ - zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes); - - if (use_timer) - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); - - retval = zfcp_fsf_req_send(fsf_req); - if (unlikely(retval < 0)) - goto send_failed; - - goto success; - - send_failed: - no_fit: - failed_scsi_cmnd: - zfcp_unit_put(unit); - unit_blocked: - zfcp_fsf_req_free(fsf_req); - fsf_req = NULL; - scsi_cmnd->host_scribble = NULL; - success: - failed_req_create: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return retval; -} - -struct zfcp_fsf_req * -zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, - struct zfcp_unit *unit, - u8 tm_flags, int req_flags) +int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) { - struct zfcp_fsf_req *fsf_req = NULL; - int retval = 0; - struct fcp_cmnd_iu *fcp_cmnd_iu; - unsigned long lock_flags; volatile struct qdio_buffer_element *sbale; + struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_fsf_req *req; + int retval = -EIO; - /* setup new FSF request */ - retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, - adapter->pool.fsf_req_scsi, - &lock_flags, &fsf_req); - if (retval < 0) + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) goto out; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, + ZFCP_REQ_AUTO_CLEANUP, + adapter->pool.fsf_req_erp); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; + } - if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &unit->status))) - goto unit_blocked; - - /* - * Used to decide on proper handler in the return path, - * could be either zfcp_fsf_send_fcp_command_task_handler or - * zfcp_fsf_send_fcp_command_task_management_handler */ - - fsf_req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; - - /* - * hold a pointer to the unit being target of this - * task management request - */ - fsf_req->data = (unsigned long) unit; - - /* set FSF related fields in QTCB */ - fsf_req->qtcb->header.lun_handle = unit->handle; - fsf_req->qtcb->header.port_handle = unit->port->handle; - fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; - fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT; - fsf_req->qtcb->bottom.io.fcp_cmnd_length = - sizeof (struct fcp_cmnd_iu) + sizeof (fcp_dl_t); - - sbale = zfcp_qdio_sbale_req(fsf_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; + sbale = zfcp_qdio_sbale_req(req); + sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - /* set FCP related fields in FCP_CMND IU in QTCB */ - fcp_cmnd_iu = (struct fcp_cmnd_iu *) - &(fsf_req->qtcb->bottom.io.fcp_cmnd); - fcp_cmnd_iu->fcp_lun = unit->fcp_lun; - fcp_cmnd_iu->task_management_flags = tm_flags; - - zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT); - retval = zfcp_fsf_req_send(fsf_req); - if (!retval) - goto out; - - unit_blocked: - zfcp_fsf_req_free(fsf_req); - fsf_req = NULL; + req->qtcb->header.port_handle = erp_action->port->handle; + req->qtcb->header.lun_handle = erp_action->unit->handle; + req->handler = zfcp_fsf_close_unit_handler; + req->data = erp_action->unit; + req->erp_action = erp_action; + erp_action->fsf_req = req; + atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status); - out: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return fsf_req; + zfcp_erp_start_timer(req); + retval = zfcp_fsf_req_send(req); + if (retval) { + zfcp_fsf_req_free(req); + erp_action->fsf_req = NULL; + } +out: + spin_unlock(&adapter->req_q.lock); + return retval; } static void zfcp_fsf_update_lat(struct fsf_latency_record *lat_rec, u32 lat) { lat_rec->sum += lat; - if (lat_rec->min > lat) - lat_rec->min = lat; - if (lat_rec->max < lat) - lat_rec->max = lat; + lat_rec->min = min(lat_rec->min, lat); + lat_rec->max = max(lat_rec->max, lat); } -static void zfcp_fsf_req_latency(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req) { struct fsf_qual_latency_info *lat_inf; struct latency_cont *lat; - struct zfcp_unit *unit; + struct zfcp_unit *unit = req->unit; unsigned long flags; - lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; - unit = fsf_req->unit; + lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info; - switch (fsf_req->qtcb->bottom.io.data_direction) { + switch (req->qtcb->bottom.io.data_direction) { case FSF_DATADIR_READ: lat = &unit->latencies.read; break; @@ -2886,212 +2008,53 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *fsf_req) zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat); zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat); lat->counter++; - spin_unlock_irqrestore(&unit->latencies.lock, flags); -} - -/* - * function: zfcp_fsf_send_fcp_command_handler - * - * purpose: is called for finished Send FCP Command - * - * returns: - */ -static int -zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) -{ - int retval = -EINVAL; - struct zfcp_unit *unit; - struct fsf_qtcb_header *header; - - header = &fsf_req->qtcb->header; - - if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)) - unit = (struct zfcp_unit *) fsf_req->data; - else - unit = fsf_req->unit; - - if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { - /* go directly to calls of special handlers */ - goto skip_fsfstatus; - } - - /* evaluate FSF status in QTCB */ - switch (header->fsf_status) { - - case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_LUN_HANDLE_NOT_VALID: - zfcp_erp_port_reopen(unit->port, 0, 113, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_HANDLE_MISMATCH: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, 114, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_SERVICE_CLASS_NOT_SUPPORTED: - zfcp_fsf_class_not_supp(fsf_req); - break; - - case FSF_FCPLUN_NOT_VALID: - zfcp_erp_port_reopen(unit->port, 0, 115, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_unit(fsf_req, unit); - break; - - case FSF_DIRECTION_INDICATOR_NOT_VALID: - dev_err(&fsf_req->adapter->ccw_device->dev, - "Invalid data direction (%d) given for unit 0x%016Lx " - "on port 0x%016Lx, shutting down adapter.\n", - fsf_req->qtcb->bottom.io.data_direction, - unit->fcp_lun, unit->port->wwpn); - zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_CMND_LENGTH_NOT_VALID: - dev_err(&fsf_req->adapter->ccw_device->dev, - "An invalid control-data-block length field (%d) " - "was found in a command for unit 0x%016Lx on port " - "0x%016Lx. Shutting down adapter.\n", - fsf_req->qtcb->bottom.io.fcp_cmnd_length, - unit->fcp_lun, unit->port->wwpn); - zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, 53, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | - ZFCP_STATUS_FSFREQ_RETRY; - break; - - case FSF_LUN_BOXED: - zfcp_erp_unit_boxed(unit, 54, fsf_req); - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR - | ZFCP_STATUS_FSFREQ_RETRY; - break; - - case FSF_ADAPTER_STATUS_AVAILABLE: - switch (header->fsf_status_qual.word[0]) { - case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* re-establish link to port */ - zfcp_test_link(unit->port); - break; - case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: - /* FIXME(hw) need proper specs for proper action */ - /* let scsi stack deal with retries and escalation */ - break; - } - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; - - case FSF_GOOD: - break; - - case FSF_FCP_RSP_AVAILABLE: - break; - } - - skip_fsfstatus: - if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) { - retval = - zfcp_fsf_send_fcp_command_task_management_handler(fsf_req); - } else { - retval = zfcp_fsf_send_fcp_command_task_handler(fsf_req); - fsf_req->unit = NULL; - zfcp_unit_put(unit); - } - return retval; + spin_unlock_irqrestore(&unit->latencies.lock, flags); } -/* - * function: zfcp_fsf_send_fcp_command_task_handler - * - * purpose: evaluates FCP_RSP IU - * - * returns: - */ -static int -zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) { - int retval = 0; - struct scsi_cmnd *scpnt; + struct scsi_cmnd *scpnt = req->data; struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) - &(fsf_req->qtcb->bottom.io.fcp_rsp); + &(req->qtcb->bottom.io.fcp_rsp); u32 sns_len; char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; unsigned long flags; - read_lock_irqsave(&fsf_req->adapter->abort_lock, flags); - scpnt = (struct scsi_cmnd *) fsf_req->data; if (unlikely(!scpnt)) - goto out; + return; - if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { - /* FIXME: (design) mid-layer should handle DID_ABORT like - * DID_SOFT_ERROR by retrying the request for devices - * that allow retries. - */ + read_lock_irqsave(&req->adapter->abort_lock, flags); + + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { set_host_byte(scpnt, DID_SOFT_ERROR); set_driver_byte(scpnt, SUGGEST_RETRY); goto skip_fsfstatus; } - if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; } - /* set message byte of result in SCSI command */ set_msg_byte(scpnt, COMMAND_COMPLETE); - /* - * copy SCSI status code of FCP_STATUS of FCP_RSP IU to status byte - * of result in SCSI command - */ scpnt->result |= fcp_rsp_iu->scsi_status; - if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) - zfcp_fsf_req_latency(fsf_req); + if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) + zfcp_fsf_req_latency(req); - /* check FCP_RSP_INFO */ if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { - switch (fcp_rsp_info[3]) { - case RSP_CODE_GOOD: - /* ok, continue */ + if (fcp_rsp_info[3] == RSP_CODE_GOOD) set_host_byte(scpnt, DID_OK); - break; - case RSP_CODE_LENGTH_MISMATCH: - /* hardware bug */ - set_host_byte(scpnt, DID_ERROR); - goto skip_fsfstatus; - case RSP_CODE_FIELD_INVALID: - /* driver or hardware bug */ - set_host_byte(scpnt, DID_ERROR); - goto skip_fsfstatus; - case RSP_CODE_RO_MISMATCH: - /* hardware bug */ - set_host_byte(scpnt, DID_ERROR); - goto skip_fsfstatus; - default: - /* invalid FCP response code */ + else { set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; } } - /* check for sense data */ if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) { - sns_len = FSF_FCP_RSP_SIZE - - sizeof (struct fcp_rsp_iu) + fcp_rsp_iu->fcp_rsp_len; + sns_len = FSF_FCP_RSP_SIZE - sizeof(struct fcp_rsp_iu) + + fcp_rsp_iu->fcp_rsp_len; sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE); sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len); @@ -3099,382 +2062,372 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len); } - /* check for underrun */ if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) { scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid); if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) < scpnt->underflow) set_host_byte(scpnt, DID_ERROR); } - - skip_fsfstatus: +skip_fsfstatus: if (scpnt->result != 0) - zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req); + zfcp_scsi_dbf_event_result("erro", 3, req->adapter, scpnt, req); else if (scpnt->retries > 0) - zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req); + zfcp_scsi_dbf_event_result("retr", 4, req->adapter, scpnt, req); else - zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req); + zfcp_scsi_dbf_event_result("norm", 6, req->adapter, scpnt, req); - /* cleanup pointer (need this especially for abort) */ scpnt->host_scribble = NULL; - - /* always call back */ (scpnt->scsi_done) (scpnt); - /* * We must hold this lock until scsi_done has been called. * Otherwise we may call scsi_done after abort regarding this * command has completed. * Note: scsi_done must not block! */ - out: - read_unlock_irqrestore(&fsf_req->adapter->abort_lock, flags); - return retval; + read_unlock_irqrestore(&req->adapter->abort_lock, flags); } -/* - * function: zfcp_fsf_send_fcp_command_task_management_handler - * - * purpose: evaluates FCP_RSP IU - * - * returns: - */ -static int -zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) +static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) { - int retval = 0; struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) - &(fsf_req->qtcb->bottom.io.fcp_rsp); + &(req->qtcb->bottom.io.fcp_rsp); char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; - if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { - fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; + if ((fcp_rsp_info[3] != RSP_CODE_GOOD) || + (req->status & ZFCP_STATUS_FSFREQ_ERROR)) + req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; +} + + +static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) +{ + struct zfcp_unit *unit; + struct fsf_qtcb_header *header = &req->qtcb->header; + + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)) + unit = req->data; + else + unit = req->unit; + + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) goto skip_fsfstatus; - } - /* check FCP_RSP_INFO */ - switch (fcp_rsp_info[3]) { - case RSP_CODE_GOOD: - /* ok, continue */ + switch (header->fsf_status) { + case FSF_HANDLE_MISMATCH: + case FSF_PORT_HANDLE_NOT_VALID: + zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + break; + case FSF_FCPLUN_NOT_VALID: + case FSF_LUN_HANDLE_NOT_VALID: + zfcp_erp_port_reopen(unit->port, 0, 113, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case RSP_CODE_TASKMAN_UNSUPP: - fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP; + case FSF_SERVICE_CLASS_NOT_SUPPORTED: + zfcp_fsf_class_not_supp(req); break; - case RSP_CODE_TASKMAN_FAILED: - fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; + case FSF_ACCESS_DENIED: + zfcp_fsf_access_denied_unit(req, unit); + break; + case FSF_DIRECTION_INDICATOR_NOT_VALID: + dev_err(&req->adapter->ccw_device->dev, + "Invalid data direction (%d) given for unit " + "0x%016Lx on port 0x%016Lx, shutting down " + "adapter.\n", + req->qtcb->bottom.io.data_direction, + unit->fcp_lun, unit->port->wwpn); + zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + break; + case FSF_CMND_LENGTH_NOT_VALID: + dev_err(&req->adapter->ccw_device->dev, + "An invalid control-data-block length field (%d) " + "was found in a command for unit 0x%016Lx on port " + "0x%016Lx. Shutting down adapter.\n", + req->qtcb->bottom.io.fcp_cmnd_length, + unit->fcp_lun, unit->port->wwpn); + zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + break; + case FSF_PORT_BOXED: + zfcp_erp_port_boxed(unit->port, 53, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; + break; + case FSF_LUN_BOXED: + zfcp_erp_unit_boxed(unit, 54, req); + req->status |= ZFCP_STATUS_FSFREQ_ERROR | + ZFCP_STATUS_FSFREQ_RETRY; + break; + case FSF_ADAPTER_STATUS_AVAILABLE: + if (header->fsf_status_qual.word[0] == + FSF_SQ_INVOKE_LINK_TEST_PROCEDURE) + zfcp_test_link(unit->port); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - default: - /* invalid FCP response code */ - fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; } - - skip_fsfstatus: - return retval; +skip_fsfstatus: + if (req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) + zfcp_fsf_send_fcp_ctm_handler(req); + else { + zfcp_fsf_send_fcp_command_task_handler(req); + req->unit = NULL; + zfcp_unit_put(unit); + } } - -/* - * function: zfcp_fsf_control_file - * - * purpose: Initiator of the control file upload/download FSF requests - * - * returns: 0 - FSF request is successfuly created and queued - * -EOPNOTSUPP - The FCP adapter does not have Control File support - * -EINVAL - Invalid direction specified - * -ENOMEM - Insufficient memory - * -EPERM - Cannot create FSF request or place it in QDIO queue +/** + * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) + * @adapter: adapter where scsi command is issued + * @unit: unit where command is sent to + * @scsi_cmnd: scsi command to be sent + * @timer: timer to be started when request is initiated + * @req_flags: flags for fsf_request */ -struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, - struct zfcp_fsf_cfdc *fsf_cfdc) +int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, + struct zfcp_unit *unit, + struct scsi_cmnd *scsi_cmnd, + int use_timer, int req_flags) { - struct zfcp_fsf_req *fsf_req; - struct fsf_qtcb_bottom_support *bottom; - volatile struct qdio_buffer_element *sbale; - unsigned long lock_flags; - int direction; - int retval; - int bytes; + struct zfcp_fsf_req *req; + struct fcp_cmnd_iu *fcp_cmnd_iu; + unsigned int sbtype; + int real_bytes, retval = -EIO; - if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) - return ERR_PTR(-EOPNOTSUPP); + if (unlikely(!(atomic_read(&unit->status) & + ZFCP_STATUS_COMMON_UNBLOCKED))) + return -EBUSY; - switch (fsf_cfdc->command) { - case FSF_QTCB_DOWNLOAD_CONTROL_FILE: - direction = SBAL_FLAGS0_TYPE_WRITE; + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, + adapter->pool.fsf_req_scsi); + if (unlikely(IS_ERR(req))) { + retval = PTR_ERR(req); + goto out; + } + + zfcp_unit_get(unit); + req->unit = unit; + req->data = scsi_cmnd; + req->handler = zfcp_fsf_send_fcp_command_handler; + req->qtcb->header.lun_handle = unit->handle; + req->qtcb->header.port_handle = unit->port->handle; + req->qtcb->bottom.io.service_class = FSF_CLASS_3; + + scsi_cmnd->host_scribble = (unsigned char *) req->req_id; + + fcp_cmnd_iu = (struct fcp_cmnd_iu *) &(req->qtcb->bottom.io.fcp_cmnd); + fcp_cmnd_iu->fcp_lun = unit->fcp_lun; + /* + * set depending on data direction: + * data direction bits in SBALE (SB Type) + * data direction bits in QTCB + * data direction bits in FCP_CMND IU + */ + switch (scsi_cmnd->sc_data_direction) { + case DMA_NONE: + req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; + sbtype = SBAL_FLAGS0_TYPE_READ; break; - case FSF_QTCB_UPLOAD_CONTROL_FILE: - direction = SBAL_FLAGS0_TYPE_READ; + case DMA_FROM_DEVICE: + req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; + sbtype = SBAL_FLAGS0_TYPE_READ; + fcp_cmnd_iu->rddata = 1; + break; + case DMA_TO_DEVICE: + req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; + sbtype = SBAL_FLAGS0_TYPE_WRITE; + fcp_cmnd_iu->wddata = 1; break; + case DMA_BIDIRECTIONAL: default: - return ERR_PTR(-EINVAL); + retval = -EIO; + goto failed_scsi_cmnd; } - retval = zfcp_fsf_req_create(adapter, fsf_cfdc->command, - ZFCP_WAIT_FOR_SBAL, - NULL, &lock_flags, &fsf_req); - if (retval < 0) { - retval = -EPERM; - goto unlock_queue_lock; - } + if (likely((scsi_cmnd->device->simple_tags) || + ((atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) && + (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_SHARED)))) + fcp_cmnd_iu->task_attribute = SIMPLE_Q; + else + fcp_cmnd_iu->task_attribute = UNTAGGED; - sbale = zfcp_qdio_sbale_req(fsf_req); - sbale[0].flags |= direction; + if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) + fcp_cmnd_iu->add_fcp_cdb_length = + (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2; - bottom = &fsf_req->qtcb->bottom.support; - bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; - bottom->option = fsf_cfdc->option; + memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); - bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction, - fsf_cfdc->sg, - ZFCP_MAX_SBALS_PER_REQ); - if (bytes != ZFCP_CFDC_MAX_SIZE) { - retval = -ENOMEM; - goto free_fsf_req; - } + req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + + fcp_cmnd_iu->add_fcp_cdb_length + sizeof(fcp_dl_t); - zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT); - retval = zfcp_fsf_req_send(fsf_req); - if (retval < 0) { - retval = -EPERM; - goto free_fsf_req; + real_bytes = zfcp_qdio_sbals_from_sg(req, sbtype, + scsi_sglist(scsi_cmnd), + FSF_MAX_SBALS_PER_REQ); + if (unlikely(real_bytes < 0)) { + if (req->sbal_number < FSF_MAX_SBALS_PER_REQ) + retval = -EIO; + else { + dev_err(&adapter->ccw_device->dev, + "SCSI request too large. " + "Shutting down unit 0x%016Lx on port " + "0x%016Lx.\n", unit->fcp_lun, + unit->port->wwpn); + zfcp_erp_unit_shutdown(unit, 0, 131, req); + retval = -EINVAL; + } + goto failed_scsi_cmnd; } - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - - wait_event(fsf_req->completion_wq, - fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); - return fsf_req; + zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes); - free_fsf_req: - zfcp_fsf_req_free(fsf_req); - unlock_queue_lock: - write_unlock_irqrestore(&adapter->req_q.lock, lock_flags); - return ERR_PTR(retval); -} + if (use_timer) + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); -static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req) -{ - if (fsf_req->qtcb->header.fsf_status != FSF_GOOD) - fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; -} + retval = zfcp_fsf_req_send(req); + if (unlikely(retval)) + goto failed_scsi_cmnd; -static inline int -zfcp_fsf_req_sbal_check(unsigned long *flags, - struct zfcp_qdio_queue *queue, int needed) -{ - write_lock_irqsave(&queue->lock, *flags); - if (likely(atomic_read(&queue->count) >= needed)) - return 1; - write_unlock_irqrestore(&queue->lock, *flags); - return 0; -} + goto out; -/* - * set qtcb pointer in fsf_req and initialize QTCB - */ -static void -zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) -{ - if (likely(fsf_req->qtcb != NULL)) { - fsf_req->qtcb->prefix.req_seq_no = - fsf_req->adapter->fsf_req_seq_no; - fsf_req->qtcb->prefix.req_id = fsf_req->req_id; - fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; - fsf_req->qtcb->prefix.qtcb_type = - fsf_qtcb_type[fsf_req->fsf_command]; - fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; - fsf_req->qtcb->header.req_handle = fsf_req->req_id; - fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command; - } +failed_scsi_cmnd: + zfcp_unit_put(unit); + zfcp_fsf_req_free(req); + scsi_cmnd->host_scribble = NULL; +out: + spin_unlock(&adapter->req_q.lock); + return retval; } /** - * zfcp_fsf_req_sbal_get - try to get one SBAL in the request queue - * @adapter: adapter for which request queue is examined - * @req_flags: flags indicating whether to wait for needed SBAL or not - * @lock_flags: lock_flags if queue_lock is taken - * Return: 0 on success, otherwise -EIO, or -ERESTARTSYS - * Locks: lock adapter->req_q->lock on success - */ -static int -zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter, int req_flags, - unsigned long *lock_flags) -{ - long ret; - struct zfcp_qdio_queue *req_q = &adapter->req_q; - - if (unlikely(req_flags & ZFCP_WAIT_FOR_SBAL)) { - ret = wait_event_interruptible_timeout(adapter->request_wq, - zfcp_fsf_req_sbal_check(lock_flags, req_q, 1), - ZFCP_SBAL_TIMEOUT); - if (ret < 0) - return ret; - if (!ret) - return -EIO; - } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_q, 1)) - return -EIO; - - return 0; -} - -/* - * function: zfcp_fsf_req_create - * - * purpose: create an FSF request at the specified adapter and - * setup common fields - * - * returns: -ENOMEM if there was insufficient memory for a request - * -EIO if no qdio buffers could be allocate to the request - * -EINVAL/-EPERM on bug conditions in req_dequeue - * 0 in success - * - * note: The created request is returned by reference. - * - * locks: lock of concerned request queue must not be held, - * but is held on completion (write, irqsave) + * zfcp_fsf_send_fcp_ctm - send SCSI task management command + * @adapter: pointer to struct zfcp-adapter + * @unit: pointer to struct zfcp_unit + * @tm_flags: unsigned byte for task management flags + * @req_flags: int request flags + * Returns: on success pointer to struct fsf_req, NULL otherwise */ -int -zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, - mempool_t *pool, unsigned long *lock_flags, - struct zfcp_fsf_req **fsf_req_p) +struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, + struct zfcp_unit *unit, + u8 tm_flags, int req_flags) { volatile struct qdio_buffer_element *sbale; - struct zfcp_fsf_req *fsf_req = NULL; - int ret = 0; - struct zfcp_qdio_queue *req_q = &adapter->req_q; - - /* allocate new FSF request */ - fsf_req = zfcp_fsf_req_alloc(pool, req_flags); - if (unlikely(!fsf_req)) { - ret = -ENOMEM; - goto failed_fsf_req; - } - - fsf_req->adapter = adapter; - fsf_req->fsf_command = fsf_cmd; - INIT_LIST_HEAD(&fsf_req->list); - init_timer(&fsf_req->timer); - - /* initialize waitqueue which may be used to wait on - this request completion */ - init_waitqueue_head(&fsf_req->completion_wq); - - ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags); - if (ret < 0) - goto failed_sbals; - - /* this is serialized (we are holding req_queue-lock of adapter) */ - if (adapter->req_no == 0) - adapter->req_no++; - fsf_req->req_id = adapter->req_no++; - - zfcp_fsf_req_qtcb_init(fsf_req); - - /* - * We hold queue_lock here. Check if QDIOUP is set and let request fail - * if it is not set (see also *_open_qdio and *_close_qdio). - */ - - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) { - write_unlock_irqrestore(&req_q->lock, *lock_flags); - ret = -EIO; - goto failed_sbals; - } + struct zfcp_fsf_req *req = NULL; + struct fcp_cmnd_iu *fcp_cmnd_iu; - if (fsf_req->qtcb) { - fsf_req->seq_no = adapter->fsf_req_seq_no; - fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; - } - fsf_req->sbal_number = 1; - fsf_req->sbal_first = req_q->first; - fsf_req->sbal_last = req_q->first; - fsf_req->sbale_curr = 1; + if (unlikely(!(atomic_read(&unit->status) & + ZFCP_STATUS_COMMON_UNBLOCKED))) + return NULL; - if (likely(req_flags & ZFCP_REQ_AUTO_CLEANUP)) { - fsf_req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - } + spin_lock(&adapter->req_q.lock); + if (!atomic_read(&adapter->req_q.count)) + goto out; + req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, + adapter->pool.fsf_req_scsi); + if (unlikely(IS_ERR(req))) + goto out; - sbale = zfcp_qdio_sbale_req(fsf_req); + req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; + req->data = unit; + req->handler = zfcp_fsf_send_fcp_command_handler; + req->qtcb->header.lun_handle = unit->handle; + req->qtcb->header.port_handle = unit->port->handle; + req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; + req->qtcb->bottom.io.service_class = FSF_CLASS_3; + req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + + sizeof(fcp_dl_t); + + sbale = zfcp_qdio_sbale_req(req); + sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; + sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; - /* setup common SBALE fields */ - sbale[0].addr = (void *) fsf_req->req_id; - sbale[0].flags |= SBAL_FLAGS0_COMMAND; - if (likely(fsf_req->qtcb != NULL)) { - sbale[1].addr = (void *) fsf_req->qtcb; - sbale[1].length = sizeof(struct fsf_qtcb); - } + fcp_cmnd_iu = (struct fcp_cmnd_iu *) &req->qtcb->bottom.io.fcp_cmnd; + fcp_cmnd_iu->fcp_lun = unit->fcp_lun; + fcp_cmnd_iu->task_management_flags = tm_flags; - goto success; + zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); + if (!zfcp_fsf_req_send(req)) + goto out; - failed_sbals: -/* dequeue new FSF request previously enqueued */ - zfcp_fsf_req_free(fsf_req); - fsf_req = NULL; + zfcp_fsf_req_free(req); + req = NULL; +out: + spin_unlock(&adapter->req_q.lock); + return req; +} - failed_fsf_req: - write_lock_irqsave(&req_q->lock, *lock_flags); - success: - *fsf_req_p = fsf_req; - return ret; +static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req) +{ + if (req->qtcb->header.fsf_status != FSF_GOOD) + req->status |= ZFCP_STATUS_FSFREQ_ERROR; } -/* - * function: zfcp_fsf_req_send - * - * purpose: start transfer of FSF request via QDIO - * - * returns: 0 - request transfer succesfully started - * !0 - start of request transfer failed +/** + * zfcp_fsf_control_file - control file upload/download + * @adapter: pointer to struct zfcp_adapter + * @fsf_cfdc: pointer to struct zfcp_fsf_cfdc + * Returns: on success pointer to struct zfcp_fsf_req, NULL otherwise */ -static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) +struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, + struct zfcp_fsf_cfdc *fsf_cfdc) { - struct zfcp_adapter *adapter; - struct zfcp_qdio_queue *req_q; volatile struct qdio_buffer_element *sbale; - int inc_seq_no; - int retval = 0; + struct zfcp_fsf_req *req = NULL; + struct fsf_qtcb_bottom_support *bottom; + int direction, retval = -EIO, bytes; + + if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) + return ERR_PTR(-EOPNOTSUPP); + + switch (fsf_cfdc->command) { + case FSF_QTCB_DOWNLOAD_CONTROL_FILE: + direction = SBAL_FLAGS0_TYPE_WRITE; + break; + case FSF_QTCB_UPLOAD_CONTROL_FILE: + direction = SBAL_FLAGS0_TYPE_READ; + break; + default: + return ERR_PTR(-EINVAL); + } - adapter = fsf_req->adapter; - req_q = &adapter->req_q; + spin_lock(&adapter->req_q.lock); + if (zfcp_fsf_req_sbal_get(adapter)) + goto out; - sbale = zfcp_qdio_sbale_req(fsf_req); + req = zfcp_fsf_req_create(adapter, fsf_cfdc->command, 0, NULL); + if (unlikely(IS_ERR(req))) { + retval = -EPERM; + goto out; + } - /* put allocated FSF request into hash table */ - spin_lock(&adapter->req_list_lock); - zfcp_reqlist_add(adapter, fsf_req); - spin_unlock(&adapter->req_list_lock); + req->handler = zfcp_fsf_control_file_handler; - inc_seq_no = (fsf_req->qtcb != NULL); + sbale = zfcp_qdio_sbale_req(req); + sbale[0].flags |= direction; - fsf_req->issued = get_clock(); + bottom = &req->qtcb->bottom.support; + bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; + bottom->option = fsf_cfdc->option; - retval = zfcp_qdio_send(fsf_req); + bytes = zfcp_qdio_sbals_from_sg(req, direction, fsf_cfdc->sg, + FSF_MAX_SBALS_PER_REQ); + if (bytes != ZFCP_CFDC_MAX_SIZE) { + retval = -ENOMEM; + zfcp_fsf_req_free(req); + goto out; + } - if (unlikely(retval)) { - /* Queues are down..... */ - del_timer(&fsf_req->timer); - spin_lock(&adapter->req_list_lock); - zfcp_reqlist_remove(adapter, fsf_req); - spin_unlock(&adapter->req_list_lock); - /* undo changes in request queue made for this request */ - atomic_add(fsf_req->sbal_number, &req_q->count); - req_q->first -= fsf_req->sbal_number; - req_q->first += QDIO_MAX_BUFFERS_PER_Q; - req_q->first %= QDIO_MAX_BUFFERS_PER_Q; - zfcp_erp_adapter_reopen(adapter, 0, 116, fsf_req); - retval = -EIO; - } else { - /* - * increase FSF sequence counter - - * this must only be done for request successfully enqueued to - * QDIO this rejected requests may be cleaned up by calling - * routines resulting in missing sequence counter values - * otherwise, - */ + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); + retval = zfcp_fsf_req_send(req); +out: + spin_unlock(&adapter->req_q.lock); - /* Don't increase for unsolicited status */ - if (inc_seq_no) - adapter->fsf_req_seq_no++; + if (!retval) { + wait_event(req->completion_wq, + req->status & ZFCP_STATUS_FSFREQ_COMPLETED); + return req; } - return retval; + return ERR_PTR(retval); } diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 6ce2f1e..bf94b4d 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -287,6 +287,18 @@ struct fsf_bit_error_payload { u32 current_transmit_b2b_credit; } __attribute__ ((packed)); +struct fsf_link_down_info { + u32 error_code; + u32 res1; + u8 res2[2]; + u8 primary_status; + u8 ioerr_code; + u8 action_code; + u8 reason_code; + u8 explanation_code; + u8 vendor_specific_code; +} __attribute__ ((packed)); + struct fsf_status_read_buffer { u32 status_type; u32 status_subtype; @@ -297,7 +309,12 @@ struct fsf_status_read_buffer { u32 class; u64 fcp_lun; u8 res3[24]; - u8 payload[FSF_STATUS_READ_PAYLOAD_SIZE]; + union { + u8 data[FSF_STATUS_READ_PAYLOAD_SIZE]; + u32 word[FSF_STATUS_READ_PAYLOAD_SIZE/sizeof(u32)]; + struct fsf_link_down_info link_down_info; + struct fsf_bit_error_payload bit_error; + } payload; } __attribute__ ((packed)); struct fsf_qual_version_error { @@ -310,18 +327,6 @@ struct fsf_qual_sequence_error { u32 res1[3]; } __attribute__ ((packed)); -struct fsf_link_down_info { - u32 error_code; - u32 res1; - u8 res2[2]; - u8 primary_status; - u8 ioerr_code; - u8 action_code; - u8 reason_code; - u8 explanation_code; - u8 vendor_specific_code; -} __attribute__ ((packed)); - struct fsf_qual_latency_info { u32 channel_lat; u32 fabric_lat; diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index b8ed42b..72e3094 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -10,7 +10,7 @@ /* FIXME(tune): free space should be one max. SBAL chain plus what? */ #define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ - - (ZFCP_MAX_SBALS_PER_REQ + 4)) + - (FSF_MAX_SBALS_PER_REQ + 4)) #define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) @@ -432,9 +432,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ req_q = &adapter->req_q; - write_lock_irq(&req_q->lock); + spin_lock(&req_q->lock); atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); - write_unlock_irq(&req_q->lock); + spin_unlock(&req_q->lock); while (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index e6d8ea8..aeae56b 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -182,7 +182,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0); return retval; } - fsf_req->data = 0; + fsf_req->data = NULL; fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING; /* don't access old fsf_req after releasing the abort_lock */ @@ -220,8 +220,7 @@ static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags, int retval = SUCCESS; /* issue task management function */ - fsf_req = zfcp_fsf_send_fcp_command_task_management - (adapter, unit, tm_flags, 0); + fsf_req = zfcp_fsf_send_fcp_ctm(adapter, unit, tm_flags, 0); if (!fsf_req) { zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt); return FAILED; -- cgit v0.10.2 From 287ac01acf22ab6aaaf9f5a4919ce2449c8b391c Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:40 +0200 Subject: [SCSI] zfcp: Cleanup code in zfcp_erp.c Cleanup the code in zfcp_erp.c, move erp internal definititions to this file and move FSF timeout handling to the FSF layer. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 206b6e7..67f45fc 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -91,17 +91,11 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) /* max. number of (data buffer) SBALEs in largest SBAL chain multiplied with number of sectors per 4k block */ -#define ZFCP_TYPE2_RECOVERY_TIME 8 /* seconds */ - /********************* FSF SPECIFIC DEFINES *********************************/ /* ATTENTION: value must not be used by hardware */ #define FSF_QTCB_UNSOLICITED_STATUS 0x6305 -/* Do 1st retry in 1 second, then double the timeout for each following retry */ -#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 1 -#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7 - /* timeout value for "default timer" for fsf requests */ #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ) @@ -349,45 +343,6 @@ struct zfcp_rc_entry { #define ZFCP_STATUS_FSFREQ_RETRY 0x00000800 #define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000 -/*********************** ERROR RECOVERY PROCEDURE DEFINES ********************/ - -#define ZFCP_MAX_ERPS 3 - -#define ZFCP_ERP_FSFREQ_TIMEOUT (30 * HZ) -#define ZFCP_ERP_MEMWAIT_TIMEOUT HZ - -#define ZFCP_STATUS_ERP_TIMEDOUT 0x10000000 -#define ZFCP_STATUS_ERP_CLOSE_ONLY 0x01000000 -#define ZFCP_STATUS_ERP_DISMISSING 0x00100000 -#define ZFCP_STATUS_ERP_DISMISSED 0x00200000 -#define ZFCP_STATUS_ERP_LOWMEM 0x00400000 - -#define ZFCP_ERP_STEP_UNINITIALIZED 0x00000000 -#define ZFCP_ERP_STEP_FSF_XCONFIG 0x00000001 -#define ZFCP_ERP_STEP_PHYS_PORT_CLOSING 0x00000010 -#define ZFCP_ERP_STEP_PORT_CLOSING 0x00000100 -#define ZFCP_ERP_STEP_NAMESERVER_OPEN 0x00000200 -#define ZFCP_ERP_STEP_NAMESERVER_LOOKUP 0x00000400 -#define ZFCP_ERP_STEP_PORT_OPENING 0x00000800 -#define ZFCP_ERP_STEP_UNIT_CLOSING 0x00001000 -#define ZFCP_ERP_STEP_UNIT_OPENING 0x00002000 - -/* Ordered by escalation level (necessary for proper erp-code operation) */ -#define ZFCP_ERP_ACTION_REOPEN_ADAPTER 0x4 -#define ZFCP_ERP_ACTION_REOPEN_PORT_FORCED 0x3 -#define ZFCP_ERP_ACTION_REOPEN_PORT 0x2 -#define ZFCP_ERP_ACTION_REOPEN_UNIT 0x1 - -#define ZFCP_ERP_ACTION_RUNNING 0x1 -#define ZFCP_ERP_ACTION_READY 0x2 - -#define ZFCP_ERP_SUCCEEDED 0x0 -#define ZFCP_ERP_FAILED 0x1 -#define ZFCP_ERP_CONTINUES 0x2 -#define ZFCP_ERP_EXIT 0x3 -#define ZFCP_ERP_DISMISSED 0x4 -#define ZFCP_ERP_NOMEM 0x5 - /************************* STRUCTURE DEFINITIONS *****************************/ struct zfcp_fsf_req; diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 4d797e5..643ac4b 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -8,373 +8,399 @@ #include "zfcp_ext.h" -static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int, u8, - void *); -static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int, u8, - void *); -static int zfcp_erp_port_reopen_internal(struct zfcp_port *, int, u8, void *); -static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *, int, u8, void *); - -static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *, int, u8, - void *); -static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *, int, u8, - void *); - -static void zfcp_erp_adapter_block(struct zfcp_adapter *, int); -static void zfcp_erp_adapter_unblock(struct zfcp_adapter *); -static void zfcp_erp_port_block(struct zfcp_port *, int); -static void zfcp_erp_port_unblock(struct zfcp_port *); -static void zfcp_erp_unit_block(struct zfcp_unit *, int); -static void zfcp_erp_unit_unblock(struct zfcp_unit *); - -static int zfcp_erp_thread(void *); - -static int zfcp_erp_strategy(struct zfcp_erp_action *); - -static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *); -static int zfcp_erp_strategy_memwait(struct zfcp_erp_action *); -static int zfcp_erp_strategy_check_target(struct zfcp_erp_action *, int); -static int zfcp_erp_strategy_check_unit(struct zfcp_unit *, int); -static int zfcp_erp_strategy_check_port(struct zfcp_port *, int); -static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *, int); -static int zfcp_erp_strategy_statechange(int, u32, struct zfcp_adapter *, - struct zfcp_port *, - struct zfcp_unit *, int); -static int zfcp_erp_strategy_statechange_detected(atomic_t *, u32); -static int zfcp_erp_strategy_followup_actions(int, struct zfcp_adapter *, - struct zfcp_port *, - struct zfcp_unit *, int); -static int zfcp_erp_strategy_check_queues(struct zfcp_adapter *); -static int zfcp_erp_strategy_check_action(struct zfcp_erp_action *, int); - -static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *, int); -static int zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *); -static int zfcp_erp_adapter_strategy_open_fsf_statusread( - struct zfcp_erp_action *); - -static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *); -static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *); - -static int zfcp_erp_port_strategy(struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_clearstati(struct zfcp_port *); -static int zfcp_erp_port_strategy_close(struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_open_nameserver_wakeup( - struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *); -static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *); - -static int zfcp_erp_unit_strategy(struct zfcp_erp_action *); -static int zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *); -static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *); -static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *); - -static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *); -static void zfcp_erp_action_dismiss_port(struct zfcp_port *); -static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *); -static void zfcp_erp_action_dismiss(struct zfcp_erp_action *); - -static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *, - struct zfcp_port *, struct zfcp_unit *, - u8 id, void *ref); -static int zfcp_erp_action_dequeue(struct zfcp_erp_action *); -static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *, - struct zfcp_port *, struct zfcp_unit *, - int); - -static void zfcp_erp_action_ready(struct zfcp_erp_action *); -static int zfcp_erp_action_exists(struct zfcp_erp_action *); - -static void zfcp_erp_action_to_ready(struct zfcp_erp_action *); -static void zfcp_erp_action_to_running(struct zfcp_erp_action *); - -static void zfcp_erp_memwait_handler(unsigned long); +#define ZFCP_MAX_ERPS 3 + +enum zfcp_erp_act_flags { + ZFCP_STATUS_ERP_TIMEDOUT = 0x10000000, + ZFCP_STATUS_ERP_CLOSE_ONLY = 0x01000000, + ZFCP_STATUS_ERP_DISMISSING = 0x00100000, + ZFCP_STATUS_ERP_DISMISSED = 0x00200000, + ZFCP_STATUS_ERP_LOWMEM = 0x00400000, +}; -/** - * zfcp_close_fsf - stop FSF operations for an adapter - * - * Dismiss and cleanup all pending fsf_reqs (this wakes up all initiators of - * requests waiting for completion; especially this returns SCSI commands - * with error state). - */ -static void zfcp_close_fsf(struct zfcp_adapter *adapter) +enum zfcp_erp_steps { + ZFCP_ERP_STEP_UNINITIALIZED = 0x0000, + ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, + ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, + ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, + ZFCP_ERP_STEP_NAMESERVER_OPEN = 0x0200, + ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400, + ZFCP_ERP_STEP_PORT_OPENING = 0x0800, + ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, + ZFCP_ERP_STEP_UNIT_OPENING = 0x2000, +}; + +enum zfcp_erp_act_type { + ZFCP_ERP_ACTION_REOPEN_UNIT = 1, + ZFCP_ERP_ACTION_REOPEN_PORT = 2, + ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3, + ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4, +}; + +enum zfcp_erp_act_state { + ZFCP_ERP_ACTION_RUNNING = 1, + ZFCP_ERP_ACTION_READY = 2, +}; + +enum zfcp_erp_act_result { + ZFCP_ERP_SUCCEEDED = 0, + ZFCP_ERP_FAILED = 1, + ZFCP_ERP_CONTINUES = 2, + ZFCP_ERP_EXIT = 3, + ZFCP_ERP_DISMISSED = 4, + ZFCP_ERP_NOMEM = 5, +}; + +static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int mask) { - /* close queues to ensure that buffers are not accessed by adapter */ - zfcp_qdio_close(adapter); - zfcp_fsf_req_dismiss_all(adapter); - /* reset FSF request sequence number */ - adapter->fsf_req_seq_no = 0; - /* all ports and units are closed */ - zfcp_erp_modify_adapter_status(adapter, 24, NULL, - ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); + zfcp_erp_modify_adapter_status(adapter, 15, NULL, + ZFCP_STATUS_COMMON_UNBLOCKED | mask, + ZFCP_CLEAR); } -/** - * zfcp_fsf_request_timeout_handler - called if a request timed out - * @data: pointer to adapter for handler function - * - * This function needs to be called if requests (ELS, Generic Service, - * or SCSI commands) exceed a certain time limit. The assumption is - * that after the time limit the adapter get stuck. So we trigger a reopen of - * the adapter. - */ -static void zfcp_fsf_request_timeout_handler(unsigned long data) +static int zfcp_erp_action_exists(struct zfcp_erp_action *act) { - struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; - zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 62, - NULL); + struct zfcp_erp_action *curr_act; + + list_for_each_entry(curr_act, &act->adapter->erp_running_head, list) + if (act == curr_act) + return ZFCP_ERP_ACTION_RUNNING; + return 0; } -void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) +static void zfcp_erp_action_ready(struct zfcp_erp_action *act) { - fsf_req->timer.function = zfcp_fsf_request_timeout_handler; - fsf_req->timer.data = (unsigned long) fsf_req->adapter; - fsf_req->timer.expires = jiffies + timeout; - add_timer(&fsf_req->timer); + struct zfcp_adapter *adapter = act->adapter; + + list_move(&act->list, &act->adapter->erp_ready_head); + zfcp_rec_dbf_event_action(146, act); + up(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread(2, adapter); } -/* - * function: - * - * purpose: called if an adapter failed, - * initiates adapter recovery which is done - * asynchronously - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action - */ -static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, - int clear_mask, u8 id, void *ref) +static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act) { - int retval; + act->status |= ZFCP_STATUS_ERP_DISMISSED; + if (zfcp_erp_action_exists(act) == ZFCP_ERP_ACTION_RUNNING) + zfcp_erp_action_ready(act); +} - zfcp_erp_adapter_block(adapter, clear_mask); +static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) +{ + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_INUSE) + zfcp_erp_action_dismiss(&unit->erp_action); +} - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) { - /* ensure propagation of failed status to new devices */ - zfcp_erp_adapter_failed(adapter, 13, NULL); - retval = -EIO; - goto out; - } - retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, - adapter, NULL, NULL, id, ref); +static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) +{ + struct zfcp_unit *unit; - out: - return retval; + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) + zfcp_erp_action_dismiss(&port->erp_action); + else + list_for_each_entry(unit, &port->unit_list_head, list) + zfcp_erp_action_dismiss_unit(unit); } -/* - * function: - * - * purpose: Wrappper for zfcp_erp_adapter_reopen_internal - * used to ensure the correct locking - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action - */ -int zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask, - u8 id, void *ref) +static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) { - int retval; - unsigned long flags; - - read_lock_irqsave(&zfcp_data.config_lock, flags); - write_lock(&adapter->erp_lock); - retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask, id, ref); - write_unlock(&adapter->erp_lock); - read_unlock_irqrestore(&zfcp_data.config_lock, flags); + struct zfcp_port *port; - return retval; + if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) + zfcp_erp_action_dismiss(&adapter->erp_action); + else + list_for_each_entry(port, &adapter->port_list_head, list) + zfcp_erp_action_dismiss_port(port); } -int zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask, - u8 id, void *ref) +static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, + struct zfcp_port *port, + struct zfcp_unit *unit) { - int retval; + int need = want; + int u_status, p_status, a_status; - retval = zfcp_erp_adapter_reopen(adapter, - ZFCP_STATUS_COMMON_RUNNING | - ZFCP_STATUS_COMMON_ERP_FAILED | - clear_mask, id, ref); + switch (want) { + case ZFCP_ERP_ACTION_REOPEN_UNIT: + u_status = atomic_read(&unit->status); + if (u_status & ZFCP_STATUS_COMMON_ERP_INUSE) + return 0; + p_status = atomic_read(&port->status); + if (!(p_status & ZFCP_STATUS_COMMON_RUNNING) || + p_status & ZFCP_STATUS_COMMON_ERP_FAILED) + return 0; + if (!(p_status & ZFCP_STATUS_COMMON_UNBLOCKED)) + need = ZFCP_ERP_ACTION_REOPEN_PORT; + /* fall through */ + case ZFCP_ERP_ACTION_REOPEN_PORT: + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + p_status = atomic_read(&port->status); + if (p_status & ZFCP_STATUS_COMMON_ERP_INUSE) + return 0; + a_status = atomic_read(&adapter->status); + if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || + a_status & ZFCP_STATUS_COMMON_ERP_FAILED) + return 0; + if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) + need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; + /* fall through */ + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + a_status = atomic_read(&adapter->status); + if (a_status & ZFCP_STATUS_COMMON_ERP_INUSE) + return 0; + } - return retval; + return need; } -int zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask, u8 id, - void *ref) +static struct zfcp_erp_action *zfcp_erp_setup_act(int need, + struct zfcp_adapter *adapter, + struct zfcp_port *port, + struct zfcp_unit *unit) { - int retval; + struct zfcp_erp_action *erp_action; + u32 status = 0; - retval = zfcp_erp_port_reopen(port, - ZFCP_STATUS_COMMON_RUNNING | - ZFCP_STATUS_COMMON_ERP_FAILED | - clear_mask, id, ref); + switch (need) { + case ZFCP_ERP_ACTION_REOPEN_UNIT: + zfcp_unit_get(unit); + atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); + erp_action = &unit->erp_action; + if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) + status = ZFCP_STATUS_ERP_CLOSE_ONLY; + break; - return retval; -} + case ZFCP_ERP_ACTION_REOPEN_PORT: + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + zfcp_port_get(port); + zfcp_erp_action_dismiss_port(port); + atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); + erp_action = &port->erp_action; + if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) + status = ZFCP_STATUS_ERP_CLOSE_ONLY; + break; -int zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask, u8 id, - void *ref) -{ - int retval; + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + zfcp_adapter_get(adapter); + zfcp_erp_action_dismiss_adapter(adapter); + atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); + erp_action = &adapter->erp_action; + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_RUNNING)) + status = ZFCP_STATUS_ERP_CLOSE_ONLY; + break; + + default: + return NULL; + } - retval = zfcp_erp_unit_reopen(unit, - ZFCP_STATUS_COMMON_RUNNING | - ZFCP_STATUS_COMMON_ERP_FAILED | - clear_mask, id, ref); + memset(erp_action, 0, sizeof(struct zfcp_erp_action)); + erp_action->adapter = adapter; + erp_action->port = port; + erp_action->unit = unit; + erp_action->action = need; + erp_action->status = status; - return retval; + return erp_action; } -/* - * function: - * - * purpose: called if a port failed to be opened normally - * initiates Forced Reopen recovery which is done - * asynchronously - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action - */ -static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, - int clear_mask, u8 id, - void *ref) +static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, + struct zfcp_port *port, + struct zfcp_unit *unit, u8 id, void *ref) { - int retval; + int retval = 1, need; + struct zfcp_erp_action *act = NULL; - zfcp_erp_port_block(port, clear_mask); + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_ERP_THREAD_UP)) + return -EIO; - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) { - retval = -EIO; + need = zfcp_erp_required_act(want, adapter, port, unit); + if (!need) goto out; - } - - retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, - port->adapter, port, NULL, id, ref); + atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); + act = zfcp_erp_setup_act(need, adapter, port, unit); + if (!act) + goto out; + ++adapter->erp_total_count; + list_add_tail(&act->list, &adapter->erp_ready_head); + up(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread(1, adapter); + retval = 0; out: + zfcp_rec_dbf_event_trigger(id, ref, want, need, act, + adapter, port, unit); return retval; } -/* - * function: - * - * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal - * used to ensure the correct locking - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action +static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, + int clear_mask, u8 id, void *ref) +{ + zfcp_erp_adapter_block(adapter, clear_mask); + + /* ensure propagation of failed status to new devices */ + if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { + zfcp_erp_adapter_failed(adapter, 13, NULL); + return -EIO; + } + return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, + adapter, NULL, NULL, id, ref); +} + +/** + * zfcp_erp_adapter_reopen - Reopen adapter. + * @adapter: Adapter to reopen. + * @clear: Status flags to clear. + * @id: Id for debug trace event. + * @ref: Reference for debug trace event. */ -int zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask, u8 id, - void *ref) +void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, + u8 id, void *ref) { - int retval; unsigned long flags; - struct zfcp_adapter *adapter; - adapter = port->adapter; read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock(&adapter->erp_lock); - retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask, id, - ref); + _zfcp_erp_adapter_reopen(adapter, clear, id, ref); write_unlock(&adapter->erp_lock); read_unlock_irqrestore(&zfcp_data.config_lock, flags); +} - return retval; +/** + * zfcp_erp_adapter_shutdown - Shutdown adapter. + * @adapter: Adapter to shut down. + * @clear: Status flags to clear. + * @id: Id for debug trace event. + * @ref: Reference for debug trace event. + */ +void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear, + u8 id, void *ref) +{ + int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; + zfcp_erp_adapter_reopen(adapter, clear | flags, id, ref); } -/* - * function: - * - * purpose: called if a port is to be opened - * initiates Reopen recovery which is done - * asynchronously - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action +/** + * zfcp_erp_port_shutdown - Shutdown port + * @port: Port to shut down. + * @clear: Status flags to clear. + * @id: Id for debug trace event. + * @ref: Reference for debug trace event. */ -static int zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask, - u8 id, void *ref) +void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, u8 id, void *ref) { - int retval; + int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; + zfcp_erp_port_reopen(port, clear | flags, id, ref); +} + +/** + * zfcp_erp_unit_shutdown - Shutdown unit + * @unit: Unit to shut down. + * @clear: Status flags to clear. + * @id: Id for debug trace event. + * @ref: Reference for debug trace event. + */ +void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, u8 id, void *ref) +{ + int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; + zfcp_erp_unit_reopen(unit, clear | flags, id, ref); +} + +static void zfcp_erp_port_block(struct zfcp_port *port, int clear) +{ + zfcp_erp_modify_port_status(port, 17, NULL, + ZFCP_STATUS_COMMON_UNBLOCKED | clear, + ZFCP_CLEAR); +} + +static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, + int clear, u8 id, void *ref) +{ + zfcp_erp_port_block(port, clear); + + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) + return; - zfcp_erp_port_block(port, clear_mask); + zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, + port->adapter, port, NULL, id, ref); +} + +/** + * zfcp_erp_port_forced_reopen - Forced close of port and open again + * @port: Port to force close and to reopen. + * @id: Id for debug trace event. + * @ref: Reference for debug trace event. + */ +void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, u8 id, + void *ref) +{ + unsigned long flags; + struct zfcp_adapter *adapter = port->adapter; + + read_lock_irqsave(&zfcp_data.config_lock, flags); + write_lock(&adapter->erp_lock); + _zfcp_erp_port_forced_reopen(port, clear, id, ref); + write_unlock(&adapter->erp_lock); + read_unlock_irqrestore(&zfcp_data.config_lock, flags); +} + +static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id, + void *ref) +{ + zfcp_erp_port_block(port, clear); - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) { + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { /* ensure propagation of failed status to new devices */ zfcp_erp_port_failed(port, 14, NULL); - retval = -EIO; - goto out; + return -EIO; } - retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, - port->adapter, port, NULL, id, ref); - - out: - return retval; + return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, + port->adapter, port, NULL, id, ref); } /** - * zfcp_erp_port_reopen - initiate reopen of a remote port - * @port: port to be reopened - * @clear_mask: specifies flags in port status to be cleared - * Return: 0 on success, < 0 on error + * zfcp_erp_port_reopen - trigger remote port recovery + * @port: port to recover + * @clear_mask: flags in port status to be cleared * - * This is a wrappper function for zfcp_erp_port_reopen_internal. It ensures - * correct locking. An error recovery task is initiated to do the reopen. - * To wait for the completion of the reopen zfcp_erp_wait should be used. + * Returns 0 if recovery has been triggered, < 0 if not. */ -int zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask, u8 id, - void *ref) +int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id, void *ref) { - int retval; unsigned long flags; + int retval; struct zfcp_adapter *adapter = port->adapter; read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock(&adapter->erp_lock); - retval = zfcp_erp_port_reopen_internal(port, clear_mask, id, ref); + retval = _zfcp_erp_port_reopen(port, clear, id, ref); write_unlock(&adapter->erp_lock); read_unlock_irqrestore(&zfcp_data.config_lock, flags); return retval; } -/* - * function: - * - * purpose: called if a unit is to be opened - * initiates Reopen recovery which is done - * asynchronously - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action - */ -static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask, - u8 id, void *ref) +static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) +{ + zfcp_erp_modify_unit_status(unit, 19, NULL, + ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, + ZFCP_CLEAR); +} + +static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id, + void *ref) { - int retval; struct zfcp_adapter *adapter = unit->port->adapter; - zfcp_erp_unit_block(unit, clear_mask); + zfcp_erp_unit_block(unit, clear); - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) { - retval = -EIO; - goto out; - } + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED) + return; - retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT, - adapter, unit->port, unit, id, ref); - out: - return retval; + zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT, + adapter, unit->port, unit, id, ref); } /** @@ -382,790 +408,655 @@ static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask, * @unit: unit to be reopened * @clear_mask: specifies flags in unit status to be cleared * Return: 0 on success, < 0 on error - * - * This is a wrappper for zfcp_erp_unit_reopen_internal. It ensures correct - * locking. An error recovery task is initiated to do the reopen. - * To wait for the completion of the reopen zfcp_erp_wait should be used. */ -int zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask, u8 id, - void *ref) +void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id, void *ref) { - int retval; unsigned long flags; - struct zfcp_adapter *adapter; - struct zfcp_port *port; - - port = unit->port; - adapter = port->adapter; + struct zfcp_port *port = unit->port; + struct zfcp_adapter *adapter = port->adapter; read_lock_irqsave(&zfcp_data.config_lock, flags); write_lock(&adapter->erp_lock); - retval = zfcp_erp_unit_reopen_internal(unit, clear_mask, id, ref); + _zfcp_erp_unit_reopen(unit, clear, id, ref); write_unlock(&adapter->erp_lock); read_unlock_irqrestore(&zfcp_data.config_lock, flags); - - return retval; } -/** - * zfcp_erp_adapter_block - mark adapter as blocked, block scsi requests - */ -static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask) +static int status_change_set(unsigned long mask, atomic_t *status) { - zfcp_erp_modify_adapter_status(adapter, 15, NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | - clear_mask, ZFCP_CLEAR); + return (atomic_read(status) ^ mask) & mask; } -/* FIXME: isn't really atomic */ -/* - * returns the mask which has not been set so far, i.e. - * 0 if no bit has been changed, !0 if some bit has been changed - */ -static int atomic_test_and_set_mask(unsigned long mask, atomic_t *v) +static int status_change_clear(unsigned long mask, atomic_t *status) { - int changed_bits = (atomic_read(v) /*XOR*/^ mask) & mask; - atomic_set_mask(mask, v); - return changed_bits; + return atomic_read(status) & mask; } -/* FIXME: isn't really atomic */ -/* - * returns the mask which has not been cleared so far, i.e. - * 0 if no bit has been changed, !0 if some bit has been changed - */ -static int atomic_test_and_clear_mask(unsigned long mask, atomic_t *v) +static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) { - int changed_bits = atomic_read(v) & mask; - atomic_clear_mask(mask, v); - return changed_bits; + if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) + zfcp_rec_dbf_event_adapter(16, NULL, adapter); + atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status); } -/** - * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests - */ -static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) +static void zfcp_erp_port_unblock(struct zfcp_port *port) { - if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &adapter->status)) - zfcp_rec_dbf_event_adapter(16, NULL, adapter); + if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) + zfcp_rec_dbf_event_port(18, NULL, port); + atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status); } -/* - * function: - * - * purpose: disable I/O, - * return any open requests and clean them up, - * aim: no pending and incoming I/O - * - * returns: - */ -static void -zfcp_erp_port_block(struct zfcp_port *port, int clear_mask) +static void zfcp_erp_unit_unblock(struct zfcp_unit *unit) { - zfcp_erp_modify_port_status(port, 17, NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, - ZFCP_CLEAR); + if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status)) + zfcp_rec_dbf_event_unit(20, NULL, unit); + atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status); } -/* - * function: - * - * purpose: enable I/O - * - * returns: - */ -static void -zfcp_erp_port_unblock(struct zfcp_port *port) +static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) { - if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &port->status)) - zfcp_rec_dbf_event_port(18, NULL, port); + list_move(&erp_action->list, &erp_action->adapter->erp_running_head); + zfcp_rec_dbf_event_action(145, erp_action); } -/* - * function: - * - * purpose: disable I/O, - * return any open requests and clean them up, - * aim: no pending and incoming I/O - * - * returns: - */ -static void -zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) +static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act) { - zfcp_erp_modify_unit_status(unit, 19, NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, - ZFCP_CLEAR); -} - -/* - * function: - * - * purpose: enable I/O - * - * returns: - */ -static void -zfcp_erp_unit_unblock(struct zfcp_unit *unit) -{ - if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &unit->status)) - zfcp_rec_dbf_event_unit(20, NULL, unit); -} - -static void -zfcp_erp_action_ready(struct zfcp_erp_action *erp_action) -{ - struct zfcp_adapter *adapter = erp_action->adapter; - - zfcp_erp_action_to_ready(erp_action); - up(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread(2, adapter); -} + struct zfcp_adapter *adapter = act->adapter; -/* - * function: - * - * purpose: - * - * returns: <0 erp_action not found in any list - * ZFCP_ERP_ACTION_READY erp_action is in ready list - * ZFCP_ERP_ACTION_RUNNING erp_action is in running list - * - * locks: erp_lock must be held - */ -static int -zfcp_erp_action_exists(struct zfcp_erp_action *erp_action) -{ - int retval = -EINVAL; - struct list_head *entry; - struct zfcp_erp_action *entry_erp_action; - struct zfcp_adapter *adapter = erp_action->adapter; + if (!act->fsf_req) + return; - /* search in running list */ - list_for_each(entry, &adapter->erp_running_head) { - entry_erp_action = - list_entry(entry, struct zfcp_erp_action, list); - if (entry_erp_action == erp_action) { - retval = ZFCP_ERP_ACTION_RUNNING; - goto out; - } - } - /* search in ready list */ - list_for_each(entry, &adapter->erp_ready_head) { - entry_erp_action = - list_entry(entry, struct zfcp_erp_action, list); - if (entry_erp_action == erp_action) { - retval = ZFCP_ERP_ACTION_READY; - goto out; + spin_lock(&adapter->req_list_lock); + if (zfcp_reqlist_find_safe(adapter, act->fsf_req) && + act->fsf_req->erp_action == act) { + if (act->status & (ZFCP_STATUS_ERP_DISMISSED | + ZFCP_STATUS_ERP_TIMEDOUT)) { + act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; + zfcp_rec_dbf_event_action(142, act); } - } - - out: - return retval; + if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) + zfcp_rec_dbf_event_action(143, act); + if (act->fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED | + ZFCP_STATUS_FSFREQ_DISMISSED)) + act->fsf_req = NULL; + } else + act->fsf_req = NULL; + spin_unlock(&adapter->req_list_lock); } -/* - * purpose: checks current status of action (timed out, dismissed, ...) - * and does appropriate preparations (dismiss fsf request, ...) - * - * locks: called under erp_lock (disabled interrupts) +/** + * zfcp_erp_notify - Trigger ERP action. + * @erp_action: ERP action to continue. + * @set_mask: ERP action status flags to set. */ -static void -zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) +void zfcp_erp_notify(struct zfcp_erp_action *erp_action, unsigned long set_mask) { struct zfcp_adapter *adapter = erp_action->adapter; + unsigned long flags; - if (erp_action->fsf_req) { - /* take lock to ensure that request is not deleted meanwhile */ - spin_lock(&adapter->req_list_lock); - if (zfcp_reqlist_find_safe(adapter, erp_action->fsf_req) && - erp_action->fsf_req->erp_action == erp_action) { - /* fsf_req still exists */ - /* dismiss fsf_req of timed out/dismissed erp_action */ - if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | - ZFCP_STATUS_ERP_TIMEDOUT)) { - erp_action->fsf_req->status |= - ZFCP_STATUS_FSFREQ_DISMISSED; - zfcp_rec_dbf_event_action(142, erp_action); - } - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) - zfcp_rec_dbf_event_action(143, erp_action); - /* - * If fsf_req is neither dismissed nor completed - * then keep it running asynchronously and don't mess - * with the association of erp_action and fsf_req. - */ - if (erp_action->fsf_req->status & - (ZFCP_STATUS_FSFREQ_COMPLETED | - ZFCP_STATUS_FSFREQ_DISMISSED)) { - /* forget about association between fsf_req - and erp_action */ - erp_action->fsf_req = NULL; - } - } else { - /* - * even if this fsf_req has gone, forget about - * association between erp_action and fsf_req - */ - erp_action->fsf_req = NULL; - } - spin_unlock(&adapter->req_list_lock); - } -} - -/** - * zfcp_erp_async_handler_nolock - complete erp_action - * - * Used for normal completion, time-out, dismissal and failure after - * low memory condition. - */ -static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, - unsigned long set_mask) -{ + write_lock_irqsave(&adapter->erp_lock, flags); if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) { erp_action->status |= set_mask; zfcp_erp_action_ready(erp_action); - } else { - /* action is ready or gone - nothing to do */ } -} - -/** - * zfcp_erp_async_handler - wrapper for erp_async_handler_nolock w/ locking - */ -void zfcp_erp_async_handler(struct zfcp_erp_action *erp_action, - unsigned long set_mask) -{ - struct zfcp_adapter *adapter = erp_action->adapter; - unsigned long flags; - - write_lock_irqsave(&adapter->erp_lock, flags); - zfcp_erp_async_handler_nolock(erp_action, set_mask); write_unlock_irqrestore(&adapter->erp_lock, flags); } -/* - * purpose: is called for erp_action which was slept waiting for - * memory becoming avaliable, - * will trigger that this action will be continued +/** + * zfcp_erp_timeout_handler - Trigger ERP action from timed out ERP request + * @data: ERP action (from timer data) */ -static void -zfcp_erp_memwait_handler(unsigned long data) +void zfcp_erp_timeout_handler(unsigned long data) { - struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; - - zfcp_erp_async_handler(erp_action, 0); + struct zfcp_erp_action *act = (struct zfcp_erp_action *) data; + zfcp_erp_notify(act, ZFCP_STATUS_ERP_TIMEDOUT); } -/* - * purpose: is called if an asynchronous erp step timed out, - * action gets an appropriate flag and will be processed - * accordingly - */ -static void zfcp_erp_timeout_handler(unsigned long data) +static void zfcp_erp_memwait_handler(unsigned long data) { - struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; - - zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT); + zfcp_erp_notify((struct zfcp_erp_action *)data, 0); } -/** - * zfcp_erp_action_dismiss - dismiss an erp_action - * - * adapter->erp_lock must be held - * - * Dismissal of an erp_action is usually required if an erp_action of - * higher priority is generated. - */ -static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action) +static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) { - erp_action->status |= ZFCP_STATUS_ERP_DISMISSED; - if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) - zfcp_erp_action_ready(erp_action); + init_timer(&erp_action->timer); + erp_action->timer.function = zfcp_erp_memwait_handler; + erp_action->timer.data = (unsigned long) erp_action; + erp_action->timer.expires = jiffies + HZ; + add_timer(&erp_action->timer); } -int -zfcp_erp_thread_setup(struct zfcp_adapter *adapter) +static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, + int clear, u8 id, void *ref) { - int retval = 0; - - atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); - - retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); - if (retval < 0) - dev_err(&adapter->ccw_device->dev, - "Creation of ERP thread failed.\n"); - else { - wait_event(adapter->erp_thread_wqh, - atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, - &adapter->status)); - } + struct zfcp_port *port; - return (retval < 0); + list_for_each_entry(port, &adapter->port_list_head, list) + if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)) + _zfcp_erp_port_reopen(port, clear, id, ref); } -/* - * function: - * - * purpose: - * - * returns: - * - * context: process (i.e. proc-fs or rmmod/insmod) - * - * note: The caller of this routine ensures that the specified - * adapter has been shut down and that this operation - * has been completed. Thus, there are no pending erp_actions - * which would need to be handled here. - */ -int -zfcp_erp_thread_kill(struct zfcp_adapter *adapter) +static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id, + void *ref) { - int retval = 0; - - atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); - up(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread_lock(2, adapter); - - wait_event(adapter->erp_thread_wqh, - !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, - &adapter->status)); - - atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, - &adapter->status); + struct zfcp_unit *unit; - return retval; + list_for_each_entry(unit, &port->unit_list_head, list) + _zfcp_erp_unit_reopen(unit, clear, id, ref); } -/* - * purpose: is run as a kernel thread, - * goes through list of error recovery actions of associated adapter - * and delegates single action to execution - * - * returns: 0 - */ -static int -zfcp_erp_thread(void *data) +static void zfcp_erp_strategy_followup_actions(struct zfcp_erp_action *act) { - struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; - struct list_head *next; - struct zfcp_erp_action *erp_action; - unsigned long flags; + struct zfcp_adapter *adapter = act->adapter; + struct zfcp_port *port = act->port; + struct zfcp_unit *unit = act->unit; + u32 status = act->status; - daemonize("zfcperp%s", zfcp_get_busid_by_adapter(adapter)); - /* Block all signals */ - siginitsetinv(¤t->blocked, 0); - atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); - wake_up(&adapter->erp_thread_wqh); + /* initiate follow-up actions depending on success of finished action */ + switch (act->action) { - while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, - &adapter->status)) { + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + if (status == ZFCP_ERP_SUCCEEDED) + _zfcp_erp_port_reopen_all(adapter, 0, 70, NULL); + else + _zfcp_erp_adapter_reopen(adapter, 0, 71, NULL); + break; - write_lock_irqsave(&adapter->erp_lock, flags); - next = adapter->erp_ready_head.next; - write_unlock_irqrestore(&adapter->erp_lock, flags); + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + if (status == ZFCP_ERP_SUCCEEDED) + _zfcp_erp_port_reopen(port, 0, 72, NULL); + else + _zfcp_erp_adapter_reopen(adapter, 0, 73, NULL); + break; - if (next != &adapter->erp_ready_head) { - erp_action = - list_entry(next, struct zfcp_erp_action, list); - /* - * process action (incl. [re]moving it - * from 'ready' queue) - */ - zfcp_erp_strategy(erp_action); - } + case ZFCP_ERP_ACTION_REOPEN_PORT: + if (status == ZFCP_ERP_SUCCEEDED) + _zfcp_erp_unit_reopen_all(port, 0, 74, NULL); + else + _zfcp_erp_port_forced_reopen(port, 0, 75, NULL); + break; - /* - * sleep as long as there is nothing to do, i.e. - * no action in 'ready' queue to be processed and - * thread is not to be killed - */ - zfcp_rec_dbf_event_thread_lock(4, adapter); - down_interruptible(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread_lock(5, adapter); + case ZFCP_ERP_ACTION_REOPEN_UNIT: + if (status != ZFCP_ERP_SUCCEEDED) + _zfcp_erp_port_reopen(unit->port, 0, 76, NULL); + break; } - - atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); - wake_up(&adapter->erp_thread_wqh); - - return 0; } -/* - * function: - * - * purpose: drives single error recovery action and schedules higher and - * subordinate actions, if necessary - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_SUCCEEDED - action finished successfully (deqd) - * ZFCP_ERP_FAILED - action finished unsuccessfully (deqd) - * ZFCP_ERP_EXIT - action finished (dequeued), offline - * ZFCP_ERP_DISMISSED - action canceled (dequeued) - */ -static int -zfcp_erp_strategy(struct zfcp_erp_action *erp_action) +static void zfcp_erp_wakeup(struct zfcp_adapter *adapter) { - int retval = 0; - struct zfcp_adapter *adapter = erp_action->adapter; - struct zfcp_port *port = erp_action->port; - struct zfcp_unit *unit = erp_action->unit; - int action = erp_action->action; - u32 status = erp_action->status; unsigned long flags; - /* serialise dismissing, timing out, moving, enqueueing */ read_lock_irqsave(&zfcp_data.config_lock, flags); - write_lock(&adapter->erp_lock); - - /* dequeue dismissed action and leave, if required */ - retval = zfcp_erp_strategy_check_action(erp_action, retval); - if (retval == ZFCP_ERP_DISMISSED) { - goto unlock; + read_lock(&adapter->erp_lock); + if (list_empty(&adapter->erp_ready_head) && + list_empty(&adapter->erp_running_head)) { + atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, + &adapter->status); + wake_up(&adapter->erp_done_wqh); } + read_unlock(&adapter->erp_lock); + read_unlock_irqrestore(&zfcp_data.config_lock, flags); +} - /* - * move action to 'running' queue before processing it - * (to avoid a race condition regarding moving the - * action to the 'running' queue and back) - */ - zfcp_erp_action_to_running(erp_action); +static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act) +{ + if (zfcp_qdio_open(act->adapter)) + return ZFCP_ERP_FAILED; + init_waitqueue_head(&act->adapter->request_wq); + atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &act->adapter->status); + return ZFCP_ERP_SUCCEEDED; +} - /* - * try to process action as far as possible, - * no lock to allow for blocking operations (kmalloc, qdio, ...), - * afterwards the lock is required again for the following reasons: - * - dequeueing of finished action and enqueueing of - * follow-up actions must be atomic so that any other - * reopen-routine does not believe there is nothing to do - * and that it is safe to enqueue something else, - * - we want to force any control thread which is dismissing - * actions to finish this before we decide about - * necessary steps to be taken here further - */ - write_unlock(&adapter->erp_lock); - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - retval = zfcp_erp_strategy_do_action(erp_action); - read_lock_irqsave(&zfcp_data.config_lock, flags); - write_lock(&adapter->erp_lock); +static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter) +{ + struct zfcp_port *port; + port = zfcp_port_enqueue(adapter, adapter->peer_wwpn, 0, + adapter->peer_d_id); + if (IS_ERR(port)) /* error or port already attached */ + return; + _zfcp_erp_port_reopen(port, 0, 150, NULL); +} - /* - * check for dismissed status again to avoid follow-up actions, - * failing of targets and so on for dismissed actions, - * we go through down() here because there has been an up() - */ - if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) - retval = ZFCP_ERP_CONTINUES; +static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action) +{ + int retries; + int sleep = 1; + struct zfcp_adapter *adapter = erp_action->adapter; - switch (retval) { - case ZFCP_ERP_NOMEM: - /* no memory to continue immediately, let it sleep */ - if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) { - ++adapter->erp_low_mem_count; - erp_action->status |= ZFCP_STATUS_ERP_LOWMEM; - } - /* This condition is true if there is no memory available - for any erp_action on this adapter. This implies that there - are no elements in the memory pool(s) left for erp_actions. - This might happen if an erp_action that used a memory pool - element was timed out. - */ - if (adapter->erp_total_count == adapter->erp_low_mem_count) - zfcp_erp_adapter_reopen_internal(adapter, 0, 66, NULL); - else - retval = zfcp_erp_strategy_memwait(erp_action); - goto unlock; - case ZFCP_ERP_CONTINUES: - /* leave since this action runs asynchronously */ - if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { - --adapter->erp_low_mem_count; - erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; + atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); + + for (retries = 7; retries; retries--) { + atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, + &adapter->status); + write_lock_irq(&adapter->erp_lock); + zfcp_erp_action_to_running(erp_action); + write_unlock_irq(&adapter->erp_lock); + if (zfcp_fsf_exchange_config_data(erp_action)) { + atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, + &adapter->status); + return ZFCP_ERP_FAILED; } - goto unlock; - } - /* ok, finished action (whatever its result is) */ - /* check for unrecoverable targets */ - retval = zfcp_erp_strategy_check_target(erp_action, retval); + zfcp_rec_dbf_event_thread_lock(6, adapter); + down(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread_lock(7, adapter); + if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) + break; - /* action must be dequeued (here to allow for further ones) */ - zfcp_erp_action_dequeue(erp_action); + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_HOST_CON_INIT)) + break; - /* - * put this target through the erp mill again if someone has - * requested to change the status of a target being online - * to offline or the other way around - * (old retval is preserved if nothing has to be done here) - */ - retval = zfcp_erp_strategy_statechange(action, status, adapter, - port, unit, retval); - - /* - * leave if target is in permanent error state or if - * action is repeated in order to process state change - */ - if (retval == ZFCP_ERP_EXIT) { - goto unlock; + ssleep(sleep); + sleep *= 2; } - /* trigger follow up actions */ - zfcp_erp_strategy_followup_actions(action, adapter, port, unit, retval); + atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, + &adapter->status); - unlock: - write_unlock(&adapter->erp_lock); - read_unlock_irqrestore(&zfcp_data.config_lock, flags); + if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_XCONFIG_OK)) + return ZFCP_ERP_FAILED; - if (retval != ZFCP_ERP_CONTINUES) - zfcp_erp_action_cleanup(action, adapter, port, unit, retval); - - /* - * a few tasks remain when the erp queues are empty - * (don't do that if the last action evaluated was dismissed - * since this clearly indicates that there is more to come) : - * - close the name server port if it is open yet - * (enqueues another [probably] final action) - * - otherwise, wake up whoever wants to be woken when we are - * done with erp - */ - if (retval != ZFCP_ERP_DISMISSED) - zfcp_erp_strategy_check_queues(adapter); + if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) + zfcp_erp_enqueue_ptp_port(adapter); - return retval; + return ZFCP_ERP_SUCCEEDED; } -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_DISMISSED - if action has been dismissed - * retval - otherwise - */ -static int -zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval) +static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act) { - zfcp_erp_strategy_check_fsfreq(erp_action); + int ret; + struct zfcp_adapter *adapter = act->adapter; - if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { - zfcp_erp_action_dequeue(erp_action); - retval = ZFCP_ERP_DISMISSED; - } + atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - return retval; + write_lock_irq(&adapter->erp_lock); + zfcp_erp_action_to_running(act); + write_unlock_irq(&adapter->erp_lock); + + ret = zfcp_fsf_exchange_port_data(act); + if (ret == -EOPNOTSUPP) + return ZFCP_ERP_SUCCEEDED; + if (ret) + return ZFCP_ERP_FAILED; + + zfcp_rec_dbf_event_thread_lock(8, adapter); + down(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread_lock(9, adapter); + if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) + return ZFCP_ERP_FAILED; + + return ZFCP_ERP_SUCCEEDED; } -static int -zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) +static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act) { - int retval = ZFCP_ERP_FAILED; + if (zfcp_erp_adapter_strat_fsf_xconf(act) == ZFCP_ERP_FAILED) + return ZFCP_ERP_FAILED; - /* - * try to execute/continue action as far as possible, - * note: no lock in subsequent strategy routines - * (this allows these routine to call schedule, e.g. - * kmalloc with such flags or qdio_initialize & friends) - * Note: in case of timeout, the separate strategies will fail - * anyhow. No need for a special action. Even worse, a nameserver - * failure would not wake up waiting ports without the call. - */ - switch (erp_action->action) { + if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED) + return ZFCP_ERP_FAILED; - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - retval = zfcp_erp_adapter_strategy(erp_action); - break; + atomic_set(&act->adapter->stat_miss, 16); + if (zfcp_status_read_refill(act->adapter)) + return ZFCP_ERP_FAILED; - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - retval = zfcp_erp_port_forced_strategy(erp_action); - break; + return ZFCP_ERP_SUCCEEDED; +} - case ZFCP_ERP_ACTION_REOPEN_PORT: - retval = zfcp_erp_port_strategy(erp_action); - break; +static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act, + int close) +{ + int retval = ZFCP_ERP_SUCCEEDED; + struct zfcp_adapter *adapter = act->adapter; - case ZFCP_ERP_ACTION_REOPEN_UNIT: - retval = zfcp_erp_unit_strategy(erp_action); - break; - } + if (close) + goto close_only; + + retval = zfcp_erp_adapter_strategy_open_qdio(act); + if (retval != ZFCP_ERP_SUCCEEDED) + goto failed_qdio; + retval = zfcp_erp_adapter_strategy_open_fsf(act); + if (retval != ZFCP_ERP_SUCCEEDED) + goto failed_openfcp; + + atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &act->adapter->status); + schedule_work(&act->adapter->scan_work); + + return ZFCP_ERP_SUCCEEDED; + + close_only: + atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, + &act->adapter->status); + + failed_openfcp: + /* close queues to ensure that buffers are not accessed by adapter */ + zfcp_qdio_close(adapter); + zfcp_fsf_req_dismiss_all(adapter); + adapter->fsf_req_seq_no = 0; + /* all ports and units are closed */ + zfcp_erp_modify_adapter_status(adapter, 24, NULL, + ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); + failed_qdio: + atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | + ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | + ZFCP_STATUS_ADAPTER_XPORT_OK, + &act->adapter->status); return retval; } -/* - * function: - * - * purpose: triggers retry of this action after a certain amount of time - * by means of timer provided by erp_action - * - * returns: ZFCP_ERP_CONTINUES - erp_action sleeps in erp running queue - */ -static int -zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) +static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act) { - int retval = ZFCP_ERP_CONTINUES; + int retval; - init_timer(&erp_action->timer); - erp_action->timer.function = zfcp_erp_memwait_handler; - erp_action->timer.data = (unsigned long) erp_action; - erp_action->timer.expires = jiffies + ZFCP_ERP_MEMWAIT_TIMEOUT; - add_timer(&erp_action->timer); + atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status); + zfcp_erp_adapter_strategy_generic(act, 1); /* close */ + atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status); + if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY) + return ZFCP_ERP_EXIT; + + atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status); + retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */ + atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status); + + if (retval == ZFCP_ERP_FAILED) + ssleep(8); return retval; } -/* - * function: zfcp_erp_adapter_failed - * - * purpose: sets the adapter and all underlying devices to ERP_FAILED - * - */ -void -zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref) +static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act) { - zfcp_erp_modify_adapter_status(adapter, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); - dev_err(&adapter->ccw_device->dev, "Adapter ERP failed.\n"); + int retval; + + retval = zfcp_fsf_close_physical_port(act); + if (retval == -ENOMEM) + return ZFCP_ERP_NOMEM; + act->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING; + if (retval) + return ZFCP_ERP_FAILED; + + return ZFCP_ERP_CONTINUES; } -/* - * function: zfcp_erp_port_failed - * - * purpose: sets the port and all underlying devices to ERP_FAILED - * - */ -void -zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref) +static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) { - zfcp_erp_modify_port_status(port, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); + atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | + ZFCP_STATUS_COMMON_CLOSING | + ZFCP_STATUS_COMMON_ACCESS_DENIED | + ZFCP_STATUS_PORT_DID_DID | + ZFCP_STATUS_PORT_PHYS_CLOSING | + ZFCP_STATUS_PORT_INVALID_WWPN, + &port->status); +} - if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) - dev_err(&port->adapter->ccw_device->dev, - "Port ERP failed for WKA port d_id=0x%06x.\n", - port->d_id); - else - dev_err(&port->adapter->ccw_device->dev, - "Port ERP failed for port wwpn=0x%016Lx.\n", - port->wwpn); +static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) +{ + struct zfcp_port *port = erp_action->port; + int status = atomic_read(&port->status); + + switch (erp_action->step) { + case ZFCP_ERP_STEP_UNINITIALIZED: + zfcp_erp_port_strategy_clearstati(port); + if ((status & ZFCP_STATUS_PORT_PHYS_OPEN) && + (status & ZFCP_STATUS_COMMON_OPEN)) + return zfcp_erp_port_forced_strategy_close(erp_action); + else + return ZFCP_ERP_FAILED; + + case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: + if (status & ZFCP_STATUS_PORT_PHYS_OPEN) + return ZFCP_ERP_SUCCEEDED; + } + return ZFCP_ERP_FAILED; } -/* - * function: zfcp_erp_unit_failed - * - * purpose: sets the unit to ERP_FAILED - * - */ -void -zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref) +static int zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) { - zfcp_erp_modify_unit_status(unit, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); + int retval; - dev_err(&unit->port->adapter->ccw_device->dev, - "Unit ERP failed for unit 0x%016Lx on port 0x%016Lx.\n", - unit->fcp_lun, unit->port->wwpn); + retval = zfcp_fsf_close_port(erp_action); + if (retval == -ENOMEM) + return ZFCP_ERP_NOMEM; + erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING; + if (retval) + return ZFCP_ERP_FAILED; + return ZFCP_ERP_CONTINUES; } -/* - * function: zfcp_erp_strategy_check_target - * - * purpose: increments the erp action count on the device currently in - * recovery if the action failed or resets the count in case of - * success. If a maximum count is exceeded the device is marked - * as ERP_FAILED. - * The 'blocked' state of a target which has been recovered - * successfully is reset. - * - * returns: ZFCP_ERP_CONTINUES - action continues (not considered) - * ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_EXIT - action failed and will not continue - */ -static int -zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result) +static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) { - struct zfcp_adapter *adapter = erp_action->adapter; - struct zfcp_port *port = erp_action->port; - struct zfcp_unit *unit = erp_action->unit; + int retval; - switch (erp_action->action) { + retval = zfcp_fsf_open_port(erp_action); + if (retval == -ENOMEM) + return ZFCP_ERP_NOMEM; + erp_action->step = ZFCP_ERP_STEP_PORT_OPENING; + if (retval) + return ZFCP_ERP_FAILED; + return ZFCP_ERP_CONTINUES; +} - case ZFCP_ERP_ACTION_REOPEN_UNIT: - result = zfcp_erp_strategy_check_unit(unit, result); - break; +static void zfcp_erp_port_strategy_open_ns_wake(struct zfcp_erp_action *ns_act) +{ + unsigned long flags; + struct zfcp_adapter *adapter = ns_act->adapter; + struct zfcp_erp_action *act, *tmp; + int status; - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - case ZFCP_ERP_ACTION_REOPEN_PORT: - result = zfcp_erp_strategy_check_port(port, result); - break; + read_lock_irqsave(&adapter->erp_lock, flags); + list_for_each_entry_safe(act, tmp, &adapter->erp_running_head, list) { + if (act->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) { + status = atomic_read(&adapter->nameserver_port->status); + if (status & ZFCP_STATUS_COMMON_ERP_FAILED) + zfcp_erp_port_failed(act->port, 27, NULL); + zfcp_erp_action_ready(act); + } + } + read_unlock_irqrestore(&adapter->erp_lock, flags); +} - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - result = zfcp_erp_strategy_check_adapter(adapter, result); - break; +static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *act) +{ + int retval; + + switch (act->step) { + case ZFCP_ERP_STEP_UNINITIALIZED: + case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: + case ZFCP_ERP_STEP_PORT_CLOSING: + return zfcp_erp_port_strategy_open_port(act); + + case ZFCP_ERP_STEP_PORT_OPENING: + if (atomic_read(&act->port->status) & ZFCP_STATUS_COMMON_OPEN) + retval = ZFCP_ERP_SUCCEEDED; + else + retval = ZFCP_ERP_FAILED; + /* this is needed anyway */ + zfcp_erp_port_strategy_open_ns_wake(act); + return retval; + + default: + return ZFCP_ERP_FAILED; } +} - return result; +static int zfcp_erp_port_strategy_open_lookup(struct zfcp_erp_action *act) +{ + int retval; + + retval = zfcp_fc_ns_gid_pn_request(act); + if (retval == -ENOMEM) + return ZFCP_ERP_NOMEM; + act->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; + if (retval) + return ZFCP_ERP_FAILED; + return ZFCP_ERP_CONTINUES; } -static int -zfcp_erp_strategy_statechange(int action, - u32 status, - struct zfcp_adapter *adapter, - struct zfcp_port *port, - struct zfcp_unit *unit, int retval) +static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) { - switch (action) { + struct zfcp_adapter *adapter = act->adapter; + struct zfcp_port *port = act->port; - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - if (zfcp_erp_strategy_statechange_detected(&adapter->status, - status)) { - zfcp_erp_adapter_reopen_internal(adapter, - ZFCP_STATUS_COMMON_ERP_FAILED, - 67, NULL); - retval = ZFCP_ERP_EXIT; + if (port->wwpn != adapter->peer_wwpn) { + dev_err(&adapter->ccw_device->dev, + "Failed to open port 0x%016Lx, " + "Peer WWPN 0x%016Lx does not " + "match.\n", port->wwpn, + adapter->peer_wwpn); + zfcp_erp_port_failed(port, 25, NULL); + return ZFCP_ERP_FAILED; + } + port->d_id = adapter->peer_d_id; + atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); + return zfcp_erp_port_strategy_open_port(act); +} + +static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) +{ + struct zfcp_adapter *adapter = act->adapter; + struct zfcp_port *port = act->port; + struct zfcp_port *ns_port = adapter->nameserver_port; + int p_status = atomic_read(&port->status); + + switch (act->step) { + case ZFCP_ERP_STEP_UNINITIALIZED: + case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: + case ZFCP_ERP_STEP_PORT_CLOSING: + if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) + return zfcp_erp_open_ptp_port(act); + if (!ns_port) { + dev_err(&adapter->ccw_device->dev, + "Nameserver port unavailable.\n"); + return ZFCP_ERP_FAILED; } - break; + if (!(atomic_read(&ns_port->status) & + ZFCP_STATUS_COMMON_UNBLOCKED)) { + /* nameserver port may live again */ + atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, + &ns_port->status); + if (zfcp_erp_port_reopen(ns_port, 0, 77, act) >= 0) { + act->step = ZFCP_ERP_STEP_NAMESERVER_OPEN; + return ZFCP_ERP_CONTINUES; + } + return ZFCP_ERP_FAILED; + } + /* else nameserver port is already open, fall through */ + case ZFCP_ERP_STEP_NAMESERVER_OPEN: + if (!(atomic_read(&ns_port->status) & ZFCP_STATUS_COMMON_OPEN)) + return ZFCP_ERP_FAILED; + return zfcp_erp_port_strategy_open_lookup(act); - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - case ZFCP_ERP_ACTION_REOPEN_PORT: - if (zfcp_erp_strategy_statechange_detected(&port->status, - status)) { - zfcp_erp_port_reopen_internal(port, - ZFCP_STATUS_COMMON_ERP_FAILED, - 68, NULL); - retval = ZFCP_ERP_EXIT; + case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: + if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { + if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) { + zfcp_erp_port_failed(port, 26, NULL); + return ZFCP_ERP_EXIT; + } + return ZFCP_ERP_FAILED; } + return zfcp_erp_port_strategy_open_port(act); + + case ZFCP_ERP_STEP_PORT_OPENING: + /* D_ID might have changed during open */ + if ((p_status & ZFCP_STATUS_COMMON_OPEN) && + (p_status & ZFCP_STATUS_PORT_DID_DID)) + return ZFCP_ERP_SUCCEEDED; + /* fall through otherwise */ + } + return ZFCP_ERP_FAILED; +} + +static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *act) +{ + if (atomic_read(&act->port->status) & (ZFCP_STATUS_PORT_WKA)) + return zfcp_erp_port_strategy_open_nameserver(act); + return zfcp_erp_port_strategy_open_common(act); +} + +static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) +{ + struct zfcp_port *port = erp_action->port; + + switch (erp_action->step) { + case ZFCP_ERP_STEP_UNINITIALIZED: + zfcp_erp_port_strategy_clearstati(port); + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) + return zfcp_erp_port_strategy_close(erp_action); break; - case ZFCP_ERP_ACTION_REOPEN_UNIT: - if (zfcp_erp_strategy_statechange_detected(&unit->status, - status)) { - zfcp_erp_unit_reopen_internal(unit, - ZFCP_STATUS_COMMON_ERP_FAILED, - 69, NULL); - retval = ZFCP_ERP_EXIT; - } + case ZFCP_ERP_STEP_PORT_CLOSING: + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN) + return ZFCP_ERP_FAILED; break; } + if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) + return ZFCP_ERP_EXIT; + else + return zfcp_erp_port_strategy_open(erp_action); - return retval; + return ZFCP_ERP_FAILED; +} + +static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) +{ + atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | + ZFCP_STATUS_COMMON_CLOSING | + ZFCP_STATUS_COMMON_ACCESS_DENIED | + ZFCP_STATUS_UNIT_SHARED | + ZFCP_STATUS_UNIT_READONLY, + &unit->status); +} + +static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action) +{ + int retval = zfcp_fsf_close_unit(erp_action); + if (retval == -ENOMEM) + return ZFCP_ERP_NOMEM; + erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING; + if (retval) + return ZFCP_ERP_FAILED; + return ZFCP_ERP_CONTINUES; +} + +static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action) +{ + int retval = zfcp_fsf_open_unit(erp_action); + if (retval == -ENOMEM) + return ZFCP_ERP_NOMEM; + erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING; + if (retval) + return ZFCP_ERP_FAILED; + return ZFCP_ERP_CONTINUES; } -static int -zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status) +static int zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) { - return - /* take it online */ - (atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) && - (ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status)) || - /* take it offline */ - (!atomic_test_mask(ZFCP_STATUS_COMMON_RUNNING, target_status) && - !(ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status)); + struct zfcp_unit *unit = erp_action->unit; + + switch (erp_action->step) { + case ZFCP_ERP_STEP_UNINITIALIZED: + zfcp_erp_unit_strategy_clearstati(unit); + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_OPEN) + return zfcp_erp_unit_strategy_close(erp_action); + /* already closed, fall through */ + case ZFCP_ERP_STEP_UNIT_CLOSING: + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_OPEN) + return ZFCP_ERP_FAILED; + if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) + return ZFCP_ERP_EXIT; + return zfcp_erp_unit_strategy_open(erp_action); + + case ZFCP_ERP_STEP_UNIT_OPENING: + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_OPEN) + return ZFCP_ERP_SUCCEEDED; + } + return ZFCP_ERP_FAILED; } -static int -zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) +static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) { switch (result) { case ZFCP_ERP_SUCCEEDED : @@ -1177,29 +1068,25 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) zfcp_erp_unit_failed(unit, 21, NULL); break; - case ZFCP_ERP_EXIT : - /* nothing */ - break; } - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &unit->status)) { - zfcp_erp_unit_block(unit, 0); /* for ZFCP_ERP_SUCCEEDED */ + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { + zfcp_erp_unit_block(unit, 0); result = ZFCP_ERP_EXIT; } - return result; } -static int -zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) +static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) { switch (result) { case ZFCP_ERP_SUCCEEDED : atomic_set(&port->erp_counter, 0); zfcp_erp_port_unblock(port); break; + case ZFCP_ERP_FAILED : - if (atomic_test_mask(ZFCP_STATUS_COMMON_NOESC, &port->status)) { + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC) { zfcp_erp_port_block(port, 0); result = ZFCP_ERP_EXIT; } @@ -1207,1402 +1094,588 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) zfcp_erp_port_failed(port, 22, NULL); break; - case ZFCP_ERP_EXIT : - /* nothing */ - break; } - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) { - zfcp_erp_port_block(port, 0); /* for ZFCP_ERP_SUCCEEDED */ + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { + zfcp_erp_port_block(port, 0); result = ZFCP_ERP_EXIT; } - return result; } -static int -zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) +static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, + int result) { switch (result) { case ZFCP_ERP_SUCCEEDED : atomic_set(&adapter->erp_counter, 0); zfcp_erp_adapter_unblock(adapter); break; + case ZFCP_ERP_FAILED : atomic_inc(&adapter->erp_counter); if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) zfcp_erp_adapter_failed(adapter, 23, NULL); break; - case ZFCP_ERP_EXIT : - /* nothing */ - break; } - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) { - zfcp_erp_adapter_block(adapter, 0); /* for ZFCP_ERP_SUCCEEDED */ + if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { + zfcp_erp_adapter_block(adapter, 0); result = ZFCP_ERP_EXIT; } - return result; } -struct zfcp_erp_add_work { - struct zfcp_unit *unit; - struct work_struct work; -}; - -/** - * zfcp_erp_scsi_scan - * @data: pointer to a struct zfcp_erp_add_work - * - * Registers a logical unit with the SCSI stack. - */ -static void zfcp_erp_scsi_scan(struct work_struct *work) +static int zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, + int result) { - struct zfcp_erp_add_work *p = - container_of(work, struct zfcp_erp_add_work, work); - struct zfcp_unit *unit = p->unit; - struct fc_rport *rport = unit->port->rport; - scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, - unit->scsi_lun, 0); - atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); - zfcp_unit_put(unit); - kfree(p); + struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_port *port = erp_action->port; + struct zfcp_unit *unit = erp_action->unit; + + switch (erp_action->action) { + + case ZFCP_ERP_ACTION_REOPEN_UNIT: + result = zfcp_erp_strategy_check_unit(unit, result); + break; + + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + case ZFCP_ERP_ACTION_REOPEN_PORT: + result = zfcp_erp_strategy_check_port(port, result); + break; + + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + result = zfcp_erp_strategy_check_adapter(adapter, result); + break; + } + return result; } -/** - * zfcp_erp_schedule_work - * @unit: pointer to unit which should be registered with SCSI stack - * - * Schedules work which registers a unit with the SCSI stack - */ -static void -zfcp_erp_schedule_work(struct zfcp_unit *unit) +static int zfcp_erp_strat_change_det(atomic_t *target_status, u32 erp_status) { - struct zfcp_erp_add_work *p; + int status = atomic_read(target_status); - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) { - dev_err(&unit->port->adapter->ccw_device->dev, - "Out of resources. Could not register unit 0x%016Lx " - "on port 0x%016Lx with SCSI stack.\n", - unit->fcp_lun, unit->port->wwpn); - return; - } + if ((status & ZFCP_STATUS_COMMON_RUNNING) && + (erp_status & ZFCP_STATUS_ERP_CLOSE_ONLY)) + return 1; /* take it online */ - zfcp_unit_get(unit); - atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); - INIT_WORK(&p->work, zfcp_erp_scsi_scan); - p->unit = unit; - schedule_work(&p->work); + if (!(status & ZFCP_STATUS_COMMON_RUNNING) && + !(erp_status & ZFCP_STATUS_ERP_CLOSE_ONLY)) + return 1; /* take it offline */ + + return 0; } -/* - * function: - * - * purpose: remaining things in good cases, - * escalation in bad cases - * - * returns: - */ -static int -zfcp_erp_strategy_followup_actions(int action, - struct zfcp_adapter *adapter, - struct zfcp_port *port, - struct zfcp_unit *unit, int status) +static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) { - /* initiate follow-up actions depending on success of finished action */ - switch (action) { + int action = act->action; + struct zfcp_adapter *adapter = act->adapter; + struct zfcp_port *port = act->port; + struct zfcp_unit *unit = act->unit; + u32 erp_status = act->status; + switch (action) { case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - if (status == ZFCP_ERP_SUCCEEDED) - zfcp_erp_port_reopen_all_internal(adapter, 0, 70, NULL); - else - zfcp_erp_adapter_reopen_internal(adapter, 0, 71, NULL); + if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) { + _zfcp_erp_adapter_reopen(adapter, + ZFCP_STATUS_COMMON_ERP_FAILED, + 67, NULL); + return ZFCP_ERP_EXIT; + } break; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - if (status == ZFCP_ERP_SUCCEEDED) - zfcp_erp_port_reopen_internal(port, 0, 72, NULL); - else - zfcp_erp_adapter_reopen_internal(adapter, 0, 73, NULL); - break; - case ZFCP_ERP_ACTION_REOPEN_PORT: - if (status == ZFCP_ERP_SUCCEEDED) - zfcp_erp_unit_reopen_all_internal(port, 0, 74, NULL); - else - zfcp_erp_port_forced_reopen_internal(port, 0, 75, NULL); + if (zfcp_erp_strat_change_det(&port->status, erp_status)) { + _zfcp_erp_port_reopen(port, + ZFCP_STATUS_COMMON_ERP_FAILED, + 68, NULL); + return ZFCP_ERP_EXIT; + } break; case ZFCP_ERP_ACTION_REOPEN_UNIT: - /* Nothing to do if status == ZFCP_ERP_SUCCEEDED */ - if (status != ZFCP_ERP_SUCCEEDED) - zfcp_erp_port_reopen_internal(unit->port, 0, 76, NULL); + if (zfcp_erp_strat_change_det(&unit->status, erp_status)) { + _zfcp_erp_unit_reopen(unit, + ZFCP_STATUS_COMMON_ERP_FAILED, + 69, NULL); + return ZFCP_ERP_EXIT; + } break; } - - return 0; + return ret; } -static int -zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter) +static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) { - unsigned long flags; + struct zfcp_adapter *adapter = erp_action->adapter; - read_lock_irqsave(&zfcp_data.config_lock, flags); - read_lock(&adapter->erp_lock); - if (list_empty(&adapter->erp_ready_head) && - list_empty(&adapter->erp_running_head)) { - atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, - &adapter->status); - wake_up(&adapter->erp_done_wqh); + adapter->erp_total_count--; + if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { + adapter->erp_low_mem_count--; + erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; } - read_unlock(&adapter->erp_lock); - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - return 0; -} + list_del(&erp_action->list); + zfcp_rec_dbf_event_action(144, erp_action); -/** - * zfcp_erp_wait - wait for completion of error recovery on an adapter - * @adapter: adapter for which to wait for completion of its error recovery - * Return: 0 - */ -int -zfcp_erp_wait(struct zfcp_adapter *adapter) -{ - int retval = 0; + switch (erp_action->action) { + case ZFCP_ERP_ACTION_REOPEN_UNIT: + atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, + &erp_action->unit->status); + break; - wait_event(adapter->erp_done_wqh, - !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, - &adapter->status)); + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + case ZFCP_ERP_ACTION_REOPEN_PORT: + atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, + &erp_action->port->status); + break; - return retval; + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, + &erp_action->adapter->status); + break; + } } -void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id, - void *ref, u32 mask, int set_or_clear) -{ - struct zfcp_port *port; - u32 changed, common_mask = mask & ZFCP_COMMON_FLAGS; - - if (set_or_clear == ZFCP_SET) { - changed = atomic_test_and_set_mask(mask, &adapter->status); - } else { - changed = atomic_test_and_clear_mask(mask, &adapter->status); - if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) - atomic_set(&adapter->erp_counter, 0); - } - if (changed) - zfcp_rec_dbf_event_adapter(id, ref, adapter); +struct zfcp_erp_add_work { + struct zfcp_unit *unit; + struct work_struct work; +}; - /* Deal with all underlying devices, only pass common_mask */ - if (common_mask) - list_for_each_entry(port, &adapter->port_list_head, list) - zfcp_erp_modify_port_status(port, id, ref, common_mask, - set_or_clear); +static void zfcp_erp_scsi_scan(struct work_struct *work) +{ + struct zfcp_erp_add_work *p = + container_of(work, struct zfcp_erp_add_work, work); + struct zfcp_unit *unit = p->unit; + struct fc_rport *rport = unit->port->rport; + scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, + unit->scsi_lun, 0); + atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); + zfcp_unit_put(unit); + kfree(p); } -/* - * function: zfcp_erp_modify_port_status - * - * purpose: sets the port and all underlying devices to ERP_FAILED - * - */ -void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref, - u32 mask, int set_or_clear) +static void zfcp_erp_schedule_work(struct zfcp_unit *unit) { - struct zfcp_unit *unit; - u32 changed, common_mask = mask & ZFCP_COMMON_FLAGS; + struct zfcp_erp_add_work *p; - if (set_or_clear == ZFCP_SET) { - changed = atomic_test_and_set_mask(mask, &port->status); - } else { - changed = atomic_test_and_clear_mask(mask, &port->status); - if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) - atomic_set(&port->erp_counter, 0); + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + dev_err(&unit->port->adapter->ccw_device->dev, + "Out of resources. Could not register unit " + "0x%016Lx on port 0x%016Lx with SCSI stack.\n", + unit->fcp_lun, unit->port->wwpn); + return; } - if (changed) - zfcp_rec_dbf_event_port(id, ref, port); - /* Modify status of all underlying devices, only pass common mask */ - if (common_mask) - list_for_each_entry(unit, &port->unit_list_head, list) - zfcp_erp_modify_unit_status(unit, id, ref, common_mask, - set_or_clear); + zfcp_unit_get(unit); + atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); + INIT_WORK(&p->work, zfcp_erp_scsi_scan); + p->unit = unit; + schedule_work(&p->work); } -/* - * function: zfcp_erp_modify_unit_status - * - * purpose: sets the unit to ERP_FAILED - * - */ -void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref, - u32 mask, int set_or_clear) +static void zfcp_erp_rport_register(struct zfcp_port *port) { - u32 changed; - - if (set_or_clear == ZFCP_SET) { - changed = atomic_test_and_set_mask(mask, &unit->status); - } else { - changed = atomic_test_and_clear_mask(mask, &unit->status); - if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) { - atomic_set(&unit->erp_counter, 0); - } + struct fc_rport_identifiers ids; + ids.node_name = port->wwnn; + ids.port_name = port->wwpn; + ids.port_id = port->d_id; + ids.roles = FC_RPORT_ROLE_FCP_TARGET; + port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids); + if (!port->rport) { + dev_err(&port->adapter->ccw_device->dev, + "Failed registration of rport " + "0x%016Lx.\n", port->wwpn); + return; } - if (changed) - zfcp_rec_dbf_event_unit(id, ref, unit); -} - -/* - * function: - * - * purpose: Wrappper for zfcp_erp_port_reopen_all_internal - * used to ensure the correct locking - * - * returns: 0 - initiated action successfully - * <0 - failed to initiate action - */ -int zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask, - u8 id, void *ref) -{ - int retval; - unsigned long flags; - - read_lock_irqsave(&zfcp_data.config_lock, flags); - write_lock(&adapter->erp_lock); - retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask, id, - ref); - write_unlock(&adapter->erp_lock); - read_unlock_irqrestore(&zfcp_data.config_lock, flags); - return retval; + scsi_target_unblock(&port->rport->dev); + port->rport->maxframe_size = port->maxframe_size; + port->rport->supported_classes = port->supported_classes; } -static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, - int clear_mask, u8 id, void *ref) +static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) { - int retval = 0; struct zfcp_port *port; - list_for_each_entry(port, &adapter->port_list_head, list) - if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) - zfcp_erp_port_reopen_internal(port, clear_mask, id, - ref); - - return retval; + if (port->rport && !(atomic_read(&port->status) & + ZFCP_STATUS_PORT_WKA)) { + fc_remote_port_delete(port->rport); + port->rport = NULL; + } } -/* - * function: - * - * purpose: - * - * returns: FIXME - */ -static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, - int clear_mask, u8 id, void *ref) +static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) { - int retval = 0; - struct zfcp_unit *unit; + struct zfcp_adapter *adapter = act->adapter; + struct zfcp_port *port = act->port; + struct zfcp_unit *unit = act->unit; - list_for_each_entry(unit, &port->unit_list_head, list) - zfcp_erp_unit_reopen_internal(unit, clear_mask, id, ref); + switch (act->action) { + case ZFCP_ERP_ACTION_REOPEN_UNIT: + if ((result == ZFCP_ERP_SUCCEEDED) && + !unit->device && port->rport) { + atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, + &unit->status); + if (!(atomic_read(&unit->status) & + ZFCP_STATUS_UNIT_SCSI_WORK_PENDING)) + zfcp_erp_schedule_work(unit); + } + zfcp_unit_put(unit); + break; - return retval; + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + case ZFCP_ERP_ACTION_REOPEN_PORT: + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN) { + zfcp_port_put(port); + return; + } + if ((result == ZFCP_ERP_SUCCEEDED) && !port->rport) + zfcp_erp_rport_register(port); + if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) { + fc_remote_port_delete(port->rport); + port->rport = NULL; + } + zfcp_port_put(port); + break; + + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + if (result != ZFCP_ERP_SUCCEEDED) + zfcp_erp_rports_del(adapter); + zfcp_adapter_put(adapter); + break; + } } -/* - * function: - * - * purpose: this routine executes the 'Reopen Adapter' action - * (the entire action is processed synchronously, since - * there are no actions which might be run concurrently - * per definition) - * - * returns: ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action) +static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) { - int retval; - - retval = zfcp_erp_adapter_strategy_close(erp_action); - if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) - retval = ZFCP_ERP_EXIT; - else - retval = zfcp_erp_adapter_strategy_open(erp_action); - - if (retval == ZFCP_ERP_FAILED) - ssleep(ZFCP_TYPE2_RECOVERY_TIME); - - return retval; + switch (erp_action->action) { + case ZFCP_ERP_ACTION_REOPEN_ADAPTER: + return zfcp_erp_adapter_strategy(erp_action); + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + return zfcp_erp_port_forced_strategy(erp_action); + case ZFCP_ERP_ACTION_REOPEN_PORT: + return zfcp_erp_port_strategy(erp_action); + case ZFCP_ERP_ACTION_REOPEN_UNIT: + return zfcp_erp_unit_strategy(erp_action); + } + return ZFCP_ERP_FAILED; } -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action) +static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) { int retval; + struct zfcp_adapter *adapter = erp_action->adapter; + unsigned long flags; - atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, - &erp_action->adapter->status); - retval = zfcp_erp_adapter_strategy_generic(erp_action, 1); - atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, - &erp_action->adapter->status); + read_lock_irqsave(&zfcp_data.config_lock, flags); + write_lock(&adapter->erp_lock); - return retval; -} + zfcp_erp_strategy_check_fsfreq(erp_action); -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action) -{ - int retval; - - atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, - &erp_action->adapter->status); - retval = zfcp_erp_adapter_strategy_generic(erp_action, 0); - atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, - &erp_action->adapter->status); - - return retval; -} - -/* - * function: zfcp_register_adapter - * - * purpose: allocate the irq associated with this devno and register - * the FSF adapter with the SCSI stack - * - * returns: - */ -static int -zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close) -{ - int retval = ZFCP_ERP_SUCCEEDED; - - if (close) - goto close_only; - - retval = zfcp_erp_adapter_strategy_open_qdio(erp_action); - if (retval != ZFCP_ERP_SUCCEEDED) - goto failed_qdio; - - retval = zfcp_erp_adapter_strategy_open_fsf(erp_action); - if (retval != ZFCP_ERP_SUCCEEDED) - goto failed_openfcp; - - atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status); - schedule_work(&erp_action->adapter->scan_work); - goto out; - - close_only: - atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, - &erp_action->adapter->status); - - failed_openfcp: - zfcp_close_fsf(erp_action->adapter); - failed_qdio: - atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | - ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | - ZFCP_STATUS_ADAPTER_XPORT_OK, - &erp_action->adapter->status); - out: - return retval; -} - -/* - * function: zfcp_qdio_init - * - * purpose: setup QDIO operation for specified adapter - * - * returns: 0 - successful setup - * !0 - failed setup - */ -static int -zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) -{ - struct zfcp_adapter *adapter = erp_action->adapter; - - if (zfcp_qdio_open(adapter)) - return ZFCP_ERP_FAILED; - - /* initialize waitqueue used to wait for free SBALs in requests queue */ - init_waitqueue_head(&adapter->request_wq); - - /* ok, we did it - skip all cleanups for different failures */ - atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); - return ZFCP_ERP_SUCCEEDED; -} - - -static int -zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) -{ - int retval; - - retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); - if (retval == ZFCP_ERP_FAILED) - return ZFCP_ERP_FAILED; - - retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); - if (retval == ZFCP_ERP_FAILED) - return ZFCP_ERP_FAILED; - - return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); -} - -static void zfcp_erp_open_ptp_port(struct zfcp_adapter *adapter) -{ - struct zfcp_port *port; - port = zfcp_port_enqueue(adapter, adapter->peer_wwpn, 0, - adapter->peer_d_id); - if (IS_ERR(port)) /* error or port already attached */ - return; - zfcp_erp_port_reopen_internal(port, 0, 150, NULL); -} - -static int -zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) -{ - int retries; - int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP; - struct zfcp_adapter *adapter = erp_action->adapter; - - atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); - - for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) { - atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, - &adapter->status); - write_lock_irq(&adapter->erp_lock); - zfcp_erp_action_to_running(erp_action); - write_unlock_irq(&adapter->erp_lock); - if (zfcp_fsf_exchange_config_data(erp_action)) { - atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, - &adapter->status); - return ZFCP_ERP_FAILED; - } - - /* - * Why this works: - * Both the normal completion handler as well as the timeout - * handler will do an 'up' when the 'exchange config data' - * request completes or times out. Thus, the signal to go on - * won't be lost utilizing this semaphore. - * Furthermore, this 'adapter_reopen' action is - * guaranteed to be the only action being there (highest action - * which prevents other actions from being created). - * Resulting from that, the wake signal recognized here - * _must_ be the one belonging to the 'exchange config - * data' request. - */ - zfcp_rec_dbf_event_thread_lock(6, adapter); - down(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread_lock(7, adapter); - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) - break; - - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, - &adapter->status)) - break; - - /* sleep a little bit before retry */ - ssleep(sleep); - sleep *= 2; + if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { + zfcp_erp_action_dequeue(erp_action); + retval = ZFCP_ERP_DISMISSED; + goto unlock; } - atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, - &adapter->status); - - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, - &adapter->status)) - return ZFCP_ERP_FAILED; - - if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) - zfcp_erp_open_ptp_port(adapter); - - return ZFCP_ERP_SUCCEEDED; -} - -static int -zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) -{ - int ret; - struct zfcp_adapter *adapter; - - adapter = erp_action->adapter; - atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); - - write_lock_irq(&adapter->erp_lock); zfcp_erp_action_to_running(erp_action); - write_unlock_irq(&adapter->erp_lock); - - ret = zfcp_fsf_exchange_port_data(erp_action); - if (ret == -EOPNOTSUPP) { - return ZFCP_ERP_SUCCEEDED; - } else if (ret) { - return ZFCP_ERP_FAILED; - } - - ret = ZFCP_ERP_SUCCEEDED; - zfcp_rec_dbf_event_thread_lock(8, adapter); - down(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread_lock(9, adapter); - if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) - ret = ZFCP_ERP_FAILED; - - return ret; -} - -static int -zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action - *erp_action) -{ - struct zfcp_adapter *adapter = erp_action->adapter; - - atomic_set(&adapter->stat_miss, 16); - return zfcp_status_read_refill(adapter); -} - -/* - * function: - * - * purpose: this routine executes the 'Reopen Physical Port' action - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) -{ - int retval = ZFCP_ERP_FAILED; - struct zfcp_port *port = erp_action->port; - - switch (erp_action->step) { - - /* - * FIXME: - * the ULP spec. begs for waiting for oustanding commands - */ - case ZFCP_ERP_STEP_UNINITIALIZED: - zfcp_erp_port_strategy_clearstati(port); - /* - * it would be sufficient to test only the normal open flag - * since the phys. open flag cannot be set if the normal - * open flag is unset - however, this is for readabilty ... - */ - if (atomic_test_mask((ZFCP_STATUS_PORT_PHYS_OPEN | - ZFCP_STATUS_COMMON_OPEN), - &port->status)) { - retval = - zfcp_erp_port_forced_strategy_close(erp_action); - } else - retval = ZFCP_ERP_FAILED; - break; - - case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: - if (atomic_test_mask(ZFCP_STATUS_PORT_PHYS_OPEN, - &port->status)) { - retval = ZFCP_ERP_FAILED; - } else - retval = ZFCP_ERP_SUCCEEDED; - break; - } - - return retval; -} - -/* - * function: - * - * purpose: this routine executes the 'Reopen Port' action - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) -{ - int retval = ZFCP_ERP_FAILED; - struct zfcp_port *port = erp_action->port; - - switch (erp_action->step) { - - /* - * FIXME: - * the ULP spec. begs for waiting for oustanding commands - */ - case ZFCP_ERP_STEP_UNINITIALIZED: - zfcp_erp_port_strategy_clearstati(port); - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) { - retval = zfcp_erp_port_strategy_close(erp_action); - goto out; - } /* else it's already closed, open it */ - break; - - case ZFCP_ERP_STEP_PORT_CLOSING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) { - retval = ZFCP_ERP_FAILED; - goto out; - } /* else it's closed now, open it */ - break; - } - if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) - retval = ZFCP_ERP_EXIT; - else - retval = zfcp_erp_port_strategy_open(erp_action); - out: - return retval; -} - -static int -zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action) -{ - int retval; - - if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, - &erp_action->port->status)) - retval = zfcp_erp_port_strategy_open_nameserver(erp_action); - else - retval = zfcp_erp_port_strategy_open_common(erp_action); - - return retval; -} - -static int -zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) -{ - int retval = 0; - struct zfcp_adapter *adapter = erp_action->adapter; - struct zfcp_port *port = erp_action->port; - - switch (erp_action->step) { + /* no lock to allow for blocking operations */ + write_unlock(&adapter->erp_lock); + read_unlock_irqrestore(&zfcp_data.config_lock, flags); + retval = zfcp_erp_strategy_do_action(erp_action); + read_lock_irqsave(&zfcp_data.config_lock, flags); + write_lock(&adapter->erp_lock); - case ZFCP_ERP_STEP_UNINITIALIZED: - case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: - case ZFCP_ERP_STEP_PORT_CLOSING: - if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) { - if (port->wwpn != adapter->peer_wwpn) { - dev_err(&adapter->ccw_device->dev, - "Failed to open port 0x%016Lx, " - "Peer WWPN 0x%016Lx does not match.\n", - port->wwpn, adapter->peer_wwpn); - zfcp_erp_port_failed(port, 25, NULL); - retval = ZFCP_ERP_FAILED; - break; - } - port->d_id = adapter->peer_d_id; - atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); - retval = zfcp_erp_port_strategy_open_port(erp_action); - break; - } + if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) + retval = ZFCP_ERP_CONTINUES; - if (!adapter->nameserver_port) { - dev_err(&adapter->ccw_device->dev, - "Nameserver port unavailable.\n"); - retval = ZFCP_ERP_FAILED; - break; - } - if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, - &adapter->nameserver_port->status)) { - /* nameserver port may live again */ - atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, - &adapter->nameserver_port->status); - if (zfcp_erp_port_reopen(adapter->nameserver_port, 0, - 77, erp_action) >= 0) { - erp_action->step = - ZFCP_ERP_STEP_NAMESERVER_OPEN; - retval = ZFCP_ERP_CONTINUES; - } else - retval = ZFCP_ERP_FAILED; - break; + switch (retval) { + case ZFCP_ERP_NOMEM: + if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) { + ++adapter->erp_low_mem_count; + erp_action->status |= ZFCP_STATUS_ERP_LOWMEM; } - /* else nameserver port is already open, fall through */ - case ZFCP_ERP_STEP_NAMESERVER_OPEN: - if (!atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, - &adapter->nameserver_port->status)) - retval = ZFCP_ERP_FAILED; - else - retval = zfcp_erp_port_strategy_open_common_lookup - (erp_action); - break; - - case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: - if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) { - if (atomic_test_mask - (ZFCP_STATUS_PORT_INVALID_WWPN, &port->status)) { - zfcp_erp_port_failed(port, 26, NULL); - retval = ZFCP_ERP_EXIT; - } else - retval = ZFCP_ERP_FAILED; - } else - retval = zfcp_erp_port_strategy_open_port(erp_action); - break; - - case ZFCP_ERP_STEP_PORT_OPENING: - /* D_ID might have changed during open */ - if (atomic_test_mask((ZFCP_STATUS_COMMON_OPEN | - ZFCP_STATUS_PORT_DID_DID), - &port->status)) - retval = ZFCP_ERP_SUCCEEDED; - else - retval = ZFCP_ERP_FAILED; - break; - - default: - /* unknown erp step */ - retval = ZFCP_ERP_FAILED; - } - - return retval; -} - -static int -zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action) -{ - int retval; - struct zfcp_port *port = erp_action->port; - - switch (erp_action->step) { - - case ZFCP_ERP_STEP_UNINITIALIZED: - case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: - case ZFCP_ERP_STEP_PORT_CLOSING: - retval = zfcp_erp_port_strategy_open_port(erp_action); - break; - - case ZFCP_ERP_STEP_PORT_OPENING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) - retval = ZFCP_ERP_SUCCEEDED; - else - retval = ZFCP_ERP_FAILED; - /* this is needed anyway (dont care for retval of wakeup) */ - zfcp_erp_port_strategy_open_nameserver_wakeup(erp_action); - break; - - default: - /* unknown erp step */ - retval = ZFCP_ERP_FAILED; - } - - return retval; -} - -/* - * function: - * - * purpose: makes the erp thread continue with reopen (physical) port - * actions which have been paused until the name server port - * is opened (or failed) - * - * returns: 0 (a kind of void retval, its not used) - */ -static int -zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action - *ns_erp_action) -{ - int retval = 0; - unsigned long flags; - struct zfcp_adapter *adapter = ns_erp_action->adapter; - struct zfcp_erp_action *erp_action, *tmp; - - read_lock_irqsave(&adapter->erp_lock, flags); - list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head, - list) { - if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) { - if (atomic_test_mask( - ZFCP_STATUS_COMMON_ERP_FAILED, - &adapter->nameserver_port->status)) - zfcp_erp_port_failed(erp_action->port, 27, - NULL); - zfcp_erp_action_ready(erp_action); + if (adapter->erp_total_count == adapter->erp_low_mem_count) + _zfcp_erp_adapter_reopen(adapter, 0, 66, NULL); + else { + zfcp_erp_strategy_memwait(erp_action); + retval = ZFCP_ERP_CONTINUES; } - } - read_unlock_irqrestore(&adapter->erp_lock, flags); - - return retval; -} - -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action) -{ - int retval; - - retval = zfcp_fsf_close_physical_port(erp_action); - if (retval == -ENOMEM) { - retval = ZFCP_ERP_NOMEM; - goto out; - } - erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING; - if (retval != 0) { - /* could not send 'open', fail */ - retval = ZFCP_ERP_FAILED; - goto out; - } - retval = ZFCP_ERP_CONTINUES; - out: - return retval; -} - -static int -zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) -{ - int retval = 0; - - atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | - ZFCP_STATUS_COMMON_CLOSING | - ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_PORT_DID_DID | - ZFCP_STATUS_PORT_PHYS_CLOSING | - ZFCP_STATUS_PORT_INVALID_WWPN, - &port->status); - return retval; -} - -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) -{ - int retval; - - retval = zfcp_fsf_close_port(erp_action); - if (retval == -ENOMEM) { - retval = ZFCP_ERP_NOMEM; - goto out; - } - erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING; - if (retval != 0) { - /* could not send 'close', fail */ - retval = ZFCP_ERP_FAILED; - goto out; - } - retval = ZFCP_ERP_CONTINUES; - out: - return retval; -} - -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) -{ - int retval; - - retval = zfcp_fsf_open_port(erp_action); - if (retval == -ENOMEM) { - retval = ZFCP_ERP_NOMEM; - goto out; - } - erp_action->step = ZFCP_ERP_STEP_PORT_OPENING; - if (retval != 0) { - /* could not send 'open', fail */ - retval = ZFCP_ERP_FAILED; - goto out; - } - retval = ZFCP_ERP_CONTINUES; - out: - return retval; -} - -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action) -{ - int retval; - - retval = zfcp_fc_ns_gid_pn_request(erp_action); - if (retval == -ENOMEM) { - retval = ZFCP_ERP_NOMEM; - goto out; - } - erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; - if (retval != 0) { - /* could not send nameserver request, fail */ - retval = ZFCP_ERP_FAILED; - goto out; - } - retval = ZFCP_ERP_CONTINUES; - out: - return retval; -} - -/* - * function: - * - * purpose: this routine executes the 'Reopen Unit' action - * currently no retries - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_SUCCEEDED - action finished successfully - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) -{ - int retval = ZFCP_ERP_FAILED; - struct zfcp_unit *unit = erp_action->unit; - - switch (erp_action->step) { + goto unlock; - /* - * FIXME: - * the ULP spec. begs for waiting for oustanding commands - */ - case ZFCP_ERP_STEP_UNINITIALIZED: - zfcp_erp_unit_strategy_clearstati(unit); - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) { - retval = zfcp_erp_unit_strategy_close(erp_action); - break; + case ZFCP_ERP_CONTINUES: + if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { + --adapter->erp_low_mem_count; + erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; } - /* else it's already closed, fall through */ - case ZFCP_ERP_STEP_UNIT_CLOSING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) - retval = ZFCP_ERP_FAILED; - else - if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) - retval = ZFCP_ERP_EXIT; - else - retval = - zfcp_erp_unit_strategy_open(erp_action); - break; - - case ZFCP_ERP_STEP_UNIT_OPENING: - if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status)) - retval = ZFCP_ERP_SUCCEEDED; - else - retval = ZFCP_ERP_FAILED; - break; + goto unlock; } - return retval; -} - -static int -zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) -{ - int retval = 0; - - atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | - ZFCP_STATUS_COMMON_CLOSING | - ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_UNIT_SHARED | - ZFCP_STATUS_UNIT_READONLY, - &unit->status); - - return retval; -} - -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action) -{ - int retval; - - retval = zfcp_fsf_close_unit(erp_action); - if (retval == -ENOMEM) { - retval = ZFCP_ERP_NOMEM; - goto out; - } - erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING; - if (retval != 0) { - /* could not send 'close', fail */ - retval = ZFCP_ERP_FAILED; - goto out; - } - retval = ZFCP_ERP_CONTINUES; + retval = zfcp_erp_strategy_check_target(erp_action, retval); + zfcp_erp_action_dequeue(erp_action); + retval = zfcp_erp_strategy_statechange(erp_action, retval); + if (retval == ZFCP_ERP_EXIT) + goto unlock; + zfcp_erp_strategy_followup_actions(erp_action); - out: - return retval; -} + unlock: + write_unlock(&adapter->erp_lock); + read_unlock_irqrestore(&zfcp_data.config_lock, flags); -/* - * function: - * - * purpose: - * - * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) - * ZFCP_ERP_FAILED - action finished unsuccessfully - */ -static int -zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action) -{ - int retval; + if (retval != ZFCP_ERP_CONTINUES) + zfcp_erp_action_cleanup(erp_action, retval); - retval = zfcp_fsf_open_unit(erp_action); - if (retval == -ENOMEM) { - retval = ZFCP_ERP_NOMEM; - goto out; - } - erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING; - if (retval != 0) { - /* could not send 'open', fail */ - retval = ZFCP_ERP_FAILED; - goto out; - } - retval = ZFCP_ERP_CONTINUES; - out: return retval; } -void zfcp_erp_start_timer(struct zfcp_fsf_req *fsf_req) -{ - BUG_ON(!fsf_req->erp_action); - fsf_req->timer.function = zfcp_erp_timeout_handler; - fsf_req->timer.data = (unsigned long) fsf_req->erp_action; - fsf_req->timer.expires = jiffies + ZFCP_ERP_FSFREQ_TIMEOUT; - add_timer(&fsf_req->timer); -} - -/* - * function: - * - * purpose: enqueue the specified error recovery action, if needed - * - * returns: - */ -static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, - struct zfcp_port *port, - struct zfcp_unit *unit, u8 id, void *ref) +static int zfcp_erp_thread(void *data) { - int retval = 1, need = want; - struct zfcp_erp_action *erp_action = NULL; - u32 status = 0; - - /* - * We need some rules here which check whether we really need - * this action or whether we should just drop it. - * E.g. if there is a unfinished 'Reopen Port' request then we drop a - * 'Reopen Unit' request for an associated unit since we can't - * satisfy this request now. A 'Reopen Port' action will trigger - * 'Reopen Unit' actions when it completes. - * Thus, there are only actions in the queue which can immediately be - * executed. This makes the processing of the action queue more - * efficient. - */ - - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, - &adapter->status)) - return -EIO; + struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; + struct list_head *next; + struct zfcp_erp_action *act; + unsigned long flags; - /* check whether we really need this */ - switch (want) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: - if (atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) { - goto out; - } - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_RUNNING, &port->status) || - atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_FAILED, &port->status)) { - goto out; - } - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) - need = ZFCP_ERP_ACTION_REOPEN_PORT; - /* fall through !!! */ + daemonize("zfcperp%s", adapter->ccw_device->dev.bus_id); + /* Block all signals */ + siginitsetinv(¤t->blocked, 0); + atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); + wake_up(&adapter->erp_thread_wqh); - case ZFCP_ERP_ACTION_REOPEN_PORT: - if (atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) { - goto out; - } - /* fall through !!! */ + while (!(atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) { + write_lock_irqsave(&adapter->erp_lock, flags); + next = adapter->erp_ready_head.next; + write_unlock_irqrestore(&adapter->erp_lock, flags); - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, - &port->status)) - goto out; - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_RUNNING, &adapter->status) || - atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) { - goto out; - } - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) - need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; - /* fall through !!! */ + if (next != &adapter->erp_ready_head) { + act = list_entry(next, struct zfcp_erp_action, list); - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - if (atomic_test_mask - (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) { - goto out; + /* there is more to come after dismission, no notify */ + if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED) + zfcp_erp_wakeup(adapter); } - break; - default: - /* unknown erp action */ - goto out; + zfcp_rec_dbf_event_thread(4, adapter); + down_interruptible(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread(5, adapter); } - /* mark adapter to have some error recovery pending */ - atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); - - /* setup error recovery action */ - switch (need) { + atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); + wake_up(&adapter->erp_thread_wqh); - case ZFCP_ERP_ACTION_REOPEN_UNIT: - zfcp_unit_get(unit); - atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); - erp_action = &unit->erp_action; - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_RUNNING, &unit->status)) - status = ZFCP_STATUS_ERP_CLOSE_ONLY; - break; + return 0; +} - case ZFCP_ERP_ACTION_REOPEN_PORT: - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - zfcp_port_get(port); - zfcp_erp_action_dismiss_port(port); - atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); - erp_action = &port->erp_action; - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_RUNNING, &port->status)) - status = ZFCP_STATUS_ERP_CLOSE_ONLY; - break; +/** + * zfcp_erp_thread_setup - Start ERP thread for adapter + * @adapter: Adapter to start the ERP thread for + * + * Returns 0 on success or error code from kernel_thread() + */ +int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) +{ + int retval; - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - zfcp_adapter_get(adapter); - zfcp_erp_action_dismiss_adapter(adapter); - atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); - erp_action = &adapter->erp_action; - if (!atomic_test_mask - (ZFCP_STATUS_COMMON_RUNNING, &adapter->status)) - status = ZFCP_STATUS_ERP_CLOSE_ONLY; - break; + atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); + retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); + if (retval < 0) { + dev_err(&adapter->ccw_device->dev, + "Creation of ERP thread failed.\n"); + return retval; } + wait_event(adapter->erp_thread_wqh, + atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_ERP_THREAD_UP); + return 0; +} - memset(erp_action, 0, sizeof (struct zfcp_erp_action)); - erp_action->adapter = adapter; - erp_action->port = port; - erp_action->unit = unit; - erp_action->action = need; - erp_action->status = status; +/** + * zfcp_erp_thread_kill - Stop ERP thread. + * @adapter: Adapter where the ERP thread should be stopped. + * + * The caller of this routine ensures that the specified adapter has + * been shut down and that this operation has been completed. Thus, + * there are no pending erp_actions which would need to be handled + * here. + */ +void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) +{ + atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); + up(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread_lock(2, adapter); - ++adapter->erp_total_count; + wait_event(adapter->erp_thread_wqh, + !(atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_ERP_THREAD_UP)); - /* finally put it into 'ready' queue and kick erp thread */ - list_add_tail(&erp_action->list, &adapter->erp_ready_head); - up(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread(1, adapter); - retval = 0; - out: - zfcp_rec_dbf_event_trigger(id, ref, want, need, erp_action, - adapter, port, unit); - return retval; + atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, + &adapter->status); } -static int -zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) +/** + * zfcp_erp_adapter_failed - Set adapter status to failed. + * @adapter: Failed adapter. + * @id: Event id for debug trace. + * @ref: Reference for debug trace. + */ +void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref) { - int retval = 0; - struct zfcp_adapter *adapter = erp_action->adapter; - - --adapter->erp_total_count; - if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { - --adapter->erp_low_mem_count; - erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; - } + zfcp_erp_modify_adapter_status(adapter, id, ref, + ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); + dev_err(&adapter->ccw_device->dev, "Adapter ERP failed.\n"); +} - list_del(&erp_action->list); - zfcp_rec_dbf_event_action(144, erp_action); +/** + * zfcp_erp_port_failed - Set port status to failed. + * @port: Failed port. + * @id: Event id for debug trace. + * @ref: Reference for debug trace. + */ +void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref) +{ + zfcp_erp_modify_port_status(port, id, ref, + ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); - switch (erp_action->action) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: - atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, - &erp_action->unit->status); - break; - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - case ZFCP_ERP_ACTION_REOPEN_PORT: - atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, - &erp_action->port->status); - break; - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, - &erp_action->adapter->status); - break; - default: - /* bug */ - break; - } - return retval; + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) + dev_err(&port->adapter->ccw_device->dev, + "Port ERP failed for WKA port d_id=0x%06x.\n", + port->d_id); + else + dev_err(&port->adapter->ccw_device->dev, + "Port ERP failed for port wwpn=0x%016Lx.\n", + port->wwpn); } /** - * zfcp_erp_action_cleanup - * - * Register unit with scsi stack if appropriate and fix reference counts. - * Note: Temporary units are not registered with scsi stack. + * zfcp_erp_unit_failed - Set unit status to failed. + * @unit: Failed unit. + * @id: Event id for debug trace. + * @ref: Reference for debug trace. */ -static void -zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, - struct zfcp_port *port, struct zfcp_unit *unit, - int result) +void zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref) { - switch (action) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: - if ((result == ZFCP_ERP_SUCCEEDED) - && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, - &unit->status)) - && !unit->device - && port->rport) { - atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, - &unit->status); - if (atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, - &unit->status) == 0) - zfcp_erp_schedule_work(unit); - } - zfcp_unit_put(unit); - break; - case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: - case ZFCP_ERP_ACTION_REOPEN_PORT: - if (atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, - &port->status)) { - zfcp_port_put(port); - break; - } + zfcp_erp_modify_unit_status(unit, id, ref, + ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); - if ((result == ZFCP_ERP_SUCCEEDED) - && !port->rport) { - struct fc_rport_identifiers ids; - ids.node_name = port->wwnn; - ids.port_name = port->wwpn; - ids.port_id = port->d_id; - ids.roles = FC_RPORT_ROLE_FCP_TARGET; - port->rport = - fc_remote_port_add(adapter->scsi_host, 0, &ids); - if (!port->rport) - dev_err(&adapter->ccw_device->dev, - "Failed registration of rport " - "0x%016Lx.\n", port->wwpn); - else { - scsi_target_unblock(&port->rport->dev); - port->rport->maxframe_size = port->maxframe_size; - port->rport->supported_classes = - port->supported_classes; - } - } - if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) { - fc_remote_port_delete(port->rport); - port->rport = NULL; - } - zfcp_port_put(port); - break; - case ZFCP_ERP_ACTION_REOPEN_ADAPTER: - if (result != ZFCP_ERP_SUCCEEDED) { - list_for_each_entry(port, &adapter->port_list_head, list) - if (port->rport && - !atomic_test_mask(ZFCP_STATUS_PORT_WKA, - &port->status)) { - fc_remote_port_delete(port->rport); - port->rport = NULL; - } - } - zfcp_adapter_put(adapter); - break; - default: - break; - } + dev_err(&unit->port->adapter->ccw_device->dev, + "Unit ERP failed for unit 0x%016Lx on port 0x%016Lx.\n", + unit->fcp_lun, unit->port->wwpn); } +/** + * zfcp_erp_wait - wait for completion of error recovery on an adapter + * @adapter: adapter for which to wait for completion of its error recovery + */ +void zfcp_erp_wait(struct zfcp_adapter *adapter) +{ + wait_event(adapter->erp_done_wqh, + !(atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_ERP_PENDING)); +} -static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) +/** + * zfcp_erp_modify_adapter_status - change adapter status bits + * @adapter: adapter to change the status + * @id: id for the debug trace + * @ref: reference for the debug trace + * @mask: status bits to change + * @set_or_clear: ZFCP_SET or ZFCP_CLEAR + * + * Changes in common status bits are propagated to attached ports and units. + */ +void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id, + void *ref, u32 mask, int set_or_clear) { struct zfcp_port *port; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) - zfcp_erp_action_dismiss(&adapter->erp_action); - else + if (set_or_clear == ZFCP_SET) { + if (status_change_set(mask, &adapter->status)) + zfcp_rec_dbf_event_adapter(id, ref, adapter); + atomic_set_mask(mask, &adapter->status); + } else { + if (status_change_clear(mask, &adapter->status)) + zfcp_rec_dbf_event_adapter(id, ref, adapter); + atomic_clear_mask(mask, &adapter->status); + if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) + atomic_set(&adapter->erp_counter, 0); + } + + if (common_mask) list_for_each_entry(port, &adapter->port_list_head, list) - zfcp_erp_action_dismiss_port(port); + zfcp_erp_modify_port_status(port, id, ref, common_mask, + set_or_clear); } -static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) +/** + * zfcp_erp_modify_port_status - change port status bits + * @port: port to change the status bits + * @id: id for the debug trace + * @ref: reference for the debug trace + * @mask: status bits to change + * @set_or_clear: ZFCP_SET or ZFCP_CLEAR + * + * Changes in common status bits are propagated to attached units. + */ +void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref, + u32 mask, int set_or_clear) { struct zfcp_unit *unit; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) - zfcp_erp_action_dismiss(&port->erp_action); - else - list_for_each_entry(unit, &port->unit_list_head, list) - zfcp_erp_action_dismiss_unit(unit); -} - -static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) -{ - if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) - zfcp_erp_action_dismiss(&unit->erp_action); -} + if (set_or_clear == ZFCP_SET) { + if (status_change_set(mask, &port->status)) + zfcp_rec_dbf_event_port(id, ref, port); + atomic_set_mask(mask, &port->status); + } else { + if (status_change_clear(mask, &port->status)) + zfcp_rec_dbf_event_port(id, ref, port); + atomic_clear_mask(mask, &port->status); + if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) + atomic_set(&port->erp_counter, 0); + } -static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) -{ - list_move(&erp_action->list, &erp_action->adapter->erp_running_head); - zfcp_rec_dbf_event_action(145, erp_action); + if (common_mask) + list_for_each_entry(unit, &port->unit_list_head, list) + zfcp_erp_modify_unit_status(unit, id, ref, common_mask, + set_or_clear); } -static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) +/** + * zfcp_erp_modify_unit_status - change unit status bits + * @unit: unit to change the status bits + * @id: id for the debug trace + * @ref: reference for the debug trace + * @mask: status bits to change + * @set_or_clear: ZFCP_SET or ZFCP_CLEAR + */ +void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref, + u32 mask, int set_or_clear) { - list_move(&erp_action->list, &erp_action->adapter->erp_ready_head); - zfcp_rec_dbf_event_action(146, erp_action); + if (set_or_clear == ZFCP_SET) { + if (status_change_set(mask, &unit->status)) + zfcp_rec_dbf_event_unit(id, ref, unit); + atomic_set_mask(mask, &unit->status); + } else { + if (status_change_clear(mask, &unit->status)) + zfcp_rec_dbf_event_unit(id, ref, unit); + atomic_clear_mask(mask, &unit->status); + if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) { + atomic_set(&unit->erp_counter, 0); + } + } } +/** + * zfcp_erp_port_boxed - Mark port as "boxed" and start ERP + * @port: The "boxed" port. + * @id: The debug trace id. + * @id: Reference for the debug trace. + */ void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref) { unsigned long flags; @@ -2614,6 +1687,12 @@ void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref) zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } +/** + * zfcp_erp_unit_boxed - Mark unit as "boxed" and start ERP + * @port: The "boxed" unit. + * @id: The debug trace id. + * @id: Reference for the debug trace. + */ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref) { zfcp_erp_modify_unit_status(unit, id, ref, @@ -2621,6 +1700,15 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref) zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } +/** + * zfcp_erp_port_access_denied - Adapter denied access to port. + * @port: port where access has been denied + * @id: id for debug trace + * @ref: reference for debug trace + * + * Since the adapter has denied access, stop using the port and the + * attached units. + */ void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref) { unsigned long flags; @@ -2632,6 +1720,14 @@ void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref) read_unlock_irqrestore(&zfcp_data.config_lock, flags); } +/** + * zfcp_erp_unit_access_denied - Adapter denied access to unit. + * @unit: unit where access has been denied + * @id: id for debug trace + * @ref: reference for debug trace + * + * Since the adapter has denied access, stop using the unit. + */ void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, u8 id, void *ref) { zfcp_erp_modify_unit_status(unit, id, ref, @@ -2639,33 +1735,26 @@ void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, u8 id, void *ref) ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); } -void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id, - void *ref) +static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id, + void *ref) { - struct zfcp_port *port; - unsigned long flags; - - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) + int status = atomic_read(&unit->status); + if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | + ZFCP_STATUS_COMMON_ACCESS_BOXED))) return; - read_lock_irqsave(&zfcp_data.config_lock, flags); - if (adapter->nameserver_port) - zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref); - list_for_each_entry(port, &adapter->port_list_head, list) - if (port != adapter->nameserver_port) - zfcp_erp_port_access_changed(port, id, ref); - read_unlock_irqrestore(&zfcp_data.config_lock, flags); + zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } -void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, void *ref) +static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, + void *ref) { struct zfcp_unit *unit; + int status = atomic_read(&port->status); - if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, - &port->status) && - !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, - &port->status)) { - if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) + if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | + ZFCP_STATUS_COMMON_ACCESS_BOXED))) { + if (!(status & ZFCP_STATUS_PORT_WKA)) list_for_each_entry(unit, &port->unit_list_head, list) zfcp_erp_unit_access_changed(unit, id, ref); return; @@ -2674,13 +1763,26 @@ void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, void *ref) zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } -void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id, void *ref) +/** + * zfcp_erp_adapter_access_changed - Process change in adapter ACT + * @adapter: Adapter where the Access Control Table (ACT) changed + * @id: Id for debug trace + * @ref: Reference for debug trace + */ +void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id, + void *ref) { - if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, - &unit->status) && - !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, - &unit->status)) + struct zfcp_port *port; + unsigned long flags; + + if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) return; - zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); + read_lock_irqsave(&zfcp_data.config_lock, flags); + if (adapter->nameserver_port) + zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref); + list_for_each_entry(port, &adapter->port_list_head, list) + if (port != adapter->nameserver_port) + zfcp_erp_port_access_changed(port, id, ref); + read_unlock_irqrestore(&zfcp_data.config_lock, flags); } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 2845693..13eb0a6 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -67,8 +67,6 @@ extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *, struct fsf_qtcb_bottom_port *); extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, struct zfcp_fsf_cfdc *fsf_cfdc); -extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); -extern void zfcp_erp_start_timer(struct zfcp_fsf_req *); extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); extern int zfcp_fsf_status_read(struct zfcp_adapter *); extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); @@ -103,37 +101,34 @@ extern struct fc_function_template zfcp_transport_functions; /******************************** ERP ****************************************/ extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *, u32, int); -extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *); -extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *); +extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *); +extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *); extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *); extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32, int); extern int zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *); -extern int zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *); -extern int zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *); +extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *); +extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *); extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *); -extern int zfcp_erp_port_reopen_all(struct zfcp_adapter *, int, u8, void *); extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32, int); -extern int zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *); -extern int zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *); +extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *); +extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *); extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *); extern int zfcp_erp_thread_setup(struct zfcp_adapter *); -extern int zfcp_erp_thread_kill(struct zfcp_adapter *); -extern int zfcp_erp_wait(struct zfcp_adapter *); -extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long); +extern void zfcp_erp_thread_kill(struct zfcp_adapter *); +extern void zfcp_erp_wait(struct zfcp_adapter *); +extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); extern void zfcp_erp_port_boxed(struct zfcp_port *, u8 id, void *ref); extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8 id, void *ref); extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8 id, void *ref); extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8 id, void *ref); extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); -extern void zfcp_erp_port_access_changed(struct zfcp_port *, u8, void *); -extern void zfcp_erp_unit_access_changed(struct zfcp_unit *, u8, void *); - +extern void zfcp_erp_timeout_handler(unsigned long); /******************************** AUX ****************************************/ extern void zfcp_sg_free_table(struct scatterlist *sg, int count); extern int zfcp_sg_setup_table(struct scatterlist *sg, int count); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index e6d8155..19c1ca9 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -8,6 +8,31 @@ #include "zfcp_ext.h" +static void zfcp_fsf_request_timeout_handler(unsigned long data) +{ + struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; + zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 62, + NULL); +} + +static void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, + unsigned long timeout) +{ + fsf_req->timer.function = zfcp_fsf_request_timeout_handler; + fsf_req->timer.data = (unsigned long) fsf_req->adapter; + fsf_req->timer.expires = jiffies + timeout; + add_timer(&fsf_req->timer); +} + +static void zfcp_fsf_start_erp_timer(struct zfcp_fsf_req *fsf_req) +{ + BUG_ON(!fsf_req->erp_action); + fsf_req->timer.function = zfcp_erp_timeout_handler; + fsf_req->timer.data = (unsigned long) fsf_req->erp_action; + fsf_req->timer.expires = jiffies + 30 * HZ; + add_timer(&fsf_req->timer); +} + /* association between FSF command and FSF QTCB type */ static u32 fsf_qtcb_type[] = { [FSF_QTCB_FCP_CMND] = FSF_IO_COMMAND, @@ -485,7 +510,7 @@ void zfcp_fsf_req_complete(struct zfcp_fsf_req *req) req->handler(req); if (req->erp_action) - zfcp_erp_async_handler(req->erp_action, 0); + zfcp_erp_notify(req->erp_action, 0); req->status |= ZFCP_STATUS_FSFREQ_COMPLETED; if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) @@ -1108,7 +1133,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, if (erp_action) { erp_action->fsf_req = req; req->erp_action = erp_action; - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); } else zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); @@ -1263,7 +1288,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) req->handler = zfcp_fsf_exchange_config_data_handler; erp_action->fsf_req = req; - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); @@ -1353,7 +1378,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) req->erp_action = erp_action; erp_action->fsf_req = req; - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); @@ -1530,7 +1555,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req = req; atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status); - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); @@ -1601,7 +1626,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req = req; atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status); - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); @@ -1699,7 +1724,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, &erp_action->port->status); - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); @@ -1878,7 +1903,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); @@ -1963,7 +1988,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) erp_action->fsf_req = req; atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status); - zfcp_erp_start_timer(req); + zfcp_fsf_start_erp_timer(req); retval = zfcp_fsf_req_send(req); if (retval) { zfcp_fsf_req_free(req); -- cgit v0.10.2 From 92c299d11acd3f3e75a721acb8f57c457d5c394f Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 2 Jul 2008 10:56:41 +0200 Subject: [SCSI] zfcp: Cleanup external header file Sort the extern definitions by file. Signed-off-by: Christof Schmitt Signed-off-by: Swen Schillig Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 13eb0a6..8065b2b 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -11,160 +11,154 @@ #include "zfcp_def.h" -extern struct zfcp_data zfcp_data; - -/* zfcp_sysfs.c */ -extern struct attribute_group zfcp_sysfs_unit_attrs; -extern struct attribute_group zfcp_sysfs_adapter_attrs; -extern struct attribute_group zfcp_sysfs_ns_port_attrs; -extern struct attribute_group zfcp_sysfs_port_attrs; -extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; -extern struct device_attribute *zfcp_sysfs_shost_attrs[]; - -/**************************** CONFIGURATION *********************************/ -extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, fcp_lun_t); -extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, wwn_t); -extern int zfcp_adapter_enqueue(struct ccw_device *); -extern int zfcp_adapter_debug_register(struct zfcp_adapter *); -extern void zfcp_adapter_dequeue(struct zfcp_adapter *); -extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *); -extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, - u32, u32); -extern void zfcp_port_dequeue(struct zfcp_port *); +/* zfcp_aux.c */ +extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, + fcp_lun_t); +extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, + wwn_t); +extern int zfcp_adapter_enqueue(struct ccw_device *); +extern void zfcp_adapter_dequeue(struct zfcp_adapter *); +extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, u32, + u32); +extern void zfcp_port_dequeue(struct zfcp_port *); extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t); -extern void zfcp_unit_dequeue(struct zfcp_unit *); -extern int zfcp_scan_ports(struct zfcp_adapter *); -extern void _zfcp_scan_ports_later(struct work_struct *work); - -/******************************* S/390 IO ************************************/ -extern int zfcp_ccw_register(void); - -extern int zfcp_qdio_allocate(struct zfcp_adapter *); -extern void zfcp_qdio_free(struct zfcp_adapter *); -extern int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req); - -extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req - (struct zfcp_fsf_req *); -extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_curr - (struct zfcp_fsf_req *); -extern int zfcp_qdio_sbals_from_sg - (struct zfcp_fsf_req *, unsigned long, struct scatterlist *, int); -extern int zfcp_qdio_open(struct zfcp_adapter *adapter); -extern void zfcp_qdio_close(struct zfcp_adapter *adapter); -/******************************** FSF ****************************************/ -extern int zfcp_fsf_open_port(struct zfcp_erp_action *); -extern int zfcp_fsf_close_port(struct zfcp_erp_action *); -extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); - -extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); -extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); - -extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); -extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *, - struct fsf_qtcb_bottom_config *); -extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); -extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *, - struct fsf_qtcb_bottom_port *); -extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, - struct zfcp_fsf_cfdc *fsf_cfdc); -extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); -extern int zfcp_fsf_status_read(struct zfcp_adapter *); -extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); -extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, - struct zfcp_erp_action *); -extern int zfcp_fsf_send_els(struct zfcp_send_els *); -extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *, - struct zfcp_unit *, - struct scsi_cmnd *, int, int); -extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *); -extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); -extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *, - struct zfcp_unit *, u8, - int); -extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command( - unsigned long, struct zfcp_adapter *, struct zfcp_unit *, int); +extern void zfcp_unit_dequeue(struct zfcp_unit *); +extern int zfcp_reqlist_isempty(struct zfcp_adapter *); +extern void zfcp_sg_free_table(struct scatterlist *, int); +extern int zfcp_sg_setup_table(struct scatterlist *, int); -/******************************* FC/FCP **************************************/ -extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); -extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *); -extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); -extern void zfcp_test_link(struct zfcp_port *); +/* zfcp_ccw.c */ +extern int zfcp_ccw_register(void); -/******************************* SCSI ****************************************/ -extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); -extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); -extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t); -extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); +/* zfcp_cfdc.c */ +extern struct miscdevice zfcp_cfdc_misc; -extern struct fc_function_template zfcp_transport_functions; +/* zfcp_dbf.c */ +extern int zfcp_adapter_debug_register(struct zfcp_adapter *); +extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *); +extern void zfcp_rec_dbf_event_thread(u8, struct zfcp_adapter *); +extern void zfcp_rec_dbf_event_thread_lock(u8, struct zfcp_adapter *); +extern void zfcp_rec_dbf_event_adapter(u8, void *, struct zfcp_adapter *); +extern void zfcp_rec_dbf_event_port(u8, void *, struct zfcp_port *); +extern void zfcp_rec_dbf_event_unit(u8, void *, struct zfcp_unit *); +extern void zfcp_rec_dbf_event_trigger(u8, void *, u8, u8, void *, + struct zfcp_adapter *, + struct zfcp_port *, struct zfcp_unit *); +extern void zfcp_rec_dbf_event_action(u8, struct zfcp_erp_action *); +extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *); +extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, + struct fsf_status_read_buffer *); +extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, + unsigned int, unsigned int, unsigned int, + int, int); +extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *); +extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *); +extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *); +extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); +extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); +extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, + struct scsi_cmnd *, + struct zfcp_fsf_req *); +extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, + struct scsi_cmnd *, struct zfcp_fsf_req *, + unsigned long); +extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, + struct scsi_cmnd *); -/******************************** ERP ****************************************/ +/* zfcp_erp.c */ extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *, u32, int); extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *); extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *); extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *); - extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32, int); extern int zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *); extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *); extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *); extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *); - extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32, int); extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *); extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *); extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *); - extern int zfcp_erp_thread_setup(struct zfcp_adapter *); extern void zfcp_erp_thread_kill(struct zfcp_adapter *); extern void zfcp_erp_wait(struct zfcp_adapter *); extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); - -extern void zfcp_erp_port_boxed(struct zfcp_port *, u8 id, void *ref); -extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8 id, void *ref); -extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8 id, void *ref); -extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8 id, void *ref); +extern void zfcp_erp_port_boxed(struct zfcp_port *, u8, void *); +extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8, void *); +extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8, void *); +extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *); extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); extern void zfcp_erp_timeout_handler(unsigned long); -/******************************** AUX ****************************************/ -extern void zfcp_sg_free_table(struct scatterlist *sg, int count); -extern int zfcp_sg_setup_table(struct scatterlist *sg, int count); -extern void zfcp_rec_dbf_event_thread(u8 id, struct zfcp_adapter *adapter); -extern void zfcp_rec_dbf_event_thread_lock(u8 id, struct zfcp_adapter *adapter); -extern void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *); -extern void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port); -extern void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit); -extern void zfcp_rec_dbf_event_trigger(u8 id, void *ref, u8 want, u8 need, - void *action, struct zfcp_adapter *, - struct zfcp_port *, struct zfcp_unit *); -extern void zfcp_rec_dbf_event_action(u8 id, struct zfcp_erp_action *); - -extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *); -extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, - struct fsf_status_read_buffer *); -extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, - unsigned int, unsigned int, unsigned int, - int, int); -extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *); -extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *); -extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *); -extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); -extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); +/* zfcp_fc.c */ +extern int zfcp_scan_ports(struct zfcp_adapter *); +extern void _zfcp_scan_ports_later(struct work_struct *); +extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); +extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *); +extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); +extern void zfcp_test_link(struct zfcp_port *); + +/* zfcp_fsf.c */ +extern int zfcp_fsf_open_port(struct zfcp_erp_action *); +extern int zfcp_fsf_close_port(struct zfcp_erp_action *); +extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); +extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); +extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); +extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); +extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *, + struct fsf_qtcb_bottom_config *); +extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); +extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *, + struct fsf_qtcb_bottom_port *); +extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *, + struct zfcp_fsf_cfdc *); +extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); +extern int zfcp_fsf_status_read(struct zfcp_adapter *); +extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); +extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, + struct zfcp_erp_action *); +extern int zfcp_fsf_send_els(struct zfcp_send_els *); +extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *, + struct zfcp_unit *, + struct scsi_cmnd *, int, int); +extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *); +extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); +extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *, + struct zfcp_unit *, u8, int); +extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long, + struct zfcp_adapter *, + struct zfcp_unit *, int); -extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, - struct scsi_cmnd *, - struct zfcp_fsf_req *); -extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, - struct scsi_cmnd *, struct zfcp_fsf_req *, - unsigned long); -extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, - struct scsi_cmnd *); -extern int zfcp_reqlist_isempty(struct zfcp_adapter *); +/* zfcp_qdio.c */ +extern int zfcp_qdio_allocate(struct zfcp_adapter *); +extern void zfcp_qdio_free(struct zfcp_adapter *); +extern int zfcp_qdio_send(struct zfcp_fsf_req *); +extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req( + struct zfcp_fsf_req *); +extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_curr( + struct zfcp_fsf_req *); +extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long, + struct scatterlist *, int); +extern int zfcp_qdio_open(struct zfcp_adapter *); +extern void zfcp_qdio_close(struct zfcp_adapter *); + +/* zfcp_scsi.c */ +extern struct zfcp_data zfcp_data; +extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); +extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); +extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t); +extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); +extern struct fc_function_template zfcp_transport_functions; -extern struct miscdevice zfcp_cfdc_misc; +/* zfcp_sysfs.c */ +extern struct attribute_group zfcp_sysfs_unit_attrs; +extern struct attribute_group zfcp_sysfs_adapter_attrs; +extern struct attribute_group zfcp_sysfs_ns_port_attrs; +extern struct attribute_group zfcp_sysfs_port_attrs; +extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; +extern struct device_attribute *zfcp_sysfs_shost_attrs[]; #endif /* ZFCP_EXT_H */ -- cgit v0.10.2 From 2476b4d0426e1d6d4a42b2f7ae08f668b2cfe510 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 3 Jul 2008 11:31:55 -0500 Subject: [SCSI] fix locking in host use of blk_plug_device() scsi_lib.c:scsi_host_queue_ready() plugs the device with incorrect locking. It should actually have the queue lock held, but it's holding the host lock. Fix this by eliminating the call. The host ready has no need to plug the queue because if it returns 0 in scsi_request_function control transfers to not_ready which acquires the queue lock and plugs the device if its at zero depth. Reported-by: Elias Oltmanns Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index aa8d5de..0451903 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1328,7 +1328,6 @@ static inline int scsi_host_queue_ready(struct request_queue *q, printk("scsi%d unblocking host at zero depth\n", shost->host_no)); } else { - blk_plug_device(q); return 0; } } -- cgit v0.10.2 From 453cd0f3ff3bf25d86c96e62d271ba238f06d5ff Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 3 Jul 2008 23:47:33 -0700 Subject: [SCSI] make struct scsi_{host,target}_type static Make the needlessly global struct scsi_{host,target}_type static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: James Bottomley diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 3690360..497ca68 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -290,7 +290,7 @@ static void scsi_host_dev_release(struct device *dev) kfree(shost); } -struct device_type scsi_host_type = { +static struct device_type scsi_host_type = { .name = "scsi_host", .release = scsi_host_dev_release, }; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a00eee6..196fe3a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -346,7 +346,7 @@ static void scsi_target_dev_release(struct device *dev) put_device(parent); } -struct device_type scsi_target_type = { +static struct device_type scsi_target_type = { .name = "scsi_target", .release = scsi_target_dev_release, }; -- cgit v0.10.2 From 02a1e3ce7df624ba91e8ff06e172f448746ad76a Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 6 Jul 2008 17:01:34 +0400 Subject: [SCSI] scsi_cmnd.h: remove double inclusion of linux/blkdev.h Signed-off-by: Alexander Beregalov Signed-off-by: James Bottomley diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 3e46dfa..66c9448 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -7,7 +7,6 @@ #include #include #include -#include struct Scsi_Host; struct scsi_device; -- cgit v0.10.2 From d7f305e9a08040649b0800245e67708df58cdb55 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2008 10:50:25 +1000 Subject: [SCSI] sym53c8xx: Fix bogus sym_que_entry re-implementation of container_of The sym53c8xx driver, for some reason, seems to mostly re-implement linux/list.h with added bogosity. The main one is it's implementation of sym_que_entry which spits warnings with recent gcc's on some 64 bits architectures. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: James Bottomley diff --git a/drivers/scsi/sym53c8xx_2/sym_misc.h b/drivers/scsi/sym53c8xx_2/sym_misc.h index 0433d5d..4305371 100644 --- a/drivers/scsi/sym53c8xx_2/sym_misc.h +++ b/drivers/scsi/sym53c8xx_2/sym_misc.h @@ -121,9 +121,7 @@ static __inline void sym_que_move(struct sym_quehead *orig, } } -#define sym_que_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned int)(&((type *)0)->member))) - +#define sym_que_entry(ptr, type, member) container_of(ptr, type, member) #define sym_insque(new, pos) __sym_que_add(new, pos, (pos)->flink) -- cgit v0.10.2 From 6eb9d32298290b956693fd85c815b817d39a9505 Mon Sep 17 00:00:00 2001 From: Andre Schwarz Date: Thu, 10 Jul 2008 11:53:16 +0200 Subject: powerpc/mpc5200: PCI write combine timer On MPC5200 the PCI target control register (PCITCR) @ MBAR + 0xD6C is initialized with only bit 7 (Latrule disable) set. The 8-Bit write combine timer (Bits 24..31) should be also set to a reasonable value _greater zero_ (0x08 = default) since setting it to 0x00 leads to _very poor_ performance as a PCI target since external burst won't be possible at all. Setting the WCT to 0x08 (cache-line size) leads to good overall perfomance. Signed-off-by: Andre Schwarz Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index e3428dd..5a382bb 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -63,6 +63,7 @@ #define MPC52xx_PCI_TCR_P 0x01000000 #define MPC52xx_PCI_TCR_LD 0x00010000 +#define MPC52xx_PCI_TCR_WCT8 0x00000008 #define MPC52xx_PCI_TBATR_DISABLE 0x0 #define MPC52xx_PCI_TBATR_ENABLE 0x1 @@ -313,7 +314,7 @@ mpc52xx_pci_setup(struct pci_controller *hose, out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM ); - out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD); + out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8); tmp = in_be32(&pci_regs->gscr); #if 0 -- cgit v0.10.2 From 0d1cde235874b00905bce23f659690d060ebf475 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 30 Jun 2008 19:01:26 -0400 Subject: powerpc/i2c: Convert i2c-mpc into an of_platform driver Convert i2c-mpc to an of_platform driver. Utilize the code in drivers/of-i2c.c to make i2c modules dynamically loadable by the device tree. Signed-off-by: Jon Smirl Signed-off-by: Grant Likely diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index ca54563..ebcec73 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -414,139 +414,6 @@ err: arch_initcall(gfar_of_init); -#ifdef CONFIG_I2C_BOARDINFO -#include -struct i2c_driver_device { - char *of_device; - char *i2c_type; -}; - -static struct i2c_driver_device i2c_devices[] __initdata = { - {"ricoh,rs5c372a", "rs5c372a"}, - {"ricoh,rs5c372b", "rs5c372b"}, - {"ricoh,rv5c386", "rv5c386"}, - {"ricoh,rv5c387a", "rv5c387a"}, - {"dallas,ds1307", "ds1307"}, - {"dallas,ds1337", "ds1337"}, - {"dallas,ds1338", "ds1338"}, - {"dallas,ds1339", "ds1339"}, - {"dallas,ds1340", "ds1340"}, - {"stm,m41t00", "m41t00"}, - {"dallas,ds1374", "ds1374"}, - {"cirrus,cs4270", "cs4270"}, -}; - -static int __init of_find_i2c_driver(struct device_node *node, - struct i2c_board_info *info) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { - if (!of_device_is_compatible(node, i2c_devices[i].of_device)) - continue; - if (strlcpy(info->type, i2c_devices[i].i2c_type, - I2C_NAME_SIZE) >= I2C_NAME_SIZE) - return -ENOMEM; - return 0; - } - - pr_warning("fsl_soc.c: unrecognized i2c node %s\n", - (const char *) of_get_property(node, "compatible", NULL)); - - return -ENODEV; -} - -static void __init of_register_i2c_devices(struct device_node *adap_node, - int bus_num) -{ - struct device_node *node = NULL; - - while ((node = of_get_next_child(adap_node, node))) { - struct i2c_board_info info = {}; - const u32 *addr; - int len; - - addr = of_get_property(node, "reg", &len); - if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { - printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n"); - continue; - } - - info.irq = irq_of_parse_and_map(node, 0); - if (info.irq == NO_IRQ) - info.irq = -1; - - if (of_find_i2c_driver(node, &info) < 0) - continue; - - info.addr = *addr; - - i2c_register_board_info(bus_num, &info, 1); - } -} - -static int __init fsl_i2c_of_init(void) -{ - struct device_node *np; - unsigned int i = 0; - struct platform_device *i2c_dev; - int ret; - - for_each_compatible_node(np, NULL, "fsl-i2c") { - struct resource r[2]; - struct fsl_i2c_platform_data i2c_data; - const unsigned char *flags = NULL; - int idx; - const u32 *iprop; - - memset(&r, 0, sizeof(r)); - memset(&i2c_data, 0, sizeof(i2c_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - - of_irq_to_resource(np, 0, &r[1]); - - iprop = of_get_property(np, "cell-index", NULL); - idx = iprop ? *iprop : i; - - i2c_dev = platform_device_register_simple("fsl-i2c", idx, r, 2); - if (IS_ERR(i2c_dev)) { - ret = PTR_ERR(i2c_dev); - goto err; - } - - i2c_data.device_flags = 0; - flags = of_get_property(np, "dfsrr", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - - flags = of_get_property(np, "fsl5200-clocking", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; - - ret = - platform_device_add_data(i2c_dev, &i2c_data, - sizeof(struct - fsl_i2c_platform_data)); - if (ret) - goto unreg; - - of_register_i2c_devices(np, idx); - i++; - } - - return 0; - -unreg: - platform_device_unregister(i2c_dev); -err: - return ret; -} - -arch_initcall(fsl_i2c_of_init); -#endif #ifdef CONFIG_PPC_83xx static int __init mpc83xx_wdt_init(void) diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a076129..4fdfb62d 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include @@ -25,13 +26,13 @@ #include #include -#define MPC_I2C_ADDR 0x00 +#define DRV_NAME "mpc-i2c" + #define MPC_I2C_FDR 0x04 #define MPC_I2C_CR 0x08 #define MPC_I2C_SR 0x0c #define MPC_I2C_DR 0x10 #define MPC_I2C_DFSRR 0x14 -#define MPC_I2C_REGION 0x20 #define CCR_MEN 0x80 #define CCR_MIEN 0x40 @@ -315,102 +316,117 @@ static struct i2c_adapter mpc_ops = { .timeout = 1, }; -static int fsl_i2c_probe(struct platform_device *pdev) +static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match) { int result = 0; struct mpc_i2c *i2c; - struct fsl_i2c_platform_data *pdata; - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; - i2c->irq = platform_get_irq(pdev, 0); - if (i2c->irq < 0) - i2c->irq = NO_IRQ; /* Use polling */ + if (of_get_property(op->node, "dfsrr", NULL)) + i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - i2c->flags = pdata->device_flags; - init_waitqueue_head(&i2c->queue); + if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") || + of_device_is_compatible(op->node, "mpc5200-i2c")) + i2c->flags |= FSL_I2C_DEV_CLOCK_5200; - i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION); + init_waitqueue_head(&i2c->queue); + i2c->base = of_iomap(op->node, 0); if (!i2c->base) { printk(KERN_ERR "i2c-mpc - failed to map controller\n"); result = -ENOMEM; goto fail_map; } - if (i2c->irq != NO_IRQ) - if ((result = request_irq(i2c->irq, mpc_i2c_isr, - IRQF_SHARED, "i2c-mpc", i2c)) < 0) { - printk(KERN_ERR - "i2c-mpc - failed to attach interrupt\n"); - goto fail_irq; + i2c->irq = irq_of_parse_and_map(op->node, 0); + if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ + result = request_irq(i2c->irq, mpc_i2c_isr, + IRQF_SHARED, "i2c-mpc", i2c); + if (result < 0) { + printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n"); + goto fail_request; } - + } + mpc_i2c_setclock(i2c); - platform_set_drvdata(pdev, i2c); + + dev_set_drvdata(&op->dev, i2c); i2c->adap = mpc_ops; - i2c->adap.nr = pdev->id; i2c_set_adapdata(&i2c->adap, i2c); - i2c->adap.dev.parent = &pdev->dev; - if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) { + i2c->adap.dev.parent = &op->dev; + + result = i2c_add_adapter(&i2c->adap); + if (result < 0) { printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); goto fail_add; } + of_register_i2c_devices(&i2c->adap, op->node); return result; - fail_add: - if (i2c->irq != NO_IRQ) - free_irq(i2c->irq, i2c); - fail_irq: - iounmap(i2c->base); - fail_map: + fail_add: + dev_set_drvdata(&op->dev, NULL); + free_irq(i2c->irq, i2c); + fail_request: + irq_dispose_mapping(i2c->irq); + iounmap(i2c->base); + fail_map: kfree(i2c); return result; }; -static int fsl_i2c_remove(struct platform_device *pdev) +static int __devexit fsl_i2c_remove(struct of_device *op) { - struct mpc_i2c *i2c = platform_get_drvdata(pdev); + struct mpc_i2c *i2c = dev_get_drvdata(&op->dev); i2c_del_adapter(&i2c->adap); - platform_set_drvdata(pdev, NULL); + dev_set_drvdata(&op->dev, NULL); if (i2c->irq != NO_IRQ) free_irq(i2c->irq, i2c); + irq_dispose_mapping(i2c->irq); iounmap(i2c->base); kfree(i2c); return 0; }; -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:fsl-i2c"); +static const struct of_device_id mpc_i2c_of_match[] = { + {.compatible = "fsl-i2c",}, + {}, +}; +MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); + /* Structure for a device driver */ -static struct platform_driver fsl_i2c_driver = { - .probe = fsl_i2c_probe, - .remove = fsl_i2c_remove, - .driver = { - .owner = THIS_MODULE, - .name = "fsl-i2c", +static struct of_platform_driver mpc_i2c_driver = { + .match_table = mpc_i2c_of_match, + .probe = fsl_i2c_probe, + .remove = __devexit_p(fsl_i2c_remove), + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, }, }; static int __init fsl_i2c_init(void) { - return platform_driver_register(&fsl_i2c_driver); + int rv; + + rv = of_register_platform_driver(&mpc_i2c_driver); + if (rv) + printk(KERN_ERR DRV_NAME + " of_register_platform_driver failed (%i)\n", rv); + return rv; } static void __exit fsl_i2c_exit(void) { - platform_driver_unregister(&fsl_i2c_driver); + of_unregister_platform_driver(&mpc_i2c_driver); } module_init(fsl_i2c_init); -- cgit v0.10.2 From f40987b64d0f4d40b006ce09e37161b57c1e970b Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 8 Jul 2008 06:38:24 -0400 Subject: OpenFirmware: Include from of_i2c.c. drivers/of/of_i2c.c should include for the prototype for of_register_i2c_devices(). Signed-off-by: Robert P. J. Day Acked-by: Jean Delvare Acked-by: Jochen Friedrich Acked-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index b2ccdcb..5c015d3 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -13,6 +13,7 @@ #include #include +#include #include struct i2c_driver_device { -- cgit v0.10.2 From b0852cb8841f35b124f4344d92abd8c0a6b54fcf Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 2 Jul 2008 11:56:40 +0200 Subject: powerpc/mpc5200: add missing MSCAN FDT nodes for TQM52xx This patch adds the still missing FDT nodes for the MSCAN devices for the TQM52xx modules. Signed-off-by: Wolfgang Grandegger Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts index 773a68e..3008bf8 100644 --- a/arch/powerpc/boot/dts/tqm5200.dts +++ b/arch/powerpc/boot/dts/tqm5200.dts @@ -70,6 +70,20 @@ fsl,has-wdt; }; + can@900 { + compatible = "fsl,mpc5200-mscan"; + interrupts = <2 17 0>; + interrupt-parent = <&mpc5200_pic>; + reg = <0x900 0x80>; + }; + + can@980 { + compatible = "fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + interrupt-parent = <&mpc5200_pic>; + reg = <0x980 0x80>; + }; + gpio@b00 { compatible = "fsl,mpc5200-gpio"; reg = <0xb00 0x40>; -- cgit v0.10.2 From e6a9192d066b30353b78ce1647070c0c171dd9a7 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 May 2008 16:16:27 +1000 Subject: powerpc/pata_mpc52xx: use linux/of_platform.h instead of asm Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index bc79df6..a9e8273 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -16,10 +16,10 @@ #include #include #include +#include #include #include -#include #include -- cgit v0.10.2 From 76ef7dd030823518506d65237a12666fc3f5a0d4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 May 2008 16:35:47 +1000 Subject: powerpc/mpc52xx_psc_spi: use linux/of_platform.h instead of asm Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 681d623..604e5f0 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -17,7 +17,7 @@ #include #if defined(CONFIG_PPC_MERGE) -#include +#include #else #include #endif -- cgit v0.10.2 From 75195dabce797f49b7d96d272e4e9330873e4340 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 23 May 2008 16:42:56 +1000 Subject: powerpc/mpc5200_wdt: use linux/of_platform.h instead of asm Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c index 80a91d4..77c1c2a 100644 --- a/drivers/watchdog/mpc5200_wdt.c +++ b/drivers/watchdog/mpc5200_wdt.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include -- cgit v0.10.2 From 7ba6d6dc8d58c49cff0533819195b44fb35d6ece Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 1 Jul 2008 21:38:16 -0600 Subject: powerpc/mpc5200: Add PSC helpers for bestcomm engine Simplify the interface for setting up bestcomm DMA to PSCs by adding some helper functions. The helper function sets the correct values for the initator and ipr values in PSC DMA tasks based on the PSC number. Signed-off-by: Grant Likely diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.c b/arch/powerpc/sysdev/bestcomm/gen_bd.c index 8d33eaf..a3a134c 100644 --- a/arch/powerpc/sysdev/bestcomm/gen_bd.c +++ b/arch/powerpc/sysdev/bestcomm/gen_bd.c @@ -20,6 +20,7 @@ #include #include +#include #include "bestcomm.h" #include "bestcomm_priv.h" @@ -253,6 +254,100 @@ bcom_gen_bd_tx_release(struct bcom_task *tsk) } EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release); +/* --------------------------------------------------------------------- + * PSC support code + */ + +/** + * bcom_psc_parameters - Bestcomm initialization value table for PSC devices + * + * This structure is only used internally. It is a lookup table for PSC + * specific parameters to bestcomm tasks. + */ +static struct bcom_psc_params { + int rx_initiator; + int rx_ipr; + int tx_initiator; + int tx_ipr; +} bcom_psc_params[] = { + [0] = { + .rx_initiator = BCOM_INITIATOR_PSC1_RX, + .rx_ipr = BCOM_IPR_PSC1_RX, + .tx_initiator = BCOM_INITIATOR_PSC1_TX, + .tx_ipr = BCOM_IPR_PSC1_TX, + }, + [1] = { + .rx_initiator = BCOM_INITIATOR_PSC2_RX, + .rx_ipr = BCOM_IPR_PSC2_RX, + .tx_initiator = BCOM_INITIATOR_PSC2_TX, + .tx_ipr = BCOM_IPR_PSC2_TX, + }, + [2] = { + .rx_initiator = BCOM_INITIATOR_PSC3_RX, + .rx_ipr = BCOM_IPR_PSC3_RX, + .tx_initiator = BCOM_INITIATOR_PSC3_TX, + .tx_ipr = BCOM_IPR_PSC3_TX, + }, + [3] = { + .rx_initiator = BCOM_INITIATOR_PSC4_RX, + .rx_ipr = BCOM_IPR_PSC4_RX, + .tx_initiator = BCOM_INITIATOR_PSC4_TX, + .tx_ipr = BCOM_IPR_PSC4_TX, + }, + [4] = { + .rx_initiator = BCOM_INITIATOR_PSC5_RX, + .rx_ipr = BCOM_IPR_PSC5_RX, + .tx_initiator = BCOM_INITIATOR_PSC5_TX, + .tx_ipr = BCOM_IPR_PSC5_TX, + }, + [5] = { + .rx_initiator = BCOM_INITIATOR_PSC6_RX, + .rx_ipr = BCOM_IPR_PSC6_RX, + .tx_initiator = BCOM_INITIATOR_PSC6_TX, + .tx_ipr = BCOM_IPR_PSC6_TX, + }, +}; + +/** + * bcom_psc_gen_bd_rx_init - Allocate a receive bcom_task for a PSC port + * @psc_num: Number of the PSC to allocate a task for + * @queue_len: number of buffer descriptors to allocate for the task + * @fifo: physical address of FIFO register + * @maxbufsize: Maximum receive data size in bytes. + * + * Allocate a bestcomm task structure for receiving data from a PSC. + */ +struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len, + phys_addr_t fifo, int maxbufsize) +{ + if (psc_num >= MPC52xx_PSC_MAXNUM) + return NULL; + + return bcom_gen_bd_rx_init(queue_len, fifo, + bcom_psc_params[psc_num].rx_initiator, + bcom_psc_params[psc_num].rx_ipr, + maxbufsize); +} +EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init); + +/** + * bcom_psc_gen_bd_tx_init - Allocate a transmit bcom_task for a PSC port + * @psc_num: Number of the PSC to allocate a task for + * @queue_len: number of buffer descriptors to allocate for the task + * @fifo: physical address of FIFO register + * + * Allocate a bestcomm task structure for transmitting data to a PSC. + */ +struct bcom_task * +bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len, phys_addr_t fifo) +{ + struct psc; + return bcom_gen_bd_tx_init(queue_len, fifo, + bcom_psc_params[psc_num].tx_initiator, + bcom_psc_params[psc_num].tx_ipr); +} +EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_tx_init); + MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver"); MODULE_AUTHOR("Jeff Gibbons "); diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.h b/arch/powerpc/sysdev/bestcomm/gen_bd.h index 5b6fa80..de47260 100644 --- a/arch/powerpc/sysdev/bestcomm/gen_bd.h +++ b/arch/powerpc/sysdev/bestcomm/gen_bd.h @@ -44,5 +44,10 @@ extern void bcom_gen_bd_tx_release(struct bcom_task *tsk); +/* PSC support utility wrappers */ +struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len, + phys_addr_t fifo, int maxbufsize); +struct bcom_task * bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len, + phys_addr_t fifo); #endif /* __BESTCOMM_GEN_BD_H__ */ -- cgit v0.10.2 From 08b6c06de5d3f37295f6dbf7010fb45ae5ee14a7 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 11 Jul 2008 16:17:58 -0600 Subject: powerpc/mpc5200: fix compile warnings in bestcomm driver Fix for the following compiler warnings: CC arch/powerpc/sysdev/bestcomm/bestcomm.o arch/powerpc/sysdev/bestcomm/bestcomm.c: In function 'mpc52xx_bcom_probe': arch/powerpc/sysdev/bestcomm/bestcomm.c:446: warning: format '%08lx' expects type 'long unsigned int', but argument 2 has type 'phys_addr_t' CC arch/powerpc/sysdev/bestcomm/sram.o arch/powerpc/sysdev/bestcomm/sram.c: In function 'bcom_sram_init': arch/powerpc/sysdev/bestcomm/sram.c:89: warning: format '%08lx' expects type 'long unsigned int', but argument 3 has type 'phys_addr_t' Signed-off-by: Grant Likely diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 64ec7d6..446c9ea 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -443,7 +443,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) /* Done ! */ printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n", - bcom_eng->regs_base); + (long)bcom_eng->regs_base); return 0; diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c index 9978438..5d74ef7 100644 --- a/arch/powerpc/sysdev/bestcomm/sram.c +++ b/arch/powerpc/sysdev/bestcomm/sram.c @@ -86,7 +86,7 @@ int bcom_sram_init(struct device_node *sram_node, char *owner) if (!bcom_sram->base_virt) { printk(KERN_ERR "%s: bcom_sram_init: " "Map error SRAM zone 0x%08lx (0x%0x)!\n", - owner, bcom_sram->base_phys, bcom_sram->size ); + owner, (long)bcom_sram->base_phys, bcom_sram->size ); rv = -ENOMEM; goto error_release; } -- cgit v0.10.2 From 4df64c3e58d28ffc5c61bdbdd733c5d0303b9f3c Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:01 -0600 Subject: powerpc/mpc5121: Update device tree for MPC5121ADS evaluation board Current device tree is only bare bones. This patch adds nodes to make it a complete tree for the MPC5121ads. Added nodes include: mbx - opengl coprocessor nfc - nand flash controller cpld-pic - on board cpld rtc clock - clock control pmc - power management control gpio mscan - can module i2c axe - audio coprocessor display - display interface unit mdio ethernet usb ioctl - pin config pata ac97 - PSC configured as AC97 pscfifo - psc fifo configuration dma pci Fix typo in header changing MDS to ADS. Add a compatible property of the form "fsl,mpc5121-..." to nodes missing one. Changed localbus compatible to fsl,mpc5121-localbus, this does not break anything because the only code that uses it finds it via the node name, not compatible. Signed-off-by: John Rigby Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts index 94ad7b2..1f9036c 100644 --- a/arch/powerpc/boot/dts/mpc5121ads.dts +++ b/arch/powerpc/boot/dts/mpc5121ads.dts @@ -1,7 +1,7 @@ /* - * MPC5121E MDS Device Tree Source + * MPC5121E ADS Device Tree Source * - * Copyright 2007 Freescale Semiconductor Inc. + * Copyright 2007,2008 Freescale Semiconductor 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 @@ -17,6 +17,10 @@ #address-cells = <1>; #size-cells = <1>; + aliases { + pci = &pci; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -39,8 +43,41 @@ reg = <0x00000000 0x10000000>; // 256MB at 0 }; + mbx@20000000 { + compatible = "fsl,mpc5121-mbx"; + reg = <0x20000000 0x4000>; + interrupts = <66 0x8>; + interrupt-parent = < &ipic >; + }; + + sram@30000000 { + compatible = "fsl,mpc5121-sram"; + reg = <0x30000000 0x20000>; // 128K at 0x30000000 + }; + + nfc@40000000 { + compatible = "fsl,mpc5121-nfc"; + reg = <0x40000000 0x100000>; // 1M at 0x40000000 + interrupts = <6 8>; + interrupt-parent = < &ipic >; + #address-cells = <1>; + #size-cells = <1>; + bank-width = <1>; + // ADS has two Hynix 512MB Nand flash chips in a single + // stacked package . + chips = <2>; + nand0@0 { + label = "nand0"; + reg = <0x00000000 0x02000000>; // first 32 MB of chip 0 + }; + nand1@20000000 { + label = "nand1"; + reg = <0x20000000 0x02000000>; // first 32 MB of chip 1 + }; + }; + localbus@80000020 { - compatible = "fsl,mpc5121ads-localbus"; + compatible = "fsl,mpc5121-localbus"; #address-cells = <2>; #size-cells = <1>; reg = <0x80000020 0x40>; @@ -51,14 +88,51 @@ flash@0,0 { compatible = "cfi-flash"; reg = <0 0x0 0x4000000>; + #address-cells = <1>; + #size-cells = <1>; bank-width = <4>; - device-width = <1>; + device-width = <2>; + protected@0 { + label = "protected"; + reg = <0x00000000 0x00040000>; // first sector is protected + read-only; + }; + filesystem@40000 { + label = "filesystem"; + reg = <0x00040000 0x03c00000>; // 60M for filesystem + }; + kernel@3c40000 { + label = "kernel"; + reg = <0x03c40000 0x00280000>; // 2.5M for kernel + }; + device-tree@3ec0000 { + label = "device-tree"; + reg = <0x03ec0000 0x00040000>; // one sector for device tree + }; + u-boot@3f00000 { + label = "u-boot"; + reg = <0x03f00000 0x00100000>; // 1M for u-boot + read-only; + }; }; board-control@2,0 { compatible = "fsl,mpc5121ads-cpld"; reg = <0x2 0x0 0x8000>; }; + + cpld_pic: pic@2,a { + compatible = "fsl,mpc5121ads-cpld-pic"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2 0xa 0x5>; + interrupt-parent = < &ipic >; + // irq routing + // all irqs but touch screen are routed to irq0 (ipic 48) + // touch screen is statically routed to irq1 (ipic 17) + // so don't use it here + interrupts = <48 0x8>; + }; }; soc@80000000 { @@ -85,38 +159,252 @@ reg = <0xc00 0x100>; }; - // 512x PSCs are not 52xx PSCs compatible + rtc@a00 { // Real time clock + compatible = "fsl,mpc5121-rtc"; + reg = <0xa00 0x100>; + interrupts = <79 0x8 80 0x8>; + interrupt-parent = < &ipic >; + }; + + clock@f00 { // Clock control + compatible = "fsl,mpc5121-clock"; + reg = <0xf00 0x100>; + }; + + pmc@1000{ //Power Management Controller + compatible = "fsl,mpc5121-pmc"; + reg = <0x1000 0x100>; + interrupts = <83 0x2>; + interrupt-parent = < &ipic >; + }; + + gpio@1100 { + compatible = "fsl,mpc5121-gpio"; + reg = <0x1100 0x100>; + interrupts = <78 0x8>; + interrupt-parent = < &ipic >; + }; + + mscan@1300 { + compatible = "fsl,mpc5121-mscan"; + cell-index = <0>; + interrupts = <12 0x8>; + interrupt-parent = < &ipic >; + reg = <0x1300 0x80>; + }; + + mscan@1380 { + compatible = "fsl,mpc5121-mscan"; + cell-index = <1>; + interrupts = <13 0x8>; + interrupt-parent = < &ipic >; + reg = <0x1380 0x80>; + }; + + i2c@1700 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5121-i2c", "fsl-i2c"; + cell-index = <0>; + reg = <0x1700 0x20>; + interrupts = <9 0x8>; + interrupt-parent = < &ipic >; + fsl5200-clocking; + }; + + i2c@1720 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5121-i2c", "fsl-i2c"; + cell-index = <1>; + reg = <0x1720 0x20>; + interrupts = <10 0x8>; + interrupt-parent = < &ipic >; + fsl5200-clocking; + }; + + i2c@1740 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5121-i2c", "fsl-i2c"; + cell-index = <2>; + reg = <0x1740 0x20>; + interrupts = <11 0x8>; + interrupt-parent = < &ipic >; + fsl5200-clocking; + }; + + i2ccontrol@1760 { + compatible = "fsl,mpc5121-i2c-ctrl"; + reg = <0x1760 0x8>; + }; + + axe@2000 { + compatible = "fsl,mpc5121-axe"; + reg = <0x2000 0x100>; + interrupts = <42 0x8>; + interrupt-parent = < &ipic >; + }; + + display@2100 { + compatible = "fsl,mpc5121-diu", "fsl-diu"; + reg = <0x2100 0x100>; + interrupts = <64 0x8>; + interrupt-parent = < &ipic >; + }; + + mdio@2800 { + compatible = "fsl,mpc5121-fec-mdio"; + reg = <0x2800 0x800>; + #address-cells = <1>; + #size-cells = <0>; + phy: ethernet-phy@0 { + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + ethernet@2800 { + device_type = "network"; + compatible = "fsl,mpc5121-fec"; + reg = <0x2800 0x800>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <4 0x8>; + interrupt-parent = < &ipic >; + phy-handle = < &phy >; + fsl,align-tx-packets = <4>; + }; + + // 5121e has two dr usb modules + // mpc5121_ads only uses USB0 + + // USB1 using external ULPI PHY + //usb@3000 { + // compatible = "fsl,mpc5121-usb2-dr", "fsl-usb2-dr"; + // reg = <0x3000 0x1000>; + // #address-cells = <1>; + // #size-cells = <0>; + // interrupt-parent = < &ipic >; + // interrupts = <43 0x8>; + // dr_mode = "otg"; + // phy_type = "ulpi"; + // port1; + //}; + + // USB0 using internal UTMI PHY + usb@4000 { + compatible = "fsl,mpc5121-usb2-dr", "fsl-usb2-dr"; + reg = <0x4000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = < &ipic >; + interrupts = <44 0x8>; + dr_mode = "otg"; + phy_type = "utmi_wide"; + port0; + }; + + // IO control + ioctl@a000 { + compatible = "fsl,mpc5121-ioctl"; + reg = <0xA000 0x1000>; + }; + + pata@10200 { + compatible = "fsl,mpc5121-pata"; + reg = <0x10200 0x100>; + interrupts = <5 0x8>; + interrupt-parent = < &ipic >; + }; + + // 512x PSCs are not 52xx PSC compatible // PSC3 serial port A aka ttyPSC0 serial@11300 { device_type = "serial"; - compatible = "fsl,mpc5121-psc-uart"; + compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; // Logical port assignment needed until driver // learns to use aliases port-number = <0>; cell-index = <3>; reg = <0x11300 0x100>; - interrupts = <0x28 0x8>; // actually the fifo irq + interrupts = <40 0x8>; interrupt-parent = < &ipic >; + rx-fifo-size = <16>; + tx-fifo-size = <16>; }; // PSC4 serial port B aka ttyPSC1 serial@11400 { device_type = "serial"; - compatible = "fsl,mpc5121-psc-uart"; + compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc"; // Logical port assignment needed until driver // learns to use aliases port-number = <1>; cell-index = <4>; reg = <0x11400 0x100>; - interrupts = <0x28 0x8>; // actually the fifo irq + interrupts = <40 0x8>; interrupt-parent = < &ipic >; + rx-fifo-size = <16>; + tx-fifo-size = <16>; }; - pscsfifo@11f00 { + // PSC5 in ac97 mode + ac97@11500 { + compatible = "fsl,mpc5121-psc-ac97", "fsl,mpc5121-psc"; + cell-index = <5>; + reg = <0x11500 0x100>; + interrupts = <40 0x8>; + interrupt-parent = < &ipic >; + fsl,mode = "ac97-slave"; + rx-fifo-size = <384>; + tx-fifo-size = <384>; + }; + + pscfifo@11f00 { compatible = "fsl,mpc5121-psc-fifo"; reg = <0x11f00 0x100>; - interrupts = <0x28 0x8>; + interrupts = <40 0x8>; interrupt-parent = < &ipic >; }; + + dma@14000 { + compatible = "fsl,mpc5121-dma2"; + reg = <0x14000 0x1800>; + interrupts = <65 0x8>; + interrupt-parent = < &ipic >; + }; + + }; + + pci: pci@80008500 { + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + // IDSEL 0x15 - Slot 1 PCI + 0xa800 0x0 0x0 0x1 &cpld_pic 0x0 0x8 + 0xa800 0x0 0x0 0x2 &cpld_pic 0x1 0x8 + 0xa800 0x0 0x0 0x3 &cpld_pic 0x2 0x8 + 0xa800 0x0 0x0 0x4 &cpld_pic 0x3 0x8 + + // IDSEL 0x16 - Slot 2 MiniPCI + 0xb000 0x0 0x0 0x1 &cpld_pic 0x4 0x8 + 0xb000 0x0 0x0 0x2 &cpld_pic 0x5 0x8 + + // IDSEL 0x17 - Slot 3 MiniPCI + 0xb800 0x0 0x0 0x1 &cpld_pic 0x6 0x8 + 0xb800 0x0 0x0 0x2 &cpld_pic 0x7 0x8 + >; + interrupt-parent = < &ipic >; + interrupts = <1 0x8>; + bus-range = <0 0>; + ranges = <0x42000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000 + 0x02000000 0x0 0xb0000000 0xb0000000 0x0 0x10000000 + 0x01000000 0x0 0x00000000 0x84000000 0x0 0x01000000>; + clock-frequency = <0>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0x80008500 0x100>; + compatible = "fsl,mpc5121-pci"; + device_type = "pci"; }; }; -- cgit v0.10.2 From 137e95906e294913fab02162e8a1948ade49acb5 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:02 -0600 Subject: powerpc/mpc5121: Add clock driver Plugs into the generic powerpc clock driver in arch/powerpc/kernel/clock.c The following subset of clk_interface is implemented: clk_get, clk_put: get clock via name, release clock clk_enable, clk_disable: enable or disable clock clk_get_rate: get clock rate in Hz clk_set_rate: stubbed clk_round_rate: stubbed clk_set_parent: NULL clk_get_parent: NULL Signed-off-by: John Rigby Signed-off-by: Grant Likely diff --git a/Makefile b/Makefile index 6aff5f4..fc3ae9f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +FRED=42 VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 4c0da0c..162af06 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -2,6 +2,7 @@ config PPC_MPC512x bool select FSL_SOC select IPIC + select PPC_CLOCK default n config PPC_MPC5121 diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 232c89f..90910c1 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile @@ -1,4 +1,5 @@ # # Makefile for the Freescale PowerPC 512x linux kernel. # +obj-y += clock.o obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c new file mode 100644 index 0000000..f416014 --- /dev/null +++ b/arch/powerpc/platforms/512x/clock.c @@ -0,0 +1,729 @@ +/* + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: John Rigby + * + * Implements the clk api defined in include/linux/clk.h + * + * Original based on linux/arch/arm/mach-integrator/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#undef CLK_DEBUG + +static int clocks_initialized; + +#define CLK_HAS_RATE 0x1 /* has rate in MHz */ +#define CLK_HAS_CTRL 0x2 /* has control reg and bit */ + +struct clk { + struct list_head node; + char name[32]; + int flags; + struct device *dev; + unsigned long rate; + struct module *owner; + void (*calc) (struct clk *); + struct clk *parent; + int reg, bit; /* CLK_HAS_CTRL */ + int div_shift; /* only used by generic_div_clk_calc */ +}; + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +static struct clk *mpc5121_clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + int dev_match = 0; + int id_match = 0; + + if (dev == NULL && id == NULL) + return NULL; + + mutex_lock(&clocks_mutex); + list_for_each_entry(p, &clocks, node) { + if (dev && dev == p->dev) + dev_match++; + if (strcmp(id, p->name) == 0) + id_match++; + if ((dev_match || id_match) && try_module_get(p->owner)) { + clk = p; + break; + } + } + mutex_unlock(&clocks_mutex); + + return clk; +} + +#ifdef CLK_DEBUG +static void dump_clocks(void) +{ + struct clk *p; + + mutex_lock(&clocks_mutex); + printk(KERN_INFO "CLOCKS:\n"); + list_for_each_entry(p, &clocks, node) { + printk(KERN_INFO " %s %ld", p->name, p->rate); + if (p->parent) + printk(KERN_INFO " %s %ld", p->parent->name, + p->parent->rate); + if (p->flags & CLK_HAS_CTRL) + printk(KERN_INFO " reg/bit %d/%d", p->reg, p->bit); + printk("\n"); + } + mutex_unlock(&clocks_mutex); +} +#define DEBUG_CLK_DUMP() dump_clocks() +#else +#define DEBUG_CLK_DUMP() +#endif + + +static void mpc5121_clk_put(struct clk *clk) +{ + module_put(clk->owner); +} + +#define NRPSC 12 + +struct mpc512x_clockctl { + u32 spmr; /* System PLL Mode Reg */ + u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */ + u32 scfr1; /* System Clk Freq Reg 1 */ + u32 scfr2; /* System Clk Freq Reg 2 */ + u32 reserved; + u32 bcr; /* Bread Crumb Reg */ + u32 pccr[NRPSC]; /* PSC Clk Ctrl Reg 0-11 */ + u32 spccr; /* SPDIF Clk Ctrl Reg */ + u32 cccr; /* CFM Clk Ctrl Reg */ + u32 dccr; /* DIU Clk Cnfg Reg */ +}; + +struct mpc512x_clockctl __iomem *clockctl; + +static int mpc5121_clk_enable(struct clk *clk) +{ + unsigned int mask; + + if (clk->flags & CLK_HAS_CTRL) { + mask = in_be32(&clockctl->sccr[clk->reg]); + mask |= 1 << clk->bit; + out_be32(&clockctl->sccr[clk->reg], mask); + } + return 0; +} + +static void mpc5121_clk_disable(struct clk *clk) +{ + unsigned int mask; + + if (clk->flags & CLK_HAS_CTRL) { + mask = in_be32(&clockctl->sccr[clk->reg]); + mask &= ~(1 << clk->bit); + out_be32(&clockctl->sccr[clk->reg], mask); + } +} + +static unsigned long mpc5121_clk_get_rate(struct clk *clk) +{ + if (clk->flags & CLK_HAS_RATE) + return clk->rate; + else + return 0; +} + +static long mpc5121_clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} + +static int mpc5121_clk_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} + +static int clk_register(struct clk *clk) +{ + mutex_lock(&clocks_mutex); + list_add(&clk->node, &clocks); + mutex_unlock(&clocks_mutex); + return 0; +} + +static unsigned long spmf_mult(void) +{ + /* + * Convert spmf to multiplier + */ + static int spmf_to_mult[] = { + 68, 1, 12, 16, + 20, 24, 28, 32, + 36, 40, 44, 48, + 52, 56, 60, 64 + }; + int spmf = (clockctl->spmr >> 24) & 0xf; + return spmf_to_mult[spmf]; +} + +static unsigned long sysdiv_div_x_2(void) +{ + /* + * Convert sysdiv to divisor x 2 + * Some divisors have fractional parts so + * multiply by 2 then divide by this value + */ + static int sysdiv_to_div_x_2[] = { + 4, 5, 6, 7, + 8, 9, 10, 14, + 12, 16, 18, 22, + 20, 24, 26, 30, + 28, 32, 34, 38, + 36, 40, 42, 46, + 44, 48, 50, 54, + 52, 56, 58, 62, + 60, 64, 66, + }; + int sysdiv = (clockctl->scfr2 >> 26) & 0x3f; + return sysdiv_to_div_x_2[sysdiv]; +} + +static unsigned long ref_to_sys(unsigned long rate) +{ + rate *= spmf_mult(); + rate *= 2; + rate /= sysdiv_div_x_2(); + + return rate; +} + +static unsigned long sys_to_ref(unsigned long rate) +{ + rate *= sysdiv_div_x_2(); + rate /= 2; + rate /= spmf_mult(); + + return rate; +} + +static long ips_to_ref(unsigned long rate) +{ + int ips_div = (clockctl->scfr1 >> 23) & 0x7; + + rate *= ips_div; /* csb_clk = ips_clk * ips_div */ + rate *= 2; /* sys_clk = csb_clk * 2 */ + return sys_to_ref(rate); +} + +static unsigned long devtree_getfreq(char *clockname) +{ + struct device_node *np; + const unsigned int *prop; + unsigned int val = 0; + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr"); + if (np) { + prop = of_get_property(np, clockname, NULL); + if (prop) + val = *prop; + of_node_put(np); + } + return val; +} + +static void ref_clk_calc(struct clk *clk) +{ + unsigned long rate; + + rate = devtree_getfreq("bus-frequency"); + if (rate == 0) { + printk(KERN_ERR "No bus-frequency in dev tree\n"); + clk->rate = 0; + return; + } + clk->rate = ips_to_ref(rate); +} + +static struct clk ref_clk = { + .name = "ref_clk", + .calc = ref_clk_calc, +}; + + +static void sys_clk_calc(struct clk *clk) +{ + clk->rate = ref_to_sys(ref_clk.rate); +} + +static struct clk sys_clk = { + .name = "sys_clk", + .calc = sys_clk_calc, +}; + +static void diu_clk_calc(struct clk *clk) +{ + int diudiv_x_2 = clockctl->scfr1 & 0xff; + unsigned long rate; + + rate = sys_clk.rate; + + rate *= 2; + rate /= diudiv_x_2; + + clk->rate = rate; +} + +static void half_clk_calc(struct clk *clk) +{ + clk->rate = clk->parent->rate / 2; +} + +static void generic_div_clk_calc(struct clk *clk) +{ + int div = (clockctl->scfr1 >> clk->div_shift) & 0x7; + + clk->rate = clk->parent->rate / div; +} + +static void unity_clk_calc(struct clk *clk) +{ + clk->rate = clk->parent->rate; +} + +static struct clk csb_clk = { + .name = "csb_clk", + .calc = half_clk_calc, + .parent = &sys_clk, +}; + +static void e300_clk_calc(struct clk *clk) +{ + int spmf = (clockctl->spmr >> 16) & 0xf; + int ratex2 = clk->parent->rate * spmf; + + clk->rate = ratex2 / 2; +} + +static struct clk e300_clk = { + .name = "e300_clk", + .calc = e300_clk_calc, + .parent = &csb_clk, +}; + +static struct clk ips_clk = { + .name = "ips_clk", + .calc = generic_div_clk_calc, + .parent = &csb_clk, + .div_shift = 23, +}; + +/* + * Clocks controlled by SCCR1 (.reg = 0) + */ +static struct clk lpc_clk = { + .name = "lpc_clk", + .flags = CLK_HAS_CTRL, + .reg = 0, + .bit = 30, + .calc = generic_div_clk_calc, + .parent = &ips_clk, + .div_shift = 11, +}; + +static struct clk nfc_clk = { + .name = "nfc_clk", + .flags = CLK_HAS_CTRL, + .reg = 0, + .bit = 29, + .calc = generic_div_clk_calc, + .parent = &ips_clk, + .div_shift = 8, +}; + +static struct clk pata_clk = { + .name = "pata_clk", + .flags = CLK_HAS_CTRL, + .reg = 0, + .bit = 28, + .calc = unity_clk_calc, + .parent = &ips_clk, +}; + +/* + * PSC clocks (bits 27 - 16) + * are setup elsewhere + */ + +static struct clk sata_clk = { + .name = "sata_clk", + .flags = CLK_HAS_CTRL, + .reg = 0, + .bit = 14, + .calc = unity_clk_calc, + .parent = &ips_clk, +}; + +static struct clk fec_clk = { + .name = "fec_clk", + .flags = CLK_HAS_CTRL, + .reg = 0, + .bit = 13, + .calc = unity_clk_calc, + .parent = &ips_clk, +}; + +static struct clk pci_clk = { + .name = "pci_clk", + .flags = CLK_HAS_CTRL, + .reg = 0, + .bit = 11, + .calc = generic_div_clk_calc, + .parent = &csb_clk, + .div_shift = 20, +}; + +/* + * Clocks controlled by SCCR2 (.reg = 1) + */ +static struct clk diu_clk = { + .name = "diu_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 31, + .calc = diu_clk_calc, +}; + +static struct clk axe_clk = { + .name = "axe_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 30, + .calc = unity_clk_calc, + .parent = &csb_clk, +}; + +static struct clk usb1_clk = { + .name = "usb1_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 28, + .calc = unity_clk_calc, + .parent = &csb_clk, +}; + +static struct clk usb2_clk = { + .name = "usb2_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 27, + .calc = unity_clk_calc, + .parent = &csb_clk, +}; + +static struct clk i2c_clk = { + .name = "i2c_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 26, + .calc = unity_clk_calc, + .parent = &ips_clk, +}; + +static struct clk mscan_clk = { + .name = "mscan_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 25, + .calc = unity_clk_calc, + .parent = &ips_clk, +}; + +static struct clk sdhc_clk = { + .name = "sdhc_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 24, + .calc = unity_clk_calc, + .parent = &ips_clk, +}; + +static struct clk mbx_bus_clk = { + .name = "mbx_bus_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 22, + .calc = half_clk_calc, + .parent = &csb_clk, +}; + +static struct clk mbx_clk = { + .name = "mbx_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 21, + .calc = unity_clk_calc, + .parent = &csb_clk, +}; + +static struct clk mbx_3d_clk = { + .name = "mbx_3d_clk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 20, + .calc = generic_div_clk_calc, + .parent = &mbx_bus_clk, + .div_shift = 14, +}; + +static void psc_mclk_in_calc(struct clk *clk) +{ + clk->rate = devtree_getfreq("psc_mclk_in"); + if (!clk->rate) + clk->rate = 25000000; +} + +static struct clk psc_mclk_in = { + .name = "psc_mclk_in", + .calc = psc_mclk_in_calc, +}; + +static struct clk spdif_txclk = { + .name = "spdif_txclk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 23, +}; + +static struct clk spdif_rxclk = { + .name = "spdif_rxclk", + .flags = CLK_HAS_CTRL, + .reg = 1, + .bit = 23, +}; + +static void ac97_clk_calc(struct clk *clk) +{ + /* ac97 bit clock is always 24.567 MHz */ + clk->rate = 24567000; +} + +static struct clk ac97_clk = { + .name = "ac97_clk_in", + .calc = ac97_clk_calc, +}; + +struct clk *rate_clks[] = { + &ref_clk, + &sys_clk, + &diu_clk, + &csb_clk, + &e300_clk, + &ips_clk, + &fec_clk, + &sata_clk, + &pata_clk, + &nfc_clk, + &lpc_clk, + &mbx_bus_clk, + &mbx_clk, + &mbx_3d_clk, + &axe_clk, + &usb1_clk, + &usb2_clk, + &i2c_clk, + &mscan_clk, + &sdhc_clk, + &pci_clk, + &psc_mclk_in, + &spdif_txclk, + &spdif_rxclk, + &ac97_clk, + NULL +}; + +static void rate_clk_init(struct clk *clk) +{ + if (clk->calc) { + clk->calc(clk); + clk->flags |= CLK_HAS_RATE; + clk_register(clk); + } else { + printk(KERN_WARNING + "Could not initialize clk %s without a calc routine\n", + clk->name); + } +} + +static void rate_clks_init(void) +{ + struct clk **cpp, *clk; + + cpp = rate_clks; + while ((clk = *cpp++)) + rate_clk_init(clk); +} + +/* + * There are two clk enable registers with 32 enable bits each + * psc clocks and device clocks are all stored in dev_clks + */ +struct clk dev_clks[2][32]; + +/* + * Given a psc number return the dev_clk + * associated with it + */ +static struct clk *psc_dev_clk(int pscnum) +{ + int reg, bit; + struct clk *clk; + + reg = 0; + bit = 27 - pscnum; + + clk = &dev_clks[reg][bit]; + clk->reg = 0; + clk->bit = bit; + return clk; +} + +/* + * PSC clock rate calculation + */ +static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np) +{ + unsigned long mclk_src = sys_clk.rate; + unsigned long mclk_div; + + /* + * Can only change value of mclk divider + * when the divider is disabled. + * + * Zero is not a valid divider so minimum + * divider is 1 + * + * disable/set divider/enable + */ + out_be32(&clockctl->pccr[pscnum], 0); + out_be32(&clockctl->pccr[pscnum], 0x00020000); + out_be32(&clockctl->pccr[pscnum], 0x00030000); + + if (clockctl->pccr[pscnum] & 0x80) { + clk->rate = spdif_rxclk.rate; + return; + } + + switch ((clockctl->pccr[pscnum] >> 14) & 0x3) { + case 0: + mclk_src = sys_clk.rate; + break; + case 1: + mclk_src = ref_clk.rate; + break; + case 2: + mclk_src = psc_mclk_in.rate; + break; + case 3: + mclk_src = spdif_txclk.rate; + break; + } + + mclk_div = ((clockctl->pccr[pscnum] >> 17) & 0x7fff) + 1; + clk->rate = mclk_src / mclk_div; +} + +/* + * Find all psc nodes in device tree and assign a clock + * with name "psc%d_mclk" and dev pointing at the device + * returned from of_find_device_by_node + */ +static void psc_clks_init(void) +{ + struct device_node *np; + const u32 *cell_index; + struct of_device *ofdev; + + for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { + cell_index = of_get_property(np, "cell-index", NULL); + if (cell_index) { + int pscnum = *cell_index; + struct clk *clk = psc_dev_clk(pscnum); + + clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL; + ofdev = of_find_device_by_node(np); + clk->dev = &ofdev->dev; + /* + * AC97 is special rate clock does + * not go through normal path + */ + if (strcmp("ac97", np->name) == 0) + clk->rate = ac97_clk.rate; + else + psc_calc_rate(clk, pscnum, np); + sprintf(clk->name, "psc%d_mclk", pscnum); + clk_register(clk); + clk_enable(clk); + } + } +} + +static struct clk_interface mpc5121_clk_functions = { + .clk_get = mpc5121_clk_get, + .clk_enable = mpc5121_clk_enable, + .clk_disable = mpc5121_clk_disable, + .clk_get_rate = mpc5121_clk_get_rate, + .clk_put = mpc5121_clk_put, + .clk_round_rate = mpc5121_clk_round_rate, + .clk_set_rate = mpc5121_clk_set_rate, + .clk_set_parent = NULL, + .clk_get_parent = NULL, +}; + +static int +mpc5121_clk_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); + if (np) { + clockctl = of_iomap(np, 0); + of_node_put(np); + } + + if (!clockctl) { + printk(KERN_ERR "Could not map clock control registers\n"); + return 0; + } + + rate_clks_init(); + psc_clks_init(); + + /* leave clockctl mapped forever */ + /*iounmap(clockctl); */ + DEBUG_CLK_DUMP(); + clocks_initialized++; + clk_functions = mpc5121_clk_functions; + return 0; +} + + +arch_initcall(mpc5121_clk_init); -- cgit v0.10.2 From fb1803224ea145e3424d6295d4aaa8e9fef70642 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:03 -0600 Subject: powerpc/mpc5121: Add generic board support for MPC5121 platforms Move shared code from mpc5121_ads.c to new file mpc512x_shared.c - mpc512x_find_ips_freq -> unchanged - contents of mpc5121_ads_init_IRQ -> mpc512x_init_IRQ - looking for fsl,mpc5121-ipic instead of fsl,ipic - mpc5121_ads_declare_of_platform_devices -> mpc5121_declare_of_platform_devices - and use compatible for lookup instead of node name Add new generic board setup mpc5121_generic.c Signed-off-by: John Rigby Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 162af06..5d72dc34 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -3,12 +3,10 @@ config PPC_MPC512x select FSL_SOC select IPIC select PPC_CLOCK - default n config PPC_MPC5121 bool select PPC_MPC512x - default n config MPC5121_ADS bool "Freescale MPC5121E ADS" @@ -17,4 +15,15 @@ config MPC5121_ADS select PPC_MPC5121 help This option enables support for the MPC5121E ADS board. - default n + +config MPC5121_GENERIC + bool "Generic support for simple MPC5121 based boards" + depends on PPC_MULTIPLATFORM && PPC32 + select DEFAULT_UIMAGE + select PPC_MPC5121 + help + This option enables support for simple MPC5121 based boards + which do not need custom platform specific setup. + + Compatible boards include: Protonic LVT base boards (ZANMCU + and VICVT2). diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 90910c1..8090e22 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile @@ -1,5 +1,6 @@ # # Makefile for the Freescale PowerPC 512x linux kernel. # -obj-y += clock.o +obj-y += clock.o mpc512x_shared.o obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o +obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c index 50bd3a3..3ec9ca3 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. + * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. All rights reserved. * * Author: John Rigby, , Thur Mar 29 2007 * @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -23,65 +22,11 @@ #include #include -/** - * mpc512x_find_ips_freq - Find the IPS bus frequency for a device - * @node: device node - * - * Returns IPS bus frequency, or 0 if the bus frequency cannot be found. - */ -unsigned long -mpc512x_find_ips_freq(struct device_node *node) -{ - struct device_node *np; - const unsigned int *p_ips_freq = NULL; - - of_node_get(node); - while (node) { - p_ips_freq = of_get_property(node, "bus-frequency", NULL); - if (p_ips_freq) - break; - - np = of_get_parent(node); - of_node_put(node); - node = np; - } - if (node) - of_node_put(node); - - return p_ips_freq ? *p_ips_freq : 0; -} -EXPORT_SYMBOL(mpc512x_find_ips_freq); - -static struct of_device_id __initdata of_bus_ids[] = { - { .name = "soc", }, - { .name = "localbus", }, - {}, -}; - -static void __init mpc5121_ads_declare_of_platform_devices(void) -{ - /* Find every child of the SOC node and add it to of_platform */ - if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) - printk(KERN_ERR __FILE__ ": " - "Error while probing of_platform bus\n"); -} +#include "mpc512x.h" static void __init mpc5121_ads_init_IRQ(void) { - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); - if (!np) - return; - - ipic_init(np, 0); - of_node_put(np); - - /* - * Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); + mpc512x_init_IRQ(); } /* @@ -97,7 +42,8 @@ static int __init mpc5121_ads_probe(void) define_machine(mpc5121_ads) { .name = "MPC5121 ADS", .probe = mpc5121_ads_probe, - .init = mpc5121_ads_declare_of_platform_devices, + .setup_arch = mpc5121_ads_setup_arch, + .init = mpc512x_declare_of_platform_devices, .init_IRQ = mpc5121_ads_init_IRQ, .get_irq = ipic_get_irq, .calibrate_decr = generic_calibrate_decr, diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c new file mode 100644 index 0000000..2479de9 --- /dev/null +++ b/arch/powerpc/platforms/512x/mpc5121_generic.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: John Rigby, + * + * Description: + * MPC5121 SoC setup + * + * This 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 +#include + +#include +#include +#include +#include + +#include "mpc512x.h" + +/* + * list of supported boards + */ +static char *board[] __initdata = { + "prt,prtlvt", + NULL +}; + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init mpc5121_generic_probe(void) +{ + unsigned long node = of_get_flat_dt_root(); + int i = 0; + + while (board[i]) { + if (of_flat_dt_is_compatible(node, board[i])) + break; + i++; + } + + return board[i] != NULL; +} + +define_machine(mpc5121_generic) { + .name = "MPC5121 generic", + .probe = mpc5121_generic_probe, + .init = mpc512x_declare_of_platform_devices, + .init_IRQ = mpc512x_init_IRQ, + .get_irq = ipic_get_irq, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h new file mode 100644 index 0000000..9c03693 --- /dev/null +++ b/arch/powerpc/platforms/512x/mpc512x.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2007 Freescale Semiconductor, 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. + * + * Prototypes for MPC512x shared code + */ + +#ifndef __MPC512X_H__ +#define __MPC512X_H__ +extern unsigned long mpc512x_find_ips_freq(struct device_node *node); +extern void __init mpc512x_init_IRQ(void); +void __init mpc512x_declare_of_platform_devices(void); +#endif /* __MPC512X_H__ */ diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c new file mode 100644 index 0000000..d8cd579 --- /dev/null +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: John Rigby + * + * Description: + * MPC512x Shared code + * + * This 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "mpc512x.h" + +unsigned long +mpc512x_find_ips_freq(struct device_node *node) +{ + struct device_node *np; + const unsigned int *p_ips_freq = NULL; + + of_node_get(node); + while (node) { + p_ips_freq = of_get_property(node, "bus-frequency", NULL); + if (p_ips_freq) + break; + + np = of_get_parent(node); + of_node_put(node); + node = np; + } + if (node) + of_node_put(node); + + return p_ips_freq ? *p_ips_freq : 0; +} +EXPORT_SYMBOL(mpc512x_find_ips_freq); + +void __init mpc512x_init_IRQ(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-ipic"); + if (!np) + return; + + ipic_init(np, 0); + of_node_put(np); + + /* + * Initialize the default interrupt mapping priorities, + * in case the boot rom changed something on us. + */ + ipic_set_default_priority(); +} + +/* + * Nodes to do bus probe on, soc and localbus + */ +static struct of_device_id __initdata of_bus_ids[] = { + { .compatible = "fsl,mpc5121-immr", }, + { .compatible = "fsl,mpc5121-localbus", }, + {}, +}; + +void __init mpc512x_declare_of_platform_devices(void) +{ + if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) + printk(KERN_ERR __FILE__ ": " + "Error while probing of_platform bus\n"); +} + -- cgit v0.10.2 From 1879f711d8c3960e0fd927f38ff885017a77291b Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 9 Jul 2008 14:54:04 -0600 Subject: powerpc/mpc5121: Add support for CPLD on MPC5121ADS board Add a interrupt host for the interrupt controller in the mpc5121ads cpld. PCI interrupts are 0-7 the rest are 8-15 Touchscreen pendown irq is hardwired to irq1 All other irqs are chained to irq0 Signed-off-by: John Rigby Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 5d72dc34..c62f893 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -13,6 +13,7 @@ config MPC5121_ADS depends on PPC_MULTIPLATFORM && PPC32 select DEFAULT_UIMAGE select PPC_MPC5121 + select MPC5121_ADS_CPLD help This option enables support for the MPC5121E ADS board. diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 8090e22..90be2f5 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile @@ -2,5 +2,5 @@ # Makefile for the Freescale PowerPC 512x linux kernel. # obj-y += clock.o mpc512x_shared.o -obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o +obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c index 3ec9ca3..5ebf693 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads.c @@ -23,10 +23,21 @@ #include #include "mpc512x.h" +#include "mpc5121_ads.h" + +static void __init mpc5121_ads_setup_arch(void) +{ + printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n"); + /* + * cpld regs are needed early + */ + mpc5121_ads_cpld_map(); +} static void __init mpc5121_ads_init_IRQ(void) { mpc512x_init_IRQ(); + mpc5121_ads_cpld_pic_init(); } /* diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.h b/arch/powerpc/platforms/512x/mpc5121_ads.h new file mode 100644 index 0000000..662076c --- /dev/null +++ b/arch/powerpc/platforms/512x/mpc5121_ads.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2008 Freescale Semiconductor, 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. + * + * Prototypes for ADS5121 specific code + */ + +#ifndef __MPC512ADS_H__ +#define __MPC512ADS_H__ +extern void __init mpc5121_ads_cpld_map(void); +extern void __init mpc5121_ads_cpld_pic_init(void); +#endif /* __MPC512ADS_H__ */ diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c new file mode 100644 index 0000000..a6ce805 --- /dev/null +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: John Rigby, + * + * Description: + * MPC5121ADS CPLD irq handling + * + * This 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. + */ + +#undef DEBUG + +#include +#include +#include +#include +#include + +static struct device_node *cpld_pic_node; +static struct irq_host *cpld_pic_host; + +/* + * Bits to ignore in the misc_status register + * 0x10 touch screen pendown is hard routed to irq1 + * 0x02 pci status is read from pci status register + */ +#define MISC_IGNORE 0x12 + +/* + * Nothing to ignore in pci status register + */ +#define PCI_IGNORE 0x00 + +struct cpld_pic { + u8 pci_mask; + u8 pci_status; + u8 route; + u8 misc_mask; + u8 misc_status; + u8 misc_control; +}; + +static struct cpld_pic __iomem *cpld_regs; + +static void __iomem * +irq_to_pic_mask(unsigned int irq) +{ + return irq <= 7 ? &cpld_regs->pci_mask : &cpld_regs->misc_mask; +} + +static unsigned int +irq_to_pic_bit(unsigned int irq) +{ + return 1 << (irq & 0x7); +} + +static void +cpld_mask_irq(unsigned int irq) +{ + unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq; + void __iomem *pic_mask = irq_to_pic_mask(cpld_irq); + + out_8(pic_mask, + in_8(pic_mask) | irq_to_pic_bit(cpld_irq)); +} + +static void +cpld_unmask_irq(unsigned int irq) +{ + unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq; + void __iomem *pic_mask = irq_to_pic_mask(cpld_irq); + + out_8(pic_mask, + in_8(pic_mask) & ~irq_to_pic_bit(cpld_irq)); +} + +static struct irq_chip cpld_pic = { + .typename = " CPLD PIC ", + .mask = cpld_mask_irq, + .ack = cpld_mask_irq, + .unmask = cpld_unmask_irq, +}; + +static int +cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp, + u8 __iomem *maskp) +{ + int cpld_irq; + u8 status = in_8(statusp); + u8 mask = in_8(maskp); + + /* ignore don't cares and masked irqs */ + status |= (ignore | mask); + + if (status == 0xff) + return NO_IRQ_IGNORE; + + cpld_irq = ffz(status) + offset; + + return irq_linear_revmap(cpld_pic_host, cpld_irq); +} + +static void +cpld_pic_cascade(unsigned int irq, struct irq_desc *desc) +{ + irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status, + &cpld_regs->pci_mask); + if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) { + generic_handle_irq(irq); + return; + } + + irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status, + &cpld_regs->misc_mask); + if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) { + generic_handle_irq(irq); + return; + } +} + +static int +cpld_pic_host_match(struct irq_host *h, struct device_node *node) +{ + return cpld_pic_node == node; +} + +static int +cpld_pic_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq); + return 0; +} + +static struct +irq_host_ops cpld_pic_host_ops = { + .match = cpld_pic_host_match, + .map = cpld_pic_host_map, +}; + +void __init +mpc5121_ads_cpld_map(void) +{ + struct device_node *np = NULL; + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld-pic"); + if (!np) { + printk(KERN_ERR "CPLD PIC init: can not find cpld-pic node\n"); + return; + } + + cpld_regs = of_iomap(np, 0); + of_node_put(np); +} + +void __init +mpc5121_ads_cpld_pic_init(void) +{ + unsigned int cascade_irq; + struct device_node *np = NULL; + + pr_debug("cpld_ic_init\n"); + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld-pic"); + if (!np) { + printk(KERN_ERR "CPLD PIC init: can not find cpld-pic node\n"); + return; + } + + if (!cpld_regs) + goto end; + + cascade_irq = irq_of_parse_and_map(np, 0); + if (cascade_irq == NO_IRQ) + goto end; + + /* + * statically route touch screen pendown through 1 + * and ignore it here + * route all others through our cascade irq + */ + out_8(&cpld_regs->route, 0xfd); + out_8(&cpld_regs->pci_mask, 0xff); + /* unmask pci ints in misc mask */ + out_8(&cpld_regs->misc_mask, ~(MISC_IGNORE)); + + cpld_pic_node = of_node_get(np); + + cpld_pic_host = + irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16); + if (!cpld_pic_host) { + printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n"); + goto end; + } + + set_irq_chained_handler(cascade_irq, cpld_pic_cascade); +end: + of_node_put(np); +} -- cgit v0.10.2 From 77a76369475801ab8cbb338b9d8cfa92a491badb Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 12 Jul 2008 12:11:43 -0600 Subject: powerpc: Modify MPC52xx maintainers entry to cover all MPC5xxx parts Linux now supports the MPC5121 part and is handled by the same maintainer. Update MAINTAINERS to reflect this. Also remove URLs which are out of date or are not particularly relevant. Signed-off-by: Grant Likely diff --git a/MAINTAINERS b/MAINTAINERS index 8f0ec46..c984014 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2489,13 +2489,11 @@ W: http://www.penguinppc.org/ L: linuxppc-dev@ozlabs.org S: Maintained -LINUX FOR POWERPC EMBEDDED MPC52XX +LINUX FOR POWERPC EMBEDDED MPC5XXX P: Sylvain Munaut M: tnt@246tNt.com P: Grant Likely M: grant.likely@secretlab.ca -W: http://www.246tNt.com/mpc52xx/ -W: http://www.penguinppc.org/ L: linuxppc-dev@ozlabs.org S: Maintained -- cgit v0.10.2 From 7ab073b6e0cde1544f4e79fadb75532528af7595 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 14:30:35 -0700 Subject: x86: max_low_pfn_mapped fix, #1 fix crash on Ingo's big box: calling pci_iommu_init+0x0/0x17 PCI-DMA: Disabling AGP. PCI-DMA: aperture base @ d0000000 size 65536 KB PCI-DMA: using GART IOMMU. PCI-DMA: Reserving 64MB of IOMMU area in the AGP aperture BUG: unable to handle kernel paging request at ffff88000003be88 IP: [] __alloc_pages_internal+0xc3/0x3f2 PGD 202063 PUD 206063 PMD 22fc00163 PTE 3b162 Oops: 0000 [1] SMP and e820 is: BIOS-e820: 0000000000000000 - 000000000009ac00 (usable) BIOS-e820: 000000000009ac00 - 00000000000a0000 (reserved) BIOS-e820: 00000000000ca000 - 0000000000100000 (reserved) BIOS-e820: 0000000000100000 - 000000007ff70000 (usable) BIOS-e820: 000000007ff70000 - 000000007ff86000 (ACPI data) BIOS-e820: 000000007ff86000 - 0000000080000000 (ACPI NVS) BIOS-e820: 0000000080000000 - 00000000cfe00000 (usable) BIOS-e820: 00000000cfe00000 - 00000000d0000000 (reserved) BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved) BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved) BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved) BIOS-e820: 00000000fff80000 - 0000000100000000 (reserved) BIOS-e820: 0000000100000000 - 0000000830000000 (usable) system has 32 GB RAM installed. max_low_pfn_mapped is 0xcfe00, and GART aperture is not mapped. So try to use init_memory_mapping to map that area, because the iommu thinks that area is ram ... Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index d0d18db..a614ee1 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -630,6 +630,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) struct pci_dev *dev; void *gatt; int i, error; + unsigned long start_pfn, end_pfn; printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; @@ -674,6 +675,16 @@ static __init int init_k8_gatt(struct agp_kern_info *info) printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10); + + /* need to map that range */ + end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT); + if (end_pfn > max_low_pfn_mapped) { + start_pfn = max_low_pfn_mapped; + max_low_pfn_mapped = init_memory_mapping(start_pfn< Date: Sat, 12 Jul 2008 14:31:28 -0700 Subject: x86: max_low_pfn_mapped fix, #2 tighten the boundary checks around max_low_pfn_mapped - dont overmap nor undermap into holes. also print out tseg for AMD cpus, for diagnostic purposes. (this is an SMM area, and we split up any big mappings around that area) Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c index bd182b76..7c36fb8 100644 --- a/arch/x86/kernel/cpu/amd_64.c +++ b/arch/x86/kernel/cpu/amd_64.c @@ -200,6 +200,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) * benefit in doing so. */ if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { + printk(KERN_DEBUG "tseg: %010llx\n", tseg); if ((tseg>>PMD_SHIFT) < (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) || ((tseg>>PMD_SHIFT) < diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 0389cb8..fb6f2ab 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -658,11 +658,11 @@ static int cpa_process_alias(struct cpa_data *cpa) struct cpa_data alias_cpa; int ret = 0; - if (cpa->pfn > max_pfn_mapped) + if (cpa->pfn >= max_pfn_mapped) return 0; #ifdef CONFIG_X86_64 - if (cpa->pfn > max_low_pfn_mapped && cpa->pfn < (1UL<<(32-PAGE_SHIFT))) + if (cpa->pfn >= max_low_pfn_mapped && cpa->pfn < (1UL<<(32-PAGE_SHIFT))) return 0; #endif /* diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 749766c..d458507 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -449,8 +449,8 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, if (retval < 0) return 0; - if (((pfn <= max_low_pfn_mapped) || - (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn <= max_pfn_mapped)) && + if (((pfn < max_low_pfn_mapped) || + (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) && ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { free_memtype(offset, offset + size); printk(KERN_INFO diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 5281e34..2aafb67 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -334,9 +334,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, flags = new_flags; } - if (((vma->vm_pgoff <= max_low_pfn_mapped) || + if (((vma->vm_pgoff < max_low_pfn_mapped) || (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) && - vma->vm_pgoff <= max_pfn_mapped)) && + vma->vm_pgoff < max_pfn_mapped)) && ioremap_change_attr((unsigned long)__va(addr), len, flags)) { free_memtype(addr, addr + len); return -EINVAL; -- cgit v0.10.2 From 9958e810f8ac92f8a447035ee6555420ba27b847 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 14:32:45 -0700 Subject: x86: max_low_pfn_mapped fix, #3 optimization: try to merge the range with same page size in init_memory_mapping, to get the best possible linear mappings set up. thus when GBpages is not there, we could do 2M pages. Signed-off-by: Yinghai Lu Cc: Suresh Siddha Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 122bcef..a25cc6f 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -763,6 +763,20 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, end_pfn = end>>PAGE_SHIFT; nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); + /* try to merge same page size and continuous */ + for (i = 0; nr_range > 1 && i < nr_range - 1; i++) { + unsigned long old_start; + if (mr[i].end != mr[i+1].start || + mr[i].page_size_mask != mr[i+1].page_size_mask) + continue; + /* move it */ + old_start = mr[i].start; + memmove(&mr[i], &mr[i+1], + (nr_range - 1 - i) * sizeof (struct map_range)); + mr[i].start = old_start; + nr_range--; + } + for (i = 0; i < nr_range; i++) printk(KERN_DEBUG " %010lx - %010lx page %s\n", mr[i].start, mr[i].end, -- cgit v0.10.2 From 7b479becdb8c1fb4ff6fbb2a4076c471c737b54c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 22:57:07 -0700 Subject: x86, e820: remove end_user_pfn end_user_pfn used to modify the meaning of the e820 maps. Now that all e820 operations are cleaned up, unified, tightened up, the e820 map always get updated to reality, we don't need to keep this secondary mechanism anymore. If you hit this commit in bisection it means something slipped through. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index a5383ae..28c2918 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1049,11 +1049,6 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) #endif /* - * Last pfn which the user wants to use. - */ -unsigned long __initdata end_user_pfn = MAX_ARCH_PFN; - -/* * Find the highest page frame number we have available */ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) @@ -1085,8 +1080,6 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) if (last_pfn > max_arch_pfn) last_pfn = max_arch_pfn; - if (last_pfn > end_user_pfn) - last_pfn = end_user_pfn; printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n", last_pfn, max_arch_pfn); @@ -1131,12 +1124,6 @@ int __init e820_find_active_region(const struct e820entry *ei, if (*ei_endpfn > last_pfn) *ei_endpfn = last_pfn; - /* Obey end_user_pfn to save on memmap */ - if (*ei_startpfn >= end_user_pfn) - return 0; - if (*ei_endpfn > end_user_pfn) - *ei_endpfn = end_user_pfn; - return 1; } @@ -1201,7 +1188,6 @@ static int __init parse_memopt(char *p) userdef = 1; mem_size = memparse(p, &p); - end_user_pfn = mem_size>>PAGE_SHIFT; e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); return 0; @@ -1245,10 +1231,9 @@ static int __init parse_memmap_opt(char *p) } else if (*p == '$') { start_at = memparse(p+1, &p); e820_add_region(start_at, mem_size, E820_RESERVED); - } else { - end_user_pfn = (mem_size >> PAGE_SHIFT); + } else e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); - } + return *p == '\0' ? 0 : -EINVAL; } early_param("memmap", parse_memmap_opt); -- cgit v0.10.2 From 3d88cca7085cffce077f808f36551e9050eb9e3a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 12 Jul 2008 22:52:55 -0700 Subject: x86: fix numaq_tsc_disable calling got this on a test-system: calling numaq_tsc_disable+0x0/0x39 NUMAQ: disabling TSC initcall numaq_tsc_disable+0x0/0x39 returned 0 after 0 msecs that's because we should not be using arch_initcall to call numaq_tsc_disable. need to call it in setup_arch before time_init()/tsc_init() and call it in init_intel() to make the cpu feature bits right. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index fe9224c..70609ef 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -226,6 +226,10 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if (cpu_has_bts) ds_init_intel(c); + +#ifdef CONFIG_X86_NUMAQ + numaq_tsc_disable(); +#endif } static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned int size) diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index f0f1de1..5b20a5e 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -93,12 +93,13 @@ int __init get_memcfg_numaq(void) return 1; } -static int __init numaq_tsc_disable(void) +void __init numaq_tsc_disable(void) { + if (!found_numaq) + return -1; + if (num_online_nodes() > 1) { printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); setup_clear_cpu_cap(X86_FEATURE_TSC); } - return 0; } -arch_initcall(numaq_tsc_disable); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 987b6fd..36c540d 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -849,6 +849,14 @@ void __init setup_arch(char **cmdline_p) init_cpu_to_node(); #endif +#ifdef CONFIG_X86_NUMAQ + /* + * need to check online nodes num, call it + * here before time_init/tsc_init + */ + numaq_tsc_disable(); +#endif + init_apic_mappings(); ioapic_init_mappings(); diff --git a/include/asm-x86/numaq.h b/include/asm-x86/numaq.h index ef068d24..34b92d5 100644 --- a/include/asm-x86/numaq.h +++ b/include/asm-x86/numaq.h @@ -157,6 +157,8 @@ struct sys_cfg_data { struct eachquadmem eq[MAX_NUMNODES]; /* indexed by quad id */ }; +void numaq_tsc_disable(void); + #else static inline int get_memcfg_numaq(void) { -- cgit v0.10.2 From 3e84050c81ffb4961ef43d20e1fb1d7607167d83 Mon Sep 17 00:00:00 2001 From: Dmitry Adamushko Date: Sun, 13 Jul 2008 02:10:29 +0200 Subject: cpusets, hotplug, scheduler: fix scheduler domain breakage Commit f18f982ab ("sched: CPU hotplug events must not destroy scheduler domains created by the cpusets") introduced a hotplug-related problem as described below: Upon CPU_DOWN_PREPARE, update_sched_domains() -> detach_destroy_domains(&cpu_online_map) does the following: /* * Force a reinitialization of the sched domains hierarchy. The domains * and groups cannot be updated in place without racing with the balancing * code, so we temporarily attach all running cpus to the NULL domain * which will prevent rebalancing while the sched domains are recalculated. */ The sched-domains should be rebuilt when a CPU_DOWN ops. has been completed, effectively either upon CPU_DEAD{_FROZEN} (upon success) or CPU_DOWN_FAILED{_FROZEN} (upon failure -- restore the things to their initial state). That's what update_sched_domains() also does but only for !CPUSETS case. With f18f982ab, sched-domains' reinitialization is delegated to CPUSETS code: cpuset_handle_cpuhp() -> common_cpu_mem_hotplug_unplug() -> rebuild_sched_domains() Being called for CPU_UP_PREPARE and if its callback is called after update_sched_domains()), it just negates all the work done by update_sched_domains() -- i.e. a soon-to-be-offline cpu is included in the sched-domains and that makes it visible for the load-balancer while the CPU_DOWN ops. is in progress. __migrate_live_tasks() moves the tasks off a 'dead' cpu (it's already "offline" when this function is called). try_to_wake_up() is called for one of these tasks from another CPU -> the load-balancer (wake_idle()) picks up a "dead" CPU and places the task on it. Then e.g. BUG_ON(rq->nr_running) detects this a bit later -> oops. Signed-off-by: Dmitry Adamushko Tested-by: Vegard Nossum Cc: Paul Menage Cc: Max Krasnyansky Cc: Paul Jackson Cc: Peter Zijlstra Cc: miaox@cn.fujitsu.com Cc: rostedt@goodmis.org Cc: Linus Torvalds Signed-off-by: Ingo Molnar diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 9fceb97..798b3ab 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1882,7 +1882,7 @@ static void scan_for_empty_cpusets(const struct cpuset *root) * in order to minimize text size. */ -static void common_cpu_mem_hotplug_unplug(void) +static void common_cpu_mem_hotplug_unplug(int rebuild_sd) { cgroup_lock(); @@ -1894,7 +1894,8 @@ static void common_cpu_mem_hotplug_unplug(void) * Scheduler destroys domains on hotplug events. * Rebuild them based on the current settings. */ - rebuild_sched_domains(); + if (rebuild_sd) + rebuild_sched_domains(); cgroup_unlock(); } @@ -1912,11 +1913,22 @@ static void common_cpu_mem_hotplug_unplug(void) static int cpuset_handle_cpuhp(struct notifier_block *unused_nb, unsigned long phase, void *unused_cpu) { - if (phase == CPU_DYING || phase == CPU_DYING_FROZEN) + switch (phase) { + case CPU_UP_CANCELED: + case CPU_UP_CANCELED_FROZEN: + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + case CPU_DEAD: + case CPU_DEAD_FROZEN: + common_cpu_mem_hotplug_unplug(1); + break; + default: return NOTIFY_DONE; + } - common_cpu_mem_hotplug_unplug(); - return 0; + return NOTIFY_OK; } #ifdef CONFIG_MEMORY_HOTPLUG @@ -1929,7 +1941,7 @@ static int cpuset_handle_cpuhp(struct notifier_block *unused_nb, void cpuset_track_online_nodes(void) { - common_cpu_mem_hotplug_unplug(); + common_cpu_mem_hotplug_unplug(0); } #endif -- cgit v0.10.2 From ce8b06b985ae48f9425de6e4641e77cb3613ef00 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sun, 13 Jul 2008 03:29:42 +0100 Subject: x86: I/O APIC: remove an IRQ2-mask hack Now that IRQ2 is never made available to the I/O APIC, there is no need to special-case it and mask as a workaround for broken systems. Actually, because of the former, mask_IO_APIC_irq(2) is a no-op already. Signed-off-by: Maciej W. Rozycki Cc: "Rafael J. Wysocki" Cc: Matthew Garrett Cc: Andreas Herrmann Cc: Stephen Rothwell Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 785700a..f489d7a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1409,7 +1409,6 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) { pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident); acpi_skip_timer_override = 1; - force_mask_ioapic_irq_2(); return 0; } diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index c50adb8..603261a 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c @@ -59,13 +59,6 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); static DEFINE_SPINLOCK(vector_lock); -static bool mask_ioapic_irq_2 __initdata; - -void __init force_mask_ioapic_irq_2(void) -{ - mask_ioapic_irq_2 = true; -} - int timer_through_8259 __initdata; /* @@ -2187,9 +2180,6 @@ static inline void __init check_timer(void) printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", vector, apic1, pin1, apic2, pin2); - if (mask_ioapic_irq_2) - mask_IO_APIC_irq(2); - /* * Some BIOS writers are clueless and report the ExtINTA * I/O APIC input from the cascaded 8259A as the timer diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 9e645cb..b16ef02 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@ -94,13 +94,6 @@ static int no_timer_check; static int disable_timer_pin_1 __initdata; -static bool mask_ioapic_irq_2 __initdata; - -void __init force_mask_ioapic_irq_2(void) -{ - mask_ioapic_irq_2 = true; -} - int timer_through_8259 __initdata; /* Where if anywhere is the i8259 connect in external int mode */ @@ -1706,9 +1699,6 @@ static inline void __init check_timer(void) apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", cfg->vector, apic1, pin1, apic2, pin2); - if (mask_ioapic_irq_2) - mask_IO_APIC_irq(2); - /* * Some BIOS writers are clueless and report the ExtINTA * I/O APIC input from the cascaded 8259A as the timer diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h index 33a73f5..b02ea6e 100644 --- a/include/asm-x86/genapic_32.h +++ b/include/asm-x86/genapic_32.h @@ -119,10 +119,5 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; #define is_uv_system() 0 #define uv_wakeup_secondary(a, b) 1 -#ifdef CONFIG_X86_IO_APIC -extern void force_mask_ioapic_irq_2(void); -#else -static inline void force_mask_ioapic_irq_2(void) { } -#endif #endif diff --git a/include/asm-x86/genapic_64.h b/include/asm-x86/genapic_64.h index 647e4e5..0f85046 100644 --- a/include/asm-x86/genapic_64.h +++ b/include/asm-x86/genapic_64.h @@ -46,10 +46,4 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); extern void setup_apic_routing(void); -#ifdef CONFIG_X86_IO_APIC -extern void force_mask_ioapic_irq_2(void); -#else -static inline void force_mask_ioapic_irq_2(void) { } -#endif - #endif -- cgit v0.10.2 From 815224293e5aa4c7dc1638807889e345f385b38d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 11 Jul 2008 21:48:54 -0500 Subject: pcmcia: ide-cs debugging bugfix The code in module ide-cs does not conform to the current standard if setting CONFIG_PCMCIA_DEBUG to "y", and loading the module with the option "pc_debug=N". When that is fixed, then a warning results that version is defined but not used. This patch fixes both situations. Signed-off-by: Larry Finger CC: Bartlomiej Zolnierkiewicz Signed-off-by: Dominik Brodowski diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index aa2ea3d..8b8b20d 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -63,11 +63,11 @@ MODULE_LICENSE("Dual MPL/GPL"); #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0) -#ifdef PCMCIA_DEBUG -INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); +#ifdef CONFIG_PCMCIA_DEBUG +INT_MODULE_PARM(pc_debug, 0); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -static char *version = -"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)"; +/*static char *version = +"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";*/ #else #define DEBUG(n, args...) #endif -- cgit v0.10.2 From 090657e423f45a77151943f50165ae9565bfbf33 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Sun, 13 Jul 2008 20:12:11 +0800 Subject: crypto: ixp4xx - Select CRYPTO_AUTHENC Without CRYPTO_AUTHENC the driver fails to build: drivers/built-in.o: In function `ixp_module_init': ixp4xx_crypto.c:(.init.text+0x3250): undefined reference to `crypto_aead_type' Signed-off-by: Imre Kaloz Signed-off-by: Herbert Xu diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index eb2ec2e..e522144 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -195,6 +195,7 @@ config CRYPTO_DEV_IXP4XX depends on ARCH_IXP4XX select CRYPTO_DES select CRYPTO_ALGAPI + select CRYPTO_AUTHENC select CRYPTO_BLKCIPHER help Driver for the IXP4xx NPE crypto engine. -- cgit v0.10.2 From 11369f356b66d363a615fde2c5526962f7683674 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Tue, 8 Jul 2008 14:35:21 -0700 Subject: x86: change _node_to_cpumask_ptr to return const ptr * Strengthen the return type for the _node_to_cpumask_ptr to be a const pointer. This adds compiler checking to insure that node_to_cpumask_map[] is not changed inadvertently. Signed-off-by: Mike Travis Cc: "akpm@linux-foundation.org" Cc: Yinghai Lu Acked-by: Vegard Nossum Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 5fc310f..cac6843 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -343,23 +343,23 @@ static const cpumask_t cpu_mask_none; /* * Returns a pointer to the bitmask of CPUs on Node 'node'. */ -cpumask_t *_node_to_cpumask_ptr(int node) +const cpumask_t *_node_to_cpumask_ptr(int node) { if (node_to_cpumask_map == NULL) { printk(KERN_WARNING "_node_to_cpumask_ptr(%d): no node_to_cpumask_map!\n", node); dump_stack(); - return &cpu_online_map; + return (const cpumask_t *)&cpu_online_map; } if (node >= nr_node_ids) { printk(KERN_WARNING "_node_to_cpumask_ptr(%d): node > nr_node_ids(%d)\n", node, nr_node_ids); dump_stack(); - return (cpumask_t *)&cpu_mask_none; + return &cpu_mask_none; } - return (cpumask_t *)&node_to_cpumask_map[node]; + return &node_to_cpumask_map[node]; } EXPORT_SYMBOL(_node_to_cpumask_ptr); diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h index a6aea79..54bbf6e 100644 --- a/include/asm-generic/topology.h +++ b/include/asm-generic/topology.h @@ -60,7 +60,8 @@ #ifndef node_to_cpumask_ptr #define node_to_cpumask_ptr(v, node) \ - cpumask_t _##v = node_to_cpumask(node), *v = &_##v + cpumask_t _##v = node_to_cpumask(node); \ + const cpumask_t *v = &_##v #define node_to_cpumask_ptr_next(v, node) \ _##v = node_to_cpumask(node) diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 98e5f17..90ac771 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -82,7 +82,7 @@ DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); #ifdef CONFIG_DEBUG_PER_CPU_MAPS extern int cpu_to_node(int cpu); extern int early_cpu_to_node(int cpu); -extern cpumask_t *_node_to_cpumask_ptr(int node); +extern const cpumask_t *_node_to_cpumask_ptr(int node); extern cpumask_t node_to_cpumask(int node); #else /* !CONFIG_DEBUG_PER_CPU_MAPS */ @@ -103,7 +103,7 @@ static inline int early_cpu_to_node(int cpu) } /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ -static inline cpumask_t *_node_to_cpumask_ptr(int node) +static inline const cpumask_t *_node_to_cpumask_ptr(int node) { return &node_to_cpumask_map[node]; } @@ -118,7 +118,7 @@ static inline cpumask_t node_to_cpumask(int node) /* Replace default node_to_cpumask_ptr with optimized version */ #define node_to_cpumask_ptr(v, node) \ - cpumask_t *v = _node_to_cpumask_ptr(node) + const cpumask_t *v = _node_to_cpumask_ptr(node) #define node_to_cpumask_ptr_next(v, node) \ v = _node_to_cpumask_ptr(node) @@ -186,7 +186,7 @@ extern int __node_distance(int, int); #define cpu_to_node(cpu) 0 #define early_cpu_to_node(cpu) 0 -static inline cpumask_t *_node_to_cpumask_ptr(int node) +static inline const cpumask_t *_node_to_cpumask_ptr(int node) { return &cpu_online_map; } @@ -201,7 +201,7 @@ static inline int node_to_first_cpu(int node) /* Replace default node_to_cpumask_ptr with optimized version */ #define node_to_cpumask_ptr(v, node) \ - cpumask_t *v = _node_to_cpumask_ptr(node) + const cpumask_t *v = _node_to_cpumask_ptr(node) #define node_to_cpumask_ptr_next(v, node) \ v = _node_to_cpumask_ptr(node) -- cgit v0.10.2 From 0302c01b4b793cfbc5c7bf8723f6d14bf9bd7cf4 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sun, 13 Jul 2008 12:13:59 -0700 Subject: Documentation/HOWTO: correct wrong kernel bugzilla FAQ URL Signed-off-by: Jiri Pirko Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/HOWTO b/Documentation/HOWTO index 0291ade..619e8ca 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -377,7 +377,7 @@ Bug Reporting bugzilla.kernel.org is where the Linux kernel developers track kernel bugs. Users are encouraged to report all bugs that they find in this tool. For details on how to use the kernel bugzilla, please see: - http://test.kernel.org/bugzilla/faq.html + http://bugzilla.kernel.org/page.cgi?id=faq.html The file REPORTING-BUGS in the main kernel source directory has a good template for how to report a possible kernel bug, and details what kind -- cgit v0.10.2 From 17d213f806dad629e9af36fc45f082b87ed7bceb Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sun, 13 Jul 2008 12:14:02 -0700 Subject: devcgroup: always show positive major/minor num # echo "b $((0x7fffffff)):$((0x80000000)) rwm" > devices.allow # cat devices.list b 214748364:-21474836 rwm though a major/minor number of 0x800000000 is meaningless, we should not cast it to a negative value. Signed-off-by: Li Zefan Acked-by: Serge Hallyn Cc: Serge Hallyn Cc: Paul Menage Cc: Pavel Emelyanov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/security/device_cgroup.c b/security/device_cgroup.c index fd764a0..1e2e28a 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -222,7 +222,7 @@ static void devcgroup_destroy(struct cgroup_subsys *ss, #define DEVCG_DENY 2 #define DEVCG_LIST 3 -#define MAJMINLEN 10 +#define MAJMINLEN 13 #define ACCLEN 4 static void set_access(char *acc, short access) @@ -254,7 +254,7 @@ static void set_majmin(char *str, unsigned m) if (m == ~0) sprintf(str, "*"); else - snprintf(str, MAJMINLEN, "%d", m); + snprintf(str, MAJMINLEN, "%u", m); } static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, -- cgit v0.10.2 From ec229e830060091b9be63c8f873c1b2407a82821 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sun, 13 Jul 2008 12:14:04 -0700 Subject: devcgroup: fix permission check when adding entry to child cgroup # cat devices.list c 1:3 r # echo 'c 1:3 w' > sub/devices.allow # cat sub/devices.list c 1:3 w As illustrated, the parent group has no write permission to /dev/null, so it's child should not be allowed to add this write permission. Signed-off-by: Li Zefan Acked-by: Serge Hallyn Cc: Serge Hallyn Cc: Paul Menage Cc: Pavel Emelyanov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 1e2e28a..ddd92ce 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -300,7 +300,7 @@ static int may_access_whitelist(struct dev_cgroup *c, continue; if (whitem->minor != ~0 && whitem->minor != refwh->minor) continue; - if (refwh->access & (~(whitem->access | ACC_MASK))) + if (refwh->access & (~whitem->access)) continue; return 1; } -- cgit v0.10.2 From 199a952876adbfc2b6c13b8b07adabebf4ff54b2 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 26 Jun 2008 10:06:43 +0800 Subject: rcu classic: update qlen when cpu offline When callbacks are moved from offline cpu to this cpu, the qlen field of this rdp should be updated. [ Paul E. McKenney: ] The effect of this bug would be for force_quiescent_state() to be invoked when it should not and vice versa -- wasting cycles in the first case and letting RCU callbacks remain piled up in the second case. The bug is thus "benign" in that it does not result in premature grace-period termination, but should of course be fixed nonetheless. Preemption is disabled by the caller's get_cpu_var(), so we are guaranteed to remain on the same CPU, as required. The local_irq_disable() is indeed needed, otherwise, an interrupt might invoke call_rcu() or call_rcu_bh(), which could cause that interrupt's increment of ->qlen to be lost. Signed-off-by: Lai Jiangshan Cc: Andrew Morton Reviewed-by: Paul E. McKenney Signed-off-by: Ingo Molnar diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index 214e1cd..529190c 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c @@ -387,6 +387,10 @@ static void __rcu_offline_cpu(struct rcu_data *this_rdp, rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail); rcu_move_batch(this_rdp, rdp->curlist, rdp->curtail); rcu_move_batch(this_rdp, rdp->nxtlist, rdp->nxttail); + + local_irq_disable(); + this_rdp->qlen += rdp->qlen; + local_irq_enable(); } static void rcu_offline_cpu(int cpu) -- cgit v0.10.2 From bce7f793daec3e65ec5c5705d2457b81fe7b5725 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 13 Jul 2008 14:51:29 -0700 Subject: Linux 2.6.26 diff --git a/Makefile b/Makefile index 6315424..e3c5eb6 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 -EXTRAVERSION = -rc9 +EXTRAVERSION = NAME = Rotary Wombat # *DOCUMENTATION* -- cgit v0.10.2 From c0e09200dc0813972442e550a5905a132768e56c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2008 10:09:59 +1000 Subject: drm: reorganise drm tree to be more future proof. With the coming of kernel based modesetting and the memory manager stuff, the everything in one directory approach was getting very ugly and starting to be unmanageable. This restructures the drm along the lines of other kernel components. It creates a drivers/gpu/drm directory and moves the hw drivers into subdirectores. It moves the includes into an include/drm, and sets up the unifdef for the userspace headers we should be exporting. Signed-off-by: Dave Airlie diff --git a/drivers/Makefile b/drivers/Makefile index f65deda..fda4467 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ +obj-y += gpu/ obj-$(CONFIG_ACPI) += acpi/ # PnP must come after ACPI since it will eventually need to check if acpi # was used and do nothing if so diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 4c1c584..81630a6 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -101,7 +101,6 @@ obj-$(CONFIG_TELCLOCK) += tlclk.o obj-$(CONFIG_MWAVE) += mwave/ obj-$(CONFIG_AGP) += agp/ -obj-$(CONFIG_DRM) += drm/ obj-$(CONFIG_PCMCIA) += pcmcia/ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig deleted file mode 100644 index 610d6fd..0000000 --- a/drivers/char/drm/Kconfig +++ /dev/null @@ -1,107 +0,0 @@ -# -# Drm device configuration -# -# This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -# -menuconfig DRM - tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" - depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG - help - Kernel-level support for the Direct Rendering Infrastructure (DRI) - introduced in XFree86 4.0. If you say Y here, you need to select - the module that's right for your graphics card from the list below. - These modules provide support for synchronization, security, and - DMA transfers. Please see for more - details. You should also select and configure AGP - (/dev/agpgart) support. - -config DRM_TDFX - tristate "3dfx Banshee/Voodoo3+" - depends on DRM && PCI - help - Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), - graphics card. If M is selected, the module will be called tdfx. - -config DRM_R128 - tristate "ATI Rage 128" - depends on DRM && PCI - help - Choose this option if you have an ATI Rage 128 graphics card. If M - is selected, the module will be called r128. AGP support for - this card is strongly suggested (unless you have a PCI version). - -config DRM_RADEON - tristate "ATI Radeon" - depends on DRM && PCI - help - Choose this option if you have an ATI Radeon graphics card. There - are both PCI and AGP versions. You don't need to choose this to - run the Radeon in plain VGA mode. - - If M is selected, the module will be called radeon. - -config DRM_I810 - tristate "Intel I810" - depends on DRM && AGP && AGP_INTEL - help - Choose this option if you have an Intel I810 graphics card. If M is - selected, the module will be called i810. AGP support is required - for this driver to work. - -choice - prompt "Intel 830M, 845G, 852GM, 855GM, 865G" - depends on DRM && AGP && AGP_INTEL - optional - -config DRM_I830 - tristate "i830 driver" - help - Choose this option if you have a system that has Intel 830M, 845G, - 852GM, 855GM or 865G integrated graphics. If M is selected, the - module will be called i830. AGP support is required for this driver - to work. This driver is used by the older X releases X.org 6.7 and - XFree86 4.3. If unsure, build this and i915 as modules and the X server - will load the correct one. - -config DRM_I915 - tristate "i915 driver" - help - Choose this option if you have a system that has Intel 830M, 845G, - 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the - module will be called i915. AGP support is required for this driver - to work. This driver is used by the Intel driver in X.org 6.8 and - 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_MGA - tristate "Matrox g200/g400" - depends on DRM - help - Choose this option if you have a Matrox G200, G400 or G450 graphics - card. If M is selected, the module will be called mga. AGP - support is required for this driver to work. - -config DRM_SIS - tristate "SiS video cards" - depends on DRM && AGP - help - Choose this option if you have a SiS 630 or compatible video - chipset. If M is selected the module will be called sis. AGP - support is required for this driver to work. - -config DRM_VIA - tristate "Via unichrome video cards" - depends on DRM - help - Choose this option if you have a Via unichrome or compatible video - chipset. If M is selected the module will be called via. - -config DRM_SAVAGE - tristate "Savage video cards" - depends on DRM - help - Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister - chipset. If M is selected the module will be called savage. diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile deleted file mode 100644 index 1283ded..0000000 --- a/drivers/char/drm/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ - drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ - drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ - drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o - -tdfx-objs := tdfx_drv.o -r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o -mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o -i810-objs := i810_drv.o i810_dma.o -i830-objs := i830_drv.o i830_dma.o i830_irq.o -i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o -sis-objs := sis_drv.o sis_mm.o -savage-objs := savage_drv.o savage_bci.o savage_state.o -via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o - -ifeq ($(CONFIG_COMPAT),y) -drm-objs += drm_ioc32.o -radeon-objs += radeon_ioc32.o -mga-objs += mga_ioc32.o -r128-objs += r128_ioc32.o -i915-objs += i915_ioc32.o -endif - -obj-$(CONFIG_DRM) += drm.o -obj-$(CONFIG_DRM_TDFX) += tdfx.o -obj-$(CONFIG_DRM_R128) += r128.o -obj-$(CONFIG_DRM_RADEON)+= radeon.o -obj-$(CONFIG_DRM_MGA) += mga.o -obj-$(CONFIG_DRM_I810) += i810.o -obj-$(CONFIG_DRM_I830) += i830.o -obj-$(CONFIG_DRM_I915) += i915.o -obj-$(CONFIG_DRM_SIS) += sis.o -obj-$(CONFIG_DRM_SAVAGE)+= savage.o -obj-$(CONFIG_DRM_VIA) +=via.o diff --git a/drivers/char/drm/README.drm b/drivers/char/drm/README.drm deleted file mode 100644 index b5b3327..0000000 --- a/drivers/char/drm/README.drm +++ /dev/null @@ -1,43 +0,0 @@ -************************************************************ -* For the very latest on DRI development, please see: * -* http://dri.freedesktop.org/ * -************************************************************ - -The Direct Rendering Manager (drm) is a device-independent kernel-level -device driver that provides support for the XFree86 Direct Rendering -Infrastructure (DRI). - -The DRM supports the Direct Rendering Infrastructure (DRI) in four major -ways: - - 1. The DRM provides synchronized access to the graphics hardware via - the use of an optimized two-tiered lock. - - 2. The DRM enforces the DRI security policy for access to the graphics - hardware by only allowing authenticated X11 clients access to - restricted regions of memory. - - 3. The DRM provides a generic DMA engine, complete with multiple - queues and the ability to detect the need for an OpenGL context - switch. - - 4. The DRM is extensible via the use of small device-specific modules - that rely extensively on the API exported by the DRM module. - - -Documentation on the DRI is available from: - http://dri.freedesktop.org/wiki/Documentation - http://sourceforge.net/project/showfiles.php?group_id=387 - http://dri.sourceforge.net/doc/ - -For specific information about kernel-level support, see: - - The Direct Rendering Manager, Kernel Support for the Direct Rendering - Infrastructure - http://dri.sourceforge.net/doc/drm_low_level.html - - Hardware Locking for the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/hardware_locking_low_level.html - - A Security Analysis of the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/security_low_level.html diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c deleted file mode 100644 index c533d0c..0000000 --- a/drivers/char/drm/ati_pcigart.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * \file ati_pcigart.c - * ATI PCI GART support - * - * \author Gareth Hughes - */ - -/* - * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ - -static int drm_ati_alloc_pcigart_table(struct drm_device *dev, - struct drm_ati_pcigart_info *gart_info) -{ - gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, - PAGE_SIZE, - gart_info->table_mask); - if (gart_info->table_handle == NULL) - return -ENOMEM; - - return 0; -} - -static void drm_ati_free_pcigart_table(struct drm_device *dev, - struct drm_ati_pcigart_info *gart_info) -{ - drm_pci_free(dev, gart_info->table_handle); - gart_info->table_handle = NULL; -} - -int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) -{ - struct drm_sg_mem *entry = dev->sg; - unsigned long pages; - int i; - int max_pages; - - /* we need to support large memory configurations */ - if (!entry) { - DRM_ERROR("no scatter/gather memory!\n"); - return 0; - } - - if (gart_info->bus_addr) { - - max_pages = (gart_info->table_size / sizeof(u32)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; - - for (i = 0; i < pages; i++) { - if (!entry->busaddr[i]) - break; - pci_unmap_page(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_TODEVICE); - } - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) - gart_info->bus_addr = 0; - } - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && - gart_info->table_handle) { - drm_ati_free_pcigart_table(dev, gart_info); - } - - return 1; -} -EXPORT_SYMBOL(drm_ati_pcigart_cleanup); - -int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) -{ - struct drm_sg_mem *entry = dev->sg; - void *address = NULL; - unsigned long pages; - u32 *pci_gart, page_base; - dma_addr_t bus_address = 0; - int i, j, ret = 0; - int max_pages; - - if (!entry) { - DRM_ERROR("no scatter/gather memory!\n"); - goto done; - } - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { - DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); - - ret = drm_ati_alloc_pcigart_table(dev, gart_info); - if (ret) { - DRM_ERROR("cannot allocate PCI GART page!\n"); - goto done; - } - - address = gart_info->table_handle->vaddr; - bus_address = gart_info->table_handle->busaddr; - } else { - address = gart_info->addr; - bus_address = gart_info->bus_addr; - DRM_DEBUG("PCI: Gart Table: VRAM %08LX mapped at %08lX\n", - (unsigned long long)bus_address, - (unsigned long)address); - } - - pci_gart = (u32 *) address; - - max_pages = (gart_info->table_size / sizeof(u32)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; - - memset(pci_gart, 0, max_pages * sizeof(u32)); - - for (i = 0; i < pages; i++) { - /* we need to support large memory configurations */ - entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i], - 0, PAGE_SIZE, PCI_DMA_TODEVICE); - if (entry->busaddr[i] == 0) { - DRM_ERROR("unable to map PCIGART pages!\n"); - drm_ati_pcigart_cleanup(dev, gart_info); - address = NULL; - bus_address = 0; - goto done; - } - page_base = (u32) entry->busaddr[i]; - - for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - switch(gart_info->gart_reg_if) { - case DRM_ATI_GART_IGP: - *pci_gart = cpu_to_le32((page_base) | 0xc); - break; - case DRM_ATI_GART_PCIE: - *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); - break; - default: - case DRM_ATI_GART_PCI: - *pci_gart = cpu_to_le32(page_base); - break; - } - pci_gart++; - page_base += ATI_PCIGART_PAGE_SIZE; - } - } - ret = 1; - -#if defined(__i386__) || defined(__x86_64__) - wbinvd(); -#else - mb(); -#endif - - done: - gart_info->addr = address; - gart_info->bus_addr = bus_address; - return ret; -} -EXPORT_SYMBOL(drm_ati_pcigart_init); diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h deleted file mode 100644 index 38d3c6b..0000000 --- a/drivers/char/drm/drm.h +++ /dev/null @@ -1,694 +0,0 @@ -/** - * \file drm.h - * Header for the Direct Rendering Manager - * - * \author Rickard E. (Rik) Faith - * - * \par Acknowledgments: - * Dec 1999, Richard Henderson , move to generic \c cmpxchg. - */ - -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _DRM_H_ -#define _DRM_H_ - -#if defined(__linux__) -#if defined(__KERNEL__) -#endif -#include /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_IOC_VOID _IOC_NONE -#define DRM_IOC_READ _IOC_READ -#define DRM_IOC_WRITE _IOC_WRITE -#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#if defined(__FreeBSD__) && defined(IN_MODULE) -/* Prevent name collision when including sys/ioccom.h */ -#undef ioctl -#include -#define ioctl(a,b,c) xf86ioctl(a,b,c) -#else -#include -#endif /* __FreeBSD__ && xf86ioctl */ -#define DRM_IOCTL_NR(n) ((n) & 0xff) -#define DRM_IOC_VOID IOC_VOID -#define DRM_IOC_READ IOC_OUT -#define DRM_IOC_WRITE IOC_IN -#define DRM_IOC_READWRITE IOC_INOUT -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -#endif - -#define DRM_MAJOR 226 -#define DRM_MAX_MINOR 15 - -#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ -#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ -#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ -#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ - -#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ -#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ -#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) -#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) -#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) - -typedef unsigned int drm_handle_t; -typedef unsigned int drm_context_t; -typedef unsigned int drm_drawable_t; -typedef unsigned int drm_magic_t; - -/** - * Cliprect. - * - * \warning: If you change this structure, make sure you change - * XF86DRIClipRectRec in the server as well - * - * \note KW: Actually it's illegal to change either for - * backwards-compatibility reasons. - */ -struct drm_clip_rect { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -}; - -/** - * Drawable information. - */ -struct drm_drawable_info { - unsigned int num_rects; - struct drm_clip_rect *rects; -}; - -/** - * Texture region, - */ -struct drm_tex_region { - unsigned char next; - unsigned char prev; - unsigned char in_use; - unsigned char padding; - unsigned int age; -}; - -/** - * Hardware lock. - * - * The lock structure is a simple cache-line aligned integer. To avoid - * processor bus contention on a multiprocessor system, there should not be any - * other data stored in the same cache line. - */ -struct drm_hw_lock { - __volatile__ unsigned int lock; /**< lock variable */ - char padding[60]; /**< Pad to cache line */ -}; - -/** - * DRM_IOCTL_VERSION ioctl argument type. - * - * \sa drmGetVersion(). - */ -struct drm_version { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - size_t name_len; /**< Length of name buffer */ - char __user *name; /**< Name of driver */ - size_t date_len; /**< Length of date buffer */ - char __user *date; /**< User-space buffer to hold date */ - size_t desc_len; /**< Length of desc buffer */ - char __user *desc; /**< User-space buffer to hold desc */ -}; - -/** - * DRM_IOCTL_GET_UNIQUE ioctl argument type. - * - * \sa drmGetBusid() and drmSetBusId(). - */ -struct drm_unique { - size_t unique_len; /**< Length of unique */ - char __user *unique; /**< Unique name for driver instantiation */ -}; - -struct drm_list { - int count; /**< Length of user-space structures */ - struct drm_version __user *version; -}; - -struct drm_block { - int unused; -}; - -/** - * DRM_IOCTL_CONTROL ioctl argument type. - * - * \sa drmCtlInstHandler() and drmCtlUninstHandler(). - */ -struct drm_control { - enum { - DRM_ADD_COMMAND, - DRM_RM_COMMAND, - DRM_INST_HANDLER, - DRM_UNINST_HANDLER - } func; - int irq; -}; - -/** - * Type of memory to map. - */ -enum drm_map_type { - _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ - _DRM_REGISTERS = 1, /**< no caching, no core dump */ - _DRM_SHM = 2, /**< shared, cached */ - _DRM_AGP = 3, /**< AGP/GART */ - _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ - _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ -}; - -/** - * Memory mapping flags. - */ -enum drm_map_flags { - _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ - _DRM_READ_ONLY = 0x02, - _DRM_LOCKED = 0x04, /**< shared, cached, locked */ - _DRM_KERNEL = 0x08, /**< kernel requires access */ - _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ - _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40, /**< Removable mapping */ - _DRM_DRIVER = 0x80 /**< Managed by driver */ -}; - -struct drm_ctx_priv_map { - unsigned int ctx_id; /**< Context requesting private mapping */ - void *handle; /**< Handle of map */ -}; - -/** - * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls - * argument type. - * - * \sa drmAddMap(). - */ -struct drm_map { - unsigned long offset; /**< Requested physical address (0 for SAREA)*/ - unsigned long size; /**< Requested physical size (bytes) */ - enum drm_map_type type; /**< Type of memory to map */ - enum drm_map_flags flags; /**< Flags */ - void *handle; /**< User-space: "Handle" to pass to mmap() */ - /**< Kernel-space: kernel-virtual address */ - int mtrr; /**< MTRR slot used */ - /* Private data */ -}; - -/** - * DRM_IOCTL_GET_CLIENT ioctl argument type. - */ -struct drm_client { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - unsigned long pid; /**< Process ID */ - unsigned long uid; /**< User ID */ - unsigned long magic; /**< Magic */ - unsigned long iocs; /**< Ioctl count */ -}; - -enum drm_stat_type { - _DRM_STAT_LOCK, - _DRM_STAT_OPENS, - _DRM_STAT_CLOSES, - _DRM_STAT_IOCTLS, - _DRM_STAT_LOCKS, - _DRM_STAT_UNLOCKS, - _DRM_STAT_VALUE, /**< Generic value */ - _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */ - _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */ - - _DRM_STAT_IRQ, /**< IRQ */ - _DRM_STAT_PRIMARY, /**< Primary DMA bytes */ - _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */ - _DRM_STAT_DMA, /**< DMA */ - _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ - _DRM_STAT_MISSED /**< Missed DMA opportunity */ - /* Add to the *END* of the list */ -}; - -/** - * DRM_IOCTL_GET_STATS ioctl argument type. - */ -struct drm_stats { - unsigned long count; - struct { - unsigned long value; - enum drm_stat_type type; - } data[15]; -}; - -/** - * Hardware locking flags. - */ -enum drm_lock_flags { - _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ - _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ - _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ - _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ - /* These *HALT* flags aren't supported yet - -- they will be used to support the - full-screen DGA-like mode. */ - _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ - _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ -}; - -/** - * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. - * - * \sa drmGetLock() and drmUnlock(). - */ -struct drm_lock { - int context; - enum drm_lock_flags flags; -}; - -/** - * DMA flags - * - * \warning - * These values \e must match xf86drm.h. - * - * \sa drm_dma. - */ -enum drm_dma_flags { - /* Flags for DMA buffer dispatch */ - _DRM_DMA_BLOCK = 0x01, /**< - * Block until buffer dispatched. - * - * \note The buffer may not yet have - * been processed by the hardware -- - * getting a hardware lock with the - * hardware quiescent will ensure - * that the buffer has been - * processed. - */ - _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ - _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ - - /* Flags for DMA buffer request */ - _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ - _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ - _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ -}; - -/** - * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. - * - * \sa drmAddBufs(). - */ -struct drm_buf_desc { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - enum { - _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ - _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ - _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ - _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ - _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ - } flags; - unsigned long agp_start; /**< - * Start address of where the AGP buffers are - * in the AGP aperture - */ -}; - -/** - * DRM_IOCTL_INFO_BUFS ioctl argument type. - */ -struct drm_buf_info { - int count; /**< Entries in list */ - struct drm_buf_desc __user *list; -}; - -/** - * DRM_IOCTL_FREE_BUFS ioctl argument type. - */ -struct drm_buf_free { - int count; - int __user *list; -}; - -/** - * Buffer information - * - * \sa drm_buf_map. - */ -struct drm_buf_pub { - int idx; /**< Index into the master buffer list */ - int total; /**< Buffer size */ - int used; /**< Amount of buffer in use (for DMA) */ - void __user *address; /**< Address of buffer */ -}; - -/** - * DRM_IOCTL_MAP_BUFS ioctl argument type. - */ -struct drm_buf_map { - int count; /**< Length of the buffer list */ - void __user *virtual; /**< Mmap'd area in user-virtual */ - struct drm_buf_pub __user *list; /**< Buffer information */ -}; - -/** - * DRM_IOCTL_DMA ioctl argument type. - * - * Indices here refer to the offset into the buffer list in drm_buf_get. - * - * \sa drmDMA(). - */ -struct drm_dma { - int context; /**< Context handle */ - int send_count; /**< Number of buffers to send */ - int __user *send_indices; /**< List of handles to buffers */ - int __user *send_sizes; /**< Lengths of data to send */ - enum drm_dma_flags flags; /**< Flags */ - int request_count; /**< Number of buffers requested */ - int request_size; /**< Desired size for buffers */ - int __user *request_indices; /**< Buffer information */ - int __user *request_sizes; - int granted_count; /**< Number of buffers granted */ -}; - -enum drm_ctx_flags { - _DRM_CONTEXT_PRESERVED = 0x01, - _DRM_CONTEXT_2DONLY = 0x02 -}; - -/** - * DRM_IOCTL_ADD_CTX ioctl argument type. - * - * \sa drmCreateContext() and drmDestroyContext(). - */ -struct drm_ctx { - drm_context_t handle; - enum drm_ctx_flags flags; -}; - -/** - * DRM_IOCTL_RES_CTX ioctl argument type. - */ -struct drm_ctx_res { - int count; - struct drm_ctx __user *contexts; -}; - -/** - * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. - */ -struct drm_draw { - drm_drawable_t handle; -}; - -/** - * DRM_IOCTL_UPDATE_DRAW ioctl argument type. - */ -typedef enum { - DRM_DRAWABLE_CLIPRECTS, -} drm_drawable_info_type_t; - -struct drm_update_draw { - drm_drawable_t handle; - unsigned int type; - unsigned int num; - unsigned long long data; -}; - -/** - * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. - */ -struct drm_auth { - drm_magic_t magic; -}; - -/** - * DRM_IOCTL_IRQ_BUSID ioctl argument type. - * - * \sa drmGetInterruptFromBusID(). - */ -struct drm_irq_busid { - int irq; /**< IRQ number */ - int busnum; /**< bus number */ - int devnum; /**< device number */ - int funcnum; /**< function number */ -}; - -enum drm_vblank_seq_type { - _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ - _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ - _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ - _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ - _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ -}; - -#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) -#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ - _DRM_VBLANK_NEXTONMISS) - -struct drm_wait_vblank_request { - enum drm_vblank_seq_type type; - unsigned int sequence; - unsigned long signal; -}; - -struct drm_wait_vblank_reply { - enum drm_vblank_seq_type type; - unsigned int sequence; - long tval_sec; - long tval_usec; -}; - -/** - * DRM_IOCTL_WAIT_VBLANK ioctl argument type. - * - * \sa drmWaitVBlank(). - */ -union drm_wait_vblank { - struct drm_wait_vblank_request request; - struct drm_wait_vblank_reply reply; -}; - -/** - * DRM_IOCTL_AGP_ENABLE ioctl argument type. - * - * \sa drmAgpEnable(). - */ -struct drm_agp_mode { - unsigned long mode; /**< AGP mode */ -}; - -/** - * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. - * - * \sa drmAgpAlloc() and drmAgpFree(). - */ -struct drm_agp_buffer { - unsigned long size; /**< In bytes -- will round to page boundary */ - unsigned long handle; /**< Used for binding / unbinding */ - unsigned long type; /**< Type of memory to allocate */ - unsigned long physical; /**< Physical used by i810 */ -}; - -/** - * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. - * - * \sa drmAgpBind() and drmAgpUnbind(). - */ -struct drm_agp_binding { - unsigned long handle; /**< From drm_agp_buffer */ - unsigned long offset; /**< In bytes -- will round to page boundary */ -}; - -/** - * DRM_IOCTL_AGP_INFO ioctl argument type. - * - * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(), - * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), - * drmAgpVendorId() and drmAgpDeviceId(). - */ -struct drm_agp_info { - int agp_version_major; - int agp_version_minor; - unsigned long mode; - unsigned long aperture_base; /* physical address */ - unsigned long aperture_size; /* bytes */ - unsigned long memory_allowed; /* bytes */ - unsigned long memory_used; - - /* PCI information */ - unsigned short id_vendor; - unsigned short id_device; -}; - -/** - * DRM_IOCTL_SG_ALLOC ioctl argument type. - */ -struct drm_scatter_gather { - unsigned long size; /**< In bytes -- will round to page boundary */ - unsigned long handle; /**< Used for mapping / unmapping */ -}; - -/** - * DRM_IOCTL_SET_VERSION ioctl argument type. - */ -struct drm_set_version { - int drm_di_major; - int drm_di_minor; - int drm_dd_major; - int drm_dd_minor; -}; - -#define DRM_IOCTL_BASE 'd' -#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) -#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) -#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) - -#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version) -#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique) -#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth) -#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid) -#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map) -#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) -#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) -#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) - -#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) -#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) -#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) -#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block) -#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control) -#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map) -#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc) -#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc) -#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info) -#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map) -#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free) - -#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map) - -#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) -#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) - -#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) -#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) -#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) -#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx) -#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx) -#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx) -#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res) -#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw) -#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw) -#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma) -#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock) -#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) -#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) - -#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) -#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) -#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) -#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info) -#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer) -#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer) -#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) -#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) - -#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather) -#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) - -#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) - -#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) - -/** - * Device specific ioctls should only be in their respective headers - * The device specific ioctl range is from 0x40 to 0x99. - * Generic IOCTLS restart at 0xA0. - * - * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and - * drmCommandReadWrite(). - */ -#define DRM_COMMAND_BASE 0x40 -#define DRM_COMMAND_END 0xA0 - -/* typedef area */ -#ifndef __KERNEL__ -typedef struct drm_clip_rect drm_clip_rect_t; -typedef struct drm_drawable_info drm_drawable_info_t; -typedef struct drm_tex_region drm_tex_region_t; -typedef struct drm_hw_lock drm_hw_lock_t; -typedef struct drm_version drm_version_t; -typedef struct drm_unique drm_unique_t; -typedef struct drm_list drm_list_t; -typedef struct drm_block drm_block_t; -typedef struct drm_control drm_control_t; -typedef enum drm_map_type drm_map_type_t; -typedef enum drm_map_flags drm_map_flags_t; -typedef struct drm_ctx_priv_map drm_ctx_priv_map_t; -typedef struct drm_map drm_map_t; -typedef struct drm_client drm_client_t; -typedef enum drm_stat_type drm_stat_type_t; -typedef struct drm_stats drm_stats_t; -typedef enum drm_lock_flags drm_lock_flags_t; -typedef struct drm_lock drm_lock_t; -typedef enum drm_dma_flags drm_dma_flags_t; -typedef struct drm_buf_desc drm_buf_desc_t; -typedef struct drm_buf_info drm_buf_info_t; -typedef struct drm_buf_free drm_buf_free_t; -typedef struct drm_buf_pub drm_buf_pub_t; -typedef struct drm_buf_map drm_buf_map_t; -typedef struct drm_dma drm_dma_t; -typedef union drm_wait_vblank drm_wait_vblank_t; -typedef struct drm_agp_mode drm_agp_mode_t; -typedef enum drm_ctx_flags drm_ctx_flags_t; -typedef struct drm_ctx drm_ctx_t; -typedef struct drm_ctx_res drm_ctx_res_t; -typedef struct drm_draw drm_draw_t; -typedef struct drm_update_draw drm_update_draw_t; -typedef struct drm_auth drm_auth_t; -typedef struct drm_irq_busid drm_irq_busid_t; -typedef enum drm_vblank_seq_type drm_vblank_seq_type_t; - -typedef struct drm_agp_buffer drm_agp_buffer_t; -typedef struct drm_agp_binding drm_agp_binding_t; -typedef struct drm_agp_info drm_agp_info_t; -typedef struct drm_scatter_gather drm_scatter_gather_t; -typedef struct drm_set_version drm_set_version_t; -#endif - -#endif diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h deleted file mode 100644 index 0764b66..0000000 --- a/drivers/char/drm/drmP.h +++ /dev/null @@ -1,1153 +0,0 @@ -/** - * \file drmP.h - * Private header for Direct Rendering Manager - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _DRM_P_H_ -#define _DRM_P_H_ - -/* If you want the memory alloc debug functionality, change define below */ -/* #define DEBUG_MEMORY */ - -#ifdef __KERNEL__ -#ifdef __alpha__ -/* add include of current.h so that "current" is defined - * before static inline funcs in wait.h. Doing this so we - * can build the DRM (part of PI DRI). 4/21/2000 S + B */ -#include -#endif /* __alpha__ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* For (un)lock_kernel */ -#include -#include -#include -#include -#if defined(__alpha__) || defined(__powerpc__) -#include /* For pte_wrprotect */ -#endif -#include -#include -#include -#ifdef CONFIG_MTRR -#include -#endif -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) -#include -#include -#endif -#include -#include -#include -#include "drm.h" - -#include - -#define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE))) -#define __OS_HAS_MTRR (defined(CONFIG_MTRR)) - -struct drm_file; -struct drm_device; - -#include "drm_os_linux.h" -#include "drm_hashtab.h" - -/***********************************************************************/ -/** \name DRM template customization defaults */ -/*@{*/ - -/* driver capabilities and requirements mask */ -#define DRIVER_USE_AGP 0x1 -#define DRIVER_REQUIRE_AGP 0x2 -#define DRIVER_USE_MTRR 0x4 -#define DRIVER_PCI_DMA 0x8 -#define DRIVER_SG 0x10 -#define DRIVER_HAVE_DMA 0x20 -#define DRIVER_HAVE_IRQ 0x40 -#define DRIVER_IRQ_SHARED 0x80 -#define DRIVER_IRQ_VBL 0x100 -#define DRIVER_DMA_QUEUE 0x200 -#define DRIVER_FB_DMA 0x400 -#define DRIVER_IRQ_VBL2 0x800 - -/***********************************************************************/ -/** \name Begin the DRM... */ -/*@{*/ - -#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then - also include looping detection. */ - -#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */ -#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */ -#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */ -#define DRM_LOOPING_LIMIT 5000000 -#define DRM_TIME_SLICE (HZ/20) /**< Time slice for GLXContexts */ -#define DRM_LOCK_SLICE 1 /**< Time slice for lock, in jiffies */ - -#define DRM_FLAG_DEBUG 0x01 - -#define DRM_MEM_DMA 0 -#define DRM_MEM_SAREA 1 -#define DRM_MEM_DRIVER 2 -#define DRM_MEM_MAGIC 3 -#define DRM_MEM_IOCTLS 4 -#define DRM_MEM_MAPS 5 -#define DRM_MEM_VMAS 6 -#define DRM_MEM_BUFS 7 -#define DRM_MEM_SEGS 8 -#define DRM_MEM_PAGES 9 -#define DRM_MEM_FILES 10 -#define DRM_MEM_QUEUES 11 -#define DRM_MEM_CMDS 12 -#define DRM_MEM_MAPPINGS 13 -#define DRM_MEM_BUFLISTS 14 -#define DRM_MEM_AGPLISTS 15 -#define DRM_MEM_TOTALAGP 16 -#define DRM_MEM_BOUNDAGP 17 -#define DRM_MEM_CTXBITMAP 18 -#define DRM_MEM_STUB 19 -#define DRM_MEM_SGLISTS 20 -#define DRM_MEM_CTXLIST 21 -#define DRM_MEM_MM 22 -#define DRM_MEM_HASHTAB 23 - -#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) -#define DRM_MAP_HASH_OFFSET 0x10000000 - -/*@}*/ - -/***********************************************************************/ -/** \name Macros to make printk easier */ -/*@{*/ - -/** - * Error output. - * - * \param fmt printf() like format string. - * \param arg arguments - */ -#define DRM_ERROR(fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg) - -/** - * Memory error output. - * - * \param area memory area where the error occurred. - * \param fmt printf() like format string. - * \param arg arguments - */ -#define DRM_MEM_ERROR(area, fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __func__, \ - drm_mem_stats[area].name , ##arg) - -#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) - -/** - * Debug output. - * - * \param fmt printf() like format string. - * \param arg arguments - */ -#if DRM_DEBUG_CODE -#define DRM_DEBUG(fmt, arg...) \ - do { \ - if ( drm_debug ) \ - printk(KERN_DEBUG \ - "[" DRM_NAME ":%s] " fmt , \ - __func__ , ##arg); \ - } while (0) -#else -#define DRM_DEBUG(fmt, arg...) do { } while (0) -#endif - -#define DRM_PROC_LIMIT (PAGE_SIZE-80) - -#define DRM_PROC_PRINT(fmt, arg...) \ - len += sprintf(&buf[len], fmt , ##arg); \ - if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; } - -#define DRM_PROC_PRINT_RET(ret, fmt, arg...) \ - len += sprintf(&buf[len], fmt , ##arg); \ - if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } - -/*@}*/ - -/***********************************************************************/ -/** \name Internal types and structures */ -/*@{*/ - -#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x) - -#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) -#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) -#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist) - -#define DRM_IF_VERSION(maj, min) (maj << 16 | min) -/** - * Get the private SAREA mapping. - * - * \param _dev DRM device. - * \param _ctx context number. - * \param _map output mapping. - */ -#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \ - (_map) = (_dev)->context_sareas[_ctx]; \ -} while(0) - -/** - * Test that the hardware lock is held by the caller, returning otherwise. - * - * \param dev DRM device. - * \param filp file pointer of the caller. - */ -#define LOCK_TEST_WITH_RETURN( dev, file_priv ) \ -do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.file_priv != file_priv ) { \ - DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ - __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\ - dev->lock.file_priv, file_priv ); \ - return -EINVAL; \ - } \ -} while (0) - -/** - * Copy and IOCTL return string to user space - */ -#define DRM_COPY( name, value ) \ - len = strlen( value ); \ - if ( len > name##_len ) len = name##_len; \ - name##_len = strlen( value ); \ - if ( len && name ) { \ - if ( copy_to_user( name, value, len ) ) \ - return -EFAULT; \ - } - -/** - * Ioctl function type. - * - * \param inode device inode. - * \param file_priv DRM file private pointer. - * \param cmd command. - * \param arg argument. - */ -typedef int drm_ioctl_t(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, - unsigned long arg); - -#define DRM_AUTH 0x1 -#define DRM_MASTER 0x2 -#define DRM_ROOT_ONLY 0x4 - -struct drm_ioctl_desc { - unsigned int cmd; - drm_ioctl_t *func; - int flags; -}; - -/** - * Creates a driver or general drm_ioctl_desc array entry for the given - * ioctl, for use by drm_ioctl(). - */ -#define DRM_IOCTL_DEF(ioctl, func, flags) \ - [DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags} - -struct drm_magic_entry { - struct list_head head; - struct drm_hash_item hash_item; - struct drm_file *priv; -}; - -struct drm_vma_entry { - struct list_head head; - struct vm_area_struct *vma; - pid_t pid; -}; - -/** - * DMA buffer. - */ -struct drm_buf { - int idx; /**< Index into master buflist */ - int total; /**< Buffer size */ - int order; /**< log-base-2(total) */ - int used; /**< Amount of buffer in use (for DMA) */ - unsigned long offset; /**< Byte offset (used internally) */ - void *address; /**< Address of buffer */ - unsigned long bus_address; /**< Bus address of buffer */ - struct drm_buf *next; /**< Kernel-only: used for free list */ - __volatile__ int waiting; /**< On kernel DMA queue */ - __volatile__ int pending; /**< On hardware DMA queue */ - wait_queue_head_t dma_wait; /**< Processes waiting */ - struct drm_file *file_priv; /**< Private of holding file descr */ - int context; /**< Kernel queue for this buffer */ - int while_locked; /**< Dispatch this buffer while locked */ - enum { - DRM_LIST_NONE = 0, - DRM_LIST_FREE = 1, - DRM_LIST_WAIT = 2, - DRM_LIST_PEND = 3, - DRM_LIST_PRIO = 4, - DRM_LIST_RECLAIM = 5 - } list; /**< Which list we're on */ - - int dev_priv_size; /**< Size of buffer private storage */ - void *dev_private; /**< Per-buffer private storage */ -}; - -/** bufs is one longer than it has to be */ -struct drm_waitlist { - int count; /**< Number of possible buffers */ - struct drm_buf **bufs; /**< List of pointers to buffers */ - struct drm_buf **rp; /**< Read pointer */ - struct drm_buf **wp; /**< Write pointer */ - struct drm_buf **end; /**< End pointer */ - spinlock_t read_lock; - spinlock_t write_lock; -}; - -struct drm_freelist { - int initialized; /**< Freelist in use */ - atomic_t count; /**< Number of free buffers */ - struct drm_buf *next; /**< End pointer */ - - wait_queue_head_t waiting; /**< Processes waiting on free bufs */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - atomic_t wfh; /**< If waiting for high mark */ - spinlock_t lock; -}; - -typedef struct drm_dma_handle { - dma_addr_t busaddr; - void *vaddr; - size_t size; -} drm_dma_handle_t; - -/** - * Buffer entry. There is one of this for each buffer size order. - */ -struct drm_buf_entry { - int buf_size; /**< size */ - int buf_count; /**< number of buffers */ - struct drm_buf *buflist; /**< buffer list */ - int seg_count; - int page_order; - struct drm_dma_handle **seglist; - - struct drm_freelist freelist; -}; - -/** File private data */ -struct drm_file { - int authenticated; - int master; - pid_t pid; - uid_t uid; - drm_magic_t magic; - unsigned long ioctl_count; - struct list_head lhead; - struct drm_minor *minor; - int remove_auth_on_close; - unsigned long lock_count; - struct file *filp; - void *driver_priv; -}; - -/** Wait queue */ -struct drm_queue { - atomic_t use_count; /**< Outstanding uses (+1) */ - atomic_t finalization; /**< Finalization in progress */ - atomic_t block_count; /**< Count of processes waiting */ - atomic_t block_read; /**< Queue blocked for reads */ - wait_queue_head_t read_queue; /**< Processes waiting on block_read */ - atomic_t block_write; /**< Queue blocked for writes */ - wait_queue_head_t write_queue; /**< Processes waiting on block_write */ - atomic_t total_queued; /**< Total queued statistic */ - atomic_t total_flushed; /**< Total flushes statistic */ - atomic_t total_locks; /**< Total locks statistics */ - enum drm_ctx_flags flags; /**< Context preserving and 2D-only */ - struct drm_waitlist waitlist; /**< Pending buffers */ - wait_queue_head_t flush_queue; /**< Processes waiting until flush */ -}; - -/** - * Lock data. - */ -struct drm_lock_data { - struct drm_hw_lock *hw_lock; /**< Hardware lock */ - /** Private of lock holder's file (NULL=kernel) */ - struct drm_file *file_priv; - wait_queue_head_t lock_queue; /**< Queue of blocked processes */ - unsigned long lock_time; /**< Time of last lock in jiffies */ - spinlock_t spinlock; - uint32_t kernel_waiters; - uint32_t user_waiters; - int idle_has_lock; -}; - -/** - * DMA data. - */ -struct drm_device_dma { - - struct drm_buf_entry bufs[DRM_MAX_ORDER + 1]; /**< buffers, grouped by their size order */ - int buf_count; /**< total number of buffers */ - struct drm_buf **buflist; /**< Vector of pointers into drm_device_dma::bufs */ - int seg_count; - int page_count; /**< number of pages */ - unsigned long *pagelist; /**< page list */ - unsigned long byte_count; - enum { - _DRM_DMA_USE_AGP = 0x01, - _DRM_DMA_USE_SG = 0x02, - _DRM_DMA_USE_FB = 0x04, - _DRM_DMA_USE_PCI_RO = 0x08 - } flags; - -}; - -/** - * AGP memory entry. Stored as a doubly linked list. - */ -struct drm_agp_mem { - unsigned long handle; /**< handle */ - DRM_AGP_MEM *memory; - unsigned long bound; /**< address */ - int pages; - struct list_head head; -}; - -/** - * AGP data. - * - * \sa drm_agp_init() and drm_device::agp. - */ -struct drm_agp_head { - DRM_AGP_KERN agp_info; /**< AGP device information */ - struct list_head memory; - unsigned long mode; /**< AGP mode */ - struct agp_bridge_data *bridge; - int enabled; /**< whether the AGP bus as been enabled */ - int acquired; /**< whether the AGP device has been acquired */ - unsigned long base; - int agp_mtrr; - int cant_use_aperture; - unsigned long page_mask; -}; - -/** - * Scatter-gather memory. - */ -struct drm_sg_mem { - unsigned long handle; - void *virtual; - int pages; - struct page **pagelist; - dma_addr_t *busaddr; -}; - -struct drm_sigdata { - int context; - struct drm_hw_lock *lock; -}; - - -/* - * Generic memory manager structs - */ - -struct drm_mm_node { - struct list_head fl_entry; - struct list_head ml_entry; - int free; - unsigned long start; - unsigned long size; - struct drm_mm *mm; - void *private; -}; - -struct drm_mm { - struct list_head fl_entry; - struct list_head ml_entry; -}; - - -/** - * Mappings list - */ -struct drm_map_list { - struct list_head head; /**< list head */ - struct drm_hash_item hash; - struct drm_map *map; /**< mapping */ - uint64_t user_token; -}; - -typedef struct drm_map drm_local_map_t; - -/** - * Context handle list - */ -struct drm_ctx_list { - struct list_head head; /**< list head */ - drm_context_t handle; /**< context handle */ - struct drm_file *tag; /**< associated fd private data */ -}; - -struct drm_vbl_sig { - struct list_head head; - unsigned int sequence; - struct siginfo info; - struct task_struct *task; -}; - -/* location of GART table */ -#define DRM_ATI_GART_MAIN 1 -#define DRM_ATI_GART_FB 2 - -#define DRM_ATI_GART_PCI 1 -#define DRM_ATI_GART_PCIE 2 -#define DRM_ATI_GART_IGP 3 - -struct drm_ati_pcigart_info { - int gart_table_location; - int gart_reg_if; - void *addr; - dma_addr_t bus_addr; - dma_addr_t table_mask; - struct drm_dma_handle *table_handle; - drm_local_map_t mapping; - int table_size; -}; - -/** - * DRM driver structure. This structure represent the common code for - * a family of cards. There will one drm_device for each card present - * in this family - */ -struct drm_driver { - int (*load) (struct drm_device *, unsigned long flags); - int (*firstopen) (struct drm_device *); - int (*open) (struct drm_device *, struct drm_file *); - void (*preclose) (struct drm_device *, struct drm_file *file_priv); - void (*postclose) (struct drm_device *, struct drm_file *); - void (*lastclose) (struct drm_device *); - int (*unload) (struct drm_device *); - int (*suspend) (struct drm_device *, pm_message_t state); - int (*resume) (struct drm_device *); - int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); - void (*dma_ready) (struct drm_device *); - int (*dma_quiescent) (struct drm_device *); - int (*context_ctor) (struct drm_device *dev, int context); - int (*context_dtor) (struct drm_device *dev, int context); - int (*kernel_context_switch) (struct drm_device *dev, int old, - int new); - void (*kernel_context_switch_unlock) (struct drm_device *dev); - int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); - int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); - int (*dri_library_name) (struct drm_device *dev, char *buf); - - /** - * Called by \c drm_device_is_agp. Typically used to determine if a - * card is really attached to AGP or not. - * - * \param dev DRM device handle - * - * \returns - * One of three values is returned depending on whether or not the - * card is absolutely \b not AGP (return of 0), absolutely \b is AGP - * (return of 1), or may or may not be AGP (return of 2). - */ - int (*device_is_agp) (struct drm_device *dev); - - /* these have to be filled in */ - - irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); - void (*irq_preinstall) (struct drm_device *dev); - void (*irq_postinstall) (struct drm_device *dev); - void (*irq_uninstall) (struct drm_device *dev); - void (*reclaim_buffers) (struct drm_device *dev, - struct drm_file * file_priv); - void (*reclaim_buffers_locked) (struct drm_device *dev, - struct drm_file *file_priv); - void (*reclaim_buffers_idlelocked) (struct drm_device *dev, - struct drm_file *file_priv); - unsigned long (*get_map_ofs) (struct drm_map * map); - unsigned long (*get_reg_ofs) (struct drm_device *dev); - void (*set_version) (struct drm_device *dev, - struct drm_set_version *sv); - - int major; - int minor; - int patchlevel; - char *name; - char *desc; - char *date; - - u32 driver_features; - int dev_priv_size; - struct drm_ioctl_desc *ioctls; - int num_ioctls; - struct file_operations fops; - struct pci_driver pci_driver; -}; - -#define DRM_MINOR_UNASSIGNED 0 -#define DRM_MINOR_LEGACY 1 - -/** - * DRM minor structure. This structure represents a drm minor number. - */ -struct drm_minor { - int index; /**< Minor device number */ - int type; /**< Control or render */ - dev_t device; /**< Device number for mknod */ - struct device kdev; /**< Linux device */ - struct drm_device *dev; - struct proc_dir_entry *dev_root; /**< proc directory entry */ -}; - -/** - * DRM device structure. This structure represent a complete card that - * may contain multiple heads. - */ -struct drm_device { - char *unique; /**< Unique identifier: e.g., busid */ - int unique_len; /**< Length of unique field */ - char *devname; /**< For /proc/interrupts */ - int if_version; /**< Highest interface version set */ - - int blocked; /**< Blocked due to VC switch? */ - - /** \name Locks */ - /*@{ */ - spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ - struct mutex struct_mutex; /**< For others */ - /*@} */ - - /** \name Usage Counters */ - /*@{ */ - int open_count; /**< Outstanding files open */ - atomic_t ioctl_count; /**< Outstanding IOCTLs pending */ - atomic_t vma_count; /**< Outstanding vma areas open */ - int buf_use; /**< Buffers in use -- cannot alloc */ - atomic_t buf_alloc; /**< Buffer allocation in progress */ - /*@} */ - - /** \name Performance counters */ - /*@{ */ - unsigned long counters; - enum drm_stat_type types[15]; - atomic_t counts[15]; - /*@} */ - - /** \name Authentication */ - /*@{ */ - struct list_head filelist; - struct drm_open_hash magiclist; /**< magic hash table */ - struct list_head magicfree; - /*@} */ - - /** \name Memory management */ - /*@{ */ - struct list_head maplist; /**< Linked list of regions */ - int map_count; /**< Number of mappable regions */ - struct drm_open_hash map_hash; /**< User token hash table for maps */ - - /** \name Context handle management */ - /*@{ */ - struct list_head ctxlist; /**< Linked list of context handles */ - int ctx_count; /**< Number of context handles */ - struct mutex ctxlist_mutex; /**< For ctxlist */ - - struct idr ctx_idr; - - struct list_head vmalist; /**< List of vmas (for debugging) */ - struct drm_lock_data lock; /**< Information on hardware lock */ - /*@} */ - - /** \name DMA queues (contexts) */ - /*@{ */ - int queue_count; /**< Number of active DMA queues */ - int queue_reserved; /**< Number of reserved DMA queues */ - int queue_slots; /**< Actual length of queuelist */ - struct drm_queue **queuelist; /**< Vector of pointers to DMA queues */ - struct drm_device_dma *dma; /**< Optional pointer for DMA support */ - /*@} */ - - /** \name Context support */ - /*@{ */ - int irq; /**< Interrupt used by board */ - int irq_enabled; /**< True if irq handler is enabled */ - __volatile__ long context_flag; /**< Context swapping flag */ - __volatile__ long interrupt_flag; /**< Interruption handler flag */ - __volatile__ long dma_flag; /**< DMA dispatch flag */ - struct timer_list timer; /**< Timer for delaying ctx switch */ - wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */ - int last_checked; /**< Last context checked for DMA */ - int last_context; /**< Last current context */ - unsigned long last_switch; /**< jiffies at last context switch */ - /*@} */ - - struct work_struct work; - /** \name VBLANK IRQ support */ - /*@{ */ - - wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ - atomic_t vbl_received; - atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ - spinlock_t vbl_lock; - struct list_head vbl_sigs; /**< signal list to send on VBLANK */ - struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ - unsigned int vbl_pending; - spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ - void (*locked_tasklet_func)(struct drm_device *dev); - - /*@} */ - cycles_t ctx_start; - cycles_t lck_start; - - struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ - wait_queue_head_t buf_readers; /**< Processes waiting to read */ - wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */ - - struct drm_agp_head *agp; /**< AGP data */ - - struct pci_dev *pdev; /**< PCI device structure */ - int pci_vendor; /**< PCI vendor id */ - int pci_device; /**< PCI device id */ -#ifdef __alpha__ - struct pci_controller *hose; -#endif - struct drm_sg_mem *sg; /**< Scatter gather memory */ - void *dev_private; /**< device private data */ - struct drm_sigdata sigdata; /**< For block_all_signals */ - sigset_t sigmask; - - struct drm_driver *driver; - drm_local_map_t *agp_buffer_map; - unsigned int agp_buffer_token; - struct drm_minor *primary; /**< render type primary screen head */ - - /** \name Drawable information */ - /*@{ */ - spinlock_t drw_lock; - struct idr drw_idr; - /*@} */ -}; - -static __inline__ int drm_core_check_feature(struct drm_device *dev, - int feature) -{ - return ((dev->driver->driver_features & feature) ? 1 : 0); -} - -#ifdef __alpha__ -#define drm_get_pci_domain(dev) dev->hose->index -#else -#define drm_get_pci_domain(dev) 0 -#endif - -#if __OS_HAS_AGP -static inline int drm_core_has_AGP(struct drm_device *dev) -{ - return drm_core_check_feature(dev, DRIVER_USE_AGP); -} -#else -#define drm_core_has_AGP(dev) (0) -#endif - -#if __OS_HAS_MTRR -static inline int drm_core_has_MTRR(struct drm_device *dev) -{ - return drm_core_check_feature(dev, DRIVER_USE_MTRR); -} - -#define DRM_MTRR_WC MTRR_TYPE_WRCOMB - -static inline int drm_mtrr_add(unsigned long offset, unsigned long size, - unsigned int flags) -{ - return mtrr_add(offset, size, flags, 1); -} - -static inline int drm_mtrr_del(int handle, unsigned long offset, - unsigned long size, unsigned int flags) -{ - return mtrr_del(handle, offset, size); -} - -#else -#define drm_core_has_MTRR(dev) (0) - -#define DRM_MTRR_WC 0 - -static inline int drm_mtrr_add(unsigned long offset, unsigned long size, - unsigned int flags) -{ - return 0; -} - -static inline int drm_mtrr_del(int handle, unsigned long offset, - unsigned long size, unsigned int flags) -{ - return 0; -} -#endif - -/******************************************************************/ -/** \name Internal function definitions */ -/*@{*/ - - /* Driver support (drm_drv.h) */ -extern int drm_init(struct drm_driver *driver); -extern void drm_exit(struct drm_driver *driver); -extern int drm_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern long drm_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_lastclose(struct drm_device *dev); - - /* Device support (drm_fops.h) */ -extern int drm_open(struct inode *inode, struct file *filp); -extern int drm_stub_open(struct inode *inode, struct file *filp); -extern int drm_fasync(int fd, struct file *filp, int on); -extern int drm_release(struct inode *inode, struct file *filp); - - /* Mapping support (drm_vm.h) */ -extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); -extern unsigned long drm_core_get_map_ofs(struct drm_map * map); -extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); -extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); - - /* Memory management support (drm_memory.h) */ -#include "drm_memory.h" -extern void drm_mem_init(void); -extern int drm_mem_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); - -extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type); -extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); -extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); -extern int drm_unbind_agp(DRM_AGP_MEM * handle); - - /* Misc. IOCTL support (drm_ioctl.h) */ -extern int drm_irq_by_busid(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_getunique(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_setunique(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_getmap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_getclient(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_getstats(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_setversion(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_noop(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - /* Context IOCTL support (drm_context.h) */ -extern int drm_resctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_addctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_modctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_getctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_switchctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_newctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_rmctx(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern int drm_ctxbitmap_init(struct drm_device *dev); -extern void drm_ctxbitmap_cleanup(struct drm_device *dev); -extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle); - -extern int drm_setsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_getsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - /* Drawable IOCTL support (drm_drawable.h) */ -extern int drm_adddraw(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_rmdraw(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_update_drawable_info(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, - drm_drawable_t id); -extern void drm_drawable_free_all(struct drm_device *dev); - - /* Authentication IOCTL support (drm_auth.h) */ -extern int drm_getmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_authmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - /* Locking IOCTL support (drm_lock.h) */ -extern int drm_lock(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_unlock(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context); -extern int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context); -extern void drm_idlelock_take(struct drm_lock_data *lock_data); -extern void drm_idlelock_release(struct drm_lock_data *lock_data); - -/* - * These are exported to drivers so that they can implement fencing using - * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. - */ - -extern int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv); - - /* Buffer management support (drm_bufs.h) */ -extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request); -extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request); -extern int drm_addmap(struct drm_device *dev, unsigned int offset, - unsigned int size, enum drm_map_type type, - enum drm_map_flags flags, drm_local_map_t ** map_ptr); -extern int drm_addmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_rmmap(struct drm_device *dev, drm_local_map_t *map); -extern int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map); -extern int drm_rmmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_addbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_infobufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_markbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_freebufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_mapbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_order(unsigned long size); -extern unsigned long drm_get_resource_start(struct drm_device *dev, - unsigned int resource); -extern unsigned long drm_get_resource_len(struct drm_device *dev, - unsigned int resource); - - /* DMA support (drm_dma.h) */ -extern int drm_dma_setup(struct drm_device *dev); -extern void drm_dma_takedown(struct drm_device *dev); -extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf); -extern void drm_core_reclaim_buffers(struct drm_device *dev, - struct drm_file *filp); - - /* IRQ support (drm_irq.h) */ -extern int drm_control(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); -extern int drm_irq_uninstall(struct drm_device *dev); -extern void drm_driver_irq_preinstall(struct drm_device *dev); -extern void drm_driver_irq_postinstall(struct drm_device *dev); -extern void drm_driver_irq_uninstall(struct drm_device *dev); - -extern int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); -extern void drm_vbl_send_signals(struct drm_device *dev); -extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); - - /* AGP/GART support (drm_agpsupport.h) */ -extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); -extern int drm_agp_acquire(struct drm_device *dev); -extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_release(struct drm_device *dev); -extern int drm_agp_release_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode); -extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info); -extern int drm_agp_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request); -extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request); -extern int drm_agp_free_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request); -extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request); -extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type); -extern int drm_agp_free_memory(DRM_AGP_MEM * handle); -extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); -extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); - - /* Stub support (drm_stub.h) */ -extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver); -extern int drm_put_dev(struct drm_device *dev); -extern int drm_put_minor(struct drm_minor **minor); -extern unsigned int drm_debug; - -extern struct class *drm_class; -extern struct proc_dir_entry *drm_proc_root; - -extern struct idr drm_minors_idr; - -extern drm_local_map_t *drm_getsarea(struct drm_device *dev); - - /* Proc support (drm_proc.h) */ -extern int drm_proc_init(struct drm_minor *minor, int minor_id, - struct proc_dir_entry *root); -extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); - - /* Scatter Gather Support (drm_scatter.h) */ -extern void drm_sg_cleanup(struct drm_sg_mem * entry); -extern int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request); -extern int drm_sg_free(struct drm_device *dev, void *data, - struct drm_file *file_priv); - - /* ATI PCIGART support (ati_pcigart.h) */ -extern int drm_ati_pcigart_init(struct drm_device *dev, - struct drm_ati_pcigart_info * gart_info); -extern int drm_ati_pcigart_cleanup(struct drm_device *dev, - struct drm_ati_pcigart_info * gart_info); - -extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, - size_t align, dma_addr_t maxaddr); -extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); -extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); - - /* sysfs support (drm_sysfs.c) */ -struct drm_sysfs_class; -extern struct class *drm_sysfs_create(struct module *owner, char *name); -extern void drm_sysfs_destroy(void); -extern int drm_sysfs_device_add(struct drm_minor *minor); -extern void drm_sysfs_device_remove(struct drm_minor *minor); - -/* - * Basic memory manager support (drm_mm.c) - */ -extern struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, - unsigned long size, - unsigned alignment); -extern void drm_mm_put_block(struct drm_mm_node * cur); -extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, - unsigned alignment, int best_match); -extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size); -extern void drm_mm_takedown(struct drm_mm *mm); -extern int drm_mm_clean(struct drm_mm *mm); -extern unsigned long drm_mm_tail_space(struct drm_mm *mm); -extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size); -extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size); - -extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); -extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); - -static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, - unsigned int token) -{ - struct drm_map_list *_entry; - list_for_each_entry(_entry, &dev->maplist, head) - if (_entry->user_token == token) - return _entry->map; - return NULL; -} - -static __inline__ int drm_device_is_agp(struct drm_device *dev) -{ - if (dev->driver->device_is_agp != NULL) { - int err = (*dev->driver->device_is_agp) (dev); - - if (err != 2) { - return err; - } - } - - return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP); -} - -static __inline__ int drm_device_is_pcie(struct drm_device *dev) -{ - return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); -} - -static __inline__ void drm_core_dropmap(struct drm_map *map) -{ -} - -#ifndef DEBUG_MEMORY -/** Wrapper around kmalloc() */ -static __inline__ void *drm_alloc(size_t size, int area) -{ - return kmalloc(size, GFP_KERNEL); -} - -/** Wrapper around kfree() */ -static __inline__ void drm_free(void *pt, size_t size, int area) -{ - kfree(pt); -} - -/** Wrapper around kcalloc() */ -static __inline__ void *drm_calloc(size_t nmemb, size_t size, int area) -{ - return kcalloc(nmemb, size, GFP_KERNEL); -} -#else -extern void *drm_alloc(size_t size, int area); -extern void drm_free(void *pt, size_t size, int area); -extern void *drm_calloc(size_t nmemb, size_t size, int area); -#endif - -/*@}*/ - -#endif /* __KERNEL__ */ -#endif diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c deleted file mode 100644 index aefa5ac..0000000 --- a/drivers/char/drm/drm_agpsupport.c +++ /dev/null @@ -1,455 +0,0 @@ -/** - * \file drm_agpsupport.c - * DRM support for AGP/GART backend - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include - -#if __OS_HAS_AGP - -/** - * Get AGP information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a (output) drm_agp_info structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device has been initialized and acquired and fills in the - * drm_agp_info structure with the information in drm_agp_head::agp_info. - */ -int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info) -{ - DRM_AGP_KERN *kern; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - - kern = &dev->agp->agp_info; - info->agp_version_major = kern->version.major; - info->agp_version_minor = kern->version.minor; - info->mode = kern->mode; - info->aperture_base = kern->aper_base; - info->aperture_size = kern->aper_size * 1024 * 1024; - info->memory_allowed = kern->max_memory << PAGE_SHIFT; - info->memory_used = kern->current_memory << PAGE_SHIFT; - info->id_vendor = kern->device->vendor; - info->id_device = kern->device->device; - - return 0; -} - -EXPORT_SYMBOL(drm_agp_info); - -int drm_agp_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_info *info = data; - int err; - - err = drm_agp_info(dev, info); - if (err) - return err; - - return 0; -} - -/** - * Acquire the AGP device. - * - * \param dev DRM device that is to acquire AGP. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device hasn't been acquired before and calls - * \c agp_backend_acquire. - */ -int drm_agp_acquire(struct drm_device * dev) -{ - if (!dev->agp) - return -ENODEV; - if (dev->agp->acquired) - return -EBUSY; - if (!(dev->agp->bridge = agp_backend_acquire(dev->pdev))) - return -ENODEV; - dev->agp->acquired = 1; - return 0; -} - -EXPORT_SYMBOL(drm_agp_acquire); - -/** - * Acquire the AGP device (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device hasn't been acquired before and calls - * \c agp_backend_acquire. - */ -int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); -} - -/** - * Release the AGP device. - * - * \param dev DRM device that is to release AGP. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device has been acquired and calls \c agp_backend_release. - */ -int drm_agp_release(struct drm_device * dev) -{ - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - agp_backend_release(dev->agp->bridge); - dev->agp->acquired = 0; - return 0; -} -EXPORT_SYMBOL(drm_agp_release); - -int drm_agp_release_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return drm_agp_release(dev); -} - -/** - * Enable the AGP bus. - * - * \param dev DRM device that has previously acquired AGP. - * \param mode Requested AGP mode. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device has been acquired but not enabled, and calls - * \c agp_enable. - */ -int drm_agp_enable(struct drm_device * dev, struct drm_agp_mode mode) -{ - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - - dev->agp->mode = mode.mode; - agp_enable(dev->agp->bridge, mode.mode); - dev->agp->enabled = 1; - return 0; -} - -EXPORT_SYMBOL(drm_agp_enable); - -int drm_agp_enable_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_mode *mode = data; - - return drm_agp_enable(dev, *mode); -} - -/** - * Allocate AGP memory. - * - * \param inode device inode. - * \param file_priv file private pointer. - * \param cmd command. - * \param arg pointer to a drm_agp_buffer structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and has been acquired, allocates the - * memory via alloc_agp() and creates a drm_agp_mem entry for it. - */ -int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) -{ - struct drm_agp_mem *entry; - DRM_AGP_MEM *memory; - unsigned long pages; - u32 type; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) - return -ENOMEM; - - memset(entry, 0, sizeof(*entry)); - - pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; - type = (u32) request->type; - if (!(memory = drm_alloc_agp(dev, pages, type))) { - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); - return -ENOMEM; - } - - entry->handle = (unsigned long)memory->key + 1; - entry->memory = memory; - entry->bound = 0; - entry->pages = pages; - list_add(&entry->head, &dev->agp->memory); - - request->handle = entry->handle; - request->physical = memory->physical; - - return 0; -} -EXPORT_SYMBOL(drm_agp_alloc); - - -int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_buffer *request = data; - - return drm_agp_alloc(dev, request); -} - -/** - * Search for the AGP memory entry associated with a handle. - * - * \param dev DRM device structure. - * \param handle AGP memory handle. - * \return pointer to the drm_agp_mem structure associated with \p handle. - * - * Walks through drm_agp_head::memory until finding a matching handle. - */ -static struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device * dev, - unsigned long handle) -{ - struct drm_agp_mem *entry; - - list_for_each_entry(entry, &dev->agp->memory, head) { - if (entry->handle == handle) - return entry; - } - return NULL; -} - -/** - * Unbind AGP memory from the GATT (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_agp_binding structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and acquired, looks-up the AGP memory - * entry and passes it to the unbind_agp() function. - */ -int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) -{ - struct drm_agp_mem *entry; - int ret; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) - return -EINVAL; - if (!entry->bound) - return -EINVAL; - ret = drm_unbind_agp(entry->memory); - if (ret == 0) - entry->bound = 0; - return ret; -} -EXPORT_SYMBOL(drm_agp_unbind); - - -int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_binding *request = data; - - return drm_agp_unbind(dev, request); -} - -/** - * Bind AGP memory into the GATT (ioctl) - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_agp_binding structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and has been acquired and that no memory - * is currently bound into the GATT. Looks-up the AGP memory entry and passes - * it to bind_agp() function. - */ -int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) -{ - struct drm_agp_mem *entry; - int retcode; - int page; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) - return -EINVAL; - if (entry->bound) - return -EINVAL; - page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; - if ((retcode = drm_bind_agp(entry->memory, page))) - return retcode; - entry->bound = dev->agp->base + (page << PAGE_SHIFT); - DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", - dev->agp->base, entry->bound); - return 0; -} -EXPORT_SYMBOL(drm_agp_bind); - - -int drm_agp_bind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_binding *request = data; - - return drm_agp_bind(dev, request); -} - -/** - * Free AGP memory (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_agp_buffer structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and has been acquired and looks up the - * AGP memory entry. If the memory it's currently bound, unbind it via - * unbind_agp(). Frees it via free_agp() as well as the entry itself - * and unlinks from the doubly linked list it's inserted in. - */ -int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) -{ - struct drm_agp_mem *entry; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) - return -EINVAL; - if (entry->bound) - drm_unbind_agp(entry->memory); - - list_del(&entry->head); - - drm_free_agp(entry->memory, entry->pages); - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); - return 0; -} -EXPORT_SYMBOL(drm_agp_free); - - - -int drm_agp_free_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_buffer *request = data; - - return drm_agp_free(dev, request); -} - -/** - * Initialize the AGP resources. - * - * \return pointer to a drm_agp_head structure. - * - * Gets the drm_agp_t structure which is made available by the agpgart module - * via the inter_module_* functions. Creates and initializes a drm_agp_head - * structure. - */ -struct drm_agp_head *drm_agp_init(struct drm_device *dev) -{ - struct drm_agp_head *head = NULL; - - if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) - return NULL; - memset((void *)head, 0, sizeof(*head)); - head->bridge = agp_find_bridge(dev->pdev); - if (!head->bridge) { - if (!(head->bridge = agp_backend_acquire(dev->pdev))) { - drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); - return NULL; - } - agp_copy_info(head->bridge, &head->agp_info); - agp_backend_release(head->bridge); - } else { - agp_copy_info(head->bridge, &head->agp_info); - } - if (head->agp_info.chipset == NOT_SUPPORTED) { - drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); - return NULL; - } - INIT_LIST_HEAD(&head->memory); - head->cant_use_aperture = head->agp_info.cant_use_aperture; - head->page_mask = head->agp_info.page_mask; - head->base = head->agp_info.aper_base; - return head; -} - -/** Calls agp_allocate_memory() */ -DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge, - size_t pages, u32 type) -{ - return agp_allocate_memory(bridge, pages, type); -} - -/** Calls agp_free_memory() */ -int drm_agp_free_memory(DRM_AGP_MEM * handle) -{ - if (!handle) - return 0; - agp_free_memory(handle); - return 1; -} - -/** Calls agp_bind_memory() */ -int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start) -{ - if (!handle) - return -EINVAL; - return agp_bind_memory(handle, start); -} - -/** Calls agp_unbind_memory() */ -int drm_agp_unbind_memory(DRM_AGP_MEM * handle) -{ - if (!handle) - return -EINVAL; - return agp_unbind_memory(handle); -} - -#endif /* __OS_HAS_AGP */ diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c deleted file mode 100644 index a734627..0000000 --- a/drivers/char/drm/drm_auth.c +++ /dev/null @@ -1,190 +0,0 @@ -/** - * \file drm_auth.c - * IOCTLs for authentication - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -/** - * Find the file with the given magic number. - * - * \param dev DRM device. - * \param magic magic number. - * - * Searches in drm_device::magiclist within all files with the same hash key - * the one with matching magic number, while holding the drm_device::struct_mutex - * lock. - */ -static struct drm_file *drm_find_file(struct drm_device * dev, drm_magic_t magic) -{ - struct drm_file *retval = NULL; - struct drm_magic_entry *pt; - struct drm_hash_item *hash; - - mutex_lock(&dev->struct_mutex); - if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { - pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item); - retval = pt->priv; - } - mutex_unlock(&dev->struct_mutex); - return retval; -} - -/** - * Adds a magic number. - * - * \param dev DRM device. - * \param priv file private data. - * \param magic magic number. - * - * Creates a drm_magic_entry structure and appends to the linked list - * associated the magic number hash key in drm_device::magiclist, while holding - * the drm_device::struct_mutex lock. - */ -static int drm_add_magic(struct drm_device * dev, struct drm_file * priv, - drm_magic_t magic) -{ - struct drm_magic_entry *entry; - - DRM_DEBUG("%d\n", magic); - - entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); - if (!entry) - return -ENOMEM; - memset(entry, 0, sizeof(*entry)); - entry->priv = priv; - - entry->hash_item.key = (unsigned long)magic; - mutex_lock(&dev->struct_mutex); - drm_ht_insert_item(&dev->magiclist, &entry->hash_item); - list_add_tail(&entry->head, &dev->magicfree); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Remove a magic number. - * - * \param dev DRM device. - * \param magic magic number. - * - * Searches and unlinks the entry in drm_device::magiclist with the magic - * number hash key, while holding the drm_device::struct_mutex lock. - */ -static int drm_remove_magic(struct drm_device * dev, drm_magic_t magic) -{ - struct drm_magic_entry *pt; - struct drm_hash_item *hash; - - DRM_DEBUG("%d\n", magic); - - mutex_lock(&dev->struct_mutex); - if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item); - drm_ht_remove_item(&dev->magiclist, hash); - list_del(&pt->head); - mutex_unlock(&dev->struct_mutex); - - drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); - - return 0; -} - -/** - * Get a unique magic number (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a resulting drm_auth structure. - * \return zero on success, or a negative number on failure. - * - * If there is a magic number in drm_file::magic then use it, otherwise - * searches an unique non-zero magic number and add it associating it with \p - * file_priv. - */ -int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - static drm_magic_t sequence = 0; - static DEFINE_SPINLOCK(lock); - struct drm_auth *auth = data; - - /* Find unique magic */ - if (file_priv->magic) { - auth->magic = file_priv->magic; - } else { - do { - spin_lock(&lock); - if (!sequence) - ++sequence; /* reserve 0 */ - auth->magic = sequence++; - spin_unlock(&lock); - } while (drm_find_file(dev, auth->magic)); - file_priv->magic = auth->magic; - drm_add_magic(dev, file_priv, auth->magic); - } - - DRM_DEBUG("%u\n", auth->magic); - - return 0; -} - -/** - * Authenticate with a magic. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_auth structure. - * \return zero if authentication successed, or a negative number otherwise. - * - * Checks if \p file_priv is associated with the magic number passed in \arg. - */ -int drm_authmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_auth *auth = data; - struct drm_file *file; - - DRM_DEBUG("%u\n", auth->magic); - if ((file = drm_find_file(dev, auth->magic))) { - file->authenticated = 1; - drm_remove_magic(dev, auth->magic); - return 0; - } - return -EINVAL; -} diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c deleted file mode 100644 index bde64b8..0000000 --- a/drivers/char/drm/drm_bufs.c +++ /dev/null @@ -1,1601 +0,0 @@ -/** - * \file drm_bufs.c - * Generic buffer template - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource) -{ - return pci_resource_start(dev->pdev, resource); -} -EXPORT_SYMBOL(drm_get_resource_start); - -unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource) -{ - return pci_resource_len(dev->pdev, resource); -} - -EXPORT_SYMBOL(drm_get_resource_len); - -static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, - drm_local_map_t *map) -{ - struct drm_map_list *entry; - list_for_each_entry(entry, &dev->maplist, head) { - if (entry->map && map->type == entry->map->type && - ((entry->map->offset == map->offset) || - (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { - return entry; - } - } - - return NULL; -} - -static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, - unsigned long user_token, int hashed_handle) -{ - int use_hashed_handle; -#if (BITS_PER_LONG == 64) - use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle); -#elif (BITS_PER_LONG == 32) - use_hashed_handle = hashed_handle; -#else -#error Unsupported long size. Neither 64 nor 32 bits. -#endif - - if (!use_hashed_handle) { - int ret; - hash->key = user_token >> PAGE_SHIFT; - ret = drm_ht_insert_item(&dev->map_hash, hash); - if (ret != -EINVAL) - return ret; - } - return drm_ht_just_insert_please(&dev->map_hash, hash, - user_token, 32 - PAGE_SHIFT - 3, - 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT); -} - -/** - * Ioctl to specify a range of memory that is available for mapping by a non-root process. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_map structure. - * \return zero on success or a negative value on error. - * - * Adjusts the memory offset to its absolute value according to the mapping - * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where - * applicable and if supported by the kernel. - */ -static int drm_addmap_core(struct drm_device * dev, unsigned int offset, - unsigned int size, enum drm_map_type type, - enum drm_map_flags flags, - struct drm_map_list ** maplist) -{ - struct drm_map *map; - struct drm_map_list *list; - drm_dma_handle_t *dmah; - unsigned long user_token; - int ret; - - map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); - if (!map) - return -ENOMEM; - - map->offset = offset; - map->size = size; - map->flags = flags; - map->type = type; - - /* Only allow shared memory to be removable since we only keep enough - * book keeping information about shared memory to allow for removal - * when processes fork. - */ - if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } - DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", - map->offset, map->size, map->type); - if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } - map->mtrr = -1; - map->handle = NULL; - - switch (map->type) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) - if (map->offset + (map->size-1) < map->offset || - map->offset < virt_to_phys(high_memory)) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } -#endif -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif - /* Some drivers preinitialize some maps, without the X Server - * needing to be aware of it. Therefore, we just return success - * when the server tries to create a duplicate map. - */ - list = drm_find_matching_map(dev, map); - if (list != NULL) { - if (list->map->size != map->size) { - DRM_DEBUG("Matching maps of type %d with " - "mismatched sizes, (%ld vs %ld)\n", - map->type, map->size, - list->map->size); - list->map->size = map->size; - } - - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - *maplist = list; - return 0; - } - - if (drm_core_has_MTRR(dev)) { - if (map->type == _DRM_FRAME_BUFFER || - (map->flags & _DRM_WRITE_COMBINING)) { - map->mtrr = mtrr_add(map->offset, map->size, - MTRR_TYPE_WRCOMB, 1); - } - } - if (map->type == _DRM_REGISTERS) { - map->handle = ioremap(map->offset, map->size); - if (!map->handle) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -ENOMEM; - } - } - - break; - case _DRM_SHM: - list = drm_find_matching_map(dev, map); - if (list != NULL) { - if(list->map->size != map->size) { - DRM_DEBUG("Matching maps of type %d with " - "mismatched sizes, (%ld vs %ld)\n", - map->type, map->size, list->map->size); - list->map->size = map->size; - } - - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - *maplist = list; - return 0; - } - map->handle = vmalloc_user(map->size); - DRM_DEBUG("%lu %d %p\n", - map->size, drm_order(map->size), map->handle); - if (!map->handle) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -ENOMEM; - } - map->offset = (unsigned long)map->handle; - if (map->flags & _DRM_CONTAINS_LOCK) { - /* Prevent a 2nd X Server from creating a 2nd lock */ - if (dev->lock.hw_lock != NULL) { - vfree(map->handle); - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EBUSY; - } - dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ - } - break; - case _DRM_AGP: { - struct drm_agp_mem *entry; - int valid = 0; - - if (!drm_core_has_AGP(dev)) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif - /* In some cases (i810 driver), user space may have already - * added the AGP base itself, because dev->agp->base previously - * only got set during AGP enable. So, only add the base - * address if the map's offset isn't already within the - * aperture. - */ - if (map->offset < dev->agp->base || - map->offset > dev->agp->base + - dev->agp->agp_info.aper_size * 1024 * 1024 - 1) { - map->offset += dev->agp->base; - } - map->mtrr = dev->agp->agp_mtrr; /* for getmap */ - - /* This assumes the DRM is in total control of AGP space. - * It's not always the case as AGP can be in the control - * of user space (i.e. i810 driver). So this loop will get - * skipped and we double check that dev->agp->memory is - * actually set as well as being invalid before EPERM'ing - */ - list_for_each_entry(entry, &dev->agp->memory, head) { - if ((map->offset >= entry->bound) && - (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (!list_empty(&dev->agp->memory) && !valid) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EPERM; - } - DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); - - break; - } - case _DRM_SCATTER_GATHER: - if (!dev->sg) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } - map->offset += (unsigned long)dev->sg->virtual; - break; - case _DRM_CONSISTENT: - /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, - * As we're limiting the address to 2^32-1 (or less), - * casting it down to 32 bits is no problem, but we - * need to point to a 64bit variable first. */ - dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); - if (!dmah) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -ENOMEM; - } - map->handle = dmah->vaddr; - map->offset = (unsigned long)dmah->busaddr; - kfree(dmah); - break; - default: - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } - - list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); - if (!list) { - if (map->type == _DRM_REGISTERS) - iounmap(map->handle); - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } - memset(list, 0, sizeof(*list)); - list->map = map; - - mutex_lock(&dev->struct_mutex); - list_add(&list->head, &dev->maplist); - - /* Assign a 32-bit handle */ - /* We do it here so that dev->struct_mutex protects the increment */ - user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : - map->offset; - ret = drm_map_handle(dev, &list->hash, user_token, 0); - if (ret) { - if (map->type == _DRM_REGISTERS) - iounmap(map->handle); - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - drm_free(list, sizeof(*list), DRM_MEM_MAPS); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - list->user_token = list->hash.key << PAGE_SHIFT; - mutex_unlock(&dev->struct_mutex); - - *maplist = list; - return 0; - } - -int drm_addmap(struct drm_device * dev, unsigned int offset, - unsigned int size, enum drm_map_type type, - enum drm_map_flags flags, drm_local_map_t ** map_ptr) -{ - struct drm_map_list *list; - int rc; - - rc = drm_addmap_core(dev, offset, size, type, flags, &list); - if (!rc) - *map_ptr = list->map; - return rc; -} - -EXPORT_SYMBOL(drm_addmap); - -int drm_addmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *map = data; - struct drm_map_list *maplist; - int err; - - if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP)) - return -EPERM; - - err = drm_addmap_core(dev, map->offset, map->size, map->type, - map->flags, &maplist); - - if (err) - return err; - - /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */ - map->handle = (void *)(unsigned long)maplist->user_token; - return 0; -} - -/** - * Remove a map private from list and deallocate resources if the mapping - * isn't in use. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a struct drm_map structure. - * \return zero on success or a negative value on error. - * - * Searches the map on drm_device::maplist, removes it from the list, see if - * its being used, and free any associate resource (such as MTRR's) if it's not - * being on use. - * - * \sa drm_addmap - */ -int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map) -{ - struct drm_map_list *r_list = NULL, *list_t; - drm_dma_handle_t dmah; - int found = 0; - - /* Find the list entry for the map and remove it */ - list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { - if (r_list->map == map) { - list_del(&r_list->head); - drm_ht_remove_key(&dev->map_hash, - r_list->user_token >> PAGE_SHIFT); - drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS); - found = 1; - break; - } - } - - if (!found) - return -EINVAL; - - switch (map->type) { - case _DRM_REGISTERS: - iounmap(map->handle); - /* FALLTHROUGH */ - case _DRM_FRAME_BUFFER: - if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { - int retcode; - retcode = mtrr_del(map->mtrr, map->offset, map->size); - DRM_DEBUG("mtrr_del=%d\n", retcode); - } - break; - case _DRM_SHM: - vfree(map->handle); - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; - case _DRM_CONSISTENT: - dmah.vaddr = map->handle; - dmah.busaddr = map->offset; - dmah.size = map->size; - __drm_pci_free(dev, &dmah); - break; - } - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - - return 0; -} - -int drm_rmmap(struct drm_device *dev, drm_local_map_t *map) -{ - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm_rmmap_locked(dev, map); - mutex_unlock(&dev->struct_mutex); - - return ret; -} -EXPORT_SYMBOL(drm_rmmap); - -/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on - * the last close of the device, and this is necessary for cleanup when things - * exit uncleanly. Therefore, having userland manually remove mappings seems - * like a pointless exercise since they're going away anyway. - * - * One use case might be after addmap is allowed for normal users for SHM and - * gets used by drivers that the server doesn't need to care about. This seems - * unlikely. - */ -int drm_rmmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *request = data; - drm_local_map_t *map = NULL; - struct drm_map_list *r_list; - int ret; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map && - r_list->user_token == (unsigned long)request->handle && - r_list->map->flags & _DRM_REMOVABLE) { - map = r_list->map; - break; - } - } - - /* List has wrapped around to the head pointer, or its empty we didn't - * find anything. - */ - if (list_empty(&dev->maplist) || !map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - /* Register and framebuffer maps are permanent */ - if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { - mutex_unlock(&dev->struct_mutex); - return 0; - } - - ret = drm_rmmap_locked(dev, map); - - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -/** - * Cleanup after an error on one of the addbufs() functions. - * - * \param dev DRM device. - * \param entry buffer entry where the error occurred. - * - * Frees any pages and buffers associated with the given entry. - */ -static void drm_cleanup_buf_error(struct drm_device * dev, - struct drm_buf_entry * entry) -{ - int i; - - if (entry->seg_count) { - for (i = 0; i < entry->seg_count; i++) { - if (entry->seglist[i]) { - drm_pci_free(dev, entry->seglist[i]); - } - } - drm_free(entry->seglist, - entry->seg_count * - sizeof(*entry->seglist), DRM_MEM_SEGS); - - entry->seg_count = 0; - } - - if (entry->buf_count) { - for (i = 0; i < entry->buf_count; i++) { - if (entry->buflist[i].dev_private) { - drm_free(entry->buflist[i].dev_private, - entry->buflist[i].dev_priv_size, - DRM_MEM_BUFS); - } - } - drm_free(entry->buflist, - entry->buf_count * - sizeof(*entry->buflist), DRM_MEM_BUFS); - - entry->buf_count = 0; - } -} - -#if __OS_HAS_AGP -/** - * Add AGP buffers for DMA transfers. - * - * \param dev struct drm_device to which the buffers are to be added. - * \param request pointer to a struct drm_buf_desc describing the request. - * \return zero on success or a negative number on failure. - * - * After some sanity checks creates a drm_buf structure for each buffer and - * reallocates the buffer list of the same size order to accommodate the new - * buffers. - */ -int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_entry *entry; - struct drm_agp_mem *agp_entry; - struct drm_buf *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i, valid; - struct drm_buf **temp_buflist; - - if (!dma) - return -EINVAL; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = dev->agp->base + request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lx\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - /* Make sure buffers are located in AGP memory that we own */ - valid = 0; - list_for_each_entry(agp_entry, &dev->agp->memory, head) { - if ((agp_offset >= agp_entry->bound) && - (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (!list_empty(&dev->agp->memory) && !valid) { - DRM_DEBUG("zone invalid\n"); - return -EINVAL; - } - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(buf->dev_private, 0, buf->dev_priv_size); - - DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), DRM_MEM_BUFS); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_AGP; - - atomic_dec(&dev->buf_alloc); - return 0; -} -EXPORT_SYMBOL(drm_addbufs_agp); -#endif /* __OS_HAS_AGP */ - -int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - int count; - int order; - int size; - int total; - int page_order; - struct drm_buf_entry *entry; - drm_dma_handle_t *dmah; - struct drm_buf *buf; - int alignment; - unsigned long offset; - int i; - int byte_count; - int page_count; - unsigned long *temp_pagelist; - struct drm_buf **temp_buflist; - - if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n", - request->count, request->size, size, order, dev->queue_count); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - - entry->seglist = drm_alloc(count * sizeof(*entry->seglist), - DRM_MEM_SEGS); - if (!entry->seglist) { - drm_free(entry->buflist, - count * sizeof(*entry->buflist), DRM_MEM_BUFS); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->seglist, 0, count * sizeof(*entry->seglist)); - - /* Keep the original pagelist until we know all the allocations - * have succeeded - */ - temp_pagelist = drm_alloc((dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), DRM_MEM_PAGES); - if (!temp_pagelist) { - drm_free(entry->buflist, - count * sizeof(*entry->buflist), DRM_MEM_BUFS); - drm_free(entry->seglist, - count * sizeof(*entry->seglist), DRM_MEM_SEGS); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memcpy(temp_pagelist, - dma->pagelist, dma->page_count * sizeof(*dma->pagelist)); - DRM_DEBUG("pagelist: %d entries\n", - dma->page_count + (count << page_order)); - - entry->buf_size = size; - entry->page_order = page_order; - byte_count = 0; - page_count = 0; - - while (entry->buf_count < count) { - - dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful); - - if (!dmah) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - entry->seg_count = count; - drm_cleanup_buf_error(dev, entry); - drm_free(temp_pagelist, - (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), DRM_MEM_PAGES); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - entry->seglist[entry->seg_count++] = dmah; - for (i = 0; i < (1 << page_order); i++) { - DRM_DEBUG("page %d @ 0x%08lx\n", - dma->page_count + page_count, - (unsigned long)dmah->vaddr + PAGE_SIZE * i); - temp_pagelist[dma->page_count + page_count++] - = (unsigned long)dmah->vaddr + PAGE_SIZE * i; - } - for (offset = 0; - offset + size <= total && entry->buf_count < count; - offset += alignment, ++entry->buf_count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = (dma->byte_count + byte_count + offset); - buf->address = (void *)(dmah->vaddr + offset); - buf->bus_address = dmah->busaddr + offset; - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc(buf->dev_priv_size, - DRM_MEM_BUFS); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - entry->seg_count = count; - drm_cleanup_buf_error(dev, entry); - drm_free(temp_pagelist, - (dma->page_count + - (count << page_order)) - * sizeof(*dma->pagelist), - DRM_MEM_PAGES); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(buf->dev_private, 0, buf->dev_priv_size); - - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } - byte_count += PAGE_SIZE << page_order; - } - - temp_buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), DRM_MEM_BUFS); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - drm_free(temp_pagelist, - (dma->page_count + (count << page_order)) - * sizeof(*dma->pagelist), DRM_MEM_PAGES); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - /* No allocations failed, so now we can replace the orginal pagelist - * with the new one. - */ - if (dma->page_count) { - drm_free(dma->pagelist, - dma->page_count * sizeof(*dma->pagelist), - DRM_MEM_PAGES); - } - dma->pagelist = temp_pagelist; - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += entry->seg_count << page_order; - dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - if (request->flags & _DRM_PCI_BUFFER_RO) - dma->flags = _DRM_DMA_USE_PCI_RO; - - atomic_dec(&dev->buf_alloc); - return 0; - -} -EXPORT_SYMBOL(drm_addbufs_pci); - -static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_entry *entry; - struct drm_buf *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - struct drm_buf **temp_buflist; - - if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lu\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset - + (unsigned long)dev->sg->virtual); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - memset(buf->dev_private, 0, buf->dev_priv_size); - - DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), DRM_MEM_BUFS); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_SG; - - atomic_dec(&dev->buf_alloc); - return 0; -} - -static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_entry *entry; - struct drm_buf *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - struct drm_buf **temp_buflist; - - if (!drm_core_check_feature(dev, DRIVER_FB_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lu\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(buf->dev_private, 0, buf->dev_priv_size); - - DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), DRM_MEM_BUFS); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_FB; - - atomic_dec(&dev->buf_alloc); - return 0; -} - - -/** - * Add buffers for DMA transfers (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a struct drm_buf_desc request. - * \return zero on success or a negative number on failure. - * - * According with the memory type specified in drm_buf_desc::flags and the - * build options, it dispatches the call either to addbufs_agp(), - * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent - * PCI memory respectively. - */ -int drm_addbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_buf_desc *request = data; - int ret; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - -#if __OS_HAS_AGP - if (request->flags & _DRM_AGP_BUFFER) - ret = drm_addbufs_agp(dev, request); - else -#endif - if (request->flags & _DRM_SG_BUFFER) - ret = drm_addbufs_sg(dev, request); - else if (request->flags & _DRM_FB_BUFFER) - ret = drm_addbufs_fb(dev, request); - else - ret = drm_addbufs_pci(dev, request); - - return ret; -} - -/** - * Get information about the buffer mappings. - * - * This was originally mean for debugging purposes, or by a sophisticated - * client library to determine how best to use the available buffers (e.g., - * large buffers can be used for image transfer). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_buf_info structure. - * \return zero on success or a negative number on failure. - * - * Increments drm_device::buf_use while holding the drm_device::count_lock - * lock, preventing of allocating more buffers after this call. Information - * about each requested buffer is then copied into user space. - */ -int drm_infobufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_info *request = data; - int i; - int count; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - spin_lock(&dev->count_lock); - if (atomic_read(&dev->buf_alloc)) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - ++dev->buf_use; /* Can't allocate more after this call */ - spin_unlock(&dev->count_lock); - - for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) - ++count; - } - - DRM_DEBUG("count = %d\n", count); - - if (request->count >= count) { - for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) { - struct drm_buf_desc __user *to = - &request->list[count]; - struct drm_buf_entry *from = &dma->bufs[i]; - struct drm_freelist *list = &dma->bufs[i].freelist; - if (copy_to_user(&to->count, - &from->buf_count, - sizeof(from->buf_count)) || - copy_to_user(&to->size, - &from->buf_size, - sizeof(from->buf_size)) || - copy_to_user(&to->low_mark, - &list->low_mark, - sizeof(list->low_mark)) || - copy_to_user(&to->high_mark, - &list->high_mark, - sizeof(list->high_mark))) - return -EFAULT; - - DRM_DEBUG("%d %d %d %d %d\n", - i, - dma->bufs[i].buf_count, - dma->bufs[i].buf_size, - dma->bufs[i].freelist.low_mark, - dma->bufs[i].freelist.high_mark); - ++count; - } - } - } - request->count = count; - - return 0; -} - -/** - * Specifies a low and high water mark for buffer allocation - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg a pointer to a drm_buf_desc structure. - * \return zero on success or a negative number on failure. - * - * Verifies that the size order is bounded between the admissible orders and - * updates the respective drm_device_dma::bufs entry low and high water mark. - * - * \note This ioctl is deprecated and mostly never used. - */ -int drm_markbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_desc *request = data; - int order; - struct drm_buf_entry *entry; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - DRM_DEBUG("%d, %d, %d\n", - request->size, request->low_mark, request->high_mark); - order = drm_order(request->size); - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - entry = &dma->bufs[order]; - - if (request->low_mark < 0 || request->low_mark > entry->buf_count) - return -EINVAL; - if (request->high_mark < 0 || request->high_mark > entry->buf_count) - return -EINVAL; - - entry->freelist.low_mark = request->low_mark; - entry->freelist.high_mark = request->high_mark; - - return 0; -} - -/** - * Unreserve the buffers in list, previously reserved using drmDMA. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_buf_free structure. - * \return zero on success or a negative number on failure. - * - * Calls free_buffer() for each used buffer. - * This function is primarily used for debugging. - */ -int drm_freebufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_free *request = data; - int i; - int idx; - struct drm_buf *buf; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - DRM_DEBUG("%d\n", request->count); - for (i = 0; i < request->count; i++) { - if (copy_from_user(&idx, &request->list[i], sizeof(idx))) - return -EFAULT; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("Index %d (of %d max)\n", - idx, dma->buf_count - 1); - return -EINVAL; - } - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv) { - DRM_ERROR("Process %d freeing buffer not owned\n", - task_pid_nr(current)); - return -EINVAL; - } - drm_free_buffer(dev, buf); - } - - return 0; -} - -/** - * Maps all of the DMA buffers into client-virtual space (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_buf_map structure. - * \return zero on success or a negative number on failure. - * - * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls do_mmap() with - * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls - * drm_mmap_dma(). - */ -int drm_mapbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int retcode = 0; - const int zero = 0; - unsigned long virtual; - unsigned long address; - struct drm_buf_map *request = data; - int i; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - spin_lock(&dev->count_lock); - if (atomic_read(&dev->buf_alloc)) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - dev->buf_use++; /* Can't allocate more after this call */ - spin_unlock(&dev->count_lock); - - if (request->count >= dma->buf_count) { - if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) - || (drm_core_check_feature(dev, DRIVER_SG) - && (dma->flags & _DRM_DMA_USE_SG)) - || (drm_core_check_feature(dev, DRIVER_FB_DMA) - && (dma->flags & _DRM_DMA_USE_FB))) { - struct drm_map *map = dev->agp_buffer_map; - unsigned long token = dev->agp_buffer_token; - - if (!map) { - retcode = -EINVAL; - goto done; - } - down_write(¤t->mm->mmap_sem); - virtual = do_mmap(file_priv->filp, 0, map->size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - token); - up_write(¤t->mm->mmap_sem); - } else { - down_write(¤t->mm->mmap_sem); - virtual = do_mmap(file_priv->filp, 0, dma->byte_count, - PROT_READ | PROT_WRITE, - MAP_SHARED, 0); - up_write(¤t->mm->mmap_sem); - } - if (virtual > -1024UL) { - /* Real error */ - retcode = (signed long)virtual; - goto done; - } - request->virtual = (void __user *)virtual; - - for (i = 0; i < dma->buf_count; i++) { - if (copy_to_user(&request->list[i].idx, - &dma->buflist[i]->idx, - sizeof(request->list[0].idx))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request->list[i].total, - &dma->buflist[i]->total, - sizeof(request->list[0].total))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request->list[i].used, - &zero, sizeof(zero))) { - retcode = -EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; /* *** */ - if (copy_to_user(&request->list[i].address, - &address, sizeof(address))) { - retcode = -EFAULT; - goto done; - } - } - } - done: - request->count = dma->buf_count; - DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode); - - return retcode; -} - -/** - * Compute size order. Returns the exponent of the smaller power of two which - * is greater or equal to given number. - * - * \param size size. - * \return order. - * - * \todo Can be made faster. - */ -int drm_order(unsigned long size) -{ - int order; - unsigned long tmp; - - for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ; - - if (size & (size - 1)) - ++order; - - return order; -} -EXPORT_SYMBOL(drm_order); diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c deleted file mode 100644 index d505f69..0000000 --- a/drivers/char/drm/drm_context.c +++ /dev/null @@ -1,471 +0,0 @@ -/** - * \file drm_context.c - * IOCTLs for generic contexts - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * ChangeLog: - * 2001-11-16 Torsten Duwe - * added context constructor/destructor hooks, - * needed by SiS driver's memory management. - */ - -#include "drmP.h" - -/******************************************************************/ -/** \name Context bitmap support */ -/*@{*/ - -/** - * Free a handle from the context bitmap. - * - * \param dev DRM device. - * \param ctx_handle context handle. - * - * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry - * in drm_device::ctx_idr, while holding the drm_device::struct_mutex - * lock. - */ -void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) -{ - mutex_lock(&dev->struct_mutex); - idr_remove(&dev->ctx_idr, ctx_handle); - mutex_unlock(&dev->struct_mutex); -} - -/** - * Context bitmap allocation. - * - * \param dev DRM device. - * \return (non-negative) context handle on success or a negative number on failure. - * - * Allocate a new idr from drm_device::ctx_idr while holding the - * drm_device::struct_mutex lock. - */ -static int drm_ctxbitmap_next(struct drm_device * dev) -{ - int new_id; - int ret; - -again: - if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) { - DRM_ERROR("Out of memory expanding drawable idr\n"); - return -ENOMEM; - } - mutex_lock(&dev->struct_mutex); - ret = idr_get_new_above(&dev->ctx_idr, NULL, - DRM_RESERVED_CONTEXTS, &new_id); - if (ret == -EAGAIN) { - mutex_unlock(&dev->struct_mutex); - goto again; - } - mutex_unlock(&dev->struct_mutex); - return new_id; -} - -/** - * Context bitmap initialization. - * - * \param dev DRM device. - * - * Initialise the drm_device::ctx_idr - */ -int drm_ctxbitmap_init(struct drm_device * dev) -{ - idr_init(&dev->ctx_idr); - return 0; -} - -/** - * Context bitmap cleanup. - * - * \param dev DRM device. - * - * Free all idr members using drm_ctx_sarea_free helper function - * while holding the drm_device::struct_mutex lock. - */ -void drm_ctxbitmap_cleanup(struct drm_device * dev) -{ - mutex_lock(&dev->struct_mutex); - idr_remove_all(&dev->ctx_idr); - mutex_unlock(&dev->struct_mutex); -} - -/*@}*/ - -/******************************************************************/ -/** \name Per Context SAREA Support */ -/*@{*/ - -/** - * Get per-context SAREA. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx_priv_map structure. - * \return zero on success or a negative number on failure. - * - * Gets the map from drm_device::ctx_idr with the handle specified and - * returns its handle. - */ -int drm_getsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_priv_map *request = data; - struct drm_map *map; - struct drm_map_list *_entry; - - mutex_lock(&dev->struct_mutex); - - map = idr_find(&dev->ctx_idr, request->ctx_id); - if (!map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - mutex_unlock(&dev->struct_mutex); - - request->handle = NULL; - list_for_each_entry(_entry, &dev->maplist, head) { - if (_entry->map == map) { - request->handle = - (void *)(unsigned long)_entry->user_token; - break; - } - } - if (request->handle == NULL) - return -EINVAL; - - return 0; -} - -/** - * Set per-context SAREA. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx_priv_map structure. - * \return zero on success or a negative number on failure. - * - * Searches the mapping specified in \p arg and update the entry in - * drm_device::ctx_idr with it. - */ -int drm_setsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_priv_map *request = data; - struct drm_map *map = NULL; - struct drm_map_list *r_list = NULL; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map - && r_list->user_token == (unsigned long) request->handle) - goto found; - } - bad: - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - - found: - map = r_list->map; - if (!map) - goto bad; - - if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id))) - goto bad; - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/*@}*/ - -/******************************************************************/ -/** \name The actual DRM context handling routines */ -/*@{*/ - -/** - * Switch context. - * - * \param dev DRM device. - * \param old old context handle. - * \param new new context handle. - * \return zero on success or a negative number on failure. - * - * Attempt to set drm_device::context_flag. - */ -static int drm_context_switch(struct drm_device * dev, int old, int new) -{ - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return -EBUSY; - } - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - return 0; -} - -/** - * Complete context switch. - * - * \param dev DRM device. - * \param new new context handle. - * \return zero on success or a negative number on failure. - * - * Updates drm_device::last_context and drm_device::last_switch. Verifies the - * hardware lock is held, clears the drm_device::context_flag and wakes up - * drm_device::context_wait. - */ -static int drm_context_switch_complete(struct drm_device * dev, int new) -{ - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - /* If a context switch is ever initiated - when the kernel holds the lock, release - that lock here. */ - clear_bit(0, &dev->context_flag); - wake_up(&dev->context_wait); - - return 0; -} - -/** - * Reserve contexts. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx_res structure. - * \return zero on success or a negative number on failure. - */ -int drm_resctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_res *res = data; - struct drm_ctx ctx; - int i; - - if (res->count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx))) - return -EFAULT; - } - } - res->count = DRM_RESERVED_CONTEXTS; - - return 0; -} - -/** - * Add context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * Get a new handle for the context and copy to userspace. - */ -int drm_addctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_list *ctx_entry; - struct drm_ctx *ctx = data; - - ctx->handle = drm_ctxbitmap_next(dev); - if (ctx->handle == DRM_KERNEL_CONTEXT) { - /* Skip kernel's context and get a new one. */ - ctx->handle = drm_ctxbitmap_next(dev); - } - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle == -1) { - DRM_DEBUG("Not enough free contexts.\n"); - /* Should this return -EBUSY instead? */ - return -ENOMEM; - } - - if (ctx->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_ctor) - if (!dev->driver->context_ctor(dev, ctx->handle)) { - DRM_DEBUG("Running out of ctxs or memory.\n"); - return -ENOMEM; - } - } - - ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST); - if (!ctx_entry) { - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - - INIT_LIST_HEAD(&ctx_entry->head); - ctx_entry->handle = ctx->handle; - ctx_entry->tag = file_priv; - - mutex_lock(&dev->ctxlist_mutex); - list_add(&ctx_entry->head, &dev->ctxlist); - ++dev->ctx_count; - mutex_unlock(&dev->ctxlist_mutex); - - return 0; -} - -int drm_modctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - /* This does nothing */ - return 0; -} - -/** - * Get context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - */ -int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - /* This is 0, because we don't handle any context flags */ - ctx->flags = 0; - - return 0; -} - -/** - * Switch context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * Calls context_switch(). - */ -int drm_switchctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - return drm_context_switch(dev, dev->last_context, ctx->handle); -} - -/** - * New context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * Calls context_switch_complete(). - */ -int drm_newctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - drm_context_switch_complete(dev, ctx->handle); - - return 0; -} - -/** - * Remove context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * If not the special kernel context, calls ctxbitmap_free() to free the specified context. - */ -int drm_rmctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle == DRM_KERNEL_CONTEXT + 1) { - file_priv->remove_auth_on_close = 1; - } - if (ctx->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_dtor) - dev->driver->context_dtor(dev, ctx->handle); - drm_ctxbitmap_free(dev, ctx->handle); - } - - mutex_lock(&dev->ctxlist_mutex); - if (!list_empty(&dev->ctxlist)) { - struct drm_ctx_list *pos, *n; - - list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { - if (pos->handle == ctx->handle) { - list_del(&pos->head); - drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); - --dev->ctx_count; - } - } - } - mutex_unlock(&dev->ctxlist_mutex); - - return 0; -} - -/*@}*/ diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h deleted file mode 100644 index 3167390..0000000 --- a/drivers/char/drm/drm_core.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2004 Jon Smirl - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#define CORE_AUTHOR "Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl" - -#define CORE_NAME "drm" -#define CORE_DESC "DRM shared core routines" -#define CORE_DATE "20060810" - -#define DRM_IF_MAJOR 1 -#define DRM_IF_MINOR 3 - -#define CORE_MAJOR 1 -#define CORE_MINOR 1 -#define CORE_PATCHLEVEL 0 diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c deleted file mode 100644 index 7a8e2fb..0000000 --- a/drivers/char/drm/drm_dma.c +++ /dev/null @@ -1,180 +0,0 @@ -/** - * \file drm_dma.c - * DMA IOCTL and function support - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -/** - * Initialize the DMA data. - * - * \param dev DRM device. - * \return zero on success or a negative value on failure. - * - * Allocate and initialize a drm_device_dma structure. - */ -int drm_dma_setup(struct drm_device *dev) -{ - int i; - - dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER); - if (!dev->dma) - return -ENOMEM; - - memset(dev->dma, 0, sizeof(*dev->dma)); - - for (i = 0; i <= DRM_MAX_ORDER; i++) - memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0])); - - return 0; -} - -/** - * Cleanup the DMA resources. - * - * \param dev DRM device. - * - * Free all pages associated with DMA buffers, the buffers and pages lists, and - * finally the drm_device::dma structure itself. - */ -void drm_dma_takedown(struct drm_device *dev) -{ - struct drm_device_dma *dma = dev->dma; - int i, j; - - if (!dma) - return; - - /* Clear dma buffers */ - for (i = 0; i <= DRM_MAX_ORDER; i++) { - if (dma->bufs[i].seg_count) { - DRM_DEBUG("order %d: buf_count = %d," - " seg_count = %d\n", - i, - dma->bufs[i].buf_count, - dma->bufs[i].seg_count); - for (j = 0; j < dma->bufs[i].seg_count; j++) { - if (dma->bufs[i].seglist[j]) { - drm_pci_free(dev, dma->bufs[i].seglist[j]); - } - } - drm_free(dma->bufs[i].seglist, - dma->bufs[i].seg_count - * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS); - } - if (dma->bufs[i].buf_count) { - for (j = 0; j < dma->bufs[i].buf_count; j++) { - if (dma->bufs[i].buflist[j].dev_private) { - drm_free(dma->bufs[i].buflist[j]. - dev_private, - dma->bufs[i].buflist[j]. - dev_priv_size, DRM_MEM_BUFS); - } - } - drm_free(dma->bufs[i].buflist, - dma->bufs[i].buf_count * - sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS); - } - } - - if (dma->buflist) { - drm_free(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS); - } - - if (dma->pagelist) { - drm_free(dma->pagelist, - dma->page_count * sizeof(*dma->pagelist), - DRM_MEM_PAGES); - } - drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); - dev->dma = NULL; -} - -/** - * Free a buffer. - * - * \param dev DRM device. - * \param buf buffer to free. - * - * Resets the fields of \p buf. - */ -void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf) -{ - if (!buf) - return; - - buf->waiting = 0; - buf->pending = 0; - buf->file_priv = NULL; - buf->used = 0; - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) - && waitqueue_active(&buf->dma_wait)) { - wake_up_interruptible(&buf->dma_wait); - } -} - -/** - * Reclaim the buffers. - * - * \param file_priv DRM file private. - * - * Frees each buffer associated with \p file_priv not already on the hardware. - */ -void drm_core_reclaim_buffers(struct drm_device *dev, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - if (!dma) - return; - for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->file_priv == file_priv) { - switch (dma->buflist[i]->list) { - case DRM_LIST_NONE: - drm_free_buffer(dev, dma->buflist[i]); - break; - case DRM_LIST_WAIT: - dma->buflist[i]->list = DRM_LIST_RECLAIM; - break; - default: - /* Buffer already on hardware. */ - break; - } - } - } -} - -EXPORT_SYMBOL(drm_core_reclaim_buffers); diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c deleted file mode 100644 index 1839c57..0000000 --- a/drivers/char/drm/drm_drawable.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * \file drm_drawable.c - * IOCTLs for drawables - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - * \author Michel Dänzer - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -/** - * Allocate drawable ID and memory to store information about it. - */ -int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - unsigned long irqflags; - struct drm_draw *draw = data; - int new_id = 0; - int ret; - -again: - if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { - DRM_ERROR("Out of memory expanding drawable idr\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&dev->drw_lock, irqflags); - ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id); - if (ret == -EAGAIN) { - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - goto again; - } - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - draw->handle = new_id; - - DRM_DEBUG("%d\n", draw->handle); - - return 0; -} - -/** - * Free drawable ID and memory to store information about it. - */ -int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_draw *draw = data; - unsigned long irqflags; - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - drm_free(drm_get_drawable_info(dev, draw->handle), - sizeof(struct drm_drawable_info), DRM_MEM_BUFS); - - idr_remove(&dev->drw_idr, draw->handle); - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - DRM_DEBUG("%d\n", draw->handle); - return 0; -} - -int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_update_draw *update = data; - unsigned long irqflags; - struct drm_clip_rect *rects; - struct drm_drawable_info *info; - int err; - - info = idr_find(&dev->drw_idr, update->handle); - if (!info) { - info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); - if (!info) - return -ENOMEM; - if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) { - DRM_ERROR("No such drawable %d\n", update->handle); - drm_free(info, sizeof(*info), DRM_MEM_BUFS); - return -EINVAL; - } - } - - switch (update->type) { - case DRM_DRAWABLE_CLIPRECTS: - if (update->num != info->num_rects) { - rects = drm_alloc(update->num * sizeof(struct drm_clip_rect), - DRM_MEM_BUFS); - } else - rects = info->rects; - - if (update->num && !rects) { - DRM_ERROR("Failed to allocate cliprect memory\n"); - err = -ENOMEM; - goto error; - } - - if (update->num && DRM_COPY_FROM_USER(rects, - (struct drm_clip_rect __user *) - (unsigned long)update->data, - update->num * - sizeof(*rects))) { - DRM_ERROR("Failed to copy cliprects from userspace\n"); - err = -EFAULT; - goto error; - } - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - if (rects != info->rects) { - drm_free(info->rects, info->num_rects * - sizeof(struct drm_clip_rect), DRM_MEM_BUFS); - } - - info->rects = rects; - info->num_rects = update->num; - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - DRM_DEBUG("Updated %d cliprects for drawable %d\n", - info->num_rects, update->handle); - break; - default: - DRM_ERROR("Invalid update type %d\n", update->type); - return -EINVAL; - } - - return 0; - -error: - if (rects != info->rects) - drm_free(rects, update->num * sizeof(struct drm_clip_rect), - DRM_MEM_BUFS); - - return err; -} - -/** - * Caller must hold the drawable spinlock! - */ -struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id) -{ - return idr_find(&dev->drw_idr, id); -} -EXPORT_SYMBOL(drm_get_drawable_info); - -static int drm_drawable_free(int idr, void *p, void *data) -{ - struct drm_drawable_info *info = p; - - if (info) { - drm_free(info->rects, info->num_rects * - sizeof(struct drm_clip_rect), DRM_MEM_BUFS); - drm_free(info, sizeof(*info), DRM_MEM_BUFS); - } - - return 0; -} - -void drm_drawable_free_all(struct drm_device *dev) -{ - idr_for_each(&dev->drw_idr, drm_drawable_free, NULL); - idr_remove_all(&dev->drw_idr); -} diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c deleted file mode 100644 index 5641387..0000000 --- a/drivers/char/drm/drm_drv.c +++ /dev/null @@ -1,540 +0,0 @@ -/** - * \file drm_drv.c - * Generic driver template - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - * - * To use this template, you must at least define the following (samples - * given for the MGA driver): - * - * \code - * #define DRIVER_AUTHOR "VA Linux Systems, Inc." - * - * #define DRIVER_NAME "mga" - * #define DRIVER_DESC "Matrox G200/G400" - * #define DRIVER_DATE "20001127" - * - * #define drm_x mga_##x - * \endcode - */ - -/* - * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_core.h" - -static int drm_version(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/** Ioctl table */ -static struct drm_ioctl_desc drm_ioctls[] = { - DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), - DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), - DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH), - /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ - DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - -#if __OS_HAS_AGP - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -#endif - - DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), - - DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -}; - -#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) - -/** - * Take down the DRM device. - * - * \param dev DRM device structure. - * - * Frees every resource in \p dev. - * - * \sa drm_device - */ -int drm_lastclose(struct drm_device * dev) -{ - struct drm_magic_entry *pt, *next; - struct drm_map_list *r_list, *list_t; - struct drm_vma_entry *vma, *vma_temp; - int i; - - DRM_DEBUG("\n"); - - if (dev->driver->lastclose) - dev->driver->lastclose(dev); - DRM_DEBUG("driver lastclose completed\n"); - - if (dev->unique) { - drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); - dev->unique = NULL; - dev->unique_len = 0; - } - - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - mutex_lock(&dev->struct_mutex); - - /* Free drawable information memory */ - drm_drawable_free_all(dev); - del_timer(&dev->timer); - - /* Clear pid list */ - if (dev->magicfree.next) { - list_for_each_entry_safe(pt, next, &dev->magicfree, head) { - list_del(&pt->head); - drm_ht_remove_item(&dev->magiclist, &pt->hash_item); - drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); - } - drm_ht_remove(&dev->magiclist); - } - - /* Clear AGP information */ - if (drm_core_has_AGP(dev) && dev->agp) { - struct drm_agp_mem *entry, *tempe; - - /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ - list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { - if (entry->bound) - drm_unbind_agp(entry->memory); - drm_free_agp(entry->memory, entry->pages); - drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); - } - INIT_LIST_HEAD(&dev->agp->memory); - - if (dev->agp->acquired) - drm_agp_release(dev); - - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } - if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { - drm_sg_cleanup(dev->sg); - dev->sg = NULL; - } - - /* Clear vma list (only built for debugging) */ - list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) { - list_del(&vma->head); - drm_free(vma, sizeof(*vma), DRM_MEM_VMAS); - } - - list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { - if (!(r_list->map->flags & _DRM_DRIVER)) { - drm_rmmap_locked(dev, r_list->map); - r_list = NULL; - } - } - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { - for (i = 0; i < dev->queue_count; i++) { - if (dev->queuelist[i]) { - drm_free(dev->queuelist[i], - sizeof(*dev->queuelist[0]), - DRM_MEM_QUEUES); - dev->queuelist[i] = NULL; - } - } - drm_free(dev->queuelist, - dev->queue_slots * sizeof(*dev->queuelist), - DRM_MEM_QUEUES); - dev->queuelist = NULL; - } - dev->queue_count = 0; - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - drm_dma_takedown(dev); - - if (dev->lock.hw_lock) { - dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.file_priv = NULL; - wake_up_interruptible(&dev->lock.lock_queue); - } - mutex_unlock(&dev->struct_mutex); - - DRM_DEBUG("lastclose completed\n"); - return 0; -} - -/** - * Module initialization. Called via init_module at module load time, or via - * linux/init/main.c (this is not currently supported). - * - * \return zero on success or a negative number on failure. - * - * Initializes an array of drm_device structures, and attempts to - * initialize all available devices, using consecutive minors, registering the - * stubs and initializing the AGP device. - * - * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and - * after the initialization for driver customization. - */ -int drm_init(struct drm_driver *driver) -{ - struct pci_dev *pdev = NULL; - struct pci_device_id *pid; - int i; - - DRM_DEBUG("\n"); - - for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { - pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; - - pdev = NULL; - /* pass back in pdev to account for multiple identical cards */ - while ((pdev = - pci_get_subsys(pid->vendor, pid->device, pid->subvendor, - pid->subdevice, pdev)) != NULL) { - /* stealth mode requires a manual probe */ - pci_dev_get(pdev); - drm_get_dev(pdev, pid, driver); - } - } - return 0; -} - -EXPORT_SYMBOL(drm_init); - -/** - * Called via cleanup_module() at module unload time. - * - * Cleans up all DRM device, calling drm_lastclose(). - * - * \sa drm_init - */ -static void drm_cleanup(struct drm_device * dev) -{ - DRM_DEBUG("\n"); - - if (!dev) { - DRM_ERROR("cleanup called no dev\n"); - return; - } - - drm_lastclose(dev); - - if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && - dev->agp && dev->agp->agp_mtrr >= 0) { - int retval; - retval = mtrr_del(dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024 * 1024); - DRM_DEBUG("mtrr_del=%d\n", retval); - } - - if (drm_core_has_AGP(dev) && dev->agp) { - drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); - dev->agp = NULL; - } - - if (dev->driver->unload) - dev->driver->unload(dev); - - drm_ht_remove(&dev->map_hash); - drm_ctxbitmap_cleanup(dev); - - drm_put_minor(&dev->primary); - if (drm_put_dev(dev)) - DRM_ERROR("Cannot unload module\n"); -} - -int drm_minors_cleanup(int id, void *ptr, void *data) -{ - struct drm_minor *minor = ptr; - struct drm_device *dev; - struct drm_driver *driver = data; - - dev = minor->dev; - if (minor->dev->driver != driver) - return 0; - - if (minor->type != DRM_MINOR_LEGACY) - return 0; - - if (dev) - pci_dev_put(dev->pdev); - drm_cleanup(dev); - return 1; -} - -void drm_exit(struct drm_driver *driver) -{ - DRM_DEBUG("\n"); - - idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver); - - DRM_INFO("Module unloaded\n"); -} - -EXPORT_SYMBOL(drm_exit); - -/** File operations structure */ -static const struct file_operations drm_stub_fops = { - .owner = THIS_MODULE, - .open = drm_stub_open -}; - -static int __init drm_core_init(void) -{ - int ret = -ENOMEM; - - idr_init(&drm_minors_idr); - - if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) - goto err_p1; - - drm_class = drm_sysfs_create(THIS_MODULE, "drm"); - if (IS_ERR(drm_class)) { - printk(KERN_ERR "DRM: Error creating drm class.\n"); - ret = PTR_ERR(drm_class); - goto err_p2; - } - - drm_proc_root = proc_mkdir("dri", NULL); - if (!drm_proc_root) { - DRM_ERROR("Cannot create /proc/dri\n"); - ret = -1; - goto err_p3; - } - - drm_mem_init(); - - DRM_INFO("Initialized %s %d.%d.%d %s\n", - CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); - return 0; -err_p3: - drm_sysfs_destroy(); -err_p2: - unregister_chrdev(DRM_MAJOR, "drm"); - - idr_destroy(&drm_minors_idr); -err_p1: - return ret; -} - -static void __exit drm_core_exit(void) -{ - remove_proc_entry("dri", NULL); - drm_sysfs_destroy(); - - unregister_chrdev(DRM_MAJOR, "drm"); - - idr_destroy(&drm_minors_idr); -} - -module_init(drm_core_init); -module_exit(drm_core_exit); - -/** - * Get version information - * - * \param inode device inode. - * \param filp file pointer. - * \param cmd command. - * \param arg user argument, pointing to a drm_version structure. - * \return zero on success or negative number on failure. - * - * Fills in the version information in \p arg. - */ -static int drm_version(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_version *version = data; - int len; - - version->version_major = dev->driver->major; - version->version_minor = dev->driver->minor; - version->version_patchlevel = dev->driver->patchlevel; - DRM_COPY(version->name, dev->driver->name); - DRM_COPY(version->date, dev->driver->date); - DRM_COPY(version->desc, dev->driver->desc); - - return 0; -} - -/** - * Called whenever a process performs an ioctl on /dev/drm. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - * - * Looks up the ioctl function in the ::ioctls table, checking for root - * previleges if so required, and dispatches to the respective function. - */ -int drm_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->minor->dev; - struct drm_ioctl_desc *ioctl; - drm_ioctl_t *func; - unsigned int nr = DRM_IOCTL_NR(cmd); - int retcode = -EINVAL; - char *kdata = NULL; - - atomic_inc(&dev->ioctl_count); - atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); - ++file_priv->ioctl_count; - - DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", - task_pid_nr(current), cmd, nr, - (long)old_encode_dev(file_priv->minor->device), - file_priv->authenticated); - - if ((nr >= DRM_CORE_IOCTL_COUNT) && - ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) - goto err_i1; - if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && - (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) - ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; - else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { - ioctl = &drm_ioctls[nr]; - cmd = ioctl->cmd; - } else - goto err_i1; - - /* Do not trust userspace, use our own definition */ - func = ioctl->func; - /* is there a local override? */ - if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl) - func = dev->driver->dma_ioctl; - - if (!func) { - DRM_DEBUG("no function\n"); - retcode = -EINVAL; - } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || - ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || - ((ioctl->flags & DRM_MASTER) && !file_priv->master)) { - retcode = -EACCES; - } else { - if (cmd & (IOC_IN | IOC_OUT)) { - kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); - if (!kdata) { - retcode = -ENOMEM; - goto err_i1; - } - } - - if (cmd & IOC_IN) { - if (copy_from_user(kdata, (void __user *)arg, - _IOC_SIZE(cmd)) != 0) { - retcode = -EFAULT; - goto err_i1; - } - } - retcode = func(dev, kdata, file_priv); - - if ((retcode == 0) && (cmd & IOC_OUT)) { - if (copy_to_user((void __user *)arg, kdata, - _IOC_SIZE(cmd)) != 0) - retcode = -EFAULT; - } - } - - err_i1: - if (kdata) - kfree(kdata); - atomic_dec(&dev->ioctl_count); - if (retcode) - DRM_DEBUG("ret = %x\n", retcode); - return retcode; -} - -EXPORT_SYMBOL(drm_ioctl); - -drm_local_map_t *drm_getsarea(struct drm_device *dev) -{ - struct drm_map_list *entry; - - list_for_each_entry(entry, &dev->maplist, head) { - if (entry->map && entry->map->type == _DRM_SHM && - (entry->map->flags & _DRM_CONTAINS_LOCK)) { - return entry->map; - } - } - return NULL; -} -EXPORT_SYMBOL(drm_getsarea); diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c deleted file mode 100644 index d2e6da8..0000000 --- a/drivers/char/drm/drm_fops.c +++ /dev/null @@ -1,466 +0,0 @@ -/** - * \file drm_fops.c - * File operations for DRM - * - * \author Rickard E. (Rik) Faith - * \author Daryll Strauss - * \author Gareth Hughes - */ - -/* - * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_sarea.h" -#include - -static int drm_open_helper(struct inode *inode, struct file *filp, - struct drm_device * dev); - -static int drm_setup(struct drm_device * dev) -{ - drm_local_map_t *map; - int i; - int ret; - u32 sareapage; - - if (dev->driver->firstopen) { - ret = dev->driver->firstopen(dev); - if (ret != 0) - return ret; - } - - dev->magicfree.next = NULL; - - /* prebuild the SAREA */ - sareapage = max_t(unsigned, SAREA_MAX, PAGE_SIZE); - i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); - if (i != 0) - return i; - - atomic_set(&dev->ioctl_count, 0); - atomic_set(&dev->vma_count, 0); - dev->buf_use = 0; - atomic_set(&dev->buf_alloc, 0); - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { - i = drm_dma_setup(dev); - if (i < 0) - return i; - } - - for (i = 0; i < ARRAY_SIZE(dev->counts); i++) - atomic_set(&dev->counts[i], 0); - - drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); - INIT_LIST_HEAD(&dev->magicfree); - - dev->sigdata.lock = NULL; - init_waitqueue_head(&dev->lock.lock_queue); - dev->queue_count = 0; - dev->queue_reserved = 0; - dev->queue_slots = 0; - dev->queuelist = NULL; - dev->irq_enabled = 0; - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - dev->last_context = 0; - dev->last_switch = 0; - dev->last_checked = 0; - init_waitqueue_head(&dev->context_wait); - dev->if_version = 0; - - dev->ctx_start = 0; - dev->lck_start = 0; - - dev->buf_async = NULL; - init_waitqueue_head(&dev->buf_readers); - init_waitqueue_head(&dev->buf_writers); - - DRM_DEBUG("\n"); - - /* - * The kernel's context could be created here, but is now created - * in drm_dma_enqueue. This is more resource-efficient for - * hardware that does not do DMA, but may mean that - * drm_select_queue fails between the time the interrupt is - * initialized and the time the queues are initialized. - */ - - return 0; -} - -/** - * Open file. - * - * \param inode device inode - * \param filp file pointer. - * \return zero on success or a negative number on failure. - * - * Searches the DRM device with the same minor number, calls open_helper(), and - * increments the device open count. If the open count was previous at zero, - * i.e., it's the first that the device is open, then calls setup(). - */ -int drm_open(struct inode *inode, struct file *filp) -{ - struct drm_device *dev = NULL; - int minor_id = iminor(inode); - struct drm_minor *minor; - int retcode = 0; - - minor = idr_find(&drm_minors_idr, minor_id); - if (!minor) - return -ENODEV; - - if (!(dev = minor->dev)) - return -ENODEV; - - retcode = drm_open_helper(inode, filp, dev); - if (!retcode) { - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - spin_lock(&dev->count_lock); - if (!dev->open_count++) { - spin_unlock(&dev->count_lock); - return drm_setup(dev); - } - spin_unlock(&dev->count_lock); - } - - return retcode; -} -EXPORT_SYMBOL(drm_open); - -/** - * File \c open operation. - * - * \param inode device inode. - * \param filp file pointer. - * - * Puts the dev->fops corresponding to the device minor number into - * \p filp, call the \c open method, and restore the file operations. - */ -int drm_stub_open(struct inode *inode, struct file *filp) -{ - struct drm_device *dev = NULL; - struct drm_minor *minor; - int minor_id = iminor(inode); - int err = -ENODEV; - const struct file_operations *old_fops; - - DRM_DEBUG("\n"); - - minor = idr_find(&drm_minors_idr, minor_id); - if (!minor) - return -ENODEV; - - if (!(dev = minor->dev)) - return -ENODEV; - - old_fops = filp->f_op; - filp->f_op = fops_get(&dev->driver->fops); - if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { - fops_put(filp->f_op); - filp->f_op = fops_get(old_fops); - } - fops_put(old_fops); - - return err; -} - -/** - * Check whether DRI will run on this CPU. - * - * \return non-zero if the DRI will run on this CPU, or zero otherwise. - */ -static int drm_cpu_valid(void) -{ -#if defined(__i386__) - if (boot_cpu_data.x86 == 3) - return 0; /* No cmpxchg on a 386 */ -#endif -#if defined(__sparc__) && !defined(__sparc_v9__) - return 0; /* No cmpxchg before v9 sparc. */ -#endif - return 1; -} - -/** - * Called whenever a process opens /dev/drm. - * - * \param inode device inode. - * \param filp file pointer. - * \param dev device. - * \return zero on success or a negative number on failure. - * - * Creates and initializes a drm_file structure for the file private data in \p - * filp and add it into the double linked list in \p dev. - */ -static int drm_open_helper(struct inode *inode, struct file *filp, - struct drm_device * dev) -{ - int minor_id = iminor(inode); - struct drm_file *priv; - int ret; - - if (filp->f_flags & O_EXCL) - return -EBUSY; /* No exclusive opens */ - if (!drm_cpu_valid()) - return -EINVAL; - - DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); - - priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); - if (!priv) - return -ENOMEM; - - memset(priv, 0, sizeof(*priv)); - filp->private_data = priv; - priv->filp = filp; - priv->uid = current->euid; - priv->pid = task_pid_nr(current); - priv->minor = idr_find(&drm_minors_idr, minor_id); - priv->ioctl_count = 0; - /* for compatibility root is always authenticated */ - priv->authenticated = capable(CAP_SYS_ADMIN); - priv->lock_count = 0; - - INIT_LIST_HEAD(&priv->lhead); - - if (dev->driver->open) { - ret = dev->driver->open(dev, priv); - if (ret < 0) - goto out_free; - } - - mutex_lock(&dev->struct_mutex); - if (list_empty(&dev->filelist)) - priv->master = 1; - - list_add(&priv->lhead, &dev->filelist); - mutex_unlock(&dev->struct_mutex); - -#ifdef __alpha__ - /* - * Default the hose - */ - if (!dev->hose) { - struct pci_dev *pci_dev; - pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); - if (pci_dev) { - dev->hose = pci_dev->sysdata; - pci_dev_put(pci_dev); - } - if (!dev->hose) { - struct pci_bus *b = pci_bus_b(pci_root_buses.next); - if (b) - dev->hose = b->sysdata; - } - } -#endif - - return 0; - out_free: - drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - filp->private_data = NULL; - return ret; -} - -/** No-op. */ -int drm_fasync(int fd, struct file *filp, int on) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - int retcode; - - DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, - (long)old_encode_dev(priv->minor->device)); - retcode = fasync_helper(fd, filp, on, &dev->buf_async); - if (retcode < 0) - return retcode; - return 0; -} -EXPORT_SYMBOL(drm_fasync); - -/** - * Release file. - * - * \param inode device inode - * \param file_priv DRM file private. - * \return zero on success or a negative number on failure. - * - * If the hardware lock is held then free it, and take it again for the kernel - * context since it's necessary to reclaim buffers. Unlink the file private - * data from its list and free it. Decreases the open count and if it reaches - * zero calls drm_lastclose(). - */ -int drm_release(struct inode *inode, struct file *filp) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->minor->dev; - int retcode = 0; - - lock_kernel(); - - DRM_DEBUG("open_count = %d\n", dev->open_count); - - if (dev->driver->preclose) - dev->driver->preclose(dev, file_priv); - - /* ======================================================== - * Begin inline drm_release - */ - - DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - task_pid_nr(current), - (long)old_encode_dev(file_priv->minor->device), - dev->open_count); - - if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { - if (drm_i_have_hw_lock(dev, file_priv)) { - dev->driver->reclaim_buffers_locked(dev, file_priv); - } else { - unsigned long endtime = jiffies + 3 * DRM_HZ; - int locked = 0; - - drm_idlelock_take(&dev->lock); - - /* - * Wait for a while. - */ - - do{ - spin_lock_bh(&dev->lock.spinlock); - locked = dev->lock.idle_has_lock; - spin_unlock_bh(&dev->lock.spinlock); - if (locked) - break; - schedule(); - } while (!time_after_eq(jiffies, endtime)); - - if (!locked) { - DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" - "\tdriver to use reclaim_buffers_idlelocked() instead.\n" - "\tI will go on reclaiming the buffers anyway.\n"); - } - - dev->driver->reclaim_buffers_locked(dev, file_priv); - drm_idlelock_release(&dev->lock); - } - } - - if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) { - - drm_idlelock_take(&dev->lock); - dev->driver->reclaim_buffers_idlelocked(dev, file_priv); - drm_idlelock_release(&dev->lock); - - } - - if (drm_i_have_hw_lock(dev, file_priv)) { - DRM_DEBUG("File %p released, freeing lock for context %d\n", - filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - - drm_lock_free(&dev->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - } - - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && - !dev->driver->reclaim_buffers_locked) { - dev->driver->reclaim_buffers(dev, file_priv); - } - - drm_fasync(-1, filp, 0); - - mutex_lock(&dev->ctxlist_mutex); - if (!list_empty(&dev->ctxlist)) { - struct drm_ctx_list *pos, *n; - - list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { - if (pos->tag == file_priv && - pos->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_dtor) - dev->driver->context_dtor(dev, - pos->handle); - - drm_ctxbitmap_free(dev, pos->handle); - - list_del(&pos->head); - drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); - --dev->ctx_count; - } - } - } - mutex_unlock(&dev->ctxlist_mutex); - - mutex_lock(&dev->struct_mutex); - if (file_priv->remove_auth_on_close == 1) { - struct drm_file *temp; - - list_for_each_entry(temp, &dev->filelist, lhead) - temp->authenticated = 0; - } - list_del(&file_priv->lhead); - mutex_unlock(&dev->struct_mutex); - - if (dev->driver->postclose) - dev->driver->postclose(dev, file_priv); - drm_free(file_priv, sizeof(*file_priv), DRM_MEM_FILES); - - /* ======================================================== - * End inline drm_release - */ - - atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); - spin_lock(&dev->count_lock); - if (!--dev->open_count) { - if (atomic_read(&dev->ioctl_count) || dev->blocked) { - DRM_ERROR("Device busy: %d %d\n", - atomic_read(&dev->ioctl_count), dev->blocked); - spin_unlock(&dev->count_lock); - unlock_kernel(); - return -EBUSY; - } - spin_unlock(&dev->count_lock); - unlock_kernel(); - return drm_lastclose(dev); - } - spin_unlock(&dev->count_lock); - - unlock_kernel(); - - return retcode; -} -EXPORT_SYMBOL(drm_release); - -/** No-op. */ -unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) -{ - return 0; -} -EXPORT_SYMBOL(drm_poll); diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c deleted file mode 100644 index 3316067..0000000 --- a/drivers/char/drm/drm_hashtab.c +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "drm_hashtab.h" -#include - -int drm_ht_create(struct drm_open_hash *ht, unsigned int order) -{ - unsigned int i; - - ht->size = 1 << order; - ht->order = order; - ht->fill = 0; - ht->table = NULL; - ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); - if (!ht->use_vmalloc) { - ht->table = drm_calloc(ht->size, sizeof(*ht->table), - DRM_MEM_HASHTAB); - } - if (!ht->table) { - ht->use_vmalloc = 1; - ht->table = vmalloc(ht->size*sizeof(*ht->table)); - } - if (!ht->table) { - DRM_ERROR("Out of memory for hash table\n"); - return -ENOMEM; - } - for (i=0; i< ht->size; ++i) { - INIT_HLIST_HEAD(&ht->table[i]); - } - return 0; -} - -void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key) -{ - struct drm_hash_item *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - int count = 0; - - hashed_key = hash_long(key, ht->order); - DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, struct drm_hash_item, head); - DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key); - } -} - -static struct hlist_node *drm_ht_find_key(struct drm_open_hash *ht, - unsigned long key) -{ - struct drm_hash_item *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, struct drm_hash_item, head); - if (entry->key == key) - return list; - if (entry->key > key) - break; - } - return NULL; -} - - -int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item) -{ - struct drm_hash_item *entry; - struct hlist_head *h_list; - struct hlist_node *list, *parent; - unsigned int hashed_key; - unsigned long key = item->key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - parent = NULL; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, struct drm_hash_item, head); - if (entry->key == key) - return -EINVAL; - if (entry->key > key) - break; - parent = list; - } - if (parent) { - hlist_add_after(parent, &item->head); - } else { - hlist_add_head(&item->head, h_list); - } - return 0; -} - -/* - * Just insert an item and return any "bits" bit key that hasn't been - * used before. - */ -int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, - unsigned long seed, int bits, int shift, - unsigned long add) -{ - int ret; - unsigned long mask = (1 << bits) - 1; - unsigned long first, unshifted_key; - - unshifted_key = hash_long(seed, bits); - first = unshifted_key; - do { - item->key = (unshifted_key << shift) + add; - ret = drm_ht_insert_item(ht, item); - if (ret) - unshifted_key = (unshifted_key + 1) & mask; - } while(ret && (unshifted_key != first)); - - if (ret) { - DRM_ERROR("Available key bit space exhausted\n"); - return -EINVAL; - } - return 0; -} - -int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, - struct drm_hash_item **item) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (!list) - return -EINVAL; - - *item = hlist_entry(list, struct drm_hash_item, head); - return 0; -} - -int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (list) { - hlist_del_init(list); - ht->fill--; - return 0; - } - return -EINVAL; -} - -int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item) -{ - hlist_del_init(&item->head); - ht->fill--; - return 0; -} - -void drm_ht_remove(struct drm_open_hash *ht) -{ - if (ht->table) { - if (ht->use_vmalloc) - vfree(ht->table); - else - drm_free(ht->table, ht->size * sizeof(*ht->table), - DRM_MEM_HASHTAB); - ht->table = NULL; - } -} diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h deleted file mode 100644 index cd2b189..0000000 --- a/drivers/char/drm/drm_hashtab.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_HASHTAB_H -#define DRM_HASHTAB_H - -#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) - -struct drm_hash_item { - struct hlist_node head; - unsigned long key; -}; - -struct drm_open_hash { - unsigned int size; - unsigned int order; - unsigned int fill; - struct hlist_head *table; - int use_vmalloc; -}; - - -extern int drm_ht_create(struct drm_open_hash *ht, unsigned int order); -extern int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item); -extern int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, - unsigned long seed, int bits, int shift, - unsigned long add); -extern int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item); - -extern void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key); -extern int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key); -extern int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item); -extern void drm_ht_remove(struct drm_open_hash *ht); - - -#endif diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c deleted file mode 100644 index 90f5a8d..0000000 --- a/drivers/char/drm/drm_ioc32.c +++ /dev/null @@ -1,1073 +0,0 @@ -/** - * \file drm_ioc32.c - * - * 32-bit ioctl compatibility routines for the DRM. - * - * \author Paul Mackerras - * - * Copyright (C) Paul Mackerras 2005. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm_core.h" - -#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t) -#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t) -#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t) -#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t) -#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t) - -#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t) -#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t) -#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t) -#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t) -#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t) -#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t) -#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t) - -#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t) - -#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t) -#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t) - -#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t) -#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t) - -#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t) -#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t) -#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t) -#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t) -#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t) -#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t) - -#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t) -#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t) - -#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) - -typedef struct drm_version_32 { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - u32 name_len; /**< Length of name buffer */ - u32 name; /**< Name of driver */ - u32 date_len; /**< Length of date buffer */ - u32 date; /**< User-space buffer to hold date */ - u32 desc_len; /**< Length of desc buffer */ - u32 desc; /**< User-space buffer to hold desc */ -} drm_version32_t; - -static int compat_drm_version(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_version32_t v32; - struct drm_version __user *version; - int err; - - if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) - return -EFAULT; - - version = compat_alloc_user_space(sizeof(*version)); - if (!access_ok(VERIFY_WRITE, version, sizeof(*version))) - return -EFAULT; - if (__put_user(v32.name_len, &version->name_len) - || __put_user((void __user *)(unsigned long)v32.name, - &version->name) - || __put_user(v32.date_len, &version->date_len) - || __put_user((void __user *)(unsigned long)v32.date, - &version->date) - || __put_user(v32.desc_len, &version->desc_len) - || __put_user((void __user *)(unsigned long)v32.desc, - &version->desc)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_VERSION, (unsigned long)version); - if (err) - return err; - - if (__get_user(v32.version_major, &version->version_major) - || __get_user(v32.version_minor, &version->version_minor) - || __get_user(v32.version_patchlevel, &version->version_patchlevel) - || __get_user(v32.name_len, &version->name_len) - || __get_user(v32.date_len, &version->date_len) - || __get_user(v32.desc_len, &version->desc_len)) - return -EFAULT; - - if (copy_to_user((void __user *)arg, &v32, sizeof(v32))) - return -EFAULT; - return 0; -} - -typedef struct drm_unique32 { - u32 unique_len; /**< Length of unique */ - u32 unique; /**< Unique name for driver instantiation */ -} drm_unique32_t; - -static int compat_drm_getunique(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_unique32_t uq32; - struct drm_unique __user *u; - int err; - - if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) - return -EFAULT; - - u = compat_alloc_user_space(sizeof(*u)); - if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) - return -EFAULT; - if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long)uq32.unique, - &u->unique)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_UNIQUE, (unsigned long)u); - if (err) - return err; - - if (__get_user(uq32.unique_len, &u->unique_len)) - return -EFAULT; - if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32))) - return -EFAULT; - return 0; -} - -static int compat_drm_setunique(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_unique32_t uq32; - struct drm_unique __user *u; - - if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) - return -EFAULT; - - u = compat_alloc_user_space(sizeof(*u)); - if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) - return -EFAULT; - if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long)uq32.unique, - &u->unique)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SET_UNIQUE, (unsigned long)u); -} - -typedef struct drm_map32 { - u32 offset; /**< Requested physical address (0 for SAREA)*/ - u32 size; /**< Requested physical size (bytes) */ - enum drm_map_type type; /**< Type of memory to map */ - enum drm_map_flags flags; /**< Flags */ - u32 handle; /**< User-space: "Handle" to pass to mmap() */ - int mtrr; /**< MTRR slot used */ -} drm_map32_t; - -static int compat_drm_getmap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_map32_t __user *argp = (void __user *)arg; - drm_map32_t m32; - struct drm_map __user *map; - int idx, err; - void *handle; - - if (get_user(idx, &argp->offset)) - return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) - return -EFAULT; - if (__put_user(idx, &map->offset)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_MAP, (unsigned long)map); - if (err) - return err; - - if (__get_user(m32.offset, &map->offset) - || __get_user(m32.size, &map->size) - || __get_user(m32.type, &map->type) - || __get_user(m32.flags, &map->flags) - || __get_user(handle, &map->handle) - || __get_user(m32.mtrr, &map->mtrr)) - return -EFAULT; - - m32.handle = (unsigned long)handle; - if (copy_to_user(argp, &m32, sizeof(m32))) - return -EFAULT; - return 0; - -} - -static int compat_drm_addmap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_map32_t __user *argp = (void __user *)arg; - drm_map32_t m32; - struct drm_map __user *map; - int err; - void *handle; - - if (copy_from_user(&m32, argp, sizeof(m32))) - return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) - return -EFAULT; - if (__put_user(m32.offset, &map->offset) - || __put_user(m32.size, &map->size) - || __put_user(m32.type, &map->type) - || __put_user(m32.flags, &map->flags)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_ADD_MAP, (unsigned long)map); - if (err) - return err; - - if (__get_user(m32.offset, &map->offset) - || __get_user(m32.mtrr, &map->mtrr) - || __get_user(handle, &map->handle)) - return -EFAULT; - - m32.handle = (unsigned long)handle; - if (m32.handle != (unsigned long)handle && printk_ratelimit()) - printk(KERN_ERR "compat_drm_addmap truncated handle" - " %p for type %d offset %x\n", - handle, m32.type, m32.offset); - - if (copy_to_user(argp, &m32, sizeof(m32))) - return -EFAULT; - - return 0; -} - -static int compat_drm_rmmap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_map32_t __user *argp = (void __user *)arg; - struct drm_map __user *map; - u32 handle; - - if (get_user(handle, &argp->handle)) - return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) - return -EFAULT; - if (__put_user((void *)(unsigned long)handle, &map->handle)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RM_MAP, (unsigned long)map); -} - -typedef struct drm_client32 { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - u32 pid; /**< Process ID */ - u32 uid; /**< User ID */ - u32 magic; /**< Magic */ - u32 iocs; /**< Ioctl count */ -} drm_client32_t; - -static int compat_drm_getclient(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_client32_t c32; - drm_client32_t __user *argp = (void __user *)arg; - struct drm_client __user *client; - int idx, err; - - if (get_user(idx, &argp->idx)) - return -EFAULT; - - client = compat_alloc_user_space(sizeof(*client)); - if (!access_ok(VERIFY_WRITE, client, sizeof(*client))) - return -EFAULT; - if (__put_user(idx, &client->idx)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_CLIENT, (unsigned long)client); - if (err) - return err; - - if (__get_user(c32.auth, &client->auth) - || __get_user(c32.pid, &client->pid) - || __get_user(c32.uid, &client->uid) - || __get_user(c32.magic, &client->magic) - || __get_user(c32.iocs, &client->iocs)) - return -EFAULT; - - if (copy_to_user(argp, &c32, sizeof(c32))) - return -EFAULT; - return 0; -} - -typedef struct drm_stats32 { - u32 count; - struct { - u32 value; - enum drm_stat_type type; - } data[15]; -} drm_stats32_t; - -static int compat_drm_getstats(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_stats32_t s32; - drm_stats32_t __user *argp = (void __user *)arg; - struct drm_stats __user *stats; - int i, err; - - stats = compat_alloc_user_space(sizeof(*stats)); - if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_STATS, (unsigned long)stats); - if (err) - return err; - - if (__get_user(s32.count, &stats->count)) - return -EFAULT; - for (i = 0; i < 15; ++i) - if (__get_user(s32.data[i].value, &stats->data[i].value) - || __get_user(s32.data[i].type, &stats->data[i].type)) - return -EFAULT; - - if (copy_to_user(argp, &s32, sizeof(s32))) - return -EFAULT; - return 0; -} - -typedef struct drm_buf_desc32 { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - int flags; - u32 agp_start; /**< Start address in the AGP aperture */ -} drm_buf_desc32_t; - -static int compat_drm_addbufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_desc32_t __user *argp = (void __user *)arg; - struct drm_buf_desc __user *buf; - int err; - unsigned long agp_start; - - buf = compat_alloc_user_space(sizeof(*buf)); - if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)) - || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))) - return -EFAULT; - - if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start)) - || __get_user(agp_start, &argp->agp_start) - || __put_user(agp_start, &buf->agp_start)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_ADD_BUFS, (unsigned long)buf); - if (err) - return err; - - if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start)) - || __get_user(agp_start, &buf->agp_start) - || __put_user(agp_start, &argp->agp_start)) - return -EFAULT; - - return 0; -} - -static int compat_drm_markbufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_desc32_t b32; - drm_buf_desc32_t __user *argp = (void __user *)arg; - struct drm_buf_desc __user *buf; - - if (copy_from_user(&b32, argp, sizeof(b32))) - return -EFAULT; - - buf = compat_alloc_user_space(sizeof(*buf)); - if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))) - return -EFAULT; - - if (__put_user(b32.size, &buf->size) - || __put_user(b32.low_mark, &buf->low_mark) - || __put_user(b32.high_mark, &buf->high_mark)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MARK_BUFS, (unsigned long)buf); -} - -typedef struct drm_buf_info32 { - int count; /**< Entries in list */ - u32 list; -} drm_buf_info32_t; - -static int compat_drm_infobufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_info32_t req32; - drm_buf_info32_t __user *argp = (void __user *)arg; - drm_buf_desc32_t __user *to; - struct drm_buf_info __user *request; - struct drm_buf_desc __user *list; - size_t nbytes; - int i, err; - int count, actual; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - count = req32.count; - to = (drm_buf_desc32_t __user *) (unsigned long)req32.list; - if (count < 0) - count = 0; - if (count > 0 - && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t))) - return -EFAULT; - - nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc); - request = compat_alloc_user_space(nbytes); - if (!access_ok(VERIFY_WRITE, request, nbytes)) - return -EFAULT; - list = (struct drm_buf_desc *) (request + 1); - - if (__put_user(count, &request->count) - || __put_user(list, &request->list)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_INFO_BUFS, (unsigned long)request); - if (err) - return err; - - if (__get_user(actual, &request->count)) - return -EFAULT; - if (count >= actual) - for (i = 0; i < actual; ++i) - if (__copy_in_user(&to[i], &list[i], - offsetof(struct drm_buf_desc, flags))) - return -EFAULT; - - if (__put_user(actual, &argp->count)) - return -EFAULT; - - return 0; -} - -typedef struct drm_buf_pub32 { - int idx; /**< Index into the master buffer list */ - int total; /**< Buffer size */ - int used; /**< Amount of buffer in use (for DMA) */ - u32 address; /**< Address of buffer */ -} drm_buf_pub32_t; - -typedef struct drm_buf_map32 { - int count; /**< Length of the buffer list */ - u32 virtual; /**< Mmap'd area in user-virtual */ - u32 list; /**< Buffer information */ -} drm_buf_map32_t; - -static int compat_drm_mapbufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_map32_t __user *argp = (void __user *)arg; - drm_buf_map32_t req32; - drm_buf_pub32_t __user *list32; - struct drm_buf_map __user *request; - struct drm_buf_pub __user *list; - int i, err; - int count, actual; - size_t nbytes; - void __user *addr; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - count = req32.count; - list32 = (void __user *)(unsigned long)req32.list; - - if (count < 0) - return -EINVAL; - nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub); - request = compat_alloc_user_space(nbytes); - if (!access_ok(VERIFY_WRITE, request, nbytes)) - return -EFAULT; - list = (struct drm_buf_pub *) (request + 1); - - if (__put_user(count, &request->count) - || __put_user(list, &request->list)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MAP_BUFS, (unsigned long)request); - if (err) - return err; - - if (__get_user(actual, &request->count)) - return -EFAULT; - if (count >= actual) - for (i = 0; i < actual; ++i) - if (__copy_in_user(&list32[i], &list[i], - offsetof(struct drm_buf_pub, address)) - || __get_user(addr, &list[i].address) - || __put_user((unsigned long)addr, - &list32[i].address)) - return -EFAULT; - - if (__put_user(actual, &argp->count) - || __get_user(addr, &request->virtual) - || __put_user((unsigned long)addr, &argp->virtual)) - return -EFAULT; - - return 0; -} - -typedef struct drm_buf_free32 { - int count; - u32 list; -} drm_buf_free32_t; - -static int compat_drm_freebufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_free32_t req32; - struct drm_buf_free __user *request; - drm_buf_free32_t __user *argp = (void __user *)arg; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) - return -EFAULT; - if (__put_user(req32.count, &request->count) - || __put_user((int __user *)(unsigned long)req32.list, - &request->list)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_FREE_BUFS, (unsigned long)request); -} - -typedef struct drm_ctx_priv_map32 { - unsigned int ctx_id; /**< Context requesting private mapping */ - u32 handle; /**< Handle of map */ -} drm_ctx_priv_map32_t; - -static int compat_drm_setsareactx(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_priv_map32_t req32; - struct drm_ctx_priv_map __user *request; - drm_ctx_priv_map32_t __user *argp = (void __user *)arg; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) - return -EFAULT; - if (__put_user(req32.ctx_id, &request->ctx_id) - || __put_user((void *)(unsigned long)req32.handle, - &request->handle)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); -} - -static int compat_drm_getsareactx(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct drm_ctx_priv_map __user *request; - drm_ctx_priv_map32_t __user *argp = (void __user *)arg; - int err; - unsigned int ctx_id; - void *handle; - - if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(ctx_id, &argp->ctx_id)) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) - return -EFAULT; - if (__put_user(ctx_id, &request->ctx_id)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); - if (err) - return err; - - if (__get_user(handle, &request->handle) - || __put_user((unsigned long)handle, &argp->handle)) - return -EFAULT; - - return 0; -} - -typedef struct drm_ctx_res32 { - int count; - u32 contexts; -} drm_ctx_res32_t; - -static int compat_drm_resctx(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_res32_t __user *argp = (void __user *)arg; - drm_ctx_res32_t res32; - struct drm_ctx_res __user *res; - int err; - - if (copy_from_user(&res32, argp, sizeof(res32))) - return -EFAULT; - - res = compat_alloc_user_space(sizeof(*res)); - if (!access_ok(VERIFY_WRITE, res, sizeof(*res))) - return -EFAULT; - if (__put_user(res32.count, &res->count) - || __put_user((struct drm_ctx __user *) (unsigned long)res32.contexts, - &res->contexts)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RES_CTX, (unsigned long)res); - if (err) - return err; - - if (__get_user(res32.count, &res->count) - || __put_user(res32.count, &argp->count)) - return -EFAULT; - - return 0; -} - -typedef struct drm_dma32 { - int context; /**< Context handle */ - int send_count; /**< Number of buffers to send */ - u32 send_indices; /**< List of handles to buffers */ - u32 send_sizes; /**< Lengths of data to send */ - enum drm_dma_flags flags; /**< Flags */ - int request_count; /**< Number of buffers requested */ - int request_size; /**< Desired size for buffers */ - u32 request_indices; /**< Buffer information */ - u32 request_sizes; - int granted_count; /**< Number of buffers granted */ -} drm_dma32_t; - -static int compat_drm_dma(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_dma32_t d32; - drm_dma32_t __user *argp = (void __user *)arg; - struct drm_dma __user *d; - int err; - - if (copy_from_user(&d32, argp, sizeof(d32))) - return -EFAULT; - - d = compat_alloc_user_space(sizeof(*d)); - if (!access_ok(VERIFY_WRITE, d, sizeof(*d))) - return -EFAULT; - - if (__put_user(d32.context, &d->context) - || __put_user(d32.send_count, &d->send_count) - || __put_user((int __user *)(unsigned long)d32.send_indices, - &d->send_indices) - || __put_user((int __user *)(unsigned long)d32.send_sizes, - &d->send_sizes) - || __put_user(d32.flags, &d->flags) - || __put_user(d32.request_count, &d->request_count) - || __put_user((int __user *)(unsigned long)d32.request_indices, - &d->request_indices) - || __put_user((int __user *)(unsigned long)d32.request_sizes, - &d->request_sizes)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_DMA, (unsigned long)d); - if (err) - return err; - - if (__get_user(d32.request_size, &d->request_size) - || __get_user(d32.granted_count, &d->granted_count) - || __put_user(d32.request_size, &argp->request_size) - || __put_user(d32.granted_count, &argp->granted_count)) - return -EFAULT; - - return 0; -} - -#if __OS_HAS_AGP -typedef struct drm_agp_mode32 { - u32 mode; /**< AGP mode */ -} drm_agp_mode32_t; - -static int compat_drm_agp_enable(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_mode32_t __user *argp = (void __user *)arg; - drm_agp_mode32_t m32; - struct drm_agp_mode __user *mode; - - if (get_user(m32.mode, &argp->mode)) - return -EFAULT; - - mode = compat_alloc_user_space(sizeof(*mode)); - if (put_user(m32.mode, &mode->mode)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); -} - -typedef struct drm_agp_info32 { - int agp_version_major; - int agp_version_minor; - u32 mode; - u32 aperture_base; /* physical address */ - u32 aperture_size; /* bytes */ - u32 memory_allowed; /* bytes */ - u32 memory_used; - - /* PCI information */ - unsigned short id_vendor; - unsigned short id_device; -} drm_agp_info32_t; - -static int compat_drm_agp_info(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_info32_t __user *argp = (void __user *)arg; - drm_agp_info32_t i32; - struct drm_agp_info __user *info; - int err; - - info = compat_alloc_user_space(sizeof(*info)); - if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_INFO, (unsigned long)info); - if (err) - return err; - - if (__get_user(i32.agp_version_major, &info->agp_version_major) - || __get_user(i32.agp_version_minor, &info->agp_version_minor) - || __get_user(i32.mode, &info->mode) - || __get_user(i32.aperture_base, &info->aperture_base) - || __get_user(i32.aperture_size, &info->aperture_size) - || __get_user(i32.memory_allowed, &info->memory_allowed) - || __get_user(i32.memory_used, &info->memory_used) - || __get_user(i32.id_vendor, &info->id_vendor) - || __get_user(i32.id_device, &info->id_device)) - return -EFAULT; - - if (copy_to_user(argp, &i32, sizeof(i32))) - return -EFAULT; - - return 0; -} - -typedef struct drm_agp_buffer32 { - u32 size; /**< In bytes -- will round to page boundary */ - u32 handle; /**< Used for binding / unbinding */ - u32 type; /**< Type of memory to allocate */ - u32 physical; /**< Physical used by i810 */ -} drm_agp_buffer32_t; - -static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_buffer32_t __user *argp = (void __user *)arg; - drm_agp_buffer32_t req32; - struct drm_agp_buffer __user *request; - int err; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.size, &request->size) - || __put_user(req32.type, &request->type)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_ALLOC, (unsigned long)request); - if (err) - return err; - - if (__get_user(req32.handle, &request->handle) - || __get_user(req32.physical, &request->physical) - || copy_to_user(argp, &req32, sizeof(req32))) { - drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_FREE, (unsigned long)request); - return -EFAULT; - } - - return 0; -} - -static int compat_drm_agp_free(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_buffer32_t __user *argp = (void __user *)arg; - struct drm_agp_buffer __user *request; - u32 handle; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || get_user(handle, &argp->handle) - || __put_user(handle, &request->handle)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_FREE, (unsigned long)request); -} - -typedef struct drm_agp_binding32 { - u32 handle; /**< From drm_agp_buffer */ - u32 offset; /**< In bytes -- will round to page boundary */ -} drm_agp_binding32_t; - -static int compat_drm_agp_bind(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_binding32_t __user *argp = (void __user *)arg; - drm_agp_binding32_t req32; - struct drm_agp_binding __user *request; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.handle, &request->handle) - || __put_user(req32.offset, &request->offset)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_BIND, (unsigned long)request); -} - -static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_binding32_t __user *argp = (void __user *)arg; - struct drm_agp_binding __user *request; - u32 handle; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || get_user(handle, &argp->handle) - || __put_user(handle, &request->handle)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_AGP_UNBIND, (unsigned long)request); -} -#endif /* __OS_HAS_AGP */ - -typedef struct drm_scatter_gather32 { - u32 size; /**< In bytes -- will round to page boundary */ - u32 handle; /**< Used for mapping / unmapping */ -} drm_scatter_gather32_t; - -static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_scatter_gather32_t __user *argp = (void __user *)arg; - struct drm_scatter_gather __user *request; - int err; - unsigned long x; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(x, &argp->size) - || __put_user(x, &request->size)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SG_ALLOC, (unsigned long)request); - if (err) - return err; - - /* XXX not sure about the handle conversion here... */ - if (__get_user(x, &request->handle) - || __put_user(x >> PAGE_SHIFT, &argp->handle)) - return -EFAULT; - - return 0; -} - -static int compat_drm_sg_free(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_scatter_gather32_t __user *argp = (void __user *)arg; - struct drm_scatter_gather __user *request; - unsigned long x; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(x, &argp->handle) - || __put_user(x << PAGE_SHIFT, &request->handle)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_SG_FREE, (unsigned long)request); -} - -struct drm_wait_vblank_request32 { - enum drm_vblank_seq_type type; - unsigned int sequence; - u32 signal; -}; - -struct drm_wait_vblank_reply32 { - enum drm_vblank_seq_type type; - unsigned int sequence; - s32 tval_sec; - s32 tval_usec; -}; - -typedef union drm_wait_vblank32 { - struct drm_wait_vblank_request32 request; - struct drm_wait_vblank_reply32 reply; -} drm_wait_vblank32_t; - -static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_wait_vblank32_t __user *argp = (void __user *)arg; - drm_wait_vblank32_t req32; - union drm_wait_vblank __user *request; - int err; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.request.type, &request->request.type) - || __put_user(req32.request.sequence, &request->request.sequence) - || __put_user(req32.request.signal, &request->request.signal)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); - if (err) - return err; - - if (__get_user(req32.reply.type, &request->reply.type) - || __get_user(req32.reply.sequence, &request->reply.sequence) - || __get_user(req32.reply.tval_sec, &request->reply.tval_sec) - || __get_user(req32.reply.tval_usec, &request->reply.tval_usec)) - return -EFAULT; - - if (copy_to_user(argp, &req32, sizeof(req32))) - return -EFAULT; - - return 0; -} - -drm_ioctl_compat_t *drm_compat_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats, - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap, - [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx, - [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx, - [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma, -#if __OS_HAS_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind, -#endif - [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc, - [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free, - [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/drm. - * - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn; - int ret; - - /* Assume that ioctls without an explicit compat routine will just - * work. This may not always be a good assumption, but it's better - * than always failing. - */ - if (nr >= ARRAY_SIZE(drm_compat_ioctls)) - return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); - - fn = drm_compat_ioctls[nr]; - - lock_kernel(); /* XXX for now */ - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - - return ret; -} - -EXPORT_SYMBOL(drm_compat_ioctl); diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c deleted file mode 100644 index 16829fb..0000000 --- a/drivers/char/drm/drm_ioctl.c +++ /dev/null @@ -1,352 +0,0 @@ -/** - * \file drm_ioctl.c - * IOCTL processing for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_core.h" - -#include "linux/pci.h" - -/** - * Get the bus id. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_unique structure. - * \return zero on success or a negative number on failure. - * - * Copies the bus id from drm_device::unique into user space. - */ -int drm_getunique(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_unique *u = data; - - if (u->unique_len >= dev->unique_len) { - if (copy_to_user(u->unique, dev->unique, dev->unique_len)) - return -EFAULT; - } - u->unique_len = dev->unique_len; - - return 0; -} - -/** - * Set the bus id. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_unique structure. - * \return zero on success or a negative number on failure. - * - * Copies the bus id from userspace into drm_device::unique, and verifies that - * it matches the device this DRM is attached to (EINVAL otherwise). Deprecated - * in interface version 1.1 and will return EBUSY when setversion has requested - * version 1.1 or greater. - */ -int drm_setunique(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_unique *u = data; - int domain, bus, slot, func, ret; - - if (dev->unique_len || dev->unique) - return -EBUSY; - - if (!u->unique_len || u->unique_len > 1024) - return -EINVAL; - - dev->unique_len = u->unique_len; - dev->unique = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER); - if (!dev->unique) - return -ENOMEM; - if (copy_from_user(dev->unique, u->unique, dev->unique_len)) - return -EFAULT; - - dev->unique[dev->unique_len] = '\0'; - - dev->devname = - drm_alloc(strlen(dev->driver->pci_driver.name) + - strlen(dev->unique) + 2, DRM_MEM_DRIVER); - if (!dev->devname) - return -ENOMEM; - - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, - dev->unique); - - /* Return error if the busid submitted doesn't match the device's actual - * busid. - */ - ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func); - if (ret != 3) - return -EINVAL; - domain = bus >> 8; - bus &= 0xff; - - if ((domain != drm_get_pci_domain(dev)) || - (bus != dev->pdev->bus->number) || - (slot != PCI_SLOT(dev->pdev->devfn)) || - (func != PCI_FUNC(dev->pdev->devfn))) - return -EINVAL; - - return 0; -} - -static int drm_set_busid(struct drm_device * dev) -{ - int len; - - if (dev->unique != NULL) - return 0; - - dev->unique_len = 40; - dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); - if (dev->unique == NULL) - return -ENOMEM; - - len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", - drm_get_pci_domain(dev), dev->pdev->bus->number, - PCI_SLOT(dev->pdev->devfn), - PCI_FUNC(dev->pdev->devfn)); - - if (len > dev->unique_len) - DRM_ERROR("Unique buffer overflowed\n"); - - dev->devname = - drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + - 2, DRM_MEM_DRIVER); - if (dev->devname == NULL) - return -ENOMEM; - - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, - dev->unique); - - return 0; -} - -/** - * Get a mapping information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_map structure. - * - * \return zero on success or a negative number on failure. - * - * Searches for the mapping with the specified offset and copies its information - * into userspace - */ -int drm_getmap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *map = data; - struct drm_map_list *r_list = NULL; - struct list_head *list; - int idx; - int i; - - idx = map->offset; - - mutex_lock(&dev->struct_mutex); - if (idx < 0) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - i = 0; - list_for_each(list, &dev->maplist) { - if (i == idx) { - r_list = list_entry(list, struct drm_map_list, head); - break; - } - i++; - } - if (!r_list || !r_list->map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - map->offset = r_list->map->offset; - map->size = r_list->map->size; - map->type = r_list->map->type; - map->flags = r_list->map->flags; - map->handle = (void *)(unsigned long) r_list->user_token; - map->mtrr = r_list->map->mtrr; - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Get client information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_client structure. - * - * \return zero on success or a negative number on failure. - * - * Searches for the client with the specified index and copies its information - * into userspace - */ -int drm_getclient(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_client *client = data; - struct drm_file *pt; - int idx; - int i; - - idx = client->idx; - mutex_lock(&dev->struct_mutex); - - i = 0; - list_for_each_entry(pt, &dev->filelist, lhead) { - if (i++ >= idx) { - client->auth = pt->authenticated; - client->pid = pt->pid; - client->uid = pt->uid; - client->magic = pt->magic; - client->iocs = pt->ioctl_count; - mutex_unlock(&dev->struct_mutex); - - return 0; - } - } - mutex_unlock(&dev->struct_mutex); - - return -EINVAL; -} - -/** - * Get statistics information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_stats structure. - * - * \return zero on success or a negative number on failure. - */ -int drm_getstats(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_stats *stats = data; - int i; - - memset(stats, 0, sizeof(*stats)); - - mutex_lock(&dev->struct_mutex); - - for (i = 0; i < dev->counters; i++) { - if (dev->types[i] == _DRM_STAT_LOCK) - stats->data[i].value = - (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); - else - stats->data[i].value = atomic_read(&dev->counts[i]); - stats->data[i].type = dev->types[i]; - } - - stats->count = dev->counters; - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Setversion ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_lock structure. - * \return zero on success or negative number on failure. - * - * Sets the requested interface version - */ -int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_set_version *sv = data; - int if_version, retcode = 0; - - if (sv->drm_di_major != -1) { - if (sv->drm_di_major != DRM_IF_MAJOR || - sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) { - retcode = -EINVAL; - goto done; - } - if_version = DRM_IF_VERSION(sv->drm_di_major, - sv->drm_di_minor); - dev->if_version = max(if_version, dev->if_version); - if (sv->drm_di_minor >= 1) { - /* - * Version 1.1 includes tying of DRM to specific device - */ - drm_set_busid(dev); - } - } - - if (sv->drm_dd_major != -1) { - if (sv->drm_dd_major != dev->driver->major || - sv->drm_dd_minor < 0 || sv->drm_dd_minor > - dev->driver->minor) { - retcode = -EINVAL; - goto done; - } - - if (dev->driver->set_version) - dev->driver->set_version(dev, sv); - } - -done: - sv->drm_di_major = DRM_IF_MAJOR; - sv->drm_di_minor = DRM_IF_MINOR; - sv->drm_dd_major = dev->driver->major; - sv->drm_dd_minor = dev->driver->minor; - - return retcode; -} - -/** No-op ioctl. */ -int drm_noop(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - return 0; -} diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c deleted file mode 100644 index 089c015..0000000 --- a/drivers/char/drm/drm_irq.c +++ /dev/null @@ -1,462 +0,0 @@ -/** - * \file drm_irq.c - * IRQ support - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -#include /* For task queue support */ - -/** - * Get interrupt from bus id. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_irq_busid structure. - * \return zero on success or a negative number on failure. - * - * Finds the PCI device with the specified bus id and gets its IRQ number. - * This IOCTL is deprecated, and will now return EINVAL for any busid not equal - * to that of the device that this DRM instance attached to. - */ -int drm_irq_by_busid(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_irq_busid *p = data; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; - - if ((p->busnum >> 8) != drm_get_pci_domain(dev) || - (p->busnum & 0xff) != dev->pdev->bus->number || - p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) - return -EINVAL; - - p->irq = dev->irq; - - DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, - p->irq); - - return 0; -} - -/** - * Install IRQ handler. - * - * \param dev DRM device. - * \param irq IRQ number. - * - * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver - * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions - * before and after the installation. - */ -static int drm_irq_install(struct drm_device * dev) -{ - int ret; - unsigned long sh_flags = 0; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; - - if (dev->irq == 0) - return -EINVAL; - - mutex_lock(&dev->struct_mutex); - - /* Driver must have been initialized */ - if (!dev->dev_private) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - if (dev->irq_enabled) { - mutex_unlock(&dev->struct_mutex); - return -EBUSY; - } - dev->irq_enabled = 1; - mutex_unlock(&dev->struct_mutex); - - DRM_DEBUG("irq=%d\n", dev->irq); - - if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { - init_waitqueue_head(&dev->vbl_queue); - - spin_lock_init(&dev->vbl_lock); - - INIT_LIST_HEAD(&dev->vbl_sigs); - INIT_LIST_HEAD(&dev->vbl_sigs2); - - dev->vbl_pending = 0; - } - - /* Before installing handler */ - dev->driver->irq_preinstall(dev); - - /* Install handler */ - if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) - sh_flags = IRQF_SHARED; - - ret = request_irq(dev->irq, dev->driver->irq_handler, - sh_flags, dev->devname, dev); - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - return ret; - } - - /* After installing handler */ - dev->driver->irq_postinstall(dev); - - return 0; -} - -/** - * Uninstall the IRQ handler. - * - * \param dev DRM device. - * - * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq. - */ -int drm_irq_uninstall(struct drm_device * dev) -{ - int irq_enabled; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; - - mutex_lock(&dev->struct_mutex); - irq_enabled = dev->irq_enabled; - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - - if (!irq_enabled) - return -EINVAL; - - DRM_DEBUG("irq=%d\n", dev->irq); - - dev->driver->irq_uninstall(dev); - - free_irq(dev->irq, dev); - - dev->locked_tasklet_func = NULL; - - return 0; -} - -EXPORT_SYMBOL(drm_irq_uninstall); - -/** - * IRQ control ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_control structure. - * \return zero on success or a negative number on failure. - * - * Calls irq_install() or irq_uninstall() according to \p arg. - */ -int drm_control(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_control *ctl = data; - - /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */ - - - switch (ctl->func) { - case DRM_INST_HANDLER: - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return 0; - if (dev->if_version < DRM_IF_VERSION(1, 2) && - ctl->irq != dev->irq) - return -EINVAL; - return drm_irq_install(dev); - case DRM_UNINST_HANDLER: - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return 0; - return drm_irq_uninstall(dev); - default: - return -EINVAL; - } -} - -/** - * Wait for VBLANK. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param data user argument, pointing to a drm_wait_vblank structure. - * \return zero on success or a negative number on failure. - * - * Verifies the IRQ is installed. - * - * If a signal is requested checks if this task has already scheduled the same signal - * for the same vblank sequence number - nothing to be done in - * that case. If the number of tasks waiting for the interrupt exceeds 100 the - * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this - * task. - * - * If a signal is not requested, then calls vblank_wait(). - */ -int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - union drm_wait_vblank *vblwait = data; - struct timeval now; - int ret = 0; - unsigned int flags, seq; - - if ((!dev->irq) || (!dev->irq_enabled)) - return -EINVAL; - - if (vblwait->request.type & - ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { - DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", - vblwait->request.type, - (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)); - return -EINVAL; - } - - flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; - - if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? - DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) - return -EINVAL; - - seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 - : &dev->vbl_received); - - switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { - case _DRM_VBLANK_RELATIVE: - vblwait->request.sequence += seq; - vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; - case _DRM_VBLANK_ABSOLUTE: - break; - default: - return -EINVAL; - } - - if ((flags & _DRM_VBLANK_NEXTONMISS) && - (seq - vblwait->request.sequence) <= (1<<23)) { - vblwait->request.sequence = seq + 1; - } - - if (flags & _DRM_VBLANK_SIGNAL) { - unsigned long irqflags; - struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) - ? &dev->vbl_sigs2 : &dev->vbl_sigs; - struct drm_vbl_sig *vbl_sig; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); - - /* Check if this task has already scheduled the same signal - * for the same vblank sequence number; nothing to be done in - * that case - */ - list_for_each_entry(vbl_sig, vbl_sigs, head) { - if (vbl_sig->sequence == vblwait->request.sequence - && vbl_sig->info.si_signo == - vblwait->request.signal - && vbl_sig->task == current) { - spin_unlock_irqrestore(&dev->vbl_lock, - irqflags); - vblwait->reply.sequence = seq; - goto done; - } - } - - if (dev->vbl_pending >= 100) { - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - return -EBUSY; - } - - dev->vbl_pending++; - - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - if (! - (vbl_sig = - drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { - return -ENOMEM; - } - - memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); - - vbl_sig->sequence = vblwait->request.sequence; - vbl_sig->info.si_signo = vblwait->request.signal; - vbl_sig->task = current; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); - - list_add_tail(&vbl_sig->head, vbl_sigs); - - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - vblwait->reply.sequence = seq; - } else { - if (flags & _DRM_VBLANK_SECONDARY) { - if (dev->driver->vblank_wait2) - ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); - } else if (dev->driver->vblank_wait) - ret = - dev->driver->vblank_wait(dev, - &vblwait->request.sequence); - - do_gettimeofday(&now); - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; - } - - done: - return ret; -} - -/** - * Send the VBLANK signals. - * - * \param dev DRM device. - * - * Sends a signal for each task in drm_device::vbl_sigs and empties the list. - * - * If a signal is not requested, then calls vblank_wait(). - */ -void drm_vbl_send_signals(struct drm_device * dev) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&dev->vbl_lock, flags); - - for (i = 0; i < 2; i++) { - struct drm_vbl_sig *vbl_sig, *tmp; - struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs; - unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 : - &dev->vbl_received); - - list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { - if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { - vbl_sig->info.si_code = vbl_seq; - send_sig_info(vbl_sig->info.si_signo, - &vbl_sig->info, vbl_sig->task); - - list_del(&vbl_sig->head); - - drm_free(vbl_sig, sizeof(*vbl_sig), - DRM_MEM_DRIVER); - - dev->vbl_pending--; - } - } - } - - spin_unlock_irqrestore(&dev->vbl_lock, flags); -} - -EXPORT_SYMBOL(drm_vbl_send_signals); - -/** - * Tasklet wrapper function. - * - * \param data DRM device in disguise. - * - * Attempts to grab the HW lock and calls the driver callback on success. On - * failure, leave the lock marked as contended so the callback can be called - * from drm_unlock(). - */ -static void drm_locked_tasklet_func(unsigned long data) -{ - struct drm_device *dev = (struct drm_device *)data; - unsigned long irqflags; - - spin_lock_irqsave(&dev->tasklet_lock, irqflags); - - if (!dev->locked_tasklet_func || - !drm_lock_take(&dev->lock, - DRM_KERNEL_CONTEXT)) { - spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); - return; - } - - dev->lock.lock_time = jiffies; - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); - - dev->locked_tasklet_func(dev); - - drm_lock_free(&dev->lock, - DRM_KERNEL_CONTEXT); - - dev->locked_tasklet_func = NULL; - - spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); -} - -/** - * Schedule a tasklet to call back a driver hook with the HW lock held. - * - * \param dev DRM device. - * \param func Driver callback. - * - * This is intended for triggering actions that require the HW lock from an - * interrupt handler. The lock will be grabbed ASAP after the interrupt handler - * completes. Note that the callback may be called from interrupt or process - * context, it must not make any assumptions about this. Also, the HW lock will - * be held with the kernel context or any client context. - */ -void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device *)) -{ - unsigned long irqflags; - static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0); - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) || - test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state)) - return; - - spin_lock_irqsave(&dev->tasklet_lock, irqflags); - - if (dev->locked_tasklet_func) { - spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); - return; - } - - dev->locked_tasklet_func = func; - - spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); - - drm_tasklet.data = (unsigned long)dev; - - tasklet_hi_schedule(&drm_tasklet); -} -EXPORT_SYMBOL(drm_locked_tasklet); diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c deleted file mode 100644 index 0998723..0000000 --- a/drivers/char/drm/drm_lock.c +++ /dev/null @@ -1,391 +0,0 @@ -/** - * \file drm_lock.c - * IOCTLs for locking - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -static int drm_notifier(void *priv); - -/** - * Lock ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_lock structure. - * \return zero on success or negative number on failure. - * - * Add the current task to the lock wait queue, and attempt to take to lock. - */ -int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - DECLARE_WAITQUEUE(entry, current); - struct drm_lock *lock = data; - int ret = 0; - - ++file_priv->lock_count; - - if (lock->context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - task_pid_nr(current), lock->context); - return -EINVAL; - } - - DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock->context, task_pid_nr(current), - dev->lock.hw_lock->lock, lock->flags); - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)) - if (lock->context < 0) - return -EINVAL; - - add_wait_queue(&dev->lock.lock_queue, &entry); - spin_lock_bh(&dev->lock.spinlock); - dev->lock.user_waiters++; - spin_unlock_bh(&dev->lock.spinlock); - for (;;) { - __set_current_state(TASK_INTERRUPTIBLE); - if (!dev->lock.hw_lock) { - /* Device has been unregistered */ - ret = -EINTR; - break; - } - if (drm_lock_take(&dev->lock, lock->context)) { - dev->lock.file_priv = file_priv; - dev->lock.lock_time = jiffies; - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); - break; /* Got lock */ - } - - /* Contention */ - schedule(); - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - } - spin_lock_bh(&dev->lock.spinlock); - dev->lock.user_waiters--; - spin_unlock_bh(&dev->lock.spinlock); - __set_current_state(TASK_RUNNING); - remove_wait_queue(&dev->lock.lock_queue, &entry); - - DRM_DEBUG("%d %s\n", lock->context, - ret ? "interrupted" : "has lock"); - if (ret) return ret; - - sigemptyset(&dev->sigmask); - sigaddset(&dev->sigmask, SIGSTOP); - sigaddset(&dev->sigmask, SIGTSTP); - sigaddset(&dev->sigmask, SIGTTIN); - sigaddset(&dev->sigmask, SIGTTOU); - dev->sigdata.context = lock->context; - dev->sigdata.lock = dev->lock.hw_lock; - block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); - - if (dev->driver->dma_ready && (lock->flags & _DRM_LOCK_READY)) - dev->driver->dma_ready(dev); - - if (dev->driver->dma_quiescent && (lock->flags & _DRM_LOCK_QUIESCENT)) - { - if (dev->driver->dma_quiescent(dev)) { - DRM_DEBUG("%d waiting for DMA quiescent\n", - lock->context); - return -EBUSY; - } - } - - if (dev->driver->kernel_context_switch && - dev->last_context != lock->context) { - dev->driver->kernel_context_switch(dev, dev->last_context, - lock->context); - } - - return 0; -} - -/** - * Unlock ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_lock structure. - * \return zero on success or negative number on failure. - * - * Transfer and free the lock. - */ -int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_lock *lock = data; - unsigned long irqflags; - - if (lock->context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - task_pid_nr(current), lock->context); - return -EINVAL; - } - - spin_lock_irqsave(&dev->tasklet_lock, irqflags); - - if (dev->locked_tasklet_func) { - dev->locked_tasklet_func(dev); - - dev->locked_tasklet_func = NULL; - } - - spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); - - atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); - - /* kernel_context_switch isn't used by any of the x86 drm - * modules but is required by the Sparc driver. - */ - if (dev->driver->kernel_context_switch_unlock) - dev->driver->kernel_context_switch_unlock(dev); - else { - if (drm_lock_free(&dev->lock,lock->context)) { - /* FIXME: Should really bail out here. */ - } - } - - unblock_all_signals(); - return 0; -} - -/** - * Take the heavyweight lock. - * - * \param lock lock pointer. - * \param context locking context. - * \return one if the lock is held, or zero otherwise. - * - * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. - */ -int drm_lock_take(struct drm_lock_data *lock_data, - unsigned int context) -{ - unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock_bh(&lock_data->spinlock); - do { - old = *lock; - if (old & _DRM_LOCK_HELD) - new = old | _DRM_LOCK_CONT; - else { - new = context | _DRM_LOCK_HELD | - ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ? - _DRM_LOCK_CONT : 0); - } - prev = cmpxchg(lock, old, new); - } while (prev != old); - spin_unlock_bh(&lock_data->spinlock); - - if (_DRM_LOCKING_CONTEXT(old) == context) { - if (old & _DRM_LOCK_HELD) { - if (context != DRM_KERNEL_CONTEXT) { - DRM_ERROR("%d holds heavyweight lock\n", - context); - } - return 0; - } - } - - if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) { - /* Have lock */ - return 1; - } - return 0; -} - -/** - * This takes a lock forcibly and hands it to context. Should ONLY be used - * inside *_unlock to give lock to kernel before calling *_dma_schedule. - * - * \param dev DRM device. - * \param lock lock pointer. - * \param context locking context. - * \return always one. - * - * Resets the lock file pointer. - * Marks the lock as held by the given context, via the \p cmpxchg instruction. - */ -static int drm_lock_transfer(struct drm_lock_data *lock_data, - unsigned int context) -{ - unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - lock_data->file_priv = NULL; - do { - old = *lock; - new = context | _DRM_LOCK_HELD; - prev = cmpxchg(lock, old, new); - } while (prev != old); - return 1; -} - -/** - * Free lock. - * - * \param dev DRM device. - * \param lock lock. - * \param context context. - * - * Resets the lock file pointer. - * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task - * waiting on the lock queue. - */ -int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) -{ - unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock_bh(&lock_data->spinlock); - if (lock_data->kernel_waiters != 0) { - drm_lock_transfer(lock_data, 0); - lock_data->idle_has_lock = 1; - spin_unlock_bh(&lock_data->spinlock); - return 1; - } - spin_unlock_bh(&lock_data->spinlock); - - do { - old = *lock; - new = _DRM_LOCKING_CONTEXT(old); - prev = cmpxchg(lock, old, new); - } while (prev != old); - - if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d\n", - context, _DRM_LOCKING_CONTEXT(old)); - return 1; - } - wake_up_interruptible(&lock_data->lock_queue); - return 0; -} - -/** - * If we get here, it means that the process has called DRM_IOCTL_LOCK - * without calling DRM_IOCTL_UNLOCK. - * - * If the lock is not held, then let the signal proceed as usual. If the lock - * is held, then set the contended flag and keep the signal blocked. - * - * \param priv pointer to a drm_sigdata structure. - * \return one if the signal should be delivered normally, or zero if the - * signal should be blocked. - */ -static int drm_notifier(void *priv) -{ - struct drm_sigdata *s = (struct drm_sigdata *) priv; - unsigned int old, new, prev; - - /* Allow signal delivery if lock isn't held */ - if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock) - || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) - return 1; - - /* Otherwise, set flag to force call to - drmUnlock */ - do { - old = s->lock->lock; - new = old | _DRM_LOCK_CONT; - prev = cmpxchg(&s->lock->lock, old, new); - } while (prev != old); - return 0; -} - -/** - * This function returns immediately and takes the hw lock - * with the kernel context if it is free, otherwise it gets the highest priority when and if - * it is eventually released. - * - * This guarantees that the kernel will _eventually_ have the lock _unless_ it is held - * by a blocked process. (In the latter case an explicit wait for the hardware lock would cause - * a deadlock, which is why the "idlelock" was invented). - * - * This should be sufficient to wait for GPU idle without - * having to worry about starvation. - */ - -void drm_idlelock_take(struct drm_lock_data *lock_data) -{ - int ret = 0; - - spin_lock_bh(&lock_data->spinlock); - lock_data->kernel_waiters++; - if (!lock_data->idle_has_lock) { - - spin_unlock_bh(&lock_data->spinlock); - ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); - spin_lock_bh(&lock_data->spinlock); - - if (ret == 1) - lock_data->idle_has_lock = 1; - } - spin_unlock_bh(&lock_data->spinlock); -} -EXPORT_SYMBOL(drm_idlelock_take); - -void drm_idlelock_release(struct drm_lock_data *lock_data) -{ - unsigned int old, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock_bh(&lock_data->spinlock); - if (--lock_data->kernel_waiters == 0) { - if (lock_data->idle_has_lock) { - do { - old = *lock; - prev = cmpxchg(lock, old, DRM_KERNEL_CONTEXT); - } while (prev != old); - wake_up_interruptible(&lock_data->lock_queue); - lock_data->idle_has_lock = 0; - } - } - spin_unlock_bh(&lock_data->spinlock); -} -EXPORT_SYMBOL(drm_idlelock_release); - - -int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv) -{ - return (file_priv->lock_count && dev->lock.hw_lock && - _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.file_priv == file_priv); -} - -EXPORT_SYMBOL(drm_i_have_hw_lock); diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c deleted file mode 100644 index 845081b4..0000000 --- a/drivers/char/drm/drm_memory.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * \file drm_memory.c - * Memory management wrappers for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -#ifdef DEBUG_MEMORY -#include "drm_memory_debug.h" -#else - -/** No-op. */ -void drm_mem_init(void) -{ -} - -/** - * Called when "/proc/dri/%dev%/mem" is read. - * - * \param buf output buffer. - * \param start start of output data. - * \param offset requested start offset. - * \param len requested number of bytes. - * \param eof whether there is no more data to return. - * \param data private data. - * \return number of written bytes. - * - * No-op. - */ -int drm_mem_info(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ - return 0; -} - -/** Wrapper around kmalloc() and kfree() */ -void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) -{ - void *pt; - - if (!(pt = kmalloc(size, GFP_KERNEL))) - return NULL; - if (oldpt && oldsize) { - memcpy(pt, oldpt, oldsize); - kfree(oldpt); - } - return pt; -} - -#if __OS_HAS_AGP -static void *agp_remap(unsigned long offset, unsigned long size, - struct drm_device * dev) -{ - unsigned long *phys_addr_map, i, num_pages = - PAGE_ALIGN(size) / PAGE_SIZE; - struct drm_agp_mem *agpmem; - struct page **page_map; - void *addr; - - size = PAGE_ALIGN(size); - -#ifdef __alpha__ - offset -= dev->hose->mem_space->start; -#endif - - list_for_each_entry(agpmem, &dev->agp->memory, head) - if (agpmem->bound <= offset - && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= - (offset + size)) - break; - if (!agpmem) - return NULL; - - /* - * OK, we're mapping AGP space on a chipset/platform on which memory accesses by - * the CPU do not get remapped by the GART. We fix this by using the kernel's - * page-table instead (that's probably faster anyhow...). - */ - /* note: use vmalloc() because num_pages could be large... */ - page_map = vmalloc(num_pages * sizeof(struct page *)); - if (!page_map) - return NULL; - - phys_addr_map = - agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; - for (i = 0; i < num_pages; ++i) - page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); - addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); - vfree(page_map); - - return addr; -} - -/** Wrapper around agp_allocate_memory() */ -DRM_AGP_MEM *drm_alloc_agp(struct drm_device * dev, int pages, u32 type) -{ - return drm_agp_allocate_memory(dev->agp->bridge, pages, type); -} - -/** Wrapper around agp_free_memory() */ -int drm_free_agp(DRM_AGP_MEM * handle, int pages) -{ - return drm_agp_free_memory(handle) ? 0 : -EINVAL; -} - -/** Wrapper around agp_bind_memory() */ -int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) -{ - return drm_agp_bind_memory(handle, start); -} - -/** Wrapper around agp_unbind_memory() */ -int drm_unbind_agp(DRM_AGP_MEM * handle) -{ - return drm_agp_unbind_memory(handle); -} - -#else /* __OS_HAS_AGP */ -static inline void *agp_remap(unsigned long offset, unsigned long size, - struct drm_device * dev) -{ - return NULL; -} - -#endif /* agp */ - -#endif /* debug_memory */ - -void drm_core_ioremap(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(map->offset, map->size); -} -EXPORT_SYMBOL(drm_core_ioremap); - -void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) -{ - if (!map->handle || !map->size) - return; - - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - vunmap(map->handle); - else - iounmap(map->handle); -} -EXPORT_SYMBOL(drm_core_ioremapfree); diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h deleted file mode 100644 index 63e425b..0000000 --- a/drivers/char/drm/drm_memory.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * \file drm_memory.h - * Memory management wrappers for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "drmP.h" - -/** - * Cut down version of drm_memory_debug.h, which used to be called - * drm_memory.h. - */ - -#if __OS_HAS_AGP - -#include - -#ifdef HAVE_PAGE_AGP -#include -#else -# ifdef __powerpc__ -# define PAGE_AGP __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) -# else -# define PAGE_AGP PAGE_KERNEL -# endif -#endif - -#else /* __OS_HAS_AGP */ - -#endif diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h deleted file mode 100644 index 6463271..0000000 --- a/drivers/char/drm/drm_memory_debug.h +++ /dev/null @@ -1,309 +0,0 @@ -/** - * \file drm_memory_debug.h - * Memory management wrappers for DRM. - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -typedef struct drm_mem_stats { - const char *name; - int succeed_count; - int free_count; - int fail_count; - unsigned long bytes_allocated; - unsigned long bytes_freed; -} drm_mem_stats_t; - -static DEFINE_SPINLOCK(drm_mem_lock); -static unsigned long drm_ram_available = 0; /* In pages */ -static unsigned long drm_ram_used = 0; -static drm_mem_stats_t drm_mem_stats[] = -{ - [DRM_MEM_DMA] = {"dmabufs"}, - [DRM_MEM_SAREA] = {"sareas"}, - [DRM_MEM_DRIVER] = {"driver"}, - [DRM_MEM_MAGIC] = {"magic"}, - [DRM_MEM_IOCTLS] = {"ioctltab"}, - [DRM_MEM_MAPS] = {"maplist"}, - [DRM_MEM_VMAS] = {"vmalist"}, - [DRM_MEM_BUFS] = {"buflist"}, - [DRM_MEM_SEGS] = {"seglist"}, - [DRM_MEM_PAGES] = {"pagelist"}, - [DRM_MEM_FILES] = {"files"}, - [DRM_MEM_QUEUES] = {"queues"}, - [DRM_MEM_CMDS] = {"commands"}, - [DRM_MEM_MAPPINGS] = {"mappings"}, - [DRM_MEM_BUFLISTS] = {"buflists"}, - [DRM_MEM_AGPLISTS] = {"agplist"}, - [DRM_MEM_SGLISTS] = {"sglist"}, - [DRM_MEM_TOTALAGP] = {"totalagp"}, - [DRM_MEM_BOUNDAGP] = {"boundagp"}, - [DRM_MEM_CTXBITMAP] = {"ctxbitmap"}, - [DRM_MEM_CTXLIST] = {"ctxlist"}, - [DRM_MEM_STUB] = {"stub"}, - {NULL, 0,} /* Last entry must be null */ -}; - -void drm_mem_init (void) { - drm_mem_stats_t *mem; - struct sysinfo si; - - for (mem = drm_mem_stats; mem->name; ++mem) { - mem->succeed_count = 0; - mem->free_count = 0; - mem->fail_count = 0; - mem->bytes_allocated = 0; - mem->bytes_freed = 0; - } - - si_meminfo(&si); - drm_ram_available = si.totalram; - drm_ram_used = 0; -} - -/* drm_mem_info is called whenever a process reads /dev/drm/mem. */ - -static int drm__mem_info (char *buf, char **start, off_t offset, - int request, int *eof, void *data) { - drm_mem_stats_t *pt; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *eof = 0; - *start = &buf[offset]; - - DRM_PROC_PRINT(" total counts " - " | outstanding \n"); - DRM_PROC_PRINT("type alloc freed fail bytes freed" - " | allocs bytes\n\n"); - DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", - "system", 0, 0, 0, - drm_ram_available << (PAGE_SHIFT - 10)); - DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", - "locked", 0, 0, 0, drm_ram_used >> 10); - DRM_PROC_PRINT("\n"); - for (pt = drm_mem_stats; pt->name; pt++) { - DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", - pt->name, - pt->succeed_count, - pt->free_count, - pt->fail_count, - pt->bytes_allocated, - pt->bytes_freed, - pt->succeed_count - pt->free_count, - (long)pt->bytes_allocated - - (long)pt->bytes_freed); - } - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -int drm_mem_info (char *buf, char **start, off_t offset, - int len, int *eof, void *data) { - int ret; - - spin_lock(&drm_mem_lock); - ret = drm__mem_info (buf, start, offset, len, eof, data); - spin_unlock(&drm_mem_lock); - return ret; -} - -void *drm_alloc (size_t size, int area) { - void *pt; - - if (!size) { - DRM_MEM_ERROR(area, "Allocating 0 bytes\n"); - return NULL; - } - - if (!(pt = kmalloc(size, GFP_KERNEL))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].fail_count; - spin_unlock(&drm_mem_lock); - return NULL; - } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].succeed_count; - drm_mem_stats[area].bytes_allocated += size; - spin_unlock(&drm_mem_lock); - return pt; -} - -void *drm_calloc (size_t nmemb, size_t size, int area) { - void *addr; - - addr = drm_alloc (nmemb * size, area); - if (addr != NULL) - memset((void *)addr, 0, size * nmemb); - - return addr; -} - -void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) { - void *pt; - - if (!(pt = drm_alloc (size, area))) - return NULL; - if (oldpt && oldsize) { - memcpy(pt, oldpt, oldsize); - drm_free (oldpt, oldsize, area); - } - return pt; -} - -void drm_free (void *pt, size_t size, int area) { - int alloc_count; - int free_count; - - if (!pt) - DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); - else - kfree(pt); - spin_lock(&drm_mem_lock); - drm_mem_stats[area].bytes_freed += size; - free_count = ++drm_mem_stats[area].free_count; - alloc_count = drm_mem_stats[area].succeed_count; - spin_unlock(&drm_mem_lock); - if (free_count > alloc_count) { - DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } -} - -#if __OS_HAS_AGP - -DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { - DRM_AGP_MEM *handle; - - if (!pages) { - DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n"); - return NULL; - } - - if ((handle = drm_agp_allocate_memory (pages, type))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; - drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated - += pages << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - return handle; - } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; - spin_unlock(&drm_mem_lock); - return NULL; -} - -int drm_free_agp (DRM_AGP_MEM * handle, int pages) { - int alloc_count; - int free_count; - int retval = -EINVAL; - - if (!handle) { - DRM_MEM_ERROR(DRM_MEM_TOTALAGP, - "Attempt to free NULL AGP handle\n"); - return retval; - } - - if (drm_agp_free_memory (handle)) { - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; - alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; - drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed - += pages << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - if (free_count > alloc_count) { - DRM_MEM_ERROR(DRM_MEM_TOTALAGP, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } - return 0; - } - return retval; -} - -int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) { - int retcode = -EINVAL; - - if (!handle) { - DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, - "Attempt to bind NULL AGP handle\n"); - return retcode; - } - - if (!(retcode = drm_agp_bind_memory (handle, start))) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated - += handle->page_count << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - return retcode; - } - spin_lock(&drm_mem_lock); - ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; - spin_unlock(&drm_mem_lock); - return retcode; -} - -int drm_unbind_agp (DRM_AGP_MEM * handle) { - int alloc_count; - int free_count; - int retcode = -EINVAL; - - if (!handle) { - DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, - "Attempt to unbind NULL AGP handle\n"); - return retcode; - } - - if ((retcode = drm_agp_unbind_memory (handle))) - return retcode; - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; - alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; - drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed - += handle->page_count << PAGE_SHIFT; - spin_unlock(&drm_mem_lock); - if (free_count > alloc_count) { - DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } - return retcode; -} -#endif diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c deleted file mode 100644 index dcff9e9..0000000 --- a/drivers/char/drm/drm_mm.c +++ /dev/null @@ -1,295 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Generic simple memory manager implementation. Intended to be used as a base - * class implementation for more advanced memory managers. - * - * Note that the algorithm used is quite simple and there might be substantial - * performance gains if a smarter free list is implemented. Currently it is just an - * unordered stack of free regions. This could easily be improved if an RB-tree - * is used instead. At least if we expect heavy fragmentation. - * - * Aligned allocations can also see improvement. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include - -unsigned long drm_mm_tail_space(struct drm_mm *mm) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) - return 0; - - return entry->size; -} - -int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) - return -ENOMEM; - - if (entry->size <= size) - return -ENOMEM; - - entry->size -= size; - return 0; -} - - -static int drm_mm_create_tail_node(struct drm_mm *mm, - unsigned long start, - unsigned long size) -{ - struct drm_mm_node *child; - - child = (struct drm_mm_node *) - drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return -ENOMEM; - - child->free = 1; - child->size = size; - child->start = start; - child->mm = mm; - - list_add_tail(&child->ml_entry, &mm->ml_entry); - list_add_tail(&child->fl_entry, &mm->fl_entry); - - return 0; -} - - -int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) { - return drm_mm_create_tail_node(mm, entry->start + entry->size, size); - } - entry->size += size; - return 0; -} - -static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, - unsigned long size) -{ - struct drm_mm_node *child; - - child = (struct drm_mm_node *) - drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return NULL; - - INIT_LIST_HEAD(&child->fl_entry); - - child->free = 0; - child->size = size; - child->start = parent->start; - child->mm = parent->mm; - - list_add_tail(&child->ml_entry, &parent->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); - - parent->size -= size; - parent->start += size; - return child; -} - - - -struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent, - unsigned long size, unsigned alignment) -{ - - struct drm_mm_node *align_splitoff = NULL; - struct drm_mm_node *child; - unsigned tmp = 0; - - if (alignment) - tmp = parent->start % alignment; - - if (tmp) { - align_splitoff = drm_mm_split_at_start(parent, alignment - tmp); - if (!align_splitoff) - return NULL; - } - - if (parent->size == size) { - list_del_init(&parent->fl_entry); - parent->free = 0; - return parent; - } else { - child = drm_mm_split_at_start(parent, size); - } - - if (align_splitoff) - drm_mm_put_block(align_splitoff); - - return child; -} - -/* - * Put a block. Merge with the previous and / or next block if they are free. - * Otherwise add to the free stack. - */ - -void drm_mm_put_block(struct drm_mm_node * cur) -{ - - struct drm_mm *mm = cur->mm; - struct list_head *cur_head = &cur->ml_entry; - struct list_head *root_head = &mm->ml_entry; - struct drm_mm_node *prev_node = NULL; - struct drm_mm_node *next_node; - - int merged = 0; - - if (cur_head->prev != root_head) { - prev_node = list_entry(cur_head->prev, struct drm_mm_node, ml_entry); - if (prev_node->free) { - prev_node->size += cur->size; - merged = 1; - } - } - if (cur_head->next != root_head) { - next_node = list_entry(cur_head->next, struct drm_mm_node, ml_entry); - if (next_node->free) { - if (merged) { - prev_node->size += next_node->size; - list_del(&next_node->ml_entry); - list_del(&next_node->fl_entry); - drm_free(next_node, sizeof(*next_node), - DRM_MEM_MM); - } else { - next_node->size += cur->size; - next_node->start = cur->start; - merged = 1; - } - } - } - if (!merged) { - cur->free = 1; - list_add(&cur->fl_entry, &mm->fl_entry); - } else { - list_del(&cur->ml_entry); - drm_free(cur, sizeof(*cur), DRM_MEM_MM); - } -} - -struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, - unsigned long size, - unsigned alignment, int best_match) -{ - struct list_head *list; - const struct list_head *free_stack = &mm->fl_entry; - struct drm_mm_node *entry; - struct drm_mm_node *best; - unsigned long best_size; - unsigned wasted; - - best = NULL; - best_size = ~0UL; - - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); - wasted = 0; - - if (entry->size < size) - continue; - - if (alignment) { - register unsigned tmp = entry->start % alignment; - if (tmp) - wasted += alignment - tmp; - } - - - if (entry->size >= size + wasted) { - if (!best_match) - return entry; - if (size < best_size) { - best = entry; - best_size = entry->size; - } - } - } - - return best; -} - -int drm_mm_clean(struct drm_mm * mm) -{ - struct list_head *head = &mm->ml_entry; - - return (head->next->next == head); -} - -int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) -{ - INIT_LIST_HEAD(&mm->ml_entry); - INIT_LIST_HEAD(&mm->fl_entry); - - return drm_mm_create_tail_node(mm, start, size); -} - - -void drm_mm_takedown(struct drm_mm * mm) -{ - struct list_head *bnode = mm->fl_entry.next; - struct drm_mm_node *entry; - - entry = list_entry(bnode, struct drm_mm_node, fl_entry); - - if (entry->ml_entry.next != &mm->ml_entry || - entry->fl_entry.next != &mm->fl_entry) { - DRM_ERROR("Memory manager not clean. Delaying takedown\n"); - return; - } - - list_del(&entry->fl_entry); - list_del(&entry->ml_entry); - - drm_free(entry, sizeof(*entry), DRM_MEM_MM); -} diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h deleted file mode 100644 index 8dbd257..0000000 --- a/drivers/char/drm/drm_os_linux.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * \file drm_os_linux.h - * OS abstraction macros. - */ - -#include /* For task queue support */ -#include - -/** Current process ID */ -#define DRM_CURRENTPID task_pid_nr(current) -#define DRM_SUSER(p) capable(CAP_SYS_ADMIN) -#define DRM_UDELAY(d) udelay(d) -/** Read a byte from a MMIO region */ -#define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset)) -/** Read a word from a MMIO region */ -#define DRM_READ16(map, offset) readw(((void __iomem *)(map)->handle) + (offset)) -/** Read a dword from a MMIO region */ -#define DRM_READ32(map, offset) readl(((void __iomem *)(map)->handle) + (offset)) -/** Write a byte into a MMIO region */ -#define DRM_WRITE8(map, offset, val) writeb(val, ((void __iomem *)(map)->handle) + (offset)) -/** Write a word into a MMIO region */ -#define DRM_WRITE16(map, offset, val) writew(val, ((void __iomem *)(map)->handle) + (offset)) -/** Write a dword into a MMIO region */ -#define DRM_WRITE32(map, offset, val) writel(val, ((void __iomem *)(map)->handle) + (offset)) -/** Read memory barrier */ -#define DRM_READMEMORYBARRIER() rmb() -/** Write memory barrier */ -#define DRM_WRITEMEMORYBARRIER() wmb() -/** Read/write memory barrier */ -#define DRM_MEMORYBARRIER() mb() - -/** IRQ handler arguments and return type and values */ -#define DRM_IRQ_ARGS int irq, void *arg - -/** AGP types */ -#if __OS_HAS_AGP -#define DRM_AGP_MEM struct agp_memory -#define DRM_AGP_KERN struct agp_kern_info -#else -/* define some dummy types for non AGP supporting kernels */ -struct no_agp_kern { - unsigned long aper_base; - unsigned long aper_size; -}; -#define DRM_AGP_MEM int -#define DRM_AGP_KERN struct no_agp_kern -#endif - -#if !(__OS_HAS_MTRR) -static __inline__ int mtrr_add(unsigned long base, unsigned long size, - unsigned int type, char increment) -{ - return -ENODEV; -} - -static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size) -{ - return -ENODEV; -} - -#define MTRR_TYPE_WRCOMB 1 - -#endif - -/** Other copying of data to kernel space */ -#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ - copy_from_user(arg1, arg2, arg3) -/** Other copying of data from kernel space */ -#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ - copy_to_user(arg1, arg2, arg3) -/* Macros for copyfrom user, but checking readability only once */ -#define DRM_VERIFYAREA_READ( uaddr, size ) \ - (access_ok( VERIFY_READ, uaddr, size ) ? 0 : -EFAULT) -#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ - __copy_from_user(arg1, arg2, arg3) -#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \ - __copy_to_user(arg1, arg2, arg3) -#define DRM_GET_USER_UNCHECKED(val, uaddr) \ - __get_user(val, uaddr) - -#define DRM_HZ HZ - -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -do { \ - DECLARE_WAITQUEUE(entry, current); \ - unsigned long end = jiffies + (timeout); \ - add_wait_queue(&(queue), &entry); \ - \ - for (;;) { \ - __set_current_state(TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (time_after_eq(jiffies, end)) { \ - ret = -EBUSY; \ - break; \ - } \ - schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \ - if (signal_pending(current)) { \ - ret = -EINTR; \ - break; \ - } \ - } \ - __set_current_state(TASK_RUNNING); \ - remove_wait_queue(&(queue), &entry); \ -} while (0) - -#define DRM_WAKEUP( queue ) wake_up_interruptible( queue ) -#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c deleted file mode 100644 index b55d5bc..0000000 --- a/drivers/char/drm/drm_pci.c +++ /dev/null @@ -1,183 +0,0 @@ -/* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */ -/** - * \file drm_pci.c - * \brief Functions and ioctls to manage PCI memory - * - * \warning These interfaces aren't stable yet. - * - * \todo Implement the remaining ioctl's for the PCI pools. - * \todo The wrappers here are so thin that they would be better off inlined.. - * - * \author José Fonseca - * \author Leif Delgass - */ - -/* - * Copyright 2003 José Fonseca. - * Copyright 2003 Leif Delgass. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "drmP.h" - -/**********************************************************************/ -/** \name PCI memory */ -/*@{*/ - -/** - * \brief Allocate a PCI consistent memory block, for DMA. - */ -drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align, - dma_addr_t maxaddr) -{ - drm_dma_handle_t *dmah; -#if 1 - unsigned long addr; - size_t sz; -#endif -#ifdef DRM_DEBUG_MEMORY - int area = DRM_MEM_DMA; - - spin_lock(&drm_mem_lock); - if ((drm_ram_used >> PAGE_SHIFT) - > (DRM_RAM_PERCENT * drm_ram_available) / 100) { - spin_unlock(&drm_mem_lock); - return 0; - } - spin_unlock(&drm_mem_lock); -#endif - - /* pci_alloc_consistent only guarantees alignment to the smallest - * PAGE_SIZE order which is greater than or equal to the requested size. - * Return NULL here for now to make sure nobody tries for larger alignment - */ - if (align > size) - return NULL; - - if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) { - DRM_ERROR("Setting pci dma mask failed\n"); - return NULL; - } - - dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); - if (!dmah) - return NULL; - - dmah->size = size; - dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); - -#ifdef DRM_DEBUG_MEMORY - if (dmah->vaddr == NULL) { - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].fail_count; - spin_unlock(&drm_mem_lock); - kfree(dmah); - return NULL; - } - - spin_lock(&drm_mem_lock); - ++drm_mem_stats[area].succeed_count; - drm_mem_stats[area].bytes_allocated += size; - drm_ram_used += size; - spin_unlock(&drm_mem_lock); -#else - if (dmah->vaddr == NULL) { - kfree(dmah); - return NULL; - } -#endif - - memset(dmah->vaddr, 0, size); - - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Reserve */ - for (addr = (unsigned long)dmah->vaddr, sz = size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - SetPageReserved(virt_to_page(addr)); - } - - return dmah; -} - -EXPORT_SYMBOL(drm_pci_alloc); - -/** - * \brief Free a PCI consistent memory block without freeing its descriptor. - * - * This function is for internal use in the Linux-specific DRM core code. - */ -void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) -{ -#if 1 - unsigned long addr; - size_t sz; -#endif -#ifdef DRM_DEBUG_MEMORY - int area = DRM_MEM_DMA; - int alloc_count; - int free_count; -#endif - - if (!dmah->vaddr) { -#ifdef DRM_DEBUG_MEMORY - DRM_MEM_ERROR(area, "Attempt to free address 0\n"); -#endif - } else { - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Unreserve */ - for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - } - dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, - dmah->busaddr); - } - -#ifdef DRM_DEBUG_MEMORY - spin_lock(&drm_mem_lock); - free_count = ++drm_mem_stats[area].free_count; - alloc_count = drm_mem_stats[area].succeed_count; - drm_mem_stats[area].bytes_freed += size; - drm_ram_used -= size; - spin_unlock(&drm_mem_lock); - if (free_count > alloc_count) { - DRM_MEM_ERROR(area, - "Excess frees: %d frees, %d allocs\n", - free_count, alloc_count); - } -#endif - -} - -/** - * \brief Free a PCI consistent memory block - */ -void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) -{ - __drm_pci_free(dev, dmah); - kfree(dmah); -} - -EXPORT_SYMBOL(drm_pci_free); - -/*@}*/ diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h deleted file mode 100644 index 135bd19..0000000 --- a/drivers/char/drm/drm_pciids.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - This file is auto-generated from the drm_pciids.txt in the DRM CVS - Please contact dri-devel@lists.sf.net to add new cards to this list -*/ -#define radeon_PCI_IDS \ - {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \ - {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ - {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x414A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x414B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ - {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ - {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ - {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ - {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ - {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ - {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ - {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x710A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x710B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x710C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x710E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x710F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7140, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7141, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7142, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7143, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x714A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x714B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x714C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x714D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x714E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x714F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x715E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x715F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7183, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7186, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7187, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7188, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x718A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x718B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x718C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x718D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x718F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7193, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7196, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x719B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x719F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71CE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71D2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71D4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71D5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71D6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x71DE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7244, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7245, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7247, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7248, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x724A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x724B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x724C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x724D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x724E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7280, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7283, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7284, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x728B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x728C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7290, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7291, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7293, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ - {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ - {0, 0, 0} - -#define r128_PCI_IDS \ - {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4d46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5041, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5044, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5045, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5046, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5047, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5048, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5049, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x504A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x504B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x504C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x504D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x504E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x504F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5245, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5247, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x524b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x524c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x534d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - -#define mga_PCI_IDS \ - {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \ - {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \ - {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \ - {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \ - {0, 0, 0} - -#define mach64_PCI_IDS \ - {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x474c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x474f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x474d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x474e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - -#define sisdrv_PCI_IDS \ - {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ - {0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ - {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ - {0, 0, 0} - -#define tdfx_PCI_IDS \ - {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x121a, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x121a, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - -#define viadrv_PCI_IDS \ - {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ - {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ - {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ - {0, 0, 0} - -#define i810_PCI_IDS \ - {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - -#define i830_PCI_IDS \ - {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - -#define gamma_PCI_IDS \ - {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} - -#define savage_PCI_IDS \ - {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ - {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ - {0x5333, 0x8a22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE4}, \ - {0x5333, 0x8a23, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE4}, \ - {0x5333, 0x8c10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \ - {0x5333, 0x8c11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \ - {0x5333, 0x8c12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \ - {0x5333, 0x8c13, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \ - {0x5333, 0x8c22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c24, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c2a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c2b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c2c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8c2f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \ - {0x5333, 0x8a25, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGE}, \ - {0x5333, 0x8a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGE}, \ - {0x5333, 0x8d01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \ - {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \ - {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \ - {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \ - {0, 0, 0} - -#define ffb_PCI_IDS \ - {0, 0, 0} - -#define i915_PCI_IDS \ - {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x258a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x27ae, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x29b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x29c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x29d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0, 0, 0} diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c deleted file mode 100644 index 93b1e04..0000000 --- a/drivers/char/drm/drm_proc.c +++ /dev/null @@ -1,557 +0,0 @@ -/** - * \file drm_proc.c - * /proc support for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - * - * \par Acknowledgements: - * Matthew J Sottek sent in a patch to fix - * the problem with the proc files not outputting all their information. - */ - -/* - * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -static int drm_name_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_vm_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_clients_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_queues_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -static int drm_bufs_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -#if DRM_DEBUG_CODE -static int drm_vma_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data); -#endif - -/** - * Proc file list. - */ -static struct drm_proc_list { - const char *name; /**< file name */ - int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ -} drm_proc_list[] = { - {"name", drm_name_info}, - {"mem", drm_mem_info}, - {"vm", drm_vm_info}, - {"clients", drm_clients_info}, - {"queues", drm_queues_info}, - {"bufs", drm_bufs_info}, -#if DRM_DEBUG_CODE - {"vma", drm_vma_info}, -#endif -}; - -#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) - -/** - * Initialize the DRI proc filesystem for a device. - * - * \param dev DRM device. - * \param minor device minor number. - * \param root DRI proc dir entry. - * \param dev_root resulting DRI device proc dir entry. - * \return root entry pointer on success, or NULL on failure. - * - * Create the DRI proc root entry "/proc/dri", the device proc root entry - * "/proc/dri/%minor%/", and each entry in proc_list as - * "/proc/dri/%minor%/%name%". - */ -int drm_proc_init(struct drm_minor *minor, int minor_id, - struct proc_dir_entry *root) -{ - struct proc_dir_entry *ent; - int i, j; - char name[64]; - - sprintf(name, "%d", minor_id); - minor->dev_root = proc_mkdir(name, root); - if (!minor->dev_root) { - DRM_ERROR("Cannot create /proc/dri/%s\n", name); - return -1; - } - - for (i = 0; i < DRM_PROC_ENTRIES; i++) { - ent = create_proc_entry(drm_proc_list[i].name, - S_IFREG | S_IRUGO, minor->dev_root); - if (!ent) { - DRM_ERROR("Cannot create /proc/dri/%s/%s\n", - name, drm_proc_list[i].name); - for (j = 0; j < i; j++) - remove_proc_entry(drm_proc_list[i].name, - minor->dev_root); - remove_proc_entry(name, root); - minor->dev_root = NULL; - return -1; - } - ent->read_proc = drm_proc_list[i].f; - ent->data = minor; - } - - return 0; -} - -/** - * Cleanup the proc filesystem resources. - * - * \param minor device minor number. - * \param root DRI proc dir entry. - * \param dev_root DRI device proc dir entry. - * \return always zero. - * - * Remove all proc entries created by proc_init(). - */ -int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) -{ - int i; - char name[64]; - - if (!root || !minor->dev_root) - return 0; - - for (i = 0; i < DRM_PROC_ENTRIES; i++) - remove_proc_entry(drm_proc_list[i].name, minor->dev_root); - sprintf(name, "%d", minor->index); - remove_proc_entry(name, root); - - return 0; -} - -/** - * Called when "/proc/dri/.../name" is read. - * - * \param buf output buffer. - * \param start start of output data. - * \param offset requested start offset. - * \param request requested number of bytes. - * \param eof whether there is no more data to return. - * \param data private data. - * \return number of written bytes. - * - * Prints the device name together with the bus id if available. - */ -static int drm_name_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - if (dev->unique) { - DRM_PROC_PRINT("%s %s %s\n", - dev->driver->pci_driver.name, - pci_name(dev->pdev), dev->unique); - } else { - DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, - pci_name(dev->pdev)); - } - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -/** - * Called when "/proc/dri/.../vm" is read. - * - * \param buf output buffer. - * \param start start of output data. - * \param offset requested start offset. - * \param request requested number of bytes. - * \param eof whether there is no more data to return. - * \param data private data. - * \return number of written bytes. - * - * Prints information about all mappings in drm_device::maplist. - */ -static int drm__vm_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - struct drm_map *map; - struct drm_map_list *r_list; - - /* Hardcoded from _DRM_FRAME_BUFFER, - _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and - _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; - const char *type; - int i; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT("slot offset size type flags " - "address mtrr\n\n"); - i = 0; - list_for_each_entry(r_list, &dev->maplist, head) { - map = r_list->map; - if (!map) - continue; - if (map->type < 0 || map->type > 5) - type = "??"; - else - type = types[map->type]; - DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", - i, - map->offset, - map->size, type, map->flags, - (unsigned long) r_list->user_token); - if (map->mtrr < 0) { - DRM_PROC_PRINT("none\n"); - } else { - DRM_PROC_PRINT("%4d\n", map->mtrr); - } - i++; - } - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -/** - * Simply calls _vm_info() while holding the drm_device::struct_mutex lock. - */ -static int drm_vm_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm__vm_info(buf, start, offset, request, eof, data); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Called when "/proc/dri/.../queues" is read. - * - * \param buf output buffer. - * \param start start of output data. - * \param offset requested start offset. - * \param request requested number of bytes. - * \param eof whether there is no more data to return. - * \param data private data. - * \return number of written bytes. - */ -static int drm__queues_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - int i; - struct drm_queue *q; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT(" ctx/flags use fin" - " blk/rw/rwf wait flushed queued" - " locks\n\n"); - for (i = 0; i < dev->queue_count; i++) { - q = dev->queuelist[i]; - atomic_inc(&q->use_count); - DRM_PROC_PRINT_RET(atomic_dec(&q->use_count), - "%5d/0x%03x %5d %5d" - " %5d/%c%c/%c%c%c %5Zd\n", - i, - q->flags, - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count), - atomic_read(&q->block_read) ? 'r' : '-', - atomic_read(&q->block_write) ? 'w' : '-', - waitqueue_active(&q->read_queue) ? 'r' : '-', - waitqueue_active(&q-> - write_queue) ? 'w' : '-', - waitqueue_active(&q-> - flush_queue) ? 'f' : '-', - DRM_BUFCOUNT(&q->waitlist)); - atomic_dec(&q->use_count); - } - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -/** - * Simply calls _queues_info() while holding the drm_device::struct_mutex lock. - */ -static int drm_queues_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm__queues_info(buf, start, offset, request, eof, data); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Called when "/proc/dri/.../bufs" is read. - * - * \param buf output buffer. - * \param start start of output data. - * \param offset requested start offset. - * \param request requested number of bytes. - * \param eof whether there is no more data to return. - * \param data private data. - * \return number of written bytes. - */ -static int drm__bufs_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - struct drm_device_dma *dma = dev->dma; - int i; - - if (!dma || offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT(" o size count free segs pages kB\n\n"); - for (i = 0; i <= DRM_MAX_ORDER; i++) { - if (dma->bufs[i].buf_count) - DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n", - i, - dma->bufs[i].buf_size, - dma->bufs[i].buf_count, - atomic_read(&dma->bufs[i] - .freelist.count), - dma->bufs[i].seg_count, - dma->bufs[i].seg_count - * (1 << dma->bufs[i].page_order), - (dma->bufs[i].seg_count - * (1 << dma->bufs[i].page_order)) - * PAGE_SIZE / 1024); - } - DRM_PROC_PRINT("\n"); - for (i = 0; i < dma->buf_count; i++) { - if (i && !(i % 32)) - DRM_PROC_PRINT("\n"); - DRM_PROC_PRINT(" %d", dma->buflist[i]->list); - } - DRM_PROC_PRINT("\n"); - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -/** - * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock. - */ -static int drm_bufs_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm__bufs_info(buf, start, offset, request, eof, data); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Called when "/proc/dri/.../clients" is read. - * - * \param buf output buffer. - * \param start start of output data. - * \param offset requested start offset. - * \param request requested number of bytes. - * \param eof whether there is no more data to return. - * \param data private data. - * \return number of written bytes. - */ -static int drm__clients_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - struct drm_file *priv; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n"); - list_for_each_entry(priv, &dev->filelist, lhead) { - DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", - priv->authenticated ? 'y' : 'n', - priv->minor->index, - priv->pid, - priv->uid, priv->magic, priv->ioctl_count); - } - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -/** - * Simply calls _clients_info() while holding the drm_device::struct_mutex lock. - */ -static int drm_clients_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm__clients_info(buf, start, offset, request, eof, data); - mutex_unlock(&dev->struct_mutex); - return ret; -} - -#if DRM_DEBUG_CODE - -static int drm__vma_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int len = 0; - struct drm_vma_entry *pt; - struct vm_area_struct *vma; -#if defined(__i386__) - unsigned int pgprot; -#endif - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - - DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n", - atomic_read(&dev->vma_count), - high_memory, virt_to_phys(high_memory)); - list_for_each_entry(pt, &dev->vmalist, head) { - if (!(vma = pt->vma)) - continue; - DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", - pt->pid, - vma->vm_start, - vma->vm_end, - vma->vm_flags & VM_READ ? 'r' : '-', - vma->vm_flags & VM_WRITE ? 'w' : '-', - vma->vm_flags & VM_EXEC ? 'x' : '-', - vma->vm_flags & VM_MAYSHARE ? 's' : 'p', - vma->vm_flags & VM_LOCKED ? 'l' : '-', - vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_pgoff); - -#if defined(__i386__) - pgprot = pgprot_val(vma->vm_page_prot); - DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c", - pgprot & _PAGE_PRESENT ? 'p' : '-', - pgprot & _PAGE_RW ? 'w' : 'r', - pgprot & _PAGE_USER ? 'u' : 's', - pgprot & _PAGE_PWT ? 't' : 'b', - pgprot & _PAGE_PCD ? 'u' : 'c', - pgprot & _PAGE_ACCESSED ? 'a' : '-', - pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_PSE ? 'm' : 'k', - pgprot & _PAGE_GLOBAL ? 'g' : 'l'); -#endif - DRM_PROC_PRINT("\n"); - } - - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int drm_vma_info(char *buf, char **start, off_t offset, int request, - int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm__vma_info(buf, start, offset, request, eof, data); - mutex_unlock(&dev->struct_mutex); - return ret; -} -#endif diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h deleted file mode 100644 index 4800373..0000000 --- a/drivers/char/drm/drm_sarea.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * \file drm_sarea.h - * \brief SAREA definitions - * - * \author Michel Dänzer - */ - -/* - * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _DRM_SAREA_H_ -#define _DRM_SAREA_H_ - -#include "drm.h" - -/* SAREA area needs to be at least a page */ -#if defined(__alpha__) -#define SAREA_MAX 0x2000 -#elif defined(__ia64__) -#define SAREA_MAX 0x10000 /* 64kB */ -#else -/* Intel 830M driver needs at least 8k SAREA */ -#define SAREA_MAX 0x2000 -#endif - -/** Maximum number of drawables in the SAREA */ -#define SAREA_MAX_DRAWABLES 256 - -#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000 - -/** SAREA drawable */ -struct drm_sarea_drawable { - unsigned int stamp; - unsigned int flags; -}; - -/** SAREA frame */ -struct drm_sarea_frame { - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - unsigned int fullscreen; -}; - -/** SAREA */ -struct drm_sarea { - /** first thing is always the DRM locking structure */ - struct drm_hw_lock lock; - /** \todo Use readers/writer lock for drm_sarea::drawable_lock */ - struct drm_hw_lock drawable_lock; - struct drm_sarea_drawable drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */ - struct drm_sarea_frame frame; /**< frame */ - drm_context_t dummy_context; -}; - -#ifndef __KERNEL__ -typedef struct drm_sarea_drawable drm_sarea_drawable_t; -typedef struct drm_sarea_frame drm_sarea_frame_t; -typedef struct drm_sarea drm_sarea_t; -#endif - -#endif /* _DRM_SAREA_H_ */ diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c deleted file mode 100644 index b2b0f3d..0000000 --- a/drivers/char/drm/drm_scatter.c +++ /dev/null @@ -1,227 +0,0 @@ -/** - * \file drm_scatter.c - * IOCTLs to manage scatter/gather memory - * - * \author Gareth Hughes - */ - -/* - * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -#define DEBUG_SCATTER 0 - -static inline void *drm_vmalloc_dma(unsigned long size) -{ -#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE) - return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE); -#else - return vmalloc_32(size); -#endif -} - -void drm_sg_cleanup(struct drm_sg_mem * entry) -{ - struct page *page; - int i; - - for (i = 0; i < entry->pages; i++) { - page = entry->pagelist[i]; - if (page) - ClearPageReserved(page); - } - - vfree(entry->virtual); - - drm_free(entry->busaddr, - entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); - drm_free(entry->pagelist, - entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES); - drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); -} - -#ifdef _LP64 -# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1))) -#else -# define ScatterHandle(x) (unsigned int)(x) -#endif - -int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) -{ - struct drm_sg_mem *entry; - unsigned long pages, i, j; - - DRM_DEBUG("\n"); - - if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; - - if (dev->sg) - return -EINVAL; - - entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS); - if (!entry) - return -ENOMEM; - - memset(entry, 0, sizeof(*entry)); - pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages); - - entry->pages = pages; - entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES); - if (!entry->pagelist) { - drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); - return -ENOMEM; - } - - memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); - - entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr), - DRM_MEM_PAGES); - if (!entry->busaddr) { - drm_free(entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES); - drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); - return -ENOMEM; - } - memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); - - entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); - if (!entry->virtual) { - drm_free(entry->busaddr, - entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); - drm_free(entry->pagelist, - entry->pages * sizeof(*entry->pagelist), - DRM_MEM_PAGES); - drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); - return -ENOMEM; - } - - /* This also forces the mapping of COW pages, so our page list - * will be valid. Please don't remove it... - */ - memset(entry->virtual, 0, pages << PAGE_SHIFT); - - entry->handle = ScatterHandle((unsigned long)entry->virtual); - - DRM_DEBUG("handle = %08lx\n", entry->handle); - DRM_DEBUG("virtual = %p\n", entry->virtual); - - for (i = (unsigned long)entry->virtual, j = 0; j < pages; - i += PAGE_SIZE, j++) { - entry->pagelist[j] = vmalloc_to_page((void *)i); - if (!entry->pagelist[j]) - goto failed; - SetPageReserved(entry->pagelist[j]); - } - - request->handle = entry->handle; - - dev->sg = entry; - -#if DEBUG_SCATTER - /* Verify that each page points to its virtual address, and vice - * versa. - */ - { - int error = 0; - - for (i = 0; i < pages; i++) { - unsigned long *tmp; - - tmp = page_address(entry->pagelist[i]); - for (j = 0; - j < PAGE_SIZE / sizeof(unsigned long); - j++, tmp++) { - *tmp = 0xcafebabe; - } - tmp = (unsigned long *)((u8 *) entry->virtual + - (PAGE_SIZE * i)); - for (j = 0; - j < PAGE_SIZE / sizeof(unsigned long); - j++, tmp++) { - if (*tmp != 0xcafebabe && error == 0) { - error = 1; - DRM_ERROR("Scatter allocation error, " - "pagelist does not match " - "virtual mapping\n"); - } - } - tmp = page_address(entry->pagelist[i]); - for (j = 0; - j < PAGE_SIZE / sizeof(unsigned long); - j++, tmp++) { - *tmp = 0; - } - } - if (error == 0) - DRM_ERROR("Scatter allocation matches pagelist\n"); - } -#endif - - return 0; - - failed: - drm_sg_cleanup(entry); - return -ENOMEM; -} -EXPORT_SYMBOL(drm_sg_alloc); - - -int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_scatter_gather *request = data; - - return drm_sg_alloc(dev, request); - -} - -int drm_sg_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_scatter_gather *request = data; - struct drm_sg_mem *entry; - - if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; - - entry = dev->sg; - dev->sg = NULL; - - if (!entry || entry->handle != request->handle) - return -EINVAL; - - DRM_DEBUG("virtual = %p\n", entry->virtual); - - drm_sg_cleanup(entry); - - return 0; -} diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c deleted file mode 100644 index 926f146..0000000 --- a/drivers/char/drm/drm_sman.c +++ /dev/null @@ -1,353 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck., ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Simple memory manager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#include "drm_sman.h" - -struct drm_owner_item { - struct drm_hash_item owner_hash; - struct list_head sman_list; - struct list_head mem_blocks; -}; - -void drm_sman_takedown(struct drm_sman * sman) -{ - drm_ht_remove(&sman->user_hash_tab); - drm_ht_remove(&sman->owner_hash_tab); - if (sman->mm) - drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm), - DRM_MEM_MM); -} - -EXPORT_SYMBOL(drm_sman_takedown); - -int -drm_sman_init(struct drm_sman * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order) -{ - int ret = 0; - - sman->mm = (struct drm_sman_mm *) drm_calloc(num_managers, sizeof(*sman->mm), - DRM_MEM_MM); - if (!sman->mm) { - ret = -ENOMEM; - goto out; - } - sman->num_managers = num_managers; - INIT_LIST_HEAD(&sman->owner_items); - ret = drm_ht_create(&sman->owner_hash_tab, owner_order); - if (ret) - goto out1; - ret = drm_ht_create(&sman->user_hash_tab, user_order); - if (!ret) - goto out; - - drm_ht_remove(&sman->owner_hash_tab); -out1: - drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM); -out: - return ret; -} - -EXPORT_SYMBOL(drm_sman_init); - -static void *drm_sman_mm_allocate(void *private, unsigned long size, - unsigned alignment) -{ - struct drm_mm *mm = (struct drm_mm *) private; - struct drm_mm_node *tmp; - - tmp = drm_mm_search_free(mm, size, alignment, 1); - if (!tmp) { - return NULL; - } - tmp = drm_mm_get_block(tmp, size, alignment); - return tmp; -} - -static void drm_sman_mm_free(void *private, void *ref) -{ - struct drm_mm_node *node = (struct drm_mm_node *) ref; - - drm_mm_put_block(node); -} - -static void drm_sman_mm_destroy(void *private) -{ - struct drm_mm *mm = (struct drm_mm *) private; - drm_mm_takedown(mm); - drm_free(mm, sizeof(*mm), DRM_MEM_MM); -} - -static unsigned long drm_sman_mm_offset(void *private, void *ref) -{ - struct drm_mm_node *node = (struct drm_mm_node *) ref; - return node->start; -} - -int -drm_sman_set_range(struct drm_sman * sman, unsigned int manager, - unsigned long start, unsigned long size) -{ - struct drm_sman_mm *sman_mm; - struct drm_mm *mm; - int ret; - - BUG_ON(manager >= sman->num_managers); - - sman_mm = &sman->mm[manager]; - mm = drm_calloc(1, sizeof(*mm), DRM_MEM_MM); - if (!mm) { - return -ENOMEM; - } - sman_mm->private = mm; - ret = drm_mm_init(mm, start, size); - - if (ret) { - drm_free(mm, sizeof(*mm), DRM_MEM_MM); - return ret; - } - - sman_mm->allocate = drm_sman_mm_allocate; - sman_mm->free = drm_sman_mm_free; - sman_mm->destroy = drm_sman_mm_destroy; - sman_mm->offset = drm_sman_mm_offset; - - return 0; -} - -EXPORT_SYMBOL(drm_sman_set_range); - -int -drm_sman_set_manager(struct drm_sman * sman, unsigned int manager, - struct drm_sman_mm * allocator) -{ - BUG_ON(manager >= sman->num_managers); - sman->mm[manager] = *allocator; - - return 0; -} -EXPORT_SYMBOL(drm_sman_set_manager); - -static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman, - unsigned long owner) -{ - int ret; - struct drm_hash_item *owner_hash_item; - struct drm_owner_item *owner_item; - - ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item); - if (!ret) { - return drm_hash_entry(owner_hash_item, struct drm_owner_item, - owner_hash); - } - - owner_item = drm_calloc(1, sizeof(*owner_item), DRM_MEM_MM); - if (!owner_item) - goto out; - - INIT_LIST_HEAD(&owner_item->mem_blocks); - owner_item->owner_hash.key = owner; - if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash)) - goto out1; - - list_add_tail(&owner_item->sman_list, &sman->owner_items); - return owner_item; - -out1: - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); -out: - return NULL; -} - -struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int manager, - unsigned long size, unsigned alignment, - unsigned long owner) -{ - void *tmp; - struct drm_sman_mm *sman_mm; - struct drm_owner_item *owner_item; - struct drm_memblock_item *memblock; - - BUG_ON(manager >= sman->num_managers); - - sman_mm = &sman->mm[manager]; - tmp = sman_mm->allocate(sman_mm->private, size, alignment); - - if (!tmp) { - return NULL; - } - - memblock = drm_calloc(1, sizeof(*memblock), DRM_MEM_MM); - - if (!memblock) - goto out; - - memblock->mm_info = tmp; - memblock->mm = sman_mm; - memblock->sman = sman; - - if (drm_ht_just_insert_please - (&sman->user_hash_tab, &memblock->user_hash, - (unsigned long)memblock, 32, 0, 0)) - goto out1; - - owner_item = drm_sman_get_owner_item(sman, owner); - if (!owner_item) - goto out2; - - list_add_tail(&memblock->owner_list, &owner_item->mem_blocks); - - return memblock; - -out2: - drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); -out1: - drm_free(memblock, sizeof(*memblock), DRM_MEM_MM); -out: - sman_mm->free(sman_mm->private, tmp); - - return NULL; -} - -EXPORT_SYMBOL(drm_sman_alloc); - -static void drm_sman_free(struct drm_memblock_item *item) -{ - struct drm_sman *sman = item->sman; - - list_del(&item->owner_list); - drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); - item->mm->free(item->mm->private, item->mm_info); - drm_free(item, sizeof(*item), DRM_MEM_MM); -} - -int drm_sman_free_key(struct drm_sman *sman, unsigned int key) -{ - struct drm_hash_item *hash_item; - struct drm_memblock_item *memblock_item; - - if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item)) - return -EINVAL; - - memblock_item = drm_hash_entry(hash_item, struct drm_memblock_item, - user_hash); - drm_sman_free(memblock_item); - return 0; -} - -EXPORT_SYMBOL(drm_sman_free_key); - -static void drm_sman_remove_owner(struct drm_sman *sman, - struct drm_owner_item *owner_item) -{ - list_del(&owner_item->sman_list); - drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); -} - -int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner) -{ - - struct drm_hash_item *hash_item; - struct drm_owner_item *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - return -1; - } - - owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash); - if (owner_item->mem_blocks.next == &owner_item->mem_blocks) { - drm_sman_remove_owner(sman, owner_item); - return -1; - } - - return 0; -} - -EXPORT_SYMBOL(drm_sman_owner_clean); - -static void drm_sman_do_owner_cleanup(struct drm_sman *sman, - struct drm_owner_item *owner_item) -{ - struct drm_memblock_item *entry, *next; - - list_for_each_entry_safe(entry, next, &owner_item->mem_blocks, - owner_list) { - drm_sman_free(entry); - } - drm_sman_remove_owner(sman, owner_item); -} - -void drm_sman_owner_cleanup(struct drm_sman *sman, unsigned long owner) -{ - - struct drm_hash_item *hash_item; - struct drm_owner_item *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - - return; - } - - owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash); - drm_sman_do_owner_cleanup(sman, owner_item); -} - -EXPORT_SYMBOL(drm_sman_owner_cleanup); - -void drm_sman_cleanup(struct drm_sman *sman) -{ - struct drm_owner_item *entry, *next; - unsigned int i; - struct drm_sman_mm *sman_mm; - - list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) { - drm_sman_do_owner_cleanup(sman, entry); - } - if (sman->mm) { - for (i = 0; i < sman->num_managers; ++i) { - sman_mm = &sman->mm[i]; - if (sman_mm->private) { - sman_mm->destroy(sman_mm->private); - sman_mm->private = NULL; - } - } - } -} - -EXPORT_SYMBOL(drm_sman_cleanup); diff --git a/drivers/char/drm/drm_sman.h b/drivers/char/drm/drm_sman.h deleted file mode 100644 index 08ecf83..0000000 --- a/drivers/char/drm/drm_sman.h +++ /dev/null @@ -1,176 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple memory MANager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_SMAN_H -#define DRM_SMAN_H - -#include "drmP.h" -#include "drm_hashtab.h" - -/* - * A class that is an abstration of a simple memory allocator. - * The sman implementation provides a default such allocator - * using the drm_mm.c implementation. But the user can replace it. - * See the SiS implementation, which may use the SiS FB kernel module - * for memory management. - */ - -struct drm_sman_mm { - /* private info. If allocated, needs to be destroyed by the destroy - function */ - void *private; - - /* Allocate a memory block with given size and alignment. - Return an opaque reference to the memory block */ - - void *(*allocate) (void *private, unsigned long size, - unsigned alignment); - - /* Free a memory block. "ref" is the opaque reference that we got from - the "alloc" function */ - - void (*free) (void *private, void *ref); - - /* Free all resources associated with this allocator */ - - void (*destroy) (void *private); - - /* Return a memory offset from the opaque reference returned from the - "alloc" function */ - - unsigned long (*offset) (void *private, void *ref); -}; - -struct drm_memblock_item { - struct list_head owner_list; - struct drm_hash_item user_hash; - void *mm_info; - struct drm_sman_mm *mm; - struct drm_sman *sman; -}; - -struct drm_sman { - struct drm_sman_mm *mm; - int num_managers; - struct drm_open_hash owner_hash_tab; - struct drm_open_hash user_hash_tab; - struct list_head owner_items; -}; - -/* - * Take down a memory manager. This function should only be called after a - * successful init and after a call to drm_sman_cleanup. - */ - -extern void drm_sman_takedown(struct drm_sman * sman); - -/* - * Allocate structures for a manager. - * num_managers are the number of memory pools to manage. (VRAM, AGP, ....) - * user_order is the log2 of the number of buckets in the user hash table. - * set this to approximately log2 of the max number of memory regions - * that will be allocated for _all_ pools together. - * owner_order is the log2 of the number of buckets in the owner hash table. - * set this to approximately log2 of - * the number of client file connections that will - * be using the manager. - * - */ - -extern int drm_sman_init(struct drm_sman * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order); - -/* - * Initialize a drm_mm.c allocator. Should be called only once for each - * manager unless a customized allogator is used. - */ - -extern int drm_sman_set_range(struct drm_sman * sman, unsigned int manager, - unsigned long start, unsigned long size); - -/* - * Initialize a customized allocator for one of the managers. - * (See the SiS module). The object pointed to by "allocator" is copied, - * so it can be destroyed after this call. - */ - -extern int drm_sman_set_manager(struct drm_sman * sman, unsigned int mananger, - struct drm_sman_mm * allocator); - -/* - * Allocate a memory block. Aligment is not implemented yet. - */ - -extern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman, - unsigned int manager, - unsigned long size, - unsigned alignment, - unsigned long owner); -/* - * Free a memory block identified by its user hash key. - */ - -extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key); - -/* - * returns 1 iff there are no stale memory blocks associated with this owner. - * Typically called to determine if we need to idle the hardware and call - * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all - * resources associated with owner. - */ - -extern int drm_sman_owner_clean(struct drm_sman * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with this owner. Note that this - * requires that the hardware is finished with all blocks, so the graphics engine - * should be idled before this call is made. This function also frees - * any resources associated with "owner" and should be called when owner - * is not going to be referenced anymore. - */ - -extern void drm_sman_owner_cleanup(struct drm_sman * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with the memory manager. - * See idling above. - */ - -extern void drm_sman_cleanup(struct drm_sman * sman); - -#endif diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c deleted file mode 100644 index c2f584f..0000000 --- a/drivers/char/drm/drm_stub.c +++ /dev/null @@ -1,331 +0,0 @@ -/** - * \file drm_stub.h - * Stub support - * - * \author Rickard E. (Rik) Faith - */ - -/* - * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org - * - * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "drmP.h" -#include "drm_core.h" - -unsigned int drm_debug = 0; /* 1 to enable debug output */ -EXPORT_SYMBOL(drm_debug); - -MODULE_AUTHOR(CORE_AUTHOR); -MODULE_DESCRIPTION(CORE_DESC); -MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(debug, "Enable debug output"); - -module_param_named(debug, drm_debug, int, 0600); - -struct idr drm_minors_idr; - -struct class *drm_class; -struct proc_dir_entry *drm_proc_root; - -static int drm_minor_get_id(struct drm_device *dev, int type) -{ - int new_id; - int ret; - int base = 0, limit = 63; - -again: - if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { - DRM_ERROR("Out of memory expanding drawable idr\n"); - return -ENOMEM; - } - mutex_lock(&dev->struct_mutex); - ret = idr_get_new_above(&drm_minors_idr, NULL, - base, &new_id); - mutex_unlock(&dev->struct_mutex); - if (ret == -EAGAIN) { - goto again; - } else if (ret) { - return ret; - } - - if (new_id >= limit) { - idr_remove(&drm_minors_idr, new_id); - return -EINVAL; - } - return new_id; -} - -static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, - const struct pci_device_id *ent, - struct drm_driver *driver) -{ - int retcode; - - INIT_LIST_HEAD(&dev->filelist); - INIT_LIST_HEAD(&dev->ctxlist); - INIT_LIST_HEAD(&dev->vmalist); - INIT_LIST_HEAD(&dev->maplist); - - spin_lock_init(&dev->count_lock); - spin_lock_init(&dev->drw_lock); - spin_lock_init(&dev->tasklet_lock); - spin_lock_init(&dev->lock.spinlock); - init_timer(&dev->timer); - mutex_init(&dev->struct_mutex); - mutex_init(&dev->ctxlist_mutex); - - idr_init(&dev->drw_idr); - - dev->pdev = pdev; - dev->pci_device = pdev->device; - dev->pci_vendor = pdev->vendor; - -#ifdef __alpha__ - dev->hose = pdev->sysdata; -#endif - dev->irq = pdev->irq; - - if (drm_ht_create(&dev->map_hash, 12)) { - return -ENOMEM; - } - - /* the DRM has 6 basic counters */ - dev->counters = 6; - dev->types[0] = _DRM_STAT_LOCK; - dev->types[1] = _DRM_STAT_OPENS; - dev->types[2] = _DRM_STAT_CLOSES; - dev->types[3] = _DRM_STAT_IOCTLS; - dev->types[4] = _DRM_STAT_LOCKS; - dev->types[5] = _DRM_STAT_UNLOCKS; - - dev->driver = driver; - - if (drm_core_has_AGP(dev)) { - if (drm_device_is_agp(dev)) - dev->agp = drm_agp_init(dev); - if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) - && (dev->agp == NULL)) { - DRM_ERROR("Cannot initialize the agpgart module.\n"); - retcode = -EINVAL; - goto error_out_unreg; - } - if (drm_core_has_MTRR(dev)) { - if (dev->agp) - dev->agp->agp_mtrr = - mtrr_add(dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * - 1024 * 1024, MTRR_TYPE_WRCOMB, 1); - } - } - - if (dev->driver->load) - if ((retcode = dev->driver->load(dev, ent->driver_data))) - goto error_out_unreg; - - retcode = drm_ctxbitmap_init(dev); - if (retcode) { - DRM_ERROR("Cannot allocate memory for context bitmap.\n"); - goto error_out_unreg; - } - - return 0; - - error_out_unreg: - drm_lastclose(dev); - return retcode; -} - - -/** - * Get a secondary minor number. - * - * \param dev device data structure - * \param sec-minor structure to hold the assigned minor - * \return negative number on failure. - * - * Search an empty entry and initialize it to the given parameters, and - * create the proc init entry via proc_init(). This routines assigns - * minor numbers to secondary heads of multi-headed cards - */ -static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) -{ - struct drm_minor *new_minor; - int ret; - int minor_id; - - DRM_DEBUG("\n"); - - minor_id = drm_minor_get_id(dev, type); - if (minor_id < 0) - return minor_id; - - new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); - if (!new_minor) { - ret = -ENOMEM; - goto err_idr; - } - - new_minor->type = type; - new_minor->device = MKDEV(DRM_MAJOR, minor_id); - new_minor->dev = dev; - new_minor->index = minor_id; - - idr_replace(&drm_minors_idr, new_minor, minor_id); - - if (type == DRM_MINOR_LEGACY) { - ret = drm_proc_init(new_minor, minor_id, drm_proc_root); - if (ret) { - DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); - goto err_mem; - } - } else - new_minor->dev_root = NULL; - - ret = drm_sysfs_device_add(new_minor); - if (ret) { - printk(KERN_ERR - "DRM: Error sysfs_device_add.\n"); - goto err_g2; - } - *minor = new_minor; - - DRM_DEBUG("new minor assigned %d\n", minor_id); - return 0; - - -err_g2: - if (new_minor->type == DRM_MINOR_LEGACY) - drm_proc_cleanup(new_minor, drm_proc_root); -err_mem: - kfree(new_minor); -err_idr: - idr_remove(&drm_minors_idr, minor_id); - *minor = NULL; - return ret; -} - -/** - * Register. - * - * \param pdev - PCI device structure - * \param ent entry from the PCI ID table with device type flags - * \return zero on success or a negative number on failure. - * - * Attempt to gets inter module "drm" information. If we are first - * then register the character device and inter module information. - * Try and register, if we fail to register, backout previous work. - */ -int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver) -{ - struct drm_device *dev; - int ret; - - DRM_DEBUG("\n"); - - dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB); - if (!dev) - return -ENOMEM; - - ret = pci_enable_device(pdev); - if (ret) - goto err_g1; - - pci_set_master(pdev); - if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g2; - } - if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) - goto err_g2; - - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - - return 0; - -err_g2: - pci_disable_device(pdev); -err_g1: - drm_free(dev, sizeof(*dev), DRM_MEM_STUB); - return ret; -} - -/** - * Put a device minor number. - * - * \param dev device data structure - * \return always zero - * - * Cleans up the proc resources. If it is the last minor then release the foreign - * "drm" data, otherwise unregisters the "drm" data, frees the dev list and - * unregisters the character device. - */ -int drm_put_dev(struct drm_device * dev) -{ - DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name); - - if (dev->unique) { - drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); - dev->unique = NULL; - dev->unique_len = 0; - } - if (dev->devname) { - drm_free(dev->devname, strlen(dev->devname) + 1, - DRM_MEM_DRIVER); - dev->devname = NULL; - } - drm_free(dev, sizeof(*dev), DRM_MEM_STUB); - return 0; -} - -/** - * Put a secondary minor number. - * - * \param sec_minor - structure to be released - * \return always zero - * - * Cleans up the proc resources. Not legal for this to be the - * last minor released. - * - */ -int drm_put_minor(struct drm_minor **minor_p) -{ - struct drm_minor *minor = *minor_p; - DRM_DEBUG("release secondary minor %d\n", minor->index); - - if (minor->type == DRM_MINOR_LEGACY) - drm_proc_cleanup(minor, drm_proc_root); - drm_sysfs_device_remove(minor); - - idr_remove(&drm_minors_idr, minor->index); - - kfree(minor); - *minor_p = NULL; - return 0; -} diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c deleted file mode 100644 index af211a0..0000000 --- a/drivers/char/drm/drm_sysfs.c +++ /dev/null @@ -1,208 +0,0 @@ - -/* - * drm_sysfs.c - Modifications to drm_sysfs_class.c to support - * extra sysfs attribute from DRM. Normal drm_sysfs_class - * does not allow adding attributes. - * - * Copyright (c) 2004 Jon Smirl - * Copyright (c) 2003-2004 Greg Kroah-Hartman - * Copyright (c) 2003-2004 IBM Corp. - * - * This file is released under the GPLv2 - * - */ - -#include -#include -#include - -#include "drm_core.h" -#include "drmP.h" - -#define to_drm_minor(d) container_of(d, struct drm_minor, kdev) - -/** - * drm_sysfs_suspend - DRM class suspend hook - * @dev: Linux device to suspend - * @state: power state to enter - * - * Just figures out what the actual struct drm_device associated with - * @dev is and calls its suspend hook, if present. - */ -static int drm_sysfs_suspend(struct device *dev, pm_message_t state) -{ - struct drm_minor *drm_minor = to_drm_minor(dev); - struct drm_device *drm_dev = drm_minor->dev; - - if (drm_dev->driver->suspend) - return drm_dev->driver->suspend(drm_dev, state); - - return 0; -} - -/** - * drm_sysfs_resume - DRM class resume hook - * @dev: Linux device to resume - * - * Just figures out what the actual struct drm_device associated with - * @dev is and calls its resume hook, if present. - */ -static int drm_sysfs_resume(struct device *dev) -{ - struct drm_minor *drm_minor = to_drm_minor(dev); - struct drm_device *drm_dev = drm_minor->dev; - - if (drm_dev->driver->resume) - return drm_dev->driver->resume(drm_dev); - - return 0; -} - -/* Display the version of drm_core. This doesn't work right in current design */ -static ssize_t version_show(struct class *dev, char *buf) -{ - return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR, - CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); -} - -static CLASS_ATTR(version, S_IRUGO, version_show, NULL); - -/** - * drm_sysfs_create - create a struct drm_sysfs_class structure - * @owner: pointer to the module that is to "own" this struct drm_sysfs_class - * @name: pointer to a string for the name of this class. - * - * This is used to create DRM class pointer that can then be used - * in calls to drm_sysfs_device_add(). - * - * Note, the pointer created here is to be destroyed when finished by making a - * call to drm_sysfs_destroy(). - */ -struct class *drm_sysfs_create(struct module *owner, char *name) -{ - struct class *class; - int err; - - class = class_create(owner, name); - if (IS_ERR(class)) { - err = PTR_ERR(class); - goto err_out; - } - - class->suspend = drm_sysfs_suspend; - class->resume = drm_sysfs_resume; - - err = class_create_file(class, &class_attr_version); - if (err) - goto err_out_class; - - return class; - -err_out_class: - class_destroy(class); -err_out: - return ERR_PTR(err); -} - -/** - * drm_sysfs_destroy - destroys DRM class - * - * Destroy the DRM device class. - */ -void drm_sysfs_destroy(void) -{ - if ((drm_class == NULL) || (IS_ERR(drm_class))) - return; - class_remove_file(drm_class, &class_attr_version); - class_destroy(drm_class); -} - -static ssize_t show_dri(struct device *device, struct device_attribute *attr, - char *buf) -{ - struct drm_minor *drm_minor = to_drm_minor(device); - struct drm_device *drm_dev = drm_minor->dev; - if (drm_dev->driver->dri_library_name) - return drm_dev->driver->dri_library_name(drm_dev, buf); - return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); -} - -static struct device_attribute device_attrs[] = { - __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), -}; - -/** - * drm_sysfs_device_release - do nothing - * @dev: Linux device - * - * Normally, this would free the DRM device associated with @dev, along - * with cleaning up any other stuff. But we do that in the DRM core, so - * this function can just return and hope that the core does its job. - */ -static void drm_sysfs_device_release(struct device *dev) -{ - return; -} - -/** - * drm_sysfs_device_add - adds a class device to sysfs for a character driver - * @dev: DRM device to be added - * @head: DRM head in question - * - * Add a DRM device to the DRM's device model class. We use @dev's PCI device - * as the parent for the Linux device, and make sure it has a file containing - * the driver we're using (for userspace compatibility). - */ -int drm_sysfs_device_add(struct drm_minor *minor) -{ - int err; - int i, j; - char *minor_str; - - minor->kdev.parent = &minor->dev->pdev->dev; - minor->kdev.class = drm_class; - minor->kdev.release = drm_sysfs_device_release; - minor->kdev.devt = minor->device; - minor_str = "card%d"; - - snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index); - - err = device_register(&minor->kdev); - if (err) { - DRM_ERROR("device add failed: %d\n", err); - goto err_out; - } - - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(&minor->kdev, &device_attrs[i]); - if (err) - goto err_out_files; - } - - return 0; - -err_out_files: - if (i > 0) - for (j = 0; j < i; j++) - device_remove_file(&minor->kdev, &device_attrs[i]); - device_unregister(&minor->kdev); -err_out: - - return err; -} - -/** - * drm_sysfs_device_remove - remove DRM device - * @dev: DRM device to remove - * - * This call unregisters and cleans up a class device that was created with a - * call to drm_sysfs_device_add() - */ -void drm_sysfs_device_remove(struct drm_minor *minor) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(&minor->kdev, &device_attrs[i]); - device_unregister(&minor->kdev); -} diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c deleted file mode 100644 index c234c6f..0000000 --- a/drivers/char/drm/drm_vm.c +++ /dev/null @@ -1,673 +0,0 @@ -/** - * \file drm_vm.c - * Memory mapping for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#if defined(__ia64__) -#include -#endif - -static void drm_vm_open(struct vm_area_struct *vma); -static void drm_vm_close(struct vm_area_struct *vma); - -static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) -{ - pgprot_t tmp = vm_get_page_prot(vma->vm_flags); - -#if defined(__i386__) || defined(__x86_64__) - if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { - pgprot_val(tmp) |= _PAGE_PCD; - pgprot_val(tmp) &= ~_PAGE_PWT; - } -#elif defined(__powerpc__) - pgprot_val(tmp) |= _PAGE_NO_CACHE; - if (map_type == _DRM_REGISTERS) - pgprot_val(tmp) |= _PAGE_GUARDED; -#elif defined(__ia64__) - if (efi_range_is_wc(vma->vm_start, vma->vm_end - - vma->vm_start)) - tmp = pgprot_writecombine(tmp); - else - tmp = pgprot_noncached(tmp); -#elif defined(__sparc__) - tmp = pgprot_noncached(tmp); -#endif - return tmp; -} - -static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma) -{ - pgprot_t tmp = vm_get_page_prot(vma->vm_flags); - -#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE) - tmp |= _PAGE_NO_CACHE; -#endif - return tmp; -} - -/** - * \c fault method for AGP virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Find the right map and if it's AGP memory find the real physical page to - * map, get the page, increment the use count and return it. - */ -#if __OS_HAS_AGP -static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_map *map = NULL; - struct drm_map_list *r_list; - struct drm_hash_item *hash; - - /* - * Find the right map - */ - if (!drm_core_has_AGP(dev)) - goto vm_fault_error; - - if (!dev->agp || !dev->agp->cant_use_aperture) - goto vm_fault_error; - - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) - goto vm_fault_error; - - r_list = drm_hash_entry(hash, struct drm_map_list, hash); - map = r_list->map; - - if (map && map->type == _DRM_AGP) { - /* - * Using vm_pgoff as a selector forces us to use this unusual - * addressing scheme. - */ - unsigned long offset = (unsigned long)vmf->virtual_address - - vma->vm_start; - unsigned long baddr = map->offset + offset; - struct drm_agp_mem *agpmem; - struct page *page; - -#ifdef __alpha__ - /* - * Adjust to a bus-relative address - */ - baddr -= dev->hose->mem_space->start; -#endif - - /* - * It's AGP memory - find the real physical page to map - */ - list_for_each_entry(agpmem, &dev->agp->memory, head) { - if (agpmem->bound <= baddr && - agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) - break; - } - - if (!agpmem) - goto vm_fault_error; - - /* - * Get the page, inc the use count, and return it - */ - offset = (baddr - agpmem->bound) >> PAGE_SHIFT; - page = virt_to_page(__va(agpmem->memory->memory[offset])); - get_page(page); - vmf->page = page; - - DRM_DEBUG - ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", - baddr, __va(agpmem->memory->memory[offset]), offset, - page_count(page)); - return 0; - } -vm_fault_error: - return VM_FAULT_SIGBUS; /* Disallow mremap */ -} -#else /* __OS_HAS_AGP */ -static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return VM_FAULT_SIGBUS; -} -#endif /* __OS_HAS_AGP */ - -/** - * \c nopage method for shared virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Get the mapping, find the real physical page to map, get the page, and - * return it. - */ -static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_map *map = (struct drm_map *) vma->vm_private_data; - unsigned long offset; - unsigned long i; - struct page *page; - - if (!map) - return VM_FAULT_SIGBUS; /* Nothing allocated */ - - offset = (unsigned long)vmf->virtual_address - vma->vm_start; - i = (unsigned long)map->handle + offset; - page = vmalloc_to_page((void *)i); - if (!page) - return VM_FAULT_SIGBUS; - get_page(page); - vmf->page = page; - - DRM_DEBUG("shm_fault 0x%lx\n", offset); - return 0; -} - -/** - * \c close method for shared virtual memory. - * - * \param vma virtual memory area. - * - * Deletes map information if we are the last - * person to close a mapping and it's not in the global maplist. - */ -static void drm_vm_shm_close(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_vma_entry *pt, *temp; - struct drm_map *map; - struct drm_map_list *r_list; - int found_maps = 0; - - DRM_DEBUG("0x%08lx,0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - atomic_dec(&dev->vma_count); - - map = vma->vm_private_data; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { - if (pt->vma->vm_private_data == map) - found_maps++; - if (pt->vma == vma) { - list_del(&pt->head); - drm_free(pt, sizeof(*pt), DRM_MEM_VMAS); - } - } - - /* We were the only map that was found */ - if (found_maps == 1 && map->flags & _DRM_REMOVABLE) { - /* Check to see if we are in the maplist, if we are not, then - * we delete this mappings information. - */ - found_maps = 0; - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map == map) - found_maps++; - } - - if (!found_maps) { - drm_dma_handle_t dmah; - - switch (map->type) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: - if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { - int retcode; - retcode = mtrr_del(map->mtrr, - map->offset, - map->size); - DRM_DEBUG("mtrr_del = %d\n", retcode); - } - iounmap(map->handle); - break; - case _DRM_SHM: - vfree(map->handle); - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; - case _DRM_CONSISTENT: - dmah.vaddr = map->handle; - dmah.busaddr = map->offset; - dmah.size = map->size; - __drm_pci_free(dev, &dmah); - break; - } - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - } - } - mutex_unlock(&dev->struct_mutex); -} - -/** - * \c fault method for DMA virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Determine the page number from the page offset and get it from drm_device_dma::pagelist. - */ -static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_device_dma *dma = dev->dma; - unsigned long offset; - unsigned long page_nr; - struct page *page; - - if (!dma) - return VM_FAULT_SIGBUS; /* Error */ - if (!dma->pagelist) - return VM_FAULT_SIGBUS; /* Nothing allocated */ - - offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ - page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */ - page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK)))); - - get_page(page); - vmf->page = page; - - DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr); - return 0; -} - -/** - * \c fault method for scatter-gather virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. - */ -static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_map *map = (struct drm_map *) vma->vm_private_data; - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_sg_mem *entry = dev->sg; - unsigned long offset; - unsigned long map_offset; - unsigned long page_offset; - struct page *page; - - if (!entry) - return VM_FAULT_SIGBUS; /* Error */ - if (!entry->pagelist) - return VM_FAULT_SIGBUS; /* Nothing allocated */ - - offset = (unsigned long)vmf->virtual_address - vma->vm_start; - map_offset = map->offset - (unsigned long)dev->sg->virtual; - page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); - page = entry->pagelist[page_offset]; - get_page(page); - vmf->page = page; - - return 0; -} - -static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_fault(vma, vmf); -} - -static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_shm_fault(vma, vmf); -} - -static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_dma_fault(vma, vmf); -} - -static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_sg_fault(vma, vmf); -} - -/** AGP virtual memory operations */ -static struct vm_operations_struct drm_vm_ops = { - .fault = drm_vm_fault, - .open = drm_vm_open, - .close = drm_vm_close, -}; - -/** Shared virtual memory operations */ -static struct vm_operations_struct drm_vm_shm_ops = { - .fault = drm_vm_shm_fault, - .open = drm_vm_open, - .close = drm_vm_shm_close, -}; - -/** DMA virtual memory operations */ -static struct vm_operations_struct drm_vm_dma_ops = { - .fault = drm_vm_dma_fault, - .open = drm_vm_open, - .close = drm_vm_close, -}; - -/** Scatter-gather virtual memory operations */ -static struct vm_operations_struct drm_vm_sg_ops = { - .fault = drm_vm_sg_fault, - .open = drm_vm_open, - .close = drm_vm_close, -}; - -/** - * \c open method for shared virtual memory. - * - * \param vma virtual memory area. - * - * Create a new drm_vma_entry structure as the \p vma private data entry and - * add it to drm_device::vmalist. - */ -static void drm_vm_open_locked(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_vma_entry *vma_entry; - - DRM_DEBUG("0x%08lx,0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - atomic_inc(&dev->vma_count); - - vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); - if (vma_entry) { - vma_entry->vma = vma; - vma_entry->pid = current->pid; - list_add(&vma_entry->head, &dev->vmalist); - } -} - -static void drm_vm_open(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - - mutex_lock(&dev->struct_mutex); - drm_vm_open_locked(vma); - mutex_unlock(&dev->struct_mutex); -} - -/** - * \c close method for all virtual memory types. - * - * \param vma virtual memory area. - * - * Search the \p vma private data entry in drm_device::vmalist, unlink it, and - * free it. - */ -static void drm_vm_close(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_vma_entry *pt, *temp; - - DRM_DEBUG("0x%08lx,0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - atomic_dec(&dev->vma_count); - - mutex_lock(&dev->struct_mutex); - list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { - if (pt->vma == vma) { - list_del(&pt->head); - drm_free(pt, sizeof(*pt), DRM_MEM_VMAS); - break; - } - } - mutex_unlock(&dev->struct_mutex); -} - -/** - * mmap DMA memory. - * - * \param file_priv DRM file private. - * \param vma virtual memory area. - * \return zero on success or a negative number on failure. - * - * Sets the virtual memory area operations structure to vm_dma_ops, the file - * pointer, and calls vm_open(). - */ -static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev; - struct drm_device_dma *dma; - unsigned long length = vma->vm_end - vma->vm_start; - - dev = priv->minor->dev; - dma = dev->dma; - DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff); - - /* Length must match exact page count */ - if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { - return -EINVAL; - } - - if (!capable(CAP_SYS_ADMIN) && - (dma->flags & _DRM_DMA_USE_PCI_RO)) { - vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); -#if defined(__i386__) || defined(__x86_64__) - pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; -#else - /* Ye gads this is ugly. With more thought - we could move this up higher and use - `protection_map' instead. */ - vma->vm_page_prot = - __pgprot(pte_val - (pte_wrprotect - (__pte(pgprot_val(vma->vm_page_prot))))); -#endif - } - - vma->vm_ops = &drm_vm_dma_ops; - - vma->vm_flags |= VM_RESERVED; /* Don't swap */ - vma->vm_flags |= VM_DONTEXPAND; - - vma->vm_file = filp; /* Needed for drm_vm_open() */ - drm_vm_open_locked(vma); - return 0; -} - -unsigned long drm_core_get_map_ofs(struct drm_map * map) -{ - return map->offset; -} - -EXPORT_SYMBOL(drm_core_get_map_ofs); - -unsigned long drm_core_get_reg_ofs(struct drm_device *dev) -{ -#ifdef __alpha__ - return dev->hose->dense_mem_base - dev->hose->mem_space->start; -#else - return 0; -#endif -} - -EXPORT_SYMBOL(drm_core_get_reg_ofs); - -/** - * mmap DMA memory. - * - * \param file_priv DRM file private. - * \param vma virtual memory area. - * \return zero on success or a negative number on failure. - * - * If the virtual memory area has no offset associated with it then it's a DMA - * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist, - * checks that the restricted flag is not set, sets the virtual memory operations - * according to the mapping type and remaps the pages. Finally sets the file - * pointer and calls vm_open(). - */ -static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_map *map = NULL; - unsigned long offset = 0; - struct drm_hash_item *hash; - - DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff); - - if (!priv->authenticated) - return -EACCES; - - /* We check for "dma". On Apple's UniNorth, it's valid to have - * the AGP mapped at physical address 0 - * --BenH. - */ - if (!vma->vm_pgoff -#if __OS_HAS_AGP - && (!dev->agp - || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) -#endif - ) - return drm_mmap_dma(filp, vma); - - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) { - DRM_ERROR("Could not find map\n"); - return -EINVAL; - } - - map = drm_hash_entry(hash, struct drm_map_list, hash)->map; - if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) - return -EPERM; - - /* Check for valid size. */ - if (map->size < vma->vm_end - vma->vm_start) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { - vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); -#if defined(__i386__) || defined(__x86_64__) - pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; -#else - /* Ye gads this is ugly. With more thought - we could move this up higher and use - `protection_map' instead. */ - vma->vm_page_prot = - __pgprot(pte_val - (pte_wrprotect - (__pte(pgprot_val(vma->vm_page_prot))))); -#endif - } - - switch (map->type) { - case _DRM_AGP: - if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { - /* - * On some platforms we can't talk to bus dma address from the CPU, so for - * memory of type DRM_AGP, we'll deal with sorting out the real physical - * pages and mappings in fault() - */ -#if defined(__powerpc__) - pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; -#endif - vma->vm_ops = &drm_vm_ops; - break; - } - /* fall through to _DRM_FRAME_BUFFER... */ - case _DRM_FRAME_BUFFER: - case _DRM_REGISTERS: - offset = dev->driver->get_reg_ofs(dev); - vma->vm_flags |= VM_IO; /* not in core dump */ - vma->vm_page_prot = drm_io_prot(map->type, vma); - if (io_remap_pfn_range(vma, vma->vm_start, - (map->offset + offset) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," - " offset = 0x%lx\n", - map->type, - vma->vm_start, vma->vm_end, map->offset + offset); - vma->vm_ops = &drm_vm_ops; - break; - case _DRM_CONSISTENT: - /* Consistent memory is really like shared memory. But - * it's allocated in a different way, so avoid fault */ - if (remap_pfn_range(vma, vma->vm_start, - page_to_pfn(virt_to_page(map->handle)), - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - vma->vm_page_prot = drm_dma_prot(map->type, vma); - /* fall through to _DRM_SHM */ - case _DRM_SHM: - vma->vm_ops = &drm_vm_shm_ops; - vma->vm_private_data = (void *)map; - /* Don't let this area swap. Change when - DRM_KERNEL advisory is supported. */ - vma->vm_flags |= VM_RESERVED; - break; - case _DRM_SCATTER_GATHER: - vma->vm_ops = &drm_vm_sg_ops; - vma->vm_private_data = (void *)map; - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = drm_dma_prot(map->type, vma); - break; - default: - return -EINVAL; /* This should never happen. */ - } - vma->vm_flags |= VM_RESERVED; /* Don't swap */ - vma->vm_flags |= VM_DONTEXPAND; - - vma->vm_file = filp; /* Needed for drm_vm_open() */ - drm_vm_open_locked(vma); - return 0; -} - -int drm_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm_mmap_locked(filp, vma); - mutex_unlock(&dev->struct_mutex); - - return ret; -} -EXPORT_SYMBOL(drm_mmap); diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c deleted file mode 100644 index e5de8ea..0000000 --- a/drivers/char/drm/i810_dma.c +++ /dev/null @@ -1,1283 +0,0 @@ -/* i810_dma.c -- DMA support for the i810 -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Rickard E. (Rik) Faith - * Jeff Hartmann - * Keith Whitwell - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i810_drm.h" -#include "i810_drv.h" -#include /* For task queue support */ -#include -#include - -#define I810_BUF_FREE 2 -#define I810_BUF_CLIENT 1 -#define I810_BUF_HARDWARE 0 - -#define I810_BUF_UNMAPPED 0 -#define I810_BUF_MAPPED 1 - -static struct drm_buf *i810_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - int i; - int used; - - /* Linear search might not be the best solution */ - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, - I810_BUF_CLIENT); - if (used == I810_BUF_FREE) { - return buf; - } - } - return NULL; -} - -/* This should only be called if the buffer is not sent to the hardware - * yet, the hardware updates in use for us once its on the ring buffer. - */ - -static int i810_freelist_put(struct drm_device * dev, struct drm_buf * buf) -{ - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - int used; - - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); - if (used != I810_BUF_CLIENT) { - DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); - return -EINVAL; - } - - return 0; -} - -static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev; - drm_i810_private_t *dev_priv; - struct drm_buf *buf; - drm_i810_buf_priv_t *buf_priv; - - lock_kernel(); - dev = priv->minor->dev; - dev_priv = dev->dev_private; - buf = dev_priv->mmap_buffer; - buf_priv = buf->dev_private; - - vma->vm_flags |= (VM_IO | VM_DONTCOPY); - vma->vm_file = filp; - - buf_priv->currently_mapped = I810_BUF_MAPPED; - unlock_kernel(); - - if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - return 0; -} - -static const struct file_operations i810_buffer_fops = { - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = i810_mmap_buffers, - .fasync = drm_fasync, -}; - -static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) -{ - struct drm_device *dev = file_priv->minor->dev; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_private_t *dev_priv = dev->dev_private; - const struct file_operations *old_fops; - int retcode = 0; - - if (buf_priv->currently_mapped == I810_BUF_MAPPED) - return -EINVAL; - - down_write(¤t->mm->mmap_sem); - old_fops = file_priv->filp->f_op; - file_priv->filp->f_op = &i810_buffer_fops; - dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(file_priv->filp, 0, buf->total, - PROT_READ | PROT_WRITE, - MAP_SHARED, buf->bus_address); - dev_priv->mmap_buffer = NULL; - file_priv->filp->f_op = old_fops; - if (IS_ERR(buf_priv->virtual)) { - /* Real error */ - DRM_ERROR("mmap error\n"); - retcode = PTR_ERR(buf_priv->virtual); - buf_priv->virtual = NULL; - } - up_write(¤t->mm->mmap_sem); - - return retcode; -} - -static int i810_unmap_buffer(struct drm_buf * buf) -{ - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - int retcode = 0; - - if (buf_priv->currently_mapped != I810_BUF_MAPPED) - return -EINVAL; - - down_write(¤t->mm->mmap_sem); - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, - (size_t) buf->total); - up_write(¤t->mm->mmap_sem); - - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - buf_priv->virtual = NULL; - - return retcode; -} - -static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d, - struct drm_file *file_priv) -{ - struct drm_buf *buf; - drm_i810_buf_priv_t *buf_priv; - int retcode = 0; - - buf = i810_freelist_get(dev); - if (!buf) { - retcode = -ENOMEM; - DRM_DEBUG("retcode=%d\n", retcode); - return retcode; - } - - retcode = i810_map_buffer(buf, file_priv); - if (retcode) { - i810_freelist_put(dev, buf); - DRM_ERROR("mapbuf failed, retcode %d\n", retcode); - return retcode; - } - buf->file_priv = file_priv; - buf_priv = buf->dev_private; - d->granted = 1; - d->request_idx = buf->idx; - d->request_size = buf->total; - d->virtual = buf_priv->virtual; - - return retcode; -} - -static int i810_dma_cleanup(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - int i; - drm_i810_private_t *dev_priv = - (drm_i810_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } - if (dev_priv->hw_status_page) { - pci_free_consistent(dev->pdev, PAGE_SIZE, - dev_priv->hw_status_page, - dev_priv->dma_status_page); - /* Need to rewrite hardware status page */ - I810_WRITE(0x02080, 0x1ffff000); - } - drm_free(dev->dev_private, sizeof(drm_i810_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - if (buf_priv->kernel_virtual && buf->total) - drm_core_ioremapfree(&buf_priv->map, dev); - } - } - return 0; -} - -static int i810_wait_ring(struct drm_device * dev, int n) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - int iters = 0; - unsigned long end; - unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - - end = jiffies + (HZ * 3); - while (ring->space < n) { - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - - if (ring->head != last_head) { - end = jiffies + (HZ * 3); - last_head = ring->head; - } - - iters++; - if (time_before(end, jiffies)) { - DRM_ERROR("space: %d wanted %d\n", ring->space, n); - DRM_ERROR("lockup\n"); - goto out_wait_ring; - } - udelay(1); - } - - out_wait_ring: - return iters; -} - -static void i810_kernel_lost_context(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I810_READ(LP_RING + RING_TAIL); - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; -} - -static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_priv) -{ - struct drm_device_dma *dma = dev->dma; - int my_idx = 24; - u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx); - int i; - - if (dma->buf_count > 1019) { - /* Not enough space in the status page for the freelist */ - return -EINVAL; - } - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - buf_priv->in_use = hw_status++; - buf_priv->my_use_idx = my_idx; - my_idx += 4; - - *buf_priv->in_use = I810_BUF_FREE; - - buf_priv->map.offset = buf->bus_address; - buf_priv->map.size = buf->total; - buf_priv->map.type = _DRM_AGP; - buf_priv->map.flags = 0; - buf_priv->map.mtrr = 0; - - drm_core_ioremap(&buf_priv->map, dev); - buf_priv->kernel_virtual = buf_priv->map.handle; - - } - return 0; -} - -static int i810_dma_initialize(struct drm_device * dev, - drm_i810_private_t * dev_priv, - drm_i810_init_t * init) -{ - struct drm_map_list *r_list; - memset(dev_priv, 0, sizeof(drm_i810_private_t)); - - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK) { - dev_priv->sarea_map = r_list->map; - break; - } - } - if (!dev_priv->sarea_map) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find sarea!\n"); - return -EINVAL; - } - dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find dma buffer map!\n"); - return -EINVAL; - } - - dev_priv->sarea_priv = (drm_i810_sarea_t *) - ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset); - - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; - - dev_priv->ring.map.offset = dev->agp->base + init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = _DRM_AGP; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap(&dev_priv->ring.map, dev); - - if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - - dev_priv->w = init->w; - dev_priv->h = init->h; - dev_priv->pitch = init->pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->depth_offset = init->depth_offset; - dev_priv->front_offset = init->front_offset; - - dev_priv->overlay_offset = init->overlay_offset; - dev_priv->overlay_physical = init->overlay_physical; - - dev_priv->front_di1 = init->front_offset | init->pitch_bits; - dev_priv->back_di1 = init->back_offset | init->pitch_bits; - dev_priv->zi1 = init->depth_offset | init->pitch_bits; - - /* Program Hardware Status Page */ - dev_priv->hw_status_page = - pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); - if (!dev_priv->hw_status_page) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - I810_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - - /* Now we need to init our freelist */ - if (i810_freelist_init(dev, dev_priv) != 0) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("Not enough space in the status page for" - " the freelist\n"); - return -ENOMEM; - } - dev->dev_private = (void *)dev_priv; - - return 0; -} - -static int i810_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv; - drm_i810_init_t *init = data; - int retcode = 0; - - switch (init->func) { - case I810_INIT_DMA_1_4: - DRM_INFO("Using v1.4 init.\n"); - dev_priv = drm_alloc(sizeof(drm_i810_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i810_dma_initialize(dev, dev_priv, init); - break; - - case I810_CLEANUP_DMA: - DRM_INFO("DMA Cleanup\n"); - retcode = i810_dma_cleanup(dev); - break; - default: - return -EINVAL; - } - - return retcode; -} - -/* Most efficient way to verify state for the i810 is as it is - * emitted. Non-conformant state is silently dropped. - * - * Use 'volatile' & local var tmp to force the emitted values to be - * identical to the verified ones. - */ -static void i810EmitContextVerified(struct drm_device * dev, - volatile unsigned int *code) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I810_CTX_SETUP_SIZE); - - OUT_RING(GFX_OP_COLOR_FACTOR); - OUT_RING(code[I810_CTXREG_CF1]); - - OUT_RING(GFX_OP_STIPPLE); - OUT_RING(code[I810_CTXREG_ST1]); - - for (i = 4; i < I810_CTX_SETUP_SIZE; i++) { - tmp = code[i]; - - if ((tmp & (7 << 29)) == (3 << 29) && - (tmp & (0x1f << 24)) < (0x1d << 24)) { - OUT_RING(tmp); - j++; - } else - printk("constext state dropped!!!\n"); - } - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *code) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I810_TEX_SETUP_SIZE); - - OUT_RING(GFX_OP_MAP_INFO); - OUT_RING(code[I810_TEXREG_MI1]); - OUT_RING(code[I810_TEXREG_MI2]); - OUT_RING(code[I810_TEXREG_MI3]); - - for (i = 4; i < I810_TEX_SETUP_SIZE; i++) { - tmp = code[i]; - - if ((tmp & (7 << 29)) == (3 << 29) && - (tmp & (0x1f << 24)) < (0x1d << 24)) { - OUT_RING(tmp); - j++; - } else - printk("texture state dropped!!!\n"); - } - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -/* Need to do some additional checking when setting the dest buffer. - */ -static void i810EmitDestVerified(struct drm_device * dev, - volatile unsigned int *code) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); - - tmp = code[I810_DESTREG_DI1]; - if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { - OUT_RING(CMD_OP_DESTBUFFER_INFO); - OUT_RING(tmp); - } else - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", - tmp, dev_priv->front_di1, dev_priv->back_di1); - - /* invarient: - */ - OUT_RING(CMD_OP_Z_BUFFER_INFO); - OUT_RING(dev_priv->zi1); - - OUT_RING(GFX_OP_DESTBUFFER_VARS); - OUT_RING(code[I810_DESTREG_DV1]); - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(code[I810_DESTREG_DR1]); - OUT_RING(code[I810_DESTREG_DR2]); - OUT_RING(code[I810_DESTREG_DR3]); - OUT_RING(code[I810_DESTREG_DR4]); - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i810EmitState(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG("%x\n", dirty); - - if (dirty & I810_UPLOAD_BUFFERS) { - i810EmitDestVerified(dev, sarea_priv->BufferState); - sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; - } - - if (dirty & I810_UPLOAD_CTX) { - i810EmitContextVerified(dev, sarea_priv->ContextState); - sarea_priv->dirty &= ~I810_UPLOAD_CTX; - } - - if (dirty & I810_UPLOAD_TEX0) { - i810EmitTexVerified(dev, sarea_priv->TexState[0]); - sarea_priv->dirty &= ~I810_UPLOAD_TEX0; - } - - if (dirty & I810_UPLOAD_TEX1) { - i810EmitTexVerified(dev, sarea_priv->TexState[1]); - sarea_priv->dirty &= ~I810_UPLOAD_TEX1; - } -} - -/* need to verify - */ -static void i810_dma_dispatch_clear(struct drm_device * dev, int flags, - unsigned int clear_color, - unsigned int clear_zval) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int pitch = dev_priv->pitch; - int cpp = 2; - int i; - RING_LOCALS; - - if (dev_priv->current_page == 1) { - unsigned int tmp = flags; - - flags &= ~(I810_FRONT | I810_BACK); - if (tmp & I810_FRONT) - flags |= I810_BACK; - if (tmp & I810_BACK) - flags |= I810_FRONT; - } - - i810_kernel_lost_context(dev); - - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; - - for (i = 0; i < nbox; i++, pbox++) { - unsigned int x = pbox->x1; - unsigned int y = pbox->y1; - unsigned int width = (pbox->x2 - x) * cpp; - unsigned int height = pbox->y2 - y; - unsigned int start = y * pitch + x * cpp; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) - continue; - - if (flags & I810_FRONT) { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); - OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); - OUT_RING((height << 16) | width); - OUT_RING(start); - OUT_RING(clear_color); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - if (flags & I810_BACK) { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); - OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); - OUT_RING((height << 16) | width); - OUT_RING(dev_priv->back_offset + start); - OUT_RING(clear_color); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - if (flags & I810_DEPTH) { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); - OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); - OUT_RING((height << 16) | width); - OUT_RING(dev_priv->depth_offset + start); - OUT_RING(clear_zval); - OUT_RING(0); - ADVANCE_LP_RING(); - } - } -} - -static void i810_dma_dispatch_swap(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int pitch = dev_priv->pitch; - int cpp = 2; - int i; - RING_LOCALS; - - DRM_DEBUG("swapbuffers\n"); - - i810_kernel_lost_context(dev); - - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; - - for (i = 0; i < nbox; i++, pbox++) { - unsigned int w = pbox->x2 - pbox->x1; - unsigned int h = pbox->y2 - pbox->y1; - unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch; - unsigned int start = dst; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) - continue; - - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); - OUT_RING(pitch | (0xCC << 16)); - OUT_RING((h << 16) | (w * cpp)); - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->front_offset + start); - else - OUT_RING(dev_priv->back_offset + start); - OUT_RING(pitch); - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->back_offset + start); - else - OUT_RING(dev_priv->front_offset + start); - ADVANCE_LP_RING(); - } -} - -static void i810_dma_dispatch_vertex(struct drm_device * dev, - struct drm_buf * buf, int discard, int used) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_clip_rect *box = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - int i = 0; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; - - if (used > 4 * 1024) - used = 0; - - if (sarea_priv->dirty) - i810EmitState(dev); - - if (buf_priv->currently_mapped == I810_BUF_MAPPED) { - unsigned int prim = (sarea_priv->vertex_prim & PR_MASK); - - *(u32 *) buf_priv->kernel_virtual = - ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); - - if (used & 4) { - *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0; - used += 4; - } - - i810_unmap_buffer(buf); - } - - if (used) { - do { - if (i < nbox) { - BEGIN_LP_RING(4); - OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | - SC_ENABLE); - OUT_RING(GFX_OP_SCISSOR_INFO); - OUT_RING(box[i].x1 | (box[i].y1 << 16)); - OUT_RING((box[i].x2 - - 1) | ((box[i].y2 - 1) << 16)); - ADVANCE_LP_RING(); - } - - BEGIN_LP_RING(4); - OUT_RING(CMD_OP_BATCH_BUFFER); - OUT_RING(start | BB1_PROTECTED); - OUT_RING(start + used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - - } while (++i < nbox); - } - - if (discard) { - dev_priv->counter++; - - (void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_HARDWARE); - - BEGIN_LP_RING(8); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(buf_priv->my_use_idx); - OUT_RING(I810_BUF_FREE); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - ADVANCE_LP_RING(); - } -} - -static void i810_dma_dispatch_flip(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - int pitch = dev_priv->pitch; - RING_LOCALS; - - DRM_DEBUG("page=%d pfCurrentPage=%d\n", - dev_priv->current_page, - dev_priv->sarea_priv->pf_current_page); - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); - /* On i815 at least ASYNC is buggy */ - /* pitch<<5 is from 11.2.8 p158, - its the pitch / 8 then left shifted 8, - so (pitch >> 3) << 8 */ - OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ ); - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_offset); - dev_priv->current_page = 1; - } else { - OUT_RING(dev_priv->front_offset); - dev_priv->current_page = 0; - } - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(2); - OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP); - OUT_RING(0); - ADVANCE_LP_RING(); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; - -} - -static void i810_dma_quiescent(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(4); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - OUT_RING(0); - ADVANCE_LP_RING(); - - i810_wait_ring(dev, dev_priv->ring.Size - 8); -} - -static int i810_flush_queue(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - int i, ret = 0; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - ADVANCE_LP_RING(); - - i810_wait_ring(dev, dev_priv->ring.Size - 8); - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, - I810_BUF_FREE); - - if (used == I810_BUF_HARDWARE) - DRM_DEBUG("reclaimed from HARDWARE\n"); - if (used == I810_BUF_CLIENT) - DRM_DEBUG("still on client\n"); - } - - return ret; -} - -/* Must be called with the lock held */ -static void i810_reclaim_buffers(struct drm_device * dev, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - if (!dma) - return; - if (!dev->dev_private) - return; - if (!dma->buflist) - return; - - i810_flush_queue(dev); - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->file_priv == file_priv && buf_priv) { - int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_FREE); - - if (used == I810_BUF_CLIENT) - DRM_DEBUG("reclaimed from client\n"); - if (buf_priv->currently_mapped == I810_BUF_MAPPED) - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - } - } -} - -static int i810_flush_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - LOCK_TEST_WITH_RETURN(dev, file_priv); - - i810_flush_queue(dev); - return 0; -} - -static int i810_dma_vertex(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - drm_i810_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("idx %d used %d discard %d\n", - vertex->idx, vertex->used, vertex->discard); - - if (vertex->idx < 0 || vertex->idx > dma->buf_count) - return -EINVAL; - - i810_dma_dispatch_vertex(dev, - dma->buflist[vertex->idx], - vertex->discard, vertex->used); - - atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]); - atomic_inc(&dev->counts[_DRM_STAT_DMA]); - sarea_priv->last_enqueue = dev_priv->counter - 1; - sarea_priv->last_dispatch = (int)hw_status[5]; - - return 0; -} - -static int i810_clear_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_clear_t *clear = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) { - return -EINVAL; - } - - i810_dma_dispatch_clear(dev, clear->flags, - clear->clear_color, clear->clear_depth); - return 0; -} - -static int i810_swap_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - i810_dma_dispatch_swap(dev); - return 0; -} - -static int i810_getage(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - - sarea_priv->last_dispatch = (int)hw_status[5]; - return 0; -} - -static int i810_getbuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int retcode = 0; - drm_i810_dma_t *d = data; - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - d->granted = 0; - - retcode = i810_dma_get_buffer(dev, d, file_priv); - - DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", - task_pid_nr(current), retcode, d->granted); - - sarea_priv->last_dispatch = (int)hw_status[5]; - - return retcode; -} - -static int i810_copybuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* Never copy - 2.4.x doesn't need it */ - return 0; -} - -static int i810_docopy(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* Never copy - 2.4.x doesn't need it */ - return 0; -} - -static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, int used, - unsigned int last_render) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - int u; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); - if (u != I810_BUF_CLIENT) { - DRM_DEBUG("MC found buffer that isn't mine!\n"); - } - - if (used > 4 * 1024) - used = 0; - - sarea_priv->dirty = 0x7f; - - DRM_DEBUG("addr 0x%lx, used 0x%x\n", address, used); - - dev_priv->counter++; - DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG("start : %lx\n", start); - DRM_DEBUG("used : %d\n", used); - DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4); - - if (buf_priv->currently_mapped == I810_BUF_MAPPED) { - if (used & 4) { - *(u32 *) ((char *) buf_priv->virtual + used) = 0; - used += 4; - } - - i810_unmap_buffer(buf); - } - BEGIN_LP_RING(4); - OUT_RING(CMD_OP_BATCH_BUFFER); - OUT_RING(start | BB1_PROTECTED); - OUT_RING(start + used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(8); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(buf_priv->my_use_idx); - OUT_RING(I810_BUF_FREE); - OUT_RING(0); - - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(16); - OUT_RING(last_render); - OUT_RING(0); - ADVANCE_LP_RING(); -} - -static int i810_dma_mc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - drm_i810_mc_t *mc = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (mc->idx >= dma->buf_count || mc->idx < 0) - return -EINVAL; - - i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used, - mc->last_render); - - atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]); - atomic_inc(&dev->counts[_DRM_STAT_DMA]); - sarea_priv->last_enqueue = dev_priv->counter - 1; - sarea_priv->last_dispatch = (int)hw_status[5]; - - return 0; -} - -static int i810_rstatus(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - - return (int)(((u32 *) (dev_priv->hw_status_page))[4]); -} - -static int i810_ov0_info(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - drm_i810_overlay_t *ov = data; - - ov->offset = dev_priv->overlay_offset; - ov->physical = dev_priv->overlay_physical; - - return 0; -} - -static int i810_fstatus(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - return I810_READ(0x30008); -} - -static int i810_ov0_flip(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - //Tell the overlay to update - I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); - - return 0; -} - -/* Not sure why this isn't set all the time: - */ -static void i810_do_init_pageflip(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; -} - -static int i810_do_cleanup_pageflip(struct drm_device * dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - if (dev_priv->current_page != 0) - i810_dma_dispatch_flip(dev); - - dev_priv->page_flipping = 0; - return 0; -} - -static int i810_flip_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv->page_flipping) - i810_do_init_pageflip(dev); - - i810_dma_dispatch_flip(dev); - return 0; -} - -int i810_driver_load(struct drm_device *dev, unsigned long flags) -{ - /* i810 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - return 0; -} - -void i810_driver_lastclose(struct drm_device * dev) -{ - i810_dma_cleanup(dev); -} - -void i810_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_i810_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { - i810_do_cleanup_pageflip(dev); - } - } -} - -void i810_driver_reclaim_buffers_locked(struct drm_device * dev, - struct drm_file *file_priv) -{ - i810_reclaim_buffers(dev, file_priv); -} - -int i810_driver_dma_quiescent(struct drm_device * dev) -{ - i810_dma_quiescent(dev); - return 0; -} - -struct drm_ioctl_desc i810_ioctls[] = { - DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH) -}; - -int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); - -/** - * Determine if the device really is AGP or not. - * - * All Intel graphics chipsets are treated as AGP, even if they are really - * PCI-e. - * - * \param dev The device to be tested. - * - * \returns - * A value of 1 is always retured to indictate every i810 is AGP. - */ -int i810_driver_device_is_agp(struct drm_device * dev) -{ - return 1; -} diff --git a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h deleted file mode 100644 index 7a10bb6..0000000 --- a/drivers/char/drm/i810_drm.h +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef _I810_DRM_H_ -#define _I810_DRM_H_ - -/* WARNING: These defines must be the same as what the Xserver uses. - * if you change them, you must change the defines in the Xserver. - */ - -#ifndef _I810_DEFINES_ -#define _I810_DEFINES_ - -#define I810_DMA_BUF_ORDER 12 -#define I810_DMA_BUF_SZ (1< - * Jeff Hartmann - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "i810_drm.h" -#include "i810_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - i810_PCI_IDS -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | - DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, - .dev_priv_size = sizeof(drm_i810_buf_priv_t), - .load = i810_driver_load, - .lastclose = i810_driver_lastclose, - .preclose = i810_driver_preclose, - .device_is_agp = i810_driver_device_is_agp, - .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, - .dma_quiescent = i810_driver_dma_quiescent, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = i810_ioctls, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, - - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init i810_init(void) -{ - driver.num_ioctls = i810_max_ioctl; - return drm_init(&driver); -} - -static void __exit i810_exit(void) -{ - drm_exit(&driver); -} - -module_init(i810_init); -module_exit(i810_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h deleted file mode 100644 index 0118849..0000000 --- a/drivers/char/drm/i810_drv.h +++ /dev/null @@ -1,242 +0,0 @@ -/* i810_drv.h -- Private header for the Matrox g200/g400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Rickard E. (Rik) Faith - * Jeff Hartmann - * - */ - -#ifndef _I810_DRV_H_ -#define _I810_DRV_H_ - -/* General customization: - */ - -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i810" -#define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20030605" - -/* Interface history - * - * 1.1 - XFree86 4.1 - * 1.2 - XvMC interfaces - * - XFree86 4.2 - * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) - * - Remove requirement for interrupt (leave stubs again) - * 1.3 - Add page flipping. - * 1.4 - fix DRM interface - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 4 -#define DRIVER_PATCHLEVEL 0 - -typedef struct drm_i810_buf_priv { - u32 *in_use; - int my_use_idx; - int currently_mapped; - void *virtual; - void *kernel_virtual; - drm_local_map_t map; -} drm_i810_buf_priv_t; - -typedef struct _drm_i810_ring_buffer { - int tail_mask; - unsigned long Start; - unsigned long End; - unsigned long Size; - u8 *virtual_start; - int head; - int tail; - int space; - drm_local_map_t map; -} drm_i810_ring_buffer_t; - -typedef struct drm_i810_private { - struct drm_map *sarea_map; - struct drm_map *mmio_map; - - drm_i810_sarea_t *sarea_priv; - drm_i810_ring_buffer_t ring; - - void *hw_status_page; - unsigned long counter; - - dma_addr_t dma_status_page; - - struct drm_buf *mmap_buffer; - - u32 front_di1, back_di1, zi1; - - int back_offset; - int depth_offset; - int overlay_offset; - int overlay_physical; - int w, h; - int pitch; - int back_pitch; - int depth_pitch; - - int do_boxes; - int dma_used; - - int current_page; - int page_flipping; - - wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; - - int front_offset; -} drm_i810_private_t; - - /* i810_dma.c */ -extern int i810_driver_dma_quiescent(struct drm_device * dev); -extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev, - struct drm_file *file_priv); -extern int i810_driver_load(struct drm_device *, unsigned long flags); -extern void i810_driver_lastclose(struct drm_device * dev); -extern void i810_driver_preclose(struct drm_device * dev, - struct drm_file *file_priv); -extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev, - struct drm_file *file_priv); -extern int i810_driver_device_is_agp(struct drm_device * dev); - -extern struct drm_ioctl_desc i810_ioctls[]; -extern int i810_max_ioctl; - -#define I810_BASE(reg) ((unsigned long) \ - dev_priv->mmio_map->handle) -#define I810_ADDR(reg) (I810_BASE(reg) + reg) -#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) -#define I810_READ(reg) I810_DEREF(reg) -#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) -#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) -#define I810_READ16(reg) I810_DEREF16(reg) -#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) - -#define I810_VERBOSE 0 -#define RING_LOCALS unsigned int outring, ringmask; \ - volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) - -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) -#define CMD_REPORT_HEAD (7<<23) -#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) -#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) - -#define INST_PARSER_CLIENT 0x00000000 -#define INST_OP_FLUSH 0x02000000 -#define INST_FLUSH_MAP_CACHE 0x00000001 - -#define BB1_START_ADDR_MASK (~0x7) -#define BB1_PROTECTED (1<<0) -#define BB1_UNPROTECTED (0<<0) -#define BB2_END_ADDR_MASK (~0x7) - -#define I810REG_HWSTAM 0x02098 -#define I810REG_INT_IDENTITY_R 0x020a4 -#define I810REG_INT_MASK_R 0x020a8 -#define I810REG_INT_ENABLE_R 0x020a0 - -#define LP_RING 0x2030 -#define HP_RING 0x2040 -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0x00FFFFF8 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x000FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) - -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) - -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24)) - -#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) -#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) -#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23)) -#define CMD_OP_WAIT_FOR_EVENT ((0x0<<29)|(0x03<<23)) - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define WAIT_FOR_PLANE_A_SCANLINES (1<<1) -#define WAIT_FOR_PLANE_A_FLIP (1<<2) -#define WAIT_FOR_VBLANK (1<<3) - -#endif diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c deleted file mode 100644 index a86ab30..0000000 --- a/drivers/char/drm/i830_dma.c +++ /dev/null @@ -1,1553 +0,0 @@ -/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Rickard E. (Rik) Faith - * Jeff Hartmann - * Keith Whitwell - * Abraham vd Merwe - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i830_drm.h" -#include "i830_drv.h" -#include /* For task queue support */ -#include -#include -#include - -#define I830_BUF_FREE 2 -#define I830_BUF_CLIENT 1 -#define I830_BUF_HARDWARE 0 - -#define I830_BUF_UNMAPPED 0 -#define I830_BUF_MAPPED 1 - -static struct drm_buf *i830_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - int i; - int used; - - /* Linear search might not be the best solution */ - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, - I830_BUF_CLIENT); - if (used == I830_BUF_FREE) { - return buf; - } - } - return NULL; -} - -/* This should only be called if the buffer is not sent to the hardware - * yet, the hardware updates in use for us once its on the ring buffer. - */ - -static int i830_freelist_put(struct drm_device * dev, struct drm_buf * buf) -{ - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - int used; - - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); - if (used != I830_BUF_CLIENT) { - DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); - return -EINVAL; - } - - return 0; -} - -static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev; - drm_i830_private_t *dev_priv; - struct drm_buf *buf; - drm_i830_buf_priv_t *buf_priv; - - lock_kernel(); - dev = priv->minor->dev; - dev_priv = dev->dev_private; - buf = dev_priv->mmap_buffer; - buf_priv = buf->dev_private; - - vma->vm_flags |= (VM_IO | VM_DONTCOPY); - vma->vm_file = filp; - - buf_priv->currently_mapped = I830_BUF_MAPPED; - unlock_kernel(); - - if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - return 0; -} - -static const struct file_operations i830_buffer_fops = { - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = i830_mmap_buffers, - .fasync = drm_fasync, -}; - -static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) -{ - struct drm_device *dev = file_priv->minor->dev; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - drm_i830_private_t *dev_priv = dev->dev_private; - const struct file_operations *old_fops; - unsigned long virtual; - int retcode = 0; - - if (buf_priv->currently_mapped == I830_BUF_MAPPED) - return -EINVAL; - - down_write(¤t->mm->mmap_sem); - old_fops = file_priv->filp->f_op; - file_priv->filp->f_op = &i830_buffer_fops; - dev_priv->mmap_buffer = buf; - virtual = do_mmap(file_priv->filp, 0, buf->total, PROT_READ | PROT_WRITE, - MAP_SHARED, buf->bus_address); - dev_priv->mmap_buffer = NULL; - file_priv->filp->f_op = old_fops; - if (IS_ERR((void *)virtual)) { /* ugh */ - /* Real error */ - DRM_ERROR("mmap error\n"); - retcode = PTR_ERR((void *)virtual); - buf_priv->virtual = NULL; - } else { - buf_priv->virtual = (void __user *)virtual; - } - up_write(¤t->mm->mmap_sem); - - return retcode; -} - -static int i830_unmap_buffer(struct drm_buf * buf) -{ - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - int retcode = 0; - - if (buf_priv->currently_mapped != I830_BUF_MAPPED) - return -EINVAL; - - down_write(¤t->mm->mmap_sem); - retcode = do_munmap(current->mm, - (unsigned long)buf_priv->virtual, - (size_t) buf->total); - up_write(¤t->mm->mmap_sem); - - buf_priv->currently_mapped = I830_BUF_UNMAPPED; - buf_priv->virtual = NULL; - - return retcode; -} - -static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, - struct drm_file *file_priv) -{ - struct drm_buf *buf; - drm_i830_buf_priv_t *buf_priv; - int retcode = 0; - - buf = i830_freelist_get(dev); - if (!buf) { - retcode = -ENOMEM; - DRM_DEBUG("retcode=%d\n", retcode); - return retcode; - } - - retcode = i830_map_buffer(buf, file_priv); - if (retcode) { - i830_freelist_put(dev, buf); - DRM_ERROR("mapbuf failed, retcode %d\n", retcode); - return retcode; - } - buf->file_priv = file_priv; - buf_priv = buf->dev_private; - d->granted = 1; - d->request_idx = buf->idx; - d->request_size = buf->total; - d->virtual = buf_priv->virtual; - - return retcode; -} - -static int i830_dma_cleanup(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - int i; - drm_i830_private_t *dev_priv = - (drm_i830_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } - if (dev_priv->hw_status_page) { - pci_free_consistent(dev->pdev, PAGE_SIZE, - dev_priv->hw_status_page, - dev_priv->dma_status_page); - /* Need to rewrite hardware status page */ - I830_WRITE(0x02080, 0x1ffff000); - } - - drm_free(dev->dev_private, sizeof(drm_i830_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - if (buf_priv->kernel_virtual && buf->total) - drm_core_ioremapfree(&buf_priv->map, dev); - } - } - return 0; -} - -int i830_wait_ring(struct drm_device * dev, int n, const char *caller) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_ring_buffer_t *ring = &(dev_priv->ring); - int iters = 0; - unsigned long end; - unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - - end = jiffies + (HZ * 3); - while (ring->space < n) { - ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - - if (ring->head != last_head) { - end = jiffies + (HZ * 3); - last_head = ring->head; - } - - iters++; - if (time_before(end, jiffies)) { - DRM_ERROR("space: %d wanted %d\n", ring->space, n); - DRM_ERROR("lockup\n"); - goto out_wait_ring; - } - udelay(1); - dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; - } - - out_wait_ring: - return iters; -} - -static void i830_kernel_lost_context(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_ring_buffer_t *ring = &(dev_priv->ring); - - ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - - if (ring->head == ring->tail) - dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; -} - -static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_priv) -{ - struct drm_device_dma *dma = dev->dma; - int my_idx = 36; - u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx); - int i; - - if (dma->buf_count > 1019) { - /* Not enough space in the status page for the freelist */ - return -EINVAL; - } - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - - buf_priv->in_use = hw_status++; - buf_priv->my_use_idx = my_idx; - my_idx += 4; - - *buf_priv->in_use = I830_BUF_FREE; - - buf_priv->map.offset = buf->bus_address; - buf_priv->map.size = buf->total; - buf_priv->map.type = _DRM_AGP; - buf_priv->map.flags = 0; - buf_priv->map.mtrr = 0; - - drm_core_ioremap(&buf_priv->map, dev); - buf_priv->kernel_virtual = buf_priv->map.handle; - } - return 0; -} - -static int i830_dma_initialize(struct drm_device * dev, - drm_i830_private_t * dev_priv, - drm_i830_init_t * init) -{ - struct drm_map_list *r_list; - - memset(dev_priv, 0, sizeof(drm_i830_private_t)); - - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK) { - dev_priv->sarea_map = r_list->map; - break; - } - } - - if (!dev_priv->sarea_map) { - dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("can not find sarea!\n"); - return -EINVAL; - } - dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("can not find dma buffer map!\n"); - return -EINVAL; - } - - dev_priv->sarea_priv = (drm_i830_sarea_t *) - ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset); - - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; - - dev_priv->ring.map.offset = dev->agp->base + init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = _DRM_AGP; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap(&dev_priv->ring.map, dev); - - if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - - dev_priv->w = init->w; - dev_priv->h = init->h; - dev_priv->pitch = init->pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->depth_offset = init->depth_offset; - dev_priv->front_offset = init->front_offset; - - dev_priv->front_di1 = init->front_offset | init->pitch_bits; - dev_priv->back_di1 = init->back_offset | init->pitch_bits; - dev_priv->zi1 = init->depth_offset | init->pitch_bits; - - DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1); - DRM_DEBUG("back_offset %x\n", dev_priv->back_offset); - DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1); - DRM_DEBUG("pitch_bits %x\n", init->pitch_bits); - - dev_priv->cpp = init->cpp; - /* We are using separate values as placeholders for mechanisms for - * private backbuffer/depthbuffer usage. - */ - - dev_priv->back_pitch = init->back_pitch; - dev_priv->depth_pitch = init->depth_pitch; - dev_priv->do_boxes = 0; - dev_priv->use_mi_batchbuffer_start = 0; - - /* Program Hardware Status Page */ - dev_priv->hw_status_page = - pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); - if (!dev_priv->hw_status_page) { - dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - I830_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - - /* Now we need to init our freelist */ - if (i830_freelist_init(dev, dev_priv) != 0) { - dev->dev_private = (void *)dev_priv; - i830_dma_cleanup(dev); - DRM_ERROR("Not enough space in the status page for" - " the freelist\n"); - return -ENOMEM; - } - dev->dev_private = (void *)dev_priv; - - return 0; -} - -static int i830_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv; - drm_i830_init_t *init = data; - int retcode = 0; - - switch (init->func) { - case I830_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i830_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i830_dma_initialize(dev, dev_priv, init); - break; - case I830_CLEANUP_DMA: - retcode = i830_dma_cleanup(dev); - break; - default: - retcode = -EINVAL; - break; - } - - return retcode; -} - -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define ST1_ENABLE (1<<16) -#define ST1_MASK (0xffff) - -/* Most efficient way to verify state for the i830 is as it is - * emitted. Non-conformant state is silently dropped. - */ -static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I830_CTX_SETUP_SIZE + 4); - - for (i = 0; i < I830_CTXREG_BLENDCOLR0; i++) { - tmp = code[i]; - if ((tmp & (7 << 29)) == CMD_3D && - (tmp & (0x1f << 24)) < (0x1d << 24)) { - OUT_RING(tmp); - j++; - } else { - DRM_ERROR("Skipping %d\n", i); - } - } - - OUT_RING(STATE3D_CONST_BLEND_COLOR_CMD); - OUT_RING(code[I830_CTXREG_BLENDCOLR]); - j += 2; - - for (i = I830_CTXREG_VF; i < I830_CTXREG_MCSB0; i++) { - tmp = code[i]; - if ((tmp & (7 << 29)) == CMD_3D && - (tmp & (0x1f << 24)) < (0x1d << 24)) { - OUT_RING(tmp); - j++; - } else { - DRM_ERROR("Skipping %d\n", i); - } - } - - OUT_RING(STATE3D_MAP_COORD_SETBIND_CMD); - OUT_RING(code[I830_CTXREG_MCSB1]); - j += 2; - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || - (code[I830_TEXREG_MI0] & ~(0xf * LOAD_TEXTURE_MAP0)) == - (STATE3D_LOAD_STATE_IMMEDIATE_2 | 4)) { - - BEGIN_LP_RING(I830_TEX_SETUP_SIZE); - - OUT_RING(code[I830_TEXREG_MI0]); /* TM0LI */ - OUT_RING(code[I830_TEXREG_MI1]); /* TM0S0 */ - OUT_RING(code[I830_TEXREG_MI2]); /* TM0S1 */ - OUT_RING(code[I830_TEXREG_MI3]); /* TM0S2 */ - OUT_RING(code[I830_TEXREG_MI4]); /* TM0S3 */ - OUT_RING(code[I830_TEXREG_MI5]); /* TM0S4 */ - - for (i = 6; i < I830_TEX_SETUP_SIZE; i++) { - tmp = code[i]; - OUT_RING(tmp); - j++; - } - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); - } else - printk("rejected packet %x\n", code[0]); -} - -static void i830EmitTexBlendVerified(struct drm_device * dev, - unsigned int *code, unsigned int num) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - if (!num) - return; - - BEGIN_LP_RING(num + 1); - - for (i = 0; i < num; i++) { - tmp = code[i]; - OUT_RING(tmp); - j++; - } - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i830EmitTexPalette(struct drm_device * dev, - unsigned int *palette, int number, int is_shared) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - int i; - RING_LOCALS; - - return; - - BEGIN_LP_RING(258); - - if (is_shared == 1) { - OUT_RING(CMD_OP_MAP_PALETTE_LOAD | - MAP_PALETTE_NUM(0) | MAP_PALETTE_BOTH); - } else { - OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); - } - for (i = 0; i < 256; i++) { - OUT_RING(palette[i]); - } - OUT_RING(0); - /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! - */ -} - -/* Need to do some additional checking when setting the dest buffer. - */ -static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I830_DEST_SETUP_SIZE + 10); - - tmp = code[I830_DESTREG_CBUFADDR]; - if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { - if (((int)outring) & 8) { - OUT_RING(0); - OUT_RING(0); - } - - OUT_RING(CMD_OP_DESTBUFFER_INFO); - OUT_RING(BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | - BUF_3D_USE_FENCE); - OUT_RING(tmp); - OUT_RING(0); - - OUT_RING(CMD_OP_DESTBUFFER_INFO); - OUT_RING(BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | - BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); - OUT_RING(dev_priv->zi1); - OUT_RING(0); - } else { - DRM_ERROR("bad di1 %x (allow %x or %x)\n", - tmp, dev_priv->front_di1, dev_priv->back_di1); - } - - /* invarient: - */ - - OUT_RING(GFX_OP_DESTBUFFER_VARS); - OUT_RING(code[I830_DESTREG_DV1]); - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(code[I830_DESTREG_DR1]); - OUT_RING(code[I830_DESTREG_DR2]); - OUT_RING(code[I830_DESTREG_DR3]); - OUT_RING(code[I830_DESTREG_DR4]); - - /* Need to verify this */ - tmp = code[I830_DESTREG_SENABLE]; - if ((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { - OUT_RING(tmp); - } else { - DRM_ERROR("bad scissor enable\n"); - OUT_RING(0); - } - - OUT_RING(GFX_OP_SCISSOR_RECT); - OUT_RING(code[I830_DESTREG_SR1]); - OUT_RING(code[I830_DESTREG_SR2]); - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - BEGIN_LP_RING(2); - OUT_RING(GFX_OP_STIPPLE); - OUT_RING(code[1]); - ADVANCE_LP_RING(); -} - -static void i830EmitState(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG("%s %x\n", __func__, dirty); - - if (dirty & I830_UPLOAD_BUFFERS) { - i830EmitDestVerified(dev, sarea_priv->BufferState); - sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; - } - - if (dirty & I830_UPLOAD_CTX) { - i830EmitContextVerified(dev, sarea_priv->ContextState); - sarea_priv->dirty &= ~I830_UPLOAD_CTX; - } - - if (dirty & I830_UPLOAD_TEX0) { - i830EmitTexVerified(dev, sarea_priv->TexState[0]); - sarea_priv->dirty &= ~I830_UPLOAD_TEX0; - } - - if (dirty & I830_UPLOAD_TEX1) { - i830EmitTexVerified(dev, sarea_priv->TexState[1]); - sarea_priv->dirty &= ~I830_UPLOAD_TEX1; - } - - if (dirty & I830_UPLOAD_TEXBLEND0) { - i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[0], - sarea_priv->TexBlendStateWordsUsed[0]); - sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0; - } - - if (dirty & I830_UPLOAD_TEXBLEND1) { - i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[1], - sarea_priv->TexBlendStateWordsUsed[1]); - sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1; - } - - if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); - } else { - if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { - i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); - } - if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { - i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); - } - - /* 1.3: - */ -#if 0 - if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) { - i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); - } - if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) { - i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0); - sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); - } -#endif - } - - /* 1.3: - */ - if (dirty & I830_UPLOAD_STIPPLE) { - i830EmitStippleVerified(dev, sarea_priv->StippleState); - sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; - } - - if (dirty & I830_UPLOAD_TEX2) { - i830EmitTexVerified(dev, sarea_priv->TexState2); - sarea_priv->dirty &= ~I830_UPLOAD_TEX2; - } - - if (dirty & I830_UPLOAD_TEX3) { - i830EmitTexVerified(dev, sarea_priv->TexState3); - sarea_priv->dirty &= ~I830_UPLOAD_TEX3; - } - - if (dirty & I830_UPLOAD_TEXBLEND2) { - i830EmitTexBlendVerified(dev, - sarea_priv->TexBlendState2, - sarea_priv->TexBlendStateWordsUsed2); - - sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; - } - - if (dirty & I830_UPLOAD_TEXBLEND3) { - i830EmitTexBlendVerified(dev, - sarea_priv->TexBlendState3, - sarea_priv->TexBlendStateWordsUsed3); - sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; - } -} - -/* ================================================================ - * Performance monitoring functions - */ - -static void i830_fill_box(struct drm_device * dev, - int x, int y, int w, int h, int r, int g, int b) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - u32 color; - unsigned int BR13, CMD; - RING_LOCALS; - - BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1 << 24); - CMD = XY_COLOR_BLT_CMD; - x += dev_priv->sarea_priv->boxes[0].x1; - y += dev_priv->sarea_priv->boxes[0].y1; - - if (dev_priv->cpp == 4) { - BR13 |= (1 << 25); - CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); - } else { - color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); - } - - BEGIN_LP_RING(6); - OUT_RING(CMD); - OUT_RING(BR13); - OUT_RING((y << 16) | x); - OUT_RING(((y + h) << 16) | (x + w)); - - if (dev_priv->current_page == 1) { - OUT_RING(dev_priv->front_offset); - } else { - OUT_RING(dev_priv->back_offset); - } - - OUT_RING(color); - ADVANCE_LP_RING(); -} - -static void i830_cp_performance_boxes(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - - /* Purple box for page flipping - */ - if (dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP) - i830_fill_box(dev, 4, 4, 8, 8, 255, 0, 255); - - /* Red box if we have to wait for idle at any point - */ - if (dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT) - i830_fill_box(dev, 16, 4, 8, 8, 255, 0, 0); - - /* Blue box: lost context? - */ - if (dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT) - i830_fill_box(dev, 28, 4, 8, 8, 0, 0, 255); - - /* Yellow box for texture swaps - */ - if (dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD) - i830_fill_box(dev, 40, 4, 8, 8, 255, 255, 0); - - /* Green box if hardware never idles (as far as we can tell) - */ - if (!(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY)) - i830_fill_box(dev, 64, 4, 8, 8, 0, 255, 0); - - /* Draw bars indicating number of buffers allocated - * (not a great measure, easily confused) - */ - if (dev_priv->dma_used) { - int bar = dev_priv->dma_used / 10240; - if (bar > 100) - bar = 100; - if (bar < 1) - bar = 1; - i830_fill_box(dev, 4, 16, bar, 4, 196, 128, 128); - dev_priv->dma_used = 0; - } - - dev_priv->sarea_priv->perf_boxes = 0; -} - -static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, - unsigned int clear_color, - unsigned int clear_zval, - unsigned int clear_depthmask) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int pitch = dev_priv->pitch; - int cpp = dev_priv->cpp; - int i; - unsigned int BR13, CMD, D_CMD; - RING_LOCALS; - - if (dev_priv->current_page == 1) { - unsigned int tmp = flags; - - flags &= ~(I830_FRONT | I830_BACK); - if (tmp & I830_FRONT) - flags |= I830_BACK; - if (tmp & I830_BACK) - flags |= I830_FRONT; - } - - i830_kernel_lost_context(dev); - - switch (cpp) { - case 2: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); - D_CMD = CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25); - CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - D_CMD = XY_COLOR_BLT_CMD; - if (clear_depthmask & 0x00ffffff) - D_CMD |= XY_COLOR_BLT_WRITE_RGB; - if (clear_depthmask & 0xff000000) - D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; - break; - default: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); - D_CMD = CMD = XY_COLOR_BLT_CMD; - break; - } - - if (nbox > I830_NR_SAREA_CLIPRECTS) - nbox = I830_NR_SAREA_CLIPRECTS; - - for (i = 0; i < nbox; i++, pbox++) { - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) - continue; - - if (flags & I830_FRONT) { - DRM_DEBUG("clear front\n"); - BEGIN_LP_RING(6); - OUT_RING(CMD); - OUT_RING(BR13); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(dev_priv->front_offset); - OUT_RING(clear_color); - ADVANCE_LP_RING(); - } - - if (flags & I830_BACK) { - DRM_DEBUG("clear back\n"); - BEGIN_LP_RING(6); - OUT_RING(CMD); - OUT_RING(BR13); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(dev_priv->back_offset); - OUT_RING(clear_color); - ADVANCE_LP_RING(); - } - - if (flags & I830_DEPTH) { - DRM_DEBUG("clear depth\n"); - BEGIN_LP_RING(6); - OUT_RING(D_CMD); - OUT_RING(BR13); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(dev_priv->depth_offset); - OUT_RING(clear_zval); - ADVANCE_LP_RING(); - } - } -} - -static void i830_dma_dispatch_swap(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int pitch = dev_priv->pitch; - int cpp = dev_priv->cpp; - int i; - unsigned int CMD, BR13; - RING_LOCALS; - - DRM_DEBUG("swapbuffers\n"); - - i830_kernel_lost_context(dev); - - if (dev_priv->do_boxes) - i830_cp_performance_boxes(dev); - - switch (cpp) { - case 2: - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - break; - case 4: - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - break; - default: - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - break; - } - - if (nbox > I830_NR_SAREA_CLIPRECTS) - nbox = I830_NR_SAREA_CLIPRECTS; - - for (i = 0; i < nbox; i++, pbox++) { - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) - continue; - - DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", - pbox->x1, pbox->y1, pbox->x2, pbox->y2); - - BEGIN_LP_RING(8); - OUT_RING(CMD); - OUT_RING(BR13); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING((pbox->y2 << 16) | pbox->x2); - - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->front_offset); - else - OUT_RING(dev_priv->back_offset); - - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING(BR13 & 0xffff); - - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->back_offset); - else - OUT_RING(dev_priv->front_offset); - - ADVANCE_LP_RING(); - } -} - -static void i830_dma_dispatch_flip(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", - __func__, - dev_priv->current_page, - dev_priv->sarea_priv->pf_current_page); - - i830_kernel_lost_context(dev); - - if (dev_priv->do_boxes) { - dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; - i830_cp_performance_boxes(dev); - } - - BEGIN_LP_RING(2); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(6); - OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); - OUT_RING(0); - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_offset); - dev_priv->current_page = 1; - } else { - OUT_RING(dev_priv->front_offset); - dev_priv->current_page = 0; - } - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(2); - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); - OUT_RING(0); - ADVANCE_LP_RING(); - - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; -} - -static void i830_dma_dispatch_vertex(struct drm_device * dev, - struct drm_buf * buf, int discard, int used) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_clip_rect *box = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - int i = 0, u; - RING_LOCALS; - - i830_kernel_lost_context(dev); - - if (nbox > I830_NR_SAREA_CLIPRECTS) - nbox = I830_NR_SAREA_CLIPRECTS; - - if (discard) { - u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, - I830_BUF_HARDWARE); - if (u != I830_BUF_CLIENT) { - DRM_DEBUG("xxxx 2\n"); - } - } - - if (used > 4 * 1023) - used = 0; - - if (sarea_priv->dirty) - i830EmitState(dev); - - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", - address, used, nbox); - - dev_priv->counter++; - DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG("i830_dma_dispatch\n"); - DRM_DEBUG("start : %lx\n", start); - DRM_DEBUG("used : %d\n", used); - DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4); - - if (buf_priv->currently_mapped == I830_BUF_MAPPED) { - u32 *vp = buf_priv->kernel_virtual; - - vp[0] = (GFX_OP_PRIMITIVE | - sarea_priv->vertex_prim | ((used / 4) - 2)); - - if (dev_priv->use_mi_batchbuffer_start) { - vp[used / 4] = MI_BATCH_BUFFER_END; - used += 4; - } - - if (used & 4) { - vp[used / 4] = 0; - used += 4; - } - - i830_unmap_buffer(buf); - } - - if (used) { - do { - if (i < nbox) { - BEGIN_LP_RING(6); - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(sarea_priv-> - BufferState[I830_DESTREG_DR1]); - OUT_RING(box[i].x1 | (box[i].y1 << 16)); - OUT_RING(box[i].x2 | (box[i].y2 << 16)); - OUT_RING(sarea_priv-> - BufferState[I830_DESTREG_DR4]); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - if (dev_priv->use_mi_batchbuffer_start) { - BEGIN_LP_RING(2); - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(start | MI_BATCH_NON_SECURE); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(start | MI_BATCH_NON_SECURE); - OUT_RING(start + used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - } while (++i < nbox); - } - - if (discard) { - dev_priv->counter++; - - (void)cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, - I830_BUF_HARDWARE); - - BEGIN_LP_RING(8); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(buf_priv->my_use_idx); - OUT_RING(I830_BUF_FREE); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - ADVANCE_LP_RING(); - } -} - -static void i830_dma_quiescent(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i830_kernel_lost_context(dev); - - BEGIN_LP_RING(4); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - OUT_RING(0); - ADVANCE_LP_RING(); - - i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); -} - -static int i830_flush_queue(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - int i, ret = 0; - RING_LOCALS; - - i830_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - ADVANCE_LP_RING(); - - i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - - int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, - I830_BUF_FREE); - - if (used == I830_BUF_HARDWARE) - DRM_DEBUG("reclaimed from HARDWARE\n"); - if (used == I830_BUF_CLIENT) - DRM_DEBUG("still on client\n"); - } - - return ret; -} - -/* Must be called with the lock held */ -static void i830_reclaim_buffers(struct drm_device * dev, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - if (!dma) - return; - if (!dev->dev_private) - return; - if (!dma->buflist) - return; - - i830_flush_queue(dev); - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i830_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->file_priv == file_priv && buf_priv) { - int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, - I830_BUF_FREE); - - if (used == I830_BUF_CLIENT) - DRM_DEBUG("reclaimed from client\n"); - if (buf_priv->currently_mapped == I830_BUF_MAPPED) - buf_priv->currently_mapped = I830_BUF_UNMAPPED; - } - } -} - -static int i830_flush_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - LOCK_TEST_WITH_RETURN(dev, file_priv); - - i830_flush_queue(dev); - return 0; -} - -static int i830_dma_vertex(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; - drm_i830_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n", - vertex->idx, vertex->used, vertex->discard); - - if (vertex->idx < 0 || vertex->idx > dma->buf_count) - return -EINVAL; - - i830_dma_dispatch_vertex(dev, - dma->buflist[vertex->idx], - vertex->discard, vertex->used); - - sarea_priv->last_enqueue = dev_priv->counter - 1; - sarea_priv->last_dispatch = (int)hw_status[5]; - - return 0; -} - -static int i830_clear_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_clear_t *clear = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) { - return -EINVAL; - } - - i830_dma_dispatch_clear(dev, clear->flags, - clear->clear_color, - clear->clear_depth, clear->clear_depthmask); - return 0; -} - -static int i830_swap_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - DRM_DEBUG("i830_swap_bufs\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - i830_dma_dispatch_swap(dev); - return 0; -} - -/* Not sure why this isn't set all the time: - */ -static void i830_do_init_pageflip(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("%s\n", __func__); - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; -} - -static int i830_do_cleanup_pageflip(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("%s\n", __func__); - if (dev_priv->current_page != 0) - i830_dma_dispatch_flip(dev); - - dev_priv->page_flipping = 0; - return 0; -} - -static int i830_flip_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("%s\n", __func__); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv->page_flipping) - i830_do_init_pageflip(dev); - - i830_dma_dispatch_flip(dev); - return 0; -} - -static int i830_getage(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; - - sarea_priv->last_dispatch = (int)hw_status[5]; - return 0; -} - -static int i830_getbuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int retcode = 0; - drm_i830_dma_t *d = data; - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) - dev_priv->sarea_priv; - - DRM_DEBUG("getbuf\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - d->granted = 0; - - retcode = i830_dma_get_buffer(dev, d, file_priv); - - DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n", - task_pid_nr(current), retcode, d->granted); - - sarea_priv->last_dispatch = (int)hw_status[5]; - - return retcode; -} - -static int i830_copybuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* Never copy - 2.4.x doesn't need it */ - return 0; -} - -static int i830_docopy(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return 0; -} - -static int i830_getparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_getparam_t *param = data; - int value; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __func__); - return -EINVAL; - } - - switch (param->param) { - case I830_PARAM_IRQ_ACTIVE: - value = dev->irq_enabled; - break; - default: - return -EINVAL; - } - - if (copy_to_user(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -static int i830_setparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_setparam_t *param = data; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __func__); - return -EINVAL; - } - - switch (param->param) { - case I830_SETPARAM_USE_MI_BATCHBUFFER_START: - dev_priv->use_mi_batchbuffer_start = param->value; - break; - default: - return -EINVAL; - } - - return 0; -} - -int i830_driver_load(struct drm_device *dev, unsigned long flags) -{ - /* i830 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - return 0; -} - -void i830_driver_lastclose(struct drm_device * dev) -{ - i830_dma_cleanup(dev); -} - -void i830_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_i830_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { - i830_do_cleanup_pageflip(dev); - } - } -} - -void i830_driver_reclaim_buffers_locked(struct drm_device * dev, struct drm_file *file_priv) -{ - i830_reclaim_buffers(dev, file_priv); -} - -int i830_driver_dma_quiescent(struct drm_device * dev) -{ - i830_dma_quiescent(dev); - return 0; -} - -struct drm_ioctl_desc i830_ioctls[] = { - DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH) -}; - -int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); - -/** - * Determine if the device really is AGP or not. - * - * All Intel graphics chipsets are treated as AGP, even if they are really - * PCI-e. - * - * \param dev The device to be tested. - * - * \returns - * A value of 1 is always retured to indictate every i8xx is AGP. - */ -int i830_driver_device_is_agp(struct drm_device * dev) -{ - return 1; -} diff --git a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h deleted file mode 100644 index 4b00d2d..0000000 --- a/drivers/char/drm/i830_drm.h +++ /dev/null @@ -1,342 +0,0 @@ -#ifndef _I830_DRM_H_ -#define _I830_DRM_H_ - -/* WARNING: These defines must be the same as what the Xserver uses. - * if you change them, you must change the defines in the Xserver. - * - * KW: Actually, you can't ever change them because doing so would - * break backwards compatibility. - */ - -#ifndef _I830_DEFINES_ -#define _I830_DEFINES_ - -#define I830_DMA_BUF_ORDER 12 -#define I830_DMA_BUF_SZ (1< - * Jeff Hartmann - * Gareth Hughes - * Abraham vd Merwe - * Keith Whitwell - */ - -#include "drmP.h" -#include "drm.h" -#include "i830_drm.h" -#include "i830_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - i830_PCI_IDS -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | - DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, -#if USE_IRQS - .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ, -#endif - .dev_priv_size = sizeof(drm_i830_buf_priv_t), - .load = i830_driver_load, - .lastclose = i830_driver_lastclose, - .preclose = i830_driver_preclose, - .device_is_agp = i830_driver_device_is_agp, - .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked, - .dma_quiescent = i830_driver_dma_quiescent, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, -#if USE_IRQS - .irq_preinstall = i830_driver_irq_preinstall, - .irq_postinstall = i830_driver_irq_postinstall, - .irq_uninstall = i830_driver_irq_uninstall, - .irq_handler = i830_driver_irq_handler, -#endif - .ioctls = i830_ioctls, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, - - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init i830_init(void) -{ - driver.num_ioctls = i830_max_ioctl; - return drm_init(&driver); -} - -static void __exit i830_exit(void) -{ - drm_exit(&driver); -} - -module_init(i830_init); -module_exit(i830_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h deleted file mode 100644 index b5bf8cc..0000000 --- a/drivers/char/drm/i830_drv.h +++ /dev/null @@ -1,292 +0,0 @@ -/* i830_drv.h -- Private header for the I830 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Rickard E. (Rik) Faith - * Jeff Hartmann - * - */ - -#ifndef _I830_DRV_H_ -#define _I830_DRV_H_ - -/* General customization: - */ - -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i830" -#define DRIVER_DESC "Intel 830M" -#define DRIVER_DATE "20021108" - -/* Interface history: - * - * 1.1: Original. - * 1.2: ? - * 1.3: New irq emit/wait ioctls. - * New pageflip ioctl. - * New getparam ioctl. - * State for texunits 3&4 in sarea. - * New (alternative) layout for texture state. - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 -#define DRIVER_PATCHLEVEL 2 - -/* Driver will work either way: IRQ's save cpu time when waiting for - * the card, but are subject to subtle interactions between bios, - * hardware and the driver. - */ -/* XXX: Add vblank support? */ -#define USE_IRQS 0 - -typedef struct drm_i830_buf_priv { - u32 *in_use; - int my_use_idx; - int currently_mapped; - void __user *virtual; - void *kernel_virtual; - drm_local_map_t map; -} drm_i830_buf_priv_t; - -typedef struct _drm_i830_ring_buffer { - int tail_mask; - unsigned long Start; - unsigned long End; - unsigned long Size; - u8 *virtual_start; - int head; - int tail; - int space; - drm_local_map_t map; -} drm_i830_ring_buffer_t; - -typedef struct drm_i830_private { - struct drm_map *sarea_map; - struct drm_map *mmio_map; - - drm_i830_sarea_t *sarea_priv; - drm_i830_ring_buffer_t ring; - - void *hw_status_page; - unsigned long counter; - - dma_addr_t dma_status_page; - - struct drm_buf *mmap_buffer; - - u32 front_di1, back_di1, zi1; - - int back_offset; - int depth_offset; - int front_offset; - int w, h; - int pitch; - int back_pitch; - int depth_pitch; - unsigned int cpp; - - int do_boxes; - int dma_used; - - int current_page; - int page_flipping; - - wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; - - int use_mi_batchbuffer_start; - -} drm_i830_private_t; - -extern struct drm_ioctl_desc i830_ioctls[]; -extern int i830_max_ioctl; - -/* i830_irq.c */ -extern int i830_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i830_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); -extern void i830_driver_irq_preinstall(struct drm_device * dev); -extern void i830_driver_irq_postinstall(struct drm_device * dev); -extern void i830_driver_irq_uninstall(struct drm_device * dev); -extern int i830_driver_load(struct drm_device *, unsigned long flags); -extern void i830_driver_preclose(struct drm_device * dev, - struct drm_file *file_priv); -extern void i830_driver_lastclose(struct drm_device * dev); -extern void i830_driver_reclaim_buffers_locked(struct drm_device * dev, - struct drm_file *file_priv); -extern int i830_driver_dma_quiescent(struct drm_device * dev); -extern int i830_driver_device_is_agp(struct drm_device * dev); - -#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) -#define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) -#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) -#define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val) - -#define I830_VERBOSE 0 - -#define RING_LOCALS unsigned int outring, ringmask, outcount; \ - volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (I830_VERBOSE) \ - printk("BEGIN_LP_RING(%d)\n", (n)); \ - if (dev_priv->ring.space < n*4) \ - i830_wait_ring(dev, n*4, __func__); \ - outcount = 0; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define OUT_RING(n) do { \ - if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outcount++; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ - dev_priv->ring.tail = outring; \ - dev_priv->ring.space -= outcount * 4; \ - I830_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -extern int i830_wait_ring(struct drm_device * dev, int n, const char *caller); - -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) -#define CMD_REPORT_HEAD (7<<23) -#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) -#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) - -#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) -#define LOAD_TEXTURE_MAP0 (1<<11) - -#define INST_PARSER_CLIENT 0x00000000 -#define INST_OP_FLUSH 0x02000000 -#define INST_FLUSH_MAP_CACHE 0x00000001 - -#define BB1_START_ADDR_MASK (~0x7) -#define BB1_PROTECTED (1<<0) -#define BB1_UNPROTECTED (0<<0) -#define BB2_END_ADDR_MASK (~0x7) - -#define I830REG_HWSTAM 0x02098 -#define I830REG_INT_IDENTITY_R 0x020a4 -#define I830REG_INT_MASK_R 0x020a8 -#define I830REG_INT_ENABLE_R 0x020a0 - -#define I830_IRQ_RESERVED ((1<<13)|(3<<2)) - -#define LP_RING 0x2030 -#define HP_RING 0x2040 -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x001FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0x0xFFFFF000 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) - -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) - -#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24)) - -#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) - -#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) -#define ASYNC_FLIP (1<<22) - -#define CMD_3D (0x3<<29) -#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) -#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define BUF_3D_ID_COLOR_BACK (0x3<<24) -#define BUF_3D_ID_DEPTH (0x7<<24) -#define BUF_3D_USE_FENCE (1<<23) -#define BUF_3D_PITCH(x) (((x)/4)<<2) - -#define CMD_OP_MAP_PALETTE_LOAD ((3<<29)|(0x1d<<24)|(0x82<<16)|255) -#define MAP_PALETTE_NUM(x) ((x<<8) & (1<<8)) -#define MAP_PALETTE_BOTH (1<<11) - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_BATCH_BUFFER ((0x30<<23)|1) -#define MI_BATCH_BUFFER_START (0x31<<23) -#define MI_BATCH_BUFFER_END (0xA<<23) -#define MI_BATCH_NON_SECURE (1) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) - -#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) - -#endif diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c deleted file mode 100644 index 91ec2bb..0000000 --- a/drivers/char/drm/i830_irq.c +++ /dev/null @@ -1,186 +0,0 @@ -/* i830_dma.c -- DMA support for the I830 -*- linux-c -*- - * - * Copyright 2002 Tungsten Graphics, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Keith Whitwell - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i830_drm.h" -#include "i830_drv.h" -#include /* For task queue support */ -#include - -irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - u16 temp; - - temp = I830_READ16(I830REG_INT_IDENTITY_R); - DRM_DEBUG("%x\n", temp); - - if (!(temp & 2)) - return IRQ_NONE; - - I830_WRITE16(I830REG_INT_IDENTITY_R, temp); - - atomic_inc(&dev_priv->irq_received); - wake_up_interruptible(&dev_priv->irq_queue); - - return IRQ_HANDLED; -} - -static int i830_emit_irq(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - DRM_DEBUG("%s\n", __func__); - - atomic_inc(&dev_priv->irq_emitted); - - BEGIN_LP_RING(2); - OUT_RING(0); - OUT_RING(GFX_OP_USER_INTERRUPT); - ADVANCE_LP_RING(); - - return atomic_read(&dev_priv->irq_emitted); -} - -static int i830_wait_irq(struct drm_device * dev, int irq_nr) -{ - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - DECLARE_WAITQUEUE(entry, current); - unsigned long end = jiffies + HZ * 3; - int ret = 0; - - DRM_DEBUG("%s\n", __func__); - - if (atomic_read(&dev_priv->irq_received) >= irq_nr) - return 0; - - dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; - - add_wait_queue(&dev_priv->irq_queue, &entry); - - for (;;) { - __set_current_state(TASK_INTERRUPTIBLE); - if (atomic_read(&dev_priv->irq_received) >= irq_nr) - break; - if ((signed)(end - jiffies) <= 0) { - DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n", - I830_READ16(I830REG_INT_IDENTITY_R), - I830_READ16(I830REG_INT_MASK_R), - I830_READ16(I830REG_INT_ENABLE_R), - I830_READ16(I830REG_HWSTAM)); - - ret = -EBUSY; /* Lockup? Missed irq? */ - break; - } - schedule_timeout(HZ * 3); - if (signal_pending(current)) { - ret = -EINTR; - break; - } - } - - __set_current_state(TASK_RUNNING); - remove_wait_queue(&dev_priv->irq_queue, &entry); - return ret; -} - -/* Needs the lock as it touches the ring. - */ -int i830_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_irq_emit_t *emit = data; - int result; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __func__); - return -EINVAL; - } - - result = i830_emit_irq(dev); - - if (copy_to_user(emit->irq_seq, &result, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -/* Doesn't need the hardware lock. - */ -int i830_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i830_private_t *dev_priv = dev->dev_private; - drm_i830_irq_wait_t *irqwait = data; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __func__); - return -EINVAL; - } - - return i830_wait_irq(dev, irqwait->irq_seq); -} - -/* drm_dma.h hooks -*/ -void i830_driver_irq_preinstall(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - - I830_WRITE16(I830REG_HWSTAM, 0xffff); - I830_WRITE16(I830REG_INT_MASK_R, 0x0); - I830_WRITE16(I830REG_INT_ENABLE_R, 0x0); - atomic_set(&dev_priv->irq_received, 0); - atomic_set(&dev_priv->irq_emitted, 0); - init_waitqueue_head(&dev_priv->irq_queue); -} - -void i830_driver_irq_postinstall(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - - I830_WRITE16(I830REG_INT_ENABLE_R, 0x2); -} - -void i830_driver_irq_uninstall(struct drm_device * dev) -{ - drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - if (!dev_priv) - return; - - I830_WRITE16(I830REG_INT_MASK_R, 0xffff); - I830_WRITE16(I830REG_INT_ENABLE_R, 0x0); -} diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c deleted file mode 100644 index 8897434..0000000 --- a/drivers/char/drm/i915_dma.c +++ /dev/null @@ -1,858 +0,0 @@ -/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/* Really want an OS-independent resettable timer. Would like to have - * this loop run for (eg) 3 sec, but have the timer reset every time - * the head pointer changes, so that EBUSY only happens if the ring - * actually stalls for (eg) 3 seconds. - */ -int i915_wait_ring(struct drm_device * dev, int n, const char *caller) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_ring_buffer_t *ring = &(dev_priv->ring); - u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - int i; - - for (i = 0; i < 10000; i++) { - ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - if (ring->space >= n) - return 0; - - dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - - if (ring->head != last_head) - i = 0; - - last_head = ring->head; - } - - return -EBUSY; -} - -void i915_kernel_lost_context(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_ring_buffer_t *ring = &(dev_priv->ring); - - ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - - if (ring->head == ring->tail) - dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; -} - -static int i915_dma_cleanup(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq) - drm_irq_uninstall(dev); - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - dev_priv->ring.virtual_start = 0; - dev_priv->ring.map.handle = 0; - dev_priv->ring.map.size = 0; - } - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - I915_WRITE(0x2080, 0x1ffff000); - } - - return 0; -} - -static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - i915_dma_cleanup(dev); - return -EINVAL; - } - - dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio_map) { - i915_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; - } - - dev_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); - - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - - dev_priv->ring.map.offset = init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap(&dev_priv->ring.map, dev); - - if (dev_priv->ring.map.handle == NULL) { - i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - - dev_priv->cpp = init->cpp; - dev_priv->back_offset = init->back_offset; - dev_priv->front_offset = init->front_offset; - dev_priv->current_page = 0; - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; - - /* We are using separate values as placeholders for mechanisms for - * private backbuffer/depthbuffer usage. - */ - dev_priv->use_mi_batchbuffer_start = 0; - if (IS_I965G(dev)) /* 965 doesn't support older method */ - dev_priv->use_mi_batchbuffer_start = 1; - - /* Allow hardware batchbuffers unless told otherwise. - */ - dev_priv->allow_batchbuffer = 1; - - /* Program Hardware Status Page */ - if (!I915_NEED_GFX_HWS(dev)) { - dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); - - if (!dev_priv->status_page_dmah) { - i915_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(0x02080, dev_priv->dma_status_page); - } - DRM_DEBUG("Enabled hardware status page\n"); - return 0; -} - -static int i915_dma_resume(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - DRM_DEBUG("%s\n", __func__); - - if (!dev_priv->sarea) { - DRM_ERROR("can not find sarea!\n"); - return -EINVAL; - } - - if (!dev_priv->mmio_map) { - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; - } - - if (dev_priv->ring.map.handle == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - /* Program Hardware Status Page */ - if (!dev_priv->hw_status_page) { - DRM_ERROR("Can not find hardware status page\n"); - return -EINVAL; - } - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - if (dev_priv->status_gfx_addr != 0) - I915_WRITE(0x02080, dev_priv->status_gfx_addr); - else - I915_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - - return 0; -} - -static int i915_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_init_t *init = data; - int retcode = 0; - - switch (init->func) { - case I915_INIT_DMA: - retcode = i915_initialize(dev, init); - break; - case I915_CLEANUP_DMA: - retcode = i915_dma_cleanup(dev); - break; - case I915_RESUME_DMA: - retcode = i915_dma_resume(dev); - break; - default: - retcode = -EINVAL; - break; - } - - return retcode; -} - -/* Implement basically the same security restrictions as hardware does - * for MI_BATCH_NON_SECURE. These can be made stricter at any time. - * - * Most of the calculations below involve calculating the size of a - * particular instruction. It's important to get the size right as - * that tells us where the next instruction to check is. Any illegal - * instruction detected will be given a size of zero, which is a - * signal to abort the rest of the buffer. - */ -static int do_validate_cmd(int cmd) -{ - switch (((cmd >> 29) & 0x7)) { - case 0x0: - switch ((cmd >> 23) & 0x3f) { - case 0x0: - return 1; /* MI_NOOP */ - case 0x4: - return 1; /* MI_FLUSH */ - default: - return 0; /* disallow everything else */ - } - break; - case 0x1: - return 0; /* reserved */ - case 0x2: - return (cmd & 0xff) + 2; /* 2d commands */ - case 0x3: - if (((cmd >> 24) & 0x1f) <= 0x18) - return 1; - - switch ((cmd >> 24) & 0x1f) { - case 0x1c: - return 1; - case 0x1d: - switch ((cmd >> 16) & 0xff) { - case 0x3: - return (cmd & 0x1f) + 2; - case 0x4: - return (cmd & 0xf) + 2; - default: - return (cmd & 0xffff) + 2; - } - case 0x1e: - if (cmd & (1 << 23)) - return (cmd & 0xffff) + 1; - else - return 1; - case 0x1f: - if ((cmd & (1 << 23)) == 0) /* inline vertices */ - return (cmd & 0x1ffff) + 2; - else if (cmd & (1 << 17)) /* indirect random */ - if ((cmd & 0xffff) == 0) - return 0; /* unknown length, too hard */ - else - return (((cmd & 0xffff) + 1) / 2) + 1; - else - return 2; /* indirect sequential */ - default: - return 0; - } - default: - return 0; - } - - return 0; -} - -static int validate_cmd(int cmd) -{ - int ret = do_validate_cmd(cmd); - -/* printk("validate_cmd( %x ): %d\n", cmd, ret); */ - - return ret; -} - -static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i; - RING_LOCALS; - - if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) - return -EINVAL; - - BEGIN_LP_RING((dwords+1)&~1); - - for (i = 0; i < dwords;) { - int cmd, sz; - - if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) - return -EINVAL; - - if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) - return -EINVAL; - - OUT_RING(cmd); - - while (++i, --sz) { - if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], - sizeof(cmd))) { - return -EINVAL; - } - OUT_RING(cmd); - } - } - - if (dwords & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); - - return 0; -} - -static int i915_emit_box(struct drm_device * dev, - struct drm_clip_rect __user * boxes, - int i, int DR1, int DR4) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_clip_rect box; - RING_LOCALS; - - if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return -EFAULT; - } - - if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { - DRM_ERROR("Bad box %d,%d..%d,%d\n", - box.x1, box.y1, box.x2, box.y2); - return -EINVAL; - } - - if (IS_I965G(dev)) { - BEGIN_LP_RING(4); - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); - OUT_RING(DR4); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(6); - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(DR1); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); - OUT_RING(DR4); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - return 0; -} - -/* XXX: Emitting the counter should really be moved to part of the IRQ - * emit. For now, do it in both places: - */ - -static void i915_emit_breadcrumb(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; - - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; - - BEGIN_LP_RING(4); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); -} - -static int i915_dispatch_cmdbuffer(struct drm_device * dev, - drm_i915_cmdbuffer_t * cmd) -{ - int nbox = cmd->num_cliprects; - int i = 0, count, ret; - - if (cmd->sz & 0x3) { - DRM_ERROR("alignment"); - return -EINVAL; - } - - i915_kernel_lost_context(dev); - - count = nbox ? nbox : 1; - - for (i = 0; i < count; i++) { - if (i < nbox) { - ret = i915_emit_box(dev, cmd->cliprects, i, - cmd->DR1, cmd->DR4); - if (ret) - return ret; - } - - ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4); - if (ret) - return ret; - } - - i915_emit_breadcrumb(dev); - return 0; -} - -static int i915_dispatch_batchbuffer(struct drm_device * dev, - drm_i915_batchbuffer_t * batch) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_clip_rect __user *boxes = batch->cliprects; - int nbox = batch->num_cliprects; - int i = 0, count; - RING_LOCALS; - - if ((batch->start | batch->used) & 0x7) { - DRM_ERROR("alignment"); - return -EINVAL; - } - - i915_kernel_lost_context(dev); - - count = nbox ? nbox : 1; - - for (i = 0; i < count; i++) { - if (i < nbox) { - int ret = i915_emit_box(dev, boxes, i, - batch->DR1, batch->DR4); - if (ret) - return ret; - } - - if (dev_priv->use_mi_batchbuffer_start) { - BEGIN_LP_RING(2); - if (IS_I965G(dev)) { - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); - OUT_RING(batch->start); - } else { - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - } - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - OUT_RING(batch->start + batch->used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - } - } - - i915_emit_breadcrumb(dev); - - return 0; -} - -static int i915_dispatch_flip(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", - __FUNCTION__, - dev_priv->current_page, - dev_priv->sarea_priv->pf_current_page); - - i915_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(6); - OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); - OUT_RING(0); - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_offset); - dev_priv->current_page = 1; - } else { - OUT_RING(dev_priv->front_offset); - dev_priv->current_page = 0; - } - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(2); - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); - OUT_RING(0); - ADVANCE_LP_RING(); - - dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; - - BEGIN_LP_RING(4); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); - - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; - return 0; -} - -static int i915_quiescent(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - i915_kernel_lost_context(dev); - return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); -} - -static int i915_flush_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return i915_quiescent(dev); -} - -static int i915_batchbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) - dev_priv->sarea_priv; - drm_i915_batchbuffer_t *batch = data; - int ret; - - if (!dev_priv->allow_batchbuffer) { - DRM_ERROR("Batchbuffer ioctl disabled\n"); - return -EINVAL; - } - - DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", - batch->start, batch->used, batch->num_cliprects); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, - batch->num_cliprects * - sizeof(struct drm_clip_rect))) - return -EFAULT; - - ret = i915_dispatch_batchbuffer(dev, batch); - - sarea_priv->last_dispatch = (int)hw_status[5]; - return ret; -} - -static int i915_cmdbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) - dev_priv->sarea_priv; - drm_i915_cmdbuffer_t *cmdbuf = data; - int ret; - - DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", - cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (cmdbuf->num_cliprects && - DRM_VERIFYAREA_READ(cmdbuf->cliprects, - cmdbuf->num_cliprects * - sizeof(struct drm_clip_rect))) { - DRM_ERROR("Fault accessing cliprects\n"); - return -EFAULT; - } - - ret = i915_dispatch_cmdbuffer(dev, cmdbuf); - if (ret) { - DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); - return ret; - } - - sarea_priv->last_dispatch = (int)hw_status[5]; - return 0; -} - -static int i915_flip_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - DRM_DEBUG("%s\n", __FUNCTION__); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return i915_dispatch_flip(dev); -} - -static int i915_getparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_getparam_t *param = data; - int value; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - switch (param->param) { - case I915_PARAM_IRQ_ACTIVE: - value = dev->irq ? 1 : 0; - break; - case I915_PARAM_ALLOW_BATCHBUFFER: - value = dev_priv->allow_batchbuffer ? 1 : 0; - break; - case I915_PARAM_LAST_DISPATCH: - value = READ_BREADCRUMB(dev_priv); - break; - default: - DRM_ERROR("Unknown parameter %d\n", param->param); - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return -EFAULT; - } - - return 0; -} - -static int i915_setparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_setparam_t *param = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - switch (param->param) { - case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - if (!IS_I965G(dev)) - dev_priv->use_mi_batchbuffer_start = param->value; - break; - case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: - dev_priv->tex_lru_log_granularity = param->value; - break; - case I915_SETPARAM_ALLOW_BATCHBUFFER: - dev_priv->allow_batchbuffer = param->value; - break; - default: - DRM_ERROR("unknown parameter %d\n", param->param); - return -EINVAL; - } - - return 0; -} - -static int i915_set_status_page(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_hws_addr_t *hws = data; - - if (!I915_NEED_GFX_HWS(dev)) - return -EINVAL; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); - - dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); - - dev_priv->hws_map.offset = dev->agp->base + hws->addr; - dev_priv->hws_map.size = 4*1024; - dev_priv->hws_map.type = 0; - dev_priv->hws_map.flags = 0; - dev_priv->hws_map.mtrr = 0; - - 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; - DRM_ERROR("can not ioremap virtual address for" - " G33 hw status page\n"); - return -ENOMEM; - } - dev_priv->hw_status_page = dev_priv->hws_map.handle; - - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(0x02080, dev_priv->status_gfx_addr); - DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", - dev_priv->status_gfx_addr); - DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); - return 0; -} - -int i915_driver_load(struct drm_device *dev, unsigned long flags) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long base, size; - int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; - - /* i915 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - - memset(dev_priv, 0, sizeof(drm_i915_private_t)); - - dev->dev_private = (void *)dev_priv; - - /* Add register map (needed for suspend/resume) */ - base = drm_get_resource_start(dev, mmio_bar); - size = drm_get_resource_len(dev, mmio_bar); - - ret = drm_addmap(dev, base, size, _DRM_REGISTERS, - _DRM_KERNEL | _DRM_DRIVER, - &dev_priv->mmio_map); - return ret; -} - -int i915_driver_unload(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->mmio_map) - drm_rmmap(dev, dev_priv->mmio_map); - - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - - return 0; -} - -void i915_driver_lastclose(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev_priv) - return; - - if (dev_priv->agp_heap) - i915_mem_takedown(&(dev_priv->agp_heap)); - - i915_dma_cleanup(dev); -} - -void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, file_priv, dev_priv->agp_heap); -} - -struct drm_ioctl_desc i915_ioctls[] = { - DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), - DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), - DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), - DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), -}; - -int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); - -/** - * Determine if the device really is AGP or not. - * - * All Intel graphics chipsets are treated as AGP, even if they are really - * PCI-e. - * - * \param dev The device to be tested. - * - * \returns - * A value of 1 is always retured to indictate every i9x5 is AGP. - */ -int i915_driver_device_is_agp(struct drm_device * dev) -{ - return 1; -} diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h deleted file mode 100644 index 05c66cf..0000000 --- a/drivers/char/drm/i915_drm.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef _I915_DRM_H_ -#define _I915_DRM_H_ - -/* Please note that modifications to all structs defined here are - * subject to backwards-compatibility constraints. - */ - -#include "drm.h" - -/* Each region is a minimum of 16k, and there are at most 255 of them. - */ -#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use - * of chars for next/prev indices */ -#define I915_LOG_MIN_TEX_REGION_SIZE 14 - -typedef struct _drm_i915_init { - enum { - I915_INIT_DMA = 0x01, - I915_CLEANUP_DMA = 0x02, - I915_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drm_i915_init_t; - -typedef struct _drm_i915_sarea { - struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; - - int pipeA_x; - int pipeA_y; - int pipeA_w; - int pipeA_h; - int pipeB_x; - int pipeB_y; - int pipeB_w; - int pipeB_h; -} drm_i915_sarea_t; - -/* Flags for perf_boxes - */ -#define I915_BOX_RING_EMPTY 0x1 -#define I915_BOX_FLIP 0x2 -#define I915_BOX_WAIT 0x4 -#define I915_BOX_TEXTURE_LOAD 0x8 -#define I915_BOX_LOST_CONTEXT 0x10 - -/* I915 specific ioctls - * The device specific ioctl range is 0x40 to 0x79. - */ -#define DRM_I915_INIT 0x00 -#define DRM_I915_FLUSH 0x01 -#define DRM_I915_FLIP 0x02 -#define DRM_I915_BATCHBUFFER 0x03 -#define DRM_I915_IRQ_EMIT 0x04 -#define DRM_I915_IRQ_WAIT 0x05 -#define DRM_I915_GETPARAM 0x06 -#define DRM_I915_SETPARAM 0x07 -#define DRM_I915_ALLOC 0x08 -#define DRM_I915_FREE 0x09 -#define DRM_I915_INIT_HEAP 0x0a -#define DRM_I915_CMDBUFFER 0x0b -#define DRM_I915_DESTROY_HEAP 0x0c -#define DRM_I915_SET_VBLANK_PIPE 0x0d -#define DRM_I915_GET_VBLANK_PIPE 0x0e -#define DRM_I915_VBLANK_SWAP 0x0f -#define DRM_I915_HWS_ADDR 0x11 - -#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) -#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) -#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) -#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) -#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) -#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) -#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t) -#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t) -#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t) -#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) -#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) -#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) -#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) -#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) -#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) -#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) - -/* Allow drivers to submit batchbuffers directly to hardware, relying - * on the security mechanisms provided by hardware. - */ -typedef struct _drm_i915_batchbuffer { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ - int num_cliprects; /* mulitpass with multiple cliprects? */ - struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ -} drm_i915_batchbuffer_t; - -/* As above, but pass a pointer to userspace buffer which can be - * validated by the kernel prior to sending to hardware. - */ -typedef struct _drm_i915_cmdbuffer { - char __user *buf; /* pointer to userspace command buffer */ - int sz; /* nr bytes in buf */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ - int num_cliprects; /* mulitpass with multiple cliprects? */ - struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ -} drm_i915_cmdbuffer_t; - -/* Userspace can request & wait on irq's: - */ -typedef struct drm_i915_irq_emit { - int __user *irq_seq; -} drm_i915_irq_emit_t; - -typedef struct drm_i915_irq_wait { - int irq_seq; -} drm_i915_irq_wait_t; - -/* Ioctl to query kernel params: - */ -#define I915_PARAM_IRQ_ACTIVE 1 -#define I915_PARAM_ALLOW_BATCHBUFFER 2 -#define I915_PARAM_LAST_DISPATCH 3 - -typedef struct drm_i915_getparam { - int param; - int __user *value; -} drm_i915_getparam_t; - -/* Ioctl to set kernel params: - */ -#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I915_SETPARAM_ALLOW_BATCHBUFFER 3 - -typedef struct drm_i915_setparam { - int param; - int value; -} drm_i915_setparam_t; - -/* A memory manager for regions of shared memory: - */ -#define I915_MEM_REGION_AGP 1 - -typedef struct drm_i915_mem_alloc { - int region; - int alignment; - int size; - int __user *region_offset; /* offset from start of fb or agp */ -} drm_i915_mem_alloc_t; - -typedef struct drm_i915_mem_free { - int region; - int region_offset; -} drm_i915_mem_free_t; - -typedef struct drm_i915_mem_init_heap { - int region; - int size; - int start; -} drm_i915_mem_init_heap_t; - -/* Allow memory manager to be torn down and re-initialized (eg on - * rotate): - */ -typedef struct drm_i915_mem_destroy_heap { - int region; -} drm_i915_mem_destroy_heap_t; - -/* Allow X server to configure which pipes to monitor for vblank signals - */ -#define DRM_I915_VBLANK_PIPE_A 1 -#define DRM_I915_VBLANK_PIPE_B 2 - -typedef struct drm_i915_vblank_pipe { - int pipe; -} drm_i915_vblank_pipe_t; - -/* Schedule buffer swap at given vertical blank: - */ -typedef struct drm_i915_vblank_swap { - drm_drawable_t drawable; - enum drm_vblank_seq_type seqtype; - unsigned int sequence; -} drm_i915_vblank_swap_t; - -typedef struct drm_i915_hws_addr { - uint64_t addr; -} drm_i915_hws_addr_t; - -#endif /* _I915_DRM_H_ */ diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c deleted file mode 100644 index 93aed1c..0000000 --- a/drivers/char/drm/i915_drv.c +++ /dev/null @@ -1,605 +0,0 @@ -/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- - */ -/* - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - i915_PCI_IDS -}; - -enum pipe { - PIPE_A = 0, - PIPE_B, -}; - -static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (pipe == PIPE_A) - return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); - else - return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); -} - -static void i915_save_palette(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); - u32 *array; - int i; - - if (!i915_pipe_enabled(dev, pipe)) - return; - - if (pipe == PIPE_A) - array = dev_priv->save_palette_a; - else - array = dev_priv->save_palette_b; - - for(i = 0; i < 256; i++) - array[i] = I915_READ(reg + (i << 2)); -} - -static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); - u32 *array; - int i; - - if (!i915_pipe_enabled(dev, pipe)) - return; - - if (pipe == PIPE_A) - array = dev_priv->save_palette_a; - else - array = dev_priv->save_palette_b; - - for(i = 0; i < 256; i++) - I915_WRITE(reg + (i << 2), array[i]); -} - -static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg) -{ - outb(reg, index_port); - return inb(data_port); -} - -static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable) -{ - inb(st01); - outb(palette_enable | reg, VGA_AR_INDEX); - return inb(VGA_AR_DATA_READ); -} - -static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable) -{ - inb(st01); - outb(palette_enable | reg, VGA_AR_INDEX); - outb(val, VGA_AR_DATA_WRITE); -} - -static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val) -{ - outb(reg, index_port); - outb(val, data_port); -} - -static void i915_save_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - u16 cr_index, cr_data, st01; - - /* VGA color palette registers */ - dev_priv->saveDACMASK = inb(VGA_DACMASK); - /* DACCRX automatically increments during read */ - outb(0, VGA_DACRX); - /* Read 3 bytes of color data from each index */ - for (i = 0; i < 256 * 3; i++) - dev_priv->saveDACDATA[i] = inb(VGA_DACDATA); - - /* MSR bits */ - dev_priv->saveMSR = inb(VGA_MSR_READ); - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { - cr_index = VGA_CR_INDEX_CGA; - cr_data = VGA_CR_DATA_CGA; - st01 = VGA_ST01_CGA; - } else { - cr_index = VGA_CR_INDEX_MDA; - cr_data = VGA_CR_DATA_MDA; - st01 = VGA_ST01_MDA; - } - - /* CRT controller regs */ - i915_write_indexed(cr_index, cr_data, 0x11, - i915_read_indexed(cr_index, cr_data, 0x11) & - (~0x80)); - for (i = 0; i <= 0x24; i++) - dev_priv->saveCR[i] = - i915_read_indexed(cr_index, cr_data, i); - /* Make sure we don't turn off CR group 0 writes */ - dev_priv->saveCR[0x11] &= ~0x80; - - /* Attribute controller registers */ - inb(st01); - dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); - for (i = 0; i <= 0x14; i++) - dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); - inb(st01); - outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); - inb(st01); - - /* Graphics controller registers */ - for (i = 0; i < 9; i++) - dev_priv->saveGR[i] = - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i); - - dev_priv->saveGR[0x10] = - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10); - dev_priv->saveGR[0x11] = - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11); - dev_priv->saveGR[0x18] = - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18); - - /* Sequencer registers */ - for (i = 0; i < 8; i++) - dev_priv->saveSR[i] = - i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i); -} - -static void i915_restore_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - u16 cr_index, cr_data, st01; - - /* MSR bits */ - outb(dev_priv->saveMSR, VGA_MSR_WRITE); - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { - cr_index = VGA_CR_INDEX_CGA; - cr_data = VGA_CR_DATA_CGA; - st01 = VGA_ST01_CGA; - } else { - cr_index = VGA_CR_INDEX_MDA; - cr_data = VGA_CR_DATA_MDA; - st01 = VGA_ST01_MDA; - } - - /* Sequencer registers, don't write SR07 */ - for (i = 0; i < 7; i++) - i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i, - dev_priv->saveSR[i]); - - /* CRT controller regs */ - /* Enable CR group 0 writes */ - i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); - for (i = 0; i <= 0x24; i++) - i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); - - /* Graphics controller regs */ - for (i = 0; i < 9; i++) - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i, - dev_priv->saveGR[i]); - - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10, - dev_priv->saveGR[0x10]); - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11, - dev_priv->saveGR[0x11]); - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18, - dev_priv->saveGR[0x18]); - - /* Attribute controller registers */ - inb(st01); - for (i = 0; i <= 0x14; i++) - i915_write_ar(st01, i, dev_priv->saveAR[i], 0); - inb(st01); /* switch back to index mode */ - outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); - inb(st01); - - /* VGA color palette registers */ - outb(dev_priv->saveDACMASK, VGA_DACMASK); - /* DACCRX automatically increments during read */ - outb(0, VGA_DACWX); - /* Read 3 bytes of color data from each index */ - for (i = 0; i < 256 * 3; i++) - outb(dev_priv->saveDACDATA[i], VGA_DACDATA); - -} - -static int i915_suspend(struct drm_device *dev, pm_message_t state) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - if (!dev || !dev_priv) { - printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); - printk(KERN_ERR "DRM not initialized, aborting suspend.\n"); - return -ENODEV; - } - - if (state.event == PM_EVENT_PRETHAW) - return 0; - - pci_save_state(dev->pdev); - pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); - - /* Display arbitration control */ - dev_priv->saveDSPARB = I915_READ(DSPARB); - - /* Pipe & plane A info */ - dev_priv->savePIPEACONF = I915_READ(PIPEACONF); - dev_priv->savePIPEASRC = I915_READ(PIPEASRC); - dev_priv->saveFPA0 = I915_READ(FPA0); - dev_priv->saveFPA1 = I915_READ(FPA1); - dev_priv->saveDPLL_A = I915_READ(DPLL_A); - if (IS_I965G(dev)) - dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); - dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); - dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); - dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); - dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); - dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); - dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); - - dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); - dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); - dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); - dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); - dev_priv->saveDSPABASE = I915_READ(DSPABASE); - if (IS_I965G(dev)) { - dev_priv->saveDSPASURF = I915_READ(DSPASURF); - dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); - } - i915_save_palette(dev, PIPE_A); - dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); - - /* Pipe & plane B info */ - dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); - dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); - dev_priv->saveFPB0 = I915_READ(FPB0); - dev_priv->saveFPB1 = I915_READ(FPB1); - dev_priv->saveDPLL_B = I915_READ(DPLL_B); - if (IS_I965G(dev)) - dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); - dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); - dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); - dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); - dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); - dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); - dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); - - dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); - dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); - dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); - dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); - dev_priv->saveDSPBBASE = I915_READ(DSPBBASE); - if (IS_I965GM(dev) || IS_IGD_GM(dev)) { - dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); - dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); - } - i915_save_palette(dev, PIPE_B); - dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); - - /* CRT state */ - dev_priv->saveADPA = I915_READ(ADPA); - - /* LVDS state */ - dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); - if (IS_I965G(dev)) - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); - if (IS_MOBILE(dev) && !IS_I830(dev)) - dev_priv->saveLVDS = I915_READ(LVDS); - if (!IS_I830(dev) && !IS_845G(dev)) - dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); - dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON); - dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF); - dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); - - /* FIXME: save TV & SDVO state */ - - /* FBC state */ - dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); - dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); - dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); - dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); - - /* Interrupt state */ - dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); - dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); - dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); - - /* VGA state */ - dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); - dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); - dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); - dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); - - /* Clock gating state */ - dev_priv->saveD_STATE = I915_READ(D_STATE); - dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); - - /* Cache mode state */ - dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); - - /* Memory Arbitration state */ - dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); - - /* Scratch space */ - for (i = 0; i < 16; i++) { - dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); - dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); - } - for (i = 0; i < 3; i++) - dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); - - i915_save_vga(dev); - - if (state.event == PM_EVENT_SUSPEND) { - /* Shut down the device */ - pci_disable_device(dev->pdev); - pci_set_power_state(dev->pdev, PCI_D3hot); - } - - return 0; -} - -static int i915_resume(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - pci_set_power_state(dev->pdev, PCI_D0); - pci_restore_state(dev->pdev); - if (pci_enable_device(dev->pdev)) - return -1; - pci_set_master(dev->pdev); - - pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); - - I915_WRITE(DSPARB, dev_priv->saveDSPARB); - - /* Pipe & plane A info */ - /* Prime the clock */ - if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { - I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & - ~DPLL_VCO_ENABLE); - udelay(150); - } - I915_WRITE(FPA0, dev_priv->saveFPA0); - I915_WRITE(FPA1, dev_priv->saveFPA1); - /* Actually enable it */ - I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); - udelay(150); - if (IS_I965G(dev)) - I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); - udelay(150); - - /* Restore mode */ - I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); - I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); - I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); - I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); - I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); - I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); - I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); - - /* Restore plane info */ - I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); - I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); - I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); - I915_WRITE(DSPABASE, dev_priv->saveDSPABASE); - I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); - if (IS_I965G(dev)) { - I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); - I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); - } - - I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); - - i915_restore_palette(dev, PIPE_A); - /* Enable the plane */ - I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); - I915_WRITE(DSPABASE, I915_READ(DSPABASE)); - - /* Pipe & plane B info */ - if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { - I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & - ~DPLL_VCO_ENABLE); - udelay(150); - } - I915_WRITE(FPB0, dev_priv->saveFPB0); - I915_WRITE(FPB1, dev_priv->saveFPB1); - /* Actually enable it */ - I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); - udelay(150); - if (IS_I965G(dev)) - I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); - udelay(150); - - /* Restore mode */ - I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); - I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); - I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); - I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); - I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); - I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); - I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); - - /* Restore plane info */ - I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); - I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); - I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); - I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE); - I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); - if (IS_I965G(dev)) { - I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); - I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); - } - - I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); - - i915_restore_palette(dev, PIPE_B); - /* Enable the plane */ - I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); - I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); - - /* CRT state */ - I915_WRITE(ADPA, dev_priv->saveADPA); - - /* LVDS state */ - if (IS_I965G(dev)) - I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); - if (IS_MOBILE(dev) && !IS_I830(dev)) - I915_WRITE(LVDS, dev_priv->saveLVDS); - if (!IS_I830(dev) && !IS_845G(dev)) - I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); - - I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); - I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON); - I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF); - I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); - I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - - /* FIXME: restore TV & SDVO state */ - - /* FBC info */ - I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); - I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); - I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); - I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); - - /* VGA state */ - I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); - I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0); - I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1); - I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); - udelay(150); - - /* Clock gating state */ - I915_WRITE (D_STATE, dev_priv->saveD_STATE); - I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); - - /* Cache mode state */ - I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); - - /* Memory arbitration state */ - I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); - - for (i = 0; i < 16; i++) { - I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); - I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); - } - for (i = 0; i < 3; i++) - I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); - - i915_restore_vga(dev); - - return 0; -} - -static struct drm_driver driver = { - /* don't use mtrr's here, the Xserver or user space app should - * deal with them for intel hardware. - */ - .driver_features = - DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | - DRIVER_IRQ_VBL2, - .load = i915_driver_load, - .unload = i915_driver_unload, - .lastclose = i915_driver_lastclose, - .preclose = i915_driver_preclose, - .suspend = i915_suspend, - .resume = i915_resume, - .device_is_agp = i915_driver_device_is_agp, - .vblank_wait = i915_driver_vblank_wait, - .vblank_wait2 = i915_driver_vblank_wait2, - .irq_preinstall = i915_driver_irq_preinstall, - .irq_postinstall = i915_driver_irq_postinstall, - .irq_uninstall = i915_driver_irq_uninstall, - .irq_handler = i915_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = i915_ioctls, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = i915_compat_ioctl, -#endif - }, - - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init i915_init(void) -{ - driver.num_ioctls = i915_max_ioctl; - return drm_init(&driver); -} - -static void __exit i915_exit(void) -{ - drm_exit(&driver); -} - -module_init(i915_init); -module_exit(i915_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h deleted file mode 100644 index d7326d9..0000000 --- a/drivers/char/drm/i915_drv.h +++ /dev/null @@ -1,1142 +0,0 @@ -/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- - */ -/* - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef _I915_DRV_H_ -#define _I915_DRV_H_ - -/* General customization: - */ - -#define DRIVER_AUTHOR "Tungsten Graphics, Inc." - -#define DRIVER_NAME "i915" -#define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20060119" - -/* Interface history: - * - * 1.1: Original. - * 1.2: Add Power Management - * 1.3: Add vblank support - * 1.4: Fix cmdbuffer path, add heap destroy - * 1.5: Add vblank pipe configuration - * 1.6: - New ioctl for scheduling buffer swaps on vertical blank - * - Support vertical blank on secondary display pipe - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 6 -#define DRIVER_PATCHLEVEL 0 - -typedef struct _drm_i915_ring_buffer { - int tail_mask; - unsigned long Start; - unsigned long End; - unsigned long Size; - u8 *virtual_start; - int head; - int tail; - int space; - drm_local_map_t map; -} drm_i915_ring_buffer_t; - -struct mem_block { - struct mem_block *next; - struct mem_block *prev; - int start; - int size; - struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ -}; - -typedef struct _drm_i915_vbl_swap { - struct list_head head; - drm_drawable_t drw_id; - unsigned int pipe; - unsigned int sequence; -} drm_i915_vbl_swap_t; - -typedef struct drm_i915_private { - drm_local_map_t *sarea; - drm_local_map_t *mmio_map; - - drm_i915_sarea_t *sarea_priv; - drm_i915_ring_buffer_t ring; - - drm_dma_handle_t *status_page_dmah; - void *hw_status_page; - dma_addr_t dma_status_page; - unsigned long counter; - unsigned int status_gfx_addr; - drm_local_map_t hws_map; - - unsigned int cpp; - int back_offset; - int front_offset; - int current_page; - int page_flipping; - int use_mi_batchbuffer_start; - - wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; - - int tex_lru_log_granularity; - int allow_batchbuffer; - struct mem_block *agp_heap; - unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; - int vblank_pipe; - - spinlock_t swaps_lock; - drm_i915_vbl_swap_t vbl_swaps; - unsigned int swaps_pending; - - /* Register state */ - u8 saveLBB; - u32 saveDSPACNTR; - u32 saveDSPBCNTR; - u32 saveDSPARB; - u32 savePIPEACONF; - u32 savePIPEBCONF; - u32 savePIPEASRC; - u32 savePIPEBSRC; - u32 saveFPA0; - u32 saveFPA1; - u32 saveDPLL_A; - u32 saveDPLL_A_MD; - u32 saveHTOTAL_A; - u32 saveHBLANK_A; - u32 saveHSYNC_A; - u32 saveVTOTAL_A; - u32 saveVBLANK_A; - u32 saveVSYNC_A; - u32 saveBCLRPAT_A; - u32 savePIPEASTAT; - u32 saveDSPASTRIDE; - u32 saveDSPASIZE; - u32 saveDSPAPOS; - u32 saveDSPABASE; - u32 saveDSPASURF; - u32 saveDSPATILEOFF; - u32 savePFIT_PGM_RATIOS; - u32 saveBLC_PWM_CTL; - u32 saveBLC_PWM_CTL2; - u32 saveFPB0; - u32 saveFPB1; - u32 saveDPLL_B; - u32 saveDPLL_B_MD; - u32 saveHTOTAL_B; - u32 saveHBLANK_B; - u32 saveHSYNC_B; - u32 saveVTOTAL_B; - u32 saveVBLANK_B; - u32 saveVSYNC_B; - u32 saveBCLRPAT_B; - u32 savePIPEBSTAT; - u32 saveDSPBSTRIDE; - u32 saveDSPBSIZE; - u32 saveDSPBPOS; - u32 saveDSPBBASE; - u32 saveDSPBSURF; - u32 saveDSPBTILEOFF; - u32 saveVCLK_DIVISOR_VGA0; - u32 saveVCLK_DIVISOR_VGA1; - u32 saveVCLK_POST_DIV; - u32 saveVGACNTRL; - u32 saveADPA; - u32 saveLVDS; - u32 saveLVDSPP_ON; - u32 saveLVDSPP_OFF; - u32 saveDVOA; - u32 saveDVOB; - u32 saveDVOC; - u32 savePP_ON; - u32 savePP_OFF; - u32 savePP_CONTROL; - u32 savePP_CYCLE; - u32 savePFIT_CONTROL; - u32 save_palette_a[256]; - u32 save_palette_b[256]; - u32 saveFBC_CFB_BASE; - u32 saveFBC_LL_BASE; - u32 saveFBC_CONTROL; - u32 saveFBC_CONTROL2; - u32 saveIER; - u32 saveIIR; - u32 saveIMR; - u32 saveCACHE_MODE_0; - u32 saveD_STATE; - u32 saveDSPCLK_GATE_D; - u32 saveMI_ARB_STATE; - u32 saveSWF0[16]; - u32 saveSWF1[16]; - u32 saveSWF2[3]; - u8 saveMSR; - u8 saveSR[8]; - u8 saveGR[25]; - u8 saveAR_INDEX; - u8 saveAR[21]; - u8 saveDACMASK; - u8 saveDACDATA[256*3]; /* 256 3-byte colors */ - u8 saveCR[37]; -} drm_i915_private_t; - -extern struct drm_ioctl_desc i915_ioctls[]; -extern int i915_max_ioctl; - - /* i915_dma.c */ -extern void i915_kernel_lost_context(struct drm_device * dev); -extern int i915_driver_load(struct drm_device *, unsigned long flags); -extern int i915_driver_unload(struct drm_device *); -extern void i915_driver_lastclose(struct drm_device * dev); -extern void i915_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv); -extern int i915_driver_device_is_agp(struct drm_device * dev); -extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -/* i915_irq.c */ -extern int i915_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); -extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); -extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); -extern void i915_driver_irq_preinstall(struct drm_device * dev); -extern void i915_driver_irq_postinstall(struct drm_device * dev); -extern void i915_driver_irq_uninstall(struct drm_device * dev); -extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_vblank_swap(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* i915_mem.c */ -extern int i915_mem_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_free(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_init_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern void i915_mem_takedown(struct mem_block **heap); -extern void i915_mem_release(struct drm_device * dev, - struct drm_file *file_priv, struct mem_block *heap); - -#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg)) -#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val)) -#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg)) -#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) - -#define I915_VERBOSE 0 - -#define RING_LOCALS unsigned int outring, ringmask, outcount; \ - volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (I915_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ - if (dev_priv->ring.space < (n)*4) \ - i915_wait_ring(dev, (n)*4, __func__); \ - outcount = 0; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define OUT_RING(n) do { \ - if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = (n); \ - outcount++; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ - dev_priv->ring.tail = outring; \ - dev_priv->ring.space -= outcount * 4; \ - I915_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); - -/* Extended config space */ -#define LBB 0xf4 - -/* VGA stuff */ - -#define VGA_ST01_MDA 0x3ba -#define VGA_ST01_CGA 0x3da - -#define VGA_MSR_WRITE 0x3c2 -#define VGA_MSR_READ 0x3cc -#define VGA_MSR_MEM_EN (1<<1) -#define VGA_MSR_CGA_MODE (1<<0) - -#define VGA_SR_INDEX 0x3c4 -#define VGA_SR_DATA 0x3c5 - -#define VGA_AR_INDEX 0x3c0 -#define VGA_AR_VID_EN (1<<5) -#define VGA_AR_DATA_WRITE 0x3c0 -#define VGA_AR_DATA_READ 0x3c1 - -#define VGA_GR_INDEX 0x3ce -#define VGA_GR_DATA 0x3cf -/* GR05 */ -#define VGA_GR_MEM_READ_MODE_SHIFT 3 -#define VGA_GR_MEM_READ_MODE_PLANE 1 -/* GR06 */ -#define VGA_GR_MEM_MODE_MASK 0xc -#define VGA_GR_MEM_MODE_SHIFT 2 -#define VGA_GR_MEM_A0000_AFFFF 0 -#define VGA_GR_MEM_A0000_BFFFF 1 -#define VGA_GR_MEM_B0000_B7FFF 2 -#define VGA_GR_MEM_B0000_BFFFF 3 - -#define VGA_DACMASK 0x3c6 -#define VGA_DACRX 0x3c7 -#define VGA_DACWX 0x3c8 -#define VGA_DACDATA 0x3c9 - -#define VGA_CR_INDEX_MDA 0x3b4 -#define VGA_CR_DATA_MDA 0x3b5 -#define VGA_CR_INDEX_CGA 0x3d4 -#define VGA_CR_DATA_CGA 0x3d5 - -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) -#define CMD_REPORT_HEAD (7<<23) -#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) -#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) - -#define INST_PARSER_CLIENT 0x00000000 -#define INST_OP_FLUSH 0x02000000 -#define INST_FLUSH_MAP_CACHE 0x00000001 - -#define BB1_START_ADDR_MASK (~0x7) -#define BB1_PROTECTED (1<<0) -#define BB1_UNPROTECTED (0<<0) -#define BB2_END_ADDR_MASK (~0x7) - -/* Framebuffer compression */ -#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ -#define FBC_LL_BASE 0x03204 /* 4k page aligned */ -#define FBC_CONTROL 0x03208 -#define FBC_CTL_EN (1<<31) -#define FBC_CTL_PERIODIC (1<<30) -#define FBC_CTL_INTERVAL_SHIFT (16) -#define FBC_CTL_UNCOMPRESSIBLE (1<<14) -#define FBC_CTL_STRIDE_SHIFT (5) -#define FBC_CTL_FENCENO (1<<0) -#define FBC_COMMAND 0x0320c -#define FBC_CMD_COMPRESS (1<<0) -#define FBC_STATUS 0x03210 -#define FBC_STAT_COMPRESSING (1<<31) -#define FBC_STAT_COMPRESSED (1<<30) -#define FBC_STAT_MODIFIED (1<<29) -#define FBC_STAT_CURRENT_LINE (1<<0) -#define FBC_CONTROL2 0x03214 -#define FBC_CTL_FENCE_DBL (0<<4) -#define FBC_CTL_IDLE_IMM (0<<2) -#define FBC_CTL_IDLE_FULL (1<<2) -#define FBC_CTL_IDLE_LINE (2<<2) -#define FBC_CTL_IDLE_DEBUG (3<<2) -#define FBC_CTL_CPU_FENCE (1<<1) -#define FBC_CTL_PLANEA (0<<0) -#define FBC_CTL_PLANEB (1<<0) -#define FBC_FENCE_OFF 0x0321b - -#define FBC_LL_SIZE (1536) -#define FBC_LL_PAD (32) - -/* Interrupt bits: - */ -#define USER_INT_FLAG (1<<1) -#define VSYNC_PIPEB_FLAG (1<<5) -#define VSYNC_PIPEA_FLAG (1<<7) -#define HWB_OOM_FLAG (1<<13) /* binner out of memory */ - -#define I915REG_HWSTAM 0x02098 -#define I915REG_INT_IDENTITY_R 0x020a4 -#define I915REG_INT_MASK_R 0x020a8 -#define I915REG_INT_ENABLE_R 0x020a0 - -#define I915REG_PIPEASTAT 0x70024 -#define I915REG_PIPEBSTAT 0x71024 - -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_VBLANK_CLEAR (1UL<<1) - -#define SRX_INDEX 0x3c4 -#define SRX_DATA 0x3c5 -#define SR01 1 -#define SR01_SCREEN_OFF (1<<5) - -#define PPCR 0x61204 -#define PPCR_ON (1<<0) - -#define DVOB 0x61140 -#define DVOB_ON (1<<31) -#define DVOC 0x61160 -#define DVOC_ON (1<<31) -#define LVDS 0x61180 -#define LVDS_ON (1<<31) - -#define ADPA 0x61100 -#define ADPA_DPMS_MASK (~(3<<10)) -#define ADPA_DPMS_ON (0<<10) -#define ADPA_DPMS_SUSPEND (1<<10) -#define ADPA_DPMS_STANDBY (2<<10) -#define ADPA_DPMS_OFF (3<<10) - -#define NOPID 0x2094 -#define LP_RING 0x2030 -#define HP_RING 0x2040 -/* The binner has its own ring buffer: - */ -#define HWB_RING 0x2400 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x001FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0x0xFFFFF000 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -/* Instruction parser error reg: - */ -#define IPEIR 0x2088 - -/* Scratch pad debug 0 reg: - */ -#define SCPD0 0x209c - -/* Error status reg: - */ -#define ESR 0x20b8 - -/* Secondary DMA fetch address debug reg: - */ -#define DMA_FADD_S 0x20d4 - -/* Memory Interface Arbitration State - */ -#define MI_ARB_STATE 0x20e4 - -/* Cache mode 0 reg. - * - Manipulating render cache behaviour is central - * to the concept of zone rendering, tuning this reg can help avoid - * unnecessary render cache reads and even writes (for z/stencil) - * at beginning and end of scene. - * - * - To change a bit, write to this reg with a mask bit set and the - * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. - */ -#define Cache_Mode_0 0x2120 -#define CACHE_MODE_0 0x2120 -#define CM0_MASK_SHIFT 16 -#define CM0_IZ_OPT_DISABLE (1<<6) -#define CM0_ZR_OPT_DISABLE (1<<5) -#define CM0_DEPTH_EVICT_DISABLE (1<<4) -#define CM0_COLOR_EVICT_DISABLE (1<<3) -#define CM0_DEPTH_WRITE_DISABLE (1<<1) -#define CM0_RC_OP_FLUSH_DISABLE (1<<0) - - -/* Graphics flush control. A CPU write flushes the GWB of all writes. - * The data is discarded. - */ -#define GFX_FLSH_CNTL 0x2170 - -/* Binner control. Defines the location of the bin pointer list: - */ -#define BINCTL 0x2420 -#define BC_MASK (1 << 9) - -/* Binned scene info. - */ -#define BINSCENE 0x2428 -#define BS_OP_LOAD (1 << 8) -#define BS_MASK (1 << 22) - -/* Bin command parser debug reg: - */ -#define BCPD 0x2480 - -/* Bin memory control debug reg: - */ -#define BMCD 0x2484 - -/* Bin data cache debug reg: - */ -#define BDCD 0x2488 - -/* Binner pointer cache debug reg: - */ -#define BPCD 0x248c - -/* Binner scratch pad debug reg: - */ -#define BINSKPD 0x24f0 - -/* HWB scratch pad debug reg: - */ -#define HWBSKPD 0x24f4 - -/* Binner memory pool reg: - */ -#define BMP_BUFFER 0x2430 -#define BMP_PAGE_SIZE_4K (0 << 10) -#define BMP_BUFFER_SIZE_SHIFT 1 -#define BMP_ENABLE (1 << 0) - -/* Get/put memory from the binner memory pool: - */ -#define BMP_GET 0x2438 -#define BMP_PUT 0x2440 -#define BMP_OFFSET_SHIFT 5 - -/* 3D state packets: - */ -#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) - -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) - -#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) - -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) - -#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) - -#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) - -#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) -#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) -#define XY_SRC_COPY_BLT_DST_TILED (1<<11) - -#define MI_BATCH_BUFFER ((0x30<<23)|1) -#define MI_BATCH_BUFFER_START (0x31<<23) -#define MI_BATCH_BUFFER_END (0xA<<23) -#define MI_BATCH_NON_SECURE (1) -#define MI_BATCH_NON_SECURE_I965 (1<<8) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) - -#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23)) - -#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) -#define ASYNC_FLIP (1<<22) -#define DISPLAY_PLANE_A (0<<20) -#define DISPLAY_PLANE_B (1<<20) - -/* Display regs */ -#define DSPACNTR 0x70180 -#define DSPBCNTR 0x71180 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) - -/* Define the region of interest for the binner: - */ -#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4) - -#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) - -#define CMD_MI_FLUSH (0x04 << 23) -#define MI_NO_WRITE_FLUSH (1 << 2) -#define MI_READ_FLUSH (1 << 0) -#define MI_EXE_FLUSH (1 << 1) -#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ -#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ - -#define BREADCRUMB_BITS 31 -#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) - -#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) -#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) - -#define BLC_PWM_CTL 0x61254 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) - -#define BLC_PWM_CTL2 0x61250 -/** - * This is the most significant 15 bits of the number of backlight cycles in a - * complete cycle of the modulated backlight control. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) -/** - * This is the number of cycles out of the backlight modulation cycle for which - * the backlight is on. - * - * This field must be no greater than the number of cycles in the complete - * backlight modulation cycle. - */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) - -#define I915_GCFGC 0xf0 -#define I915_LOW_FREQUENCY_ENABLE (1 << 7) -#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define I915_DISPLAY_CLOCK_MASK (7 << 4) - -#define I855_HPLLCC 0xc0 -#define I855_CLOCK_CONTROL_MASK (3 << 0) -#define I855_CLOCK_133_200 (0 << 0) -#define I855_CLOCK_100_200 (1 << 0) -#define I855_CLOCK_100_133 (2 << 0) -#define I855_CLOCK_166_250 (3 << 0) - -/* p317, 319 - */ -#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ -#define VCLK2_VCO_N 0x600a -#define VCLK2_VCO_DIV_SEL 0x6012 - -#define VCLK_DIVISOR_VGA0 0x6000 -#define VCLK_DIVISOR_VGA1 0x6004 -#define VCLK_POST_DIV 0x6010 -/** Selects a post divisor of 4 instead of 2. */ -# define VGA1_PD_P2_DIV_4 (1 << 15) -/** Overrides the p2 post divisor field */ -# define VGA1_PD_P1_DIV_2 (1 << 13) -# define VGA1_PD_P1_SHIFT 8 -/** P1 value is 2 greater than this field */ -# define VGA1_PD_P1_MASK (0x1f << 8) -/** Selects a post divisor of 4 instead of 2. */ -# define VGA0_PD_P2_DIV_4 (1 << 7) -/** Overrides the p2 post divisor field */ -# define VGA0_PD_P1_DIV_2 (1 << 5) -# define VGA0_PD_P1_SHIFT 0 -/** P1 value is 2 greater than this field */ -# define VGA0_PD_P1_MASK (0x1f << 0) - -/* PCI D state control register */ -#define D_STATE 0x6104 -#define DSPCLK_GATE_D 0x6200 - -/* I830 CRTC registers */ -#define HTOTAL_A 0x60000 -#define HBLANK_A 0x60004 -#define HSYNC_A 0x60008 -#define VTOTAL_A 0x6000c -#define VBLANK_A 0x60010 -#define VSYNC_A 0x60014 -#define PIPEASRC 0x6001c -#define BCLRPAT_A 0x60020 -#define VSYNCSHIFT_A 0x60028 - -#define HTOTAL_B 0x61000 -#define HBLANK_B 0x61004 -#define HSYNC_B 0x61008 -#define VTOTAL_B 0x6100c -#define VBLANK_B 0x61010 -#define VSYNC_B 0x61014 -#define PIPEBSRC 0x6101c -#define BCLRPAT_B 0x61020 -#define VSYNCSHIFT_B 0x61028 - -#define PP_STATUS 0x61200 -# define PP_ON (1 << 31) -/** - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -# define PP_READY (1 << 30) -# define PP_SEQUENCE_NONE (0 << 28) -# define PP_SEQUENCE_ON (1 << 28) -# define PP_SEQUENCE_OFF (2 << 28) -# define PP_SEQUENCE_MASK 0x30000000 -#define PP_CONTROL 0x61204 -# define POWER_TARGET_ON (1 << 0) - -#define LVDSPP_ON 0x61208 -#define LVDSPP_OFF 0x6120c -#define PP_CYCLE 0x61210 - -#define PFIT_CONTROL 0x61230 -# define PFIT_ENABLE (1 << 31) -# define PFIT_PIPE_MASK (3 << 29) -# define PFIT_PIPE_SHIFT 29 -# define VERT_INTERP_DISABLE (0 << 10) -# define VERT_INTERP_BILINEAR (1 << 10) -# define VERT_INTERP_MASK (3 << 10) -# define VERT_AUTO_SCALE (1 << 9) -# define HORIZ_INTERP_DISABLE (0 << 6) -# define HORIZ_INTERP_BILINEAR (1 << 6) -# define HORIZ_INTERP_MASK (3 << 6) -# define HORIZ_AUTO_SCALE (1 << 5) -# define PANEL_8TO6_DITHER_ENABLE (1 << 3) - -#define PFIT_PGM_RATIOS 0x61234 -# define PFIT_VERT_SCALE_MASK 0xfff00000 -# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 - -#define PFIT_AUTO_RATIOS 0x61238 - - -#define DPLL_A 0x06014 -#define DPLL_B 0x06018 -# define DPLL_VCO_ENABLE (1 << 31) -# define DPLL_DVO_HIGH_SPEED (1 << 30) -# define DPLL_SYNCLOCK_ENABLE (1 << 29) -# define DPLL_VGA_MODE_DIS (1 << 28) -# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -# define DPLL_MODE_MASK (3 << 26) -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ -/** - * The i830 generation, in DAC/serial mode, defines p1 as two plus this - * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. - */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/** - * The i830 generation, in LVDS mode, defines P1 as the bit number set within - * this field (only one bit may be set). - */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ -# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -# define PLL_REF_INPUT_DREFCLK (0 << 13) -# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ -# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -# define PLL_REF_INPUT_MASK (3 << 13) -# define PLL_LOAD_PULSE_PHASE_SHIFT 9 -/* - * Parallel to Serial Load Pulse phase selection. - * Selects the phase for the 10X DPLL clock for the PCIe - * digital display port. The range is 4 to 13; 10 or more - * is just a flip delay. The default is 6 - */ -# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) - -/** - * SDVO multiplier for 945G/GM. Not used on 965. - * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK - */ -# define SDVO_MULTIPLIER_MASK 0x000000ff -# define SDVO_MULTIPLIER_SHIFT_HIRES 4 -# define SDVO_MULTIPLIER_SHIFT_VGA 0 - -/** @defgroup DPLL_MD - * @{ - */ -/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_A_MD 0x0601c -/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_B_MD 0x06020 -/** - * UDI pixel divider, controlling how many pixels are stuffed into a packet. - * - * Value is pixels minus 1. Must be set to 1 pixel for SDVO. - */ -# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -# define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/** - * SDVO/UDI pixel multiplier. - * - * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus - * clock rate is 10 times the DPLL clock. At low resolution/refresh rate - * modes, the bus rate would be below the limits, so SDVO allows for stuffing - * dummy bytes in the datastream at an increased clock rate, with both sides of - * the link knowing how many bytes are fill. - * - * So, for a mode with a dotclock of 65Mhz, we would want to double the clock - * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be - * set to 130Mhz, and the SDVO multiplier set to 2x in this register and - * through an SDVO command. - * - * This register field has values of multiplication factor minus 1, with - * a maximum multiplier of 5 for SDVO. - */ -# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. - * This best be set to the default value (3) or the CRT won't work. No, - * I don't entirely understand what this does... - */ -# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 -/** @} */ - -#define DPLL_TEST 0x606c -# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -# define DPLLB_TEST_N_BYPASS (1 << 19) -# define DPLLB_TEST_M_BYPASS (1 << 18) -# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -# define DPLLA_TEST_N_BYPASS (1 << 3) -# define DPLLA_TEST_M_BYPASS (1 << 2) -# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) - -#define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1<<31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1<<30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1<<30) -#define ADPA_USE_VGA_HVPOLARITY (1<<15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) -#define ADPA_HSYNC_ACTIVE_LOW 0 - -#define FPA0 0x06040 -#define FPA1 0x06044 -#define FPB0 0x06048 -#define FPB1 0x0604c -# define FP_N_DIV_MASK 0x003f0000 -# define FP_N_DIV_SHIFT 16 -# define FP_M1_DIV_MASK 0x00003f00 -# define FP_M1_DIV_SHIFT 8 -# define FP_M2_DIV_MASK 0x0000003f -# define FP_M2_DIV_SHIFT 0 - - -#define PORT_HOTPLUG_EN 0x61110 -# define SDVOB_HOTPLUG_INT_EN (1 << 26) -# define SDVOC_HOTPLUG_INT_EN (1 << 25) -# define TV_HOTPLUG_INT_EN (1 << 18) -# define CRT_HOTPLUG_INT_EN (1 << 9) -# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) - -#define PORT_HOTPLUG_STAT 0x61114 -# define CRT_HOTPLUG_INT_STATUS (1 << 11) -# define TV_HOTPLUG_INT_STATUS (1 << 10) -# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) - -#define SDVOB 0x61140 -#define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) -/** - * 915G/GM SDVO pixel multiplier. - * - * Programmed value is multiplier - 1, up to 5x. - * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK - */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) -/* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) -#define SDVOC_PRESERVE_MASK (1 << 17) - -/** @defgroup LVDS - * @{ - */ -/** - * This register controls the LVDS output enable, pipe selection, and data - * format selection. - * - * All of the clock/data pairs are force powered down by power sequencing. - */ -#define LVDS 0x61180 -/** - * Enables the LVDS port. This bit must be set before DPLLs are enabled, as - * the DPLL semantics change when the LVDS is assigned to that pipe. - */ -# define LVDS_PORT_EN (1 << 31) -/** Selects pipe B for LVDS data. Must be set on pre-965. */ -# define LVDS_PIPEB_SELECT (1 << 30) - -/** - * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per - * pixel. - */ -# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/** - * Controls the A3 data pair, which contains the additional LSBs for 24 bit - * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be - * on. - */ -# define LVDS_A3_POWER_MASK (3 << 6) -# define LVDS_A3_POWER_DOWN (0 << 6) -# define LVDS_A3_POWER_UP (3 << 6) -/** - * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP - * is set. - */ -# define LVDS_CLKB_POWER_MASK (3 << 4) -# define LVDS_CLKB_POWER_DOWN (0 << 4) -# define LVDS_CLKB_POWER_UP (3 << 4) - -/** - * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 - * setting for whether we are in dual-channel mode. The B3 pair will - * additionally only be powered up when LVDS_A3_POWER_UP is set. - */ -# define LVDS_B0B3_POWER_MASK (3 << 2) -# define LVDS_B0B3_POWER_DOWN (0 << 2) -# define LVDS_B0B3_POWER_UP (3 << 2) - -#define PIPEACONF 0x70008 -#define PIPEACONF_ENABLE (1<<31) -#define PIPEACONF_DISABLE 0 -#define PIPEACONF_DOUBLE_WIDE (1<<30) -#define I965_PIPECONF_ACTIVE (1<<30) -#define PIPEACONF_SINGLE_WIDE 0 -#define PIPEACONF_PIPE_UNLOCKED 0 -#define PIPEACONF_PIPE_LOCKED (1<<25) -#define PIPEACONF_PALETTE 0 -#define PIPEACONF_GAMMA (1<<24) -#define PIPECONF_FORCE_BORDER (1<<25) -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) - -#define DSPARB 0x70030 -#define DSPARB_CSTART_MASK (0x7f << 7) -#define DSPARB_CSTART_SHIFT 7 -#define DSPARB_BSTART_MASK (0x7f) -#define DSPARB_BSTART_SHIFT 0 - -#define PIPEBCONF 0x71008 -#define PIPEBCONF_ENABLE (1<<31) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_DOUBLE_WIDE (1<<30) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_GAMMA (1<<24) -#define PIPEBCONF_PALETTE 0 - -#define PIPEBGCMAXRED 0x71010 -#define PIPEBGCMAXGREEN 0x71014 -#define PIPEBGCMAXBLUE 0x71018 -#define PIPEBSTAT 0x71024 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPEBFRAMEPIXEL 0x71044 - -#define DSPACNTR 0x70180 -#define DSPBCNTR 0x71180 -#define DISPLAY_PLANE_ENABLE (1<<31) -#define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1<<30) -#define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) -#define DISPPLANE_8BPP (0x2<<26) -#define DISPPLANE_15_16BPP (0x4<<26) -#define DISPPLANE_16BPP (0x5<<26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) -#define DISPPLANE_32BPP (0x7<<26) -#define DISPPLANE_STEREO_ENABLE (1<<25) -#define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) -#define DISPPLANE_SEL_PIPE_A 0 -#define DISPPLANE_SEL_PIPE_B (1<<24) -#define DISPPLANE_SRC_KEY_ENABLE (1<<22) -#define DISPPLANE_SRC_KEY_DISABLE 0 -#define DISPPLANE_LINE_DOUBLE (1<<20) -#define DISPPLANE_NO_LINE_DOUBLE 0 -#define DISPPLANE_STEREO_POLARITY_FIRST 0 -#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) -/* plane B only */ -#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) -#define DISPPLANE_ALPHA_TRANS_DISABLE 0 -#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 -#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) - -#define DSPABASE 0x70184 -#define DSPASTRIDE 0x70188 - -#define DSPBBASE 0x71184 -#define DSPBADDR DSPBBASE -#define DSPBSTRIDE 0x71188 - -#define DSPAKEYVAL 0x70194 -#define DSPAKEYMASK 0x70198 - -#define DSPAPOS 0x7018C /* reserved */ -#define DSPASIZE 0x70190 -#define DSPBPOS 0x7118C -#define DSPBSIZE 0x71190 - -#define DSPASURF 0x7019C -#define DSPATILEOFF 0x701A4 - -#define DSPBSURF 0x7119C -#define DSPBTILEOFF 0x711A4 - -#define VGACNTRL 0x71400 -# define VGA_DISP_DISABLE (1 << 31) -# define VGA_2X_MODE (1 << 30) -# define VGA_PIPE_B_SELECT (1 << 29) - -/* - * Some BIOS scratch area registers. The 845 (and 830?) store the amount - * of video memory available to the BIOS in SWF1. - */ - -#define SWF0 0x71410 - -/* - * 855 scratch registers. - */ -#define SWF10 0x70410 - -#define SWF30 0x72414 - -/* - * Overlay registers. These are overlay registers accessed via MMIO. - * Those loaded via the overlay register page are defined in i830_video.c. - */ -#define OVADD 0x30000 - -#define DOVSTA 0x30008 -#define OC_BUF (0x3<<20) - -#define OGAMC5 0x30010 -#define OGAMC4 0x30014 -#define OGAMC3 0x30018 -#define OGAMC2 0x3001c -#define OGAMC1 0x30020 -#define OGAMC0 0x30024 -/* - * Palette registers - */ -#define PALETTE_A 0x0a000 -#define PALETTE_B 0x0a800 - -#define IS_I830(dev) ((dev)->pci_device == 0x3577) -#define IS_845G(dev) ((dev)->pci_device == 0x2562) -#define IS_I85X(dev) ((dev)->pci_device == 0x3582) -#define IS_I855(dev) ((dev)->pci_device == 0x3582) -#define IS_I865G(dev) ((dev)->pci_device == 0x2572) - -#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) -#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) -#define IS_I945G(dev) ((dev)->pci_device == 0x2772) -#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\ - (dev)->pci_device == 0x27AE) -#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ - (dev)->pci_device == 0x2982 || \ - (dev)->pci_device == 0x2992 || \ - (dev)->pci_device == 0x29A2 || \ - (dev)->pci_device == 0x2A02 || \ - (dev)->pci_device == 0x2A12 || \ - (dev)->pci_device == 0x2A42 || \ - (dev)->pci_device == 0x2E02 || \ - (dev)->pci_device == 0x2E12 || \ - (dev)->pci_device == 0x2E22) - -#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) - -#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42) - -#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ - (dev)->pci_device == 0x2E12 || \ - (dev)->pci_device == 0x2E22) - -#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ - (dev)->pci_device == 0x29B2 || \ - (dev)->pci_device == 0x29D2) - -#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ - IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) - -#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) - -#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev)) - -#define PRIMARY_RINGBUFFER_SIZE (128*1024) - -#endif diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c deleted file mode 100644 index 1fe68a2..0000000 --- a/drivers/char/drm/i915_ioc32.c +++ /dev/null @@ -1,222 +0,0 @@ -/** - * \file i915_ioc32.c - * - * 32-bit ioctl compatibility routines for the i915 DRM. - * - * \author Alan Hourihane - * - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Alan Hourihane 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" - -typedef struct _drm_i915_batchbuffer32 { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ - int num_cliprects; /* mulitpass with multiple cliprects? */ - u32 cliprects; /* pointer to userspace cliprects */ -} drm_i915_batchbuffer32_t; - -static int compat_i915_batchbuffer(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_batchbuffer32_t batchbuffer32; - drm_i915_batchbuffer_t __user *batchbuffer; - - if (copy_from_user - (&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32))) - return -EFAULT; - - batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer)); - if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer)) - || __put_user(batchbuffer32.start, &batchbuffer->start) - || __put_user(batchbuffer32.used, &batchbuffer->used) - || __put_user(batchbuffer32.DR1, &batchbuffer->DR1) - || __put_user(batchbuffer32.DR4, &batchbuffer->DR4) - || __put_user(batchbuffer32.num_cliprects, - &batchbuffer->num_cliprects) - || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects, - &batchbuffer->cliprects)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_BATCHBUFFER, - (unsigned long)batchbuffer); -} - -typedef struct _drm_i915_cmdbuffer32 { - u32 buf; /* pointer to userspace command buffer */ - int sz; /* nr bytes in buf */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ - int num_cliprects; /* mulitpass with multiple cliprects? */ - u32 cliprects; /* pointer to userspace cliprects */ -} drm_i915_cmdbuffer32_t; - -static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_cmdbuffer32_t cmdbuffer32; - drm_i915_cmdbuffer_t __user *cmdbuffer; - - if (copy_from_user - (&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32))) - return -EFAULT; - - cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer)); - if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer)) - || __put_user((int __user *)(unsigned long)cmdbuffer32.buf, - &cmdbuffer->buf) - || __put_user(cmdbuffer32.sz, &cmdbuffer->sz) - || __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1) - || __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4) - || __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects) - || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects, - &cmdbuffer->cliprects)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer); -} - -typedef struct drm_i915_irq_emit32 { - u32 irq_seq; -} drm_i915_irq_emit32_t; - -static int compat_i915_irq_emit(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_irq_emit32_t req32; - drm_i915_irq_emit_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((int __user *)(unsigned long)req32.irq_seq, - &request->irq_seq)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request); -} -typedef struct drm_i915_getparam32 { - int param; - u32 value; -} drm_i915_getparam32_t; - -static int compat_i915_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_getparam32_t req32; - drm_i915_getparam_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_GETPARAM, (unsigned long)request); -} - -typedef struct drm_i915_mem_alloc32 { - int region; - int alignment; - int size; - u32 region_offset; /* offset from start of fb or agp */ -} drm_i915_mem_alloc32_t; - -static int compat_i915_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_mem_alloc32_t req32; - drm_i915_mem_alloc_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.region, &request->region) - || __put_user(req32.alignment, &request->alignment) - || __put_user(req32.size, &request->size) - || __put_user((void __user *)(unsigned long)req32.region_offset, - &request->region_offset)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_I915_ALLOC, (unsigned long)request); -} - -drm_ioctl_compat_t *i915_compat_ioctls[] = { - [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, - [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, - [DRM_I915_GETPARAM] = compat_i915_getparam, - [DRM_I915_IRQ_EMIT] = compat_i915_irq_emit, - [DRM_I915_ALLOC] = compat_i915_alloc -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) - fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; - - lock_kernel(); /* XXX for now */ - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - - return ret; -} diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c deleted file mode 100644 index df03611..0000000 --- a/drivers/char/drm/i915_irq.c +++ /dev/null @@ -1,623 +0,0 @@ -/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -#define USER_INT_FLAG (1<<1) -#define VSYNC_PIPEB_FLAG (1<<5) -#define VSYNC_PIPEA_FLAG (1<<7) - -#define MAX_NOPID ((u32)~0) - -/** - * Emit blits for scheduled buffer swaps. - * - * This function will be called with the HW lock held. - */ -static void i915_vblank_tasklet(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - struct list_head *list, *tmp, hits, *hit; - int nhits, nrects, slice[2], upper[2], lower[2], i; - unsigned counter[2] = { atomic_read(&dev->vbl_received), - atomic_read(&dev->vbl_received2) }; - struct drm_drawable_info *drw; - drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 cpp = dev_priv->cpp; - u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | - XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB) - : XY_SRC_COPY_BLT_CMD; - u32 src_pitch = sarea_priv->pitch * cpp; - u32 dst_pitch = sarea_priv->pitch * cpp; - u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); - RING_LOCALS; - - if (IS_I965G(dev) && sarea_priv->front_tiled) { - cmd |= XY_SRC_COPY_BLT_DST_TILED; - dst_pitch >>= 2; - } - if (IS_I965G(dev) && sarea_priv->back_tiled) { - cmd |= XY_SRC_COPY_BLT_SRC_TILED; - src_pitch >>= 2; - } - - DRM_DEBUG("\n"); - - INIT_LIST_HEAD(&hits); - - nhits = nrects = 0; - - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); - - /* Find buffer swaps scheduled for this vertical blank */ - list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { - drm_i915_vbl_swap_t *vbl_swap = - list_entry(list, drm_i915_vbl_swap_t, head); - - if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) - continue; - - list_del(list); - dev_priv->swaps_pending--; - - spin_unlock(&dev_priv->swaps_lock); - spin_lock(&dev->drw_lock); - - drw = drm_get_drawable_info(dev, vbl_swap->drw_id); - - if (!drw) { - spin_unlock(&dev->drw_lock); - drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); - spin_lock(&dev_priv->swaps_lock); - continue; - } - - list_for_each(hit, &hits) { - drm_i915_vbl_swap_t *swap_cmp = - list_entry(hit, drm_i915_vbl_swap_t, head); - struct drm_drawable_info *drw_cmp = - drm_get_drawable_info(dev, swap_cmp->drw_id); - - if (drw_cmp && - drw_cmp->rects[0].y1 > drw->rects[0].y1) { - list_add_tail(list, hit); - break; - } - } - - spin_unlock(&dev->drw_lock); - - /* List of hits was empty, or we reached the end of it */ - if (hit == &hits) - list_add_tail(list, hits.prev); - - nhits++; - - spin_lock(&dev_priv->swaps_lock); - } - - if (nhits == 0) { - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); - return; - } - - spin_unlock(&dev_priv->swaps_lock); - - i915_kernel_lost_context(dev); - - if (IS_I965G(dev)) { - BEGIN_LP_RING(4); - - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING(0); - OUT_RING(((sarea_priv->width - 1) & 0xffff) | ((sarea_priv->height - 1) << 16)); - OUT_RING(0); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(6); - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(0); - OUT_RING(0); - OUT_RING(sarea_priv->width | sarea_priv->height << 16); - OUT_RING(sarea_priv->width | sarea_priv->height << 16); - OUT_RING(0); - - ADVANCE_LP_RING(); - } - - sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; - - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->pipeA_h / nhits, 1); - slice[1] = max(sarea_priv->pipeB_h / nhits, 1); - lower[0] = sarea_priv->pipeA_y + slice[0]; - lower[1] = sarea_priv->pipeB_y + slice[0]; - - spin_lock(&dev->drw_lock); - - /* Emit blits for buffer swaps, partitioning both outputs into as many - * slices as there are buffer swaps scheduled in order to avoid tearing - * (based on the assumption that a single buffer swap would always - * complete before scanout starts). - */ - for (i = 0; i++ < nhits; - upper[0] = lower[0], lower[0] += slice[0], - upper[1] = lower[1], lower[1] += slice[1]) { - if (i == nhits) - lower[0] = lower[1] = sarea_priv->height; - - list_for_each(hit, &hits) { - drm_i915_vbl_swap_t *swap_hit = - list_entry(hit, drm_i915_vbl_swap_t, head); - struct drm_clip_rect *rect; - int num_rects, pipe; - unsigned short top, bottom; - - drw = drm_get_drawable_info(dev, swap_hit->drw_id); - - if (!drw) - continue; - - rect = drw->rects; - pipe = swap_hit->pipe; - top = upper[pipe]; - bottom = lower[pipe]; - - for (num_rects = drw->num_rects; num_rects--; rect++) { - int y1 = max(rect->y1, top); - int y2 = min(rect->y2, bottom); - - if (y1 >= y2) - continue; - - BEGIN_LP_RING(8); - - OUT_RING(cmd); - OUT_RING(ropcpp | dst_pitch); - OUT_RING((y1 << 16) | rect->x1); - OUT_RING((y2 << 16) | rect->x2); - OUT_RING(sarea_priv->front_offset); - OUT_RING((y1 << 16) | rect->x1); - OUT_RING(src_pitch); - OUT_RING(sarea_priv->back_offset); - - ADVANCE_LP_RING(); - } - } - } - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - list_for_each_safe(hit, tmp, &hits) { - drm_i915_vbl_swap_t *swap_hit = - list_entry(hit, drm_i915_vbl_swap_t, head); - - list_del(hit); - - drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER); - } -} - -irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u16 temp; - u32 pipea_stats, pipeb_stats; - - pipea_stats = I915_READ(I915REG_PIPEASTAT); - pipeb_stats = I915_READ(I915REG_PIPEBSTAT); - - temp = I915_READ16(I915REG_INT_IDENTITY_R); - - temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); - - DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); - - if (temp == 0) - return IRQ_NONE; - - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - (void) I915_READ16(I915REG_INT_IDENTITY_R); - DRM_READMEMORYBARRIER(); - - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - - if (temp & USER_INT_FLAG) - DRM_WAKEUP(&dev_priv->irq_queue); - - if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { - int vblank_pipe = dev_priv->vblank_pipe; - - if ((vblank_pipe & - (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) - == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { - if (temp & VSYNC_PIPEA_FLAG) - atomic_inc(&dev->vbl_received); - if (temp & VSYNC_PIPEB_FLAG) - atomic_inc(&dev->vbl_received2); - } else if (((temp & VSYNC_PIPEA_FLAG) && - (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) || - ((temp & VSYNC_PIPEB_FLAG) && - (vblank_pipe & DRM_I915_VBLANK_PIPE_B))) - atomic_inc(&dev->vbl_received); - - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); - - if (dev_priv->swaps_pending > 0) - drm_locked_tasklet(dev, i915_vblank_tasklet); - I915_WRITE(I915REG_PIPEASTAT, - pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| - I915_VBLANK_CLEAR); - I915_WRITE(I915REG_PIPEBSTAT, - pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| - I915_VBLANK_CLEAR); - } - - return IRQ_HANDLED; -} - -static int i915_emit_irq(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i915_kernel_lost_context(dev); - - DRM_DEBUG("\n"); - - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; - - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; - - BEGIN_LP_RING(6); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(0); - OUT_RING(0); - OUT_RING(GFX_OP_USER_INTERRUPT); - ADVANCE_LP_RING(); - - return dev_priv->counter; -} - -static int i915_wait_irq(struct drm_device * dev, int irq_nr) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret = 0; - - DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, - READ_BREADCRUMB(dev_priv)); - - if (READ_BREADCRUMB(dev_priv) >= irq_nr) - return 0; - - dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - - DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, - READ_BREADCRUMB(dev_priv) >= irq_nr); - - if (ret == -EBUSY) { - DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", - READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); - } - - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - return ret; -} - -static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, - atomic_t *counter) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - unsigned int cur_vblank; - int ret = 0; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(counter)) - - *sequence) <= (1<<23))); - - *sequence = cur_vblank; - - return ret; -} - - -int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) -{ - return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); -} - -int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) -{ - return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); -} - -/* Needs the lock as it touches the ring. - */ -int i915_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_emit_t *emit = data; - int result; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - result = i915_emit_irq(dev); - - if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -/* Doesn't need the hardware lock. - */ -int i915_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_wait_t *irqwait = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - return i915_wait_irq(dev, irqwait->irq_seq); -} - -static void i915_enable_interrupt (struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u16 flag; - - flag = 0; - if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) - flag |= VSYNC_PIPEA_FLAG; - if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) - flag |= VSYNC_PIPEB_FLAG; - - I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); -} - -/* Set the vblank monitor pipe - */ -int i915_vblank_pipe_set(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t *pipe = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { - DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe); - return -EINVAL; - } - - dev_priv->vblank_pipe = pipe->pipe; - - i915_enable_interrupt (dev); - - return 0; -} - -int i915_vblank_pipe_get(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t *pipe = data; - u16 flag; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - flag = I915_READ(I915REG_INT_ENABLE_R); - pipe->pipe = 0; - if (flag & VSYNC_PIPEA_FLAG) - pipe->pipe |= DRM_I915_VBLANK_PIPE_A; - if (flag & VSYNC_PIPEB_FLAG) - pipe->pipe |= DRM_I915_VBLANK_PIPE_B; - - return 0; -} - -/** - * Schedule buffer swap at given vertical blank. - */ -int i915_vblank_swap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_swap_t *swap = data; - drm_i915_vbl_swap_t *vbl_swap; - unsigned int pipe, seqtype, curseq; - unsigned long irqflags; - struct list_head *list; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __func__); - return -EINVAL; - } - - if (dev_priv->sarea_priv->rotation) { - DRM_DEBUG("Rotation not supported\n"); - return -EINVAL; - } - - if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | - _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { - DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); - return -EINVAL; - } - - pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; - - seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); - - if (!(dev_priv->vblank_pipe & (1 << pipe))) { - DRM_ERROR("Invalid pipe %d\n", pipe); - return -EINVAL; - } - - spin_lock_irqsave(&dev->drw_lock, irqflags); - - if (!drm_get_drawable_info(dev, swap->drawable)) { - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); - return -EINVAL; - } - - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - - curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); - - if (seqtype == _DRM_VBLANK_RELATIVE) - swap->sequence += curseq; - - if ((curseq - swap->sequence) <= (1<<23)) { - if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) { - swap->sequence = curseq + 1; - } else { - DRM_DEBUG("Missed target sequence\n"); - return -EINVAL; - } - } - - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); - - list_for_each(list, &dev_priv->vbl_swaps.head) { - vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); - - if (vbl_swap->drw_id == swap->drawable && - vbl_swap->pipe == pipe && - vbl_swap->sequence == swap->sequence) { - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); - DRM_DEBUG("Already scheduled\n"); - return 0; - } - } - - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); - - if (dev_priv->swaps_pending >= 100) { - DRM_DEBUG("Too many swaps queued\n"); - return -EBUSY; - } - - vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER); - - if (!vbl_swap) { - DRM_ERROR("Failed to allocate memory to queue swap\n"); - return -ENOMEM; - } - - DRM_DEBUG("\n"); - - vbl_swap->drw_id = swap->drawable; - vbl_swap->pipe = pipe; - vbl_swap->sequence = swap->sequence; - - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); - - list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head); - dev_priv->swaps_pending++; - - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); - - return 0; -} - -/* drm_dma.h hooks -*/ -void i915_driver_irq_preinstall(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - I915_WRITE16(I915REG_HWSTAM, 0xfffe); - I915_WRITE16(I915REG_INT_MASK_R, 0x0); - I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); -} - -void i915_driver_irq_postinstall(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - spin_lock_init(&dev_priv->swaps_lock); - INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); - dev_priv->swaps_pending = 0; - - if (!dev_priv->vblank_pipe) - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; - i915_enable_interrupt(dev); - DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); -} - -void i915_driver_irq_uninstall(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u16 temp; - - if (!dev_priv) - return; - - I915_WRITE16(I915REG_HWSTAM, 0xffff); - I915_WRITE16(I915REG_INT_MASK_R, 0xffff); - I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); - - temp = I915_READ16(I915REG_INT_IDENTITY_R); - I915_WRITE16(I915REG_INT_IDENTITY_R, temp); -} diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c deleted file mode 100644 index 6126a60..0000000 --- a/drivers/char/drm/i915_mem.c +++ /dev/null @@ -1,386 +0,0 @@ -/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/* This memory manager is integrated into the global/local lru - * mechanisms used by the clients. Specifically, it operates by - * setting the 'in_use' fields of the global LRU to indicate whether - * this region is privately allocated to a client. - * - * This does require the client to actually respect that field. - * - * Currently no effort is made to allocate 'private' memory in any - * clever way - the LRU information isn't used to determine which - * block to allocate, and the ring is drained prior to allocations -- - * in other words allocation is expensive. - */ -static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_tex_region *list; - unsigned shift, nr; - unsigned start; - unsigned end; - unsigned i; - int age; - - shift = dev_priv->tex_lru_log_granularity; - nr = I915_NR_TEX_REGIONS; - - start = p->start >> shift; - end = (p->start + p->size - 1) >> shift; - - age = ++sarea_priv->texAge; - list = sarea_priv->texList; - - /* Mark the regions with the new flag and update their age. Move - * them to head of list to preserve LRU semantics. - */ - for (i = start; i <= end; i++) { - list[i].in_use = in_use; - list[i].age = age; - - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = nr; - list[i].next = list[nr].next; - list[(unsigned)list[nr].next].prev = i; - list[nr].next = i; - } -} - -/* Very simple allocator for agp memory, working on a static range - * already mapped into each client's address space. - */ - -static struct mem_block *split_block(struct mem_block *p, int start, int size, - struct drm_file *file_priv) -{ - /* Maybe cut off the start of an existing block */ - if (start > p->start) { - struct mem_block *newblock = - drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); - if (!newblock) - goto out; - newblock->start = start; - newblock->size = p->size - (start - p->start); - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size -= newblock->size; - p = newblock; - } - - /* Maybe cut off the end of an existing block */ - if (size < p->size) { - struct mem_block *newblock = - drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); - if (!newblock) - goto out; - newblock->start = start + size; - newblock->size = p->size - size; - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size = size; - } - - out: - /* Our block is in the middle */ - p->file_priv = file_priv; - return p; -} - -static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, struct drm_file *file_priv) -{ - struct mem_block *p; - int mask = (1 << align2) - 1; - - for (p = heap->next; p != heap; p = p->next) { - int start = (p->start + mask) & ~mask; - if (p->file_priv == NULL && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - - return NULL; -} - -static struct mem_block *find_block(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) - if (p->start == start) - return p; - - return NULL; -} - -static void free_block(struct mem_block *p) -{ - p->file_priv = NULL; - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - if (p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); - } - - if (p->prev->file_priv == NULL) { - struct mem_block *q = p->prev; - q->size += p->size; - q->next = p->next; - q->next->prev = q; - drm_free(p, sizeof(*q), DRM_MEM_BUFLISTS); - } -} - -/* Initialize. How to check for an uninitialized heap? - */ -static int init_heap(struct mem_block **heap, int start, int size) -{ - struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFLISTS); - - if (!blocks) - return -ENOMEM; - - *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFLISTS); - if (!*heap) { - drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFLISTS); - return -ENOMEM; - } - - blocks->start = start; - blocks->size = size; - blocks->file_priv = NULL; - blocks->next = blocks->prev = *heap; - - memset(*heap, 0, sizeof(**heap)); - (*heap)->file_priv = (struct drm_file *) - 1; - (*heap)->next = (*heap)->prev = blocks; - return 0; -} - -/* Free all blocks associated with the releasing file. - */ -void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, - struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap || !heap->next) - return; - - for (p = heap->next; p != heap; p = p->next) { - if (p->file_priv == file_priv) { - p->file_priv = NULL; - mark_block(dev, p, 0); - } - } - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - for (p = heap->next; p != heap; p = p->next) { - while (p->file_priv == NULL && p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); - } - } -} - -/* Shutdown. - */ -void i915_mem_takedown(struct mem_block **heap) -{ - struct mem_block *p; - - if (!*heap) - return; - - for (p = (*heap)->next; p != *heap;) { - struct mem_block *q = p; - p = p->next; - drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); - } - - drm_free(*heap, sizeof(**heap), DRM_MEM_BUFLISTS); - *heap = NULL; -} - -static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region) -{ - switch (region) { - case I915_MEM_REGION_AGP: - return &dev_priv->agp_heap; - default: - return NULL; - } -} - -/* IOCTL HANDLERS */ - -int i915_mem_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_alloc_t *alloc = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, alloc->region); - if (!heap || !*heap) - return -EFAULT; - - /* Make things easier on ourselves: all allocations at least - * 4k aligned. - */ - if (alloc->alignment < 12) - alloc->alignment = 12; - - block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); - - if (!block) - return -ENOMEM; - - mark_block(dev, block, 1); - - if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, - sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -int i915_mem_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_free_t *memfree = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, memfree->region); - if (!heap || !*heap) - return -EFAULT; - - block = find_block(*heap, memfree->region_offset); - if (!block) - return -EFAULT; - - if (block->file_priv != file_priv) - return -EPERM; - - mark_block(dev, block, 0); - free_block(block); - return 0; -} - -int i915_mem_init_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_init_heap_t *initheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, initheap->region); - if (!heap) - return -EFAULT; - - if (*heap) { - DRM_ERROR("heap already initialized?"); - return -EFAULT; - } - - return init_heap(heap, initheap->start, initheap->size); -} - -int i915_mem_destroy_heap( struct drm_device *dev, void *data, - struct drm_file *file_priv ) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_destroy_heap_t *destroyheap = data; - struct mem_block **heap; - - if ( !dev_priv ) { - DRM_ERROR( "called with no initialization\n" ); - return -EINVAL; - } - - heap = get_heap( dev_priv, destroyheap->region ); - if (!heap) { - DRM_ERROR("get_heap failed"); - return -EFAULT; - } - - if (!*heap) { - DRM_ERROR("heap not initialized?"); - return -EFAULT; - } - - i915_mem_takedown( heap ); - return 0; -} diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c deleted file mode 100644 index c1d12db..0000000 --- a/drivers/char/drm/mga_dma.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file mga_dma.c - * DMA support for MGA G200 / G400. - * - * \author Rickard E. (Rik) Faith - * \author Jeff Hartmann - * \author Keith Whitwell - * \author Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "mga_drm.h" -#include "mga_drv.h" - -#define MGA_DEFAULT_USEC_TIMEOUT 10000 -#define MGA_FREELIST_DEBUG 0 - -#define MINIMAL_CLEANUP 0 -#define FULL_CLEANUP 1 -static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup); - -/* ================================================================ - * Engine control - */ - -int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) -{ - u32 status = 0; - int i; - DRM_DEBUG("\n"); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; - if (status == MGA_ENDPRDMASTS) { - MGA_WRITE8(MGA_CRTC_INDEX, 0); - return 0; - } - DRM_UDELAY(1); - } - -#if MGA_DMA_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x\n", status); -#endif - return -EBUSY; -} - -static int mga_do_dma_reset(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - - DRM_DEBUG("\n"); - - /* The primary DMA stream should look like new right about now. - */ - primary->tail = 0; - primary->space = primary->size; - primary->last_flush = 0; - - sarea_priv->last_wrap = 0; - - /* FIXME: Reset counters, buffer ages etc... - */ - - /* FIXME: What else do we need to reinitialize? WARP stuff? - */ - - return 0; -} - -/* ================================================================ - * Primary DMA stream - */ - -void mga_do_dma_flush(drm_mga_private_t * dev_priv) -{ - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - u32 head, tail; - u32 status = 0; - int i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - /* We need to wait so that we can do an safe flush */ - for (i = 0; i < dev_priv->usec_timeout; i++) { - status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; - if (status == MGA_ENDPRDMASTS) - break; - DRM_UDELAY(1); - } - - if (primary->tail == primary->last_flush) { - DRM_DEBUG(" bailing out...\n"); - return; - } - - tail = primary->tail + dev_priv->primary->offset; - - /* We need to pad the stream between flushes, as the card - * actually (partially?) reads the first of these commands. - * See page 4-16 in the G400 manual, middle of the page or so. - */ - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); - - primary->last_flush = primary->tail; - - head = MGA_READ(MGA_PRIMADDRESS); - - if (head <= tail) { - primary->space = primary->size - primary->tail; - } else { - primary->space = head - tail; - } - - DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); - DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset); - DRM_DEBUG(" space = 0x%06x\n", primary->space); - - mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); - - DRM_DEBUG("done.\n"); -} - -void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) -{ - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - u32 head, tail; - DMA_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_DMA_WRAP(); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); - - tail = primary->tail + dev_priv->primary->offset; - - primary->tail = 0; - primary->last_flush = 0; - primary->last_wrap++; - - head = MGA_READ(MGA_PRIMADDRESS); - - if (head == dev_priv->primary->offset) { - primary->space = primary->size; - } else { - primary->space = head - dev_priv->primary->offset; - } - - DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); - DRM_DEBUG(" tail = 0x%06x\n", primary->tail); - DRM_DEBUG(" wrap = %d\n", primary->last_wrap); - DRM_DEBUG(" space = 0x%06x\n", primary->space); - - mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); - - set_bit(0, &primary->wrapped); - DRM_DEBUG("done.\n"); -} - -void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) -{ - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 head = dev_priv->primary->offset; - DRM_DEBUG("\n"); - - sarea_priv->last_wrap++; - DRM_DEBUG(" wrap = %d\n", sarea_priv->last_wrap); - - mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL); - - clear_bit(0, &primary->wrapped); - DRM_DEBUG("done.\n"); -} - -/* ================================================================ - * Freelist management - */ - -#define MGA_BUFFER_USED ~0 -#define MGA_BUFFER_FREE 0 - -#if MGA_FREELIST_DEBUG -static void mga_freelist_print(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_freelist_t *entry; - - DRM_INFO("\n"); - DRM_INFO("current dispatch: last=0x%x done=0x%x\n", - dev_priv->sarea_priv->last_dispatch, - (unsigned int)(MGA_READ(MGA_PRIMADDRESS) - - dev_priv->primary->offset)); - DRM_INFO("current freelist:\n"); - - for (entry = dev_priv->head->next; entry; entry = entry->next) { - DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n", - entry, entry->buf->idx, entry->age.head, - entry->age.head - dev_priv->primary->offset); - } - DRM_INFO("\n"); -} -#endif - -static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_freelist_t *entry; - int i; - DRM_DEBUG("count=%d\n", dma->buf_count); - - dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); - if (dev_priv->head == NULL) - return -ENOMEM; - - memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); - SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - - entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); - if (entry == NULL) - return -ENOMEM; - - memset(entry, 0, sizeof(drm_mga_freelist_t)); - - entry->next = dev_priv->head->next; - entry->prev = dev_priv->head; - SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); - entry->buf = buf; - - if (dev_priv->head->next != NULL) - dev_priv->head->next->prev = entry; - if (entry->next == NULL) - dev_priv->tail = entry; - - buf_priv->list_entry = entry; - buf_priv->discard = 0; - buf_priv->dispatched = 0; - - dev_priv->head->next = entry; - } - - return 0; -} - -static void mga_freelist_cleanup(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_freelist_t *entry; - drm_mga_freelist_t *next; - DRM_DEBUG("\n"); - - entry = dev_priv->head; - while (entry) { - next = entry->next; - drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); - entry = next; - } - - dev_priv->head = dev_priv->tail = NULL; -} - -#if 0 -/* FIXME: Still needed? - */ -static void mga_freelist_reset(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - int i; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0); - } -} -#endif - -static struct drm_buf *mga_freelist_get(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_freelist_t *next; - drm_mga_freelist_t *prev; - drm_mga_freelist_t *tail = dev_priv->tail; - u32 head, wrap; - DRM_DEBUG("\n"); - - head = MGA_READ(MGA_PRIMADDRESS); - wrap = dev_priv->sarea_priv->last_wrap; - - DRM_DEBUG(" tail=0x%06lx %d\n", - tail->age.head ? - tail->age.head - dev_priv->primary->offset : 0, - tail->age.wrap); - DRM_DEBUG(" head=0x%06lx %d\n", - head - dev_priv->primary->offset, wrap); - - if (TEST_AGE(&tail->age, head, wrap)) { - prev = dev_priv->tail->prev; - next = dev_priv->tail; - prev->next = NULL; - next->prev = next->next = NULL; - dev_priv->tail = prev; - SET_AGE(&next->age, MGA_BUFFER_USED, 0); - return next->buf; - } - - DRM_DEBUG("returning NULL!\n"); - return NULL; -} - -int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_freelist_t *head, *entry, *prev; - - DRM_DEBUG("age=0x%06lx wrap=%d\n", - buf_priv->list_entry->age.head - - dev_priv->primary->offset, buf_priv->list_entry->age.wrap); - - entry = buf_priv->list_entry; - head = dev_priv->head; - - if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) { - SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); - prev = dev_priv->tail; - prev->next = entry; - entry->prev = prev; - entry->next = NULL; - } else { - prev = head->next; - head->next = entry; - prev->prev = entry; - entry->prev = head; - entry->next = prev; - } - - return 0; -} - -/* ================================================================ - * DMA initialization, cleanup - */ - -int mga_driver_load(struct drm_device * dev, unsigned long flags) -{ - drm_mga_private_t *dev_priv; - - dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); - if (!dev_priv) - return -ENOMEM; - - dev->dev_private = (void *)dev_priv; - memset(dev_priv, 0, sizeof(drm_mga_private_t)); - - dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; - dev_priv->chipset = flags; - - dev_priv->mmio_base = drm_get_resource_start(dev, 1); - dev_priv->mmio_size = drm_get_resource_len(dev, 1); - - dev->counters += 3; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - - return 0; -} - -#if __OS_HAS_AGP -/** - * Bootstrap the driver for AGP DMA. - * - * \todo - * Investigate whether there is any benifit to storing the WARP microcode in - * AGP memory. If not, the microcode may as well always be put in PCI - * memory. - * - * \todo - * This routine needs to set dma_bs->agp_mode to the mode actually configured - * in the hardware. Looking just at the Linux AGP driver code, I don't see - * an easy way to determine this. - * - * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap - */ -static int mga_do_agp_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) -{ - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - unsigned int warp_size = mga_warp_microcode_size(dev_priv); - int err; - unsigned offset; - const unsigned secondary_size = dma_bs->secondary_bin_count - * dma_bs->secondary_bin_size; - const unsigned agp_size = (dma_bs->agp_size << 20); - struct drm_buf_desc req; - struct drm_agp_mode mode; - struct drm_agp_info info; - struct drm_agp_buffer agp_req; - struct drm_agp_binding bind_req; - - /* Acquire AGP. */ - err = drm_agp_acquire(dev); - if (err) { - DRM_ERROR("Unable to acquire AGP: %d\n", err); - return err; - } - - err = drm_agp_info(dev, &info); - if (err) { - DRM_ERROR("Unable to get AGP info: %d\n", err); - return err; - } - - mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode; - err = drm_agp_enable(dev, mode); - if (err) { - DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); - return err; - } - - /* In addition to the usual AGP mode configuration, the G200 AGP cards - * need to have the AGP mode "manually" set. - */ - - if (dev_priv->chipset == MGA_CARD_TYPE_G200) { - if (mode.mode & 0x02) { - MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); - } else { - MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); - } - } - - /* Allocate and bind AGP memory. */ - agp_req.size = agp_size; - agp_req.type = 0; - err = drm_agp_alloc(dev, &agp_req); - if (err) { - dev_priv->agp_size = 0; - DRM_ERROR("Unable to allocate %uMB AGP memory\n", - dma_bs->agp_size); - return err; - } - - dev_priv->agp_size = agp_size; - dev_priv->agp_handle = agp_req.handle; - - bind_req.handle = agp_req.handle; - bind_req.offset = 0; - err = drm_agp_bind(dev, &bind_req); - if (err) { - DRM_ERROR("Unable to bind AGP memory: %d\n", err); - return err; - } - - /* Make drm_addbufs happy by not trying to create a mapping for less - * than a page. - */ - if (warp_size < PAGE_SIZE) - warp_size = PAGE_SIZE; - - offset = 0; - err = drm_addmap(dev, offset, warp_size, - _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); - if (err) { - DRM_ERROR("Unable to map WARP microcode: %d\n", err); - return err; - } - - offset += warp_size; - err = drm_addmap(dev, offset, dma_bs->primary_size, - _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); - if (err) { - DRM_ERROR("Unable to map primary DMA region: %d\n", err); - return err; - } - - offset += dma_bs->primary_size; - err = drm_addmap(dev, offset, secondary_size, - _DRM_AGP, 0, &dev->agp_buffer_map); - if (err) { - DRM_ERROR("Unable to map secondary DMA region: %d\n", err); - return err; - } - - (void)memset(&req, 0, sizeof(req)); - req.count = dma_bs->secondary_bin_count; - req.size = dma_bs->secondary_bin_size; - req.flags = _DRM_AGP_BUFFER; - req.agp_start = offset; - - err = drm_addbufs_agp(dev, &req); - if (err) { - DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); - return err; - } - - { - struct drm_map_list *_entry; - unsigned long agp_token = 0; - - list_for_each_entry(_entry, &dev->maplist, head) { - if (_entry->map == dev->agp_buffer_map) - agp_token = _entry->user_token; - } - if (!agp_token) - return -EFAULT; - - dev->agp_buffer_token = agp_token; - } - - offset += secondary_size; - err = drm_addmap(dev, offset, agp_size - offset, - _DRM_AGP, 0, &dev_priv->agp_textures); - if (err) { - DRM_ERROR("Unable to map AGP texture region %d\n", err); - return err; - } - - drm_core_ioremap(dev_priv->warp, dev); - drm_core_ioremap(dev_priv->primary, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); - - if (!dev_priv->warp->handle || - !dev_priv->primary->handle || !dev->agp_buffer_map->handle) { - DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n", - dev_priv->warp->handle, dev_priv->primary->handle, - dev->agp_buffer_map->handle); - return -ENOMEM; - } - - dev_priv->dma_access = MGA_PAGPXFER; - dev_priv->wagp_enable = MGA_WAGP_ENABLE; - - DRM_INFO("Initialized card for AGP DMA.\n"); - return 0; -} -#else -static int mga_do_agp_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) -{ - return -EINVAL; -} -#endif - -/** - * Bootstrap the driver for PCI DMA. - * - * \todo - * The algorithm for decreasing the size of the primary DMA buffer could be - * better. The size should be rounded up to the nearest page size, then - * decrease the request size by a single page each pass through the loop. - * - * \todo - * Determine whether the maximum address passed to drm_pci_alloc is correct. - * The same goes for drm_addbufs_pci. - * - * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap - */ -static int mga_do_pci_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) -{ - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - unsigned int warp_size = mga_warp_microcode_size(dev_priv); - unsigned int primary_size; - unsigned int bin_count; - int err; - struct drm_buf_desc req; - - if (dev->dma == NULL) { - DRM_ERROR("dev->dma is NULL\n"); - return -EFAULT; - } - - /* Make drm_addbufs happy by not trying to create a mapping for less - * than a page. - */ - if (warp_size < PAGE_SIZE) - warp_size = PAGE_SIZE; - - /* The proper alignment is 0x100 for this mapping */ - err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, - _DRM_READ_ONLY, &dev_priv->warp); - if (err != 0) { - DRM_ERROR("Unable to create mapping for WARP microcode: %d\n", - err); - return err; - } - - /* Other than the bottom two bits being used to encode other - * information, there don't appear to be any restrictions on the - * alignment of the primary or secondary DMA buffers. - */ - - for (primary_size = dma_bs->primary_size; primary_size != 0; - primary_size >>= 1) { - /* The proper alignment for this mapping is 0x04 */ - err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT, - _DRM_READ_ONLY, &dev_priv->primary); - if (!err) - break; - } - - if (err != 0) { - DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); - return -ENOMEM; - } - - if (dev_priv->primary->size != dma_bs->primary_size) { - DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n", - dma_bs->primary_size, - (unsigned)dev_priv->primary->size); - dma_bs->primary_size = dev_priv->primary->size; - } - - for (bin_count = dma_bs->secondary_bin_count; bin_count > 0; - bin_count--) { - (void)memset(&req, 0, sizeof(req)); - req.count = bin_count; - req.size = dma_bs->secondary_bin_size; - - err = drm_addbufs_pci(dev, &req); - if (!err) { - break; - } - } - - if (bin_count == 0) { - DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); - return err; - } - - if (bin_count != dma_bs->secondary_bin_count) { - DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u " - "to %u.\n", dma_bs->secondary_bin_count, bin_count); - - dma_bs->secondary_bin_count = bin_count; - } - - dev_priv->dma_access = 0; - dev_priv->wagp_enable = 0; - - dma_bs->agp_mode = 0; - - DRM_INFO("Initialized card for PCI DMA.\n"); - return 0; -} - -static int mga_do_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) -{ - const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); - int err; - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - dev_priv->used_new_dma_init = 1; - - /* The first steps are the same for both PCI and AGP based DMA. Map - * the cards MMIO registers and map a status page. - */ - err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); - if (err) { - DRM_ERROR("Unable to map MMIO region: %d\n", err); - return err; - } - - err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, - _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, - &dev_priv->status); - if (err) { - DRM_ERROR("Unable to map status region: %d\n", err); - return err; - } - - /* The DMA initialization procedure is slightly different for PCI and - * AGP cards. AGP cards just allocate a large block of AGP memory and - * carve off portions of it for internal uses. The remaining memory - * is returned to user-mode to be used for AGP textures. - */ - if (is_agp) { - err = mga_do_agp_dma_bootstrap(dev, dma_bs); - } - - /* If we attempted to initialize the card for AGP DMA but failed, - * clean-up any mess that may have been created. - */ - - if (err) { - mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); - } - - /* Not only do we want to try and initialized PCI cards for PCI DMA, - * but we also try to initialized AGP cards that could not be - * initialized for AGP DMA. This covers the case where we have an AGP - * card in a system with an unsupported AGP chipset. In that case the - * card will be detected as AGP, but we won't be able to allocate any - * AGP memory, etc. - */ - - if (!is_agp || err) { - err = mga_do_pci_dma_bootstrap(dev, dma_bs); - } - - return err; -} - -int mga_dma_bootstrap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_dma_bootstrap_t *bootstrap = data; - int err; - static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; - const drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - err = mga_do_dma_bootstrap(dev, bootstrap); - if (err) { - mga_do_cleanup_dma(dev, FULL_CLEANUP); - return err; - } - - if (dev_priv->agp_textures != NULL) { - bootstrap->texture_handle = dev_priv->agp_textures->offset; - bootstrap->texture_size = dev_priv->agp_textures->size; - } else { - bootstrap->texture_handle = 0; - bootstrap->texture_size = 0; - } - - bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07]; - - return err; -} - -static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init) -{ - drm_mga_private_t *dev_priv; - int ret; - DRM_DEBUG("\n"); - - dev_priv = dev->dev_private; - - if (init->sgram) { - dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; - } else { - dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; - } - dev_priv->maccess = init->maccess; - - dev_priv->fb_cpp = init->fb_cpp; - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - dev_priv->depth_cpp = init->depth_cpp; - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - - /* FIXME: Need to support AGP textures... - */ - dev_priv->texture_offset = init->texture_offset[0]; - dev_priv->texture_size = init->texture_size[0]; - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("failed to find sarea!\n"); - return -EINVAL; - } - - if (!dev_priv->used_new_dma_init) { - - dev_priv->dma_access = MGA_PAGPXFER; - dev_priv->wagp_enable = MGA_WAGP_ENABLE; - - dev_priv->status = drm_core_findmap(dev, init->status_offset); - if (!dev_priv->status) { - DRM_ERROR("failed to find status page!\n"); - return -EINVAL; - } - dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio) { - DRM_ERROR("failed to find mmio region!\n"); - return -EINVAL; - } - dev_priv->warp = drm_core_findmap(dev, init->warp_offset); - if (!dev_priv->warp) { - DRM_ERROR("failed to find warp microcode region!\n"); - return -EINVAL; - } - dev_priv->primary = drm_core_findmap(dev, init->primary_offset); - if (!dev_priv->primary) { - DRM_ERROR("failed to find primary dma region!\n"); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = - drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("failed to find dma buffer region!\n"); - return -EINVAL; - } - - drm_core_ioremap(dev_priv->warp, dev); - drm_core_ioremap(dev_priv->primary, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); - } - - dev_priv->sarea_priv = - (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - - if (!dev_priv->warp->handle || - !dev_priv->primary->handle || - ((dev_priv->dma_access != 0) && - ((dev->agp_buffer_map == NULL) || - (dev->agp_buffer_map->handle == NULL)))) { - DRM_ERROR("failed to ioremap agp regions!\n"); - return -ENOMEM; - } - - ret = mga_warp_install_microcode(dev_priv); - if (ret < 0) { - DRM_ERROR("failed to install WARP ucode!: %d\n", ret); - return ret; - } - - ret = mga_warp_init(dev_priv); - if (ret < 0) { - DRM_ERROR("failed to init WARP engine!: %d\n", ret); - return ret; - } - - dev_priv->prim.status = (u32 *) dev_priv->status->handle; - - mga_do_wait_for_idle(dev_priv); - - /* Init the primary DMA registers. - */ - MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL); -#if 0 - MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ - MGA_PRIMPTREN1); /* DWGSYNC */ -#endif - - dev_priv->prim.start = (u8 *) dev_priv->primary->handle; - dev_priv->prim.end = ((u8 *) dev_priv->primary->handle - + dev_priv->primary->size); - dev_priv->prim.size = dev_priv->primary->size; - - dev_priv->prim.tail = 0; - dev_priv->prim.space = dev_priv->prim.size; - dev_priv->prim.wrapped = 0; - - dev_priv->prim.last_flush = 0; - dev_priv->prim.last_wrap = 0; - - dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; - - dev_priv->prim.status[0] = dev_priv->primary->offset; - dev_priv->prim.status[1] = 0; - - dev_priv->sarea_priv->last_wrap = 0; - dev_priv->sarea_priv->last_frame.head = 0; - dev_priv->sarea_priv->last_frame.wrap = 0; - - if (mga_freelist_init(dev, dev_priv) < 0) { - DRM_ERROR("could not initialize freelist\n"); - return -ENOMEM; - } - - return 0; -} - -static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) -{ - int err = 0; - DRM_DEBUG("\n"); - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - drm_mga_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->warp != NULL) - && (dev_priv->warp->type != _DRM_CONSISTENT)) - drm_core_ioremapfree(dev_priv->warp, dev); - - if ((dev_priv->primary != NULL) - && (dev_priv->primary->type != _DRM_CONSISTENT)) - drm_core_ioremapfree(dev_priv->primary, dev); - - if (dev->agp_buffer_map != NULL) - drm_core_ioremapfree(dev->agp_buffer_map, dev); - - if (dev_priv->used_new_dma_init) { -#if __OS_HAS_AGP - if (dev_priv->agp_handle != 0) { - struct drm_agp_binding unbind_req; - struct drm_agp_buffer free_req; - - unbind_req.handle = dev_priv->agp_handle; - drm_agp_unbind(dev, &unbind_req); - - free_req.handle = dev_priv->agp_handle; - drm_agp_free(dev, &free_req); - - dev_priv->agp_textures = NULL; - dev_priv->agp_size = 0; - dev_priv->agp_handle = 0; - } - - if ((dev->agp != NULL) && dev->agp->acquired) { - err = drm_agp_release(dev); - } -#endif - } - - dev_priv->warp = NULL; - dev_priv->primary = NULL; - dev_priv->sarea = NULL; - dev_priv->sarea_priv = NULL; - dev->agp_buffer_map = NULL; - - if (full_cleanup) { - dev_priv->mmio = NULL; - dev_priv->status = NULL; - dev_priv->used_new_dma_init = 0; - } - - memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); - dev_priv->warp_pipe = 0; - memset(dev_priv->warp_pipe_phys, 0, - sizeof(dev_priv->warp_pipe_phys)); - - if (dev_priv->head != NULL) { - mga_freelist_cleanup(dev); - } - } - - return err; -} - -int mga_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_init_t *init = data; - int err; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - switch (init->func) { - case MGA_INIT_DMA: - err = mga_do_init_dma(dev, init); - if (err) { - (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); - } - return err; - case MGA_CLEANUP_DMA: - return mga_do_cleanup_dma(dev, FULL_CLEANUP); - } - - return -EINVAL; -} - -/* ================================================================ - * Primary DMA stream management - */ - -int mga_dma_flush(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - struct drm_lock *lock = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("%s%s%s\n", - (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "", - (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", - (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : ""); - - WRAP_WAIT_WITH_RETURN(dev_priv); - - if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) { - mga_do_dma_flush(dev_priv); - } - - if (lock->flags & _DRM_LOCK_QUIESCENT) { -#if MGA_DMA_DEBUG - int ret = mga_do_wait_for_idle(dev_priv); - if (ret < 0) - DRM_INFO("-EBUSY\n"); - return ret; -#else - return mga_do_wait_for_idle(dev_priv); -#endif - } else { - return 0; - } -} - -int mga_dma_reset(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return mga_do_dma_reset(dev_priv); -} - -/* ================================================================ - * DMA buffer management - */ - -static int mga_dma_get_buffers(struct drm_device * dev, - struct drm_file *file_priv, struct drm_dma * d) -{ - struct drm_buf *buf; - int i; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = mga_freelist_get(dev); - if (!buf) - return -EAGAIN; - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], - &buf->idx, sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], - &buf->total, sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int mga_dma_buffers(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - struct drm_dma *d = data; - int ret = 0; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - d->granted_count = 0; - - if (d->request_count) { - ret = mga_dma_get_buffers(dev, file_priv, d); - } - - return ret; -} - -/** - * Called just before the module is unloaded. - */ -int mga_driver_unload(struct drm_device * dev) -{ - drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); - dev->dev_private = NULL; - - return 0; -} - -/** - * Called when the last opener of the device is closed. - */ -void mga_driver_lastclose(struct drm_device * dev) -{ - mga_do_cleanup_dma(dev, FULL_CLEANUP); -} - -int mga_driver_dma_quiescent(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - return mga_do_wait_for_idle(dev_priv); -} diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h deleted file mode 100644 index 944b50a..0000000 --- a/drivers/char/drm/mga_drm.h +++ /dev/null @@ -1,417 +0,0 @@ -/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- - * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jeff Hartmann - * Keith Whitwell - * - * Rewritten by: - * Gareth Hughes - */ - -#ifndef __MGA_DRM_H__ -#define __MGA_DRM_H__ - -/* WARNING: If you change any of these defines, make sure to change the - * defines in the Xserver file (mga_sarea.h) - */ - -#ifndef __MGA_SAREA_DEFINES__ -#define __MGA_SAREA_DEFINES__ - -/* WARP pipe flags - */ -#define MGA_F 0x1 /* fog */ -#define MGA_A 0x2 /* alpha */ -#define MGA_S 0x4 /* specular */ -#define MGA_T2 0x8 /* multitexture */ - -#define MGA_WARP_TGZ 0 -#define MGA_WARP_TGZF (MGA_F) -#define MGA_WARP_TGZA (MGA_A) -#define MGA_WARP_TGZAF (MGA_F|MGA_A) -#define MGA_WARP_TGZS (MGA_S) -#define MGA_WARP_TGZSF (MGA_S|MGA_F) -#define MGA_WARP_TGZSA (MGA_S|MGA_A) -#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A) -#define MGA_WARP_T2GZ (MGA_T2) -#define MGA_WARP_T2GZF (MGA_T2|MGA_F) -#define MGA_WARP_T2GZA (MGA_T2|MGA_A) -#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F) -#define MGA_WARP_T2GZS (MGA_T2|MGA_S) -#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F) -#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A) -#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A) - -#define MGA_MAX_G200_PIPES 8 /* no multitex */ -#define MGA_MAX_G400_PIPES 16 -#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES -#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */ - -#define MGA_CARD_TYPE_G200 1 -#define MGA_CARD_TYPE_G400 2 -#define MGA_CARD_TYPE_G450 3 /* not currently used */ -#define MGA_CARD_TYPE_G550 4 - -#define MGA_FRONT 0x1 -#define MGA_BACK 0x2 -#define MGA_DEPTH 0x4 - -/* What needs to be changed for the current vertex dma buffer? - */ -#define MGA_UPLOAD_CONTEXT 0x1 -#define MGA_UPLOAD_TEX0 0x2 -#define MGA_UPLOAD_TEX1 0x4 -#define MGA_UPLOAD_PIPE 0x8 -#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */ -#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */ -#define MGA_UPLOAD_2D 0x40 -#define MGA_WAIT_AGE 0x80 /* handled client-side */ -#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ -#if 0 -#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock - quiescent */ -#endif - -/* 32 buffers of 64k each, total 2 meg. - */ -#define MGA_BUFFER_SIZE (1 << 16) -#define MGA_NUM_BUFFERS 128 - -/* Keep these small for testing. - */ -#define MGA_NR_SAREA_CLIPRECTS 8 - -/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 - * regions, subject to a minimum region size of (1<<16) == 64k. - * - * Clients may subdivide regions internally, but when sharing between - * clients, the region size is the minimum granularity. - */ - -#define MGA_CARD_HEAP 0 -#define MGA_AGP_HEAP 1 -#define MGA_NR_TEX_HEAPS 2 -#define MGA_NR_TEX_REGIONS 16 -#define MGA_LOG_MIN_TEX_REGION_SIZE 16 - -#define DRM_MGA_IDLE_RETRY 2048 - -#endif /* __MGA_SAREA_DEFINES__ */ - -/* Setup registers for 3D context - */ -typedef struct { - unsigned int dstorg; - unsigned int maccess; - unsigned int plnwt; - unsigned int dwgctl; - unsigned int alphactrl; - unsigned int fogcolor; - unsigned int wflag; - unsigned int tdualstage0; - unsigned int tdualstage1; - unsigned int fcol; - unsigned int stencil; - unsigned int stencilctl; -} drm_mga_context_regs_t; - -/* Setup registers for 2D, X server - */ -typedef struct { - unsigned int pitch; -} drm_mga_server_regs_t; - -/* Setup registers for each texture unit - */ -typedef struct { - unsigned int texctl; - unsigned int texctl2; - unsigned int texfilter; - unsigned int texbordercol; - unsigned int texorg; - unsigned int texwidth; - unsigned int texheight; - unsigned int texorg1; - unsigned int texorg2; - unsigned int texorg3; - unsigned int texorg4; -} drm_mga_texture_regs_t; - -/* General aging mechanism - */ -typedef struct { - unsigned int head; /* Position of head pointer */ - unsigned int wrap; /* Primary DMA wrap count */ -} drm_mga_age_t; - -typedef struct _drm_mga_sarea { - /* The channel for communication of state information to the kernel - * on firing a vertex dma buffer. - */ - drm_mga_context_regs_t context_state; - drm_mga_server_regs_t server_state; - drm_mga_texture_regs_t tex_state[2]; - unsigned int warp_pipe; - unsigned int dirty; - unsigned int vertsize; - - /* The current cliprects, or a subset thereof. - */ - struct drm_clip_rect boxes[MGA_NR_SAREA_CLIPRECTS]; - unsigned int nbox; - - /* Information about the most recently used 3d drawable. The - * client fills in the req_* fields, the server fills in the - * exported_ fields and puts the cliprects into boxes, above. - * - * The client clears the exported_drawable field before - * clobbering the boxes data. - */ - unsigned int req_drawable; /* the X drawable id */ - unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */ - - unsigned int exported_drawable; - unsigned int exported_index; - unsigned int exported_stamp; - unsigned int exported_buffers; - unsigned int exported_nfront; - unsigned int exported_nback; - int exported_back_x, exported_front_x, exported_w; - int exported_back_y, exported_front_y, exported_h; - struct drm_clip_rect exported_boxes[MGA_NR_SAREA_CLIPRECTS]; - - /* Counters for aging textures and for client-side throttling. - */ - unsigned int status[4]; - unsigned int last_wrap; - - drm_mga_age_t last_frame; - unsigned int last_enqueue; /* last time a buffer was enqueued */ - unsigned int last_dispatch; /* age of the most recently dispatched buffer */ - unsigned int last_quiescent; /* */ - - /* LRU lists for texture memory in agp space and on the card. - */ - struct drm_tex_region texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1]; - unsigned int texAge[MGA_NR_TEX_HEAPS]; - - /* Mechanism to validate card state. - */ - int ctxOwner; -} drm_mga_sarea_t; - -/* MGA specific ioctls - * The device specific ioctl range is 0x40 to 0x79. - */ -#define DRM_MGA_INIT 0x00 -#define DRM_MGA_FLUSH 0x01 -#define DRM_MGA_RESET 0x02 -#define DRM_MGA_SWAP 0x03 -#define DRM_MGA_CLEAR 0x04 -#define DRM_MGA_VERTEX 0x05 -#define DRM_MGA_INDICES 0x06 -#define DRM_MGA_ILOAD 0x07 -#define DRM_MGA_BLIT 0x08 -#define DRM_MGA_GETPARAM 0x09 - -/* 3.2: - * ioctls for operating on fences. - */ -#define DRM_MGA_SET_FENCE 0x0a -#define DRM_MGA_WAIT_FENCE 0x0b -#define DRM_MGA_DMA_BOOTSTRAP 0x0c - -#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) -#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) -#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t) -#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t) -#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t) -#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, uint32_t) -#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, uint32_t) -#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t) - -typedef struct _drm_mga_warp_index { - int installed; - unsigned long phys_addr; - int size; -} drm_mga_warp_index_t; - -typedef struct drm_mga_init { - enum { - MGA_INIT_DMA = 0x01, - MGA_CLEANUP_DMA = 0x02 - } func; - - unsigned long sarea_priv_offset; - - int chipset; - int sgram; - - unsigned int maccess; - - unsigned int fb_cpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - - unsigned int depth_cpp; - unsigned int depth_offset, depth_pitch; - - unsigned int texture_offset[MGA_NR_TEX_HEAPS]; - unsigned int texture_size[MGA_NR_TEX_HEAPS]; - - unsigned long fb_offset; - unsigned long mmio_offset; - unsigned long status_offset; - unsigned long warp_offset; - unsigned long primary_offset; - unsigned long buffers_offset; -} drm_mga_init_t; - -typedef struct drm_mga_dma_bootstrap { - /** - * \name AGP texture region - * - * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will - * be filled in with the actual AGP texture settings. - * - * \warning - * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode - * is zero, it means that PCI memory (most likely through the use of - * an IOMMU) is being used for "AGP" textures. - */ - /*@{ */ - unsigned long texture_handle; /**< Handle used to map AGP textures. */ - uint32_t texture_size; /**< Size of the AGP texture region. */ - /*@} */ - - /** - * Requested size of the primary DMA region. - * - * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be - * filled in with the actual AGP mode. If AGP was not available - */ - uint32_t primary_size; - - /** - * Requested number of secondary DMA buffers. - * - * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be - * filled in with the actual number of secondary DMA buffers - * allocated. Particularly when PCI DMA is used, this may be - * (subtantially) less than the number requested. - */ - uint32_t secondary_bin_count; - - /** - * Requested size of each secondary DMA buffer. - * - * While the kernel \b is free to reduce - * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed - * to reduce dma_mga_dma_bootstrap::secondary_bin_size. - */ - uint32_t secondary_bin_size; - - /** - * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X, - * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is - * zero, it means that PCI DMA should be used, even if AGP is - * possible. - * - * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be - * filled in with the actual AGP mode. If AGP was not available - * (i.e., PCI DMA was used), this value will be zero. - */ - uint32_t agp_mode; - - /** - * Desired AGP GART size, measured in megabytes. - */ - uint8_t agp_size; -} drm_mga_dma_bootstrap_t; - -typedef struct drm_mga_clear { - unsigned int flags; - unsigned int clear_color; - unsigned int clear_depth; - unsigned int color_mask; - unsigned int depth_mask; -} drm_mga_clear_t; - -typedef struct drm_mga_vertex { - int idx; /* buffer to queue */ - int used; /* bytes in use */ - int discard; /* client finished with buffer? */ -} drm_mga_vertex_t; - -typedef struct drm_mga_indices { - int idx; /* buffer to queue */ - unsigned int start; - unsigned int end; - int discard; /* client finished with buffer? */ -} drm_mga_indices_t; - -typedef struct drm_mga_iload { - int idx; - unsigned int dstorg; - unsigned int length; -} drm_mga_iload_t; - -typedef struct _drm_mga_blit { - unsigned int planemask; - unsigned int srcorg; - unsigned int dstorg; - int src_pitch, dst_pitch; - int delta_sx, delta_sy; - int delta_dx, delta_dy; - int height, ydir; /* flip image vertically */ - int source_pitch, dest_pitch; -} drm_mga_blit_t; - -/* 3.1: An ioctl to get parameters that aren't available to the 3d - * client any other way. - */ -#define MGA_PARAM_IRQ_NR 1 - -/* 3.2: Query the actual card type. The DDX only distinguishes between - * G200 chips and non-G200 chips, which it calls G400. It turns out that - * there are some very sublte differences between the G4x0 chips and the G550 - * chips. Using this parameter query, a client-side driver can detect the - * difference between a G4x0 and a G550. - */ -#define MGA_PARAM_CARD_TYPE 2 - -typedef struct drm_mga_getparam { - int param; - void __user *value; -} drm_mga_getparam_t; - -#endif diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c deleted file mode 100644 index 5572939..0000000 --- a/drivers/char/drm/mga_drv.c +++ /dev/null @@ -1,141 +0,0 @@ -/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -#include "drm_pciids.h" - -static int mga_driver_device_is_agp(struct drm_device * dev); - -static struct pci_device_id pciidlist[] = { - mga_PCI_IDS -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | - DRIVER_IRQ_VBL, - .dev_priv_size = sizeof(drm_mga_buf_priv_t), - .load = mga_driver_load, - .unload = mga_driver_unload, - .lastclose = mga_driver_lastclose, - .dma_quiescent = mga_driver_dma_quiescent, - .device_is_agp = mga_driver_device_is_agp, - .vblank_wait = mga_driver_vblank_wait, - .irq_preinstall = mga_driver_irq_preinstall, - .irq_postinstall = mga_driver_irq_postinstall, - .irq_uninstall = mga_driver_irq_uninstall, - .irq_handler = mga_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = mga_ioctls, - .dma_ioctl = mga_dma_buffers, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = mga_compat_ioctl, -#endif - }, - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init mga_init(void) -{ - driver.num_ioctls = mga_max_ioctl; - return drm_init(&driver); -} - -static void __exit mga_exit(void) -{ - drm_exit(&driver); -} - -module_init(mga_init); -module_exit(mga_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); - -/** - * Determine if the device really is AGP or not. - * - * In addition to the usual tests performed by \c drm_device_is_agp, this - * function detects PCI G450 cards that appear to the system exactly like - * AGP G450 cards. - * - * \param dev The device to be tested. - * - * \returns - * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. - */ -static int mga_driver_device_is_agp(struct drm_device * dev) -{ - const struct pci_dev *const pdev = dev->pdev; - - /* There are PCI versions of the G450. These cards have the - * same PCI ID as the AGP G450, but have an additional PCI-to-PCI - * bridge chip. We detect these cards, which are not currently - * supported by this driver, by looking at the device ID of the - * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the - * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the - * device. - */ - - if ((pdev->device == 0x0525) && pdev->bus->self - && (pdev->bus->self->vendor == 0x3388) - && (pdev->bus->self->device == 0x0021)) { - return 0; - } - - return 2; -} diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h deleted file mode 100644 index f6ebd24..0000000 --- a/drivers/char/drm/mga_drv.h +++ /dev/null @@ -1,687 +0,0 @@ -/* mga_drv.h -- Private header for the Matrox G200/G400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#ifndef __MGA_DRV_H__ -#define __MGA_DRV_H__ - -/* General customization: - */ - -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "mga" -#define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20051102" - -#define DRIVER_MAJOR 3 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 - -typedef struct drm_mga_primary_buffer { - u8 *start; - u8 *end; - int size; - - u32 tail; - int space; - volatile long wrapped; - - volatile u32 *status; - - u32 last_flush; - u32 last_wrap; - - u32 high_mark; -} drm_mga_primary_buffer_t; - -typedef struct drm_mga_freelist { - struct drm_mga_freelist *next; - struct drm_mga_freelist *prev; - drm_mga_age_t age; - struct drm_buf *buf; -} drm_mga_freelist_t; - -typedef struct { - drm_mga_freelist_t *list_entry; - int discard; - int dispatched; -} drm_mga_buf_priv_t; - -typedef struct drm_mga_private { - drm_mga_primary_buffer_t prim; - drm_mga_sarea_t *sarea_priv; - - drm_mga_freelist_t *head; - drm_mga_freelist_t *tail; - - unsigned int warp_pipe; - unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES]; - - int chipset; - int usec_timeout; - - /** - * If set, the new DMA initialization sequence was used. This is - * primarilly used to select how the driver should uninitialized its - * internal DMA structures. - */ - int used_new_dma_init; - - /** - * If AGP memory is used for DMA buffers, this will be the value - * \c MGA_PAGPXFER. Otherwise, it will be zero (for a PCI transfer). - */ - u32 dma_access; - - /** - * If AGP memory is used for DMA buffers, this will be the value - * \c MGA_WAGP_ENABLE. Otherwise, it will be zero (for a PCI - * transfer). - */ - u32 wagp_enable; - - /** - * \name MMIO region parameters. - * - * \sa drm_mga_private_t::mmio - */ - /*@{ */ - u32 mmio_base; /**< Bus address of base of MMIO. */ - u32 mmio_size; /**< Size of the MMIO region. */ - /*@} */ - - u32 clear_cmd; - u32 maccess; - - wait_queue_head_t fence_queue; - atomic_t last_fence_retired; - u32 next_fence_to_post; - - unsigned int fb_cpp; - unsigned int front_offset; - unsigned int front_pitch; - unsigned int back_offset; - unsigned int back_pitch; - - unsigned int depth_cpp; - unsigned int depth_offset; - unsigned int depth_pitch; - - unsigned int texture_offset; - unsigned int texture_size; - - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *status; - drm_local_map_t *warp; - drm_local_map_t *primary; - drm_local_map_t *agp_textures; - - unsigned long agp_handle; - unsigned int agp_size; -} drm_mga_private_t; - -extern struct drm_ioctl_desc mga_ioctls[]; -extern int mga_max_ioctl; - - /* mga_dma.c */ -extern int mga_dma_bootstrap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_flush(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_reset(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_buffers(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_driver_load(struct drm_device *dev, unsigned long flags); -extern int mga_driver_unload(struct drm_device * dev); -extern void mga_driver_lastclose(struct drm_device * dev); -extern int mga_driver_dma_quiescent(struct drm_device * dev); - -extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); - -extern void mga_do_dma_flush(drm_mga_private_t * dev_priv); -extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv); -extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); - -extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); - - /* mga_warp.c */ -extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv); -extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); -extern int mga_warp_init(drm_mga_private_t * dev_priv); - - /* mga_irq.c */ -extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); -extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); -extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); -extern void mga_driver_irq_preinstall(struct drm_device * dev); -extern void mga_driver_irq_postinstall(struct drm_device * dev); -extern void mga_driver_irq_uninstall(struct drm_device * dev); -extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() - -#if defined(__linux__) && defined(__alpha__) -#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) -#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg) - -#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg ) -#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg ) - -#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) -#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg))) -#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) - -static inline u32 _MGA_READ(u32 * addr) -{ - DRM_MEMORYBARRIER(); - return *(volatile u32 *)addr; -} -#else -#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg)) -#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg)) -#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val)) -#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val)) -#endif - -#define DWGREG0 0x1c00 -#define DWGREG0_END 0x1dff -#define DWGREG1 0x2c00 -#define DWGREG1_END 0x2dff - -#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) -#define DMAREG0(r) (u8)((r - DWGREG0) >> 2) -#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) -#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) - -/* ================================================================ - * Helper macross... - */ - -#define MGA_EMIT_STATE( dev_priv, dirty ) \ -do { \ - if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \ - if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) { \ - mga_g400_emit_state( dev_priv ); \ - } else { \ - mga_g200_emit_state( dev_priv ); \ - } \ - } \ -} while (0) - -#define WRAP_TEST_WITH_RETURN( dev_priv ) \ -do { \ - if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( mga_is_idle( dev_priv ) ) { \ - mga_do_dma_wrap_end( dev_priv ); \ - } else if ( dev_priv->prim.space < \ - dev_priv->prim.high_mark ) { \ - if ( MGA_DMA_DEBUG ) \ - DRM_INFO( "wrap...\n"); \ - return -EBUSY; \ - } \ - } \ -} while (0) - -#define WRAP_WAIT_WITH_RETURN( dev_priv ) \ -do { \ - if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \ - if ( MGA_DMA_DEBUG ) \ - DRM_INFO( "wrap...\n"); \ - return -EBUSY; \ - } \ - mga_do_dma_wrap_end( dev_priv ); \ - } \ -} while (0) - -/* ================================================================ - * Primary DMA command stream - */ - -#define MGA_VERBOSE 0 - -#define DMA_LOCALS unsigned int write; volatile u8 *prim; - -#define DMA_BLOCK_SIZE (5 * sizeof(u32)) - -#define BEGIN_DMA( n ) \ -do { \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA( %d )\n", (n) ); \ - DRM_INFO( " space=0x%x req=0x%Zx\n", \ - dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ - } \ - prim = dev_priv->prim.start; \ - write = dev_priv->prim.tail; \ -} while (0) - -#define BEGIN_DMA_WRAP() \ -do { \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA()\n" ); \ - DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ - } \ - prim = dev_priv->prim.start; \ - write = dev_priv->prim.tail; \ -} while (0) - -#define ADVANCE_DMA() \ -do { \ - dev_priv->prim.tail = write; \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ - write, dev_priv->prim.space ); \ - } \ -} while (0) - -#define FLUSH_DMA() \ -do { \ - if ( 0 ) { \ - DRM_INFO( "\n" ); \ - DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ - dev_priv->prim.tail, \ - MGA_READ( MGA_PRIMADDRESS ) - \ - dev_priv->primary->offset ); \ - } \ - if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( dev_priv->prim.space < \ - dev_priv->prim.high_mark ) { \ - mga_do_dma_wrap_start( dev_priv ); \ - } else { \ - mga_do_dma_flush( dev_priv ); \ - } \ - } \ -} while (0) - -/* Never use this, always use DMA_BLOCK(...) for primary DMA output. - */ -#define DMA_WRITE( offset, val ) \ -do { \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ - (u32)(val), write + (offset) * sizeof(u32) ); \ - } \ - *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ -} while (0) - -#define DMA_BLOCK( reg0, val0, reg1, val1, reg2, val2, reg3, val3 ) \ -do { \ - DMA_WRITE( 0, ((DMAREG( reg0 ) << 0) | \ - (DMAREG( reg1 ) << 8) | \ - (DMAREG( reg2 ) << 16) | \ - (DMAREG( reg3 ) << 24)) ); \ - DMA_WRITE( 1, val0 ); \ - DMA_WRITE( 2, val1 ); \ - DMA_WRITE( 3, val2 ); \ - DMA_WRITE( 4, val3 ); \ - write += DMA_BLOCK_SIZE; \ -} while (0) - -/* Buffer aging via primary DMA stream head pointer. - */ - -#define SET_AGE( age, h, w ) \ -do { \ - (age)->head = h; \ - (age)->wrap = w; \ -} while (0) - -#define TEST_AGE( age, h, w ) ( (age)->wrap < w || \ - ( (age)->wrap == w && \ - (age)->head < h ) ) - -#define AGE_BUFFER( buf_priv ) \ -do { \ - drm_mga_freelist_t *entry = (buf_priv)->list_entry; \ - if ( (buf_priv)->dispatched ) { \ - entry->age.head = (dev_priv->prim.tail + \ - dev_priv->primary->offset); \ - entry->age.wrap = dev_priv->sarea_priv->last_wrap; \ - } else { \ - entry->age.head = 0; \ - entry->age.wrap = 0; \ - } \ -} while (0) - -#define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \ - MGA_DWGENGSTS | \ - MGA_ENDPRDMASTS) -#define MGA_DMA_IDLE_MASK (MGA_SOFTRAPEN | \ - MGA_ENDPRDMASTS) - -#define MGA_DMA_DEBUG 0 - -/* A reduced set of the mga registers. - */ -#define MGA_CRTC_INDEX 0x1fd4 -#define MGA_CRTC_DATA 0x1fd5 - -/* CRTC11 */ -#define MGA_VINTCLR (1 << 4) -#define MGA_VINTEN (1 << 5) - -#define MGA_ALPHACTRL 0x2c7c -#define MGA_AR0 0x1c60 -#define MGA_AR1 0x1c64 -#define MGA_AR2 0x1c68 -#define MGA_AR3 0x1c6c -#define MGA_AR4 0x1c70 -#define MGA_AR5 0x1c74 -#define MGA_AR6 0x1c78 - -#define MGA_CXBNDRY 0x1c80 -#define MGA_CXLEFT 0x1ca0 -#define MGA_CXRIGHT 0x1ca4 - -#define MGA_DMAPAD 0x1c54 -#define MGA_DSTORG 0x2cb8 -#define MGA_DWGCTL 0x1c00 -# define MGA_OPCOD_MASK (15 << 0) -# define MGA_OPCOD_TRAP (4 << 0) -# define MGA_OPCOD_TEXTURE_TRAP (6 << 0) -# define MGA_OPCOD_BITBLT (8 << 0) -# define MGA_OPCOD_ILOAD (9 << 0) -# define MGA_ATYPE_MASK (7 << 4) -# define MGA_ATYPE_RPL (0 << 4) -# define MGA_ATYPE_RSTR (1 << 4) -# define MGA_ATYPE_ZI (3 << 4) -# define MGA_ATYPE_BLK (4 << 4) -# define MGA_ATYPE_I (7 << 4) -# define MGA_LINEAR (1 << 7) -# define MGA_ZMODE_MASK (7 << 8) -# define MGA_ZMODE_NOZCMP (0 << 8) -# define MGA_ZMODE_ZE (2 << 8) -# define MGA_ZMODE_ZNE (3 << 8) -# define MGA_ZMODE_ZLT (4 << 8) -# define MGA_ZMODE_ZLTE (5 << 8) -# define MGA_ZMODE_ZGT (6 << 8) -# define MGA_ZMODE_ZGTE (7 << 8) -# define MGA_SOLID (1 << 11) -# define MGA_ARZERO (1 << 12) -# define MGA_SGNZERO (1 << 13) -# define MGA_SHIFTZERO (1 << 14) -# define MGA_BOP_MASK (15 << 16) -# define MGA_BOP_ZERO (0 << 16) -# define MGA_BOP_DST (10 << 16) -# define MGA_BOP_SRC (12 << 16) -# define MGA_BOP_ONE (15 << 16) -# define MGA_TRANS_SHIFT 20 -# define MGA_TRANS_MASK (15 << 20) -# define MGA_BLTMOD_MASK (15 << 25) -# define MGA_BLTMOD_BMONOLEF (0 << 25) -# define MGA_BLTMOD_BMONOWF (4 << 25) -# define MGA_BLTMOD_PLAN (1 << 25) -# define MGA_BLTMOD_BFCOL (2 << 25) -# define MGA_BLTMOD_BU32BGR (3 << 25) -# define MGA_BLTMOD_BU32RGB (7 << 25) -# define MGA_BLTMOD_BU24BGR (11 << 25) -# define MGA_BLTMOD_BU24RGB (15 << 25) -# define MGA_PATTERN (1 << 29) -# define MGA_TRANSC (1 << 30) -# define MGA_CLIPDIS (1 << 31) -#define MGA_DWGSYNC 0x2c4c - -#define MGA_FCOL 0x1c24 -#define MGA_FIFOSTATUS 0x1e10 -#define MGA_FOGCOL 0x1cf4 -#define MGA_FXBNDRY 0x1c84 -#define MGA_FXLEFT 0x1ca8 -#define MGA_FXRIGHT 0x1cac - -#define MGA_ICLEAR 0x1e18 -# define MGA_SOFTRAPICLR (1 << 0) -# define MGA_VLINEICLR (1 << 5) -#define MGA_IEN 0x1e1c -# define MGA_SOFTRAPIEN (1 << 0) -# define MGA_VLINEIEN (1 << 5) - -#define MGA_LEN 0x1c5c - -#define MGA_MACCESS 0x1c04 - -#define MGA_PITCH 0x1c8c -#define MGA_PLNWT 0x1c1c -#define MGA_PRIMADDRESS 0x1e58 -# define MGA_DMA_GENERAL (0 << 0) -# define MGA_DMA_BLIT (1 << 0) -# define MGA_DMA_VECTOR (2 << 0) -# define MGA_DMA_VERTEX (3 << 0) -#define MGA_PRIMEND 0x1e5c -# define MGA_PRIMNOSTART (1 << 0) -# define MGA_PAGPXFER (1 << 1) -#define MGA_PRIMPTR 0x1e50 -# define MGA_PRIMPTREN0 (1 << 0) -# define MGA_PRIMPTREN1 (1 << 1) - -#define MGA_RST 0x1e40 -# define MGA_SOFTRESET (1 << 0) -# define MGA_SOFTEXTRST (1 << 1) - -#define MGA_SECADDRESS 0x2c40 -#define MGA_SECEND 0x2c44 -#define MGA_SETUPADDRESS 0x2cd0 -#define MGA_SETUPEND 0x2cd4 -#define MGA_SGN 0x1c58 -#define MGA_SOFTRAP 0x2c48 -#define MGA_SRCORG 0x2cb4 -# define MGA_SRMMAP_MASK (1 << 0) -# define MGA_SRCMAP_FB (0 << 0) -# define MGA_SRCMAP_SYSMEM (1 << 0) -# define MGA_SRCACC_MASK (1 << 1) -# define MGA_SRCACC_PCI (0 << 1) -# define MGA_SRCACC_AGP (1 << 1) -#define MGA_STATUS 0x1e14 -# define MGA_SOFTRAPEN (1 << 0) -# define MGA_VSYNCPEN (1 << 4) -# define MGA_VLINEPEN (1 << 5) -# define MGA_DWGENGSTS (1 << 16) -# define MGA_ENDPRDMASTS (1 << 17) -#define MGA_STENCIL 0x2cc8 -#define MGA_STENCILCTL 0x2ccc - -#define MGA_TDUALSTAGE0 0x2cf8 -#define MGA_TDUALSTAGE1 0x2cfc -#define MGA_TEXBORDERCOL 0x2c5c -#define MGA_TEXCTL 0x2c30 -#define MGA_TEXCTL2 0x2c3c -# define MGA_DUALTEX (1 << 7) -# define MGA_G400_TC2_MAGIC (1 << 15) -# define MGA_MAP1_ENABLE (1 << 31) -#define MGA_TEXFILTER 0x2c58 -#define MGA_TEXHEIGHT 0x2c2c -#define MGA_TEXORG 0x2c24 -# define MGA_TEXORGMAP_MASK (1 << 0) -# define MGA_TEXORGMAP_FB (0 << 0) -# define MGA_TEXORGMAP_SYSMEM (1 << 0) -# define MGA_TEXORGACC_MASK (1 << 1) -# define MGA_TEXORGACC_PCI (0 << 1) -# define MGA_TEXORGACC_AGP (1 << 1) -#define MGA_TEXORG1 0x2ca4 -#define MGA_TEXORG2 0x2ca8 -#define MGA_TEXORG3 0x2cac -#define MGA_TEXORG4 0x2cb0 -#define MGA_TEXTRANS 0x2c34 -#define MGA_TEXTRANSHIGH 0x2c38 -#define MGA_TEXWIDTH 0x2c28 - -#define MGA_WACCEPTSEQ 0x1dd4 -#define MGA_WCODEADDR 0x1e6c -#define MGA_WFLAG 0x1dc4 -#define MGA_WFLAG1 0x1de0 -#define MGA_WFLAGNB 0x1e64 -#define MGA_WFLAGNB1 0x1e08 -#define MGA_WGETMSB 0x1dc8 -#define MGA_WIADDR 0x1dc0 -#define MGA_WIADDR2 0x1dd8 -# define MGA_WMODE_SUSPEND (0 << 0) -# define MGA_WMODE_RESUME (1 << 0) -# define MGA_WMODE_JUMP (2 << 0) -# define MGA_WMODE_START (3 << 0) -# define MGA_WAGP_ENABLE (1 << 2) -#define MGA_WMISC 0x1e70 -# define MGA_WUCODECACHE_ENABLE (1 << 0) -# define MGA_WMASTER_ENABLE (1 << 1) -# define MGA_WCACHEFLUSH_ENABLE (1 << 3) -#define MGA_WVRTXSZ 0x1dcc - -#define MGA_YBOT 0x1c9c -#define MGA_YDST 0x1c90 -#define MGA_YDSTLEN 0x1c88 -#define MGA_YDSTORG 0x1c94 -#define MGA_YTOP 0x1c98 - -#define MGA_ZORG 0x1c0c - -/* This finishes the current batch of commands - */ -#define MGA_EXEC 0x0100 - -/* AGP PLL encoding (for G200 only). - */ -#define MGA_AGP_PLL 0x1e4c -# define MGA_AGP2XPLL_DISABLE (0 << 0) -# define MGA_AGP2XPLL_ENABLE (1 << 0) - -/* Warp registers - */ -#define MGA_WR0 0x2d00 -#define MGA_WR1 0x2d04 -#define MGA_WR2 0x2d08 -#define MGA_WR3 0x2d0c -#define MGA_WR4 0x2d10 -#define MGA_WR5 0x2d14 -#define MGA_WR6 0x2d18 -#define MGA_WR7 0x2d1c -#define MGA_WR8 0x2d20 -#define MGA_WR9 0x2d24 -#define MGA_WR10 0x2d28 -#define MGA_WR11 0x2d2c -#define MGA_WR12 0x2d30 -#define MGA_WR13 0x2d34 -#define MGA_WR14 0x2d38 -#define MGA_WR15 0x2d3c -#define MGA_WR16 0x2d40 -#define MGA_WR17 0x2d44 -#define MGA_WR18 0x2d48 -#define MGA_WR19 0x2d4c -#define MGA_WR20 0x2d50 -#define MGA_WR21 0x2d54 -#define MGA_WR22 0x2d58 -#define MGA_WR23 0x2d5c -#define MGA_WR24 0x2d60 -#define MGA_WR25 0x2d64 -#define MGA_WR26 0x2d68 -#define MGA_WR27 0x2d6c -#define MGA_WR28 0x2d70 -#define MGA_WR29 0x2d74 -#define MGA_WR30 0x2d78 -#define MGA_WR31 0x2d7c -#define MGA_WR32 0x2d80 -#define MGA_WR33 0x2d84 -#define MGA_WR34 0x2d88 -#define MGA_WR35 0x2d8c -#define MGA_WR36 0x2d90 -#define MGA_WR37 0x2d94 -#define MGA_WR38 0x2d98 -#define MGA_WR39 0x2d9c -#define MGA_WR40 0x2da0 -#define MGA_WR41 0x2da4 -#define MGA_WR42 0x2da8 -#define MGA_WR43 0x2dac -#define MGA_WR44 0x2db0 -#define MGA_WR45 0x2db4 -#define MGA_WR46 0x2db8 -#define MGA_WR47 0x2dbc -#define MGA_WR48 0x2dc0 -#define MGA_WR49 0x2dc4 -#define MGA_WR50 0x2dc8 -#define MGA_WR51 0x2dcc -#define MGA_WR52 0x2dd0 -#define MGA_WR53 0x2dd4 -#define MGA_WR54 0x2dd8 -#define MGA_WR55 0x2ddc -#define MGA_WR56 0x2de0 -#define MGA_WR57 0x2de4 -#define MGA_WR58 0x2de8 -#define MGA_WR59 0x2dec -#define MGA_WR60 0x2df0 -#define MGA_WR61 0x2df4 -#define MGA_WR62 0x2df8 -#define MGA_WR63 0x2dfc -# define MGA_G400_WR_MAGIC (1 << 6) -# define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */ - -#define MGA_ILOAD_ALIGN 64 -#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1) - -#define MGA_DWGCTL_FLUSH (MGA_OPCOD_TEXTURE_TRAP | \ - MGA_ATYPE_I | \ - MGA_ZMODE_NOZCMP | \ - MGA_ARZERO | \ - MGA_SGNZERO | \ - MGA_BOP_SRC | \ - (15 << MGA_TRANS_SHIFT)) - -#define MGA_DWGCTL_CLEAR (MGA_OPCOD_TRAP | \ - MGA_ZMODE_NOZCMP | \ - MGA_SOLID | \ - MGA_ARZERO | \ - MGA_SGNZERO | \ - MGA_SHIFTZERO | \ - MGA_BOP_SRC | \ - (0 << MGA_TRANS_SHIFT) | \ - MGA_BLTMOD_BMONOLEF | \ - MGA_TRANSC | \ - MGA_CLIPDIS) - -#define MGA_DWGCTL_COPY (MGA_OPCOD_BITBLT | \ - MGA_ATYPE_RPL | \ - MGA_SGNZERO | \ - MGA_SHIFTZERO | \ - MGA_BOP_SRC | \ - (0 << MGA_TRANS_SHIFT) | \ - MGA_BLTMOD_BFCOL | \ - MGA_CLIPDIS) - -/* Simple idle test. - */ -static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv) -{ - u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; - return (status == MGA_ENDPRDMASTS); -} - -#endif diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c deleted file mode 100644 index 30d0047..0000000 --- a/drivers/char/drm/mga_ioc32.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * \file mga_ioc32.c - * - * 32-bit ioctl compatibility routines for the MGA DRM. - * - * \author Dave Airlie with code from patches by Egbert Eich - * - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Egbert Eich 2003,2004 - * Copyright (C) Dave Airlie 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" - -typedef struct drm32_mga_init { - int func; - u32 sarea_priv_offset; - int chipset; - int sgram; - unsigned int maccess; - unsigned int fb_cpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_cpp; - unsigned int depth_offset, depth_pitch; - unsigned int texture_offset[MGA_NR_TEX_HEAPS]; - unsigned int texture_size[MGA_NR_TEX_HEAPS]; - u32 fb_offset; - u32 mmio_offset; - u32 status_offset; - u32 warp_offset; - u32 primary_offset; - u32 buffers_offset; -} drm_mga_init32_t; - -static int compat_mga_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_mga_init32_t init32; - drm_mga_init_t __user *init; - int err = 0, i; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.chipset, &init->chipset) - || __put_user(init32.sgram, &init->sgram) - || __put_user(init32.maccess, &init->maccess) - || __put_user(init32.fb_cpp, &init->fb_cpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_cpp, &init->depth_cpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.status_offset, &init->status_offset) - || __put_user(init32.warp_offset, &init->warp_offset) - || __put_user(init32.primary_offset, &init->primary_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset)) - return -EFAULT; - - for (i = 0; i < MGA_NR_TEX_HEAPS; i++) { - err |= - __put_user(init32.texture_offset[i], - &init->texture_offset[i]); - err |= - __put_user(init32.texture_size[i], &init->texture_size[i]); - } - if (err) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MGA_INIT, (unsigned long)init); -} - -typedef struct drm_mga_getparam32 { - int param; - u32 value; -} drm_mga_getparam32_t; - -static int compat_mga_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_mga_getparam32_t getparam32; - drm_mga_getparam_t __user *getparam; - - if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) - return -EFAULT; - - getparam = compat_alloc_user_space(sizeof(*getparam)); - if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) - || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, - &getparam->value)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); -} - -typedef struct drm_mga_drm_bootstrap32 { - u32 texture_handle; - u32 texture_size; - u32 primary_size; - u32 secondary_bin_count; - u32 secondary_bin_size; - u32 agp_mode; - u8 agp_size; -} drm_mga_dma_bootstrap32_t; - -static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_mga_dma_bootstrap32_t dma_bootstrap32; - drm_mga_dma_bootstrap_t __user *dma_bootstrap; - int err; - - if (copy_from_user(&dma_bootstrap32, (void __user *)arg, - sizeof(dma_bootstrap32))) - return -EFAULT; - - dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap)); - if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap)) - || __put_user(dma_bootstrap32.texture_handle, - &dma_bootstrap->texture_handle) - || __put_user(dma_bootstrap32.texture_size, - &dma_bootstrap->texture_size) - || __put_user(dma_bootstrap32.primary_size, - &dma_bootstrap->primary_size) - || __put_user(dma_bootstrap32.secondary_bin_count, - &dma_bootstrap->secondary_bin_count) - || __put_user(dma_bootstrap32.secondary_bin_size, - &dma_bootstrap->secondary_bin_size) - || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) - || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) - return -EFAULT; - - err = drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_MGA_DMA_BOOTSTRAP, - (unsigned long)dma_bootstrap); - if (err) - return err; - - if (__get_user(dma_bootstrap32.texture_handle, - &dma_bootstrap->texture_handle) - || __get_user(dma_bootstrap32.texture_size, - &dma_bootstrap->texture_size) - || __get_user(dma_bootstrap32.primary_size, - &dma_bootstrap->primary_size) - || __get_user(dma_bootstrap32.secondary_bin_count, - &dma_bootstrap->secondary_bin_count) - || __get_user(dma_bootstrap32.secondary_bin_size, - &dma_bootstrap->secondary_bin_size) - || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) - || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) - return -EFAULT; - - if (copy_to_user((void __user *)arg, &dma_bootstrap32, - sizeof(dma_bootstrap32))) - return -EFAULT; - - return 0; -} - -drm_ioctl_compat_t *mga_compat_ioctls[] = { - [DRM_MGA_INIT] = compat_mga_init, - [DRM_MGA_GETPARAM] = compat_mga_getparam, - [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) - fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; - - lock_kernel(); /* XXX for now */ - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - - return ret; -} diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c deleted file mode 100644 index 9302cb8..0000000 --- a/drivers/char/drm/mga_irq.c +++ /dev/null @@ -1,148 +0,0 @@ -/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- - * - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - * Eric Anholt - */ - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - int status; - int handled = 0; - - status = MGA_READ(MGA_STATUS); - - /* VBLANK interrupt */ - if (status & MGA_VLINEPEN) { - MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); - atomic_inc(&dev->vbl_received); - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); - handled = 1; - } - - /* SOFTRAP interrupt */ - if (status & MGA_SOFTRAPEN) { - const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); - const u32 prim_end = MGA_READ(MGA_PRIMEND); - - MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); - - /* In addition to clearing the interrupt-pending bit, we - * have to write to MGA_PRIMEND to re-start the DMA operation. - */ - if ((prim_start & ~0x03) != (prim_end & ~0x03)) { - MGA_WRITE(MGA_PRIMEND, prim_end); - } - - atomic_inc(&dev_priv->last_fence_retired); - DRM_WAKEUP(&dev_priv->fence_queue); - handled = 1; - } - - if (handled) { - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) -{ - unsigned int cur_vblank; - int ret = 0; - - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using vertical blanks... - */ - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) - - *sequence) <= (1 << 23))); - - *sequence = cur_vblank; - - return ret; -} - -int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - unsigned int cur_fence; - int ret = 0; - - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using fences. - */ - DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ, - (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) - - *sequence) <= (1 << 23))); - - *sequence = cur_fence; - - return ret; -} - -void mga_driver_irq_preinstall(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - /* Disable *all* interrupts */ - MGA_WRITE(MGA_IEN, 0); - /* Clear bits if they're already high */ - MGA_WRITE(MGA_ICLEAR, ~0); -} - -void mga_driver_irq_postinstall(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); - - /* Turn on vertical blank interrupt and soft trap interrupt. */ - MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); -} - -void mga_driver_irq_uninstall(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - if (!dev_priv) - return; - - /* Disable *all* interrupts */ - MGA_WRITE(MGA_IEN, 0); - - dev->irq_enabled = 0; -} diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c deleted file mode 100644 index d3f8aad..0000000 --- a/drivers/char/drm/mga_state.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*- - * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jeff Hartmann - * Keith Whitwell - * - * Rewritten by: - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -/* ================================================================ - * DMA hardware state programming functions - */ - -static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, - struct drm_clip_rect * box) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - unsigned int pitch = dev_priv->front_pitch; - DMA_LOCALS; - - BEGIN_DMA(2); - - /* Force reset of DWGCTL on G400 (eliminates clip disable bit). - */ - if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { - DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl, - MGA_LEN + MGA_EXEC, 0x80000000, - MGA_DWGCTL, ctx->dwgctl, - MGA_LEN + MGA_EXEC, 0x80000000); - } - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1, - MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - DMA_LOCALS; - - BEGIN_DMA(3); - - DMA_BLOCK(MGA_DSTORG, ctx->dstorg, - MGA_MACCESS, ctx->maccess, - MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - - DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, - MGA_FOGCOL, ctx->fogcolor, - MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); - - DMA_BLOCK(MGA_FCOL, ctx->fcol, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - DMA_LOCALS; - - BEGIN_DMA(4); - - DMA_BLOCK(MGA_DSTORG, ctx->dstorg, - MGA_MACCESS, ctx->maccess, - MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - - DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, - MGA_FOGCOL, ctx->fogcolor, - MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); - - DMA_BLOCK(MGA_WFLAG1, ctx->wflag, - MGA_TDUALSTAGE0, ctx->tdualstage0, - MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol); - - DMA_BLOCK(MGA_STENCIL, ctx->stencil, - MGA_STENCILCTL, ctx->stencilctl, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; - DMA_LOCALS; - - BEGIN_DMA(4); - - DMA_BLOCK(MGA_TEXCTL2, tex->texctl2, - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol); - - DMA_BLOCK(MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - - DMA_BLOCK(MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth); - - DMA_BLOCK(MGA_WR34, tex->texheight, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; - DMA_LOCALS; - -/* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */ -/* tex->texctl, tex->texctl2); */ - - BEGIN_DMA(6); - - DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol); - - DMA_BLOCK(MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - - DMA_BLOCK(MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); - - DMA_BLOCK(MGA_WR57, 0x00000000, - MGA_WR53, 0x00000000, - MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC); - - DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC, - MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, - MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, - MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; - DMA_LOCALS; - -/* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */ -/* tex->texctl, tex->texctl2); */ - - BEGIN_DMA(5); - - DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 | - MGA_MAP1_ENABLE | - MGA_G400_TC2_MAGIC), - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol); - - DMA_BLOCK(MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - - DMA_BLOCK(MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); - - DMA_BLOCK(MGA_WR57, 0x00000000, - MGA_WR53, 0x00000000, - MGA_WR61, 0x00000000, - MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC); - - DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff, - MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int pipe = sarea_priv->warp_pipe; - DMA_LOCALS; - - BEGIN_DMA(3); - - DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND, - MGA_WVRTXSZ, 0x00000007, - MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000); - - DMA_BLOCK(MGA_WR25, 0x00000100, - MGA_WR34, 0x00000000, - MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff); - - /* Padding required to to hardware bug. - */ - DMA_BLOCK(MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | - MGA_WMODE_START | dev_priv->wagp_enable)); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int pipe = sarea_priv->warp_pipe; - DMA_LOCALS; - -/* printk("mga_g400_emit_pipe %x\n", pipe); */ - - BEGIN_DMA(10); - - DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - if (pipe & MGA_T2) { - DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x1e000000); - } else { - if (dev_priv->warp_pipe & MGA_T2) { - /* Flush the WARP pipe */ - DMA_BLOCK(MGA_YDST, 0x00000000, - MGA_FXLEFT, 0x00000000, - MGA_FXRIGHT, 0x00000001, - MGA_DWGCTL, MGA_DWGCTL_FLUSH); - - DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001, - MGA_DWGSYNC, 0x00007000, - MGA_TEXCTL2, MGA_G400_TC2_MAGIC, - MGA_LEN + MGA_EXEC, 0x00000000); - - DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX | - MGA_G400_TC2_MAGIC), - MGA_LEN + MGA_EXEC, 0x00000000, - MGA_TEXCTL2, MGA_G400_TC2_MAGIC, - MGA_DMAPAD, 0x00000000); - } - - DMA_BLOCK(MGA_WVRTXSZ, 0x00001807, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x18000000); - } - - DMA_BLOCK(MGA_WFLAG, 0x00000000, - MGA_WFLAG1, 0x00000000, - MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0 */ - MGA_WR57, 0x00000000, /* tex0 */ - MGA_WR53, 0x00000000, /* tex1 */ - MGA_WR61, 0x00000000); /* tex1 */ - - DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ - MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ - MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ - MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height */ - - /* Padding required to to hardware bug */ - DMA_BLOCK(MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | - MGA_WMODE_START | dev_priv->wagp_enable)); - - ADVANCE_DMA(); -} - -static void mga_g200_emit_state(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { - mga_g200_emit_pipe(dev_priv); - dev_priv->warp_pipe = sarea_priv->warp_pipe; - } - - if (dirty & MGA_UPLOAD_CONTEXT) { - mga_g200_emit_context(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; - } - - if (dirty & MGA_UPLOAD_TEX0) { - mga_g200_emit_tex0(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; - } -} - -static void mga_g400_emit_state(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - int multitex = sarea_priv->warp_pipe & MGA_T2; - - if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { - mga_g400_emit_pipe(dev_priv); - dev_priv->warp_pipe = sarea_priv->warp_pipe; - } - - if (dirty & MGA_UPLOAD_CONTEXT) { - mga_g400_emit_context(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; - } - - if (dirty & MGA_UPLOAD_TEX0) { - mga_g400_emit_tex0(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; - } - - if ((dirty & MGA_UPLOAD_TEX1) && multitex) { - mga_g400_emit_tex1(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; - } -} - -/* ================================================================ - * SAREA state verification - */ - -/* Disallow all write destinations except the front and backbuffer. - */ -static int mga_verify_context(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - - if (ctx->dstorg != dev_priv->front_offset && - ctx->dstorg != dev_priv->back_offset) { - DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n", - ctx->dstorg, dev_priv->front_offset, - dev_priv->back_offset); - ctx->dstorg = 0; - return -EINVAL; - } - - return 0; -} - -/* Disallow texture reads from PCI space. - */ -static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; - unsigned int org; - - org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK); - - if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) { - DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit); - tex->texorg = 0; - return -EINVAL; - } - - return 0; -} - -static int mga_verify_state(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - int ret = 0; - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - if (dirty & MGA_UPLOAD_CONTEXT) - ret |= mga_verify_context(dev_priv); - - if (dirty & MGA_UPLOAD_TEX0) - ret |= mga_verify_tex(dev_priv, 0); - - if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { - if (dirty & MGA_UPLOAD_TEX1) - ret |= mga_verify_tex(dev_priv, 1); - - if (dirty & MGA_UPLOAD_PIPE) - ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES); - } else { - if (dirty & MGA_UPLOAD_PIPE) - ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES); - } - - return (ret == 0); -} - -static int mga_verify_iload(drm_mga_private_t * dev_priv, - unsigned int dstorg, unsigned int length) -{ - if (dstorg < dev_priv->texture_offset || - dstorg + length > (dev_priv->texture_offset + - dev_priv->texture_size)) { - DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg); - return -EINVAL; - } - - if (length & MGA_ILOAD_MASK) { - DRM_ERROR("*** bad iload length: 0x%x\n", - length & MGA_ILOAD_MASK); - return -EINVAL; - } - - return 0; -} - -static int mga_verify_blit(drm_mga_private_t * dev_priv, - unsigned int srcorg, unsigned int dstorg) -{ - if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || - (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) { - DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg); - return -EINVAL; - } - return 0; -} - -/* ================================================================ - * - */ - -static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * clear) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - int i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - ADVANCE_DMA(); - - for (i = 0; i < nbox; i++) { - struct drm_clip_rect *box = &pbox[i]; - u32 height = box->y2 - box->y1; - - DRM_DEBUG(" from=%d,%d to=%d,%d\n", - box->x1, box->y1, box->x2, box->y2); - - if (clear->flags & MGA_FRONT) { - BEGIN_DMA(2); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->color_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_color, - MGA_DSTORG, dev_priv->front_offset, - MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); - - ADVANCE_DMA(); - } - - if (clear->flags & MGA_BACK) { - BEGIN_DMA(2); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->color_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_color, - MGA_DSTORG, dev_priv->back_offset, - MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); - - ADVANCE_DMA(); - } - - if (clear->flags & MGA_DEPTH) { - BEGIN_DMA(2); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->depth_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_depth, - MGA_DSTORG, dev_priv->depth_offset, - MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); - - ADVANCE_DMA(); - } - - } - - BEGIN_DMA(1); - - /* Force reset of DWGCTL */ - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - - ADVANCE_DMA(); - - FLUSH_DMA(); -} - -static void mga_dma_dispatch_swap(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - int i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - sarea_priv->last_frame.head = dev_priv->prim.tail; - sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; - - BEGIN_DMA(4 + nbox); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset, - MGA_MACCESS, dev_priv->maccess, - MGA_SRCORG, dev_priv->back_offset, - MGA_AR5, dev_priv->front_pitch); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY); - - for (i = 0; i < nbox; i++) { - struct drm_clip_rect *box = &pbox[i]; - u32 height = box->y2 - box->y1; - u32 start = box->y1 * dev_priv->front_pitch; - - DRM_DEBUG(" from=%d,%d to=%d,%d\n", - box->x1, box->y1, box->x2, box->y2); - - DMA_BLOCK(MGA_AR0, start + box->x2 - 1, - MGA_AR3, start + box->x1, - MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, - MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height); - } - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl); - - ADVANCE_DMA(); - - FLUSH_DMA(); - - DRM_DEBUG("... done.\n"); -} - -static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 address = (u32) buf->bus_address; - u32 length = (u32) buf->used; - int i = 0; - DMA_LOCALS; - DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); - - if (buf->used) { - buf_priv->dispatched = 1; - - MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); - - do { - if (i < sarea_priv->nbox) { - mga_emit_clip_rect(dev_priv, - &sarea_priv->boxes[i]); - } - - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_SECADDRESS, (address | - MGA_DMA_VERTEX), - MGA_SECEND, ((address + length) | - dev_priv->dma_access)); - - ADVANCE_DMA(); - } while (++i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - AGE_BUFFER(buf_priv); - buf->pending = 0; - buf->used = 0; - buf_priv->dispatched = 0; - - mga_freelist_put(dev, buf); - } - - FLUSH_DMA(); -} - -static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf, - unsigned int start, unsigned int end) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 address = (u32) buf->bus_address; - int i = 0; - DMA_LOCALS; - DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end); - - if (start != end) { - buf_priv->dispatched = 1; - - MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); - - do { - if (i < sarea_priv->nbox) { - mga_emit_clip_rect(dev_priv, - &sarea_priv->boxes[i]); - } - - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_SETUPADDRESS, address + start, - MGA_SETUPEND, ((address + end) | - dev_priv->dma_access)); - - ADVANCE_DMA(); - } while (++i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - AGE_BUFFER(buf_priv); - buf->pending = 0; - buf->used = 0; - buf_priv->dispatched = 0; - - mga_freelist_put(dev, buf); - } - - FLUSH_DMA(); -} - -/* This copies a 64 byte aligned agp region to the frambuffer with a - * standard blit, the ioctl needs to do checking. - */ -static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf, - unsigned int dstorg, unsigned int length) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; - u32 srcorg = - buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; - u32 y2; - DMA_LOCALS; - DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); - - y2 = length / 64; - - BEGIN_DMA(5); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - DMA_BLOCK(MGA_DSTORG, dstorg, - MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64); - - DMA_BLOCK(MGA_PITCH, 64, - MGA_PLNWT, 0xffffffff, - MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY); - - DMA_BLOCK(MGA_AR0, 63, - MGA_AR3, 0, - MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2); - - DMA_BLOCK(MGA_PLNWT, ctx->plnwt, - MGA_SRCORG, dev_priv->front_offset, - MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000); - - ADVANCE_DMA(); - - AGE_BUFFER(buf_priv); - - buf->pending = 0; - buf->used = 0; - buf_priv->dispatched = 0; - - mga_freelist_put(dev, buf); - - FLUSH_DMA(); -} - -static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - u32 scandir = 0, i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_DMA(4 + nbox); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY, - MGA_PLNWT, blit->planemask, - MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg); - - DMA_BLOCK(MGA_SGN, scandir, - MGA_MACCESS, dev_priv->maccess, - MGA_AR5, blit->ydir * blit->src_pitch, - MGA_PITCH, blit->dst_pitch); - - for (i = 0; i < nbox; i++) { - int srcx = pbox[i].x1 + blit->delta_sx; - int srcy = pbox[i].y1 + blit->delta_sy; - int dstx = pbox[i].x1 + blit->delta_dx; - int dsty = pbox[i].y1 + blit->delta_dy; - int h = pbox[i].y2 - pbox[i].y1; - int w = pbox[i].x2 - pbox[i].x1 - 1; - int start; - - if (blit->ydir == -1) { - srcy = blit->height - srcy - 1; - } - - start = srcy * blit->src_pitch + srcx; - - DMA_BLOCK(MGA_AR0, start + w, - MGA_AR3, start, - MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), - MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h); - } - - /* Do something to flush AGP? - */ - - /* Force reset of DWGCTL */ - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl); - - ADVANCE_DMA(); -} - -/* ================================================================ - * - */ - -static int mga_dma_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_clear_t *clear = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_clear(dev, clear); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_swap(dev); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (vertex->idx < 0 || vertex->idx > dma->buf_count) - return -EINVAL; - buf = dma->buflist[vertex->idx]; - buf_priv = buf->dev_private; - - buf->used = vertex->used; - buf_priv->discard = vertex->discard; - - if (!mga_verify_state(dev_priv)) { - if (vertex->discard) { - if (buf_priv->dispatched == 1) - AGE_BUFFER(buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_vertex(dev, buf); - - return 0; -} - -static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_indices_t *indices = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (indices->idx < 0 || indices->idx > dma->buf_count) - return -EINVAL; - - buf = dma->buflist[indices->idx]; - buf_priv = buf->dev_private; - - buf_priv->discard = indices->discard; - - if (!mga_verify_state(dev_priv)) { - if (indices->discard) { - if (buf_priv->dispatched == 1) - AGE_BUFFER(buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_indices(dev, buf, indices->start, indices->end); - - return 0; -} - -static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_mga_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_iload_t *iload = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -#if 0 - if (mga_do_wait_for_idle(dev_priv) < 0) { - if (MGA_DMA_DEBUG) - DRM_INFO("-EBUSY\n"); - return -EBUSY; - } -#endif - if (iload->idx < 0 || iload->idx > dma->buf_count) - return -EINVAL; - - buf = dma->buflist[iload->idx]; - buf_priv = buf->dev_private; - - if (mga_verify_iload(dev_priv, iload->dstorg, iload->length)) { - mga_freelist_put(dev, buf); - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_iload(dev, buf, iload->dstorg, iload->length); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_blit_t *blit = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - if (mga_verify_blit(dev_priv, blit->srcorg, blit->dstorg)) - return -EINVAL; - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_blit(dev, blit); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_getparam_t *param = data; - int value; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - switch (param->param) { - case MGA_PARAM_IRQ_NR: - value = dev->irq; - break; - case MGA_PARAM_CARD_TYPE: - value = dev_priv->chipset; - break; - default: - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - u32 *fence = data; - DMA_LOCALS; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - /* I would normal do this assignment in the declaration of fence, - * but dev_priv may be NULL. - */ - - *fence = dev_priv->next_fence_to_post; - dev_priv->next_fence_to_post++; - - BEGIN_DMA(1); - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000); - ADVANCE_DMA(); - - return 0; -} - -static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file * -file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - u32 *fence = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - mga_driver_fence_wait(dev, fence); - return 0; -} - -struct drm_ioctl_desc mga_ioctls[] = { - DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), - DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -}; - -int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); diff --git a/drivers/char/drm/mga_ucode.h b/drivers/char/drm/mga_ucode.h deleted file mode 100644 index b611e27..0000000 --- a/drivers/char/drm/mga_ucode.h +++ /dev/null @@ -1,11645 +0,0 @@ -/* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*- - * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com - * - * Copyright 1999 Matrox Graphics Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Kernel-based WARP engine management: - * Gareth Hughes - */ - -/* - * WARP pipes are named according to the functions they perform, where: - * - * - T stands for computation of texture stage 0 - * - T2 stands for computation of both texture stage 0 and texture stage 1 - * - G stands for computation of triangle intensity (Gouraud interpolation) - * - Z stands for computation of Z buffer interpolation - * - S stands for computation of specular highlight - * - A stands for computation of the alpha channel - * - F stands for computation of vertex fog interpolation - */ - -static unsigned char warp_g200_tgz[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x72, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x60, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x03, 0x80, 0x0A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x57, 0x39, 0x20, 0xE9, - 0x28, 0x19, 0x60, 0xEC, - - 0x2B, 0x32, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0xB3, 0x05, - 0x00, 0xE0, - 0x16, 0x28, 0x20, 0xE9, - - 0x23, 0x3B, 0x33, 0xAD, - 0x1E, 0x2B, 0x20, 0xE9, - - 0x1C, 0x80, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x85, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x84, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x82, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x7F, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgza[] = { - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x7D, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x6B, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x2D, 0x44, 0x4C, 0xB6, - 0x25, 0x44, 0x54, 0xB6, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x2D, 0x20, - 0x25, 0x20, - 0x07, 0xC0, 0x44, 0xC6, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x1F, 0x62, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x3F, 0x3D, 0x5D, 0x9F, - 0x00, 0xE0, - 0x07, 0x20, - - 0x00, 0x80, 0x00, 0xE8, - 0x28, 0x19, 0x60, 0xEC, - - 0xB3, 0x05, - 0x00, 0xE0, - 0x00, 0x80, 0x00, 0xE8, - - 0x23, 0x3B, 0x33, 0xAD, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0x26, 0x1F, 0xDF, - 0x9D, 0x1F, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x9E, 0x3F, 0x4F, 0xE9, - - 0x07, 0x07, 0x1F, 0xAF, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x9C, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x7A, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x79, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x77, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x74, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgzaf[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x83, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x21, 0x45, 0x80, 0xE8, - 0x1A, 0x4D, 0x80, 0xE8, - - 0x31, 0x55, 0x80, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x6F, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0D, 0x21, 0x1A, 0xB6, - 0x05, 0x21, 0x31, 0xB6, - - 0x2D, 0x44, 0x4C, 0xB6, - 0x25, 0x44, 0x54, 0xB6, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x0D, 0x20, - 0x05, 0x20, - 0x2F, 0xC0, 0x21, 0xC6, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x00, 0xE0, - 0x25, 0x20, - 0x07, 0xC0, 0x44, 0xC6, - - 0x17, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x2D, 0x20, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0xE0, - 0x2F, 0x20, - - 0x1F, 0x62, 0x57, 0x9F, - 0x00, 0xE0, - 0x07, 0x20, - - 0x3F, 0x3D, 0x5D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x28, 0x19, 0x60, 0xEC, - - 0xB3, 0x05, - 0x00, 0xE0, - 0x17, 0x26, 0x17, 0xDF, - - 0x23, 0x3B, 0x33, 0xAD, - 0x35, 0x17, 0x4F, 0xE9, - - 0x1F, 0x26, 0x1F, 0xDF, - 0x9D, 0x1F, 0x4F, 0xE9, - - 0x9E, 0x3F, 0x4F, 0xE9, - 0x39, 0x37, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x17, 0xAF, - 0x00, 0x80, 0x00, 0xE8, - - 0x07, 0x07, 0x1F, 0xAF, - 0x00, 0x80, 0x00, 0xE8, - - 0x31, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x9C, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x74, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x73, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x71, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x6E, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgzf[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x7F, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x21, 0x45, 0x80, 0xE8, - 0x1A, 0x4D, 0x80, 0xE8, - - 0x31, 0x55, 0x80, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x6B, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0D, 0x21, 0x1A, 0xB6, - 0x05, 0x21, 0x31, 0xB6, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x0D, 0x20, - 0x05, 0x20, - 0x2F, 0xC0, 0x21, 0xC6, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x17, 0x50, 0x56, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0xE0, - 0x2F, 0x20, - - 0x00, 0x80, 0x00, 0xE8, - 0x28, 0x19, 0x60, 0xEC, - - 0xB3, 0x05, - 0x00, 0xE0, - 0x00, 0x80, 0x00, 0xE8, - - 0x23, 0x3B, 0x33, 0xAD, - 0x00, 0x80, 0x00, 0xE8, - - 0x17, 0x26, 0x17, 0xDF, - 0x35, 0x17, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x39, 0x37, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x17, 0xAF, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x31, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x78, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x77, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x75, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x72, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgzs[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x8B, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x21, 0x45, 0x80, 0xE8, - 0x1A, 0x4D, 0x80, 0xE8, - - 0x31, 0x55, 0x80, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x77, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x2D, 0x21, 0x1A, 0xB0, - 0x25, 0x21, 0x31, 0xB0, - - 0x0D, 0x21, 0x1A, 0xB2, - 0x05, 0x21, 0x31, 0xB2, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x2D, 0x20, - 0x25, 0x20, - 0x05, 0x20, - 0x0D, 0x20, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x2F, 0xC0, 0x21, 0xC0, - - 0x16, 0x42, 0x56, 0x9F, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x1E, 0x62, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x21, 0x31, 0xB4, - 0x2D, 0x21, 0x1A, 0xB4, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0x05, - 0x00, 0xE0, - 0x28, 0x19, 0x60, 0xEC, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0xE0, - 0x2F, 0x20, - - 0x23, 0x3B, 0x33, 0xAD, - 0x1E, 0x26, 0x1E, 0xDF, - - 0xA7, 0x1E, 0x4F, 0xE9, - 0x17, 0x26, 0x16, 0xDF, - - 0x2D, 0x20, - 0x00, 0xE0, - 0xA8, 0x3F, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x1E, 0xAF, - 0x25, 0x20, - 0x00, 0xE0, - - 0xA4, 0x16, 0x4F, 0xE9, - 0x0F, 0xC0, 0x21, 0xC2, - - 0xA6, 0x80, 0x4F, 0xE9, - 0x1F, 0x62, 0x57, 0x9F, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0xE0, - 0x8F, 0x20, - - 0xA5, 0x37, 0x4F, 0xE9, - 0x0F, 0x17, 0x0F, 0xAF, - - 0x06, 0xC0, 0x21, 0xC4, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0xA3, 0x80, 0x4F, 0xE9, - - 0x06, 0x20, - 0x00, 0xE0, - 0x1F, 0x26, 0x1F, 0xDF, - - 0xA1, 0x1F, 0x4F, 0xE9, - 0xA2, 0x3F, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x06, 0x06, 0x1F, 0xAF, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x6C, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x6B, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x69, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgzsa[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x8F, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x21, 0x45, 0x80, 0xE8, - 0x1A, 0x4D, 0x80, 0xE8, - - 0x31, 0x55, 0x80, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x7B, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x2D, 0x21, 0x1A, 0xB0, - 0x25, 0x21, 0x31, 0xB0, - - 0x0D, 0x21, 0x1A, 0xB2, - 0x05, 0x21, 0x31, 0xB2, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x2D, 0x20, - 0x25, 0x20, - 0x05, 0x20, - 0x0D, 0x20, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x2F, 0xC0, 0x21, 0xC0, - - 0x16, 0x42, 0x56, 0x9F, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x1E, 0x62, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x21, 0x31, 0xB4, - 0x2D, 0x21, 0x1A, 0xB4, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0x05, - 0x00, 0xE0, - 0x28, 0x19, 0x60, 0xEC, - - 0x0D, 0x44, 0x4C, 0xB6, - 0x05, 0x44, 0x54, 0xB6, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0xE0, - 0x2F, 0x20, - - 0x23, 0x3B, 0x33, 0xAD, - 0x1E, 0x26, 0x1E, 0xDF, - - 0xA7, 0x1E, 0x4F, 0xE9, - 0x17, 0x26, 0x16, 0xDF, - - 0x2D, 0x20, - 0x00, 0xE0, - 0xA8, 0x3F, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x1E, 0xAF, - 0x25, 0x20, - 0x00, 0xE0, - - 0xA4, 0x16, 0x4F, 0xE9, - 0x0F, 0xC0, 0x21, 0xC2, - - 0xA6, 0x80, 0x4F, 0xE9, - 0x1F, 0x62, 0x57, 0x9F, - - 0x0D, 0x20, - 0x05, 0x20, - 0x00, 0x80, 0x00, 0xE8, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0xE0, - 0x0F, 0x20, - - 0x17, 0x50, 0x56, 0x9F, - 0xA5, 0x37, 0x4F, 0xE9, - - 0x06, 0xC0, 0x21, 0xC4, - 0x0F, 0x17, 0x0F, 0xAF, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x2F, 0xC0, 0x44, 0xC6, - 0xA3, 0x80, 0x4F, 0xE9, - - 0x06, 0x20, - 0x00, 0xE0, - 0x1F, 0x26, 0x1F, 0xDF, - - 0x17, 0x26, 0x17, 0xDF, - 0x9D, 0x17, 0x4F, 0xE9, - - 0xA1, 0x1F, 0x4F, 0xE9, - 0xA2, 0x3F, 0x4F, 0xE9, - - 0x06, 0x06, 0x1F, 0xAF, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x9E, 0x37, 0x4F, 0xE9, - 0x2F, 0x17, 0x2F, 0xAF, - - 0xA0, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x9C, 0x80, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x68, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x67, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x65, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x62, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgzsaf[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x94, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x21, 0x45, 0x80, 0xE8, - 0x1A, 0x4D, 0x80, 0xE8, - - 0x31, 0x55, 0x80, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x80, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x2D, 0x21, 0x1A, 0xB0, - 0x25, 0x21, 0x31, 0xB0, - - 0x0D, 0x21, 0x1A, 0xB2, - 0x05, 0x21, 0x31, 0xB2, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x2D, 0x20, - 0x25, 0x20, - 0x05, 0x20, - 0x0D, 0x20, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x2F, 0xC0, 0x21, 0xC0, - - 0x16, 0x42, 0x56, 0x9F, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x1E, 0x62, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x21, 0x31, 0xB4, - 0x2D, 0x21, 0x1A, 0xB4, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0x05, - 0x00, 0xE0, - 0x28, 0x19, 0x60, 0xEC, - - 0x0D, 0x21, 0x1A, 0xB6, - 0x05, 0x21, 0x31, 0xB6, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0xE0, - 0x2F, 0x20, - - 0x23, 0x3B, 0x33, 0xAD, - 0x1E, 0x26, 0x1E, 0xDF, - - 0xA7, 0x1E, 0x4F, 0xE9, - 0x17, 0x26, 0x16, 0xDF, - - 0x2D, 0x20, - 0x00, 0xE0, - 0xA8, 0x3F, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x1E, 0xAF, - 0x25, 0x20, - 0x00, 0xE0, - - 0xA4, 0x16, 0x4F, 0xE9, - 0x0F, 0xC0, 0x21, 0xC2, - - 0xA6, 0x80, 0x4F, 0xE9, - 0x1F, 0x62, 0x57, 0x9F, - - 0x0D, 0x20, - 0x05, 0x20, - 0x2F, 0xC0, 0x21, 0xC6, - - 0x2D, 0x44, 0x4C, 0xB6, - 0x25, 0x44, 0x54, 0xB6, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0xE0, - 0x0F, 0x20, - - 0x2D, 0x20, - 0x25, 0x20, - 0x07, 0xC0, 0x44, 0xC6, - - 0x17, 0x50, 0x56, 0x9F, - 0xA5, 0x37, 0x4F, 0xE9, - - 0x06, 0xC0, 0x21, 0xC4, - 0x0F, 0x17, 0x0F, 0xAF, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x1E, 0x62, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x3E, 0x3D, 0x5D, 0x9F, - 0x00, 0xE0, - 0x07, 0x20, - - 0x2F, 0x20, - 0x00, 0xE0, - 0xA3, 0x0F, 0x4F, 0xE9, - - 0x06, 0x20, - 0x00, 0xE0, - 0x1F, 0x26, 0x1F, 0xDF, - - 0x17, 0x26, 0x17, 0xDF, - 0xA1, 0x1F, 0x4F, 0xE9, - - 0x1E, 0x26, 0x1E, 0xDF, - 0x9D, 0x1E, 0x4F, 0xE9, - - 0x35, 0x17, 0x4F, 0xE9, - 0xA2, 0x3F, 0x4F, 0xE9, - - 0x06, 0x06, 0x1F, 0xAF, - 0x39, 0x37, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x17, 0xAF, - 0x07, 0x07, 0x1E, 0xAF, - - 0xA0, 0x80, 0x4F, 0xE9, - 0x9E, 0x3E, 0x4F, 0xE9, - - 0x31, 0x80, 0x4F, 0xE9, - 0x9C, 0x80, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x63, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x62, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x60, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x5D, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g200_tgzsf[] = { - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x98, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x81, 0x04, - 0x89, 0x04, - 0x01, 0x04, - 0x09, 0x04, - - 0xC9, 0x41, 0xC0, 0xEC, - 0x11, 0x04, - 0x00, 0xE0, - - 0x41, 0xCC, 0x41, 0xCD, - 0x49, 0xCC, 0x49, 0xCD, - - 0xD1, 0x41, 0xC0, 0xEC, - 0x51, 0xCC, 0x51, 0xCD, - - 0x80, 0x04, - 0x10, 0x04, - 0x08, 0x04, - 0x00, 0xE0, - - 0x00, 0xCC, 0xC0, 0xCD, - 0xD1, 0x49, 0xC0, 0xEC, - - 0x8A, 0x1F, 0x20, 0xE9, - 0x8B, 0x3F, 0x20, 0xE9, - - 0x41, 0x3C, 0x41, 0xAD, - 0x49, 0x3C, 0x49, 0xAD, - - 0x10, 0xCC, 0x10, 0xCD, - 0x08, 0xCC, 0x08, 0xCD, - - 0xB9, 0x41, 0x49, 0xBB, - 0x1F, 0xF0, 0x41, 0xCD, - - 0x51, 0x3C, 0x51, 0xAD, - 0x00, 0x98, 0x80, 0xE9, - - 0x8F, 0x80, 0x07, 0xEA, - 0x24, 0x1F, 0x20, 0xE9, - - 0x21, 0x45, 0x80, 0xE8, - 0x1A, 0x4D, 0x80, 0xE8, - - 0x31, 0x55, 0x80, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0x41, 0x49, 0xBD, - 0x1D, 0x41, 0x51, 0xBD, - - 0x2E, 0x41, 0x2A, 0xB8, - 0x34, 0x53, 0xA0, 0xE8, - - 0x15, 0x30, - 0x1D, 0x30, - 0x58, 0xE3, - 0x00, 0xE0, - - 0xB5, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x24, 0x43, 0xA0, 0xE8, - 0x2C, 0x4B, 0xA0, 0xE8, - - 0x15, 0x72, - 0x09, 0xE3, - 0x00, 0xE0, - 0x1D, 0x72, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0x97, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x6C, 0x64, 0xC8, 0xEC, - 0x98, 0xE1, - 0xB5, 0x05, - - 0xBD, 0x05, - 0x2E, 0x30, - 0x32, 0xC0, 0xA0, 0xE8, - - 0x33, 0xC0, 0xA0, 0xE8, - 0x74, 0x64, 0xC8, 0xEC, - - 0x40, 0x3C, 0x40, 0xAD, - 0x32, 0x6A, - 0x2A, 0x30, - - 0x20, 0x73, - 0x33, 0x6A, - 0x00, 0xE0, - 0x28, 0x73, - - 0x1C, 0x72, - 0x83, 0xE2, - 0x7B, 0x80, 0x15, 0xEA, - - 0xB8, 0x3D, 0x28, 0xDF, - 0x30, 0x35, 0x20, 0xDF, - - 0x40, 0x30, - 0x00, 0xE0, - 0xCC, 0xE2, - 0x64, 0x72, - - 0x25, 0x42, 0x52, 0xBF, - 0x2D, 0x42, 0x4A, 0xBF, - - 0x30, 0x2E, 0x30, 0xDF, - 0x38, 0x2E, 0x38, 0xDF, - - 0x18, 0x1D, 0x45, 0xE9, - 0x1E, 0x15, 0x45, 0xE9, - - 0x2B, 0x49, 0x51, 0xBD, - 0x00, 0xE0, - 0x1F, 0x73, - - 0x38, 0x38, 0x40, 0xAF, - 0x30, 0x30, 0x40, 0xAF, - - 0x24, 0x1F, 0x24, 0xDF, - 0x1D, 0x32, 0x20, 0xE9, - - 0x2C, 0x1F, 0x2C, 0xDF, - 0x1A, 0x33, 0x20, 0xE9, - - 0xB0, 0x10, - 0x08, 0xE3, - 0x40, 0x10, - 0xB8, 0x10, - - 0x26, 0xF0, 0x30, 0xCD, - 0x2F, 0xF0, 0x38, 0xCD, - - 0x2B, 0x80, 0x20, 0xE9, - 0x2A, 0x80, 0x20, 0xE9, - - 0xA6, 0x20, - 0x88, 0xE2, - 0x00, 0xE0, - 0xAF, 0x20, - - 0x28, 0x2A, 0x26, 0xAF, - 0x20, 0x2A, 0xC0, 0xAF, - - 0x34, 0x1F, 0x34, 0xDF, - 0x46, 0x24, 0x46, 0xDF, - - 0x28, 0x30, 0x80, 0xBF, - 0x20, 0x38, 0x80, 0xBF, - - 0x47, 0x24, 0x47, 0xDF, - 0x4E, 0x2C, 0x4E, 0xDF, - - 0x4F, 0x2C, 0x4F, 0xDF, - 0x56, 0x34, 0x56, 0xDF, - - 0x28, 0x15, 0x28, 0xDF, - 0x20, 0x1D, 0x20, 0xDF, - - 0x57, 0x34, 0x57, 0xDF, - 0x00, 0xE0, - 0x1D, 0x05, - - 0x04, 0x80, 0x10, 0xEA, - 0x89, 0xE2, - 0x2B, 0x30, - - 0x3F, 0xC1, 0x1D, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x68, - 0xBF, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x20, 0xC0, 0x20, 0xAF, - 0x28, 0x05, - 0x97, 0x74, - - 0x00, 0xE0, - 0x2A, 0x10, - 0x16, 0xC0, 0x20, 0xE9, - - 0x04, 0x80, 0x10, 0xEA, - 0x8C, 0xE2, - 0x95, 0x05, - - 0x28, 0xC1, 0x28, 0xAD, - 0x1F, 0xC1, 0x15, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xA8, 0x67, - 0x9F, 0x6B, - 0x00, 0x80, 0x00, 0xE8, - - 0x28, 0xC0, 0x28, 0xAD, - 0x1D, 0x25, - 0x20, 0x05, - - 0x28, 0x32, 0x80, 0xAD, - 0x40, 0x2A, 0x40, 0xBD, - - 0x1C, 0x80, 0x20, 0xE9, - 0x20, 0x33, 0x20, 0xAD, - - 0x20, 0x73, - 0x00, 0xE0, - 0xB6, 0x49, 0x51, 0xBB, - - 0x26, 0x2F, 0xB0, 0xE8, - 0x19, 0x20, 0x20, 0xE9, - - 0x35, 0x20, 0x35, 0xDF, - 0x3D, 0x20, 0x3D, 0xDF, - - 0x15, 0x20, 0x15, 0xDF, - 0x1D, 0x20, 0x1D, 0xDF, - - 0x26, 0xD0, 0x26, 0xCD, - 0x29, 0x49, 0x2A, 0xB8, - - 0x26, 0x40, 0x80, 0xBD, - 0x3B, 0x48, 0x50, 0xBD, - - 0x3E, 0x54, 0x57, 0x9F, - 0x00, 0xE0, - 0x82, 0xE1, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x26, 0x30, - 0x29, 0x30, - 0x48, 0x3C, 0x48, 0xAD, - - 0x2B, 0x72, - 0xC2, 0xE1, - 0x2C, 0xC0, 0x44, 0xC2, - - 0x05, 0x24, 0x34, 0xBF, - 0x0D, 0x24, 0x2C, 0xBF, - - 0x2D, 0x46, 0x4E, 0xBF, - 0x25, 0x46, 0x56, 0xBF, - - 0x20, 0x1D, 0x6F, 0x8F, - 0x32, 0x3E, 0x5F, 0xE9, - - 0x3E, 0x50, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x30, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x33, 0x1E, 0x5F, 0xE9, - - 0x05, 0x44, 0x54, 0xB2, - 0x0D, 0x44, 0x4C, 0xB2, - - 0x19, 0xC0, 0xB0, 0xE8, - 0x34, 0xC0, 0x44, 0xC4, - - 0x33, 0x73, - 0x00, 0xE0, - 0x3E, 0x62, 0x57, 0x9F, - - 0x1E, 0xAF, 0x59, 0x9F, - 0x00, 0xE0, - 0x0D, 0x20, - - 0x84, 0x3E, 0x58, 0xE9, - 0x28, 0x1D, 0x6F, 0x8F, - - 0x05, 0x20, - 0x00, 0xE0, - 0x85, 0x1E, 0x58, 0xE9, - - 0x9B, 0x3B, 0x33, 0xDF, - 0x20, 0x20, 0x42, 0xAF, - - 0x30, 0x42, 0x56, 0x9F, - 0x80, 0x3E, 0x57, 0xE9, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x30, 0x80, 0x5F, 0xE9, - - 0x28, 0x28, 0x24, 0xAF, - 0x81, 0x1E, 0x57, 0xE9, - - 0x05, 0x47, 0x57, 0xBF, - 0x0D, 0x47, 0x4F, 0xBF, - - 0x88, 0x80, 0x58, 0xE9, - 0x1B, 0x29, 0x1B, 0xDF, - - 0x30, 0x1D, 0x6F, 0x8F, - 0x3A, 0x30, 0x4F, 0xE9, - - 0x1C, 0x30, 0x26, 0xDF, - 0x09, 0xE3, - 0x3B, 0x05, - - 0x3E, 0x50, 0x56, 0x9F, - 0x3B, 0x3F, 0x4F, 0xE9, - - 0x1E, 0x8F, 0x51, 0x9F, - 0x00, 0xE0, - 0xAC, 0x20, - - 0x2D, 0x44, 0x4C, 0xB4, - 0x2C, 0x1C, 0xC0, 0xAF, - - 0x25, 0x44, 0x54, 0xB4, - 0x00, 0xE0, - 0xC8, 0x30, - - 0x30, 0x46, 0x30, 0xAF, - 0x1B, 0x1B, 0x48, 0xAF, - - 0x00, 0xE0, - 0x25, 0x20, - 0x38, 0x2C, 0x4F, 0xE9, - - 0x86, 0x80, 0x57, 0xE9, - 0x38, 0x1D, 0x6F, 0x8F, - - 0x28, 0x74, - 0x00, 0xE0, - 0x0D, 0x44, 0x4C, 0xB0, - - 0x05, 0x44, 0x54, 0xB0, - 0x2D, 0x20, - 0x9B, 0x10, - - 0x82, 0x3E, 0x57, 0xE9, - 0x32, 0xF0, 0x1B, 0xCD, - - 0x1E, 0xBD, 0x59, 0x9F, - 0x83, 0x1E, 0x57, 0xE9, - - 0x38, 0x47, 0x38, 0xAF, - 0x34, 0x20, - 0x2A, 0x30, - - 0x00, 0xE0, - 0x0D, 0x20, - 0x32, 0x20, - 0x05, 0x20, - - 0x87, 0x80, 0x57, 0xE9, - 0x1F, 0x54, 0x57, 0x9F, - - 0x17, 0x42, 0x56, 0x9F, - 0x00, 0xE0, - 0x3B, 0x6A, - - 0x3F, 0x8F, 0x51, 0x9F, - 0x37, 0x1E, 0x4F, 0xE9, - - 0x37, 0x32, 0x2A, 0xAF, - 0x00, 0xE0, - 0x32, 0x00, - - 0x00, 0x80, 0x00, 0xE8, - 0x27, 0xC0, 0x44, 0xC0, - - 0x36, 0x1F, 0x4F, 0xE9, - 0x1F, 0x1F, 0x26, 0xDF, - - 0x37, 0x1B, 0x37, 0xBF, - 0x17, 0x26, 0x17, 0xDF, - - 0x3E, 0x17, 0x4F, 0xE9, - 0x3F, 0x3F, 0x4F, 0xE9, - - 0x34, 0x1F, 0x34, 0xAF, - 0x2B, 0x05, - 0xA7, 0x20, - - 0x33, 0x2B, 0x37, 0xDF, - 0x27, 0x17, 0xC0, 0xAF, - - 0x34, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x2D, 0x21, 0x1A, 0xB0, - 0x25, 0x21, 0x31, 0xB0, - - 0x0D, 0x21, 0x1A, 0xB2, - 0x05, 0x21, 0x31, 0xB2, - - 0x03, 0x80, 0x2A, 0xEA, - 0x17, 0xC1, 0x2B, 0xBD, - - 0x2D, 0x20, - 0x25, 0x20, - 0x05, 0x20, - 0x0D, 0x20, - - 0xB3, 0x68, - 0x97, 0x25, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0xC0, 0x33, 0xAF, - 0x2F, 0xC0, 0x21, 0xC0, - - 0x16, 0x42, 0x56, 0x9F, - 0x3C, 0x27, 0x4F, 0xE9, - - 0x1E, 0x62, 0x57, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x21, 0x31, 0xB4, - 0x2D, 0x21, 0x1A, 0xB4, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x33, 0x05, - 0x00, 0xE0, - 0x28, 0x19, 0x60, 0xEC, - - 0x0D, 0x21, 0x1A, 0xB6, - 0x05, 0x21, 0x31, 0xB6, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0xE0, - 0x2F, 0x20, - - 0x23, 0x3B, 0x33, 0xAD, - 0x1E, 0x26, 0x1E, 0xDF, - - 0xA7, 0x1E, 0x4F, 0xE9, - 0x17, 0x26, 0x16, 0xDF, - - 0x2D, 0x20, - 0x00, 0xE0, - 0xA8, 0x3F, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x1E, 0xAF, - 0x25, 0x20, - 0x00, 0xE0, - - 0xA4, 0x16, 0x4F, 0xE9, - 0x0F, 0xC0, 0x21, 0xC2, - - 0xA6, 0x80, 0x4F, 0xE9, - 0x1F, 0x62, 0x57, 0x9F, - - 0x0D, 0x20, - 0x05, 0x20, - 0x2F, 0xC0, 0x21, 0xC6, - - 0x3F, 0x2F, 0x5D, 0x9F, - 0x00, 0xE0, - 0x0F, 0x20, - - 0x17, 0x50, 0x56, 0x9F, - 0xA5, 0x37, 0x4F, 0xE9, - - 0x06, 0xC0, 0x21, 0xC4, - 0x0F, 0x17, 0x0F, 0xAF, - - 0x37, 0x0F, 0x5C, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x2F, 0x20, - 0x00, 0xE0, - 0xA3, 0x80, 0x4F, 0xE9, - - 0x06, 0x20, - 0x00, 0xE0, - 0x1F, 0x26, 0x1F, 0xDF, - - 0x17, 0x26, 0x17, 0xDF, - 0x35, 0x17, 0x4F, 0xE9, - - 0xA1, 0x1F, 0x4F, 0xE9, - 0xA2, 0x3F, 0x4F, 0xE9, - - 0x06, 0x06, 0x1F, 0xAF, - 0x39, 0x37, 0x4F, 0xE9, - - 0x2F, 0x2F, 0x17, 0xAF, - 0x00, 0x80, 0x00, 0xE8, - - 0xA0, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x31, 0x80, 0x4F, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x57, 0x39, 0x20, 0xE9, - - 0x16, 0x28, 0x20, 0xE9, - 0x1D, 0x3B, 0x20, 0xE9, - - 0x1E, 0x2B, 0x20, 0xE9, - 0x2B, 0x32, 0x20, 0xE9, - - 0x1C, 0x23, 0x20, 0xE9, - 0x57, 0x36, 0x20, 0xE9, - - 0x00, 0x80, 0xA0, 0xE9, - 0x40, 0x40, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x90, 0xE2, - 0x00, 0xE0, - - 0x68, 0xFF, 0x20, 0xEA, - 0x19, 0xC8, 0xC1, 0xCD, - - 0x1F, 0xD7, 0x18, 0xBD, - 0x3F, 0xD7, 0x22, 0xBD, - - 0x9F, 0x41, 0x49, 0xBD, - 0x00, 0x80, 0x00, 0xE8, - - 0x25, 0x41, 0x49, 0xBD, - 0x2D, 0x41, 0x51, 0xBD, - - 0x0D, 0x80, 0x07, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x35, 0x40, 0x48, 0xBD, - 0x3D, 0x40, 0x50, 0xBD, - - 0x00, 0x80, 0x00, 0xE8, - 0x25, 0x30, - 0x2D, 0x30, - - 0x35, 0x30, - 0xB5, 0x30, - 0xBD, 0x30, - 0x3D, 0x30, - - 0x9C, 0xA7, 0x5B, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x67, 0xFF, 0x0A, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0xC9, 0x41, 0xC8, 0xEC, - 0x42, 0xE1, - 0x00, 0xE0, - - 0x65, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0xC8, 0x40, 0xC0, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x62, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - -}; - -static unsigned char warp_g400_t2gz[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x78, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x69, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0x34, 0x80, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x25, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x3D, 0xCF, 0x74, 0xC2, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x2A, 0x44, 0x54, 0xB4, - 0x1A, 0x44, 0x64, 0xB4, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x9F, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xBE, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x7D, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gza[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x7C, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x6D, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0x34, 0x80, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x29, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0F, 0xCF, 0x74, 0xC6, - 0x3D, 0xCF, 0x74, 0xC2, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x0F, 0x20, 0xE9, - - 0x0A, 0x44, 0x54, 0xB4, - 0x02, 0x44, 0x64, 0xB4, - - 0x2A, 0x44, 0x54, 0xB6, - 0x1A, 0x44, 0x64, 0xB6, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x36, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x37, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x9B, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xBA, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x79, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gzaf[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x81, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x72, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x31, 0x53, 0x2F, 0x9F, - 0x34, 0x37, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x2E, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x3D, 0xCF, 0x74, 0xC2, - 0x0F, 0xCF, 0x74, 0xC6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x0F, 0x20, 0xE9, - - 0x0A, 0x44, 0x54, 0xB4, - 0x02, 0x44, 0x64, 0xB4, - - 0x2A, 0x44, 0x54, 0xB6, - 0x1A, 0x44, 0x64, 0xB6, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x3D, 0xCF, 0x75, 0xC6, - 0x00, 0x80, 0x00, 0xE8, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x0A, 0x45, 0x55, 0xB6, - 0x02, 0x45, 0x65, 0xB6, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x31, 0x3D, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x38, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x96, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xB5, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x74, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gzf[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x7D, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x6E, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x34, 0x80, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x88, 0x73, 0x5E, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0F, 0xCF, 0x75, 0xC6, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x28, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x3D, 0xCF, 0x74, 0xC2, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x31, 0x0F, 0x20, 0xE9, - - 0x0A, 0x44, 0x54, 0xB4, - 0x02, 0x44, 0x64, 0xB4, - - 0x2A, 0x45, 0x55, 0xB6, - 0x1A, 0x45, 0x65, 0xB6, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x36, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x37, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x39, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x9A, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xBB, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x78, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gzs[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x85, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x76, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x0F, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x31, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0F, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB4, - 0x1A, 0x44, 0x64, 0xB4, - - 0x0A, 0x45, 0x55, 0xB0, - 0x02, 0x45, 0x65, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x2A, 0x45, 0x55, 0xB2, - 0x1A, 0x45, 0x65, 0xB2, - - 0x0A, 0x45, 0x55, 0xB4, - 0x02, 0x45, 0x65, 0xB4, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x20, - 0x1A, 0x20, - 0x0A, 0x20, - 0x02, 0x20, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0xA7, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x92, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xB2, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x70, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gzsa[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x8A, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x7B, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x0F, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x36, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0F, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB4, - 0x1A, 0x44, 0x64, 0xB4, - - 0x0A, 0x45, 0x55, 0xB0, - 0x02, 0x45, 0x65, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x45, 0x55, 0xB2, - 0x1A, 0x45, 0x65, 0xB2, - - 0x0A, 0x45, 0x55, 0xB4, - 0x02, 0x45, 0x65, 0xB4, - - 0x0F, 0xCF, 0x74, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA7, 0x30, 0x4F, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x2A, 0x44, 0x54, 0xB6, - 0x1A, 0x44, 0x64, 0xB6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x8D, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xAD, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x6B, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gzsaf[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x8E, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x7F, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x0F, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x3A, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0F, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB4, - 0x1A, 0x44, 0x64, 0xB4, - - 0x0A, 0x45, 0x55, 0xB0, - 0x02, 0x45, 0x65, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x45, 0x55, 0xB2, - 0x1A, 0x45, 0x65, 0xB2, - - 0x0A, 0x45, 0x55, 0xB4, - 0x02, 0x45, 0x65, 0xB4, - - 0x0F, 0xCF, 0x74, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA7, 0x30, 0x4F, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x2A, 0x44, 0x54, 0xB6, - 0x1A, 0x44, 0x64, 0xB6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x0A, 0x45, 0x55, 0xB6, - 0x02, 0x45, 0x65, 0xB6, - - 0x3D, 0xCF, 0x75, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x31, 0x3D, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x38, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x89, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xA9, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x67, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_t2gzsf[] = { - - 0x00, 0x8A, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x0A, 0x40, 0x50, 0xBF, - 0x2A, 0x40, 0x60, 0xBF, - - 0x32, 0x41, 0x51, 0xBF, - 0x3A, 0x41, 0x61, 0xBF, - - 0xC3, 0x6B, - 0xD3, 0x6B, - 0x00, 0x8A, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x53, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x23, 0x9F, - 0x00, 0xE0, - 0x51, 0x04, - - 0x90, 0xE2, - 0x61, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x51, 0x41, 0xE0, 0xEC, - 0x39, 0x67, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x63, 0xA0, 0xE8, - - 0x61, 0x41, 0xE0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x8A, 0x80, 0x15, 0xEA, - 0x10, 0x04, - 0x20, 0x04, - - 0x61, 0x51, 0xE0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x52, 0xBF, - 0x0F, 0x52, 0xA0, 0xE8, - - 0x1A, 0x42, 0x62, 0xBF, - 0x1E, 0x51, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x0E, 0x61, 0x60, 0xEA, - - 0x32, 0x40, 0x50, 0xBD, - 0x22, 0x40, 0x60, 0xBD, - - 0x12, 0x41, 0x51, 0xBD, - 0x3A, 0x41, 0x61, 0xBD, - - 0xBF, 0x2F, 0x0E, 0xBD, - 0x97, 0xE2, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x35, 0x48, 0xB1, 0xE8, - 0x3D, 0x59, 0xB1, 0xE8, - - 0x46, 0x31, 0x46, 0xBF, - 0x56, 0x31, 0x56, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x66, 0x31, 0x66, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x57, 0x39, 0x57, 0xBF, - 0x67, 0x39, 0x67, 0xBF, - - 0x7B, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x35, 0x00, - 0x3D, 0x00, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0x8D, 0x2F, 0x1E, 0xBD, - - 0x43, 0x75, 0xF8, 0xEC, - 0x35, 0x20, - 0x3D, 0x20, - - 0x43, 0x43, 0x2D, 0xDF, - 0x53, 0x53, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x0E, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x48, 0x35, 0x48, 0xBF, - 0x58, 0x35, 0x58, 0xBF, - - 0x68, 0x35, 0x68, 0xBF, - 0x49, 0x3D, 0x49, 0xBF, - - 0x59, 0x3D, 0x59, 0xBF, - 0x69, 0x3D, 0x69, 0xBF, - - 0x63, 0x63, 0x2D, 0xDF, - 0x4D, 0x7D, 0xF8, 0xEC, - - 0x59, 0xE3, - 0x00, 0xE0, - 0xB8, 0x38, 0x33, 0xBF, - - 0x2D, 0x73, - 0x30, 0x76, - 0x18, 0x3A, 0x41, 0xE9, - - 0x3F, 0x53, 0xA0, 0xE8, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x63, 0xA0, 0xE8, - - 0x50, 0x70, 0xF8, 0xEC, - 0x2B, 0x50, 0x3C, 0xE9, - - 0x1F, 0x0F, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x59, 0x78, 0xF8, 0xEC, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x46, 0x37, 0x46, 0xDF, - 0x56, 0x3F, 0x56, 0xDF, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x66, 0x3D, 0x66, 0xDF, - - 0x1D, 0x32, 0x41, 0xE9, - 0x67, 0x3D, 0x67, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3F, 0x57, 0xDF, - - 0x2A, 0x40, 0x20, 0xE9, - 0x59, 0x3F, 0x59, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x69, 0x3D, 0x69, 0xDF, - - 0x48, 0x37, 0x48, 0xDF, - 0x58, 0x3F, 0x58, 0xDF, - - 0x68, 0x3D, 0x68, 0xDF, - 0x49, 0x37, 0x49, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x0F, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x54, 0xB0, - 0x02, 0x44, 0x64, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB2, - 0x1A, 0x44, 0x64, 0xB2, - - 0x36, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0F, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x54, 0xB4, - 0x1A, 0x44, 0x64, 0xB4, - - 0x0A, 0x45, 0x55, 0xB0, - 0x02, 0x45, 0x65, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x45, 0x55, 0xB2, - 0x1A, 0x45, 0x65, 0xB2, - - 0x0A, 0x45, 0x55, 0xB4, - 0x02, 0x45, 0x65, 0xB4, - - 0x0F, 0xCF, 0x75, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA7, 0x30, 0x4F, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x31, 0x0F, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x2A, 0x45, 0x55, 0xB6, - 0x1A, 0x45, 0x65, 0xB6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x56, 0xBF, - 0x1A, 0x46, 0x66, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x0A, 0x47, 0x57, 0xBF, - 0x02, 0x47, 0x67, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x53, 0xBF, - 0x1A, 0x43, 0x63, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x39, 0x4F, 0xE9, - - 0x0A, 0x48, 0x58, 0xBF, - 0x02, 0x48, 0x68, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x2A, 0x49, 0x59, 0xBF, - 0x1A, 0x49, 0x69, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x82, 0x30, 0x57, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x83, 0x38, 0x57, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x84, 0x31, 0x5E, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x85, 0x39, 0x5E, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8A, 0x36, 0x20, 0xE9, - - 0x87, 0x77, 0x57, 0xE9, - 0x8B, 0x3E, 0xBF, 0xEA, - - 0x80, 0x30, 0x57, 0xE9, - 0x81, 0x38, 0x57, 0xE9, - - 0x82, 0x31, 0x57, 0xE9, - 0x86, 0x78, 0x57, 0xE9, - - 0x83, 0x39, 0x57, 0xE9, - 0x87, 0x79, 0x57, 0xE9, - - 0x30, 0x1F, 0x5F, 0xE9, - 0x8A, 0x34, 0x20, 0xE9, - - 0x8B, 0x3C, 0x20, 0xE9, - 0x37, 0x50, 0x60, 0xBD, - - 0x57, 0x0D, 0x20, 0xE9, - 0x35, 0x51, 0x61, 0xBD, - - 0x2B, 0x50, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x0E, 0x77, - - 0x24, 0x51, 0x20, 0xE9, - 0x8D, 0xFF, 0x20, 0xEA, - - 0x16, 0x0E, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x0B, 0x46, 0xA0, 0xE8, - 0x1B, 0x56, 0xA0, 0xE8, - - 0x2B, 0x66, 0xA0, 0xE8, - 0x0C, 0x47, 0xA0, 0xE8, - - 0x1C, 0x57, 0xA0, 0xE8, - 0x2C, 0x67, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x57, 0x80, 0x57, 0xCF, - - 0x66, 0x33, 0x66, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x67, 0x3B, 0x67, 0xCF, - - 0x0B, 0x48, 0xA0, 0xE8, - 0x1B, 0x58, 0xA0, 0xE8, - - 0x2B, 0x68, 0xA0, 0xE8, - 0x0C, 0x49, 0xA0, 0xE8, - - 0x1C, 0x59, 0xA0, 0xE8, - 0x2C, 0x69, 0xA0, 0xE8, - - 0x0B, 0x00, - 0x1B, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x0C, 0x00, - 0x1C, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x0B, 0x65, - 0x1B, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x0C, 0x65, - 0x1C, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x0B, 0x1B, 0x60, 0xEC, - 0x34, 0xD7, 0x34, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x0C, 0x1C, 0x60, 0xEC, - - 0x3C, 0xD7, 0x3C, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x0B, 0x2B, 0xDE, 0xE8, - 0x1B, 0x80, 0xDE, 0xE8, - - 0x34, 0x80, 0x34, 0xBD, - 0x3C, 0x80, 0x3C, 0xBD, - - 0x33, 0xD7, 0x0B, 0xBD, - 0x3B, 0xD7, 0x1B, 0xBD, - - 0x48, 0x80, 0x48, 0xCF, - 0x59, 0x80, 0x59, 0xCF, - - 0x68, 0x33, 0x68, 0xCF, - 0x49, 0x3B, 0x49, 0xCF, - - 0xAD, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x58, 0x33, 0x58, 0xCF, - 0x69, 0x3B, 0x69, 0xCF, - - 0x6B, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgz[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x58, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x4A, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0x34, 0x80, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x1D, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x3D, 0xCF, 0x74, 0xC2, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x2A, 0x44, 0x4C, 0xB4, - 0x1A, 0x44, 0x54, 0xB4, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0xAF, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xD6, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x9D, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgza[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x5C, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x4E, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0x34, 0x80, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x27, 0xCF, 0x74, 0xC6, - 0x3D, 0xCF, 0x74, 0xC2, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x20, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x27, 0x20, 0xE9, - - 0x0A, 0x44, 0x4C, 0xB4, - 0x02, 0x44, 0x54, 0xB4, - - 0x2A, 0x44, 0x4C, 0xB6, - 0x1A, 0x44, 0x54, 0xB6, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x36, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x37, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0xAB, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xD3, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x99, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgzaf[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x61, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x53, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x31, 0x53, 0x2F, 0x9F, - 0x34, 0x37, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x26, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x3D, 0xCF, 0x74, 0xC2, - 0x27, 0xCF, 0x74, 0xC6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x27, 0x20, 0xE9, - - 0x0A, 0x44, 0x4C, 0xB4, - 0x02, 0x44, 0x54, 0xB4, - - 0x2A, 0x44, 0x4C, 0xB6, - 0x1A, 0x44, 0x54, 0xB6, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x3D, 0xCF, 0x75, 0xC6, - 0x00, 0x80, 0x00, 0xE8, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x0A, 0x45, 0x4D, 0xB6, - 0x02, 0x45, 0x55, 0xB6, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x31, 0x3D, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0xA6, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xCD, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x94, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgzf[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x5D, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x4F, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x37, 0xCF, 0x74, 0xC4, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x34, 0x80, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x88, 0x73, 0x5E, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x27, 0xCF, 0x75, 0xC6, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x20, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x3D, 0xCF, 0x74, 0xC2, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x31, 0x27, 0x20, 0xE9, - - 0x0A, 0x44, 0x4C, 0xB4, - 0x02, 0x44, 0x54, 0xB4, - - 0x2A, 0x45, 0x4D, 0xB6, - 0x1A, 0x45, 0x55, 0xB6, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x38, 0x3D, 0x20, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x36, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x37, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0xAA, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xD3, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x98, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgzs[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x65, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x57, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x27, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x29, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x27, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB4, - 0x1A, 0x44, 0x54, 0xB4, - - 0x0A, 0x45, 0x4D, 0xB0, - 0x02, 0x45, 0x55, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x2A, 0x45, 0x4D, 0xB2, - 0x1A, 0x45, 0x55, 0xB2, - - 0x0A, 0x45, 0x4D, 0xB4, - 0x02, 0x45, 0x55, 0xB4, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x0A, 0x20, - 0x02, 0x20, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0xA7, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0xA2, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xCA, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x90, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgzsa[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x6A, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x5C, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x27, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x2E, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x27, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB4, - 0x1A, 0x44, 0x54, 0xB4, - - 0x0A, 0x45, 0x4D, 0xB0, - 0x02, 0x45, 0x55, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x45, 0x4D, 0xB2, - 0x1A, 0x45, 0x55, 0xB2, - - 0x0A, 0x45, 0x4D, 0xB4, - 0x02, 0x45, 0x55, 0xB4, - - 0x27, 0xCF, 0x74, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA7, 0x30, 0x4F, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB6, - 0x1A, 0x44, 0x54, 0xB6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0x9D, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xC5, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x8B, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgzsaf[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x6E, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x60, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x27, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x32, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x27, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB4, - 0x1A, 0x44, 0x54, 0xB4, - - 0x0A, 0x45, 0x4D, 0xB0, - 0x02, 0x45, 0x55, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x45, 0x4D, 0xB2, - 0x1A, 0x45, 0x55, 0xB2, - - 0x0A, 0x45, 0x4D, 0xB4, - 0x02, 0x45, 0x55, 0xB4, - - 0x27, 0xCF, 0x74, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA7, 0x30, 0x4F, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9C, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB6, - 0x1A, 0x44, 0x54, 0xB6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x0A, 0x45, 0x4D, 0xB6, - 0x02, 0x45, 0x55, 0xB6, - - 0x3D, 0xCF, 0x75, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x31, 0x3D, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x9D, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x9E, 0x39, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x30, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x38, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0x99, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xC1, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x87, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; - -static unsigned char warp_g400_tgzsf[] = { - - 0x00, 0x88, 0x98, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - - 0xFF, 0x80, 0xC0, 0xE9, - 0x00, 0x80, 0x00, 0xE8, - - 0x22, 0x40, 0x48, 0xBF, - 0x2A, 0x40, 0x50, 0xBF, - - 0x32, 0x41, 0x49, 0xBF, - 0x3A, 0x41, 0x51, 0xBF, - - 0xC3, 0x6B, - 0xCB, 0x6B, - 0x00, 0x88, 0x98, 0xE9, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x96, 0xE2, - 0x41, 0x04, - - 0x7B, 0x43, 0xA0, 0xE8, - 0x73, 0x4B, 0xA0, 0xE8, - - 0xAD, 0xEE, 0x29, 0x9F, - 0x00, 0xE0, - 0x49, 0x04, - - 0x90, 0xE2, - 0x51, 0x04, - 0x31, 0x46, 0xB1, 0xE8, - - 0x49, 0x41, 0xC0, 0xEC, - 0x39, 0x57, 0xB1, 0xE8, - - 0x00, 0x04, - 0x46, 0xE2, - 0x73, 0x53, 0xA0, 0xE8, - - 0x51, 0x41, 0xC0, 0xEC, - 0x31, 0x00, - 0x39, 0x00, - - 0x6A, 0x80, 0x15, 0xEA, - 0x08, 0x04, - 0x10, 0x04, - - 0x51, 0x49, 0xC0, 0xEC, - 0x2F, 0x41, 0x60, 0xEA, - - 0x31, 0x20, - 0x39, 0x20, - 0x1F, 0x42, 0xA0, 0xE8, - - 0x2A, 0x42, 0x4A, 0xBF, - 0x27, 0x4A, 0xA0, 0xE8, - - 0x1A, 0x42, 0x52, 0xBF, - 0x1E, 0x49, 0x60, 0xEA, - - 0x73, 0x7B, 0xC8, 0xEC, - 0x26, 0x51, 0x60, 0xEA, - - 0x32, 0x40, 0x48, 0xBD, - 0x22, 0x40, 0x50, 0xBD, - - 0x12, 0x41, 0x49, 0xBD, - 0x3A, 0x41, 0x51, 0xBD, - - 0xBF, 0x2F, 0x26, 0xBD, - 0x00, 0xE0, - 0x7B, 0x72, - - 0x32, 0x20, - 0x22, 0x20, - 0x12, 0x20, - 0x3A, 0x20, - - 0x46, 0x31, 0x46, 0xBF, - 0x4E, 0x31, 0x4E, 0xBF, - - 0xB3, 0xE2, 0x2D, 0x9F, - 0x00, 0x80, 0x00, 0xE8, - - 0x56, 0x31, 0x56, 0xBF, - 0x47, 0x39, 0x47, 0xBF, - - 0x4F, 0x39, 0x4F, 0xBF, - 0x57, 0x39, 0x57, 0xBF, - - 0x5C, 0x80, 0x07, 0xEA, - 0x24, 0x41, 0x20, 0xE9, - - 0x42, 0x73, 0xF8, 0xEC, - 0x00, 0xE0, - 0x2D, 0x73, - - 0x33, 0x72, - 0x0C, 0xE3, - 0xA5, 0x2F, 0x1E, 0xBD, - - 0x43, 0x43, 0x2D, 0xDF, - 0x4B, 0x4B, 0x2D, 0xDF, - - 0xAE, 0x1E, 0x26, 0xBD, - 0x58, 0xE3, - 0x33, 0x66, - - 0x53, 0x53, 0x2D, 0xDF, - 0x00, 0x80, 0x00, 0xE8, - - 0xB8, 0x38, 0x33, 0xBF, - 0x00, 0xE0, - 0x59, 0xE3, - - 0x1E, 0x12, 0x41, 0xE9, - 0x1A, 0x22, 0x41, 0xE9, - - 0x2B, 0x40, 0x3D, 0xE9, - 0x3F, 0x4B, 0xA0, 0xE8, - - 0x2D, 0x73, - 0x30, 0x76, - 0x05, 0x80, 0x3D, 0xEA, - - 0x37, 0x43, 0xA0, 0xE8, - 0x3D, 0x53, 0xA0, 0xE8, - - 0x48, 0x70, 0xF8, 0xEC, - 0x2B, 0x48, 0x3C, 0xE9, - - 0x1F, 0x27, 0xBC, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x00, 0x80, 0x00, 0xE8, - 0x00, 0x80, 0x00, 0xE8, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x15, 0xC0, 0x20, 0xE9, - 0x15, 0xC0, 0x20, 0xE9, - - 0x18, 0x3A, 0x41, 0xE9, - 0x1D, 0x32, 0x41, 0xE9, - - 0x2A, 0x40, 0x20, 0xE9, - 0x56, 0x3D, 0x56, 0xDF, - - 0x46, 0x37, 0x46, 0xDF, - 0x4E, 0x3F, 0x4E, 0xDF, - - 0x16, 0x30, 0x20, 0xE9, - 0x4F, 0x3F, 0x4F, 0xDF, - - 0x47, 0x37, 0x47, 0xDF, - 0x57, 0x3D, 0x57, 0xDF, - - 0x32, 0x32, 0x2D, 0xDF, - 0x22, 0x22, 0x2D, 0xDF, - - 0x12, 0x12, 0x2D, 0xDF, - 0x3A, 0x3A, 0x2D, 0xDF, - - 0x27, 0xCF, 0x74, 0xC2, - 0x37, 0xCF, 0x74, 0xC4, - - 0x0A, 0x44, 0x4C, 0xB0, - 0x02, 0x44, 0x54, 0xB0, - - 0x3D, 0xCF, 0x74, 0xC0, - 0x34, 0x37, 0x20, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x38, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3C, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB2, - 0x1A, 0x44, 0x54, 0xB2, - - 0x2E, 0x80, 0x3A, 0xEA, - 0x0A, 0x20, - 0x02, 0x20, - - 0x27, 0xCF, 0x75, 0xC0, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x30, 0x50, 0x2E, 0x9F, - 0x32, 0x31, 0x5F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x33, 0x39, 0x5F, 0xE9, - - 0x3D, 0xCF, 0x75, 0xC2, - 0x37, 0xCF, 0x75, 0xC4, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA6, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA3, 0x3D, 0x20, 0xE9, - - 0x2A, 0x44, 0x4C, 0xB4, - 0x1A, 0x44, 0x54, 0xB4, - - 0x0A, 0x45, 0x4D, 0xB0, - 0x02, 0x45, 0x55, 0xB0, - - 0x88, 0x73, 0x5E, 0xE9, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA0, 0x37, 0x20, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x3E, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x3F, 0x38, 0x4F, 0xE9, - - 0x30, 0x50, 0x2E, 0x9F, - 0x3A, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x3B, 0x39, 0x4F, 0xE9, - - 0x2A, 0x45, 0x4D, 0xB2, - 0x1A, 0x45, 0x55, 0xB2, - - 0x0A, 0x45, 0x4D, 0xB4, - 0x02, 0x45, 0x55, 0xB4, - - 0x27, 0xCF, 0x75, 0xC6, - 0x2A, 0x20, - 0x1A, 0x20, - - 0xA7, 0x30, 0x4F, 0xE9, - 0x0A, 0x20, - 0x02, 0x20, - - 0x31, 0x53, 0x2F, 0x9F, - 0x31, 0x27, 0x20, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA8, 0x38, 0x4F, 0xE9, - - 0x2A, 0x45, 0x4D, 0xB6, - 0x1A, 0x45, 0x55, 0xB6, - - 0x30, 0x50, 0x2E, 0x9F, - 0x36, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x37, 0x39, 0x4F, 0xE9, - - 0x00, 0x80, 0x00, 0xE8, - 0x2A, 0x20, - 0x1A, 0x20, - - 0x2A, 0x46, 0x4E, 0xBF, - 0x1A, 0x46, 0x56, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA4, 0x31, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA5, 0x39, 0x4F, 0xE9, - - 0x0A, 0x47, 0x4F, 0xBF, - 0x02, 0x47, 0x57, 0xBF, - - 0x31, 0x53, 0x2F, 0x9F, - 0xA1, 0x30, 0x4F, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0xA2, 0x38, 0x4F, 0xE9, - - 0x2A, 0x43, 0x4B, 0xBF, - 0x1A, 0x43, 0x53, 0xBF, - - 0x30, 0x50, 0x2E, 0x9F, - 0x35, 0x31, 0x4F, 0xE9, - - 0x38, 0x21, 0x2C, 0x9F, - 0x39, 0x39, 0x4F, 0xE9, - - 0x31, 0x53, 0x2F, 0x9F, - 0x80, 0x31, 0x57, 0xE9, - - 0x39, 0xE5, 0x2C, 0x9F, - 0x81, 0x39, 0x57, 0xE9, - - 0x37, 0x48, 0x50, 0xBD, - 0x8A, 0x36, 0x20, 0xE9, - - 0x86, 0x76, 0x57, 0xE9, - 0x8B, 0x3E, 0x20, 0xE9, - - 0x82, 0x30, 0x57, 0xE9, - 0x87, 0x77, 0x57, 0xE9, - - 0x83, 0x38, 0x57, 0xE9, - 0x35, 0x49, 0x51, 0xBD, - - 0x84, 0x31, 0x5E, 0xE9, - 0x30, 0x1F, 0x5F, 0xE9, - - 0x85, 0x39, 0x5E, 0xE9, - 0x57, 0x25, 0x20, 0xE9, - - 0x2B, 0x48, 0x20, 0xE9, - 0x1D, 0x37, 0xE1, 0xEA, - - 0x1E, 0x35, 0xE1, 0xEA, - 0x00, 0xE0, - 0x26, 0x77, - - 0x24, 0x49, 0x20, 0xE9, - 0x9D, 0xFF, 0x20, 0xEA, - - 0x16, 0x26, 0x20, 0xE9, - 0x57, 0x2E, 0xBF, 0xEA, - - 0x1C, 0x46, 0xA0, 0xE8, - 0x23, 0x4E, 0xA0, 0xE8, - - 0x2B, 0x56, 0xA0, 0xE8, - 0x1D, 0x47, 0xA0, 0xE8, - - 0x24, 0x4F, 0xA0, 0xE8, - 0x2C, 0x57, 0xA0, 0xE8, - - 0x1C, 0x00, - 0x23, 0x00, - 0x2B, 0x00, - 0x00, 0xE0, - - 0x1D, 0x00, - 0x24, 0x00, - 0x2C, 0x00, - 0x00, 0xE0, - - 0x1C, 0x65, - 0x23, 0x65, - 0x2B, 0x65, - 0x00, 0xE0, - - 0x1D, 0x65, - 0x24, 0x65, - 0x2C, 0x65, - 0x00, 0xE0, - - 0x1C, 0x23, 0x60, 0xEC, - 0x36, 0xD7, 0x36, 0xAD, - - 0x2B, 0x80, 0x60, 0xEC, - 0x1D, 0x24, 0x60, 0xEC, - - 0x3E, 0xD7, 0x3E, 0xAD, - 0x2C, 0x80, 0x60, 0xEC, - - 0x1C, 0x2B, 0xDE, 0xE8, - 0x23, 0x80, 0xDE, 0xE8, - - 0x36, 0x80, 0x36, 0xBD, - 0x3E, 0x80, 0x3E, 0xBD, - - 0x33, 0xD7, 0x1C, 0xBD, - 0x3B, 0xD7, 0x23, 0xBD, - - 0x46, 0x80, 0x46, 0xCF, - 0x4F, 0x80, 0x4F, 0xCF, - - 0x56, 0x33, 0x56, 0xCF, - 0x47, 0x3B, 0x47, 0xCF, - - 0xC5, 0xFF, 0x20, 0xEA, - 0x00, 0x80, 0x00, 0xE8, - - 0x4E, 0x33, 0x4E, 0xCF, - 0x57, 0x3B, 0x57, 0xCF, - - 0x8B, 0xFF, 0x20, 0xEA, - 0x57, 0xC0, 0xBF, 0xEA, - - 0x00, 0x80, 0xA0, 0xE9, - 0x00, 0x00, 0xD8, 0xEC, - -}; diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c deleted file mode 100644 index 651b93c..0000000 --- a/drivers/char/drm/mga_warp.c +++ /dev/null @@ -1,193 +0,0 @@ -/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- - * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" -#include "mga_ucode.h" - -#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ - -#define WARP_UCODE_SIZE( which ) \ - ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) - -#define WARP_UCODE_INSTALL( which, where ) \ -do { \ - DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\ - dev_priv->warp_pipe_phys[where] = pcbase; \ - memcpy( vcbase, which, sizeof(which) ); \ - pcbase += WARP_UCODE_SIZE( which ); \ - vcbase += WARP_UCODE_SIZE( which ); \ -} while (0) - -static const unsigned int mga_warp_g400_microcode_size = - (WARP_UCODE_SIZE(warp_g400_tgz) + - WARP_UCODE_SIZE(warp_g400_tgza) + - WARP_UCODE_SIZE(warp_g400_tgzaf) + - WARP_UCODE_SIZE(warp_g400_tgzf) + - WARP_UCODE_SIZE(warp_g400_tgzs) + - WARP_UCODE_SIZE(warp_g400_tgzsa) + - WARP_UCODE_SIZE(warp_g400_tgzsaf) + - WARP_UCODE_SIZE(warp_g400_tgzsf) + - WARP_UCODE_SIZE(warp_g400_t2gz) + - WARP_UCODE_SIZE(warp_g400_t2gza) + - WARP_UCODE_SIZE(warp_g400_t2gzaf) + - WARP_UCODE_SIZE(warp_g400_t2gzf) + - WARP_UCODE_SIZE(warp_g400_t2gzs) + - WARP_UCODE_SIZE(warp_g400_t2gzsa) + - WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf)); - -static const unsigned int mga_warp_g200_microcode_size = - (WARP_UCODE_SIZE(warp_g200_tgz) + - WARP_UCODE_SIZE(warp_g200_tgza) + - WARP_UCODE_SIZE(warp_g200_tgzaf) + - WARP_UCODE_SIZE(warp_g200_tgzf) + - WARP_UCODE_SIZE(warp_g200_tgzs) + - WARP_UCODE_SIZE(warp_g200_tgzsa) + - WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf)); - -unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv) -{ - switch (dev_priv->chipset) { - case MGA_CARD_TYPE_G400: - case MGA_CARD_TYPE_G550: - return PAGE_ALIGN(mga_warp_g400_microcode_size); - case MGA_CARD_TYPE_G200: - return PAGE_ALIGN(mga_warp_g200_microcode_size); - default: - return 0; - } -} - -static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv) -{ - unsigned char *vcbase = dev_priv->warp->handle; - unsigned long pcbase = dev_priv->warp->offset; - - memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); - - WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ); - WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF); - WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA); - WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF); - WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS); - WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF); - WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA); - WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF); - - WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ); - WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF); - WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA); - WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF); - WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS); - WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF); - WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA); - WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF); - - return 0; -} - -static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv) -{ - unsigned char *vcbase = dev_priv->warp->handle; - unsigned long pcbase = dev_priv->warp->offset; - - memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); - - WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ); - WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF); - WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA); - WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF); - WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS); - WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF); - WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA); - WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF); - - return 0; -} - -int mga_warp_install_microcode(drm_mga_private_t * dev_priv) -{ - const unsigned int size = mga_warp_microcode_size(dev_priv); - - DRM_DEBUG("MGA ucode size = %d bytes\n", size); - if (size > dev_priv->warp->size) { - DRM_ERROR("microcode too large! (%u > %lu)\n", - size, dev_priv->warp->size); - return -ENOMEM; - } - - switch (dev_priv->chipset) { - case MGA_CARD_TYPE_G400: - case MGA_CARD_TYPE_G550: - return mga_warp_install_g400_microcode(dev_priv); - case MGA_CARD_TYPE_G200: - return mga_warp_install_g200_microcode(dev_priv); - default: - return -EINVAL; - } -} - -#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) - -int mga_warp_init(drm_mga_private_t * dev_priv) -{ - u32 wmisc; - - /* FIXME: Get rid of these damned magic numbers... - */ - switch (dev_priv->chipset) { - case MGA_CARD_TYPE_G400: - case MGA_CARD_TYPE_G550: - MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND); - MGA_WRITE(MGA_WGETMSB, 0x00000E00); - MGA_WRITE(MGA_WVRTXSZ, 0x00001807); - MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000); - break; - case MGA_CARD_TYPE_G200: - MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND); - MGA_WRITE(MGA_WGETMSB, 0x1606); - MGA_WRITE(MGA_WVRTXSZ, 7); - break; - default: - return -EINVAL; - } - - MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE | - MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE)); - wmisc = MGA_READ(MGA_WMISC); - if (wmisc != WMISC_EXPECTED) { - DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n", - wmisc, WMISC_EXPECTED); - return -EINVAL; - } - - return 0; -} diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c deleted file mode 100644 index c31afbd..0000000 --- a/drivers/char/drm/r128_cce.c +++ /dev/null @@ -1,935 +0,0 @@ -/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- - * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com - */ -/* - * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -#define R128_FIFO_DEBUG 0 - -/* CCE microcode (from ATI) */ -static u32 r128_cce_microcode[] = { - 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, - 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, - 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1, - 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11, - 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28, - 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, - 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, - 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, - 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071, - 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2, - 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1, - 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, - 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, - 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, - 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1, - 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82, - 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729, - 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008, - 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, - 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, - 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, - 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0, - 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370, - 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1, - 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793, - 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, - 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, - 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1, - 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1, - 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894, - 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14, - 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1, - 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, - 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, - 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static int R128_READ_PLL(struct drm_device * dev, int addr) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - - R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); - return R128_READ(R128_CLOCK_CNTL_DATA); -} - -#if R128_FIFO_DEBUG -static void r128_status(drm_r128_private_t * dev_priv) -{ - printk("GUI_STAT = 0x%08x\n", - (unsigned int)R128_READ(R128_GUI_STAT)); - printk("PM4_STAT = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_STAT)); - printk("PM4_BUFFER_DL_WPTR = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR)); - printk("PM4_BUFFER_DL_RPTR = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR)); - printk("PM4_MICRO_CNTL = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_MICRO_CNTL)); - printk("PM4_BUFFER_CNTL = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL)); -} -#endif - -/* ================================================================ - * Engine, FIFO control - */ - -static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) -{ - u32 tmp; - int i; - - tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL; - R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) { - return 0; - } - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) -{ - int i; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; - if (slots >= entries) - return 0; - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) -{ - int i, ret; - - ret = r128_do_wait_for_fifo(dev_priv, 64); - if (ret) - return ret; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) { - r128_do_pixcache_flush(dev_priv); - return 0; - } - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -/* ================================================================ - * CCE control, initialization - */ - -/* Load the microcode for the CCE */ -static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) -{ - int i; - - DRM_DEBUG("\n"); - - r128_do_wait_for_idle(dev_priv); - - R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); - for (i = 0; i < 256; i++) { - R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); - R128_WRITE(R128_PM4_MICROCODE_DATAL, - r128_cce_microcode[i * 2 + 1]); - } -} - -/* Flush any pending commands to the CCE. This should only be used just - * prior to a wait for idle, as it informs the engine that the command - * stream is ending. - */ -static void r128_do_cce_flush(drm_r128_private_t * dev_priv) -{ - u32 tmp; - - tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE; - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp); -} - -/* Wait for the CCE to go idle. - */ -int r128_do_cce_idle(drm_r128_private_t * dev_priv) -{ - int i; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) { - int pm4stat = R128_READ(R128_PM4_STAT); - if (((pm4stat & R128_PM4_FIFOCNT_MASK) >= - dev_priv->cce_fifo_size) && - !(pm4stat & (R128_PM4_BUSY | - R128_PM4_GUI_ACTIVE))) { - return r128_do_pixcache_flush(dev_priv); - } - } - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); - r128_status(dev_priv); -#endif - return -EBUSY; -} - -/* Start the Concurrent Command Engine. - */ -static void r128_do_cce_start(drm_r128_private_t * dev_priv) -{ - r128_do_wait_for_idle(dev_priv); - - R128_WRITE(R128_PM4_BUFFER_CNTL, - dev_priv->cce_mode | dev_priv->ring.size_l2qw - | R128_PM4_BUFFER_CNTL_NOUPDATE); - R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */ - R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); - - dev_priv->cce_running = 1; -} - -/* Reset the Concurrent Command Engine. This will not flush any pending - * commands, so you must wait for the CCE command stream to complete - * before calling this routine. - */ -static void r128_do_cce_reset(drm_r128_private_t * dev_priv) -{ - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); - R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); - dev_priv->ring.tail = 0; -} - -/* Stop the Concurrent Command Engine. This will not flush any pending - * commands, so you must flush the command stream and wait for the CCE - * to go idle before calling this routine. - */ -static void r128_do_cce_stop(drm_r128_private_t * dev_priv) -{ - R128_WRITE(R128_PM4_MICRO_CNTL, 0); - R128_WRITE(R128_PM4_BUFFER_CNTL, - R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE); - - dev_priv->cce_running = 0; -} - -/* Reset the engine. This will stop the CCE if it is running. - */ -static int r128_do_engine_reset(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; - - r128_do_pixcache_flush(dev_priv); - - clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX); - mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL); - - R128_WRITE_PLL(R128_MCLK_CNTL, - mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); - - gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL); - - /* Taken from the sample code - do not change */ - R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); - R128_READ(R128_GEN_RESET_CNTL); - R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); - R128_READ(R128_GEN_RESET_CNTL); - - R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl); - R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index); - R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl); - - /* Reset the CCE ring */ - r128_do_cce_reset(dev_priv); - - /* The CCE is no longer running after an engine reset */ - dev_priv->cce_running = 0; - - /* Reset any pending vertex, indirect buffers */ - r128_freelist_reset(dev); - - return 0; -} - -static void r128_cce_init_ring_buffer(struct drm_device * dev, - drm_r128_private_t * dev_priv) -{ - u32 ring_start; - u32 tmp; - - DRM_DEBUG("\n"); - - /* The manual (p. 2) says this address is in "VM space". This - * means it's an offset from the start of AGP space. - */ -#if __OS_HAS_AGP - if (!dev_priv->is_pci) - ring_start = dev_priv->cce_ring->offset - dev->agp->base; - else -#endif - ring_start = dev_priv->cce_ring->offset - - (unsigned long)dev->sg->virtual; - - R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET); - - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); - R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); - - /* Set watermark control */ - R128_WRITE(R128_PM4_BUFFER_WM_CNTL, - ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT) - | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT) - | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT) - | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT)); - - /* Force read. Why? Because it's in the examples... */ - R128_READ(R128_PM4_BUFFER_ADDR); - - /* Turn on bus mastering */ - tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS; - R128_WRITE(R128_BUS_CNTL, tmp); -} - -static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) -{ - drm_r128_private_t *dev_priv; - - DRM_DEBUG("\n"); - - dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - - memset(dev_priv, 0, sizeof(drm_r128_private_t)); - - dev_priv->is_pci = init->is_pci; - - if (dev_priv->is_pci && !dev->sg) { - DRM_ERROR("PCI GART memory not allocated!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - dev_priv->usec_timeout = init->usec_timeout; - if (dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) { - DRM_DEBUG("TIMEOUT problem!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - dev_priv->cce_mode = init->cce_mode; - - /* GH: Simple idle check. - */ - atomic_set(&dev_priv->idle_count, 0); - - /* We don't support anything other than bus-mastering ring mode, - * but the ring can be in either AGP or PCI space for the ring - * read pointer. - */ - if ((init->cce_mode != R128_PM4_192BM) && - (init->cce_mode != R128_PM4_128BM_64INDBM) && - (init->cce_mode != R128_PM4_64BM_128INDBM) && - (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) { - DRM_DEBUG("Bad cce_mode!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - switch (init->cce_mode) { - case R128_PM4_NONPM4: - dev_priv->cce_fifo_size = 0; - break; - case R128_PM4_192PIO: - case R128_PM4_192BM: - dev_priv->cce_fifo_size = 192; - break; - case R128_PM4_128PIO_64INDBM: - case R128_PM4_128BM_64INDBM: - dev_priv->cce_fifo_size = 128; - break; - case R128_PM4_64PIO_128INDBM: - case R128_PM4_64BM_128INDBM: - case R128_PM4_64PIO_64VCBM_64INDBM: - case R128_PM4_64BM_64VCBM_64INDBM: - case R128_PM4_64PIO_64VCPIO_64INDPIO: - dev_priv->cce_fifo_size = 64; - break; - } - - switch (init->fb_bpp) { - case 16: - dev_priv->color_fmt = R128_DATATYPE_RGB565; - break; - case 32: - default: - dev_priv->color_fmt = R128_DATATYPE_ARGB8888; - break; - } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - switch (init->depth_bpp) { - case 16: - dev_priv->depth_fmt = R128_DATATYPE_RGB565; - break; - case 24: - case 32: - default: - dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; - break; - } - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - dev_priv->span_offset = init->span_offset; - - dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) | - (dev_priv->front_offset >> 5)); - dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) | - (dev_priv->back_offset >> 5)); - dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | - (dev_priv->depth_offset >> 5) | - R128_DST_TILE); - dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | - (dev_priv->span_offset >> 5)); - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio) { - DRM_ERROR("could not find mmio region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->cce_ring) { - DRM_ERROR("could not find cce ring region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if (!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find dma buffer region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - if (!dev_priv->is_pci) { - dev_priv->agp_textures = - drm_core_findmap(dev, init->agp_textures_offset); - if (!dev_priv->agp_textures) { - DRM_ERROR("could not find agp texture region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - } - - dev_priv->sarea_priv = - (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - -#if __OS_HAS_AGP - if (!dev_priv->is_pci) { - drm_core_ioremap(dev_priv->cce_ring, dev); - drm_core_ioremap(dev_priv->ring_rptr, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); - if (!dev_priv->cce_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { - DRM_ERROR("Could not ioremap agp regions!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -ENOMEM; - } - } else -#endif - { - dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset; - dev_priv->ring_rptr->handle = - (void *)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = - (void *)dev->agp_buffer_map->offset; - } - -#if __OS_HAS_AGP - if (!dev_priv->is_pci) - dev_priv->cce_buffers_offset = dev->agp->base; - else -#endif - dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual; - - dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle; - dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle - + init->ring_size / sizeof(u32)); - dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; - - dev_priv->ring.high_mark = 128; - - dev_priv->sarea_priv->last_frame = 0; - R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); - - dev_priv->sarea_priv->last_dispatch = 0; - R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch); - -#if __OS_HAS_AGP - if (dev_priv->is_pci) { -#endif - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); - dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; - dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; - dev_priv->gart_info.addr = NULL; - dev_priv->gart_info.bus_addr = 0; - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { - DRM_ERROR("failed to init PCI GART!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -ENOMEM; - } - R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); -#if __OS_HAS_AGP - } -#endif - - r128_cce_init_ring_buffer(dev, dev_priv); - r128_cce_load_microcode(dev_priv); - - dev->dev_private = (void *)dev_priv; - - r128_do_engine_reset(dev); - - return 0; -} - -int r128_do_cleanup_cce(struct drm_device * dev) -{ - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - drm_r128_private_t *dev_priv = dev->dev_private; - -#if __OS_HAS_AGP - if (!dev_priv->is_pci) { - if (dev_priv->cce_ring != NULL) - drm_core_ioremapfree(dev_priv->cce_ring, dev); - if (dev_priv->ring_rptr != NULL) - drm_core_ioremapfree(dev_priv->ring_rptr, dev); - if (dev->agp_buffer_map != NULL) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } - } else -#endif - { - if (dev_priv->gart_info.bus_addr) - if (!drm_ati_pcigart_cleanup(dev, - &dev_priv->gart_info)) - DRM_ERROR - ("failed to cleanup PCI GART!\n"); - } - - drm_free(dev->dev_private, sizeof(drm_r128_private_t), - DRM_MEM_DRIVER); - dev->dev_private = NULL; - } - - return 0; -} - -int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_init_t *init = data; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - switch (init->func) { - case R128_INIT_CCE: - return r128_do_init_cce(dev, init); - case R128_CLEANUP_CCE: - return r128_do_cleanup_cce(dev); - } - - return -EINVAL; -} - -int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { - DRM_DEBUG("while CCE running\n"); - return 0; - } - - r128_do_cce_start(dev_priv); - - return 0; -} - -/* Stop the CCE. The engine must have been idled before calling this - * routine. - */ -int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_cce_stop_t *stop = data; - int ret; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Flush any pending CCE commands. This ensures any outstanding - * commands are exectuted by the engine before we turn it off. - */ - if (stop->flush) { - r128_do_cce_flush(dev_priv); - } - - /* If we fail to make the engine go idle, we return an error - * code so that the DRM ioctl wrapper can try again. - */ - if (stop->idle) { - ret = r128_do_cce_idle(dev_priv); - if (ret) - return ret; - } - - /* Finally, we can turn off the CCE. If the engine isn't idle, - * we will get some dropped triangles as they won't be fully - * rendered before the CCE is shut down. - */ - r128_do_cce_stop(dev_priv); - - /* Reset the engine */ - r128_do_engine_reset(dev); - - return 0; -} - -/* Just reset the CCE ring. Called as part of an X Server engine reset. - */ -int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_DEBUG("called before init done\n"); - return -EINVAL; - } - - r128_do_cce_reset(dev_priv); - - /* The CCE is no longer running after an engine reset */ - dev_priv->cce_running = 0; - - return 0; -} - -int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (dev_priv->cce_running) { - r128_do_cce_flush(dev_priv); - } - - return r128_do_cce_idle(dev_priv); -} - -int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return r128_do_engine_reset(dev); -} - -int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - return -EINVAL; -} - -/* ================================================================ - * Freelist management - */ -#define R128_BUFFER_USED 0xffffffff -#define R128_BUFFER_FREE 0 - -#if 0 -static int r128_freelist_init(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_freelist_t *entry; - int i; - - dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); - if (dev_priv->head == NULL) - return -ENOMEM; - - memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t)); - dev_priv->head->age = R128_BUFFER_USED; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - - entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); - if (!entry) - return -ENOMEM; - - entry->age = R128_BUFFER_FREE; - entry->buf = buf; - entry->prev = dev_priv->head; - entry->next = dev_priv->head->next; - if (!entry->next) - dev_priv->tail = entry; - - buf_priv->discard = 0; - buf_priv->dispatched = 0; - buf_priv->list_entry = entry; - - dev_priv->head->next = entry; - - if (dev_priv->head->next) - dev_priv->head->next->prev = entry; - } - - return 0; - -} -#endif - -static struct drm_buf *r128_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv; - struct drm_buf *buf; - int i, t; - - /* FIXME: Optimize -- use freelist code */ - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if (!buf->file_priv) - return buf; - } - - for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = R128_READ(R128_LAST_DISPATCH_REG); - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if (buf->pending && buf_priv->age <= done_age) { - /* The buffer has been processed, so it - * can now be used. - */ - buf->pending = 0; - return buf; - } - } - DRM_UDELAY(1); - } - - DRM_DEBUG("returning NULL!\n"); - return NULL; -} - -void r128_freelist_reset(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->age = 0; - } -} - -/* ================================================================ - * CCE command submission - */ - -int r128_wait_ring(drm_r128_private_t * dev_priv, int n) -{ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; - int i; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - r128_update_ring_snapshot(dev_priv); - if (ring->space >= n) - return 0; - DRM_UDELAY(1); - } - - /* FIXME: This is being ignored... */ - DRM_ERROR("failed!\n"); - return -EBUSY; -} - -static int r128_cce_get_buffers(struct drm_device * dev, - struct drm_file *file_priv, - struct drm_dma * d) -{ - int i; - struct drm_buf *buf; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = r128_freelist_get(dev); - if (!buf) - return -EAGAIN; - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, - sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, - sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int ret = 0; - struct drm_dma *d = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - d->granted_count = 0; - - if (d->request_count) { - ret = r128_cce_get_buffers(dev, file_priv, d); - } - - return ret; -} diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h deleted file mode 100644 index 8d8878b..0000000 --- a/drivers/char/drm/r128_drm.h +++ /dev/null @@ -1,326 +0,0 @@ -/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- - * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com - */ -/* - * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - * Kevin E. Martin - */ - -#ifndef __R128_DRM_H__ -#define __R128_DRM_H__ - -/* WARNING: If you change any of these defines, make sure to change the - * defines in the X server file (r128_sarea.h) - */ -#ifndef __R128_SAREA_DEFINES__ -#define __R128_SAREA_DEFINES__ - -/* What needs to be changed for the current vertex buffer? - */ -#define R128_UPLOAD_CONTEXT 0x001 -#define R128_UPLOAD_SETUP 0x002 -#define R128_UPLOAD_TEX0 0x004 -#define R128_UPLOAD_TEX1 0x008 -#define R128_UPLOAD_TEX0IMAGES 0x010 -#define R128_UPLOAD_TEX1IMAGES 0x020 -#define R128_UPLOAD_CORE 0x040 -#define R128_UPLOAD_MASKS 0x080 -#define R128_UPLOAD_WINDOW 0x100 -#define R128_UPLOAD_CLIPRECTS 0x200 /* handled client-side */ -#define R128_REQUIRE_QUIESCENCE 0x400 -#define R128_UPLOAD_ALL 0x7ff - -#define R128_FRONT 0x1 -#define R128_BACK 0x2 -#define R128_DEPTH 0x4 - -/* Primitive types - */ -#define R128_POINTS 0x1 -#define R128_LINES 0x2 -#define R128_LINE_STRIP 0x3 -#define R128_TRIANGLES 0x4 -#define R128_TRIANGLE_FAN 0x5 -#define R128_TRIANGLE_STRIP 0x6 - -/* Vertex/indirect buffer size - */ -#define R128_BUFFER_SIZE 16384 - -/* Byte offsets for indirect buffer data - */ -#define R128_INDEX_PRIM_OFFSET 20 -#define R128_HOSTDATA_BLIT_OFFSET 32 - -/* Keep these small for testing. - */ -#define R128_NR_SAREA_CLIPRECTS 12 - -/* There are 2 heaps (local/AGP). Each region within a heap is a - * minimum of 64k, and there are at most 64 of them per heap. - */ -#define R128_LOCAL_TEX_HEAP 0 -#define R128_AGP_TEX_HEAP 1 -#define R128_NR_TEX_HEAPS 2 -#define R128_NR_TEX_REGIONS 64 -#define R128_LOG_TEX_GRANULARITY 16 - -#define R128_NR_CONTEXT_REGS 12 - -#define R128_MAX_TEXTURE_LEVELS 11 -#define R128_MAX_TEXTURE_UNITS 2 - -#endif /* __R128_SAREA_DEFINES__ */ - -typedef struct { - /* Context state - can be written in one large chunk */ - unsigned int dst_pitch_offset_c; - unsigned int dp_gui_master_cntl_c; - unsigned int sc_top_left_c; - unsigned int sc_bottom_right_c; - unsigned int z_offset_c; - unsigned int z_pitch_c; - unsigned int z_sten_cntl_c; - unsigned int tex_cntl_c; - unsigned int misc_3d_state_cntl_reg; - unsigned int texture_clr_cmp_clr_c; - unsigned int texture_clr_cmp_msk_c; - unsigned int fog_color_c; - - /* Texture state */ - unsigned int tex_size_pitch_c; - unsigned int constant_color_c; - - /* Setup state */ - unsigned int pm4_vc_fpu_setup; - unsigned int setup_cntl; - - /* Mask state */ - unsigned int dp_write_mask; - unsigned int sten_ref_mask_c; - unsigned int plane_3d_mask_c; - - /* Window state */ - unsigned int window_xy_offset; - - /* Core state */ - unsigned int scale_3d_cntl; -} drm_r128_context_regs_t; - -/* Setup registers for each texture unit - */ -typedef struct { - unsigned int tex_cntl; - unsigned int tex_combine_cntl; - unsigned int tex_size_pitch; - unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS]; - unsigned int tex_border_color; -} drm_r128_texture_regs_t; - -typedef struct drm_r128_sarea { - /* The channel for communication of state information to the kernel - * on firing a vertex buffer. - */ - drm_r128_context_regs_t context_state; - drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS]; - unsigned int dirty; - unsigned int vertsize; - unsigned int vc_format; - - /* The current cliprects, or a subset thereof. - */ - struct drm_clip_rect boxes[R128_NR_SAREA_CLIPRECTS]; - unsigned int nbox; - - /* Counters for client-side throttling of rendering clients. - */ - unsigned int last_frame; - unsigned int last_dispatch; - - struct drm_tex_region tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1]; - unsigned int tex_age[R128_NR_TEX_HEAPS]; - int ctx_owner; - int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */ - int pfCurrentPage; /* which buffer is being displayed? */ -} drm_r128_sarea_t; - -/* WARNING: If you change any of these defines, make sure to change the - * defines in the Xserver file (xf86drmR128.h) - */ - -/* Rage 128 specific ioctls - * The device specific ioctl range is 0x40 to 0x79. - */ -#define DRM_R128_INIT 0x00 -#define DRM_R128_CCE_START 0x01 -#define DRM_R128_CCE_STOP 0x02 -#define DRM_R128_CCE_RESET 0x03 -#define DRM_R128_CCE_IDLE 0x04 -/* 0x05 not used */ -#define DRM_R128_RESET 0x06 -#define DRM_R128_SWAP 0x07 -#define DRM_R128_CLEAR 0x08 -#define DRM_R128_VERTEX 0x09 -#define DRM_R128_INDICES 0x0a -#define DRM_R128_BLIT 0x0b -#define DRM_R128_DEPTH 0x0c -#define DRM_R128_STIPPLE 0x0d -/* 0x0e not used */ -#define DRM_R128_INDIRECT 0x0f -#define DRM_R128_FULLSCREEN 0x10 -#define DRM_R128_CLEAR2 0x11 -#define DRM_R128_GETPARAM 0x12 -#define DRM_R128_FLIP 0x13 - -#define DRM_IOCTL_R128_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INIT, drm_r128_init_t) -#define DRM_IOCTL_R128_CCE_START DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_START) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CCE_STOP, drm_r128_cce_stop_t) -#define DRM_IOCTL_R128_CCE_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_RESET) -#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_IDLE) -/* 0x05 not used */ -#define DRM_IOCTL_R128_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_RESET) -#define DRM_IOCTL_R128_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_R128_SWAP) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_R128_VERTEX, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_BLIT, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( DRM_COMMAND_BASE + DRM_R128_DEPTH, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_R128_STIPPLE, drm_r128_stipple_t) -/* 0x0e not used */ -#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t) -#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t) -#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t) -#define DRM_IOCTL_R128_GETPARAM DRM_IOWR( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) -#define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP) - -typedef struct drm_r128_init { - enum { - R128_INIT_CCE = 0x01, - R128_CLEANUP_CCE = 0x02 - } func; - unsigned long sarea_priv_offset; - int is_pci; - int cce_mode; - int cce_secure; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - unsigned int span_offset; - - unsigned long fb_offset; - unsigned long mmio_offset; - unsigned long ring_offset; - unsigned long ring_rptr_offset; - unsigned long buffers_offset; - unsigned long agp_textures_offset; -} drm_r128_init_t; - -typedef struct drm_r128_cce_stop { - int flush; - int idle; -} drm_r128_cce_stop_t; - -typedef struct drm_r128_clear { - unsigned int flags; - unsigned int clear_color; - unsigned int clear_depth; - unsigned int color_mask; - unsigned int depth_mask; -} drm_r128_clear_t; - -typedef struct drm_r128_vertex { - int prim; - int idx; /* Index of vertex buffer */ - int count; /* Number of vertices in buffer */ - int discard; /* Client finished with buffer? */ -} drm_r128_vertex_t; - -typedef struct drm_r128_indices { - int prim; - int idx; - int start; - int end; - int discard; /* Client finished with buffer? */ -} drm_r128_indices_t; - -typedef struct drm_r128_blit { - int idx; - int pitch; - int offset; - int format; - unsigned short x, y; - unsigned short width, height; -} drm_r128_blit_t; - -typedef struct drm_r128_depth { - enum { - R128_WRITE_SPAN = 0x01, - R128_WRITE_PIXELS = 0x02, - R128_READ_SPAN = 0x03, - R128_READ_PIXELS = 0x04 - } func; - int n; - int __user *x; - int __user *y; - unsigned int __user *buffer; - unsigned char __user *mask; -} drm_r128_depth_t; - -typedef struct drm_r128_stipple { - unsigned int __user *mask; -} drm_r128_stipple_t; - -typedef struct drm_r128_indirect { - int idx; - int start; - int end; - int discard; -} drm_r128_indirect_t; - -typedef struct drm_r128_fullscreen { - enum { - R128_INIT_FULLSCREEN = 0x01, - R128_CLEANUP_FULLSCREEN = 0x02 - } func; -} drm_r128_fullscreen_t; - -/* 2.3: An ioctl to get parameters that aren't available to the 3d - * client any other way. - */ -#define R128_PARAM_IRQ_NR 1 - -typedef struct drm_r128_getparam { - int param; - void __user *value; -} drm_r128_getparam_t; - -#endif diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c deleted file mode 100644 index 6108e75..0000000 --- a/drivers/char/drm/r128_drv.c +++ /dev/null @@ -1,103 +0,0 @@ -/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*- - * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - r128_PCI_IDS -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | - DRIVER_IRQ_VBL, - .dev_priv_size = sizeof(drm_r128_buf_priv_t), - .preclose = r128_driver_preclose, - .lastclose = r128_driver_lastclose, - .vblank_wait = r128_driver_vblank_wait, - .irq_preinstall = r128_driver_irq_preinstall, - .irq_postinstall = r128_driver_irq_postinstall, - .irq_uninstall = r128_driver_irq_uninstall, - .irq_handler = r128_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = r128_ioctls, - .dma_ioctl = r128_cce_buffers, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = r128_compat_ioctl, -#endif - }, - - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init r128_init(void) -{ - driver.num_ioctls = r128_max_ioctl; - return drm_init(&driver); -} - -static void __exit r128_exit(void) -{ - drm_exit(&driver); -} - -module_init(r128_init); -module_exit(r128_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h deleted file mode 100644 index 011105e..0000000 --- a/drivers/char/drm/r128_drv.h +++ /dev/null @@ -1,522 +0,0 @@ -/* r128_drv.h -- Private header for r128 driver -*- linux-c -*- - * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com - */ -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Kevin E. Martin - * Gareth Hughes - * Michel Dänzer - */ - -#ifndef __R128_DRV_H__ -#define __R128_DRV_H__ - -/* General customization: - */ -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "r128" -#define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20030725" - -/* Interface history: - * - * ?? - ?? - * 2.4 - Add support for ycbcr textures (no new ioctls) - * 2.5 - Add FLIP ioctl, disable FULLSCREEN. - */ -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 5 -#define DRIVER_PATCHLEVEL 0 - -#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) - -typedef struct drm_r128_freelist { - unsigned int age; - struct drm_buf *buf; - struct drm_r128_freelist *next; - struct drm_r128_freelist *prev; -} drm_r128_freelist_t; - -typedef struct drm_r128_ring_buffer { - u32 *start; - u32 *end; - int size; - int size_l2qw; - - u32 tail; - u32 tail_mask; - int space; - - int high_mark; -} drm_r128_ring_buffer_t; - -typedef struct drm_r128_private { - drm_r128_ring_buffer_t ring; - drm_r128_sarea_t *sarea_priv; - - int cce_mode; - int cce_fifo_size; - int cce_running; - - drm_r128_freelist_t *head; - drm_r128_freelist_t *tail; - - int usec_timeout; - int is_pci; - unsigned long cce_buffers_offset; - - atomic_t idle_count; - - int page_flipping; - int current_page; - u32 crtc_offset; - u32 crtc_offset_cntl; - - u32 color_fmt; - unsigned int front_offset; - unsigned int front_pitch; - unsigned int back_offset; - unsigned int back_pitch; - - u32 depth_fmt; - unsigned int depth_offset; - unsigned int depth_pitch; - unsigned int span_offset; - - u32 front_pitch_offset_c; - u32 back_pitch_offset_c; - u32 depth_pitch_offset_c; - u32 span_pitch_offset_c; - - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *cce_ring; - drm_local_map_t *ring_rptr; - drm_local_map_t *agp_textures; - struct drm_ati_pcigart_info gart_info; -} drm_r128_private_t; - -typedef struct drm_r128_buf_priv { - u32 age; - int prim; - int discard; - int dispatched; - drm_r128_freelist_t *list_entry; -} drm_r128_buf_priv_t; - -extern struct drm_ioctl_desc r128_ioctls[]; -extern int r128_max_ioctl; - - /* r128_cce.c */ -extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); - -extern void r128_freelist_reset(struct drm_device * dev); - -extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); - -extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); -extern int r128_do_cleanup_cce(struct drm_device * dev); - -extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); - -extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); -extern void r128_driver_irq_preinstall(struct drm_device * dev); -extern void r128_driver_irq_postinstall(struct drm_device * dev); -extern void r128_driver_irq_uninstall(struct drm_device * dev); -extern void r128_driver_lastclose(struct drm_device * dev); -extern void r128_driver_preclose(struct drm_device * dev, - struct drm_file *file_priv); - -extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -/* Register definitions, register access macros and drmAddMap constants - * for Rage 128 kernel driver. - */ - -#define R128_AUX_SC_CNTL 0x1660 -# define R128_AUX1_SC_EN (1 << 0) -# define R128_AUX1_SC_MODE_OR (0 << 1) -# define R128_AUX1_SC_MODE_NAND (1 << 1) -# define R128_AUX2_SC_EN (1 << 2) -# define R128_AUX2_SC_MODE_OR (0 << 3) -# define R128_AUX2_SC_MODE_NAND (1 << 3) -# define R128_AUX3_SC_EN (1 << 4) -# define R128_AUX3_SC_MODE_OR (0 << 5) -# define R128_AUX3_SC_MODE_NAND (1 << 5) -#define R128_AUX1_SC_LEFT 0x1664 -#define R128_AUX1_SC_RIGHT 0x1668 -#define R128_AUX1_SC_TOP 0x166c -#define R128_AUX1_SC_BOTTOM 0x1670 -#define R128_AUX2_SC_LEFT 0x1674 -#define R128_AUX2_SC_RIGHT 0x1678 -#define R128_AUX2_SC_TOP 0x167c -#define R128_AUX2_SC_BOTTOM 0x1680 -#define R128_AUX3_SC_LEFT 0x1684 -#define R128_AUX3_SC_RIGHT 0x1688 -#define R128_AUX3_SC_TOP 0x168c -#define R128_AUX3_SC_BOTTOM 0x1690 - -#define R128_BRUSH_DATA0 0x1480 -#define R128_BUS_CNTL 0x0030 -# define R128_BUS_MASTER_DIS (1 << 6) - -#define R128_CLOCK_CNTL_INDEX 0x0008 -#define R128_CLOCK_CNTL_DATA 0x000c -# define R128_PLL_WR_EN (1 << 7) -#define R128_CONSTANT_COLOR_C 0x1d34 -#define R128_CRTC_OFFSET 0x0224 -#define R128_CRTC_OFFSET_CNTL 0x0228 -# define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16) - -#define R128_DP_GUI_MASTER_CNTL 0x146c -# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) -# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) -# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) -# define R128_GMC_BRUSH_NONE (15 << 4) -# define R128_GMC_DST_16BPP (4 << 8) -# define R128_GMC_DST_24BPP (5 << 8) -# define R128_GMC_DST_32BPP (6 << 8) -# define R128_GMC_DST_DATATYPE_SHIFT 8 -# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) -# define R128_DP_SRC_SOURCE_MEMORY (2 << 24) -# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24) -# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) -# define R128_GMC_AUX_CLIP_DIS (1 << 29) -# define R128_GMC_WR_MSK_DIS (1 << 30) -# define R128_ROP3_S 0x00cc0000 -# define R128_ROP3_P 0x00f00000 -#define R128_DP_WRITE_MASK 0x16cc -#define R128_DST_PITCH_OFFSET_C 0x1c80 -# define R128_DST_TILE (1 << 31) - -#define R128_GEN_INT_CNTL 0x0040 -# define R128_CRTC_VBLANK_INT_EN (1 << 0) -#define R128_GEN_INT_STATUS 0x0044 -# define R128_CRTC_VBLANK_INT (1 << 0) -# define R128_CRTC_VBLANK_INT_AK (1 << 0) -#define R128_GEN_RESET_CNTL 0x00f0 -# define R128_SOFT_RESET_GUI (1 << 0) - -#define R128_GUI_SCRATCH_REG0 0x15e0 -#define R128_GUI_SCRATCH_REG1 0x15e4 -#define R128_GUI_SCRATCH_REG2 0x15e8 -#define R128_GUI_SCRATCH_REG3 0x15ec -#define R128_GUI_SCRATCH_REG4 0x15f0 -#define R128_GUI_SCRATCH_REG5 0x15f4 - -#define R128_GUI_STAT 0x1740 -# define R128_GUI_FIFOCNT_MASK 0x0fff -# define R128_GUI_ACTIVE (1 << 31) - -#define R128_MCLK_CNTL 0x000f -# define R128_FORCE_GCP (1 << 16) -# define R128_FORCE_PIPE3D_CP (1 << 17) -# define R128_FORCE_RCP (1 << 18) - -#define R128_PC_GUI_CTLSTAT 0x1748 -#define R128_PC_NGUI_CTLSTAT 0x0184 -# define R128_PC_FLUSH_GUI (3 << 0) -# define R128_PC_RI_GUI (1 << 2) -# define R128_PC_FLUSH_ALL 0x00ff -# define R128_PC_BUSY (1 << 31) - -#define R128_PCI_GART_PAGE 0x017c -#define R128_PRIM_TEX_CNTL_C 0x1cb0 - -#define R128_SCALE_3D_CNTL 0x1a00 -#define R128_SEC_TEX_CNTL_C 0x1d00 -#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c -#define R128_SETUP_CNTL 0x1bc4 -#define R128_STEN_REF_MASK_C 0x1d40 - -#define R128_TEX_CNTL_C 0x1c9c -# define R128_TEX_CACHE_FLUSH (1 << 23) - -#define R128_WAIT_UNTIL 0x1720 -# define R128_EVENT_CRTC_OFFSET (1 << 0) -#define R128_WINDOW_XY_OFFSET 0x1bcc - -/* CCE registers - */ -#define R128_PM4_BUFFER_OFFSET 0x0700 -#define R128_PM4_BUFFER_CNTL 0x0704 -# define R128_PM4_MASK (15 << 28) -# define R128_PM4_NONPM4 (0 << 28) -# define R128_PM4_192PIO (1 << 28) -# define R128_PM4_192BM (2 << 28) -# define R128_PM4_128PIO_64INDBM (3 << 28) -# define R128_PM4_128BM_64INDBM (4 << 28) -# define R128_PM4_64PIO_128INDBM (5 << 28) -# define R128_PM4_64BM_128INDBM (6 << 28) -# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) -# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) -# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) -# define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27) - -#define R128_PM4_BUFFER_WM_CNTL 0x0708 -# define R128_WMA_SHIFT 0 -# define R128_WMB_SHIFT 8 -# define R128_WMC_SHIFT 16 -# define R128_WB_WM_SHIFT 24 - -#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c -#define R128_PM4_BUFFER_DL_RPTR 0x0710 -#define R128_PM4_BUFFER_DL_WPTR 0x0714 -# define R128_PM4_BUFFER_DL_DONE (1 << 31) - -#define R128_PM4_VC_FPU_SETUP 0x071c - -#define R128_PM4_IW_INDOFF 0x0738 -#define R128_PM4_IW_INDSIZE 0x073c - -#define R128_PM4_STAT 0x07b8 -# define R128_PM4_FIFOCNT_MASK 0x0fff -# define R128_PM4_BUSY (1 << 16) -# define R128_PM4_GUI_ACTIVE (1 << 31) - -#define R128_PM4_MICROCODE_ADDR 0x07d4 -#define R128_PM4_MICROCODE_RADDR 0x07d8 -#define R128_PM4_MICROCODE_DATAH 0x07dc -#define R128_PM4_MICROCODE_DATAL 0x07e0 - -#define R128_PM4_BUFFER_ADDR 0x07f0 -#define R128_PM4_MICRO_CNTL 0x07fc -# define R128_PM4_MICRO_FREERUN (1 << 30) - -#define R128_PM4_FIFO_DATA_EVEN 0x1000 -#define R128_PM4_FIFO_DATA_ODD 0x1004 - -/* CCE command packets - */ -#define R128_CCE_PACKET0 0x00000000 -#define R128_CCE_PACKET1 0x40000000 -#define R128_CCE_PACKET2 0x80000000 -#define R128_CCE_PACKET3 0xC0000000 -# define R128_CNTL_HOSTDATA_BLT 0x00009400 -# define R128_CNTL_PAINT_MULTI 0x00009A00 -# define R128_CNTL_BITBLT_MULTI 0x00009B00 -# define R128_3D_RNDR_GEN_INDX_PRIM 0x00002300 - -#define R128_CCE_PACKET_MASK 0xC0000000 -#define R128_CCE_PACKET_COUNT_MASK 0x3fff0000 -#define R128_CCE_PACKET0_REG_MASK 0x000007ff -#define R128_CCE_PACKET1_REG0_MASK 0x000007ff -#define R128_CCE_PACKET1_REG1_MASK 0x003ff800 - -#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 -#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 -#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 -#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 -#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 -#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 -#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 -#define R128_CCE_VC_CNTL_NUM_SHIFT 16 - -#define R128_DATATYPE_VQ 0 -#define R128_DATATYPE_CI4 1 -#define R128_DATATYPE_CI8 2 -#define R128_DATATYPE_ARGB1555 3 -#define R128_DATATYPE_RGB565 4 -#define R128_DATATYPE_RGB888 5 -#define R128_DATATYPE_ARGB8888 6 -#define R128_DATATYPE_RGB332 7 -#define R128_DATATYPE_Y8 8 -#define R128_DATATYPE_RGB8 9 -#define R128_DATATYPE_CI16 10 -#define R128_DATATYPE_YVYU422 11 -#define R128_DATATYPE_VYUY422 12 -#define R128_DATATYPE_AYUV444 14 -#define R128_DATATYPE_ARGB4444 15 - -/* Constants */ -#define R128_AGP_OFFSET 0x02000000 - -#define R128_WATERMARK_L 16 -#define R128_WATERMARK_M 8 -#define R128_WATERMARK_N 8 -#define R128_WATERMARK_K 128 - -#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */ - -#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0 -#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1 -#define R128_MAX_VB_AGE 0x7fffffff -#define R128_MAX_VB_VERTS (0xffff) - -#define R128_RING_HIGH_MARK 128 - -#define R128_PERFORMANCE_BOXES 0 - -#define R128_PCIGART_TABLE_SIZE 32768 - -#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) -#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) -#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) - -#define R128_WRITE_PLL(addr,val) \ -do { \ - R128_WRITE8(R128_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | R128_PLL_WR_EN); \ - R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ -} while (0) - -#define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \ - ((n) << 16) | ((reg) >> 2)) -#define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \ - (((reg1) >> 2) << 11) | ((reg0) >> 2)) -#define CCE_PACKET2() (R128_CCE_PACKET2) -#define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \ - (pkt) | ((n) << 16)) - -static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv) -{ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; - ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32); - if (ring->space <= 0) - ring->space += ring->size; -} - -/* ================================================================ - * Misc helper macros - */ - -#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ - if ( ring->space < ring->high_mark ) { \ - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ - r128_update_ring_snapshot( dev_priv ); \ - if ( ring->space >= ring->high_mark ) \ - goto __ring_space_done; \ - DRM_UDELAY(1); \ - } \ - DRM_ERROR( "ring space check failed!\n" ); \ - return -EBUSY; \ - } \ - __ring_space_done: \ - ; \ -} while (0) - -#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ - if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \ - int __ret = r128_do_cce_idle( dev_priv ); \ - if ( __ret ) return __ret; \ - sarea_priv->last_dispatch = 0; \ - r128_freelist_reset( dev ); \ - } \ -} while (0) - -#define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ - OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \ - OUT_RING( R128_EVENT_CRTC_OFFSET ); \ -} while (0) - -/* ================================================================ - * Ring control - */ - -#define R128_VERBOSE 0 - -#define RING_LOCALS \ - int write, _nr; unsigned int tail_mask; volatile u32 *ring; - -#define BEGIN_RING( n ) do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ - } \ - if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ - COMMIT_RING(); \ - r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ - } \ - _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ - ring = dev_priv->ring.start; \ - write = dev_priv->ring.tail; \ - tail_mask = dev_priv->ring.tail_mask; \ -} while (0) - -/* You can set this to zero if you want. If the card locks up, you'll - * need to keep this set. It works around a bug in early revs of the - * Rage 128 chipset, where the CCE would read 32 dwords past the end of - * the ring buffer before wrapping around. - */ -#define R128_BROKEN_CCE 1 - -#define ADVANCE_RING() do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ - write, dev_priv->ring.tail ); \ - } \ - if ( R128_BROKEN_CCE && write < 32 ) { \ - memcpy( dev_priv->ring.end, \ - dev_priv->ring.start, \ - write * sizeof(u32) ); \ - } \ - if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \ - DRM_ERROR( \ - "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ - ((dev_priv->ring.tail + _nr) & tail_mask), \ - write, __LINE__); \ - } else \ - dev_priv->ring.tail = write; \ -} while (0) - -#define COMMIT_RING() do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \ - dev_priv->ring.tail ); \ - } \ - DRM_MEMORYBARRIER(); \ - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \ - R128_READ( R128_PM4_BUFFER_DL_WPTR ); \ -} while (0) - -#define OUT_RING( x ) do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ - (unsigned int)(x), write ); \ - } \ - ring[write++] = cpu_to_le32( x ); \ - write &= tail_mask; \ -} while (0) - -#endif /* __R128_DRV_H__ */ diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c deleted file mode 100644 index d3cb676..0000000 --- a/drivers/char/drm/r128_ioc32.c +++ /dev/null @@ -1,221 +0,0 @@ -/** - * \file r128_ioc32.c - * - * 32-bit ioctl compatibility routines for the R128 DRM. - * - * \author Dave Airlie with code from patches by Egbert Eich - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Egbert Eich 2003,2004 - * Copyright (C) Dave Airlie 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" - -typedef struct drm_r128_init32 { - int func; - unsigned int sarea_priv_offset; - int is_pci; - int cce_mode; - int cce_secure; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - unsigned int span_offset; - - unsigned int fb_offset; - unsigned int mmio_offset; - unsigned int ring_offset; - unsigned int ring_rptr_offset; - unsigned int buffers_offset; - unsigned int agp_textures_offset; -} drm_r128_init32_t; - -static int compat_r128_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_init32_t init32; - drm_r128_init_t __user *init; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.is_pci, &init->is_pci) - || __put_user(init32.cce_mode, &init->cce_mode) - || __put_user(init32.cce_secure, &init->cce_secure) - || __put_user(init32.ring_size, &init->ring_size) - || __put_user(init32.usec_timeout, &init->usec_timeout) - || __put_user(init32.fb_bpp, &init->fb_bpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_bpp, &init->depth_bpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.span_offset, &init->span_offset) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.ring_offset, &init->ring_offset) - || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset) - || __put_user(init32.agp_textures_offset, - &init->agp_textures_offset)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_INIT, (unsigned long)init); -} - -typedef struct drm_r128_depth32 { - int func; - int n; - u32 x; - u32 y; - u32 buffer; - u32 mask; -} drm_r128_depth32_t; - -static int compat_r128_depth(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_depth32_t depth32; - drm_r128_depth_t __user *depth; - - if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32))) - return -EFAULT; - - depth = compat_alloc_user_space(sizeof(*depth)); - if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth)) - || __put_user(depth32.func, &depth->func) - || __put_user(depth32.n, &depth->n) - || __put_user((int __user *)(unsigned long)depth32.x, &depth->x) - || __put_user((int __user *)(unsigned long)depth32.y, &depth->y) - || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, - &depth->buffer) - || __put_user((unsigned char __user *)(unsigned long)depth32.mask, - &depth->mask)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_DEPTH, (unsigned long)depth); - -} - -typedef struct drm_r128_stipple32 { - u32 mask; -} drm_r128_stipple32_t; - -static int compat_r128_stipple(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_stipple32_t stipple32; - drm_r128_stipple_t __user *stipple; - - if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32))) - return -EFAULT; - - stipple = compat_alloc_user_space(sizeof(*stipple)); - if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple)) - || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, - &stipple->mask)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); -} - -typedef struct drm_r128_getparam32 { - int param; - u32 value; -} drm_r128_getparam32_t; - -static int compat_r128_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_getparam32_t getparam32; - drm_r128_getparam_t __user *getparam; - - if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) - return -EFAULT; - - getparam = compat_alloc_user_space(sizeof(*getparam)); - if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) - || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, - &getparam->value)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); -} - -drm_ioctl_compat_t *r128_compat_ioctls[] = { - [DRM_R128_INIT] = compat_r128_init, - [DRM_R128_DEPTH] = compat_r128_depth, - [DRM_R128_STIPPLE] = compat_r128_stipple, - [DRM_R128_GETPARAM] = compat_r128_getparam, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) - fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; - - lock_kernel(); /* XXX for now */ - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - - return ret; -} diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c deleted file mode 100644 index c76fdca..0000000 --- a/drivers/char/drm/r128_irq.c +++ /dev/null @@ -1,101 +0,0 @@ -/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - * Eric Anholt - */ - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - int status; - - status = R128_READ(R128_GEN_INT_STATUS); - - /* VBLANK interrupt */ - if (status & R128_CRTC_VBLANK_INT) { - R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); - atomic_inc(&dev->vbl_received); - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) -{ - unsigned int cur_vblank; - int ret = 0; - - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using vertical blanks... - */ - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) - - *sequence) <= (1 << 23))); - - *sequence = cur_vblank; - - return ret; -} - -void r128_driver_irq_preinstall(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - - /* Disable *all* interrupts */ - R128_WRITE(R128_GEN_INT_CNTL, 0); - /* Clear vblank bit if it's already high */ - R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); -} - -void r128_driver_irq_postinstall(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - - /* Turn on VBL interrupt */ - R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); -} - -void r128_driver_irq_uninstall(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - if (!dev_priv) - return; - - /* Disable *all* interrupts */ - R128_WRITE(R128_GEN_INT_CNTL, 0); -} diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c deleted file mode 100644 index 51a9afc..0000000 --- a/drivers/char/drm/r128_state.c +++ /dev/null @@ -1,1681 +0,0 @@ -/* r128_state.c -- State support for r128 -*- linux-c -*- - * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com - */ -/* - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -/* ================================================================ - * CCE hardware state programming functions - */ - -static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, - struct drm_clip_rect * boxes, int count) -{ - u32 aux_sc_cntl = 0x00000000; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING((count < 3 ? count : 3) * 5 + 2); - - if (count >= 1) { - OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3)); - OUT_RING(boxes[0].x1); - OUT_RING(boxes[0].x2 - 1); - OUT_RING(boxes[0].y1); - OUT_RING(boxes[0].y2 - 1); - - aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); - } - if (count >= 2) { - OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3)); - OUT_RING(boxes[1].x1); - OUT_RING(boxes[1].x2 - 1); - OUT_RING(boxes[1].y1); - OUT_RING(boxes[1].y2 - 1); - - aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); - } - if (count >= 3) { - OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3)); - OUT_RING(boxes[2].x1); - OUT_RING(boxes[2].x2 - 1); - OUT_RING(boxes[2].y1); - OUT_RING(boxes[2].y2 - 1); - - aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); - } - - OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0)); - OUT_RING(aux_sc_cntl); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0)); - OUT_RING(ctx->scale_3d_cntl); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(13); - - OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11)); - OUT_RING(ctx->dst_pitch_offset_c); - OUT_RING(ctx->dp_gui_master_cntl_c); - OUT_RING(ctx->sc_top_left_c); - OUT_RING(ctx->sc_bottom_right_c); - OUT_RING(ctx->z_offset_c); - OUT_RING(ctx->z_pitch_c); - OUT_RING(ctx->z_sten_cntl_c); - OUT_RING(ctx->tex_cntl_c); - OUT_RING(ctx->misc_3d_state_cntl_reg); - OUT_RING(ctx->texture_clr_cmp_clr_c); - OUT_RING(ctx->texture_clr_cmp_msk_c); - OUT_RING(ctx->fog_color_c); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(3); - - OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP)); - OUT_RING(ctx->setup_cntl); - OUT_RING(ctx->pm4_vc_fpu_setup); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5); - - OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); - OUT_RING(ctx->dp_write_mask); - - OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1)); - OUT_RING(ctx->sten_ref_mask_c); - OUT_RING(ctx->plane_3d_mask_c); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0)); - OUT_RING(ctx->window_xy_offset); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS); - - OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, - 2 + R128_MAX_TEXTURE_LEVELS)); - OUT_RING(tex->tex_cntl); - OUT_RING(tex->tex_combine_cntl); - OUT_RING(ctx->tex_size_pitch_c); - for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { - OUT_RING(tex->tex_offset[i]); - } - - OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); - OUT_RING(ctx->constant_color_c); - OUT_RING(tex->tex_border_color); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS); - - OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); - OUT_RING(tex->tex_cntl); - OUT_RING(tex->tex_combine_cntl); - for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { - OUT_RING(tex->tex_offset[i]); - } - - OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); - OUT_RING(tex->tex_border_color); - - ADVANCE_RING(); -} - -static void r128_emit_state(drm_r128_private_t * dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG("dirty=0x%08x\n", dirty); - - if (dirty & R128_UPLOAD_CORE) { - r128_emit_core(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_CORE; - } - - if (dirty & R128_UPLOAD_CONTEXT) { - r128_emit_context(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; - } - - if (dirty & R128_UPLOAD_SETUP) { - r128_emit_setup(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_SETUP; - } - - if (dirty & R128_UPLOAD_MASKS) { - r128_emit_masks(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_MASKS; - } - - if (dirty & R128_UPLOAD_WINDOW) { - r128_emit_window(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; - } - - if (dirty & R128_UPLOAD_TEX0) { - r128_emit_tex0(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_TEX0; - } - - if (dirty & R128_UPLOAD_TEX1) { - r128_emit_tex1(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_TEX1; - } - - /* Turn off the texture cache flushing */ - sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; - - sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; -} - -#if R128_PERFORMANCE_BOXES -/* ================================================================ - * Performance monitoring functions - */ - -static void r128_clear_box(drm_r128_private_t * dev_priv, - int x, int y, int w, int h, int r, int g, int b) -{ - u32 pitch, offset; - u32 fb_bpp, color; - RING_LOCALS; - - switch (dev_priv->fb_bpp) { - case 16: - fb_bpp = R128_GMC_DST_16BPP; - color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); - break; - case 24: - fb_bpp = R128_GMC_DST_24BPP; - color = ((r << 16) | (g << 8) | b); - break; - case 32: - fb_bpp = R128_GMC_DST_32BPP; - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); - break; - default: - return; - } - - offset = dev_priv->back_offset; - pitch = dev_priv->back_pitch >> 3; - - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - fb_bpp | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); - - OUT_RING((pitch << 21) | (offset >> 5)); - OUT_RING(color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); -} - -static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv) -{ - if (atomic_read(&dev_priv->idle_count) == 0) { - r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); - } else { - atomic_set(&dev_priv->idle_count, 0); - } -} - -#endif - -/* ================================================================ - * CCE command dispatch functions - */ - -static void r128_print_dirty(const char *msg, unsigned int flags) -{ - DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & R128_UPLOAD_CORE) ? "core, " : "", - (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", - (flags & R128_UPLOAD_SETUP) ? "setup, " : "", - (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", - (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", - (flags & R128_UPLOAD_MASKS) ? "masks, " : "", - (flags & R128_UPLOAD_WINDOW) ? "window, " : "", - (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", - (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); -} - -static void r128_cce_dispatch_clear(struct drm_device * dev, - drm_r128_clear_t * clear) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - unsigned int flags = clear->flags; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - if (dev_priv->page_flipping && dev_priv->current_page == 1) { - unsigned int tmp = flags; - - flags &= ~(R128_FRONT | R128_BACK); - if (tmp & R128_FRONT) - flags |= R128_BACK; - if (tmp & R128_BACK) - flags |= R128_FRONT; - } - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", - pbox[i].x1, pbox[i].y1, pbox[i].x2, - pbox[i].y2, flags); - - if (flags & (R128_FRONT | R128_BACK)) { - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); - OUT_RING(clear->color_mask); - - ADVANCE_RING(); - } - - if (flags & R128_FRONT) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS); - - OUT_RING(dev_priv->front_pitch_offset_c); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - if (flags & R128_BACK) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS); - - OUT_RING(dev_priv->back_pitch_offset_c); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - if (flags & R128_DEPTH) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(clear->clear_depth); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - } -} - -static void r128_cce_dispatch_swap(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - -#if R128_PERFORMANCE_BOXES - /* Do some trivial performance monitoring... - */ - r128_cce_performance_boxes(dev_priv); -#endif - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - BEGIN_RING(7); - - OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); - OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); - - /* Make this work even if front & back are flipped: - */ - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_pitch_offset_c); - OUT_RING(dev_priv->front_pitch_offset_c); - } else { - OUT_RING(dev_priv->front_pitch_offset_c); - OUT_RING(dev_priv->back_pitch_offset_c); - } - - OUT_RING((x << 16) | y); - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->last_frame++; - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); - OUT_RING(dev_priv->sarea_priv->last_frame); - - ADVANCE_RING(); -} - -static void r128_cce_dispatch_flip(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG("page=%d pfCurrentPage=%d\n", - dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); - -#if R128_PERFORMANCE_BOXES - /* Do some trivial performance monitoring... - */ - r128_cce_performance_boxes(dev_priv); -#endif - - BEGIN_RING(4); - - R128_WAIT_UNTIL_PAGE_FLIPPED(); - OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); - - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_offset); - } else { - OUT_RING(dev_priv->front_offset); - } - - ADVANCE_RING(); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->last_frame++; - dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = - 1 - dev_priv->current_page; - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); - OUT_RING(dev_priv->sarea_priv->last_frame); - - ADVANCE_RING(); -} - -static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = buf->bus_address; - int size = buf->used; - int prim = buf_priv->prim; - int i = 0; - RING_LOCALS; - DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox); - - if (0) - r128_print_dirty("dispatch_vertex", sarea_priv->dirty); - - if (buf->used) { - buf_priv->dispatched = 1; - - if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { - r128_emit_state(dev_priv); - } - - do { - /* Emit the next set of up to three cliprects */ - if (i < sarea_priv->nbox) { - r128_emit_clip_rects(dev_priv, - &sarea_priv->boxes[i], - sarea_priv->nbox - i); - } - - /* Emit the vertex buffer rendering commands */ - BEGIN_RING(5); - - OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3)); - OUT_RING(offset); - OUT_RING(size); - OUT_RING(format); - OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | - (size << R128_CCE_VC_CNTL_NUM_SHIFT)); - - ADVANCE_RING(); - - i += 3; - } while (i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); - OUT_RING(buf_priv->age); - - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; - - sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; -} - -static void r128_cce_dispatch_indirect(struct drm_device * dev, - struct drm_buf * buf, int start, int end) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - RING_LOCALS; - DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); - - if (start != end) { - int offset = buf->bus_address + start; - int dwords = (end - start + 3) / sizeof(u32); - - /* Indirect buffer data must be an even number of - * dwords, so if we've been given an odd number we must - * pad the data with a Type-2 CCE packet. - */ - if (dwords & 1) { - u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = cpu_to_le32(R128_CCE_PACKET2); - } - - buf_priv->dispatched = 1; - - /* Fire off the indirect buffer */ - BEGIN_RING(3); - - OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1)); - OUT_RING(offset); - OUT_RING(dwords); - - ADVANCE_RING(); - } - - if (buf_priv->discard) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the indirect buffer age */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); - OUT_RING(buf_priv->age); - - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; -} - -static void r128_cce_dispatch_indices(struct drm_device * dev, - struct drm_buf * buf, - int start, int end, int count) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset; - int prim = buf_priv->prim; - u32 *data; - int dwords; - int i = 0; - RING_LOCALS; - DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count); - - if (0) - r128_print_dirty("dispatch_indices", sarea_priv->dirty); - - if (start != end) { - buf_priv->dispatched = 1; - - if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { - r128_emit_state(dev_priv); - } - - dwords = (end - start + 3) / sizeof(u32); - - data = (u32 *) ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - - data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, - dwords - 2)); - - data[1] = cpu_to_le32(offset); - data[2] = cpu_to_le32(R128_MAX_VB_VERTS); - data[3] = cpu_to_le32(format); - data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | - (count << 16))); - - if (count & 0x1) { -#ifdef __LITTLE_ENDIAN - data[dwords - 1] &= 0x0000ffff; -#else - data[dwords - 1] &= 0xffff0000; -#endif - } - - do { - /* Emit the next set of up to three cliprects */ - if (i < sarea_priv->nbox) { - r128_emit_clip_rects(dev_priv, - &sarea_priv->boxes[i], - sarea_priv->nbox - i); - } - - r128_cce_dispatch_indirect(dev, buf, start, end); - - i += 3; - } while (i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); - OUT_RING(buf_priv->age); - - ADVANCE_RING(); - - buf->pending = 1; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; - - sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; -} - -static int r128_cce_dispatch_blit(struct drm_device * dev, - struct drm_file *file_priv, - drm_r128_blit_t * blit) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - u32 *data; - int dword_shift, dwords; - RING_LOCALS; - DRM_DEBUG("\n"); - - /* The compiler won't optimize away a division by a variable, - * even if the only legal values are powers of two. Thus, we'll - * use a shift instead. - */ - switch (blit->format) { - case R128_DATATYPE_ARGB8888: - dword_shift = 0; - break; - case R128_DATATYPE_ARGB1555: - case R128_DATATYPE_RGB565: - case R128_DATATYPE_ARGB4444: - case R128_DATATYPE_YVYU422: - case R128_DATATYPE_VYUY422: - dword_shift = 1; - break; - case R128_DATATYPE_CI8: - case R128_DATATYPE_RGB8: - dword_shift = 2; - break; - default: - DRM_ERROR("invalid blit format %d\n", blit->format); - return -EINVAL; - } - - /* Flush the pixel cache, and mark the contents as Read Invalid. - * This ensures no pixel data gets mixed up with the texture - * data from the host data blit, otherwise part of the texture - * image may be corrupted. - */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); - OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI); - - ADVANCE_RING(); - - /* Dispatch the indirect buffer. - */ - buf = dma->buflist[blit->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", blit->idx); - return -EINVAL; - } - - buf_priv->discard = 1; - - dwords = (blit->width * blit->height) >> dword_shift; - - data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); - - data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6)); - data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (blit->format << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_HOST_DATA | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS)); - - data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5)); - data[3] = cpu_to_le32(0xffffffff); - data[4] = cpu_to_le32(0xffffffff); - data[5] = cpu_to_le32((blit->y << 16) | blit->x); - data[6] = cpu_to_le32((blit->height << 16) | blit->width); - data[7] = cpu_to_le32(dwords); - - buf->used = (dwords + 8) * sizeof(u32); - - r128_cce_dispatch_indirect(dev, buf, 0, buf->used); - - /* Flush the pixel cache after the blit completes. This ensures - * the texture data is written out to memory before rendering - * continues. - */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); - OUT_RING(R128_PC_FLUSH_GUI); - - ADVANCE_RING(); - - return 0; -} - -/* ================================================================ - * Tiled depth buffer management - * - * FIXME: These should all set the destination write mask for when we - * have hardware stencil support. - */ - -static int r128_cce_dispatch_write_span(struct drm_device * dev, - drm_r128_depth_t * depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, x, y; - u32 *buffer; - u8 *mask; - int i, buffer_size, mask_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { - return -EFAULT; - } - if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { - return -EFAULT; - } - - buffer_size = depth->n * sizeof(u32); - buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); - if (buffer == NULL) - return -ENOMEM; - if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return -EFAULT; - } - - mask_size = depth->n * sizeof(u8); - if (depth->mask) { - mask = drm_alloc(mask_size, DRM_MEM_BUFS); - if (mask == NULL) { - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - drm_free(mask, mask_size, DRM_MEM_BUFS); - return -EFAULT; - } - - for (i = 0; i < count; i++, x++) { - if (mask[i]) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x << 16) | y); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - drm_free(mask, mask_size, DRM_MEM_BUFS); - } else { - for (i = 0; i < count; i++, x++) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x << 16) | y); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - - return 0; -} - -static int r128_cce_dispatch_write_pixels(struct drm_device * dev, - drm_r128_depth_t * depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, *x, *y; - u32 *buffer; - u8 *mask; - int i, xbuf_size, ybuf_size, buffer_size, mask_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - xbuf_size = count * sizeof(*x); - ybuf_size = count * sizeof(*y); - x = drm_alloc(xbuf_size, DRM_MEM_BUFS); - if (x == NULL) { - return -ENOMEM; - } - y = drm_alloc(ybuf_size, DRM_MEM_BUFS); - if (y == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - return -EFAULT; - } - if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - return -EFAULT; - } - - buffer_size = depth->n * sizeof(u32); - buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); - if (buffer == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return -EFAULT; - } - - if (depth->mask) { - mask_size = depth->n * sizeof(u8); - mask = drm_alloc(mask_size, DRM_MEM_BUFS); - if (mask == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - drm_free(mask, mask_size, DRM_MEM_BUFS); - return -EFAULT; - } - - for (i = 0; i < count; i++) { - if (mask[i]) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x[i] << 16) | y[i]); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - drm_free(mask, mask_size, DRM_MEM_BUFS); - } else { - for (i = 0; i < count; i++) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x[i] << 16) | y[i]); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - drm_free(buffer, buffer_size, DRM_MEM_BUFS); - - return 0; -} - -static int r128_cce_dispatch_read_span(struct drm_device * dev, - drm_r128_depth_t * depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, x, y; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { - return -EFAULT; - } - if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { - return -EFAULT; - } - - BEGIN_RING(7); - - OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); - OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(dev_priv->span_pitch_offset_c); - - OUT_RING((x << 16) | y); - OUT_RING((0 << 16) | 0); - OUT_RING((count << 16) | 1); - - ADVANCE_RING(); - - return 0; -} - -static int r128_cce_dispatch_read_pixels(struct drm_device * dev, - drm_r128_depth_t * depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, *x, *y; - int i, xbuf_size, ybuf_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - if (count > dev_priv->depth_pitch) { - count = dev_priv->depth_pitch; - } - - xbuf_size = count * sizeof(*x); - ybuf_size = count * sizeof(*y); - x = drm_alloc(xbuf_size, DRM_MEM_BUFS); - if (x == NULL) { - return -ENOMEM; - } - y = drm_alloc(ybuf_size, DRM_MEM_BUFS); - if (y == NULL) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - return -EFAULT; - } - if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - return -EFAULT; - } - - for (i = 0; i < count; i++) { - BEGIN_RING(7); - - OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); - OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(dev_priv->span_pitch_offset_c); - - OUT_RING((x[i] << 16) | y[i]); - OUT_RING((i << 16) | 0); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - - drm_free(x, xbuf_size, DRM_MEM_BUFS); - drm_free(y, ybuf_size, DRM_MEM_BUFS); - - return 0; -} - -/* ================================================================ - * Polygon stipple - */ - -static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(33); - - OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); - for (i = 0; i < 32; i++) { - OUT_RING(stipple[i]); - } - - ADVANCE_RING(); -} - -/* ================================================================ - * IOCTL functions - */ - -static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_clear_t *clear = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - - r128_cce_dispatch_clear(dev, clear); - COMMIT_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; - - return 0; -} - -static int r128_do_init_pageflip(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET); - dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL); - - R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset); - R128_WRITE(R128_CRTC_OFFSET_CNTL, - dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL); - - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; - - return 0; -} - -static int r128_do_cleanup_pageflip(struct drm_device * dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset); - R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl); - - if (dev_priv->current_page != 0) { - r128_cce_dispatch_flip(dev); - COMMIT_RING(); - } - - dev_priv->page_flipping = 0; - return 0; -} - -/* Swapping and flipping are different operations, need different ioctls. - * They can & should be intermixed to support multiple 3d windows. - */ - -static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (!dev_priv->page_flipping) - r128_do_init_pageflip(dev); - - r128_cce_dispatch_flip(dev); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - - r128_cce_dispatch_swap(dev); - dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_MASKS); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); - - if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - vertex->idx, dma->buf_count - 1); - return -EINVAL; - } - if (vertex->prim < 0 || - vertex->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { - DRM_ERROR("buffer prim %d\n", vertex->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[vertex->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex->idx); - return -EINVAL; - } - - buf->used = vertex->count; - buf_priv->prim = vertex->prim; - buf_priv->discard = vertex->discard; - - r128_cce_dispatch_vertex(dev, buf); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_indices_t *elts = data; - int count; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, - elts->idx, elts->start, elts->end, elts->discard); - - if (elts->idx < 0 || elts->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - elts->idx, dma->buf_count - 1); - return -EINVAL; - } - if (elts->prim < 0 || - elts->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { - DRM_ERROR("buffer prim %d\n", elts->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[elts->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", elts->idx); - return -EINVAL; - } - - count = (elts->end - elts->start) / sizeof(u16); - elts->start -= R128_INDEX_PRIM_OFFSET; - - if (elts->start & 0x7) { - DRM_ERROR("misaligned buffer 0x%x\n", elts->start); - return -EINVAL; - } - if (elts->start < buf->used) { - DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); - return -EINVAL; - } - - buf->used = elts->end; - buf_priv->prim = elts->prim; - buf_priv->discard = elts->discard; - - r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_blit_t *blit = data; - int ret; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx); - - if (blit->idx < 0 || blit->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - blit->idx, dma->buf_count - 1); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - ret = r128_cce_dispatch_blit(dev, file_priv, blit); - - COMMIT_RING(); - return ret; -} - -static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_depth_t *depth = data; - int ret; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - ret = -EINVAL; - switch (depth->func) { - case R128_WRITE_SPAN: - ret = r128_cce_dispatch_write_span(dev, depth); - break; - case R128_WRITE_PIXELS: - ret = r128_cce_dispatch_write_pixels(dev, depth); - break; - case R128_READ_SPAN: - ret = r128_cce_dispatch_read_span(dev, depth); - break; - case R128_READ_PIXELS: - ret = r128_cce_dispatch_read_pixels(dev, depth); - break; - } - - COMMIT_RING(); - return ret; -} - -static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_stipple_t *stipple = data; - u32 mask[32]; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) - return -EFAULT; - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - r128_cce_dispatch_stipple(dev, mask); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_indirect_t *indirect = data; -#if 0 - RING_LOCALS; -#endif - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", - indirect->idx, indirect->start, indirect->end, - indirect->discard); - - if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - indirect->idx, dma->buf_count - 1); - return -EINVAL; - } - - buf = dma->buflist[indirect->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", indirect->idx); - return -EINVAL; - } - - if (indirect->start < buf->used) { - DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", - indirect->start, buf->used); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf->used = indirect->end; - buf_priv->discard = indirect->discard; - -#if 0 - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); -#endif - - /* Dispatch the indirect buffer full of commands from the - * X server. This is insecure and is thus only available to - * privileged clients. - */ - r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end); - - COMMIT_RING(); - return 0; -} - -static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_getparam_t *param = data; - int value; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - switch (param->param) { - case R128_PARAM_IRQ_NR: - value = dev->irq; - break; - default: - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_r128_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { - r128_do_cleanup_pageflip(dev); - } - } -} - -void r128_driver_lastclose(struct drm_device * dev) -{ - r128_do_cleanup_cce(dev); -} - -struct drm_ioctl_desc r128_ioctls[] = { - DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH), - DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH), -}; - -int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c deleted file mode 100644 index 702df45..0000000 --- a/drivers/char/drm/r300_cmdbuf.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* r300_cmdbuf.c -- Command buffer emission for R300 -*- linux-c -*- - * - * Copyright (C) The Weather Channel, Inc. 2002. - * Copyright (C) 2004 Nicolai Haehnle. - * All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Nicolai Haehnle - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" -#include "r300_reg.h" - -#define R300_SIMULTANEOUS_CLIPRECTS 4 - -/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects - */ -static const int r300_cliprect_cntl[4] = { - 0xAAAA, - 0xEEEE, - 0xFEFE, - 0xFFFE -}; - -/** - * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command - * buffer, starting with index n. - */ -static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, int n) -{ - struct drm_clip_rect box; - int nr; - int i; - RING_LOCALS; - - nr = cmdbuf->nbox - n; - if (nr > R300_SIMULTANEOUS_CLIPRECTS) - nr = R300_SIMULTANEOUS_CLIPRECTS; - - DRM_DEBUG("%i cliprects\n", nr); - - if (nr) { - BEGIN_RING(6 + nr * 2); - OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); - - for (i = 0; i < nr; ++i) { - if (DRM_COPY_FROM_USER_UNCHECKED - (&box, &cmdbuf->boxes[n + i], sizeof(box))) { - DRM_ERROR("copy cliprect faulted\n"); - return -EFAULT; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - box.x1 = (box.x1) & - R300_CLIPRECT_MASK; - box.y1 = (box.y1) & - R300_CLIPRECT_MASK; - box.x2 = (box.x2) & - R300_CLIPRECT_MASK; - box.y2 = (box.y2) & - R300_CLIPRECT_MASK; - } else { - box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - - } - OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) | - (box.y1 << R300_CLIPRECT_Y_SHIFT)); - OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) | - (box.y2 << R300_CLIPRECT_Y_SHIFT)); - - } - - OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]); - - /* TODO/SECURITY: Force scissors to a safe value, otherwise the - * client might be able to trample over memory. - * The impact should be very limited, but I'd rather be safe than - * sorry. - */ - OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1)); - OUT_RING(0); - OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK); - ADVANCE_RING(); - } else { - /* Why we allow zero cliprect rendering: - * There are some commands in a command buffer that must be submitted - * even when there are no cliprects, e.g. DMA buffer discard - * or state setting (though state setting could be avoided by - * simulating a loss of context). - * - * Now since the cmdbuf interface is so chaotic right now (and is - * bound to remain that way for a bit until things settle down), - * it is basically impossible to filter out the commands that are - * necessary and those that aren't. - * - * So I choose the safe way and don't do any filtering at all; - * instead, I simply set up the engine so that all rendering - * can't produce any fragments. - */ - BEGIN_RING(2); - OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0); - ADVANCE_RING(); - } - - return 0; -} - -static u8 r300_reg_flags[0x10000 >> 2]; - -void r300_init_reg_flags(struct drm_device *dev) -{ - int i; - drm_radeon_private_t *dev_priv = dev->dev_private; - - memset(r300_reg_flags, 0, 0x10000 >> 2); -#define ADD_RANGE_MARK(reg, count,mark) \ - for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\ - r300_reg_flags[i]|=(mark); - -#define MARK_SAFE 1 -#define MARK_CHECK_OFFSET 2 - -#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) - - /* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */ - ADD_RANGE(R300_SE_VPORT_XSCALE, 6); - ADD_RANGE(R300_VAP_CNTL, 1); - ADD_RANGE(R300_SE_VTE_CNTL, 2); - ADD_RANGE(0x2134, 2); - ADD_RANGE(R300_VAP_CNTL_STATUS, 1); - ADD_RANGE(R300_VAP_INPUT_CNTL_0, 2); - ADD_RANGE(0x21DC, 1); - ADD_RANGE(R300_VAP_UNKNOWN_221C, 1); - ADD_RANGE(R300_VAP_CLIP_X_0, 4); - ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1); - ADD_RANGE(R300_VAP_UNKNOWN_2288, 1); - ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2); - ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); - ADD_RANGE(R300_GB_ENABLE, 1); - ADD_RANGE(R300_GB_MSPOS0, 5); - ADD_RANGE(R300_TX_CNTL, 1); - ADD_RANGE(R300_TX_ENABLE, 1); - ADD_RANGE(0x4200, 4); - ADD_RANGE(0x4214, 1); - ADD_RANGE(R300_RE_POINTSIZE, 1); - ADD_RANGE(0x4230, 3); - ADD_RANGE(R300_RE_LINE_CNT, 1); - ADD_RANGE(R300_RE_UNK4238, 1); - ADD_RANGE(0x4260, 3); - ADD_RANGE(R300_RE_SHADE, 4); - ADD_RANGE(R300_RE_POLYGON_MODE, 5); - ADD_RANGE(R300_RE_ZBIAS_CNTL, 1); - ADD_RANGE(R300_RE_ZBIAS_T_FACTOR, 4); - ADD_RANGE(R300_RE_OCCLUSION_CNTL, 1); - ADD_RANGE(R300_RE_CULL_CNTL, 1); - ADD_RANGE(0x42C0, 2); - ADD_RANGE(R300_RS_CNTL_0, 2); - - ADD_RANGE(R300_SC_HYPERZ, 2); - ADD_RANGE(0x43E8, 1); - - ADD_RANGE(0x46A4, 5); - - ADD_RANGE(R300_RE_FOG_STATE, 1); - ADD_RANGE(R300_FOG_COLOR_R, 3); - ADD_RANGE(R300_PP_ALPHA_TEST, 2); - ADD_RANGE(0x4BD8, 1); - ADD_RANGE(R300_PFS_PARAM_0_X, 64); - ADD_RANGE(0x4E00, 1); - ADD_RANGE(R300_RB3D_CBLEND, 2); - ADD_RANGE(R300_RB3D_COLORMASK, 1); - ADD_RANGE(R300_RB3D_BLEND_COLOR, 3); - ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */ - ADD_RANGE(R300_RB3D_COLORPITCH0, 1); - ADD_RANGE(0x4E50, 9); - ADD_RANGE(0x4E88, 1); - ADD_RANGE(0x4EA0, 2); - ADD_RANGE(R300_ZB_CNTL, 3); - ADD_RANGE(R300_ZB_FORMAT, 4); - ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ - ADD_RANGE(R300_ZB_DEPTHPITCH, 1); - ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1); - ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13); - - ADD_RANGE(R300_TX_FILTER_0, 16); - ADD_RANGE(R300_TX_FILTER1_0, 16); - ADD_RANGE(R300_TX_SIZE_0, 16); - ADD_RANGE(R300_TX_FORMAT_0, 16); - ADD_RANGE(R300_TX_PITCH_0, 16); - /* Texture offset is dangerous and needs more checking */ - ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); - ADD_RANGE(R300_TX_CHROMA_KEY_0, 16); - ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); - - /* Sporadic registers used as primitives are emitted */ - ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1); - ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); - ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); - ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - ADD_RANGE(R500_VAP_INDEX_OFFSET, 1); - ADD_RANGE(R500_US_CONFIG, 2); - ADD_RANGE(R500_US_CODE_ADDR, 3); - ADD_RANGE(R500_US_FC_CTRL, 1); - ADD_RANGE(R500_RS_IP_0, 16); - ADD_RANGE(R500_RS_INST_0, 16); - ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); - ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2); - ADD_RANGE(R500_ZB_FIFO_SIZE, 2); - } else { - ADD_RANGE(R300_PFS_CNTL_0, 3); - ADD_RANGE(R300_PFS_NODE_0, 4); - ADD_RANGE(R300_PFS_TEXI_0, 64); - ADD_RANGE(R300_PFS_INSTR0_0, 64); - ADD_RANGE(R300_PFS_INSTR1_0, 64); - ADD_RANGE(R300_PFS_INSTR2_0, 64); - ADD_RANGE(R300_PFS_INSTR3_0, 64); - ADD_RANGE(R300_RS_INTERP_0, 8); - ADD_RANGE(R300_RS_ROUTE_0, 8); - - } -} - -static __inline__ int r300_check_range(unsigned reg, int count) -{ - int i; - if (reg & ~0xffff) - return -1; - for (i = (reg >> 2); i < (reg >> 2) + count; i++) - if (r300_reg_flags[i] != MARK_SAFE) - return 1; - return 0; -} - -static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * - dev_priv, - drm_radeon_kcmd_buffer_t - * cmdbuf, - drm_r300_cmd_header_t - header) -{ - int reg; - int sz; - int i; - int values[64]; - RING_LOCALS; - - sz = header.packet0.count; - reg = (header.packet0.reghi << 8) | header.packet0.reglo; - - if ((sz > 64) || (sz < 0)) { - DRM_ERROR - ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", - reg, sz); - return -EINVAL; - } - for (i = 0; i < sz; i++) { - values[i] = ((int *)cmdbuf->buf)[i]; - switch (r300_reg_flags[(reg >> 2) + i]) { - case MARK_SAFE: - break; - case MARK_CHECK_OFFSET: - if (!radeon_check_offset(dev_priv, (u32) values[i])) { - DRM_ERROR - ("Offset failed range check (reg=%04x sz=%d)\n", - reg, sz); - return -EINVAL; - } - break; - default: - DRM_ERROR("Register %04x failed check as flag=%02x\n", - reg + i * 4, r300_reg_flags[(reg >> 2) + i]); - return -EINVAL; - } - } - - BEGIN_RING(1 + sz); - OUT_RING(CP_PACKET0(reg, sz - 1)); - OUT_RING_TABLE(values, sz); - ADVANCE_RING(); - - cmdbuf->buf += sz * 4; - cmdbuf->bufsz -= sz * 4; - - return 0; -} - -/** - * Emits a packet0 setting arbitrary registers. - * Called by r300_do_cp_cmdbuf. - * - * Note that checks are performed on contents and addresses of the registers - */ -static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int reg; - int sz; - RING_LOCALS; - - sz = header.packet0.count; - reg = (header.packet0.reghi << 8) | header.packet0.reglo; - - if (!sz) - return 0; - - if (sz * 4 > cmdbuf->bufsz) - return -EINVAL; - - if (reg + sz * 4 >= 0x10000) { - DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, - sz); - return -EINVAL; - } - - if (r300_check_range(reg, sz)) { - /* go and check everything */ - return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, - header); - } - /* the rest of the data is safe to emit, whatever the values the user passed */ - - BEGIN_RING(1 + sz); - OUT_RING(CP_PACKET0(reg, sz - 1)); - OUT_RING_TABLE((int *)cmdbuf->buf, sz); - ADVANCE_RING(); - - cmdbuf->buf += sz * 4; - cmdbuf->bufsz -= sz * 4; - - return 0; -} - -/** - * Uploads user-supplied vertex program instructions or parameters onto - * the graphics card. - * Called by r300_do_cp_cmdbuf. - */ -static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int sz; - int addr; - RING_LOCALS; - - sz = header.vpu.count; - addr = (header.vpu.adrhi << 8) | header.vpu.adrlo; - - if (!sz) - return 0; - if (sz * 16 > cmdbuf->bufsz) - return -EINVAL; - - BEGIN_RING(5 + sz * 4); - /* Wait for VAP to come to senses.. */ - /* there is no need to emit it multiple times, (only once before VAP is programmed, - but this optimization is for later */ - OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0); - OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr); - OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1)); - OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4); - - ADVANCE_RING(); - - cmdbuf->buf += sz * 16; - cmdbuf->bufsz -= sz * 16; - - return 0; -} - -/** - * Emit a clear packet from userspace. - * Called by r300_emit_packet3. - */ -static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - RING_LOCALS; - - if (8 * 4 > cmdbuf->bufsz) - return -EINVAL; - - BEGIN_RING(10); - OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); - OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | - (1 << R300_PRIM_NUM_VERTICES_SHIFT)); - OUT_RING_TABLE((int *)cmdbuf->buf, 8); - ADVANCE_RING(); - - cmdbuf->buf += 8 * 4; - cmdbuf->bufsz -= 8 * 4; - - return 0; -} - -static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - u32 header) -{ - int count, i, k; -#define MAX_ARRAY_PACKET 64 - u32 payload[MAX_ARRAY_PACKET]; - u32 narrays; - RING_LOCALS; - - count = (header >> 16) & 0x3fff; - - if ((count + 1) > MAX_ARRAY_PACKET) { - DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", - count); - return -EINVAL; - } - memset(payload, 0, MAX_ARRAY_PACKET * 4); - memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4); - - /* carefully check packet contents */ - - narrays = payload[0]; - k = 0; - i = 1; - while ((k < narrays) && (i < (count + 1))) { - i++; /* skip attribute field */ - if (!radeon_check_offset(dev_priv, payload[i])) { - DRM_ERROR - ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - if (k == narrays) - break; - /* have one more to process, they come in pairs */ - if (!radeon_check_offset(dev_priv, payload[i])) { - DRM_ERROR - ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - } - /* do the counts match what we expect ? */ - if ((k != narrays) || (i != (count + 1))) { - DRM_ERROR - ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", - k, i, narrays, count + 1); - return -EINVAL; - } - - /* all clear, output packet */ - - BEGIN_RING(count + 2); - OUT_RING(header); - OUT_RING_TABLE(payload, count + 1); - ADVANCE_RING(); - - cmdbuf->buf += (count + 2) * 4; - cmdbuf->bufsz -= (count + 2) * 4; - - return 0; -} - -static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 *cmd = (u32 *) cmdbuf->buf; - int count, ret; - RING_LOCALS; - - count=(cmd[0]>>16) & 0x3fff; - - if (cmd[0] & 0x8000) { - u32 offset; - - if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL - | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - offset = cmd[2] << 10; - ret = !radeon_check_offset(dev_priv, offset); - if (ret) { - DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); - return -EINVAL; - } - } - - if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && - (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - offset = cmd[3] << 10; - ret = !radeon_check_offset(dev_priv, offset); - if (ret) { - DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); - return -EINVAL; - } - - } - } - - BEGIN_RING(count+2); - OUT_RING(cmd[0]); - OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); - ADVANCE_RING(); - - cmdbuf->buf += (count+2)*4; - cmdbuf->bufsz -= (count+2)*4; - - return 0; -} - -static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 *cmd = (u32 *) cmdbuf->buf; - int count, ret; - RING_LOCALS; - - count=(cmd[0]>>16) & 0x3fff; - - if ((cmd[1] & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); - return -EINVAL; - } - ret = !radeon_check_offset(dev_priv, cmd[2]); - if (ret) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); - return -EINVAL; - } - - BEGIN_RING(count+2); - OUT_RING(cmd[0]); - OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); - ADVANCE_RING(); - - cmdbuf->buf += (count+2)*4; - cmdbuf->bufsz -= (count+2)*4; - - return 0; -} - -static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 header; - int count; - RING_LOCALS; - - if (4 > cmdbuf->bufsz) - return -EINVAL; - - /* Fixme !! This simply emits a packet without much checking. - We need to be smarter. */ - - /* obtain first word - actual packet3 header */ - header = *(u32 *) cmdbuf->buf; - - /* Is it packet 3 ? */ - if ((header >> 30) != 0x3) { - DRM_ERROR("Not a packet3 header (0x%08x)\n", header); - return -EINVAL; - } - - count = (header >> 16) & 0x3fff; - - /* Check again now that we know how much data to expect */ - if ((count + 2) * 4 > cmdbuf->bufsz) { - DRM_ERROR - ("Expected packet3 of length %d but have only %d bytes left\n", - (count + 2) * 4, cmdbuf->bufsz); - return -EINVAL; - } - - /* Is it a packet type we know about ? */ - switch (header & 0xff00) { - case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ - return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); - - case RADEON_CNTL_BITBLT_MULTI: - return r300_emit_bitblt_multi(dev_priv, cmdbuf); - - case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ - return r300_emit_indx_buffer(dev_priv, cmdbuf); - case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ - case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ - case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ - case RADEON_WAIT_FOR_IDLE: - case RADEON_CP_NOP: - /* these packets are safe */ - break; - default: - DRM_ERROR("Unknown packet3 header (0x%08x)\n", header); - return -EINVAL; - } - - BEGIN_RING(count + 2); - OUT_RING(header); - OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); - ADVANCE_RING(); - - cmdbuf->buf += (count + 2) * 4; - cmdbuf->bufsz -= (count + 2) * 4; - - return 0; -} - -/** - * Emit a rendering packet3 from userspace. - * Called by r300_do_cp_cmdbuf. - */ -static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int n; - int ret; - char *orig_buf = cmdbuf->buf; - int orig_bufsz = cmdbuf->bufsz; - - /* This is a do-while-loop so that we run the interior at least once, - * even if cmdbuf->nbox is 0. Compare r300_emit_cliprects for rationale. - */ - n = 0; - do { - if (cmdbuf->nbox > R300_SIMULTANEOUS_CLIPRECTS) { - ret = r300_emit_cliprects(dev_priv, cmdbuf, n); - if (ret) - return ret; - - cmdbuf->buf = orig_buf; - cmdbuf->bufsz = orig_bufsz; - } - - switch (header.packet3.packet) { - case R300_CMD_PACKET3_CLEAR: - DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n"); - ret = r300_emit_clear(dev_priv, cmdbuf); - if (ret) { - DRM_ERROR("r300_emit_clear failed\n"); - return ret; - } - break; - - case R300_CMD_PACKET3_RAW: - DRM_DEBUG("R300_CMD_PACKET3_RAW\n"); - ret = r300_emit_raw_packet3(dev_priv, cmdbuf); - if (ret) { - DRM_ERROR("r300_emit_raw_packet3 failed\n"); - return ret; - } - break; - - default: - DRM_ERROR("bad packet3 type %i at %p\n", - header.packet3.packet, - cmdbuf->buf - sizeof(header)); - return -EINVAL; - } - - n += R300_SIMULTANEOUS_CLIPRECTS; - } while (n < cmdbuf->nbox); - - return 0; -} - -/* Some of the R300 chips seem to be extremely touchy about the two registers - * that are configured in r300_pacify. - * Among the worst offenders seems to be the R300 ND (0x4E44): When userspace - * sends a command buffer that contains only state setting commands and a - * vertex program/parameter upload sequence, this will eventually lead to a - * lockup, unless the sequence is bracketed by calls to r300_pacify. - * So we should take great care to *always* call r300_pacify before - * *anything* 3D related, and again afterwards. This is what the - * call bracket in r300_do_cp_cmdbuf is for. - */ - -/** - * Emit the sequence to pacify R300. - */ -static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) -{ - RING_LOCALS; - - BEGIN_RING(6); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A); - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); - OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE| - R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); - OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); - OUT_RING(0x0); - ADVANCE_RING(); -} - -/** - * Called by r300_do_cp_cmdbuf to update the internal buffer age and state. - * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must - * be careful about how this function is called. - */ -static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - - buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; - buf->pending = 1; - buf->used = 0; -} - -static void r300_cmd_wait(drm_radeon_private_t * dev_priv, - drm_r300_cmd_header_t header) -{ - u32 wait_until; - RING_LOCALS; - - if (!header.wait.flags) - return; - - wait_until = 0; - - switch(header.wait.flags) { - case R300_WAIT_2D: - wait_until = RADEON_WAIT_2D_IDLE; - break; - case R300_WAIT_3D: - wait_until = RADEON_WAIT_3D_IDLE; - break; - case R300_NEW_WAIT_2D_3D: - wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE; - break; - case R300_NEW_WAIT_2D_2D_CLEAN: - wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN; - break; - case R300_NEW_WAIT_3D_3D_CLEAN: - wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN; - break; - case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN: - wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN; - wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN; - break; - default: - return; - } - - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(wait_until); - ADVANCE_RING(); -} - -static int r300_scratch(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - u32 *ref_age_base; - u32 i, buf_idx, h_pending; - RING_LOCALS; - - if (cmdbuf->bufsz < - (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) { - return -EINVAL; - } - - if (header.scratch.reg >= 5) { - return -EINVAL; - } - - dev_priv->scratch_ages[header.scratch.reg]++; - - ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf); - - cmdbuf->buf += sizeof(u64); - cmdbuf->bufsz -= sizeof(u64); - - for (i=0; i < header.scratch.n_bufs; i++) { - buf_idx = *(u32 *)cmdbuf->buf; - buf_idx *= 2; /* 8 bytes per buf */ - - if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) { - return -EINVAL; - } - - if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) { - return -EINVAL; - } - - if (h_pending == 0) { - return -EINVAL; - } - - h_pending--; - - if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) { - return -EINVAL; - } - - cmdbuf->buf += sizeof(buf_idx); - cmdbuf->bufsz -= sizeof(buf_idx); - } - - BEGIN_RING(2); - OUT_RING( CP_PACKET0( RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0 ) ); - OUT_RING( dev_priv->scratch_ages[header.scratch.reg] ); - ADVANCE_RING(); - - return 0; -} - -/** - * Uploads user-supplied vertex program instructions or parameters onto - * the graphics card. - * Called by r300_do_cp_cmdbuf. - */ -static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int sz; - int addr; - int type; - int clamp; - int stride; - RING_LOCALS; - - sz = header.r500fp.count; - /* address is 9 bits 0 - 8, bit 1 of flags is part of address */ - addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo; - - type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); - clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); - - addr |= (type << 16); - addr |= (clamp << 17); - - stride = type ? 4 : 6; - - DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type); - if (!sz) - return 0; - if (sz * stride * 4 > cmdbuf->bufsz) - return -EINVAL; - - BEGIN_RING(3 + sz * stride); - OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr); - OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1)); - OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride); - - ADVANCE_RING(); - - cmdbuf->buf += sz * stride * 4; - cmdbuf->bufsz -= sz * stride * 4; - - return 0; -} - - -/** - * Parses and validates a user-supplied command buffer and emits appropriate - * commands on the DMA ring buffer. - * Called by the ioctl handler function radeon_cp_cmdbuf. - */ -int r300_do_cp_cmdbuf(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf = NULL; - int emit_dispatch_age = 0; - int ret = 0; - - DRM_DEBUG("\n"); - - /* See the comment above r300_emit_begin3d for why this call must be here, - * and what the cleanup gotos are for. */ - r300_pacify(dev_priv); - - if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) { - ret = r300_emit_cliprects(dev_priv, cmdbuf, 0); - if (ret) - goto cleanup; - } - - while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) { - int idx; - drm_r300_cmd_header_t header; - - header.u = *(unsigned int *)cmdbuf->buf; - - cmdbuf->buf += sizeof(header); - cmdbuf->bufsz -= sizeof(header); - - switch (header.header.cmd_type) { - case R300_CMD_PACKET0: - DRM_DEBUG("R300_CMD_PACKET0\n"); - ret = r300_emit_packet0(dev_priv, cmdbuf, header); - if (ret) { - DRM_ERROR("r300_emit_packet0 failed\n"); - goto cleanup; - } - break; - - case R300_CMD_VPU: - DRM_DEBUG("R300_CMD_VPU\n"); - ret = r300_emit_vpu(dev_priv, cmdbuf, header); - if (ret) { - DRM_ERROR("r300_emit_vpu failed\n"); - goto cleanup; - } - break; - - case R300_CMD_PACKET3: - DRM_DEBUG("R300_CMD_PACKET3\n"); - ret = r300_emit_packet3(dev_priv, cmdbuf, header); - if (ret) { - DRM_ERROR("r300_emit_packet3 failed\n"); - goto cleanup; - } - break; - - case R300_CMD_END3D: - DRM_DEBUG("R300_CMD_END3D\n"); - /* TODO: - Ideally userspace driver should not need to issue this call, - i.e. the drm driver should issue it automatically and prevent - lockups. - - In practice, we do not understand why this call is needed and what - it does (except for some vague guesses that it has to do with cache - coherence) and so the user space driver does it. - - Once we are sure which uses prevent lockups the code could be moved - into the kernel and the userspace driver will not - need to use this command. - - Note that issuing this command does not hurt anything - except, possibly, performance */ - r300_pacify(dev_priv); - break; - - case R300_CMD_CP_DELAY: - /* simple enough, we can do it here */ - DRM_DEBUG("R300_CMD_CP_DELAY\n"); - { - int i; - RING_LOCALS; - - BEGIN_RING(header.delay.count); - for (i = 0; i < header.delay.count; i++) - OUT_RING(RADEON_CP_PACKET2); - ADVANCE_RING(); - } - break; - - case R300_CMD_DMA_DISCARD: - DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); - idx = header.dma.buf_idx; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - idx, dma->buf_count - 1); - ret = -EINVAL; - goto cleanup; - } - - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv || buf->pending) { - DRM_ERROR("bad buffer %p %p %d\n", - buf->file_priv, file_priv, - buf->pending); - ret = -EINVAL; - goto cleanup; - } - - emit_dispatch_age = 1; - r300_discard_buffer(dev, buf); - break; - - case R300_CMD_WAIT: - DRM_DEBUG("R300_CMD_WAIT\n"); - r300_cmd_wait(dev_priv, header); - break; - - case R300_CMD_SCRATCH: - DRM_DEBUG("R300_CMD_SCRATCH\n"); - ret = r300_scratch(dev_priv, cmdbuf, header); - if (ret) { - DRM_ERROR("r300_scratch failed\n"); - goto cleanup; - } - break; - - case R300_CMD_R500FP: - if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) { - DRM_ERROR("Calling r500 command on r300 card\n"); - ret = -EINVAL; - goto cleanup; - } - DRM_DEBUG("R300_CMD_R500FP\n"); - ret = r300_emit_r500fp(dev_priv, cmdbuf, header); - if (ret) { - DRM_ERROR("r300_emit_r500fp failed\n"); - goto cleanup; - } - break; - default: - DRM_ERROR("bad cmd_type %i at %p\n", - header.header.cmd_type, - cmdbuf->buf - sizeof(header)); - ret = -EINVAL; - goto cleanup; - } - } - - DRM_DEBUG("END\n"); - - cleanup: - r300_pacify(dev_priv); - - /* We emit the vertex buffer age here, outside the pacifier "brackets" - * for two reasons: - * (1) This may coalesce multiple age emissions into a single one and - * (2) more importantly, some chips lock up hard when scratch registers - * are written inside the pacifier bracket. - */ - if (emit_dispatch_age) { - RING_LOCALS; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch); - ADVANCE_RING(); - } - - COMMIT_RING(); - - return ret; -} diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h deleted file mode 100644 index a6802f2..0000000 --- a/drivers/char/drm/r300_reg.h +++ /dev/null @@ -1,1772 +0,0 @@ -/************************************************************************** - -Copyright (C) 2004-2005 Nicolai Haehnle et al. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#ifndef _R300_REG_H -#define _R300_REG_H - -#define R300_MC_INIT_MISC_LAT_TIMER 0x180 -# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0 -# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4 -# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8 -# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12 -# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16 -# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20 -# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24 -# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28 - -#define R300_MC_INIT_GFX_LAT_TIMER 0x154 -# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0 -# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4 -# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8 -# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12 -# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16 -# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20 -# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24 -# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28 - -/* - * This file contains registers and constants for the R300. They have been - * found mostly by examining command buffers captured using glxtest, as well - * as by extrapolating some known registers and constants from the R200. - * I am fairly certain that they are correct unless stated otherwise - * in comments. - */ - -#define R300_SE_VPORT_XSCALE 0x1D98 -#define R300_SE_VPORT_XOFFSET 0x1D9C -#define R300_SE_VPORT_YSCALE 0x1DA0 -#define R300_SE_VPORT_YOFFSET 0x1DA4 -#define R300_SE_VPORT_ZSCALE 0x1DA8 -#define R300_SE_VPORT_ZOFFSET 0x1DAC - - -/* - * Vertex Array Processing (VAP) Control - * Stolen from r200 code from Christoph Brill (It's a guess!) - */ -#define R300_VAP_CNTL 0x2080 - -/* This register is written directly and also starts data section - * in many 3d CP_PACKET3's - */ -#define R300_VAP_VF_CNTL 0x2084 -# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0 -# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0) -# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0) -# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0) -# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0) -# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0) -# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0) -# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0) -# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0) -# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0) -# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0) -# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0) - -# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4 - /* State based - direct writes to registers trigger vertex - generation */ -# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4) -# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4) -# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4) -# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4) - - /* I don't think I saw these three used.. */ -# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6 -# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9 -# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10 - - /* index size - when not set the indices are assumed to be 16 bit */ -# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11) - /* number of vertices */ -# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16 - -/* BEGIN: Wild guesses */ -#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 -# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1) -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */ - -#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094 - /* each of the following is 3 bits wide, specifies number - of components */ -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 -/* END: Wild guesses */ - -#define R300_SE_VTE_CNTL 0x20b0 -# define R300_VPORT_X_SCALE_ENA 0x00000001 -# define R300_VPORT_X_OFFSET_ENA 0x00000002 -# define R300_VPORT_Y_SCALE_ENA 0x00000004 -# define R300_VPORT_Y_OFFSET_ENA 0x00000008 -# define R300_VPORT_Z_SCALE_ENA 0x00000010 -# define R300_VPORT_Z_OFFSET_ENA 0x00000020 -# define R300_VTX_XY_FMT 0x00000100 -# define R300_VTX_Z_FMT 0x00000200 -# define R300_VTX_W0_FMT 0x00000400 -# define R300_VTX_W0_NORMALIZE 0x00000800 -# define R300_VTX_ST_DENORMALIZED 0x00001000 - -/* BEGIN: Vertex data assembly - lots of uncertainties */ - -/* gap */ - -#define R300_VAP_CNTL_STATUS 0x2140 -# define R300_VC_NO_SWAP (0 << 0) -# define R300_VC_16BIT_SWAP (1 << 0) -# define R300_VC_32BIT_SWAP (2 << 0) -# define R300_VAP_TCL_BYPASS (1 << 8) - -/* gap */ - -/* Where do we get our vertex data? - * - * Vertex data either comes either from immediate mode registers or from - * vertex arrays. - * There appears to be no mixed mode (though we can force the pitch of - * vertex arrays to 0, effectively reusing the same element over and over - * again). - * - * Immediate mode is controlled by the INPUT_CNTL registers. I am not sure - * if these registers influence vertex array processing. - * - * Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3. - * - * In both cases, vertex attributes are then passed through INPUT_ROUTE. - * - * Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data - * into the vertex processor's input registers. - * The first word routes the first input, the second word the second, etc. - * The corresponding input is routed into the register with the given index. - * The list is ended by a word with INPUT_ROUTE_END set. - * - * Always set COMPONENTS_4 in immediate mode. - */ - -#define R300_VAP_INPUT_ROUTE_0_0 0x2150 -# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */ -# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8 -# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */ -# define R300_VAP_INPUT_ROUTE_END (1 << 13) -# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */ -#define R300_VAP_INPUT_ROUTE_0_1 0x2154 -#define R300_VAP_INPUT_ROUTE_0_2 0x2158 -#define R300_VAP_INPUT_ROUTE_0_3 0x215C -#define R300_VAP_INPUT_ROUTE_0_4 0x2160 -#define R300_VAP_INPUT_ROUTE_0_5 0x2164 -#define R300_VAP_INPUT_ROUTE_0_6 0x2168 -#define R300_VAP_INPUT_ROUTE_0_7 0x216C - -/* gap */ - -/* Notes: - * - always set up to produce at least two attributes: - * if vertex program uses only position, fglrx will set normal, too - * - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal. - */ -#define R300_VAP_INPUT_CNTL_0 0x2180 -# define R300_INPUT_CNTL_0_COLOR 0x00000001 -#define R300_VAP_INPUT_CNTL_1 0x2184 -# define R300_INPUT_CNTL_POS 0x00000001 -# define R300_INPUT_CNTL_NORMAL 0x00000002 -# define R300_INPUT_CNTL_COLOR 0x00000004 -# define R300_INPUT_CNTL_TC0 0x00000400 -# define R300_INPUT_CNTL_TC1 0x00000800 -# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */ -# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */ -# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */ -# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */ -# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */ -# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */ - -/* gap */ - -/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0 - * are set to a swizzling bit pattern, other words are 0. - * - * In immediate mode, the pattern is always set to xyzw. In vertex array - * mode, the swizzling pattern is e.g. used to set zw components in texture - * coordinates with only tweo components. - */ -#define R300_VAP_INPUT_ROUTE_1_0 0x21E0 -# define R300_INPUT_ROUTE_SELECT_X 0 -# define R300_INPUT_ROUTE_SELECT_Y 1 -# define R300_INPUT_ROUTE_SELECT_Z 2 -# define R300_INPUT_ROUTE_SELECT_W 3 -# define R300_INPUT_ROUTE_SELECT_ZERO 4 -# define R300_INPUT_ROUTE_SELECT_ONE 5 -# define R300_INPUT_ROUTE_SELECT_MASK 7 -# define R300_INPUT_ROUTE_X_SHIFT 0 -# define R300_INPUT_ROUTE_Y_SHIFT 3 -# define R300_INPUT_ROUTE_Z_SHIFT 6 -# define R300_INPUT_ROUTE_W_SHIFT 9 -# define R300_INPUT_ROUTE_ENABLE (15 << 12) -#define R300_VAP_INPUT_ROUTE_1_1 0x21E4 -#define R300_VAP_INPUT_ROUTE_1_2 0x21E8 -#define R300_VAP_INPUT_ROUTE_1_3 0x21EC -#define R300_VAP_INPUT_ROUTE_1_4 0x21F0 -#define R300_VAP_INPUT_ROUTE_1_5 0x21F4 -#define R300_VAP_INPUT_ROUTE_1_6 0x21F8 -#define R300_VAP_INPUT_ROUTE_1_7 0x21FC - -/* END: Vertex data assembly */ - -/* gap */ - -/* BEGIN: Upload vertex program and data */ - -/* - * The programmable vertex shader unit has a memory bank of unknown size - * that can be written to in 16 byte units by writing the address into - * UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs). - * - * Pointers into the memory bank are always in multiples of 16 bytes. - * - * The memory bank is divided into areas with fixed meaning. - * - * Starting at address UPLOAD_PROGRAM: Vertex program instructions. - * Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB), - * whereas the difference between known addresses suggests size 512. - * - * Starting at address UPLOAD_PARAMETERS: Vertex program parameters. - * Native reported limits and the VPI layout suggest size 256, whereas - * difference between known addresses suggests size 512. - * - * At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the - * floating point pointsize. The exact purpose of this state is uncertain, - * as there is also the R300_RE_POINTSIZE register. - * - * Multiple vertex programs and parameter sets can be loaded at once, - * which could explain the size discrepancy. - */ -#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 -# define R300_PVS_UPLOAD_PROGRAM 0x00000000 -# define R300_PVS_UPLOAD_PARAMETERS 0x00000200 -# define R300_PVS_UPLOAD_POINTSIZE 0x00000406 - -/* gap */ - -#define R300_VAP_PVS_UPLOAD_DATA 0x2208 - -/* END: Upload vertex program and data */ - -/* gap */ - -/* I do not know the purpose of this register. However, I do know that - * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL - * for normal rendering. - */ -#define R300_VAP_UNKNOWN_221C 0x221C -# define R300_221C_NORMAL 0x00000000 -# define R300_221C_CLEAR 0x0001C000 - -/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first - * plane is per-pixel and the second plane is per-vertex. - * - * This was determined by experimentation alone but I believe it is correct. - * - * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest. - */ -#define R300_VAP_CLIP_X_0 0x2220 -#define R300_VAP_CLIP_X_1 0x2224 -#define R300_VAP_CLIP_Y_0 0x2228 -#define R300_VAP_CLIP_Y_1 0x2230 - -/* gap */ - -/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between - * rendering commands and overwriting vertex program parameters. - * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and - * avoids bugs caused by still running shaders reading bad data from memory. - */ -#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */ - -/* Absolutely no clue what this register is about. */ -#define R300_VAP_UNKNOWN_2288 0x2288 -# define R300_2288_R300 0x00750000 /* -- nh */ -# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ - -/* gap */ - -/* Addresses are relative to the vertex program instruction area of the - * memory bank. PROGRAM_END points to the last instruction of the active - * program - * - * The meaning of the two UNKNOWN fields is obviously not known. However, - * experiments so far have shown that both *must* point to an instruction - * inside the vertex program, otherwise the GPU locks up. - * - * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and - * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to - * position takes place. - * - * Most likely this is used to ignore rest of the program in cases - * where group of verts arent visible. For some reason this "section" - * is sometimes accepted other instruction that have no relationship with - * position calculations. - */ -#define R300_VAP_PVS_CNTL_1 0x22D0 -# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 -# define R300_PVS_CNTL_1_POS_END_SHIFT 10 -# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20 -/* Addresses are relative the the vertex program parameters area. */ -#define R300_VAP_PVS_CNTL_2 0x22D4 -# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0 -# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16 -#define R300_VAP_PVS_CNTL_3 0x22D8 -# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10 -# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0 - -/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for - * immediate vertices - */ -#define R300_VAP_VTX_COLOR_R 0x2464 -#define R300_VAP_VTX_COLOR_G 0x2468 -#define R300_VAP_VTX_COLOR_B 0x246C -#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */ -#define R300_VAP_VTX_POS_0_Y_1 0x2494 -#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */ -#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */ -#define R300_VAP_VTX_POS_0_Y_2 0x24A4 -#define R300_VAP_VTX_POS_0_Z_2 0x24A8 -/* write 0 to indicate end of packet? */ -#define R300_VAP_VTX_END_OF_PKT 0x24AC - -/* gap */ - -/* These are values from r300_reg/r300_reg.h - they are known to be correct - * and are here so we can use one register file instead of several - * - Vladimir - */ -#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000 -# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5) -# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16) - -#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004 - /* each of the following is 3 bits wide, specifies number - of components */ -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 - -/* UNK30 seems to enables point to quad transformation on textures - * (or something closely related to that). - * This bit is rather fatal at the time being due to lackings at pixel - * shader side - */ -#define R300_GB_ENABLE 0x4008 -# define R300_GB_POINT_STUFF_ENABLE (1<<0) -# define R300_GB_LINE_STUFF_ENABLE (1<<1) -# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2) -# define R300_GB_STENCIL_AUTO_ENABLE (1<<4) -# define R300_GB_UNK31 (1<<31) - /* each of the following is 2 bits wide */ -#define R300_GB_TEX_REPLICATE 0 -#define R300_GB_TEX_ST 1 -#define R300_GB_TEX_STR 2 -# define R300_GB_TEX0_SOURCE_SHIFT 16 -# define R300_GB_TEX1_SOURCE_SHIFT 18 -# define R300_GB_TEX2_SOURCE_SHIFT 20 -# define R300_GB_TEX3_SOURCE_SHIFT 22 -# define R300_GB_TEX4_SOURCE_SHIFT 24 -# define R300_GB_TEX5_SOURCE_SHIFT 26 -# define R300_GB_TEX6_SOURCE_SHIFT 28 -# define R300_GB_TEX7_SOURCE_SHIFT 30 - -/* MSPOS - positions for multisample antialiasing (?) */ -#define R300_GB_MSPOS0 0x4010 - /* shifts - each of the fields is 4 bits */ -# define R300_GB_MSPOS0__MS_X0_SHIFT 0 -# define R300_GB_MSPOS0__MS_Y0_SHIFT 4 -# define R300_GB_MSPOS0__MS_X1_SHIFT 8 -# define R300_GB_MSPOS0__MS_Y1_SHIFT 12 -# define R300_GB_MSPOS0__MS_X2_SHIFT 16 -# define R300_GB_MSPOS0__MS_Y2_SHIFT 20 -# define R300_GB_MSPOS0__MSBD0_Y 24 -# define R300_GB_MSPOS0__MSBD0_X 28 - -#define R300_GB_MSPOS1 0x4014 -# define R300_GB_MSPOS1__MS_X3_SHIFT 0 -# define R300_GB_MSPOS1__MS_Y3_SHIFT 4 -# define R300_GB_MSPOS1__MS_X4_SHIFT 8 -# define R300_GB_MSPOS1__MS_Y4_SHIFT 12 -# define R300_GB_MSPOS1__MS_X5_SHIFT 16 -# define R300_GB_MSPOS1__MS_Y5_SHIFT 20 -# define R300_GB_MSPOS1__MSBD1 24 - - -#define R300_GB_TILE_CONFIG 0x4018 -# define R300_GB_TILE_ENABLE (1<<0) -# define R300_GB_TILE_PIPE_COUNT_RV300 0 -# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1) -# define R300_GB_TILE_PIPE_COUNT_R420 (7<<1) -# define R300_GB_TILE_PIPE_COUNT_RV410 (3<<1) -# define R300_GB_TILE_SIZE_8 0 -# define R300_GB_TILE_SIZE_16 (1<<4) -# define R300_GB_TILE_SIZE_32 (2<<4) -# define R300_GB_SUPER_SIZE_1 (0<<6) -# define R300_GB_SUPER_SIZE_2 (1<<6) -# define R300_GB_SUPER_SIZE_4 (2<<6) -# define R300_GB_SUPER_SIZE_8 (3<<6) -# define R300_GB_SUPER_SIZE_16 (4<<6) -# define R300_GB_SUPER_SIZE_32 (5<<6) -# define R300_GB_SUPER_SIZE_64 (6<<6) -# define R300_GB_SUPER_SIZE_128 (7<<6) -# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */ -# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */ -# define R300_GB_SUPER_TILE_A 0 -# define R300_GB_SUPER_TILE_B (1<<15) -# define R300_GB_SUBPIXEL_1_12 0 -# define R300_GB_SUBPIXEL_1_16 (1<<16) - -#define R300_GB_FIFO_SIZE 0x4024 - /* each of the following is 2 bits wide */ -#define R300_GB_FIFO_SIZE_32 0 -#define R300_GB_FIFO_SIZE_64 1 -#define R300_GB_FIFO_SIZE_128 2 -#define R300_GB_FIFO_SIZE_256 3 -# define R300_SC_IFIFO_SIZE_SHIFT 0 -# define R300_SC_TZFIFO_SIZE_SHIFT 2 -# define R300_SC_BFIFO_SIZE_SHIFT 4 - -# define R300_US_OFIFO_SIZE_SHIFT 12 -# define R300_US_WFIFO_SIZE_SHIFT 14 - /* the following use the same constants as above, but meaning is - is times 2 (i.e. instead of 32 words it means 64 */ -# define R300_RS_TFIFO_SIZE_SHIFT 6 -# define R300_RS_CFIFO_SIZE_SHIFT 8 -# define R300_US_RAM_SIZE_SHIFT 10 - /* watermarks, 3 bits wide */ -# define R300_RS_HIGHWATER_COL_SHIFT 16 -# define R300_RS_HIGHWATER_TEX_SHIFT 19 -# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ -# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 - -#define R300_GB_SELECT 0x401C -# define R300_GB_FOG_SELECT_C0A 0 -# define R300_GB_FOG_SELECT_C1A 1 -# define R300_GB_FOG_SELECT_C2A 2 -# define R300_GB_FOG_SELECT_C3A 3 -# define R300_GB_FOG_SELECT_1_1_W 4 -# define R300_GB_FOG_SELECT_Z 5 -# define R300_GB_DEPTH_SELECT_Z 0 -# define R300_GB_DEPTH_SELECT_1_1_W (1<<3) -# define R300_GB_W_SELECT_1_W 0 -# define R300_GB_W_SELECT_1 (1<<4) - -#define R300_GB_AA_CONFIG 0x4020 -# define R300_AA_DISABLE 0x00 -# define R300_AA_ENABLE 0x01 -# define R300_AA_SUBSAMPLES_2 0 -# define R300_AA_SUBSAMPLES_3 (1<<1) -# define R300_AA_SUBSAMPLES_4 (2<<1) -# define R300_AA_SUBSAMPLES_6 (3<<1) - -/* gap */ - -/* Zero to flush caches. */ -#define R300_TX_CNTL 0x4100 -#define R300_TX_FLUSH 0x0 - -/* The upper enable bits are guessed, based on fglrx reported limits. */ -#define R300_TX_ENABLE 0x4104 -# define R300_TX_ENABLE_0 (1 << 0) -# define R300_TX_ENABLE_1 (1 << 1) -# define R300_TX_ENABLE_2 (1 << 2) -# define R300_TX_ENABLE_3 (1 << 3) -# define R300_TX_ENABLE_4 (1 << 4) -# define R300_TX_ENABLE_5 (1 << 5) -# define R300_TX_ENABLE_6 (1 << 6) -# define R300_TX_ENABLE_7 (1 << 7) -# define R300_TX_ENABLE_8 (1 << 8) -# define R300_TX_ENABLE_9 (1 << 9) -# define R300_TX_ENABLE_10 (1 << 10) -# define R300_TX_ENABLE_11 (1 << 11) -# define R300_TX_ENABLE_12 (1 << 12) -# define R300_TX_ENABLE_13 (1 << 13) -# define R300_TX_ENABLE_14 (1 << 14) -# define R300_TX_ENABLE_15 (1 << 15) - -/* The pointsize is given in multiples of 6. The pointsize can be - * enormous: Clear() renders a single point that fills the entire - * framebuffer. - */ -#define R300_RE_POINTSIZE 0x421C -# define R300_POINTSIZE_Y_SHIFT 0 -# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */ -# define R300_POINTSIZE_X_SHIFT 16 -# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */ -# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6) - -/* The line width is given in multiples of 6. - * In default mode lines are classified as vertical lines. - * HO: horizontal - * VE: vertical or horizontal - * HO & VE: no classification - */ -#define R300_RE_LINE_CNT 0x4234 -# define R300_LINESIZE_SHIFT 0 -# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */ -# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6) -# define R300_LINE_CNT_HO (1 << 16) -# define R300_LINE_CNT_VE (1 << 17) - -/* Some sort of scale or clamp value for texcoordless textures. */ -#define R300_RE_UNK4238 0x4238 - -/* Something shade related */ -#define R300_RE_SHADE 0x4274 - -#define R300_RE_SHADE_MODEL 0x4278 -# define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa -# define R300_RE_SHADE_MODEL_FLAT 0x39595 - -/* Dangerous */ -#define R300_RE_POLYGON_MODE 0x4288 -# define R300_PM_ENABLED (1 << 0) -# define R300_PM_FRONT_POINT (0 << 0) -# define R300_PM_BACK_POINT (0 << 0) -# define R300_PM_FRONT_LINE (1 << 4) -# define R300_PM_FRONT_FILL (1 << 5) -# define R300_PM_BACK_LINE (1 << 7) -# define R300_PM_BACK_FILL (1 << 8) - -/* Fog parameters */ -#define R300_RE_FOG_SCALE 0x4294 -#define R300_RE_FOG_START 0x4298 - -/* Not sure why there are duplicate of factor and constant values. - * My best guess so far is that there are separate zbiases for test and write. - * Ordering might be wrong. - * Some of the tests indicate that fgl has a fallback implementation of zbias - * via pixel shaders. - */ -#define R300_RE_ZBIAS_CNTL 0x42A0 /* GUESS */ -#define R300_RE_ZBIAS_T_FACTOR 0x42A4 -#define R300_RE_ZBIAS_T_CONSTANT 0x42A8 -#define R300_RE_ZBIAS_W_FACTOR 0x42AC -#define R300_RE_ZBIAS_W_CONSTANT 0x42B0 - -/* This register needs to be set to (1<<1) for RV350 to correctly - * perform depth test (see --vb-triangles in r300_demo) - * Don't know about other chips. - Vladimir - * This is set to 3 when GL_POLYGON_OFFSET_FILL is on. - * My guess is that there are two bits for each zbias primitive - * (FILL, LINE, POINT). - * One to enable depth test and one for depth write. - * Yet this doesnt explain why depth writes work ... - */ -#define R300_RE_OCCLUSION_CNTL 0x42B4 -# define R300_OCCLUSION_ON (1<<1) - -#define R300_RE_CULL_CNTL 0x42B8 -# define R300_CULL_FRONT (1 << 0) -# define R300_CULL_BACK (1 << 1) -# define R300_FRONT_FACE_CCW (0 << 2) -# define R300_FRONT_FACE_CW (1 << 2) - - -/* BEGIN: Rasterization / Interpolators - many guesses */ - -/* 0_UNKNOWN_18 has always been set except for clear operations. - * TC_CNT is the number of incoming texture coordinate sets (i.e. it depends - * on the vertex program, *not* the fragment program) - */ -#define R300_RS_CNTL_0 0x4300 -# define R300_RS_CNTL_TC_CNT_SHIFT 2 -# define R300_RS_CNTL_TC_CNT_MASK (7 << 2) - /* number of color interpolators used */ -# define R300_RS_CNTL_CI_CNT_SHIFT 7 -# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18) - /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n - register. */ -#define R300_RS_CNTL_1 0x4304 - -/* gap */ - -/* Only used for texture coordinates. - * Use the source field to route texture coordinate input from the - * vertex program to the desired interpolator. Note that the source - * field is relative to the outputs the vertex program *actually* - * writes. If a vertex program only writes texcoord[1], this will - * be source index 0. - * Set INTERP_USED on all interpolators that produce data used by - * the fragment program. INTERP_USED looks like a swizzling mask, - * but I haven't seen it used that way. - * - * Note: The _UNKNOWN constants are always set in their respective - * register. I don't know if this is necessary. - */ -#define R300_RS_INTERP_0 0x4310 -#define R300_RS_INTERP_1 0x4314 -# define R300_RS_INTERP_1_UNKNOWN 0x40 -#define R300_RS_INTERP_2 0x4318 -# define R300_RS_INTERP_2_UNKNOWN 0x80 -#define R300_RS_INTERP_3 0x431C -# define R300_RS_INTERP_3_UNKNOWN 0xC0 -#define R300_RS_INTERP_4 0x4320 -#define R300_RS_INTERP_5 0x4324 -#define R300_RS_INTERP_6 0x4328 -#define R300_RS_INTERP_7 0x432C -# define R300_RS_INTERP_SRC_SHIFT 2 -# define R300_RS_INTERP_SRC_MASK (7 << 2) -# define R300_RS_INTERP_USED 0x00D10000 - -/* These DWORDs control how vertex data is routed into fragment program - * registers, after interpolators. - */ -#define R300_RS_ROUTE_0 0x4330 -#define R300_RS_ROUTE_1 0x4334 -#define R300_RS_ROUTE_2 0x4338 -#define R300_RS_ROUTE_3 0x433C /* GUESS */ -#define R300_RS_ROUTE_4 0x4340 /* GUESS */ -#define R300_RS_ROUTE_5 0x4344 /* GUESS */ -#define R300_RS_ROUTE_6 0x4348 /* GUESS */ -#define R300_RS_ROUTE_7 0x434C /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_0 0 -# define R300_RS_ROUTE_SOURCE_INTERP_1 1 -# define R300_RS_ROUTE_SOURCE_INTERP_2 2 -# define R300_RS_ROUTE_SOURCE_INTERP_3 3 -# define R300_RS_ROUTE_SOURCE_INTERP_4 4 -# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ -# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ -# define R300_RS_ROUTE_DEST_SHIFT 6 -# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ - -/* Special handling for color: When the fragment program uses color, - * the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the - * color register index. - * - * Apperently you may set the R300_RS_ROUTE_0_COLOR bit, but not provide any - * R300_RS_ROUTE_0_COLOR_DEST value; this setup is used for clearing the state. - * See r300_ioctl.c:r300EmitClearState. I'm not sure if this setup is strictly - * correct or not. - Oliver. - */ -# define R300_RS_ROUTE_0_COLOR (1 << 14) -# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17 -# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ -/* As above, but for secondary color */ -# define R300_RS_ROUTE_1_COLOR1 (1 << 14) -# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 -# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17) -# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11) -/* END: Rasterization / Interpolators - many guesses */ - -/* Hierarchical Z Enable */ -#define R300_SC_HYPERZ 0x43a4 -# define R300_SC_HYPERZ_DISABLE (0 << 0) -# define R300_SC_HYPERZ_ENABLE (1 << 0) -# define R300_SC_HYPERZ_MIN (0 << 1) -# define R300_SC_HYPERZ_MAX (1 << 1) -# define R300_SC_HYPERZ_ADJ_256 (0 << 2) -# define R300_SC_HYPERZ_ADJ_128 (1 << 2) -# define R300_SC_HYPERZ_ADJ_64 (2 << 2) -# define R300_SC_HYPERZ_ADJ_32 (3 << 2) -# define R300_SC_HYPERZ_ADJ_16 (4 << 2) -# define R300_SC_HYPERZ_ADJ_8 (5 << 2) -# define R300_SC_HYPERZ_ADJ_4 (6 << 2) -# define R300_SC_HYPERZ_ADJ_2 (7 << 2) -# define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5) -# define R300_SC_HYPERZ_HZ_Z0MIN (1 << 5) -# define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6) -# define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6) - -#define R300_SC_EDGERULE 0x43a8 - -/* BEGIN: Scissors and cliprects */ - -/* There are four clipping rectangles. Their corner coordinates are inclusive. - * Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending - * on whether the pixel is inside cliprects 0-3, respectively. For example, - * if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned - * the number 3 (binary 0011). - * Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set, - * the pixel is rasterized. - * - * In addition to this, there is a scissors rectangle. Only pixels inside the - * scissors rectangle are drawn. (coordinates are inclusive) - * - * For some reason, the top-left corner of the framebuffer is at (1440, 1440) - * for the purpose of clipping and scissors. - */ -#define R300_RE_CLIPRECT_TL_0 0x43B0 -#define R300_RE_CLIPRECT_BR_0 0x43B4 -#define R300_RE_CLIPRECT_TL_1 0x43B8 -#define R300_RE_CLIPRECT_BR_1 0x43BC -#define R300_RE_CLIPRECT_TL_2 0x43C0 -#define R300_RE_CLIPRECT_BR_2 0x43C4 -#define R300_RE_CLIPRECT_TL_3 0x43C8 -#define R300_RE_CLIPRECT_BR_3 0x43CC -# define R300_CLIPRECT_OFFSET 1440 -# define R300_CLIPRECT_MASK 0x1FFF -# define R300_CLIPRECT_X_SHIFT 0 -# define R300_CLIPRECT_X_MASK (0x1FFF << 0) -# define R300_CLIPRECT_Y_SHIFT 13 -# define R300_CLIPRECT_Y_MASK (0x1FFF << 13) -#define R300_RE_CLIPRECT_CNTL 0x43D0 -# define R300_CLIP_OUT (1 << 0) -# define R300_CLIP_0 (1 << 1) -# define R300_CLIP_1 (1 << 2) -# define R300_CLIP_10 (1 << 3) -# define R300_CLIP_2 (1 << 4) -# define R300_CLIP_20 (1 << 5) -# define R300_CLIP_21 (1 << 6) -# define R300_CLIP_210 (1 << 7) -# define R300_CLIP_3 (1 << 8) -# define R300_CLIP_30 (1 << 9) -# define R300_CLIP_31 (1 << 10) -# define R300_CLIP_310 (1 << 11) -# define R300_CLIP_32 (1 << 12) -# define R300_CLIP_320 (1 << 13) -# define R300_CLIP_321 (1 << 14) -# define R300_CLIP_3210 (1 << 15) - -/* gap */ - -#define R300_RE_SCISSORS_TL 0x43E0 -#define R300_RE_SCISSORS_BR 0x43E4 -# define R300_SCISSORS_OFFSET 1440 -# define R300_SCISSORS_X_SHIFT 0 -# define R300_SCISSORS_X_MASK (0x1FFF << 0) -# define R300_SCISSORS_Y_SHIFT 13 -# define R300_SCISSORS_Y_MASK (0x1FFF << 13) -/* END: Scissors and cliprects */ - -/* BEGIN: Texture specification */ - -/* - * The texture specification dwords are grouped by meaning and not by texture - * unit. This means that e.g. the offset for texture image unit N is found in - * register TX_OFFSET_0 + (4*N) - */ -#define R300_TX_FILTER_0 0x4400 -# define R300_TX_REPEAT 0 -# define R300_TX_MIRRORED 1 -# define R300_TX_CLAMP 4 -# define R300_TX_CLAMP_TO_EDGE 2 -# define R300_TX_CLAMP_TO_BORDER 6 -# define R300_TX_WRAP_S_SHIFT 0 -# define R300_TX_WRAP_S_MASK (7 << 0) -# define R300_TX_WRAP_T_SHIFT 3 -# define R300_TX_WRAP_T_MASK (7 << 3) -# define R300_TX_WRAP_Q_SHIFT 6 -# define R300_TX_WRAP_Q_MASK (7 << 6) -# define R300_TX_MAG_FILTER_NEAREST (1 << 9) -# define R300_TX_MAG_FILTER_LINEAR (2 << 9) -# define R300_TX_MAG_FILTER_MASK (3 << 9) -# define R300_TX_MIN_FILTER_NEAREST (1 << 11) -# define R300_TX_MIN_FILTER_LINEAR (2 << 11) -# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11) -# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11) -# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) -# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) - -/* NOTE: NEAREST doesnt seem to exist. - * Im not seting MAG_FILTER_MASK and (3 << 11) on for all - * anisotropy modes because that would void selected mag filter - */ -# define R300_TX_MIN_FILTER_ANISO_NEAREST (0 << 13) -# define R300_TX_MIN_FILTER_ANISO_LINEAR (0 << 13) -# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (1 << 13) -# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (2 << 13) -# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) ) -# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21) -# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21) -# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21) -# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21) -# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) -# define R300_TX_MAX_ANISO_MASK (14 << 21) - -#define R300_TX_FILTER1_0 0x4440 -# define R300_CHROMA_KEY_MODE_DISABLE 0 -# define R300_CHROMA_KEY_FORCE 1 -# define R300_CHROMA_KEY_BLEND 2 -# define R300_MC_ROUND_NORMAL (0<<2) -# define R300_MC_ROUND_MPEG4 (1<<2) -# define R300_LOD_BIAS_MASK 0x1fff -# define R300_EDGE_ANISO_EDGE_DIAG (0<<13) -# define R300_EDGE_ANISO_EDGE_ONLY (1<<13) -# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) -# define R300_MC_COORD_TRUNCATE_MPEG (1<<14) -# define R300_TX_TRI_PERF_0_8 (0<<15) -# define R300_TX_TRI_PERF_1_8 (1<<15) -# define R300_TX_TRI_PERF_1_4 (2<<15) -# define R300_TX_TRI_PERF_3_8 (3<<15) -# define R300_ANISO_THRESHOLD_MASK (7<<17) - -#define R300_TX_SIZE_0 0x4480 -# define R300_TX_WIDTHMASK_SHIFT 0 -# define R300_TX_WIDTHMASK_MASK (2047 << 0) -# define R300_TX_HEIGHTMASK_SHIFT 11 -# define R300_TX_HEIGHTMASK_MASK (2047 << 11) -# define R300_TX_UNK23 (1 << 23) -# define R300_TX_MAX_MIP_LEVEL_SHIFT 26 -# define R300_TX_MAX_MIP_LEVEL_MASK (0xf << 26) -# define R300_TX_SIZE_PROJECTED (1<<30) -# define R300_TX_SIZE_TXPITCH_EN (1<<31) -#define R300_TX_FORMAT_0 0x44C0 - /* The interpretation of the format word by Wladimir van der Laan */ - /* The X, Y, Z and W refer to the layout of the components. - They are given meanings as R, G, B and Alpha by the swizzle - specification */ -# define R300_TX_FORMAT_X8 0x0 -# define R300_TX_FORMAT_X16 0x1 -# define R300_TX_FORMAT_Y4X4 0x2 -# define R300_TX_FORMAT_Y8X8 0x3 -# define R300_TX_FORMAT_Y16X16 0x4 -# define R300_TX_FORMAT_Z3Y3X2 0x5 -# define R300_TX_FORMAT_Z5Y6X5 0x6 -# define R300_TX_FORMAT_Z6Y5X5 0x7 -# define R300_TX_FORMAT_Z11Y11X10 0x8 -# define R300_TX_FORMAT_Z10Y11X11 0x9 -# define R300_TX_FORMAT_W4Z4Y4X4 0xA -# define R300_TX_FORMAT_W1Z5Y5X5 0xB -# define R300_TX_FORMAT_W8Z8Y8X8 0xC -# define R300_TX_FORMAT_W2Z10Y10X10 0xD -# define R300_TX_FORMAT_W16Z16Y16X16 0xE -# define R300_TX_FORMAT_DXT1 0xF -# define R300_TX_FORMAT_DXT3 0x10 -# define R300_TX_FORMAT_DXT5 0x11 -# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ -# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ -# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ -# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ - /* 0x16 - some 16 bit green format.. ?? */ -# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ -# define R300_TX_FORMAT_CUBIC_MAP (1 << 26) - - /* gap */ - /* Floating point formats */ - /* Note - hardware supports both 16 and 32 bit floating point */ -# define R300_TX_FORMAT_FL_I16 0x18 -# define R300_TX_FORMAT_FL_I16A16 0x19 -# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A -# define R300_TX_FORMAT_FL_I32 0x1B -# define R300_TX_FORMAT_FL_I32A32 0x1C -# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D - /* alpha modes, convenience mostly */ - /* if you have alpha, pick constant appropriate to the - number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ -# define R300_TX_FORMAT_ALPHA_1CH 0x000 -# define R300_TX_FORMAT_ALPHA_2CH 0x200 -# define R300_TX_FORMAT_ALPHA_4CH 0x600 -# define R300_TX_FORMAT_ALPHA_NONE 0xA00 - /* Swizzling */ - /* constants */ -# define R300_TX_FORMAT_X 0 -# define R300_TX_FORMAT_Y 1 -# define R300_TX_FORMAT_Z 2 -# define R300_TX_FORMAT_W 3 -# define R300_TX_FORMAT_ZERO 4 -# define R300_TX_FORMAT_ONE 5 - /* 2.0*Z, everything above 1.0 is set to 0.0 */ -# define R300_TX_FORMAT_CUT_Z 6 - /* 2.0*W, everything above 1.0 is set to 0.0 */ -# define R300_TX_FORMAT_CUT_W 7 - -# define R300_TX_FORMAT_B_SHIFT 18 -# define R300_TX_FORMAT_G_SHIFT 15 -# define R300_TX_FORMAT_R_SHIFT 12 -# define R300_TX_FORMAT_A_SHIFT 9 - /* Convenience macro to take care of layout and swizzling */ -# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) ( \ - ((R300_TX_FORMAT_##B)< 0.5, return ARG0, else return ARG1 - * - CMP: If ARG2 < 0, return ARG1, else return ARG0 - * - FLR: use FRC+MAD - * - XPD: use MAD+MAD - * - SGE, SLT: use MAD+CMP - * - RSQ: use ABS modifier for argument - * - Use OUTC_REPL_ALPHA to write results of an alpha-only operation - * (e.g. RCP) into color register - * - apparently, there's no quick DST operation - * - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2" - * - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0" - * - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1" - * - * Operand selection - * First stage selects three sources from the available registers and - * constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha). - * fglrx sorts the three source fields: Registers before constants, - * lower indices before higher indices; I do not know whether this is - * necessary. - * - * fglrx fills unused sources with "read constant 0" - * According to specs, you cannot select more than two different constants. - * - * Second stage selects the operands from the sources. This is defined in - * INSTR0 (color) and INSTR2 (alpha). You can also select the special constants - * zero and one. - * Swizzling and negation happens in this stage, as well. - * - * Important: Color and alpha seem to be mostly separate, i.e. their sources - * selection appears to be fully independent (the register storage is probably - * physically split into a color and an alpha section). - * However (because of the apparent physical split), there is some interaction - * WRT swizzling. If, for example, you want to load an R component into an - * Alpha operand, this R component is taken from a *color* source, not from - * an alpha source. The corresponding register doesn't even have to appear in - * the alpha sources list. (I hope this all makes sense to you) - * - * Destination selection - * The destination register index is in FPI1 (color) and FPI3 (alpha) - * together with enable bits. - * There are separate enable bits for writing into temporary registers - * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* - * /DSTA_OUTPUT). You can write to both at once, or not write at all (the - * same index must be used for both). - * - * Note: There is a special form for LRP - * - Argument order is the same as in ARB_fragment_program. - * - Operation is MAD - * - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP - * - Set FPI0/FPI2_SPECIAL_LRP - * Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD - */ -#define R300_PFS_INSTR1_0 0x46C0 -# define R300_FPI1_SRC0C_SHIFT 0 -# define R300_FPI1_SRC0C_MASK (31 << 0) -# define R300_FPI1_SRC0C_CONST (1 << 5) -# define R300_FPI1_SRC1C_SHIFT 6 -# define R300_FPI1_SRC1C_MASK (31 << 6) -# define R300_FPI1_SRC1C_CONST (1 << 11) -# define R300_FPI1_SRC2C_SHIFT 12 -# define R300_FPI1_SRC2C_MASK (31 << 12) -# define R300_FPI1_SRC2C_CONST (1 << 17) -# define R300_FPI1_SRC_MASK 0x0003ffff -# define R300_FPI1_DSTC_SHIFT 18 -# define R300_FPI1_DSTC_MASK (31 << 18) -# define R300_FPI1_DSTC_REG_MASK_SHIFT 23 -# define R300_FPI1_DSTC_REG_X (1 << 23) -# define R300_FPI1_DSTC_REG_Y (1 << 24) -# define R300_FPI1_DSTC_REG_Z (1 << 25) -# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26 -# define R300_FPI1_DSTC_OUTPUT_X (1 << 26) -# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) -# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) - -#define R300_PFS_INSTR3_0 0x47C0 -# define R300_FPI3_SRC0A_SHIFT 0 -# define R300_FPI3_SRC0A_MASK (31 << 0) -# define R300_FPI3_SRC0A_CONST (1 << 5) -# define R300_FPI3_SRC1A_SHIFT 6 -# define R300_FPI3_SRC1A_MASK (31 << 6) -# define R300_FPI3_SRC1A_CONST (1 << 11) -# define R300_FPI3_SRC2A_SHIFT 12 -# define R300_FPI3_SRC2A_MASK (31 << 12) -# define R300_FPI3_SRC2A_CONST (1 << 17) -# define R300_FPI3_SRC_MASK 0x0003ffff -# define R300_FPI3_DSTA_SHIFT 18 -# define R300_FPI3_DSTA_MASK (31 << 18) -# define R300_FPI3_DSTA_REG (1 << 23) -# define R300_FPI3_DSTA_OUTPUT (1 << 24) -# define R300_FPI3_DSTA_DEPTH (1 << 27) - -#define R300_PFS_INSTR0_0 0x48C0 -# define R300_FPI0_ARGC_SRC0C_XYZ 0 -# define R300_FPI0_ARGC_SRC0C_XXX 1 -# define R300_FPI0_ARGC_SRC0C_YYY 2 -# define R300_FPI0_ARGC_SRC0C_ZZZ 3 -# define R300_FPI0_ARGC_SRC1C_XYZ 4 -# define R300_FPI0_ARGC_SRC1C_XXX 5 -# define R300_FPI0_ARGC_SRC1C_YYY 6 -# define R300_FPI0_ARGC_SRC1C_ZZZ 7 -# define R300_FPI0_ARGC_SRC2C_XYZ 8 -# define R300_FPI0_ARGC_SRC2C_XXX 9 -# define R300_FPI0_ARGC_SRC2C_YYY 10 -# define R300_FPI0_ARGC_SRC2C_ZZZ 11 -# define R300_FPI0_ARGC_SRC0A 12 -# define R300_FPI0_ARGC_SRC1A 13 -# define R300_FPI0_ARGC_SRC2A 14 -# define R300_FPI0_ARGC_SRC1C_LRP 15 -# define R300_FPI0_ARGC_ZERO 20 -# define R300_FPI0_ARGC_ONE 21 - /* GUESS */ -# define R300_FPI0_ARGC_HALF 22 -# define R300_FPI0_ARGC_SRC0C_YZX 23 -# define R300_FPI0_ARGC_SRC1C_YZX 24 -# define R300_FPI0_ARGC_SRC2C_YZX 25 -# define R300_FPI0_ARGC_SRC0C_ZXY 26 -# define R300_FPI0_ARGC_SRC1C_ZXY 27 -# define R300_FPI0_ARGC_SRC2C_ZXY 28 -# define R300_FPI0_ARGC_SRC0CA_WZY 29 -# define R300_FPI0_ARGC_SRC1CA_WZY 30 -# define R300_FPI0_ARGC_SRC2CA_WZY 31 - -# define R300_FPI0_ARG0C_SHIFT 0 -# define R300_FPI0_ARG0C_MASK (31 << 0) -# define R300_FPI0_ARG0C_NEG (1 << 5) -# define R300_FPI0_ARG0C_ABS (1 << 6) -# define R300_FPI0_ARG1C_SHIFT 7 -# define R300_FPI0_ARG1C_MASK (31 << 7) -# define R300_FPI0_ARG1C_NEG (1 << 12) -# define R300_FPI0_ARG1C_ABS (1 << 13) -# define R300_FPI0_ARG2C_SHIFT 14 -# define R300_FPI0_ARG2C_MASK (31 << 14) -# define R300_FPI0_ARG2C_NEG (1 << 19) -# define R300_FPI0_ARG2C_ABS (1 << 20) -# define R300_FPI0_SPECIAL_LRP (1 << 21) -# define R300_FPI0_OUTC_MAD (0 << 23) -# define R300_FPI0_OUTC_DP3 (1 << 23) -# define R300_FPI0_OUTC_DP4 (2 << 23) -# define R300_FPI0_OUTC_MIN (4 << 23) -# define R300_FPI0_OUTC_MAX (5 << 23) -# define R300_FPI0_OUTC_CMPH (7 << 23) -# define R300_FPI0_OUTC_CMP (8 << 23) -# define R300_FPI0_OUTC_FRC (9 << 23) -# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) -# define R300_FPI0_OUTC_SAT (1 << 30) -# define R300_FPI0_INSERT_NOP (1 << 31) - -#define R300_PFS_INSTR2_0 0x49C0 -# define R300_FPI2_ARGA_SRC0C_X 0 -# define R300_FPI2_ARGA_SRC0C_Y 1 -# define R300_FPI2_ARGA_SRC0C_Z 2 -# define R300_FPI2_ARGA_SRC1C_X 3 -# define R300_FPI2_ARGA_SRC1C_Y 4 -# define R300_FPI2_ARGA_SRC1C_Z 5 -# define R300_FPI2_ARGA_SRC2C_X 6 -# define R300_FPI2_ARGA_SRC2C_Y 7 -# define R300_FPI2_ARGA_SRC2C_Z 8 -# define R300_FPI2_ARGA_SRC0A 9 -# define R300_FPI2_ARGA_SRC1A 10 -# define R300_FPI2_ARGA_SRC2A 11 -# define R300_FPI2_ARGA_SRC1A_LRP 15 -# define R300_FPI2_ARGA_ZERO 16 -# define R300_FPI2_ARGA_ONE 17 - /* GUESS */ -# define R300_FPI2_ARGA_HALF 18 -# define R300_FPI2_ARG0A_SHIFT 0 -# define R300_FPI2_ARG0A_MASK (31 << 0) -# define R300_FPI2_ARG0A_NEG (1 << 5) - /* GUESS */ -# define R300_FPI2_ARG0A_ABS (1 << 6) -# define R300_FPI2_ARG1A_SHIFT 7 -# define R300_FPI2_ARG1A_MASK (31 << 7) -# define R300_FPI2_ARG1A_NEG (1 << 12) - /* GUESS */ -# define R300_FPI2_ARG1A_ABS (1 << 13) -# define R300_FPI2_ARG2A_SHIFT 14 -# define R300_FPI2_ARG2A_MASK (31 << 14) -# define R300_FPI2_ARG2A_NEG (1 << 19) - /* GUESS */ -# define R300_FPI2_ARG2A_ABS (1 << 20) -# define R300_FPI2_SPECIAL_LRP (1 << 21) -# define R300_FPI2_OUTA_MAD (0 << 23) -# define R300_FPI2_OUTA_DP4 (1 << 23) -# define R300_FPI2_OUTA_MIN (2 << 23) -# define R300_FPI2_OUTA_MAX (3 << 23) -# define R300_FPI2_OUTA_CMP (6 << 23) -# define R300_FPI2_OUTA_FRC (7 << 23) -# define R300_FPI2_OUTA_EX2 (8 << 23) -# define R300_FPI2_OUTA_LG2 (9 << 23) -# define R300_FPI2_OUTA_RCP (10 << 23) -# define R300_FPI2_OUTA_RSQ (11 << 23) -# define R300_FPI2_OUTA_SAT (1 << 30) -# define R300_FPI2_UNKNOWN_31 (1 << 31) -/* END: Fragment program instruction set */ - -/* Fog state and color */ -#define R300_RE_FOG_STATE 0x4BC0 -# define R300_FOG_ENABLE (1 << 0) -# define R300_FOG_MODE_LINEAR (0 << 1) -# define R300_FOG_MODE_EXP (1 << 1) -# define R300_FOG_MODE_EXP2 (2 << 1) -# define R300_FOG_MODE_MASK (3 << 1) -#define R300_FOG_COLOR_R 0x4BC8 -#define R300_FOG_COLOR_G 0x4BCC -#define R300_FOG_COLOR_B 0x4BD0 - -#define R300_PP_ALPHA_TEST 0x4BD4 -# define R300_REF_ALPHA_MASK 0x000000ff -# define R300_ALPHA_TEST_FAIL (0 << 8) -# define R300_ALPHA_TEST_LESS (1 << 8) -# define R300_ALPHA_TEST_LEQUAL (3 << 8) -# define R300_ALPHA_TEST_EQUAL (2 << 8) -# define R300_ALPHA_TEST_GEQUAL (6 << 8) -# define R300_ALPHA_TEST_GREATER (4 << 8) -# define R300_ALPHA_TEST_NEQUAL (5 << 8) -# define R300_ALPHA_TEST_PASS (7 << 8) -# define R300_ALPHA_TEST_OP_MASK (7 << 8) -# define R300_ALPHA_TEST_ENABLE (1 << 11) - -/* gap */ - -/* Fragment program parameters in 7.16 floating point */ -#define R300_PFS_PARAM_0_X 0x4C00 -#define R300_PFS_PARAM_0_Y 0x4C04 -#define R300_PFS_PARAM_0_Z 0x4C08 -#define R300_PFS_PARAM_0_W 0x4C0C -/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */ -#define R300_PFS_PARAM_31_X 0x4DF0 -#define R300_PFS_PARAM_31_Y 0x4DF4 -#define R300_PFS_PARAM_31_Z 0x4DF8 -#define R300_PFS_PARAM_31_W 0x4DFC - -/* Notes: - * - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in - * the application - * - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND - * are set to the same - * function (both registers are always set up completely in any case) - * - Most blend flags are simply copied from R200 and not tested yet - */ -#define R300_RB3D_CBLEND 0x4E04 -#define R300_RB3D_ABLEND 0x4E08 -/* the following only appear in CBLEND */ -# define R300_BLEND_ENABLE (1 << 0) -# define R300_BLEND_UNKNOWN (3 << 1) -# define R300_BLEND_NO_SEPARATE (1 << 3) -/* the following are shared between CBLEND and ABLEND */ -# define R300_FCN_MASK (3 << 12) -# define R300_COMB_FCN_ADD_CLAMP (0 << 12) -# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12) -# define R300_COMB_FCN_SUB_CLAMP (2 << 12) -# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12) -# define R300_COMB_FCN_MIN (4 << 12) -# define R300_COMB_FCN_MAX (5 << 12) -# define R300_COMB_FCN_RSUB_CLAMP (6 << 12) -# define R300_COMB_FCN_RSUB_NOCLAMP (7 << 12) -# define R300_BLEND_GL_ZERO (32) -# define R300_BLEND_GL_ONE (33) -# define R300_BLEND_GL_SRC_COLOR (34) -# define R300_BLEND_GL_ONE_MINUS_SRC_COLOR (35) -# define R300_BLEND_GL_DST_COLOR (36) -# define R300_BLEND_GL_ONE_MINUS_DST_COLOR (37) -# define R300_BLEND_GL_SRC_ALPHA (38) -# define R300_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) -# define R300_BLEND_GL_DST_ALPHA (40) -# define R300_BLEND_GL_ONE_MINUS_DST_ALPHA (41) -# define R300_BLEND_GL_SRC_ALPHA_SATURATE (42) -# define R300_BLEND_GL_CONST_COLOR (43) -# define R300_BLEND_GL_ONE_MINUS_CONST_COLOR (44) -# define R300_BLEND_GL_CONST_ALPHA (45) -# define R300_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) -# define R300_BLEND_MASK (63) -# define R300_SRC_BLEND_SHIFT (16) -# define R300_DST_BLEND_SHIFT (24) -#define R300_RB3D_BLEND_COLOR 0x4E10 -#define R300_RB3D_COLORMASK 0x4E0C -# define R300_COLORMASK0_B (1<<0) -# define R300_COLORMASK0_G (1<<1) -# define R300_COLORMASK0_R (1<<2) -# define R300_COLORMASK0_A (1<<3) - -/* gap */ - -#define R300_RB3D_COLOROFFSET0 0x4E28 -# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ -#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ -#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ -#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */ - -/* gap */ - -/* Bit 16: Larger tiles - * Bit 17: 4x2 tiles - * Bit 18: Extremely weird tile like, but some pixels duplicated? - */ -#define R300_RB3D_COLORPITCH0 0x4E38 -# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ -# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ -# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ -# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ -# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ -# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ -# define R300_COLOR_FORMAT_RGB565 (2 << 22) -# define R300_COLOR_FORMAT_ARGB8888 (3 << 22) -#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */ -#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ -#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ - -/* gap */ - -/* Guess by Vladimir. - * Set to 0A before 3D operations, set to 02 afterwards. - */ -/*#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C*/ -# define R300_RB3D_DSTCACHE_UNKNOWN_02 0x00000002 -# define R300_RB3D_DSTCACHE_UNKNOWN_0A 0x0000000A - -/* gap */ -/* There seems to be no "write only" setting, so use Z-test = ALWAYS - * for this. - * Bit (1<<8) is the "test" bit. so plain write is 6 - vd - */ -#define R300_ZB_CNTL 0x4F00 -# define R300_STENCIL_ENABLE (1 << 0) -# define R300_Z_ENABLE (1 << 1) -# define R300_Z_WRITE_ENABLE (1 << 2) -# define R300_Z_SIGNED_COMPARE (1 << 3) -# define R300_STENCIL_FRONT_BACK (1 << 4) - -#define R300_ZB_ZSTENCILCNTL 0x4f04 - /* functions */ -# define R300_ZS_NEVER 0 -# define R300_ZS_LESS 1 -# define R300_ZS_LEQUAL 2 -# define R300_ZS_EQUAL 3 -# define R300_ZS_GEQUAL 4 -# define R300_ZS_GREATER 5 -# define R300_ZS_NOTEQUAL 6 -# define R300_ZS_ALWAYS 7 -# define R300_ZS_MASK 7 - /* operations */ -# define R300_ZS_KEEP 0 -# define R300_ZS_ZERO 1 -# define R300_ZS_REPLACE 2 -# define R300_ZS_INCR 3 -# define R300_ZS_DECR 4 -# define R300_ZS_INVERT 5 -# define R300_ZS_INCR_WRAP 6 -# define R300_ZS_DECR_WRAP 7 -# define R300_Z_FUNC_SHIFT 0 - /* front and back refer to operations done for front - and back faces, i.e. separate stencil function support */ -# define R300_S_FRONT_FUNC_SHIFT 3 -# define R300_S_FRONT_SFAIL_OP_SHIFT 6 -# define R300_S_FRONT_ZPASS_OP_SHIFT 9 -# define R300_S_FRONT_ZFAIL_OP_SHIFT 12 -# define R300_S_BACK_FUNC_SHIFT 15 -# define R300_S_BACK_SFAIL_OP_SHIFT 18 -# define R300_S_BACK_ZPASS_OP_SHIFT 21 -# define R300_S_BACK_ZFAIL_OP_SHIFT 24 - -#define R300_ZB_STENCILREFMASK 0x4f08 -# define R300_STENCILREF_SHIFT 0 -# define R300_STENCILREF_MASK 0x000000ff -# define R300_STENCILMASK_SHIFT 8 -# define R300_STENCILMASK_MASK 0x0000ff00 -# define R300_STENCILWRITEMASK_SHIFT 16 -# define R300_STENCILWRITEMASK_MASK 0x00ff0000 - -/* gap */ - -#define R300_ZB_FORMAT 0x4f10 -# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0) -# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0) -# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0) -/* reserved up to (15 << 0) */ -# define R300_INVERT_13E3_LEADING_ONES (0 << 4) -# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4) - -#define R300_ZB_ZTOP 0x4F14 -# define R300_ZTOP_DISABLE (0 << 0) -# define R300_ZTOP_ENABLE (1 << 0) - -/* gap */ - -#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) - -#define R300_ZB_BW_CNTL 0x4f1c -# define R300_HIZ_DISABLE (0 << 0) -# define R300_HIZ_ENABLE (1 << 0) -# define R300_HIZ_MIN (0 << 1) -# define R300_HIZ_MAX (1 << 1) -# define R300_FAST_FILL_DISABLE (0 << 2) -# define R300_FAST_FILL_ENABLE (1 << 2) -# define R300_RD_COMP_DISABLE (0 << 3) -# define R300_RD_COMP_ENABLE (1 << 3) -# define R300_WR_COMP_DISABLE (0 << 4) -# define R300_WR_COMP_ENABLE (1 << 4) -# define R300_ZB_CB_CLEAR_RMW (0 << 5) -# define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5) -# define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6) -# define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6) - -# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7) -# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7) -# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8) -# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8) - -# define R500_BMASK_ENABLE (0 << 10) -# define R500_BMASK_DISABLE (1 << 10) -# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11) -# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11) -# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12) -# define R500_HIZ_FP_EXP_BITS_1 (1 << 12) -# define R500_HIZ_FP_EXP_BITS_2 (2 << 12) -# define R500_HIZ_FP_EXP_BITS_3 (3 << 12) -# define R500_HIZ_FP_EXP_BITS_4 (4 << 12) -# define R500_HIZ_FP_EXP_BITS_5 (5 << 12) -# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15) -# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15) -# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16) -# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16) -# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17) -# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17) -# define R500_PEQ_PACKING_DISABLE (0 << 18) -# define R500_PEQ_PACKING_ENABLE (1 << 18) -# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18) -# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18) - - -/* gap */ - -/* Z Buffer Address Offset. - * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles. - */ -#define R300_ZB_DEPTHOFFSET 0x4f20 - -/* Z Buffer Pitch and Endian Control */ -#define R300_ZB_DEPTHPITCH 0x4f24 -# define R300_DEPTHPITCH_MASK 0x00003FFC -# define R300_DEPTHMACROTILE_DISABLE (0 << 16) -# define R300_DEPTHMACROTILE_ENABLE (1 << 16) -# define R300_DEPTHMICROTILE_LINEAR (0 << 17) -# define R300_DEPTHMICROTILE_TILED (1 << 17) -# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17) -# define R300_DEPTHENDIAN_NO_SWAP (0 << 18) -# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18) -# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18) -# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18) - -/* Z Buffer Clear Value */ -#define R300_ZB_DEPTHCLEARVALUE 0x4f28 - -#define R300_ZB_ZMASK_OFFSET 0x4f30 -#define R300_ZB_ZMASK_PITCH 0x4f34 -#define R300_ZB_ZMASK_WRINDEX 0x4f38 -#define R300_ZB_ZMASK_DWORD 0x4f3c -#define R300_ZB_ZMASK_RDINDEX 0x4f40 - -/* Hierarchical Z Memory Offset */ -#define R300_ZB_HIZ_OFFSET 0x4f44 - -/* Hierarchical Z Write Index */ -#define R300_ZB_HIZ_WRINDEX 0x4f48 - -/* Hierarchical Z Data */ -#define R300_ZB_HIZ_DWORD 0x4f4c - -/* Hierarchical Z Read Index */ -#define R300_ZB_HIZ_RDINDEX 0x4f50 - -/* Hierarchical Z Pitch */ -#define R300_ZB_HIZ_PITCH 0x4f54 - -/* Z Buffer Z Pass Counter Data */ -#define R300_ZB_ZPASS_DATA 0x4f58 - -/* Z Buffer Z Pass Counter Address */ -#define R300_ZB_ZPASS_ADDR 0x4f5c - -/* Depth buffer X and Y coordinate offset */ -#define R300_ZB_DEPTHXY_OFFSET 0x4f60 -# define R300_DEPTHX_OFFSET_SHIFT 1 -# define R300_DEPTHX_OFFSET_MASK 0x000007FE -# define R300_DEPTHY_OFFSET_SHIFT 17 -# define R300_DEPTHY_OFFSET_MASK 0x07FE0000 - -/* Sets the fifo sizes */ -#define R500_ZB_FIFO_SIZE 0x4fd0 -# define R500_OP_FIFO_SIZE_FULL (0 << 0) -# define R500_OP_FIFO_SIZE_HALF (1 << 0) -# define R500_OP_FIFO_SIZE_QUATER (2 << 0) -# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0) - -/* Stencil Reference Value and Mask for backfacing quads */ -/* R300_ZB_STENCILREFMASK handles front face */ -#define R500_ZB_STENCILREFMASK_BF 0x4fd4 -# define R500_STENCILREF_SHIFT 0 -# define R500_STENCILREF_MASK 0x000000ff -# define R500_STENCILMASK_SHIFT 8 -# define R500_STENCILMASK_MASK 0x0000ff00 -# define R500_STENCILWRITEMASK_SHIFT 16 -# define R500_STENCILWRITEMASK_MASK 0x00ff0000 - -/* BEGIN: Vertex program instruction set */ - -/* Every instruction is four dwords long: - * DWORD 0: output and opcode - * DWORD 1: first argument - * DWORD 2: second argument - * DWORD 3: third argument - * - * Notes: - * - ABS r, a is implemented as MAX r, a, -a - * - MOV is implemented as ADD to zero - * - XPD is implemented as MUL + MAD - * - FLR is implemented as FRC + ADD - * - apparently, fglrx tries to schedule instructions so that there is at - * least one instruction between the write to a temporary and the first - * read from said temporary; however, violations of this scheduling are - * allowed - * - register indices seem to be unrelated with OpenGL aliasing to - * conventional state - * - only one attribute and one parameter can be loaded at a time; however, - * the same attribute/parameter can be used for more than one argument - * - the second software argument for POW is the third hardware argument - * (no idea why) - * - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2 - * - * There is some magic surrounding LIT: - * The single argument is replicated across all three inputs, but swizzled: - * First argument: xyzy - * Second argument: xyzx - * Third argument: xyzw - * Whenever the result is used later in the fragment program, fglrx forces - * x and w to be 1.0 in the input selection; I don't know whether this is - * strictly necessary - */ -#define R300_VPI_OUT_OP_DOT (1 << 0) -#define R300_VPI_OUT_OP_MUL (2 << 0) -#define R300_VPI_OUT_OP_ADD (3 << 0) -#define R300_VPI_OUT_OP_MAD (4 << 0) -#define R300_VPI_OUT_OP_DST (5 << 0) -#define R300_VPI_OUT_OP_FRC (6 << 0) -#define R300_VPI_OUT_OP_MAX (7 << 0) -#define R300_VPI_OUT_OP_MIN (8 << 0) -#define R300_VPI_OUT_OP_SGE (9 << 0) -#define R300_VPI_OUT_OP_SLT (10 << 0) - /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */ -#define R300_VPI_OUT_OP_UNK12 (12 << 0) -#define R300_VPI_OUT_OP_ARL (13 << 0) -#define R300_VPI_OUT_OP_EXP (65 << 0) -#define R300_VPI_OUT_OP_LOG (66 << 0) - /* Used in fog computations, scalar(scalar) */ -#define R300_VPI_OUT_OP_UNK67 (67 << 0) -#define R300_VPI_OUT_OP_LIT (68 << 0) -#define R300_VPI_OUT_OP_POW (69 << 0) -#define R300_VPI_OUT_OP_RCP (70 << 0) -#define R300_VPI_OUT_OP_RSQ (72 << 0) - /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */ -#define R300_VPI_OUT_OP_UNK73 (73 << 0) -#define R300_VPI_OUT_OP_EX2 (75 << 0) -#define R300_VPI_OUT_OP_LG2 (76 << 0) -#define R300_VPI_OUT_OP_MAD_2 (128 << 0) - /* all temps, vector(scalar, vector, vector) */ -#define R300_VPI_OUT_OP_UNK129 (129 << 0) - -#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8) -#define R300_VPI_OUT_REG_CLASS_ADDR (1 << 8) -#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8) -#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8) - -#define R300_VPI_OUT_REG_INDEX_SHIFT 13 - /* GUESS based on fglrx native limits */ -#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) - -#define R300_VPI_OUT_WRITE_X (1 << 20) -#define R300_VPI_OUT_WRITE_Y (1 << 21) -#define R300_VPI_OUT_WRITE_Z (1 << 22) -#define R300_VPI_OUT_WRITE_W (1 << 23) - -#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0) -#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0) -#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0) -#define R300_VPI_IN_REG_CLASS_NONE (9 << 0) -#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) - -#define R300_VPI_IN_REG_INDEX_SHIFT 5 - /* GUESS based on fglrx native limits */ -#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) - -/* The R300 can select components from the input register arbitrarily. - * Use the following constants, shifted by the component shift you - * want to select - */ -#define R300_VPI_IN_SELECT_X 0 -#define R300_VPI_IN_SELECT_Y 1 -#define R300_VPI_IN_SELECT_Z 2 -#define R300_VPI_IN_SELECT_W 3 -#define R300_VPI_IN_SELECT_ZERO 4 -#define R300_VPI_IN_SELECT_ONE 5 -#define R300_VPI_IN_SELECT_MASK 7 - -#define R300_VPI_IN_X_SHIFT 13 -#define R300_VPI_IN_Y_SHIFT 16 -#define R300_VPI_IN_Z_SHIFT 19 -#define R300_VPI_IN_W_SHIFT 22 - -#define R300_VPI_IN_NEG_X (1 << 25) -#define R300_VPI_IN_NEG_Y (1 << 26) -#define R300_VPI_IN_NEG_Z (1 << 27) -#define R300_VPI_IN_NEG_W (1 << 28) -/* END: Vertex program instruction set */ - -/* BEGIN: Packet 3 commands */ - -/* A primitive emission dword. */ -#define R300_PRIM_TYPE_NONE (0 << 0) -#define R300_PRIM_TYPE_POINT (1 << 0) -#define R300_PRIM_TYPE_LINE (2 << 0) -#define R300_PRIM_TYPE_LINE_STRIP (3 << 0) -#define R300_PRIM_TYPE_TRI_LIST (4 << 0) -#define R300_PRIM_TYPE_TRI_FAN (5 << 0) -#define R300_PRIM_TYPE_TRI_STRIP (6 << 0) -#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0) -#define R300_PRIM_TYPE_RECT_LIST (8 << 0) -#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) -#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) - /* GUESS (based on r200) */ -#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) -#define R300_PRIM_TYPE_LINE_LOOP (12 << 0) -#define R300_PRIM_TYPE_QUADS (13 << 0) -#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0) -#define R300_PRIM_TYPE_POLYGON (15 << 0) -#define R300_PRIM_TYPE_MASK 0xF -#define R300_PRIM_WALK_IND (1 << 4) -#define R300_PRIM_WALK_LIST (2 << 4) -#define R300_PRIM_WALK_RING (3 << 4) -#define R300_PRIM_WALK_MASK (3 << 4) - /* GUESS (based on r200) */ -#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) -#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) -#define R300_PRIM_NUM_VERTICES_SHIFT 16 -#define R300_PRIM_NUM_VERTICES_MASK 0xffff - -/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. - * Two parameter dwords: - * 0. The first parameter appears to be always 0 - * 1. The second parameter is a standard primitive emission dword. - */ -#define R300_PACKET3_3D_DRAW_VBUF 0x00002800 - -/* Specify the full set of vertex arrays as (address, stride). - * The first parameter is the number of vertex arrays specified. - * The rest of the command is a variable length list of blocks, where - * each block is three dwords long and specifies two arrays. - * The first dword of a block is split into two words, the lower significant - * word refers to the first array, the more significant word to the second - * array in the block. - * The low byte of each word contains the size of an array entry in dwords, - * the high byte contains the stride of the array. - * The second dword of a block contains the pointer to the first array, - * the third dword of a block contains the pointer to the second array. - * Note that if the total number of arrays is odd, the third dword of - * the last block is omitted. - */ -#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 - -#define R300_PACKET3_INDX_BUFFER 0x00003300 -# define R300_EB_UNK1_SHIFT 24 -# define R300_EB_UNK1 (0x80<<24) -# define R300_EB_UNK2 0x0810 -#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400 -#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 - -/* END: Packet 3 commands */ - - -/* Color formats for 2d packets - */ -#define R300_CP_COLOR_FORMAT_CI8 2 -#define R300_CP_COLOR_FORMAT_ARGB1555 3 -#define R300_CP_COLOR_FORMAT_RGB565 4 -#define R300_CP_COLOR_FORMAT_ARGB8888 6 -#define R300_CP_COLOR_FORMAT_RGB332 7 -#define R300_CP_COLOR_FORMAT_RGB8 9 -#define R300_CP_COLOR_FORMAT_ARGB4444 15 - -/* - * CP type-3 packets - */ -#define R300_CP_CMD_BITBLT_MULTI 0xC0009B00 - -#define R500_VAP_INDEX_OFFSET 0x208c - -#define R500_GA_US_VECTOR_INDEX 0x4250 -#define R500_GA_US_VECTOR_DATA 0x4254 - -#define R500_RS_IP_0 0x4074 -#define R500_RS_INST_0 0x4320 - -#define R500_US_CONFIG 0x4600 - -#define R500_US_FC_CTRL 0x4624 -#define R500_US_CODE_ADDR 0x4630 - -#define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0 -#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8 - -#endif /* _R300_REG_H */ diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c deleted file mode 100644 index e53158f..0000000 --- a/drivers/char/drm/radeon_cp.c +++ /dev/null @@ -1,1773 +0,0 @@ -/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */ -/* - * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * Copyright 2007 Advanced Micro Devices, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kevin E. Martin - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" -#include "r300_reg.h" - -#include "radeon_microcode.h" - -#define RADEON_FIFO_DEBUG 0 - -static int radeon_do_cleanup_cp(struct drm_device * dev); - -static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff)); - ret = RADEON_READ(R520_MC_IND_DATA); - RADEON_WRITE(R520_MC_IND_INDEX, 0); - return ret; -} - -static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff); - ret = RADEON_READ(RS480_NB_MC_DATA); - RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); - return ret; -} - -static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); - ret = RADEON_READ(RS690_MC_DATA); - RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK); - return ret; -} - -static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) - return RS690_READ_MCIND(dev_priv, addr); - else - return RS480_READ_MCIND(dev_priv, addr); -} - -u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) -{ - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) - return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) - return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) - return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); - else - return RADEON_READ(RADEON_MC_FB_LOCATION); -} - -static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) -{ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) - R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) - RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) - R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); - else - RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); -} - -static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) -{ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) - R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) - RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) - R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); - else - RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); -} - -static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) -{ - u32 agp_base_hi = upper_32_bits(agp_base); - u32 agp_base_lo = agp_base & 0xffffffff; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { - R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); - R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { - RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); - RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { - R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); - R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) { - RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); - RADEON_WRITE(RS480_AGP_BASE_2, 0); - } else { - RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200) - RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi); - } -} - -static int RADEON_READ_PLL(struct drm_device * dev, int addr) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); - return RADEON_READ(RADEON_CLOCK_CNTL_DATA); -} - -static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) -{ - RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); - return RADEON_READ(RADEON_PCIE_DATA); -} - -#if RADEON_FIFO_DEBUG -static void radeon_status(drm_radeon_private_t * dev_priv) -{ - printk("%s:\n", __func__); - printk("RBBM_STATUS = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); - printk("CP_RB_RTPR = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR)); - printk("CP_RB_WTPR = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR)); - printk("AIC_CNTL = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_CNTL)); - printk("AIC_STAT = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_STAT)); - printk("AIC_PT_BASE = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE)); - printk("TLB_ADDR = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR)); - printk("TLB_DATA = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA)); -} -#endif - -/* ================================================================ - * Engine, FIFO control - */ - -static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) -{ - u32 tmp; - int i; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { - tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB3D_DC_FLUSH_ALL; - RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) - & RADEON_RB3D_DC_BUSY)) { - return 0; - } - DRM_UDELAY(1); - } - } else { - /* 3D */ - tmp = RADEON_READ(R300_RB3D_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB3D_DC_FLUSH_ALL; - RADEON_WRITE(R300_RB3D_DSTCACHE_CTLSTAT, tmp); - - /* 2D */ - tmp = RADEON_READ(R300_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB3D_DC_FLUSH_ALL; - RADEON_WRITE(R300_DSTCACHE_CTLSTAT, tmp); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(R300_DSTCACHE_CTLSTAT) - & RADEON_RB3D_DC_BUSY)) { - return 0; - } - DRM_UDELAY(1); - } - } - -#if RADEON_FIFO_DEBUG - DRM_ERROR("failed!\n"); - radeon_status(dev_priv); -#endif - return -EBUSY; -} - -static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) -{ - int i; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - int slots = (RADEON_READ(RADEON_RBBM_STATUS) - & RADEON_RBBM_FIFOCNT_MASK); - if (slots >= entries) - return 0; - DRM_UDELAY(1); - } - -#if RADEON_FIFO_DEBUG - DRM_ERROR("failed!\n"); - radeon_status(dev_priv); -#endif - return -EBUSY; -} - -static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) -{ - int i, ret; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - ret = radeon_do_wait_for_fifo(dev_priv, 64); - if (ret) - return ret; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RBBM_STATUS) - & RADEON_RBBM_ACTIVE)) { - radeon_do_pixcache_flush(dev_priv); - return 0; - } - DRM_UDELAY(1); - } - -#if RADEON_FIFO_DEBUG - DRM_ERROR("failed!\n"); - radeon_status(dev_priv); -#endif - return -EBUSY; -} - -static void radeon_init_pipes(drm_radeon_private_t *dev_priv) -{ - uint32_t gb_tile_config, gb_pipe_sel = 0; - - /* RS4xx/RS6xx/R4xx/R5xx */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { - gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); - dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; - } else { - /* R3xx */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { - dev_priv->num_gb_pipes = 2; - } else { - /* R3Vxx */ - dev_priv->num_gb_pipes = 1; - } - } - DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes); - - gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/); - - switch (dev_priv->num_gb_pipes) { - case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; - case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; - case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; - default: - case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); - RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); - } - RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); - radeon_do_wait_for_idle(dev_priv); - RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); - RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) | - R300_DC_AUTOFLUSH_ENABLE | - R300_DC_DC_DISABLE_IGNORE_PE)); - - -} - -/* ================================================================ - * CP control, initialization - */ - -/* Load the microcode for the CP */ -static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) -{ - int i; - DRM_DEBUG("\n"); - - radeon_do_wait_for_idle(dev_priv); - - RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { - DRM_INFO("Loading R100 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - R100_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - R100_cp_microcode[i][0]); - } - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { - DRM_INFO("Loading R200 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - R200_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - R200_cp_microcode[i][0]); - } - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - DRM_INFO("Loading R300 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - R300_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - R300_cp_microcode[i][0]); - } - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { - DRM_INFO("Loading R400 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - R420_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - R420_cp_microcode[i][0]); - } - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { - DRM_INFO("Loading RS690 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - RS690_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - RS690_cp_microcode[i][0]); - } - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R580) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { - DRM_INFO("Loading R500 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - R520_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - R520_cp_microcode[i][0]); - } - } -} - -/* Flush any pending commands to the CP. This should only be used just - * prior to a wait for idle, as it informs the engine that the command - * stream is ending. - */ -static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv) -{ - DRM_DEBUG("\n"); -#if 0 - u32 tmp; - - tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); - RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); -#endif -} - -/* Wait for the CP to go idle. - */ -int radeon_do_cp_idle(drm_radeon_private_t * dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(6); - - RADEON_PURGE_CACHE(); - RADEON_PURGE_ZCACHE(); - RADEON_WAIT_UNTIL_IDLE(); - - ADVANCE_RING(); - COMMIT_RING(); - - return radeon_do_wait_for_idle(dev_priv); -} - -/* Start the Command Processor. - */ -static void radeon_do_cp_start(drm_radeon_private_t * dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - radeon_do_wait_for_idle(dev_priv); - - RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode); - - dev_priv->cp_running = 1; - - BEGIN_RING(6); - - RADEON_PURGE_CACHE(); - RADEON_PURGE_ZCACHE(); - RADEON_WAIT_UNTIL_IDLE(); - - ADVANCE_RING(); - COMMIT_RING(); -} - -/* Reset the Command Processor. This will not flush any pending - * commands, so you must wait for the CP command stream to complete - * before calling this routine. - */ -static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv) -{ - u32 cur_read_ptr; - DRM_DEBUG("\n"); - - cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); - RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); - SET_RING_HEAD(dev_priv, cur_read_ptr); - dev_priv->ring.tail = cur_read_ptr; -} - -/* Stop the Command Processor. This will not flush any pending - * commands, so you must flush the command stream and wait for the CP - * to go idle before calling this routine. - */ -static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) -{ - DRM_DEBUG("\n"); - - RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); - - dev_priv->cp_running = 0; -} - -/* Reset the engine. This will stop the CP if it is running. - */ -static int radeon_do_engine_reset(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 clock_cntl_index = 0, mclk_cntl = 0, rbbm_soft_reset; - DRM_DEBUG("\n"); - - radeon_do_pixcache_flush(dev_priv); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - /* may need something similar for newer chips */ - clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); - mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); - - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | - RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC | - RADEON_FORCEON_AIC)); - } - - rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); - - RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | - RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB)); - RADEON_READ(RADEON_RBBM_SOFT_RESET); - RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & - ~(RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB))); - RADEON_READ(RADEON_RBBM_SOFT_RESET); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); - RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); - RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); - } - - /* setup the raster pipes */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) - radeon_init_pipes(dev_priv); - - /* Reset the CP ring */ - radeon_do_cp_reset(dev_priv); - - /* The CP is no longer running after an engine reset */ - dev_priv->cp_running = 0; - - /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset(dev); - - return 0; -} - -static void radeon_cp_init_ring_buffer(struct drm_device * dev, - drm_radeon_private_t * dev_priv) -{ - u32 ring_start, cur_read_ptr; - u32 tmp; - - /* Initialize the memory controller. With new memory map, the fb location - * is not changed, it should have been properly initialized already. Part - * of the problem is that the code below is bogus, assuming the GART is - * always appended to the fb which is not necessarily the case - */ - if (!dev_priv->new_memmap) - radeon_write_fb_location(dev_priv, - ((dev_priv->gart_vm_start - 1) & 0xffff0000) - | (dev_priv->fb_location >> 16)); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - radeon_write_agp_base(dev_priv, dev->agp->base); - - radeon_write_agp_location(dev_priv, - (((dev_priv->gart_vm_start - 1 + - dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); - - ring_start = (dev_priv->cp_ring->offset - - dev->agp->base - + dev_priv->gart_vm_start); - } else -#endif - ring_start = (dev_priv->cp_ring->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); - - /* Set the write pointer delay */ - RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0); - - /* Initialize the ring buffer's read and write pointers */ - cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); - RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); - SET_RING_HEAD(dev_priv, cur_read_ptr); - dev_priv->ring.tail = cur_read_ptr; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset - - dev->agp->base + dev_priv->gart_vm_start); - } else -#endif - { - struct drm_sg_mem *entry = dev->sg; - unsigned long tmp_ofs, page_ofs; - - tmp_ofs = dev_priv->ring_rptr->offset - - (unsigned long)dev->sg->virtual; - page_ofs = tmp_ofs >> PAGE_SHIFT; - - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", - (unsigned long)entry->busaddr[page_ofs], - entry->handle + tmp_ofs); - } - - /* Set ring buffer size */ -#ifdef __BIG_ENDIAN - RADEON_WRITE(RADEON_CP_RB_CNTL, - RADEON_BUF_SWAP_32BIT | - (dev_priv->ring.fetch_size_l2ow << 18) | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(RADEON_CP_RB_CNTL, - (dev_priv->ring.fetch_size_l2ow << 18) | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - - /* Initialize the scratch register pointer. This will cause - * the scratch register values to be written out to memory - * whenever they are updated. - * - * We simply put this behind the ring read pointer, this works - * with PCI GART as well as (whatever kind of) AGP GART - */ - RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) - + RADEON_SCRATCH_REG_OFFSET); - - dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle + - (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); - - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); - - /* Turn on bus mastering */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - - dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; - RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); - - dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; - RADEON_WRITE(RADEON_LAST_DISPATCH_REG, - dev_priv->sarea_priv->last_dispatch); - - dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; - RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); - - radeon_do_wait_for_idle(dev_priv); - - /* Sync everything up */ - RADEON_WRITE(RADEON_ISYNC_CNTL, - (RADEON_ISYNC_ANY2D_IDLE3D | - RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI)); - -} - -static void radeon_test_writeback(drm_radeon_private_t * dev_priv) -{ - u32 tmp; - - /* Writeback doesn't seem to work everywhere, test it here and possibly - * enable it if it appears to work - */ - DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); - RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); - - for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == - 0xdeadbeef) - break; - DRM_UDELAY(1); - } - - if (tmp < dev_priv->usec_timeout) { - dev_priv->writeback_works = 1; - DRM_INFO("writeback test succeeded in %d usecs\n", tmp); - } else { - dev_priv->writeback_works = 0; - DRM_INFO("writeback test failed\n"); - } - if (radeon_no_wb == 1) { - dev_priv->writeback_works = 0; - DRM_INFO("writeback forced off\n"); - } - - if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | - RADEON_RB_NO_UPDATE); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); - } -} - -/* Enable or disable IGP GART on the chip */ -static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) -{ - u32 temp; - - if (on) { - DRM_DEBUG("programming igp gart %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - - temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) - IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | - RS690_BLOCK_GFX_D3_EN)); - else - IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); - - IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | - RS480_VA_SIZE_32MB)); - - temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID); - IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN | - RS480_TLB_ENABLE | - RS480_GTW_LAC_EN | - RS480_1LEVEL_GART)); - - temp = dev_priv->gart_info.bus_addr & 0xfffff000; - temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4; - IGP_WRITE_MCIND(RS480_GART_BASE, temp); - - temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL); - IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) | - RS480_REQ_TYPE_SNOOP_DIS)); - - radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start); - - dev_priv->gart_size = 32*1024*1024; - temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & - 0xffff0000) | (dev_priv->gart_vm_start >> 16)); - - radeon_write_agp_location(dev_priv, temp); - - temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); - IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | - RS480_VA_SIZE_32MB)); - - do { - temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); - if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) - break; - DRM_UDELAY(1); - } while (1); - - IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, - RS480_GART_CACHE_INVALIDATE); - - do { - temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); - if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) - break; - DRM_UDELAY(1); - } while (1); - - IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); - } else { - IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0); - } -} - -static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) -{ - u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); - if (on) { - - DRM_DEBUG("programming pcie %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, - dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, - dev_priv->gart_info.bus_addr); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, - dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, - dev_priv->gart_vm_start + - dev_priv->gart_size - 1); - - radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ - - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, - RADEON_PCIE_TX_GART_EN); - } else { - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, - tmp & ~RADEON_PCIE_TX_GART_EN); - } -} - -/* Enable or disable PCI GART on the chip */ -static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) -{ - u32 tmp; - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - (dev_priv->flags & RADEON_IS_IGPGART)) { - radeon_set_igpgart(dev_priv, on); - return; - } - - if (dev_priv->flags & RADEON_IS_PCIE) { - radeon_set_pciegart(dev_priv, on); - return; - } - - tmp = RADEON_READ(RADEON_AIC_CNTL); - - if (on) { - RADEON_WRITE(RADEON_AIC_CNTL, - tmp | RADEON_PCIGART_TRANSLATE_EN); - - /* set PCI GART page-table base address - */ - RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); - - /* set address range for PCI address translate - */ - RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start); - RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start - + dev_priv->gart_size - 1); - - /* Turn off AGP aperture -- is this required for PCI GART? - */ - radeon_write_agp_location(dev_priv, 0xffffffc0); - RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ - } else { - RADEON_WRITE(RADEON_AIC_CNTL, - tmp & ~RADEON_PCIGART_TRANSLATE_EN); - } -} - -static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - - /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { - DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; - } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) { - DRM_DEBUG("Restoring AGP flag\n"); - dev_priv->flags |= RADEON_IS_AGP; - } - - if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { - DRM_ERROR("PCI GART memory not allocated!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->usec_timeout = init->usec_timeout; - if (dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { - DRM_DEBUG("TIMEOUT problem!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - /* Enable vblank on CRTC1 for older X servers - */ - dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; - - switch(init->func) { - case RADEON_INIT_R200_CP: - dev_priv->microcode_version = UCODE_R200; - break; - case RADEON_INIT_R300_CP: - dev_priv->microcode_version = UCODE_R300; - break; - default: - dev_priv->microcode_version = UCODE_R100; - } - - dev_priv->do_boxes = 0; - dev_priv->cp_mode = init->cp_mode; - - /* We don't support anything other than bus-mastering ring mode, - * but the ring can be in either AGP or PCI space for the ring - * read pointer. - */ - if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && - (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { - DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - switch (init->fb_bpp) { - case 16: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; - break; - case 32: - default: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; - break; - } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - switch (init->depth_bpp) { - case 16: - dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; - break; - case 32: - default: - dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; - break; - } - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - - /* Hardware state for depth clears. Remove this if/when we no - * longer clear the depth buffer with a 3D rectangle. Hard-code - * all values to prevent unwanted 3D state from slipping through - * and screwing with the clear operation. - */ - dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | - (dev_priv->color_fmt << 10) | - (dev_priv->microcode_version == - UCODE_R100 ? RADEON_ZBLOCK16 : 0)); - - dev_priv->depth_clear.rb3d_zstencilcntl = - (dev_priv->depth_fmt | - RADEON_Z_TEST_ALWAYS | - RADEON_STENCIL_TEST_ALWAYS | - RADEON_STENCIL_S_FAIL_REPLACE | - RADEON_STENCIL_ZPASS_REPLACE | - RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE); - - dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | - RADEON_BFACE_SOLID | - RADEON_FFACE_SOLID | - RADEON_FLAT_SHADE_VTX_LAST | - RADEON_DIFFUSE_SHADE_FLAT | - RADEON_ALPHA_SHADE_FLAT | - RADEON_SPECULAR_SHADE_FLAT | - RADEON_FOG_SHADE_FLAT | - RADEON_VTX_PIX_CENTER_OGL | - RADEON_ROUND_MODE_TRUNC | - RADEON_ROUND_PREC_8TH_PIX); - - - dev_priv->ring_offset = init->ring_offset; - dev_priv->ring_rptr_offset = init->ring_rptr_offset; - dev_priv->buffers_offset = init->buffers_offset; - dev_priv->gart_textures_offset = init->gart_textures_offset; - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->cp_ring) { - DRM_ERROR("could not find cp ring region!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if (!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find dma buffer region!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->gart_textures_offset) { - dev_priv->gart_textures = - drm_core_findmap(dev, init->gart_textures_offset); - if (!dev_priv->gart_textures) { - DRM_ERROR("could not find GART texture region!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - } - - dev_priv->sarea_priv = - (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - 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) { - DRM_ERROR("could not find ioremap agp regions!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - } else -#endif - { - dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; - dev_priv->ring_rptr->handle = - (void *)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = - (void *)dev->agp_buffer_map->offset; - - DRM_DEBUG("dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle); - DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle); - DRM_DEBUG("dev->agp_buffer_map->handle %p\n", - dev->agp_buffer_map->handle); - } - - dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; - dev_priv->fb_size = - ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) - - dev_priv->fb_location; - - dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | - ((dev_priv->front_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | - ((dev_priv->back_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | - ((dev_priv->depth_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->gart_size = init->gart_size; - - /* New let's set the memory map ... */ - if (dev_priv->new_memmap) { - u32 base = 0; - - DRM_INFO("Setting GART location based on new memory map\n"); - - /* If using AGP, try to locate the AGP aperture at the same - * location in the card and on the bus, though we have to - * align it down. - */ -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - base = dev->agp->base; - /* Check if valid */ - if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && - base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { - DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", - dev->agp->base); - base = 0; - } - } -#endif - /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ - if (base == 0) { - base = dev_priv->fb_location + dev_priv->fb_size; - if (base < dev_priv->fb_location || - ((base + dev_priv->gart_size) & 0xfffffffful) < base) - base = dev_priv->fb_location - - dev_priv->gart_size; - } - dev_priv->gart_vm_start = base & 0xffc00000u; - if (dev_priv->gart_vm_start != base) - DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", - base, dev_priv->gart_vm_start); - } else { - DRM_INFO("Setting GART location based on old memory map\n"); - dev_priv->gart_vm_start = dev_priv->fb_location + - RADEON_READ(RADEON_CONFIG_APER_SIZE); - } - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->agp->base - + dev_priv->gart_vm_start); - else -#endif - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); - DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start); - DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n", - dev_priv->gart_buffers_offset); - - dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; - dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle - + init->ring_size / sizeof(u32)); - dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - - dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; - dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8); - - dev_priv->ring.fetch_size = /* init->fetch_size */ 32; - dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; - - dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); - } else -#endif - { - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); - /* if we have an offset set from userspace */ - if (dev_priv->pcigart_offset_set) { - dev_priv->gart_info.bus_addr = - dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->pcigart_offset + dev_priv->fb_aper_offset; - dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; - - drm_core_ioremap(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; - - if (dev_priv->flags & RADEON_IS_PCIE) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - dev_priv->gart_info.gart_table_location = - DRM_ATI_GART_FB; - - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", - dev_priv->gart_info.addr, - dev_priv->pcigart_offset); - } else { - if (dev_priv->flags & RADEON_IS_IGPGART) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - dev_priv->gart_info.gart_table_location = - DRM_ATI_GART_MAIN; - dev_priv->gart_info.addr = NULL; - dev_priv->gart_info.bus_addr = 0; - if (dev_priv->flags & RADEON_IS_PCIE) { - DRM_ERROR - ("Cannot use PCI Express without GART in FB memory\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - } - - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { - DRM_ERROR("failed to init PCI GART!\n"); - radeon_do_cleanup_cp(dev); - return -ENOMEM; - } - - /* Turn on PCI GART */ - radeon_set_pcigart(dev_priv, 1); - } - - radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv); - - dev_priv->last_buf = 0; - - radeon_do_engine_reset(dev); - radeon_test_writeback(dev_priv); - - return 0; -} - -static int radeon_do_cleanup_cp(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - if (dev_priv->cp_ring != NULL) { - drm_core_ioremapfree(dev_priv->cp_ring, dev); - dev_priv->cp_ring = NULL; - } - if (dev_priv->ring_rptr != NULL) { - drm_core_ioremapfree(dev_priv->ring_rptr, dev); - dev_priv->ring_rptr = NULL; - } - if (dev->agp_buffer_map != NULL) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } - } else -#endif - { - - if (dev_priv->gart_info.bus_addr) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); - } - - if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) - { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = 0; - } - } - /* only clear to the start of flags */ - memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); - - return 0; -} - -/* This code will reinit the Radeon CP hardware after a resume from disc. - * AFAIK, it would be very difficult to pickle the state at suspend time, so - * here we make sure that all Radeon hardware initialisation is re-done without - * affecting running applications. - * - * Charl P. Botha - */ -static int radeon_do_resume_cp(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (!dev_priv) { - DRM_ERROR("Called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("Starting radeon_do_resume_cp()\n"); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); - } else -#endif - { - /* Turn on PCI GART */ - radeon_set_pcigart(dev_priv, 1); - } - - radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv); - - radeon_do_engine_reset(dev); - radeon_enable_interrupt(dev); - - DRM_DEBUG("radeon_do_resume_cp() complete\n"); - - return 0; -} - -int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_init_t *init = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (init->func == RADEON_INIT_R300_CP) - r300_init_reg_flags(dev); - - switch (init->func) { - case RADEON_INIT_CP: - case RADEON_INIT_R200_CP: - case RADEON_INIT_R300_CP: - return radeon_do_init_cp(dev, init); - case RADEON_CLEANUP_CP: - return radeon_do_cleanup_cp(dev); - } - - return -EINVAL; -} - -int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (dev_priv->cp_running) { - DRM_DEBUG("while CP running\n"); - return 0; - } - if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) { - DRM_DEBUG("called with bogus CP mode (%d)\n", - dev_priv->cp_mode); - return 0; - } - - radeon_do_cp_start(dev_priv); - - return 0; -} - -/* Stop the CP. The engine must have been idled before calling this - * routine. - */ -int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_cp_stop_t *stop = data; - int ret; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv->cp_running) - return 0; - - /* Flush any pending CP commands. This ensures any outstanding - * commands are exectuted by the engine before we turn it off. - */ - if (stop->flush) { - radeon_do_cp_flush(dev_priv); - } - - /* If we fail to make the engine go idle, we return an error - * code so that the DRM ioctl wrapper can try again. - */ - if (stop->idle) { - ret = radeon_do_cp_idle(dev_priv); - if (ret) - return ret; - } - - /* Finally, we can turn off the CP. If the engine isn't idle, - * we will get some dropped triangles as they won't be fully - * rendered before the CP is shut down. - */ - radeon_do_cp_stop(dev_priv); - - /* Reset the engine */ - radeon_do_engine_reset(dev); - - return 0; -} - -void radeon_do_release(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int i, ret; - - if (dev_priv) { - if (dev_priv->cp_running) { - /* Stop the cp */ - while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); -#ifdef __linux__ - schedule(); -#else - tsleep(&ret, PZERO, "rdnrel", 1); -#endif - } - radeon_do_cp_stop(dev_priv); - radeon_do_engine_reset(dev); - } - - /* Disable *all* interrupts */ - if (dev_priv->mmio) /* remove this after permanent addmaps */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - - if (dev_priv->mmio) { /* remove all surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + - 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + - 16 * i, 0); - } - } - - /* Free memory heap structures */ - radeon_mem_takedown(&(dev_priv->gart_heap)); - radeon_mem_takedown(&(dev_priv->fb_heap)); - - /* deallocate kernel resources */ - radeon_do_cleanup_cp(dev); - } -} - -/* Just reset the CP ring. Called as part of an X Server engine reset. - */ -int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_DEBUG("called before init done\n"); - return -EINVAL; - } - - radeon_do_cp_reset(dev_priv); - - /* The CP is no longer running after an engine reset */ - dev_priv->cp_running = 0; - - return 0; -} - -int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return radeon_do_cp_idle(dev_priv); -} - -/* Added by Charl P. Botha to call radeon_do_resume_cp(). - */ -int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - - return radeon_do_resume_cp(dev); -} - -int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return radeon_do_engine_reset(dev); -} - -/* ================================================================ - * Fullscreen mode - */ - -/* KW: Deprecated to say the least: - */ -int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - return 0; -} - -/* ================================================================ - * Freelist management - */ - -/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through - * bufs until freelist code is used. Note this hides a problem with - * the scratch register * (used to keep track of last buffer - * completed) being written to before * the last buffer has actually - * completed rendering. - * - * KW: It's also a good way to find free buffers quickly. - * - * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't - * sleep. However, bugs in older versions of radeon_accel.c mean that - * we essentially have to do this, else old clients will break. - * - * However, it does leave open a potential deadlock where all the - * buffers are held by other clients, which can't release them because - * they can't get the lock. - */ - -struct drm_buf *radeon_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv; - struct drm_buf *buf; - int i, t; - int start; - - if (++dev_priv->last_buf >= dma->buf_count) - dev_priv->last_buf = 0; - - start = dev_priv->last_buf; - - for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = GET_SCRATCH(1); - DRM_DEBUG("done_age = %d\n", done_age); - for (i = start; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if (buf->file_priv == NULL || (buf->pending && - buf_priv->age <= - done_age)) { - dev_priv->stats.requested_bufs++; - buf->pending = 0; - return buf; - } - start = 0; - } - - if (t) { - DRM_UDELAY(1); - dev_priv->stats.freelist_loops++; - } - } - - DRM_DEBUG("returning NULL!\n"); - return NULL; -} - -#if 0 -struct drm_buf *radeon_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv; - struct drm_buf *buf; - int i, t; - int start; - u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); - - if (++dev_priv->last_buf >= dma->buf_count) - dev_priv->last_buf = 0; - - start = dev_priv->last_buf; - dev_priv->stats.freelist_loops++; - - for (t = 0; t < 2; t++) { - for (i = start; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if (buf->file_priv == 0 || (buf->pending && - buf_priv->age <= - done_age)) { - dev_priv->stats.requested_bufs++; - buf->pending = 0; - return buf; - } - } - start = 0; - } - - return NULL; -} -#endif - -void radeon_freelist_reset(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_radeon_private_t *dev_priv = dev->dev_private; - int i; - - dev_priv->last_buf = 0; - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->age = 0; - } -} - -/* ================================================================ - * CP command submission - */ - -int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) -{ - drm_radeon_ring_buffer_t *ring = &dev_priv->ring; - int i; - u32 last_head = GET_RING_HEAD(dev_priv); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - u32 head = GET_RING_HEAD(dev_priv); - - ring->space = (head - ring->tail) * sizeof(u32); - if (ring->space <= 0) - ring->space += ring->size; - if (ring->space > n) - return 0; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if (head != last_head) - i = 0; - last_head = head; - - DRM_UDELAY(1); - } - - /* FIXME: This return value is ignored in the BEGIN_RING macro! */ -#if RADEON_FIFO_DEBUG - radeon_status(dev_priv); - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -static int radeon_cp_get_buffers(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_dma * d) -{ - int i; - struct drm_buf *buf; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = radeon_freelist_get(dev); - if (!buf) - return -EBUSY; /* NOTE: broken client */ - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, - sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, - sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int ret = 0; - struct drm_dma *d = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - d->granted_count = 0; - - if (d->request_count) { - ret = radeon_cp_get_buffers(dev, file_priv, d); - } - - return ret; -} - -int radeon_driver_load(struct drm_device *dev, unsigned long flags) -{ - drm_radeon_private_t *dev_priv; - int ret = 0; - - dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - - memset(dev_priv, 0, sizeof(drm_radeon_private_t)); - dev->dev_private = (void *)dev_priv; - dev_priv->flags = flags; - - switch (flags & RADEON_FAMILY_MASK) { - case CHIP_R100: - case CHIP_RV200: - case CHIP_R200: - case CHIP_R300: - case CHIP_R350: - case CHIP_R420: - case CHIP_RV410: - case CHIP_RV515: - case CHIP_R520: - case CHIP_RV570: - case CHIP_R580: - dev_priv->flags |= RADEON_HAS_HIERZ; - break; - default: - /* all other chips have no hierarchical z buffer */ - break; - } - - if (drm_device_is_agp(dev)) - dev_priv->flags |= RADEON_IS_AGP; - else if (drm_device_is_pcie(dev)) - dev_priv->flags |= RADEON_IS_PCIE; - else - dev_priv->flags |= RADEON_IS_PCI; - - DRM_DEBUG("%s card detected\n", - ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); - return ret; -} - -/* Create mappings for registers and framebuffer so userland doesn't necessarily - * have to find them. - */ -int radeon_driver_firstopen(struct drm_device *dev) -{ - int ret; - drm_local_map_t *map; - drm_radeon_private_t *dev_priv = dev->dev_private; - - dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - - ret = drm_addmap(dev, drm_get_resource_start(dev, 2), - drm_get_resource_len(dev, 2), _DRM_REGISTERS, - _DRM_READ_ONLY, &dev_priv->mmio); - if (ret != 0) - return ret; - - dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); - ret = drm_addmap(dev, dev_priv->fb_aper_offset, - drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING, &map); - if (ret != 0) - return ret; - - return 0; -} - -int radeon_driver_unload(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); - - dev->dev_private = NULL; - return 0; -} diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h deleted file mode 100644 index 73ff51f..0000000 --- a/drivers/char/drm/radeon_drm.h +++ /dev/null @@ -1,749 +0,0 @@ -/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*- - * - * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kevin E. Martin - * Gareth Hughes - * Keith Whitwell - */ - -#ifndef __RADEON_DRM_H__ -#define __RADEON_DRM_H__ - -/* WARNING: If you change any of these defines, make sure to change the - * defines in the X server file (radeon_sarea.h) - */ -#ifndef __RADEON_SAREA_DEFINES__ -#define __RADEON_SAREA_DEFINES__ - -/* Old style state flags, required for sarea interface (1.1 and 1.2 - * clears) and 1.2 drm_vertex2 ioctl. - */ -#define RADEON_UPLOAD_CONTEXT 0x00000001 -#define RADEON_UPLOAD_VERTFMT 0x00000002 -#define RADEON_UPLOAD_LINE 0x00000004 -#define RADEON_UPLOAD_BUMPMAP 0x00000008 -#define RADEON_UPLOAD_MASKS 0x00000010 -#define RADEON_UPLOAD_VIEWPORT 0x00000020 -#define RADEON_UPLOAD_SETUP 0x00000040 -#define RADEON_UPLOAD_TCL 0x00000080 -#define RADEON_UPLOAD_MISC 0x00000100 -#define RADEON_UPLOAD_TEX0 0x00000200 -#define RADEON_UPLOAD_TEX1 0x00000400 -#define RADEON_UPLOAD_TEX2 0x00000800 -#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 -#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 -#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 -#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ -#define RADEON_REQUIRE_QUIESCENCE 0x00010000 -#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */ -#define RADEON_UPLOAD_ALL 0x003effff -#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff - -/* New style per-packet identifiers for use in cmd_buffer ioctl with - * the RADEON_EMIT_PACKET command. Comments relate new packets to old - * state bits and the packet size: - */ -#define RADEON_EMIT_PP_MISC 0 /* context/7 */ -#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ -#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ -#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ -#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ -#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ -#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ -#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ -#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ -#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ -#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ -#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ -#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ -#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ -#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ -#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ -#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ -#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ -#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ -#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ -#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ -#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */ -#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */ -#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */ -#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */ -#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */ -#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */ -#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */ -#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */ -#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */ -#define R200_EMIT_TFACTOR_0 30 /* tf/7 */ -#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */ -#define R200_EMIT_VAP_CTL 32 /* vap/1 */ -#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */ -#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */ -#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */ -#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */ -#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */ -#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */ -#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */ -#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */ -#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */ -#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */ -#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */ -#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */ -#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */ -#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */ -#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */ -#define R200_EMIT_VTE_CNTL 48 /* vte/1 */ -#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */ -#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */ -#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */ -#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */ -#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */ -#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */ -#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */ -#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */ -#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */ -#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */ -#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */ -#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */ -#define R200_EMIT_PP_CUBIC_FACES_0 61 -#define R200_EMIT_PP_CUBIC_OFFSETS_0 62 -#define R200_EMIT_PP_CUBIC_FACES_1 63 -#define R200_EMIT_PP_CUBIC_OFFSETS_1 64 -#define R200_EMIT_PP_CUBIC_FACES_2 65 -#define R200_EMIT_PP_CUBIC_OFFSETS_2 66 -#define R200_EMIT_PP_CUBIC_FACES_3 67 -#define R200_EMIT_PP_CUBIC_OFFSETS_3 68 -#define R200_EMIT_PP_CUBIC_FACES_4 69 -#define R200_EMIT_PP_CUBIC_OFFSETS_4 70 -#define R200_EMIT_PP_CUBIC_FACES_5 71 -#define R200_EMIT_PP_CUBIC_OFFSETS_5 72 -#define RADEON_EMIT_PP_TEX_SIZE_0 73 -#define RADEON_EMIT_PP_TEX_SIZE_1 74 -#define RADEON_EMIT_PP_TEX_SIZE_2 75 -#define R200_EMIT_RB3D_BLENDCOLOR 76 -#define R200_EMIT_TCL_POINT_SPRITE_CNTL 77 -#define RADEON_EMIT_PP_CUBIC_FACES_0 78 -#define RADEON_EMIT_PP_CUBIC_OFFSETS_T0 79 -#define RADEON_EMIT_PP_CUBIC_FACES_1 80 -#define RADEON_EMIT_PP_CUBIC_OFFSETS_T1 81 -#define RADEON_EMIT_PP_CUBIC_FACES_2 82 -#define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83 -#define R200_EMIT_PP_TRI_PERF_CNTL 84 -#define R200_EMIT_PP_AFS_0 85 -#define R200_EMIT_PP_AFS_1 86 -#define R200_EMIT_ATF_TFACTOR 87 -#define R200_EMIT_PP_TXCTLALL_0 88 -#define R200_EMIT_PP_TXCTLALL_1 89 -#define R200_EMIT_PP_TXCTLALL_2 90 -#define R200_EMIT_PP_TXCTLALL_3 91 -#define R200_EMIT_PP_TXCTLALL_4 92 -#define R200_EMIT_PP_TXCTLALL_5 93 -#define R200_EMIT_VAP_PVS_CNTL 94 -#define RADEON_MAX_STATE_PACKETS 95 - -/* Commands understood by cmd_buffer ioctl. More can be added but - * obviously these can't be removed or changed: - */ -#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ -#define RADEON_CMD_SCALARS 2 /* emit scalar data */ -#define RADEON_CMD_VECTORS 3 /* emit vector data */ -#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ -#define RADEON_CMD_PACKET3 5 /* emit hw packet */ -#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ -#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */ -#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: - * doesn't make the cpu wait, just - * the graphics hardware */ -#define RADEON_CMD_VECLINEAR 9 /* another r200 stopgap */ - -typedef union { - int i; - struct { - unsigned char cmd_type, pad0, pad1, pad2; - } header; - struct { - unsigned char cmd_type, packet_id, pad0, pad1; - } packet; - struct { - unsigned char cmd_type, offset, stride, count; - } scalars; - struct { - unsigned char cmd_type, offset, stride, count; - } vectors; - struct { - unsigned char cmd_type, addr_lo, addr_hi, count; - } veclinear; - struct { - unsigned char cmd_type, buf_idx, pad0, pad1; - } dma; - struct { - unsigned char cmd_type, flags, pad0, pad1; - } wait; -} drm_radeon_cmd_header_t; - -#define RADEON_WAIT_2D 0x1 -#define RADEON_WAIT_3D 0x2 - -/* Allowed parameters for R300_CMD_PACKET3 - */ -#define R300_CMD_PACKET3_CLEAR 0 -#define R300_CMD_PACKET3_RAW 1 - -/* Commands understood by cmd_buffer ioctl for R300. - * The interface has not been stabilized, so some of these may be removed - * and eventually reordered before stabilization. - */ -#define R300_CMD_PACKET0 1 -#define R300_CMD_VPU 2 /* emit vertex program upload */ -#define R300_CMD_PACKET3 3 /* emit a packet3 */ -#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */ -#define R300_CMD_CP_DELAY 5 -#define R300_CMD_DMA_DISCARD 6 -#define R300_CMD_WAIT 7 -# define R300_WAIT_2D 0x1 -# define R300_WAIT_3D 0x2 -/* these two defines are DOING IT WRONG - however - * we have userspace which relies on using these. - * The wait interface is backwards compat new - * code should use the NEW_WAIT defines below - * THESE ARE NOT BIT FIELDS - */ -# define R300_WAIT_2D_CLEAN 0x3 -# define R300_WAIT_3D_CLEAN 0x4 - -# define R300_NEW_WAIT_2D_3D 0x3 -# define R300_NEW_WAIT_2D_2D_CLEAN 0x4 -# define R300_NEW_WAIT_3D_3D_CLEAN 0x6 -# define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8 - -#define R300_CMD_SCRATCH 8 -#define R300_CMD_R500FP 9 - -typedef union { - unsigned int u; - struct { - unsigned char cmd_type, pad0, pad1, pad2; - } header; - struct { - unsigned char cmd_type, count, reglo, reghi; - } packet0; - struct { - unsigned char cmd_type, count, adrlo, adrhi; - } vpu; - struct { - unsigned char cmd_type, packet, pad0, pad1; - } packet3; - struct { - unsigned char cmd_type, packet; - unsigned short count; /* amount of packet2 to emit */ - } delay; - struct { - unsigned char cmd_type, buf_idx, pad0, pad1; - } dma; - struct { - unsigned char cmd_type, flags, pad0, pad1; - } wait; - struct { - unsigned char cmd_type, reg, n_bufs, flags; - } scratch; - struct { - unsigned char cmd_type, count, adrlo, adrhi_flags; - } r500fp; -} drm_r300_cmd_header_t; - -#define RADEON_FRONT 0x1 -#define RADEON_BACK 0x2 -#define RADEON_DEPTH 0x4 -#define RADEON_STENCIL 0x8 -#define RADEON_CLEAR_FASTZ 0x80000000 -#define RADEON_USE_HIERZ 0x40000000 -#define RADEON_USE_COMP_ZBUF 0x20000000 - -#define R500FP_CONSTANT_TYPE (1 << 1) -#define R500FP_CONSTANT_CLAMP (1 << 2) - -/* Primitive types - */ -#define RADEON_POINTS 0x1 -#define RADEON_LINES 0x2 -#define RADEON_LINE_STRIP 0x3 -#define RADEON_TRIANGLES 0x4 -#define RADEON_TRIANGLE_FAN 0x5 -#define RADEON_TRIANGLE_STRIP 0x6 - -/* Vertex/indirect buffer size - */ -#define RADEON_BUFFER_SIZE 65536 - -/* Byte offsets for indirect buffer data - */ -#define RADEON_INDEX_PRIM_OFFSET 20 - -#define RADEON_SCRATCH_REG_OFFSET 32 - -#define RADEON_NR_SAREA_CLIPRECTS 12 - -/* There are 2 heaps (local/GART). Each region within a heap is a - * minimum of 64k, and there are at most 64 of them per heap. - */ -#define RADEON_LOCAL_TEX_HEAP 0 -#define RADEON_GART_TEX_HEAP 1 -#define RADEON_NR_TEX_HEAPS 2 -#define RADEON_NR_TEX_REGIONS 64 -#define RADEON_LOG_TEX_GRANULARITY 16 - -#define RADEON_MAX_TEXTURE_LEVELS 12 -#define RADEON_MAX_TEXTURE_UNITS 3 - -#define RADEON_MAX_SURFACES 8 - -/* Blits have strict offset rules. All blit offset must be aligned on - * a 1K-byte boundary. - */ -#define RADEON_OFFSET_SHIFT 10 -#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT) -#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1) - -#endif /* __RADEON_SAREA_DEFINES__ */ - -typedef struct { - unsigned int red; - unsigned int green; - unsigned int blue; - unsigned int alpha; -} radeon_color_regs_t; - -typedef struct { - /* Context state */ - unsigned int pp_misc; /* 0x1c14 */ - unsigned int pp_fog_color; - unsigned int re_solid_color; - unsigned int rb3d_blendcntl; - unsigned int rb3d_depthoffset; - unsigned int rb3d_depthpitch; - unsigned int rb3d_zstencilcntl; - - unsigned int pp_cntl; /* 0x1c38 */ - unsigned int rb3d_cntl; - unsigned int rb3d_coloroffset; - unsigned int re_width_height; - unsigned int rb3d_colorpitch; - unsigned int se_cntl; - - /* Vertex format state */ - unsigned int se_coord_fmt; /* 0x1c50 */ - - /* Line state */ - unsigned int re_line_pattern; /* 0x1cd0 */ - unsigned int re_line_state; - - unsigned int se_line_width; /* 0x1db8 */ - - /* Bumpmap state */ - unsigned int pp_lum_matrix; /* 0x1d00 */ - - unsigned int pp_rot_matrix_0; /* 0x1d58 */ - unsigned int pp_rot_matrix_1; - - /* Mask state */ - unsigned int rb3d_stencilrefmask; /* 0x1d7c */ - unsigned int rb3d_ropcntl; - unsigned int rb3d_planemask; - - /* Viewport state */ - unsigned int se_vport_xscale; /* 0x1d98 */ - unsigned int se_vport_xoffset; - unsigned int se_vport_yscale; - unsigned int se_vport_yoffset; - unsigned int se_vport_zscale; - unsigned int se_vport_zoffset; - - /* Setup state */ - unsigned int se_cntl_status; /* 0x2140 */ - - /* Misc state */ - unsigned int re_top_left; /* 0x26c0 */ - unsigned int re_misc; -} drm_radeon_context_regs_t; - -typedef struct { - /* Zbias state */ - unsigned int se_zbias_factor; /* 0x1dac */ - unsigned int se_zbias_constant; -} drm_radeon_context2_regs_t; - -/* Setup registers for each texture unit - */ -typedef struct { - unsigned int pp_txfilter; - unsigned int pp_txformat; - unsigned int pp_txoffset; - unsigned int pp_txcblend; - unsigned int pp_txablend; - unsigned int pp_tfactor; - unsigned int pp_border_color; -} drm_radeon_texture_regs_t; - -typedef struct { - unsigned int start; - unsigned int finish; - unsigned int prim:8; - unsigned int stateidx:8; - unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ - unsigned int vc_format; /* vertex format */ -} drm_radeon_prim_t; - -typedef struct { - drm_radeon_context_regs_t context; - drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS]; - drm_radeon_context2_regs_t context2; - unsigned int dirty; -} drm_radeon_state_t; - -typedef struct { - /* The channel for communication of state information to the - * kernel on firing a vertex buffer with either of the - * obsoleted vertex/index ioctls. - */ - drm_radeon_context_regs_t context_state; - drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS]; - unsigned int dirty; - unsigned int vertsize; - unsigned int vc_format; - - /* The current cliprects, or a subset thereof. - */ - struct drm_clip_rect boxes[RADEON_NR_SAREA_CLIPRECTS]; - unsigned int nbox; - - /* Counters for client-side throttling of rendering clients. - */ - unsigned int last_frame; - unsigned int last_dispatch; - unsigned int last_clear; - - struct drm_tex_region tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS + - 1]; - unsigned int tex_age[RADEON_NR_TEX_HEAPS]; - int ctx_owner; - int pfState; /* number of 3d windows (0,1,2ormore) */ - int pfCurrentPage; /* which buffer is being displayed? */ - int crtc2_base; /* CRTC2 frame offset */ - int tiling_enabled; /* set by drm, read by 2d + 3d clients */ -} drm_radeon_sarea_t; - -/* WARNING: If you change any of these defines, make sure to change the - * defines in the Xserver file (xf86drmRadeon.h) - * - * KW: actually it's illegal to change any of this (backwards compatibility). - */ - -/* Radeon specific ioctls - * The device specific ioctl range is 0x40 to 0x79. - */ -#define DRM_RADEON_CP_INIT 0x00 -#define DRM_RADEON_CP_START 0x01 -#define DRM_RADEON_CP_STOP 0x02 -#define DRM_RADEON_CP_RESET 0x03 -#define DRM_RADEON_CP_IDLE 0x04 -#define DRM_RADEON_RESET 0x05 -#define DRM_RADEON_FULLSCREEN 0x06 -#define DRM_RADEON_SWAP 0x07 -#define DRM_RADEON_CLEAR 0x08 -#define DRM_RADEON_VERTEX 0x09 -#define DRM_RADEON_INDICES 0x0A -#define DRM_RADEON_NOT_USED -#define DRM_RADEON_STIPPLE 0x0C -#define DRM_RADEON_INDIRECT 0x0D -#define DRM_RADEON_TEXTURE 0x0E -#define DRM_RADEON_VERTEX2 0x0F -#define DRM_RADEON_CMDBUF 0x10 -#define DRM_RADEON_GETPARAM 0x11 -#define DRM_RADEON_FLIP 0x12 -#define DRM_RADEON_ALLOC 0x13 -#define DRM_RADEON_FREE 0x14 -#define DRM_RADEON_INIT_HEAP 0x15 -#define DRM_RADEON_IRQ_EMIT 0x16 -#define DRM_RADEON_IRQ_WAIT 0x17 -#define DRM_RADEON_CP_RESUME 0x18 -#define DRM_RADEON_SETPARAM 0x19 -#define DRM_RADEON_SURF_ALLOC 0x1a -#define DRM_RADEON_SURF_FREE 0x1b - -#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) -#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) -#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t) -#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESET) -#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_IDLE) -#define DRM_IOCTL_RADEON_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_RESET) -#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FULLSCREEN, drm_radeon_fullscreen_t) -#define DRM_IOCTL_RADEON_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_SWAP) -#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CLEAR, drm_radeon_clear_t) -#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX, drm_radeon_vertex_t) -#define DRM_IOCTL_RADEON_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INDICES, drm_radeon_indices_t) -#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_STIPPLE, drm_radeon_stipple_t) -#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INDIRECT, drm_radeon_indirect_t) -#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_TEXTURE, drm_radeon_texture_t) -#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX2, drm_radeon_vertex2_t) -#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CMDBUF, drm_radeon_cmd_buffer_t) -#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GETPARAM, drm_radeon_getparam_t) -#define DRM_IOCTL_RADEON_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_FLIP) -#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_ALLOC, drm_radeon_mem_alloc_t) -#define DRM_IOCTL_RADEON_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FREE, drm_radeon_mem_free_t) -#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INIT_HEAP, drm_radeon_mem_init_heap_t) -#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_IRQ_EMIT, drm_radeon_irq_emit_t) -#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t) -#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME) -#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) -#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) -#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) - -typedef struct drm_radeon_init { - enum { - RADEON_INIT_CP = 0x01, - RADEON_CLEANUP_CP = 0x02, - RADEON_INIT_R200_CP = 0x03, - RADEON_INIT_R300_CP = 0x04 - } func; - unsigned long sarea_priv_offset; - int is_pci; - int cp_mode; - int gart_size; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - unsigned long fb_offset; - unsigned long mmio_offset; - unsigned long ring_offset; - unsigned long ring_rptr_offset; - unsigned long buffers_offset; - unsigned long gart_textures_offset; -} drm_radeon_init_t; - -typedef struct drm_radeon_cp_stop { - int flush; - int idle; -} drm_radeon_cp_stop_t; - -typedef struct drm_radeon_fullscreen { - enum { - RADEON_INIT_FULLSCREEN = 0x01, - RADEON_CLEANUP_FULLSCREEN = 0x02 - } func; -} drm_radeon_fullscreen_t; - -#define CLEAR_X1 0 -#define CLEAR_Y1 1 -#define CLEAR_X2 2 -#define CLEAR_Y2 3 -#define CLEAR_DEPTH 4 - -typedef union drm_radeon_clear_rect { - float f[5]; - unsigned int ui[5]; -} drm_radeon_clear_rect_t; - -typedef struct drm_radeon_clear { - unsigned int flags; - unsigned int clear_color; - unsigned int clear_depth; - unsigned int color_mask; - unsigned int depth_mask; /* misnamed field: should be stencil */ - drm_radeon_clear_rect_t __user *depth_boxes; -} drm_radeon_clear_t; - -typedef struct drm_radeon_vertex { - int prim; - int idx; /* Index of vertex buffer */ - int count; /* Number of vertices in buffer */ - int discard; /* Client finished with buffer? */ -} drm_radeon_vertex_t; - -typedef struct drm_radeon_indices { - int prim; - int idx; - int start; - int end; - int discard; /* Client finished with buffer? */ -} drm_radeon_indices_t; - -/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices - * - allows multiple primitives and state changes in a single ioctl - * - supports driver change to emit native primitives - */ -typedef struct drm_radeon_vertex2 { - int idx; /* Index of vertex buffer */ - int discard; /* Client finished with buffer? */ - int nr_states; - drm_radeon_state_t __user *state; - int nr_prims; - drm_radeon_prim_t __user *prim; -} drm_radeon_vertex2_t; - -/* v1.3 - obsoletes drm_radeon_vertex2 - * - allows arbitarily large cliprect list - * - allows updating of tcl packet, vector and scalar state - * - allows memory-efficient description of state updates - * - allows state to be emitted without a primitive - * (for clears, ctx switches) - * - allows more than one dma buffer to be referenced per ioctl - * - supports tcl driver - * - may be extended in future versions with new cmd types, packets - */ -typedef struct drm_radeon_cmd_buffer { - int bufsz; - char __user *buf; - int nbox; - struct drm_clip_rect __user *boxes; -} drm_radeon_cmd_buffer_t; - -typedef struct drm_radeon_tex_image { - unsigned int x, y; /* Blit coordinates */ - unsigned int width, height; - const void __user *data; -} drm_radeon_tex_image_t; - -typedef struct drm_radeon_texture { - unsigned int offset; - int pitch; - int format; - int width; /* Texture image coordinates */ - int height; - drm_radeon_tex_image_t __user *image; -} drm_radeon_texture_t; - -typedef struct drm_radeon_stipple { - unsigned int __user *mask; -} drm_radeon_stipple_t; - -typedef struct drm_radeon_indirect { - int idx; - int start; - int end; - int discard; -} drm_radeon_indirect_t; - -/* enum for card type parameters */ -#define RADEON_CARD_PCI 0 -#define RADEON_CARD_AGP 1 -#define RADEON_CARD_PCIE 2 - -/* 1.3: An ioctl to get parameters that aren't available to the 3d - * client any other way. - */ -#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */ -#define RADEON_PARAM_LAST_FRAME 2 -#define RADEON_PARAM_LAST_DISPATCH 3 -#define RADEON_PARAM_LAST_CLEAR 4 -/* Added with DRM version 1.6. */ -#define RADEON_PARAM_IRQ_NR 5 -#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */ -/* Added with DRM version 1.8. */ -#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */ -#define RADEON_PARAM_STATUS_HANDLE 8 -#define RADEON_PARAM_SAREA_HANDLE 9 -#define RADEON_PARAM_GART_TEX_HANDLE 10 -#define RADEON_PARAM_SCRATCH_OFFSET 11 -#define RADEON_PARAM_CARD_TYPE 12 -#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ -#define RADEON_PARAM_FB_LOCATION 14 /* FB location */ -#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ - -typedef struct drm_radeon_getparam { - int param; - void __user *value; -} drm_radeon_getparam_t; - -/* 1.6: Set up a memory manager for regions of shared memory: - */ -#define RADEON_MEM_REGION_GART 1 -#define RADEON_MEM_REGION_FB 2 - -typedef struct drm_radeon_mem_alloc { - int region; - int alignment; - int size; - int __user *region_offset; /* offset from start of fb or GART */ -} drm_radeon_mem_alloc_t; - -typedef struct drm_radeon_mem_free { - int region; - int region_offset; -} drm_radeon_mem_free_t; - -typedef struct drm_radeon_mem_init_heap { - int region; - int size; - int start; -} drm_radeon_mem_init_heap_t; - -/* 1.6: Userspace can request & wait on irq's: - */ -typedef struct drm_radeon_irq_emit { - int __user *irq_seq; -} drm_radeon_irq_emit_t; - -typedef struct drm_radeon_irq_wait { - int irq_seq; -} drm_radeon_irq_wait_t; - -/* 1.10: Clients tell the DRM where they think the framebuffer is located in - * the card's address space, via a new generic ioctl to set parameters - */ - -typedef struct drm_radeon_setparam { - unsigned int param; - int64_t value; -} drm_radeon_setparam_t; - -#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ -#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ -#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ -#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ -#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ -#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ -/* 1.14: Clients can allocate/free a surface - */ -typedef struct drm_radeon_surface_alloc { - unsigned int address; - unsigned int size; - unsigned int flags; -} drm_radeon_surface_alloc_t; - -typedef struct drm_radeon_surface_free { - unsigned int address; -} drm_radeon_surface_free_t; - -#define DRM_RADEON_VBLANK_CRTC1 1 -#define DRM_RADEON_VBLANK_CRTC2 2 - -#endif diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c deleted file mode 100644 index 349ac3d..0000000 --- a/drivers/char/drm/radeon_drv.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * \file radeon_drv.c - * ATI Radeon driver - * - * \author Gareth Hughes - */ - -/* - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -#include "drm_pciids.h" - -int radeon_no_wb; - -MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n"); -module_param_named(no_wb, radeon_no_wb, int, 0444); - -static int dri_library_name(struct drm_device *dev, char *buf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int family = dev_priv->flags & RADEON_FAMILY_MASK; - - return snprintf(buf, PAGE_SIZE, "%s\n", - (family < CHIP_R200) ? "radeon" : - ((family < CHIP_R300) ? "r200" : - "r300")); -} - -static struct pci_device_id pciidlist[] = { - radeon_PCI_IDS -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | - DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, - .dev_priv_size = sizeof(drm_radeon_buf_priv_t), - .load = radeon_driver_load, - .firstopen = radeon_driver_firstopen, - .open = radeon_driver_open, - .preclose = radeon_driver_preclose, - .postclose = radeon_driver_postclose, - .lastclose = radeon_driver_lastclose, - .unload = radeon_driver_unload, - .vblank_wait = radeon_driver_vblank_wait, - .vblank_wait2 = radeon_driver_vblank_wait2, - .dri_library_name = dri_library_name, - .irq_preinstall = radeon_driver_irq_preinstall, - .irq_postinstall = radeon_driver_irq_postinstall, - .irq_uninstall = radeon_driver_irq_uninstall, - .irq_handler = radeon_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = radeon_ioctls, - .dma_ioctl = radeon_cp_buffers, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = radeon_compat_ioctl, -#endif - }, - - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init radeon_init(void) -{ - driver.num_ioctls = radeon_max_ioctl; - return drm_init(&driver); -} - -static void __exit radeon_exit(void) -{ - drm_exit(&driver); -} - -module_init(radeon_init); -module_exit(radeon_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h deleted file mode 100644 index 3f0eca9..0000000 --- a/drivers/char/drm/radeon_drv.h +++ /dev/null @@ -1,1406 +0,0 @@ -/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*- - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kevin E. Martin - * Gareth Hughes - */ - -#ifndef __RADEON_DRV_H__ -#define __RADEON_DRV_H__ - -/* General customization: - */ - -#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others." - -#define DRIVER_NAME "radeon" -#define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20080528" - -/* Interface history: - * - * 1.1 - ?? - * 1.2 - Add vertex2 ioctl (keith) - * - Add stencil capability to clear ioctl (gareth, keith) - * - Increase MAX_TEXTURE_LEVELS (brian) - * 1.3 - Add cmdbuf ioctl (keith) - * - Add support for new radeon packets (keith) - * - Add getparam ioctl (keith) - * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). - * 1.4 - Add scratch registers to get_param ioctl. - * 1.5 - Add r200 packets to cmdbuf ioctl - * - Add r200 function to init ioctl - * - Add 'scalar2' instruction to cmdbuf - * 1.6 - Add static GART memory manager - * Add irq handler (won't be turned on unless X server knows to) - * Add irq ioctls and irq_active getparam. - * Add wait command for cmdbuf ioctl - * Add GART offset query for getparam - * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5] - * and R200_PP_CUBIC_OFFSET_F1_[0..5]. - * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and - * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian) - * 1.8 - Remove need to call cleanup ioctls on last client exit (keith) - * Add 'GET' queries for starting additional clients on different VT's. - * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl. - * Add texture rectangle support for r100. - * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which - * clients use to tell the DRM where they think the framebuffer is - * located in the card's address space - * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color - * and GL_EXT_blend_[func|equation]_separate on r200 - * 1.12- Add R300 CP microcode support - this just loads the CP on r300 - * (No 3D support yet - just microcode loading). - * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters - * - Add hyperz support, add hyperz flags to clear ioctl. - * 1.14- Add support for color tiling - * - Add R100/R200 surface allocation/free support - * 1.15- Add support for texture micro tiling - * - Add support for r100 cube maps - * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear - * texture filtering on r200 - * 1.17- Add initial support for R300 (3D). - * 1.18- Add support for GL_ATI_fragment_shader, new packets - * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces - * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR - * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) - * 1.19- Add support for gart table in FB memory and PCIE r300 - * 1.20- Add support for r300 texrect - * 1.21- Add support for card type getparam - * 1.22- Add support for texture cache flushes (R300_TX_CNTL) - * 1.23- Add new radeon memory map work from benh - * 1.24- Add general-purpose packet for manipulating scratch registers (r300) - * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, - * new packet type) - * 1.26- Add support for variable size PCI(E) gart aperture - * 1.27- Add support for IGP GART - * 1.28- Add support for VBL on CRTC2 - * 1.29- R500 3D cmd buffer support - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 29 -#define DRIVER_PATCHLEVEL 0 - -/* - * Radeon chip families - */ -enum radeon_family { - CHIP_R100, - CHIP_RV100, - CHIP_RS100, - CHIP_RV200, - CHIP_RS200, - CHIP_R200, - CHIP_RV250, - CHIP_RS300, - CHIP_RV280, - CHIP_R300, - CHIP_R350, - CHIP_RV350, - CHIP_RV380, - CHIP_R420, - CHIP_RV410, - CHIP_RS480, - CHIP_RS690, - CHIP_RV515, - CHIP_R520, - CHIP_RV530, - CHIP_RV560, - CHIP_RV570, - CHIP_R580, - CHIP_LAST, -}; - -enum radeon_cp_microcode_version { - UCODE_R100, - UCODE_R200, - UCODE_R300, -}; - -/* - * Chip flags - */ -enum radeon_chip_flags { - RADEON_FAMILY_MASK = 0x0000ffffUL, - RADEON_FLAGS_MASK = 0xffff0000UL, - RADEON_IS_MOBILITY = 0x00010000UL, - RADEON_IS_IGP = 0x00020000UL, - RADEON_SINGLE_CRTC = 0x00040000UL, - RADEON_IS_AGP = 0x00080000UL, - RADEON_HAS_HIERZ = 0x00100000UL, - RADEON_IS_PCIE = 0x00200000UL, - RADEON_NEW_MEMMAP = 0x00400000UL, - RADEON_IS_PCI = 0x00800000UL, - RADEON_IS_IGPGART = 0x01000000UL, -}; - -#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) -#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) - -typedef struct drm_radeon_freelist { - unsigned int age; - struct drm_buf *buf; - struct drm_radeon_freelist *next; - struct drm_radeon_freelist *prev; -} drm_radeon_freelist_t; - -typedef struct drm_radeon_ring_buffer { - u32 *start; - u32 *end; - int size; - int size_l2qw; - - int rptr_update; /* Double Words */ - int rptr_update_l2qw; /* log2 Quad Words */ - - int fetch_size; /* Double Words */ - int fetch_size_l2ow; /* log2 Oct Words */ - - u32 tail; - u32 tail_mask; - int space; - - int high_mark; -} drm_radeon_ring_buffer_t; - -typedef struct drm_radeon_depth_clear_t { - u32 rb3d_cntl; - u32 rb3d_zstencilcntl; - u32 se_cntl; -} drm_radeon_depth_clear_t; - -struct drm_radeon_driver_file_fields { - int64_t radeon_fb_delta; -}; - -struct mem_block { - struct mem_block *next; - struct mem_block *prev; - int start; - int size; - struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ -}; - -struct radeon_surface { - int refcount; - u32 lower; - u32 upper; - u32 flags; -}; - -struct radeon_virt_surface { - int surface_index; - u32 lower; - u32 upper; - u32 flags; - struct drm_file *file_priv; -}; - -typedef struct drm_radeon_private { - drm_radeon_ring_buffer_t ring; - drm_radeon_sarea_t *sarea_priv; - - u32 fb_location; - u32 fb_size; - int new_memmap; - - int gart_size; - u32 gart_vm_start; - unsigned long gart_buffers_offset; - - int cp_mode; - int cp_running; - - drm_radeon_freelist_t *head; - drm_radeon_freelist_t *tail; - int last_buf; - volatile u32 *scratch; - int writeback_works; - - int usec_timeout; - - int microcode_version; - - struct { - u32 boxes; - int freelist_timeouts; - int freelist_loops; - int requested_bufs; - int last_frame_reads; - int last_clear_reads; - int clears; - int texture_uploads; - } stats; - - int do_boxes; - int page_flipping; - - u32 color_fmt; - unsigned int front_offset; - unsigned int front_pitch; - unsigned int back_offset; - unsigned int back_pitch; - - u32 depth_fmt; - unsigned int depth_offset; - unsigned int depth_pitch; - - u32 front_pitch_offset; - u32 back_pitch_offset; - u32 depth_pitch_offset; - - drm_radeon_depth_clear_t depth_clear; - - unsigned long ring_offset; - unsigned long ring_rptr_offset; - unsigned long buffers_offset; - unsigned long gart_textures_offset; - - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *cp_ring; - drm_local_map_t *ring_rptr; - drm_local_map_t *gart_textures; - - struct mem_block *gart_heap; - struct mem_block *fb_heap; - - /* SW interrupt */ - wait_queue_head_t swi_queue; - atomic_t swi_emitted; - int vblank_crtc; - uint32_t irq_enable_reg; - int irq_enabled; - uint32_t r500_disp_irq_reg; - - struct radeon_surface surfaces[RADEON_MAX_SURFACES]; - struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; - - unsigned long pcigart_offset; - unsigned int pcigart_offset_set; - struct drm_ati_pcigart_info gart_info; - - u32 scratch_ages[5]; - - /* starting from here on, data is preserved accross an open */ - uint32_t flags; /* see radeon_chip_flags */ - unsigned long fb_aper_offset; - - int num_gb_pipes; -} drm_radeon_private_t; - -typedef struct drm_radeon_buf_priv { - u32 age; -} drm_radeon_buf_priv_t; - -typedef struct drm_radeon_kcmd_buffer { - int bufsz; - char *buf; - int nbox; - struct drm_clip_rect __user *boxes; -} drm_radeon_kcmd_buffer_t; - -extern int radeon_no_wb; -extern struct drm_ioctl_desc radeon_ioctls[]; -extern int radeon_max_ioctl; - -/* Check whether the given hardware address is inside the framebuffer or the - * GART area. - */ -static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, - u64 off) -{ - u32 fb_start = dev_priv->fb_location; - u32 fb_end = fb_start + dev_priv->fb_size - 1; - u32 gart_start = dev_priv->gart_vm_start; - u32 gart_end = gart_start + dev_priv->gart_size - 1; - - return ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)); -} - - /* radeon_cp.c */ -extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); - -extern void radeon_freelist_reset(struct drm_device * dev); -extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); - -extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); - -extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); - -extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); -extern int radeon_presetup(struct drm_device *dev); -extern int radeon_driver_postcleanup(struct drm_device *dev); - -extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void radeon_mem_takedown(struct mem_block **heap); -extern void radeon_mem_release(struct drm_file *file_priv, - struct mem_block *heap); - - /* radeon_irq.c */ -extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); - -extern void radeon_do_release(struct drm_device * dev); -extern int radeon_driver_vblank_wait(struct drm_device * dev, - unsigned int *sequence); -extern int radeon_driver_vblank_wait2(struct drm_device * dev, - unsigned int *sequence); -extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); -extern void radeon_driver_irq_preinstall(struct drm_device * dev); -extern void radeon_driver_irq_postinstall(struct drm_device * dev); -extern void radeon_driver_irq_uninstall(struct drm_device * dev); -extern void radeon_enable_interrupt(struct drm_device *dev); -extern int radeon_vblank_crtc_get(struct drm_device *dev); -extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); - -extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); -extern int radeon_driver_unload(struct drm_device *dev); -extern int radeon_driver_firstopen(struct drm_device *dev); -extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv); -extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp); -extern void radeon_driver_lastclose(struct drm_device * dev); -extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv); -extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -/* r300_cmdbuf.c */ -extern void r300_init_reg_flags(struct drm_device *dev); - -extern int r300_do_cp_cmdbuf(struct drm_device * dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t * cmdbuf); - -/* Flags for stats.boxes - */ -#define RADEON_BOX_DMA_IDLE 0x1 -#define RADEON_BOX_RING_FULL 0x2 -#define RADEON_BOX_FLIP 0x4 -#define RADEON_BOX_WAIT_IDLE 0x8 -#define RADEON_BOX_TEXTURE_LOAD 0x10 - -/* Register definitions, register access macros and drmAddMap constants - * for Radeon kernel driver. - */ - -#define RADEON_AGP_COMMAND 0x0f60 -#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ -# define RADEON_AGP_ENABLE (1<<8) -#define RADEON_AUX_SCISSOR_CNTL 0x26f0 -# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) -# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) -# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26) -# define RADEON_SCISSOR_0_ENABLE (1 << 28) -# define RADEON_SCISSOR_1_ENABLE (1 << 29) -# define RADEON_SCISSOR_2_ENABLE (1 << 30) - -#define RADEON_BUS_CNTL 0x0030 -# define RADEON_BUS_MASTER_DIS (1 << 6) - -#define RADEON_CLOCK_CNTL_DATA 0x000c -# define RADEON_PLL_WR_EN (1 << 7) -#define RADEON_CLOCK_CNTL_INDEX 0x0008 -#define RADEON_CONFIG_APER_SIZE 0x0108 -#define RADEON_CONFIG_MEMSIZE 0x00f8 -#define RADEON_CRTC_OFFSET 0x0224 -#define RADEON_CRTC_OFFSET_CNTL 0x0228 -# define RADEON_CRTC_TILE_EN (1 << 15) -# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) -#define RADEON_CRTC2_OFFSET 0x0324 -#define RADEON_CRTC2_OFFSET_CNTL 0x0328 - -#define RADEON_PCIE_INDEX 0x0030 -#define RADEON_PCIE_DATA 0x0034 -#define RADEON_PCIE_TX_GART_CNTL 0x10 -# define RADEON_PCIE_TX_GART_EN (1 << 0) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0 << 1) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1 << 1) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3 << 1) -# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0 << 3) -# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1 << 3) -# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1 << 5) -# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1 << 8) -#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11 -#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12 -#define RADEON_PCIE_TX_GART_BASE 0x13 -#define RADEON_PCIE_TX_GART_START_LO 0x14 -#define RADEON_PCIE_TX_GART_START_HI 0x15 -#define RADEON_PCIE_TX_GART_END_LO 0x16 -#define RADEON_PCIE_TX_GART_END_HI 0x17 - -#define RS480_NB_MC_INDEX 0x168 -# define RS480_NB_MC_IND_WR_EN (1 << 8) -#define RS480_NB_MC_DATA 0x16c - -#define RS690_MC_INDEX 0x78 -# define RS690_MC_INDEX_MASK 0x1ff -# define RS690_MC_INDEX_WR_EN (1 << 9) -# define RS690_MC_INDEX_WR_ACK 0x7f -#define RS690_MC_DATA 0x7c - -/* MC indirect registers */ -#define RS480_MC_MISC_CNTL 0x18 -# define RS480_DISABLE_GTW (1 << 1) -/* switch between MCIND GART and MM GART registers. 0 = mmgart, 1 = mcind gart */ -# define RS480_GART_INDEX_REG_EN (1 << 12) -# define RS690_BLOCK_GFX_D3_EN (1 << 14) -#define RS480_K8_FB_LOCATION 0x1e -#define RS480_GART_FEATURE_ID 0x2b -# define RS480_HANG_EN (1 << 11) -# define RS480_TLB_ENABLE (1 << 18) -# define RS480_P2P_ENABLE (1 << 19) -# define RS480_GTW_LAC_EN (1 << 25) -# define RS480_2LEVEL_GART (0 << 30) -# define RS480_1LEVEL_GART (1 << 30) -# define RS480_PDC_EN (1 << 31) -#define RS480_GART_BASE 0x2c -#define RS480_GART_CACHE_CNTRL 0x2e -# define RS480_GART_CACHE_INVALIDATE (1 << 0) /* wait for it to clear */ -#define RS480_AGP_ADDRESS_SPACE_SIZE 0x38 -# define RS480_GART_EN (1 << 0) -# define RS480_VA_SIZE_32MB (0 << 1) -# define RS480_VA_SIZE_64MB (1 << 1) -# define RS480_VA_SIZE_128MB (2 << 1) -# define RS480_VA_SIZE_256MB (3 << 1) -# define RS480_VA_SIZE_512MB (4 << 1) -# define RS480_VA_SIZE_1GB (5 << 1) -# define RS480_VA_SIZE_2GB (6 << 1) -#define RS480_AGP_MODE_CNTL 0x39 -# define RS480_POST_GART_Q_SIZE (1 << 18) -# define RS480_NONGART_SNOOP (1 << 19) -# define RS480_AGP_RD_BUF_SIZE (1 << 20) -# define RS480_REQ_TYPE_SNOOP_SHIFT 22 -# define RS480_REQ_TYPE_SNOOP_MASK 0x3 -# define RS480_REQ_TYPE_SNOOP_DIS (1 << 24) -#define RS480_MC_MISC_UMA_CNTL 0x5f -#define RS480_MC_MCLK_CNTL 0x7a -#define RS480_MC_UMA_DUALCH_CNTL 0x86 - -#define RS690_MC_FB_LOCATION 0x100 -#define RS690_MC_AGP_LOCATION 0x101 -#define RS690_MC_AGP_BASE 0x102 -#define RS690_MC_AGP_BASE_2 0x103 - -#define R520_MC_IND_INDEX 0x70 -#define R520_MC_IND_WR_EN (1 << 24) -#define R520_MC_IND_DATA 0x74 - -#define RV515_MC_FB_LOCATION 0x01 -#define RV515_MC_AGP_LOCATION 0x02 -#define RV515_MC_AGP_BASE 0x03 -#define RV515_MC_AGP_BASE_2 0x04 - -#define R520_MC_FB_LOCATION 0x04 -#define R520_MC_AGP_LOCATION 0x05 -#define R520_MC_AGP_BASE 0x06 -#define R520_MC_AGP_BASE_2 0x07 - -#define RADEON_MPP_TB_CONFIG 0x01c0 -#define RADEON_MEM_CNTL 0x0140 -#define RADEON_MEM_SDRAM_MODE_REG 0x0158 -#define RADEON_AGP_BASE_2 0x015c /* r200+ only */ -#define RS480_AGP_BASE_2 0x0164 -#define RADEON_AGP_BASE 0x0170 - -/* pipe config regs */ -#define R400_GB_PIPE_SELECT 0x402c -#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ -#define R500_SU_REG_DEST 0x42c8 -#define R300_GB_TILE_CONFIG 0x4018 -# define R300_ENABLE_TILING (1 << 0) -# define R300_PIPE_COUNT_RV350 (0 << 1) -# define R300_PIPE_COUNT_R300 (3 << 1) -# define R300_PIPE_COUNT_R420_3P (6 << 1) -# define R300_PIPE_COUNT_R420 (7 << 1) -# define R300_TILE_SIZE_8 (0 << 4) -# define R300_TILE_SIZE_16 (1 << 4) -# define R300_TILE_SIZE_32 (2 << 4) -# define R300_SUBPIXEL_1_12 (0 << 16) -# define R300_SUBPIXEL_1_16 (1 << 16) -#define R300_DST_PIPE_CONFIG 0x170c -# define R300_PIPE_AUTO_CONFIG (1 << 31) -#define R300_RB2D_DSTCACHE_MODE 0x3428 -# define R300_DC_AUTOFLUSH_ENABLE (1 << 8) -# define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17) - -#define RADEON_RB3D_COLOROFFSET 0x1c40 -#define RADEON_RB3D_COLORPITCH 0x1c48 - -#define RADEON_SRC_X_Y 0x1590 - -#define RADEON_DP_GUI_MASTER_CNTL 0x146c -# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) -# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) -# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) -# define RADEON_GMC_BRUSH_NONE (15 << 4) -# define RADEON_GMC_DST_16BPP (4 << 8) -# define RADEON_GMC_DST_24BPP (5 << 8) -# define RADEON_GMC_DST_32BPP (6 << 8) -# define RADEON_GMC_DST_DATATYPE_SHIFT 8 -# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) -# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) -# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) -# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) -# define RADEON_GMC_WR_MSK_DIS (1 << 30) -# define RADEON_ROP3_S 0x00cc0000 -# define RADEON_ROP3_P 0x00f00000 -#define RADEON_DP_WRITE_MASK 0x16cc -#define RADEON_SRC_PITCH_OFFSET 0x1428 -#define RADEON_DST_PITCH_OFFSET 0x142c -#define RADEON_DST_PITCH_OFFSET_C 0x1c80 -# define RADEON_DST_TILE_LINEAR (0 << 30) -# define RADEON_DST_TILE_MACRO (1 << 30) -# define RADEON_DST_TILE_MICRO (2 << 30) -# define RADEON_DST_TILE_BOTH (3 << 30) - -#define RADEON_SCRATCH_REG0 0x15e0 -#define RADEON_SCRATCH_REG1 0x15e4 -#define RADEON_SCRATCH_REG2 0x15e8 -#define RADEON_SCRATCH_REG3 0x15ec -#define RADEON_SCRATCH_REG4 0x15f0 -#define RADEON_SCRATCH_REG5 0x15f4 -#define RADEON_SCRATCH_UMSK 0x0770 -#define RADEON_SCRATCH_ADDR 0x0774 - -#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) - -#define GET_SCRATCH( x ) (dev_priv->writeback_works \ - ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ - : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) - -#define RADEON_GEN_INT_CNTL 0x0040 -# define RADEON_CRTC_VBLANK_MASK (1 << 0) -# define RADEON_CRTC2_VBLANK_MASK (1 << 9) -# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) -# define RADEON_SW_INT_ENABLE (1 << 25) - -#define RADEON_GEN_INT_STATUS 0x0044 -# define RADEON_CRTC_VBLANK_STAT (1 << 0) -# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) -# define RADEON_CRTC2_VBLANK_STAT (1 << 9) -# define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) -# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) -# define RADEON_SW_INT_TEST (1 << 25) -# define RADEON_SW_INT_TEST_ACK (1 << 25) -# define RADEON_SW_INT_FIRE (1 << 26) - -#define RADEON_HOST_PATH_CNTL 0x0130 -# define RADEON_HDP_SOFT_RESET (1 << 26) -# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) -# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28) - -#define RADEON_ISYNC_CNTL 0x1724 -# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) -# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) -# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) -# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) -# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) -# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) - -#define RADEON_RBBM_GUICNTL 0x172c -# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) -# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) -# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) -# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) - -#define RADEON_MC_AGP_LOCATION 0x014c -#define RADEON_MC_FB_LOCATION 0x0148 -#define RADEON_MCLK_CNTL 0x0012 -# define RADEON_FORCEON_MCLKA (1 << 16) -# define RADEON_FORCEON_MCLKB (1 << 17) -# define RADEON_FORCEON_YCLKA (1 << 18) -# define RADEON_FORCEON_YCLKB (1 << 19) -# define RADEON_FORCEON_MC (1 << 20) -# define RADEON_FORCEON_AIC (1 << 21) - -#define RADEON_PP_BORDER_COLOR_0 0x1d40 -#define RADEON_PP_BORDER_COLOR_1 0x1d44 -#define RADEON_PP_BORDER_COLOR_2 0x1d48 -#define RADEON_PP_CNTL 0x1c38 -# define RADEON_SCISSOR_ENABLE (1 << 1) -#define RADEON_PP_LUM_MATRIX 0x1d00 -#define RADEON_PP_MISC 0x1c14 -#define RADEON_PP_ROT_MATRIX_0 0x1d58 -#define RADEON_PP_TXFILTER_0 0x1c54 -#define RADEON_PP_TXOFFSET_0 0x1c5c -#define RADEON_PP_TXFILTER_1 0x1c6c -#define RADEON_PP_TXFILTER_2 0x1c84 - -#define R300_RB2D_DSTCACHE_CTLSTAT 0x342c /* use R300_DSTCACHE_CTLSTAT */ -#define R300_DSTCACHE_CTLSTAT 0x1714 -# define R300_RB2D_DC_FLUSH (3 << 0) -# define R300_RB2D_DC_FREE (3 << 2) -# define R300_RB2D_DC_FLUSH_ALL 0xf -# define R300_RB2D_DC_BUSY (1 << 31) -#define RADEON_RB3D_CNTL 0x1c3c -# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) -# define RADEON_PLANE_MASK_ENABLE (1 << 1) -# define RADEON_DITHER_ENABLE (1 << 2) -# define RADEON_ROUND_ENABLE (1 << 3) -# define RADEON_SCALE_DITHER_ENABLE (1 << 4) -# define RADEON_DITHER_INIT (1 << 5) -# define RADEON_ROP_ENABLE (1 << 6) -# define RADEON_STENCIL_ENABLE (1 << 7) -# define RADEON_Z_ENABLE (1 << 8) -# define RADEON_ZBLOCK16 (1 << 15) -#define RADEON_RB3D_DEPTHOFFSET 0x1c24 -#define RADEON_RB3D_DEPTHCLEARVALUE 0x3230 -#define RADEON_RB3D_DEPTHPITCH 0x1c28 -#define RADEON_RB3D_PLANEMASK 0x1d84 -#define RADEON_RB3D_STENCILREFMASK 0x1d7c -#define RADEON_RB3D_ZCACHE_MODE 0x3250 -#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254 -# define RADEON_RB3D_ZC_FLUSH (1 << 0) -# define RADEON_RB3D_ZC_FREE (1 << 2) -# define RADEON_RB3D_ZC_FLUSH_ALL 0x5 -# define RADEON_RB3D_ZC_BUSY (1 << 31) -#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 -# define R300_ZC_FLUSH (1 << 0) -# define R300_ZC_FREE (1 << 1) -# define R300_ZC_FLUSH_ALL 0x3 -# define R300_ZC_BUSY (1 << 31) -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c -# define RADEON_RB3D_DC_FLUSH (3 << 0) -# define RADEON_RB3D_DC_FREE (3 << 2) -# define RADEON_RB3D_DC_FLUSH_ALL 0xf -# define RADEON_RB3D_DC_BUSY (1 << 31) -#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c -# define R300_RB3D_DC_FINISH (1 << 4) -#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c -# define RADEON_Z_TEST_MASK (7 << 4) -# define RADEON_Z_TEST_ALWAYS (7 << 4) -# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) -# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) -# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) -# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) -# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) -# define RADEON_FORCE_Z_DIRTY (1 << 29) -# define RADEON_Z_WRITE_ENABLE (1 << 30) -# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) -#define RADEON_RBBM_SOFT_RESET 0x00f0 -# define RADEON_SOFT_RESET_CP (1 << 0) -# define RADEON_SOFT_RESET_HI (1 << 1) -# define RADEON_SOFT_RESET_SE (1 << 2) -# define RADEON_SOFT_RESET_RE (1 << 3) -# define RADEON_SOFT_RESET_PP (1 << 4) -# define RADEON_SOFT_RESET_E2 (1 << 5) -# define RADEON_SOFT_RESET_RB (1 << 6) -# define RADEON_SOFT_RESET_HDP (1 << 7) -/* - * 6:0 Available slots in the FIFO - * 8 Host Interface active - * 9 CP request active - * 10 FIFO request active - * 11 Host Interface retry active - * 12 CP retry active - * 13 FIFO retry active - * 14 FIFO pipeline busy - * 15 Event engine busy - * 16 CP command stream busy - * 17 2D engine busy - * 18 2D portion of render backend busy - * 20 3D setup engine busy - * 26 GA engine busy - * 27 CBA 2D engine busy - * 31 2D engine busy or 3D engine busy or FIFO not empty or CP busy or - * command stream queue not empty or Ring Buffer not empty - */ -#define RADEON_RBBM_STATUS 0x0e40 -/* Same as the previous RADEON_RBBM_STATUS; this is a mirror of that register. */ -/* #define RADEON_RBBM_STATUS 0x1740 */ -/* bits 6:0 are dword slots available in the cmd fifo */ -# define RADEON_RBBM_FIFOCNT_MASK 0x007f -# define RADEON_HIRQ_ON_RBB (1 << 8) -# define RADEON_CPRQ_ON_RBB (1 << 9) -# define RADEON_CFRQ_ON_RBB (1 << 10) -# define RADEON_HIRQ_IN_RTBUF (1 << 11) -# define RADEON_CPRQ_IN_RTBUF (1 << 12) -# define RADEON_CFRQ_IN_RTBUF (1 << 13) -# define RADEON_PIPE_BUSY (1 << 14) -# define RADEON_ENG_EV_BUSY (1 << 15) -# define RADEON_CP_CMDSTRM_BUSY (1 << 16) -# define RADEON_E2_BUSY (1 << 17) -# define RADEON_RB2D_BUSY (1 << 18) -# define RADEON_RB3D_BUSY (1 << 19) /* not used on r300 */ -# define RADEON_VAP_BUSY (1 << 20) -# define RADEON_RE_BUSY (1 << 21) /* not used on r300 */ -# define RADEON_TAM_BUSY (1 << 22) /* not used on r300 */ -# define RADEON_TDM_BUSY (1 << 23) /* not used on r300 */ -# define RADEON_PB_BUSY (1 << 24) /* not used on r300 */ -# define RADEON_TIM_BUSY (1 << 25) /* not used on r300 */ -# define RADEON_GA_BUSY (1 << 26) -# define RADEON_CBA2D_BUSY (1 << 27) -# define RADEON_RBBM_ACTIVE (1 << 31) -#define RADEON_RE_LINE_PATTERN 0x1cd0 -#define RADEON_RE_MISC 0x26c4 -#define RADEON_RE_TOP_LEFT 0x26c0 -#define RADEON_RE_WIDTH_HEIGHT 0x1c44 -#define RADEON_RE_STIPPLE_ADDR 0x1cc8 -#define RADEON_RE_STIPPLE_DATA 0x1ccc - -#define RADEON_SCISSOR_TL_0 0x1cd8 -#define RADEON_SCISSOR_BR_0 0x1cdc -#define RADEON_SCISSOR_TL_1 0x1ce0 -#define RADEON_SCISSOR_BR_1 0x1ce4 -#define RADEON_SCISSOR_TL_2 0x1ce8 -#define RADEON_SCISSOR_BR_2 0x1cec -#define RADEON_SE_COORD_FMT 0x1c50 -#define RADEON_SE_CNTL 0x1c4c -# define RADEON_FFACE_CULL_CW (0 << 0) -# define RADEON_BFACE_SOLID (3 << 1) -# define RADEON_FFACE_SOLID (3 << 3) -# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) -# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) -# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) -# define RADEON_ALPHA_SHADE_FLAT (1 << 10) -# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) -# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) -# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) -# define RADEON_FOG_SHADE_FLAT (1 << 14) -# define RADEON_FOG_SHADE_GOURAUD (2 << 14) -# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) -# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) -# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) -# define RADEON_ROUND_MODE_TRUNC (0 << 28) -# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) -#define RADEON_SE_CNTL_STATUS 0x2140 -#define RADEON_SE_LINE_WIDTH 0x1db8 -#define RADEON_SE_VPORT_XSCALE 0x1d98 -#define RADEON_SE_ZBIAS_FACTOR 0x1db0 -#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 -#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 -#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200 -# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16 -# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28 -#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204 -#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208 -# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16 -#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C -#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8 -#define RADEON_SURFACE_ACCESS_CLR 0x0bfc -#define RADEON_SURFACE_CNTL 0x0b00 -# define RADEON_SURF_TRANSLATION_DIS (1 << 8) -# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20) -# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20) -# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20) -# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20) -# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22) -# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22) -# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22) -# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22) -#define RADEON_SURFACE0_INFO 0x0b0c -# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0) -# define RADEON_SURF_TILE_MODE_MASK (3 << 16) -# define RADEON_SURF_TILE_MODE_MACRO (0 << 16) -# define RADEON_SURF_TILE_MODE_MICRO (1 << 16) -# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16) -# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16) -#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 -#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 -# define RADEON_SURF_ADDRESS_FIXED_MASK (0x3ff << 0) -#define RADEON_SURFACE1_INFO 0x0b1c -#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 -#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 -#define RADEON_SURFACE2_INFO 0x0b2c -#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 -#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 -#define RADEON_SURFACE3_INFO 0x0b3c -#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 -#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 -#define RADEON_SURFACE4_INFO 0x0b4c -#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 -#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 -#define RADEON_SURFACE5_INFO 0x0b5c -#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 -#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 -#define RADEON_SURFACE6_INFO 0x0b6c -#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 -#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 -#define RADEON_SURFACE7_INFO 0x0b7c -#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 -#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 -#define RADEON_SW_SEMAPHORE 0x013c - -#define RADEON_WAIT_UNTIL 0x1720 -# define RADEON_WAIT_CRTC_PFLIP (1 << 0) -# define RADEON_WAIT_2D_IDLE (1 << 14) -# define RADEON_WAIT_3D_IDLE (1 << 15) -# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) -# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) -# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) - -#define RADEON_RB3D_ZMASKOFFSET 0x3234 -#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c -# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) -# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) - -/* CP registers */ -#define RADEON_CP_ME_RAM_ADDR 0x07d4 -#define RADEON_CP_ME_RAM_RADDR 0x07d8 -#define RADEON_CP_ME_RAM_DATAH 0x07dc -#define RADEON_CP_ME_RAM_DATAL 0x07e0 - -#define RADEON_CP_RB_BASE 0x0700 -#define RADEON_CP_RB_CNTL 0x0704 -# define RADEON_BUF_SWAP_32BIT (2 << 16) -# define RADEON_RB_NO_UPDATE (1 << 27) -#define RADEON_CP_RB_RPTR_ADDR 0x070c -#define RADEON_CP_RB_RPTR 0x0710 -#define RADEON_CP_RB_WPTR 0x0714 - -#define RADEON_CP_RB_WPTR_DELAY 0x0718 -# define RADEON_PRE_WRITE_TIMER_SHIFT 0 -# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 - -#define RADEON_CP_IB_BASE 0x0738 - -#define RADEON_CP_CSQ_CNTL 0x0740 -# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) -# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) -# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) -# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) -# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) -# define RADEON_CSQ_PRIBM_INDBM (4 << 28) -# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) - -#define RADEON_AIC_CNTL 0x01d0 -# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -#define RADEON_AIC_STAT 0x01d4 -#define RADEON_AIC_PT_BASE 0x01d8 -#define RADEON_AIC_LO_ADDR 0x01dc -#define RADEON_AIC_HI_ADDR 0x01e0 -#define RADEON_AIC_TLB_ADDR 0x01e4 -#define RADEON_AIC_TLB_DATA 0x01e8 - -/* CP command packets */ -#define RADEON_CP_PACKET0 0x00000000 -# define RADEON_ONE_REG_WR (1 << 15) -#define RADEON_CP_PACKET1 0x40000000 -#define RADEON_CP_PACKET2 0x80000000 -#define RADEON_CP_PACKET3 0xC0000000 -# define RADEON_CP_NOP 0x00001000 -# define RADEON_CP_NEXT_CHAR 0x00001900 -# define RADEON_CP_PLY_NEXTSCAN 0x00001D00 -# define RADEON_CP_SET_SCISSORS 0x00001E00 - /* GEN_INDX_PRIM is unsupported starting with R300 */ -# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 -# define RADEON_WAIT_FOR_IDLE 0x00002600 -# define RADEON_3D_DRAW_VBUF 0x00002800 -# define RADEON_3D_DRAW_IMMD 0x00002900 -# define RADEON_3D_DRAW_INDX 0x00002A00 -# define RADEON_CP_LOAD_PALETTE 0x00002C00 -# define RADEON_3D_LOAD_VBPNTR 0x00002F00 -# define RADEON_MPEG_IDCT_MACROBLOCK 0x00003000 -# define RADEON_MPEG_IDCT_MACROBLOCK_REV 0x00003100 -# define RADEON_3D_CLEAR_ZMASK 0x00003200 -# define RADEON_CP_INDX_BUFFER 0x00003300 -# define RADEON_CP_3D_DRAW_VBUF_2 0x00003400 -# define RADEON_CP_3D_DRAW_IMMD_2 0x00003500 -# define RADEON_CP_3D_DRAW_INDX_2 0x00003600 -# define RADEON_3D_CLEAR_HIZ 0x00003700 -# define RADEON_CP_3D_CLEAR_CMASK 0x00003802 -# define RADEON_CNTL_HOSTDATA_BLT 0x00009400 -# define RADEON_CNTL_PAINT_MULTI 0x00009A00 -# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 -# define RADEON_CNTL_SET_SCISSORS 0xC0001E00 - -#define RADEON_CP_PACKET_MASK 0xC0000000 -#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 -#define RADEON_CP_PACKET0_REG_MASK 0x000007ff -#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff -#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 - -#define RADEON_VTX_Z_PRESENT (1 << 31) -#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3) - -#define RADEON_PRIM_TYPE_NONE (0 << 0) -#define RADEON_PRIM_TYPE_POINT (1 << 0) -#define RADEON_PRIM_TYPE_LINE (2 << 0) -#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0) -#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0) -#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0) -#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0) -#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0) -#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0) -#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) -#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) -#define RADEON_PRIM_TYPE_MASK 0xf -#define RADEON_PRIM_WALK_IND (1 << 4) -#define RADEON_PRIM_WALK_LIST (2 << 4) -#define RADEON_PRIM_WALK_RING (3 << 4) -#define RADEON_COLOR_ORDER_BGRA (0 << 6) -#define RADEON_COLOR_ORDER_RGBA (1 << 6) -#define RADEON_MAOS_ENABLE (1 << 7) -#define RADEON_VTX_FMT_R128_MODE (0 << 8) -#define RADEON_VTX_FMT_RADEON_MODE (1 << 8) -#define RADEON_NUM_VERTICES_SHIFT 16 - -#define RADEON_COLOR_FORMAT_CI8 2 -#define RADEON_COLOR_FORMAT_ARGB1555 3 -#define RADEON_COLOR_FORMAT_RGB565 4 -#define RADEON_COLOR_FORMAT_ARGB8888 6 -#define RADEON_COLOR_FORMAT_RGB332 7 -#define RADEON_COLOR_FORMAT_RGB8 9 -#define RADEON_COLOR_FORMAT_ARGB4444 15 - -#define RADEON_TXFORMAT_I8 0 -#define RADEON_TXFORMAT_AI88 1 -#define RADEON_TXFORMAT_RGB332 2 -#define RADEON_TXFORMAT_ARGB1555 3 -#define RADEON_TXFORMAT_RGB565 4 -#define RADEON_TXFORMAT_ARGB4444 5 -#define RADEON_TXFORMAT_ARGB8888 6 -#define RADEON_TXFORMAT_RGBA8888 7 -#define RADEON_TXFORMAT_Y8 8 -#define RADEON_TXFORMAT_VYUY422 10 -#define RADEON_TXFORMAT_YVYU422 11 -#define RADEON_TXFORMAT_DXT1 12 -#define RADEON_TXFORMAT_DXT23 14 -#define RADEON_TXFORMAT_DXT45 15 - -#define R200_PP_TXCBLEND_0 0x2f00 -#define R200_PP_TXCBLEND_1 0x2f10 -#define R200_PP_TXCBLEND_2 0x2f20 -#define R200_PP_TXCBLEND_3 0x2f30 -#define R200_PP_TXCBLEND_4 0x2f40 -#define R200_PP_TXCBLEND_5 0x2f50 -#define R200_PP_TXCBLEND_6 0x2f60 -#define R200_PP_TXCBLEND_7 0x2f70 -#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 -#define R200_PP_TFACTOR_0 0x2ee0 -#define R200_SE_VTX_FMT_0 0x2088 -#define R200_SE_VAP_CNTL 0x2080 -#define R200_SE_TCL_MATRIX_SEL_0 0x2230 -#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 -#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 -#define R200_PP_TXFILTER_5 0x2ca0 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFILTER_0 0x2c00 -#define R200_PP_TXOFFSET_5 0x2d78 -#define R200_PP_TXOFFSET_4 0x2d60 -#define R200_PP_TXOFFSET_3 0x2d48 -#define R200_PP_TXOFFSET_2 0x2d30 -#define R200_PP_TXOFFSET_1 0x2d18 -#define R200_PP_TXOFFSET_0 0x2d00 - -#define R200_PP_CUBIC_FACES_0 0x2c18 -#define R200_PP_CUBIC_FACES_1 0x2c38 -#define R200_PP_CUBIC_FACES_2 0x2c58 -#define R200_PP_CUBIC_FACES_3 0x2c78 -#define R200_PP_CUBIC_FACES_4 0x2c98 -#define R200_PP_CUBIC_FACES_5 0x2cb8 -#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 -#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c -#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 -#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c -#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 -#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c - -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_SE_VTE_CNTL 0x20b0 -#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 -#define R200_PP_TAM_DEBUG3 0x2d9c -#define R200_PP_CNTL_X 0x2cc4 -#define R200_SE_VAP_CNTL_STATUS 0x2140 -#define R200_RE_SCISSOR_TL_0 0x1cd8 -#define R200_RE_SCISSOR_TL_1 0x1ce0 -#define R200_RE_SCISSOR_TL_2 0x1ce8 -#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_SE_VTX_STATE_CNTL 0x2180 -#define R200_RE_POINTSIZE 0x2648 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 - -#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ -#define RADEON_PP_TEX_SIZE_1 0x1d0c -#define RADEON_PP_TEX_SIZE_2 0x1d14 - -#define RADEON_PP_CUBIC_FACES_0 0x1d24 -#define RADEON_PP_CUBIC_FACES_1 0x1d28 -#define RADEON_PP_CUBIC_FACES_2 0x1d2c -#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */ -#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 -#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 - -#define RADEON_SE_TCL_STATE_FLUSH 0x2284 - -#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 -#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 -#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012 -#define SE_VTE_CNTL__VTX_XY_FMT_MASK 0x00000100 -#define SE_VTE_CNTL__VTX_Z_FMT_MASK 0x00000200 -#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK 0x00000001 -#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK 0x00000002 -#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b -#define R200_3D_DRAW_IMMD_2 0xC0003500 -#define R200_SE_VTX_FMT_1 0x208c -#define R200_RE_CNTL 0x1c50 - -#define R200_RB3D_BLENDCOLOR 0x3218 - -#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 - -#define R200_PP_TRI_PERF 0x2cf8 - -#define R200_PP_AFS_0 0x2f80 -#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ - -#define R200_VAP_PVS_CNTL_1 0x22D0 - -#define R500_D1CRTC_STATUS 0x609c -#define R500_D2CRTC_STATUS 0x689c -#define R500_CRTC_V_BLANK (1<<0) - -#define R500_D1CRTC_FRAME_COUNT 0x60a4 -#define R500_D2CRTC_FRAME_COUNT 0x68a4 - -#define R500_D1MODE_V_COUNTER 0x6530 -#define R500_D2MODE_V_COUNTER 0x6d30 - -#define R500_D1MODE_VBLANK_STATUS 0x6534 -#define R500_D2MODE_VBLANK_STATUS 0x6d34 -#define R500_VBLANK_OCCURED (1<<0) -#define R500_VBLANK_ACK (1<<4) -#define R500_VBLANK_STAT (1<<12) -#define R500_VBLANK_INT (1<<16) - -#define R500_DxMODE_INT_MASK 0x6540 -#define R500_D1MODE_INT_MASK (1<<0) -#define R500_D2MODE_INT_MASK (1<<8) - -#define R500_DISP_INTERRUPT_STATUS 0x7edc -#define R500_D1_VBLANK_INTERRUPT (1 << 4) -#define R500_D2_VBLANK_INTERRUPT (1 << 5) - -/* Constants */ -#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ - -#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0 -#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1 -#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2 -#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 -#define RADEON_LAST_DISPATCH 1 - -#define RADEON_MAX_VB_AGE 0x7fffffff -#define RADEON_MAX_VB_VERTS (0xffff) - -#define RADEON_RING_HIGH_MARK 128 - -#define RADEON_PCIGART_TABLE_SIZE (32*1024) - -#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) -#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) -#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) - -#define RADEON_WRITE_PLL(addr, val) \ -do { \ - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ - RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ -} while (0) - -#define RADEON_WRITE_PCIE(addr, val) \ -do { \ - RADEON_WRITE8(RADEON_PCIE_INDEX, \ - ((addr) & 0xff)); \ - RADEON_WRITE(RADEON_PCIE_DATA, (val)); \ -} while (0) - -#define R500_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \ - RADEON_WRITE(R520_MC_IND_DATA, (val)); \ - RADEON_WRITE(R520_MC_IND_INDEX, 0); \ -} while (0) - -#define RS480_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(RS480_NB_MC_INDEX, \ - ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \ - RADEON_WRITE(RS480_NB_MC_DATA, (val)); \ - RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); \ -} while (0) - -#define RS690_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ - RADEON_WRITE(RS690_MC_DATA, val); \ - RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ -} while (0) - -#define IGP_WRITE_MCIND(addr, val) \ -do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ - RS690_WRITE_MCIND(addr, val); \ - else \ - RS480_WRITE_MCIND(addr, val); \ -} while (0) - -#define CP_PACKET0( reg, n ) \ - (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) -#define CP_PACKET0_TABLE( reg, n ) \ - (RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2)) -#define CP_PACKET1( reg0, reg1 ) \ - (RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2)) -#define CP_PACKET2() \ - (RADEON_CP_PACKET2) -#define CP_PACKET3( pkt, n ) \ - (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) - -/* ================================================================ - * Engine control helper macros - */ - -#define RADEON_WAIT_UNTIL_2D_IDLE() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ - RADEON_WAIT_HOST_IDLECLEAN) ); \ -} while (0) - -#define RADEON_WAIT_UNTIL_3D_IDLE() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ - RADEON_WAIT_HOST_IDLECLEAN) ); \ -} while (0) - -#define RADEON_WAIT_UNTIL_IDLE() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ - RADEON_WAIT_3D_IDLECLEAN | \ - RADEON_WAIT_HOST_IDLECLEAN) ); \ -} while (0) - -#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \ -} while (0) - -#define RADEON_FLUSH_CACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH); \ - } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH); \ - } \ -} while (0) - -#define RADEON_PURGE_CACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \ - } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \ - } \ -} while (0) - -#define RADEON_FLUSH_ZCACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_ZC_FLUSH); \ - } else { \ - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_ZC_FLUSH); \ - } \ -} while (0) - -#define RADEON_PURGE_ZCACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \ - } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_ZC_FLUSH_ALL); \ - } \ -} while (0) - -/* ================================================================ - * Misc helper macros - */ - -/* Perfbox functionality only. - */ -#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \ - u32 head = GET_RING_HEAD( dev_priv ); \ - if (head == dev_priv->ring.tail) \ - dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \ - } \ -} while (0) - -#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ - if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ - int __ret = radeon_do_cp_idle( dev_priv ); \ - if ( __ret ) return __ret; \ - sarea_priv->last_dispatch = 0; \ - radeon_freelist_reset( dev ); \ - } \ -} while (0) - -#define RADEON_DISPATCH_AGE( age ) do { \ - OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \ - OUT_RING( age ); \ -} while (0) - -#define RADEON_FRAME_AGE( age ) do { \ - OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \ - OUT_RING( age ); \ -} while (0) - -#define RADEON_CLEAR_AGE( age ) do { \ - OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \ - OUT_RING( age ); \ -} while (0) - -/* ================================================================ - * Ring control - */ - -#define RADEON_VERBOSE 0 - -#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; - -#define BEGIN_RING( n ) do { \ - if ( RADEON_VERBOSE ) { \ - DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ - } \ - if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ - COMMIT_RING(); \ - radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ - } \ - _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ - ring = dev_priv->ring.start; \ - write = dev_priv->ring.tail; \ - mask = dev_priv->ring.tail_mask; \ -} while (0) - -#define ADVANCE_RING() do { \ - if ( RADEON_VERBOSE ) { \ - DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ - write, dev_priv->ring.tail ); \ - } \ - if (((dev_priv->ring.tail + _nr) & mask) != write) { \ - DRM_ERROR( \ - "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ - ((dev_priv->ring.tail + _nr) & mask), \ - write, __LINE__); \ - } else \ - dev_priv->ring.tail = write; \ -} while (0) - -#define COMMIT_RING() do { \ - /* Flush writes to ring */ \ - DRM_MEMORYBARRIER(); \ - GET_RING_HEAD( dev_priv ); \ - RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ - /* read from PCI bus to ensure correct posting */ \ - RADEON_READ( RADEON_CP_RB_RPTR ); \ -} while (0) - -#define OUT_RING( x ) do { \ - if ( RADEON_VERBOSE ) { \ - DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ - (unsigned int)(x), write ); \ - } \ - ring[write++] = (x); \ - write &= mask; \ -} while (0) - -#define OUT_RING_REG( reg, val ) do { \ - OUT_RING( CP_PACKET0( reg, 0 ) ); \ - OUT_RING( val ); \ -} while (0) - -#define OUT_RING_TABLE( tab, sz ) do { \ - int _size = (sz); \ - int *_tab = (int *)(tab); \ - \ - if (write + _size > mask) { \ - int _i = (mask+1) - write; \ - _size -= _i; \ - while (_i > 0 ) { \ - *(int *)(ring + write) = *_tab++; \ - write++; \ - _i--; \ - } \ - write = 0; \ - _tab += _i; \ - } \ - while (_size > 0) { \ - *(ring + write) = *_tab++; \ - write++; \ - _size--; \ - } \ - write &= mask; \ -} while (0) - -#endif /* __RADEON_DRV_H__ */ diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c deleted file mode 100644 index 56decda..0000000 --- a/drivers/char/drm/radeon_ioc32.c +++ /dev/null @@ -1,424 +0,0 @@ -/** - * \file radeon_ioc32.c - * - * 32-bit ioctl compatibility routines for the Radeon DRM. - * - * \author Paul Mackerras - * - * Copyright (C) Paul Mackerras 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -typedef struct drm_radeon_init32 { - int func; - u32 sarea_priv_offset; - int is_pci; - int cp_mode; - int gart_size; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - u32 fb_offset; - u32 mmio_offset; - u32 ring_offset; - u32 ring_rptr_offset; - u32 buffers_offset; - u32 gart_textures_offset; -} drm_radeon_init32_t; - -static int compat_radeon_cp_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_init32_t init32; - drm_radeon_init_t __user *init; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.is_pci, &init->is_pci) - || __put_user(init32.cp_mode, &init->cp_mode) - || __put_user(init32.gart_size, &init->gart_size) - || __put_user(init32.ring_size, &init->ring_size) - || __put_user(init32.usec_timeout, &init->usec_timeout) - || __put_user(init32.fb_bpp, &init->fb_bpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_bpp, &init->depth_bpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.ring_offset, &init->ring_offset) - || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset) - || __put_user(init32.gart_textures_offset, - &init->gart_textures_offset)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); -} - -typedef struct drm_radeon_clear32 { - unsigned int flags; - unsigned int clear_color; - unsigned int clear_depth; - unsigned int color_mask; - unsigned int depth_mask; /* misnamed field: should be stencil */ - u32 depth_boxes; -} drm_radeon_clear32_t; - -static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_clear32_t clr32; - drm_radeon_clear_t __user *clr; - - if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32))) - return -EFAULT; - - clr = compat_alloc_user_space(sizeof(*clr)); - if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr)) - || __put_user(clr32.flags, &clr->flags) - || __put_user(clr32.clear_color, &clr->clear_color) - || __put_user(clr32.clear_depth, &clr->clear_depth) - || __put_user(clr32.color_mask, &clr->color_mask) - || __put_user(clr32.depth_mask, &clr->depth_mask) - || __put_user((void __user *)(unsigned long)clr32.depth_boxes, - &clr->depth_boxes)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); -} - -typedef struct drm_radeon_stipple32 { - u32 mask; -} drm_radeon_stipple32_t; - -static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_stipple32_t __user *argp = (void __user *)arg; - drm_radeon_stipple_t __user *request; - u32 mask; - - if (get_user(mask, &argp->mask)) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((unsigned int __user *)(unsigned long)mask, - &request->mask)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); -} - -typedef struct drm_radeon_tex_image32 { - unsigned int x, y; /* Blit coordinates */ - unsigned int width, height; - u32 data; -} drm_radeon_tex_image32_t; - -typedef struct drm_radeon_texture32 { - unsigned int offset; - int pitch; - int format; - int width; /* Texture image coordinates */ - int height; - u32 image; -} drm_radeon_texture32_t; - -static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_texture32_t req32; - drm_radeon_texture_t __user *request; - drm_radeon_tex_image32_t img32; - drm_radeon_tex_image_t __user *image; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - if (req32.image == 0) - return -EINVAL; - if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image, - sizeof(img32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request) + sizeof(*image)); - if (!access_ok(VERIFY_WRITE, request, - sizeof(*request) + sizeof(*image))) - return -EFAULT; - image = (drm_radeon_tex_image_t __user *) (request + 1); - - if (__put_user(req32.offset, &request->offset) - || __put_user(req32.pitch, &request->pitch) - || __put_user(req32.format, &request->format) - || __put_user(req32.width, &request->width) - || __put_user(req32.height, &request->height) - || __put_user(image, &request->image) - || __put_user(img32.x, &image->x) - || __put_user(img32.y, &image->y) - || __put_user(img32.width, &image->width) - || __put_user(img32.height, &image->height) - || __put_user((const void __user *)(unsigned long)img32.data, - &image->data)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); -} - -typedef struct drm_radeon_vertex2_32 { - int idx; /* Index of vertex buffer */ - int discard; /* Client finished with buffer? */ - int nr_states; - u32 state; - int nr_prims; - u32 prim; -} drm_radeon_vertex2_32_t; - -static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_vertex2_32_t req32; - drm_radeon_vertex2_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.idx, &request->idx) - || __put_user(req32.discard, &request->discard) - || __put_user(req32.nr_states, &request->nr_states) - || __put_user((void __user *)(unsigned long)req32.state, - &request->state) - || __put_user(req32.nr_prims, &request->nr_prims) - || __put_user((void __user *)(unsigned long)req32.prim, - &request->prim)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); -} - -typedef struct drm_radeon_cmd_buffer32 { - int bufsz; - u32 buf; - int nbox; - u32 boxes; -} drm_radeon_cmd_buffer32_t; - -static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_cmd_buffer32_t req32; - drm_radeon_cmd_buffer_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.bufsz, &request->bufsz) - || __put_user((void __user *)(unsigned long)req32.buf, - &request->buf) - || __put_user(req32.nbox, &request->nbox) - || __put_user((void __user *)(unsigned long)req32.boxes, - &request->boxes)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); -} - -typedef struct drm_radeon_getparam32 { - int param; - u32 value; -} drm_radeon_getparam32_t; - -static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_getparam32_t req32; - drm_radeon_getparam_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); -} - -typedef struct drm_radeon_mem_alloc32 { - int region; - int alignment; - int size; - u32 region_offset; /* offset from start of fb or GART */ -} drm_radeon_mem_alloc32_t; - -static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_mem_alloc32_t req32; - drm_radeon_mem_alloc_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.region, &request->region) - || __put_user(req32.alignment, &request->alignment) - || __put_user(req32.size, &request->size) - || __put_user((int __user *)(unsigned long)req32.region_offset, - &request->region_offset)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); -} - -typedef struct drm_radeon_irq_emit32 { - u32 irq_seq; -} drm_radeon_irq_emit32_t; - -static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_irq_emit32_t req32; - drm_radeon_irq_emit_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((int __user *)(unsigned long)req32.irq_seq, - &request->irq_seq)) - return -EFAULT; - - return drm_ioctl(file->f_path.dentry->d_inode, file, - DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); -} - -/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */ -#if defined (CONFIG_X86_64) || defined(CONFIG_IA64) -typedef struct drm_radeon_setparam32 { - int param; - u64 value; -} __attribute__((packed)) drm_radeon_setparam32_t; - -static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_setparam32_t req32; - drm_radeon_setparam_t __user *request; - - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); -} -#else -#define compat_radeon_cp_setparam NULL -#endif /* X86_64 || IA64 */ - -drm_ioctl_compat_t *radeon_compat_ioctls[] = { - [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, - [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, - [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple, - [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture, - [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2, - [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf, - [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam, - [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam, - [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc, - [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) - fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; - - lock_kernel(); /* XXX for now */ - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - - return ret; -} diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c deleted file mode 100644 index ee40d19..0000000 --- a/drivers/char/drm/radeon_irq.c +++ /dev/null @@ -1,320 +0,0 @@ -/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - * Michel Dänzer - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, - u32 mask) -{ - u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; - if (irqs) - RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); - return irqs; -} - -/* Interrupts - Used for device synchronization and flushing in the - * following circumstances: - * - * - Exclusive FB access with hw idle: - * - Wait for GUI Idle (?) interrupt, then do normal flush. - * - * - Frame throttling, NV_fence: - * - Drop marker irq's into command stream ahead of time. - * - Wait on irq's with lock *not held* - * - Check each for termination condition - * - * - Internally in cp_getbuffer, etc: - * - as above, but wait with lock held??? - * - * NOTE: These functions are misleadingly named -- the irq's aren't - * tied to dma at all, this is just a hangover from dri prehistory. - */ - -irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - u32 stat; - - /* Only consider the bits we're interested in - others could be used - * outside the DRM - */ - stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | - RADEON_CRTC_VBLANK_STAT | - RADEON_CRTC2_VBLANK_STAT)); - if (!stat) - return IRQ_NONE; - - stat &= dev_priv->irq_enable_reg; - - /* SW interrupt */ - if (stat & RADEON_SW_INT_TEST) { - DRM_WAKEUP(&dev_priv->swi_queue); - } - - /* VBLANK interrupt */ - if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { - int vblank_crtc = dev_priv->vblank_crtc; - - if ((vblank_crtc & - (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == - (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { - if (stat & RADEON_CRTC_VBLANK_STAT) - atomic_inc(&dev->vbl_received); - if (stat & RADEON_CRTC2_VBLANK_STAT) - atomic_inc(&dev->vbl_received2); - } else if (((stat & RADEON_CRTC_VBLANK_STAT) && - (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || - ((stat & RADEON_CRTC2_VBLANK_STAT) && - (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) - atomic_inc(&dev->vbl_received); - - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); - } - - return IRQ_HANDLED; -} - -static int radeon_emit_irq(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - unsigned int ret; - RING_LOCALS; - - atomic_inc(&dev_priv->swi_emitted); - ret = atomic_read(&dev_priv->swi_emitted); - - BEGIN_RING(4); - OUT_RING_REG(RADEON_LAST_SWI_REG, ret); - OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); - ADVANCE_RING(); - COMMIT_RING(); - - return ret; -} - -static int radeon_wait_irq(struct drm_device * dev, int swi_nr) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - int ret = 0; - - if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) - return 0; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, - RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); - - return ret; -} - -static int radeon_driver_vblank_do_wait(struct drm_device * dev, - unsigned int *sequence, int crtc) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - unsigned int cur_vblank; - int ret = 0; - int ack = 0; - atomic_t *counter; - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if (crtc == DRM_RADEON_VBLANK_CRTC1) { - counter = &dev->vbl_received; - ack |= RADEON_CRTC_VBLANK_STAT; - } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { - counter = &dev->vbl_received2; - ack |= RADEON_CRTC2_VBLANK_STAT; - } else - return -EINVAL; - - radeon_acknowledge_irqs(dev_priv, ack); - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using vertical blanks... - */ - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(counter)) - - *sequence) <= (1 << 23))); - - *sequence = cur_vblank; - - return ret; -} - -int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) -{ - return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); -} - -int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) -{ - return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); -} - -/* Needs the lock as it touches the ring. - */ -int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_irq_emit_t *emit = data; - int result; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - result = radeon_emit_irq(dev); - - if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -/* Doesn't need the hardware lock. - */ -int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_irq_wait_t *irqwait = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - return radeon_wait_irq(dev, irqwait->irq_seq); -} - -void radeon_enable_interrupt(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - - dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; - if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) - dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; - - if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) - dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; - - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); - dev_priv->irq_enabled = 1; -} - -/* drm_dma.h hooks -*/ -void radeon_driver_irq_preinstall(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - - /* Disable *all* interrupts */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - - /* Clear bits if they're already high */ - radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | - RADEON_CRTC_VBLANK_STAT | - RADEON_CRTC2_VBLANK_STAT)); -} - -void radeon_driver_irq_postinstall(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - - atomic_set(&dev_priv->swi_emitted, 0); - DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - - radeon_enable_interrupt(dev); -} - -void radeon_driver_irq_uninstall(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - if (!dev_priv) - return; - - dev_priv->irq_enabled = 0; - - /* Disable *all* interrupts */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); -} - - -int radeon_vblank_crtc_get(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - u32 flag; - u32 value; - - flag = RADEON_READ(RADEON_GEN_INT_CNTL); - value = 0; - - if (flag & RADEON_CRTC_VBLANK_MASK) - value |= DRM_RADEON_VBLANK_CRTC1; - - if (flag & RADEON_CRTC2_VBLANK_MASK) - value |= DRM_RADEON_VBLANK_CRTC2; - return value; -} - -int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) -{ - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { - DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); - return -EINVAL; - } - dev_priv->vblank_crtc = (unsigned int)value; - radeon_enable_interrupt(dev); - return 0; -} diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c deleted file mode 100644 index 4af5286..0000000 --- a/drivers/char/drm/radeon_mem.c +++ /dev/null @@ -1,302 +0,0 @@ -/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -/* Very simple allocator for GART memory, working on a static range - * already mapped into each client's address space. - */ - -static struct mem_block *split_block(struct mem_block *p, int start, int size, - struct drm_file *file_priv) -{ - /* Maybe cut off the start of an existing block */ - if (start > p->start) { - struct mem_block *newblock = - drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); - if (!newblock) - goto out; - newblock->start = start; - newblock->size = p->size - (start - p->start); - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size -= newblock->size; - p = newblock; - } - - /* Maybe cut off the end of an existing block */ - if (size < p->size) { - struct mem_block *newblock = - drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); - if (!newblock) - goto out; - newblock->start = start + size; - newblock->size = p->size - size; - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size = size; - } - - out: - /* Our block is in the middle */ - p->file_priv = file_priv; - return p; -} - -static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, struct drm_file *file_priv) -{ - struct mem_block *p; - int mask = (1 << align2) - 1; - - list_for_each(p, heap) { - int start = (p->start + mask) & ~mask; - if (p->file_priv == NULL && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - - return NULL; -} - -static struct mem_block *find_block(struct mem_block *heap, int start) -{ - struct mem_block *p; - - list_for_each(p, heap) - if (p->start == start) - return p; - - return NULL; -} - -static void free_block(struct mem_block *p) -{ - p->file_priv = NULL; - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - if (p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_BUFS); - } - - if (p->prev->file_priv == NULL) { - struct mem_block *q = p->prev; - q->size += p->size; - q->next = p->next; - q->next->prev = q; - drm_free(p, sizeof(*q), DRM_MEM_BUFS); - } -} - -/* Initialize. How to check for an uninitialized heap? - */ -static int init_heap(struct mem_block **heap, int start, int size) -{ - struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); - - if (!blocks) - return -ENOMEM; - - *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); - if (!*heap) { - drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); - return -ENOMEM; - } - - blocks->start = start; - blocks->size = size; - blocks->file_priv = NULL; - blocks->next = blocks->prev = *heap; - - memset(*heap, 0, sizeof(**heap)); - (*heap)->file_priv = (struct drm_file *) - 1; - (*heap)->next = (*heap)->prev = blocks; - return 0; -} - -/* Free all blocks associated with the releasing file. - */ -void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap || !heap->next) - return; - - list_for_each(p, heap) { - if (p->file_priv == file_priv) - p->file_priv = NULL; - } - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - list_for_each(p, heap) { - while (p->file_priv == NULL && p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - drm_free(q, sizeof(*q), DRM_MEM_DRIVER); - } - } -} - -/* Shutdown. - */ -void radeon_mem_takedown(struct mem_block **heap) -{ - struct mem_block *p; - - if (!*heap) - return; - - for (p = (*heap)->next; p != *heap;) { - struct mem_block *q = p; - p = p->next; - drm_free(q, sizeof(*q), DRM_MEM_DRIVER); - } - - drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER); - *heap = NULL; -} - -/* IOCTL HANDLERS */ - -static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region) -{ - switch (region) { - case RADEON_MEM_REGION_GART: - return &dev_priv->gart_heap; - case RADEON_MEM_REGION_FB: - return &dev_priv->fb_heap; - default: - return NULL; - } -} - -int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_alloc_t *alloc = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, alloc->region); - if (!heap || !*heap) - return -EFAULT; - - /* Make things easier on ourselves: all allocations at least - * 4k aligned. - */ - if (alloc->alignment < 12) - alloc->alignment = 12; - - block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); - - if (!block) - return -ENOMEM; - - if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, - sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_free_t *memfree = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, memfree->region); - if (!heap || !*heap) - return -EFAULT; - - block = find_block(*heap, memfree->region_offset); - if (!block) - return -EFAULT; - - if (block->file_priv != file_priv) - return -EPERM; - - free_block(block); - return 0; -} - -int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_init_heap_t *initheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, initheap->region); - if (!heap) - return -EFAULT; - - if (*heap) { - DRM_ERROR("heap already initialized?"); - return -EFAULT; - } - - return init_heap(heap, initheap->start, initheap->size); -} diff --git a/drivers/char/drm/radeon_microcode.h b/drivers/char/drm/radeon_microcode.h deleted file mode 100644 index a348c9e..0000000 --- a/drivers/char/drm/radeon_microcode.h +++ /dev/null @@ -1,1844 +0,0 @@ -/* - * Copyright 2007 Advanced Micro Devices, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef RADEON_MICROCODE_H -#define RADEON_MICROCODE_H - -/* production radeon ucode r1xx-r6xx */ -static const u32 R100_cp_microcode[][2] = { - { 0x21007000, 0000000000 }, - { 0x20007000, 0000000000 }, - { 0x000000b4, 0x00000004 }, - { 0x000000b8, 0x00000004 }, - { 0x6f5b4d4c, 0000000000 }, - { 0x4c4c427f, 0000000000 }, - { 0x5b568a92, 0000000000 }, - { 0x4ca09c6d, 0000000000 }, - { 0xad4c4c4c, 0000000000 }, - { 0x4ce1af3d, 0000000000 }, - { 0xd8afafaf, 0000000000 }, - { 0xd64c4cdc, 0000000000 }, - { 0x4cd10d10, 0000000000 }, - { 0x000f0000, 0x00000016 }, - { 0x362f242d, 0000000000 }, - { 0x00000012, 0x00000004 }, - { 0x000f0000, 0x00000016 }, - { 0x362f282d, 0000000000 }, - { 0x000380e7, 0x00000002 }, - { 0x04002c97, 0x00000002 }, - { 0x000f0001, 0x00000016 }, - { 0x333a3730, 0000000000 }, - { 0x000077ef, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000021, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000021, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000021, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00000017, 0x00000004 }, - { 0x0003802b, 0x00000002 }, - { 0x040067e0, 0x00000002 }, - { 0x00000017, 0x00000004 }, - { 0x000077e0, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x000037e1, 0x00000002 }, - { 0x040067e1, 0x00000006 }, - { 0x000077e0, 0x00000002 }, - { 0x000077e1, 0x00000002 }, - { 0x000077e1, 0x00000006 }, - { 0xffffffff, 0000000000 }, - { 0x10000000, 0000000000 }, - { 0x0003802b, 0x00000002 }, - { 0x040067e0, 0x00000006 }, - { 0x00007675, 0x00000002 }, - { 0x00007676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0003802c, 0x00000002 }, - { 0x04002676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0000002f, 0x00000018 }, - { 0x0000002f, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x00000030, 0x00000018 }, - { 0x00000030, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x01605000, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00098000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x64c0603e, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00080000, 0x00000016 }, - { 0000000000, 0000000000 }, - { 0x0400251d, 0x00000002 }, - { 0x00007580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x04002580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x00000049, 0x00000004 }, - { 0x00005000, 0000000000 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x00019000, 0x00000002 }, - { 0x00011055, 0x00000014 }, - { 0x00000055, 0x00000012 }, - { 0x0400250f, 0x00000002 }, - { 0x0000504f, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00007565, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x00000058, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x01e655b4, 0x00000002 }, - { 0x4401b0e4, 0x00000002 }, - { 0x01c110e4, 0x00000002 }, - { 0x26667066, 0x00000018 }, - { 0x040c2565, 0x00000002 }, - { 0x00000066, 0x00000018 }, - { 0x04002564, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x0000005d, 0x00000004 }, - { 0x00401069, 0x00000008 }, - { 0x00101000, 0x00000002 }, - { 0x000d80ff, 0x00000002 }, - { 0x0080006c, 0x00000008 }, - { 0x000f9000, 0x00000002 }, - { 0x000e00ff, 0x00000002 }, - { 0000000000, 0x00000006 }, - { 0x0000008f, 0x00000018 }, - { 0x0000005b, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00007576, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00009000, 0x00000002 }, - { 0x00041000, 0x00000002 }, - { 0x0c00350e, 0x00000002 }, - { 0x00049000, 0x00000002 }, - { 0x00051000, 0x00000002 }, - { 0x01e785f8, 0x00000002 }, - { 0x00200000, 0x00000002 }, - { 0x0060007e, 0x0000000c }, - { 0x00007563, 0x00000002 }, - { 0x006075f0, 0x00000021 }, - { 0x20007073, 0x00000004 }, - { 0x00005073, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00007576, 0x00000002 }, - { 0x00007577, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x0000750f, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00600083, 0x0000000c }, - { 0x006075f0, 0x00000021 }, - { 0x000075f8, 0x00000002 }, - { 0x00000083, 0x00000004 }, - { 0x000a750e, 0x00000002 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x0020750f, 0x00000002 }, - { 0x00600086, 0x00000004 }, - { 0x00007570, 0x00000002 }, - { 0x00007571, 0x00000002 }, - { 0x00007572, 0x00000006 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00005000, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00007568, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000095, 0x0000000c }, - { 0x00058000, 0x00000002 }, - { 0x0c607562, 0x00000002 }, - { 0x00000097, 0x00000004 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x00600096, 0x00000004 }, - { 0x400070e5, 0000000000 }, - { 0x000380e6, 0x00000002 }, - { 0x040025c5, 0x00000002 }, - { 0x000380e5, 0x00000002 }, - { 0x000000a8, 0x0000001c }, - { 0x000650aa, 0x00000018 }, - { 0x040025bb, 0x00000002 }, - { 0x000610ab, 0x00000018 }, - { 0x040075bc, 0000000000 }, - { 0x000075bb, 0x00000002 }, - { 0x000075bc, 0000000000 }, - { 0x00090000, 0x00000006 }, - { 0x00090000, 0x00000002 }, - { 0x000d8002, 0x00000006 }, - { 0x00007832, 0x00000002 }, - { 0x00005000, 0x00000002 }, - { 0x000380e7, 0x00000002 }, - { 0x04002c97, 0x00000002 }, - { 0x00007820, 0x00000002 }, - { 0x00007821, 0x00000002 }, - { 0x00007800, 0000000000 }, - { 0x01200000, 0x00000002 }, - { 0x20077000, 0x00000002 }, - { 0x01200000, 0x00000002 }, - { 0x20007000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x0120751b, 0x00000002 }, - { 0x8040750a, 0x00000002 }, - { 0x8040750b, 0x00000002 }, - { 0x00110000, 0x00000002 }, - { 0x000380e5, 0x00000002 }, - { 0x000000c6, 0x0000001c }, - { 0x000610ab, 0x00000018 }, - { 0x844075bd, 0x00000002 }, - { 0x000610aa, 0x00000018 }, - { 0x840075bb, 0x00000002 }, - { 0x000610ab, 0x00000018 }, - { 0x844075bc, 0x00000002 }, - { 0x000000c9, 0x00000004 }, - { 0x804075bd, 0x00000002 }, - { 0x800075bb, 0x00000002 }, - { 0x804075bc, 0x00000002 }, - { 0x00108000, 0x00000002 }, - { 0x01400000, 0x00000002 }, - { 0x006000cd, 0x0000000c }, - { 0x20c07000, 0x00000020 }, - { 0x000000cf, 0x00000012 }, - { 0x00800000, 0x00000006 }, - { 0x0080751d, 0x00000006 }, - { 0000000000, 0000000000 }, - { 0x0000775c, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00661000, 0x00000002 }, - { 0x0460275d, 0x00000020 }, - { 0x00004000, 0000000000 }, - { 0x01e00830, 0x00000002 }, - { 0x21007000, 0000000000 }, - { 0x6464614d, 0000000000 }, - { 0x69687420, 0000000000 }, - { 0x00000073, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x00005000, 0x00000002 }, - { 0x000380d0, 0x00000002 }, - { 0x040025e0, 0x00000002 }, - { 0x000075e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000380e0, 0x00000002 }, - { 0x04002394, 0x00000002 }, - { 0x00005000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x00000008, 0000000000 }, - { 0x00000004, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - -static const u32 R200_cp_microcode[][2] = { - { 0x21007000, 0000000000 }, - { 0x20007000, 0000000000 }, - { 0x000000bf, 0x00000004 }, - { 0x000000c3, 0x00000004 }, - { 0x7a685e5d, 0000000000 }, - { 0x5d5d5588, 0000000000 }, - { 0x68659197, 0000000000 }, - { 0x5da19f78, 0000000000 }, - { 0x5d5d5d5d, 0000000000 }, - { 0x5dee5d50, 0000000000 }, - { 0xf2acacac, 0000000000 }, - { 0xe75df9e9, 0000000000 }, - { 0xb1dd0e11, 0000000000 }, - { 0xe2afafaf, 0000000000 }, - { 0x000f0000, 0x00000016 }, - { 0x452f232d, 0000000000 }, - { 0x00000013, 0x00000004 }, - { 0x000f0000, 0x00000016 }, - { 0x452f272d, 0000000000 }, - { 0x000f0001, 0x00000016 }, - { 0x3e4d4a37, 0000000000 }, - { 0x000077ef, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000020, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000020, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00061000, 0x00000002 }, - { 0x00000020, 0x0000001a }, - { 0x00004000, 0x0000001e }, - { 0x00000016, 0x00000004 }, - { 0x0003802a, 0x00000002 }, - { 0x040067e0, 0x00000002 }, - { 0x00000016, 0x00000004 }, - { 0x000077e0, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x000037e1, 0x00000002 }, - { 0x040067e1, 0x00000006 }, - { 0x000077e0, 0x00000002 }, - { 0x000077e1, 0x00000002 }, - { 0x000077e1, 0x00000006 }, - { 0xffffffff, 0000000000 }, - { 0x10000000, 0000000000 }, - { 0x07f007f0, 0000000000 }, - { 0x0003802a, 0x00000002 }, - { 0x040067e0, 0x00000006 }, - { 0x0003802c, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002743, 0x00000002 }, - { 0x00007675, 0x00000002 }, - { 0x00007676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0003802c, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002743, 0x00000002 }, - { 0x00007676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0003802b, 0x00000002 }, - { 0x04002676, 0x00000002 }, - { 0x00007677, 0x00000002 }, - { 0x0003802c, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002743, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0003802c, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002741, 0x00000002 }, - { 0x04002743, 0x00000002 }, - { 0x00007678, 0x00000006 }, - { 0x0000002f, 0x00000018 }, - { 0x0000002f, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x00000037, 0x00000018 }, - { 0x00000037, 0x00000018 }, - { 0000000000, 0x00000006 }, - { 0x01605000, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00098000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x64c06051, 0x00000004 }, - { 0x00080000, 0x00000016 }, - { 0000000000, 0000000000 }, - { 0x0400251d, 0x00000002 }, - { 0x00007580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x04002580, 0x00000002 }, - { 0x00067581, 0x00000002 }, - { 0x0000005a, 0x00000004 }, - { 0x00005000, 0000000000 }, - { 0x00061000, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x00019000, 0x00000002 }, - { 0x00011064, 0x00000014 }, - { 0x00000064, 0x00000012 }, - { 0x0400250f, 0x00000002 }, - { 0x0000505e, 0x00000004 }, - { 0x00007565, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x00000065, 0x00000004 }, - { 0x01e655b4, 0x00000002 }, - { 0x4401b0f0, 0x00000002 }, - { 0x01c110f0, 0x00000002 }, - { 0x26667071, 0x00000018 }, - { 0x040c2565, 0x00000002 }, - { 0x00000071, 0x00000018 }, - { 0x04002564, 0x00000002 }, - { 0x00007566, 0x00000002 }, - { 0x00000068, 0x00000004 }, - { 0x00401074, 0x00000008 }, - { 0x00101000, 0x00000002 }, - { 0x000d80ff, 0x00000002 }, - { 0x00800077, 0x00000008 }, - { 0x000f9000, 0x00000002 }, - { 0x000e00ff, 0x00000002 }, - { 0000000000, 0x00000006 }, - { 0x00000094, 0x00000018 }, - { 0x00000068, 0x00000004 }, - { 0x00007576, 0x00000002 }, - { 0x00065000, 0x00000002 }, - { 0x00009000, 0x00000002 }, - { 0x00041000, 0x00000002 }, - { 0x0c00350e, 0x00000002 }, - { 0x00049000, 0x00000002 }, - { 0x00051000, 0x00000002 }, - { 0x01e785f8, 0x00000002 }, - { 0x00200000, 0x00000002 }, - { 0x00600087, 0x0000000c }, - { 0x00007563, 0x00000002 }, - { 0x006075f0, 0x00000021 }, - { 0x2000707c, 0x00000004 }, - { 0x0000507c, 0x00000004 }, - { 0x00007576, 0x00000002 }, - { 0x00007577, 0x00000002 }, - { 0x0000750e, 0x00000002 }, - { 0x0000750f, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x0060008a, 0x0000000c }, - { 0x006075f0, 0x00000021 }, - { 0x000075f8, 0x00000002 }, - { 0x0000008a, 0x00000004 }, - { 0x000a750e, 0x00000002 }, - { 0x0020750f, 0x00000002 }, - { 0x0060008d, 0x00000004 }, - { 0x00007570, 0x00000002 }, - { 0x00007571, 0x00000002 }, - { 0x00007572, 0x00000006 }, - { 0x00005000, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00007568, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x00000098, 0x0000000c }, - { 0x00058000, 0x00000002 }, - { 0x0c607562, 0x00000002 }, - { 0x0000009a, 0x00000004 }, - { 0x00600099, 0x00000004 }, - { 0x400070f1, 0000000000 }, - { 0x000380f1, 0x00000002 }, - { 0x000000a7, 0x0000001c }, - { 0x000650a9, 0x00000018 }, - { 0x040025bb, 0x00000002 }, - { 0x000610aa, 0x00000018 }, - { 0x040075bc, 0000000000 }, - { 0x000075bb, 0x00000002 }, - { 0x000075bc, 0000000000 }, - { 0x00090000, 0x00000006 }, - { 0x00090000, 0x00000002 }, - { 0x000d8002, 0x00000006 }, - { 0x00005000, 0x00000002 }, - { 0x00007821, 0x00000002 }, - { 0x00007800, 0000000000 }, - { 0x00007821, 0x00000002 }, - { 0x00007800, 0000000000 }, - { 0x01665000, 0x00000002 }, - { 0x000a0000, 0x00000002 }, - { 0x000671cc, 0x00000002 }, - { 0x0286f1cd, 0x00000002 }, - { 0x000000b7, 0x00000010 }, - { 0x21007000, 0000000000 }, - { 0x000000be, 0x0000001c }, - { 0x00065000, 0x00000002 }, - { 0x000a0000, 0x00000002 }, - { 0x00061000, 0x00000002 }, - { 0x000b0000, 0x00000002 }, - { 0x38067000, 0x00000002 }, - { 0x000a00ba, 0x00000004 }, - { 0x20007000, 0000000000 }, - { 0x01200000, 0x00000002 }, - { 0x20077000, 0x00000002 }, - { 0x01200000, 0x00000002 }, - { 0x20007000, 0000000000 }, - { 0x00061000, 0x00000002 }, - { 0x0120751b, 0x00000002 }, - { 0x8040750a, 0x00000002 }, - { 0x8040750b, 0x00000002 }, - { 0x00110000, 0x00000002 }, - { 0x000380f1, 0x00000002 }, - { 0x000000d1, 0x0000001c }, - { 0x000610aa, 0x00000018 }, - { 0x844075bd, 0x00000002 }, - { 0x000610a9, 0x00000018 }, - { 0x840075bb, 0x00000002 }, - { 0x000610aa, 0x00000018 }, - { 0x844075bc, 0x00000002 }, - { 0x000000d4, 0x00000004 }, - { 0x804075bd, 0x00000002 }, - { 0x800075bb, 0x00000002 }, - { 0x804075bc, 0x00000002 }, - { 0x00108000, 0x00000002 }, - { 0x01400000, 0x00000002 }, - { 0x006000d8, 0x0000000c }, - { 0x20c07000, 0x00000020 }, - { 0x000000da, 0x00000012 }, - { 0x00800000, 0x00000006 }, - { 0x0080751d, 0x00000006 }, - { 0x000025bb, 0x00000002 }, - { 0x000040d4, 0x00000004 }, - { 0x0000775c, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00661000, 0x00000002 }, - { 0x0460275d, 0x00000020 }, - { 0x00004000, 0000000000 }, - { 0x00007999, 0x00000002 }, - { 0x00a05000, 0x00000002 }, - { 0x00661000, 0x00000002 }, - { 0x0460299b, 0x00000020 }, - { 0x00004000, 0000000000 }, - { 0x01e00830, 0x00000002 }, - { 0x21007000, 0000000000 }, - { 0x00005000, 0x00000002 }, - { 0x00038056, 0x00000002 }, - { 0x040025e0, 0x00000002 }, - { 0x000075e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000380ed, 0x00000002 }, - { 0x04007394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x000078c4, 0x00000002 }, - { 0x000078c5, 0x00000002 }, - { 0x000078c6, 0x00000002 }, - { 0x00007924, 0x00000002 }, - { 0x00007925, 0x00000002 }, - { 0x00007926, 0x00000002 }, - { 0x000000f2, 0x00000004 }, - { 0x00007924, 0x00000002 }, - { 0x00007925, 0x00000002 }, - { 0x00007926, 0x00000002 }, - { 0x000000f9, 0x00000004 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - -static const u32 R300_cp_microcode[][2] = { - { 0x4200e000, 0000000000 }, - { 0x4000e000, 0000000000 }, - { 0x000000ae, 0x00000008 }, - { 0x000000b2, 0x00000008 }, - { 0x67554b4a, 0000000000 }, - { 0x4a4a4475, 0000000000 }, - { 0x55527d83, 0000000000 }, - { 0x4a8c8b65, 0000000000 }, - { 0x4aef4af6, 0000000000 }, - { 0x4ae14a4a, 0000000000 }, - { 0xe4979797, 0000000000 }, - { 0xdb4aebdd, 0000000000 }, - { 0x9ccc4a4a, 0000000000 }, - { 0xd1989898, 0000000000 }, - { 0x4a0f9ad6, 0000000000 }, - { 0x000ca000, 0x00000004 }, - { 0x000d0012, 0x00000038 }, - { 0x0000e8b4, 0x00000004 }, - { 0x000d0014, 0x00000038 }, - { 0x0000e8b6, 0x00000004 }, - { 0x000d0016, 0x00000038 }, - { 0x0000e854, 0x00000004 }, - { 0x000d0018, 0x00000038 }, - { 0x0000e855, 0x00000004 }, - { 0x000d001a, 0x00000038 }, - { 0x0000e856, 0x00000004 }, - { 0x000d001c, 0x00000038 }, - { 0x0000e857, 0x00000004 }, - { 0x000d001e, 0x00000038 }, - { 0x0000e824, 0x00000004 }, - { 0x000d0020, 0x00000038 }, - { 0x0000e825, 0x00000004 }, - { 0x000d0022, 0x00000038 }, - { 0x0000e830, 0x00000004 }, - { 0x000d0024, 0x00000038 }, - { 0x0000f0c0, 0x00000004 }, - { 0x000d0026, 0x00000038 }, - { 0x0000f0c1, 0x00000004 }, - { 0x000d0028, 0x00000038 }, - { 0x0000f041, 0x00000004 }, - { 0x000d002a, 0x00000038 }, - { 0x0000f184, 0x00000004 }, - { 0x000d002c, 0x00000038 }, - { 0x0000f185, 0x00000004 }, - { 0x000d002e, 0x00000038 }, - { 0x0000f186, 0x00000004 }, - { 0x000d0030, 0x00000038 }, - { 0x0000f187, 0x00000004 }, - { 0x000d0032, 0x00000038 }, - { 0x0000f180, 0x00000004 }, - { 0x000d0034, 0x00000038 }, - { 0x0000f393, 0x00000004 }, - { 0x000d0036, 0x00000038 }, - { 0x0000f38a, 0x00000004 }, - { 0x000d0038, 0x00000038 }, - { 0x0000f38e, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000043, 0x00000018 }, - { 0x00cce800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x0000003a, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x2000451d, 0x00000004 }, - { 0x0000e580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x08004580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x00000047, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x00032000, 0x00000004 }, - { 0x00022051, 0x00000028 }, - { 0x00000051, 0x00000024 }, - { 0x0800450f, 0x00000004 }, - { 0x0000a04b, 0x00000008 }, - { 0x0000e565, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000052, 0x00000008 }, - { 0x03cca5b4, 0x00000004 }, - { 0x05432000, 0x00000004 }, - { 0x00022000, 0x00000004 }, - { 0x4ccce05e, 0x00000030 }, - { 0x08274565, 0x00000004 }, - { 0x0000005e, 0x00000030 }, - { 0x08004564, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000055, 0x00000008 }, - { 0x00802061, 0x00000010 }, - { 0x00202000, 0x00000004 }, - { 0x001b00ff, 0x00000004 }, - { 0x01000064, 0x00000010 }, - { 0x001f2000, 0x00000004 }, - { 0x001c00ff, 0x00000004 }, - { 0000000000, 0x0000000c }, - { 0x00000080, 0x00000030 }, - { 0x00000055, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x00012000, 0x00000004 }, - { 0x00082000, 0x00000004 }, - { 0x1800650e, 0x00000004 }, - { 0x00092000, 0x00000004 }, - { 0x000a2000, 0x00000004 }, - { 0x000f0000, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x00000074, 0x00000018 }, - { 0x0000e563, 0x00000004 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x00000069, 0x00000008 }, - { 0x0000a069, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x0000e577, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x0000e50f, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000077, 0x00000018 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x00000077, 0x00000008 }, - { 0x0014e50e, 0x00000004 }, - { 0x0040e50f, 0x00000004 }, - { 0x00c0007a, 0x00000008 }, - { 0x0000e570, 0x00000004 }, - { 0x0000e571, 0x00000004 }, - { 0x0000e572, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000e568, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00000084, 0x00000018 }, - { 0x000b0000, 0x00000004 }, - { 0x18c0e562, 0x00000004 }, - { 0x00000086, 0x00000008 }, - { 0x00c00085, 0x00000008 }, - { 0x000700e3, 0x00000004 }, - { 0x00000092, 0x00000038 }, - { 0x000ca094, 0x00000030 }, - { 0x080045bb, 0x00000004 }, - { 0x000c2095, 0x00000030 }, - { 0x0800e5bc, 0000000000 }, - { 0x0000e5bb, 0x00000004 }, - { 0x0000e5bc, 0000000000 }, - { 0x00120000, 0x0000000c }, - { 0x00120000, 0x00000004 }, - { 0x001b0002, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e800, 0000000000 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e82e, 0000000000 }, - { 0x02cca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000ce1cc, 0x00000004 }, - { 0x050de1cd, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x000000a4, 0x00000018 }, - { 0x00c0a000, 0x00000004 }, - { 0x000000a1, 0x00000008 }, - { 0x000000a6, 0x00000020 }, - { 0x4200e000, 0000000000 }, - { 0x000000ad, 0x00000038 }, - { 0x000ca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00160000, 0x00000004 }, - { 0x700ce000, 0x00000004 }, - { 0x001400a9, 0x00000008 }, - { 0x4000e000, 0000000000 }, - { 0x02400000, 0x00000004 }, - { 0x400ee000, 0x00000004 }, - { 0x02400000, 0x00000004 }, - { 0x4000e000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0240e51b, 0x00000004 }, - { 0x0080e50a, 0x00000005 }, - { 0x0080e50b, 0x00000005 }, - { 0x00220000, 0x00000004 }, - { 0x000700e3, 0x00000004 }, - { 0x000000c0, 0x00000038 }, - { 0x000c2095, 0x00000030 }, - { 0x0880e5bd, 0x00000005 }, - { 0x000c2094, 0x00000030 }, - { 0x0800e5bb, 0x00000005 }, - { 0x000c2095, 0x00000030 }, - { 0x0880e5bc, 0x00000005 }, - { 0x000000c3, 0x00000008 }, - { 0x0080e5bd, 0x00000005 }, - { 0x0000e5bb, 0x00000005 }, - { 0x0080e5bc, 0x00000005 }, - { 0x00210000, 0x00000004 }, - { 0x02800000, 0x00000004 }, - { 0x00c000c7, 0x00000018 }, - { 0x4180e000, 0x00000040 }, - { 0x000000c9, 0x00000024 }, - { 0x01000000, 0x0000000c }, - { 0x0100e51d, 0x0000000c }, - { 0x000045bb, 0x00000004 }, - { 0x000080c3, 0x00000008 }, - { 0x0000f3ce, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053cf, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f3d2, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053d3, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f39d, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c0539e, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x03c00830, 0x00000004 }, - { 0x4200e000, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x200045e0, 0x00000004 }, - { 0x0000e5e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000700e0, 0x00000004 }, - { 0x0800e394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x0000e8c4, 0x00000004 }, - { 0x0000e8c5, 0x00000004 }, - { 0x0000e8c6, 0x00000004 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000e4, 0x00000008 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000eb, 0x00000008 }, - { 0x02c02000, 0x00000004 }, - { 0x00060000, 0x00000004 }, - { 0x000000f3, 0x00000034 }, - { 0x000000f0, 0x00000008 }, - { 0x00008000, 0x00000004 }, - { 0xc000e000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x001d0018, 0x00000004 }, - { 0x001a0001, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0x0500a04a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - -static const u32 R420_cp_microcode[][2] = { - { 0x4200e000, 0000000000 }, - { 0x4000e000, 0000000000 }, - { 0x00000099, 0x00000008 }, - { 0x0000009d, 0x00000008 }, - { 0x4a554b4a, 0000000000 }, - { 0x4a4a4467, 0000000000 }, - { 0x55526f75, 0000000000 }, - { 0x4a7e7d65, 0000000000 }, - { 0xd9d3dff6, 0000000000 }, - { 0x4ac54a4a, 0000000000 }, - { 0xc8828282, 0000000000 }, - { 0xbf4acfc1, 0000000000 }, - { 0x87b04a4a, 0000000000 }, - { 0xb5838383, 0000000000 }, - { 0x4a0f85ba, 0000000000 }, - { 0x000ca000, 0x00000004 }, - { 0x000d0012, 0x00000038 }, - { 0x0000e8b4, 0x00000004 }, - { 0x000d0014, 0x00000038 }, - { 0x0000e8b6, 0x00000004 }, - { 0x000d0016, 0x00000038 }, - { 0x0000e854, 0x00000004 }, - { 0x000d0018, 0x00000038 }, - { 0x0000e855, 0x00000004 }, - { 0x000d001a, 0x00000038 }, - { 0x0000e856, 0x00000004 }, - { 0x000d001c, 0x00000038 }, - { 0x0000e857, 0x00000004 }, - { 0x000d001e, 0x00000038 }, - { 0x0000e824, 0x00000004 }, - { 0x000d0020, 0x00000038 }, - { 0x0000e825, 0x00000004 }, - { 0x000d0022, 0x00000038 }, - { 0x0000e830, 0x00000004 }, - { 0x000d0024, 0x00000038 }, - { 0x0000f0c0, 0x00000004 }, - { 0x000d0026, 0x00000038 }, - { 0x0000f0c1, 0x00000004 }, - { 0x000d0028, 0x00000038 }, - { 0x0000f041, 0x00000004 }, - { 0x000d002a, 0x00000038 }, - { 0x0000f184, 0x00000004 }, - { 0x000d002c, 0x00000038 }, - { 0x0000f185, 0x00000004 }, - { 0x000d002e, 0x00000038 }, - { 0x0000f186, 0x00000004 }, - { 0x000d0030, 0x00000038 }, - { 0x0000f187, 0x00000004 }, - { 0x000d0032, 0x00000038 }, - { 0x0000f180, 0x00000004 }, - { 0x000d0034, 0x00000038 }, - { 0x0000f393, 0x00000004 }, - { 0x000d0036, 0x00000038 }, - { 0x0000f38a, 0x00000004 }, - { 0x000d0038, 0x00000038 }, - { 0x0000f38e, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000043, 0x00000018 }, - { 0x00cce800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x0000003a, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x2000451d, 0x00000004 }, - { 0x0000e580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x08004580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x00000047, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x00032000, 0x00000004 }, - { 0x00022051, 0x00000028 }, - { 0x00000051, 0x00000024 }, - { 0x0800450f, 0x00000004 }, - { 0x0000a04b, 0x00000008 }, - { 0x0000e565, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000052, 0x00000008 }, - { 0x03cca5b4, 0x00000004 }, - { 0x05432000, 0x00000004 }, - { 0x00022000, 0x00000004 }, - { 0x4ccce05e, 0x00000030 }, - { 0x08274565, 0x00000004 }, - { 0x0000005e, 0x00000030 }, - { 0x08004564, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000055, 0x00000008 }, - { 0x00802061, 0x00000010 }, - { 0x00202000, 0x00000004 }, - { 0x001b00ff, 0x00000004 }, - { 0x01000064, 0x00000010 }, - { 0x001f2000, 0x00000004 }, - { 0x001c00ff, 0x00000004 }, - { 0000000000, 0x0000000c }, - { 0x00000072, 0x00000030 }, - { 0x00000055, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x0000e577, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x0000e50f, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000069, 0x00000018 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x00000069, 0x00000008 }, - { 0x0014e50e, 0x00000004 }, - { 0x0040e50f, 0x00000004 }, - { 0x00c0006c, 0x00000008 }, - { 0x0000e570, 0x00000004 }, - { 0x0000e571, 0x00000004 }, - { 0x0000e572, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000e568, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00000076, 0x00000018 }, - { 0x000b0000, 0x00000004 }, - { 0x18c0e562, 0x00000004 }, - { 0x00000078, 0x00000008 }, - { 0x00c00077, 0x00000008 }, - { 0x000700c7, 0x00000004 }, - { 0x00000080, 0x00000038 }, - { 0x0000e5bb, 0x00000004 }, - { 0x0000e5bc, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e800, 0000000000 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e82e, 0000000000 }, - { 0x02cca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000ce1cc, 0x00000004 }, - { 0x050de1cd, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x0000008f, 0x00000018 }, - { 0x00c0a000, 0x00000004 }, - { 0x0000008c, 0x00000008 }, - { 0x00000091, 0x00000020 }, - { 0x4200e000, 0000000000 }, - { 0x00000098, 0x00000038 }, - { 0x000ca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00160000, 0x00000004 }, - { 0x700ce000, 0x00000004 }, - { 0x00140094, 0x00000008 }, - { 0x4000e000, 0000000000 }, - { 0x02400000, 0x00000004 }, - { 0x400ee000, 0x00000004 }, - { 0x02400000, 0x00000004 }, - { 0x4000e000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0240e51b, 0x00000004 }, - { 0x0080e50a, 0x00000005 }, - { 0x0080e50b, 0x00000005 }, - { 0x00220000, 0x00000004 }, - { 0x000700c7, 0x00000004 }, - { 0x000000a4, 0x00000038 }, - { 0x0080e5bd, 0x00000005 }, - { 0x0000e5bb, 0x00000005 }, - { 0x0080e5bc, 0x00000005 }, - { 0x00210000, 0x00000004 }, - { 0x02800000, 0x00000004 }, - { 0x00c000ab, 0x00000018 }, - { 0x4180e000, 0x00000040 }, - { 0x000000ad, 0x00000024 }, - { 0x01000000, 0x0000000c }, - { 0x0100e51d, 0x0000000c }, - { 0x000045bb, 0x00000004 }, - { 0x000080a7, 0x00000008 }, - { 0x0000f3ce, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053cf, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f3d2, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053d3, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f39d, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c0539e, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x03c00830, 0x00000004 }, - { 0x4200e000, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x200045e0, 0x00000004 }, - { 0x0000e5e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000700c4, 0x00000004 }, - { 0x0800e394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x0000e8c4, 0x00000004 }, - { 0x0000e8c5, 0x00000004 }, - { 0x0000e8c6, 0x00000004 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000c8, 0x00000008 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000cf, 0x00000008 }, - { 0x02c02000, 0x00000004 }, - { 0x00060000, 0x00000004 }, - { 0x000000d7, 0x00000034 }, - { 0x000000d4, 0x00000008 }, - { 0x00008000, 0x00000004 }, - { 0xc000e000, 0000000000 }, - { 0x0000e1cc, 0x00000004 }, - { 0x0500e1cd, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x000000de, 0x00000034 }, - { 0x000000da, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x0019e1cc, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x0500a000, 0x00000004 }, - { 0x080041cd, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x001d0018, 0x00000004 }, - { 0x001a0001, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0x0500a04a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - -static const u32 RS600_cp_microcode[][2] = { - { 0x4200e000, 0000000000 }, - { 0x4000e000, 0000000000 }, - { 0x000000a0, 0x00000008 }, - { 0x000000a4, 0x00000008 }, - { 0x4a554b4a, 0000000000 }, - { 0x4a4a4467, 0000000000 }, - { 0x55526f75, 0000000000 }, - { 0x4a7e7d65, 0000000000 }, - { 0x4ae74af6, 0000000000 }, - { 0x4ad34a4a, 0000000000 }, - { 0xd6898989, 0000000000 }, - { 0xcd4addcf, 0000000000 }, - { 0x8ebe4ae2, 0000000000 }, - { 0xc38a8a8a, 0000000000 }, - { 0x4a0f8cc8, 0000000000 }, - { 0x000ca000, 0x00000004 }, - { 0x000d0012, 0x00000038 }, - { 0x0000e8b4, 0x00000004 }, - { 0x000d0014, 0x00000038 }, - { 0x0000e8b6, 0x00000004 }, - { 0x000d0016, 0x00000038 }, - { 0x0000e854, 0x00000004 }, - { 0x000d0018, 0x00000038 }, - { 0x0000e855, 0x00000004 }, - { 0x000d001a, 0x00000038 }, - { 0x0000e856, 0x00000004 }, - { 0x000d001c, 0x00000038 }, - { 0x0000e857, 0x00000004 }, - { 0x000d001e, 0x00000038 }, - { 0x0000e824, 0x00000004 }, - { 0x000d0020, 0x00000038 }, - { 0x0000e825, 0x00000004 }, - { 0x000d0022, 0x00000038 }, - { 0x0000e830, 0x00000004 }, - { 0x000d0024, 0x00000038 }, - { 0x0000f0c0, 0x00000004 }, - { 0x000d0026, 0x00000038 }, - { 0x0000f0c1, 0x00000004 }, - { 0x000d0028, 0x00000038 }, - { 0x0000f041, 0x00000004 }, - { 0x000d002a, 0x00000038 }, - { 0x0000f184, 0x00000004 }, - { 0x000d002c, 0x00000038 }, - { 0x0000f185, 0x00000004 }, - { 0x000d002e, 0x00000038 }, - { 0x0000f186, 0x00000004 }, - { 0x000d0030, 0x00000038 }, - { 0x0000f187, 0x00000004 }, - { 0x000d0032, 0x00000038 }, - { 0x0000f180, 0x00000004 }, - { 0x000d0034, 0x00000038 }, - { 0x0000f393, 0x00000004 }, - { 0x000d0036, 0x00000038 }, - { 0x0000f38a, 0x00000004 }, - { 0x000d0038, 0x00000038 }, - { 0x0000f38e, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000043, 0x00000018 }, - { 0x00cce800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x0000003a, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x2000451d, 0x00000004 }, - { 0x0000e580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x08004580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x00000047, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x00032000, 0x00000004 }, - { 0x00022051, 0x00000028 }, - { 0x00000051, 0x00000024 }, - { 0x0800450f, 0x00000004 }, - { 0x0000a04b, 0x00000008 }, - { 0x0000e565, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000052, 0x00000008 }, - { 0x03cca5b4, 0x00000004 }, - { 0x05432000, 0x00000004 }, - { 0x00022000, 0x00000004 }, - { 0x4ccce05e, 0x00000030 }, - { 0x08274565, 0x00000004 }, - { 0x0000005e, 0x00000030 }, - { 0x08004564, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000055, 0x00000008 }, - { 0x00802061, 0x00000010 }, - { 0x00202000, 0x00000004 }, - { 0x001b00ff, 0x00000004 }, - { 0x01000064, 0x00000010 }, - { 0x001f2000, 0x00000004 }, - { 0x001c00ff, 0x00000004 }, - { 0000000000, 0x0000000c }, - { 0x00000072, 0x00000030 }, - { 0x00000055, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x0000e577, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x0000e50f, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000069, 0x00000018 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x00000069, 0x00000008 }, - { 0x0014e50e, 0x00000004 }, - { 0x0040e50f, 0x00000004 }, - { 0x00c0006c, 0x00000008 }, - { 0x0000e570, 0x00000004 }, - { 0x0000e571, 0x00000004 }, - { 0x0000e572, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000e568, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00000076, 0x00000018 }, - { 0x000b0000, 0x00000004 }, - { 0x18c0e562, 0x00000004 }, - { 0x00000078, 0x00000008 }, - { 0x00c00077, 0x00000008 }, - { 0x000700d5, 0x00000004 }, - { 0x00000084, 0x00000038 }, - { 0x000ca086, 0x00000030 }, - { 0x080045bb, 0x00000004 }, - { 0x000c2087, 0x00000030 }, - { 0x0800e5bc, 0000000000 }, - { 0x0000e5bb, 0x00000004 }, - { 0x0000e5bc, 0000000000 }, - { 0x00120000, 0x0000000c }, - { 0x00120000, 0x00000004 }, - { 0x001b0002, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e800, 0000000000 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e82e, 0000000000 }, - { 0x02cca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000ce1cc, 0x00000004 }, - { 0x050de1cd, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x00000096, 0x00000018 }, - { 0x00c0a000, 0x00000004 }, - { 0x00000093, 0x00000008 }, - { 0x00000098, 0x00000020 }, - { 0x4200e000, 0000000000 }, - { 0x0000009f, 0x00000038 }, - { 0x000ca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00160000, 0x00000004 }, - { 0x700ce000, 0x00000004 }, - { 0x0014009b, 0x00000008 }, - { 0x4000e000, 0000000000 }, - { 0x02400000, 0x00000004 }, - { 0x400ee000, 0x00000004 }, - { 0x02400000, 0x00000004 }, - { 0x4000e000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0240e51b, 0x00000004 }, - { 0x0080e50a, 0x00000005 }, - { 0x0080e50b, 0x00000005 }, - { 0x00220000, 0x00000004 }, - { 0x000700d5, 0x00000004 }, - { 0x000000b2, 0x00000038 }, - { 0x000c2087, 0x00000030 }, - { 0x0880e5bd, 0x00000005 }, - { 0x000c2086, 0x00000030 }, - { 0x0800e5bb, 0x00000005 }, - { 0x000c2087, 0x00000030 }, - { 0x0880e5bc, 0x00000005 }, - { 0x000000b5, 0x00000008 }, - { 0x0080e5bd, 0x00000005 }, - { 0x0000e5bb, 0x00000005 }, - { 0x0080e5bc, 0x00000005 }, - { 0x00210000, 0x00000004 }, - { 0x02800000, 0x00000004 }, - { 0x00c000b9, 0x00000018 }, - { 0x4180e000, 0x00000040 }, - { 0x000000bb, 0x00000024 }, - { 0x01000000, 0x0000000c }, - { 0x0100e51d, 0x0000000c }, - { 0x000045bb, 0x00000004 }, - { 0x000080b5, 0x00000008 }, - { 0x0000f3ce, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053cf, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f3d2, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053d3, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f39d, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c0539e, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x03c00830, 0x00000004 }, - { 0x4200e000, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x200045e0, 0x00000004 }, - { 0x0000e5e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000700d2, 0x00000004 }, - { 0x0800e394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x0000e8c4, 0x00000004 }, - { 0x0000e8c5, 0x00000004 }, - { 0x0000e8c6, 0x00000004 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000d6, 0x00000008 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000dd, 0x00000008 }, - { 0x00e00116, 0000000000 }, - { 0x000700e1, 0x00000004 }, - { 0x0800401c, 0x00000004 }, - { 0x200050e7, 0x00000004 }, - { 0x0000e01d, 0x00000004 }, - { 0x000000e4, 0x00000008 }, - { 0x02c02000, 0x00000004 }, - { 0x00060000, 0x00000004 }, - { 0x000000eb, 0x00000034 }, - { 0x000000e8, 0x00000008 }, - { 0x00008000, 0x00000004 }, - { 0xc000e000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x001d0018, 0x00000004 }, - { 0x001a0001, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0x0500a04a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - -static const u32 RS690_cp_microcode[][2] = { - { 0x000000dd, 0x00000008 }, - { 0x000000df, 0x00000008 }, - { 0x000000a0, 0x00000008 }, - { 0x000000a4, 0x00000008 }, - { 0x4a554b4a, 0000000000 }, - { 0x4a4a4467, 0000000000 }, - { 0x55526f75, 0000000000 }, - { 0x4a7e7d65, 0000000000 }, - { 0x4ad74af6, 0000000000 }, - { 0x4ac94a4a, 0000000000 }, - { 0xcc898989, 0000000000 }, - { 0xc34ad3c5, 0000000000 }, - { 0x8e4a4a4a, 0000000000 }, - { 0x4a8a8a8a, 0000000000 }, - { 0x4a0f8c4a, 0000000000 }, - { 0x000ca000, 0x00000004 }, - { 0x000d0012, 0x00000038 }, - { 0x0000e8b4, 0x00000004 }, - { 0x000d0014, 0x00000038 }, - { 0x0000e8b6, 0x00000004 }, - { 0x000d0016, 0x00000038 }, - { 0x0000e854, 0x00000004 }, - { 0x000d0018, 0x00000038 }, - { 0x0000e855, 0x00000004 }, - { 0x000d001a, 0x00000038 }, - { 0x0000e856, 0x00000004 }, - { 0x000d001c, 0x00000038 }, - { 0x0000e857, 0x00000004 }, - { 0x000d001e, 0x00000038 }, - { 0x0000e824, 0x00000004 }, - { 0x000d0020, 0x00000038 }, - { 0x0000e825, 0x00000004 }, - { 0x000d0022, 0x00000038 }, - { 0x0000e830, 0x00000004 }, - { 0x000d0024, 0x00000038 }, - { 0x0000f0c0, 0x00000004 }, - { 0x000d0026, 0x00000038 }, - { 0x0000f0c1, 0x00000004 }, - { 0x000d0028, 0x00000038 }, - { 0x0000f041, 0x00000004 }, - { 0x000d002a, 0x00000038 }, - { 0x0000f184, 0x00000004 }, - { 0x000d002c, 0x00000038 }, - { 0x0000f185, 0x00000004 }, - { 0x000d002e, 0x00000038 }, - { 0x0000f186, 0x00000004 }, - { 0x000d0030, 0x00000038 }, - { 0x0000f187, 0x00000004 }, - { 0x000d0032, 0x00000038 }, - { 0x0000f180, 0x00000004 }, - { 0x000d0034, 0x00000038 }, - { 0x0000f393, 0x00000004 }, - { 0x000d0036, 0x00000038 }, - { 0x0000f38a, 0x00000004 }, - { 0x000d0038, 0x00000038 }, - { 0x0000f38e, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000043, 0x00000018 }, - { 0x00cce800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x0000003a, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x2000451d, 0x00000004 }, - { 0x0000e580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x08004580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x00000047, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x00032000, 0x00000004 }, - { 0x00022051, 0x00000028 }, - { 0x00000051, 0x00000024 }, - { 0x0800450f, 0x00000004 }, - { 0x0000a04b, 0x00000008 }, - { 0x0000e565, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000052, 0x00000008 }, - { 0x03cca5b4, 0x00000004 }, - { 0x05432000, 0x00000004 }, - { 0x00022000, 0x00000004 }, - { 0x4ccce05e, 0x00000030 }, - { 0x08274565, 0x00000004 }, - { 0x0000005e, 0x00000030 }, - { 0x08004564, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000055, 0x00000008 }, - { 0x00802061, 0x00000010 }, - { 0x00202000, 0x00000004 }, - { 0x001b00ff, 0x00000004 }, - { 0x01000064, 0x00000010 }, - { 0x001f2000, 0x00000004 }, - { 0x001c00ff, 0x00000004 }, - { 0000000000, 0x0000000c }, - { 0x00000072, 0x00000030 }, - { 0x00000055, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x0000e577, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x0000e50f, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000069, 0x00000018 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x00000069, 0x00000008 }, - { 0x0014e50e, 0x00000004 }, - { 0x0040e50f, 0x00000004 }, - { 0x00c0006c, 0x00000008 }, - { 0x0000e570, 0x00000004 }, - { 0x0000e571, 0x00000004 }, - { 0x0000e572, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000e568, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00000076, 0x00000018 }, - { 0x000b0000, 0x00000004 }, - { 0x18c0e562, 0x00000004 }, - { 0x00000078, 0x00000008 }, - { 0x00c00077, 0x00000008 }, - { 0x000700cb, 0x00000004 }, - { 0x00000084, 0x00000038 }, - { 0x000ca086, 0x00000030 }, - { 0x080045bb, 0x00000004 }, - { 0x000c2087, 0x00000030 }, - { 0x0800e5bc, 0000000000 }, - { 0x0000e5bb, 0x00000004 }, - { 0x0000e5bc, 0000000000 }, - { 0x00120000, 0x0000000c }, - { 0x00120000, 0x00000004 }, - { 0x001b0002, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e800, 0000000000 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e82e, 0000000000 }, - { 0x02cca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000ce1cc, 0x00000004 }, - { 0x050de1cd, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x00000096, 0x00000018 }, - { 0x00c0a000, 0x00000004 }, - { 0x00000093, 0x00000008 }, - { 0x00000098, 0x00000020 }, - { 0x4200e000, 0000000000 }, - { 0x0000009f, 0x00000038 }, - { 0x000ca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00160000, 0x00000004 }, - { 0x700ce000, 0x00000004 }, - { 0x0014009b, 0x00000008 }, - { 0x4000e000, 0000000000 }, - { 0x02400000, 0x00000004 }, - { 0x400ee000, 0x00000004 }, - { 0x02400000, 0x00000004 }, - { 0x4000e000, 0000000000 }, - { 0x00100000, 0x0000002c }, - { 0x00004000, 0000000000 }, - { 0x080045c8, 0x00000004 }, - { 0x00240005, 0x00000004 }, - { 0x08004d0b, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x0240e51b, 0x00000004 }, - { 0x0080e50a, 0x00000005 }, - { 0x0080e50b, 0x00000005 }, - { 0x00220000, 0x00000004 }, - { 0x000700cb, 0x00000004 }, - { 0x000000b7, 0x00000038 }, - { 0x000c2087, 0x00000030 }, - { 0x0880e5bd, 0x00000005 }, - { 0x000c2086, 0x00000030 }, - { 0x0800e5bb, 0x00000005 }, - { 0x000c2087, 0x00000030 }, - { 0x0880e5bc, 0x00000005 }, - { 0x000000ba, 0x00000008 }, - { 0x0080e5bd, 0x00000005 }, - { 0x0000e5bb, 0x00000005 }, - { 0x0080e5bc, 0x00000005 }, - { 0x00210000, 0x00000004 }, - { 0x02800000, 0x00000004 }, - { 0x00c000be, 0x00000018 }, - { 0x4180e000, 0x00000040 }, - { 0x000000c0, 0x00000024 }, - { 0x01000000, 0x0000000c }, - { 0x0100e51d, 0x0000000c }, - { 0x000045bb, 0x00000004 }, - { 0x000080ba, 0x00000008 }, - { 0x03c00830, 0x00000004 }, - { 0x4200e000, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x200045e0, 0x00000004 }, - { 0x0000e5e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000700c8, 0x00000004 }, - { 0x0800e394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x0000e8c4, 0x00000004 }, - { 0x0000e8c5, 0x00000004 }, - { 0x0000e8c6, 0x00000004 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000cc, 0x00000008 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000d3, 0x00000008 }, - { 0x02c02000, 0x00000004 }, - { 0x00060000, 0x00000004 }, - { 0x000000db, 0x00000034 }, - { 0x000000d8, 0x00000008 }, - { 0x00008000, 0x00000004 }, - { 0xc000e000, 0000000000 }, - { 0x000000e1, 0x00000030 }, - { 0x4200e000, 0000000000 }, - { 0x000000e1, 0x00000030 }, - { 0x4000e000, 0000000000 }, - { 0x0025001b, 0x00000004 }, - { 0x00230000, 0x00000004 }, - { 0x00250005, 0x00000004 }, - { 0x000000e6, 0x00000034 }, - { 0000000000, 0x0000000c }, - { 0x00244000, 0x00000004 }, - { 0x080045c8, 0x00000004 }, - { 0x00240005, 0x00000004 }, - { 0x08004d0b, 0x0000000c }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x001d0018, 0x00000004 }, - { 0x001a0001, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0x0500a04a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - -static const u32 R520_cp_microcode[][2] = { - { 0x4200e000, 0000000000 }, - { 0x4000e000, 0000000000 }, - { 0x00000099, 0x00000008 }, - { 0x0000009d, 0x00000008 }, - { 0x4a554b4a, 0000000000 }, - { 0x4a4a4467, 0000000000 }, - { 0x55526f75, 0000000000 }, - { 0x4a7e7d65, 0000000000 }, - { 0xe0dae6f6, 0000000000 }, - { 0x4ac54a4a, 0000000000 }, - { 0xc8828282, 0000000000 }, - { 0xbf4acfc1, 0000000000 }, - { 0x87b04ad5, 0000000000 }, - { 0xb5838383, 0000000000 }, - { 0x4a0f85ba, 0000000000 }, - { 0x000ca000, 0x00000004 }, - { 0x000d0012, 0x00000038 }, - { 0x0000e8b4, 0x00000004 }, - { 0x000d0014, 0x00000038 }, - { 0x0000e8b6, 0x00000004 }, - { 0x000d0016, 0x00000038 }, - { 0x0000e854, 0x00000004 }, - { 0x000d0018, 0x00000038 }, - { 0x0000e855, 0x00000004 }, - { 0x000d001a, 0x00000038 }, - { 0x0000e856, 0x00000004 }, - { 0x000d001c, 0x00000038 }, - { 0x0000e857, 0x00000004 }, - { 0x000d001e, 0x00000038 }, - { 0x0000e824, 0x00000004 }, - { 0x000d0020, 0x00000038 }, - { 0x0000e825, 0x00000004 }, - { 0x000d0022, 0x00000038 }, - { 0x0000e830, 0x00000004 }, - { 0x000d0024, 0x00000038 }, - { 0x0000f0c0, 0x00000004 }, - { 0x000d0026, 0x00000038 }, - { 0x0000f0c1, 0x00000004 }, - { 0x000d0028, 0x00000038 }, - { 0x0000e000, 0x00000004 }, - { 0x000d002a, 0x00000038 }, - { 0x0000e000, 0x00000004 }, - { 0x000d002c, 0x00000038 }, - { 0x0000e000, 0x00000004 }, - { 0x000d002e, 0x00000038 }, - { 0x0000e000, 0x00000004 }, - { 0x000d0030, 0x00000038 }, - { 0x0000e000, 0x00000004 }, - { 0x000d0032, 0x00000038 }, - { 0x0000f180, 0x00000004 }, - { 0x000d0034, 0x00000038 }, - { 0x0000f393, 0x00000004 }, - { 0x000d0036, 0x00000038 }, - { 0x0000f38a, 0x00000004 }, - { 0x000d0038, 0x00000038 }, - { 0x0000f38e, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000043, 0x00000018 }, - { 0x00cce800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x08004800, 0x00000004 }, - { 0x0000003a, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x2000451d, 0x00000004 }, - { 0x0000e580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x08004580, 0x00000004 }, - { 0x000ce581, 0x00000004 }, - { 0x00000047, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x00032000, 0x00000004 }, - { 0x00022051, 0x00000028 }, - { 0x00000051, 0x00000024 }, - { 0x0800450f, 0x00000004 }, - { 0x0000a04b, 0x00000008 }, - { 0x0000e565, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000052, 0x00000008 }, - { 0x03cca5b4, 0x00000004 }, - { 0x05432000, 0x00000004 }, - { 0x00022000, 0x00000004 }, - { 0x4ccce05e, 0x00000030 }, - { 0x08274565, 0x00000004 }, - { 0x0000005e, 0x00000030 }, - { 0x08004564, 0x00000004 }, - { 0x0000e566, 0x00000004 }, - { 0x00000055, 0x00000008 }, - { 0x00802061, 0x00000010 }, - { 0x00202000, 0x00000004 }, - { 0x001b00ff, 0x00000004 }, - { 0x01000064, 0x00000010 }, - { 0x001f2000, 0x00000004 }, - { 0x001c00ff, 0x00000004 }, - { 0000000000, 0x0000000c }, - { 0x00000072, 0x00000030 }, - { 0x00000055, 0x00000008 }, - { 0x0000e576, 0x00000004 }, - { 0x0000e577, 0x00000004 }, - { 0x0000e50e, 0x00000004 }, - { 0x0000e50f, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00000069, 0x00000018 }, - { 0x00c0e5f9, 0x000000c2 }, - { 0x00000069, 0x00000008 }, - { 0x0014e50e, 0x00000004 }, - { 0x0040e50f, 0x00000004 }, - { 0x00c0006c, 0x00000008 }, - { 0x0000e570, 0x00000004 }, - { 0x0000e571, 0x00000004 }, - { 0x0000e572, 0x0000000c }, - { 0x0000a000, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x0000e568, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00000076, 0x00000018 }, - { 0x000b0000, 0x00000004 }, - { 0x18c0e562, 0x00000004 }, - { 0x00000078, 0x00000008 }, - { 0x00c00077, 0x00000008 }, - { 0x000700c7, 0x00000004 }, - { 0x00000080, 0x00000038 }, - { 0x0000e5bb, 0x00000004 }, - { 0x0000e5bc, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e800, 0000000000 }, - { 0x0000e821, 0x00000004 }, - { 0x0000e82e, 0000000000 }, - { 0x02cca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000ce1cc, 0x00000004 }, - { 0x050de1cd, 0x00000004 }, - { 0x00400000, 0x00000004 }, - { 0x0000008f, 0x00000018 }, - { 0x00c0a000, 0x00000004 }, - { 0x0000008c, 0x00000008 }, - { 0x00000091, 0x00000020 }, - { 0x4200e000, 0000000000 }, - { 0x00000098, 0x00000038 }, - { 0x000ca000, 0x00000004 }, - { 0x00140000, 0x00000004 }, - { 0x000c2000, 0x00000004 }, - { 0x00160000, 0x00000004 }, - { 0x700ce000, 0x00000004 }, - { 0x00140094, 0x00000008 }, - { 0x4000e000, 0000000000 }, - { 0x02400000, 0x00000004 }, - { 0x400ee000, 0x00000004 }, - { 0x02400000, 0x00000004 }, - { 0x4000e000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x0240e51b, 0x00000004 }, - { 0x0080e50a, 0x00000005 }, - { 0x0080e50b, 0x00000005 }, - { 0x00220000, 0x00000004 }, - { 0x000700c7, 0x00000004 }, - { 0x000000a4, 0x00000038 }, - { 0x0080e5bd, 0x00000005 }, - { 0x0000e5bb, 0x00000005 }, - { 0x0080e5bc, 0x00000005 }, - { 0x00210000, 0x00000004 }, - { 0x02800000, 0x00000004 }, - { 0x00c000ab, 0x00000018 }, - { 0x4180e000, 0x00000040 }, - { 0x000000ad, 0x00000024 }, - { 0x01000000, 0x0000000c }, - { 0x0100e51d, 0x0000000c }, - { 0x000045bb, 0x00000004 }, - { 0x000080a7, 0x00000008 }, - { 0x0000f3ce, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053cf, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f3d2, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c053d3, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x0000f39d, 0x00000004 }, - { 0x0140a000, 0x00000004 }, - { 0x00cc2000, 0x00000004 }, - { 0x08c0539e, 0x00000040 }, - { 0x00008000, 0000000000 }, - { 0x03c00830, 0x00000004 }, - { 0x4200e000, 0000000000 }, - { 0x0000a000, 0x00000004 }, - { 0x200045e0, 0x00000004 }, - { 0x0000e5e1, 0000000000 }, - { 0x00000001, 0000000000 }, - { 0x000700c4, 0x00000004 }, - { 0x0800e394, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x0000e8c4, 0x00000004 }, - { 0x0000e8c5, 0x00000004 }, - { 0x0000e8c6, 0x00000004 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000c8, 0x00000008 }, - { 0x0000e928, 0x00000004 }, - { 0x0000e929, 0x00000004 }, - { 0x0000e92a, 0x00000004 }, - { 0x000000cf, 0x00000008 }, - { 0xdeadbeef, 0000000000 }, - { 0x00000116, 0000000000 }, - { 0x000700d3, 0x00000004 }, - { 0x080050e7, 0x00000004 }, - { 0x000700d4, 0x00000004 }, - { 0x0800401c, 0x00000004 }, - { 0x0000e01d, 0000000000 }, - { 0x02c02000, 0x00000004 }, - { 0x00060000, 0x00000004 }, - { 0x000000de, 0x00000034 }, - { 0x000000db, 0x00000008 }, - { 0x00008000, 0x00000004 }, - { 0xc000e000, 0000000000 }, - { 0x0000e1cc, 0x00000004 }, - { 0x0500e1cd, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x000000e5, 0x00000034 }, - { 0x000000e1, 0x00000008 }, - { 0x0000a000, 0000000000 }, - { 0x0019e1cc, 0x00000004 }, - { 0x001b0001, 0x00000004 }, - { 0x0500a000, 0x00000004 }, - { 0x080041cd, 0x00000004 }, - { 0x000ca000, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0x000c2000, 0x00000004 }, - { 0x001d0018, 0x00000004 }, - { 0x001a0001, 0x00000004 }, - { 0x000000fb, 0x00000034 }, - { 0x0000004a, 0x00000008 }, - { 0x0500a04a, 0x00000008 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, - { 0000000000, 0000000000 }, -}; - - -#endif diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c deleted file mode 100644 index 11c146b..0000000 --- a/drivers/char/drm/radeon_state.c +++ /dev/null @@ -1,3203 +0,0 @@ -/* radeon_state.c -- State support for Radeon -*- linux-c -*- */ -/* - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - * Kevin E. Martin - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -/* ================================================================ - * Helper functions for client state checking and fixup - */ - -static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * - dev_priv, - struct drm_file * file_priv, - u32 *offset) -{ - u64 off = *offset; - u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1; - struct drm_radeon_driver_file_fields *radeon_priv; - - /* Hrm ... the story of the offset ... So this function converts - * the various ideas of what userland clients might have for an - * offset in the card address space into an offset into the card - * address space :) So with a sane client, it should just keep - * the value intact and just do some boundary checking. However, - * not all clients are sane. Some older clients pass us 0 based - * offsets relative to the start of the framebuffer and some may - * assume the AGP aperture it appended to the framebuffer, so we - * try to detect those cases and fix them up. - * - * Note: It might be a good idea here to make sure the offset lands - * in some "allowed" area to protect things like the PCIE GART... - */ - - /* First, the best case, the offset already lands in either the - * framebuffer or the GART mapped space - */ - if (radeon_check_offset(dev_priv, off)) - return 0; - - /* Ok, that didn't happen... now check if we have a zero based - * offset that fits in the framebuffer + gart space, apply the - * magic offset we get from SETPARAM or calculated from fb_location - */ - if (off < (dev_priv->fb_size + dev_priv->gart_size)) { - radeon_priv = file_priv->driver_priv; - off += radeon_priv->radeon_fb_delta; - } - - /* Finally, assume we aimed at a GART offset if beyond the fb */ - if (off > fb_end) - off = off - fb_end - 1 + dev_priv->gart_vm_start; - - /* Now recheck and fail if out of bounds */ - if (radeon_check_offset(dev_priv, off)) { - DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); - *offset = off; - return 0; - } - return -EINVAL; -} - -static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * - dev_priv, - struct drm_file *file_priv, - int id, u32 *data) -{ - switch (id) { - - case RADEON_EMIT_PP_MISC: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) { - DRM_ERROR("Invalid depth buffer offset\n"); - return -EINVAL; - } - break; - - case RADEON_EMIT_PP_CNTL: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) { - DRM_ERROR("Invalid colour buffer offset\n"); - return -EINVAL; - } - break; - - case R200_EMIT_PP_TXOFFSET_0: - case R200_EMIT_PP_TXOFFSET_1: - case R200_EMIT_PP_TXOFFSET_2: - case R200_EMIT_PP_TXOFFSET_3: - case R200_EMIT_PP_TXOFFSET_4: - case R200_EMIT_PP_TXOFFSET_5: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[0])) { - DRM_ERROR("Invalid R200 texture offset\n"); - return -EINVAL; - } - break; - - case RADEON_EMIT_PP_TXFILTER_0: - case RADEON_EMIT_PP_TXFILTER_1: - case RADEON_EMIT_PP_TXFILTER_2: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) { - DRM_ERROR("Invalid R100 texture offset\n"); - return -EINVAL; - } - break; - - case R200_EMIT_PP_CUBIC_OFFSETS_0: - case R200_EMIT_PP_CUBIC_OFFSETS_1: - case R200_EMIT_PP_CUBIC_OFFSETS_2: - case R200_EMIT_PP_CUBIC_OFFSETS_3: - case R200_EMIT_PP_CUBIC_OFFSETS_4: - case R200_EMIT_PP_CUBIC_OFFSETS_5:{ - int i; - for (i = 0; i < 5; i++) { - if (radeon_check_and_fixup_offset(dev_priv, - file_priv, - &data[i])) { - DRM_ERROR - ("Invalid R200 cubic texture offset\n"); - return -EINVAL; - } - } - break; - } - - case RADEON_EMIT_PP_CUBIC_OFFSETS_T0: - case RADEON_EMIT_PP_CUBIC_OFFSETS_T1: - case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{ - int i; - for (i = 0; i < 5; i++) { - if (radeon_check_and_fixup_offset(dev_priv, - file_priv, - &data[i])) { - DRM_ERROR - ("Invalid R100 cubic texture offset\n"); - return -EINVAL; - } - } - } - break; - - case R200_EMIT_VAP_CTL:{ - RING_LOCALS; - BEGIN_RING(2); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - ADVANCE_RING(); - } - break; - - case RADEON_EMIT_RB3D_COLORPITCH: - case RADEON_EMIT_RE_LINE_PATTERN: - case RADEON_EMIT_SE_LINE_WIDTH: - case RADEON_EMIT_PP_LUM_MATRIX: - case RADEON_EMIT_PP_ROT_MATRIX_0: - case RADEON_EMIT_RB3D_STENCILREFMASK: - case RADEON_EMIT_SE_VPORT_XSCALE: - case RADEON_EMIT_SE_CNTL: - case RADEON_EMIT_SE_CNTL_STATUS: - case RADEON_EMIT_RE_MISC: - case RADEON_EMIT_PP_BORDER_COLOR_0: - case RADEON_EMIT_PP_BORDER_COLOR_1: - case RADEON_EMIT_PP_BORDER_COLOR_2: - case RADEON_EMIT_SE_ZBIAS_FACTOR: - case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT: - case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED: - case R200_EMIT_PP_TXCBLEND_0: - case R200_EMIT_PP_TXCBLEND_1: - case R200_EMIT_PP_TXCBLEND_2: - case R200_EMIT_PP_TXCBLEND_3: - case R200_EMIT_PP_TXCBLEND_4: - case R200_EMIT_PP_TXCBLEND_5: - case R200_EMIT_PP_TXCBLEND_6: - case R200_EMIT_PP_TXCBLEND_7: - case R200_EMIT_TCL_LIGHT_MODEL_CTL_0: - case R200_EMIT_TFACTOR_0: - case R200_EMIT_VTX_FMT_0: - case R200_EMIT_MATRIX_SELECT_0: - case R200_EMIT_TEX_PROC_CTL_2: - case R200_EMIT_TCL_UCP_VERT_BLEND_CTL: - case R200_EMIT_PP_TXFILTER_0: - case R200_EMIT_PP_TXFILTER_1: - case R200_EMIT_PP_TXFILTER_2: - case R200_EMIT_PP_TXFILTER_3: - case R200_EMIT_PP_TXFILTER_4: - case R200_EMIT_PP_TXFILTER_5: - case R200_EMIT_VTE_CNTL: - case R200_EMIT_OUTPUT_VTX_COMP_SEL: - case R200_EMIT_PP_TAM_DEBUG3: - case R200_EMIT_PP_CNTL_X: - case R200_EMIT_RB3D_DEPTHXY_OFFSET: - case R200_EMIT_RE_AUX_SCISSOR_CNTL: - case R200_EMIT_RE_SCISSOR_TL_0: - case R200_EMIT_RE_SCISSOR_TL_1: - case R200_EMIT_RE_SCISSOR_TL_2: - case R200_EMIT_SE_VAP_CNTL_STATUS: - case R200_EMIT_SE_VTX_STATE_CNTL: - case R200_EMIT_RE_POINTSIZE: - case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0: - case R200_EMIT_PP_CUBIC_FACES_0: - case R200_EMIT_PP_CUBIC_FACES_1: - case R200_EMIT_PP_CUBIC_FACES_2: - case R200_EMIT_PP_CUBIC_FACES_3: - case R200_EMIT_PP_CUBIC_FACES_4: - case R200_EMIT_PP_CUBIC_FACES_5: - case RADEON_EMIT_PP_TEX_SIZE_0: - case RADEON_EMIT_PP_TEX_SIZE_1: - case RADEON_EMIT_PP_TEX_SIZE_2: - case R200_EMIT_RB3D_BLENDCOLOR: - case R200_EMIT_TCL_POINT_SPRITE_CNTL: - case RADEON_EMIT_PP_CUBIC_FACES_0: - case RADEON_EMIT_PP_CUBIC_FACES_1: - case RADEON_EMIT_PP_CUBIC_FACES_2: - case R200_EMIT_PP_TRI_PERF_CNTL: - case R200_EMIT_PP_AFS_0: - case R200_EMIT_PP_AFS_1: - case R200_EMIT_ATF_TFACTOR: - case R200_EMIT_PP_TXCTLALL_0: - case R200_EMIT_PP_TXCTLALL_1: - case R200_EMIT_PP_TXCTLALL_2: - case R200_EMIT_PP_TXCTLALL_3: - case R200_EMIT_PP_TXCTLALL_4: - case R200_EMIT_PP_TXCTLALL_5: - case R200_EMIT_VAP_PVS_CNTL: - /* These packets don't contain memory offsets */ - break; - - default: - DRM_ERROR("Unknown state packet ID %d\n", id); - return -EINVAL; - } - - return 0; -} - -static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * - dev_priv, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t * - cmdbuf, - unsigned int *cmdsz) -{ - u32 *cmd = (u32 *) cmdbuf->buf; - u32 offset, narrays; - int count, i, k; - - *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); - - if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) { - DRM_ERROR("Not a type 3 packet\n"); - return -EINVAL; - } - - if (4 * *cmdsz > cmdbuf->bufsz) { - DRM_ERROR("Packet size larger than size of data provided\n"); - return -EINVAL; - } - - switch(cmd[0] & 0xff00) { - /* XXX Are there old drivers needing other packets? */ - - case RADEON_3D_DRAW_IMMD: - case RADEON_3D_DRAW_VBUF: - case RADEON_3D_DRAW_INDX: - case RADEON_WAIT_FOR_IDLE: - case RADEON_CP_NOP: - case RADEON_3D_CLEAR_ZMASK: -/* case RADEON_CP_NEXT_CHAR: - case RADEON_CP_PLY_NEXTSCAN: - case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */ - /* these packets are safe */ - break; - - case RADEON_CP_3D_DRAW_IMMD_2: - case RADEON_CP_3D_DRAW_VBUF_2: - case RADEON_CP_3D_DRAW_INDX_2: - case RADEON_3D_CLEAR_HIZ: - /* safe but r200 only */ - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return -EINVAL; - } - break; - - case RADEON_3D_LOAD_VBPNTR: - count = (cmd[0] >> 16) & 0x3fff; - - if (count > 18) { /* 12 arrays max */ - DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", - count); - return -EINVAL; - } - - /* carefully check packet contents */ - narrays = cmd[1] & ~0xc000; - k = 0; - i = 2; - while ((k < narrays) && (i < (count + 2))) { - i++; /* skip attribute field */ - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &cmd[i])) { - DRM_ERROR - ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - if (k == narrays) - break; - /* have one more to process, they come in pairs */ - if (radeon_check_and_fixup_offset(dev_priv, - file_priv, &cmd[i])) - { - DRM_ERROR - ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - } - /* do the counts match what we expect ? */ - if ((k != narrays) || (i != (count + 2))) { - DRM_ERROR - ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", - k, i, narrays, count + 1); - return -EINVAL; - } - break; - - case RADEON_3D_RNDR_GEN_INDX_PRIM: - if (dev_priv->microcode_version != UCODE_R100) { - DRM_ERROR("Invalid 3d packet for r200-class chip\n"); - return -EINVAL; - } - if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) { - DRM_ERROR("Invalid rndr_gen_indx offset\n"); - return -EINVAL; - } - break; - - case RADEON_CP_INDX_BUFFER: - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return -EINVAL; - } - if ((cmd[1] & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); - return -EINVAL; - } - if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[2])) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); - return -EINVAL; - } - break; - - case RADEON_CNTL_HOSTDATA_BLT: - case RADEON_CNTL_PAINT_MULTI: - case RADEON_CNTL_BITBLT_MULTI: - /* MSB of opcode: next DWORD GUI_CNTL */ - if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL - | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - offset = cmd[2] << 10; - if (radeon_check_and_fixup_offset - (dev_priv, file_priv, &offset)) { - DRM_ERROR("Invalid first packet offset\n"); - return -EINVAL; - } - cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10; - } - - if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && - (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - offset = cmd[3] << 10; - if (radeon_check_and_fixup_offset - (dev_priv, file_priv, &offset)) { - DRM_ERROR("Invalid second packet offset\n"); - return -EINVAL; - } - cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; - } - break; - - default: - DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00); - return -EINVAL; - } - - return 0; -} - -/* ================================================================ - * CP hardware state programming functions - */ - -static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, - struct drm_clip_rect * box) -{ - RING_LOCALS; - - DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n", - box->x1, box->y1, box->x2, box->y2); - - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0)); - OUT_RING((box->y1 << 16) | box->x1); - OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0)); - OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1)); - ADVANCE_RING(); -} - -/* Emit 1.1 state - */ -static int radeon_emit_state(drm_radeon_private_t * dev_priv, - struct drm_file *file_priv, - drm_radeon_context_regs_t * ctx, - drm_radeon_texture_regs_t * tex, - unsigned int dirty) -{ - RING_LOCALS; - DRM_DEBUG("dirty=0x%08x\n", dirty); - - if (dirty & RADEON_UPLOAD_CONTEXT) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &ctx->rb3d_depthoffset)) { - DRM_ERROR("Invalid depth buffer offset\n"); - return -EINVAL; - } - - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &ctx->rb3d_coloroffset)) { - DRM_ERROR("Invalid depth buffer offset\n"); - return -EINVAL; - } - - BEGIN_RING(14); - OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6)); - OUT_RING(ctx->pp_misc); - OUT_RING(ctx->pp_fog_color); - OUT_RING(ctx->re_solid_color); - OUT_RING(ctx->rb3d_blendcntl); - OUT_RING(ctx->rb3d_depthoffset); - OUT_RING(ctx->rb3d_depthpitch); - OUT_RING(ctx->rb3d_zstencilcntl); - OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2)); - OUT_RING(ctx->pp_cntl); - OUT_RING(ctx->rb3d_cntl); - OUT_RING(ctx->rb3d_coloroffset); - OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0)); - OUT_RING(ctx->rb3d_colorpitch); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_VERTFMT) { - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0)); - OUT_RING(ctx->se_coord_fmt); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_LINE) { - BEGIN_RING(5); - OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1)); - OUT_RING(ctx->re_line_pattern); - OUT_RING(ctx->re_line_state); - OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0)); - OUT_RING(ctx->se_line_width); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_BUMPMAP) { - BEGIN_RING(5); - OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0)); - OUT_RING(ctx->pp_lum_matrix); - OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1)); - OUT_RING(ctx->pp_rot_matrix_0); - OUT_RING(ctx->pp_rot_matrix_1); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_MASKS) { - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2)); - OUT_RING(ctx->rb3d_stencilrefmask); - OUT_RING(ctx->rb3d_ropcntl); - OUT_RING(ctx->rb3d_planemask); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_VIEWPORT) { - BEGIN_RING(7); - OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5)); - OUT_RING(ctx->se_vport_xscale); - OUT_RING(ctx->se_vport_xoffset); - OUT_RING(ctx->se_vport_yscale); - OUT_RING(ctx->se_vport_yoffset); - OUT_RING(ctx->se_vport_zscale); - OUT_RING(ctx->se_vport_zoffset); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_SETUP) { - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0)); - OUT_RING(ctx->se_cntl); - OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0)); - OUT_RING(ctx->se_cntl_status); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_MISC) { - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0)); - OUT_RING(ctx->re_misc); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_TEX0) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &tex[0].pp_txoffset)) { - DRM_ERROR("Invalid texture offset for unit 0\n"); - return -EINVAL; - } - - BEGIN_RING(9); - OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5)); - OUT_RING(tex[0].pp_txfilter); - OUT_RING(tex[0].pp_txformat); - OUT_RING(tex[0].pp_txoffset); - OUT_RING(tex[0].pp_txcblend); - OUT_RING(tex[0].pp_txablend); - OUT_RING(tex[0].pp_tfactor); - OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0)); - OUT_RING(tex[0].pp_border_color); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_TEX1) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &tex[1].pp_txoffset)) { - DRM_ERROR("Invalid texture offset for unit 1\n"); - return -EINVAL; - } - - BEGIN_RING(9); - OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5)); - OUT_RING(tex[1].pp_txfilter); - OUT_RING(tex[1].pp_txformat); - OUT_RING(tex[1].pp_txoffset); - OUT_RING(tex[1].pp_txcblend); - OUT_RING(tex[1].pp_txablend); - OUT_RING(tex[1].pp_tfactor); - OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0)); - OUT_RING(tex[1].pp_border_color); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_TEX2) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &tex[2].pp_txoffset)) { - DRM_ERROR("Invalid texture offset for unit 2\n"); - return -EINVAL; - } - - BEGIN_RING(9); - OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5)); - OUT_RING(tex[2].pp_txfilter); - OUT_RING(tex[2].pp_txformat); - OUT_RING(tex[2].pp_txoffset); - OUT_RING(tex[2].pp_txcblend); - OUT_RING(tex[2].pp_txablend); - OUT_RING(tex[2].pp_tfactor); - OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0)); - OUT_RING(tex[2].pp_border_color); - ADVANCE_RING(); - } - - return 0; -} - -/* Emit 1.2 state - */ -static int radeon_emit_state2(drm_radeon_private_t * dev_priv, - struct drm_file *file_priv, - drm_radeon_state_t * state) -{ - RING_LOCALS; - - if (state->dirty & RADEON_UPLOAD_ZBIAS) { - BEGIN_RING(3); - OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1)); - OUT_RING(state->context2.se_zbias_factor); - OUT_RING(state->context2.se_zbias_constant); - ADVANCE_RING(); - } - - return radeon_emit_state(dev_priv, file_priv, &state->context, - state->tex, state->dirty); -} - -/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in - * 1.3 cmdbuffers allow all previous state to be updated as well as - * the tcl scalar and vector areas. - */ -static struct { - int start; - int len; - const char *name; -} packet[RADEON_MAX_STATE_PACKETS] = { - {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, - {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, - {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, - {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, - {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, - {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, - {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, - {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, - {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, - {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, - {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, - {RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, - {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, - {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, - {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, - {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, - {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, - {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, - {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, - {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, - {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, - "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, - {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, - {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, - {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, - {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, - {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, - {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, - {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, - {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, - {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, - {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, - {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, - {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, - {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, - {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, - {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, - {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, - {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, - {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, - {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, - {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, - {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, - {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, - {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, - {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, - {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, - {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, - {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, - {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, - {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, - "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, - {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, - {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, - {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, - {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, - {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, - {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, - {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, - {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, - {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, - {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, - {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, - "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, - {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ - {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ - {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, - {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, - {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, - {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, - {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, - {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, - {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, - {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, - {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, - {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, - {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, - {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, - {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, - {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, - {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, - {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, - {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, - {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, - {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, - {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, - {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, - {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, - {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ - {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, - {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, - {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, - {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, - {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, - {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, - {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, - {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, - {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"}, -}; - -/* ================================================================ - * Performance monitoring functions - */ - -static void radeon_clear_box(drm_radeon_private_t * dev_priv, - int x, int y, int w, int h, int r, int g, int b) -{ - u32 color; - RING_LOCALS; - - x += dev_priv->sarea_priv->boxes[0].x1; - y += dev_priv->sarea_priv->boxes[0].y1; - - switch (dev_priv->color_fmt) { - case RADEON_COLOR_FORMAT_RGB565: - color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); - break; - case RADEON_COLOR_FORMAT_ARGB8888: - default: - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); - break; - } - - BEGIN_RING(4); - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0)); - OUT_RING(0xffffffff); - ADVANCE_RING(); - - BEGIN_RING(6); - - OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4)); - OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); - - if (dev_priv->sarea_priv->pfCurrentPage == 1) { - OUT_RING(dev_priv->front_pitch_offset); - } else { - OUT_RING(dev_priv->back_pitch_offset); - } - - OUT_RING(color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); -} - -static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) -{ - /* Collapse various things into a wait flag -- trying to - * guess if userspase slept -- better just to have them tell us. - */ - if (dev_priv->stats.last_frame_reads > 1 || - dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - } - - if (dev_priv->stats.freelist_loops) { - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - } - - /* Purple box for page flipping - */ - if (dev_priv->stats.boxes & RADEON_BOX_FLIP) - radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255); - - /* Red box if we have to wait for idle at any point - */ - if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE) - radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0); - - /* Blue box: lost context? - */ - - /* Yellow box for texture swaps - */ - if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD) - radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0); - - /* Green box if hardware never idles (as far as we can tell) - */ - if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) - radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); - - /* Draw bars indicating number of buffers allocated - * (not a great measure, easily confused) - */ - if (dev_priv->stats.requested_bufs) { - if (dev_priv->stats.requested_bufs > 100) - dev_priv->stats.requested_bufs = 100; - - radeon_clear_box(dev_priv, 4, 16, - dev_priv->stats.requested_bufs, 4, - 196, 128, 128); - } - - memset(&dev_priv->stats, 0, sizeof(dev_priv->stats)); - -} - -/* ================================================================ - * CP command dispatch functions - */ - -static void radeon_cp_dispatch_clear(struct drm_device * dev, - drm_radeon_clear_t * clear, - drm_radeon_clear_rect_t * depth_boxes) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - unsigned int flags = clear->flags; - u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0; - int i; - RING_LOCALS; - DRM_DEBUG("flags = 0x%x\n", flags); - - dev_priv->stats.clears++; - - if (dev_priv->sarea_priv->pfCurrentPage == 1) { - unsigned int tmp = flags; - - flags &= ~(RADEON_FRONT | RADEON_BACK); - if (tmp & RADEON_FRONT) - flags |= RADEON_BACK; - if (tmp & RADEON_BACK) - flags |= RADEON_FRONT; - } - - if (flags & (RADEON_FRONT | RADEON_BACK)) { - - BEGIN_RING(4); - - /* Ensure the 3D stream is idle before doing a - * 2D fill to clear the front or back buffer. - */ - RADEON_WAIT_UNTIL_3D_IDLE(); - - OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0)); - OUT_RING(clear->color_mask); - - ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->ctx_owner = 0; - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n", - x, y, w, h, flags); - - if (flags & RADEON_FRONT) { - BEGIN_RING(6); - - OUT_RING(CP_PACKET3 - (RADEON_CNTL_PAINT_MULTI, 4)); - OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv-> - color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS); - - OUT_RING(dev_priv->front_pitch_offset); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - if (flags & RADEON_BACK) { - BEGIN_RING(6); - - OUT_RING(CP_PACKET3 - (RADEON_CNTL_PAINT_MULTI, 4)); - OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv-> - color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS); - - OUT_RING(dev_priv->back_pitch_offset); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - } - } - - /* hyper z clear */ - /* no docs available, based on reverse engeneering by Stephane Marchesin */ - if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) - && (flags & RADEON_CLEAR_FASTZ)) { - - int i; - int depthpixperline = - dev_priv->depth_fmt == - RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch / - 2) : (dev_priv-> - depth_pitch / 4); - - u32 clearmask; - - u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth | - ((clear->depth_mask & 0xff) << 24); - - /* Make sure we restore the 3D state next time. - * we haven't touched any "normal" state - still need this? - */ - dev_priv->sarea_priv->ctx_owner = 0; - - if ((dev_priv->flags & RADEON_HAS_HIERZ) - && (flags & RADEON_USE_HIERZ)) { - /* FIXME : reverse engineer that for Rx00 cards */ - /* FIXME : the mask supposedly contains low-res z values. So can't set - just to the max (0xff? or actually 0x3fff?), need to take z clear - value into account? */ - /* pattern seems to work for r100, though get slight - rendering errors with glxgears. If hierz is not enabled for r100, - only 4 bits which indicate clear (15,16,31,32, all zero) matter, the - other ones are ignored, and the same clear mask can be used. That's - very different behaviour than R200 which needs different clear mask - and different number of tiles to clear if hierz is enabled or not !?! - */ - clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f; - } else { - /* clear mask : chooses the clearing pattern. - rv250: could be used to clear only parts of macrotiles - (but that would get really complicated...)? - bit 0 and 1 (either or both of them ?!?!) are used to - not clear tile (or maybe one of the bits indicates if the tile is - compressed or not), bit 2 and 3 to not clear tile 1,...,. - Pattern is as follows: - | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29| - bits ------------------------------------------------- - | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31| - rv100: clearmask covers 2x8 4x1 tiles, but one clear still - covers 256 pixels ?!? - */ - clearmask = 0x0; - } - - BEGIN_RING(8); - RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE, - tempRB3D_DEPTHCLEARVALUE); - /* what offset is this exactly ? */ - OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0); - /* need ctlstat, otherwise get some strange black flickering */ - OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT, - RADEON_RB3D_ZC_FLUSH_ALL); - ADVANCE_RING(); - - for (i = 0; i < nbox; i++) { - int tileoffset, nrtilesx, nrtilesy, j; - /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) - && !(dev_priv->microcode_version == UCODE_R200)) { - /* FIXME : figure this out for r200 (when hierz is enabled). Or - maybe r200 actually doesn't need to put the low-res z value into - the tile cache like r100, but just needs to clear the hi-level z-buffer? - Works for R100, both with hierz and without. - R100 seems to operate on 2x1 8x8 tiles, but... - odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially - problematic with resolutions which are not 64 pix aligned? */ - tileoffset = - ((pbox[i].y1 >> 3) * depthpixperline + - pbox[i].x1) >> 6; - nrtilesx = - ((pbox[i].x2 & ~63) - - (pbox[i].x1 & ~63)) >> 4; - nrtilesy = - (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); - for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING(4); - OUT_RING(CP_PACKET3 - (RADEON_3D_CLEAR_ZMASK, 2)); - /* first tile */ - OUT_RING(tileoffset * 8); - /* the number of tiles to clear */ - OUT_RING(nrtilesx + 4); - /* clear mask : chooses the clearing pattern. */ - OUT_RING(clearmask); - ADVANCE_RING(); - tileoffset += depthpixperline >> 6; - } - } else if (dev_priv->microcode_version == UCODE_R200) { - /* works for rv250. */ - /* find first macro tile (8x2 4x4 z-pixels on rv250) */ - tileoffset = - ((pbox[i].y1 >> 3) * depthpixperline + - pbox[i].x1) >> 5; - nrtilesx = - (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5); - nrtilesy = - (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); - for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING(4); - OUT_RING(CP_PACKET3 - (RADEON_3D_CLEAR_ZMASK, 2)); - /* first tile */ - /* judging by the first tile offset needed, could possibly - directly address/clear 4x4 tiles instead of 8x2 * 4x4 - macro tiles, though would still need clear mask for - right/bottom if truely 4x4 granularity is desired ? */ - OUT_RING(tileoffset * 16); - /* the number of tiles to clear */ - OUT_RING(nrtilesx + 1); - /* clear mask : chooses the clearing pattern. */ - OUT_RING(clearmask); - ADVANCE_RING(); - tileoffset += depthpixperline >> 5; - } - } else { /* rv 100 */ - /* rv100 might not need 64 pix alignment, who knows */ - /* offsets are, hmm, weird */ - tileoffset = - ((pbox[i].y1 >> 4) * depthpixperline + - pbox[i].x1) >> 6; - nrtilesx = - ((pbox[i].x2 & ~63) - - (pbox[i].x1 & ~63)) >> 4; - nrtilesy = - (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4); - for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING(4); - OUT_RING(CP_PACKET3 - (RADEON_3D_CLEAR_ZMASK, 2)); - OUT_RING(tileoffset * 128); - /* the number of tiles to clear */ - OUT_RING(nrtilesx + 4); - /* clear mask : chooses the clearing pattern. */ - OUT_RING(clearmask); - ADVANCE_RING(); - tileoffset += depthpixperline >> 6; - } - } - } - - /* TODO don't always clear all hi-level z tiles */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) - && (dev_priv->microcode_version == UCODE_R200) - && (flags & RADEON_USE_HIERZ)) - /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ - /* FIXME : the mask supposedly contains low-res z values. So can't set - just to the max (0xff? or actually 0x3fff?), need to take z clear - value into account? */ - { - BEGIN_RING(4); - OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2)); - OUT_RING(0x0); /* First tile */ - OUT_RING(0x3cc0); - OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f); - ADVANCE_RING(); - } - } - - /* We have to clear the depth and/or stencil buffers by - * rendering a quad into just those buffers. Thus, we have to - * make sure the 3D engine is configured correctly. - */ - else if ((dev_priv->microcode_version == UCODE_R200) && - (flags & (RADEON_DEPTH | RADEON_STENCIL))) { - - int tempPP_CNTL; - int tempRE_CNTL; - int tempRB3D_CNTL; - int tempRB3D_ZSTENCILCNTL; - int tempRB3D_STENCILREFMASK; - int tempRB3D_PLANEMASK; - int tempSE_CNTL; - int tempSE_VTE_CNTL; - int tempSE_VTX_FMT_0; - int tempSE_VTX_FMT_1; - int tempSE_VAP_CNTL; - int tempRE_AUX_SCISSOR_CNTL; - - tempPP_CNTL = 0; - tempRE_CNTL = 0; - - tempRB3D_CNTL = depth_clear->rb3d_cntl; - - tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; - tempRB3D_STENCILREFMASK = 0x0; - - tempSE_CNTL = depth_clear->se_cntl; - - /* Disable TCL */ - - tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ - (0x9 << - SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); - - tempRB3D_PLANEMASK = 0x0; - - tempRE_AUX_SCISSOR_CNTL = 0x0; - - tempSE_VTE_CNTL = - SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK; - - /* Vertex format (X, Y, Z, W) */ - tempSE_VTX_FMT_0 = - SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | - SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; - tempSE_VTX_FMT_1 = 0x0; - - /* - * Depth buffer specific enables - */ - if (flags & RADEON_DEPTH) { - /* Enable depth buffer */ - tempRB3D_CNTL |= RADEON_Z_ENABLE; - } else { - /* Disable depth buffer */ - tempRB3D_CNTL &= ~RADEON_Z_ENABLE; - } - - /* - * Stencil buffer specific enables - */ - if (flags & RADEON_STENCIL) { - tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; - tempRB3D_STENCILREFMASK = clear->depth_mask; - } else { - tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; - tempRB3D_STENCILREFMASK = 0x00000000; - } - - if (flags & RADEON_USE_COMP_ZBUF) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | - RADEON_Z_DECOMPRESSION_ENABLE; - } - if (flags & RADEON_USE_HIERZ) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; - } - - BEGIN_RING(26); - RADEON_WAIT_UNTIL_2D_IDLE(); - - OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL); - OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL); - OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL); - OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL); - OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, - tempRB3D_STENCILREFMASK); - OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK); - OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL); - OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL); - OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0); - OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1); - OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL); - OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL); - ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->ctx_owner = 0; - - for (i = 0; i < nbox; i++) { - - /* Funny that this should be required -- - * sets top-left? - */ - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - - BEGIN_RING(14); - OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12)); - OUT_RING((RADEON_PRIM_TYPE_RECT_LIST | - RADEON_PRIM_WALK_RING | - (3 << RADEON_NUM_VERTICES_SHIFT))); - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y1]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x3f800000); - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x3f800000); - OUT_RING(depth_boxes[i].ui[CLEAR_X2]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x3f800000); - ADVANCE_RING(); - } - } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) { - - int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; - - rb3d_cntl = depth_clear->rb3d_cntl; - - if (flags & RADEON_DEPTH) { - rb3d_cntl |= RADEON_Z_ENABLE; - } else { - rb3d_cntl &= ~RADEON_Z_ENABLE; - } - - if (flags & RADEON_STENCIL) { - rb3d_cntl |= RADEON_STENCIL_ENABLE; - rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ - } else { - rb3d_cntl &= ~RADEON_STENCIL_ENABLE; - rb3d_stencilrefmask = 0x00000000; - } - - if (flags & RADEON_USE_COMP_ZBUF) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | - RADEON_Z_DECOMPRESSION_ENABLE; - } - if (flags & RADEON_USE_HIERZ) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; - } - - BEGIN_RING(13); - RADEON_WAIT_UNTIL_2D_IDLE(); - - OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1)); - OUT_RING(0x00000000); - OUT_RING(rb3d_cntl); - - OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL); - OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask); - OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000); - OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl); - ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->ctx_owner = 0; - - for (i = 0; i < nbox; i++) { - - /* Funny that this should be required -- - * sets top-left? - */ - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - - BEGIN_RING(15); - - OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13)); - OUT_RING(RADEON_VTX_Z_PRESENT | - RADEON_VTX_PKCOLOR_PRESENT); - OUT_RING((RADEON_PRIM_TYPE_RECT_LIST | - RADEON_PRIM_WALK_RING | - RADEON_MAOS_ENABLE | - RADEON_VTX_FMT_RADEON_MODE | - (3 << RADEON_NUM_VERTICES_SHIFT))); - - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y1]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x0); - - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x0); - - OUT_RING(depth_boxes[i].ui[CLEAR_X2]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x0); - - ADVANCE_RING(); - } - } - - /* Increment the clear counter. The client-side 3D driver must - * wait on this value before performing the clear ioctl. We - * need this because the card's so damned fast... - */ - dev_priv->sarea_priv->last_clear++; - - BEGIN_RING(4); - - RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear); - RADEON_WAIT_UNTIL_IDLE(); - - ADVANCE_RING(); -} - -static void radeon_cp_dispatch_swap(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - /* Do some trivial performance monitoring... - */ - if (dev_priv->do_boxes) - radeon_cp_performance_boxes(dev_priv); - - /* Wait for the 3D stream to idle before dispatching the bitblt. - * This will prevent data corruption between the two streams. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h); - - BEGIN_RING(9); - - OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0)); - OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - - /* Make this work even if front & back are flipped: - */ - OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); - if (dev_priv->sarea_priv->pfCurrentPage == 0) { - OUT_RING(dev_priv->back_pitch_offset); - OUT_RING(dev_priv->front_pitch_offset); - } else { - OUT_RING(dev_priv->front_pitch_offset); - OUT_RING(dev_priv->back_pitch_offset); - } - - OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2)); - OUT_RING((x << 16) | y); - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->last_frame++; - - BEGIN_RING(4); - - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); - RADEON_WAIT_UNTIL_2D_IDLE(); - - ADVANCE_RING(); -} - -static void radeon_cp_dispatch_flip(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle; - int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) - ? dev_priv->front_offset : dev_priv->back_offset; - RING_LOCALS; - DRM_DEBUG("pfCurrentPage=%d\n", - dev_priv->sarea_priv->pfCurrentPage); - - /* Do some trivial performance monitoring... - */ - if (dev_priv->do_boxes) { - dev_priv->stats.boxes |= RADEON_BOX_FLIP; - radeon_cp_performance_boxes(dev_priv); - } - - /* Update the frame offsets for both CRTCs - */ - BEGIN_RING(6); - - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING_REG(RADEON_CRTC_OFFSET, - ((sarea->frame.y * dev_priv->front_pitch + - sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7) - + offset); - OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base - + offset); - - ADVANCE_RING(); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->last_frame++; - dev_priv->sarea_priv->pfCurrentPage = - 1 - dev_priv->sarea_priv->pfCurrentPage; - - BEGIN_RING(2); - - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); - - ADVANCE_RING(); -} - -static int bad_prim_vertex_nr(int primitive, int nr) -{ - switch (primitive & RADEON_PRIM_TYPE_MASK) { - case RADEON_PRIM_TYPE_NONE: - case RADEON_PRIM_TYPE_POINT: - return nr < 1; - case RADEON_PRIM_TYPE_LINE: - return (nr & 1) || nr == 0; - case RADEON_PRIM_TYPE_LINE_STRIP: - return nr < 2; - case RADEON_PRIM_TYPE_TRI_LIST: - case RADEON_PRIM_TYPE_3VRT_POINT_LIST: - case RADEON_PRIM_TYPE_3VRT_LINE_LIST: - case RADEON_PRIM_TYPE_RECT_LIST: - return nr % 3 || nr == 0; - case RADEON_PRIM_TYPE_TRI_FAN: - case RADEON_PRIM_TYPE_TRI_STRIP: - return nr < 3; - default: - return 1; - } -} - -typedef struct { - unsigned int start; - unsigned int finish; - unsigned int prim; - unsigned int numverts; - unsigned int offset; - unsigned int vc_format; -} drm_radeon_tcl_prim_t; - -static void radeon_cp_dispatch_vertex(struct drm_device * dev, - struct drm_buf * buf, - drm_radeon_tcl_prim_t * prim) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start; - int numverts = (int)prim->numverts; - int nbox = sarea_priv->nbox; - int i = 0; - RING_LOCALS; - - DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", - prim->prim, - prim->vc_format, prim->start, prim->finish, prim->numverts); - - if (bad_prim_vertex_nr(prim->prim, prim->numverts)) { - DRM_ERROR("bad prim %x numverts %d\n", - prim->prim, prim->numverts); - return; - } - - do { - /* Emit the next cliprect */ - if (i < nbox) { - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - } - - /* Emit the vertex buffer rendering commands */ - BEGIN_RING(5); - - OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3)); - OUT_RING(offset); - OUT_RING(numverts); - OUT_RING(prim->vc_format); - OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (numverts << RADEON_NUM_VERTICES_SHIFT)); - - ADVANCE_RING(); - - i++; - } while (i < nbox); -} - -static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - RING_LOCALS; - - buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - RADEON_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; -} - -static void radeon_cp_dispatch_indirect(struct drm_device * dev, - struct drm_buf * buf, int start, int end) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); - - if (start != end) { - int offset = (dev_priv->gart_buffers_offset - + buf->offset + start); - int dwords = (end - start + 3) / sizeof(u32); - - /* Indirect buffer data must be an even number of - * dwords, so if we've been given an odd number we must - * pad the data with a Type-2 CP packet. - */ - if (dwords & 1) { - u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = RADEON_CP_PACKET2; - } - - /* Fire off the indirect buffer */ - BEGIN_RING(3); - - OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); - OUT_RING(offset); - OUT_RING(dwords); - - ADVANCE_RING(); - } -} - -static void radeon_cp_dispatch_indices(struct drm_device * dev, - struct drm_buf * elt_buf, - drm_radeon_tcl_prim_t * prim) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - int offset = dev_priv->gart_buffers_offset + prim->offset; - u32 *data; - int dwords; - int i = 0; - int start = prim->start + RADEON_INDEX_PRIM_OFFSET; - int count = (prim->finish - start) / sizeof(u16); - int nbox = sarea_priv->nbox; - - DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", - prim->prim, - prim->vc_format, - prim->start, prim->finish, prim->offset, prim->numverts); - - if (bad_prim_vertex_nr(prim->prim, count)) { - DRM_ERROR("bad prim %x count %d\n", prim->prim, count); - return; - } - - if (start >= prim->finish || (prim->start & 0x7)) { - DRM_ERROR("buffer prim %d\n", prim->prim); - return; - } - - dwords = (prim->finish - prim->start + 3) / sizeof(u32); - - data = (u32 *) ((char *)dev->agp_buffer_map->handle + - elt_buf->offset + prim->start); - - data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2); - data[1] = offset; - data[2] = prim->numverts; - data[3] = prim->vc_format; - data[4] = (prim->prim | - RADEON_PRIM_WALK_IND | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (count << RADEON_NUM_VERTICES_SHIFT)); - - do { - if (i < nbox) - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - - radeon_cp_dispatch_indirect(dev, elt_buf, - prim->start, prim->finish); - - i++; - } while (i < nbox); - -} - -#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE - -static int radeon_cp_dispatch_texture(struct drm_device * dev, - struct drm_file *file_priv, - drm_radeon_texture_t * tex, - drm_radeon_tex_image_t * image) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - u32 format; - u32 *buffer; - const u8 __user *data; - int size, dwords, tex_width, blit_width, spitch; - u32 height; - int i; - u32 texpitch, microtile; - u32 offset, byte_offset; - RING_LOCALS; - - if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) { - DRM_ERROR("Invalid destination offset\n"); - return -EINVAL; - } - - dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; - - /* Flush the pixel cache. This ensures no pixel data gets mixed - * up with the texture data from the host data blit, otherwise - * part of the texture image may be corrupted. - */ - BEGIN_RING(4); - RADEON_FLUSH_CACHE(); - RADEON_WAIT_UNTIL_IDLE(); - ADVANCE_RING(); - - /* The compiler won't optimize away a division by a variable, - * even if the only legal values are powers of two. Thus, we'll - * use a shift instead. - */ - switch (tex->format) { - case RADEON_TXFORMAT_ARGB8888: - case RADEON_TXFORMAT_RGBA8888: - format = RADEON_COLOR_FORMAT_ARGB8888; - tex_width = tex->width * 4; - blit_width = image->width * 4; - break; - case RADEON_TXFORMAT_AI88: - case RADEON_TXFORMAT_ARGB1555: - case RADEON_TXFORMAT_RGB565: - case RADEON_TXFORMAT_ARGB4444: - case RADEON_TXFORMAT_VYUY422: - case RADEON_TXFORMAT_YVYU422: - format = RADEON_COLOR_FORMAT_RGB565; - tex_width = tex->width * 2; - blit_width = image->width * 2; - break; - case RADEON_TXFORMAT_I8: - case RADEON_TXFORMAT_RGB332: - format = RADEON_COLOR_FORMAT_CI8; - tex_width = tex->width * 1; - blit_width = image->width * 1; - break; - default: - DRM_ERROR("invalid texture format %d\n", tex->format); - return -EINVAL; - } - spitch = blit_width >> 6; - if (spitch == 0 && image->height > 1) - return -EINVAL; - - texpitch = tex->pitch; - if ((texpitch << 22) & RADEON_DST_TILE_MICRO) { - microtile = 1; - if (tex_width < 64) { - texpitch &= ~(RADEON_DST_TILE_MICRO >> 22); - /* we got tiled coordinates, untile them */ - image->x *= 2; - } - } else - microtile = 0; - - /* this might fail for zero-sized uploads - are those illegal? */ - if (!radeon_check_offset(dev_priv, tex->offset + image->height * - blit_width - 1)) { - DRM_ERROR("Invalid final destination offset\n"); - return -EINVAL; - } - - DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width); - - do { - DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", - tex->offset >> 10, tex->pitch, tex->format, - image->x, image->y, image->width, image->height); - - /* Make a copy of some parameters in case we have to - * update them for a multi-pass texture blit. - */ - height = image->height; - data = (const u8 __user *)image->data; - - size = height * blit_width; - - if (size > RADEON_MAX_TEXTURE_SIZE) { - height = RADEON_MAX_TEXTURE_SIZE / blit_width; - size = height * blit_width; - } else if (size < 4 && size > 0) { - size = 4; - } else if (size == 0) { - return 0; - } - - buf = radeon_freelist_get(dev); - if (0 && !buf) { - radeon_do_cp_idle(dev_priv); - buf = radeon_freelist_get(dev); - } - if (!buf) { - DRM_DEBUG("EAGAIN\n"); - if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) - return -EFAULT; - return -EAGAIN; - } - - /* Dispatch the indirect buffer. - */ - buffer = - (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); - dwords = size / 4; - -#define RADEON_COPY_MT(_buf, _data, _width) \ - do { \ - if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ - DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ - return -EFAULT; \ - } \ - } while(0) - - if (microtile) { - /* texture micro tiling in use, minimum texture width is thus 16 bytes. - however, we cannot use blitter directly for texture width < 64 bytes, - since minimum tex pitch is 64 bytes and we need this to match - the texture width, otherwise the blitter will tile it wrong. - Thus, tiling manually in this case. Additionally, need to special - case tex height = 1, since our actual image will have height 2 - and we need to ensure we don't read beyond the texture size - from user space. */ - if (tex->height == 1) { - if (tex_width >= 64 || tex_width <= 16) { - RADEON_COPY_MT(buffer, data, - (int)(tex_width * sizeof(u32))); - } else if (tex_width == 32) { - RADEON_COPY_MT(buffer, data, 16); - RADEON_COPY_MT(buffer + 8, - data + 16, 16); - } - } else if (tex_width >= 64 || tex_width == 16) { - RADEON_COPY_MT(buffer, data, - (int)(dwords * sizeof(u32))); - } else if (tex_width < 16) { - for (i = 0; i < tex->height; i++) { - RADEON_COPY_MT(buffer, data, tex_width); - buffer += 4; - data += tex_width; - } - } else if (tex_width == 32) { - /* TODO: make sure this works when not fitting in one buffer - (i.e. 32bytes x 2048...) */ - for (i = 0; i < tex->height; i += 2) { - RADEON_COPY_MT(buffer, data, 16); - data += 16; - RADEON_COPY_MT(buffer + 8, data, 16); - data += 16; - RADEON_COPY_MT(buffer + 4, data, 16); - data += 16; - RADEON_COPY_MT(buffer + 12, data, 16); - data += 16; - buffer += 16; - } - } - } else { - if (tex_width >= 32) { - /* Texture image width is larger than the minimum, so we - * can upload it directly. - */ - RADEON_COPY_MT(buffer, data, - (int)(dwords * sizeof(u32))); - } else { - /* Texture image width is less than the minimum, so we - * need to pad out each image scanline to the minimum - * width. - */ - for (i = 0; i < tex->height; i++) { - RADEON_COPY_MT(buffer, data, tex_width); - buffer += 8; - data += tex_width; - } - } - } - -#undef RADEON_COPY_MT - byte_offset = (image->y & ~2047) * blit_width; - buf->file_priv = file_priv; - buf->used = size; - offset = dev_priv->gart_buffers_offset + buf->offset; - BEGIN_RING(9); - OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); - OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (format << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - OUT_RING((spitch << 22) | (offset >> 10)); - OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10))); - OUT_RING(0); - OUT_RING((image->x << 16) | (image->y % 2048)); - OUT_RING((image->width << 16) | height); - RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - COMMIT_RING(); - - radeon_cp_discard_buffer(dev, buf); - - /* Update the input parameters for next time */ - image->y += height; - image->height -= height; - image->data = (const u8 __user *)image->data + size; - } while (image->height > 0); - - /* Flush the pixel cache after the blit completes. This ensures - * the texture data is written out to memory before rendering - * continues. - */ - BEGIN_RING(4); - RADEON_FLUSH_CACHE(); - RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - COMMIT_RING(); - - return 0; -} - -static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(35); - - OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0)); - OUT_RING(0x00000000); - - OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31)); - for (i = 0; i < 32; i++) { - OUT_RING(stipple[i]); - } - - ADVANCE_RING(); -} - -static void radeon_apply_surface_regs(int surf_index, - drm_radeon_private_t *dev_priv) -{ - if (!dev_priv->mmio) - return; - - radeon_do_cp_idle(dev_priv); - - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index, - dev_priv->surfaces[surf_index].flags); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index, - dev_priv->surfaces[surf_index].lower); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index, - dev_priv->surfaces[surf_index].upper); -} - -/* Allocates a virtual surface - * doesn't always allocate a real surface, will stretch an existing - * surface when possible. - * - * Note that refcount can be at most 2, since during a free refcount=3 - * might mean we have to allocate a new surface which might not always - * be available. - * For example : we allocate three contigous surfaces ABC. If B is - * freed, we suddenly need two surfaces to store A and C, which might - * not always be available. - */ -static int alloc_surface(drm_radeon_surface_alloc_t *new, - drm_radeon_private_t *dev_priv, - struct drm_file *file_priv) -{ - struct radeon_virt_surface *s; - int i; - int virt_surface_index; - uint32_t new_upper, new_lower; - - new_lower = new->address; - new_upper = new_lower + new->size - 1; - - /* sanity check */ - if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) || - ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != - RADEON_SURF_ADDRESS_FIXED_MASK) - || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0)) - return -1; - - /* make sure there is no overlap with existing surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - if ((dev_priv->surfaces[i].refcount != 0) && - (((new_lower >= dev_priv->surfaces[i].lower) && - (new_lower < dev_priv->surfaces[i].upper)) || - ((new_lower < dev_priv->surfaces[i].lower) && - (new_upper > dev_priv->surfaces[i].lower)))) { - return -1; - } - } - - /* find a virtual surface */ - for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) - if (dev_priv->virt_surfaces[i].file_priv == 0) - break; - if (i == 2 * RADEON_MAX_SURFACES) { - return -1; - } - virt_surface_index = i; - - /* try to reuse an existing surface */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - /* extend before */ - if ((dev_priv->surfaces[i].refcount == 1) && - (new->flags == dev_priv->surfaces[i].flags) && - (new_upper + 1 == dev_priv->surfaces[i].lower)) { - s = &(dev_priv->virt_surfaces[virt_surface_index]); - s->surface_index = i; - s->lower = new_lower; - s->upper = new_upper; - s->flags = new->flags; - s->file_priv = file_priv; - dev_priv->surfaces[i].refcount++; - dev_priv->surfaces[i].lower = s->lower; - radeon_apply_surface_regs(s->surface_index, dev_priv); - return virt_surface_index; - } - - /* extend after */ - if ((dev_priv->surfaces[i].refcount == 1) && - (new->flags == dev_priv->surfaces[i].flags) && - (new_lower == dev_priv->surfaces[i].upper + 1)) { - s = &(dev_priv->virt_surfaces[virt_surface_index]); - s->surface_index = i; - s->lower = new_lower; - s->upper = new_upper; - s->flags = new->flags; - s->file_priv = file_priv; - dev_priv->surfaces[i].refcount++; - dev_priv->surfaces[i].upper = s->upper; - radeon_apply_surface_regs(s->surface_index, dev_priv); - return virt_surface_index; - } - } - - /* okay, we need a new one */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - if (dev_priv->surfaces[i].refcount == 0) { - s = &(dev_priv->virt_surfaces[virt_surface_index]); - s->surface_index = i; - s->lower = new_lower; - s->upper = new_upper; - s->flags = new->flags; - s->file_priv = file_priv; - dev_priv->surfaces[i].refcount = 1; - dev_priv->surfaces[i].lower = s->lower; - dev_priv->surfaces[i].upper = s->upper; - dev_priv->surfaces[i].flags = s->flags; - radeon_apply_surface_regs(s->surface_index, dev_priv); - return virt_surface_index; - } - } - - /* we didn't find anything */ - return -1; -} - -static int free_surface(struct drm_file *file_priv, - drm_radeon_private_t * dev_priv, - int lower) -{ - struct radeon_virt_surface *s; - int i; - /* find the virtual surface */ - for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { - s = &(dev_priv->virt_surfaces[i]); - if (s->file_priv) { - if ((lower == s->lower) && (file_priv == s->file_priv)) - { - if (dev_priv->surfaces[s->surface_index]. - lower == s->lower) - dev_priv->surfaces[s->surface_index]. - lower = s->upper; - - if (dev_priv->surfaces[s->surface_index]. - upper == s->upper) - dev_priv->surfaces[s->surface_index]. - upper = s->lower; - - dev_priv->surfaces[s->surface_index].refcount--; - if (dev_priv->surfaces[s->surface_index]. - refcount == 0) - dev_priv->surfaces[s->surface_index]. - flags = 0; - s->file_priv = NULL; - radeon_apply_surface_regs(s->surface_index, - dev_priv); - return 0; - } - } - } - return 1; -} - -static void radeon_surfaces_release(struct drm_file *file_priv, - drm_radeon_private_t * dev_priv) -{ - int i; - for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { - if (dev_priv->virt_surfaces[i].file_priv == file_priv) - free_surface(file_priv, dev_priv, - dev_priv->virt_surfaces[i].lower); - } -} - -/* ================================================================ - * IOCTL functions - */ -static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_surface_alloc_t *alloc = data; - - if (alloc_surface(alloc, dev_priv, file_priv) == -1) - return -EINVAL; - else - return 0; -} - -static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_surface_free_t *memfree = data; - - if (free_surface(file_priv, dev_priv, memfree->address)) - return -EINVAL; - else - return 0; -} - -static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_clear_t *clear = data; - drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - - if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes, - sarea_priv->nbox * sizeof(depth_boxes[0]))) - return -EFAULT; - - radeon_cp_dispatch_clear(dev, clear, depth_boxes); - - COMMIT_RING(); - return 0; -} - -/* Not sure why this isn't set all the time: - */ -static int radeon_do_init_pageflip(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - DRM_DEBUG("\n"); - - BEGIN_RING(6); - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0)); - OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) | - RADEON_CRTC_OFFSET_FLIP_CNTL); - OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0)); - OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) | - RADEON_CRTC_OFFSET_FLIP_CNTL); - ADVANCE_RING(); - - dev_priv->page_flipping = 1; - - if (dev_priv->sarea_priv->pfCurrentPage != 1) - dev_priv->sarea_priv->pfCurrentPage = 0; - - return 0; -} - -/* Swapping and flipping are different operations, need different ioctls. - * They can & should be intermixed to support multiple 3d windows. - */ -static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (!dev_priv->page_flipping) - radeon_do_init_pageflip(dev); - - radeon_cp_dispatch_flip(dev); - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - - radeon_cp_dispatch_swap(dev); - dev_priv->sarea_priv->ctx_owner = 0; - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_vertex_t *vertex = data; - drm_radeon_tcl_prim_t prim; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); - - if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - vertex->idx, dma->buf_count - 1); - return -EINVAL; - } - if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { - DRM_ERROR("buffer prim %d\n", vertex->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[vertex->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex->idx); - return -EINVAL; - } - - /* Build up a prim_t record: - */ - if (vertex->count) { - buf->used = vertex->count; /* not used? */ - - if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { - if (radeon_emit_state(dev_priv, file_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty)) { - DRM_ERROR("radeon_emit_state failed\n"); - return -EINVAL; - } - - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); - } - - prim.start = 0; - prim.finish = vertex->count; /* unused */ - prim.prim = vertex->prim; - prim.numverts = vertex->count; - prim.vc_format = dev_priv->sarea_priv->vc_format; - - radeon_cp_dispatch_vertex(dev, buf, &prim); - } - - if (vertex->discard) { - radeon_cp_discard_buffer(dev, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_indices_t *elts = data; - drm_radeon_tcl_prim_t prim; - int count; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", - DRM_CURRENTPID, elts->idx, elts->start, elts->end, - elts->discard); - - if (elts->idx < 0 || elts->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - elts->idx, dma->buf_count - 1); - return -EINVAL; - } - if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { - DRM_ERROR("buffer prim %d\n", elts->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[elts->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", elts->idx); - return -EINVAL; - } - - count = (elts->end - elts->start) / sizeof(u16); - elts->start -= RADEON_INDEX_PRIM_OFFSET; - - if (elts->start & 0x7) { - DRM_ERROR("misaligned buffer 0x%x\n", elts->start); - return -EINVAL; - } - if (elts->start < buf->used) { - DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); - return -EINVAL; - } - - buf->used = elts->end; - - if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { - if (radeon_emit_state(dev_priv, file_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty)) { - DRM_ERROR("radeon_emit_state failed\n"); - return -EINVAL; - } - - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); - } - - /* Build up a prim_t record: - */ - prim.start = elts->start; - prim.finish = elts->end; - prim.prim = elts->prim; - prim.offset = 0; /* offset from start of dma buffers */ - prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - prim.vc_format = dev_priv->sarea_priv->vc_format; - - radeon_cp_dispatch_indices(dev, buf, &prim); - if (elts->discard) { - radeon_cp_discard_buffer(dev, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_texture_t *tex = data; - drm_radeon_tex_image_t image; - int ret; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (tex->image == NULL) { - DRM_ERROR("null texture image!\n"); - return -EINVAL; - } - - if (DRM_COPY_FROM_USER(&image, - (drm_radeon_tex_image_t __user *) tex->image, - sizeof(image))) - return -EFAULT; - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); - - return ret; -} - -static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_stipple_t *stipple = data; - u32 mask[32]; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) - return -EFAULT; - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - radeon_cp_dispatch_stipple(dev, mask); - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_indirect_t *indirect = data; - RING_LOCALS; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", - indirect->idx, indirect->start, indirect->end, - indirect->discard); - - if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - indirect->idx, dma->buf_count - 1); - return -EINVAL; - } - - buf = dma->buflist[indirect->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", indirect->idx); - return -EINVAL; - } - - if (indirect->start < buf->used) { - DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", - indirect->start, buf->used); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf->used = indirect->end; - - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - - /* Dispatch the indirect buffer full of commands from the - * X server. This is insecure and is thus only available to - * privileged clients. - */ - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - if (indirect->discard) { - radeon_cp_discard_buffer(dev, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_vertex2_t *vertex = data; - int i; - unsigned char laststate; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("pid=%d index=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->discard); - - if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - vertex->idx, dma->buf_count - 1); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[vertex->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex->idx); - return -EINVAL; - } - - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - return -EINVAL; - - for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) { - drm_radeon_prim_t prim; - drm_radeon_tcl_prim_t tclprim; - - if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim))) - return -EFAULT; - - if (prim.stateidx != laststate) { - drm_radeon_state_t state; - - if (DRM_COPY_FROM_USER(&state, - &vertex->state[prim.stateidx], - sizeof(state))) - return -EFAULT; - - if (radeon_emit_state2(dev_priv, file_priv, &state)) { - DRM_ERROR("radeon_emit_state2 failed\n"); - return -EINVAL; - } - - laststate = prim.stateidx; - } - - tclprim.start = prim.start; - tclprim.finish = prim.finish; - tclprim.prim = prim.prim; - tclprim.vc_format = prim.vc_format; - - if (prim.prim & RADEON_PRIM_WALK_IND) { - tclprim.offset = prim.numverts * 64; - tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - - radeon_cp_dispatch_indices(dev, buf, &tclprim); - } else { - tclprim.numverts = prim.numverts; - tclprim.offset = 0; /* not used */ - - radeon_cp_dispatch_vertex(dev, buf, &tclprim); - } - - if (sarea_priv->nbox == 1) - sarea_priv->nbox = 0; - } - - if (vertex->discard) { - radeon_cp_discard_buffer(dev, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_emit_packets(drm_radeon_private_t * dev_priv, - struct drm_file *file_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int id = (int)header.packet.packet_id; - int sz, reg; - int *data = (int *)cmdbuf->buf; - RING_LOCALS; - - if (id >= RADEON_MAX_STATE_PACKETS) - return -EINVAL; - - sz = packet[id].len; - reg = packet[id].start; - - if (sz * sizeof(int) > cmdbuf->bufsz) { - DRM_ERROR("Packet size provided larger than data provided\n"); - return -EINVAL; - } - - if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, data)) { - DRM_ERROR("Packet verification failed\n"); - return -EINVAL; - } - - BEGIN_RING(sz + 1); - OUT_RING(CP_PACKET0(reg, (sz - 1))); - OUT_RING_TABLE(data, sz); - ADVANCE_RING(); - - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); - return 0; -} - -static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.scalars.count; - int start = header.scalars.offset; - int stride = header.scalars.stride; - RING_LOCALS; - - BEGIN_RING(3 + sz); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); - OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); - OUT_RING_TABLE(cmdbuf->buf, sz); - ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); - return 0; -} - -/* God this is ugly - */ -static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.scalars.count; - int start = ((unsigned int)header.scalars.offset) + 0x100; - int stride = header.scalars.stride; - RING_LOCALS; - - BEGIN_RING(3 + sz); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); - OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); - OUT_RING_TABLE(cmdbuf->buf, sz); - ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); - return 0; -} - -static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.vectors.count; - int start = header.vectors.offset; - int stride = header.vectors.stride; - RING_LOCALS; - - BEGIN_RING(5 + sz); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); - OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_TABLE(cmdbuf->buf, sz); - ADVANCE_RING(); - - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); - return 0; -} - -static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.veclinear.count * 4; - int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8); - RING_LOCALS; - - if (!sz) - return 0; - if (sz * 4 > cmdbuf->bufsz) - return -EINVAL; - - BEGIN_RING(5 + sz); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); - OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_TABLE(cmdbuf->buf, sz); - ADVANCE_RING(); - - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); - return 0; -} - -static int radeon_emit_packet3(struct drm_device * dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - unsigned int cmdsz; - int ret; - RING_LOCALS; - - DRM_DEBUG("\n"); - - if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv, - cmdbuf, &cmdsz))) { - DRM_ERROR("Packet verification failed\n"); - return ret; - } - - BEGIN_RING(cmdsz); - OUT_RING_TABLE(cmdbuf->buf, cmdsz); - ADVANCE_RING(); - - cmdbuf->buf += cmdsz * 4; - cmdbuf->bufsz -= cmdsz * 4; - return 0; -} - -static int radeon_emit_packet3_cliprect(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - int orig_nbox) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_clip_rect box; - unsigned int cmdsz; - int ret; - struct drm_clip_rect __user *boxes = cmdbuf->boxes; - int i = 0; - RING_LOCALS; - - DRM_DEBUG("\n"); - - if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv, - cmdbuf, &cmdsz))) { - DRM_ERROR("Packet verification failed\n"); - return ret; - } - - if (!orig_nbox) - goto out; - - do { - if (i < cmdbuf->nbox) { - if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box))) - return -EFAULT; - /* FIXME The second and subsequent times round - * this loop, send a WAIT_UNTIL_3D_IDLE before - * calling emit_clip_rect(). This fixes a - * lockup on fast machines when sending - * several cliprects with a cmdbuf, as when - * waving a 2D window over a 3D - * window. Something in the commands from user - * space seems to hang the card when they're - * sent several times in a row. That would be - * the correct place to fix it but this works - * around it until I can figure that out - Tim - * Smith */ - if (i) { - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); - } - radeon_emit_clip_rect(dev_priv, &box); - } - - BEGIN_RING(cmdsz); - OUT_RING_TABLE(cmdbuf->buf, cmdsz); - ADVANCE_RING(); - - } while (++i < cmdbuf->nbox); - if (cmdbuf->nbox == 1) - cmdbuf->nbox = 0; - - out: - cmdbuf->buf += cmdsz * 4; - cmdbuf->bufsz -= cmdsz * 4; - return 0; -} - -static int radeon_emit_wait(struct drm_device * dev, int flags) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - DRM_DEBUG("%x\n", flags); - switch (flags) { - case RADEON_WAIT_2D: - BEGIN_RING(2); - RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - break; - case RADEON_WAIT_3D: - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); - break; - case RADEON_WAIT_2D | RADEON_WAIT_3D: - BEGIN_RING(2); - RADEON_WAIT_UNTIL_IDLE(); - ADVANCE_RING(); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf = NULL; - int idx; - drm_radeon_kcmd_buffer_t *cmdbuf = data; - drm_radeon_cmd_header_t header; - int orig_nbox, orig_bufsz; - char *kbuf = NULL; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) { - return -EINVAL; - } - - /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid - * races between checking values and using those values in other code, - * and simply to avoid a lot of function calls to copy in data. - */ - orig_bufsz = cmdbuf->bufsz; - if (orig_bufsz != 0) { - kbuf = drm_alloc(cmdbuf->bufsz, DRM_MEM_DRIVER); - if (kbuf == NULL) - return -ENOMEM; - if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf, - cmdbuf->bufsz)) { - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - return -EFAULT; - } - cmdbuf->buf = kbuf; - } - - orig_nbox = cmdbuf->nbox; - - if (dev_priv->microcode_version == UCODE_R300) { - int temp; - temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); - - if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - - return temp; - } - - /* microcode_version != r300 */ - while (cmdbuf->bufsz >= sizeof(header)) { - - header.i = *(int *)cmdbuf->buf; - cmdbuf->buf += sizeof(header); - cmdbuf->bufsz -= sizeof(header); - - switch (header.header.cmd_type) { - case RADEON_CMD_PACKET: - DRM_DEBUG("RADEON_CMD_PACKET\n"); - if (radeon_emit_packets - (dev_priv, file_priv, header, cmdbuf)) { - DRM_ERROR("radeon_emit_packets failed\n"); - goto err; - } - break; - - case RADEON_CMD_SCALARS: - DRM_DEBUG("RADEON_CMD_SCALARS\n"); - if (radeon_emit_scalars(dev_priv, header, cmdbuf)) { - DRM_ERROR("radeon_emit_scalars failed\n"); - goto err; - } - break; - - case RADEON_CMD_VECTORS: - DRM_DEBUG("RADEON_CMD_VECTORS\n"); - if (radeon_emit_vectors(dev_priv, header, cmdbuf)) { - DRM_ERROR("radeon_emit_vectors failed\n"); - goto err; - } - break; - - case RADEON_CMD_DMA_DISCARD: - DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); - idx = header.dma.buf_idx; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - idx, dma->buf_count - 1); - goto err; - } - - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv || buf->pending) { - DRM_ERROR("bad buffer %p %p %d\n", - buf->file_priv, file_priv, - buf->pending); - goto err; - } - - radeon_cp_discard_buffer(dev, buf); - break; - - case RADEON_CMD_PACKET3: - DRM_DEBUG("RADEON_CMD_PACKET3\n"); - if (radeon_emit_packet3(dev, file_priv, cmdbuf)) { - DRM_ERROR("radeon_emit_packet3 failed\n"); - goto err; - } - break; - - case RADEON_CMD_PACKET3_CLIP: - DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); - if (radeon_emit_packet3_cliprect - (dev, file_priv, cmdbuf, orig_nbox)) { - DRM_ERROR("radeon_emit_packet3_clip failed\n"); - goto err; - } - break; - - case RADEON_CMD_SCALARS2: - DRM_DEBUG("RADEON_CMD_SCALARS2\n"); - if (radeon_emit_scalars2(dev_priv, header, cmdbuf)) { - DRM_ERROR("radeon_emit_scalars2 failed\n"); - goto err; - } - break; - - case RADEON_CMD_WAIT: - DRM_DEBUG("RADEON_CMD_WAIT\n"); - if (radeon_emit_wait(dev, header.wait.flags)) { - DRM_ERROR("radeon_emit_wait failed\n"); - goto err; - } - break; - case RADEON_CMD_VECLINEAR: - DRM_DEBUG("RADEON_CMD_VECLINEAR\n"); - if (radeon_emit_veclinear(dev_priv, header, cmdbuf)) { - DRM_ERROR("radeon_emit_veclinear failed\n"); - goto err; - } - break; - - default: - DRM_ERROR("bad cmd_type %d at %p\n", - header.header.cmd_type, - cmdbuf->buf - sizeof(header)); - goto err; - } - } - - if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - - DRM_DEBUG("DONE\n"); - COMMIT_RING(); - return 0; - - err: - if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - return -EINVAL; -} - -static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_getparam_t *param = data; - int value; - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - switch (param->param) { - case RADEON_PARAM_GART_BUFFER_OFFSET: - value = dev_priv->gart_buffers_offset; - break; - case RADEON_PARAM_LAST_FRAME: - dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH(0); - break; - case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH(1); - break; - case RADEON_PARAM_LAST_CLEAR: - dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH(2); - break; - case RADEON_PARAM_IRQ_NR: - value = dev->irq; - break; - case RADEON_PARAM_GART_BASE: - value = dev_priv->gart_vm_start; - break; - case RADEON_PARAM_REGISTER_HANDLE: - value = dev_priv->mmio->offset; - break; - case RADEON_PARAM_STATUS_HANDLE: - value = dev_priv->ring_rptr_offset; - break; -#if BITS_PER_LONG == 32 - /* - * This ioctl() doesn't work on 64-bit platforms because hw_lock is a - * pointer which can't fit into an int-sized variable. According to - * Michel Dänzer, the ioctl() is only used on embedded platforms, so - * not supporting it shouldn't be a problem. If the same functionality - * is needed on 64-bit platforms, a new ioctl() would have to be added, - * so backwards-compatibility for the embedded platforms can be - * maintained. --davidm 4-Feb-2004. - */ - case RADEON_PARAM_SAREA_HANDLE: - /* The lock is the first dword in the sarea. */ - value = (long)dev->lock.hw_lock; - break; -#endif - case RADEON_PARAM_GART_TEX_HANDLE: - value = dev_priv->gart_textures_offset; - break; - case RADEON_PARAM_SCRATCH_OFFSET: - if (!dev_priv->writeback_works) - return -EINVAL; - value = RADEON_SCRATCH_REG_OFFSET; - break; - case RADEON_PARAM_CARD_TYPE: - if (dev_priv->flags & RADEON_IS_PCIE) - value = RADEON_CARD_PCIE; - else if (dev_priv->flags & RADEON_IS_AGP) - value = RADEON_CARD_AGP; - else - value = RADEON_CARD_PCI; - break; - case RADEON_PARAM_VBLANK_CRTC: - value = radeon_vblank_crtc_get(dev); - break; - case RADEON_PARAM_FB_LOCATION: - value = radeon_read_fb_location(dev_priv); - break; - case RADEON_PARAM_NUM_GB_PIPES: - value = dev_priv->num_gb_pipes; - break; - default: - DRM_DEBUG("Invalid parameter %d\n", param->param); - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_setparam_t *sp = data; - struct drm_radeon_driver_file_fields *radeon_priv; - - switch (sp->param) { - case RADEON_SETPARAM_FB_LOCATION: - radeon_priv = file_priv->driver_priv; - radeon_priv->radeon_fb_delta = dev_priv->fb_location - - sp->value; - break; - case RADEON_SETPARAM_SWITCH_TILING: - if (sp->value == 0) { - DRM_DEBUG("color tiling disabled\n"); - dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; - dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO; - dev_priv->sarea_priv->tiling_enabled = 0; - } else if (sp->value == 1) { - DRM_DEBUG("color tiling enabled\n"); - dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO; - dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO; - dev_priv->sarea_priv->tiling_enabled = 1; - } - break; - case RADEON_SETPARAM_PCIGART_LOCATION: - dev_priv->pcigart_offset = sp->value; - dev_priv->pcigart_offset_set = 1; - break; - case RADEON_SETPARAM_NEW_MEMMAP: - dev_priv->new_memmap = sp->value; - break; - case RADEON_SETPARAM_PCIGART_TABLE_SIZE: - dev_priv->gart_info.table_size = sp->value; - if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) - dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - break; - case RADEON_SETPARAM_VBLANK_CRTC: - return radeon_vblank_crtc_set(dev, sp->value); - break; - default: - DRM_DEBUG("Invalid parameter %d\n", sp->param); - return -EINVAL; - } - - return 0; -} - -/* When a client dies: - * - Check for and clean up flipped page state - * - Free any alloced GART memory. - * - Free any alloced radeon surfaces. - * - * DRM infrastructure takes care of reclaiming dma buffers. - */ -void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - dev_priv->page_flipping = 0; - radeon_mem_release(file_priv, dev_priv->gart_heap); - radeon_mem_release(file_priv, dev_priv->fb_heap); - radeon_surfaces_release(file_priv, dev_priv); - } -} - -void radeon_driver_lastclose(struct drm_device *dev) -{ - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (dev_priv->sarea_priv && - dev_priv->sarea_priv->pfCurrentPage != 0) - radeon_cp_dispatch_flip(dev); - } - - radeon_do_release(dev); -} - -int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_driver_file_fields *radeon_priv; - - DRM_DEBUG("\n"); - radeon_priv = - (struct drm_radeon_driver_file_fields *) - drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); - - if (!radeon_priv) - return -ENOMEM; - - file_priv->driver_priv = radeon_priv; - - if (dev_priv) - radeon_priv->radeon_fb_delta = dev_priv->fb_location; - else - radeon_priv->radeon_fb_delta = 0; - return 0; -} - -void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_radeon_driver_file_fields *radeon_priv = - file_priv->driver_priv; - - drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); -} - -struct drm_ioctl_desc radeon_ioctls[] = { - DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) -}; - -int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c deleted file mode 100644 index d465b2f..0000000 --- a/drivers/char/drm/savage_bci.c +++ /dev/null @@ -1,1095 +0,0 @@ -/* savage_bci.c -- BCI support for Savage - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" - -/* Need a long timeout for shadow status updates can take a while - * and so can waiting for events when the queue is full. */ -#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */ -#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ -#define SAVAGE_FREELIST_DEBUG 0 - -static int savage_do_cleanup_bci(struct drm_device *dev); - -static int -savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n) -{ - uint32_t mask = dev_priv->status_used_mask; - uint32_t threshold = dev_priv->bci_threshold_hi; - uint32_t status; - int i; - -#if SAVAGE_BCI_DEBUG - if (n > dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - threshold) - DRM_ERROR("Trying to emit %d words " - "(more than guaranteed space in COB)\n", n); -#endif - - for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { - DRM_MEMORYBARRIER(); - status = dev_priv->status_ptr[0]; - if ((status & mask) < threshold) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x, threshold=0x%08x\n", status, threshold); -#endif - return -EBUSY; -} - -static int -savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n) -{ - uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { - status = SAVAGE_READ(SAVAGE_STATUS_WORD0); - if ((status & SAVAGE_FIFO_USED_MASK_S3D) <= maxUsed) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x\n", status); -#endif - return -EBUSY; -} - -static int -savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n) -{ - uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { - status = SAVAGE_READ(SAVAGE_ALT_STATUS_WORD0); - if ((status & SAVAGE_FIFO_USED_MASK_S4) <= maxUsed) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x\n", status); -#endif - return -EBUSY; -} - -/* - * Waiting for events. - * - * The BIOSresets the event tag to 0 on mode changes. Therefore we - * never emit 0 to the event tag. If we find a 0 event tag we know the - * BIOS stomped on it and return success assuming that the BIOS waited - * for engine idle. - * - * Note: if the Xserver uses the event tag it has to follow the same - * rule. Otherwise there may be glitches every 2^16 events. - */ -static int -savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e) -{ - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) { - DRM_MEMORYBARRIER(); - status = dev_priv->status_ptr[1]; - if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff || - (status & 0xffff) == 0) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); -#endif - - return -EBUSY; -} - -static int -savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e) -{ - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) { - status = SAVAGE_READ(SAVAGE_STATUS_WORD1); - if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff || - (status & 0xffff) == 0) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); -#endif - - return -EBUSY; -} - -uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv, - unsigned int flags) -{ - uint16_t count; - BCI_LOCALS; - - if (dev_priv->status_ptr) { - /* coordinate with Xserver */ - count = dev_priv->status_ptr[1023]; - if (count < dev_priv->event_counter) - dev_priv->event_wrap++; - } else { - count = dev_priv->event_counter; - } - count = (count + 1) & 0xffff; - if (count == 0) { - count++; /* See the comment above savage_wait_event_*. */ - dev_priv->event_wrap++; - } - dev_priv->event_counter = count; - if (dev_priv->status_ptr) - dev_priv->status_ptr[1023] = (uint32_t) count; - - if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) { - unsigned int wait_cmd = BCI_CMD_WAIT; - if ((flags & SAVAGE_WAIT_2D)) - wait_cmd |= BCI_CMD_WAIT_2D; - if ((flags & SAVAGE_WAIT_3D)) - wait_cmd |= BCI_CMD_WAIT_3D; - BEGIN_BCI(2); - BCI_WRITE(wait_cmd); - } else { - BEGIN_BCI(1); - } - BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count); - - return count; -} - -/* - * Freelist management - */ -static int savage_freelist_init(struct drm_device * dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_savage_buf_priv_t *entry; - int i; - DRM_DEBUG("count=%d\n", dma->buf_count); - - dev_priv->head.next = &dev_priv->tail; - dev_priv->head.prev = NULL; - dev_priv->head.buf = NULL; - - dev_priv->tail.next = NULL; - dev_priv->tail.prev = &dev_priv->head; - dev_priv->tail.buf = NULL; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - entry = buf->dev_private; - - SET_AGE(&entry->age, 0, 0); - entry->buf = buf; - - entry->next = dev_priv->head.next; - entry->prev = &dev_priv->head; - dev_priv->head.next->prev = entry; - dev_priv->head.next = entry; - } - - return 0; -} - -static struct drm_buf *savage_freelist_get(struct drm_device * dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_buf_priv_t *tail = dev_priv->tail.prev; - uint16_t event; - unsigned int wrap; - DRM_DEBUG("\n"); - - UPDATE_EVENT_COUNTER(); - if (dev_priv->status_ptr) - event = dev_priv->status_ptr[1] & 0xffff; - else - event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; - wrap = dev_priv->event_wrap; - if (event > dev_priv->event_counter) - wrap--; /* hardware hasn't passed the last wrap yet */ - - DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap); - DRM_DEBUG(" head=0x%04x %d\n", event, wrap); - - if (tail->buf && (TEST_AGE(&tail->age, event, wrap) || event == 0)) { - drm_savage_buf_priv_t *next = tail->next; - drm_savage_buf_priv_t *prev = tail->prev; - prev->next = next; - next->prev = prev; - tail->next = tail->prev = NULL; - return tail->buf; - } - - DRM_DEBUG("returning NULL, tail->buf=%p!\n", tail->buf); - return NULL; -} - -void savage_freelist_put(struct drm_device * dev, struct drm_buf * buf) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next; - - DRM_DEBUG("age=0x%04x wrap=%d\n", entry->age.event, entry->age.wrap); - - if (entry->next != NULL || entry->prev != NULL) { - DRM_ERROR("entry already on freelist.\n"); - return; - } - - prev = &dev_priv->head; - next = prev->next; - prev->next = entry; - next->prev = entry; - entry->prev = prev; - entry->next = next; -} - -/* - * Command DMA - */ -static int savage_dma_init(drm_savage_private_t * dev_priv) -{ - unsigned int i; - - dev_priv->nr_dma_pages = dev_priv->cmd_dma->size / - (SAVAGE_DMA_PAGE_SIZE * 4); - dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) * - dev_priv->nr_dma_pages, DRM_MEM_DRIVER); - if (dev_priv->dma_pages == NULL) - return -ENOMEM; - - for (i = 0; i < dev_priv->nr_dma_pages; ++i) { - SET_AGE(&dev_priv->dma_pages[i].age, 0, 0); - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - SET_AGE(&dev_priv->last_dma_age, 0, 0); - - dev_priv->first_dma_page = 0; - dev_priv->current_dma_page = 0; - - return 0; -} - -void savage_dma_reset(drm_savage_private_t * dev_priv) -{ - uint16_t event; - unsigned int wrap, i; - event = savage_bci_emit_event(dev_priv, 0); - wrap = dev_priv->event_wrap; - for (i = 0; i < dev_priv->nr_dma_pages; ++i) { - SET_AGE(&dev_priv->dma_pages[i].age, event, wrap); - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - SET_AGE(&dev_priv->last_dma_age, event, wrap); - dev_priv->first_dma_page = dev_priv->current_dma_page = 0; -} - -void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page) -{ - uint16_t event; - unsigned int wrap; - - /* Faked DMA buffer pages don't age. */ - if (dev_priv->cmd_dma == &dev_priv->fake_dma) - return; - - UPDATE_EVENT_COUNTER(); - if (dev_priv->status_ptr) - event = dev_priv->status_ptr[1] & 0xffff; - else - event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; - wrap = dev_priv->event_wrap; - if (event > dev_priv->event_counter) - wrap--; /* hardware hasn't passed the last wrap yet */ - - if (dev_priv->dma_pages[page].age.wrap > wrap || - (dev_priv->dma_pages[page].age.wrap == wrap && - dev_priv->dma_pages[page].age.event > event)) { - if (dev_priv->wait_evnt(dev_priv, - dev_priv->dma_pages[page].age.event) - < 0) - DRM_ERROR("wait_evnt failed!\n"); - } -} - -uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n) -{ - unsigned int cur = dev_priv->current_dma_page; - unsigned int rest = SAVAGE_DMA_PAGE_SIZE - - dev_priv->dma_pages[cur].used; - unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) / - SAVAGE_DMA_PAGE_SIZE; - uint32_t *dma_ptr; - unsigned int i; - - DRM_DEBUG("cur=%u, cur->used=%u, n=%u, rest=%u, nr_pages=%u\n", - cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages); - - if (cur + nr_pages < dev_priv->nr_dma_pages) { - dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + - cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used; - if (n < rest) - rest = n; - dev_priv->dma_pages[cur].used += rest; - n -= rest; - cur++; - } else { - dev_priv->dma_flush(dev_priv); - nr_pages = - (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE; - for (i = cur; i < dev_priv->nr_dma_pages; ++i) { - dev_priv->dma_pages[i].age = dev_priv->last_dma_age; - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle; - dev_priv->first_dma_page = cur = 0; - } - for (i = cur; nr_pages > 0; ++i, --nr_pages) { -#if SAVAGE_DMA_DEBUG - if (dev_priv->dma_pages[i].used) { - DRM_ERROR("unflushed page %u: used=%u\n", - i, dev_priv->dma_pages[i].used); - } -#endif - if (n > SAVAGE_DMA_PAGE_SIZE) - dev_priv->dma_pages[i].used = SAVAGE_DMA_PAGE_SIZE; - else - dev_priv->dma_pages[i].used = n; - n -= SAVAGE_DMA_PAGE_SIZE; - } - dev_priv->current_dma_page = --i; - - DRM_DEBUG("cur=%u, cur->used=%u, n=%u\n", - i, dev_priv->dma_pages[i].used, n); - - savage_dma_wait(dev_priv, dev_priv->current_dma_page); - - return dma_ptr; -} - -static void savage_dma_flush(drm_savage_private_t * dev_priv) -{ - unsigned int first = dev_priv->first_dma_page; - unsigned int cur = dev_priv->current_dma_page; - uint16_t event; - unsigned int wrap, pad, align, len, i; - unsigned long phys_addr; - BCI_LOCALS; - - if (first == cur && - dev_priv->dma_pages[cur].used == dev_priv->dma_pages[cur].flushed) - return; - - /* pad length to multiples of 2 entries - * align start of next DMA block to multiles of 8 entries */ - pad = -dev_priv->dma_pages[cur].used & 1; - align = -(dev_priv->dma_pages[cur].used + pad) & 7; - - DRM_DEBUG("first=%u, cur=%u, first->flushed=%u, cur->used=%u, " - "pad=%u, align=%u\n", - first, cur, dev_priv->dma_pages[first].flushed, - dev_priv->dma_pages[cur].used, pad, align); - - /* pad with noops */ - if (pad) { - uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + - cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used; - dev_priv->dma_pages[cur].used += pad; - while (pad != 0) { - *dma_ptr++ = BCI_CMD_WAIT; - pad--; - } - } - - DRM_MEMORYBARRIER(); - - /* do flush ... */ - phys_addr = dev_priv->cmd_dma->offset + - (first * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[first].flushed) * 4; - len = (cur - first) * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed; - - DRM_DEBUG("phys_addr=%lx, len=%u\n", - phys_addr | dev_priv->dma_type, len); - - BEGIN_BCI(3); - BCI_SET_REGISTERS(SAVAGE_DMABUFADDR, 1); - BCI_WRITE(phys_addr | dev_priv->dma_type); - BCI_DMA(len); - - /* fix alignment of the start of the next block */ - dev_priv->dma_pages[cur].used += align; - - /* age DMA pages */ - event = savage_bci_emit_event(dev_priv, 0); - wrap = dev_priv->event_wrap; - for (i = first; i < cur; ++i) { - SET_AGE(&dev_priv->dma_pages[i].age, event, wrap); - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - /* age the current page only when it's full */ - if (dev_priv->dma_pages[cur].used == SAVAGE_DMA_PAGE_SIZE) { - SET_AGE(&dev_priv->dma_pages[cur].age, event, wrap); - dev_priv->dma_pages[cur].used = 0; - dev_priv->dma_pages[cur].flushed = 0; - /* advance to next page */ - cur++; - if (cur == dev_priv->nr_dma_pages) - cur = 0; - dev_priv->first_dma_page = dev_priv->current_dma_page = cur; - } else { - dev_priv->first_dma_page = cur; - dev_priv->dma_pages[cur].flushed = dev_priv->dma_pages[i].used; - } - SET_AGE(&dev_priv->last_dma_age, event, wrap); - - DRM_DEBUG("first=cur=%u, cur->used=%u, cur->flushed=%u\n", cur, - dev_priv->dma_pages[cur].used, - dev_priv->dma_pages[cur].flushed); -} - -static void savage_fake_dma_flush(drm_savage_private_t * dev_priv) -{ - unsigned int i, j; - BCI_LOCALS; - - if (dev_priv->first_dma_page == dev_priv->current_dma_page && - dev_priv->dma_pages[dev_priv->current_dma_page].used == 0) - return; - - DRM_DEBUG("first=%u, cur=%u, cur->used=%u\n", - dev_priv->first_dma_page, dev_priv->current_dma_page, - dev_priv->dma_pages[dev_priv->current_dma_page].used); - - for (i = dev_priv->first_dma_page; - i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used; - ++i) { - uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + - i * SAVAGE_DMA_PAGE_SIZE; -#if SAVAGE_DMA_DEBUG - /* Sanity check: all pages except the last one must be full. */ - if (i < dev_priv->current_dma_page && - dev_priv->dma_pages[i].used != SAVAGE_DMA_PAGE_SIZE) { - DRM_ERROR("partial DMA page %u: used=%u", - i, dev_priv->dma_pages[i].used); - } -#endif - BEGIN_BCI(dev_priv->dma_pages[i].used); - for (j = 0; j < dev_priv->dma_pages[i].used; ++j) { - BCI_WRITE(dma_ptr[j]); - } - dev_priv->dma_pages[i].used = 0; - } - - /* reset to first page */ - dev_priv->first_dma_page = dev_priv->current_dma_page = 0; -} - -int savage_driver_load(struct drm_device *dev, unsigned long chipset) -{ - drm_savage_private_t *dev_priv; - - dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - - memset(dev_priv, 0, sizeof(drm_savage_private_t)); - dev->dev_private = (void *)dev_priv; - - dev_priv->chipset = (enum savage_family)chipset; - - return 0; -} - - -/* - * Initalize mappings. On Savage4 and SavageIX the alignment - * and size of the aperture is not suitable for automatic MTRR setup - * in drm_addmap. Therefore we add them manually before the maps are - * initialized, and tear them down on last close. - */ -int savage_driver_firstopen(struct drm_device *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - unsigned long mmio_base, fb_base, fb_size, aperture_base; - /* fb_rsrc and aper_rsrc aren't really used currently, but still exist - * in case we decide we need information on the BAR for BSD in the - * future. - */ - unsigned int fb_rsrc, aper_rsrc; - int ret = 0; - - dev_priv->mtrr[0].handle = -1; - dev_priv->mtrr[1].handle = -1; - dev_priv->mtrr[2].handle = -1; - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - fb_rsrc = 0; - fb_base = drm_get_resource_start(dev, 0); - fb_size = SAVAGE_FB_SIZE_S3; - mmio_base = fb_base + SAVAGE_FB_SIZE_S3; - aper_rsrc = 0; - aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; - /* this should always be true */ - if (drm_get_resource_len(dev, 0) == 0x08000000) { - /* Don't make MMIO write-cobining! We need 3 - * MTRRs. */ - dev_priv->mtrr[0].base = fb_base; - dev_priv->mtrr[0].size = 0x01000000; - dev_priv->mtrr[0].handle = - drm_mtrr_add(dev_priv->mtrr[0].base, - dev_priv->mtrr[0].size, DRM_MTRR_WC); - dev_priv->mtrr[1].base = fb_base + 0x02000000; - dev_priv->mtrr[1].size = 0x02000000; - dev_priv->mtrr[1].handle = - drm_mtrr_add(dev_priv->mtrr[1].base, - dev_priv->mtrr[1].size, DRM_MTRR_WC); - dev_priv->mtrr[2].base = fb_base + 0x04000000; - dev_priv->mtrr[2].size = 0x04000000; - dev_priv->mtrr[2].handle = - drm_mtrr_add(dev_priv->mtrr[2].base, - dev_priv->mtrr[2].size, DRM_MTRR_WC); - } else { - DRM_ERROR("strange pci_resource_len %08lx\n", - drm_get_resource_len(dev, 0)); - } - } else if (dev_priv->chipset != S3_SUPERSAVAGE && - dev_priv->chipset != S3_SAVAGE2000) { - mmio_base = drm_get_resource_start(dev, 0); - fb_rsrc = 1; - fb_base = drm_get_resource_start(dev, 1); - fb_size = SAVAGE_FB_SIZE_S4; - aper_rsrc = 1; - aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; - /* this should always be true */ - if (drm_get_resource_len(dev, 1) == 0x08000000) { - /* Can use one MTRR to cover both fb and - * aperture. */ - dev_priv->mtrr[0].base = fb_base; - dev_priv->mtrr[0].size = 0x08000000; - dev_priv->mtrr[0].handle = - drm_mtrr_add(dev_priv->mtrr[0].base, - dev_priv->mtrr[0].size, DRM_MTRR_WC); - } else { - DRM_ERROR("strange pci_resource_len %08lx\n", - drm_get_resource_len(dev, 1)); - } - } else { - mmio_base = drm_get_resource_start(dev, 0); - fb_rsrc = 1; - fb_base = drm_get_resource_start(dev, 1); - fb_size = drm_get_resource_len(dev, 1); - aper_rsrc = 2; - aperture_base = drm_get_resource_start(dev, 2); - /* Automatic MTRR setup will do the right thing. */ - } - - ret = drm_addmap(dev, mmio_base, SAVAGE_MMIO_SIZE, _DRM_REGISTERS, - _DRM_READ_ONLY, &dev_priv->mmio); - if (ret) - return ret; - - ret = drm_addmap(dev, fb_base, fb_size, _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING, &dev_priv->fb); - if (ret) - return ret; - - ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE, - _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING, - &dev_priv->aperture); - if (ret) - return ret; - - return ret; -} - -/* - * Delete MTRRs and free device-private data. - */ -void savage_driver_lastclose(struct drm_device *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - int i; - - for (i = 0; i < 3; ++i) - if (dev_priv->mtrr[i].handle >= 0) - drm_mtrr_del(dev_priv->mtrr[i].handle, - dev_priv->mtrr[i].base, - dev_priv->mtrr[i].size, DRM_MTRR_WC); -} - -int savage_driver_unload(struct drm_device *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - - drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); - - return 0; -} - -static int savage_do_init_bci(struct drm_device * dev, drm_savage_init_t * init) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - - if (init->fb_bpp != 16 && init->fb_bpp != 32) { - DRM_ERROR("invalid frame buffer bpp %d!\n", init->fb_bpp); - return -EINVAL; - } - if (init->depth_bpp != 16 && init->depth_bpp != 32) { - DRM_ERROR("invalid depth buffer bpp %d!\n", init->fb_bpp); - return -EINVAL; - } - if (init->dma_type != SAVAGE_DMA_AGP && - init->dma_type != SAVAGE_DMA_PCI) { - DRM_ERROR("invalid dma memory type %d!\n", init->dma_type); - return -EINVAL; - } - - dev_priv->cob_size = init->cob_size; - dev_priv->bci_threshold_lo = init->bci_threshold_lo; - dev_priv->bci_threshold_hi = init->bci_threshold_hi; - dev_priv->dma_type = init->dma_type; - - dev_priv->fb_bpp = init->fb_bpp; - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - dev_priv->depth_bpp = init->depth_bpp; - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - - dev_priv->texture_offset = init->texture_offset; - dev_priv->texture_size = init->texture_size; - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - if (init->status_offset != 0) { - dev_priv->status = drm_core_findmap(dev, init->status_offset); - if (!dev_priv->status) { - DRM_ERROR("could not find shadow status region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - } else { - dev_priv->status = NULL; - } - if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) { - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, - init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find DMA buffer region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - drm_core_ioremap(dev->agp_buffer_map, dev); - if (!dev->agp_buffer_map) { - DRM_ERROR("failed to ioremap DMA buffer region!\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - } - if (init->agp_textures_offset) { - dev_priv->agp_textures = - drm_core_findmap(dev, init->agp_textures_offset); - if (!dev_priv->agp_textures) { - DRM_ERROR("could not find agp texture region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - } else { - dev_priv->agp_textures = NULL; - } - - if (init->cmd_dma_offset) { - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - DRM_ERROR("command DMA not supported on " - "Savage3D/MX/IX.\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - if (dev->dma && dev->dma->buflist) { - DRM_ERROR("command and vertex DMA not supported " - "at the same time.\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - dev_priv->cmd_dma = drm_core_findmap(dev, init->cmd_dma_offset); - if (!dev_priv->cmd_dma) { - DRM_ERROR("could not find command DMA region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - if (dev_priv->dma_type == SAVAGE_DMA_AGP) { - if (dev_priv->cmd_dma->type != _DRM_AGP) { - DRM_ERROR("AGP command DMA region is not a " - "_DRM_AGP map!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - drm_core_ioremap(dev_priv->cmd_dma, dev); - if (!dev_priv->cmd_dma->handle) { - DRM_ERROR("failed to ioremap command " - "DMA region!\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - } else if (dev_priv->cmd_dma->type != _DRM_CONSISTENT) { - DRM_ERROR("PCI command DMA region is not a " - "_DRM_CONSISTENT map!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - } else { - dev_priv->cmd_dma = NULL; - } - - dev_priv->dma_flush = savage_dma_flush; - if (!dev_priv->cmd_dma) { - DRM_DEBUG("falling back to faked command DMA.\n"); - dev_priv->fake_dma.offset = 0; - dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE; - dev_priv->fake_dma.type = _DRM_SHM; - dev_priv->fake_dma.handle = drm_alloc(SAVAGE_FAKE_DMA_SIZE, - DRM_MEM_DRIVER); - if (!dev_priv->fake_dma.handle) { - DRM_ERROR("could not allocate faked DMA buffer!\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - dev_priv->cmd_dma = &dev_priv->fake_dma; - dev_priv->dma_flush = savage_fake_dma_flush; - } - - dev_priv->sarea_priv = - (drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle + - init->sarea_priv_offset); - - /* setup bitmap descriptors */ - { - unsigned int color_tile_format; - unsigned int depth_tile_format; - unsigned int front_stride, back_stride, depth_stride; - if (dev_priv->chipset <= S3_SAVAGE4) { - color_tile_format = dev_priv->fb_bpp == 16 ? - SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; - depth_tile_format = dev_priv->depth_bpp == 16 ? - SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; - } else { - color_tile_format = SAVAGE_BD_TILE_DEST; - depth_tile_format = SAVAGE_BD_TILE_DEST; - } - front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8); - back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8); - depth_stride = - dev_priv->depth_pitch / (dev_priv->depth_bpp / 8); - - dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | - (color_tile_format << SAVAGE_BD_TILE_SHIFT); - - dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | - (color_tile_format << SAVAGE_BD_TILE_SHIFT); - - dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) | - (depth_tile_format << SAVAGE_BD_TILE_SHIFT); - } - - /* setup status and bci ptr */ - dev_priv->event_counter = 0; - dev_priv->event_wrap = 0; - dev_priv->bci_ptr = (volatile uint32_t *) - ((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET); - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D; - } else { - dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S4; - } - if (dev_priv->status != NULL) { - dev_priv->status_ptr = - (volatile uint32_t *)dev_priv->status->handle; - dev_priv->wait_fifo = savage_bci_wait_fifo_shadow; - dev_priv->wait_evnt = savage_bci_wait_event_shadow; - dev_priv->status_ptr[1023] = dev_priv->event_counter; - } else { - dev_priv->status_ptr = NULL; - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - dev_priv->wait_fifo = savage_bci_wait_fifo_s3d; - } else { - dev_priv->wait_fifo = savage_bci_wait_fifo_s4; - } - dev_priv->wait_evnt = savage_bci_wait_event_reg; - } - - /* cliprect functions */ - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) - dev_priv->emit_clip_rect = savage_emit_clip_rect_s3d; - else - dev_priv->emit_clip_rect = savage_emit_clip_rect_s4; - - if (savage_freelist_init(dev) < 0) { - DRM_ERROR("could not initialize freelist\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - - if (savage_dma_init(dev_priv) < 0) { - DRM_ERROR("could not initialize command DMA\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - - return 0; -} - -static int savage_do_cleanup_bci(struct drm_device * dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - - if (dev_priv->cmd_dma == &dev_priv->fake_dma) { - if (dev_priv->fake_dma.handle) - drm_free(dev_priv->fake_dma.handle, - SAVAGE_FAKE_DMA_SIZE, DRM_MEM_DRIVER); - } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle && - dev_priv->cmd_dma->type == _DRM_AGP && - dev_priv->dma_type == SAVAGE_DMA_AGP) - drm_core_ioremapfree(dev_priv->cmd_dma, dev); - - if (dev_priv->dma_type == SAVAGE_DMA_AGP && - dev->agp_buffer_map && dev->agp_buffer_map->handle) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - /* make sure the next instance (which may be running - * in PCI mode) doesn't try to use an old - * agp_buffer_map. */ - dev->agp_buffer_map = NULL; - } - - if (dev_priv->dma_pages) - drm_free(dev_priv->dma_pages, - sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages, - DRM_MEM_DRIVER); - - return 0; -} - -static int savage_bci_init(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_init_t *init = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - switch (init->func) { - case SAVAGE_INIT_BCI: - return savage_do_init_bci(dev, init); - case SAVAGE_CLEANUP_BCI: - return savage_do_cleanup_bci(dev); - } - - return -EINVAL; -} - -static int savage_bci_event_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_event_emit_t *event = data; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - event->count = savage_bci_emit_event(dev_priv, event->flags); - event->count |= dev_priv->event_wrap << 16; - - return 0; -} - -static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_event_wait_t *event = data; - unsigned int event_e, hw_e; - unsigned int event_w, hw_w; - - DRM_DEBUG("\n"); - - UPDATE_EVENT_COUNTER(); - if (dev_priv->status_ptr) - hw_e = dev_priv->status_ptr[1] & 0xffff; - else - hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; - hw_w = dev_priv->event_wrap; - if (hw_e > dev_priv->event_counter) - hw_w--; /* hardware hasn't passed the last wrap yet */ - - event_e = event->count & 0xffff; - event_w = event->count >> 16; - - /* Don't need to wait if - * - event counter wrapped since the event was emitted or - * - the hardware has advanced up to or over the event to wait for. - */ - if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e)) - return 0; - else - return dev_priv->wait_evnt(dev_priv, event_e); -} - -/* - * DMA buffer management - */ - -static int savage_bci_get_buffers(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_dma *d) -{ - struct drm_buf *buf; - int i; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = savage_freelist_get(dev); - if (!buf) - return -EAGAIN; - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], - &buf->idx, sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], - &buf->total, sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_dma *d = data; - int ret = 0; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - d->granted_count = 0; - - if (d->request_count) { - ret = savage_bci_get_buffers(dev, file_priv, d); - } - - return ret; -} - -void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_savage_private_t *dev_priv = dev->dev_private; - int i; - - if (!dma) - return; - if (!dev_priv) - return; - if (!dma->buflist) - return; - - /*i830_flush_queue(dev); */ - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_savage_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->file_priv == file_priv && buf_priv && - buf_priv->next == NULL && buf_priv->prev == NULL) { - uint16_t event; - DRM_DEBUG("reclaimed from client\n"); - event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D); - SET_AGE(&buf_priv->age, event, dev_priv->event_wrap); - savage_freelist_put(dev, buf); - } - } - - drm_core_reclaim_buffers(dev, file_priv); -} - -struct drm_ioctl_desc savage_ioctls[] = { - DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), -}; - -int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); diff --git a/drivers/char/drm/savage_drm.h b/drivers/char/drm/savage_drm.h deleted file mode 100644 index 8a576ef..0000000 --- a/drivers/char/drm/savage_drm.h +++ /dev/null @@ -1,210 +0,0 @@ -/* savage_drm.h -- Public header for the savage driver - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __SAVAGE_DRM_H__ -#define __SAVAGE_DRM_H__ - -#ifndef __SAVAGE_SAREA_DEFINES__ -#define __SAVAGE_SAREA_DEFINES__ - -/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 - * regions, subject to a minimum region size of (1<<16) == 64k. - * - * Clients may subdivide regions internally, but when sharing between - * clients, the region size is the minimum granularity. - */ - -#define SAVAGE_CARD_HEAP 0 -#define SAVAGE_AGP_HEAP 1 -#define SAVAGE_NR_TEX_HEAPS 2 -#define SAVAGE_NR_TEX_REGIONS 16 -#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16 - -#endif /* __SAVAGE_SAREA_DEFINES__ */ - -typedef struct _drm_savage_sarea { - /* LRU lists for texture memory in agp space and on the card. - */ - struct drm_tex_region texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS + - 1]; - unsigned int texAge[SAVAGE_NR_TEX_HEAPS]; - - /* Mechanism to validate card state. - */ - int ctxOwner; -} drm_savage_sarea_t, *drm_savage_sarea_ptr; - -/* Savage-specific ioctls - */ -#define DRM_SAVAGE_BCI_INIT 0x00 -#define DRM_SAVAGE_BCI_CMDBUF 0x01 -#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02 -#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03 - -#define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t) -#define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t) -#define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t) -#define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t) - -#define SAVAGE_DMA_PCI 1 -#define SAVAGE_DMA_AGP 3 -typedef struct drm_savage_init { - enum { - SAVAGE_INIT_BCI = 1, - SAVAGE_CLEANUP_BCI = 2 - } func; - unsigned int sarea_priv_offset; - - /* some parameters */ - unsigned int cob_size; - unsigned int bci_threshold_lo, bci_threshold_hi; - unsigned int dma_type; - - /* frame buffer layout */ - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - /* local textures */ - unsigned int texture_offset; - unsigned int texture_size; - - /* physical locations of non-permanent maps */ - unsigned long status_offset; - unsigned long buffers_offset; - unsigned long agp_textures_offset; - unsigned long cmd_dma_offset; -} drm_savage_init_t; - -typedef union drm_savage_cmd_header drm_savage_cmd_header_t; -typedef struct drm_savage_cmdbuf { - /* command buffer in client's address space */ - drm_savage_cmd_header_t __user *cmd_addr; - unsigned int size; /* size of the command buffer in 64bit units */ - - unsigned int dma_idx; /* DMA buffer index to use */ - int discard; /* discard DMA buffer when done */ - /* vertex buffer in client's address space */ - unsigned int __user *vb_addr; - unsigned int vb_size; /* size of client vertex buffer in bytes */ - unsigned int vb_stride; /* stride of vertices in 32bit words */ - /* boxes in client's address space */ - struct drm_clip_rect __user *box_addr; - unsigned int nbox; /* number of clipping boxes */ -} drm_savage_cmdbuf_t; - -#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */ -#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */ -#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */ -typedef struct drm_savage_event { - unsigned int count; - unsigned int flags; -} drm_savage_event_emit_t, drm_savage_event_wait_t; - -/* Commands for the cmdbuf ioctl - */ -#define SAVAGE_CMD_STATE 0 /* a range of state registers */ -#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */ -#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */ -#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */ -#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */ -#define SAVAGE_CMD_CLEAR 5 /* clear buffers */ -#define SAVAGE_CMD_SWAP 6 /* swap buffers */ - -/* Primitive types -*/ -#define SAVAGE_PRIM_TRILIST 0 /* triangle list */ -#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */ -#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */ -#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat - * shading on s3d */ - -/* Skip flags (vertex format) - */ -#define SAVAGE_SKIP_Z 0x01 -#define SAVAGE_SKIP_W 0x02 -#define SAVAGE_SKIP_C0 0x04 -#define SAVAGE_SKIP_C1 0x08 -#define SAVAGE_SKIP_S0 0x10 -#define SAVAGE_SKIP_T0 0x20 -#define SAVAGE_SKIP_ST0 0x30 -#define SAVAGE_SKIP_S1 0x40 -#define SAVAGE_SKIP_T1 0x80 -#define SAVAGE_SKIP_ST1 0xc0 -#define SAVAGE_SKIP_ALL_S3D 0x3f -#define SAVAGE_SKIP_ALL_S4 0xff - -/* Buffer names for clear command - */ -#define SAVAGE_FRONT 0x1 -#define SAVAGE_BACK 0x2 -#define SAVAGE_DEPTH 0x4 - -/* 64-bit command header - */ -union drm_savage_cmd_header { - struct { - unsigned char cmd; /* command */ - unsigned char pad0; - unsigned short pad1; - unsigned short pad2; - unsigned short pad3; - } cmd; /* generic */ - struct { - unsigned char cmd; - unsigned char global; /* need idle engine? */ - unsigned short count; /* number of consecutive registers */ - unsigned short start; /* first register */ - unsigned short pad3; - } state; /* SAVAGE_CMD_STATE */ - struct { - unsigned char cmd; - unsigned char prim; /* primitive type */ - unsigned short skip; /* vertex format (skip flags) */ - unsigned short count; /* number of vertices */ - unsigned short start; /* first vertex in DMA/vertex buffer */ - } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */ - struct { - unsigned char cmd; - unsigned char prim; - unsigned short skip; - unsigned short count; /* number of indices that follow */ - unsigned short pad3; - } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */ - struct { - unsigned char cmd; - unsigned char pad0; - unsigned short pad1; - unsigned int flags; - } clear0; /* SAVAGE_CMD_CLEAR */ - struct { - unsigned int mask; - unsigned int value; - } clear1; /* SAVAGE_CMD_CLEAR data */ -}; - -#endif diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c deleted file mode 100644 index eee52aa..0000000 --- a/drivers/char/drm/savage_drv.c +++ /dev/null @@ -1,88 +0,0 @@ -/* savage_drv.c -- Savage driver for Linux - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - savage_PCI_IDS -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, - .dev_priv_size = sizeof(drm_savage_buf_priv_t), - .load = savage_driver_load, - .firstopen = savage_driver_firstopen, - .lastclose = savage_driver_lastclose, - .unload = savage_driver_unload, - .reclaim_buffers = savage_reclaim_buffers, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = savage_ioctls, - .dma_ioctl = savage_bci_buffers, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, - - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init savage_init(void) -{ - driver.num_ioctls = savage_max_ioctl; - return drm_init(&driver); -} - -static void __exit savage_exit(void) -{ - drm_exit(&driver); -} - -module_init(savage_init); -module_exit(savage_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h deleted file mode 100644 index df2aac6..0000000 --- a/drivers/char/drm/savage_drv.h +++ /dev/null @@ -1,575 +0,0 @@ -/* savage_drv.h -- Private header for the savage driver */ -/* - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __SAVAGE_DRV_H__ -#define __SAVAGE_DRV_H__ - -#define DRIVER_AUTHOR "Felix Kuehling" - -#define DRIVER_NAME "savage" -#define DRIVER_DESC "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]" -#define DRIVER_DATE "20050313" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 4 -#define DRIVER_PATCHLEVEL 1 -/* Interface history: - * - * 1.x The DRM driver from the VIA/S3 code drop, basically a dummy - * 2.0 The first real DRM - * 2.1 Scissors registers managed by the DRM, 3D operations clipped by - * cliprects of the cmdbuf ioctl - * 2.2 Implemented SAVAGE_CMD_DMA_IDX and SAVAGE_CMD_VB_IDX - * 2.3 Event counters used by BCI_EVENT_EMIT/WAIT ioctls are now 32 bits - * wide and thus very long lived (unlikely to ever wrap). The size - * in the struct was 32 bits before, but only 16 bits were used - * 2.4 Implemented command DMA. Now drm_savage_init_t.cmd_dma_offset is - * actually used - */ - -typedef struct drm_savage_age { - uint16_t event; - unsigned int wrap; -} drm_savage_age_t; - -typedef struct drm_savage_buf_priv { - struct drm_savage_buf_priv *next; - struct drm_savage_buf_priv *prev; - drm_savage_age_t age; - struct drm_buf *buf; -} drm_savage_buf_priv_t; - -typedef struct drm_savage_dma_page { - drm_savage_age_t age; - unsigned int used, flushed; -} drm_savage_dma_page_t; -#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */ -/* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command - * size of 16kbytes or 4k entries. Minimum requirement would be - * 10kbytes for 255 40-byte vertices in one drawing command. */ -#define SAVAGE_FAKE_DMA_SIZE (SAVAGE_DMA_PAGE_SIZE*4*4) - -/* interesting bits of hardware state that are saved in dev_priv */ -typedef union { - struct drm_savage_common_state { - uint32_t vbaddr; - } common; - struct { - unsigned char pad[sizeof(struct drm_savage_common_state)]; - uint32_t texctrl, texaddr; - uint32_t scstart, new_scstart; - uint32_t scend, new_scend; - } s3d; - struct { - unsigned char pad[sizeof(struct drm_savage_common_state)]; - uint32_t texdescr, texaddr0, texaddr1; - uint32_t drawctrl0, new_drawctrl0; - uint32_t drawctrl1, new_drawctrl1; - } s4; -} drm_savage_state_t; - -/* these chip tags should match the ones in the 2D driver in savage_regs.h. */ -enum savage_family { - S3_UNKNOWN = 0, - S3_SAVAGE3D, - S3_SAVAGE_MX, - S3_SAVAGE4, - S3_PROSAVAGE, - S3_TWISTER, - S3_PROSAVAGEDDR, - S3_SUPERSAVAGE, - S3_SAVAGE2000, - S3_LAST -}; - -extern struct drm_ioctl_desc savage_ioctls[]; -extern int savage_max_ioctl; - -#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) - -#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \ - || (chip==S3_PROSAVAGE) \ - || (chip==S3_TWISTER) \ - || (chip==S3_PROSAVAGEDDR)) - -#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) - -#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) - -#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \ - ||(chip==S3_PROSAVAGEDDR)) - -/* flags */ -#define SAVAGE_IS_AGP 1 - -typedef struct drm_savage_private { - drm_savage_sarea_t *sarea_priv; - - drm_savage_buf_priv_t head, tail; - - /* who am I? */ - enum savage_family chipset; - - unsigned int cob_size; - unsigned int bci_threshold_lo, bci_threshold_hi; - unsigned int dma_type; - - /* frame buffer layout */ - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - /* bitmap descriptors for swap and clear */ - unsigned int front_bd, back_bd, depth_bd; - - /* local textures */ - unsigned int texture_offset; - unsigned int texture_size; - - /* memory regions in physical memory */ - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *fb; - drm_local_map_t *aperture; - drm_local_map_t *status; - drm_local_map_t *agp_textures; - drm_local_map_t *cmd_dma; - drm_local_map_t fake_dma; - - struct { - int handle; - unsigned long base, size; - } mtrr[3]; - - /* BCI and status-related stuff */ - volatile uint32_t *status_ptr, *bci_ptr; - uint32_t status_used_mask; - uint16_t event_counter; - unsigned int event_wrap; - - /* Savage4 command DMA */ - drm_savage_dma_page_t *dma_pages; - unsigned int nr_dma_pages, first_dma_page, current_dma_page; - drm_savage_age_t last_dma_age; - - /* saved hw state for global/local check on S3D */ - uint32_t hw_draw_ctrl, hw_zbuf_ctrl; - /* and for scissors (global, so don't emit if not changed) */ - uint32_t hw_scissors_start, hw_scissors_end; - - drm_savage_state_t state; - - /* after emitting a wait cmd Savage3D needs 63 nops before next DMA */ - unsigned int waiting; - - /* config/hardware-dependent function pointers */ - int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n); - int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e); - /* Err, there is a macro wait_event in include/linux/wait.h. - * Avoid unwanted macro expansion. */ - void (*emit_clip_rect) (struct drm_savage_private * dev_priv, - const struct drm_clip_rect * pbox); - void (*dma_flush) (struct drm_savage_private * dev_priv); -} drm_savage_private_t; - -/* ioctls */ -extern int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); - -/* BCI functions */ -extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv, - unsigned int flags); -extern void savage_freelist_put(struct drm_device * dev, struct drm_buf * buf); -extern void savage_dma_reset(drm_savage_private_t * dev_priv); -extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); -extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, - unsigned int n); -extern int savage_driver_load(struct drm_device *dev, unsigned long chipset); -extern int savage_driver_firstopen(struct drm_device *dev); -extern void savage_driver_lastclose(struct drm_device *dev); -extern int savage_driver_unload(struct drm_device *dev); -extern void savage_reclaim_buffers(struct drm_device *dev, - struct drm_file *file_priv); - -/* state functions */ -extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox); -extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox); - -#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ -#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ -#define SAVAGE_MMIO_SIZE 0x00080000 /* 512kB */ -#define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */ -#define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */ - -#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region - * inside the MMIO region */ -#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip - * BCI FIFO */ - -/* - * MMIO registers - */ -#define SAVAGE_STATUS_WORD0 0x48C00 -#define SAVAGE_STATUS_WORD1 0x48C04 -#define SAVAGE_ALT_STATUS_WORD0 0x48C60 - -#define SAVAGE_FIFO_USED_MASK_S3D 0x0001ffff -#define SAVAGE_FIFO_USED_MASK_S4 0x001fffff - -/* Copied from savage_bci.h in the 2D driver with some renaming. */ - -/* Bitmap descriptors */ -#define SAVAGE_BD_STRIDE_SHIFT 0 -#define SAVAGE_BD_BPP_SHIFT 16 -#define SAVAGE_BD_TILE_SHIFT 24 -#define SAVAGE_BD_BW_DISABLE (1<<28) -/* common: */ -#define SAVAGE_BD_TILE_LINEAR 0 -/* savage4, MX, IX, 3D */ -#define SAVAGE_BD_TILE_16BPP 2 -#define SAVAGE_BD_TILE_32BPP 3 -/* twister, prosavage, DDR, supersavage, 2000 */ -#define SAVAGE_BD_TILE_DEST 1 -#define SAVAGE_BD_TILE_TEXTURE 2 -/* GBD - BCI enable */ -/* savage4, MX, IX, 3D */ -#define SAVAGE_GBD_BCI_ENABLE 8 -/* twister, prosavage, DDR, supersavage, 2000 */ -#define SAVAGE_GBD_BCI_ENABLE_TWISTER 0 - -#define SAVAGE_GBD_BIG_ENDIAN 4 -#define SAVAGE_GBD_LITTLE_ENDIAN 0 -#define SAVAGE_GBD_64 1 - -/* Global Bitmap Descriptor */ -#define SAVAGE_BCI_GLB_BD_LOW 0x8168 -#define SAVAGE_BCI_GLB_BD_HIGH 0x816C - -/* - * BCI registers - */ -/* Savage4/Twister/ProSavage 3D registers */ -#define SAVAGE_DRAWLOCALCTRL_S4 0x1e -#define SAVAGE_TEXPALADDR_S4 0x1f -#define SAVAGE_TEXCTRL0_S4 0x20 -#define SAVAGE_TEXCTRL1_S4 0x21 -#define SAVAGE_TEXADDR0_S4 0x22 -#define SAVAGE_TEXADDR1_S4 0x23 -#define SAVAGE_TEXBLEND0_S4 0x24 -#define SAVAGE_TEXBLEND1_S4 0x25 -#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */ -#define SAVAGE_TEXDESCR_S4 0x27 -#define SAVAGE_FOGTABLE_S4 0x28 -#define SAVAGE_FOGCTRL_S4 0x30 -#define SAVAGE_STENCILCTRL_S4 0x31 -#define SAVAGE_ZBUFCTRL_S4 0x32 -#define SAVAGE_ZBUFOFF_S4 0x33 -#define SAVAGE_DESTCTRL_S4 0x34 -#define SAVAGE_DRAWCTRL0_S4 0x35 -#define SAVAGE_DRAWCTRL1_S4 0x36 -#define SAVAGE_ZWATERMARK_S4 0x37 -#define SAVAGE_DESTTEXRWWATERMARK_S4 0x38 -#define SAVAGE_TEXBLENDCOLOR_S4 0x39 -/* Savage3D/MX/IX 3D registers */ -#define SAVAGE_TEXPALADDR_S3D 0x18 -#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */ -#define SAVAGE_TEXADDR_S3D 0x1A -#define SAVAGE_TEXDESCR_S3D 0x1B -#define SAVAGE_TEXCTRL_S3D 0x1C -#define SAVAGE_FOGTABLE_S3D 0x20 -#define SAVAGE_FOGCTRL_S3D 0x30 -#define SAVAGE_DRAWCTRL_S3D 0x31 -#define SAVAGE_ZBUFCTRL_S3D 0x32 -#define SAVAGE_ZBUFOFF_S3D 0x33 -#define SAVAGE_DESTCTRL_S3D 0x34 -#define SAVAGE_SCSTART_S3D 0x35 -#define SAVAGE_SCEND_S3D 0x36 -#define SAVAGE_ZWATERMARK_S3D 0x37 -#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38 -/* common stuff */ -#define SAVAGE_VERTBUFADDR 0x3e -#define SAVAGE_BITPLANEWTMASK 0xd7 -#define SAVAGE_DMABUFADDR 0x51 - -/* texture enable bits (needed for tex addr checking) */ -#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */ -#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */ -#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */ - -/* Global fields in Savage4/Twister/ProSavage 3D registers: - * - * All texture registers and DrawLocalCtrl are local. All other - * registers are global. */ - -/* Global fields in Savage3D/MX/IX 3D registers: - * - * All texture registers are local. DrawCtrl and ZBufCtrl are - * partially local. All other registers are global. - * - * DrawCtrl global fields: cullMode, alphaTestCmpFunc, alphaTestEn, alphaRefVal - * ZBufCtrl global fields: zCmpFunc, zBufEn - */ -#define SAVAGE_DRAWCTRL_S3D_GLOBAL 0x03f3c00c -#define SAVAGE_ZBUFCTRL_S3D_GLOBAL 0x00000027 - -/* Masks for scissor bits (drawCtrl[01] on s4, scissorStart/End on s3d) - */ -#define SAVAGE_SCISSOR_MASK_S4 0x00fff7ff -#define SAVAGE_SCISSOR_MASK_S3D 0x07ff07ff - -/* - * BCI commands - */ -#define BCI_CMD_NOP 0x40000000 -#define BCI_CMD_RECT 0x48000000 -#define BCI_CMD_RECT_XP 0x01000000 -#define BCI_CMD_RECT_YP 0x02000000 -#define BCI_CMD_SCANLINE 0x50000000 -#define BCI_CMD_LINE 0x5C000000 -#define BCI_CMD_LINE_LAST_PIXEL 0x58000000 -#define BCI_CMD_BYTE_TEXT 0x63000000 -#define BCI_CMD_NT_BYTE_TEXT 0x67000000 -#define BCI_CMD_BIT_TEXT 0x6C000000 -#define BCI_CMD_GET_ROP(cmd) (((cmd) >> 16) & 0xFF) -#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16)) -#define BCI_CMD_SEND_COLOR 0x00008000 - -#define BCI_CMD_CLIP_NONE 0x00000000 -#define BCI_CMD_CLIP_CURRENT 0x00002000 -#define BCI_CMD_CLIP_LR 0x00004000 -#define BCI_CMD_CLIP_NEW 0x00006000 - -#define BCI_CMD_DEST_GBD 0x00000000 -#define BCI_CMD_DEST_PBD 0x00000800 -#define BCI_CMD_DEST_PBD_NEW 0x00000C00 -#define BCI_CMD_DEST_SBD 0x00001000 -#define BCI_CMD_DEST_SBD_NEW 0x00001400 - -#define BCI_CMD_SRC_TRANSPARENT 0x00000200 -#define BCI_CMD_SRC_SOLID 0x00000000 -#define BCI_CMD_SRC_GBD 0x00000020 -#define BCI_CMD_SRC_COLOR 0x00000040 -#define BCI_CMD_SRC_MONO 0x00000060 -#define BCI_CMD_SRC_PBD_COLOR 0x00000080 -#define BCI_CMD_SRC_PBD_MONO 0x000000A0 -#define BCI_CMD_SRC_PBD_COLOR_NEW 0x000000C0 -#define BCI_CMD_SRC_PBD_MONO_NEW 0x000000E0 -#define BCI_CMD_SRC_SBD_COLOR 0x00000100 -#define BCI_CMD_SRC_SBD_MONO 0x00000120 -#define BCI_CMD_SRC_SBD_COLOR_NEW 0x00000140 -#define BCI_CMD_SRC_SBD_MONO_NEW 0x00000160 - -#define BCI_CMD_PAT_TRANSPARENT 0x00000010 -#define BCI_CMD_PAT_NONE 0x00000000 -#define BCI_CMD_PAT_COLOR 0x00000002 -#define BCI_CMD_PAT_MONO 0x00000003 -#define BCI_CMD_PAT_PBD_COLOR 0x00000004 -#define BCI_CMD_PAT_PBD_MONO 0x00000005 -#define BCI_CMD_PAT_PBD_COLOR_NEW 0x00000006 -#define BCI_CMD_PAT_PBD_MONO_NEW 0x00000007 -#define BCI_CMD_PAT_SBD_COLOR 0x00000008 -#define BCI_CMD_PAT_SBD_MONO 0x00000009 -#define BCI_CMD_PAT_SBD_COLOR_NEW 0x0000000A -#define BCI_CMD_PAT_SBD_MONO_NEW 0x0000000B - -#define BCI_BD_BW_DISABLE 0x10000000 -#define BCI_BD_TILE_MASK 0x03000000 -#define BCI_BD_TILE_NONE 0x00000000 -#define BCI_BD_TILE_16 0x02000000 -#define BCI_BD_TILE_32 0x03000000 -#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF) -#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16)) -#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF) -#define BCI_BD_SET_STRIDE(bd, st) ((bd) |= ((st) & 0xFFFF)) - -#define BCI_CMD_SET_REGISTER 0x96000000 - -#define BCI_CMD_WAIT 0xC0000000 -#define BCI_CMD_WAIT_3D 0x00010000 -#define BCI_CMD_WAIT_2D 0x00020000 - -#define BCI_CMD_UPDATE_EVENT_TAG 0x98000000 - -#define BCI_CMD_DRAW_PRIM 0x80000000 -#define BCI_CMD_DRAW_INDEXED_PRIM 0x88000000 -#define BCI_CMD_DRAW_CONT 0x01000000 -#define BCI_CMD_DRAW_TRILIST 0x00000000 -#define BCI_CMD_DRAW_TRISTRIP 0x02000000 -#define BCI_CMD_DRAW_TRIFAN 0x04000000 -#define BCI_CMD_DRAW_SKIPFLAGS 0x000000ff -#define BCI_CMD_DRAW_NO_Z 0x00000001 -#define BCI_CMD_DRAW_NO_W 0x00000002 -#define BCI_CMD_DRAW_NO_CD 0x00000004 -#define BCI_CMD_DRAW_NO_CS 0x00000008 -#define BCI_CMD_DRAW_NO_U0 0x00000010 -#define BCI_CMD_DRAW_NO_V0 0x00000020 -#define BCI_CMD_DRAW_NO_UV0 0x00000030 -#define BCI_CMD_DRAW_NO_U1 0x00000040 -#define BCI_CMD_DRAW_NO_V1 0x00000080 -#define BCI_CMD_DRAW_NO_UV1 0x000000c0 - -#define BCI_CMD_DMA 0xa8000000 - -#define BCI_W_H(w, h) ((((h) << 16) | (w)) & 0x0FFF0FFF) -#define BCI_X_Y(x, y) ((((y) << 16) | (x)) & 0x0FFF0FFF) -#define BCI_X_W(x, y) ((((w) << 16) | (x)) & 0x0FFF0FFF) -#define BCI_CLIP_LR(l, r) ((((r) << 16) | (l)) & 0x0FFF0FFF) -#define BCI_CLIP_TL(t, l) ((((t) << 16) | (l)) & 0x0FFF0FFF) -#define BCI_CLIP_BR(b, r) ((((b) << 16) | (r)) & 0x0FFF0FFF) - -#define BCI_LINE_X_Y(x, y) (((y) << 16) | ((x) & 0xFFFF)) -#define BCI_LINE_STEPS(diag, axi) (((axi) << 16) | ((diag) & 0xFFFF)) -#define BCI_LINE_MISC(maj, ym, xp, yp, err) \ - (((maj) & 0x1FFF) | \ - ((ym) ? 1<<13 : 0) | \ - ((xp) ? 1<<14 : 0) | \ - ((yp) ? 1<<15 : 0) | \ - ((err) << 16)) - -/* - * common commands - */ -#define BCI_SET_REGISTERS( first, n ) \ - BCI_WRITE(BCI_CMD_SET_REGISTER | \ - ((uint32_t)(n) & 0xff) << 16 | \ - ((uint32_t)(first) & 0xffff)) -#define DMA_SET_REGISTERS( first, n ) \ - DMA_WRITE(BCI_CMD_SET_REGISTER | \ - ((uint32_t)(n) & 0xff) << 16 | \ - ((uint32_t)(first) & 0xffff)) - -#define BCI_DRAW_PRIMITIVE(n, type, skip) \ - BCI_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \ - ((n) << 16)) -#define DMA_DRAW_PRIMITIVE(n, type, skip) \ - DMA_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \ - ((n) << 16)) - -#define BCI_DRAW_INDICES_S3D(n, type, i0) \ - BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \ - ((n) << 16) | (i0)) - -#define BCI_DRAW_INDICES_S4(n, type, skip) \ - BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \ - (skip) | ((n) << 16)) - -#define BCI_DMA(n) \ - BCI_WRITE(BCI_CMD_DMA | (((n) >> 1) - 1)) - -/* - * access to MMIO - */ -#define SAVAGE_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define SAVAGE_WRITE(reg) DRM_WRITE32( dev_priv->mmio, (reg) ) - -/* - * access to the burst command interface (BCI) - */ -#define SAVAGE_BCI_DEBUG 1 - -#define BCI_LOCALS volatile uint32_t *bci_ptr; - -#define BEGIN_BCI( n ) do { \ - dev_priv->wait_fifo(dev_priv, (n)); \ - bci_ptr = dev_priv->bci_ptr; \ -} while(0) - -#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) - -/* - * command DMA support - */ -#define SAVAGE_DMA_DEBUG 1 - -#define DMA_LOCALS uint32_t *dma_ptr; - -#define BEGIN_DMA( n ) do { \ - unsigned int cur = dev_priv->current_dma_page; \ - unsigned int rest = SAVAGE_DMA_PAGE_SIZE - \ - dev_priv->dma_pages[cur].used; \ - if ((n) > rest) { \ - dma_ptr = savage_dma_alloc(dev_priv, (n)); \ - } else { /* fast path for small allocations */ \ - dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + \ - cur * SAVAGE_DMA_PAGE_SIZE + \ - dev_priv->dma_pages[cur].used; \ - if (dev_priv->dma_pages[cur].used == 0) \ - savage_dma_wait(dev_priv, cur); \ - dev_priv->dma_pages[cur].used += (n); \ - } \ -} while(0) - -#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) - -#define DMA_COPY(src, n) do { \ - memcpy(dma_ptr, (src), (n)*4); \ - dma_ptr += n; \ -} while(0) - -#if SAVAGE_DMA_DEBUG -#define DMA_COMMIT() do { \ - unsigned int cur = dev_priv->current_dma_page; \ - uint32_t *expected = (uint32_t *)dev_priv->cmd_dma->handle + \ - cur * SAVAGE_DMA_PAGE_SIZE + \ - dev_priv->dma_pages[cur].used; \ - if (dma_ptr != expected) { \ - DRM_ERROR("DMA allocation and use don't match: " \ - "%p != %p\n", expected, dma_ptr); \ - savage_dma_reset(dev_priv); \ - } \ -} while(0) -#else -#define DMA_COMMIT() do {/* nothing */} while(0) -#endif - -#define DMA_FLUSH() dev_priv->dma_flush(dev_priv) - -/* Buffer aging via event tag - */ - -#define UPDATE_EVENT_COUNTER( ) do { \ - if (dev_priv->status_ptr) { \ - uint16_t count; \ - /* coordinate with Xserver */ \ - count = dev_priv->status_ptr[1023]; \ - if (count < dev_priv->event_counter) \ - dev_priv->event_wrap++; \ - dev_priv->event_counter = count; \ - } \ -} while(0) - -#define SET_AGE( age, e, w ) do { \ - (age)->event = e; \ - (age)->wrap = w; \ -} while(0) - -#define TEST_AGE( age, e, w ) \ - ( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) ) - -#endif /* __SAVAGE_DRV_H__ */ diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c deleted file mode 100644 index 5f6238f..0000000 --- a/drivers/char/drm/savage_state.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* savage_state.c -- State and drawing support for Savage - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" - -void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox) -{ - uint32_t scstart = dev_priv->state.s3d.new_scstart; - uint32_t scend = dev_priv->state.s3d.new_scend; - scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) | - ((uint32_t) pbox->x1 & 0x000007ff) | - (((uint32_t) pbox->y1 << 16) & 0x07ff0000); - scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) | - (((uint32_t) pbox->x2 - 1) & 0x000007ff) | - ((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000); - if (scstart != dev_priv->state.s3d.scstart || - scend != dev_priv->state.s3d.scend) { - DMA_LOCALS; - BEGIN_DMA(4); - DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); - DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2); - DMA_WRITE(scstart); - DMA_WRITE(scend); - dev_priv->state.s3d.scstart = scstart; - dev_priv->state.s3d.scend = scend; - dev_priv->waiting = 1; - DMA_COMMIT(); - } -} - -void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox) -{ - uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; - uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; - drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) | - ((uint32_t) pbox->x1 & 0x000007ff) | - (((uint32_t) pbox->y1 << 12) & 0x00fff000); - drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) | - (((uint32_t) pbox->x2 - 1) & 0x000007ff) | - ((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000); - if (drawctrl0 != dev_priv->state.s4.drawctrl0 || - drawctrl1 != dev_priv->state.s4.drawctrl1) { - DMA_LOCALS; - BEGIN_DMA(4); - DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); - DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2); - DMA_WRITE(drawctrl0); - DMA_WRITE(drawctrl1); - dev_priv->state.s4.drawctrl0 = drawctrl0; - dev_priv->state.s4.drawctrl1 = drawctrl1; - dev_priv->waiting = 1; - DMA_COMMIT(); - } -} - -static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit, - uint32_t addr) -{ - if ((addr & 6) != 2) { /* reserved bits */ - DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr); - return -EINVAL; - } - if (!(addr & 1)) { /* local */ - addr &= ~7; - if (addr < dev_priv->texture_offset || - addr >= dev_priv->texture_offset + dev_priv->texture_size) { - DRM_ERROR - ("bad texAddr%d %08x (local addr out of range)\n", - unit, addr); - return -EINVAL; - } - } else { /* AGP */ - if (!dev_priv->agp_textures) { - DRM_ERROR("bad texAddr%d %08x (AGP not available)\n", - unit, addr); - return -EINVAL; - } - addr &= ~7; - if (addr < dev_priv->agp_textures->offset || - addr >= (dev_priv->agp_textures->offset + - dev_priv->agp_textures->size)) { - DRM_ERROR - ("bad texAddr%d %08x (AGP addr out of range)\n", - unit, addr); - return -EINVAL; - } - } - return 0; -} - -#define SAVE_STATE(reg,where) \ - if(start <= reg && start+count > reg) \ - dev_priv->state.where = regs[reg - start] -#define SAVE_STATE_MASK(reg,where,mask) do { \ - if(start <= reg && start+count > reg) { \ - uint32_t tmp; \ - tmp = regs[reg - start]; \ - dev_priv->state.where = (tmp & (mask)) | \ - (dev_priv->state.where & ~(mask)); \ - } \ -} while (0) - -static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, - unsigned int start, unsigned int count, - const uint32_t *regs) -{ - if (start < SAVAGE_TEXPALADDR_S3D || - start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { - DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", - start, start + count - 1); - return -EINVAL; - } - - SAVE_STATE_MASK(SAVAGE_SCSTART_S3D, s3d.new_scstart, - ~SAVAGE_SCISSOR_MASK_S3D); - SAVE_STATE_MASK(SAVAGE_SCEND_S3D, s3d.new_scend, - ~SAVAGE_SCISSOR_MASK_S3D); - - /* if any texture regs were changed ... */ - if (start <= SAVAGE_TEXCTRL_S3D && - start + count > SAVAGE_TEXPALADDR_S3D) { - /* ... check texture state */ - SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl); - SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); - if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) - return savage_verify_texaddr(dev_priv, 0, - dev_priv->state.s3d.texaddr); - } - - return 0; -} - -static int savage_verify_state_s4(drm_savage_private_t * dev_priv, - unsigned int start, unsigned int count, - const uint32_t *regs) -{ - int ret = 0; - - if (start < SAVAGE_DRAWLOCALCTRL_S4 || - start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) { - DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", - start, start + count - 1); - return -EINVAL; - } - - SAVE_STATE_MASK(SAVAGE_DRAWCTRL0_S4, s4.new_drawctrl0, - ~SAVAGE_SCISSOR_MASK_S4); - SAVE_STATE_MASK(SAVAGE_DRAWCTRL1_S4, s4.new_drawctrl1, - ~SAVAGE_SCISSOR_MASK_S4); - - /* if any texture regs were changed ... */ - if (start <= SAVAGE_TEXDESCR_S4 && - start + count > SAVAGE_TEXPALADDR_S4) { - /* ... check texture state */ - SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); - SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); - SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); - if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) - ret |= savage_verify_texaddr(dev_priv, 0, - dev_priv->state.s4.texaddr0); - if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) - ret |= savage_verify_texaddr(dev_priv, 1, - dev_priv->state.s4.texaddr1); - } - - return ret; -} - -#undef SAVE_STATE -#undef SAVE_STATE_MASK - -static int savage_dispatch_state(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint32_t *regs) -{ - unsigned int count = cmd_header->state.count; - unsigned int start = cmd_header->state.start; - unsigned int count2 = 0; - unsigned int bci_size; - int ret; - DMA_LOCALS; - - if (!count) - return 0; - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - ret = savage_verify_state_s3d(dev_priv, start, count, regs); - if (ret != 0) - return ret; - /* scissor regs are emitted in savage_dispatch_draw */ - if (start < SAVAGE_SCSTART_S3D) { - if (start + count > SAVAGE_SCEND_S3D + 1) - count2 = count - (SAVAGE_SCEND_S3D + 1 - start); - if (start + count > SAVAGE_SCSTART_S3D) - count = SAVAGE_SCSTART_S3D - start; - } else if (start <= SAVAGE_SCEND_S3D) { - if (start + count > SAVAGE_SCEND_S3D + 1) { - count -= SAVAGE_SCEND_S3D + 1 - start; - start = SAVAGE_SCEND_S3D + 1; - } else - return 0; - } - } else { - ret = savage_verify_state_s4(dev_priv, start, count, regs); - if (ret != 0) - return ret; - /* scissor regs are emitted in savage_dispatch_draw */ - if (start < SAVAGE_DRAWCTRL0_S4) { - if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) - count2 = count - - (SAVAGE_DRAWCTRL1_S4 + 1 - start); - if (start + count > SAVAGE_DRAWCTRL0_S4) - count = SAVAGE_DRAWCTRL0_S4 - start; - } else if (start <= SAVAGE_DRAWCTRL1_S4) { - if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) { - count -= SAVAGE_DRAWCTRL1_S4 + 1 - start; - start = SAVAGE_DRAWCTRL1_S4 + 1; - } else - return 0; - } - } - - bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255; - - if (cmd_header->state.global) { - BEGIN_DMA(bci_size + 1); - DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); - dev_priv->waiting = 1; - } else { - BEGIN_DMA(bci_size); - } - - do { - while (count > 0) { - unsigned int n = count < 255 ? count : 255; - DMA_SET_REGISTERS(start, n); - DMA_COPY(regs, n); - count -= n; - start += n; - regs += n; - } - start += 2; - regs += 2; - count = count2; - count2 = 0; - } while (count); - - DMA_COMMIT(); - - return 0; -} - -static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const struct drm_buf * dmabuf) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->prim.prim; - unsigned int skip = cmd_header->prim.skip; - unsigned int n = cmd_header->prim.count; - unsigned int start = cmd_header->prim.start; - unsigned int i; - BCI_LOCALS; - - if (!dmabuf) { - DRM_ERROR("called without dma buffers!\n"); - return -EINVAL; - } - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of vertices %u in TRILIST\n", - n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of vertices %u in TRIFAN/STRIP\n", - n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip != 0) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - } else { - unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - - (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - - (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); - if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - if (reorder) { - DRM_ERROR("TRILIST_201 used on Savage4 hardware\n"); - return -EINVAL; - } - } - - if (start + n > dmabuf->total / 32) { - DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", - start, start + n - 1, dmabuf->total / 32); - return -EINVAL; - } - - /* Vertex DMA doesn't work with command DMA at the same time, - * so we use BCI_... to submit commands here. Flush buffered - * faked DMA first. */ - DMA_FLUSH(); - - if (dmabuf->bus_address != dev_priv->state.common.vbaddr) { - BEGIN_BCI(2); - BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1); - BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type); - dev_priv->state.common.vbaddr = dmabuf->bus_address; - } - if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) { - /* Workaround for what looks like a hardware bug. If a - * WAIT_3D_IDLE was emitted some time before the - * indexed drawing command then the engine will lock - * up. There are two known workarounds: - * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */ - BEGIN_BCI(63); - for (i = 0; i < 63; ++i) - BCI_WRITE(BCI_CMD_WAIT); - dev_priv->waiting = 0; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 indices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - if (reorder) { - /* Need to reorder indices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { -1, -1, -1 }; - reorder[start % 3] = 2; - - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, start + 2); - - for (i = start + 1; i + 1 < start + count; i += 2) - BCI_WRITE((i + reorder[i % 3]) | - ((i + 1 + - reorder[(i + 1) % 3]) << 16)); - if (i < start + count) - BCI_WRITE(i + reorder[i % 3]); - } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, start); - - for (i = start + 1; i + 1 < start + count; i += 2) - BCI_WRITE(i | ((i + 1) << 16)); - if (i < start + count) - BCI_WRITE(i); - } else { - BEGIN_BCI((count + 2 + 1) / 2); - BCI_DRAW_INDICES_S4(count, prim, skip); - - for (i = start; i + 1 < start + count; i += 2) - BCI_WRITE(i | ((i + 1) << 16)); - if (i < start + count) - BCI_WRITE(i); - } - - start += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint32_t *vtxbuf, unsigned int vb_size, - unsigned int vb_stride) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->prim.prim; - unsigned int skip = cmd_header->prim.skip; - unsigned int n = cmd_header->prim.count; - unsigned int start = cmd_header->prim.start; - unsigned int vtx_size; - unsigned int i; - DMA_LOCALS; - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of vertices %u in TRILIST\n", - n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of vertices %u in TRIFAN/STRIP\n", - n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip > SAVAGE_SKIP_ALL_S3D) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 8; /* full vertex */ - } else { - if (skip > SAVAGE_SKIP_ALL_S4) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 10; /* full vertex */ - } - - vtx_size -= (skip & 1) + (skip >> 1 & 1) + - (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + - (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); - - if (vtx_size > vb_stride) { - DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", - vtx_size, vb_stride); - return -EINVAL; - } - - if (start + n > vb_size / (vb_stride * 4)) { - DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", - start, start + n - 1, vb_size / (vb_stride * 4)); - return -EINVAL; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 vertices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - if (reorder) { - /* Need to reorder vertices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { -1, -1, -1 }; - reorder[start % 3] = 2; - - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - for (i = start; i < start + count; ++i) { - unsigned int j = i + reorder[i % 3]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); - } - - DMA_COMMIT(); - } else { - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - if (vb_stride == vtx_size) { - DMA_COPY(&vtxbuf[vb_stride * start], - vtx_size * count); - } else { - for (i = start; i < start + count; ++i) { - DMA_COPY(&vtxbuf [vb_stride * i], - vtx_size); - } - } - - DMA_COMMIT(); - } - - start += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint16_t *idx, - const struct drm_buf * dmabuf) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->idx.prim; - unsigned int skip = cmd_header->idx.skip; - unsigned int n = cmd_header->idx.count; - unsigned int i; - BCI_LOCALS; - - if (!dmabuf) { - DRM_ERROR("called without dma buffers!\n"); - return -EINVAL; - } - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of indices %u in TRILIST\n", n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of indices %u in TRIFAN/STRIP\n", n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip != 0) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - } else { - unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - - (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - - (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); - if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - if (reorder) { - DRM_ERROR("TRILIST_201 used on Savage4 hardware\n"); - return -EINVAL; - } - } - - /* Vertex DMA doesn't work with command DMA at the same time, - * so we use BCI_... to submit commands here. Flush buffered - * faked DMA first. */ - DMA_FLUSH(); - - if (dmabuf->bus_address != dev_priv->state.common.vbaddr) { - BEGIN_BCI(2); - BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1); - BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type); - dev_priv->state.common.vbaddr = dmabuf->bus_address; - } - if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) { - /* Workaround for what looks like a hardware bug. If a - * WAIT_3D_IDLE was emitted some time before the - * indexed drawing command then the engine will lock - * up. There are two known workarounds: - * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */ - BEGIN_BCI(63); - for (i = 0; i < 63; ++i) - BCI_WRITE(BCI_CMD_WAIT); - dev_priv->waiting = 0; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 indices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - - /* check indices */ - for (i = 0; i < count; ++i) { - if (idx[i] > dmabuf->total / 32) { - DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", - i, idx[i], dmabuf->total / 32); - return -EINVAL; - } - } - - if (reorder) { - /* Need to reorder indices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { 2, -1, -1 }; - - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, idx[2]); - - for (i = 1; i + 1 < count; i += 2) - BCI_WRITE(idx[i + reorder[i % 3]] | - (idx[i + 1 + - reorder[(i + 1) % 3]] << 16)); - if (i < count) - BCI_WRITE(idx[i + reorder[i % 3]]); - } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, idx[0]); - - for (i = 1; i + 1 < count; i += 2) - BCI_WRITE(idx[i] | (idx[i + 1] << 16)); - if (i < count) - BCI_WRITE(idx[i]); - } else { - BEGIN_BCI((count + 2 + 1) / 2); - BCI_DRAW_INDICES_S4(count, prim, skip); - - for (i = 0; i + 1 < count; i += 2) - BCI_WRITE(idx[i] | (idx[i + 1] << 16)); - if (i < count) - BCI_WRITE(idx[i]); - } - - idx += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint16_t *idx, - const uint32_t *vtxbuf, - unsigned int vb_size, unsigned int vb_stride) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->idx.prim; - unsigned int skip = cmd_header->idx.skip; - unsigned int n = cmd_header->idx.count; - unsigned int vtx_size; - unsigned int i; - DMA_LOCALS; - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of indices %u in TRILIST\n", n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of indices %u in TRIFAN/STRIP\n", n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip > SAVAGE_SKIP_ALL_S3D) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 8; /* full vertex */ - } else { - if (skip > SAVAGE_SKIP_ALL_S4) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 10; /* full vertex */ - } - - vtx_size -= (skip & 1) + (skip >> 1 & 1) + - (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + - (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); - - if (vtx_size > vb_stride) { - DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", - vtx_size, vb_stride); - return -EINVAL; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 vertices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - - /* Check indices */ - for (i = 0; i < count; ++i) { - if (idx[i] > vb_size / (vb_stride * 4)) { - DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", - i, idx[i], vb_size / (vb_stride * 4)); - return -EINVAL; - } - } - - if (reorder) { - /* Need to reorder vertices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { 2, -1, -1 }; - - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - for (i = 0; i < count; ++i) { - unsigned int j = idx[i + reorder[i % 3]]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); - } - - DMA_COMMIT(); - } else { - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - for (i = 0; i < count; ++i) { - unsigned int j = idx[i]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); - } - - DMA_COMMIT(); - } - - idx += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_clear(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const drm_savage_cmd_header_t *data, - unsigned int nbox, - const struct drm_clip_rect *boxes) -{ - unsigned int flags = cmd_header->clear0.flags; - unsigned int clear_cmd; - unsigned int i, nbufs; - DMA_LOCALS; - - if (nbox == 0) - return 0; - - clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | - BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; - BCI_CMD_SET_ROP(clear_cmd, 0xCC); - - nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) + - ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0); - if (nbufs == 0) - return 0; - - if (data->clear1.mask != 0xffffffff) { - /* set mask */ - BEGIN_DMA(2); - DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); - DMA_WRITE(data->clear1.mask); - DMA_COMMIT(); - } - for (i = 0; i < nbox; ++i) { - unsigned int x, y, w, h; - unsigned int buf; - x = boxes[i].x1, y = boxes[i].y1; - w = boxes[i].x2 - boxes[i].x1; - h = boxes[i].y2 - boxes[i].y1; - BEGIN_DMA(nbufs * 6); - for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { - if (!(flags & buf)) - continue; - DMA_WRITE(clear_cmd); - switch (buf) { - case SAVAGE_FRONT: - DMA_WRITE(dev_priv->front_offset); - DMA_WRITE(dev_priv->front_bd); - break; - case SAVAGE_BACK: - DMA_WRITE(dev_priv->back_offset); - DMA_WRITE(dev_priv->back_bd); - break; - case SAVAGE_DEPTH: - DMA_WRITE(dev_priv->depth_offset); - DMA_WRITE(dev_priv->depth_bd); - break; - } - DMA_WRITE(data->clear1.value); - DMA_WRITE(BCI_X_Y(x, y)); - DMA_WRITE(BCI_W_H(w, h)); - } - DMA_COMMIT(); - } - if (data->clear1.mask != 0xffffffff) { - /* reset mask */ - BEGIN_DMA(2); - DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); - DMA_WRITE(0xffffffff); - DMA_COMMIT(); - } - - return 0; -} - -static int savage_dispatch_swap(drm_savage_private_t * dev_priv, - unsigned int nbox, const struct drm_clip_rect *boxes) -{ - unsigned int swap_cmd; - unsigned int i; - DMA_LOCALS; - - if (nbox == 0) - return 0; - - swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | - BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD; - BCI_CMD_SET_ROP(swap_cmd, 0xCC); - - for (i = 0; i < nbox; ++i) { - BEGIN_DMA(6); - DMA_WRITE(swap_cmd); - DMA_WRITE(dev_priv->back_offset); - DMA_WRITE(dev_priv->back_bd); - DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); - DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); - DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1, - boxes[i].y2 - boxes[i].y1)); - DMA_COMMIT(); - } - - return 0; -} - -static int savage_dispatch_draw(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t *start, - const drm_savage_cmd_header_t *end, - const struct drm_buf * dmabuf, - const unsigned int *vtxbuf, - unsigned int vb_size, unsigned int vb_stride, - unsigned int nbox, - const struct drm_clip_rect *boxes) -{ - unsigned int i, j; - int ret; - - for (i = 0; i < nbox; ++i) { - const drm_savage_cmd_header_t *cmdbuf; - dev_priv->emit_clip_rect(dev_priv, &boxes[i]); - - cmdbuf = start; - while (cmdbuf < end) { - drm_savage_cmd_header_t cmd_header; - cmd_header = *cmdbuf; - cmdbuf++; - switch (cmd_header.cmd.cmd) { - case SAVAGE_CMD_DMA_PRIM: - ret = savage_dispatch_dma_prim( - dev_priv, &cmd_header, dmabuf); - break; - case SAVAGE_CMD_VB_PRIM: - ret = savage_dispatch_vb_prim( - dev_priv, &cmd_header, - vtxbuf, vb_size, vb_stride); - break; - case SAVAGE_CMD_DMA_IDX: - j = (cmd_header.idx.count + 3) / 4; - /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_dma_idx(dev_priv, - &cmd_header, (const uint16_t *)cmdbuf, - dmabuf); - cmdbuf += j; - break; - case SAVAGE_CMD_VB_IDX: - j = (cmd_header.idx.count + 3) / 4; - /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_vb_idx(dev_priv, - &cmd_header, (const uint16_t *)cmdbuf, - (const uint32_t *)vtxbuf, vb_size, - vb_stride); - cmdbuf += j; - break; - default: - /* What's the best return code? EFAULT? */ - DRM_ERROR("IMPLEMENTATION ERROR: " - "non-drawing-command %d\n", - cmd_header.cmd.cmd); - return -EINVAL; - } - - if (ret != 0) - return ret; - } - } - - return 0; -} - -int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *dmabuf; - drm_savage_cmdbuf_t *cmdbuf = data; - drm_savage_cmd_header_t *kcmd_addr = NULL; - drm_savage_cmd_header_t *first_draw_cmd; - unsigned int *kvb_addr = NULL; - struct drm_clip_rect *kbox_addr = NULL; - unsigned int i, j; - int ret = 0; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (dma && dma->buflist) { - if (cmdbuf->dma_idx > dma->buf_count) { - DRM_ERROR - ("vertex buffer index %u out of range (0-%u)\n", - cmdbuf->dma_idx, dma->buf_count - 1); - return -EINVAL; - } - dmabuf = dma->buflist[cmdbuf->dma_idx]; - } else { - dmabuf = NULL; - } - - /* Copy the user buffers into kernel temporary areas. This hasn't been - * a performance loss compared to VERIFYAREA_READ/ - * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct - * for locking on FreeBSD. - */ - if (cmdbuf->size) { - kcmd_addr = drm_alloc(cmdbuf->size * 8, DRM_MEM_DRIVER); - if (kcmd_addr == NULL) - return -ENOMEM; - - if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr, - cmdbuf->size * 8)) - { - drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); - return -EFAULT; - } - cmdbuf->cmd_addr = kcmd_addr; - } - if (cmdbuf->vb_size) { - kvb_addr = drm_alloc(cmdbuf->vb_size, DRM_MEM_DRIVER); - if (kvb_addr == NULL) { - ret = -ENOMEM; - goto done; - } - - if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf->vb_addr, - cmdbuf->vb_size)) { - ret = -EFAULT; - goto done; - } - cmdbuf->vb_addr = kvb_addr; - } - if (cmdbuf->nbox) { - kbox_addr = drm_alloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), - DRM_MEM_DRIVER); - if (kbox_addr == NULL) { - ret = -ENOMEM; - goto done; - } - - if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf->box_addr, - cmdbuf->nbox * sizeof(struct drm_clip_rect))) { - ret = -EFAULT; - goto done; - } - cmdbuf->box_addr = kbox_addr; - } - - /* Make sure writes to DMA buffers are finished before sending - * DMA commands to the graphics hardware. */ - DRM_MEMORYBARRIER(); - - /* Coming from user space. Don't know if the Xserver has - * emitted wait commands. Assuming the worst. */ - dev_priv->waiting = 1; - - i = 0; - first_draw_cmd = NULL; - while (i < cmdbuf->size) { - drm_savage_cmd_header_t cmd_header; - cmd_header = *(drm_savage_cmd_header_t *)cmdbuf->cmd_addr; - cmdbuf->cmd_addr++; - i++; - - /* Group drawing commands with same state to minimize - * iterations over clip rects. */ - j = 0; - switch (cmd_header.cmd.cmd) { - case SAVAGE_CMD_DMA_IDX: - case SAVAGE_CMD_VB_IDX: - j = (cmd_header.idx.count + 3) / 4; - if (i + j > cmdbuf->size) { - DRM_ERROR("indexed drawing command extends " - "beyond end of command buffer\n"); - DMA_FLUSH(); - return -EINVAL; - } - /* fall through */ - case SAVAGE_CMD_DMA_PRIM: - case SAVAGE_CMD_VB_PRIM: - if (!first_draw_cmd) - first_draw_cmd = cmdbuf->cmd_addr - 1; - cmdbuf->cmd_addr += j; - i += j; - break; - default: - if (first_draw_cmd) { - ret = savage_dispatch_draw( - dev_priv, first_draw_cmd, - cmdbuf->cmd_addr - 1, - dmabuf, cmdbuf->vb_addr, cmdbuf->vb_size, - cmdbuf->vb_stride, - cmdbuf->nbox, cmdbuf->box_addr); - if (ret != 0) - return ret; - first_draw_cmd = NULL; - } - } - if (first_draw_cmd) - continue; - - switch (cmd_header.cmd.cmd) { - case SAVAGE_CMD_STATE: - j = (cmd_header.state.count + 1) / 2; - if (i + j > cmdbuf->size) { - DRM_ERROR("command SAVAGE_CMD_STATE extends " - "beyond end of command buffer\n"); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - ret = savage_dispatch_state(dev_priv, &cmd_header, - (const uint32_t *)cmdbuf->cmd_addr); - cmdbuf->cmd_addr += j; - i += j; - break; - case SAVAGE_CMD_CLEAR: - if (i + 1 > cmdbuf->size) { - DRM_ERROR("command SAVAGE_CMD_CLEAR extends " - "beyond end of command buffer\n"); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - ret = savage_dispatch_clear(dev_priv, &cmd_header, - cmdbuf->cmd_addr, - cmdbuf->nbox, - cmdbuf->box_addr); - cmdbuf->cmd_addr++; - i++; - break; - case SAVAGE_CMD_SWAP: - ret = savage_dispatch_swap(dev_priv, cmdbuf->nbox, - cmdbuf->box_addr); - break; - default: - DRM_ERROR("invalid command 0x%x\n", - cmd_header.cmd.cmd); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - - if (ret != 0) { - DMA_FLUSH(); - goto done; - } - } - - if (first_draw_cmd) { - ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, cmdbuf->cmd_addr, dmabuf, - cmdbuf->vb_addr, cmdbuf->vb_size, cmdbuf->vb_stride, - cmdbuf->nbox, cmdbuf->box_addr); - if (ret != 0) { - DMA_FLUSH(); - goto done; - } - } - - DMA_FLUSH(); - - if (dmabuf && cmdbuf->discard) { - drm_savage_buf_priv_t *buf_priv = dmabuf->dev_private; - uint16_t event; - event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D); - SET_AGE(&buf_priv->age, event, dev_priv->event_wrap); - savage_freelist_put(dev, dmabuf); - } - -done: - /* If we didn't need to allocate them, these'll be NULL */ - drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); - drm_free(kvb_addr, cmdbuf->vb_size, DRM_MEM_DRIVER); - drm_free(kbox_addr, cmdbuf->nbox * sizeof(struct drm_clip_rect), - DRM_MEM_DRIVER); - - return ret; -} diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h deleted file mode 100644 index 30f7b38..0000000 --- a/drivers/char/drm/sis_drm.h +++ /dev/null @@ -1,67 +0,0 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ -/* - * Copyright 2005 Eric Anholt - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef __SIS_DRM_H__ -#define __SIS_DRM_H__ - -/* SiS specific ioctls */ -#define NOT_USED_0_3 -#define DRM_SIS_FB_ALLOC 0x04 -#define DRM_SIS_FB_FREE 0x05 -#define NOT_USED_6_12 -#define DRM_SIS_AGP_INIT 0x13 -#define DRM_SIS_AGP_ALLOC 0x14 -#define DRM_SIS_AGP_FREE 0x15 -#define DRM_SIS_FB_INIT 0x16 - -#define DRM_IOCTL_SIS_FB_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_FB_ALLOC, drm_sis_mem_t) -#define DRM_IOCTL_SIS_FB_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_FREE, drm_sis_mem_t) -#define DRM_IOCTL_SIS_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_INIT, drm_sis_agp_t) -#define DRM_IOCTL_SIS_AGP_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_ALLOC, drm_sis_mem_t) -#define DRM_IOCTL_SIS_AGP_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_AGP_FREE, drm_sis_mem_t) -#define DRM_IOCTL_SIS_FB_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_INIT, drm_sis_fb_t) -/* -#define DRM_IOCTL_SIS_FLIP DRM_IOW( 0x48, drm_sis_flip_t) -#define DRM_IOCTL_SIS_FLIP_INIT DRM_IO( 0x49) -#define DRM_IOCTL_SIS_FLIP_FINAL DRM_IO( 0x50) -*/ - -typedef struct { - int context; - unsigned int offset; - unsigned int size; - unsigned long free; -} drm_sis_mem_t; - -typedef struct { - unsigned int offset, size; -} drm_sis_agp_t; - -typedef struct { - unsigned int offset, size; -} drm_sis_fb_t; - -#endif /* __SIS_DRM_H__ */ diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c deleted file mode 100644 index 7dacc64..0000000 --- a/drivers/char/drm/sis_drv.c +++ /dev/null @@ -1,117 +0,0 @@ -/* sis.c -- sis driver -*- linux-c -*- - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "sis_drm.h" -#include "sis_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - sisdrv_PCI_IDS -}; - -static int sis_driver_load(struct drm_device *dev, unsigned long chipset) -{ - drm_sis_private_t *dev_priv; - int ret; - - dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - - dev->dev_private = (void *)dev_priv; - dev_priv->chipset = chipset; - ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); - if (ret) { - drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER); - } - - return ret; -} - -static int sis_driver_unload(struct drm_device *dev) -{ - drm_sis_private_t *dev_priv = dev->dev_private; - - drm_sman_takedown(&dev_priv->sman); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); - - return 0; -} - -static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, - .load = sis_driver_load, - .unload = sis_driver_unload, - .context_dtor = NULL, - .dma_quiescent = sis_idle, - .reclaim_buffers = NULL, - .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, - .lastclose = sis_lastclose, - .get_map_ofs = drm_core_get_map_ofs, - .get_reg_ofs = drm_core_get_reg_ofs, - .ioctls = sis_ioctls, - .fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - }, - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - }, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static int __init sis_init(void) -{ - driver.num_ioctls = sis_max_ioctl; - return drm_init(&driver); -} - -static void __exit sis_exit(void) -{ - drm_exit(&driver); -} - -module_init(sis_init); -module_exit(sis_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h deleted file mode 100644 index ef940ba..0000000 --- a/drivers/char/drm/sis_drv.h +++ /dev/null @@ -1,73 +0,0 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef _SIS_DRV_H_ -#define _SIS_DRV_H_ - -/* General customization: - */ - -#define DRIVER_AUTHOR "SIS, Tungsten Graphics" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540 and XGI V3XE/V5/V8" -#define DRIVER_DATE "20070626" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 -#define DRIVER_PATCHLEVEL 0 - -enum sis_family { - SIS_OTHER = 0, - SIS_CHIP_315 = 1, -}; - -#include "drm_sman.h" - - -#define SIS_BASE (dev_priv->mmio) -#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg); -#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val); - -typedef struct drm_sis_private { - drm_local_map_t *mmio; - unsigned int idle_fault; - struct drm_sman sman; - unsigned int chipset; - int vram_initialized; - int agp_initialized; - unsigned long vram_offset; - unsigned long agp_offset; -} drm_sis_private_t; - -extern int sis_idle(struct drm_device *dev); -extern void sis_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); -extern void sis_lastclose(struct drm_device *dev); - -extern struct drm_ioctl_desc sis_ioctls[]; -extern int sis_max_ioctl; - -#endif diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c deleted file mode 100644 index b387877..0000000 --- a/drivers/char/drm/sis_mm.c +++ /dev/null @@ -1,333 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "sis_drm.h" -#include "sis_drv.h" - -#include where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - phy-handle : The phandle for the PHY connected to this ethernet - controller. - - fixed-link : where a is emulated phy id - choose any, - but unique to the all specified fixed-links, b is duplex - 0 half, - 1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no - pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause. - - Recommended properties: - - - phy-connection-type : a string naming the controller/PHY interface type, - i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii", - "tbi", or "rtbi". This property is only really needed if the connection - is of type "rgmii-id", as all other connection types are detected by - hardware. - - - Example: - - ethernet@24000 { - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - mac-address = [ 00 E0 0C 00 73 00 ]; - interrupts = ; - interrupt-parent = <40000>; - phy-handle = <2452000> - }; - - - - c) PHY nodes + a) PHY nodes Required properties: @@ -1351,7 +1263,7 @@ platforms are moved over to use the flattened-device-tree model. }; - d) Interrupt controllers + b) Interrupt controllers Some SOC devices contain interrupt controllers that are different from the standard Open PIC specification. The SOC device nodes for @@ -1371,508 +1283,7 @@ platforms are moved over to use the flattened-device-tree model. device_type = "open-pic"; }; - - e) I2C - - Required properties : - - - device_type : Should be "i2c" - - reg : Offset and length of the register set for the device - - Recommended properties : - - - compatible : Should be "fsl-i2c" for parts compatible with - Freescale I2C specifications. - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - dfsrr : boolean; if defined, indicates that this I2C device has - a digital filter sampling rate register - - fsl5200-clocking : boolean; if defined, indicated that this device - uses the FSL 5200 clocking mechanism. - - Example : - - i2c@3000 { - interrupt-parent = <40000>; - interrupts = <1b 3>; - reg = <3000 18>; - device_type = "i2c"; - compatible = "fsl-i2c"; - dfsrr; - }; - - - f) Freescale SOC USB controllers - - The device node for a USB controller that is part of a Freescale - SOC is as described in the document "Open Firmware Recommended - Practice : Universal Serial Bus" with the following modifications - and additions : - - Required properties : - - compatible : Should be "fsl-usb2-mph" for multi port host USB - controllers, or "fsl-usb2-dr" for dual role USB controllers - - phy_type : For multi port host USB controllers, should be one of - "ulpi", or "serial". For dual role USB controllers, should be - one of "ulpi", "utmi", "utmi_wide", or "serial". - - reg : Offset and length of the register set for the device - - port0 : boolean; if defined, indicates port0 is connected for - fsl-usb2-mph compatible controllers. Either this property or - "port1" (or both) must be defined for "fsl-usb2-mph" compatible - controllers. - - port1 : boolean; if defined, indicates port1 is connected for - fsl-usb2-mph compatible controllers. Either this property or - "port0" (or both) must be defined for "fsl-usb2-mph" compatible - controllers. - - dr_mode : indicates the working mode for "fsl-usb2-dr" compatible - controllers. Can be "host", "peripheral", or "otg". Default to - "host" if not defined for backward compatibility. - - Recommended properties : - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - Example multi port host USB controller device node : - usb@22000 { - compatible = "fsl-usb2-mph"; - reg = <22000 1000>; - #address-cells = <1>; - #size-cells = <0>; - interrupt-parent = <700>; - interrupts = <27 1>; - phy_type = "ulpi"; - port0; - port1; - }; - - Example dual role USB controller device node : - usb@23000 { - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; - #size-cells = <0>; - interrupt-parent = <700>; - interrupts = <26 1>; - dr_mode = "otg"; - phy = "ulpi"; - }; - - - g) Freescale SOC SEC Security Engines - - Required properties: - - - device_type : Should be "crypto" - - model : Model of the device. Should be "SEC1" or "SEC2" - - compatible : Should be "talitos" - - reg : Offset and length of the register set for the device - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - num-channels : An integer representing the number of channels - available. - - channel-fifo-len : An integer representing the number of - descriptor pointers each channel fetch fifo can hold. - - exec-units-mask : The bitmask representing what execution units - (EUs) are available. It's a single 32-bit cell. EU information - should be encoded following the SEC's Descriptor Header Dword - EU_SEL0 field documentation, i.e. as follows: - - bit 0 = reserved - should be 0 - bit 1 = set if SEC has the ARC4 EU (AFEU) - bit 2 = set if SEC has the DES/3DES EU (DEU) - bit 3 = set if SEC has the message digest EU (MDEU) - bit 4 = set if SEC has the random number generator EU (RNG) - bit 5 = set if SEC has the public key EU (PKEU) - bit 6 = set if SEC has the AES EU (AESU) - bit 7 = set if SEC has the Kasumi EU (KEU) - - bits 8 through 31 are reserved for future SEC EUs. - - - descriptor-types-mask : The bitmask representing what descriptors - are available. It's a single 32-bit cell. Descriptor type - information should be encoded following the SEC's Descriptor - Header Dword DESC_TYPE field documentation, i.e. as follows: - - bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type - bit 1 = set if SEC supports the ipsec_esp descriptor type - bit 2 = set if SEC supports the common_nonsnoop desc. type - bit 3 = set if SEC supports the 802.11i AES ccmp desc. type - bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type - bit 5 = set if SEC supports the srtp descriptor type - bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type - bit 7 = set if SEC supports the pkeu_assemble descriptor type - bit 8 = set if SEC supports the aesu_key_expand_output desc.type - bit 9 = set if SEC supports the pkeu_ptmul descriptor type - bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type - bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type - - ..and so on and so forth. - - Example: - - /* MPC8548E */ - crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <30000 10000>; - interrupts = <1d 3>; - interrupt-parent = <40000>; - num-channels = <4>; - channel-fifo-len = <18>; - exec-units-mask = <000000fe>; - descriptor-types-mask = <012b0ebf>; - }; - - h) Board Control and Status (BCSR) - - Required properties: - - - device_type : Should be "board-control" - - reg : Offset and length of the register set for the device - - Example: - - bcsr@f8000000 { - device_type = "board-control"; - reg = ; - }; - - i) Freescale QUICC Engine module (QE) - This represents qe module that is installed on PowerQUICC II Pro. - - NOTE: This is an interim binding; it should be updated to fit - in with the CPM binding later in this document. - - Basically, it is a bus of devices, that could act more or less - as a complete entity (UCC, USB etc ). All of them should be siblings on - the "root" qe node, using the common properties from there. - The description below applies to the qe of MPC8360 and - more nodes and properties would be extended in the future. - - i) Root QE device - - Required properties: - - compatible : should be "fsl,qe"; - - model : precise model of the QE, Can be "QE", "CPM", or "CPM2" - - reg : offset and length of the device registers. - - bus-frequency : the clock frequency for QUICC Engine. - - Recommended properties - - brg-frequency : the internal clock source frequency for baud-rate - generators in Hz. - - Example: - qe@e0100000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - compatible = "fsl,qe"; - ranges = <0 e0100000 00100000>; - reg = ; - brg-frequency = <0>; - bus-frequency = <179A7B00>; - } - - - ii) SPI (Serial Peripheral Interface) - - Required properties: - - cell-index : SPI controller index. - - compatible : should be "fsl,spi". - - mode : the SPI operation mode, it can be "cpu" or "cpu-qe". - - reg : Offset and length of the register set for the device - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - Example: - spi@4c0 { - cell-index = <0>; - compatible = "fsl,spi"; - reg = <4c0 40>; - interrupts = <82 0>; - interrupt-parent = <700>; - mode = "cpu"; - }; - - - iii) USB (Universal Serial Bus Controller) - - Required properties: - - compatible : could be "qe_udc" or "fhci-hcd". - - mode : the could be "host" or "slave". - - reg : Offset and length of the register set for the device - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - Example(slave): - usb@6c0 { - compatible = "qe_udc"; - reg = <6c0 40>; - interrupts = <8b 0>; - interrupt-parent = <700>; - mode = "slave"; - }; - - - iv) UCC (Unified Communications Controllers) - - Required properties: - - device_type : should be "network", "hldc", "uart", "transparent" - "bisync", "atm", or "serial". - - compatible : could be "ucc_geth" or "fsl_atm" and so on. - - cell-index : the ucc number(1-8), corresponding to UCCx in UM. - - reg : Offset and length of the register set for the device - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - pio-handle : The phandle for the Parallel I/O port configuration. - - port-number : for UART drivers, the port number to use, between 0 and 3. - This usually corresponds to the /dev/ttyQE device, e.g. <0> = /dev/ttyQE0. - The port number is added to the minor number of the device. Unlike the - CPM UART driver, the port-number is required for the QE UART driver. - - soft-uart : for UART drivers, if specified this means the QE UART device - driver should use "Soft-UART" mode, which is needed on some SOCs that have - broken UART hardware. Soft-UART is provided via a microcode upload. - - rx-clock-name: the UCC receive clock source - "none": clock source is disabled - "brg1" through "brg16": clock source is BRG1-BRG16, respectively - "clk1" through "clk24": clock source is CLK1-CLK24, respectively - - tx-clock-name: the UCC transmit clock source - "none": clock source is disabled - "brg1" through "brg16": clock source is BRG1-BRG16, respectively - "clk1" through "clk24": clock source is CLK1-CLK24, respectively - The following two properties are deprecated. rx-clock has been replaced - with rx-clock-name, and tx-clock has been replaced with tx-clock-name. - Drivers that currently use the deprecated properties should continue to - do so, in order to support older device trees, but they should be updated - to check for the new properties first. - - rx-clock : represents the UCC receive clock source. - 0x00 : clock source is disabled; - 0x1~0x10 : clock source is BRG1~BRG16 respectively; - 0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively. - - tx-clock: represents the UCC transmit clock source; - 0x00 : clock source is disabled; - 0x1~0x10 : clock source is BRG1~BRG16 respectively; - 0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively. - - Required properties for network device_type: - - mac-address : list of bytes representing the ethernet address. - - phy-handle : The phandle for the PHY connected to this controller. - - Recommended properties: - - phy-connection-type : a string naming the controller/PHY interface type, - i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id" (Internal - Delay), "rgmii-txid" (delay on TX only), "rgmii-rxid" (delay on RX only), - "tbi", or "rtbi". - - Example: - ucc@2000 { - device_type = "network"; - compatible = "ucc_geth"; - cell-index = <1>; - reg = <2000 200>; - interrupts = ; - interrupt-parent = <700>; - mac-address = [ 00 04 9f 00 23 23 ]; - rx-clock = "none"; - tx-clock = "clk9"; - phy-handle = <212000>; - phy-connection-type = "gmii"; - pio-handle = <140001>; - }; - - - v) Parallel I/O Ports - - This node configures Parallel I/O ports for CPUs with QE support. - The node should reside in the "soc" node of the tree. For each - device that using parallel I/O ports, a child node should be created. - See the definition of the Pin configuration nodes below for more - information. - - Required properties: - - device_type : should be "par_io". - - reg : offset to the register set and its length. - - num-ports : number of Parallel I/O ports - - Example: - par_io@1400 { - reg = <1400 100>; - #address-cells = <1>; - #size-cells = <0>; - device_type = "par_io"; - num-ports = <7>; - ucc_pin@01 { - ...... - }; - - Note that "par_io" nodes are obsolete, and should not be used for - the new device trees. Instead, each Par I/O bank should be represented - via its own gpio-controller node: - - Required properties: - - #gpio-cells : should be "2". - - compatible : should be "fsl,-qe-pario-bank", - "fsl,mpc8323-qe-pario-bank". - - reg : offset to the register set and its length. - - gpio-controller : node to identify gpio controllers. - - Example: - qe_pio_a: gpio-controller@1400 { - #gpio-cells = <2>; - compatible = "fsl,mpc8360-qe-pario-bank", - "fsl,mpc8323-qe-pario-bank"; - reg = <0x1400 0x18>; - gpio-controller; - }; - - qe_pio_e: gpio-controller@1460 { - #gpio-cells = <2>; - compatible = "fsl,mpc8360-qe-pario-bank", - "fsl,mpc8323-qe-pario-bank"; - reg = <0x1460 0x18>; - gpio-controller; - }; - - vi) Pin configuration nodes - - Required properties: - - linux,phandle : phandle of this node; likely referenced by a QE - device. - - pio-map : array of pin configurations. Each pin is defined by 6 - integers. The six numbers are respectively: port, pin, dir, - open_drain, assignment, has_irq. - - port : port number of the pin; 0-6 represent port A-G in UM. - - pin : pin number in the port. - - dir : direction of the pin, should encode as follows: - - 0 = The pin is disabled - 1 = The pin is an output - 2 = The pin is an input - 3 = The pin is I/O - - - open_drain : indicates the pin is normal or wired-OR: - - 0 = The pin is actively driven as an output - 1 = The pin is an open-drain driver. As an output, the pin is - driven active-low, otherwise it is three-stated. - - - assignment : function number of the pin according to the Pin Assignment - tables in User Manual. Each pin can have up to 4 possible functions in - QE and two options for CPM. - - has_irq : indicates if the pin is used as source of external - interrupts. - - Example: - ucc_pin@01 { - linux,phandle = <140001>; - pio-map = < - /* port pin dir open_drain assignment has_irq */ - 0 3 1 0 1 0 /* TxD0 */ - 0 4 1 0 1 0 /* TxD1 */ - 0 5 1 0 1 0 /* TxD2 */ - 0 6 1 0 1 0 /* TxD3 */ - 1 6 1 0 3 0 /* TxD4 */ - 1 7 1 0 1 0 /* TxD5 */ - 1 9 1 0 2 0 /* TxD6 */ - 1 a 1 0 2 0 /* TxD7 */ - 0 9 2 0 1 0 /* RxD0 */ - 0 a 2 0 1 0 /* RxD1 */ - 0 b 2 0 1 0 /* RxD2 */ - 0 c 2 0 1 0 /* RxD3 */ - 0 d 2 0 1 0 /* RxD4 */ - 1 1 2 0 2 0 /* RxD5 */ - 1 0 2 0 2 0 /* RxD6 */ - 1 4 2 0 2 0 /* RxD7 */ - 0 7 1 0 1 0 /* TX_EN */ - 0 8 1 0 1 0 /* TX_ER */ - 0 f 2 0 1 0 /* RX_DV */ - 0 10 2 0 1 0 /* RX_ER */ - 0 0 2 0 1 0 /* RX_CLK */ - 2 9 1 0 3 0 /* GTX_CLK - CLK10 */ - 2 8 2 0 1 0>; /* GTX125 - CLK9 */ - }; - - vii) Multi-User RAM (MURAM) - - Required properties: - - compatible : should be "fsl,qe-muram", "fsl,cpm-muram". - - mode : the could be "host" or "slave". - - ranges : Should be defined as specified in 1) to describe the - translation of MURAM addresses. - - data-only : sub-node which defines the address area under MURAM - bus that can be allocated as data/parameter - - Example: - - muram@10000 { - compatible = "fsl,qe-muram", "fsl,cpm-muram"; - ranges = <0 00010000 0000c000>; - - data-only@0{ - compatible = "fsl,qe-muram-data", - "fsl,cpm-muram-data"; - reg = <0 c000>; - }; - }; - - viii) Uploaded QE firmware - - If a new firwmare has been uploaded to the QE (usually by the - boot loader), then a 'firmware' child node should be added to the QE - node. This node provides information on the uploaded firmware that - device drivers may need. - - Required properties: - - id: The string name of the firmware. This is taken from the 'id' - member of the qe_firmware structure of the uploaded firmware. - Device drivers can search this string to determine if the - firmware they want is already present. - - extended-modes: The Extended Modes bitfield, taken from the - firmware binary. It is a 64-bit number represented - as an array of two 32-bit numbers. - - virtual-traps: The virtual traps, taken from the firmware binary. - It is an array of 8 32-bit numbers. - - Example: - - firmware { - id = "Soft-UART"; - extended-modes = <0 0>; - virtual-traps = <0 0 0 0 0 0 0 0>; - } - - j) CFI or JEDEC memory-mapped NOR flash + c) CFI or JEDEC memory-mapped NOR flash Flash chips (Memory Technology Devices) are often used for solid state file systems on embedded devices. @@ -1936,310 +1347,7 @@ platforms are moved over to use the flattened-device-tree model. }; }; - k) Global Utilities Block - - The global utilities block controls power management, I/O device - enabling, power-on-reset configuration monitoring, general-purpose - I/O signal configuration, alternate function selection for multiplexed - signals, and clock control. - - Required properties: - - - compatible : Should define the compatible device type for - global-utilities. - - reg : Offset and length of the register set for the device. - - Recommended properties: - - - fsl,has-rstcr : Indicates that the global utilities register set - contains a functioning "reset control register" (i.e. the board - is wired to reset upon setting the HRESET_REQ bit in this register). - - Example: - - global-utilities@e0000 { /* global utilities block */ - compatible = "fsl,mpc8548-guts"; - reg = ; - fsl,has-rstcr; - }; - - l) Freescale Communications Processor Module - - NOTE: This is an interim binding, and will likely change slightly, - as more devices are supported. The QE bindings especially are - incomplete. - - i) Root CPM node - - Properties: - - compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe". - - reg : A 48-byte region beginning with CPCR. - - Example: - cpm@119c0 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - compatible = "fsl,mpc8272-cpm", "fsl,cpm2"; - reg = <119c0 30>; - } - - ii) Properties common to mulitple CPM/QE devices - - - fsl,cpm-command : This value is ORed with the opcode and command flag - to specify the device on which a CPM command operates. - - - fsl,cpm-brg : Indicates which baud rate generator the device - is associated with. If absent, an unused BRG - should be dynamically allocated. If zero, the - device uses an external clock rather than a BRG. - - - reg : Unless otherwise specified, the first resource represents the - scc/fcc/ucc registers, and the second represents the device's - parameter RAM region (if it has one). - - iii) Serial - - Currently defined compatibles: - - fsl,cpm1-smc-uart - - fsl,cpm2-smc-uart - - fsl,cpm1-scc-uart - - fsl,cpm2-scc-uart - - fsl,qe-uart - - Example: - - serial@11a00 { - device_type = "serial"; - compatible = "fsl,mpc8272-scc-uart", - "fsl,cpm2-scc-uart"; - reg = <11a00 20 8000 100>; - interrupts = <28 8>; - interrupt-parent = <&PIC>; - fsl,cpm-brg = <1>; - fsl,cpm-command = <00800000>; - }; - - iii) Network - - Currently defined compatibles: - - fsl,cpm1-scc-enet - - fsl,cpm2-scc-enet - - fsl,cpm1-fec-enet - - fsl,cpm2-fcc-enet (third resource is GFEMR) - - fsl,qe-enet - - Example: - - ethernet@11300 { - device_type = "network"; - compatible = "fsl,mpc8272-fcc-enet", - "fsl,cpm2-fcc-enet"; - reg = <11300 20 8400 100 11390 1>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <20 8>; - interrupt-parent = <&PIC>; - phy-handle = <&PHY0>; - fsl,cpm-command = <12000300>; - }; - - iv) MDIO - - Currently defined compatibles: - fsl,pq1-fec-mdio (reg is same as first resource of FEC device) - fsl,cpm2-mdio-bitbang (reg is port C registers) - - Properties for fsl,cpm2-mdio-bitbang: - fsl,mdio-pin : pin of port C controlling mdio data - fsl,mdc-pin : pin of port C controlling mdio clock - - Example: - - mdio@10d40 { - device_type = "mdio"; - compatible = "fsl,mpc8272ads-mdio-bitbang", - "fsl,mpc8272-mdio-bitbang", - "fsl,cpm2-mdio-bitbang"; - reg = <10d40 14>; - #address-cells = <1>; - #size-cells = <0>; - fsl,mdio-pin = <12>; - fsl,mdc-pin = <13>; - }; - - v) Baud Rate Generators - - Currently defined compatibles: - fsl,cpm-brg - fsl,cpm1-brg - fsl,cpm2-brg - - Properties: - - reg : There may be an arbitrary number of reg resources; BRG - numbers are assigned to these in order. - - clock-frequency : Specifies the base frequency driving - the BRG. - - Example: - - brg@119f0 { - compatible = "fsl,mpc8272-brg", - "fsl,cpm2-brg", - "fsl,cpm-brg"; - reg = <119f0 10 115f0 10>; - clock-frequency = ; - }; - - vi) Interrupt Controllers - - Currently defined compatibles: - - fsl,cpm1-pic - - only one interrupt cell - - fsl,pq1-pic - - fsl,cpm2-pic - - second interrupt cell is level/sense: - - 2 is falling edge - - 8 is active low - - Example: - - interrupt-controller@10c00 { - #interrupt-cells = <2>; - interrupt-controller; - reg = <10c00 80>; - compatible = "mpc8272-pic", "fsl,cpm2-pic"; - }; - - vii) USB (Universal Serial Bus Controller) - - Properties: - - compatible : "fsl,cpm1-usb", "fsl,cpm2-usb", "fsl,qe-usb" - - Example: - usb@11bc0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,cpm2-usb"; - reg = <11b60 18 8b00 100>; - interrupts = ; - interrupt-parent = <&PIC>; - fsl,cpm-command = <2e600000>; - }; - - viii) Multi-User RAM (MURAM) - - The multi-user/dual-ported RAM is expressed as a bus under the CPM node. - - Ranges must be set up subject to the following restrictions: - - - Children's reg nodes must be offsets from the start of all muram, even - if the user-data area does not begin at zero. - - If multiple range entries are used, the difference between the parent - address and the child address must be the same in all, so that a single - mapping can cover them all while maintaining the ability to determine - CPM-side offsets with pointer subtraction. It is recommended that - multiple range entries not be used. - - A child address of zero must be translatable, even if no reg resources - contain it. - - A child "data" node must exist, compatible with "fsl,cpm-muram-data", to - indicate the portion of muram that is usable by the OS for arbitrary - purposes. The data node may have an arbitrary number of reg resources, - all of which contribute to the allocatable muram pool. - - Example, based on mpc8272: - - muram@0 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0 10000>; - - data@0 { - compatible = "fsl,cpm-muram-data"; - reg = <0 2000 9800 800>; - }; - }; - - x) I2C - - The I2C controller is expressed as a bus under the CPM node. - - Properties: - - compatible : "fsl,cpm1-i2c", "fsl,cpm2-i2c" - - reg : On CPM2 devices, the second resource doesn't specify the I2C - Parameter RAM itself, but the I2C_BASE field of the CPM2 Parameter RAM - (typically 0x8afc 0x2). - - #address-cells : Should be one. The cell is the i2c device address with - the r/w bit set to zero. - - #size-cells : Should be zero. - - clock-frequency : Can be used to set the i2c clock frequency. If - unspecified, a default frequency of 60kHz is being used. - The following two properties are deprecated. They are only used by legacy - i2c drivers to find the bus to probe: - - linux,i2c-index : Can be used to hard code an i2c bus number. By default, - the bus number is dynamically assigned by the i2c core. - - linux,i2c-class : Can be used to override the i2c class. The class is used - by legacy i2c device drivers to find a bus in a specific context like - system management, video or sound. By default, I2C_CLASS_HWMON (1) is - being used. The definition of the classes can be found in - include/i2c/i2c.h - - Example, based on mpc823: - - i2c@860 { - compatible = "fsl,mpc823-i2c", - "fsl,cpm1-i2c"; - reg = <0x860 0x20 0x3c80 0x30>; - interrupts = <16>; - interrupt-parent = <&CPM_PIC>; - fsl,cpm-command = <0x10>; - #address-cells = <1>; - #size-cells = <0>; - - rtc@68 { - compatible = "dallas,ds1307"; - reg = <0x68>; - }; - }; - - m) Chipselect/Local Bus - - Properties: - - name : Should be localbus - - #address-cells : Should be either two or three. The first cell is the - chipselect number, and the remaining cells are the - offset into the chipselect. - - #size-cells : Either one or two, depending on how large each chipselect - can be. - - ranges : Each range corresponds to a single chipselect, and cover - the entire access window as configured. - - Example: - localbus@f0010100 { - compatible = "fsl,mpc8272-localbus", - "fsl,pq2-localbus"; - #address-cells = <2>; - #size-cells = <1>; - reg = ; - - ranges = <0 0 fe000000 02000000 - 1 0 f4500000 00008000>; - - flash@0,0 { - compatible = "jedec-flash"; - reg = <0 0 2000000>; - bank-width = <4>; - device-width = <1>; - }; - - board-control@1,0 { - reg = <1 0 20>; - compatible = "fsl,mpc8272ads-bcsr"; - }; - }; - - - n) 4xx/Axon EMAC ethernet nodes + d) 4xx/Axon EMAC ethernet nodes The EMAC ethernet controller in IBM and AMCC 4xx chips, and also the Axon bridge. To operate this needs to interact with a ths @@ -2387,7 +1495,7 @@ platforms are moved over to use the flattened-device-tree model. available. For Axon: 0x0000012a - o) Xilinx IP cores + e) Xilinx IP cores The Xilinx EDK toolchain ships with a set of IP cores (devices) for use in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range @@ -2681,206 +1789,7 @@ platforms are moved over to use the flattened-device-tree model. - reg-offset : A value of 3 is required - reg-shift : A value of 2 is required - - p) Freescale Synchronous Serial Interface - - The SSI is a serial device that communicates with audio codecs. It can - be programmed in AC97, I2S, left-justified, or right-justified modes. - - Required properties: - - compatible : compatible list, containing "fsl,ssi" - - cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on - - reg : offset and length of the register set for the device - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and - level information for the interrupt. This should be - encoded based on the information in section 2) - depending on the type of interrupt controller you - have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - fsl,mode : the operating mode for the SSI interface - "i2s-slave" - I2S mode, SSI is clock slave - "i2s-master" - I2S mode, SSI is clock master - "lj-slave" - left-justified mode, SSI is clock slave - "lj-master" - l.j. mode, SSI is clock master - "rj-slave" - right-justified mode, SSI is clock slave - "rj-master" - r.j., SSI is clock master - "ac97-slave" - AC97 mode, SSI is clock slave - "ac97-master" - AC97 mode, SSI is clock master - - Optional properties: - - codec-handle : phandle to a 'codec' node that defines an audio - codec connected to this SSI. This node is typically - a child of an I2C or other control node. - - Child 'codec' node required properties: - - compatible : compatible list, contains the name of the codec - - Child 'codec' node optional properties: - - clock-frequency : The frequency of the input clock, which typically - comes from an on-board dedicated oscillator. - - * Freescale 83xx DMA Controller - - Freescale PowerPC 83xx have on chip general purpose DMA controllers. - - Required properties: - - - compatible : compatible list, contains 2 entries, first is - "fsl,CHIP-dma", where CHIP is the processor - (mpc8349, mpc8360, etc.) and the second is - "fsl,elo-dma" - - reg : - - ranges : Should be defined as specified in 1) to describe the - DMA controller channels. - - cell-index : controller index. 0 for controller @ 0x8100 - - interrupts : - - interrupt-parent : optional, if needed for interrupt mapping - - - - DMA channel nodes: - - compatible : compatible list, contains 2 entries, first is - "fsl,CHIP-dma-channel", where CHIP is the processor - (mpc8349, mpc8350, etc.) and the second is - "fsl,elo-dma-channel" - - reg : - - cell-index : dma channel index starts at 0. - - Optional properties: - - interrupts : - (on 83xx this is expected to be identical to - the interrupts property of the parent node) - - interrupt-parent : optional, if needed for interrupt mapping - - Example: - dma@82a8 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8349-dma", "fsl,elo-dma"; - reg = <82a8 4>; - ranges = <0 8100 1a4>; - interrupt-parent = <&ipic>; - interrupts = <47 8>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; - cell-index = <0>; - reg = <0 80>; - }; - dma-channel@80 { - compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; - cell-index = <1>; - reg = <80 80>; - }; - dma-channel@100 { - compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; - cell-index = <2>; - reg = <100 80>; - }; - dma-channel@180 { - compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; - cell-index = <3>; - reg = <180 80>; - }; - }; - - * Freescale 85xx/86xx DMA Controller - - Freescale PowerPC 85xx/86xx have on chip general purpose DMA controllers. - - Required properties: - - - compatible : compatible list, contains 2 entries, first is - "fsl,CHIP-dma", where CHIP is the processor - (mpc8540, mpc8540, etc.) and the second is - "fsl,eloplus-dma" - - reg : - - cell-index : controller index. 0 for controller @ 0x21000, - 1 for controller @ 0xc000 - - ranges : Should be defined as specified in 1) to describe the - DMA controller channels. - - - DMA channel nodes: - - compatible : compatible list, contains 2 entries, first is - "fsl,CHIP-dma-channel", where CHIP is the processor - (mpc8540, mpc8560, etc.) and the second is - "fsl,eloplus-dma-channel" - - cell-index : dma channel index starts at 0. - - reg : - - interrupts : - - interrupt-parent : optional, if needed for interrupt mapping - - Example: - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma"; - reg = <21300 4>; - ranges = <0 21100 200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; - reg = <0 80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <14 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; - reg = <80 80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <15 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; - reg = <100 80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <16 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; - reg = <180 80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <17 2>; - }; - }; - - * Freescale 8xxx/3.0 Gb/s SATA nodes - - SATA nodes are defined to describe on-chip Serial ATA controllers. - Each SATA port should have its own node. - - Required properties: - - compatible : compatible list, contains 2 entries, first is - "fsl,CHIP-sata", where CHIP is the processor - (mpc8315, mpc8379, etc.) and the second is - "fsl,pq-sata" - - interrupts : - - cell-index : controller index. - 1 for controller @ 0x18000 - 2 for controller @ 0x19000 - 3 for controller @ 0x1a000 - 4 for controller @ 0x1b000 - - Optional properties: - - interrupt-parent : optional, if needed for interrupt mapping - - reg : - - Example: - - sata@18000 { - compatible = "fsl,mpc8379-sata", "fsl,pq-sata"; - reg = <0x18000 0x1000>; - cell-index = <1>; - interrupts = <2c 8>; - interrupt-parent = < &ipic >; - }; - - q) USB EHCI controllers + f) USB EHCI controllers Required properties: - compatible : should be "usb-ehci". @@ -2906,109 +1815,6 @@ platforms are moved over to use the flattened-device-tree model. big-endian; }; - r) Freescale Display Interface Unit - - The Freescale DIU is a LCD controller, with proper hardware, it can also - drive DVI monitors. - - Required properties: - - compatible : should be "fsl-diu". - - reg : should contain at least address and length of the DIU register - set. - - Interrupts : one DIU interrupt should be describe here. - - Example (MPC8610HPCD) - display@2c000 { - compatible = "fsl,diu"; - reg = <0x2c000 100>; - interrupts = <72 2>; - interrupt-parent = <&mpic>; - }; - - s) Freescale on board FPGA - - This is the memory-mapped registers for on board FPGA. - - Required properities: - - compatible : should be "fsl,fpga-pixis". - - reg : should contain the address and the lenght of the FPPGA register - set. - - Example (MPC8610HPCD) - board-control@e8000000 { - compatible = "fsl,fpga-pixis"; - reg = <0xe8000000 32>; - }; - - t) Freescale MSI interrupt controller - - Reguired properities: - - compatible : compatible list, contains 2 entries, - first is "fsl,CHIP-msi", where CHIP is the processor(mpc8610, mpc8572, - etc.) and the second is "fsl,mpic-msi" or "fsl,ipic-msi" depending on - the parent type. - - reg : should contain the address and the length of the shared message - interrupt register set. - - msi-available-ranges: use style section to define which - msi interrupt can be used in the 256 msi interrupts. This property is - optional, without this, all the 256 MSI interrupts can be used. - - interrupts : each one of the interrupts here is one entry per 32 MSIs, - and routed to the host interrupt controller. the interrupts should - be set as edge sensitive. - - interrupt-parent: the phandle for the interrupt controller - that services interrupts for this device. for 83xx cpu, the interrupts - are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed - to MPIC. - - Example - msi@41600 { - compatible = "fsl,mpc8610-msi", "fsl,mpic-msi"; - reg = <0x41600 0x80>; - msi-available-ranges = <0 0x100>; - interrupts = < - 0xe0 0 - 0xe1 0 - 0xe2 0 - 0xe3 0 - 0xe4 0 - 0xe5 0 - 0xe6 0 - 0xe7 0>; - interrupt-parent = <&mpic>; - }; - - u) Freescale General-purpose Timers Module - - Required properties: - - compatible : should be - "fsl,-gtm", "fsl,gtm" for SOC GTMs - "fsl,-qe-gtm", "fsl,qe-gtm", "fsl,gtm" for QE GTMs - "fsl,-cpm2-gtm", "fsl,cpm2-gtm", "fsl,gtm" for CPM2 GTMs - - reg : should contain gtm registers location and length (0x40). - - interrupts : should contain four interrupts. - - interrupt-parent : interrupt source phandle. - - clock-frequency : specifies the frequency driving the timer. - - Example: - - timer@500 { - compatible = "fsl,mpc8360-gtm", "fsl,gtm"; - reg = <0x500 0x40>; - interrupts = <90 8 78 8 84 8 72 8>; - interrupt-parent = <&ipic>; - /* filled by u-boot */ - clock-frequency = <0>; - }; - - timer@440 { - compatible = "fsl,mpc8360-qe-gtm", "fsl,qe-gtm", "fsl,gtm"; - reg = <0x440 0x40>; - interrupts = <12 13 14 15>; - interrupt-parent = <&qeic>; - /* filled by u-boot */ - clock-frequency = <0>; - }; - VII - Marvell Discovery mv64[345]6x System Controller chips =========================================================== diff --git a/Documentation/powerpc/dts-bindings/fsl/board.txt b/Documentation/powerpc/dts-bindings/fsl/board.txt new file mode 100644 index 0000000..74ae6f1 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/board.txt @@ -0,0 +1,29 @@ +* Board Control and Status (BCSR) + +Required properties: + + - device_type : Should be "board-control" + - reg : Offset and length of the register set for the device + +Example: + + bcsr@f8000000 { + device_type = "board-control"; + reg = ; + }; + +* Freescale on board FPGA + +This is the memory-mapped registers for on board FPGA. + +Required properities: +- compatible : should be "fsl,fpga-pixis". +- reg : should contain the address and the lenght of the FPPGA register + set. + +Example (MPC8610HPCD): + + board-control@e8000000 { + compatible = "fsl,fpga-pixis"; + reg = <0xe8000000 32>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt new file mode 100644 index 0000000..088fc47 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm.txt @@ -0,0 +1,67 @@ +* Freescale Communications Processor Module + +NOTE: This is an interim binding, and will likely change slightly, +as more devices are supported. The QE bindings especially are +incomplete. + +* Root CPM node + +Properties: +- compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe". +- reg : A 48-byte region beginning with CPCR. + +Example: + cpm@119c0 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + compatible = "fsl,mpc8272-cpm", "fsl,cpm2"; + reg = <119c0 30>; + } + +* Properties common to mulitple CPM/QE devices + +- fsl,cpm-command : This value is ORed with the opcode and command flag + to specify the device on which a CPM command operates. + +- fsl,cpm-brg : Indicates which baud rate generator the device + is associated with. If absent, an unused BRG + should be dynamically allocated. If zero, the + device uses an external clock rather than a BRG. + +- reg : Unless otherwise specified, the first resource represents the + scc/fcc/ucc registers, and the second represents the device's + parameter RAM region (if it has one). + +* Multi-User RAM (MURAM) + +The multi-user/dual-ported RAM is expressed as a bus under the CPM node. + +Ranges must be set up subject to the following restrictions: + +- Children's reg nodes must be offsets from the start of all muram, even + if the user-data area does not begin at zero. +- If multiple range entries are used, the difference between the parent + address and the child address must be the same in all, so that a single + mapping can cover them all while maintaining the ability to determine + CPM-side offsets with pointer subtraction. It is recommended that + multiple range entries not be used. +- A child address of zero must be translatable, even if no reg resources + contain it. + +A child "data" node must exist, compatible with "fsl,cpm-muram-data", to +indicate the portion of muram that is usable by the OS for arbitrary +purposes. The data node may have an arbitrary number of reg resources, +all of which contribute to the allocatable muram pool. + +Example, based on mpc8272: + muram@0 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 10000>; + + data@0 { + compatible = "fsl,cpm-muram-data"; + reg = <0 2000 9800 800>; + }; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt new file mode 100644 index 0000000..4c7d45e --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/brg.txt @@ -0,0 +1,21 @@ +* Baud Rate Generators + +Currently defined compatibles: +fsl,cpm-brg +fsl,cpm1-brg +fsl,cpm2-brg + +Properties: +- reg : There may be an arbitrary number of reg resources; BRG + numbers are assigned to these in order. +- clock-frequency : Specifies the base frequency driving + the BRG. + +Example: + brg@119f0 { + compatible = "fsl,mpc8272-brg", + "fsl,cpm2-brg", + "fsl,cpm-brg"; + reg = <119f0 10 115f0 10>; + clock-frequency = ; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt new file mode 100644 index 0000000..87bc604 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/i2c.txt @@ -0,0 +1,41 @@ +* I2C + +The I2C controller is expressed as a bus under the CPM node. + +Properties: +- compatible : "fsl,cpm1-i2c", "fsl,cpm2-i2c" +- reg : On CPM2 devices, the second resource doesn't specify the I2C + Parameter RAM itself, but the I2C_BASE field of the CPM2 Parameter RAM + (typically 0x8afc 0x2). +- #address-cells : Should be one. The cell is the i2c device address with + the r/w bit set to zero. +- #size-cells : Should be zero. +- clock-frequency : Can be used to set the i2c clock frequency. If + unspecified, a default frequency of 60kHz is being used. +The following two properties are deprecated. They are only used by legacy +i2c drivers to find the bus to probe: +- linux,i2c-index : Can be used to hard code an i2c bus number. By default, + the bus number is dynamically assigned by the i2c core. +- linux,i2c-class : Can be used to override the i2c class. The class is used + by legacy i2c device drivers to find a bus in a specific context like + system management, video or sound. By default, I2C_CLASS_HWMON (1) is + being used. The definition of the classes can be found in + include/i2c/i2c.h + +Example, based on mpc823: + + i2c@860 { + compatible = "fsl,mpc823-i2c", + "fsl,cpm1-i2c"; + reg = <0x860 0x20 0x3c80 0x30>; + interrupts = <16>; + interrupt-parent = <&CPM_PIC>; + fsl,cpm-command = <0x10>; + #address-cells = <1>; + #size-cells = <0>; + + rtc@68 { + compatible = "dallas,ds1307"; + reg = <0x68>; + }; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt new file mode 100644 index 0000000..8e3ee16 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/pic.txt @@ -0,0 +1,18 @@ +* Interrupt Controllers + +Currently defined compatibles: +- fsl,cpm1-pic + - only one interrupt cell +- fsl,pq1-pic +- fsl,cpm2-pic + - second interrupt cell is level/sense: + - 2 is falling edge + - 8 is active low + +Example: + interrupt-controller@10c00 { + #interrupt-cells = <2>; + interrupt-controller; + reg = <10c00 80>; + compatible = "mpc8272-pic", "fsl,cpm2-pic"; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt new file mode 100644 index 0000000..74bfda4 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/cpm/usb.txt @@ -0,0 +1,15 @@ +* USB (Universal Serial Bus Controller) + +Properties: +- compatible : "fsl,cpm1-usb", "fsl,cpm2-usb", "fsl,qe-usb" + +Example: + usb@11bc0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,cpm2-usb"; + reg = <11b60 18 8b00 100>; + interrupts = ; + interrupt-parent = <&PIC>; + fsl,cpm-command = <2e600000>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt new file mode 100644 index 0000000..0e42694 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/network.txt @@ -0,0 +1,45 @@ +* Network + +Currently defined compatibles: +- fsl,cpm1-scc-enet +- fsl,cpm2-scc-enet +- fsl,cpm1-fec-enet +- fsl,cpm2-fcc-enet (third resource is GFEMR) +- fsl,qe-enet + +Example: + + ethernet@11300 { + device_type = "network"; + compatible = "fsl,mpc8272-fcc-enet", + "fsl,cpm2-fcc-enet"; + reg = <11300 20 8400 100 11390 1>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <20 8>; + interrupt-parent = <&PIC>; + phy-handle = <&PHY0>; + fsl,cpm-command = <12000300>; + }; + +* MDIO + +Currently defined compatibles: +fsl,pq1-fec-mdio (reg is same as first resource of FEC device) +fsl,cpm2-mdio-bitbang (reg is port C registers) + +Properties for fsl,cpm2-mdio-bitbang: +fsl,mdio-pin : pin of port C controlling mdio data +fsl,mdc-pin : pin of port C controlling mdio clock + +Example: + mdio@10d40 { + device_type = "mdio"; + compatible = "fsl,mpc8272ads-mdio-bitbang", + "fsl,mpc8272-mdio-bitbang", + "fsl,cpm2-mdio-bitbang"; + reg = <10d40 14>; + #address-cells = <1>; + #size-cells = <0>; + fsl,mdio-pin = <12>; + fsl,mdc-pin = <13>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt new file mode 100644 index 0000000..78790d5 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt @@ -0,0 +1,58 @@ +* Freescale QUICC Engine module (QE) +This represents qe module that is installed on PowerQUICC II Pro. + +NOTE: This is an interim binding; it should be updated to fit +in with the CPM binding later in this document. + +Basically, it is a bus of devices, that could act more or less +as a complete entity (UCC, USB etc ). All of them should be siblings on +the "root" qe node, using the common properties from there. +The description below applies to the qe of MPC8360 and +more nodes and properties would be extended in the future. + +i) Root QE device + +Required properties: +- compatible : should be "fsl,qe"; +- model : precise model of the QE, Can be "QE", "CPM", or "CPM2" +- reg : offset and length of the device registers. +- bus-frequency : the clock frequency for QUICC Engine. + +Recommended properties +- brg-frequency : the internal clock source frequency for baud-rate + generators in Hz. + +Example: + qe@e0100000 { + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + compatible = "fsl,qe"; + ranges = <0 e0100000 00100000>; + reg = ; + brg-frequency = <0>; + bus-frequency = <179A7B00>; + } + +* Multi-User RAM (MURAM) + +Required properties: +- compatible : should be "fsl,qe-muram", "fsl,cpm-muram". +- mode : the could be "host" or "slave". +- ranges : Should be defined as specified in 1) to describe the + translation of MURAM addresses. +- data-only : sub-node which defines the address area under MURAM + bus that can be allocated as data/parameter + +Example: + + muram@10000 { + compatible = "fsl,qe-muram", "fsl,cpm-muram"; + ranges = <0 00010000 0000c000>; + + data-only@0{ + compatible = "fsl,qe-muram-data", + "fsl,cpm-muram-data"; + reg = <0 c000>; + }; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt new file mode 100644 index 0000000..6c238f5 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt @@ -0,0 +1,24 @@ +* Uploaded QE firmware + + If a new firwmare has been uploaded to the QE (usually by the + boot loader), then a 'firmware' child node should be added to the QE + node. This node provides information on the uploaded firmware that + device drivers may need. + + Required properties: + - id: The string name of the firmware. This is taken from the 'id' + member of the qe_firmware structure of the uploaded firmware. + Device drivers can search this string to determine if the + firmware they want is already present. + - extended-modes: The Extended Modes bitfield, taken from the + firmware binary. It is a 64-bit number represented + as an array of two 32-bit numbers. + - virtual-traps: The virtual traps, taken from the firmware binary. + It is an array of 8 32-bit numbers. + +Example: + firmware { + id = "Soft-UART"; + extended-modes = <0 0>; + virtual-traps = <0 0 0 0 0 0 0 0>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt new file mode 100644 index 0000000..6098426 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/par_io.txt @@ -0,0 +1,51 @@ +* Parallel I/O Ports + +This node configures Parallel I/O ports for CPUs with QE support. +The node should reside in the "soc" node of the tree. For each +device that using parallel I/O ports, a child node should be created. +See the definition of the Pin configuration nodes below for more +information. + +Required properties: +- device_type : should be "par_io". +- reg : offset to the register set and its length. +- num-ports : number of Parallel I/O ports + +Example: +par_io@1400 { + reg = <1400 100>; + #address-cells = <1>; + #size-cells = <0>; + device_type = "par_io"; + num-ports = <7>; + ucc_pin@01 { + ...... + }; + +Note that "par_io" nodes are obsolete, and should not be used for +the new device trees. Instead, each Par I/O bank should be represented +via its own gpio-controller node: + +Required properties: +- #gpio-cells : should be "2". +- compatible : should be "fsl,-qe-pario-bank", + "fsl,mpc8323-qe-pario-bank". +- reg : offset to the register set and its length. +- gpio-controller : node to identify gpio controllers. + +Example: + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,mpc8360-qe-pario-bank", + "fsl,mpc8323-qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,mpc8360-qe-pario-bank", + "fsl,mpc8323-qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt new file mode 100644 index 0000000..c5b4306 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/pincfg.txt @@ -0,0 +1,60 @@ +* Pin configuration nodes + +Required properties: +- linux,phandle : phandle of this node; likely referenced by a QE + device. +- pio-map : array of pin configurations. Each pin is defined by 6 + integers. The six numbers are respectively: port, pin, dir, + open_drain, assignment, has_irq. + - port : port number of the pin; 0-6 represent port A-G in UM. + - pin : pin number in the port. + - dir : direction of the pin, should encode as follows: + + 0 = The pin is disabled + 1 = The pin is an output + 2 = The pin is an input + 3 = The pin is I/O + + - open_drain : indicates the pin is normal or wired-OR: + + 0 = The pin is actively driven as an output + 1 = The pin is an open-drain driver. As an output, the pin is + driven active-low, otherwise it is three-stated. + + - assignment : function number of the pin according to the Pin Assignment + tables in User Manual. Each pin can have up to 4 possible functions in + QE and two options for CPM. + - has_irq : indicates if the pin is used as source of external + interrupts. + +Example: + ucc_pin@01 { + linux,phandle = <140001>; + pio-map = < + /* port pin dir open_drain assignment has_irq */ + 0 3 1 0 1 0 /* TxD0 */ + 0 4 1 0 1 0 /* TxD1 */ + 0 5 1 0 1 0 /* TxD2 */ + 0 6 1 0 1 0 /* TxD3 */ + 1 6 1 0 3 0 /* TxD4 */ + 1 7 1 0 1 0 /* TxD5 */ + 1 9 1 0 2 0 /* TxD6 */ + 1 a 1 0 2 0 /* TxD7 */ + 0 9 2 0 1 0 /* RxD0 */ + 0 a 2 0 1 0 /* RxD1 */ + 0 b 2 0 1 0 /* RxD2 */ + 0 c 2 0 1 0 /* RxD3 */ + 0 d 2 0 1 0 /* RxD4 */ + 1 1 2 0 2 0 /* RxD5 */ + 1 0 2 0 2 0 /* RxD6 */ + 1 4 2 0 2 0 /* RxD7 */ + 0 7 1 0 1 0 /* TX_EN */ + 0 8 1 0 1 0 /* TX_ER */ + 0 f 2 0 1 0 /* RX_DV */ + 0 10 2 0 1 0 /* RX_ER */ + 0 0 2 0 1 0 /* RX_CLK */ + 2 9 1 0 3 0 /* GTX_CLK - CLK10 */ + 2 8 2 0 1 0>; /* GTX125 - CLK9 */ + }; + + diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt new file mode 100644 index 0000000..e47734b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/ucc.txt @@ -0,0 +1,70 @@ +* UCC (Unified Communications Controllers) + +Required properties: +- device_type : should be "network", "hldc", "uart", "transparent" + "bisync", "atm", or "serial". +- compatible : could be "ucc_geth" or "fsl_atm" and so on. +- cell-index : the ucc number(1-8), corresponding to UCCx in UM. +- reg : Offset and length of the register set for the device +- interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. +- interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. +- pio-handle : The phandle for the Parallel I/O port configuration. +- port-number : for UART drivers, the port number to use, between 0 and 3. + This usually corresponds to the /dev/ttyQE device, e.g. <0> = /dev/ttyQE0. + The port number is added to the minor number of the device. Unlike the + CPM UART driver, the port-number is required for the QE UART driver. +- soft-uart : for UART drivers, if specified this means the QE UART device + driver should use "Soft-UART" mode, which is needed on some SOCs that have + broken UART hardware. Soft-UART is provided via a microcode upload. +- rx-clock-name: the UCC receive clock source + "none": clock source is disabled + "brg1" through "brg16": clock source is BRG1-BRG16, respectively + "clk1" through "clk24": clock source is CLK1-CLK24, respectively +- tx-clock-name: the UCC transmit clock source + "none": clock source is disabled + "brg1" through "brg16": clock source is BRG1-BRG16, respectively + "clk1" through "clk24": clock source is CLK1-CLK24, respectively +The following two properties are deprecated. rx-clock has been replaced +with rx-clock-name, and tx-clock has been replaced with tx-clock-name. +Drivers that currently use the deprecated properties should continue to +do so, in order to support older device trees, but they should be updated +to check for the new properties first. +- rx-clock : represents the UCC receive clock source. + 0x00 : clock source is disabled; + 0x1~0x10 : clock source is BRG1~BRG16 respectively; + 0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively. +- tx-clock: represents the UCC transmit clock source; + 0x00 : clock source is disabled; + 0x1~0x10 : clock source is BRG1~BRG16 respectively; + 0x11~0x28: clock source is QE_CLK1~QE_CLK24 respectively. + +Required properties for network device_type: +- mac-address : list of bytes representing the ethernet address. +- phy-handle : The phandle for the PHY connected to this controller. + +Recommended properties: +- phy-connection-type : a string naming the controller/PHY interface type, + i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id" (Internal + Delay), "rgmii-txid" (delay on TX only), "rgmii-rxid" (delay on RX only), + "tbi", or "rtbi". + +Example: + ucc@2000 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <1>; + reg = <2000 200>; + interrupts = ; + interrupt-parent = <700>; + mac-address = [ 00 04 9f 00 23 23 ]; + rx-clock = "none"; + tx-clock = "clk9"; + phy-handle = <212000>; + phy-connection-type = "gmii"; + pio-handle = <140001>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt new file mode 100644 index 0000000..c8f44d6 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt @@ -0,0 +1,22 @@ +* USB (Universal Serial Bus Controller) + +Required properties: +- compatible : could be "qe_udc" or "fhci-hcd". +- mode : the could be "host" or "slave". +- reg : Offset and length of the register set for the device +- interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. +- interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + +Example(slave): + usb@6c0 { + compatible = "qe_udc"; + reg = <6c0 40>; + interrupts = <8b 0>; + interrupt-parent = <700>; + mode = "slave"; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt new file mode 100644 index 0000000..b35f348 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt @@ -0,0 +1,21 @@ +* Serial + +Currently defined compatibles: +- fsl,cpm1-smc-uart +- fsl,cpm2-smc-uart +- fsl,cpm1-scc-uart +- fsl,cpm2-scc-uart +- fsl,qe-uart + +Example: + + serial@11a00 { + device_type = "serial"; + compatible = "fsl,mpc8272-scc-uart", + "fsl,cpm2-scc-uart"; + reg = <11a00 20 8000 100>; + interrupts = <28 8>; + interrupt-parent = <&PIC>; + fsl,cpm-brg = <1>; + fsl,cpm-command = <00800000>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/diu.txt b/Documentation/powerpc/dts-bindings/fsl/diu.txt new file mode 100644 index 0000000..deb35de --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/diu.txt @@ -0,0 +1,18 @@ +* Freescale Display Interface Unit + +The Freescale DIU is a LCD controller, with proper hardware, it can also +drive DVI monitors. + +Required properties: +- compatible : should be "fsl-diu". +- reg : should contain at least address and length of the DIU register + set. +- Interrupts : one DIU interrupt should be describe here. + +Example (MPC8610HPCD): + display@2c000 { + compatible = "fsl,diu"; + reg = <0x2c000 100>; + interrupts = <72 2>; + interrupt-parent = <&mpic>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/dma.txt b/Documentation/powerpc/dts-bindings/fsl/dma.txt new file mode 100644 index 0000000..86826df --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/dma.txt @@ -0,0 +1,127 @@ +* Freescale 83xx DMA Controller + +Freescale PowerPC 83xx have on chip general purpose DMA controllers. + +Required properties: + +- compatible : compatible list, contains 2 entries, first is + "fsl,CHIP-dma", where CHIP is the processor + (mpc8349, mpc8360, etc.) and the second is + "fsl,elo-dma" +- reg : +- ranges : Should be defined as specified in 1) to describe the + DMA controller channels. +- cell-index : controller index. 0 for controller @ 0x8100 +- interrupts : +- interrupt-parent : optional, if needed for interrupt mapping + + +- DMA channel nodes: + - compatible : compatible list, contains 2 entries, first is + "fsl,CHIP-dma-channel", where CHIP is the processor + (mpc8349, mpc8350, etc.) and the second is + "fsl,elo-dma-channel" + - reg : + - cell-index : dma channel index starts at 0. + +Optional properties: + - interrupts : + (on 83xx this is expected to be identical to + the interrupts property of the parent node) + - interrupt-parent : optional, if needed for interrupt mapping + +Example: + dma@82a8 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8349-dma", "fsl,elo-dma"; + reg = <82a8 4>; + ranges = <0 8100 1a4>; + interrupt-parent = <&ipic>; + interrupts = <47 8>; + cell-index = <0>; + dma-channel@0 { + compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; + cell-index = <0>; + reg = <0 80>; + }; + dma-channel@80 { + compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; + cell-index = <1>; + reg = <80 80>; + }; + dma-channel@100 { + compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; + cell-index = <2>; + reg = <100 80>; + }; + dma-channel@180 { + compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; + cell-index = <3>; + reg = <180 80>; + }; + }; + +* Freescale 85xx/86xx DMA Controller + +Freescale PowerPC 85xx/86xx have on chip general purpose DMA controllers. + +Required properties: + +- compatible : compatible list, contains 2 entries, first is + "fsl,CHIP-dma", where CHIP is the processor + (mpc8540, mpc8540, etc.) and the second is + "fsl,eloplus-dma" +- reg : +- cell-index : controller index. 0 for controller @ 0x21000, + 1 for controller @ 0xc000 +- ranges : Should be defined as specified in 1) to describe the + DMA controller channels. + +- DMA channel nodes: + - compatible : compatible list, contains 2 entries, first is + "fsl,CHIP-dma-channel", where CHIP is the processor + (mpc8540, mpc8560, etc.) and the second is + "fsl,eloplus-dma-channel" + - cell-index : dma channel index starts at 0. + - reg : + - interrupts : + - interrupt-parent : optional, if needed for interrupt mapping + +Example: + dma@21300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma"; + reg = <21300 4>; + ranges = <0 21100 200>; + cell-index = <0>; + dma-channel@0 { + compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; + reg = <0 80>; + cell-index = <0>; + interrupt-parent = <&mpic>; + interrupts = <14 2>; + }; + dma-channel@80 { + compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; + reg = <80 80>; + cell-index = <1>; + interrupt-parent = <&mpic>; + interrupts = <15 2>; + }; + dma-channel@100 { + compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; + reg = <100 80>; + cell-index = <2>; + interrupt-parent = <&mpic>; + interrupts = <16 2>; + }; + dma-channel@180 { + compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel"; + reg = <180 80>; + cell-index = <3>; + interrupt-parent = <&mpic>; + interrupts = <17 2>; + }; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/gtm.txt b/Documentation/powerpc/dts-bindings/fsl/gtm.txt new file mode 100644 index 0000000..9a33efd --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/gtm.txt @@ -0,0 +1,31 @@ +* Freescale General-purpose Timers Module + +Required properties: + - compatible : should be + "fsl,-gtm", "fsl,gtm" for SOC GTMs + "fsl,-qe-gtm", "fsl,qe-gtm", "fsl,gtm" for QE GTMs + "fsl,-cpm2-gtm", "fsl,cpm2-gtm", "fsl,gtm" for CPM2 GTMs + - reg : should contain gtm registers location and length (0x40). + - interrupts : should contain four interrupts. + - interrupt-parent : interrupt source phandle. + - clock-frequency : specifies the frequency driving the timer. + +Example: + +timer@500 { + compatible = "fsl,mpc8360-gtm", "fsl,gtm"; + reg = <0x500 0x40>; + interrupts = <90 8 78 8 84 8 72 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; +}; + +timer@440 { + compatible = "fsl,mpc8360-qe-gtm", "fsl,qe-gtm", "fsl,gtm"; + reg = <0x440 0x40>; + interrupts = <12 13 14 15>; + interrupt-parent = <&qeic>; + /* filled by u-boot */ + clock-frequency = <0>; +}; diff --git a/Documentation/powerpc/dts-bindings/fsl/guts.txt b/Documentation/powerpc/dts-bindings/fsl/guts.txt new file mode 100644 index 0000000..9e7a241 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/guts.txt @@ -0,0 +1,25 @@ +* Global Utilities Block + +The global utilities block controls power management, I/O device +enabling, power-on-reset configuration monitoring, general-purpose +I/O signal configuration, alternate function selection for multiplexed +signals, and clock control. + +Required properties: + + - compatible : Should define the compatible device type for + global-utilities. + - reg : Offset and length of the register set for the device. + +Recommended properties: + + - fsl,has-rstcr : Indicates that the global utilities register set + contains a functioning "reset control register" (i.e. the board + is wired to reset upon setting the HRESET_REQ bit in this register). + +Example: + global-utilities@e0000 { /* global utilities block */ + compatible = "fsl,mpc8548-guts"; + reg = ; + fsl,has-rstcr; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/i2c.txt new file mode 100644 index 0000000..d0ab33e --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/i2c.txt @@ -0,0 +1,32 @@ +* I2C + +Required properties : + + - device_type : Should be "i2c" + - reg : Offset and length of the register set for the device + +Recommended properties : + + - compatible : Should be "fsl-i2c" for parts compatible with + Freescale I2C specifications. + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - dfsrr : boolean; if defined, indicates that this I2C device has + a digital filter sampling rate register + - fsl5200-clocking : boolean; if defined, indicated that this device + uses the FSL 5200 clocking mechanism. + +Example : + i2c@3000 { + interrupt-parent = <40000>; + interrupts = <1b 3>; + reg = <3000 18>; + device_type = "i2c"; + compatible = "fsl-i2c"; + dfsrr; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/lbc.txt b/Documentation/powerpc/dts-bindings/fsl/lbc.txt new file mode 100644 index 0000000..3300fec --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/lbc.txt @@ -0,0 +1,35 @@ +* Chipselect/Local Bus + +Properties: +- name : Should be localbus +- #address-cells : Should be either two or three. The first cell is the + chipselect number, and the remaining cells are the + offset into the chipselect. +- #size-cells : Either one or two, depending on how large each chipselect + can be. +- ranges : Each range corresponds to a single chipselect, and cover + the entire access window as configured. + +Example: + localbus@f0010100 { + compatible = "fsl,mpc8272-localbus", + "fsl,pq2-localbus"; + #address-cells = <2>; + #size-cells = <1>; + reg = ; + + ranges = <0 0 fe000000 02000000 + 1 0 f4500000 00008000>; + + flash@0,0 { + compatible = "jedec-flash"; + reg = <0 0 2000000>; + bank-width = <4>; + device-width = <1>; + }; + + board-control@1,0 { + reg = <1 0 20>; + compatible = "fsl,mpc8272ads-bcsr"; + }; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/msi-pic.txt b/Documentation/powerpc/dts-bindings/fsl/msi-pic.txt new file mode 100644 index 0000000..b26b919 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/msi-pic.txt @@ -0,0 +1,36 @@ +* Freescale MSI interrupt controller + +Reguired properities: +- compatible : compatible list, contains 2 entries, + first is "fsl,CHIP-msi", where CHIP is the processor(mpc8610, mpc8572, + etc.) and the second is "fsl,mpic-msi" or "fsl,ipic-msi" depending on + the parent type. +- reg : should contain the address and the length of the shared message + interrupt register set. +- msi-available-ranges: use style section to define which + msi interrupt can be used in the 256 msi interrupts. This property is + optional, without this, all the 256 MSI interrupts can be used. +- interrupts : each one of the interrupts here is one entry per 32 MSIs, + and routed to the host interrupt controller. the interrupts should + be set as edge sensitive. +- interrupt-parent: the phandle for the interrupt controller + that services interrupts for this device. for 83xx cpu, the interrupts + are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed + to MPIC. + +Example: + msi@41600 { + compatible = "fsl,mpc8610-msi", "fsl,mpic-msi"; + reg = <0x41600 0x80>; + msi-available-ranges = <0 0x100>; + interrupts = < + 0xe0 0 + 0xe1 0 + 0xe2 0 + 0xe3 0 + 0xe4 0 + 0xe5 0 + 0xe6 0 + 0xe7 0>; + interrupt-parent = <&mpic>; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/sata.txt b/Documentation/powerpc/dts-bindings/fsl/sata.txt new file mode 100644 index 0000000..b46bcf4 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/sata.txt @@ -0,0 +1,29 @@ +* Freescale 8xxx/3.0 Gb/s SATA nodes + +SATA nodes are defined to describe on-chip Serial ATA controllers. +Each SATA port should have its own node. + +Required properties: +- compatible : compatible list, contains 2 entries, first is + "fsl,CHIP-sata", where CHIP is the processor + (mpc8315, mpc8379, etc.) and the second is + "fsl,pq-sata" +- interrupts : +- cell-index : controller index. + 1 for controller @ 0x18000 + 2 for controller @ 0x19000 + 3 for controller @ 0x1a000 + 4 for controller @ 0x1b000 + +Optional properties: +- interrupt-parent : optional, if needed for interrupt mapping +- reg : + +Example: + sata@18000 { + compatible = "fsl,mpc8379-sata", "fsl,pq-sata"; + reg = <0x18000 0x1000>; + cell-index = <1>; + interrupts = <2c 8>; + interrupt-parent = < &ipic >; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/spi.txt b/Documentation/powerpc/dts-bindings/fsl/spi.txt new file mode 100644 index 0000000..e7d9a34 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/spi.txt @@ -0,0 +1,24 @@ +* SPI (Serial Peripheral Interface) + +Required properties: +- cell-index : SPI controller index. +- compatible : should be "fsl,spi". +- mode : the SPI operation mode, it can be "cpu" or "cpu-qe". +- reg : Offset and length of the register set for the device +- interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. +- interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + +Example: + spi@4c0 { + cell-index = <0>; + compatible = "fsl,spi"; + reg = <4c0 40>; + interrupts = <82 0>; + interrupt-parent = <700>; + mode = "cpu"; + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/ssi.txt b/Documentation/powerpc/dts-bindings/fsl/ssi.txt new file mode 100644 index 0000000..d100555 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/ssi.txt @@ -0,0 +1,38 @@ +Freescale Synchronous Serial Interface + +The SSI is a serial device that communicates with audio codecs. It can +be programmed in AC97, I2S, left-justified, or right-justified modes. + +Required properties: +- compatible : compatible list, containing "fsl,ssi" +- cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on +- reg : offset and length of the register set for the device +- interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and + level information for the interrupt. This should be + encoded based on the information in section 2) + depending on the type of interrupt controller you + have. +- interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. +- fsl,mode : the operating mode for the SSI interface + "i2s-slave" - I2S mode, SSI is clock slave + "i2s-master" - I2S mode, SSI is clock master + "lj-slave" - left-justified mode, SSI is clock slave + "lj-master" - l.j. mode, SSI is clock master + "rj-slave" - right-justified mode, SSI is clock slave + "rj-master" - r.j., SSI is clock master + "ac97-slave" - AC97 mode, SSI is clock slave + "ac97-master" - AC97 mode, SSI is clock master + +Optional properties: +- codec-handle : phandle to a 'codec' node that defines an audio + codec connected to this SSI. This node is typically + a child of an I2C or other control node. + +Child 'codec' node required properties: +- compatible : compatible list, contains the name of the codec + +Child 'codec' node optional properties: +- clock-frequency : The frequency of the input clock, which typically + comes from an on-board dedicated oscillator. diff --git a/Documentation/powerpc/dts-bindings/fsl/tsec.txt b/Documentation/powerpc/dts-bindings/fsl/tsec.txt new file mode 100644 index 0000000..583ef6b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/tsec.txt @@ -0,0 +1,69 @@ +* MDIO IO device + +The MDIO is a bus to which the PHY devices are connected. For each +device that exists on this bus, a child node should be created. See +the definition of the PHY node below for an example of how to define +a PHY. + +Required properties: + - reg : Offset and length of the register set for the device + - compatible : Should define the compatible device type for the + mdio. Currently, this is most likely to be "fsl,gianfar-mdio" + +Example: + + mdio@24520 { + reg = <24520 20>; + compatible = "fsl,gianfar-mdio"; + + ethernet-phy@0 { + ...... + }; + }; + + +* Gianfar-compatible ethernet nodes + +Required properties: + + - device_type : Should be "network" + - model : Model of the device. Can be "TSEC", "eTSEC", or "FEC" + - compatible : Should be "gianfar" + - reg : Offset and length of the register set for the device + - mac-address : List of bytes representing the ethernet address of + this controller + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - phy-handle : The phandle for the PHY connected to this ethernet + controller. + - fixed-link : where a is emulated phy id - choose any, + but unique to the all specified fixed-links, b is duplex - 0 half, + 1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no + pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause. + +Recommended properties: + + - phy-connection-type : a string naming the controller/PHY interface type, + i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii", + "tbi", or "rtbi". This property is only really needed if the connection + is of type "rgmii-id", as all other connection types are detected by + hardware. + + +Example: + ethernet@24000 { + #size-cells = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <24000 1000>; + mac-address = [ 00 E0 0C 00 73 00 ]; + interrupts = ; + interrupt-parent = <40000>; + phy-handle = <2452000> + }; diff --git a/Documentation/powerpc/dts-bindings/fsl/usb.txt b/Documentation/powerpc/dts-bindings/fsl/usb.txt new file mode 100644 index 0000000..b001524 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/usb.txt @@ -0,0 +1,59 @@ +Freescale SOC USB controllers + +The device node for a USB controller that is part of a Freescale +SOC is as described in the document "Open Firmware Recommended +Practice : Universal Serial Bus" with the following modifications +and additions : + +Required properties : + - compatible : Should be "fsl-usb2-mph" for multi port host USB + controllers, or "fsl-usb2-dr" for dual role USB controllers + - phy_type : For multi port host USB controllers, should be one of + "ulpi", or "serial". For dual role USB controllers, should be + one of "ulpi", "utmi", "utmi_wide", or "serial". + - reg : Offset and length of the register set for the device + - port0 : boolean; if defined, indicates port0 is connected for + fsl-usb2-mph compatible controllers. Either this property or + "port1" (or both) must be defined for "fsl-usb2-mph" compatible + controllers. + - port1 : boolean; if defined, indicates port1 is connected for + fsl-usb2-mph compatible controllers. Either this property or + "port0" (or both) must be defined for "fsl-usb2-mph" compatible + controllers. + - dr_mode : indicates the working mode for "fsl-usb2-dr" compatible + controllers. Can be "host", "peripheral", or "otg". Default to + "host" if not defined for backward compatibility. + +Recommended properties : + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + +Example multi port host USB controller device node : + usb@22000 { + compatible = "fsl-usb2-mph"; + reg = <22000 1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <700>; + interrupts = <27 1>; + phy_type = "ulpi"; + port0; + port1; + }; + +Example dual role USB controller device node : + usb@23000 { + compatible = "fsl-usb2-dr"; + reg = <23000 1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <700>; + interrupts = <26 1>; + dr_mode = "otg"; + phy = "ulpi"; + }; -- cgit v0.10.2 From 3fd44736db9a5bf33e4a216b9cd43c9cfd57c459 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 8 Jul 2008 19:13:33 -0500 Subject: powerpc/fsl: update crypto node definition and device tree instances delete obsolete device-type property, delete model property (use compatible property instead), prepend "fsl," to Freescale specific properties. Add nodes to device trees that are missing them, and fix broken property values in other trees. Signed-off-by: Kim Phillips Signed-off-by: Kumar Gala diff --git a/Documentation/powerpc/dts-bindings/fsl/sec.txt b/Documentation/powerpc/dts-bindings/fsl/sec.txt new file mode 100644 index 0000000..2b6f2d4 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/sec.txt @@ -0,0 +1,68 @@ +Freescale SoC SEC Security Engines + +Required properties: + +- compatible : Should contain entries for this and backward compatible + SEC versions, high to low, e.g., "fsl,sec2.1", "fsl,sec2.0" +- reg : Offset and length of the register set for the device +- interrupts : the SEC's interrupt number +- fsl,num-channels : An integer representing the number of channels + available. +- fsl,channel-fifo-len : An integer representing the number of + descriptor pointers each channel fetch fifo can hold. +- fsl,exec-units-mask : The bitmask representing what execution units + (EUs) are available. It's a single 32-bit cell. EU information + should be encoded following the SEC's Descriptor Header Dword + EU_SEL0 field documentation, i.e. as follows: + + bit 0 = reserved - should be 0 + bit 1 = set if SEC has the ARC4 EU (AFEU) + bit 2 = set if SEC has the DES/3DES EU (DEU) + bit 3 = set if SEC has the message digest EU (MDEU/MDEU-A) + bit 4 = set if SEC has the random number generator EU (RNG) + bit 5 = set if SEC has the public key EU (PKEU) + bit 6 = set if SEC has the AES EU (AESU) + bit 7 = set if SEC has the Kasumi EU (KEU) + bit 8 = set if SEC has the CRC EU (CRCU) + bit 11 = set if SEC has the message digest EU extended alg set (MDEU-B) + +remaining bits are reserved for future SEC EUs. + +- fsl,descriptor-types-mask : The bitmask representing what descriptors + are available. It's a single 32-bit cell. Descriptor type information + should be encoded following the SEC's Descriptor Header Dword DESC_TYPE + field documentation, i.e. as follows: + + bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type + bit 1 = set if SEC supports the ipsec_esp descriptor type + bit 2 = set if SEC supports the common_nonsnoop desc. type + bit 3 = set if SEC supports the 802.11i AES ccmp desc. type + bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type + bit 5 = set if SEC supports the srtp descriptor type + bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type + bit 7 = set if SEC supports the pkeu_assemble descriptor type + bit 8 = set if SEC supports the aesu_key_expand_output desc.type + bit 9 = set if SEC supports the pkeu_ptmul descriptor type + bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type + bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type + + ..and so on and so forth. + +Optional properties: + +- interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + +Example: + + /* MPC8548E */ + crypto@30000 { + compatible = "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <29 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0xfe>; + fsl,descriptor-types-mask = <0x12b0ebf>; + }; diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts index d27f8a7..2a1929a 100644 --- a/arch/powerpc/boot/dts/mpc8272ads.dts +++ b/arch/powerpc/boot/dts/mpc8272ads.dts @@ -237,22 +237,15 @@ compatible = "fsl,mpc8272-pic", "fsl,cpm2-pic"; }; -/* May need to remove if on a part without crypto engine */ crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "fsl,mpc8272-talitos-sec2", - "fsl,talitos-sec2", - "fsl,talitos", - "talitos"; - reg = <0x30000 0x10000>; - interrupts = <11 8>; + compatible = "fsl,sec1.0"; + reg = <0x40000 0x13000>; + interrupts = <47 0x8>; interrupt-parent = <&PIC>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x7e>; -/* desc mask is for rev1.x, we need runtime fixup for >=2.x */ - descriptor-types-mask = <0x1010ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x1010415>; }; }; diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts index b206843..3664fb5 100644 --- a/arch/powerpc/boot/dts/mpc8313erdb.dts +++ b/arch/powerpc/boot/dts/mpc8313erdb.dts @@ -254,17 +254,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <0x30000 0x7000>; + compatible = "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 2.2 */ - num-channels = <1>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000004c>; - descriptor-types-mask = <0x0122003f>; + fsl,num-channels = <1>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x4c>; + fsl,descriptor-types-mask = <0x0122003f>; }; /* IPIC diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index a40e806..f704513 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -241,17 +241,16 @@ }; crypto@30000 { - model = "SEC3"; - device_type = "crypto"; - compatible = "talitos"; + compatible = "fsl,sec3.3", "fsl,sec3.1", "fsl,sec3.0", + "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", + "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x97c>; + fsl,descriptor-types-mask = <0x3ab0abf>; }; sata@18000 { diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts index b5968b6..7345743 100644 --- a/arch/powerpc/boot/dts/mpc832x_mds.dts +++ b/arch/powerpc/boot/dts/mpc832x_mds.dts @@ -150,17 +150,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <0x30000 0x7000>; + compatible = "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 2.2 */ - num-channels = <1>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000004c>; - descriptor-types-mask = <0x0122003f>; + fsl,num-channels = <1>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x4c>; + fsl,descriptor-types-mask = <0x0122003f>; }; ipic: pic@700 { diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts index a798d86..e74c045 100644 --- a/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -128,17 +128,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <0x30000 0x7000>; + compatible = "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 2.2 */ - num-channels = <1>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000004c>; - descriptor-types-mask = <0x0122003f>; + fsl,num-channels = <1>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x4c>; + fsl,descriptor-types-mask = <0x0122003f>; }; ipic:pic@700 { diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index fc0f4c9..8dfab56 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -213,16 +213,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; + compatible = "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000007e>; - descriptor-types-mask = <0x01010ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; }; ipic: pic@700 { diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index e6afb1d..49ca349 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -186,16 +186,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; + compatible = "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000007e>; - descriptor-types-mask = <0x01010ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; }; ipic: pic@700 { diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts index 9c75c7c..ba586cb 100644 --- a/arch/powerpc/boot/dts/mpc834x_mds.dts +++ b/arch/powerpc/boot/dts/mpc834x_mds.dts @@ -228,20 +228,15 @@ interrupt-parent = <&ipic>; }; - /* May need to remove if on a part without crypto engine */ crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; + compatible = "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000007e>; - /* desc mask is for rev2.0, - * we need runtime fixup for >2.0 */ - descriptor-types-mask = <0x01010ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; }; /* IPIC diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts index 8e33b15..3701dae 100644 --- a/arch/powerpc/boot/dts/mpc836x_mds.dts +++ b/arch/powerpc/boot/dts/mpc836x_mds.dts @@ -154,17 +154,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; + compatible = "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000007e>; - /* desc mask is for rev1.x, we need runtime fixup for >=2.x */ - descriptor-types-mask = <0x01010ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; }; ipic: pic@700 { diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts index 49a38cb..0a700cb 100644 --- a/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -269,16 +269,15 @@ }; crypto@30000 { - model = "SEC3"; - compatible = "talitos"; + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; }; sdhc@2e000 { diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 1f45387..ed137aa 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -248,17 +248,15 @@ }; crypto@30000 { - model = "SEC3"; - device_type = "crypto"; - compatible = "talitos"; + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; }; sata@18000 { diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts index 99ad49d..29c8c76 100644 --- a/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -269,16 +269,15 @@ }; crypto@30000 { - model = "SEC3"; - compatible = "talitos"; + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; }; sdhc@2e000 { diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 44e34d3..34a7f2f 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -248,17 +248,15 @@ }; crypto@30000 { - model = "SEC3"; - device_type = "crypto"; - compatible = "talitos"; + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; }; /* IPIC diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts index 980be81..d641a89 100644 --- a/arch/powerpc/boot/dts/mpc8379_mds.dts +++ b/arch/powerpc/boot/dts/mpc8379_mds.dts @@ -269,16 +269,15 @@ }; crypto@30000 { - model = "SEC3"; - compatible = "talitos"; + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; }; sdhc@2e000 { diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index eeedf58..e4d7030 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -248,17 +248,15 @@ }; crypto@30000 { - model = "SEC3"; - device_type = "crypto"; - compatible = "talitos"; + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - /* Rev. 3.0 geometry */ - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x000001fe>; - descriptor-types-mask = <0x03ab0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; }; sata@18000 { diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts index 98ad27a..02cfa24 100644 --- a/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -231,6 +231,18 @@ interrupt-parent = <&mpic>; }; + crypto@30000 { + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2 58 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; + }; + sata@18000 { compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; reg = <0x18000 0x1000>; diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts index 21ad71b..c4469f1 100644 --- a/arch/powerpc/boot/dts/mpc8541cds.dts +++ b/arch/powerpc/boot/dts/mpc8541cds.dts @@ -189,6 +189,17 @@ interrupt-parent = <&mpic>; }; + crypto@30000 { + compatible = "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts index 6cf533f..7d3829d 100644 --- a/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/arch/powerpc/boot/dts/mpc8544ds.dts @@ -210,6 +210,17 @@ fsl,has-rstcr; }; + crypto@30000 { + compatible = "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0xfe>; + fsl,descriptor-types-mask = <0x12b0ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts index d1fa6bb..d84466b 100644 --- a/arch/powerpc/boot/dts/mpc8548cds.dts +++ b/arch/powerpc/boot/dts/mpc8548cds.dts @@ -249,6 +249,17 @@ fsl,has-rstcr; }; + crypto@30000 { + compatible = "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0xfe>; + fsl,descriptor-types-mask = <0x12b0ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts index 6fc8059..e03a780 100644 --- a/arch/powerpc/boot/dts/mpc8555cds.dts +++ b/arch/powerpc/boot/dts/mpc8555cds.dts @@ -189,6 +189,17 @@ interrupt-parent = <&mpic>; }; + crypto@30000 { + compatible = "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts index be9a289..9c30a34 100644 --- a/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/arch/powerpc/boot/dts/mpc8568mds.dts @@ -231,16 +231,14 @@ }; crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <0x30000 0xf000>; + compatible = "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; interrupts = <45 2>; interrupt-parent = <&mpic>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0xfe>; - descriptor-types-mask = <0x12b0ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0xfe>; + fsl,descriptor-types-mask = <0x12b0ebf>; }; mpic: pic@40000 { diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index cb06325..08c61e3 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -321,6 +321,18 @@ interrupt-parent = <&mpic>; }; + crypto@30000 { + compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", + "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2 58 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x9fe>; + fsl,descriptor-types-mask = <0x3ab0ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/sbc8349.dts b/arch/powerpc/boot/dts/sbc8349.dts index 5b76bb2..45f789b 100644 --- a/arch/powerpc/boot/dts/sbc8349.dts +++ b/arch/powerpc/boot/dts/sbc8349.dts @@ -221,19 +221,15 @@ interrupt-parent = <&ipic>; }; - /* May need to remove if on a part without crypto engine */ crypto@30000 { - model = "SEC2"; - compatible = "talitos"; + compatible = "fsl,sec2.0"; reg = <0x30000 0x10000>; interrupts = <11 0x8>; interrupt-parent = <&ipic>; - num-channels = <4>; - channel-fifo-len = <24>; - exec-units-mask = <0x0000007e>; - /* desc mask is for rev2.0, - * we need runtime fixup for >2.0 */ - descriptor-types-mask = <0x01010ebf>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; }; /* IPIC diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts index 21cbacb..333552b 100644 --- a/arch/powerpc/boot/dts/sbc8548.dts +++ b/arch/powerpc/boot/dts/sbc8548.dts @@ -304,6 +304,17 @@ fsl,has-rstcr; }; + crypto@30000 { + compatible = "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0xfe>; + fsl,descriptor-types-mask = <0x12b0ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/tqm8541.dts b/arch/powerpc/boot/dts/tqm8541.dts index d083a64..d76441e 100644 --- a/arch/powerpc/boot/dts/tqm8541.dts +++ b/arch/powerpc/boot/dts/tqm8541.dts @@ -200,6 +200,17 @@ interrupt-parent = <&mpic>; }; + crypto@30000 { + compatible = "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/boot/dts/tqm8555.dts b/arch/powerpc/boot/dts/tqm8555.dts index 96b0b94..6f7ea59 100644 --- a/arch/powerpc/boot/dts/tqm8555.dts +++ b/arch/powerpc/boot/dts/tqm8555.dts @@ -200,6 +200,17 @@ interrupt-parent = <&mpic>; }; + crypto@30000 { + compatible = "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x7e>; + fsl,descriptor-types-mask = <0x01010ebf>; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; -- cgit v0.10.2 From 1c776bf87c855a6e823e13c3667f0cf7c14635bd Mon Sep 17 00:00:00 2001 From: Krzysztof Oledzki Date: Wed, 4 Jun 2008 03:40:17 +0200 Subject: x86: add another PCI ID for ICH6 force-hpet Tested on Asus P5GDC-V $ lspci -n -n |grep ISA 00:1f.0 ISA bridge [0601]: Intel Corporation 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge [8086:2640] (rev 03) Force enabled HPET at base address 0xfed00000 hpet clockevent registered hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0 hpet0: 3 64-bit timers, 14318180 Hz Signed-off-by: Krzysztof Piotr Oledzki Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index d89a648..06e1fd6 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -158,6 +158,8 @@ static void ich_force_enable_hpet(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, ich_force_enable_hpet); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, + ich_force_enable_hpet); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, ich_force_enable_hpet); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, -- cgit v0.10.2 From 4c2a997c34c0aa952ba9c247b0c2043526054919 Mon Sep 17 00:00:00 2001 From: Joe Buehler Date: Mon, 9 Jun 2008 08:55:20 -0400 Subject: x86: add PCI ID for 6300ESB force hpet 00:1f.0 ISA bridge: Intel Corporation 6300ESB LPC Interface Controller (rev 02) 00:1f.0 Class 0601: 8086:25a1 (rev 02) kernel: pci 0000:00:1f.0: Force enabled HPET at 0xfed00000 kernel: hpet clockevent registered kernel: hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0 kernel: hpet0: 3 64-bit timers, 14318180 Hz Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 06e1fd6..f327aba 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -257,6 +257,8 @@ static void old_ich_force_enable_hpet_user(struct pci_dev *dev) old_ich_force_enable_hpet(dev); } +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, + old_ich_force_enable_hpet_user); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, old_ich_force_enable_hpet_user); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, -- cgit v0.10.2 From 7798ed0f57b4d137e660fbf5be1e1528e40f89ac Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 14 Jul 2008 19:55:03 +1000 Subject: generic-ipi: powerpc/generic-ipi tree build failure Today's linux-next build (powerpc allmodconfig) failed like this: ERROR: ".save_stack_trace" [tests/backtracetest.ko] undefined! But save_stack_trace is exported in arch/powerpc/kernel/stacktrace.c I couldn't figure it out until I noticed these earlier warnings: arch/powerpc/kernel/stacktrace.c:47: warning: data definition has no type or storage class arch/powerpc/kernel/stacktrace.c:47: warning: type defaults to 'int' in declaration of 'EXPORT_SYMBOL_GPL' arch/powerpc/kernel/stacktrace.c:47: warning: parameter names (without types) in function declaration I applied the patch below. Signed-off-by: Stephen Rothwell Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Signed-off-by: Ingo Molnar diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index 9861f17..3cf0d94 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -12,6 +12,7 @@ #include #include +#include #include /* -- cgit v0.10.2 From ae8547b0a9e5d718ce272ddc48f91703a0f52a0b Mon Sep 17 00:00:00 2001 From: Hans Reiser Date: Wed, 7 May 2008 15:48:57 +0300 Subject: VFS: move inode_lock into sync_sb_inodes This patch makes 'sync_sb_inodes()' lock 'inode_lock', rather than expect that the caller will do this. This change was previously done by Hans Reiser and sat in the -mm tree. Signed-off-by: Artem Bityutskiy diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ae45f77..16519fe 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -424,8 +424,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) * WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so * that it can be located for waiting on in __writeback_single_inode(). * - * Called under inode_lock. - * * If `bdi' is non-zero then we're being asked to writeback a specific queue. * This function assumes that the blockdev superblock's inodes are backed by * a variety of queues, so all inodes are searched. For other superblocks, @@ -446,6 +444,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) { const unsigned long start = jiffies; /* livelock avoidance */ + spin_lock(&inode_lock); if (!wbc->for_kupdate || list_empty(&sb->s_io)) queue_io(sb, wbc->older_than_this); @@ -524,6 +523,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (!list_empty(&sb->s_more_io)) wbc->more_io = 1; } + spin_unlock(&inode_lock); return; /* Leave any unwritten inodes on s_io */ } @@ -565,11 +565,8 @@ restart: * be unmounted by the time it is released. */ if (down_read_trylock(&sb->s_umount)) { - if (sb->s_root) { - spin_lock(&inode_lock); + if (sb->s_root) sync_sb_inodes(sb, wbc); - spin_unlock(&inode_lock); - } up_read(&sb->s_umount); } spin_lock(&sb_lock); @@ -607,9 +604,7 @@ void sync_inodes_sb(struct super_block *sb, int wait) (inodes_stat.nr_inodes - inodes_stat.nr_unused) + nr_dirty + nr_unstable; wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */ - spin_lock(&inode_lock); sync_sb_inodes(sb, &wbc); - spin_unlock(&inode_lock); } /* -- cgit v0.10.2 From 4ee6afd34409d296782a5b667d7991b1050e910a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 7 May 2008 21:01:30 +0300 Subject: VFS: export sync_sb_inodes This patch exports the 'sync_sb_inodes()' which is needed for UBIFS because it has to force write-back from time to time. Namely, the UBIFS budgeting subsystem forces write-back when its pessimistic callculations show that there is no free space on the media. Signed-off-by: Artem Bityutskiy diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 16519fe..25adfc3 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -439,8 +439,8 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) * on the writer throttling path, and we get decent balancing between many * throttled threads: we don't want them all piling up on inode_sync_wait. */ -static void -sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) +void generic_sync_sb_inodes(struct super_block *sb, + struct writeback_control *wbc) { const unsigned long start = jiffies; /* livelock avoidance */ @@ -526,6 +526,13 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) spin_unlock(&inode_lock); return; /* Leave any unwritten inodes on s_io */ } +EXPORT_SYMBOL_GPL(generic_sync_sb_inodes); + +static void sync_sb_inodes(struct super_block *sb, + struct writeback_control *wbc) +{ + generic_sync_sb_inodes(sb, wbc); +} /* * Start writeback of dirty pagecache data against all unlocked inodes. diff --git a/include/linux/fs.h b/include/linux/fs.h index d8e2762..f9d2aab 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1729,6 +1729,8 @@ static inline void invalidate_remote_inode(struct inode *inode) extern int invalidate_inode_pages2(struct address_space *mapping); extern int invalidate_inode_pages2_range(struct address_space *mapping, pgoff_t start, pgoff_t end); +extern void generic_sync_sb_inodes(struct super_block *sb, + struct writeback_control *wbc); extern int write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); extern int filemap_flush(struct address_space *); -- cgit v0.10.2 From 2d62f488585405bc9108c47cb06957397cfd1059 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jan 2008 17:25:00 +0200 Subject: do_mounts: allow UBI root device name Similarly to MTD devices, allow UBI devices. Signed-off-by: Adrian Hunter diff --git a/init/do_mounts.c b/init/do_mounts.c index 660c1e5..a1de1bf 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -372,7 +372,8 @@ void __init prepare_namespace(void) if (saved_root_name[0]) { root_device_name = saved_root_name; - if (!strncmp(root_device_name, "mtd", 3)) { + if (!strncmp(root_device_name, "mtd", 3) || + !strncmp(root_device_name, "ubi", 3)) { mount_block_root(root_device_name, root_mountflags); goto out; } -- cgit v0.10.2 From 3bf2e77453a87c22eb57ed4926760ac131c84459 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 13 Jul 2008 21:18:02 -0700 Subject: x86, suspend, acpi: enter Big Real Mode The explanation for recent video BIOS suspend quirk failures is that the VESA BIOS expects to be entered in Big Real Mode (*.limit = 0xffffffff) instead of ordinary Real Mode (*.limit = 0xffff). This patch changes the segment descriptors to Big Real Mode instead. The segment descriptor registers (what Intel calls "segment cache") is always active. The only thing that changes based on CR0.PE is how it is *loaded* and the interpretation of the CS flags. The segment descriptor registers contain of the following sub-registers: selector (the "visible" part), base, limit and flags. In protected mode or long mode, they are loaded from descriptors (or fs.base or gs.base can be manipulated directly in long mode.) In real mode, the only thing changed by a segment register load is the selector and the base, where the base <- selector << 4. In particular, *the limit and the flags are not changed*. As far as the handling of the CS flags: a code segment cannot be writable in protected mode, whereas it is "just another segment" in real mode, so there is some kind of quirk that kicks in for this when CR0.PE <- 0. I'm not sure if this is accomplished by actually changing the cs.flags register or just changing the interpretation; it might be something that is CPU-specific. In particular, the Transmeta CPUs had an explicit "CS is writable if you're in real mode" override, so even if you had loaded CS with an execute-only segment it'd be writable (but not readable!) on return to real mode. I'm not at all sure if that is how other CPUs behave. Signed-off-by: "H. Peter Anvin" Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 36af01f..130711f 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -23,6 +23,15 @@ static unsigned long acpi_realmode; static char temp_stack[10240]; #endif +/* XXX: this macro should move to asm-x86/segment.h and be shared with the + boot code... */ +#define GDT_ENTRY(flags, base, limit) \ + (((u64)(base & 0xff000000) << 32) | \ + ((u64)flags << 40) | \ + ((u64)(limit & 0x00ff0000) << 32) | \ + ((u64)(base & 0x00ffffff) << 16) | \ + ((u64)(limit & 0x0000ffff))) + /** * acpi_save_state_mem - save kernel state * @@ -58,11 +67,11 @@ int acpi_save_state_mem(void) ((char *)&header->wakeup_gdt - (char *)acpi_realmode)) << 16); /* GDT[1]: real-mode-like code segment */ - header->wakeup_gdt[1] = (0x009bULL << 40) + - ((u64)acpi_wakeup_address << 16) + 0xffff; + header->wakeup_gdt[1] = + GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff); /* GDT[2]: real-mode-like data segment */ - header->wakeup_gdt[2] = (0x0093ULL << 40) + - ((u64)acpi_wakeup_address << 16) + 0xffff; + header->wakeup_gdt[2] = + GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff); #ifndef CONFIG_64BIT store_gdt((struct desc_ptr *)&header->pmode_gdt); -- cgit v0.10.2 From 065cb3dfe24978651caedfa54da585388ad15dde Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 14 Jul 2008 11:44:26 -0700 Subject: x86, suspend, acpi: correct and add comments about Big Real Mode Explain that we set up the descriptors for Big Real Mode, and why we do so. In particular, one system that is known to fail without it is the Lenovo X61. Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 130711f..41bb130 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -60,16 +60,25 @@ int acpi_save_state_mem(void) header->video_mode = saved_video_mode; header->wakeup_jmp_seg = acpi_wakeup_address >> 4; + + /* + * Set up the wakeup GDT. We set these up as Big Real Mode, + * that is, with limits set to 4 GB. At least the Lenovo + * Thinkpad X61 is known to need this for the video BIOS + * initialization quirk to work; this is likely to also + * be the case for other laptops or integrated video devices. + */ + /* GDT[0]: GDT self-pointer */ header->wakeup_gdt[0] = (u64)(sizeof(header->wakeup_gdt) - 1) + ((u64)(acpi_wakeup_address + ((char *)&header->wakeup_gdt - (char *)acpi_realmode)) << 16); - /* GDT[1]: real-mode-like code segment */ + /* GDT[1]: big real mode-like code segment */ header->wakeup_gdt[1] = GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff); - /* GDT[2]: real-mode-like data segment */ + /* GDT[2]: big real mode-like data segment */ header->wakeup_gdt[2] = GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff); -- cgit v0.10.2 From 7daf705f362e349983e92037a198b8821db198af Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 14 Jul 2008 12:12:53 -0700 Subject: Start using the new '%pS' infrastructure to print symbols This simplifies the code significantly, and was the whole point of the exercise. Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index adff76e..f1a95d1 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -104,30 +104,7 @@ int kstack_depth_to_print = 12; void printk_address(unsigned long address, int reliable) { -#ifdef CONFIG_KALLSYMS - unsigned long offset = 0, symsize; - const char *symname; - char *modname; - char *delim = ":"; - char namebuf[KSYM_NAME_LEN]; - char reliab[4] = ""; - - symname = kallsyms_lookup(address, &symsize, &offset, - &modname, namebuf); - if (!symname) { - printk(" [<%016lx>]\n", address); - return; - } - if (!reliable) - strcpy(reliab, "? "); - - if (!modname) - modname = delim = ""; - printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n", - address, reliab, delim, modname, delim, symname, offset, symsize); -#else - printk(" [<%016lx>]\n", address); -#endif + printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address); } static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, diff --git a/mm/slub.c b/mm/slub.c index 315c392..5f6e2c4 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -431,9 +431,8 @@ static void print_track(const char *s, struct track *t) if (!t->addr) return; - printk(KERN_ERR "INFO: %s in ", s); - __print_symbol("%s", (unsigned long)t->addr); - printk(" age=%lu cpu=%u pid=%d\n", jiffies - t->when, t->cpu, t->pid); + printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n", + s, t->addr, jiffies - t->when, t->cpu, t->pid); } static void print_tracking(struct kmem_cache *s, void *object) -- cgit v0.10.2 From 341c2c958ec7bdd9f54733a8b0b432fe76842a82 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:51 +0900 Subject: libata: consistently use msecs for time durations libata has been using mix of jiffies and msecs for time druations. This is getting confusing. As writing sub HZ values in jiffies is PITA and msecs_to_jiffies() can't be used as initializer, unify unit for all time durations to msecs. So, durations are in msecs and deadlines are in jiffies. ata_deadline() is added to compute deadline from a start time and duration in msecs. While at it, drop now superflous _msec suffix from arguments and rename @timeout to @deadline if it represents a fixed point in time rather than duration. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 303fc0d..c5c3b1b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include @@ -145,7 +144,7 @@ static int libata_dma_mask = ATA_DMA_MASK_ATA|ATA_DMA_MASK_ATAPI|ATA_DMA_MASK_CF module_param_named(dma, libata_dma_mask, int, 0444); MODULE_PARM_DESC(dma, "DMA enable/disable (0x1==ATA, 0x2==ATAPI, 0x4==CF)"); -static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; +static int ata_probe_timeout = ATA_TMOUT_INTERNAL / 1000; module_param(ata_probe_timeout, int, 0444); MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); @@ -1533,7 +1532,7 @@ unsigned long ata_id_xfermask(const u16 *id) * @ap: The ata_port to queue port_task for * @fn: workqueue function to be scheduled * @data: data for @fn to use - * @delay: delay time for workqueue function + * @delay: delay time in msecs for workqueue function * * Schedule @fn(@data) for execution after @delay jiffies using * port_task. There is one port_task per port and it's the @@ -1552,7 +1551,7 @@ void ata_pio_queue_task(struct ata_port *ap, void *data, unsigned long delay) ap->port_task_data = data; /* may fail if ata_port_flush_task() in progress */ - queue_delayed_work(ata_wq, &ap->port_task, delay); + queue_delayed_work(ata_wq, &ap->port_task, msecs_to_jiffies(delay)); } /** @@ -1685,7 +1684,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, spin_unlock_irqrestore(ap->lock, flags); if (!timeout) - timeout = ata_probe_timeout * 1000 / HZ; + timeout = ata_probe_timeout * 1000; rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout)); @@ -3319,7 +3318,7 @@ int ata_wait_ready(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)) { unsigned long start = jiffies; - unsigned long nodev_deadline = start + ATA_TMOUT_FF_WAIT; + unsigned long nodev_deadline = ata_deadline(start, ATA_TMOUT_FF_WAIT); int warned = 0; if (time_after(nodev_deadline, deadline)) @@ -3387,7 +3386,7 @@ int ata_wait_ready(struct ata_link *link, unsigned long deadline, int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int (*check_ready)(struct ata_link *link)) { - msleep(ATA_WAIT_AFTER_RESET_MSECS); + msleep(ATA_WAIT_AFTER_RESET); return ata_wait_ready(link, deadline, check_ready); } @@ -3417,13 +3416,13 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, int sata_link_debounce(struct ata_link *link, const unsigned long *params, unsigned long deadline) { - unsigned long interval_msec = params[0]; - unsigned long duration = msecs_to_jiffies(params[1]); + unsigned long interval = params[0]; + unsigned long duration = params[1]; unsigned long last_jiffies, t; u32 last, cur; int rc; - t = jiffies + msecs_to_jiffies(params[2]); + t = ata_deadline(jiffies, params[2]); if (time_before(t, deadline)) deadline = t; @@ -3435,7 +3434,7 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, last_jiffies = jiffies; while (1) { - msleep(interval_msec); + msleep(interval); if ((rc = sata_scr_read(link, SCR_STATUS, &cur))) return rc; cur &= 0xf; @@ -3444,7 +3443,8 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params, if (cur == last) { if (cur == 1 && time_before(jiffies, deadline)) continue; - if (time_after(jiffies, last_jiffies + duration)) + if (time_after(jiffies, + ata_deadline(last_jiffies, duration))) return 0; continue; } @@ -3636,7 +3636,8 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, if (check_ready) { unsigned long pmp_deadline; - pmp_deadline = jiffies + ATA_TMOUT_PMP_SRST_WAIT; + pmp_deadline = ata_deadline(jiffies, + ATA_TMOUT_PMP_SRST_WAIT); if (time_after(pmp_deadline, deadline)) pmp_deadline = deadline; ata_wait_ready(link, pmp_deadline, check_ready); @@ -6073,8 +6074,6 @@ static void __init ata_parse_force_param(void) static int __init ata_init(void) { - ata_probe_timeout *= HZ; - ata_parse_force_param(); ata_wq = create_workqueue("ata"); @@ -6127,8 +6126,8 @@ int ata_ratelimit(void) * @reg: IO-mapped register * @mask: Mask to apply to read register value * @val: Wait condition - * @interval_msec: polling interval in milliseconds - * @timeout_msec: timeout in milliseconds + * @interval: polling interval in milliseconds + * @timeout: timeout in milliseconds * * Waiting for some bits of register to change is a common * operation for ATA controllers. This function reads 32bit LE @@ -6146,10 +6145,9 @@ int ata_ratelimit(void) * The final register value. */ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, - unsigned long interval_msec, - unsigned long timeout_msec) + unsigned long interval, unsigned long timeout) { - unsigned long timeout; + unsigned long deadline; u32 tmp; tmp = ioread32(reg); @@ -6158,10 +6156,10 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, * preceding writes reach the controller before starting to * eat away the timeout. */ - timeout = jiffies + (timeout_msec * HZ) / 1000; + deadline = ata_deadline(jiffies, timeout); - while ((tmp & mask) == val && time_before(jiffies, timeout)) { - msleep(interval_msec); + while ((tmp & mask) == val && time_before(jiffies, deadline)) { + msleep(interval); tmp = ioread32(reg); } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7894d83..08dd07f 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -66,15 +66,14 @@ enum { ATA_ECAT_DUBIOUS_TOUT_HSM = 6, ATA_ECAT_DUBIOUS_UNK_DEV = 7, ATA_ECAT_NR = 8, -}; -/* Waiting in ->prereset can never be reliable. It's sometimes nice - * to wait there but it can't be depended upon; otherwise, we wouldn't - * be resetting. Just give it enough time for most drives to spin up. - */ -enum { - ATA_EH_PRERESET_TIMEOUT = 10 * HZ, - ATA_EH_FASTDRAIN_INTERVAL = 3 * HZ, + /* Waiting in ->prereset can never be reliable. It's + * sometimes nice to wait there but it can't be depended upon; + * otherwise, we wouldn't be resetting. Just give it enough + * time for most drives to spin up. + */ + ATA_EH_PRERESET_TIMEOUT = 10000, + ATA_EH_FASTDRAIN_INTERVAL = 3000, }; /* The following table determines how we sequence resets. Each entry @@ -84,10 +83,10 @@ enum { * are mostly for error handling, hotplug and retarded devices. */ static const unsigned long ata_eh_reset_timeouts[] = { - 10 * HZ, /* most drives spin up by 10sec */ - 10 * HZ, /* > 99% working drives spin up before 20sec */ - 35 * HZ, /* give > 30 secs of idleness for retarded devices */ - 5 * HZ, /* and sweet one last chance */ + 10000, /* most drives spin up by 10sec */ + 10000, /* > 99% working drives spin up before 20sec */ + 35000, /* give > 30 secs of idleness for retarded devices */ + 5000, /* and sweet one last chance */ /* > 1 min has elapsed, give up */ }; @@ -641,7 +640,7 @@ void ata_eh_fastdrain_timerfn(unsigned long arg) /* some qcs have finished, give it another chance */ ap->fastdrain_cnt = cnt; ap->fastdrain_timer.expires = - jiffies + ATA_EH_FASTDRAIN_INTERVAL; + ata_deadline(jiffies, ATA_EH_FASTDRAIN_INTERVAL); add_timer(&ap->fastdrain_timer); } @@ -681,7 +680,8 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) /* activate fast drain */ ap->fastdrain_cnt = cnt; - ap->fastdrain_timer.expires = jiffies + ATA_EH_FASTDRAIN_INTERVAL; + ap->fastdrain_timer.expires = + ata_deadline(jiffies, ATA_EH_FASTDRAIN_INTERVAL); add_timer(&ap->fastdrain_timer); } @@ -2125,7 +2125,8 @@ int ata_eh_reset(struct ata_link *link, int classify, } if (prereset) { - rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT); + rc = prereset(link, + ata_deadline(jiffies, ATA_EH_PRERESET_TIMEOUT)); if (rc) { if (rc == -ENOENT) { ata_link_printk(link, KERN_DEBUG, @@ -2160,7 +2161,7 @@ int ata_eh_reset(struct ata_link *link, int classify, if (ata_is_host_link(link)) ata_eh_freeze_port(ap); - deadline = jiffies + ata_eh_reset_timeouts[try++]; + deadline = ata_deadline(jiffies, ata_eh_reset_timeouts[try++]); if (reset) { if (verbose) diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 7daf4c0..63691d7 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -785,7 +785,8 @@ static int sata_pmp_eh_handle_disabled_links(struct ata_port *ap) * SError.N working. */ sata_link_hardreset(link, sata_deb_timing_normal, - jiffies + ATA_TMOUT_INTERNAL_QUICK, NULL, NULL); + ata_deadline(jiffies, ATA_TMOUT_INTERNAL_QUICK), + NULL, NULL); /* unconditionally clear SError.N */ rc = sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c0908c2..304fdc6 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -345,8 +345,8 @@ void ata_sff_dma_pause(struct ata_port *ap) /** * ata_sff_busy_sleep - sleep until BSY clears, or timeout * @ap: port containing status register to be polled - * @tmout_pat: impatience timeout - * @tmout: overall timeout + * @tmout_pat: impatience timeout in msecs + * @tmout: overall timeout in msecs * * Sleep until ATA Status register bit BSY clears, * or a timeout occurs. @@ -365,7 +365,7 @@ int ata_sff_busy_sleep(struct ata_port *ap, status = ata_sff_busy_wait(ap, ATA_BUSY, 300); timer_start = jiffies; - timeout = timer_start + tmout_pat; + timeout = ata_deadline(timer_start, tmout_pat); while (status != 0xff && (status & ATA_BUSY) && time_before(jiffies, timeout)) { msleep(50); @@ -377,7 +377,7 @@ int ata_sff_busy_sleep(struct ata_port *ap, "port is slow to respond, please be patient " "(Status 0x%x)\n", status); - timeout = timer_start + tmout; + timeout = ata_deadline(timer_start, tmout); while (status != 0xff && (status & ATA_BUSY) && time_before(jiffies, timeout)) { msleep(50); @@ -390,7 +390,7 @@ int ata_sff_busy_sleep(struct ata_port *ap, if (status & ATA_BUSY) { ata_port_printk(ap, KERN_ERR, "port failed to respond " "(%lu secs, Status 0x%x)\n", - tmout / HZ, status); + DIV_ROUND_UP(tmout, 1000), status); return -EBUSY; } @@ -1888,7 +1888,7 @@ int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask, unsigned int dev1 = devmask & (1 << 1); int rc, ret = 0; - msleep(ATA_WAIT_AFTER_RESET_MSECS); + msleep(ATA_WAIT_AFTER_RESET); /* always check readiness of the master device */ rc = ata_sff_wait_ready(link, deadline); @@ -2371,7 +2371,8 @@ void ata_bus_reset(struct ata_port *ap) /* issue bus reset */ if (ap->flags & ATA_FLAG_SRST) { - rc = ata_bus_softreset(ap, devmask, jiffies + 40 * HZ); + rc = ata_bus_softreset(ap, devmask, + ata_deadline(jiffies, 40000)); if (rc && rc != -ENODEV) goto err_out; } diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 5551610..d393290 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1011,7 +1011,7 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask) void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; unsigned int dev0 = devmask & (1 << 0); unsigned int dev1 = devmask & (1 << 1); - unsigned long timeout; + unsigned long deadline; /* if device 0 was found in ata_devchk, wait for its * BSY bit to clear @@ -1022,7 +1022,7 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask) /* if device 1 was found in ata_devchk, wait for * register access, then wait for BSY to clear */ - timeout = jiffies + ATA_TMOUT_BOOT; + deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT); while (dev1) { u8 nsect, lbal; @@ -1031,7 +1031,7 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask) lbal = read_atapi_register(base, ATA_REG_LBAL); if ((nsect == 1) && (lbal == 1)) break; - if (time_after(jiffies, timeout)) { + if (time_after(jiffies, deadline)) { dev1 = 0; break; } diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index bbf5aa3..16673d1 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -696,7 +696,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) if (reg & INTSTS_BMSINT) { unsigned int classes; - unsigned long deadline = jiffies + ATA_TMOUT_BOOT; + unsigned long deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT); printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); /* TBD: SW reset */ diff --git a/include/linux/libata.h b/include/linux/libata.h index e57e5d0..94110b6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -27,6 +27,7 @@ #define __LINUX_LIBATA_H__ #include +#include #include #include #include @@ -115,7 +116,7 @@ enum { /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ ATA_MAX_QUEUE = 32, ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, - ATA_SHORT_PAUSE = (HZ >> 6) + 1, + ATA_SHORT_PAUSE = 16, ATAPI_MAX_DRAIN = 16 << 10, @@ -234,17 +235,17 @@ enum { /* bits 24:31 of host->flags are reserved for LLD specific flags */ /* various lengths of time */ - ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */ - ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */ - ATA_TMOUT_INTERNAL = 30 * HZ, - ATA_TMOUT_INTERNAL_QUICK = 5 * HZ, + ATA_TMOUT_BOOT = 30000, /* heuristic */ + ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */ + ATA_TMOUT_INTERNAL = 30000, + ATA_TMOUT_INTERNAL_QUICK = 5000, /* FIXME: GoVault needs 2s but we can't afford that without * parallel probing. 800ms is enough for iVDR disk * HHD424020F7SV00. Increase to 2secs when parallel probing * is in place. */ - ATA_TMOUT_FF_WAIT = 4 * HZ / 5, + ATA_TMOUT_FF_WAIT = 800, /* Spec mandates to wait for ">= 2ms" before checking status * after reset. We wait 150ms, because that was the magic @@ -256,14 +257,14 @@ enum { * * Old drivers/ide uses the 2mS rule and then waits for ready. */ - ATA_WAIT_AFTER_RESET_MSECS = 150, + ATA_WAIT_AFTER_RESET = 150, /* If PMP is supported, we have to do follow-up SRST. As some * PMPs don't send D2H Reg FIS after hardreset, LLDs are * advised to wait only for the following duration before * doing SRST. */ - ATA_TMOUT_PMP_SRST_WAIT = 1 * HZ, + ATA_TMOUT_PMP_SRST_WAIT = 1000, /* ATA bus states */ BUS_UNKNOWN = 0, @@ -895,8 +896,7 @@ extern void ata_host_resume(struct ata_host *host); #endif extern int ata_ratelimit(void); extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, - unsigned long interval_msec, - unsigned long timeout_msec); + unsigned long interval, unsigned long timeout); extern int atapi_cmd_type(u8 opcode); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); @@ -1389,6 +1389,12 @@ static inline int ata_check_ready(u8 status) return 0; } +static inline unsigned long ata_deadline(unsigned long from_jiffies, + unsigned long timeout_msecs) +{ + return from_jiffies + msecs_to_jiffies(timeout_msecs); +} + /************************************************************************** * PMP - drivers/ata/libata-pmp.c -- cgit v0.10.2 From 0a2c0f56159999e20015241d3b8fa89b1ab14309 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:52 +0900 Subject: libata: improve EH retry delay handling EH retries were delayed by 5 seconds to ensure that resets don't occur back-to-back. However, this 5 second delay is superflous or excessive in many cases. For example, after IDENTIFY times out, there's no reason to wait five more seconds before retrying. This patch adds ehc->last_reset timestamp and record the timestamp for the last reset trial or success and uses it to space resets by ATA_EH_RESET_COOL_DOWN which is 5 secs and removes unconditional 5 sec sleeps. As this change makes inter-try waits often shorter and they're redundant in nature, this patch also removes the "retrying..." messages. While at it, convert explicit rounding up division to DIV_ROUND_UP(). This change speeds up EH in many cases w/o sacrificing robustness. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 08dd07f..5b5ae63 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -67,6 +67,9 @@ enum { ATA_ECAT_DUBIOUS_UNK_DEV = 7, ATA_ECAT_NR = 8, + /* always put at least this amount of time between resets */ + ATA_EH_RESET_COOL_DOWN = 5000, + /* Waiting in ->prereset can never be reliable. It's * sometimes nice to wait there but it can't be depended upon; * otherwise, we wouldn't be resetting. Just give it enough @@ -485,6 +488,9 @@ void ata_scsi_error(struct Scsi_Host *host) if (ata_ncq_enabled(dev)) ehc->saved_ncq_enabled |= 1 << devno; } + + /* set last reset timestamp to some time in the past */ + ehc->last_reset = jiffies - 60 * HZ; } ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; @@ -2088,11 +2094,17 @@ int ata_eh_reset(struct ata_link *link, int classify, /* * Prepare to reset */ + now = jiffies; + deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); + if (time_before(now, deadline)) + schedule_timeout_uninterruptible(deadline - now); + spin_lock_irqsave(ap->lock, flags); ap->pflags |= ATA_PFLAG_RESETTING; spin_unlock_irqrestore(ap->lock, flags); ata_eh_about_to_do(link, NULL, ATA_EH_RESET); + ehc->last_reset = jiffies; ata_link_for_each_dev(dev, link) { /* If we issue an SRST then an ATA drive (not ATAPI) @@ -2158,6 +2170,7 @@ int ata_eh_reset(struct ata_link *link, int classify, /* * Perform reset */ + ehc->last_reset = jiffies; if (ata_is_host_link(link)) ata_eh_freeze_port(ap); @@ -2278,6 +2291,7 @@ int ata_eh_reset(struct ata_link *link, int classify, /* reset successful, schedule revalidation */ ata_eh_done(link, NULL, ATA_EH_RESET); + ehc->last_reset = jiffies; ehc->i.action |= ATA_EH_REVALIDATE; rc = 0; @@ -2304,9 +2318,9 @@ int ata_eh_reset(struct ata_link *link, int classify, if (time_before(now, deadline)) { unsigned long delta = deadline - now; - ata_link_printk(link, KERN_WARNING, "reset failed " - "(errno=%d), retrying in %u secs\n", - rc, (jiffies_to_msecs(delta) + 999) / 1000); + ata_link_printk(link, KERN_WARNING, + "reset failed (errno=%d), retrying in %u secs\n", + rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000)); while (delta) delta = schedule_timeout_uninterruptible(delta); @@ -2623,7 +2637,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, { struct ata_link *link; struct ata_device *dev; - int nr_failed_devs, nr_disabled_devs; + int nr_failed_devs; int rc; unsigned long flags; @@ -2666,7 +2680,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, retry: rc = 0; nr_failed_devs = 0; - nr_disabled_devs = 0; /* if UNLOADING, finish immediately */ if (ap->pflags & ATA_PFLAG_UNLOADING) @@ -2733,8 +2746,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, dev_fail: nr_failed_devs++; - if (ata_eh_handle_dev_fail(dev, rc)) - nr_disabled_devs++; + ata_eh_handle_dev_fail(dev, rc); if (ap->pflags & ATA_PFLAG_FROZEN) { /* PMP reset requires working host port. @@ -2746,18 +2758,8 @@ dev_fail: } } - if (nr_failed_devs) { - if (nr_failed_devs != nr_disabled_devs) { - ata_port_printk(ap, KERN_WARNING, "failed to recover " - "some devices, retrying in 5 secs\n"); - ssleep(5); - } else { - /* no device left to recover, repeat fast */ - msleep(500); - } - + if (nr_failed_devs) goto retry; - } out: if (rc && r_failed_link) diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 63691d7..b65db30 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -727,19 +727,12 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, } if (tries) { - int sleep = ehc->i.flags & ATA_EHI_DID_RESET; - /* consecutive revalidation failures? speed down */ if (reval_failed) sata_down_spd_limit(link); else reval_failed = 1; - ata_dev_printk(dev, KERN_WARNING, - "retrying reset%s\n", - sleep ? " in 5 secs" : ""); - if (sleep) - ssleep(5); ehc->i.action |= ATA_EH_RESET; goto retry; } else { @@ -991,10 +984,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap) goto retry; if (--pmp_tries) { - ata_port_printk(ap, KERN_WARNING, - "failed to recover PMP, retrying in 5 secs\n"); pmp_ehc->i.action |= ATA_EH_RESET; - ssleep(5); goto retry; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 94110b6..9058c2a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -602,6 +602,8 @@ struct ata_eh_context { unsigned int did_probe_mask; unsigned int saved_ncq_enabled; u8 saved_xfer_mode[ATA_MAX_DEVICES]; + /* timestamp for the last reset attempt or success */ + unsigned long last_reset; }; struct ata_acpi_drive -- cgit v0.10.2 From d8af0eb6046c56e7238171ca420622541db24926 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:53 +0900 Subject: libata: use ULONG_MAX to terminate reset timeout table This doesn't introduce any functional changes. This is to make reset timeout table consistent with to-be-added command timeout tables. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5b5ae63..83d1451 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -90,7 +90,7 @@ static const unsigned long ata_eh_reset_timeouts[] = { 10000, /* > 99% working drives spin up before 20sec */ 35000, /* give > 30 secs of idleness for retarded devices */ 5000, /* and sweet one last chance */ - /* > 1 min has elapsed, give up */ + ULONG_MAX, /* > 1 min has elapsed, give up */ }; static void __ata_port_freeze(struct ata_port *ap); @@ -2077,13 +2077,12 @@ int ata_eh_reset(struct ata_link *link, int classify, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) { - const int max_tries = ARRAY_SIZE(ata_eh_reset_timeouts); struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &link->eh_context; unsigned int *classes = ehc->classes; unsigned int lflags = link->flags; int verbose = !(ehc->i.flags & ATA_EHI_QUIET); - int try = 0; + int max_tries = 0, try = 0; struct ata_device *dev; unsigned long deadline, now; ata_reset_fn_t reset; @@ -2094,6 +2093,9 @@ int ata_eh_reset(struct ata_link *link, int classify, /* * Prepare to reset */ + while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX) + max_tries++; + now = jiffies; deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); if (time_before(now, deadline)) -- cgit v0.10.2 From 87fbc5a060faf2394bee88a93519f9b9d434727c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 May 2008 02:17:54 +0900 Subject: libata: improve EH internal command timeout handling ATA_TMOUT_INTERNAL which was 30secs were used for all internal commands which is way too long when something goes wrong. This patch implements command type based stepped timeouts. Different command types can use different timeouts and each command type can use different timeout values after timeouts. ie. the initial timeout is set to a value which should cover most of the cases but not too long so that run away cases don't delay things too much. After the first try times out, the second try can use longer timeout and if that one times out too, it can go for full 30sec timeout. IDENTIFYs use 5s - 10s - 30s timeout and all other commands use 5s - 10s timeouts. This patch significantly cuts down the needed time to handle failure cases while still allowing libata to work with nut job devices through retries. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c5c3b1b..9bef1a8 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -144,7 +144,7 @@ static int libata_dma_mask = ATA_DMA_MASK_ATA|ATA_DMA_MASK_ATAPI|ATA_DMA_MASK_CF module_param_named(dma, libata_dma_mask, int, 0444); MODULE_PARM_DESC(dma, "DMA enable/disable (0x1==ATA, 0x2==ATAPI, 0x4==CF)"); -static int ata_probe_timeout = ATA_TMOUT_INTERNAL / 1000; +static int ata_probe_timeout; module_param(ata_probe_timeout, int, 0444); MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); @@ -1611,6 +1611,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, struct ata_link *link = dev->link; struct ata_port *ap = link->ap; u8 command = tf->command; + int auto_timeout = 0; struct ata_queued_cmd *qc; unsigned int tag, preempted_tag; u32 preempted_sactive, preempted_qc_active; @@ -1683,8 +1684,14 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, spin_unlock_irqrestore(ap->lock, flags); - if (!timeout) - timeout = ata_probe_timeout * 1000; + if (!timeout) { + if (ata_probe_timeout) + timeout = ata_probe_timeout * 1000; + else { + timeout = ata_internal_cmd_timeout(dev, command); + auto_timeout = 1; + } + } rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout)); @@ -1760,6 +1767,9 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, spin_unlock_irqrestore(ap->lock, flags); + if ((err_mask & AC_ERR_TIMEOUT) && auto_timeout) + ata_internal_cmd_timed_out(dev, command); + return err_mask; } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 83d1451..d5f03a6 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -67,6 +67,8 @@ enum { ATA_ECAT_DUBIOUS_UNK_DEV = 7, ATA_ECAT_NR = 8, + ATA_EH_CMD_DFL_TIMEOUT = 5000, + /* always put at least this amount of time between resets */ ATA_EH_RESET_COOL_DOWN = 5000, @@ -93,6 +95,53 @@ static const unsigned long ata_eh_reset_timeouts[] = { ULONG_MAX, /* > 1 min has elapsed, give up */ }; +static const unsigned long ata_eh_identify_timeouts[] = { + 5000, /* covers > 99% of successes and not too boring on failures */ + 10000, /* combined time till here is enough even for media access */ + 30000, /* for true idiots */ + ULONG_MAX, +}; + +static const unsigned long ata_eh_other_timeouts[] = { + 5000, /* same rationale as identify timeout */ + 10000, /* ditto */ + /* but no merciful 30sec for other commands, it just isn't worth it */ + ULONG_MAX, +}; + +struct ata_eh_cmd_timeout_ent { + const u8 *commands; + const unsigned long *timeouts; +}; + +/* The following table determines timeouts to use for EH internal + * commands. Each table entry is a command class and matches the + * commands the entry applies to and the timeout table to use. + * + * On the retry after a command timed out, the next timeout value from + * the table is used. If the table doesn't contain further entries, + * the last value is used. + * + * ehc->cmd_timeout_idx keeps track of which timeout to use per + * command class, so if SET_FEATURES times out on the first try, the + * next try will use the second timeout value only for that class. + */ +#define CMDS(cmds...) (const u8 []){ cmds, 0 } +static const struct ata_eh_cmd_timeout_ent +ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { + { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), + .timeouts = ata_eh_identify_timeouts, }, + { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), + .timeouts = ata_eh_other_timeouts, }, + { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), + .timeouts = ata_eh_other_timeouts, }, + { .commands = CMDS(ATA_CMD_SET_FEATURES), + .timeouts = ata_eh_other_timeouts, }, + { .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS), + .timeouts = ata_eh_other_timeouts, }, +}; +#undef CMDS + static void __ata_port_freeze(struct ata_port *ap); #ifdef CONFIG_PM static void ata_eh_handle_port_suspend(struct ata_port *ap); @@ -238,6 +287,73 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, #endif /* CONFIG_PCI */ +static int ata_lookup_timeout_table(u8 cmd) +{ + int i; + + for (i = 0; i < ATA_EH_CMD_TIMEOUT_TABLE_SIZE; i++) { + const u8 *cur; + + for (cur = ata_eh_cmd_timeout_table[i].commands; *cur; cur++) + if (*cur == cmd) + return i; + } + + return -1; +} + +/** + * ata_internal_cmd_timeout - determine timeout for an internal command + * @dev: target device + * @cmd: internal command to be issued + * + * Determine timeout for internal command @cmd for @dev. + * + * LOCKING: + * EH context. + * + * RETURNS: + * Determined timeout. + */ +unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd) +{ + struct ata_eh_context *ehc = &dev->link->eh_context; + int ent = ata_lookup_timeout_table(cmd); + int idx; + + if (ent < 0) + return ATA_EH_CMD_DFL_TIMEOUT; + + idx = ehc->cmd_timeout_idx[dev->devno][ent]; + return ata_eh_cmd_timeout_table[ent].timeouts[idx]; +} + +/** + * ata_internal_cmd_timed_out - notification for internal command timeout + * @dev: target device + * @cmd: internal command which timed out + * + * Notify EH that internal command @cmd for @dev timed out. This + * function should be called only for commands whose timeouts are + * determined using ata_internal_cmd_timeout(). + * + * LOCKING: + * EH context. + */ +void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd) +{ + struct ata_eh_context *ehc = &dev->link->eh_context; + int ent = ata_lookup_timeout_table(cmd); + int idx; + + if (ent < 0) + return; + + idx = ehc->cmd_timeout_idx[dev->devno][ent]; + if (ata_eh_cmd_timeout_table[ent].timeouts[idx + 1] != ULONG_MAX) + ehc->cmd_timeout_idx[dev->devno][ent]++; +} + static void ata_ering_record(struct ata_ering *ering, unsigned int eflags, unsigned int err_mask) { @@ -2600,8 +2716,11 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err) ata_eh_detach_dev(dev); /* schedule probe if necessary */ - if (ata_eh_schedule_probe(dev)) + if (ata_eh_schedule_probe(dev)) { ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; + memset(ehc->cmd_timeout_idx[dev->devno], 0, + sizeof(ehc->cmd_timeout_idx[dev->devno])); + } return 1; } else { diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 1cf803a..f6f9c28 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -151,6 +151,8 @@ extern void ata_scsi_dev_rescan(struct work_struct *work); extern int ata_bus_probe(struct ata_port *ap); /* libata-eh.c */ +extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd); +extern void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd); extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); extern void ata_scsi_error(struct Scsi_Host *host); extern void ata_port_wait_eh(struct ata_port *ap); diff --git a/include/linux/libata.h b/include/linux/libata.h index 9058c2a..035f8e1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -237,7 +237,6 @@ enum { /* various lengths of time */ ATA_TMOUT_BOOT = 30000, /* heuristic */ ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */ - ATA_TMOUT_INTERNAL = 30000, ATA_TMOUT_INTERNAL_QUICK = 5000, /* FIXME: GoVault needs 2s but we can't afford that without @@ -341,6 +340,11 @@ enum { SATA_PMP_RW_TIMEOUT = 3000, /* PMP read/write timeout */ + /* This should match the actual table size of + * ata_eh_cmd_timeout_table in libata-eh.c. + */ + ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 5, + /* Horkage types. May be set by libata or controller on drives (some horkage may be drive/controller pair dependant */ @@ -598,6 +602,8 @@ struct ata_eh_info { struct ata_eh_context { struct ata_eh_info i; int tries[ATA_MAX_DEVICES]; + int cmd_timeout_idx[ATA_MAX_DEVICES] + [ATA_EH_CMD_TIMEOUT_TABLE_SIZE]; unsigned int classes[ATA_MAX_DEVICES]; unsigned int did_probe_mask; unsigned int saved_ncq_enabled; -- cgit v0.10.2 From 18f7ba4c2f4be6b37d925931f04d6cc28d88d1ee Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Tue, 3 Jun 2008 10:33:55 -0700 Subject: libata/ahci: enclosure management support Add Enclosure Management support to libata and ahci. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5e6468a..65d4e96 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -56,6 +56,12 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip) static int ahci_enable_alpm(struct ata_port *ap, enum link_pm policy); static void ahci_disable_alpm(struct ata_port *ap); +static ssize_t ahci_led_show(struct ata_port *ap, char *buf); +static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, + size_t size); +static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, + ssize_t size); +#define MAX_SLOTS 8 enum { AHCI_PCI_BAR = 5, @@ -98,6 +104,8 @@ enum { HOST_IRQ_STAT = 0x08, /* interrupt status */ HOST_PORTS_IMPL = 0x0c, /* bitmap of implemented ports */ HOST_VERSION = 0x10, /* AHCI spec. version compliancy */ + HOST_EM_LOC = 0x1c, /* Enclosure Management location */ + HOST_EM_CTL = 0x20, /* Enclosure Management Control */ /* HOST_CTL bits */ HOST_RESET = (1 << 0), /* reset controller; self-clear */ @@ -105,6 +113,7 @@ enum { HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ /* HOST_CAP bits */ + HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */ HOST_CAP_SSC = (1 << 14), /* Slumber capable */ HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */ HOST_CAP_CLO = (1 << 24), /* Command List Override support */ @@ -202,6 +211,11 @@ enum { ATA_FLAG_IPM, ICH_MAP = 0x90, /* ICH MAP register */ + + /* em_ctl bits */ + EM_CTL_RST = (1 << 9), /* Reset */ + EM_CTL_TM = (1 << 8), /* Transmit Message */ + EM_CTL_ALHD = (1 << 26), /* Activity LED */ }; struct ahci_cmd_hdr { @@ -219,12 +233,21 @@ struct ahci_sg { __le32 flags_size; }; +struct ahci_em_priv { + enum sw_activity blink_policy; + struct timer_list timer; + unsigned long saved_activity; + unsigned long activity; + unsigned long led_state; +}; + struct ahci_host_priv { unsigned int flags; /* AHCI_HFLAG_* */ u32 cap; /* cap to use */ u32 port_map; /* port map to use */ u32 saved_cap; /* saved initial cap */ u32 saved_port_map; /* saved initial port_map */ + u32 em_loc; /* enclosure management location */ }; struct ahci_port_priv { @@ -240,6 +263,8 @@ struct ahci_port_priv { unsigned int ncq_saw_dmas:1; unsigned int ncq_saw_sdb:1; u32 intr_mask; /* interrupts to enable */ + struct ahci_em_priv em_priv[MAX_SLOTS];/* enclosure management info + * per PM slot */ }; static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); @@ -277,9 +302,20 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int ahci_pci_device_resume(struct pci_dev *pdev); #endif +static ssize_t ahci_activity_show(struct ata_device *dev, char *buf); +static ssize_t ahci_activity_store(struct ata_device *dev, + enum sw_activity val); +static void ahci_init_sw_activity(struct ata_link *link); static struct device_attribute *ahci_shost_attrs[] = { &dev_attr_link_power_management_policy, + &dev_attr_em_message_type, + &dev_attr_em_message, + NULL +}; + +static struct device_attribute *ahci_sdev_attrs[] = { + &dev_attr_sw_activity, NULL }; @@ -289,6 +325,7 @@ static struct scsi_host_template ahci_sht = { .sg_tablesize = AHCI_MAX_SG, .dma_boundary = AHCI_DMA_BOUNDARY, .shost_attrs = ahci_shost_attrs, + .sdev_attrs = ahci_sdev_attrs, }; static struct ata_port_operations ahci_ops = { @@ -316,6 +353,10 @@ static struct ata_port_operations ahci_ops = { .enable_pm = ahci_enable_alpm, .disable_pm = ahci_disable_alpm, + .em_show = ahci_led_show, + .em_store = ahci_led_store, + .sw_activity_show = ahci_activity_show, + .sw_activity_store = ahci_activity_store, #ifdef CONFIG_PM .port_suspend = ahci_port_suspend, .port_resume = ahci_port_resume, @@ -561,6 +602,11 @@ static struct pci_driver ahci_pci_driver = { #endif }; +static int ahci_em_messages = 1; +module_param(ahci_em_messages, int, 0444); +/* add other LED protocol types when they become supported */ +MODULE_PARM_DESC(ahci_em_messages, + "Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED"); static inline int ahci_nr_ports(u32 cap) { @@ -1031,11 +1077,28 @@ static void ahci_power_down(struct ata_port *ap) static void ahci_start_port(struct ata_port *ap) { + struct ahci_port_priv *pp = ap->private_data; + struct ata_link *link; + struct ahci_em_priv *emp; + /* enable FIS reception */ ahci_start_fis_rx(ap); /* enable DMA */ ahci_start_engine(ap); + + /* turn on LEDs */ + if (ap->flags & ATA_FLAG_EM) { + ata_port_for_each_link(link, ap) { + emp = &pp->em_priv[link->pmp]; + ahci_transmit_led_message(ap, emp->led_state, 4); + } + } + + if (ap->flags & ATA_FLAG_SW_ACTIVITY) + ata_port_for_each_link(link, ap) + ahci_init_sw_activity(link); + } static int ahci_deinit_port(struct ata_port *ap, const char **emsg) @@ -1116,6 +1179,230 @@ static int ahci_reset_controller(struct ata_host *host) return 0; } +static void ahci_sw_activity(struct ata_link *link) +{ + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_em_priv *emp = &pp->em_priv[link->pmp]; + + if (!(link->flags & ATA_LFLAG_SW_ACTIVITY)) + return; + + emp->activity++; + if (!timer_pending(&emp->timer)) + mod_timer(&emp->timer, jiffies + msecs_to_jiffies(10)); +} + +static void ahci_sw_activity_blink(unsigned long arg) +{ + struct ata_link *link = (struct ata_link *)arg; + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_em_priv *emp = &pp->em_priv[link->pmp]; + unsigned long led_message = emp->led_state; + u32 activity_led_state; + + led_message &= 0xffff0000; + led_message |= ap->port_no | (link->pmp << 8); + + /* check to see if we've had activity. If so, + * toggle state of LED and reset timer. If not, + * turn LED to desired idle state. + */ + if (emp->saved_activity != emp->activity) { + emp->saved_activity = emp->activity; + /* get the current LED state */ + activity_led_state = led_message & 0x00010000; + + if (activity_led_state) + activity_led_state = 0; + else + activity_led_state = 1; + + /* clear old state */ + led_message &= 0xfff8ffff; + + /* toggle state */ + led_message |= (activity_led_state << 16); + mod_timer(&emp->timer, jiffies + msecs_to_jiffies(100)); + } else { + /* switch to idle */ + led_message &= 0xfff8ffff; + if (emp->blink_policy == BLINK_OFF) + led_message |= (1 << 16); + } + ahci_transmit_led_message(ap, led_message, 4); +} + +static void ahci_init_sw_activity(struct ata_link *link) +{ + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_em_priv *emp = &pp->em_priv[link->pmp]; + + /* init activity stats, setup timer */ + emp->saved_activity = emp->activity = 0; + setup_timer(&emp->timer, ahci_sw_activity_blink, (unsigned long)link); + + /* check our blink policy and set flag for link if it's enabled */ + if (emp->blink_policy) + link->flags |= ATA_LFLAG_SW_ACTIVITY; +} + +static int ahci_reset_em(struct ata_host *host) +{ + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; + u32 em_ctl; + + em_ctl = readl(mmio + HOST_EM_CTL); + if ((em_ctl & EM_CTL_TM) || (em_ctl & EM_CTL_RST)) + return -EINVAL; + + writel(em_ctl | EM_CTL_RST, mmio + HOST_EM_CTL); + return 0; +} + +static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, + ssize_t size) +{ + struct ahci_host_priv *hpriv = ap->host->private_data; + struct ahci_port_priv *pp = ap->private_data; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; + u32 em_ctl; + u32 message[] = {0, 0}; + unsigned int flags; + int pmp; + struct ahci_em_priv *emp; + + /* get the slot number from the message */ + pmp = (state & 0x0000ff00) >> 8; + if (pmp < MAX_SLOTS) + emp = &pp->em_priv[pmp]; + else + return -EINVAL; + + spin_lock_irqsave(ap->lock, flags); + + /* + * if we are still busy transmitting a previous message, + * do not allow + */ + em_ctl = readl(mmio + HOST_EM_CTL); + if (em_ctl & EM_CTL_TM) { + spin_unlock_irqrestore(ap->lock, flags); + return -EINVAL; + } + + /* + * create message header - this is all zero except for + * the message size, which is 4 bytes. + */ + message[0] |= (4 << 8); + + /* ignore 0:4 of byte zero, fill in port info yourself */ + message[1] = ((state & 0xfffffff0) | ap->port_no); + + /* write message to EM_LOC */ + writel(message[0], mmio + hpriv->em_loc); + writel(message[1], mmio + hpriv->em_loc+4); + + /* save off new led state for port/slot */ + emp->led_state = message[1]; + + /* + * tell hardware to transmit the message + */ + writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL); + + spin_unlock_irqrestore(ap->lock, flags); + return size; +} + +static ssize_t ahci_led_show(struct ata_port *ap, char *buf) +{ + struct ahci_port_priv *pp = ap->private_data; + struct ata_link *link; + struct ahci_em_priv *emp; + int rc = 0; + + ata_port_for_each_link(link, ap) { + emp = &pp->em_priv[link->pmp]; + rc += sprintf(buf, "%lx\n", emp->led_state); + } + return rc; +} + +static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, + size_t size) +{ + int state; + int pmp; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_em_priv *emp; + + state = simple_strtoul(buf, NULL, 0); + + /* get the slot number from the message */ + pmp = (state & 0x0000ff00) >> 8; + if (pmp < MAX_SLOTS) + emp = &pp->em_priv[pmp]; + else + return -EINVAL; + + /* mask off the activity bits if we are in sw_activity + * mode, user should turn off sw_activity before setting + * activity led through em_message + */ + if (emp->blink_policy) + state &= 0xfff8ffff; + + return ahci_transmit_led_message(ap, state, size); +} + +static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val) +{ + struct ata_link *link = dev->link; + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_em_priv *emp = &pp->em_priv[link->pmp]; + u32 port_led_state = emp->led_state; + + /* save the desired Activity LED behavior */ + if (val == OFF) { + /* clear LFLAG */ + link->flags &= ~(ATA_LFLAG_SW_ACTIVITY); + + /* set the LED to OFF */ + port_led_state &= 0xfff80000; + port_led_state |= (ap->port_no | (link->pmp << 8)); + ahci_transmit_led_message(ap, port_led_state, 4); + } else { + link->flags |= ATA_LFLAG_SW_ACTIVITY; + if (val == BLINK_OFF) { + /* set LED to ON for idle */ + port_led_state &= 0xfff80000; + port_led_state |= (ap->port_no | (link->pmp << 8)); + port_led_state |= 0x00010000; /* check this */ + ahci_transmit_led_message(ap, port_led_state, 4); + } + } + emp->blink_policy = val; + return 0; +} + +static ssize_t ahci_activity_show(struct ata_device *dev, char *buf) +{ + struct ata_link *link = dev->link; + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_em_priv *emp = &pp->em_priv[link->pmp]; + + /* display the saved value of activity behavior for this + * disk. + */ + return sprintf(buf, "%d\n", emp->blink_policy); +} + static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap, int port_no, void __iomem *mmio, void __iomem *port_mmio) @@ -1848,6 +2135,8 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); readl(port_mmio + PORT_CMD_ISSUE); /* flush */ + ahci_sw_activity(qc->dev->link); + return 0; } @@ -2154,7 +2443,8 @@ static void ahci_print_info(struct ata_host *host) dev_printk(KERN_INFO, &pdev->dev, "flags: " "%s%s%s%s%s%s%s" - "%s%s%s%s%s%s%s\n" + "%s%s%s%s%s%s%s" + "%s\n" , cap & (1 << 31) ? "64bit " : "", @@ -2171,7 +2461,8 @@ static void ahci_print_info(struct ata_host *host) cap & (1 << 17) ? "pmp " : "", cap & (1 << 15) ? "pio " : "", cap & (1 << 14) ? "slum " : "", - cap & (1 << 13) ? "part " : "" + cap & (1 << 13) ? "part " : "", + cap & (1 << 6) ? "ems ": "" ); } @@ -2291,6 +2582,24 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (hpriv->cap & HOST_CAP_PMP) pi.flags |= ATA_FLAG_PMP; + if (ahci_em_messages && (hpriv->cap & HOST_CAP_EMS)) { + u8 messages; + void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; + u32 em_loc = readl(mmio + HOST_EM_LOC); + u32 em_ctl = readl(mmio + HOST_EM_CTL); + + messages = (em_ctl & 0x000f0000) >> 16; + + /* we only support LED message type right now */ + if ((messages & 0x01) && (ahci_em_messages == 1)) { + /* store em_loc */ + hpriv->em_loc = ((em_loc >> 16) * 4); + pi.flags |= ATA_FLAG_EM; + if (!(em_ctl & EM_CTL_ALHD)) + pi.flags |= ATA_FLAG_SW_ACTIVITY; + } + } + /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at @@ -2304,6 +2613,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) host->iomap = pcim_iomap_table(pdev); host->private_data = hpriv; + if (pi.flags & ATA_FLAG_EM) + ahci_reset_em(host); + for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; @@ -2314,6 +2626,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* set initial link pm policy */ ap->pm_policy = NOT_AVAILABLE; + /* set enclosure management message type */ + if (ap->flags & ATA_FLAG_EM) + ap->em_message_type = ahci_em_messages; + + /* disabled/not-implemented port */ if (!(hpriv->port_map & (1 << i))) ap->ops = &ata_dummy_port_ops; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 57a4364..b578b11 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -190,6 +190,85 @@ static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); } +static ssize_t +ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) + return ap->ops->em_store(ap, buf, count); + return -EINVAL; +} + +static ssize_t +ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) + return ap->ops->em_show(ap, buf); + return -EINVAL; +} +DEVICE_ATTR(em_message, S_IRUGO | S_IWUGO, + ata_scsi_em_message_show, ata_scsi_em_message_store); +EXPORT_SYMBOL_GPL(dev_attr_em_message); + +static ssize_t +ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct ata_port *ap = ata_shost_to_port(shost); + + return snprintf(buf, 23, "%d\n", ap->em_message_type); +} +DEVICE_ATTR(em_message_type, S_IRUGO, + ata_scsi_em_message_type_show, NULL); +EXPORT_SYMBOL_GPL(dev_attr_em_message_type); + +static ssize_t +ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + + if (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY)) + return ap->ops->sw_activity_show(atadev, buf); + return -EINVAL; +} + +static ssize_t +ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); + enum sw_activity val; + int rc; + + if (ap->ops->sw_activity_store && (ap->flags & ATA_FLAG_SW_ACTIVITY)) { + val = simple_strtoul(buf, NULL, 0); + switch (val) { + case OFF: case BLINK_ON: case BLINK_OFF: + rc = ap->ops->sw_activity_store(atadev, val); + if (!rc) + return count; + else + return rc; + } + } + return -EINVAL; +} +DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show, + ata_scsi_activity_store); +EXPORT_SYMBOL_GPL(dev_attr_sw_activity); + static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { diff --git a/include/linux/libata.h b/include/linux/libata.h index 035f8e1..5b247b8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -169,6 +169,7 @@ enum { ATA_LFLAG_ASSUME_CLASS = ATA_LFLAG_ASSUME_ATA | ATA_LFLAG_ASSUME_SEMB, ATA_LFLAG_NO_RETRY = (1 << 5), /* don't retry this link */ ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */ + ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ /* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ @@ -191,6 +192,10 @@ enum { ATA_FLAG_AN = (1 << 18), /* controller supports AN */ ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */ ATA_FLAG_IPM = (1 << 20), /* driver can handle IPM */ + ATA_FLAG_EM = (1 << 21), /* driver supports enclosure + * management */ + ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity + * led */ /* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be @@ -446,6 +451,15 @@ enum link_pm { MEDIUM_POWER, }; extern struct device_attribute dev_attr_link_power_management_policy; +extern struct device_attribute dev_attr_em_message_type; +extern struct device_attribute dev_attr_em_message; +extern struct device_attribute dev_attr_sw_activity; + +enum sw_activity { + OFF, + BLINK_ON, + BLINK_OFF, +}; #ifdef CONFIG_ATA_SFF struct ata_ioports { @@ -701,6 +715,7 @@ struct ata_port { struct timer_list fastdrain_timer; unsigned long fastdrain_cnt; + int em_message_type; void *private_data; #ifdef CONFIG_ATA_ACPI @@ -792,6 +807,12 @@ struct ata_port_operations { u8 (*bmdma_status)(struct ata_port *ap); #endif /* CONFIG_ATA_SFF */ + ssize_t (*em_show)(struct ata_port *ap, char *buf); + ssize_t (*em_store)(struct ata_port *ap, const char *message, + size_t size); + ssize_t (*sw_activity_show)(struct ata_device *dev, char *buf); + ssize_t (*sw_activity_store)(struct ata_device *dev, + enum sw_activity val); /* * Obsolete */ -- cgit v0.10.2 From ec6add99307d5149e17f6e358f19f0205b622407 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 23 Jun 2008 11:01:31 +0200 Subject: [libata] sata_svw: update code comments relating to data corruption Signed-off-by: Pavel Machek Signed-off-by: Jeff Garzik diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 16aa683..fb13b82 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -253,21 +253,29 @@ static void k2_bmdma_start_mmio(struct ata_queued_cmd *qc) /* start host DMA transaction */ dmactl = readb(mmio + ATA_DMA_CMD); writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD); - /* There is a race condition in certain SATA controllers that can - be seen when the r/w command is given to the controller before the - host DMA is started. On a Read command, the controller would initiate - the command to the drive even before it sees the DMA start. When there - are very fast drives connected to the controller, or when the data request - hits in the drive cache, there is the possibility that the drive returns a part - or all of the requested data to the controller before the DMA start is issued. - In this case, the controller would become confused as to what to do with the data. - In the worst case when all the data is returned back to the controller, the - controller could hang. In other cases it could return partial data returning - in data corruption. This problem has been seen in PPC systems and can also appear - on an system with very fast disks, where the SATA controller is sitting behind a - number of bridges, and hence there is significant latency between the r/w command - and the start command. */ - /* issue r/w command if the access is to ATA*/ + /* This works around possible data corruption. + + On certain SATA controllers that can be seen when the r/w + command is given to the controller before the host DMA is + started. + + On a Read command, the controller would initiate the + command to the drive even before it sees the DMA + start. When there are very fast drives connected to the + controller, or when the data request hits in the drive + cache, there is the possibility that the drive returns a + part or all of the requested data to the controller before + the DMA start is issued. In this case, the controller + would become confused as to what to do with the data. In + the worst case when all the data is returned back to the + controller, the controller could hang. In other cases it + could return partial data returning in data + corruption. This problem has been seen in PPC systems and + can also appear on an system with very fast disks, where + the SATA controller is sitting behind a number of bridges, + and hence there is significant latency between the r/w + command and the start command. */ + /* issue r/w command if the access is to ATA */ if (qc->tf.protocol == ATA_PROT_DMA) ap->ops->sff_exec_command(ap, &qc->tf); } -- cgit v0.10.2 From 3eabddb8ed4f488664ff5d67968392bb424836a3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 10 Jun 2008 18:28:05 +0900 Subject: libata-eh: update atapi_eh_request_sense() to take @dev instead of @qc Update atapi_eh_request_sense() to take @dev, @sense_buf and @dfl_sense_key instead of taking @qc and extracting information from it. This change is to make the function more generic and allow it to be called from other places. While at it, make cdb initialization use initializer. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index d5f03a6..58bdc53 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1360,6 +1360,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev, * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE * @dev: device to perform REQUEST_SENSE to * @sense_buf: result sense data buffer (SCSI_SENSE_BUFFERSIZE bytes long) + * @dfl_sense_key: default sense key to use * * Perform ATAPI REQUEST_SENSE after the device reported CHECK * SENSE. This function is EH helper. @@ -1370,13 +1371,13 @@ static int ata_eh_read_log_10h(struct ata_device *dev, * RETURNS: * 0 on success, AC_ERR_* mask on failure */ -static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc) +static unsigned int atapi_eh_request_sense(struct ata_device *dev, + u8 *sense_buf, u8 dfl_sense_key) { - struct ata_device *dev = qc->dev; - unsigned char *sense_buf = qc->scsicmd->sense_buffer; + u8 cdb[ATAPI_CDB_LEN] = + { REQUEST_SENSE, 0, 0, 0, SCSI_SENSE_BUFFERSIZE, 0 }; struct ata_port *ap = dev->link->ap; struct ata_taskfile tf; - u8 cdb[ATAPI_CDB_LEN]; DPRINTK("ATAPI request sense\n"); @@ -1387,15 +1388,11 @@ static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc) * for the case where they are -not- overwritten */ sense_buf[0] = 0x70; - sense_buf[2] = qc->result_tf.feature >> 4; + sense_buf[2] = dfl_sense_key; /* some devices time out if garbage left in tf */ ata_tf_init(dev, &tf); - memset(cdb, 0, ATAPI_CDB_LEN); - cdb[0] = REQUEST_SENSE; - cdb[4] = SCSI_SENSE_BUFFERSIZE; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.command = ATA_CMD_PACKET; @@ -1567,7 +1564,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, case ATA_DEV_ATAPI: if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) { - tmp = atapi_eh_request_sense(qc); + tmp = atapi_eh_request_sense(qc->dev, + qc->scsicmd->sense_buffer, + qc->result_tf.feature >> 4); if (!tmp) { /* ATA_QCFLAG_SENSE_VALID is used to * tell atapi_qc_complete() that sense -- cgit v0.10.2 From 6ad67403da47e833d9e418caf7f28295c9472e11 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 18 Jun 2008 17:16:43 -0700 Subject: ata: endianness annotations in pata drivers drivers/ata/pata_qdi.c:142:9: warning: incorrect type in assignment (different base types) drivers/ata/pata_qdi.c:142:9: expected unsigned int [unsigned] [usertype] pad drivers/ata/pata_qdi.c:142:9: got restricted __le32 [usertype] drivers/ata/pata_qdi.c:146:15: warning: cast to restricted __le32 drivers/ata/pata_winbond.c:110:9: warning: incorrect type in assignment (different base types) drivers/ata/pata_winbond.c:110:9: expected unsigned int [unsigned] [usertype] pad drivers/ata/pata_winbond.c:110:9: got restricted __le32 [usertype] drivers/ata/pata_winbond.c:114:15: warning: cast to restricted __le32 drivers/ata/pata_legacy.c:310:9: warning: incorrect type in assignment (different base types) drivers/ata/pata_legacy.c:310:9: expected unsigned int [unsigned] [usertype] pad drivers/ata/pata_legacy.c:310:9: got restricted __le32 [usertype] drivers/ata/pata_legacy.c:314:15: warning: cast to restricted __le32 drivers/ata/pata_legacy.c:752:11: warning: cast to restricted __le32 drivers/ata/pata_legacy.c:756:9: warning: incorrect type in assignment (different base types) drivers/ata/pata_legacy.c:756:9: expected unsigned int [unsigned] [addressable] [assigned] [usertype] pad drivers/ata/pata_legacy.c:756:9: got restricted __le32 [usertype] Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index fe7cc8e..bc037ff 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -305,7 +305,7 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad; if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); @@ -746,14 +746,12 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad; if (rw == WRITE) { memcpy(&pad, buf + buflen - slop, slop); - pad = le32_to_cpu(pad); - iowrite32(pad, ap->ioaddr.data_addr); + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); } else { - pad = ioread32(ap->ioaddr.data_addr); - pad = cpu_to_le32(pad); + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); } } diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 97e5b09..63b7a1c 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -137,7 +137,7 @@ static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf, iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad; if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 474528f..a7606b0 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -105,7 +105,7 @@ static unsigned int winbond_data_xfer(struct ata_device *dev, iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - u32 pad; + __le32 pad; if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); -- cgit v0.10.2 From 1e9dbc9291738149577cc488fd441f061815e02e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 19 Jun 2008 13:13:38 -0600 Subject: [libata] Add support for VPD page b1 SCSI VPD page b1 reports the nominal rotation speed and physical size of the device. Devices that conform to ATA-8 can return this information in words 217 and 168 of the identify data. Signed-off-by: Matthew Wilcox Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b578b11..479c29e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1857,7 +1857,9 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) const u8 pages[] = { 0x00, /* page 0x00, this page */ 0x80, /* page 0x80, unit serial no page */ - 0x83 /* page 0x83, device ident page */ + 0x83, /* page 0x83, device ident page */ + 0x89, /* page 0x89, ata info page */ + 0xb1, /* page 0xb1, block device characteristics page */ }; rbuf[3] = sizeof(pages); /* number of supported VPD pages */ @@ -1978,6 +1980,19 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) return 0; } +static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) +{ + rbuf[1] = 0xb1; + rbuf[3] = 0x3c; + if (ata_id_major_version(args->id) > 7) { + rbuf[4] = args->id[217] >> 8; + rbuf[5] = args->id[217]; + rbuf[7] = args->id[168] & 0xf; + } + + return 0; +} + /** * ata_scsiop_noop - Command handler that simply returns success. * @args: device IDENTIFY data / SCSI command of interest. @@ -2999,6 +3014,9 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, case 0x89: ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); break; + case 0xb1: + ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1); + break; default: ata_scsi_invalid_field(cmd, done); break; -- cgit v0.10.2 From 24920c8a6358bf5532f1336b990b1c0fe2b599ee Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 4 Jul 2008 13:32:17 +0800 Subject: AHCI: speed up resume During resume, sleep 1 second to wait for the HBA reset to finish is a waste of time. According to the AHCI 1.2 spec, We should poll the HOST_CTL register, and return error if the host reset is not finished within 1 second. Test results show that the HBA reset can be done quickly(in usecs). And this patch may save nearly 1 second during resume. Signed-off-by: Zhang Rui Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 65d4e96..4ff3f03 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1142,12 +1142,15 @@ static int ahci_reset_controller(struct ata_host *host) readl(mmio + HOST_CTL); /* flush */ } - /* reset must complete within 1 second, or + /* + * to perform host reset, OS should set HOST_RESET + * and poll until this bit is read to be "0". + * reset must complete within 1 second, or * the hardware should be considered fried. */ - ssleep(1); + tmp = ata_wait_register(mmio + HOST_CTL, HOST_RESET, + HOST_RESET, 10, 1000); - tmp = readl(mmio + HOST_CTL); if (tmp & HOST_RESET) { dev_printk(KERN_ERR, host->dev, "controller reset failed (0x%x)\n", tmp); -- cgit v0.10.2 From 2640d7c0b8d5d9d9ee303b8cd09f5124176f6239 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 6 Jul 2008 09:23:20 -0400 Subject: AHCI: Remove an unnecessary flush from ahci_qc_issue In an I/O heavy workload (IOZone), ahci_qc_issue is the second-highest consumer of CPU cycles. Removing the flush gets us approximately 10% bandwidth improvement. I believe this to be because the CPU can start queueing the next request instead of waiting for the readl() to flush the writes to the device. The flush isn't necessary because we're using a 'queue' metaphor; we don't guarantee the command has got to the device, nor do we need to guarantee the command has got to the controller. Signed-off-by: Matthew Wilcox Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 4ff3f03..dc7596f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2136,7 +2136,6 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) if (qc->tf.protocol == ATA_PROT_NCQ) writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); - readl(port_mmio + PORT_CMD_ISSUE); /* flush */ ahci_sw_activity(qc->dev->link); -- cgit v0.10.2 From 7f101a97866e2687a455ecffeb96bcf317c8482a Mon Sep 17 00:00:00 2001 From: Dave Young Date: Mon, 14 Jul 2008 22:38:19 +0200 Subject: i2c: Use class_for_each_device Use class_for_each_device for iteration. Signed-off-by: Dave Young Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d0175f4..f489683 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "i2c-core.h" @@ -646,6 +645,16 @@ EXPORT_SYMBOL(i2c_del_adapter); /* ------------------------------------------------------------------------- */ +static int __attach_adapter(struct device *dev, void *data) +{ + struct i2c_adapter *adapter = to_i2c_adapter(dev); + struct i2c_driver *driver = data; + + driver->attach_adapter(adapter); + + return 0; +} + /* * An i2c_driver is used with one or more i2c_client (device) nodes to access * i2c slave chips, on a bus instance associated with some i2c_adapter. There @@ -686,21 +695,49 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); /* legacy drivers scan i2c busses directly */ - if (driver->attach_adapter) { - struct i2c_adapter *adapter; + if (driver->attach_adapter) + class_for_each_device(&i2c_adapter_class, driver, + __attach_adapter); - down(&i2c_adapter_class.sem); - list_for_each_entry(adapter, &i2c_adapter_class.devices, - dev.node) { - driver->attach_adapter(adapter); + mutex_unlock(&core_lock); + return 0; +} +EXPORT_SYMBOL(i2c_register_driver); + +static int __detach_adapter(struct device *dev, void *data) +{ + struct i2c_adapter *adapter = to_i2c_adapter(dev); + struct i2c_driver *driver = data; + + /* Have a look at each adapter, if clients of this driver are still + * attached. If so, detach them to be able to kill the driver + * afterwards. + */ + if (driver->detach_adapter) { + if (driver->detach_adapter(adapter)) + dev_err(&adapter->dev, + "detach_adapter failed for driver [%s]\n", + driver->driver.name); + } else { + struct list_head *item, *_n; + struct i2c_client *client; + + list_for_each_safe(item, _n, &adapter->clients) { + client = list_entry(item, struct i2c_client, list); + if (client->driver != driver) + continue; + dev_dbg(&adapter->dev, + "detaching client [%s] at 0x%02x\n", + client->name, client->addr); + if (driver->detach_client(client)) + dev_err(&adapter->dev, "detach_client " + "failed for client [%s] at 0x%02x\n", + client->name, client->addr); } - up(&i2c_adapter_class.sem); } - mutex_unlock(&core_lock); return 0; } -EXPORT_SYMBOL(i2c_register_driver); /** * i2c_del_driver - unregister I2C driver @@ -709,46 +746,13 @@ EXPORT_SYMBOL(i2c_register_driver); */ void i2c_del_driver(struct i2c_driver *driver) { - struct list_head *item2, *_n; - struct i2c_client *client; - struct i2c_adapter *adap; - mutex_lock(&core_lock); /* new-style driver? */ if (is_newstyle_driver(driver)) goto unregister; - /* Have a look at each adapter, if clients of this driver are still - * attached. If so, detach them to be able to kill the driver - * afterwards. - */ - down(&i2c_adapter_class.sem); - list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) { - if (driver->detach_adapter) { - if (driver->detach_adapter(adap)) { - dev_err(&adap->dev, "detach_adapter failed " - "for driver [%s]\n", - driver->driver.name); - } - } else { - list_for_each_safe(item2, _n, &adap->clients) { - client = list_entry(item2, struct i2c_client, list); - if (client->driver != driver) - continue; - dev_dbg(&adap->dev, "detaching client [%s] " - "at 0x%02x\n", client->name, - client->addr); - if (driver->detach_client(client)) { - dev_err(&adap->dev, "detach_client " - "failed for client [%s] at " - "0x%02x\n", client->name, - client->addr); - } - } - } - } - up(&i2c_adapter_class.sem); + class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); unregister: driver_unregister(&driver->driver); -- cgit v0.10.2 From cc99ff70c7ad36e01db545a81a8594474964f918 Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:20 +0200 Subject: i2c-davinci: Ensure clock between 7-12 MHz Ensure psc value gives a clock between 7-12 MHz Signed-off-by: Troy Kisky Signed-off-by: Kevin Hilman Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 7ecbfc4..7fdbca1 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -142,6 +142,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; u16 psc; u32 clk; + u32 d; u32 clkh; u32 clkl; u32 input_clock = clk_get_rate(dev->clk); @@ -171,23 +172,29 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) * if PSC > 1 , d = 5 */ - psc = 26; /* To get 1MHz clock */ + /* get minimum of 7 MHz clock, but max of 12 MHz */ + psc = (input_clock / 7000000) - 1; + if ((input_clock / (psc + 1)) > 12000000) + psc++; /* better to run under spec than over */ + d = (psc >= 2) ? 5 : 7 - psc; - clk = ((input_clock / (psc + 1)) / (pdata->bus_freq * 1000)) - 10; - clkh = (50 * clk) / 100; + clk = ((input_clock / (psc + 1)) / (pdata->bus_freq * 1000)) - (d << 1); + clkh = clk >> 1; clkl = clk - clkh; davinci_i2c_write_reg(dev, DAVINCI_I2C_PSC_REG, psc); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); - dev_dbg(dev->dev, "CLK = %d\n", clk); + dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); dev_dbg(dev->dev, "PSC = %d\n", davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); dev_dbg(dev->dev, "CLKL = %d\n", davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG)); dev_dbg(dev->dev, "CLKH = %d\n", davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG)); + dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n", + pdata->bus_freq, pdata->bus_delay); /* Take the I2C module out of reset: */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); -- cgit v0.10.2 From d868caa177d4487ce1935926498f542a8f67c1cf Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:20 +0200 Subject: i2c-davinci: Move dev_dbg statement for more output Previously the dev_dbg only printed if no error. Printing also on an error is more useful Signed-off-by: Troy Kisky Signed-off-by: Kevin Hilman Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 7fdbca1..85097fd 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -345,12 +345,11 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) for (i = 0; i < num; i++) { ret = i2c_davinci_xfer_msg(adap, &msgs[i], (i == (num - 1))); + dev_dbg(dev->dev, "%s [%d/%d] ret: %d\n", __func__, i + 1, num, + ret); if (ret < 0) return ret; } - - dev_dbg(dev->dev, "%s:%d ret: %d\n", __func__, __LINE__, ret); - return num; } -- cgit v0.10.2 From 0ab56e20674b41dd0203d16b602aac8d9d26a70a Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:20 +0200 Subject: i2c-davinci: Remove useless IVR read Interrupts are enabled at the point where the DAVINCI_I2C_IVR_REG is read, so unless an interrupt happened just at that moment, no interrupt would be pending. Even though documentation implies you should do this, I see no reason. If slave support is added, this read would cause a hard to reproduce bug. Signed-off-by: Troy Kisky Signed-off-by: Kevin Hilman Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 85097fd..c56f8fe 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -240,7 +240,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) struct davinci_i2c_dev *dev = i2c_get_adapdata(adap); struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; u32 flag; - u32 stat; u16 w; int r; @@ -264,9 +263,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) init_completion(&dev->cmd_complete); dev->cmd_err = 0; - /* Clear any pending interrupts by reading the IVR */ - stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG); - /* Take I2C out of reset, configure it as master and set the * start bit */ flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT; -- cgit v0.10.2 From 5a0d5f5ffa5d294d895ef54fc220c6182db63998 Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:21 +0200 Subject: i2c-davinci: Fix signal handling bug If wait_for_completion_interruptible_timeout exits due to a signal, the i2c bus was locking up. Signed-off-by: Troy Kisky Signed-off-by: Kevin Hilman Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c56f8fe..1608572 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -85,6 +85,7 @@ #define DAVINCI_I2C_MDR_MST (1 << 10) #define DAVINCI_I2C_MDR_TRX (1 << 9) #define DAVINCI_I2C_MDR_XA (1 << 8) +#define DAVINCI_I2C_MDR_RM (1 << 7) #define DAVINCI_I2C_MDR_IRS (1 << 5) #define DAVINCI_I2C_IMR_AAS (1 << 6) @@ -112,6 +113,7 @@ struct davinci_i2c_dev { u8 *buf; size_t buf_len; int irq; + u8 terminate; struct i2c_adapter adapter; }; @@ -283,20 +285,34 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1); davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); + dev->terminate = 0; /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, DAVINCI_I2C_TIMEOUT); - dev->buf_len = 0; - if (r < 0) - return r; - if (r == 0) { dev_err(dev->dev, "controller timed out\n"); i2c_davinci_init(dev); + dev->buf_len = 0; return -ETIMEDOUT; } + if (dev->buf_len) { + /* This should be 0 if all bytes were transferred + * or dev->cmd_err denotes an error. + * A signal may have aborted the transfer. + */ + if (r >= 0) { + dev_err(dev->dev, "abnormal termination buf_len=%i\n", + dev->buf_len); + r = -EREMOTEIO; + } + dev->terminate = 1; + wmb(); + dev->buf_len = 0; + } + if (r < 0) + return r; /* no error */ if (likely(!dev->cmd_err)) @@ -354,6 +370,27 @@ static u32 i2c_davinci_func(struct i2c_adapter *adap) return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); } +static void terminate_read(struct davinci_i2c_dev *dev) +{ + u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); + w |= DAVINCI_I2C_MDR_NACK; + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); + + /* Throw away data */ + davinci_i2c_read_reg(dev, DAVINCI_I2C_DRR_REG); + if (!dev->terminate) + dev_err(dev->dev, "RDR IRQ while no data requested\n"); +} +static void terminate_write(struct davinci_i2c_dev *dev) +{ + u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); + w |= DAVINCI_I2C_MDR_RM | DAVINCI_I2C_MDR_STP; + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); + + if (!dev->terminate) + dev_err(dev->dev, "TDR IRQ while no data to send\n"); +} + /* * Interrupt service routine. This gets called whenever an I2C interrupt * occurs. @@ -374,12 +411,15 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) switch (stat) { case DAVINCI_I2C_IVR_AL: + /* Arbitration lost, must retry */ dev->cmd_err |= DAVINCI_I2C_STR_AL; + dev->buf_len = 0; complete(&dev->cmd_complete); break; case DAVINCI_I2C_IVR_NACK: dev->cmd_err |= DAVINCI_I2C_STR_NACK; + dev->buf_len = 0; complete(&dev->cmd_complete); break; @@ -401,9 +441,10 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, DAVINCI_I2C_IMR_RRDY); - } else - dev_err(dev->dev, "RDR IRQ while no " - "data requested\n"); + } else { + /* signal can terminate transfer */ + terminate_read(dev); + } break; case DAVINCI_I2C_IVR_XRDY: @@ -420,9 +461,10 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); - } else - dev_err(dev->dev, "TDR IRQ while no data to " - "send\n"); + } else { + /* signal can terminate transfer */ + terminate_write(dev); + } break; case DAVINCI_I2C_IVR_SCD: -- cgit v0.10.2 From 2e7437879897a4185bd84478a0451e5367dee7ed Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Mon, 14 Jul 2008 22:38:21 +0200 Subject: i2c-davinci: Initialize cmd_complete sooner If an interrupt happens before an I2c master read/write, complete is called on uninitialized structure. Signed-off-by: Troy Kisky Signed-off-by: Kevin Hilman Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 1608572..af3846e 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -262,7 +262,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); - init_completion(&dev->cmd_complete); + INIT_COMPLETION(dev->cmd_complete); dev->cmd_err = 0; /* Take I2C out of reset, configure it as master and set the @@ -519,6 +519,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) goto err_release_region; } + init_completion(&dev->cmd_complete); dev->dev = get_device(&pdev->dev); dev->irq = irq->start; platform_set_drvdata(pdev, dev); -- cgit v0.10.2 From 279e902445557897707d325182916a6e28ba80de Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:21 +0200 Subject: i2c-nforce2: Add support for multiplexing on the Tyan S4985 Just like the Tyan S4882, the S4985 uses a multiplexer to give access to all 16 memory module SPD EEPROMs. This specific i2c-nforce2-s4985 driver adds support for this. It is heavily based on the older i2c-amd756-s4882 driver. As more mainboards will use multiplexer chips, we will have to find a way to support them without having to write a new specfic driver for each. The recent changes to the i2c subsystem should help us, and the new gpio subsystem might help, too. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 48438cc..00d76e1 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -315,6 +315,19 @@ config I2C_NFORCE2 This driver can also be built as a module. If so, the module will be called i2c-nforce2. +config I2C_NFORCE2_S4985 + tristate "SMBus multiplexing on the Tyan S4985" + depends on I2C_NFORCE2 && EXPERIMENTAL + help + Enabling this option will add specific SMBus support for the Tyan + S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed + over 4 different channels, where the various memory module EEPROMs + live. Saying yes here will give you access to these in addition + to the trunk. + + This driver can also be built as a module. If so, the module + will be called i2c-nforce2-s4985. + config I2C_OCORES tristate "OpenCores I2C Controller" depends on EXPERIMENTAL diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index e8c882a..8b0a8c2 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o +obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o obj-$(CONFIG_I2C_OMAP) += i2c-omap.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c new file mode 100644 index 0000000..6a8995d --- /dev/null +++ b/drivers/i2c/busses/i2c-nforce2-s4985.c @@ -0,0 +1,257 @@ +/* + * i2c-nforce2-s4985.c - i2c-nforce2 extras for the Tyan S4985 motherboard + * + * Copyright (C) 2008 Jean Delvare + * + * 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. + */ + +/* + * We select the channels by sending commands to the Philips + * PCA9556 chip at I2C address 0x18. The main adapter is used for + * the non-multiplexed part of the bus, and 4 virtual adapters + * are defined for the multiplexed addresses: 0x50-0x53 (memory + * module EEPROM) located on channels 1-4. We define one virtual + * adapter per CPU, which corresponds to one multiplexed channel: + * CPU0: virtual adapter 1, channel 1 + * CPU1: virtual adapter 2, channel 2 + * CPU2: virtual adapter 3, channel 3 + * CPU3: virtual adapter 4, channel 4 + */ + +#include +#include +#include +#include +#include +#include + +extern struct i2c_adapter *nforce2_smbus; + +static struct i2c_adapter *s4985_adapter; +static struct i2c_algorithm *s4985_algo; + +/* Wrapper access functions for multiplexed SMBus */ +static DEFINE_MUTEX(nforce2_lock); + +static s32 nforce2_access_virt0(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + int error; + + /* We exclude the multiplexed addresses */ + if ((addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30 + || addr == 0x18) + return -ENXIO; + + mutex_lock(&nforce2_lock); + error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write, + command, size, data); + mutex_unlock(&nforce2_lock); + + return error; +} + +/* We remember the last used channels combination so as to only switch + channels when it is really needed. This greatly reduces the SMBus + overhead, but also assumes that nobody will be writing to the PCA9556 + in our back. */ +static u8 last_channels; + +static inline s32 nforce2_access_channel(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data, + u8 channels) +{ + int error; + + /* We exclude the non-multiplexed addresses */ + if ((addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30) + return -ENXIO; + + mutex_lock(&nforce2_lock); + if (last_channels != channels) { + union i2c_smbus_data mplxdata; + mplxdata.byte = channels; + + error = nforce2_smbus->algo->smbus_xfer(adap, 0x18, 0, + I2C_SMBUS_WRITE, 0x01, + I2C_SMBUS_BYTE_DATA, + &mplxdata); + if (error) + goto UNLOCK; + last_channels = channels; + } + error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write, + command, size, data); + +UNLOCK: + mutex_unlock(&nforce2_lock); + return error; +} + +static s32 nforce2_access_virt1(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + /* CPU0: channel 1 enabled */ + return nforce2_access_channel(adap, addr, flags, read_write, command, + size, data, 0x02); +} + +static s32 nforce2_access_virt2(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + /* CPU1: channel 2 enabled */ + return nforce2_access_channel(adap, addr, flags, read_write, command, + size, data, 0x04); +} + +static s32 nforce2_access_virt3(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + /* CPU2: channel 3 enabled */ + return nforce2_access_channel(adap, addr, flags, read_write, command, + size, data, 0x08); +} + +static s32 nforce2_access_virt4(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + /* CPU3: channel 4 enabled */ + return nforce2_access_channel(adap, addr, flags, read_write, command, + size, data, 0x10); +} + +static int __init nforce2_s4985_init(void) +{ + int i, error; + union i2c_smbus_data ioconfig; + + /* Unregister physical bus */ + if (!nforce2_smbus) + return -ENODEV; + error = i2c_del_adapter(nforce2_smbus); + if (error) { + dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n"); + goto ERROR0; + } + + printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n"); + /* Define the 5 virtual adapters and algorithms structures */ + s4985_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL); + if (!s4985_adapter) { + error = -ENOMEM; + goto ERROR1; + } + s4985_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL); + if (!s4985_algo) { + error = -ENOMEM; + goto ERROR2; + } + + /* Fill in the new structures */ + s4985_algo[0] = *(nforce2_smbus->algo); + s4985_algo[0].smbus_xfer = nforce2_access_virt0; + s4985_adapter[0] = *nforce2_smbus; + s4985_adapter[0].algo = s4985_algo; + s4985_adapter[0].dev.parent = nforce2_smbus->dev.parent; + for (i = 1; i < 5; i++) { + s4985_algo[i] = *(nforce2_smbus->algo); + s4985_adapter[i] = *nforce2_smbus; + snprintf(s4985_adapter[i].name, sizeof(s4985_adapter[i].name), + "SMBus nForce2 adapter (CPU%d)", i - 1); + s4985_adapter[i].algo = s4985_algo + i; + s4985_adapter[i].dev.parent = nforce2_smbus->dev.parent; + } + s4985_algo[1].smbus_xfer = nforce2_access_virt1; + s4985_algo[2].smbus_xfer = nforce2_access_virt2; + s4985_algo[3].smbus_xfer = nforce2_access_virt3; + s4985_algo[4].smbus_xfer = nforce2_access_virt4; + + /* Configure the PCA9556 multiplexer */ + ioconfig.byte = 0x00; /* All I/O to output mode */ + error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0, + I2C_SMBUS_WRITE, 0x03, + I2C_SMBUS_BYTE_DATA, &ioconfig); + if (error) { + dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n"); + error = -EIO; + goto ERROR3; + } + + /* Register virtual adapters */ + for (i = 0; i < 5; i++) { + error = i2c_add_adapter(s4985_adapter + i); + if (error) { + dev_err(&nforce2_smbus->dev, + "Virtual adapter %d registration " + "failed, module not inserted\n", i); + for (i--; i >= 0; i--) + i2c_del_adapter(s4985_adapter + i); + goto ERROR3; + } + } + + return 0; + +ERROR3: + kfree(s4985_algo); + s4985_algo = NULL; +ERROR2: + kfree(s4985_adapter); + s4985_adapter = NULL; +ERROR1: + /* Restore physical bus */ + i2c_add_adapter(nforce2_smbus); +ERROR0: + return error; +} + +static void __exit nforce2_s4985_exit(void) +{ + if (s4985_adapter) { + int i; + + for (i = 0; i < 5; i++) + i2c_del_adapter(s4985_adapter+i); + kfree(s4985_adapter); + s4985_adapter = NULL; + } + kfree(s4985_algo); + s4985_algo = NULL; + + /* Restore physical bus */ + if (i2c_add_adapter(nforce2_smbus)) + dev_err(&nforce2_smbus->dev, "Physical bus restoration " + "failed\n"); +} + +MODULE_AUTHOR("Jean Delvare "); +MODULE_DESCRIPTION("S4985 SMBus multiplexing"); +MODULE_LICENSE("GPL"); + +module_init(nforce2_s4985_init); +module_exit(nforce2_s4985_exit); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 43c9f8d..f95efff 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -124,6 +124,20 @@ static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = { static struct pci_driver nforce2_driver; +/* For multiplexing support, we need a global reference to the 1st + SMBus channel */ +#if defined CONFIG_I2C_NFORCE2_S4985 || defined CONFIG_I2C_NFORCE2_S4985_MODULE +struct i2c_adapter *nforce2_smbus; +EXPORT_SYMBOL_GPL(nforce2_smbus); + +static void nforce2_set_reference(struct i2c_adapter *adap) +{ + nforce2_smbus = adap; +} +#else +static inline void nforce2_set_reference(struct i2c_adapter *adap) { } +#endif + static void nforce2_abort(struct i2c_adapter *adap) { struct nforce2_smbus *smbus = adap->algo_data; @@ -398,6 +412,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ return -ENODEV; } + nforce2_set_reference(&smbuses[0].adapter); return 0; } @@ -406,6 +421,7 @@ static void __devexit nforce2_remove(struct pci_dev *dev) { struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev); + nforce2_set_reference(NULL); if (smbuses[0].base) { i2c_del_adapter(&smbuses[0].adapter); release_region(smbuses[0].base, smbuses[0].size); -- cgit v0.10.2 From 20a9b6e7c303f2a6f9afe17c0997bc9a3c734442 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: i2c: Remove 3 deprecated bus drivers This patch contains the scheduled removal of i2c-i810, i2c-prosavage and i2c-savage4. Signed-off-by: Adrian Bunk Signed-off-by: Jean Delvare diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 46ece3f..65a1482 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -222,13 +222,6 @@ Who: Thomas Gleixner --------------------------- -What: i2c-i810, i2c-prosavage and i2c-savage4 -When: May 2008 -Why: These drivers are superseded by i810fb, intelfb and savagefb. -Who: Jean Delvare - ---------------------------- - What (Why): - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files (superseded by xt_TOS/xt_tos target & match) diff --git a/Documentation/i2c/busses/i2c-i810 b/Documentation/i2c/busses/i2c-i810 deleted file mode 100644 index 778210e..0000000 --- a/Documentation/i2c/busses/i2c-i810 +++ /dev/null @@ -1,47 +0,0 @@ -Kernel driver i2c-i810 - -Supported adapters: - * Intel 82810, 82810-DC100, 82810E, and 82815 (GMCH) - * Intel 82845G (GMCH) - -Authors: - Frodo Looijaard , - Philip Edelbrock , - Kyösti Mälkki , - Ralph Metzler , - Mark D. Studebaker - -Main contact: Mark Studebaker - -Description ------------ - -WARNING: If you have an '810' or '815' motherboard, your standard I2C -temperature sensors are most likely on the 801's I2C bus. You want the -i2c-i801 driver for those, not this driver. - -Now for the i2c-i810... - -The GMCH chip contains two I2C interfaces. - -The first interface is used for DDC (Data Display Channel) which is a -serial channel through the VGA monitor connector to a DDC-compliant -monitor. This interface is defined by the Video Electronics Standards -Association (VESA). The standards are available for purchase at -http://www.vesa.org . - -The second interface is a general-purpose I2C bus. It may be connected to a -TV-out chip such as the BT869 or possibly to a digital flat-panel display. - -Features --------- - -Both busses use the i2c-algo-bit driver for 'bit banging' -and support for specific transactions is provided by i2c-algo-bit. - -Issues ------- - -If you enable bus testing in i2c-algo-bit (insmod i2c-algo-bit bit_test=1), -the test may fail; if so, the i2c-i810 driver won't be inserted. However, -we think this has been fixed. diff --git a/Documentation/i2c/busses/i2c-prosavage b/Documentation/i2c/busses/i2c-prosavage deleted file mode 100644 index 7036879..0000000 --- a/Documentation/i2c/busses/i2c-prosavage +++ /dev/null @@ -1,23 +0,0 @@ -Kernel driver i2c-prosavage - -Supported adapters: - - S3/VIA KM266/VT8375 aka ProSavage8 - S3/VIA KM133/VT8365 aka Savage4 - -Author: Henk Vergonet - -Description ------------ - -The Savage4 chips contain two I2C interfaces (aka a I2C 'master' or -'host'). - -The first interface is used for DDC (Data Display Channel) which is a -serial channel through the VGA monitor connector to a DDC-compliant -monitor. This interface is defined by the Video Electronics Standards -Association (VESA). The standards are available for purchase at -http://www.vesa.org . The second interface is a general-purpose I2C bus. - -Usefull for gaining access to the TV Encoder chips. - diff --git a/Documentation/i2c/busses/i2c-savage4 b/Documentation/i2c/busses/i2c-savage4 deleted file mode 100644 index 6ecceab..0000000 --- a/Documentation/i2c/busses/i2c-savage4 +++ /dev/null @@ -1,26 +0,0 @@ -Kernel driver i2c-savage4 - -Supported adapters: - * Savage4 - * Savage2000 - -Authors: - Alexander Wold , - Mark D. Studebaker - -Description ------------ - -The Savage4 chips contain two I2C interfaces (aka a I2C 'master' -or 'host'). - -The first interface is used for DDC (Data Display Channel) which is a -serial channel through the VGA monitor connector to a DDC-compliant -monitor. This interface is defined by the Video Electronics Standards -Association (VESA). The standards are available for purchase at -http://www.vesa.org . The DDC bus is not yet supported because its register -is not directly memory-mapped. - -The second interface is a general-purpose I2C bus. This is the only -interface supported by the driver at the moment. - diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 00d76e1..b7cce92 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -186,26 +186,6 @@ config I2C_I801 This driver can also be built as a module. If so, the module will be called i2c-i801. -config I2C_I810 - tristate "Intel 810/815 (DEPRECATED)" - default n - depends on PCI - select I2C_ALGOBIT - help - If you say yes to this option, support will be included for the Intel - 810/815 family of mainboard I2C interfaces. Specifically, the - following versions of the chipset are supported: - i810AA - i810AB - i810E - i815 - i845G - - This driver is deprecated in favor of the i810fb and intelfb drivers. - - This driver can also be built as a module. If so, the module - will be called i2c-i810. - config I2C_PXA tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" depends on EXPERIMENTAL && ARCH_PXA @@ -402,24 +382,6 @@ config I2C_PASEMI help Supports the PA Semi PWRficient on-chip SMBus interfaces. -config I2C_PROSAVAGE - tristate "S3/VIA (Pro)Savage (DEPRECATED)" - default n - depends on PCI - select I2C_ALGOBIT - help - If you say yes to this option, support will be included for the - I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8 - graphics processors. - chipsets supported: - S3/VIA KM266/VT8375 aka ProSavage8 - S3/VIA KM133/VT8365 aka Savage4 - - This driver is deprecated in favor of the savagefb driver. - - This support is also available as a module. If so, the module - will be called i2c-prosavage. - config I2C_S3C2410 tristate "S3C2410 I2C Driver" depends on ARCH_S3C2410 @@ -427,20 +389,6 @@ config I2C_S3C2410 Say Y here to include support for I2C controller in the Samsung S3C2410 based System-on-Chip devices. -config I2C_SAVAGE4 - tristate "S3 Savage 4 (DEPRECATED)" - default n - depends on PCI - select I2C_ALGOBIT - help - If you say yes to this option, support will be included for the - S3 Savage 4 I2C interface. - - This driver is deprecated in favor of the savagefb driver. - - This driver can also be built as a module. If so, the module - will be called i2c-savage4. - config I2C_SIBYTE tristate "SiByte SMBus interface" depends on SIBYTE_SB1xxx_SOC diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 8b0a8c2..81bb407 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_I801) += i2c-i801.o -obj-$(CONFIG_I2C_I810) += i2c-i810.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o @@ -35,10 +34,8 @@ obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o obj-$(CONFIG_I2C_PNX) += i2c-pnx.o -obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o -obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c deleted file mode 100644 index 42e8d94..0000000 --- a/drivers/i2c/busses/i2c-i810.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - i2c-i810.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1998, 1999, 2000 Frodo Looijaard , - Philip Edelbrock , - Ralph Metzler , and - Mark D. Studebaker - - Based on code written by Ralph Metzler and - Simon Vogl - - 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. -*/ -/* - This interfaces to the I810/I815 to provide access to - the DDC Bus and the I2C Bus. - - SUPPORTED DEVICES PCI ID - i810AA 7121 - i810AB 7123 - i810E 7125 - i815 1132 - i845G 2562 -*/ - -#include -#include -#include -#include -#include -#include -#include - -/* GPIO register locations */ -#define I810_IOCONTROL_OFFSET 0x5000 -#define I810_HVSYNC 0x00 /* not used */ -#define I810_GPIOA 0x10 -#define I810_GPIOB 0x14 - -/* bit locations in the registers */ -#define SCL_DIR_MASK 0x0001 -#define SCL_DIR 0x0002 -#define SCL_VAL_MASK 0x0004 -#define SCL_VAL_OUT 0x0008 -#define SCL_VAL_IN 0x0010 -#define SDA_DIR_MASK 0x0100 -#define SDA_DIR 0x0200 -#define SDA_VAL_MASK 0x0400 -#define SDA_VAL_OUT 0x0800 -#define SDA_VAL_IN 0x1000 - -/* initialization states */ -#define INIT1 0x1 -#define INIT2 0x2 -#define INIT3 0x4 - -/* delays */ -#define CYCLE_DELAY 10 -#define TIMEOUT (HZ / 2) - -static void __iomem *ioaddr; - -/* The i810 GPIO registers have individual masks for each bit - so we never have to read before writing. Nice. */ - -static void bit_i810i2c_setscl(void *data, int val) -{ - writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK, - ioaddr + I810_GPIOB); - readl(ioaddr + I810_GPIOB); /* flush posted write */ -} - -static void bit_i810i2c_setsda(void *data, int val) -{ - writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK, - ioaddr + I810_GPIOB); - readl(ioaddr + I810_GPIOB); /* flush posted write */ -} - -/* The GPIO pins are open drain, so the pins could always remain outputs. - However, some chip versions don't latch the inputs unless they - are set as inputs. - We rely on the i2c-algo-bit routines to set the pins high before - reading the input from other chips. Following guidance in the 815 - prog. ref. guide, we do a "dummy write" of 0 to the register before - reading which forces the input value to be latched. We presume this - applies to the 810 as well; shouldn't hurt anyway. This is necessary to get - i2c_algo_bit bit_test=1 to pass. */ - -static int bit_i810i2c_getscl(void *data) -{ - writel(SCL_DIR_MASK, ioaddr + I810_GPIOB); - writel(0, ioaddr + I810_GPIOB); - return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN)); -} - -static int bit_i810i2c_getsda(void *data) -{ - writel(SDA_DIR_MASK, ioaddr + I810_GPIOB); - writel(0, ioaddr + I810_GPIOB); - return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN)); -} - -static void bit_i810ddc_setscl(void *data, int val) -{ - writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK, - ioaddr + I810_GPIOA); - readl(ioaddr + I810_GPIOA); /* flush posted write */ -} - -static void bit_i810ddc_setsda(void *data, int val) -{ - writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK, - ioaddr + I810_GPIOA); - readl(ioaddr + I810_GPIOA); /* flush posted write */ -} - -static int bit_i810ddc_getscl(void *data) -{ - writel(SCL_DIR_MASK, ioaddr + I810_GPIOA); - writel(0, ioaddr + I810_GPIOA); - return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN)); -} - -static int bit_i810ddc_getsda(void *data) -{ - writel(SDA_DIR_MASK, ioaddr + I810_GPIOA); - writel(0, ioaddr + I810_GPIOA); - return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN)); -} - -static int config_i810(struct pci_dev *dev) -{ - unsigned long cadr; - - /* map I810 memory */ - cadr = dev->resource[1].start; - cadr += I810_IOCONTROL_OFFSET; - cadr &= PCI_BASE_ADDRESS_MEM_MASK; - ioaddr = ioremap_nocache(cadr, 0x1000); - if (ioaddr) { - bit_i810i2c_setscl(NULL, 1); - bit_i810i2c_setsda(NULL, 1); - bit_i810ddc_setscl(NULL, 1); - bit_i810ddc_setsda(NULL, 1); - return 0; - } - return -ENODEV; -} - -static struct i2c_algo_bit_data i810_i2c_bit_data = { - .setsda = bit_i810i2c_setsda, - .setscl = bit_i810i2c_setscl, - .getsda = bit_i810i2c_getsda, - .getscl = bit_i810i2c_getscl, - .udelay = CYCLE_DELAY, - .timeout = TIMEOUT, -}; - -static struct i2c_adapter i810_i2c_adapter = { - .owner = THIS_MODULE, - .id = I2C_HW_B_I810, - .name = "I810/I815 I2C Adapter", - .algo_data = &i810_i2c_bit_data, -}; - -static struct i2c_algo_bit_data i810_ddc_bit_data = { - .setsda = bit_i810ddc_setsda, - .setscl = bit_i810ddc_setscl, - .getsda = bit_i810ddc_getsda, - .getscl = bit_i810ddc_getscl, - .udelay = CYCLE_DELAY, - .timeout = TIMEOUT, -}; - -static struct i2c_adapter i810_ddc_adapter = { - .owner = THIS_MODULE, - .id = I2C_HW_B_I810, - .name = "I810/I815 DDC Adapter", - .algo_data = &i810_ddc_bit_data, -}; - -static struct pci_device_id i810_ids[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) }, - { 0, }, -}; - -MODULE_DEVICE_TABLE (pci, i810_ids); - -static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - int retval; - - retval = config_i810(dev); - if (retval) - return retval; - dev_info(&dev->dev, "i810/i815 i2c device found.\n"); - - /* set up the sysfs linkage to our parent device */ - i810_i2c_adapter.dev.parent = &dev->dev; - i810_ddc_adapter.dev.parent = &dev->dev; - - retval = i2c_bit_add_bus(&i810_i2c_adapter); - if (retval) - return retval; - retval = i2c_bit_add_bus(&i810_ddc_adapter); - if (retval) - i2c_del_adapter(&i810_i2c_adapter); - return retval; -} - -static void __devexit i810_remove(struct pci_dev *dev) -{ - i2c_del_adapter(&i810_ddc_adapter); - i2c_del_adapter(&i810_i2c_adapter); - iounmap(ioaddr); -} - -static struct pci_driver i810_driver = { - .name = "i810_smbus", - .id_table = i810_ids, - .probe = i810_probe, - .remove = __devexit_p(i810_remove), -}; - -static int __init i2c_i810_init(void) -{ - return pci_register_driver(&i810_driver); -} - -static void __exit i2c_i810_exit(void) -{ - pci_unregister_driver(&i810_driver); -} - -MODULE_AUTHOR("Frodo Looijaard , " - "Philip Edelbrock , " - "Ralph Metzler , " - "and Mark D. Studebaker "); -MODULE_DESCRIPTION("I810/I815 I2C/DDC driver"); -MODULE_LICENSE("GPL"); - -module_init(i2c_i810_init); -module_exit(i2c_i810_exit); diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c deleted file mode 100644 index 07c1f1e..0000000 --- a/drivers/i2c/busses/i2c-prosavage.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * kernel/busses/i2c-prosavage.c - * - * i2c bus driver for S3/VIA 8365/8375 graphics processor. - * Copyright (c) 2003 Henk Vergonet - * Based on code written by: - * Frodo Looijaard , - * Philip Edelbrock , - * Ralph Metzler , and - * Mark D. Studebaker - * Simon Vogl - * and others - * - * Please read the lm_sensors documentation for details on use. - * - * 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. - * - */ -/* 18-05-2003 HVE - created - * 14-06-2003 HVE - adapted for lm_sensors2 - * 17-06-2003 HVE - linux 2.5.xx compatible - * 18-06-2003 HVE - codingstyle - * 21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx - * codingstyle, mmio enabled - * - * This driver interfaces to the I2C bus of the VIA north bridge embedded - * ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips. - * - * Graphics cores: - * S3/VIA KM266/VT8375 aka ProSavage8 - * S3/VIA KM133/VT8365 aka Savage4 - * - * Two serial busses are implemented: - * SERIAL1 - I2C serial communications interface - * SERIAL2 - DDC2 monitor communications interface - * - * Tested on a FX41 mainboard, see http://www.shuttle.com - * - * - * TODO: - * - integration with prosavage framebuffer device - * (Additional documentation needed :( - */ - -#include -#include -#include -#include -#include -#include - -/* - * driver configuration - */ -#define MAX_BUSSES 2 - -struct s_i2c_bus { - void __iomem *mmvga; - int i2c_reg; - int adap_ok; - struct i2c_adapter adap; - struct i2c_algo_bit_data algo; -}; - -struct s_i2c_chip { - void __iomem *mmio; - struct s_i2c_bus i2c_bus[MAX_BUSSES]; -}; - - -/* - * i2c configuration - */ -#define CYCLE_DELAY 10 -#define TIMEOUT (HZ / 2) - - -/* - * S3/VIA 8365/8375 registers - */ -#define VGA_CR_IX 0x3d4 -#define VGA_CR_DATA 0x3d5 - -#define CR_SERIAL1 0xa0 /* I2C serial communications interface */ -#define MM_SERIAL1 0xff20 -#define CR_SERIAL2 0xb1 /* DDC2 monitor communications interface */ - -/* based on vt8365 documentation */ -#define I2C_ENAB 0x10 -#define I2C_SCL_OUT 0x01 -#define I2C_SDA_OUT 0x02 -#define I2C_SCL_IN 0x04 -#define I2C_SDA_IN 0x08 - -#define SET_CR_IX(p, val) writeb((val), (p)->mmvga + VGA_CR_IX) -#define SET_CR_DATA(p, val) writeb((val), (p)->mmvga + VGA_CR_DATA) -#define GET_CR_DATA(p) readb((p)->mmvga + VGA_CR_DATA) - - -/* - * Serial bus line handling - * - * serial communications register as parameter in private data - * - * TODO: locks with other code sections accessing video registers? - */ -static void bit_s3via_setscl(void *bus, int val) -{ - struct s_i2c_bus *p = (struct s_i2c_bus *)bus; - unsigned int r; - - SET_CR_IX(p, p->i2c_reg); - r = GET_CR_DATA(p); - r |= I2C_ENAB; - if (val) { - r |= I2C_SCL_OUT; - } else { - r &= ~I2C_SCL_OUT; - } - SET_CR_DATA(p, r); -} - -static void bit_s3via_setsda(void *bus, int val) -{ - struct s_i2c_bus *p = (struct s_i2c_bus *)bus; - unsigned int r; - - SET_CR_IX(p, p->i2c_reg); - r = GET_CR_DATA(p); - r |= I2C_ENAB; - if (val) { - r |= I2C_SDA_OUT; - } else { - r &= ~I2C_SDA_OUT; - } - SET_CR_DATA(p, r); -} - -static int bit_s3via_getscl(void *bus) -{ - struct s_i2c_bus *p = (struct s_i2c_bus *)bus; - - SET_CR_IX(p, p->i2c_reg); - return (0 != (GET_CR_DATA(p) & I2C_SCL_IN)); -} - -static int bit_s3via_getsda(void *bus) -{ - struct s_i2c_bus *p = (struct s_i2c_bus *)bus; - - SET_CR_IX(p, p->i2c_reg); - return (0 != (GET_CR_DATA(p) & I2C_SDA_IN)); -} - - -/* - * adapter initialisation - */ -static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, void __iomem *mmvga, u32 i2c_reg) -{ - int ret; - p->adap.owner = THIS_MODULE; - p->adap.id = I2C_HW_B_S3VIA; - p->adap.algo_data = &p->algo; - p->adap.dev.parent = &dev->dev; - p->algo.setsda = bit_s3via_setsda; - p->algo.setscl = bit_s3via_setscl; - p->algo.getsda = bit_s3via_getsda; - p->algo.getscl = bit_s3via_getscl; - p->algo.udelay = CYCLE_DELAY; - p->algo.timeout = TIMEOUT; - p->algo.data = p; - p->mmvga = mmvga; - p->i2c_reg = i2c_reg; - - ret = i2c_bit_add_bus(&p->adap); - if (ret) { - return ret; - } - - p->adap_ok = 1; - return 0; -} - - -/* - * Cleanup stuff - */ -static void prosavage_remove(struct pci_dev *dev) -{ - struct s_i2c_chip *chip; - int i, ret; - - chip = (struct s_i2c_chip *)pci_get_drvdata(dev); - - if (!chip) { - return; - } - for (i = MAX_BUSSES - 1; i >= 0; i--) { - if (chip->i2c_bus[i].adap_ok == 0) - continue; - - ret = i2c_del_adapter(&chip->i2c_bus[i].adap); - if (ret) { - dev_err(&dev->dev, "%s not removed\n", - chip->i2c_bus[i].adap.name); - } - } - if (chip->mmio) { - iounmap(chip->mmio); - } - kfree(chip); -} - - -/* - * Detect chip and initialize it - */ -static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - int ret; - unsigned long base, len; - struct s_i2c_chip *chip; - struct s_i2c_bus *bus; - - pci_set_drvdata(dev, kzalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); - chip = (struct s_i2c_chip *)pci_get_drvdata(dev); - if (chip == NULL) { - return -ENOMEM; - } - - base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK; - len = dev->resource[0].end - base + 1; - chip->mmio = ioremap_nocache(base, len); - - if (chip->mmio == NULL) { - dev_err(&dev->dev, "ioremap failed\n"); - prosavage_remove(dev); - return -ENODEV; - } - - - /* - * Chip initialisation - */ - /* Unlock Extended IO Space ??? */ - - - /* - * i2c bus registration - */ - bus = &chip->i2c_bus[0]; - snprintf(bus->adap.name, sizeof(bus->adap.name), - "ProSavage I2C bus at %02x:%02x.%x", - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1); - if (ret) { - goto err_adap; - } - /* - * ddc bus registration - */ - bus = &chip->i2c_bus[1]; - snprintf(bus->adap.name, sizeof(bus->adap.name), - "ProSavage DDC bus at %02x:%02x.%x", - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2); - if (ret) { - goto err_adap; - } - return 0; -err_adap: - dev_err(&dev->dev, "%s failed\n", bus->adap.name); - prosavage_remove(dev); - return ret; -} - - -/* - * Data for PCI driver interface - */ -static struct pci_device_id prosavage_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SAVAGE4) }, - { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_PROSAVAGE8) }, - { 0, }, -}; - -MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl); - -static struct pci_driver prosavage_driver = { - .name = "prosavage_smbus", - .id_table = prosavage_pci_tbl, - .probe = prosavage_probe, - .remove = prosavage_remove, -}; - -static int __init i2c_prosavage_init(void) -{ - return pci_register_driver(&prosavage_driver); -} - -static void __exit i2c_prosavage_exit(void) -{ - pci_unregister_driver(&prosavage_driver); -} - -MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl); -MODULE_AUTHOR("Henk Vergonet"); -MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver"); -MODULE_LICENSE("GPL"); - -module_init (i2c_prosavage_init); -module_exit (i2c_prosavage_exit); diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c deleted file mode 100644 index 8adf4ab..0000000 --- a/drivers/i2c/busses/i2c-savage4.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (C) 1998-2003 The LM Sensors Team - Alexander Wold - Mark D. Studebaker - - Based on i2c-voodoo3.c. - - 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. -*/ - -/* This interfaces to the I2C bus of the Savage4 to gain access to - the BT869 and possibly other I2C devices. The DDC bus is not - yet supported because its register is not memory-mapped. -*/ - -#include -#include -#include -#include -#include -#include -#include - -/* device IDs */ -#define PCI_CHIP_SAVAGE4 0x8A22 -#define PCI_CHIP_SAVAGE2000 0x9102 - -#define REG 0xff20 /* Serial Port 1 Register */ - -/* bit locations in the register */ -#define I2C_ENAB 0x00000020 -#define I2C_SCL_OUT 0x00000001 -#define I2C_SDA_OUT 0x00000002 -#define I2C_SCL_IN 0x00000008 -#define I2C_SDA_IN 0x00000010 - -/* delays */ -#define CYCLE_DELAY 10 -#define TIMEOUT (HZ / 2) - - -static void __iomem *ioaddr; - -/* The sav GPIO registers don't have individual masks for each bit - so we always have to read before writing. */ - -static void bit_savi2c_setscl(void *data, int val) -{ - unsigned int r; - r = readl(ioaddr + REG); - if(val) - r |= I2C_SCL_OUT; - else - r &= ~I2C_SCL_OUT; - writel(r, ioaddr + REG); - readl(ioaddr + REG); /* flush posted write */ -} - -static void bit_savi2c_setsda(void *data, int val) -{ - unsigned int r; - r = readl(ioaddr + REG); - if(val) - r |= I2C_SDA_OUT; - else - r &= ~I2C_SDA_OUT; - writel(r, ioaddr + REG); - readl(ioaddr + REG); /* flush posted write */ -} - -/* The GPIO pins are open drain, so the pins always remain outputs. - We rely on the i2c-algo-bit routines to set the pins high before - reading the input from other chips. */ - -static int bit_savi2c_getscl(void *data) -{ - return (0 != (readl(ioaddr + REG) & I2C_SCL_IN)); -} - -static int bit_savi2c_getsda(void *data) -{ - return (0 != (readl(ioaddr + REG) & I2C_SDA_IN)); -} - -/* Configures the chip */ - -static int config_s4(struct pci_dev *dev) -{ - unsigned long cadr; - - /* map memory */ - cadr = dev->resource[0].start; - cadr &= PCI_BASE_ADDRESS_MEM_MASK; - ioaddr = ioremap_nocache(cadr, 0x0080000); - if (ioaddr) { - /* writel(0x8160, ioaddr + REG2); */ - writel(0x00000020, ioaddr + REG); - dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr); - return 0; - } - return -ENODEV; -} - -static struct i2c_algo_bit_data sav_i2c_bit_data = { - .setsda = bit_savi2c_setsda, - .setscl = bit_savi2c_setscl, - .getsda = bit_savi2c_getsda, - .getscl = bit_savi2c_getscl, - .udelay = CYCLE_DELAY, - .timeout = TIMEOUT -}; - -static struct i2c_adapter savage4_i2c_adapter = { - .owner = THIS_MODULE, - .id = I2C_HW_B_SAVAGE, - .name = "I2C Savage4 adapter", - .algo_data = &sav_i2c_bit_data, -}; - -static struct pci_device_id savage4_ids[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) }, - { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) }, - { 0, } -}; - -MODULE_DEVICE_TABLE (pci, savage4_ids); - -static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - int retval; - - retval = config_s4(dev); - if (retval) - return retval; - - /* set up the sysfs linkage to our parent device */ - savage4_i2c_adapter.dev.parent = &dev->dev; - - return i2c_bit_add_bus(&savage4_i2c_adapter); -} - -static void __devexit savage4_remove(struct pci_dev *dev) -{ - i2c_del_adapter(&savage4_i2c_adapter); - iounmap(ioaddr); -} - -static struct pci_driver savage4_driver = { - .name = "savage4_smbus", - .id_table = savage4_ids, - .probe = savage4_probe, - .remove = __devexit_p(savage4_remove), -}; - -static int __init i2c_savage4_init(void) -{ - return pci_register_driver(&savage4_driver); -} - -static void __exit i2c_savage4_exit(void) -{ - pci_unregister_driver(&savage4_driver); -} - -MODULE_AUTHOR("Alexander Wold " - "and Mark D. Studebaker "); -MODULE_DESCRIPTION("Savage4 I2C/SMBus driver"); -MODULE_LICENSE("GPL"); - -module_init(i2c_savage4_init); -module_exit(i2c_savage4_exit); diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 580acc9..988e566 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -111,7 +111,6 @@ #define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ #define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */ #define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ -#define I2C_HW_B_S3VIA 0x010018 /* S3Via ProSavage adapter */ #define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ #define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ #define I2C_HW_B_CX2388x 0x01001b /* connexant 2388x based tv cards */ -- cgit v0.10.2 From 4d2bee582be1e9da76e0717bad0cfd988c2a5921 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: i2c-bfin-twi: Update the dependencies Since only a few Blackfins lack TWI, just list them in a depends statement. Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b7cce92..37f5b84 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -101,10 +101,9 @@ config I2C_AU1550 config I2C_BLACKFIN_TWI tristate "Blackfin TWI I2C support" depends on BLACKFIN + depends on !BF561 && !BF531 && !BF532 && !BF533 help - This is the TWI I2C device driver for Blackfin BF522, BF525, - BF527, BF534, BF536, BF537 and BF54x. For other Blackfin processors, - please don't use this driver. + This is the I2C bus driver for Blackfin on-chip TWI interface. This driver can also be built as a module. If so, the module will be called i2c-bfin-twi. -- cgit v0.10.2 From 81fded1f79771809059bdfa721ae5ab9114af545 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: i2c: Document standard fault codes Create Documentation/i2c/fault-codes to help standardize fault/error code usage in the I2C stack. It turns out that returning -1 (-EPERM) for everything was not at all helpful. Signed-off-by: David Brownell Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/fault-codes b/Documentation/i2c/fault-codes new file mode 100644 index 0000000..045765c --- /dev/null +++ b/Documentation/i2c/fault-codes @@ -0,0 +1,127 @@ +This is a summary of the most important conventions for use of fault +codes in the I2C/SMBus stack. + + +A "Fault" is not always an "Error" +---------------------------------- +Not all fault reports imply errors; "page faults" should be a familiar +example. Software often retries idempotent operations after transient +faults. There may be fancier recovery schemes that are appropriate in +some cases, such as re-initializing (and maybe resetting). After such +recovery, triggered by a fault report, there is no error. + +In a similar way, sometimes a "fault" code just reports one defined +result for an operation ... it doesn't indicate that anything is wrong +at all, just that the outcome wasn't on the "golden path". + +In short, your I2C driver code may need to know these codes in order +to respond correctly. Other code may need to rely on YOUR code reporting +the right fault code, so that it can (in turn) behave correctly. + + +I2C and SMBus fault codes +------------------------- +These are returned as negative numbers from most calls, with zero or +some positive number indicating a non-fault return. The specific +numbers associated with these symbols differ between architectures, +though most Linux systems use numbering. + +Note that the descriptions here are not exhaustive. There are other +codes that may be returned, and other cases where these codes should +be returned. However, drivers should not return other codes for these +cases (unless the hardware doesn't provide unique fault reports). + +Also, codes returned by adapter probe methods follow rules which are +specific to their host bus (such as PCI, or the platform bus). + + +EAGAIN + Returned by I2C adapters when they lose arbitration in master + transmit mode: some other master was transmitting different + data at the same time. + + Also returned when trying to invoke an I2C operation in an + atomic context, when some task is already using that I2C bus + to execute some other operation. + +EBADMSG + Returned by SMBus logic when an invalid Packet Error Code byte + is received. This code is a CRC covering all bytes in the + transaction, and is sent before the terminating STOP. This + fault is only reported on read transactions; the SMBus slave + may have a way to report PEC mismatches on writes from the + host. Note that even if PECs are in use, you should not rely + on these as the only way to detect incorrect data transfers. + +EBUSY + Returned by SMBus adapters when the bus was busy for longer + than allowed. This usually indicates some device (maybe the + SMBus adapter) needs some fault recovery (such as resetting), + or that the reset was attempted but failed. + +EINVAL + This rather vague error means an invalid parameter has been + detected before any I/O operation was started. Use a more + specific fault code when you can. + + One example would be a driver trying an SMBus Block Write + with block size outside the range of 1-32 bytes. + +EIO + This rather vague error means something went wrong when + performing an I/O operation. Use a more specific fault + code when you can. + +ENODEV + Returned by driver probe() methods. This is a bit more + specific than ENXIO, implying the problem isn't with the + address, but with the device found there. Driver probes + may verify the device returns *correct* responses, and + return this as appropriate. (The driver core will warn + about probe faults other than ENXIO and ENODEV.) + +ENOMEM + Returned by any component that can't allocate memory when + it needs to do so. + +ENXIO + Returned by I2C adapters to indicate that the address phase + of a transfer didn't get an ACK. While it might just mean + an I2C device was temporarily not responding, usually it + means there's nothing listening at that address. + + Returned by driver probe() methods to indicate that they + found no device to bind to. (ENODEV may also be used.) + +EOPNOTSUPP + Returned by an adapter when asked to perform an operation + that it doesn't, or can't, support. + + For example, this would be returned when an adapter that + doesn't support SMBus block transfers is asked to execute + one. In that case, the driver making that request should + have verified that functionality was supported before it + made that block transfer request. + + Similarly, if an I2C adapter can't execute all legal I2C + messages, it should return this when asked to perform a + transaction it can't. (These limitations can't be seen in + the adapter's functionality mask, since the assumption is + that if an adapter supports I2C it supports all of I2C.) + +EPROTO + Returned when slave does not conform to the relevant I2C + or SMBus (or chip-specific) protocol specifications. One + case is when the length of an SMBus block data response + (from the SMBus slave) is outside the range 1-32 bytes. + +ETIMEDOUT + This is returned by drivers when an operation took too much + time, and was aborted before it completed. + + SMBus adapters may return it when an operation took more + time than allowed by the SMBus specification; for example, + when a slave stretches clocks too far. I2C has no such + timeouts, but it's normal for I2C adapters to impose some + arbitrary limits (much longer than SMBus!) too. + -- cgit v0.10.2 From 75415490d6adc1aecbf0cade0785b007957d0cfe Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:22 +0200 Subject: i2c-core: Remove needless include i2c-core doesn't use seq files, so doesn't need to include . Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f489683..bb5c215 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 24a5bb7b1838dc4524dd353224e2aa09c22cac3b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:23 +0200 Subject: i2c-core: Return -Errno, not -1 More updates to the I2C stack's fault reporting: make the core stop returning "-1" (usually "-EPERM") for all faults. Instead, pass lower level fault code up the stack, or return some appropriate errno. This patch happens to touch almost exclusively SMBus calls. Signed-off-by: David Brownell Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index d4cd412..ba5d197 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -598,10 +598,10 @@ be added back later if needed: u8 command, u8 length, u8 *values) -All these transactions return -1 on failure. The 'write' transactions -return 0 on success; the 'read' transactions return the read value, except -for read_block, which returns the number of values read. The block buffers -need not be longer than 32 bytes. +All these transactions return a negative errno value on failure. The 'write' +transactions return 0 on success; the 'read' transactions return the read +value, except for block transactions, which return the number of values +read. The block buffers need not be longer than 32 bytes. You can read the file `smbus-protocol' for more information about the actual SMBus protocol. diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index bb5c215..937f1dc 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -974,7 +974,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) return ret; } else { dev_dbg(&adap->dev, "I2C level transfers not supported\n"); - return -ENOSYS; + return -EOPNOTSUPP; } } EXPORT_SYMBOL(i2c_transfer); @@ -1106,7 +1106,7 @@ int i2c_probe(struct i2c_adapter *adapter, dev_warn(&adapter->dev, "SMBus Quick command not supported, " "can't probe for chips\n"); - return -1; + return -EOPNOTSUPP; } /* Probe entries are done second, and are not affected by ignore @@ -1298,7 +1298,7 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) if (rpec != cpec) { pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n", rpec, cpec); - return -1; + return -EBADMSG; } return 0; } @@ -1313,11 +1313,12 @@ EXPORT_SYMBOL(i2c_smbus_write_quick); s32 i2c_smbus_read_byte(struct i2c_client *client) { union i2c_smbus_data data; - if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, - I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data)) - return -1; - else - return data.byte; + int status; + + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE, &data); + return (status < 0) ? status : data.byte; } EXPORT_SYMBOL(i2c_smbus_read_byte); @@ -1331,11 +1332,12 @@ EXPORT_SYMBOL(i2c_smbus_write_byte); s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) { union i2c_smbus_data data; - if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, - I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data)) - return -1; - else - return data.byte; + int status; + + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_READ, command, + I2C_SMBUS_BYTE_DATA, &data); + return (status < 0) ? status : data.byte; } EXPORT_SYMBOL(i2c_smbus_read_byte_data); @@ -1352,11 +1354,12 @@ EXPORT_SYMBOL(i2c_smbus_write_byte_data); s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) { union i2c_smbus_data data; - if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, - I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data)) - return -1; - else - return data.word; + int status; + + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_READ, command, + I2C_SMBUS_WORD_DATA, &data); + return (status < 0) ? status : data.word; } EXPORT_SYMBOL(i2c_smbus_read_word_data); @@ -1390,11 +1393,13 @@ s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command, u8 *values) { union i2c_smbus_data data; + int status; - if (i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_READ, command, - I2C_SMBUS_BLOCK_DATA, &data)) - return -1; + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_READ, command, + I2C_SMBUS_BLOCK_DATA, &data); + if (status) + return status; memcpy(values, &data.block[1], data.block[0]); return data.block[0]; @@ -1421,14 +1426,16 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 length, u8 *values) { union i2c_smbus_data data; + int status; if (length > I2C_SMBUS_BLOCK_MAX) length = I2C_SMBUS_BLOCK_MAX; data.block[0] = length; - if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, - I2C_SMBUS_READ,command, - I2C_SMBUS_I2C_BLOCK_DATA,&data)) - return -1; + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_READ, command, + I2C_SMBUS_I2C_BLOCK_DATA, &data); + if (status < 0) + return status; memcpy(values, &data.block[1], data.block[0]); return data.block[0]; @@ -1469,6 +1476,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, }; int i; u8 partial_pec = 0; + int status; msgbuf0[0] = command; switch(size) { @@ -1518,10 +1526,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, } else { msg[0].len = data->block[0] + 2; if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { - dev_err(&adapter->dev, "smbus_access called with " - "invalid block write size (%d)\n", - data->block[0]); - return -1; + dev_err(&adapter->dev, + "Invalid block write size %d\n", + data->block[0]); + return -EINVAL; } for (i = 1; i < msg[0].len; i++) msgbuf0[i] = data->block[i-1]; @@ -1531,10 +1539,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, num = 2; /* Another special case */ read_write = I2C_SMBUS_READ; if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { - dev_err(&adapter->dev, "%s called with invalid " - "block proc call size (%d)\n", __func__, + dev_err(&adapter->dev, + "Invalid block write size %d\n", data->block[0]); - return -1; + return -EINVAL; } msg[0].len = data->block[0] + 2; for (i = 1; i < msg[0].len; i++) @@ -1549,19 +1557,18 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, } else { msg[0].len = data->block[0] + 1; if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { - dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with " - "invalid block write size (%d)\n", - data->block[0]); - return -1; + dev_err(&adapter->dev, + "Invalid block write size %d\n", + data->block[0]); + return -EINVAL; } for (i = 1; i <= data->block[0]; i++) msgbuf0[i] = data->block[i]; } break; default: - dev_err(&adapter->dev, "smbus_access called with invalid size (%d)\n", - size); - return -1; + dev_err(&adapter->dev, "Unsupported transaction %d\n", size); + return -EOPNOTSUPP; } i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK @@ -1579,13 +1586,15 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, msg[num-1].len++; } - if (i2c_transfer(adapter, msg, num) < 0) - return -1; + status = i2c_transfer(adapter, msg, num); + if (status < 0) + return status; /* Check PEC if last message is a read */ if (i && (msg[num-1].flags & I2C_M_RD)) { - if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0) - return -1; + status = i2c_smbus_check_pec(partial_pec, &msg[num-1]); + if (status < 0) + return status; } if (read_write == I2C_SMBUS_READ) -- cgit v0.10.2 From f5b728a164b22ec38a5657ebe038def36ffae98b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:23 +0200 Subject: i2c: Group bus drivers by type The list of I2C/SMBus bus drivers is growing and it is sometimes difficult for the users to figure out what drivers they should enable. By grouping the drivers by type, I hope to make the selection easier. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 37f5b84..2b0874b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -4,6 +4,9 @@ menu "I2C Hardware Bus support" +comment "PC SMBus host controller drivers" + depends on PCI + config I2C_ALI1535 tristate "ALI 1535" depends on PCI @@ -73,93 +76,6 @@ config I2C_AMD8111 This driver can also be built as a module. If so, the module will be called i2c-amd8111. -config I2C_AT91 - tristate "Atmel AT91 I2C Two-Wire interface (TWI)" - depends on ARCH_AT91 && EXPERIMENTAL && BROKEN - help - This supports the use of the I2C interface on Atmel AT91 - processors. - - This driver is BROKEN because the controller which it uses - will easily trigger RX overrun and TX underrun errors. Using - low I2C clock rates may partially work around those issues - on some systems. Another serious problem is that there is no - documented way to issue repeated START conditions, as needed - to support combined I2C messages. Use the i2c-gpio driver - unless your system can cope with those limitations. - -config I2C_AU1550 - tristate "Au1550/Au1200 SMBus interface" - depends on SOC_AU1550 || SOC_AU1200 - help - If you say yes to this option, support will be included for the - Au1550 and Au1200 SMBus interface. - - This driver can also be built as a module. If so, the module - will be called i2c-au1550. - -config I2C_BLACKFIN_TWI - tristate "Blackfin TWI I2C support" - depends on BLACKFIN - depends on !BF561 && !BF531 && !BF532 && !BF533 - help - This is the I2C bus driver for Blackfin on-chip TWI interface. - - This driver can also be built as a module. If so, the module - will be called i2c-bfin-twi. - -config I2C_BLACKFIN_TWI_CLK_KHZ - int "Blackfin TWI I2C clock (kHz)" - depends on I2C_BLACKFIN_TWI - range 10 400 - default 50 - help - The unit of the TWI clock is kHz. - -config I2C_DAVINCI - tristate "DaVinci I2C driver" - depends on ARCH_DAVINCI - help - Support for TI DaVinci I2C controller driver. - - This driver can also be built as a module. If so, the module - will be called i2c-davinci. - - Please note that this driver might be needed to bring up other - devices such as DaVinci NIC. - For details please see http://www.ti.com/davinci - -config I2C_ELEKTOR - tristate "Elektor ISA card" - depends on ISA && BROKEN_ON_SMP - select I2C_ALGOPCF - help - This supports the PCF8584 ISA bus I2C adapter. Say Y if you own - such an adapter. - - This support is also available as a module. If so, the module - will be called i2c-elektor. - -config I2C_GPIO - tristate "GPIO-based bitbanging I2C" - depends on GENERIC_GPIO - select I2C_ALGOBIT - help - This is a very simple bitbanging I2C driver utilizing the - arch-neutral GPIO API to control the SCL and SDA lines. - -config I2C_HYDRA - tristate "CHRP Apple Hydra Mac I/O I2C interface" - depends on PCI && PPC_CHRP && EXPERIMENTAL - select I2C_ALGOBIT - help - This supports the use of the I2C interface in the Apple Hydra Mac - I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you - have such a machine. - - This support is also available as a module. If so, the module - will be called i2c-hydra. - config I2C_I801 tristate "Intel 82801 (ICH)" depends on PCI @@ -185,22 +101,6 @@ config I2C_I801 This driver can also be built as a module. If so, the module will be called i2c-i801. -config I2C_PXA - tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" - depends on EXPERIMENTAL && ARCH_PXA - help - If you have devices in the PXA I2C bus, say yes to this option. - This driver can also be built as a module. If so, the module - will be called i2c-pxa. - -config I2C_PXA_SLAVE - bool "Intel PXA2XX I2C Slave comms support" - depends on I2C_PXA - help - Support I2C slave mode communications on the PXA I2C bus. This - is necessary for systems where the PXA may be a target on the - I2C bus. - config I2C_PIIX4 tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" depends on PCI @@ -226,64 +126,6 @@ config I2C_PIIX4 This driver can also be built as a module. If so, the module will be called i2c-piix4. -config I2C_IBM_IIC - tristate "IBM PPC 4xx on-chip I2C interface" - depends on 4xx - help - Say Y here if you want to use IIC peripheral found on - embedded IBM PPC 4xx based systems. - - This driver can also be built as a module. If so, the module - will be called i2c-ibm_iic. - -config I2C_IOP3XX - tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" - depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX - help - Say Y here if you want to use the IIC bus controller on - the Intel IOPx3xx I/O Processors or IXP4xx Network Processors. - - This driver can also be built as a module. If so, the module - will be called i2c-iop3xx. - -config I2C_IXP2000 - tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)" - depends on ARCH_IXP2000 - select I2C_ALGOBIT - help - Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based - system and are using GPIO lines for an I2C bus. - - This support is also available as a module. If so, the module - will be called i2c-ixp2000. - - This driver is deprecated and will be dropped soon. Use i2c-gpio - instead. - -config I2C_POWERMAC - tristate "Powermac I2C interface" - depends on PPC_PMAC - default y - help - This exposes the various PowerMac i2c interfaces to the linux i2c - layer and to userland. It is used by various drivers on the PowerMac - platform, and should generally be enabled. - - This support is also available as a module. If so, the module - will be called i2c-powermac. - -config I2C_MPC - tristate "MPC107/824x/85xx/52xx/86xx" - depends on PPC32 - help - If you say yes to this option, support will be included for the - built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and - MPC85xx/MPC8641 family processors. The driver may also work on 52xx - family processors, though interrupts are known not to work. - - This driver can also be built as a module. If so, the module - will be called i2c-mpc. - config I2C_NFORCE2 tristate "Nvidia nForce2, nForce3 and nForce4" depends on PCI @@ -307,73 +149,243 @@ config I2C_NFORCE2_S4985 This driver can also be built as a module. If so, the module will be called i2c-nforce2-s4985. -config I2C_OCORES - tristate "OpenCores I2C Controller" - depends on EXPERIMENTAL +config I2C_SIS5595 + tristate "SiS 5595" + depends on PCI help If you say yes to this option, support will be included for the - OpenCores I2C controller. For details see - http://www.opencores.org/projects.cgi/web/i2c/overview + SiS5595 SMBus (a subset of I2C) interface. This driver can also be built as a module. If so, the module - will be called i2c-ocores. + will be called i2c-sis5595. -config I2C_OMAP - tristate "OMAP I2C adapter" - depends on ARCH_OMAP - default y if MACH_OMAP_H3 || MACH_OMAP_OSK +config I2C_SIS630 + tristate "SiS 630/730" + depends on PCI help If you say yes to this option, support will be included for the - I2C interface on the Texas Instruments OMAP1/2 family of processors. - Like OMAP1510/1610/1710/5912 and OMAP242x. - For details see http://www.ti.com/omap. + SiS630 and SiS730 SMBus (a subset of I2C) interface. -config I2C_PARPORT - tristate "Parallel port adapter" - depends on PARPORT + This driver can also be built as a module. If so, the module + will be called i2c-sis630. + +config I2C_SIS96X + tristate "SiS 96x" + depends on PCI + help + If you say yes to this option, support will be included for the SiS + 96x SMBus (a subset of I2C) interfaces. Specifically, the following + chipsets are supported: + 645/961 + 645DX/961 + 645DX/962 + 648/961 + 650/961 + 735 + 745 + + This driver can also be built as a module. If so, the module + will be called i2c-sis96x. + +config I2C_VIA + tristate "VIA VT82C586B" + depends on PCI && EXPERIMENTAL select I2C_ALGOBIT help - This supports parallel port I2C adapters such as the ones made by - Philips or Velleman, Analog Devices evaluation boards, and more. - Basically any adapter using the parallel port as an I2C bus with - no extra chipset is supported by this driver, or could be. + If you say yes to this option, support will be included for the VIA + 82C586B I2C interface - This driver is a replacement for (and was inspired by) an older - driver named i2c-philips-par. The new driver supports more devices, - and makes it easier to add support for new devices. + This driver can also be built as a module. If so, the module + will be called i2c-via. - An adapter type parameter is now mandatory. Please read the file - Documentation/i2c/busses/i2c-parport for details. +config I2C_VIAPRO + tristate "VIA VT82C596/82C686/82xx and CX700" + depends on PCI + help + If you say yes to this option, support will be included for the VIA + VT82C596 and later SMBus interface. Specifically, the following + chipsets are supported: + VT82C596A/B + VT82C686A/B + VT8231 + VT8233/A + VT8235 + VT8237R/A/S + VT8251 + CX700 - Another driver exists, named i2c-parport-light, which doesn't depend - on the parport driver. This is meant for embedded systems. Don't say - Y here if you intend to say Y or M there. + This driver can also be built as a module. If so, the module + will be called i2c-viapro. - This support is also available as a module. If so, the module - will be called i2c-parport. +comment "Mac SMBus host controller drivers" + depends on PPC_CHRP || PPC_PMAC -config I2C_PARPORT_LIGHT - tristate "Parallel port adapter (light)" +config I2C_HYDRA + tristate "CHRP Apple Hydra Mac I/O I2C interface" + depends on PCI && PPC_CHRP && EXPERIMENTAL select I2C_ALGOBIT help - This supports parallel port I2C adapters such as the ones made by - Philips or Velleman, Analog Devices evaluation boards, and more. - Basically any adapter using the parallel port as an I2C bus with - no extra chipset is supported by this driver, or could be. - - This driver is a light version of i2c-parport. It doesn't depend - on the parport driver, and uses direct I/O access instead. This - might be preferred on embedded systems where wasting memory for - the clean but heavy parport handling is not an option. The - drawback is a reduced portability and the impossibility to - daisy-chain other parallel port devices. + This supports the use of the I2C interface in the Apple Hydra Mac + I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you + have such a machine. - Don't say Y here if you said Y or M to i2c-parport. Saying M to - both is possible but both modules should not be loaded at the same - time. + This support is also available as a module. If so, the module + will be called i2c-hydra. + +config I2C_POWERMAC + tristate "Powermac I2C interface" + depends on PPC_PMAC + default y + help + This exposes the various PowerMac i2c interfaces to the linux i2c + layer and to userland. It is used by various drivers on the PowerMac + platform, and should generally be enabled. This support is also available as a module. If so, the module - will be called i2c-parport-light. + will be called i2c-powermac. + +comment "I2C system bus drivers (mostly embedded / system-on-chip)" + +config I2C_AT91 + tristate "Atmel AT91 I2C Two-Wire interface (TWI)" + depends on ARCH_AT91 && EXPERIMENTAL && BROKEN + help + This supports the use of the I2C interface on Atmel AT91 + processors. + + This driver is BROKEN because the controller which it uses + will easily trigger RX overrun and TX underrun errors. Using + low I2C clock rates may partially work around those issues + on some systems. Another serious problem is that there is no + documented way to issue repeated START conditions, as needed + to support combined I2C messages. Use the i2c-gpio driver + unless your system can cope with those limitations. + +config I2C_AU1550 + tristate "Au1550/Au1200 SMBus interface" + depends on SOC_AU1550 || SOC_AU1200 + help + If you say yes to this option, support will be included for the + Au1550 and Au1200 SMBus interface. + + This driver can also be built as a module. If so, the module + will be called i2c-au1550. + +config I2C_BLACKFIN_TWI + tristate "Blackfin TWI I2C support" + depends on BLACKFIN + depends on !BF561 && !BF531 && !BF532 && !BF533 + help + This is the I2C bus driver for Blackfin on-chip TWI interface. + + This driver can also be built as a module. If so, the module + will be called i2c-bfin-twi. + +config I2C_BLACKFIN_TWI_CLK_KHZ + int "Blackfin TWI I2C clock (kHz)" + depends on I2C_BLACKFIN_TWI + range 10 400 + default 50 + help + The unit of the TWI clock is kHz. + +config I2C_DAVINCI + tristate "DaVinci I2C driver" + depends on ARCH_DAVINCI + help + Support for TI DaVinci I2C controller driver. + + This driver can also be built as a module. If so, the module + will be called i2c-davinci. + + Please note that this driver might be needed to bring up other + devices such as DaVinci NIC. + For details please see http://www.ti.com/davinci + +config I2C_GPIO + tristate "GPIO-based bitbanging I2C" + depends on GENERIC_GPIO + select I2C_ALGOBIT + help + This is a very simple bitbanging I2C driver utilizing the + arch-neutral GPIO API to control the SCL and SDA lines. + +config I2C_IBM_IIC + tristate "IBM PPC 4xx on-chip I2C interface" + depends on 4xx + help + Say Y here if you want to use IIC peripheral found on + embedded IBM PPC 4xx based systems. + + This driver can also be built as a module. If so, the module + will be called i2c-ibm_iic. + +config I2C_IOP3XX + tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" + depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX + help + Say Y here if you want to use the IIC bus controller on + the Intel IOPx3xx I/O Processors or IXP4xx Network Processors. + + This driver can also be built as a module. If so, the module + will be called i2c-iop3xx. + +config I2C_IXP2000 + tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)" + depends on ARCH_IXP2000 + select I2C_ALGOBIT + help + Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based + system and are using GPIO lines for an I2C bus. + + This support is also available as a module. If so, the module + will be called i2c-ixp2000. + + This driver is deprecated and will be dropped soon. Use i2c-gpio + instead. + +config I2C_MPC + tristate "MPC107/824x/85xx/52xx/86xx" + depends on PPC32 + help + If you say yes to this option, support will be included for the + built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and + MPC85xx/MPC8641 family processors. The driver may also work on 52xx + family processors, though interrupts are known not to work. + + This driver can also be built as a module. If so, the module + will be called i2c-mpc. + +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges. + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. + +config I2C_OCORES + tristate "OpenCores I2C Controller" + depends on EXPERIMENTAL + help + If you say yes to this option, support will be included for the + OpenCores I2C controller. For details see + http://www.opencores.org/projects.cgi/web/i2c/overview + + This driver can also be built as a module. If so, the module + will be called i2c-ocores. + +config I2C_OMAP + tristate "OMAP I2C adapter" + depends on ARCH_OMAP + default y if MACH_OMAP_H3 || MACH_OMAP_OSK + help + If you say yes to this option, support will be included for the + I2C interface on the Texas Instruments OMAP1/2 family of processors. + Like OMAP1510/1610/1710/5912 and OMAP242x. + For details see http://www.ti.com/omap. config I2C_PASEMI tristate "PA Semi SMBus interface" @@ -381,6 +393,32 @@ config I2C_PASEMI help Supports the PA Semi PWRficient on-chip SMBus interfaces. +config I2C_PNX + tristate "I2C bus support for Philips PNX targets" + depends on ARCH_PNX4008 + help + This driver supports the Philips IP3204 I2C IP block master and/or + slave controller + + This driver can also be built as a module. If so, the module + will be called i2c-pnx. + +config I2C_PXA + tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" + depends on EXPERIMENTAL && ARCH_PXA + help + If you have devices in the PXA I2C bus, say yes to this option. + This driver can also be built as a module. If so, the module + will be called i2c-pxa. + +config I2C_PXA_SLAVE + bool "Intel PXA2XX I2C Slave comms support" + depends on I2C_PXA + help + Support I2C slave mode communications on the PXA I2C bus. This + is necessary for systems where the PXA may be a target on the + I2C bus. + config I2C_S3C2410 tristate "S3C2410 I2C Driver" depends on ARCH_S3C2410 @@ -388,11 +426,24 @@ config I2C_S3C2410 Say Y here to include support for I2C controller in the Samsung S3C2410 based System-on-Chip devices. -config I2C_SIBYTE - tristate "SiByte SMBus interface" - depends on SIBYTE_SB1xxx_SOC +config I2C_SH7760 + tristate "Renesas SH7760 I2C Controller" + depends on CPU_SUBTYPE_SH7760 help - Supports the SiByte SOC on-chip I2C interfaces (2 channels). + This driver supports the 2 I2C interfaces on the Renesas SH7760. + + This driver can also be built as a module. If so, the module + will be called i2c-sh7760. + +config I2C_SH_MOBILE + tristate "SuperH Mobile I2C Controller" + depends on SUPERH + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Renesas SH-Mobile processor. + + This driver can also be built as a module. If so, the module + will be called i2c-sh_mobile. config I2C_SIMTEC tristate "Simtec Generic I2C interface" @@ -406,86 +457,65 @@ config I2C_SIMTEC This driver can also be built as a module. If so, the module will be called i2c-simtec. -config SCx200_I2C - tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)" - depends on SCx200_GPIO +config I2C_VERSATILE + tristate "ARM Versatile/Realview I2C bus support" + depends on ARCH_VERSATILE || ARCH_REALVIEW select I2C_ALGOBIT help - Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. - - If you don't know what to do here, say N. + Say yes if you want to support the I2C serial bus on ARMs Versatile + range of platforms. - This support is also available as a module. If so, the module - will be called scx200_i2c. + This driver can also be built as a module. If so, the module + will be called i2c-versatile. - This driver is deprecated and will be dropped soon. Use i2c-gpio - (or scx200_acb) instead. +comment "External I2C/SMBus adapter drivers" -config SCx200_I2C_SCL - int "GPIO pin used for SCL" - depends on SCx200_I2C - default "12" +config I2C_PARPORT + tristate "Parallel port adapter" + depends on PARPORT + select I2C_ALGOBIT help - Enter the GPIO pin number used for the SCL signal. This value can - also be specified with a module parameter. + This supports parallel port I2C adapters such as the ones made by + Philips or Velleman, Analog Devices evaluation boards, and more. + Basically any adapter using the parallel port as an I2C bus with + no extra chipset is supported by this driver, or could be. -config SCx200_I2C_SDA - int "GPIO pin used for SDA" - depends on SCx200_I2C - default "13" - help - Enter the GPIO pin number used for the SSA signal. This value can - also be specified with a module parameter. + This driver is a replacement for (and was inspired by) an older + driver named i2c-philips-par. The new driver supports more devices, + and makes it easier to add support for new devices. -config SCx200_ACB - tristate "Geode ACCESS.bus support" - depends on X86_32 && PCI - help - Enable the use of the ACCESS.bus controllers on the Geode SCx200 and - SC1100 processors and the CS5535 and CS5536 Geode companion devices. + An adapter type parameter is now mandatory. Please read the file + Documentation/i2c/busses/i2c-parport for details. - If you don't know what to do here, say N. + Another driver exists, named i2c-parport-light, which doesn't depend + on the parport driver. This is meant for embedded systems. Don't say + Y here if you intend to say Y or M there. This support is also available as a module. If so, the module - will be called scx200_acb. - -config I2C_SIS5595 - tristate "SiS 5595" - depends on PCI - help - If you say yes to this option, support will be included for the - SiS5595 SMBus (a subset of I2C) interface. - - This driver can also be built as a module. If so, the module - will be called i2c-sis5595. + will be called i2c-parport. -config I2C_SIS630 - tristate "SiS 630/730" - depends on PCI +config I2C_PARPORT_LIGHT + tristate "Parallel port adapter (light)" + select I2C_ALGOBIT help - If you say yes to this option, support will be included for the - SiS630 and SiS730 SMBus (a subset of I2C) interface. + This supports parallel port I2C adapters such as the ones made by + Philips or Velleman, Analog Devices evaluation boards, and more. + Basically any adapter using the parallel port as an I2C bus with + no extra chipset is supported by this driver, or could be. - This driver can also be built as a module. If so, the module - will be called i2c-sis630. + This driver is a light version of i2c-parport. It doesn't depend + on the parport driver, and uses direct I/O access instead. This + might be preferred on embedded systems where wasting memory for + the clean but heavy parport handling is not an option. The + drawback is a reduced portability and the impossibility to + daisy-chain other parallel port devices. -config I2C_SIS96X - tristate "SiS 96x" - depends on PCI - help - If you say yes to this option, support will be included for the SiS - 96x SMBus (a subset of I2C) interfaces. Specifically, the following - chipsets are supported: - 645/961 - 645DX/961 - 645DX/962 - 648/961 - 650/961 - 735 - 745 + Don't say Y here if you said Y or M to i2c-parport. Saying M to + both is possible but both modules should not be loaded at the same + time. - This driver can also be built as a module. If so, the module - will be called i2c-sis96x. + This support is also available as a module. If so, the module + will be called i2c-parport-light. config I2C_TAOS_EVM tristate "TAOS evaluation module" @@ -503,21 +533,8 @@ config I2C_TAOS_EVM This support is also available as a module. If so, the module will be called i2c-taos-evm. -config I2C_STUB - tristate "I2C/SMBus Test Stub" - depends on EXPERIMENTAL && m - default 'n' - help - This module may be useful to developers of SMBus client drivers, - especially for certain kinds of sensor chips. - - If you do build this module, be sure to read the notes and warnings - in . - - If you don't know what to do here, definitely say N. - config I2C_TINY_USB - tristate "I2C-Tiny-USB" + tristate "Tiny-USB adapter" depends on USB help If you say yes to this option, support will be included for the @@ -527,16 +544,21 @@ config I2C_TINY_USB This driver can also be built as a module. If so, the module will be called i2c-tiny-usb. -config I2C_VERSATILE - tristate "ARM Versatile/Realview I2C bus support" - depends on ARCH_VERSATILE || ARCH_REALVIEW +comment "Graphics adapter I2C/DDC channel drivers" + depends on PCI + +config I2C_VOODOO3 + tristate "Voodoo 3" + depends on PCI select I2C_ALGOBIT help - Say yes if you want to support the I2C serial bus on ARMs Versatile - range of platforms. + If you say yes to this option, support will be included for the + Voodoo 3 I2C interface. This driver can also be built as a module. If so, the module - will be called i2c-versatile. + will be called i2c-voodoo3. + +comment "Other I2C/SMBus bus drivers" config I2C_ACORN tristate "Acorn IOC/IOMD I2C bus support" @@ -548,46 +570,16 @@ config I2C_ACORN If you don't know, say Y. -config I2C_VIA - tristate "VIA 82C586B" - depends on PCI && EXPERIMENTAL - select I2C_ALGOBIT - help - If you say yes to this option, support will be included for the VIA - 82C586B I2C interface - - This driver can also be built as a module. If so, the module - will be called i2c-via. - -config I2C_VIAPRO - tristate "VIA VT82C596/82C686/82xx and CX700" - depends on PCI - help - If you say yes to this option, support will be included for the VIA - VT82C596 and later SMBus interface. Specifically, the following - chipsets are supported: - VT82C596A/B - VT82C686A/B - VT8231 - VT8233/A - VT8235 - VT8237R/A/S - VT8251 - CX700 - - This driver can also be built as a module. If so, the module - will be called i2c-viapro. - -config I2C_VOODOO3 - tristate "Voodoo 3" - depends on PCI - select I2C_ALGOBIT +config I2C_ELEKTOR + tristate "Elektor ISA card" + depends on ISA && BROKEN_ON_SMP + select I2C_ALGOPCF help - If you say yes to this option, support will be included for the - Voodoo 3 I2C interface. + This supports the PCF8584 ISA bus I2C adapter. Say Y if you own + such an adapter. - This driver can also be built as a module. If so, the module - will be called i2c-voodoo3. + This support is also available as a module. If so, the module + will be called i2c-elektor. config I2C_PCA_ISA tristate "PCA9564 on an ISA bus" @@ -617,26 +609,6 @@ config I2C_PCA_PLATFORM This driver can also be built as a module. If so, the module will be called i2c-pca-platform. -config I2C_MV64XXX - tristate "Marvell mv64xxx I2C Controller" - depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL - help - If you say yes to this option, support will be included for the - built-in I2C interface on the Marvell 64xxx line of host bridges. - - This driver can also be built as a module. If so, the module - will be called i2c-mv64xxx. - -config I2C_PNX - tristate "I2C bus support for Philips PNX targets" - depends on ARCH_PNX4008 - help - This driver supports the Philips IP3204 I2C IP block master and/or - slave controller - - This driver can also be built as a module. If so, the module - will be called i2c-pnx. - config I2C_PMCMSP tristate "PMC MSP I2C TWI Controller" depends on PMC_MSP @@ -646,23 +618,66 @@ config I2C_PMCMSP This driver can also be built as module. If so, the module will be called i2c-pmcmsp. -config I2C_SH7760 - tristate "Renesas SH7760 I2C Controller" - depends on CPU_SUBTYPE_SH7760 +config I2C_SIBYTE + tristate "SiByte SMBus interface" + depends on SIBYTE_SB1xxx_SOC help - This driver supports the 2 I2C interfaces on the Renesas SH7760. + Supports the SiByte SOC on-chip I2C interfaces (2 channels). - This driver can also be built as a module. If so, the module - will be called i2c-sh7760. +config I2C_STUB + tristate "I2C/SMBus Test Stub" + depends on EXPERIMENTAL && m + default 'n' + help + This module may be useful to developers of SMBus client drivers, + especially for certain kinds of sensor chips. -config I2C_SH_MOBILE - tristate "SuperH Mobile I2C Controller" - depends on SUPERH + If you do build this module, be sure to read the notes and warnings + in . + + If you don't know what to do here, definitely say N. + +config SCx200_I2C + tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)" + depends on SCx200_GPIO + select I2C_ALGOBIT help - If you say yes to this option, support will be included for the - built-in I2C interface on the Renesas SH-Mobile processor. + Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. - This driver can also be built as a module. If so, the module - will be called i2c-sh_mobile. + If you don't know what to do here, say N. + + This support is also available as a module. If so, the module + will be called scx200_i2c. + + This driver is deprecated and will be dropped soon. Use i2c-gpio + (or scx200_acb) instead. + +config SCx200_I2C_SCL + int "GPIO pin used for SCL" + depends on SCx200_I2C + default "12" + help + Enter the GPIO pin number used for the SCL signal. This value can + also be specified with a module parameter. + +config SCx200_I2C_SDA + int "GPIO pin used for SDA" + depends on SCx200_I2C + default "13" + help + Enter the GPIO pin number used for the SSA signal. This value can + also be specified with a module parameter. + +config SCx200_ACB + tristate "Geode ACCESS.bus support" + depends on X86_32 && PCI + help + Enable the use of the ACCESS.bus controllers on the Geode SCx200 and + SC1100 processors and the CS5535 and CS5536 Geode companion devices. + + If you don't know what to do here, say N. + + This support is also available as a module. If so, the module + will be called scx200_acb. endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 81bb407..48a6a5b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -2,55 +2,66 @@ # Makefile for the i2c bus drivers. # +# PC SMBus host controller drivers obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o +obj-$(CONFIG_I2C_I801) += i2c-i801.o +obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o +obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o +obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o +obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o +obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o +obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o +obj-$(CONFIG_I2C_VIA) += i2c-via.o +obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o + +# Mac SMBus host controller drivers +obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o +obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o + +# Embebbed system I2C/SMBus host controller drivers obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o -obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o -obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o -obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o -obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o -obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o -obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o obj-$(CONFIG_I2C_OMAP) += i2c-omap.o -obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o -obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o -obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o -obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o -obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o -obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o obj-$(CONFIG_I2C_PNX) += i2c-pnx.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o -obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o -obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o -obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o -obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o -obj-$(CONFIG_I2C_STUB) += i2c-stub.o +obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o + +# External I2C/SMBus adapter drivers +obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o +obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o obj-$(CONFIG_I2C_TAOS_EVM) += i2c-taos-evm.o obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o -obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o -obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o -obj-$(CONFIG_I2C_VIA) += i2c-via.o -obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o + +# Graphics adapter I2C/DDC channel drivers obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o + +# Other I2C/SMBus bus drivers +obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o +obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o +obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o +obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o +obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o +obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o +obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o -- cgit v0.10.2 From 67c2e66571c383404a5acd08189194da660da942 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:23 +0200 Subject: i2c: Delete unused function i2c_smbus_write_quick Function i2c_smbus_write_quick has no users left, so we can delete it. Also update the list of these helper functions which are gone but could be added back if needed. Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/smbus-protocol b/Documentation/i2c/smbus-protocol index 03f08fb..24bfb65d 100644 --- a/Documentation/i2c/smbus-protocol +++ b/Documentation/i2c/smbus-protocol @@ -42,8 +42,8 @@ Count (8 bits): A data byte containing the length of a block operation. [..]: Data sent by I2C device, as opposed to data sent by the host adapter. -SMBus Quick Command: i2c_smbus_write_quick() -============================================= +SMBus Quick Command +=================== This sends a single bit to the device, at the place of the Rd/Wr bit. diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index ba5d197..63722d3 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -569,7 +569,6 @@ SMBus communication in terms of it. Never use this function directly! - extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value); extern s32 i2c_smbus_read_byte(struct i2c_client * client); extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value); extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command); @@ -578,20 +577,21 @@ SMBus communication extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); extern s32 i2c_smbus_write_word_data(struct i2c_client * client, u8 command, u16 value); + extern s32 i2c_smbus_read_block_data(struct i2c_client * client, + u8 command, u8 *values); extern s32 i2c_smbus_write_block_data(struct i2c_client * client, u8 command, u8 length, u8 *values); extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, u8 command, u8 length, u8 *values); - -These ones were removed in Linux 2.6.10 because they had no users, but could -be added back later if needed: - - extern s32 i2c_smbus_read_block_data(struct i2c_client * client, - u8 command, u8 *values); extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, u8 command, u8 length, u8 *values); + +These ones were removed from i2c-core because they had no users, but could +be added back later if needed: + + extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value); extern s32 i2c_smbus_process_call(struct i2c_client * client, u8 command, u16 value); extern s32 i2c_smbus_block_process_call(struct i2c_client *client, diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 937f1dc..3695a4a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1303,13 +1303,6 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) return 0; } -s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value) -{ - return i2c_smbus_xfer(client->adapter,client->addr,client->flags, - value,0,I2C_SMBUS_QUICK,NULL); -} -EXPORT_SYMBOL(i2c_smbus_write_quick); - s32 i2c_smbus_read_byte(struct i2c_client *client) { union i2c_smbus_data data; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 8dc7301..b3695f3 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -71,7 +71,6 @@ extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, /* Now follow the 'nice' access routines. These also document the calling conventions of smbus_access. */ -extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value); extern s32 i2c_smbus_read_byte(struct i2c_client * client); extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value); extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command); -- cgit v0.10.2 From ae7193f7fa3e1735ab70807eb6e35a2a6575623f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:24 +0200 Subject: i2c: Update stray references to smbus_access That function is actually named i2c_smbus_xfer. Signed-off-by: Jean Delvare diff --git a/include/linux/i2c.h b/include/linux/i2c.h index b3695f3..7c36d51 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -69,7 +69,7 @@ extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, union i2c_smbus_data * data); /* Now follow the 'nice' access routines. These also document the calling - conventions of smbus_access. */ + conventions of i2c_smbus_xfer. */ extern s32 i2c_smbus_read_byte(struct i2c_client * client); extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value); @@ -536,7 +536,7 @@ union i2c_smbus_data { /* and one more for user-space compatibility */ }; -/* smbus_access read or write markers */ +/* i2c_smbus_xfer read or write markers */ #define I2C_SMBUS_READ 1 #define I2C_SMBUS_WRITE 0 -- cgit v0.10.2 From a1cdedac634eef81f747078bf1c27ad36ab13553 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:24 +0200 Subject: i2c: Kerneldoc for most I/O calls Provide kerneldoc for most of the I2C and SMBus I/O calls. Add a comment summarizing some fault reporting issues which affect the ability to provide clean fault reports through I2C master transfer calls. (Making it hard to precisely specify their return values...) Signed-off-by: David Brownell Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 3695a4a..527d513 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -945,10 +945,39 @@ module_exit(i2c_exit); * ---------------------------------------------------- */ +/** + * i2c_transfer - execute a single or combined I2C message + * @adap: Handle to I2C bus + * @msgs: One or more messages to execute before STOP is issued to + * terminate the operation; each message begins with a START. + * @num: Number of messages to be executed. + * + * Returns negative errno, else the number of messages executed. + * + * Note that there is no requirement that each message be sent to + * the same slave address, although that is the most common model. + */ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) { int ret; + /* REVISIT the fault reporting model here is weak: + * + * - When we get an error after receiving N bytes from a slave, + * there is no way to report "N". + * + * - When we get a NAK after transmitting N bytes to a slave, + * there is no way to report "N" ... or to let the master + * continue executing the rest of this combined message, if + * that's the appropriate response. + * + * - When for example "num" is two and we successfully complete + * the first message but get an error part way through the + * second, it's unclear whether that should be reported as + * one (discarding status on the second message) or errno + * (discarding status on the first one). + */ + if (adap->algo->master_xfer) { #ifdef DEBUG for (ret = 0; ret < num; ret++) { @@ -979,6 +1008,14 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) } EXPORT_SYMBOL(i2c_transfer); +/** + * i2c_master_send - issue a single I2C message in master transmit mode + * @client: Handle to slave device + * @buf: Data that will be written to the slave + * @count: How many bytes to write + * + * Returns negative errno, or else the number of bytes written. + */ int i2c_master_send(struct i2c_client *client,const char *buf ,int count) { int ret; @@ -998,6 +1035,14 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count) } EXPORT_SYMBOL(i2c_master_send); +/** + * i2c_master_recv - issue a single I2C message in master receive mode + * @client: Handle to slave device + * @buf: Where to store data read from slave + * @count: How many bytes to read + * + * Returns negative errno, or else the number of bytes read. + */ int i2c_master_recv(struct i2c_client *client, char *buf ,int count) { struct i2c_adapter *adap=client->adapter; @@ -1303,6 +1348,13 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) return 0; } +/** + * i2c_smbus_read_byte - SMBus "receive byte" protocol + * @client: Handle to slave device + * + * This executes the SMBus "receive byte" protocol, returning negative errno + * else the byte received from the device. + */ s32 i2c_smbus_read_byte(struct i2c_client *client) { union i2c_smbus_data data; @@ -1315,6 +1367,14 @@ s32 i2c_smbus_read_byte(struct i2c_client *client) } EXPORT_SYMBOL(i2c_smbus_read_byte); +/** + * i2c_smbus_write_byte - SMBus "send byte" protocol + * @client: Handle to slave device + * @value: Byte to be sent + * + * This executes the SMBus "send byte" protocol, returning negative errno + * else zero on success. + */ s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter,client->addr,client->flags, @@ -1322,6 +1382,14 @@ s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) } EXPORT_SYMBOL(i2c_smbus_write_byte); +/** + * i2c_smbus_read_byte_data - SMBus "read byte" protocol + * @client: Handle to slave device + * @command: Byte interpreted by slave + * + * This executes the SMBus "read byte" protocol, returning negative errno + * else a data byte received from the device. + */ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) { union i2c_smbus_data data; @@ -1334,6 +1402,15 @@ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) } EXPORT_SYMBOL(i2c_smbus_read_byte_data); +/** + * i2c_smbus_write_byte_data - SMBus "write byte" protocol + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @value: Byte being written + * + * This executes the SMBus "write byte" protocol, returning negative errno + * else zero on success. + */ s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) { union i2c_smbus_data data; @@ -1344,6 +1421,14 @@ s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) } EXPORT_SYMBOL(i2c_smbus_write_byte_data); +/** + * i2c_smbus_read_word_data - SMBus "read word" protocol + * @client: Handle to slave device + * @command: Byte interpreted by slave + * + * This executes the SMBus "read word" protocol, returning negative errno + * else a 16-bit unsigned "word" received from the device. + */ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) { union i2c_smbus_data data; @@ -1356,6 +1441,15 @@ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) } EXPORT_SYMBOL(i2c_smbus_read_word_data); +/** + * i2c_smbus_write_word_data - SMBus "write word" protocol + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @value: 16-bit "word" being written + * + * This executes the SMBus "write word" protocol, returning negative errno + * else zero on success. + */ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) { union i2c_smbus_data data; @@ -1367,15 +1461,14 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) EXPORT_SYMBOL(i2c_smbus_write_word_data); /** - * i2c_smbus_read_block_data - SMBus block read request + * i2c_smbus_read_block_data - SMBus "block read" protocol * @client: Handle to slave device - * @command: Command byte issued to let the slave know what data should - * be returned + * @command: Byte interpreted by slave * @values: Byte array into which data will be read; big enough to hold * the data returned by the slave. SMBus allows at most 32 bytes. * - * Returns the number of bytes read in the slave's response, else a - * negative number to indicate some kind of error. + * This executes the SMBus "block read" protocol, returning negative errno + * else the number of data bytes in the slave's response. * * Note that using this function requires that the client's adapter support * the I2C_FUNC_SMBUS_READ_BLOCK_DATA functionality. Not all adapter drivers @@ -1399,6 +1492,16 @@ s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command, } EXPORT_SYMBOL(i2c_smbus_read_block_data); +/** + * i2c_smbus_write_block_data - SMBus "block write" protocol + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @length: Size of data block; SMBus allows at most 32 bytes + * @values: Byte array which will be written. + * + * This executes the SMBus "block write" protocol, returning negative errno + * else zero on success. + */ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, u8 length, const u8 *values) { @@ -1615,9 +1718,21 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, return 0; } - +/** + * i2c_smbus_xfer - execute SMBus protocol operations + * @adapter: Handle to I2C bus + * @addr: Address of SMBus slave on that bus + * @flags: I2C_CLIENT_* flags (usually zero or I2C_CLIENT_PEC) + * @read_write: I2C_SMBUS_READ or I2C_SMBUS_WRITE + * @command: Byte interpreted by slave, for protocols which use such bytes + * @protocol: SMBus protocol operation to execute, such as I2C_SMBUS_PROC_CALL + * @data: Data to be read or written + * + * This executes an SMBus protocol operation, and returns a negative + * errno code else zero on success. + */ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, - char read_write, u8 command, int size, + char read_write, u8 command, int protocol, union i2c_smbus_data * data) { s32 res; @@ -1627,11 +1742,11 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, if (adapter->algo->smbus_xfer) { mutex_lock(&adapter->bus_lock); res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, - command,size,data); + command, protocol, data); mutex_unlock(&adapter->bus_lock); } else res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, - command,size,data); + command, protocol, data); return res; } -- cgit v0.10.2 From 6ea438ec8da4ec56bf415f5ea360e6b0cb59c6c3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:24 +0200 Subject: i2c: i2c_use_client() defends against NULL Defend the i2c refcount calls against NULL pointers, as is important (and conventional) for such calls. Note that none of the current callers of i2c_use_client() use its return value. [JD: I hate this but apparently all the other subsystems do it so...] Signed-off-by: David Brownell Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 527d513..b995502 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -866,8 +866,9 @@ EXPORT_SYMBOL(i2c_detach_client); */ struct i2c_client *i2c_use_client(struct i2c_client *client) { - get_device(&client->dev); - return client; + if (client && get_device(&client->dev)) + return client; + return NULL; } EXPORT_SYMBOL(i2c_use_client); @@ -879,7 +880,8 @@ EXPORT_SYMBOL(i2c_use_client); */ void i2c_release_client(struct i2c_client *client) { - put_device(&client->dev); + if (client) + put_device(&client->dev); } EXPORT_SYMBOL(i2c_release_client); -- cgit v0.10.2 From 97140342e69d479a3ad82bfd4c154c0b08fe3eea Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: i2c: Bus drivers return -Errno not -1 Tighten error paths used by various i2c adapters (mostly x86) so they return real fault/errno codes instead of a "-1" (which is most often interpreted as "-EPERM"). Build tested, with eyeball review. One minor initial goal is to have adapters consistently return the code "-ENXIO" when addressing a device doesn't get an ACK response, at least in the probe paths where they are already good at stifling related logspam. Signed-off-by: David Brownell Signed-off-by: Jean Delvare diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 3581282..eb8f72c 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -320,7 +320,7 @@ static int try_address(struct i2c_adapter *i2c_adap, unsigned char addr, int retries) { struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - int i, ret = -1; + int i, ret = 0; for (i = 0; i <= retries; i++) { ret = i2c_outb(i2c_adap, addr); @@ -508,7 +508,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) addr ^= 1; ret = try_address(i2c_adap, addr, retries); if ((ret != 1) && !nak_ok) - return -EREMOTEIO; + return -ENXIO; } return 0; diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index f14372a..c21e4d9 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -259,7 +259,7 @@ static int ali1535_transaction(struct i2c_adapter *adap) dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - controller or " "device on bus is probably hung\n", temp); - return -1; + return -EBUSY; } } else { /* check and clear done bit */ @@ -281,12 +281,12 @@ static int ali1535_transaction(struct i2c_adapter *adap) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { - result = -1; + result = -ETIMEDOUT; dev_err(&adap->dev, "SMBus Timeout!\n"); } if (temp & ALI1535_STS_FAIL) { - result = -1; + result = -EIO; dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); } @@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2c_adapter *adap) * do a printk. This means that bus collisions go unreported. */ if (temp & ALI1535_STS_BUSERR) { - result = -1; + result = -ENXIO; dev_dbg(&adap->dev, "Error: no response or bus collision ADD=%02x\n", inb_p(SMBHSTADD)); @@ -303,13 +303,13 @@ static int ali1535_transaction(struct i2c_adapter *adap) /* haven't ever seen this */ if (temp & ALI1535_STS_DEV) { - result = -1; + result = -EIO; dev_err(&adap->dev, "Error: device error\n"); } /* check to see if the "command complete" indication is set */ if (!(temp & ALI1535_STS_DONE)) { - result = -1; + result = -ETIMEDOUT; dev_err(&adap->dev, "Error: command never completed\n"); } @@ -332,7 +332,7 @@ static int ali1535_transaction(struct i2c_adapter *adap) return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) @@ -359,7 +359,7 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, switch (size) { case I2C_SMBUS_PROC_CALL: dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - result = -1; + result = -EOPNOTSUPP; goto EXIT; case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), @@ -420,11 +420,9 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, break; } - if (ali1535_transaction(adap)) { - /* Error in transaction */ - result = -1; + result = ali1535_transaction(adap); + if (result) goto EXIT; - } if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) { result = 0; diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 6b68074..30bd3ee 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -67,6 +67,7 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) { u32 data; int timeout; + int status = -EIO; dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, " "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", @@ -103,13 +104,15 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) /* Issue 'kill' to host controller */ outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); data = inb_p(SMB_HST_STS); + status = -ETIMEDOUT; } /* device error - no response, ignore the autodetection case */ - if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { - dev_err(&a->dev, "Device error!\n"); + if (data & HST_STS_DEVERR) { + if (size != HST_CNTL2_QUICK) + dev_err(&a->dev, "Device error!\n"); + status = -ENXIO; } - /* bus collision */ if (data & HST_STS_BUSERR) { dev_err(&a->dev, "Bus collision!\n"); @@ -122,13 +125,14 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) outb_p(0x0,SMB_HST_CNTL2); } - return -1; + return status; } static int ali1563_block_start(struct i2c_adapter * a) { u32 data; int timeout; + int status = -EIO; dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, " "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", @@ -164,13 +168,20 @@ static int ali1563_block_start(struct i2c_adapter * a) if (timeout && !(data & HST_STS_BAD)) return 0; + + if (timeout == 0) + status = -ETIMEDOUT; + + if (data & HST_STS_DEVERR) + status = -ENXIO; + dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", - timeout ? "Timeout " : "", + timeout ? "" : "Timeout ", data & HST_STS_FAIL ? "Transaction Failed " : "", data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "", !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); - return -1; + return status; } static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw) diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 93bf87d..3d75256 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -282,7 +282,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap) dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - " "controller or device on bus is probably hung\n", temp); - return -1; + return -EBUSY; } } else { /* check and clear done bit */ @@ -304,12 +304,12 @@ static int ali15x3_transaction(struct i2c_adapter *adap) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { - result = -1; + result = -ETIMEDOUT; dev_err(&adap->dev, "SMBus Timeout!\n"); } if (temp & ALI15X3_STS_TERM) { - result = -1; + result = -EIO; dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); } @@ -320,7 +320,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap) This means that bus collisions go unreported. */ if (temp & ALI15X3_STS_COLL) { - result = -1; + result = -ENXIO; dev_dbg(&adap->dev, "Error: no response or bus collision ADD=%02x\n", inb_p(SMBHSTADD)); @@ -328,7 +328,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap) /* haven't ever seen this */ if (temp & ALI15X3_STS_DEV) { - result = -1; + result = -EIO; dev_err(&adap->dev, "Error: device error\n"); } dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, " @@ -338,7 +338,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap) return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) @@ -364,7 +364,7 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr, switch (size) { case I2C_SMBUS_PROC_CALL: dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - return -1; + return -EOPNOTSUPP; case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); @@ -421,8 +421,9 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr, outb_p(size, SMBHSTCNT); /* output command */ - if (ali15x3_transaction(adap)) /* Error in transaction */ - return -1; + temp = ali15x3_transaction(adap); + if (temp) + return temp; if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK)) return 0; diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index c38a0a1..2f150e3 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr, /* We exclude the multiplexed addresses */ if (addr == 0x4c || (addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30 || addr == 0x18) - return -1; + return -ENXIO; mutex_lock(&amd756_lock); @@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr, /* We exclude the non-multiplexed addresses */ if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30) - return -1; + return -ENXIO; mutex_lock(&amd756_lock); diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 43508d6..3d5bcb6 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c_adapter *adap) } if (temp & GS_PRERR_STS) { - result = -1; + result = -ENXIO; dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); } if (temp & GS_COL_STS) { - result = -1; + result = -EIO; dev_warn(&adap->dev, "SMBus collision!\n"); } if (temp & GS_TO_STS) { - result = -1; + result = -ETIMEDOUT; dev_dbg(&adap->dev, "SMBus protocol timeout!\n"); } @@ -189,22 +189,23 @@ static int amd756_transaction(struct i2c_adapter *adap) outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); msleep(100); outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); - return -1; + return -EIO; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 amd756_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { int i, len; + int status; /** TODO: Should I supporte the 10-bit transfers? */ switch (size) { case I2C_SMBUS_PROC_CALL: dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); /* TODO: Well... It is supported, I'm just not sure what to do here... */ - return -1; + return -EOPNOTSUPP; case I2C_SMBUS_QUICK: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); @@ -256,8 +257,9 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr, /* How about enabling interrupts... */ outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); - if (amd756_transaction(adap)) /* Error in transaction */ - return -1; + status = amd756_transaction(adap); + if (status) + return status; if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) return 0; diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 5d1a27e..a4f6879 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -77,7 +77,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) if (!timeout) { dev_warn(&smbus->dev->dev, "Timeout while waiting for IBF to clear\n"); - return -1; + return -ETIMEDOUT; } return 0; @@ -93,7 +93,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) if (!timeout) { dev_warn(&smbus->dev->dev, "Timeout while waiting for OBF to set\n"); - return -1; + return -ETIMEDOUT; } return 0; @@ -102,16 +102,21 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, unsigned char *data) { - if (amd_ec_wait_write(smbus)) - return -1; + int status; + + status = amd_ec_wait_write(smbus); + if (status) + return status; outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD); - if (amd_ec_wait_write(smbus)) - return -1; + status = amd_ec_wait_write(smbus); + if (status) + return status; outb(address, smbus->base + AMD_EC_DATA); - if (amd_ec_wait_read(smbus)) - return -1; + status = amd_ec_wait_read(smbus); + if (status) + return status; *data = inb(smbus->base + AMD_EC_DATA); return 0; @@ -120,16 +125,21 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, unsigned char data) { - if (amd_ec_wait_write(smbus)) - return -1; + int status; + + status = amd_ec_wait_write(smbus); + if (status) + return status; outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD); - if (amd_ec_wait_write(smbus)) - return -1; + status = amd_ec_wait_write(smbus); + if (status) + return status; outb(address, smbus->base + AMD_EC_DATA); - if (amd_ec_wait_write(smbus)) - return -1; + status = amd_ec_wait_write(smbus); + if (status) + return status; outb(data, smbus->base + AMD_EC_DATA); return 0; @@ -267,12 +277,17 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, default: dev_warn(&adap->dev, "Unsupported transaction %d\n", size); - return -1; + return -EOPNOTSUPP; } amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1); amd_ec_write(smbus, AMD_SMB_PRTCL, protocol); + /* FIXME this discards status from ec_read(); so temp[0] will + * hold stack garbage ... the rest of this routine will act + * nonsensically. Ignored ec_write() status might explain + * some such failures... + */ amd_ec_read(smbus, AMD_SMB_STS, temp + 0); if (~temp[0] & AMD_SMB_STS_DONE) { @@ -286,7 +301,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, } if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS)) - return -1; + return -EIO; if (read_write == I2C_SMBUS_WRITE) return 0; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index b0f771f..7d6d9df 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -151,7 +151,7 @@ static int i801_transaction(int xact) outb_p(temp, SMBHSTSTS); if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp); - return -1; + return -EBUSY; } else { dev_dbg(&I801_dev->dev, "Successful!\n"); } @@ -170,7 +170,7 @@ static int i801_transaction(int xact) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); - result = -1; + result = -ETIMEDOUT; /* try to stop the current command */ dev_dbg(&I801_dev->dev, "Terminating the current operation\n"); outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT); @@ -179,19 +179,19 @@ static int i801_transaction(int xact) } if (temp & SMBHSTSTS_FAILED) { - result = -1; + result = -EIO; dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); } if (temp & SMBHSTSTS_BUS_ERR) { - result = -1; + result = -EIO; dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " "until next hard reset. (sorry!)\n"); /* Clock stops and slave is stuck in mid-transmission */ } if (temp & SMBHSTSTS_DEV_ERR) { - result = -1; + result = -ENXIO; dev_dbg(&I801_dev->dev, "Error: no response!\n"); } @@ -231,6 +231,7 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data, char read_write, int hwpec) { int i, len; + int status; inb_p(SMBHSTCNT); /* reset the data buffer index */ @@ -242,14 +243,15 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data, outb_p(data->block[i+1], SMBBLKDAT); } - if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 | - I801_PEC_EN * hwpec)) - return -1; + status = i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 | + I801_PEC_EN * hwpec); + if (status) + return status; if (read_write == I2C_SMBUS_READ) { len = inb_p(SMBHSTDAT0); if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) - return -1; + return -EPROTO; data->block[0] = len; for (i = 0; i < len; i++) @@ -314,11 +316,11 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { dev_err(&I801_dev->dev, "Reset failed! (%02x)\n", temp); - return -1; + return -EBUSY; } if (i != 1) /* if die in middle of block transaction, fail */ - return -1; + return -EIO; } if (i == 1) @@ -342,19 +344,19 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, msleep(1); outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT); - result = -1; + result = -ETIMEDOUT; dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); } if (temp & SMBHSTSTS_FAILED) { - result = -1; + result = -EIO; dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); } else if (temp & SMBHSTSTS_BUS_ERR) { - result = -1; + result = -EIO; dev_err(&I801_dev->dev, "Bus collision!\n"); } else if (temp & SMBHSTSTS_DEV_ERR) { - result = -1; + result = -ENXIO; dev_dbg(&I801_dev->dev, "Error: no response!\n"); } @@ -362,7 +364,7 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, && command != I2C_SMBUS_I2C_BLOCK_DATA) { len = inb_p(SMBHSTDAT0); if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) - return -1; + return -EPROTO; data->block[0] = len; } @@ -394,7 +396,7 @@ static int i801_set_block_buffer_mode(void) { outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL); if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0) - return -1; + return -EIO; return 0; } @@ -414,7 +416,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) { dev_err(&I801_dev->dev, "I2C block read is unsupported!\n"); - return -1; + return -EOPNOTSUPP; } } @@ -449,7 +451,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 i801_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) @@ -514,7 +516,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, case I2C_SMBUS_PROC_CALL: default: dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); - return -1; + return -EOPNOTSUPP; } if (hwpec) /* enable/disable hardware PEC */ @@ -537,7 +539,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, if(block) return ret; if(ret) - return -1; + return ret; if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) return 0; diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index f95efff..081fdf3 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -172,16 +172,16 @@ static int nforce2_check_status(struct i2c_adapter *adap) dev_dbg(&adap->dev, "SMBus Timeout!\n"); if (smbus->can_abort) nforce2_abort(adap); - return -1; + return -ETIMEDOUT; } if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) { dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp); - return -1; + return -EIO; } return 0; } -/* Return -1 on error */ +/* Return negative errno on error */ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) @@ -189,7 +189,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, struct nforce2_smbus *smbus = adap->algo_data; unsigned char protocol, pec; u8 len; - int i; + int i, status; protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ : NVIDIA_SMB_PRTCL_WRITE; @@ -233,7 +233,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, "Transaction failed " "(requested block size: %d)\n", len); - return -1; + return -EINVAL; } outb_p(len, NVIDIA_SMB_BCNT); for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++) @@ -245,14 +245,15 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, default: dev_err(&adap->dev, "Unsupported transaction %d\n", size); - return -1; + return -EOPNOTSUPP; } outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR); outb_p(protocol, NVIDIA_SMB_PRTCL); - if (nforce2_check_status(adap)) - return -1; + status = nforce2_check_status(adap); + if (status) + return status; if (read_write == I2C_SMBUS_WRITE) return 0; @@ -274,7 +275,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, dev_err(&adap->dev, "Transaction failed " "(received block size: 0x%02x)\n", len); - return -1; + return -EPROTO; } for (i = 0; i < len; i++) data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i); @@ -335,7 +336,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, != PCIBIOS_SUCCESSFUL) { dev_err(&dev->dev, "Error reading PCI config for %s\n", name); - return -1; + return -EIO; } smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK; @@ -345,7 +346,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", smbus->base, smbus->base+smbus->size-1, name); - return -1; + return -EBUSY; } smbus->adapter.owner = THIS_MODULE; smbus->adapter.id = I2C_HW_SMBUS_NFORCE2; @@ -360,7 +361,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, if (error) { dev_err(&smbus->adapter.dev, "Failed to register adapter.\n"); release_region(smbus->base, smbus->size); - return -1; + return error; } dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base); return 0; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index ac91659..dc76c0e 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -253,7 +253,7 @@ static int piix4_transaction(void) outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) != 0x00) { dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp); - return -1; + return -EBUSY; } else { dev_dbg(&piix4_adapter.dev, "Successful!\n"); } @@ -275,23 +275,23 @@ static int piix4_transaction(void) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_err(&piix4_adapter.dev, "SMBus Timeout!\n"); - result = -1; + result = -ETIMEDOUT; } if (temp & 0x10) { - result = -1; + result = -EIO; dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n"); } if (temp & 0x08) { - result = -1; + result = -EIO; dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n"); /* Clock stops and slave is stuck in mid-transmission */ } if (temp & 0x04) { - result = -1; + result = -ENXIO; dev_dbg(&piix4_adapter.dev, "Error: no response!\n"); } @@ -309,17 +309,18 @@ static int piix4_transaction(void) return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { int i, len; + int status; switch (size) { case I2C_SMBUS_PROC_CALL: dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - return -1; + return -EOPNOTSUPP; case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); @@ -371,8 +372,9 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); - if (piix4_transaction()) /* Error in transaction */ - return -1; + status = piix4_transaction(); + if (status) + return status; if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK)) return 0; diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 9ca8f91..328441b 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -236,7 +236,7 @@ static int sis5595_transaction(struct i2c_adapter *adap) sis5595_write(SMB_STS_HI, temp >> 8); if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) { dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); - return -1; + return -EBUSY; } else { dev_dbg(&adap->dev, "Successful!\n"); } @@ -254,19 +254,19 @@ static int sis5595_transaction(struct i2c_adapter *adap) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&adap->dev, "SMBus Timeout!\n"); - result = -1; + result = -ETIMEDOUT; } if (temp & 0x10) { dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); - result = -1; + result = -ENXIO; } if (temp & 0x20) { dev_err(&adap->dev, "Bus collision! SMBus may be locked until " "next hard reset (or not...)\n"); /* Clock stops and slave is stuck in mid-transmission */ - result = -1; + result = -EIO; } temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8); @@ -282,11 +282,13 @@ static int sis5595_transaction(struct i2c_adapter *adap) return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis5595_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { + int status; + switch (size) { case I2C_SMBUS_QUICK: sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); @@ -318,13 +320,14 @@ static s32 sis5595_access(struct i2c_adapter *adap, u16 addr, break; default: dev_warn(&adap->dev, "Unsupported transaction %d\n", size); - return -1; + return -EOPNOTSUPP; } sis5595_write(SMB_CTL_LO, ((size & 0x0E))); - if (sis5595_transaction(adap)) - return -1; + status = sis5595_transaction(adap); + if (status) + return status; if ((size != SIS5595_PROC_CALL) && ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK))) diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 3765dd7..c4cc5ed 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -134,7 +134,7 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); - return -1; + return -EBUSY; } else { dev_dbg(&adap->dev, "Successful!\n"); } @@ -177,17 +177,17 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&adap->dev, "SMBus Timeout!\n"); - result = -1; + result = -ETIMEDOUT; } if (temp & 0x02) { dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); - result = -1; + result = -ENXIO; } if (temp & 0x04) { dev_err(&adap->dev, "Bus collision!\n"); - result = -1; + result = -EIO; /* TBD: Datasheet say: the software should clear this bit and restart SMBUS operation. @@ -250,8 +250,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat if (i==8 || (len<8 && i==len)) { dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i); /* first transaction */ - if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) - return -1; + rc = sis630_transaction_start(adap, + SIS630_BLOCK_DATA, &oldclock); + if (rc) + return rc; } else if ((i-1)%8 == 7 || i==len) { dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i); @@ -264,9 +266,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat */ sis630_write(SMB_STS,0x10); } - if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { + rc = sis630_transaction_wait(adap, + SIS630_BLOCK_DATA); + if (rc) { dev_dbg(&adap->dev, "trans_wait failed\n"); - rc = -1; break; } } @@ -275,13 +278,14 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat else { /* read request */ data->block[0] = len = 0; - if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) { - return -1; - } + rc = sis630_transaction_start(adap, + SIS630_BLOCK_DATA, &oldclock); + if (rc) + return rc; do { - if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { + rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA); + if (rc) { dev_dbg(&adap->dev, "trans_wait failed\n"); - rc = -1; break; } /* if this first transaction then read byte count */ @@ -311,11 +315,13 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat return rc; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { + int status; + switch (size) { case I2C_SMBUS_QUICK: sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); @@ -350,13 +356,13 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, size = SIS630_BLOCK_DATA; return sis630_block_data(adap, data, read_write); default: - printk("Unsupported I2C size\n"); - return -1; - break; + printk("Unsupported SMBus operation\n"); + return -EOPNOTSUPP; } - if (sis630_transaction(adap, size)) - return -1; + status = sis630_transaction(adap, size); + if (status) + return status; if ((size != SIS630_PCALL) && ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) { @@ -373,8 +379,7 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); break; default: - return -1; - break; + return -EOPNOTSUPP; } return 0; diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index dc235bb..29757b2 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -111,7 +111,7 @@ static int sis96x_transaction(int size) /* check it again */ if (((temp = sis96x_read(SMB_CNT)) & 0x03) != 0x00) { dev_dbg(&sis96x_adapter.dev, "Failed (0x%02x)\n", temp); - return -1; + return -EBUSY; } else { dev_dbg(&sis96x_adapter.dev, "Successful\n"); } @@ -136,19 +136,19 @@ static int sis96x_transaction(int size) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&sis96x_adapter.dev, "SMBus Timeout! (0x%02x)\n", temp); - result = -1; + result = -ETIMEDOUT; } /* device error - probably missing ACK */ if (temp & 0x02) { dev_dbg(&sis96x_adapter.dev, "Failed bus transaction!\n"); - result = -1; + result = -ENXIO; } /* bus collision */ if (temp & 0x04) { dev_dbg(&sis96x_adapter.dev, "Bus collision!\n"); - result = -1; + result = -EIO; } /* Finish up by resetting the bus */ @@ -161,11 +161,12 @@ static int sis96x_transaction(int size) return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis96x_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { + int status; switch (size) { case I2C_SMBUS_QUICK: @@ -203,17 +204,17 @@ static s32 sis96x_access(struct i2c_adapter * adap, u16 addr, case I2C_SMBUS_BLOCK_DATA: /* TO DO: */ dev_info(&adap->dev, "SMBus block not implemented!\n"); - return -1; + return -EOPNOTSUPP; break; default: - dev_info(&adap->dev, "Unsupported I2C size\n"); - return -1; - break; + dev_info(&adap->dev, "Unsupported SMBus operation\n"); + return -EOPNOTSUPP; } - if (sis96x_transaction(size)) - return -1; + status = sis96x_transaction(size); + if (status) + return status; if ((size != SIS96x_PROC_CALL) && ((read_write == I2C_SMBUS_WRITE) || (size == SIS96x_QUICK))) diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index d08eeec..e37ccd8 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c @@ -43,7 +43,7 @@ struct stub_chip { static struct stub_chip *stub_chips; -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { @@ -120,7 +120,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, default: dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); - ret = -1; + ret = -EOPNOTSUPP; break; } /* switch (size) */ diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 77b13d0..7628fe8 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -152,7 +152,7 @@ static int vt596_transaction(u8 size) if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_err(&vt596_adapter.dev, "SMBus reset failed! " "(0x%02x)\n", temp); - return -1; + return -EBUSY; } } @@ -167,24 +167,24 @@ static int vt596_transaction(u8 size) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { - result = -1; + result = -ETIMEDOUT; dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); } if (temp & 0x10) { - result = -1; + result = -EIO; dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", size); } if (temp & 0x08) { - result = -1; + result = -EIO; dev_err(&vt596_adapter.dev, "SMBus collision!\n"); } if (temp & 0x04) { int read = inb_p(SMBHSTADD) & 0x01; - result = -1; + result = -ENXIO; /* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */ @@ -202,12 +202,13 @@ static int vt596_transaction(u8 size) return result; } -/* Return -1 on error, 0 on success */ +/* Return negative errno on error, 0 on success */ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { int i; + int status; switch (size) { case I2C_SMBUS_QUICK: @@ -258,8 +259,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD); - if (vt596_transaction(size)) /* Error in transaction */ - return -1; + status = vt596_transaction(size); + if (status) + return status; if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) return 0; @@ -287,7 +289,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, exit_unsupported: dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n", size); - return -1; + return -EOPNOTSUPP; } static u32 vt596_func(struct i2c_adapter *adapter) -- cgit v0.10.2 From fa63cd56d2f09806169307d761e8f430e23bc09b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: i2c-piix4: Various cleanups and minor fixes The i2c-piix4 driver was used recently as a model to write a new SMBus host controller driver and this made me realize that the code of this old driver wasn't exactly good. So, here are many cleanups and minor fixes to this driver, so that these minor mistakes aren't duplicated again: * Delete unused structure. * Delete needless forward function declaration. * Properly announce the SMBus host controller as we find it. * Spell it SMBus not SMB. * Return -EBUSY instead of -ENODEV when the I/O region is already in use. * Drop useless masks on the 7-bit address and the R/W bit. * Reject block transaction requests with an invalid block length. * Check and report block transaction replies with an invalid block length. * Delete a useless comment. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index dc76c0e..77aaa5f 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -42,13 +42,6 @@ #include -struct sd { - const unsigned short mfr; - const unsigned short dev; - const unsigned char fn; - const char *name; -}; - /* PIIX4 SMBus address offsets */ #define SMBHSTSTS (0 + piix4_smba) #define SMBHSLVSTS (1 + piix4_smba) @@ -101,8 +94,6 @@ MODULE_PARM_DESC(force_addr, "Forcibly enable the PIIX4 at the given address. " "EXTREMELY DANGEROUS!"); -static int piix4_transaction(void); - static unsigned short piix4_smba; static int srvrworks_csb5_delay; static struct pci_driver piix4_driver; @@ -141,8 +132,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, { unsigned char temp; - dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); - if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) srvrworks_csb5_delay = 1; @@ -172,7 +161,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba); piix4_smba &= 0xfff0; if(piix4_smba == 0) { - dev_err(&PIIX4_dev->dev, "SMB base address " + dev_err(&PIIX4_dev->dev, "SMBus base address " "uninitialized - upgrade BIOS or use " "force_addr=0xaddr\n"); return -ENODEV; @@ -180,9 +169,9 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, } if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { - dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n", + dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", piix4_smba); - return -ENODEV; + return -EBUSY; } pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); @@ -228,13 +217,13 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, "(or code out of date)!\n"); pci_read_config_byte(PIIX4_dev, SMBREV, &temp); - dev_dbg(&PIIX4_dev->dev, "SMBREV = 0x%X\n", temp); - dev_dbg(&PIIX4_dev->dev, "SMBA = 0x%X\n", piix4_smba); + dev_info(&PIIX4_dev->dev, + "SMBus Host Controller at 0x%x, revision %d\n", + piix4_smba, temp); return 0; } -/* Another internally used function */ static int piix4_transaction(void) { int temp; @@ -322,19 +311,19 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); return -EOPNOTSUPP; case I2C_SMBUS_QUICK: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + outb_p((addr << 1) | read_write, SMBHSTADD); size = PIIX4_QUICK; break; case I2C_SMBUS_BYTE: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + outb_p((addr << 1) | read_write, SMBHSTADD); if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMBHSTCMD); size = PIIX4_BYTE; break; case I2C_SMBUS_BYTE_DATA: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + outb_p((addr << 1) | read_write, SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) @@ -342,7 +331,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, size = PIIX4_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + outb_p((addr << 1) | read_write, SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { @@ -352,15 +341,13 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, size = PIIX4_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: - outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + outb_p((addr << 1) | read_write, SMBHSTADD); outb_p(command, SMBHSTCMD); if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; - if (len < 0) - len = 0; - if (len > 32) - len = 32; + if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; outb_p(len, SMBHSTDAT0); i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= len; i++) @@ -390,6 +377,8 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, break; case PIIX4_BLOCK_DATA: data->block[0] = inb_p(SMBHSTDAT0); + if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) + return -EPROTO; i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= data->block[0]; i++) data->block[i] = inb_p(SMBBLKDAT); -- cgit v0.10.2 From ac7fc4fb2b6a126af8d07f46500440c9641976cf Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: i2c: Consistently reject unsupported transactions Many PC SMBus host controller drivers don't properly handle the case where they are requested to achieve a transaction they do not support. Update them so that the consistently print a warning message and return a single error value in this case. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index c21e4d9..704436c 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -357,10 +357,6 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, outb_p(0xFF, SMBHSTSTS); switch (size) { - case I2C_SMBUS_PROC_CALL: - dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - result = -EOPNOTSUPP; - goto EXIT; case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); @@ -418,6 +414,10 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, outb_p(data->block[i], SMBBLKDAT); } break; + default: + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); + result = -EOPNOTSUPP; + goto EXIT; } result = ali1535_transaction(adap); diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 30bd3ee..da5a382 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -246,10 +246,6 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, /* Map the size to what the chip understands */ switch (size) { - case I2C_SMBUS_PROC_CALL: - dev_err(&a->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - error = -EINVAL; - break; case I2C_SMBUS_QUICK: size = HST_CNTL2_QUICK; break; @@ -265,6 +261,10 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, case I2C_SMBUS_BLOCK_DATA: size = HST_CNTL2_BLOCK; break; + default: + dev_warn(&a->dev, "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; } outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 3d75256..7b029b1 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -362,9 +362,6 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr, } switch (size) { - case I2C_SMBUS_PROC_CALL: - dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - return -EOPNOTSUPP; case I2C_SMBUS_QUICK: outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); @@ -417,6 +414,9 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr, } size = ALI15X3_BLOCK_DATA; break; + default: + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); + return -EOPNOTSUPP; } outb_p(size, SMBHSTCNT); /* output command */ diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 3d5bcb6..f0baea6 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -200,12 +200,7 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr, int i, len; int status; - /** TODO: Should I supporte the 10-bit transfers? */ switch (size) { - case I2C_SMBUS_PROC_CALL: - dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - /* TODO: Well... It is supported, I'm just not sure what to do here... */ - return -EOPNOTSUPP; case I2C_SMBUS_QUICK: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); @@ -252,6 +247,9 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr, } size = AMD756_BLOCK_DATA; break; + default: + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); + return -EOPNOTSUPP; } /* How about enabling interrupts... */ diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 7d6d9df..2131192 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -513,7 +513,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, outb_p(command, SMBHSTCMD); block = 1; break; - case I2C_SMBUS_PROC_CALL: default: dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); return -EOPNOTSUPP; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 77aaa5f..2bde475 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -307,9 +307,6 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, int status; switch (size) { - case I2C_SMBUS_PROC_CALL: - dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); - return -EOPNOTSUPP; case I2C_SMBUS_QUICK: outb_p((addr << 1) | read_write, SMBHSTADD); @@ -355,6 +352,9 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, } size = PIIX4_BLOCK_DATA; break; + default: + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); + return -EOPNOTSUPP; } outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index c4cc5ed..d7e6ff3 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -356,7 +356,8 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, size = SIS630_BLOCK_DATA; return sis630_block_data(adap, data, read_write); default: - printk("Unsupported SMBus operation\n"); + dev_warn(&adap->dev, "Unsupported transaction %d\n", + size); return -EOPNOTSUPP; } @@ -378,8 +379,6 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, case SIS630_WORD_DATA: data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); break; - default: - return -EOPNOTSUPP; } return 0; diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 29757b2..cde8e58 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -201,14 +201,8 @@ static s32 sis96x_access(struct i2c_adapter * adap, u16 addr, SIS96x_PROC_CALL : SIS96x_WORD_DATA); break; - case I2C_SMBUS_BLOCK_DATA: - /* TO DO: */ - dev_info(&adap->dev, "SMBus block not implemented!\n"); - return -EOPNOTSUPP; - break; - default: - dev_info(&adap->dev, "Unsupported SMBus operation\n"); + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); return -EOPNOTSUPP; } diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c index de9db49..224aa12 100644 --- a/drivers/i2c/busses/i2c-taos-evm.c +++ b/drivers/i2c/busses/i2c-taos-evm.c @@ -96,9 +96,8 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr, sprintf(p, "$%02X", command); break; default: - dev_dbg(&adapter->dev, "Unsupported transaction size %d\n", - size); - return -EINVAL; + dev_warn(&adapter->dev, "Unsupported transaction %d\n", size); + return -EOPNOTSUPP; } /* Send the transaction to the TAOS EVM */ diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 7628fe8..c611905 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -287,7 +287,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr, return 0; exit_unsupported: - dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n", + dev_warn(&vt596_adapter.dev, "Unsupported transaction %d\n", size); return -EOPNOTSUPP; } -- cgit v0.10.2 From c80ebe7987931ec4e80abc33ebf8aa2dad0d3763 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: i2c-pca-algo: Fix error code Give a more concrete error code, when the bus is not idle. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index e954a20..d50b329 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -182,7 +182,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, } if (state != 0xf8) { dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state); - return -EIO; + return -EAGAIN; } DEB1("{{{ XFER %d messages\n", num); -- cgit v0.10.2 From 7650da023eb05426812bbf8999b69dc93fee67ab Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: i2c-pca-platform: Fix error code Fix errorcode to be more descriptive when ioremap fails. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 9d75f51..6bb15ad 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -163,7 +163,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) i2c->reg_base = ioremap(res->start, res_len(res)); if (!i2c->reg_base) { - ret = -EIO; + ret = -ENOMEM; goto e_remap; } i2c->io_base = res->start; -- cgit v0.10.2 From 6a03cd931196673634b58c955d2f9d42da602045 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: i2c: Use list_for_each_entry_safe Use list_for_each_entry_safe() in i2c_del_adapter() and i2c_del_driver(). Signed-off-by: Matthias Kaehlcke Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b995502..1a71645 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -580,8 +580,7 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data) */ int i2c_del_adapter(struct i2c_adapter *adap) { - struct list_head *item, *_n; - struct i2c_client *client; + struct i2c_client *client, *_n; int res = 0; mutex_lock(&core_lock); @@ -602,10 +601,9 @@ int i2c_del_adapter(struct i2c_adapter *adap) /* detach any active clients. This must be done first, because * it can fail; in which case we give up. */ - list_for_each_safe(item, _n, &adap->clients) { + list_for_each_entry_safe(client, _n, &adap->clients, list) { struct i2c_driver *driver; - client = list_entry(item, struct i2c_client, list); driver = client->driver; /* new style, follow standard driver model */ @@ -718,11 +716,9 @@ static int __detach_adapter(struct device *dev, void *data) "detach_adapter failed for driver [%s]\n", driver->driver.name); } else { - struct list_head *item, *_n; - struct i2c_client *client; + struct i2c_client *client, *_n; - list_for_each_safe(item, _n, &adapter->clients) { - client = list_entry(item, struct i2c_client, list); + list_for_each_entry_safe(client, _n, &adapter->clients, list) { if (client->driver != driver) continue; dev_dbg(&adapter->dev, -- cgit v0.10.2 From f7050bd716047a4dfec7d061e28df7ffd6815ebd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:26 +0200 Subject: i2c: Simplify i2c_del_driver() i2c_del_driver() can be simplified a bit. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1a71645..e06067e 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -743,13 +743,11 @@ void i2c_del_driver(struct i2c_driver *driver) { mutex_lock(&core_lock); - /* new-style driver? */ - if (is_newstyle_driver(driver)) - goto unregister; - - class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); + /* legacy driver? */ + if (!is_newstyle_driver(driver)) + class_for_each_device(&i2c_adapter_class, driver, + __detach_adapter); - unregister: driver_unregister(&driver->driver); pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); -- cgit v0.10.2 From 5bc1200852c3dfc312481f57622f48b289ac802e Mon Sep 17 00:00:00 2001 From: Alek Du Date: Mon, 14 Jul 2008 22:38:27 +0200 Subject: i2c: Add Intel SCH SMBus support New i2c bus driver for the Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L). Signed-off-by: Alek Du Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 2b0874b..56b6f29 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -101,6 +101,16 @@ config I2C_I801 This driver can also be built as a module. If so, the module will be called i2c-i801. +config I2C_ISCH + tristate "Intel SCH SMBus 1.0" + depends on PCI + help + Say Y here if you want to use SMBus controller on the Intel SCH + based systems. + + This driver can also be built as a module. If so, the module + will be called i2c-isch. + config I2C_PIIX4 tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" depends on PCI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 48a6a5b..cbeac7d 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_I801) += i2c-i801.o +obj-$(CONFIG_I2C_ISCH) += i2c-isch.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c new file mode 100644 index 0000000..c9cd46b --- /dev/null +++ b/drivers/i2c/busses/i2c-isch.c @@ -0,0 +1,336 @@ +/* + i2c-isch.c - Linux kernel driver for Intel SCH chipset SMBus + - Based on i2c-piix4.c + Copyright (c) 1998 - 2002 Frodo Looijaard and + Philip Edelbrock + - Intel SCH support + Copyright (c) 2007 - 2008 Jacob Jun Pan + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + Supports: + Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L) + Note: we assume there can only be one device, with one SMBus interface. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* SCH SMBus address offsets */ +#define SMBHSTCNT (0 + sch_smba) +#define SMBHSTSTS (1 + sch_smba) +#define SMBHSTADD (4 + sch_smba) /* TSA */ +#define SMBHSTCMD (5 + sch_smba) +#define SMBHSTDAT0 (6 + sch_smba) +#define SMBHSTDAT1 (7 + sch_smba) +#define SMBBLKDAT (0x20 + sch_smba) + +/* count for request_region */ +#define SMBIOSIZE 64 + +/* PCI Address Constants */ +#define SMBBA_SCH 0x40 + +/* Other settings */ +#define MAX_TIMEOUT 500 + +/* I2C constants */ +#define SCH_QUICK 0x00 +#define SCH_BYTE 0x01 +#define SCH_BYTE_DATA 0x02 +#define SCH_WORD_DATA 0x03 +#define SCH_BLOCK_DATA 0x05 + +static unsigned short sch_smba; +static struct pci_driver sch_driver; +static struct i2c_adapter sch_adapter; + +/* + * Start the i2c transaction -- the i2c_access will prepare the transaction + * and this function will execute it. + * return 0 for success and others for failure. + */ +static int sch_transaction(void) +{ + int temp; + int result = 0; + int timeout = 0; + + dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, " + "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT), + inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0), + inb(SMBHSTDAT1)); + + /* Make sure the SMBus host is ready to start transmitting */ + temp = inb(SMBHSTSTS) & 0x0f; + if (temp) { + /* Can not be busy since we checked it in sch_access */ + if (temp & 0x01) { + dev_dbg(&sch_adapter.dev, "Completion (%02x). " + "Clear...\n", temp); + } + if (temp & 0x06) { + dev_dbg(&sch_adapter.dev, "SMBus error (%02x). " + "Resetting...\n", temp); + } + outb(temp, SMBHSTSTS); + temp = inb(SMBHSTSTS) & 0x0f; + if (temp) { + dev_err(&sch_adapter.dev, + "SMBus is not ready: (%02x)\n", temp); + return -EAGAIN; + } + } + + /* start the transaction by setting bit 4 */ + outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT); + + do { + msleep(1); + temp = inb(SMBHSTSTS) & 0x0f; + } while ((temp & 0x08) && (timeout++ < MAX_TIMEOUT)); + + /* If the SMBus is still busy, we give up */ + if (timeout >= MAX_TIMEOUT) { + dev_err(&sch_adapter.dev, "SMBus Timeout!\n"); + result = -ETIMEDOUT; + } + if (temp & 0x04) { + result = -EIO; + dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be " + "locked until next hard reset. (sorry!)\n"); + /* Clock stops and slave is stuck in mid-transmission */ + } else if (temp & 0x02) { + result = -EIO; + dev_err(&sch_adapter.dev, "Error: no response!\n"); + } else if (temp & 0x01) { + dev_dbg(&sch_adapter.dev, "Post complete!\n"); + outb(temp, SMBHSTSTS); + temp = inb(SMBHSTSTS) & 0x07; + if (temp & 0x06) { + /* Completion clear failed */ + dev_dbg(&sch_adapter.dev, "Failed reset at end of " + "transaction (%02x), Bus error!\n", temp); + } + } else { + result = -ENXIO; + dev_dbg(&sch_adapter.dev, "No such address.\n"); + } + dev_dbg(&sch_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, " + "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT), + inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0), + inb(SMBHSTDAT1)); + return result; +} + +/* + * This is the main access entry for i2c-sch access + * adap is i2c_adapter pointer, addr is the i2c device bus address, read_write + * (0 for read and 1 for write), size is i2c transaction type and data is the + * union of transaction for data to be transfered or data read from bus. + * return 0 for success and others for failure. + */ +static s32 sch_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data) +{ + int i, len, temp, rc; + + /* Make sure the SMBus host is not busy */ + temp = inb(SMBHSTSTS) & 0x0f; + if (temp & 0x08) { + dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp); + return -EAGAIN; + } + dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size, + (read_write)?"READ":"WRITE"); + switch (size) { + case I2C_SMBUS_QUICK: + outb((addr << 1) | read_write, SMBHSTADD); + size = SCH_QUICK; + break; + case I2C_SMBUS_BYTE: + outb((addr << 1) | read_write, SMBHSTADD); + if (read_write == I2C_SMBUS_WRITE) + outb(command, SMBHSTCMD); + size = SCH_BYTE; + break; + case I2C_SMBUS_BYTE_DATA: + outb((addr << 1) | read_write, SMBHSTADD); + outb(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) + outb(data->byte, SMBHSTDAT0); + size = SCH_BYTE_DATA; + break; + case I2C_SMBUS_WORD_DATA: + outb((addr << 1) | read_write, SMBHSTADD); + outb(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) { + outb(data->word & 0xff, SMBHSTDAT0); + outb((data->word & 0xff00) >> 8, SMBHSTDAT1); + } + size = SCH_WORD_DATA; + break; + case I2C_SMBUS_BLOCK_DATA: + outb((addr << 1) | read_write, SMBHSTADD); + outb(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) { + len = data->block[0]; + if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + outb(len, SMBHSTDAT0); + for (i = 1; i <= len; i++) + outb(data->block[i], SMBBLKDAT+i-1); + } + size = SCH_BLOCK_DATA; + break; + default: + dev_warn(&adap->dev, "Unsupported transaction %d\n", size); + return -EOPNOTSUPP; + } + dev_dbg(&sch_adapter.dev, "write size %d to 0x%04x\n", size, SMBHSTCNT); + outb((inb(SMBHSTCNT) & 0xb0) | (size & 0x7), SMBHSTCNT); + + rc = sch_transaction(); + if (rc) /* Error in transaction */ + return rc; + + if ((read_write == I2C_SMBUS_WRITE) || (size == SCH_QUICK)) + return 0; + + switch (size) { + case SCH_BYTE: + case SCH_BYTE_DATA: + data->byte = inb(SMBHSTDAT0); + break; + case SCH_WORD_DATA: + data->word = inb(SMBHSTDAT0) + (inb(SMBHSTDAT1) << 8); + break; + case SCH_BLOCK_DATA: + data->block[0] = inb(SMBHSTDAT0); + if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) + return -EPROTO; + for (i = 1; i <= data->block[0]; i++) + data->block[i] = inb(SMBBLKDAT+i-1); + break; + } + return 0; +} + +static u32 sch_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm smbus_algorithm = { + .smbus_xfer = sch_access, + .functionality = sch_func, +}; + +static struct i2c_adapter sch_adapter = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo = &smbus_algorithm, +}; + +static struct pci_device_id sch_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, sch_ids); + +static int __devinit sch_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + int retval; + unsigned int smba; + + pci_read_config_dword(dev, SMBBA_SCH, &smba); + if (!(smba & (1 << 31))) { + dev_err(&dev->dev, "SMBus I/O space disabled!\n"); + return -ENODEV; + } + + sch_smba = (unsigned short)smba; + if (sch_smba == 0) { + dev_err(&dev->dev, "SMBus base address uninitialized!\n"); + return -ENODEV; + } + if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { + dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", + sch_smba); + return -EBUSY; + } + dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba); + + /* set up the sysfs linkage to our parent device */ + sch_adapter.dev.parent = &dev->dev; + + snprintf(sch_adapter.name, sizeof(sch_adapter.name), + "SMBus SCH adapter at %04x", sch_smba); + + retval = i2c_add_adapter(&sch_adapter); + if (retval) { + dev_err(&dev->dev, "Couldn't register adapter!\n"); + release_region(sch_smba, SMBIOSIZE); + sch_smba = 0; + } + + return retval; +} + +static void __devexit sch_remove(struct pci_dev *dev) +{ + if (sch_smba) { + i2c_del_adapter(&sch_adapter); + release_region(sch_smba, SMBIOSIZE); + sch_smba = 0; + } +} + +static struct pci_driver sch_driver = { + .name = "isch_smbus", + .id_table = sch_ids, + .probe = sch_probe, + .remove = __devexit_p(sch_remove), +}; + +static int __init i2c_sch_init(void) +{ + return pci_register_driver(&sch_driver); +} + +static void __exit i2c_sch_exit(void) +{ + pci_unregister_driver(&sch_driver); +} + +MODULE_AUTHOR("Jacob Pan "); +MODULE_DESCRIPTION("Intel SCH SMBus driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_sch_init); +module_exit(i2c_sch_exit); -- cgit v0.10.2 From 77e38bffe0fcaa48f0be68eaa1de4a59d1fd93ad Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Jul 2008 22:38:27 +0200 Subject: i2c: Push ioctl BKL down into the i2c code This is part of the effort to get rid of the BKL. [JD: In fact i2c-dev doesn't need more locking than is already done for the other i2c drivers, so we can simply switch to unlocked_ioctl.] Signed-off-by: Alan Cox Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index d34c14c..e96d986 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -366,8 +366,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, return res; } -static int i2cdev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct i2c_client *client = (struct i2c_client *)file->private_data; unsigned long funcs; @@ -487,7 +486,7 @@ static const struct file_operations i2cdev_fops = { .llseek = no_llseek, .read = i2cdev_read, .write = i2cdev_write, - .ioctl = i2cdev_ioctl, + .unlocked_ioctl = i2cdev_ioctl, .open = i2cdev_open, .release = i2cdev_release, }; -- cgit v0.10.2 From 61045dbe9d8d81b1bae4dc1e9482d389ca99edc1 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Mon, 14 Jul 2008 22:38:27 +0200 Subject: i2c: Add support for I2C bus on Freescale CPM1/CPM2 controllers This driver uses the port of 2.4 code from Vitaly Bordug and the actual algorithm used by the i2c driver of the DBox code on cvs.tuxboc.org from Felix Domke (tmbinc@gmx.net) and Gillem (htoa@gmx.net) converted to an of_platform_driver. Tested on CPM1 (MPC823 on dbox2 hardware) and CPM2 (MPC8272). Signed-off-by: Jochen Friedrich Tested-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 56b6f29..6ee997b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -299,6 +299,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ help The unit of the TWI clock is kHz. +config I2C_CPM + tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)" + depends on (CPM1 || CPM2) && OF_I2C + help + This supports the use of the I2C interface on Freescale + processors with CPM1 or CPM2. + + This driver can also be built as a module. If so, the module + will be called i2c-cpm. + config I2C_DAVINCI tristate "DaVinci I2C driver" depends on ARCH_DAVINCI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index cbeac7d..97dbfa2 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o +obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c new file mode 100644 index 0000000..1c955a8 --- /dev/null +++ b/drivers/i2c/busses/i2c-cpm.c @@ -0,0 +1,745 @@ +/* + * Freescale CPM1/CPM2 I2C interface. + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net). + * + * moved into proper i2c interface; + * Brad Parker (brad@heeltoe.com) + * + * Parts from dbox2_i2c.c (cvs.tuxbox.org) + * (C) 2000-2001 Felix Domke (tmbinc@gmx.net), Gillem (htoa@gmx.net) + * + * (C) 2007 Montavista Software, Inc. + * Vitaly Bordug + * + * Converted to of_platform_device. Renamed to i2c-cpm.c. + * (C) 2007,2008 Jochen Friedrich + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Try to define this if you have an older CPU (earlier than rev D4) */ +/* However, better use a GPIO based bitbang driver in this case :/ */ +#undef I2C_CHIP_ERRATA + +#define CPM_MAX_READ 513 +#define CPM_MAXBD 4 + +#define I2C_EB (0x10) /* Big endian mode */ +#define I2C_EB_CPM2 (0x30) /* Big endian mode, memory snoop */ + +#define DPRAM_BASE ((u8 __iomem __force *)cpm_muram_addr(0)) + +/* I2C parameter RAM. */ +struct i2c_ram { + ushort rbase; /* Rx Buffer descriptor base address */ + ushort tbase; /* Tx Buffer descriptor base address */ + u_char rfcr; /* Rx function code */ + u_char tfcr; /* Tx function code */ + ushort mrblr; /* Max receive buffer length */ + uint rstate; /* Internal */ + uint rdp; /* Internal */ + ushort rbptr; /* Rx Buffer descriptor pointer */ + ushort rbc; /* Internal */ + uint rxtmp; /* Internal */ + uint tstate; /* Internal */ + uint tdp; /* Internal */ + ushort tbptr; /* Tx Buffer descriptor pointer */ + ushort tbc; /* Internal */ + uint txtmp; /* Internal */ + char res1[4]; /* Reserved */ + ushort rpbase; /* Relocation pointer */ + char res2[2]; /* Reserved */ +}; + +#define I2COM_START 0x80 +#define I2COM_MASTER 0x01 +#define I2CER_TXE 0x10 +#define I2CER_BUSY 0x04 +#define I2CER_TXB 0x02 +#define I2CER_RXB 0x01 +#define I2MOD_EN 0x01 + +/* I2C Registers */ +struct i2c_reg { + u8 i2mod; + u8 res1[3]; + u8 i2add; + u8 res2[3]; + u8 i2brg; + u8 res3[3]; + u8 i2com; + u8 res4[3]; + u8 i2cer; + u8 res5[3]; + u8 i2cmr; +}; + +struct cpm_i2c { + char *base; + struct of_device *ofdev; + struct i2c_adapter adap; + uint dp_addr; + int version; /* CPM1=1, CPM2=2 */ + int irq; + int cp_command; + int freq; + struct i2c_reg __iomem *i2c_reg; + struct i2c_ram __iomem *i2c_ram; + u16 i2c_addr; + wait_queue_head_t i2c_wait; + cbd_t __iomem *tbase; + cbd_t __iomem *rbase; + u_char *txbuf[CPM_MAXBD]; + u_char *rxbuf[CPM_MAXBD]; + u32 txdma[CPM_MAXBD]; + u32 rxdma[CPM_MAXBD]; +}; + +static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id) +{ + struct cpm_i2c *cpm; + struct i2c_reg __iomem *i2c_reg; + struct i2c_adapter *adap = dev_id; + int i; + + cpm = i2c_get_adapdata(dev_id); + i2c_reg = cpm->i2c_reg; + + /* Clear interrupt. */ + i = in_8(&i2c_reg->i2cer); + out_8(&i2c_reg->i2cer, i); + + dev_dbg(&adap->dev, "Interrupt: %x\n", i); + + wake_up_interruptible(&cpm->i2c_wait); + + return i ? IRQ_HANDLED : IRQ_NONE; +} + +static void cpm_reset_i2c_params(struct cpm_i2c *cpm) +{ + struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram; + + /* Set up the I2C parameters in the parameter ram. */ + out_be16(&i2c_ram->tbase, (u8 __iomem *)cpm->tbase - DPRAM_BASE); + out_be16(&i2c_ram->rbase, (u8 __iomem *)cpm->rbase - DPRAM_BASE); + + if (cpm->version == 1) { + out_8(&i2c_ram->tfcr, I2C_EB); + out_8(&i2c_ram->rfcr, I2C_EB); + } else { + out_8(&i2c_ram->tfcr, I2C_EB_CPM2); + out_8(&i2c_ram->rfcr, I2C_EB_CPM2); + } + + out_be16(&i2c_ram->mrblr, CPM_MAX_READ); + + out_be32(&i2c_ram->rstate, 0); + out_be32(&i2c_ram->rdp, 0); + out_be16(&i2c_ram->rbptr, 0); + out_be16(&i2c_ram->rbc, 0); + out_be32(&i2c_ram->rxtmp, 0); + out_be32(&i2c_ram->tstate, 0); + out_be32(&i2c_ram->tdp, 0); + out_be16(&i2c_ram->tbptr, 0); + out_be16(&i2c_ram->tbc, 0); + out_be32(&i2c_ram->txtmp, 0); +} + +static void cpm_i2c_force_close(struct i2c_adapter *adap) +{ + struct cpm_i2c *cpm = i2c_get_adapdata(adap); + struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg; + + dev_dbg(&adap->dev, "cpm_i2c_force_close()\n"); + + cpm_command(cpm->cp_command, CPM_CR_CLOSE_RX_BD); + + out_8(&i2c_reg->i2cmr, 0x00); /* Disable all interrupts */ + out_8(&i2c_reg->i2cer, 0xff); +} + +static void cpm_i2c_parse_message(struct i2c_adapter *adap, + struct i2c_msg *pmsg, int num, int tx, int rx) +{ + cbd_t __iomem *tbdf; + cbd_t __iomem *rbdf; + u_char addr; + u_char *tb; + u_char *rb; + struct cpm_i2c *cpm = i2c_get_adapdata(adap); + + tbdf = cpm->tbase + tx; + rbdf = cpm->rbase + rx; + + addr = pmsg->addr << 1; + if (pmsg->flags & I2C_M_RD) + addr |= 1; + + tb = cpm->txbuf[tx]; + rb = cpm->rxbuf[rx]; + + /* Align read buffer */ + rb = (u_char *) (((ulong) rb + 1) & ~1); + + tb[0] = addr; /* Device address byte w/rw flag */ + + out_be16(&tbdf->cbd_datlen, pmsg->len + 1); + out_be16(&tbdf->cbd_sc, 0); + + if (!(pmsg->flags & I2C_M_NOSTART)) + setbits16(&tbdf->cbd_sc, BD_I2C_START); + + if (tx + 1 == num) + setbits16(&tbdf->cbd_sc, BD_SC_LAST | BD_SC_WRAP); + + if (pmsg->flags & I2C_M_RD) { + /* + * To read, we need an empty buffer of the proper length. + * All that is used is the first byte for address, the remainder + * is just used for timing (and doesn't really have to exist). + */ + + dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr); + + out_be16(&rbdf->cbd_datlen, 0); + out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT); + + if (rx + 1 == CPM_MAXBD) + setbits16(&rbdf->cbd_sc, BD_SC_WRAP); + + eieio(); + setbits16(&tbdf->cbd_sc, BD_SC_READY); + } else { + dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr); + + memcpy(tb+1, pmsg->buf, pmsg->len); + + eieio(); + setbits16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_INTRPT); + } +} + +static int cpm_i2c_check_message(struct i2c_adapter *adap, + struct i2c_msg *pmsg, int tx, int rx) +{ + cbd_t __iomem *tbdf; + cbd_t __iomem *rbdf; + u_char *tb; + u_char *rb; + struct cpm_i2c *cpm = i2c_get_adapdata(adap); + + tbdf = cpm->tbase + tx; + rbdf = cpm->rbase + rx; + + tb = cpm->txbuf[tx]; + rb = cpm->rxbuf[rx]; + + /* Align read buffer */ + rb = (u_char *) (((uint) rb + 1) & ~1); + + eieio(); + if (pmsg->flags & I2C_M_RD) { + dev_dbg(&adap->dev, "tx sc 0x%04x, rx sc 0x%04x\n", + in_be16(&tbdf->cbd_sc), in_be16(&rbdf->cbd_sc)); + + if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) { + dev_dbg(&adap->dev, "I2C read; No ack\n"); + return -ENXIO; + } + if (in_be16(&rbdf->cbd_sc) & BD_SC_EMPTY) { + dev_err(&adap->dev, + "I2C read; complete but rbuf empty\n"); + return -EREMOTEIO; + } + if (in_be16(&rbdf->cbd_sc) & BD_SC_OV) { + dev_err(&adap->dev, "I2C read; Overrun\n"); + return -EREMOTEIO; + } + memcpy(pmsg->buf, rb, pmsg->len); + } else { + dev_dbg(&adap->dev, "tx sc %d 0x%04x\n", tx, + in_be16(&tbdf->cbd_sc)); + + if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) { + dev_dbg(&adap->dev, "I2C write; No ack\n"); + return -ENXIO; + } + if (in_be16(&tbdf->cbd_sc) & BD_SC_UN) { + dev_err(&adap->dev, "I2C write; Underrun\n"); + return -EIO; + } + if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) { + dev_err(&adap->dev, "I2C write; Collision\n"); + return -EIO; + } + } + return 0; +} + +static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct cpm_i2c *cpm = i2c_get_adapdata(adap); + struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg; + struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram; + struct i2c_msg *pmsg; + int ret, i; + int tptr; + int rptr; + cbd_t __iomem *tbdf; + cbd_t __iomem *rbdf; + + if (num > CPM_MAXBD) + return -EINVAL; + + /* Check if we have any oversized READ requests */ + for (i = 0; i < num; i++) { + pmsg = &msgs[i]; + if (pmsg->len >= CPM_MAX_READ) + return -EINVAL; + } + + /* Reset to use first buffer */ + out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase)); + out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase)); + + tbdf = cpm->tbase; + rbdf = cpm->rbase; + + tptr = 0; + rptr = 0; + + while (tptr < num) { + pmsg = &msgs[tptr]; + dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr); + + cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr); + if (pmsg->flags & I2C_M_RD) + rptr++; + tptr++; + } + /* Start transfer now */ + /* Enable RX/TX/Error interupts */ + out_8(&i2c_reg->i2cmr, I2CER_BUSY | I2CER_TXB | I2CER_RXB); + out_8(&i2c_reg->i2cer, 0xff); /* Clear interrupt status */ + /* Chip bug, set enable here */ + setbits8(&i2c_reg->i2mod, I2MOD_EN); /* Enable */ + /* Begin transmission */ + setbits8(&i2c_reg->i2com, I2COM_START); + + tptr = 0; + rptr = 0; + + while (tptr < num) { + /* Check for outstanding messages */ + dev_dbg(&adap->dev, "test ready.\n"); + pmsg = &msgs[tptr]; + if (pmsg->flags & I2C_M_RD) + ret = wait_event_interruptible_timeout(cpm->i2c_wait, + !(in_be16(&rbdf[rptr].cbd_sc) & BD_SC_EMPTY), + 1 * HZ); + else + ret = wait_event_interruptible_timeout(cpm->i2c_wait, + !(in_be16(&tbdf[tptr].cbd_sc) & BD_SC_READY), + 1 * HZ); + if (ret == 0) { + ret = -EREMOTEIO; + dev_err(&adap->dev, "I2C transfer: timeout\n"); + goto out_err; + } + if (ret > 0) { + dev_dbg(&adap->dev, "ready.\n"); + ret = cpm_i2c_check_message(adap, pmsg, tptr, rptr); + tptr++; + if (pmsg->flags & I2C_M_RD) + rptr++; + if (ret) + goto out_err; + } + } +#ifdef I2C_CHIP_ERRATA + /* + * Chip errata, clear enable. This is not needed on rev D4 CPUs. + * Disabling I2C too early may cause too short stop condition + */ + udelay(4); + clrbits8(&i2c_reg->i2mod, I2MOD_EN); +#endif + return (num); + +out_err: + cpm_i2c_force_close(adap); +#ifdef I2C_CHIP_ERRATA + /* + * Chip errata, clear enable. This is not needed on rev D4 CPUs. + */ + clrbits8(&i2c_reg->i2mod, I2MOD_EN); +#endif + return ret; +} + +static u32 cpm_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +} + +/* -----exported algorithm data: ------------------------------------- */ + +static const struct i2c_algorithm cpm_i2c_algo = { + .master_xfer = cpm_i2c_xfer, + .functionality = cpm_i2c_func, +}; + +static const struct i2c_adapter cpm_ops = { + .owner = THIS_MODULE, + .name = "i2c-cpm", + .algo = &cpm_i2c_algo, + .class = I2C_CLASS_HWMON, +}; + +static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) +{ + struct of_device *ofdev = cpm->ofdev; + const u32 *data; + int len, ret, i; + void __iomem *i2c_base; + cbd_t __iomem *tbdf; + cbd_t __iomem *rbdf; + unsigned char brg; + + dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n"); + + init_waitqueue_head(&cpm->i2c_wait); + + cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL); + if (cpm->irq == NO_IRQ) + return -EINVAL; + + /* Install interrupt handler. */ + ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c", + &cpm->adap); + if (ret) + return ret; + + /* I2C parameter RAM */ + i2c_base = of_iomap(ofdev->node, 1); + if (i2c_base == NULL) { + ret = -EINVAL; + goto out_irq; + } + + if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) { + + /* Check for and use a microcode relocation patch. */ + cpm->i2c_ram = i2c_base; + cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase); + + /* + * Maybe should use cpm_muram_alloc instead of hardcoding + * this in micropatch.c + */ + if (cpm->i2c_addr) { + cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); + iounmap(i2c_base); + } + + cpm->version = 1; + + } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) { + cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64); + cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); + out_be16(i2c_base, cpm->i2c_addr); + iounmap(i2c_base); + + cpm->version = 2; + + } else { + iounmap(i2c_base); + ret = -EINVAL; + goto out_irq; + } + + /* I2C control/status registers */ + cpm->i2c_reg = of_iomap(ofdev->node, 0); + if (cpm->i2c_reg == NULL) { + ret = -EINVAL; + goto out_ram; + } + + data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + if (!data || len != 4) { + ret = -EINVAL; + goto out_reg; + } + cpm->cp_command = *data; + + data = of_get_property(ofdev->node, "linux,i2c-class", &len); + if (data && len == 4) + cpm->adap.class = *data; + + data = of_get_property(ofdev->node, "clock-frequency", &len); + if (data && len == 4) + cpm->freq = *data; + else + cpm->freq = 60000; /* use 60kHz i2c clock by default */ + + /* + * Allocate space for CPM_MAXBD transmit and receive buffer + * descriptors in the DP ram. + */ + cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8); + if (!cpm->dp_addr) { + ret = -ENOMEM; + goto out_reg; + } + + cpm->tbase = cpm_muram_addr(cpm->dp_addr); + cpm->rbase = cpm_muram_addr(cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD); + + /* Allocate TX and RX buffers */ + + tbdf = cpm->tbase; + rbdf = cpm->rbase; + + for (i = 0; i < CPM_MAXBD; i++) { + cpm->rxbuf[i] = dma_alloc_coherent( + NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL); + if (!cpm->rxbuf[i]) { + ret = -ENOMEM; + goto out_muram; + } + out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1)); + + cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent( + NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL); + if (!cpm->txbuf[i]) { + ret = -ENOMEM; + goto out_muram; + } + out_be32(&tbdf[i].cbd_bufaddr, cpm->txdma[i]); + } + + /* Initialize Tx/Rx parameters. */ + + cpm_reset_i2c_params(cpm); + + dev_dbg(&cpm->ofdev->dev, "i2c_ram %p, i2c_addr 0x%04x\n", + cpm->i2c_ram, cpm->i2c_addr); + dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n", + (u8 __iomem *)cpm->tbase - DPRAM_BASE, + (u8 __iomem *)cpm->rbase - DPRAM_BASE); + + cpm_command(cpm->cp_command, CPM_CR_INIT_TRX); + + /* + * Select an invalid address. Just make sure we don't use loopback mode + */ + out_8(&cpm->i2c_reg->i2add, 0x7f << 1); + + /* + * PDIV is set to 00 in i2mod, so brgclk/32 is used as input to the + * i2c baud rate generator. This is divided by 2 x (DIV + 3) to get + * the actual i2c bus frequency. + */ + brg = get_brgfreq() / (32 * 2 * cpm->freq) - 3; + out_8(&cpm->i2c_reg->i2brg, brg); + + out_8(&cpm->i2c_reg->i2mod, 0x00); + out_8(&cpm->i2c_reg->i2com, I2COM_MASTER); /* Master mode */ + + /* Disable interrupts. */ + out_8(&cpm->i2c_reg->i2cmr, 0); + out_8(&cpm->i2c_reg->i2cer, 0xff); + + return 0; + +out_muram: + for (i = 0; i < CPM_MAXBD; i++) { + if (cpm->rxbuf[i]) + dma_free_coherent(NULL, CPM_MAX_READ + 1, + cpm->rxbuf[i], cpm->rxdma[i]); + if (cpm->txbuf[i]) + dma_free_coherent(NULL, CPM_MAX_READ + 1, + cpm->txbuf[i], cpm->txdma[i]); + } + cpm_muram_free(cpm->dp_addr); +out_reg: + iounmap(cpm->i2c_reg); +out_ram: + if ((cpm->version == 1) && (!cpm->i2c_addr)) + iounmap(cpm->i2c_ram); + if (cpm->version == 2) + cpm_muram_free(cpm->i2c_addr); +out_irq: + free_irq(cpm->irq, &cpm->adap); + return ret; +} + +static void cpm_i2c_shutdown(struct cpm_i2c *cpm) +{ + int i; + + /* Shut down I2C. */ + clrbits8(&cpm->i2c_reg->i2mod, I2MOD_EN); + + /* Disable interrupts */ + out_8(&cpm->i2c_reg->i2cmr, 0); + out_8(&cpm->i2c_reg->i2cer, 0xff); + + free_irq(cpm->irq, &cpm->adap); + + /* Free all memory */ + for (i = 0; i < CPM_MAXBD; i++) { + dma_free_coherent(NULL, CPM_MAX_READ + 1, + cpm->rxbuf[i], cpm->rxdma[i]); + dma_free_coherent(NULL, CPM_MAX_READ + 1, + cpm->txbuf[i], cpm->txdma[i]); + } + + cpm_muram_free(cpm->dp_addr); + iounmap(cpm->i2c_reg); + + if ((cpm->version == 1) && (!cpm->i2c_addr)) + iounmap(cpm->i2c_ram); + if (cpm->version == 2) + cpm_muram_free(cpm->i2c_addr); +} + +static int __devinit cpm_i2c_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + int result, len; + struct cpm_i2c *cpm; + const u32 *data; + + cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL); + if (!cpm) + return -ENOMEM; + + cpm->ofdev = ofdev; + + dev_set_drvdata(&ofdev->dev, cpm); + + cpm->adap = cpm_ops; + i2c_set_adapdata(&cpm->adap, cpm); + cpm->adap.dev.parent = &ofdev->dev; + + result = cpm_i2c_setup(cpm); + if (result) { + dev_err(&ofdev->dev, "Unable to init hardware\n"); + goto out_free; + } + + /* register new adapter to i2c module... */ + + data = of_get_property(ofdev->node, "linux,i2c-index", &len); + if (data && len == 4) { + cpm->adap.nr = *data; + result = i2c_add_numbered_adapter(&cpm->adap); + } else + result = i2c_add_adapter(&cpm->adap); + + if (result < 0) { + dev_err(&ofdev->dev, "Unable to register with I2C\n"); + goto out_shut; + } + + dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", + cpm->adap.name); + + /* + * register OF I2C devices + */ + of_register_i2c_devices(&cpm->adap, ofdev->node); + + return 0; +out_shut: + cpm_i2c_shutdown(cpm); +out_free: + dev_set_drvdata(&ofdev->dev, NULL); + kfree(cpm); + + return result; +} + +static int __devexit cpm_i2c_remove(struct of_device *ofdev) +{ + struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev); + + i2c_del_adapter(&cpm->adap); + + cpm_i2c_shutdown(cpm); + + dev_set_drvdata(&ofdev->dev, NULL); + kfree(cpm); + + return 0; +} + +static const struct of_device_id cpm_i2c_match[] = { + { + .compatible = "fsl,cpm1-i2c", + }, + { + .compatible = "fsl,cpm2-i2c", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, cpm_i2c_match); + +static struct of_platform_driver cpm_i2c_driver = { + .match_table = cpm_i2c_match, + .probe = cpm_i2c_probe, + .remove = __devexit_p(cpm_i2c_remove), + .driver = { + .name = "fsl-i2c-cpm", + .owner = THIS_MODULE, + } +}; + +static int __init cpm_i2c_init(void) +{ + return of_register_platform_driver(&cpm_i2c_driver); +} + +static void __exit cpm_i2c_exit(void) +{ + of_unregister_platform_driver(&cpm_i2c_driver); +} + +module_init(cpm_i2c_init); +module_exit(cpm_i2c_exit); + +MODULE_AUTHOR("Jochen Friedrich "); +MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 3b270804a9345e4a0c493889f98e838692f7bc9b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:28 +0200 Subject: i2c-cpm: Bugfixes Bugfixes to the i2c-cpm driver - enable correct interrupts (I2CER_TXE instead of I2CER_BUSY) - replace forgotten iic with i2c - prefix debug-output on init with 0x and add frequency Signed-off-by: Wolfram Sang Acked-by: Jochen Friedrich Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 1c955a8..53af744 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -240,7 +240,7 @@ static void cpm_i2c_parse_message(struct i2c_adapter *adap, eieio(); setbits16(&tbdf->cbd_sc, BD_SC_READY); } else { - dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr); + dev_dbg(&adap->dev, "cpm_i2c_write(abyte=0x%x)\n", addr); memcpy(tb+1, pmsg->buf, pmsg->len); @@ -349,7 +349,7 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } /* Start transfer now */ /* Enable RX/TX/Error interupts */ - out_8(&i2c_reg->i2cmr, I2CER_BUSY | I2CER_TXB | I2CER_RXB); + out_8(&i2c_reg->i2cmr, I2CER_TXE | I2CER_TXB | I2CER_RXB); out_8(&i2c_reg->i2cer, 0xff); /* Clear interrupt status */ /* Chip bug, set enable here */ setbits8(&i2c_reg->i2mod, I2MOD_EN); /* Enable */ @@ -552,8 +552,8 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) cpm_reset_i2c_params(cpm); - dev_dbg(&cpm->ofdev->dev, "i2c_ram %p, i2c_addr 0x%04x\n", - cpm->i2c_ram, cpm->i2c_addr); + dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n", + cpm->i2c_ram, cpm->i2c_addr, cpm->freq); dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n", (u8 __iomem *)cpm->tbase - DPRAM_BASE, (u8 __iomem *)cpm->rbase - DPRAM_BASE); -- cgit v0.10.2 From 0d2b405a628309310b4fc02b26d713b855ad5f68 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Mon, 14 Jul 2008 22:38:28 +0200 Subject: i2c: Add MAINTAINER entry for i2c-cpm Signed-off-by: Jochen Friedrich Signed-off-by: Jean Delvare diff --git a/MAINTAINERS b/MAINTAINERS index 56a2f67..dd20fe3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1680,6 +1680,13 @@ L: linuxppc-embedded@ozlabs.org L: linux-kernel@vger.kernel.org S: Maintained +FREESCALE I2C CPM DRIVER +P: Jochen Friedrich +M: jochen@scram.de +L: linuxppc-dev@ozlabs.org +L: i2c@lm-sensors.org +S: Maintained + FREESCALE SOC FS_ENET DRIVER P: Pantelis Antoniou M: pantelis.antoniou@gmail.com -- cgit v0.10.2 From c1b6b4f2342d073698dfc2547240c35045a1d00e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:28 +0200 Subject: i2c: Let framebuffer drivers set their I2C bus class to DDC Let framebuffer drivers set their I2C bus class to DDC. Once this is done, we will be able to tell the eeprom driver to only probe for EDID EEPROMs on these buses. Signed-off-by: Jean Delvare diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c index a0df632..0cf96eb 100644 --- a/drivers/video/fb_ddc.c +++ b/drivers/video/fb_ddc.c @@ -106,6 +106,7 @@ unsigned char *fb_ddc_read(struct i2c_adapter *adapter) algo_data->setsda(algo_data->data, 1); algo_data->setscl(algo_data->data, 1); + adapter->class |= I2C_CLASS_DDC; return edid; } diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c index ca95f09..fcf9fad 100644 --- a/drivers/video/intelfb/intelfb_i2c.c +++ b/drivers/video/intelfb/intelfb_i2c.c @@ -100,7 +100,8 @@ static int intelfb_gpio_getsda(void *data) static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, struct intelfb_i2c_chan *chan, - const u32 reg, const char *name) + const u32 reg, const char *name, + int class) { int rc; @@ -108,6 +109,7 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, chan->reg = reg; snprintf(chan->adapter.name, sizeof(chan->adapter.name), "intelfb %s", name); + chan->adapter.class = class; chan->adapter.owner = THIS_MODULE; chan->adapter.id = I2C_HW_B_INTELFB; chan->adapter.algo_data = &chan->algo; @@ -145,7 +147,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo) /* setup the DDC bus for analog output */ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, - "CRTDDC_A"); + "CRTDDC_A", I2C_CLASS_DDC); i++; /* need to add the output busses for each device @@ -159,9 +161,9 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo) case INTEL_865G: dinfo->output[i].type = INTELFB_OUTPUT_DVO; intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, - GPIOD, "DVODDC_D"); + GPIOD, "DVODDC_D", I2C_CLASS_DDC); intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, - GPIOE, "DVOI2C_E"); + GPIOE, "DVOI2C_E", 0); i++; break; case INTEL_915G: @@ -174,7 +176,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo) /* SDVO ports have a single control bus - 2 devices */ dinfo->output[i].type = INTELFB_OUTPUT_SDVO; intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, - GPIOE, "SDVOCTRL_E"); + GPIOE, "SDVOCTRL_E", 0); /* TODO: initialize the SDVO */ /* I830SDVOInit(pScrn, i, DVOB); */ i++; diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c index 4baab7b..75ee5a1 100644 --- a/drivers/video/matrox/i2c-matroxfb.c +++ b/drivers/video/matrox/i2c-matroxfb.c @@ -104,7 +104,9 @@ static struct i2c_algo_bit_data matrox_i2c_algo_template = }; static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, - unsigned int data, unsigned int clock, const char* name) { + unsigned int data, unsigned int clock, const char *name, + int class) +{ int err; b->minfo = minfo; @@ -114,6 +116,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo, snprintf(b->adapter.name, sizeof(b->adapter.name), name, minfo->fbcon.node); i2c_set_adapdata(&b->adapter, b); + b->adapter.class = class; b->adapter.algo_data = &b->bac; b->adapter.dev.parent = &ACCESS_FBINFO(pcidev)->dev; b->bac = matrox_i2c_algo_template; @@ -159,22 +162,29 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { switch (ACCESS_FBINFO(chip)) { case MGA_2064: case MGA_2164: - err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1B_DATA, DDC1B_CLK, "DDC:fb%u #0"); + err = i2c_bus_reg(&m2info->ddc1, minfo, + DDC1B_DATA, DDC1B_CLK, + "DDC:fb%u #0", I2C_CLASS_DDC); break; default: - err = i2c_bus_reg(&m2info->ddc1, minfo, DDC1_DATA, DDC1_CLK, "DDC:fb%u #0"); + err = i2c_bus_reg(&m2info->ddc1, minfo, + DDC1_DATA, DDC1_CLK, + "DDC:fb%u #0", I2C_CLASS_DDC); break; } if (err) goto fail_ddc1; if (ACCESS_FBINFO(devflags.dualhead)) { - err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1"); + err = i2c_bus_reg(&m2info->ddc2, minfo, + DDC2_DATA, DDC2_CLK, + "DDC:fb%u #1", I2C_CLASS_DDC); if (err == -ENODEV) { printk(KERN_INFO "i2c-matroxfb: VGA->TV plug detected, DDC unavailable.\n"); } else if (err) printk(KERN_INFO "i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.\n"); /* Register maven bus even on G450/G550 */ - err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u"); + err = i2c_bus_reg(&m2info->maven, minfo, + MAT_DATA, MAT_CLK, "MAVEN:fb%u", 0); if (err) printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n"); } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 7c36d51..145797f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -349,7 +349,7 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ #define I2C_CLASS_TV_ANALOG (1<<1) /* bttv + friends */ #define I2C_CLASS_TV_DIGITAL (1<<2) /* dvb cards */ -#define I2C_CLASS_DDC (1<<3) /* i2c-matroxfb ? */ +#define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ #define I2C_CLASS_CAM_ANALOG (1<<4) /* camera with analog CCD */ #define I2C_CLASS_CAM_DIGITAL (1<<5) /* most webcams */ #define I2C_CLASS_SOUND (1<<6) /* sound devices */ -- cgit v0.10.2 From 3401b2fff38fbb8b73ea6bcc69a8370ae5d2a7a0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: i2c: Let bus drivers add SPD to their class Let general purpose I2C/SMBus bus drivers add SPD to their class. Once this is done, we will be able to tell the eeprom driver to only probe for SPD EEPROMs and similar on these buses. Note that I took a conservative approach here, adding I2C_CLASS_SPD to many drivers that have no idea whether they can host SPD EEPROMs or not. This is to make sure that the eeprom driver doesn't stop probing buses where SPD EEPROMs or equivalent live. So, bus driver maintainers and users should feel free to remove the SPD class from drivers those buses never have SPD EEPROMs or they don't want the eeprom driver to bind to them. Likewise, feel free to add the SPD class to any bus driver I might have missed. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 704436c..8d1d90a 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -473,7 +473,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter ali1535_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_ALI1535, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index da5a382..4b55ae1 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -382,7 +382,7 @@ static const struct i2c_algorithm ali1563_algorithm = { static struct i2c_adapter ali1563_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_ALI1563, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &ali1563_algorithm, }; diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 7b029b1..e922c39 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -471,7 +471,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter ali15x3_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_ALI15X3, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index f0baea6..bd4f638 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -301,7 +301,7 @@ static const struct i2c_algorithm smbus_algorithm = { struct i2c_adapter amd756_smbus = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_AMD756, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index a4f6879..0e18fe8 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -383,7 +383,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), "SMBus2 AMD8111 adapter at %04x", smbus->base); smbus->adapter.id = I2C_HW_SMBUS_AMD8111; - smbus->adapter.class = I2C_CLASS_HWMON; + smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 53af744..8164de1 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -423,7 +423,7 @@ static const struct i2c_adapter cpm_ops = { .owner = THIS_MODULE, .name = "i2c-cpm", .algo = &cpm_i2c_algo, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, }; static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index b7a9977..c251cf2 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -202,7 +202,7 @@ static struct i2c_algo_pcf_data pcf_isa_data = { static struct i2c_adapter pcf_isa_ops = { .owner = THIS_MODULE, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .id = I2C_HW_P_ELEK, .algo_data = &pcf_isa_data, .name = "i2c-elektor", diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 7c1b762..79b455a 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -140,7 +140,7 @@ static int __init i2c_gpio_probe(struct platform_device *pdev) adap->owner = THIS_MODULE; snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); adap->algo_data = bit_data; - adap->class = I2C_CLASS_HWMON; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->dev.parent = &pdev->dev; /* diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 2131192..9717ffe 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -573,7 +573,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter i801_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_I801, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 85dbf34..6f7bfde 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -740,7 +740,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ strcpy(adap->name, "IBM IIC"); i2c_set_adapdata(adap, dev); adap->id = I2C_HW_OCP; - adap->class = I2C_CLASS_HWMON; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->algo = &iic_algo; adap->client_register = NULL; adap->client_unregister = NULL; @@ -934,7 +934,7 @@ static int __devinit iic_probe(struct of_device *ofdev, strlcpy(adap->name, "IBM IIC", sizeof(adap->name)); i2c_set_adapdata(adap, dev); adap->id = I2C_HW_OCP; - adap->class = I2C_CLASS_HWMON; + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->algo = &iic_algo; adap->timeout = 1; adap->nr = dev->idx; diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 39884e7..fc2714a 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -482,7 +482,7 @@ iop3xx_i2c_probe(struct platform_device *pdev) memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); new_adapter->id = I2C_HW_IOP3XX; new_adapter->owner = THIS_MODULE; - new_adapter->class = I2C_CLASS_HWMON; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; new_adapter->dev.parent = &pdev->dev; new_adapter->nr = pdev->id; diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index c9cd46b..8d64891 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -251,7 +251,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sch_adapter = { .owner = THIS_MODULE, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a076129..10b9342 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -311,7 +311,7 @@ static struct i2c_adapter mpc_ops = { .name = "MPC adapter", .id = I2C_HW_MPC107, .algo = &mpc_algo, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .timeout = 1, }; diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 036e6a8..9e8118d 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -530,7 +530,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) drv_data->adapter.id = I2C_HW_MV64XXX; drv_data->adapter.algo = &mv64xxx_i2c_algo; drv_data->adapter.owner = THIS_MODULE; - drv_data->adapter.class = I2C_CLASS_HWMON; + drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; drv_data->adapter.timeout = pdata->timeout; drv_data->adapter.nr = pd->id; platform_set_drvdata(pd, drv_data); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 081fdf3..2654f20 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -350,7 +350,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, } smbus->adapter.owner = THIS_MODULE; smbus->adapter.id = I2C_HW_SMBUS_NFORCE2; - smbus->adapter.class = I2C_CLASS_HWMON; + smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; smbus->adapter.dev.parent = &dev->dev; diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index f145692..51ca79b 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -205,7 +205,7 @@ static const struct i2c_algorithm ocores_algorithm = { static struct i2c_adapter ocores_adapter = { .owner = THIS_MODULE, .name = "i2c-ocores", - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &ocores_algorithm, }; diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c index 1603c81..adf0fbb 100644 --- a/drivers/i2c/busses/i2c-pasemi.c +++ b/drivers/i2c/busses/i2c-pasemi.c @@ -365,7 +365,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev, smbus->adapter.owner = THIS_MODULE; snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), "PA Semi SMBus adapter at 0x%lx", smbus->base); - smbus->adapter.class = I2C_CLASS_HWMON; + smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; smbus->adapter.nr = PCI_FUNC(dev->devfn); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 2bde475..85d69f3 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -402,7 +402,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter piix4_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_PIIX4, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 63b3e2c..dcf2045 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -622,7 +622,7 @@ static struct i2c_algorithm pmcmsptwi_algo = { static struct i2c_adapter pmcmsptwi_adapter = { .owner = THIS_MODULE, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &pmcmsptwi_algo, .name = DRV_NAME, }; diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 9e8c875..007390a 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -590,7 +590,7 @@ static struct s3c24xx_i2c s3c24xx_i2c = { .owner = THIS_MODULE, .algo = &s3c24xx_i2c_algorithm, .retries = 2, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, }, }; diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 114634d..ac8822e 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -156,7 +156,7 @@ static struct i2c_adapter sibyte_board_adapter[2] = { { .owner = THIS_MODULE, .id = I2C_HW_SIBYTE, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = NULL, .algo_data = &sibyte_board_data[0], .name = "SiByte SMBus 0", @@ -164,7 +164,7 @@ static struct i2c_adapter sibyte_board_adapter[2] = { { .owner = THIS_MODULE, .id = I2C_HW_SIBYTE, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = NULL, .algo_data = &sibyte_board_data[1], .name = "SiByte SMBus 1", diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 328441b..f76944b 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -362,7 +362,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis5595_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_SIS5595, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index d7e6ff3..eb2b218 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -462,7 +462,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis630_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_SIS630, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index cde8e58..413e9e4 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -244,7 +244,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis96x_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_SIS96X, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index e37ccd8..1b7b2af 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c @@ -140,7 +140,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter stub_adapter = { .owner = THIS_MODULE, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, .name = "SMBus stub driver", }; diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 61716f6..6517f8a 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -87,7 +87,7 @@ static struct i2c_algo_bit_data bit_data = { static struct i2c_adapter vt586b_adapter = { .owner = THIS_MODULE, .id = I2C_HW_B_VIA, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .name = "VIA i2c", .algo_data = &bit_data, }; diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index c611905..7957ce5 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -311,7 +311,7 @@ static const struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter vt596_adapter = { .owner = THIS_MODULE, .id = I2C_HW_SMBUS_VIA2, - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 61abe0f..ed794b1 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -442,7 +442,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text, adapter->owner = THIS_MODULE; adapter->id = I2C_HW_SMBUS_SCX200; adapter->algo = &scx200_acb_algorithm; - adapter->class = I2C_CLASS_HWMON; + adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adapter->dev.parent = dev; mutex_init(&iface->mutex); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 145797f..839d0ea 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -353,6 +353,7 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) #define I2C_CLASS_CAM_ANALOG (1<<4) /* camera with analog CCD */ #define I2C_CLASS_CAM_DIGITAL (1<<5) /* most webcams */ #define I2C_CLASS_SOUND (1<<6) /* sound devices */ +#define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */ #define I2C_CLASS_ALL (UINT_MAX) /* all of the above */ /* i2c_client_address_data is the struct for holding default client -- cgit v0.10.2 From d4653bf946a5856a17342cd47c47d10b16b1cc22 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: i2c/eeprom: Only probe buses with DDC or SPD class The eeprom driver shouldn't probe i2c buses which don't want to be probed. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 7dee001..213a9f9 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -159,6 +159,8 @@ static struct bin_attribute eeprom_attr = { static int eeprom_attach_adapter(struct i2c_adapter *adapter) { + if (!(adapter->class & (I2C_CLASS_DDC | I2C_CLASS_SPD))) + return 0; return i2c_probe(adapter, &addr_data, eeprom_detect); } @@ -169,6 +171,12 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) struct eeprom_data *data; int err = 0; + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x50. So decline + attaching to addresses >= 0x51 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51) + goto exit; + /* There are three ways we can read the EEPROM data: (1) I2C block reads (faster, but unsupported by most adapters) (2) Consecutive byte reads (100% overhead) -- cgit v0.10.2 From 1b4dff9cd37d430bc76112396e92bb3552f37ccd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: i2c/eeprom: Fall back to SMBus read word transactions When I2C block reads are not supported by the underlying adapter, use SMBus read word transactions instead of consecutive byte reads. Reasons for this change are: * The consecutive byte read approach is not safe on multi-master buses. * While consecutive byte reads have less overhead if you only count the bytes on the bus, it takes more than twice as many transactions as with SMBus read word transactions, and each transaction has a cost: taking and releasing the adapter mutex, and for polling drivers, waiting for the transaction to complete. This change yields a significant performance boost at HZ=250 with EEPROMs on an Intel 82801 bus (basically twice as fast.) SMBus read word transactions are widely supported so I don't expect compatibility issues. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 213a9f9..9a81252 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -78,7 +78,7 @@ static struct i2c_driver eeprom_driver = { static void eeprom_update_client(struct i2c_client *client, u8 slice) { struct eeprom_data *data = i2c_get_clientdata(client); - int i, j; + int i; mutex_lock(&data->update_lock); @@ -93,15 +93,12 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice) != 32) goto exit; } else { - if (i2c_smbus_write_byte(client, slice << 5)) { - dev_dbg(&client->dev, "eeprom read start has failed!\n"); - goto exit; - } - for (i = slice << 5; i < (slice + 1) << 5; i++) { - j = i2c_smbus_read_byte(client); - if (j < 0) + for (i = slice << 5; i < (slice + 1) << 5; i += 2) { + int word = i2c_smbus_read_word_data(client, i); + if (word < 0) goto exit; - data->data[i] = (u8) j; + data->data[i] = word & 0xff; + data->data[i + 1] = word >> 8; } } data->last_updated[slice] = jiffies; @@ -177,14 +174,15 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51) goto exit; - /* There are three ways we can read the EEPROM data: + /* There are four ways we can read the EEPROM data: (1) I2C block reads (faster, but unsupported by most adapters) - (2) Consecutive byte reads (100% overhead) - (3) Regular byte data reads (200% overhead) - The third method is not implemented by this driver because all - known adapters support at least the second. */ - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA - | I2C_FUNC_SMBUS_BYTE)) + (2) Word reads (128% overhead) + (3) Consecutive byte reads (88% overhead, unsafe) + (4) Regular byte data reads (265% overhead) + The third and fourth methods are not implemented by this driver + because all known adapters support one of the first two. */ + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) goto exit; if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { @@ -212,13 +210,14 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) /* Detect the Vaio nature of EEPROMs. We use the "PCG-" or "VGN-" prefix as the signature. */ - if (address == 0x57) { + if (address == 0x57 + && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { char name[4]; name[0] = i2c_smbus_read_byte_data(new_client, 0x80); - name[1] = i2c_smbus_read_byte(new_client); - name[2] = i2c_smbus_read_byte(new_client); - name[3] = i2c_smbus_read_byte(new_client); + name[1] = i2c_smbus_read_byte_data(new_client, 0x81); + name[2] = i2c_smbus_read_byte_data(new_client, 0x82); + name[3] = i2c_smbus_read_byte_data(new_client, 0x83); if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) { dev_info(&new_client->dev, "Vaio EEPROM detected, " -- cgit v0.10.2 From e0457442fd522107204da14a2dc2cbbb5dcac5f6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: i2c: Simplify i2c_device_probe i2c_driver.id_table is mandatory now, so we can simplify i2c_device_probe() a bit. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e06067e..d6cc58a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -101,19 +101,14 @@ static int i2c_device_probe(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct i2c_driver *driver = to_i2c_driver(dev->driver); - const struct i2c_device_id *id; int status; - if (!driver->probe) + if (!driver->probe || !driver->id_table) return -ENODEV; client->driver = driver; dev_dbg(dev, "probe\n"); - if (driver->id_table) - id = i2c_match_id(driver->id_table, client); - else - id = NULL; - status = driver->probe(client, id); + status = driver->probe(client, i2c_match_id(driver->id_table, client)); if (status) client->driver = NULL; return status; -- cgit v0.10.2 From e6c3de6c146d2513332c581433caca6e5cae62bf Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: i2c-ibm_iic: Remove deprecated OCP style part The deprecated OCP style driver part is used by the "old" arch/ppc platform. This platform is scheduled for removal in June/July this year. This patch now removes the OCP driver part from the IBM I2C driver. Signed-off-by: Stefan Roese Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 6f7bfde..d8a19c1 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -42,13 +42,7 @@ #include #include #include - -#ifdef CONFIG_IBM_OCP -#include -#include -#else #include -#endif #include "i2c-ibm_iic.h" @@ -665,180 +659,6 @@ static inline u8 iic_clckdiv(unsigned int opb) return (u8)((opb + 9) / 10 - 1); } -#ifdef CONFIG_IBM_OCP -/* - * Register single IIC interface - */ -static int __devinit iic_probe(struct ocp_device *ocp){ - - struct ibm_iic_private* dev; - struct i2c_adapter* adap; - struct ocp_func_iic_data* iic_data = ocp->def->additions; - int ret; - - if (!iic_data) - printk(KERN_WARNING"ibm-iic%d: missing additional data!\n", - ocp->def->index); - - if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) { - printk(KERN_ERR "ibm-iic%d: failed to allocate device data\n", - ocp->def->index); - return -ENOMEM; - } - - dev->idx = ocp->def->index; - ocp_set_drvdata(ocp, dev); - - if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs), - "ibm_iic")) { - ret = -EBUSY; - goto fail1; - } - - if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){ - printk(KERN_ERR "ibm-iic%d: failed to ioremap device registers\n", - dev->idx); - ret = -ENXIO; - goto fail2; - } - - init_waitqueue_head(&dev->wq); - - dev->irq = iic_force_poll ? -1 : ocp->def->irq; - if (dev->irq >= 0){ - /* Disable interrupts until we finish initialization, - assumes level-sensitive IRQ setup... - */ - iic_interrupt_mode(dev, 0); - if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){ - printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", - dev->idx, dev->irq); - /* Fallback to the polling mode */ - dev->irq = -1; - } - } - - if (dev->irq < 0) - printk(KERN_WARNING "ibm-iic%d: using polling mode\n", - dev->idx); - - /* Board specific settings */ - dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0); - - /* clckdiv is the same for *all* IIC interfaces, - * but I'd rather make a copy than introduce another global. --ebs - */ - dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq); - DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv); - - /* Initialize IIC interface */ - iic_dev_init(dev); - - /* Register it with i2c layer */ - adap = &dev->adap; - adap->dev.parent = &ocp->dev; - strcpy(adap->name, "IBM IIC"); - i2c_set_adapdata(adap, dev); - adap->id = I2C_HW_OCP; - adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - adap->algo = &iic_algo; - adap->client_register = NULL; - adap->client_unregister = NULL; - adap->timeout = 1; - - /* - * If "dev->idx" is negative we consider it as zero. - * The reason to do so is to avoid sysfs names that only make - * sense when there are multiple adapters. - */ - adap->nr = dev->idx >= 0 ? dev->idx : 0; - - if ((ret = i2c_add_numbered_adapter(adap)) < 0) { - printk(KERN_ERR "ibm-iic%d: failed to register i2c adapter\n", - dev->idx); - goto fail; - } - - printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx, - dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); - - return 0; - -fail: - if (dev->irq >= 0){ - iic_interrupt_mode(dev, 0); - free_irq(dev->irq, dev); - } - - iounmap(dev->vaddr); -fail2: - release_mem_region(ocp->def->paddr, sizeof(struct iic_regs)); -fail1: - ocp_set_drvdata(ocp, NULL); - kfree(dev); - return ret; -} - -/* - * Cleanup initialized IIC interface - */ -static void __devexit iic_remove(struct ocp_device *ocp) -{ - struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp); - BUG_ON(dev == NULL); - if (i2c_del_adapter(&dev->adap)){ - printk(KERN_ERR "ibm-iic%d: failed to delete i2c adapter :(\n", - dev->idx); - /* That's *very* bad, just shutdown IRQ ... */ - if (dev->irq >= 0){ - iic_interrupt_mode(dev, 0); - free_irq(dev->irq, dev); - dev->irq = -1; - } - } else { - if (dev->irq >= 0){ - iic_interrupt_mode(dev, 0); - free_irq(dev->irq, dev); - } - iounmap(dev->vaddr); - release_mem_region(ocp->def->paddr, sizeof(struct iic_regs)); - kfree(dev); - } -} - -static struct ocp_device_id ibm_iic_ids[] __devinitdata = -{ - { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC }, - { .vendor = OCP_VENDOR_INVALID } -}; - -MODULE_DEVICE_TABLE(ocp, ibm_iic_ids); - -static struct ocp_driver ibm_iic_driver = -{ - .name = "iic", - .id_table = ibm_iic_ids, - .probe = iic_probe, - .remove = __devexit_p(iic_remove), -#if defined(CONFIG_PM) - .suspend = NULL, - .resume = NULL, -#endif -}; - -static int __init iic_init(void) -{ - printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n"); - return ocp_register_driver(&ibm_iic_driver); -} - -static void __exit iic_exit(void) -{ - ocp_unregister_driver(&ibm_iic_driver); -} - -#else /* !CONFIG_IBM_OCP */ - static int __devinit iic_request_irq(struct of_device *ofdev, struct ibm_iic_private *dev) { @@ -1011,7 +831,6 @@ static void __exit iic_exit(void) { of_unregister_platform_driver(&ibm_iic_driver); } -#endif /* CONFIG_IBM_OCP */ module_init(iic_init); module_exit(iic_exit); -- cgit v0.10.2 From d3dc685eb5ef64aa695dabb74f00440ec3ab6796 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: i2c-ibm_iic: Enable driver for all PPC4xx variants in arch/powerpc Enable the IBM I2C driver for all PPC4xx variants by adding "ibm,iic" to the compatible list. This way all currently available arch/powerpc 4xx ports can make use of this driver without any changes. Additionally all "other" compatible entries are removed since they are not needed anymore. Currently all 4xx PPC's have the same compatible I2C macro. If at some time an incompatibility is detected we can take care of this with an additional property. Signed-off-by: Stefan Roese Acked-by: Josh Boyer Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index d8a19c1..070f078 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -807,11 +807,7 @@ static int __devexit iic_remove(struct of_device *ofdev) } static const struct of_device_id ibm_iic_match[] = { - { .compatible = "ibm,iic-405ex", }, - { .compatible = "ibm,iic-405gp", }, - { .compatible = "ibm,iic-440gp", }, - { .compatible = "ibm,iic-440gpx", }, - { .compatible = "ibm,iic-440grx", }, + { .compatible = "ibm,iic", }, {} }; -- cgit v0.10.2 From 47a9b1379a5ebc8b00ba8635d1d3885fc0d51739 Mon Sep 17 00:00:00 2001 From: Uli Luckas Date: Mon, 14 Jul 2008 22:38:30 +0200 Subject: i2c-pxa: Initialize early Initialize the pxa i2c bus during subsystem initialization to make it available during driver initialization (e.g. display powerup for pxafb). Signed-off-by: Uli Luckas Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index eb69fba..78c0fc4 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1134,5 +1134,5 @@ static void __exit i2c_adap_pxa_exit(void) MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:pxa2xx-i2c"); -module_init(i2c_adap_pxa_init); +subsys_initcall(i2c_adap_pxa_init); module_exit(i2c_adap_pxa_exit); -- cgit v0.10.2 From 8a56ce1033073657572bd993595a56498baa4800 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:31 +0200 Subject: i2c: Deprecate the legacy gpio drivers The legacy pcf8574 and pcf8575 drivers should be avoided on systems using the new gpiolib code, and generally deprecated in the same way the legacy pca9539 driver is deprecated. Also, correct the pca9539 deprecation to match the current name of the preferred driver: pca953x, supporting several more chips. Signed-off-by: David Brownell Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 2da2edf..6326468 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -26,8 +26,8 @@ config SENSORS_EEPROM will be called eeprom. config SENSORS_PCF8574 - tristate "Philips PCF8574 and PCF8574A" - depends on EXPERIMENTAL + tristate "Philips PCF8574 and PCF8574A (DEPRECATED)" + depends on EXPERIMENTAL && GPIO_PCF857X = "n" default n help If you say yes here you get support for Philips PCF8574 and @@ -36,12 +36,16 @@ config SENSORS_PCF8574 This driver can also be built as a module. If so, the module will be called pcf8574. + This driver is deprecated and will be dropped soon. Use + drivers/gpio/pcf857x.c instead. + These devices are hard to detect and rarely found on mainstream hardware. If unsure, say N. config PCF8575 - tristate "Philips PCF8575" + tristate "Philips PCF8575 (DEPRECATED)" default n + depends on GPIO_PCF857X = "n" help If you say yes here you get support for Philips PCF8575 chip. This chip is a 16-bit I/O expander for the I2C bus. Several other @@ -50,12 +54,15 @@ config PCF8575 This driver can also be built as a module. If so, the module will be called pcf8575. + This driver is deprecated and will be dropped soon. Use + drivers/gpio/pcf857x.c instead. + This device is hard to detect and is rarely found on mainstream hardware. If unsure, say N. config SENSORS_PCA9539 tristate "Philips PCA9539 16-bit I/O port (DEPRECATED)" - depends on EXPERIMENTAL && GPIO_PCA9539 = "n" + depends on EXPERIMENTAL && GPIO_PCA953X = "n" help If you say yes here you get support for the Philips PCA9539 16-bit I/O port. @@ -64,7 +71,7 @@ config SENSORS_PCA9539 will be called pca9539. This driver is deprecated and will be dropped soon. Use - drivers/gpio/pca9539.c instead. + drivers/gpio/pca953x.c instead. config SENSORS_PCF8591 tristate "Philips PCF8591" -- cgit v0.10.2 From 0573d11b2bbd0e4774f33f4c1959c1939c055e96 Mon Sep 17 00:00:00 2001 From: Eric Brower Date: Mon, 14 Jul 2008 22:38:31 +0200 Subject: i2c-algo-pcf: Multi-master lost-arbitration improvement Improve lost-arbitration handling of PCF8584. This is necessary for support of a currently out-of-kernel driver for Sun Microsystems E250 environmental management; perhaps others. Signed-off-by: Eric Brower Acked-by: Dan Smolik Signed-off-by: Jean Delvare diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 8907b01..1e328d19 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -78,6 +78,36 @@ static void i2c_stop(struct i2c_algo_pcf_data *adap) set_pcf(adap, 1, I2C_PCF_STOP); } +static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) +{ + DEB2(printk(KERN_INFO + "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", + *status)); + + /* Cleanup from LAB -- reset and enable ESO. + * This resets the PCF8584; since we've lost the bus, no + * further attempts should be made by callers to clean up + * (no i2c_stop() etc.) + */ + set_pcf(adap, 1, I2C_PCF_PIN); + set_pcf(adap, 1, I2C_PCF_ESO); + + /* We pause for a time period sufficient for any running + * I2C transaction to complete -- the arbitration logic won't + * work properly until the next START is seen. + * It is assumed the bus driver or client has set a proper value. + * + * REVISIT: should probably use msleep instead of mdelay if we + * know we can sleep. + */ + if (adap->lab_mdelay) + mdelay(adap->lab_mdelay); + + DEB2(printk(KERN_INFO + "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", + get_pcf(adap, 1))); +} + static int wait_for_bb(struct i2c_algo_pcf_data *adap) { int timeout = DEF_TIMEOUT; @@ -109,23 +139,7 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) { *status = get_pcf(adap, 1); } if (*status & I2C_PCF_LAB) { - DEB2(printk(KERN_INFO - "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", - *status)); - /* Cleanup from LAB-- reset and enable ESO. - * This resets the PCF8584; since we've lost the bus, no - * further attempts should be made by callers to clean up - * (no i2c_stop() etc.) - */ - set_pcf(adap, 1, I2C_PCF_PIN); - set_pcf(adap, 1, I2C_PCF_ESO); - /* TODO: we should pause for a time period sufficient for any - * running I2C transaction to complete-- the arbitration - * logic won't work properly until the next START is seen. - */ - DEB2(printk(KERN_INFO - "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", - get_pcf(adap,1))); + handle_lab(adap, status); return(-EINTR); } #endif diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index 77afbb6..74fb6f8 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -36,6 +36,12 @@ struct i2c_algo_pcf_data { /* local settings */ int udelay; int timeout; + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; }; int i2c_pcf_add_bus(struct i2c_adapter *); -- cgit v0.10.2 From e3e7fc3c401a5d53f0599a357b3cf65d6a4f52e3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:31 +0200 Subject: i2c-algo-pcf: Drop unused struct members Struct members udelay and timeout aren't used anywhere, so drop them. Signed-off-by: Jean Delvare Acked-by: Eric Brower diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index c251cf2..7f38c01 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -196,8 +196,6 @@ static struct i2c_algo_pcf_data pcf_isa_data = { .getown = pcf_isa_getown, .getclock = pcf_isa_getclock, .waitforpin = pcf_isa_waitforpin, - .udelay = 10, - .timeout = 100, }; static struct i2c_adapter pcf_isa_ops = { diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index 74fb6f8..0177d28 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -33,10 +33,6 @@ struct i2c_algo_pcf_data { int (*getclock) (void *data); void (*waitforpin) (void); - /* local settings */ - int udelay; - int timeout; - /* Multi-master lost arbitration back-off delay (msecs) * This should be set by the bus adapter or knowledgable client * if bus is multi-mastered, else zero -- cgit v0.10.2 From 90df2cb1c8822ef8d06a2b30627e7a810218b0dd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:32 +0200 Subject: i2c-i801: Remove verbose debugging messages Dumping the register values before and after every transaction was useful during driver development but now it's only spamming the log. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9717ffe..965905f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -138,11 +138,6 @@ static int i801_transaction(int xact) int result = 0; int timeout = 0; - dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), - inb_p(SMBHSTDAT1)); - /* Make sure the SMBus host is ready to start transmitting */ /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { @@ -202,10 +197,6 @@ static int i801_transaction(int xact) dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " "(%02x)\n", temp); } - dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), - inb_p(SMBHSTDAT1)); return result; } @@ -293,11 +284,6 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, } outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); - dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i, - inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), - inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT)); - /* Make sure the SMBus host is ready to start transmitting */ temp = inb_p(SMBHSTSTS); if (i == 1) { @@ -381,10 +367,6 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, "Bad status (%02x) at end of transaction\n", temp); } - dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " - "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i, - inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), - inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT)); if (result < 0) return result; -- cgit v0.10.2 From dcb5c9239de8d3ff1c663e75f0f1c75bcb21ee20 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:32 +0200 Subject: i2c-i801: Properly report bus arbitration loss Bit BUS_ERR of the status register means that the ICH host controller lost the arbitration. Report this event as such. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 965905f..614c9e4 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -179,10 +179,8 @@ static int i801_transaction(int xact) } if (temp & SMBHSTSTS_BUS_ERR) { - result = -EIO; - dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " - "until next hard reset. (sorry!)\n"); - /* Clock stops and slave is stuck in mid-transmission */ + result = -EAGAIN; + dev_dbg(&I801_dev->dev, "Lost arbitration\n"); } if (temp & SMBHSTSTS_DEV_ERR) { @@ -339,8 +337,8 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); } else if (temp & SMBHSTSTS_BUS_ERR) { - result = -EIO; - dev_err(&I801_dev->dev, "Bus collision!\n"); + result = -EAGAIN; + dev_dbg(&I801_dev->dev, "Lost arbitration\n"); } else if (temp & SMBHSTSTS_DEV_ERR) { result = -ENXIO; dev_dbg(&I801_dev->dev, "Error: no response!\n"); -- cgit v0.10.2 From 2b73809d06649fe6c7f4294b051ca4934a34bb91 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:32 +0200 Subject: i2c-i801: Rename local variable temp to status "temp" isn't a terribly well chosen name for a local variable. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 614c9e4..73bd855 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -134,18 +134,18 @@ static unsigned int i801_features; static int i801_transaction(int xact) { - int temp; + int status; int result = 0; int timeout = 0; /* Make sure the SMBus host is ready to start transmitting */ /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ - if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { + if ((status = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n", - temp); - outb_p(temp, SMBHSTSTS); - if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp); + status); + outb_p(status, SMBHSTSTS); + if ((status = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { + dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", status); return -EBUSY; } else { dev_dbg(&I801_dev->dev, "Successful!\n"); @@ -159,8 +159,8 @@ static int i801_transaction(int xact) /* We will always wait for a fraction of a second! */ do { msleep(1); - temp = inb_p(SMBHSTSTS); - } while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT)); + status = inb_p(SMBHSTSTS); + } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { @@ -173,17 +173,17 @@ static int i801_transaction(int xact) outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT); } - if (temp & SMBHSTSTS_FAILED) { + if (status & SMBHSTSTS_FAILED) { result = -EIO; dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); } - if (temp & SMBHSTSTS_BUS_ERR) { + if (status & SMBHSTSTS_BUS_ERR) { result = -EAGAIN; dev_dbg(&I801_dev->dev, "Lost arbitration\n"); } - if (temp & SMBHSTSTS_DEV_ERR) { + if (status & SMBHSTSTS_DEV_ERR) { result = -ENXIO; dev_dbg(&I801_dev->dev, "Error: no response!\n"); } @@ -191,9 +191,9 @@ static int i801_transaction(int xact) if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) outb_p(inb(SMBHSTSTS), SMBHSTSTS); - if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { + if ((status = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " - "(%02x)\n", temp); + "(%02x)\n", status); } return result; } @@ -202,18 +202,18 @@ static int i801_transaction(int xact) static void i801_wait_hwpec(void) { int timeout = 0; - int temp; + int status; do { msleep(1); - temp = inb_p(SMBHSTSTS); - } while ((!(temp & SMBHSTSTS_INTR)) + status = inb_p(SMBHSTSTS); + } while ((!(status & SMBHSTSTS_INTR)) && (timeout++ < MAX_TIMEOUT)); if (timeout >= MAX_TIMEOUT) { dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); } - outb_p(temp, SMBHSTSTS); + outb_p(status, SMBHSTSTS); } static int i801_block_transaction_by_block(union i2c_smbus_data *data, @@ -255,7 +255,7 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, { int i, len; int smbcmd; - int temp; + int status; int result = 0; int timeout; unsigned char errmask; @@ -283,7 +283,7 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); /* Make sure the SMBus host is ready to start transmitting */ - temp = inb_p(SMBHSTSTS); + status = inb_p(SMBHSTSTS); if (i == 1) { /* Erroneous conditions before transaction: * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ @@ -293,13 +293,13 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, * Failed, Bus_Err, Dev_Err, Intr */ errmask = 0x1e; } - if (temp & errmask) { + if (status & errmask) { dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " - "Resetting...\n", temp); - outb_p(temp, SMBHSTSTS); - if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { + "Resetting...\n", status); + outb_p(status, SMBHSTSTS); + if (((status = inb_p(SMBHSTSTS)) & errmask) != 0x00) { dev_err(&I801_dev->dev, - "Reset failed! (%02x)\n", temp); + "Reset failed! (%02x)\n", status); return -EBUSY; } if (i != 1) @@ -314,9 +314,9 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, timeout = 0; do { msleep(1); - temp = inb_p(SMBHSTSTS); + status = inb_p(SMBHSTSTS); } - while ((!(temp & SMBHSTSTS_BYTE_DONE)) + while ((!(status & SMBHSTSTS_BYTE_DONE)) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ @@ -332,14 +332,14 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); } - if (temp & SMBHSTSTS_FAILED) { + if (status & SMBHSTSTS_FAILED) { result = -EIO; dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); - } else if (temp & SMBHSTSTS_BUS_ERR) { + } else if (status & SMBHSTSTS_BUS_ERR) { result = -EAGAIN; dev_dbg(&I801_dev->dev, "Lost arbitration\n"); - } else if (temp & SMBHSTSTS_DEV_ERR) { + } else if (status & SMBHSTSTS_DEV_ERR) { result = -ENXIO; dev_dbg(&I801_dev->dev, "Error: no response!\n"); } @@ -357,13 +357,13 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, data->block[i] = inb_p(SMBBLKDAT); if (read_write == I2C_SMBUS_WRITE && i+1 <= len) outb_p(data->block[i+1], SMBBLKDAT); - if ((temp & 0x9e) != 0x00) - outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */ + if ((status & 0x9e) != 0x00) + outb_p(status, SMBHSTSTS); /* signals SMBBLKDAT ready */ - if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { + if ((status = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(&I801_dev->dev, "Bad status (%02x) at end of transaction\n", - temp); + status); } if (result < 0) -- cgit v0.10.2 From cf898dc5e9dfd1487b28ca0176b68722f05d4d48 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: i2c-i801: Fix handling of error conditions Move the check of pre-transaction and post-transaction conditions to separate functions, and adjust them a bit. Having dedicated functions for that ensures that errors are handled in a consistent way. Bit HOST_BUSY of the status register is read-only, so writing to it is certainly not going to clear it. If this bit is set then we simply don't want to start the transaction, as it means that somebody else (ACPI, SMM?) is already using the controller. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 73bd855..46aa41f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -4,7 +4,7 @@ Copyright (c) 1998 - 2002 Frodo Looijaard , Philip Edelbrock , and Mark D. Studebaker - Copyright (C) 2007 Jean Delvare + Copyright (C) 2007, 2008 Jean Delvare 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 @@ -121,6 +121,10 @@ #define SMBHSTSTS_INTR 0x02 #define SMBHSTSTS_HOST_BUSY 0x01 +#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \ + SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ + SMBHSTSTS_INTR) + static unsigned long i801_smba; static unsigned char i801_original_hstcfg; static struct pci_driver i801_driver; @@ -132,72 +136,114 @@ static struct pci_dev *I801_dev; #define FEATURE_I2C_BLOCK_READ (1 << 3) static unsigned int i801_features; -static int i801_transaction(int xact) +/* Make sure the SMBus host is ready to start transmitting. + Return 0 if it is, -EBUSY if it is not. */ +static int i801_check_pre(void) { int status; - int result = 0; - int timeout = 0; - /* Make sure the SMBus host is ready to start transmitting */ - /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ - if ((status = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n", + status = inb_p(SMBHSTSTS); + if (status & SMBHSTSTS_HOST_BUSY) { + dev_err(&I801_dev->dev, "SMBus is busy, can't use it!\n"); + return -EBUSY; + } + + status &= STATUS_FLAGS; + if (status) { + dev_dbg(&I801_dev->dev, "Clearing status flags (%02x)\n", status); outb_p(status, SMBHSTSTS); - if ((status = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", status); + status = inb_p(SMBHSTSTS) & STATUS_FLAGS; + if (status) { + dev_err(&I801_dev->dev, + "Failed clearing status flags (%02x)\n", + status); return -EBUSY; - } else { - dev_dbg(&I801_dev->dev, "Successful!\n"); } } - /* the current contents of SMBHSTCNT can be overwritten, since PEC, - * INTREN, SMBSCMD are passed in xact */ - outb_p(xact | I801_START, SMBHSTCNT); + return 0; +} - /* We will always wait for a fraction of a second! */ - do { - msleep(1); - status = inb_p(SMBHSTSTS); - } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT)); +/* Convert the status register to an error code, and clear it. */ +static int i801_check_post(int status, int timeout) +{ + int result = 0; /* If the SMBus is still busy, we give up */ - if (timeout >= MAX_TIMEOUT) { - dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); - result = -ETIMEDOUT; + if (timeout) { + dev_err(&I801_dev->dev, "Transaction timeout\n"); /* try to stop the current command */ dev_dbg(&I801_dev->dev, "Terminating the current operation\n"); outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT); msleep(1); outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT); + + /* Check if it worked */ + status = inb_p(SMBHSTSTS); + if ((status & SMBHSTSTS_HOST_BUSY) || + !(status & SMBHSTSTS_FAILED)) + dev_err(&I801_dev->dev, + "Failed terminating the transaction\n"); + outb_p(STATUS_FLAGS, SMBHSTSTS); + return -ETIMEDOUT; } if (status & SMBHSTSTS_FAILED) { result = -EIO; - dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); + dev_err(&I801_dev->dev, "Transaction failed\n"); + } + if (status & SMBHSTSTS_DEV_ERR) { + result = -ENXIO; + dev_dbg(&I801_dev->dev, "No response\n"); } - if (status & SMBHSTSTS_BUS_ERR) { result = -EAGAIN; dev_dbg(&I801_dev->dev, "Lost arbitration\n"); } - if (status & SMBHSTSTS_DEV_ERR) { - result = -ENXIO; - dev_dbg(&I801_dev->dev, "Error: no response!\n"); + if (result) { + /* Clear error flags */ + outb_p(status & STATUS_FLAGS, SMBHSTSTS); + status = inb_p(SMBHSTSTS) & STATUS_FLAGS; + if (status) { + dev_warn(&I801_dev->dev, "Failed clearing status " + "flags at end of transaction (%02x)\n", + status); + } } - if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) - outb_p(inb(SMBHSTSTS), SMBHSTSTS); - - if ((status = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " - "(%02x)\n", status); - } return result; } +static int i801_transaction(int xact) +{ + int status; + int result; + int timeout = 0; + + result = i801_check_pre(); + if (result < 0) + return result; + + /* the current contents of SMBHSTCNT can be overwritten, since PEC, + * INTREN, SMBSCMD are passed in xact */ + outb_p(xact | I801_START, SMBHSTCNT); + + /* We will always wait for a fraction of a second! */ + do { + msleep(1); + status = inb_p(SMBHSTSTS); + } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT)); + + result = i801_check_post(status, timeout >= MAX_TIMEOUT); + if (result < 0) + return result; + + outb_p(SMBHSTSTS_INTR, SMBHSTSTS); + return 0; +} + /* wait for INTR bit as advised by Intel */ static void i801_wait_hwpec(void) { @@ -256,9 +302,12 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, int i, len; int smbcmd; int status; - int result = 0; + int result; int timeout; - unsigned char errmask; + + result = i801_check_pre(); + if (result < 0) + return result; len = data->block[0]; @@ -282,31 +331,6 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, } outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); - /* Make sure the SMBus host is ready to start transmitting */ - status = inb_p(SMBHSTSTS); - if (i == 1) { - /* Erroneous conditions before transaction: - * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ - errmask = 0x9f; - } else { - /* Erroneous conditions during transaction: - * Failed, Bus_Err, Dev_Err, Intr */ - errmask = 0x1e; - } - if (status & errmask) { - dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " - "Resetting...\n", status); - outb_p(status, SMBHSTSTS); - if (((status = inb_p(SMBHSTSTS)) & errmask) != 0x00) { - dev_err(&I801_dev->dev, - "Reset failed! (%02x)\n", status); - return -EBUSY; - } - if (i != 1) - /* if die in middle of block transaction, fail */ - return -EIO; - } - if (i == 1) outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); @@ -319,36 +343,23 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, while ((!(status & SMBHSTSTS_BYTE_DONE)) && (timeout++ < MAX_TIMEOUT)); - /* If the SMBus is still busy, we give up */ - if (timeout >= MAX_TIMEOUT) { - /* try to stop the current command */ - dev_dbg(&I801_dev->dev, "Terminating the current " - "operation\n"); - outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT); - msleep(1); - outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), - SMBHSTCNT); - result = -ETIMEDOUT; - dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); - } - - if (status & SMBHSTSTS_FAILED) { - result = -EIO; - dev_dbg(&I801_dev->dev, - "Error: Failed bus transaction\n"); - } else if (status & SMBHSTSTS_BUS_ERR) { - result = -EAGAIN; - dev_dbg(&I801_dev->dev, "Lost arbitration\n"); - } else if (status & SMBHSTSTS_DEV_ERR) { - result = -ENXIO; - dev_dbg(&I801_dev->dev, "Error: no response!\n"); - } + result = i801_check_post(status, timeout >= MAX_TIMEOUT); + if (result < 0) + return result; if (i == 1 && read_write == I2C_SMBUS_READ && command != I2C_SMBUS_I2C_BLOCK_DATA) { len = inb_p(SMBHSTDAT0); - if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) + if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) { + dev_err(&I801_dev->dev, + "Illegal SMBus block read size %d\n", + len); + /* Recover */ + while (inb_p(SMBHSTSTS) & SMBHSTSTS_HOST_BUSY) + outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS); + outb_p(SMBHSTSTS_INTR, SMBHSTSTS); return -EPROTO; + } data->block[0] = len; } @@ -357,19 +368,12 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, data->block[i] = inb_p(SMBBLKDAT); if (read_write == I2C_SMBUS_WRITE && i+1 <= len) outb_p(data->block[i+1], SMBBLKDAT); - if ((status & 0x9e) != 0x00) - outb_p(status, SMBHSTSTS); /* signals SMBBLKDAT ready */ - if ((status = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, - "Bad status (%02x) at end of transaction\n", - status); - } - - if (result < 0) - return result; + /* signals SMBBLKDAT ready */ + outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS); } - return result; + + return 0; } static int i801_set_block_buffer_mode(void) -- cgit v0.10.2 From 392a0408fdc4c9069c32a9a02b0088eae76c4618 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: i2c-sibyte: SWARM I2C board initialization The standard rtc-m41t80.c driver cannot be used with the SWARM as it is, because the board does not provide setup information for the I2C core. As a result the bus and the address to probe for the M41T80 chip is not known. Here is a set of changes that fix the problem: 1. swarm-i2c.c -- SWARM I2C board setup, currently for the M41T80 chip on the bus #1 only (there is a MAX6654 temperature sensor on the bus #0 which may be added in the future if we have a driver for that chip). 2. The i2c-sibyte.c BCM1250A SMBus controller driver now registers its buses as numbered so that board setup is correctly applied. Signed-off-by: Maciej W. Rozycki Signed-off-by: Jean Delvare diff --git a/arch/mips/sibyte/swarm/Makefile b/arch/mips/sibyte/swarm/Makefile index 1775755..255d692 100644 --- a/arch/mips/sibyte/swarm/Makefile +++ b/arch/mips/sibyte/swarm/Makefile @@ -1,3 +1,4 @@ obj-y := setup.o rtc_xicor1241.o rtc_m41t81.o +obj-$(CONFIG_I2C_BOARDINFO) += swarm-i2c.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/sibyte/swarm/swarm-i2c.c b/arch/mips/sibyte/swarm/swarm-i2c.c new file mode 100644 index 0000000..4282ac9 --- /dev/null +++ b/arch/mips/sibyte/swarm/swarm-i2c.c @@ -0,0 +1,37 @@ +/* + * arch/mips/sibyte/swarm/swarm-i2c.c + * + * Broadcom BCM91250A (SWARM), etc. I2C platform setup. + * + * Copyright (c) 2008 Maciej W. Rozycki + * + * 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 +#include +#include + + +static struct i2c_board_info swarm_i2c_info1[] __initdata = { + { + I2C_BOARD_INFO("m41t81", 0x68), + }, +}; + +static int __init swarm_i2c_init(void) +{ + int err; + + err = i2c_register_board_info(1, swarm_i2c_info1, + ARRAY_SIZE(swarm_i2c_info1)); + if (err < 0) + printk(KERN_ERR + "swarm-i2c: cannot register board I2C devices\n"); + return err; +} + +arch_initcall(swarm_i2c_init); diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index ac8822e..4ddefbf 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -143,7 +143,7 @@ static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); - return i2c_add_adapter(i2c_adap); + return i2c_add_numbered_adapter(i2c_adap); } @@ -159,6 +159,7 @@ static struct i2c_adapter sibyte_board_adapter[2] = { .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = NULL, .algo_data = &sibyte_board_data[0], + .nr = 0, .name = "SiByte SMBus 0", }, { @@ -167,6 +168,7 @@ static struct i2c_adapter sibyte_board_adapter[2] = { .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .algo = NULL, .algo_data = &sibyte_board_data[1], + .nr = 1, .name = "SiByte SMBus 1", }, }; -- cgit v0.10.2 From 2373c1801afd06d3a206376902b39a98458c9cfb Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: i2c-ocores: basic PM support Basic PM support: reinit the core on resume, disable it on suspend. Signed-off-by: Manuel Lauss Acked-by: Peter Korsgaard Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 51ca79b..e5193bf 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -29,6 +29,7 @@ struct ocores_i2c { int pos; int nmsgs; int state; /* see STATE_ */ + int clock_khz; }; /* registers */ @@ -173,8 +174,7 @@ static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) return -ETIMEDOUT; } -static void ocores_init(struct ocores_i2c *i2c, - struct ocores_i2c_platform_data *pdata) +static void ocores_init(struct ocores_i2c *i2c) { int prescale; u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); @@ -182,7 +182,7 @@ static void ocores_init(struct ocores_i2c *i2c, /* make sure the device is disabled */ oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); - prescale = (pdata->clock_khz / (5*100)) - 1; + prescale = (i2c->clock_khz / (5*100)) - 1; oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); @@ -248,7 +248,8 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) } i2c->regstep = pdata->regstep; - ocores_init(i2c, pdata); + i2c->clock_khz = pdata->clock_khz; + ocores_init(i2c); init_waitqueue_head(&i2c->wait); ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c); @@ -312,13 +313,40 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev) return 0; } +#ifdef CONFIG_PM +static int ocores_i2c_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); + + /* make sure the device is disabled */ + oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); + + return 0; +} + +static int ocores_i2c_resume(struct platform_device *pdev) +{ + struct ocores_i2c *i2c = platform_get_drvdata(pdev); + + ocores_init(i2c); + + return 0; +} +#else +#define ocores_i2c_suspend NULL +#define ocores_i2c_resume NULL +#endif + /* work with hotplug and coldplug */ MODULE_ALIAS("platform:ocores-i2c"); static struct platform_driver ocores_i2c_driver = { - .probe = ocores_i2c_probe, - .remove = __devexit_p(ocores_i2c_remove), - .driver = { + .probe = ocores_i2c_probe, + .remove = __devexit_p(ocores_i2c_remove), + .suspend = ocores_i2c_suspend, + .resume = ocores_i2c_resume, + .driver = { .owner = THIS_MODULE, .name = "ocores-i2c", }, -- cgit v0.10.2 From 54fb4a05af0a4b814e6716cfdf3fa97fc6be7a32 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: i2c: Check for ACPI resource conflicts Check for ACPI resource conflicts in i2c bus drivers. I've included all recent SMBus master drivers for PC hardware. I've voluntarily left out: * Drivers that don't run on PCs: they can't conflict with ACPI. * Bit-banged bus device drivers: it's very unlikely that ACPI would deal with such buses. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 8d1d90a..442d559 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -61,6 +61,7 @@ #include #include #include +#include #include @@ -159,6 +160,11 @@ static int ali1535_setup(struct pci_dev *dev) goto exit; } + retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE, + ali1535_driver.name); + if (retval) + goto exit; + if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, ali1535_driver.name)) { dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n", diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 4b55ae1..fc3e5b0 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -21,6 +21,7 @@ #include #include #include +#include #define ALI1563_MAX_TIMEOUT 500 #define ALI1563_SMBBA 0x80 @@ -356,6 +357,10 @@ static int __devinit ali1563_setup(struct pci_dev * dev) } } + if (acpi_check_region(ali1563_smba, ALI1563_SMB_IOSIZE, + ali1563_pci_driver.name)) + goto Err; + if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE, ali1563_pci_driver.name)) { dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n", diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index e922c39..a030abd 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -68,6 +68,7 @@ #include #include #include +#include #include /* ALI15X3 SMBus address offsets */ @@ -166,6 +167,10 @@ static int ali15x3_setup(struct pci_dev *ALI15X3_dev) if(force_addr) ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1); + if (acpi_check_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, + ali15x3_driver.name)) + return -EBUSY; + if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, ali15x3_driver.name)) { dev_err(&ALI15X3_dev->dev, diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index bd4f638..26acc65 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -45,6 +45,7 @@ #include #include #include +#include #include /* AMD756 SMBus address offsets */ @@ -368,6 +369,11 @@ static int __devinit amd756_probe(struct pci_dev *pdev, amd756_ioport += SMB_ADDR_OFFSET; } + error = acpi_check_region(amd756_ioport, SMB_IOSIZE, + amd756_driver.name); + if (error) + return error; + if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", amd756_ioport); diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 0e18fe8..3972208 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -16,6 +16,7 @@ #include #include #include +#include #include MODULE_LICENSE("GPL"); @@ -374,6 +375,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev, smbus->base = pci_resource_start(dev, 0); smbus->size = pci_resource_len(dev, 0); + error = acpi_check_resource_conflict(&dev->resource[0]); + if (error) + goto out_kfree; + if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { error = -EBUSY; goto out_kfree; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 46aa41f..8d0bc4b 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -64,6 +64,7 @@ #include #include #include +#include #include /* I801 SMBus address offsets */ @@ -624,6 +625,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id goto exit; } + err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); + if (err) + goto exit; + err = pci_request_region(dev, SMBBAR, i801_driver.name); if (err) { dev_err(&dev->dev, "Failed to request SMBus region " diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 8d64891..b9c01aa 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -35,6 +35,7 @@ #include #include #include +#include /* SCH SMBus address offsets */ #define SMBHSTCNT (0 + sch_smba) @@ -279,6 +280,8 @@ static int __devinit sch_probe(struct pci_dev *dev, dev_err(&dev->dev, "SMBus base address uninitialized!\n"); return -ENODEV; } + if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name)) + return -EBUSY; if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", sch_smba); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 2654f20..3b19bc4 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -51,6 +51,7 @@ #include #include #include +#include #include MODULE_LICENSE("GPL"); @@ -343,6 +344,11 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, smbus->size = 64; } + error = acpi_check_region(smbus->base, smbus->size, + nforce2_driver.name); + if (error) + return -1; + if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", smbus->base, smbus->base+smbus->size-1, name); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 85d69f3..924e84a 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -168,6 +169,9 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, } } + if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) + return -EBUSY; + if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", piix4_smba); diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index f76944b..3c8e0e1 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -62,6 +62,7 @@ #include #include #include +#include #include static int blacklist[] = { @@ -174,6 +175,11 @@ static int sis5595_setup(struct pci_dev *SIS5595_dev) /* NB: We grab just the two SMBus registers here, but this may still * interfere with ACPI :-( */ + retval = acpi_check_region(sis5595_base + SMB_INDEX, 2, + sis5595_driver.name); + if (retval) + return retval; + if (!request_region(sis5595_base + SMB_INDEX, 2, sis5595_driver.name)) { dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n", diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index eb2b218..72c29a6 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -55,6 +55,7 @@ #include #include #include +#include #include /* SIS630 SMBus registers */ @@ -437,6 +438,11 @@ static int sis630_setup(struct pci_dev *sis630_dev) dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base); + retval = acpi_check_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, + sis630_driver.name); + if (retval) + goto exit; + /* Everything is happy, let's grab the memory and set things up. */ if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, sis630_driver.name)) { diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 413e9e4..848b37c 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -40,6 +40,7 @@ #include #include #include +#include #include /* base address register in PCI config space */ @@ -281,6 +282,10 @@ static int __devinit sis96x_probe(struct pci_dev *dev, dev_info(&dev->dev, "SiS96x SMBus base address: 0x%04x\n", sis96x_smbus_base); + retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]); + if (retval) + return retval; + /* Everything is happy, let's grab the memory and set things up. */ if (!request_region(sis96x_smbus_base, SMB_IOSIZE, sis96x_driver.name)) { diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 7957ce5..faef995 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -50,6 +50,7 @@ #include #include #include +#include #include static struct pci_dev *vt596_pdev; @@ -356,6 +357,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev, } found: + error = acpi_check_region(vt596_smba, 8, vt596_driver.name); + if (error) + return error; + if (!request_region(vt596_smba, 8, vt596_driver.name)) { dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", vt596_smba); -- cgit v0.10.2 From 954a99307f256f1badd751a2e128c09af235c317 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:34 +0200 Subject: i2c: Drop stray references to lm_sensors Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 442d559..9cead9b 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -1,6 +1,4 @@ /* - i2c-ali1535.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 2000 Frodo Looijaard , Philip Edelbrock , Mark D. Studebaker , diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index a030abd..234fdde 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -1,6 +1,4 @@ /* - ali15x3.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 1999 Frodo Looijaard and Philip Edelbrock and Mark D. Studebaker diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 26acc65..1ea3925 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -1,7 +1,4 @@ /* - amd756.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 1999-2002 Merlin Hughes Shamelessly ripped from i2c-piix4.c: diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c index f9972f9..1098f21 100644 --- a/drivers/i2c/busses/i2c-hydra.c +++ b/drivers/i2c/busses/i2c-hydra.c @@ -1,7 +1,4 @@ /* - i2c-hydra.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring - i2c Support for the Apple `Hydra' Mac I/O Copyright (c) 1999-2004 Geert Uytterhoeven diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 8d0bc4b..dc7ea32 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1,6 +1,4 @@ /* - i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 1998 - 2002 Frodo Looijaard , Philip Edelbrock , and Mark D. Studebaker diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 924e84a..eaa9b38 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -1,6 +1,4 @@ /* - piix4.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 1998 - 2002 Frodo Looijaard and Philip Edelbrock diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 3c8e0e1..dfc2d5e 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -1,6 +1,4 @@ /* - sis5595.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 1998, 1999 Frodo Looijaard and Philip Edelbrock diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 72c29a6..e7c4b79 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -1,7 +1,4 @@ /* - i2c-sis630.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 2002,2003 Alexander Malysh This program is free software; you can redistribute it and/or modify diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 848b37c..f1bba63 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -1,7 +1,4 @@ /* - sis96x.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 2003 Mark M. Hoffman This program is free software; you can redistribute it and/or modify diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 6517f8a..29cef04 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -1,7 +1,4 @@ /* - i2c-via.c - Part of lm_sensors, Linux kernel modules - for hardware monitoring - i2c Support for Via Technologies 82C586B South Bridge Copyright (c) 1998, 1999 Kyösti Mälkki diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index faef995..862eb35 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -1,6 +1,4 @@ /* - i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 1998 - 2002 Frodo Looijaard , Philip Edelbrock , Kyösti Mälkki , Mark D. Studebaker diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c index 88a3447..1d4ae26 100644 --- a/drivers/i2c/busses/i2c-voodoo3.c +++ b/drivers/i2c/busses/i2c-voodoo3.c @@ -1,6 +1,4 @@ /* - voodoo3.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 1998, 1999 Frodo Looijaard , Philip Edelbrock , Ralph Metzler , and diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 9a81252..e22ec3b 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -1,15 +1,9 @@ /* - eeprom.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (C) 1998, 1999 Frodo Looijaard and Philip Edelbrock Copyright (C) 2003 Greg Kroah-Hartman Copyright (C) 2003 IBM Corp. - - 2004-01-16 Jean Delvare - Divide the eeprom in 32-byte (arbitrary) slices. This significantly - speeds sensors up, as well as various scripts using the eeprom - module. + Copyright (C) 2004 Jean Delvare 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 --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index e5b3132..ad2f790 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c @@ -1,6 +1,4 @@ /* - pcf8574.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (c) 2000 Frodo Looijaard , Philip Edelbrock , Dan Eaton diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index 66c7c3b..d3a2452 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c @@ -1,6 +1,4 @@ /* - pcf8591.c - Part of lm_sensors, Linux kernel modules for hardware - monitoring Copyright (C) 2001-2004 Aurelien Jarno Ported to Linux 2.6 by Aurelien Jarno with the help of Jean Delvare -- cgit v0.10.2 From f6a7110520037ba786f17b53790c6eb8a3d4ef55 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:34 +0200 Subject: i2c-dev: Delete empty detach_client callback Implementing detach_client is optional, so there is no point in an empty implementation. Likewise, i2c driver IDs are optional, and we don't need one. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index e96d986..50df536 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -548,19 +548,12 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) return 0; } -static int i2cdev_detach_client(struct i2c_client *client) -{ - return 0; -} - static struct i2c_driver i2cdev_driver = { .driver = { .name = "dev_driver", }, - .id = I2C_DRIVERID_I2CDEV, .attach_adapter = i2cdev_attach_adapter, .detach_adapter = i2cdev_detach_adapter, - .detach_client = i2cdev_detach_client, }; /* ------------------------------------------------------------------------- */ diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 988e566..ef13b7c6 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -91,8 +91,6 @@ #define I2C_DRIVERID_M52790 95 /* Mitsubishi M52790SP/FP AV switch */ #define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ -#define I2C_DRIVERID_I2CDEV 900 - #define I2C_DRIVERID_OV7670 1048 /* Omnivision 7670 camera */ /* -- cgit v0.10.2 From f09f71b24e77a2f2b4e5c98311c8804fc61ad8bc Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 14 Jul 2008 22:38:34 +0200 Subject: i2c-au1550: Fix PM support Fix driver power management: - suspend the PSC while driver is idle. - move PSC init/deinit to separate functions, as PSC must be initialized/shutdown on resume/suspend. Signed-off-by: Manuel Lauss Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index cae9dc8..66a04c2 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -269,9 +269,13 @@ static int au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct i2c_au1550_data *adap = i2c_adap->algo_data; + volatile psc_smb_t *sp = (volatile psc_smb_t *)adap->psc_base; struct i2c_msg *p; int i, err = 0; + sp->psc_ctrl = PSC_CTRL_ENABLE; + au_sync(); + for (i = 0; !err && i < num; i++) { p = &msgs[i]; err = do_address(adap, p->addr, p->flags & I2C_M_RD, @@ -288,6 +292,10 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) */ if (err == 0) err = num; + + sp->psc_ctrl = PSC_CTRL_SUSPEND; + au_sync(); + return err; } @@ -302,6 +310,61 @@ static const struct i2c_algorithm au1550_algo = { .functionality = au1550_func, }; +static void i2c_au1550_setup(struct i2c_au1550_data *priv) +{ + volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; + u32 stat; + + sp->psc_ctrl = PSC_CTRL_DISABLE; + au_sync(); + sp->psc_sel = PSC_SEL_PS_SMBUSMODE; + sp->psc_smbcfg = 0; + au_sync(); + sp->psc_ctrl = PSC_CTRL_ENABLE; + au_sync(); + do { + stat = sp->psc_smbstat; + au_sync(); + } while ((stat & PSC_SMBSTAT_SR) == 0); + + sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | + PSC_SMBCFG_DD_DISABLE); + + /* Divide by 8 to get a 6.25 MHz clock. The later protocol + * timings are based on this clock. + */ + sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); + sp->psc_smbmsk = PSC_SMBMSK_ALLMASK; + au_sync(); + + /* Set the protocol timer values. See Table 71 in the + * Au1550 Data Book for standard timing values. + */ + sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ + PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ + PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ + PSC_SMBTMR_SET_CH(15); + au_sync(); + + sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE; + do { + stat = sp->psc_smbstat; + au_sync(); + } while ((stat & PSC_SMBSTAT_SR) == 0); + + sp->psc_ctrl = PSC_CTRL_SUSPEND; + au_sync(); +} + +static void i2c_au1550_disable(struct i2c_au1550_data *priv) +{ + volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; + + sp->psc_smbcfg = 0; + sp->psc_ctrl = PSC_CTRL_DISABLE; + au_sync(); +} + /* * registering functions to load algorithms at runtime * Prior to calling us, the 50MHz clock frequency and routing @@ -311,9 +374,7 @@ static int __devinit i2c_au1550_probe(struct platform_device *pdev) { struct i2c_au1550_data *priv; - volatile psc_smb_t *sp; struct resource *r; - u32 stat; int ret; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -348,43 +409,7 @@ i2c_au1550_probe(struct platform_device *pdev) /* Now, set up the PSC for SMBus PIO mode. */ - sp = (volatile psc_smb_t *)priv->psc_base; - sp->psc_ctrl = PSC_CTRL_DISABLE; - au_sync(); - sp->psc_sel = PSC_SEL_PS_SMBUSMODE; - sp->psc_smbcfg = 0; - au_sync(); - sp->psc_ctrl = PSC_CTRL_ENABLE; - au_sync(); - do { - stat = sp->psc_smbstat; - au_sync(); - } while ((stat & PSC_SMBSTAT_SR) == 0); - - sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | - PSC_SMBCFG_DD_DISABLE); - - /* Divide by 8 to get a 6.25 MHz clock. The later protocol - * timings are based on this clock. - */ - sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); - sp->psc_smbmsk = PSC_SMBMSK_ALLMASK; - au_sync(); - - /* Set the protocol timer values. See Table 71 in the - * Au1550 Data Book for standard timing values. - */ - sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \ - PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \ - PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \ - PSC_SMBTMR_SET_CH(15); - au_sync(); - - sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE; - do { - stat = sp->psc_smbstat; - au_sync(); - } while ((stat & PSC_SMBSTAT_DR) == 0); + i2c_au1550_setup(priv); ret = i2c_add_numbered_adapter(&priv->adap); if (ret == 0) { @@ -392,10 +417,7 @@ i2c_au1550_probe(struct platform_device *pdev) return 0; } - /* disable the PSC */ - sp->psc_smbcfg = 0; - sp->psc_ctrl = PSC_CTRL_DISABLE; - au_sync(); + i2c_au1550_disable(priv); release_resource(priv->ioarea); kfree(priv->ioarea); @@ -409,27 +431,24 @@ static int __devexit i2c_au1550_remove(struct platform_device *pdev) { struct i2c_au1550_data *priv = platform_get_drvdata(pdev); - volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; platform_set_drvdata(pdev, NULL); i2c_del_adapter(&priv->adap); - sp->psc_smbcfg = 0; - sp->psc_ctrl = PSC_CTRL_DISABLE; - au_sync(); + i2c_au1550_disable(priv); release_resource(priv->ioarea); kfree(priv->ioarea); kfree(priv); return 0; } +#ifdef CONFIG_PM static int i2c_au1550_suspend(struct platform_device *pdev, pm_message_t state) { struct i2c_au1550_data *priv = platform_get_drvdata(pdev); - volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; - sp->psc_ctrl = PSC_CTRL_SUSPEND; - au_sync(); + i2c_au1550_disable(priv); + return 0; } @@ -437,14 +456,15 @@ static int i2c_au1550_resume(struct platform_device *pdev) { struct i2c_au1550_data *priv = platform_get_drvdata(pdev); - volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; - sp->psc_ctrl = PSC_CTRL_ENABLE; - au_sync(); - while (!(sp->psc_smbstat & PSC_SMBSTAT_SR)) - au_sync(); + i2c_au1550_setup(priv); + return 0; } +#else +#define i2c_au1550_suspend NULL +#define i2c_au1550_resume NULL +#endif static struct platform_driver au1xpsc_smbus_driver = { .driver = { -- cgit v0.10.2 From e9ca9eb9d7fc7bf3dc3cec5ba7edb089c4625f7b Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 14 Jul 2008 22:38:35 +0200 Subject: i2c: Export the i2c_bus_type symbol Export the root of the i2c bus so that PowerPC device tree code can iterate over devices on the i2c bus. Signed-off-by: Jon Smirl Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d6cc58a..e45bb28 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -201,7 +201,7 @@ static struct device_attribute i2c_dev_attrs[] = { { }, }; -static struct bus_type i2c_bus_type = { +struct bus_type i2c_bus_type = { .name = "i2c", .dev_attrs = i2c_dev_attrs, .match = i2c_device_match, @@ -212,6 +212,7 @@ static struct bus_type i2c_bus_type = { .suspend = i2c_device_suspend, .resume = i2c_device_resume, }; +EXPORT_SYMBOL_GPL(i2c_bus_type); /** diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 839d0ea..50cbab4 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -35,6 +35,8 @@ #include /* for completion */ #include +extern struct bus_type i2c_bus_type; + /* --- General options ------------------------------------------------ */ struct i2c_msg; -- cgit v0.10.2 From 2b7a5056a0a7ff17d5d2004c29c852a92a6bd632 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 14 Jul 2008 22:38:35 +0200 Subject: i2c: New-style EEPROM driver using device IDs Add a new-style driver for most I2C EEPROMs, giving sysfs read/write access to their data. Tested with various chips and clock rates. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 6326468..50e0a46 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -14,6 +14,32 @@ config DS1682 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 diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index e47aca0..39e3e69 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -10,6 +10,7 @@ # obj-$(CONFIG_DS1682) += ds1682.o +obj-$(CONFIG_AT24) += at24.o obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o obj-$(CONFIG_SENSORS_MAX6875) += max6875.o obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o diff --git a/drivers/i2c/chips/at24.c b/drivers/i2c/chips/at24.c new file mode 100644 index 0000000..e764c94 --- /dev/null +++ b/drivers/i2c/chips/at24.c @@ -0,0 +1,583 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + bool use_smbus; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = 128; +module_param(io_limit, uint, 0); +MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)"); + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; +module_param(write_timeout, uint, 0); +MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +static const struct i2c_device_id at24_ids[] = { + /* needs 8 addresses as A0-A2 are ignored */ + { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) }, + /* old variants can't be handled with this generic entry! */ + { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) }, + { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) }, + /* spd is a 24c02 in memory DIMMs */ + { "spd", AT24_DEVICE_MAGIC(2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO) }, + { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) }, + /* 24rf08 quirk is handled at i2c-core */ + { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) }, + { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) }, + { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) }, + { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) }, + { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) }, + { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) }, + { "at24", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + struct i2c_client *client; + int status, i; + + memset(msg, 0, sizeof(msg)); + + /* + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ + + /* + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + /* Smaller eeproms can work given some SMBus extension calls */ + if (at24->use_smbus) { + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + dev_dbg(&client->dev, "smbus read %zd@%d --> %d\n", + count, offset, status); + return (status < 0) ? -EIO : status; + } + + /* + * When we have a better choice than SMBus calls, use a combined + * I2C message. Write address; then read up to io_limit data bytes. + * Note that read page rollover helps us here (unlike writes). + * msgbuf is u8 and will cast to our needs. + */ + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + status = i2c_transfer(client->adapter, msg, 2); + dev_dbg(&client->dev, "i2c read %zd@%d --> %d\n", + count, offset, status); + + if (status == 2) + return count; + else if (status >= 0) + return -EIO; + else + return status; +} + +static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + ssize_t retval = 0; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + if (unlikely(!count)) + return count; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_read(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&at24->lock); + + return retval; +} + + +/* + * REVISIT: export at24_bin{read,write}() to let other kernel code use + * eeprom data. For example, it might hold a board's Ethernet address, or + * board-specific calibration data generated on the manufacturing floor. + */ + + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. This routine + * writes at most one page. + */ +static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf, + unsigned offset, size_t count) +{ + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page; + + /* Get corresponding I2C address and adjust offset */ + client = at24_translate_offset(at24, &offset); + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + /* If we'll use I2C calls for I/O, set up the message */ + if (!at24->use_smbus) { + int i = 0; + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + } + + /* + * Writes fail if the previous one didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + if (at24->use_smbus) { + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + } else { + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + } + dev_dbg(&client->dev, "write %zd@%d --> %zd (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + ssize_t retval = 0; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + if (unlikely(!count)) + return count; + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_write(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&at24->lock); + + return retval; +} + +/*-------------------------------------------------------------------------*/ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + bool writable; + bool use_smbus = false; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + kernel_ulong_t magic; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (!id->driver_data) { + err = -ENODEV; + goto err_out; + } + magic = id->driver_data; + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (chip.flags & AT24_FLAG_ADDR16) { + err = -EPFNOSUPPORT; + goto err_out; + } + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + err = -EPFNOSUPPORT; + goto err_out; + } + use_smbus = true; + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = kzalloc(sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) { + err = -ENOMEM; + goto err_out; + } + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->chip = chip; + at24->num_addresses = num_addresses; + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + at24->bin.attr.name = "eeprom"; + at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; + at24->bin.attr.owner = THIS_MODULE; + at24->bin.read = at24_bin_read; + at24->bin.size = chip.byte_len; + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + + unsigned write_max = chip.page_size; + + at24->bin.write = at24_bin_write; + at24->bin.attr.mode |= S_IWUSR; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = kmalloc(write_max + 2, GFP_KERNEL); + if (!at24->writebuf) { + err = -ENOMEM; + goto err_struct; + } + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin); + if (err) + goto err_clients; + + i2c_set_clientdata(client, at24); + + dev_info(&client->dev, "%Zd byte %s EEPROM %s\n", + at24->bin.size, client->name, + writable ? "(writable)" : "(read-only)"); + dev_dbg(&client->dev, + "page_size %d, num_addresses %d, write_max %d%s\n", + chip.page_size, num_addresses, + at24->write_max, + use_smbus ? ", use_smbus" : ""); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + kfree(at24->writebuf); +err_struct: + kfree(at24); +err_out: + dev_dbg(&client->dev, "probe error %d\n", err); + return err; +} + +static int __devexit at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &at24->bin); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + kfree(at24->writebuf); + kfree(at24); + i2c_set_clientdata(client, NULL); + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver at24_driver = { + .driver = { + .name = "at24", + .owner = THIS_MODULE, + }, + .probe = at24_probe, + .remove = __devexit_p(at24_remove), + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/i2c/at24.h b/include/linux/i2c/at24.h new file mode 100644 index 0000000..f6edd52 --- /dev/null +++ b/include/linux/i2c/at24.h @@ -0,0 +1,28 @@ +#ifndef _LINUX_AT24_H +#define _LINUX_AT24_H + +#include + +/* + * As seen through Linux I2C, differences between the most common types of I2C + * memory include: + * - How much memory is available (usually specified in bit)? + * - What write page size does it support? + * - Special flags (16 bit addresses, read_only, world readable...)? + * + * If you set up a custom eeprom type, please double-check the parameters. + * Especially page_size needs extra care, as you risk data loss if your value + * is bigger than what the chip actually supports! + */ + +struct at24_platform_data { + u32 byte_len; /* size (sum of all addr) */ + u16 page_size; /* for writes */ + u8 flags; +#define AT24_FLAG_ADDR16 0x80 /* address pointer is 16 bit */ +#define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */ +#define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */ +#define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */ +}; + +#endif /* _LINUX_AT24_H */ -- cgit v0.10.2 From b1204e6ec16468ebf89d9d818bfe425ca7adcdf3 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: i2c-ibm_iic: Register child nodes This patch completes the conversion of the IBM IIC driver to an of-platform driver. It removes the index from the IBM IIC driver and makes it an unnumbered driver. It then calls of_register_i2c_devices to properly register all the child nodes in the DTS. Signed-off-by: Sean MacLennan Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 070f078..651f2f1 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "i2c-ibm_iic.h" @@ -696,7 +697,7 @@ static int __devinit iic_probe(struct of_device *ofdev, struct device_node *np = ofdev->node; struct ibm_iic_private *dev; struct i2c_adapter *adap; - const u32 *indexp, *freq; + const u32 *freq; int ret; dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -707,14 +708,6 @@ static int __devinit iic_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, dev); - indexp = of_get_property(np, "index", NULL); - if (!indexp) { - dev_err(&ofdev->dev, "no index specified\n"); - ret = -EINVAL; - goto error_cleanup; - } - dev->idx = *indexp; - dev->vaddr = of_iomap(np, 0); if (dev->vaddr == NULL) { dev_err(&ofdev->dev, "failed to iomap device\n"); @@ -757,14 +750,16 @@ static int __devinit iic_probe(struct of_device *ofdev, adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->algo = &iic_algo; adap->timeout = 1; - adap->nr = dev->idx; - ret = i2c_add_numbered_adapter(adap); + ret = i2c_add_adapter(adap); if (ret < 0) { dev_err(&ofdev->dev, "failed to register i2c adapter\n"); goto error_cleanup; } + /* Now register all the child nodes */ + of_register_i2c_devices(adap, np); + dev_info(&ofdev->dev, "using %s mode\n", dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); -- cgit v0.10.2 From f741f673298b03b92d46e30b0b6fd0e960423665 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: i2c: Clean up old chip drivers Clean up old i2c chip drivers: * Name the i2c_client "client" instead of "new_client". * Drop useless initializations to 0. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index e22ec3b..373ea8d 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -158,7 +158,7 @@ static int eeprom_attach_adapter(struct i2c_adapter *adapter) /* This function is called by i2c_probe */ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *new_client; + struct i2c_client *client; struct eeprom_data *data; int err = 0; @@ -184,22 +184,20 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) goto exit; } - new_client = &data->client; + client = &data->client; memset(data->data, 0xff, EEPROM_SIZE); - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &eeprom_driver; - new_client->flags = 0; + i2c_set_clientdata(client, data); + client->addr = address; + client->adapter = adapter; + client->driver = &eeprom_driver; /* Fill in the remaining client fields */ - strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); - data->valid = 0; + strlcpy(client->name, "eeprom", I2C_NAME_SIZE); mutex_init(&data->update_lock); data->nature = UNKNOWN; /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) + if ((err = i2c_attach_client(client))) goto exit_kfree; /* Detect the Vaio nature of EEPROMs. @@ -208,27 +206,27 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { char name[4]; - name[0] = i2c_smbus_read_byte_data(new_client, 0x80); - name[1] = i2c_smbus_read_byte_data(new_client, 0x81); - name[2] = i2c_smbus_read_byte_data(new_client, 0x82); - name[3] = i2c_smbus_read_byte_data(new_client, 0x83); + name[0] = i2c_smbus_read_byte_data(client, 0x80); + name[1] = i2c_smbus_read_byte_data(client, 0x81); + name[2] = i2c_smbus_read_byte_data(client, 0x82); + name[3] = i2c_smbus_read_byte_data(client, 0x83); if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) { - dev_info(&new_client->dev, "Vaio EEPROM detected, " + dev_info(&client->dev, "Vaio EEPROM detected, " "enabling privacy protection\n"); data->nature = VAIO; } } /* create the sysfs eeprom file */ - err = sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr); + err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); if (err) goto exit_detach; return 0; exit_detach: - i2c_detach_client(new_client); + i2c_detach_client(client); exit_kfree: kfree(data); exit: diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index cf507b3..5a0285d 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c @@ -170,7 +170,7 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) struct i2c_client *real_client; struct i2c_client *fake_client; struct max6875_data *data; - int err = 0; + int err; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA | I2C_FUNC_SMBUS_READ_BYTE)) @@ -195,7 +195,6 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) real_client->addr = address; real_client->adapter = adapter; real_client->driver = &max6875_driver; - real_client->flags = 0; strlcpy(real_client->name, "max6875", I2C_NAME_SIZE); mutex_init(&data->update_lock); @@ -204,7 +203,6 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) fake_client->addr = address | 1; fake_client->adapter = adapter; fake_client->driver = &max6875_driver; - fake_client->flags = 0; strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE); if ((err = i2c_attach_client(real_client)) != 0) diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c index f43c4e7..58ab7f2 100644 --- a/drivers/i2c/chips/pca9539.c +++ b/drivers/i2c/chips/pca9539.c @@ -113,7 +113,7 @@ static int pca9539_attach_adapter(struct i2c_adapter *adapter) /* This function is called by i2c_probe */ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *new_client; + struct i2c_client *client; struct pca9539_data *data; int err = 0; @@ -127,29 +127,28 @@ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind) goto exit; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &pca9539_driver; - new_client->flags = 0; + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; + client->adapter = adapter; + client->driver = &pca9539_driver; if (kind < 0) { /* Detection: the pca9539 only has 8 registers (0-7). A read of 7 should succeed, but a read of 8 should fail. */ - if ((i2c_smbus_read_byte_data(new_client, 7) < 0) || - (i2c_smbus_read_byte_data(new_client, 8) >= 0)) + if ((i2c_smbus_read_byte_data(client, 7) < 0) || + (i2c_smbus_read_byte_data(client, 8) >= 0)) goto exit_kfree; } - strlcpy(new_client->name, "pca9539", I2C_NAME_SIZE); + strlcpy(client->name, "pca9539", I2C_NAME_SIZE); /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) + if ((err = i2c_attach_client(client))) goto exit_kfree; /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, + err = sysfs_create_group(&client->dev.kobj, &pca9539_defattr_group); if (err) goto exit_detach; @@ -157,7 +156,7 @@ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind) return 0; exit_detach: - i2c_detach_client(new_client); + i2c_detach_client(client); exit_kfree: kfree(data); exit: diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index ad2f790..1b3db2b 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c @@ -127,7 +127,7 @@ static int pcf8574_attach_adapter(struct i2c_adapter *adapter) /* This function is called by i2c_probe */ static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *new_client; + struct i2c_client *client; struct pcf8574_data *data; int err = 0; const char *client_name = ""; @@ -142,12 +142,11 @@ static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) goto exit; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &pcf8574_driver; - new_client->flags = 0; + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; + client->adapter = adapter; + client->driver = &pcf8574_driver; /* Now, we would do the remaining detection. But the PCF8574 is plainly impossible to detect! Stupid chip. */ @@ -166,23 +165,23 @@ static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) client_name = "pcf8574"; /* Fill in the remaining client fields and put it into the global list */ - strlcpy(new_client->name, client_name, I2C_NAME_SIZE); + strlcpy(client->name, client_name, I2C_NAME_SIZE); /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) + if ((err = i2c_attach_client(client))) goto exit_free; /* Initialize the PCF8574 chip */ - pcf8574_init_client(new_client); + pcf8574_init_client(client); /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &pcf8574_attr_group); + err = sysfs_create_group(&client->dev.kobj, &pcf8574_attr_group); if (err) goto exit_detach; return 0; exit_detach: - i2c_detach_client(new_client); + i2c_detach_client(client); exit_free: kfree(data); exit: diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index d3a2452..db73537 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c @@ -188,7 +188,7 @@ static int pcf8591_attach_adapter(struct i2c_adapter *adapter) /* This function is called by i2c_probe */ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *new_client; + struct i2c_client *client; struct pcf8591_data *data; int err = 0; @@ -203,12 +203,11 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) goto exit; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &pcf8591_driver; - new_client->flags = 0; + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; + client->adapter = adapter; + client->driver = &pcf8591_driver; /* Now, we would do the remaining detection. But the PCF8591 is plainly impossible to detect! Stupid chip. */ @@ -219,31 +218,31 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) /* Fill in the remaining client fields and put it into the global list */ - strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE); + strlcpy(client->name, "pcf8591", I2C_NAME_SIZE); mutex_init(&data->update_lock); /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) + if ((err = i2c_attach_client(client))) goto exit_kfree; /* Initialize the PCF8591 chip */ - pcf8591_init_client(new_client); + pcf8591_init_client(client); /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &pcf8591_attr_group); + err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group); if (err) goto exit_detach; /* Register input2 if not in "two differential inputs" mode */ if (input_mode != 3) { - if ((err = device_create_file(&new_client->dev, + if ((err = device_create_file(&client->dev, &dev_attr_in2_input))) goto exit_sysfs_remove; } /* Register input3 only in "four single ended inputs" mode */ if (input_mode == 0) { - if ((err = device_create_file(&new_client->dev, + if ((err = device_create_file(&client->dev, &dev_attr_in3_input))) goto exit_sysfs_remove; } @@ -251,10 +250,10 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) return 0; exit_sysfs_remove: - sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group_opt); - sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group); + sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); + sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); exit_detach: - i2c_detach_client(new_client); + i2c_detach_client(client); exit_kfree: kfree(data); exit: -- cgit v0.10.2 From 8508159e2f3b82bf109f0ec77bcbd8ff3f3a7e17 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: i2c: Call client_unregister for new-style devices too We call adapter->client_register for both legacy and new-style i2c devices, however we only call adapter->client_unregister for legacy drivers. This doesn't make much sense. Usually, drivers will undo in client_unregister what they did in client_register, so we should call neither or both for every given i2c device. In order to ease the transition from legacy to new-style devices, it seems preferable to actually call both. Signed-off-by: Jean Delvare Cc: David Brownell diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e45bb28..5e249d7 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -300,6 +300,14 @@ void i2c_unregister_device(struct i2c_client *client) return; } + if (adapter->client_unregister) { + if (adapter->client_unregister(client)) { + dev_warn(&client->dev, + "client_unregister [%s] failed\n", + client->name); + } + } + mutex_lock(&adapter->clist_lock); list_del(&client->list); mutex_unlock(&adapter->clist_lock); -- cgit v0.10.2 From 4735c98f8447acb1c8977e2b8024640f7bf36dd6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:36 +0200 Subject: i2c: Add detection capability to new-style drivers Add a mechanism to let new-style i2c drivers optionally autodetect devices they would support on selected buses and ask i2c-core to instantiate them. This is a replacement for legacy i2c drivers, much cleaner. Where drivers had to implement both a legacy i2c_driver and a new-style i2c_driver so far, this mechanism makes it possible to get rid of the legacy i2c_driver and implement both enumerated and detected device support with just one (new-style) i2c_driver. Here is a quick conversion guide for these drivers, step by step: * Delete the legacy driver definition, registration and removal. Delete the attach_adapter and detach_client methods of the legacy driver. * Change the prototype of the legacy detect function from static int foo_detect(struct i2c_adapter *adapter, int address, int kind); to static int foo_detect(struct i2c_client *client, int kind, struct i2c_board_info *info); * Set the new-style driver detect callback to this new function, and set its address_data to &addr_data (addr_data is generally provided by I2C_CLIENT_INSMOD.) * Add the appropriate class to the new-style driver. This is typically the class the legacy attach_adapter method was checking for. Class checking is now mandatory (done by i2c-core.) See for the list of available classes. * Remove the i2c_client allocation and freeing from the detect function. A pre-allocated client is now handed to you by i2c-core, and is freed automatically. * Make the detect function fill the type field of the i2c_board_info structure it was passed as a parameter, and return 0, on success. If the detection fails, return -ENODEV. Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 63722d3..6b61b3a 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -44,6 +44,10 @@ static struct i2c_driver foo_driver = { .id_table = foo_ids, .probe = foo_probe, .remove = foo_remove, + /* if device autodetection is needed: */ + .class = I2C_CLASS_SOMETHING, + .detect = foo_detect, + .address_data = &addr_data, /* else, driver uses "legacy" binding model: */ .attach_adapter = foo_attach_adapter, @@ -217,6 +221,31 @@ in the I2C bus driver. You may want to save the returned i2c_client reference for later use. +Device Detection (Standard driver model) +---------------------------------------- + +Sometimes you do not know in advance which I2C devices are connected to +a given I2C bus. This is for example the case of hardware monitoring +devices on a PC's SMBus. In that case, you may want to let your driver +detect supported devices automatically. This is how the legacy model +was working, and is now available as an extension to the standard +driver model (so that we can finally get rid of the legacy model.) + +You simply have to define a detect callback which will attempt to +identify supported devices (returning 0 for supported ones and -ENODEV +for unsupported ones), a list of addresses to probe, and a device type +(or class) so that only I2C buses which may have that type of device +connected (and not otherwise enumerated) will be probed. The i2c +core will then call you back as needed and will instantiate a device +for you for every successful detection. + +Note that this mechanism is purely optional and not suitable for all +devices. You need some reliable way to identify the supported devices +(typically using device-specific, dedicated identification registers), +otherwise misdetections are likely to occur and things can get wrong +quickly. + + Device Deletion (Standard driver model) --------------------------------------- diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 5e249d7..0a79f76 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -42,7 +42,9 @@ static DEFINE_MUTEX(core_lock); static DEFINE_IDR(i2c_adapter_idr); -#define is_newstyle_driver(d) ((d)->probe || (d)->remove) +#define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect) + +static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); /* ------------------------------------------------------------------------- */ @@ -418,6 +420,10 @@ static int i2c_do_add_adapter(struct device_driver *d, void *data) struct i2c_driver *driver = to_i2c_driver(d); struct i2c_adapter *adap = data; + /* Detect supported devices on that bus, and instantiate them */ + i2c_detect(adap, driver); + + /* Let legacy drivers scan this bus for matching devices */ if (driver->attach_adapter) { /* We ignore the return code; if it fails, too bad */ driver->attach_adapter(adap); @@ -457,7 +463,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); - /* let legacy drivers scan this bus for matching devices */ + /* Notify drivers */ dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, i2c_do_add_adapter); @@ -563,8 +569,19 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data) { struct i2c_driver *driver = to_i2c_driver(d); struct i2c_adapter *adapter = data; + struct i2c_client *client, *_n; int res; + /* Remove the devices we created ourselves */ + list_for_each_entry_safe(client, _n, &driver->clients, detected) { + if (client->adapter == adapter) { + dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", + client->name, client->addr); + list_del(&client->detected); + i2c_unregister_device(client); + } + } + if (!driver->detach_adapter) return 0; res = driver->detach_adapter(adapter); @@ -651,7 +668,11 @@ static int __attach_adapter(struct device *dev, void *data) struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; - driver->attach_adapter(adapter); + i2c_detect(adapter, driver); + + /* Legacy drivers scan i2c busses directly */ + if (driver->attach_adapter) + driver->attach_adapter(adapter); return 0; } @@ -695,10 +716,9 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); - /* legacy drivers scan i2c busses directly */ - if (driver->attach_adapter) - class_for_each_device(&i2c_adapter_class, driver, - __attach_adapter); + INIT_LIST_HEAD(&driver->clients); + /* Walk the adapters that are already present */ + class_for_each_device(&i2c_adapter_class, driver, __attach_adapter); mutex_unlock(&core_lock); return 0; @@ -709,6 +729,17 @@ static int __detach_adapter(struct device *dev, void *data) { struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; + struct i2c_client *client, *_n; + + list_for_each_entry_safe(client, _n, &driver->clients, detected) { + dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", + client->name, client->addr); + list_del(&client->detected); + i2c_unregister_device(client); + } + + if (is_newstyle_driver(driver)) + return 0; /* Have a look at each adapter, if clients of this driver are still * attached. If so, detach them to be able to kill the driver @@ -747,10 +778,7 @@ void i2c_del_driver(struct i2c_driver *driver) { mutex_lock(&core_lock); - /* legacy driver? */ - if (!is_newstyle_driver(driver)) - class_for_each_device(&i2c_adapter_class, driver, - __detach_adapter); + class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); driver_unregister(&driver->driver); pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); @@ -1205,6 +1233,179 @@ int i2c_probe(struct i2c_adapter *adapter, } EXPORT_SYMBOL(i2c_probe); +/* Separate detection function for new-style drivers */ +static int i2c_detect_address(struct i2c_client *temp_client, int kind, + struct i2c_driver *driver) +{ + struct i2c_board_info info; + struct i2c_adapter *adapter = temp_client->adapter; + int addr = temp_client->addr; + int err; + + /* Make sure the address is valid */ + 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)) + return 0; + + /* Make sure there is something at this address, unless forced */ + if (kind < 0) { + if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, + I2C_SMBUS_QUICK, NULL) < 0) + return 0; + + /* prevent 24RF08 corruption */ + if ((addr & ~0x0f) == 0x50) + i2c_smbus_xfer(adapter, addr, 0, 0, 0, + I2C_SMBUS_QUICK, NULL); + } + + /* Finally call the custom detection function */ + memset(&info, 0, sizeof(struct i2c_board_info)); + info.addr = addr; + err = driver->detect(temp_client, kind, &info); + if (err) { + /* -ENODEV is returned if the detection fails. We catch it + here as this isn't an error. */ + return err == -ENODEV ? 0 : err; + } + + /* Consistency check */ + if (info.type[0] == '\0') { + dev_err(&adapter->dev, "%s detection function provided " + "no name for 0x%x\n", driver->driver.name, + addr); + } else { + struct i2c_client *client; + + /* Detection succeeded, instantiate the device */ + dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n", + info.type, info.addr); + client = i2c_new_device(adapter, &info); + if (client) + list_add_tail(&client->detected, &driver->clients); + else + dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n", + info.type, info.addr); + } + return 0; +} + +static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) +{ + const struct i2c_client_address_data *address_data; + struct i2c_client *temp_client; + int i, err = 0; + int adap_id = i2c_adapter_id(adapter); + + address_data = driver->address_data; + if (!driver->detect || !address_data) + return 0; + + /* Set up a temporary client to help detect callback */ + temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!temp_client) + return -ENOMEM; + temp_client->adapter = adapter; + + /* Force entries are done first, and are not affected by ignore + entries */ + if (address_data->forces) { + const unsigned short * const *forces = address_data->forces; + int kind; + + for (kind = 0; forces[kind]; kind++) { + for (i = 0; forces[kind][i] != I2C_CLIENT_END; + i += 2) { + if (forces[kind][i] == adap_id + || forces[kind][i] == ANY_I2C_BUS) { + dev_dbg(&adapter->dev, "found force " + "parameter for adapter %d, " + "addr 0x%02x, kind %d\n", + adap_id, forces[kind][i + 1], + kind); + temp_client->addr = forces[kind][i + 1]; + err = i2c_detect_address(temp_client, + kind, driver); + if (err) + goto exit_free; + } + } + } + } + + /* Stop here if we can't use SMBUS_QUICK */ + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { + if (address_data->probe[0] == I2C_CLIENT_END + && address_data->normal_i2c[0] == I2C_CLIENT_END) + goto exit_free; + + dev_warn(&adapter->dev, "SMBus Quick command not supported, " + "can't probe for chips\n"); + err = -EOPNOTSUPP; + goto exit_free; + } + + /* Stop here if the classes do not match */ + if (!(adapter->class & driver->class)) + goto exit_free; + + /* Probe entries are done second, and are not affected by ignore + entries either */ + for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) { + if (address_data->probe[i] == adap_id + || address_data->probe[i] == ANY_I2C_BUS) { + dev_dbg(&adapter->dev, "found probe parameter for " + "adapter %d, addr 0x%02x\n", adap_id, + address_data->probe[i + 1]); + temp_client->addr = address_data->probe[i + 1]; + err = i2c_detect_address(temp_client, -1, driver); + if (err) + goto exit_free; + } + } + + /* Normal entries are done last, unless shadowed by an ignore entry */ + for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { + int j, ignore; + + ignore = 0; + for (j = 0; address_data->ignore[j] != I2C_CLIENT_END; + j += 2) { + if ((address_data->ignore[j] == adap_id || + address_data->ignore[j] == ANY_I2C_BUS) + && address_data->ignore[j + 1] + == address_data->normal_i2c[i]) { + dev_dbg(&adapter->dev, "found ignore " + "parameter for adapter %d, " + "addr 0x%02x\n", adap_id, + address_data->ignore[j + 1]); + ignore = 1; + break; + } + } + if (ignore) + continue; + + dev_dbg(&adapter->dev, "found normal entry for adapter %d, " + "addr 0x%02x\n", adap_id, + address_data->normal_i2c[i]); + temp_client->addr = address_data->normal_i2c[i]; + err = i2c_detect_address(temp_client, -1, driver); + if (err) + goto exit_free; + } + + exit_free: + kfree(temp_client); + return err; +} + struct i2c_client * i2c_new_probed_device(struct i2c_adapter *adap, struct i2c_board_info *info, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 50cbab4..08be0d2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -45,6 +45,7 @@ struct i2c_adapter; struct i2c_client; struct i2c_driver; union i2c_smbus_data; +struct i2c_board_info; /* * The master routines are the ones normally used to transmit data to devices @@ -94,15 +95,33 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, u8 command, u8 length, const u8 *values); -/* - * A driver is capable of handling one or more physical devices present on - * I2C adapters. This information is used to inform the driver of adapter - * events. +/** + * struct i2c_driver - represent an I2C device driver + * @class: What kind of i2c device we instantiate (for detect) + * @detect: Callback for device detection + * @address_data: The I2C addresses to probe, ignore or force (for detect) + * @clients: List of detected clients we created (for i2c-core use only) * * The driver.owner field should be set to the module owner of this driver. * The driver.name field should be set to the name of this driver. + * + * For automatic device detection, both @detect and @address_data must + * be defined. @class should also be set, otherwise only devices forced + * with module parameters will be created. The detect function must + * fill at least the name field of the i2c_board_info structure it is + * handed upon successful detection, and possibly also the flags field. + * + * If @detect is missing, the driver will still work fine for enumerated + * devices. Detected devices simply won't be supported. This is expected + * for the many I2C/SMBus devices which can't be detected reliably, and + * the ones which can always be enumerated in practice. + * + * The i2c_client structure which is handed to the @detect callback is + * not a real i2c_client. It is initialized just enough so that you can + * call i2c_smbus_read_byte_data and friends on it. Don't do anything + * else with it. In particular, calling dev_dbg and friends on it is + * not allowed. */ - struct i2c_driver { int id; unsigned int class; @@ -142,6 +161,11 @@ struct i2c_driver { struct device_driver driver; const struct i2c_device_id *id_table; + + /* Device detection callback for automatic device creation */ + int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); + const struct i2c_client_address_data *address_data; + struct list_head clients; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) @@ -157,6 +181,7 @@ struct i2c_driver { * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) * @list: list of active/busy clients (DEPRECATED) + * @detected: member of an i2c_driver.clients list * @released: used to synchronize client releases & detaches and references * * An i2c_client identifies a single device (i.e. chip) connected to an @@ -174,6 +199,7 @@ struct i2c_client { struct device dev; /* the device structure */ int irq; /* irq issued by device */ struct list_head list; /* DEPRECATED */ + struct list_head detected; struct completion released; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) -- cgit v0.10.2 From ce7231e92dac381f6e4f9cfdfdf9e0ea055223ad Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 13 May 2008 13:45:14 -0700 Subject: [PATCH 1/2] ocfs2: Add CONFIG_OCFS2_FS_STATS config option This patch adds config option CONFIG_OCFS2_FS_STATS to allow building the fs with instrumentation enabled. An upcoming patch will provide support to instrument cluster locking, which is a crucial overhead in a cluster file system. This config option allows users to avoid the cpu and memory overhead that is involved in gathering such statistics. Signed-off-by: Sunil Mushran Signed-off-by: Mark Fasheh diff --git a/fs/Kconfig b/fs/Kconfig index 2694648..9c07a4f 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -470,6 +470,14 @@ config OCFS2_FS_USERSPACE_CLUSTER It is safe to say Y, as the clustering method is run-time selectable. +config OCFS2_FS_STATS + bool "OCFS2 statistics" + depends on OCFS2_FS + default y + help + This option allows some fs statistics to be captured. Enabling + this option may increase the memory consumption. + config OCFS2_DEBUG_MASKLOG bool "OCFS2 logging support" depends on OCFS2_FS -- cgit v0.10.2 From 8ddb7b004dfa1832a750e199df8bff4b75b73565 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 13 May 2008 13:45:15 -0700 Subject: [PATCH 2/2] ocfs2: Instrument fs cluster locks This patch adds code to track the number of times the fs takes various cluster locks as well as the times associated with it. The information is made available to users via debugfs. This patch was originally written by Jan Kara . Signed-off-by: Sunil Mushran Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 80e20d9..80537b7 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -31,6 +31,7 @@ #include #include #include +#include #define MLOG_MASK_PREFIX ML_DLM_GLUE #include @@ -59,6 +60,9 @@ struct ocfs2_mask_waiter { struct completion mw_complete; unsigned long mw_mask; unsigned long mw_goal; +#ifdef CONFIG_OCFS2_FS_STATS + unsigned long long mw_lock_start; +#endif }; static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); @@ -366,6 +370,75 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res) spin_unlock(&ocfs2_dlm_tracking_lock); } +#ifdef CONFIG_OCFS2_FS_STATS +static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) +{ + res->l_lock_num_prmode = 0; + res->l_lock_num_prmode_failed = 0; + res->l_lock_total_prmode = 0; + res->l_lock_max_prmode = 0; + res->l_lock_num_exmode = 0; + res->l_lock_num_exmode_failed = 0; + res->l_lock_total_exmode = 0; + res->l_lock_max_exmode = 0; + res->l_lock_refresh = 0; +} + +static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level, + struct ocfs2_mask_waiter *mw, int ret) +{ + unsigned long long *num, *sum; + unsigned int *max, *failed; + struct timespec ts = current_kernel_time(); + unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start; + + if (level == LKM_PRMODE) { + num = &res->l_lock_num_prmode; + sum = &res->l_lock_total_prmode; + max = &res->l_lock_max_prmode; + failed = &res->l_lock_num_prmode_failed; + } else if (level == LKM_EXMODE) { + num = &res->l_lock_num_exmode; + sum = &res->l_lock_total_exmode; + max = &res->l_lock_max_exmode; + failed = &res->l_lock_num_exmode_failed; + } else + return; + + (*num)++; + (*sum) += time; + if (time > *max) + *max = time; + if (ret) + (*failed)++; +} + +static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) +{ + lockres->l_lock_refresh++; +} + +static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw) +{ + struct timespec ts = current_kernel_time(); + mw->mw_lock_start = timespec_to_ns(&ts); +} +#else +static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res) +{ +} +static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, + int level, struct ocfs2_mask_waiter *mw, int ret) +{ +} +static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres) +{ +} +static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw) +{ +} +#endif + static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, struct ocfs2_lock_res *res, enum ocfs2_lock_type type, @@ -385,6 +458,8 @@ static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, res->l_flags = OCFS2_LOCK_INITIALIZED; ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug); + + ocfs2_init_lock_stats(res); } void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) @@ -1048,6 +1123,7 @@ static void ocfs2_init_mask_waiter(struct ocfs2_mask_waiter *mw) { INIT_LIST_HEAD(&mw->mw_item); init_completion(&mw->mw_complete); + ocfs2_init_start_time(mw); } static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw) @@ -1254,6 +1330,7 @@ out: goto again; mlog_errno(ret); } + ocfs2_update_lock_stats(lockres, level, &mw, ret); mlog_exit(ret); return ret; @@ -1983,6 +2060,7 @@ static int ocfs2_inode_lock_update(struct inode *inode, le32_to_cpu(fe->i_flags)); ocfs2_refresh_inode(inode, fe); + ocfs2_track_lock_refresh(lockres); } status = 0; @@ -2267,6 +2345,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb, if (status < 0) mlog_errno(status); + ocfs2_track_lock_refresh(lockres); } bail: mlog_exit(status); @@ -2461,7 +2540,7 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos) } /* So that debugfs.ocfs2 can determine which format is being used */ -#define OCFS2_DLM_DEBUG_STR_VERSION 1 +#define OCFS2_DLM_DEBUG_STR_VERSION 2 static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) { int i; @@ -2502,6 +2581,47 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) for(i = 0; i < DLM_LVB_LEN; i++) seq_printf(m, "0x%x\t", lvb[i]); +#ifdef CONFIG_OCFS2_FS_STATS +# define lock_num_prmode(_l) (_l)->l_lock_num_prmode +# define lock_num_exmode(_l) (_l)->l_lock_num_exmode +# define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed +# define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed +# define lock_total_prmode(_l) (_l)->l_lock_total_prmode +# define lock_total_exmode(_l) (_l)->l_lock_total_exmode +# define lock_max_prmode(_l) (_l)->l_lock_max_prmode +# define lock_max_exmode(_l) (_l)->l_lock_max_exmode +# define lock_refresh(_l) (_l)->l_lock_refresh +#else +# define lock_num_prmode(_l) (0) +# define lock_num_exmode(_l) (0) +# define lock_num_prmode_failed(_l) (0) +# define lock_num_exmode_failed(_l) (0) +# define lock_total_prmode(_l) (0) +# define lock_total_exmode(_l) (0) +# define lock_max_prmode(_l) (0) +# define lock_max_exmode(_l) (0) +# define lock_refresh(_l) (0) +#endif + /* The following seq_print was added in version 2 of this output */ + seq_printf(m, "%llu\t" + "%llu\t" + "%u\t" + "%u\t" + "%llu\t" + "%llu\t" + "%u\t" + "%u\t" + "%u\t", + lock_num_prmode(lockres), + lock_num_exmode(lockres), + lock_num_prmode_failed(lockres), + lock_num_exmode_failed(lockres), + lock_total_prmode(lockres), + lock_total_exmode(lockres), + lock_max_prmode(lockres), + lock_max_exmode(lockres), + lock_refresh(lockres)); + /* End the line */ seq_printf(m, "\n"); return 0; diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 3169237..1cb814b 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -132,6 +132,18 @@ struct ocfs2_lock_res { wait_queue_head_t l_event; struct list_head l_debug_list; + +#ifdef CONFIG_OCFS2_FS_STATS + unsigned long long l_lock_num_prmode; /* PR acquires */ + unsigned long long l_lock_num_exmode; /* EX acquires */ + unsigned int l_lock_num_prmode_failed; /* Failed PR gets */ + unsigned int l_lock_num_exmode_failed; /* Failed EX gets */ + unsigned long long l_lock_total_prmode; /* Tot wait for PR */ + unsigned long long l_lock_total_exmode; /* Tot wait for EX */ + unsigned int l_lock_max_prmode; /* Max wait for PR */ + unsigned int l_lock_max_exmode; /* Max wait for EX */ + unsigned int l_lock_refresh; /* Disk refreshes */ +#endif }; struct ocfs2_dlm_debug { -- cgit v0.10.2 From dd25e55ea133b14678cfaa9e205b082b24b26dbc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 28 May 2008 14:41:00 -0700 Subject: ocfs2: fix printk format warnings with OCFS2_FS_STATS=n Fix printk format warnings when OCFS2_FS_STATS=n: linux-next-20080528/fs/ocfs2/dlmglue.c: In function 'ocfs2_dlm_seq_show': linux-next-20080528/fs/ocfs2/dlmglue.c:2623: warning: format '%llu' expects type 'long long unsigned int', but argument 3 has type 'int' linux-next-20080528/fs/ocfs2/dlmglue.c:2623: warning: format '%llu' expects type 'long long unsigned int', but argument 4 has type 'int' linux-next-20080528/fs/ocfs2/dlmglue.c:2623: warning: format '%llu' expects type 'long long unsigned int', but argument 7 has type 'int' linux-next-20080528/fs/ocfs2/dlmglue.c:2623: warning: format '%llu' expects type 'long long unsigned int', but argument 8 has type 'int' Signed-off-by: Randy Dunlap Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 80537b7..eae3d64 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -2592,12 +2592,12 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) # define lock_max_exmode(_l) (_l)->l_lock_max_exmode # define lock_refresh(_l) (_l)->l_lock_refresh #else -# define lock_num_prmode(_l) (0) -# define lock_num_exmode(_l) (0) +# define lock_num_prmode(_l) (0ULL) +# define lock_num_exmode(_l) (0ULL) # define lock_num_prmode_failed(_l) (0) # define lock_num_exmode_failed(_l) (0) -# define lock_total_prmode(_l) (0) -# define lock_total_exmode(_l) (0) +# define lock_total_prmode(_l) (0ULL) +# define lock_total_exmode(_l) (0ULL) # define lock_max_prmode(_l) (0) # define lock_max_exmode(_l) (0) # define lock_refresh(_l) (0) -- cgit v0.10.2 From 7600c72b75bab374ad39b2a4799a0728579a8e2f Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 9 Jun 2008 16:34:23 -0700 Subject: ocfs2: use simple_read_from_buffer() Signed-off-by: Akinobu Mita Acked-by: Joel Becker Signed-off-by: Andrew Morton Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index c021280..24e0b19 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c @@ -549,26 +549,17 @@ static ssize_t ocfs2_control_read(struct file *file, size_t count, loff_t *ppos) { - char *proto_string = OCFS2_CONTROL_PROTO; - size_t to_write = 0; - - if (*ppos >= OCFS2_CONTROL_PROTO_LEN) - return 0; - - to_write = OCFS2_CONTROL_PROTO_LEN - *ppos; - if (to_write > count) - to_write = count; - if (copy_to_user(buf, proto_string + *ppos, to_write)) - return -EFAULT; + ssize_t ret; - *ppos += to_write; + ret = simple_read_from_buffer(buf, count, ppos, + OCFS2_CONTROL_PROTO, OCFS2_CONTROL_PROTO_LEN); /* Have we read the whole protocol list? */ - if (*ppos >= OCFS2_CONTROL_PROTO_LEN) + if (ret > 0 && *ppos >= OCFS2_CONTROL_PROTO_LEN) ocfs2_control_set_handshake_state(file, OCFS2_CONTROL_HANDSHAKE_READ); - return to_write; + return ret; } static int ocfs2_control_release(struct inode *inode, struct file *file) -- cgit v0.10.2 From 56753bd3b9220f6f2477eb1cf97f40c24e0a4c91 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 9 Jun 2008 11:24:41 -0700 Subject: ocfs2: Silence an error message in ocfs2_file_aio_read() This patch silences an EINVAL error message in ocfs2_file_aio_read() that is always due to a user error. Signed-off-by: Sunil Mushran Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 57e0d30..e8514e8 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2202,7 +2202,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); if (ret == -EINVAL) - mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); + mlog(0, "generic_file_aio_read returned -EINVAL\n"); /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); -- cgit v0.10.2 From 01af482037d32c215aab208a0b110ffe6fd782c0 Mon Sep 17 00:00:00 2001 From: Wengang Wang Date: Tue, 10 Jun 2008 14:24:48 +0800 Subject: ocfs2: Handle error during journal load This patch ensures the mount fails if the fs is unable to load the journal. Signed-off-by: Wengang Wang Acked-by: Sunil Mushran Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index df63ba2..ccecfe5 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1703,7 +1703,11 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) local = ocfs2_mount_local(osb); /* will play back anything left in the journal. */ - ocfs2_journal_load(osb->journal, local); + status = ocfs2_journal_load(osb->journal, local); + if (status < 0) { + mlog(ML_ERROR, "ocfs2 journal load failed! %d\n", status); + goto finally; + } if (dirty) { /* recover my local alloc if we didn't unmount cleanly. */ -- cgit v0.10.2 From 461c6a30eca6f25add1dadb9fd8a1d8e89a6e627 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 19 May 2008 16:23:37 -0700 Subject: ocfs2/net: Silence build warnings on sparc64 suseconds_t is type long on most arches except sparc64 where it is type int. This patch silences the following warnings that are generated when building on it. netdebug.c: In function 'nst_seq_show': netdebug.c:152: warning: format '%lu' expects type 'long unsigned int', but argument 13 has type 'suseconds_t' netdebug.c:152: warning: format '%lu' expects type 'long unsigned int', but argument 15 has type 'suseconds_t' netdebug.c:152: warning: format '%lu' expects type 'long unsigned int', but argument 17 has type 'suseconds_t' netdebug.c: In function 'sc_seq_show': netdebug.c:332: warning: format '%lu' expects type 'long unsigned int', but argument 19 has type 'suseconds_t' netdebug.c:332: warning: format '%lu' expects type 'long unsigned int', but argument 21 has type 'suseconds_t' netdebug.c:332: warning: format '%lu' expects type 'long unsigned int', but argument 23 has type 'suseconds_t' netdebug.c:332: warning: format '%lu' expects type 'long unsigned int', but argument 25 has type 'suseconds_t' netdebug.c:332: warning: format '%lu' expects type 'long unsigned int', but argument 27 has type 'suseconds_t' netdebug.c:332: warning: format '%lu' expects type 'long unsigned int', but argument 29 has type 'suseconds_t' Signed-off-by: Sunil Mushran Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 7bf3c0e..d8bfa0e 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -146,8 +146,10 @@ static int nst_seq_show(struct seq_file *seq, void *v) nst->st_task->comm, nst->st_node, nst->st_sc, nst->st_id, nst->st_msg_type, nst->st_msg_key, - nst->st_sock_time.tv_sec, nst->st_sock_time.tv_usec, - nst->st_send_time.tv_sec, nst->st_send_time.tv_usec, + nst->st_sock_time.tv_sec, + (unsigned long)nst->st_sock_time.tv_usec, + nst->st_send_time.tv_sec, + (unsigned long)nst->st_send_time.tv_usec, nst->st_status_time.tv_sec, nst->st_status_time.tv_usec); } @@ -274,7 +276,7 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) return sc; /* unused, just needs to be null when done */ } -#define TV_SEC_USEC(TV) TV.tv_sec, TV.tv_usec +#define TV_SEC_USEC(TV) TV.tv_sec, (unsigned long)TV.tv_usec static int sc_seq_show(struct seq_file *seq, void *v) { -- cgit v0.10.2 From e407e39783a7206d20b3e9961aedf272de966e31 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Thu, 12 Jun 2008 22:35:39 -0700 Subject: ocfs2: Fix CONFIG_OCFS2_DEBUG_FS #ifdefs A couple places use OCFS2_DEBUG_FS where they really mean CONFIG_OCFS2_DEBUG_FS. Reported-by: Robert P. J. Day Signed-off-by: Joel Becker diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 9698338..a8c19cb 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -329,7 +329,7 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); -#ifdef OCFS2_DEBUG_FS +#ifdef CONFIG_OCFS2_DEBUG_FS status = 1; #else status = journal_extend(handle, nblocks); diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index be774bd..28e492e 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -498,7 +498,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; -#ifdef OCFS2_DEBUG_FS +#ifdef CONFIG_OCFS2_DEBUG_FS if (le32_to_cpu(alloc->id1.bitmap1.i_used) != ocfs2_local_alloc_count_bits(alloc)) { ocfs2_error(osb->sb, "local alloc inode %llu says it has " -- cgit v0.10.2 From fe9f387740ac7cb3b7c2fffa76807e997e6c6292 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Thu, 12 Jun 2008 22:39:18 -0700 Subject: ocfs2: Don't snprintf() without a format. Some system files are per-slot. Their names include the slot number. ocfs2_sprintf_system_inode_name() uses the system inode definitions to fill in the slot number with snprintf(). For global system files, there is no node number, and the name was printed as a format with no arguments. -Wformat-nonliteral and -Wformat-security don't like this. Instead, use a static "%s" format and the name as the argument. Signed-off-by: Joel Becker diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 52c4266..3f19451 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -901,7 +901,7 @@ static inline int ocfs2_sprintf_system_inode_name(char *buf, int len, * list has a copy per slot. */ if (type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE) - chars = snprintf(buf, len, + chars = snprintf(buf, len, "%s", ocfs2_system_inodes[type].si_name); else chars = snprintf(buf, len, -- cgit v0.10.2 From 6f61076406251626be39651d114fac412b1e0c39 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:00:58 +0200 Subject: configfs: Introduce configfs_dirent_lock This patch introduces configfs_dirent_lock spinlock to protect configfs_dirent traversals against linkage mutations (add/del/move). This will allow configfs_detach_prep() to avoid locking i_mutexes. Locking rules for configfs_dirent linkage mutations are the same plus the requirement of taking configfs_dirent_lock. For configfs_dirent walking, one can either take appropriate i_mutex as before, or take configfs_dirent_lock. The spinlock could actually be a mutex, but the critical sections are either O(1) or should not be too long (default groups walking in last patch). ChangeLog: - Clarify the comment on configfs_dirent_lock usage - Move sd->s_element init before linking the new dirent - In lseek(), do not release configfs_dirent_lock before the dirent is relinked. Signed-off-by: Louis Rilling Signed-off-by: Joel Becker diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index cca9860..5a33b58 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h @@ -26,6 +26,7 @@ #include #include +#include struct configfs_dirent { atomic_t s_count; @@ -49,6 +50,8 @@ struct configfs_dirent { #define CONFIGFS_USET_DROPPING 0x0100 #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) +extern spinlock_t configfs_dirent_lock; + extern struct vfsmount * configfs_mount; extern struct kmem_cache *configfs_dir_cachep; diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index a48dc7d..2619f48 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -35,6 +35,14 @@ #include "configfs_internal.h" DECLARE_RWSEM(configfs_rename_sem); +/* + * Protects mutations of configfs_dirent linkage together with proper i_mutex + * Mutators of configfs_dirent linkage must *both* have the proper inode locked + * and configfs_dirent_lock locked, in that order. + * This allows one to safely traverse configfs_dirent trees without having to + * lock inodes. + */ +DEFINE_SPINLOCK(configfs_dirent_lock); static void configfs_d_iput(struct dentry * dentry, struct inode * inode) @@ -79,8 +87,10 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare atomic_set(&sd->s_count, 1); INIT_LIST_HEAD(&sd->s_links); INIT_LIST_HEAD(&sd->s_children); - list_add(&sd->s_sibling, &parent_sd->s_children); sd->s_element = element; + spin_lock(&configfs_dirent_lock); + list_add(&sd->s_sibling, &parent_sd->s_children); + spin_unlock(&configfs_dirent_lock); return sd; } @@ -173,7 +183,9 @@ static int create_dir(struct config_item * k, struct dentry * p, } else { struct configfs_dirent *sd = d->d_fsdata; if (sd) { + spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); configfs_put(sd); } } @@ -224,7 +236,9 @@ int configfs_create_link(struct configfs_symlink *sl, else { struct configfs_dirent *sd = dentry->d_fsdata; if (sd) { + spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); configfs_put(sd); } } @@ -238,7 +252,9 @@ static void remove_dir(struct dentry * d) struct configfs_dirent * sd; sd = d->d_fsdata; + spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); configfs_put(sd); if (d->d_inode) simple_rmdir(parent->d_inode,d); @@ -410,7 +426,9 @@ static void detach_attrs(struct config_item * item) list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED)) continue; + spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dentry); configfs_put(sd); } @@ -1268,7 +1286,9 @@ static int configfs_dir_close(struct inode *inode, struct file *file) struct configfs_dirent * cursor = file->private_data; mutex_lock(&dentry->d_inode->i_mutex); + spin_lock(&configfs_dirent_lock); list_del_init(&cursor->s_sibling); + spin_unlock(&configfs_dirent_lock); mutex_unlock(&dentry->d_inode->i_mutex); release_configfs_dirent(cursor); @@ -1308,7 +1328,9 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir /* fallthrough */ default: if (filp->f_pos == 2) { + spin_lock(&configfs_dirent_lock); list_move(q, &parent_sd->s_children); + spin_unlock(&configfs_dirent_lock); } for (p=q->next; p!= &parent_sd->s_children; p=p->next) { struct configfs_dirent *next; @@ -1331,7 +1353,9 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir dt_type(next)) < 0) return 0; + spin_lock(&configfs_dirent_lock); list_move(q, p); + spin_unlock(&configfs_dirent_lock); p = q; filp->f_pos++; } @@ -1362,6 +1386,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) struct list_head *p; loff_t n = file->f_pos - 2; + spin_lock(&configfs_dirent_lock); list_del(&cursor->s_sibling); p = sd->s_children.next; while (n && p != &sd->s_children) { @@ -1373,6 +1398,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) p = p->next; } list_add_tail(&cursor->s_sibling, p); + spin_unlock(&configfs_dirent_lock); } } mutex_unlock(&dentry->d_inode->i_mutex); diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index b9a1d81..4803ccc 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -247,7 +247,9 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name) if (!sd->s_element) continue; if (!strcmp(configfs_get_name(sd), name)) { + spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dir); configfs_put(sd); break; diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index 2a731ef..676c84c 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c @@ -169,7 +169,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) parent_item = configfs_get_config_item(dentry->d_parent); type = parent_item->ci_type; + spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dentry->d_parent); dput(dentry); configfs_put(sd); -- cgit v0.10.2 From 5301a77da2da1e4c22573e0e8d394a653b8ad9f9 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:00:59 +0200 Subject: configfs: Protect configfs_dirent s_links list mutations Symlinks to a config_item are listed under its configfs_dirent s_links, but the list mutations are not protected by any common lock. This patch uses the configfs_dirent_lock spinlock to add the necessary protection. Note: we should also protect the list_empty() test in configfs_detach_prep() but 1/ the lock should not be released immediately because nothing would prevent the list from being filled after a successful list_empty() test, making the problem tricky, 2/ this will be solved by the rmdir() vs rename() deadlock bugfix. Signed-off-by: Louis Rilling Signed-off-by: Joel Becker diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 2619f48..a08e5c2 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -37,10 +37,11 @@ DECLARE_RWSEM(configfs_rename_sem); /* * Protects mutations of configfs_dirent linkage together with proper i_mutex + * Also protects mutations of symlinks linkage to target configfs_dirent * Mutators of configfs_dirent linkage must *both* have the proper inode locked * and configfs_dirent_lock locked, in that order. - * This allows one to safely traverse configfs_dirent trees without having to - * lock inodes. + * This allows one to safely traverse configfs_dirent trees and symlinks without + * having to lock inodes. */ DEFINE_SPINLOCK(configfs_dirent_lock); diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index 676c84c..faeb441 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c @@ -77,12 +77,15 @@ static int create_link(struct config_item *parent_item, sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); if (sl) { sl->sl_target = config_item_get(item); - /* FIXME: needs a lock, I'd bet */ + spin_lock(&configfs_dirent_lock); list_add(&sl->sl_list, &target_sd->s_links); + spin_unlock(&configfs_dirent_lock); ret = configfs_create_link(sl, parent_item->ci_dentry, dentry); if (ret) { + spin_lock(&configfs_dirent_lock); list_del_init(&sl->sl_list); + spin_unlock(&configfs_dirent_lock); config_item_put(item); kfree(sl); } @@ -186,8 +189,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) type->ct_item_ops->drop_link(parent_item, sl->sl_target); - /* FIXME: Needs lock */ + spin_lock(&configfs_dirent_lock); list_del_init(&sl->sl_list); + spin_unlock(&configfs_dirent_lock); /* Put reference from create_link() */ config_item_put(sl->sl_target); -- cgit v0.10.2 From 107ed40bd070df5e4a0a012042c45c40963dc574 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:01:00 +0200 Subject: configfs: Make configfs_new_dirent() return error code instead of NULL This patch makes configfs_new_dirent return negative error code instead of NULL, which will be useful in the next patch to differentiate ENOMEM from ENOENT. Signed-off-by: Louis Rilling Signed-off-by: Joel Becker diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index a08e5c2..918a332 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "configfs_internal.h" @@ -83,7 +84,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare sd = kmem_cache_zalloc(configfs_dir_cachep, GFP_KERNEL); if (!sd) - return NULL; + return ERR_PTR(-ENOMEM); atomic_set(&sd->s_count, 1); INIT_LIST_HEAD(&sd->s_links); @@ -129,8 +130,8 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd, struct configfs_dirent * sd; sd = configfs_new_dirent(parent_sd, element); - if (!sd) - return -ENOMEM; + if (IS_ERR(sd)) + return PTR_ERR(sd); sd->s_mode = mode; sd->s_type = type; @@ -1277,7 +1278,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file) file->private_data = configfs_new_dirent(parent_sd, NULL); mutex_unlock(&dentry->d_inode->i_mutex); - return file->private_data ? 0 : -ENOMEM; + return IS_ERR(file->private_data) ? PTR_ERR(file->private_data) : 0; } -- cgit v0.10.2 From b3e76af87441fc36eef3516d73ab2314e7b2d911 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:01:01 +0200 Subject: configfs: Fix deadlock with racing rmdir() and rename() This patch fixes the deadlock between racing sys_rename() and configfs_rmdir(). The idea is to avoid locking i_mutexes of default groups in configfs_detach_prep(), and rely instead on the new configfs_dirent_lock to protect against configfs_dirent's linkage mutations. To ensure that an mkdir() racing with rmdir() will not create new items in a to-be-removed default group, we make configfs_new_dirent() check for the CONFIGFS_USET_DROPPING flag right before linking the new dirent, and return error if the flag is set. This makes racing mkdir()/symlink()/dir_open() fail in places where errors could already happen, resp. in (attach_item()|attach_group())/create_link()/new_dirent(). configfs_depend() remains safe since it locks all the path from configfs root, and is thus mutually exclusive with rmdir(). An advantage of this is that now detach_groups() unconditionnaly takes the default groups i_mutex, which makes it more consistent with populate_groups(). Signed-off-by: Louis Rilling Signed-off-by: Joel Becker diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 918a332..d5b5985 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -43,6 +43,10 @@ DECLARE_RWSEM(configfs_rename_sem); * and configfs_dirent_lock locked, in that order. * This allows one to safely traverse configfs_dirent trees and symlinks without * having to lock inodes. + * + * Protects setting of CONFIGFS_USET_DROPPING: checking the flag + * unlocked is not reliable unless in detach_groups() called from + * rmdir()/unregister() and from configfs_attach_group() */ DEFINE_SPINLOCK(configfs_dirent_lock); @@ -91,6 +95,11 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare INIT_LIST_HEAD(&sd->s_children); sd->s_element = element; spin_lock(&configfs_dirent_lock); + if (parent_sd->s_type & CONFIGFS_USET_DROPPING) { + spin_unlock(&configfs_dirent_lock); + kmem_cache_free(configfs_dir_cachep, sd); + return ERR_PTR(-ENOENT); + } list_add(&sd->s_sibling, &parent_sd->s_children); spin_unlock(&configfs_dirent_lock); @@ -349,11 +358,11 @@ static struct dentry * configfs_lookup(struct inode *dir, /* * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are - * attributes and are removed by rmdir(). We recurse, taking i_mutex - * on all children that are candidates for default detach. If the - * result is clean, then configfs_detach_group() will handle dropping - * i_mutex. If there is an error, the caller will clean up the i_mutex - * holders via configfs_detach_rollback(). + * attributes and are removed by rmdir(). We recurse, setting + * CONFIGFS_USET_DROPPING on all children that are candidates for + * default detach. + * If there is an error, the caller will reset the flags via + * configfs_detach_rollback(). */ static int configfs_detach_prep(struct dentry *dentry) { @@ -370,8 +379,7 @@ static int configfs_detach_prep(struct dentry *dentry) if (sd->s_type & CONFIGFS_NOT_PINNED) continue; if (sd->s_type & CONFIGFS_USET_DEFAULT) { - mutex_lock(&sd->s_dentry->d_inode->i_mutex); - /* Mark that we've taken i_mutex */ + /* Mark that we're trying to drop the group */ sd->s_type |= CONFIGFS_USET_DROPPING; /* @@ -392,7 +400,7 @@ out: } /* - * Walk the tree, dropping i_mutex wherever CONFIGFS_USET_DROPPING is + * Walk the tree, resetting CONFIGFS_USET_DROPPING wherever it was * set. */ static void configfs_detach_rollback(struct dentry *dentry) @@ -403,11 +411,7 @@ static void configfs_detach_rollback(struct dentry *dentry) list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { if (sd->s_type & CONFIGFS_USET_DEFAULT) { configfs_detach_rollback(sd->s_dentry); - - if (sd->s_type & CONFIGFS_USET_DROPPING) { - sd->s_type &= ~CONFIGFS_USET_DROPPING; - mutex_unlock(&sd->s_dentry->d_inode->i_mutex); - } + sd->s_type &= ~CONFIGFS_USET_DROPPING; } } } @@ -486,16 +490,12 @@ static void detach_groups(struct config_group *group) child = sd->s_dentry; + mutex_lock(&child->d_inode->i_mutex); + configfs_detach_group(sd->s_element); child->d_inode->i_flags |= S_DEAD; - /* - * From rmdir/unregister, a configfs_detach_prep() pass - * has taken our i_mutex for us. Drop it. - * From mkdir/register cleanup, there is no sem held. - */ - if (sd->s_type & CONFIGFS_USET_DROPPING) - mutex_unlock(&child->d_inode->i_mutex); + mutex_unlock(&child->d_inode->i_mutex); d_delete(child); dput(child); @@ -1181,12 +1181,15 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) return -EINVAL; } + spin_lock(&configfs_dirent_lock); ret = configfs_detach_prep(dentry); if (ret) { configfs_detach_rollback(dentry); + spin_unlock(&configfs_dirent_lock); config_item_put(parent_item); return ret; } + spin_unlock(&configfs_dirent_lock); /* Get a working ref for the duration of this function */ item = configfs_get_config_item(dentry); @@ -1476,9 +1479,11 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, I_MUTEX_PARENT); mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); + spin_lock(&configfs_dirent_lock); if (configfs_detach_prep(dentry)) { printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); } + spin_unlock(&configfs_dirent_lock); configfs_detach_group(&group->cg_item); dentry->d_inode->i_flags |= S_DEAD; mutex_unlock(&dentry->d_inode->i_mutex); -- cgit v0.10.2 From 6d8344baee99402de58b5fa5dfea197242955c15 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Mon, 16 Jun 2008 19:01:02 +0200 Subject: configfs: Fix failing mkdir() making racing rmdir() fail When fixing the rename() vs rmdir() deadlock, we stopped locking default groups' inodes in configfs_detach_prep(), letting racing mkdir() in default groups proceed concurrently. This enables races like below happen, which leads to a failing mkdir() making rmdir() fail, despite the group to remove having no user-created directory under it in the end. process A: process B: /* PWD=A/B */ mkdir("C") make_item("C") attach_group("C") rmdir("A") detach_prep("A") detach_prep("B") error because of "C" return -ENOTEMPTY attach_group("C/D") error (eg -ENOMEM) return -ENOMEM This patch prevents such scenarii by making rmdir() wait as long as detach_prep() fails because a racing mkdir() is in the middle of attach_group(). To achieve this, mkdir() sets a flag CONFIGFS_USET_IN_MKDIR in parent's configfs_dirent before calling attach_group(), and clears the flag once attach_group() is done. detach_prep() fails with -EAGAIN whenever the flag is hit and returns the guilty inode's mutex so that rmdir() can wait on it. Signed-off-by: Louis Rilling Signed-off-by: Joel Becker diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 5a33b58..da015c1 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h @@ -48,6 +48,7 @@ struct configfs_dirent { #define CONFIGFS_USET_DIR 0x0040 #define CONFIGFS_USET_DEFAULT 0x0080 #define CONFIGFS_USET_DROPPING 0x0100 +#define CONFIGFS_USET_IN_MKDIR 0x0200 #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) extern spinlock_t configfs_dirent_lock; diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index d5b5985..614e382 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -364,7 +364,7 @@ static struct dentry * configfs_lookup(struct inode *dir, * If there is an error, the caller will reset the flags via * configfs_detach_rollback(). */ -static int configfs_detach_prep(struct dentry *dentry) +static int configfs_detach_prep(struct dentry *dentry, struct mutex **wait_mutex) { struct configfs_dirent *parent_sd = dentry->d_fsdata; struct configfs_dirent *sd; @@ -379,6 +379,12 @@ static int configfs_detach_prep(struct dentry *dentry) if (sd->s_type & CONFIGFS_NOT_PINNED) continue; if (sd->s_type & CONFIGFS_USET_DEFAULT) { + /* Abort if racing with mkdir() */ + if (sd->s_type & CONFIGFS_USET_IN_MKDIR) { + if (wait_mutex) + *wait_mutex = &sd->s_dentry->d_inode->i_mutex; + return -EAGAIN; + } /* Mark that we're trying to drop the group */ sd->s_type |= CONFIGFS_USET_DROPPING; @@ -386,7 +392,7 @@ static int configfs_detach_prep(struct dentry *dentry) * Yup, recursive. If there's a problem, blame * deep nesting of default_groups */ - ret = configfs_detach_prep(sd->s_dentry); + ret = configfs_detach_prep(sd->s_dentry, wait_mutex); if (!ret) continue; } else @@ -1113,11 +1119,26 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) */ module_got = 1; + /* + * Make racing rmdir() fail if it did not tag parent with + * CONFIGFS_USET_DROPPING + * Note: if CONFIGFS_USET_DROPPING is already set, attach_group() will + * fail and let rmdir() terminate correctly + */ + spin_lock(&configfs_dirent_lock); + /* This will make configfs_detach_prep() fail */ + sd->s_type |= CONFIGFS_USET_IN_MKDIR; + spin_unlock(&configfs_dirent_lock); + if (group) ret = configfs_attach_group(parent_item, item, dentry); else ret = configfs_attach_item(parent_item, item, dentry); + spin_lock(&configfs_dirent_lock); + sd->s_type &= ~CONFIGFS_USET_IN_MKDIR; + spin_unlock(&configfs_dirent_lock); + out_unlink: if (ret) { /* Tear down everything we built up */ @@ -1182,13 +1203,25 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) } spin_lock(&configfs_dirent_lock); - ret = configfs_detach_prep(dentry); - if (ret) { - configfs_detach_rollback(dentry); - spin_unlock(&configfs_dirent_lock); - config_item_put(parent_item); - return ret; - } + do { + struct mutex *wait_mutex; + + ret = configfs_detach_prep(dentry, &wait_mutex); + if (ret) { + configfs_detach_rollback(dentry); + spin_unlock(&configfs_dirent_lock); + if (ret != -EAGAIN) { + config_item_put(parent_item); + return ret; + } + + /* Wait until the racing operation terminates */ + mutex_lock(wait_mutex); + mutex_unlock(wait_mutex); + + spin_lock(&configfs_dirent_lock); + } + } while (ret == -EAGAIN); spin_unlock(&configfs_dirent_lock); /* Get a working ref for the duration of this function */ @@ -1480,7 +1513,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) I_MUTEX_PARENT); mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); spin_lock(&configfs_dirent_lock); - if (configfs_detach_prep(dentry)) { + if (configfs_detach_prep(dentry, NULL)) { printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); } spin_unlock(&configfs_dirent_lock); -- cgit v0.10.2 From 11c3b79218390a139f2d474ee1e983a672d5839a Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Thu, 12 Jun 2008 14:00:18 -0700 Subject: configfs: Allow ->make_item() and ->make_group() to return detailed errors. The configfs operations ->make_item() and ->make_group() currently return a new item/group. A return of NULL signifies an error. Because of this, -ENOMEM is the only return code bubbled up the stack. Multiple folks have requested the ability to return specific error codes when these operations fail. This patch adds that ability by changing the ->make_item/group() ops to return an int. Also updated are the in-kernel users of configfs. Signed-off-by: Joel Becker diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt index 44c97e6..15838d7 100644 --- a/Documentation/filesystems/configfs/configfs.txt +++ b/Documentation/filesystems/configfs/configfs.txt @@ -233,10 +233,12 @@ accomplished via the group operations specified on the group's config_item_type. struct configfs_group_operations { - struct config_item *(*make_item)(struct config_group *group, - const char *name); - struct config_group *(*make_group)(struct config_group *group, - const char *name); + int (*make_item)(struct config_group *group, + const char *name, + struct config_item **new_item); + int (*make_group)(struct config_group *group, + const char *name, + struct config_group **new_group); int (*commit_item)(struct config_item *item); void (*disconnect_notify)(struct config_group *group, struct config_item *item); diff --git a/Documentation/filesystems/configfs/configfs_example.c b/Documentation/filesystems/configfs/configfs_example.c index 25151fd..0b422ac 100644 --- a/Documentation/filesystems/configfs/configfs_example.c +++ b/Documentation/filesystems/configfs/configfs_example.c @@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; } -static struct config_item *simple_children_make_item(struct config_group *group, const char *name) +static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item) { struct simple_child *simple_child; simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); if (!simple_child) - return NULL; + return -ENOMEM; config_item_init_type_name(&simple_child->item, name, @@ -287,7 +287,8 @@ static struct config_item *simple_children_make_item(struct config_group *group, simple_child->storeme = 0; - return &simple_child->item; + *new_item = &simple_child->item; + return 0; } static struct configfs_attribute simple_children_attr_description = { @@ -359,20 +360,21 @@ static struct configfs_subsystem simple_children_subsys = { * children of its own. */ -static struct config_group *group_children_make_group(struct config_group *group, const char *name) +static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group) { struct simple_children *simple_children; simple_children = kzalloc(sizeof(struct simple_children), GFP_KERNEL); if (!simple_children) - return NULL; + return -ENOMEM; config_group_init_type_name(&simple_children->group, name, &simple_children_type); - return &simple_children->group; + *new_group = &simple_children->group; + return 0; } static struct configfs_attribute group_children_attr_description = { diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 665341e..387a133 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -585,8 +585,9 @@ static struct config_item_type netconsole_target_type = { * Group operations and type for netconsole_subsys. */ -static struct config_item *make_netconsole_target(struct config_group *group, - const char *name) +static int make_netconsole_target(struct config_group *group, + const char *name, + struct config_item **new_item) { unsigned long flags; struct netconsole_target *nt; @@ -598,7 +599,7 @@ static struct config_item *make_netconsole_target(struct config_group *group, nt = kzalloc(sizeof(*nt), GFP_KERNEL); if (!nt) { printk(KERN_ERR "netconsole: failed to allocate memory\n"); - return NULL; + return -ENOMEM; } nt->np.name = "netconsole"; @@ -615,7 +616,8 @@ static struct config_item *make_netconsole_target(struct config_group *group, list_add(&nt->list, &target_list); spin_unlock_irqrestore(&target_list_lock, flags); - return &nt->item; + *new_item = &nt->item; + return 0; } static void drop_netconsole_target(struct config_group *group, diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 614e382..0e64312 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1073,25 +1073,24 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) group = NULL; item = NULL; if (type->ct_group_ops->make_group) { - group = type->ct_group_ops->make_group(to_config_group(parent_item), name); - if (group) { + ret = type->ct_group_ops->make_group(to_config_group(parent_item), name, &group); + if (!ret) { link_group(to_config_group(parent_item), group); item = &group->cg_item; } } else { - item = type->ct_group_ops->make_item(to_config_group(parent_item), name); - if (item) + ret = type->ct_group_ops->make_item(to_config_group(parent_item), name, &item); + if (!ret) link_obj(parent_item, item); } mutex_unlock(&subsys->su_mutex); kfree(name); - if (!item) { + if (ret) { /* - * If item == NULL, then link_obj() was never called. + * If ret != 0, then link_obj() was never called. * There are no extra references to clean up. */ - ret = -ENOMEM; goto out_put; } diff --git a/fs/dlm/config.c b/fs/dlm/config.c index eac23bd..492d8ca 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -41,16 +41,20 @@ struct comm; struct nodes; struct node; -static struct config_group *make_cluster(struct config_group *, const char *); +static int make_cluster(struct config_group *, const char *, + struct config_group **); static void drop_cluster(struct config_group *, struct config_item *); static void release_cluster(struct config_item *); -static struct config_group *make_space(struct config_group *, const char *); +static int make_space(struct config_group *, const char *, + struct config_group **); static void drop_space(struct config_group *, struct config_item *); static void release_space(struct config_item *); -static struct config_item *make_comm(struct config_group *, const char *); +static int make_comm(struct config_group *, const char *, + struct config_item **); static void drop_comm(struct config_group *, struct config_item *); static void release_comm(struct config_item *); -static struct config_item *make_node(struct config_group *, const char *); +static int make_node(struct config_group *, const char *, + struct config_item **); static void drop_node(struct config_group *, struct config_item *); static void release_node(struct config_item *); @@ -392,8 +396,8 @@ static struct node *to_node(struct config_item *i) return i ? container_of(i, struct node, item) : NULL; } -static struct config_group *make_cluster(struct config_group *g, - const char *name) +static int make_cluster(struct config_group *g, const char *name, + struct config_group **new_g) { struct cluster *cl = NULL; struct spaces *sps = NULL; @@ -431,14 +435,15 @@ static struct config_group *make_cluster(struct config_group *g, space_list = &sps->ss_group; comm_list = &cms->cs_group; - return &cl->group; + *new_g = &cl->group; + return 0; fail: kfree(cl); kfree(gps); kfree(sps); kfree(cms); - return NULL; + return -ENOMEM; } static void drop_cluster(struct config_group *g, struct config_item *i) @@ -466,7 +471,8 @@ static void release_cluster(struct config_item *i) kfree(cl); } -static struct config_group *make_space(struct config_group *g, const char *name) +static int make_space(struct config_group *g, const char *name, + struct config_group **new_g) { struct space *sp = NULL; struct nodes *nds = NULL; @@ -489,13 +495,14 @@ static struct config_group *make_space(struct config_group *g, const char *name) INIT_LIST_HEAD(&sp->members); mutex_init(&sp->members_lock); sp->members_count = 0; - return &sp->group; + *new_g = &sp->group; + return 0; fail: kfree(sp); kfree(gps); kfree(nds); - return NULL; + return -ENOMEM; } static void drop_space(struct config_group *g, struct config_item *i) @@ -522,19 +529,21 @@ static void release_space(struct config_item *i) kfree(sp); } -static struct config_item *make_comm(struct config_group *g, const char *name) +static int make_comm(struct config_group *g, const char *name, + struct config_item **new_i) { struct comm *cm; cm = kzalloc(sizeof(struct comm), GFP_KERNEL); if (!cm) - return NULL; + return -ENOMEM; config_item_init_type_name(&cm->item, name, &comm_type); cm->nodeid = -1; cm->local = 0; cm->addr_count = 0; - return &cm->item; + *new_i = &cm->item; + return 0; } static void drop_comm(struct config_group *g, struct config_item *i) @@ -554,14 +563,15 @@ static void release_comm(struct config_item *i) kfree(cm); } -static struct config_item *make_node(struct config_group *g, const char *name) +static int make_node(struct config_group *g, const char *name, + struct config_item **new_i) { struct space *sp = to_space(g->cg_item.ci_parent); struct node *nd; nd = kzalloc(sizeof(struct node), GFP_KERNEL); if (!nd) - return NULL; + return -ENOMEM; config_item_init_type_name(&nd->item, name, &node_type); nd->nodeid = -1; @@ -573,7 +583,8 @@ static struct config_item *make_node(struct config_group *g, const char *name) sp->members_count++; mutex_unlock(&sp->members_lock); - return &nd->item; + *new_i = &nd->item; + return 0; } static void drop_node(struct config_group *g, struct config_item *i) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index f02ccb3..443d108 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1489,25 +1489,28 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group : NULL; } -static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group, - const char *name) +static int o2hb_heartbeat_group_make_item(struct config_group *group, + const char *name, + struct config_item **new_item) { struct o2hb_region *reg = NULL; - struct config_item *ret = NULL; + int ret = 0; reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); - if (reg == NULL) - goto out; /* ENOMEM */ + if (reg == NULL) { + ret = -ENOMEM; + goto out; + } config_item_init_type_name(®->hr_item, name, &o2hb_region_type); - ret = ®->hr_item; + *new_item = ®->hr_item; spin_lock(&o2hb_live_lock); list_add_tail(®->hr_all_item, &o2hb_all_regions); spin_unlock(&o2hb_live_lock); out: - if (ret == NULL) + if (ret) kfree(reg); return ret; diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index cfdb08b..b364b70 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -644,27 +644,32 @@ out: return ret; } -static struct config_item *o2nm_node_group_make_item(struct config_group *group, - const char *name) +static int o2nm_node_group_make_item(struct config_group *group, + const char *name, + struct config_item **new_item) { struct o2nm_node *node = NULL; - struct config_item *ret = NULL; + int ret = 0; - if (strlen(name) > O2NM_MAX_NAME_LEN) - goto out; /* ENAMETOOLONG */ + if (strlen(name) > O2NM_MAX_NAME_LEN) { + ret = -ENAMETOOLONG; + goto out; + } node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); - if (node == NULL) - goto out; /* ENOMEM */ + if (node == NULL) { + ret = -ENOMEM; + goto out; + } strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); spin_lock_init(&node->nd_lock); - ret = &node->nd_item; + *new_item = &node->nd_item; out: - if (ret == NULL) + if (ret) kfree(node); return ret; @@ -751,25 +756,31 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro } #endif -static struct config_group *o2nm_cluster_group_make_group(struct config_group *group, - const char *name) +static int o2nm_cluster_group_make_group(struct config_group *group, + const char *name, + struct config_group **new_group) { struct o2nm_cluster *cluster = NULL; struct o2nm_node_group *ns = NULL; - struct config_group *o2hb_group = NULL, *ret = NULL; + struct config_group *o2hb_group = NULL; void *defs = NULL; + int ret = 0; /* this runs under the parent dir's i_mutex; there can be only * one caller in here at a time */ - if (o2nm_single_cluster) - goto out; /* ENOSPC */ + if (o2nm_single_cluster) { + ret = -ENOSPC; + goto out; + } cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); o2hb_group = o2hb_alloc_hb_set(); - if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) + if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) { + ret = -ENOMEM; goto out; + } config_group_init_type_name(&cluster->cl_group, name, &o2nm_cluster_type); @@ -786,11 +797,11 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; - ret = &cluster->cl_group; + *new_group = &cluster->cl_group; o2nm_single_cluster = cluster; out: - if (ret == NULL) { + if (ret) { kfree(cluster); kfree(ns); o2hb_free_hb_set(o2hb_group); diff --git a/include/linux/configfs.h b/include/linux/configfs.h index 3ae65b1..0488f93 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h @@ -165,8 +165,8 @@ struct configfs_item_operations { }; struct configfs_group_operations { - struct config_item *(*make_item)(struct config_group *group, const char *name); - struct config_group *(*make_group)(struct config_group *group, const char *name); + int (*make_item)(struct config_group *group, const char *name, struct config_item **new_item); + int (*make_group)(struct config_group *group, const char *name, struct config_group **new_group); int (*commit_item)(struct config_item *item); void (*disconnect_notify)(struct config_group *group, struct config_item *item); void (*drop_item)(struct config_group *group, struct config_item *item); -- cgit v0.10.2 From e75206517504461778c283b942440ef312e437d5 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Thu, 12 Jun 2008 17:26:47 +0200 Subject: configfs: call drop_link() to cleanup after create_link() failure When allow_link() succeeds but create_link() fails, the subsystem is not informed of the failure. This patch fixes this by calling drop_link() on create_link() failures. Signed-off-by: Louis Rilling Signed-off-by: Joel Becker diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index faeb441..0004d18 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c @@ -140,8 +140,12 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna goto out_put; ret = type->ct_item_ops->allow_link(parent_item, target_item); - if (!ret) + if (!ret) { ret = create_link(parent_item, target_item, dentry); + if (ret && type->ct_item_ops->drop_link) + type->ct_item_ops->drop_link(parent_item, + target_item); + } config_item_put(target_item); path_put(&nd.path); -- cgit v0.10.2 From a41eebab7537890409ea9dfe0fcda9b5fbdb090d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 14 Jul 2008 16:41:12 -0400 Subject: ftrace: document updates The following updates were recommended by Elias Oltmanns and Randy Dunlap. [ updates based on Andrew Morton's comments are still to come. ] Signed-off-by: Steven Rostedt Signed-off-by: Linus Torvalds diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt index 13e4bf0..77d3faa 100644 --- a/Documentation/ftrace.txt +++ b/Documentation/ftrace.txt @@ -2,8 +2,11 @@ ======================== Copyright 2008 Red Hat Inc. -Author: Steven Rostedt + Author: Steven Rostedt + License: The GNU Free Documentation License, Version 1.2 +Reviewers: Elias Oltmanns and Randy Dunlap +Writen for: 2.6.26-rc8 linux-2.6-tip.git tip/tracing/ftrace branch Introduction ------------ @@ -46,7 +49,7 @@ of ftrace. Here is a list of some of the key files: that is configured. available_tracers : This holds the different types of tracers that - has been compiled into the kernel. The tracers + have been compiled into the kernel. The tracers listed here can be configured by echoing in their name into current_tracer. @@ -90,11 +93,13 @@ of ftrace. Here is a list of some of the key files: trace_entries : This sets or displays the number of trace entries each CPU buffer can hold. The tracer buffers are the same size for each CPU, so care must be - taken when modifying the trace_entries. The number - of actually entries will be the number given - times the number of possible CPUS. The buffers - are saved as individual pages, and the actual entries - will always be rounded up to entries per page. + taken when modifying the trace_entries. The trace + buffers are allocated in pages (blocks of memory that + the kernel uses for allocation, usually 4 KB in size). + Since each entry is smaller than a page, if the last + allocated page has room for more entries than were + requested, the rest of the page is used to allocate + entries. This can only be updated when the current_tracer is set to "none". @@ -114,13 +119,13 @@ of ftrace. Here is a list of some of the key files: in performance. This also has a side effect of enabling or disabling specific functions to be traced. Echoing in names of functions into this - file will limit the trace to only those files. + file will limit the trace to only these functions. set_ftrace_notrace: This has the opposite effect that set_ftrace_filter has. Any function that is added here will not be traced. If a function exists - in both set_ftrace_filter and set_ftrace_notrace - the function will _not_ bet traced. + in both set_ftrace_filter and set_ftrace_notrace, + the function will _not_ be traced. available_filter_functions : When a function is encountered the first time by the dynamic tracer, it is recorded and @@ -138,7 +143,7 @@ Here are the list of current tracers that can be configured. ftrace - function tracer that uses mcount to trace all functions. It is possible to filter out which functions that are - traced when dynamic ftrace is configured in. + to be traced when dynamic ftrace is configured in. sched_switch - traces the context switches between tasks. @@ -297,13 +302,13 @@ explains which is which. The above is mostly meaningful for kernel developers. - time: This differs from the trace output where as the trace output - contained a absolute timestamp. This timestamp is relative - to the start of the first entry in the the trace. + time: This differs from the trace file output. The trace file output + included an absolute timestamp. The timestamp used by the + latency_trace file is relative to the start of the trace. delay: This is just to help catch your eye a bit better. And needs to be fixed to be only relative to the same CPU. - The marks is determined by the difference between this + The marks are determined by the difference between this current trace and the next trace. '!' - greater than preempt_mark_thresh (default 100) '+' - greater than 1 microsecond @@ -322,13 +327,13 @@ output. To see what is available, simply cat the file: print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \ noblock nostacktrace nosched-tree -To disable one of the options, echo in the option appended with "no". +To disable one of the options, echo in the option prepended with "no". echo noprint-parent > /debug/tracing/iter_ctrl To enable an option, leave off the "no". - echo sym-offest > /debug/tracing/iter_ctrl + echo sym-offset > /debug/tracing/iter_ctrl Here are the available options: @@ -344,7 +349,7 @@ Here are the available options: sym-offset - Display not only the function name, but also the offset in the function. For example, instead of seeing just - "ktime_get" you will see "ktime_get+0xb/0x20" + "ktime_get", you will see "ktime_get+0xb/0x20". sym-offset: bash-4000 [01] 1477.606694: simple_strtoul+0x6/0xa0 @@ -364,7 +369,7 @@ Here are the available options: user applications that can translate the raw numbers better than having it done in the kernel. - hex - similar to raw, but the numbers will be in a hexadecimal format. + hex - Similar to raw, but the numbers will be in a hexadecimal format. bin - This will print out the formats in raw binary. @@ -381,7 +386,7 @@ sched_switch ------------ This tracer simply records schedule switches. Here's an example -on how to implement it. +of how to use it. # echo sched_switch > /debug/tracing/current_tracer # echo 1 > /debug/tracing/tracing_enabled @@ -470,7 +475,7 @@ interrupt from triggering or the mouse interrupt from letting the kernel know of a new mouse event. The result is a latency with the reaction time. -The irqsoff tracer tracks the time interrupts are disabled and when +The irqsoff tracer tracks the time interrupts are disabled to the time they are re-enabled. When a new maximum latency is hit, it saves off the trace so that it may be retrieved at a later time. Every time a new maximum in reached, the old saved trace is discarded and the new @@ -519,7 +524,7 @@ The difference between the 6 and the displayed timestamp 7us is because the clock must have incremented between the time of recording the max latency and recording the function that had that latency. -Note the above had ftrace_enabled not set. If we set the ftrace_enabled +Note the above had ftrace_enabled not set. If we set the ftrace_enabled, we get a much larger output: # tracer: irqsoff @@ -570,21 +575,21 @@ vim:ft=help Here we traced a 50 microsecond latency. But we also see all the -functions that were called during that time. Note that enabling -function tracing we endure an added overhead. This overhead may -extend the latency times. But never the less, this trace has provided -some very helpful debugging. +functions that were called during that time. Note that by enabling +function tracing, we endure an added overhead. This overhead may +extend the latency times. But nevertheless, this trace has provided +some very helpful debugging information. preemptoff ---------- -When preemption is disabled we may be able to receive interrupts but -the task can not be preempted and a higher priority task must wait +When preemption is disabled, we may be able to receive interrupts but +the task cannot be preempted and a higher priority task must wait for preemption to be enabled again before it can preempt a lower priority task. -The preemptoff tracer traces the places that disables preemption. +The preemptoff tracer traces the places that disable preemption. Like the irqsoff, it records the maximum latency that preemption was disabled. The control of preemptoff is much like the irqsoff. @@ -696,7 +701,7 @@ Notice that the __do_softirq when called doesn't have a preempt_count. It may seem that we missed a preempt enabled. What really happened is that the preempt count is held on the threads stack and we switched to the softirq stack (4K stacks in effect). The code -does not copy the preempt count, but because interrupts are disabled +does not copy the preempt count, but because interrupts are disabled, we don't need to worry about it. Having a tracer like this is good to let people know what really happens inside the kernel. @@ -732,7 +737,7 @@ To record this time, use the preemptirqsoff tracer. Again, using this trace is much like the irqsoff and preemptoff tracers. - # echo preemptoff > /debug/tracing/current_tracer + # echo preemptirqsoff > /debug/tracing/current_tracer # echo 0 > /debug/tracing/tracing_max_latency # echo 1 > /debug/tracing/tracing_enabled # ls -ltr @@ -862,9 +867,9 @@ This is a very interesting trace. It started with the preemption of the ls task. We see that the task had the "need_resched" bit set with the 'N' in the trace. Interrupts are disabled in the spin_lock and the trace started. We see that a schedule took place to run -sshd. When the interrupts were enabled we took an interrupt. -On return of the interrupt the softirq ran. We took another interrupt -while running the softirq as we see with the capital 'H'. +sshd. When the interrupts were enabled, we took an interrupt. +On return from the interrupt handler, the softirq ran. We took another +interrupt while running the softirq as we see with the capital 'H'. wakeup @@ -876,9 +881,9 @@ time it executes. This is also known as "schedule latency". I stress the point that this is about RT tasks. It is also important to know the scheduling latency of non-RT tasks, but the average schedule latency is better for non-RT tasks. Tools like -LatencyTop is more appropriate for such measurements. +LatencyTop are more appropriate for such measurements. -Real-Time environments is interested in the worst case latency. +Real-Time environments are interested in the worst case latency. That is the longest latency it takes for something to happen, and not the average. We can have a very fast scheduler that may only have a large latency once in a while, but that would not work well @@ -889,8 +894,8 @@ tasks that are unpredictable will overwrite the worst case latency of RT tasks. Since this tracer only deals with RT tasks, we will run this slightly -different than we did with the previous tracers. Instead of performing -an 'ls' we will run 'sleep 1' under 'chrt' which changes the +differently than we did with the previous tracers. Instead of performing +an 'ls', we will run 'sleep 1' under 'chrt' which changes the priority of the task. # echo wakeup > /debug/tracing/current_tracer @@ -924,9 +929,9 @@ wakeup latency trace v1.1.5 on 2.6.26-rc8 vim:ft=help -Running this on an idle system we see that it only took 4 microseconds +Running this on an idle system, we see that it only took 4 microseconds to perform the task switch. Note, since the trace marker in the -schedule is before the actual "switch" we stop the tracing when +schedule is before the actual "switch", we stop the tracing when the recorded task is about to schedule in. This may change if we add a new marker at the end of the scheduler. @@ -992,12 +997,15 @@ ksoftirq-7 1d..4 50us : schedule (__cond_resched) The interrupt went off while running ksoftirqd. This task runs at SCHED_OTHER. Why didn't we see the 'N' set early? This may be -a harmless bug with x86_32 and 4K stacks. The need_reched() function -that tests if we need to reschedule looks on the actual stack. -Where as the setting of the NEED_RESCHED bit happens on the -task's stack. But because we are in a hard interrupt, the test -is with the interrupts stack which has that to be false. We don't -see the 'N' until we switch back to the task's stack. +a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K stacks +configured, the interrupt and softirq runs with their own stack. +Some information is held on the top of the task's stack (need_resched +and preempt_count are both stored there). The setting of the NEED_RESCHED +bit is done directly to the task's stack, but the reading of the +NEED_RESCHED is done by looking at the current stack, which in this case +is the stack for the hard interrupt. This hides the fact that NEED_RESCHED +has been set. We don't see the 'N' until we switch back to the task's +assigned stack. ftrace ------ @@ -1067,10 +1075,10 @@ this works is the mcount function call (placed at the start of every kernel function, produced by the -pg switch in gcc), starts of pointing to a simple return. -When dynamic ftrace is initialized, it calls kstop_machine to make it -act like a uniprocessor so that it can freely modify code without -worrying about other processors executing that same code. At -initialization, the mcount calls are change to call a "record_ip" +When dynamic ftrace is initialized, it calls kstop_machine to make +the machine act like a uniprocessor so that it can freely modify code +without worrying about other processors executing that same code. At +initialization, the mcount calls are changed to call a "record_ip" function. After this, the first time a kernel function is called, it has the calling address saved in a hash table. @@ -1085,8 +1093,8 @@ traced, is that we can now selectively choose which functions we want to trace and which ones we want the mcount calls to remain as nops. -Two files that contain to the enabling and disabling of recorded -functions are: +Two files are used, one for enabling and one for disabling the tracing +of recorded functions. They are: set_ftrace_filter @@ -1094,7 +1102,7 @@ and set_ftrace_notrace -A list of available functions that you can add to this files is listed +A list of available functions that you can add to these files is listed in: available_filter_functions @@ -1133,9 +1141,9 @@ sys_nanosleep Perhaps this isn't enough. The filters also allow simple wild cards. -Only the following is currently available +Only the following are currently available - * - will match functions that begins with + * - will match functions that begin with * - will match functions that end with ** - will match functions that have in it @@ -1187,7 +1195,7 @@ This is because the '>' and '>>' act just like they do in bash. To rewrite the filters, use '>' To append to the filters, use '>>' -To clear out a filter so that all functions will be recorded again. +To clear out a filter so that all functions will be recorded again: # echo > /debug/tracing/set_ftrace_filter # cat /debug/tracing/set_ftrace_filter @@ -1246,8 +1254,8 @@ ftraced As mentioned above, when dynamic ftrace is configured in, a kernel thread wakes up once a second and checks to see if there are mcount -calls that need to be converted into nops. If there is not, then -it simply goes back to sleep. But if there is, it will call +calls that need to be converted into nops. If there are not any, then +it simply goes back to sleep. But if there are some, it will call kstop_machine to convert the calls to nops. There may be a case that you do not want this added latency. @@ -1262,8 +1270,8 @@ mcount calls to nops. Remember that there's a large overhead to calling mcount. Without this kernel thread, that overhead will exist. -Any write to the ftraced_enabled file will cause the kstop_machine -to run if there are recorded calls to mcount. This means that a +If there are recorded calls to mcount, any write to the ftraced_enabled +file will cause the kstop_machine to run. This means that a user can manually perform the updates when they want to by simply echoing a '0' into the ftraced_enabled file. @@ -1315,7 +1323,7 @@ trace entries Having too much or not enough data can be troublesome in diagnosing some issue in the kernel. The file trace_entries is used to modify -the size of the internal trace buffers. The numbers listed +the size of the internal trace buffers. The number listed is the number of entries that can be recorded per CPU. To know the full size, multiply the number of possible CPUS with the number of entries. @@ -1323,7 +1331,7 @@ number of entries. # cat /debug/tracing/trace_entries 65620 -Note, to modify this you must have tracing fulling disabled. To do that, +Note, to modify this, you must have tracing completely disabled. To do that, echo "none" into the current_tracer. # echo none > /debug/tracing/current_tracer @@ -1344,7 +1352,7 @@ it will add them. This shows us that 85 entries can fit on a single page. The number of pages that will be allocated is a percentage of available -memory. Allocating too much will produces an error. +memory. Allocating too much will produce an error. # echo 1000000000000 > /debug/tracing/trace_entries -bash: echo: write error: Cannot allocate memory -- cgit v0.10.2 From beef3129b3afb74817acff72fda4a9d951e3973e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 11 Jul 2008 15:21:17 -0600 Subject: x86/PCI: Fix PCI config space for domains > 0 John Keller reports that PCI config space access is broken on machines with more than one domain. conf1 accesses only work for domain 0, so make sure we check the domain number in the raw routines before trying conf1. Reported-by: John Keller Signed-off-by: Matthew Wilcox Signed-off-by: Jesse Barnes diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index d19fd07..86aff81 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -32,7 +32,7 @@ struct pci_raw_ops *raw_pci_ext_ops; int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 *val) { - if (reg < 256 && raw_pci_ops) + if (domain == 0 && reg < 256 && raw_pci_ops) return raw_pci_ops->read(domain, bus, devfn, reg, len, val); if (raw_pci_ext_ops) return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val); @@ -42,7 +42,7 @@ int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 val) { - if (reg < 256 && raw_pci_ops) + if (domain == 0 && reg < 256 && raw_pci_ops) return raw_pci_ops->write(domain, bus, devfn, reg, len, val); if (raw_pci_ext_ops) return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val); -- cgit v0.10.2 From c157dfa3e4aea5775389f2f4d53c040bc8813af1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 13 Jul 2008 22:45:06 +0200 Subject: PCI PM: Fix pci_prepare_to_sleep The recently introduced pci_prepare_to_sleep() needs the following fix, because there are systems which are not power manageable by ACPI (ie. ACPI doesn't provide methods to put the device into low power states and back), but require ACPI hooks to be executed for wake-up to work. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e632a58..ace5181 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1152,7 +1152,6 @@ int pci_prepare_to_sleep(struct pci_dev *dev) break; default: target_state = state; - pci_enable_wake(dev, target_state, true); } } else if (device_may_wakeup(&dev->dev)) { /* @@ -1167,10 +1166,11 @@ int pci_prepare_to_sleep(struct pci_dev *dev) while (target_state && !(dev->pme_support & (1 << target_state))) target_state--; - pci_pme_active(dev, true); } } + pci_enable_wake(dev, target_state, true); + error = pci_set_power_state(dev, target_state); if (error) -- cgit v0.10.2 From c300bd2fb583afb6d68804afd38bc90b31310d95 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 10 Jul 2008 02:16:44 +0200 Subject: PCI: include linux/pm_wakeup.h for device_set_wakeup_capable drivers/pci/pci.c needs pm_wakeup.h since it uses device_set_wakup_capable(). The latter also needs to be stubbed out for !CONFIG_PM. Signed-off-by: Stephen Rothwell Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ace5181..44a46c9 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include /* isa_dma_bridge_buggy */ #include "pci.h" diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 3af0c8d..0aae777 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -63,6 +63,8 @@ static inline void device_init_wakeup(struct device *dev, int val) dev->power.can_wakeup = !!val; } +static inline void device_set_wakeup_capable(struct device *dev, int val) { } + static inline int device_can_wakeup(struct device *dev) { return dev->power.can_wakeup; -- cgit v0.10.2 From 04a33e406a062cd1bb55014ee17a3558109a2d74 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 23 Jun 2008 11:36:23 +0100 Subject: cpia2: use request_firmware() Thanks for Jaswinder Singh for converting the firmware blob itself to ihex. Signed-off-by: David Woodhouse diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index c8b9fdb..f2e8b1c 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/drivers/media/video/cpia2/cpia2_core.c @@ -33,11 +33,10 @@ #include #include +#include /* #define _CPIA2_DEBUG_ */ -#include "cpia2patch.h" - #ifdef _CPIA2_DEBUG_ static const char *block_name[] = { @@ -893,24 +892,53 @@ int cpia2_set_low_power(struct camera_data *cam) * apply_vp_patch * *****************************************************************************/ +static int cpia2_send_onebyte_command(struct camera_data *cam, + struct cpia2_command *cmd, + u8 start, u8 datum) +{ + cmd->buffer.block_data[0] = datum; + cmd->start = start; + cmd->reg_count = 1; + return cpia2_send_command(cam, cmd); +} + static int apply_vp_patch(struct camera_data *cam) { - int i, j; + const struct firmware *fw; + const char fw_name[] = "cpia2/stv0672_vp4.bin"; + int i, ret; struct cpia2_command cmd; + ret = request_firmware(&fw, fw_name, &cam->dev->dev); + if (ret) { + printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n", + fw_name); + return ret; + } + cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP; cmd.direction = TRANSFER_WRITE; - for (i = 0; i < PATCH_DATA_SIZE; i++) { - for (j = 0; j < patch_data[i].count; j++) { - cmd.buffer.block_data[j] = patch_data[i].data[j]; - } + /* First send the start address... */ + cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */ + cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */ - cmd.start = patch_data[i].reg; - cmd.reg_count = patch_data[i].count; + /* ... followed by the data payload */ + for (i = 2; i < fw->size; i += 64) { + cmd.start = 0x0C; /* Data */ + cmd.reg_count = min_t(int, 64, fw->size - i); + memcpy(cmd.buffer.block_data, &fw->data[i], cmd.reg_count); cpia2_send_command(cam, &cmd); } + /* Next send the start address... */ + cpia2_send_onebyte_command(cam, &cmd, 0x0A, fw->data[0]); /* hi */ + cpia2_send_onebyte_command(cam, &cmd, 0x0B, fw->data[1]); /* lo */ + + /* ... followed by the 'goto' command */ + cpia2_send_onebyte_command(cam, &cmd, 0x0D, 1); + + release_firmware(fw); return 0; } diff --git a/drivers/media/video/cpia2/cpia2patch.h b/drivers/media/video/cpia2/cpia2patch.h deleted file mode 100644 index 7f085fb..0000000 --- a/drivers/media/video/cpia2/cpia2patch.h +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** - * - * Filename: cpia2patch.h - * - * Copyright 2001, STMicrolectronics, Inc. - * - * Contact: steve.miller@st.com - * - * Description: - * This file contains patch data for the CPiA2 (stv0672) VP4. - * - * 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. - * - ****************************************************************************/ - -#ifndef CPIA2_PATCH_HEADER -#define CPIA2_PATCH_HEADER - -typedef struct { - unsigned char reg; - unsigned char count; - const unsigned char *data; -} cpia2_patch; - -static const unsigned char start_address_hi[1] = { - 0x01 -}; - -static const unsigned char start_address_lo[1] = { - 0xBC -}; - -static const unsigned char patch_block0[64] = { - 0xE3, 0x02, 0xE3, 0x03, 0xE3, 0x04, 0xE3, 0x05, - 0xE3, 0x06, 0xE3, 0x07, 0x93, 0x44, 0x56, 0xD4, - 0x93, 0x4E, 0x56, 0x51, 0x93, 0x4E, 0x51, 0xD6, - 0x93, 0x4E, 0x4F, 0x54, 0x93, 0x4E, 0x92, 0x4F, - 0x92, 0xA4, 0x93, 0x05, 0x92, 0xF4, 0x93, 0x1B, - 0x92, 0x92, 0x91, 0xE6, 0x92, 0x36, 0x92, 0x74, - 0x92, 0x4A, 0x92, 0x8C, 0x92, 0x8E, 0xC8, 0xD0, - 0x0B, 0x42, 0x02, 0xA0, 0xCA, 0x92, 0x09, 0x02 -}; - -static const unsigned char patch_block1[64] = { - 0xC9, 0x10, 0x0A, 0x0A, 0x0A, 0x81, 0xE3, 0xB8, - 0xE3, 0xB0, 0xE3, 0xA8, 0xE3, 0xA0, 0xE3, 0x98, - 0xE3, 0x90, 0xE1, 0x00, 0xCF, 0xD7, 0x0A, 0x12, - 0xCC, 0x95, 0x08, 0xB2, 0x0A, 0x18, 0xE1, 0x00, - 0x01, 0xEE, 0x0C, 0x08, 0x4A, 0x12, 0xC8, 0x18, - 0xF0, 0x9A, 0xC0, 0x22, 0xF3, 0x1C, 0x4A, 0x13, - 0xF3, 0x14, 0xC8, 0xA0, 0xF2, 0x14, 0xF2, 0x1C, - 0xEB, 0x13, 0xD3, 0xA2, 0x63, 0x16, 0x48, 0x9E -}; - -static const unsigned char patch_block2[64] = { - 0xF0, 0x18, 0xA4, 0x03, 0xF3, 0x93, 0xC0, 0x58, - 0xF7, 0x13, 0x51, 0x9C, 0xE9, 0x20, 0xCF, 0xEF, - 0x63, 0xF9, 0x92, 0x2E, 0xD3, 0x5F, 0x63, 0xFA, - 0x92, 0x2E, 0xD3, 0x67, 0x63, 0xFB, 0x92, 0x2E, - 0xD3, 0x6F, 0xE9, 0x1A, 0x63, 0x16, 0x48, 0xA7, - 0xF0, 0x20, 0xA4, 0x06, 0xF3, 0x94, 0xC0, 0x27, - 0xF7, 0x14, 0xF5, 0x13, 0x51, 0x9D, 0xF6, 0x13, - 0x63, 0x18, 0xC4, 0x20, 0xCB, 0xEF, 0x63, 0xFC -}; - -static const unsigned char patch_block3[64] = { - 0x92, 0x2E, 0xD3, 0x77, 0x63, 0xFD, 0x92, 0x2E, - 0xD3, 0x7F, 0x63, 0xFE, 0x92, 0x2E, 0xD3, 0x87, - 0x63, 0xFF, 0x92, 0x2E, 0xD3, 0x8F, 0x64, 0x38, - 0x92, 0x2E, 0xD3, 0x97, 0x64, 0x39, 0x92, 0x2E, - 0xD3, 0x9F, 0xE1, 0x00, 0xF5, 0x3A, 0xF4, 0x3B, - 0xF7, 0xBF, 0xF2, 0xBC, 0xF2, 0x3D, 0xE1, 0x00, - 0x80, 0x87, 0x90, 0x80, 0x51, 0xD5, 0x02, 0x22, - 0x02, 0x32, 0x4B, 0xD3, 0xF7, 0x11, 0x0B, 0xDA -}; - -static const unsigned char patch_block4[64] = { - 0xE1, 0x00, 0x0E, 0x02, 0x02, 0x40, 0x0D, 0xB5, - 0xE3, 0x02, 0x48, 0x55, 0xE5, 0x12, 0xA4, 0x01, - 0xE8, 0x1B, 0xE3, 0x90, 0xF0, 0x18, 0xA4, 0x01, - 0xE8, 0xBF, 0x8D, 0xB8, 0x4B, 0xD1, 0x4B, 0xD8, - 0x0B, 0xCB, 0x0B, 0xC2, 0xE1, 0x00, 0xE3, 0x02, - 0xE3, 0x03, 0x52, 0xD3, 0x60, 0x59, 0xE6, 0x93, - 0x0D, 0x22, 0x52, 0xD4, 0xE6, 0x93, 0x0D, 0x2A, - 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x5D -}; - -static const unsigned char patch_block5[64] = { - 0x02, 0x63, 0xE3, 0x02, 0xC8, 0x12, 0x02, 0xCA, - 0xC8, 0x52, 0x02, 0xC2, 0x82, 0x68, 0xE3, 0x02, - 0xC8, 0x14, 0x02, 0xCA, 0xC8, 0x90, 0x02, 0xC2, - 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, 0xCC, 0xD2, - 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA, 0x0A, 0x98, - 0x0A, 0xA0, 0x0A, 0xA8, 0xE3, 0x90, 0xE1, 0x00, - 0xE3, 0x02, 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, - 0xCC, 0xD2, 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA -}; - -static const unsigned char patch_block6[64] = { - 0x0A, 0x98, 0x0A, 0xA0, 0x0A, 0xA8, 0x49, 0x91, - 0xE5, 0x6A, 0xA4, 0x04, 0xC8, 0x12, 0x02, 0xCA, - 0xC8, 0x52, 0x82, 0x89, 0xC8, 0x14, 0x02, 0xCA, - 0xC8, 0x90, 0x02, 0xC2, 0xE3, 0x90, 0xE1, 0x00, - 0x08, 0x60, 0xE1, 0x00, 0x48, 0x53, 0xE8, 0x97, - 0x08, 0x5A, 0xE1, 0x00, 0xE3, 0x02, 0xE3, 0x03, - 0x54, 0xD3, 0x60, 0x59, 0xE6, 0x93, 0x0D, 0x52, - 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x9C -}; - -static const unsigned char patch_block7[64] = { - 0xE3, 0x02, 0x55, 0x13, 0x93, 0x17, 0x55, 0x13, - 0x93, 0x17, 0xE3, 0x90, 0xE1, 0x00, 0x75, 0x30, - 0xE3, 0x02, 0xE3, 0x03, 0x55, 0x55, 0x60, 0x59, - 0xE6, 0x93, 0x0D, 0xB2, 0xE3, 0x98, 0xE3, 0x90, - 0xE1, 0x00, 0x02, 0xAE, 0xE7, 0x92, 0xE9, 0x18, - 0xEA, 0x9A, 0xE8, 0x98, 0xE8, 0x10, 0xE8, 0x11, - 0xE8, 0x51, 0xD2, 0xDA, 0xD2, 0xF3, 0xE8, 0x13, - 0xD2, 0xFA, 0xE8, 0x50, 0xD2, 0xEA, 0xE8, 0xD0 -}; - -static const unsigned char patch_block8[64] = { - 0xE8, 0xD1, 0xD3, 0x0A, 0x03, 0x09, 0x48, 0x23, - 0xE5, 0x2C, 0xA0, 0x03, 0x48, 0x24, 0xEA, 0x1C, - 0x03, 0x08, 0xD2, 0xE3, 0xD3, 0x03, 0xD3, 0x13, - 0xE1, 0x00, 0x02, 0xCB, 0x05, 0x93, 0x57, 0x93, - 0xF0, 0x9A, 0xAC, 0x0B, 0xE3, 0x07, 0x92, 0xEA, - 0xE2, 0x9F, 0xE5, 0x06, 0xE3, 0xB0, 0xA0, 0x02, - 0xEB, 0x1E, 0x82, 0xD7, 0xEA, 0x1E, 0xE2, 0x3B, - 0x85, 0x9B, 0xE9, 0x1E, 0xC8, 0x90, 0x85, 0x94 -}; - -static const unsigned char patch_block9[64] = { - 0x02, 0xDE, 0x05, 0x80, 0x57, 0x93, 0xF0, 0xBA, - 0xAC, 0x06, 0x92, 0xEA, 0xE2, 0xBF, 0xE5, 0x06, - 0xA0, 0x01, 0xEB, 0xBF, 0x85, 0x88, 0xE9, 0x3E, - 0xC8, 0x90, 0x85, 0x81, 0xE9, 0x3E, 0xF0, 0xBA, - 0xF3, 0x39, 0xF0, 0x3A, 0x60, 0x17, 0xF0, 0x3A, - 0xC0, 0x90, 0xF0, 0xBA, 0xE1, 0x00, 0x00, 0x3F, - 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x10, 0x60, 0x59, - 0xE6, 0x93, 0x0D, 0xA2, 0x58, 0x12, 0xE6, 0x93 -}; - -static const unsigned char patch_block10[64] = { - 0x0D, 0xAA, 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, - 0x03, 0x01, 0xE1, 0x00, 0x03, 0x03, 0x9B, 0x7D, - 0x8B, 0x8B, 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x56, - 0x60, 0x59, 0xE6, 0x93, 0x0D, 0xBA, 0xE3, 0x98, - 0xE3, 0x90, 0xE1, 0x00, 0x03, 0x0F, 0x93, 0x11, - 0xE1, 0x00, 0xE3, 0x02, 0x4A, 0x11, 0x0B, 0x42, - 0x91, 0xAF, 0xE3, 0x90, 0xE1, 0x00, 0xF2, 0x91, - 0xF0, 0x91, 0xA3, 0xFE, 0xE1, 0x00, 0x60, 0x92 -}; - -static const unsigned char patch_block11[64] = { - 0xC0, 0x5F, 0xF0, 0x13, 0xF0, 0x13, 0x59, 0x5B, - 0xE2, 0x13, 0xF0, 0x11, 0x5A, 0x19, 0xE2, 0x13, - 0xE1, 0x00, 0x00, 0x00, 0x03, 0x27, 0x68, 0x61, - 0x76, 0x61, 0x6E, 0x61, 0x00, 0x06, 0x03, 0x2C, - 0xE3, 0x02, 0xE3, 0x03, 0xE9, 0x38, 0x59, 0x15, - 0x59, 0x5A, 0xF2, 0x9A, 0xBC, 0x0B, 0xA4, 0x0A, - 0x59, 0x1E, 0xF3, 0x11, 0xF0, 0x1A, 0xE2, 0xBB, - 0x59, 0x15, 0xF0, 0x11, 0x19, 0x2A, 0xE5, 0x02 -}; - -static const unsigned char patch_block12[54] = { - 0xA4, 0x01, 0xEB, 0xBF, 0xE3, 0x98, 0xE3, 0x90, - 0xE1, 0x00, 0x03, 0x42, 0x19, 0x28, 0xE1, 0x00, - 0xE9, 0x30, 0x60, 0x79, 0xE1, 0x00, 0xE3, 0x03, - 0xE3, 0x07, 0x60, 0x79, 0x93, 0x4E, 0xE3, 0xB8, - 0xE3, 0x98, 0xE1, 0x00, 0xE9, 0x1A, 0xF0, 0x1F, - 0xE2, 0x33, 0xF0, 0x91, 0xE2, 0x92, 0xE0, 0x32, - 0xF0, 0x31, 0xE1, 0x00, 0x00, 0x00 -}; - -static const unsigned char do_call[1] = { - 0x01 -}; - - -#define PATCH_DATA_SIZE 18 - -static const cpia2_patch patch_data[PATCH_DATA_SIZE] = { - {0x0A, sizeof(start_address_hi), start_address_hi} - , // 0 - {0x0B, sizeof(start_address_lo), start_address_lo} - , // 1 - {0x0C, sizeof(patch_block0), patch_block0} - , // 2 - {0x0C, sizeof(patch_block1), patch_block1} - , // 3 - {0x0C, sizeof(patch_block2), patch_block2} - , // 4 - {0x0C, sizeof(patch_block3), patch_block3} - , // 5 - {0x0C, sizeof(patch_block4), patch_block4} - , // 6 - {0x0C, sizeof(patch_block5), patch_block5} - , // 7 - {0x0C, sizeof(patch_block6), patch_block6} - , // 8 - {0x0C, sizeof(patch_block7), patch_block7} - , // 9 - {0x0C, sizeof(patch_block8), patch_block8} - , // 10 - {0x0C, sizeof(patch_block9), patch_block9} - , //11 - {0x0C, sizeof(patch_block10), patch_block10} - , // 12 - {0x0C, sizeof(patch_block11), patch_block11} - , // 13 - {0x0C, sizeof(patch_block12), patch_block12} - , // 14 - {0x0A, sizeof(start_address_hi), start_address_hi} - , // 15 - {0x0B, sizeof(start_address_lo), start_address_lo} - , // 16 - {0x0D, sizeof(do_call), do_call} //17 -}; - - -#endif diff --git a/firmware/Makefile b/firmware/Makefile index 2f81089..8d5465f 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -60,6 +60,7 @@ fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ # whiteheat_loader_debug.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw +fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index 6c7b0b4..d8f6199 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -236,3 +236,16 @@ Licence: Unknown Found in hex form in kernel source. -------------------------------------------------------------------------- + +Driver: CPiA2 -- cameras based on Vision's CPiA2 + +File: cpia2/stv0672_vp4.bin + +Licence: Allegedly GPLv2+, but no source visible. Marked: + Copyright (C) 2001 STMicroelectronics, Inc. + Contact: steve.miller@st.com + Description: This file contains patch data for the CPiA2 (stv0672) VP4. + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/cpia2/stv0672_vp4.bin.ihex b/firmware/cpia2/stv0672_vp4.bin.ihex new file mode 100644 index 0000000..bd0b9cf --- /dev/null +++ b/firmware/cpia2/stv0672_vp4.bin.ihex @@ -0,0 +1,73 @@ +:1000000001BCE302E303E304E305E306E3079344EF +:1000100056D4934E5651934E51D6934E4F54934EC1 +:10002000924F92A4930592F4931B929291E692368A +:100030009274924A928C928EC8D00B4202A0CA92BD +:100040000902C9100A0A0A81E3B8E3B0E3A8E3A0F1 +:10005000E398E390E100CFD70A12CC9508B20A18D2 +:10006000E10001EE0C084A12C818F09AC022F31CF5 +:100070004A13F314C8A0F214F21CEB13D3A26316B4 +:10008000489EF018A403F393C058F713519CE9203D +:10009000CFEF63F9922ED35F63FA922ED36763FB9F +:1000A000922ED36FE91A631648A7F020A406F394A2 +:1000B000C027F714F513519DF6136318C420CBEF36 +:1000C00063FC922ED37763FD922ED37F63FE922E34 +:1000D000D38763FF922ED38F6438922ED3976439DF +:1000E000922ED39FE100F53AF43BF7BFF2BCF23D0C +:1000F000E1008087908051D5022202324BD3F71164 +:100100000BDAE1000E0202400DB5E3024855E5129C +:10011000A401E81BE390F018A401E8BF8DB84BD10F +:100120004BD80BCB0BC2E100E302E30352D360597F +:10013000E6930D2252D4E6930D2AE398E390E10072 +:10014000025D0263E302C81202CAC85202C2826898 +:10015000E302C81402CAC89002C20AD0C9930ADADC +:10016000CCD20AE2631202DA0A980AA00AA8E39043 +:10017000E100E3020AD0C9930ADACCD20AE26312A0 +:1001800002DA0A980AA00AA84991E56AA404C812EA +:1001900002CAC8528289C81402CAC89002C2E39037 +:1001A000E1000860E1004853E897085AE100E302E3 +:1001B000E30354D36059E6930D52E398E390E100D2 +:1001C000029CE3025513931755139317E390E10034 +:1001D0007530E302E30355556059E6930DB2E39899 +:1001E000E390E10002AEE792E918EA9AE898E81095 +:1001F000E811E851D2DAD2F3E813D2FAE850D2EAA1 +:10020000E8D0E8D1D30A03094823E52CA003482409 +:10021000EA1C0308D2E3D303D313E10002CB059316 +:100220005793F09AAC0BE30792EAE29FE506E3B03E +:10023000A002EB1E82D7EA1EE23B859BE91EC89016 +:10024000859402DE05805793F0BAAC0692EAE2BFCD +:10025000E506A001EBBF8588E93EC8908581E93EAF +:10026000F0BAF339F03A6017F03AC090F0BAE10012 +:10027000003FE302E30358106059E6930DA25812C1 +:10028000E6930DAAE398E390E1000301E100030384 +:100290009B7D8B8BE302E30358566059E6930DBABE +:1002A000E398E390E100030F9311E100E3024A11A8 +:1002B0000B4291AFE390E100F291F091A3FEE100D7 +:1002C0006092C05FF013F013595BE213F0115A19FA +:1002D000E213E10000000327686176616E610006A9 +:1002E000032CE302E303E9385915595AF29ABC0B7F +:1002F000A40A591EF311F01AE2BB5915F011192A7C +:10030000E502A401EBBFE398E390E1000342192862 +:10031000E100E9306079E100E303E3076079934E9F +:10032000E3B8E398E100E91AF01FE233F091E292BA +:08033000E032F031E1000000B1 +:00000001FF + + Copyright 2001, STMicrolectronics, Inc. + Contact: steve.miller@st.com + + Description: + This file contains patch data for the CPiA2 (stv0672) VP4. + + 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. -- cgit v0.10.2 From c466774636b3cc43c2c304b44e52974d9d53f3e0 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 23 Jun 2008 11:41:04 +0100 Subject: dabusb: use request_firmware() Signed-off-by: David Woodhouse diff --git a/drivers/media/video/dabfirmware.h b/drivers/media/video/dabfirmware.h deleted file mode 100644 index cbd9263..0000000 --- a/drivers/media/video/dabfirmware.h +++ /dev/null @@ -1,1415 +0,0 @@ -/* - * dabdata.h - dab usb firmware and bitstream data - * - * Copyright (C) 1999 BayCom GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that redistributions of source - * code retain the above copyright notice and this comment without - * modification. - */ - -static INTEL_HEX_RECORD firmware[] = { - -{ 2, 0x0000, 0, {0x21,0x57} }, -{ 3, 0x0003, 0, {0x02,0x01,0x66} }, -{ 3, 0x000b, 0, {0x02,0x01,0x66} }, -{ 3, 0x0013, 0, {0x02,0x01,0x66} }, -{ 3, 0x001b, 0, {0x02,0x01,0x66} }, -{ 3, 0x0023, 0, {0x02,0x01,0x66} }, -{ 3, 0x002b, 0, {0x02,0x01,0x66} }, -{ 3, 0x0033, 0, {0x02,0x03,0x0f} }, -{ 3, 0x003b, 0, {0x02,0x01,0x66} }, -{ 3, 0x0043, 0, {0x02,0x01,0x00} }, -{ 3, 0x004b, 0, {0x02,0x01,0x66} }, -{ 3, 0x0053, 0, {0x02,0x01,0x66} }, -{ 3, 0x005b, 0, {0x02,0x04,0xbd} }, -{ 3, 0x0063, 0, {0x02,0x01,0x67} }, -{ 3, 0x0100, 0, {0x02,0x0c,0x5a} }, -{ 3, 0x0104, 0, {0x02,0x01,0xed} }, -{ 3, 0x0108, 0, {0x02,0x02,0x51} }, -{ 3, 0x010c, 0, {0x02,0x02,0x7c} }, -{ 3, 0x0110, 0, {0x02,0x02,0xe4} }, -{ 1, 0x0114, 0, {0x32} }, -{ 1, 0x0118, 0, {0x32} }, -{ 3, 0x011c, 0, {0x02,0x05,0xfd} }, -{ 3, 0x0120, 0, {0x02,0x00,0x00} }, -{ 3, 0x0124, 0, {0x02,0x00,0x00} }, -{ 3, 0x0128, 0, {0x02,0x04,0x3c} }, -{ 3, 0x012c, 0, {0x02,0x04,0x6a} }, -{ 3, 0x0130, 0, {0x02,0x00,0x00} }, -{ 3, 0x0134, 0, {0x02,0x00,0x00} }, -{ 3, 0x0138, 0, {0x02,0x00,0x00} }, -{ 3, 0x013c, 0, {0x02,0x00,0x00} }, -{ 3, 0x0140, 0, {0x02,0x00,0x00} }, -{ 3, 0x0144, 0, {0x02,0x00,0x00} }, -{ 3, 0x0148, 0, {0x02,0x00,0x00} }, -{ 3, 0x014c, 0, {0x02,0x00,0x00} }, -{ 3, 0x0150, 0, {0x02,0x00,0x00} }, -{ 3, 0x0154, 0, {0x02,0x00,0x00} }, -{ 10, 0x0157, 0, {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61} }, -{ 5, 0x0161, 0, {0x12,0x07,0x6f,0x21,0x64} }, -{ 1, 0x0166, 0, {0x32} }, -{ 14, 0x0167, 0, {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0} }, -{ 14, 0x0175, 0, {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, -{ 14, 0x0183, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, -{ 14, 0x0191, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0} }, -{ 3, 0x019f, 0, {0x55,0x7f,0xf0} }, -{ 14, 0x01a2, 0, {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0} }, -{ 14, 0x01b0, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, -{ 14, 0x01be, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} }, -{ 14, 0x01cc, 0, {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86} }, -{ 3, 0x01da, 0, {0xd0,0xd0,0x32} }, -{ 8, 0x01dd, 0, {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05} }, -{ 7, 0x01e5, 0, {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} }, -{ 1, 0x01ec, 0, {0x22} }, -{ 14, 0x01ed, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0} }, -{ 14, 0x01fb, 0, {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91} }, -{ 13, 0x0209, 0, {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90} }, -{ 9, 0x0216, 0, {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21} }, -{ 4, 0x021f, 0, {0x7a,0x00,0x7b,0x00} }, -{ 11, 0x0223, 0, {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12} }, -{ 14, 0x022e, 0, {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00} }, -{ 2, 0x023c, 0, {0x01,0x0b} }, -{ 2, 0x023e, 0, {0x80,0xe3} }, -{ 2, 0x0240, 0, {0xd0,0x86} }, -{ 14, 0x0242, 0, {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0} }, -{ 1, 0x0250, 0, {0x32} }, -{ 14, 0x0251, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 14, 0x025f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} }, -{ 4, 0x026d, 0, {0x04,0xf0,0xd0,0x86} }, -{ 11, 0x0271, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x027c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, -{ 14, 0x028a, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, -{ 13, 0x0298, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} }, -{ 12, 0x02a5, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12} }, -{ 6, 0x02b1, 0, {0x11,0x44,0x75,0x70,0x39,0x75} }, -{ 6, 0x02b7, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} }, -{ 12, 0x02bd, 0, {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86} }, -{ 14, 0x02c9, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, -{ 13, 0x02d7, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x02e4, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 14, 0x02f2, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} }, -{ 4, 0x0300, 0, {0x10,0xf0,0xd0,0x86} }, -{ 11, 0x0304, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x030f, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, -{ 14, 0x031d, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, -{ 12, 0x032b, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02} }, -{ 7, 0x0337, 0, {0x12,0x11,0x44,0x75,0x70,0x40,0x75} }, -{ 6, 0x033e, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} }, -{ 14, 0x0344, 0, {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0} }, -{ 5, 0x0352, 0, {0x75,0xd8,0x10,0xd0,0x86} }, -{ 14, 0x0357, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, -{ 13, 0x0365, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 13, 0x0372, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} }, -{ 12, 0x037f, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90} }, -{ 13, 0x038b, 0, {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40} }, -{ 1, 0x0398, 0, {0xf0} }, -{ 1, 0x0399, 0, {0x22} }, -{ 13, 0x039a, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} }, -{ 12, 0x03a7, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90} }, -{ 12, 0x03b3, 0, {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5} }, -{ 11, 0x03bf, 0, {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0} }, -{ 1, 0x03ca, 0, {0x22} }, -{ 10, 0x03cb, 0, {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12} }, -{ 9, 0x03d5, 0, {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12} }, -{ 2, 0x03de, 0, {0x03,0x72} }, -{ 1, 0x03e0, 0, {0x22} }, -{ 12, 0x03e1, 0, {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25} }, -{ 9, 0x03ed, 0, {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75} }, -{ 9, 0x03f6, 0, {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75} }, -{ 9, 0x03ff, 0,{0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75} }, -{ 8, 0x0408, 0,{0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72} }, -{ 1, 0x0410, 0,{0x22} }, -{ 14, 0x0411, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 14, 0x041f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} }, -{ 4, 0x042d, 0, {0x02,0xf0,0xd0,0x86} }, -{ 11, 0x0431, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x043c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 14, 0x044a, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74} }, -{ 7, 0x0458, 0, {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86} }, -{ 11, 0x045f, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x046a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 14, 0x0478, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} }, -{ 7, 0x0486, 0, {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86} }, -{ 11, 0x048d, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x0498, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 12, 0x04a6, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86} }, -{ 11, 0x04b2, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x04bd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} }, -{ 12, 0x04cb, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86} }, -{ 11, 0x04d7, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 12, 0x04e2, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0} }, -{ 1, 0x04ee, 0, {0x22} }, -{ 7, 0x04ef, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21} }, -{ 1, 0x04f6, 0, {0x22} }, -{ 14, 0x04f7, 0, {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa} }, -{ 14, 0x0505, 0, {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54} }, -{ 14, 0x0513, 0, {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54} }, -{ 11, 0x0521, 0, {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02} }, -{ 2, 0x052c, 0, {0x7a,0x00} }, -{ 7, 0x052e, 0, {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02} }, -{ 2, 0x0535, 0, {0x7b,0x00} }, -{ 11, 0x0537, 0, {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b} }, -{ 7, 0x0542, 0, {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75} }, -{ 9, 0x0549, 0, {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75} }, -{ 4, 0x0552, 0, {0x70,0x47,0x75,0x71} }, -{ 8, 0x0556, 0, {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85} }, -{ 5, 0x055e, 0, {0x3a,0x73,0x12,0x11,0xa0} }, -{ 1, 0x0563, 0, {0x22} }, -{ 14, 0x0564, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} }, -{ 14, 0x0572, 0, {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc} }, -{ 14, 0x0580, 0, {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33} }, -{ 14, 0x058e, 0, {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe} }, -{ 5, 0x059c, 0, {0xbe,0x01,0x02,0x80,0x03} }, -{ 3, 0x05a1, 0, {0x02,0x05,0xf9} }, -{ 6, 0x05a4, 0, {0xbc,0x01,0x21,0xbd,0x00,0x1e} }, -{ 14, 0x05aa, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc} }, -{ 14, 0x05b8, 0, {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0} }, -{ 2, 0x05c6, 0, {0x80,0x31} }, -{ 14, 0x05c8, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00} }, -{ 14, 0x05d6, 0, {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83} }, -{ 14, 0x05e4, 0, {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1} }, -{ 7, 0x05f2, 0, {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0} }, -{ 3, 0x05f9, 0, {0x75,0x38,0x01} }, -{ 1, 0x05fc, 0, {0x22} }, -{ 14, 0x05fd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, -{ 14, 0x060b, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, -{ 13, 0x0619, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} }, -{ 13, 0x0626, 0, {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86} }, -{ 14, 0x0633, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, -{ 13, 0x0641, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 14, 0x064e, 0, {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0} }, -{ 14, 0x065c, 0, {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74} }, -{ 14, 0x066a, 0, {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54} }, -{ 14, 0x0678, 0, {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17} }, -{ 14, 0x0686, 0, {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4} }, -{ 14, 0x0694, 0, {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff} }, -{ 3, 0x06a2, 0, {0xbf,0x81,0x0a} }, -{ 10, 0x06a5, 0, {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0} }, -{ 8, 0x06af, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a} }, -{ 3, 0x06b7, 0, {0xba,0x01,0x0c} }, -{ 12, 0x06ba, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} }, -{ 11, 0x06c6, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0} }, -{ 8, 0x06d1, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b} }, -{ 3, 0x06d9, 0, {0xba,0x01,0x0d} }, -{ 13, 0x06dc, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} }, -{ 11, 0x06e9, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0} }, -{ 8, 0x06f4, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c} }, -{ 3, 0x06fc, 0, {0xba,0x01,0x0d} }, -{ 13, 0x06ff, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c} }, -{ 12, 0x070c, 0, {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0} }, -{ 5, 0x0718, 0, {0x90,0x7f,0xb5,0xec,0xf0} }, -{ 1, 0x071d, 0, {0x22} }, -{ 12, 0x071e, 0, {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80} }, -{ 10, 0x072a, 0, {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} }, -{ 9, 0x0734, 0, {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} }, -{ 9, 0x073d, 0, {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} }, -{ 7, 0x0746, 0, {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00} }, -{ 3, 0x074d, 0, {0xba,0xff,0x00} }, -{ 2, 0x0750, 0, {0x50,0x0a} }, -{ 10, 0x0752, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} }, -{ 10, 0x075c, 0, {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75} }, -{ 8, 0x0766, 0, {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2} }, -{ 1, 0x076e, 0, {0x22} }, -{ 14, 0x076f, 0, {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92} }, -{ 14, 0x077d, 0, {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8} }, -{ 14, 0x078b, 0, {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75} }, -{ 9, 0x0799, 0, {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75} }, -{ 5, 0x07a2, 0, {0x23,0x00,0x75,0x47,0x00} }, -{ 7, 0x07a7, 0, {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11} }, -{ 13, 0x07ae, 0, {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0} }, -{ 4, 0x07bb, 0, {0x05,0x47,0x80,0xe8} }, -{ 9, 0x07bf, 0, {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5} }, -{ 7, 0x07c8, 0, {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75} }, -{ 11, 0x07cf, 0, {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93} }, -{ 14, 0x07da, 0, {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80} }, -{ 14, 0x07e8, 0, {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} }, -{ 14, 0x07f6, 0, {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74} }, -{ 14, 0x0804, 0, {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90} }, -{ 14, 0x0812, 0, {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0} }, -{ 14, 0x0820, 0, {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4} }, -{ 14, 0x082e, 0, {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9} }, -{ 14, 0x083c, 0, {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0} }, -{ 14, 0x084a, 0, {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90} }, -{ 14, 0x0858, 0, {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0} }, -{ 14, 0x0866, 0, {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80} }, -{ 11, 0x0874, 0, {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00} }, -{ 9, 0x087f, 0, {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17} }, -{ 12, 0x0888, 0, {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47} }, -{ 9, 0x0894, 0, {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b} }, -{ 2, 0x089d, 0, {0x80,0xe0} }, -{ 12, 0x089f, 0, {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00} }, -{ 13, 0x08ab, 0, {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a} }, -{ 14, 0x08b8, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} }, -{ 10, 0x08c6, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} }, -{ 2, 0x08d0, 0, {0x80,0xd9} }, -{ 13, 0x08d2, 0, {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90} }, -{ 14, 0x08df, 0, {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac} }, -{ 14, 0x08ed, 0, {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10} }, -{ 13, 0x08fb, 0, {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90} }, -{ 12, 0x0908, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75} }, -{ 12, 0x0914, 0, {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7} }, -{ 10, 0x0920, 0, {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01} }, -{ 13, 0x092a, 0, {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03} }, -{ 3, 0x0937, 0, {0x02,0x0a,0x3f} }, -{ 12, 0x093a, 0, {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97} }, -{ 14, 0x0946, 0, {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa} }, -{ 12, 0x0954, 0, {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} }, -{ 13, 0x0960, 0, {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33} }, -{ 13, 0x096d, 0, {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33} }, -{ 2, 0x097a, 0, {0x60,0x0c} }, -{ 12, 0x097c, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0} }, -{ 11, 0x0988, 0, {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12} }, -{ 14, 0x0993, 0, {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a} }, -{ 6, 0x09a1, 0, {0xfa,0xe5,0x33,0xb4,0x04,0x29} }, -{ 3, 0x09a7, 0, {0xba,0xa0,0x00} }, -{ 2, 0x09aa, 0, {0x50,0x24} }, -{ 13, 0x09ac, 0, {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90} }, -{ 14, 0x09b9, 0, {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05} }, -{ 9, 0x09c7, 0, {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02} }, -{ 5, 0x09d0, 0, {0xe5,0x33,0xb4,0x02,0x26} }, -{ 6, 0x09d5, 0, {0xc3,0x74,0x04,0x9a,0x50,0x20} }, -{ 13, 0x09db, 0, {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90} }, -{ 13, 0x09e8, 0, {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12} }, -{ 6, 0x09f5, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04} }, -{ 5, 0x09fb, 0, {0xe5,0x33,0xb4,0x08,0x1d} }, -{ 4, 0x0a00, 0, {0xe5,0x34,0x70,0x19} }, -{ 10, 0x0a04, 0, {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35} }, -{ 12, 0x0a0e, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} }, -{ 3, 0x0a1a, 0, {0x05,0xd0,0x04} }, -{ 5, 0x0a1d, 0, {0xe5,0x33,0xb4,0x01,0x1d} }, -{ 4, 0x0a22, 0, {0xe5,0x34,0x70,0x19} }, -{ 10, 0x0a26, 0, {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35} }, -{ 12, 0x0a30, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} }, -{ 3, 0x0a3c, 0, {0x05,0xd0,0x04} }, -{ 14, 0x0a3f, 0, {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96} }, -{ 14, 0x0a4d, 0, {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08} }, -{ 10, 0x0a5b, 0, {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08} }, -{ 8, 0x0a65, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08} }, -{ 8, 0x0a6d, 0, {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13} }, -{ 14, 0x0a75, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c} }, -{ 5, 0x0a83, 0, {0x00,0x7d,0x00,0x80,0x05} }, -{ 5, 0x0a88, 0, {0x0c,0xbc,0x00,0x01,0x0d} }, -{ 5, 0x0a8d, 0, {0xe5,0x38,0xb4,0x01,0x0e} }, -{ 13, 0x0a92, 0, {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38} }, -{ 1, 0x0a9f, 0, {0x00} }, -{ 7, 0x0aa0, 0, {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a} }, -{ 10, 0x0aa7, 0, {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d} }, -{ 14, 0x0ab1, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} }, -{ 9, 0x0abf, 0, {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03} }, -{ 3, 0x0ac8, 0, {0x02,0x0b,0x36} }, -{ 5, 0x0acb, 0, {0x75,0x32,0x00,0x7b,0x00} }, -{ 3, 0x0ad0, 0, {0xbb,0x64,0x00} }, -{ 2, 0x0ad3, 0, {0x50,0x1c} }, -{ 14, 0x0ad5, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} }, -{ 13, 0x0ae3, 0, {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80} }, -{ 1, 0x0af0, 0, {0xdf} }, -{ 13, 0x0af1, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12} }, -{ 12, 0x0afe, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75} }, -{ 13, 0x0b0a, 0, {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05} }, -{ 9, 0x0b17, 0, {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71} }, -{ 11, 0x0b20, 0, {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} }, -{ 11, 0x0b2b, 0, {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d} }, -{ 3, 0x0b36, 0, {0xba,0x2a,0x3b} }, -{ 13, 0x0b39, 0, {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} }, -{ 14, 0x0b46, 0, {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0} }, -{ 2, 0x0b54, 0, {0x7b,0x00} }, -{ 3, 0x0b56, 0, {0xbb,0x0a,0x00} }, -{ 5, 0x0b59, 0, {0x40,0x03,0x02,0x0c,0x2d} }, -{ 14, 0x0b5e, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} }, -{ 8, 0x0b6c, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2} }, -{ 3, 0x0b74, 0, {0xba,0x2b,0x1a} }, -{ 8, 0x0b77, 0, {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12} }, -{ 14, 0x0b7f, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0} }, -{ 4, 0x0b8d, 0, {0x02,0x02,0x0c,0x2d} }, -{ 3, 0x0b91, 0, {0xba,0x10,0x1f} }, -{ 14, 0x0b94, 0, {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0} }, -{ 14, 0x0ba2, 0, {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02} }, -{ 3, 0x0bb0, 0, {0x02,0x0c,0x2d} }, -{ 3, 0x0bb3, 0, {0xba,0x11,0x12} }, -{ 14, 0x0bb6, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0} }, -{ 4, 0x0bc4, 0, {0x02,0x02,0x0c,0x2d} }, -{ 3, 0x0bc8, 0, {0xba,0x12,0x12} }, -{ 14, 0x0bcb, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0} }, -{ 4, 0x0bd9, 0, {0x02,0x02,0x0c,0x2d} }, -{ 3, 0x0bdd, 0, {0xba,0x13,0x0b} }, -{ 11, 0x0be0, 0, {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42} }, -{ 3, 0x0beb, 0, {0xba,0x14,0x11} }, -{ 14, 0x0bee, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0} }, -{ 3, 0x0bfc, 0, {0x02,0x80,0x2e} }, -{ 3, 0x0bff, 0, {0xba,0x15,0x1d} }, -{ 12, 0x0c02, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76} }, -{ 14, 0x0c0e, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0} }, -{ 3, 0x0c1c, 0, {0x02,0x80,0x0e} }, -{ 3, 0x0c1f, 0, {0xba,0x16,0x0b} }, -{ 11, 0x0c22, 0, {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04} }, -{ 11, 0x0c2d, 0, {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a} }, -{ 1, 0x0c38, 0, {0x22} }, -{ 7, 0x0c39, 0, {0x53,0x55,0x50,0x45,0x4e,0x44,0x00} }, -{ 7, 0x0c40, 0, {0x52,0x45,0x53,0x55,0x4d,0x45,0x00} }, -{ 6, 0x0c47, 0, {0x20,0x56,0x6f,0x6c,0x20,0x00} }, -{ 13, 0x0c4d, 0, {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00} }, -{ 14, 0x0c5a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} }, -{ 14, 0x0c68, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} }, -{ 13, 0x0c76, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} }, -{ 14, 0x0c83, 0, {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0} }, -{ 6, 0x0c91, 0, {0xfb,0xbb,0x00,0x02,0x80,0x03} }, -{ 3, 0x0c97, 0, {0x02,0x0d,0x38} }, -{ 3, 0x0c9a, 0, {0xba,0x80,0x14} }, -{ 14, 0x0c9d, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5} }, -{ 6, 0x0cab, 0, {0x74,0x02,0xf0,0x02,0x0e,0xcd} }, -{ 5, 0x0cb1, 0, {0xba,0x82,0x02,0x80,0x03} }, -{ 3, 0x0cb6, 0, {0x02,0x0d,0x1d} }, -{ 8, 0x0cb9, 0, {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00} }, -{ 2, 0x0cc1, 0, {0x40,0x21} }, -{ 6, 0x0cc3, 0, {0xc3,0x74,0x07,0x9c,0x40,0x1b} }, -{ 14, 0x0cc9, 0, {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} }, -{ 13, 0x0cd7, 0, {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b} }, -{ 3, 0x0ce4, 0, {0xbc,0x81,0x00} }, -{ 2, 0x0ce7, 0, {0x40,0x21} }, -{ 6, 0x0ce9, 0, {0xc3,0x74,0x87,0x9c,0x40,0x1b} }, -{ 14, 0x0cef, 0, {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} }, -{ 13, 0x0cfd, 0, {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05} }, -{ 5, 0x0d0a, 0, {0x90,0x7f,0x00,0xe4,0xf0} }, -{ 14, 0x0d0f, 0, {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd} }, -{ 5, 0x0d1d, 0, {0xba,0x81,0x02,0x80,0x03} }, -{ 3, 0x0d22, 0, {0x02,0x0e,0xc5} }, -{ 14, 0x0d25, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74} }, -{ 5, 0x0d33, 0, {0x02,0xf0,0x02,0x0e,0xcd} }, -{ 3, 0x0d38, 0, {0xbb,0x01,0x2d} }, -{ 6, 0x0d3b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} }, -{ 3, 0x0d41, 0, {0xba,0x02,0x11} }, -{ 13, 0x0d44, 0, {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} }, -{ 4, 0x0d51, 0, {0x02,0x02,0x0e,0xcd} }, -{ 5, 0x0d55, 0, {0xba,0x21,0x02,0x80,0x03} }, -{ 3, 0x0d5a, 0, {0x02,0x0e,0xcd} }, -{ 11, 0x0d5d, 0, {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd} }, -{ 3, 0x0d68, 0, {0xbb,0x03,0x1f} }, -{ 6, 0x0d6b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} }, -{ 5, 0x0d71, 0, {0xba,0x02,0x02,0x80,0x03} }, -{ 3, 0x0d76, 0, {0x02,0x0e,0xcd} }, -{ 13, 0x0d79, 0, {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} }, -{ 4, 0x0d86, 0, {0x02,0x02,0x0e,0xcd} }, -{ 3, 0x0d8a, 0, {0xbb,0x06,0x54} }, -{ 5, 0x0d8d, 0, {0xba,0x80,0x02,0x80,0x03} }, -{ 3, 0x0d92, 0, {0x02,0x0e,0xc5} }, -{ 8, 0x0d95, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15} }, -{ 12, 0x0d9d, 0, {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} }, -{ 9, 0x0da9, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} }, -{ 10, 0x0db2, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03} }, -{ 3, 0x0dbc, 0, {0x02,0x0e,0xc5} }, -{ 10, 0x0dbf, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03} }, -{ 3, 0x0dc9, 0, {0x02,0x0e,0xc5} }, -{ 12, 0x0dcc, 0, {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} }, -{ 9, 0x0dd8, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} }, -{ 6, 0x0de1, 0, {0xbb,0x07,0x03,0x02,0x0e,0xc5} }, -{ 3, 0x0de7, 0, {0xbb,0x08,0x10} }, -{ 13, 0x0dea, 0, {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} }, -{ 3, 0x0df7, 0, {0x02,0x0e,0xcd} }, -{ 3, 0x0dfa, 0, {0xbb,0x09,0x31} }, -{ 5, 0x0dfd, 0, {0xba,0x00,0x02,0x80,0x03} }, -{ 3, 0x0e02, 0, {0x02,0x0e,0xc5} }, -{ 14, 0x0e05, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5} }, -{ 8, 0x0e13, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a} }, -{ 10, 0x0e1b, 0, {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0} }, -{ 9, 0x0e25, 0, {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd} }, -{ 3, 0x0e2e, 0, {0xbb,0x0a,0x27} }, -{ 5, 0x0e31, 0, {0xba,0x81,0x02,0x80,0x03} }, -{ 3, 0x0e36, 0, {0x02,0x0e,0xc5} }, -{ 14, 0x0e39, 0, {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82} }, -{ 14, 0x0e47, 0, {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} }, -{ 3, 0x0e55, 0, {0x02,0x0e,0xcd} }, -{ 5, 0x0e58, 0, {0xbb,0x0b,0x02,0x80,0x03} }, -{ 3, 0x0e5d, 0, {0x02,0x0e,0xa9} }, -{ 13, 0x0e60, 0, {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a} }, -{ 8, 0x0e6d, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12} }, -{ 14, 0x0e75, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2} }, -{ 4, 0x0e83, 0, {0xd0,0x03,0x80,0x46} }, -{ 8, 0x0e87, 0, {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e} }, -{ 8, 0x0e8f, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36} }, -{ 13, 0x0e97, 0, {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90} }, -{ 5, 0x0ea4, 0, {0x17,0x22,0xf0,0x80,0x24} }, -{ 5, 0x0ea9, 0, {0xbb,0x12,0x02,0x80,0x17} }, -{ 5, 0x0eae, 0, {0xbb,0x81,0x02,0x80,0x0d} }, -{ 5, 0x0eb3, 0, {0xbb,0x83,0x02,0x80,0x08} }, -{ 5, 0x0eb8, 0, {0xbb,0x82,0x02,0x80,0x03} }, -{ 3, 0x0ebd, 0, {0xbb,0x84,0x05} }, -{ 5, 0x0ec0, 0, {0x12,0x06,0x4e,0x80,0x08} }, -{ 8, 0x0ec5, 0, {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06} }, -{ 6, 0x0ecd, 0, {0x90,0x7f,0xb4,0x74,0x02,0xf0} }, -{ 2, 0x0ed3, 0, {0xd0,0x86} }, -{ 14, 0x0ed5, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} }, -{ 13, 0x0ee3, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} }, -{ 11, 0x0ef0, 0, {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d} }, -{ 7, 0x0efb, 0, {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16} }, -{ 13, 0x0f02, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34} }, -{ 9, 0x0f0f, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22} }, -{ 7, 0x0f18, 0, {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b} }, -{ 7, 0x0f1f, 0, {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14} }, -{ 13, 0x0f26, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34} }, -{ 7, 0x0f33, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0} }, -{ 1, 0x0f3a, 0, {0x22} }, -{ 14, 0x0f3b, 0, {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00} }, -{ 14, 0x0f49, 0, {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c} }, -{ 14, 0x0f57, 0, {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06} }, -{ 14, 0x0f65, 0, {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02} }, -{ 14, 0x0f73, 0, {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00} }, -{ 14, 0x0f81, 0, {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00} }, -{ 14, 0x0f8f, 0, {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07} }, -{ 14, 0x0f9d, 0, {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01} }, -{ 14, 0x0fab, 0, {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25} }, -{ 14, 0x0fb9, 0, {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00} }, -{ 14, 0x0fc7, 0, {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00} }, -{ 14, 0x0fd5, 0, {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40} }, -{ 14, 0x0fe3, 0, {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0} }, -{ 10, 0x0ff1, 0, {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00} }, -{ 14, 0x0ffb, 0, {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01} }, -{ 14, 0x1009, 0, {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba} }, -{ 4, 0x1017, 0, {0x00,0x03,0x01,0x00} }, -{ 2, 0x101b, 0, {0x7a,0x00} }, -{ 3, 0x101d, 0, {0xba,0x05,0x00} }, -{ 2, 0x1020, 0, {0x50,0x17} }, -{ 8, 0x1022, 0, {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05} }, -{ 5, 0x102a, 0, {0x90,0x00,0x01,0x80,0x0d} }, -{ 10, 0x102f, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4} }, -{ 3, 0x1039, 0, {0x90,0x00,0x01} }, -{ 1, 0x103c, 0, {0x22} }, -{ 14, 0x103d, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d} }, -{ 4, 0x104b, 0, {0x7e,0xeb,0x60,0x12} }, -{ 14, 0x104f, 0, {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83} }, -{ 4, 0x105d, 0, {0xf0,0x0c,0xdb,0xee} }, -{ 8, 0x1061, 0, {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0} }, -{ 1, 0x1069, 0, {0x22} }, -{ 14, 0x106a, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d} }, -{ 4, 0x1078, 0, {0x7d,0xeb,0x60,0xe5} }, -{ 14, 0x107c, 0, {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82} }, -{ 4, 0x108a, 0, {0xaa,0x83,0xdb,0xee} }, -{ 1, 0x108e, 0, {0x22} }, -{ 14, 0x108f, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86} }, -{ 14, 0x109d, 0, {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9} }, -{ 5, 0x10ab, 0, {0x60,0x16,0xa3,0x05,0x86} }, -{ 13, 0x10b0, 0, {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12} }, -{ 6, 0x10bd, 0, {0x10,0x1b,0xd0,0x01,0xd9,0xed} }, -{ 6, 0x10c3, 0, {0x90,0x7f,0xa5,0x74,0x40,0xf0} }, -{ 1, 0x10c9, 0, {0x22} }, -{ 8, 0x10ca, 0, {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00} }, -{ 3, 0x10d2, 0, {0xba,0xff,0x00} }, -{ 2, 0x10d5, 0, {0x50,0x0a} }, -{ 10, 0x10d7, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} }, -{ 1, 0x10e1, 0, {0x22} }, -{ 5, 0x10e2, 0, {0xe5,0x6b,0xb4,0xc0,0x08} }, -{ 8, 0x10e7, 0, {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06} }, -{ 6, 0x10ef, 0, {0x90,0x88,0x02,0xe5,0x6c,0xf0} }, -{ 4, 0x10f5, 0, {0x7a,0x00,0x7b,0x00} }, -{ 11, 0x10f9, 0, {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07} }, -{ 5, 0x1104, 0, {0x0a,0xba,0x00,0x01,0x0b} }, -{ 2, 0x1109, 0, {0x80,0xee} }, -{ 1, 0x110b, 0, {0x22} }, -{ 10, 0x110c, 0, {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00} }, -{ 3, 0x1116, 0, {0xba,0x28,0x00} }, -{ 2, 0x1119, 0, {0x50,0x03} }, -{ 3, 0x111b, 0, {0x0a,0x80,0xf8} }, -{ 5, 0x111e, 0, {0xe5,0x39,0xb4,0x10,0x08} }, -{ 8, 0x1123, 0, {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e} }, -{ 5, 0x112b, 0, {0xe5,0x39,0xb4,0x20,0x09} }, -{ 9, 0x1130, 0, {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00} }, -{ 2, 0x1139, 0, {0x7a,0x00} }, -{ 3, 0x113b, 0, {0xba,0x28,0x00} }, -{ 2, 0x113e, 0, {0x50,0x03} }, -{ 3, 0x1140, 0, {0x0a,0x80,0xf8} }, -{ 1, 0x1143, 0, {0x22} }, -{ 4, 0x1144, 0, {0xe5,0x6f,0x60,0x02} }, -{ 2, 0x1148, 0, {0x80,0x07} }, -{ 7, 0x114a, 0, {0x7a,0x00,0x75,0x39,0x00,0x80,0x05} }, -{ 5, 0x1151, 0, {0x7a,0x40,0x75,0x39,0x10} }, -{ 9, 0x1156, 0, {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5} }, -{ 10, 0x115f, 0, {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00} }, -{ 8, 0x1169, 0, {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03} }, -{ 3, 0x1171, 0, {0x0a,0x80,0xf5} }, -{ 1, 0x1174, 0, {0x22} }, -{ 6, 0x1175, 0, {0xaa,0x70,0xab,0x71,0xac,0x72} }, -{ 12, 0x117b, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18} }, -{ 13, 0x1187, 0, {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04} }, -{ 9, 0x1194, 0, {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} }, -{ 2, 0x119d, 0, {0x80,0xdc} }, -{ 1, 0x119f, 0, {0x22} }, -{ 13, 0x11a0, 0, {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a} }, -{ 2, 0x11ad, 0, {0x50,0x06} }, -{ 6, 0x11af, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} }, -{ 4, 0x11b5, 0, {0x74,0x30,0x2a,0xfb} }, -{ 12, 0x11b9, 0, {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53} }, -{ 8, 0x11c5, 0, {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06} }, -{ 6, 0x11cd, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} }, -{ 4, 0x11d3, 0, {0x74,0x30,0x2a,0xfb} }, -{ 5, 0x11d7, 0, {0x8b,0x6d,0x12,0x11,0x0c} }, -{ 1, 0x11dc, 0, {0x22} }, -{ 7, 0x11dd, 0, {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f} }, -{ 12, 0x11e4, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f} }, -{ 3, 0x11f0, 0, {0x12,0x11,0x44} }, -{ 12, 0x11f3, 0, {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75} }, -{ 5, 0x11ff, 0, {0x72,0x01,0x12,0x11,0x75} }, -{ 1, 0x1204, 0, {0x22} }, -{ 2, 0x1205, 0, {0x7a,0x04} }, -{ 3, 0x1207, 0, {0xba,0x40,0x00} }, -{ 2, 0x120a, 0, {0x50,0x36} }, -{ 14, 0x120c, 0, {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00} }, -{ 3, 0x121a, 0, {0xbc,0x08,0x00} }, -{ 2, 0x121d, 0, {0x50,0x20} }, -{ 6, 0x121f, 0, {0x8b,0x05,0xed,0x30,0xe7,0x0b} }, -{ 11, 0x1225, 0, {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08} }, -{ 8, 0x1230, 0, {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0} }, -{ 7, 0x1238, 0, {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb} }, -{ 3, 0x123f, 0, {0x0a,0x80,0xc5} }, -{ 1, 0x1242, 0, {0x22} }, -{ 4, 0x1243, 0, {0x7a,0x00,0x7b,0xef} }, -{ 3, 0x1247, 0, {0xba,0x10,0x00} }, -{ 2, 0x124a, 0, {0x50,0x20} }, -{ 14, 0x124c, 0, {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d} }, -{ 14, 0x125a, 0, {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4} }, -{ 4, 0x1268, 0, {0xf0,0x0a,0x80,0xdb} }, -{ 1, 0x126c, 0, {0x22} }, -{ 14, 0x126d, 0, {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, -{ 14, 0x127b, 0, {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, -{ 14, 0x1289, 0, {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, -{ 14, 0x1297, 0, {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, -{ 14, 0x12a5, 0, {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} }, -{ 1, 0x12b3, 0, {0x22} }, -{ 14, 0x12b4, 0, {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01} }, -{ 14, 0x12c2, 0, {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74} }, -{ 14, 0x12d0, 0, {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e} }, -{ 14, 0x12de, 0, {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b} }, -{ 14, 0x12ec, 0, {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74} }, -{ 14, 0x12fa, 0, {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0} }, -{ 14, 0x1308, 0, {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07} }, -{ 14, 0x1316, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d} }, -{ 14, 0x1324, 0, {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01} }, -{ 14, 0x1332, 0, {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83} }, -{ 14, 0x1340, 0, {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f} }, -{ 14, 0x134e, 0, {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00} }, -{ 3, 0x135c, 0, {0xbd,0x06,0x00} }, -{ 2, 0x135f, 0, {0x50,0x12} }, -{ 11, 0x1361, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b} }, -{ 7, 0x136c, 0, {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9} }, -{ 13, 0x1373, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9} }, -{ 14, 0x1380, 0, {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74} }, -{ 14, 0x138e, 0, {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0} }, -{ 6, 0x139c, 0, {0x12,0x03,0xe1,0x12,0x04,0xf7} }, -{ 1, 0x13a2, 0, {0x22} }, -{ 13, 0x13a3, 0, {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90} }, -{ 14, 0x13b0, 0, {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4} }, -{ 3, 0x13be, 0, {0xfa,0x7b,0x00} }, -{ 3, 0x13c1, 0, {0xbb,0x10,0x00} }, -{ 2, 0x13c4, 0, {0x50,0x24} }, -{ 14, 0x13c6, 0, {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd} }, -{ 14, 0x13d4, 0, {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe} }, -{ 8, 0x13e2, 0, {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7} }, -{ 14, 0x13ea, 0, {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4} }, -{ 5, 0x13f8, 0, {0x3b,0xf5,0x83,0xe4,0xf0} }, -{ 1, 0x13fd, 0, {0x22} }, -{ 4, 0x13fe, 0, {0xe5,0x76,0x60,0x02} }, -{ 2, 0x1402, 0, {0x80,0x16} }, -{ 12, 0x1404, 0, {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4} }, -{ 10, 0x1410, 0, {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4} }, -{ 10, 0x141a, 0, {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12} }, -{ 6, 0x1424, 0, {0x11,0x44,0x75,0x70,0xb9,0x75} }, -{ 6, 0x142a, 0, {0x71,0x14,0x75,0x72,0x02,0x12} }, -{ 11, 0x1430, 0, {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01} }, -{ 1, 0x143b, 0, {0xe4} }, -{ 3, 0x143c, 0, {0xfa,0x70,0x0f} }, -{ 12, 0x143f, 0, {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0} }, -{ 3, 0x144b, 0, {0x02,0x80,0x0a} }, -{ 10, 0x144e, 0, {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02} }, -{ 12, 0x1458, 0, {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0} }, -{ 4, 0x1464, 0, {0x02,0xea,0x70,0x1a} }, -{ 13, 0x1468, 0, {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18} }, -{ 9, 0x1475, 0, {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12} }, -{ 4, 0x147e, 0, {0x11,0x75,0x80,0x36} }, -{ 2, 0x1482, 0, {0x7a,0x00} }, -{ 3, 0x1484, 0, {0xba,0x10,0x00} }, -{ 2, 0x1487, 0, {0x50,0x2f} }, -{ 13, 0x1489, 0, {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5} }, -{ 4, 0x1496, 0, {0x75,0xb5,0x03,0x1b} }, -{ 14, 0x149a, 0, {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b} }, -{ 9, 0x14a8, 0, {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12} }, -{ 4, 0x14b1, 0, {0x11,0x75,0xd0,0x02} }, -{ 3, 0x14b5, 0, {0x0a,0x80,0xcc} }, -{ 1, 0x14b8, 0, {0x22} }, -{ 6, 0x14b9, 0, {0x50,0x72,0x6f,0x67,0x20,0x00} }, -{ 14, 0x14bf, 0, {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14} }, -{ 7, 0x14cd, 0, {0x60,0x11,0x14,0x60,0x12,0x80,0x15} }, -{ 7, 0x14d4, 0, {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e} }, -{ 5, 0x14db, 0, {0xd0,0xe0,0xf0,0x80,0x09} }, -{ 4, 0x14e0, 0, {0xd0,0xe0,0x80,0x05} }, -{ 5, 0x14e4, 0, {0xd0,0xe0,0xa8,0x82,0xf2} }, -{ 4, 0x14e9, 0, {0xc8,0xd0,0xe0,0xc8} }, -{ 1, 0x14ed, 0, {0x22} }, -{ 14, 0x14ee, 0, {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14} }, -{ 6, 0x14fc, 0, {0x60,0x10,0x74,0xff,0x80,0x0f} }, -{ 5, 0x1502, 0, {0xa8,0x82,0xe6,0x80,0x0a} }, -{ 3, 0x1507, 0, {0xe0,0x80,0x07} }, -{ 4, 0x150a, 0, {0xe4,0x93,0x80,0x03} }, -{ 3, 0x150e, 0, {0xa8,0x82,0xe2} }, -{ 4, 0x1511, 0, {0xf8,0xd0,0xe0,0xc8} }, -{ 1, 0x1515, 0, {0x22} }, -{ 0, 0x0000, 1, {0} } - -}; - -static unsigned char bitstream[] = { - -0x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0, 0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D, -0x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72, 0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B, -0x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31, 0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39, -0x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34, 0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34, -0x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00, 0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B, -0xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF, 0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F, -0xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF, -0xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF, 0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF, 0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF, -0xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9, 0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE, -0xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF, 0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF, -0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF, 0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF, -0x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD, 0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1, -0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, -0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF, -0xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF, 0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD, -0xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, 0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F, -0x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF, -0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7, 0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D, -0xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF, 0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE, -0xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB, 0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, -0xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB, 0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F, -0xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF, 0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F, -0xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF, -0xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF, 0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F, -0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD, 0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F, -0xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF, 0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F, -0x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2, -0xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF, 0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF, 0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65, 0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF, -0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF, -0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF, 0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE, -0xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF, 0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF, -0xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF, 0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF, -0xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B, -0xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D, 0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF, -0x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D, 0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED, 0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7, -0xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F, 0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF, -0xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF, -0xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F, 0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5, -0xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD, -0xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7, 0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF, -0xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF, 0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF, -0xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE, 0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B, -0xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF, 0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF, -0xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF, 0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED, -0xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF, 0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF, -0xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD, 0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB, -0xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE, 0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF, -0xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE, 0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1, 0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE, -0xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB, 0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7, -0xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF, 0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE, -0xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE, 0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF, -0xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE, 0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD, -0xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF, 0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD, -0xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7, 0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF, -0x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF, 0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD, -0x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8, 0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A, -0xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F, 0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF, -0xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF, -0xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF, 0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA, -0xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF, -0xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE, 0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD, -0xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF, 0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF, -0xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF, 0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF, -0xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF, 0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E, -0xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F, 0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF, -0xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF, 0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF, -0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF, 0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF, -0x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF, -0xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB, 0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3, -0x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E, 0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF, -0xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF, 0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F, -0xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF, 0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF, -0xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB, 0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF, -0xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7, -0xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF, -0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF, -0xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD, -0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED, 0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD, -0x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4, 0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE, -0xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF, 0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF, 0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF, -0xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF, 0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF, -0xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE, 0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3, -0x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD, 0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A, -0xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD, 0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6, -0xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A, 0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF, -0x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7, 0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB, -0x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C, 0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF, -0xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA, 0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD, -0xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE, 0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6, -0xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB, 0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF, -0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF, 0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB, -0xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF, 0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F, -0xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F, 0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF, -0xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F, -0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF, 0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF, -0x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB, 0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED, -0xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE, 0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF, -0xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7, -0xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35, 0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7, -0xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B, 0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF, -0x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9, 0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F, -0x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD, 0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE, -0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB, 0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF, -0xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6, 0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF, -0xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA, 0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA, -0xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF, 0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F, -0x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC, 0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA, -0xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B, 0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB, -0xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7, 0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF, -0xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB, 0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB, -0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF, 0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF, -0xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF, 0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF, -0xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF, 0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD, -0x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF, 0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF, -0xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF, -0xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB, 0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C, -0xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF, -0xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF, -0xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB, 0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD, -0xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF, 0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF, -0xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3, -0x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F, 0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB, -0xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF, 0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F, -0xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3, 0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3, -0xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE, 0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF, -0xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD, 0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7, -0x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F, 0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7, -0xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE, 0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF, -0xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC, 0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE, -0xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF, 0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF, -0xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2, 0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB, -0x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF, 0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66, -0xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF, 0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE, -0xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD, 0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6, -0x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF, 0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED, -0xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA, 0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD, -0xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F, 0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7, -0xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE, 0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF, -0xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7, 0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB, -0xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF, 0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF, -0x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA, 0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F, -0xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD, 0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7, -0xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE, 0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9, -0xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F, 0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF, -0xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97, 0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF, -0xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF, 0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE, -0xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF, 0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF, -0xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F, 0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF, -0x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD, 0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF, -0xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7, 0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF, -0xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F, 0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD, -0xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF, 0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1, -0xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7, 0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF, -0xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC, 0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5, -0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF, 0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF, -0xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB, 0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB, -0xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD, 0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF, -0xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F, 0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF, -0xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE, 0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3, -0xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5, 0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE, -0xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9, 0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD, -0xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE, -0xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7, 0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF, -0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF, -0x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF, 0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB, -0xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5, 0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF, -0xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE, 0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF, -0x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF, 0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF, -0xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF, 0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F, -0xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF, 0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C, -0x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF, 0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD, -0xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9, 0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF, -0xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF, 0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F, -0x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF, 0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE, -0xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB, 0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD, -0x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F, 0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54, -0xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE, 0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2, -0xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7, 0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD, -0xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE, 0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF, -0xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE, 0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF, -0xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF, 0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7, -0xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF, 0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA, -0xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF, 0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF, -0xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF, 0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C, -0xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE, 0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF, -0xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF, 0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5, -0xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB, 0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB, -0xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD, 0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF, -0xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD, 0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF, -0xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7, 0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F, -0xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC, 0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F, -0xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F, 0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF, -0xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD, 0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF, -0xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD, 0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF, -0xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5, -0xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF, 0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF, -0x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF, 0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF, -0xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE, 0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A, -0xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF, 0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36, -0xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD, 0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF, -0xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F, -0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD, 0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB, 0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F, -0xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF, 0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF, -0xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF, 0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF, -0xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF, 0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF, -0xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F, 0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF, -0x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B, 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE, -0x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF, 0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF, -0xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E, 0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF, -0xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB, 0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F, -0xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD, 0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B, -0xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7, 0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF, -0xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF, 0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE, -0x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF, 0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB, -0xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF, 0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF, -0xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F, 0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF, -0x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE, 0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA, -0xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37, -0xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6, 0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD, -0x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF, 0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B, -0xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF, 0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF, -0xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF, 0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B, -0xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E, 0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B, -0xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF, 0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF, -0xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF, 0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF, -0xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF, 0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD, -0xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB, 0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF, -0xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD, 0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE, -0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB, 0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF, -0xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF, 0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF, -0x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF, 0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA, -0xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF, 0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E, -0x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF, 0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF, -0xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5, 0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF, -0x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F, 0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6, -0x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1, 0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD, -0x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE, 0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB, -0xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF, 0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF, -0xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD, 0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F, -0xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F, 0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F, -0xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF, 0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7, -0xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB, 0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, -0x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A, 0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB, -0xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE, 0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD, -0x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E, -0xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF, -0xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA, 0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE, -0xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF, 0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF, -0xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB, 0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF, -0xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE, 0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE, -0xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF, 0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2, -0xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF, 0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, -0xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9, 0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF, -0xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF, 0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF, -0xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE, 0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF, -0xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD, 0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC, -0xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F, 0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF, -0xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7, -0xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3, 0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7, -0xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE, 0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3, -0xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF, 0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9, -0xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF, 0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF, -0xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD, 0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, -0xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6, -0xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A, 0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F, -0xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7, 0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B, -0xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF, 0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE, -0x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF, 0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79, -0xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF, 0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F, -0xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E, 0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7, -0xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB, 0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC, -0x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7, 0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, -0xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7, 0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7, -0xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D, 0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF, -0xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF, 0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF, -0xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD, 0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7, -0xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF, 0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F, -0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE, 0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE, -0xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF, -0xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE, 0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F, -0xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9, 0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7, -0xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F, 0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7, -0xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF, 0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF, -0xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF, -0xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF, 0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF, 0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD, -0xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF, -0xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF, 0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB, -0xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F, 0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE, -0xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7, 0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3, -0x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F, 0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF, -0xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE, 0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF, -0xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE, -0xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF, 0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6, -0xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5, 0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF, -0xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE, 0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE, 0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF, -0xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF, 0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F, -0x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF, 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE, -0xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF, 0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, 0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6, -0xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF, 0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77, -0xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF, 0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF, -0x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5, 0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A, -0xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF, 0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F, -0xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F, -0xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB, 0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF, -0xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB, -0xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF, 0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F, -0xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A, 0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67, -0xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47, 0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF, -0xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76, 0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D, -0x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE, 0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3, -0xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7, 0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D, -0xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD, 0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB, -0xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC, 0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE, -0xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5, -0xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7, 0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA, 0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D, -0x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3, 0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F, -0xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB, -0xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE, 0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB, -0xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF, 0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9, -0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9, 0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF, -0xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF, -0xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF, 0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF, -0xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B, 0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77, -0x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF, 0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F, -0xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE, -0xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF, -0x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD, 0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF, -0xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD, -0xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7, 0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F, -0xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA, 0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A, -0xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF, 0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA, -0xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF, 0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF, -0xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF, 0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF, -0xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF, -0xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF, 0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07, 0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF, -0xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6, 0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF, -0xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7, 0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF, 0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9, -0x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F, -0x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5, 0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7, -0xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F, 0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4, -0xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF, 0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE, -0xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF, 0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9, -0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF, 0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF, -0xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF, 0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7, -0xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF, 0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF, -0xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D, 0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF, 0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF, -0xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7, 0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2, 0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF, -0x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7, 0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5, -0x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF, -0xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF, 0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD, -0xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B, 0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77, -0x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3, 0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE, -0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF, -0xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED, 0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF, -0xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF, 0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC, -0x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7, 0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB, -0x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, 0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F, -0xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F, 0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6, -0xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77, 0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD, -0x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF, 0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB, 0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF, -0xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB, 0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC, -0xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F, -0xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF, 0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF, 0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E, -0xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB, 0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F, -0xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F, 0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB, -0x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF, 0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF, -0x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7, -0xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F, -0xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F, 0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2, -0xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE, 0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA, -0xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA, 0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF, -0xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF, 0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8, -0xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3, 0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB, -0xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F, 0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF, -0xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF, 0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB, -0xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE, 0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF, -0xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD, 0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF, -0xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF, 0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7, -0xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE, 0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3, -0xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4, 0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F, -0xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF, 0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD, -0x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF, 0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF, -0xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF, 0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, -0xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB, 0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF, -0xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF, 0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF, -0xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF, 0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F, -0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D, 0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF, -0xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F, -0xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF, 0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE, 0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C, 0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF, -0xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF, 0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7, -0xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F, 0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9, -0xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B, 0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71, -0xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F, 0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF, -0xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF, -0xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF, 0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F, -0xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA, 0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7, -0xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF, 0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF, 0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC, -0xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE, -0xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65, 0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7, -0x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF, -0xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F, 0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB, -0xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE, 0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B, -0xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, -0xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2, 0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD, 0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF, -0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE, -0x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17, -0xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C, 0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9, -0xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF, 0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F, -0xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE, -0xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF, 0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD, -0xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD, 0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F, -0xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE, 0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF, -0xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF, 0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF, -0xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8, 0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F, -0xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF, 0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF, -0xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F, 0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5, -0xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA, -0x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3, 0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE, -0x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9, 0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF, -0xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF, 0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA, -0xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF, 0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3, -0xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF, 0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF, -0xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF, 0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7, -0xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB, 0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF, 0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, -0xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF, -0x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF, 0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB, -0xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE, 0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE, -0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F, 0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF, 0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9, -0x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF, 0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF, -0xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD, 0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD, -0xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF, 0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE, -0x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7, 0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE, -0xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3, 0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB, -0xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F, 0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB, -0xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7, 0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB, -0x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF, 0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF, -0xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B, 0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF, -0xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF, 0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77, -0xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF, 0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE, -0xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6, 0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8, -0xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF, 0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E, -0xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E, 0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3, -0xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF, 0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF, -0xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF, 0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7, -0xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB, -0xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7, 0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF, -0x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73, 0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF, -0xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF, 0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF, -0xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF, 0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3, -0xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B, 0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F, -0xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F, 0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F, -0x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF, 0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF, -0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, -0xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF, -0x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7, 0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF, -0xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F, 0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD, -0xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF, 0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE, -0xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA, 0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1, -0xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF, 0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF, -0x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF, 0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC, -0xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF, -0xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF, 0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB, -0xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF, 0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9, -0xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D, 0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E, -0xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB, 0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF, -0xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB, 0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF, -0x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF, 0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, -0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF, -0x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5, 0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7, -0xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8, 0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF, -0xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF, 0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F, -0x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F, 0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF, -0xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF, 0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF, -0xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF, 0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF, -0xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3, -0xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB, 0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC, -0x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6, 0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF, -0xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE, 0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF, -0xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF, 0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF, -0xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F, 0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF, -0xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77, 0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF, -0xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, 0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA, -0xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59, 0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF, -0xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF, -0xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9, 0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF, -0xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF, -0xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F, 0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB, -0x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF, 0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F, -0xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF, 0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF, -0xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF, 0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD, -0xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD, -0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76, 0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE, -0xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F, 0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF, -0x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F, 0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5, -0xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7, 0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F, -0x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF, -0xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE, -0xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB, -0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF, -0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF, 0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF, -0xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE, 0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF, -0x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF, 0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF, -0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF, 0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB, -0xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25, 0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7, -0xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB, 0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF, -0xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F, 0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F, -0xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7, -0x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE, 0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF, -0xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF, 0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB, -0xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF, 0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF, -0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF, 0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF, -0xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF, 0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF, -0xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF, 0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB, -0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF, -0xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD, 0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF, -0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3, 0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF, -0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE, -0xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF, 0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF, 0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, -0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE, -0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF, 0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4, -0x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC, -0x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5, 0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7, 0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF, 0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF, -0xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF, 0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7, -0xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65, -0x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6, 0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF, -0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF, 0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3, -0xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF, 0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF, -0xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF, 0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF, -0xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F, 0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB, -0xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC, 0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF, -0xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE, 0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B, -0x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF, 0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF, -0xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F, 0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF, -0xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, 0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF, -0xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF, 0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7, -0xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF, 0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF, -0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF, 0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9, -0xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2, 0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF, -0xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7, 0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF, -0xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF, -0xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4, 0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, -0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A, -0xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7, -0xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF, 0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF, -0x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF, 0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD, -0xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE, 0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC, -0xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF, 0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA, -0x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF, 0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D, -0xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB, 0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE, 0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF, -0xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF, 0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6, -0xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7, 0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF, -0x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF, 0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF, -0xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF, -0xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF, -0xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF, 0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF, -0xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB, -0xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D, 0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E, -0xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F, 0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF, -0xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF, -0xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD, 0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF, -0xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF, -0xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF, 0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16, -0xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3, 0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF, -0xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E, 0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7, -0x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF, 0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9, -0x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB, 0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF, -0xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB, 0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F, -0xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D, 0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A, -0x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76, 0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE, -0xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB, -0x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB, -0xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE, 0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3, -0xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF, 0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF, -0xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D, 0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE, -0xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB, 0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB, -0x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF, 0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF, -0x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF, 0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE, -0xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF, 0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5, -0xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF, -0xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF, 0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, -0xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F, 0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD, -0x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF, 0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F, -0xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F, 0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7, -0xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F, 0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF, -0xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF, 0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA, -0xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F, 0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD, -0xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F, -0xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC, 0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF, 0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA, -0xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB, 0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33, -0xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9, -0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF, 0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF, -0xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF, 0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77, -0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF, -0x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F, -0xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF, 0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF, -0xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF, 0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF, -0xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE, 0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7, -0xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF, -0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6, 0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF, -0xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF, 0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB, -0xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF, 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF, -0xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF, 0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD, -0x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF, 0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE, -0x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF, 0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F, 0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF, -0xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF, 0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F, -0xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F, 0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B, -0xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38, 0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9, -0xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF, 0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF, -0xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB, 0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD, -0xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF, -0xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5, 0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF, -0xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F, 0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7, 0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB, -0xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD, 0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF, -0xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6, 0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF, -0xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE, 0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF, -0x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF, 0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9, -0xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7, 0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF, -0xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F, 0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD, -0xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF, 0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF, 0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE, -0xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF, -0xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F, 0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF, -0xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB, 0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE, -0xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF, 0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE, -0xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA, 0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE, -0x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF, -0xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD, 0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF, -0xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB, 0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF, -0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF, -0x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF, -0xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F, 0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF, -0xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF, 0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA, 0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD, -0x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF, 0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF, -0xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC, 0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F, -0xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF, 0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF, -0xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF, -0xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF, 0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE, -0xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD, 0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB, -0xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF, 0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF, -0xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF, 0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF, -0xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07, 0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5, -0x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF, 0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF, -0xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF, -0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE, -0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF, 0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB, -0xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF, 0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7, -0xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F, 0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF, -0xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB, 0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE, -0xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB, -0xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD, 0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF, -0xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF, -0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F, 0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB, -0xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3, 0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF, -0xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF, 0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7, -0xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE, 0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F, -0x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E, 0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF, -0xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF, -0xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F, -0xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF, 0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD, -0x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF, -0x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF, 0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF, -0xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF, -0xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7, -0xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD, -0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2, -0x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8, 0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC, -0xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC, -0xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF, 0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF, -0xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF, -0xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB, 0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB, -0xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB, 0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD, -0xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC, 0xEF,0xFF - -}; diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index 8d1f8ee..48f4b92 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c @@ -38,9 +38,10 @@ #include #include #include +#include +#include #include "dabusb.h" -#include "dabfirmware.h" /* * Version Information @@ -297,7 +298,8 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) return ret; } /* --------------------------------------------------------------------- */ -static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len) +static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data, + int len) { int ret; unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL); @@ -324,24 +326,35 @@ static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit) static int dabusb_loadmem (pdabusb_t s, const char *fname) { int ret; - PINTEL_HEX_RECORD ptr = firmware; + const struct ihex_binrec *rec; + const struct firmware *fw; dbg("Enter dabusb_loadmem (internal)"); + ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev); + if (ret) { + err("Failed to load \"dabusb/firmware.fw\": %d\n", ret); + goto out; + } ret = dabusb_8051_reset (s, 1); - while (ptr->Type == 0) { - dbg("dabusb_writemem: %04X %p %d)", ptr->Address, ptr->Data, ptr->Length); + for (rec = (const struct ihex_binrec *)fw->data; rec; + rec = ihex_next_binrec(rec)) { + dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr), + rec->data, be16_to_cpu(rec->len)); - ret = dabusb_writemem (s, ptr->Address, ptr->Data, ptr->Length); + ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data, + be16_to_cpu(rec->len)); if (ret < 0) { - err("dabusb_writemem failed (%d %04X %p %d)", ret, ptr->Address, ptr->Data, ptr->Length); + err("dabusb_writemem failed (%d %04X %p %d)", ret, + be32_to_cpu(rec->addr), rec->data, + be16_to_cpu(rec->len)); break; } - ptr++; } ret = dabusb_8051_reset (s, 0); - + release_firmware(fw); + out: dbg("dabusb_loadmem: exit"); return ret; @@ -376,9 +389,9 @@ static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b) static int dabusb_fpga_download (pdabusb_t s, const char *fname) { pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL); + const struct firmware *fw; unsigned int blen, n; int ret; - unsigned char *buf = bitstream; dbg("Enter dabusb_fpga_download (internal)"); @@ -387,10 +400,16 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) return -ENOMEM; } + ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev); + if (ret) { + err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret); + return ret; + } + b->pipe = 1; ret = dabusb_fpga_clear (s, b); mdelay (10); - blen = buf[73] + (buf[72] << 8); + blen = fw->data[73] + (fw->data[72] << 8); dbg("Bitstream len: %i", blen); @@ -402,7 +421,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) for (n = 0; n <= blen + 60; n += 60) { // some cclks for startup b->size = 64; - memcpy (b->data + 4, buf + 74 + n, 60); + memcpy (b->data + 4, fw->data + 74 + n, 60); ret = dabusb_bulk (s, b); if (ret < 0) { err("dabusb_bulk failed."); @@ -413,6 +432,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) ret = dabusb_fpga_init (s, b); kfree (b); + release_firmware(fw); dbg("exit dabusb_fpga_download"); diff --git a/firmware/Makefile b/firmware/Makefile index 8d5465f..331d10c 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -29,6 +29,9 @@ fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ yamaha/ds1e_ctrl.fw +fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \ + tigon/tg3_tso5.bin +fw-shipped-$(CONFIG_USB_DABUSB) += dabusb/firmware.fw dabusb/bitstream.bin fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ emi26/bitstream.fw fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \ diff --git a/firmware/WHENCE b/firmware/WHENCE index d8f6199..8784565 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -249,3 +249,19 @@ Licence: Allegedly GPLv2+, but no source visible. Marked: Found in hex form in kernel source. -------------------------------------------------------------------------- + +Driver: DABUSB -- Digital Audio Broadcasting (DAB) Receiver for USB and Linux + +File: dabusb/firmware.fw +File: dabusb/bitstream.bin + +Licence: Distributable + + * Copyright (C) 1999 BayCom GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that redistributions of source + * code retain the above copyright notice and this comment without + * modification. + +-------------------------------------------------------------------------- diff --git a/firmware/dabusb/bitstream.bin.ihex b/firmware/dabusb/bitstream.bin.ihex new file mode 100644 index 0000000..5021a4b --- /dev/null +++ b/firmware/dabusb/bitstream.bin.ihex @@ -0,0 +1,761 @@ +:1000000000090FF00FF00FF00FF000000161000D7C +:1000100064616275736274722E6E63640062000BB9 +:10002000733130786C76713130300063000B3139C8 +:1000300039392F30392F32340064000931303A34E5 +:10004000323A3436006500002EC0FF20175F9F5BF8 +:10005000FEFBBBB7BBBBFBBFAFEFFBDFB7FBFB7F61 +:10006000BFB7EFF2FFFBFEFFFFEFFFFEFFBFFFFF9B +:10007000FFFFAFFFFAFFFFFFC9FFFFFFDFFFFFFF3B +:10008000FFFFFFFFFFFFFFFFFFFFFFFBFFA3FFFBE4 +:10009000FEFFBFEFE3FEFFBFE3FEFFBF6FFBF6FF18 +:1000A000BFFF47FFFF9FEEF9FECF9FEFFBCF9BEE19 +:1000B000F8FEEF8FEEFBFE0BFFFFFFFFFFFFFFFFE2 +:1000C000FFFFBFFFFFFBFFFFBFFFFFFC17FFFFFFAF +:1000D000FFFFFF7FFFFFFF7FFFFFFBFFFF7FFFFFB4 +:1000E000FC3FFFFFFFFFFFFFFFFFFFFBFFFFFFFFE7 +:1000F000FFFFFFFFFFFE5FFFFFFDFFFFDBFFFDFFD9 +:1001000077FFFDFFFFDFFEFDFFFFF2FFFFFFFFFFB9 +:10011000FFFDFFFFFFFDFFFFFFFFFFFFFFFFFFE111 +:100120007FFFFFFFFFFFFFFFFFFFFFFFFF3FFFFF1F +:10013000FFFFFFFFE3FFFFFFFFFFFFFFFFFFFFBF2B +:10014000FFFEFFFFFFFFFFFFFF67FFFFFFFFFFFF58 +:100150007FFFFFFF7FFFFFFFFFFFDFFFFFFF2FFF9F +:10016000F3FDFF7FDEF7FDFF7FF77DFF7FDFF7BD4C +:10017000FF7FFF1FFFEFFBFEFFBFEFFBFEFFEFFB6D +:10018000FEFFBFEFFBFEFFFF3FFE7F9FE7F9FE7F15 +:100190009FE7FA7F9FE7F9FE7F9FE7FFFC7FBFBFE6 +:1001A000EFFBFEFFBFEFFBB7BFEFFBFEFFBFEFFBB9 +:1001B000FFE0FDF9FE7F9FE7F9FE7F9DF9FE7D9D43 +:1001C000E7F9FE7F9FEDEDFFFDFF7FDFF7FDFF7F8E +:1001D000DFFDFF7FDFF7FDFF7FDFFF9BFFEFFBFE14 +:1001E000FBBFEFBBFEFFAFBBBEFFBFEFFBFEFFFFE2 +:1001F000B7BFDBF6BDBF6BDBF6F9BF5BD6F9BF6FF0 +:10020000DBF6FDBFFF0EFFFFFFFF5FFFF7FFFF7F86 +:10021000F7BDFFFFFFFFFFFFFFDF9FFFFFFFFEFFB9 +:10022000FFEFFEFEFFFF77FFFBFBFFFFFFFFF83F47 +:10023000FFFDFFFFFFFDFFFFFFFFFFFFFFFFFFFFD2 +:10024000FFFFFFF47FFFFEFDBEFFDFFEFFFFEF7F3E +:10025000FFCFFFCFFFFFFFDFE6FFFF7FDFF7DD7F91 +:100260007FDFF7FF7FDFD7FDFF7FDFF7FFCDFFF2F7 +:10027000FFFF4F7FF4FFFFFFE7EFFFFFFFFFFFFFF1 +:10028000FFFFBBFFEFFFFEFFFFFFEFFFFFEFFFFBF7 +:10029000FFFFFFFFFFFFFF65EFFFFF7FFFFDEFFFAA +:1002A000FFFFFEFFFFFFFFFFFFFFFFFECFDFFEFFB1 +:1002B000FFFBFFFFFFFFF3FFFFFFFFFFFFFFFFFF5E +:1002C000FEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F +:1002D000FFFFFFFFFFFEBFFFFFFFE37FFFFFFFFF0B +:1002E000FFFFEFEBFFFEBFFFEBFFFC7FFFFFFFEE2B +:1002F000FFFFFFFFFFFFDDFFD6FFFDBFFFFBFFFEA0 +:10030000FDFFFFFDEFFFFFFFFFFFFFDEFFFFFFFF32 +:10031000FFFFBFFFFDFF7FBFFF5FDFFFFFBF77FF77 +:10032000FFFF7FD7FFFFFFFFFFC3FFFFFFFFDFEFF1 +:10033000FFFFFEFBFFFFDFBFFFFFFFFFEDFFB7FF8C +:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:10035000FFFFFFAF7FFFFFFFFFFFFFFFFFFFFFFF7D +:10036000FFFFFFFFFFFFFFFFDFBFDFF3FDFBFF5BD3 +:10037000FDFFBFEFF7FFFF7DFFFFFFFFF83BFFBF74 +:100380006FFFFEFFBFFFEB7DFFEFFBFEFFFFFFFFF9 +:10039000FFF27FFCFF3FDFEDFEFFFFFFFFEF5FF7A8 +:1003A000B5FFEFFFFFFFE03F9F9EFFFFEFFFDFFF87 +:1003B000BF5FBFCFF3FFFFFFFFFFFF69AF33FDFF5D +:1003C000FBFFFFFFFFFCFF7FD9FFDFFFFFFFFFF514 +:1003D000A3DF6EDEFFFFBDFFFFFEFFFFFFFEE7FDB9 +:1003E000FFFFFFF9EFC6FEB7ADE5F9FFFFFFCFFF57 +:1003F000FFFFCDFB7FFFFFFFF9F60FDFECCF7FFFA5 +:10040000FB7FFFFFFFFDFFFEF9FD7FFF7FFFF95B35 +:10041000FF73DCFD7BDFFFFFFF7BFFFFF753D6FFA2 +:10042000FFFFFFD89FFEFFEF7FEEFFFFFFFBEDED2D +:10043000FDFFFEFFFFFB7FFFE27FFF6FD857F7FF57 +:10044000FFFFDFFFE8FFFFFDFFFFFC7FFFE4FFFB97 +:10045000EFFBFEDFB7EDFFFEDF7FFFFE7FB7FFFFA5 +:10046000FFFF89FFFFCFF3FE7FFFEFFFFE7E7FFBE5 +:10047000FFFFFFFFFFFFFFF1FFEB7AD5BF6FDBBE92 +:10048000FDB7D8F6E5BF6FFBFEF5BD7E06FFDFF7D3 +:10049000FBF6FF3FFFDBFFFF6FFBF7FFFFFFFBFEFE +:1004A000F7AFFFB7EDEFF7FEFFFFDFFFFEFFEFFF58 +:1004B000FFFFFFBFF7FC1FEEFBFEBDFF7F5FD7FD19 +:1004C000FB43FFFFFDFF5FFFF7FFF93FFFCFF3FDAA +:1004D000F77EEFA7F9FE8FA7E9F37E9FFBF8FFFFFA +:1004E0003FFD7F5FDFFDFFFF5FFFFD5FFFFF7FFDE4 +:1004F0007FFD9FFFE0FFFAF8BE6F9FE6F8BE3F9AD0 +:10050000F9BE6F9FE2F9FE6F9FF9FFF5FD7FCFDF28 +:10051000FDFD7FFFF5FFFFFFF7F5FD0FDBFFD3FFCD +:10052000EBFAFFFFBFFFFAFFFFCBFBFEFFFFEBFA8B +:10053000FEFFFFB7FFFFFFFFBFFFDFF5FFFFD7FFA6 +:10054000FFFFDFD7F5FF7FFE4FFFFDFF7F7FFFAD92 +:10055000EBFBFFADFFFFFFFFAFEBFBFFFC0DFFFF72 +:10056000DFD2FDFFFFFDF6FFFF7FFFFF1FFFFFFF55 +:10057000FFFB3F7DEB32FEBF2FEBFAAEBDE0FA7E14 +:10058000BFADEBFAFEBFF57FFFDEFEE3FBFFFFFF33 +:10059000DFEF4FDFFF7FDFFFF7FFFFF87FFFFFEFAA +:1005A000FBFFFFFFEFFFFFDFEDFBDFFFBFFFFFFF05 +:1005B00081FFFFFFFF3FFFFFFFFFFEDDFEEFFDFFBF +:1005C000FFFBFEF7FF93FDFB7EFFFE87E9FF7FB396 +:1005D0009FFEFEFFAFFDFE7E3FFE67FFFFF7FFFFC2 +:1005E000FCF7DFFDFF7FFFFF7F6DFFFFFEFFFF2FAB +:1005F000FFBFFFFFEEFFBEFFFFFEFFEFFFFFFEFFAF +:10060000EFFFFFFA5FFFFFFBFFFFEFFFFBFEFDFFCA +:10061000FEFFFBFFFFFF7FFFFEBFDFFFFBFFFFF7DC +:10062000FCFDFFFFFFFFFF7FFFFFFFFFFFF27FFFEC +:10063000FFFFFF7FFFFFFFFFF3FFFFFFEFFBFFFF6A +:10064000FFDFE2FFFFFBFFFFFFFFFFFFFBE7FFFD19 +:10065000FFFFFFBFFFFFFFEDEFFDFFFFDFD7F5FD62 +:100660007F5DFDFF7FDF97F4FD7B5FFFC9FFFBFE32 +:10067000FFBFFF5FFFFFF7FFEFFDFFEFFFFFFFFF94 +:10068000FFF7FFD7FD7D7FFFFFFFFFEFDFF7FDFFE8 +:10069000BBFFFF7FFFFEE3FFF9FE7FBFEFFBFEFF27 +:1006A000BFF9FEFF9FEFF9FEFFBFF3DAFF37CDF38F +:1006B0007CDF37CDF37F37CDF37CDF37CCF37F5A48 +:1006C000BDF6FDBF6FDBF6FDBF6FDEFDBF6FDBF676 +:1006D000FDBF6FFEF16FEB7ADEB7ADEB7ADEB7AF41 +:1006E0007ADEB7ADEB7ADEB7FF7EFFFECDB36CDB13 +:1006F00036CDB36CDECDB36CDB36CDB36CDFC9BFAA +:10070000F7BDEF7A9EA7A9EA7AB7BDEA7BDEA7BD5F +:10071000CA728D91FFEFFBFEFFBFEFFBFEF7EFFB11 +:10072000FEFFBFEFFBFEFFFE87FFF6FDBF6FDBF6B0 +:10073000FDBF6FF6FDBF6FDBF6FDBF6FFE4FFFBF66 +:10074000EFBBEEFBBEEFBBEFBEEFBBEEFBBEEFBB06 +:10075000EFFC5FFFFFFF3FCFF3FCFF3FCFFCFF3F0E +:10076000CFF3FCFF3FCFFD9FFEBFAFEBFAFEBFAF65 +:10077000EBFEBFAFEBFAFEBFAFEBFFE16FFDFF7F1C +:10078000DFF7FDFF7FDFFDFF7FDFF7FDFF7FDFFF8F +:100790007ABFFBFEDFB7EDFB7EDFB7FB7EDFB7ED99 +:1007A000FB7EDFB7FFC9FFFFBFEFFBFEFFBFEFFB25 +:1007B000FFBFEFFBFEFFBFEEFBFEBBFFFEFFBFEF89 +:1007C000FBFEFFBFEFFEFFBFEFFBFEFF3FCFFFE7EC +:1007D000FEFFF5FD775DD735DD77D7F5CD7B5DD7AE +:1007E000F5DD77FE27FFFF8BE2F8BE2F8BE2F9AF36 +:1007F0008BE2F8BE2F8BE2F9FE1FFF5FD7F5FD7F7E +:100800005FD7F5FF5FD7F5FD7F5FD7F5FFFA3FFEB6 +:10081000BFAFEBFAFEBFAFEBECBFAFEBFAFEBFAF83 +:10082000EBFFFE7FFD7FFFFFFFFFFFFFFFFFFFFFEF +:10083000FFFFFFFFFFFFFFE6FFFADFF7FDFF7FDFB0 +:10084000F7FCFFDFF7FDFF7FDFF7FDFFF5FFFFFFA1 +:10085000FFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFAC +:10086000FF02FFFEBFABEBFABEBF23EBDE1FAFEA1A +:10087000FAFEAFAFEBFD97FFF3FC7B1FCFF1FC7FE0 +:100880001FF1FC771FCDF1FCFF1FFE87FFAFEFFAD2 +:10089000FEFFAFEFFAFDBF2BFB7EBFBFEBFBFBFB09 +:1008A000DFFFFBF7FFFF7FF7F7FFFDDFFEFCDFFF5A +:1008B000DFFFFDFFDABFFFBBEFFBF9FFBEEFFBFB86 +:1008C000BFEFFBFEFFBFEFFBFFF77FFDD7FFFF7F13 +:1008D000FFFFFFFEF7FFFEFFF7FFFF7FFFFFECFFCD +:1008E000FFFEDFBFFFFBFEFFBB68AE1FAEFBFBFFE3 +:1008F000FFBFFFD5FF7FFFFFF7FEFEFFBFEF9FFDAE +:100900007FFFCBFFFFDFFFFFBBF7BFFFFFFFFFDF77 +:10091000FFBFFBFFFFFFDE3FFFFFFFFFFFA7FFFF64 +:10092000FFFFEFFF7FFBFDFB7FFFFFFFFFCFF37CB0 +:10093000FF7F8D7FFFFFFFFFFBFFF7FBFEFDFFFF4C +:10094000FFFFF7FDFF7FFD1FFDFFFFFFFFBFDFFF85 +:10095000FFFE5CFF6DFF7FABE7F1FFFD9FFFFFAD8B +:10096000EB7A3F1FFFFFFEBFAFF3DEF5FF8FFBDF2C +:10097000E67FFFDFF3FDFF7EFFFFFFFFFFFDF7F3E5 +:100980007FDFF7EFFFF63F9FDFFFFFEEFFFFEFFB9D +:10099000FFFFF9FBFE4FBFEFBBFF69AFAFFCFF3FAF +:1009A000DDFFFCBF8FFFFDF3BFED9EFCBF6FF5D3F6 +:1009B000DFFFDBD6F5EFFDFEFFB9FF1FD2A9AFFFCA +:1009C000DBF7BFEF46FFFFADEB7ADFEFF7FF7FF717 +:1009D0009FEDFF7FFFADEB7FF56FFFFDFBD6F4F7DB +:1009E000FBF97E7FFF5FC2FEBFFDFB33DFF95BFFDC +:1009F000FFDD677DCFEFDBECFF77DDF7FDFFFFDE8F +:100A0000A7BFD49FFFFFBFEFFEFFDFEFBBFFFFEFEE +:100A1000EBFAFFEFBDFBFFE27FFFDFDFF7FDBFBBC0 +:100A200073F7FD7FDFDEF7BFEADBF6FFD6FFFF6679 +:100A3000FFBEFFBF6BD9F6DFFFFB7E7FB77EFFFEF9 +:100A4000FFCDFFFE7FFFFCFD3FFBFBF7FFFFFBF64B +:100A50007DFE7FFFFCFFB9FFF9FAFEBFAF5BD6ED6D +:100A6000AD7BF6F9BFEFF8FAFEBFFEE6FFFFF7FD3C +:100A7000FF7FBFEFF3FFFF6FF7FEFFFFF7FDFEF70E +:100A8000EFFFFBEFFB7EDEFEFFBFFFFEFFFFFBFF86 +:100A9000FFEFFB6FFC1FFEE7FFFFFFEFFFD3B4BBD1 +:100AA000FFFFFDBF6FE3FEFFBFFCBFF7CFF7FDFF0A +:100AB0002FDFABEAFFDFE7EA9AAFEFFBFEFFF53F80 +:100AC000FD7EFFD7F5FBFFFDF7FF7FFEF7FDFFD7AC +:100AD000FFD77FEE7FFA79FE2F8BE6F9FE3F9EF976 +:100AE000BE2F0BE7F9FE2F9FFDFFFE7D7F5FD7FF37 +:100AF000FF7FFFFDFF7F5F97FFFD7F5FFFE3FFFF4E +:100B0000FAFEBFAFFBFBFFFFCFEBFEBFAFFFFAFE6E +:100B1000BFFF87FFFFF5FFFFFFFFFDFF7FFFFFFF29 +:100B2000FBFFFFF5FFFFFE0FFFFDEBFFFFF7FFEF02 +:100B30007BDFFEFFFFDFF7FDEB7FDFFF5FFFFFFFE8 +:100B4000FFFDBFFF7EFABFC7DBF7BD3FFBFFF6FF30 +:100B5000FAAFFFEBFAFE3F2FEAFA3EADC9BAF6ADA7 +:100B6000AFEBFAF6BFFE7FFFFFFDFFF17F3FCFF156 +:100B7000EFFF7FFFBCDFDFF7DDFFE07FFFFFFEFF62 +:100B8000FAECBB7F5FFFFBECFFEFB7FFF7FFFFB5B2 +:100B9000FFFF7FFFFFFFEEDF5FDFDEFFAEE777FFE8 +:100BA000FFDFF7FFE3FFFABBFEFFAFFDFBFEBFABCE +:100BB000F9FEFFBF7FBFFEBDFED7FF9FFDFFBEEF6B +:100BC000FFEEFDBB5BEFFF7FEFFFEFFF7FFF4FFF10 +:100BD000EFFBBCFCFFFFFFFEFEFDFAFEFBFFFDF39B +:100BE000FBFFF85FFFFFD7F5FDDFEFFFF3DC5FCE24 +:100BF000F5BDFFFFD7FFFFF93FFFDFF7FFFEFFFD6A +:100C0000FFFBFFF7B97DFEDFFFFFFFFFF97FFFFE70 +:100C1000FFFF7FFFFEFFFFF7F6FFBFF1F8FFFFFFCB +:100C2000FFE0FFFFFFFFF9FFFFFFFFFFEFEFFFFF19 +:100C30009BFB7FFFFFFFC1FFDFFF3F5FD7BFEFBB26 +:100C4000DEEEFF7FDFFFFEF57FDFFF99FFFFFAFF9C +:100C5000BFFDEB7AFFB7FEFEFFFFEFFFFFFDBFFF1B +:100C600097FFFDF7FF7FF7FFFFFD5FFEF3F9DFDF83 +:100C7000FFFFFCFFFF83FFFFFEFF9EECFBEEFF9FED +:100C8000BFEFFFFEED7BFFFFFFF15AFFFFFDFF7C93 +:100C9000693BDFFF7F1FDFFFFDBAFFFFFBFF5BBD8F +:100CA000FFFFFFFFD7B6EDE9FFD6BD6F5FFBFFEF9C +:100CB000FF5FFEF66FFFFFFFFFF7EB7ADFFF9F7F1F +:100CC0007FFFB7FFFFFEDFFF6CFFFBFFBB6FEBFE9D +:100CD000CCF7A5FA5CF575BBB7DFFE6F5FC5BFFD4E +:100CE0007BFEFF95E729CF4FF591EE6BDFEFFD54CB +:100CF000F5BDB1FFEFEEFBBEBFAFFEDEBD6FDAF2BA +:100D0000FFAFBEFFFFFD7EA7FFF7FFBFEF7BF6FD46 +:100D1000BD4AF28585BF5BFEB5FDFAFF4FFFFEDFE2 +:100D2000FFEDFFBFFFBF7FFEFFB76DFFF7BFBFEF58 +:100D3000FD1FFFFE7DFF67FFFFFF3F7FFEBFFFE759 +:100D4000DFE7FFEF6BFC1FFFBFEFFBFEDEBFAFFA7D +:100D5000FFB6EFF9FEFF8FEFDBEFAB6FFBFEFFFFA0 +:100D6000EFFDFF7FFFFFDEFFFFEFFFFFFF3FFF6CA9 +:100D7000FFBFFBFFFEFFFBFEDFFFFFEFFFFFBFFF3D +:100D8000FFFEFBFFD57FFFFFEFFBFFFFBFEF43B58C +:100D9000FD6FCFD6BE3F7FDBFEC3FFFDFFAFEBFB9A +:100DA000FCFF3EEFE8FABDCDAAFEFE7DCFFFB7FF08 +:100DB000F7FFFFFFFDFF75CD52D7FDFBF7DDFBEF22 +:100DC000EBFFFF4FFFBF9FE7F9FC7F8BC3F9AF8FAE +:100DD000E7E9BE7F9FE6F9FC5FFFFFF7FDFF7A5F63 +:100DE000D7EDFFFFD7FFDD7FE7FFFCFFFC3FFFFFF5 +:100DF000FFFBFFFEBFAFFFFDFFEFFFEBFFFFFFFFBE +:100E0000FFF77FFF7FDFFFFDFD7FFEF7FD7FDFFF49 +:100E1000FDFFFFDFFBFFEEFFFBFFF7FDFF7ADFF5D6 +:100E2000FDFADFF7FCFF7FDFBFEDFFC9FFDFFFBF8C +:100E30002FFBFFBCADFFF7FFFFEFD3FF7DBF6FFFC1 +:100E4000FAFFFEBFAEEAFABEADA5EBCEBFA7EB5AE6 +:100E5000DEBDAF6BFD57FFFFF47F1F7FFDFF7F36C9 +:100E6000F0DF79FFFFFFF7FDBFFF87FFFBF3FCFF1C +:100E7000FFFFFF7EFFBFDFFFFFFFFFFFFDBFF89F0C +:100E8000FFFFFFFFBFFFFFFDF7FCBDFFFEFFFFFF02 +:100E9000FFFFFBF9BFFFFFEBE2FEFFBFEFA9BA2F99 +:100EA000EBF9FE77DFF7FFFFF97FFFFF7FEFD7FF5B +:100EB000FDFFFBF5FFBF6FDFFFFFFDFFFFF0FFFF53 +:100EC000FF3FCFFFBAEE9BBFEED7FECDEFFFDFBFF8 +:100ED000FFFFC5FFFFFD7F4FFDF6D9FF4FD6FDBFDA +:100EE0006EFFFFF47FFF7F8BFFFFFFFFF7FFF9FE31 +:100EF00037FFD9FBF5AFFDFFFFFBFFFF07FFFFFF4C +:100F0000FBF7FFFDFF7CFA7E4FFCDF1DC7FFFFFFF5 +:100F1000FFAEFFFFFFFFFDFBFFFFFEFEFCFF7F7F3D +:100F2000BFEFFEFFFFFF5FFDFFFFFFFD6F5AD77BA7 +:100F3000BE5FFE39FFF7FFF7FDFEAA1FFFFFFFFFB1 +:100F4000FEFEABAFFDFEBFFFF7FF7FFE8FE3FBEEC4 +:100F50007FFFFFFFFFEBFBFFFDBFEFDFFFFFFFFFAB +:100F6000FFFFFFFBE43FFFDFFFFFFFFFF3EFBBFBF4 +:100F7000BFEFBBFFD7BFFFFFFF29AFF7FFFFFBFFAF +:100F8000FBE6FF0FFB3FDF0FFFAFFFFFFFF5C3DF08 +:100F90005FFFFFFFFE6BCABEBCFF9FF2BFFFFEFA02 +:100FA000FFFFEF16FFFFFFFFFFFCDF97FD79FF3725 +:100FB000E77FFFFFB5FFFFF62FFFFDFBFEFFFFFD05 +:100FC0005F575FFFDB52DFFFFDBFFFFFFCDBFF7BF7 +:100FD000B5FD7FFF719C6EFFF635A59BFFFFFDFF02 +:100FE000FFDB9E7FFEEFFBFFFFBDEFFFDEB7F94BA0 +:100FF000FFF5EFFFFFFFE87EFFEADFF7FFFD695B2C +:10100000FC9FEF78D6FFEBEFFFFFFFE8FFFFEDFF60 +:10101000FFFFFFE3F9F6BFFFFFFEDFFF7FFFFFFFEC +:10102000D1FFFFE7FFFFFFFFE7F9FFBF7FD9FFFD1C +:10103000FE7FFFFEFFF9FFFBD6DFBFEF5BD6FFBFF2 +:10104000FBF6FFBFEFF8F6DDBEFE16FFBFEFFFFEBB +:10105000FFBFEFFFFFFF6FFBFFFFFF6FF3FFF7EF38 +:10106000FBFFBFFFEFFEFFBFFFFFFFBEBFFFEFFFB6 +:101070007FEFFFFD17FB7BFFFFFD7FDBF6F47FFAC1 +:10108000FEF5BFEBE3F7FFFFE9BFFFAFF7FDF37E30 +:101090008FA3EAFFCBF3EEFFBFEFF7F9FFFE7FFF71 +:1010A000FFFFFFF5FBF6FFF52FFEFBD7BFFFBEDF0F +:1010B0009FFFF0FFFFF9FE7F8FA3F8FE6F9FF9F609 +:1010C0002F9FE7F9FE2F9FE1FFFFFF7FDFF7F5FD81 +:1010D0007F7FF5FF9F5FFBFEFF7FFFFFCBFFFFFBE7 +:1010E000FEFFBFAFFBFEFFDFFEFEBFF7FFFFFFFF10 +:1010F000FFC7FFFFFDFF7FDDF7FDFFFFD7FFFD7F90 +:10110000FFFBFDFFFFFEEF7FFDEFFBFEFBFDFF7F23 +:10111000DFFDFF7ADFF7FDFFFFFFFF1FFFFFD3F7C4 +:10112000FFFF6FDBFFFFEFCBF4FFFFFFFFFFFFFED3 +:1011300029FFE8DA769FAF6ADAFE35EBDAD6BFAB85 +:10114000EB7ADEBFD77FFFFEFFBFEFFDDF77BFFD8E +:1011500037EFFFEFFF3FFFFFFFFE7FFFFFFFF77E51 +:10116000DFFFFFFFFAB77FFFFFFEFFFFFFFF89FFF3 +:10117000FFFFFFFFFFFFFFFFFF9FFBFFFFFFE7FFFB +:10118000FFFFFFAAFFABFBFAEFBFFFDFFA7BB9FE61 +:10119000FEFFFDFFF7FE3FFFB7FFF7EEFF7FEFFF1C +:1011A000FF7FFF1FFBFFBFFBFEFFBDFFFF2FFFBF4A +:1011B000FF7FDFFAFFFFFCEEF5F3BEFB0FEFF3BEA0 +:1011C000EFFC5FFF5AFFF7DFFFFFFED5FC5FFBF28E +:1011D000FFFF2FBBF3FFFFBFFFEFFFEFFFFFFFFF9F +:1011E000BFFFFFFD7BFFDFB9FFFBFFD87FFFFFFFE6 +:1011F000FBFFFC7F1FBFE0DFF7EFFFFD7FFEDFFFA0 +:10120000E0FFFFFDEFFBFFFEF7DFFFEB5FFFF7FF08 +:10121000FFFFFFBFFFFDFFFDFFFFFFF7FDFF3BDC13 +:10122000FD6D7B5F57F5FD7F5FFFB1FFEBFFFFFFBC +:10123000FBFBFEFFBFFBBEFFBFEFFBFEFFAFFEF7FA +:10124000DFDFFFFFFF7FCFF3F8FFD7FBFF5FBFF7C5 +:10125000FBFF7FFE23FFFFFE7FF3FFFBFEFFFFF39D +:10126000FFFFF5F9FF3FFFFFF09AFFBE7FFFFCF99C +:10127000FFFDAFEBFEBFFFCFF3FE7FFFFF5BBDFFC8 +:10128000BCEBFFD7D4AFAFFDFFCFF7FDFF7FDFF79C +:10129000FDFEFF6FFFFBFFFFFFFD7F5EFDBFDBF687 +:1012A000FDBF6FFBEEFDFF7AFFFAFBFF3FFBB75F71 +:1012B000D6F71F71DC771DC731DC77DFF9BFF55B2F +:1012C000F4D79DAEFFBFFDBFDBF6FDBF6FDBF6FEC3 +:1012D0003D81FFEBFEFEFEFFEB7ADF7D777DF5794A +:1012E000DF57DDF57D7EE6FFD63FBF7FFFD4F53FBC +:1012F000BFFBBEEFB3EEFB9EEFBBFE8BFFFEDFB787 +:10130000EDFFF7FDFEFFEFBBEEFFBEEFBBEEEBFC2C +:101310001FFFFFFDFFE7FFF7FDFFEFFEFFBFEFFB46 +:10132000FEFFBFEBFA1FFFB7EF5BFEFFAFEBDDE7A2 +:10133000DE779DE779DE779DBFE66FFFFEFFBFEFAB +:10134000FBFEFDBF6FF6FDBF6FDBF6FDBFFF7EFF4F +:10135000FFFBFEFEFFEFFBFDEF7EF7BDEF7BDEF751 +:10136000BDEFFFD5FFBFFFEFFEFFFC3F0FE7FE7FA6 +:101370009FE7F9FE7F9FE7FEF3FFFEDFADDF67EE3D +:10138000FBBFEFFEFFBFEFFBFEFFBFEFFF23FFFF43 +:10139000FFFF7FFFF3BCDBFEFBFFFBBEF7FBFF7F26 +:1013A000DFFFCFFBFF9FE3F9BE3F8FE779FF9DE7AC +:1013B000F9FE7F9FE7F9FE5FFFCFF7FFFFFFDFF743 +:1013C000FE7FE7F9FE7FFFFFFBFEFFFFBFFFBFBF12 +:1013D000FFFEFFBFEFFFFDFFFFFFFFFFFFF7FDFF7A +:1013E000FF3FFFBFFFF7FFFF7FDFFFFFFFFFFFFFB5 +:1013F000FFFFFFFFFFE8EFFF5FF7BFF9FEDFB7FD7D +:10140000FFDFF7FDFF7FDFF7FDFFDDFFF2FFBFFF2F +:10141000FFBFFFFF2FF2FFBF2F7BD2F7BF2FFFBB16 +:10142000FFEE8FAFEBFAFE3FA769CE8FA4EAFAEE8C +:10143000B7AEEBFDC7FFF7F7FFFFFFFFFF7F3EF300 +:1014400074FF3F4FFFE7FF3FFEA7FFFFDFF7B7FF48 +:10145000F7FFBAEF37EBFBFEBFFBFEF3FFF9DFFF51 +:10146000BFFFFFFFBFFFFFFFFDDFFFFDFFFFFBFE35 +:10147000FDFFFBBFFE3FEDFFDFBE3DA7FBFA3FE6F2 +:10148000E1FEFE3FEFE3DFF57FFEFF7EFFFFFFFFA4 +:10149000EF6FF6FF7DEFD7DEFF7DEFFFF2FFFFFF7F +:1014A000FFFFFF7BDEFBE6EEEF376EF37EEB37EF01 +:1014B000FFC1FFFEFFF7EFFFFFFFBF3FD2DFBF2FF0 +:1014C0007BE2FFFE3BBDDBFFFEFFFFFFFFFFEFFE0A +:1014D000FFFBFFFFBFFFFBDFFFBFFFB7FFFFBFEF5C +:1014E000FFFFFFFFFFFF0FFF7FFF1FEFF1FDFFF685 +:1014F000AFFFFFFFFFFFEFFFFFFFFE9FFFFFFF7745 +:10150000EFF7FBFFFE5FFFFFBFCFFBF7DDF7F5FF58 +:101510005FD5F5FD7F5FD7F5FFFB0FFFFFA9EA7AE7 +:10152000FFAF8FFEDFAFEFFBFEFFBFEFFBDFE55F3F +:10153000FFFFFFFFFFBD57FFFF6F77BFF7FBFF7F89 +:10154000BFF7FFFCBFFF9FFFFFEFFFFEFFFFFF1F87 +:10155000CFFFFCFFFFFFFFFB65AFF37CFF3FDFFF2B +:10156000FDE9FE7FE7FFFE7FFFFFFFFFFDE3DFFBFF +:10157000DBF6FDEF5BFBFFDFFCFF3FDFF3FDFF7FF3 +:10158000DFEF66FFDFADEB7ADEF7F7E7D9FD9F67A8 +:10159000D9F67D9FE7DFF547FD655BD6F4FEFFEFEB +:1015A000FF6DF6DDB76DDB76DCB77DFA9BF66D9DE2 +:1015B0006759DFF7DDFFEBFEBFAFEBFAFEBFAFE32E +:1015C000D19FFFBDBFEFFEF7BFBFF7D77FDDF79D10 +:1015D000DF7FDFF7FFE07FFDC1DFF7FDC77F7FFB28 +:1015E000FFBBECFB3EFFBFECFBFFD87FBF6CFFBE39 +:1015F000FFBFEDFFEFFEFBBFEFFBFEFFBFEEFFC542 +:10160000FFAF6FFFFCFD3FE7FFFEFFEFFBFEFFBFFD +:10161000EFFBFEBF89FEFABAFEBFAFFBF6F5D97D40 +:101620009765D9745D9765D3FED6FFBFF7FDFF7F41 +:10163000BFCFFBFEFFEFFBFEFFBFEFFBFFF68FFB15 +:10164000FFEFFB7EDBFEFFBEEFEEFBBEEFBBEEFB74 +:10165000BEFFFFDFFF43FFFFFBEF5FB7FE7FE7F952 +:10166000FE7F9FE7F9FE7FF9BFFEAF77FDFF2FAF4B +:10167000A7FEFFEFFBFEFFBFEFFBFEFFF17FEFDFFB +:10168000FF97F5EFFFDFFFFFBFFFBFFFFFFEFFFF8D +:10169000FFE0FFFFF9FE2F8BE3F8BE779FF9DA77C3 +:1016A0009DE779DE779FDDFFFDFD7F5FD7FDFF7F43 +:1016B000E7FE7F97E7FBFEFFBFEFFFABFFEFFAFE12 +:1016C000BFAFFFFAFFFFDFFFFBFFF7FDFF7FDFFF8D +:1016D00067FFF7F5FFFFFFDFFDFFFFFFFFFFFFFFE6 +:1016E000FFFFFFFFFFEFFFBDEBFFFFF7ADEBFFDFFE +:1016F000FDFF3FDFF7FDFF7FDFFF5FFFF7FFFFFD30 +:10170000BFFFCBF4FF7FD3F7FD3F7FD3F7FFFC3F55 +:10171000FFEAFABEAFABEBBAF4956B52D4AD2F4AE9 +:10172000D2F6BFD27FF73FFFFFF37FFFFFF7FFBA8D +:10173000DFFBFDFFBFFFFBFFF87FEAFFFEFEDFFFE1 +:10174000F7FF7FBBFFFFBFDFFBFFFFBFFFB17FFFE7 +:10175000FBEFFFFFFFFFFFBFCFFEFFFFEFFFF7FF36 +:10176000FFFFF1FF69BEFABFAFE2FFFEFDAFF3FE80 +:10177000FFBFEFFBFCFFFF07FD95DBDF7FDFAFFF68 +:10178000F7AF36FEBF65EBF6FE9F6FFE07FFCFFF9C +:10179000F8FEFFCFFFF6FAE7FBFEFFBBEDF9FFFF18 +:1017A000FF5FFFFFFF75FFEF7EFDE0E85ED3E5F929 +:1017B0003E5FD7F7FFFA2FFBFFFFFFFFFEFFFF7F24 +:1017C0007FD7F57D5F57D5F5EFFFF37FFC7FFFC730 +:1017D000F1FFFF1FCFB0FF3FCFF3FCFF3FCEFFE491 +:1017E000FFDF7FFEF7BBFFFFDFEFEEFFBFEFFBFE8C +:1017F000BFBFEFFFD1FFFFFFFDFBFFFDFFFB9FE939 +:10180000FE7F9FE7F9FE7FBFFFB3FFFFF7FFFFAF4C +:10181000F7FFB63FEBFAFEBFAFEBFAFEBFFEA7FF46 +:10182000FFFFFFFFF7FFFFFFFE9FF7F9FF7F9FE737 +:10183000FFFFFEAF6FFFFFFF9FFFDFFF7D5FDDFF5D +:10184000FBBFE7BBFFFBDF6D5F7EFFFFFFFFFFFF1F +:10185000EBF7FFE7EFF7FFFF7FFFF7FFFC8FFFEFEF +:10186000FDFEFFBEF4F27DD7CFFF3FFFFFFFFFFF7E +:10187000FFCF6BFFBF3FFBF2FC7FEBFF9FFAFFFF49 +:101880003FFFF3FFFFFD70F7FFFFBFFFFBD7FEF544 +:1018900077FF15DD77FDFF7FDFF7FBCDBFFFFDFF96 +:1018A000FFDF37CDF9ECFEEFBBF4FB3F4FB3FFFD9D +:1018B000CBFFE97E549FE54BB7FFDD7DC771DD7738 +:1018C0005DD775CD7FD6FFD3F6F93F6D95AF7FFE1F +:1018D000FFEFFBFEFFBFEFFBFEF6C7FFAD7BCAFFCE +:1018E000BFBFEFFDE3DFB7EDFB7EDF37EDE3FBDFEF +:1018F000FF525C15FDCF7FDFFEEFEFFBFEFFBFEC7D +:101900007BFEFFFE3E7FDAF7FDFF7FFFFFFBEFBBB5 +:101910006FFBFEFFBFEFFBFFF77DFFD8FFFDBF7F33 +:10192000FBFFFF9FFBFE7F9FE7F9FE7F9FEA7FF6AD +:10193000BFBD6A5AF6E5BF775F6DDD775DD775DDB0 +:1019400077FFA5BFCFFBFFFFBFCFFBFDFFBFF3FEC0 +:10195000FFBFEFFBFEFFFDABFFBFBFFFFBFF7FEF56 +:10196000FFBEFBEEFBBEEFBBEEFBBFFFB5FFD0BC87 +:10197000FD2F4BF7FFFF9FF9FE7F9FE7F9FE7F9F4B +:10198000FA8FFDABFADABFAFB3FDFFBFFBFEFFBFBF +:10199000EFFBFEF7BFFF9FFF77F7BDFD77DFFF7E11 +:1019A000DFEDBBFEFFBEEFFBFEFFFA3FFFBE6F8F1A +:1019B000E6F9FE7F9FC7FE7F9FE7F9FE7F9FE7FB6B +:1019C0007FFF7FCFFFFDFFFFDFFBAFBFEFFFFEFF1E +:1019D0009FEFFBFFFCFFFBFEFFFFFFFFFEFFFFF79C +:1019E000FFFFFFFFFFFFFFFFFFF5FFFFFF3FDFF7F9 +:1019F000FFFF7FEFFEFFBFFFFBFFFFBFEFFFB37FE8 +:101A0000FF7B5EF7FDFF7B7FF7FF7FDFF7FDFF7F4B +:101A1000DFF7FF17FFFFFF7FFFFFDDF6FCBFCBF215 +:101A2000BCBF2FCBF2FCBFFE8FFFFA7EBFA7EBDA65 +:101A3000FCBFAF7AFEBFAFEAFAFEBFAFF4DFFEFF36 +:101A4000F33C7F3EFFCFF8BF8FE3F8FE3F8FE7E820 +:101A5000FFFC9FFFFFCFEBB3E7FB7BF3FEFFCFDB8A +:101A6000FBFBBF6F6FDFEC7FFFFFF7FDFDFFFFFFAD +:101A7000FFB2BFFFDEFDBDEFFBF6DFEAE7DBFEBB3B +:101A8000FFEBFBBF9F8FE8FE3F8FA3F8FE3F8FFF6A +:101A9000F87EFDFD7FFFFBCDFFFDFF5FEFFDFFFF4C +:101AA000DFF7FDFFBE90FFFFEEFF3FBFF3BBFEB7CA +:101AB000ABFAFEAFADEAFADEABFF63FFFEF2FFB3B7 +:101AC000FFDFEE7DFF03F1F43F1FC3F1EC7FFE6FFC +:101AD000FFFBFBFF9FFFBFFF7B5FFDFFDFF7FDFD10 +:101AE0007F7FDFFECFFBFFFFAFFBFF1FEFA5FDBF3B +:101AF000DFFB7DFFBFDFFBFFFD3BFFFFFFFFFFFDC8 +:101B0000AFF3FFFB7FBFD7FBBF7FBBF7FFF87FFFC4 +:101B1000FA5FD7FFDF7FEFFFFF7FDBF7FDFF7FDFA0 +:101B2000B7FBECFFFFF7BFEFFDFCFBFFEFF0FE3F65 +:101B30008FE3F8FE3F8FEF8DFFFFEF7FBFFFFBFFCF +:101B4000DBBFFFFFFFFFFFFFFFFFFFEFD8FF2E7F91 +:101B5000BEEFFE6EFFBFF9FFFFF3FFFFFFFFFFFFCA +:101B6000FC66BE47F37FDFFE879FFFFFFFFFE7FFB7 +:101B7000FFFFFFFFFFD66F7CFB4FD2FFFD2BFEFF69 +:101B8000FFFD5FD7D5F57DFFFFFFBF9BFFFFDFB7F1 +:101B9000FFFFDFFF3FCFFE7FBFEFFBFCFF3FFFD923 +:101BA000BFFE97EC8FB7FE9B7DFDB7DD771DC7713C +:101BB000DD775DD7F36FFD3F73DDAFFD7AFFFFAFDC +:101BC000FEFDBFEFFBFEFFBFEF667FFFFFBFBFFF66 +:101BD000FBFFF7DFFDFB7DDFB7CDF37C5F3F913F80 +:101BE000FF3DEF7BFFFCFFCAEFFEFFBDEFFB1EE7F3 +:101BF000BBEC7FB3FFFD9FFFFFFEFFFF7FBFFBFE40 +:101C0000FFBFEFFBEEFBBFDF67FFFFBFEFDBFFBCFC +:101C1000FE7FFBFF9FEFF9FE7F9FE7F9FE87FFEE58 +:101C2000FBBEE5BFEFF9D765F7DDE77DDF775DD771 +:101C30007FF89BFEFFBFEFFBFFFFBFEFFBFF7FCFF8 +:101C4000F3FCFFBFEFFFDB3FEFFBFEFFDFFFFEFB21 +:101C5000BBEFBFEFBBEEFBBEEFBBFFFC7FFD3B5B13 +:101C6000D6E5FD4FC3FBFFBFEFFBFEFFBFEFFBFF62 +:101C7000B4FFFABC8FB2E9D22ECFFBFFBFEFFBFE61 +:101C8000FFBFEFFBFFECFFFDFD7FDFF7E4DF5FFF52 +:101C9000FFFBFFFFFFFFFFFFFFFFC3FFEFE6F8FEC5 +:101CA0003F8B83F9FE7FE7F9FE7F9FE7F9FE7F1701 +:101CB000FDFFFFFF7F5FF72CFFFFFFFE7FFFE7F9D0 +:101CC000FE7F9FFE2FFFFFEFFFFEBFEFADFFFF7F09 +:101CD000FFFFFFFFFFFFFFFFFEDFFFDFFFFDFD7FD9 +:101CE000DFF7FFFFFFFFFFFFFFFFFFFFFFFA3FFEF2 +:101CF000F7FDEF7AFFB1BDFF7FF7FDFF7FDFF7FD57 +:101D0000FF7FF327FFDFFFDDFFFC9BFFCBFCBF2F37 +:101D1000CBF2FCBF2FC9FFDEFFDFAFEBDAFEBBAFBC +:101D2000EBF8F7AFE8FAFEBFAFEBF2FFFDFFFFEF16 +:101D3000BDD7BFFFFFDE8FB8DE378DA378DA3F8FC8 +:101D4000FFA1FFFFFBFBFFFFFFFFA7BDFB76FDBF72 +:101D5000EFDBFEBBBFFE277FFFFEFEFDF5FFEFF5CD +:101D6000DF1FE7FDFF7FDFF7FDFFFFCDFDAEFFFAD1 +:101D70003E3FABFDF87E8FE3F8FE3E8FE3F8FFFEBB +:101D80001FEFDFBFFEDEDFD9FFDFBCFFFF7FFFEF0E +:101D9000FD7FDFF7F93FFEFFFF6FFEDEBFF7EDEAE5 +:101DA000FD8F83F8EA3F8FEFFFF47FFFEFEF7BF3C8 +:101DB000F15FFFFFF13B7FDFF7FDFFFFFFFFE0FF7C +:101DC000FFFFF7FF6FFF7FFFFFF7DEF7BFEFFBF7C8 +:101DD000FDFFFFF5FAFFFFFBE7FFF3F87FF3DFFFFF +:101DE000FFFFFFFFFFFF1FEFBBFFFFFFFFFFFFFD39 +:101DF000FF7FFF9FFFFFFFFFFFFFFFCFFF37FFFFCB +:101E00007FDF775DE7FCFFBFF7F5FBFFFFD7F5FB53 +:101E1000FFFF45FD7FEAFDBEBFDFF7FFFFDBFBFEF7 +:101E2000FFBFEFFFFFFFFB5F7FFFFEFFFFFFFFFF37 +:101E3000FFFEFFEFFDFF7FDFFFEFFBF80FF3FFF982 +:101E40002EFBFEFCF3EFFFFFBFFFFBE7FFFE7EFF75 +:101E5000C06BCFFF34DFF1FDFFEFFFFFFFDFF7FDCA +:101E6000CF7F9CFDFD6CF7FFF6FDEB2B9FFFFCFE8B +:101E70007EFFFFFFFFD7F3F7FFFBE1BFFFEB7ADE4B +:101E8000D7FBFFF9FEFFFFF3DE7FFDE77FFFFDBB22 +:101E9000FFFF7ECCF6AF5F7FFEF47DF7FDBB6EDB10 +:101EA000B7FFF7DF66FFFFF73DCFDEBDFFFFDEDBED +:101EB0008DF77EDFB7EF7FFFF687FFFFEFFEDEBF18 +:101EC000FFFFFFBBEFFDFF7BDEF73FFFBFFBDBFF4D +:101ED000F2B6FDBD7FE7FFFFFF6FF7FFFFFFFE7765 +:101EE000FFBFF8AFFFDFBFFFBF7FFBFFFFFFDBFEE2 +:101EF000FFBFFFFAFFFDFFF67FFF9FFFFF3FEFF8F9 +:101F0000EE7E9FBAFEBF8FEFFEFEF9FFFA7FFE7EE8 +:101F1000BFAFFB96FD9FEF5E65BEEF5BB6FFBEE316 +:101F2000FFB5BFFFFDFF7FFFEFDFFEFFBFFBFEFF43 +:101F3000BFCFFFFFFFFD9BFFFEFBFEDFFF7FFFF735 +:101F4000FEFFDFFBFBFEFFFFFFFFFFB7FEFAFFAB6D +:101F5000EFFFFDB57B7FFBF7FDFFFFDDFFEF8FFFA1 +:101F60002FFFFB7CFF3FDF73EBFE3FFFEFFBFEFF2E +:101F7000EFFDFFBFFD0FFFFFFFF5F9FF7FD7FDFF6F +:101F8000DFFFF7FBFF7FBFFFFFF09FFFFE7F8BE3CD +:101F9000F9DE279BE6BE7F9BC3F8DE7F9DE7FE7FD1 +:101FA000FFFF5FD7FFFFFF4FFBFFFF7FFFAFFF9FED +:101FB0007FFBFFE8FFFFFEBFAFFFFFFEBFEFF7FFB6 +:101FC000BFFFFFFFFFFFF7FFFCFFFFFD7FFFFFFFEE +:101FD000FD3FCFFFFFFFFFF7FFFD7FFFFF93FFFFF9 +:101FE0007ADFF7FFFF7B7FB7EFFFFFFDBFFDFBFF52 +:101FF000F7FFD7FFFFFFFC9F6FCBFFF4BBDFD6FDE2 +:10200000BF2FD3F7FFDFFFCFFFFABEBDAF6ADABE47 +:10201000BBAB3ABE2DAEEBDAF63FADF5DDFFCFF14F +:10202000FFF97FFF73FEFFCFC3F4F72FF3FFFCFF31 +:102030007C1FFF3F4FFF7EFFEFBDF6FEFF2BEFDC67 +:10204000FBFDFFFBFFEA7BFFFFFFFFFFFBF7DFFF6F +:10205000E37DFFB7FFBFFFFFDFFFF8FFBFFFBFEB71 +:10206000E7FAFE3DBFE9FCBFFFFAFBFEFFFFFFD929 +:10207000FFFFFFF67FFFF67DFFDFCFFDBFFBEF7EAB +:10208000FF7FFFFFD3FFFDFBFFFBFFFFFFEFFFBF66 +:10209000FEFFF7EFFFFFFFFBFF87FFFDFFFFFFFFE7 +:1020A0007BFEFFFE3BF7F7FF3FFFFFFFFFFF0FFF4A +:1020B000FFFFFFFBFFFFFFF7FFFFADFFFEF7FFFF97 +:1020C0005FFFFFDFFFFDFFF5FFDFFFBDFFE9FFC79C +:1020D000F3FFFFF7FFF3FFF83BFFFF7BDFBFFBEFF3 +:1020E000FBFFFBF7F7BBFFFFFFFFFBFFFE7FF37F6D +:1020F0005EB7BFFD7FFFF97FFBFFEBFD7F7FFFEF4B +:10210000FBE03FFEBFBFDFFF7EFFF7FFFFFEBFFF2D +:10211000DB78FFFFFFEEA1BFF5DEFBF7FFFBFFFF64 +:10212000FFFFFBFFFFD7FFFFFFFFEFF0FFFFFFF316 +:10213000F7FFEFFFE7CFFFFBFFEFFFFF9F9FEFFCF6 +:1021400016BFFEF3E4FFFFC6FFE7FFFFFDFFBFFF83 +:10215000FF3FFFBFD6AF7FFE6B7E7FFFAFFFFFBFAE +:10216000FF5FFFFEFFFFFEFFFFBDDBFFFE5FF2FF35 +:10217000FF5FFFFFFFFFFFFFEF7FFFFFFFFFDEBF00 +:10218000FFFFEFFB77FEBD7F5FFFFFFFDF6FEDFF20 +:10219000FDFF7FFD6FFFFF77DACFFD5FFFBFFFFF22 +:1021A000DF7FFFFBFFFFFFFF667FFFFEBFE7BFFA9A +:1021B000FFFEFFFFFFDFFF59EFFFEFFB7F89FFFF10 +:1021C000E9FF6FFFF5FFFFFFFFFF7FF2F7FFFFEF74 +:1021D000F87FFBFFFDFFFFD9FFEFBBFFFFFFBFEF66 +:1021E000DEFFFF9F7FDFFFF7FFFFFFFFDFFFFFAF98 +:1021F000FFFFF73FEB9FFE7F9E7F9FFE87FFEDDB9C +:1022000056FFBFAF0BD2FFEFDB6E7DBD6FF8FE3F19 +:10221000FA5BFFFDBFEFFFBF6FDBE6FFFF3FFFDFB6 +:10222000FEFFFFFFFFDA3FFFFBFEFEFFFFDFF7BD14 +:10223000FFFDFFFEFFFBFFFFFFFFF15FFD9FDFFDE7 +:10224000FFFD7FFFFFFFFF76FAFFFF7FE3F8FFAEA2 +:10225000FFFB7E9D73FFFA7FDFFFFF7FFFFBCDFF5C +:102260007FEFFBFFFDFFF77F7FEFFFEDFFFFFFB588 +:10227000FFBFFFBFFDEFDBF7FF93FFEFE2F9BE7F8C +:102280008BE7F9FE6BE7F9FE7F9FE7F9FE7F47FFDB +:10229000FFFDFF9FFFD7FFFFFFFFF5FF9FFFF7FE4B +:1022A000FFBFFE6FFFFFFBFFFFFFAFFFFFFF7FFBE7 +:1022B000FFFEFFFFFFFFFFFDDFFFFFF7FFFFFFDF79 +:1022C000FFFFFF5FFFFFFFFF5FFBFEFFF837FFFF32 +:1022D000EFFF7FFEBFFFFFFEBFFFFF7FFFBFFDFFE2 +:1022E0007FFA7FFFFF6FFFFF7DFFCFFFFFFF4FFFF5 +:1022F000F2FFFFFFFFFFFABFFFAEEBFAFEBBADEB55 +:10230000FAF7AF6BFAF6BF25E9F27F45FFFFFDF75D +:10231000F7BFFFDFFFFFBFFBFFDFF3FFF73FCFFF9D +:10232000A1FFFFBFE7FFFF7FFF3DFFFFFFF7FF2F8D +:10233000FFFBF57FFE57FFFFFFFFFFFFFFFFFFF7EC +:102340003FFFFEFFFFFFFDFEF7EEAFFEEEE7FAFFF9 +:10235000FE9DF95EFEFFEBFFFFDFA7FFFFFFFCDB4B +:10236000FFFFFF7EFBFFFFEFFBFDFFDBFFFFFFEF4C +:10237000FFFFFFFDBFFEBFFF6F7FFFF7FFFFF9FF0E +:10238000F7FFBFDEF7FFFFFFFA7FFDBF5FFFFFBF75 +:10239000FFEDFFF7BFFFFFEFFFDFFFFFFFE6FFFBF4 +:1023A0007FFFFFFFFFFFF7FFFFFFFFFFFFFFEBFFD9 +:1023B000FDFFF5FFF67FDFBDCFFFFFFFFFDFFFFF74 +:1023C000FFF9FFFFFFFFFFE3FFEEBFFF7DEFFEFF23 +:1023D000FFFFBFFFFFFFFFFEFFFFFFFFE7FFB5AE01 +:1023E000FFFFB6FEBFFFFFBFFFFFFFFFFFFFFFFFC7 +:1023F000FF27FFEFFE7FDFFF7EFFFFFFFFFFFFFFF7 +:10240000FFFFFDFFF7F99FFF5FFFFFFFFFFFFF7F6C +:10241000FFFFFEFFFFFFFFFFFFFFFF0FFFE7BFFE16 +:10242000FFBFFFFFFFFFFCBFFFFFFEFFFFFFFFC47B +:102430006BFF291FFBAFFFFFFFFFFFEF1BFEFFFC42 +:102440006FFFFFFD6AF7D7F5BFFFFEFFFFFFFFFF3E +:10245000FEBFFFFFFAFFFFF7FBDDBFFFE7FFFFFF58 +:10246000FFFFFFFFFFFD7FFFFFF5FFFFF7FDB3EF6E +:10247000FD7E5DFFFDFFFFFFFD7FD2F5FB7ECBB74D +:10248000FFFFFFC6FFFDEE63FFFFFFFFFFF6FD65E9 +:102490005BDFFFD5FFFFFFF6E7BFF7A9FFFFEDFF0B +:1024A000FFFFFFFFEBFFFFFFAFFFFFFFF81BFFE3A7 +:1024B000D0BFFFE1FFFFFFFFFFD7FFFFFF5FFFFF81 +:1024C000FFFFAFFFDB76BFFF7FFFBFEFFEFFBFEF7A +:1024D000FBFEFFFFFFBFF27FFF9FFEBDFE7FFFFF02 +:1024E000FFFFFFFFFFFFFFFFFFF73FEC7FF695BB0E +:1024F000EFF8FEFCBF2FDAFCBF2FCBF2FCBFEFFFE3 +:10250000A9BFCFFBFFFFFFFEDDB76DF6D9B66D9B10 +:1025100076D9BFFBFDA3FFBFEFFFEFFFFFFF7FDF1C +:10252000FDEF7BDEF7FDEF7FFFFF05FFFAFE7FEF9C +:10253000E3FFFFFD7FFFFFFFFF5FFFFFFD7FFBAFBF +:10254000FF63C8FFBFEFFFFFFA7FFFFFFFFE9FF7AC +:10255000FFFABFFE9FFB7FFFFFEFD7FFFFF5FFFFF7 +:10256000FFFFFD7FFFFFBFFFF9BFFFBE279FE7F91A +:10257000FE7F8BE7FE7F9FE2F9FE7F9FE7F17FFF03 +:10258000FFFFFBFEFFFFFFD7FFFFFFFFF5FFFFFF92 +:10259000D7FFFAFFFEFFFFFFFDFFFFFFAFF7FFFFD3 +:1025A000FFEBFFFFFFAFFFC4FFF7FFFFEFFFFFFFF2 +:1025B000FF5FFFFFFFFFD7FFFFFFFFFFEBFFFB7A90 +:1025C000DFF7FDFFFFFEBFFFFF7FFFAFFFFFFFF75E +:1025D000EFE3FFDDD2FFDFFFFFF2FCBFCBF6FDBF75 +:1025E0002FCBFF7FDFDEAFFFDAEEBFAFE9FAF4BD3E +:1025F000AF5AAEBBAB6BDADEBFADD75EFFFFBFFC41 +:10260000FFDFFDFFFFFFFFDFF7FFFFFFFFFDFFFA2B +:102610001FFFFEFBEFBFFDFFFDBD77FFFFFFFF9D2F +:10262000EFFFFFFFEF7DFFFBFEEFFFFFFFFFFFF779 +:10263000FFFFFFFFFFFFFFEEBFE4FBFFFE3FFEFFDC +:10264000FFFFFFAFEAFEBFAFEBFAFEFFFFFF55F65D +:10265000FFFEF7FF7FFFEBF75FC5FD7F5FD7F5FF5D +:102660006FFBFF8AFFFFFFFFEBFFFFFFFFFBBFBF1B +:10267000EFFBFFFFFFFFFBFF77DFFBFFFD7FEFFFC0 +:10268000FFFFBF7FFFDFBFFFFBFFFFFFFEEFDFFFAF +:10269000FEFF9FEF7DFFF7FF7FFFFFDFF7FDFFEFFF +:1026A000DFFFDFFFFFFFFFFFFFFFFFFFFDFFFFFB80 +:1026B000FDFFBFDFD1FFF83BFFFFFFFFFFFFFFFF85 +:1026C0007EDBFDFF77DBB77DBFFBFFF87FED7B5E39 +:1026D000FFFEFFFF4FD7FD7FDFD7F5FF7FFFFFFF37 +:1026E000F23FFEFFBFFFFFFFFFBFEFFEFF3BEEFF2E +:1026F000FCEFFFFFFF85FFFDFEFFF5FFFFFEFFDFA5 +:10270000FBFF5FBFFFFDFFFFFFFFA8FFFF9F9EFFD7 +:10271000FFFF7FF3FFFFCFFFF7FDFF7FFFFFFC16FB +:10272000BFCFA3E5EF7FFFF3E4FFCF93FCFF3FCFE5 +:10273000FFFFFFD60F7DBF6EFBF4FCAF6DDB77B7FD +:102740006DDBF6FDBFFFFFFFBF9BFADEB7B7EDF90C +:102750007EB7ACEBD6B3ADEB7ADFFFFFFFD8BFFFA0 +:10276000B7ED9F6FDDF768DB37B36CDB36CDB37F3A +:10277000FF7FF56FFDEF793DF793E47A9EADEA7A3E +:102780009EF7BDEFFFFFFF767FFBC6FFBBEFDAFED4 +:10279000FDBFFBFEFFBFEFFBFFFFFBFFA5FFFDAB98 +:1027A0006F78DE178F79DFFDFF7FDFF7FDFFFFFB1F +:1027B000FFFBFFEFFBEFFBFEFFBBDAF3EF3BCEF3DC +:1027C000BCEF3FCFDFFFB7FFFFFFCF73FFBFEFFFD0 +:1027D000F3FF3FCFF3FCFF3DCF9FFE07FFAFEBFEC4 +:1027E000FDBFEFEBFAFFAFEBFAFEBFAFFBFE3FFB27 +:1027F0009BFF7FDFFFF3FEFFDEF7BF7BDEF7BDEF62 +:102800007BFEFFFFDF3FFEFFB7FFEFF7FFBFEDFEF1 +:10281000DFB7EDFB7EDFFFFFFFFD5FEFEBFAFEF5BD +:10282000BF6FFFFFFFFFFFFFFFFFFFFEF8FFA8FFE7 +:10283000FFBFEFFB6AFBB7EFFBFFBFEFFBFEFFBF86 +:10284000EFFBFFE0FFFFFD7F5CD77DDFF35CF5CDA5 +:10285000735ED7B5FD7FEFFFDBFFFFE2F8BE2F8F82 +:10286000E7F8BE6BE2F8BE2F8BE2F9FE7FE7FFD7F9 +:10287000F5FD7FFFF7F5FD7FD7F5FD7F5FD7F5FF0E +:10288000FFFF8FFFAFEBFAFFFFBFEBFAFF2FEBFA73 +:10289000FEBFAFEBFFFFFE5FFF5FFFFFFDFFFFD758 +:1028A000FFFFFFFFFFFFFFFFFFFFFFFFBFFEB7FDC3 +:1028B000FF7EDFF7ADFF7FF7FDFF7FDFF7FDFF7FD7 +:1028C000F67FFFFFFFDBF6FCAFFFFFFFFFF7FFFF29 +:1028D000FFFFFFFFFFECBFFFAFEBFAF6AB8FEBFAAA +:1028E000F7A5EBFABEBFAFEBFAFF6DFFFF7FDF335B +:1028F000DDFF7FFEF7FC7FFBFFFFFFFFFFFFFFA970 +:10290000FFFDFFFFFEFFFFDFFFFFEFEFFDFF7FFF9C +:10291000FFFFFFFEA7FFFFFF77DFF7FD9F7FFE773B +:10292000EFFFFFFFFFFFFFFFFFAFBFAFFFF9BEBF2E +:102930008FFBFEFEEFFBFEFFBFEFFBFFFFFDDF6F38 +:10294000EFFF7FFFBFBFDFFFFCFFDFF7FDEF7FDFA4 +:10295000FFFFFF3FF6FFCFFFDBFBF7FFEB7AFFFF49 +:10296000FFBFEFFBFFFFFFFE6DFDFF5FFBFFFFF70C +:10297000FF5FF5FFFFFFFFFFFFFFFFFFF8FFFBFF1C +:10298000FFFDFFFFFFFFE7F6BFFFFFFFFFFBFFFFBE +:10299000FFC9FFFFFFBDFFBFAFEFEF3FD1FC7FFBE4 +:1029A000C7FFFFFFFFFFE3FFFFFFFFFDFFFF77FF15 +:1029B000DFB7FDF7FDF7FFFFFFFFFF57FFF7A5FDAF +:1029C0003FDFBFBFFE7FFFFFFFDFFAFDFFFFFFFE20 +:1029D00087FFE9FFFEEFBFEFFEFEFFEFFFFFFFFF08 +:1029E000FFFFFFFFFA9FFF3FFFFDFD57DFFDF3FFF6 +:1029F000DFFDFF5FDFF5FDFFFFF98FFFFFFFEE7FDC +:102A0000FFFFBF5EFEECFB3F7F9FEFF9FFFFCD6B4B +:102A1000FFFFFFC5F3FCFA38FFAF3FEE7F9FFFD902 +:102A2000FFFFFD7AF7FFF3FFAF6FDBF2B9E9FBFFC2 +:102A3000FFFFFEFFFFEFFFFBC5BFFFEFFF5EB7AD80 +:102A4000CD797CFFFFFFFFFFFFFFFFFFFD93FFEF4F +:102A5000EAFEBFEF5BD2CDF56D77DFF7FDFF7FDFDD +:102A6000FFFF66FFD5657D5F759D657FD6FB4FFFD8 +:102A7000FFFFFFFFFFFFF6C7FFBFEFFAFEFFBFEB51 +:102A8000FFDFFF7EFFFFEFFD7ED7FF78DFFF5FDF19 +:102A9000F5BF7FDFC5FF3FF67EFF0FEFF23EBFFFC2 +:102AA000FB3FFFFB7FFFB3FEFBF6FDFFDAF7FDFF09 +:102AB0007FDFF7BFFFFA7FFFFFFFFF9FFFF3DCF928 +:102AC000BFCEE7F9FE7F9FE7FFFFE27FFEFFBFEF8C +:102AD000EBFAFF9F671EFF8FE7F8FE7F8FEFFFBDCA +:102AE000BFFFFBFFFFDFF7FFFCFFBFFFFFFFFFFFA5 +:102AF000FFFFFFFDB3FFFFEFFFFFBFEDFFFBEEFEAC +:102B0000FFFFEFFFFEFFFFFFFFB5FFB7FDFD6EFF0D +:102B1000FFFEFD2FD8FEBF8FEBF9FE3FFFFACFFF80 +:102B2000E7D9FABFDF77FCFB3FABFEFFBFEFFBFE51 +:102B3000FFFFEE1FFFDFF7FFFFFF5F9735BF5EFE72 +:102B4000BFEFFFF7FDFFFFFABFFFBE6F9FE7F8BEC5 +:102B50002F8B66947D9DE7F9FE7F9FE7F17FFFFF56 +:102B6000FFF7F5FD7F5FFBFD9EFFFBFEFFFFEFFF25 +:102B7000FFA0FFFFFFBFEFEBFAFEBFB7F7F7FFFFC6 +:102B8000FDFFFFFFFFFFDDFFFDFFFFFFD7FFFFFFA3 +:102B90007FF5FFFFEFFFFFFFBFFFFFABFEFBFEFF79 +:102BA000F7AFFFFFDEF7EB5FDFF7FDFF7FDFFFFF34 +:102BB000B3FFC9FEFFFFFFFFD6FFFFCBFFFFDFFF25 +:102BC000FFFFFFFFFC8FFFBABEBFAFEB78FEB7ADD4 +:102BD0003AFEB7AFEB7AFEBFAFFF9FFFFFDFFCFF10 +:102BE000FFFEC3FEFFFF33FCFFBFDFF3FFFFBB9F12 +:102BF000FFFFFFEBDFFFFFAFF76FF9BFEFFDFFFF59 +:102C0000FFFFFFE37FFFFFFFFBFFFFBFFDFBF7FFC2 +:102C1000DFF7FFFEEF5FBDFFFAFFF8FFBFAFFBFE80 +:102C2000FE3FEFE8FFDFF3FDFFFFFFFFFFEDFFFBE0 +:102C3000FDFFAFFFFFFEFEBFDBFFFFFFBFFFDFFFBC +:102C4000FDFFCBFFFFFFFFFFBF6FFF7FB7B3FFFFAE +:102C5000DFFFFBEFFFFFFF07FFFBFFFFFFEDFFF5D0 +:102C60007CFF7FFEFFFFEFCFFFFBFFFF2FFFFFFF8C +:102C7000FFF3FFFBFFFEFFFFFFFFFFFFBFFFFFFFB5 +:102C8000FD1BFFFFFFFFFFFFFFFFFE7CFFFFFFFFBE +:102C9000EFFFFFFFFFFBBF7FFDFFFFFFFFFFFFFF1A +:102CA000DBFFFFFFFFFFFFFDFFFFF07FFFFFFFFFE9 +:102CB000FFFFFFFFFFFBFFDFFFFFFFFFFFFDBFFE8B +:102CC0007FFFFFFFFFFFFFFFFFEFFEFFBFFFFFFFE5 +:102CD000FFFFEFFAB5FFFFFFF7F7FFFFFFFFDFFB97 +:102CE000FCFFFFFEFF7FDFBFFFCBBFF9FE7F9FE74B +:102CF000F9FE7F97E1FE799FE7FDFE7FDFFE37FF5C +:102D0000FBDEDEBDEFF3FEFBAFEBFEFFFFCFFFFE12 +:102D1000FFBFFF8FFFEFFBFEFFBFE7F95E7FEFFB1B +:102D2000DAFFBFEFFBFEFFFD1FFFFFFFFFFFFFDF2F +:102D3000FFFF7FFFFFF7FB7FFFFFFFFFFC3FFFBFB2 +:102D4000EFFBFEFFBFEF7B7FBFEFFBFEFFB5EFFBAF +:102D5000BFFA7FFCFF3FCFF3FCFF3FCFBCFF3FEF4D +:102D6000F3FCFE3FCFFFEEEFFBFEFFBFEFFB6AD7AA +:102D7000B7FBF8FFB7EFBAFEFFBF7FE9FFF97E5F51 +:102D800097E5F9FE7FBFF97E5F9FE5FBFE5FB7FF2A +:102D9000A3FFF7FDFF7FDFF7FDFF5EF77DFF77DF26 +:102DA000F7FDFF7FFFD7FFFFFFFFFFFFFDDFFB7F8B +:102DB000FFFFEFFFFEFBFFFFBFFE8FFFDFF7FDFD15 +:102DC0007FDFF7FD3EDFF5BDFF7FDFF7FDF7FF9FFC +:102DD000FFFFFFFFFFFFFFFFFFFDFFBEFFFFFFFF46 +:102DE000FFFFFFFD3FFFDFF7FDFF7FDFF7FDFFCFB9 +:102DF00077FCFF5FDFF7FDFFF47FFFFFFFFFFFFFC3 +:102E0000FFFFFFFFFFFFFFFFFFFDFFFFFFEEFFFFE5 +:102E1000FFFFFFFFFFFFFFFFEDFBFFFFBFFFFFFF18 +:102E2000FFFFE9FFFFFFFFFFFFFBFFFFFFD3FFFFF8 +:102E3000BF3FFBFFFFFFFBF3FFFFFFFFFFFFFFFFB6 +:102E4000FFFFFFFFFFFEFFF7FFFFFFFF17FFFFFF83 +:102E5000DFFFFDFFFFFFFFFFDFDFFFFDFFFFDFF70E +:102E6000FF4FFFFFFFFFFFFFFFFFFFFEFFFFFFFD25 +:102E7000FFFFFFFFFEFF9FFFFFFFFFFFFFFFFFFFC3 +:102E8000FDFFFFFFFFFF7FFFFFFF7A3FFFFFFFFF19 +:102E9000FFFFFF7FFFFFFFFFFFFFFFFFFFFFFFF2CF +:102EA0007FFFFBFEFFBFEFF8FEFFBFFBFEFF8FECD7 +:102EB000FBFEFFBFF8F7FEFFBFEFFBFEFDBFCFEC51 +:102EC000FF3FEFDBF8FFBFCFFFF9FFFFBFFFFBFFC7 +:102ED000FFFFEFFBDFFFFFFFFFFFBFFFFFFFBBFFBA +:102EE000EFFBFEEFBFEEEBFBFEFFEFFEEEBFFEEBF8 +:102EF000FFEFFF17FF7EEBBBFEBFBEFBEF5BF7BD37 +:0A2F0000FBCFBFBFBBFB7ECCEFFF91 +:00000001FF + + * Copyright (C) 1999 BayCom GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that redistributions of source + * code retain the above copyright notice and this comment without + * modification. diff --git a/firmware/dabusb/firmware.HEX b/firmware/dabusb/firmware.HEX new file mode 100644 index 0000000..7c258df --- /dev/null +++ b/firmware/dabusb/firmware.HEX @@ -0,0 +1,649 @@ +:02000000215786 +:0300030002016691 +:03000B0002016689 +:0300130002016681 +:03001B0002016679 +:0300230002016671 +:03002B0002016669 +:0300330002030FB6 +:03003B0002016659 +:03004300020100B7 +:03004B0002016649 +:0300530002016641 +:03005B000204BDDF +:0300630002016730 +:03010000020C5A94 +:030104000201ED08 +:030108000202519F +:03010C0002027C70 +:030110000202E404 +:0101140032B8 +:0101180032B4 +:03011C000205FDDC +:03012000020000DA +:03012400020000D6 +:0301280002043C92 +:03012C0002046A60 +:03013000020000CA +:03013400020000C6 +:03013800020000C2 +:03013C00020000BE +:03014000020000BA +:03014400020000B6 +:03014800020000B2 +:03014C00020000AE +:03015000020000AA +:03015400020000A6 +:0A01570075817FE5826003020161FB +:0501610012076F21648C +:010166003266 +:0E016700C0D0C086C082C083C0E0907F97E009 +:0E0175004480F0907F69F0F0F0F0F0F0F0F0D0 +:0E018300F0F0F0F0F0F0F0F0F0F0F0F0F0F04E +:0E019100F0F0F0F0F0F0F0F0F0F0907F97E07A +:03019F00557FF099 +:0E01A200907F9AE030E423907F68F0F0F0F058 +:0E01B000F0F0F0F0F0F0F0F0F0F0F0F0F0F021 +:0E01BE00F0F0F0F0F0F0F0F0F0F0F0F0F0F013 +:0E01CC00E5D8C2E3F5D8D0E0D083D082D0864B +:0301DA00D0D03250 +:0801DD0075860090FFC37C054C +:0701E500A3E582458370F9D8 +:0101EC0022F0 +:0E01ED00C0E0C0F0C082C083C002C003C0D01A +:0E01FB0075D000C086758600E591C2E4F591CE +:0D020900908800E0F541907FAB7402F0900A +:090216007FAB7402F0E5326021B7 +:04021F007A007B00E6 +:0B022300C3EA9418EB64809480501232 +:0E022E00907F69F0F0F0F0F0F0F0F00ABA0006 +:02023C00010BB4 +:02023E0080E35B +:02024000D08666 +:0E024200D0D0D003D002D083D082D0F0D0E054 +:01025000327B +:0E025100C0E0C0F0C082C083C0D075D000C035 +:0E025F0086758600E591C2E4F591907FAB7440 +:04026D0004F0D08643 +:0B027100D0D0D083D082D0F0D0E0329B +:0E027C00C0E0C0F0C082C083C002C003C00456 +:0E028A00C005C006C007C000C001C0D075D0BE +:0D02980000C086758600E591C2E4F59190E6 +:0C02A5007FAB7408F0756E00756F0212DC +:0602B1001144757039755F +:0602B700710C75720212C9 +:0C02BD001175907FD6E4F075D820D08633 +:0E02C900D0D0D001D000D007D006D005D00490 +:0D02D700D003D002D083D082D0F0D0E0322E +:0E02E400C0E0C0F0C082C083C0D075D000C0A2 +:0E02F20086758600E591C2E4F591907FAB74AD +:0403000010F0D086A3 +:0B030400D0D0D083D082D0F0D0E03207 +:0E030F00C0E0C0F0C082C083C002C003C004C2 +:0E031D00C005C006C007C000C001C0D075D02A +:0C032B0000C086758600756E00756F02BC +:0703370012114475704075BE +:06033E00710C7572021241 +:0E0344001175907FD67402F0907FD67406F08B +:0503520075D810D086F3 +:0E035700D0D0D001D000D007D006D005D00401 +:0D036500D003D002D083D082D0F0D0E0329F +:0D037200907FA57480F0907FA6749AF01221 +:0C037F00101B907FA6E542F012101B90AE +:0D038B007FA6E543F012101B907FA5744083 +:01039800F074 +:010399002241 +:0D039A00907FA57480F0907FA6749AF012F9 +:0C03A700101B907FA6E544F012101B9084 +:0C03B3007FA6E545F012101B907FA6E528 +:0B03BF0046F012101B907FA57440F068 +:0103CA002210 +:0A03CB0075440275450075460012E6 +:0903D500039A75420375430012FE +:0203DE000372A8 +:0103E00022FA +:0C03E100908800E536F09088007410252C +:0903ED0036F01201DD75420175C4 +:0903F600431812037275440275EC +:0903FF00450075460012039A75D1 +:08040800420375434412037224 +:0104100022C9 +:0E041100C0E0C0F0C082C083C0D075D000C073 +:0E041F0086758600E591C2E4F591907FAA747F +:04042D0002F0D08683 +:0B043100D0D0D083D082D0F0D0E032D9 +:0E043C00C0E0C0F0C082C083C0D075D000C048 +:0E044A0086758600E591C2E4F591907FA97455 +:0704580004F0753001D086AD +:0B045F00D0D0D083D082D0F0D0E032AB +:0E046A00C0E0C0F0C082C083C0D075D000C01A +:0E04780086758600E591C2E4F591907FAA7426 +:0704860004F0753101D0867E +:0B048D00D0D0D083D082D0F0D0E0327D +:0E049800C0E0C0F0C082C083C0D075D000C0EC +:0C04A60086758600E591C2E5F591D086D0 +:0B04B200D0D0D083D082D0F0D0E03258 +:0E04BD00C0E0C0F0C082C083C0D075D000C0C7 +:0C04CB0086758600E591C2E7F591D086A9 +:0B04D700D0D0D083D082D0F0D0E03233 +:0C04E200907FEAE0FA8A20907F96E4F018 +:0104EE0022EB +:0704EF00907FEAE0FA8A2188 +:0104F60022E3 +:0E04F700901713E0FA901715E0FB74802AFAB4 +:0E05050074802BFBEA0303543FFCEAC423542A +:0E0513001FFA2CFAEB0303543FFCEBC42354F5 +:0B0521001FFB2CFB90170AE0FC60029F +:02052C007A0053 +:07052E0090170CE0FC6002D5 +:020535007B0049 +:0B053700EA2BFCC313F53A7544028B5D +:07054200458A4612039A7579 +:090549006E08756F001211447573 +:040552007047757108 +:080556000C757202121175858B +:05055E003A731211A028 +:010563002275 +:0E056400907F96E0FA907F9674806502F0908A +:0E0572007FEBE0FA907FEAE0FB907FEFE0FC89 +:0E0580003395E0FD8C057C00907FEEE0FE33AD +:0E058E0095E0FFEC2EFCED3FFD907FE9E0FED6 +:05059C00BE0102800316 +:0305A1000205F957 +:0605A400BC0121BD001E98 +:0E05AA00EAC40354F8FCEB25E0FD2C2400FC11 +:0E05B800E43417FD907EC0E0FE8C828D83F04F +:0205C600803182 +:0E05C800EAC40354F8FAEB25E0FB2AFA2400FB +:0E05D600FBE43417FC907EC0E0FD8B828C832A +:0E05E400F074012A2400FAE43417FB907EC163 +:0705F200E0FC8A828B83F01C +:0305F90075380151 +:0105FC0022DC +:0E05FD00C0E0C0F0C082C083C002C003C004D2 +:0E060B00C005C006C007C000C001C0D075D039 +:0D06190000C086758600E591C2E4F5919061 +:0D0626007FAA7401F0120564753700D086BC +:0E063300D0D0D001D000D007D006D005D00422 +:0D064100D003D002D083D082D0F0D0E032C0 +:0E064E00907FEBE0FA907FEAE0FB907FEEE019 +:0E065C00FC3395E0FD907F96E0FE907F967453 +:0E066A00806506F0907F007401F0EAC403542E +:0E067800F8FEEB25E0FB2EFE2400FBE4341719 +:0E068600FF8B828F83E0FB74012E2400FEE4C4 +:0E0694003417FF8E828F83E0FE907FE9E0FF37 +:0306A200BF810A0B +:0A06A500907F00EBF0907F01EEF073 +:0806AF00907FE9E0FBBB821A19 +:0306B700BA010C79 +:0C06BA00907F00E4F0907F01E4F0800BE2 +:0B06C600907F00E4F0907F0174B5F01D +:0806D100907FE9E0FBBB831BF5 +:0306D900BA010D56 +:0D06DC00907F007401F0907F01E4F0800B2E +:0B06E900907F00E4F0907F017412F09D +:0806F400907FE9E0FBBB841CD0 +:0306FC00BA010D33 +:0D06FF00907F007401F0907F01E4F0800C0A +:0C070C00907F007480F0907F017401F079 +:05071800907FB5ECF03C +:01071D0022B9 +:0C071E0075360D908800741DF0756B801E +:0A072A00756C3C1210E2756B8075CF +:090734006C0F1210E2756B807568 +:09073D006C061210E2756B807568 +:070746006C011210E27A00C1 +:03074D00BAFF00F0 +:02075000500A4D +:0A075200C0021201DDD0020A80F19E +:0A075C00756B80756C3C1210E2759D +:080766006B80756C0F1210E2AC +:01076E002268 +:0E076F00907FA1E4F0907FAF7401F0907F9234 +:0E077D007402F0758E3175892175880075C87B +:0E078B0000758D4075984075C04075870075EB +:0907990020007521007522007595 +:0507A200230075470073 +:0707A700C3E5479420501147 +:0D07AE00E5472400F582E43417F583E4F0FC +:0407BB00054780E886 +:0907BF00E4F540F53FE4F53CF5DA +:0707C8003BE4F53EF53D7531 +:0B07CF003200753700753900907F93F1 +:0E07DA00743CF0907F9C74FFF0907F967480CA +:0E07E800F0907F947470F0907F9D748FF0906D +:0E07F6007F97E4F0907F9574C2F0907F987426 +:0E08040028F0907F9E7428F0907FF0E4F09032 +:0E0812007FF1E4F0907FF2E4F0907FF3E4F0E9 +:0E082000907FF4E4F0907FF5E4F0907FF6E432 +:0E082E00F0907FF7E4F0907FF8E4F0907FF90F +:0E083C007438F0907FFA74A0F0907FFB74A0E7 +:0E084A00F0907FFC74A0F0907FFD74A0F09001 +:0E0858007FFE74A0F0907FFF74A0F0907FE010 +:0E0866007403F0907FE17401F0907FDD7480E8 +:0B087400F012124312071E7A007B00F6 +:09087F00C3EA941EEB940050172B +:0C088800908800E0F54790880BE0F547F1 +:09089400907F68F00ABA00010B24 +:02089D0080E0F9 +:0C089F001203E1907FD6E4F07A007B00A9 +:0D08AB008A048B05C3EA94E0EB942E501AEA +:0E08B800C002C003C004C0051201DDD005D08F +:0A08C60004D003D0020ABA00010BAF +:0208D00080D9CD +:0D08D200907FD67402F0907FD67406F090EF +:0E08DF007FDE7405F0907FDF7405F0907FAC33 +:0E08ED00E4F0907FAD7405F075A88075F810EA +:0D08FB00907FAE740BF0907FE27488F09057 +:0C0908007FAB7408F075E81175320175C2 +:0C0914003100753000C004C0051204F76B +:0A092000D005D004753400753501D0 +:0D092A00907FAE7403F08C02BA00028003CF +:03093700020A3F72 +:0C093A00853334907F9D748FF0907F9780 +:0E0946007408F0907F9D7488F0907F9AE0FA1C +:0C09540074055AF533907F9D748FF0906D +:0D0960007F977402F0907F9D7482F0E53364 +:0D096D0025E0FA907F9AE05405FB4AF5332F +:02097A00600C0F +:0C097C00907F96E0FA907F9674804AF01D +:0B098800756E00756F00C004C0051202 +:0E0993001144D005D004901713E0FA74802AA6 +:0609A100FAE533B404295D +:0309A700BAA000F3 +:0209AA005024D7 +:0D09AC00901713E004FB0B901713EBF09075 +:0E09B9001713E0FB901715F0C002C004C00534 +:0909C7001204F7D005D004D0029F +:0509D000E533B402262E +:0609D500C374049A5020D7 +:0D09DB00901713E0FA1A1A901713EAF09023 +:0D09E8001713E0FA901715F0C004C00512B7 +:0609F50004F7D005D00458 +:0509FB00E533B4081D06 +:040A0000E534701950 +:0A0A040074012535540FF5358535D2 +:0C0A0E0075757600C004C0051213FED000 +:030A1A0005D00400 +:050A1D00E533B4011DEA +:040A2200E53470192E +:0A0A2600E53524FF540FF535853542 +:0C0A300075757600C004C0051213FED0DE +:030A3C0005D004DE +:0E0A3F00C004C0051201DDD005D004907F96E2 +:0E0A4D00E0FA907F96747F5AF0907F977408BD +:0A0A5B00F0C3EC9400ED9402400893 +:080A6500907F96E0FA20E608FC +:080A6D00C3E49C74089D5013C2 +:0E0A7500907F96E0FA907F9674406502F07CC8 +:050A8300007D0080056C +:050A88000CBC00010D93 +:050A8D00E538B4010E84 +:0D0A9200C004C0051204F7D005D00475386B +:010A9F000056 +:070AA000E531700302092A91 +:0A0AA700907FC9E0FA7003020C2DE5 +:0E0AB100907F96E0FA907F9674806502F09038 +:090ABF007DC0E0FABA2C028003AC +:030AC800020B36E8 +:050ACB007532007B0004 +:030AD000BB640004 +:020AD300501CB5 +:0E0AD500C002C003C004C0051201DDD005D070 +:0D0AE30004D003D00290880FE0F5470B808F +:010AF000DF26 +:0D0AF100C002C004C00512071E1203E1126E +:0C0AFE0004F7D005D004D002756E00751E +:0D0B0A006F01C002C004C005121144D005E7 +:090B1700D004D00275704D757117 +:0B0B20000C757202C002C004C0051278 +:0B0B2B001175D005D004D002020C2D83 +:030B3600BA2A3B9D +:0D0B3900907F987420F0C002C004C0051227 +:0E0B460001DDD005D004D002907F987428F015 +:020B54007B0024 +:030B5600BB0A00D7 +:050B59004003020C2D19 +:0E0B5E00C002C003C004C0051201DDD005D0E6 +:080B6C0004D003D0020B80E26B +:030B7400BA2B1A7F +:080B7700907FC9E0FBBB4012B6 +:0E0B7F00C002C004C005121205D005D004D07B +:040B8D0002020C2D27 +:030B9100BA101F78 +:0E0B9400907F96E0FB907F9674806503F0C022 +:0E0BA20002C004C00512103DD005D004D002E0 +:030BB000020C2D07 +:030BB300BA111262 +:0E0BB600C002C004C00512106AD005D004D0E1 +:040BC40002020C2DF0 +:030BC800BA12124C +:0E0BCB00C002C004C00512108FD005D004D0A7 +:040BD90002020C2DDB +:030BDD00BA130B3D +:0B0BE000907DC1E0FB908800F0804297 +:030BEB00BA141128 +:0E0BEE00C002C004C0051211DDD005D004D035 +:030BFC0002802E46 +:030BFF00BA151D07 +:0C0C0200907DC1E0F575907DC2E0F576B4 +:0E0C0E00C002C004C0051213FED005D004D0F1 +:030C1C0002800E45 +:030C1F00BA160BF7 +:0B0C2200C004C0051213A3D005D004CD +:0B0C2D00907FC9E4F075310002092A35 +:010C38002299 +:070C3900535550454E4400E5 +:070C4000524553554D4500DC +:060C470020566F6C200036 +:0D0C4D004441425553422076312E30300094 +:0E0C5A00C0E0C0F0C082C083C002C003C0046E +:0E0C6800C005C006C007C000C001C0D075D0D6 +:0D0C760000C086758600E591C2E4F59190FE +:0E0C83007FAB7401F0907FE8E0FA907FE9E02B +:060C9100FBBB0002800322 +:030C9700020D3813 +:030C9A00BA801409 +:0E0C9D00907F007401F0907F01E4F0907FB52D +:060CAB007402F0020ECD00 +:050CB100BA820280037D +:030CB600020D1D0F +:080CB900907FECE0FCBC01009F +:020CC1004021D0 +:060CC300C374079C401BF6 +:0E0CC900EC24FF25E0FD24C6F582E4347FF51F +:0D0CD70083E0FD530501907F00EDF0802BC0 +:030CE400BC8100D0 +:020CE7004021AA +:060CE900C374879C401B50 +:0E0CEF00EC247F25E0FC24B6F582E4347FF58A +:0D0CFD0083E0FC530401907F00ECF08005C3 +:050D0A00907F00E4F001 +:0E0D0F00907F01E4F0907FB57402F0020ECDEB +:050D1D00BA8102800311 +:030D2200020EC5F9 +:0E0D2500907F00E4F0907F01E4F0907FB574C1 +:050D330002F0020ECDEC +:030D3800BB012DCF +:060D3B00BA0003020ECD18 +:030D4100BA0211E2 +:0D0D4400755900C002C003120EF0D003D09C +:040D510002020ECDBF +:050D5500BA2102800339 +:030D5A00020ECDB9 +:0B0D5D00753701907FC5E4F0020ECD59 +:030D6800BB031FAB +:060D6B00BA0003020ECDE8 +:050D7100BA020280033C +:030D7600020ECD9D +:0D0D7900755901C002C003120EF0D003D066 +:040D860002020ECD8A +:030D8A00BB065451 +:050D8D00BA80028003A2 +:030D9200020EC589 +:080D9500907FEBE0FCBC0115AE +:0C0D9D007CFB7D0F8D067F00907FD4EE64 +:090DA900F0907FD5ECF0020ECDB4 +:0A0DB200907FEBE0FCBC020280031E +:030DBC00020EC55F +:0A0DBF00907FEAE0FCBC0002800314 +:030DC900020EC552 +:0C0DCC007C3B7D0F8D067F00907FD4EEF5 +:090DD800F0907FD5ECF0020ECD85 +:060DE100BB0703020EC572 +:030DE700BB081036 +:0D0DEA00AC48907F00ECF0907FB57401F0F4 +:030DF700020ECD1C +:030DFA00BB093101 +:050DFD00BA00028003B2 +:030E0200020EC518 +:0E0E0500907FEAE0FCC374019C5003020EC50E +:080E1300907FEAE0FCBC000A3C +:0A0E1B00901721E4F0901722E4F094 +:090E2500907FEAE0F548020ECDD1 +:030E2E00BB0A27D5 +:050E3100BA81028003FC +:030E3600020EC5E4 +:0E0E3900907FECE0FA2420FAE43417FC8A8261 +:0E0E47008C83E0FA907F00F0907FB57401F08C +:030E5500020ECDBD +:050E5800BB0B0280034A +:030E5D00020EA9D9 +:0D0E6000901720E4F0907FECE0FABA011A40 +:080E6D00907FEDE0FABA0012DB +:0E0E7500907FEAE0FA901721F0C0031204E229 +:040E8300D0038046D2 +:080E8700907FECE0FABA023E94 +:080E8F00907FEDE0FABA003695 +:0D0E9700C0031204EFD003907FEAE0FA9050 +:050EA4001722F080247C +:050EA900BB12028017DE +:050EAE00BB8102800D74 +:050EB300BB8302800872 +:050EB800BB8202800373 +:030EBD00BB8405EE +:050EC00012064E80083F +:080EC500907FB47403F0800675 +:060ECD00907FB47402F0F6 +:020ED300D086C7 +:0E0ED500D0D0D001D000D007D006D005D00478 +:0D0EE300D003D002D083D082D0F0D0E03216 +:0B0EF000907FECE0F55AC39401401D18 +:070EFB00C37407955A40166D +:0D0F0200E55A24FF25E0FA24C6F582E43408 +:090F0F007FF583AA59EAF0802263 +:070F1800C3E55A9481401B60 +:070F1F00C37487955A4014CA +:0D0F2600E55A24FF25E0FA24B6F582E434F4 +:070F33007FF583AA59EAF0E3 +:010F3A002294 +:0E0F3B000902BA000301004000090400000092 +:0E0F49000101000009240100013D0001010C1E +:0E0F570024020110070002030000000D240612 +:0E0F650003010215000300030000092403022B +:0E0F7300010100010009240304020300030031 +:0E0F8100092403050306000100090401000015 +:0E0F8F00010200000904010101010200000737 +:0E0F9D002401020101000B24020102021001D6 +:0E0FAB0080BB00090588050001010000072534 +:0E0FB900010000000009040200020000000018 +:0E0FC7000705820240000007050202400000FC +:0E0FD50009040201030000000007058202402B +:0E0FE30000000705020240000009058905A074 +:0A0FF1000101000000FFFFFFFF00F8 +:0E0FFB00120100010000004047059999000115 +:0E10090000000001000000000000000902BA13 +:0410170000030100D1 +:02101B007A0059 +:03101D00BA050011 +:02102000501767 +:08102200907FA5E0FB30E00522 +:05102A00900001800DA3 +:0A102F00C0021201DDD0020A80E4C5 +:0310390090000123 +:01103C002291 +:0E103D00907DC1E0F9A3E0FAA3E0FB7C007D0A +:04104B007EEB6012C6 +:0E104F0089828A83E0A3A982AA838C828D8382 +:04105D00F00CDBEECA +:08106100907DC3E0907FB9F01F +:011069002264 +:0E106A00907DC1E0F9A3E0FAA3E0FB7CC47D19 +:041078007DEB60E5C7 +:0E107C008C828D83E00C89828A83F0A3A98286 +:04108A00AA83DBEE6C +:01108E00223F +:0E108F00907FA57480F00586907DC1E00586F7 +:0E109D00A3F012101B907FA60586A3A3E0F916 +:0510AB006016A305869C +:0D10B000907FA60586E0A30586F0C0011222 +:0610BD00101BD001D9ED6B +:0610C300907FA57440F0CF +:0110C9002204 +:0810CA009088027401F07A0025 +:0310D200BAFF0062 +:0210D500500ABF +:0A10D700C0021201DDD0020A80F110 +:0110E10022EC +:0510E200E56BB4C0083D +:0810E700908803E56CF080061F +:0610EF00908802E56CF0A0 +:0410F5007A007B0002 +:0B10F900C3EA9432EB6480948050073F +:051104000ABA00010B16 +:0211090080EE76 +:01110B0022C1 +:0A110C00908803E56DF005397A00C4 +:03111600BA2800F4 +:02111900500381 +:03111B000A80F84F +:05111E00E539B41008E2 +:0811230090880274C0F0800EF8 +:05112B00E539B42009C4 +:091130009088027480F07539000A +:021139007A003A +:03113B00BA2800CF +:02113E0050035C +:031140000A80F82A +:011143002289 +:04114400E56F6002F1 +:0211480080071E +:07114A007A007539008005F1 +:051151007A4075391021 +:09115600E56E2AFAE56E2539F573 +:0A115F003990880274802AF07A00AB +:08116900C3EA648094A850035E +:031171000A80F5FC +:011174002258 +:06117500AA70AB71AC7220 +:0C117B008A828B838CF01214EEFD601849 +:0D1187008D6DC002C003C00412110CD00415 +:09119400D003D0020ABA00010BDD +:02119D0080DCF4 +:01119F00222D +:0D11A000E573C4540FFA53020FC374099A8B +:0211AD005006EA +:0611AF0074372AFB8004E6 +:0411B50074302AFB6D +:0C11B9008B6DC00312110CD003AA7353FD +:0811C500020FC374099A5006E1 +:0611CD0074372AFB8004C8 +:0411D30074302AFB4F +:0511D7008B6D12110CEC +:0111DC0022F0 +:0711DD00907DC3E0FA600FF2 +:0C11E400907DC1E0F56E907DC2E0F56FDB +:0311F00012114495 +:0C11F300907DFFE4F07570C475717D758F +:0511FF007201121175E0 +:0112040022C7 +:021205007A0469 +:03120700BA4000EA +:02120A0050365C +:0E120C00EA24C0F582E4347DF583E0FB7C002B +:03121A00BC08000D +:02121D0050205F +:06121F008B05ED30E70B2A +:0B122500907F967442F074C3F08008C4 +:08123000907F96E4F07481F058 +:07123800EB25E0FB0C80DB5D +:03123F000A80C55D +:011242002289 +:041243007A007BEFC3 +:03124700BA1000DA +:02124A00502032 +:0E124C0074112BFB2400FCE43418FD8C828D01 +:0E125A0083E4F0EA2400F582E43419F583E41D +:04126800F00A80DB2D +:01126C00225F +:0E126D0074F82400F58274033484F583E4F0F1 +:0E127B0074F92400F58274033484F583E4F0E2 +:0E12890074FA2400F58274033484F583E4F0D3 +:0E12970074FB2400F58274033484F583E4F0C4 +:0E12A50074FF2400F58274033484F583E4F0B2 +:0112B3002218 +:0E12B4001203CB12126D7AC07B877C0174018D +:0E12C2002AFDE43BFE8C078A828B838CF0743D +:0E12D000011214BF2DFAE43EFB8F048D828EB6 +:0E12DE00838FF074061214BF74012AFDE43BE6 +:0E12EC00FE8C078A828B838CF0E41214BF7490 +:0E12FA00012DFAE43EFB8F048D828E838FF06F +:0E130800740B1214BF74012AFDE43BFE8C0727 +:0E1316008A828B838CF074081214BF74012D30 +:0E132400FAE43EFB8F048D828E838FF07401FD +:0E1332001214BF2AFDE43BFE8C078A828B83D7 +:0E1340008CF0E41214BF74012DFAE43EFB8F12 +:0E134E00048D828E838FF074031214BF7D0015 +:03135C00BD0600CB +:02135F0050122A +:0B1361008A828B838CF00ABA00010B1B +:07136C00E41214BF0D80E93B +:0D1373008A828B838CF0E5741214BF74F92C +:0E1380002400F58274033484F583740FF07436 +:0E138E00FE2400F58274033484F5837401F0AC +:06139C001203E11204F748 +:0113A2002228 +:0D13A300907DC1E0FA2400FBE43419FC90B9 +:0E13B0007DC2E0FD8B828C83F075F011EAA403 +:0313BE00FA7B00B7 +:0313C100BB10005E +:0213C4005024B3 +:0E13C600EA2400FCE43418FDEB2CFCE43DFDB1 +:0E13D40074042B24C0F582E4347DF583E0FE22 +:0813E2008C828D83F00B80D793 +:0E13EA00EA2400FAE43418FB74102AF582E4B9 +:0513F8003BF583E4F069 +:0113FD0022CD +:0413FE00E57660022E +:02140200801652 +:0C140400740F5575FA8A752400F582E417 +:0A1410003419F583E0F5741212B4EC +:0A141A001210CA756E00756F001203 +:0614240011447570B9755A +:06142A007114757202123C +:0B1430001175E576B402047401800120 +:01143B00E4CC +:03143C00FA700F34 +:0C143F0074012575F573C0021211A0D0D5 +:03144B0002800A12 +:0A144E00857573C0021211A0D002D0 +:0C145800756E00756F01C002121144D0C7 +:0414640002EA701A0E +:0D14680075F011E575A4FA2400FAE43418BB +:09147500FB8A708B717572011283 +:04147E00117580362E +:021482007A00EE +:03148400BA10009B +:02148700502FE4 +:0D148900EA2400F582E43419F583E0FBE568 +:0414960075B5031B0A +:0E149A0075F011EAA4FB2400FBE43418FC8B6F +:0914A800708C71757201C0021212 +:0414B1001175D002DF +:0314B5000A80CCDE +:0114B8002211 +:0614B90050726F67200075 +:0E14BF00C8C0E0C8C0E0E5F0600B14600F1478 +:0714CD00601114601280158C +:0714D400D0E0A882F6800EB3 +:0514DB00D0E0F08009E3 +:0414E000D0E08005D3 +:0514E400D0E0A882F237 +:0414E900C8D0E0C8BF +:0114ED0022DC +:0E14EE00C8C0E0E5F0600D14600F14600F142C +:0614FC00601074FF800F78 +:05150200A882E6800A4A +:03150700E080077A +:04150A00E4938003E3 +:03150E00A882E2CE +:04151100F8D0E0C866 +:0115150022B3 +:00000001FF + + * Copyright (C) 1999 BayCom GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that redistributions of source + * code retain the above copyright notice and this comment without + * modification. -- cgit v0.10.2 From fb54be8755d386008bfadb7fc8ff89451fa3a9c9 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Fri, 27 Jun 2008 19:50:40 +0530 Subject: vicam: use request_firmware() Although it wasn't actually using ihex records before, we use the Intel HEX record format for this firmware -- because that gives us a simple way to split it into separate chunks internally as we need, without loading each part as a separate file. Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 17f542d..40d053e 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include "usbvideo.h" // #define VICAM_DEBUG @@ -70,284 +72,6 @@ #define VICAM_HEADER_SIZE 64 -/* Not sure what all the bytes in these char - * arrays do, but they're necessary to make - * the camera work. - */ - -static unsigned char setup1[] = { - 0xB6, 0xC3, 0x1F, 0x00, 0x02, 0x64, 0xE7, 0x67, - 0xFD, 0xFF, 0x0E, 0xC0, 0xE7, 0x09, 0xDE, 0x00, - 0x8E, 0x00, 0xC0, 0x09, 0x40, 0x03, 0xC0, 0x17, - 0x44, 0x03, 0x4B, 0xAF, 0xC0, 0x07, 0x00, 0x00, - 0x4B, 0xAF, 0x97, 0xCF, 0x00, 0x00 -}; - -static unsigned char setup2[] = { - 0xB6, 0xC3, 0x03, 0x00, 0x03, 0x64, 0x18, 0x00, - 0x00, 0x00 -}; - -static unsigned char setup3[] = { - 0xB6, 0xC3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00 -}; - -static unsigned char setup4[] = { - 0xB6, 0xC3, 0x8F, 0x06, 0x02, 0x64, 0xE7, 0x07, - 0x00, 0x00, 0x08, 0xC0, 0xE7, 0x07, 0x00, 0x00, - 0x3E, 0xC0, 0xE7, 0x07, 0x54, 0x01, 0xAA, 0x00, - 0xE7, 0x07, 0xC8, 0x05, 0xB6, 0x00, 0xE7, 0x07, - 0x42, 0x01, 0xD2, 0x00, 0xE7, 0x07, 0x7C, 0x00, - 0x16, 0x00, 0xE7, 0x07, 0x56, 0x00, 0x18, 0x00, - 0xE7, 0x07, 0x06, 0x00, 0x92, 0xC0, 0xE7, 0x07, - 0x00, 0x00, 0x1E, 0xC0, 0xE7, 0x07, 0xFF, 0xFF, - 0x22, 0xC0, 0xE7, 0x07, 0x04, 0x00, 0x24, 0xC0, - 0xE7, 0x07, 0xEC, 0x27, 0x28, 0xC0, 0xE7, 0x07, - 0x16, 0x01, 0x8E, 0x00, 0xE7, 0x87, 0x01, 0x00, - 0x0E, 0xC0, 0x97, 0xCF, 0xD7, 0x09, 0x00, 0xC0, - 0xE7, 0x77, 0x01, 0x00, 0x92, 0xC0, 0x09, 0xC1, - 0xE7, 0x09, 0xFE, 0x05, 0x24, 0x01, 0xE7, 0x09, - 0x04, 0x06, 0x26, 0x01, 0xE7, 0x07, 0x07, 0x00, - 0x92, 0xC0, 0xE7, 0x05, 0x00, 0xC0, 0xC0, 0xDF, - 0x97, 0xCF, 0x17, 0x00, 0x57, 0x00, 0x17, 0x02, - 0xD7, 0x09, 0x00, 0xC0, 0xE7, 0x77, 0x01, 0x00, - 0x92, 0xC0, 0x0A, 0xC1, 0xE7, 0x57, 0xFF, 0xFF, - 0xFA, 0x05, 0x0D, 0xC0, 0xE7, 0x57, 0x00, 0x00, - 0xFA, 0x05, 0x0F, 0xC0, 0x9F, 0xAF, 0xC6, 0x00, - 0xE7, 0x05, 0x00, 0xC0, 0xC8, 0x05, 0xC1, 0x05, - 0xC0, 0x05, 0xC0, 0xDF, 0x97, 0xCF, 0x27, 0xDA, - 0xFA, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x0B, 0x06, - 0x73, 0xCF, 0x9F, 0xAF, 0x78, 0x01, 0x9F, 0xAF, - 0x1A, 0x03, 0x6E, 0xCF, 0xE7, 0x09, 0xFC, 0x05, - 0x24, 0x01, 0xE7, 0x09, 0x02, 0x06, 0x26, 0x01, - 0xE7, 0x07, 0x07, 0x00, 0x92, 0xC0, 0xE7, 0x09, - 0xFC, 0x05, 0xFE, 0x05, 0xE7, 0x09, 0x02, 0x06, - 0x04, 0x06, 0xE7, 0x09, 0x00, 0x06, 0xFC, 0x05, - 0xE7, 0x09, 0xFE, 0x05, 0x00, 0x06, 0x27, 0xDA, - 0xFA, 0x05, 0xE7, 0x57, 0x01, 0x00, 0xFA, 0x05, - 0x02, 0xCA, 0x04, 0xC0, 0x97, 0xCF, 0x9F, 0xAF, - 0x66, 0x05, 0x97, 0xCF, 0xE7, 0x07, 0x40, 0x00, - 0x02, 0x06, 0xC8, 0x09, 0xFC, 0x05, 0x9F, 0xAF, - 0xDA, 0x02, 0x97, 0xCF, 0xCF, 0x17, 0x02, 0x00, - 0xEF, 0x57, 0x81, 0x00, 0x09, 0x06, 0x9F, 0xA0, - 0xB6, 0x01, 0xEF, 0x57, 0x80, 0x00, 0x09, 0x06, - 0x9F, 0xA0, 0x40, 0x02, 0xEF, 0x57, 0x01, 0x00, - 0x0B, 0x06, 0x9F, 0xA0, 0x46, 0x03, 0xE7, 0x07, - 0x01, 0x00, 0x0A, 0xC0, 0x46, 0xAF, 0x47, 0xAF, - 0x9F, 0xAF, 0x40, 0x02, 0xE7, 0x07, 0x2E, 0x00, - 0x0A, 0xC0, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06, - 0x97, 0xCF, 0x00, 0x0E, 0x01, 0x00, 0xC0, 0x57, - 0x51, 0x00, 0x9F, 0xC0, 0x9E, 0x02, 0xC0, 0x57, - 0x50, 0x00, 0x20, 0xC0, 0xC0, 0x57, 0x55, 0x00, - 0x12, 0xC0, 0xC0, 0x57, 0x56, 0x00, 0x9F, 0xC0, - 0x72, 0x02, 0x9F, 0xCF, 0xD6, 0x02, 0xC1, 0x0B, - 0x08, 0x06, 0x01, 0xD0, 0x6F, 0x90, 0x08, 0x06, - 0xC0, 0x07, 0x08, 0x00, 0xC1, 0x0B, 0x08, 0x06, - 0x9F, 0xAF, 0x28, 0x05, 0x97, 0xCF, 0x2F, 0x0E, - 0x02, 0x00, 0x08, 0x06, 0xC0, 0x07, 0x08, 0x00, - 0xC1, 0x0B, 0x08, 0x06, 0x9F, 0xAF, 0x28, 0x05, - 0x9F, 0xCF, 0xD6, 0x02, 0x2F, 0x0E, 0x02, 0x00, - 0x09, 0x06, 0xEF, 0x87, 0x80, 0x00, 0x09, 0x06, - 0x9F, 0xCF, 0xD6, 0x02, 0xEF, 0x67, 0x7F, 0xFF, - 0x09, 0x06, 0xE7, 0x67, 0xFF, 0xFD, 0x22, 0xC0, - 0xE7, 0x67, 0xEF, 0xFF, 0x24, 0xC0, 0xE7, 0x87, - 0x10, 0x00, 0x28, 0xC0, 0x9F, 0xAF, 0xB8, 0x05, - 0xE7, 0x87, 0xE0, 0x21, 0x24, 0xC0, 0x9F, 0xAF, - 0xA8, 0x05, 0xE7, 0x87, 0x08, 0x00, 0x24, 0xC0, - 0xE7, 0x67, 0xDF, 0xFF, 0x24, 0xC0, 0xC8, 0x07, - 0x0A, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xC1, 0x07, - 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0x9F, 0xAF, - 0xB8, 0x05, 0xC0, 0x07, 0x9E, 0x00, 0x9F, 0xAF, - 0x44, 0x05, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0, - 0xC0, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01, - 0x24, 0xC0, 0xC0, 0x77, 0x00, 0x02, 0x0F, 0xC1, - 0xE7, 0x67, 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x67, - 0xF7, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x08, 0x00, - 0x24, 0xC0, 0x08, 0xDA, 0x5E, 0xC1, 0xEF, 0x07, - 0x80, 0x00, 0x09, 0x06, 0x97, 0xCF, 0xEF, 0x07, - 0x01, 0x00, 0x0A, 0x06, 0x97, 0xCF, 0xEF, 0x07, - 0x00, 0x00, 0x0B, 0x06, 0xEF, 0x07, 0x00, 0x00, - 0x0A, 0x06, 0xEF, 0x67, 0x7F, 0xFF, 0x09, 0x06, - 0xEF, 0x07, 0x00, 0x00, 0x0D, 0x06, 0xE7, 0x67, - 0xEF, 0xFF, 0x28, 0xC0, 0xE7, 0x67, 0x17, 0xD8, - 0x24, 0xC0, 0xE7, 0x07, 0x00, 0x00, 0x1E, 0xC0, - 0xE7, 0x07, 0xFF, 0xFF, 0x22, 0xC0, 0x97, 0xCF, - 0xC8, 0x07, 0x0E, 0x06, 0x9F, 0xAF, 0xDA, 0x02, - 0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07, - 0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0x0E, 0x06, - 0xF4, 0x05, 0xE7, 0x07, 0xD6, 0x02, 0xF8, 0x05, - 0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80, - 0x50, 0xAF, 0x97, 0xCF, 0x2F, 0x0C, 0x02, 0x00, - 0x07, 0x06, 0x2F, 0x0C, 0x04, 0x00, 0x06, 0x06, - 0xE7, 0x07, 0x00, 0x00, 0xF2, 0x05, 0xE7, 0x07, - 0x10, 0x00, 0xF6, 0x05, 0xE7, 0x07, 0xE2, 0x05, - 0xF4, 0x05, 0xE7, 0x07, 0xCE, 0x02, 0xF8, 0x05, - 0xC8, 0x07, 0xF2, 0x05, 0xC1, 0x07, 0x00, 0x80, - 0x51, 0xAF, 0x97, 0xCF, 0x9F, 0xAF, 0x66, 0x04, - 0x9F, 0xAF, 0x1A, 0x03, 0x59, 0xAF, 0x97, 0xCF, - 0xC0, 0x07, 0x0E, 0x00, 0xC1, 0x0B, 0x0C, 0x06, - 0x41, 0xD1, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, - 0x3C, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0x68, 0x00, - 0xC0, 0x07, 0x3B, 0x00, 0x9F, 0xAF, 0x44, 0x05, - 0x6F, 0x00, 0x0C, 0x06, 0x68, 0x00, 0xE0, 0x07, - 0x04, 0x01, 0xE8, 0x0B, 0x0A, 0x06, 0xE8, 0x07, - 0x00, 0x00, 0xE0, 0x07, 0x00, 0x02, 0xE0, 0x07, - 0xEC, 0x01, 0xE0, 0x07, 0xFC, 0xFF, 0x97, 0xCF, - 0xE7, 0x07, 0xFF, 0xFF, 0xFA, 0x05, 0xEF, 0x07, - 0x00, 0x00, 0x0B, 0x06, 0xE7, 0x07, 0x0E, 0x06, - 0x24, 0x01, 0xE7, 0x07, 0x0E, 0x06, 0xFE, 0x05, - 0xE7, 0x07, 0x40, 0x00, 0x26, 0x01, 0xE7, 0x07, - 0x40, 0x00, 0x04, 0x06, 0xE7, 0x07, 0x07, 0x00, - 0x92, 0xC0, 0x97, 0xCF, 0xEF, 0x07, 0x02, 0x00, - 0x0B, 0x06, 0x9F, 0xAF, 0x78, 0x01, 0xEF, 0x77, - 0x80, 0x00, 0x07, 0x06, 0x9F, 0xC0, 0x14, 0x04, - 0xEF, 0x77, 0x01, 0x00, 0x07, 0x06, 0x37, 0xC0, - 0xEF, 0x77, 0x01, 0x00, 0x0D, 0x06, 0x0F, 0xC1, - 0xEF, 0x07, 0x01, 0x00, 0x0D, 0x06, 0xC0, 0x07, - 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00, 0x9F, 0xAF, - 0x28, 0x05, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07, - 0x02, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07, - 0xFF, 0x4F, 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07, - 0x38, 0x00, 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x77, - 0x03, 0x00, 0x02, 0xC1, 0x08, 0xDA, 0x75, 0xC1, - 0xC1, 0x77, 0x01, 0x00, 0x0A, 0xC1, 0xC0, 0x07, - 0x01, 0x00, 0xC1, 0x07, 0x02, 0x00, 0x9F, 0xAF, - 0x28, 0x05, 0xEF, 0x07, 0x01, 0x00, 0x06, 0x06, - 0x2C, 0xCF, 0xC0, 0x07, 0x01, 0x00, 0xC1, 0x07, - 0x04, 0x00, 0x9F, 0xAF, 0x28, 0x05, 0xEF, 0x07, - 0x00, 0x00, 0x06, 0x06, 0x22, 0xCF, 0xEF, 0x07, - 0x00, 0x00, 0x0D, 0x06, 0xEF, 0x57, 0x01, 0x00, - 0x06, 0x06, 0x1B, 0xC0, 0xC0, 0x07, 0x01, 0x00, - 0xC1, 0x07, 0x01, 0x00, 0x9F, 0xAF, 0x28, 0x05, - 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07, 0x30, 0x00, - 0x9F, 0xAF, 0x28, 0x05, 0xC8, 0x07, 0xFF, 0x4F, - 0x9F, 0xAF, 0xA8, 0x05, 0xC0, 0x07, 0x38, 0x00, - 0x9F, 0xAF, 0x44, 0x05, 0xC1, 0x67, 0x03, 0x00, - 0xC1, 0x57, 0x03, 0x00, 0x02, 0xC0, 0x08, 0xDA, - 0x73, 0xC1, 0xC0, 0x07, 0x02, 0x00, 0xC1, 0x07, - 0x12, 0x00, 0xEF, 0x57, 0x00, 0x00, 0x06, 0x06, - 0x02, 0xC0, 0xC1, 0x07, 0x23, 0x00, 0x9F, 0xAF, - 0x28, 0x05, 0xC0, 0x07, 0x14, 0x00, 0xC1, 0x0B, - 0xEA, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, - 0x3E, 0x00, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x09, - 0xE4, 0x05, 0xFA, 0x05, 0x27, 0xD8, 0xFA, 0x05, - 0xE7, 0x07, 0x0E, 0x06, 0xFC, 0x05, 0xE7, 0x07, - 0x4E, 0x06, 0x00, 0x06, 0xE7, 0x07, 0x40, 0x00, - 0x02, 0x06, 0x9F, 0xAF, 0x66, 0x05, 0x9F, 0xAF, - 0xC6, 0x00, 0x97, 0xCF, 0xC1, 0x0B, 0xE2, 0x05, - 0x41, 0xD0, 0x01, 0xD2, 0xC1, 0x17, 0x23, 0x00, - 0x9F, 0xAF, 0xDC, 0x04, 0xC0, 0x07, 0x04, 0x00, - 0xC1, 0x0B, 0xE3, 0x05, 0x9F, 0xAF, 0x28, 0x05, - 0xC0, 0x07, 0x06, 0x00, 0xC1, 0x09, 0xE6, 0x05, - 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x07, 0x00, - 0xC1, 0x09, 0xE6, 0x05, 0xC1, 0xD1, 0x9F, 0xAF, - 0x28, 0x05, 0xC0, 0x07, 0x0B, 0x00, 0xC1, 0x09, - 0xE8, 0x05, 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, - 0x0C, 0x00, 0xC1, 0x09, 0xE8, 0x05, 0xC1, 0xD1, - 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0D, 0x00, - 0xC1, 0x07, 0x09, 0x00, 0x9F, 0xAF, 0x28, 0x05, - 0xC0, 0x07, 0x03, 0x00, 0xC1, 0x07, 0x32, 0x00, - 0x9F, 0xAF, 0x28, 0x05, 0xC0, 0x07, 0x0F, 0x00, - 0xC1, 0x07, 0x00, 0x00, 0x9F, 0xAF, 0x28, 0x05, - 0x97, 0xCF, 0xE7, 0x67, 0xFF, 0xD9, 0x24, 0xC0, - 0xC8, 0x07, 0x0A, 0x00, 0x40, 0x00, 0xC0, 0x67, - 0x00, 0x02, 0x27, 0x80, 0x24, 0xC0, 0xE7, 0x87, - 0x00, 0x04, 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xF9, - 0x24, 0xC0, 0x01, 0xD2, 0x08, 0xDA, 0x72, 0xC1, - 0xE7, 0x87, 0x00, 0x20, 0x24, 0xC0, 0x97, 0xCF, - 0x27, 0x00, 0x1E, 0xC0, 0xE7, 0x87, 0xFF, 0x00, - 0x22, 0xC0, 0xE7, 0x67, 0x7F, 0xFF, 0x24, 0xC0, - 0xE7, 0x87, 0x80, 0x00, 0x24, 0xC0, 0xE7, 0x87, - 0x80, 0x00, 0x24, 0xC0, 0x97, 0xCF, 0x9F, 0xAF, - 0x0A, 0x05, 0x67, 0x00, 0x1E, 0xC0, 0xE7, 0x67, - 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00, - 0x24, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0, - 0x97, 0xCF, 0x9F, 0xAF, 0x0A, 0x05, 0xE7, 0x67, - 0x00, 0xFF, 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, - 0x24, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0, - 0xC1, 0x09, 0x20, 0xC0, 0xE7, 0x87, 0x00, 0x01, - 0x24, 0xC0, 0x97, 0xCF, 0xC0, 0x07, 0x40, 0x00, - 0xC8, 0x09, 0xFC, 0x05, 0xE7, 0x67, 0x00, 0xFF, - 0x22, 0xC0, 0xE7, 0x67, 0xFF, 0xFE, 0x24, 0xC0, - 0xE7, 0x67, 0xBF, 0xFF, 0x24, 0xC0, 0xE7, 0x67, - 0xBF, 0xFF, 0x24, 0xC0, 0x00, 0xDA, 0xE8, 0x09, - 0x20, 0xC0, 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0, - 0xE7, 0x87, 0x40, 0x00, 0x24, 0xC0, 0x00, 0xDA, - 0xE8, 0x09, 0x20, 0xC0, 0x6D, 0xC1, 0xE7, 0x87, - 0x00, 0x01, 0x24, 0xC0, 0x97, 0xCF, 0xE7, 0x07, - 0x32, 0x00, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80, - 0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0xE7, 0x07, - 0x20, 0x4E, 0x12, 0xC0, 0xE7, 0x77, 0x00, 0x80, - 0x12, 0xC0, 0x7C, 0xC0, 0x97, 0xCF, 0x09, 0x02, - 0x19, 0x00, 0x01, 0x01, 0x00, 0x80, 0x96, 0x09, - 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static unsigned char setup5[] = { - 0xB6, 0xC3, 0x2F, 0x01, 0x03, 0x64, 0x0E, 0x00, - 0x14, 0x00, 0x1A, 0x00, 0x20, 0x00, 0x26, 0x00, - 0x4A, 0x00, 0x64, 0x00, 0x6A, 0x00, 0x92, 0x00, - 0x9A, 0x00, 0xA0, 0x00, 0xB2, 0x00, 0xB8, 0x00, - 0xBE, 0x00, 0xC2, 0x00, 0xC8, 0x00, 0xCE, 0x00, - 0xDC, 0x00, 0xDA, 0x00, 0xE2, 0x00, 0xE0, 0x00, - 0xE8, 0x00, 0xE6, 0x00, 0xEE, 0x00, 0xEC, 0x00, - 0xF2, 0x00, 0xF8, 0x00, 0x02, 0x01, 0x0A, 0x01, - 0x0E, 0x01, 0x12, 0x01, 0x1E, 0x01, 0x22, 0x01, - 0x28, 0x01, 0x2C, 0x01, 0x32, 0x01, 0x36, 0x01, - 0x44, 0x01, 0x50, 0x01, 0x5E, 0x01, 0x72, 0x01, - 0x76, 0x01, 0x7A, 0x01, 0x80, 0x01, 0x88, 0x01, - 0x8C, 0x01, 0x94, 0x01, 0x9C, 0x01, 0xA0, 0x01, - 0xA4, 0x01, 0xAA, 0x01, 0xB0, 0x01, 0xB4, 0x01, - 0xBA, 0x01, 0xD0, 0x01, 0xDA, 0x01, 0xF6, 0x01, - 0xFA, 0x01, 0x02, 0x02, 0x34, 0x02, 0x3C, 0x02, - 0x44, 0x02, 0x4A, 0x02, 0x50, 0x02, 0x56, 0x02, - 0x74, 0x02, 0x78, 0x02, 0x7E, 0x02, 0x84, 0x02, - 0x8A, 0x02, 0x88, 0x02, 0x90, 0x02, 0x8E, 0x02, - 0x94, 0x02, 0xA2, 0x02, 0xA8, 0x02, 0xAE, 0x02, - 0xB4, 0x02, 0xBA, 0x02, 0xB8, 0x02, 0xC0, 0x02, - 0xBE, 0x02, 0xC4, 0x02, 0xD0, 0x02, 0xD4, 0x02, - 0xE0, 0x02, 0xE6, 0x02, 0xEE, 0x02, 0xF8, 0x02, - 0xFC, 0x02, 0x06, 0x03, 0x1E, 0x03, 0x24, 0x03, - 0x28, 0x03, 0x30, 0x03, 0x2E, 0x03, 0x3C, 0x03, - 0x4A, 0x03, 0x4E, 0x03, 0x54, 0x03, 0x58, 0x03, - 0x5E, 0x03, 0x66, 0x03, 0x6E, 0x03, 0x7A, 0x03, - 0x86, 0x03, 0x8E, 0x03, 0x96, 0x03, 0xB2, 0x03, - 0xB8, 0x03, 0xC6, 0x03, 0xCC, 0x03, 0xD4, 0x03, - 0xDA, 0x03, 0xE8, 0x03, 0xF4, 0x03, 0xFC, 0x03, - 0x04, 0x04, 0x20, 0x04, 0x2A, 0x04, 0x32, 0x04, - 0x36, 0x04, 0x3E, 0x04, 0x44, 0x04, 0x42, 0x04, - 0x48, 0x04, 0x4E, 0x04, 0x4C, 0x04, 0x54, 0x04, - 0x52, 0x04, 0x5A, 0x04, 0x5E, 0x04, 0x62, 0x04, - 0x68, 0x04, 0x74, 0x04, 0x7C, 0x04, 0x80, 0x04, - 0x88, 0x04, 0x8C, 0x04, 0x94, 0x04, 0x9A, 0x04, - 0xA2, 0x04, 0xA6, 0x04, 0xAE, 0x04, 0xB4, 0x04, - 0xC0, 0x04, 0xCC, 0x04, 0xD8, 0x04, 0x2A, 0x05, - 0x46, 0x05, 0x6C, 0x05, 0x00, 0x00 -}; - /* rvmalloc / rvfree copied from usbvideo.c * * Not sure why these are not yet non-statics which I can reference through @@ -464,28 +188,28 @@ static int send_control_msg(struct vicam_camera *cam, static int initialize_camera(struct vicam_camera *cam) { - const struct { - u8 *data; - u32 size; - } firmware[] = { - { .data = setup1, .size = sizeof(setup1) }, - { .data = setup2, .size = sizeof(setup2) }, - { .data = setup3, .size = sizeof(setup3) }, - { .data = setup4, .size = sizeof(setup4) }, - { .data = setup5, .size = sizeof(setup5) }, - { .data = setup3, .size = sizeof(setup3) }, - { .data = NULL, .size = 0 } - }; - - int err, i; - - for (i = 0, err = 0; firmware[i].data && !err; i++) { - memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size); + int err; + const struct ihex_binrec *rec; + const struct firmware *fw; + + err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev); + if (err) { + printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n", + err); + return err; + } + + for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { + memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len)); err = send_control_msg(cam, 0xff, 0, 0, - cam->cntrlbuf, firmware[i].size); + cam->cntrlbuf, be16_to_cpu(rec->len)); + if (err) + break; } + release_firmware(fw); + return err; } @@ -1226,3 +950,4 @@ module_exit(usb_vicam_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("vicam/firmware.fw"); diff --git a/firmware/Makefile b/firmware/Makefile index 331d10c..5ed36ae 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -63,6 +63,7 @@ fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ # whiteheat_loader_debug.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw +fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) diff --git a/firmware/WHENCE b/firmware/WHENCE index 8784565..b14b86c 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -265,3 +265,13 @@ Licence: Distributable * modification. -------------------------------------------------------------------------- + +Driver: USB_VICAM -- USB 3com HomeConnect (aka vicam) + +File: vicam/firmware.fw + +Licence: Unknown + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/vicam/firmware.H16 b/firmware/vicam/firmware.H16 new file mode 100644 index 0000000..cac0cba --- /dev/null +++ b/firmware/vicam/firmware.H16 @@ -0,0 +1,7 @@ +:0026000000B6C31F000264E767FDFF0EC0E709DE008E00C0094003C01744034BAFC00700004BAF97CF00001D +:000A000000B6C30300036418000000FB +:0008000000B6C301000664000014 +:0696000000B6C38F060264E707000008C0E70700003EC0E7075401AA00E707C805B600E7074201D200E7077C001600E70756001800E707060092C0E70700001EC0E707FFFF22C0E707040024C0E707EC2728C0E70716018E00E78701000EC097CFD70900C0E777010092C009C1E709FE052401E70904062601E707070092C0E70500C0C0DF97CF170057001702D70900C0E777010092C00AC1E757FFFFFA050DC0E7570000FA050FC09FAFC600E70500C0C805C105C005C0DF97CF27DAFA05EF0701000B0673CF9FAF78019FAF1A036ECFE709FC052401E70902062601E707070092C0E709FC05FE05E70902060406E7090006FC05E709FE05000627DAFA05E7570100FA0502CA04C097CF9FAF660597CFE70740000206C809FC059FAFDA0297CFCF170200EF57810009069FA0B601EF57800009069FA04002EF5701000B069FA04603E70701000AC046AF47AF9FAF4002E7072E000AC0EF878000090697CF000E0100C05751009FC09E02C057500020C0C057550012C0C05756009FC072029FCFD602C10B080601D06F900806C0070800C10B08069FAF280597CF2F0E02000806C0070800C10B08069FAF28059FCFD6022F0E02000906EF87800009069FCFD602EF677FFF0906E767FFFD22C0E767EFFF24C0E787100028C09FAFB805E787E02124C09FAFA805E787080024C0E767DFFF24C0C8070A00C0070000C10701009FAF28059FAFB805C0079E009FAF4405E767FFFE24C0C00920C0E787000124C0C07700020FC1E767F7FF24C0E767F7FF24C0E787080024C008DA5EC1EF078000090697CFEF0701000A0697CFEF0700000B06EF0700000A06EF677FFF0906EF0700000D06E767EFFF28C0E76717D824C0E70700001EC0E707FFFF22C097CFC8070E069FAFDA02E7070000F205E7071000F605E7070E06F405E707D602F805C807F205C107008050AF97CF2F0C020007062F0C04000606E7070000F205E7071000F605E707E205F405E707CE02F805C807F205C107008051AF97CF9FAF66049FAF1A0359AF97CFC0070E00C10B0C0641D19FAF2805C0073C009FAF44056800C0073B009FAF44056F000C066800E0070401E80B0A06E8070000E0070002E007EC01E007FCFF97CFE707FFFFFA05EF0700000B06E7070E062401E7070E06FE05E70740002601E70740000406E707070092C097CFEF0702000B069FAF7801EF77800007069FC01404EF770100070637C0EF7701000D060FC1EF0701000D06C0070200C10730009FAF2805C0070100C10702009FAF2805C807FF4F9FAFA805C00738009FAF4405C177030002C108DA75C1C17701000AC1C0070100C10702009FAF2805EF07010006062CCFC0070100C10704009FAF2805EF070000060622CFEF0700000D06EF57010006061BC0C0070100C10701009FAF2805C0070200C10730009FAF2805C807FF4F9FAFA805C00738009FAF4405C1670300C157030002C008DA73C1C0070200C1071200EF570000060602C0C10723009FAF2805C0071400C10BEA059FAF2805C0073E009FAF0A05E709E405FA0527D8FA05E7070E06FC05E7074E060006E707400002069FAF66059FAFC60097CFC10BE20541D001D2C11723009FAFDC04C0070400C10BE3059FAF2805C0070600C109E6059FAF2805C0070700C109E605C1D19FAF2805C0070B00C109E8059FAF2805C0070C00C109E805C1D19FAF2805C0070D00C10709009FAF2805C0070300C10732009FAF2805C0070F00C10700009FAF280597CFE767FFD924C0C8070A004000C0670002278024C0E787000424C0E767FFF924C001D208DA72C1E787002024C097CF27001EC0E787FF0022C0E7677FFF24C0E787800024C0E787800024C097CF9FAF0A0567001EC0E767BFFF24C0E787400024C0E787400024C097CF9FAF0A05E76700FF22C0E767FFFE24C0E767FFFE24C0C10920C0E787000124C097CFC0074000C809FC05E76700FF22C0E767FFFE24C0E767BFFF24C0E767BFFF24C000DAE80920C0E787400024C0E787400024C000DAE80920C06DC1E787000124C097CFE707320012C0E777008012C07CC097CFE707204E12C0E777008012C07CC097CF0902190001010080960904000001000000000705810240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A1 +:0136000000B6C32F0103640E0014001A00200026004A0064006A0092009A00A000B200B800BE00C200C800CE00DC00DA00E200E000E800E600EE00EC00F200F80002010A010E0112011E01220128012C0132013601440150015E01720176017A01800188018C0194019C01A001A401AA01B001B401BA01D001DA01F601FA01020234023C0244024A0250025602740278027E0284028A02880290028E029402A202A802AE02B402BA02B802C002BE02C402D002D402E002E602EE02F802FC0206031E032403280330032E033C034A034E03540358035E0366036E037A0386038E039603B203B803C603CC03D403DA03E803F403FC03040420042A04320436043E044404420448044E044C04540452045A045E046204680474047C04800488048C0494049A04A204A604AE04B404C004CC04D8042A0546056C0500005E +:0008000000B6C301000664000014 +:0000000001FF -- cgit v0.10.2 From 5b9ea9322605da09d6f7119f03f71cc52b044911 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Thu, 3 Jul 2008 17:00:23 +0530 Subject: edgeport: use request_firmware() Version number provided in first HEX record. Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 06b52f4..2fd449b 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include @@ -56,26 +58,6 @@ #define DRIVER_AUTHOR "Greg Kroah-Hartman and David Iacovelli" #define DRIVER_DESC "Edgeport USB Serial Driver" -/* First, the latest boot code - for first generation edgeports */ -#define IMAGE_ARRAY_NAME BootCodeImage_GEN1 -#define IMAGE_VERSION_NAME BootCodeImageVersion_GEN1 -#include "io_fw_boot.h" /* the bootloader firmware to download to a device, if it needs it */ - -/* for second generation edgeports */ -#define IMAGE_ARRAY_NAME BootCodeImage_GEN2 -#define IMAGE_VERSION_NAME BootCodeImageVersion_GEN2 -#include "io_fw_boot2.h" /* the bootloader firmware to download to a device, if it needs it */ - -/* Then finally the main run-time operational code - for first generation edgeports */ -#define IMAGE_ARRAY_NAME OperationalCodeImage_GEN1 -#define IMAGE_VERSION_NAME OperationalCodeImageVersion_GEN1 -#include "io_fw_down.h" /* Define array OperationalCodeImage[] */ - -/* for second generation edgeports */ -#define IMAGE_ARRAY_NAME OperationalCodeImage_GEN2 -#define IMAGE_VERSION_NAME OperationalCodeImageVersion_GEN2 -#include "io_fw_down2.h" /* Define array OperationalCodeImage[] */ - #define MAX_NAME_LEN 64 #define CHASE_TIMEOUT (5*HZ) /* 5 seconds */ @@ -256,9 +238,9 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer, int writeLength); static void send_more_port_data (struct edgeport_serial *edge_serial, struct edgeport_port *edge_port); -static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data); +static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data); static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data); -static int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data); +static int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data); static void get_manufacturing_desc (struct edgeport_serial *edge_serial); static void get_boot_desc (struct edgeport_serial *edge_serial); static void load_application_firmware (struct edgeport_serial *edge_serial); @@ -283,37 +265,41 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial) { __u32 BootCurVer; __u32 BootNewVer; - __u8 BootMajorVersion; - __u8 BootMinorVersion; - __le16 BootBuildNumber; - __u8 *BootImage; - __u32 BootSize; - struct edge_firmware_image_record *record; - unsigned char *firmware; + __u8 BootMajorVersion; + __u8 BootMinorVersion; + __u16 BootBuildNumber; + __u32 Bootaddr; + const struct ihex_binrec *rec; + const struct firmware *fw; + const char *fw_name; int response; - switch (edge_serial->product_info.iDownloadFile) { case EDGE_DOWNLOAD_FILE_I930: - BootMajorVersion = BootCodeImageVersion_GEN1.MajorVersion; - BootMinorVersion = BootCodeImageVersion_GEN1.MinorVersion; - BootBuildNumber = cpu_to_le16(BootCodeImageVersion_GEN1.BuildNumber); - BootImage = &BootCodeImage_GEN1[0]; - BootSize = sizeof( BootCodeImage_GEN1 ); + fw_name = "edgeport/boot.fw"; break; case EDGE_DOWNLOAD_FILE_80251: - BootMajorVersion = BootCodeImageVersion_GEN2.MajorVersion; - BootMinorVersion = BootCodeImageVersion_GEN2.MinorVersion; - BootBuildNumber = cpu_to_le16(BootCodeImageVersion_GEN2.BuildNumber); - BootImage = &BootCodeImage_GEN2[0]; - BootSize = sizeof( BootCodeImage_GEN2 ); + fw_name = "edgeport/boot2.fw"; break; default: return; } + response = request_ihex_firmware(&fw, fw_name, + &edge_serial->serial->dev->dev); + if (response) { + printk(KERN_ERR "Failed to load image \"%s\" err %d\n", + fw_name, response); + return; + } + + rec = (const struct ihex_binrec *)fw->data; + BootMajorVersion = rec->data[0]; + BootMinorVersion = rec->data[1]; + BootBuildNumber = (rec->data[2] << 8) | rec->data[3]; + // Check Boot Image Version BootCurVer = (edge_serial->boot_descriptor.MajorVersion << 24) + (edge_serial->boot_descriptor.MinorVersion << 16) + @@ -321,7 +307,7 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial) BootNewVer = (BootMajorVersion << 24) + (BootMinorVersion << 16) + - le16_to_cpu(BootBuildNumber); + BootBuildNumber; dbg("Current Boot Image version %d.%d.%d", edge_serial->boot_descriptor.MajorVersion, @@ -334,30 +320,30 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial) edge_serial->boot_descriptor.MajorVersion, edge_serial->boot_descriptor.MinorVersion, le16_to_cpu(edge_serial->boot_descriptor.BuildNumber), - BootMajorVersion, - BootMinorVersion, - le16_to_cpu(BootBuildNumber)); - + BootMajorVersion, BootMinorVersion, BootBuildNumber); dbg("Downloading new Boot Image"); - firmware = BootImage; - - for (;;) { - record = (struct edge_firmware_image_record *)firmware; - response = rom_write (edge_serial->serial, le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len), &record->Data[0]); + for (rec = ihex_next_binrec(rec); rec; + rec = ihex_next_binrec(rec)) { + Bootaddr = be32_to_cpu(rec->addr); + response = rom_write(edge_serial->serial, + Bootaddr >> 16, + Bootaddr & 0xFFFF, + be16_to_cpu(rec->len), + &rec->data[0]); if (response < 0) { - dev_err(&edge_serial->serial->dev->dev, "rom_write failed (%x, %x, %d)\n", le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len)); - break; - } - firmware += sizeof (struct edge_firmware_image_record) + le16_to_cpu(record->Len); - if (firmware >= &BootImage[BootSize]) { + dev_err(&edge_serial->serial->dev->dev, + "rom_write failed (%x, %x, %d)\n", + Bootaddr >> 16, Bootaddr & 0xFFFF, + be16_to_cpu(rec->len)); break; } } } else { dbg("Boot Image -- already up to date"); } + release_firmware(fw); } @@ -447,9 +433,6 @@ static void dump_product_info(struct edgeport_product_info *product_info) dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, product_info->BootMinorVersion, le16_to_cpu(product_info->BootBuildNumber)); - dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, - product_info->FirmwareMinorVersion, - le16_to_cpu(product_info->FirmwareBuildNumber)); dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], product_info->ManufactureDescDate[1], product_info->ManufactureDescDate[2]+1900); @@ -480,14 +463,8 @@ static void get_product_info(struct edgeport_serial *edge_serial) // check if this is 2nd generation hardware if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) { - product_info->FirmwareMajorVersion = OperationalCodeImageVersion_GEN2.MajorVersion; - product_info->FirmwareMinorVersion = OperationalCodeImageVersion_GEN2.MinorVersion; - product_info->FirmwareBuildNumber = cpu_to_le16(OperationalCodeImageVersion_GEN2.BuildNumber); product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_80251; } else { - product_info->FirmwareMajorVersion = OperationalCodeImageVersion_GEN1.MajorVersion; - product_info->FirmwareMinorVersion = OperationalCodeImageVersion_GEN1.MinorVersion; - product_info->FirmwareBuildNumber = cpu_to_le16(OperationalCodeImageVersion_GEN1.BuildNumber); product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930; } @@ -2130,7 +2107,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, __u8 l * If successful returns the number of bytes written, otherwise it returns * a negative error number of the problem. ****************************************************************************/ -static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data) +static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data) { int result; __u16 current_length; @@ -2175,7 +2152,7 @@ static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u * If successful returns the number of bytes written, otherwise it returns * a negative error number of the problem. ****************************************************************************/ -static int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data) +static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data) { int result; __u16 current_length; @@ -2761,32 +2738,23 @@ static void get_boot_desc (struct edgeport_serial *edge_serial) ****************************************************************************/ static void load_application_firmware (struct edgeport_serial *edge_serial) { - struct edge_firmware_image_record *record; - unsigned char *firmware; - unsigned char *FirmwareImage; - int ImageSize; + const struct ihex_binrec *rec; + const struct firmware *fw; + const char *fw_name; + const char *fw_info; int response; - + __u32 Operaddr; + __u16 build; switch (edge_serial->product_info.iDownloadFile) { case EDGE_DOWNLOAD_FILE_I930: - dbg("downloading firmware version (930) %d.%d.%d", - OperationalCodeImageVersion_GEN1.MajorVersion, - OperationalCodeImageVersion_GEN1.MinorVersion, - OperationalCodeImageVersion_GEN1.BuildNumber); - firmware = &OperationalCodeImage_GEN1[0]; - FirmwareImage = &OperationalCodeImage_GEN1[0]; - ImageSize = sizeof(OperationalCodeImage_GEN1); + fw_info = "downloading firmware version (930)"; + fw_name = "edgeport/down.fw"; break; case EDGE_DOWNLOAD_FILE_80251: - dbg("downloading firmware version (80251) %d.%d.%d", - OperationalCodeImageVersion_GEN2.MajorVersion, - OperationalCodeImageVersion_GEN2.MinorVersion, - OperationalCodeImageVersion_GEN2.BuildNumber); - firmware = &OperationalCodeImage_GEN2[0]; - FirmwareImage = &OperationalCodeImage_GEN2[0]; - ImageSize = sizeof(OperationalCodeImage_GEN2); + fw_info = "downloading firmware version (80251)"; + fw_name = "edgeport/down2.fw"; break; case EDGE_DOWNLOAD_FILE_NONE: @@ -2797,16 +2765,36 @@ static void load_application_firmware (struct edgeport_serial *edge_serial) return; } + response = request_ihex_firmware(&fw, fw_name, + &edge_serial->serial->dev->dev); + if (response) { + printk(KERN_ERR "Failed to load image \"%s\" err %d\n", + fw_name, response); + return; + } + + rec = (const struct ihex_binrec *)fw->data; + build = (rec->data[2] << 8) | rec->data[3]; + + dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build); + + edge_serial->product_info.FirmwareMajorVersion = fw->data[0]; + edge_serial->product_info.FirmwareMinorVersion = fw->data[1]; + edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build); - for (;;) { - record = (struct edge_firmware_image_record *)firmware; - response = sram_write (edge_serial->serial, le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len), &record->Data[0]); + for (rec = ihex_next_binrec(rec); rec; + rec = ihex_next_binrec(rec)) { + Operaddr = be32_to_cpu(rec->addr); + response = sram_write(edge_serial->serial, + Operaddr >> 16, + Operaddr & 0xFFFF, + be16_to_cpu(rec->len), + &rec->data[0]); if (response < 0) { - dev_err(&edge_serial->serial->dev->dev, "sram_write failed (%x, %x, %d)\n", le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len)); - break; - } - firmware += sizeof (struct edge_firmware_image_record) + le16_to_cpu(record->Len); - if (firmware >= &FirmwareImage[ImageSize]) { + dev_err(&edge_serial->serial->dev->dev, + "sram_write failed (%x, %x, %d)\n", + Operaddr >> 16, Operaddr & 0xFFFF, + be16_to_cpu(rec->len)); break; } } @@ -2817,6 +2805,7 @@ static void load_application_firmware (struct edgeport_serial *edge_serial) USB_REQUEST_ION_EXEC_DL_CODE, 0x40, 0x4000, 0x0001, NULL, 0, 3000); + release_firmware(fw); return; } @@ -2903,6 +2892,10 @@ static int edge_startup (struct usb_serial *serial) // dbg("set_configuration 1"); // usb_set_configuration (dev, 1); } + dbg(" FirmwareMajorVersion %d.%d.%d", + edge_serial->product_info.FirmwareMajorVersion, + edge_serial->product_info.FirmwareMinorVersion, + le16_to_cpu(edge_serial->product_info.FirmwareBuildNumber)); /* we set up the pointers to the endpoints in the edge_open function, * as the structures aren't created yet. */ @@ -3115,6 +3108,10 @@ module_exit(edgeport_exit); MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("edgeport/boot.fw"); +MODULE_FIRMWARE("edgeport/boot2.fw"); +MODULE_FIRMWARE("edgeport/down.fw"); +MODULE_FIRMWARE("edgeport/down2.fw"); module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/drivers/usb/serial/io_fw_boot.h b/drivers/usb/serial/io_fw_boot.h deleted file mode 100644 index 099fafa..0000000 --- a/drivers/usb/serial/io_fw_boot.h +++ /dev/null @@ -1,556 +0,0 @@ -//************************************************************** -//* Edgeport/4 Binary Image -//* Generated by HEX2C v1.06 -//* Copyright (C) 1998 Inside Out Networks, 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. -//************************************************************** - - -//Image structure definition -#if !defined(DEFINED_EDGE_FIRMWARE_IMAGE_RECORD) -#define DEFINED_EDGE_FIRMWARE_IMAGE_RECORD - struct edge_firmware_image_record { - __le16 ExtAddr; - __le16 Addr; - __le16 Len; - unsigned char Data[0]; - } __attribute__ ((packed)); - - struct edge_firmware_version_info { - unsigned char MajorVersion; - unsigned char MinorVersion; - unsigned short BuildNumber; - }; - -#endif - -#if !defined(IMAGE_ARRAY_NAME) -#define IMAGE_ARRAY_NAME FirmwareImage -#define IMAGE_VERSION_NAME FirmwareImageVersion -#endif - -static unsigned char IMAGE_ARRAY_NAME[] = { - -// Segment #1, Start Address 00ff0000, Length 6 -0xff,0x00,0x00,0x00,0x06,0x00, - 0x02, 0x00, 0x80, 0x02, 0x00, 0x03, - -// Segment #2, Start Address 00ff000b, Length 3 -0xff,0x00,0x0b,0x00,0x03,0x00, - 0x02, 0x00, 0x0b, - -// Segment #3, Start Address 00ff0013, Length 3 -0xff,0x00,0x13,0x00,0x03,0x00, - 0x02, 0x01, 0xb8, - -// Segment #4, Start Address 00ff001b, Length 3 -0xff,0x00,0x1b,0x00,0x03,0x00, - 0x02, 0x00, 0x1b, - -// Segment #5, Start Address 00ff0023, Length 3 -0xff,0x00,0x23,0x00,0x03,0x00, - 0x02, 0x00, 0x23, - -// Segment #6, Start Address 00ff002b, Length 3 -0xff,0x00,0x2b,0x00,0x03,0x00, - 0x02, 0x00, 0x2b, - -// Segment #7, Start Address 00ff0033, Length 3 -0xff,0x00,0x33,0x00,0x03,0x00, - 0x02, 0x00, 0x33, - -// Segment #8, Start Address 00ff003b, Length 3 -0xff,0x00,0x3b,0x00,0x03,0x00, - 0x02, 0x00, 0x3b, - -// Segment #9, Start Address 00ff0043, Length 3 -0xff,0x00,0x43,0x00,0x03,0x00, - 0x02, 0x01, 0xbd, - -// Segment #10, Start Address 00ff004b, Length 3 -0xff,0x00,0x4b,0x00,0x03,0x00, - 0x02, 0x01, 0xd0, - -// Segment #11, Start Address 00ff0053, Length 3 -0xff,0x00,0x53,0x00,0x03,0x00, - 0x02, 0x01, 0x21, - -// Segment #12, Start Address 00ff007b, Length 3 -0xff,0x00,0x7b,0x00,0x03,0x00, - 0x02, 0x00, 0x7b, - -// Segment #13, Start Address 00ff0080, Length 358 -0xff,0x00,0x80,0x00,0x66,0x01, - 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x3f, 0xf2, 0x7e, 0xf8, 0x00, 0x23, 0x7e, 0x00, 0x01, 0x7e, 0x10, - 0x00, 0x12, 0x07, 0x5f, 0x69, 0x20, 0x00, 0x0a, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x05, 0x75, 0x90, - 0x0d, 0x80, 0x03, 0x75, 0x90, 0x1d, 0xd2, 0xb5, 0x7e, 0x00, 0x00, 0xa5, 0xd8, 0xfd, 0x75, 0xa8, - 0x00, 0x75, 0xb1, 0x00, 0xa9, 0xd5, 0x87, 0xca, 0x29, 0x12, 0x09, 0xcc, 0x12, 0x09, 0xa0, 0xf5, - 0x09, 0x7a, 0xa1, 0x20, 0x12, 0x01, 0xe6, 0xda, 0x29, 0xa9, 0xd0, 0xc7, 0x7e, 0x00, 0x05, 0x7a, - 0x01, 0xf1, 0x75, 0xe1, 0x10, 0xa9, 0xd7, 0xf4, 0xa9, 0xd7, 0xe4, 0xa5, 0xd8, 0xf1, 0x75, 0xf1, - 0x00, 0x75, 0xe1, 0x3f, 0x75, 0xa2, 0x03, 0x75, 0xa3, 0x00, 0x75, 0xc0, 0x00, 0x75, 0xc1, 0x00, - 0xa9, 0xd1, 0xb1, 0xa9, 0xd0, 0xb1, 0xa9, 0xd5, 0xd3, 0xd2, 0xaf, 0xe4, 0x7e, 0x04, 0x28, 0x00, - 0x8d, 0xef, 0x1b, 0x04, 0x78, 0xfa, 0x04, 0xa9, 0x34, 0xd3, 0x03, 0x30, 0xe0, 0xee, 0xbe, 0x24, - 0x00, 0x00, 0x78, 0x05, 0x63, 0x90, 0x30, 0x80, 0xe3, 0xb2, 0x95, 0x80, 0xdf, 0xbe, 0xb0, 0x02, - 0x22, 0xc0, 0xd0, 0xa9, 0x20, 0xdf, 0x0f, 0xa9, 0x31, 0xdf, 0x03, 0x02, 0x01, 0xb5, 0x75, 0x08, - 0x01, 0x12, 0x08, 0x33, 0x80, 0xfe, 0x75, 0x08, 0xfe, 0x12, 0x08, 0x33, 0x75, 0xa8, 0x00, 0x7e, - 0xb3, 0x3f, 0xf2, 0x30, 0xe0, 0x4b, 0x30, 0x01, 0x46, 0xc2, 0x92, 0x7e, 0x24, 0x80, 0x00, 0x7e, - 0x11, 0x09, 0x74, 0x08, 0x19, 0xb2, 0x00, 0x10, 0x74, 0x0e, 0x19, 0xb2, 0x00, 0x04, 0x2e, 0x24, - 0x01, 0x00, 0xa5, 0xd9, 0xed, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0xe4, 0xd5, 0xe0, 0xfd, - 0x09, 0xb2, 0x00, 0x08, 0x20, 0xe0, 0x0a, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, 0x18, 0x80, - 0xeb, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xe4, 0x43, 0x90, 0x30, 0xd2, 0xaa, 0x80, 0x05, 0xd2, - 0xaa, 0x43, 0x90, 0x34, 0xd2, 0xaf, 0xa9, 0xd1, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x11, - 0xdf, 0x03, 0xa9, 0xd2, 0xdf, 0x75, 0x08, 0xff, 0x12, 0x08, 0x33, 0xc0, 0xd1, 0xca, 0x02, 0xff, - 0xca, 0x06, 0x83, 0x00, 0x32, 0xd0, 0xd0, 0x32, 0xc2, 0x8b, 0xc2, 0xaa, 0x32, 0x75, 0x08, 0x08, - 0x12, 0x08, 0x33, 0xa9, 0xc0, 0xb1, 0xa9, 0xc5, 0xd3, 0xa9, 0xc6, 0xd3, 0xa9, 0xd2, 0xb1, 0x32, - 0xca, 0xb8, 0x75, 0x08, 0x02, 0x12, 0x08, 0x33, 0xe5, 0xc0, 0x54, 0x03, 0x68, 0x05, 0x12, 0x01, - 0xee, 0x80, 0xf5, 0xda, 0xb8, 0x32, - -// Segment #14, Start Address 00ff1bca, Length 1 -0xff,0x00,0xca,0x1b,0x01,0x00, - 0x00, - -// Segment #15, Start Address 00ff01e6, Length 1613 -0xff,0x00,0xe6,0x01,0x4d,0x06, - 0xe4, 0x7a, 0xb3, 0x3f, 0xf1, 0x02, 0x02, 0x63, 0xca, 0x0b, 0xca, 0x1b, 0xca, 0x2b, 0xca, 0x3b, - 0xca, 0x4b, 0xca, 0x5b, 0xca, 0x6b, 0xca, 0x7b, 0xca, 0xeb, 0xc0, 0xf1, 0x7e, 0xb3, 0x01, 0x2b, - 0xb4, 0x00, 0x02, 0x80, 0x19, 0xb4, 0x01, 0x16, 0x30, 0xc0, 0x08, 0x75, 0xf1, 0x00, 0x12, 0x02, - 0x4d, 0x80, 0x1f, 0x30, 0xc1, 0x1c, 0x75, 0xf1, 0x00, 0x12, 0x02, 0xde, 0x80, 0x14, 0x30, 0xc1, - 0x08, 0x75, 0xf1, 0x00, 0x12, 0x02, 0xde, 0x80, 0x09, 0x30, 0xc0, 0x06, 0x75, 0xf1, 0x00, 0x12, - 0x02, 0x4d, 0xd0, 0xf1, 0xda, 0xeb, 0xda, 0x7b, 0xda, 0x6b, 0xda, 0x5b, 0xda, 0x4b, 0xda, 0x3b, - 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0xc2, 0xc0, 0x7e, 0xb3, 0x01, 0x2b, 0xb4, 0x02, 0x07, - 0x12, 0x02, 0x6f, 0x02, 0x02, 0x63, 0x22, 0xb4, 0x01, 0xfc, 0x02, 0x02, 0xa9, 0x7e, 0x00, 0x00, - 0x7a, 0x03, 0x01, 0x2b, 0x7a, 0x03, 0x01, 0x2c, 0x22, 0x7e, 0xb3, 0x01, 0x23, 0x54, 0x60, 0x60, - 0x05, 0xb4, 0x40, 0x15, 0x80, 0x13, 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x05, 0x0c, 0x75, 0x08, 0x71, - 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, 0x26, 0xf5, 0x8f, 0x22, 0x75, 0xf6, 0x00, 0x22, 0xbe, 0x57, - 0x01, 0x29, 0x28, 0x04, 0x7e, 0x57, 0x01, 0x29, 0x7a, 0x0f, 0x01, 0x2e, 0x7a, 0x57, 0x01, 0x32, - 0x02, 0x02, 0xa9, 0x7e, 0xef, 0x01, 0x2e, 0x7e, 0xf7, 0x01, 0x32, 0x7e, 0x07, 0x01, 0x32, 0x4d, - 0x00, 0x68, 0x21, 0x7e, 0x00, 0x00, 0x7e, 0xeb, 0xb0, 0xf5, 0xf3, 0xa3, 0xa5, 0x08, 0x1b, 0xf4, - 0x68, 0x04, 0xa5, 0xb8, 0x08, 0xf0, 0x7a, 0xef, 0x01, 0x2e, 0x7a, 0xf7, 0x01, 0x32, 0x75, 0x08, - 0x06, 0x12, 0x08, 0x33, 0x7a, 0x01, 0xf6, 0x22, 0xc2, 0xc1, 0x75, 0x08, 0x03, 0x12, 0x08, 0x33, - 0xa9, 0x36, 0xe2, 0x16, 0xe5, 0xf5, 0x54, 0xc0, 0x68, 0x07, 0xa9, 0xd7, 0xf4, 0xa9, 0x27, 0xf4, - 0xfc, 0x53, 0xe1, 0x3f, 0x43, 0xf2, 0x88, 0x02, 0x03, 0x55, 0x7e, 0xb3, 0x01, 0x2c, 0xb4, 0x02, - 0x0f, 0xa9, 0xd4, 0xe4, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x01, 0x2c, 0x7a, 0xb3, 0x01, 0x2b, 0x22, - 0xb4, 0x01, 0x39, 0x7e, 0x21, 0xe6, 0x7c, 0x32, 0x7e, 0x13, 0x01, 0x2d, 0x2c, 0x21, 0x7a, 0x23, - 0x01, 0x2d, 0x7e, 0x00, 0x00, 0x2e, 0x04, 0x01, 0x34, 0xe5, 0xe3, 0x7a, 0x09, 0xb0, 0x0b, 0x04, - 0xa5, 0xdb, 0xf6, 0xa9, 0xd4, 0xe4, 0x75, 0x08, 0x70, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, 0x2d, - 0x7e, 0xa3, 0x01, 0x2a, 0xbc, 0xab, 0x78, 0x03, 0x12, 0x03, 0xec, 0x22, 0x02, 0x07, 0x55, 0xe5, - 0xe6, 0xb4, 0x08, 0x65, 0xa9, 0xc4, 0xe2, 0x7e, 0x01, 0xe3, 0x7e, 0x11, 0xe3, 0x7e, 0x31, 0xe3, - 0x7e, 0x21, 0xe3, 0x7e, 0x51, 0xe3, 0x7e, 0x41, 0xe3, 0x7e, 0x71, 0xe3, 0x7e, 0x61, 0xe3, 0x7a, - 0x0f, 0x01, 0x23, 0x7a, 0x1f, 0x01, 0x27, 0x75, 0x08, 0x04, 0x12, 0x08, 0x33, 0x7a, 0x01, 0x08, - 0x12, 0x08, 0x33, 0x7a, 0x11, 0x08, 0x12, 0x08, 0x33, 0x7a, 0x21, 0x08, 0x12, 0x08, 0x33, 0x7a, - 0x31, 0x08, 0x12, 0x08, 0x33, 0x7a, 0x41, 0x08, 0x12, 0x08, 0x33, 0x7a, 0x51, 0x08, 0x12, 0x08, - 0x33, 0x7a, 0x61, 0x08, 0x12, 0x08, 0x33, 0x7a, 0x71, 0x08, 0x12, 0x08, 0x33, 0xa9, 0xd4, 0xe4, - 0xa9, 0xd7, 0xf4, 0xa9, 0xc6, 0xe2, 0x12, 0x03, 0xc0, 0x22, 0x6d, 0x00, 0x7e, 0x14, 0x01, 0x02, - 0x7a, 0x07, 0x01, 0x32, 0x7a, 0x03, 0x01, 0x2d, 0x7e, 0xb3, 0x01, 0x23, 0x20, 0xe7, 0x0f, 0x7a, - 0x23, 0x01, 0x2c, 0x7a, 0x33, 0x01, 0x2b, 0xbe, 0x07, 0x01, 0x29, 0x68, 0x09, 0x22, 0x7a, 0x33, - 0x01, 0x2c, 0x7a, 0x23, 0x01, 0x2b, 0x7e, 0xb3, 0x01, 0x23, 0x54, 0xe3, 0x23, 0x23, 0x30, 0xe0, - 0x02, 0xd2, 0xe5, 0x30, 0xe7, 0x02, 0xd2, 0xe4, 0x30, 0xe5, 0x06, 0x30, 0xe4, 0x03, 0x02, 0x07, - 0x55, 0x54, 0x3e, 0xf5, 0xf0, 0x03, 0x54, 0x1f, 0xc3, 0x25, 0xf0, 0x90, 0x04, 0x18, 0x75, 0x84, - 0xff, 0x73, 0x02, 0x05, 0x6c, 0x02, 0x04, 0x60, 0x02, 0x06, 0x09, 0x02, 0x06, 0x24, 0x02, 0x05, - 0x05, 0x02, 0x04, 0xc6, 0x02, 0x06, 0x3d, 0x02, 0x06, 0x3d, 0x02, 0x06, 0x40, 0x02, 0x06, 0x40, - 0x02, 0x06, 0x40, 0x02, 0x06, 0x40, 0x02, 0x06, 0x40, 0x02, 0x06, 0x40, 0x02, 0x06, 0x40, 0x02, - 0x06, 0x40, 0x02, 0x06, 0x46, 0x02, 0x06, 0xfa, 0x02, 0x06, 0x43, 0x02, 0x06, 0x43, 0x02, 0x06, - 0x43, 0x02, 0x06, 0x43, 0x02, 0x06, 0x43, 0x02, 0x06, 0x43, 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x06, - 0x2a, 0x7e, 0xb3, 0x01, 0x25, 0x60, 0x56, 0x7c, 0x0b, 0x7e, 0x13, 0x01, 0x26, 0x7e, 0x17, 0x01, - 0x27, 0x75, 0x08, 0x72, 0x12, 0x08, 0x33, 0x7a, 0x01, 0x08, 0x12, 0x08, 0x33, 0x7a, 0x11, 0x08, - 0x12, 0x08, 0x33, 0x12, 0x07, 0x5f, 0x40, 0x35, 0x02, 0x02, 0x94, 0xb4, 0x08, 0x10, 0x75, 0x08, - 0x74, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x3f, 0xf1, 0xf5, 0xf3, 0x75, 0xf6, 0x01, 0x22, 0xb4, 0x00, - 0x1c, 0x75, 0x08, 0x75, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x3f, 0xf2, 0x30, 0xe0, 0x05, 0x75, 0xf3, - 0x02, 0x80, 0x03, 0x75, 0xf3, 0x00, 0x75, 0xf3, 0x00, 0x75, 0xf6, 0x02, 0x22, 0x02, 0x07, 0x55, - 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x00, 0x35, 0x75, 0x08, 0x76, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, - 0x28, 0x54, 0x0f, 0xf5, 0xf1, 0x7e, 0xb3, 0x01, 0x28, 0x20, 0xe7, 0x09, 0xe5, 0xe1, 0x30, 0xe7, - 0x0d, 0x74, 0x01, 0x80, 0x0b, 0xe5, 0xe1, 0x30, 0xe6, 0x04, 0x74, 0x01, 0x80, 0x02, 0x74, 0x00, - 0x53, 0xf1, 0x80, 0xf5, 0xf3, 0x75, 0xf3, 0x00, 0x75, 0xf6, 0x02, 0x22, 0x02, 0x07, 0x55, 0xc0, - 0xf1, 0x7e, 0xb3, 0x01, 0x28, 0x54, 0x0f, 0x42, 0xf1, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x00, 0x45, - 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x01, 0x24, 0x75, 0x08, 0x77, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, - 0x28, 0x54, 0x0f, 0x78, 0x05, 0x53, 0xe1, 0x3f, 0x80, 0x37, 0x7e, 0xb3, 0x01, 0x28, 0x20, 0xe7, - 0x05, 0x53, 0xe1, 0x7f, 0x80, 0x2b, 0x53, 0xe1, 0xbf, 0x80, 0x26, 0xb4, 0x03, 0x17, 0x75, 0x08, - 0x78, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, 0x28, 0x20, 0xe7, 0x05, 0x43, 0xe1, 0x80, 0x80, 0x11, - 0x43, 0xe1, 0x40, 0x80, 0x0c, 0x43, 0xe1, 0xc0, 0xd0, 0xf1, 0x75, 0x08, 0x07, 0x12, 0x08, 0x33, - 0x22, 0xd0, 0xf1, 0x02, 0x02, 0x90, 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x09, 0x23, 0x75, 0x08, 0x79, - 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, 0x26, 0xbe, 0xb3, 0x3f, 0xf1, 0x68, 0x11, 0xca, 0xb8, 0xc0, - 0xf1, 0x12, 0x01, 0x1d, 0xd0, 0xf1, 0xda, 0xb8, 0x50, 0x76, 0x7a, 0xb3, 0x3f, 0xf1, 0x80, 0x6d, - 0xb4, 0x05, 0x08, 0x75, 0x08, 0x7a, 0x12, 0x08, 0x33, 0x80, 0x62, 0xb4, 0x03, 0x19, 0x75, 0x08, - 0x7b, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x01, 0x55, 0x7e, 0xb3, 0x3f, 0xf2, 0x44, - 0x01, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, 0x46, 0xb4, 0x01, 0x19, 0x75, 0x08, 0x7c, 0x12, 0x08, 0x33, - 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x01, 0x39, 0x7e, 0xb3, 0x3f, 0xf2, 0x54, 0xfe, 0x7a, 0xb3, 0x3f, - 0xf2, 0x80, 0x2a, 0xb4, 0x07, 0x2a, 0x7e, 0xb3, 0x01, 0x25, 0x60, 0x24, 0x7c, 0x0b, 0x7e, 0x13, - 0x01, 0x26, 0x7e, 0x17, 0x01, 0x27, 0x75, 0x08, 0x73, 0x12, 0x08, 0x33, 0x7a, 0x01, 0x08, 0x12, - 0x08, 0x33, 0x7a, 0x11, 0x08, 0x12, 0x08, 0x33, 0x12, 0x07, 0x8b, 0x40, 0x03, 0x02, 0x02, 0x90, - 0x02, 0x07, 0x55, 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x0b, 0xf6, 0x75, 0x08, 0x7d, 0x12, 0x08, 0x33, - 0x7e, 0xb3, 0x01, 0x26, 0x7e, 0xa3, 0x01, 0x28, 0x4c, 0xab, 0x78, 0xe4, 0x80, 0xdf, 0x7e, 0xb3, - 0x01, 0x24, 0xb4, 0x0a, 0xdb, 0x75, 0x08, 0x7e, 0x12, 0x08, 0x33, 0x7e, 0xb3, 0x01, 0x26, 0x70, - 0xcf, 0xf5, 0xf3, 0x75, 0xf6, 0x01, 0x22, 0x02, 0x07, 0x55, 0x02, 0x07, 0x55, 0x02, 0x07, 0x55, - 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x04, 0x20, 0x75, 0x08, 0xc3, 0x12, 0x08, 0x33, 0x7e, 0x04, 0x00, - 0x01, 0x7e, 0x17, 0x01, 0x25, 0x7e, 0x18, 0x01, 0x34, 0x7a, 0x1c, 0x00, 0x00, 0x7e, 0x47, 0x01, - 0x29, 0x12, 0x08, 0x3f, 0x02, 0x06, 0xf4, 0xb4, 0x06, 0x3a, 0x75, 0x08, 0xc1, 0x12, 0x08, 0x33, - 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7d, 0xca, 0x7e, 0xd7, 0x01, 0x25, 0x7e, 0x78, - 0x01, 0x34, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x77, 0x01, 0x29, 0x75, 0x08, 0xc1, 0x12, 0x08, 0x33, - 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x12, 0x08, 0xd6, 0xd0, 0x87, 0xd0, 0xa8, - 0x40, 0x4f, 0x80, 0x4a, 0xb4, 0x00, 0x1c, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x12, 0x02, 0x90, 0xe4, - 0x8d, 0xef, 0x8d, 0xef, 0x8d, 0xef, 0xd5, 0xe0, 0xf7, 0xc0, 0xd1, 0xca, 0x02, 0xff, 0xca, 0x06, - 0x00, 0x00, 0x32, 0xb4, 0x09, 0x12, 0x7e, 0x57, 0x01, 0x25, 0x4d, 0x55, 0x68, 0x05, 0xa9, 0xd2, - 0xb1, 0x80, 0x03, 0xa9, 0xc2, 0xb1, 0x80, 0x16, 0xb4, 0x07, 0x16, 0xc2, 0xaf, 0x7e, 0x07, 0x01, - 0x27, 0x7e, 0x17, 0x01, 0x25, 0xc0, 0xd1, 0xca, 0x18, 0xca, 0x38, 0xca, 0x28, 0x32, 0x02, 0x02, - 0x90, 0x02, 0x07, 0x55, 0x7e, 0xb3, 0x01, 0x24, 0xb4, 0x03, 0x15, 0x75, 0x08, 0xc2, 0x12, 0x08, - 0x33, 0x7e, 0x04, 0x00, 0x01, 0x7e, 0x17, 0x01, 0x25, 0x7e, 0x57, 0x01, 0x29, 0x02, 0x02, 0x94, - 0xb4, 0x05, 0x39, 0x75, 0x08, 0xc0, 0x12, 0x08, 0x33, 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, - 0xd5, 0x87, 0x7e, 0x08, 0x01, 0x34, 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x24, 0x00, 0xfe, 0x7e, 0x37, - 0x01, 0x25, 0x7e, 0x47, 0x01, 0x29, 0x12, 0x08, 0x3f, 0xd0, 0x87, 0xd0, 0xa8, 0x7e, 0x08, 0x01, - 0x34, 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x57, 0x01, 0x29, 0x02, 0x02, 0x94, 0x02, 0x07, 0x55, 0x75, - 0x08, 0x07, 0x12, 0x08, 0x33, 0x43, 0xe1, 0xc0, 0x22, 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, - 0xd5, 0x87, 0x12, 0x07, 0xca, 0x40, 0x19, 0x7e, 0x08, 0x01, 0x34, 0x7a, 0x0c, 0x00, 0x00, 0xca, - 0x0b, 0xca, 0x49, 0x12, 0x08, 0x3f, 0xda, 0x59, 0xda, 0x0b, 0xd0, 0x87, 0xd0, 0xa8, 0xc3, 0x22, - 0xd0, 0x87, 0xd0, 0xa8, 0x22, 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x12, 0x07, - 0xca, 0x40, 0x2b, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7f, 0x61, 0x7e, 0x78, 0x01, - 0x34, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x77, 0x01, 0x29, 0xbd, 0x74, 0x78, 0x11, 0x75, 0x08, 0xc1, - 0x12, 0x08, 0x33, 0x12, 0x08, 0xd6, 0x40, 0x06, 0xd0, 0x87, 0xd0, 0xa8, 0xc3, 0x22, 0xd0, 0x87, - 0xd0, 0xa8, 0xd3, 0x22, 0x7e, 0x24, 0x00, 0xfe, 0x7e, 0x34, 0x7f, 0xca, 0x0b, 0x1a, 0x50, 0xc5, - 0xf0, 0x7d, 0x62, 0x7d, 0x75, 0x7d, 0x87, 0x7e, 0x34, 0x7f, 0x03, 0x7e, 0x1b, 0xb0, 0xbc, 0x0b, - 0x50, 0x49, 0x3e, 0x00, 0x3e, 0x00, 0x0a, 0x50, 0x2d, 0x75, 0x0b, 0x3a, 0x30, 0x69, 0x53, 0x00, - 0x02, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, 0xbc, 0x1b, 0x50, 0x30, 0x3e, 0x10, 0x3e, 0x10, 0x0a, - 0x51, 0x2d, 0x35, 0x69, 0x41, 0x00, 0x02, 0x0b, 0x1a, 0x30, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, - 0xbe, 0x44, 0xff, 0xff, 0x78, 0x05, 0x7e, 0x1b, 0x90, 0x0a, 0x49, 0x4d, 0x44, 0x68, 0x0c, 0xbe, - 0x44, 0x00, 0xff, 0x28, 0x04, 0x7e, 0x44, 0x00, 0xff, 0xc3, 0x22, 0xd3, 0x22, - -// Segment #16, EXCLUDED Start Address 00ff7c00, Length 199 - - -// Segment #17, EXCLUDED Start Address 00ff7f00, Length 192 - - -// Segment #17, Start Address 00ff7fc0, Length 64 -0xff,0x00,0xc0,0x7f,0x40,0x00, - 0x40, 0x01, 0x02, 0x00, 0xca, 0x1b, 0x01, 0x0c, 0x02, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -// Segment #18, Start Address 00ff0833, Length 5015 -0xff,0x00,0x33,0x08,0x97,0x13, - 0xca, 0x08, 0x7e, 0x01, 0x08, 0x7a, 0x03, 0x3f, 0xf0, 0xda, 0x08, 0x22, 0x80, 0x50, 0x0b, 0x1a, - 0x60, 0x0b, 0x35, 0x0b, 0x1a, 0x70, 0x0b, 0x35, 0x0b, 0x1a, 0x80, 0x0b, 0x35, 0x0b, 0x1a, 0x90, - 0x0b, 0x35, 0x0b, 0x1a, 0xa0, 0x0b, 0x35, 0x0b, 0x1a, 0xb0, 0x0b, 0x35, 0x0b, 0x1a, 0xc0, 0x0b, - 0x35, 0x0b, 0x1a, 0xd0, 0x0b, 0x35, 0x1b, 0x0a, 0x60, 0x0b, 0x15, 0x1b, 0x0a, 0x70, 0x0b, 0x15, - 0x1b, 0x0a, 0x80, 0x0b, 0x15, 0x1b, 0x0a, 0x90, 0x0b, 0x15, 0x1b, 0x0a, 0xa0, 0x0b, 0x15, 0x1b, - 0x0a, 0xb0, 0x0b, 0x15, 0x1b, 0x0a, 0xc0, 0x0b, 0x15, 0x1b, 0x0a, 0xd0, 0x0b, 0x15, 0x9e, 0x44, - 0x00, 0x10, 0x50, 0xaa, 0x2e, 0x44, 0x00, 0x10, 0x68, 0x0e, 0x7e, 0x1b, 0xc0, 0x7a, 0x0b, 0xc0, - 0x0b, 0x14, 0x0b, 0x34, 0x1b, 0x44, 0x78, 0xf2, 0x22, 0x7f, 0x6f, 0x7f, 0xf0, 0x1b, 0xfc, 0x7c, - 0x54, 0x7d, 0x32, 0x80, 0x08, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0x9e, 0x44, 0x00, - 0x10, 0x50, 0xf2, 0x2e, 0x44, 0x00, 0x10, 0x68, 0x06, 0xca, 0x48, 0x1b, 0x44, 0x78, 0xfa, 0x7f, - 0xf6, 0x89, 0xe4, 0xca, 0x6b, 0x5e, 0xd4, 0x00, 0x3f, 0x68, 0x20, 0x7e, 0x84, 0x00, 0x40, 0x9d, - 0x8d, 0xda, 0x6b, 0xbd, 0x87, 0x38, 0x16, 0xca, 0x79, 0x7d, 0x78, 0x12, 0x09, 0x00, 0xda, 0x79, - 0x40, 0x08, 0x9d, 0x78, 0x68, 0x02, 0x80, 0x05, 0xc2, 0xd7, 0x22, 0xda, 0x6b, 0x43, 0x90, 0x30, - 0x74, 0xaa, 0x39, 0xb5, 0x55, 0x55, 0x74, 0x55, 0x39, 0xb5, 0x2a, 0xaa, 0x74, 0xa0, 0x39, 0xb5, - 0x55, 0x55, 0x7e, 0x04, 0x00, 0x40, 0x9d, 0x70, 0x50, 0x06, 0x2d, 0x70, 0x7d, 0x07, 0x6d, 0x77, - 0x7c, 0x31, 0x7e, 0x7b, 0x00, 0x7a, 0x6b, 0x00, 0x0b, 0x7c, 0x0b, 0x6c, 0xa5, 0xd9, 0xf3, 0x7f, - 0x16, 0x1b, 0x1c, 0x7e, 0x54, 0x27, 0x10, 0x7e, 0x1b, 0x10, 0xbc, 0x10, 0x68, 0x06, 0x1b, 0x54, - 0x78, 0xf5, 0x80, 0x2c, 0x6d, 0x00, 0x7c, 0x20, 0x7f, 0x16, 0x9f, 0x10, 0x7f, 0x27, 0x9f, 0x20, - 0x7e, 0x2b, 0x00, 0x7e, 0x1b, 0x10, 0xbc, 0x01, 0x78, 0x16, 0x0b, 0x2c, 0x0b, 0x1c, 0xa5, 0xdb, - 0xef, 0x7c, 0xb6, 0x20, 0xe0, 0x03, 0x63, 0x90, 0x30, 0x4d, 0x77, 0x78, 0x93, 0xc2, 0xd7, 0x22, - 0xd2, 0xd7, 0x22, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, - 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x04, 0x00, 0x08, 0x10, 0x02, 0x10, 0x04, 0x02, 0x08, 0x00, 0x01, 0x01, 0x08, 0x7e, 0x18, 0x7f, - 0xbd, 0x7a, 0x1c, 0x00, 0xff, 0x0b, 0x1a, 0x00, 0xbe, 0x10, 0x14, 0x38, 0x1a, 0x0a, 0x51, 0x23, - 0x7e, 0x18, 0x09, 0x76, 0x7a, 0x1c, 0x00, 0xff, 0x2d, 0x35, 0x0b, 0x1a, 0x50, 0x60, 0x08, 0xa5, - 0xb8, 0x02, 0x03, 0x4e, 0xa0, 0x08, 0x22, 0x80, 0xfe, 0x7e, 0xe8, 0x7f, 0xbf, 0x7a, 0xec, 0x00, - 0xff, 0xe0, 0xf5, 0x22, 0x54, 0xc0, 0x68, 0x16, 0x7e, 0xe8, 0x7f, 0xbe, 0x7a, 0xec, 0x00, 0xff, - 0xe0, 0x60, 0x0c, 0x12, 0x09, 0xa0, 0xf5, 0x09, 0x7a, 0xa1, 0x20, 0x02, 0x0f, 0x0a, 0x22, 0xc2, - 0x95, 0xd2, 0x94, 0x12, 0x19, 0xfb, 0x53, 0x90, 0xcf, 0x12, 0x19, 0xfb, 0x80, 0xf1, 0x0d, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0d, - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x45, 0x64, 0x67, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x34, 0x20, 0x2d, 0x20, 0x48, 0x61, 0x72, - 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, - 0x73, 0x2c, 0x20, 0x52, 0x65, 0x76, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x3b, 0x20, 0x43, 0x6f, 0x70, - 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20, 0x49, 0x6e, 0x73, 0x69, - 0x64, 0x65, 0x20, 0x4f, 0x75, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x0d, - 0x0a, 0x00, 0x50, 0x61, 0x73, 0x73, 0x00, 0x46, 0x41, 0x49, 0x4c, 0x20, 0x21, 0x21, 0x00, 0x50, - 0x61, 0x73, 0x73, 0x20, 0x20, 0x20, 0x20, 0x00, 0x46, 0x41, 0x49, 0x4c, 0x20, 0x21, 0x21, 0x20, - 0x00, 0x0d, 0x0a, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x20, 0x52, 0x61, 0x6d, 0x3a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x52, 0x61, 0x6d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x3a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x62, - 0x69, 0x74, 0x20, 0x30, 0x2d, 0x31, 0x34, 0x20, 0x74, 0x65, 0x73, 0x74, 0x3a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x57, 0x72, 0x6f, 0x74, 0x65, 0x20, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x20, 0x30, 0x30, 0x3a, 0x00, 0x20, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x00, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x72, 0x65, 0x61, 0x64, 0x3a, 0x20, 0x00, 0x0d, 0x0a, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, - 0x62, 0x6f, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, - 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x62, 0x69, - 0x74, 0x73, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x68, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x0d, 0x0a, 0x74, 0x6f, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x00, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x00, 0x0d, 0x0a, 0x44, 0x65, - 0x74, 0x65, 0x63, 0x74, 0x20, 0x55, 0x61, 0x72, 0x74, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, - 0x53, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x20, 0x50, 0x61, 0x64, 0x2c, 0x46, 0x69, 0x46, 0x6f, - 0x20, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x26, 0x20, 0x52, 0x53, 0x54, 0x3a, 0x20, 0x00, - 0x0d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x55, 0x61, 0x72, 0x74, 0x20, 0x54, 0x65, 0x73, 0x74, 0x73, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x50, 0x6f, 0x72, 0x74, 0x31, 0x20, 0x20, 0x20, 0x50, 0x6f, 0x72, 0x74, - 0x32, 0x20, 0x20, 0x20, 0x50, 0x6f, 0x72, 0x74, 0x33, 0x20, 0x20, 0x20, 0x50, 0x6f, 0x72, 0x74, - 0x34, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x00, 0x0d, 0x0a, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, - 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x41, 0x6e, 0x61, 0x6c, - 0x6f, 0x67, 0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, - 0x52, 0x58, 0x44, 0x2c, 0x54, 0x58, 0x44, 0x20, 0x74, 0x6f, 0x20, 0x52, 0x54, 0x53, 0x2c, 0x43, - 0x54, 0x53, 0x2c, 0x52, 0x49, 0x20, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x00, 0x0d, 0x0a, 0x52, 0x58, 0x44, 0x2c, 0x54, 0x58, 0x44, 0x20, 0x74, 0x6f, 0x20, 0x44, - 0x54, 0x52, 0x2c, 0x44, 0x53, 0x52, 0x2c, 0x43, 0x44, 0x20, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x3a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x52, 0x54, 0x53, 0x5b, 0x43, 0x54, 0x53, 0x2c, - 0x52, 0x49, 0x5d, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x54, 0x52, 0x2c, 0x44, 0x53, 0x52, 0x2c, 0x43, - 0x44, 0x20, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x00, 0x0d, 0x0a, 0x52, 0x54, 0x53, 0x5b, - 0x43, 0x54, 0x53, 0x2c, 0x43, 0x44, 0x5d, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x53, 0x52, 0x2c, 0x52, - 0x49, 0x20, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, - 0x44, 0x54, 0x52, 0x5b, 0x44, 0x53, 0x52, 0x2c, 0x43, 0x44, 0x5d, 0x20, 0x74, 0x6f, 0x20, 0x52, - 0x54, 0x53, 0x2c, 0x43, 0x54, 0x53, 0x2c, 0x52, 0x49, 0x20, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x3a, - 0x20, 0x00, 0x0d, 0x0a, 0x44, 0x54, 0x52, 0x20, 0x74, 0x6f, 0x20, 0x43, 0x54, 0x53, 0x2c, 0x43, - 0x44, 0x20, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x52, 0x54, 0x53, 0x20, 0x74, 0x6f, 0x20, 0x43, - 0x54, 0x53, 0x2c, 0x52, 0x49, 0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, 0x52, 0x54, 0x53, 0x20, - 0x74, 0x6f, 0x20, 0x43, 0x54, 0x53, 0x2c, 0x43, 0x44, 0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, - 0x63, 0x6b, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x0d, 0x0a, - 0x44, 0x54, 0x52, 0x20, 0x74, 0x6f, 0x20, 0x44, 0x53, 0x52, 0x2c, 0x43, 0x44, 0x20, 0x4c, 0x6f, - 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x00, 0x0d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x45, 0x20, 0x52, 0x20, 0x52, 0x20, 0x4f, 0x20, - 0x52, 0x20, 0x21, 0x21, 0x21, 0x2c, 0x20, 0x45, 0x20, 0x52, 0x20, 0x52, 0x20, 0x4f, 0x20, 0x52, - 0x20, 0x21, 0x21, 0x21, 0x20, 0x2c, 0x20, 0x45, 0x20, 0x52, 0x20, 0x52, 0x20, 0x4f, 0x20, 0x52, - 0x20, 0x21, 0x21, 0x21, 0x0d, 0x0a, 0x0a, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, - 0x63, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x65, 0x6e, 0x74, 0x65, - 0x72, 0x20, 0x61, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x6f, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x64, 0x65, 0x74, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x00, 0x0d, 0x0a, 0x0a, 0x4e, - 0x6f, 0x20, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x20, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x00, 0x43, 0x6f, - 0x70, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, - 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x6c, 0x61, 0x76, 0x65, 0x27, - 0x73, 0x20, 0x45, 0x45, 0x70, 0x72, 0x6f, 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x00, 0x44, 0x6f, 0x6e, - 0x65, 0x0d, 0x0a, 0x0a, 0x2d, 0x3e, 0x20, 0x54, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x74, - 0x20, 0x6f, 0x66, 0x66, 0x2c, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x20, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x73, - 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x20, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, - 0x73, 0x74, 0x69, 0x63, 0x73, 0x2e, 0x00, 0xc2, 0xaf, 0xc2, 0x09, 0xc2, 0x0a, 0x75, 0x90, 0x0d, - 0x20, 0x17, 0x02, 0xd2, 0xb5, 0x43, 0x90, 0x30, 0x6c, 0x00, 0x7e, 0x10, 0x03, 0x12, 0x0f, 0x38, - 0x7e, 0x68, 0x0a, 0x01, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x0b, 0x00, 0x30, 0xb4, 0x02, - 0x80, 0x24, 0x02, 0x1b, 0x3c, 0x20, 0x09, 0x1d, 0xc2, 0x94, 0xd2, 0x95, 0x12, 0x19, 0xfb, 0x53, - 0x90, 0xcf, 0x12, 0x19, 0xfb, 0xc2, 0x95, 0xd2, 0x94, 0x12, 0x19, 0xfb, 0xa5, 0xd9, 0xe6, 0x43, - 0x90, 0x30, 0x12, 0x19, 0xfb, 0x22, 0x7e, 0x68, 0x0a, 0x94, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, - 0x93, 0x7e, 0xe4, 0x10, 0x00, 0x7e, 0x40, 0x55, 0x7a, 0xe9, 0x40, 0x0b, 0xe4, 0x7e, 0x50, 0xaa, - 0x7a, 0xe9, 0x50, 0x1b, 0xe4, 0xbe, 0xe9, 0x40, 0x68, 0x19, 0x7e, 0x68, 0x0a, 0x7a, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0x13, 0x7a, 0xe9, 0x40, 0x7e, 0xe9, - 0x10, 0x80, 0xf8, 0x7e, 0x68, 0x0a, 0x75, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x0b, 0x00, - 0x7e, 0x68, 0x0a, 0xd8, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x78, 0x00, 0x00, 0x7e, - 0x70, 0x0e, 0x7e, 0xa4, 0xff, 0xff, 0x7e, 0xb4, 0xbf, 0xff, 0x7d, 0xcb, 0x0e, 0xc4, 0x7d, 0xdc, - 0x5d, 0xdb, 0x6c, 0xbb, 0x7d, 0xfa, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x0b, 0xb0, 0x7d, - 0xfb, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x0b, 0xb0, 0x7d, 0xfc, 0x5e, 0xf4, 0x7f, 0xff, - 0x7a, 0x7b, 0xb0, 0x0b, 0xb0, 0x7d, 0xfd, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x6c, 0xbb, - 0x7d, 0xfa, 0x5e, 0xf4, 0x7f, 0xff, 0xbe, 0x7b, 0xb0, 0x78, 0x41, 0x0b, 0xb0, 0x7d, 0xfb, 0x5e, - 0xf4, 0x7f, 0xff, 0xbe, 0x7b, 0xb0, 0x78, 0x34, 0x0b, 0xb0, 0x7d, 0xfc, 0x5e, 0xf4, 0x7f, 0xff, - 0xbe, 0x7b, 0xb0, 0x78, 0x27, 0x0b, 0xb0, 0x7d, 0xfd, 0x5e, 0xf4, 0x7f, 0xff, 0xbe, 0x7b, 0xb0, - 0x78, 0x1a, 0x0b, 0xb0, 0xbe, 0xc4, 0xff, 0xfe, 0x78, 0x92, 0x0e, 0xb4, 0xa5, 0xdf, 0x8b, 0x7e, - 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x80, 0x77, 0xca, 0x5b, 0xca, 0x6b, - 0x7e, 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x68, 0x0b, 0x2a, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x0a, 0x47, 0x12, 0x1a, 0xc9, 0x7e, 0x68, 0x0b, 0x79, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x6c, 0x77, 0xda, 0x6b, 0xca, 0x6b, 0x0b, 0x70, 0x0e, 0xc4, - 0xbe, 0xc4, 0xff, 0xff, 0x78, 0xf6, 0x1b, 0x70, 0x0a, 0x47, 0x12, 0x1a, 0xc9, 0x12, 0x1a, 0x08, - 0x30, 0x09, 0x30, 0xda, 0x6b, 0xda, 0x5b, 0x6c, 0xbb, 0x7e, 0x78, 0x00, 0x00, 0x7d, 0xfa, 0x5e, - 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x7d, 0xfb, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x7d, - 0xfc, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x7d, 0xfd, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, - 0xb0, 0x80, 0xd4, 0x7e, 0x68, 0x0a, 0xb6, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x30, 0x17, - 0x0e, 0x7e, 0x78, 0x04, 0x20, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x44, 0x7b, 0xe0, 0x80, 0x0c, 0x7e, - 0x78, 0x00, 0x00, 0x7a, 0x7c, 0x00, 0x01, 0x7e, 0x44, 0x80, 0x00, 0x0b, 0x00, 0x7e, 0x40, 0x3a, - 0x7c, 0x54, 0x7f, 0x57, 0x7d, 0x84, 0x6c, 0x66, 0x7a, 0x5b, 0x50, 0x0b, 0x5c, 0x0b, 0x50, 0xa5, - 0xde, 0x02, 0x0b, 0x50, 0x1b, 0x84, 0x78, 0xf0, 0x7c, 0x54, 0x7f, 0x57, 0x7d, 0x84, 0x6c, 0x66, - 0xbe, 0x5b, 0x50, 0x78, 0x1a, 0x0b, 0x5c, 0x0b, 0x50, 0xa5, 0xde, 0x02, 0x0b, 0x50, 0x1b, 0x84, - 0x78, 0xee, 0x7e, 0x68, 0x0a, 0x75, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x80, 0x4b, 0x7f, - 0x45, 0x7e, 0x68, 0x0a, 0x7a, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x68, 0x0a, 0xfa, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7d, 0x4b, 0x12, 0x1a, 0xc9, 0x7e, 0x68, 0x0b, 0x0f, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x6c, 0x88, 0x7c, 0x95, 0x12, 0x1a, 0xc9, 0x7e, 0x68, - 0x0b, 0x1d, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x4b, 0x90, 0x12, 0x1a, 0xc9, 0x12, - 0x1a, 0x08, 0x30, 0x09, 0x05, 0x7e, 0x4b, 0x90, 0x80, 0xfb, 0x7e, 0x68, 0x0b, 0x7f, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x1a, 0x93, 0x0b, 0x00, 0xd2, 0x92, 0x7e, 0x24, 0x80, 0x00, 0x09, 0xb2, 0x00, - 0x08, 0xbe, 0xb0, 0x01, 0x78, 0x0b, 0x09, 0xb2, 0x00, 0x14, 0xbe, 0xb0, 0x60, 0x78, 0x02, 0x80, - 0x17, 0x7e, 0x68, 0x0a, 0x7a, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, - 0x09, 0x11, 0x09, 0xb2, 0x00, 0x08, 0x80, 0xfa, 0x7e, 0x68, 0x0a, 0x75, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x1a, 0x93, 0x7e, 0x68, 0x0b, 0xa1, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x0b, 0x00, - 0xc2, 0x92, 0x12, 0x19, 0xee, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0xa0, 0x55, 0x19, 0xa2, 0x00, 0x1c, - 0x7e, 0xb0, 0x01, 0x19, 0xb2, 0x00, 0x08, 0x09, 0xb2, 0x00, 0x1c, 0xbc, 0xab, 0x78, 0x37, 0x09, - 0xb2, 0x00, 0x08, 0x5e, 0xb0, 0xc0, 0xbe, 0xb0, 0xc0, 0x78, 0x2b, 0x7e, 0xa0, 0xaa, 0x19, 0xa2, - 0x00, 0x1c, 0x6c, 0xbb, 0x19, 0xb2, 0x00, 0x08, 0x09, 0xb2, 0x00, 0x1c, 0xbc, 0xab, 0x78, 0x16, - 0x09, 0xb2, 0x00, 0x08, 0x5e, 0xb0, 0xc0, 0x78, 0x0d, 0x7e, 0x68, 0x0a, 0x75, 0x7a, 0x6c, 0x00, - 0xff, 0x12, 0x1a, 0x93, 0x80, 0x1b, 0x7e, 0x68, 0x0a, 0x7a, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, - 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0x0a, 0x19, 0xa2, 0x00, 0x1c, 0x09, 0xb2, 0x00, 0x1c, 0x80, - 0xf6, 0x7e, 0x68, 0x0b, 0xc3, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x68, 0x0c, 0x45, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x7e, 0xb0, - 0x01, 0x19, 0xb2, 0x00, 0x1c, 0x2e, 0x24, 0x01, 0x00, 0x0b, 0xb0, 0xa5, 0xd9, 0xf3, 0x7e, 0x24, - 0x80, 0x00, 0x7e, 0x11, 0x09, 0x7e, 0xb0, 0x01, 0x0b, 0x00, 0x09, 0xa2, 0x00, 0x1c, 0xbc, 0xab, - 0x78, 0x16, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x2e, 0x24, 0x01, - 0x00, 0x0b, 0xb0, 0xa5, 0xd9, 0xe2, 0x80, 0x25, 0x7e, 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0xe4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, - 0x09, 0xa2, 0x00, 0x1c, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xf5, 0x80, 0xec, 0x7e, 0x68, 0x0c, - 0x69, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x13, 0x8a, 0x7e, 0x24, 0x80, 0x00, 0x7e, - 0x11, 0x09, 0x0b, 0x00, 0x74, 0x10, 0x19, 0xb2, 0x00, 0x10, 0x12, 0x13, 0x03, 0x2e, 0x24, 0x01, - 0x00, 0xa5, 0xd9, 0xee, 0x7e, 0x68, 0x0c, 0x8d, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, - 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0xe4, 0x19, 0xb2, 0x00, 0x10, 0x12, 0x13, 0x03, - 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xef, 0x30, 0x00, 0x03, 0x02, 0x18, 0xb7, 0x02, 0x13, 0xbb, - 0x74, 0x07, 0x19, 0xb2, 0x00, 0x08, 0x12, 0x19, 0xfb, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, - 0x14, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, 0x14, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, - 0x14, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xc2, 0x0b, 0x7e, 0xb0, 0x55, 0x12, 0x13, - 0x64, 0x7e, 0xb0, 0xaa, 0x12, 0x13, 0x64, 0x7e, 0xb0, 0x00, 0x12, 0x13, 0x64, 0x7e, 0xb0, 0xff, - 0x12, 0x13, 0x64, 0x30, 0x0b, 0x0f, 0x7e, 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, - 0x93, 0x12, 0x1a, 0x08, 0x22, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, - 0x22, 0x19, 0xb2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x09, 0xa2, 0x00, 0x00, 0xbc, 0xab, 0x78, 0x01, - 0x22, 0x20, 0x09, 0x03, 0xd2, 0x0b, 0x22, 0x12, 0x1a, 0x08, 0x19, 0xb2, 0x00, 0x00, 0x12, 0x19, - 0xee, 0x09, 0xa2, 0x00, 0x00, 0x80, 0xf3, 0xd2, 0x92, 0x12, 0x19, 0xee, 0xc2, 0x92, 0x12, 0x19, - 0xee, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x74, 0x80, 0x19, 0xb2, 0x00, 0x0c, 0x7e, 0x54, - 0x00, 0x02, 0x19, 0xa2, 0x00, 0x04, 0x19, 0xb2, 0x00, 0x00, 0x74, 0x03, 0x19, 0xb2, 0x00, 0x0c, - 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xe1, 0x22, 0x7e, 0x68, 0x0c, 0xb1, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x12, 0x19, 0xee, 0x09, - 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x55, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, - 0x18, 0x5e, 0xb0, 0x05, 0x78, 0x0d, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, - 0x93, 0x80, 0x1a, 0x7e, 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, - 0x08, 0x30, 0x09, 0x09, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x80, 0xf7, 0x2e, 0x24, 0x01, - 0x00, 0xa5, 0xd9, 0xb6, 0x7e, 0x68, 0x0c, 0xd5, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, - 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x7e, - 0xa0, 0x55, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x0a, - 0x78, 0x0d, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x80, 0x1a, 0x7e, - 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0x09, - 0x19, 0xa2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x80, 0xf7, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xb6, - 0x30, 0x04, 0x03, 0x02, 0x16, 0x8c, 0x7e, 0x68, 0x0c, 0xf9, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, - 0x93, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, - 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, - 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x0a, 0x78, 0x3c, - 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, - 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, - 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x0a, 0x78, 0x14, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x1a, 0x93, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, 0x80, 0x20, 0x7e, 0x68, 0x0a, 0x8b, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0xe6, 0x7e, 0xa0, 0x02, - 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x7e, 0x68, 0x0d, 0x41, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, - 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x01, - 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, - 0x18, 0x5e, 0xb0, 0x05, 0x78, 0x3c, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, - 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, 0x02, 0x19, 0xa2, - 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x05, 0x78, 0x14, 0x7e, 0x68, - 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, - 0x80, 0x20, 0x7e, 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, - 0x30, 0x09, 0xe6, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, - 0x80, 0xf1, 0x7e, 0x68, 0x0d, 0x89, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, - 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, - 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x50, 0xbe, 0xb0, 0x50, 0x78, 0x1f, 0x6c, 0xaa, 0x19, 0xa2, - 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x50, 0x78, 0x0d, 0x7e, 0x68, - 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x80, 0x20, 0x7e, 0x68, 0x0a, 0x8b, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0x0f, 0x7e, 0xa0, 0x02, 0x19, - 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x2e, 0x24, 0x01, 0x00, 0xa5, - 0xd9, 0xa2, 0x7e, 0x68, 0x0d, 0xd1, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, - 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, - 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0xa0, 0xbe, 0xb0, 0xa0, 0x78, 0x1f, - 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0xa0, - 0x78, 0x0d, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x80, 0x20, 0x7e, - 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0x0f, - 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x2e, - 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, 0x02, 0x18, 0x2b, 0x7e, 0x68, 0x0d, 0x1d, 0x7a, 0x6c, 0x00, - 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x6c, 0xaa, 0x19, - 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, - 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, - 0x06, 0x78, 0x3c, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, - 0x18, 0x7e, 0xa0, 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, - 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x06, 0x78, 0x14, 0x7e, 0x68, 0x0a, 0x82, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, 0x80, 0x20, 0x7e, - 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0xe6, - 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x7e, - 0x68, 0x0d, 0x65, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, - 0x09, 0x0b, 0x00, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, - 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, - 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x09, 0x78, 0x3c, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, - 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, - 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x09, 0x78, - 0x14, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x2e, 0x24, 0x01, 0x00, - 0xa5, 0xd9, 0x9e, 0x80, 0x20, 0x7e, 0x68, 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, - 0x12, 0x1a, 0x08, 0x30, 0x09, 0xe6, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, - 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x7e, 0x68, 0x0d, 0xad, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, - 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, - 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x90, 0xbe, 0xb0, 0x90, 0x78, 0x1f, 0x6c, - 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x90, 0x78, - 0x0d, 0x7e, 0x68, 0x0a, 0x82, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x80, 0x20, 0x7e, 0x68, - 0x0a, 0x8b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1a, 0x08, 0x30, 0x09, 0x0f, 0x7e, - 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x2e, 0x24, - 0x01, 0x00, 0xa5, 0xd9, 0xa2, 0x02, 0x18, 0xb7, 0x30, 0x17, 0x03, 0x02, 0x19, 0x3b, 0xc2, 0x8a, - 0x12, 0x19, 0x22, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x04, - 0x12, 0x19, 0xee, 0x0b, 0x00, 0x7e, 0xa0, 0x08, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x20, - 0x8b, 0x3e, 0x20, 0x89, 0x3b, 0x7e, 0xa0, 0x08, 0x19, 0xa2, 0x00, 0x04, 0x09, 0xa2, 0x00, 0x10, - 0x4e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x30, 0x8b, 0x23, 0x30, 0x89, 0x20, - 0x09, 0xa2, 0x00, 0x10, 0x5e, 0xa0, 0xfd, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, 0x7e, 0xa0, - 0x00, 0x19, 0xa2, 0x00, 0x04, 0x12, 0x19, 0xee, 0x20, 0x8b, 0x05, 0x20, 0x89, 0x02, 0x80, 0x1a, - 0x12, 0x1a, 0x08, 0x30, 0x09, 0x14, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x00, 0x00, 0x5e, - 0xa0, 0xfd, 0x19, 0xa2, 0x00, 0x10, 0x00, 0x00, 0x80, 0xec, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, - 0x89, 0x02, 0x19, 0x3b, 0x20, 0x17, 0xfa, 0x12, 0x13, 0x8a, 0x12, 0x19, 0x22, 0x7e, 0x24, 0x80, - 0x00, 0x7e, 0x11, 0x09, 0x0b, 0x00, 0x20, 0x89, 0x26, 0x7e, 0xa0, 0xff, 0x19, 0xa2, 0x00, 0x04, - 0x12, 0x19, 0xee, 0x7e, 0xb0, 0x55, 0x19, 0xb2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x30, 0x89, 0x0f, - 0x7e, 0xa0, 0x00, 0x19, 0xa2, 0x00, 0x04, 0x12, 0x19, 0xee, 0x20, 0x89, 0x02, 0x80, 0x26, 0x12, - 0x1a, 0x08, 0x30, 0x09, 0x20, 0x7e, 0xa0, 0xff, 0x19, 0xa2, 0x00, 0x04, 0x12, 0x19, 0xee, 0x7e, - 0xb0, 0x55, 0x19, 0xb2, 0x00, 0x00, 0x12, 0x19, 0xee, 0x7e, 0xa0, 0x00, 0x19, 0xa2, 0x00, 0x04, - 0x12, 0x19, 0xee, 0x80, 0xe0, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xa8, 0x02, 0x19, 0x3b, 0x7e, - 0x24, 0x80, 0x00, 0x7e, 0x11, 0x09, 0x7e, 0xa0, 0x08, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x19, 0xee, - 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xef, 0x22, 0x30, 0x0a, 0x19, 0x7e, 0x68, 0x0d, 0xf5, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0xd2, 0x09, 0x12, 0x19, 0xee, 0x12, 0x19, 0xee, 0x12, 0x19, - 0xee, 0x02, 0x0f, 0x10, 0x30, 0x17, 0x1c, 0x7e, 0x68, 0x0e, 0x6f, 0x7a, 0x6c, 0x00, 0xff, 0x12, - 0x1a, 0x93, 0x7e, 0x68, 0x0e, 0x91, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x1a, 0x93, 0x12, 0x1b, 0x3c, - 0x02, 0x19, 0xe6, 0x0b, 0x00, 0x7e, 0x78, 0x19, 0xa0, 0x7a, 0x7c, 0x00, 0xff, 0x7f, 0x67, 0x7a, - 0x6c, 0x00, 0x00, 0x7e, 0x70, 0x3e, 0x7e, 0x7b, 0xb0, 0x7a, 0x6b, 0xb0, 0x0b, 0x7c, 0x0b, 0x6c, - 0xa5, 0xdf, 0xf3, 0x7e, 0x78, 0x19, 0xa0, 0x7a, 0x7c, 0x00, 0x00, 0x89, 0x78, 0x7e, 0x78, 0x00, - 0x00, 0x7a, 0x7c, 0x00, 0xfe, 0x7e, 0x68, 0x7f, 0xbf, 0x7a, 0x6c, 0x00, 0xfe, 0x74, 0xaa, 0x39, - 0xb7, 0x55, 0x55, 0x74, 0x55, 0x39, 0xb7, 0x2a, 0xaa, 0x74, 0xa0, 0x39, 0xb7, 0x55, 0x55, 0x6c, - 0x99, 0x7a, 0x6b, 0x90, 0x7e, 0x54, 0x27, 0x10, 0x7e, 0x6b, 0x80, 0xbc, 0x89, 0x68, 0x08, 0x1b, - 0x54, 0x78, 0xf5, 0x8a, 0xff, 0x19, 0xde, 0x8a, 0xff, 0x19, 0xe6, 0x12, 0x1a, 0x08, 0x7e, 0x6b, - 0x80, 0x80, 0xfb, 0x7e, 0x10, 0xff, 0x12, 0x1a, 0x85, 0x80, 0xf8, 0xca, 0xf9, 0x7e, 0xf4, 0x00, - 0xff, 0x1b, 0xf4, 0x78, 0xfc, 0xda, 0xf9, 0x22, 0xca, 0xf9, 0x7e, 0xf4, 0x00, 0x00, 0x1b, 0xf4, - 0x78, 0xfc, 0xda, 0xf9, 0x22, 0x20, 0x09, 0x19, 0xd2, 0x0a, 0x12, 0x19, 0xfb, 0xc2, 0x95, 0xd2, - 0x94, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x43, 0x90, 0x30, - 0x22, 0xca, 0x0b, 0x7e, 0x10, 0x03, 0x7c, 0x30, 0x6c, 0x22, 0x0b, 0x20, 0x9e, 0x30, 0x0a, 0x50, - 0xf9, 0x2e, 0x30, 0x0b, 0x1b, 0x20, 0x68, 0x18, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x53, 0x90, - 0xcf, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x43, 0x90, 0x30, 0xa5, 0xda, 0xe8, - 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x1b, 0x30, 0x68, 0x19, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, - 0xc2, 0x95, 0xd2, 0x94, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x12, 0x19, 0xfb, 0x43, 0x90, 0x30, - 0xa5, 0xdb, 0xe7, 0x7e, 0x20, 0x0a, 0x12, 0x19, 0xfb, 0xa5, 0xda, 0xfa, 0xa5, 0xd9, 0xa7, 0xda, - 0x0b, 0x22, 0x20, 0x09, 0x0a, 0x12, 0x19, 0xfb, 0xb2, 0x94, 0x12, 0x19, 0xfb, 0xb2, 0x94, 0x22, - 0x30, 0x17, 0x32, 0x20, 0x09, 0x2f, 0xca, 0x2b, 0xca, 0x7b, 0x7e, 0x78, 0x80, 0x00, 0x7a, 0x7c, - 0x00, 0xfe, 0x12, 0x1b, 0x1c, 0x7e, 0x6b, 0xa0, 0x5c, 0xaa, 0x68, 0x10, 0x29, 0xb7, 0x00, 0x14, - 0x54, 0x60, 0x68, 0xf8, 0x39, 0xa7, 0x00, 0x00, 0x0b, 0x6c, 0x80, 0xe9, 0x12, 0x19, 0xee, 0xd2, - 0xb5, 0xda, 0x7b, 0xda, 0x2b, 0x22, 0x12, 0x1a, 0xd4, 0x7e, 0x68, 0x00, 0x0b, 0x12, 0x1a, 0x93, - 0x22, 0xca, 0x59, 0xca, 0x5b, 0x7e, 0xb4, 0x00, 0x0b, 0x7c, 0xb8, 0xc4, 0x12, 0x1b, 0x04, 0x7c, - 0xb8, 0x12, 0x1b, 0x04, 0x7c, 0xb9, 0xc4, 0x12, 0x1b, 0x04, 0x7c, 0xb9, 0x12, 0x1b, 0x04, 0x7e, - 0xb0, 0x68, 0x7a, 0xb9, 0xb0, 0x0b, 0xb4, 0x6c, 0xbb, 0x7a, 0xb9, 0xb0, 0xda, 0x59, 0xda, 0x5b, - 0x22, 0x5e, 0xb0, 0x0f, 0x7c, 0xab, 0x9e, 0xa0, 0x0a, 0x40, 0x05, 0x2e, 0xb0, 0x37, 0x80, 0x03, - 0x2e, 0xb0, 0x30, 0x7a, 0xb9, 0xb0, 0x0b, 0xb4, 0x22, 0xc2, 0xb5, 0xc2, 0x92, 0x12, 0x19, 0xee, - 0x74, 0x80, 0x39, 0xb7, 0x00, 0x0c, 0x7e, 0x54, 0x00, 0x06, 0x39, 0xa7, 0x00, 0x04, 0x39, 0xb7, - 0x00, 0x00, 0x74, 0x03, 0x39, 0xb7, 0x00, 0x0c, 0x22, 0x7e, 0x78, 0x00, 0x00, 0x7a, 0x7c, 0x00, - 0xff, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0x01, 0x7f, 0x65, 0x7e, 0x74, 0x20, 0x00, 0x12, - 0x08, 0xd6, 0x40, 0x54, 0x7e, 0x78, 0x7c, 0x00, 0x7a, 0x7c, 0x00, 0xff, 0x7e, 0x58, 0x00, 0x00, - 0x7a, 0x5c, 0x00, 0x01, 0x7e, 0x68, 0x7c, 0x00, 0x7a, 0x6c, 0x00, 0x01, 0x7e, 0x74, 0x04, 0x00, - 0x12, 0x08, 0xd6, 0x40, 0x33, 0x74, 0x80, 0x12, 0x1b, 0xb1, 0x40, 0x2c, 0x53, 0x90, 0xcf, 0xd2, - 0x08, 0x7e, 0x04, 0x00, 0x08, 0x7e, 0x14, 0x00, 0x00, 0x84, 0xa5, 0xdb, 0xfc, 0xa5, 0xda, 0xf9, - 0xa5, 0xd9, 0xf6, 0x74, 0x40, 0x12, 0x1b, 0xb1, 0x40, 0x0e, 0x7e, 0x68, 0x0e, 0xc0, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x1a, 0x93, 0x02, 0x19, 0xe6, 0xc2, 0x95, 0xd2, 0x94, 0x80, 0xfe, 0xf5, 0x0a, - 0x7e, 0x78, 0x00, 0x0a, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x68, 0x7f, 0xbf, 0x7a, 0x6c, 0x00, 0x01, - 0x7e, 0x74, 0x00, 0x01, 0x02, 0x08, 0xd6, -}; - -static struct edge_firmware_version_info IMAGE_VERSION_NAME = { - 1, 12, 2 }; // Major, Minor, Build - -#undef IMAGE_VERSION_NAME - -#undef IMAGE_ARRAY_NAME - diff --git a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h deleted file mode 100644 index e3463de..0000000 --- a/drivers/usb/serial/io_fw_boot2.h +++ /dev/null @@ -1,546 +0,0 @@ -//************************************************************** -//* Edgeport/4 Binary Image -//* Generated by HEX2C v1.06 -//* Copyright (C) 1998 Inside Out Networks, 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. -//************************************************************** - - -//Image structure definition -#if !defined(DEFINED_EDGE_FIRMWARE_IMAGE_RECORD) -#define DEFINED_EDGE_FIRMWARE_IMAGE_RECORD - struct edge_firmware_image_record { - __le16 ExtAddr; - __le16 Addr; - __le16 Len; - unsigned char Data[0]; - } __attribute__ ((packed)); - - struct edge_firmware_version_info { - unsigned char MajorVersion; - unsigned char MinorVersion; - unsigned short BuildNumber; - }; - -#endif - -#if !defined(IMAGE_ARRAY_NAME) -#define IMAGE_ARRAY_NAME FirmwareImage -#define IMAGE_VERSION_NAME FirmwareImageVersion -#endif - -static unsigned char IMAGE_ARRAY_NAME[] = { - -// Segment #1, Start Address 00ff0000, Length 6 -0xff,0x00,0x00,0x00,0x06,0x00, - 0x02, 0x00, 0x80, 0x02, 0x00, 0x03, - -// Segment #2, Start Address 00ff000b, Length 3 -0xff,0x00,0x0b,0x00,0x03,0x00, - 0x02, 0x00, 0x0b, - -// Segment #3, Start Address 00ff0013, Length 3 -0xff,0x00,0x13,0x00,0x03,0x00, - 0x02, 0x02, 0x56, - -// Segment #4, Start Address 00ff001b, Length 3 -0xff,0x00,0x1b,0x00,0x03,0x00, - 0x02, 0x00, 0x1b, - -// Segment #5, Start Address 00ff0023, Length 3 -0xff,0x00,0x23,0x00,0x03,0x00, - 0x02, 0x00, 0x23, - -// Segment #6, Start Address 00ff002b, Length 3 -0xff,0x00,0x2b,0x00,0x03,0x00, - 0x02, 0x00, 0x2b, - -// Segment #7, Start Address 00ff0033, Length 3 -0xff,0x00,0x33,0x00,0x03,0x00, - 0x02, 0x00, 0x33, - -// Segment #8, Start Address 00ff003b, Length 3 -0xff,0x00,0x3b,0x00,0x03,0x00, - 0x02, 0x00, 0x3b, - -// Segment #9, Start Address 00ff0043, Length 3 -0xff,0x00,0x43,0x00,0x03,0x00, - 0x02, 0x00, 0x43, - -// Segment #10, Start Address 00ff004b, Length 3 -0xff,0x00,0x4b,0x00,0x03,0x00, - 0x02, 0x00, 0x4b, - -// Segment #11, Start Address 00ff0053, Length 3 -0xff,0x00,0x53,0x00,0x03,0x00, - 0x02, 0x01, 0xf5, - -// Segment #12, Start Address 00ff007b, Length 3 -0xff,0x00,0x7b,0x00,0x03,0x00, - 0x02, 0x00, 0x7b, - -// Segment #13, Start Address 00ff0080, Length 534 -0xff,0x00,0x80,0x00,0x16,0x02, - 0x7e, 0xb3, 0x91, 0x01, 0x20, 0xe3, 0x0c, 0x7e, 0xb3, 0x3f, 0xf2, 0x54, 0xfe, 0x7a, 0xb3, 0x3f, - 0xf2, 0x80, 0x0a, 0x7e, 0xb3, 0x3f, 0xf2, 0x44, 0x01, 0x7a, 0xb3, 0x3f, 0xf2, 0x74, 0x00, 0x7a, - 0xb3, 0x91, 0x00, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x12, 0x7e, 0xf8, 0x00, 0x24, 0x7e, 0x00, 0x01, - 0x7e, 0x10, 0x00, 0x12, 0x09, 0xd0, 0x69, 0x20, 0x00, 0x0a, 0x5e, 0x40, 0x1f, 0xbe, 0x24, 0x00, - 0x00, 0x78, 0x09, 0x7e, 0x00, 0x03, 0x7a, 0x03, 0x90, 0x00, 0x80, 0x07, 0x7e, 0x00, 0x02, 0x7a, - 0x03, 0x90, 0x00, 0x75, 0xb0, 0xdf, 0x7e, 0x00, 0x01, 0x7a, 0x03, 0x94, 0x00, 0x7a, 0x03, 0x01, - 0x24, 0x7e, 0x00, 0x01, 0x7a, 0x03, 0x93, 0x00, 0x7e, 0x00, 0x00, 0xa5, 0xd8, 0xfd, 0x75, 0xa8, - 0x00, 0x75, 0xb1, 0x00, 0xca, 0x29, 0x12, 0x0c, 0x66, 0x12, 0x0c, 0x37, 0xf5, 0x21, 0x7a, 0xa1, - 0x20, 0x20, 0x09, 0x08, 0x20, 0x0a, 0x0a, 0x7e, 0xb0, 0x0c, 0x80, 0x08, 0x7e, 0xb0, 0x00, 0x80, - 0x03, 0x7e, 0xb0, 0x08, 0x7a, 0xb3, 0x92, 0x00, 0x12, 0x02, 0x96, 0xda, 0x29, 0x74, 0x10, 0x7a, - 0xb3, 0x91, 0x01, 0x7e, 0x20, 0x04, 0x7c, 0xb2, 0xc2, 0xd7, 0x13, 0x13, 0x13, 0x13, 0x7a, 0xb3, - 0x91, 0x00, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x10, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x74, 0x02, - 0x7a, 0xb3, 0x91, 0x12, 0xa5, 0xda, 0xdf, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, - 0xb3, 0x91, 0x1c, 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x07, 0x74, - 0x34, 0x7a, 0xb3, 0x91, 0x13, 0x74, 0x3f, 0x7a, 0xb3, 0x91, 0x14, 0x74, 0x02, 0x7a, 0xb3, 0x91, - 0x06, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x07, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x44, 0x7a, - 0xb3, 0x91, 0x07, 0x74, 0xef, 0x7a, 0xb3, 0x91, 0x04, 0x74, 0x07, 0x7a, 0xb3, 0x91, 0x06, 0x7e, - 0xb3, 0x91, 0x07, 0x7a, 0xb1, 0x0a, 0x75, 0x09, 0x01, 0xd2, 0xaa, 0xd2, 0xaf, 0xe4, 0x7e, 0x60, - 0x02, 0x4d, 0x22, 0x78, 0x03, 0x7e, 0x60, 0x03, 0x7c, 0x76, 0x7e, 0x04, 0x28, 0x00, 0x8d, 0xef, - 0x1b, 0x04, 0x78, 0xfa, 0x04, 0x7e, 0x20, 0x07, 0x7a, 0x23, 0x91, 0x06, 0x7e, 0x23, 0x91, 0x07, - 0x7e, 0x31, 0x0a, 0xbc, 0x32, 0x68, 0x22, 0x7a, 0x21, 0x0a, 0x7e, 0x21, 0x09, 0x68, 0x17, 0xca, - 0xb8, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x7e, 0xb3, 0x91, 0x07, 0x44, 0x02, 0x7a, 0xb3, 0x91, - 0x07, 0xda, 0xb8, 0x75, 0x09, 0x00, 0x30, 0xe0, 0xc1, 0x6c, 0x67, 0x7a, 0x63, 0x90, 0x00, 0x80, - 0xb9, 0xbe, 0xb0, 0x02, 0x22, 0xc0, 0xd0, 0x75, 0x08, 0xfe, 0x12, 0x0a, 0xc0, 0x74, 0x02, 0x7a, - 0xb3, 0x91, 0x06, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x07, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x74, - 0x00, 0x7a, 0xb3, 0x91, 0x07, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x04, 0x7e, 0xb3, 0x3f, 0xf2, 0x30, - 0xe0, 0x08, 0x74, 0x18, 0x7a, 0xb3, 0x91, 0x01, 0x80, 0x06, 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x01, - 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x04, 0x02, 0x02, 0x36, 0x75, 0x08, 0xff, 0x12, 0x0a, 0xc0, 0x74, - 0x01, 0x7a, 0xb3, 0x91, 0x04, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x7e, 0xb3, 0x91, 0x07, 0x54, - 0xfc, 0x7a, 0xb3, 0x91, 0x07, 0x32, 0xca, 0xb8, 0x75, 0x08, 0x02, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, - 0x91, 0x03, 0x20, 0xe5, 0x08, 0x30, 0xe0, 0x2b, 0x12, 0x02, 0x9e, 0x80, 0xf1, 0x7e, 0xb3, 0x91, - 0x04, 0x30, 0xe0, 0x05, 0xda, 0xb8, 0x02, 0x02, 0x39, 0x30, 0xe1, 0x05, 0xda, 0xb8, 0x02, 0x01, - 0xf5, 0x30, 0xe6, 0x05, 0x12, 0x04, 0x03, 0x80, 0xd5, 0x30, 0xe2, 0x05, 0xda, 0xb8, 0x02, 0x00, - 0x80, 0x80, 0xcb, 0xda, 0xb8, 0x32, - -// Segment #14, EXCLUDED Start Address 00ff31d7, Length 1 - - -// Segment #15, Start Address 00ff0296, Length 2090 -0xff,0x00,0x96,0x02,0x2a,0x08, - 0xe4, 0x7a, 0xb3, 0x3f, 0xf1, 0x02, 0x03, 0x41, 0xca, 0x0b, 0xca, 0x1b, 0xca, 0x2b, 0xca, 0x3b, - 0xca, 0x4b, 0xca, 0x5b, 0xca, 0x6b, 0xca, 0x7b, 0xca, 0xeb, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, - 0x7e, 0xb3, 0x01, 0x2e, 0xb4, 0x00, 0x02, 0x80, 0x1c, 0xb4, 0x01, 0x19, 0x7e, 0xb3, 0x91, 0x14, - 0x54, 0x14, 0x68, 0x05, 0x12, 0x03, 0x05, 0x80, 0x23, 0x7e, 0xb3, 0x91, 0x14, 0x30, 0xe5, 0x1c, - 0x12, 0x04, 0x43, 0x80, 0x17, 0x7e, 0xb3, 0x91, 0x14, 0x30, 0xe5, 0x05, 0x12, 0x04, 0x43, 0x80, - 0x0b, 0x7e, 0xb3, 0x91, 0x14, 0x54, 0x14, 0x68, 0x03, 0x12, 0x03, 0x05, 0xda, 0xeb, 0xda, 0x7b, - 0xda, 0x6b, 0xda, 0x5b, 0xda, 0x4b, 0xda, 0x3b, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0x20, - 0xe4, 0x19, 0x75, 0x08, 0x0a, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x01, 0x2d, 0x70, 0x0a, 0x7e, 0xb3, - 0x01, 0x2e, 0xb4, 0x01, 0x1f, 0x02, 0x03, 0x9d, 0x02, 0x09, 0x8b, 0x75, 0x08, 0x0b, 0x12, 0x0a, - 0xc0, 0x74, 0x14, 0x7a, 0xb3, 0x91, 0x14, 0x7e, 0xb3, 0x01, 0x2e, 0xb4, 0x02, 0x0c, 0x12, 0x03, - 0x4d, 0x02, 0x03, 0x41, 0x74, 0x04, 0x7a, 0xb3, 0x91, 0x14, 0x22, 0x7e, 0x00, 0x00, 0x7a, 0x03, - 0x01, 0x2e, 0x7a, 0x03, 0x01, 0x2f, 0x22, 0x7e, 0xb3, 0x01, 0x25, 0x54, 0x60, 0x60, 0x05, 0xb4, - 0x40, 0x1e, 0x80, 0x1c, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x05, 0x15, 0x75, 0x08, 0x71, 0x12, 0x0a, - 0xc0, 0x7e, 0xb3, 0x01, 0x28, 0x7e, 0xa0, 0x01, 0x7a, 0xa3, 0x91, 0x06, 0x7a, 0xb3, 0x91, 0x07, - 0x22, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x12, 0x22, 0xbe, 0x57, - 0x01, 0x2b, 0x28, 0x04, 0x7e, 0x57, 0x01, 0x2b, 0x7a, 0x0f, 0x01, 0x31, 0x7a, 0x57, 0x01, 0x35, - 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x12, 0x22, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x91, - 0x1a, 0x70, 0x53, 0x7e, 0xb3, 0x91, 0x14, 0x20, 0xe4, 0x4c, 0x7e, 0xef, 0x01, 0x31, 0x7e, 0xf7, - 0x01, 0x35, 0x7e, 0x07, 0x01, 0x35, 0x4d, 0x00, 0x68, 0x21, 0x7e, 0x00, 0x00, 0xe0, 0x7a, 0xb3, - 0x91, 0x17, 0xa3, 0xa5, 0x08, 0x1b, 0xf4, 0x68, 0x06, 0xa5, 0xb8, 0x10, 0xf0, 0x80, 0x19, 0x7e, - 0xb0, 0x00, 0x7a, 0xb3, 0x01, 0x2e, 0xbe, 0x00, 0x10, 0x68, 0x0d, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, - 0x01, 0x2e, 0x74, 0x80, 0x7a, 0xb3, 0x91, 0x1e, 0x7a, 0xef, 0x01, 0x31, 0x7a, 0xf7, 0x01, 0x35, - 0x75, 0x08, 0x06, 0x12, 0x0a, 0xc0, 0x74, 0x04, 0x7a, 0xb3, 0x91, 0x14, 0x22, 0xca, 0x0b, 0xca, - 0x1b, 0xca, 0x2b, 0xca, 0x3b, 0xca, 0x4b, 0xca, 0x5b, 0xca, 0x6b, 0xca, 0x7b, 0xca, 0xeb, 0x75, - 0x08, 0x03, 0x12, 0x0a, 0xc0, 0x74, 0x00, 0x7a, 0xb3, 0x01, 0x2d, 0x74, 0x00, 0x7a, 0xb3, 0x91, - 0x00, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x12, 0x12, 0x04, 0xb2, 0xda, 0xeb, 0xda, 0x7b, 0xda, 0x6b, - 0xda, 0x5b, 0xda, 0x4b, 0xda, 0x3b, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0x75, 0x08, 0x03, - 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x01, 0x2f, 0xb4, 0x02, 0x11, 0x74, 0x00, 0x7a, 0xb3, 0x01, 0x2f, - 0x7a, 0xb3, 0x01, 0x2e, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x14, 0x22, 0xb4, 0x01, 0x46, 0x7e, 0xb3, - 0x91, 0x04, 0x20, 0xe6, 0x42, 0x7e, 0x23, 0x91, 0x1a, 0x7c, 0x32, 0x7e, 0x13, 0x01, 0x30, 0x2c, - 0x21, 0x7a, 0x23, 0x01, 0x30, 0x7e, 0x00, 0x00, 0x2e, 0x04, 0x01, 0x37, 0x7e, 0xb3, 0x91, 0x16, - 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0xa5, 0xdb, 0xf4, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x14, 0x75, 0x08, - 0x70, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x01, 0x30, 0x7e, 0xa3, 0x01, 0x2c, 0xbc, 0xab, 0x78, 0x03, - 0x12, 0x05, 0x52, 0x22, 0x02, 0x09, 0x8b, 0xda, 0x59, 0x02, 0x04, 0x15, 0x74, 0xe0, 0x7a, 0xb3, - 0x91, 0x00, 0x7e, 0x03, 0x91, 0x10, 0x7e, 0x13, 0x91, 0x11, 0x7e, 0x33, 0x91, 0x12, 0x7e, 0x23, - 0x91, 0x13, 0x7e, 0x53, 0x91, 0x14, 0x7e, 0x43, 0x91, 0x15, 0x7e, 0x73, 0x91, 0x16, 0x7e, 0x63, - 0x91, 0x17, 0x7a, 0x0f, 0x01, 0x25, 0x7a, 0x1f, 0x01, 0x29, 0x75, 0x08, 0x04, 0x12, 0x0a, 0xc0, - 0x7a, 0x01, 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x11, 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x21, 0x08, 0x12, - 0x0a, 0xc0, 0x7a, 0x31, 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x41, 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x51, - 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x61, 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x71, 0x08, 0x12, 0x0a, 0xc0, - 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x04, 0x12, 0x05, 0x26, 0x22, - 0x6d, 0x00, 0x7e, 0x14, 0x01, 0x02, 0x7a, 0x07, 0x01, 0x35, 0x7a, 0x03, 0x01, 0x30, 0x7e, 0xb3, - 0x01, 0x25, 0x20, 0xe7, 0x0f, 0x7a, 0x23, 0x01, 0x2f, 0x7a, 0x33, 0x01, 0x2e, 0xbe, 0x07, 0x01, - 0x2b, 0x68, 0x09, 0x22, 0x7a, 0x33, 0x01, 0x2f, 0x7a, 0x23, 0x01, 0x2e, 0x7e, 0xb3, 0x01, 0x25, - 0x54, 0xe3, 0x23, 0x23, 0x30, 0xe0, 0x02, 0xd2, 0xe5, 0x30, 0xe7, 0x02, 0xd2, 0xe4, 0x30, 0xe5, - 0x06, 0x30, 0xe4, 0x03, 0x02, 0x09, 0x8b, 0x54, 0x3e, 0xf5, 0xf0, 0x03, 0x54, 0x1f, 0xc3, 0x25, - 0xf0, 0x90, 0x05, 0x7e, 0x75, 0x84, 0xff, 0x73, 0x02, 0x07, 0x39, 0x02, 0x05, 0xc6, 0x02, 0x07, - 0xd2, 0x02, 0x07, 0xed, 0x02, 0x06, 0xd0, 0x02, 0x06, 0x5b, 0x02, 0x08, 0x1e, 0x02, 0x08, 0x1e, - 0x02, 0x08, 0x21, 0x02, 0x08, 0x21, 0x02, 0x08, 0x21, 0x02, 0x08, 0x21, 0x02, 0x08, 0x21, 0x02, - 0x08, 0x21, 0x02, 0x08, 0x21, 0x02, 0x08, 0x21, 0x02, 0x08, 0x27, 0x02, 0x08, 0xf9, 0x02, 0x08, - 0x24, 0x02, 0x08, 0x24, 0x02, 0x08, 0x24, 0x02, 0x08, 0x24, 0x02, 0x08, 0x24, 0x02, 0x08, 0x24, - 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x7e, 0xb3, 0x01, 0x26, - 0xb4, 0x06, 0x2a, 0x7e, 0xb3, 0x01, 0x27, 0x60, 0x79, 0x7c, 0x0b, 0x7e, 0x13, 0x01, 0x28, 0x7e, - 0x17, 0x01, 0x29, 0x75, 0x08, 0x72, 0x12, 0x0a, 0xc0, 0x7a, 0x01, 0x08, 0x12, 0x0a, 0xc0, 0x7a, - 0x11, 0x08, 0x12, 0x0a, 0xc0, 0x12, 0x09, 0xd0, 0x40, 0x58, 0x02, 0x03, 0x84, 0xb4, 0x08, 0x1c, - 0x75, 0x08, 0x74, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x3f, 0xf1, 0x7e, 0x08, 0x01, 0x37, 0x7a, 0x0c, - 0x00, 0x00, 0x7a, 0x0b, 0xb0, 0x7e, 0x54, 0x00, 0x01, 0x02, 0x03, 0x84, 0xb4, 0x00, 0x33, 0x75, - 0x08, 0x75, 0x12, 0x0a, 0xc0, 0x7e, 0x08, 0x01, 0x37, 0x7a, 0x0c, 0x00, 0x00, 0xca, 0x0b, 0x7e, - 0xb3, 0x3f, 0xf2, 0x30, 0xe0, 0x07, 0x74, 0x02, 0x7a, 0x0b, 0xb0, 0x80, 0x05, 0x74, 0x00, 0x7a, - 0x0b, 0xb0, 0x0b, 0x14, 0x74, 0x00, 0x7a, 0x0b, 0xb0, 0x7e, 0x54, 0x00, 0x02, 0xda, 0x0b, 0x02, - 0x03, 0x84, 0x02, 0x09, 0x8b, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, - 0x1c, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x00, 0x5f, 0x75, 0x08, 0x76, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, - 0x01, 0x2a, 0x54, 0x0f, 0xb4, 0x02, 0x05, 0x7e, 0xb0, 0x60, 0x80, 0x17, 0xb4, 0x00, 0x05, 0x7e, - 0xb0, 0x00, 0x80, 0x0f, 0x7e, 0xb3, 0x01, 0x2a, 0x20, 0xe7, 0x05, 0x7e, 0xb0, 0x40, 0x80, 0x03, - 0x7e, 0xb0, 0x20, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x91, 0x11, 0x30, 0xe0, 0x04, 0x74, 0x01, - 0x80, 0x02, 0x74, 0x00, 0x7e, 0x08, 0x01, 0x37, 0x7a, 0x0c, 0x00, 0x00, 0xca, 0x0b, 0x7a, 0x0b, - 0xb0, 0x0b, 0x14, 0x74, 0x00, 0x7a, 0x0b, 0xb0, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0x54, - 0x00, 0x02, 0xda, 0x0b, 0x02, 0x03, 0x84, 0x02, 0x09, 0x8b, 0x7e, 0xb3, 0x01, 0x2a, 0x54, 0x0f, - 0xb4, 0x02, 0x05, 0x7e, 0xb0, 0x60, 0x80, 0x17, 0xb4, 0x00, 0x05, 0x7e, 0xb0, 0x00, 0x80, 0x0f, - 0x7e, 0xb3, 0x01, 0x2a, 0x20, 0xe7, 0x05, 0x7e, 0xb0, 0x40, 0x80, 0x03, 0x7e, 0xb0, 0x20, 0x7a, - 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x01, 0x28, 0xb4, 0x00, 0x26, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x01, - 0x0e, 0x75, 0x08, 0x77, 0x12, 0x0a, 0xc0, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x12, 0x80, 0x1b, 0xb4, - 0x03, 0x0e, 0x75, 0x08, 0x78, 0x12, 0x0a, 0xc0, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x11, 0x80, 0x0a, - 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x12, 0x09, 0x8b, 0x22, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, - 0x02, 0x03, 0x77, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x09, 0x1f, 0x75, 0x08, 0x79, 0x12, 0x0a, 0xc0, - 0x7e, 0xb3, 0x01, 0x28, 0xbe, 0xb3, 0x3f, 0xf1, 0x68, 0x0d, 0xca, 0xb8, 0x12, 0x01, 0xf1, 0xda, - 0xb8, 0x50, 0x76, 0x7a, 0xb3, 0x3f, 0xf1, 0x80, 0x6d, 0xb4, 0x05, 0x08, 0x75, 0x08, 0x7a, 0x12, - 0x0a, 0xc0, 0x80, 0x62, 0xb4, 0x03, 0x19, 0x75, 0x08, 0x7b, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x01, - 0x28, 0xb4, 0x01, 0x55, 0x7e, 0xb3, 0x3f, 0xf2, 0x44, 0x01, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, 0x46, - 0xb4, 0x01, 0x19, 0x75, 0x08, 0x7c, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x01, 0x28, 0xb4, 0x01, 0x39, - 0x7e, 0xb3, 0x3f, 0xf2, 0x54, 0xfe, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, 0x2a, 0xb4, 0x07, 0x2a, 0x7e, - 0xb3, 0x01, 0x27, 0x60, 0x24, 0x7c, 0x0b, 0x7e, 0x13, 0x01, 0x28, 0x7e, 0x17, 0x01, 0x29, 0x75, - 0x08, 0x73, 0x12, 0x0a, 0xc0, 0x7a, 0x01, 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x11, 0x08, 0x12, 0x0a, - 0xc0, 0x12, 0x0a, 0x0a, 0x40, 0x03, 0x02, 0x03, 0x77, 0x02, 0x09, 0x8b, 0x7e, 0xb3, 0x01, 0x26, - 0xb4, 0x0b, 0xf6, 0x75, 0x08, 0x7d, 0x12, 0x0a, 0xc0, 0x7e, 0xb3, 0x01, 0x28, 0x7e, 0xa3, 0x01, - 0x2a, 0x4c, 0xab, 0x78, 0xe4, 0x80, 0xdf, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, - 0xb3, 0x91, 0x1c, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x0a, 0xcf, 0x75, 0x08, 0x7e, 0x12, 0x0a, 0xc0, - 0x7e, 0xb3, 0x01, 0x28, 0x70, 0xc3, 0x7e, 0x08, 0x01, 0x37, 0x7a, 0x0c, 0x00, 0x00, 0x7a, 0x0b, - 0xb0, 0x7e, 0x54, 0x00, 0x01, 0x02, 0x03, 0x84, 0x02, 0x09, 0x8b, 0x02, 0x09, 0x8b, 0x02, 0x09, - 0x8b, 0x7e, 0xb3, 0x01, 0x26, 0xb4, 0x04, 0x20, 0x75, 0x08, 0xc3, 0x12, 0x0a, 0xc0, 0x7e, 0x04, - 0x00, 0x01, 0x7e, 0x17, 0x01, 0x27, 0x7e, 0x18, 0x01, 0x37, 0x7a, 0x1c, 0x00, 0x00, 0x7e, 0x47, - 0x01, 0x2b, 0x12, 0x0a, 0xcc, 0x02, 0x08, 0xf3, 0xb4, 0x06, 0x42, 0x75, 0x08, 0xc1, 0x12, 0x0a, - 0xc0, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7d, 0xca, 0x7e, 0xd7, 0x01, 0x27, 0x7e, - 0x78, 0x01, 0x37, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x77, 0x01, 0x2b, 0x75, 0x08, 0xc1, 0x12, 0x0a, - 0xc0, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, 0x94, 0x00, 0x12, 0x0b, 0x63, 0x7e, - 0x43, 0x01, 0x24, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, 0x40, 0x65, 0x80, 0x60, 0xb4, 0x00, 0x24, - 0xc2, 0xaf, 0x7e, 0xb0, 0x01, 0x7a, 0xb3, 0x94, 0x00, 0x7a, 0xb3, 0x01, 0x24, 0x12, 0x03, 0x77, - 0xe4, 0x8d, 0xef, 0x8d, 0xef, 0x8d, 0xef, 0xd5, 0xe0, 0xf7, 0xc0, 0xd1, 0xca, 0x02, 0xff, 0xca, - 0x06, 0x00, 0x00, 0x32, 0xb4, 0x09, 0x20, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x7e, 0x23, 0x91, - 0x07, 0x7e, 0x57, 0x01, 0x27, 0x4d, 0x55, 0x68, 0x05, 0x4e, 0x20, 0x02, 0x80, 0x03, 0x5e, 0x20, - 0xfd, 0x7a, 0x23, 0x91, 0x07, 0x80, 0x16, 0xb4, 0x07, 0x16, 0xc2, 0xaf, 0x7e, 0x07, 0x01, 0x29, - 0x7e, 0x17, 0x01, 0x27, 0xc0, 0xd1, 0xca, 0x18, 0xca, 0x38, 0xca, 0x28, 0x32, 0x02, 0x03, 0x77, - 0x02, 0x09, 0x8b, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x7e, - 0xb3, 0x01, 0x26, 0xb4, 0x03, 0x15, 0x75, 0x08, 0xc2, 0x12, 0x0a, 0xc0, 0x7e, 0x04, 0x00, 0x01, - 0x7e, 0x17, 0x01, 0x27, 0x7e, 0x57, 0x01, 0x2b, 0x02, 0x03, 0x84, 0xb4, 0x05, 0x41, 0x75, 0x08, - 0xc0, 0x12, 0x0a, 0xc0, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, 0x94, 0x00, 0x7e, - 0x08, 0x01, 0x37, 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x24, 0x00, 0xfe, 0x7e, 0x37, 0x01, 0x27, 0x7e, - 0x47, 0x01, 0x2b, 0x12, 0x0a, 0xcc, 0x7e, 0x43, 0x01, 0x24, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, - 0x7e, 0x08, 0x01, 0x37, 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x57, 0x01, 0x2b, 0x02, 0x03, 0x84, 0xb4, - 0x01, 0x20, 0x7e, 0x00, 0x00, 0x7e, 0x10, 0x01, 0x75, 0x08, 0x72, 0x12, 0x0a, 0xc0, 0x7a, 0x01, - 0x08, 0x12, 0x0a, 0xc0, 0x7a, 0x11, 0x08, 0x12, 0x0a, 0xc0, 0x12, 0x09, 0xd0, 0x40, 0x03, 0x02, - 0x03, 0x84, 0x02, 0x09, 0x8b, 0x75, 0x08, 0x07, 0x12, 0x0a, 0xc0, 0x7e, 0xb0, 0x02, 0x7a, 0xb3, - 0x90, 0x00, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x15, 0x74, 0x01, - 0x7a, 0xb3, 0x91, 0x11, 0x7e, 0xb3, 0x91, 0x15, 0x54, 0x60, 0xbe, 0xb0, 0x40, 0x68, 0x08, 0x74, - 0x20, 0x7a, 0xb3, 0x91, 0x15, 0x80, 0xed, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x12, 0x74, 0x04, 0x7a, - 0xb3, 0x91, 0x14, 0x74, 0xff, 0x7a, 0xb3, 0x01, 0x2d, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, - 0x01, 0x7a, 0x43, 0x94, 0x00, 0x12, 0x0a, 0x57, 0x40, 0x1f, 0x7e, 0x08, 0x01, 0x37, 0x7a, 0x0c, - 0x00, 0x00, 0xca, 0x0b, 0xca, 0x49, 0x12, 0x0a, 0xcc, 0xda, 0x59, 0xda, 0x0b, 0x7e, 0x43, 0x01, - 0x24, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, 0xc3, 0x22, 0x7e, 0x43, 0x01, 0x24, 0x7a, 0x43, 0x94, - 0x00, 0xd0, 0xa8, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, 0x94, 0x00, 0x12, - 0x0a, 0x57, 0x40, 0x31, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7f, 0x61, 0x7e, 0x78, - 0x01, 0x37, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x77, 0x01, 0x2b, 0xbd, 0x74, 0x78, 0x17, 0x75, 0x08, - 0xc1, 0x12, 0x0a, 0xc0, 0x12, 0x0b, 0x63, 0x40, 0x0c, 0x7e, 0x43, 0x01, 0x24, 0x7a, 0x43, 0x94, - 0x00, 0xd0, 0xa8, 0xc3, 0x22, 0x7e, 0x43, 0x01, 0x24, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, 0xd3, - 0x22, 0x7e, 0x24, 0x00, 0xfe, 0x7e, 0x34, 0x7f, 0xca, 0x0b, 0x1a, 0x50, 0xc5, 0xf0, 0x7d, 0x62, - 0x7d, 0x75, 0x7d, 0x87, 0x7e, 0x34, 0x7f, 0x03, 0x7e, 0x1b, 0xb0, 0xbc, 0x0b, 0x50, 0x49, 0x3e, - 0x00, 0x3e, 0x00, 0x0a, 0x50, 0x2d, 0x75, 0x0b, 0x3a, 0x30, 0x69, 0x53, 0x00, 0x02, 0xbd, 0x38, - 0x50, 0x02, 0x2d, 0x38, 0xbc, 0x1b, 0x50, 0x30, 0x3e, 0x10, 0x3e, 0x10, 0x0a, 0x51, 0x2d, 0x35, - 0x69, 0x41, 0x00, 0x02, 0x0b, 0x1a, 0x30, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, 0xbe, 0x44, 0xff, - 0xff, 0x78, 0x05, 0x7e, 0x1b, 0x90, 0x0a, 0x49, 0x4d, 0x44, 0x68, 0x0c, 0xbe, 0x44, 0x00, 0xff, - 0x28, 0x04, 0x7e, 0x44, 0x00, 0xff, 0xc3, 0x22, 0xd3, 0x22, - -// Segment #16, EXCLUDED Start Address 00ff7c00, Length 227 - - -// Segment #17, EXCLUDED Start Address 00ff7f00, Length 192 - - -// Segment #17, Start Address 00ff7fc0, Length 64 -0xff,0x00,0xc0,0x7f,0x40,0x00, - 0x40, 0x01, 0x02, 0x00, 0xd7, 0x31, 0x02, 0x00, 0x03, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -// Segment #18, Start Address 00ff0ac0, Length 4163 -0xff,0x00,0xc0,0x0a,0x43,0x10, - 0xca, 0x08, 0x7e, 0x01, 0x08, 0x7a, 0x03, 0x3f, 0xf0, 0xda, 0x08, 0x22, 0x80, 0x50, 0x0b, 0x1a, - 0x60, 0x0b, 0x35, 0x0b, 0x1a, 0x70, 0x0b, 0x35, 0x0b, 0x1a, 0x80, 0x0b, 0x35, 0x0b, 0x1a, 0x90, - 0x0b, 0x35, 0x0b, 0x1a, 0xa0, 0x0b, 0x35, 0x0b, 0x1a, 0xb0, 0x0b, 0x35, 0x0b, 0x1a, 0xc0, 0x0b, - 0x35, 0x0b, 0x1a, 0xd0, 0x0b, 0x35, 0x1b, 0x0a, 0x60, 0x0b, 0x15, 0x1b, 0x0a, 0x70, 0x0b, 0x15, - 0x1b, 0x0a, 0x80, 0x0b, 0x15, 0x1b, 0x0a, 0x90, 0x0b, 0x15, 0x1b, 0x0a, 0xa0, 0x0b, 0x15, 0x1b, - 0x0a, 0xb0, 0x0b, 0x15, 0x1b, 0x0a, 0xc0, 0x0b, 0x15, 0x1b, 0x0a, 0xd0, 0x0b, 0x15, 0x9e, 0x44, - 0x00, 0x10, 0x50, 0xaa, 0x2e, 0x44, 0x00, 0x10, 0x68, 0x0e, 0x7e, 0x1b, 0xc0, 0x7a, 0x0b, 0xc0, - 0x0b, 0x14, 0x0b, 0x34, 0x1b, 0x44, 0x78, 0xf2, 0x22, 0x7f, 0x6f, 0x7f, 0xf0, 0x1b, 0xfc, 0x7c, - 0x54, 0x7d, 0x32, 0x80, 0x08, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0x9e, 0x44, 0x00, - 0x10, 0x50, 0xf2, 0x2e, 0x44, 0x00, 0x10, 0x68, 0x06, 0xca, 0x48, 0x1b, 0x44, 0x78, 0xfa, 0x7f, - 0xf6, 0x89, 0xe4, 0xca, 0x6b, 0x5e, 0xd4, 0x00, 0x3f, 0x68, 0x20, 0x7e, 0x84, 0x00, 0x40, 0x9d, - 0x8d, 0xda, 0x6b, 0xbd, 0x87, 0x38, 0x16, 0xca, 0x79, 0x7d, 0x78, 0x12, 0x0b, 0x8d, 0xda, 0x79, - 0x40, 0x08, 0x9d, 0x78, 0x68, 0x02, 0x80, 0x05, 0xc2, 0xd7, 0x22, 0xda, 0x6b, 0x7e, 0xc0, 0x03, - 0x7e, 0xd0, 0x00, 0x7a, 0xd3, 0x90, 0x00, 0x74, 0xaa, 0x39, 0xb5, 0x55, 0x55, 0x74, 0x55, 0x39, - 0xb5, 0x2a, 0xaa, 0x74, 0xa0, 0x39, 0xb5, 0x55, 0x55, 0x7e, 0x04, 0x00, 0x40, 0x9d, 0x70, 0x50, - 0x06, 0x2d, 0x70, 0x7d, 0x07, 0x6d, 0x77, 0x7c, 0x31, 0x7e, 0x7b, 0x00, 0x7a, 0x6b, 0x00, 0x0b, - 0x7c, 0x0b, 0x6c, 0xa5, 0xd9, 0xf3, 0x7f, 0x16, 0x1b, 0x1c, 0x7e, 0x54, 0x27, 0x10, 0x7e, 0x1b, - 0x10, 0xbc, 0x10, 0x68, 0x06, 0x1b, 0x54, 0x78, 0xf5, 0x80, 0x2f, 0x6d, 0x00, 0x7c, 0x20, 0x7f, - 0x16, 0x9f, 0x10, 0x7f, 0x27, 0x9f, 0x20, 0x7e, 0x2b, 0x00, 0x7e, 0x1b, 0x10, 0xbc, 0x01, 0x78, - 0x19, 0x0b, 0x2c, 0x0b, 0x1c, 0xa5, 0xdb, 0xef, 0x7c, 0xb6, 0x20, 0xe0, 0x06, 0x6c, 0xdc, 0x7a, - 0xd3, 0x90, 0x00, 0x4d, 0x77, 0x78, 0x90, 0xc2, 0xd7, 0x22, 0xd2, 0xd7, 0x22, 0x00, 0x04, 0x00, - 0x04, 0x00, 0x00, 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x08, 0x10, 0x02, 0x10, - 0x04, 0x02, 0x08, 0x00, 0x01, 0x01, 0x08, 0x7e, 0x18, 0x7f, 0xbd, 0x7a, 0x1c, 0x00, 0xff, 0x0b, - 0x1a, 0x00, 0x5e, 0x10, 0x1f, 0xbe, 0x10, 0x14, 0x38, 0x1a, 0x0a, 0x51, 0x23, 0x7e, 0x18, 0x0c, - 0x0d, 0x7a, 0x1c, 0x00, 0xff, 0x2d, 0x35, 0x0b, 0x1a, 0x50, 0x60, 0x08, 0xa5, 0xb8, 0x02, 0x03, - 0x4e, 0xa0, 0x08, 0x22, 0x80, 0xfe, 0x7e, 0xe8, 0x7f, 0xbf, 0x7a, 0xec, 0x00, 0xff, 0xe0, 0xf5, - 0x23, 0x54, 0xc0, 0x68, 0x38, 0x7e, 0xe8, 0x7f, 0xbe, 0x7a, 0xec, 0x00, 0xff, 0xe0, 0x60, 0x2e, - 0x12, 0x0c, 0x37, 0xf5, 0x21, 0x7a, 0xa1, 0x20, 0x20, 0x09, 0x0c, 0x20, 0x0a, 0x12, 0x7e, 0xb0, - 0x0e, 0x7a, 0xb3, 0x92, 0x00, 0x80, 0x10, 0x7e, 0xb0, 0x02, 0x7a, 0xb3, 0x92, 0x00, 0x80, 0x07, - 0x7e, 0xb0, 0x0a, 0x7a, 0xb3, 0x92, 0x00, 0x7a, 0xb1, 0x0d, 0x02, 0x0c, 0xc4, 0x22, 0x7e, 0xb0, - 0x02, 0x7a, 0xb3, 0x90, 0x00, 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x03, 0x7a, 0xb3, 0x90, 0x00, 0x12, - 0x19, 0x0c, 0x80, 0xea, 0xc2, 0xaf, 0xc2, 0x11, 0xc2, 0x12, 0x75, 0xb0, 0xdf, 0x7e, 0x00, 0x01, - 0x7a, 0x03, 0x93, 0x00, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x90, 0x00, 0x6c, 0x00, 0x7e, 0x10, 0x03, - 0x12, 0x0c, 0xf5, 0x7e, 0x68, 0x2c, 0x66, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x0b, 0x00, - 0x80, 0x32, 0x02, 0x1a, 0x6e, 0x20, 0x11, 0x2b, 0x7e, 0xb0, 0x01, 0x7a, 0xb3, 0x90, 0x00, 0x12, - 0x19, 0x0c, 0x7e, 0xb0, 0x03, 0x7a, 0xb3, 0x90, 0x00, 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x02, 0x7a, - 0xb3, 0x90, 0x00, 0x12, 0x19, 0x0c, 0xa5, 0xd9, 0xdc, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x90, 0x00, - 0x12, 0x19, 0x0c, 0x22, 0x7e, 0x68, 0x2c, 0xf9, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, - 0xe4, 0x10, 0x00, 0x7e, 0x40, 0x55, 0x7a, 0xe9, 0x40, 0x0b, 0xe4, 0x7e, 0x50, 0xaa, 0x7a, 0xe9, - 0x50, 0x1b, 0xe4, 0xbe, 0xe9, 0x40, 0x68, 0x19, 0x7e, 0x68, 0x2c, 0xdf, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, 0x13, 0x7a, 0xe9, 0x40, 0x7e, 0xe9, 0x10, 0x80, - 0xf8, 0x7e, 0x68, 0x2c, 0xda, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x0b, 0x00, 0x7e, 0x68, - 0x2d, 0x3d, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x78, 0x00, 0x00, 0x7e, 0x70, 0x0e, - 0x7e, 0xa4, 0xff, 0xff, 0x7e, 0xb4, 0xbf, 0xff, 0x7d, 0xcb, 0x0e, 0xc4, 0x7d, 0xdc, 0x5d, 0xdb, - 0x6c, 0xbb, 0x7d, 0xfa, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x0b, 0xb0, 0x7d, 0xfb, 0x5e, - 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x0b, 0xb0, 0x7d, 0xfc, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, - 0xb0, 0x0b, 0xb0, 0x7d, 0xfd, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x6c, 0xbb, 0x7d, 0xfa, - 0x5e, 0xf4, 0x7f, 0xff, 0xbe, 0x7b, 0xb0, 0x78, 0x41, 0x0b, 0xb0, 0x7d, 0xfb, 0x5e, 0xf4, 0x7f, - 0xff, 0xbe, 0x7b, 0xb0, 0x78, 0x34, 0x0b, 0xb0, 0x7d, 0xfc, 0x5e, 0xf4, 0x7f, 0xff, 0xbe, 0x7b, - 0xb0, 0x78, 0x27, 0x0b, 0xb0, 0x7d, 0xfd, 0x5e, 0xf4, 0x7f, 0xff, 0xbe, 0x7b, 0xb0, 0x78, 0x1a, - 0x0b, 0xb0, 0xbe, 0xc4, 0xff, 0xfe, 0x78, 0x92, 0x0e, 0xb4, 0xa5, 0xdf, 0x8b, 0x7e, 0x68, 0x2c, - 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, 0x77, 0xca, 0x5b, 0xca, 0x6b, 0x7e, 0x68, - 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x68, 0x2d, 0x8f, 0x7a, 0x6c, 0x00, - 0xff, 0x12, 0x19, 0xc4, 0x0a, 0x47, 0x12, 0x19, 0xfa, 0x7e, 0x68, 0x2d, 0xde, 0x7a, 0x6c, 0x00, - 0xff, 0x12, 0x19, 0xc4, 0x6c, 0x77, 0xda, 0x6b, 0xca, 0x6b, 0x0b, 0x70, 0x0e, 0xc4, 0xbe, 0xc4, - 0xff, 0xff, 0x78, 0xf6, 0x1b, 0x70, 0x0a, 0x47, 0x12, 0x19, 0xfa, 0x12, 0x19, 0x19, 0x30, 0x11, - 0x30, 0xda, 0x6b, 0xda, 0x5b, 0x6c, 0xbb, 0x7e, 0x78, 0x00, 0x00, 0x7d, 0xfa, 0x5e, 0xf4, 0x7f, - 0xff, 0x7a, 0x7b, 0xb0, 0x7d, 0xfb, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x7d, 0xfc, 0x5e, - 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x7d, 0xfd, 0x5e, 0xf4, 0x7f, 0xff, 0x7a, 0x7b, 0xb0, 0x80, - 0xd4, 0x7e, 0x68, 0x2d, 0x1b, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x30, 0x1f, 0x0e, 0x7e, - 0x78, 0x04, 0x20, 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x44, 0x7b, 0xe0, 0x80, 0x0c, 0x7e, 0x78, 0x00, - 0x00, 0x7a, 0x7c, 0x00, 0x01, 0x7e, 0x44, 0x80, 0x00, 0x0b, 0x00, 0x7e, 0x40, 0x3a, 0x7c, 0x54, - 0x7f, 0x57, 0x7d, 0x84, 0x6c, 0x66, 0x7a, 0x5b, 0x50, 0x0b, 0x5c, 0x0b, 0x50, 0xa5, 0xde, 0x02, - 0x0b, 0x50, 0x1b, 0x84, 0x78, 0xf0, 0x7c, 0x54, 0x7f, 0x57, 0x7d, 0x84, 0x6c, 0x66, 0xbe, 0x5b, - 0x50, 0x78, 0x1a, 0x0b, 0x5c, 0x0b, 0x50, 0xa5, 0xde, 0x02, 0x0b, 0x50, 0x1b, 0x84, 0x78, 0xee, - 0x7e, 0x68, 0x2c, 0xda, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, 0x4b, 0x7f, 0x45, 0x7e, - 0x68, 0x2c, 0xdf, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x68, 0x2d, 0x5f, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7d, 0x4b, 0x12, 0x19, 0xfa, 0x7e, 0x68, 0x2d, 0x74, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x19, 0xc4, 0x6c, 0x88, 0x7c, 0x95, 0x12, 0x19, 0xfa, 0x7e, 0x68, 0x2d, 0x82, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x4b, 0x90, 0x12, 0x19, 0xfa, 0x12, 0x19, 0x19, - 0x30, 0x11, 0x05, 0x7e, 0x4b, 0x90, 0x80, 0xfb, 0x7e, 0x68, 0x2e, 0x28, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x19, 0xc4, 0x0b, 0x00, 0x7e, 0xb0, 0x80, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xa0, 0x55, 0x7a, - 0xa3, 0x91, 0x10, 0x7e, 0xb3, 0x91, 0x07, 0x7e, 0xb3, 0x91, 0x10, 0xbc, 0xab, 0x78, 0x20, 0x7e, - 0xa0, 0xaa, 0x7a, 0xa3, 0x91, 0x10, 0x7e, 0xb3, 0x91, 0x07, 0x7e, 0xb3, 0x91, 0x10, 0xbc, 0xab, - 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xda, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, 0x1b, 0x7e, - 0x68, 0x2c, 0xdf, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, 0x0a, - 0x7a, 0xa3, 0x91, 0x10, 0x7e, 0xb3, 0x91, 0x10, 0x80, 0xf6, 0x7e, 0x68, 0x2e, 0x4a, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x12, 0x31, 0x0b, 0x00, 0x7e, 0xe4, 0x10, 0x00, 0x7e, 0xa0, - 0xa5, 0xca, 0xa8, 0x7a, 0xe9, 0xa0, 0x7e, 0xb0, 0x30, 0x7a, 0xb3, 0x95, 0x00, 0x7e, 0xe9, 0xa0, - 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x95, 0x00, 0x12, 0x19, 0x0c, 0x0b, 0xe5, 0x7e, 0xb0, 0x20, 0x7a, - 0xb3, 0x95, 0x00, 0x7e, 0xe9, 0xb0, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x95, 0x00, 0x7e, 0xe9, 0xb0, - 0xda, 0xa8, 0xbc, 0xab, 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xda, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, - 0xc4, 0x80, 0x1d, 0x7e, 0x68, 0x2c, 0xdf, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, - 0x19, 0x30, 0x11, 0x0c, 0x7e, 0xb0, 0x38, 0x7a, 0xb3, 0x95, 0x00, 0x7e, 0xe9, 0xb0, 0x80, 0xfb, - 0x80, 0x00, 0x7e, 0x68, 0x2d, 0xe4, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x0b, 0x00, 0x75, - 0xb0, 0xdf, 0x7e, 0x24, 0x80, 0x00, 0x09, 0xb2, 0x00, 0x08, 0xbe, 0xb0, 0x01, 0x78, 0x0b, 0x09, - 0xb2, 0x00, 0x14, 0xbe, 0xb0, 0x60, 0x78, 0x02, 0x80, 0x17, 0x7e, 0x68, 0x2c, 0xdf, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, 0x11, 0x09, 0xb2, 0x00, 0x08, 0x80, - 0xfa, 0x7e, 0x68, 0x2c, 0xda, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x68, 0x2e, 0x06, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x0b, 0x00, 0x75, 0xb0, 0xef, 0x12, 0x18, 0xff, 0x7e, - 0x24, 0x80, 0x00, 0x7e, 0xa0, 0x55, 0x19, 0xa2, 0x00, 0x1c, 0x7e, 0xb0, 0x01, 0x19, 0xb2, 0x00, - 0x08, 0x09, 0xb2, 0x00, 0x1c, 0xbc, 0xab, 0x78, 0x37, 0x09, 0xb2, 0x00, 0x08, 0x5e, 0xb0, 0xc0, - 0xbe, 0xb0, 0xc0, 0x78, 0x2b, 0x7e, 0xa0, 0xaa, 0x19, 0xa2, 0x00, 0x1c, 0x6c, 0xbb, 0x19, 0xb2, - 0x00, 0x08, 0x09, 0xb2, 0x00, 0x1c, 0xbc, 0xab, 0x78, 0x16, 0x09, 0xb2, 0x00, 0x08, 0x5e, 0xb0, - 0xc0, 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xda, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, 0x1b, - 0x7e, 0x68, 0x2c, 0xdf, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, - 0x0a, 0x19, 0xa2, 0x00, 0x1c, 0x09, 0xb2, 0x00, 0x1c, 0x80, 0xf6, 0x7e, 0x68, 0x2e, 0x6c, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x68, 0x2e, 0xee, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, - 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x7e, 0xb0, 0x01, 0x19, 0xb2, 0x00, 0x1c, 0x2e, - 0x24, 0x01, 0x00, 0x0b, 0xb0, 0xa5, 0xd9, 0xf3, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x7e, - 0xb0, 0x01, 0x0b, 0x00, 0x09, 0xa2, 0x00, 0x1c, 0xbc, 0xab, 0x78, 0x16, 0x7e, 0x68, 0x2c, 0xe7, - 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x2e, 0x24, 0x01, 0x00, 0x0b, 0xb0, 0xa5, 0xd9, 0xe2, - 0x80, 0x25, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, - 0x30, 0x11, 0xe4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x09, 0xa2, 0x00, 0x1c, 0x2e, 0x24, - 0x01, 0x00, 0xa5, 0xd9, 0xf5, 0x80, 0xec, 0x7e, 0x68, 0x2f, 0x12, 0x7a, 0x6c, 0x00, 0xff, 0x12, - 0x19, 0xc4, 0x12, 0x12, 0x31, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x74, 0x10, - 0x19, 0xb2, 0x00, 0x10, 0x12, 0x11, 0xaa, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xee, 0x7e, 0x68, - 0x2f, 0x36, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, - 0x0b, 0x00, 0xe4, 0x19, 0xb2, 0x00, 0x10, 0x12, 0x11, 0xaa, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, - 0xef, 0x30, 0x00, 0x03, 0x02, 0x17, 0x3b, 0x02, 0x12, 0x6a, 0x74, 0x07, 0x19, 0xb2, 0x00, 0x08, - 0x12, 0x19, 0x0c, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, 0x14, 0x09, 0xb2, 0x00, 0x00, 0x09, - 0xb2, 0x00, 0x14, 0x09, 0xb2, 0x00, 0x00, 0x09, 0xb2, 0x00, 0x14, 0x09, 0xb2, 0x00, 0x00, 0x09, - 0xb2, 0x00, 0x14, 0xc2, 0x13, 0x7e, 0xb0, 0x55, 0x12, 0x12, 0x0b, 0x7e, 0xb0, 0xaa, 0x12, 0x12, - 0x0b, 0x7e, 0xb0, 0x00, 0x12, 0x12, 0x0b, 0x7e, 0xb0, 0xff, 0x12, 0x12, 0x0b, 0x30, 0x13, 0x0f, - 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x22, 0x7e, - 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x22, 0x19, 0xb2, 0x00, 0x00, 0x12, - 0x18, 0xff, 0x09, 0xa2, 0x00, 0x00, 0xbc, 0xab, 0x78, 0x01, 0x22, 0x20, 0x11, 0x03, 0xd2, 0x13, - 0x22, 0x12, 0x19, 0x19, 0x19, 0xb2, 0x00, 0x00, 0x12, 0x18, 0xff, 0x09, 0xa2, 0x00, 0x00, 0x80, - 0xf3, 0x75, 0xb0, 0xdf, 0x12, 0x18, 0xff, 0x75, 0xb0, 0xef, 0x12, 0x18, 0xff, 0x7e, 0x24, 0x80, - 0x00, 0x7e, 0x11, 0x21, 0x74, 0x80, 0x19, 0xb2, 0x00, 0x0c, 0x7e, 0x54, 0x00, 0x02, 0x19, 0xa2, - 0x00, 0x04, 0x19, 0xb2, 0x00, 0x00, 0x74, 0x03, 0x19, 0xb2, 0x00, 0x0c, 0x74, 0x06, 0x19, 0xb2, - 0x00, 0x08, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xdb, 0x22, 0x7e, 0x68, 0x2f, 0x5a, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x12, 0x18, - 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x55, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x18, 0xff, 0x09, - 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x05, 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x19, 0xc4, 0x80, 0x1a, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, - 0x12, 0x19, 0x19, 0x30, 0x11, 0x09, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x18, 0xff, 0x80, 0xf7, 0x2e, - 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xb6, 0x7e, 0x68, 0x2f, 0x7e, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, - 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, - 0x18, 0x7e, 0xa0, 0x55, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, - 0xb0, 0x0a, 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, - 0x1a, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, - 0x11, 0x09, 0x19, 0xa2, 0x00, 0x00, 0x12, 0x18, 0xff, 0x80, 0xf7, 0x2e, 0x24, 0x01, 0x00, 0xa5, - 0xd9, 0xb6, 0x30, 0x04, 0x03, 0x02, 0x15, 0x9f, 0x7e, 0x68, 0x2f, 0xa2, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x6c, 0xaa, 0x19, 0xa2, - 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, - 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x0a, - 0x78, 0x3c, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, - 0x7e, 0xa0, 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, - 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x0a, 0x78, 0x14, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, - 0x00, 0xff, 0x12, 0x19, 0xc4, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, 0x80, 0x20, 0x7e, 0x68, - 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, 0xe6, 0x7e, - 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x7e, 0x68, - 0x2f, 0xea, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, - 0x0b, 0x00, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, - 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, - 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x05, 0x78, 0x3c, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, - 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, 0x02, - 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x05, 0x78, 0x14, - 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x2e, 0x24, 0x01, 0x00, 0xa5, - 0xd9, 0x9e, 0x80, 0x20, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, - 0x19, 0x19, 0x30, 0x11, 0xe6, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, - 0x00, 0x10, 0x80, 0xf1, 0x7e, 0x68, 0x30, 0x32, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, - 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, - 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x50, 0xbe, 0xb0, 0x50, 0x78, 0x1f, 0x6c, 0xaa, - 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x50, 0x78, 0x0d, - 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, 0x20, 0x7e, 0x68, 0x2c, - 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, 0x0f, 0x7e, 0xa0, - 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x2e, 0x24, 0x01, - 0x00, 0xa5, 0xd9, 0xa2, 0x7e, 0x68, 0x30, 0x7a, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, - 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x01, 0x19, - 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0xa0, 0xbe, 0xb0, 0xa0, - 0x78, 0x1f, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, - 0xb0, 0xa0, 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x80, - 0x20, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, - 0x11, 0x0f, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, - 0xf1, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, 0x7e, 0x68, 0x30, 0x9e, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x20, 0xb1, 0x26, 0x7e, - 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x30, 0xb1, 0x19, 0x6c, 0xaa, 0x19, 0xa2, - 0x00, 0x10, 0x12, 0x18, 0xff, 0x20, 0xb1, 0x0d, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, - 0x12, 0x19, 0xc4, 0x80, 0x20, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, - 0x12, 0x19, 0x19, 0x30, 0x11, 0x0f, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, - 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xae, 0x02, 0x17, 0x3b, 0x7e, - 0x68, 0x2f, 0xc6, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, - 0x21, 0x0b, 0x00, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, - 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, - 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x06, 0x78, 0x3c, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, - 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x03, 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, - 0x01, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x06, 0x78, - 0x14, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x2e, 0x24, 0x01, 0x00, - 0xa5, 0xd9, 0x9e, 0x80, 0x20, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, - 0x12, 0x19, 0x19, 0x30, 0x11, 0xe6, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, - 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x7e, 0x68, 0x30, 0x0e, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, - 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, - 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x01, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, - 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x09, 0x78, 0x3c, 0x7e, - 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x7e, 0xa0, 0x03, - 0x19, 0xa2, 0x00, 0x10, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, - 0x00, 0x18, 0x5e, 0xb0, 0x09, 0x78, 0x14, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, - 0x19, 0xc4, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0x9e, 0x80, 0x20, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, 0x19, 0x19, 0x30, 0x11, 0xe6, 0x7e, 0xa0, 0x01, 0x19, - 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x80, 0xf1, 0x7e, 0x68, 0x30, 0x56, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x7e, - 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, 0x00, 0x18, 0x5e, 0xb0, 0x90, - 0xbe, 0xb0, 0x90, 0x78, 0x1f, 0x6c, 0xaa, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x09, 0xb2, - 0x00, 0x18, 0x5e, 0xb0, 0x90, 0x78, 0x0d, 0x7e, 0x68, 0x2c, 0xe7, 0x7a, 0x6c, 0x00, 0xff, 0x12, - 0x19, 0xc4, 0x80, 0x20, 0x7e, 0x68, 0x2c, 0xf0, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x12, - 0x19, 0x19, 0x30, 0x11, 0x0f, 0x7e, 0xa0, 0x02, 0x19, 0xa2, 0x00, 0x10, 0x6c, 0xaa, 0x19, 0xa2, - 0x00, 0x10, 0x80, 0xf1, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xa2, 0x20, 0x1f, 0x68, 0x12, 0x12, - 0x31, 0x12, 0x17, 0xa9, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, 0x0b, 0x00, 0x20, 0x89, 0x26, - 0x7e, 0xa0, 0xff, 0x19, 0xa2, 0x00, 0x04, 0x12, 0x18, 0xff, 0x7e, 0xb0, 0x55, 0x19, 0xb2, 0x00, - 0x00, 0x12, 0x18, 0xff, 0x30, 0x89, 0x0f, 0x7e, 0xa0, 0x00, 0x19, 0xa2, 0x00, 0x04, 0x12, 0x18, - 0xff, 0x20, 0x89, 0x02, 0x80, 0x26, 0x12, 0x19, 0x19, 0x30, 0x11, 0x20, 0x7e, 0xa0, 0xff, 0x19, - 0xa2, 0x00, 0x04, 0x12, 0x18, 0xff, 0x7e, 0xb0, 0x55, 0x19, 0xb2, 0x00, 0x00, 0x12, 0x18, 0xff, - 0x7e, 0xa0, 0x00, 0x19, 0xa2, 0x00, 0x04, 0x12, 0x18, 0xff, 0x80, 0xe0, 0x2e, 0x24, 0x01, 0x00, - 0xa5, 0xd9, 0xa8, 0x02, 0x17, 0xc2, 0x02, 0x18, 0x4c, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x21, - 0x7e, 0xa0, 0x08, 0x19, 0xa2, 0x00, 0x10, 0x12, 0x18, 0xff, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, - 0xef, 0x22, 0x30, 0x1f, 0x03, 0x02, 0x18, 0x4c, 0xc2, 0x8a, 0x12, 0x17, 0xa9, 0x0b, 0x00, 0x12, - 0x18, 0x16, 0x20, 0x8b, 0x24, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x02, 0x7a, 0xb3, 0x91, - 0x07, 0x74, 0x0c, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x07, 0x12, 0x19, 0x0c, - 0x30, 0x8b, 0x06, 0x12, 0x18, 0x16, 0x30, 0x8b, 0xad, 0x12, 0x19, 0x19, 0x30, 0x11, 0xa7, 0x12, - 0x18, 0x16, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x07, 0x12, 0x19, - 0x0c, 0x12, 0x18, 0x16, 0x80, 0xe9, 0x7e, 0xa0, 0x00, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x06, 0x7a, - 0xa3, 0x91, 0x07, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x7a, 0xa3, 0x91, 0x07, 0x12, 0x18, 0xff, - 0x74, 0xef, 0x7a, 0xb3, 0x91, 0x04, 0x74, 0x80, 0x7a, 0xb3, 0x91, 0x03, 0x74, 0x0c, 0x7a, 0xb3, - 0x91, 0x06, 0x74, 0x08, 0x7a, 0xb3, 0x91, 0x07, 0x12, 0x19, 0x0c, 0x22, 0x30, 0x12, 0x19, 0x7e, - 0x68, 0x30, 0xc2, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0xd2, 0x11, 0x12, 0x18, 0xff, 0x12, - 0x18, 0xff, 0x12, 0x18, 0xff, 0x02, 0x0c, 0xca, 0x30, 0x1f, 0x1c, 0x7e, 0x68, 0x31, 0x3c, 0x7a, - 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x7e, 0x68, 0x31, 0x5e, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, - 0xc4, 0x12, 0x1a, 0x6e, 0x02, 0x18, 0xf7, 0x0b, 0x00, 0x7e, 0x78, 0x18, 0xb1, 0x7a, 0x7c, 0x00, - 0xff, 0x7f, 0x67, 0x7a, 0x6c, 0x00, 0x00, 0x7e, 0x70, 0x3e, 0x7e, 0x7b, 0xb0, 0x7a, 0x6b, 0xb0, - 0x0b, 0x7c, 0x0b, 0x6c, 0xa5, 0xdf, 0xf3, 0x7e, 0x78, 0x18, 0xb1, 0x7a, 0x7c, 0x00, 0x00, 0x89, - 0x78, 0x7e, 0x78, 0x00, 0x00, 0x7a, 0x7c, 0x00, 0xfe, 0x7e, 0x68, 0x7f, 0xbf, 0x7a, 0x6c, 0x00, - 0xfe, 0x74, 0xaa, 0x39, 0xb7, 0x55, 0x55, 0x74, 0x55, 0x39, 0xb7, 0x2a, 0xaa, 0x74, 0xa0, 0x39, - 0xb7, 0x55, 0x55, 0x6c, 0x99, 0x7a, 0x6b, 0x90, 0x7e, 0x54, 0x27, 0x10, 0x7e, 0x6b, 0x80, 0xbc, - 0x89, 0x68, 0x08, 0x1b, 0x54, 0x78, 0xf5, 0x8a, 0xff, 0x18, 0xef, 0x8a, 0xff, 0x18, 0xf7, 0x12, - 0x19, 0x19, 0x7e, 0x6b, 0x80, 0x80, 0xfb, 0x7e, 0x10, 0xff, 0x12, 0x19, 0xac, 0x80, 0xf8, 0xca, - 0xf9, 0x7e, 0xf4, 0x00, 0xff, 0x1b, 0xf4, 0x78, 0xfc, 0xda, 0xf9, 0x22, 0xca, 0xf9, 0x7e, 0xf4, - 0x00, 0x00, 0x1b, 0xf4, 0x78, 0xfc, 0xda, 0xf9, 0x22, 0x20, 0x11, 0x20, 0xd2, 0x12, 0x12, 0x19, - 0x0c, 0x7e, 0xb0, 0x02, 0x7a, 0xb3, 0x90, 0x00, 0x12, 0x19, 0x0c, 0x12, 0x19, 0x0c, 0x12, 0x19, - 0x0c, 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x90, 0x00, 0x22, 0xca, 0x0b, 0x7e, 0x10, - 0x03, 0x7c, 0x30, 0x6c, 0x22, 0x0b, 0x20, 0x9e, 0x30, 0x0a, 0x50, 0xf9, 0x2e, 0x30, 0x0b, 0x1b, - 0x20, 0x68, 0x20, 0x12, 0x19, 0x0c, 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x03, 0x7a, 0xb3, 0x90, 0x00, - 0x12, 0x19, 0x0c, 0x12, 0x19, 0x0c, 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x90, 0x00, - 0xa5, 0xda, 0xe0, 0x12, 0x19, 0x0c, 0x12, 0x19, 0x0c, 0x1b, 0x30, 0x68, 0x20, 0x12, 0x19, 0x0c, - 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x02, 0x7a, 0xb3, 0x90, 0x00, 0x12, 0x19, 0x0c, 0x12, 0x19, 0x0c, - 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x90, 0x00, 0xa5, 0xdb, 0xe0, 0x7e, 0x20, 0x0a, - 0x12, 0x19, 0x0c, 0xa5, 0xda, 0xfa, 0xa5, 0xd9, 0x98, 0xda, 0x0b, 0x22, 0x20, 0x11, 0x14, 0x12, - 0x19, 0x0c, 0x7e, 0xb0, 0x01, 0x7a, 0xb3, 0x90, 0x00, 0x12, 0x19, 0x0c, 0x7e, 0xb0, 0x00, 0x7a, - 0xb3, 0x90, 0x00, 0x22, 0x30, 0x1f, 0x32, 0x20, 0x11, 0x2f, 0xca, 0x2b, 0xca, 0x7b, 0x7e, 0x78, - 0x80, 0x00, 0x7a, 0x7c, 0x00, 0xfe, 0x12, 0x1a, 0x4d, 0x7e, 0x6b, 0xa0, 0x5c, 0xaa, 0x68, 0x10, - 0x29, 0xb7, 0x00, 0x14, 0x54, 0x60, 0x68, 0xf8, 0x39, 0xa7, 0x00, 0x00, 0x0b, 0x6c, 0x80, 0xe9, - 0x12, 0x18, 0xff, 0xd2, 0xb5, 0xda, 0x7b, 0xda, 0x2b, 0x22, 0x12, 0x1a, 0x05, 0x7e, 0x68, 0x00, - 0x0c, 0x12, 0x19, 0xc4, 0x22, 0xca, 0x59, 0xca, 0x5b, 0x7e, 0xb4, 0x00, 0x0c, 0x7c, 0xb8, 0xc4, - 0x12, 0x1a, 0x35, 0x7c, 0xb8, 0x12, 0x1a, 0x35, 0x7c, 0xb9, 0xc4, 0x12, 0x1a, 0x35, 0x7c, 0xb9, - 0x12, 0x1a, 0x35, 0x7e, 0xb0, 0x68, 0x7a, 0xb9, 0xb0, 0x0b, 0xb4, 0x6c, 0xbb, 0x7a, 0xb9, 0xb0, - 0xda, 0x59, 0xda, 0x5b, 0x22, 0x5e, 0xb0, 0x0f, 0x7c, 0xab, 0x9e, 0xa0, 0x0a, 0x40, 0x05, 0x2e, - 0xb0, 0x37, 0x80, 0x03, 0x2e, 0xb0, 0x30, 0x7a, 0xb9, 0xb0, 0x0b, 0xb4, 0x22, 0xc2, 0xb5, 0x75, - 0xb0, 0xef, 0x12, 0x18, 0xff, 0x74, 0x80, 0x39, 0xb7, 0x00, 0x0c, 0x7e, 0x54, 0x00, 0x06, 0x39, - 0xa7, 0x00, 0x04, 0x39, 0xb7, 0x00, 0x00, 0x74, 0x03, 0x39, 0xb7, 0x00, 0x0c, 0x22, 0x7e, 0x78, - 0x00, 0x00, 0x7a, 0x7c, 0x00, 0xff, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0x01, 0x7f, 0x65, - 0x7e, 0x74, 0x20, 0x00, 0x12, 0x0b, 0x63, 0x40, 0x58, 0x7e, 0x78, 0x7c, 0x00, 0x7a, 0x7c, 0x00, - 0xff, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0x01, 0x7e, 0x68, 0x7c, 0x00, 0x7a, 0x6c, 0x00, - 0x01, 0x7e, 0x74, 0x04, 0x00, 0x12, 0x0b, 0x63, 0x40, 0x37, 0x74, 0x80, 0x12, 0x1a, 0xea, 0x40, - 0x30, 0x7e, 0x00, 0x03, 0x7a, 0x03, 0x90, 0x00, 0xd2, 0x10, 0x7e, 0x04, 0x00, 0x08, 0x7e, 0x14, - 0x00, 0x00, 0x84, 0xa5, 0xdb, 0xfc, 0xa5, 0xda, 0xf9, 0xa5, 0xd9, 0xf6, 0x74, 0x40, 0x12, 0x1a, - 0xea, 0x40, 0x0e, 0x7e, 0x68, 0x31, 0x8d, 0x7a, 0x6c, 0x00, 0xff, 0x12, 0x19, 0xc4, 0x02, 0x18, - 0xf7, 0x7e, 0xb0, 0x02, 0x7a, 0xb3, 0x90, 0x00, 0x80, 0xfe, 0xf5, 0x0b, 0x7e, 0x78, 0x00, 0x0b, - 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x68, 0x7f, 0xbf, 0x7a, 0x6c, 0x00, 0x01, 0x7e, 0x74, 0x00, 0x01, - 0x02, 0x0b, 0x63, - -// Segment #19, EXCLUDED Start Address 00ff2c66, Length 1393 - -}; - -static const struct edge_firmware_version_info IMAGE_VERSION_NAME = { - 2, 0, 3 }; // Major, Minor, Build - -#undef IMAGE_VERSION_NAME - -#undef IMAGE_ARRAY_NAME - diff --git a/drivers/usb/serial/io_fw_down.h b/drivers/usb/serial/io_fw_down.h deleted file mode 100644 index 5a61d80..0000000 --- a/drivers/usb/serial/io_fw_down.h +++ /dev/null @@ -1,1229 +0,0 @@ -//************************************************************** -//* Edgeport/4 Binary Image -//* Generated by HEX2C v1.06 -//* Copyright (C) 1998 Inside Out Networks, 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. -//************************************************************** - - -//Image structure definition -#if !defined(DEFINED_EDGE_FIRMWARE_IMAGE_RECORD) - #define DEFINED_EDGE_FIRMWARE_IMAGE_RECORD - struct edge_firmware_image_record { - __le16 ExtAddr; - __le16 Addr; - __le16 Len; - unsigned char Data[0]; - } __attribute__ ((packed)); - - struct edge_firmware_version_info { - unsigned char MajorVersion; - unsigned char MinorVersion; - unsigned short BuildNumber; - }; - -#endif - -#if !defined(IMAGE_ARRAY_NAME) - #define IMAGE_ARRAY_NAME FirmwareImage - #define IMAGE_VERSION_NAME FirmwareImageVersion -#endif - -static unsigned char IMAGE_ARRAY_NAME[] = { - -// Segment #1, Start Address 00ff0000, Length 6 -0xff,0x00,0x00,0x00,0x06,0x00, - 0x02, 0x00, 0x80, 0x02, 0x44, 0xb0, - -// Segment #2, Start Address 00ff000b, Length 3 -0xff,0x00,0x0b,0x00,0x03,0x00, - 0x02, 0x44, 0x72, - -// Segment #3, Start Address 00ff0013, Length 3 -0xff,0x00,0x13,0x00,0x03,0x00, - 0x02, 0x00, 0x13, - -// Segment #4, Start Address 00ff001b, Length 3 -0xff,0x00,0x1b,0x00,0x03,0x00, - 0x02, 0x00, 0x1b, - -// Segment #5, Start Address 00ff0023, Length 3 -0xff,0x00,0x23,0x00,0x03,0x00, - 0x02, 0x00, 0x23, - -// Segment #6, Start Address 00ff002b, Length 3 -0xff,0x00,0x2b,0x00,0x03,0x00, - 0x02, 0x00, 0x2b, - -// Segment #7, Start Address 00ff0033, Length 3 -0xff,0x00,0x33,0x00,0x03,0x00, - 0x02, 0x00, 0x33, - -// Segment #8, Start Address 00ff003b, Length 3 -0xff,0x00,0x3b,0x00,0x03,0x00, - 0x02, 0x00, 0x3b, - -// Segment #9, Start Address 00ff0043, Length 3 -0xff,0x00,0x43,0x00,0x03,0x00, - 0x02, 0x00, 0x43, - -// Segment #10, Start Address 00ff004b, Length 3 -0xff,0x00,0x4b,0x00,0x03,0x00, - 0x02, 0x6e, 0xc4, - -// Segment #11, Start Address 00ff0053, Length 3 -0xff,0x00,0x53,0x00,0x03,0x00, - 0x02, 0x75, 0x8d, - -// Segment #12, Start Address 00ff007b, Length 3 -0xff,0x00,0x7b,0x00,0x03,0x00, - 0x02, 0x00, 0x7b, - -// Segment #13, Start Address 00ff0080, Length 7 -0xff,0x00,0x80,0x00,0x07,0x00, - 0x7e, 0x14, 0x00, 0x00, 0x02, 0x40, 0x51, - -// Segment #14, Start Address 00ff3000, Length 2178 -0xff,0x00,0x00,0x30,0x82,0x08, - 0x12, 0x37, 0x28, 0x12, 0x30, 0x3e, 0x12, 0x30, 0x54, 0x12, 0x30, 0xe5, 0x12, 0x31, 0x68, 0x12, - 0x35, 0x20, 0x12, 0x38, 0x58, 0x12, 0x31, 0x15, 0x12, 0x31, 0x40, 0x12, 0x30, 0xa0, 0x80, 0xe0, - 0xe5, 0x23, 0x60, 0x19, 0x7e, 0x14, 0x00, 0x00, 0x09, 0xb1, 0x01, 0xcf, 0xb4, 0x00, 0x02, 0x80, - 0x05, 0x14, 0x19, 0xb1, 0x01, 0xcf, 0xa5, 0x0b, 0xbe, 0x31, 0x2f, 0x78, 0xeb, 0x22, 0xc2, 0xaf, - 0x7e, 0xb3, 0x3f, 0xf1, 0xb4, 0x01, 0x0a, 0xc0, 0xf1, 0x75, 0xf1, 0x02, 0x12, 0x70, 0xef, 0xd0, - 0xf1, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0xe5, 0x22, 0x60, 0x43, 0x7e, 0x07, 0x01, 0xe1, 0xbe, 0x04, - 0x03, 0x80, 0x38, 0x39, 0x7e, 0x04, 0x80, 0x00, 0x7e, 0x20, 0x00, 0x13, 0x50, 0x21, 0x09, 0xa0, - 0x00, 0x04, 0x4e, 0xa0, 0x05, 0x19, 0xa0, 0x00, 0x04, 0x0a, 0x32, 0x09, 0x53, 0x67, 0x8e, 0x5e, - 0x51, 0x27, 0x68, 0x0b, 0x09, 0xa0, 0x00, 0x10, 0x4e, 0xa0, 0x01, 0x19, 0xa0, 0x00, 0x10, 0x2e, - 0x04, 0x01, 0x00, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, 0x78, 0xd1, 0x75, 0x22, 0x00, 0xd2, 0xaf, 0x22, - 0xc2, 0xaf, 0x7e, 0x20, 0x00, 0x7e, 0x30, 0x01, 0x7c, 0xb2, 0x23, 0x0a, 0x2b, 0x49, 0x32, 0x01, - 0x8f, 0xbe, 0x34, 0x00, 0x00, 0x68, 0x12, 0x7e, 0xb1, 0x21, 0xa5, 0x4b, 0x7a, 0xb1, 0x21, 0xca, - 0x19, 0x49, 0x22, 0x30, 0xd5, 0x99, 0x24, 0xda, 0x19, 0x3e, 0x30, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, - 0x78, 0xd6, 0xd2, 0xaf, 0x22, 0x46, 0x0f, 0x49, 0x67, 0x4c, 0xbf, 0x50, 0x17, 0x53, 0x6f, 0x56, - 0xc7, 0x5a, 0x1f, 0x5d, 0x77, 0xc2, 0xaf, 0xe5, 0x32, 0x60, 0x14, 0x7e, 0x20, 0x00, 0x13, 0x50, - 0x07, 0xca, 0xb8, 0x12, 0x31, 0x02, 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, 0x78, 0xef, 0xd2, - 0xaf, 0x22, 0xca, 0x28, 0x12, 0x67, 0xab, 0xda, 0x28, 0x40, 0x09, 0x0a, 0x22, 0x09, 0xb2, 0x67, - 0x8e, 0xf4, 0x52, 0x32, 0x22, 0xc2, 0xaf, 0xe5, 0x34, 0x60, 0x14, 0x7e, 0x20, 0x00, 0x13, 0x50, - 0x07, 0xca, 0xb8, 0x12, 0x31, 0x32, 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, 0x78, 0xef, 0xd2, - 0xaf, 0x22, 0xca, 0x28, 0x0a, 0x22, 0x09, 0x42, 0x00, 0x3e, 0x12, 0x69, 0xc2, 0xda, 0x28, 0x22, - 0xc2, 0xaf, 0xe5, 0x35, 0x60, 0x14, 0x7e, 0x20, 0x00, 0x13, 0x50, 0x07, 0xca, 0xb8, 0x12, 0x31, - 0x5d, 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, 0x78, 0xef, 0xd2, 0xaf, 0x22, 0xca, 0x28, 0x7e, - 0x40, 0x00, 0x12, 0x6c, 0x5b, 0xda, 0x28, 0x22, 0xc2, 0xaf, 0xe5, 0x23, 0x60, 0x14, 0x7e, 0x20, - 0x00, 0x13, 0x50, 0x07, 0xca, 0xb8, 0x12, 0x31, 0x85, 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, - 0x78, 0xef, 0xd2, 0xaf, 0x22, 0x7c, 0xb2, 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x31, 0x90, 0x89, 0x24, - 0x31, 0xa0, 0x32, 0x10, 0x32, 0x80, 0x32, 0xf0, 0x33, 0x60, 0x33, 0xd0, 0x34, 0x40, 0x34, 0xb0, - 0x7e, 0x27, 0x01, 0x8f, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x80, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x49, 0x30, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0x9f, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0x9f, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xcf, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xcf, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x18, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xcf, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x91, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x81, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x4c, 0x88, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xa1, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xa1, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd0, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd0, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x19, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd0, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x93, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x82, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x4f, 0xe0, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xa3, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xa3, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd1, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd1, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x1a, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd1, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x95, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x83, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x53, 0x38, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xa5, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xa5, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd2, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd2, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x1b, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd2, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x97, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x84, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x56, 0x90, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xa7, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xa7, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd3, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd3, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x1c, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd3, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x99, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x85, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x59, 0xe8, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xa9, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xa9, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd4, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd4, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x1d, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd4, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x9b, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x86, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x5d, 0x40, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xab, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xab, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd5, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd5, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x1e, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd5, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x27, 0x01, 0x9d, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x87, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x60, 0x98, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0xad, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0xad, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xd6, 0x80, - 0x2e, 0x7e, 0x63, 0x01, 0xd6, 0xa5, 0xbe, 0x00, 0x26, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x62, 0xb6, 0x40, 0x18, 0x75, 0x31, 0xb3, 0x12, 0x7c, 0x15, 0xc2, 0x1f, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xd6, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0xc2, 0xaf, 0xe5, 0x24, 0x60, 0x14, 0x7e, 0x20, 0x00, 0x13, 0x50, 0x07, 0xca, 0xb8, 0x12, 0x35, - 0x3d, 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, 0x78, 0xef, 0xd2, 0xaf, 0x22, 0x7c, 0xb2, 0x23, - 0x0a, 0x2b, 0x49, 0x22, 0x35, 0x48, 0x89, 0x24, 0x35, 0x58, 0x35, 0x92, 0x35, 0xcc, 0x36, 0x06, - 0x36, 0x40, 0x36, 0x7a, 0x36, 0xb4, 0x36, 0xee, 0x7e, 0x24, 0x80, 0x00, 0x09, 0xb2, 0x00, 0x14, - 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x49, 0x30, - 0x7d, 0x21, 0xda, 0x19, 0x5e, 0xb0, 0x01, 0x7e, 0xa0, 0x90, 0x12, 0x62, 0x93, 0x40, 0x12, 0x75, - 0x31, 0xb8, 0x12, 0x7c, 0x15, 0xc2, 0x20, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, - 0xf1, 0x22, 0x7e, 0x24, 0x81, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, - 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x4c, 0x88, 0x7d, 0x21, 0xda, 0x19, 0x5e, 0xb0, - 0x01, 0x7e, 0xa0, 0x90, 0x12, 0x62, 0x93, 0x40, 0x12, 0x75, 0x31, 0xb8, 0x12, 0x7c, 0x15, 0xc2, - 0x21, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x82, 0x00, - 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, - 0x12, 0x12, 0x4f, 0xe0, 0x7d, 0x21, 0xda, 0x19, 0x5e, 0xb0, 0x01, 0x7e, 0xa0, 0x90, 0x12, 0x62, - 0x93, 0x40, 0x12, 0x75, 0x31, 0xb8, 0x12, 0x7c, 0x15, 0xc2, 0x22, 0xc0, 0xf1, 0x75, 0xf1, 0x01, - 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x83, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, - 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x53, 0x38, 0x7d, 0x21, - 0xda, 0x19, 0x5e, 0xb0, 0x01, 0x7e, 0xa0, 0x90, 0x12, 0x62, 0x93, 0x40, 0x12, 0x75, 0x31, 0xb8, - 0x12, 0x7c, 0x15, 0xc2, 0x23, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, - 0x7e, 0x24, 0x84, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, - 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x56, 0x90, 0x7d, 0x21, 0xda, 0x19, 0x5e, 0xb0, 0x01, 0x7e, - 0xa0, 0x90, 0x12, 0x62, 0x93, 0x40, 0x12, 0x75, 0x31, 0xb8, 0x12, 0x7c, 0x15, 0xc2, 0x24, 0xc0, - 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x85, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x59, 0xe8, 0x7d, 0x21, 0xda, 0x19, 0x5e, 0xb0, 0x01, 0x7e, 0xa0, 0x90, 0x12, 0x62, 0x93, 0x40, - 0x12, 0x75, 0x31, 0xb8, 0x12, 0x7c, 0x15, 0xc2, 0x25, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, - 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x86, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, - 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x5d, 0x40, 0x7d, 0x21, 0xda, 0x19, - 0x5e, 0xb0, 0x01, 0x7e, 0xa0, 0x90, 0x12, 0x62, 0x93, 0x40, 0x12, 0x75, 0x31, 0xb8, 0x12, 0x7c, - 0x15, 0xc2, 0x26, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, - 0x87, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, - 0x19, 0x7d, 0x12, 0x12, 0x60, 0x98, 0x7d, 0x21, 0xda, 0x19, 0x5e, 0xb0, 0x01, 0x7e, 0xa0, 0x90, - 0x12, 0x62, 0x93, 0x40, 0x12, 0x75, 0x31, 0xb8, 0x12, 0x7c, 0x15, 0xc2, 0x27, 0xc0, 0xf1, 0x75, - 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0xc2, 0xaf, 0xe5, 0x33, 0x60, 0x14, 0x7e, 0x20, - 0x00, 0x13, 0x50, 0x07, 0xca, 0xb8, 0x12, 0x37, 0x45, 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2f, - 0x78, 0xef, 0xd2, 0xaf, 0x22, 0x7c, 0xb2, 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x37, 0x50, 0x89, 0x24, - 0x37, 0x60, 0x37, 0x7f, 0x37, 0x9e, 0x37, 0xbd, 0x37, 0xdc, 0x37, 0xfb, 0x38, 0x1a, 0x38, 0x39, - 0x7e, 0x24, 0x80, 0x00, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x48, 0x1b, 0xda, 0x19, 0x10, 0x04, 0x02, - 0x80, 0x0c, 0xd2, 0x01, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, - 0x24, 0x81, 0x00, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x4b, 0x73, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, - 0x0c, 0xd2, 0x01, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, - 0x82, 0x00, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x4e, 0xcb, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, 0x0c, - 0xd2, 0x01, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x83, - 0x00, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x52, 0x23, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, 0x0c, 0xd2, - 0x01, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x84, 0x00, - 0xca, 0x19, 0x7d, 0x12, 0x12, 0x55, 0x7b, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, 0x0c, 0xd2, 0x01, - 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x85, 0x00, 0xca, - 0x19, 0x7d, 0x12, 0x12, 0x58, 0xd3, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, 0x0c, 0xd2, 0x01, 0xc0, - 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x86, 0x00, 0xca, 0x19, - 0x7d, 0x12, 0x12, 0x5c, 0x2b, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, 0x0c, 0xd2, 0x01, 0xc0, 0xf1, - 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x7e, 0x24, 0x87, 0x00, 0xca, 0x19, 0x7d, - 0x12, 0x12, 0x5f, 0x83, 0xda, 0x19, 0x10, 0x04, 0x02, 0x80, 0x0c, 0xd2, 0x01, 0xc0, 0xf1, 0x75, - 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0xc2, 0xaf, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0xa9, - 0x32, 0xf2, 0x1a, 0x7e, 0x07, 0x01, 0xe1, 0xbe, 0x04, 0x00, 0x00, 0x78, 0x10, 0xe5, 0xf5, 0x33, - 0x82, 0xe7, 0x40, 0x09, 0x85, 0x31, 0x31, 0x12, 0x7c, 0x15, 0x75, 0xf6, 0x00, 0xd0, 0xf1, 0xd2, - 0xaf, 0x22, - -// Segment #15, Start Address 00ff4000, Length 15381 -0xff,0x00,0x00,0x40,0x15,0x3c, - 0x7e, 0x04, 0x00, 0x01, 0x7e, 0x14, 0x7f, 0xf8, 0x7e, 0x24, 0x00, 0xfe, 0x7d, 0x31, 0x0b, 0x1a, - 0x50, 0x1b, 0x0a, 0x50, 0x7e, 0x14, 0x40, 0x1b, 0x02, 0x40, 0x6a, 0x7e, 0xf8, 0x00, 0x6f, 0xd2, - 0x04, 0xc2, 0x94, 0xd2, 0x95, 0x7e, 0xf4, 0x40, 0x2c, 0x02, 0x40, 0x7c, 0x12, 0x7d, 0x30, 0xf5, - 0x2f, 0x7a, 0xa1, 0x30, 0x7a, 0x11, 0x6e, 0x12, 0x75, 0xca, 0x12, 0x40, 0xdc, 0x7e, 0xb3, 0x3f, - 0xf1, 0x60, 0x03, 0x12, 0x43, 0xd4, 0x75, 0xf1, 0x00, 0x12, 0x76, 0x6f, 0xd2, 0xaf, 0x02, 0x30, - 0x00, 0x7e, 0x04, 0x00, 0xff, 0x7e, 0x18, 0x40, 0x5f, 0x7a, 0x1c, 0x00, 0x01, 0x89, 0x18, 0xa9, - 0x25, 0x87, 0x03, 0xa9, 0xd5, 0x87, 0xd2, 0x93, 0x89, 0x08, 0x7e, 0x04, 0x00, 0xff, 0x7e, 0x18, - 0x40, 0x78, 0x7a, 0x1c, 0x00, 0x01, 0x89, 0x18, 0xc2, 0x93, 0x89, 0x08, 0x7e, 0x08, 0x00, 0x20, - 0x7e, 0x44, 0x04, 0x00, 0x7e, 0x40, 0x00, 0x7e, 0xe4, 0x40, 0x8e, 0x02, 0x7c, 0x30, 0x7e, 0x08, - 0x01, 0x6f, 0x7e, 0x44, 0x28, 0x7c, 0x7e, 0x40, 0x00, 0x7e, 0xe4, 0x40, 0xa0, 0x02, 0x7c, 0x30, - 0x7e, 0x08, 0x00, 0x6f, 0x7e, 0x44, 0x01, 0x00, 0x7e, 0x40, 0x53, 0x7e, 0xe4, 0x40, 0xb2, 0x02, - 0x7c, 0x30, 0x75, 0x6d, 0x20, 0x75, 0x6c, 0x30, 0x7e, 0x04, 0x00, 0x08, 0x75, 0x6a, 0x58, 0x75, - 0x6b, 0x08, 0x75, 0x67, 0x08, 0x75, 0x69, 0x01, 0x75, 0x89, 0x01, 0x75, 0x8a, 0x01, 0x75, 0x8c, - 0x00, 0xd2, 0x8c, 0x7e, 0x04, 0x00, 0x02, 0x7a, 0x05, 0x58, 0x89, 0xf4, 0x75, 0xb7, 0x7f, 0x75, - 0xb8, 0x7f, 0x75, 0xb3, 0x07, 0x75, 0xb2, 0x07, 0xd2, 0xa9, 0x22, 0xd2, 0x92, 0xe4, 0xd5, 0xe0, - 0xfd, 0xc2, 0x92, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x2f, 0x7e, 0xa0, 0x08, 0x19, 0xa2, 0x00, - 0x10, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xf2, 0x7e, 0x20, 0x00, 0x12, 0x41, 0x7e, 0x0b, 0x20, - 0xbe, 0x21, 0x2f, 0x78, 0xf6, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x74, 0xbf, 0x19, 0xb0, - 0x00, 0x0c, 0x74, 0x10, 0x19, 0xb0, 0x00, 0x08, 0x74, 0x80, 0x19, 0xb0, 0x00, 0x0c, 0x7e, 0x54, - 0x00, 0x02, 0x19, 0xa0, 0x00, 0x04, 0x19, 0xb0, 0x00, 0x00, 0x74, 0x03, 0x19, 0xb0, 0x00, 0x0c, - 0x74, 0x07, 0xa9, 0x20, 0x30, 0x0b, 0xa9, 0x35, 0x30, 0x05, 0xbe, 0x20, 0x01, 0x28, 0x02, 0x74, - 0x0f, 0x19, 0xb0, 0x00, 0x04, 0xa9, 0x33, 0x30, 0x18, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x74, - 0x28, 0xa9, 0x20, 0x30, 0x02, 0x74, 0x20, 0x19, 0xb0, 0x00, 0x04, 0x74, 0x03, 0x19, 0xb0, 0x00, - 0x0c, 0x74, 0xa7, 0x19, 0xb0, 0x00, 0x08, 0x74, 0x0c, 0x19, 0xb0, 0x00, 0x10, 0x22, 0x7e, 0x04, - 0x80, 0x00, 0x4c, 0x02, 0xe4, 0x19, 0xb0, 0x00, 0x04, 0x09, 0xb0, 0x00, 0x10, 0x54, 0x08, 0x19, - 0xb0, 0x00, 0x10, 0x74, 0xa7, 0x19, 0xb0, 0x00, 0x08, 0x22, 0x7c, 0xb2, 0x23, 0x0a, 0x2b, 0x49, - 0x22, 0x41, 0xa5, 0x89, 0x24, 0x41, 0xb5, 0x41, 0xd4, 0x41, 0xf3, 0x42, 0x12, 0x42, 0x31, 0x42, - 0x50, 0x42, 0x6f, 0x42, 0x8e, 0xc2, 0x10, 0xc2, 0x18, 0xc2, 0x20, 0xc2, 0x08, 0x7e, 0x04, 0x09, - 0xe3, 0x7a, 0x07, 0x01, 0x6f, 0x7a, 0x07, 0x01, 0x7f, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x8f, 0x7a, - 0x07, 0x01, 0x9f, 0x22, 0xc2, 0x11, 0xc2, 0x19, 0xc2, 0x21, 0xc2, 0x09, 0x7e, 0x04, 0x0d, 0xe3, - 0x7a, 0x07, 0x01, 0x71, 0x7a, 0x07, 0x01, 0x81, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x91, 0x7a, 0x07, - 0x01, 0xa1, 0x22, 0xc2, 0x12, 0xc2, 0x1a, 0xc2, 0x22, 0xc2, 0x0a, 0x7e, 0x04, 0x11, 0xe3, 0x7a, - 0x07, 0x01, 0x73, 0x7a, 0x07, 0x01, 0x83, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x93, 0x7a, 0x07, 0x01, - 0xa3, 0x22, 0xc2, 0x13, 0xc2, 0x1b, 0xc2, 0x23, 0xc2, 0x0b, 0x7e, 0x04, 0x15, 0xe3, 0x7a, 0x07, - 0x01, 0x75, 0x7a, 0x07, 0x01, 0x85, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x95, 0x7a, 0x07, 0x01, 0xa5, - 0x22, 0xc2, 0x14, 0xc2, 0x1c, 0xc2, 0x24, 0xc2, 0x0c, 0x7e, 0x04, 0x19, 0xe3, 0x7a, 0x07, 0x01, - 0x77, 0x7a, 0x07, 0x01, 0x87, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x97, 0x7a, 0x07, 0x01, 0xa7, 0x22, - 0xc2, 0x15, 0xc2, 0x1d, 0xc2, 0x25, 0xc2, 0x0d, 0x7e, 0x04, 0x1d, 0xe3, 0x7a, 0x07, 0x01, 0x79, - 0x7a, 0x07, 0x01, 0x89, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x99, 0x7a, 0x07, 0x01, 0xa9, 0x22, 0xc2, - 0x16, 0xc2, 0x1e, 0xc2, 0x26, 0xc2, 0x0e, 0x7e, 0x04, 0x21, 0xe3, 0x7a, 0x07, 0x01, 0x7b, 0x7a, - 0x07, 0x01, 0x8b, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x9b, 0x7a, 0x07, 0x01, 0xab, 0x22, 0xc2, 0x17, - 0xc2, 0x1f, 0xc2, 0x27, 0xc2, 0x0f, 0x7e, 0x04, 0x25, 0xe3, 0x7a, 0x07, 0x01, 0x7d, 0x7a, 0x07, - 0x01, 0x8d, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x9d, 0x7a, 0x07, 0x01, 0xad, 0x22, 0x7c, 0xb2, 0x23, - 0x0a, 0x2b, 0x49, 0x22, 0x42, 0xb8, 0x89, 0x24, 0x42, 0xc8, 0x42, 0xe9, 0x43, 0x0a, 0x43, 0x2b, - 0x43, 0x4c, 0x43, 0x6d, 0x43, 0x8e, 0x43, 0xaf, 0x30, 0x50, 0x07, 0x20, 0x68, 0x04, 0xc2, 0x28, - 0x80, 0x16, 0x30, 0x40, 0x07, 0x20, 0x60, 0x04, 0xc2, 0x28, 0x80, 0x0c, 0x30, 0x48, 0x07, 0x20, - 0x58, 0x04, 0xc2, 0x28, 0x80, 0x02, 0xd2, 0x28, 0x22, 0x30, 0x51, 0x07, 0x20, 0x69, 0x04, 0xc2, - 0x29, 0x80, 0x16, 0x30, 0x41, 0x07, 0x20, 0x61, 0x04, 0xc2, 0x29, 0x80, 0x0c, 0x30, 0x49, 0x07, - 0x20, 0x59, 0x04, 0xc2, 0x29, 0x80, 0x02, 0xd2, 0x29, 0x22, 0x30, 0x52, 0x07, 0x20, 0x6a, 0x04, - 0xc2, 0x2a, 0x80, 0x16, 0x30, 0x42, 0x07, 0x20, 0x62, 0x04, 0xc2, 0x2a, 0x80, 0x0c, 0x30, 0x4a, - 0x07, 0x20, 0x5a, 0x04, 0xc2, 0x2a, 0x80, 0x02, 0xd2, 0x2a, 0x22, 0x30, 0x53, 0x07, 0x20, 0x6b, - 0x04, 0xc2, 0x2b, 0x80, 0x16, 0x30, 0x43, 0x07, 0x20, 0x63, 0x04, 0xc2, 0x2b, 0x80, 0x0c, 0x30, - 0x4b, 0x07, 0x20, 0x5b, 0x04, 0xc2, 0x2b, 0x80, 0x02, 0xd2, 0x2b, 0x22, 0x30, 0x54, 0x07, 0x20, - 0x6c, 0x04, 0xc2, 0x2c, 0x80, 0x16, 0x30, 0x44, 0x07, 0x20, 0x64, 0x04, 0xc2, 0x2c, 0x80, 0x0c, - 0x30, 0x4c, 0x07, 0x20, 0x5c, 0x04, 0xc2, 0x2c, 0x80, 0x02, 0xd2, 0x2c, 0x22, 0x30, 0x55, 0x07, - 0x20, 0x6d, 0x04, 0xc2, 0x2d, 0x80, 0x16, 0x30, 0x45, 0x07, 0x20, 0x65, 0x04, 0xc2, 0x2d, 0x80, - 0x0c, 0x30, 0x4d, 0x07, 0x20, 0x5d, 0x04, 0xc2, 0x2d, 0x80, 0x02, 0xd2, 0x2d, 0x22, 0x30, 0x56, - 0x07, 0x20, 0x6e, 0x04, 0xc2, 0x2e, 0x80, 0x16, 0x30, 0x46, 0x07, 0x20, 0x66, 0x04, 0xc2, 0x2e, - 0x80, 0x0c, 0x30, 0x4e, 0x07, 0x20, 0x5e, 0x04, 0xc2, 0x2e, 0x80, 0x02, 0xd2, 0x2e, 0x22, 0x30, - 0x57, 0x07, 0x20, 0x6f, 0x04, 0xc2, 0x2f, 0x80, 0x16, 0x30, 0x47, 0x07, 0x20, 0x67, 0x04, 0xc2, - 0x2f, 0x80, 0x0c, 0x30, 0x4f, 0x07, 0x20, 0x5f, 0x04, 0xc2, 0x2f, 0x80, 0x02, 0xd2, 0x2f, 0x22, - 0x44, 0x38, 0x43, 0xe5, 0xbe, 0xb0, 0x02, 0x40, 0x01, 0x22, 0x23, 0x0a, 0x5b, 0x49, 0x55, 0x43, - 0xd0, 0x99, 0x54, 0xd3, 0x22, 0xa9, 0xc5, 0x87, 0x12, 0x44, 0x43, 0x7e, 0x04, 0x05, 0xe3, 0x7a, - 0x07, 0x01, 0xd7, 0x7a, 0x07, 0x01, 0xd9, 0x7e, 0x04, 0x01, 0xe3, 0x7a, 0x07, 0x01, 0xdd, 0x7a, - 0x07, 0x01, 0xdf, 0x7e, 0x04, 0x74, 0xad, 0x7a, 0x05, 0x61, 0x75, 0xf1, 0x01, 0x75, 0xe1, 0x1f, - 0x75, 0xe4, 0x04, 0x75, 0xf4, 0x04, 0x75, 0xf1, 0x02, 0x75, 0xe1, 0x03, 0x75, 0xe4, 0x04, 0x75, - 0xf4, 0x04, 0x43, 0xa2, 0x1c, 0x12, 0x40, 0xeb, 0x7e, 0x20, 0x00, 0x12, 0x41, 0x9a, 0x0b, 0x20, - 0xbe, 0x21, 0x2f, 0x78, 0xf6, 0xd2, 0xa8, 0x22, 0xa9, 0xd5, 0x87, 0x12, 0x44, 0x43, 0xd2, 0x92, - 0xc2, 0xa8, 0x22, 0x75, 0xa3, 0x00, 0x53, 0xa2, 0x03, 0x75, 0xc1, 0x00, 0x53, 0xc0, 0x03, 0x7e, - 0x00, 0x05, 0x7a, 0x01, 0xf1, 0x43, 0xf4, 0x80, 0x43, 0xe4, 0x80, 0xe5, 0xf2, 0x54, 0x7f, 0x44, - 0x08, 0xf5, 0xf2, 0xe5, 0xe2, 0x54, 0x7f, 0x44, 0x08, 0xf5, 0xe2, 0x75, 0xe1, 0x10, 0xa5, 0xd8, - 0xe1, 0x22, 0xca, 0x09, 0x12, 0x30, 0x20, 0x10, 0x01, 0x12, 0xd5, 0x67, 0x1e, 0x63, 0x69, 0x01, - 0x7e, 0x00, 0x6a, 0x2e, 0x01, 0x69, 0xa5, 0xe6, 0xf5, 0x67, 0x80, 0x12, 0x20, 0x02, 0x1e, 0x75, - 0x69, 0x00, 0x85, 0x6a, 0x67, 0xd2, 0x02, 0x74, 0x00, 0x80, 0x0d, 0x30, 0x02, 0x0f, 0xc2, 0x02, - 0x7e, 0x00, 0x6c, 0x2e, 0x01, 0x69, 0xa5, 0xe6, 0x53, 0x90, 0xcf, 0x42, 0x90, 0xda, 0x09, 0x32, - 0xc0, 0xd0, 0xc0, 0xd1, 0xc0, 0xe0, 0xc0, 0xf0, 0xca, 0x0b, 0xca, 0x1b, 0xca, 0x2b, 0xd2, 0x01, - 0x75, 0x31, 0x89, 0x12, 0x7c, 0x15, 0x7e, 0x14, 0x80, 0x00, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, - 0x03, 0x02, 0x45, 0x4f, 0x20, 0x78, 0x5a, 0xa5, 0x0a, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x03, - 0x02, 0x45, 0x67, 0x20, 0x79, 0x4b, 0xa5, 0x0a, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x03, 0x02, - 0x45, 0x7f, 0xa5, 0x0a, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x03, 0x02, 0x45, 0x97, 0x20, 0x7a, - 0x30, 0xa5, 0x0a, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x03, 0x02, 0x45, 0xaf, 0xa5, 0x0a, 0x09, - 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x03, 0x02, 0x45, 0xc7, 0xa5, 0x0a, 0x09, 0xb1, 0x00, 0x08, 0x20, - 0xe0, 0x03, 0x02, 0x45, 0xdf, 0xa5, 0x0a, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x03, 0x02, 0x45, - 0xf7, 0x30, 0x04, 0x0c, 0xc2, 0x04, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, - 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0xd0, 0xf0, 0xd0, 0xe0, 0xd0, 0xd1, 0xd0, 0xd0, 0x32, 0x75, - 0x31, 0x80, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x63, - 0x2b, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, 0x31, 0x81, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, - 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x63, 0x6b, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, - 0x31, 0x82, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x63, - 0xab, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, 0x31, 0x83, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, - 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x63, 0xeb, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, - 0x31, 0x84, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x64, - 0x2b, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, 0x31, 0x85, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, - 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x64, 0x6b, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, - 0x31, 0x86, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x64, - 0xab, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x75, 0x31, 0x87, 0x12, 0x7c, 0x15, 0x54, 0x3e, 0x0a, - 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x64, 0xeb, 0xca, 0x06, 0xc6, 0x44, 0x89, 0x54, 0x10, - 0x08, 0x01, 0x22, 0x20, 0x28, 0x03, 0xd2, 0x08, 0x22, 0x75, 0x31, 0xa0, 0x12, 0x7c, 0x15, 0x7e, - 0x14, 0x80, 0x00, 0x80, 0x06, 0x20, 0x28, 0x03, 0xd2, 0x08, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, - 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x49, 0x30, 0x20, 0xe6, 0x03, 0xd2, 0x08, - 0x22, 0x30, 0x30, 0x49, 0xd2, 0x70, 0x7e, 0x37, 0x01, 0x8f, 0x7e, 0x27, 0x01, 0xaf, 0x9d, 0x32, - 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x48, 0x7a, 0x05, 0x48, 0x7a, 0x37, 0x01, 0x8f, 0x7e, 0x37, - 0x01, 0x6f, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x0d, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x6f, - 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, - 0x70, 0xc4, 0x22, 0xc2, 0x70, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, - 0x8f, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xaf, 0x28, 0x04, 0x7e, 0x27, 0x01, - 0xaf, 0x7e, 0x37, 0x01, 0x8f, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x48, 0x7a, 0x05, 0x48, 0x7a, - 0x37, 0x01, 0x8f, 0x7e, 0x37, 0x01, 0x6f, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x0d, 0xe2, 0x38, - 0x13, 0x7a, 0x47, 0x01, 0x6f, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, - 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x0d, 0xe3, 0x9d, 0x24, 0x12, 0x65, 0x2b, 0x7e, 0x34, 0x09, 0xe3, 0x7d, 0x24, 0x2d, - 0x43, 0x7a, 0x47, 0x01, 0x6f, 0x12, 0x65, 0x2b, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x46, 0x7f, - 0x22, 0xd2, 0x08, 0x7e, 0x04, 0x09, 0xe3, 0x7a, 0x07, 0x01, 0x6f, 0x7a, 0x07, 0x01, 0x7f, 0x75, - 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, - 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, - 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xbf, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, - 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, - 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, - 0x01, 0xdf, 0x7e, 0x24, 0x00, 0x00, 0x2e, 0x27, 0x01, 0xbf, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, - 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, - 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, - 0x30, 0x38, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x10, 0x22, - 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, - 0x00, 0x00, 0x2e, 0x67, 0x01, 0xbf, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, - 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, - 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, - 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x00, 0x7a, 0x69, - 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, - 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, - 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, - 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, - 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, - 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, - 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, - 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, - 0x02, 0x47, 0xe3, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, - 0xb1, 0x00, 0x04, 0x30, 0x38, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, - 0xd2, 0x10, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x47, - 0xe3, 0xda, 0xb8, 0x02, 0x49, 0x30, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, - 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, - 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, - 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, - 0x68, 0x80, 0x02, 0xc2, 0x68, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x60, 0x80, 0x02, - 0xc2, 0x60, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x58, 0x80, 0x02, 0xc2, 0x58, 0x12, - 0x42, 0xc8, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, - 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, - 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, - 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, - 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x48, 0x35, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, - 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, 0x09, 0x01, 0x22, 0x20, 0x29, 0x03, 0xd2, 0x09, - 0x22, 0x75, 0x31, 0xa1, 0x12, 0x7c, 0x15, 0x7e, 0x14, 0x81, 0x00, 0x80, 0x06, 0x20, 0x29, 0x03, - 0xd2, 0x09, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, - 0x12, 0x4c, 0x88, 0x20, 0xe6, 0x03, 0xd2, 0x09, 0x22, 0x30, 0x31, 0x49, 0xd2, 0x71, 0x7e, 0x37, - 0x01, 0x91, 0x7e, 0x27, 0x01, 0xb1, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x4a, 0x7a, - 0x05, 0x4a, 0x7a, 0x37, 0x01, 0x91, 0x7e, 0x37, 0x01, 0x71, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, - 0x11, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x71, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, - 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, 0x71, 0xc4, 0x22, 0xc2, 0x71, 0x2d, 0x23, 0x68, - 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x91, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, - 0x27, 0x01, 0xb1, 0x28, 0x04, 0x7e, 0x27, 0x01, 0xb1, 0x7e, 0x37, 0x01, 0x91, 0x9d, 0x32, 0x7d, - 0x02, 0x2e, 0x05, 0x4a, 0x7a, 0x05, 0x4a, 0x7a, 0x37, 0x01, 0x91, 0x7e, 0x37, 0x01, 0x71, 0x7d, - 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x11, 0xe2, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x71, 0x75, 0x31, 0x94, - 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, - 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x11, 0xe3, 0x9d, 0x24, 0x12, 0x65, - 0x2b, 0x7e, 0x34, 0x0d, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x71, 0x12, 0x65, 0x2b, - 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x49, 0xd7, 0x22, 0xd2, 0x09, 0x7e, 0x04, 0x0d, 0xe3, 0x7a, - 0x07, 0x01, 0x71, 0x7a, 0x07, 0x01, 0x81, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, - 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, - 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xc1, - 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, - 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, - 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, 0x01, 0xdf, 0x7e, 0x24, 0x01, 0x00, 0x2e, 0x27, - 0x01, 0xc1, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, - 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, - 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x39, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, - 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x11, 0x22, 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, 0x01, 0x00, 0x2e, 0x67, 0x01, 0xc1, 0x9e, 0x24, - 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, - 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, - 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, - 0x0f, 0x23, 0x23, 0x23, 0x44, 0x01, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, - 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, - 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, - 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, - 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, - 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, - 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, - 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, - 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x4b, 0x3b, 0x75, 0x31, 0x99, 0x12, 0x7c, - 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x39, 0x0a, 0x09, 0xb1, - 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x11, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, - 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x4b, 0x3b, 0xda, 0xb8, 0x02, 0x4c, 0x88, 0x09, 0xb1, - 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, - 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, - 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, - 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x69, 0x80, 0x02, 0xc2, 0x69, 0xa5, 0xfd, 0x5e, - 0x50, 0x20, 0x68, 0x04, 0xd2, 0x61, 0x80, 0x02, 0xc2, 0x61, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, - 0x04, 0xd2, 0x59, 0x80, 0x02, 0xc2, 0x59, 0x12, 0x42, 0xe9, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, - 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, - 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, - 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, - 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x4b, - 0x8d, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, - 0x0a, 0x01, 0x22, 0x20, 0x2a, 0x03, 0xd2, 0x0a, 0x22, 0x75, 0x31, 0xa2, 0x12, 0x7c, 0x15, 0x7e, - 0x14, 0x82, 0x00, 0x80, 0x06, 0x20, 0x2a, 0x03, 0xd2, 0x0a, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, - 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x4f, 0xe0, 0x20, 0xe6, 0x03, 0xd2, 0x0a, - 0x22, 0x30, 0x32, 0x49, 0xd2, 0x72, 0x7e, 0x37, 0x01, 0x93, 0x7e, 0x27, 0x01, 0xb3, 0x9d, 0x32, - 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x4c, 0x7a, 0x05, 0x4c, 0x7a, 0x37, 0x01, 0x93, 0x7e, 0x37, - 0x01, 0x73, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x15, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x73, - 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, - 0x72, 0xc4, 0x22, 0xc2, 0x72, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, - 0x93, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xb3, 0x28, 0x04, 0x7e, 0x27, 0x01, - 0xb3, 0x7e, 0x37, 0x01, 0x93, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x4c, 0x7a, 0x05, 0x4c, 0x7a, - 0x37, 0x01, 0x93, 0x7e, 0x37, 0x01, 0x73, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x15, 0xe2, 0x38, - 0x13, 0x7a, 0x47, 0x01, 0x73, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, - 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x15, 0xe3, 0x9d, 0x24, 0x12, 0x65, 0x2b, 0x7e, 0x34, 0x11, 0xe3, 0x7d, 0x24, 0x2d, - 0x43, 0x7a, 0x47, 0x01, 0x73, 0x12, 0x65, 0x2b, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x4d, 0x2f, - 0x22, 0xd2, 0x0a, 0x7e, 0x04, 0x11, 0xe3, 0x7a, 0x07, 0x01, 0x73, 0x7a, 0x07, 0x01, 0x83, 0x75, - 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, - 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, - 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xc3, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, - 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, - 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, - 0x01, 0xdf, 0x7e, 0x24, 0x02, 0x00, 0x2e, 0x27, 0x01, 0xc3, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, - 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, - 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, - 0x30, 0x3a, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x12, 0x22, - 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, - 0x02, 0x00, 0x2e, 0x67, 0x01, 0xc3, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, - 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, - 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, - 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x02, 0x7a, 0x69, - 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, - 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, - 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, - 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, - 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, - 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, - 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, - 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, - 0x02, 0x4e, 0x93, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, - 0xb1, 0x00, 0x04, 0x30, 0x3a, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, - 0xd2, 0x12, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x4e, - 0x93, 0xda, 0xb8, 0x02, 0x4f, 0xe0, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, - 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, - 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, - 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, - 0x6a, 0x80, 0x02, 0xc2, 0x6a, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x62, 0x80, 0x02, - 0xc2, 0x62, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5a, 0x80, 0x02, 0xc2, 0x5a, 0x12, - 0x43, 0x0a, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, - 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, - 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, - 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, - 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x4e, 0xe5, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, - 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, 0x0b, 0x01, 0x22, 0x20, 0x2b, 0x03, 0xd2, 0x0b, - 0x22, 0x75, 0x31, 0xa3, 0x12, 0x7c, 0x15, 0x7e, 0x14, 0x83, 0x00, 0x80, 0x06, 0x20, 0x2b, 0x03, - 0xd2, 0x0b, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, - 0x12, 0x53, 0x38, 0x20, 0xe6, 0x03, 0xd2, 0x0b, 0x22, 0x30, 0x33, 0x49, 0xd2, 0x73, 0x7e, 0x37, - 0x01, 0x95, 0x7e, 0x27, 0x01, 0xb5, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x4e, 0x7a, - 0x05, 0x4e, 0x7a, 0x37, 0x01, 0x95, 0x7e, 0x37, 0x01, 0x75, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, - 0x19, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x75, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, - 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, 0x73, 0xc4, 0x22, 0xc2, 0x73, 0x2d, 0x23, 0x68, - 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x95, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, - 0x27, 0x01, 0xb5, 0x28, 0x04, 0x7e, 0x27, 0x01, 0xb5, 0x7e, 0x37, 0x01, 0x95, 0x9d, 0x32, 0x7d, - 0x02, 0x2e, 0x05, 0x4e, 0x7a, 0x05, 0x4e, 0x7a, 0x37, 0x01, 0x95, 0x7e, 0x37, 0x01, 0x75, 0x7d, - 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x19, 0xe2, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x75, 0x75, 0x31, 0x94, - 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, - 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x19, 0xe3, 0x9d, 0x24, 0x12, 0x65, - 0x2b, 0x7e, 0x34, 0x15, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x75, 0x12, 0x65, 0x2b, - 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x50, 0x87, 0x22, 0xd2, 0x0b, 0x7e, 0x04, 0x15, 0xe3, 0x7a, - 0x07, 0x01, 0x75, 0x7a, 0x07, 0x01, 0x85, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, - 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, - 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xc5, - 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, - 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, - 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, 0x01, 0xdf, 0x7e, 0x24, 0x03, 0x00, 0x2e, 0x27, - 0x01, 0xc5, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, - 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, - 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3b, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, - 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x13, 0x22, 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, 0x03, 0x00, 0x2e, 0x67, 0x01, 0xc5, 0x9e, 0x24, - 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, - 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, - 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, - 0x0f, 0x23, 0x23, 0x23, 0x44, 0x03, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, - 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, - 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, - 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, - 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, - 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, - 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, - 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, - 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x51, 0xeb, 0x75, 0x31, 0x99, 0x12, 0x7c, - 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3b, 0x0a, 0x09, 0xb1, - 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x13, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, - 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x51, 0xeb, 0xda, 0xb8, 0x02, 0x53, 0x38, 0x09, 0xb1, - 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, - 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, - 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, - 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6b, 0x80, 0x02, 0xc2, 0x6b, 0xa5, 0xfd, 0x5e, - 0x50, 0x20, 0x68, 0x04, 0xd2, 0x63, 0x80, 0x02, 0xc2, 0x63, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, - 0x04, 0xd2, 0x5b, 0x80, 0x02, 0xc2, 0x5b, 0x12, 0x43, 0x2b, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, - 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, - 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, - 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, - 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x52, - 0x3d, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, - 0x0c, 0x01, 0x22, 0x20, 0x2c, 0x03, 0xd2, 0x0c, 0x22, 0x75, 0x31, 0xa4, 0x12, 0x7c, 0x15, 0x7e, - 0x14, 0x84, 0x00, 0x80, 0x06, 0x20, 0x2c, 0x03, 0xd2, 0x0c, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, - 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x56, 0x90, 0x20, 0xe6, 0x03, 0xd2, 0x0c, - 0x22, 0x30, 0x34, 0x49, 0xd2, 0x74, 0x7e, 0x37, 0x01, 0x97, 0x7e, 0x27, 0x01, 0xb7, 0x9d, 0x32, - 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x50, 0x7a, 0x05, 0x50, 0x7a, 0x37, 0x01, 0x97, 0x7e, 0x37, - 0x01, 0x77, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x1d, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x77, - 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, - 0x74, 0xc4, 0x22, 0xc2, 0x74, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, - 0x97, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xb7, 0x28, 0x04, 0x7e, 0x27, 0x01, - 0xb7, 0x7e, 0x37, 0x01, 0x97, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x50, 0x7a, 0x05, 0x50, 0x7a, - 0x37, 0x01, 0x97, 0x7e, 0x37, 0x01, 0x77, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x1d, 0xe2, 0x38, - 0x13, 0x7a, 0x47, 0x01, 0x77, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, - 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x1d, 0xe3, 0x9d, 0x24, 0x12, 0x65, 0x2b, 0x7e, 0x34, 0x19, 0xe3, 0x7d, 0x24, 0x2d, - 0x43, 0x7a, 0x47, 0x01, 0x77, 0x12, 0x65, 0x2b, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x53, 0xdf, - 0x22, 0xd2, 0x0c, 0x7e, 0x04, 0x19, 0xe3, 0x7a, 0x07, 0x01, 0x77, 0x7a, 0x07, 0x01, 0x87, 0x75, - 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, - 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, - 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xc7, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, - 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, - 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, - 0x01, 0xdf, 0x7e, 0x24, 0x04, 0x00, 0x2e, 0x27, 0x01, 0xc7, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, - 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, - 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, - 0x30, 0x3c, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x14, 0x22, - 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, - 0x04, 0x00, 0x2e, 0x67, 0x01, 0xc7, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, - 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, - 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, - 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x04, 0x7a, 0x69, - 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, - 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, - 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, - 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, - 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, - 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, - 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, - 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, - 0x02, 0x55, 0x43, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, - 0xb1, 0x00, 0x04, 0x30, 0x3c, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, - 0xd2, 0x14, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x55, - 0x43, 0xda, 0xb8, 0x02, 0x56, 0x90, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, - 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, - 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, - 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, - 0x6c, 0x80, 0x02, 0xc2, 0x6c, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x64, 0x80, 0x02, - 0xc2, 0x64, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5c, 0x80, 0x02, 0xc2, 0x5c, 0x12, - 0x43, 0x4c, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, - 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, - 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, - 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, - 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x55, 0x95, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, - 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, 0x0d, 0x01, 0x22, 0x20, 0x2d, 0x03, 0xd2, 0x0d, - 0x22, 0x75, 0x31, 0xa5, 0x12, 0x7c, 0x15, 0x7e, 0x14, 0x85, 0x00, 0x80, 0x06, 0x20, 0x2d, 0x03, - 0xd2, 0x0d, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, - 0x12, 0x59, 0xe8, 0x20, 0xe6, 0x03, 0xd2, 0x0d, 0x22, 0x30, 0x35, 0x49, 0xd2, 0x75, 0x7e, 0x37, - 0x01, 0x99, 0x7e, 0x27, 0x01, 0xb9, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x52, 0x7a, - 0x05, 0x52, 0x7a, 0x37, 0x01, 0x99, 0x7e, 0x37, 0x01, 0x79, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, - 0x21, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x79, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, - 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, 0x75, 0xc4, 0x22, 0xc2, 0x75, 0x2d, 0x23, 0x68, - 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x99, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, - 0x27, 0x01, 0xb9, 0x28, 0x04, 0x7e, 0x27, 0x01, 0xb9, 0x7e, 0x37, 0x01, 0x99, 0x9d, 0x32, 0x7d, - 0x02, 0x2e, 0x05, 0x52, 0x7a, 0x05, 0x52, 0x7a, 0x37, 0x01, 0x99, 0x7e, 0x37, 0x01, 0x79, 0x7d, - 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x21, 0xe2, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x79, 0x75, 0x31, 0x94, - 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, - 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x21, 0xe3, 0x9d, 0x24, 0x12, 0x65, - 0x2b, 0x7e, 0x34, 0x1d, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x79, 0x12, 0x65, 0x2b, - 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x57, 0x37, 0x22, 0xd2, 0x0d, 0x7e, 0x04, 0x1d, 0xe3, 0x7a, - 0x07, 0x01, 0x79, 0x7a, 0x07, 0x01, 0x89, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, - 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, - 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xc9, - 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, - 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, - 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, 0x01, 0xdf, 0x7e, 0x24, 0x05, 0x00, 0x2e, 0x27, - 0x01, 0xc9, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, - 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, - 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3d, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, - 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x15, 0x22, 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, 0x05, 0x00, 0x2e, 0x67, 0x01, 0xc9, 0x9e, 0x24, - 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, - 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, - 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, - 0x0f, 0x23, 0x23, 0x23, 0x44, 0x05, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, - 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, - 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, - 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, - 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, - 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, - 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, - 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, - 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x58, 0x9b, 0x75, 0x31, 0x99, 0x12, 0x7c, - 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3d, 0x0a, 0x09, 0xb1, - 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x15, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, - 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x58, 0x9b, 0xda, 0xb8, 0x02, 0x59, 0xe8, 0x09, 0xb1, - 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, - 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, - 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, - 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6d, 0x80, 0x02, 0xc2, 0x6d, 0xa5, 0xfd, 0x5e, - 0x50, 0x20, 0x68, 0x04, 0xd2, 0x65, 0x80, 0x02, 0xc2, 0x65, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, - 0x04, 0xd2, 0x5d, 0x80, 0x02, 0xc2, 0x5d, 0x12, 0x43, 0x6d, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, - 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, - 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, - 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, - 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x58, - 0xed, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, - 0x0e, 0x01, 0x22, 0x20, 0x2e, 0x03, 0xd2, 0x0e, 0x22, 0x75, 0x31, 0xa6, 0x12, 0x7c, 0x15, 0x7e, - 0x14, 0x86, 0x00, 0x80, 0x06, 0x20, 0x2e, 0x03, 0xd2, 0x0e, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, - 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x5d, 0x40, 0x20, 0xe6, 0x03, 0xd2, 0x0e, - 0x22, 0x30, 0x36, 0x49, 0xd2, 0x76, 0x7e, 0x37, 0x01, 0x9b, 0x7e, 0x27, 0x01, 0xbb, 0x9d, 0x32, - 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x54, 0x7a, 0x05, 0x54, 0x7a, 0x37, 0x01, 0x9b, 0x7e, 0x37, - 0x01, 0x7b, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x25, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x7b, - 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, - 0x76, 0xc4, 0x22, 0xc2, 0x76, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, - 0x9b, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xbb, 0x28, 0x04, 0x7e, 0x27, 0x01, - 0xbb, 0x7e, 0x37, 0x01, 0x9b, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x54, 0x7a, 0x05, 0x54, 0x7a, - 0x37, 0x01, 0x9b, 0x7e, 0x37, 0x01, 0x7b, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x25, 0xe2, 0x38, - 0x13, 0x7a, 0x47, 0x01, 0x7b, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, - 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x25, 0xe3, 0x9d, 0x24, 0x12, 0x65, 0x2b, 0x7e, 0x34, 0x21, 0xe3, 0x7d, 0x24, 0x2d, - 0x43, 0x7a, 0x47, 0x01, 0x7b, 0x12, 0x65, 0x2b, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x5a, 0x8f, - 0x22, 0xd2, 0x0e, 0x7e, 0x04, 0x21, 0xe3, 0x7a, 0x07, 0x01, 0x7b, 0x7a, 0x07, 0x01, 0x8b, 0x75, - 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, - 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, - 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xcb, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, - 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, - 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, - 0x01, 0xdf, 0x7e, 0x24, 0x06, 0x00, 0x2e, 0x27, 0x01, 0xcb, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, - 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, - 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, - 0x30, 0x3e, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x16, 0x22, - 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, - 0x06, 0x00, 0x2e, 0x67, 0x01, 0xcb, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, - 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, - 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, - 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x06, 0x7a, 0x69, - 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, - 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, - 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, - 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, - 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, - 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, - 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, - 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, - 0x02, 0x5b, 0xf3, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, - 0xb1, 0x00, 0x04, 0x30, 0x3e, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, - 0xd2, 0x16, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x5b, - 0xf3, 0xda, 0xb8, 0x02, 0x5d, 0x40, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, - 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, - 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, - 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, - 0x6e, 0x80, 0x02, 0xc2, 0x6e, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x66, 0x80, 0x02, - 0xc2, 0x66, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5e, 0x80, 0x02, 0xc2, 0x5e, 0x12, - 0x43, 0x8e, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, - 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, - 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, - 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, - 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x5c, 0x45, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, - 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x10, 0x0f, 0x01, 0x22, 0x20, 0x2f, 0x03, 0xd2, 0x0f, - 0x22, 0x75, 0x31, 0xa7, 0x12, 0x7c, 0x15, 0x7e, 0x14, 0x87, 0x00, 0x80, 0x06, 0x20, 0x2f, 0x03, - 0xd2, 0x0f, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, - 0x12, 0x60, 0x98, 0x20, 0xe6, 0x03, 0xd2, 0x0f, 0x22, 0x30, 0x37, 0x49, 0xd2, 0x77, 0x7e, 0x37, - 0x01, 0x9d, 0x7e, 0x27, 0x01, 0xbd, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x56, 0x7a, - 0x05, 0x56, 0x7a, 0x37, 0x01, 0x9d, 0x7e, 0x37, 0x01, 0x7d, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, - 0x29, 0xe2, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x7d, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x7a, 0x51, - 0x31, 0x12, 0x7c, 0x15, 0x12, 0x65, 0x2b, 0x10, 0x77, 0xc4, 0x22, 0xc2, 0x77, 0x2d, 0x23, 0x68, - 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x9d, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, - 0x27, 0x01, 0xbd, 0x28, 0x04, 0x7e, 0x27, 0x01, 0xbd, 0x7e, 0x37, 0x01, 0x9d, 0x9d, 0x32, 0x7d, - 0x02, 0x2e, 0x05, 0x56, 0x7a, 0x05, 0x56, 0x7a, 0x37, 0x01, 0x9d, 0x7e, 0x37, 0x01, 0x7d, 0x7d, - 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x29, 0xe2, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x7d, 0x75, 0x31, 0x94, - 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x02, 0x65, 0x2b, 0x75, 0x31, 0x94, 0x12, - 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x29, 0xe3, 0x9d, 0x24, 0x12, 0x65, - 0x2b, 0x7e, 0x34, 0x25, 0xe3, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x7d, 0x12, 0x65, 0x2b, - 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x5d, 0xe7, 0x22, 0xd2, 0x0f, 0x7e, 0x04, 0x25, 0xe3, 0x7a, - 0x07, 0x01, 0x7d, 0x7a, 0x07, 0x01, 0x8d, 0x75, 0x31, 0x94, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x00, - 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x92, 0x12, 0x7c, 0x15, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, - 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x70, 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x27, 0x01, 0xcd, - 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x3c, 0x7d, 0x02, 0x2e, 0x05, - 0x46, 0x7a, 0x05, 0x46, 0x7a, 0x37, 0x01, 0xe1, 0x7e, 0x37, 0x01, 0xdf, 0x7d, 0x43, 0x2d, 0x42, - 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x44, 0x7a, 0x47, 0x01, 0xdf, 0x7e, 0x24, 0x07, 0x00, 0x2e, 0x27, - 0x01, 0xcd, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0xbe, 0x50, 0x38, - 0x78, 0x03, 0x02, 0x66, 0x16, 0x02, 0x65, 0xfb, 0x75, 0x31, 0x99, 0x12, 0x7c, 0x15, 0x09, 0xb1, - 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3f, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, - 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x17, 0x22, 0x80, 0x7d, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, - 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x24, 0x7e, 0x64, 0x07, 0x00, 0x2e, 0x67, 0x01, 0xcd, 0x9e, 0x24, - 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x65, 0xfb, 0x7e, 0x34, 0x01, 0xe3, - 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdf, 0x02, 0x65, 0xfb, 0x7a, 0x39, 0xc0, 0x7e, 0x34, - 0x01, 0xe3, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, - 0x0f, 0x23, 0x23, 0x23, 0x44, 0x07, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x31, - 0x93, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0xbd, 0x04, 0x68, 0x29, 0x7a, 0x07, - 0x01, 0xdf, 0x7e, 0x47, 0x01, 0xe1, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xe1, 0x2e, 0x35, 0x46, 0x7a, - 0x35, 0x46, 0x22, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, - 0x2a, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0x2c, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0xd1, 0xd2, 0x04, 0x7e, - 0x07, 0x01, 0xe1, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xdf, 0x7e, - 0x44, 0x05, 0xe3, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x70, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xce, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, - 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, - 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x5f, 0x4b, 0x75, 0x31, 0x99, 0x12, 0x7c, - 0x15, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3f, 0x0a, 0x09, 0xb1, - 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x17, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, - 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x5f, 0x4b, 0xda, 0xb8, 0x02, 0x60, 0x98, 0x09, 0xb1, - 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x31, 0x90, 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, 0x7c, 0x15, - 0xa5, 0xfc, 0x5e, 0xb0, 0xf0, 0xa5, 0xfd, 0x09, 0xb1, 0x00, 0x18, 0x4c, 0x4b, 0x5e, 0xb0, 0xf0, - 0xbc, 0xb5, 0x78, 0xf1, 0x5e, 0x40, 0x0f, 0x4c, 0x54, 0x7c, 0xb5, 0x5e, 0x50, 0x0b, 0x68, 0x2a, - 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6f, 0x80, 0x02, 0xc2, 0x6f, 0xa5, 0xfd, 0x5e, - 0x50, 0x20, 0x68, 0x04, 0xd2, 0x67, 0x80, 0x02, 0xc2, 0x67, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, - 0x04, 0xd2, 0x5f, 0x80, 0x02, 0xc2, 0x5f, 0x12, 0x43, 0xaf, 0x02, 0x62, 0x93, 0x75, 0x31, 0x91, - 0x12, 0x7c, 0x15, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x20, 0xe0, 0x08, - 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x62, 0x93, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, - 0x12, 0x62, 0x93, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, - 0x61, 0x00, 0x00, 0x12, 0x62, 0xb6, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x5f, - 0x9d, 0x75, 0x31, 0x95, 0x12, 0x7c, 0x15, 0x22, 0x75, 0x31, 0x96, 0x12, 0x7c, 0x15, 0x22, 0x7c, - 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x10, - 0x68, 0x04, 0xd2, 0x68, 0x80, 0x02, 0xc2, 0x68, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, - 0x60, 0x80, 0x02, 0xc2, 0x60, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x58, 0x80, 0x02, - 0xc2, 0x58, 0x02, 0x62, 0x7f, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, - 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x69, 0x80, 0x02, 0xc2, 0x69, 0xa5, 0xfd, - 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x61, 0x80, 0x02, 0xc2, 0x61, 0xa5, 0xfd, 0x5e, 0x50, 0x80, - 0x68, 0x04, 0xd2, 0x59, 0x80, 0x02, 0xc2, 0x59, 0x02, 0x62, 0x7f, 0x7c, 0x02, 0x7e, 0x14, 0x80, - 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6a, - 0x80, 0x02, 0xc2, 0x6a, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x62, 0x80, 0x02, 0xc2, - 0x62, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5a, 0x80, 0x02, 0xc2, 0x5a, 0x02, 0x62, - 0x7f, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, - 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6b, 0x80, 0x02, 0xc2, 0x6b, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, - 0x04, 0xd2, 0x63, 0x80, 0x02, 0xc2, 0x63, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5b, - 0x80, 0x02, 0xc2, 0x5b, 0x02, 0x62, 0x7f, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, - 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6c, 0x80, 0x02, 0xc2, 0x6c, - 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x64, 0x80, 0x02, 0xc2, 0x64, 0xa5, 0xfd, 0x5e, - 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5c, 0x80, 0x02, 0xc2, 0x5c, 0x02, 0x62, 0x7f, 0x7c, 0x02, 0x7e, - 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, - 0xd2, 0x6d, 0x80, 0x02, 0xc2, 0x6d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x65, 0x80, - 0x02, 0xc2, 0x65, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5d, 0x80, 0x02, 0xc2, 0x5d, - 0x02, 0x62, 0x7f, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, - 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6e, 0x80, 0x02, 0xc2, 0x6e, 0xa5, 0xfd, 0x5e, 0x50, - 0x20, 0x68, 0x04, 0xd2, 0x66, 0x80, 0x02, 0xc2, 0x66, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, - 0xd2, 0x5e, 0x80, 0x02, 0xc2, 0x5e, 0x02, 0x62, 0x7f, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, - 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x10, 0x68, 0x04, 0xd2, 0x6f, 0x80, 0x02, - 0xc2, 0x6f, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x67, 0x80, 0x02, 0xc2, 0x67, 0xa5, - 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x5f, 0x80, 0x02, 0xc2, 0x5f, 0x02, 0x62, 0x7f, 0x54, - 0xf0, 0xc4, 0xa5, 0xff, 0xc4, 0xa5, 0x4f, 0x75, 0x31, 0x90, 0x12, 0x7c, 0x15, 0xf5, 0x31, 0x12, - 0x7c, 0x15, 0x22, 0xca, 0x19, 0x5e, 0x20, 0x07, 0x4c, 0xa2, 0x7e, 0x74, 0x29, 0xe3, 0xca, 0x79, - 0x7a, 0x79, 0xa0, 0x0b, 0x74, 0x7a, 0x79, 0xb0, 0x0b, 0x74, 0xda, 0x79, 0x7e, 0x30, 0x02, 0x7e, - 0x64, 0x00, 0x02, 0x02, 0x62, 0xde, 0xca, 0x19, 0x5e, 0x20, 0x07, 0x4c, 0xa2, 0x7e, 0x74, 0x29, - 0xe3, 0xca, 0x79, 0x7a, 0x79, 0xa0, 0x0b, 0x74, 0x7a, 0x79, 0xb0, 0x0b, 0x74, 0x7a, 0x79, 0x60, - 0x0b, 0x74, 0xda, 0x79, 0x7e, 0x30, 0x03, 0x7e, 0x64, 0x00, 0x03, 0x02, 0x62, 0xde, 0xd2, 0x04, - 0x7e, 0x27, 0x01, 0xe1, 0x2d, 0x26, 0xbe, 0x24, 0x04, 0x00, 0x38, 0x2e, 0x7e, 0x07, 0x01, 0xdf, - 0x7e, 0x44, 0x05, 0xe3, 0x7e, 0x79, 0xa0, 0x7a, 0x09, 0xa0, 0x0b, 0x04, 0x0b, 0x74, 0xbd, 0x04, - 0x68, 0x23, 0xa5, 0xdb, 0xef, 0x7a, 0x27, 0x01, 0xe1, 0x7e, 0x25, 0x46, 0x2d, 0x26, 0x7a, 0x25, - 0x46, 0x7a, 0x07, 0x01, 0xdf, 0xda, 0x19, 0xc2, 0xd7, 0x22, 0x75, 0x31, 0x9a, 0x12, 0x7c, 0x15, - 0xda, 0x19, 0xd2, 0xd7, 0x22, 0x7e, 0x04, 0x01, 0xe3, 0x80, 0xd7, 0x48, 0xb6, 0x46, 0x25, 0x47, - 0x1c, 0x49, 0x15, 0x44, 0xc6, 0x44, 0xc6, 0x48, 0x1b, 0x44, 0xc6, 0x49, 0x59, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x49, 0x60, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x4c, 0x0e, 0x49, 0x7d, 0x4a, - 0x74, 0x4c, 0x6d, 0x44, 0xc6, 0x44, 0xc6, 0x4b, 0x73, 0x44, 0xc6, 0x4c, 0xb1, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x4c, 0xb8, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x4f, 0x66, 0x4c, 0xd5, 0x4d, - 0xcc, 0x4f, 0xc5, 0x44, 0xc6, 0x44, 0xc6, 0x4e, 0xcb, 0x44, 0xc6, 0x50, 0x09, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x50, 0x10, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x52, 0xbe, 0x50, 0x2d, 0x51, - 0x24, 0x53, 0x1d, 0x44, 0xc6, 0x44, 0xc6, 0x52, 0x23, 0x44, 0xc6, 0x53, 0x61, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x53, 0x68, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x56, 0x16, 0x53, 0x85, 0x54, - 0x7c, 0x56, 0x75, 0x44, 0xc6, 0x44, 0xc6, 0x55, 0x7b, 0x44, 0xc6, 0x56, 0xb9, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x56, 0xc0, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x59, 0x6e, 0x56, 0xdd, 0x57, - 0xd4, 0x59, 0xcd, 0x44, 0xc6, 0x44, 0xc6, 0x58, 0xd3, 0x44, 0xc6, 0x5a, 0x11, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x5a, 0x18, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x5c, 0xc6, 0x5a, 0x35, 0x5b, - 0x2c, 0x5d, 0x25, 0x44, 0xc6, 0x44, 0xc6, 0x5c, 0x2b, 0x44, 0xc6, 0x5d, 0x69, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x5d, 0x70, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x60, 0x1e, 0x5d, 0x8d, 0x5e, - 0x84, 0x60, 0x7d, 0x44, 0xc6, 0x44, 0xc6, 0x5f, 0x83, 0x44, 0xc6, 0x60, 0xc1, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x60, 0xc8, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, - 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0x44, 0xc6, 0xca, 0x29, 0x1e, 0x50, 0x40, - 0x0d, 0x7e, 0x54, 0x0b, 0x10, 0x9c, 0xb5, 0xa4, 0x2e, 0x54, 0x65, 0x48, 0x89, 0x54, 0x7e, 0x39, - 0x00, 0x7a, 0x19, 0x00, 0x0b, 0x34, 0x80, 0xe9, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, - 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, - 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, - 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, - 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, - 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, - 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, - 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, - 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, - 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, - 0x0b, 0x35, 0x0b, 0x38, 0x00, 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0x0b, 0x38, 0x00, - 0x7a, 0x19, 0x00, 0x7a, 0x19, 0x10, 0x0b, 0x35, 0xda, 0x29, 0x22, 0x1e, 0x50, 0x40, 0x0d, 0x7e, - 0x54, 0x0b, 0x1c, 0x9c, 0xb5, 0xa4, 0x2e, 0x54, 0x66, 0x16, 0x89, 0x54, 0x7e, 0x19, 0x00, 0x7a, - 0x39, 0x00, 0x0b, 0x34, 0x80, 0xe9, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, - 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, - 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, - 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, - 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, - 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, - 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, - 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, - 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, - 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, - 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, - 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, - 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, - 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, - 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, - 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, - 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, - 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, - 0x38, 0x00, 0x0b, 0x35, 0x7e, 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x7e, - 0x19, 0x00, 0x7e, 0x19, 0x10, 0x1b, 0x38, 0x00, 0x0b, 0x35, 0x22, 0x67, 0x96, 0x69, 0x63, 0x69, - 0x7b, 0x6a, 0x49, 0x6a, 0xe4, 0x6b, 0x8e, 0x6b, 0xa9, 0x6c, 0x3b, 0x6b, 0xc4, 0x6c, 0x05, 0x69, - 0x96, 0x69, 0xaa, 0x7c, 0xb3, 0xbe, 0xb0, 0x0b, 0x28, 0x14, 0x75, 0x31, 0x09, 0x12, 0x7c, 0x15, - 0x75, 0x6d, 0x10, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x43, 0xe1, 0xc0, 0xd0, 0xf1, 0x22, 0xc0, 0xa8, - 0xc2, 0xaf, 0x23, 0x6c, 0xaa, 0x2e, 0x54, 0x67, 0x4b, 0x0b, 0x58, 0x50, 0x89, 0x54, 0x01, 0x02, - 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x75, 0x31, 0xb0, 0x12, 0x7c, 0x15, 0x0a, 0x32, 0x09, 0xb3, - 0x67, 0x8e, 0x42, 0x32, 0x19, 0x43, 0x00, 0x36, 0xd0, 0xa8, 0x22, 0x7c, 0xb2, 0x23, 0x0a, 0x3b, - 0x49, 0x33, 0x67, 0xcb, 0x0a, 0x22, 0x09, 0x32, 0x00, 0x36, 0x09, 0xb2, 0x67, 0x8e, 0xa5, 0xbb, - 0x00, 0x05, 0xf4, 0x52, 0x33, 0x80, 0x02, 0x42, 0x33, 0x89, 0x34, 0x67, 0xdb, 0x68, 0x09, 0x68, - 0x37, 0x68, 0x65, 0x68, 0x93, 0x68, 0xc1, 0x68, 0xef, 0x69, 0x1d, 0x12, 0x41, 0xb5, 0xd2, 0x28, - 0xd2, 0x08, 0xc2, 0x40, 0xc2, 0x48, 0xc2, 0x38, 0xc2, 0x30, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xcf, - 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xaf, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xbf, - 0x12, 0x41, 0x16, 0x12, 0x60, 0xcf, 0x02, 0x69, 0x4b, 0x12, 0x41, 0xd4, 0xd2, 0x29, 0xd2, 0x09, - 0xc2, 0x41, 0xc2, 0x49, 0xc2, 0x39, 0xc2, 0x31, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xd0, 0x7e, 0x04, - 0x00, 0x20, 0x7a, 0x07, 0x01, 0xb1, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xc1, 0x12, 0x41, - 0x16, 0x12, 0x61, 0x05, 0x02, 0x69, 0x4b, 0x12, 0x41, 0xf3, 0xd2, 0x2a, 0xd2, 0x0a, 0xc2, 0x42, - 0xc2, 0x4a, 0xc2, 0x3a, 0xc2, 0x32, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xd1, 0x7e, 0x04, 0x00, 0x20, - 0x7a, 0x07, 0x01, 0xb3, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xc3, 0x12, 0x41, 0x16, 0x12, - 0x61, 0x3b, 0x02, 0x69, 0x4b, 0x12, 0x42, 0x12, 0xd2, 0x2b, 0xd2, 0x0b, 0xc2, 0x43, 0xc2, 0x4b, - 0xc2, 0x3b, 0xc2, 0x33, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xd2, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, - 0x01, 0xb5, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xc5, 0x12, 0x41, 0x16, 0x12, 0x61, 0x71, - 0x02, 0x69, 0x4b, 0x12, 0x42, 0x31, 0xd2, 0x2c, 0xd2, 0x0c, 0xc2, 0x44, 0xc2, 0x4c, 0xc2, 0x3c, - 0xc2, 0x34, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xd3, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xb7, - 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xc7, 0x12, 0x41, 0x16, 0x12, 0x61, 0xa7, 0x02, 0x69, - 0x4b, 0x12, 0x42, 0x50, 0xd2, 0x2d, 0xd2, 0x0d, 0xc2, 0x45, 0xc2, 0x4d, 0xc2, 0x3d, 0xc2, 0x35, - 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xd4, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xb9, 0x7e, 0x04, - 0x00, 0x38, 0x7a, 0x07, 0x01, 0xc9, 0x12, 0x41, 0x16, 0x12, 0x61, 0xdd, 0x02, 0x69, 0x4b, 0x12, - 0x42, 0x6f, 0xd2, 0x2e, 0xd2, 0x0e, 0xc2, 0x46, 0xc2, 0x4e, 0xc2, 0x3e, 0xc2, 0x36, 0x6d, 0x00, - 0x7a, 0x03, 0x01, 0xd5, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xbb, 0x7e, 0x04, 0x00, 0x38, - 0x7a, 0x07, 0x01, 0xcb, 0x12, 0x41, 0x16, 0x12, 0x62, 0x13, 0x02, 0x69, 0x4b, 0x12, 0x42, 0x8e, - 0xd2, 0x2f, 0xd2, 0x0f, 0xc2, 0x47, 0xc2, 0x4f, 0xc2, 0x3f, 0xc2, 0x37, 0x6d, 0x00, 0x7a, 0x03, - 0x01, 0xd6, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xbd, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, - 0x01, 0xcd, 0x12, 0x41, 0x16, 0x12, 0x62, 0x49, 0x02, 0x69, 0x4b, 0x7e, 0xa0, 0xd0, 0x7e, 0x60, - 0x0f, 0x12, 0x62, 0xb6, 0x40, 0x0c, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, - 0xc2, 0xd7, 0x22, 0x75, 0x31, 0xb1, 0x12, 0x7c, 0x15, 0x0a, 0x52, 0x23, 0x6d, 0x00, 0x59, 0x05, - 0x00, 0x48, 0x12, 0x41, 0x7e, 0x12, 0x41, 0x9a, 0xd0, 0xa8, 0x22, 0x75, 0x31, 0xb2, 0x12, 0x7c, - 0x15, 0x0a, 0x22, 0x09, 0xb2, 0x67, 0x8e, 0x42, 0x23, 0x7e, 0xb0, 0x9c, 0x19, 0xb2, 0x01, 0xcf, - 0x12, 0x31, 0x85, 0xd0, 0xa8, 0x22, 0x75, 0x31, 0xb7, 0x12, 0x7c, 0x15, 0x0a, 0x22, 0x09, 0xb2, - 0x67, 0x8e, 0x42, 0x24, 0x12, 0x35, 0x3d, 0xd0, 0xa8, 0x22, 0x75, 0x31, 0xb9, 0x12, 0x7c, 0x15, - 0x0a, 0x32, 0x09, 0xb3, 0x67, 0x8e, 0x42, 0x34, 0x19, 0x43, 0x00, 0x3e, 0x12, 0x69, 0xc2, 0xd0, - 0xa8, 0x22, 0x7c, 0xb2, 0x23, 0x0a, 0x0b, 0x7c, 0xb4, 0x20, 0xe0, 0x04, 0x6d, 0x33, 0x80, 0x04, - 0x49, 0x30, 0x01, 0x8f, 0x7e, 0xa0, 0xd8, 0xa5, 0xef, 0xca, 0x0b, 0xca, 0x29, 0x12, 0x62, 0xb6, - 0xda, 0x29, 0xda, 0x0b, 0x40, 0x62, 0x75, 0x31, 0xba, 0x12, 0x7c, 0x15, 0x7c, 0xb4, 0x30, 0xe0, - 0x1e, 0x6d, 0x33, 0x59, 0x30, 0x01, 0x8f, 0x7e, 0x34, 0x09, 0xe3, 0x0a, 0x82, 0x7e, 0x94, 0x04, - 0x00, 0xad, 0x89, 0x2d, 0x39, 0x59, 0x30, 0x01, 0x6f, 0x59, 0x30, 0x01, 0x7f, 0x7c, 0xb4, 0x30, - 0xe1, 0x10, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x09, 0xb0, 0x00, 0x08, 0x44, 0x04, 0x19, 0xb0, - 0x00, 0x08, 0x0a, 0x02, 0x09, 0xb0, 0x67, 0x8e, 0x42, 0x21, 0xf4, 0x52, 0x34, 0x7c, 0xb2, 0x23, - 0x0a, 0x0b, 0xca, 0x19, 0x49, 0x00, 0x30, 0xd5, 0x99, 0x04, 0xda, 0x19, 0xc0, 0xf1, 0x75, 0xf1, - 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0xc2, 0xd7, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x09, - 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x09, 0xb0, 0x00, 0x08, 0x19, 0x30, 0x00, - 0x0c, 0x7c, 0x74, 0x5e, 0x70, 0x01, 0x68, 0x12, 0x44, 0x40, 0xca, 0xb8, 0x09, 0xb0, 0x00, 0x10, - 0x44, 0x02, 0x19, 0xb0, 0x00, 0x10, 0xda, 0xb8, 0x80, 0x02, 0x54, 0xbf, 0x7c, 0x74, 0x5e, 0x70, - 0x08, 0x68, 0x04, 0x44, 0x08, 0x80, 0x02, 0x54, 0xf7, 0x09, 0x30, 0x00, 0x0c, 0xca, 0xb8, 0x74, - 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0xda, 0xb8, 0x19, 0xb0, 0x00, 0x08, 0x19, 0x30, 0x00, 0x0c, 0x0a, - 0x62, 0x09, 0xb6, 0x67, 0x8e, 0x3e, 0x20, 0x0a, 0x62, 0x7c, 0x74, 0x5e, 0x70, 0x02, 0x68, 0x20, - 0x42, 0x27, 0xca, 0xb8, 0x74, 0x61, 0x19, 0xb0, 0x00, 0x08, 0x7e, 0x44, 0x00, 0x10, 0x59, 0x46, - 0x01, 0xbf, 0x09, 0xb0, 0x00, 0x10, 0x44, 0x01, 0x19, 0xb0, 0x00, 0x10, 0xda, 0xb8, 0x80, 0x11, - 0xf4, 0x52, 0x27, 0x74, 0xa1, 0x19, 0xb0, 0x00, 0x08, 0x7e, 0x44, 0x00, 0x38, 0x59, 0x46, 0x01, - 0xbf, 0xd0, 0xa8, 0x22, 0x7c, 0x74, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x0a, 0x62, 0x09, 0xb6, - 0x67, 0x8e, 0xa5, 0xfd, 0xf4, 0xa5, 0xfe, 0xca, 0x28, 0x3e, 0x20, 0x0a, 0x62, 0xa5, 0xee, 0x52, - 0x26, 0x7e, 0x44, 0x00, 0x20, 0x59, 0x46, 0x01, 0xaf, 0xda, 0x28, 0x09, 0x30, 0x00, 0x0c, 0x74, - 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x09, 0xb0, 0x00, 0x08, 0x7c, 0x74, 0x5e, 0x70, 0x01, 0x68, 0x0c, - 0x44, 0x80, 0xca, 0xb8, 0xa5, 0xed, 0x42, 0x2a, 0xda, 0xb8, 0x80, 0x0a, 0x54, 0x7f, 0xca, 0xb8, - 0xa5, 0xee, 0x52, 0x2a, 0xda, 0xb8, 0x7c, 0x74, 0x5e, 0x70, 0x08, 0x68, 0x04, 0x44, 0x02, 0x80, - 0x02, 0x54, 0xfd, 0x19, 0xb0, 0x00, 0x08, 0x19, 0x30, 0x00, 0x0c, 0x7c, 0x74, 0x5e, 0x70, 0x02, - 0x68, 0x10, 0xa5, 0xed, 0x42, 0x28, 0x42, 0x26, 0x7e, 0x44, 0x00, 0x08, 0x59, 0x46, 0x01, 0xaf, - 0x80, 0x04, 0xa5, 0xee, 0x52, 0x28, 0x7c, 0x74, 0x5e, 0x70, 0x04, 0x68, 0x10, 0xa5, 0xed, 0x42, - 0x29, 0x42, 0x26, 0x7e, 0x44, 0x00, 0x08, 0x59, 0x46, 0x01, 0xaf, 0x80, 0x0b, 0xa5, 0xee, 0x52, - 0x29, 0x7c, 0x74, 0x5e, 0x70, 0x02, 0x78, 0x00, 0x12, 0x42, 0xad, 0xd0, 0xa8, 0x22, 0x7e, 0x04, - 0x80, 0x00, 0x4c, 0x02, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x19, 0x40, - 0x00, 0x10, 0x19, 0x30, 0x00, 0x0c, 0xd0, 0xa8, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x09, - 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x19, 0x40, 0x00, 0x18, 0x19, 0x30, 0x00, - 0x0c, 0xd0, 0xa8, 0x22, 0x75, 0x31, 0xb5, 0x12, 0x7c, 0x15, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, - 0x09, 0xb0, 0x00, 0x0c, 0x44, 0x40, 0x19, 0xb0, 0x00, 0x0c, 0xe5, 0x6e, 0xb4, 0x07, 0x23, 0x09, - 0xb0, 0x00, 0x10, 0x4e, 0xb0, 0x02, 0x19, 0xb0, 0x00, 0x10, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, - 0x19, 0xb0, 0x00, 0x0c, 0x09, 0xb0, 0x00, 0x04, 0x54, 0xf7, 0x19, 0xb0, 0x00, 0x04, 0x19, 0x30, - 0x00, 0x0c, 0xd0, 0xa8, 0x22, 0x75, 0x31, 0xb6, 0x12, 0x7c, 0x15, 0x7e, 0x04, 0x80, 0x00, 0x4c, - 0x02, 0xe5, 0x6e, 0xb4, 0x07, 0x18, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, - 0x09, 0xb0, 0x00, 0x04, 0x44, 0x08, 0x19, 0xb0, 0x00, 0x04, 0x19, 0x30, 0x00, 0x0c, 0x09, 0xb0, - 0x00, 0x0c, 0x54, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0xd0, 0xa8, 0x22, 0x75, 0x31, 0xb4, 0x12, 0x7c, - 0x15, 0x7a, 0x21, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x41, 0x31, 0x12, 0x7c, 0x15, 0x0a, 0x32, 0x09, - 0xb3, 0x67, 0x8e, 0x42, 0x35, 0x12, 0x6c, 0x5b, 0xd0, 0xa8, 0x22, 0x7e, 0xb0, 0x01, 0x7e, 0xa0, - 0xc8, 0x7c, 0x64, 0x12, 0x62, 0xb6, 0x40, 0x13, 0x0a, 0x32, 0x09, 0xb3, 0x67, 0x8e, 0xf4, 0x52, - 0x35, 0xc0, 0xf1, 0x75, 0xf1, 0x01, 0x12, 0x6f, 0xd9, 0xd0, 0xf1, 0x22, 0x6c, 0x8c, 0x6c, 0xd3, - 0x6d, 0x1a, 0x6d, 0x61, 0x6d, 0xa8, 0x6d, 0xef, 0x6e, 0x36, 0x6e, 0x7d, 0x75, 0x31, 0x55, 0x12, - 0x7c, 0x15, 0x75, 0x31, 0x00, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x71, - 0x31, 0x12, 0x7c, 0x15, 0x7e, 0x17, 0x01, 0x7f, 0x7e, 0x27, 0x01, 0x8f, 0x2d, 0x23, 0x7e, 0x09, - 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x0d, 0xe2, 0x38, 0x0f, 0x1b, 0x34, - 0x78, 0xec, 0x7a, 0x17, 0x01, 0x7f, 0x7a, 0x27, 0x01, 0x8f, 0x02, 0x46, 0x0f, 0x7e, 0x14, 0x09, - 0xe3, 0x80, 0xeb, 0x75, 0x31, 0x55, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x01, 0x12, 0x7c, 0x15, 0x7a, - 0x61, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0x7e, 0x17, 0x01, 0x81, 0x7e, - 0x27, 0x01, 0x91, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, - 0x14, 0x11, 0xe2, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x81, 0x7a, 0x27, 0x01, - 0x91, 0x02, 0x49, 0x67, 0x7e, 0x14, 0x0d, 0xe3, 0x80, 0xeb, 0x75, 0x31, 0x55, 0x12, 0x7c, 0x15, - 0x75, 0x31, 0x02, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, - 0x7c, 0x15, 0x7e, 0x17, 0x01, 0x83, 0x7e, 0x27, 0x01, 0x93, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, - 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x15, 0xe2, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, - 0x7a, 0x17, 0x01, 0x83, 0x7a, 0x27, 0x01, 0x93, 0x02, 0x4c, 0xbf, 0x7e, 0x14, 0x11, 0xe3, 0x80, - 0xeb, 0x75, 0x31, 0x55, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x03, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, - 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0x7e, 0x17, 0x01, 0x85, 0x7e, 0x27, 0x01, - 0x95, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x19, - 0xe2, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x85, 0x7a, 0x27, 0x01, 0x95, 0x02, - 0x50, 0x17, 0x7e, 0x14, 0x15, 0xe3, 0x80, 0xeb, 0x75, 0x31, 0x55, 0x12, 0x7c, 0x15, 0x75, 0x31, - 0x04, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, - 0x7e, 0x17, 0x01, 0x87, 0x7e, 0x27, 0x01, 0x97, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, - 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x1d, 0xe2, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, - 0x01, 0x87, 0x7a, 0x27, 0x01, 0x97, 0x02, 0x53, 0x6f, 0x7e, 0x14, 0x19, 0xe3, 0x80, 0xeb, 0x75, - 0x31, 0x55, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x05, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, - 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0x7e, 0x17, 0x01, 0x89, 0x7e, 0x27, 0x01, 0x99, 0x2d, - 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x21, 0xe2, 0x38, - 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x89, 0x7a, 0x27, 0x01, 0x99, 0x02, 0x56, 0xc7, - 0x7e, 0x14, 0x1d, 0xe3, 0x80, 0xeb, 0x75, 0x31, 0x55, 0x12, 0x7c, 0x15, 0x75, 0x31, 0x06, 0x12, - 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0x7e, 0x17, - 0x01, 0x8b, 0x7e, 0x27, 0x01, 0x9b, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, - 0x0b, 0x14, 0xbe, 0x14, 0x25, 0xe2, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x8b, - 0x7a, 0x27, 0x01, 0x9b, 0x02, 0x5a, 0x1f, 0x7e, 0x14, 0x21, 0xe3, 0x80, 0xeb, 0x75, 0x31, 0x55, - 0x12, 0x7c, 0x15, 0x75, 0x31, 0x07, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, 0x15, 0x7a, - 0x71, 0x31, 0x12, 0x7c, 0x15, 0x7e, 0x17, 0x01, 0x8d, 0x7e, 0x27, 0x01, 0x9d, 0x2d, 0x23, 0x7e, - 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x29, 0xe2, 0x38, 0x0f, 0x1b, - 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x8d, 0x7a, 0x27, 0x01, 0x9d, 0x02, 0x5d, 0x77, 0x7e, 0x14, - 0x25, 0xe3, 0x80, 0xeb, 0xca, 0xb8, 0xc0, 0xf1, 0x75, 0x31, 0x02, 0x12, 0x7c, 0x15, 0xe5, 0xc0, - 0x54, 0x03, 0x68, 0x05, 0x12, 0x75, 0xcd, 0x80, 0xf5, 0x30, 0xc2, 0x08, 0x75, 0xf1, 0x01, 0x12, - 0x6f, 0xd9, 0x80, 0x14, 0x30, 0xc3, 0x08, 0x75, 0xf1, 0x01, 0x12, 0x6e, 0xfd, 0x80, 0x09, 0x30, - 0xc4, 0x06, 0x75, 0xf1, 0x02, 0x12, 0x70, 0xe9, 0xd0, 0xf1, 0xda, 0xb8, 0x32, 0x75, 0x31, 0x10, - 0x12, 0x7c, 0x15, 0xca, 0x0b, 0xca, 0x39, 0xca, 0x59, 0xc2, 0xc3, 0xa9, 0x21, 0xe2, 0x5c, 0xe5, - 0xe5, 0x54, 0xc0, 0x68, 0x4f, 0xe5, 0xe6, 0x6c, 0xaa, 0x7e, 0x37, 0x01, 0xdb, 0x2d, 0x35, 0xbe, - 0x34, 0x04, 0x00, 0x38, 0x4a, 0x7a, 0x37, 0x01, 0xdb, 0x7e, 0x37, 0x01, 0xd9, 0x7d, 0x43, 0x2d, - 0x45, 0xbe, 0x44, 0x09, 0xe2, 0x38, 0x40, 0x7a, 0x47, 0x01, 0xd9, 0x75, 0x31, 0x11, 0x12, 0x7c, - 0x15, 0x7a, 0xb1, 0x31, 0x12, 0x7c, 0x15, 0x12, 0x71, 0xb8, 0xa9, 0x21, 0xe5, 0x1f, 0xa9, 0xd4, - 0xe4, 0xa9, 0x24, 0xe4, 0xfc, 0xc2, 0xc3, 0xa9, 0x21, 0xe2, 0x3b, 0xe5, 0xe5, 0x54, 0xc0, 0x78, - 0xb4, 0x12, 0x74, 0x5a, 0xda, 0x59, 0xda, 0x39, 0xda, 0x0b, 0x22, 0x80, 0x29, 0x80, 0x58, 0x75, - 0x31, 0x16, 0x12, 0x7c, 0x15, 0x80, 0xed, 0x75, 0x31, 0x12, 0x12, 0x7c, 0x15, 0x7a, 0xb1, 0x31, - 0x12, 0x7c, 0x15, 0x9e, 0x44, 0x09, 0xe3, 0x9d, 0x54, 0x12, 0x71, 0xb8, 0x7e, 0x34, 0x05, 0xe3, - 0x7d, 0x54, 0x2d, 0x43, 0x80, 0xa1, 0xe5, 0xe5, 0x54, 0x03, 0x78, 0x12, 0x75, 0x31, 0x13, 0x12, - 0x7c, 0x15, 0x7e, 0x0f, 0x29, 0xff, 0x0b, 0x0c, 0x7a, 0x0f, 0x29, 0xff, 0x80, 0xa7, 0x75, 0x31, - 0x14, 0x12, 0x7c, 0x15, 0x7e, 0x0f, 0x2a, 0x03, 0x0b, 0x0c, 0x7a, 0x0f, 0x2a, 0x03, 0xa9, 0xd7, - 0xe4, 0xa9, 0x27, 0xe4, 0xfc, 0x80, 0x9d, 0x75, 0x31, 0x15, 0x12, 0x7c, 0x15, 0x7e, 0x0f, 0x2a, - 0x07, 0x0b, 0x0c, 0x7a, 0x0f, 0x2a, 0x07, 0x80, 0xe5, 0x75, 0x31, 0x18, 0x12, 0x7c, 0x15, 0xca, - 0x09, 0xca, 0x39, 0xca, 0x2b, 0xc2, 0xc2, 0xa9, 0x21, 0xf2, 0x52, 0xe5, 0xf5, 0x33, 0x82, 0xe7, - 0x40, 0x44, 0x7e, 0x37, 0x01, 0xe1, 0x7e, 0x54, 0x00, 0x40, 0x9d, 0x35, 0x40, 0x43, 0x7a, 0x37, - 0x01, 0xe1, 0x7e, 0x37, 0x01, 0xdd, 0x7d, 0x43, 0x2d, 0x45, 0xbe, 0x44, 0x05, 0xe2, 0x38, 0x52, - 0x7a, 0x47, 0x01, 0xdd, 0x7d, 0x45, 0x12, 0x73, 0x16, 0xa9, 0x20, 0xf5, 0x22, 0x75, 0x31, 0x19, - 0x12, 0x7c, 0x15, 0x7a, 0x91, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x81, 0xf7, 0x7a, 0x91, 0xf6, 0xe5, - 0xf5, 0x33, 0x82, 0xe7, 0x50, 0xbc, 0xda, 0x2b, 0xda, 0x39, 0xda, 0x09, 0x22, 0x80, 0x41, 0x80, - 0x64, 0x2d, 0x53, 0x6d, 0x33, 0x70, 0xb7, 0x7e, 0x04, 0x01, 0xe3, 0x7a, 0x07, 0x01, 0xdf, 0x7a, - 0x07, 0x01, 0xdd, 0xa9, 0x32, 0xf2, 0xdf, 0x85, 0x30, 0x31, 0x12, 0x7c, 0x15, 0x75, 0xf6, 0x00, - 0x80, 0xd4, 0xca, 0x59, 0x9e, 0x44, 0x05, 0xe3, 0x9d, 0x54, 0x12, 0x73, 0x16, 0x7e, 0x34, 0x01, - 0xe3, 0x7d, 0x54, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xdd, 0x12, 0x73, 0x16, 0xda, 0x49, 0x80, 0x99, - 0xe5, 0xf5, 0x54, 0x03, 0x78, 0x1f, 0x7e, 0x0f, 0x29, 0xef, 0x0b, 0x0c, 0x7a, 0x0f, 0x29, 0xef, - 0x80, 0x9d, 0x7e, 0x0f, 0x29, 0xf7, 0x0b, 0x0c, 0x7a, 0x0f, 0x29, 0xf7, 0xa9, 0xd7, 0xf4, 0xa9, - 0x27, 0xf4, 0xfc, 0x80, 0x8a, 0x7e, 0x0f, 0x29, 0xf3, 0x0b, 0x0c, 0x7a, 0x0f, 0x29, 0xf3, 0x80, - 0xeb, 0xe5, 0xf5, 0x54, 0x03, 0x78, 0x1f, 0x7e, 0x2f, 0x2a, 0x0f, 0x0b, 0x2c, 0x7a, 0x2f, 0x2a, - 0x0f, 0x80, 0x34, 0x7e, 0x2f, 0x2a, 0x17, 0x0b, 0x2c, 0x7a, 0x2f, 0x2a, 0x17, 0xa9, 0xd7, 0xf4, - 0xa9, 0x27, 0xf4, 0xfc, 0x80, 0x21, 0x7e, 0x2f, 0x2a, 0x13, 0x0b, 0x2c, 0x7a, 0x2f, 0x2a, 0x13, - 0x80, 0xeb, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0x75, 0x31, 0x28, 0x12, 0x7c, 0x15, 0xca, - 0x0b, 0xca, 0x1b, 0xca, 0x2b, 0xc2, 0xc4, 0xa9, 0x21, 0xf2, 0xb6, 0xe5, 0xf5, 0x33, 0x72, 0xe7, - 0x40, 0xe0, 0x7e, 0x0d, 0x46, 0x7e, 0x1d, 0x4a, 0x7e, 0x2d, 0x4e, 0x7e, 0x3d, 0x52, 0x7e, 0x85, - 0x56, 0x7d, 0x90, 0x4d, 0x91, 0x4d, 0x92, 0x4d, 0x93, 0x4d, 0x94, 0x4d, 0x95, 0x4d, 0x96, 0x4d, - 0x97, 0x4d, 0x98, 0x68, 0x72, 0x7a, 0x11, 0xf3, 0x7a, 0x01, 0xf3, 0x7a, 0x31, 0xf3, 0x7a, 0x21, - 0xf3, 0x7a, 0x51, 0xf3, 0x7a, 0x41, 0xf3, 0x7a, 0x71, 0xf3, 0x7a, 0x61, 0xf3, 0x7a, 0x91, 0xf3, - 0x7a, 0x81, 0xf3, 0x30, 0x7b, 0x1a, 0x7a, 0xb1, 0xf3, 0x7a, 0xa1, 0xf3, 0x7a, 0xd1, 0xf3, 0x7a, - 0xc1, 0xf3, 0x7a, 0xf1, 0xf3, 0x7a, 0xe1, 0xf3, 0x7d, 0x78, 0x7a, 0xf1, 0xf3, 0x7a, 0xe1, 0xf3, - 0xa9, 0x30, 0xf5, 0x03, 0x02, 0x70, 0xd6, 0x75, 0x31, 0x29, 0x12, 0x7c, 0x15, 0x20, 0x7b, 0x0b, - 0x75, 0x31, 0x0a, 0x12, 0x7c, 0x15, 0x75, 0xf6, 0x0a, 0x80, 0x09, 0x75, 0x31, 0x12, 0x12, 0x7c, - 0x15, 0x75, 0xf6, 0x12, 0x6d, 0x00, 0x7d, 0x10, 0x7a, 0x0d, 0x46, 0x7a, 0x0d, 0x4a, 0x7a, 0x0d, - 0x4e, 0x7a, 0x0d, 0x52, 0x7a, 0x05, 0x56, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0x1e, 0xb0, - 0x40, 0x0c, 0x7e, 0xa0, 0x0a, 0xa4, 0x7e, 0x04, 0x72, 0xfb, 0x9d, 0x05, 0x89, 0x04, 0x7e, 0xa1, - 0xe3, 0x7a, 0x39, 0xa0, 0x0b, 0x34, 0x80, 0xea, 0xb4, 0x40, 0xe3, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, - 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, - 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, - 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, - 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, - 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, - 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, - 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, - 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, - 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, - 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, - 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, - 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, - 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, - 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, - 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, - 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, - 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, - 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, - 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, - 0x35, 0x7e, 0xa1, 0xe3, 0xe5, 0xe3, 0x1b, 0x38, 0x50, 0x0b, 0x35, 0x22, 0x1e, 0xb0, 0x40, 0x0c, - 0x7e, 0xa0, 0x0a, 0xa4, 0x7e, 0x04, 0x74, 0x59, 0x9d, 0x05, 0x89, 0x04, 0x7e, 0x39, 0xa0, 0x7a, - 0xa1, 0xf3, 0x0b, 0x34, 0x80, 0xea, 0xb4, 0x40, 0xe3, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, - 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, - 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, - 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, - 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, - 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, - 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, - 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, - 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, - 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, - 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, - 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, - 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, - 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, - 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, - 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, - 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, - 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, - 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, - 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x0b, - 0x38, 0x50, 0x7a, 0xa1, 0xf3, 0xf5, 0xf3, 0x0b, 0x35, 0x22, 0xc2, 0xaf, 0x7e, 0x37, 0x01, 0xdb, - 0x4d, 0x33, 0x68, 0x3b, 0x7e, 0x07, 0x01, 0xd7, 0x7e, 0x54, 0x09, 0xe3, 0x9d, 0x50, 0xbd, 0x35, - 0x40, 0x02, 0x7d, 0x35, 0xca, 0x39, 0x7e, 0x65, 0x61, 0x99, 0x64, 0xda, 0x39, 0x7e, 0x07, 0x01, - 0xdb, 0x9d, 0x03, 0x7a, 0x07, 0x01, 0xdb, 0x2e, 0x37, 0x01, 0xd7, 0x7a, 0x37, 0x01, 0xd7, 0xbe, - 0x34, 0x09, 0xe2, 0x28, 0xc7, 0x7e, 0x34, 0x05, 0xe3, 0x7a, 0x37, 0x01, 0xd7, 0x80, 0xbd, 0xd2, - 0xaf, 0x22, 0x75, 0x31, 0x53, 0x12, 0x7c, 0x15, 0x7e, 0x15, 0x63, 0x80, 0x11, 0x75, 0x31, 0x51, - 0x12, 0x7c, 0x15, 0x0b, 0x08, 0x10, 0x0b, 0x05, 0x9e, 0x34, 0x00, 0x02, 0x28, 0x4d, 0x7c, 0xb2, - 0x20, 0xe7, 0x27, 0x54, 0x07, 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x6c, 0x7c, 0x7c, 0xb2, 0x54, 0x78, - 0x03, 0x03, 0x03, 0x7c, 0x2b, 0x9d, 0x13, 0x40, 0x1a, 0x68, 0x12, 0x7a, 0x15, 0x63, 0x7a, 0x25, - 0x65, 0x7e, 0x64, 0x75, 0x37, 0x7a, 0x65, 0x61, 0x89, 0x24, 0x02, 0x75, 0x45, 0x7e, 0x64, 0x74, - 0xad, 0x80, 0xf2, 0x2d, 0x13, 0x9d, 0x31, 0xca, 0x39, 0x7d, 0x31, 0x2d, 0x10, 0xca, 0x19, 0xca, - 0x29, 0x99, 0x24, 0xda, 0x29, 0xda, 0x09, 0xda, 0x39, 0x80, 0xa2, 0x7a, 0x15, 0x63, 0x7e, 0x64, - 0x75, 0x23, 0x4d, 0x33, 0x78, 0x09, 0x7c, 0xb2, 0x20, 0xe7, 0x2a, 0x7e, 0x64, 0x74, 0xa2, 0x7a, - 0x65, 0x61, 0x22, 0x75, 0x31, 0x52, 0x12, 0x7c, 0x15, 0x7e, 0x21, 0x63, 0x7e, 0x09, 0x30, 0x0b, - 0x04, 0x1b, 0x34, 0x78, 0x89, 0x80, 0xd4, 0x75, 0x31, 0x54, 0x12, 0x7c, 0x15, 0x7e, 0x15, 0x63, - 0x7e, 0x25, 0x65, 0x80, 0x90, 0x5e, 0x20, 0x07, 0x54, 0x78, 0x7e, 0x44, 0x75, 0xc1, 0x30, 0xe6, - 0x16, 0x4d, 0x33, 0x68, 0x26, 0x1b, 0x34, 0x7e, 0x09, 0x40, 0x0b, 0x04, 0x7e, 0x44, 0x67, 0x63, - 0x20, 0xe3, 0x04, 0x7e, 0x44, 0x75, 0xc9, 0xca, 0x09, 0xca, 0x39, 0x99, 0x44, 0xda, 0x39, 0xda, - 0x09, 0x7e, 0x64, 0x74, 0xad, 0x4d, 0x33, 0x68, 0xa6, 0x89, 0x64, 0x7a, 0x15, 0x63, 0xf5, 0x65, - 0x7e, 0x64, 0x75, 0x86, 0x80, 0x99, 0x7e, 0x15, 0x63, 0xe5, 0x65, 0x80, 0xc4, 0xc0, 0xd0, 0xc0, - 0xd1, 0xc0, 0xe0, 0xca, 0x19, 0xa9, 0x20, 0xdf, 0x12, 0xa9, 0x21, 0xdf, 0x1b, 0x75, 0x31, 0x01, - 0x12, 0x7c, 0x15, 0x53, 0xdf, 0xf7, 0x12, 0x40, 0xdc, 0x80, 0x0d, 0x75, 0x31, 0xfe, 0x12, 0x7c, - 0x15, 0x7e, 0x14, 0x00, 0x53, 0x02, 0x40, 0x51, 0xda, 0x19, 0xd0, 0xe0, 0xd0, 0xd1, 0xd0, 0xd0, - 0x32, 0x03, 0xa5, 0xcb, 0x19, 0xb1, 0x80, 0x00, 0x22, 0x22, 0x02, 0x76, 0x42, 0xca, 0x0b, 0xca, - 0x1b, 0xca, 0x2b, 0xca, 0x3b, 0xca, 0x4b, 0xca, 0x5b, 0xca, 0x6b, 0xca, 0x7b, 0xca, 0xeb, 0xc0, - 0xf1, 0x7e, 0xb3, 0x2a, 0x33, 0xb4, 0x00, 0x02, 0x80, 0x19, 0xb4, 0x01, 0x16, 0x30, 0xc0, 0x08, - 0x75, 0xf1, 0x00, 0x12, 0x76, 0x2c, 0x80, 0x1f, 0x30, 0xc1, 0x1c, 0x75, 0xf1, 0x00, 0x12, 0x76, - 0xbd, 0x80, 0x14, 0x30, 0xc1, 0x08, 0x75, 0xf1, 0x00, 0x12, 0x76, 0xbd, 0x80, 0x09, 0x30, 0xc0, - 0x06, 0x75, 0xf1, 0x00, 0x12, 0x76, 0x2c, 0xd0, 0xf1, 0xda, 0xeb, 0xda, 0x7b, 0xda, 0x6b, 0xda, - 0x5b, 0xda, 0x4b, 0xda, 0x3b, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0xc2, 0xc0, 0x7e, 0xb3, - 0x2a, 0x33, 0xb4, 0x02, 0x07, 0x12, 0x76, 0x4e, 0x02, 0x76, 0x42, 0x22, 0xb4, 0x01, 0xfc, 0x02, - 0x76, 0x88, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x2a, 0x33, 0x7a, 0x03, 0x2a, 0x34, 0x22, 0x7e, 0xb3, - 0x2a, 0x2b, 0x54, 0x60, 0x60, 0x05, 0xb4, 0x40, 0x15, 0x80, 0x13, 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, - 0x05, 0x0c, 0x75, 0x31, 0x71, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x2e, 0xf5, 0x8f, 0x22, 0x75, - 0xf6, 0x00, 0x22, 0xbe, 0x57, 0x2a, 0x31, 0x28, 0x04, 0x7e, 0x57, 0x2a, 0x31, 0x7a, 0x0f, 0x2a, - 0x36, 0x7a, 0x57, 0x2a, 0x3a, 0x02, 0x76, 0x88, 0x7e, 0xef, 0x2a, 0x36, 0x7e, 0xf7, 0x2a, 0x3a, - 0x7e, 0x07, 0x2a, 0x3a, 0x4d, 0x00, 0x68, 0x21, 0x7e, 0x00, 0x00, 0x7e, 0xeb, 0xb0, 0xf5, 0xf3, - 0xa3, 0xa5, 0x08, 0x1b, 0xf4, 0x68, 0x04, 0xa5, 0xb8, 0x08, 0xf0, 0x7a, 0xef, 0x2a, 0x36, 0x7a, - 0xf7, 0x2a, 0x3a, 0x75, 0x31, 0x06, 0x12, 0x7c, 0x15, 0x7a, 0x01, 0xf6, 0x22, 0xc2, 0xc1, 0x75, - 0x31, 0x03, 0x12, 0x7c, 0x15, 0xa9, 0x36, 0xe2, 0x16, 0xe5, 0xf5, 0x54, 0xc0, 0x68, 0x07, 0xa9, - 0xd7, 0xf4, 0xa9, 0x27, 0xf4, 0xfc, 0x53, 0xe1, 0x3f, 0x43, 0xf2, 0x88, 0x02, 0x77, 0x29, 0x7e, - 0xb3, 0x2a, 0x34, 0xb4, 0x02, 0x04, 0xa9, 0xd4, 0xe4, 0x22, 0xb4, 0x01, 0x39, 0x7e, 0x21, 0xe6, - 0x7c, 0x32, 0x7e, 0x13, 0x2a, 0x35, 0x2c, 0x21, 0x7a, 0x23, 0x2a, 0x35, 0x7e, 0x00, 0x00, 0x2e, - 0x04, 0x2a, 0x3c, 0xe5, 0xe3, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0xa5, 0xdb, 0xf6, 0xa9, 0xd4, 0xe4, - 0x75, 0x31, 0x70, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x35, 0x7e, 0xa3, 0x2a, 0x32, 0xbc, 0xab, - 0x78, 0x03, 0x12, 0x77, 0xc0, 0x22, 0x02, 0x7b, 0x29, 0xe5, 0xe6, 0xb4, 0x08, 0x65, 0xa9, 0xc4, - 0xe2, 0x7e, 0x01, 0xe3, 0x7e, 0x11, 0xe3, 0x7e, 0x31, 0xe3, 0x7e, 0x21, 0xe3, 0x7e, 0x51, 0xe3, - 0x7e, 0x41, 0xe3, 0x7e, 0x71, 0xe3, 0x7e, 0x61, 0xe3, 0x7a, 0x0f, 0x2a, 0x2b, 0x7a, 0x1f, 0x2a, - 0x2f, 0x75, 0x31, 0x04, 0x12, 0x7c, 0x15, 0x7a, 0x01, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x11, 0x31, - 0x12, 0x7c, 0x15, 0x7a, 0x21, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x31, 0x31, 0x12, 0x7c, 0x15, 0x7a, - 0x41, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x51, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x61, 0x31, 0x12, 0x7c, - 0x15, 0x7a, 0x71, 0x31, 0x12, 0x7c, 0x15, 0xa9, 0xd4, 0xe4, 0xa9, 0xd7, 0xf4, 0xa9, 0xc6, 0xe2, - 0x12, 0x77, 0x94, 0x22, 0x6d, 0x00, 0x7e, 0x14, 0x01, 0x02, 0x7a, 0x07, 0x2a, 0x3a, 0x7a, 0x03, - 0x2a, 0x35, 0x7e, 0xb3, 0x2a, 0x2b, 0x20, 0xe7, 0x0f, 0x7a, 0x23, 0x2a, 0x34, 0x7a, 0x33, 0x2a, - 0x33, 0xbe, 0x07, 0x2a, 0x31, 0x68, 0x09, 0x22, 0x7a, 0x33, 0x2a, 0x34, 0x7a, 0x23, 0x2a, 0x33, - 0x7e, 0xb3, 0x2a, 0x2b, 0x54, 0xe3, 0x23, 0x23, 0x30, 0xe0, 0x02, 0xd2, 0xe5, 0x30, 0xe7, 0x02, - 0xd2, 0xe4, 0x30, 0xe5, 0x06, 0x30, 0xe4, 0x03, 0x02, 0x7b, 0x29, 0x54, 0x3e, 0xf5, 0xf0, 0x03, - 0x54, 0x1f, 0xc3, 0x25, 0xf0, 0x90, 0x77, 0xec, 0x75, 0x84, 0xff, 0x73, 0x02, 0x79, 0x40, 0x02, - 0x78, 0x34, 0x02, 0x79, 0xdd, 0x02, 0x79, 0xf8, 0x02, 0x78, 0xd9, 0x02, 0x78, 0x9a, 0x02, 0x7a, - 0x11, 0x02, 0x7a, 0x11, 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x14, - 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x14, 0x02, 0x7a, 0x1a, 0x02, - 0x7a, 0xce, 0x02, 0x7a, 0x17, 0x02, 0x7a, 0x17, 0x02, 0x7a, 0x17, 0x02, 0x7a, 0x17, 0x02, 0x7a, - 0x17, 0x02, 0x7a, 0x17, 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, 0x06, 0x2a, 0x7e, 0xb3, 0x2a, 0x2d, 0x60, - 0x56, 0x7c, 0x0b, 0x7e, 0x13, 0x2a, 0x2e, 0x7e, 0x17, 0x2a, 0x2f, 0x75, 0x31, 0x72, 0x12, 0x7c, - 0x15, 0x7a, 0x01, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x11, 0x31, 0x12, 0x7c, 0x15, 0x12, 0x7b, 0x33, - 0x40, 0x35, 0x02, 0x76, 0x73, 0xb4, 0x08, 0x10, 0x75, 0x31, 0x74, 0x12, 0x7c, 0x15, 0x7e, 0xb3, - 0x3f, 0xf1, 0xf5, 0xf3, 0x75, 0xf6, 0x01, 0x22, 0xb4, 0x00, 0x1c, 0x75, 0x31, 0x75, 0x12, 0x7c, - 0x15, 0x7e, 0xb3, 0x3f, 0xf2, 0x30, 0xe0, 0x05, 0x75, 0xf3, 0x02, 0x80, 0x03, 0x75, 0xf3, 0x00, - 0x75, 0xf3, 0x00, 0x75, 0xf6, 0x02, 0x22, 0x02, 0x7b, 0x29, 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, 0x00, - 0x35, 0x75, 0x31, 0x76, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x30, 0x54, 0x0f, 0xf5, 0xf1, 0x7e, - 0xb3, 0x2a, 0x30, 0x20, 0xe7, 0x09, 0xe5, 0xe1, 0x30, 0xe7, 0x0d, 0x74, 0x01, 0x80, 0x0b, 0xe5, - 0xe1, 0x30, 0xe6, 0x04, 0x74, 0x01, 0x80, 0x02, 0x74, 0x00, 0x53, 0xf1, 0x80, 0xf5, 0xf3, 0x75, - 0xf3, 0x00, 0x75, 0xf6, 0x02, 0x22, 0x02, 0x7b, 0x29, 0xc0, 0xf1, 0x7e, 0xb3, 0x2a, 0x30, 0x54, - 0x0f, 0x42, 0xf1, 0x7e, 0xb3, 0x2a, 0x2e, 0xb4, 0x00, 0x45, 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, 0x01, - 0x24, 0x75, 0x31, 0x77, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x30, 0x54, 0x0f, 0x78, 0x05, 0x53, - 0xe1, 0x3f, 0x80, 0x37, 0x7e, 0xb3, 0x2a, 0x30, 0x20, 0xe7, 0x05, 0x53, 0xe1, 0x7f, 0x80, 0x2b, - 0x53, 0xe1, 0xbf, 0x80, 0x26, 0xb4, 0x03, 0x17, 0x75, 0x31, 0x78, 0x12, 0x7c, 0x15, 0x7e, 0xb3, - 0x2a, 0x30, 0x20, 0xe7, 0x05, 0x43, 0xe1, 0x80, 0x80, 0x11, 0x43, 0xe1, 0x40, 0x80, 0x0c, 0x43, - 0xe1, 0xc0, 0xd0, 0xf1, 0x75, 0x31, 0x07, 0x12, 0x7c, 0x15, 0x22, 0xd0, 0xf1, 0x02, 0x76, 0x6f, - 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, 0x09, 0x23, 0x75, 0x31, 0x79, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, - 0x2e, 0xbe, 0xb3, 0x3f, 0xf1, 0x68, 0x11, 0xca, 0xb8, 0xc0, 0xf1, 0x12, 0x43, 0xd4, 0xd0, 0xf1, - 0xda, 0xb8, 0x50, 0x76, 0x7a, 0xb3, 0x3f, 0xf1, 0x80, 0x6d, 0xb4, 0x05, 0x08, 0x75, 0x31, 0x7a, - 0x12, 0x7c, 0x15, 0x80, 0x62, 0xb4, 0x03, 0x19, 0x75, 0x31, 0x7b, 0x12, 0x7c, 0x15, 0x7e, 0xb3, - 0x2a, 0x2e, 0xb4, 0x01, 0x55, 0x7e, 0xb3, 0x3f, 0xf2, 0x44, 0x01, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, - 0x46, 0xb4, 0x01, 0x19, 0x75, 0x31, 0x7c, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x2e, 0xb4, 0x01, - 0x39, 0x7e, 0xb3, 0x3f, 0xf2, 0x54, 0xfe, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, 0x2a, 0xb4, 0x07, 0x2a, - 0x7e, 0xb3, 0x2a, 0x2d, 0x60, 0x24, 0x7c, 0x0b, 0x7e, 0x13, 0x2a, 0x2e, 0x7e, 0x17, 0x2a, 0x2f, - 0x75, 0x31, 0x73, 0x12, 0x7c, 0x15, 0x7a, 0x01, 0x31, 0x12, 0x7c, 0x15, 0x7a, 0x11, 0x31, 0x12, - 0x7c, 0x15, 0x12, 0x7b, 0x5f, 0x40, 0x03, 0x02, 0x76, 0x6f, 0x02, 0x7b, 0x29, 0x7e, 0xb3, 0x2a, - 0x2c, 0xb4, 0x0b, 0xf6, 0x75, 0x31, 0x7d, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x2e, 0x7e, 0xa3, - 0x2a, 0x30, 0x4c, 0xab, 0x78, 0xe4, 0x80, 0xdf, 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, 0x0a, 0xdb, 0x75, - 0x31, 0x7e, 0x12, 0x7c, 0x15, 0x7e, 0xb3, 0x2a, 0x2e, 0x70, 0xcf, 0xf5, 0xf3, 0x75, 0xf6, 0x01, - 0x22, 0x02, 0x7b, 0x29, 0x02, 0x7b, 0x29, 0x02, 0x7b, 0x29, 0x7e, 0xb3, 0x2a, 0x2c, 0xb4, 0x04, - 0x20, 0x75, 0x31, 0xc3, 0x12, 0x7c, 0x15, 0x7e, 0x04, 0x00, 0x01, 0x7e, 0x17, 0x2a, 0x2d, 0x7e, - 0x18, 0x2a, 0x3c, 0x7a, 0x1c, 0x00, 0x00, 0x7e, 0x47, 0x2a, 0x31, 0x12, 0x7c, 0x21, 0x02, 0x7a, - 0xc8, 0xb4, 0x06, 0x3a, 0x75, 0x31, 0xc1, 0x12, 0x7c, 0x15, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, - 0x00, 0xfe, 0x7d, 0xca, 0x7e, 0xd7, 0x2a, 0x2d, 0x7e, 0x78, 0x2a, 0x3c, 0x7a, 0x7c, 0x00, 0x00, - 0x7e, 0x77, 0x2a, 0x31, 0x75, 0x31, 0xc1, 0x12, 0x7c, 0x15, 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, - 0xa9, 0xd5, 0x87, 0x12, 0x7c, 0x5a, 0xd0, 0x87, 0xd0, 0xa8, 0x40, 0x4f, 0x80, 0x4a, 0xb4, 0x00, - 0x1c, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x12, 0x76, 0x6f, 0xe4, 0x8d, 0xef, 0x8d, 0xef, 0x8d, 0xef, - 0xd5, 0xe0, 0xf7, 0xc0, 0xd1, 0xca, 0x02, 0xff, 0xca, 0x06, 0x00, 0x00, 0x32, 0xb4, 0x09, 0x12, - 0x7e, 0x57, 0x2a, 0x2d, 0x4d, 0x55, 0x68, 0x05, 0xa9, 0xd2, 0xb1, 0x80, 0x03, 0xa9, 0xc2, 0xb1, - 0x80, 0x16, 0xb4, 0x07, 0x16, 0xc2, 0xaf, 0x7e, 0x07, 0x2a, 0x2f, 0x7e, 0x17, 0x2a, 0x2d, 0xc0, - 0xd1, 0xca, 0x18, 0xca, 0x38, 0xca, 0x28, 0x32, 0x02, 0x76, 0x6f, 0x02, 0x7b, 0x29, 0x7e, 0xb3, - 0x2a, 0x2c, 0xb4, 0x03, 0x15, 0x75, 0x31, 0xc2, 0x12, 0x7c, 0x15, 0x7e, 0x04, 0x00, 0x01, 0x7e, - 0x17, 0x2a, 0x2d, 0x7e, 0x57, 0x2a, 0x31, 0x02, 0x76, 0x73, 0xb4, 0x05, 0x39, 0x75, 0x31, 0xc0, - 0x12, 0x7c, 0x15, 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x7e, 0x08, 0x2a, 0x3c, - 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x24, 0x00, 0xfe, 0x7e, 0x37, 0x2a, 0x2d, 0x7e, 0x47, 0x2a, 0x31, - 0x12, 0x7c, 0x21, 0xd0, 0x87, 0xd0, 0xa8, 0x7e, 0x08, 0x2a, 0x3c, 0x7a, 0x0c, 0x00, 0x00, 0x7e, - 0x57, 0x2a, 0x31, 0x02, 0x76, 0x73, 0x02, 0x7b, 0x29, 0x75, 0x31, 0x07, 0x12, 0x7c, 0x15, 0x43, - 0xe1, 0xc0, 0x22, 0xc0, 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x12, 0x7b, 0x9e, 0x40, - 0x19, 0x7e, 0x08, 0x2a, 0x3c, 0x7a, 0x0c, 0x00, 0x00, 0xca, 0x0b, 0xca, 0x49, 0x12, 0x7c, 0x21, - 0xda, 0x59, 0xda, 0x0b, 0xd0, 0x87, 0xd0, 0xa8, 0xc3, 0x22, 0xd0, 0x87, 0xd0, 0xa8, 0x22, 0xc0, - 0xa8, 0xc0, 0x87, 0xc2, 0xaf, 0xa9, 0xd5, 0x87, 0x12, 0x7b, 0x9e, 0x40, 0x2b, 0x7e, 0x58, 0x00, - 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7f, 0x61, 0x7e, 0x78, 0x2a, 0x3c, 0x7a, 0x7c, 0x00, 0x00, 0x7e, - 0x77, 0x2a, 0x31, 0xbd, 0x74, 0x78, 0x11, 0x75, 0x31, 0xc1, 0x12, 0x7c, 0x15, 0x12, 0x7c, 0x5a, - 0x40, 0x06, 0xd0, 0x87, 0xd0, 0xa8, 0xc3, 0x22, 0xd0, 0x87, 0xd0, 0xa8, 0xd3, 0x22, 0x7e, 0x24, - 0x00, 0xfe, 0x7e, 0x34, 0x7f, 0xca, 0x0b, 0x1a, 0x50, 0xc5, 0xf0, 0x7d, 0x62, 0x7d, 0x75, 0x7d, - 0x87, 0x7e, 0x34, 0x7f, 0xc2, 0x7e, 0x1b, 0xb0, 0x7e, 0x34, 0x7f, 0x03, 0xb4, 0x01, 0x04, 0x7e, - 0x34, 0x7f, 0xcc, 0x7e, 0x1b, 0xb0, 0xbc, 0x0b, 0x50, 0x49, 0x3e, 0x00, 0x3e, 0x00, 0x0a, 0x50, - 0x2d, 0x75, 0x0b, 0x3a, 0x30, 0x69, 0x53, 0x00, 0x02, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, 0xbc, - 0x1b, 0x50, 0x30, 0x3e, 0x10, 0x3e, 0x10, 0x0a, 0x51, 0x2d, 0x35, 0x69, 0x41, 0x00, 0x02, 0x0b, - 0x1a, 0x30, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, 0xbe, 0x44, 0xff, 0xff, 0x78, 0x05, 0x7e, 0x1b, - 0x90, 0x0a, 0x49, 0x4d, 0x44, 0x68, 0x0c, 0xbe, 0x44, 0x00, 0xff, 0x28, 0x04, 0x7e, 0x44, 0x00, - 0xff, 0xc3, 0x22, 0xd3, 0x22, - -// Segment #16, Start Address 00ff7fc6, Length 4 -0xff,0x00,0xc6,0x7f,0x04,0x00, - 0x01, 0x10, 0x04, 0x00, - -// Segment #17, Start Address 00ff7c15, Length 330 -0xff,0x00,0x15,0x7c,0x4a,0x01, - 0xca, 0x08, 0x7e, 0x01, 0x31, 0x7a, 0x03, 0x3f, 0xf0, 0xda, 0x08, 0x22, 0x7e, 0x1b, 0xc0, 0x7a, - 0x0b, 0xc0, 0x0b, 0x14, 0x0b, 0x34, 0x1b, 0x44, 0x78, 0xf2, 0x22, 0x7f, 0x6f, 0x7f, 0xf0, 0x1b, - 0xfc, 0x7c, 0x54, 0x7d, 0x32, 0x80, 0x08, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0x9e, - 0x44, 0x00, 0x10, 0x50, 0xf2, 0x2e, 0x44, 0x00, 0x10, 0x68, 0x06, 0xca, 0x48, 0x1b, 0x44, 0x78, - 0xfa, 0x7f, 0xf6, 0x89, 0xe4, 0xca, 0x6b, 0x5e, 0xd4, 0x00, 0x3f, 0x68, 0x20, 0x7e, 0x84, 0x00, - 0x40, 0x9d, 0x8d, 0xda, 0x6b, 0xbd, 0x87, 0x38, 0x16, 0xca, 0x79, 0x7d, 0x78, 0x12, 0x7c, 0x84, - 0xda, 0x79, 0x40, 0x08, 0x9d, 0x78, 0x68, 0x02, 0x80, 0x05, 0xc2, 0xd7, 0x22, 0xda, 0x6b, 0x43, - 0x90, 0x30, 0x74, 0xaa, 0x39, 0xb5, 0x55, 0x55, 0x74, 0x55, 0x39, 0xb5, 0x2a, 0xaa, 0x74, 0xa0, - 0x39, 0xb5, 0x55, 0x55, 0x7e, 0x04, 0x00, 0x40, 0x9d, 0x70, 0x50, 0x06, 0x2d, 0x70, 0x7d, 0x07, - 0x6d, 0x77, 0x7c, 0x31, 0x7e, 0x7b, 0x00, 0x7a, 0x6b, 0x00, 0x0b, 0x7c, 0x0b, 0x6c, 0xa5, 0xd9, - 0xf3, 0x7f, 0x16, 0x1b, 0x1c, 0x7e, 0x54, 0x27, 0x10, 0x7e, 0x1b, 0x10, 0xbc, 0x10, 0x68, 0x06, - 0x1b, 0x54, 0x78, 0xf5, 0x80, 0x2c, 0x6d, 0x00, 0x7c, 0x20, 0x7f, 0x16, 0x9f, 0x10, 0x7f, 0x27, - 0x9f, 0x20, 0x7e, 0x2b, 0x00, 0x7e, 0x1b, 0x10, 0xbc, 0x01, 0x78, 0x16, 0x0b, 0x2c, 0x0b, 0x1c, - 0xa5, 0xdb, 0xef, 0x7c, 0xb6, 0x20, 0xe0, 0x03, 0x63, 0x90, 0x30, 0x4d, 0x77, 0x78, 0x93, 0xc2, - 0xd7, 0x22, 0xd2, 0xd7, 0x22, 0x00, 0x04, 0x00, 0x04, 0x42, 0x08, 0x06, 0x04, 0x02, 0x04, 0x00, - 0x02, 0x01, 0x04, 0x01, 0x02, 0x82, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x04, 0x02, 0x08, 0x10, 0x02, 0x10, 0x04, 0x02, 0x08, 0x00, 0x01, 0x01, 0x08, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x02, 0x02, 0x08, 0x02, 0x04, 0x20, 0x04, 0x7e, 0x18, 0x7f, 0xbd, 0x7a, - 0x1c, 0x00, 0xfe, 0x0b, 0x1a, 0x00, 0x5e, 0x10, 0x1f, 0xbe, 0x10, 0x1a, 0x38, 0x1a, 0x0a, 0x51, - 0x23, 0x7e, 0x18, 0x7c, 0xfa, 0x7a, 0x1c, 0x00, 0xff, 0x2d, 0x35, 0x0b, 0x1a, 0x50, 0x60, 0x08, - 0xa5, 0xb8, 0x02, 0x03, 0x4e, 0xa0, 0x08, 0x22, 0x80, 0xfe, -}; - -static struct edge_firmware_version_info IMAGE_VERSION_NAME = { - 1, 16, 4 }; // Major, Minor, Build - -#undef IMAGE_VERSION_NAME - -#undef IMAGE_ARRAY_NAME - diff --git a/drivers/usb/serial/io_fw_down2.h b/drivers/usb/serial/io_fw_down2.h deleted file mode 100644 index 067277e..0000000 --- a/drivers/usb/serial/io_fw_down2.h +++ /dev/null @@ -1,1133 +0,0 @@ -//************************************************************** -//* Edgeport/4 Binary Image -//* Generated by HEX2C v1.06 -//* Copyright (C) 1998 Inside Out Networks, 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. -//************************************************************** - - -//Image structure definition -#if !defined(DEFINED_EDGE_FIRMWARE_IMAGE_RECORD) - #define DEFINED_EDGE_FIRMWARE_IMAGE_RECORD - struct edge_firmware_image_record { - __le16 ExtAddr; - __le16 Addr; - __le16 Len; - unsigned char Data[0]; - } __attribute__ ((packed)); - - struct edge_firmware_version_info { - unsigned char MajorVersion; - unsigned char MinorVersion; - unsigned short BuildNumber; - }; - -#endif - -#if !defined(IMAGE_ARRAY_NAME) - #define IMAGE_ARRAY_NAME FirmwareImage - #define IMAGE_VERSION_NAME FirmwareImageVersion -#endif - -static unsigned char IMAGE_ARRAY_NAME[] = { - -// Segment #1, Start Address 00ff0000, Length 6 -0xff,0x00,0x00,0x00,0x06,0x00, - 0x02, 0x00, 0x80, 0x02, 0x45, 0x14, - -// Segment #2, Start Address 00ff000b, Length 3 -0xff,0x00,0x0b,0x00,0x03,0x00, - 0x02, 0x44, 0xa5, - -// Segment #3, Start Address 00ff0013, Length 3 -0xff,0x00,0x13,0x00,0x03,0x00, - 0x02, 0x63, 0xab, - -// Segment #4, Start Address 00ff001b, Length 3 -0xff,0x00,0x1b,0x00,0x03,0x00, - 0x02, 0x00, 0x1b, - -// Segment #5, Start Address 00ff0023, Length 3 -0xff,0x00,0x23,0x00,0x03,0x00, - 0x02, 0x00, 0x23, - -// Segment #6, Start Address 00ff002b, Length 3 -0xff,0x00,0x2b,0x00,0x03,0x00, - 0x02, 0x00, 0x2b, - -// Segment #7, Start Address 00ff0033, Length 3 -0xff,0x00,0x33,0x00,0x03,0x00, - 0x02, 0x00, 0x33, - -// Segment #8, Start Address 00ff003b, Length 3 -0xff,0x00,0x3b,0x00,0x03,0x00, - 0x02, 0x00, 0x3b, - -// Segment #9, Start Address 00ff0043, Length 3 -0xff,0x00,0x43,0x00,0x03,0x00, - 0x02, 0x00, 0x43, - -// Segment #10, Start Address 00ff004b, Length 3 -0xff,0x00,0x4b,0x00,0x03,0x00, - 0x02, 0x00, 0x4b, - -// Segment #11, Start Address 00ff0053, Length 3 -0xff,0x00,0x53,0x00,0x03,0x00, - 0x02, 0x67, 0x5f, - -// Segment #12, Start Address 00ff007b, Length 3 -0xff,0x00,0x7b,0x00,0x03,0x00, - 0x02, 0x00, 0x7b, - -// Segment #13, Start Address 00ff0080, Length 7 -0xff,0x00,0x80,0x00,0x07,0x00, - 0x7e, 0x14, 0x00, 0x00, 0x02, 0x40, 0x52, - -// Segment #14, Start Address 00ff3000, Length 2918 -0xff,0x00,0x00,0x30,0x66,0x0b, - 0x12, 0x30, 0x64, 0x12, 0x30, 0xff, 0x12, 0x31, 0x2f, 0x12, 0x30, 0xb0, 0x80, 0xf2, 0xe5, 0x23, - 0x60, 0x19, 0x7e, 0x14, 0x00, 0x00, 0x09, 0xb1, 0x01, 0xb9, 0xb4, 0x00, 0x02, 0x80, 0x05, 0x14, - 0x19, 0xb1, 0x01, 0xb9, 0xa5, 0x0a, 0xbe, 0x21, 0x2e, 0x78, 0xeb, 0x22, 0xc2, 0xaf, 0x7e, 0xb3, - 0x3f, 0xf1, 0xb4, 0x01, 0x03, 0x12, 0x65, 0x67, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x7e, 0xb3, 0x3f, - 0xf1, 0xb4, 0x01, 0x1d, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x91, 0x1a, 0x6c, 0xaa, - 0x60, 0x0f, 0xca, 0x0b, 0xca, 0x39, 0xca, 0x59, 0x12, 0x64, 0x24, 0xda, 0x59, 0xda, 0x39, 0xda, - 0x0b, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0xe5, 0x22, 0x60, 0x43, 0x7e, 0x07, 0x01, 0xcb, 0xbe, 0x04, - 0x03, 0x80, 0x38, 0x39, 0x7e, 0x04, 0x80, 0x00, 0x7e, 0x20, 0x00, 0x13, 0x50, 0x21, 0x09, 0xa0, - 0x00, 0x04, 0x4e, 0xa0, 0x05, 0x19, 0xa0, 0x00, 0x04, 0x0a, 0x32, 0x09, 0x53, 0x35, 0x33, 0x5e, - 0x51, 0x27, 0x68, 0x0b, 0x09, 0xa0, 0x00, 0x10, 0x4e, 0xa0, 0x01, 0x19, 0xa0, 0x00, 0x10, 0x2e, - 0x04, 0x01, 0x00, 0xa5, 0x0a, 0xbe, 0x21, 0x2e, 0x78, 0xd1, 0x75, 0x22, 0x00, 0xd2, 0xaf, 0x22, - 0xc2, 0xaf, 0xe5, 0x26, 0x60, 0x36, 0x7e, 0x20, 0x00, 0x7e, 0x30, 0x01, 0xe5, 0x26, 0xa5, 0x5b, - 0x68, 0x21, 0x7c, 0xb2, 0x23, 0x0a, 0x2b, 0x49, 0x32, 0x01, 0x79, 0xbe, 0x34, 0x00, 0x00, 0x68, - 0x12, 0x7e, 0xb1, 0x21, 0xa5, 0x4b, 0x7a, 0xb1, 0x21, 0xca, 0x19, 0x49, 0x22, 0x30, 0xef, 0x99, - 0x24, 0xda, 0x19, 0x3e, 0x30, 0xa5, 0x0a, 0xbe, 0x21, 0x2e, 0x78, 0xd0, 0xd2, 0xaf, 0x22, 0x46, - 0x4f, 0x49, 0x7c, 0x4c, 0xa9, 0x4f, 0xd6, 0x53, 0x03, 0x56, 0x30, 0x59, 0x5d, 0x5c, 0x8a, 0xc2, - 0xaf, 0xe5, 0x24, 0x60, 0x14, 0x7e, 0x20, 0x00, 0x13, 0x50, 0x07, 0xca, 0xb8, 0x12, 0x31, 0x1c, - 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2e, 0x78, 0xef, 0xd2, 0xaf, 0x22, 0xca, 0x28, 0x12, 0x35, - 0x4c, 0xda, 0x28, 0x40, 0x09, 0x0a, 0x22, 0x09, 0xb2, 0x35, 0x33, 0xf4, 0x52, 0x24, 0x22, 0xc2, - 0xaf, 0xe5, 0x23, 0x60, 0x14, 0x7e, 0x20, 0x00, 0x13, 0x50, 0x07, 0xca, 0xb8, 0x12, 0x31, 0x4c, - 0xda, 0xb8, 0xa5, 0x0a, 0xbe, 0x21, 0x2e, 0x78, 0xef, 0xd2, 0xaf, 0x22, 0x7c, 0xb2, 0x23, 0x0a, - 0x2b, 0x49, 0x22, 0x31, 0x57, 0x89, 0x24, 0x31, 0x67, 0x31, 0xd0, 0x32, 0x39, 0x32, 0xa2, 0x33, - 0x0b, 0x33, 0x74, 0x33, 0xdd, 0x34, 0x46, 0x7e, 0x27, 0x01, 0x79, 0xbe, 0x24, 0x00, 0x00, 0x78, - 0x24, 0x7e, 0x24, 0x80, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, - 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x49, 0x45, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, - 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, 0x01, 0x89, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0x89, 0x7e, - 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xb9, 0x80, 0x27, 0x7e, 0x63, 0x01, 0xb9, 0xa5, 0xbe, 0x00, 0x1f, - 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, 0xa0, 0xc8, 0x12, 0x61, 0x36, 0x40, 0x11, 0x75, 0x2f, - 0xb3, 0x12, 0x73, 0x35, 0xc2, 0x18, 0x6c, 0x00, 0x7a, 0x03, 0x01, 0xb9, 0x12, 0x64, 0x86, 0x22, - 0x7e, 0x27, 0x01, 0x7b, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x81, 0x00, 0x09, 0xb2, - 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, - 0x4c, 0x72, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, - 0x01, 0x8b, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0x8b, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xba, 0x80, - 0x27, 0x7e, 0x63, 0x01, 0xba, 0xa5, 0xbe, 0x00, 0x1f, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, - 0xa0, 0xc8, 0x12, 0x61, 0x36, 0x40, 0x11, 0x75, 0x2f, 0xb3, 0x12, 0x73, 0x35, 0xc2, 0x19, 0x6c, - 0x00, 0x7a, 0x03, 0x01, 0xba, 0x12, 0x64, 0x86, 0x22, 0x7e, 0x27, 0x01, 0x7d, 0xbe, 0x24, 0x00, - 0x00, 0x78, 0x24, 0x7e, 0x24, 0x82, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, - 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x4f, 0x9f, 0x7d, 0x21, 0xda, 0x19, 0x30, - 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, 0x01, 0x8d, 0x68, 0x0d, 0x7a, 0x27, 0x01, - 0x8d, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xbb, 0x80, 0x27, 0x7e, 0x63, 0x01, 0xbb, 0xa5, 0xbe, - 0x00, 0x1f, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, 0xa0, 0xc8, 0x12, 0x61, 0x36, 0x40, 0x11, - 0x75, 0x2f, 0xb3, 0x12, 0x73, 0x35, 0xc2, 0x1a, 0x6c, 0x00, 0x7a, 0x03, 0x01, 0xbb, 0x12, 0x64, - 0x86, 0x22, 0x7e, 0x27, 0x01, 0x7f, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x83, 0x00, - 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, - 0x12, 0x12, 0x52, 0xcc, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, - 0xbe, 0x27, 0x01, 0x8f, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0x8f, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, - 0xbc, 0x80, 0x27, 0x7e, 0x63, 0x01, 0xbc, 0xa5, 0xbe, 0x00, 0x1f, 0x7e, 0x60, 0x01, 0x7e, 0xb0, - 0x00, 0x7e, 0xa0, 0xc8, 0x12, 0x61, 0x36, 0x40, 0x11, 0x75, 0x2f, 0xb3, 0x12, 0x73, 0x35, 0xc2, - 0x1b, 0x6c, 0x00, 0x7a, 0x03, 0x01, 0xbc, 0x12, 0x64, 0x86, 0x22, 0x7e, 0x27, 0x01, 0x81, 0xbe, - 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x84, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, - 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x55, 0xf9, 0x7d, 0x21, 0xda, - 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, 0x01, 0x91, 0x68, 0x0d, 0x7a, - 0x27, 0x01, 0x91, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xbd, 0x80, 0x27, 0x7e, 0x63, 0x01, 0xbd, - 0xa5, 0xbe, 0x00, 0x1f, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, 0xa0, 0xc8, 0x12, 0x61, 0x36, - 0x40, 0x11, 0x75, 0x2f, 0xb3, 0x12, 0x73, 0x35, 0xc2, 0x1c, 0x6c, 0x00, 0x7a, 0x03, 0x01, 0xbd, - 0x12, 0x64, 0x86, 0x22, 0x7e, 0x27, 0x01, 0x83, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, - 0x85, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, - 0x19, 0x7d, 0x12, 0x12, 0x59, 0x26, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, - 0x80, 0x1e, 0xbe, 0x27, 0x01, 0x93, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0x93, 0x7e, 0x60, 0x9c, 0x7a, - 0x63, 0x01, 0xbe, 0x80, 0x27, 0x7e, 0x63, 0x01, 0xbe, 0xa5, 0xbe, 0x00, 0x1f, 0x7e, 0x60, 0x01, - 0x7e, 0xb0, 0x00, 0x7e, 0xa0, 0xc8, 0x12, 0x61, 0x36, 0x40, 0x11, 0x75, 0x2f, 0xb3, 0x12, 0x73, - 0x35, 0xc2, 0x1d, 0x6c, 0x00, 0x7a, 0x03, 0x01, 0xbe, 0x12, 0x64, 0x86, 0x22, 0x7e, 0x27, 0x01, - 0x85, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, 0x7e, 0x24, 0x86, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, - 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x5c, 0x53, 0x7d, - 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, 0x01, 0x95, 0x68, - 0x0d, 0x7a, 0x27, 0x01, 0x95, 0x7e, 0x60, 0x9c, 0x7a, 0x63, 0x01, 0xbf, 0x80, 0x27, 0x7e, 0x63, - 0x01, 0xbf, 0xa5, 0xbe, 0x00, 0x1f, 0x7e, 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, 0xa0, 0xc8, 0x12, - 0x61, 0x36, 0x40, 0x11, 0x75, 0x2f, 0xb3, 0x12, 0x73, 0x35, 0xc2, 0x1e, 0x6c, 0x00, 0x7a, 0x03, - 0x01, 0xbf, 0x12, 0x64, 0x86, 0x22, 0x7e, 0x27, 0x01, 0x87, 0xbe, 0x24, 0x00, 0x00, 0x78, 0x24, - 0x7e, 0x24, 0x87, 0x00, 0x09, 0xb2, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, - 0x0b, 0xca, 0x19, 0x7d, 0x12, 0x12, 0x5f, 0x80, 0x7d, 0x21, 0xda, 0x19, 0x30, 0xe6, 0x18, 0x7e, - 0x60, 0x00, 0x80, 0x1e, 0xbe, 0x27, 0x01, 0x97, 0x68, 0x0d, 0x7a, 0x27, 0x01, 0x97, 0x7e, 0x60, - 0x9c, 0x7a, 0x63, 0x01, 0xc0, 0x80, 0x27, 0x7e, 0x63, 0x01, 0xc0, 0xa5, 0xbe, 0x00, 0x1f, 0x7e, - 0x60, 0x01, 0x7e, 0xb0, 0x00, 0x7e, 0xa0, 0xc8, 0x12, 0x61, 0x36, 0x40, 0x11, 0x75, 0x2f, 0xb3, - 0x12, 0x73, 0x35, 0xc2, 0x1f, 0x6c, 0x00, 0x7a, 0x03, 0x01, 0xc0, 0x12, 0x64, 0x86, 0x22, 0xc2, - 0xaf, 0x7e, 0x07, 0x01, 0xcb, 0xbe, 0x04, 0x00, 0x00, 0x78, 0x28, 0x74, 0x20, 0x7a, 0xb3, 0x91, - 0x00, 0x7e, 0xb3, 0x91, 0x15, 0x30, 0xe5, 0x1b, 0x7e, 0xb3, 0x91, 0x1a, 0xbe, 0xb0, 0x3f, 0x38, - 0x0c, 0x85, 0x31, 0x2f, 0x12, 0x73, 0x35, 0x74, 0x80, 0x7a, 0xb3, 0x91, 0x1e, 0x74, 0x20, 0x7a, - 0xb3, 0x91, 0x15, 0xd2, 0xaf, 0x22, 0x35, 0x3b, 0x36, 0xe8, 0x37, 0x00, 0x37, 0x1b, 0x37, 0xb6, - 0x38, 0x4e, 0x38, 0x69, 0x38, 0xfb, 0x38, 0x84, 0x38, 0xc5, 0x7c, 0xb3, 0xbe, 0xb0, 0x09, 0x28, - 0x22, 0x75, 0x2f, 0x09, 0x12, 0x73, 0x35, 0x75, 0x57, 0x02, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x00, - 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x11, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x01, 0x7a, 0xb3, - 0x91, 0x11, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0x23, 0x6c, 0xaa, 0x2e, 0x54, 0x34, 0xe6, 0x0b, 0x58, - 0x50, 0x89, 0x54, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x75, 0x2f, 0xb0, 0x12, 0x73, - 0x35, 0x0a, 0x22, 0x09, 0xb2, 0x35, 0x33, 0x42, 0x24, 0xd0, 0xa8, 0x22, 0x7c, 0xb2, 0x23, 0x0a, - 0x3b, 0x49, 0x33, 0x35, 0x57, 0x89, 0x34, 0x35, 0x67, 0x35, 0x95, 0x35, 0xc3, 0x35, 0xf1, 0x36, - 0x1f, 0x36, 0x4d, 0x36, 0x7b, 0x36, 0xa9, 0x12, 0x41, 0xba, 0xd2, 0x28, 0xd2, 0x08, 0xc2, 0x40, - 0xc2, 0x48, 0xc2, 0x38, 0xc2, 0x30, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xb9, 0x7e, 0x04, 0x00, 0x20, - 0x7a, 0x07, 0x01, 0x99, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xa9, 0x12, 0x41, 0x27, 0x12, - 0x5f, 0xb7, 0x02, 0x36, 0xd7, 0x12, 0x41, 0xd7, 0xd2, 0x29, 0xd2, 0x09, 0xc2, 0x41, 0xc2, 0x49, - 0xc2, 0x39, 0xc2, 0x31, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xba, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, - 0x01, 0x9b, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xab, 0x12, 0x41, 0x27, 0x12, 0x5f, 0xe0, - 0x02, 0x36, 0xd7, 0x12, 0x41, 0xf4, 0xd2, 0x2a, 0xd2, 0x0a, 0xc2, 0x42, 0xc2, 0x4a, 0xc2, 0x3a, - 0xc2, 0x32, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xbb, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0x9d, - 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xad, 0x12, 0x41, 0x27, 0x12, 0x60, 0x09, 0x02, 0x36, - 0xd7, 0x12, 0x42, 0x11, 0xd2, 0x2b, 0xd2, 0x0b, 0xc2, 0x43, 0xc2, 0x4b, 0xc2, 0x3b, 0xc2, 0x33, - 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xbc, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0x9f, 0x7e, 0x04, - 0x00, 0x38, 0x7a, 0x07, 0x01, 0xaf, 0x12, 0x41, 0x27, 0x12, 0x60, 0x32, 0x02, 0x36, 0xd7, 0x12, - 0x42, 0x2e, 0xd2, 0x2c, 0xd2, 0x0c, 0xc2, 0x44, 0xc2, 0x4c, 0xc2, 0x3c, 0xc2, 0x34, 0x6d, 0x00, - 0x7a, 0x03, 0x01, 0xbd, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xa1, 0x7e, 0x04, 0x00, 0x38, - 0x7a, 0x07, 0x01, 0xb1, 0x12, 0x41, 0x27, 0x12, 0x60, 0x5b, 0x02, 0x36, 0xd7, 0x12, 0x42, 0x4b, - 0xd2, 0x2d, 0xd2, 0x0d, 0xc2, 0x45, 0xc2, 0x4d, 0xc2, 0x3d, 0xc2, 0x35, 0x6d, 0x00, 0x7a, 0x03, - 0x01, 0xbe, 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xa3, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, - 0x01, 0xb3, 0x12, 0x41, 0x27, 0x12, 0x60, 0x84, 0x02, 0x36, 0xd7, 0x12, 0x42, 0x68, 0xd2, 0x2e, - 0xd2, 0x0e, 0xc2, 0x46, 0xc2, 0x4e, 0xc2, 0x3e, 0xc2, 0x36, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xbf, - 0x7e, 0x04, 0x00, 0x20, 0x7a, 0x07, 0x01, 0xa5, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xb5, - 0x12, 0x41, 0x27, 0x12, 0x60, 0xad, 0x02, 0x36, 0xd7, 0x12, 0x42, 0x85, 0xd2, 0x2f, 0xd2, 0x0f, - 0xc2, 0x47, 0xc2, 0x4f, 0xc2, 0x3f, 0xc2, 0x37, 0x6d, 0x00, 0x7a, 0x03, 0x01, 0xc0, 0x7e, 0x04, - 0x00, 0x20, 0x7a, 0x07, 0x01, 0xa7, 0x7e, 0x04, 0x00, 0x38, 0x7a, 0x07, 0x01, 0xb7, 0x12, 0x41, - 0x27, 0x12, 0x60, 0xd6, 0x02, 0x36, 0xd7, 0x7e, 0xa0, 0xd0, 0x7e, 0x60, 0x0f, 0x12, 0x61, 0x36, - 0x40, 0x05, 0x12, 0x64, 0x86, 0xc2, 0xd7, 0x22, 0x75, 0x2f, 0xb1, 0x12, 0x73, 0x35, 0x0a, 0x52, - 0x23, 0x6d, 0x00, 0x59, 0x05, 0x00, 0x32, 0x12, 0x41, 0x83, 0x12, 0x41, 0x9f, 0xd0, 0xa8, 0x22, - 0x75, 0x2f, 0xb2, 0x12, 0x73, 0x35, 0x0a, 0x22, 0x09, 0xb2, 0x35, 0x33, 0x42, 0x23, 0x7e, 0xb0, - 0x9c, 0x19, 0xb2, 0x01, 0xb9, 0x12, 0x31, 0x4c, 0xd0, 0xa8, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, - 0x02, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x09, 0xb0, 0x00, 0x08, 0x19, - 0x30, 0x00, 0x0c, 0x7c, 0x74, 0x5e, 0x70, 0x01, 0x68, 0x12, 0x44, 0x40, 0xca, 0xb8, 0x09, 0xb0, - 0x00, 0x10, 0x44, 0x02, 0x19, 0xb0, 0x00, 0x10, 0xda, 0xb8, 0x80, 0x02, 0x54, 0xbf, 0x7c, 0x74, - 0x5e, 0x70, 0x08, 0x68, 0x04, 0x44, 0x08, 0x80, 0x02, 0x54, 0xf7, 0x09, 0x30, 0x00, 0x0c, 0xca, - 0xb8, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0xda, 0xb8, 0x19, 0xb0, 0x00, 0x08, 0x19, 0x30, 0x00, - 0x0c, 0x0a, 0x62, 0x09, 0xb6, 0x35, 0x33, 0x3e, 0x20, 0x0a, 0x62, 0x7c, 0x74, 0x5e, 0x70, 0x02, - 0x68, 0x20, 0x42, 0x27, 0xca, 0xb8, 0x74, 0x61, 0x19, 0xb0, 0x00, 0x08, 0x7e, 0x44, 0x00, 0x10, - 0x59, 0x46, 0x01, 0xa9, 0x09, 0xb0, 0x00, 0x10, 0x44, 0x01, 0x19, 0xb0, 0x00, 0x10, 0xda, 0xb8, - 0x80, 0x11, 0xf4, 0x52, 0x27, 0x74, 0xa1, 0x19, 0xb0, 0x00, 0x08, 0x7e, 0x44, 0x00, 0x38, 0x59, - 0x46, 0x01, 0xa9, 0xd0, 0xa8, 0x22, 0x7c, 0x74, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x09, 0x30, - 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x09, 0xb0, 0x00, 0x08, 0x7c, 0x74, 0x5e, 0x70, - 0x01, 0x68, 0x04, 0x44, 0x80, 0x80, 0x02, 0x54, 0x7f, 0x7c, 0x74, 0x5e, 0x70, 0x08, 0x68, 0x04, - 0x44, 0x02, 0x80, 0x02, 0x54, 0xfd, 0x19, 0xb0, 0x00, 0x08, 0x19, 0x30, 0x00, 0x0c, 0x0a, 0x62, - 0x09, 0xb6, 0x35, 0x33, 0xa5, 0xfd, 0xf4, 0xa5, 0xfe, 0xca, 0x28, 0x3e, 0x20, 0x0a, 0x62, 0xda, - 0x28, 0x7c, 0x74, 0x5e, 0x70, 0x02, 0x68, 0x10, 0xa5, 0xed, 0x42, 0x28, 0x42, 0x26, 0x7e, 0x44, - 0x00, 0x08, 0x59, 0x46, 0x01, 0x99, 0x80, 0x04, 0xa5, 0xee, 0x52, 0x28, 0x7c, 0x74, 0x5e, 0x70, - 0x04, 0x68, 0x10, 0xa5, 0xed, 0x42, 0x29, 0x42, 0x26, 0x7e, 0x44, 0x00, 0x08, 0x59, 0x46, 0x01, - 0x99, 0x80, 0x15, 0xa5, 0xee, 0x52, 0x29, 0x7c, 0x74, 0x5e, 0x70, 0x02, 0x78, 0x0a, 0x52, 0x26, - 0x7e, 0x44, 0x00, 0x20, 0x59, 0x46, 0x01, 0x99, 0x12, 0x42, 0xa2, 0xd0, 0xa8, 0x22, 0x7e, 0x04, - 0x80, 0x00, 0x4c, 0x02, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x19, 0x40, - 0x00, 0x10, 0x19, 0x30, 0x00, 0x0c, 0xd0, 0xa8, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x09, - 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x19, 0x40, 0x00, 0x18, 0x19, 0x30, 0x00, - 0x0c, 0xd0, 0xa8, 0x22, 0x75, 0x2f, 0xb5, 0x12, 0x73, 0x35, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, - 0x09, 0xb0, 0x00, 0x0c, 0x44, 0x40, 0x19, 0xb0, 0x00, 0x0c, 0xe5, 0x58, 0xb4, 0x07, 0x23, 0x09, - 0xb0, 0x00, 0x10, 0x4e, 0xb0, 0x02, 0x19, 0xb0, 0x00, 0x10, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, - 0x19, 0xb0, 0x00, 0x0c, 0x09, 0xb0, 0x00, 0x04, 0x54, 0xf7, 0x19, 0xb0, 0x00, 0x04, 0x19, 0x30, - 0x00, 0x0c, 0xd0, 0xa8, 0x22, 0x75, 0x2f, 0xb6, 0x12, 0x73, 0x35, 0x7e, 0x04, 0x80, 0x00, 0x4c, - 0x02, 0xe5, 0x58, 0xb4, 0x07, 0x18, 0x09, 0x30, 0x00, 0x0c, 0x74, 0xbf, 0x19, 0xb0, 0x00, 0x0c, - 0x09, 0xb0, 0x00, 0x04, 0x44, 0x08, 0x19, 0xb0, 0x00, 0x04, 0x19, 0x30, 0x00, 0x0c, 0x09, 0xb0, - 0x00, 0x0c, 0x54, 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0xd0, 0xa8, 0x22, 0x75, 0x2f, 0xb4, 0x12, 0x73, - 0x35, 0x7a, 0x21, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x41, 0x2f, 0x12, 0x73, 0x35, 0x7e, 0xb0, 0x01, - 0x7e, 0xa0, 0xc8, 0x7c, 0x64, 0x12, 0x61, 0x36, 0x12, 0x64, 0x86, 0xd0, 0xa8, 0x22, 0x39, 0x2e, - 0x39, 0x75, 0x39, 0xbc, 0x3a, 0x03, 0x3a, 0x4a, 0x3a, 0x91, 0x3a, 0xd8, 0x3b, 0x1f, 0x75, 0x2f, - 0x55, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, 0x35, - 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0x7e, 0x17, 0x01, 0x69, 0x7e, 0x27, 0x01, 0x79, 0x2d, 0x23, - 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x08, 0x2c, 0x38, 0x0f, - 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x69, 0x7a, 0x27, 0x01, 0x79, 0x02, 0x46, 0x4f, 0x7e, - 0x14, 0x04, 0x2d, 0x80, 0xeb, 0x75, 0x2f, 0x55, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x01, 0x12, 0x73, - 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0x7e, 0x17, 0x01, - 0x6b, 0x7e, 0x27, 0x01, 0x7b, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, - 0x14, 0xbe, 0x14, 0x0c, 0x2c, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x6b, 0x7a, - 0x27, 0x01, 0x7b, 0x02, 0x49, 0x7c, 0x7e, 0x14, 0x08, 0x2d, 0x80, 0xeb, 0x75, 0x2f, 0x55, 0x12, - 0x73, 0x35, 0x75, 0x2f, 0x02, 0x12, 0x73, 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x71, - 0x2f, 0x12, 0x73, 0x35, 0x7e, 0x17, 0x01, 0x6d, 0x7e, 0x27, 0x01, 0x7d, 0x2d, 0x23, 0x7e, 0x09, - 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x10, 0x2c, 0x38, 0x0f, 0x1b, 0x34, - 0x78, 0xec, 0x7a, 0x17, 0x01, 0x6d, 0x7a, 0x27, 0x01, 0x7d, 0x02, 0x4c, 0xa9, 0x7e, 0x14, 0x0c, - 0x2d, 0x80, 0xeb, 0x75, 0x2f, 0x55, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x03, 0x12, 0x73, 0x35, 0x7a, - 0x61, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0x7e, 0x17, 0x01, 0x6f, 0x7e, - 0x27, 0x01, 0x7f, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, - 0x14, 0x14, 0x2c, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x6f, 0x7a, 0x27, 0x01, - 0x7f, 0x02, 0x4f, 0xd6, 0x7e, 0x14, 0x10, 0x2d, 0x80, 0xeb, 0x75, 0x2f, 0x55, 0x12, 0x73, 0x35, - 0x75, 0x2f, 0x04, 0x12, 0x73, 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, - 0x73, 0x35, 0x7e, 0x17, 0x01, 0x71, 0x7e, 0x27, 0x01, 0x81, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, - 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x18, 0x2c, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, - 0x7a, 0x17, 0x01, 0x71, 0x7a, 0x27, 0x01, 0x81, 0x02, 0x53, 0x03, 0x7e, 0x14, 0x14, 0x2d, 0x80, - 0xeb, 0x75, 0x2f, 0x55, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x05, 0x12, 0x73, 0x35, 0x7a, 0x61, 0x2f, - 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0x7e, 0x17, 0x01, 0x73, 0x7e, 0x27, 0x01, - 0x83, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x1c, - 0x2c, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x73, 0x7a, 0x27, 0x01, 0x83, 0x02, - 0x56, 0x30, 0x7e, 0x14, 0x18, 0x2d, 0x80, 0xeb, 0x75, 0x2f, 0x55, 0x12, 0x73, 0x35, 0x75, 0x2f, - 0x06, 0x12, 0x73, 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, - 0x7e, 0x17, 0x01, 0x75, 0x7e, 0x27, 0x01, 0x85, 0x2d, 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, - 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x20, 0x2c, 0x38, 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, - 0x01, 0x75, 0x7a, 0x27, 0x01, 0x85, 0x02, 0x59, 0x5d, 0x7e, 0x14, 0x1c, 0x2d, 0x80, 0xeb, 0x75, - 0x2f, 0x55, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x07, 0x12, 0x73, 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, - 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0x7e, 0x17, 0x01, 0x77, 0x7e, 0x27, 0x01, 0x87, 0x2d, - 0x23, 0x7e, 0x09, 0xb0, 0x0b, 0x04, 0x7a, 0x19, 0xb0, 0x0b, 0x14, 0xbe, 0x14, 0x24, 0x2c, 0x38, - 0x0f, 0x1b, 0x34, 0x78, 0xec, 0x7a, 0x17, 0x01, 0x77, 0x7a, 0x27, 0x01, 0x87, 0x02, 0x5c, 0x8a, - 0x7e, 0x14, 0x20, 0x2d, 0x80, 0xeb, - -// Segment #15, Start Address 00ff4000, Length 13109 -0xff,0x00,0x00,0x40,0x35,0x33, - 0x7e, 0x04, 0x00, 0x01, 0x7e, 0x14, 0x7f, 0xf8, 0x7e, 0x24, 0x00, 0xfe, 0x7d, 0x31, 0x0b, 0x1a, - 0x50, 0x1b, 0x0a, 0x50, 0x7e, 0x14, 0x40, 0x1b, 0x02, 0x40, 0x74, 0x7e, 0xf8, 0x00, 0x59, 0x75, - 0xb0, 0xdf, 0x7e, 0xb0, 0x01, 0x7a, 0xb3, 0x90, 0x00, 0x7e, 0xf4, 0x40, 0x30, 0x02, 0x40, 0x8b, - 0x12, 0x74, 0x4e, 0xf5, 0x2e, 0x7a, 0xa1, 0x2d, 0x7a, 0x11, 0x58, 0x12, 0x6b, 0x02, 0x12, 0x40, - 0xeb, 0x7e, 0xb3, 0x3f, 0xf1, 0x60, 0x03, 0x12, 0x43, 0x79, 0x12, 0x6b, 0xde, 0xd2, 0xaf, 0x02, - 0x30, 0x00, 0x7e, 0x04, 0x00, 0xff, 0x7e, 0x18, 0x40, 0x60, 0x7a, 0x1c, 0x00, 0x01, 0x89, 0x18, - 0x7e, 0xb0, 0x01, 0x7a, 0xb3, 0x94, 0x00, 0x7a, 0xb3, 0x2c, 0x35, 0x7e, 0xb0, 0x01, 0x7a, 0xb3, - 0x93, 0x00, 0x89, 0x08, 0x7e, 0x04, 0x00, 0xff, 0x7e, 0x18, 0x40, 0x82, 0x7a, 0x1c, 0x00, 0x01, - 0x89, 0x18, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x93, 0x00, 0x89, 0x08, 0x7e, 0x08, 0x00, 0x20, 0x7e, - 0x44, 0x04, 0x00, 0x7e, 0x40, 0x00, 0x7e, 0xe4, 0x40, 0x9d, 0x02, 0x73, 0x50, 0x7e, 0x08, 0x01, - 0x59, 0x7e, 0x44, 0x2a, 0xdd, 0x7e, 0x40, 0x00, 0x7e, 0xe4, 0x40, 0xaf, 0x02, 0x73, 0x50, 0x7e, - 0x08, 0x00, 0x59, 0x7e, 0x44, 0x01, 0x00, 0x7e, 0x40, 0x53, 0x7e, 0xe4, 0x40, 0xc1, 0x02, 0x73, - 0x50, 0x75, 0x57, 0x01, 0x75, 0x56, 0x00, 0x7e, 0x04, 0x00, 0x08, 0x75, 0x54, 0x58, 0x75, 0x55, - 0x08, 0x75, 0x51, 0x08, 0x75, 0x53, 0x01, 0x75, 0x89, 0x01, 0x75, 0x8a, 0x01, 0x75, 0x8c, 0x00, - 0xd2, 0x8c, 0x7e, 0x04, 0x00, 0x02, 0x7a, 0x05, 0x42, 0x89, 0xf4, 0x75, 0xb7, 0x7f, 0x75, 0xb8, - 0x7f, 0x75, 0xb3, 0x01, 0x75, 0xb2, 0x01, 0xd2, 0xa9, 0x22, 0x75, 0xb0, 0xdf, 0xe4, 0xd5, 0xe0, - 0xfd, 0x75, 0xb0, 0xef, 0x7e, 0x24, 0x80, 0x00, 0x7e, 0x11, 0x2e, 0x7e, 0xa0, 0x08, 0x19, 0xa2, - 0x00, 0x10, 0x2e, 0x24, 0x01, 0x00, 0xa5, 0xd9, 0xf2, 0x7e, 0x20, 0x00, 0x12, 0x41, 0x83, 0x0b, - 0x20, 0xbe, 0x21, 0x2e, 0x78, 0xf6, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0x74, 0xbf, 0x19, - 0xb0, 0x00, 0x0c, 0x74, 0x10, 0x19, 0xb0, 0x00, 0x08, 0x74, 0x80, 0x19, 0xb0, 0x00, 0x0c, 0x7e, - 0x54, 0x00, 0x02, 0x19, 0xa0, 0x00, 0x04, 0x19, 0xb0, 0x00, 0x00, 0x74, 0x03, 0x19, 0xb0, 0x00, - 0x0c, 0x74, 0x07, 0x20, 0x68, 0x02, 0x74, 0x0f, 0x19, 0xb0, 0x00, 0x04, 0x30, 0x6b, 0x17, 0x74, - 0xbf, 0x19, 0xb0, 0x00, 0x0c, 0x74, 0x28, 0x20, 0x68, 0x02, 0x74, 0x20, 0x19, 0xb0, 0x00, 0x04, - 0x74, 0x03, 0x19, 0xb0, 0x00, 0x0c, 0x74, 0xa7, 0x19, 0xb0, 0x00, 0x08, 0x74, 0x0c, 0x19, 0xb0, - 0x00, 0x10, 0x22, 0x7e, 0x04, 0x80, 0x00, 0x4c, 0x02, 0xe4, 0x19, 0xb0, 0x00, 0x04, 0x09, 0xb0, - 0x00, 0x10, 0x54, 0x08, 0x19, 0xb0, 0x00, 0x10, 0x74, 0xa7, 0x19, 0xb0, 0x00, 0x08, 0x22, 0x7c, - 0xb2, 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x41, 0xaa, 0x89, 0x24, 0x41, 0xba, 0x41, 0xd7, 0x41, 0xf4, - 0x42, 0x11, 0x42, 0x2e, 0x42, 0x4b, 0x42, 0x68, 0x42, 0x85, 0xc2, 0x10, 0xc2, 0x18, 0xc2, 0x08, - 0x7e, 0x04, 0x04, 0x2d, 0x7a, 0x07, 0x01, 0x59, 0x7a, 0x07, 0x01, 0x69, 0x6d, 0x00, 0x7a, 0x07, - 0x01, 0x79, 0x7a, 0x07, 0x01, 0x89, 0x22, 0xc2, 0x11, 0xc2, 0x19, 0xc2, 0x09, 0x7e, 0x04, 0x08, - 0x2d, 0x7a, 0x07, 0x01, 0x5b, 0x7a, 0x07, 0x01, 0x6b, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x7b, 0x7a, - 0x07, 0x01, 0x8b, 0x22, 0xc2, 0x12, 0xc2, 0x1a, 0xc2, 0x0a, 0x7e, 0x04, 0x0c, 0x2d, 0x7a, 0x07, - 0x01, 0x5d, 0x7a, 0x07, 0x01, 0x6d, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x7d, 0x7a, 0x07, 0x01, 0x8d, - 0x22, 0xc2, 0x13, 0xc2, 0x1b, 0xc2, 0x0b, 0x7e, 0x04, 0x10, 0x2d, 0x7a, 0x07, 0x01, 0x5f, 0x7a, - 0x07, 0x01, 0x6f, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x7f, 0x7a, 0x07, 0x01, 0x8f, 0x22, 0xc2, 0x14, - 0xc2, 0x1c, 0xc2, 0x0c, 0x7e, 0x04, 0x14, 0x2d, 0x7a, 0x07, 0x01, 0x61, 0x7a, 0x07, 0x01, 0x71, - 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x81, 0x7a, 0x07, 0x01, 0x91, 0x22, 0xc2, 0x15, 0xc2, 0x1d, 0xc2, - 0x0d, 0x7e, 0x04, 0x18, 0x2d, 0x7a, 0x07, 0x01, 0x63, 0x7a, 0x07, 0x01, 0x73, 0x6d, 0x00, 0x7a, - 0x07, 0x01, 0x83, 0x7a, 0x07, 0x01, 0x93, 0x22, 0xc2, 0x16, 0xc2, 0x1e, 0xc2, 0x0e, 0x7e, 0x04, - 0x1c, 0x2d, 0x7a, 0x07, 0x01, 0x65, 0x7a, 0x07, 0x01, 0x75, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x85, - 0x7a, 0x07, 0x01, 0x95, 0x22, 0xc2, 0x17, 0xc2, 0x1f, 0xc2, 0x0f, 0x7e, 0x04, 0x20, 0x2d, 0x7a, - 0x07, 0x01, 0x67, 0x7a, 0x07, 0x01, 0x77, 0x6d, 0x00, 0x7a, 0x07, 0x01, 0x87, 0x7a, 0x07, 0x01, - 0x97, 0x22, 0x7c, 0xb2, 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x42, 0xad, 0x89, 0x24, 0x42, 0xbd, 0x42, - 0xd4, 0x42, 0xeb, 0x43, 0x02, 0x43, 0x19, 0x43, 0x30, 0x43, 0x47, 0x43, 0x5e, 0x30, 0x40, 0x07, - 0x20, 0x58, 0x04, 0xc2, 0x28, 0x80, 0x0c, 0x30, 0x48, 0x07, 0x20, 0x50, 0x04, 0xc2, 0x28, 0x80, - 0x02, 0xd2, 0x28, 0x22, 0x30, 0x41, 0x07, 0x20, 0x59, 0x04, 0xc2, 0x29, 0x80, 0x0c, 0x30, 0x49, - 0x07, 0x20, 0x51, 0x04, 0xc2, 0x29, 0x80, 0x02, 0xd2, 0x29, 0x22, 0x30, 0x42, 0x07, 0x20, 0x5a, - 0x04, 0xc2, 0x2a, 0x80, 0x0c, 0x30, 0x4a, 0x07, 0x20, 0x52, 0x04, 0xc2, 0x2a, 0x80, 0x02, 0xd2, - 0x2a, 0x22, 0x30, 0x43, 0x07, 0x20, 0x5b, 0x04, 0xc2, 0x2b, 0x80, 0x0c, 0x30, 0x4b, 0x07, 0x20, - 0x53, 0x04, 0xc2, 0x2b, 0x80, 0x02, 0xd2, 0x2b, 0x22, 0x30, 0x44, 0x07, 0x20, 0x5c, 0x04, 0xc2, - 0x2c, 0x80, 0x0c, 0x30, 0x4c, 0x07, 0x20, 0x54, 0x04, 0xc2, 0x2c, 0x80, 0x02, 0xd2, 0x2c, 0x22, - 0x30, 0x45, 0x07, 0x20, 0x5d, 0x04, 0xc2, 0x2d, 0x80, 0x0c, 0x30, 0x4d, 0x07, 0x20, 0x55, 0x04, - 0xc2, 0x2d, 0x80, 0x02, 0xd2, 0x2d, 0x22, 0x30, 0x46, 0x07, 0x20, 0x5e, 0x04, 0xc2, 0x2e, 0x80, - 0x0c, 0x30, 0x4e, 0x07, 0x20, 0x56, 0x04, 0xc2, 0x2e, 0x80, 0x02, 0xd2, 0x2e, 0x22, 0x30, 0x47, - 0x07, 0x20, 0x5f, 0x04, 0xc2, 0x2f, 0x80, 0x0c, 0x30, 0x4f, 0x07, 0x20, 0x57, 0x04, 0xc2, 0x2f, - 0x80, 0x02, 0xd2, 0x2f, 0x22, 0x44, 0x66, 0x43, 0x8a, 0xbe, 0xb0, 0x02, 0x40, 0x01, 0x22, 0x23, - 0x0a, 0x5b, 0x49, 0x55, 0x43, 0x75, 0x99, 0x54, 0xd3, 0x22, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x94, - 0x00, 0x7a, 0xb3, 0x2c, 0x35, 0x12, 0x44, 0x7a, 0x7e, 0x04, 0x28, 0x2d, 0x7a, 0x07, 0x01, 0xc1, - 0x7a, 0x07, 0x01, 0xc3, 0x7e, 0x04, 0x24, 0x2d, 0x7a, 0x07, 0x01, 0xc7, 0x7a, 0x07, 0x01, 0xc9, - 0x7e, 0x04, 0x66, 0x7f, 0x7a, 0x05, 0x4b, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, - 0xb3, 0x91, 0x1c, 0x74, 0x12, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x07, 0x74, - 0x1e, 0x7a, 0xb3, 0x91, 0x10, 0x74, 0x48, 0x7a, 0xb3, 0x91, 0x12, 0x74, 0x10, 0x7a, 0xb3, 0x91, - 0x13, 0x74, 0x3f, 0x7a, 0xb3, 0x91, 0x14, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, - 0xb3, 0x91, 0x1c, 0x74, 0x14, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x07, 0x74, - 0x16, 0x7a, 0xb3, 0x91, 0x10, 0x74, 0x08, 0x7a, 0xb3, 0x91, 0x11, 0x74, 0x20, 0x7a, 0xb3, 0x91, - 0x13, 0x74, 0x3f, 0x7a, 0xb3, 0x91, 0x14, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, - 0xb3, 0x91, 0x1c, 0x74, 0x16, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x07, 0x74, - 0x2f, 0x7a, 0xb3, 0x91, 0x10, 0x74, 0x48, 0x7a, 0xb3, 0x91, 0x12, 0x74, 0x10, 0x7a, 0xb3, 0x91, - 0x13, 0x74, 0x3f, 0x7a, 0xb3, 0x91, 0x14, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x06, 0x74, 0x0f, 0x7a, - 0xb3, 0x91, 0x07, 0x12, 0x40, 0xfa, 0x7e, 0x20, 0x00, 0x12, 0x41, 0x9f, 0x0b, 0x20, 0xbe, 0x21, - 0x2e, 0x78, 0xf6, 0xd2, 0xa8, 0x22, 0x7e, 0xb0, 0x01, 0x7a, 0xb3, 0x94, 0x00, 0x7a, 0xb3, 0x2c, - 0x35, 0x12, 0x44, 0x7a, 0x75, 0xb0, 0xdf, 0xc2, 0xa8, 0x22, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x06, - 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x07, 0x7e, 0x20, 0x04, 0x7c, 0xb2, 0xc2, 0xd7, 0x13, 0x13, 0x13, - 0x13, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x74, 0x02, 0x7a, 0xb3, 0x91, - 0x12, 0xa5, 0xda, 0xe5, 0x22, 0xca, 0x09, 0x12, 0x30, 0x0e, 0x10, 0x01, 0x34, 0xd5, 0x51, 0x40, - 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x06, 0x7e, 0xb3, 0x91, 0x07, - 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x7e, 0xb3, 0x91, 0x07, 0x7e, 0xb3, 0x91, 0x14, 0x7e, 0xb3, - 0x91, 0x04, 0x63, 0x53, 0x01, 0x7e, 0x00, 0x54, 0x2e, 0x01, 0x53, 0xa5, 0xe6, 0xf5, 0x51, 0x80, - 0x12, 0x20, 0x02, 0x1d, 0x75, 0x53, 0x00, 0x85, 0x54, 0x51, 0xd2, 0x02, 0x74, 0x03, 0x80, 0x0d, - 0x30, 0x02, 0x0e, 0xc2, 0x02, 0x7e, 0x00, 0x56, 0x2e, 0x01, 0x53, 0xa5, 0xe6, 0x7a, 0xb3, 0x90, - 0x00, 0xda, 0x09, 0x32, 0x45, 0x6f, 0x45, 0x8b, 0x45, 0xa7, 0x45, 0xc3, 0x45, 0xdf, 0x45, 0xfb, - 0x46, 0x17, 0x46, 0x33, 0xc0, 0xd0, 0xc0, 0xd1, 0xc0, 0xe0, 0xc0, 0xf0, 0xca, 0x0b, 0xca, 0x1b, - 0xca, 0x2b, 0xd2, 0x01, 0x75, 0x2f, 0x89, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x90, 0x00, 0x60, 0x28, - 0x7e, 0x14, 0x80, 0x00, 0x7e, 0x00, 0x00, 0x13, 0x50, 0x13, 0xca, 0x0b, 0xca, 0x59, 0x7c, 0xb0, - 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x45, 0x04, 0x99, 0x24, 0xda, 0x59, 0xda, 0x0b, 0xa5, 0x0a, 0xa5, - 0x08, 0xbe, 0x01, 0x2e, 0x78, 0xe1, 0x80, 0xd2, 0x30, 0x04, 0x05, 0xc2, 0x04, 0x12, 0x64, 0x86, - 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0xd0, 0xf0, 0xd0, 0xe0, 0xd0, 0xd1, 0xd0, 0xd0, 0x32, 0x09, - 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x14, 0x75, 0x2f, 0x80, 0x12, 0x73, 0x35, 0x54, 0x3e, 0x0a, 0x5b, - 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x61, 0xab, 0x89, 0x54, 0x22, 0x09, 0xb1, 0x00, 0x08, 0x20, - 0xe0, 0x14, 0x75, 0x2f, 0x81, 0x12, 0x73, 0x35, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, - 0x69, 0x52, 0x61, 0xeb, 0x89, 0x54, 0x22, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x14, 0x75, 0x2f, - 0x82, 0x12, 0x73, 0x35, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x62, 0x2b, - 0x89, 0x54, 0x22, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x14, 0x75, 0x2f, 0x83, 0x12, 0x73, 0x35, - 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x62, 0x6b, 0x89, 0x54, 0x22, 0x09, - 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x14, 0x75, 0x2f, 0x84, 0x12, 0x73, 0x35, 0x54, 0x3e, 0x0a, 0x5b, - 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x62, 0xab, 0x89, 0x54, 0x22, 0x09, 0xb1, 0x00, 0x08, 0x20, - 0xe0, 0x14, 0x75, 0x2f, 0x85, 0x12, 0x73, 0x35, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, - 0x69, 0x52, 0x62, 0xeb, 0x89, 0x54, 0x22, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x14, 0x75, 0x2f, - 0x86, 0x12, 0x73, 0x35, 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x63, 0x2b, - 0x89, 0x54, 0x22, 0x09, 0xb1, 0x00, 0x08, 0x20, 0xe0, 0x14, 0x75, 0x2f, 0x87, 0x12, 0x73, 0x35, - 0x54, 0x3e, 0x0a, 0x5b, 0x7e, 0x44, 0x00, 0xff, 0x69, 0x52, 0x63, 0x6b, 0x89, 0x54, 0x22, 0x10, - 0x08, 0x01, 0x22, 0x20, 0x28, 0x03, 0xd2, 0x08, 0x22, 0x75, 0x2f, 0xa0, 0x12, 0x73, 0x35, 0x7e, - 0x14, 0x80, 0x00, 0x80, 0x06, 0x20, 0x28, 0x03, 0xd2, 0x08, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, - 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x49, 0x45, 0x30, 0x30, 0x06, 0x20, 0xe6, - 0x4f, 0xd2, 0x08, 0x22, 0x30, 0xe6, 0x02, 0xd2, 0x60, 0x7e, 0x37, 0x01, 0x79, 0x7e, 0x27, 0x01, - 0x99, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x32, 0x7a, 0x05, 0x32, 0x7a, 0x37, 0x01, - 0x79, 0x7e, 0x37, 0x01, 0x59, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x08, 0x2c, 0x38, 0x68, 0x7a, - 0x47, 0x01, 0x59, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x12, - 0x69, 0xf0, 0x10, 0x60, 0xc4, 0x22, 0xc2, 0x60, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, - 0x7e, 0x27, 0x01, 0x79, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0x99, 0x28, 0x04, - 0x7e, 0x27, 0x01, 0x99, 0x7e, 0x37, 0x01, 0x79, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x32, 0x7a, - 0x05, 0x32, 0x7a, 0x37, 0x01, 0x79, 0x7e, 0x37, 0x01, 0x59, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, - 0x08, 0x2c, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x59, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, - 0x2f, 0x12, 0x73, 0x35, 0x02, 0x69, 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, - 0x12, 0x73, 0x35, 0x9e, 0x44, 0x08, 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x04, 0x2d, - 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x59, 0x12, 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, 0x03, - 0x02, 0x46, 0xc2, 0x22, 0xd2, 0x08, 0x7e, 0x04, 0x04, 0x2d, 0x7a, 0x07, 0x01, 0x59, 0x7a, 0x07, - 0x01, 0x69, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, 0x75, - 0x2f, 0x92, 0x12, 0x73, 0x35, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, - 0xb8, 0x78, 0x68, 0x7e, 0x37, 0x01, 0xcb, 0x7e, 0x27, 0x01, 0xa9, 0x2e, 0x24, 0x00, 0x02, 0x2d, - 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, 0x7a, - 0x37, 0x01, 0xcb, 0x7e, 0x37, 0x01, 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, 0x38, - 0x3c, 0x7a, 0x47, 0x01, 0xc9, 0x7e, 0x24, 0x00, 0x00, 0x2e, 0x27, 0x01, 0xa9, 0x1b, 0x38, 0x20, - 0x0b, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, 0x73, - 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x38, 0x0a, 0x09, 0xb1, - 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x10, 0x22, 0x80, 0x7f, 0x7a, 0x51, 0x2f, - 0x12, 0x73, 0x35, 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x00, 0x00, 0x2e, 0x67, 0x01, - 0xa9, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, 0x7e, - 0x34, 0x24, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, 0x39, - 0xc0, 0x7e, 0x34, 0x24, 0x2d, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, - 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x00, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, - 0x35, 0x75, 0x2f, 0x93, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, 0x68, - 0x2b, 0x7a, 0x07, 0x01, 0xc9, 0x7e, 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, 0x2e, - 0x35, 0x30, 0x7a, 0x35, 0x30, 0x22, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, - 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x28, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, 0x2d, - 0x80, 0xcf, 0x7e, 0x07, 0x01, 0xcb, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, - 0x01, 0xc9, 0x7e, 0x44, 0x28, 0x2d, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, 0x70, - 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, - 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, - 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x48, 0x1e, 0x75, 0x2f, - 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x38, - 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x10, 0x22, 0xda, 0xb8, - 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x48, 0x1e, 0xda, 0xb8, 0x02, 0x49, - 0x45, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, - 0x12, 0x73, 0x35, 0xa5, 0xfd, 0x5e, 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, - 0x04, 0xd2, 0x58, 0x80, 0x02, 0xc2, 0x58, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x50, - 0x80, 0x02, 0xc2, 0x50, 0x12, 0x42, 0xbd, 0x02, 0x61, 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, 0x35, - 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, - 0xa0, 0x80, 0x02, 0x61, 0x13, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, 0x13, - 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, - 0x12, 0x61, 0x36, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x48, 0x72, 0x75, 0x2f, - 0x95, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, 0x10, 0x09, 0x01, 0x22, - 0x20, 0x29, 0x03, 0xd2, 0x09, 0x22, 0x75, 0x2f, 0xa1, 0x12, 0x73, 0x35, 0x7e, 0x14, 0x81, 0x00, - 0x80, 0x06, 0x20, 0x29, 0x03, 0xd2, 0x09, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, - 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x4c, 0x72, 0x30, 0x31, 0x06, 0x20, 0xe6, 0x4f, 0xd2, 0x09, - 0x22, 0x30, 0xe6, 0x02, 0xd2, 0x61, 0x7e, 0x37, 0x01, 0x7b, 0x7e, 0x27, 0x01, 0x9b, 0x9d, 0x32, - 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x34, 0x7a, 0x05, 0x34, 0x7a, 0x37, 0x01, 0x7b, 0x7e, 0x37, - 0x01, 0x5b, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x0c, 0x2c, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x5b, - 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x69, 0xf0, 0x10, - 0x61, 0xc4, 0x22, 0xc2, 0x61, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, - 0x7b, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0x9b, 0x28, 0x04, 0x7e, 0x27, 0x01, - 0x9b, 0x7e, 0x37, 0x01, 0x7b, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x34, 0x7a, 0x05, 0x34, 0x7a, - 0x37, 0x01, 0x7b, 0x7e, 0x37, 0x01, 0x5b, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x0c, 0x2c, 0x38, - 0x13, 0x7a, 0x47, 0x01, 0x5b, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, - 0x35, 0x02, 0x69, 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, - 0x9e, 0x44, 0x0c, 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x08, 0x2d, 0x7d, 0x24, 0x2d, - 0x43, 0x7a, 0x47, 0x01, 0x5b, 0x12, 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x49, 0xef, - 0x22, 0xd2, 0x09, 0x7e, 0x04, 0x08, 0x2d, 0x7a, 0x07, 0x01, 0x5b, 0x7a, 0x07, 0x01, 0x6b, 0x75, - 0x2f, 0x94, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x92, 0x12, - 0x73, 0x35, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x68, - 0x7e, 0x37, 0x01, 0xcb, 0x7e, 0x27, 0x01, 0xab, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, - 0x04, 0x00, 0x38, 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, 0x7a, 0x37, 0x01, 0xcb, - 0x7e, 0x37, 0x01, 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, 0x38, 0x3c, 0x7a, 0x47, - 0x01, 0xc9, 0x7e, 0x24, 0x01, 0x00, 0x2e, 0x27, 0x01, 0xab, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, - 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, - 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x39, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, - 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x11, 0x22, 0x80, 0x7f, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, - 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x01, 0x00, 0x2e, 0x67, 0x01, 0xab, 0x9e, 0x24, - 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, 0x7e, 0x34, 0x24, 0x2d, - 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, 0x39, 0xc0, 0x7e, 0x34, - 0x24, 0x2d, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, - 0x0f, 0x23, 0x23, 0x23, 0x44, 0x01, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x2f, - 0x93, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, 0x68, 0x2b, 0x7a, 0x07, - 0x01, 0xc9, 0x7e, 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, 0x2e, 0x35, 0x30, 0x7a, - 0x35, 0x30, 0x22, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x24, - 0x2d, 0x80, 0x28, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xcf, 0x7e, - 0x07, 0x01, 0xcb, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xc9, 0x7e, - 0x44, 0x28, 0x2d, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, 0x70, 0x0b, 0x04, 0xbd, - 0x04, 0x68, 0xd0, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, - 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, - 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x4b, 0x4b, 0x75, 0x2f, 0x99, 0x12, 0x73, - 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x39, 0x0a, 0x09, 0xb1, - 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x11, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, - 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x4b, 0x4b, 0xda, 0xb8, 0x02, 0x4c, 0x72, 0x09, 0xb1, - 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, 0x12, 0x73, 0x35, - 0xa5, 0xfd, 0x5e, 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x59, - 0x80, 0x02, 0xc2, 0x59, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x51, 0x80, 0x02, 0xc2, - 0x51, 0x12, 0x42, 0xd4, 0x02, 0x61, 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, - 0x14, 0x7a, 0xb1, 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, - 0x61, 0x13, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, 0x13, 0xca, 0xb8, 0x5e, - 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x61, 0x36, - 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x4b, 0x9f, 0x75, 0x2f, 0x95, 0x12, 0x73, - 0x35, 0x22, 0x75, 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, 0x10, 0x0a, 0x01, 0x22, 0x20, 0x2a, 0x03, - 0xd2, 0x0a, 0x22, 0x75, 0x2f, 0xa2, 0x12, 0x73, 0x35, 0x7e, 0x14, 0x82, 0x00, 0x80, 0x06, 0x20, - 0x2a, 0x03, 0xd2, 0x0a, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, - 0x68, 0x03, 0x12, 0x4f, 0x9f, 0x30, 0x32, 0x06, 0x20, 0xe6, 0x4f, 0xd2, 0x0a, 0x22, 0x30, 0xe6, - 0x02, 0xd2, 0x62, 0x7e, 0x37, 0x01, 0x7d, 0x7e, 0x27, 0x01, 0x9d, 0x9d, 0x32, 0x40, 0x31, 0x7d, - 0x02, 0x2e, 0x05, 0x36, 0x7a, 0x05, 0x36, 0x7a, 0x37, 0x01, 0x7d, 0x7e, 0x37, 0x01, 0x5d, 0x7d, - 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x10, 0x2c, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x5d, 0x75, 0x2f, 0x94, - 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x69, 0xf0, 0x10, 0x62, 0xc4, 0x22, - 0xc2, 0x62, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x7d, 0xbe, 0x24, - 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0x9d, 0x28, 0x04, 0x7e, 0x27, 0x01, 0x9d, 0x7e, 0x37, - 0x01, 0x7d, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x36, 0x7a, 0x05, 0x36, 0x7a, 0x37, 0x01, 0x7d, - 0x7e, 0x37, 0x01, 0x5d, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x10, 0x2c, 0x38, 0x13, 0x7a, 0x47, - 0x01, 0x5d, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x69, - 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x10, - 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x0c, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, - 0x01, 0x5d, 0x12, 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x4d, 0x1c, 0x22, 0xd2, 0x0a, - 0x7e, 0x04, 0x0c, 0x2d, 0x7a, 0x07, 0x01, 0x5d, 0x7a, 0x07, 0x01, 0x6d, 0x75, 0x2f, 0x94, 0x12, - 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x92, 0x12, 0x73, 0x35, 0xd2, - 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x68, 0x7e, 0x37, 0x01, - 0xcb, 0x7e, 0x27, 0x01, 0xad, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, - 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, 0x7a, 0x37, 0x01, 0xcb, 0x7e, 0x37, 0x01, - 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, 0x38, 0x3c, 0x7a, 0x47, 0x01, 0xc9, 0x7e, - 0x24, 0x02, 0x00, 0x2e, 0x27, 0x01, 0xad, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x2f, 0x12, - 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, - 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3a, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, - 0x00, 0x10, 0xd2, 0x12, 0x22, 0x80, 0x7f, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x28, - 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x02, 0x00, 0x2e, 0x67, 0x01, 0xad, 0x9e, 0x24, 0x00, 0x02, 0x40, - 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, 0x7e, 0x34, 0x24, 0x2d, 0x7d, 0x24, 0x2d, - 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x24, 0x2d, 0x7a, - 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, - 0x23, 0x44, 0x02, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x2f, 0x93, 0x12, 0x73, - 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, 0x68, 0x2b, 0x7a, 0x07, 0x01, 0xc9, 0x7e, - 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, 0x2e, 0x35, 0x30, 0x7a, 0x35, 0x30, 0x22, - 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x28, - 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xcf, 0x7e, 0x07, 0x01, 0xcb, - 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xc9, 0x7e, 0x44, 0x28, 0x2d, - 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, - 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, - 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, - 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x4e, 0x78, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, - 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3a, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, - 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x12, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, - 0x07, 0xca, 0xb8, 0x12, 0x4e, 0x78, 0xda, 0xb8, 0x02, 0x4f, 0x9f, 0x09, 0xb1, 0x00, 0x18, 0x7e, - 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, 0x12, 0x73, 0x35, 0xa5, 0xfd, 0x5e, - 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5a, 0x80, 0x02, 0xc2, - 0x5a, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x52, 0x80, 0x02, 0xc2, 0x52, 0x12, 0x42, - 0xeb, 0x02, 0x61, 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, - 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x61, 0x13, 0xd2, - 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, 0x13, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, - 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x61, 0x36, 0x09, 0xb1, 0x00, - 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x4e, 0xcc, 0x75, 0x2f, 0x95, 0x12, 0x73, 0x35, 0x22, 0x75, - 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, 0x10, 0x0b, 0x01, 0x22, 0x20, 0x2b, 0x03, 0xd2, 0x0b, 0x22, - 0x75, 0x2f, 0xa3, 0x12, 0x73, 0x35, 0x7e, 0x14, 0x83, 0x00, 0x80, 0x06, 0x20, 0x2b, 0x03, 0xd2, - 0x0b, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, - 0x52, 0xcc, 0x30, 0x33, 0x06, 0x20, 0xe6, 0x4f, 0xd2, 0x0b, 0x22, 0x30, 0xe6, 0x02, 0xd2, 0x63, - 0x7e, 0x37, 0x01, 0x7f, 0x7e, 0x27, 0x01, 0x9f, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, - 0x38, 0x7a, 0x05, 0x38, 0x7a, 0x37, 0x01, 0x7f, 0x7e, 0x37, 0x01, 0x5f, 0x7d, 0x43, 0x2d, 0x42, - 0xbe, 0x44, 0x14, 0x2c, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x5f, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, - 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x69, 0xf0, 0x10, 0x63, 0xc4, 0x22, 0xc2, 0x63, 0x2d, - 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x7f, 0xbe, 0x24, 0x00, 0x00, 0x68, - 0x6a, 0xbe, 0x27, 0x01, 0x9f, 0x28, 0x04, 0x7e, 0x27, 0x01, 0x9f, 0x7e, 0x37, 0x01, 0x7f, 0x9d, - 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x38, 0x7a, 0x05, 0x38, 0x7a, 0x37, 0x01, 0x7f, 0x7e, 0x37, 0x01, - 0x5f, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x14, 0x2c, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x5f, 0x75, - 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x69, 0xf0, 0x75, 0x2f, - 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x14, 0x2d, 0x9d, 0x24, - 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x10, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x5f, 0x12, - 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x50, 0x49, 0x22, 0xd2, 0x0b, 0x7e, 0x04, 0x10, - 0x2d, 0x7a, 0x07, 0x01, 0x5f, 0x7a, 0x07, 0x01, 0x6f, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x75, - 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x92, 0x12, 0x73, 0x35, 0xd2, 0x04, 0x09, 0xb1, - 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x68, 0x7e, 0x37, 0x01, 0xcb, 0x7e, 0x27, - 0x01, 0xaf, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x34, 0x7d, 0x02, - 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, 0x7a, 0x37, 0x01, 0xcb, 0x7e, 0x37, 0x01, 0xc9, 0x7d, 0x43, - 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, 0x38, 0x3c, 0x7a, 0x47, 0x01, 0xc9, 0x7e, 0x24, 0x03, 0x00, - 0x2e, 0x27, 0x01, 0xaf, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, - 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, - 0x00, 0x04, 0x30, 0x3b, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, - 0x13, 0x22, 0x80, 0x7f, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x24, - 0x7e, 0x64, 0x03, 0x00, 0x2e, 0x67, 0x01, 0xaf, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, - 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, 0x7e, 0x34, 0x24, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, - 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x24, 0x2d, 0x7a, 0x39, 0xd0, 0x0b, - 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x03, - 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x2f, 0x93, 0x12, 0x73, 0x35, 0x7a, 0x71, - 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, 0x68, 0x2b, 0x7a, 0x07, 0x01, 0xc9, 0x7e, 0x47, 0x01, 0xcb, - 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, 0x2e, 0x35, 0x30, 0x7a, 0x35, 0x30, 0x22, 0xd2, 0x04, 0x09, - 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x28, 0x7e, 0x04, 0x24, - 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xcf, 0x7e, 0x07, 0x01, 0xcb, 0x7e, 0x24, 0x03, - 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xc9, 0x7e, 0x44, 0x28, 0x2d, 0x7d, 0x60, 0x0b, - 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x54, 0x9d, - 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, - 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, - 0x78, 0xe7, 0x02, 0x51, 0xa5, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, - 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3b, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, - 0x00, 0x10, 0xd2, 0x13, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, - 0x12, 0x51, 0xa5, 0xda, 0xb8, 0x02, 0x52, 0xcc, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, - 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, 0x12, 0x73, 0x35, 0xa5, 0xfd, 0x5e, 0x50, 0x0a, 0x68, - 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5b, 0x80, 0x02, 0xc2, 0x5b, 0xa5, 0xfd, - 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x53, 0x80, 0x02, 0xc2, 0x53, 0x12, 0x43, 0x02, 0x02, 0x61, - 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x2f, 0x12, 0x73, - 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x61, 0x13, 0xd2, 0x04, 0x30, 0xe1, - 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, 0x13, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, - 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x61, 0x36, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, - 0xdb, 0x22, 0x02, 0x51, 0xf9, 0x75, 0x2f, 0x95, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x96, 0x12, - 0x73, 0x35, 0x22, 0x10, 0x0c, 0x01, 0x22, 0x20, 0x2c, 0x03, 0xd2, 0x0c, 0x22, 0x75, 0x2f, 0xa4, - 0x12, 0x73, 0x35, 0x7e, 0x14, 0x84, 0x00, 0x80, 0x06, 0x20, 0x2c, 0x03, 0xd2, 0x0c, 0x22, 0x09, - 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x55, 0xf9, 0x30, - 0x34, 0x06, 0x20, 0xe6, 0x4f, 0xd2, 0x0c, 0x22, 0x30, 0xe6, 0x02, 0xd2, 0x64, 0x7e, 0x37, 0x01, - 0x81, 0x7e, 0x27, 0x01, 0xa1, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x3a, 0x7a, 0x05, - 0x3a, 0x7a, 0x37, 0x01, 0x81, 0x7e, 0x37, 0x01, 0x61, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x18, - 0x2c, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x61, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, - 0x12, 0x73, 0x35, 0x12, 0x69, 0xf0, 0x10, 0x64, 0xc4, 0x22, 0xc2, 0x64, 0x2d, 0x23, 0x68, 0x78, - 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x81, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, - 0x01, 0xa1, 0x28, 0x04, 0x7e, 0x27, 0x01, 0xa1, 0x7e, 0x37, 0x01, 0x81, 0x9d, 0x32, 0x7d, 0x02, - 0x2e, 0x05, 0x3a, 0x7a, 0x05, 0x3a, 0x7a, 0x37, 0x01, 0x81, 0x7e, 0x37, 0x01, 0x61, 0x7d, 0x43, - 0x2d, 0x42, 0xbe, 0x44, 0x18, 0x2c, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x61, 0x75, 0x2f, 0x94, 0x12, - 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x69, 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, - 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x18, 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, - 0x7e, 0x34, 0x14, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x61, 0x12, 0x69, 0xf0, 0xbe, - 0x25, 0x20, 0x78, 0x03, 0x02, 0x53, 0x76, 0x22, 0xd2, 0x0c, 0x7e, 0x04, 0x14, 0x2d, 0x7a, 0x07, - 0x01, 0x61, 0x7a, 0x07, 0x01, 0x71, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, - 0x73, 0x35, 0x22, 0x75, 0x2f, 0x92, 0x12, 0x73, 0x35, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, - 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x68, 0x7e, 0x37, 0x01, 0xcb, 0x7e, 0x27, 0x01, 0xb1, 0x2e, - 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, - 0x7a, 0x05, 0x30, 0x7a, 0x37, 0x01, 0xcb, 0x7e, 0x37, 0x01, 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, - 0x44, 0x28, 0x2c, 0x38, 0x3c, 0x7a, 0x47, 0x01, 0xc9, 0x7e, 0x24, 0x04, 0x00, 0x2e, 0x27, 0x01, - 0xb1, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, - 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, - 0x3c, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x14, 0x22, 0x80, - 0x7f, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x04, - 0x00, 0x2e, 0x67, 0x01, 0xb1, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, - 0x12, 0x6a, 0x63, 0x7e, 0x34, 0x24, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, - 0x6a, 0x63, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x24, 0x2d, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, - 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x04, 0x7a, 0x69, 0xb0, - 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x2f, 0x93, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, - 0x35, 0xbd, 0x04, 0x68, 0x2b, 0x7a, 0x07, 0x01, 0xc9, 0x7e, 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, - 0x47, 0x01, 0xcb, 0x2e, 0x35, 0x30, 0x7a, 0x35, 0x30, 0x22, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, - 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x28, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, - 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xcf, 0x7e, 0x07, 0x01, 0xcb, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, - 0x28, 0x40, 0x7e, 0x07, 0x01, 0xc9, 0x7e, 0x44, 0x28, 0x2d, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, - 0x68, 0xd2, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, - 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, - 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, - 0x54, 0xd2, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, - 0x00, 0x04, 0x30, 0x3c, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, - 0x14, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x54, 0xd2, - 0xda, 0xb8, 0x02, 0x55, 0xf9, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, - 0x73, 0x35, 0xf5, 0x2f, 0x12, 0x73, 0x35, 0xa5, 0xfd, 0x5e, 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, - 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5c, 0x80, 0x02, 0xc2, 0x5c, 0xa5, 0xfd, 0x5e, 0x50, 0x80, - 0x68, 0x04, 0xd2, 0x54, 0x80, 0x02, 0xc2, 0x54, 0x12, 0x43, 0x19, 0x02, 0x61, 0x13, 0x75, 0x2f, - 0x91, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, - 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x61, 0x13, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, - 0x80, 0x12, 0x61, 0x13, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, - 0x09, 0x61, 0x00, 0x00, 0x12, 0x61, 0x36, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, - 0x55, 0x26, 0x75, 0x2f, 0x95, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, - 0x10, 0x0d, 0x01, 0x22, 0x20, 0x2d, 0x03, 0xd2, 0x0d, 0x22, 0x75, 0x2f, 0xa5, 0x12, 0x73, 0x35, - 0x7e, 0x14, 0x85, 0x00, 0x80, 0x06, 0x20, 0x2d, 0x03, 0xd2, 0x0d, 0x22, 0x09, 0xb1, 0x00, 0x14, - 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x59, 0x26, 0x30, 0x35, 0x06, 0x20, - 0xe6, 0x4f, 0xd2, 0x0d, 0x22, 0x30, 0xe6, 0x02, 0xd2, 0x65, 0x7e, 0x37, 0x01, 0x83, 0x7e, 0x27, - 0x01, 0xa3, 0x9d, 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x3c, 0x7a, 0x05, 0x3c, 0x7a, 0x37, - 0x01, 0x83, 0x7e, 0x37, 0x01, 0x63, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x1c, 0x2c, 0x38, 0x68, - 0x7a, 0x47, 0x01, 0x63, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, - 0x12, 0x69, 0xf0, 0x10, 0x65, 0xc4, 0x22, 0xc2, 0x65, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, - 0x1a, 0x7e, 0x27, 0x01, 0x83, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xa3, 0x28, - 0x04, 0x7e, 0x27, 0x01, 0xa3, 0x7e, 0x37, 0x01, 0x83, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x3c, - 0x7a, 0x05, 0x3c, 0x7a, 0x37, 0x01, 0x83, 0x7e, 0x37, 0x01, 0x63, 0x7d, 0x43, 0x2d, 0x42, 0xbe, - 0x44, 0x1c, 0x2c, 0x38, 0x13, 0x7a, 0x47, 0x01, 0x63, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, - 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x69, 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, - 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x1c, 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x18, - 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x63, 0x12, 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, - 0x03, 0x02, 0x56, 0xa3, 0x22, 0xd2, 0x0d, 0x7e, 0x04, 0x18, 0x2d, 0x7a, 0x07, 0x01, 0x63, 0x7a, - 0x07, 0x01, 0x73, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, - 0x75, 0x2f, 0x92, 0x12, 0x73, 0x35, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, - 0xda, 0xb8, 0x78, 0x68, 0x7e, 0x37, 0x01, 0xcb, 0x7e, 0x27, 0x01, 0xb3, 0x2e, 0x24, 0x00, 0x02, - 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, - 0x7a, 0x37, 0x01, 0xcb, 0x7e, 0x37, 0x01, 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, - 0x38, 0x3c, 0x7a, 0x47, 0x01, 0xc9, 0x7e, 0x24, 0x05, 0x00, 0x2e, 0x27, 0x01, 0xb3, 0x1b, 0x38, - 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, - 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3d, 0x0a, 0x09, - 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x15, 0x22, 0x80, 0x7f, 0x7a, 0x51, - 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x05, 0x00, 0x2e, 0x67, - 0x01, 0xb3, 0x9e, 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, - 0x7e, 0x34, 0x24, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, - 0x39, 0xc0, 0x7e, 0x34, 0x24, 0x2d, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, - 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x05, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, - 0x0b, 0x35, 0x75, 0x2f, 0x93, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, - 0x68, 0x2b, 0x7a, 0x07, 0x01, 0xc9, 0x7e, 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, - 0x2e, 0x35, 0x30, 0x7a, 0x35, 0x30, 0x22, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, - 0x22, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x28, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, - 0x2d, 0x80, 0xcf, 0x7e, 0x07, 0x01, 0xcb, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, - 0x07, 0x01, 0xc9, 0x7e, 0x44, 0x28, 0x2d, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, - 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, - 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, - 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x57, 0xff, 0x75, - 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, - 0x3d, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x15, 0x22, 0xda, - 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x57, 0xff, 0xda, 0xb8, 0x02, - 0x59, 0x26, 0x09, 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, - 0x2f, 0x12, 0x73, 0x35, 0xa5, 0xfd, 0x5e, 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, - 0x68, 0x04, 0xd2, 0x5d, 0x80, 0x02, 0xc2, 0x5d, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, - 0x55, 0x80, 0x02, 0xc2, 0x55, 0x12, 0x43, 0x30, 0x02, 0x61, 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, - 0x35, 0x09, 0xb1, 0x00, 0x14, 0x7a, 0xb1, 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, - 0x7e, 0xa0, 0x80, 0x02, 0x61, 0x13, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, - 0x13, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, - 0x00, 0x12, 0x61, 0x36, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x58, 0x53, 0x75, - 0x2f, 0x95, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, 0x10, 0x0e, 0x01, - 0x22, 0x20, 0x2e, 0x03, 0xd2, 0x0e, 0x22, 0x75, 0x2f, 0xa6, 0x12, 0x73, 0x35, 0x7e, 0x14, 0x86, - 0x00, 0x80, 0x06, 0x20, 0x2e, 0x03, 0xd2, 0x0e, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, - 0xb0, 0x1e, 0xda, 0xb8, 0x68, 0x03, 0x12, 0x5c, 0x53, 0x30, 0x36, 0x06, 0x20, 0xe6, 0x4f, 0xd2, - 0x0e, 0x22, 0x30, 0xe6, 0x02, 0xd2, 0x66, 0x7e, 0x37, 0x01, 0x85, 0x7e, 0x27, 0x01, 0xa5, 0x9d, - 0x32, 0x40, 0x31, 0x7d, 0x02, 0x2e, 0x05, 0x3e, 0x7a, 0x05, 0x3e, 0x7a, 0x37, 0x01, 0x85, 0x7e, - 0x37, 0x01, 0x65, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x20, 0x2c, 0x38, 0x68, 0x7a, 0x47, 0x01, - 0x65, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x69, 0xf0, - 0x10, 0x66, 0xc4, 0x22, 0xc2, 0x66, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, - 0x01, 0x85, 0xbe, 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xa5, 0x28, 0x04, 0x7e, 0x27, - 0x01, 0xa5, 0x7e, 0x37, 0x01, 0x85, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x3e, 0x7a, 0x05, 0x3e, - 0x7a, 0x37, 0x01, 0x85, 0x7e, 0x37, 0x01, 0x65, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x20, 0x2c, - 0x38, 0x13, 0x7a, 0x47, 0x01, 0x65, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, - 0x73, 0x35, 0x02, 0x69, 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, - 0x35, 0x9e, 0x44, 0x20, 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x1c, 0x2d, 0x7d, 0x24, - 0x2d, 0x43, 0x7a, 0x47, 0x01, 0x65, 0x12, 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x59, - 0xd0, 0x22, 0xd2, 0x0e, 0x7e, 0x04, 0x1c, 0x2d, 0x7a, 0x07, 0x01, 0x65, 0x7a, 0x07, 0x01, 0x75, - 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x92, - 0x12, 0x73, 0x35, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, - 0x68, 0x7e, 0x37, 0x01, 0xcb, 0x7e, 0x27, 0x01, 0xb5, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, - 0x34, 0x04, 0x00, 0x38, 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, 0x7a, 0x37, 0x01, - 0xcb, 0x7e, 0x37, 0x01, 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, 0x38, 0x3c, 0x7a, - 0x47, 0x01, 0xc9, 0x7e, 0x24, 0x06, 0x00, 0x2e, 0x27, 0x01, 0xb5, 0x1b, 0x38, 0x20, 0x0b, 0x35, - 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, - 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3e, 0x0a, 0x09, 0xb1, 0x00, 0x10, - 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x16, 0x22, 0x80, 0x7f, 0x7a, 0x51, 0x2f, 0x12, 0x73, - 0x35, 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x06, 0x00, 0x2e, 0x67, 0x01, 0xb5, 0x9e, - 0x24, 0x00, 0x02, 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, 0x7e, 0x34, 0x24, - 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, 0x39, 0xc0, 0x7e, - 0x34, 0x24, 0x2d, 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, - 0x54, 0x0f, 0x23, 0x23, 0x23, 0x44, 0x06, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, - 0x2f, 0x93, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, 0x68, 0x2b, 0x7a, - 0x07, 0x01, 0xc9, 0x7e, 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, 0x2e, 0x35, 0x30, - 0x7a, 0x35, 0x30, 0x22, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, - 0x24, 0x2d, 0x80, 0x28, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xcf, - 0x7e, 0x07, 0x01, 0xcb, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xc9, - 0x7e, 0x44, 0x28, 0x2d, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, 0x70, 0x0b, 0x04, - 0xbd, 0x04, 0x68, 0xd0, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, - 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, - 0x7a, 0x09, 0xb0, 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x5b, 0x2c, 0x75, 0x2f, 0x99, 0x12, - 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3e, 0x0a, 0x09, - 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x16, 0x22, 0xda, 0xb8, 0x30, 0xe0, - 0xd8, 0xbd, 0x32, 0x68, 0x07, 0xca, 0xb8, 0x12, 0x5b, 0x2c, 0xda, 0xb8, 0x02, 0x5c, 0x53, 0x09, - 0xb1, 0x00, 0x18, 0x7e, 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, 0x12, 0x73, - 0x35, 0xa5, 0xfd, 0x5e, 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, - 0x5e, 0x80, 0x02, 0xc2, 0x5e, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x56, 0x80, 0x02, - 0xc2, 0x56, 0x12, 0x43, 0x47, 0x02, 0x61, 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, 0x35, 0x09, 0xb1, - 0x00, 0x14, 0x7a, 0xb1, 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, - 0x02, 0x61, 0x13, 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, 0x13, 0xca, 0xb8, - 0x5e, 0xb0, 0x1c, 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x61, - 0x36, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x5b, 0x80, 0x75, 0x2f, 0x95, 0x12, - 0x73, 0x35, 0x22, 0x75, 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, 0x10, 0x0f, 0x01, 0x22, 0x20, 0x2f, - 0x03, 0xd2, 0x0f, 0x22, 0x75, 0x2f, 0xa7, 0x12, 0x73, 0x35, 0x7e, 0x14, 0x87, 0x00, 0x80, 0x06, - 0x20, 0x2f, 0x03, 0xd2, 0x0f, 0x22, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x5e, 0xb0, 0x1e, 0xda, - 0xb8, 0x68, 0x03, 0x12, 0x5f, 0x80, 0x30, 0x37, 0x06, 0x20, 0xe6, 0x4f, 0xd2, 0x0f, 0x22, 0x30, - 0xe6, 0x02, 0xd2, 0x67, 0x7e, 0x37, 0x01, 0x87, 0x7e, 0x27, 0x01, 0xa7, 0x9d, 0x32, 0x40, 0x31, - 0x7d, 0x02, 0x2e, 0x05, 0x40, 0x7a, 0x05, 0x40, 0x7a, 0x37, 0x01, 0x87, 0x7e, 0x37, 0x01, 0x67, - 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x24, 0x2c, 0x38, 0x68, 0x7a, 0x47, 0x01, 0x67, 0x75, 0x2f, - 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x69, 0xf0, 0x10, 0x67, 0xc4, - 0x22, 0xc2, 0x67, 0x2d, 0x23, 0x68, 0x78, 0x6d, 0x33, 0x80, 0x1a, 0x7e, 0x27, 0x01, 0x87, 0xbe, - 0x24, 0x00, 0x00, 0x68, 0x6a, 0xbe, 0x27, 0x01, 0xa7, 0x28, 0x04, 0x7e, 0x27, 0x01, 0xa7, 0x7e, - 0x37, 0x01, 0x87, 0x9d, 0x32, 0x7d, 0x02, 0x2e, 0x05, 0x40, 0x7a, 0x05, 0x40, 0x7a, 0x37, 0x01, - 0x87, 0x7e, 0x37, 0x01, 0x67, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x24, 0x2c, 0x38, 0x13, 0x7a, - 0x47, 0x01, 0x67, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x02, - 0x69, 0xf0, 0x75, 0x2f, 0x94, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, - 0x24, 0x2d, 0x9d, 0x24, 0x12, 0x69, 0xf0, 0x7e, 0x34, 0x20, 0x2d, 0x7d, 0x24, 0x2d, 0x43, 0x7a, - 0x47, 0x01, 0x67, 0x12, 0x69, 0xf0, 0xbe, 0x25, 0x20, 0x78, 0x03, 0x02, 0x5c, 0xfd, 0x22, 0xd2, - 0x0f, 0x7e, 0x04, 0x20, 0x2d, 0x7a, 0x07, 0x01, 0x67, 0x7a, 0x07, 0x01, 0x77, 0x75, 0x2f, 0x94, - 0x12, 0x73, 0x35, 0x75, 0x2f, 0x00, 0x12, 0x73, 0x35, 0x22, 0x75, 0x2f, 0x92, 0x12, 0x73, 0x35, - 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0xca, 0xb8, 0x54, 0x82, 0xda, 0xb8, 0x78, 0x68, 0x7e, 0x37, - 0x01, 0xcb, 0x7e, 0x27, 0x01, 0xb7, 0x2e, 0x24, 0x00, 0x02, 0x2d, 0x32, 0xbe, 0x34, 0x04, 0x00, - 0x38, 0x34, 0x7d, 0x02, 0x2e, 0x05, 0x30, 0x7a, 0x05, 0x30, 0x7a, 0x37, 0x01, 0xcb, 0x7e, 0x37, - 0x01, 0xc9, 0x7d, 0x43, 0x2d, 0x42, 0xbe, 0x44, 0x28, 0x2c, 0x38, 0x3c, 0x7a, 0x47, 0x01, 0xc9, - 0x7e, 0x24, 0x07, 0x00, 0x2e, 0x27, 0x01, 0xb7, 0x1b, 0x38, 0x20, 0x0b, 0x35, 0x7a, 0x51, 0x2f, - 0x12, 0x73, 0x35, 0x02, 0x6a, 0x63, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x04, - 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3f, 0x0a, 0x09, 0xb1, 0x00, 0x10, 0x54, 0xfe, 0x19, - 0xb1, 0x00, 0x10, 0xd2, 0x17, 0x22, 0x80, 0x7f, 0x7a, 0x51, 0x2f, 0x12, 0x73, 0x35, 0x9e, 0x44, - 0x28, 0x2d, 0x9d, 0x24, 0x7e, 0x64, 0x07, 0x00, 0x2e, 0x67, 0x01, 0xb7, 0x9e, 0x24, 0x00, 0x02, - 0x40, 0x17, 0x1b, 0x38, 0x60, 0x0b, 0x35, 0x12, 0x6a, 0x63, 0x7e, 0x34, 0x24, 0x2d, 0x7d, 0x24, - 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc9, 0x02, 0x6a, 0x63, 0x7a, 0x39, 0xc0, 0x7e, 0x34, 0x24, 0x2d, - 0x7a, 0x39, 0xd0, 0x0b, 0x34, 0x1b, 0x44, 0x80, 0xe5, 0x9d, 0x32, 0x7c, 0xb6, 0x54, 0x0f, 0x23, - 0x23, 0x23, 0x44, 0x07, 0x7a, 0x69, 0xb0, 0x7a, 0x79, 0x70, 0x0b, 0x35, 0x75, 0x2f, 0x93, 0x12, - 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0xbd, 0x04, 0x68, 0x2b, 0x7a, 0x07, 0x01, 0xc9, - 0x7e, 0x47, 0x01, 0xcb, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xcb, 0x2e, 0x35, 0x30, 0x7a, 0x35, 0x30, - 0x22, 0xd2, 0x04, 0x09, 0xb1, 0x00, 0x14, 0x20, 0xe0, 0x13, 0x22, 0x7e, 0x04, 0x24, 0x2d, 0x80, - 0x28, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0x2a, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xcf, 0x7e, 0x07, 0x01, - 0xcb, 0x7e, 0x24, 0x03, 0xfe, 0x9d, 0x20, 0x28, 0x40, 0x7e, 0x07, 0x01, 0xc9, 0x7e, 0x44, 0x28, - 0x2d, 0x7d, 0x60, 0x0b, 0x04, 0xbd, 0x04, 0x68, 0xd2, 0x7d, 0x70, 0x0b, 0x04, 0xbd, 0x04, 0x68, - 0xd0, 0x7d, 0x54, 0x9d, 0x50, 0xbd, 0x25, 0x40, 0x02, 0x7d, 0x25, 0x7d, 0x32, 0x09, 0xb1, 0x00, - 0x14, 0xca, 0xb8, 0x54, 0x1f, 0xb4, 0x01, 0x31, 0xda, 0xb8, 0x7e, 0x19, 0xb0, 0x7a, 0x09, 0xb0, - 0x0b, 0x04, 0x1b, 0x24, 0x78, 0xe7, 0x02, 0x5e, 0x59, 0x75, 0x2f, 0x99, 0x12, 0x73, 0x35, 0x09, - 0xb1, 0x00, 0x04, 0x54, 0xfa, 0x19, 0xb1, 0x00, 0x04, 0x30, 0x3f, 0x0a, 0x09, 0xb1, 0x00, 0x10, - 0x54, 0xfe, 0x19, 0xb1, 0x00, 0x10, 0xd2, 0x17, 0x22, 0xda, 0xb8, 0x30, 0xe0, 0xd8, 0xbd, 0x32, - 0x68, 0x07, 0xca, 0xb8, 0x12, 0x5e, 0x59, 0xda, 0xb8, 0x02, 0x5f, 0x80, 0x09, 0xb1, 0x00, 0x18, - 0x7e, 0xa0, 0x88, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, 0x12, 0x73, 0x35, 0xa5, 0xfd, - 0x5e, 0x50, 0x0a, 0x68, 0x1d, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5f, 0x80, 0x02, - 0xc2, 0x5f, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x57, 0x80, 0x02, 0xc2, 0x57, 0x12, - 0x43, 0x5e, 0x02, 0x61, 0x13, 0x75, 0x2f, 0x91, 0x12, 0x73, 0x35, 0x09, 0xb1, 0x00, 0x14, 0x7a, - 0xb1, 0x2f, 0x12, 0x73, 0x35, 0x20, 0xe0, 0x08, 0xd2, 0x04, 0x7e, 0xa0, 0x80, 0x02, 0x61, 0x13, - 0xd2, 0x04, 0x30, 0xe1, 0x06, 0x7e, 0xa0, 0x80, 0x12, 0x61, 0x13, 0xca, 0xb8, 0x5e, 0xb0, 0x1c, - 0xda, 0xb8, 0x68, 0x12, 0x7e, 0xa0, 0xc0, 0x09, 0x61, 0x00, 0x00, 0x12, 0x61, 0x36, 0x09, 0xb1, - 0x00, 0x14, 0x20, 0xe0, 0xdb, 0x22, 0x02, 0x5e, 0xad, 0x75, 0x2f, 0x95, 0x12, 0x73, 0x35, 0x22, - 0x75, 0x2f, 0x96, 0x12, 0x73, 0x35, 0x22, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, - 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x58, 0x80, 0x02, 0xc2, 0x58, - 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x50, 0x80, 0x02, 0xc2, 0x50, 0x02, 0x60, 0xff, - 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, - 0x20, 0x68, 0x04, 0xd2, 0x59, 0x80, 0x02, 0xc2, 0x59, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, - 0xd2, 0x51, 0x80, 0x02, 0xc2, 0x51, 0x02, 0x60, 0xff, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, - 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5a, 0x80, 0x02, - 0xc2, 0x5a, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x52, 0x80, 0x02, 0xc2, 0x52, 0x02, - 0x60, 0xff, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, - 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5b, 0x80, 0x02, 0xc2, 0x5b, 0xa5, 0xfd, 0x5e, 0x50, 0x80, - 0x68, 0x04, 0xd2, 0x53, 0x80, 0x02, 0xc2, 0x53, 0x02, 0x60, 0xff, 0x7c, 0x02, 0x7e, 0x14, 0x80, - 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5c, - 0x80, 0x02, 0xc2, 0x5c, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x54, 0x80, 0x02, 0xc2, - 0x54, 0x02, 0x60, 0xff, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, - 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5d, 0x80, 0x02, 0xc2, 0x5d, 0xa5, 0xfd, 0x5e, - 0x50, 0x80, 0x68, 0x04, 0xd2, 0x55, 0x80, 0x02, 0xc2, 0x55, 0x02, 0x60, 0xff, 0x7c, 0x02, 0x7e, - 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, - 0xd2, 0x5e, 0x80, 0x02, 0xc2, 0x5e, 0xa5, 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x56, 0x80, - 0x02, 0xc2, 0x56, 0x02, 0x60, 0xff, 0x7c, 0x02, 0x7e, 0x14, 0x80, 0x00, 0x4c, 0x20, 0x09, 0xb1, - 0x00, 0x18, 0xa5, 0xfd, 0x5e, 0x50, 0x20, 0x68, 0x04, 0xd2, 0x5f, 0x80, 0x02, 0xc2, 0x5f, 0xa5, - 0xfd, 0x5e, 0x50, 0x80, 0x68, 0x04, 0xd2, 0x57, 0x80, 0x02, 0xc2, 0x57, 0x02, 0x60, 0xff, 0x54, - 0xf0, 0xc4, 0xa5, 0xff, 0xc4, 0xa5, 0x4f, 0x75, 0x2f, 0x90, 0x12, 0x73, 0x35, 0xf5, 0x2f, 0x12, - 0x73, 0x35, 0x22, 0xca, 0x19, 0x5e, 0x20, 0x07, 0x4c, 0xa2, 0x7e, 0x74, 0x2c, 0x2d, 0xca, 0x79, - 0x7a, 0x79, 0xa0, 0x0b, 0x74, 0x7a, 0x79, 0xb0, 0x0b, 0x74, 0xda, 0x79, 0x7e, 0x30, 0x02, 0x7e, - 0x64, 0x00, 0x02, 0x02, 0x61, 0x5e, 0xca, 0x19, 0x5e, 0x20, 0x07, 0x4c, 0xa2, 0x7e, 0x74, 0x2c, - 0x2d, 0xca, 0x79, 0x7a, 0x79, 0xa0, 0x0b, 0x74, 0x7a, 0x79, 0xb0, 0x0b, 0x74, 0x7a, 0x79, 0x60, - 0x0b, 0x74, 0xda, 0x79, 0x7e, 0x30, 0x03, 0x7e, 0x64, 0x00, 0x03, 0x02, 0x61, 0x5e, 0xd2, 0x04, - 0x7e, 0x27, 0x01, 0xcb, 0x2d, 0x26, 0xbe, 0x24, 0x04, 0x00, 0x38, 0x2e, 0x7e, 0x07, 0x01, 0xc9, - 0x7e, 0x44, 0x28, 0x2d, 0x7e, 0x79, 0xa0, 0x7a, 0x09, 0xa0, 0x0b, 0x04, 0x0b, 0x74, 0xbd, 0x04, - 0x68, 0x23, 0xa5, 0xdb, 0xef, 0x7a, 0x27, 0x01, 0xcb, 0x7e, 0x25, 0x30, 0x2d, 0x26, 0x7a, 0x25, - 0x30, 0x7a, 0x07, 0x01, 0xc9, 0xda, 0x19, 0xc2, 0xd7, 0x22, 0x75, 0x2f, 0x9a, 0x12, 0x73, 0x35, - 0xda, 0x19, 0xd2, 0xd7, 0x22, 0x7e, 0x04, 0x24, 0x2d, 0x80, 0xd7, 0x48, 0xf1, 0x46, 0x65, 0x47, - 0x5f, 0x49, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x48, 0x56, 0x45, 0x2a, 0x49, 0x6e, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x49, 0x75, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x4c, 0x1e, 0x49, 0x92, 0x4a, - 0x8c, 0x4c, 0x57, 0x45, 0x2a, 0x45, 0x2a, 0x4b, 0x83, 0x45, 0x2a, 0x4c, 0x9b, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x4c, 0xa2, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x4f, 0x4b, 0x4c, 0xbf, 0x4d, - 0xb9, 0x4f, 0x84, 0x45, 0x2a, 0x45, 0x2a, 0x4e, 0xb0, 0x45, 0x2a, 0x4f, 0xc8, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x4f, 0xcf, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x52, 0x78, 0x4f, 0xec, 0x50, - 0xe6, 0x52, 0xb1, 0x45, 0x2a, 0x45, 0x2a, 0x51, 0xdd, 0x45, 0x2a, 0x52, 0xf5, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x52, 0xfc, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x55, 0xa5, 0x53, 0x19, 0x54, - 0x13, 0x55, 0xde, 0x45, 0x2a, 0x45, 0x2a, 0x55, 0x0a, 0x45, 0x2a, 0x56, 0x22, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x56, 0x29, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x58, 0xd2, 0x56, 0x46, 0x57, - 0x40, 0x59, 0x0b, 0x45, 0x2a, 0x45, 0x2a, 0x58, 0x37, 0x45, 0x2a, 0x59, 0x4f, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x59, 0x56, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x5b, 0xff, 0x59, 0x73, 0x5a, - 0x6d, 0x5c, 0x38, 0x45, 0x2a, 0x45, 0x2a, 0x5b, 0x64, 0x45, 0x2a, 0x5c, 0x7c, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x5c, 0x83, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x5f, 0x2c, 0x5c, 0xa0, 0x5d, - 0x9a, 0x5f, 0x65, 0x45, 0x2a, 0x45, 0x2a, 0x5e, 0x91, 0x45, 0x2a, 0x5f, 0xa9, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x5f, 0xb0, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, - 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0x45, 0x2a, 0xca, 0xb8, 0x75, 0x2f, 0x02, - 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x91, 0x03, 0x20, 0xe5, 0x20, 0x30, 0xe0, 0x05, 0x12, 0x6b, 0x05, - 0x80, 0x30, 0x30, 0xe1, 0x05, 0x12, 0x64, 0x86, 0x80, 0x28, 0x30, 0xe2, 0x05, 0x12, 0x63, 0xf5, - 0x80, 0x20, 0x30, 0xe3, 0x1d, 0x12, 0x65, 0x61, 0x80, 0x18, 0x7e, 0xb3, 0x91, 0x04, 0x30, 0xe1, - 0x03, 0x02, 0x67, 0x5f, 0x30, 0xe6, 0x05, 0x12, 0x6c, 0x6a, 0x80, 0x06, 0x20, 0xe2, 0x03, 0x02, - 0x00, 0x80, 0xda, 0xb8, 0x32, 0x75, 0x2f, 0x10, 0x12, 0x73, 0x35, 0xca, 0x0b, 0xca, 0x39, 0xca, - 0x59, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x91, 0x1a, 0x6c, 0xaa, 0xbe, 0xb0, 0x40, - 0x28, 0x0a, 0x12, 0x64, 0x24, 0xda, 0x59, 0xda, 0x39, 0xda, 0x0b, 0x22, 0x74, 0x20, 0x7a, 0xb3, - 0x91, 0x14, 0x80, 0xf1, 0x7e, 0x37, 0x01, 0xc5, 0x2d, 0x35, 0xbe, 0x34, 0x04, 0x00, 0x38, 0x2f, - 0x7a, 0x37, 0x01, 0xc5, 0x7e, 0x37, 0x01, 0xc3, 0x7d, 0x43, 0x2d, 0x45, 0xbe, 0x44, 0x2c, 0x2c, - 0x38, 0x25, 0x7a, 0x47, 0x01, 0xc3, 0x75, 0x2f, 0x11, 0x12, 0x73, 0x35, 0x7a, 0xb1, 0x2f, 0x12, - 0x73, 0x35, 0x12, 0x67, 0x9f, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x14, 0x12, 0x66, 0x30, 0x22, 0x75, - 0x2f, 0x16, 0x12, 0x73, 0x35, 0x80, 0xf4, 0x75, 0x2f, 0x12, 0x12, 0x73, 0x35, 0x7a, 0xb1, 0x2f, - 0x12, 0x73, 0x35, 0x9e, 0x44, 0x2c, 0x2d, 0x9d, 0x54, 0x12, 0x67, 0x9f, 0x7e, 0x34, 0x28, 0x2d, - 0x7d, 0x54, 0x2d, 0x43, 0x80, 0xbc, 0x75, 0x2f, 0x18, 0x12, 0x73, 0x35, 0xca, 0x09, 0xca, 0x39, - 0xca, 0x2b, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0x63, 0x91, 0x1a, 0x74, 0x10, 0x7a, 0xb3, - 0x91, 0x14, 0x7e, 0xb0, 0x80, 0x9c, 0xb6, 0x60, 0x38, 0x6c, 0xaa, 0x7e, 0x37, 0x01, 0xcb, 0x9d, - 0x35, 0x40, 0x37, 0x7a, 0x37, 0x01, 0xcb, 0x7e, 0x37, 0x01, 0xc7, 0x7d, 0x43, 0x2d, 0x45, 0xbe, - 0x44, 0x28, 0x2c, 0x38, 0x3b, 0x7a, 0x47, 0x01, 0xc7, 0x7d, 0x45, 0x12, 0x68, 0xd4, 0x7e, 0xb3, - 0x91, 0x1e, 0x20, 0xe5, 0x13, 0x75, 0x2f, 0x19, 0x12, 0x73, 0x35, 0x7a, 0x91, 0x2f, 0x12, 0x73, - 0x35, 0xda, 0x2b, 0xda, 0x39, 0xda, 0x09, 0x22, 0x80, 0x34, 0x2d, 0x53, 0x6d, 0x33, 0x60, 0x02, - 0x80, 0xc1, 0x7e, 0x04, 0x24, 0x2d, 0x7a, 0x07, 0x01, 0xc9, 0x7a, 0x07, 0x01, 0xc7, 0x80, 0xe1, - 0xca, 0x59, 0x9e, 0x44, 0x28, 0x2d, 0x9d, 0x54, 0x12, 0x68, 0xd4, 0x7e, 0x34, 0x24, 0x2d, 0x7d, - 0x54, 0x2d, 0x43, 0x7a, 0x47, 0x01, 0xc7, 0x12, 0x68, 0xd4, 0xda, 0x49, 0x80, 0xb0, 0x7e, 0x0f, - 0x2c, 0x3e, 0x0b, 0x0c, 0x7a, 0x0f, 0x2c, 0x3e, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x1e, 0x74, 0x60, - 0x7a, 0xb3, 0x91, 0x1c, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x12, 0x80, 0xa5, 0x7e, 0x2f, 0x2c, 0x5e, - 0x0b, 0x2c, 0x7a, 0x2f, 0x2c, 0x5e, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x1e, 0x74, 0x60, 0x7a, 0xb3, - 0x91, 0x1c, 0x74, 0x02, 0x7a, 0xb3, 0x91, 0x12, 0x80, 0x1f, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, - 0x22, 0x75, 0x2f, 0x28, 0x12, 0x73, 0x35, 0xca, 0x0b, 0xca, 0x1b, 0xca, 0x2b, 0x74, 0x60, 0x7a, - 0xb3, 0x91, 0x00, 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x14, 0x7e, 0xb3, 0x91, 0x1a, 0x70, 0xdb, 0x7e, - 0x0d, 0x30, 0x7e, 0x1d, 0x34, 0x7e, 0x2d, 0x38, 0x7e, 0x3d, 0x3c, 0x7e, 0x85, 0x40, 0x7d, 0x90, - 0x4d, 0x91, 0x4d, 0x92, 0x4d, 0x93, 0x4d, 0x94, 0x4d, 0x95, 0x4d, 0x96, 0x4d, 0x97, 0x4d, 0x98, - 0x68, 0xb8, 0x7a, 0x13, 0x91, 0x17, 0x7a, 0x03, 0x91, 0x17, 0x7a, 0x33, 0x91, 0x17, 0x7a, 0x23, - 0x91, 0x17, 0x7a, 0x53, 0x91, 0x17, 0x7a, 0x43, 0x91, 0x17, 0x7a, 0x73, 0x91, 0x17, 0x7a, 0x63, - 0x91, 0x17, 0x7a, 0x93, 0x91, 0x17, 0x7a, 0x83, 0x91, 0x17, 0x30, 0x73, 0x22, 0x7a, 0xb3, 0x91, - 0x17, 0x7a, 0xa3, 0x91, 0x17, 0x7a, 0xd3, 0x91, 0x17, 0x7a, 0xc3, 0x91, 0x17, 0x7a, 0xf3, 0x91, - 0x17, 0x7a, 0xe3, 0x91, 0x17, 0x7d, 0x78, 0x7a, 0xf3, 0x91, 0x17, 0x7a, 0xe3, 0x91, 0x17, 0x7e, - 0xb3, 0x91, 0x1e, 0x30, 0xe5, 0x03, 0x02, 0x65, 0x3c, 0x75, 0x2f, 0x29, 0x12, 0x73, 0x35, 0x20, - 0x73, 0x08, 0x75, 0x2f, 0x0a, 0x12, 0x73, 0x35, 0x80, 0x06, 0x75, 0x2f, 0x12, 0x12, 0x73, 0x35, - 0x74, 0x80, 0x7a, 0xb3, 0x91, 0x1e, 0x6d, 0x00, 0x7d, 0x10, 0x7a, 0x0d, 0x30, 0x7a, 0x0d, 0x34, - 0x7a, 0x0d, 0x38, 0x7a, 0x0d, 0x3c, 0x7a, 0x05, 0x40, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, - 0x7e, 0x37, 0x01, 0xc5, 0x4d, 0x33, 0x68, 0x3b, 0x7e, 0x07, 0x01, 0xc1, 0x7e, 0x54, 0x2c, 0x2d, - 0x9d, 0x50, 0xbd, 0x35, 0x40, 0x02, 0x7d, 0x35, 0xca, 0x39, 0x7e, 0x65, 0x4b, 0x99, 0x64, 0xda, - 0x39, 0x7e, 0x07, 0x01, 0xc5, 0x9d, 0x03, 0x7a, 0x07, 0x01, 0xc5, 0x2e, 0x37, 0x01, 0xc1, 0x7a, - 0x37, 0x01, 0xc1, 0xbe, 0x34, 0x2c, 0x2c, 0x28, 0xc7, 0x7e, 0x34, 0x28, 0x2d, 0x7a, 0x37, 0x01, - 0xc1, 0x80, 0xbd, 0x22, 0x75, 0x2f, 0x53, 0x12, 0x73, 0x35, 0x7e, 0x15, 0x4d, 0x80, 0x11, 0x75, - 0x2f, 0x51, 0x12, 0x73, 0x35, 0x0b, 0x08, 0x10, 0x0b, 0x05, 0x9e, 0x34, 0x00, 0x02, 0x28, 0x4d, - 0x7c, 0xb2, 0x20, 0xe7, 0x27, 0x54, 0x07, 0x23, 0x0a, 0x2b, 0x49, 0x22, 0x39, 0x1e, 0x7c, 0xb2, - 0x54, 0x78, 0x03, 0x03, 0x03, 0x7c, 0x2b, 0x9d, 0x13, 0x40, 0x1a, 0x68, 0x12, 0x7a, 0x15, 0x4d, - 0x7a, 0x25, 0x4f, 0x7e, 0x64, 0x67, 0x09, 0x7a, 0x65, 0x4b, 0x89, 0x24, 0x02, 0x67, 0x17, 0x7e, - 0x64, 0x66, 0x7f, 0x80, 0xf2, 0x2d, 0x13, 0x9d, 0x31, 0xca, 0x39, 0x7d, 0x31, 0x2d, 0x10, 0xca, - 0x19, 0xca, 0x29, 0x99, 0x24, 0xda, 0x29, 0xda, 0x09, 0xda, 0x39, 0x80, 0xa2, 0x7a, 0x15, 0x4d, - 0x7e, 0x64, 0x66, 0xf5, 0x4d, 0x33, 0x78, 0x09, 0x7c, 0xb2, 0x20, 0xe7, 0x2a, 0x7e, 0x64, 0x66, - 0x74, 0x7a, 0x65, 0x4b, 0x22, 0x75, 0x2f, 0x52, 0x12, 0x73, 0x35, 0x7e, 0x21, 0x4d, 0x7e, 0x09, - 0x30, 0x0b, 0x04, 0x1b, 0x34, 0x78, 0x89, 0x80, 0xd4, 0x75, 0x2f, 0x54, 0x12, 0x73, 0x35, 0x7e, - 0x15, 0x4d, 0x7e, 0x25, 0x4f, 0x80, 0x90, 0x5e, 0x20, 0x07, 0x54, 0x78, 0x7e, 0x44, 0x67, 0x7d, - 0x30, 0xe6, 0x16, 0x4d, 0x33, 0x68, 0x26, 0x1b, 0x34, 0x7e, 0x09, 0x40, 0x0b, 0x04, 0x7e, 0x44, - 0x34, 0xfa, 0x20, 0xe3, 0x04, 0x7e, 0x44, 0x67, 0x85, 0xca, 0x09, 0xca, 0x39, 0x99, 0x44, 0xda, - 0x39, 0xda, 0x09, 0x7e, 0x64, 0x66, 0x7f, 0x4d, 0x33, 0x68, 0xa6, 0x89, 0x64, 0x7a, 0x15, 0x4d, - 0xf5, 0x4f, 0x7e, 0x64, 0x67, 0x58, 0x80, 0x99, 0x7e, 0x15, 0x4d, 0xe5, 0x4f, 0x80, 0xc4, 0xc0, - 0xd0, 0xc0, 0xd1, 0xc0, 0xe0, 0xca, 0x19, 0x75, 0x2f, 0xfe, 0x12, 0x73, 0x35, 0x7e, 0x14, 0x00, - 0x53, 0x02, 0x40, 0x52, 0xda, 0x19, 0xd0, 0xe0, 0xd0, 0xd1, 0xd0, 0xd0, 0x32, 0x03, 0xa5, 0xcb, - 0x19, 0xb1, 0x80, 0x00, 0x22, 0x22, 0x7e, 0x24, 0x00, 0x00, 0x7f, 0xe1, 0x7e, 0xa0, 0x02, 0xa4, - 0x7e, 0x04, 0x68, 0xb1, 0x9d, 0x05, 0x7e, 0xb0, 0x28, 0x7a, 0xb3, 0x95, 0x00, 0x89, 0x04, 0xca, - 0x29, 0xb4, 0x80, 0xe2, 0x7e, 0x24, 0x00, 0x00, 0x7f, 0xe1, 0x7e, 0x00, 0x28, 0x7a, 0x03, 0x95, - 0x00, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x95, 0x00, 0xda, 0x29, 0x22, 0x7e, 0x24, 0x00, 0x00, 0x7f, - 0xe1, 0x7e, 0xa0, 0x02, 0xa4, 0x7e, 0x04, 0x69, 0xe6, 0x9d, 0x05, 0x7e, 0xb0, 0x38, 0x7a, 0xb3, - 0x95, 0x00, 0x89, 0x04, 0xca, 0x29, 0xb4, 0x80, 0xe2, 0x7e, 0x24, 0x00, 0x00, 0x7f, 0xe1, 0x7e, - 0x00, 0x38, 0x7a, 0x03, 0x95, 0x00, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x95, 0x00, 0xda, 0x29, 0x22, - 0xca, 0x29, 0xca, 0x19, 0xca, 0x58, 0x7e, 0x24, 0x00, 0x00, 0x7f, 0xe1, 0xda, 0x58, 0x7e, 0x54, - 0x02, 0x20, 0x9c, 0xb5, 0xa4, 0x7e, 0x50, 0x30, 0x5e, 0x20, 0x07, 0x2c, 0x52, 0x7a, 0x53, 0x95, - 0x00, 0x2e, 0x54, 0x6a, 0x17, 0x89, 0x54, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, - 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x95, 0x00, 0xda, 0x19, - 0xda, 0x29, 0x22, 0xca, 0x19, 0xca, 0x58, 0x7e, 0x24, 0x00, 0x00, 0x7f, 0xe1, 0xda, 0x58, 0x7e, - 0x54, 0x02, 0x38, 0x9c, 0xb5, 0xa4, 0x7e, 0x50, 0x20, 0x5e, 0x20, 0x07, 0x2c, 0x52, 0x7a, 0x53, - 0x95, 0x00, 0x2e, 0x54, 0x6a, 0x88, 0x89, 0x54, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, - 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0xe0, 0xa3, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x95, 0x00, 0xda, - 0x19, 0x22, 0x02, 0x6b, 0xa8, 0xca, 0x0b, 0xca, 0x1b, 0xca, 0x2b, 0xca, 0x3b, 0xca, 0x4b, 0xca, - 0x5b, 0xca, 0x6b, 0xca, 0x7b, 0xca, 0xeb, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x2c, - 0x7f, 0xb4, 0x00, 0x02, 0x80, 0x1c, 0xb4, 0x01, 0x19, 0x7e, 0xb3, 0x91, 0x14, 0x54, 0x14, 0x68, - 0x05, 0x12, 0x6b, 0x6c, 0x80, 0x23, 0x7e, 0xb3, 0x91, 0x14, 0x30, 0xe5, 0x1c, 0x12, 0x6c, 0xaa, - 0x80, 0x17, 0x7e, 0xb3, 0x91, 0x14, 0x30, 0xe5, 0x05, 0x12, 0x6c, 0xaa, 0x80, 0x0b, 0x7e, 0xb3, - 0x91, 0x14, 0x54, 0x14, 0x68, 0x03, 0x12, 0x6b, 0x6c, 0xda, 0xeb, 0xda, 0x7b, 0xda, 0x6b, 0xda, - 0x5b, 0xda, 0x4b, 0xda, 0x3b, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0x20, 0xe4, 0x19, 0x75, - 0x2f, 0x0a, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, 0x7e, 0x70, 0x0a, 0x7e, 0xb3, 0x2c, 0x7f, 0xb4, - 0x01, 0x1f, 0x02, 0x6c, 0x04, 0x02, 0x71, 0xf2, 0x75, 0x2f, 0x0b, 0x12, 0x73, 0x35, 0x74, 0x14, - 0x7a, 0xb3, 0x91, 0x14, 0x7e, 0xb3, 0x2c, 0x7f, 0xb4, 0x02, 0x0c, 0x12, 0x6b, 0xb4, 0x02, 0x6b, - 0xa8, 0x74, 0x04, 0x7a, 0xb3, 0x91, 0x14, 0x22, 0x7e, 0x00, 0x00, 0x7a, 0x03, 0x2c, 0x7f, 0x7a, - 0x03, 0x2c, 0x80, 0x22, 0x7e, 0xb3, 0x2c, 0x76, 0x54, 0x60, 0x60, 0x05, 0xb4, 0x40, 0x1e, 0x80, - 0x1c, 0x7e, 0xb3, 0x2c, 0x77, 0xb4, 0x05, 0x15, 0x75, 0x2f, 0x71, 0x12, 0x73, 0x35, 0x7e, 0xb3, - 0x2c, 0x79, 0x7e, 0xa0, 0x01, 0x7a, 0xa3, 0x91, 0x06, 0x7a, 0xb3, 0x91, 0x07, 0x22, 0x74, 0x00, - 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x10, 0x7a, 0xb3, 0x91, 0x12, 0x22, 0xbe, 0x57, 0x2c, 0x7c, 0x28, - 0x04, 0x7e, 0x57, 0x2c, 0x7c, 0x7a, 0x0f, 0x2c, 0x82, 0x7a, 0x57, 0x2c, 0x86, 0x74, 0x10, 0x7a, - 0xb3, 0x91, 0x12, 0x22, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x91, 0x1a, 0x70, 0x53, - 0x7e, 0xb3, 0x91, 0x14, 0x20, 0xe4, 0x4c, 0x7e, 0xef, 0x2c, 0x82, 0x7e, 0xf7, 0x2c, 0x86, 0x7e, - 0x07, 0x2c, 0x86, 0x4d, 0x00, 0x68, 0x21, 0x7e, 0x00, 0x00, 0xe0, 0x7a, 0xb3, 0x91, 0x17, 0xa3, - 0xa5, 0x08, 0x1b, 0xf4, 0x68, 0x06, 0xa5, 0xb8, 0x10, 0xf0, 0x80, 0x19, 0x7e, 0xb0, 0x00, 0x7a, - 0xb3, 0x2c, 0x7f, 0xbe, 0x00, 0x10, 0x68, 0x0d, 0x7e, 0xb0, 0x00, 0x7a, 0xb3, 0x2c, 0x7f, 0x74, - 0x80, 0x7a, 0xb3, 0x91, 0x1e, 0x7a, 0xef, 0x2c, 0x82, 0x7a, 0xf7, 0x2c, 0x86, 0x75, 0x2f, 0x06, - 0x12, 0x73, 0x35, 0x74, 0x04, 0x7a, 0xb3, 0x91, 0x14, 0x22, 0xca, 0x0b, 0xca, 0x1b, 0xca, 0x2b, - 0xca, 0x3b, 0xca, 0x4b, 0xca, 0x5b, 0xca, 0x6b, 0xca, 0x7b, 0xca, 0xeb, 0x75, 0x2f, 0x03, 0x12, - 0x73, 0x35, 0x74, 0x00, 0x7a, 0xb3, 0x2c, 0x7e, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x01, - 0x7a, 0xb3, 0x91, 0x12, 0x12, 0x6d, 0x19, 0xda, 0xeb, 0xda, 0x7b, 0xda, 0x6b, 0xda, 0x5b, 0xda, - 0x4b, 0xda, 0x3b, 0xda, 0x2b, 0xda, 0x1b, 0xda, 0x0b, 0x22, 0x75, 0x2f, 0x03, 0x12, 0x73, 0x35, - 0x7e, 0xb3, 0x2c, 0x80, 0xb4, 0x02, 0x11, 0x74, 0x00, 0x7a, 0xb3, 0x2c, 0x80, 0x7a, 0xb3, 0x2c, - 0x7f, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x14, 0x22, 0xb4, 0x01, 0x46, 0x7e, 0xb3, 0x91, 0x04, 0x20, - 0xe6, 0x42, 0x7e, 0x23, 0x91, 0x1a, 0x7c, 0x32, 0x7e, 0x13, 0x2c, 0x81, 0x2c, 0x21, 0x7a, 0x23, - 0x2c, 0x81, 0x7e, 0x00, 0x00, 0x2e, 0x04, 0x2c, 0x88, 0x7e, 0xb3, 0x91, 0x16, 0x7a, 0x09, 0xb0, - 0x0b, 0x04, 0xa5, 0xdb, 0xf4, 0x74, 0x20, 0x7a, 0xb3, 0x91, 0x14, 0x75, 0x2f, 0x70, 0x12, 0x73, - 0x35, 0x7e, 0xb3, 0x2c, 0x81, 0x7e, 0xa3, 0x2c, 0x7d, 0xbc, 0xab, 0x78, 0x03, 0x12, 0x6d, 0xb9, - 0x22, 0x02, 0x71, 0xf2, 0xda, 0x59, 0x02, 0x6c, 0x7c, 0x74, 0xe0, 0x7a, 0xb3, 0x91, 0x00, 0x7e, - 0x03, 0x91, 0x10, 0x7e, 0x13, 0x91, 0x11, 0x7e, 0x33, 0x91, 0x12, 0x7e, 0x23, 0x91, 0x13, 0x7e, - 0x53, 0x91, 0x14, 0x7e, 0x43, 0x91, 0x15, 0x7e, 0x73, 0x91, 0x16, 0x7e, 0x63, 0x91, 0x17, 0x7a, - 0x0f, 0x2c, 0x76, 0x7a, 0x1f, 0x2c, 0x7a, 0x75, 0x2f, 0x04, 0x12, 0x73, 0x35, 0x7a, 0x01, 0x2f, - 0x12, 0x73, 0x35, 0x7a, 0x11, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x21, 0x2f, 0x12, 0x73, 0x35, 0x7a, - 0x31, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x41, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x51, 0x2f, 0x12, 0x73, - 0x35, 0x7a, 0x61, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x71, 0x2f, 0x12, 0x73, 0x35, 0x74, 0x00, 0x7a, - 0xb3, 0x91, 0x00, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x04, 0x12, 0x6d, 0x8d, 0x22, 0x6d, 0x00, 0x7e, - 0x14, 0x01, 0x02, 0x7a, 0x07, 0x2c, 0x86, 0x7a, 0x03, 0x2c, 0x81, 0x7e, 0xb3, 0x2c, 0x76, 0x20, - 0xe7, 0x0f, 0x7a, 0x23, 0x2c, 0x80, 0x7a, 0x33, 0x2c, 0x7f, 0xbe, 0x07, 0x2c, 0x7c, 0x68, 0x09, - 0x22, 0x7a, 0x33, 0x2c, 0x80, 0x7a, 0x23, 0x2c, 0x7f, 0x7e, 0xb3, 0x2c, 0x76, 0x54, 0xe3, 0x23, - 0x23, 0x30, 0xe0, 0x02, 0xd2, 0xe5, 0x30, 0xe7, 0x02, 0xd2, 0xe4, 0x30, 0xe5, 0x06, 0x30, 0xe4, - 0x03, 0x02, 0x71, 0xf2, 0x54, 0x3e, 0xf5, 0xf0, 0x03, 0x54, 0x1f, 0xc3, 0x25, 0xf0, 0x90, 0x6d, - 0xe5, 0x75, 0x84, 0xff, 0x73, 0x02, 0x6f, 0xa0, 0x02, 0x6e, 0x2d, 0x02, 0x70, 0x39, 0x02, 0x70, - 0x54, 0x02, 0x6f, 0x37, 0x02, 0x6e, 0xc2, 0x02, 0x70, 0x85, 0x02, 0x70, 0x85, 0x02, 0x70, 0x88, - 0x02, 0x70, 0x88, 0x02, 0x70, 0x88, 0x02, 0x70, 0x88, 0x02, 0x70, 0x88, 0x02, 0x70, 0x88, 0x02, - 0x70, 0x88, 0x02, 0x70, 0x88, 0x02, 0x70, 0x8e, 0x02, 0x71, 0x60, 0x02, 0x70, 0x8b, 0x02, 0x70, - 0x8b, 0x02, 0x70, 0x8b, 0x02, 0x70, 0x8b, 0x02, 0x70, 0x8b, 0x02, 0x70, 0x8b, 0x74, 0x00, 0x7a, - 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x7e, 0xb3, 0x2c, 0x77, 0xb4, 0x06, 0x2a, - 0x7e, 0xb3, 0x2c, 0x78, 0x60, 0x79, 0x7c, 0x0b, 0x7e, 0x13, 0x2c, 0x79, 0x7e, 0x17, 0x2c, 0x7a, - 0x75, 0x2f, 0x72, 0x12, 0x73, 0x35, 0x7a, 0x01, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x11, 0x2f, 0x12, - 0x73, 0x35, 0x12, 0x72, 0x37, 0x40, 0x58, 0x02, 0x6b, 0xeb, 0xb4, 0x08, 0x1c, 0x75, 0x2f, 0x74, - 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x3f, 0xf1, 0x7e, 0x08, 0x2c, 0x88, 0x7a, 0x0c, 0x00, 0x00, 0x7a, - 0x0b, 0xb0, 0x7e, 0x54, 0x00, 0x01, 0x02, 0x6b, 0xeb, 0xb4, 0x00, 0x33, 0x75, 0x2f, 0x75, 0x12, - 0x73, 0x35, 0x7e, 0x08, 0x2c, 0x88, 0x7a, 0x0c, 0x00, 0x00, 0xca, 0x0b, 0x7e, 0xb3, 0x3f, 0xf2, - 0x30, 0xe0, 0x07, 0x74, 0x02, 0x7a, 0x0b, 0xb0, 0x80, 0x05, 0x74, 0x00, 0x7a, 0x0b, 0xb0, 0x0b, - 0x14, 0x74, 0x00, 0x7a, 0x0b, 0xb0, 0x7e, 0x54, 0x00, 0x02, 0xda, 0x0b, 0x02, 0x6b, 0xeb, 0x02, - 0x71, 0xf2, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x7e, 0xb3, - 0x2c, 0x77, 0xb4, 0x00, 0x5f, 0x75, 0x2f, 0x76, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, 0x7b, 0x54, - 0x0f, 0xb4, 0x02, 0x05, 0x7e, 0xb0, 0x60, 0x80, 0x17, 0xb4, 0x00, 0x05, 0x7e, 0xb0, 0x00, 0x80, - 0x0f, 0x7e, 0xb3, 0x2c, 0x7b, 0x20, 0xe7, 0x05, 0x7e, 0xb0, 0x40, 0x80, 0x03, 0x7e, 0xb0, 0x20, - 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0xb3, 0x91, 0x11, 0x30, 0xe0, 0x04, 0x74, 0x01, 0x80, 0x02, 0x74, - 0x00, 0x7e, 0x08, 0x2c, 0x88, 0x7a, 0x0c, 0x00, 0x00, 0xca, 0x0b, 0x7a, 0x0b, 0xb0, 0x0b, 0x14, - 0x74, 0x00, 0x7a, 0x0b, 0xb0, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x7e, 0x54, 0x00, 0x02, 0xda, - 0x0b, 0x02, 0x6b, 0xeb, 0x02, 0x71, 0xf2, 0x7e, 0xb3, 0x2c, 0x7b, 0x54, 0x0f, 0xb4, 0x02, 0x05, - 0x7e, 0xb0, 0x60, 0x80, 0x17, 0xb4, 0x00, 0x05, 0x7e, 0xb0, 0x00, 0x80, 0x0f, 0x7e, 0xb3, 0x2c, - 0x7b, 0x20, 0xe7, 0x05, 0x7e, 0xb0, 0x40, 0x80, 0x03, 0x7e, 0xb0, 0x20, 0x7a, 0xb3, 0x91, 0x00, - 0x7e, 0xb3, 0x2c, 0x79, 0xb4, 0x00, 0x26, 0x7e, 0xb3, 0x2c, 0x77, 0xb4, 0x01, 0x0e, 0x75, 0x2f, - 0x77, 0x12, 0x73, 0x35, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x12, 0x80, 0x1b, 0xb4, 0x03, 0x0e, 0x75, - 0x2f, 0x78, 0x12, 0x73, 0x35, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x11, 0x80, 0x0a, 0x74, 0x00, 0x7a, - 0xb3, 0x91, 0x00, 0x12, 0x71, 0xf2, 0x22, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x02, 0x6b, 0xde, - 0x7e, 0xb3, 0x2c, 0x77, 0xb4, 0x09, 0x1f, 0x75, 0x2f, 0x79, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, - 0x79, 0xbe, 0xb3, 0x3f, 0xf1, 0x68, 0x0d, 0xca, 0xb8, 0x12, 0x43, 0x79, 0xda, 0xb8, 0x50, 0x76, - 0x7a, 0xb3, 0x3f, 0xf1, 0x80, 0x6d, 0xb4, 0x05, 0x08, 0x75, 0x2f, 0x7a, 0x12, 0x73, 0x35, 0x80, - 0x62, 0xb4, 0x03, 0x19, 0x75, 0x2f, 0x7b, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, 0x79, 0xb4, 0x01, - 0x55, 0x7e, 0xb3, 0x3f, 0xf2, 0x44, 0x01, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, 0x46, 0xb4, 0x01, 0x19, - 0x75, 0x2f, 0x7c, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, 0x79, 0xb4, 0x01, 0x39, 0x7e, 0xb3, 0x3f, - 0xf2, 0x54, 0xfe, 0x7a, 0xb3, 0x3f, 0xf2, 0x80, 0x2a, 0xb4, 0x07, 0x2a, 0x7e, 0xb3, 0x2c, 0x78, - 0x60, 0x24, 0x7c, 0x0b, 0x7e, 0x13, 0x2c, 0x79, 0x7e, 0x17, 0x2c, 0x7a, 0x75, 0x2f, 0x73, 0x12, - 0x73, 0x35, 0x7a, 0x01, 0x2f, 0x12, 0x73, 0x35, 0x7a, 0x11, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x72, - 0x71, 0x40, 0x03, 0x02, 0x6b, 0xde, 0x02, 0x71, 0xf2, 0x7e, 0xb3, 0x2c, 0x77, 0xb4, 0x0b, 0xf6, - 0x75, 0x2f, 0x7d, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, 0x79, 0x7e, 0xa3, 0x2c, 0x7b, 0x4c, 0xab, - 0x78, 0xe4, 0x80, 0xdf, 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, - 0x7e, 0xb3, 0x2c, 0x77, 0xb4, 0x0a, 0xcf, 0x75, 0x2f, 0x7e, 0x12, 0x73, 0x35, 0x7e, 0xb3, 0x2c, - 0x79, 0x70, 0xc3, 0x7e, 0x08, 0x2c, 0x88, 0x7a, 0x0c, 0x00, 0x00, 0x7a, 0x0b, 0xb0, 0x7e, 0x54, - 0x00, 0x01, 0x02, 0x6b, 0xeb, 0x02, 0x71, 0xf2, 0x02, 0x71, 0xf2, 0x02, 0x71, 0xf2, 0x7e, 0xb3, - 0x2c, 0x77, 0xb4, 0x04, 0x20, 0x75, 0x2f, 0xc3, 0x12, 0x73, 0x35, 0x7e, 0x04, 0x00, 0x01, 0x7e, - 0x17, 0x2c, 0x78, 0x7e, 0x18, 0x2c, 0x88, 0x7a, 0x1c, 0x00, 0x00, 0x7e, 0x47, 0x2c, 0x7c, 0x12, - 0x73, 0x41, 0x02, 0x71, 0x5a, 0xb4, 0x06, 0x42, 0x75, 0x2f, 0xc1, 0x12, 0x73, 0x35, 0x7e, 0x58, - 0x00, 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7d, 0xca, 0x7e, 0xd7, 0x2c, 0x78, 0x7e, 0x78, 0x2c, 0x88, - 0x7a, 0x7c, 0x00, 0x00, 0x7e, 0x77, 0x2c, 0x7c, 0x75, 0x2f, 0xc1, 0x12, 0x73, 0x35, 0xc0, 0xa8, - 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, 0x94, 0x00, 0x12, 0x73, 0x7a, 0x7e, 0x43, 0x2c, 0x35, - 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, 0x40, 0x65, 0x80, 0x60, 0xb4, 0x00, 0x24, 0xc2, 0xaf, 0x7e, - 0xb0, 0x01, 0x7a, 0xb3, 0x94, 0x00, 0x7a, 0xb3, 0x2c, 0x35, 0x12, 0x6b, 0xde, 0xe4, 0x8d, 0xef, - 0x8d, 0xef, 0x8d, 0xef, 0xd5, 0xe0, 0xf7, 0xc0, 0xd1, 0xca, 0x02, 0xff, 0xca, 0x06, 0x00, 0x00, - 0x32, 0xb4, 0x09, 0x20, 0x74, 0x03, 0x7a, 0xb3, 0x91, 0x06, 0x7e, 0x23, 0x91, 0x07, 0x7e, 0x57, - 0x2c, 0x78, 0x4d, 0x55, 0x68, 0x05, 0x4e, 0x20, 0x02, 0x80, 0x03, 0x5e, 0x20, 0xfd, 0x7a, 0x23, - 0x91, 0x07, 0x80, 0x16, 0xb4, 0x07, 0x16, 0xc2, 0xaf, 0x7e, 0x07, 0x2c, 0x7a, 0x7e, 0x17, 0x2c, - 0x78, 0xc0, 0xd1, 0xca, 0x18, 0xca, 0x38, 0xca, 0x28, 0x32, 0x02, 0x6b, 0xde, 0x02, 0x71, 0xf2, - 0x74, 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x60, 0x7a, 0xb3, 0x91, 0x1c, 0x7e, 0xb3, 0x2c, 0x77, - 0xb4, 0x03, 0x15, 0x75, 0x2f, 0xc2, 0x12, 0x73, 0x35, 0x7e, 0x04, 0x00, 0x01, 0x7e, 0x17, 0x2c, - 0x78, 0x7e, 0x57, 0x2c, 0x7c, 0x02, 0x6b, 0xeb, 0xb4, 0x05, 0x41, 0x75, 0x2f, 0xc0, 0x12, 0x73, - 0x35, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, 0x94, 0x00, 0x7e, 0x08, 0x2c, 0x88, - 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x24, 0x00, 0xfe, 0x7e, 0x37, 0x2c, 0x78, 0x7e, 0x47, 0x2c, 0x7c, - 0x12, 0x73, 0x41, 0x7e, 0x43, 0x2c, 0x35, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, 0x7e, 0x08, 0x2c, - 0x88, 0x7a, 0x0c, 0x00, 0x00, 0x7e, 0x57, 0x2c, 0x7c, 0x02, 0x6b, 0xeb, 0xb4, 0x01, 0x20, 0x7e, - 0x00, 0x00, 0x7e, 0x10, 0x01, 0x75, 0x2f, 0x72, 0x12, 0x73, 0x35, 0x7a, 0x01, 0x2f, 0x12, 0x73, - 0x35, 0x7a, 0x11, 0x2f, 0x12, 0x73, 0x35, 0x12, 0x72, 0x37, 0x40, 0x03, 0x02, 0x6b, 0xeb, 0x02, - 0x71, 0xf2, 0x75, 0x2f, 0x07, 0x12, 0x73, 0x35, 0x7e, 0xb0, 0x02, 0x7a, 0xb3, 0x90, 0x00, 0x74, - 0x00, 0x7a, 0xb3, 0x91, 0x00, 0x74, 0x40, 0x7a, 0xb3, 0x91, 0x15, 0x74, 0x01, 0x7a, 0xb3, 0x91, - 0x11, 0x7e, 0xb3, 0x91, 0x15, 0x54, 0x60, 0xbe, 0xb0, 0x40, 0x68, 0x08, 0x74, 0x20, 0x7a, 0xb3, - 0x91, 0x15, 0x80, 0xed, 0x74, 0x01, 0x7a, 0xb3, 0x91, 0x12, 0x74, 0x04, 0x7a, 0xb3, 0x91, 0x14, - 0x74, 0xff, 0x7a, 0xb3, 0x2c, 0x7e, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, - 0x94, 0x00, 0x12, 0x72, 0xbe, 0x40, 0x1f, 0x7e, 0x08, 0x2c, 0x88, 0x7a, 0x0c, 0x00, 0x00, 0xca, - 0x0b, 0xca, 0x49, 0x12, 0x73, 0x41, 0xda, 0x59, 0xda, 0x0b, 0x7e, 0x43, 0x2c, 0x35, 0x7a, 0x43, - 0x94, 0x00, 0xd0, 0xa8, 0xc3, 0x22, 0x7e, 0x43, 0x2c, 0x35, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, - 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0x7e, 0x40, 0x01, 0x7a, 0x43, 0x94, 0x00, 0x12, 0x72, 0xbe, 0x40, - 0x31, 0x7e, 0x58, 0x00, 0x00, 0x7a, 0x5c, 0x00, 0xfe, 0x7f, 0x61, 0x7e, 0x78, 0x2c, 0x88, 0x7a, - 0x7c, 0x00, 0x00, 0x7e, 0x77, 0x2c, 0x7c, 0xbd, 0x74, 0x78, 0x17, 0x75, 0x2f, 0xc1, 0x12, 0x73, - 0x35, 0x12, 0x73, 0x7a, 0x40, 0x0c, 0x7e, 0x43, 0x2c, 0x35, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, - 0xc3, 0x22, 0x7e, 0x43, 0x2c, 0x35, 0x7a, 0x43, 0x94, 0x00, 0xd0, 0xa8, 0xd3, 0x22, 0x7e, 0x24, - 0x00, 0xfe, 0x7e, 0x34, 0x7f, 0xca, 0x0b, 0x1a, 0x50, 0xc5, 0xf0, 0x7d, 0x62, 0x7d, 0x75, 0x7d, - 0x87, 0x7e, 0x34, 0x7f, 0xc2, 0x7e, 0x1b, 0xb0, 0x7e, 0x34, 0x7f, 0x03, 0xb4, 0x01, 0x04, 0x7e, - 0x34, 0x7f, 0xcc, 0x7e, 0x1b, 0xb0, 0xbc, 0x0b, 0x50, 0x49, 0x3e, 0x00, 0x3e, 0x00, 0x0a, 0x50, - 0x2d, 0x75, 0x0b, 0x3a, 0x30, 0x69, 0x53, 0x00, 0x02, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, 0xbc, - 0x1b, 0x50, 0x30, 0x3e, 0x10, 0x3e, 0x10, 0x0a, 0x51, 0x2d, 0x35, 0x69, 0x41, 0x00, 0x02, 0x0b, - 0x1a, 0x30, 0xbd, 0x38, 0x50, 0x02, 0x2d, 0x38, 0xbe, 0x44, 0xff, 0xff, 0x78, 0x05, 0x7e, 0x1b, - 0x90, 0x0a, 0x49, 0x4d, 0x44, 0x68, 0x0c, 0xbe, 0x44, 0x00, 0xff, 0x28, 0x04, 0x7e, 0x44, 0x00, - 0xff, 0xc3, 0x22, 0xd3, 0x22, - -// Segment #16, Start Address 00ff7fc6, Length 4 -0xff,0x00,0xc6,0x7f,0x04,0x00, - 0x02, 0x00, 0x03, 0x00, - -// Segment #17, Start Address 00ff7335, Length 328 -0xff,0x00,0x35,0x73,0x48,0x01, - 0xca, 0x08, 0x7e, 0x01, 0x2f, 0x7a, 0x03, 0x3f, 0xf0, 0xda, 0x08, 0x22, 0x7e, 0x1b, 0xc0, 0x7a, - 0x0b, 0xc0, 0x0b, 0x14, 0x0b, 0x34, 0x1b, 0x44, 0x78, 0xf2, 0x22, 0x7f, 0x6f, 0x7f, 0xf0, 0x1b, - 0xfc, 0x7c, 0x54, 0x7d, 0x32, 0x80, 0x08, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0xca, 0x1b, 0x9e, - 0x44, 0x00, 0x10, 0x50, 0xf2, 0x2e, 0x44, 0x00, 0x10, 0x68, 0x06, 0xca, 0x48, 0x1b, 0x44, 0x78, - 0xfa, 0x7f, 0xf6, 0x89, 0xe4, 0xca, 0x6b, 0x5e, 0xd4, 0x00, 0x3f, 0x68, 0x20, 0x7e, 0x84, 0x00, - 0x40, 0x9d, 0x8d, 0xda, 0x6b, 0xbd, 0x87, 0x38, 0x16, 0xca, 0x79, 0x7d, 0x78, 0x12, 0x73, 0xa4, - 0xda, 0x79, 0x40, 0x08, 0x9d, 0x78, 0x68, 0x02, 0x80, 0x05, 0xc2, 0xd7, 0x22, 0xda, 0x6b, 0x7e, - 0xc0, 0x03, 0x7e, 0xd0, 0x00, 0x7a, 0xd3, 0x90, 0x00, 0x74, 0xaa, 0x39, 0xb5, 0x55, 0x55, 0x74, - 0x55, 0x39, 0xb5, 0x2a, 0xaa, 0x74, 0xa0, 0x39, 0xb5, 0x55, 0x55, 0x7e, 0x04, 0x00, 0x40, 0x9d, - 0x70, 0x50, 0x06, 0x2d, 0x70, 0x7d, 0x07, 0x6d, 0x77, 0x7c, 0x31, 0x7e, 0x7b, 0x00, 0x7a, 0x6b, - 0x00, 0x0b, 0x7c, 0x0b, 0x6c, 0xa5, 0xd9, 0xf3, 0x7f, 0x16, 0x1b, 0x1c, 0x7e, 0x54, 0x27, 0x10, - 0x7e, 0x1b, 0x10, 0xbc, 0x10, 0x68, 0x06, 0x1b, 0x54, 0x78, 0xf5, 0x80, 0x2f, 0x6d, 0x00, 0x7c, - 0x20, 0x7f, 0x16, 0x9f, 0x10, 0x7f, 0x27, 0x9f, 0x20, 0x7e, 0x2b, 0x00, 0x7e, 0x1b, 0x10, 0xbc, - 0x01, 0x78, 0x19, 0x0b, 0x2c, 0x0b, 0x1c, 0xa5, 0xdb, 0xef, 0x7c, 0xb6, 0x20, 0xe0, 0x06, 0x6c, - 0xdc, 0x7a, 0xd3, 0x90, 0x00, 0x4d, 0x77, 0x78, 0x90, 0xc2, 0xd7, 0x22, 0xd2, 0xd7, 0x22, 0x00, - 0x04, 0x00, 0x04, 0x00, 0x00, 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, 0x04, 0x01, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x08, 0x10, - 0x02, 0x10, 0x04, 0x02, 0x08, 0x00, 0x01, 0x01, 0x08, 0x7e, 0x18, 0x7f, 0xbd, 0x7a, 0x1c, 0x00, - 0xfe, 0x0b, 0x1a, 0x00, 0x5e, 0x10, 0x1f, 0xbe, 0x10, 0x14, 0x38, 0x1a, 0x0a, 0x51, 0x23, 0x7e, - 0x18, 0x74, 0x24, 0x7a, 0x1c, 0x00, 0xff, 0x2d, 0x35, 0x0b, 0x1a, 0x50, 0x60, 0x08, 0xa5, 0xb8, - 0x02, 0x03, 0x4e, 0xa0, 0x08, 0x22, 0x80, 0xfe, -}; - -static struct edge_firmware_version_info IMAGE_VERSION_NAME = { - 2, 0, 3 }; // Major, Minor, Build - -#undef IMAGE_VERSION_NAME - -#undef IMAGE_ARRAY_NAME - diff --git a/firmware/Makefile b/firmware/Makefile index 5ed36ae..be3a9e9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -59,6 +59,8 @@ fw-shipped- := keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw endif fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw +fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \ + edgeport/down.fw edgeport/down2.fw fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ # whiteheat_loader_debug.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw diff --git a/firmware/WHENCE b/firmware/WHENCE index b14b86c..8eada2d 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -275,3 +275,21 @@ Licence: Unknown Found in hex form in kernel source. -------------------------------------------------------------------------- + +Driver: USB_SERIAL_EDGEPORT - USB Inside Out Edgeport Serial Driver + +File: edgeport/boot.fw +File: edgeport/boot2.fw +File: edgeport/down.fw +File: edgeport/down2.fw + +Licence: Allegedly GPLv2+, but no source visible. Marked: +//************************************************************** +//* Edgeport/4 Binary Image +//* Generated by HEX2C v1.06 +//* Copyright (C) 1998 Inside Out Networks, All rights reserved. +//************************************************************** + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/edgeport/boot.H16 b/firmware/edgeport/boot.H16 new file mode 100644 index 0000000..4bf8e91 --- /dev/null +++ b/firmware/edgeport/boot.H16 @@ -0,0 +1,29 @@ +:0004000000010C0002ED +:000200000400FFFB +:000600000002008002000373 +:0003000B0002000BE5 +:00030013000201B82F +:0003001B0002001BC5 +:0003002300020023B5 +:0003002B0002002BA5 +:000300330002003395 +:0003003B0002003B85 +:00030043000201BDFA +:0003004B000201D0DF +:000300530002012186 +:0003007B0002007B05 +:01660080007EB0007AB33FF27EF800237E00017E100012075F6920000ABE240000780575900D800375901DD2B57E0000A5D8FD75A80075B100A9D587CA291209CC1209A0F5097AA1201201E6DA29A9D0C77E00057A01F175E110A9D7F4A9D7E4A5D8F175F10075E13F75A20375A30075C00075C100A9D1B1A9D0B1A9D5D3D2AFE47E0428008DEF1B0478FA04A934D30330E0EEBE240000780563903080E3B29580DFBEB00222C0D0A920DF0FA931DF030201B575080112083380FE7508FE12083375A8007EB33FF230E04B300146C2927E2480007E1109740819B20010740E19B200042E240100A5D9ED7E2480007E1109E4D5E0FD09B2000820E00A09B2000009B2001880EB2E240100A5D9E4439030D2AA8005D2AA439034D2AFA9D1870000000000A911DF03A9D2DF7508FF120833C0D1CA02FFCA06830032D0D032C28BC2AA32750808120833A9C0B1A9C5D3A9C6D3A9D2B132CAB8750802120833E5C0540368051201EE80F5DAB832AE +:00011BCA00001A +:064D01E600E47AB33FF1020263CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEBC0F17EB3012BB400028019B4011630C00875F10012024D801F30C11C75F1001202DE801430C10875F1001202DE800930C00675F10012024DD0F1DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22C2C07EB3012BB4020712026F02026322B401FC0202A97E00007A03012B7A03012C227EB3012354606005B4401580137EB30124B4050C7508711208337EB30126F58F2275F60022BE57012928047E5701297A0F012E7A5701320202A97EEF012E7EF701327E0701324D0068217E00007EEBB0F5F3A3A5081BF46804A5B808F07AEF012E7AF701327508061208337A01F622C2C1750803120833A936E216E5F554C06807A9D7F4A927F4FC53E13F43F2880203557EB3012CB4020FA9D4E47EB0007AB3012C7AB3012B22B401397E21E67C327E13012D2C217A23012D7E00002E040134E5E37A09B00B04A5DBF6A9D4E47508701208337EB3012D7EA3012ABCAB78031203EC22020755E5E6B40865A9C4E27E01E37E11E37E31E37E21E37E51E37E41E37E71E37E61E37A0F01237A1F01277508041208337A01081208337A11081208337A21081208337A31081208337A41081208337A51081208337A61081208337A7108120833A9D4E4A9D7F4A9C6E21203C0226D007E1401027A0701327A03012D7EB3012320E70F7A23012C7A33012BBE0701296809227A33012C7A23012B7EB3012354E3232330E002D2E530E702D2E430E50630E403020755543EF5F003541FC325F09004187584FF7302056C0204600206090206240205050204C602063D02063D0206400206400206400206400206400206400206400206400206460206FA0206430206430206430206430206430206437EB30124B4062A7EB3012560567C0B7E1301267E1701277508721208337A01081208337A110812083312075F4035020294B408107508741208337EB33FF1F5F375F60122B4001C7508751208337EB33FF230E00575F302800375F30075F30075F602220207557EB30124B400357508761208337EB30128540FF5F17EB3012820E709E5E130E70D7401800BE5E130E60474018002740053F180F5F375F30075F60222020755C0F17EB30128540F42F17EB30126B400457EB30124B401247508771208337EB30128540F780553E13F80377EB3012820E70553E17F802B53E1BF8026B403177508781208337EB3012820E70543E180801143E140800C43E1C0D0F175080712083322D0F10202907EB30124B409237508791208337EB30126BEB33FF16811CAB8C0F112011DD0F1DAB850767AB33FF1806DB4050875087A1208338062B4031975087B1208337EB30126B401557EB33FF244017AB33FF28046B4011975087C1208337EB30126B401397EB33FF254FE7AB33FF2802AB4072A7EB3012560247C0B7E1301267E1701277508731208337A01081208337A110812083312078B40030202900207557EB30124B40BF675087D1208337EB301267EA301284CAB78E480DF7EB30124B40ADB75087E1208337EB3012670CFF5F375F601220207550207550207557EB30124B404207508C31208337E0400017E1701257E1801347A1C00007E47012912083F0206F4B4063A7508C11208337E5800007A5C00FE7DCA7ED701257E7801347A7C00007E7701297508C1120833C0A8C087C2AFA9D5871208D6D087D0A8404F804AB4001CC2AFA9D587120290E48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B409127E5701254D556805A9D2B18003A9C2B18016B40716C2AF7E0701277E170125C0D1CA18CA38CA28320202900207557EB30124B403157508C21208337E0400017E1701257E570129020294B405397508C0120833C0A8C087C2AFA9D5877E0801347A0C00007E2400FE7E3701257E47012912083FD087D0A87E0801347A0C00007E57012902029402075575080712083343E1C022C0A8C087C2AFA9D5871207CA40197E0801347A0C0000CA0BCA4912083FDA59DA0BD087D0A8C322D087D0A822C0A8C087C2AFA9D5871207CA402B7E5800007A5C00FE7F617E7801347A7C00007E770129BD7478117508C11208331208D64006D087D0A8C322D087D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347F037E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D32234 +:00407FC00040010200CA1B010C0200007C0000010000000000000000000000000000000000000000000000000000000000000000000000000000000000F17F0000000000005D +:1397083300CA087E01087A033FF0DA082280500B1A600B350B1A700B350B1A800B350B1A900B350B1AA00B350B1AB00B350B1AC00B350B1AD00B351B0A600B151B0A700B151B0A800B151B0A900B151B0AA00B151B0AB00B151B0AC00B151B0AD00B159E44001050AA2E440010680E7E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D78120900DA7940089D7868028005C2D722DA6B43903074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802C6D007C207F169F107F279F207E2B007E1B10BC0178160B2C0B1CA5DBEF7CB620E0036390304D777893C2D722D2D7220004000400000604020400020104010200000000000000000202020202040008100210040208000101087E187FBD7A1C00FF0B1A00BE1014381A0A51237E1809767A1C00FF2D350B1A506008A5B802034EA0082280FE7EE87FBF7AEC00FFE0F52254C068167EE87FBE7AEC00FFE0600C1209A0F5097AA120020F0A22C295D2941219FB5390CF1219FB80F10D0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0D0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A45646765706F72742F34202D20486172647761726520446961676E6F73746963732C2052657620312E30303B20436F70797269676874203139393820496E73696465204F7574204E6574776F726B730D0A0050617373004641494C202121005061737320202020004641494C20212120000D0A4465746563742052616D3A2020202020202020202020202020202020202020000D0A52616D20546573743A20202020202020202020202020202020202020202020000D0A416464726573732062697420302D313420746573743A202020202020202020000D0A57726F746520416464726573733A2030303A0020207769746820646174613A20002C20616E6420726561643A20000D0A4F6E65206F7220626F7468206F662074686520666F6C6C6F77696E6720416464726573732062697473206C6973746564206172652073686F727465640D0A746F20736F6D657468696E673A200020616E6420000D0A44657465637420556172743A20202020202020202020202020202020202020000D0A53637261746368205061642C4669466F20456E61626C652026205253543A20000D0A0A202020556172742054657374732020202020202020202020202020202020202020506F727431202020506F727432202020506F727433202020506F7274340D0A2020202020202020202020202020202020202020202020202020202020202020202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D000D0A506F7274204465636F6465723A2020202020202020202020202020202020202020000D0A4469676974616C204C6F6F706261636B3A20202020202020202020202020202020000D0A416E616C6F67204C6F6F706261636B3A2020202020202020202020202020202020000D0A5258442C54584420746F205254532C4354532C52492053686F72743A2020202020000D0A5258442C54584420746F204454522C4453522C43442053686F72743A2020202020000D0A5254535B4354532C52495D20746F204454522C4453522C43442053686F72743A20000D0A5254535B4354532C43445D20746F204453522C52492053686F72743A2020202020000D0A4454525B4453522C43445D20746F205254532C4354532C52492053686F72743A20000D0A44545220746F204354532C43442053686F72743A20202020202020202020202020000D0A52545320746F204354532C5249204C6F6F706261636B3A20202020202020202020000D0A52545320746F204354532C4344204C6F6F706261636B3A20202020202020202020000D0A44545220746F204453522C4344204C6F6F706261636B3A20202020202020202020000D0A0A2020204520522052204F2052202121212C204520522052204F205220212121202C204520522052204F2052202121210D0A0A446961676E6F7374696373206E6F772077696C6C20656E7465722061206465627567206C6F6F70206F6620746865206669727374206465746563746564206572726F722E000D0A0A4E6F204861726477617265206572726F72732064657465637465642E0D0A00436F7079696E6720636F64652066726F6D204D617374657220746F20536C617665277320454570726F6D202E2E2E00446F6E650D0A0A2D3E205475726E20756E6974206F66662C20646973636F6E6E656374206361626C6520616E642072756E207374616E64616C6F6E6520646961676E6F73746963732E00C2AFC209C20A75900D201702D2B54390306C007E1003120F387E680A017A6C00FF121A930B0030B4028024021B3C20091DC294D2951219FB5390CF1219FBC295D2941219FBA5D9E64390301219FB227E680A947A6C00FF121A937EE410007E40557AE9400BE47E50AA7AE9501BE4BEE94068197E680A7A7A6C00FF121A93121A083009137AE9407EE91080F87E680A757A6C00FF121A930B007E680AD87A6C00FF121A937E7800007E700E7EA4FFFF7EB4BFFF7DCB0EC47DDC5DDB6CBB7DFA5EF47FFF7A7BB00BB07DFB5EF47FFF7A7BB00BB07DFC5EF47FFF7A7BB00BB07DFD5EF47FFF7A7BB06CBB7DFA5EF47FFFBE7BB078410BB07DFB5EF47FFFBE7BB078340BB07DFC5EF47FFFBE7BB078270BB07DFD5EF47FFFBE7BB0781A0BB0BEC4FFFE78920EB4A5DF8B7E680A827A6C00FF121A938077CA5BCA6B7E680A8B7A6C00FF121A937E680B2A7A6C00FF121A930A47121AC97E680B797A6C00FF121A936C77DA6BCA6B0B700EC4BEC4FFFF78F61B700A47121AC9121A08300930DA6BDA5B6CBB7E7800007DFA5EF47FFF7A7BB07DFB5EF47FFF7A7BB07DFC5EF47FFF7A7BB07DFD5EF47FFF7A7BB080D47E680AB67A6C00FF121A9330170E7E7804207A7C00007E447BE0800C7E7800007A7C00017E4480000B007E403A7C547F577D846C667A5B500B5C0B50A5DE020B501B8478F07C547F577D846C66BE5B50781A0B5C0B50A5DE020B501B8478EE7E680A757A6C00FF121A93804B7F457E680A7A7A6C00FF121A937E680AFA7A6C00FF121A937D4B121AC97E680B0F7A6C00FF121A936C887C95121AC97E680B1D7A6C00FF121A937E4B90121AC9121A083009057E4B9080FB7E680B7F7A6C00FF121A930B00D2927E24800009B20008BEB001780B09B20014BEB060780280177E680A7A7A6C00FF121A93121A0830091109B2000880FA7E680A757A6C00FF121A937E680BA17A6C00FF121A930B00C2921219EE7E2480007EA05519A2001C7EB00119B2000809B2001CBCAB783709B200085EB0C0BEB0C0782B7EA0AA19A2001C6CBB19B2000809B2001CBCAB781609B200085EB0C0780D7E680A757A6C00FF121A93801B7E680A7A7A6C00FF121A93121A0830090A19A2001C09B2001C80F67E680BC37A6C00FF121A937E680C457A6C00FF121A937E2480007E11097EB00119B2001C2E2401000BB0A5D9F37E2480007E11097EB0010B0009A2001CBCAB78167E680A827A6C00FF121A932E2401000BB0A5D9E280257E680A8B7A6C00FF121A93121A083009E47E2480007E110909A2001C2E240100A5D9F580EC7E680C697A6C00FF121A9312138A7E2480007E11090B00741019B200101213032E240100A5D9EE7E680C8D7A6C00FF121A937E2480007E11090B00E419B200101213032E240100A5D9EF3000030218B70213BB740719B200081219FB09B2000009B2001409B2000009B2001409B2000009B2001409B2000009B20014C20B7EB0551213647EB0AA1213647EB0001213647EB0FF121364300B0F7E680A8B7A6C00FF121A93121A08227E680A827A6C00FF121A932219B200001219EE09A20000BCAB780122200903D20B22121A0819B200001219EE09A2000080F3D2921219EEC2921219EE7E2480007E1109748019B2000C7E54000219A2000419B20000740319B2000C2E240100A5D9E1227E680CB17A6C00FF121A937E2480007E11090B001219EE09B200187EA05519A200001219EE09B200185EB005780D7E680A827A6C00FF121A93801A7E680A8B7A6C00FF121A93121A0830090919A200001219EE80F72E240100A5D9B67E680CD57A6C00FF121A937E2480007E11090B001219EE09B200187EA05519A200001219EE09B200185EB00A780D7E680A827A6C00FF121A93801A7E680A8B7A6C00FF121A93121A0830090919A200001219EE80F72E240100A5D9B630040302168C7E680CF97A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00219A200106CAA19A200101219EE09B200185EB00A783C7EA00119A200101219EE09B200187EA00319A200107EA00119A200101219EE09B200185EB00A78147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00219A200106CAA19A2001080F17E680D417A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00119A200106CAA19A200101219EE09B200185EB005783C7EA00219A200101219EE09B200187EA00319A200107EA00219A200101219EE09B200185EB00578147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00119A200106CAA19A2001080F17E680D897A6C00FF121A937E2480007E11090B007EA00219A200101219EE09B200185EB050BEB050781F6CAA19A200101219EE09B200185EB050780D7E680A827A6C00FF121A9380207E680A8B7A6C00FF121A93121A0830090F7EA00219A200106CAA19A2001080F12E240100A5D9A27E680DD17A6C00FF121A937E2480007E11090B0009B200187EA00119A200101219EE09B200185EB0A0BEB0A0781F6CAA19A200101219EE09B200185EB0A0780D7E680A827A6C00FF121A9380207E680A8B7A6C00FF121A93121A0830090F7EA00119A200106CAA19A2001080F12E240100A5D99E02182B7E680D1D7A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00219A200106CAA19A200101219EE09B200185EB006783C7EA00119A200101219EE09B200187EA00319A200107EA00119A200101219EE09B200185EB00678147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00219A200106CAA19A2001080F17E680D657A6C00FF121A937E2480007E11090B006CAA19A200101219EE09B200187EA00119A200106CAA19A200101219EE09B200185EB009783C7EA00219A200101219EE09B200187EA00319A200107EA00219A200101219EE09B200185EB00978147E680A827A6C00FF121A932E240100A5D99E80207E680A8B7A6C00FF121A93121A083009E67EA00119A200106CAA19A2001080F17E680DAD7A6C00FF121A937E2480007E11090B007EA00219A200101219EE09B200185EB090BEB090781F6CAA19A200101219EE09B200185EB090780D7E680A827A6C00FF121A9380207E680A8B7A6C00FF121A93121A0830090F7EA00219A200106CAA19A2001080F12E240100A5D9A20218B730170302193BC28A1219227E2480007E11096CAA19A200041219EE0B007EA00819A200101219EE208B3E20893B7EA00819A2000409A200104EA00219A200101219EE308B2330892009A200105EA0FD19A200101219EE7EA00019A200041219EE208B05208902801A121A083009147EA00219A2001000005EA0FD19A20010000080EC2E240100A5D98902193B2017FA12138A1219227E2480007E11090B002089267EA0FF19A200041219EE7EB05519B200001219EE30890F7EA00019A200041219EE2089028026121A083009207EA0FF19A200041219EE7EB05519B200001219EE7EA00019A200041219EE80E02E240100A5D9A802193B7E2480007E11097EA00819A200101219EE2E240100A5D9EF22300A197E680DF57A6C00FF121A93D2091219EE1219EE1219EE020F1030171C7E680E6F7A6C00FF121A937E680E917A6C00FF121A93121B3C0219E60B007E7819A07A7C00FF7F677A6C00007E703E7E7BB07A6BB00B7C0B6CA5DFF37E7819A07A7C000089787E7800007A7C00FE7E687FBF7A6C00FE74AA39B75555745539B72AAA74A039B755556C997A6B907E5427107E6B80BC8968081B5478F58AFF19DE8AFF19E6121A087E6B8080FB7E10FF121A8580F8CAF97EF400FF1BF478FCDAF922CAF97EF400001BF478FCDAF922200919D20A1219FBC295D2941219FB1219FB1219FB1219FB43903022CA0B7E10037C306C220B209E300A50F92E300B1B2068181219FB1219FB5390CF1219FB1219FB1219FB439030A5DAE81219FB1219FB1B3068191219FB1219FBC295D2941219FB1219FB1219FB439030A5DBE77E200A1219FBA5DAFAA5D9A7DA0B2220090A1219FBB2941219FBB2942230173220092FCA2BCA7B7E7880007A7C00FE121B1C7E6BA05CAA681029B70014546068F839A700000B6C80E91219EED2B5DA7BDA2B22121AD47E68000B121A9322CA59CA5B7EB4000B7CB8C4121B047CB8121B047CB9C4121B047CB9121B047EB0687AB9B00BB46CBB7AB9B0DA59DA5B225EB00F7CAB9EA00A40052EB03780032EB0307AB9B00BB422C2B5C2921219EE748039B7000C7E54000639A7000439B70000740339B7000C227E7800007A7C00FF7E5800007A5C00017F657E7420001208D640547E787C007A7C00FF7E5800007A5C00017E687C007A6C00017E7404001208D640337480121BB1402C5390CFD2087E0400087E14000084A5DBFCA5DAF9A5D9F67440121BB1400E7E680EC07A6C00FF121A930219E6C295D29480FEF50A7E78000A7A7C00007E687FBF7A6C00017E7400010208D6D2 +:0000000001FF +//************************************************************** +//* Edgeport/4 Binary Image +//* Generated by HEX2C v1.06 +//* Copyright (C) 1998 Inside Out Networks, 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. +//************************************************************** diff --git a/firmware/edgeport/boot2.H16 b/firmware/edgeport/boot2.H16 new file mode 100644 index 0000000..8b14295 --- /dev/null +++ b/firmware/edgeport/boot2.H16 @@ -0,0 +1,28 @@ +:000400000002000003F7 +:000200000400FFFB +:000600000002008002000373 +:0003000B0002000BE5 +:000300130002025690 +:0003001B0002001BC5 +:0003002300020023B5 +:0003002B0002002BA5 +:000300330002003395 +:0003003B0002003B85 +:000300430002004375 +:0003004B0002004B65 +:00030053000201F5B2 +:0003007B0002007B05 +:02160080007EB3910120E30C7EB33FF254FE7AB33FF2800A7EB33FF244017AB33FF274007AB3910074017AB391127EF800247E00017E10001209D06920000A5E401FBE24000078097E00037A03900080077E00027A03900075B0DF7E00017A0394007A0301247E00017A0393007E0000A5D8FD75A80075B100CA29120C66120C37F5217AA120200908200A0A7EB00C80087EB00080037EB0087AB39200120296DA2974107AB391017E20047CB2C2D7131313137AB3910074007AB3911074607AB3911C74027AB39112A5DADF74007AB3910074607AB3911C74107AB3910674107AB3910774347AB39113743F7AB3911474027AB3910674017AB3910774037AB3910674447AB3910774EF7AB3910474077AB391067EB391077AB10A750901D2AAD2AFE47E60024D2278037E60037C767E0428008DEF1B0478FA047E20077A2391067E2391077E310ABC3268227A210A7E21096817CAB874037AB391067EB3910744027AB39107DAB875090030E0C16C677A63900080B9BEB00222C0D07508FE120AC074027AB3910674007AB3910774037AB3910674007AB3910774027AB391047EB33FF230E00874187AB39101800674107AB3910174107AB391040202367508FF120AC074017AB3910474037AB391067EB3910754FC7AB3910732CAB8750802120AC07EB3910320E50830E02B12029E80F17EB3910430E005DAB802023930E105DAB80201F530E60512040380D530E205DAB802008080CBDAB8326D +:082A029600E47AB33FF1020341CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB74007AB391007EB3012EB40002801CB401197EB391145414680512030580237EB3911430E51C12044380177EB3911430E505120443800B7EB3911454146803120305DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B2220E41975080A120AC07EB3012D700A7EB3012EB4011F02039D02098B75080B120AC074147AB391147EB3012EB4020C12034D02034174047AB39114227E00007A03012E7A03012F227EB3012554606005B4401E801C7EB30126B40515750871120AC07EB301287EA0017AA391067AB391072274007AB3910074107AB3911222BE57012B28047E57012B7A0F01317A57013574107AB391122274007AB391007EB3911A70537EB3911420E44C7EEF01317EF701357E0701354D0068217E0000E07AB39117A3A5081BF46806A5B810F080197EB0007AB3012EBE0010680D7EB0007AB3012E74807AB3911E7AEF01317AF70135750806120AC074047AB3911422CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB750803120AC074007AB3012D74007AB3910074017AB391121204B2DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22750803120AC07EB3012FB4021174007AB3012F7AB3012E74207AB3911422B401467EB3910420E6427E23911A7C327E1301302C217A2301307E00002E0401377EB391167A09B00B04A5DBF474207AB39114750870120AC07EB301307EA3012CBCAB78031205522202098BDA5902041574E07AB391007E0391107E1391117E3391127E2391137E5391147E4391157E7391167E6391177A0F01257A1F0129750804120AC07A0108120AC07A1108120AC07A2108120AC07A3108120AC07A4108120AC07A5108120AC07A6108120AC07A7108120AC074007AB3910074407AB39104120526226D007E1401027A0701357A0301307EB3012520E70F7A23012F7A33012EBE07012B6809227A33012F7A23012E7EB3012554E3232330E002D2E530E702D2E430E50630E40302098B543EF5F003541FC325F090057E7584FF730207390205C60207D20207ED0206D002065B02081E02081E0208210208210208210208210208210208210208210208210208270208F902082402082402082402082402082402082474007AB3910074607AB3911C7EB30126B4062A7EB3012760797C0B7E1301287E170129750872120AC07A0108120AC07A1108120AC01209D04058020384B4081C750874120AC07EB33FF17E0801377A0C00007A0BB07E540001020384B40033750875120AC07E0801377A0C0000CA0B7EB33FF230E00774027A0BB0800574007A0BB00B1474007A0BB07E540002DA0B02038402098B74007AB3910074607AB3911C7EB30126B4005F750876120AC07EB3012A540FB402057EB0608017B400057EB000800F7EB3012A20E7057EB04080037EB0207AB391007EB3911130E0047401800274007E0801377A0C0000CA0B7A0BB00B1474007A0BB074007AB391007E540002DA0B02038402098B7EB3012A540FB402057EB0608017B400057EB000800F7EB3012A20E7057EB04080037EB0207AB391007EB30128B400267EB30126B4010E750877120AC074017AB39112801BB4030E750878120AC074017AB39111800A74007AB3910012098B2274007AB391000203777EB30126B4091F750879120AC07EB30128BEB33FF1680DCAB81201F1DAB850767AB33FF1806DB4050875087A120AC08062B4031975087B120AC07EB30128B401557EB33FF244017AB33FF28046B4011975087C120AC07EB30128B401397EB33FF254FE7AB33FF2802AB4072A7EB3012760247C0B7E1301287E170129750873120AC07A0108120AC07A1108120AC0120A0A400302037702098B7EB30126B40BF675087D120AC07EB301287EA3012A4CAB78E480DF74007AB3910074607AB3911C7EB30126B40ACF75087E120AC07EB3012870C37E0801377A0C00007A0BB07E54000102038402098B02098B02098B7EB30126B404207508C3120AC07E0400017E1701277E1801377A1C00007E47012B120ACC0208F3B406427508C1120AC07E5800007A5C00FE7DCA7ED701277E7801377A7C00007E77012B7508C1120AC0C0A8C2AF7E40017A439400120B637E4301247A439400D0A840658060B40024C2AF7EB0017AB394007AB30124120377E48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B4092074037AB391067E2391077E5701274D5568054E200280035E20FD7A2391078016B40716C2AF7E0701297E170127C0D1CA18CA38CA283202037702098B74007AB3910074607AB3911C7EB30126B403157508C2120AC07E0400017E1701277E57012B020384B405417508C0120AC0C0A8C2AF7E40017A4394007E0801377A0C00007E2400FE7E3701277E47012B120ACC7E4301247A439400D0A87E0801377A0C00007E57012B020384B401207E00007E1001750872120AC07A0108120AC07A1108120AC01209D0400302038402098B750807120AC07EB0027AB3900074007AB3910074407AB3911574017AB391117EB391155460BEB040680874207AB3911580ED74017AB3911274047AB3911474FF7AB3012D22C0A8C2AF7E40017A439400120A57401F7E0801377A0C0000CA0BCA49120ACCDA59DA0B7E4301247A439400D0A8C3227E4301247A439400D0A822C0A8C2AF7E40017A439400120A5740317E5800007A5C00FE7F617E7801377A7C00007E77012BBD7478177508C1120AC0120B63400C7E4301247A439400D0A8C3227E4301247A439400D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347F037E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D32248 +:00407FC00040010200D73102000300007C0000010000000000000000000000000000000000000000000000000000000000000000000000000000000000F17F00000000000044 +:10430AC000CA087E01087A033FF0DA082280500B1A600B350B1A700B350B1A800B350B1A900B350B1AA00B350B1AB00B350B1AC00B350B1AD00B351B0A600B151B0A700B151B0A800B151B0A900B151B0AA00B151B0AB00B151B0AC00B151B0AD00B159E44001050AA2E440010680E7E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D78120B8DDA7940089D7868028005C2D722DA6B7EC0037ED0007AD3900074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802F6D007C207F169F107F279F207E2B007E1B10BC0178190B2C0B1CA5DBEF7CB620E0066CDC7AD390004D777890C2D722D2D7220004000400000604020400020104010200000000000000000202020202040008100210040208000101087E187FBD7A1C00FF0B1A005E101FBE1014381A0A51237E180C0D7A1C00FF2D350B1A506008A5B802034EA0082280FE7EE87FBF7AEC00FFE0F52354C068387EE87FBE7AEC00FFE0602E120C37F5217AA12020090C200A127EB00E7AB3920080107EB0027AB3920080077EB00A7AB392007AB10D020CC4227EB0027AB3900012190C7EB0037AB3900012190C80EAC2AFC211C21275B0DF7E00017A0393007E00007A0390006C007E1003120CF57E682C667A6C00FF1219C40B008032021A6E20112B7EB0017AB3900012190C7EB0037AB3900012190C7EB0027AB3900012190CA5D9DC7EB0007AB3900012190C227E682CF97A6C00FF1219C47EE410007E40557AE9400BE47E50AA7AE9501BE4BEE94068197E682CDF7A6C00FF1219C41219193011137AE9407EE91080F87E682CDA7A6C00FF1219C40B007E682D3D7A6C00FF1219C47E7800007E700E7EA4FFFF7EB4BFFF7DCB0EC47DDC5DDB6CBB7DFA5EF47FFF7A7BB00BB07DFB5EF47FFF7A7BB00BB07DFC5EF47FFF7A7BB00BB07DFD5EF47FFF7A7BB06CBB7DFA5EF47FFFBE7BB078410BB07DFB5EF47FFFBE7BB078340BB07DFC5EF47FFFBE7BB078270BB07DFD5EF47FFFBE7BB0781A0BB0BEC4FFFE78920EB4A5DF8B7E682CE77A6C00FF1219C48077CA5BCA6B7E682CF07A6C00FF1219C47E682D8F7A6C00FF1219C40A471219FA7E682DDE7A6C00FF1219C46C77DA6BCA6B0B700EC4BEC4FFFF78F61B700A471219FA121919301130DA6BDA5B6CBB7E7800007DFA5EF47FFF7A7BB07DFB5EF47FFF7A7BB07DFC5EF47FFF7A7BB07DFD5EF47FFF7A7BB080D47E682D1B7A6C00FF1219C4301F0E7E7804207A7C00007E447BE0800C7E7800007A7C00017E4480000B007E403A7C547F577D846C667A5B500B5C0B50A5DE020B501B8478F07C547F577D846C66BE5B50781A0B5C0B50A5DE020B501B8478EE7E682CDA7A6C00FF1219C4804B7F457E682CDF7A6C00FF1219C47E682D5F7A6C00FF1219C47D4B1219FA7E682D747A6C00FF1219C46C887C951219FA7E682D827A6C00FF1219C47E4B901219FA1219193011057E4B9080FB7E682E287A6C00FF1219C40B007EB0807AB391007EA0557AA391107EB391077EB39110BCAB78207EA0AA7AA391107EB391077EB39110BCAB780D7E682CDA7A6C00FF1219C4801B7E682CDF7A6C00FF1219C412191930110A7AA391107EB3911080F67E682E4A7A6C00FF1219C41212310B007EE410007EA0A5CAA87AE9A07EB0307AB395007EE9A07EB0007AB3950012190C0BE57EB0207AB395007EE9B07EB0007AB395007EE9B0DAA8BCAB780D7E682CDA7A6C00FF1219C4801D7E682CDF7A6C00FF1219C412191930110C7EB0387AB395007EE9B080FB80007E682DE47A6C00FF1219C40B0075B0DF7E24800009B20008BEB001780B09B20014BEB060780280177E682CDF7A6C00FF1219C412191930111109B2000880FA7E682CDA7A6C00FF1219C47E682E067A6C00FF1219C40B0075B0EF1218FF7E2480007EA05519A2001C7EB00119B2000809B2001CBCAB783709B200085EB0C0BEB0C0782B7EA0AA19A2001C6CBB19B2000809B2001CBCAB781609B200085EB0C0780D7E682CDA7A6C00FF1219C4801B7E682CDF7A6C00FF1219C412191930110A19A2001C09B2001C80F67E682E6C7A6C00FF1219C47E682EEE7A6C00FF1219C47E2480007E11217EB00119B2001C2E2401000BB0A5D9F37E2480007E11217EB0010B0009A2001CBCAB78167E682CE77A6C00FF1219C42E2401000BB0A5D9E280257E682CF07A6C00FF1219C41219193011E47E2480007E112109A2001C2E240100A5D9F580EC7E682F127A6C00FF1219C41212317E2480007E11210B00741019B200101211AA2E240100A5D9EE7E682F367A6C00FF1219C47E2480007E11210B00E419B200101211AA2E240100A5D9EF30000302173B02126A740719B2000812190C09B2000009B2001409B2000009B2001409B2000009B2001409B2000009B20014C2137EB05512120B7EB0AA12120B7EB00012120B7EB0FF12120B30130F7E682CF07A6C00FF1219C4121919227E682CE77A6C00FF1219C42219B200001218FF09A20000BCAB780122201103D2132212191919B200001218FF09A2000080F375B0DF1218FF75B0EF1218FF7E2480007E1121748019B2000C7E54000219A2000419B20000740319B2000C740619B200082E240100A5D9DB227E682F5A7A6C00FF1219C47E2480007E11210B001218FF09B200187EA05519A200001218FF09B200185EB005780D7E682CE77A6C00FF1219C4801A7E682CF07A6C00FF1219C412191930110919A200001218FF80F72E240100A5D9B67E682F7E7A6C00FF1219C47E2480007E11210B001218FF09B200187EA05519A200001218FF09B200185EB00A780D7E682CE77A6C00FF1219C4801A7E682CF07A6C00FF1219C412191930110919A200001218FF80F72E240100A5D9B630040302159F7E682FA27A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00219A200106CAA19A200101218FF09B200185EB00A783C7EA00119A200101218FF09B200187EA00319A200107EA00119A200101218FF09B200185EB00A78147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00219A200106CAA19A2001080F17E682FEA7A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00119A200106CAA19A200101218FF09B200185EB005783C7EA00219A200101218FF09B200187EA00319A200107EA00219A200101218FF09B200185EB00578147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00119A200106CAA19A2001080F17E6830327A6C00FF1219C47E2480007E11210B007EA00219A200101218FF09B200185EB050BEB050781F6CAA19A200101218FF09B200185EB050780D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00219A200106CAA19A2001080F12E240100A5D9A27E68307A7A6C00FF1219C47E2480007E11210B0009B200187EA00119A200101218FF09B200185EB0A0BEB0A0781F6CAA19A200101218FF09B200185EB0A0780D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00119A200106CAA19A2001080F12E240100A5D99E7E68309E7A6C00FF1219C47E2480007E11210B0020B1267EA00219A200101218FF30B1196CAA19A200101218FF20B10D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00219A200106CAA19A2001080F12E240100A5D9AE02173B7E682FC67A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00219A200106CAA19A200101218FF09B200185EB006783C7EA00119A200101218FF09B200187EA00319A200107EA00119A200101218FF09B200185EB00678147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00219A200106CAA19A2001080F17E68300E7A6C00FF1219C47E2480007E11210B006CAA19A200101218FF09B200187EA00119A200106CAA19A200101218FF09B200185EB009783C7EA00219A200101218FF09B200187EA00319A200107EA00219A200101218FF09B200185EB00978147E682CE77A6C00FF1219C42E240100A5D99E80207E682CF07A6C00FF1219C41219193011E67EA00119A200106CAA19A2001080F17E6830567A6C00FF1219C47E2480007E11210B007EA00219A200101218FF09B200185EB090BEB090781F6CAA19A200101218FF09B200185EB090780D7E682CE77A6C00FF1219C480207E682CF07A6C00FF1219C412191930110F7EA00219A200106CAA19A2001080F12E240100A5D9A2201F681212311217A97E2480007E11210B002089267EA0FF19A200041218FF7EB05519B200001218FF30890F7EA00019A200041218FF20890280261219193011207EA0FF19A200041218FF7EB05519B200001218FF7EA00019A200041218FF80E02E240100A5D9A80217C202184C7E2480007E11217EA00819A200101218FF2E240100A5D9EF22301F0302184CC28A1217A90B00121816208B2474037AB3910674027AB39107740C7AB3910674007AB3910712190C308B06121816308BAD1219193011A712181674037AB3910674027AB3910712190C12181680E97EA00074027AB391067AA3910774037AB391067AA391071218FF74EF7AB3910474807AB39103740C7AB3910674087AB3910712190C223012197E6830C27A6C00FF1219C4D2111218FF1218FF1218FF020CCA301F1C7E68313C7A6C00FF1219C47E68315E7A6C00FF1219C4121A6E0218F70B007E7818B17A7C00FF7F677A6C00007E703E7E7BB07A6BB00B7C0B6CA5DFF37E7818B17A7C000089787E7800007A7C00FE7E687FBF7A6C00FE74AA39B75555745539B72AAA74A039B755556C997A6B907E5427107E6B80BC8968081B5478F58AFF18EF8AFF18F71219197E6B8080FB7E10FF1219AC80F8CAF97EF400FF1BF478FCDAF922CAF97EF400001BF478FCDAF922201120D21212190C7EB0027AB3900012190C12190C12190C12190C7EB0007AB3900022CA0B7E10037C306C220B209E300A50F92E300B1B20682012190C12190C7EB0037AB3900012190C12190C12190C7EB0007AB39000A5DAE012190C12190C1B30682012190C12190C7EB0027AB3900012190C12190C12190C7EB0007AB39000A5DBE07E200A12190CA5DAFAA5D998DA0B2220111412190C7EB0017AB3900012190C7EB0007AB3900022301F3220112FCA2BCA7B7E7880007A7C00FE121A4D7E6BA05CAA681029B70014546068F839A700000B6C80E91218FFD2B5DA7BDA2B22121A057E68000C1219C422CA59CA5B7EB4000C7CB8C4121A357CB8121A357CB9C4121A357CB9121A357EB0687AB9B00BB46CBB7AB9B0DA59DA5B225EB00F7CAB9EA00A40052EB03780032EB0307AB9B00BB422C2B575B0EF1218FF748039B7000C7E54000639A7000439B70000740339B7000C227E7800007A7C00FF7E5800007A5C00017F657E742000120B6340587E787C007A7C00FF7E5800007A5C00017E687C007A6C00017E740400120B6340377480121AEA40307E00037A039000D2107E0400087E14000084A5DBFCA5DAF9A5D9F67440121AEA400E7E68318D7A6C00FF1219C40218F77EB0027AB3900080FEF50B7E78000B7A7C00007E687FBF7A6C00017E740001020B6374 +:0000000001FF +//************************************************************** +//* Edgeport/4 Binary Image +//* Generated by HEX2C v1.06 +//* Copyright (C) 1998 Inside Out Networks, 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. +//************************************************************** diff --git a/firmware/edgeport/down.H16 b/firmware/edgeport/down.H16 new file mode 100644 index 0000000..7e36fe1 --- /dev/null +++ b/firmware/edgeport/down.H16 @@ -0,0 +1,29 @@ +:000400000001100004E7 +:000200000400FFFB +:00060000000200800244B082 +:0003000B000244723A +:0003001300020013D5 +:0003001B0002001BC5 +:0003002300020023B5 +:0003002B0002002BA5 +:000300330002003395 +:0003003B0002003B85 +:000300430002004375 +:0003004B00026EC47E +:000300530002758DA6 +:0003007B0002007B05 +:00070080007E14000002405154 +:088230000012372812303E1230541230E51231681235201238581231151231401230A080E0E52360197E14000009B101CFB4000280051419B101CFA50BBE312F78EB22C2AF7EB33FF1B4010AC0F175F1021270EFD0F1D2AF22C2AFE52260437E0701E1BE04038038397E0480007E200013502109A000044EA00519A000040A320953678E5E5127680B09A000104EA00119A000102E040100A50ABE212F78D1752200D2AF22C2AF7E20007E30017CB2230A2B4932018FBE34000068127EB121A54B7AB121CA19492230D59924DA193E30A50ABE212F78D6D2AF22460F49674CBF5017536F56C75A1F5D77C2AFE53260147E2000135007CAB8123102DAB8A50ABE212F78EFD2AF22CA281267ABDA2840090A2209B2678EF4523222C2AFE53460147E2000135007CAB8123132DAB8A50ABE212F78EFD2AF22CA280A220942003E1269C2DA2822C2AFE53560147E2000135007CAB812315DDAB8A50ABE212F78EFD2AF22CA287E4000126C5BDA2822C2AFE52360147E2000135007CAB8123185DAB8A50ABE212F78EFD2AF227CB2230A2B49223190892431A03210328032F0336033D0344034B07E27018FBE24000078247E24800009B20014CAB85EB01EDAB8680BCA197D121249307D21DA1930E6187E6000801EBE27019F680D7A27019F7E609C7A6301CF802E7E6301CFA5BE00267E60017EB0007EA0C81262B640187531B3127C15C2186C007A0301CFC0F175F101126FD9D0F1227E270191BE24000078247E24810009B20014CAB85EB01EDAB8680BCA197D12124C887D21DA1930E6187E6000801EBE2701A1680D7A2701A17E609C7A6301D0802E7E6301D0A5BE00267E60017EB0007EA0C81262B640187531B3127C15C2196C007A0301D0C0F175F101126FD9D0F1227E270193BE24000078247E24820009B20014CAB85EB01EDAB8680BCA197D12124FE07D21DA1930E6187E6000801EBE2701A3680D7A2701A37E609C7A6301D1802E7E6301D1A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21A6C007A0301D1C0F175F101126FD9D0F1227E270195BE24000078247E24830009B20014CAB85EB01EDAB8680BCA197D121253387D21DA1930E6187E6000801EBE2701A5680D7A2701A57E609C7A6301D2802E7E6301D2A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21B6C007A0301D2C0F175F101126FD9D0F1227E270197BE24000078247E24840009B20014CAB85EB01EDAB8680BCA197D121256907D21DA1930E6187E6000801EBE2701A7680D7A2701A77E609C7A6301D3802E7E6301D3A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21C6C007A0301D3C0F175F101126FD9D0F1227E270199BE24000078247E24850009B20014CAB85EB01EDAB8680BCA197D121259E87D21DA1930E6187E6000801EBE2701A9680D7A2701A97E609C7A6301D4802E7E6301D4A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21D6C007A0301D4C0F175F101126FD9D0F1227E27019BBE24000078247E24860009B20014CAB85EB01EDAB8680BCA197D12125D407D21DA1930E6187E6000801EBE2701AB680D7A2701AB7E609C7A6301D5802E7E6301D5A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21E6C007A0301D5C0F175F101126FD9D0F1227E27019DBE24000078247E24870009B20014CAB85EB01EDAB8680BCA197D121260987D21DA1930E6187E6000801EBE2701AD680D7A2701AD7E609C7A6301D6802E7E6301D6A5BE00267E60017EB0007EA0C81262B640187531B3127C15C21F6C007A0301D6C0F175F101126FD9D0F122C2AFE52460147E2000135007CAB812353DDAB8A50ABE212F78EFD2AF227CB2230A2B4922354889243558359235CC36063640367A36B436EE7E24800009B20014CAB85EB01EDAB8680BCA197D121249307D21DA195EB0017EA09012629340127531B8127C15C220C0F175F101126FD9D0F1227E24810009B20014CAB85EB01EDAB8680BCA197D12124C887D21DA195EB0017EA09012629340127531B8127C15C221C0F175F101126FD9D0F1227E24820009B20014CAB85EB01EDAB8680BCA197D12124FE07D21DA195EB0017EA09012629340127531B8127C15C222C0F175F101126FD9D0F1227E24830009B20014CAB85EB01EDAB8680BCA197D121253387D21DA195EB0017EA09012629340127531B8127C15C223C0F175F101126FD9D0F1227E24840009B20014CAB85EB01EDAB8680BCA197D121256907D21DA195EB0017EA09012629340127531B8127C15C224C0F175F101126FD9D0F1227E24850009B20014CAB85EB01EDAB8680BCA197D121259E87D21DA195EB0017EA09012629340127531B8127C15C225C0F175F101126FD9D0F1227E24860009B20014CAB85EB01EDAB8680BCA197D12125D407D21DA195EB0017EA09012629340127531B8127C15C226C0F175F101126FD9D0F1227E24870009B20014CAB85EB01EDAB8680BCA197D121260987D21DA195EB0017EA09012629340127531B8127C15C227C0F175F101126FD9D0F122C2AFE53360147E2000135007CAB8123745DAB8A50ABE212F78EFD2AF227CB2230A2B4922375089243760377F379E37BD37DC37FB381A38397E248000CA197D1212481BDA19100402800CD201C0F175F101126FD9D0F1227E248100CA197D12124B73DA19100402800CD201C0F175F101126FD9D0F1227E248200CA197D12124ECBDA19100402800CD201C0F175F101126FD9D0F1227E248300CA197D12125223DA19100402800CD201C0F175F101126FD9D0F1227E248400CA197D1212557BDA19100402800CD201C0F175F101126FD9D0F1227E248500CA197D121258D3DA19100402800CD201C0F175F101126FD9D0F1227E248600CA197D12125C2BDA19100402800CD201C0F175F101126FD9D0F1227E248700CA197D12125F83DA19100402800CD201C0F175F101126FD9D0F122C2AFC0F175F101A932F21A7E0701E1BE0400007810E5F53382E74009853131127C1575F600D0F1D2AF2247 +:3C154000007E0400017E147FF87E2400FE7D310B1A501B0A507E14401B02406A7EF8006FD204C294D2957EF4402C02407C127D30F52F7AA1307A116E1275CA1240DC7EB33FF160031243D475F10012766FD2AF0230007E0400FF7E18405F7A1C00018918A9258703A9D587D29389087E0400FF7E1840787A1C00018918C29389087E0800207E4404007E40007EE4408E027C307E08016F7E44287C7E40007EE440A0027C307E08006F7E4401007E40537EE440B2027C30756D20756C307E040008756A58756B08756708756901758901758A01758C00D28C7E0400027A055889F475B77F75B87F75B30775B207D2A922D292E4D5E0FDC2927E2480007E112F7EA00819A200102E240100A5D9F27E200012417E0B20BE212F78F6227E0480004C0274BF19B0000C741019B00008748019B0000C7E54000219A0000419B00000740319B0000C7407A920300BA9353005BE20012802740F19B00004A933301874BF19B0000C7428A9203002742019B00004740319B0000C74A719B00008740C19B00010227E0480004C02E419B0000409B00010540819B0001074A719B00008227CB2230A2B492241A5892441B541D441F3421242314250426F428EC210C218C220C2087E0409E37A07016F7A07017F6D007A07018F7A07019F22C211C219C221C2097E040DE37A0701717A0701816D007A0701917A0701A122C212C21AC222C20A7E0411E37A0701737A0701836D007A0701937A0701A322C213C21BC223C20B7E0415E37A0701757A0701856D007A0701957A0701A522C214C21CC224C20C7E0419E37A0701777A0701876D007A0701977A0701A722C215C21DC225C20D7E041DE37A0701797A0701896D007A0701997A0701A922C216C21EC226C20E7E0421E37A07017B7A07018B6D007A07019B7A0701AB22C217C21FC227C20F7E0425E37A07017D7A07018D6D007A07019D7A0701AD227CB2230A2B492242B8892442C842E9430A432B434C436D438E43AF305007206804C2288016304007206004C228800C304807205804C2288002D22822305107206904C2298016304107206104C229800C304907205904C2298002D22922305207206A04C22A8016304207206204C22A800C304A07205A04C22A8002D22A22305307206B04C22B8016304307206304C22B800C304B07205B04C22B8002D22B22305407206C04C22C8016304407206404C22C800C304C07205C04C22C8002D22C22305507206D04C22D8016304507206504C22D800C304D07205D04C22D8002D22D22305607206E04C22E8016304607206604C22E800C304E07205E04C22E8002D22E22305707206F04C22F8016304707206704C22F800C304F07205F04C22F8002D22F22443843E5BEB002400122230A5B495543D09954D322A9C5871244437E0405E37A0701D77A0701D97E0401E37A0701DD7A0701DF7E0474AD7A056175F10175E11F75E40475F40475F10275E10375E40475F40443A21C1240EB7E200012419A0B20BE212F78F6D2A822A9D587124443D292C2A82275A30053A20375C10053C0037E00057A01F143F48043E480E5F2547F4408F5F2E5E2547F4408F5E275E110A5D8E122CA09123020100112D5671E6369017E006A2E0169A5E6F567801220021E756900856A67D2027400800D30020FC2027E006C2E0169A5E65390CF4290DA0932C0D0C0D1C0E0C0F0CA0BCA1BCA2BD201753189127C157E14800009B1000820E00302454F20785AA50A09B1000820E00302456720794BA50A09B1000820E00302457FA50A09B1000820E003024597207A30A50A09B1000820E0030245AFA50A09B1000820E0030245C7A50A09B1000820E0030245DFA50A09B1000820E0030245F730040CC204C0F175F101126FD9D0F1DA2BDA1BDA0BD0F0D0E0D0D1D0D032753180127C15543E0A5B7E4400FF6952632BCA06C6448954753181127C15543E0A5B7E4400FF6952636BCA06C6448954753182127C15543E0A5B7E4400FF695263ABCA06C6448954753183127C15543E0A5B7E4400FF695263EBCA06C6448954753184127C15543E0A5B7E4400FF6952642BCA06C6448954753185127C15543E0A5B7E4400FF6952646BCA06C6448954753186127C15543E0A5B7E4400FF695264ABCA06C6448954753187127C15543E0A5B7E4400FF695264EBCA06C644895410080122202803D208227531A0127C157E1480008006202803D2082209B10014CAB85EB01EDAB8680312493020E603D20822303049D2707E37018F7E2701AF9D3240317D022E05487A05487A37018F7E37016F7D432D42BE440DE238687A47016F753194127C157A5131127C1512652B1070C422C2702D2368786D33801A7E27018FBE240000686ABE2701AF28047E2701AF7E37018F9D327D022E05487A05487A37018F7E37016F7D432D42BE440DE238137A47016F753194127C157A5131127C1502652B753194127C157A5131127C159E440DE39D2412652B7E3409E37D242D437A47016F12652BBE2520780302467F22D2087E0409E37A07016F7A07017F753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701BF2E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2400002E2701BF1B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B1000430380A09B1001054FE19B10010D21022807D7A5131127C159E4405E39D247E6400002E6701BF9E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344007A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70247E3753199127C1509B1000454FA19B1000430380A09B1001054FE19B10010D21022DAB830E0D8BD326807CAB81247E3DAB802493009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D2688002C268A5FD5E50206804D2608002C260A5FD5E50806804D2588002C2581242C8026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22024835753195127C1522753196127C152210090122202903D209227531A1127C157E1481008006202903D2092209B10014CAB85EB01EDAB86803124C8820E603D20922303149D2717E3701917E2701B19D3240317D022E054A7A054A7A3701917E3701717D432D42BE4411E238687A470171753194127C157A5131127C1512652B1071C422C2712D2368786D33801A7E270191BE240000686ABE2701B128047E2701B17E3701919D327D022E054A7A054A7A3701917E3701717D432D42BE4411E238137A470171753194127C157A5131127C1502652B753194127C157A5131127C159E4411E39D2412652B7E340DE37D242D437A47017112652BBE252078030249D722D2097E040DE37A0701717A070181753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C12E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2401002E2701C11B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B1000430390A09B1001054FE19B10010D21122807D7A5131127C159E4405E39D247E6401002E6701C19E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344017A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024B3B753199127C1509B1000454FA19B1000430390A09B1001054FE19B10010D21122DAB830E0D8BD326807CAB8124B3BDAB8024C8809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D2698002C269A5FD5E50206804D2618002C261A5FD5E50806804D2598002C2591242E9026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22024B8D753195127C1522753196127C1522100A0122202A03D20A227531A2127C157E1482008006202A03D20A2209B10014CAB85EB01EDAB86803124FE020E603D20A22303249D2727E3701937E2701B39D3240317D022E054C7A054C7A3701937E3701737D432D42BE4415E238687A470173753194127C157A5131127C1512652B1072C422C2722D2368786D33801A7E270193BE240000686ABE2701B328047E2701B37E3701939D327D022E054C7A054C7A3701937E3701737D432D42BE4415E238137A470173753194127C157A5131127C1502652B753194127C157A5131127C159E4415E39D2412652B7E3411E37D242D437A47017312652BBE25207803024D2F22D20A7E0411E37A0701737A070183753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C32E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2402002E2701C31B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303A0A09B1001054FE19B10010D21222807D7A5131127C159E4405E39D247E6402002E6701C39E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344027A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024E93753199127C1509B1000454FA19B10004303A0A09B1001054FE19B10010D21222DAB830E0D8BD326807CAB8124E93DAB8024FE009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26A8002C26AA5FD5E50206804D2628002C262A5FD5E50806804D25A8002C25A12430A026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22024EE5753195127C1522753196127C1522100B0122202B03D20B227531A3127C157E1483008006202B03D20B2209B10014CAB85EB01EDAB8680312533820E603D20B22303349D2737E3701957E2701B59D3240317D022E054E7A054E7A3701957E3701757D432D42BE4419E238687A470175753194127C157A5131127C1512652B1073C422C2732D2368786D33801A7E270195BE240000686ABE2701B528047E2701B57E3701959D327D022E054E7A054E7A3701957E3701757D432D42BE4419E238137A470175753194127C157A5131127C1502652B753194127C157A5131127C159E4419E39D2412652B7E3415E37D242D437A47017512652BBE2520780302508722D20B7E0415E37A0701757A070185753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C52E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2403002E2701C51B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303B0A09B1001054FE19B10010D21322807D7A5131127C159E4405E39D247E6403002E6701C59E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344037A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70251EB753199127C1509B1000454FA19B10004303B0A09B1001054FE19B10010D21322DAB830E0D8BD326807CAB81251EBDAB802533809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26B8002C26BA5FD5E50206804D2638002C263A5FD5E50806804D25B8002C25B12432B026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB2202523D753195127C1522753196127C1522100C0122202C03D20C227531A4127C157E1484008006202C03D20C2209B10014CAB85EB01EDAB8680312569020E603D20C22303449D2747E3701977E2701B79D3240317D022E05507A05507A3701977E3701777D432D42BE441DE238687A470177753194127C157A5131127C1512652B1074C422C2742D2368786D33801A7E270197BE240000686ABE2701B728047E2701B77E3701979D327D022E05507A05507A3701977E3701777D432D42BE441DE238137A470177753194127C157A5131127C1502652B753194127C157A5131127C159E441DE39D2412652B7E3419E37D242D437A47017712652BBE252078030253DF22D20C7E0419E37A0701777A070187753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C72E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2404002E2701C71B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303C0A09B1001054FE19B10010D21422807D7A5131127C159E4405E39D247E6404002E6701C79E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344047A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025543753199127C1509B1000454FA19B10004303C0A09B1001054FE19B10010D21422DAB830E0D8BD326807CAB8125543DAB802569009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26C8002C26CA5FD5E50206804D2648002C264A5FD5E50806804D25C8002C25C12434C026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22025595753195127C1522753196127C1522100D0122202D03D20D227531A5127C157E1485008006202D03D20D2209B10014CAB85EB01EDAB868031259E820E603D20D22303549D2757E3701997E2701B99D3240317D022E05527A05527A3701997E3701797D432D42BE4421E238687A470179753194127C157A5131127C1512652B1075C422C2752D2368786D33801A7E270199BE240000686ABE2701B928047E2701B97E3701999D327D022E05527A05527A3701997E3701797D432D42BE4421E238137A470179753194127C157A5131127C1502652B753194127C157A5131127C159E4421E39D2412652B7E341DE37D242D437A47017912652BBE2520780302573722D20D7E041DE37A0701797A070189753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701C92E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2405002E2701C91B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303D0A09B1001054FE19B10010D21522807D7A5131127C159E4405E39D247E6405002E6701C99E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344057A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E702589B753199127C1509B1000454FA19B10004303D0A09B1001054FE19B10010D21522DAB830E0D8BD326807CAB812589BDAB80259E809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26D8002C26DA5FD5E50206804D2658002C265A5FD5E50806804D25D8002C25D12436D026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB220258ED753195127C1522753196127C1522100E0122202E03D20E227531A6127C157E1486008006202E03D20E2209B10014CAB85EB01EDAB86803125D4020E603D20E22303649D2767E37019B7E2701BB9D3240317D022E05547A05547A37019B7E37017B7D432D42BE4425E238687A47017B753194127C157A5131127C1512652B1076C422C2762D2368786D33801A7E27019BBE240000686ABE2701BB28047E2701BB7E37019B9D327D022E05547A05547A37019B7E37017B7D432D42BE4425E238137A47017B753194127C157A5131127C1502652B753194127C157A5131127C159E4425E39D2412652B7E3421E37D242D437A47017B12652BBE25207803025A8F22D20E7E0421E37A07017B7A07018B753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701CB2E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2406002E2701CB1B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303E0A09B1001054FE19B10010D21622807D7A5131127C159E4405E39D247E6406002E6701CB9E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344067A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025BF3753199127C1509B1000454FA19B10004303E0A09B1001054FE19B10010D21622DAB830E0D8BD326807CAB8125BF3DAB8025D4009B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26E8002C26EA5FD5E50206804D2668002C266A5FD5E50806804D25E8002C25E12438E026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22025C45753195127C1522753196127C1522100F0122202F03D20F227531A7127C157E1487008006202F03D20F2209B10014CAB85EB01EDAB8680312609820E603D20F22303749D2777E37019D7E2701BD9D3240317D022E05567A05567A37019D7E37017D7D432D42BE4429E238687A47017D753194127C157A5131127C1512652B1077C422C2772D2368786D33801A7E27019DBE240000686ABE2701BD28047E2701BD7E37019D9D327D022E05567A05567A37019D7E37017D7D432D42BE4429E238137A47017D753194127C157A5131127C1502652B753194127C157A5131127C159E4429E39D2412652B7E3425E37D242D437A47017D12652BBE25207803025DE722D20F7E0425E37A07017D7A07018D753194127C15753100127C1522753192127C15D20409B10014CAB85482DAB878707E3701E17E2701CD2E2400022D32BE340400383C7D022E05467A05467A3701E17E3701DF7D432D42BE4405E238447A4701DF7E2407002E2701CD1B38200B357A5131127C15BE503878030266160265FB753199127C1509B1000454FA19B10004303F0A09B1001054FE19B10010D21722807D7A5131127C159E4405E39D247E6407002E6701CD9E24000240171B38600B351265FB7E3401E37D242D437A4701DF0265FB7A39C07E3401E37A39D00B341B4480E59D327CB6540F23232344077A69B07A79700B35753193127C157A7131127C15BD0468297A0701DF7E4701E12D437A4701E12E35467A35462209B1001420E013227E0401E3802A7E0401E3802C7E0401E380D1D2047E0701E17E2403FE9D2028407E0701DF7E4405E37D600B04BD0468D07D700B04BD0468CE7D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025F4B753199127C1509B1000454FA19B10004303F0A09B1001054FE19B10010D21722DAB830E0D8BD326807CAB8125F4BDAB802609809B100187EA088753190127C15F531127C15A5FC5EB0F0A5FD09B100184C4B5EB0F0BCB578F15E400F4C547CB55E500B682AA5FD5E50106804D26F8002C26FA5FD5E50206804D2678002C267A5FD5E50806804D25F8002C25F1243AF026293753191127C1509B100147AB131127C1520E008D2047EA080026293D20430E1067EA080126293CAB85EB01CDAB868127EA0C0096100001262B609B1001420E0DB22025F9D753195127C1522753196127C15227C027E1480004C2009B10018A5FD5E50106804D2688002C268A5FD5E50206804D2608002C260A5FD5E50806804D2588002C25802627F7C027E1480004C2009B10018A5FD5E50106804D2698002C269A5FD5E50206804D2618002C261A5FD5E50806804D2598002C25902627F7C027E1480004C2009B10018A5FD5E50106804D26A8002C26AA5FD5E50206804D2628002C262A5FD5E50806804D25A8002C25A02627F7C027E1480004C2009B10018A5FD5E50106804D26B8002C26BA5FD5E50206804D2638002C263A5FD5E50806804D25B8002C25B02627F7C027E1480004C2009B10018A5FD5E50106804D26C8002C26CA5FD5E50206804D2648002C264A5FD5E50806804D25C8002C25C02627F7C027E1480004C2009B10018A5FD5E50106804D26D8002C26DA5FD5E50206804D2658002C265A5FD5E50806804D25D8002C25D02627F7C027E1480004C2009B10018A5FD5E50106804D26E8002C26EA5FD5E50206804D2668002C266A5FD5E50806804D25E8002C25E02627F7C027E1480004C2009B10018A5FD5E50106804D26F8002C26FA5FD5E50206804D2678002C267A5FD5E50806804D25F8002C25F02627F54F0C4A5FFC4A54F753190127C15F531127C1522CA195E20074CA27E7429E3CA797A79A00B747A79B00B74DA797E30027E6400020262DECA195E20074CA27E7429E3CA797A79A00B747A79B00B747A79600B74DA797E30037E6400030262DED2047E2701E12D26BE240400382E7E0701DF7E4405E37E79A07A09A00B040B74BD046823A5DBEF7A2701E17E25462D267A25467A0701DFDA19C2D72275319A127C15DA19D2D7227E0401E380D748B64625471C491544C644C6481B44C6495944C644C644C644C644C644C644C6496044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C64C0E497D4A744C6D44C644C64B7344C64CB144C644C644C644C644C644C644C64CB844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C64F664CD54DCC4FC544C644C64ECB44C6500944C644C644C644C644C644C644C6501044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C652BE502D5124531D44C644C6522344C6536144C644C644C644C644C644C644C6536844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C656165385547C567544C644C6557B44C656B944C644C644C644C644C644C644C656C044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C6596E56DD57D459CD44C644C658D344C65A1144C644C644C644C644C644C644C65A1844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C65CC65A355B2C5D2544C644C65C2B44C65D6944C644C644C644C644C644C644C65D7044C644C644C644C644C644C644C644C644C644C644C644C644C644C644C6601E5D8D5E84607D44C644C65F8344C660C144C644C644C644C644C644C644C660C844C644C644C644C644C644C644C644C644C644C644C644C644C644C644C6CA291E50400D7E540B109CB5A42E54654889547E39007A19000B3480E90B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B350B38007A19007A19100B35DA29221E50400D7E540B1C9CB5A42E54661689547E19007A39000B3480E97E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B357E19007E19101B38000B352267966963697B6A496AE46B8E6BA96C3B6BC46C05699669AA7CB3BEB00B2814753109127C15756D10C0F175F10143E1C0D0F122C0A8C2AF236CAA2E54674B0B5850895401020408102040807531B0127C150A3209B3678E423219430036D0A8227CB2230A3B493367CB0A220932003609B2678EA5BB0005F4523380024233893467DB680968376865689368C168EF691D1241B5D228D208C240C248C238C2306D007A0301CF7E0400207A0701AF7E0400387A0701BF1241161260CF02694B1241D4D229D209C241C249C239C2316D007A0301D07E0400207A0701B17E0400387A0701C112411612610502694B1241F3D22AD20AC242C24AC23AC2326D007A0301D17E0400207A0701B37E0400387A0701C312411612613B02694B124212D22BD20BC243C24BC23BC2336D007A0301D27E0400207A0701B57E0400387A0701C512411612617102694B124231D22CD20CC244C24CC23CC2346D007A0301D37E0400207A0701B77E0400387A0701C71241161261A702694B124250D22DD20DC245C24DC23DC2356D007A0301D47E0400207A0701B97E0400387A0701C91241161261DD02694B12426FD22ED20EC246C24EC23EC2366D007A0301D57E0400207A0701BB7E0400387A0701CB12411612621302694B12428ED22FD20FC247C24FC23FC2376D007A0301D67E0400207A0701BD7E0400387A0701CD12411612624902694B7EA0D07E600F1262B6400CC0F175F101126FD9D0F1C2D7227531B1127C150A52236D005905004812417E12419AD0A8227531B2127C150A2209B2678E42237EB09C19B201CF123185D0A8227531B7127C150A2209B2678E422412353DD0A8227531B9127C150A3209B3678E42341943003E1269C2D0A8227CB2230A0B7CB420E0046D3380044930018F7EA0D8A5EFCA0BCA291262B6DA29DA0B40627531BA127C157CB430E01E6D335930018F7E3409E30A827E940400AD892D395930016F5930017F7CB430E1107E0480004C0209B00008440419B000080A0209B0678E4221F452347CB2230A0BCA19490030D59904DA19C0F175F101126FD9D0F1C2D7227E0480004C020930000C74BF19B0000C09B000081930000C7C745E700168124440CAB809B00010440219B00010DAB8800254BF7C745E700868044408800254F70930000CCAB874BF19B0000CDAB819B000081930000C0A6209B6678E3E200A627C745E700268204227CAB8746119B000087E440010594601BF09B00010440119B00010DAB88011F4522774A119B000087E440038594601BFD0A8227C747E0480004C020A6209B6678EA5FDF4A5FECA283E200A62A5EE52267E440020594601AFDA280930000C74BF19B0000C09B000087C745E7001680C4480CAB8A5ED422ADAB8800A547FCAB8A5EE522ADAB87C745E700868044402800254FD19B000081930000C7C745E70026810A5ED422842267E440008594601AF8004A5EE52287C745E70046810A5ED422942267E440008594601AF800BA5EE52297C745E700278001242ADD0A8227E0480004C020930000C74BF19B0000C194000101930000CD0A8227E0480004C020930000C74BF19B0000C194000181930000CD0A8227531B5127C157E0480004C0209B0000C444019B0000CE56EB4072309B000104EB00219B000100930000C74BF19B0000C09B0000454F719B000041930000CD0A8227531B6127C157E0480004C02E56EB407180930000C74BF19B0000C09B00004440819B000041930000C09B0000C54BF19B0000CD0A8227531B4127C157A2131127C157A4131127C150A3209B3678E4235126C5BD0A8227EB0017EA0C87C641262B640130A3209B3678EF45235C0F175F101126FD9D0F1226C8C6CD36D1A6D616DA86DEF6E366E7D753155127C15753100127C157A6131127C157A7131127C157E17017F7E27018F2D237E09B00B047A19B00B14BE140DE2380F1B3478EC7A17017F7A27018F02460F7E1409E380EB753155127C15753101127C157A6131127C157A7131127C157E1701817E2701912D237E09B00B047A19B00B14BE1411E2380F1B3478EC7A1701817A2701910249677E140DE380EB753155127C15753102127C157A6131127C157A7131127C157E1701837E2701932D237E09B00B047A19B00B14BE1415E2380F1B3478EC7A1701837A270193024CBF7E1411E380EB753155127C15753103127C157A6131127C157A7131127C157E1701857E2701952D237E09B00B047A19B00B14BE1419E2380F1B3478EC7A1701857A2701950250177E1415E380EB753155127C15753104127C157A6131127C157A7131127C157E1701877E2701972D237E09B00B047A19B00B14BE141DE2380F1B3478EC7A1701877A27019702536F7E1419E380EB753155127C15753105127C157A6131127C157A7131127C157E1701897E2701992D237E09B00B047A19B00B14BE1421E2380F1B3478EC7A1701897A2701990256C77E141DE380EB753155127C15753106127C157A6131127C157A7131127C157E17018B7E27019B2D237E09B00B047A19B00B14BE1425E2380F1B3478EC7A17018B7A27019B025A1F7E1421E380EB753155127C15753107127C157A6131127C157A7131127C157E17018D7E27019D2D237E09B00B047A19B00B14BE1429E2380F1B3478EC7A17018D7A27019D025D777E1425E380EBCAB8C0F1753102127C15E5C0540368051275CD80F530C20875F101126FD9801430C30875F101126EFD800930C40675F1021270E9D0F1DAB832753110127C15CA0BCA39CA59C2C3A921E25CE5E554C0684FE5E66CAA7E3701DB2D35BE340400384A7A3701DB7E3701D97D432D45BE4409E238407A4701D9753111127C157AB131127C151271B8A921E51FA9D4E4A924E4FCC2C3A921E23BE5E554C078B412745ADA59DA39DA0B2280298058753116127C1580ED753112127C157AB131127C159E4409E39D541271B87E3405E37D542D4380A1E5E554037812753113127C157E0F29FF0B0C7A0F29FF80A7753114127C157E0F2A030B0C7A0F2A03A9D7E4A927E4FC809D753115127C157E0F2A070B0C7A0F2A0780E5753118127C15CA09CA39CA2BC2C2A921F252E5F53382E740447E3701E17E5400409D3540437A3701E17E3701DD7D432D45BE4405E238527A4701DD7D45127316A920F522753119127C157A9131127C157A81F77A91F6E5F53382E750BCDA2BDA39DA0922804180642D536D3370B77E0401E37A0701DF7A0701DDA932F2DF853031127C1575F60080D4CA599E4405E39D541273167E3401E37D542D437A4701DD127316DA498099E5F55403781F7E0F29EF0B0C7A0F29EF809D7E0F29F70B0C7A0F29F7A9D7F4A927F4FC808A7E0F29F30B0C7A0F29F380EBE5F55403781F7E2F2A0F0B2C7A2F2A0F80347E2F2A170B2C7A2F2A17A9D7F4A927F4FC80217E2F2A130B2C7A2F2A1380EBDA2BDA1BDA0B22753128127C15CA0BCA1BCA2BC2C4A921F2B6E5F53372E740E07E0D467E1D4A7E2D4E7E3D527E85567D904D914D924D934D944D954D964D974D9868727A11F37A01F37A31F37A21F37A51F37A41F37A71F37A61F37A91F37A81F3307B1A7AB1F37AA1F37AD1F37AC1F37AF1F37AE1F37D787AF1F37AE1F3A930F5030270D6753129127C15207B0B75310A127C1575F60A8009753112127C1575F6126D007D107A0D467A0D4A7A0D4E7A0D527A0556DA2BDA1BDA0B221EB0400C7EA00AA47E0472FB9D0589047EA1E37A39A00B3480EAB440E37EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B357EA1E3E5E31B38500B35221EB0400C7EA00AA47E0474599D0589047E39A07AA1F30B3480EAB440E30B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B350B38507AA1F3F5F30B3522C2AF7E3701DB4D33683B7E0701D77E5409E39D50BD3540027D35CA397E65619964DA397E0701DB9D037A0701DB2E3701D77A3701D7BE3409E228C77E3405E37A3701D780BDD2AF22753153127C157E15638011753151127C150B08100B059E340002284D7CB220E7275407230A2B49226C7C7CB254780303037C2B9D13401A68127A15637A25657E6475377A656189240275457E6474AD80F22D139D31CA397D312D10CA19CA299924DA29DA09DA3980A27A15637E6475234D3378097CB220E72A7E6474A27A656122753152127C157E21637E09300B041B34788980D4753154127C157E15637E256580905E200754787E4475C130E6164D3368261B347E09400B047E44676320E3047E4475C9CA09CA399944DA39DA097E6474AD4D3368A689647A1563F5657E64758680997E1563E56580C4C0D0C0D1C0E0CA19A920DF12A921DF1B753101127C1553DFF71240DC800D7531FE127C157E140053024051DA19D0E0D0D1D0D03203A5CB19B180002222027642CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEBC0F17EB32A33B400028019B4011630C00875F10012762C801F30C11C75F1001276BD801430C10875F1001276BD800930C00675F10012762CD0F1DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22C2C07EB32A33B4020712764E02764222B401FC0276887E00007A032A337A032A34227EB32A2B54606005B4401580137EB32A2CB4050C753171127C157EB32A2EF58F2275F60022BE572A3128047E572A317A0F2A367A572A3A0276887EEF2A367EF72A3A7E072A3A4D0068217E00007EEBB0F5F3A3A5081BF46804A5B808F07AEF2A367AF72A3A753106127C157A01F622C2C1753103127C15A936E216E5F554C06807A9D7F4A927F4FC53E13F43F2880277297EB32A34B40204A9D4E422B401397E21E67C327E132A352C217A232A357E00002E042A3CE5E37A09B00B04A5DBF6A9D4E4753170127C157EB32A357EA32A32BCAB78031277C022027B29E5E6B40865A9C4E27E01E37E11E37E31E37E21E37E51E37E41E37E71E37E61E37A0F2A2B7A1F2A2F753104127C157A0131127C157A1131127C157A2131127C157A3131127C157A4131127C157A5131127C157A6131127C157A7131127C15A9D4E4A9D7F4A9C6E2127794226D007E1401027A072A3A7A032A357EB32A2B20E70F7A232A347A332A33BE072A316809227A332A347A232A337EB32A2B54E3232330E002D2E530E702D2E430E50630E403027B29543EF5F003541FC325F09077EC7584FF730279400278340279DD0279F80278D902789A027A11027A11027A14027A14027A14027A14027A14027A14027A14027A14027A1A027ACE027A17027A17027A17027A17027A17027A177EB32A2CB4062A7EB32A2D60567C0B7E132A2E7E172A2F753172127C157A0131127C157A1131127C15127B334035027673B40810753174127C157EB33FF1F5F375F60122B4001C753175127C157EB33FF230E00575F302800375F30075F30075F60222027B297EB32A2CB40035753176127C157EB32A30540FF5F17EB32A3020E709E5E130E70D7401800BE5E130E60474018002740053F180F5F375F30075F60222027B29C0F17EB32A30540F42F17EB32A2EB400457EB32A2CB40124753177127C157EB32A30540F780553E13F80377EB32A3020E70553E17F802B53E1BF8026B40317753178127C157EB32A3020E70543E180801143E140800C43E1C0D0F1753107127C1522D0F102766F7EB32A2CB40923753179127C157EB32A2EBEB33FF16811CAB8C0F11243D4D0F1DAB850767AB33FF1806DB4050875317A127C158062B4031975317B127C157EB32A2EB401557EB33FF244017AB33FF28046B4011975317C127C157EB32A2EB401397EB33FF254FE7AB33FF2802AB4072A7EB32A2D60247C0B7E132A2E7E172A2F753173127C157A0131127C157A1131127C15127B5F400302766F027B297EB32A2CB40BF675317D127C157EB32A2E7EA32A304CAB78E480DF7EB32A2CB40ADB75317E127C157EB32A2E70CFF5F375F60122027B29027B29027B297EB32A2CB404207531C3127C157E0400017E172A2D7E182A3C7A1C00007E472A31127C21027AC8B4063A7531C1127C157E5800007A5C00FE7DCA7ED72A2D7E782A3C7A7C00007E772A317531C1127C15C0A8C087C2AFA9D587127C5AD087D0A8404F804AB4001CC2AFA9D58712766FE48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B409127E572A2D4D556805A9D2B18003A9C2B18016B40716C2AF7E072A2F7E172A2DC0D1CA18CA38CA283202766F027B297EB32A2CB403157531C2127C157E0400017E172A2D7E572A31027673B405397531C0127C15C0A8C087C2AFA9D5877E082A3C7A0C00007E2400FE7E372A2D7E472A31127C21D087D0A87E082A3C7A0C00007E572A31027673027B29753107127C1543E1C022C0A8C087C2AFA9D587127B9E40197E082A3C7A0C0000CA0BCA49127C21DA59DA0BD087D0A8C322D087D0A822C0A8C087C2AFA9D587127B9E402B7E5800007A5C00FE7F617E782A3C7A7C00007E772A31BD7478117531C1127C15127C5A4006D087D0A8C322D087D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347FC27E1BB07E347F03B401047E347FCC7E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D322FA +:00047FC60001100400A2 +:014A7C1500CA087E01317A033FF0DA08227E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D78127C84DA7940089D7868028005C2D722DA6B43903074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802C6D007C207F169F107F279F207E2B007E1B10BC0178160B2C0B1CA5DBEF7CB620E0036390304D777893C2D722D2D7220004000442080604020400020104010282080000000000000202020202040208100210040208000101080001000200020208020420047E187FBD7A1C00FE0B1A005E101FBE101A381A0A51237E187CFA7A1C00FF2D350B1A506008A5B802034EA0082280FE73 +:0000000001FF +//************************************************************** +//* Edgeport/4 Binary Image +//* Generated by HEX2C v1.06 +//* Copyright (C) 1998 Inside Out Networks, 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. +//************************************************************** diff --git a/firmware/edgeport/down2.H16 b/firmware/edgeport/down2.H16 new file mode 100644 index 0000000..2f4b4ff --- /dev/null +++ b/firmware/edgeport/down2.H16 @@ -0,0 +1,29 @@ +:000400000002000003F7 +:000200000400FFFB +:00060000000200800245141D +:0003000B000244A507 +:00030013000263ABDA +:0003001B0002001BC5 +:0003002300020023B5 +:0003002B0002002BA5 +:000300330002003395 +:0003003B0002003B85 +:000300430002004375 +:0003004B0002004B65 +:000300530002675FE2 +:0003007B0002007B05 +:00070080007E14000002405253 +:0B663000001230641230FF12312F1230B080F2E52360197E14000009B101B9B4000280051419B101B9A50ABE212E78EB22C2AF7EB33FF1B40103126567D2AF22C2AF7EB33FF1B4011D74407AB391007EB3911A6CAA600FCA0BCA39CA59126424DA59DA39DA0BD2AF22C2AFE52260437E0701CBBE04038038397E0480007E200013502109A000044EA00519A000040A32095335335E5127680B09A000104EA00119A000102E040100A50ABE212E78D1752200D2AF22C2AFE52660367E20007E3001E526A55B68217CB2230A2B49320179BE34000068127EB121A54B7AB121CA19492230EF9924DA193E30A50ABE212E78D0D2AF22464F497C4CA94FD653035630595D5C8AC2AFE52460147E2000135007CAB812311CDAB8A50ABE212E78EFD2AF22CA2812354CDA2840090A2209B23533F4522422C2AFE52360147E2000135007CAB812314CDAB8A50ABE212E78EFD2AF227CB2230A2B492231578924316731D0323932A2330B337433DD34467E270179BE24000078247E24800009B20014CAB85EB01EDAB8680BCA197D121249457D21DA1930E6187E6000801EBE270189680D7A2701897E609C7A6301B980277E6301B9A5BE001F7E60017EB0007EA0C81261364011752FB3127335C2186C007A0301B9126486227E27017BBE24000078247E24810009B20014CAB85EB01EDAB8680BCA197D12124C727D21DA1930E6187E6000801EBE27018B680D7A27018B7E609C7A6301BA80277E6301BAA5BE001F7E60017EB0007EA0C81261364011752FB3127335C2196C007A0301BA126486227E27017DBE24000078247E24820009B20014CAB85EB01EDAB8680BCA197D12124F9F7D21DA1930E6187E6000801EBE27018D680D7A27018D7E609C7A6301BB80277E6301BBA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21A6C007A0301BB126486227E27017FBE24000078247E24830009B20014CAB85EB01EDAB8680BCA197D121252CC7D21DA1930E6187E6000801EBE27018F680D7A27018F7E609C7A6301BC80277E6301BCA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21B6C007A0301BC126486227E270181BE24000078247E24840009B20014CAB85EB01EDAB8680BCA197D121255F97D21DA1930E6187E6000801EBE270191680D7A2701917E609C7A6301BD80277E6301BDA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21C6C007A0301BD126486227E270183BE24000078247E24850009B20014CAB85EB01EDAB8680BCA197D121259267D21DA1930E6187E6000801EBE270193680D7A2701937E609C7A6301BE80277E6301BEA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21D6C007A0301BE126486227E270185BE24000078247E24860009B20014CAB85EB01EDAB8680BCA197D12125C537D21DA1930E6187E6000801EBE270195680D7A2701957E609C7A6301BF80277E6301BFA5BE001F7E60017EB0007EA0C81261364011752FB3127335C21E6C007A0301BF126486227E270187BE24000078247E24870009B20014CAB85EB01EDAB8680BCA197D12125F807D21DA1930E6187E6000801EBE270197680D7A2701977E609C7A6301C080277E6301C0A5BE001F7E60017EB0007EA0C81261364011752FB3127335C21F6C007A0301C012648622C2AF7E0701CBBE040000782874207AB391007EB3911530E51B7EB3911ABEB03F380C85312F12733574807AB3911E74207AB39115D2AF22353B36E83700371B37B6384E386938FB388438C57CB3BEB0092822752F0912733575570274207AB3910074017AB3911174407AB3910074017AB3911122C0A8C2AF236CAA2E5434E60B585089540102040810204080752FB01273350A2209B235334224D0A8227CB2230A3B4933355789343567359535C335F1361F364D367B36A91241BAD228D208C240C248C238C2306D007A0301B97E0400207A0701997E0400387A0701A9124127125FB70236D71241D7D229D209C241C249C239C2316D007A0301BA7E0400207A07019B7E0400387A0701AB124127125FE00236D71241F4D22AD20AC242C24AC23AC2326D007A0301BB7E0400207A07019D7E0400387A0701AD1241271260090236D7124211D22BD20BC243C24BC23BC2336D007A0301BC7E0400207A07019F7E0400387A0701AF1241271260320236D712422ED22CD20CC244C24CC23CC2346D007A0301BD7E0400207A0701A17E0400387A0701B112412712605B0236D712424BD22DD20DC245C24DC23DC2356D007A0301BE7E0400207A0701A37E0400387A0701B31241271260840236D7124268D22ED20EC246C24EC23EC2366D007A0301BF7E0400207A0701A57E0400387A0701B51241271260AD0236D7124285D22FD20FC247C24FC23FC2376D007A0301C07E0400207A0701A77E0400387A0701B71241271260D60236D77EA0D07E600F1261364005126486C2D722752FB11273350A52236D005905003212418312419FD0A822752FB21273350A2209B2353342237EB09C19B201B912314CD0A8227E0480004C020930000C74BF19B0000C09B000081930000C7C745E700168124440CAB809B00010440219B00010DAB8800254BF7C745E700868044408800254F70930000CCAB874BF19B0000CDAB819B000081930000C0A6209B635333E200A627C745E700268204227CAB8746119B000087E440010594601A909B00010440119B00010DAB88011F4522774A119B000087E440038594601A9D0A8227C747E0480004C020930000C74BF19B0000C09B000087C745E7001680444808002547F7C745E700868044402800254FD19B000081930000C0A6209B63533A5FDF4A5FECA283E200A62DA287C745E70026810A5ED422842267E440008594601998004A5EE52287C745E70046810A5ED422942267E440008594601998015A5EE52297C745E7002780A52267E440020594601991242A2D0A8227E0480004C020930000C74BF19B0000C194000101930000CD0A8227E0480004C020930000C74BF19B0000C194000181930000CD0A822752FB51273357E0480004C0209B0000C444019B0000CE558B4072309B000104EB00219B000100930000C74BF19B0000C09B0000454F719B000041930000CD0A822752FB61273357E0480004C02E558B407180930000C74BF19B0000C09B00004440819B000041930000C09B0000C54BF19B0000CD0A822752FB41273357A212F1273357A412F1273357EB0017EA0C87C64126136126486D0A822392E397539BC3A033A4A3A913AD83B1F752F55127335752F001273357A612F1273357A712F1273357E1701697E2701792D237E09B00B047A19B00B14BE14082C380F1B3478EC7A1701697A27017902464F7E14042D80EB752F55127335752F011273357A612F1273357A712F1273357E17016B7E27017B2D237E09B00B047A19B00B14BE140C2C380F1B3478EC7A17016B7A27017B02497C7E14082D80EB752F55127335752F021273357A612F1273357A712F1273357E17016D7E27017D2D237E09B00B047A19B00B14BE14102C380F1B3478EC7A17016D7A27017D024CA97E140C2D80EB752F55127335752F031273357A612F1273357A712F1273357E17016F7E27017F2D237E09B00B047A19B00B14BE14142C380F1B3478EC7A17016F7A27017F024FD67E14102D80EB752F55127335752F041273357A612F1273357A712F1273357E1701717E2701812D237E09B00B047A19B00B14BE14182C380F1B3478EC7A1701717A2701810253037E14142D80EB752F55127335752F051273357A612F1273357A712F1273357E1701737E2701832D237E09B00B047A19B00B14BE141C2C380F1B3478EC7A1701737A2701830256307E14182D80EB752F55127335752F061273357A612F1273357A712F1273357E1701757E2701852D237E09B00B047A19B00B14BE14202C380F1B3478EC7A1701757A27018502595D7E141C2D80EB752F55127335752F071273357A612F1273357A712F1273357E1701777E2701872D237E09B00B047A19B00B14BE14242C380F1B3478EC7A1701777A270187025C8A7E14202D80EB64 +:33354000007E0400017E147FF87E2400FE7D310B1A501B0A507E14401B0240747EF8005975B0DF7EB0017AB390007EF4403002408B12744EF52E7AA12D7A1158126B021240EB7EB33FF16003124379126BDED2AF0230007E0400FF7E1840607A1C000189187EB0017AB394007AB32C357EB0017AB3930089087E0400FF7E1840827A1C000189187EB0007AB3930089087E0800207E4404007E40007EE4409D0273507E0801597E442ADD7E40007EE440AF0273507E0800597E4401007E40537EE440C10273507557017556007E040008755458755508755108755301758901758A01758C00D28C7E0400027A054289F475B77F75B87F75B30175B201D2A92275B0DFE4D5E0FD75B0EF7E2480007E112E7EA00819A200102E240100A5D9F27E20001241830B20BE212E78F6227E0480004C0274BF19B0000C741019B00008748019B0000C7E54000219A0000419B00000740319B0000C7407206802740F19B00004306B1774BF19B0000C7428206802742019B00004740319B0000C74A719B00008740C19B00010227E0480004C02E419B0000409B00010540819B0001074A719B00008227CB2230A2B492241AA892441BA41D741F44211422E424B42684285C210C218C2087E04042D7A0701597A0701696D007A0701797A07018922C211C219C2097E04082D7A07015B7A07016B6D007A07017B7A07018B22C212C21AC20A7E040C2D7A07015D7A07016D6D007A07017D7A07018D22C213C21BC20B7E04102D7A07015F7A07016F6D007A07017F7A07018F22C214C21CC20C7E04142D7A0701617A0701716D007A0701817A07019122C215C21DC20D7E04182D7A0701637A0701736D007A0701837A07019322C216C21EC20E7E041C2D7A0701657A0701756D007A0701857A07019522C217C21FC20F7E04202D7A0701677A0701776D007A0701877A070197227CB2230A2B492242AD892442BD42D442EB4302431943304347435E304007205804C228800C304807205004C2288002D22822304107205904C229800C304907205104C2298002D22922304207205A04C22A800C304A07205204C22A8002D22A22304307205B04C22B800C304B07205304C22B8002D22B22304407205C04C22C800C304C07205404C22C8002D22C22304507205D04C22D800C304D07205504C22D8002D22D22304607205E04C22E800C304E07205604C22E8002D22E22304707205F04C22F800C304F07205704C22F8002D22F224466438ABEB002400122230A5B495543759954D3227EB0007AB394007AB32C3512447A7E04282D7A0701C17A0701C37E04242D7A0701C77A0701C97E04667F7A054B74207AB3910074607AB3911C74127AB3910674407AB39107741E7AB3911074487AB3911274107AB39113743F7AB3911474407AB3910074607AB3911C74147AB3910674407AB3910774167AB3911074087AB3911174207AB39113743F7AB3911474607AB3910074607AB3911C74167AB3910674207AB39107742F7AB3911074487AB3911274107AB39113743F7AB3911474027AB39106740F7AB391071240FA7E200012419F0B20BE212E78F6D2A8227EB0017AB394007AB32C3512447A75B0DFC2A82274027AB3910674017AB391077E20047CB2C2D7131313137AB3910074607AB3911C74027AB39112A5DAE522CA0912300E100134D5514074007AB3910074027AB391067EB3910774037AB391067EB391077EB391147EB391046353017E00542E0153A5E6F551801220021D755300855451D2027403800D30020EC2027E00562E0153A5E67AB39000DA0932456F458B45A745C345DF45FB46174633C0D0C0D1C0E0C0F0CA0BCA1BCA2BD201752F891273357EB3900060287E1480007E0000135013CA0BCA597CB0230A2B492245049924DA59DA0BA50AA508BE012E78E180D2300405C204126486DA2BDA1BDA0BD0F0D0E0D0D1D0D03209B1000820E014752F80127335543E0A5B7E4400FF695261AB89542209B1000820E014752F81127335543E0A5B7E4400FF695261EB89542209B1000820E014752F82127335543E0A5B7E4400FF6952622B89542209B1000820E014752F83127335543E0A5B7E4400FF6952626B89542209B1000820E014752F84127335543E0A5B7E4400FF695262AB89542209B1000820E014752F85127335543E0A5B7E4400FF695262EB89542209B1000820E014752F86127335543E0A5B7E4400FF6952632B89542209B1000820E014752F87127335543E0A5B7E4400FF6952636B89542210080122202803D20822752FA01273357E1480008006202803D2082209B10014CAB85EB01EDAB8680312494530300620E64FD2082230E602D2607E3701797E2701999D3240317D022E05327A05327A3701797E3701597D432D42BE44082C38687A470159752F941273357A512F1273351269F01060C422C2602D2368786D33801A7E270179BE240000686ABE27019928047E2701997E3701799D327D022E05327A05327A3701797E3701597D432D42BE44082C38137A470159752F941273357A512F1273350269F0752F941273357A512F1273359E44082D9D241269F07E34042D7D242D437A4701591269F0BE252078030246C222D2087E04042D7A0701597A070169752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701A92E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2400002E2701A91B38200B357A512F127335026A63752F9912733509B1000454FA19B1000430380A09B1001054FE19B10010D21022807F7A512F1273359E44282D9D247E6400002E6701A99E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344007A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E702481E752F9912733509B1000454FA19B1000430380A09B1001054FE19B10010D21022DAB830E0D8BD326807CAB812481EDAB802494509B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D2588002C258A5FD5E50806804D2508002C2501242BD026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22024872752F9512733522752F961273352210090122202903D20922752FA11273357E1481008006202903D2092209B10014CAB85EB01EDAB86803124C7230310620E64FD2092230E602D2617E37017B7E27019B9D3240317D022E05347A05347A37017B7E37015B7D432D42BE440C2C38687A47015B752F941273357A512F1273351269F01061C422C2612D2368786D33801A7E27017BBE240000686ABE27019B28047E27019B7E37017B9D327D022E05347A05347A37017B7E37015B7D432D42BE440C2C38137A47015B752F941273357A512F1273350269F0752F941273357A512F1273359E440C2D9D241269F07E34082D7D242D437A47015B1269F0BE252078030249EF22D2097E04082D7A07015B7A07016B752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701AB2E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2401002E2701AB1B38200B357A512F127335026A63752F9912733509B1000454FA19B1000430390A09B1001054FE19B10010D21122807F7A512F1273359E44282D9D247E6401002E6701AB9E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344017A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024B4B752F9912733509B1000454FA19B1000430390A09B1001054FE19B10010D21122DAB830E0D8BD326807CAB8124B4BDAB8024C7209B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D2598002C259A5FD5E50806804D2518002C2511242D4026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22024B9F752F9512733522752F9612733522100A0122202A03D20A22752FA21273357E1482008006202A03D20A2209B10014CAB85EB01EDAB86803124F9F30320620E64FD20A2230E602D2627E37017D7E27019D9D3240317D022E05367A05367A37017D7E37015D7D432D42BE44102C38687A47015D752F941273357A512F1273351269F01062C422C2622D2368786D33801A7E27017DBE240000686ABE27019D28047E27019D7E37017D9D327D022E05367A05367A37017D7E37015D7D432D42BE44102C38137A47015D752F941273357A512F1273350269F0752F941273357A512F1273359E44102D9D241269F07E340C2D7D242D437A47015D1269F0BE25207803024D1C22D20A7E040C2D7A07015D7A07016D752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701AD2E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2402002E2701AD1B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303A0A09B1001054FE19B10010D21222807F7A512F1273359E44282D9D247E6402002E6701AD9E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344027A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7024E78752F9912733509B1000454FA19B10004303A0A09B1001054FE19B10010D21222DAB830E0D8BD326807CAB8124E78DAB8024F9F09B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25A8002C25AA5FD5E50806804D2528002C2521242EB026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22024ECC752F9512733522752F9612733522100B0122202B03D20B22752FA31273357E1483008006202B03D20B2209B10014CAB85EB01EDAB868031252CC30330620E64FD20B2230E602D2637E37017F7E27019F9D3240317D022E05387A05387A37017F7E37015F7D432D42BE44142C38687A47015F752F941273357A512F1273351269F01063C422C2632D2368786D33801A7E27017FBE240000686ABE27019F28047E27019F7E37017F9D327D022E05387A05387A37017F7E37015F7D432D42BE44142C38137A47015F752F941273357A512F1273350269F0752F941273357A512F1273359E44142D9D241269F07E34102D7D242D437A47015F1269F0BE2520780302504922D20B7E04102D7A07015F7A07016F752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701AF2E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2403002E2701AF1B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303B0A09B1001054FE19B10010D21322807F7A512F1273359E44282D9D247E6403002E6701AF9E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344037A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70251A5752F9912733509B1000454FA19B10004303B0A09B1001054FE19B10010D21322DAB830E0D8BD326807CAB81251A5DAB80252CC09B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25B8002C25BA5FD5E50806804D2538002C253124302026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB220251F9752F9512733522752F9612733522100C0122202C03D20C22752FA41273357E1484008006202C03D20C2209B10014CAB85EB01EDAB868031255F930340620E64FD20C2230E602D2647E3701817E2701A19D3240317D022E053A7A053A7A3701817E3701617D432D42BE44182C38687A470161752F941273357A512F1273351269F01064C422C2642D2368786D33801A7E270181BE240000686ABE2701A128047E2701A17E3701819D327D022E053A7A053A7A3701817E3701617D432D42BE44182C38137A470161752F941273357A512F1273350269F0752F941273357A512F1273359E44182D9D241269F07E34142D7D242D437A4701611269F0BE2520780302537622D20C7E04142D7A0701617A070171752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B12E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2404002E2701B11B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303C0A09B1001054FE19B10010D21422807F7A512F1273359E44282D9D247E6404002E6701B19E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344047A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70254D2752F9912733509B1000454FA19B10004303C0A09B1001054FE19B10010D21422DAB830E0D8BD326807CAB81254D2DAB80255F909B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25C8002C25CA5FD5E50806804D2548002C254124319026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025526752F9512733522752F9612733522100D0122202D03D20D22752FA51273357E1485008006202D03D20D2209B10014CAB85EB01EDAB8680312592630350620E64FD20D2230E602D2657E3701837E2701A39D3240317D022E053C7A053C7A3701837E3701637D432D42BE441C2C38687A470163752F941273357A512F1273351269F01065C422C2652D2368786D33801A7E270183BE240000686ABE2701A328047E2701A37E3701839D327D022E053C7A053C7A3701837E3701637D432D42BE441C2C38137A470163752F941273357A512F1273350269F0752F941273357A512F1273359E441C2D9D241269F07E34182D7D242D437A4701631269F0BE252078030256A322D20D7E04182D7A0701637A070173752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B32E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2405002E2701B31B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303D0A09B1001054FE19B10010D21522807F7A512F1273359E44282D9D247E6405002E6701B39E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344057A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E70257FF752F9912733509B1000454FA19B10004303D0A09B1001054FE19B10010D21522DAB830E0D8BD326807CAB81257FFDAB802592609B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25D8002C25DA5FD5E50806804D2558002C255124330026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025853752F9512733522752F9612733522100E0122202E03D20E22752FA61273357E1486008006202E03D20E2209B10014CAB85EB01EDAB86803125C5330360620E64FD20E2230E602D2667E3701857E2701A59D3240317D022E053E7A053E7A3701857E3701657D432D42BE44202C38687A470165752F941273357A512F1273351269F01066C422C2662D2368786D33801A7E270185BE240000686ABE2701A528047E2701A57E3701859D327D022E053E7A053E7A3701857E3701657D432D42BE44202C38137A470165752F941273357A512F1273350269F0752F941273357A512F1273359E44202D9D241269F07E341C2D7D242D437A4701651269F0BE252078030259D022D20E7E041C2D7A0701657A070175752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B52E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2406002E2701B51B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303E0A09B1001054FE19B10010D21622807F7A512F1273359E44282D9D247E6406002E6701B59E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344067A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025B2C752F9912733509B1000454FA19B10004303E0A09B1001054FE19B10010D21622DAB830E0D8BD326807CAB8125B2CDAB8025C5309B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25E8002C25EA5FD5E50806804D2568002C256124347026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025B80752F9512733522752F9612733522100F0122202F03D20F22752FA71273357E1487008006202F03D20F2209B10014CAB85EB01EDAB86803125F8030370620E64FD20F2230E602D2677E3701877E2701A79D3240317D022E05407A05407A3701877E3701677D432D42BE44242C38687A470167752F941273357A512F1273351269F01067C422C2672D2368786D33801A7E270187BE240000686ABE2701A728047E2701A77E3701879D327D022E05407A05407A3701877E3701677D432D42BE44242C38137A470167752F941273357A512F1273350269F0752F941273357A512F1273359E44242D9D241269F07E34202D7D242D437A4701671269F0BE25207803025CFD22D20F7E04202D7A0701677A070177752F94127335752F0012733522752F92127335D20409B10014CAB85482DAB878687E3701CB7E2701B72E2400022D32BE34040038347D022E05307A05307A3701CB7E3701C97D432D42BE44282C383C7A4701C97E2407002E2701B71B38200B357A512F127335026A63752F9912733509B1000454FA19B10004303F0A09B1001054FE19B10010D21722807F7A512F1273359E44282D9D247E6407002E6701B79E24000240171B38600B35126A637E34242D7D242D437A4701C9026A637A39C07E34242D7A39D00B341B4480E59D327CB6540F23232344077A69B07A79700B35752F931273357A712F127335BD04682B7A0701C97E4701CB2D437A4701CB2E35307A353022D20409B1001420E013227E04242D80287E04242D802A7E04242D80CF7E0701CB7E2403FE9D2028407E0701C97E44282D7D600B04BD0468D27D700B04BD0468D07D549D50BD2540027D257D3209B10014CAB8541FB40131DAB87E19B07A09B00B041B2478E7025E59752F9912733509B1000454FA19B10004303F0A09B1001054FE19B10010D21722DAB830E0D8BD326807CAB8125E59DAB8025F8009B100187EA088752F90127335F52F127335A5FD5E500A681DA5FD5E50206804D25F8002C25FA5FD5E50806804D2578002C25712435E026113752F9112733509B100147AB12F12733520E008D2047EA080026113D20430E1067EA080126113CAB85EB01CDAB868127EA0C00961000012613609B1001420E0DB22025EAD752F9512733522752F96127335227C027E1480004C2009B10018A5FD5E50206804D2588002C258A5FD5E50806804D2508002C2500260FF7C027E1480004C2009B10018A5FD5E50206804D2598002C259A5FD5E50806804D2518002C2510260FF7C027E1480004C2009B10018A5FD5E50206804D25A8002C25AA5FD5E50806804D2528002C2520260FF7C027E1480004C2009B10018A5FD5E50206804D25B8002C25BA5FD5E50806804D2538002C2530260FF7C027E1480004C2009B10018A5FD5E50206804D25C8002C25CA5FD5E50806804D2548002C2540260FF7C027E1480004C2009B10018A5FD5E50206804D25D8002C25DA5FD5E50806804D2558002C2550260FF7C027E1480004C2009B10018A5FD5E50206804D25E8002C25EA5FD5E50806804D2568002C2560260FF7C027E1480004C2009B10018A5FD5E50206804D25F8002C25FA5FD5E50806804D2578002C2570260FF54F0C4A5FFC4A54F752F90127335F52F12733522CA195E20074CA27E742C2DCA797A79A00B747A79B00B74DA797E30027E64000202615ECA195E20074CA27E742C2DCA797A79A00B747A79B00B747A79600B74DA797E30037E64000302615ED2047E2701CB2D26BE240400382E7E0701C97E44282D7E79A07A09A00B040B74BD046823A5DBEF7A2701CB7E25302D267A25307A0701C9DA19C2D722752F9A127335DA19D2D7227E04242D80D748F14665475F492A452A452A4856452A496E452A452A452A452A452A452A452A4975452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A4C1E49924A8C4C57452A452A4B83452A4C9B452A452A452A452A452A452A452A4CA2452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A4F4B4CBF4DB94F84452A452A4EB0452A4FC8452A452A452A452A452A452A452A4FCF452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A52784FEC50E652B1452A452A51DD452A52F5452A452A452A452A452A452A452A52FC452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A55A55319541355DE452A452A550A452A5622452A452A452A452A452A452A452A5629452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A58D256465740590B452A452A5837452A594F452A452A452A452A452A452A452A5956452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A5BFF59735A6D5C38452A452A5B64452A5C7C452A452A452A452A452A452A452A5C83452A452A452A452A452A452A452A452A452A452A452A452A452A452A452A5F2C5CA05D9A5F65452A452A5E91452A5FA9452A452A452A452A452A452A452A5FB0452A452A452A452A452A452A452A452A452A452A452A452A452A452A452ACAB8752F021273357EB3910320E52030E005126B05803030E105126486802830E2051263F5802030E31D12656180187EB3910430E10302675F30E605126C6A800620E203020080DAB832752F10127335CA0BCA39CA5974407AB391007EB3911A6CAABEB040280A126424DA59DA39DA0B2274207AB3911480F17E3701C52D35BE340400382F7A3701C57E3701C37D432D45BE442C2C38257A4701C3752F111273357AB12F12733512679F74207AB3911412663022752F1612733580F4752F121273357AB12F1273359E442C2D9D5412679F7E34282D7D542D4380BC752F18127335CA09CA39CA2B74207AB391007E63911A74107AB391147EB0809CB660386CAA7E3701CB9D3540377A3701CB7E3701C77D432D45BE44282C383B7A4701C77D451268D47EB3911E20E513752F191273357A912F127335DA2BDA39DA092280342D536D33600280C17E04242D7A0701C97A0701C780E1CA599E44282D9D541268D47E34242D7D542D437A4701C71268D4DA4980B07E0F2C3E0B0C7A0F2C3E74207AB3911E74607AB3911C74027AB3911280A57E2F2C5E0B2C7A2F2C5E74207AB3911E74607AB3911C74027AB39112801FDA2BDA1BDA0B22752F28127335CA0BCA1BCA2B74607AB3910074107AB391147EB3911A70DB7E0D307E1D347E2D387E3D3C7E85407D904D914D924D934D944D954D964D974D9868B87A1391177A0391177A3391177A2391177A5391177A4391177A7391177A6391177A9391177A8391173073227AB391177AA391177AD391177AC391177AF391177AE391177D787AF391177AE391177EB3911E30E50302653C752F29127335207308752F0A1273358006752F1212733574807AB3911E6D007D107A0D307A0D347A0D387A0D3C7A0540DA2BDA1BDA0B227E3701C54D33683B7E0701C17E542C2D9D50BD3540027D35CA397E654B9964DA397E0701C59D037A0701C52E3701C17A3701C1BE342C2C28C77E34282D7A3701C180BD22752F531273357E154D8011752F511273350B08100B059E340002284D7CB220E7275407230A2B4922391E7CB254780303037C2B9D13401A68127A154D7A254F7E6467097A654B89240267177E64667F80F22D139D31CA397D312D10CA19CA299924DA29DA09DA3980A27A154D7E6466F54D3378097CB220E72A7E6466747A654B22752F521273357E214D7E09300B041B34788980D4752F541273357E154D7E254F80905E200754787E44677D30E6164D3368261B347E09400B047E4434FA20E3047E446785CA09CA399944DA39DA097E64667F4D3368A689647A154DF54F7E64675880997E154DE54F80C4C0D0C0D1C0E0CA19752FFE1273357E140053024052DA19D0E0D0D1D0D03203A5CB19B1800022227E2400007FE17EA002A47E0468B19D057EB0287AB395008904CA29B480E27E2400007FE17E00287A039500E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA29227E2400007FE17EA002A47E0469E69D057EB0387AB395008904CA29B480E27E2400007FE17E00387A039500E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA2922CA29CA19CA587E2400007FE1DA587E5402209CB5A47E50305E20072C527A5395002E546A178954E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA19DA2922CA19CA587E2400007FE1DA587E5402389CB5A47E50205E20072C527A5395002E546A888954E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A3E0A37E00007A039500DA1922026BA8CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB74007AB391007EB32C7FB40002801CB401197EB3911454146805126B6C80237EB3911430E51C126CAA80177EB3911430E505126CAA800B7EB3911454146803126B6CDAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B2220E419752F0A1273357EB32C7E700A7EB32C7FB4011F026C040271F2752F0B12733574147AB391147EB32C7FB4020C126BB4026BA874047AB39114227E00007A032C7F7A032C80227EB32C7654606005B4401E801C7EB32C77B40515752F711273357EB32C797EA0017AA391067AB391072274007AB3910074107AB3911222BE572C7C28047E572C7C7A0F2C827A572C8674107AB391122274007AB391007EB3911A70537EB3911420E44C7EEF2C827EF72C867E072C864D0068217E0000E07AB39117A3A5081BF46806A5B810F080197EB0007AB32C7FBE0010680D7EB0007AB32C7F74807AB3911E7AEF2C827AF72C86752F0612733574047AB3911422CA0BCA1BCA2BCA3BCA4BCA5BCA6BCA7BCAEB752F0312733574007AB32C7E74007AB3910074017AB39112126D19DAEBDA7BDA6BDA5BDA4BDA3BDA2BDA1BDA0B22752F031273357EB32C80B4021174007AB32C807AB32C7F74207AB3911422B401467EB3910420E6427E23911A7C327E132C812C217A232C817E00002E042C887EB391167A09B00B04A5DBF474207AB39114752F701273357EB32C817EA32C7DBCAB7803126DB9220271F2DA59026C7C74E07AB391007E0391107E1391117E3391127E2391137E5391147E4391157E7391167E6391177A0F2C767A1F2C7A752F041273357A012F1273357A112F1273357A212F1273357A312F1273357A412F1273357A512F1273357A612F1273357A712F12733574007AB3910074407AB39104126D8D226D007E1401027A072C867A032C817EB32C7620E70F7A232C807A332C7FBE072C7C6809227A332C807A232C7F7EB32C7654E3232330E002D2E530E702D2E430E50630E4030271F2543EF5F003541FC325F0906DE57584FF73026FA0026E2D027039027054026F37026EC202708502708502708802708802708802708802708802708802708802708802708E02716002708B02708B02708B02708B02708B02708B74007AB3910074607AB3911C7EB32C77B4062A7EB32C7860797C0B7E132C797E172C7A752F721273357A012F1273357A112F1273351272374058026BEBB4081C752F741273357EB33FF17E082C887A0C00007A0BB07E540001026BEBB40033752F751273357E082C887A0C0000CA0B7EB33FF230E00774027A0BB0800574007A0BB00B1474007A0BB07E540002DA0B026BEB0271F274007AB3910074607AB3911C7EB32C77B4005F752F761273357EB32C7B540FB402057EB0608017B400057EB000800F7EB32C7B20E7057EB04080037EB0207AB391007EB3911130E0047401800274007E082C887A0C0000CA0B7A0BB00B1474007A0BB074007AB391007E540002DA0B026BEB0271F27EB32C7B540FB402057EB0608017B400057EB000800F7EB32C7B20E7057EB04080037EB0207AB391007EB32C79B400267EB32C77B4010E752F7712733574017AB39112801BB4030E752F7812733574017AB39111800A74007AB391001271F22274007AB39100026BDE7EB32C77B4091F752F791273357EB32C79BEB33FF1680DCAB8124379DAB850767AB33FF1806DB40508752F7A1273358062B40319752F7B1273357EB32C79B401557EB33FF244017AB33FF28046B40119752F7C1273357EB32C79B401397EB33FF254FE7AB33FF2802AB4072A7EB32C7860247C0B7E132C797E172C7A752F731273357A012F1273357A112F1273351272714003026BDE0271F27EB32C77B40BF6752F7D1273357EB32C797EA32C7B4CAB78E480DF74007AB3910074607AB3911C7EB32C77B40ACF752F7E1273357EB32C7970C37E082C887A0C00007A0BB07E540001026BEB0271F20271F20271F27EB32C77B40420752FC31273357E0400017E172C787E182C887A1C00007E472C7C12734102715AB40642752FC11273357E5800007A5C00FE7DCA7ED72C787E782C887A7C00007E772C7C752FC1127335C0A8C2AF7E40017A43940012737A7E432C357A439400D0A840658060B40024C2AF7EB0017AB394007AB32C35126BDEE48DEF8DEF8DEFD5E0F7C0D1CA02FFCA06000032B4092074037AB391067E2391077E572C784D5568054E200280035E20FD7A2391078016B40716C2AF7E072C7A7E172C78C0D1CA18CA38CA2832026BDE0271F274007AB3910074607AB3911C7EB32C77B40315752FC21273357E0400017E172C787E572C7C026BEBB40541752FC0127335C0A8C2AF7E40017A4394007E082C887A0C00007E2400FE7E372C787E472C7C1273417E432C357A439400D0A87E082C887A0C00007E572C7C026BEBB401207E00007E1001752F721273357A012F1273357A112F1273351272374003026BEB0271F2752F071273357EB0027AB3900074007AB3910074407AB3911574017AB391117EB391155460BEB040680874207AB3911580ED74017AB3911274047AB3911474FF7AB32C7E22C0A8C2AF7E40017A4394001272BE401F7E082C887A0C0000CA0BCA49127341DA59DA0B7E432C357A439400D0A8C3227E432C357A439400D0A822C0A8C2AF7E40017A4394001272BE40317E5800007A5C00FE7F617E782C887A7C00007E772C7CBD747817752FC112733512737A400C7E432C357A439400D0A8C3227E432C357A439400D0A8D3227E2400FE7E347FCA0B1A50C5F07D627D757D877E347FC27E1BB07E347F03B401047E347FCC7E1BB0BC0B50493E003E000A502D750B3A3069530002BD3850022D38BC1B50303E103E100A512D35694100020B1A30BD3850022D38BE44FFFF78057E1B900A494D44680CBE4400FF28047E4400FFC322D32274 +:00047FC60002000300B2 +:0148733500CA087E012F7A033FF0DA08227E1BC07A0BC00B140B341B4478F2227F6F7FF01BFC7C547D328008CA1BCA1BCA1BCA1B9E44001050F22E4400106806CA481B4478FA7FF689E4CA6B5ED4003F68207E8400409D8DDA6BBD873816CA797D781273A4DA7940089D7868028005C2D722DA6B7EC0037ED0007AD3900074AA39B55555745539B52AAA74A039B555557E0400409D7050062D707D076D777C317E7B007A6B000B7C0B6CA5D9F37F161B1C7E5427107E1B10BC1068061B5478F5802F6D007C207F169F107F279F207E2B007E1B10BC0178190B2C0B1CA5DBEF7CB620E0066CDC7AD390004D777890C2D722D2D7220004000400000604020400020104010200000000000000000202020202040008100210040208000101087E187FBD7A1C00FE0B1A005E101FBE1014381A0A51237E1874247A1C00FF2D350B1A506008A5B802034EA0082280FECB +:0000000001FF +//************************************************************** +//* Edgeport/4 Binary Image +//* Generated by HEX2C v1.06 +//* Copyright (C) 1998 Inside Out Networks, 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. +//************************************************************** -- cgit v0.10.2 From d12b219a228efe92f0778ed3af21305e65fbb052 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Fri, 4 Jul 2008 23:06:09 +0530 Subject: edgeport-ti: use request_firmware() Firmware blob looks like this... uint8_t MajorVersion uint8_t MinorVersion __le16 BuildNumber uint8_t data[] Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse diff --git a/drivers/usb/serial/io_fw_down3.h b/drivers/usb/serial/io_fw_down3.h deleted file mode 100644 index 4496b06..0000000 --- a/drivers/usb/serial/io_fw_down3.h +++ /dev/null @@ -1,847 +0,0 @@ -//************************************************************** -//* Edgeport Binary Image (for TI based products) -//* Generated by TIBin2C v2.00 (watchport) -//* Copyright (C) 2001 Inside Out Networks, All rights reserved. -//************************************************************** - - -static int IMAGE_SIZE = 12938; - -struct EDGE_FIRMWARE_VERSION_INFO -{ - unsigned char MajorVersion; - unsigned char MinorVersion; - unsigned short BuildNumber; -}; - -static struct EDGE_FIRMWARE_VERSION_INFO IMAGE_VERSION_NAME = -{ - 4, 80, 0 // Major, Minor, Build - -}; - -static unsigned char IMAGE_ARRAY_NAME[] = -{ -// struct ImageHdr -// { -// WORD Length; -// BYTE CheckSum; -// }; -0x87, 0x32, -0x9a, - -0x02, 0x27, 0xbf, 0x02, 0x21, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x1a, 0x85, 0x3f, -0x8c, 0x85, 0x40, 0x8a, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, -0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x3e, -0x24, 0x08, 0xf8, 0xe6, 0x60, 0x2b, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0xa6, 0x81, 0xe5, 0x3e, 0x75, -0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0x78, 0x8c, 0xe5, 0x81, -0x04, 0xc3, 0x98, 0xf9, 0x94, 0x22, 0x40, 0x03, 0x02, 0x11, 0xdc, 0xe6, 0xf0, 0x08, 0xa3, 0xd9, -0xfa, 0x74, 0x08, 0x25, 0x3e, 0xf8, 0x05, 0x3e, 0x08, 0xe6, 0x54, 0x80, 0x70, 0x0c, 0xe5, 0x3e, -0xb4, 0x07, 0xf3, 0x78, 0x08, 0x75, 0x3e, 0x00, 0x80, 0xef, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0x86, -0x81, 0xe5, 0x3e, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, -0x78, 0x8c, 0xe5, 0x81, 0x04, 0xc3, 0x98, 0xf9, 0xe0, 0xf6, 0x08, 0xa3, 0xd9, 0xfa, 0xd0, 0x07, -0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0x83, -0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 0x30, 0x01, 0x4d, 0x30, 0xb4, 0x48, 0x10, -0x00, 0x45, 0x90, 0xff, 0x08, 0xe0, 0x54, 0x20, 0xf8, 0x90, 0xff, 0x48, 0xe0, 0x54, 0x20, 0xf9, -0x90, 0xff, 0x10, 0xe0, 0x54, 0x20, 0xfa, 0x90, 0xff, 0x50, 0xe0, 0x54, 0x20, 0xfb, 0x74, 0x00, -0xf5, 0x82, 0x74, 0xf8, 0xf5, 0x83, 0xe0, 0xc8, 0xf0, 0x68, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, -0xc9, 0xf0, 0x69, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, 0xca, 0xf0, 0x6a, 0x60, 0x02, 0x7e, 0x04, -0xa3, 0xe0, 0xcb, 0xf0, 0x6b, 0x60, 0x02, 0x7e, 0x04, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, -0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, -0xc0, 0x06, 0xc0, 0x07, 0x74, 0x15, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x60, 0x23, 0x74, -0x66, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x16, 0x74, 0xff, 0xf0, 0x74, -0x1c, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x60, 0x04, 0x14, 0xf0, 0x70, 0x04, 0xc2, 0x90, -0x80, 0xfc, 0x90, 0xff, 0x93, 0x74, 0x81, 0xf0, 0xe5, 0x81, 0x94, 0xfd, 0x40, 0x03, 0x02, 0x11, -0xdc, 0x85, 0x41, 0x8d, 0x85, 0x42, 0x8b, 0x74, 0xb2, 0xf5, 0x82, 0x74, 0xfa, 0xf5, 0x83, 0xe0, -0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x4a, 0xe0, 0x30, 0xe7, 0x2c, 0x90, 0xff, -0x4e, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, 0xb4, 0x02, -0x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x28, 0x4e, 0x80, -0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, 0xa3, 0xe0, -0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x52, 0xe0, 0x30, 0xe7, 0x2c, 0x90, 0xff, -0x56, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x25, 0xb4, 0x02, -0x22, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x28, 0x4e, 0x80, -0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x80, 0x03, -0x02, 0x02, 0x90, 0x74, 0x16, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x20, 0x04, 0xf1, 0x20, -0x02, 0x03, 0x30, 0x01, 0xeb, 0x74, 0x19, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, 0xfc, -0xf0, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0x64, 0x04, 0x70, 0x0f, 0xec, 0x70, 0x62, 0x7e, 0x01, -0x12, 0x00, 0xc9, 0x7c, 0x0a, 0x7d, 0xfa, 0x02, 0x02, 0x61, 0x12, 0x00, 0xc9, 0xee, 0x64, 0x04, -0x60, 0x1d, 0xec, 0x70, 0x4b, 0x7c, 0x0a, 0xed, 0x14, 0xfd, 0x70, 0x15, 0xee, 0x64, 0x02, 0x60, -0x07, 0x7e, 0x02, 0x7d, 0x32, 0x02, 0x02, 0x61, 0x7e, 0x01, 0x7d, 0xfa, 0x02, 0x02, 0x61, 0x7c, -0x0a, 0x74, 0x19, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, -0xf0, 0x14, 0x60, 0x18, 0x20, 0xe1, 0x0f, 0x20, 0x01, 0x06, 0xd2, 0xb1, 0xc2, 0xb0, 0x80, 0x10, -0xc2, 0xb1, 0xd2, 0xb0, 0x80, 0x0a, 0xc2, 0xb1, 0xc2, 0xb0, 0x80, 0x04, 0xd2, 0xb0, 0xd2, 0xb1, -0x78, 0x19, 0x79, 0x09, 0x7a, 0x07, 0xe7, 0x70, 0x04, 0xa6, 0x00, 0x80, 0x0b, 0xe6, 0x60, 0x08, -0x16, 0xe6, 0x70, 0x04, 0xe7, 0x44, 0x80, 0xf7, 0x08, 0x09, 0xda, 0xea, 0xe5, 0x3d, 0x60, 0x13, -0x14, 0xf5, 0x3d, 0x70, 0x0e, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0x57, 0xd2, -0x8c, 0xd2, 0x8d, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, -0x01, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 0x90, 0xff, -0x04, 0xe0, 0x90, 0xfa, 0xb9, 0xf0, 0x90, 0xff, 0x06, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff, -0xea, 0xfe, 0xef, 0xc3, 0x94, 0x08, 0xee, 0x94, 0x01, 0x50, 0x02, 0x80, 0x04, 0x7e, 0x01, 0x7f, -0x08, 0x8e, 0x3b, 0x8f, 0x3c, 0x90, 0xff, 0x02, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff, 0xea, -0x90, 0xfa, 0xbd, 0xf0, 0xef, 0xa3, 0xf0, 0x12, 0x1c, 0xe0, 0xe4, 0xf5, 0x4d, 0xe5, 0x4d, 0xc3, -0x94, 0x02, 0x50, 0x0f, 0x12, 0x1c, 0xc1, 0xe4, 0x12, 0x1a, 0xe8, 0x05, 0x4d, 0x04, 0x12, 0x1c, -0xb2, 0x80, 0xea, 0x12, 0x1c, 0xe0, 0x90, 0xff, 0x00, 0xe0, 0xff, 0x54, 0x60, 0x24, 0xc0, 0x70, -0x03, 0x02, 0x08, 0xf3, 0x24, 0x40, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xfe, -0x54, 0x0f, 0xf5, 0x4d, 0xee, 0x30, 0xe7, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0a, 0x90, 0xff, -0x01, 0xe0, 0x12, 0x1b, 0xfc, 0x03, 0x84, 0x00, 0x04, 0x57, 0x01, 0x05, 0x6a, 0x03, 0x06, 0x31, -0x05, 0x06, 0x73, 0x06, 0x07, 0xd5, 0x08, 0x08, 0x1d, 0x09, 0x08, 0x79, 0x0a, 0x08, 0xb9, 0x0b, -0x00, 0x00, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, -0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x64, 0x02, 0x45, 0x3b, 0x60, -0x03, 0x02, 0x0f, 0x6e, 0xef, 0x54, 0x1f, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x47, 0x24, 0x02, 0x60, -0x03, 0x02, 0x0f, 0x6e, 0xee, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1c, 0xc1, 0x74, 0x01, 0x12, -0x1a, 0xe8, 0x78, 0x67, 0xe6, 0x30, 0xe0, 0x08, 0x12, 0x1c, 0xc1, 0x74, 0x02, 0x12, 0x1a, 0xe8, -0x7f, 0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x09, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, -0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x7f, -0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x0e, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x60, 0x07, -0x64, 0x80, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0xfa, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe5, -0x4d, 0x70, 0x19, 0x30, 0x0a, 0x0b, 0x90, 0xff, 0x80, 0x12, 0x1c, 0xbe, 0x12, 0x1a, 0xe8, 0x80, -0x24, 0x90, 0xff, 0x82, 0x12, 0x1c, 0xbe, 0x12, 0x1a, 0xe8, 0x80, 0x19, 0x15, 0x4d, 0x30, 0x0a, -0x0b, 0x12, 0x1d, 0x55, 0x12, 0x1c, 0xbc, 0x12, 0x1a, 0xe8, 0x80, 0x09, 0x12, 0x1d, 0x63, 0x12, -0x1c, 0xbc, 0x12, 0x1a, 0xe8, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xa2, 0x60, 0x05, 0x74, 0x01, 0x12, -0x1a, 0xe8, 0x7f, 0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, -0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x14, 0x60, 0x2d, 0x14, 0x60, -0x59, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x04, 0xa3, 0xe0, -0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, -0x78, 0x67, 0xe6, 0x54, 0xfe, 0xf6, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x06, -0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x09, 0x90, 0xfa, 0xb9, 0xe0, 0x60, -0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x0c, 0x90, 0xfa, 0xb9, 0xe0, 0xd3, 0x94, 0x01, -0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, -0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0xfa, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe5, -0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x07, 0xe5, -0x4d, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x4d, 0x70, 0x0f, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7, -0xf0, 0x90, 0xff, 0x80, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0xe5, 0x4d, 0x24, 0xfe, 0x60, 0x20, 0x24, -0xfb, 0x60, 0x34, 0x24, 0x06, 0x70, 0x35, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, -0x03, 0x12, 0x2e, 0x79, 0x80, 0x26, 0xe4, 0xfd, 0x7f, 0x03, 0x12, 0x2e, 0x79, 0x80, 0x1d, 0x30, -0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, 0x04, 0x12, 0x2e, 0x79, 0x80, 0x0e, 0xe4, 0xfd, -0x7f, 0x04, 0x12, 0x2e, 0x79, 0x80, 0x05, 0x7f, 0x87, 0x12, 0x31, 0xef, 0x15, 0x4d, 0x30, 0x0a, -0x0b, 0x12, 0x1d, 0x55, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x80, 0x09, 0x12, 0x1d, 0x63, 0xf5, -0x83, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, -0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x14, 0x60, -0x2d, 0x14, 0x60, 0x55, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, -0x04, 0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, -0x02, 0x0f, 0x6e, 0x78, 0x67, 0xe6, 0x44, 0x01, 0xf6, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, -0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x07, 0xe5, 0x4d, -0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x0a, 0xe5, 0x4d, 0xd3, 0x94, 0x01, 0x40, -0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, -0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x12, 0x32, 0x3f, 0x40, 0x03, -0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x4d, -0x70, 0x09, 0x30, 0x0a, 0x03, 0x02, 0x1e, 0x14, 0x02, 0x1d, 0xdf, 0xe5, 0x35, 0x20, 0xe1, 0x03, -0x02, 0x0f, 0x6e, 0x15, 0x4d, 0x30, 0x0a, 0x0b, 0x12, 0x1d, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x08, -0xf0, 0x80, 0x09, 0x12, 0x1d, 0x63, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0xe4, 0xff, 0x02, 0x32, -0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, -0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, -0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbe, 0xe0, 0x90, -0xff, 0xff, 0xf0, 0xe0, 0x60, 0x05, 0x43, 0x35, 0x01, 0x80, 0x03, 0x53, 0x35, 0xfe, 0xe4, 0xff, -0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x70, -0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, -0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0x24, 0xfe, 0x60, 0x3a, 0x14, 0x60, 0x75, 0x24, 0x02, 0x60, 0x03, -0x02, 0x0f, 0x6e, 0xed, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1c, 0xe0, 0x12, 0x1e, 0x0d, 0x7d, -0x03, 0x12, 0x0f, 0xb5, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0x72, 0x90, 0xfa, 0xb6, 0xe0, -0xfd, 0xa3, 0x12, 0x1d, 0x2b, 0x12, 0x0f, 0xd1, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, -0x02, 0x10, 0x02, 0x12, 0x1c, 0xe0, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe4, 0x0d, 0x12, 0x1e, 0x0d, -0x7d, 0x14, 0x12, 0x0f, 0xb5, 0x60, 0x10, 0x02, 0x0f, 0x6e, 0x12, 0x1e, 0x0d, 0x7d, 0x04, 0x12, -0x10, 0x09, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0x72, 0x90, 0xfa, 0xb6, 0xe0, 0xfd, 0xa3, -0x12, 0x1d, 0x2b, 0x12, 0x0f, 0xd1, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x02, 0x10, -0x02, 0x12, 0x1e, 0x0d, 0x7d, 0x05, 0x12, 0x10, 0x09, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x7b, 0x01, -0x7a, 0xfa, 0x79, 0xb6, 0x12, 0x1d, 0x28, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb7, 0xe4, -0x75, 0xf0, 0x03, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xbe, 0xe0, 0x90, 0xfa, 0xb5, 0xf0, 0xe4, 0xf5, -0x4c, 0x90, 0xfa, 0xb5, 0xe0, 0xff, 0xe5, 0x4c, 0xc3, 0x9f, 0x50, 0x24, 0x12, 0x1d, 0x22, 0x12, -0x10, 0x14, 0xff, 0xfd, 0x90, 0xfa, 0xb7, 0xe4, 0x8d, 0xf0, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xb6, -0xe0, 0xc3, 0x9f, 0xf0, 0xd3, 0x94, 0x00, 0x50, 0x03, 0x02, 0x0f, 0x6e, 0x05, 0x4c, 0x80, 0xd1, -0x12, 0x1d, 0x22, 0x12, 0x10, 0x14, 0x24, 0xfe, 0xff, 0x90, 0xfa, 0xb6, 0xf0, 0xfd, 0xa3, 0xe4, -0x75, 0xf0, 0x02, 0x12, 0x1b, 0x1c, 0x7a, 0xf9, 0x79, 0x72, 0x7b, 0x01, 0x8b, 0x36, 0x8a, 0x37, -0x89, 0x38, 0xe9, 0x24, 0x02, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, 0x1d, 0x28, 0x12, 0x26, 0x98, 0x8f, -0x4c, 0x05, 0x4c, 0x05, 0x4c, 0x12, 0x1c, 0xc1, 0xe5, 0x4c, 0x12, 0x1a, 0xe8, 0x12, 0x1c, 0xc1, -0x90, 0x00, 0x01, 0x74, 0x03, 0x12, 0x1a, 0xfa, 0xaf, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x3c, -0xee, 0x95, 0x3b, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x8e, 0x39, 0x8f, 0x3a, 0x02, -0x2c, 0xd8, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x64, -0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, -0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, -0x79, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f, -0x6e, 0x75, 0x36, 0x00, 0x75, 0x37, 0x00, 0x75, 0x38, 0x32, 0x02, 0x0f, 0xf1, 0xe5, 0x35, 0x30, -0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, -0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xd3, 0x90, 0xfa, 0xbe, 0xe0, 0x94, 0x01, 0x90, 0xfa, -0xbd, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, 0x02, 0x0f, -0x6e, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbe, 0xe0, -0xf5, 0x32, 0xe5, 0x32, 0x70, 0x08, 0x43, 0x35, 0x01, 0x53, 0x35, 0xfd, 0x80, 0x06, 0x53, 0x35, -0xfe, 0x43, 0x35, 0x02, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, -0x6e, 0xe5, 0x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, -0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, -0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, -0x03, 0x02, 0x0f, 0x6e, 0x7f, 0x01, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, -0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xd3, 0x90, 0xfa, 0xbe, 0xe0, 0x94, -0x00, 0x90, 0xfa, 0xbd, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x64, -0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, -0x02, 0x32, 0x6e, 0x90, 0xff, 0x01, 0x12, 0x1e, 0x24, 0xef, 0x12, 0x1a, 0xe8, 0x90, 0xfa, 0xb9, -0x12, 0x1e, 0x24, 0x90, 0x00, 0x01, 0xef, 0x12, 0x1a, 0xfa, 0x90, 0x00, 0x02, 0xe4, 0x12, 0x1a, -0xfa, 0x74, 0x03, 0x12, 0x1c, 0xb2, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0xa3, 0xe0, 0x85, 0x38, 0x82, -0x85, 0x37, 0x83, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 0xfc, 0x09, -0x7b, 0x02, 0x09, 0x9d, 0x04, 0x09, 0xbf, 0x05, 0x09, 0xeb, 0x06, 0x0a, 0x09, 0x07, 0x0a, 0x27, -0x08, 0x0a, 0x45, 0x09, 0x0a, 0x63, 0x0b, 0x0b, 0x18, 0x80, 0x0d, 0xb7, 0x81, 0x0d, 0xe8, 0x82, -0x0b, 0x5f, 0x83, 0x0b, 0xa8, 0x84, 0x0b, 0xc7, 0x85, 0x0c, 0x0c, 0x86, 0x0c, 0x57, 0x87, 0x0c, -0xe8, 0x88, 0x0d, 0x73, 0x89, 0x0a, 0x81, 0x92, 0x0a, 0x81, 0x93, 0x0d, 0xa0, 0xb0, 0x0e, 0x9b, -0xc0, 0x0e, 0xc7, 0xc1, 0x0e, 0xd8, 0xc2, 0x00, 0x00, 0x0f, 0x5d, 0xe5, 0x35, 0x20, 0xe7, 0x05, -0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, -0x00, 0x7f, 0x07, 0x02, 0x11, 0x5e, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0xb4, 0xe5, 0x35, 0x20, -0xe7, 0x05, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, -0xfd, 0x7c, 0x00, 0x7f, 0x0c, 0x02, 0x11, 0x5e, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0xb4, 0xe5, -0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1e, 0x42, 0x50, 0x06, 0xe5, 0x3c, 0x45, 0x3b, -0x70, 0x05, 0x7f, 0x02, 0x02, 0x31, 0xa9, 0x90, 0xfa, 0xb9, 0xe0, 0x24, 0xfe, 0x24, 0xfd, 0x50, -0x02, 0x80, 0x03, 0x02, 0x32, 0x2c, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, -0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, -0x08, 0x02, 0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, -0x71, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x09, 0x02, -0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, -0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0a, 0x02, 0x11, 0x5e, -0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, -0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0b, 0x02, 0x11, 0x5e, 0x7f, 0x07, -0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, 0x60, 0x03, -0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0e, 0x02, 0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, -0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x56, 0x12, 0x1d, 0x79, 0x70, 0x4a, 0x90, 0xff, 0x02, 0xe0, 0xf5, -0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 0x4c, 0xb4, 0x83, 0x05, -0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 0x4c, 0x12, 0x1c, 0x22, -0x12, 0x1e, 0x3b, 0x12, 0x25, 0xfa, 0x12, 0x1d, 0x89, 0x12, 0x1a, 0xbb, 0x60, 0x05, 0x12, 0x32, -0x7a, 0x80, 0x06, 0x85, 0x33, 0x39, 0x85, 0x34, 0x3a, 0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, -0x38, 0x75, 0x02, 0x2c, 0xd8, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0xb4, 0x12, 0x1d, 0x79, 0x60, -0x05, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1e, 0x42, 0x40, 0x05, 0x7f, 0x03, 0x02, 0x31, 0xa9, -0x90, 0xff, 0x02, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, -0xe5, 0x4c, 0xb4, 0x83, 0x05, 0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, -0xf5, 0x4c, 0x12, 0x1c, 0x22, 0x02, 0x32, 0x2c, 0x12, 0x1e, 0x4c, 0x12, 0x2a, 0xc7, 0x12, 0x1d, -0x33, 0xe0, 0x54, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x90, 0xfa, 0xba, 0xf0, 0x78, 0x68, 0x12, -0x1b, 0xd8, 0x90, 0x00, 0x02, 0x12, 0x1a, 0xbb, 0x30, 0xe7, 0xf2, 0x90, 0x00, 0x02, 0xe4, 0x12, -0x1a, 0xfa, 0x90, 0xfa, 0xba, 0xe0, 0x44, 0x80, 0xff, 0xf0, 0x78, 0x7c, 0xe6, 0xfc, 0x08, 0xe6, -0x8c, 0x83, 0x12, 0x1d, 0x3b, 0xef, 0xf0, 0x12, 0x32, 0x84, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x90, -0xfa, 0xb9, 0xe0, 0x64, 0x01, 0x70, 0x1f, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, -0xa3, 0xe0, 0xf5, 0x90, 0x80, 0x2d, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0x90, 0x90, 0xfa, 0xbe, 0xe0, -0x42, 0x90, 0xd2, 0xaf, 0x80, 0x1d, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3, -0xe0, 0xf5, 0xb0, 0x80, 0x0e, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0xb0, 0x90, 0xfa, 0xbe, 0xe0, 0x42, -0xb0, 0xd2, 0xaf, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1c, 0xe0, 0x90, 0xfa, 0xb9, 0xe0, 0xb4, -0x01, 0x0a, 0x12, 0x1c, 0xc1, 0xe5, 0x90, 0x12, 0x1a, 0xe8, 0x80, 0x08, 0x12, 0x1c, 0xc1, 0xe5, -0xb0, 0x12, 0x1a, 0xe8, 0x02, 0x0f, 0xf1, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x24, 0x13, 0x12, 0x1c, -0xf1, 0x20, 0xe1, 0x33, 0x12, 0x1d, 0x80, 0xef, 0x24, 0xfc, 0x60, 0x18, 0x04, 0x70, 0x28, 0x90, -0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x19, 0x12, 0x1e, -0x56, 0xf0, 0x80, 0x13, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, -0xf0, 0x80, 0x04, 0x12, 0x1e, 0x5d, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x90, 0xfa, 0xb9, 0xe0, -0xff, 0x24, 0x13, 0x12, 0x1c, 0xf1, 0x20, 0xe1, 0x39, 0x12, 0x1d, 0x80, 0xef, 0x24, 0xfc, 0x60, -0x1b, 0x04, 0x70, 0x2e, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, -0xf0, 0x80, 0x1f, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xba, 0xe0, -0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, -0xdf, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x12, 0x1d, 0x71, 0x60, 0x4d, 0x04, -0x60, 0x03, 0x02, 0x0c, 0xe3, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x0f, 0x90, 0xff, 0xa4, 0x12, 0x1c, -0xea, 0x30, 0xe1, 0x6f, 0x12, 0x1e, 0x2c, 0x02, 0x0c, 0xe3, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfb, -0x12, 0x1c, 0xed, 0xfe, 0x30, 0xe1, 0x5c, 0x30, 0xe2, 0x11, 0x30, 0xb4, 0x05, 0x12, 0x1e, 0x2c, -0x80, 0x51, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x48, 0x30, 0x95, 0x05, 0x12, 0x1e, -0x2c, 0x80, 0x40, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x37, 0x90, 0xfa, 0xba, 0xe0, -0x60, 0x12, 0x90, 0xff, 0xb4, 0x12, 0x1c, 0xea, 0x30, 0xe1, 0x28, 0x90, 0xff, 0xb4, 0xe0, 0x44, -0x02, 0xf0, 0x80, 0x1f, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xfb, 0x12, 0x1c, 0xed, 0x30, 0xe1, 0x13, -0x30, 0x93, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, -0x54, 0xfd, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x90, 0xfa, 0xb9, 0xe0, 0x24, -0xfc, 0x60, 0x40, 0x04, 0x70, 0x78, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xa2, 0xe0, -0x44, 0x40, 0xf0, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x65, 0xd2, 0x03, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, -0x90, 0xff, 0xa3, 0xef, 0x54, 0x7f, 0xf0, 0x80, 0x55, 0x30, 0x03, 0x0e, 0x90, 0xff, 0xa3, 0xe0, -0x44, 0x80, 0xf0, 0xc2, 0x03, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x54, 0xbf, -0xf0, 0x80, 0x3b, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xb2, 0xe0, 0x44, 0x40, 0xf0, -0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x28, 0xd2, 0x04, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0xff, 0xb3, -0xef, 0x54, 0x7f, 0xf0, 0x80, 0x18, 0x30, 0x04, 0x0e, 0x90, 0xff, 0xb3, 0xe0, 0x44, 0x80, 0xf0, -0xc2, 0x04, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x54, 0xbf, 0xf0, 0xe4, 0xff, -0x02, 0x31, 0xa9, 0x12, 0x1c, 0xe0, 0x90, 0xfa, 0xb9, 0xe0, 0x24, 0xfc, 0x60, 0x0f, 0x04, 0x70, -0x16, 0x90, 0xff, 0xa6, 0xe0, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x80, 0x0a, 0x90, 0xff, 0xb6, -0xe0, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0xd8, -0x90, 0xf9, 0x15, 0x74, 0x01, 0xf0, 0x90, 0xf9, 0x1c, 0x74, 0x19, 0xf0, 0x90, 0xf9, 0x66, 0x74, -0xff, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0xe4, 0xff, 0x12, 0x31, 0xa9, 0x12, 0x1d, 0xe7, 0x7f, -0x03, 0x12, 0x12, 0x61, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe4, 0x08, 0x90, 0xff, 0x93, 0x74, 0x80, -0xf0, 0x80, 0x10, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0xff, 0x7e, 0x00, 0x12, 0x30, -0xd3, 0xc2, 0x90, 0xc2, 0xaf, 0x00, 0x80, 0xfd, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x90, 0xfa, 0xbf, -0x74, 0x3e, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0xfa, 0xb7, 0xf0, 0xa3, 0x74, 0x15, 0xf0, 0xe0, 0x54, -0x3f, 0xff, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0xfa, 0xbc, 0xf0, 0xd3, 0x94, 0x00, 0xe4, 0x94, 0x3e, -0x40, 0x08, 0x90, 0xfa, 0xc0, 0xe0, 0x90, 0xfa, 0xbc, 0xf0, 0x12, 0x0f, 0x98, 0xe5, 0x31, 0x45, -0x30, 0x70, 0x73, 0x12, 0x1c, 0xfa, 0x90, 0xfa, 0xbf, 0x12, 0x1e, 0x06, 0x60, 0x27, 0xd3, 0xef, -0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x08, 0x90, 0xfa, 0xbc, 0x74, 0x40, 0xf0, 0x80, 0x08, 0x90, -0xfa, 0xc0, 0xe0, 0x90, 0xfa, 0xbc, 0xf0, 0x12, 0x0f, 0x98, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x46, -0x12, 0x1c, 0xfa, 0x80, 0xd1, 0x75, 0x4c, 0x02, 0x90, 0xfa, 0xbf, 0xe4, 0xf0, 0xa3, 0x04, 0xf0, -0x90, 0xfa, 0xb7, 0xe4, 0xf0, 0xa3, 0x74, 0x0f, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0x90, -0xfa, 0xc0, 0xe0, 0xf5, 0x4a, 0x7d, 0x0f, 0x7c, 0x00, 0x12, 0x29, 0x60, 0x75, 0x30, 0x00, 0x8f, -0x31, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0xe4, 0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, -0x98, 0xe4, 0xf5, 0x30, 0xf5, 0x31, 0xaf, 0x31, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x30, 0xe7, -0x10, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x67, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x15, 0xc2, 0x95, 0x80, -0x11, 0x90, 0xfa, 0xba, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x65, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x02, -0xc2, 0x94, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1e, 0x4c, 0xbf, 0x01, 0x04, 0xd2, 0x93, 0x80, -0x02, 0xc2, 0x93, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x54, 0x03, 0x14, 0x60, 0x0a, -0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x91, 0x80, 0x27, 0xc2, 0x91, -0x80, 0x23, 0x12, 0x1e, 0x56, 0x12, 0x0f, 0xc0, 0x60, 0x04, 0xd2, 0x91, 0x80, 0x17, 0x90, 0xff, -0xa4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0xc0, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x91, 0x80, 0x02, 0xd2, -0x91, 0x12, 0x1e, 0x56, 0xf0, 0x90, 0xfa, 0xba, 0xe0, 0x54, 0x0c, 0xff, 0x13, 0x13, 0x54, 0x3f, -0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x92, 0x80, -0x27, 0xc2, 0x92, 0x80, 0x23, 0x12, 0x1e, 0x5d, 0x12, 0x0f, 0xe0, 0x60, 0x04, 0xd2, 0x92, 0x80, -0x17, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0xe0, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x92, -0x80, 0x02, 0xd2, 0x92, 0x12, 0x1e, 0x5d, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, -0xe7, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0xb4, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x32, -0x7a, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb6, 0x90, 0xfa, 0xb7, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, -0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb7, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1b, -0x1c, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xaa, 0x4e, 0xa9, 0x4f, 0x7b, 0xff, 0x90, 0xfa, -0xb7, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xbc, 0xe0, 0xf5, 0x4a, 0x12, 0x29, 0x60, 0x75, -0x30, 0x00, 0x8f, 0x31, 0x22, 0x12, 0x23, 0x61, 0x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22, -0xf0, 0x7f, 0x01, 0x12, 0x12, 0x61, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xbb, 0xf0, 0x54, 0xa0, -0x22, 0x12, 0x26, 0x98, 0x8f, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x3c, 0xee, 0x95, 0x3b, 0x22, -0xf0, 0x7f, 0x01, 0x12, 0x12, 0x61, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xbb, 0xf0, 0x54, 0xa0, -0x22, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0xd8, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x02, -0x32, 0x3f, 0x8e, 0x39, 0x8f, 0x3a, 0x02, 0x2c, 0xd8, 0x12, 0x23, 0x61, 0x7e, 0x00, 0x8e, 0x30, -0x8f, 0x31, 0xef, 0x22, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb4, 0xe0, 0x22, 0xef, 0x90, -0xf8, 0x04, 0xf0, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0xee, 0x60, 0x0a, 0xc0, 0x05, 0x7d, 0x7f, 0xdd, -0xfe, 0xde, 0xfa, 0xd0, 0x05, 0xef, 0xc3, 0x94, 0x15, 0x50, 0x03, 0xd0, 0xa8, 0x22, 0x13, 0x70, -0x03, 0xd0, 0xa8, 0x22, 0xff, 0xd5, 0x07, 0xfd, 0xd0, 0xa8, 0x22, 0xc0, 0x00, 0xc0, 0x01, 0xc0, -0x02, 0xc0, 0x04, 0xc0, 0x05, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x86, 0x05, 0x53, 0x05, 0x7f, 0x7c, -0xff, 0x12, 0x10, 0xc0, 0x7f, 0x00, 0x7e, 0x00, 0xe5, 0x43, 0x60, 0x46, 0xfc, 0x90, 0xf9, 0x1d, -0xe0, 0x54, 0x7f, 0x6d, 0x70, 0x0f, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, -0xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xdc, 0xe6, 0x80, 0x26, 0xdc, 0x06, 0xd0, 0x82, -0xd0, 0x83, 0x80, 0x1e, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, -0xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, -0x80, 0xda, 0x12, 0x11, 0x57, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, -0x85, 0xa8, 0x44, 0x75, 0xa8, 0x88, 0xec, 0x70, 0x02, 0x7c, 0x3f, 0x8c, 0x3d, 0x22, 0xe5, 0x3e, -0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0xae, 0x80, 0xfb, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, -0xc0, 0x04, 0xc0, 0x06, 0x7c, 0xff, 0x12, 0x10, 0xc0, 0xe5, 0x43, 0x60, 0x42, 0xfe, 0x90, 0xf9, -0x1d, 0xe0, 0x54, 0x7f, 0x6f, 0x70, 0x0b, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x15, 0x43, -0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xde, 0xea, 0x80, 0x26, 0xde, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80, -0xd8, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3, -0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x78, -0x08, 0x08, 0x79, 0x18, 0x09, 0x7c, 0x01, 0xe6, 0x54, 0x7f, 0x6f, 0x70, 0x06, 0x76, 0x00, 0x77, -0x00, 0x80, 0x06, 0x08, 0x09, 0x0c, 0xbc, 0x08, 0xee, 0x12, 0x11, 0x57, 0xd0, 0x06, 0xd0, 0x04, -0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x75, 0x3d, 0x00, 0x85, 0x44, 0xa8, 0x22, 0xc0, 0xf0, -0xc0, 0x82, 0xc0, 0x83, 0xc3, 0xe5, 0x43, 0x24, 0xe8, 0x50, 0x05, 0x12, 0x11, 0xae, 0x80, 0xf4, -0xef, 0x60, 0x31, 0x90, 0x31, 0x11, 0xe4, 0x93, 0xc3, 0x9f, 0x40, 0x2f, 0xc0, 0x04, 0x7c, 0xff, -0x12, 0x10, 0xc0, 0xd0, 0x04, 0x43, 0x07, 0x80, 0xe5, 0x43, 0x75, 0xf0, 0x03, 0xa4, 0x24, 0x1d, -0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xef, 0xf0, 0xec, 0xa3, 0xf0, 0xed, 0xa3, 0xf0, 0x05, -0x43, 0x12, 0x11, 0x57, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x02, 0x11, 0xdc, 0xc0, 0x04, -0x7c, 0x20, 0xd2, 0x8c, 0xd2, 0x8d, 0xd5, 0x04, 0xfd, 0xd0, 0x04, 0x22, 0x75, 0xa8, 0x00, 0x75, -0x88, 0x00, 0x75, 0xb8, 0x00, 0x75, 0xf0, 0x00, 0x75, 0xd0, 0x00, 0xe4, 0xf8, 0x90, 0xf8, 0x04, -0xf0, 0x90, 0x00, 0x00, 0xf6, 0x08, 0xb8, 0x00, 0xfb, 0x02, 0x00, 0x00, 0xc2, 0xaf, 0xe4, 0x90, -0xff, 0x48, 0xf0, 0x90, 0xff, 0x50, 0xf0, 0x90, 0xff, 0x08, 0xf0, 0x90, 0xff, 0x10, 0xf0, 0x90, -0xff, 0x80, 0xf0, 0xa3, 0xa3, 0xf0, 0xd2, 0xb1, 0xc2, 0xb0, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, -0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0xd2, -0xb0, 0xd2, 0xb1, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, -0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x80, 0xcc, 0xc3, 0xee, 0x94, 0x02, 0x50, 0x04, -0x7e, 0x03, 0x7f, 0xe8, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, -0x42, 0x8e, 0x41, 0x22, 0xc3, 0xef, 0x94, 0xbc, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x07, 0x7f, -0xd0, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x40, 0x8e, 0x3f, -0x22, 0xef, 0x70, 0x01, 0x22, 0xc0, 0x00, 0xc0, 0xa8, 0xc2, 0xaf, 0xe5, 0x3e, 0x24, 0x18, 0xf8, -0xa6, 0x07, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0xc6, 0x54, 0x7f, 0xf6, 0xd0, 0xa8, 0xe6, 0x30, 0xe7, -0x03, 0xd0, 0x00, 0x22, 0x12, 0x11, 0xae, 0x80, 0xf4, 0xc0, 0x00, 0x7f, 0x01, 0xef, 0x24, 0x08, -0xf8, 0xe6, 0x60, 0x09, 0x0f, 0xbf, 0x08, 0xf5, 0x12, 0x11, 0xae, 0x80, 0xee, 0xd0, 0x00, 0x22, -0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x06, 0xc0, 0x04, 0xed, 0x24, 0x10, 0xf8, -0x76, 0x9a, 0xed, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, -0xc0, 0x82, 0xc0, 0x83, 0xa3, 0xa3, 0xe4, 0x78, 0x0d, 0xf0, 0xa3, 0xd8, 0xfc, 0xef, 0x54, 0x7f, -0x75, 0xf0, 0x02, 0xa4, 0x24, 0xf3, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x30, 0xf5, 0x83, 0xe4, 0x93, -0xfe, 0x74, 0x01, 0x93, 0xfc, 0xd0, 0x83, 0xd0, 0x82, 0xec, 0xf0, 0xa3, 0xee, 0xf0, 0xed, 0x24, -0x08, 0xf8, 0xef, 0x44, 0x80, 0xf6, 0xd0, 0x04, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, -0xd0, 0xf0, 0x22, 0x75, 0x3e, 0x00, 0x75, 0x43, 0x00, 0x7a, 0x08, 0x79, 0x18, 0x78, 0x08, 0x76, -0x00, 0x77, 0x00, 0x08, 0x09, 0xda, 0xf8, 0x90, 0xf8, 0x04, 0xe0, 0xfc, 0x90, 0x31, 0x11, 0xe4, -0x93, 0xc3, 0x9c, 0x50, 0x05, 0xe4, 0x90, 0xf8, 0x04, 0xf0, 0x78, 0x08, 0x74, 0x80, 0x44, 0x7f, -0xf6, 0x74, 0x01, 0x44, 0x10, 0xf5, 0x89, 0x75, 0xb8, 0x00, 0xd2, 0xab, 0xd2, 0xa9, 0x22, 0x75, -0x81, 0x8b, 0xd2, 0x8e, 0xd2, 0x8c, 0xd2, 0xaf, 0xe5, 0x43, 0x60, 0x36, 0xff, 0x90, 0xf9, 0x1d, -0xe0, 0x54, 0x80, 0x60, 0x28, 0x78, 0x08, 0x79, 0x08, 0xe0, 0x54, 0x7f, 0xfa, 0x7b, 0x00, 0xe6, -0x54, 0x7f, 0xb5, 0x02, 0x02, 0x7b, 0xff, 0x08, 0xd9, 0xf5, 0xeb, 0x70, 0x10, 0xea, 0xf0, 0xc0, -0x07, 0x12, 0x12, 0x89, 0xad, 0x07, 0xaf, 0x02, 0x12, 0x12, 0xa0, 0xd0, 0x07, 0xa3, 0xa3, 0xa3, -0xdf, 0xce, 0x12, 0x11, 0xae, 0x80, 0xc1, 0x8f, 0x24, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xb5, 0xa3, -0xa3, 0xe0, 0xa3, 0x30, 0xe7, 0x28, 0x78, 0x7e, 0x12, 0x22, 0x99, 0xe0, 0x44, 0x01, 0xf0, 0x12, -0x22, 0xfa, 0x12, 0x22, 0x9d, 0xe0, 0x20, 0xe0, 0xf6, 0x12, 0x23, 0x50, 0x74, 0x02, 0xf0, 0x12, -0x22, 0xda, 0xe0, 0xa3, 0x30, 0xe5, 0x07, 0x12, 0x23, 0x50, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x80, -0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x08, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0x12, 0x23, -0x39, 0x8a, 0x83, 0x24, 0x0a, 0x12, 0x22, 0xa1, 0xed, 0xf0, 0x12, 0x23, 0x06, 0x24, 0x07, 0x12, -0x22, 0xa1, 0xe0, 0xff, 0x12, 0x23, 0x5a, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0x90, 0xf9, -0x16, 0xe0, 0x30, 0xe4, 0x20, 0x08, 0x12, 0x22, 0xb7, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0x25, -0xe0, 0xff, 0x05, 0x82, 0xd5, 0x82, 0x02, 0x15, 0x83, 0x15, 0x82, 0xe0, 0x33, 0xd0, 0x82, 0xd0, -0x83, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x22, 0xb5, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0xff, 0x12, -0x23, 0x39, 0x8a, 0x83, 0x24, 0x08, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0xed, 0x12, 0x23, 0x5a, 0x24, -0x07, 0x12, 0x22, 0xa1, 0xed, 0xf0, 0x12, 0x22, 0xa9, 0xe0, 0x30, 0xe6, 0x0a, 0x12, 0x23, 0x41, -0x24, 0x09, 0x12, 0x22, 0xa1, 0xe4, 0xf0, 0x12, 0x22, 0xa9, 0xe0, 0xff, 0x30, 0xe7, 0x1b, 0x12, -0x23, 0x1e, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x60, 0x09, 0x12, 0x22, 0xa9, 0xef, 0x44, 0x02, -0xf0, 0x80, 0x07, 0x12, 0x22, 0xa9, 0xef, 0x54, 0xfd, 0xf0, 0x78, 0x7e, 0x12, 0x22, 0xb7, 0xa3, -0xa3, 0xe0, 0xff, 0x53, 0x07, 0xc7, 0x08, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x12, 0x22, 0xe0, 0xa3, -0xe0, 0x30, 0xe3, 0x12, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0x12, 0x22, 0xa1, 0xe0, -0x90, 0x32, 0x51, 0x93, 0x42, 0x07, 0x53, 0x07, 0xfb, 0x12, 0x23, 0x1e, 0x24, 0x06, 0x12, 0x22, -0xa1, 0xe0, 0x60, 0x03, 0x43, 0x07, 0x04, 0x53, 0x07, 0xfc, 0x78, 0x80, 0x12, 0x23, 0x29, 0x24, -0x04, 0x12, 0x22, 0xa1, 0xe0, 0x42, 0x07, 0x43, 0x07, 0x80, 0x12, 0x23, 0x39, 0xf5, 0x82, 0x8a, -0x83, 0xa3, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0x5a, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0xff, 0x8d, -0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe1, 0x05, 0x53, 0x07, 0xdf, -0x80, 0x03, 0x43, 0x07, 0x20, 0xec, 0x30, 0xe4, 0x05, 0x53, 0x07, 0xef, 0x80, 0x03, 0x43, 0x07, -0x10, 0x12, 0x22, 0xa9, 0xe0, 0xfe, 0x54, 0x03, 0x60, 0x73, 0x53, 0x07, 0xdf, 0xee, 0x30, 0xe1, -0x69, 0x12, 0x23, 0x1e, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x12, 0x1b, 0xfc, 0x15, 0x2c, 0x00, -0x15, 0x60, 0x01, 0x15, 0x65, 0x03, 0x15, 0x60, 0x05, 0x15, 0x65, 0x07, 0x15, 0x60, 0x09, 0x15, -0x65, 0x0b, 0x15, 0x60, 0x0d, 0x15, 0x65, 0x0f, 0x00, 0x00, 0x15, 0x6d, 0xe5, 0x24, 0x64, 0x03, -0x70, 0x21, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe2, 0x0d, 0x30, 0xb4, 0x05, 0x43, 0x07, 0x02, 0x80, -0x2c, 0x53, 0x07, 0xfd, 0x80, 0x27, 0x30, 0x95, 0x05, 0x43, 0x07, 0x02, 0x80, 0x1f, 0x53, 0x07, -0xfd, 0x80, 0x1a, 0x30, 0x93, 0x05, 0x43, 0x07, 0x02, 0x80, 0x12, 0x53, 0x07, 0xfd, 0x80, 0x0d, -0x43, 0x07, 0x02, 0x80, 0x08, 0x53, 0x07, 0xfd, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x12, 0x23, 0x27, -0x24, 0x04, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xff, -0x12, 0x22, 0xa9, 0xe0, 0xfe, 0x54, 0x03, 0x70, 0x03, 0x02, 0x16, 0x60, 0xee, 0x20, 0xe1, 0x03, -0x02, 0x16, 0x5d, 0x08, 0x12, 0x23, 0x20, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x12, 0x1b, 0xfc, -0x15, 0xbf, 0x00, 0x15, 0xf5, 0x01, 0x15, 0xf5, 0x03, 0x16, 0x29, 0x05, 0x16, 0x29, 0x07, 0x16, -0x0f, 0x09, 0x16, 0x0f, 0x0b, 0x16, 0x43, 0x0d, 0x16, 0x43, 0x0f, 0x00, 0x00, 0x16, 0x60, 0xe5, -0x24, 0x64, 0x03, 0x70, 0x23, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe2, 0x0f, 0x30, 0xb1, 0x06, 0x53, -0x07, 0x7f, 0x02, 0x16, 0x60, 0x43, 0x07, 0x80, 0x02, 0x16, 0x60, 0x30, 0x94, 0x05, 0x53, 0x07, -0x7f, 0x80, 0x7d, 0x43, 0x07, 0x80, 0x80, 0x78, 0x30, 0x92, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x70, -0x43, 0x07, 0x80, 0x80, 0x6b, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef, -0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x51, 0xe5, -0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, -0xe0, 0x44, 0x20, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x37, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, -0x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x43, 0x07, -0x80, 0x80, 0x1d, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80, -0x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x43, 0x07, 0x80, 0x80, 0x03, 0x53, 0x07, 0x7f, -0x12, 0x22, 0xda, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x20, 0x80, 0x03, -0x53, 0x07, 0xdf, 0xec, 0x30, 0xe3, 0x05, 0x43, 0x07, 0x40, 0x80, 0x03, 0x53, 0x07, 0xbf, 0xec, -0x30, 0xe0, 0x05, 0x43, 0x07, 0x10, 0x80, 0x03, 0x53, 0x07, 0xef, 0xed, 0x30, 0xe4, 0x05, 0x43, -0x07, 0x08, 0x80, 0x03, 0x53, 0x07, 0xf7, 0xed, 0x30, 0xe5, 0x05, 0x43, 0x07, 0x04, 0x80, 0x03, -0x53, 0x07, 0xfb, 0xed, 0x30, 0xe6, 0x05, 0x43, 0x07, 0x01, 0x80, 0x03, 0x53, 0x07, 0xfe, 0xed, -0x30, 0xe7, 0x05, 0x43, 0x07, 0x02, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x78, 0x7e, 0x12, 0x22, 0xdc, -0xa3, 0xef, 0xf0, 0x12, 0x32, 0x84, 0x7f, 0x00, 0x22, 0x90, 0xff, 0xfa, 0x74, 0x08, 0xf0, 0xa3, -0x74, 0x16, 0xf0, 0x90, 0xff, 0xf9, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcf, 0xe4, -0xfd, 0x12, 0x23, 0x61, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1b, 0x1c, 0x12, 0x19, -0x92, 0xe5, 0x23, 0x30, 0xe7, 0x02, 0xd2, 0x02, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x24, 0x90, 0xfa, -0xcf, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xcf, -0xe4, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x75, 0x2d, 0x00, 0xf5, -0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0xe5, 0x23, 0x24, 0x80, 0x90, 0xff, 0xf8, 0xf0, 0xe5, 0x23, -0x64, 0x07, 0x60, 0x1e, 0xe5, 0x23, 0x64, 0x06, 0x60, 0x18, 0xe5, 0x23, 0x64, 0x14, 0x60, 0x12, -0xe5, 0x23, 0x64, 0x41, 0x60, 0x0c, 0xe5, 0x23, 0x64, 0x1a, 0x70, 0x46, 0xe5, 0x24, 0x64, 0x02, -0x70, 0x40, 0xe5, 0x23, 0xb4, 0x07, 0x16, 0xd2, 0x94, 0xd2, 0x95, 0xd2, 0x92, 0xd2, 0x93, 0x90, -0xf9, 0x16, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1e, 0xe5, 0x23, 0xb4, -0x41, 0x12, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x06, 0xf0, 0xa3, 0xe0, 0x44, 0x06, 0xf0, 0xd2, 0xb1, -0xd2, 0xb4, 0x80, 0x07, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x44, -0x01, 0xf0, 0xe5, 0x23, 0x64, 0x42, 0x60, 0x0c, 0xe5, 0x23, 0x64, 0x43, 0x60, 0x06, 0xe5, 0x23, -0x64, 0x44, 0x70, 0x2e, 0x90, 0xf9, 0x16, 0xe0, 0xff, 0xe5, 0x23, 0xb4, 0x44, 0x04, 0x7e, 0x40, -0x80, 0x02, 0x7e, 0x00, 0xee, 0x24, 0x80, 0x4f, 0x90, 0xf9, 0x16, 0xf0, 0xa3, 0xe0, 0xff, 0xe5, -0x23, 0xb4, 0x44, 0x04, 0x7e, 0x40, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x24, 0x80, 0x4f, 0x90, 0xf9, -0x17, 0xf0, 0x90, 0xfa, 0xcf, 0xe4, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0x12, 0x19, 0x92, 0x90, 0xff, -0xf5, 0xe5, 0x23, 0xf0, 0xe4, 0xf5, 0x35, 0xf5, 0x33, 0xf5, 0x34, 0xf5, 0x32, 0x12, 0x1e, 0x34, -0x12, 0x1c, 0xe0, 0x12, 0x1e, 0x3b, 0x90, 0xf9, 0x6a, 0x12, 0x1b, 0xf3, 0x90, 0xf9, 0x6f, 0x12, -0x1b, 0xf3, 0x90, 0xff, 0xff, 0xe4, 0xf0, 0x90, 0xff, 0x83, 0xe0, 0xe4, 0xf0, 0x90, 0xff, 0x81, -0x74, 0x80, 0xf0, 0xa3, 0x74, 0x84, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xe4, 0xf5, 0x23, 0xe5, 0x23, -0x12, 0x1d, 0x57, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x23, 0x12, 0x1d, 0x65, 0xf5, 0x83, 0xe4, 0xf0, -0x05, 0x23, 0xe5, 0x23, 0xb4, 0x07, 0xe7, 0x78, 0x7a, 0x76, 0xfe, 0x08, 0x76, 0xf0, 0x90, 0x32, -0x0a, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xad, 0x07, 0x90, 0x32, 0x17, 0xe4, 0x93, 0xff, -0x08, 0xf6, 0xff, 0xed, 0x54, 0x0f, 0xfd, 0x12, 0x1d, 0x47, 0x74, 0x84, 0xf0, 0xed, 0x75, 0xf0, -0x08, 0xa4, 0x24, 0x47, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xc3, 0x74, 0xf0, -0x9f, 0x78, 0x7b, 0xf6, 0x74, 0xfe, 0x94, 0x00, 0x18, 0x12, 0x1c, 0xd8, 0xce, 0xc3, 0x13, 0xce, -0x13, 0xd8, 0xf9, 0xff, 0xed, 0x12, 0x1d, 0xa8, 0xef, 0xf0, 0xed, 0x12, 0x1d, 0xce, 0xe4, 0xf5, -0x23, 0xe5, 0x23, 0x90, 0x32, 0x04, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xe5, 0x23, 0x25, 0xe0, -0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x34, 0x32, 0xf5, 0x83, 0xe4, 0x93, 0x08, 0xf6, 0xed, 0x30, 0xe7, -0x53, 0x18, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1d, 0x47, 0x12, 0x1d, 0xb6, 0x24, 0x47, 0xf5, 0x82, -0xe4, 0x34, 0xff, 0x12, 0x1c, 0xc8, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe9, 0x12, -0x1d, 0xa8, 0xef, 0xf0, 0x12, 0x1c, 0xcf, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, -0xbb, 0x24, 0x45, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x12, 0x1d, 0xce, -0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x46, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, -0xf0, 0x02, 0x19, 0x67, 0x78, 0x78, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1d, 0x9a, 0x12, 0x1d, 0xb6, -0x24, 0x07, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x12, 0x1c, 0xc8, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, -0xf9, 0x12, 0x1d, 0xbb, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0x12, -0x1c, 0xcf, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 0xbb, 0x24, 0x05, 0xf5, 0x82, -0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, -0xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, -0xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x23, 0xe5, 0x23, 0x64, 0x04, 0x60, 0x03, 0x02, -0x18, 0x91, 0x90, 0x32, 0x09, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0x12, 0x1d, 0x98, 0xe4, 0xf0, -0x90, 0x32, 0x08, 0x93, 0xff, 0xf6, 0x12, 0x1d, 0x45, 0xe4, 0xf0, 0x90, 0xff, 0xfd, 0x74, 0x05, -0xf0, 0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12, -0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x26, 0x98, 0xe7, 0x09, 0xf6, 0x08, -0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e, 0x88, 0x82, 0x8c, 0x83, -0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x78, -0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83, 0xe3, 0x09, 0xf0, 0xa3, -0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x58, -0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c, 0x80, 0xd2, 0x80, 0xfa, -0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10, 0x80, 0xa6, 0x80, 0xea, -0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33, 0x89, 0x82, 0x8a, 0x83, -0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, -0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0x0d, 0x89, 0x82, 0x8a, -0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0, 0xed, 0xfb, 0x22, 0x89, -0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xf0, -0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde, 0xe8, 0x80, 0xdb, 0x89, -0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc, 0x88, 0xf0, 0xef, 0x60, -0x01, 0x0e, 0x4e, 0x60, 0xc3, 0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xb9, 0xf5, -0x82, 0xeb, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xaf, 0x23, 0x23, 0x45, 0x82, 0x23, 0x90, 0x19, -0xfc, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, -0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, -0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, -0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, -0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, -0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, -0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 0xf0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, -0xc8, 0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 0xc8, 0xf2, 0x22, 0xc5, 0xf0, 0xf8, 0xa3, -0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xe0, 0x38, -0xf0, 0x22, 0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, -0x15, 0x83, 0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22, 0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, -0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0, 0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, -0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe, 0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, -0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83, 0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22, -0xbb, 0x01, 0x0a, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0xe5, 0xf0, 0xa3, 0xf0, 0x22, 0x50, 0x06, 0xf7, -0x09, 0xa7, 0xf0, 0x19, 0x22, 0xbb, 0xfe, 0x06, 0xf3, 0xe5, 0xf0, 0x09, 0xf3, 0x19, 0x22, 0xf8, -0xbb, 0x01, 0x11, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 0xf0, 0xe5, -0xf0, 0xa3, 0xf0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xc8, 0xf6, 0x08, 0xa6, 0xf0, 0x22, 0xbb, -0xfe, 0x09, 0xe9, 0x25, 0x82, 0xc8, 0xf2, 0xe5, 0xf0, 0x08, 0xf2, 0x22, 0xa4, 0x25, 0x82, 0xf5, -0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xe6, 0xfb, 0x08, 0xe6, 0xfa, 0x08, 0xe6, 0xf9, -0x22, 0xeb, 0xf6, 0x08, 0xea, 0xf6, 0x08, 0xe9, 0xf6, 0x22, 0xe0, 0xfb, 0xa3, 0xe0, 0xfa, 0xa3, -0xe0, 0xf9, 0x22, 0xeb, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xe9, 0xf0, 0x22, 0xd0, 0x83, 0xd0, 0x82, -0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, -0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, -0x80, 0xdf, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0xe5, 0x4c, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, -0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0x74, 0x11, 0x12, -0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x06, -0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, -0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 0xe8, 0x04, 0x25, -0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, -0xe8, 0x04, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x04, 0xe0, 0xab, -0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, -0x37, 0xf5, 0x37, 0x90, 0xff, 0x05, 0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, -0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x22, 0xf5, 0x83, 0xe0, 0x54, -0x08, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xf5, 0x83, 0xef, 0xf0, 0xfd, 0x7c, 0x00, 0xc3, -0x78, 0x7b, 0xe6, 0x9d, 0xf6, 0x18, 0xe6, 0x9c, 0xf6, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x03, 0x22, -0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 0x72, 0x22, 0xe0, 0x44, 0x04, 0xf0, 0x74, 0x13, -0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xe0, 0x22, 0x90, 0xfa, 0xbc, 0xe0, 0xff, 0x7e, -0x00, 0xc3, 0x90, 0xfa, 0xc0, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xbf, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, -0xb7, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0xef, 0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5, -0x4e, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb4, 0x90, 0xfa, 0xb7, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, -0xf5, 0x2e, 0x22, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x24, 0x04, 0xf5, 0x82, 0xe4, -0x35, 0x83, 0xf5, 0x83, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe4, -0x34, 0xff, 0xf5, 0x83, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x48, 0xf5, 0x82, 0xe4, -0x34, 0xff, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x34, 0xff, -0x22, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x24, 0xfc, 0x22, 0x90, 0xff, 0x00, 0xe0, 0x54, 0x1f, 0x22, -0x90, 0xfa, 0xbe, 0xe0, 0x90, 0xfa, 0xba, 0xf0, 0x22, 0x75, 0x33, 0x00, 0x8f, 0x34, 0x90, 0xf9, -0x6f, 0x12, 0x1b, 0xea, 0x90, 0x00, 0x02, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, -0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x41, 0xf5, 0x82, -0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x74, 0x80, 0xf0, 0x08, 0xe6, 0xff, 0xe9, 0x75, 0xf0, 0x08, -0xa4, 0x22, 0x74, 0xb2, 0x25, 0x22, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0x22, 0x75, 0xf0, -0x08, 0xa4, 0x24, 0x42, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x22, 0x90, -0xff, 0x82, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x03, 0xf0, 0x90, 0xff, -0xfc, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x78, 0x67, 0xe6, 0x54, 0xfd, 0xf6, 0x90, 0xff, 0xfd, 0x74, -0x65, 0xf0, 0x22, 0x12, 0x1b, 0xcc, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x22, 0x7b, 0x01, 0x7a, -0xfa, 0x79, 0xb7, 0x22, 0x90, 0xff, 0x80, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0x83, 0xe0, -0x54, 0x7f, 0xf0, 0x22, 0xe0, 0xff, 0x90, 0xf9, 0x6a, 0x02, 0x1b, 0xea, 0x90, 0xff, 0xa4, 0xe0, -0x44, 0x02, 0xf0, 0x22, 0x75, 0x39, 0x01, 0x75, 0x3a, 0x09, 0x22, 0x7b, 0x01, 0x7a, 0xf9, 0x79, -0x72, 0x22, 0xd3, 0xe5, 0x3c, 0x94, 0x08, 0xe5, 0x3b, 0x94, 0x01, 0x22, 0x90, 0xfa, 0xbe, 0xe0, -0xff, 0x90, 0xfa, 0xba, 0xf0, 0x22, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xef, 0x22, 0x90, 0xff, 0xb4, -0xe0, 0x54, 0xef, 0x22, 0x12, 0x10, 0x4b, 0x78, 0x88, 0xef, 0xf6, 0x12, 0x2a, 0xc7, 0x12, 0x22, -0xfa, 0x8e, 0x83, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x0a, -0x12, 0x23, 0x02, 0x24, 0x0a, 0x12, 0x22, 0xa1, 0xe0, 0x90, 0x00, 0x0b, 0x12, 0x1a, 0xfa, 0x12, -0x22, 0xfa, 0xf5, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x53, 0x12, 0x23, 0x06, 0x24, -0x04, 0x12, 0x22, 0xa1, 0xe0, 0xf5, 0x54, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x55, -0xe5, 0x53, 0xc4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x78, 0x88, 0xf6, 0xd3, 0x94, 0x00, 0x40, 0x06, -0xe5, 0x54, 0x30, 0xe1, 0x01, 0x06, 0x78, 0x88, 0xe6, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x0c, 0xef, -0x12, 0x1a, 0xfa, 0x12, 0x22, 0xb5, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x53, 0x07, 0x0c, -0x53, 0x06, 0xe6, 0xe5, 0x53, 0x30, 0xe5, 0x03, 0x43, 0x07, 0x01, 0xe5, 0x54, 0x20, 0xe5, 0x0e, -0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43, 0x07, 0x02, 0xe5, 0x53, -0x30, 0xe3, 0x03, 0x43, 0x07, 0x10, 0xe5, 0x53, 0x30, 0xe2, 0x03, 0x43, 0x07, 0x20, 0xe5, 0x53, -0x54, 0x03, 0x60, 0x03, 0x43, 0x07, 0x40, 0xe5, 0x53, 0x30, 0xe1, 0x03, 0x43, 0x07, 0x80, 0xe5, -0x53, 0x30, 0xe4, 0x03, 0x43, 0x06, 0x01, 0xe5, 0x53, 0x30, 0xe6, 0x03, 0x43, 0x06, 0x08, 0xe5, -0x54, 0x20, 0xe4, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43, -0x06, 0x10, 0x53, 0x07, 0xfb, 0x53, 0x06, 0x79, 0x90, 0x00, 0x05, 0xee, 0x8f, 0xf0, 0x12, 0x1b, -0x9f, 0xe5, 0x55, 0x30, 0xe3, 0x12, 0x54, 0x30, 0xff, 0xc4, 0x54, 0x0f, 0x12, 0x22, 0xe7, 0x90, -0x00, 0x08, 0xef, 0x12, 0x1a, 0xfa, 0x80, 0x0a, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x08, 0xe4, 0x12, -0x1a, 0xfa, 0xe5, 0x55, 0x54, 0x03, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x07, 0xef, 0x12, 0x1a, 0xfa, -0xe5, 0x55, 0x54, 0x04, 0xff, 0xc3, 0x13, 0x90, 0x00, 0x09, 0x12, 0x1a, 0xfa, 0x90, 0x00, 0x07, -0x12, 0x1a, 0xbb, 0x70, 0x13, 0x12, 0x22, 0xe8, 0xe9, 0x24, 0x09, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, -0x1a, 0xa2, 0xff, 0xc3, 0x13, 0x12, 0x1a, 0xe8, 0x12, 0x23, 0x27, 0x24, 0x08, 0x12, 0x22, 0xa1, -0xe0, 0xfe, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x07, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0xee, -0xed, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x03, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x9f, 0x12, 0x32, 0x84, -0x7d, 0x0a, 0xe4, 0xff, 0x12, 0x2f, 0xb4, 0x02, 0x10, 0xce, 0x90, 0xfa, 0xe6, 0xe0, 0xb4, 0x03, -0x06, 0x7e, 0x00, 0x7f, 0x40, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x08, 0x90, 0xfa, 0xda, 0xee, 0xf0, -0xa3, 0xef, 0xf0, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, 0xff, 0x7e, 0x00, 0x90, 0xfa, 0xd6, 0xee, -0xf0, 0xa3, 0xef, 0xf0, 0x70, 0x03, 0x7f, 0x08, 0x22, 0x90, 0x00, 0x08, 0x12, 0x1b, 0x48, 0xff, -0x90, 0xfa, 0xd8, 0xe5, 0xf0, 0xf0, 0xa3, 0xef, 0xf0, 0xae, 0x02, 0xaf, 0x01, 0x8e, 0x50, 0x8f, -0x51, 0x74, 0x0a, 0x25, 0x51, 0xf5, 0x51, 0xe4, 0x35, 0x50, 0xf5, 0x50, 0x90, 0xfa, 0xdb, 0xe0, -0xff, 0x14, 0xfe, 0x90, 0xfa, 0xd9, 0xe0, 0x5e, 0xfe, 0xc3, 0xef, 0x9e, 0xff, 0x90, 0xfa, 0xdd, -0xf0, 0xc3, 0x90, 0xfa, 0xd7, 0xe0, 0x9f, 0x90, 0xfa, 0xd6, 0xe0, 0x94, 0x00, 0x50, 0x06, 0xa3, -0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x12, 0x20, 0xa9, 0x60, 0x03, 0xe0, 0xff, 0x22, 0x12, 0x2e, 0x2b, -0x90, 0xfa, 0xd6, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x60, 0x2b, 0x90, 0xfa, 0xda, 0xe0, 0xfc, -0xa3, 0xe0, 0xfd, 0xd3, 0xef, 0x9d, 0xee, 0x9c, 0x40, 0x07, 0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x80, -0x08, 0x90, 0xfa, 0xd7, 0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x12, 0x20, 0xa9, 0x60, 0x03, 0xe0, 0xff, -0x22, 0x12, 0x2e, 0x2b, 0x80, 0xca, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x52, 0xe4, 0xf5, 0x2d, 0xf5, -0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x7f, 0x00, 0x22, 0xaa, 0x50, 0xa9, 0x51, 0x7b, 0x01, 0x90, -0xfa, 0xd8, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xdd, 0xe0, 0xf5, 0x4a, 0x12, 0x29, 0x60, -0x90, 0xfa, 0xdc, 0xef, 0xf0, 0x22, 0xef, 0x24, 0xae, 0x60, 0x52, 0x24, 0xfe, 0x60, 0x2e, 0x24, -0xfe, 0x70, 0x03, 0x02, 0x21, 0x69, 0x24, 0x06, 0x60, 0x03, 0x02, 0x21, 0xb1, 0x78, 0x71, 0xe6, -0x54, 0xfb, 0xf6, 0x90, 0xff, 0xa5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x33, 0x90, 0xfa, -0x94, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb2, 0x74, 0x01, 0xf0, 0x22, 0x78, 0x72, 0xe6, -0x54, 0xfb, 0xf6, 0x90, 0xff, 0xb5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x43, 0x90, 0xfa, -0x96, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb3, 0x74, 0x01, 0xf0, 0x22, 0x90, 0xfa, 0xa0, -0xe0, 0xa3, 0x20, 0xe5, 0x03, 0x02, 0x21, 0xb1, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, -0xa3, 0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xa6, 0x12, -0x23, 0x0d, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xce, 0xe0, -0xff, 0x74, 0x34, 0xfe, 0x12, 0x2d, 0x85, 0xef, 0x70, 0x57, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, -0x34, 0x90, 0xfa, 0x98, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0x90, 0xfa, 0xaa, 0xe0, 0xa3, 0x30, 0xe5, -0x40, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xff, -0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xb6, 0x12, 0x23, 0x0d, 0x90, 0xff, 0xb6, 0xe0, 0x90, -0xfa, 0xcd, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, 0x44, 0xfe, 0x12, 0x2d, 0x85, -0xef, 0x70, 0x0e, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, 0x44, 0x90, 0xfa, 0x9a, 0xf0, 0xef, 0xa3, -0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, -0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0x90, -0xff, 0x92, 0xe0, 0xff, 0x90, 0xfa, 0xcc, 0xf0, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0xef, 0x12, 0x1b, -0xfc, 0x22, 0x69, 0x26, 0x22, 0x69, 0x2e, 0x22, 0x0c, 0x30, 0x22, 0x0c, 0x32, 0x22, 0x1a, 0x38, -0x22, 0x2c, 0x3a, 0x22, 0x5e, 0x3e, 0x22, 0x49, 0x44, 0x22, 0x3e, 0x46, 0x22, 0x54, 0x50, 0x22, -0x54, 0x52, 0x22, 0x54, 0x54, 0x22, 0x54, 0x56, 0x00, 0x00, 0x22, 0x6e, 0x90, 0xfa, 0xcc, 0xe0, -0xfd, 0x7c, 0x00, 0x7f, 0x01, 0x12, 0x11, 0x5e, 0x80, 0x62, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x03, -0x12, 0x11, 0x5e, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x50, 0x7c, 0x00, 0x7d, 0x01, -0x7f, 0x02, 0x12, 0x11, 0x5e, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x3e, 0x7c, 0x00, -0x7d, 0x01, 0x7f, 0x05, 0x12, 0x11, 0x5e, 0x80, 0x33, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x06, 0x12, -0x11, 0x5e, 0x80, 0x28, 0x90, 0xfa, 0xcc, 0xe0, 0xff, 0x12, 0x20, 0xc6, 0x80, 0x1e, 0x7c, 0x00, -0x7d, 0x01, 0x7f, 0x04, 0x12, 0x11, 0x5e, 0x80, 0x13, 0x12, 0x28, 0x4e, 0x80, 0x0e, 0x90, 0xfa, -0xcc, 0xe0, 0x24, 0x00, 0xff, 0xe4, 0x34, 0xff, 0xfe, 0x12, 0x2d, 0x85, 0xd0, 0x07, 0xd0, 0x06, -0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, -0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x24, 0x04, 0x8e, -0x83, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x74, 0x13, 0x25, 0x24, 0xf5, 0x82, 0xe4, -0x34, 0xf9, 0xf5, 0x83, 0x22, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0x22, -0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0x7b, 0xff, 0x7a, -0x32, 0x79, 0x56, 0x7e, 0x00, 0x7f, 0x0a, 0x02, 0x1a, 0x7c, 0x78, 0x80, 0xe6, 0xfc, 0x08, 0xe6, -0xf5, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0x22, 0xff, 0x90, 0xf9, 0x6f, 0x02, 0x1b, 0xea, 0x90, 0xf9, -0x6a, 0x12, 0x1b, 0xea, 0x90, 0x00, 0x04, 0x02, 0x1a, 0xbb, 0x78, 0x7e, 0xe6, 0xfe, 0x08, 0xe6, -0xff, 0x22, 0xed, 0x12, 0x1a, 0xfa, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x22, 0xef, 0xf0, 0x90, -0xfa, 0xce, 0xe0, 0x54, 0x0f, 0x4e, 0xfe, 0xf0, 0xef, 0x54, 0xf0, 0x4e, 0xf0, 0x22, 0x78, 0x80, -0xe6, 0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x22, 0x78, 0x7e, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x8c, 0x83, -0x22, 0xa6, 0x07, 0xe6, 0x24, 0x6e, 0xf8, 0xe6, 0x22, 0x78, 0x7e, 0xe6, 0xfa, 0x08, 0xe6, 0xfb, -0x22, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x22, 0x26, 0xf6, 0x18, 0xee, 0x36, 0xf6, 0x22, -0xef, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0x22, 0x8b, 0x82, 0x8a, 0x83, 0xe5, 0x82, -0x22, 0x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0x8d, 0x28, 0x90, 0xfa, 0xd2, 0xe4, 0xf0, 0xa3, 0x74, -0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xd1, 0x90, 0xfa, 0xd2, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, -0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xd1, 0xe0, 0x65, 0x28, 0x60, 0x46, 0xa3, -0xe0, 0xff, 0xa3, 0xe0, 0xa3, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0xf0, 0x90, 0xfa, 0xd1, -0xe0, 0xff, 0x90, 0xfa, 0xd4, 0xe4, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0x12, 0x23, 0xf0, 0x90, 0xfa, -0xd4, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0xfa, 0xd2, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xfa, 0xd1, -0xe0, 0xa3, 0x75, 0xf0, 0x00, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xd2, 0xe4, 0x75, 0xf0, 0x04, 0x12, -0x1b, 0x1c, 0x02, 0x23, 0x72, 0x90, 0xfa, 0xd3, 0xe0, 0x24, 0x01, 0xff, 0x90, 0xfa, 0xd2, 0xe0, -0x34, 0x00, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x8f, 0xf0, 0x12, 0x1b, 0x80, 0x7f, 0x00, 0x22, -0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xd1, 0x90, 0xfa, 0xd2, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1b, 0x1c, -0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x26, 0x98, 0x8f, 0x62, 0x12, 0x2a, 0xc7, 0x12, -0x22, 0xfa, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x02, 0xf0, -0x08, 0x12, 0x22, 0xdc, 0xe0, 0xa3, 0x30, 0xe5, 0x0c, 0x12, 0x23, 0x06, 0x24, 0x0b, 0x12, 0x22, -0xa1, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xf5, 0x82, 0x8e, 0x83, -0xe0, 0x54, 0xb8, 0xfd, 0xf0, 0xe5, 0x62, 0x24, 0xfe, 0x44, 0x20, 0xfc, 0x4d, 0xf0, 0xe5, 0x82, -0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xb8, 0xf0, 0x4c, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, -0x74, 0x03, 0xf0, 0x18, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x05, 0x12, 0x22, 0xa1, -0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x74, 0x99, 0x25, 0x62, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, -0x83, 0xe0, 0x54, 0xfc, 0x44, 0x03, 0xfc, 0xed, 0x4c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, -0x8e, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0x44, 0x80, -0xf0, 0x12, 0x32, 0x84, 0x74, 0x6e, 0x25, 0x62, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, -0x12, 0x10, 0x4b, 0x7f, 0x02, 0x12, 0x12, 0x61, 0x78, 0x67, 0xe6, 0x44, 0x02, 0xf6, 0xd2, 0xb0, -0xd2, 0xb1, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe7, 0x07, 0x90, 0xff, 0x9e, 0xe4, 0xf0, 0x80, 0x36, -0xd2, 0xb3, 0x90, 0xff, 0xa4, 0xe0, 0x90, 0xfa, 0x7e, 0xf0, 0x90, 0xff, 0xb4, 0xe0, 0x90, 0xfa, -0x7f, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x90, 0xfa, 0x7c, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x90, 0xfa, -0x7d, 0xf0, 0x90, 0xff, 0xa4, 0x74, 0x30, 0xf0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xff, 0xa2, 0x74, -0x40, 0xf0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xfa, 0xe7, 0xe5, 0xa8, 0xf0, 0x75, 0xa8, 0x81, 0x90, -0xff, 0x92, 0xe0, 0x60, 0x04, 0xe4, 0xf0, 0x80, 0xf6, 0x90, 0xff, 0xfd, 0x74, 0x3a, 0xf0, 0x43, -0x87, 0x01, 0x00, 0x00, 0x00, 0x90, 0xfa, 0x7e, 0xe0, 0x90, 0xff, 0xa4, 0xf0, 0x90, 0xfa, 0x7f, -0xe0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xfa, 0x7c, 0xe0, 0x90, 0xff, 0xa2, 0xf0, 0x90, 0xfa, 0x7d, -0xe0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xf9, 0x18, 0xe0, 0x60, 0x02, 0xc2, 0xb3, 0x90, 0xfa, 0xe7, -0xe0, 0xf5, 0xa8, 0x02, 0x10, 0xce, 0x8b, 0x5c, 0x8a, 0x5d, 0x89, 0x5e, 0x12, 0x2e, 0x0d, 0x90, -0xfa, 0xc3, 0x12, 0x1b, 0xf3, 0xaa, 0x5d, 0xa9, 0x5e, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0xf3, 0x90, -0xfa, 0xc7, 0xe4, 0x75, 0xf0, 0x0a, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0xea, 0xe9, -0x24, 0x01, 0xf9, 0xe4, 0x3a, 0xfa, 0x90, 0xfa, 0xc9, 0x12, 0x1b, 0xf3, 0xab, 0x5c, 0xaa, 0x5d, -0xa9, 0x5e, 0x12, 0x2e, 0x19, 0xe0, 0xff, 0xc3, 0x13, 0xf0, 0xe4, 0x78, 0x82, 0xf6, 0x90, 0xfa, -0xc1, 0xe0, 0xff, 0x78, 0x82, 0xe6, 0xc3, 0x9f, 0x50, 0x4a, 0x90, 0xfa, 0xc3, 0x12, 0x2d, 0xee, -0xff, 0x78, 0x83, 0xf6, 0x90, 0xfa, 0xc6, 0x12, 0x2d, 0xee, 0xfe, 0xf4, 0x5f, 0xff, 0x78, 0x83, -0xf6, 0x12, 0x2d, 0xeb, 0x5e, 0x4f, 0xff, 0x78, 0x83, 0xf6, 0x12, 0x2d, 0xf4, 0x75, 0xf0, 0x02, -0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xc7, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1b, 0x1c, 0xab, 0x5c, 0xaa, -0x5d, 0xa9, 0x5e, 0x90, 0x00, 0x04, 0x12, 0x1a, 0xbb, 0x30, 0xe4, 0x03, 0x12, 0x2e, 0x03, 0x78, -0x82, 0x06, 0x80, 0xaa, 0xe4, 0x90, 0xfa, 0xc2, 0xf0, 0x22, 0x8b, 0x56, 0x8a, 0x57, 0x89, 0x58, -0x90, 0xfa, 0xc2, 0x74, 0x06, 0xf0, 0xe4, 0x90, 0xfa, 0xc1, 0xf0, 0x12, 0x1a, 0xa2, 0x24, 0x6e, -0x60, 0x26, 0x14, 0x70, 0x70, 0x12, 0x2d, 0xda, 0x60, 0x09, 0x24, 0x30, 0x70, 0x12, 0x12, 0x25, -0x56, 0x80, 0x62, 0x12, 0x2e, 0x24, 0x12, 0x1f, 0xda, 0x90, 0xfa, 0xc2, 0xef, 0xf0, 0x80, 0x55, -0x90, 0xfa, 0xc2, 0x74, 0x81, 0xf0, 0x80, 0x4d, 0x12, 0x2d, 0xda, 0x60, 0x09, 0x24, 0x30, 0x70, -0x3e, 0x12, 0x2d, 0x30, 0x80, 0x3f, 0xe5, 0x58, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x57, 0xfa, 0x7b, -0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0x12, 0x2e, 0x24, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, -0xfd, 0x90, 0x00, 0x08, 0x12, 0x1b, 0x48, 0xf5, 0x2e, 0x85, 0xf0, 0x2d, 0xd0, 0x01, 0xd0, 0x02, -0xd0, 0x03, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xc1, 0xef, 0xf0, 0xe4, 0xa3, 0xf0, 0x80, 0x06, 0x90, -0xfa, 0xc2, 0x74, 0x81, 0xf0, 0x90, 0xfa, 0xc2, 0xe0, 0x12, 0x2e, 0x24, 0x90, 0x00, 0x02, 0x12, -0x1a, 0xfa, 0x90, 0xfa, 0xc1, 0xe0, 0xff, 0x22, 0x8b, 0x29, 0x8a, 0x2a, 0x89, 0x2b, 0x8d, 0x2c, -0xe5, 0x2c, 0x70, 0x03, 0xaf, 0x2c, 0x22, 0x12, 0x2e, 0x53, 0x70, 0x16, 0x12, 0x2e, 0x72, 0xe5, -0x2d, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0xd8, 0x50, 0xf2, 0x12, 0x27, 0x25, 0x40, 0x0b, 0x7f, -0x00, 0x22, 0x12, 0x2e, 0x72, 0x12, 0x27, 0x25, 0x50, 0xf8, 0x90, 0xff, 0xf3, 0x74, 0xa1, 0xf0, -0xe5, 0x2c, 0xb4, 0x01, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0xf1, 0xe4, -0xf0, 0xf5, 0x2f, 0xe5, 0x2c, 0x14, 0xff, 0xe5, 0x2f, 0xc3, 0x9f, 0x50, 0x2a, 0x12, 0x31, 0xc1, -0x40, 0x03, 0xaf, 0x2f, 0x22, 0xc3, 0xe5, 0x2c, 0x95, 0x2f, 0xff, 0xbf, 0x02, 0x07, 0x90, 0xff, -0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x2e, 0x65, 0x05, 0x2f, 0x74, 0x01, 0x25, 0x2b, 0xf5, 0x2b, -0xe4, 0x35, 0x2a, 0xf5, 0x2a, 0x80, 0xcc, 0x12, 0x31, 0xc1, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x12, -0x2e, 0x65, 0xaf, 0x2c, 0x22, 0x90, 0xff, 0xf1, 0xe5, 0x2e, 0xf0, 0x02, 0x31, 0xd8, 0x12, 0x10, -0x4b, 0x78, 0x84, 0x12, 0x23, 0x31, 0x30, 0xe1, 0x08, 0x7f, 0x13, 0x12, 0x31, 0xa9, 0x02, 0x27, -0xbc, 0x78, 0x84, 0xe6, 0xf9, 0x24, 0x13, 0x12, 0x22, 0xad, 0xe0, 0xff, 0x30, 0xe7, 0x40, 0x54, -0x03, 0x60, 0x1e, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x44, -0x04, 0xf0, 0x80, 0x46, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x80, -0x39, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x01, 0xf0, -0x80, 0x28, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1b, 0xef, -0x54, 0x03, 0x60, 0x14, 0xe9, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, -0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0xb3, 0x90, 0xf9, 0x18, 0xe0, 0x04, 0xf0, -0xaf, 0x01, 0x12, 0x22, 0xee, 0xfd, 0x12, 0x2f, 0xe5, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, 0x75, -0xa8, 0x40, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x8b, 0x02, 0x28, 0x09, 0x02, 0x31, -0x8c, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, -0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, -0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, -0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x2b, 0xa9, 0xe4, 0x7e, 0x01, 0x93, -0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, -0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, -0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, -0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xe4, 0xf5, -0x22, 0x12, 0x1d, 0xc2, 0xe0, 0xb4, 0x04, 0x0d, 0xe5, 0x22, 0x24, 0x03, 0xff, 0x12, 0x30, 0x13, -0x12, 0x1d, 0xc2, 0xe4, 0xf0, 0x05, 0x22, 0xe5, 0x22, 0xc3, 0x94, 0x02, 0x40, 0xe3, 0xe4, 0xf5, -0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x94, 0x12, 0x1e, 0x03, 0x60, 0x2c, 0x12, 0x2d, -0x85, 0xef, 0x60, 0x52, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x94, 0x12, 0x1b, 0xcc, 0xe4, -0xf0, 0xa3, 0xf0, 0x75, 0xf0, 0x0a, 0xe5, 0x22, 0x90, 0xfa, 0xa0, 0x12, 0x1b, 0xcc, 0xe0, 0xa3, -0x30, 0xe6, 0x33, 0x12, 0x1d, 0xc2, 0x74, 0x04, 0xf0, 0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, -0xfa, 0x98, 0x12, 0x1e, 0x03, 0x60, 0x16, 0x12, 0x2d, 0x85, 0xef, 0x60, 0x19, 0x75, 0xf0, 0x02, -0xe5, 0x22, 0x90, 0xfa, 0x98, 0x12, 0x1b, 0xcc, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x05, 0x22, 0xe5, -0x22, 0xc3, 0x94, 0x02, 0x40, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xfe, -0xef, 0xc3, 0x9e, 0x50, 0x17, 0x74, 0xf0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xe0, -0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x0f, 0x12, 0x1c, 0xb0, 0x80, 0xdd, 0xef, 0xfd, 0xc3, 0xe5, -0x3a, 0x9d, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 0xd3, 0xe5, 0x3a, 0x94, 0x00, 0xe5, -0x39, 0x94, 0x00, 0x40, 0x06, 0xe4, 0x90, 0xff, 0x83, 0xf0, 0x22, 0x12, 0x1d, 0xdf, 0x12, 0x1e, -0x34, 0x12, 0x1e, 0x26, 0x12, 0x1a, 0xa2, 0x24, 0x6e, 0x60, 0x1e, 0x14, 0x60, 0x1b, 0x24, 0x8e, -0x70, 0x2d, 0x90, 0x00, 0x01, 0x12, 0x1a, 0xbb, 0xff, 0x24, 0xfc, 0x60, 0x03, 0x04, 0x70, 0x1f, -0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0d, 0x02, 0x11, 0x5e, 0x12, 0x1e, 0x3b, 0x12, 0x25, 0xfa, 0x12, -0x1d, 0x89, 0x12, 0x1a, 0xbb, 0x60, 0x03, 0x02, 0x32, 0x7a, 0xe4, 0xff, 0x12, 0x32, 0x6e, 0x22, -0x8b, 0x45, 0x8a, 0x46, 0x89, 0x47, 0x8c, 0x48, 0x8d, 0x49, 0xd2, 0x00, 0x12, 0x2e, 0x53, 0x70, -0x16, 0x12, 0x2e, 0x72, 0xe5, 0x48, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0xd8, 0x50, 0xf2, 0x12, -0x29, 0xd5, 0x40, 0x0b, 0x7f, 0x18, 0x22, 0x12, 0x2e, 0x72, 0x12, 0x29, 0xd5, 0x50, 0xf8, 0xe4, -0xf5, 0x4b, 0xe5, 0x4a, 0x14, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, 0x17, 0x12, 0x29, 0xc5, 0x40, -0x03, 0x7f, 0x18, 0x22, 0x05, 0x4b, 0x74, 0x01, 0x25, 0x47, 0xf5, 0x47, 0xe4, 0x35, 0x46, 0xf5, -0x46, 0x80, 0xdf, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x29, 0xc5, 0x40, 0x03, 0x7f, -0x18, 0x22, 0x7f, 0x00, 0x22, 0xab, 0x45, 0xaa, 0x46, 0xa9, 0x47, 0x12, 0x1a, 0xa2, 0x90, 0xff, -0xf1, 0xf0, 0x02, 0x31, 0xd8, 0x90, 0xff, 0xf1, 0xe5, 0x49, 0xf0, 0x02, 0x31, 0xd8, 0x7b, 0x01, -0x7a, 0xfa, 0x79, 0xcf, 0xe4, 0xfd, 0x12, 0x23, 0x61, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x09, -0x12, 0x1b, 0x1c, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, -0x12, 0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xff, 0xf7, -0xe5, 0x23, 0x12, 0x2a, 0x39, 0x90, 0xff, 0xf6, 0xe5, 0x23, 0xf0, 0x90, 0xfa, 0xcf, 0xe4, 0xf0, -0xa3, 0x74, 0x06, 0x12, 0x2a, 0x39, 0xe5, 0x23, 0x30, 0xe0, 0x07, 0x90, 0xff, 0xfc, 0x74, 0x94, -0xf0, 0x22, 0x90, 0xff, 0xfc, 0x74, 0x90, 0xf0, 0x22, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, -0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, -0x01, 0x02, 0x26, 0x98, 0x90, 0xff, 0x93, 0x74, 0x81, 0xf0, 0x90, 0xff, 0xff, 0xe0, 0x60, 0x06, -0x90, 0xff, 0xfc, 0x74, 0x10, 0xf0, 0x90, 0xff, 0x91, 0xe0, 0x44, 0x90, 0xf0, 0xe4, 0x90, 0xf9, -0x16, 0xf0, 0xa3, 0xf0, 0x12, 0x2b, 0x39, 0x12, 0x16, 0xc9, 0x12, 0x30, 0x69, 0x7e, 0x07, 0x7f, -0xd0, 0x12, 0x12, 0x2a, 0x7e, 0x0f, 0x7f, 0xa0, 0x12, 0x12, 0x44, 0xe4, 0x78, 0x77, 0xf6, 0x78, -0x77, 0xe6, 0xff, 0xc3, 0x94, 0x06, 0x50, 0x0b, 0x74, 0x6e, 0x2f, 0xf8, 0xe4, 0xf6, 0x78, 0x77, -0x06, 0x80, 0xec, 0x7f, 0x03, 0x12, 0x30, 0xb2, 0x90, 0xf9, 0x16, 0xe0, 0x20, 0xe4, 0x05, 0x7f, -0x04, 0x12, 0x30, 0xb2, 0x90, 0xff, 0x9b, 0xe4, 0xf0, 0x90, 0xff, 0x9a, 0xf0, 0x90, 0xff, 0xe8, -0xe0, 0x54, 0x1f, 0xf0, 0xd2, 0xa8, 0x22, 0x15, 0x65, 0xa8, 0x65, 0xa6, 0x07, 0x30, 0x08, 0x05, -0x12, 0x11, 0xae, 0x80, 0xf8, 0xd2, 0x08, 0xa8, 0x65, 0xe6, 0xff, 0xb4, 0x03, 0x0f, 0x78, 0x7c, -0x76, 0xff, 0x08, 0x76, 0xe0, 0x08, 0x76, 0xff, 0x08, 0x76, 0xa0, 0x80, 0x0d, 0x78, 0x7c, 0x76, -0xff, 0x08, 0x76, 0xe2, 0x08, 0x76, 0xff, 0x08, 0x76, 0xb0, 0x78, 0x80, 0x76, 0xfa, 0x08, 0x76, -0x9e, 0xef, 0x24, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0xae, 0xf0, 0x12, 0x23, 0x49, 0x7b, 0x01, 0x7a, -0xff, 0x79, 0x48, 0x78, 0x68, 0x12, 0x1b, 0xe1, 0xa8, 0x65, 0xe6, 0x24, 0xfd, 0x75, 0xf0, 0x08, -0xa4, 0xff, 0xae, 0xf0, 0x78, 0x6a, 0x12, 0x23, 0x49, 0x79, 0x08, 0x78, 0x6b, 0x12, 0x1b, 0xe1, -0x78, 0x6d, 0xef, 0x12, 0x23, 0x49, 0x05, 0x65, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xab, 0xf0, -0xe0, 0x44, 0x20, 0xf0, 0x90, 0xfa, 0xe6, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcf, -0xe4, 0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x7e, 0x00, 0x90, 0xfa, 0xe4, 0xee, -0xf0, 0xa3, 0xef, 0xf0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcf, 0xe0, 0xb4, 0x52, 0x09, 0x90, -0xf9, 0x16, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x29, 0x90, 0xfa, 0xe4, 0xe0, 0x70, 0x04, 0xa3, 0xe0, -0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcf, 0xe0, 0xb4, 0x10, 0x09, 0x90, 0xf9, 0x16, 0xe0, 0x44, -0x10, 0xf0, 0x80, 0x0d, 0x90, 0xfa, 0xe6, 0x74, 0x03, 0xf0, 0x90, 0xf9, 0x16, 0xe0, 0x54, 0xef, -0xf0, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x03, 0x68, 0x01, 0xff, 0x48, 0x03, 0x6b, -0x01, 0xff, 0x08, 0x02, 0x66, 0x00, 0x00, 0x44, 0xfa, 0x98, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfa, -0x94, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfa, 0xb2, 0x00, 0x00, 0x42, 0xfa, 0x7e, 0x00, 0x00, 0x42, -0xfa, 0x7c, 0x00, 0x00, 0x42, 0xf9, 0x6d, 0xff, 0xff, 0x42, 0xfa, 0x7a, 0x00, 0x00, 0x41, 0xf9, -0x66, 0xff, 0x41, 0xf9, 0x1c, 0x19, 0x41, 0xf9, 0x15, 0x00, 0x43, 0xf9, 0x19, 0x0a, 0x32, 0x02, -0x41, 0xf9, 0x68, 0x20, 0x41, 0xf9, 0x69, 0x20, 0x41, 0xf9, 0x65, 0x00, 0x41, 0xf9, 0x67, 0x00, -0x44, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf9, 0x16, 0x00, 0x00, 0x41, 0xf9, 0x18, 0x00, -0x01, 0x20, 0x00, 0x41, 0xf8, 0x04, 0x00, 0x00, 0x12, 0x10, 0x4b, 0x78, 0x8a, 0xef, 0xf6, 0x12, -0x2a, 0xc7, 0x12, 0x22, 0xee, 0x30, 0xe0, 0x29, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x54, 0x7f, -0xf0, 0x78, 0x6b, 0x12, 0x1b, 0xd8, 0x90, 0x00, 0x02, 0x12, 0x1a, 0xbb, 0x30, 0xe7, 0x09, 0x90, -0x00, 0x02, 0xe4, 0x12, 0x1a, 0xfa, 0x80, 0xe9, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x44, 0x80, -0xf0, 0x12, 0x22, 0xee, 0x30, 0xe1, 0x1e, 0x12, 0x22, 0x97, 0xe0, 0x54, 0x7f, 0xf0, 0x12, 0x32, -0x19, 0x78, 0x68, 0x12, 0x1b, 0xd8, 0x90, 0x00, 0x02, 0x74, 0x80, 0x12, 0x1a, 0xfa, 0x12, 0x22, -0x97, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x32, 0x84, 0xe4, 0xff, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, -0x12, 0x10, 0x4b, 0x78, 0x85, 0xef, 0xf6, 0x12, 0x31, 0x50, 0x12, 0x31, 0xa9, 0x78, 0x85, 0xe6, -0xff, 0x24, 0x13, 0x12, 0x22, 0xad, 0xe0, 0xfe, 0x30, 0xe7, 0x16, 0xef, 0xb4, 0x03, 0x09, 0x90, -0xff, 0x9e, 0xe0, 0x54, 0xfa, 0xf0, 0x80, 0x22, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf5, 0xf0, 0x80, -0x19, 0xee, 0x54, 0x03, 0x60, 0x14, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, -0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xf9, 0x18, 0xe0, 0x14, 0xf0, -0xe0, 0x70, 0x02, 0xd2, 0xb3, 0x02, 0x10, 0xce, 0x12, 0x1e, 0x1c, 0xe5, 0x3a, 0x64, 0x09, 0x70, -0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x48, 0xc3, 0xe5, 0x3a, 0x94, 0x08, 0xe5, 0x39, 0x94, 0x00, -0x40, 0x11, 0x7f, 0x08, 0xef, 0xe5, 0x3a, 0x94, 0x08, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, -0x39, 0x80, 0x05, 0xaf, 0x3a, 0x12, 0x1e, 0x34, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x19, 0x12, -0x1c, 0xc1, 0x12, 0x1a, 0xa2, 0xfd, 0x74, 0xf8, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, -0xed, 0xf0, 0x0e, 0x12, 0x1c, 0xb0, 0x80, 0xe2, 0xef, 0x54, 0x7f, 0x90, 0xff, 0x81, 0xf0, 0x22, -0x8b, 0x59, 0x8a, 0x5a, 0x89, 0x5b, 0x12, 0x2e, 0x19, 0x70, 0x05, 0xa3, 0x74, 0x08, 0xf0, 0x22, -0xab, 0x59, 0xaa, 0x5a, 0xa9, 0x5b, 0x12, 0x2e, 0x0d, 0x90, 0xfa, 0xc9, 0x12, 0x1b, 0xf3, 0xe5, -0x5b, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x5a, 0xfa, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0xf3, 0xe4, 0x90, -0xfa, 0xc2, 0xf0, 0x78, 0x8b, 0xf6, 0x90, 0xfa, 0xc1, 0xe0, 0xff, 0x78, 0x8b, 0xe6, 0xc3, 0x9f, -0x50, 0x12, 0x12, 0x2d, 0xeb, 0xff, 0x12, 0x2d, 0xf4, 0x12, 0x2e, 0x07, 0x78, 0x8b, 0x06, 0x12, -0x2e, 0x03, 0x80, 0xe2, 0x22, 0xad, 0x07, 0xac, 0x06, 0x90, 0x32, 0x0a, 0xe4, 0x93, 0xff, 0x78, -0x74, 0xf6, 0x54, 0x0f, 0x12, 0x1d, 0xa8, 0xe0, 0x08, 0x76, 0x00, 0x08, 0xf6, 0x18, 0x12, 0x1c, -0xd9, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x78, 0x75, 0xee, 0xf6, 0x08, 0xef, 0xf6, -0xee, 0x44, 0xf8, 0x18, 0xf6, 0xef, 0x08, 0xf6, 0x90, 0xff, 0x7a, 0xe0, 0x20, 0xe7, 0x03, 0x7f, -0x00, 0x22, 0x78, 0x75, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0xec, 0xf0, 0xa3, 0xed, -0xf0, 0x90, 0xff, 0x7a, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, -0x90, 0x00, 0x03, 0x12, 0x1a, 0xbb, 0x54, 0xf0, 0x24, 0xa0, 0x22, 0x90, 0xfa, 0xc9, 0x12, 0x1b, -0xea, 0x02, 0x1a, 0xa2, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0xea, 0xef, 0x12, 0x1a, 0xe8, 0x90, 0xfa, -0xca, 0xe4, 0x22, 0x90, 0xfa, 0xc4, 0xe4, 0x75, 0xf0, 0x01, 0x02, 0x1b, 0x1c, 0x90, 0x00, 0x08, -0x12, 0x1b, 0x48, 0xaa, 0xf0, 0xf9, 0x7b, 0x01, 0x22, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, 0x90, -0xfa, 0xc1, 0xf0, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x22, 0x90, 0xfa, 0xdd, 0xe0, 0xff, -0x7e, 0x00, 0xc3, 0x90, 0xfa, 0xd7, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xd6, 0xe0, 0x9e, 0xf0, 0x90, -0xfa, 0xd8, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0xef, 0x25, 0x51, 0xf5, 0x51, 0xee, 0x35, 0x50, -0xf5, 0x50, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0xfa, -0xe6, 0xe0, 0x64, 0x03, 0x22, 0x90, 0xff, 0xf2, 0xe0, 0xab, 0x29, 0xaa, 0x2a, 0xa9, 0x2b, 0x02, -0x1a, 0xe8, 0x90, 0xff, 0xf3, 0x74, 0xa0, 0xf0, 0x22, 0x8f, 0x64, 0xed, 0x70, 0x0f, 0xe5, 0x64, -0xb4, 0x03, 0x05, 0x7f, 0x01, 0x02, 0x31, 0xef, 0x7f, 0x02, 0x02, 0x31, 0xef, 0xaf, 0x64, 0x12, -0x2a, 0xc7, 0x74, 0x6e, 0x25, 0x64, 0xf8, 0xe6, 0x30, 0xe2, 0x0b, 0xd2, 0x09, 0x12, 0x1d, 0x33, -0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x02, 0xc2, 0x09, 0xe5, 0x64, 0xb4, 0x03, 0x07, 0x7f, 0x81, 0x12, -0x31, 0xef, 0x80, 0x05, 0x7f, 0x82, 0x12, 0x31, 0xef, 0x30, 0x09, 0x07, 0x12, 0x1d, 0x33, 0xe0, -0x44, 0x80, 0xf0, 0x12, 0x32, 0x84, 0x22, 0x12, 0x10, 0x4b, 0x90, 0xff, 0xfd, 0xe0, 0x44, 0x60, -0xf0, 0xd2, 0x01, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0x00, 0xe0, 0x30, 0xe7, -0x13, 0x90, 0xff, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x35, 0x80, 0x90, 0xff, 0xfc, 0xe0, 0x44, -0x01, 0xf0, 0x80, 0x0d, 0x12, 0x1d, 0xdf, 0x53, 0x35, 0x7f, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0xfe, -0xf0, 0x90, 0xff, 0x81, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x02, 0xde, 0x12, 0x1d, 0xe7, 0x02, 0x10, -0xce, 0x12, 0x10, 0x4b, 0x78, 0x89, 0xef, 0xf6, 0xd2, 0x00, 0x12, 0x2a, 0xc7, 0x90, 0xf9, 0x6a, -0x12, 0x1b, 0xea, 0xe9, 0x24, 0x03, 0xf9, 0xe4, 0x3a, 0xfa, 0xc0, 0x02, 0x78, 0x80, 0xe6, 0xfe, -0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0xd0, 0x02, 0x12, 0x22, 0xd3, 0x12, 0x32, -0x84, 0x78, 0x89, 0xe6, 0xff, 0x12, 0x13, 0x87, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, 0x8f, 0x63, -0x12, 0x2a, 0xc7, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x54, 0x3f, 0xf0, 0xe5, 0x82, 0x24, 0x04, -0x12, 0x22, 0xa1, 0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x23, 0x41, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, -0x54, 0xf8, 0xf0, 0x12, 0x32, 0x84, 0x74, 0x6e, 0x25, 0x63, 0xf8, 0x74, 0xfb, 0x56, 0xf6, 0x7f, -0x00, 0x22, 0x12, 0x10, 0x4b, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xfa, 0x24, 0x06, 0x12, 0x22, 0x9f, -0xe0, 0xfd, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x03, 0x12, 0x23, 0x02, 0x24, 0x05, 0x12, 0x22, 0xa1, -0xe0, 0x90, 0x00, 0x04, 0x12, 0x1a, 0xfa, 0x12, 0x32, 0x84, 0x7d, 0x02, 0xe4, 0xff, 0x12, 0x2f, -0xb4, 0x02, 0x10, 0xce, 0xae, 0x05, 0x12, 0x1d, 0x8e, 0xef, 0x12, 0x1a, 0xfa, 0x0e, 0x0e, 0x0e, -0xee, 0xd3, 0x95, 0x3c, 0xe4, 0x95, 0x3b, 0x40, 0x02, 0xae, 0x3c, 0xee, 0xd3, 0x94, 0x08, 0x74, -0x80, 0x94, 0x81, 0x40, 0x0a, 0x7e, 0x03, 0x90, 0x00, 0x02, 0x74, 0x02, 0x12, 0x1a, 0xfa, 0xaf, -0x06, 0x12, 0x32, 0x6e, 0x22, 0xae, 0x07, 0xed, 0x54, 0x03, 0x64, 0x01, 0x60, 0x03, 0x7f, 0x10, -0x22, 0xed, 0x54, 0x7c, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x7f, 0x0b, 0x22, 0x74, 0x6e, 0x2e, 0xf8, -0x74, 0x02, 0x46, 0xf6, 0x74, 0x99, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0xed, 0xf0, -0x7f, 0x00, 0x22, 0xbf, 0x03, 0x06, 0x7c, 0xff, 0x7d, 0xe0, 0x80, 0x04, 0x7c, 0xff, 0x7d, 0xe2, -0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, -0x44, 0x80, 0xf0, 0x74, 0x6e, 0x2f, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, 0x12, 0x10, -0x4b, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x16, 0x90, 0xff, 0x83, -0xe0, 0x54, 0x0f, 0xff, 0xc3, 0xe5, 0x3a, 0x9f, 0xe5, 0x39, 0x94, 0x00, 0x40, 0x05, 0x12, 0x28, -0xd7, 0x80, 0x03, 0x12, 0x32, 0x7a, 0x02, 0x10, 0xce, 0x90, 0xff, 0xfc, 0xe0, 0x20, 0xe7, 0x1f, -0xc2, 0xaf, 0x7d, 0xff, 0xac, 0x05, 0x1d, 0xec, 0x60, 0x15, 0x7e, 0x04, 0x7f, 0x00, 0xef, 0x1f, -0xaa, 0x06, 0x70, 0x01, 0x1e, 0x4a, 0x60, 0xec, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0x80, 0xef, 0x22, -0x12, 0x10, 0x4b, 0x78, 0x66, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x30, 0xe0, 0x12, 0x30, 0xe1, 0x0f, -0x90, 0xff, 0xfc, 0xe0, 0x44, 0x20, 0xf0, 0x7f, 0x04, 0x12, 0x12, 0x61, 0x12, 0x1d, 0xf6, 0x02, -0x10, 0xce, 0x8f, 0x23, 0xc2, 0x08, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xc0, 0x78, 0x7e, 0x12, 0x23, -0x42, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x32, 0x84, 0xaf, 0x23, 0x12, -0x13, 0x87, 0x22, 0x8e, 0x5f, 0x8f, 0x60, 0xe5, 0x60, 0x15, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x15, -0x5f, 0xd3, 0x94, 0x00, 0xee, 0x94, 0x00, 0x40, 0x09, 0x7e, 0x07, 0x7f, 0xd0, 0x12, 0x10, 0x24, -0x80, 0xe5, 0x22, 0x11, 0xdc, 0x2e, 0xc7, 0x24, 0xb0, 0x32, 0x60, 0x30, 0x90, 0x30, 0x3e, 0x31, -0x6f, 0x2f, 0x82, 0x27, 0x2e, 0x2c, 0x80, 0x31, 0x12, 0x31, 0x31, 0x1e, 0x64, 0x2f, 0x11, 0x2c, -0x18, 0x0e, 0x12, 0x10, 0x4b, 0x78, 0x86, 0x12, 0x23, 0x31, 0x20, 0xe1, 0x07, 0x7f, 0x12, 0x12, -0x31, 0xa9, 0x80, 0x0a, 0x78, 0x86, 0xe6, 0xff, 0x12, 0x24, 0x0a, 0x12, 0x31, 0xa9, 0x02, 0x10, -0xce, 0x12, 0x10, 0x4b, 0x78, 0x87, 0x12, 0x23, 0x31, 0x20, 0xe2, 0x07, 0x7f, 0x11, 0x12, 0x31, -0xa9, 0x80, 0x0a, 0x78, 0x87, 0xe6, 0xff, 0x12, 0x2f, 0x4e, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, -0x8f, 0x61, 0x12, 0x2f, 0x4e, 0xaf, 0x61, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xc0, 0x12, 0x32, 0x84, -0x74, 0x6e, 0x25, 0x61, 0xf8, 0x74, 0xfd, 0x56, 0xf6, 0xaf, 0x61, 0x12, 0x13, 0x87, 0x22, 0x12, -0x10, 0x4b, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x05, 0x12, 0x2c, -0xd8, 0x80, 0x06, 0x12, 0x1e, 0x14, 0x12, 0x1e, 0x1c, 0x02, 0x10, 0xce, 0x12, 0x2a, 0x54, 0x12, -0x13, 0x03, 0x90, 0xf8, 0x04, 0xe0, 0xff, 0x60, 0x05, 0x7d, 0x01, 0x12, 0x12, 0xa0, 0x12, 0x29, -0xde, 0x12, 0x13, 0x3f, 0x12, 0x11, 0xbc, 0x80, 0xe3, 0x12, 0x1d, 0x8e, 0xef, 0x12, 0x1a, 0xfa, -0xe4, 0xf5, 0x33, 0xf5, 0x34, 0xef, 0x60, 0x03, 0x02, 0x32, 0x7a, 0xe4, 0xff, 0x12, 0x32, 0x6e, -0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0xa0, 0x60, 0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, -0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0x28, 0x60, -0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0xef, -0x30, 0xe7, 0x08, 0x12, 0x1d, 0x45, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0xef, 0x12, 0x1d, 0x98, 0xe0, -0x54, 0xdf, 0xf0, 0x22, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03, 0x87, 0x40, 0x00, 0x40, 0x00, 0x40, -0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x08, 0x00, 0x78, 0x7e, 0x12, 0x22, 0xb7, 0xa3, 0xa3, -0xe0, 0xff, 0x30, 0xe7, 0x06, 0x54, 0x7f, 0xf0, 0x44, 0x80, 0xf0, 0x22, 0x85, 0x3b, 0x39, 0x85, -0x3c, 0x3a, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7, 0xf0, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0x22, 0xe4, -0xfe, 0xee, 0x90, 0x32, 0x04, 0x93, 0xb5, 0x07, 0x02, 0xd3, 0x22, 0x0e, 0xbe, 0x07, 0xf2, 0xc3, -0x22, 0x00, 0x08, 0x18, 0x28, 0x38, 0x01, 0x81, 0x90, 0x0a, 0x02, 0x00, 0x00, 0x11, 0x13, 0x00, -0x12, 0x10, 0x4b, 0x7f, 0x02, 0x12, 0x10, 0xda, 0x12, 0x1d, 0xf6, 0x02, 0x10, 0xce, 0x75, 0x39, -0x00, 0x8f, 0x3a, 0x12, 0x1c, 0xe0, 0x12, 0x2c, 0xd8, 0x22, 0x12, 0x1e, 0x1c, 0x12, 0x1d, 0xdf, -0x12, 0x1e, 0x14, 0x22, 0xc2, 0x08, 0x22, -}; - -#undef IMAGE_VERSION_NAME - -#undef IMAGE_ARRAY_NAME - diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 05e4fa7..61daea3 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -52,13 +53,6 @@ #define DRIVER_AUTHOR "Greg Kroah-Hartman and David Iacovelli" #define DRIVER_DESC "Edgeport USB Serial Driver" - -/* firmware image code */ -#define IMAGE_VERSION_NAME PagableOperationalCodeImageVersion -#define IMAGE_ARRAY_NAME PagableOperationalCodeImage -#define IMAGE_SIZE PagableOperationalCodeSize -#include "io_fw_down3.h" /* Define array OperationalCodeImage[] */ - #define EPROM_PAGE_SIZE 64 @@ -231,7 +225,9 @@ static struct usb_driver io_driver = { }; -static struct EDGE_FIRMWARE_VERSION_INFO OperationalCodeImageVersion; +static unsigned char OperationalMajorVersion; +static unsigned char OperationalMinorVersion; +static unsigned short OperationalBuildNumber; static int debug; @@ -885,10 +881,13 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev) __u8 *buffer; int buffer_size; int i; + int err; __u8 cs = 0; struct ti_i2c_desc *i2c_header; struct ti_i2c_image_header *img_header; struct ti_i2c_firmware_rec *firmware_rec; + const struct firmware *fw; + const char *fw_name = "edgeport/down3.bin"; // In order to update the I2C firmware we must change the type 2 record to type 0xF2. // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver @@ -909,19 +908,34 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev) // Set entire image of 0xffs memset (buffer, 0xff, buffer_size); + err = request_firmware(&fw, fw_name, dev); + if (err) { + printk(KERN_ERR "Failed to load image \"%s\" err %d\n", + fw_name, err); + kfree(buffer); + return err; + } + + /* Save Download Version Number */ + OperationalMajorVersion = fw->data[0]; + OperationalMinorVersion = fw->data[1]; + OperationalBuildNumber = fw->data[2] | (fw->data[3] << 8); + // Copy version number into firmware record firmware_rec = (struct ti_i2c_firmware_rec *)buffer; - firmware_rec->Ver_Major = OperationalCodeImageVersion.MajorVersion; - firmware_rec->Ver_Minor = OperationalCodeImageVersion.MinorVersion; + firmware_rec->Ver_Major = OperationalMajorVersion; + firmware_rec->Ver_Minor = OperationalMinorVersion; // Pointer to fw_down memory image - img_header = (struct ti_i2c_image_header *)&PagableOperationalCodeImage[0]; + img_header = (struct ti_i2c_image_header *)&fw->data[4]; memcpy (buffer + sizeof(struct ti_i2c_firmware_rec), - &PagableOperationalCodeImage[sizeof(struct ti_i2c_image_header)], + &fw->data[4 + sizeof(struct ti_i2c_image_header)], le16_to_cpu(img_header->Length)); + release_firmware(fw); + for (i=0; i < buffer_size; i++) { cs = (__u8)(cs + buffer[i]); } @@ -935,8 +949,8 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev) i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK; i2c_header->Size = (__u16)buffer_size; i2c_header->CheckSum = cs; - firmware_rec->Ver_Major = OperationalCodeImageVersion.MajorVersion; - firmware_rec->Ver_Minor = OperationalCodeImageVersion.MinorVersion; + firmware_rec->Ver_Major = OperationalMajorVersion; + firmware_rec->Ver_Minor = OperationalMinorVersion; return 0; } @@ -1075,11 +1089,6 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Otherwise we will remain in configuring mode serial->product_info.TiMode = TI_MODE_CONFIGURING; - // Save Download Version Number - OperationalCodeImageVersion.MajorVersion = PagableOperationalCodeImageVersion.MajorVersion; - OperationalCodeImageVersion.MinorVersion = PagableOperationalCodeImageVersion.MinorVersion; - OperationalCodeImageVersion.BuildNumber = PagableOperationalCodeImageVersion.BuildNumber; - /********************************************************************/ /* Download Mode */ /********************************************************************/ @@ -1154,15 +1163,15 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Check version number of download with current version in I2c download_cur_ver = (firmware_version->Ver_Major << 8) + (firmware_version->Ver_Minor); - download_new_ver = (OperationalCodeImageVersion.MajorVersion << 8) + - (OperationalCodeImageVersion.MinorVersion); + download_new_ver = (OperationalMajorVersion << 8) + + (OperationalMinorVersion); dbg ("%s - >>>Firmware Versions Device %d.%d Driver %d.%d", __func__, firmware_version->Ver_Major, firmware_version->Ver_Minor, - OperationalCodeImageVersion.MajorVersion, - OperationalCodeImageVersion.MinorVersion); + OperationalMajorVersion, + OperationalMinorVersion); // Check if we have an old version in the I2C and update if necessary if (download_cur_ver != download_new_ver) { @@ -1170,8 +1179,8 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) __func__, firmware_version->Ver_Major, firmware_version->Ver_Minor, - OperationalCodeImageVersion.MajorVersion, - OperationalCodeImageVersion.MinorVersion); + OperationalMajorVersion, + OperationalMinorVersion); // In order to update the I2C firmware we must change the type 2 record to type 0xF2. // This will force the UMP to come up in Boot Mode. Then while in boot mode, the driver @@ -1377,6 +1386,9 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) __u8 cs = 0; __u8 *buffer; int buffer_size; + int err; + const struct firmware *fw; + const char *fw_name = "edgeport/down3.bin"; /* Validate Hardware version number * Read Manufacturing Descriptor from TI Based Edgeport @@ -1425,7 +1437,15 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) // Initialize the buffer to 0xff (pad the buffer) memset (buffer, 0xff, buffer_size); - memcpy (buffer, &PagableOperationalCodeImage[0], PagableOperationalCodeSize); + err = request_firmware(&fw, fw_name, dev); + if (err) { + printk(KERN_ERR "Failed to load image \"%s\" err %d\n", + fw_name, err); + kfree(buffer); + return err; + } + memcpy(buffer, &fw->data[4], fw->size - 4); + release_firmware(fw); for(i = sizeof(struct ti_i2c_image_header); i < buffer_size; i++) { cs = (__u8)(cs + buffer[i]); @@ -3119,6 +3139,7 @@ module_exit(edgeport_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("edgeport/down3.bin"); module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/firmware/Makefile b/firmware/Makefile index be3a9e9..a162b29 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -61,6 +61,7 @@ endif fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \ edgeport/down.fw edgeport/down2.fw +fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += edgeport/down3.bin fw-shipped-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat_loader.fw whiteheat.fw \ # whiteheat_loader_debug.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw diff --git a/firmware/WHENCE b/firmware/WHENCE index 8eada2d..79e62e2 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -293,3 +293,19 @@ Licence: Allegedly GPLv2+, but no source visible. Marked: Found in hex form in kernel source. -------------------------------------------------------------------------- + +Driver: USB_SERIAL_EDGEPORT_TI - USB Inside Out Edgeport Serial Driver +(TI Devices) + +File: edgeport/down3.bin + +Licence: +//************************************************************** +//* Edgeport Binary Image (for TI based products) +//* Generated by TIBin2C v2.00 (watchport) +//* Copyright (C) 2001 Inside Out Networks, All rights reserved. +//************************************************************** + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/edgeport/down3.bin.ihex b/firmware/edgeport/down3.bin.ihex new file mode 100644 index 0000000..7935e52 --- /dev/null +++ b/firmware/edgeport/down3.bin.ihex @@ -0,0 +1,815 @@ +:100000000450000087329A0227BF0221B20000008C +:10001000000002001E0000000000000000000000C0 +:10002000000002011A853F8C85408AC0E0C0D0C024 +:10003000F0C082C083C000C001C002C003C004C0C1 +:1000400005C006C007E53E2408F8E6602BE53E241F +:1000500010F8A681E53E75F021A42405F582E4346C +:10006000F8F583788CE58104C398F9942240030263 +:1000700011DCE6F008A3D9FA7408253EF8053E081D +:10008000E65480700CE53EB407F37808753E0080B6 +:10009000EFE53E2410F88681E53E75F021A42405A5 +:1000A000F582E434F8F583788CE58104C398F9E0AF +:1000B000F608A3D9FAD007D006D005D004D003D0D3 +:1000C00002D001D000D083D082D0F0D0D0D0E032A6 +:1000D00030014D30B44810004590FF08E05420F83E +:1000E00090FF48E05420F990FF10E05420FA90FF70 +:1000F00050E05420FB7400F58274F8F583E0C8F0FA +:100100006860027E04A3E0C9F06960027E04A3E097 +:10011000CAF06A60027E04A3E0CBF06B60027E044A +:1001200022C0E0C0D0C0F0C082C083C000C001C007 +:1001300002C003C004C005C006C0077415F5827470 +:10014000F9F583E060237466F58274F9F583E014B1 +:10015000F0701674FFF0741CF58274F9F583E0609A +:100160000414F07004C29080FC90FF937481F0E559 +:100170008194FD40030211DC85418D85428B74B270 +:10018000F58274FAF583E0B4011BC082C08390FF4E +:100190004AE030E72C90FF4EE030E725D083D08254 +:1001A0007402F08020B4021DC082C08390FF7AE008 +:1001B00030E70512284E8009D083D0827403F08086 +:1001C00004D083D082A3E0B4011BC082C08390FF1F +:1001D00052E030E72C90FF56E030E725D083D08204 +:1001E0007402F08025B40222C082C08390FF7AE0BE +:1001F00030E70512284E8009D083D0827403F08046 +:1002000009D083D08280030202907416F58274F9BB +:10021000F583E02004F12002033001EB7419F5822C +:1002200074F9F583E014FCF0A3E0FDA3E0FE6404A0 +:10023000700FEC70627E011200C97C0A7DFA020226 +:10024000611200C9EE6404601DEC704B7C0AED1471 +:10025000FD7015EE640260077E027D320202617E4F +:10026000017DFA0202617C0A7419F58274F9F58342 +:10027000ECF0A3EDF0A3EEF014601820E10F2001E4 +:1002800006D2B1C2B08010C2B1D2B0800AC2B1C22F +:10029000B08004D2B0D2B1781979097A07E7700436 +:1002A000A600800BE6600816E67004E74480F708B5 +:1002B00009DAEAE53D601314F53D700EE53E2408C9 +:1002C000F87600121157D28CD28DD007D006D00507 +:1002D000D004D003D002D001D000D083D082D0F09F +:1002E000D0D0D0E03290FF04E090FAB9F090FF0651 +:1002F000E0FCA3E0FAECFFEAFEEFC39408EE940101 +:10030000500280047E017F088E3B8F3C90FF02E00C +:10031000FCA3E0FAECFFEA90FABDF0EFA3F0121CA8 +:10032000E0E4F54DE54DC39402500F121CC1E412F8 +:100330001AE8054D04121CB280EA121CE090FF007E +:10034000E0FF546024C070030208F32440600302FD +:100350000F6E90FAB9E0FE540FF54DEE30E703D37F +:100360008001C3920A90FF01E0121BFC0384000489 +:100370005701056A0306310506730607D508081DEF +:100380000908790A08B90B00000F6EE53520E7036C +:10039000020F6E90FABDE07002A3E06003020F6EE0 +:1003A000E53C6402453B6003020F6EEF541F14608E +:1003B0002B14604724026003020F6EEE6003020FED +:1003C0006E121CC17401121AE87867E630E0081258 +:1003D0001CC17402121AE87F0202326EE53520E178 +:1003E0000990FAB9E06003020F6E90FAB9E0D39475 +:1003F000014003020F6E7F0202326EE53520E10EEE +:1004000090FAB9E0FF600764806003020F6E120F7C +:10041000FA4003020F6EE54D7019300A0B90FF8011 +:10042000121CBE121AE8802490FF82121CBE121AFF +:10043000E88019154D300A0B121D55121CBC121AFA +:10044000E88009121D63121CBC121AE8121CC112AA +:100450001AA260057401121AE87F0202326EE535B5 +:1004600030E703020F6EE53C453B6003020F6E125E +:100470001D7914602D14605924026003020F6E90E0 +:10048000FABDE07004A3E064016003020F6E90FA0D +:10049000B9E06003020F6E7867E654FEF6E4FF02EF +:1004A000326EE53520E10620E003020F6EE53530BF +:1004B000E00990FAB9E06003020F6EE53530E10C17 +:1004C00090FAB9E0D394014003020F6EE4FF0232C8 +:1004D0006E90FABDE07002A3E06003020F6E120F8F +:1004E000FA4003020F6EE53520E10620E003020F1B +:1004F0006EE53530E007E54D6003020F6EE54D70A7 +:100500000F90FF82E054F7F090FF80E054F7F02264 +:10051000E54D24FE602024FB603424067035300A4B +:100520000CA20AE433FD7F03122E798026E4FD7FBE +:1005300003122E79801D300A0CA20AE433FD7F04D9 +:10054000122E79800EE4FD7F04122E7980057F87BC +:100550001231EF154D300A0B121D55F583E054F79B +:10056000F08009121D63F583E054F7F0E4FF0232D6 +:100570006EE53530E703020F6EE53C453B60030254 +:100580000F6E121D7914602D146055240260030251 +:100590000F6E90FABDE07004A3E064016003020FE7 +:1005A0006E90FAB9E06003020F6E7867E64401F6D8 +:1005B000E4FF02326EE53520E10620E003020F6E13 +:1005C000E53530E007E54D6003020F6EE53530E1BB +:1005D0000AE54DD394014003020F6EE4FF02326E30 +:1005E00090FABDE07002A3E06003020F6E90FAB9CA +:1005F000E0FF12323F4003020F6EE53520E1062096 +:10060000E003020F6EE54D7009300A03021E14026A +:100610001DDFE53520E103020F6E154D300A0B1288 +:100620001D55F583E04408F08009121D63F583E051 +:100630004408F0E4FF02326EE53530E703020F6E46 +:10064000E53C453B6003020F6E90FAB9E06003029F +:100650000F6E121D796003020F6EE53530E1030263 +:100660000F6E90FABEE090FFFFF0E06005433501A9 +:1006700080035335FEE4FF02326EE53520E70302C6 +:100680000F6EE53C453B7003020F6E121D7960034F +:10069000020F6E90FABDE0FCA3E0FDEC24FE603A90 +:1006A00014607524026003020F6EED6003020F6E8A +:1006B000121CE0121E0D7D03120FB56003020F6EB7 +:1006C000120F7290FAB6E0FDA3121D2B120FD1503B +:1006D000028004AE3BAF3C021002121CE090F916FF +:1006E000E030E40D121E0D7D14120FB56010020FE4 +:1006F0006E121E0D7D041210096003020F6E120FA0 +:100700007290FAB6E0FDA3121D2B120FD150028099 +:1007100004AE3BAF3C021002121E0D7D0512100903 +:100720006003020F6E7B017AFA79B6121D287D01F3 +:1007300012269890FAB7E475F003121B1C90FABECB +:10074000E090FAB5F0E4F54C90FAB5E0FFE54CC363 +:100750009F5024121D22121014FFFD90FAB7E48D51 +:10076000F0121B1C90FAB6E0C39FF0D39400500324 +:10077000020F6E054C80D1121D2212101424FEFFB0 +:1007800090FAB6F0FDA3E475F002121B1C7AF97919 +:10079000727B018B368A378938E92402F9E43AFA08 +:1007A000121D281226988F4C054C054C121CC1E5D1 +:1007B0004C121AE8121CC19000017403121AFAAF0D +:1007C0004C7E00C3EF953CEE953B50028004AE3B5F +:1007D000AF3C8E398F3A022CD8020F6EE53520E7F8 +:1007E00003020F6EE53C6401453B6003020F6E900F +:1007F000FAB9E06003020F6E90FABDE07002A3E068 +:100800006003020F6E121D796003020F6EE5352042 +:10081000E00620E103020F6E75360075370075386B +:1008200032020FF1E53530E703020F6EE53C453B40 +:100830006003020F6E90FAB9E06003020F6ED3906E +:10084000FABEE0940190FABDE094004003020F6EFE +:10085000121D796003020F6EE53520E00620E103EA +:10086000020F6E90FABEE0F532E5327008433501B2 +:100870005335FD80065335FE433502E4FF02326EE8 +:10088000E53520E703020F6EE53C6401453B60035C +:10089000020F6E90FAB9E06003020F6E90FABDE0AD +:1008A0007002A3E06003020F6E121D796401600301 +:1008B000020F6EE53520E103020F6E7F0102326EFA +:1008C000E53530E703020F6EE53C453B6003020F60 +:1008D0006ED390FABEE0940090FABDE0940040031D +:1008E000020F6E121D7964016003020F6EE5352060 +:1008F000E103020F6EE4FF02326E90FF01121E242C +:10090000EF121AE890FAB9121E24900001EF121AA1 +:10091000FA900002E4121AFA7403121CB290FABDA3 +:10092000E0FFA3E0853882853783CFF0A3EFF09016 +:10093000FF01E0121BFC097B02099D0409BF0509A8 +:10094000EB060A09070A27080A45090A630B0B1870 +:10095000800DB7810DE8820B5F830BA8840BC785E0 +:100960000C0C860C57870CE8880D73890A81920A53 +:1009700081930DA0B00E9BC00EC7C10ED8C200005F +:100980000F5DE53520E7057F050231A9121D716075 +:1009900003047009EFFD7C007F0702115EE4FD7F18 +:1009A00007022FB4E53520E7057F050231A9121DA6 +:1009B000716003047009EFFD7C007F0C02115EE49E +:1009C000FD7F07022FB4E53530E703020F71121ED9 +:1009D000425006E53C453B70057F020231A990FA82 +:1009E000B9E024FE24FD5002800302322C7F07026E +:1009F00031A9E53530E703020F71121D7160030460 +:100A00007009EFFD7C007F0802115E7F070231A9AB +:100A1000E53530E703020F71121D716003047009A0 +:100A2000EFFD7C007F0902115E7F070231A9E535E9 +:100A300030E703020F71121D716003047009EFFDAE +:100A40007C007F0A02115E7F070231A9E53530E79D +:100A500003020F71121D716003047009EFFD7C0029 +:100A60007F0B02115E7F070231A9E53530E70302F3 +:100A70000F71121D716003047009EFFD7C007F0E81 +:100A800002115E7F070231A9E53530E756121D7964 +:100A9000704A90FF02E0F54CE54CB48205754C615C +:100AA0008012E54CB48305754C628008E54CC45453 +:100AB000F004F54C121C22121E3B1225FA121D895D +:100AC000121ABB600512327A800685333985343AB2 +:100AD0007536017537F9753875022CD8E4FD7F0538 +:100AE000022FB4121D7960057F050231A9121E4242 +:100AF00040057F030231A990FF02E0F54CE54CB4BC +:100B00008205754C618012E54CB48305754C62809A +:100B100008E54CC454F004F54C121C2202322C128D +:100B20001E4C122AC7121D33E0547FF0000000E073 +:100B300090FABAF07868121BD8900002121ABB30F3 +:100B4000E7F2900002E4121AFA90FABAE04480FF49 +:100B5000F0787CE6FC08E68C83121D3BEFF0123245 +:100B600084E4FF0231A990FAB9E06401701F90FAA1 +:100B7000BDE0FF7E007006A3E0F590802DC2AFEFD0 +:100B8000F4529090FABEE04290D2AF801D90FABD30 +:100B9000E0FF7E007006A3E0F5B0800EC2AFEFF478 +:100BA00052B090FABEE042B0D2AFE4FF0231A912D7 +:100BB0001CE090FAB9E0B4010A121CC1E590121AC7 +:100BC000E88008121CC1E5B0121AE8020FF190FA91 +:100BD000B9E0FF2413121CF120E133121D80EF2431 +:100BE000FC601804702890FABAE0600990FFA4E055 +:100BF0004410F08019121E56F0801390FABAE0608B +:100C00000990FFB4E04410F08004121E5DF0E4FF90 +:100C10000231A990FAB9E0FF2413121CF120E13946 +:100C2000121D80EF24FC601B04702E90FABAE06065 +:100C30000990FFA4E04420F0801F90FFA4E054DF5F +:100C4000F0801690FABAE0600990FFB4E04420F01A +:100C5000800790FFB4E054DFF0E4FF0231A9121DD9 +:100C600080121D71604D046003020CE390FABAE03B +:100C7000600F90FFA4121CEA30E16F121E2C020CD0 +:100C8000E390FFA4E054FB121CEDFE30E15C30E287 +:100C90001130B405121E2C805190FFA4E054FDF0D9 +:100CA0008048309505121E2C804090FFA4E054FD32 +:100CB000F0803790FABAE0601290FFB4121CEA306C +:100CC000E12890FFB4E04402F0801F90FFB4E054AC +:100CD000FB121CED30E11330930990FFB4E04402A5 +:100CE000F0800790FFB4E054FDF0E4FF0231A91258 +:100CF0001D8090FAB9E024FC604004707890FABA44 +:100D0000E0601D90FFA2E04440F0A3E0FF30E76503 +:100D1000D203A3E054DFF090FFA3EF547FF080559F +:100D200030030E90FFA3E04480F0C203A3E0442010 +:100D3000F090FFA2E054BFF0803B90FABAE0601D53 +:100D400090FFB2E04440F0A3E0FF30E728D204A3D4 +:100D5000E054DFF090FFB3EF547FF0801830040EC2 +:100D600090FFB3E04480F0C204A3E04420F090FF81 +:100D7000B2E054BFF0E4FF0231A9121CE090FAB9CE +:100D8000E024FC600F04701690FFA6E0121CC11254 +:100D90001AE8800A90FFB6E0121CC1121AE87539F1 +:100DA00000753A01022CD890F9157401F090F91CE5 +:100DB0007419F090F96674FFF0E4FF0231A9E4FFC2 +:100DC0001231A9121DE77F0312126190F916E0306B +:100DD000E40890FF937480F0801090FFFCE0547F53 +:100DE000F07FFF7E001230D3C290C2AF0080FDE4DE +:100DF000F54EF54F90FABF743EF0A3E4F090FAB7C9 +:100E0000F0A37415F0E0543FFFC374409F90FABC08 +:100E1000F0D39400E4943E400890FAC0E090FABC0D +:100E2000F0120F98E53145307073121CFA90FABF3A +:100E3000121E066027D3EF9440EE9400400890FA0B +:100E4000BC7440F0800890FAC0E090FABCF0120F39 +:100E500098E53145307046121CFA80D1754C0290ED +:100E6000FABFE4F0A304F090FAB7E4F0A3740FF033 +:100E70007B007A00794C90FAC0E0F54A7D0F7C0047 +:100E80001229607530008F317B007A00794CE4F5CF +:100E90002DF52E7D01122698E4F530F531AF3102A3 +:100EA00031A9121D8030E710E0540F90F967F0D39C +:100EB00094004015C295801190FABAE0540F90F951 +:100EC00065F0D394004002C294E4FF0231A9121EDF +:100ED0004CBF0104D2938002C293E4FF0231A912F5 +:100EE0001D80540314600A14600F146008240370FA +:100EF0002BD2918027C2918023121E56120FC06000 +:100F000004D291801790FFA4E04410120FC0FFBFDD +:100F1000A004C2918002D291121E56F090FABAE05B +:100F2000540CFF1313543F14600A14600F1460082C +:100F30002403702BD2928027C2928023121E5D124E +:100F40000FE06004D292801790FFB4E04410120FBB +:100F5000E0FFBFA004C2928002D292121E5DF0E4B4 +:100F6000FF0231A9E53530E707E4FD7F05022FB424 +:100F70007F050231A912327A227B017AFA79B69082 +:100F8000FAB7E0F52DA3E0F52E7D0112269890FA30 +:100F9000B7E475F003121B1CAB36AA37A93822AA96 +:100FA0004EA94F7BFF90FAB7E0FCA3E0FD90FABC9E +:100FB000E0F54A1229607530008F31221223617EDC +:100FC000008E308F31EF22F07F0112126190FFA668 +:100FD000E090FABBF054A0221226988F4C7E00C3FA +:100FE000EF953CEE953B22F07F0112126190FFB627 +:100FF000E090FABBF054A022753900753A01022C3A +:10100000D890FAB9E0FF02323F8E398F3A022CD8DD +:101010001223617E008E308F31EF227D01122698DF +:1010200090FAB4E022EF90F804F022C0A8C2AFEE2C +:10103000600AC0057D7FDDFEDEFAD005EFC39415A2 +:101040005003D0A822137003D0A822FFD507FDD0EB +:10105000A822C000C001C002C004C005E53E2408AB +:10106000F8860553057F7CFF1210C07F007E00E5E7 +:10107000436046FC90F91DE0547F6D700FC083C043 +:1010800082A3E0FEA3E0FFA315438007A3A3A3DC94 +:10109000E68026DC06D082D083801EE0F8A3E0F94B +:1010A000A3E0FAD082D083E8F0A3E9F0A3EAF0A3AA +:1010B000C083C082A3A3A380DA121157D005D00445 +:1010C000D002D001D0002285A84475A888EC700217 +:1010D0007C3F8C3D22E53E2408F876001211AE805C +:1010E000FBC000C001C002C004C0067CFF1210C0DB +:1010F000E5436042FE90F91DE0547F6F700BC083A2 +:10110000C082A3A3A315438007A3A3A3DEEA80267E +:10111000DE06D082D08380D8E0F8A3E0F9A3E0FA1D +:10112000D082D083E8F0A3E9F0A3EAF0A3C083C0A3 +:1011300082A3A3A380DA7808087918097C01E65411 +:101140007F6F700676007700800608090CBC08EEF9 +:10115000121157D006D004D002D001D00022753D24 +:10116000008544A822C0F0C082C083C3E54324E8C0 +:1011700050051211AE80F4EF6031903111E493C349 +:101180009F402FC0047CFF1210C0D004430780E5AD +:101190004375F003A4241DF582E434F9F583EFF0E0 +:1011A000ECA3F0EDA3F00543121157D083D082D009 +:1011B000F0220211DCC0047C20D28CD28DD504FD3B +:1011C000D0042275A80075880075B80075F0007508 +:1011D000D000E4F890F804F0900000F608B800FBA6 +:1011E000020000C2AFE490FF48F090FF50F090FF83 +:1011F00008F090FF10F090FF80F0A3A3F0D2B1C2EE +:10120000B07EFF7FFF1210247EFF7FFF1210247E2E +:10121000FF7FFF121024D2B0D2B17EFF7FFF1210E9 +:10122000247EFF7FFF1210247EFF7FFF1210248098 +:10123000CCC3EE940250047E037FE8EFF4FFEEF49B +:10124000FE0FBF00010E8F428E4122C3EF94BCEE11 +:10125000940250047E077FD0EFF4FFEEF4FE0FBF40 +:1012600000010E8F408E3F22EF700122C000C0A807 +:10127000C2AFE53E2418F8A607E53E2408F8C65498 +:101280007FF6D0A8E630E703D000221211AE80F43A +:10129000C0007F01EF2408F8E660090FBF08F512CF +:1012A00011AE80EED00022C0F0C082C083C000C06A +:1012B00006C004ED2410F8769AED75F021A42405FB +:1012C000F582E434F8F583C082C083A3A3E4780DEB +:1012D000F0A3D8FCEF547F75F002A424F3F582E567 +:1012E000F03430F583E493FE740193FCD083D08214 +:1012F000ECF0A3EEF0ED2408F8EF4480F6D004D033 +:1013000006D000D083D082D0F022753E0075430015 +:101310007A0879187808760077000809DAF890F8E2 +:1013200004E0FC903111E493C39C5005E490F80470 +:10133000F078087480447FF674014410F58975B81C +:1013400000D2ABD2A92275818BD28ED28CD2AFE5DE +:10135000436036FF90F91DE05480602878087908D2 +:10136000E0547FFA7B00E6547FB502027BFF08D988 +:10137000F5EB7010EAF0C007121289AD07AF021248 +:1013800012A0D007A3A3A3DFCE1211AE80C18F2479 +:10139000122AC71222B5A3A3E0A330E728787E1251 +:1013A0002299E04401F01222FA12229DE020E0F698 +:1013B0001223507402F01222DAE0A330E507122360 +:1013C00050E04401F07880E6FE08E6FF8E832408B2 +:1013D0001222A1E0FD1223398A83240A1222A1EDF0 +:1013E000F012230624071222A1E0FF12235A240937 +:1013F0001222A1EFF090F916E030E420081222B793 +:10140000C083C082A3E025E0FF0582D58202158358 +:101410001582E033D082D083F0A3EFF01222B5E042 +:10142000FCA3E0FDECFF1223398A8324081222A1D9 +:10143000EFF0ED12235A24071222A1EDF01222A997 +:10144000E030E60A12234124091222A1E4F012221C +:10145000A9E0FF30E71B12231E24091222A1E0603D +:10146000091222A9EF4402F080071222A9EF54FDCD +:10147000F0787E1222B7A3A3E0FF5307C708E6FC6B +:1014800008E6FD1222E0A3E030E3128D828C83E5B2 +:101490008224051222A1E09032519342075307FBA8 +:1014A00012231E24061222A1E060034307045307FF +:1014B000FC788012232924041222A1E0420743076A +:1014C00080122339F5828A83A3A3EFF012235A24D2 +:1014D000041222A1E0FF8D828C83A3A3E0FCA3E091 +:1014E000FD30E1055307DF8003430720EC30E405BE +:1014F0005307EF80034307101222A9E0FE54036054 +:10150000735307DFEE30E16912231E24091222A172 +:10151000E0121BFC152C0015600115650315600514 +:1015200015650715600915650B15600D15650F002C +:1015300000156DE5246403702190F916E030E20D8A +:1015400030B405430702802C5307FD8027309505F2 +:10155000430702801F5307FD801A3093054307029B +:1015600080125307FD800D43070280085307FD805A +:10157000035307FD12232724041222A1EFF08D82CA +:101580008C83A3A3A3E0FF1222A9E0FE54037003FF +:10159000021660EE20E10302165D081223202409E2 +:1015A0001222A1E0121BFC15BF0015F50115F50371 +:1015B000162905162907160F09160F0B16430D16C7 +:1015C000430F00001660E5246403702390F916E0D1 +:1015D00030E20F30B10653077F02166043078002E6 +:1015E000166030940553077F807D430780807830F4 +:1015F000920553077F8070430780806BE524B40316 +:101600000990FF9EE054EFF0800790FF9EE054DFCA +:10161000F053077F8051E524B4030990FF9EE04416 +:1016200010F0800790FF9EE04420F053077F803742 +:10163000E524B4030990FF9EE054EFF0800790FF8B +:101640009EE054DFF0430780801DE524B403099039 +:10165000FF9EE04410F0800790FF9EE04420F0439E +:101660000780800353077F1222DAE0FCA3E0FD30FD +:10167000E00543072080035307DFEC30E305430711 +:101680004080035307BFEC30E0054307108003534D +:1016900007EFED30E40543070880035307F7ED300B +:1016A000E50543070480035307FBED30E6054307D8 +:1016B0000180035307FEED30E70543070280035323 +:1016C00007FD787E1222DCA3EFF01232847F002225 +:1016D00090FFFA7408F0A37416F090FFF97402F00A +:1016E0007B017AFA79CFE4FD12236190FACFE47599 +:1016F000F003121B1C121992E52330E702D2027B81 +:10170000007A00792490FACFE0F52DA3E0F52E7D44 +:101710000112269890FACFE4F0A3740BF07B007AC4 +:10172000007923752D00F52E7D01122698E52324DE +:101730008090FFF8F0E5236407601EE523640660EF +:1017400018E52364146012E5236441600CE523640A +:101750001A7046E52464027040E523B40716D2945B +:10176000D295D292D29390F916E04402F0A3E044CD +:1017700002F0801EE523B4411290F916E04406F011 +:10178000A3E04406F0D2B1D2B4800790F916E04449 +:1017900001F090F917E04401F0E5236442600CE5A4 +:1017A0002364436006E5236444702E90F916E0FF3D +:1017B000E523B444047E4080027E00EE24804F90F6 +:1017C000F916F0A3E0FFE523B444047E4080027ED6 +:1017D00000EE24804F90F917F090FACFE4F0A37454 +:1017E0000DF012199290FFF5E523F0E4F535F5338D +:1017F000F534F532121E34121CE0121E3B90F96AC9 +:10180000121BF390F96F121BF390FFFFE4F090FFAF +:1018100083E0E4F090FF817480F0A37484F090FF83 +:1018200080F0E4F523E523121D57F583E4F0E5236A +:10183000121D65F583E4F00523E523B407E7787A04 +:1018400076FE0876F090320AE493FF7878F6FDADE4 +:1018500007903217E493FF08F6FFED540FFD121DB9 +:10186000477484F0ED75F008A42447F582E434FF52 +:10187000F583EFF0C374F09F787BF674FE94001844 +:10188000121CD8CEC313CE13D8F9FFED121DA8EF4A +:10189000F0ED121DCEE4F523E52390320493FF789A +:1018A00078F6FDE52325E0240BF582E43432F58358 +:1018B000E49308F6ED30E75318E6540FF9121D478C +:1018C000121DB62447F582E434FF121CC8CEC313A0 +:1018D000CE13D8F9FFE9121DA8EFF0121CCFCEC32A +:1018E00013CE13D8F9121DBB2445F582E434FFF55D +:1018F00083EFF0E9121DCEE975F008A42446F582C5 +:10190000E434FFF5837480F00219677878E6540FA9 +:10191000F9121D9A121DB62407F582E434FF121C39 +:10192000C8CEC313CE13D8F9121DBB2401F582E42F +:1019300034FFF583EFF0121CCFCEC313CE13D8F9CA +:10194000121DBB2405F582E434FFF583EFF0E97541 +:10195000F008A42402F582E434FFF583E4F0E9758D +:10196000F008A42406F582E434FFF583E4F00523AF +:10197000E52364046003021891903209E493FF7830 +:1019800078F6121D98E4F090320893FFF6121D4588 +:10199000E4F090FFFD7405F0227B007A007923903B +:1019A000FACFE475F001121B3285F02EF52D7D0182 +:1019B000022698E709F608DFFA8046E709F208DF11 +:1019C000FA803E88828C83E709F0A3DFFA8032E355 +:1019D00009F608DFFA8078E309F208DFFA807088F8 +:1019E000828C83E309F0A3DFFA806489828A83E032 +:1019F000A3F608DFFA805889828A83E0A3F208DF21 +:101A0000FA804C80D280FA80C680D4806980F280CF +:101A100033801080A680EA809A80A880DA80E280F5 +:101A2000CA803389828A83ECFAE493A3C8C582C84A +:101A3000CCC583CCF0A3C8C582C8CCC583CCDFE9B4 +:101A4000DEE7800D89828A83E493A3F608DFF9EC50 +:101A5000FAA9F0EDFB2289828A83ECFAE0A3C8C5DB +:101A600082C8CCC583CCF0A3C8C582C8CCC583CC02 +:101A7000DFEADEE880DB89828A83E493A3F208DF71 +:101A8000F980CC88F0EF60010E4E60C388F0ED2441 +:101A900002B4040050B9F582EB2402B4040050AF44 +:101AA00023234582239019FC73BB010689828A8314 +:101AB000E0225002E722BBFE02E32289828A83E40D +:101AC0009322BB010CE58229F582E5833AF583E098 +:101AD000225006E92582F8E622BBFE06E92582F8B7 +:101AE000E222E58229F582E5833AF583E49322BB7D +:101AF000010689828A83F0225002F722BBFE01F39D +:101B000022F8BB010DE58229F582E5833AF583E8E9 +:101B1000F0225006E92582C8F622BBFE05E925829F +:101B2000C8F222C5F0F8A3E028F0C5F0F8E5821568 +:101B30008270021583E038F022A3F8E0C5F025F0AA +:101B4000F0E582158270021583E0C838F0E822BB08 +:101B50000110E58229F582E5833AF583E0F5F0A3EB +:101B6000E0225009E92582F886F008E622BBFE0A49 +:101B7000E92582F8E2F5F008E222E5832AF583E917 +:101B800093F5F0A3E99322BB010A89828A83F0E5E9 +:101B9000F0A3F0225006F709A7F01922BBFE06F3C6 +:101BA000E5F009F31922F8BB0111E58229F582E578 +:101BB000833AF583E8F0E5F0A3F0225009E92582A5 +:101BC000C8F608A6F022BBFE09E92582C8F2E5F0B6 +:101BD00008F222A42582F582E5F03583F58322E61A +:101BE000FB08E6FA08E6F922EBF608EAF608E9F659 +:101BF00022E0FBA3E0FAA3E0F922EBF0A3EAF0A3D2 +:101C0000E9F022D083D082F8E493701274019370CB +:101C10000DA3A393F8740193F5828883E47374028F +:101C2000936860EFA3A3A380DFAB36AA37A938E59A +:101C30004C121AE874012538F538E43537F537AB1E +:101C400036FAA9387411121AE874012538F538E407 +:101C50003537F53790FF06E0AB36AA37A938121AA8 +:101C6000E874012538F538E43537F537AB36FAA98D +:101C700038E4121AE8042538F538E43537F537AB7F +:101C800036FAA938E4121AE8042538F538E435376D +:101C9000F53790FF04E0AB36AA37A938121AE8747A +:101CA000012538F538E43537F53790FF05E0AB36D8 +:101CB000AA37A938121AE874012538F538E43537FF +:101CC000F53722F583E05408AB36AA37A93822F558 +:101CD00083EFF0FD7C00C3787BE69DF618E69CF66A +:101CE000E6FE08E67803227536017537F975387215 +:101CF00022E04404F074132FF582E434F9F583E014 +:101D00002290FABCE0FF7E00C390FAC0E09FF09002 +:101D1000FABFE09EF090FAB7EE8FF0121B1CEF2591 +:101D20004FF54FEE354EF54E227B017AFA79B4909D +:101D3000FAB7E0F52DA3E0F52E22787CE6FE08E662 +:101D40008E832404F582E43583F58322540F75F0E5 +:101D500008A42440F582E434FFF58322E54D75F0B4 +:101D600008A42448F582E434FF22E54D75F008A468 +:101D70002408F582E434FF2290FAB9E0FF24FC2223 +:101D800090FF00E0541F2290FABEE090FABAF022D1 +:101D90007533008F3490F96F121BEA9000022254C1 +:101DA0000F75F008A42400F582E434FFF583227552 +:101DB000F008A42441F582E434FFF583227480F016 +:101DC00008E6FFE975F008A42274B22522F582E442 +:101DD00034FAF5832275F008A42442F582E434FF36 +:101DE000F5837480F02290FF82E04408F02290FF97 +:101DF000FEE04403F090FFFCE054FDF0227867E63B +:101E000054FDF690FFFD7465F022121BCCE0FEA39A +:101E1000E0FF4E227B017AFA79B72290FF80E044FE +:101E200008F02290FF83E0547FF022E0FF90F96AEF +:101E3000021BEA90FFA4E04402F022753901753AD2 +:101E400009227B017AF9797222D3E53C9408E53BBB +:101E500094012290FABEE0FF90FABAF02290FFA41B +:101E6000E054EF2290FFB4E054EF2212104B788838 +:101E7000EFF6122AC71222FA8E8324091222A1E059 +:101E8000FD1222E890000A122302240A1222A1E085 +:101E900090000B121AFA1222FAF5828E83A3A3A3E2 +:101EA000E0F55312230624041222A1E0F5548F8298 +:101EB0008E83A3A3E0F555E553C41313135401789F +:101EC00088F6D394004006E55430E101067888E6B0 +:101ED0001222E790000CEF121AFA1222B5A3A3E027 +:101EE000FEA3E0FF53070C5306E6E55330E503433A +:101EF0000701E55420E50EE553547F7008E55320B3 +:101F0000E703430702E55330E303430710E553308B +:101F1000E203430720E55354036003430740E553BE +:101F200030E103430780E55330E403430601E55302 +:101F300030E603430608E55420E40EE553547F7071 +:101F400008E55320E7034306105307FB5306799037 +:101F50000005EE8FF0121B9FE55530E3125430FF61 +:101F6000C4540F1222E7900008EF121AFA800A12E6 +:101F700022E8900008E4121AFAE55554031222E709 +:101F8000900007EF121AFAE5555404FFC3139000AE +:101F900009121AFA900007121ABB70131222E8E90C +:101FA0002409F9E43AFA121AA2FFC313121AE8122A +:101FB000232724081222A1E0FE8D828C83E582244F +:101FC000071222A1E0FDEEED1222E7900003EE8F52 +:101FD000F0121B9F1232847D0AE4FF122FB402100C +:101FE000CE90FAE6E0B403067E007F4080047E00D7 +:101FF0007F0890FADAEEF0A3EFF0900005121ABB1A +:10200000FF7E0090FAD6EEF0A3EFF070037F082277 +:10201000900008121B48FF90FAD8E5F0F0A3EFF00B +:10202000AE02AF018E508F51740A2551F551E4353F +:1020300050F55090FADBE0FF14FE90FAD9E05EFE16 +:10204000C3EF9EFF90FADDF0C390FAD7E09F90FABD +:10205000D6E094005006A3E090FADDF01220A960CB +:1020600003E0FF22122E2B90FAD6E0FEA3E0FF4EF3 +:10207000602B90FADAE0FCA3E0FDD3EF9DEE9C40EC +:1020800007E090FADDF0800890FAD7E090FADDF0F2 +:102090001220A96003E0FF22122E2B80CA7B007A57 +:1020A000007952E4F52DF52E7D011226987F00224D +:1020B000AA50A9517B0190FAD8E0FCA3E0FD90FA68 +:1020C000DDE0F54A12296090FADCEFF022EF24AE51 +:1020D000605224FE602E24FE7003022169240660F3 +:1020E000030221B17871E654FBF690FFA5E0F522DA +:1020F000440FF0743390FA94F0E522A3F090FAB212 +:102100007401F0227872E654FBF690FFB5E0F522F8 +:10211000440FF0744390FA96F0E522A3F090FAB3DE +:102120007401F02290FAA0E0A320E5030221B1900F +:10213000FFA6E090FACDF0A3F090FACDE0FF540FA7 +:10214000FE601090FFA612230D90FFA6E090FACD3E +:10215000F080E690FACEE0FF7434FE122D85EF7029 +:102160005790FACEE0FF743490FA98F0EFA3F02283 +:1021700090FAAAE0A330E54090FFB6E090FACDF0E7 +:10218000A3F090FACDE0FF540FFE601090FFB6125E +:10219000230D90FFB6E090FACDF080E690FACEE005 +:1021A000FF7444FE122D85EF700E90FACEE0FF749E +:1021B0004490FA9AF0EFA3F022C0E0C0F0C083C0D0 +:1021C00082C0D075D000C000C001C002C003C004EE +:1021D000C005C006C00790FF92E0FF90FACCF090D7 +:1021E000FF92E4F0EF121BFC22692622692E220CDA +:1021F00030220C32221A38222C3A225E3E224944E6 +:10220000223E462254502254522254542254560004 +:1022100000226E90FACCE0FD7C007F0112115E80FE +:10222000627C007D017F0312115E90FFFEE044207E +:10223000F080507C007D017F0212115E90FFFEE075 +:102240004440F0803E7C007D017F0512115E8033AA +:102250007C007D017F0612115E802890FACCE0FFA1 +:102260001220C6801E7C007D017F0412115E801347 +:1022700012284E800E90FACCE02400FFE434FFFEDA +:10228000122D85D007D006D005D004D003D002D0BF +:1022900001D000D0D0D082D083D0F0D0E032787C92 +:1022A000E6FE08E624048E83F582E43583F5832276 +:1022B00074132524F582E434F9F583227880E6FE50 +:1022C00008E6F5828E83227880E6FE08E6AA06F804 +:1022D000AC027D017BFF7A3279567E007F0A021ABA +:1022E0007C7880E6FC08E6F5828C83A3A322FF902D +:1022F000F96F021BEA90F96A121BEA900004021AB5 +:10230000BB787EE6FE08E6FF22ED121AFA8F828E77 +:1023100083E58222EFF090FACEE0540F4EFEF0EF0C +:1023200054F04EF0227880E6FC08E68C8322787E1A +:10233000E6FC08E6FD8C8322A607E6246EF8E6227A +:10234000787EE6FA08E6FB2208E6FE08E68E83229F +:1023500026F618EE36F622EF240BF582E43EF583DE +:10236000228B828A83E582228B258A2689278D28E3 +:1023700090FAD2E4F0A37402F07B017AFA79D1905A +:10238000FAD2E0F52DA3E0F52E7D0112269890FA01 +:10239000D1E065286046A3E0FFA3E0A3CFF0A3EF60 +:1023A000F01223F090FAD1E0FF90FAD4E48FF0120B +:1023B0001B1C1223F090FAD4E0FFA3E090FAD2CFD6 +:1023C000F0A3EFF090FAD1E0A375F000121B1C907F +:1023D000FAD2E475F004121B1C02237290FAD3E0C7 +:1023E0002401FF90FAD2E03400AB25AA26A9278F5A +:1023F000F0121B807F00227B017AFA79D190FAD209 +:10240000E475F001121B1C85F02EF52D7D010226CE +:10241000988F62122AC71222FA8E83240B1222A1ED +:10242000E054FBF04402F0081222DCE0A330E50C9B +:10243000122306240B1222A1E04401F0787CE6FE70 +:1024400008E6FFF5828E83E054B8FDF0E56224FED5 +:102450004420FC4DF0E58224041222A1E054B8F09F +:102460004CF08F828E83A37403F018E6FE08E6FF1B +:102470008E8324051222A1C083C082E0FD749925B9 +:1024800062F582E434FAF583E054FC4403FCED4C3D +:10249000D082D083F08F828E83E04480F0E5822466 +:1024A000041222A1E04480F0123284746E2562F896 +:1024B000740446F67F002212104B7F0212126178DC +:1024C00067E64402F6D2B0D2B190F916E030E707E1 +:1024D00090FF9EE4F08036D2B390FFA4E090FA7EA5 +:1024E000F090FFB4E090FA7FF090FFA2E090FA7CC9 +:1024F000F090FFB2E090FA7DF090FFA47430F0907D +:10250000FFB4F090FFA27440F090FFB2F090FAE7B1 +:10251000E5A8F075A88190FF92E06004E4F080F6F1 +:1025200090FFFD743AF043870100000090FA7EE0CE +:1025300090FFA4F090FA7FE090FFB4F090FA7CE076 +:1025400090FFA2F090FA7DE090FFB2F090F918E0D1 +:102550006002C2B390FAE7E0F5A80210CE8B5C8A65 +:102560005D895E122E0D90FAC3121BF3AA5DA95E5F +:1025700090FAC6121BF390FAC7E475F00A121B1CFE +:1025800090FAC6121BEAE92401F9E43AFA90FAC972 +:10259000121BF3AB5CAA5DA95E122E19E0FFC313F8 +:1025A000F0E47882F690FAC1E0FF7882E6C39F50AB +:1025B0004A90FAC3122DEEFF7883F690FAC6122DD8 +:1025C000EEFEF45FFF7883F6122DEB5E4FFF78830B +:1025D000F6122DF475F002121B1C90FAC7E475F088 +:1025E00002121B1CAB5CAA5DA95E900004121ABB10 +:1025F00030E403122E0378820680AAE490FAC2F037 +:10260000228B568A57895890FAC27406F0E490FAE1 +:10261000C1F0121AA2246E6026147070122DDA60B6 +:1026200009243070121225568062122E24121FDAED +:1026300090FAC2EFF0805590FAC27481F0804D128A +:102640002DDA60092430703E122D30803FE5582489 +:1026500003F9E43557FA7B01C003C002C001122E12 +:1026600024900005121ABBFD900008121B48F52E9D +:1026700085F02DD001D002D00312269890FAC1EF38 +:10268000F0E4A3F0800690FAC27481F090FAC2E000 +:10269000122E24900002121AFA90FAC1E0FF228B47 +:1026A000298A2A892B8D2CE52C7003AF2C22122E1F +:1026B000537016122E72E52D90FFF1F01231D850A2 +:1026C000F2122725400B7F0022122E72122725506E +:1026D000F890FFF374A1F0E52CB4010790FFF0E04F +:1026E0004402F090FFF1E4F0F52FE52C14FFE52F04 +:1026F000C39F502A1231C14003AF2F22C3E52C954E +:102700002FFFBF020790FFF0E04402F0122E650594 +:102710002F7401252BF52BE4352AF52A80CC1231B4 +:10272000C140037F1822122E65AF2C2290FFF1E5E5 +:102730002EF00231D812104B788412233130E10888 +:102740007F131231A90227BC7884E6F924131222E0 +:10275000ADE0FF30E7405403601EE9B4030D90FF85 +:102760009EE054FEF0E04404F0804690FF9EE0546A +:10277000FDF0E04408F08039E9B4030D90FF9EE0DD +:1027800054FBF0E04401F0802890FF9EE054F7F005 +:10279000E04402F0801BEF54036014E9B403099095 +:1027A000FFA4E054DFF0800790FFB4E054DFF0C2F4 +:1027B000B390F918E004F0AF011222EEFD122FE5FC +:1027C0001231A90210CE75A840787FE4F6D8FD75C5 +:1027D000818B02280902318CE493A3F8E493A3408F +:1027E00003F68001F208DFF48029E493A3F854078C +:1027F000240CC8C333C4540F4420C8834004F45687 +:10280000800146F6DFE4800B0102040810204080BE +:10281000902BA9E47E019360BCA3FF543F30E509EF +:10282000541FFEE493A360010ECF54C025E060A8BE +:1028300040B8E493A3FAE493A3F8E493A3C8C58251 +:10284000C8CAC583CAF0A3C8C582C8CAC583CADFBF +:10285000E9DEE780BEE4F522121DC2E0B4040DE516 +:10286000222403FF123013121DC2E4F00522E522D8 +:10287000C3940240E3E4F52275F002E52290FA9455 +:10288000121E03602C122D85EF605275F002E522B6 +:1028900090FA94121BCCE4F0A3F075F00AE52290B4 +:1028A000FAA0121BCCE0A330E633121DC27404F070 +:1028B0002275F002E52290FA98121E036016122D7E +:1028C00085EF601975F002E52290FA98121BCCE4AE +:1028D000F0A3F0220522E522C39402409B22E4FFEC +:1028E00090FF83E0540FFEEFC39E501774F02FF556 +:1028F00082E434FEF583E0121CC1121AE80F121CA8 +:10290000B080DDEFFDC3E53A9DF53AE5399400F579 +:1029100039D3E53A9400E53994004006E490FF830A +:10292000F022121DDF121E34121E26121AA2246E6D +:10293000601E14601B248E702D900001121ABBFFC4 +:1029400024FC600304701FEFFD7C007F0D02115E0C +:10295000121E3B1225FA121D89121ABB60030232A5 +:102960007AE4FF12326E228B458A4689478C488D65 +:1029700049D200122E537016122E72E54890FFF1C4 +:10298000F01231D850F21229D5400B7F1822122EA6 +:10299000721229D550F8E4F54BE54A14FFE54BC314 +:1029A0009F50171229C540037F1822054B7401253B +:1029B00047F547E43546F54680DF90FFF0E04401F7 +:1029C000F01229C540037F18227F0022AB45AA469A +:1029D000A947121AA290FFF1F00231D890FFF1E559 +:1029E00049F00231D87B017AFA79CFE4FD122361F4 +:1029F00090FACFE475F009121B1C7B007A00792352 +:102A000090FACFE475F001121B3285F02EF52D7D82 +:102A10000112269890FFF7E523122A3990FFF6E578 +:102A200023F090FACFE4F0A37406122A39E523309C +:102A3000E00790FFFC7494F02290FFFC7490F02269 +:102A4000F07B007A00792390FACFE475F001121B35 +:102A50003285F02EF52D7D0102269890FF9374812A +:102A6000F090FFFFE0600690FFFC7410F090FF9183 +:102A7000E04490F0E490F916F0A3F0122B3912160E +:102A8000C91230697E077FD012122A7E0F7FA012F2 +:102A90001244E47877F67877E6FFC39406500B7417 +:102AA0006E2FF8E4F678770680EC7F031230B29050 +:102AB000F916E020E4057F041230B290FF9BE4F0A9 +:102AC00090FF9AF090FFE8E0541FF0D2A82215651D +:102AD000A865A6073008051211AE80F8D208A865CF +:102AE000E6FFB4030F787C76FF0876E00876FF08EF +:102AF00076A0800D787C76FF0876E20876FF08766F +:102B0000B0788076FA08769EEF24FD75F00AA4AEC0 +:102B1000F01223497B017AFF79487868121BE1A8FB +:102B200065E624FD75F008A4FFAEF0786A1223492B +:102B30007908786B121BE1786DEF12234905652245 +:102B400090FFF0E054ABF0E04420F090FAE674021D +:102B5000F07B017AFA79CFE4F52DF52E7D0112266E +:102B6000987E0090FAE4EEF0A3EFF064017010900C +:102B7000FACFE0B4520990F916E054EFF0802990B2 +:102B8000FAE4E07004A3E06401701090FACFE0B4BE +:102B9000100990F916E04410F0800D90FAE67403E5 +:102BA000F090F916E054EFF090FFF0E04420F022AE +:102BB000036801FF48036B01FF080266000044FA46 +:102BC000980000000044FA940000000042FAB200AD +:102BD0000042FA7E000042FA7C000042F96DFFFFDD +:102BE00042FA7A000041F966FF41F91C1941F915D2 +:102BF0000043F9190A320241F9682041F96920417C +:102C0000F9650041F9670044F8000000000042F94E +:102C100016000041F9180001200041F804000012DC +:102C2000104B788AEFF6122AC71222EE30E029788C +:102C30007C1222B7E0547FF0786B121BD890000210 +:102C4000121ABB30E709900002E4121AFA80E97800 +:102C50007C1222B7E04480F01222EE30E11E1222F4 +:102C600097E0547FF01232197868121BD890000256 +:102C70007480121AFA122297E04480F0123284E42F +:102C8000FF1231A90210CE12104B7885EFF61231E7 +:102C9000501231A97885E6FF24131222ADE0FE30F0 +:102CA000E716EFB4030990FF9EE054FAF0802290FB +:102CB000FF9EE054F5F08019EE54036014EFB40366 +:102CC0000990FFA4E04420F0800790FFB4E0442086 +:102CD000F090F918E014F0E07002D2B30210CE12B6 +:102CE0001E1CE53A64097004E53964016048C3E5D7 +:102CF0003A9408E539940040117F08EFE53A9408CA +:102D0000F53AE5399400F5398005AF3A121E34E4FE +:102D1000FEEEC39F5019121CC1121AA2FD74F82EA8 +:102D2000F582E434FEF583EDF00E121CB080E2EF84 +:102D3000547F90FF81F0228B598A5A895B122E1999 +:102D40007005A37408F022AB59AA5AA95B122E0D84 +:102D500090FAC9121BF3E55B2403F9E4355AFA90A3 +:102D6000FAC3121BF3E490FAC2F0788BF690FAC122 +:102D7000E0FF788BE6C39F5012122DEBFF122DF46B +:102D8000122E07788B06122E0380E222AD07AC06C6 +:102D900090320AE493FF7874F6540F121DA8E008ED +:102DA000760008F618121CD9C333CE33CED8F9FFFB +:102DB0007875EEF608EFF6EE44F818F6EF08F690A0 +:102DC000FF7AE020E7037F00227875E6FE08E6F54B +:102DD000828E83ECF0A3EDF090FF7A7402F07F0115 +:102DE00022AB56AA57A958900003121ABB54F024DC +:102DF000A02290FAC9121BEA021AA290FAC3121B6F +:102E0000EAEF121AE890FACAE42290FAC4E475F0E4 +:102E100001021B1C900008121B48AAF0F97B01223A +:102E2000900005121ABB90FAC1F022AB56AA57A91E +:102E3000582290FADDE0FF7E00C390FAD7E09FF0C1 +:102E400090FAD6E09EF090FAD8EE8FF0121B1CEFAD +:102E50002551F551EE3550F5502290FFF0E054FE2B +:102E6000F0E054FDF090FAE6E064032290FFF2E017 +:102E7000AB29AA2AA92B021AE890FFF374A0F0222A +:102E80008F64ED700FE564B403057F010231EF7FBD +:102E9000020231EFAF64122AC7746E2564F8E6307F +:102EA000E20BD209121D33E0547FF08002C209E523 +:102EB00064B403077F811231EF80057F821231EF06 +:102EC000300907121D33E04480F0123284221210C0 +:102ED0004B90FFFDE04460F0D20190FFFCE0440223 +:102EE000F090FF00E030E71390FF83E04480F04370 +:102EF000358090FFFCE04401F0800D121DDF53355A +:102F00007F90FFFCE054FEF090FF81E04480F012DF +:102F100002DE121DE70210CE12104B7889EFF6D2B6 +:102F200000122AC790F96A121BEAE92403F9E43A6D +:102F3000FAC0027880E6FE08E6AA06F8AC027D0137 +:102F4000D0021222D31232847889E6FF121387123C +:102F500031A90210CE8F63122AC7787C1222B7E003 +:102F6000543FF0E58224041222A1E0543FF01223E2 +:102F700041240B1222A1E054F8F0123284746E2521 +:102F800063F874FB56F67F002212104B122AC71208 +:102F900022FA240612229FE0FD1222E8900003127A +:102FA000230224051222A1E0900004121AFA123220 +:102FB000847D02E4FF122FB40210CEAE05121D8EE6 +:102FC000EF121AFA0E0E0EEED3953CE4953B40023A +:102FD000AE3CEED3940874809481400A7E03900046 +:102FE000027402121AFAAF0612326E22AE07ED54C4 +:102FF00003640160037F1022ED547CC394045003EA +:103000007F0B22746E2EF8740246F674992EF582A8 +:10301000E434FAF583EDF07F0022BF03067CFF7DE8 +:10302000E080047CFF7DE28D828C83E04480F0E5CB +:103030008224041222A1E04480F0746E2FF87404FC +:1030400046F67F002212104BE53A64097004E53918 +:103050006401601690FF83E0540FFFC3E53A9FE5DB +:1030600039940040051228D7800312327A0210CE1C +:1030700090FFFCE020E71FC2AF7DFFAC051DEC60B8 +:10308000157E047F00EF1FAA0670011E4A60EC90B7 +:10309000FF92E4F080EF2212104B7866E6FE08E61D +:1030A000FF30E01230E10F90FFFCE04420F07F049D +:1030B000121261121DF60210CE8F23C208122AC707 +:1030C0001222C0787E122342240B1222A1E054F86F +:1030D000F0123284AF23121387228E5F8F60E56077 +:1030E0001560AE5F7002155FD39400EE9400400946 +:1030F0007E077FD012102480E52211DC2EC724B079 +:1031000032603090303E316F2F82272E2C8031126A +:1031100031311E642F112C180E12104B7886122399 +:103120003120E1077F121231A9800A7886E6FF126A +:10313000240A1231A90210CE12104B7887122331C3 +:1031400020E2077F111231A9800A7887E6FF122F4B +:103150004E1231A90210CE8F61122F4EAF61122A8A +:10316000C71222C0123284746E2561F874FD56F6BF +:10317000AF611213872212104BE53A64097004E51F +:103180003964016005122CD88006121E14121E1C10 +:103190000210CE122A5412130390F804E0FF6005C7 +:1031A0007D011212A01229DE12133F1211BC80E31E +:1031B000121D8EEF121AFAE4F533F534EF600302B4 +:1031C000327AE4FF12326E2290FFF0E0FF54A060EA +:1031D000F7EF30E50890FFF04420F0C322D32290AF +:1031E000FFF0E0FF542860F7EF30E50890FFF0446F +:1031F00020F0C322D322EF30E708121D45E054DF50 +:10320000F022EF121D98E054DFF022810182028348 +:10321000038740004000400040004000400008009C +:10322000787E1222B7A3A3E0FF30E706547FF04474 +:1032300080F022853B39853C3A90FF82E054F7F0DC +:10324000A3E0547FF022E4FEEE90320493B507022F +:10325000D3220EBE07F2C32200081828380181903D +:103260000A02000011130012104B7F021210DA1232 +:103270001DF60210CE7539008F3A121CE0122CD8C0 +:0E32800022121E1C121DDF121E1422C2082272 +:00000001FF +//************************************************************** +//* Edgeport Binary Image (for TI based products) +//* Generated by TIBin2C v2.00 (watchport) +//* Copyright (C) 2001 Inside Out Networks, All rights reserved. +//************************************************************** -- cgit v0.10.2 From 7f127d5ed0da66053482a3e18014c439da3c41d1 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Sat, 5 Jul 2008 15:28:30 +0530 Subject: dsp56k: use request_firmware Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index a69c652..d716c78 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -92,49 +94,6 @@ } \ } -/* DSP56001 bootstrap code */ -static char bootstrap[] = { - 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4, - 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47, - 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00, - 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe, - 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0, - 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a, - 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4, - 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01, - 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08, - 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46, - 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa, - 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00, - 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9, - 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80, - 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a, - 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0, - 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4, - 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a, - 0xf0, 0x80, 0x00, 0x7e, 0xad}; -static int sizeof_bootstrap = 375; - - static struct dsp56k_device { unsigned long in_use; long maxio, timeout; @@ -164,18 +123,40 @@ static int dsp56k_reset(void) static int dsp56k_upload(u_char __user *bin, int len) { + struct platform_device *pdev; + const struct firmware *fw; + const char fw_name[] = "dsp56k/bootstrap.bin"; + int err; int i; - u_char *p; - + dsp56k_reset(); - - p = bootstrap; - for (i = 0; i < sizeof_bootstrap/3; i++) { + + pdev = platform_device_register_simple("dsp56k", 0, NULL, 0); + if (IS_ERR(pdev)) { + printk(KERN_ERR "Failed to register device for \"%s\"\n", + fw_name); + return -EINVAL; + } + err = request_firmware(&fw, fw_name, &pdev->dev); + platform_device_unregister(pdev); + if (err) { + printk(KERN_ERR "Failed to load image \"%s\" err %d\n", + fw_name, err); + return err; + } + if (fw->size % 3) { + printk(KERN_ERR "Bogus length %d in image \"%s\"\n", + fw->size, fw_name); + release_firmware(fw); + return -EINVAL; + } + for (i = 0; i < fw->size; i = i + 3) { /* tx_wait(10); */ - dsp56k_host_interface.data.b[1] = *p++; - dsp56k_host_interface.data.b[2] = *p++; - dsp56k_host_interface.data.b[3] = *p++; + dsp56k_host_interface.data.b[1] = fw->data[i]; + dsp56k_host_interface.data.b[2] = fw->data[i + 1]; + dsp56k_host_interface.data.b[3] = fw->data[i + 2]; } + release_firmware(fw); for (; i < 512; i++) { /* tx_wait(10); */ dsp56k_host_interface.data.b[1] = 0; @@ -534,3 +515,4 @@ static void __exit dsp56k_cleanup_driver(void) module_exit(dsp56k_cleanup_driver); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("dsp56k/bootstrap.bin"); diff --git a/firmware/Makefile b/firmware/Makefile index a162b29..782c499 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -20,6 +20,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE)) # accurate. In the latter case it doesn't matter -- it'll use $(fw-shipped-all). # But be aware that the config file might not be included at all. +fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin diff --git a/firmware/WHENCE b/firmware/WHENCE index 79e62e2..5c1dc15 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -309,3 +309,15 @@ Licence: Found in hex form in kernel source. -------------------------------------------------------------------------- + +Driver: ATARI_DSP56K - Atari DSP56k support + +File: dsp56k/bootstrap.bin +Source: dsp56k/bootstrap.asm + +Licence: GPLv2 or later + +DSP56001 assembler, possibly buildable with a56 from +http://www.zdomain.com/a56.html + +-------------------------------------------------------------------------- diff --git a/firmware/dsp56k/bootstrap.asm b/firmware/dsp56k/bootstrap.asm new file mode 100644 index 0000000..10d8919 --- /dev/null +++ b/firmware/dsp56k/bootstrap.asm @@ -0,0 +1,98 @@ +; Author: Frederik Noring +; +; 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. + +; DSP56k loader + +; Host Interface +M_BCR EQU $FFFE ; Port A Bus Control Register +M_PBC EQU $FFE0 ; Port B Control Register +M_PBDDR EQU $FFE2 ; Port B Data Direction Register +M_PBD EQU $FFE4 ; Port B Data Register +M_PCC EQU $FFE1 ; Port C Control Register +M_PCDDR EQU $FFE3 ; Port C Data Direction Register +M_PCD EQU $FFE5 ; Port C Data Register + +M_HCR EQU $FFE8 ; Host Control Register +M_HSR EQU $FFE9 ; Host Status Register +M_HRX EQU $FFEB ; Host Receive Data Register +M_HTX EQU $FFEB ; Host Transmit Data Register + +; SSI, Synchronous Serial Interface +M_RX EQU $FFEF ; Serial Receive Data Register +M_TX EQU $FFEF ; Serial Transmit Data Register +M_CRA EQU $FFEC ; SSI Control Register A +M_CRB EQU $FFED ; SSI Control Register B +M_SR EQU $FFEE ; SSI Status Register +M_TSR EQU $FFEE ; SSI Time Slot Register + +; Exception Processing +M_IPR EQU $FFFF ; Interrupt Priority Register + + org P:$0 +start jmp <$40 + + org P:$40 +; ; Zero 16384 DSP X and Y words +; clr A #0,r0 +; clr B #0,r4 +; do #64,<_block1 +; rep #256 +; move A,X:(r0)+ B,Y:(r4)+ +;_block1 ; Zero (32768-512) Program words +; clr A #512,r0 +; do #126,<_block2 +; rep #256 +; move A,P:(r0)+ +;_block2 + + ; Copy DSP program control + move #real,r0 + move #upload,r1 + do #upload_end-upload,<_copy + move P:(r0)+,x0 + move x0,P:(r1)+ +_copy movep #>4,X:<$c00,X:<1,X:<0,X:<3,x0 + cmp x0,A #>1,x0 + jeq <$0 +_get_address + jclr #0,X:<2,x0 + jeq load_X + cmp x0,A + jeq load_Y + +load_P do y0,_load + jclr #0,X:< Date: Sat, 5 Jul 2008 18:05:22 +0530 Subject: firmware: convert sb16_csp driver to use firmware loader exclusively Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse diff --git a/firmware/Makefile b/firmware/Makefile index 782c499..10028ac 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -28,6 +28,10 @@ fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw +fw-shipped-$(CONFIG_SND_SB16_CSP) += sb16/mulaw_main.csp sb16/alaw_main.csp \ + sb16/ima_adpcm_init.csp \ + sb16/ima_adpcm_playback.csp \ + sb16/ima_adpcm_capture.csp fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ yamaha/ds1e_ctrl.fw fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 5c1dc15..66c51b2 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -321,3 +321,21 @@ DSP56001 assembler, possibly buildable with a56 from http://www.zdomain.com/a56.html -------------------------------------------------------------------------- + +Driver: SND_SB16_CSP - Sound Blaster 16/AWE CSP support + +File: sb16/mulaw_main.csp +File: sb16/alaw_main.csp +File: sb16/ima_adpcm_init.csp +File: sb16/ima_adpcm_playback.csp +File: sb16/ima_adpcm_capture.csp + +Licence: Allegedly GPLv2+, but no source visible. Marked: +/* + * Copyright (c) 1994 Creative Technology Ltd. + * Microcode files for SB16 Advanced Signal Processor + */ + +Found in hex form in kernel source. + +-------------------------------------------------------------------------- diff --git a/firmware/sb16/alaw_main.csp.ihex b/firmware/sb16/alaw_main.csp.ihex new file mode 100644 index 0000000..0450270 --- /dev/null +++ b/firmware/sb16/alaw_main.csp.ihex @@ -0,0 +1,87 @@ +:10000000001000440800004400B1004400610044B6 +:10001000085000440DF261A8440404190000404552 +:10002000404939AC5555718B500563800000063945 +:10003000FF2E2149FF0FD4492001090E2000718BAA +:10004000A801A8808801A880A8000080D200718B38 +:100050008800A880A804B3802007B3808803B180FB +:10006000C000095CC2010082A100718BCD0004199F +:100070002120718BCF0004190000B180C200041947 +:100080000040001408400424000034490C4000449F +:1000900044040439000040453200095C00000C397A +:1000A00000004045404009EFFF2009CF000463A154 +:1000B000500333800004A38000FFC28B00D004549F +:1000C00004E000C4200380C03000008800007A0AE9 +:1000D000D001008200600044C0000099006000442C +:1000E00000FFC28B20000080000D428B083200C44C +:1000F000000E428B00A200C4001E428B0CB200C452 +:10010000008E428B006200C4009E428B085200C4E5 +:1001100000BE428B085200C40004428B047200C42B +:100120000024428B00D200C40055428B006000C402 +:1001300000004045200179800030428B088200C4D5 +:10014000000040450000718B4001008000600044C9 +:10015000FF00E2AB00B200C40FF2A8A82000B188F3 +:10016000000041024DF20039C001008200600044ED +:100170000DF2A3A84DF2003900600044FF00E2AB8D +:1001800020000088000061024DF204190060004464 +:10019000FF00E2ABA0000088000061104DF20419DE +:1001A00000600044FF20E2AB60000088000071C0E6 +:1001B0004DF20419006000440000798000E20084E0 +:1001C0000303044904C20054006004640060004456 +:1001D0000000638000000619030004490060004429 +:1001E00020016380000006190020E28B0CF20084DD +:1001F000BE00518BC020003908010044EC00518B37 +:10020000C02000390002E28B042100843F00518BA2 +:10021000C2200039001100443D00518BC22000393A +:10022000E500718BCD0000390000B180C9200419B0 +:10023000CB200419C1200419C32004191000718BAC +:10024000C7200419DE00518BCF0000390001B180B6 +:10025000C4200419C6200419C8200419CA2004198E +:100260002000718BCC200419030004490060004475 +:10027000090461A8C10004190B0461A8CA0004198B +:10028000046000D40D00610A9040098F0001004510 +:100290000F00610A0040098F000100458200092E0D +:1002A000804009CF02006122432561224033008053 +:1002B0000848004420B1495C9200094E0203092E0F +:1002C0000000A302C00071C02000EB800004C28BBC +:1002D0002004618000047A02C00000820CC3084937 +:1002E000B001F3800000103920000C890C88084907 +:1002F0000300A81800001039BDFF628B20010080A8 +:10030000000063CB00007A024000015B2000008007 +:1003100000004ACB2000138020007A80E02100C03A +:10032000080008491041098EAEAE628B00046122BC +:1003300000030045220133802001A30200007A80DF +:10034000C00000820720400A08A3008440210080EA +:1003500040059310C7200039000040450720400A9F +:100360000C930084080000820C246150400100803E +:10037000C7200039000040450004638000000639B2 +:100380004201090E0220610A000100450C20600AAA +:1003900000C300840004B180000006390C6104D45D +:1003A000002471C0203333C0E001A38222037A020B +:1003B000C301A3822001338000007A80C201B350C0 +:1003C000CC20003900007180000800440C20600A35 +:1003D00000F300840004B180000006390C6104D4ED +:1003E000000071C000009310CC20003900080044C8 +:1003F000CC200039002000C0003071C0000800444B +:1004000020010080AEAE628B20013380000083802B +:1004100020007A8020A1495C8200096E804A098E02 +:10042000E001B3822004A38000007ACB2804EA1004 +:100430000C047A107000C08B00001039900300800B +:100440004000215B900061800C8A084900001C1963 +:100450004000085B08000849200200800300A8183B +:1004600000001419400021CB000041020000EB8085 +:10047000F2010082402133020820610AC4000419FD +:10048000C70000990200610A0C0A04140100610A05 +:100490000300480A00580454C30004190C580044CF +:1004A0000800C80A0C580454C80004190A00610A5C +:1004B0000900480A00C80454C90004190CC80044C3 +:1004C0000B00C80A0CC80454CB0004190400610ACC +:1004D0000600480A00D80454C60004190CD8004489 +:1004E0000500C80A0CD80454C50004190700610AA5 +:1004F0000C00480A000A0454CC0004190C0A0044F9 +:100500000E00C80A0C0A0454CE000419000040452D +:080510002010718B0842060067 +:00000001FF +/* + * Copyright (c) 1994 Creative Technology Ltd. + * Microcode files for SB16 Advanced Signal Processor + */ diff --git a/firmware/sb16/ima_adpcm_capture.csp.ihex b/firmware/sb16/ima_adpcm_capture.csp.ihex new file mode 100644 index 0000000..9a50a58 --- /dev/null +++ b/firmware/sb16/ima_adpcm_capture.csp.ihex @@ -0,0 +1,121 @@ +:1000000000100044080000440070004408D0004480 +:1000100000F000440DF261A84404041900004045BA +:100020000004638000000639FF2E2149FF0CD449EB +:10003000404939AC5555718B5001B1800000718B2E +:10004000C2300419C0A00419C2A004198900718B20 +:10005000C83004197100718BCD000419CF00041948 +:100060008000718BCB2004192000718BC4200419EF +:100070004700518BC020003900006380C1A00419E3 +:100080009300014FCD300009CF3000090C4000141F +:1000900000600014000461A8020461A80C6004243C +:1000A000000034490850004444040439000040452D +:1000B0000830610A05B0E8180CC00454C8300419AF +:1000C000090400A80B0400A800004045090461A829 +:1000D000C10004190B0461A8CA0004190D00610ACB +:1000E000000100450F00610A0040098F0001004532 +:1000F000404009EFFF2009CF000463A15003338083 +:100100000004A38000FFC28B0C120454081200C428 +:10011000200380C03000008800007A0AD0010082ED +:1001200004500044C00000990450004400FFC28BFA +:1001300020000080000D428B044200C4000E428B60 +:10014000085200C4001E428B00E200C4008E428BA5 +:1001500008D200C4009E428B04F200C400BE428B51 +:1001600004F200C40004428B041100C40024428B3A +:100170000C6100C40055428B045000C4003F428B08 +:100180000C0100C400004045200179800030428B02 +:10019000046200C4000040450000718B40010080F3 +:1001A00004500044FF00E2AB08C200C40FF2A8A84C +:1001B0002000B188000041024DF20039C0010082E8 +:1001C000045000440DF2A3A84DF20039045000443D +:1001D000FF00E2AB20000088000061024DF204192C +:1001E00004500044FF00E2ABA00000880000611052 +:1001F0004DF2041904500044FF20E2AB6000008877 +:10020000000071C04DF204190450004400007A0A45 +:100210002001F08001A0410A001100C42001F080FB +:10022000C130041904500044000079800C4100845E +:100230008900718BC83004199700718BCD0000398B +:100240000001B1808000041982000419C120041942 +:10025000C3200419C2300419CD100419CF10041999 +:10026000B000718B84000419860004198000718B22 +:10027000CB2004199300014FCD300009CF30000985 +:100280000302044908410014045000440000638044 +:100290000000061903000449045000442001638053 +:1002A000000006190020E28B00C100844700518B3A +:1002B000C020003900006380C1A0041900E100449F +:1002C000BD00518BC02000390000B180C1A00419CD +:1002D00003000449045000440020610A0001004565 +:1002E0000230610A0C8300C40C780844045A0844A4 +:1002F000B200094F1042098E05B0E01804230084B3 +:100300000C01001108056110004908440048084428 +:10031000B200094F8000718BC00000820C013310C5 +:100320002801A31000017A808C0100800230610A4C +:10033000200004190C8300C405B0C818084300C489 +:100340000130C80A0C3800C4088800440C780844FE +:10035000045A08440000A318800004190B0461A883 +:10036000C3200039C33004190F10610ACA300419C0 +:10037000090441A8E1200039D100094F00046102BD +:10038000086300440330410A20000039A300094FEC +:100390000004610200480844088800440230610AF1 +:1003A000000800C40C780844045A0844B200090F3D +:1003B0001040098E0000685B2004B1800200615B80 +:1003C00088037A80AC01008005B0E01800D3008477 +:1003D0000049084400480844B200090F8000718BAE +:1003E000C00000820230610A000800C405B0C818CD +:1003F0000C1800C40130C80A0C3800C40888004436 +:100400000C780844000061182005B180000068CB1A +:10041000800004190D10610AC33004190B0441A8AF +:10042000090441A8E1200039083800440330410A9A +:100430002004B18000480844088800440000B180CE +:10044000C23004190CB800D40F30610A0D30C80A4C +:100450000CB800C49300014FE700016F0F30610A30 +:1004600020000088020061024104041902046102B4 +:1004700043040439CF3000092000094900590044E1 +:100480009300014FE700016F0D30610A2000618881 +:10049000C2000082C2030082CD3000092000094959 +:1004A0000F30610A0D30C80A0C5800840230610A0E +:1004B00005B0A818C2300419000000469040098F0A +:1004C0001204096E0300090E0001718220010080F0 +:1004D000000061CB8004B1800001E0600CD80414FE +:1004E0000001EB804000521B80007980C00171C286 +:1004F0002000C080080A0454C004A8828000721B37 +:10050000800000800001F0802000C0800C2A04548C +:10051000C004A8821000721B800000800001F080DF +:100520002000C080083A0454C004A8822000721B36 +:1005300080000080C003F0822000A0800001001134 +:100540004000C28B00AA00C40000E98005B0A818D2 +:100550000001A822D0010082F000E21B0620A80AB8 +:100560002D10610AD100092E0001A8020E10C80A40 +:100570000CBA04140E10610A044A00440C10C80A94 +:10058000044A04540C10610AD00100820010A8181B +:10059000A0000088000171820300090E9A0100602A +:1005A0003200092E00000046000171822001008007 +:1005B000000061CB8024B1C00031E0600CCA04149B +:1005C0000001EB804000521B80007980C00171C2A5 +:1005D0002000C08008DA0454C004A8828000721B86 +:1005E000800000800001F0802000C0800CFA0454DC +:1005F000C004A8821000721B800000800001F080FF +:100600002000C08008290454C004A8822000721B66 +:1006100080000080C003F0822000A0800001001153 +:100620004000C28B003900C40000E98005B0A81862 +:100630000001A822D0010082B000E21B0620A80A17 +:100640002F10610AF100092E0001A8020E10C80A3D +:100650000CA904140E10610A049900440C10C80A75 +:10066000049904540C10610AD00100820010A818EB +:10067000A0000088000171829F0100600000004618 +:10068000000033800000838020007A8020073380C0 +:100690000000838020047A80200100800000004652 +:1006A0000200610A041B04140100610A0300480AE5 +:1006B0000C790454C300041904C900440800C80A92 +:1006C00004C90454C80004190A00610A0900480A50 +:1006D0000CE90454C900041904D900440B00C80AE9 +:1006E00004D90454CB0004190400610A0600480A26 +:1006F0000CF90454C6000419040B00440500C80A90 +:10070000040B0454C50004190700610A0C00480AD0 +:100710000C2B0454CC000419041B00440E00C80A1E +:10072000041B0454CE000419000040459220718B34 +:04073000A6C5110049 +:00000001FF +/* + * Copyright (c) 1994 Creative Technology Ltd. + * Microcode files for SB16 Advanced Signal Processor + */ diff --git a/firmware/sb16/ima_adpcm_init.csp.ihex b/firmware/sb16/ima_adpcm_init.csp.ihex new file mode 100644 index 0000000..a899a9e --- /dev/null +++ b/firmware/sb16/ima_adpcm_init.csp.ihex @@ -0,0 +1,70 @@ +:10000000001000440000404500004045000040450D +:1000100000004045AAAA718B440404190000404521 +:10002000FF6E2149FF0FD449404939AC5555718BBA +:100030005005B1806200190E2100718B880000808C +:10004000B000718B880000804000718B88000080B8 +:100050006000718B880000805000718B88000080E8 +:100060007000718B88000080C000718B8800008058 +:10007000E000718B88000080D000718B88000080C8 +:100080000200718B880000802200718B8800008044 +:100090003200718B88000080A200718B8800008084 +:1000A000B200718B880000806200718B8800008034 +:1000B000C200718B88000080F200718B8800008084 +:1000C0001100718B88000080A100718B8800008076 +:1000D0006100718B88000080E100718B88000080D6 +:1000E0001300718B88000080B300718B8800008042 +:1000F000C300718B880000801800718B880000801D +:100100006800718B880000800A00718B8800008075 +:100110004A00718B880000802900718B8800008064 +:100120007900718B880000809B00718B88000080B3 +:100130001400718B88000080F400718B88000080AF +:10014000E600718B88000080E500718B88000080DC +:10015000D700718B880000802E00718B8800008092 +:100160009D00718B88000080EF00718B88000080FB +:10017000B220718B880000803320718B8800008052 +:100180002A20718B880000803B20718B88000080C2 +:100190004620718B880000802C20718B88000080A5 +:1001A000DD20718B880000800110718B8800008039 +:1001B0009A10718B880000801610718B8800008067 +:1001C0008E10718B88000080C230718B8800008097 +:1001D000C930718B880000803C30718B88000080B2 +:1001E0008180718B88000080D480718B88000080B2 +:1001F00010A0718B8800008034A0718B8800008073 +:100200000290718B880000807590718B880000804F +:100210009AB0718B880000801240718B880000803A +:100220000D40718B880000803C60718B88000080DD +:10023000E750718B880000800E70718B8800008001 +:10024000FFC0718B88000080C8D0718B880000804F +:1002500057F0718B88000080C822718B8800008065 +:10026000B032718B88000080DD82718B8800008045 +:1002700090B2718B880000808A62718B8800008048 +:10028000CE72718B88000080A5D2718B88000080AF +:100290009721718B88000080A2A1718B880000805B +:1002A0005C41718B88000080FEC1718B88000080EA +:1002B0007A23718B880000807893718B880000808E +:1002C0006773718B880000801728718B880000800D +:1002D0008848718B88000080DBF8718B8800008073 +:1002E0002BBA718B88000080F109718B8800008027 +:1002F000DC69718B88000080198B718B880000800D +:10030000FFFB718B880000802000718B88000080CB +:100310005200718BC2000082FFFF718BC20000820D +:10032000C2000082C2000082C20000821000718BF5 +:10033000C20000828000718BC20000829000718B2D +:10034000C20000824000718BC2000082FFFF718BEF +:10035000C2000082C2000082C2000082C20000828D +:100360001000718BC20000828000718BC20000827D +:100370009000718BC20000824000718BC20000822D +:10038000FFFB718BC20000820004718BC2000082EF +:100390004A00718BC20000820000718BC200008293 +:1003A0000000718BC2000082C2000082C2300419BA +:1003B0001000094FC2010082C2010082C201008206 +:1003C000C2010082C2010082C2010082C201008219 +:1003D000C2010082C2010082C2010082C201008209 +:1003E000C2010082C20100820010718BC130041969 +:1003F0009300014FCD300009CF300009000034498F +:0804000000080044C85411007B +:00000001FF +/* + * Copyright (c) 1994 Creative Technology Ltd. + * Microcode files for SB16 Advanced Signal Processor + */ diff --git a/firmware/sb16/ima_adpcm_playback.csp.ihex b/firmware/sb16/ima_adpcm_playback.csp.ihex new file mode 100644 index 0000000..f09f18c --- /dev/null +++ b/firmware/sb16/ima_adpcm_playback.csp.ihex @@ -0,0 +1,122 @@ +:1000000000100044080000440C50004400700044FC +:10001000047000440DF261A8440404190000404536 +:100020000004638000000639FF2E2149FF0DD449EA +:10003000404939AC5555718B5001B1800001B180F8 +:10004000C92004195100718BCD000419E420718B73 +:10005000CF0004198000718BCB2004191000718B24 +:10006000C42004196500518BC22000390000B18002 +:10007000C230041900006380C1A004199300014F2D +:10008000CD300009CF300009044000140C400014AA +:10009000000461A8020461A804600424000034493B +:1000A000005000444404043900004045000040452D +:1000B0000F00610A00010045404009EFFF2009CF11 +:1000C000000463A1500333800004A38000FFC28BAF +:1000D00008F004540CD000C4200380C03000008815 +:1000E00000007A0AD001008208500044C000009944 +:1000F0000850004400FFC28B20000080000D428B9E +:1001000000A200C4000E428B0C9200C4001E428B61 +:10011000046200C4008E428B0C5200C4009E428BCD +:1001200000C200C400BE428B00C200C40004428B67 +:1001300000F200C40024428B009100C40055428BA1 +:10014000085000C4003F428B08E200C40000404554 +:10015000200179800030428B009200C400004045AD +:100160000000718B4001008008500044FF00E2ABAA +:100170000C4200C40FF2A8A82000B1880000410280 +:100180004DF20039C0010082085000440DF2A3A8CE +:100190004DF2003908500044FF00E2AB2000008817 +:1001A000000061024DF2041908500044FF00E2AB68 +:1001B000A0000088000061104DF2041908500044AE +:1001C000FF20E2AB60000088000071C04DF204190E +:1001D0000850004400007A0A2001F08001A0410A82 +:1001E00004D200C42001F080C1300419085000443A +:1001F0000000798000A10084B500518BCF00003948 +:100200000001B180880004198A000419C82004196B +:10021000CA200419C2300419CD100419CF100419D2 +:10022000B000718B8C0004198E0004191000718BC2 +:10023000C42004199300014FCD300009CF300009CC +:100240000303044904810054085004640850004426 +:1002500000006380000006190300044908500044B0 +:1002600020016380000006190002E28B084100842F +:100270006500518BC220003900006380C1A00419C1 +:10028000086100442D00518BC22000390000B1806C +:10029000C1A0041903000449085000440220610A67 +:1002A000000100450230610A040300C405B0C8180B +:1002B000047100C4001300440079084400047980EC +:1002C000004900C4CA2004194A040419FF00E28B43 +:1002D0000CF90844CF1004190C2B08448E000419A3 +:1002E0000330610AC8200039480400390A30610A25 +:1002F0000CF90844CD1004190C2B08448C00041987 +:100300000CD908440C5A0044007908440004798050 +:10031000004900C4C3300419CA3000990CD90844FC +:10032000420A090E000133118C01A38000017A10EA +:100330008005B18005B0E01800930084007908447E +:1003400000047980004900C40C1B0844880004198B +:100350008A0000990CD90844420A090E8000718B6A +:10036000C004B1821000E00B004300840230610A37 +:100370000130C80A004300840000B180C230041973 +:100380000CA800440230610A00D300C405B0C818AC +:10039000046300C408F30044007908440004798031 +:1003A000004900C420000419FF00E28B0CF9084446 +:1003B000CD100419CF1004190C2B08448C0004191B +:1003C0008E0004190330610AC8200039CA200039A0 +:1003D000480400394A0400390CD908440C5A004436 +:1003E0000079084400047980004900C4C33004192E +:1003F0000CD90844420A090E05B0E0180018008420 +:100400000079084400047980004900C40C1B0844AA +:10041000800100800CD90844420A090E8000718BCB +:10042000C004B1821000E00B008800840230610A31 +:100430000130C80A008800840000B180C23004196D +:1004400000010011000FE28B000041CB8C00008006 +:10045000000048CB20007A8080010080820C096E69 +:100460000308090E804009CF000171C20008C21BB9 +:1004700004B800C42005A8802001F0800001C21B40 +:10048000044800C42005A8802001F0800002C21B9F +:10049000046800C42005A8802001F0802003A88003 +:1004A000000100110004C28B087800C40000E9803C +:1004B00005B0A81800004ACB2000A822D001008275 +:1004C00040010080C4000419B000E28B0620A80A95 +:1004D0002D10610AD108092E0001A8020CF9084468 +:1004E000CD1004190C2B08440308090E9A25B1609D +:1004F000A20E096E0300090F000171822001008025 +:10050000000061CB800100800300090F000171C26F +:100510000008C21B0C2A00C42005A8802001F0801E +:100520000001C21B0C1A00C42005A8802001F08025 +:100530000002C21B0C3A00C42005A8802001F080F4 +:100540002003A880000100110004C28B04AA00C48B +:100550000000E98005B0A81800004ACB2000A822BE +:10056000D001008240010080C7000419B000E28B76 +:100570000620A80A2F10610AF108092E0001A8021E +:100580000CF90844CF1004190C2B08449F35B160B6 +:100590000308090E0001718220010080000061CB78 +:1005A00080010080E420718B000100459040098F9C +:1005B0000005638000000639081904D49300014F38 +:1005C000E700016F0D30610A200461A8C2000082BB +:1005D000020461A8C2000082CD30000902000002BE +:1005E00002000002C0800009200009490F30610AA2 +:1005F0000D30C80A002900C40080C80A002900C4C0 +:100600000004B18000000639C920043900390044D3 +:1006100000046380000006390004B180C920043959 +:10062000003900440920230A00000619C9200419D2 +:10063000000040450200610A0CB904140400610A7C +:100640000600480A00A90454C60004190CA9004475 +:100650000500C80A0CA90454C50004190700610A62 +:100660000C00480A00B90454CC0004190CB9004429 +:100670000E00C80A0CB90454CE0004190C5A0044E8 +:10068000820D092E804009CF00DF718B8001008030 +:1006900002C1002203C1002200016580D2056582EB +:1006A00040210080D3030082403300800C5A004474 +:1006B0000F30610A0D30C80A08D900C49300014FF9 +:1006C000E700016F0F30610A20000088020061021C +:1006D00002000003CF3000092000094900046380B4 +:1006E00004D900440004B180000000460230610AD1 +:1006F00005B0A818C2300419000000460E10C80A40 +:100700000C0B04140E10610A042B00440C10C80AD0 +:10071000042B04540C10610A000000460010A818B5 +:10072000A0000088000171820000004600043380B0 +:100730000000838020047A802001338000008380C1 +:1007400020007A80200300800000004616CE1100B1 +:00000001FF +/* + * Copyright (c) 1994 Creative Technology Ltd. + * Microcode files for SB16 Advanced Signal Processor + */ diff --git a/firmware/sb16/mulaw_main.csp.ihex b/firmware/sb16/mulaw_main.csp.ihex new file mode 100644 index 0000000..b64b565 --- /dev/null +++ b/firmware/sb16/mulaw_main.csp.ihex @@ -0,0 +1,84 @@ +:10000000001000440800004400B1004400610044B6 +:10001000085000440DF261A8440404190000404552 +:10002000404939AC5555718B500563800000063945 +:10003000FF2E2149FF0FD4492001090E2000718BAA +:10004000A801A8808801A880A8000080D200718B38 +:100050008800A880A804B3802007B3808803B180FB +:10006000C000095CC2010082A100718BCD0004199F +:10007000A220718BCF0004190000B180C2000419C6 +:100080000040001408400424000034490C4000449F +:1000900044040439000040453200095C00000C397A +:1000A00000004045404009EFFF2009CF000463A154 +:1000B000500333800004A38000FFC28B00D004549F +:1000C00004E000C4200380C03000008800007A0AE9 +:1000D000D001008200600044C0000099006000442C +:1000E00000FFC28B20000080000D428B083200C44C +:1000F000000E428B00A200C4001E428B0CB200C452 +:10010000008E428B006200C4009E428B085200C4E5 +:1001100000BE428B085200C40004428B047200C42B +:100120000024428B00D200C40055428B006000C402 +:1001300000004045200179800030428B088200C4D5 +:10014000000040450000718B4001008000600044C9 +:10015000FF00E2AB00B200C40FF2A8A82000B188F3 +:10016000000041024DF20039C001008200600044ED +:100170000DF2A3A84DF2003900600044FF00E2AB8D +:1001800020000088000061024DF204190060004464 +:10019000FF00E2ABA0000088000061104DF20419DE +:1001A00000600044FF20E2AB60000088000071C0E6 +:1001B0004DF20419006000440000798000E20084E0 +:1001C0000303044908C20054006004640060004452 +:1001D0000000638000000619030004490060004429 +:1001E00020016380000006190020E28B0CF20084DD +:1001F0003E00518BC0200039080100446C00518B37 +:10020000C02000390002E28B04210084FD00518BE4 +:10021000C220003900110044FE00518BC220003979 +:10022000E500718BCD0000390000B180C9200419B0 +:10023000CB200419C1200419C32004191000718BAC +:10024000C72004195E00718BCF0000390000B18017 +:10025000C4200419C6200419C8200419CA2004198E +:100260002000718BCC200419030004490060004475 +:10027000090461A8C10004190B0461A8CA0004198B +:10028000046000D40D00610A9040098F0001004510 +:100290000F00610A0040098F000100458200092E0D +:1002A000804009CF02006122432561224033008053 +:1002B00008A800442031495C9200094E0203092E2F +:1002C0000000A302C00071C02000EB800004C28BBC +:1002D0002004618000047A02CB00A858B005F380A6 +:1002E0002004A81000001039B000E08B200100802D +:1002F000000063CB00007A024000015B2000008018 +:1003000000004ACB2000138020007A80E02100C04A +:10031000080008491041098EFFFF628B000461222A +:1003200000030045220133802001A30200007A80EF +:10033000C00000820720400A08830084402100801A +:1003400040059310C7200039000040450720400AAF +:100350000CA30084080000820C246150400100803E +:10036000C7200039000040450004638000000639C2 +:100370004201090E0220610A000100450C20600ABA +:10038000007300840004B180000006390C6104D4BD +:10039000002471C0203333C0E001A38222037A021B +:1003A000C301A3822001338000007A80C201B350D0 +:1003B000CC2000390000718000F300440C20600A5A +:1003C00000D300840004B180000006390C6104D41D +:1003D0000000B310CC200039000071C000F30044CD +:1003E000CC200039002071C0003071C000F30044FF +:1003F00020010080FFFF628B20013380000083809A +:1004000020007A8020E1095C8200092F804A098E51 +:10041000E001B3822004A38000007ACB0300A81877 +:10042000000010390804EA1008047A102000008047 +:10043000400021CB0C00E810000041020C00EB1042 +:10044000F2010082402133020820610AC40004192D +:10045000C70000990200610A0CE804140100610A57 +:100460000300480A00B80454C30004190CB800443F +:100470000800C80A0CB80454C80004190A00610A2C +:100480000900480A00680454C90004190C680044B3 +:100490000B00C80A0C680454CB0004190400610A5C +:1004A0000600480A00780454C60004190C78004479 +:1004B0000500C80A0C780454C50004190700610A35 +:1004C0000C00480A00E80454CC0004190CE800446D +:1004D0000E00C80A0CE80454CE0004190000404580 +:0804E0002010718B093F070099 +:00000001FF +/* + * Copyright (c) 1994 Creative Technology Ltd. + * Microcode files for SB16 Advanced Signal Processor + */ diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 2639a6a..1ff9f63 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -391,15 +391,6 @@ config SND_SB16_CSP coprocessor can do variable tasks like various compression and decompression algorithms. -config SND_SB16_CSP_FIRMWARE_IN_KERNEL - bool "In-kernel firmware for SB16 CSP" - depends on SND_SB16_CSP - default y - help - Say Y here to include the static firmware built in the kernel - for the SB16 CSP controller. If you choose N here, you need - to install the firmware files from the alsa-firmware package. - config SND_SGALAXY tristate "Aztech Sound Galaxy" depends on SND diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index f3fd7b4..35f3d7b 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -35,13 +35,11 @@ MODULE_AUTHOR("Uros Bizjak "); MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); MODULE_LICENSE("GPL"); -#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL MODULE_FIRMWARE("sb16/mulaw_main.csp"); MODULE_FIRMWARE("sb16/alaw_main.csp"); MODULE_FIRMWARE("sb16/ima_adpcm_init.csp"); MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp"); MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp"); -#endif #ifdef SNDRV_LITTLE_ENDIAN #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) @@ -168,17 +166,13 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) */ static void snd_sb_csp_free(struct snd_hwdep *hwdep) { -#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL int i; -#endif struct snd_sb_csp *p = hwdep->private_data; if (p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) snd_sb_csp_stop(p); -#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) release_firmware(p->csp_programs[i]); -#endif kfree(p); } } @@ -701,18 +695,6 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use return err; } -#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL -#include "sb16_csp_codecs.h" - -static const struct firmware snd_sb_csp_static_programs[] = { - { .data = mulaw_main, .size = sizeof mulaw_main }, - { .data = alaw_main, .size = sizeof alaw_main }, - { .data = ima_adpcm_init, .size = sizeof ima_adpcm_init }, - { .data = ima_adpcm_playback, .size = sizeof ima_adpcm_playback }, - { .data = ima_adpcm_capture, .size = sizeof ima_adpcm_capture }, -}; -#endif - static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) { static const char *const names[] = { @@ -727,14 +709,10 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); program = p->csp_programs[index]; if (!program) { -#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL - program = &snd_sb_csp_static_programs[index]; -#else int err = request_firmware(&program, names[index], p->chip->card->dev); if (err < 0) return err; -#endif p->csp_programs[index] = program; } return snd_sb_csp_load(p, program->data, program->size, flags); diff --git a/sound/isa/sb/sb16_csp_codecs.h b/sound/isa/sb/sb16_csp_codecs.h deleted file mode 100644 index f0e8b0d..0000000 --- a/sound/isa/sb/sb16_csp_codecs.h +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - * - * 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 - * - */ - -static unsigned char mulaw_main[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x00, 0xb1, 0x00, 0x44, 0x00, 0x61, 0x00, 0x44, - 0x08, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x05, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0f, 0xd4, 0x49, - 0x20, 0x01, 0x09, 0x0e, 0x20, 0x00, 0x71, 0x8b, - 0xa8, 0x01, 0xa8, 0x80, 0x88, 0x01, 0xa8, 0x80, - 0xa8, 0x00, 0x00, 0x80, 0xd2, 0x00, 0x71, 0x8b, - 0x88, 0x00, 0xa8, 0x80, 0xa8, 0x04, 0xb3, 0x80, - 0x20, 0x07, 0xb3, 0x80, 0x88, 0x03, 0xb1, 0x80, - 0xc0, 0x00, 0x09, 0x5c, 0xc2, 0x01, 0x00, 0x82, - 0xa1, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x04, 0x19, - 0xa2, 0x20, 0x71, 0x8b, 0xcf, 0x00, 0x04, 0x19, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x00, 0x04, 0x19, - 0x00, 0x40, 0x00, 0x14, 0x08, 0x40, 0x04, 0x24, - 0x00, 0x00, 0x34, 0x49, 0x0c, 0x40, 0x00, 0x44, - 0x44, 0x04, 0x04, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x32, 0x00, 0x09, 0x5c, 0x00, 0x00, 0x0c, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x40, 0x40, 0x09, 0xef, - 0xff, 0x20, 0x09, 0xcf, 0x00, 0x04, 0x63, 0xa1, - 0x50, 0x03, 0x33, 0x80, 0x00, 0x04, 0xa3, 0x80, - 0x00, 0xff, 0xc2, 0x8b, 0x00, 0xd0, 0x04, 0x54, - 0x04, 0xe0, 0x00, 0xc4, 0x20, 0x03, 0x80, 0xc0, - 0x30, 0x00, 0x00, 0x88, 0x00, 0x00, 0x7a, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0xc0, 0x00, 0x00, 0x99, 0x00, 0x60, 0x00, 0x44, - 0x00, 0xff, 0xc2, 0x8b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x0d, 0x42, 0x8b, 0x08, 0x32, 0x00, 0xc4, - 0x00, 0x0e, 0x42, 0x8b, 0x00, 0xa2, 0x00, 0xc4, - 0x00, 0x1e, 0x42, 0x8b, 0x0c, 0xb2, 0x00, 0xc4, - 0x00, 0x8e, 0x42, 0x8b, 0x00, 0x62, 0x00, 0xc4, - 0x00, 0x9e, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0xbe, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0x04, 0x42, 0x8b, 0x04, 0x72, 0x00, 0xc4, - 0x00, 0x24, 0x42, 0x8b, 0x00, 0xd2, 0x00, 0xc4, - 0x00, 0x55, 0x42, 0x8b, 0x00, 0x60, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x20, 0x01, 0x79, 0x80, - 0x00, 0x30, 0x42, 0x8b, 0x08, 0x82, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x71, 0x8b, - 0x40, 0x01, 0x00, 0x80, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x00, 0xb2, 0x00, 0xc4, - 0x0f, 0xf2, 0xa8, 0xa8, 0x20, 0x00, 0xb1, 0x88, - 0x00, 0x00, 0x41, 0x02, 0x4d, 0xf2, 0x00, 0x39, - 0xc0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0x0d, 0xf2, 0xa3, 0xa8, 0x4d, 0xf2, 0x00, 0x39, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x20, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x02, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0xa0, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x10, 0x4d, 0xf2, 0x04, 0x19, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x20, 0xe2, 0xab, - 0x60, 0x00, 0x00, 0x88, 0x00, 0x00, 0x71, 0xc0, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x00, 0xe2, 0x00, 0x84, - 0x03, 0x03, 0x04, 0x49, 0x08, 0xc2, 0x00, 0x54, - 0x00, 0x60, 0x04, 0x64, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x20, 0x01, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x00, 0x20, 0xe2, 0x8b, 0x0c, 0xf2, 0x00, 0x84, - 0x3e, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x08, 0x01, 0x00, 0x44, 0x6c, 0x00, 0x51, 0x8b, - 0xc0, 0x20, 0x00, 0x39, 0x00, 0x02, 0xe2, 0x8b, - 0x04, 0x21, 0x00, 0x84, 0xfd, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x11, 0x00, 0x44, - 0xfe, 0x00, 0x51, 0x8b, 0xc2, 0x20, 0x00, 0x39, - 0xe5, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x00, 0x39, - 0x00, 0x00, 0xb1, 0x80, 0xc9, 0x20, 0x04, 0x19, - 0xcb, 0x20, 0x04, 0x19, 0xc1, 0x20, 0x04, 0x19, - 0xc3, 0x20, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc7, 0x20, 0x04, 0x19, 0x5e, 0x00, 0x71, 0x8b, - 0xcf, 0x00, 0x00, 0x39, 0x00, 0x00, 0xb1, 0x80, - 0xc4, 0x20, 0x04, 0x19, 0xc6, 0x20, 0x04, 0x19, - 0xc8, 0x20, 0x04, 0x19, 0xca, 0x20, 0x04, 0x19, - 0x20, 0x00, 0x71, 0x8b, 0xcc, 0x20, 0x04, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x09, 0x04, 0x61, 0xa8, 0xc1, 0x00, 0x04, 0x19, - 0x0b, 0x04, 0x61, 0xa8, 0xca, 0x00, 0x04, 0x19, - 0x04, 0x60, 0x00, 0xd4, 0x0d, 0x00, 0x61, 0x0a, - 0x90, 0x40, 0x09, 0x8f, 0x00, 0x01, 0x00, 0x45, - 0x0f, 0x00, 0x61, 0x0a, 0x00, 0x40, 0x09, 0x8f, - 0x00, 0x01, 0x00, 0x45, 0x82, 0x00, 0x09, 0x2e, - 0x80, 0x40, 0x09, 0xcf, 0x02, 0x00, 0x61, 0x22, - 0x43, 0x25, 0x61, 0x22, 0x40, 0x33, 0x00, 0x80, - 0x08, 0xa8, 0x00, 0x44, 0x20, 0x31, 0x49, 0x5c, - 0x92, 0x00, 0x09, 0x4e, 0x02, 0x03, 0x09, 0x2e, - 0x00, 0x00, 0xa3, 0x02, 0xc0, 0x00, 0x71, 0xc0, - 0x20, 0x00, 0xeb, 0x80, 0x00, 0x04, 0xc2, 0x8b, - 0x20, 0x04, 0x61, 0x80, 0x00, 0x04, 0x7a, 0x02, - 0xcb, 0x00, 0xa8, 0x58, 0xb0, 0x05, 0xf3, 0x80, - 0x20, 0x04, 0xa8, 0x10, 0x00, 0x00, 0x10, 0x39, - 0xb0, 0x00, 0xe0, 0x8b, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x63, 0xcb, 0x00, 0x00, 0x7a, 0x02, - 0x40, 0x00, 0x01, 0x5b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x4a, 0xcb, 0x20, 0x00, 0x13, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0xe0, 0x21, 0x00, 0xc0, - 0x08, 0x00, 0x08, 0x49, 0x10, 0x41, 0x09, 0x8e, - 0xff, 0xff, 0x62, 0x8b, 0x00, 0x04, 0x61, 0x22, - 0x00, 0x03, 0x00, 0x45, 0x22, 0x01, 0x33, 0x80, - 0x20, 0x01, 0xa3, 0x02, 0x00, 0x00, 0x7a, 0x80, - 0xc0, 0x00, 0x00, 0x82, 0x07, 0x20, 0x40, 0x0a, - 0x08, 0x83, 0x00, 0x84, 0x40, 0x21, 0x00, 0x80, - 0x40, 0x05, 0x93, 0x10, 0xc7, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x07, 0x20, 0x40, 0x0a, - 0x0c, 0xa3, 0x00, 0x84, 0x08, 0x00, 0x00, 0x82, - 0x0c, 0x24, 0x61, 0x50, 0x40, 0x01, 0x00, 0x80, - 0xc7, 0x20, 0x00, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x42, 0x01, 0x09, 0x0e, 0x02, 0x20, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0x73, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x24, 0x71, 0xc0, 0x20, 0x33, 0x33, 0xc0, - 0xe0, 0x01, 0xa3, 0x82, 0x22, 0x03, 0x7a, 0x02, - 0xc3, 0x01, 0xa3, 0x82, 0x20, 0x01, 0x33, 0x80, - 0x00, 0x00, 0x7a, 0x80, 0xc2, 0x01, 0xb3, 0x50, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x00, 0x71, 0x80, - 0x00, 0xf3, 0x00, 0x44, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0xd3, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x00, 0xb3, 0x10, 0xcc, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x71, 0xc0, 0x00, 0xf3, 0x00, 0x44, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x20, 0x71, 0xc0, - 0x00, 0x30, 0x71, 0xc0, 0x00, 0xf3, 0x00, 0x44, - 0x20, 0x01, 0x00, 0x80, 0xff, 0xff, 0x62, 0x8b, - 0x20, 0x01, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0xe1, 0x09, 0x5c, - 0x82, 0x00, 0x09, 0x2f, 0x80, 0x4a, 0x09, 0x8e, - 0xe0, 0x01, 0xb3, 0x82, 0x20, 0x04, 0xa3, 0x80, - 0x00, 0x00, 0x7a, 0xcb, 0x03, 0x00, 0xa8, 0x18, - 0x00, 0x00, 0x10, 0x39, 0x08, 0x04, 0xea, 0x10, - 0x08, 0x04, 0x7a, 0x10, 0x20, 0x00, 0x00, 0x80, - 0x40, 0x00, 0x21, 0xcb, 0x0c, 0x00, 0xe8, 0x10, - 0x00, 0x00, 0x41, 0x02, 0x0c, 0x00, 0xeb, 0x10, - 0xf2, 0x01, 0x00, 0x82, 0x40, 0x21, 0x33, 0x02, - 0x08, 0x20, 0x61, 0x0a, 0xc4, 0x00, 0x04, 0x19, - 0xc7, 0x00, 0x00, 0x99, 0x02, 0x00, 0x61, 0x0a, - 0x0c, 0xe8, 0x04, 0x14, 0x01, 0x00, 0x61, 0x0a, - 0x03, 0x00, 0x48, 0x0a, 0x00, 0xb8, 0x04, 0x54, - 0xc3, 0x00, 0x04, 0x19, 0x0c, 0xb8, 0x00, 0x44, - 0x08, 0x00, 0xc8, 0x0a, 0x0c, 0xb8, 0x04, 0x54, - 0xc8, 0x00, 0x04, 0x19, 0x0a, 0x00, 0x61, 0x0a, - 0x09, 0x00, 0x48, 0x0a, 0x00, 0x68, 0x04, 0x54, - 0xc9, 0x00, 0x04, 0x19, 0x0c, 0x68, 0x00, 0x44, - 0x0b, 0x00, 0xc8, 0x0a, 0x0c, 0x68, 0x04, 0x54, - 0xcb, 0x00, 0x04, 0x19, 0x04, 0x00, 0x61, 0x0a, - 0x06, 0x00, 0x48, 0x0a, 0x00, 0x78, 0x04, 0x54, - 0xc6, 0x00, 0x04, 0x19, 0x0c, 0x78, 0x00, 0x44, - 0x05, 0x00, 0xc8, 0x0a, 0x0c, 0x78, 0x04, 0x54, - 0xc5, 0x00, 0x04, 0x19, 0x07, 0x00, 0x61, 0x0a, - 0x0c, 0x00, 0x48, 0x0a, 0x00, 0xe8, 0x04, 0x54, - 0xcc, 0x00, 0x04, 0x19, 0x0c, 0xe8, 0x00, 0x44, - 0x0e, 0x00, 0xc8, 0x0a, 0x0c, 0xe8, 0x04, 0x54, - 0xce, 0x00, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x10, 0x71, 0x8b, 0x09, 0x3f, 0x07, 0x00 -}; - -static unsigned char alaw_main[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x00, 0xb1, 0x00, 0x44, 0x00, 0x61, 0x00, 0x44, - 0x08, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x05, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0f, 0xd4, 0x49, - 0x20, 0x01, 0x09, 0x0e, 0x20, 0x00, 0x71, 0x8b, - 0xa8, 0x01, 0xa8, 0x80, 0x88, 0x01, 0xa8, 0x80, - 0xa8, 0x00, 0x00, 0x80, 0xd2, 0x00, 0x71, 0x8b, - 0x88, 0x00, 0xa8, 0x80, 0xa8, 0x04, 0xb3, 0x80, - 0x20, 0x07, 0xb3, 0x80, 0x88, 0x03, 0xb1, 0x80, - 0xc0, 0x00, 0x09, 0x5c, 0xc2, 0x01, 0x00, 0x82, - 0xa1, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x04, 0x19, - 0x21, 0x20, 0x71, 0x8b, 0xcf, 0x00, 0x04, 0x19, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x00, 0x04, 0x19, - 0x00, 0x40, 0x00, 0x14, 0x08, 0x40, 0x04, 0x24, - 0x00, 0x00, 0x34, 0x49, 0x0c, 0x40, 0x00, 0x44, - 0x44, 0x04, 0x04, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x32, 0x00, 0x09, 0x5c, 0x00, 0x00, 0x0c, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x40, 0x40, 0x09, 0xef, - 0xff, 0x20, 0x09, 0xcf, 0x00, 0x04, 0x63, 0xa1, - 0x50, 0x03, 0x33, 0x80, 0x00, 0x04, 0xa3, 0x80, - 0x00, 0xff, 0xc2, 0x8b, 0x00, 0xd0, 0x04, 0x54, - 0x04, 0xe0, 0x00, 0xc4, 0x20, 0x03, 0x80, 0xc0, - 0x30, 0x00, 0x00, 0x88, 0x00, 0x00, 0x7a, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0xc0, 0x00, 0x00, 0x99, 0x00, 0x60, 0x00, 0x44, - 0x00, 0xff, 0xc2, 0x8b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x0d, 0x42, 0x8b, 0x08, 0x32, 0x00, 0xc4, - 0x00, 0x0e, 0x42, 0x8b, 0x00, 0xa2, 0x00, 0xc4, - 0x00, 0x1e, 0x42, 0x8b, 0x0c, 0xb2, 0x00, 0xc4, - 0x00, 0x8e, 0x42, 0x8b, 0x00, 0x62, 0x00, 0xc4, - 0x00, 0x9e, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0xbe, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0x04, 0x42, 0x8b, 0x04, 0x72, 0x00, 0xc4, - 0x00, 0x24, 0x42, 0x8b, 0x00, 0xd2, 0x00, 0xc4, - 0x00, 0x55, 0x42, 0x8b, 0x00, 0x60, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x20, 0x01, 0x79, 0x80, - 0x00, 0x30, 0x42, 0x8b, 0x08, 0x82, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x71, 0x8b, - 0x40, 0x01, 0x00, 0x80, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x00, 0xb2, 0x00, 0xc4, - 0x0f, 0xf2, 0xa8, 0xa8, 0x20, 0x00, 0xb1, 0x88, - 0x00, 0x00, 0x41, 0x02, 0x4d, 0xf2, 0x00, 0x39, - 0xc0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0x0d, 0xf2, 0xa3, 0xa8, 0x4d, 0xf2, 0x00, 0x39, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x20, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x02, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0xa0, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x10, 0x4d, 0xf2, 0x04, 0x19, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x20, 0xe2, 0xab, - 0x60, 0x00, 0x00, 0x88, 0x00, 0x00, 0x71, 0xc0, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x00, 0xe2, 0x00, 0x84, - 0x03, 0x03, 0x04, 0x49, 0x04, 0xc2, 0x00, 0x54, - 0x00, 0x60, 0x04, 0x64, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x20, 0x01, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x00, 0x20, 0xe2, 0x8b, 0x0c, 0xf2, 0x00, 0x84, - 0xbe, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x08, 0x01, 0x00, 0x44, 0xec, 0x00, 0x51, 0x8b, - 0xc0, 0x20, 0x00, 0x39, 0x00, 0x02, 0xe2, 0x8b, - 0x04, 0x21, 0x00, 0x84, 0x3f, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x11, 0x00, 0x44, - 0x3d, 0x00, 0x51, 0x8b, 0xc2, 0x20, 0x00, 0x39, - 0xe5, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x00, 0x39, - 0x00, 0x00, 0xb1, 0x80, 0xc9, 0x20, 0x04, 0x19, - 0xcb, 0x20, 0x04, 0x19, 0xc1, 0x20, 0x04, 0x19, - 0xc3, 0x20, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc7, 0x20, 0x04, 0x19, 0xde, 0x00, 0x51, 0x8b, - 0xcf, 0x00, 0x00, 0x39, 0x00, 0x01, 0xb1, 0x80, - 0xc4, 0x20, 0x04, 0x19, 0xc6, 0x20, 0x04, 0x19, - 0xc8, 0x20, 0x04, 0x19, 0xca, 0x20, 0x04, 0x19, - 0x20, 0x00, 0x71, 0x8b, 0xcc, 0x20, 0x04, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x09, 0x04, 0x61, 0xa8, 0xc1, 0x00, 0x04, 0x19, - 0x0b, 0x04, 0x61, 0xa8, 0xca, 0x00, 0x04, 0x19, - 0x04, 0x60, 0x00, 0xd4, 0x0d, 0x00, 0x61, 0x0a, - 0x90, 0x40, 0x09, 0x8f, 0x00, 0x01, 0x00, 0x45, - 0x0f, 0x00, 0x61, 0x0a, 0x00, 0x40, 0x09, 0x8f, - 0x00, 0x01, 0x00, 0x45, 0x82, 0x00, 0x09, 0x2e, - 0x80, 0x40, 0x09, 0xcf, 0x02, 0x00, 0x61, 0x22, - 0x43, 0x25, 0x61, 0x22, 0x40, 0x33, 0x00, 0x80, - 0x08, 0x48, 0x00, 0x44, 0x20, 0xb1, 0x49, 0x5c, - 0x92, 0x00, 0x09, 0x4e, 0x02, 0x03, 0x09, 0x2e, - 0x00, 0x00, 0xa3, 0x02, 0xc0, 0x00, 0x71, 0xc0, - 0x20, 0x00, 0xeb, 0x80, 0x00, 0x04, 0xc2, 0x8b, - 0x20, 0x04, 0x61, 0x80, 0x00, 0x04, 0x7a, 0x02, - 0xc0, 0x00, 0x00, 0x82, 0x0c, 0xc3, 0x08, 0x49, - 0xb0, 0x01, 0xf3, 0x80, 0x00, 0x00, 0x10, 0x39, - 0x20, 0x00, 0x0c, 0x89, 0x0c, 0x88, 0x08, 0x49, - 0x03, 0x00, 0xa8, 0x18, 0x00, 0x00, 0x10, 0x39, - 0xbd, 0xff, 0x62, 0x8b, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x63, 0xcb, 0x00, 0x00, 0x7a, 0x02, - 0x40, 0x00, 0x01, 0x5b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x4a, 0xcb, 0x20, 0x00, 0x13, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0xe0, 0x21, 0x00, 0xc0, - 0x08, 0x00, 0x08, 0x49, 0x10, 0x41, 0x09, 0x8e, - 0xae, 0xae, 0x62, 0x8b, 0x00, 0x04, 0x61, 0x22, - 0x00, 0x03, 0x00, 0x45, 0x22, 0x01, 0x33, 0x80, - 0x20, 0x01, 0xa3, 0x02, 0x00, 0x00, 0x7a, 0x80, - 0xc0, 0x00, 0x00, 0x82, 0x07, 0x20, 0x40, 0x0a, - 0x08, 0xa3, 0x00, 0x84, 0x40, 0x21, 0x00, 0x80, - 0x40, 0x05, 0x93, 0x10, 0xc7, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x07, 0x20, 0x40, 0x0a, - 0x0c, 0x93, 0x00, 0x84, 0x08, 0x00, 0x00, 0x82, - 0x0c, 0x24, 0x61, 0x50, 0x40, 0x01, 0x00, 0x80, - 0xc7, 0x20, 0x00, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x42, 0x01, 0x09, 0x0e, 0x02, 0x20, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0xc3, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x24, 0x71, 0xc0, 0x20, 0x33, 0x33, 0xc0, - 0xe0, 0x01, 0xa3, 0x82, 0x22, 0x03, 0x7a, 0x02, - 0xc3, 0x01, 0xa3, 0x82, 0x20, 0x01, 0x33, 0x80, - 0x00, 0x00, 0x7a, 0x80, 0xc2, 0x01, 0xb3, 0x50, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x00, 0x71, 0x80, - 0x00, 0x08, 0x00, 0x44, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0xf3, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x93, 0x10, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x08, 0x00, 0x44, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x20, 0x00, 0xc0, - 0x00, 0x30, 0x71, 0xc0, 0x00, 0x08, 0x00, 0x44, - 0x20, 0x01, 0x00, 0x80, 0xae, 0xae, 0x62, 0x8b, - 0x20, 0x01, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0xa1, 0x49, 0x5c, - 0x82, 0x00, 0x09, 0x6e, 0x80, 0x4a, 0x09, 0x8e, - 0xe0, 0x01, 0xb3, 0x82, 0x20, 0x04, 0xa3, 0x80, - 0x00, 0x00, 0x7a, 0xcb, 0x28, 0x04, 0xea, 0x10, - 0x0c, 0x04, 0x7a, 0x10, 0x70, 0x00, 0xc0, 0x8b, - 0x00, 0x00, 0x10, 0x39, 0x90, 0x03, 0x00, 0x80, - 0x40, 0x00, 0x21, 0x5b, 0x90, 0x00, 0x61, 0x80, - 0x0c, 0x8a, 0x08, 0x49, 0x00, 0x00, 0x1c, 0x19, - 0x40, 0x00, 0x08, 0x5b, 0x08, 0x00, 0x08, 0x49, - 0x20, 0x02, 0x00, 0x80, 0x03, 0x00, 0xa8, 0x18, - 0x00, 0x00, 0x14, 0x19, 0x40, 0x00, 0x21, 0xcb, - 0x00, 0x00, 0x41, 0x02, 0x00, 0x00, 0xeb, 0x80, - 0xf2, 0x01, 0x00, 0x82, 0x40, 0x21, 0x33, 0x02, - 0x08, 0x20, 0x61, 0x0a, 0xc4, 0x00, 0x04, 0x19, - 0xc7, 0x00, 0x00, 0x99, 0x02, 0x00, 0x61, 0x0a, - 0x0c, 0x0a, 0x04, 0x14, 0x01, 0x00, 0x61, 0x0a, - 0x03, 0x00, 0x48, 0x0a, 0x00, 0x58, 0x04, 0x54, - 0xc3, 0x00, 0x04, 0x19, 0x0c, 0x58, 0x00, 0x44, - 0x08, 0x00, 0xc8, 0x0a, 0x0c, 0x58, 0x04, 0x54, - 0xc8, 0x00, 0x04, 0x19, 0x0a, 0x00, 0x61, 0x0a, - 0x09, 0x00, 0x48, 0x0a, 0x00, 0xc8, 0x04, 0x54, - 0xc9, 0x00, 0x04, 0x19, 0x0c, 0xc8, 0x00, 0x44, - 0x0b, 0x00, 0xc8, 0x0a, 0x0c, 0xc8, 0x04, 0x54, - 0xcb, 0x00, 0x04, 0x19, 0x04, 0x00, 0x61, 0x0a, - 0x06, 0x00, 0x48, 0x0a, 0x00, 0xd8, 0x04, 0x54, - 0xc6, 0x00, 0x04, 0x19, 0x0c, 0xd8, 0x00, 0x44, - 0x05, 0x00, 0xc8, 0x0a, 0x0c, 0xd8, 0x04, 0x54, - 0xc5, 0x00, 0x04, 0x19, 0x07, 0x00, 0x61, 0x0a, - 0x0c, 0x00, 0x48, 0x0a, 0x00, 0x0a, 0x04, 0x54, - 0xcc, 0x00, 0x04, 0x19, 0x0c, 0x0a, 0x00, 0x44, - 0x0e, 0x00, 0xc8, 0x0a, 0x0c, 0x0a, 0x04, 0x54, - 0xce, 0x00, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x10, 0x71, 0x8b, 0x08, 0x42, 0x06, 0x00 -}; - - -static unsigned char ima_adpcm_init[] = { - 0x00, 0x10, 0x00, 0x44, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x40, 0x45, 0xaa, 0xaa, 0x71, 0x8b, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0xff, 0x6e, 0x21, 0x49, 0xff, 0x0f, 0xd4, 0x49, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x05, 0xb1, 0x80, 0x62, 0x00, 0x19, 0x0e, - 0x21, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x40, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x60, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x50, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x70, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xd0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x02, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x22, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x32, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x62, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xf2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x11, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa1, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x61, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe1, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x13, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb3, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc3, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x18, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x68, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x0a, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x4a, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x29, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x79, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9b, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x14, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xf4, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe6, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe5, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xd7, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2e, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9d, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xef, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb2, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x33, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2a, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x3b, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x46, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2c, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdd, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x01, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9a, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x16, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x8e, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc2, 0x30, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc9, 0x30, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x3c, 0x30, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x81, 0x80, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xd4, 0x80, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x10, 0xa0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x34, 0xa0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x02, 0x90, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x75, 0x90, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9a, 0xb0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x12, 0x40, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x0d, 0x40, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x3c, 0x60, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe7, 0x50, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x0e, 0x70, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xff, 0xc0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc8, 0xd0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x57, 0xf0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc8, 0x22, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb0, 0x32, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdd, 0x82, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x90, 0xb2, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x8a, 0x62, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xce, 0x72, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa5, 0xd2, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x97, 0x21, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa2, 0xa1, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x5c, 0x41, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xfe, 0xc1, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x7a, 0x23, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x78, 0x93, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x67, 0x73, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x17, 0x28, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x88, 0x48, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdb, 0xf8, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2b, 0xba, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xf1, 0x09, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdc, 0x69, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x19, 0x8b, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xff, 0xfb, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x20, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x52, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xff, 0xff, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0x10, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0x80, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0x90, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0x40, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0xff, 0xff, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x00, 0x00, 0x82, - 0x10, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x80, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x90, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x40, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xff, 0xfb, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x00, 0x04, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x4a, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x00, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x00, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x30, 0x04, 0x19, - 0x10, 0x00, 0x09, 0x4f, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0x00, 0x10, 0x71, 0x8b, 0xc1, 0x30, 0x04, 0x19, - 0x93, 0x00, 0x01, 0x4f, 0xcd, 0x30, 0x00, 0x09, - 0xcf, 0x30, 0x00, 0x09, 0x00, 0x00, 0x34, 0x49, - 0x00, 0x08, 0x00, 0x44, 0xc8, 0x54, 0x11, 0x00 -}; - -static unsigned char ima_adpcm_playback[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x0c, 0x50, 0x00, 0x44, 0x00, 0x70, 0x00, 0x44, - 0x04, 0x70, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0d, 0xd4, 0x49, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x01, 0xb1, 0x80, 0x00, 0x01, 0xb1, 0x80, - 0xc9, 0x20, 0x04, 0x19, 0x51, 0x00, 0x71, 0x8b, - 0xcd, 0x00, 0x04, 0x19, 0xe4, 0x20, 0x71, 0x8b, - 0xcf, 0x00, 0x04, 0x19, 0x80, 0x00, 0x71, 0x8b, - 0xcb, 0x20, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc4, 0x20, 0x04, 0x19, 0x65, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x00, 0xb1, 0x80, - 0xc2, 0x30, 0x04, 0x19, 0x00, 0x00, 0x63, 0x80, - 0xc1, 0xa0, 0x04, 0x19, 0x93, 0x00, 0x01, 0x4f, - 0xcd, 0x30, 0x00, 0x09, 0xcf, 0x30, 0x00, 0x09, - 0x04, 0x40, 0x00, 0x14, 0x0c, 0x40, 0x00, 0x14, - 0x00, 0x04, 0x61, 0xa8, 0x02, 0x04, 0x61, 0xa8, - 0x04, 0x60, 0x04, 0x24, 0x00, 0x00, 0x34, 0x49, - 0x00, 0x50, 0x00, 0x44, 0x44, 0x04, 0x04, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x40, 0x45, - 0x0f, 0x00, 0x61, 0x0a, 0x00, 0x01, 0x00, 0x45, - 0x40, 0x40, 0x09, 0xef, 0xff, 0x20, 0x09, 0xcf, - 0x00, 0x04, 0x63, 0xa1, 0x50, 0x03, 0x33, 0x80, - 0x00, 0x04, 0xa3, 0x80, 0x00, 0xff, 0xc2, 0x8b, - 0x08, 0xf0, 0x04, 0x54, 0x0c, 0xd0, 0x00, 0xc4, - 0x20, 0x03, 0x80, 0xc0, 0x30, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x7a, 0x0a, 0xd0, 0x01, 0x00, 0x82, - 0x08, 0x50, 0x00, 0x44, 0xc0, 0x00, 0x00, 0x99, - 0x08, 0x50, 0x00, 0x44, 0x00, 0xff, 0xc2, 0x8b, - 0x20, 0x00, 0x00, 0x80, 0x00, 0x0d, 0x42, 0x8b, - 0x00, 0xa2, 0x00, 0xc4, 0x00, 0x0e, 0x42, 0x8b, - 0x0c, 0x92, 0x00, 0xc4, 0x00, 0x1e, 0x42, 0x8b, - 0x04, 0x62, 0x00, 0xc4, 0x00, 0x8e, 0x42, 0x8b, - 0x0c, 0x52, 0x00, 0xc4, 0x00, 0x9e, 0x42, 0x8b, - 0x00, 0xc2, 0x00, 0xc4, 0x00, 0xbe, 0x42, 0x8b, - 0x00, 0xc2, 0x00, 0xc4, 0x00, 0x04, 0x42, 0x8b, - 0x00, 0xf2, 0x00, 0xc4, 0x00, 0x24, 0x42, 0x8b, - 0x00, 0x91, 0x00, 0xc4, 0x00, 0x55, 0x42, 0x8b, - 0x08, 0x50, 0x00, 0xc4, 0x00, 0x3f, 0x42, 0x8b, - 0x08, 0xe2, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x01, 0x79, 0x80, 0x00, 0x30, 0x42, 0x8b, - 0x00, 0x92, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x71, 0x8b, 0x40, 0x01, 0x00, 0x80, - 0x08, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x0c, 0x42, 0x00, 0xc4, 0x0f, 0xf2, 0xa8, 0xa8, - 0x20, 0x00, 0xb1, 0x88, 0x00, 0x00, 0x41, 0x02, - 0x4d, 0xf2, 0x00, 0x39, 0xc0, 0x01, 0x00, 0x82, - 0x08, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0xa3, 0xa8, - 0x4d, 0xf2, 0x00, 0x39, 0x08, 0x50, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x20, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x02, 0x4d, 0xf2, 0x04, 0x19, - 0x08, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x10, - 0x4d, 0xf2, 0x04, 0x19, 0x08, 0x50, 0x00, 0x44, - 0xff, 0x20, 0xe2, 0xab, 0x60, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x71, 0xc0, 0x4d, 0xf2, 0x04, 0x19, - 0x08, 0x50, 0x00, 0x44, 0x00, 0x00, 0x7a, 0x0a, - 0x20, 0x01, 0xf0, 0x80, 0x01, 0xa0, 0x41, 0x0a, - 0x04, 0xd2, 0x00, 0xc4, 0x20, 0x01, 0xf0, 0x80, - 0xc1, 0x30, 0x04, 0x19, 0x08, 0x50, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x00, 0xa1, 0x00, 0x84, - 0xb5, 0x00, 0x51, 0x8b, 0xcf, 0x00, 0x00, 0x39, - 0x00, 0x01, 0xb1, 0x80, 0x88, 0x00, 0x04, 0x19, - 0x8a, 0x00, 0x04, 0x19, 0xc8, 0x20, 0x04, 0x19, - 0xca, 0x20, 0x04, 0x19, 0xc2, 0x30, 0x04, 0x19, - 0xcd, 0x10, 0x04, 0x19, 0xcf, 0x10, 0x04, 0x19, - 0xb0, 0x00, 0x71, 0x8b, 0x8c, 0x00, 0x04, 0x19, - 0x8e, 0x00, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc4, 0x20, 0x04, 0x19, 0x93, 0x00, 0x01, 0x4f, - 0xcd, 0x30, 0x00, 0x09, 0xcf, 0x30, 0x00, 0x09, - 0x03, 0x03, 0x04, 0x49, 0x04, 0x81, 0x00, 0x54, - 0x08, 0x50, 0x04, 0x64, 0x08, 0x50, 0x00, 0x44, - 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x08, 0x50, 0x00, 0x44, - 0x20, 0x01, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x00, 0x02, 0xe2, 0x8b, 0x08, 0x41, 0x00, 0x84, - 0x65, 0x00, 0x51, 0x8b, 0xc2, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x63, 0x80, 0xc1, 0xa0, 0x04, 0x19, - 0x08, 0x61, 0x00, 0x44, 0x2d, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x00, 0xb1, 0x80, - 0xc1, 0xa0, 0x04, 0x19, 0x03, 0x00, 0x04, 0x49, - 0x08, 0x50, 0x00, 0x44, 0x02, 0x20, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x02, 0x30, 0x61, 0x0a, - 0x04, 0x03, 0x00, 0xc4, 0x05, 0xb0, 0xc8, 0x18, - 0x04, 0x71, 0x00, 0xc4, 0x00, 0x13, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0xca, 0x20, 0x04, 0x19, - 0x4a, 0x04, 0x04, 0x19, 0xff, 0x00, 0xe2, 0x8b, - 0x0c, 0xf9, 0x08, 0x44, 0xcf, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x8e, 0x00, 0x04, 0x19, - 0x03, 0x30, 0x61, 0x0a, 0xc8, 0x20, 0x00, 0x39, - 0x48, 0x04, 0x00, 0x39, 0x0a, 0x30, 0x61, 0x0a, - 0x0c, 0xf9, 0x08, 0x44, 0xcd, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x8c, 0x00, 0x04, 0x19, - 0x0c, 0xd9, 0x08, 0x44, 0x0c, 0x5a, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0xc3, 0x30, 0x04, 0x19, - 0xca, 0x30, 0x00, 0x99, 0x0c, 0xd9, 0x08, 0x44, - 0x42, 0x0a, 0x09, 0x0e, 0x00, 0x01, 0x33, 0x11, - 0x8c, 0x01, 0xa3, 0x80, 0x00, 0x01, 0x7a, 0x10, - 0x80, 0x05, 0xb1, 0x80, 0x05, 0xb0, 0xe0, 0x18, - 0x00, 0x93, 0x00, 0x84, 0x00, 0x79, 0x08, 0x44, - 0x00, 0x04, 0x79, 0x80, 0x00, 0x49, 0x00, 0xc4, - 0x0c, 0x1b, 0x08, 0x44, 0x88, 0x00, 0x04, 0x19, - 0x8a, 0x00, 0x00, 0x99, 0x0c, 0xd9, 0x08, 0x44, - 0x42, 0x0a, 0x09, 0x0e, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x04, 0xb1, 0x82, 0x10, 0x00, 0xe0, 0x0b, - 0x00, 0x43, 0x00, 0x84, 0x02, 0x30, 0x61, 0x0a, - 0x01, 0x30, 0xc8, 0x0a, 0x00, 0x43, 0x00, 0x84, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x30, 0x04, 0x19, - 0x0c, 0xa8, 0x00, 0x44, 0x02, 0x30, 0x61, 0x0a, - 0x00, 0xd3, 0x00, 0xc4, 0x05, 0xb0, 0xc8, 0x18, - 0x04, 0x63, 0x00, 0xc4, 0x08, 0xf3, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0x20, 0x00, 0x04, 0x19, - 0xff, 0x00, 0xe2, 0x8b, 0x0c, 0xf9, 0x08, 0x44, - 0xcd, 0x10, 0x04, 0x19, 0xcf, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x8c, 0x00, 0x04, 0x19, - 0x8e, 0x00, 0x04, 0x19, 0x03, 0x30, 0x61, 0x0a, - 0xc8, 0x20, 0x00, 0x39, 0xca, 0x20, 0x00, 0x39, - 0x48, 0x04, 0x00, 0x39, 0x4a, 0x04, 0x00, 0x39, - 0x0c, 0xd9, 0x08, 0x44, 0x0c, 0x5a, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0xc3, 0x30, 0x04, 0x19, - 0x0c, 0xd9, 0x08, 0x44, 0x42, 0x0a, 0x09, 0x0e, - 0x05, 0xb0, 0xe0, 0x18, 0x00, 0x18, 0x00, 0x84, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0x0c, 0x1b, 0x08, 0x44, - 0x80, 0x01, 0x00, 0x80, 0x0c, 0xd9, 0x08, 0x44, - 0x42, 0x0a, 0x09, 0x0e, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x04, 0xb1, 0x82, 0x10, 0x00, 0xe0, 0x0b, - 0x00, 0x88, 0x00, 0x84, 0x02, 0x30, 0x61, 0x0a, - 0x01, 0x30, 0xc8, 0x0a, 0x00, 0x88, 0x00, 0x84, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x30, 0x04, 0x19, - 0x00, 0x01, 0x00, 0x11, 0x00, 0x0f, 0xe2, 0x8b, - 0x00, 0x00, 0x41, 0xcb, 0x8c, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x48, 0xcb, 0x20, 0x00, 0x7a, 0x80, - 0x80, 0x01, 0x00, 0x80, 0x82, 0x0c, 0x09, 0x6e, - 0x03, 0x08, 0x09, 0x0e, 0x80, 0x40, 0x09, 0xcf, - 0x00, 0x01, 0x71, 0xc2, 0x00, 0x08, 0xc2, 0x1b, - 0x04, 0xb8, 0x00, 0xc4, 0x20, 0x05, 0xa8, 0x80, - 0x20, 0x01, 0xf0, 0x80, 0x00, 0x01, 0xc2, 0x1b, - 0x04, 0x48, 0x00, 0xc4, 0x20, 0x05, 0xa8, 0x80, - 0x20, 0x01, 0xf0, 0x80, 0x00, 0x02, 0xc2, 0x1b, - 0x04, 0x68, 0x00, 0xc4, 0x20, 0x05, 0xa8, 0x80, - 0x20, 0x01, 0xf0, 0x80, 0x20, 0x03, 0xa8, 0x80, - 0x00, 0x01, 0x00, 0x11, 0x00, 0x04, 0xc2, 0x8b, - 0x08, 0x78, 0x00, 0xc4, 0x00, 0x00, 0xe9, 0x80, - 0x05, 0xb0, 0xa8, 0x18, 0x00, 0x00, 0x4a, 0xcb, - 0x20, 0x00, 0xa8, 0x22, 0xd0, 0x01, 0x00, 0x82, - 0x40, 0x01, 0x00, 0x80, 0xc4, 0x00, 0x04, 0x19, - 0xb0, 0x00, 0xe2, 0x8b, 0x06, 0x20, 0xa8, 0x0a, - 0x2d, 0x10, 0x61, 0x0a, 0xd1, 0x08, 0x09, 0x2e, - 0x00, 0x01, 0xa8, 0x02, 0x0c, 0xf9, 0x08, 0x44, - 0xcd, 0x10, 0x04, 0x19, 0x0c, 0x2b, 0x08, 0x44, - 0x03, 0x08, 0x09, 0x0e, 0x9a, 0x25, 0xb1, 0x60, - 0xa2, 0x0e, 0x09, 0x6e, 0x03, 0x00, 0x09, 0x0f, - 0x00, 0x01, 0x71, 0x82, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x61, 0xcb, 0x80, 0x01, 0x00, 0x80, - 0x03, 0x00, 0x09, 0x0f, 0x00, 0x01, 0x71, 0xc2, - 0x00, 0x08, 0xc2, 0x1b, 0x0c, 0x2a, 0x00, 0xc4, - 0x20, 0x05, 0xa8, 0x80, 0x20, 0x01, 0xf0, 0x80, - 0x00, 0x01, 0xc2, 0x1b, 0x0c, 0x1a, 0x00, 0xc4, - 0x20, 0x05, 0xa8, 0x80, 0x20, 0x01, 0xf0, 0x80, - 0x00, 0x02, 0xc2, 0x1b, 0x0c, 0x3a, 0x00, 0xc4, - 0x20, 0x05, 0xa8, 0x80, 0x20, 0x01, 0xf0, 0x80, - 0x20, 0x03, 0xa8, 0x80, 0x00, 0x01, 0x00, 0x11, - 0x00, 0x04, 0xc2, 0x8b, 0x04, 0xaa, 0x00, 0xc4, - 0x00, 0x00, 0xe9, 0x80, 0x05, 0xb0, 0xa8, 0x18, - 0x00, 0x00, 0x4a, 0xcb, 0x20, 0x00, 0xa8, 0x22, - 0xd0, 0x01, 0x00, 0x82, 0x40, 0x01, 0x00, 0x80, - 0xc7, 0x00, 0x04, 0x19, 0xb0, 0x00, 0xe2, 0x8b, - 0x06, 0x20, 0xa8, 0x0a, 0x2f, 0x10, 0x61, 0x0a, - 0xf1, 0x08, 0x09, 0x2e, 0x00, 0x01, 0xa8, 0x02, - 0x0c, 0xf9, 0x08, 0x44, 0xcf, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x9f, 0x35, 0xb1, 0x60, - 0x03, 0x08, 0x09, 0x0e, 0x00, 0x01, 0x71, 0x82, - 0x20, 0x01, 0x00, 0x80, 0x00, 0x00, 0x61, 0xcb, - 0x80, 0x01, 0x00, 0x80, 0xe4, 0x20, 0x71, 0x8b, - 0x00, 0x01, 0x00, 0x45, 0x90, 0x40, 0x09, 0x8f, - 0x00, 0x05, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x08, 0x19, 0x04, 0xd4, 0x93, 0x00, 0x01, 0x4f, - 0xe7, 0x00, 0x01, 0x6f, 0x0d, 0x30, 0x61, 0x0a, - 0x20, 0x04, 0x61, 0xa8, 0xc2, 0x00, 0x00, 0x82, - 0x02, 0x04, 0x61, 0xa8, 0xc2, 0x00, 0x00, 0x82, - 0xcd, 0x30, 0x00, 0x09, 0x02, 0x00, 0x00, 0x02, - 0x02, 0x00, 0x00, 0x02, 0xc0, 0x80, 0x00, 0x09, - 0x20, 0x00, 0x09, 0x49, 0x0f, 0x30, 0x61, 0x0a, - 0x0d, 0x30, 0xc8, 0x0a, 0x00, 0x29, 0x00, 0xc4, - 0x00, 0x80, 0xc8, 0x0a, 0x00, 0x29, 0x00, 0xc4, - 0x00, 0x04, 0xb1, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xc9, 0x20, 0x04, 0x39, 0x00, 0x39, 0x00, 0x44, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x00, 0x04, 0xb1, 0x80, 0xc9, 0x20, 0x04, 0x39, - 0x00, 0x39, 0x00, 0x44, 0x09, 0x20, 0x23, 0x0a, - 0x00, 0x00, 0x06, 0x19, 0xc9, 0x20, 0x04, 0x19, - 0x00, 0x00, 0x40, 0x45, 0x02, 0x00, 0x61, 0x0a, - 0x0c, 0xb9, 0x04, 0x14, 0x04, 0x00, 0x61, 0x0a, - 0x06, 0x00, 0x48, 0x0a, 0x00, 0xa9, 0x04, 0x54, - 0xc6, 0x00, 0x04, 0x19, 0x0c, 0xa9, 0x00, 0x44, - 0x05, 0x00, 0xc8, 0x0a, 0x0c, 0xa9, 0x04, 0x54, - 0xc5, 0x00, 0x04, 0x19, 0x07, 0x00, 0x61, 0x0a, - 0x0c, 0x00, 0x48, 0x0a, 0x00, 0xb9, 0x04, 0x54, - 0xcc, 0x00, 0x04, 0x19, 0x0c, 0xb9, 0x00, 0x44, - 0x0e, 0x00, 0xc8, 0x0a, 0x0c, 0xb9, 0x04, 0x54, - 0xce, 0x00, 0x04, 0x19, 0x0c, 0x5a, 0x00, 0x44, - 0x82, 0x0d, 0x09, 0x2e, 0x80, 0x40, 0x09, 0xcf, - 0x00, 0xdf, 0x71, 0x8b, 0x80, 0x01, 0x00, 0x80, - 0x02, 0xc1, 0x00, 0x22, 0x03, 0xc1, 0x00, 0x22, - 0x00, 0x01, 0x65, 0x80, 0xd2, 0x05, 0x65, 0x82, - 0x40, 0x21, 0x00, 0x80, 0xd3, 0x03, 0x00, 0x82, - 0x40, 0x33, 0x00, 0x80, 0x0c, 0x5a, 0x00, 0x44, - 0x0f, 0x30, 0x61, 0x0a, 0x0d, 0x30, 0xc8, 0x0a, - 0x08, 0xd9, 0x00, 0xc4, 0x93, 0x00, 0x01, 0x4f, - 0xe7, 0x00, 0x01, 0x6f, 0x0f, 0x30, 0x61, 0x0a, - 0x20, 0x00, 0x00, 0x88, 0x02, 0x00, 0x61, 0x02, - 0x02, 0x00, 0x00, 0x03, 0xcf, 0x30, 0x00, 0x09, - 0x20, 0x00, 0x09, 0x49, 0x00, 0x04, 0x63, 0x80, - 0x04, 0xd9, 0x00, 0x44, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x00, 0x46, 0x02, 0x30, 0x61, 0x0a, - 0x05, 0xb0, 0xa8, 0x18, 0xc2, 0x30, 0x04, 0x19, - 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0xc8, 0x0a, - 0x0c, 0x0b, 0x04, 0x14, 0x0e, 0x10, 0x61, 0x0a, - 0x04, 0x2b, 0x00, 0x44, 0x0c, 0x10, 0xc8, 0x0a, - 0x04, 0x2b, 0x04, 0x54, 0x0c, 0x10, 0x61, 0x0a, - 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0xa8, 0x18, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x01, 0x71, 0x82, - 0x00, 0x00, 0x00, 0x46, 0x00, 0x04, 0x33, 0x80, - 0x00, 0x00, 0x83, 0x80, 0x20, 0x04, 0x7a, 0x80, - 0x20, 0x01, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0x03, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x46, 0x16, 0xce, 0x11, 0x00 -}; - -static unsigned char ima_adpcm_capture[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x00, 0x70, 0x00, 0x44, 0x08, 0xd0, 0x00, 0x44, - 0x00, 0xf0, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0c, 0xd4, 0x49, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x01, 0xb1, 0x80, 0x00, 0x00, 0x71, 0x8b, - 0xc2, 0x30, 0x04, 0x19, 0xc0, 0xa0, 0x04, 0x19, - 0xc2, 0xa0, 0x04, 0x19, 0x89, 0x00, 0x71, 0x8b, - 0xc8, 0x30, 0x04, 0x19, 0x71, 0x00, 0x71, 0x8b, - 0xcd, 0x00, 0x04, 0x19, 0xcf, 0x00, 0x04, 0x19, - 0x80, 0x00, 0x71, 0x8b, 0xcb, 0x20, 0x04, 0x19, - 0x20, 0x00, 0x71, 0x8b, 0xc4, 0x20, 0x04, 0x19, - 0x47, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x63, 0x80, 0xc1, 0xa0, 0x04, 0x19, - 0x93, 0x00, 0x01, 0x4f, 0xcd, 0x30, 0x00, 0x09, - 0xcf, 0x30, 0x00, 0x09, 0x0c, 0x40, 0x00, 0x14, - 0x00, 0x60, 0x00, 0x14, 0x00, 0x04, 0x61, 0xa8, - 0x02, 0x04, 0x61, 0xa8, 0x0c, 0x60, 0x04, 0x24, - 0x00, 0x00, 0x34, 0x49, 0x08, 0x50, 0x00, 0x44, - 0x44, 0x04, 0x04, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x08, 0x30, 0x61, 0x0a, 0x05, 0xb0, 0xe8, 0x18, - 0x0c, 0xc0, 0x04, 0x54, 0xc8, 0x30, 0x04, 0x19, - 0x09, 0x04, 0x00, 0xa8, 0x0b, 0x04, 0x00, 0xa8, - 0x00, 0x00, 0x40, 0x45, 0x09, 0x04, 0x61, 0xa8, - 0xc1, 0x00, 0x04, 0x19, 0x0b, 0x04, 0x61, 0xa8, - 0xca, 0x00, 0x04, 0x19, 0x0d, 0x00, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x0f, 0x00, 0x61, 0x0a, - 0x00, 0x40, 0x09, 0x8f, 0x00, 0x01, 0x00, 0x45, - 0x40, 0x40, 0x09, 0xef, 0xff, 0x20, 0x09, 0xcf, - 0x00, 0x04, 0x63, 0xa1, 0x50, 0x03, 0x33, 0x80, - 0x00, 0x04, 0xa3, 0x80, 0x00, 0xff, 0xc2, 0x8b, - 0x0c, 0x12, 0x04, 0x54, 0x08, 0x12, 0x00, 0xc4, - 0x20, 0x03, 0x80, 0xc0, 0x30, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x7a, 0x0a, 0xd0, 0x01, 0x00, 0x82, - 0x04, 0x50, 0x00, 0x44, 0xc0, 0x00, 0x00, 0x99, - 0x04, 0x50, 0x00, 0x44, 0x00, 0xff, 0xc2, 0x8b, - 0x20, 0x00, 0x00, 0x80, 0x00, 0x0d, 0x42, 0x8b, - 0x04, 0x42, 0x00, 0xc4, 0x00, 0x0e, 0x42, 0x8b, - 0x08, 0x52, 0x00, 0xc4, 0x00, 0x1e, 0x42, 0x8b, - 0x00, 0xe2, 0x00, 0xc4, 0x00, 0x8e, 0x42, 0x8b, - 0x08, 0xd2, 0x00, 0xc4, 0x00, 0x9e, 0x42, 0x8b, - 0x04, 0xf2, 0x00, 0xc4, 0x00, 0xbe, 0x42, 0x8b, - 0x04, 0xf2, 0x00, 0xc4, 0x00, 0x04, 0x42, 0x8b, - 0x04, 0x11, 0x00, 0xc4, 0x00, 0x24, 0x42, 0x8b, - 0x0c, 0x61, 0x00, 0xc4, 0x00, 0x55, 0x42, 0x8b, - 0x04, 0x50, 0x00, 0xc4, 0x00, 0x3f, 0x42, 0x8b, - 0x0c, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x01, 0x79, 0x80, 0x00, 0x30, 0x42, 0x8b, - 0x04, 0x62, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x71, 0x8b, 0x40, 0x01, 0x00, 0x80, - 0x04, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x08, 0xc2, 0x00, 0xc4, 0x0f, 0xf2, 0xa8, 0xa8, - 0x20, 0x00, 0xb1, 0x88, 0x00, 0x00, 0x41, 0x02, - 0x4d, 0xf2, 0x00, 0x39, 0xc0, 0x01, 0x00, 0x82, - 0x04, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0xa3, 0xa8, - 0x4d, 0xf2, 0x00, 0x39, 0x04, 0x50, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x20, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x02, 0x4d, 0xf2, 0x04, 0x19, - 0x04, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x10, - 0x4d, 0xf2, 0x04, 0x19, 0x04, 0x50, 0x00, 0x44, - 0xff, 0x20, 0xe2, 0xab, 0x60, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x71, 0xc0, 0x4d, 0xf2, 0x04, 0x19, - 0x04, 0x50, 0x00, 0x44, 0x00, 0x00, 0x7a, 0x0a, - 0x20, 0x01, 0xf0, 0x80, 0x01, 0xa0, 0x41, 0x0a, - 0x00, 0x11, 0x00, 0xc4, 0x20, 0x01, 0xf0, 0x80, - 0xc1, 0x30, 0x04, 0x19, 0x04, 0x50, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x0c, 0x41, 0x00, 0x84, - 0x89, 0x00, 0x71, 0x8b, 0xc8, 0x30, 0x04, 0x19, - 0x97, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x00, 0x39, - 0x00, 0x01, 0xb1, 0x80, 0x80, 0x00, 0x04, 0x19, - 0x82, 0x00, 0x04, 0x19, 0xc1, 0x20, 0x04, 0x19, - 0xc3, 0x20, 0x04, 0x19, 0xc2, 0x30, 0x04, 0x19, - 0xcd, 0x10, 0x04, 0x19, 0xcf, 0x10, 0x04, 0x19, - 0xb0, 0x00, 0x71, 0x8b, 0x84, 0x00, 0x04, 0x19, - 0x86, 0x00, 0x04, 0x19, 0x80, 0x00, 0x71, 0x8b, - 0xcb, 0x20, 0x04, 0x19, 0x93, 0x00, 0x01, 0x4f, - 0xcd, 0x30, 0x00, 0x09, 0xcf, 0x30, 0x00, 0x09, - 0x03, 0x02, 0x04, 0x49, 0x08, 0x41, 0x00, 0x14, - 0x04, 0x50, 0x00, 0x44, 0x00, 0x00, 0x63, 0x80, - 0x00, 0x00, 0x06, 0x19, 0x03, 0x00, 0x04, 0x49, - 0x04, 0x50, 0x00, 0x44, 0x20, 0x01, 0x63, 0x80, - 0x00, 0x00, 0x06, 0x19, 0x00, 0x20, 0xe2, 0x8b, - 0x00, 0xc1, 0x00, 0x84, 0x47, 0x00, 0x51, 0x8b, - 0xc0, 0x20, 0x00, 0x39, 0x00, 0x00, 0x63, 0x80, - 0xc1, 0xa0, 0x04, 0x19, 0x00, 0xe1, 0x00, 0x44, - 0xbd, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x00, 0x00, 0xb1, 0x80, 0xc1, 0xa0, 0x04, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x04, 0x50, 0x00, 0x44, - 0x00, 0x20, 0x61, 0x0a, 0x00, 0x01, 0x00, 0x45, - 0x02, 0x30, 0x61, 0x0a, 0x0c, 0x83, 0x00, 0xc4, - 0x0c, 0x78, 0x08, 0x44, 0x04, 0x5a, 0x08, 0x44, - 0xb2, 0x00, 0x09, 0x4f, 0x10, 0x42, 0x09, 0x8e, - 0x05, 0xb0, 0xe0, 0x18, 0x04, 0x23, 0x00, 0x84, - 0x0c, 0x01, 0x00, 0x11, 0x08, 0x05, 0x61, 0x10, - 0x00, 0x49, 0x08, 0x44, 0x00, 0x48, 0x08, 0x44, - 0xb2, 0x00, 0x09, 0x4f, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x00, 0x00, 0x82, 0x0c, 0x01, 0x33, 0x10, - 0x28, 0x01, 0xa3, 0x10, 0x00, 0x01, 0x7a, 0x80, - 0x8c, 0x01, 0x00, 0x80, 0x02, 0x30, 0x61, 0x0a, - 0x20, 0x00, 0x04, 0x19, 0x0c, 0x83, 0x00, 0xc4, - 0x05, 0xb0, 0xc8, 0x18, 0x08, 0x43, 0x00, 0xc4, - 0x01, 0x30, 0xc8, 0x0a, 0x0c, 0x38, 0x00, 0xc4, - 0x08, 0x88, 0x00, 0x44, 0x0c, 0x78, 0x08, 0x44, - 0x04, 0x5a, 0x08, 0x44, 0x00, 0x00, 0xa3, 0x18, - 0x80, 0x00, 0x04, 0x19, 0x0b, 0x04, 0x61, 0xa8, - 0xc3, 0x20, 0x00, 0x39, 0xc3, 0x30, 0x04, 0x19, - 0x0f, 0x10, 0x61, 0x0a, 0xca, 0x30, 0x04, 0x19, - 0x09, 0x04, 0x41, 0xa8, 0xe1, 0x20, 0x00, 0x39, - 0xd1, 0x00, 0x09, 0x4f, 0x00, 0x04, 0x61, 0x02, - 0x08, 0x63, 0x00, 0x44, 0x03, 0x30, 0x41, 0x0a, - 0x20, 0x00, 0x00, 0x39, 0xa3, 0x00, 0x09, 0x4f, - 0x00, 0x04, 0x61, 0x02, 0x00, 0x48, 0x08, 0x44, - 0x08, 0x88, 0x00, 0x44, 0x02, 0x30, 0x61, 0x0a, - 0x00, 0x08, 0x00, 0xc4, 0x0c, 0x78, 0x08, 0x44, - 0x04, 0x5a, 0x08, 0x44, 0xb2, 0x00, 0x09, 0x0f, - 0x10, 0x40, 0x09, 0x8e, 0x00, 0x00, 0x68, 0x5b, - 0x20, 0x04, 0xb1, 0x80, 0x02, 0x00, 0x61, 0x5b, - 0x88, 0x03, 0x7a, 0x80, 0xac, 0x01, 0x00, 0x80, - 0x05, 0xb0, 0xe0, 0x18, 0x00, 0xd3, 0x00, 0x84, - 0x00, 0x49, 0x08, 0x44, 0x00, 0x48, 0x08, 0x44, - 0xb2, 0x00, 0x09, 0x0f, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x00, 0x00, 0x82, 0x02, 0x30, 0x61, 0x0a, - 0x00, 0x08, 0x00, 0xc4, 0x05, 0xb0, 0xc8, 0x18, - 0x0c, 0x18, 0x00, 0xc4, 0x01, 0x30, 0xc8, 0x0a, - 0x0c, 0x38, 0x00, 0xc4, 0x08, 0x88, 0x00, 0x44, - 0x0c, 0x78, 0x08, 0x44, 0x00, 0x00, 0x61, 0x18, - 0x20, 0x05, 0xb1, 0x80, 0x00, 0x00, 0x68, 0xcb, - 0x80, 0x00, 0x04, 0x19, 0x0d, 0x10, 0x61, 0x0a, - 0xc3, 0x30, 0x04, 0x19, 0x0b, 0x04, 0x41, 0xa8, - 0x09, 0x04, 0x41, 0xa8, 0xe1, 0x20, 0x00, 0x39, - 0x08, 0x38, 0x00, 0x44, 0x03, 0x30, 0x41, 0x0a, - 0x20, 0x04, 0xb1, 0x80, 0x00, 0x48, 0x08, 0x44, - 0x08, 0x88, 0x00, 0x44, 0x00, 0x00, 0xb1, 0x80, - 0xc2, 0x30, 0x04, 0x19, 0x0c, 0xb8, 0x00, 0xd4, - 0x0f, 0x30, 0x61, 0x0a, 0x0d, 0x30, 0xc8, 0x0a, - 0x0c, 0xb8, 0x00, 0xc4, 0x93, 0x00, 0x01, 0x4f, - 0xe7, 0x00, 0x01, 0x6f, 0x0f, 0x30, 0x61, 0x0a, - 0x20, 0x00, 0x00, 0x88, 0x02, 0x00, 0x61, 0x02, - 0x41, 0x04, 0x04, 0x19, 0x02, 0x04, 0x61, 0x02, - 0x43, 0x04, 0x04, 0x39, 0xcf, 0x30, 0x00, 0x09, - 0x20, 0x00, 0x09, 0x49, 0x00, 0x59, 0x00, 0x44, - 0x93, 0x00, 0x01, 0x4f, 0xe7, 0x00, 0x01, 0x6f, - 0x0d, 0x30, 0x61, 0x0a, 0x20, 0x00, 0x61, 0x88, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x03, 0x00, 0x82, - 0xcd, 0x30, 0x00, 0x09, 0x20, 0x00, 0x09, 0x49, - 0x0f, 0x30, 0x61, 0x0a, 0x0d, 0x30, 0xc8, 0x0a, - 0x0c, 0x58, 0x00, 0x84, 0x02, 0x30, 0x61, 0x0a, - 0x05, 0xb0, 0xa8, 0x18, 0xc2, 0x30, 0x04, 0x19, - 0x00, 0x00, 0x00, 0x46, 0x90, 0x40, 0x09, 0x8f, - 0x12, 0x04, 0x09, 0x6e, 0x03, 0x00, 0x09, 0x0e, - 0x00, 0x01, 0x71, 0x82, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x61, 0xcb, 0x80, 0x04, 0xb1, 0x80, - 0x00, 0x01, 0xe0, 0x60, 0x0c, 0xd8, 0x04, 0x14, - 0x00, 0x01, 0xeb, 0x80, 0x40, 0x00, 0x52, 0x1b, - 0x80, 0x00, 0x79, 0x80, 0xc0, 0x01, 0x71, 0xc2, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0x0a, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x80, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x0c, 0x2a, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x10, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0x3a, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x20, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0xc0, 0x03, 0xf0, 0x82, - 0x20, 0x00, 0xa0, 0x80, 0x00, 0x01, 0x00, 0x11, - 0x40, 0x00, 0xc2, 0x8b, 0x00, 0xaa, 0x00, 0xc4, - 0x00, 0x00, 0xe9, 0x80, 0x05, 0xb0, 0xa8, 0x18, - 0x00, 0x01, 0xa8, 0x22, 0xd0, 0x01, 0x00, 0x82, - 0xf0, 0x00, 0xe2, 0x1b, 0x06, 0x20, 0xa8, 0x0a, - 0x2d, 0x10, 0x61, 0x0a, 0xd1, 0x00, 0x09, 0x2e, - 0x00, 0x01, 0xa8, 0x02, 0x0e, 0x10, 0xc8, 0x0a, - 0x0c, 0xba, 0x04, 0x14, 0x0e, 0x10, 0x61, 0x0a, - 0x04, 0x4a, 0x00, 0x44, 0x0c, 0x10, 0xc8, 0x0a, - 0x04, 0x4a, 0x04, 0x54, 0x0c, 0x10, 0x61, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x10, 0xa8, 0x18, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x01, 0x71, 0x82, - 0x03, 0x00, 0x09, 0x0e, 0x9a, 0x01, 0x00, 0x60, - 0x32, 0x00, 0x09, 0x2e, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x01, 0x71, 0x82, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x61, 0xcb, 0x80, 0x24, 0xb1, 0xc0, - 0x00, 0x31, 0xe0, 0x60, 0x0c, 0xca, 0x04, 0x14, - 0x00, 0x01, 0xeb, 0x80, 0x40, 0x00, 0x52, 0x1b, - 0x80, 0x00, 0x79, 0x80, 0xc0, 0x01, 0x71, 0xc2, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0xda, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x80, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x0c, 0xfa, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x10, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0x29, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x20, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0xc0, 0x03, 0xf0, 0x82, - 0x20, 0x00, 0xa0, 0x80, 0x00, 0x01, 0x00, 0x11, - 0x40, 0x00, 0xc2, 0x8b, 0x00, 0x39, 0x00, 0xc4, - 0x00, 0x00, 0xe9, 0x80, 0x05, 0xb0, 0xa8, 0x18, - 0x00, 0x01, 0xa8, 0x22, 0xd0, 0x01, 0x00, 0x82, - 0xb0, 0x00, 0xe2, 0x1b, 0x06, 0x20, 0xa8, 0x0a, - 0x2f, 0x10, 0x61, 0x0a, 0xf1, 0x00, 0x09, 0x2e, - 0x00, 0x01, 0xa8, 0x02, 0x0e, 0x10, 0xc8, 0x0a, - 0x0c, 0xa9, 0x04, 0x14, 0x0e, 0x10, 0x61, 0x0a, - 0x04, 0x99, 0x00, 0x44, 0x0c, 0x10, 0xc8, 0x0a, - 0x04, 0x99, 0x04, 0x54, 0x0c, 0x10, 0x61, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x10, 0xa8, 0x18, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x01, 0x71, 0x82, - 0x9f, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0x07, 0x33, 0x80, - 0x00, 0x00, 0x83, 0x80, 0x20, 0x04, 0x7a, 0x80, - 0x20, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x46, - 0x02, 0x00, 0x61, 0x0a, 0x04, 0x1b, 0x04, 0x14, - 0x01, 0x00, 0x61, 0x0a, 0x03, 0x00, 0x48, 0x0a, - 0x0c, 0x79, 0x04, 0x54, 0xc3, 0x00, 0x04, 0x19, - 0x04, 0xc9, 0x00, 0x44, 0x08, 0x00, 0xc8, 0x0a, - 0x04, 0xc9, 0x04, 0x54, 0xc8, 0x00, 0x04, 0x19, - 0x0a, 0x00, 0x61, 0x0a, 0x09, 0x00, 0x48, 0x0a, - 0x0c, 0xe9, 0x04, 0x54, 0xc9, 0x00, 0x04, 0x19, - 0x04, 0xd9, 0x00, 0x44, 0x0b, 0x00, 0xc8, 0x0a, - 0x04, 0xd9, 0x04, 0x54, 0xcb, 0x00, 0x04, 0x19, - 0x04, 0x00, 0x61, 0x0a, 0x06, 0x00, 0x48, 0x0a, - 0x0c, 0xf9, 0x04, 0x54, 0xc6, 0x00, 0x04, 0x19, - 0x04, 0x0b, 0x00, 0x44, 0x05, 0x00, 0xc8, 0x0a, - 0x04, 0x0b, 0x04, 0x54, 0xc5, 0x00, 0x04, 0x19, - 0x07, 0x00, 0x61, 0x0a, 0x0c, 0x00, 0x48, 0x0a, - 0x0c, 0x2b, 0x04, 0x54, 0xcc, 0x00, 0x04, 0x19, - 0x04, 0x1b, 0x00, 0x44, 0x0e, 0x00, 0xc8, 0x0a, - 0x04, 0x1b, 0x04, 0x54, 0xce, 0x00, 0x04, 0x19, - 0x00, 0x00, 0x40, 0x45, 0x92, 0x20, 0x71, 0x8b, - 0xa6, 0xc5, 0x11, 0x00 -}; -- cgit v0.10.2 From 116a9fb3ed98c19d1ee0c6c55971f5b753949393 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 14 Jul 2008 15:03:25 -0700 Subject: x86: MMIOTRACE should not default to on Even the help-text makes it clear that normal people shouldn't enable it. Signed-off-by: Linus Torvalds diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 5236621..ae36bfa 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -179,7 +179,6 @@ config MMIOTRACE depends on DEBUG_KERNEL && PCI select TRACING select MMIOTRACE_HOOKS - default y help Mmiotrace traces Memory Mapped I/O access and is meant for debugging and reverse engineering. It is called from the ioremap -- cgit v0.10.2 From 50515af207d410c9f228380e529c56f43c3de0bd Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 14 Jul 2008 17:50:24 -0700 Subject: firmware: Correct dependency on CONFIG_EXTRA_FIRMWARE_DIR When CONFIG_EXTRA_FIRMWARE_DIR gets changed, the filename in the .S file (which uses .incbin to include the binary) needs to change. When we renamed the BUILTIN_FIRMWARE_DIR option to EXTRA_FIRMWARE_DIR, we forgot to update the manual dependency in firmware/Makefile, so it was depending on a non-existent file in include/config/ Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds diff --git a/firmware/Makefile b/firmware/Makefile index 10028ac..809a526 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -136,7 +136,7 @@ $(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps) \ | $(objtree)/$$(dir %) $(call cmd,fwbin,$(patsubst %.gen.S,%,$@)) $(patsubst %,$(obj)/%.gen.S, $(fw-external-y)): %: $(wordsize_deps) \ - include/config/builtin/firmware/dir.h | $(objtree)/$$(dir %) + include/config/extra/firmware/dir.h | $(objtree)/$$(dir %) $(call cmd,fwbin,$(fwabs)/$(patsubst $(obj)/%.gen.S,%,$@)) # The .o files depend on the binaries directly; the .S files don't. -- cgit v0.10.2 From b3fcaaa8a6359e9ed623ed4c1d2d48c79eed4648 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 14 Jul 2008 19:25:57 +1000 Subject: powerpc: mman.h export fixups Commit ef3d3246a0d06be622867d21af25f997aeeb105f ("powerpc/mm: Add Strong Access Ordering support") in the powerpc/{next,master} tree caused the following in a powerpc allmodconfig build: usr/include/asm/mman.h requires linux/mm.h, which does not exist in exported headers We should not use CONFIG_PPC64 in an unprotected (by __KERNEL__) section of an exported include file and linux/mm.h is not exported. So protect the whole section that is CONFIG_PPC64 with __KERNEL__ and put the two introduced includes in there as well. Signed-off-by: Stephen Rothwell Acked-by: Dave Kleikamp Signed-off-by: Benjamin Herrenschmidt diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild index 34a0a8d..04ce8f8 100644 --- a/include/asm-powerpc/Kbuild +++ b/include/asm-powerpc/Kbuild @@ -2,7 +2,6 @@ include include/asm-generic/Kbuild.asm header-y += auxvec.h header-y += ioctls.h -header-y += mman.h header-y += sembuf.h header-y += siginfo.h header-y += stat.h diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h index f8a32e2..9209f75 100644 --- a/include/asm-powerpc/mman.h +++ b/include/asm-powerpc/mman.h @@ -1,9 +1,7 @@ #ifndef _ASM_POWERPC_MMAN_H #define _ASM_POWERPC_MMAN_H -#include #include -#include /* * This program is free software; you can redistribute it and/or @@ -28,7 +26,12 @@ #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#ifdef __KERNEL__ #ifdef CONFIG_PPC64 + +#include +#include + /* * This file is included by linux/mman.h, so we can't use cacl_vm_prot_bits() * here. How important is the optimization? @@ -56,4 +59,5 @@ static inline int arch_validate_prot(unsigned long prot) #define arch_validate_prot(prot) arch_validate_prot(prot) #endif /* CONFIG_PPC64 */ +#endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_MMAN_H */ -- cgit v0.10.2 From fe9e8d53772b5ea9ccf8ea4e8f0f009a6885eb70 Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Tue, 8 Jul 2008 15:45:11 +1000 Subject: powerpc: Add driver for Barrier Synchronization Register Adds a character driver for BSR support on IBM POWER systems including Power5 and Power6. The BSR is an optional processor facility not currently implemented by any other processors. It's primary purpose is fast large SMP synchronization. More details on the BSR are in comments to the code which follows. This patch adds BSR driver to pseries_defconfig. Signed-off-by: Sonny Rao Signed-off-by: Joel Schopp Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index adaa05f..fe6ffa6 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -946,6 +946,7 @@ CONFIG_HVC_DRIVER=y CONFIG_HVC_CONSOLE=y CONFIG_HVC_RTAS=y CONFIG_HVCS=m +CONFIG_IBM_BSR=m # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set CONFIG_GEN_RTC=y diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 2d854bb..650e6b4 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -649,6 +649,14 @@ config HVCS which will also be compiled when this driver is built as a module. +config IBM_BSR + tristate "IBM POWER Barrier Synchronization Register support" + depends on PPC_PSERIES + help + This devices exposes a hardware mechanism for fast synchronization + of threads across a large system which avoids bouncing a cacheline + between several cores on a system + source "drivers/char/ipmi/Kconfig" config DS1620 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 4c1c584..d38ac50 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_MMTIMER) += mmtimer.o obj-$(CONFIG_VIOCONS) += viocons.o obj-$(CONFIG_VIOTAPE) += viotape.o obj-$(CONFIG_HVCS) += hvcs.o +obj-$(CONFIG_IBM_BSR) += bsr.o obj-$(CONFIG_SGI_MBCS) += mbcs.o obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o obj-$(CONFIG_BFIN_OTP) += bfin-otp.o diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c new file mode 100644 index 0000000..b650b4e --- /dev/null +++ b/drivers/char/bsr.c @@ -0,0 +1,312 @@ +/* IBM POWER Barrier Synchronization Register Driver + * + * Copyright IBM Corporation 2008 + * + * Author: Sonny Rao + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* + This driver exposes a special register which can be used for fast + synchronization across a large SMP machine. The hardware is exposed + as an array of bytes where each process will write to one of the bytes to + indicate it has finished the current stage and this update is broadcast to + all processors without having to bounce a cacheline between them. In + POWER5 and POWER6 there is one of these registers per SMP, but it is + presented in two forms; first, it is given as a whole and then as a number + of smaller registers which alias to parts of the single whole register. + This can potentially allow multiple groups of processes to each have their + own private synchronization device. + + Note that this hardware *must* be written to using *only* single byte writes. + It may be read using 1, 2, 4, or 8 byte loads which must be aligned since + this region is treated as cache-inhibited processes should also use a + full sync before and after writing to the BSR to ensure all stores and + the BSR update have made it to all chips in the system +*/ + +/* This is arbitrary number, up to Power6 it's been 17 or fewer */ +#define BSR_MAX_DEVS (32) + +struct bsr_dev { + u64 bsr_addr; /* Real address */ + u64 bsr_len; /* length of mem region we can map */ + unsigned bsr_bytes; /* size of the BSR reg itself */ + unsigned bsr_stride; /* interval at which BSR repeats in the page */ + unsigned bsr_type; /* maps to enum below */ + unsigned bsr_num; /* bsr id number for its type */ + int bsr_minor; + + dev_t bsr_dev; + struct cdev bsr_cdev; + struct device *bsr_device; + char bsr_name[32]; + +}; + +static unsigned num_bsr_devs; +static struct bsr_dev *bsr_devs; +static struct class *bsr_class; +static int bsr_major; + +enum { + BSR_8 = 0, + BSR_16 = 1, + BSR_64 = 2, + BSR_128 = 3, + BSR_UNKNOWN = 4, + BSR_MAX = 5, +}; + +static unsigned bsr_types[BSR_MAX]; + +static ssize_t +bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bsr_dev *bsr_dev = dev_get_drvdata(dev); + return sprintf(buf, "%u\n", bsr_dev->bsr_bytes); +} + +static ssize_t +bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bsr_dev *bsr_dev = dev_get_drvdata(dev); + return sprintf(buf, "%u\n", bsr_dev->bsr_stride); +} + +static ssize_t +bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bsr_dev *bsr_dev = dev_get_drvdata(dev); + return sprintf(buf, "%lu\n", bsr_dev->bsr_len); +} + +static struct device_attribute bsr_dev_attrs[] = { + __ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL), + __ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL), + __ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL), + __ATTR_NULL +}; + +static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long size = vma->vm_end - vma->vm_start; + struct bsr_dev *dev = filp->private_data; + + if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) + return -EINVAL; + + vma->vm_flags |= (VM_IO | VM_DONTEXPAND); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, + size, vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} + +static int bsr_open(struct inode * inode, struct file * filp) +{ + struct cdev *cdev = inode->i_cdev; + struct bsr_dev *dev = container_of(cdev, struct bsr_dev, bsr_cdev); + + filp->private_data = dev; + return 0; +} + +const static struct file_operations bsr_fops = { + .owner = THIS_MODULE, + .mmap = bsr_mmap, + .open = bsr_open, +}; + +static void bsr_cleanup_devs(void) +{ + int i; + for (i=0 ; i < num_bsr_devs; i++) { + struct bsr_dev *cur = bsr_devs + i; + if (cur->bsr_device) { + cdev_del(&cur->bsr_cdev); + device_del(cur->bsr_device); + } + } + + kfree(bsr_devs); +} + +static int bsr_create_devs(struct device_node *bn) +{ + int bsr_stride_len, bsr_bytes_len; + const u32 *bsr_stride; + const u32 *bsr_bytes; + unsigned i; + + bsr_stride = of_get_property(bn, "ibm,lock-stride", &bsr_stride_len); + bsr_bytes = of_get_property(bn, "ibm,#lock-bytes", &bsr_bytes_len); + + if (!bsr_stride || !bsr_bytes || + (bsr_stride_len != bsr_bytes_len)) { + printk(KERN_ERR "bsr of-node has missing/incorrect property\n"); + return -ENODEV; + } + + num_bsr_devs = bsr_bytes_len / sizeof(u32); + + /* only a warning, its informational since we'll fail and exit */ + WARN_ON(num_bsr_devs > BSR_MAX_DEVS); + + bsr_devs = kzalloc(sizeof(struct bsr_dev) * num_bsr_devs, GFP_KERNEL); + if (!bsr_devs) + return -ENOMEM; + + for (i = 0 ; i < num_bsr_devs; i++) { + struct bsr_dev *cur = bsr_devs + i; + struct resource res; + int result; + + result = of_address_to_resource(bn, i, &res); + if (result < 0) { + printk(KERN_ERR "bsr of-node has invalid reg property\n"); + goto out_err; + } + + cur->bsr_minor = i; + cur->bsr_addr = res.start; + cur->bsr_len = res.end - res.start + 1; + cur->bsr_bytes = bsr_bytes[i]; + cur->bsr_stride = bsr_stride[i]; + cur->bsr_dev = MKDEV(bsr_major, i); + + switch(cur->bsr_bytes) { + case 8: + cur->bsr_type = BSR_8; + break; + case 16: + cur->bsr_type = BSR_16; + break; + case 64: + cur->bsr_type = BSR_64; + break; + case 128: + cur->bsr_type = BSR_128; + break; + default: + cur->bsr_type = BSR_UNKNOWN; + printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); + } + + cur->bsr_num = bsr_types[cur->bsr_type]; + bsr_types[cur->bsr_type] = cur->bsr_num + 1; + snprintf(cur->bsr_name, 32, "bsr%d_%d", + cur->bsr_bytes, cur->bsr_num); + + cdev_init(&cur->bsr_cdev, &bsr_fops); + result = cdev_add(&cur->bsr_cdev, cur->bsr_dev, 1); + if (result) + goto out_err; + + cur->bsr_device = device_create_drvdata(bsr_class, NULL, + cur->bsr_dev, + cur, cur->bsr_name); + if (!cur->bsr_device) { + printk(KERN_ERR "device_create failed for %s\n", + cur->bsr_name); + cdev_del(&cur->bsr_cdev); + goto out_err; + } + } + + return 0; + + out_err: + + bsr_cleanup_devs(); + return -ENODEV; +} + +static int __init bsr_init(void) +{ + struct device_node *np; + dev_t bsr_dev = MKDEV(bsr_major, 0); + int ret = -ENODEV; + int result; + + np = of_find_compatible_node(NULL, "ibm,bsr", "ibm,bsr"); + if (!np) + goto out_err; + + bsr_class = class_create(THIS_MODULE, "bsr"); + if (IS_ERR(bsr_class)) { + printk(KERN_ERR "class_create() failed for bsr_class\n"); + goto out_err_1; + } + bsr_class->dev_attrs = bsr_dev_attrs; + + result = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr"); + bsr_major = MAJOR(bsr_dev); + if (result < 0) { + printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n"); + goto out_err_2; + } + + if ((ret = bsr_create_devs(np)) < 0) + goto out_err_3; + + of_node_put(np); + + return 0; + + out_err_3: + unregister_chrdev_region(bsr_dev, BSR_MAX_DEVS); + + out_err_2: + class_destroy(bsr_class); + + out_err_1: + of_node_put(np); + + out_err: + + return ret; +} + +static void __exit bsr_exit(void) +{ + + bsr_cleanup_devs(); + + if (bsr_class) + class_destroy(bsr_class); + + if (bsr_major) + unregister_chrdev_region(MKDEV(bsr_major, 0), BSR_MAX_DEVS); +} + +module_init(bsr_init); +module_exit(bsr_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sonny Rao "); -- cgit v0.10.2 From 0f47331475201c7785454030a9976c8ac902a35d Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Thu, 10 Jul 2008 01:06:57 +1000 Subject: powerpc: Add PPC_FEATURE_PSERIES_PERFMON_COMPAT Background from Maynard Johnson: As of POWER6, a set of 32 common events is defined that must be supported on all future POWER processors. The main impetus for this compat set is the need to support partition migration, especially from processor P(n) to processor P(n+1), where performance software that's running in the new partition may not be knowledgeable about processor P(n+1). If a performance tool determines it does not support the physical processor, but is told (via the PPC_FEATURE_PSERIES_PERFMON_COMPAT bit) that the processor supports the notion of the PMU compat set, then the performance tool can surface just those events to the user of the tool. PPC_FEATURE_PSERIES_PERFMON_COMPAT indicates that the PMU supports at least this basic subset of events which is compatible across POWER processor lines. Signed-off-by: Nathan Lynch Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 72adb19..f7f3c21 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -70,10 +70,12 @@ extern void __restore_cpu_power7(void); PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) #define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\ PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \ - PPC_FEATURE_TRUE_LE) + PPC_FEATURE_TRUE_LE | \ + PPC_FEATURE_PSERIES_PERFMON_COMPAT) #define COMMON_USER_POWER7 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_06 |\ PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \ - PPC_FEATURE_TRUE_LE) + PPC_FEATURE_TRUE_LE | \ + PPC_FEATURE_PSERIES_PERFMON_COMPAT) #define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ PPC_FEATURE_TRUE_LE | \ PPC_FEATURE_HAS_ALTIVEC_COMP) diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 4fd7689..2a3e907 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -27,6 +27,9 @@ #define PPC_FEATURE_ARCH_2_06 0x00000100 #define PPC_FEATURE_HAS_VSX 0x00000080 +#define PPC_FEATURE_PSERIES_PERFMON_COMPAT \ + 0x00000040 + #define PPC_FEATURE_TRUE_LE 0x00000002 #define PPC_FEATURE_PPC_LE 0x00000001 -- cgit v0.10.2 From 443dcac4d89622cbfc61f53523007979879d6f8e Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Thu, 10 Jul 2008 01:28:07 +1000 Subject: powerpc: Remove unnecessary condition when sanity-checking WIMG bits It is okay for both _PAGE_GUARDED and _PAGE_COHERENT (G and M) to be set in the same pte. In fact, even if that were not the case, there doesn't seem to be any place where G is set without also setting I (_PAGE_NO_CACHE), so the test for I is sufficient as a condition to clear _PAGE_COHERENT when filling the hash table. Signed-off-by: Dave Kleikamp Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c index 81467ff..2e67bd8 100644 --- a/arch/powerpc/platforms/cell/beat_htab.c +++ b/arch/powerpc/platforms/cell/beat_htab.c @@ -112,7 +112,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, if (!(vflags & HPTE_V_BOLTED)) DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); - if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + if (rflags & _PAGE_NO_CACHE) hpte_r &= ~_PAGE_COHERENT; spin_lock(&beat_htab_lock); @@ -334,7 +334,7 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, if (!(vflags & HPTE_V_BOLTED)) DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); - if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + if (rflags & _PAGE_NO_CACHE) hpte_r &= ~_PAGE_COHERENT; /* insert into not-volted entry */ diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 38b5927..52a80e5 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -305,8 +305,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, flags = 0; /* Make pHyp happy */ - if ((rflags & _PAGE_GUARDED) || - ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))) + if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU)) hpte_r &= ~_PAGE_COHERENT; lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); -- cgit v0.10.2 From 01f4b8b8b8db09b88be7df7e51192e4e678b69d3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 11 Jul 2008 00:08:18 +1000 Subject: powerpc: support for latencytop Implement save_stack_trace_tsk on powerpc, so that we can run with latencytop. Signed-off-by: Arnd Bergmann Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index aaf9989..5e21854 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -53,6 +53,9 @@ config STACKTRACE_SUPPORT bool default y +config HAVE_LATENCYTOP_SUPPORT + def_bool y + config TRACE_IRQFLAGS_SUPPORT bool depends on PPC64 diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index 9629440..6a4fb00 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -10,33 +10,34 @@ * 2 of the License, or (at your option) any later version. */ +#include #include #include #include +#include /* * Save stack-backtrace addresses into a stack_trace buffer. */ -void save_stack_trace(struct stack_trace *trace) +static void save_context_stack(struct stack_trace *trace, unsigned long sp, + struct task_struct *tsk, int savesched) { - unsigned long sp; - - asm("mr %0,1" : "=r" (sp)); - for (;;) { unsigned long *stack = (unsigned long *) sp; unsigned long newsp, ip; - if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) + if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD)) return; newsp = stack[0]; ip = stack[STACK_FRAME_LR_SAVE]; - if (!trace->skip) - trace->entries[trace->nr_entries++] = ip; - else - trace->skip--; + if (savesched || !in_sched_functions(ip)) { + if (!trace->skip) + trace->entries[trace->nr_entries++] = ip; + else + trace->skip--; + } if (trace->nr_entries >= trace->max_entries) return; @@ -44,3 +45,19 @@ void save_stack_trace(struct stack_trace *trace) sp = newsp; } } + +void save_stack_trace(struct stack_trace *trace) +{ + unsigned long sp; + + asm("mr %0,1" : "=r" (sp)); + + save_context_stack(trace, sp, current, 1); +} +EXPORT_SYMBOL_GPL(save_stack_trace); + +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + save_context_stack(trace, tsk->thread.regs->gpr[1], tsk, 0); +} +EXPORT_SYMBOL_GPL(save_stack_trace_tsk); -- cgit v0.10.2 From 7c29217096d83f657e6ee70479af09b46f4275f6 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Jul 2008 16:29:12 +1000 Subject: powerpc: fix giveup_vsx to save registers correctly giveup_vsx didn't save the FPU and VMX regsiters. Change it to be like giveup_fpr/altivec which save these registers. Also update call sites where FPU and VMX are already saved to use the original giveup_vsx (renamed to __giveup_vsx). Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 31b9026..4dd70cf 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -508,12 +508,12 @@ _GLOBAL(giveup_altivec) #ifdef CONFIG_VSX /* - * giveup_vsx(tsk) - * Disable VSX for the task given as the argument, - * and save the vector registers in its thread_struct. + * __giveup_vsx(tsk) + * Disable VSX for the task given as the argument. + * Does NOT save vsx registers. * Enables the VSX for use in the kernel on return. */ -_GLOBAL(giveup_vsx) +_GLOBAL(__giveup_vsx) mfmsr r5 oris r5,r5,MSR_VSX@h mtmsrd r5 /* enable use of VSX now */ diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 0a4eb08..219f363 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -159,6 +159,13 @@ void enable_kernel_vsx(void) EXPORT_SYMBOL(enable_kernel_vsx); #endif +void giveup_vsx(struct task_struct *tsk) +{ + giveup_fpu(tsk); + giveup_altivec(tsk); + __giveup_vsx(tsk); +} + void flush_vsx_to_thread(struct task_struct *tsk) { if (tsk->thread.regs) { @@ -290,7 +297,8 @@ struct task_struct *__switch_to(struct task_struct *prev, #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX if (prev->thread.regs && (prev->thread.regs->msr & MSR_VSX)) - giveup_vsx(prev); + /* VMX and FPU registers are already save here */ + __giveup_vsx(prev); #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 6f6810d..3e80aa3 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -452,7 +452,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr) { - flush_vsx_to_thread(current); + __giveup_vsx(current); if (copy_vsx_to_user(&frame->mc_vsregs, current)) return 1; msr |= MSR_VSX; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 5f9d2ef..65ad925 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -122,7 +122,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, * VMX data. */ if (current->thread.used_vsr) { - flush_vsx_to_thread(current); + __giveup_vsx(current); v_regs += ELF_NVRREG; err |= copy_vsx_to_user(v_regs, current); /* set MSR_VSX in the MSR value in the frame to diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index 0c12c66..e6e25e2 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h @@ -139,6 +139,7 @@ extern void enable_kernel_altivec(void); extern void giveup_altivec(struct task_struct *); extern void load_up_altivec(struct task_struct *); extern int emulate_altivec(struct pt_regs *); +extern void __giveup_vsx(struct task_struct *); extern void giveup_vsx(struct task_struct *); extern void enable_kernel_spe(void); extern void giveup_spe(struct task_struct *); -- cgit v0.10.2 From cd6f37be7fdc9fea407379745350f6630b9d3cdd Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Jul 2008 16:31:09 +1000 Subject: powerpc: Add VSX load/store alignment exception handler VSX loads and stores will take an alignment exception when the address is not on a 4 byte boundary. This add support for these alignment exceptions and will emulate the requested load or store. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index f22b5d0..3671297 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -48,6 +48,7 @@ struct aligninfo { #define HARD 0x80 /* string, stwcx. */ #define E4 0x40 /* SPE endianness is word */ #define E8 0x80 /* SPE endianness is double word */ +#define SPLT 0x80 /* VSX SPLAT load */ /* DSISR bits reported for a DCBZ instruction: */ #define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */ @@ -637,6 +638,36 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, } #endif /* CONFIG_SPE */ +#ifdef CONFIG_VSX +/* + * Emulate VSX instructions... + */ +static int emulate_vsx(unsigned char __user *addr, unsigned int reg, + unsigned int areg, struct pt_regs *regs, + unsigned int flags, unsigned int length) +{ + char *ptr = (char *) ¤t->thread.TS_FPR(reg); + int ret; + + flush_vsx_to_thread(current); + + if (flags & ST) + ret = __copy_to_user(addr, ptr, length); + else { + if (flags & SPLT){ + ret = __copy_from_user(ptr, addr, length); + ptr += length; + } + ret |= __copy_from_user(ptr, addr, length); + } + if (flags & U) + regs->gpr[areg] = regs->dar; + if (ret) + return -EFAULT; + return 1; +} +#endif + /* * Called on alignment exception. Attempts to fixup * @@ -647,7 +678,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, int fix_alignment(struct pt_regs *regs) { - unsigned int instr, nb, flags; + unsigned int instr, nb, flags, instruction = 0; unsigned int reg, areg; unsigned int dsisr; unsigned char __user *addr; @@ -689,6 +720,7 @@ int fix_alignment(struct pt_regs *regs) if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE)) instr = cpu_to_le32(instr); dsisr = make_dsisr(instr); + instruction = instr; } /* extract the operation and registers from the dsisr */ @@ -728,6 +760,30 @@ int fix_alignment(struct pt_regs *regs) /* DAR has the operand effective address */ addr = (unsigned char __user *)regs->dar; +#ifdef CONFIG_VSX + if ((instruction & 0xfc00003e) == 0x7c000018) { + /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */ + reg |= (instruction & 0x1) << 5; + /* Simple inline decoder instead of a table */ + if (instruction & 0x200) + nb = 16; + else if (instruction & 0x080) + nb = 8; + else + nb = 4; + flags = 0; + if (instruction & 0x100) + flags |= ST; + if (instruction & 0x040) + flags |= U; + /* splat load needs a special decoder */ + if ((instruction & 0x400) == 0){ + flags |= SPLT; + nb = 8; + } + return emulate_vsx(addr, reg, areg, regs, flags, nb); + } +#endif /* A size of 0 indicates an instruction we don't support, with * the exception of DCBZ which is handled as a special case here */ -- cgit v0.10.2 From b6f6b98a4e91fcf31db7de54c3aa86252fc6fb5f Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Sat, 12 Jul 2008 09:00:26 +1000 Subject: powerpc: Don't spin on sync instruction at boot time Push the sync below the secondary smp init hold loop and comment its purpose. This should speed up boot by reducing global traffic during the single-threaded portion of boot. Signed-off-by: Sonny Rao Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index ecced1e..cc8fb47 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1198,7 +1198,6 @@ _GLOBAL(generic_secondary_smp_init) 3: HMT_LOW lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ /* start. */ - sync #ifndef CONFIG_SMP b 3b /* Never go on non-SMP */ @@ -1206,6 +1205,8 @@ _GLOBAL(generic_secondary_smp_init) cmpwi 0,r23,0 beq 3b /* Loop until told to go */ + sync /* order paca.run and cur_cpu_spec */ + /* See if we need to call a cpu state restore handler */ LOAD_REG_IMMEDIATE(r23, cur_cpu_spec) ld r23,0(r23) -- cgit v0.10.2 From 004ea683d96ff51131789e78a3de7dafcdbf912d Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Wed, 9 Jul 2008 01:03:06 +1000 Subject: ibm_newemac: Add MII mode support to the EMAC RGMII bridge. This patch adds support to the RGMII handler in the EMAC driver for the MII PHY mode such that device tree entries of the form `phy-mode = "mii";' are recognized and handled appropriately. While logically, in software, "gmii" and "mii" modes are the same, they are wired differently, so it makes sense to allow DTS authors to specify each explicitly. Signed-off-by: Grant Erickson Acked-by: Stefan Roese Acked-by: Benjamin Herrenschmidt Acked-by: Jeff Garzik Signed-off-by: Benjamin Herrenschmidt diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index e32da3d..1d5379d 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -39,6 +39,7 @@ #define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) #define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) #define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) +#define RGMII_FER_MII(idx) RGMII_FER_GMII(idx) /* RGMIIx_SSR */ #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) @@ -49,6 +50,7 @@ static inline int rgmii_valid_mode(int phy_mode) { return phy_mode == PHY_MODE_GMII || + phy_mode == PHY_MODE_MII || phy_mode == PHY_MODE_RGMII || phy_mode == PHY_MODE_TBI || phy_mode == PHY_MODE_RTBI; @@ -63,6 +65,8 @@ static inline const char *rgmii_mode_name(int mode) return "TBI"; case PHY_MODE_GMII: return "GMII"; + case PHY_MODE_MII: + return "MII"; case PHY_MODE_RTBI: return "RTBI"; default: @@ -79,6 +83,8 @@ static inline u32 rgmii_mode_mask(int mode, int input) return RGMII_FER_TBI(input); case PHY_MODE_GMII: return RGMII_FER_GMII(input); + case PHY_MODE_MII: + return RGMII_FER_MII(input); case PHY_MODE_RTBI: return RGMII_FER_RTBI(input); default: -- cgit v0.10.2 From ad1f8bf073e1c1996bb37b669352e3d7b1eb2b1f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 14 Jul 2008 18:13:10 -0700 Subject: Fix accidental reference to tg3 firmware We're not updating the tg3 driver to use request_firmware() yet, but a reference to its firmware accidentally slipped in as part of commit c4667746 ("dabusb: use request_firmware()"). Remove it again. Signed-off-by: David Woodhouse Reported-by: Yinghai Lu Signed-off-by: Linus Torvalds diff --git a/firmware/Makefile b/firmware/Makefile index 809a526..e4f2fb3 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -34,8 +34,6 @@ fw-shipped-$(CONFIG_SND_SB16_CSP) += sb16/mulaw_main.csp sb16/alaw_main.csp \ sb16/ima_adpcm_capture.csp fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ yamaha/ds1e_ctrl.fw -fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \ - tigon/tg3_tso5.bin fw-shipped-$(CONFIG_USB_DABUSB) += dabusb/firmware.fw dabusb/bitstream.bin fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ emi26/bitstream.fw -- cgit v0.10.2 From 4d3702b62e004172f44870763cf56793d8de0cbf Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 18:11:23 -0700 Subject: x86: Rename "ignore" macro in to avoid collision Commit 70f1bba4 ("x86: use ignore macro instead of hash comment") breaks the 64-bit x86 build on toolchains that have CONFIG_AS_CFI undefined with: arch/x86/lib/csum-copy_64.S:48: Error: Macro `ignore' was already defined because now uses the ignore macro name itself. Fix this by changing to __cfi_ignore in dwarf2.h. Signed-off-by: Roland Dreier Signed-off-by: Linus Torvalds diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h index 0bfe250..fd4a6a0 100644 --- a/include/asm-x86/dwarf2.h +++ b/include/asm-x86/dwarf2.h @@ -38,23 +38,23 @@ /* Due to the structure of pre-exisiting code, don't use assembler line comment character # to ignore the arguments. Instead, use a dummy macro. */ -.macro ignore a=0, b=0, c=0, d=0 +.macro __cfi_ignore a=0, b=0, c=0, d=0 .endm -#define CFI_STARTPROC ignore -#define CFI_ENDPROC ignore -#define CFI_DEF_CFA ignore -#define CFI_DEF_CFA_REGISTER ignore -#define CFI_DEF_CFA_OFFSET ignore -#define CFI_ADJUST_CFA_OFFSET ignore -#define CFI_OFFSET ignore -#define CFI_REL_OFFSET ignore -#define CFI_REGISTER ignore -#define CFI_RESTORE ignore -#define CFI_REMEMBER_STATE ignore -#define CFI_RESTORE_STATE ignore -#define CFI_UNDEFINED ignore -#define CFI_SIGNAL_FRAME ignore +#define CFI_STARTPROC __cfi_ignore +#define CFI_ENDPROC __cfi_ignore +#define CFI_DEF_CFA __cfi_ignore +#define CFI_DEF_CFA_REGISTER __cfi_ignore +#define CFI_DEF_CFA_OFFSET __cfi_ignore +#define CFI_ADJUST_CFA_OFFSET __cfi_ignore +#define CFI_OFFSET __cfi_ignore +#define CFI_REL_OFFSET __cfi_ignore +#define CFI_REGISTER __cfi_ignore +#define CFI_RESTORE __cfi_ignore +#define CFI_REMEMBER_STATE __cfi_ignore +#define CFI_RESTORE_STATE __cfi_ignore +#define CFI_UNDEFINED __cfi_ignore +#define CFI_SIGNAL_FRAME __cfi_ignore #endif -- cgit v0.10.2 From 7ff86b0317bc40c665aab62f3b7669713ade07c5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 16 Jul 2008 02:20:11 +0200 Subject: powerpc: Fix a build problem on ppc32 with new DMA_ATTRs The new dma_attrs support must only be enabled for 64 bits as it's not been implemented for 32 bits yet. Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5e21854..06b7277 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -113,7 +113,7 @@ config PPC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_LMB - select HAVE_DMA_ATTRS + select HAVE_DMA_ATTRS if PPC64 config EARLY_PRINTK bool -- cgit v0.10.2 From 585583d95c5660973bc0cf64add517b040acd8a4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 14 Jul 2008 08:08:45 -0500 Subject: powerpc: Fix pte_update for CONFIG_PTE_64BIT and !PTE_ATOMIC_UPDATES Because the pte is now 64-bits the compiler was optimizing the update to always clear the upper 32-bits of the pte. We need to ensure the clr mask is treated as an unsigned long long to get the proper behavior. Signed-off-by: Kumar Gala Acked-by: Josh Boyer Signed-off-by: Benjamin Herrenschmidt diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h index 11eede4..73015f0 100644 --- a/include/asm-powerpc/pgtable-ppc32.h +++ b/include/asm-powerpc/pgtable-ppc32.h @@ -624,7 +624,7 @@ static inline unsigned long long pte_update(pte_t *p, : "cc" ); #else /* PTE_ATOMIC_UPDATES */ unsigned long long old = pte_val(*p); - *p = __pte((old & ~clr) | set); + *p = __pte((old & ~(unsigned long long)clr) | set); #endif /* !PTE_ATOMIC_UPDATES */ #ifdef CONFIG_44x -- cgit v0.10.2 From 242e3df80b8d25ed681c278512df0993725f25dd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 15 Jul 2008 15:48:05 +1000 Subject: drm/radeon: fixup issue with radeon and PAT support. With new userspace libpciaccess we can get a conflicting mapping on the PCIE GART table in the video RAM. Always try and map it _wc. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index 845081b4..0177012 100644 --- a/drivers/gpu/drm/drm_memory.c +++ b/drivers/gpu/drm/drm_memory.c @@ -167,6 +167,11 @@ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) } EXPORT_SYMBOL(drm_core_ioremap); +void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev) +{ + 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 --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index e53158f..f0de81a 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -1154,7 +1154,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) dev_priv->gart_info.mapping.size = dev_priv->gart_info.table_size; - drm_core_ioremap(&dev_priv->gart_info.mapping, dev); + drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); dev_priv->gart_info.addr = dev_priv->gart_info.mapping.handle; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0764b66..1c1b13e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1089,6 +1089,7 @@ extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size); extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size); extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); +extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, -- cgit v0.10.2 From 9527056630b68c94b94b94cd58c6cbb65e611fd1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 17:58:44 +0300 Subject: MAINTAINERS: add UBIFS section Signed-off-by: Artem Bityutskiy diff --git a/MAINTAINERS b/MAINTAINERS index 56a2f67..3882f9c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2307,6 +2307,16 @@ L: linux-mtd@lists.infradead.org W: http://www.linux-mtd.infradead.org/doc/jffs2.html S: Maintained +UBI FILE SYSTEM (UBIFS) +P: Artem Bityutskiy +M: dedekind@infradead.org +P: Adrian Hunter +M: ext-adrian.hunter@nokia.com +L: linux-mtd@lists.infradead.org +T: git git://git.infradead.org/~dedekind/ubifs-2.6.git +W: http://www.linux-mtd.infradead.org/doc/ubifs.html +S: Maintained + JFS FILESYSTEM P: Dave Kleikamp M: shaggy@austin.ibm.com -- cgit v0.10.2 From e56a99d5a42dcb91e622ae7a0289d8fb2ddabffb Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 19:08:34 +0300 Subject: UBIFS: add brief documentation Signed-off-by: Artem Bityutskiy Signed-off-by: Adrian Hunter diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt new file mode 100644 index 0000000..540e9e7 --- /dev/null +++ b/Documentation/filesystems/ubifs.txt @@ -0,0 +1,164 @@ +Introduction +============= + +UBIFS file-system stands for UBI File System. UBI stands for "Unsorted +Block Images". UBIFS is a flash file system, which means it is designed +to work with flash devices. It is important to understand, that UBIFS +is completely different to any traditional file-system in Linux, like +Ext2, XFS, JFS, etc. UBIFS represents a separate class of file-systems +which work with MTD devices, not block devices. The other Linux +file-system of this class is JFFS2. + +To make it more clear, here is a small comparison of MTD devices and +block devices. + +1 MTD devices represent flash devices and they consist of eraseblocks of + rather large size, typically about 128KiB. Block devices consist of + small blocks, typically 512 bytes. +2 MTD devices support 3 main operations - read from some offset within an + eraseblock, write to some offset within an eraseblock, and erase a whole + eraseblock. Block devices support 2 main operations - read a whole + block and write a whole block. +3 The whole eraseblock has to be erased before it becomes possible to + re-write its contents. Blocks may be just re-written. +4 Eraseblocks become worn out after some number of erase cycles - + typically 100K-1G for SLC NAND and NOR flashes, and 1K-10K for MLC + NAND flashes. Blocks do not have the wear-out property. +5 Eraseblocks may become bad (only on NAND flashes) and software should + deal with this. Blocks on hard drives typically do not become bad, + because hardware has mechanisms to substitute bad blocks, at least in + modern LBA disks. + +It should be quite obvious why UBIFS is very different to traditional +file-systems. + +UBIFS works on top of UBI. UBI is a separate software layer which may be +found in drivers/mtd/ubi. UBI is basically a volume management and +wear-leveling layer. It provides so called UBI volumes which is a higher +level abstraction than a MTD device. The programming model of UBI devices +is very similar to MTD devices - they still consist of large eraseblocks, +they have read/write/erase operations, but UBI devices are devoid of +limitations like wear and bad blocks (items 4 and 5 in the above list). + +In a sense, UBIFS is a next generation of JFFS2 file-system, but it is +very different and incompatible to JFFS2. The following are the main +differences. + +* JFFS2 works on top of MTD devices, UBIFS depends on UBI and works on + top of UBI volumes. +* JFFS2 does not have on-media index and has to build it while mounting, + which requires full media scan. UBIFS maintains the FS indexing + information on the flash media and does not require full media scan, + so it mounts many times faster than JFFS2. +* JFFS2 is a write-through file-system, while UBIFS supports write-back, + which makes UBIFS much faster on writes. + +Similarly to JFFS2, UBIFS supports on-the-flight compression which makes +it possible to fit quite a lot of data to the flash. + +Similarly to JFFS2, UBIFS is tolerant of unclean reboots and power-cuts. +It does not need stuff like ckfs.ext2. UBIFS automatically replays its +journal and recovers from crashes, ensuring that the on-flash data +structures are consistent. + +UBIFS scales logarithmically (most of the data structures it uses are +trees), so the mount time and memory consumption do not linearly depend +on the flash size, like in case of JFFS2. This is because UBIFS +maintains the FS index on the flash media. However, UBIFS depends on +UBI, which scales linearly. So overall UBI/UBIFS stack scales linearly. +Nevertheless, UBI/UBIFS scales considerably better than JFFS2. + +The authors of UBIFS believe, that it is possible to develop UBI2 which +would scale logarithmically as well. UBI2 would support the same API as UBI, +but it would be binary incompatible to UBI. So UBIFS would not need to be +changed to use UBI2 + + +Mount options +============= + +(*) == 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. + + +Quick usage instructions +======================== + +The UBI volume to mount is specified using "ubiX_Y" or "ubiX:NAME" syntax, +where "X" is UBI device number, "Y" is UBI volume number, and "NAME" is +UBI volume name. + +Mount volume 0 on UBI device 0 to /mnt/ubifs: +$ mount -t ubifs ubi0_0 /mnt/ubifs + +Mount "rootfs" volume of UBI device 0 to /mnt/ubifs ("rootfs" is volume +name): +$ mount -t ubifs ubi0:rootfs /mnt/ubifs + +The following is an example of the kernel boot arguments to attach mtd0 +to UBI and mount volume "rootfs": +ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs + + +Module Parameters for Debugging +=============================== + +When UBIFS has been compiled with debugging enabled, there are 3 module +parameters that are available to control aspects of testing and debugging. +The parameters are unsigned integers where each bit controls an option. +The parameters are: + +debug_msgs Selects which debug messages to display, as follows: + + Message Type Flag value + + General messages 1 + Journal messages 2 + Mount messages 4 + Commit messages 8 + LEB search messages 16 + Budgeting messages 32 + Garbage collection messages 64 + Tree Node Cache (TNC) messages 128 + LEB properties (lprops) messages 256 + Input/output messages 512 + Log messages 1024 + Scan messages 2048 + Recovery messages 4096 + +debug_chks Selects extra checks that UBIFS can do while running: + + Check Flag value + + General checks 1 + Check Tree Node Cache (TNC) 2 + Check indexing tree size 4 + Check orphan area 8 + Check old indexing tree 16 + Check LEB properties (lprops) 32 + Check leaf nodes and inodes 64 + +debug_tsts Selects a mode of testing, as follows: + + Test mode Flag value + + Force in-the-gaps method 2 + Failure mode for recovery testing 4 + +For example, set debug_msgs to 5 to display General messages and Mount +messages. + + +References +========== + +UBIFS documentation and FAQ/HOWTO at the MTD web site: +http://www.linux-mtd.infradead.org/doc/ubifs.html +http://www.linux-mtd.infradead.org/faq/ubifs.html -- cgit v0.10.2 From 969a60f9db3f879f95bd37026a3c3bf02cc2568f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: IB/srp: Remove use of cached P_Key/GID queries The SRP initiator is currently using ib_find_cached_pkey() and ib_get_cached_gid() in situations where the uncached ib_find_pkey() and ib_query_gid() functions serve just as well: sleeping is allowed and performance is not an issue. Since we want to eliminate the cached operations in the long term, convert SRP to use the uncached variants. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 4351457..81cc59c 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -49,8 +49,6 @@ #include #include -#include - #include "ib_srp.h" #define DRV_NAME "ib_srp" @@ -183,10 +181,10 @@ static int srp_init_qp(struct srp_target_port *target, if (!attr) return -ENOMEM; - ret = ib_find_cached_pkey(target->srp_host->srp_dev->dev, - target->srp_host->port, - be16_to_cpu(target->path.pkey), - &attr->pkey_index); + ret = ib_find_pkey(target->srp_host->srp_dev->dev, + target->srp_host->port, + be16_to_cpu(target->path.pkey), + &attr->pkey_index); if (ret) goto out; @@ -1883,8 +1881,7 @@ static ssize_t srp_create_target(struct device *dev, if (ret) goto err; - ib_get_cached_gid(host->srp_dev->dev, host->port, 0, - &target->path.sgid); + ib_query_gid(host->srp_dev->dev, host->port, 0, &target->path.sgid); shost_printk(KERN_DEBUG, target->scsi_host, PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x " -- cgit v0.10.2 From 929555a2baed9b0b050d03532655bfd721a43c44 Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: RDMA/nes: Remove unnecessary memset() Remove an explicit memset(..., 0, ...) of a 'listener' structure allocated with kzalloc(). Signed-off-by: Christophe Jaillet Acked-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 9a4b40f..6aa531d 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1603,7 +1603,6 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core, return NULL; } - memset(listener, 0, sizeof(struct nes_cm_listener)); listener->loc_addr = htonl(cm_info->loc_addr); listener->loc_port = htons(cm_info->loc_port); listener->reused_node = 0; -- cgit v0.10.2 From a9474917099e007c0f51d5474394b5890111614f Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: RDMA: Fix license text The license text for several files references a third software license that was inadvertently copied in. Update the license to what was intended. This update was based on a request from HP. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 781ea59..e4eb8be 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -4,28 +4,33 @@ * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved. * Copyright (c) 2005 Intel Corporation. All rights reserved. * - * This Software is licensed under one of the following licenses: + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. + * - 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. * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 671f137..e5bd617 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -4,29 +4,33 @@ * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved. * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. * - * This Software is licensed under one of the following licenses: + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. + * - 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. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index c36750f..b42bdd00 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -2,29 +2,33 @@ * Copyright (c) 2005 Voltaire Inc. All rights reserved. * Copyright (c) 2005 Intel Corporation. All rights reserved. * - * This Software is licensed under one of the following licenses: + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. + * - 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. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #if !defined(IB_ADDR_H) diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index 010f876..d8f9a95 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h @@ -2,29 +2,33 @@ * Copyright (c) 2005 Voltaire Inc. All rights reserved. * Copyright (c) 2005 Intel Corporation. All rights reserved. * - * This Software is licensed under one of the following licenses: + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. + * - 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. * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #if !defined(RDMA_CM_H) diff --git a/include/rdma/rdma_cm_ib.h b/include/rdma/rdma_cm_ib.h index 950424b..2389c3b 100644 --- a/include/rdma/rdma_cm_ib.h +++ b/include/rdma/rdma_cm_ib.h @@ -1,29 +1,33 @@ /* * Copyright (c) 2006 Intel Corporation. All rights reserved. * - * This Software is licensed under one of the following licenses: - * - * 1) under the terms of the "Common Public License 1.0" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/cpl.php. - * - * 2) under the terms of the "The BSD License" a copy of which is - * available from the Open Source Initiative, see - * http://www.opensource.org/licenses/bsd-license.php. - * - * 3) under the terms of the "GNU General Public License (GPL) Version 2" a - * copy of which is available from the Open Source Initiative, see - * http://www.opensource.org/licenses/gpl-license.php. - * - * Licensee has the right to choose one of the above licenses. - * - * Redistributions of source code must retain the above copyright - * notice and one of the license notices. - * - * Redistributions in binary form must reproduce both the above copyright - * notice, one of the license notices in the documentation - * and/or other materials provided with the distribution. - * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #if !defined(RDMA_CM_IB_H) -- cgit v0.10.2 From 164ba0893c27a216557396320b6063fdac040392 Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Mon, 14 Jul 2008 23:48:43 -0700 Subject: IB/sa: Fail requests made while creating new SM AH This patch solves a race that occurs after an event occurs that causes the SA query module to flush its SM address handle (AH). When SM AH becomes invalid and needs an update it is handled by the global workqueue. On the other hand this event is also handled in the IPoIB driver by queuing work in the ipoib_workqueue that does multicast joins. Although queuing is in the right order, it is done to 2 different workqueues and so there is no guarantee that the first to be queued is the first to be executed. This causes a problem because IPoIB may end up sending an request to the old SM, which will take a long time to time out (since the old SM is gone); this leads to a much longer than necessary interruption in multicast traffer. The patch sets the SA query module's SM AH to NULL when the event occurs, and until update_sm_ah() is done, any request that needs sm_ah fails with -EAGAIN return status. For consumers, the patch doesn't make things worse. Before the patch, MADs are sent to the wrong SM so the request gets lost. Consumers can be improved if they examine the return code and respond to EAGAIN properly but even without an improvement the situation is not getting worse. Signed-off-by: Moni Levy Signed-off-by: Moni Shoua Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index cf474ec..78ea815 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -361,7 +361,7 @@ static void update_sm_ah(struct work_struct *work) { struct ib_sa_port *port = container_of(work, struct ib_sa_port, update_task); - struct ib_sa_sm_ah *new_ah, *old_ah; + struct ib_sa_sm_ah *new_ah; struct ib_port_attr port_attr; struct ib_ah_attr ah_attr; @@ -397,12 +397,9 @@ static void update_sm_ah(struct work_struct *work) } spin_lock_irq(&port->ah_lock); - old_ah = port->sm_ah; port->sm_ah = new_ah; spin_unlock_irq(&port->ah_lock); - if (old_ah) - kref_put(&old_ah->ref, free_sm_ah); } static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event) @@ -413,8 +410,17 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event event->event == IB_EVENT_PKEY_CHANGE || event->event == IB_EVENT_SM_CHANGE || event->event == IB_EVENT_CLIENT_REREGISTER) { - struct ib_sa_device *sa_dev; - sa_dev = container_of(handler, typeof(*sa_dev), event_handler); + unsigned long flags; + struct ib_sa_device *sa_dev = + container_of(handler, typeof(*sa_dev), event_handler); + struct ib_sa_port *port = + &sa_dev->port[event->element.port_num - sa_dev->start_port]; + + spin_lock_irqsave(&port->ah_lock, flags); + if (port->sm_ah) + kref_put(&port->sm_ah->ref, free_sm_ah); + port->sm_ah = NULL; + spin_unlock_irqrestore(&port->ah_lock, flags); schedule_work(&sa_dev->port[event->element.port_num - sa_dev->start_port].update_task); @@ -519,6 +525,10 @@ static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask) unsigned long flags; spin_lock_irqsave(&query->port->ah_lock, flags); + if (!query->port->sm_ah) { + spin_unlock_irqrestore(&query->port->ah_lock, flags); + return -EAGAIN; + } kref_get(&query->port->sm_ah->ref); query->sm_ah = query->port->sm_ah; spin_unlock_irqrestore(&query->port->ah_lock, flags); -- cgit v0.10.2 From 9670e553915e67fb68f13258644342c68dc26b84 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: IB/mlx4: Optimize QP stamping The idea is that for QPs with fixed size work requests (eg selective signaling QPs), before stamping the WQE, we read the value of the DS field, which gives the effective size of the descriptor as used in the previous post. Then we stamp only that area, since the rest of the descriptor is already stamped. When initializing the send queue buffer, make sure the DS field is initialized to the max descriptor size so that the subsequent stamping will be done on the entire descriptor area. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a80df22..4b0ac5d 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -129,9 +129,10 @@ static void stamp_send_wqe(struct mlx4_ib_qp *qp, int n, int size) int ind; void *buf; __be32 stamp; + struct mlx4_wqe_ctrl_seg *ctrl; - s = roundup(size, 1U << qp->sq.wqe_shift); if (qp->sq_max_wqes_per_wr > 1) { + s = roundup(size, 1U << qp->sq.wqe_shift); for (i = 0; i < s; i += 64) { ind = (i >> qp->sq.wqe_shift) + n; stamp = ind & qp->sq.wqe_cnt ? cpu_to_be32(0x7fffffff) : @@ -141,7 +142,8 @@ static void stamp_send_wqe(struct mlx4_ib_qp *qp, int n, int size) *wqe = stamp; } } else { - buf = get_send_wqe(qp, n & (qp->sq.wqe_cnt - 1)); + ctrl = buf = get_send_wqe(qp, n & (qp->sq.wqe_cnt - 1)); + s = (ctrl->fence_size & 0x3f) << 4; for (i = 64; i < s; i += 64) { wqe = buf + i; *wqe = cpu_to_be32(0xffffffff); @@ -1063,6 +1065,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, for (i = 0; i < qp->sq.wqe_cnt; ++i) { ctrl = get_send_wqe(qp, i); ctrl->owner_opcode = cpu_to_be32(1 << 31); + if (qp->sq_max_wqes_per_wr == 1) + ctrl->fence_size = 1 << (qp->sq.wqe_shift - 4); stamp_send_wqe(qp, i, 1 << qp->sq.wqe_shift); } -- cgit v0.10.2 From fd91b1bf1bb6fb443cb8c7600c7314f093b31f40 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: IB/ipath: Simplify code using ARRAY_SIZE() macro Signed-off-by: Robert P. J. Day Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c index 8eee783..fb70712 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba7220.c +++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c @@ -2228,8 +2228,8 @@ static void ipath_autoneg_send(struct ipath_devdata *dd, int which) 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000001, 0x1388, 0x15e, /* rest 0's */ }; - dcnt = sizeof(madpayload_start)/sizeof(madpayload_start[0]); - hcnt = sizeof(hdr)/sizeof(hdr[0]); + dcnt = ARRAY_SIZE(madpayload_start); + hcnt = ARRAY_SIZE(hdr); if (!swapped) { /* for maintainability, do it at runtime */ for (i = 0; i < hcnt; i++) { -- cgit v0.10.2 From 4deccd6d95f1f1536dad3c842e39c1ace577329d Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: RDMA: Improve include file coding style Remove subversion $Id lines and improve readability by fixing other coding style problems pointed out by checkpatch.pl. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier diff --git a/include/rdma/ib_cache.h b/include/rdma/ib_cache.h index f179d23..00a2b8e 100644 --- a/include/rdma/ib_cache.h +++ b/include/rdma/ib_cache.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_cache.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef _IB_CACHE_H diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h index a627c86..ec7c6d9 100644 --- a/include/rdma/ib_cm.h +++ b/include/rdma/ib_cm.h @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_cm.h 4311 2005-12-05 18:42:01Z sean.hefty $ */ #if !defined(IB_CM_H) #define IB_CM_H diff --git a/include/rdma/ib_fmr_pool.h b/include/rdma/ib_fmr_pool.h index 00dadbf..f62b842 100644 --- a/include/rdma/ib_fmr_pool.h +++ b/include/rdma/ib_fmr_pool.h @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_fmr_pool.h 2730 2005-06-28 16:43:03Z sean.hefty $ */ #if !defined(IB_FMR_POOL_H) @@ -61,7 +59,7 @@ struct ib_fmr_pool_param { int pool_size; int dirty_watermark; void (*flush_function)(struct ib_fmr_pool *pool, - void * arg); + void *arg); void *flush_arg; unsigned cache:1; }; diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 7228c05..5f6c40f 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h @@ -32,11 +32,9 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_mad.h 5596 2006-03-03 01:00:07Z sean.hefty $ */ -#if !defined( IB_MAD_H ) +#if !defined(IB_MAD_H) #define IB_MAD_H #include @@ -194,8 +192,7 @@ struct ib_vendor_mad { u8 data[IB_MGMT_VENDOR_DATA]; }; -struct ib_class_port_info -{ +struct ib_class_port_info { u8 base_version; u8 class_version; __be16 capability_mask; @@ -614,11 +611,11 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent, * any class specific header, and MAD data area. * If @rmpp_active is set, the RMPP header will be initialized for sending. */ -struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, - u32 remote_qpn, u16 pkey_index, - int rmpp_active, - int hdr_len, int data_len, - gfp_t gfp_mask); +struct ib_mad_send_buf *ib_create_send_mad(struct ib_mad_agent *mad_agent, + u32 remote_qpn, u16 pkey_index, + int rmpp_active, + int hdr_len, int data_len, + gfp_t gfp_mask); /** * ib_is_mad_class_rmpp - returns whether given management class diff --git a/include/rdma/ib_pack.h b/include/rdma/ib_pack.h index f926020..d7fc45c 100644 --- a/include/rdma/ib_pack.h +++ b/include/rdma/ib_pack.h @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_pack.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef IB_PACK_H diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index 942692b..3841c1a 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_sa.h 2811 2005-07-06 18:11:43Z halr $ */ #ifndef IB_SA_H diff --git a/include/rdma/ib_smi.h b/include/rdma/ib_smi.h index f29af13..aaca087 100644 --- a/include/rdma/ib_smi.h +++ b/include/rdma/ib_smi.h @@ -32,11 +32,9 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_smi.h 1389 2004-12-27 22:56:47Z roland $ */ -#if !defined( IB_SMI_H ) +#if !defined(IB_SMI_H) #define IB_SMI_H #include diff --git a/include/rdma/ib_user_cm.h b/include/rdma/ib_user_cm.h index 37650af..bd3d380 100644 --- a/include/rdma/ib_user_cm.h +++ b/include/rdma/ib_user_cm.h @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_user_cm.h 4019 2005-11-11 00:33:09Z sean.hefty $ */ #ifndef IB_USER_CM_H diff --git a/include/rdma/ib_user_mad.h b/include/rdma/ib_user_mad.h index 29d2c72..d6fce1c 100644 --- a/include/rdma/ib_user_mad.h +++ b/include/rdma/ib_user_mad.h @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_user_mad.h 2814 2005-07-06 19:14:09Z halr $ */ #ifndef IB_USER_MAD_H diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 8d65bf0..885254f 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_user_verbs.h 4019 2005-11-11 00:33:09Z sean.hefty $ */ #ifndef IB_USER_VERBS_H diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 31d30b1..5f5621b 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -34,8 +34,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_verbs.h 1349 2004-12-16 21:09:43Z roland $ */ #if !defined(IB_VERBS_H) @@ -777,7 +775,7 @@ struct ib_cq { struct ib_uobject *uobject; ib_comp_handler comp_handler; void (*event_handler)(struct ib_event *, void *); - void * cq_context; + void *cq_context; int cqe; atomic_t usecnt; /* count number of work queues */ }; @@ -883,7 +881,7 @@ struct ib_dma_mapping_ops { void (*sync_single_for_cpu)(struct ib_device *dev, u64 dma_handle, size_t size, - enum dma_data_direction dir); + enum dma_data_direction dir); void (*sync_single_for_device)(struct ib_device *dev, u64 dma_handle, size_t size, diff --git a/include/rdma/iw_cm.h b/include/rdma/iw_cm.h index aeefa9b..cbb822e 100644 --- a/include/rdma/iw_cm.h +++ b/include/rdma/iw_cm.h @@ -62,7 +62,7 @@ struct iw_cm_event { struct sockaddr_in remote_addr; void *private_data; u8 private_data_len; - void* provider_data; + void *provider_data; }; /** diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index d8f9a95..22bb2e7 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h @@ -61,11 +61,11 @@ enum rdma_cm_event_type { }; enum rdma_port_space { - RDMA_PS_SDP = 0x0001, - RDMA_PS_IPOIB= 0x0002, - RDMA_PS_TCP = 0x0106, - RDMA_PS_UDP = 0x0111, - RDMA_PS_SCTP = 0x0183 + RDMA_PS_SDP = 0x0001, + RDMA_PS_IPOIB = 0x0002, + RDMA_PS_TCP = 0x0106, + RDMA_PS_UDP = 0x0111, + RDMA_PS_SCTP = 0x0183 }; struct rdma_addr { -- cgit v0.10.2 From f3781d2e89f12dd5afa046dc56032af6e39bd116 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: RDMA: Remove subversion $Id tags They don't get updated by git and so they're worse than useless. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index fb9ed14..6669287 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h @@ -32,8 +32,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: agent.h 1389 2004-12-27 22:56:47Z roland $ */ #ifndef __AGENT_H_ diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index e85f701..6888356 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index a47fe64..55738ee 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: cm.c 4311 2005-12-05 18:42:01Z sean.hefty $ */ #include diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 7ad47a4..05ac36e 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: core_priv.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef _CORE_PRIV_H diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 5ac5ffe..7913b80 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: device.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index 1286dc1..4507043 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: fmr_pool.c 2730 2005-06-28 16:43:03Z sean.hefty $ */ #include diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index 8b75010..05ce331 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mad_priv.h 5596 2006-03-03 01:00:07Z sean.hefty $ */ #ifndef __IB_MAD_PRIV_H__ diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index a5e2a31..d0ef7d6 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mad_rmpp.c 1921 2005-03-02 22:58:44Z sean.hefty $ */ #include "mad_priv.h" diff --git a/drivers/infiniband/core/mad_rmpp.h b/drivers/infiniband/core/mad_rmpp.h index f0616fd..3d336bf 100644 --- a/drivers/infiniband/core/mad_rmpp.h +++ b/drivers/infiniband/core/mad_rmpp.h @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mad_rmpp.h 1921 2005-02-25 22:58:44Z sean.hefty $ */ #ifndef __MAD_RMPP_H__ diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c index c972d72..019bd4b 100644 --- a/drivers/infiniband/core/packer.c +++ b/drivers/infiniband/core/packer.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 78ea815..1341de7 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: sa_query.c 2811 2005-07-06 18:11:43Z halr $ */ #include diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 9575655..36a0ef9 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: sysfs.c 1349 2004-12-16 21:09:43Z roland $ */ #include "core_priv.h" diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index b25675f..9494005 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ucm.c 4311 2005-12-05 18:42:01Z sean.hefty $ */ #include diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c index 997c07d..8ec7876 100644 --- a/drivers/infiniband/core/ud_header.c +++ b/drivers/infiniband/core/ud_header.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ud_header.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index a1768db..6f7c096 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: uverbs_mem.c 2743 2005-06-28 22:27:59Z roland $ */ #include diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 208c7f3..268a2d2 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: user_mad.c 5596 2006-03-03 01:00:07Z sean.hefty $ */ #include diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 376a57c..b3ea958 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -32,8 +32,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: uverbs.h 2559 2005-06-06 19:43:16Z roland $ */ #ifndef UVERBS_H diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 2c3bff5..112b37c 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $ */ #include diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 0f34858..aeee856 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -32,8 +32,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: uverbs_main.c 2733 2005-06-28 19:14:34Z roland $ */ #include diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 0504208..9f399d3 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -34,8 +34,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: verbs.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c index a763067..c5ccc2d 100644 --- a/drivers/infiniband/hw/mthca/mthca_allocator.c +++ b/drivers/infiniband/hw/mthca/mthca_allocator.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_allocator.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index 4b111a8..32f6c63 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_av.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index e948158..40573e4 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id$ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 54d230e..c33e1c5 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_cmd.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h index 8928ca4..6efd326 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.h +++ b/drivers/infiniband/hw/mthca/mthca_cmd.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_cmd.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef MTHCA_CMD_H diff --git a/drivers/infiniband/hw/mthca/mthca_config_reg.h b/drivers/infiniband/hw/mthca/mthca_config_reg.h index afa56bf..75671f7 100644 --- a/drivers/infiniband/hw/mthca/mthca_config_reg.h +++ b/drivers/infiniband/hw/mthca/mthca_config_reg.h @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_config_reg.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef MTHCA_CONFIG_REG_H diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 20401d2..f788fce 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c @@ -32,8 +32,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_cq.c 1369 2004-12-20 16:17:07Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 7bc32f8..2997d8d 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -32,8 +32,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_dev.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef MTHCA_DEV_H diff --git a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h index b374dc3..14f51ef 100644 --- a/drivers/infiniband/hw/mthca/mthca_doorbell.h +++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_doorbell.h 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 8bde7f9..4e36aa7 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_eq.c 1382 2004-12-24 02:21:02Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index 8b7e83e..6404495 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 200cf13..fb9f91b 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_main.c 1396 2004-12-28 04:10:27Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index a8ad072..3f5f948 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_mcg.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index d5862e5..1f7d1a2 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id$ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h index a1ab068..da9b8f9 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/drivers/infiniband/hw/mthca/mthca_memfree.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id$ */ #ifndef MTHCA_MEMFREE_H diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 820205d..8489b1e 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_mr.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c index c1e9507..266f14e 100644 --- a/drivers/infiniband/hw/mthca/mthca_pd.c +++ b/drivers/infiniband/hw/mthca/mthca_pd.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_pd.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c index 605a8d5..d168c25 100644 --- a/drivers/infiniband/hw/mthca/mthca_profile.c +++ b/drivers/infiniband/hw/mthca/mthca_profile.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_profile.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_profile.h b/drivers/infiniband/hw/mthca/mthca_profile.h index e76cb62..62b009c 100644 --- a/drivers/infiniband/hw/mthca/mthca_profile.h +++ b/drivers/infiniband/hw/mthca/mthca_profile.h @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_profile.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef MTHCA_PROFILE_H diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index be34f99..87ad889 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -32,8 +32,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_provider.c 4859 2006-01-09 21:55:10Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h index 934bf95..c621f87 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/drivers/infiniband/hw/mthca/mthca_provider.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_provider.h 1349 2004-12-16 21:09:43Z roland $ */ #ifndef MTHCA_PROVIDER_H diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 09dc361..3b1c5ba 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_qp.c 1355 2004-12-17 15:23:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c index 91934f2..acb6817f 100644 --- a/drivers/infiniband/hw/mthca/mthca_reset.c +++ b/drivers/infiniband/hw/mthca/mthca_reset.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_reset.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index a5ffff6..4fabe62 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $ */ #include diff --git a/drivers/infiniband/hw/mthca/mthca_uar.c b/drivers/infiniband/hw/mthca/mthca_uar.c index 8b72848..ca5900c 100644 --- a/drivers/infiniband/hw/mthca/mthca_uar.c +++ b/drivers/infiniband/hw/mthca/mthca_uar.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id$ */ #include /* PAGE_SHIFT */ diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h index e1262c9..5fe56e8 100644 --- a/drivers/infiniband/hw/mthca/mthca_user.h +++ b/drivers/infiniband/hw/mthca/mthca_user.h @@ -29,7 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * */ #ifndef MTHCA_USER_H diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h index b3551a8..341a5ae 100644 --- a/drivers/infiniband/hw/mthca/mthca_wqe.h +++ b/drivers/infiniband/hw/mthca/mthca_wqe.h @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: mthca_wqe.h 3047 2005-08-10 03:59:35Z roland $ */ #ifndef MTHCA_WQE_H diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index ca126fc..0dcbab3 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib.h 1358 2004-12-17 22:00:11Z roland $ */ #ifndef _IPOIB_H diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 97e67d3..91c9592 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id$ */ #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 8b882bb..961c585 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib_fs.c 1389 2004-12-27 22:56:47Z roland $ */ #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f429bce..eca8518 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -31,8 +31,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib_ib.c 1386 2004-12-27 16:23:17Z roland $ */ #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 2442090..f217b1e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib_main.c 1377 2004-12-23 19:57:12Z roland $ */ #include "ipoib.h" diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 3f663fb..4a6538b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -30,8 +30,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib_multicast.c 1362 2004-12-18 15:56:29Z roland $ */ #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 8766d29..810790a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib_verbs.c 1349 2004-12-16 21:09:43Z roland $ */ #include "ipoib.h" diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 1cdb5cf..b08eb56 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ipoib_vlan.c 1349 2004-12-16 21:09:43Z roland $ */ #include diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index aeb58ca..356fac6 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -42,9 +42,6 @@ * Zhenyu Wang * Modified by: * Erez Zilber - * - * - * $Id: iscsi_iser.c 6965 2006-05-07 11:36:20Z ogerlitz $ */ #include diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index a8c1b30..0e10703 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -36,8 +36,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: iscsi_iser.h 7051 2006-05-10 12:29:11Z ogerlitz $ */ #ifndef __ISCSI_ISER_H__ #define __ISCSI_ISER_H__ diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 08dc81c..31ad498 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: iser_initiator.c 6964 2006-05-07 11:11:43Z ogerlitz $ */ #include #include diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index cac50c4..81e49cb 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: iser_memory.c 6964 2006-05-07 11:11:43Z ogerlitz $ */ #include #include diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index d19cfe6..77cabee 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -29,8 +29,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $ */ #include #include diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 81cc59c..ed7c5f7 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $ */ #include diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 63d2ae7..e185b90 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -28,8 +28,6 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. - * - * $Id: ib_srp.h 3932 2005-11-01 17:19:29Z roland $ */ #ifndef IB_SRP_H -- cgit v0.10.2 From f89271da32bc1a636cf4eb078e615930886cd013 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:44 -0700 Subject: IPoIB: Copy small received SKBs in connected mode The connected mode implementation in the IPoIB driver has a large overhead in the way SKBs are handled in the receive flow. It usually allocates an SKB with as big as was used in the currently received SKB and moves unused fragments from the old SKB to the new one. This involves a loop on all the remaining fragments and incurs overhead on the CPU. This patch, for small SKBs, allocates an SKB just large enough to contain the received data and copies to it the data from the received SKB. The newly allocated SKB is passed to the stack and the old SKB is reposted. When running netperf, UDP small messages, without this pach I get: UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 14.4.3.178 (14.4.3.178) port 0 AF_INET Socket Message Elapsed Messages Size Size Time Okay Errors Throughput bytes bytes secs # # 10^6bits/sec 114688 128 10.00 5142034 0 526.31 114688 10.00 1130489 115.71 With this patch I get both send and receive at ~315 mbps. The reason that send performance actually slows down is as follows: When using this patch, the overhead of the CPU for handling RX packets is dramatically reduced. As a result, we do not experience RNR NAK messages from the receiver which cause the connection to be closed and reopened again; when the patch is not used, the receiver cannot handle the packets fast enough so there is less time to post new buffers and hence the mentioned RNR NACKs. So what happens is that the application *thinks* it posted a certain number of packets for transmission but these packets are flushed and do not really get transmitted. Since the connection gets opened and closed many times, each time netperf gets the CPU time that otherwise would have been given to IPoIB to actually transmit the packets. This can be verified when looking at the port counters -- the output of ifconfig and the oputput of netperf (this is for the case without the patch): tx packets ========== port counter: 1,543,996 ifconfig: 1,581,426 netperf: 5,142,034 rx packets ========== netperf 1,1304,089 Signed-off-by: Eli Cohen diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 0dcbab3..8754b36 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -95,6 +95,7 @@ enum { IPOIB_MCAST_FLAG_ATTACHED = 3, MAX_SEND_CQE = 16, + IPOIB_CM_COPYBREAK = 256, }; #define IPOIB_OP_RECV (1ul << 31) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 91c9592..6223fc3 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -523,6 +523,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) u64 mapping[IPOIB_CM_RX_SG]; int frags; int has_srq; + struct sk_buff *small_skb; ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n", wr_id, wc->status); @@ -577,6 +578,23 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) } } + if (wc->byte_len < IPOIB_CM_COPYBREAK) { + int dlen = wc->byte_len; + + small_skb = dev_alloc_skb(dlen + 12); + if (small_skb) { + skb_reserve(small_skb, 12); + ib_dma_sync_single_for_cpu(priv->ca, rx_ring[wr_id].mapping[0], + dlen, DMA_FROM_DEVICE); + skb_copy_from_linear_data(skb, small_skb->data, dlen); + ib_dma_sync_single_for_device(priv->ca, rx_ring[wr_id].mapping[0], + dlen, DMA_FROM_DEVICE); + skb_put(small_skb, dlen); + skb = small_skb; + goto copied; + } + } + frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len, (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE; @@ -599,6 +617,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) skb_put_frags(skb, IPOIB_CM_HEAD_SIZE, wc->byte_len, newskb); +copied: skb->protocol = ((struct ipoib_header *) skb->data)->proto; skb_reset_mac_header(skb); skb_pull(skb, IPOIB_ENCAP_LEN); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index f217b1e..bfe1dbf 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1302,6 +1302,12 @@ static int __init ipoib_init_module(void) ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); #endif + /* + * When copying small received packets, we only copy from the + * linear data part of the SKB, so we rely on this condition. + */ + BUILD_BUG_ON(IPOIB_CM_COPYBREAK > IPOIB_CM_HEAD_SIZE); + ret = ipoib_register_debugfs(); if (ret) return ret; -- cgit v0.10.2 From 00f7ec36c9324928e4cd23f02e6d8550f30c32ca Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: RDMA/core: Add memory management extensions support This patch adds support for the IB "base memory management extension" (BMME) and the equivalent iWARP operations (which the iWARP verbs mandates all devices must implement). The new operations are: - Allocate an ib_mr for use in fast register work requests. - Allocate/free a physical buffer lists for use in fast register work requests. This allows device drivers to allocate this memory as needed for use in posting send requests (eg via dma_alloc_coherent). - New send queue work requests: * send with remote invalidate * fast register memory region * local invalidate memory region * RDMA read with invalidate local memory region (iWARP only) Consumer interface details: - A new device capability flag IB_DEVICE_MEM_MGT_EXTENSIONS is added to indicate device support for these features. - New send work request opcodes IB_WR_FAST_REG_MR, IB_WR_LOCAL_INV, IB_WR_RDMA_READ_WITH_INV are added. - A new consumer API function, ib_alloc_mr() is added to allocate fast register memory regions. - New consumer API functions, ib_alloc_fast_reg_page_list() and ib_free_fast_reg_page_list() are added to allocate and free device-specific memory for fast registration page lists. - A new consumer API function, ib_update_fast_reg_key(), is added to allow the key portion of the R_Key and L_Key of a fast registration MR to be updated. Consumers call this if desired before posting a IB_WR_FAST_REG_MR work request. Consumers can use this as follows: - MR is allocated with ib_alloc_mr(). - Page list memory is allocated with ib_alloc_fast_reg_page_list(). - MR R_Key/L_Key "key" field is updated with ib_update_fast_reg_key(). - MR made VALID and bound to a specific page list via ib_post_send(IB_WR_FAST_REG_MR) - MR made INVALID via ib_post_send(IB_WR_LOCAL_INV), ib_post_send(IB_WR_RDMA_READ_WITH_INV) or an incoming send with invalidate operation. - MR is deallocated with ib_dereg_mr() - page lists dealloced via ib_free_fast_reg_page_list(). Applications can allocate a fast register MR once, and then can repeatedly bind the MR to different physical block lists (PBLs) via posting work requests to a send queue (SQ). For each outstanding MR-to-PBL binding in the SQ pipe, a fast_reg_page_list needs to be allocated (the fast_reg_page_list is owned by the low-level driver from the consumer posting a work request until the request completes). Thus pipelining can be achieved while still allowing device-specific page_list processing. The 32-bit fast register memory key/STag is composed of a 24-bit index and an 8-bit key. The application can change the key each time it fast registers thus allowing more control over the peer's use of the key/STag (ie it can effectively be changed each time the rkey is rebound to a page list). Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 112b37c..56feab6 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -917,7 +917,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, resp->wc[i].opcode = wc[i].opcode; resp->wc[i].vendor_err = wc[i].vendor_err; resp->wc[i].byte_len = wc[i].byte_len; - resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data; + resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data; resp->wc[i].qp_num = wc[i].qp->qp_num; resp->wc[i].src_qp = wc[i].src_qp; resp->wc[i].wc_flags = wc[i].wc_flags; diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 9f399d3..e0fbe59 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -753,6 +753,52 @@ int ib_dereg_mr(struct ib_mr *mr) } EXPORT_SYMBOL(ib_dereg_mr); +struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len) +{ + struct ib_mr *mr; + + if (!pd->device->alloc_fast_reg_mr) + return ERR_PTR(-ENOSYS); + + mr = pd->device->alloc_fast_reg_mr(pd, max_page_list_len); + + if (!IS_ERR(mr)) { + mr->device = pd->device; + mr->pd = pd; + mr->uobject = NULL; + atomic_inc(&pd->usecnt); + atomic_set(&mr->usecnt, 0); + } + + return mr; +} +EXPORT_SYMBOL(ib_alloc_fast_reg_mr); + +struct ib_fast_reg_page_list *ib_alloc_fast_reg_page_list(struct ib_device *device, + int max_page_list_len) +{ + struct ib_fast_reg_page_list *page_list; + + if (!device->alloc_fast_reg_page_list) + return ERR_PTR(-ENOSYS); + + page_list = device->alloc_fast_reg_page_list(device, max_page_list_len); + + if (!IS_ERR(page_list)) { + page_list->device = device; + page_list->max_page_list_len = max_page_list_len; + } + + return page_list; +} +EXPORT_SYMBOL(ib_alloc_fast_reg_page_list); + +void ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list) +{ + page_list->device->free_fast_reg_page_list(page_list); +} +EXPORT_SYMBOL(ib_free_fast_reg_page_list); + /* Memory windows */ struct ib_mw *ib_alloc_mw(struct ib_pd *pd) diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index f093b00..b799b27 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -681,7 +681,7 @@ poll_cq_one_read_cqe: wc->dlid_path_bits = cqe->dlid; wc->src_qp = cqe->remote_qp_number; wc->wc_flags = cqe->w_completion_flags; - wc->imm_data = cpu_to_be32(cqe->immediate_data); + wc->ex.imm_data = cpu_to_be32(cqe->immediate_data); wc->sl = cqe->service_level; poll_cq_one_exit0: diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c index a03bd28..d385e41 100644 --- a/drivers/infiniband/hw/ipath/ipath_cq.c +++ b/drivers/infiniband/hw/ipath/ipath_cq.c @@ -82,7 +82,7 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited) wc->uqueue[head].opcode = entry->opcode; wc->uqueue[head].vendor_err = entry->vendor_err; wc->uqueue[head].byte_len = entry->byte_len; - wc->uqueue[head].imm_data = (__u32 __force)entry->imm_data; + wc->uqueue[head].ex.imm_data = (__u32 __force) entry->ex.imm_data; wc->uqueue[head].qp_num = entry->qp->qp_num; wc->uqueue[head].src_qp = entry->src_qp; wc->uqueue[head].wc_flags = entry->wc_flags; diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index 108df66..9771052 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c @@ -1703,11 +1703,11 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, case OP(SEND_LAST_WITH_IMMEDIATE): send_last_imm: if (header_in_data) { - wc.imm_data = *(__be32 *) data; + wc.ex.imm_data = *(__be32 *) data; data += sizeof(__be32); } else { /* Immediate data comes after BTH */ - wc.imm_data = ohdr->u.imm_data; + wc.ex.imm_data = ohdr->u.imm_data; } hdrsize += 4; wc.wc_flags = IB_WC_WITH_IMM; diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index a4b5521..af051f7 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c @@ -331,7 +331,7 @@ again: switch (wqe->wr.opcode) { case IB_WR_SEND_WITH_IMM: wc.wc_flags = IB_WC_WITH_IMM; - wc.imm_data = wqe->wr.ex.imm_data; + wc.ex.imm_data = wqe->wr.ex.imm_data; /* FALLTHROUGH */ case IB_WR_SEND: if (!ipath_get_rwqe(qp, 0)) @@ -342,7 +342,7 @@ again: if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) goto inv_err; wc.wc_flags = IB_WC_WITH_IMM; - wc.imm_data = wqe->wr.ex.imm_data; + wc.ex.imm_data = wqe->wr.ex.imm_data; if (!ipath_get_rwqe(qp, 1)) goto rnr_nak; /* FALLTHROUGH */ diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c index 0596ec1..82cc588 100644 --- a/drivers/infiniband/hw/ipath/ipath_uc.c +++ b/drivers/infiniband/hw/ipath/ipath_uc.c @@ -379,11 +379,11 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, case OP(SEND_LAST_WITH_IMMEDIATE): send_last_imm: if (header_in_data) { - wc.imm_data = *(__be32 *) data; + wc.ex.imm_data = *(__be32 *) data; data += sizeof(__be32); } else { /* Immediate data comes after BTH */ - wc.imm_data = ohdr->u.imm_data; + wc.ex.imm_data = ohdr->u.imm_data; } hdrsize += 4; wc.wc_flags = IB_WC_WITH_IMM; @@ -483,11 +483,11 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): rdma_last_imm: if (header_in_data) { - wc.imm_data = *(__be32 *) data; + wc.ex.imm_data = *(__be32 *) data; data += sizeof(__be32); } else { /* Immediate data comes after BTH */ - wc.imm_data = ohdr->u.imm_data; + wc.ex.imm_data = ohdr->u.imm_data; } hdrsize += 4; wc.wc_flags = IB_WC_WITH_IMM; diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 77ca8ca..36aa242 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c @@ -96,7 +96,7 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) { wc.wc_flags = IB_WC_WITH_IMM; - wc.imm_data = swqe->wr.ex.imm_data; + wc.ex.imm_data = swqe->wr.ex.imm_data; } /* @@ -492,14 +492,14 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, if (qp->ibqp.qp_num > 1 && opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { if (header_in_data) { - wc.imm_data = *(__be32 *) data; + wc.ex.imm_data = *(__be32 *) data; data += sizeof(__be32); } else - wc.imm_data = ohdr->u.ud.imm_data; + wc.ex.imm_data = ohdr->u.ud.imm_data; wc.wc_flags = IB_WC_WITH_IMM; hdrsize += sizeof(u32); } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { - wc.imm_data = 0; + wc.ex.imm_data = 0; wc.wc_flags = 0; } else { dev->n_pkt_drops++; diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 4521319..299f208 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -663,18 +663,18 @@ repoll: switch (cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) { case MLX4_RECV_OPCODE_RDMA_WRITE_IMM: - wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; - wc->wc_flags = IB_WC_WITH_IMM; - wc->imm_data = cqe->immed_rss_invalid; + wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; + wc->wc_flags = IB_WC_WITH_IMM; + wc->ex.imm_data = cqe->immed_rss_invalid; break; case MLX4_RECV_OPCODE_SEND: wc->opcode = IB_WC_RECV; wc->wc_flags = 0; break; case MLX4_RECV_OPCODE_SEND_IMM: - wc->opcode = IB_WC_RECV; - wc->wc_flags = IB_WC_WITH_IMM; - wc->imm_data = cqe->immed_rss_invalid; + wc->opcode = IB_WC_RECV; + wc->wc_flags = IB_WC_WITH_IMM; + wc->ex.imm_data = cqe->immed_rss_invalid; break; } diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index f788fce..d9f4735 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c @@ -620,13 +620,13 @@ static inline int mthca_poll_one(struct mthca_dev *dev, case IB_OPCODE_SEND_LAST_WITH_IMMEDIATE: case IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE: entry->wc_flags = IB_WC_WITH_IMM; - entry->imm_data = cqe->imm_etype_pkey_eec; + entry->ex.imm_data = cqe->imm_etype_pkey_eec; entry->opcode = IB_WC_RECV; break; case IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE: case IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE: entry->wc_flags = IB_WC_WITH_IMM; - entry->imm_data = cqe->imm_etype_pkey_eec; + entry->ex.imm_data = cqe->imm_etype_pkey_eec; entry->opcode = IB_WC_RECV_RDMA_WITH_IMM; break; default: diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h index 885254f..a17f771 100644 --- a/include/rdma/ib_user_verbs.h +++ b/include/rdma/ib_user_verbs.h @@ -289,7 +289,10 @@ struct ib_uverbs_wc { __u32 opcode; __u32 vendor_err; __u32 byte_len; - __u32 imm_data; + union { + __u32 imm_data; + __u32 invalidate_rkey; + } ex; __u32 qp_num; __u32 src_qp; __u32 wc_flags; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 5f5621b..74c24b9 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -103,6 +103,7 @@ enum ib_device_cap_flags { */ IB_DEVICE_UD_IP_CSUM = (1<<18), IB_DEVICE_UD_TSO = (1<<19), + IB_DEVICE_MEM_MGT_EXTENSIONS = (1<<21), }; enum ib_atomic_cap { @@ -148,6 +149,7 @@ struct ib_device_attr { int max_srq; int max_srq_wr; int max_srq_sge; + unsigned int max_fast_reg_page_list_len; u16 max_pkeys; u8 local_ca_ack_delay; }; @@ -411,6 +413,8 @@ enum ib_wc_opcode { IB_WC_FETCH_ADD, IB_WC_BIND_MW, IB_WC_LSO, + IB_WC_LOCAL_INV, + IB_WC_FAST_REG_MR, /* * Set value of IB_WC_RECV so consumers can test if a completion is a * receive by testing (opcode & IB_WC_RECV). @@ -421,7 +425,8 @@ enum ib_wc_opcode { enum ib_wc_flags { IB_WC_GRH = 1, - IB_WC_WITH_IMM = (1<<1) + IB_WC_WITH_IMM = (1<<1), + IB_WC_WITH_INVALIDATE = (1<<2), }; struct ib_wc { @@ -431,7 +436,10 @@ struct ib_wc { u32 vendor_err; u32 byte_len; struct ib_qp *qp; - __be32 imm_data; + union { + __be32 imm_data; + u32 invalidate_rkey; + } ex; u32 src_qp; int wc_flags; u16 pkey_index; @@ -625,6 +633,9 @@ enum ib_wr_opcode { IB_WR_ATOMIC_FETCH_AND_ADD, IB_WR_LSO, IB_WR_SEND_WITH_INV, + IB_WR_RDMA_READ_WITH_INV, + IB_WR_LOCAL_INV, + IB_WR_FAST_REG_MR, }; enum ib_send_flags { @@ -641,6 +652,12 @@ struct ib_sge { u32 lkey; }; +struct ib_fast_reg_page_list { + struct ib_device *device; + u64 *page_list; + unsigned int max_page_list_len; +}; + struct ib_send_wr { struct ib_send_wr *next; u64 wr_id; @@ -673,6 +690,15 @@ struct ib_send_wr { u16 pkey_index; /* valid for GSI only */ u8 port_num; /* valid for DR SMPs on switch only */ } ud; + struct { + u64 iova_start; + struct ib_fast_reg_page_list *page_list; + unsigned int page_shift; + unsigned int page_list_len; + u32 length; + int access_flags; + u32 rkey; + } fast_reg; } wr; }; @@ -1011,6 +1037,11 @@ struct ib_device { int (*query_mr)(struct ib_mr *mr, struct ib_mr_attr *mr_attr); int (*dereg_mr)(struct ib_mr *mr); + struct ib_mr * (*alloc_fast_reg_mr)(struct ib_pd *pd, + int max_page_list_len); + struct ib_fast_reg_page_list * (*alloc_fast_reg_page_list)(struct ib_device *device, + int page_list_len); + void (*free_fast_reg_page_list)(struct ib_fast_reg_page_list *page_list); int (*rereg_phys_mr)(struct ib_mr *mr, int mr_rereg_mask, struct ib_pd *pd, @@ -1805,6 +1836,54 @@ int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr); int ib_dereg_mr(struct ib_mr *mr); /** + * ib_alloc_fast_reg_mr - Allocates memory region usable with the + * IB_WR_FAST_REG_MR send work request. + * @pd: The protection domain associated with the region. + * @max_page_list_len: requested max physical buffer list length to be + * used with fast register work requests for this MR. + */ +struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len); + +/** + * ib_alloc_fast_reg_page_list - Allocates a page list array + * @device - ib device pointer. + * @page_list_len - size of the page list array to be allocated. + * + * This allocates and returns a struct ib_fast_reg_page_list * and a + * page_list array that is at least page_list_len in size. The actual + * size is returned in max_page_list_len. The caller is responsible + * for initializing the contents of the page_list array before posting + * a send work request with the IB_WC_FAST_REG_MR opcode. + * + * The page_list array entries must be translated using one of the + * ib_dma_*() functions just like the addresses passed to + * ib_map_phys_fmr(). Once the ib_post_send() is issued, the struct + * ib_fast_reg_page_list must not be modified by the caller until the + * IB_WC_FAST_REG_MR work request completes. + */ +struct ib_fast_reg_page_list *ib_alloc_fast_reg_page_list( + struct ib_device *device, int page_list_len); + +/** + * ib_free_fast_reg_page_list - Deallocates a previously allocated + * page list array. + * @page_list - struct ib_fast_reg_page_list pointer to be deallocated. + */ +void ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list); + +/** + * ib_update_fast_reg_key - updates the key portion of the fast_reg MR + * R_Key and L_Key. + * @mr - struct ib_mr pointer to be updated. + * @newkey - new key to be used. + */ +static inline void ib_update_fast_reg_key(struct ib_mr *mr, u8 newkey) +{ + mr->lkey = (mr->lkey & 0xffffff00) | newkey; + mr->rkey = (mr->rkey & 0xffffff00) | newkey; +} + +/** * ib_alloc_mw - Allocates a memory window. * @pd: The protection domain associated with the memory window. */ -- cgit v0.10.2 From e7e55829999deaab3f43e201a087731c02c54cf9 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: RDMA/cxgb3: MEM_MGT_EXTENSIONS support - set IB_DEVICE_MEM_MGT_EXTENSIONS capability bit if fw supports it. - set max_fast_reg_page_list_len device attribute. - add iwch_alloc_fast_reg_mr function. - add iwch_alloc_fastreg_pbl - add iwch_free_fastreg_pbl - adjust the WQ depth for kernel mode work queues to account for fastreg possibly taking 2 WR slots. - add fastreg_mr work request support. - add local_inv work request support. - add send_with_inv and send_with_se_inv work request support. - removed useless duplicate enums/defines for TPT/MW/MR stuff. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 3f441fc..340e418 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -145,7 +145,9 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid) } wqe = (struct t3_modify_qp_wr *) skb_put(skb, sizeof(*wqe)); memset(wqe, 0, sizeof(*wqe)); - build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, 3, 0, qpid, 7); + build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, + T3_COMPLETION_FLAG | T3_NOTIFY_FLAG, 0, qpid, 7, + T3_SOPEOP); wqe->flags = cpu_to_be32(MODQP_WRITE_EC); sge_cmd = qpid << 8 | 3; wqe->sge_cmd = cpu_to_be64(sge_cmd); @@ -558,7 +560,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p) wqe = (struct t3_modify_qp_wr *) skb_put(skb, sizeof(*wqe)); memset(wqe, 0, sizeof(*wqe)); build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_QP_MOD, 0, 0, - T3_CTL_QP_TID, 7); + T3_CTL_QP_TID, 7, T3_SOPEOP); wqe->flags = cpu_to_be32(MODQP_WRITE_EC); sge_cmd = (3ULL << 56) | FW_RI_SGEEC_START << 8 | 3; wqe->sge_cmd = cpu_to_be64(sge_cmd); @@ -674,7 +676,7 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, build_fw_riwrh((struct fw_riwrh *) wqe, T3_WR_BP, flag, Q_GENBIT(rdev_p->ctrl_qp.wptr, T3_CTRL_QP_SIZE_LOG2), T3_CTRL_QP_ID, - wr_len); + wr_len, T3_SOPEOP); if (flag == T3_COMPLETION_FLAG) ring_doorbell(rdev_p->ctrl_qp.doorbell, T3_CTRL_QP_ID); len -= 96; @@ -816,6 +818,13 @@ int cxio_deallocate_window(struct cxio_rdev *rdev_p, u32 stag) 0, 0); } +int cxio_allocate_stag(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid, u32 pbl_size, u32 pbl_addr) +{ + *stag = T3_STAG_UNSET; + return __cxio_tpt_op(rdev_p, 0, stag, 0, pdid, TPT_NON_SHARED_MR, + 0, 0, 0ULL, 0, 0, pbl_size, pbl_addr); +} + int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) { struct t3_rdma_init_wr *wqe; diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 6e128f6..25a8806 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -165,6 +165,7 @@ int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid, int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size, u32 pbl_addr); int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid); +int cxio_allocate_stag(struct cxio_rdev *rdev, u32 *stag, u32 pdid, u32 pbl_size, u32 pbl_addr); int cxio_deallocate_window(struct cxio_rdev *rdev, u32 stag); int cxio_rdma_init(struct cxio_rdev *rdev, struct t3_rdma_init_attr *attr); void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb); diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index f1a25a8..de760e9 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h @@ -72,7 +72,8 @@ enum t3_wr_opcode { T3_WR_BIND = FW_WROPCODE_RI_BIND_MW, T3_WR_RCV = FW_WROPCODE_RI_RECEIVE, T3_WR_INIT = FW_WROPCODE_RI_RDMA_INIT, - T3_WR_QP_MOD = FW_WROPCODE_RI_MODIFY_QP + T3_WR_QP_MOD = FW_WROPCODE_RI_MODIFY_QP, + T3_WR_FASTREG = FW_WROPCODE_RI_FASTREGISTER_MR } __attribute__ ((packed)); enum t3_rdma_opcode { @@ -89,7 +90,8 @@ enum t3_rdma_opcode { T3_FAST_REGISTER, T3_LOCAL_INV, T3_QP_MOD, - T3_BYPASS + T3_BYPASS, + T3_RDMA_READ_REQ_WITH_INV, } __attribute__ ((packed)); static inline enum t3_rdma_opcode wr2opcode(enum t3_wr_opcode wrop) @@ -103,6 +105,7 @@ static inline enum t3_rdma_opcode wr2opcode(enum t3_wr_opcode wrop) case T3_WR_BIND: return T3_BIND_MW; case T3_WR_INIT: return T3_RDMA_INIT; case T3_WR_QP_MOD: return T3_QP_MOD; + case T3_WR_FASTREG: return T3_FAST_REGISTER; default: break; } return -1; @@ -170,11 +173,54 @@ struct t3_send_wr { struct t3_sge sgl[T3_MAX_SGE]; /* 4+ */ }; +#define T3_MAX_FASTREG_DEPTH 24 +#define T3_MAX_FASTREG_FRAG 10 + +struct t3_fastreg_wr { + struct fw_riwrh wrh; /* 0 */ + union t3_wrid wrid; /* 1 */ + __be32 stag; /* 2 */ + __be32 len; + __be32 va_base_hi; /* 3 */ + __be32 va_base_lo_fbo; + __be32 page_type_perms; /* 4 */ + __be32 reserved1; + __be64 pbl_addrs[0]; /* 5+ */ +}; + +/* + * If a fastreg wr spans multiple wqes, then the 2nd fragment look like this. + */ +struct t3_pbl_frag { + struct fw_riwrh wrh; /* 0 */ + __be64 pbl_addrs[14]; /* 1..14 */ +}; + +#define S_FR_PAGE_COUNT 24 +#define M_FR_PAGE_COUNT 0xff +#define V_FR_PAGE_COUNT(x) ((x) << S_FR_PAGE_COUNT) +#define G_FR_PAGE_COUNT(x) ((((x) >> S_FR_PAGE_COUNT)) & M_FR_PAGE_COUNT) + +#define S_FR_PAGE_SIZE 16 +#define M_FR_PAGE_SIZE 0x1f +#define V_FR_PAGE_SIZE(x) ((x) << S_FR_PAGE_SIZE) +#define G_FR_PAGE_SIZE(x) ((((x) >> S_FR_PAGE_SIZE)) & M_FR_PAGE_SIZE) + +#define S_FR_TYPE 8 +#define M_FR_TYPE 0x1 +#define V_FR_TYPE(x) ((x) << S_FR_TYPE) +#define G_FR_TYPE(x) ((((x) >> S_FR_TYPE)) & M_FR_TYPE) + +#define S_FR_PERMS 0 +#define M_FR_PERMS 0xff +#define V_FR_PERMS(x) ((x) << S_FR_PERMS) +#define G_FR_PERMS(x) ((((x) >> S_FR_PERMS)) & M_FR_PERMS) + struct t3_local_inv_wr { struct fw_riwrh wrh; /* 0 */ union t3_wrid wrid; /* 1 */ __be32 stag; /* 2 */ - __be32 reserved3; + __be32 reserved; }; struct t3_rdma_write_wr { @@ -193,7 +239,8 @@ struct t3_rdma_read_wr { struct fw_riwrh wrh; /* 0 */ union t3_wrid wrid; /* 1 */ u8 rdmaop; /* 2 */ - u8 reserved[3]; + u8 local_inv; + u8 reserved[2]; __be32 rem_stag; __be64 rem_to; /* 3 */ __be32 local_stag; /* 4 */ @@ -201,18 +248,6 @@ struct t3_rdma_read_wr { __be64 local_to; /* 5 */ }; -enum t3_addr_type { - T3_VA_BASED_TO = 0x0, - T3_ZERO_BASED_TO = 0x1 -} __attribute__ ((packed)); - -enum t3_mem_perms { - T3_MEM_ACCESS_LOCAL_READ = 0x1, - T3_MEM_ACCESS_LOCAL_WRITE = 0x2, - T3_MEM_ACCESS_REM_READ = 0x4, - T3_MEM_ACCESS_REM_WRITE = 0x8 -} __attribute__ ((packed)); - struct t3_bind_mw_wr { struct fw_riwrh wrh; /* 0 */ union t3_wrid wrid; /* 1 */ @@ -336,6 +371,11 @@ struct t3_genbit { __be64 genbit; }; +struct t3_wq_in_err { + u64 flit[13]; + u64 err; +}; + enum rdma_init_wr_flags { MPA_INITIATOR = (1<<0), PRIV_QP = (1<<1), @@ -346,13 +386,16 @@ union t3_wr { struct t3_rdma_write_wr write; struct t3_rdma_read_wr read; struct t3_receive_wr recv; + struct t3_fastreg_wr fastreg; + struct t3_pbl_frag pbl_frag; struct t3_local_inv_wr local_inv; struct t3_bind_mw_wr bind; struct t3_bypass_wr bypass; struct t3_rdma_init_wr init; struct t3_modify_qp_wr qp_mod; struct t3_genbit genbit; - u64 flit[16]; + struct t3_wq_in_err wq_in_err; + __be64 flit[16]; }; #define T3_SQ_CQE_FLIT 13 @@ -366,12 +409,18 @@ static inline enum t3_wr_opcode fw_riwrh_opcode(struct fw_riwrh *wqe) return G_FW_RIWR_OP(be32_to_cpu(wqe->op_seop_flags)); } +enum t3_wr_hdr_bits { + T3_EOP = 1, + T3_SOP = 2, + T3_SOPEOP = T3_EOP|T3_SOP, +}; + static inline void build_fw_riwrh(struct fw_riwrh *wqe, enum t3_wr_opcode op, enum t3_wr_flags flags, u8 genbit, u32 tid, - u8 len) + u8 len, u8 sopeop) { wqe->op_seop_flags = cpu_to_be32(V_FW_RIWR_OP(op) | - V_FW_RIWR_SOPEOP(M_FW_RIWR_SOPEOP) | + V_FW_RIWR_SOPEOP(sopeop) | V_FW_RIWR_FLAGS(flags)); wmb(); wqe->gen_tid_len = cpu_to_be32(V_FW_RIWR_GEN(genbit) | @@ -404,6 +453,7 @@ enum tpt_addr_type { }; enum tpt_mem_perm { + TPT_MW_BIND = 0x10, TPT_LOCAL_READ = 0x8, TPT_LOCAL_WRITE = 0x4, TPT_REMOTE_READ = 0x2, @@ -659,7 +709,7 @@ struct t3_cq { static inline void cxio_set_wq_in_error(struct t3_wq *wq) { - wq->queue->flit[13] = 1; + wq->queue->wq_in_err.err = 1; } static inline struct t3_cqe *cxio_next_hw_cqe(struct t3_cq *cq) diff --git a/drivers/infiniband/hw/cxgb3/iwch_cq.c b/drivers/infiniband/hw/cxgb3/iwch_cq.c index 4ee8ccd..cf5474a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cq.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cq.c @@ -81,6 +81,7 @@ static int iwch_poll_cq_one(struct iwch_dev *rhp, struct iwch_cq *chp, wc->wr_id = cookie; wc->qp = &qhp->ibqp; wc->vendor_err = CQE_STATUS(cqe); + wc->wc_flags = 0; PDBG("%s qpid 0x%x type %d opcode %d status 0x%x wrid hi 0x%x " "lo 0x%x cookie 0x%llx\n", __func__, @@ -94,6 +95,11 @@ static int iwch_poll_cq_one(struct iwch_dev *rhp, struct iwch_cq *chp, else wc->byte_len = 0; wc->opcode = IB_WC_RECV; + if (CQE_OPCODE(cqe) == T3_SEND_WITH_INV || + CQE_OPCODE(cqe) == T3_SEND_WITH_SE_INV) { + wc->ex.invalidate_rkey = CQE_WRID_STAG(cqe); + wc->wc_flags |= IB_WC_WITH_INVALIDATE; + } } else { switch (CQE_OPCODE(cqe)) { case T3_RDMA_WRITE: @@ -105,17 +111,20 @@ static int iwch_poll_cq_one(struct iwch_dev *rhp, struct iwch_cq *chp, break; case T3_SEND: case T3_SEND_WITH_SE: + case T3_SEND_WITH_INV: + case T3_SEND_WITH_SE_INV: wc->opcode = IB_WC_SEND; break; case T3_BIND_MW: wc->opcode = IB_WC_BIND_MW; break; - /* these aren't supported yet */ - case T3_SEND_WITH_INV: - case T3_SEND_WITH_SE_INV: case T3_LOCAL_INV: + wc->opcode = IB_WC_LOCAL_INV; + break; case T3_FAST_REGISTER: + wc->opcode = IB_WC_FAST_REG_MR; + break; default: printk(KERN_ERR MOD "Unexpected opcode %d " "in the CQE received for QPID=0x%0x\n", diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 95f82cf..5d504f3 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -768,6 +768,68 @@ static int iwch_dealloc_mw(struct ib_mw *mw) return 0; } +static struct ib_mr *iwch_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth) +{ + struct iwch_dev *rhp; + struct iwch_pd *php; + struct iwch_mr *mhp; + u32 mmid; + u32 stag = 0; + int ret; + + php = to_iwch_pd(pd); + rhp = php->rhp; + mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); + if (!mhp) + return ERR_PTR(-ENOMEM); + + mhp->rhp = rhp; + ret = iwch_alloc_pbl(mhp, pbl_depth); + if (ret) { + kfree(mhp); + return ERR_PTR(ret); + } + mhp->attr.pbl_size = pbl_depth; + ret = cxio_allocate_stag(&rhp->rdev, &stag, php->pdid, + mhp->attr.pbl_size, mhp->attr.pbl_addr); + if (ret) { + iwch_free_pbl(mhp); + kfree(mhp); + return ERR_PTR(ret); + } + mhp->attr.pdid = php->pdid; + mhp->attr.type = TPT_NON_SHARED_MR; + mhp->attr.stag = stag; + mhp->attr.state = 1; + mmid = (stag) >> 8; + mhp->ibmr.rkey = mhp->ibmr.lkey = stag; + insert_handle(rhp, &rhp->mmidr, mhp, mmid); + PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag); + return &(mhp->ibmr); +} + +static struct ib_fast_reg_page_list *iwch_alloc_fastreg_pbl( + struct ib_device *device, + int page_list_len) +{ + struct ib_fast_reg_page_list *page_list; + + page_list = kmalloc(sizeof *page_list + page_list_len * sizeof(u64), + GFP_KERNEL); + if (!page_list) + return ERR_PTR(-ENOMEM); + + page_list->page_list = (u64 *)(page_list + 1); + page_list->max_page_list_len = page_list_len; + + return page_list; +} + +static void iwch_free_fastreg_pbl(struct ib_fast_reg_page_list *page_list) +{ + kfree(page_list); +} + static int iwch_destroy_qp(struct ib_qp *ib_qp) { struct iwch_dev *rhp; @@ -843,6 +905,15 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd, */ sqsize = roundup_pow_of_two(attrs->cap.max_send_wr); wqsize = roundup_pow_of_two(rqsize + sqsize); + + /* + * Kernel users need more wq space for fastreg WRs which can take + * 2 WR fragments. + */ + ucontext = pd->uobject ? to_iwch_ucontext(pd->uobject->context) : NULL; + if (!ucontext && wqsize < (rqsize + (2 * sqsize))) + wqsize = roundup_pow_of_two(rqsize + + roundup_pow_of_two(attrs->cap.max_send_wr * 2)); PDBG("%s wqsize %d sqsize %d rqsize %d\n", __func__, wqsize, sqsize, rqsize); qhp = kzalloc(sizeof(*qhp), GFP_KERNEL); @@ -851,7 +922,6 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd, qhp->wq.size_log2 = ilog2(wqsize); qhp->wq.rq_size_log2 = ilog2(rqsize); qhp->wq.sq_size_log2 = ilog2(sqsize); - ucontext = pd->uobject ? to_iwch_ucontext(pd->uobject->context) : NULL; if (cxio_create_qp(&rhp->rdev, !udata, &qhp->wq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx)) { kfree(qhp); @@ -1048,6 +1118,7 @@ static int iwch_query_device(struct ib_device *ibdev, props->max_mr = dev->attr.max_mem_regs; props->max_pd = dev->attr.max_pds; props->local_ca_ack_delay = 0; + props->max_fast_reg_page_list_len = T3_MAX_FASTREG_DEPTH; return 0; } @@ -1088,6 +1159,28 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type); } +static int fw_supports_fastreg(struct iwch_dev *iwch_dev) +{ + struct ethtool_drvinfo info; + struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; + char *cp, *next; + unsigned fw_maj, fw_min; + + rtnl_lock(); + lldev->ethtool_ops->get_drvinfo(lldev, &info); + rtnl_unlock(); + + next = info.fw_version+1; + cp = strsep(&next, "."); + sscanf(cp, "%i", &fw_maj); + cp = strsep(&next, "."); + sscanf(cp, "%i", &fw_min); + + PDBG("%s maj %u min %u\n", __func__, fw_maj, fw_min); + + return fw_maj > 6 || (fw_maj == 6 && fw_min > 0); +} + static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf) { struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev, @@ -1149,8 +1242,10 @@ int iwch_register_device(struct iwch_dev *dev) memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); dev->ibdev.owner = THIS_MODULE; - dev->device_cap_flags = - (IB_DEVICE_ZERO_STAG | IB_DEVICE_MEM_WINDOW); + dev->device_cap_flags = IB_DEVICE_ZERO_STAG | + IB_DEVICE_MEM_WINDOW; + if (fw_supports_fastreg(dev)) + dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; dev->ibdev.uverbs_cmd_mask = (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | @@ -1202,6 +1297,9 @@ int iwch_register_device(struct iwch_dev *dev) dev->ibdev.alloc_mw = iwch_alloc_mw; dev->ibdev.bind_mw = iwch_bind_mw; dev->ibdev.dealloc_mw = iwch_dealloc_mw; + dev->ibdev.alloc_fast_reg_mr = iwch_alloc_fast_reg_mr; + dev->ibdev.alloc_fast_reg_page_list = iwch_alloc_fastreg_pbl; + dev->ibdev.free_fast_reg_page_list = iwch_free_fastreg_pbl; dev->ibdev.attach_mcast = iwch_multicast_attach; dev->ibdev.detach_mcast = iwch_multicast_detach; diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h index 836163f..f5ceca0 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.h +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h @@ -296,14 +296,6 @@ static inline u32 iwch_ib_to_tpt_access(int acc) TPT_LOCAL_READ; } -static inline u32 iwch_ib_to_mwbind_access(int acc) -{ - return (acc & IB_ACCESS_REMOTE_WRITE ? T3_MEM_ACCESS_REM_WRITE : 0) | - (acc & IB_ACCESS_REMOTE_READ ? T3_MEM_ACCESS_REM_READ : 0) | - (acc & IB_ACCESS_LOCAL_WRITE ? T3_MEM_ACCESS_LOCAL_WRITE : 0) | - T3_MEM_ACCESS_LOCAL_READ; -} - enum iwch_mmid_state { IWCH_STAG_STATE_VALID, IWCH_STAG_STATE_INVALID diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 9926137..3b44300 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c @@ -44,54 +44,39 @@ static int iwch_build_rdma_send(union t3_wr *wqe, struct ib_send_wr *wr, switch (wr->opcode) { case IB_WR_SEND: - case IB_WR_SEND_WITH_IMM: if (wr->send_flags & IB_SEND_SOLICITED) wqe->send.rdmaop = T3_SEND_WITH_SE; else wqe->send.rdmaop = T3_SEND; wqe->send.rem_stag = 0; break; -#if 0 /* Not currently supported */ - case TYPE_SEND_INVALIDATE: - case TYPE_SEND_INVALIDATE_IMMEDIATE: - wqe->send.rdmaop = T3_SEND_WITH_INV; - wqe->send.rem_stag = cpu_to_be32(wr->wr.rdma.rkey); - break; - case TYPE_SEND_SE_INVALIDATE: - wqe->send.rdmaop = T3_SEND_WITH_SE_INV; - wqe->send.rem_stag = cpu_to_be32(wr->wr.rdma.rkey); + case IB_WR_SEND_WITH_INV: + if (wr->send_flags & IB_SEND_SOLICITED) + wqe->send.rdmaop = T3_SEND_WITH_SE_INV; + else + wqe->send.rdmaop = T3_SEND_WITH_INV; + wqe->send.rem_stag = cpu_to_be32(wr->ex.invalidate_rkey); break; -#endif default: - break; + return -EINVAL; } if (wr->num_sge > T3_MAX_SGE) return -EINVAL; wqe->send.reserved[0] = 0; wqe->send.reserved[1] = 0; wqe->send.reserved[2] = 0; - if (wr->opcode == IB_WR_SEND_WITH_IMM) { - plen = 4; - wqe->send.sgl[0].stag = wr->ex.imm_data; - wqe->send.sgl[0].len = __constant_cpu_to_be32(0); - wqe->send.num_sgle = __constant_cpu_to_be32(0); - *flit_cnt = 5; - } else { - plen = 0; - for (i = 0; i < wr->num_sge; i++) { - if ((plen + wr->sg_list[i].length) < plen) { - return -EMSGSIZE; - } - plen += wr->sg_list[i].length; - wqe->send.sgl[i].stag = - cpu_to_be32(wr->sg_list[i].lkey); - wqe->send.sgl[i].len = - cpu_to_be32(wr->sg_list[i].length); - wqe->send.sgl[i].to = cpu_to_be64(wr->sg_list[i].addr); - } - wqe->send.num_sgle = cpu_to_be32(wr->num_sge); - *flit_cnt = 4 + ((wr->num_sge) << 1); + plen = 0; + for (i = 0; i < wr->num_sge; i++) { + if ((plen + wr->sg_list[i].length) < plen) + return -EMSGSIZE; + + plen += wr->sg_list[i].length; + wqe->send.sgl[i].stag = cpu_to_be32(wr->sg_list[i].lkey); + wqe->send.sgl[i].len = cpu_to_be32(wr->sg_list[i].length); + wqe->send.sgl[i].to = cpu_to_be64(wr->sg_list[i].addr); } + wqe->send.num_sgle = cpu_to_be32(wr->num_sge); + *flit_cnt = 4 + ((wr->num_sge) << 1); wqe->send.plen = cpu_to_be32(plen); return 0; } @@ -143,9 +128,12 @@ static int iwch_build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr, if (wr->num_sge > 1) return -EINVAL; wqe->read.rdmaop = T3_READ_REQ; + if (wr->opcode == IB_WR_RDMA_READ_WITH_INV) + wqe->read.local_inv = 1; + else + wqe->read.local_inv = 0; wqe->read.reserved[0] = 0; wqe->read.reserved[1] = 0; - wqe->read.reserved[2] = 0; wqe->read.rem_stag = cpu_to_be32(wr->wr.rdma.rkey); wqe->read.rem_to = cpu_to_be64(wr->wr.rdma.remote_addr); wqe->read.local_stag = cpu_to_be32(wr->sg_list[0].lkey); @@ -155,6 +143,57 @@ static int iwch_build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr, return 0; } +static int iwch_build_fastreg(union t3_wr *wqe, struct ib_send_wr *wr, + u8 *flit_cnt, int *wr_cnt, struct t3_wq *wq) +{ + int i; + __be64 *p; + + if (wr->wr.fast_reg.page_list_len > T3_MAX_FASTREG_DEPTH) + return -EINVAL; + *wr_cnt = 1; + wqe->fastreg.stag = cpu_to_be32(wr->wr.fast_reg.rkey); + wqe->fastreg.len = cpu_to_be32(wr->wr.fast_reg.length); + wqe->fastreg.va_base_hi = cpu_to_be32(wr->wr.fast_reg.iova_start >> 32); + wqe->fastreg.va_base_lo_fbo = + cpu_to_be32(wr->wr.fast_reg.iova_start & 0xffffffff); + wqe->fastreg.page_type_perms = cpu_to_be32( + V_FR_PAGE_COUNT(wr->wr.fast_reg.page_list_len) | + V_FR_PAGE_SIZE(wr->wr.fast_reg.page_shift-12) | + V_FR_TYPE(TPT_VATO) | + V_FR_PERMS(iwch_ib_to_tpt_access(wr->wr.fast_reg.access_flags))); + p = &wqe->fastreg.pbl_addrs[0]; + for (i = 0; i < wr->wr.fast_reg.page_list_len; i++, p++) { + + /* If we need a 2nd WR, then set it up */ + if (i == T3_MAX_FASTREG_FRAG) { + *wr_cnt = 2; + wqe = (union t3_wr *)(wq->queue + + Q_PTR2IDX((wq->wptr+1), wq->size_log2)); + build_fw_riwrh((void *)wqe, T3_WR_FASTREG, 0, + Q_GENBIT(wq->wptr + 1, wq->size_log2), + 0, 1 + wr->wr.fast_reg.page_list_len - T3_MAX_FASTREG_FRAG, + T3_EOP); + + p = &wqe->pbl_frag.pbl_addrs[0]; + } + *p = cpu_to_be64((u64)wr->wr.fast_reg.page_list->page_list[i]); + } + *flit_cnt = 5 + wr->wr.fast_reg.page_list_len; + if (*flit_cnt > 15) + *flit_cnt = 15; + return 0; +} + +static int iwch_build_inv_stag(union t3_wr *wqe, struct ib_send_wr *wr, + u8 *flit_cnt) +{ + wqe->local_inv.stag = cpu_to_be32(wr->ex.invalidate_rkey); + wqe->local_inv.reserved = 0; + *flit_cnt = sizeof(struct t3_local_inv_wr) >> 3; + return 0; +} + /* * TBD: this is going to be moved to firmware. Missing pdid/qpid check for now. */ @@ -238,6 +277,7 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, u32 num_wrs; unsigned long flag; struct t3_swsq *sqp; + int wr_cnt = 1; qhp = to_iwch_qp(ibqp); spin_lock_irqsave(&qhp->lock, flag); @@ -262,15 +302,15 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, t3_wr_flags = 0; if (wr->send_flags & IB_SEND_SOLICITED) t3_wr_flags |= T3_SOLICITED_EVENT_FLAG; - if (wr->send_flags & IB_SEND_FENCE) - t3_wr_flags |= T3_READ_FENCE_FLAG; if (wr->send_flags & IB_SEND_SIGNALED) t3_wr_flags |= T3_COMPLETION_FLAG; sqp = qhp->wq.sq + Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2); switch (wr->opcode) { case IB_WR_SEND: - case IB_WR_SEND_WITH_IMM: + case IB_WR_SEND_WITH_INV: + if (wr->send_flags & IB_SEND_FENCE) + t3_wr_flags |= T3_READ_FENCE_FLAG; t3_wr_opcode = T3_WR_SEND; err = iwch_build_rdma_send(wqe, wr, &t3_wr_flit_cnt); break; @@ -280,6 +320,7 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, err = iwch_build_rdma_write(wqe, wr, &t3_wr_flit_cnt); break; case IB_WR_RDMA_READ: + case IB_WR_RDMA_READ_WITH_INV: t3_wr_opcode = T3_WR_READ; t3_wr_flags = 0; /* T3 reads are always signaled */ err = iwch_build_rdma_read(wqe, wr, &t3_wr_flit_cnt); @@ -289,6 +330,17 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, if (!qhp->wq.oldest_read) qhp->wq.oldest_read = sqp; break; + case IB_WR_FAST_REG_MR: + t3_wr_opcode = T3_WR_FASTREG; + err = iwch_build_fastreg(wqe, wr, &t3_wr_flit_cnt, + &wr_cnt, &qhp->wq); + break; + case IB_WR_LOCAL_INV: + if (wr->send_flags & IB_SEND_FENCE) + t3_wr_flags |= T3_LOCAL_FENCE_FLAG; + t3_wr_opcode = T3_WR_INV_STAG; + err = iwch_build_inv_stag(wqe, wr, &t3_wr_flit_cnt); + break; default: PDBG("%s post of type=%d TBD!\n", __func__, wr->opcode); @@ -307,14 +359,15 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, build_fw_riwrh((void *) wqe, t3_wr_opcode, t3_wr_flags, Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), - 0, t3_wr_flit_cnt); + 0, t3_wr_flit_cnt, + (wr_cnt == 1) ? T3_SOPEOP : T3_SOP); PDBG("%s cookie 0x%llx wq idx 0x%x swsq idx %ld opcode %d\n", __func__, (unsigned long long) wr->wr_id, idx, Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2), sqp->opcode); wr = wr->next; num_wrs--; - ++(qhp->wq.wptr); + qhp->wq.wptr += wr_cnt; ++(qhp->wq.sq_wptr); } spin_unlock_irqrestore(&qhp->lock, flag); @@ -359,7 +412,7 @@ int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, wr->wr_id; build_fw_riwrh((void *) wqe, T3_WR_RCV, T3_COMPLETION_FLAG, Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), - 0, sizeof(struct t3_receive_wr) >> 3); + 0, sizeof(struct t3_receive_wr) >> 3, T3_SOPEOP); PDBG("%s cookie 0x%llx idx 0x%x rq_wptr 0x%x rw_rptr 0x%x " "wqe %p \n", __func__, (unsigned long long) wr->wr_id, idx, qhp->wq.rq_wptr, qhp->wq.rq_rptr, wqe); @@ -419,10 +472,10 @@ int iwch_bind_mw(struct ib_qp *qp, sgl.lkey = mw_bind->mr->lkey; sgl.length = mw_bind->length; wqe->bind.reserved = 0; - wqe->bind.type = T3_VA_BASED_TO; + wqe->bind.type = TPT_VATO; /* TBD: check perms */ - wqe->bind.perms = iwch_ib_to_mwbind_access(mw_bind->mw_access_flags); + wqe->bind.perms = iwch_ib_to_tpt_access(mw_bind->mw_access_flags); wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey); wqe->bind.mw_stag = cpu_to_be32(mw->rkey); wqe->bind.mw_len = cpu_to_be32(mw_bind->length); @@ -430,7 +483,7 @@ int iwch_bind_mw(struct ib_qp *qp, err = iwch_sgl2pbl_map(rhp, &sgl, 1, &pbl_addr, &page_size); if (err) { spin_unlock_irqrestore(&qhp->lock, flag); - return err; + return err; } wqe->send.wrid.id0.hi = qhp->wq.sq_wptr; sqp = qhp->wq.sq + Q_PTR2IDX(qhp->wq.sq_wptr, qhp->wq.sq_size_log2); @@ -441,10 +494,9 @@ int iwch_bind_mw(struct ib_qp *qp, sqp->signaled = (mw_bind->send_flags & IB_SEND_SIGNALED); wqe->bind.mr_pbl_addr = cpu_to_be32(pbl_addr); wqe->bind.mr_pagesz = page_size; - wqe->flit[T3_SQ_COOKIE_FLIT] = mw_bind->wr_id; build_fw_riwrh((void *)wqe, T3_WR_BIND, t3_wr_flags, Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 0, - sizeof(struct t3_bind_mw_wr) >> 3); + sizeof(struct t3_bind_mw_wr) >> 3, T3_SOPEOP); ++(qhp->wq.wptr); ++(qhp->wq.sq_wptr); spin_unlock_irqrestore(&qhp->lock, flag); -- cgit v0.10.2 From d1f2cd895f8733faa9d79d09d825a2ed80002ac7 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: IB/mlx4: Configure QPs' max message size based on real device capability ConnectX returns the max message size it supports through the QUERY_DEV_CAP firmware command. When modifying a QP to RTR, the max message size for the QP must be specified. This value must not exceed the value declared through QUERY_DEV_CAP. The current code ignores the max allowed size and unconditionally sets the value to 2^31. This patch sets all QPs to the max value allowed as returned from firmware. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 4b0ac5d..76054a7 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -908,7 +908,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, attr->path_mtu); goto out; } - context->mtu_msgmax = (attr->path_mtu << 5) | 31; + context->mtu_msgmax = (attr->path_mtu << 5) | + ilog2(dev->dev->caps.max_msg_sz); } if (qp->rq.wqe_cnt) -- cgit v0.10.2 From 6578cf33989a594bab37af988d45d87812b946b8 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:45 -0700 Subject: IB/mlx4: Pass congestion management class MADs to the HCA ConnectX HCAs support the IB_MGMT_CLASS_CONG_MGMT management class, so process MADs of this class through the MAD_IFC firmware command. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 4c1e72f..cdca3a5 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -255,7 +255,8 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, return IB_MAD_RESULT_SUCCESS; } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 || - in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS2) { + in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS2 || + in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CONG_MGMT) { if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET && in_mad->mad_hdr.method != IB_MGMT_METHOD_SET) return IB_MAD_RESULT_SUCCESS; -- cgit v0.10.2 From e5a5e7d59af5944a674b9cea420a1fedc60496f2 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Mon, 14 Jul 2008 23:48:46 -0700 Subject: IB/core: Reset to error QP state transition is not allowed I was reviewing the QP state transition diagram in the IB 1.2.1 spec and the code for qp_state_table[], and noticed that the code allows a QP to be modified from IB_QPS_RESET to IB_QPS_ERR whereas the notes for figure 124 (pg 457) specifically says that this transition isn't allowed. This is a clarification from earlier versions of the IB spec, which were ambiguous in this area and suggested that the RESET to ERR transition was allowed. Fix up the qp_state_table[] to make RESET->ERR not allowed. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index e0fbe59..a7da9be 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -315,7 +315,6 @@ static const struct { } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { [IB_QPS_RESET] = { [IB_QPS_RESET] = { .valid = 1 }, - [IB_QPS_ERR] = { .valid = 1 }, [IB_QPS_INIT] = { .valid = 1, .req_param = { -- cgit v0.10.2 From d3809ad0972297fbc7ef0585049ef465d9d8d79d Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:46 -0700 Subject: IB/mthca: Remove extra code for RESET->ERR QP state transition Commit b18aad71 ("IB/mthca: Fix RESET to ERROR transition") added some extra code to handle a QP state transition from RESET to ERROR. However, the latest 1.2.1 version of the IB spec has clarified that this transition is actually not allowed, so we can remove this extra code again. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 3b1c5ba..77b52b3 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -848,23 +848,6 @@ out: return err; } -static const struct ib_qp_attr dummy_init_attr = { .port_num = 1 }; -static const int dummy_init_attr_mask[] = { - [IB_QPT_UD] = (IB_QP_PKEY_INDEX | - IB_QP_PORT | - IB_QP_QKEY), - [IB_QPT_UC] = (IB_QP_PKEY_INDEX | - IB_QP_PORT | - IB_QP_ACCESS_FLAGS), - [IB_QPT_RC] = (IB_QP_PKEY_INDEX | - IB_QP_PORT | - IB_QP_ACCESS_FLAGS), - [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | - IB_QP_QKEY), - [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | - IB_QP_QKEY), -}; - int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata) { @@ -926,15 +909,6 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, goto out; } - if (cur_state == IB_QPS_RESET && new_state == IB_QPS_ERR) { - err = __mthca_modify_qp(ibqp, &dummy_init_attr, - dummy_init_attr_mask[ibqp->qp_type], - IB_QPS_RESET, IB_QPS_INIT); - if (err) - goto out; - cur_state = IB_QPS_INIT; - } - err = __mthca_modify_qp(ibqp, attr, attr_mask, cur_state, new_state); out: -- cgit v0.10.2 From 7c27f358209a8ce7c57b584346d7b611e823f1b1 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:46 -0700 Subject: IB/mlx4: Remove extra code for RESET->ERR QP state transition Commit 65adfa91 ("IB/mlx4: Fix RESET to RESET and RESET to ERROR transitions") added some extra code to handle a QP state transition from RESET to ERROR. However, the latest 1.2.1 version of the IB spec has clarified that this transition is actually not allowed, so we can remove this extra code again. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 76054a7..44bbd6c 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1132,23 +1132,6 @@ out: return err; } -static const struct ib_qp_attr mlx4_ib_qp_attr = { .port_num = 1 }; -static const int mlx4_ib_qp_attr_mask_table[IB_QPT_UD + 1] = { - [IB_QPT_UD] = (IB_QP_PKEY_INDEX | - IB_QP_PORT | - IB_QP_QKEY), - [IB_QPT_UC] = (IB_QP_PKEY_INDEX | - IB_QP_PORT | - IB_QP_ACCESS_FLAGS), - [IB_QPT_RC] = (IB_QP_PKEY_INDEX | - IB_QP_PORT | - IB_QP_ACCESS_FLAGS), - [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | - IB_QP_QKEY), - [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | - IB_QP_QKEY), -}; - int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata) { @@ -1191,15 +1174,6 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, goto out; } - if (cur_state == IB_QPS_RESET && new_state == IB_QPS_ERR) { - err = __mlx4_ib_modify_qp(ibqp, &mlx4_ib_qp_attr, - mlx4_ib_qp_attr_mask_table[ibqp->qp_type], - IB_QPS_RESET, IB_QPS_INIT); - if (err) - goto out; - cur_state = IB_QPS_INIT; - } - err = __mlx4_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state); out: -- cgit v0.10.2 From 3e255eac561672cbc92844b9f16cae9304c2a783 Mon Sep 17 00:00:00 2001 From: Joachim Fenkes Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: IB/ehca: Reject receive work requests if QP is in RESET state Signed-off-by: Joachim Fenkes Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index b799b27..dd9bc68 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -544,8 +544,16 @@ int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr, struct ib_recv_wr **bad_recv_wr) { - return internal_post_recv(container_of(qp, struct ehca_qp, ib_qp), - qp->device, recv_wr, bad_recv_wr); + struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp); + + /* Reject WR if QP is in RESET state */ + if (unlikely(my_qp->state == IB_QPS_RESET)) { + ehca_err(qp->device, "Invalid QP state qp_state=%d qpn=%x", + my_qp->state, qp->qp_num); + return -EINVAL; + } + + return internal_post_recv(my_qp, qp->device, recv_wr, bad_recv_wr); } int ehca_post_srq_recv(struct ib_srq *srq, -- cgit v0.10.2 From 6f7bc01a7382641c61ec036d68ff3a9140b48a1c Mon Sep 17 00:00:00 2001 From: Stefan Roscher Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: IB/ehca: In case of lost interrupts, trigger EOI to reenable interrupts During corner case testing, we noticed that some versions of ehca do not properly transition to interrupt done in special load situations. This can be resolved by periodically triggering EOI through H_EOI, if EQEs are pending. Signed-off-by: Stefan Roscher Acked-by: Benjamin Herrenschmidt Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index ce1ab05..0792d93 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -531,7 +531,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq) { struct ehca_eq *eq = &shca->eq; struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache; - u64 eqe_value; + u64 eqe_value, ret; unsigned long flags; int eqe_cnt, i; int eq_empty = 0; @@ -583,8 +583,13 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq) ehca_dbg(&shca->ib_device, "No eqe found for irq event"); goto unlock_irq_spinlock; - } else if (!is_irq) + } else if (!is_irq) { + ret = hipz_h_eoi(eq->ist); + if (ret != H_SUCCESS) + ehca_err(&shca->ib_device, + "bad return code EOI -rc = %ld\n", ret); ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt); + } if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE)) ehca_dbg(&shca->ib_device, "too many eqes for one irq event"); /* enable irq for new packets */ diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 5245e13..415d3a4 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c @@ -933,3 +933,13 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle, r_cb, 0, 0, 0, 0); } + +u64 hipz_h_eoi(int irq) +{ + unsigned long xirr; + + iosync(); + xirr = (0xffULL << 24) | irq; + + return plpar_hcall_norets(H_EOI, xirr); +} diff --git a/drivers/infiniband/hw/ehca/hcp_if.h b/drivers/infiniband/hw/ehca/hcp_if.h index 60ce02b..2c3c6e0 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.h +++ b/drivers/infiniband/hw/ehca/hcp_if.h @@ -260,5 +260,6 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle, const u64 ressource_handle, void *rblock, unsigned long *byte_count); +u64 hipz_h_eoi(int irq); #endif /* __HCP_IF_H__ */ -- cgit v0.10.2 From 97d1cc8055c7b3fbd35bf693775d61102e65d174 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: RDMA/cxgb3: Fix up some ib_device_attr fields - set fw_ver - set hw_ver - set max_qp_wr to something reasonable - set max_cqe to something reasonable Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 25a8806..a9ff32c 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -45,13 +45,14 @@ #define T3_CTRL_QP_SIZE_LOG2 8 #define T3_CTRL_CQ_ID 0 -/* TBD */ #define T3_MAX_NUM_RI (1<<15) #define T3_MAX_NUM_QP (1<<15) #define T3_MAX_NUM_CQ (1<<15) #define T3_MAX_NUM_PD (1<<15) #define T3_MAX_PBL_SIZE 256 #define T3_MAX_RQ_SIZE 1024 +#define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1) +#define T3_MAX_CQ_DEPTH 8192 #define T3_MAX_NUM_STAG (1<<15) #define T3_MAX_MR_SIZE 0x100000000ULL diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index 71554ea..e09cc1a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c @@ -74,11 +74,11 @@ static void rnic_init(struct iwch_dev *rnicp) rnicp->attr.vendor_id = 0x168; rnicp->attr.vendor_part_id = 7; rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; - rnicp->attr.max_wrs = (1UL << 24) - 1; + rnicp->attr.max_wrs = T3_MAX_QP_DEPTH; rnicp->attr.max_sge_per_wr = T3_MAX_SGE; rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE; rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1; - rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1; + rnicp->attr.max_cqes_per_cq = T3_MAX_CQ_DEPTH; rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev); rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 5d504f3..5f43806 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1093,6 +1093,29 @@ static int iwch_query_gid(struct ib_device *ibdev, u8 port, return 0; } +static u64 fw_vers_string_to_u64(struct iwch_dev *iwch_dev) +{ + struct ethtool_drvinfo info; + struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; + char *cp, *next; + unsigned fw_maj, fw_min, fw_mic; + + rtnl_lock(); + lldev->ethtool_ops->get_drvinfo(lldev, &info); + rtnl_unlock(); + + next = info.fw_version + 1; + cp = strsep(&next, "."); + sscanf(cp, "%i", &fw_maj); + cp = strsep(&next, "."); + sscanf(cp, "%i", &fw_min); + cp = strsep(&next, "."); + sscanf(cp, "%i", &fw_mic); + + return (((u64)fw_maj & 0xffff) << 32) | ((fw_min & 0xffff) << 16) | + (fw_mic & 0xffff); +} + static int iwch_query_device(struct ib_device *ibdev, struct ib_device_attr *props) { @@ -1103,6 +1126,8 @@ static int iwch_query_device(struct ib_device *ibdev, dev = to_iwch_dev(ibdev); memset(props, 0, sizeof *props); memcpy(&props->sys_image_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); + props->hw_ver = dev->rdev.t3cdev_p->type; + props->fw_ver = fw_vers_string_to_u64(dev); props->device_cap_flags = dev->device_cap_flags; props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; -- cgit v0.10.2 From eec8845d29504a12fbd434e192d61aed3d9d74fa Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: RDMA/cxgb3: Remove write-only iwch_rnic_attributes fields The members struct iwch_rnic_attributes.vendor_id and .vendor_part_id are write-only, so we might as well get rid of them. Signed-off-by: Roland Dreier Acked-by: Steve Wise diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index e09cc1a..0608625 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c @@ -71,8 +71,6 @@ static void rnic_init(struct iwch_dev *rnicp) idr_init(&rnicp->mmidr); spin_lock_init(&rnicp->lock); - rnicp->attr.vendor_id = 0x168; - rnicp->attr.vendor_part_id = 7; rnicp->attr.max_qps = T3_MAX_NUM_QP - 32; rnicp->attr.max_wrs = T3_MAX_QP_DEPTH; rnicp->attr.max_sge_per_wr = T3_MAX_SGE; diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h index d2409a5..3773453 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.h +++ b/drivers/infiniband/hw/cxgb3/iwch.h @@ -48,8 +48,6 @@ struct iwch_qp; struct iwch_mr; struct iwch_rnic_attributes { - u32 vendor_id; - u32 vendor_part_id; u32 max_qps; u32 max_wrs; /* Max for any SQ/RQ */ u32 max_sge_per_wr; -- cgit v0.10.2 From 468f2239bcc71ae0f345c3fe58c797cf4627daf4 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: RDMA/cma: Add missing newlines to printk()s Signed-off-by: Roland Dreier Acked-by: Sean Hefty diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e5bd617..44d190f 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -974,7 +974,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) event.param.conn.private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; break; default: - printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", + printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d\n", ib_event->event); goto out; } @@ -1450,7 +1450,7 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv, ret = rdma_listen(id, id_priv->backlog); if (ret) printk(KERN_WARNING "RDMA CMA: cma_listen_on_dev, error %d, " - "listening on device %s", ret, cma_dev->device->name); + "listening on device %s\n", ret, cma_dev->device->name); } static void cma_listen_on_all(struct rdma_id_private *id_priv) @@ -2155,7 +2155,7 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, event.status = 0; break; default: - printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", + printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d\n", ib_event->event); goto out; } -- cgit v0.10.2 From a7d834c4bc6be73e8f83eaa5072fac3c5549f7f2 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:47 -0700 Subject: IPoIB/cm: Fix racy use of receive WR/SGL in ipoib_cm_post_receive_nonsrq() For devices that don't support SRQs, ipoib_cm_post_receive_nonsrq() is called from both ipoib_cm_handle_rx_wc() and ipoib_cm_nonsrq_init_rx(), and these two callers are not synchronized against each other. However, ipoib_cm_post_receive_nonsrq() always reuses the same receive work request and scatter list structures, so multiple callers can end up stepping on each other, which leads to posting garbled work requests. Fix this by having the caller pass in the ib_recv_wr and ib_sge structures to use, and allocating new local structures in ipoib_cm_nonsrq_init_rx(). Based on a patch by Pradeep Satyanarayana and David Wilder , with debugging help from Hoang-Nam Nguyen . Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 6223fc3..37bf67b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -111,18 +111,20 @@ static int ipoib_cm_post_receive_srq(struct net_device *dev, int id) } static int ipoib_cm_post_receive_nonsrq(struct net_device *dev, - struct ipoib_cm_rx *rx, int id) + struct ipoib_cm_rx *rx, + struct ib_recv_wr *wr, + struct ib_sge *sge, int id) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ib_recv_wr *bad_wr; int i, ret; - priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV; + wr->wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV; for (i = 0; i < IPOIB_CM_RX_SG; ++i) - priv->cm.rx_sge[i].addr = rx->rx_ring[id].mapping[i]; + sge[i].addr = rx->rx_ring[id].mapping[i]; - ret = ib_post_recv(rx->qp, &priv->cm.rx_wr, &bad_wr); + ret = ib_post_recv(rx->qp, wr, &bad_wr); if (unlikely(ret)) { ipoib_warn(priv, "post recv failed for buf %d (%d)\n", id, ret); ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1, @@ -320,10 +322,33 @@ static int ipoib_cm_modify_rx_qp(struct net_device *dev, return 0; } +static void ipoib_cm_init_rx_wr(struct net_device *dev, + struct ib_recv_wr *wr, + struct ib_sge *sge) +{ + struct ipoib_dev_priv *priv = netdev_priv(dev); + int i; + + for (i = 0; i < priv->cm.num_frags; ++i) + sge[i].lkey = priv->mr->lkey; + + sge[0].length = IPOIB_CM_HEAD_SIZE; + for (i = 1; i < priv->cm.num_frags; ++i) + sge[i].length = PAGE_SIZE; + + wr->next = NULL; + wr->sg_list = priv->cm.rx_sge; + wr->num_sge = priv->cm.num_frags; +} + static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_id, struct ipoib_cm_rx *rx) { struct ipoib_dev_priv *priv = netdev_priv(dev); + struct { + struct ib_recv_wr wr; + struct ib_sge sge[IPOIB_CM_RX_SG]; + } *t; int ret; int i; @@ -331,6 +356,14 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i if (!rx->rx_ring) return -ENOMEM; + t = kmalloc(sizeof *t, GFP_KERNEL); + if (!t) { + ret = -ENOMEM; + goto err_free; + } + + ipoib_cm_init_rx_wr(dev, &t->wr, t->sge); + spin_lock_irq(&priv->lock); if (priv->cm.nonsrq_conn_qp >= ipoib_max_conn_qp) { @@ -349,8 +382,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); ret = -ENOMEM; goto err_count; - } - ret = ipoib_cm_post_receive_nonsrq(dev, rx, i); + } + ret = ipoib_cm_post_receive_nonsrq(dev, rx, &t->wr, t->sge, i); if (ret) { ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq " "failed for buf %d\n", i); @@ -361,6 +394,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i rx->recv_count = ipoib_recvq_size; + kfree(t); + return 0; err_count: @@ -369,6 +404,7 @@ err_count: spin_unlock_irq(&priv->lock); err_free: + kfree(t); ipoib_cm_free_rx_ring(dev, rx->rx_ring); return ret; @@ -637,7 +673,10 @@ repost: ipoib_warn(priv, "ipoib_cm_post_receive_srq failed " "for buf %d\n", wr_id); } else { - if (unlikely(ipoib_cm_post_receive_nonsrq(dev, p, wr_id))) { + if (unlikely(ipoib_cm_post_receive_nonsrq(dev, p, + &priv->cm.rx_wr, + priv->cm.rx_sge, + wr_id))) { --p->recv_count; ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq failed " "for buf %d\n", wr_id); @@ -1502,15 +1541,7 @@ int ipoib_cm_dev_init(struct net_device *dev) priv->cm.num_frags = IPOIB_CM_RX_SG; } - for (i = 0; i < priv->cm.num_frags; ++i) - priv->cm.rx_sge[i].lkey = priv->mr->lkey; - - priv->cm.rx_sge[0].length = IPOIB_CM_HEAD_SIZE; - for (i = 1; i < priv->cm.num_frags; ++i) - priv->cm.rx_sge[i].length = PAGE_SIZE; - priv->cm.rx_wr.next = NULL; - priv->cm.rx_wr.sg_list = priv->cm.rx_sge; - priv->cm.rx_wr.num_sge = priv->cm.num_frags; + ipoib_cm_init_rx_wr(dev, &priv->cm.rx_wr, priv->cm.rx_sge); if (ipoib_cm_has_srq(dev)) { for (i = 0; i < ipoib_recvq_size; ++i) { -- cgit v0.10.2 From 7f624d023b5fb150831e02c1e4c0f2619ade72c2 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: RDMA/core: Add iWARP protocol statistics attributes in sysfs This patch adds a sysfs attribute group called "proto_stats" under /sys/class/infiniband/$device/ and populates this group with protocol statistics if they exist for a given device. Currently, only iWARP stats are defined, but the code is designed to allow InfiniBand protocol stats if they become available. These stats are per-device and more importantly -not- per port. Details: - Add union rdma_protocol_stats in ib_verbs.h. This union allows defining transport-specific stats. Currently only iwarp stats are defined. - Add struct iw_protocol_stats to define the current set of iwarp protocol stats. - Add new ib_device method called get_proto_stats() to return protocol statistics. - Add logic in core/sysfs.c to create iwarp protocol stats attributes if the device is an RNIC and has a get_proto_stats() method. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 36a0ef9..4d10421 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -663,6 +663,120 @@ static struct class ib_class = { .dev_uevent = ib_device_uevent, }; +/* Show a given an attribute in the statistics group */ +static ssize_t show_protocol_stat(const struct device *device, + struct device_attribute *attr, char *buf, + unsigned offset) +{ + struct ib_device *dev = container_of(device, struct ib_device, dev); + union rdma_protocol_stats stats; + ssize_t ret; + + ret = dev->get_protocol_stats(dev, &stats); + if (ret) + return ret; + + return sprintf(buf, "%llu\n", + (unsigned long long) ((u64 *) &stats)[offset]); +} + +/* generate a read-only iwarp statistics attribute */ +#define IW_STATS_ENTRY(name) \ +static ssize_t show_##name(struct device *device, \ + struct device_attribute *attr, char *buf) \ +{ \ + return show_protocol_stat(device, attr, buf, \ + offsetof(struct iw_protocol_stats, name) / \ + sizeof (u64)); \ +} \ +static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) + +IW_STATS_ENTRY(ipInReceives); +IW_STATS_ENTRY(ipInHdrErrors); +IW_STATS_ENTRY(ipInTooBigErrors); +IW_STATS_ENTRY(ipInNoRoutes); +IW_STATS_ENTRY(ipInAddrErrors); +IW_STATS_ENTRY(ipInUnknownProtos); +IW_STATS_ENTRY(ipInTruncatedPkts); +IW_STATS_ENTRY(ipInDiscards); +IW_STATS_ENTRY(ipInDelivers); +IW_STATS_ENTRY(ipOutForwDatagrams); +IW_STATS_ENTRY(ipOutRequests); +IW_STATS_ENTRY(ipOutDiscards); +IW_STATS_ENTRY(ipOutNoRoutes); +IW_STATS_ENTRY(ipReasmTimeout); +IW_STATS_ENTRY(ipReasmReqds); +IW_STATS_ENTRY(ipReasmOKs); +IW_STATS_ENTRY(ipReasmFails); +IW_STATS_ENTRY(ipFragOKs); +IW_STATS_ENTRY(ipFragFails); +IW_STATS_ENTRY(ipFragCreates); +IW_STATS_ENTRY(ipInMcastPkts); +IW_STATS_ENTRY(ipOutMcastPkts); +IW_STATS_ENTRY(ipInBcastPkts); +IW_STATS_ENTRY(ipOutBcastPkts); +IW_STATS_ENTRY(tcpRtoAlgorithm); +IW_STATS_ENTRY(tcpRtoMin); +IW_STATS_ENTRY(tcpRtoMax); +IW_STATS_ENTRY(tcpMaxConn); +IW_STATS_ENTRY(tcpActiveOpens); +IW_STATS_ENTRY(tcpPassiveOpens); +IW_STATS_ENTRY(tcpAttemptFails); +IW_STATS_ENTRY(tcpEstabResets); +IW_STATS_ENTRY(tcpCurrEstab); +IW_STATS_ENTRY(tcpInSegs); +IW_STATS_ENTRY(tcpOutSegs); +IW_STATS_ENTRY(tcpRetransSegs); +IW_STATS_ENTRY(tcpInErrs); +IW_STATS_ENTRY(tcpOutRsts); + +static struct attribute *iw_proto_stats_attrs[] = { + &dev_attr_ipInReceives.attr, + &dev_attr_ipInHdrErrors.attr, + &dev_attr_ipInTooBigErrors.attr, + &dev_attr_ipInNoRoutes.attr, + &dev_attr_ipInAddrErrors.attr, + &dev_attr_ipInUnknownProtos.attr, + &dev_attr_ipInTruncatedPkts.attr, + &dev_attr_ipInDiscards.attr, + &dev_attr_ipInDelivers.attr, + &dev_attr_ipOutForwDatagrams.attr, + &dev_attr_ipOutRequests.attr, + &dev_attr_ipOutDiscards.attr, + &dev_attr_ipOutNoRoutes.attr, + &dev_attr_ipReasmTimeout.attr, + &dev_attr_ipReasmReqds.attr, + &dev_attr_ipReasmOKs.attr, + &dev_attr_ipReasmFails.attr, + &dev_attr_ipFragOKs.attr, + &dev_attr_ipFragFails.attr, + &dev_attr_ipFragCreates.attr, + &dev_attr_ipInMcastPkts.attr, + &dev_attr_ipOutMcastPkts.attr, + &dev_attr_ipInBcastPkts.attr, + &dev_attr_ipOutBcastPkts.attr, + &dev_attr_tcpRtoAlgorithm.attr, + &dev_attr_tcpRtoMin.attr, + &dev_attr_tcpRtoMax.attr, + &dev_attr_tcpMaxConn.attr, + &dev_attr_tcpActiveOpens.attr, + &dev_attr_tcpPassiveOpens.attr, + &dev_attr_tcpAttemptFails.attr, + &dev_attr_tcpEstabResets.attr, + &dev_attr_tcpCurrEstab.attr, + &dev_attr_tcpInSegs.attr, + &dev_attr_tcpOutSegs.attr, + &dev_attr_tcpRetransSegs.attr, + &dev_attr_tcpInErrs.attr, + &dev_attr_tcpOutRsts.attr, + NULL +}; + +static struct attribute_group iw_stats_group = { + .name = "proto_stats", + .attrs = iw_proto_stats_attrs, +}; + int ib_device_register_sysfs(struct ib_device *device) { struct device *class_dev = &device->dev; @@ -705,6 +819,12 @@ int ib_device_register_sysfs(struct ib_device *device) } } + if (device->node_type == RDMA_NODE_RNIC && device->get_protocol_stats) { + ret = sysfs_create_group(&class_dev->kobj, &iw_stats_group); + if (ret) + goto err_put; + } + return 0; err_put: diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 74c24b9..10ebaaa 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -226,6 +226,57 @@ static inline int ib_width_enum_to_int(enum ib_port_width width) } } +struct ib_protocol_stats { + /* TBD... */ +}; + +struct iw_protocol_stats { + u64 ipInReceives; + u64 ipInHdrErrors; + u64 ipInTooBigErrors; + u64 ipInNoRoutes; + u64 ipInAddrErrors; + u64 ipInUnknownProtos; + u64 ipInTruncatedPkts; + u64 ipInDiscards; + u64 ipInDelivers; + u64 ipOutForwDatagrams; + u64 ipOutRequests; + u64 ipOutDiscards; + u64 ipOutNoRoutes; + u64 ipReasmTimeout; + u64 ipReasmReqds; + u64 ipReasmOKs; + u64 ipReasmFails; + u64 ipFragOKs; + u64 ipFragFails; + u64 ipFragCreates; + u64 ipInMcastPkts; + u64 ipOutMcastPkts; + u64 ipInBcastPkts; + u64 ipOutBcastPkts; + + u64 tcpRtoAlgorithm; + u64 tcpRtoMin; + u64 tcpRtoMax; + u64 tcpMaxConn; + u64 tcpActiveOpens; + u64 tcpPassiveOpens; + u64 tcpAttemptFails; + u64 tcpEstabResets; + u64 tcpCurrEstab; + u64 tcpInSegs; + u64 tcpOutSegs; + u64 tcpRetransSegs; + u64 tcpInErrs; + u64 tcpOutRsts; +}; + +union rdma_protocol_stats { + struct ib_protocol_stats ib; + struct iw_protocol_stats iw; +}; + struct ib_port_attr { enum ib_port_state state; enum ib_mtu max_mtu; @@ -943,6 +994,8 @@ struct ib_device { struct iw_cm_verbs *iwcm; + int (*get_protocol_stats)(struct ib_device *device, + union rdma_protocol_stats *stats); int (*query_device)(struct ib_device *device, struct ib_device_attr *device_attr); int (*query_port)(struct ib_device *device, -- cgit v0.10.2 From 14cc180f7b032f8484c1a3d0533b1129ffe307fd Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: RDMA/cxgb3: Add support for protocol statistics - Add a new rdma ctl command called RDMA_GET_MIB to the cxgb3 low level driver to obtain the protocol mib from the rnic hardware. - Add new iw_cxgb3 provider method to get the MIB from the low level driver. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 5f43806..18a6609 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -56,6 +56,7 @@ #include "iwch_provider.h" #include "iwch_cm.h" #include "iwch_user.h" +#include "common.h" static int iwch_modify_port(struct ib_device *ibdev, u8 port, int port_modify_mask, @@ -1245,6 +1246,61 @@ static ssize_t show_board(struct device *dev, struct device_attribute *attr, iwch_dev->rdev.rnic_info.pdev->device); } +static int iwch_get_mib(struct ib_device *ibdev, + union rdma_protocol_stats *stats) +{ + struct iwch_dev *dev; + struct tp_mib_stats m; + int ret; + + PDBG("%s ibdev %p\n", __func__, ibdev); + dev = to_iwch_dev(ibdev); + ret = dev->rdev.t3cdev_p->ctl(dev->rdev.t3cdev_p, RDMA_GET_MIB, &m); + if (ret) + return -ENOSYS; + + memset(stats, 0, sizeof *stats); + stats->iw.ipInReceives = ((u64) m.ipInReceive_hi << 32) + + m.ipInReceive_lo; + stats->iw.ipInHdrErrors = ((u64) m.ipInHdrErrors_hi << 32) + + m.ipInHdrErrors_lo; + stats->iw.ipInAddrErrors = ((u64) m.ipInAddrErrors_hi << 32) + + m.ipInAddrErrors_lo; + stats->iw.ipInUnknownProtos = ((u64) m.ipInUnknownProtos_hi << 32) + + m.ipInUnknownProtos_lo; + stats->iw.ipInDiscards = ((u64) m.ipInDiscards_hi << 32) + + m.ipInDiscards_lo; + stats->iw.ipInDelivers = ((u64) m.ipInDelivers_hi << 32) + + m.ipInDelivers_lo; + stats->iw.ipOutRequests = ((u64) m.ipOutRequests_hi << 32) + + m.ipOutRequests_lo; + stats->iw.ipOutDiscards = ((u64) m.ipOutDiscards_hi << 32) + + m.ipOutDiscards_lo; + stats->iw.ipOutNoRoutes = ((u64) m.ipOutNoRoutes_hi << 32) + + m.ipOutNoRoutes_lo; + stats->iw.ipReasmTimeout = (u64) m.ipReasmTimeout; + stats->iw.ipReasmReqds = (u64) m.ipReasmReqds; + stats->iw.ipReasmOKs = (u64) m.ipReasmOKs; + stats->iw.ipReasmFails = (u64) m.ipReasmFails; + stats->iw.tcpActiveOpens = (u64) m.tcpActiveOpens; + stats->iw.tcpPassiveOpens = (u64) m.tcpPassiveOpens; + stats->iw.tcpAttemptFails = (u64) m.tcpAttemptFails; + stats->iw.tcpEstabResets = (u64) m.tcpEstabResets; + stats->iw.tcpOutRsts = (u64) m.tcpOutRsts; + stats->iw.tcpCurrEstab = (u64) m.tcpCurrEstab; + stats->iw.tcpInSegs = ((u64) m.tcpInSegs_hi << 32) + + m.tcpInSegs_lo; + stats->iw.tcpOutSegs = ((u64) m.tcpOutSegs_hi << 32) + + m.tcpOutSegs_lo; + stats->iw.tcpRetransSegs = ((u64) m.tcpRetransSeg_hi << 32) + + m.tcpRetransSeg_lo; + stats->iw.tcpInErrs = ((u64) m.tcpInErrs_hi << 32) + + m.tcpInErrs_lo; + stats->iw.tcpRtoMin = (u64) m.tcpRtoMin; + stats->iw.tcpRtoMax = (u64) m.tcpRtoMax; + return 0; +} + static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); @@ -1254,7 +1310,7 @@ static struct device_attribute *iwch_class_attributes[] = { &dev_attr_hw_rev, &dev_attr_fw_ver, &dev_attr_hca_type, - &dev_attr_board_id + &dev_attr_board_id, }; int iwch_register_device(struct iwch_dev *dev) @@ -1325,15 +1381,13 @@ int iwch_register_device(struct iwch_dev *dev) dev->ibdev.alloc_fast_reg_mr = iwch_alloc_fast_reg_mr; dev->ibdev.alloc_fast_reg_page_list = iwch_alloc_fastreg_pbl; dev->ibdev.free_fast_reg_page_list = iwch_free_fastreg_pbl; - dev->ibdev.attach_mcast = iwch_multicast_attach; dev->ibdev.detach_mcast = iwch_multicast_detach; dev->ibdev.process_mad = iwch_process_mad; - dev->ibdev.req_notify_cq = iwch_arm_cq; dev->ibdev.post_send = iwch_post_send; dev->ibdev.post_recv = iwch_post_receive; - + dev->ibdev.get_protocol_stats = iwch_get_mib; dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL); if (!dev->ibdev.iwcm) diff --git a/drivers/net/cxgb3/cxgb3_ctl_defs.h b/drivers/net/cxgb3/cxgb3_ctl_defs.h index 6c4f320..ed0ecd9 100644 --- a/drivers/net/cxgb3/cxgb3_ctl_defs.h +++ b/drivers/net/cxgb3/cxgb3_ctl_defs.h @@ -54,6 +54,7 @@ enum { RDMA_CQ_DISABLE = 16, RDMA_CTRL_QP_SETUP = 17, RDMA_GET_MEM = 18, + RDMA_GET_MIB = 19, GET_RX_PAGE_INFO = 50, }; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index ff9c013..cf26968 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -303,6 +303,12 @@ static int cxgb_rdma_ctl(struct adapter *adapter, unsigned int req, void *data) spin_unlock_irq(&adapter->sge.reg_lock); break; } + case RDMA_GET_MIB: { + spin_lock(&adapter->stats_lock); + t3_tp_get_mib_stats(adapter, (struct tp_mib_stats *)data); + spin_unlock(&adapter->stats_lock); + break; + } default: ret = -EOPNOTSUPP; } @@ -381,6 +387,7 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data) case RDMA_CQ_DISABLE: case RDMA_CTRL_QP_SETUP: case RDMA_GET_MEM: + case RDMA_GET_MIB: if (!offload_running(adapter)) return -EAGAIN; return cxgb_rdma_ctl(adapter, req, data); -- cgit v0.10.2 From 47ee1b9f2e7bf73950602efe0b74fa1a8481f222 Mon Sep 17 00:00:00 2001 From: Ron Livne Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: IB/core: Add support for multicast loopback blocking This patch also adds a creation flag for QPs, IB_QP_CREATE_MULTICAST_BLOCK_LOOPBACK, which when set means that multicast sends from the QP to a group that the QP is attached to will not be looped back to the QP's receive queue. This can be used to save receive resources when a consumer does not want a local copy of multicast traffic; for example IPoIB must waste CPU time throwing away such local copies of multicast traffic. This patch also adds a device capability flag that shows whether a device supports this feature or not. Signed-off-by: Ron Livne Signed-off-by: Roland Dreier diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 10ebaaa..07b41e0 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -104,6 +104,7 @@ enum ib_device_cap_flags { IB_DEVICE_UD_IP_CSUM = (1<<18), IB_DEVICE_UD_TSO = (1<<19), IB_DEVICE_MEM_MGT_EXTENSIONS = (1<<21), + IB_DEVICE_BLOCK_MULTICAST_LOOPBACK = (1<<22), }; enum ib_atomic_cap { @@ -555,7 +556,8 @@ enum ib_qp_type { }; enum ib_qp_create_flags { - IB_QP_CREATE_IPOIB_UD_LSO = 1 << 0, + IB_QP_CREATE_IPOIB_UD_LSO = 1 << 0, + IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK = 1 << 1, }; struct ib_qp_init_attr { -- cgit v0.10.2 From 521e575b9a7324a0bca762622139f69582a042bf Mon Sep 17 00:00:00 2001 From: Ron Livne Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: IB/mlx4: Add support for blocking multicast loopback packets Add support for handling the IB_QP_CREATE_MULTICAST_BLOCK_LOOPBACK flag by using the per-multicast group loopback blocking feature of mlx4 hardware. Signed-off-by: Ron Livne Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 4d61e32..bcf5064 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -90,7 +90,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | IB_DEVICE_PORT_ACTIVE_EVENT | IB_DEVICE_SYS_IMAGE_GUID | - IB_DEVICE_RC_RNR_NAK_GEN; + IB_DEVICE_RC_RNR_NAK_GEN | + IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR) props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR) @@ -437,7 +438,9 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd) static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) { return mlx4_multicast_attach(to_mdev(ibqp->device)->dev, - &to_mqp(ibqp)->mqp, gid->raw); + &to_mqp(ibqp)->mqp, gid->raw, + !!(to_mqp(ibqp)->flags & + MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)); } static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 5cf9947..c4cf5b6 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -101,7 +101,8 @@ struct mlx4_ib_wq { }; enum mlx4_ib_qp_flags { - MLX4_IB_QP_LSO = 1 << 0 + MLX4_IB_QP_LSO = 1 << 0, + MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = 1 << 1, }; struct mlx4_ib_qp { diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 44bbd6c..91590e7 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -511,6 +511,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, } else { qp->sq_no_prefetch = 0; + if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) + qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK; + if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) qp->flags |= MLX4_IB_QP_LSO; @@ -684,10 +687,15 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, struct mlx4_ib_qp *qp; int err; - /* We only support LSO, and only for kernel UD QPs. */ - if (init_attr->create_flags & ~IB_QP_CREATE_IPOIB_UD_LSO) + /* + * We only support LSO and multicast loopback blocking, and + * only for kernel UD QPs. + */ + if (init_attr->create_flags & ~(IB_QP_CREATE_IPOIB_UD_LSO | + IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)) return ERR_PTR(-EINVAL); - if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO && + + if (init_attr->create_flags && (pd->uobject || init_attr->qp_type != IB_QPT_UD)) return ERR_PTR(-EINVAL); @@ -1844,6 +1852,13 @@ done: qp_init_attr->cap = qp_attr->cap; + qp_init_attr->create_flags = 0; + if (qp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK) + qp_init_attr->create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK; + + if (qp->flags & MLX4_IB_QP_LSO) + qp_init_attr->create_flags |= IB_QP_CREATE_IPOIB_UD_LSO; + out: mutex_unlock(&qp->mutex); return err; diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c index 57f7f1f..b4b5787 100644 --- a/drivers/net/mlx4/mcg.c +++ b/drivers/net/mlx4/mcg.c @@ -38,6 +38,9 @@ #include "mlx4.h" +#define MGM_QPN_MASK 0x00FFFFFF +#define MGM_BLCK_LB_BIT 30 + struct mlx4_mgm { __be32 next_gid_index; __be32 members_count; @@ -153,7 +156,8 @@ static int find_mgm(struct mlx4_dev *dev, return err; } -int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) +int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], + int block_mcast_loopback) { struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_cmd_mailbox *mailbox; @@ -202,13 +206,18 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) } for (i = 0; i < members_count; ++i) - if (mgm->qp[i] == cpu_to_be32(qp->qpn)) { + if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) { mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn); err = 0; goto out; } - mgm->qp[members_count++] = cpu_to_be32(qp->qpn); + if (block_mcast_loopback) + mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) | + (1 << MGM_BLCK_LB_BIT)); + else + mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); + mgm->members_count = cpu_to_be32(members_count); err = mlx4_WRITE_MCG(dev, index, mailbox); @@ -283,7 +292,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) members_count = be32_to_cpu(mgm->members_count); for (loc = -1, i = 0; i < members_count; ++i) - if (mgm->qp[i] == cpu_to_be32(qp->qpn)) + if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) loc = i; if (loc == -1) { diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index a744383..81b3dd5 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -398,7 +398,8 @@ int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_waterm int mlx4_INIT_PORT(struct mlx4_dev *dev, int port); int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); -int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); +int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], + int block_mcast_loopback); int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list, -- cgit v0.10.2 From 12406734051a26e9fe4c8568e931dfddbb72d431 Mon Sep 17 00:00:00 2001 From: Ron Livne Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: IPoIB: Use multicast loopback blocking if available Set IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK for IPoIB's UD QPs if supported by the underlying device. This creates an improvement of up to 39% in bandwidth when sending multicast packets with IPoIB, and an improvment of 12% in cpu usage. Signed-off-by: Ron Livne Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 810790a..7b8fa36 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -199,7 +199,10 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) init_attr.recv_cq = priv->recv_cq; if (priv->hca_caps & IB_DEVICE_UD_TSO) - init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO; + init_attr.create_flags |= IB_QP_CREATE_IPOIB_UD_LSO; + + if (priv->hca_caps & IB_DEVICE_BLOCK_MULTICAST_LOOPBACK) + init_attr.create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK; if (dev->features & NETIF_F_SG) init_attr.cap.max_send_sge = MAX_SKB_FRAGS + 1; -- cgit v0.10.2 From af40da894e96d5c826d38be3ea53ee00d9de0367 Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Mon, 14 Jul 2008 23:48:48 -0700 Subject: IPoIB: add LRO support Add "ipoib_use_lro" module parameter to enable LRO and an "ipoib_lro_max_aggr" module parameter to set the max number of packets to be aggregated. Make LRO controllable and LRO statistics accessible through ethtool. Signed-off-by: Vladimir Sokolovsky Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig index 1f76bad..691525c 100644 --- a/drivers/infiniband/ulp/ipoib/Kconfig +++ b/drivers/infiniband/ulp/ipoib/Kconfig @@ -1,6 +1,7 @@ config INFINIBAND_IPOIB tristate "IP-over-InfiniBand" depends on NETDEVICES && INET && (IPV6 || IPV6=n) + select INET_LRO ---help--- Support for the IP-over-InfiniBand protocol (IPoIB). This transports IP packets over InfiniBand so you can use your IB diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 8754b36..2c52257 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -50,6 +50,7 @@ #include #include #include +#include /* constants */ @@ -94,6 +95,9 @@ enum { IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ IPOIB_MCAST_FLAG_ATTACHED = 3, + IPOIB_MAX_LRO_DESCRIPTORS = 8, + IPOIB_LRO_MAX_AGGR = 64, + MAX_SEND_CQE = 16, IPOIB_CM_COPYBREAK = 256, }; @@ -248,6 +252,11 @@ struct ipoib_ethtool_st { u16 max_coalesced_frames; }; +struct ipoib_lro { + struct net_lro_mgr lro_mgr; + struct net_lro_desc lro_desc[IPOIB_MAX_LRO_DESCRIPTORS]; +}; + /* * Device private locking: tx_lock protects members used in TX fast * path (and we use LLTX so upper layers don't do extra locking). @@ -334,6 +343,8 @@ struct ipoib_dev_priv { int hca_caps; struct ipoib_ethtool_st ethtool; struct timer_list poll_timer; + + struct ipoib_lro lro; }; struct ipoib_ah { diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c index 10279b7..66af5c1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c @@ -86,11 +86,57 @@ static int ipoib_set_coalesce(struct net_device *dev, return 0; } +static const char ipoib_stats_keys[][ETH_GSTRING_LEN] = { + "LRO aggregated", "LRO flushed", + "LRO avg aggr", "LRO no desc" +}; + +static void ipoib_get_strings(struct net_device *netdev, u32 stringset, u8 *data) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(data, *ipoib_stats_keys, sizeof(ipoib_stats_keys)); + break; + } +} + +static int ipoib_get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return ARRAY_SIZE(ipoib_stats_keys); + default: + return -EOPNOTSUPP; + } +} + +static void ipoib_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, uint64_t *data) +{ + struct ipoib_dev_priv *priv = netdev_priv(dev); + int index = 0; + + /* Get LRO statistics */ + data[index++] = priv->lro.lro_mgr.stats.aggregated; + data[index++] = priv->lro.lro_mgr.stats.flushed; + if (priv->lro.lro_mgr.stats.flushed) + data[index++] = priv->lro.lro_mgr.stats.aggregated / + priv->lro.lro_mgr.stats.flushed; + else + data[index++] = 0; + data[index++] = priv->lro.lro_mgr.stats.no_desc; +} + static const struct ethtool_ops ipoib_ethtool_ops = { .get_drvinfo = ipoib_get_drvinfo, .get_tso = ethtool_op_get_tso, .get_coalesce = ipoib_get_coalesce, .set_coalesce = ipoib_set_coalesce, + .get_flags = ethtool_op_get_flags, + .set_flags = ethtool_op_set_flags, + .get_strings = ipoib_get_strings, + .get_sset_count = ipoib_get_sset_count, + .get_ethtool_stats = ipoib_get_ethtool_stats, }; void ipoib_set_ethtool_ops(struct net_device *dev) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index eca8518..5d50e52 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -288,7 +288,10 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok)) skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_receive_skb(skb); + if (dev->features & NETIF_F_LRO) + lro_receive_skb(&priv->lro.lro_mgr, skb, NULL); + else + netif_receive_skb(skb); repost: if (unlikely(ipoib_ib_post_receive(dev, wr_id))) @@ -440,6 +443,9 @@ poll_more: } if (done < budget) { + if (dev->features & NETIF_F_LRO) + lro_flush_all(&priv->lro.lro_mgr); + netif_rx_complete(dev, napi); if (unlikely(ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP | diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index bfe1dbf..fead88f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -60,6 +60,15 @@ MODULE_PARM_DESC(send_queue_size, "Number of descriptors in send queue"); module_param_named(recv_queue_size, ipoib_recvq_size, int, 0444); MODULE_PARM_DESC(recv_queue_size, "Number of descriptors in receive queue"); +static int lro; +module_param(lro, bool, 0444); +MODULE_PARM_DESC(lro, "Enable LRO (Large Receive Offload)"); + +static int lro_max_aggr = IPOIB_LRO_MAX_AGGR; +module_param(lro_max_aggr, int, 0644); +MODULE_PARM_DESC(lro_max_aggr, "LRO: Max packets to be aggregated " + "(default = 64)"); + #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG int ipoib_debug_level; @@ -936,6 +945,54 @@ static const struct header_ops ipoib_header_ops = { .create = ipoib_hard_header, }; +static int get_skb_hdr(struct sk_buff *skb, void **iphdr, + void **tcph, u64 *hdr_flags, void *priv) +{ + unsigned int ip_len; + struct iphdr *iph; + + if (unlikely(skb->protocol != htons(ETH_P_IP))) + return -1; + + /* + * In the future we may add an else clause that verifies the + * checksum and allows devices which do not calculate checksum + * to use LRO. + */ + if (unlikely(skb->ip_summed != CHECKSUM_UNNECESSARY)) + return -1; + + /* Check for non-TCP packet */ + skb_reset_network_header(skb); + iph = ip_hdr(skb); + if (iph->protocol != IPPROTO_TCP) + return -1; + + ip_len = ip_hdrlen(skb); + skb_set_transport_header(skb, ip_len); + *tcph = tcp_hdr(skb); + + /* check if IP header and TCP header are complete */ + if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb)) + return -1; + + *hdr_flags = LRO_IPV4 | LRO_TCP; + *iphdr = iph; + + return 0; +} + +static void ipoib_lro_setup(struct ipoib_dev_priv *priv) +{ + priv->lro.lro_mgr.max_aggr = lro_max_aggr; + priv->lro.lro_mgr.max_desc = IPOIB_MAX_LRO_DESCRIPTORS; + priv->lro.lro_mgr.lro_arr = priv->lro.lro_desc; + priv->lro.lro_mgr.get_skb_header = get_skb_hdr; + priv->lro.lro_mgr.features = LRO_F_NAPI; + priv->lro.lro_mgr.dev = priv->dev; + priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; +} + static void ipoib_setup(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -975,6 +1032,8 @@ static void ipoib_setup(struct net_device *dev) priv->dev = dev; + ipoib_lro_setup(priv); + spin_lock_init(&priv->lock); spin_lock_init(&priv->tx_lock); @@ -1152,6 +1211,9 @@ static struct net_device *ipoib_add_port(const char *format, priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; } + if (lro) + priv->dev->features |= NETIF_F_LRO; + /* * Set the full membership bit, so that we join the right * broadcast group, etc. -- cgit v0.10.2 From 038919f29682b00ea95506e959210fc72d1aaf64 Mon Sep 17 00:00:00 2001 From: Joachim Fenkes Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: IB/ehca: Make device table externally visible This gives ehca an autogenerated modalias and therefore enables automatic loading. Signed-off-by: Joachim Fenkes Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 482103e..598844d 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -923,6 +923,7 @@ static struct of_device_id ehca_device_table[] = }, {}, }; +MODULE_DEVICE_TABLE(of, ehca_device_table); static struct of_platform_driver ehca_driver = { .name = "ehca", -- cgit v0.10.2 From ee1e2c82c245a5fb2864e9dbcdaab3390fde3fcc Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: IPoIB: Refresh paths instead of flushing them on SM change events The patch tries to solve the problem of device going down and paths being flushed on an SM change event. The method is to mark the paths as candidates for refresh (by setting the new valid flag to 0), and wait for an ARP probe a new path record query. The solution requires a different and less intrusive handling of SM change event. For that, the second argument of the flush function changes its meaning from a boolean flag to a level. In most cases, SM failover doesn't cause LID change so traffic won't stop. In the rare cases of LID change, the remote host (the one that hadn't changed its LID) will lose connectivity until paths are refreshed. This is no worse than the current state. In fact, preventing the device from going down saves packets that otherwise would be lost. Signed-off-by: Moni Levy Signed-off-by: Moni Shoua Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 2c52257..bb19587 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -54,6 +54,12 @@ /* constants */ +enum ipoib_flush_level { + IPOIB_FLUSH_LIGHT, + IPOIB_FLUSH_NORMAL, + IPOIB_FLUSH_HEAVY +}; + enum { IPOIB_ENCAP_LEN = 4, @@ -284,10 +290,11 @@ struct ipoib_dev_priv { struct delayed_work pkey_poll_task; struct delayed_work mcast_task; - struct work_struct flush_task; + struct work_struct flush_light; + struct work_struct flush_normal; + struct work_struct flush_heavy; struct work_struct restart_task; struct delayed_work ah_reap_task; - struct work_struct pkey_event_task; struct ib_device *ca; u8 port; @@ -369,6 +376,7 @@ struct ipoib_path { struct rb_node rb_node; struct list_head list; + int valid; }; struct ipoib_neigh { @@ -433,11 +441,14 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_ah *address, u32 qpn); void ipoib_reap_ah(struct work_struct *work); +void ipoib_mark_paths_invalid(struct net_device *dev); void ipoib_flush_paths(struct net_device *dev); struct ipoib_dev_priv *ipoib_intf_alloc(const char *format); int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port); -void ipoib_ib_dev_flush(struct work_struct *work); +void ipoib_ib_dev_flush_light(struct work_struct *work); +void ipoib_ib_dev_flush_normal(struct work_struct *work); +void ipoib_ib_dev_flush_heavy(struct work_struct *work); void ipoib_pkey_event(struct work_struct *work); void ipoib_ib_dev_cleanup(struct net_device *dev); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 5d50e52..66cafa2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -902,7 +902,8 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) return 0; } -static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) +static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, + enum ipoib_flush_level level) { struct ipoib_dev_priv *cpriv; struct net_device *dev = priv->dev; @@ -915,7 +916,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) * the parent is down. */ list_for_each_entry(cpriv, &priv->child_intfs, list) - __ipoib_ib_dev_flush(cpriv, pkey_event); + __ipoib_ib_dev_flush(cpriv, level); mutex_unlock(&priv->vlan_mutex); @@ -929,7 +930,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) return; } - if (pkey_event) { + if (level == IPOIB_FLUSH_HEAVY) { if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); ipoib_ib_dev_down(dev, 0); @@ -947,11 +948,15 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) priv->pkey_index = new_index; } - ipoib_dbg(priv, "flushing\n"); + if (level == IPOIB_FLUSH_LIGHT) { + ipoib_mark_paths_invalid(dev); + ipoib_mcast_dev_flush(dev); + } - ipoib_ib_dev_down(dev, 0); + if (level >= IPOIB_FLUSH_NORMAL) + ipoib_ib_dev_down(dev, 0); - if (pkey_event) { + if (level == IPOIB_FLUSH_HEAVY) { ipoib_ib_dev_stop(dev, 0); ipoib_ib_dev_open(dev); } @@ -961,27 +966,34 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) * we get here, don't bring it back up if it's not configured up */ if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { - ipoib_ib_dev_up(dev); + if (level >= IPOIB_FLUSH_NORMAL) + ipoib_ib_dev_up(dev); ipoib_mcast_restart_task(&priv->restart_task); } } -void ipoib_ib_dev_flush(struct work_struct *work) +void ipoib_ib_dev_flush_light(struct work_struct *work) +{ + struct ipoib_dev_priv *priv = + container_of(work, struct ipoib_dev_priv, flush_light); + + __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_LIGHT); +} + +void ipoib_ib_dev_flush_normal(struct work_struct *work) { struct ipoib_dev_priv *priv = - container_of(work, struct ipoib_dev_priv, flush_task); + container_of(work, struct ipoib_dev_priv, flush_normal); - ipoib_dbg(priv, "Flushing %s\n", priv->dev->name); - __ipoib_ib_dev_flush(priv, 0); + __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_NORMAL); } -void ipoib_pkey_event(struct work_struct *work) +void ipoib_ib_dev_flush_heavy(struct work_struct *work) { struct ipoib_dev_priv *priv = - container_of(work, struct ipoib_dev_priv, pkey_event_task); + container_of(work, struct ipoib_dev_priv, flush_heavy); - ipoib_dbg(priv, "Flushing %s and restarting its QP\n", priv->dev->name); - __ipoib_ib_dev_flush(priv, 1); + __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY); } void ipoib_ib_dev_cleanup(struct net_device *dev) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index fead88f..b3fd7e8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -357,6 +357,23 @@ void ipoib_path_iter_read(struct ipoib_path_iter *iter, #endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */ +void ipoib_mark_paths_invalid(struct net_device *dev) +{ + struct ipoib_dev_priv *priv = netdev_priv(dev); + struct ipoib_path *path, *tp; + + spin_lock_irq(&priv->lock); + + list_for_each_entry_safe(path, tp, &priv->path_list, list) { + ipoib_dbg(priv, "mark path LID 0x%04x GID " IPOIB_GID_FMT " invalid\n", + be16_to_cpu(path->pathrec.dlid), + IPOIB_GID_ARG(path->pathrec.dgid)); + path->valid = 0; + } + + spin_unlock_irq(&priv->lock); +} + void ipoib_flush_paths(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -393,6 +410,7 @@ static void path_rec_completion(int status, struct net_device *dev = path->dev; struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_ah *ah = NULL; + struct ipoib_ah *old_ah; struct ipoib_neigh *neigh, *tn; struct sk_buff_head skqueue; struct sk_buff *skb; @@ -416,6 +434,7 @@ static void path_rec_completion(int status, spin_lock_irqsave(&priv->lock, flags); + old_ah = path->ah; path->ah = ah; if (ah) { @@ -428,6 +447,17 @@ static void path_rec_completion(int status, __skb_queue_tail(&skqueue, skb); list_for_each_entry_safe(neigh, tn, &path->neigh_list, list) { + if (neigh->ah) { + WARN_ON(neigh->ah != old_ah); + /* + * Dropping the ah reference inside + * priv->lock is safe here, because we + * will hold one more reference from + * the original value of path->ah (ie + * old_ah). + */ + ipoib_put_ah(neigh->ah); + } kref_get(&path->ah->ref); neigh->ah = path->ah; memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, @@ -450,6 +480,7 @@ static void path_rec_completion(int status, while ((skb = __skb_dequeue(&neigh->queue))) __skb_queue_tail(&skqueue, skb); } + path->valid = 1; } path->query = NULL; @@ -457,6 +488,9 @@ static void path_rec_completion(int status, spin_unlock_irqrestore(&priv->lock, flags); + if (old_ah) + ipoib_put_ah(old_ah); + while ((skb = __skb_dequeue(&skqueue))) { skb->dev = dev; if (dev_queue_xmit(skb)) @@ -630,8 +664,9 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, spin_lock(&priv->lock); path = __path_find(dev, phdr->hwaddr + 4); - if (!path) { - path = path_rec_create(dev, phdr->hwaddr + 4); + if (!path || !path->valid) { + if (!path) + path = path_rec_create(dev, phdr->hwaddr + 4); if (path) { /* put pseudoheader back on for next time */ skb_push(skb, sizeof *phdr); @@ -1046,9 +1081,10 @@ static void ipoib_setup(struct net_device *dev) INIT_LIST_HEAD(&priv->multicast_list); INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll); - INIT_WORK(&priv->pkey_event_task, ipoib_pkey_event); INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); - INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush); + INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); + INIT_WORK(&priv->flush_normal, ipoib_ib_dev_flush_normal); + INIT_WORK(&priv->flush_heavy, ipoib_ib_dev_flush_heavy); INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task); INIT_DELAYED_WORK(&priv->ah_reap_task, ipoib_reap_ah); } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 7b8fa36..96f9aa7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -290,15 +290,17 @@ void ipoib_event(struct ib_event_handler *handler, if (record->element.port_num != priv->port) return; - if (record->event == IB_EVENT_PORT_ERR || - record->event == IB_EVENT_PORT_ACTIVE || - record->event == IB_EVENT_LID_CHANGE || - record->event == IB_EVENT_SM_CHANGE || + ipoib_dbg(priv, "Event %d on device %s port %d\n", record->event, + record->device->name, record->element.port_num); + + if (record->event == IB_EVENT_SM_CHANGE || record->event == IB_EVENT_CLIENT_REREGISTER) { - ipoib_dbg(priv, "Port state change event\n"); - queue_work(ipoib_workqueue, &priv->flush_task); + queue_work(ipoib_workqueue, &priv->flush_light); + } else if (record->event == IB_EVENT_PORT_ERR || + record->event == IB_EVENT_PORT_ACTIVE || + record->event == IB_EVENT_LID_CHANGE) { + queue_work(ipoib_workqueue, &priv->flush_normal); } else if (record->event == IB_EVENT_PKEY_CHANGE) { - ipoib_dbg(priv, "P_Key change event on port:%d\n", priv->port); - queue_work(ipoib_workqueue, &priv->pkey_event_task); + queue_work(ipoib_workqueue, &priv->flush_heavy); } } -- cgit v0.10.2 From 1ff66e8c1faee7c2711b84b9c89e1c5fcd767839 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: RDMA/nes: Encapsulate logic nes_put_cqp_request() The iw_nes driver repeats the logic if (atomic_dec_and_test(&cqp_request->refcount)) { if (cqp_request->dynamic) { kfree(cqp_request); } else { spin_lock_irqsave(&nesdev->cqp.lock, flags); list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); spin_unlock_irqrestore(&nesdev->cqp.lock, flags); } } over and over. Wrap this up in functions nes_free_cqp_request() and nes_put_cqp_request() to simplify such code. In addition to making the source smaller and more readable, this shrinks the compiled code quite a bit: add/remove: 2/0 grow/shrink: 0/13 up/down: 164/-1692 (-1528) function old new delta nes_free_cqp_request - 147 +147 nes_put_cqp_request - 17 +17 nes_modify_qp 2316 2293 -23 nes_hw_modify_qp 737 657 -80 nes_dereg_mr 945 860 -85 flush_wqes 501 416 -85 nes_manage_apbvt 648 560 -88 nes_reg_mr 1117 1026 -91 nes_cqp_ce_handler 927 769 -158 nes_alloc_mw 1052 884 -168 nes_create_qp 5314 5141 -173 nes_alloc_fmr 2212 2035 -177 nes_destroy_cq 1097 918 -179 nes_create_cq 2787 2598 -189 nes_dealloc_mw 762 566 -196 Signed-off-by: Roland Dreier Acked-by: Faisal Latif diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index 61b46e9..fe88bec 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -538,6 +538,10 @@ void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16); void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16); struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); +void nes_free_cqp_request(struct nes_device *nesdev, + struct nes_cqp_request *cqp_request); +void nes_put_cqp_request(struct nes_device *nesdev, + struct nes_cqp_request *cqp_request); void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); int nes_arp_table(struct nes_device *, u32, u8 *, u32); void nes_mh_fix(unsigned long); diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index d3278f1..80e4866 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -2710,39 +2710,11 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) barrier(); cqp_request->request_done = 1; wake_up(&cqp_request->waitq); - if (atomic_dec_and_test(&cqp_request->refcount)) { - nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", - cqp_request, - le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f); - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } - } else if (cqp_request->callback) { - /* Envoke the callback routine */ - cqp_request->cqp_callback(nesdev, cqp_request); - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } + nes_put_cqp_request(nesdev, cqp_request); } else { - nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", - cqp_request, - le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX]) & 0x3f); - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } + if (cqp_request->callback) + cqp_request->cqp_callback(nesdev, cqp_request); + nes_free_cqp_request(nesdev, cqp_request); } } else { wake_up(&nesdev->cqp.waitq); @@ -3149,7 +3121,6 @@ int nes_manage_apbvt(struct nes_vnic *nesvnic, u32 accel_local_port, { struct nes_device *nesdev = nesvnic->nesdev; struct nes_hw_cqp_wqe *cqp_wqe; - unsigned long flags; struct nes_cqp_request *cqp_request; int ret = 0; u16 major_code; @@ -3184,15 +3155,9 @@ int nes_manage_apbvt(struct nes_vnic *nesvnic, u32 accel_local_port, nes_debug(NES_DBG_QP, "Completed, ret=%u, CQP Major:Minor codes = 0x%04X:0x%04X\n", ret, cqp_request->major_code, cqp_request->minor_code); major_code = cqp_request->major_code; - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + + nes_put_cqp_request(nesdev, cqp_request); + if (!ret) return -ETIME; else if (major_code) @@ -3262,7 +3227,6 @@ void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr, void flush_wqes(struct nes_device *nesdev, struct nes_qp *nesqp, u32 which_wq, u32 wait_completion) { - unsigned long flags; struct nes_cqp_request *cqp_request; struct nes_hw_cqp_wqe *cqp_wqe; int ret; @@ -3294,14 +3258,6 @@ void flush_wqes(struct nes_device *nesdev, struct nes_qp *nesqp, nes_debug(NES_DBG_QP, "Flush SQ QP WQEs completed, ret=%u," " CQP Major:Minor codes = 0x%04X:0x%04X\n", ret, cqp_request->major_code, cqp_request->minor_code); - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + nes_put_cqp_request(nesdev, cqp_request); } } diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index fe83d1b..8f519c8 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c @@ -567,6 +567,30 @@ struct nes_cqp_request *nes_get_cqp_request(struct nes_device *nesdev) return cqp_request; } +void nes_free_cqp_request(struct nes_device *nesdev, + struct nes_cqp_request *cqp_request) +{ + unsigned long flags; + + nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", + cqp_request, + le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX]) & 0x3f); + + if (cqp_request->dynamic) { + kfree(cqp_request); + } else { + spin_lock_irqsave(&nesdev->cqp.lock, flags); + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); + } +} + +void nes_put_cqp_request(struct nes_device *nesdev, + struct nes_cqp_request *cqp_request) +{ + if (atomic_dec_and_test(&cqp_request->refcount)) + nes_free_cqp_request(nesdev, cqp_request); +} /** * nes_post_cqp_request diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index d617da9..464a98a 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -55,7 +55,6 @@ static void nes_unregister_ofa_device(struct nes_ib_device *nesibdev); * nes_alloc_mw */ static struct ib_mw *nes_alloc_mw(struct ib_pd *ibpd) { - unsigned long flags; struct nes_pd *nespd = to_nespd(ibpd); struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); struct nes_device *nesdev = nesvnic->nesdev; @@ -128,15 +127,7 @@ static struct ib_mw *nes_alloc_mw(struct ib_pd *ibpd) { " CQP Major:Minor codes = 0x%04X:0x%04X.\n", stag, ret, cqp_request->major_code, cqp_request->minor_code); if ((!ret) || (cqp_request->major_code)) { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + nes_put_cqp_request(nesdev, cqp_request); kfree(nesmr); nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); if (!ret) { @@ -144,17 +135,8 @@ static struct ib_mw *nes_alloc_mw(struct ib_pd *ibpd) { } else { return ERR_PTR(-ENOMEM); } - } else { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } } + nes_put_cqp_request(nesdev, cqp_request); nesmr->ibmw.rkey = stag; nesmr->mode = IWNES_MEMREG_TYPE_MW; @@ -178,7 +160,6 @@ static int nes_dealloc_mw(struct ib_mw *ibmw) struct nes_hw_cqp_wqe *cqp_wqe; struct nes_cqp_request *cqp_request; int err = 0; - unsigned long flags; int ret; /* Deallocate the window with the adapter */ @@ -204,32 +185,12 @@ static int nes_dealloc_mw(struct ib_mw *ibmw) nes_debug(NES_DBG_MR, "Deallocate STag completed, wait_event_timeout ret = %u," " CQP Major:Minor codes = 0x%04X:0x%04X.\n", ret, cqp_request->major_code, cqp_request->minor_code); - if ((!ret) || (cqp_request->major_code)) { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } - if (!ret) { - err = -ETIME; - } else { - err = -EIO; - } - } else { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } - } + if (!ret) + err = -ETIME; + else if (cqp_request->major_code) + err = -EIO; + + nes_put_cqp_request(nesdev, cqp_request); nes_free_resource(nesadapter, nesadapter->allocated_mrs, (ibmw->rkey & 0x0fffff00) >> 8); @@ -526,29 +487,11 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, stag, ret, cqp_request->major_code, cqp_request->minor_code); if ((!ret) || (cqp_request->major_code)) { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + nes_put_cqp_request(nesdev, cqp_request); ret = (!ret) ? -ETIME : -EIO; goto failed_leaf_vpbl_pages_alloc; - } else { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } } - + nes_put_cqp_request(nesdev, cqp_request); nesfmr->nesmr.ibfmr.lkey = stag; nesfmr->nesmr.ibfmr.rkey = stag; nesfmr->attr = *ibfmr_attr; @@ -1487,15 +1430,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, nesqp->hwqp.qp_id, ret, nesdev->cqp.sq_head, nesdev->cqp.sq_tail, cqp_request->major_code, cqp_request->minor_code); if ((!ret) || (cqp_request->major_code)) { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + nes_put_cqp_request(nesdev, cqp_request); nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); nes_free_qp_mem(nesdev, nesqp,virt_wqs); kfree(nesqp->allocated_buffer); @@ -1504,18 +1439,10 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, } else { return ERR_PTR(-EIO); } - } else { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } } + nes_put_cqp_request(nesdev, cqp_request); + if (ibpd->uobject) { uresp.mmap_sq_db_index = nesqp->mmap_sq_db_index; uresp.actual_sq_size = sq_size; @@ -1827,32 +1754,15 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, nes_debug(NES_DBG_CQ, "Create iWARP CQ%u completed, wait_event_timeout ret = %d.\n", nescq->hw_cq.cq_number, ret); if ((!ret) || (cqp_request->major_code)) { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + nes_put_cqp_request(nesdev, cqp_request); if (!context) pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, nescq->hw_cq.cq_pbase); nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); kfree(nescq); return ERR_PTR(-EIO); - } else { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } } + nes_put_cqp_request(nesdev, cqp_request); if (context) { /* free the nespbl */ @@ -1942,37 +1852,18 @@ static int nes_destroy_cq(struct ib_cq *ib_cq) " CQP Major:Minor codes = 0x%04X:0x%04X.\n", nescq->hw_cq.cq_number, ret, cqp_request->major_code, cqp_request->minor_code); - if ((!ret) || (cqp_request->major_code)) { - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } - if (!ret) { - nes_debug(NES_DBG_CQ, "iWARP CQ%u destroy timeout expired\n", + if (!ret) { + nes_debug(NES_DBG_CQ, "iWARP CQ%u destroy timeout expired\n", nescq->hw_cq.cq_number); - ret = -ETIME; - } else { - nes_debug(NES_DBG_CQ, "iWARP CQ%u destroy failed\n", + ret = -ETIME; + } else if (cqp_request->major_code) { + nes_debug(NES_DBG_CQ, "iWARP CQ%u destroy failed\n", nescq->hw_cq.cq_number); - ret = -EIO; - } + ret = -EIO; } else { ret = 0; - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } } + nes_put_cqp_request(nesdev, cqp_request); if (nescq->cq_mem_size) pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, @@ -2105,15 +1996,8 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd, " CQP Major:Minor codes = 0x%04X:0x%04X.\n", stag, ret, cqp_request->major_code, cqp_request->minor_code); major_code = cqp_request->major_code; - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + nes_put_cqp_request(nesdev, cqp_request); + if (!ret) return -ETIME; else if (major_code) @@ -2771,15 +2655,9 @@ static int nes_dereg_mr(struct ib_mr *ib_mr) major_code = cqp_request->major_code; minor_code = cqp_request->minor_code; - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + + nes_put_cqp_request(nesdev, cqp_request); + if (!ret) { nes_debug(NES_DBG_MR, "Timeout waiting to destroy STag," " ib_mr=%p, rkey = 0x%08X\n", @@ -2904,7 +2782,6 @@ int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, /* struct iw_cm_id *cm_id = nesqp->cm_id; */ /* struct iw_cm_event cm_event; */ struct nes_cqp_request *cqp_request; - unsigned long flags; int ret; u16 major_code; @@ -2950,15 +2827,9 @@ int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, nesqp->hwqp.qp_id, cqp_request->major_code, cqp_request->minor_code, next_iwarp_state); } - if (atomic_dec_and_test(&cqp_request->refcount)) { - if (cqp_request->dynamic) { - kfree(cqp_request); - } else { - spin_lock_irqsave(&nesdev->cqp.lock, flags); - list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); - spin_unlock_irqrestore(&nesdev->cqp.lock, flags); - } - } + + nes_put_cqp_request(nesdev, cqp_request); + if (!ret) return -ETIME; else if (major_code) -- cgit v0.10.2 From 52c8084b740c42af27d5bfa62cec7079d12fbc2b Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: RDMA/cxgb3: Propagate HW page size capabilities cxgb3 does not currently report the page size capabilities, and incorrectly reports them internally. This version changes the bit-shifting to a static value (per Steve's request). Signed-off-by: Jon Mason Acked-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index a9ff32c..656fe47 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -55,6 +55,7 @@ #define T3_MAX_CQ_DEPTH 8192 #define T3_MAX_NUM_STAG (1<<15) #define T3_MAX_MR_SIZE 0x100000000ULL +#define T3_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */ #define T3_STAG_UNSET 0xffffffff diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index 0608625..4489c89 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c @@ -80,7 +80,7 @@ static void rnic_init(struct iwch_dev *rnicp) rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev); rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; - rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ + rnicp->attr.mem_pgsizes_bitmask = T3_PAGESIZE_MASK; rnicp->attr.max_mr_size = T3_MAX_MR_SIZE; rnicp->attr.can_resize_wq = 0; rnicp->attr.max_rdma_reads_per_qp = 8; diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 18a6609..249d99f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1130,6 +1130,7 @@ static int iwch_query_device(struct ib_device *ibdev, props->hw_ver = dev->rdev.t3cdev_p->type; props->fw_ver = fw_vers_string_to_u64(dev); props->device_cap_flags = dev->device_cap_flags; + props->page_size_cap = dev->attr.mem_pgsizes_bitmask; props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; props->max_mr_size = dev->attr.max_mr_size; -- cgit v0.10.2 From 8294f29767c53e97664a27db9974adea8e2ea95b Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: RDMA/nes: Get rid of ring_doorbell parameter of nes_post_cqp_request() Every caller of nes_post_cqp_request() passed it NES_CQP_REQUEST_RING_DOORBELL, so just remove that parameter and always ring the doorbell. Signed-off-by: Roland Dreier Acked-by: Faisal Latif diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index a4e9269..d2884e7 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -328,7 +328,7 @@ void nes_rem_ref(struct ib_qp *ibqp) set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id); u64temp = (u64)nesqp->nesqp_context_pbase; set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); } } diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index fe88bec..39bd897 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -94,9 +94,6 @@ #define MAX_DPC_ITERATIONS 128 -#define NES_CQP_REQUEST_NO_DOORBELL_RING 0 -#define NES_CQP_REQUEST_RING_DOORBELL 1 - #define NES_DRV_OPT_ENABLE_MPA_VER_0 0x00000001 #define NES_DRV_OPT_DISABLE_MPA_CRC 0x00000002 #define NES_DRV_OPT_DISABLE_FIRST_WRITE 0x00000004 @@ -542,7 +539,7 @@ void nes_free_cqp_request(struct nes_device *nesdev, struct nes_cqp_request *cqp_request); void nes_put_cqp_request(struct nes_device *nesdev, struct nes_cqp_request *cqp_request); -void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); +void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *); int nes_arp_table(struct nes_device *, u32, u8 *, u32); void nes_mh_fix(unsigned long); void nes_clc(unsigned long); diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 80e4866..902b137 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -3147,7 +3147,7 @@ int nes_manage_apbvt(struct nes_vnic *nesvnic, u32 accel_local_port, nes_debug(NES_DBG_QP, "Waiting for CQP completion for APBVT.\n"); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); if (add_port == NES_MANAGE_APBVT_ADD) ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), @@ -3217,7 +3217,7 @@ void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr, nesdev->cqp.sq_head, nesdev->cqp.sq_tail); atomic_set(&cqp_request->refcount, 1); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); } @@ -3249,7 +3249,7 @@ void flush_wqes(struct nes_device *nesdev, struct nes_qp *nesqp, cpu_to_le32(NES_CQP_FLUSH_WQES | which_wq); cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesqp->hwqp.qp_id); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); if (wait_completion) { /* Wait for CQP */ diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 745bf94..7b81e0a 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -1172,7 +1172,7 @@ struct nes_vnic { u32 mcrq_qp_id; struct nes_ucontext *mcrq_ucontext; struct nes_cqp_request* (*get_cqp_request)(struct nes_device *nesdev); - void (*post_cqp_request)(struct nes_device*, struct nes_cqp_request *, int); + void (*post_cqp_request)(struct nes_device*, struct nes_cqp_request *); int (*mcrq_mcast_filter)( struct nes_vnic* nesvnic, __u8* dmi_addr ); struct net_device_stats netstats; /* used to put the netdev on the adapters logical port list */ diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index 8f519c8..fb8cbd7 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c @@ -596,7 +596,7 @@ void nes_put_cqp_request(struct nes_device *nesdev, * nes_post_cqp_request */ void nes_post_cqp_request(struct nes_device *nesdev, - struct nes_cqp_request *cqp_request, int ring_doorbell) + struct nes_cqp_request *cqp_request) { struct nes_hw_cqp_wqe *cqp_wqe; unsigned long flags; @@ -624,10 +624,9 @@ void nes_post_cqp_request(struct nes_device *nesdev, nesdev->cqp.sq_head, nesdev->cqp.sq_tail, nesdev->cqp.sq_size, cqp_request->waiting, atomic_read(&cqp_request->refcount)); barrier(); - if (ring_doorbell) { - /* Ring doorbell (1 WQEs) */ - nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id); - } + + /* Ring doorbell (1 WQEs) */ + nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id); barrier(); } else { diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 464a98a..e3939d1 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -118,7 +118,7 @@ static struct ib_mw *nes_alloc_mw(struct ib_pd *ibpd) { set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), @@ -175,7 +175,7 @@ static int nes_dealloc_mw(struct ib_mw *ibmw) set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, ibmw->rkey); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ nes_debug(NES_DBG_MR, "Waiting for deallocate STag 0x%08X to complete.\n", @@ -477,7 +477,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, (nesfmr->nesmr.pbls_used-1) : nesfmr->nesmr.pbls_used); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), @@ -1417,7 +1417,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ nes_debug(NES_DBG_QP, "Waiting for create iWARP QP%u to complete.\n", @@ -1744,7 +1744,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ nes_debug(NES_DBG_CQ, "Waiting for create iWARP CQ%u to complete.\n", @@ -1841,7 +1841,7 @@ static int nes_destroy_cq(struct ib_cq *ib_cq) (nescq->hw_cq.cq_number | ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 16))); nes_free_resource(nesadapter, nesadapter->allocated_cqs, nescq->hw_cq.cq_number); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ nes_debug(NES_DBG_CQ, "Waiting for destroy iWARP CQ%u to complete.\n", @@ -1987,7 +1987,7 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd, barrier(); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ ret = wait_event_timeout(cqp_request->waitq, (0 != cqp_request->request_done), @@ -2638,7 +2638,7 @@ static int nes_dereg_mr(struct ib_mr *ib_mr) set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, ib_mr->rkey); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ nes_debug(NES_DBG_MR, "Waiting for deallocate STag 0x%08X completed\n", ib_mr->rkey); @@ -2809,7 +2809,7 @@ int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, (u64)nesqp->nesqp_context_pbase); atomic_set(&cqp_request->refcount, 2); - nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); + nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ if (wait_completion) { -- cgit v0.10.2 From 70fe1796a5ebc5f955be39bba5c42eee9eb89e1f Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:49 -0700 Subject: RDMA/cxgb3: Set rkey field for new memory windows in iwch_alloc_mw() Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 249d99f..c9a3893 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -748,6 +748,7 @@ static struct ib_mw *iwch_alloc_mw(struct ib_pd *pd) mhp->attr.type = TPT_MW; mhp->attr.stag = stag; mmid = (stag) >> 8; + mhp->ibmw.rkey = stag; insert_handle(rhp, &rhp->mmidr, mhp, mmid); PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag); return &(mhp->ibmw); -- cgit v0.10.2 From c03d4731b5b6de45b95a10bf1d510dde423d6757 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: IPoIB: Remove unused IPOIB_MCAST_STARTED code The IPOIB_MCAST_STARTED flag is not used at all since commit b3e2749b ("IPoIB: Don't drop multicast sends when they can be queued"), so remove it. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index bb19587..66a8975 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -89,7 +89,6 @@ enum { IPOIB_FLAG_SUBINTERFACE = 5, IPOIB_MCAST_RUN = 6, IPOIB_STOP_REAPER = 7, - IPOIB_MCAST_STARTED = 8, IPOIB_FLAG_ADMIN_CM = 9, IPOIB_FLAG_UMCAST = 10, IPOIB_FLAG_CSUM = 11, diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 4a6538b..0b7d129 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -592,10 +592,6 @@ int ipoib_mcast_start_thread(struct net_device *dev) queue_delayed_work(ipoib_workqueue, &priv->mcast_task, 0); mutex_unlock(&mcast_mutex); - spin_lock_irq(&priv->lock); - set_bit(IPOIB_MCAST_STARTED, &priv->flags); - spin_unlock_irq(&priv->lock); - return 0; } @@ -605,10 +601,6 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) ipoib_dbg_mcast(priv, "stopping multicast thread\n"); - spin_lock_irq(&priv->lock); - clear_bit(IPOIB_MCAST_STARTED, &priv->flags); - spin_unlock_irq(&priv->lock); - mutex_lock(&mcast_mutex); clear_bit(IPOIB_MCAST_RUN, &priv->flags); cancel_delayed_work(&priv->mcast_task); -- cgit v0.10.2 From 5892eff91ad60ba365ae7f75050ce464036c5396 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: IPoIB: Remove priv->mcast_mutex No need for a mutex around calls to ib_attach_mcast/ib_detach_mcast since these operations are synchronized at the HW driver layer. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 66a8975..b875322 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -277,7 +277,6 @@ struct ipoib_dev_priv { unsigned long flags; - struct mutex mcast_mutex; struct mutex vlan_mutex; struct rb_root path_tree; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index b3fd7e8..8be9ea0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1072,7 +1072,6 @@ static void ipoib_setup(struct net_device *dev) spin_lock_init(&priv->lock); spin_lock_init(&priv->tx_lock); - mutex_init(&priv->mcast_mutex); mutex_init(&priv->vlan_mutex); INIT_LIST_HEAD(&priv->path_list); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 96f9aa7..f50ebe0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -61,9 +61,7 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) } /* attach QP to multicast group */ - mutex_lock(&priv->mcast_mutex); ret = ib_attach_mcast(priv->qp, mgid, mlid); - mutex_unlock(&priv->mcast_mutex); if (ret) ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret); @@ -77,9 +75,7 @@ int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid) struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; - mutex_lock(&priv->mcast_mutex); ret = ib_detach_mcast(priv->qp, mgid, mlid); - mutex_unlock(&priv->mcast_mutex); if (ret) ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); -- cgit v0.10.2 From d0de13622d5ac658efe7c51521dbdbe0752aa3dd Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: IPoIB: Only set Q_Key once: after joining broadcast group The current code will set the Q_Key for any join of a non-sendonly multicast group. The operation involves a modify QP operation, which is fairly heavyweight, and is only really required after the join of the broadcast group. Fix this by adding a parameter to ipoib_mcast_attach() to control when the Q_Key is set. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index b875322..7b46e2d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -485,7 +485,7 @@ void ipoib_path_iter_read(struct ipoib_path_iter *iter, #endif int ipoib_mcast_attach(struct net_device *dev, u16 mlid, - union ib_gid *mgid); + union ib_gid *mgid, int set_qkey); int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 0b7d129..55ebd95 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -186,6 +186,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_ah *ah; int ret; + int set_qkey = 0; mcast->mcmember = *mcmember; @@ -200,6 +201,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); spin_unlock_irq(&priv->lock); priv->tx_wr.wr.ud.remote_qkey = priv->qkey; + set_qkey = 1; } if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { @@ -212,7 +214,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, } ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid), - &mcast->mcmember.mgid); + &mcast->mcmember.mgid, set_qkey); if (ret < 0) { ipoib_warn(priv, "couldn't attach QP to multicast group " IPOIB_GID_FMT "\n", diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index f50ebe0..ba7c886 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -33,18 +33,13 @@ #include "ipoib.h" -int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) +int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey) { struct ipoib_dev_priv *priv = netdev_priv(dev); - struct ib_qp_attr *qp_attr; + struct ib_qp_attr *qp_attr = NULL; int ret; u16 pkey_index; - ret = -ENOMEM; - qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); - if (!qp_attr) - goto out; - if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) { clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); ret = -ENXIO; @@ -52,12 +47,19 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) } set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); - /* set correct QKey for QP */ - qp_attr->qkey = priv->qkey; - ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY); - if (ret) { - ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret); - goto out; + if (set_qkey) { + ret = -ENOMEM; + qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); + if (!qp_attr) + goto out; + + /* set correct QKey for QP */ + qp_attr->qkey = priv->qkey; + ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY); + if (ret) { + ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret); + goto out; + } } /* attach QP to multicast group */ -- cgit v0.10.2 From 9eae554c171e086c89ab83da2a2d3c8bf958fcb5 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:50 -0700 Subject: IPoIB: Get rid of ipoib_mcast_detach() wrapper ipoib_mcast_detach() does nothing except call ib_detach_mcast(), so just use the core API in the one place that does a multicast group detach. add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-105 (-105) function old new delta ipoib_mcast_leave 357 319 -38 ipoib_mcast_detach 67 - -67 Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 7b46e2d..a89b9fb 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -486,8 +486,6 @@ void ipoib_path_iter_read(struct ipoib_path_iter *iter, int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey); -int ipoib_mcast_detach(struct net_device *dev, u16 mlid, - union ib_gid *mgid); int ipoib_init_qp(struct net_device *dev); int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 55ebd95..71add7a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -627,10 +627,10 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) IPOIB_GID_ARG(mcast->mcmember.mgid)); /* Remove ourselves from the multicast group */ - ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid), - &mcast->mcmember.mgid); + ret = ib_detach_mcast(priv->qp, &mcast->mcmember.mgid, + be16_to_cpu(mcast->mcmember.mlid)); if (ret) - ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret); + ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); } return 0; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index ba7c886..6832511 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -72,18 +72,6 @@ out: return ret; } -int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid) -{ - struct ipoib_dev_priv *priv = netdev_priv(dev); - int ret; - - ret = ib_detach_mcast(priv->qp, mgid, mlid); - if (ret) - ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); - - return ret; -} - int ipoib_init_qp(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); -- cgit v0.10.2 From c8c2afe360b7366f586f6bece1109a72ea334876 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:51 -0700 Subject: IPoIB: Use rtnl lock/unlock when changing device flags Use of this lock is required to synchronize changes to the netdvice's data structs. Also move the call to ipoib_flush_paths() after the modification of the netdevice flags in set_mode(). Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 37bf67b..b426913 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -1440,7 +1440,9 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, ipoib_warn(priv, "enabling connected mode " "will cause multicast packet drops\n"); + rtnl_lock(); dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO); + rtnl_unlock(); priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; ipoib_flush_paths(dev); @@ -1449,14 +1451,16 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, if (!strcmp(buf, "datagram\n")) { clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); - dev->mtu = min(priv->mcast_mtu, dev->mtu); - ipoib_flush_paths(dev); + rtnl_lock(); if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) { dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; if (priv->hca_caps & IB_DEVICE_UD_TSO) dev->features |= NETIF_F_TSO; } + dev->mtu = min(priv->mcast_mtu, dev->mtu); + rtnl_unlock(); + ipoib_flush_paths(dev); return count; } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 71add7a..be1ed38 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -575,8 +575,11 @@ void ipoib_mcast_join_task(struct work_struct *work) priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu)); - if (!ipoib_cm_admin_enabled(dev)) + if (!ipoib_cm_admin_enabled(dev)) { + rtnl_lock(); dev->mtu = min(priv->mcast_mtu, priv->admin_mtu); + rtnl_unlock(); + } ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n"); -- cgit v0.10.2 From bd3606715effbf37df986548c43bbed0842b49d5 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:51 -0700 Subject: IPoIB: Use dev_set_mtu() to change mtu When the driver sets the MTU of the net device outside of its change_mtu method, it should make use of dev_set_mtu() instead of directly setting the mtu field of struct netdevice. Otherwise functions registered to be called upon MTU change will not get called (this is done through call_netdevice_notifiers() in dev_set_mtu()). Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index b426913..87f9f3e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -1458,7 +1458,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, if (priv->hca_caps & IB_DEVICE_UD_TSO) dev->features |= NETIF_F_TSO; } - dev->mtu = min(priv->mcast_mtu, dev->mtu); + dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); rtnl_unlock(); ipoib_flush_paths(dev); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index be1ed38..1fcc9a8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -577,7 +577,7 @@ void ipoib_mcast_join_task(struct work_struct *work) if (!ipoib_cm_admin_enabled(dev)) { rtnl_lock(); - dev->mtu = min(priv->mcast_mtu, priv->admin_mtu); + dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu)); rtnl_unlock(); } -- cgit v0.10.2 From df8666198dd058b9498ebdbc52c61957206d30a5 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: IB/ipath: Use IEEE OUI for vendor_id reported by ibv_query_device() The IB spe. for SubnGet(NodeInfo) and query HCA says that the vendor ID field should be the IEEE OUI assigned to the vendor. The ipath driver was returning the PCI vendor ID instead. This will affect applications which call ibv_query_device(). The old value was 0x001fc1 or 0x001077, the new value is 0x001175. The vendor ID doesn't appear to be exported via /sys so that should reduce possible compatibility issues. I'm only aware of Open MPI as a major application which depends on this change, and they have made necessary adjustments. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index 5f9315d..be4fc9a 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c @@ -111,9 +111,9 @@ static int recv_subn_get_nodeinfo(struct ib_smp *smp, nip->revision = cpu_to_be32((majrev << 16) | minrev); nip->local_port_num = port; vendor = dd->ipath_vendorid; - nip->vendor_id[0] = 0; - nip->vendor_id[1] = vendor >> 8; - nip->vendor_id[2] = vendor; + nip->vendor_id[0] = IPATH_SRC_OUI_1; + nip->vendor_id[1] = IPATH_SRC_OUI_2; + nip->vendor_id[2] = IPATH_SRC_OUI_3; return reply(smp); } diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 7779165..9e23ab0 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -1497,7 +1497,8 @@ static int ipath_query_device(struct ib_device *ibdev, IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN | IB_DEVICE_PORT_ACTIVE_EVENT | IB_DEVICE_SRQ_RESIZE; props->page_size_cap = PAGE_SIZE; - props->vendor_id = dev->dd->ipath_vendorid; + props->vendor_id = + IPATH_SRC_OUI_1 << 16 | IPATH_SRC_OUI_2 << 8 | IPATH_SRC_OUI_3; props->vendor_part_id = dev->dd->ipath_deviceid; props->hw_ver = dev->dd->ipath_pcirev; -- cgit v0.10.2 From e112373fd6aa280bd2cbc0d5cc3809115325a1be Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: IPoIB/cm: Reduce connected mode TX object size Since IPoIB connected mode does not NETIF_F_SG, we only have one DMA mapping per send, so we don't need a mapping[] array. Define a new struct with a single u64 mapping member and use it for the CM tx_ring. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index a89b9fb..0281c8f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -157,6 +157,11 @@ struct ipoib_tx_buf { u64 mapping[MAX_SKB_FRAGS + 1]; }; +struct ipoib_cm_tx_buf { + struct sk_buff *skb; + u64 mapping; +}; + struct ib_cm_id; struct ipoib_cm_data { @@ -215,7 +220,7 @@ struct ipoib_cm_tx { struct net_device *dev; struct ipoib_neigh *neigh; struct ipoib_path *path; - struct ipoib_tx_buf *tx_ring; + struct ipoib_cm_tx_buf *tx_ring; unsigned tx_head; unsigned tx_tail; unsigned long flags; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 87f9f3e..0f2d304 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -703,7 +703,7 @@ static inline int post_send(struct ipoib_dev_priv *priv, void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx) { struct ipoib_dev_priv *priv = netdev_priv(dev); - struct ipoib_tx_buf *tx_req; + struct ipoib_cm_tx_buf *tx_req; u64 addr; if (unlikely(skb->len > tx->mtu)) { @@ -734,7 +734,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ return; } - tx_req->mapping[0] = addr; + tx_req->mapping = addr; if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), addr, skb->len))) { @@ -759,7 +759,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_cm_tx *tx = wc->qp->qp_context; unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM; - struct ipoib_tx_buf *tx_req; + struct ipoib_cm_tx_buf *tx_req; unsigned long flags; ipoib_dbg_data(priv, "cm send completion: id %d, status: %d\n", @@ -773,7 +773,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) tx_req = &tx->tx_ring[wr_id]; - ib_dma_unmap_single(priv->ca, tx_req->mapping[0], tx_req->skb->len, DMA_TO_DEVICE); + ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE); /* FIXME: is this right? Shouldn't we only increment on success? */ ++dev->stats.tx_packets; @@ -1143,7 +1143,7 @@ err_tx: static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p) { struct ipoib_dev_priv *priv = netdev_priv(p->dev); - struct ipoib_tx_buf *tx_req; + struct ipoib_cm_tx_buf *tx_req; unsigned long flags; unsigned long begin; @@ -1171,7 +1171,7 @@ timeout: while ((int) p->tx_tail - (int) p->tx_head < 0) { tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)]; - ib_dma_unmap_single(priv->ca, tx_req->mapping[0], tx_req->skb->len, + ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(tx_req->skb); ++p->tx_tail; -- cgit v0.10.2 From bc3a290b51aaefc6a6af2d6e6d52ed32387c416c Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: IPoIB: Double default RX/TX ring sizes Increase IPoIB ring sizes to twice their original sizes (RX: 128->256, TX: 64->128) to act as a shock absorber for high traffic peaks. With the current settings, we have seen cases that there are many calls to netif_stop_queue(), which causes degradation in throughput. Also, larger receive buffer sizes help IPoIB in CM mode to avoid experiencing RNR NAK conditions due to insufficient receive buffers at the SRQ. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 0281c8f..b0ffc9a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -70,8 +70,8 @@ enum { IPOIB_CM_BUF_SIZE = IPOIB_CM_MTU + IPOIB_ENCAP_LEN, IPOIB_CM_HEAD_SIZE = IPOIB_CM_BUF_SIZE % PAGE_SIZE, IPOIB_CM_RX_SG = ALIGN(IPOIB_CM_BUF_SIZE, PAGE_SIZE) / PAGE_SIZE, - IPOIB_RX_RING_SIZE = 128, - IPOIB_TX_RING_SIZE = 64, + IPOIB_RX_RING_SIZE = 256, + IPOIB_TX_RING_SIZE = 128, IPOIB_MAX_QUEUE_SIZE = 8192, IPOIB_MIN_QUEUE_SIZE = 2, IPOIB_CM_MAX_CONN_QP = 4096, -- cgit v0.10.2 From 4522e08ced48baaf28990e2674e940aae9940310 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: IB/mthca: Remove "stop" flag for catastrophic error polling timer Since we use del_timer_sync() anyway, there's no need for an additional flag to tell the timer not to rearm. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index 40573e4..50e2792 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c @@ -126,7 +126,6 @@ static void handle_catas(struct mthca_dev *dev) static void poll_catas(unsigned long dev_ptr) { struct mthca_dev *dev = (struct mthca_dev *) dev_ptr; - unsigned long flags; int i; for (i = 0; i < dev->catas_err.size; ++i) @@ -135,13 +134,8 @@ static void poll_catas(unsigned long dev_ptr) return; } - spin_lock_irqsave(&catas_lock, flags); - if (!dev->catas_err.stop) - mod_timer(&dev->catas_err.timer, - jiffies + MTHCA_CATAS_POLL_INTERVAL); - spin_unlock_irqrestore(&catas_lock, flags); - - return; + mod_timer(&dev->catas_err.timer, + jiffies + MTHCA_CATAS_POLL_INTERVAL); } void mthca_start_catas_poll(struct mthca_dev *dev) @@ -149,7 +143,6 @@ void mthca_start_catas_poll(struct mthca_dev *dev) unsigned long addr; init_timer(&dev->catas_err.timer); - dev->catas_err.stop = 0; dev->catas_err.map = NULL; addr = pci_resource_start(dev->pdev, 0) + @@ -180,10 +173,6 @@ void mthca_start_catas_poll(struct mthca_dev *dev) void mthca_stop_catas_poll(struct mthca_dev *dev) { - spin_lock_irq(&catas_lock); - dev->catas_err.stop = 1; - spin_unlock_irq(&catas_lock); - del_timer_sync(&dev->catas_err.timer); if (dev->catas_err.map) { diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 2997d8d..ee4d073 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h @@ -277,7 +277,6 @@ struct mthca_mcg_table { struct mthca_catas_err { u64 addr; u32 __iomem *map; - unsigned long stop; u32 size; struct timer_list timer; struct list_head list; -- cgit v0.10.2 From c036925ac0e940a4e8525b08e89d2c64fe282c51 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: IB/mthca: Use round_jiffies() for catastrophic error polling timer Exactly when the catastrophic error polling timer function runs is not important, so use round_jiffies() to save unnecessary wakeups. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index 50e2792..cc440f9 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c @@ -135,7 +135,7 @@ static void poll_catas(unsigned long dev_ptr) } mod_timer(&dev->catas_err.timer, - jiffies + MTHCA_CATAS_POLL_INTERVAL); + round_jiffies(jiffies + MTHCA_CATAS_POLL_INTERVAL)); } void mthca_start_catas_poll(struct mthca_dev *dev) -- cgit v0.10.2 From aed012279d35e88e29fd55737d8821604433f50a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 14 Jul 2008 23:48:52 -0700 Subject: IB/mthca: Fix check of max_send_sge for special QPs The MLX transport requires two extra gather entries for sends (one for the header and one for the checksum at the end, as the comment says). However the code checked that max_recv_sge was not too big, instead of checking max_send_sge as it should have. Fix the code to check the correct condition. Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 77b52b3..f5081bf 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1249,10 +1249,10 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, return -EINVAL; /* - * For MLX transport we need 2 extra S/G entries: + * For MLX transport we need 2 extra send gather entries: * one for the header and one for the checksum at the end */ - if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg) + if (qp->transport == MLX && cap->max_send_sge + 2 > dev->limits.max_sg) return -EINVAL; if (mthca_is_memfree(dev)) { -- cgit v0.10.2 From 96f15c03532282366364ecfd20f04e49b5d96f3a Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: RDMA/core: Add local DMA L_Key support - Change the IB_DEVICE_ZERO_STAG flag to the transport-neutral name IB_DEVICE_LOCAL_DMA_LKEY, which is used by iWARP RNICs to indicate 0 STag support and IB HCAs to indicate reserved L_Key support. - Add a u32 local_dma_lkey member to struct ib_device. Drivers fill this in with the appropriate local DMA L_Key (if they support it). - Fix up the drivers using this flag. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index b1441aeb..dd05c48 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -454,7 +454,7 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) (IB_DEVICE_RESIZE_MAX_WR | IB_DEVICE_CURR_QP_STATE_MOD | IB_DEVICE_SYS_IMAGE_GUID | - IB_DEVICE_ZERO_STAG | + IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW); /* Allocate the qptr_array */ diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index c9a3893..7ecfd4d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1325,8 +1325,10 @@ int iwch_register_device(struct iwch_dev *dev) memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); dev->ibdev.owner = THIS_MODULE; - dev->device_cap_flags = IB_DEVICE_ZERO_STAG | - IB_DEVICE_MEM_WINDOW; + dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW; + + /* cxgb3 supports STag 0. */ + dev->ibdev.local_dma_lkey = 0; if (fw_supports_fastreg(dev)) dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 902b137..85f26d1 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -398,7 +398,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { nesadapter->base_pd = 1; nesadapter->device_cap_flags = - IB_DEVICE_ZERO_STAG | IB_DEVICE_MEM_WINDOW; + IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW; nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter) [(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 07b41e0..90b529f 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -91,7 +91,7 @@ enum ib_device_cap_flags { IB_DEVICE_RC_RNR_NAK_GEN = (1<<12), IB_DEVICE_SRQ_RESIZE = (1<<13), IB_DEVICE_N_NOTIFY_CQ = (1<<14), - IB_DEVICE_ZERO_STAG = (1<<15), + IB_DEVICE_LOCAL_DMA_LKEY = (1<<15), IB_DEVICE_RESERVED = (1<<16), /* old SEND_W_INV */ IB_DEVICE_MEM_WINDOW = (1<<17), /* @@ -1149,6 +1149,7 @@ struct ib_device { char node_desc[64]; __be64 node_guid; + u32 local_dma_lkey; u8 node_type; u8 phys_port_cnt; }; -- cgit v0.10.2 From 4ab928f69208d240d3681336f34589e4b151824f Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: RDMA/cxgb3: Fixes for zero STag Handling the zero STag in receive work request requires some extra logic in the driver: - Only set the QP_PRIV bit for kernel mode QPs. - Add a zero STag build function for recv wrs. The uP needs a PBL allocated and passed down in the recv WR so it can construct a HW PBL for the zero STag S/G entries. Note: we need to place a few restrictions on zero STag usage because of this: 1) all SGEs in a recv WR must either be zero STag or not. No mixing. 2) an individual SGE length cannot exceed 128MB for a zero-stag SGE. This should be OK since it's not really practical to allocate such a large chunk of pinned contiguous DMA mapped memory. - Add an optimized non-zero-STag recv wr format for kernel users. This is needed to optimize both zero and non-zero STag cracking in the recv path for kernel users. - Remove the iwch_ prefix from the static build functions. - Bump required FW version. Signed-off-by: Steve Wise diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 340e418..f6d5747 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -278,7 +278,7 @@ int cxio_create_qp(struct cxio_rdev *rdev_p, u32 kernel_domain, if (!wq->qpid) return -ENOMEM; - wq->rq = kzalloc(depth * sizeof(u64), GFP_KERNEL); + wq->rq = kzalloc(depth * sizeof(struct t3_swrq), GFP_KERNEL); if (!wq->rq) goto err1; @@ -302,6 +302,7 @@ int cxio_create_qp(struct cxio_rdev *rdev_p, u32 kernel_domain, if (!kernel_domain) wq->udb = (u64)rdev_p->rnic_info.udbell_physbase + (wq->qpid << rdev_p->qpshift); + wq->rdev = rdev_p; PDBG("%s qpid 0x%x doorbell 0x%p udb 0x%llx\n", __func__, wq->qpid, wq->doorbell, (unsigned long long) wq->udb); return 0; @@ -1266,13 +1267,16 @@ proc_cqe: wq->sq_rptr = CQE_WRID_SQ_WPTR(*hw_cqe); PDBG("%s completing sq idx %ld\n", __func__, Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2)); - *cookie = (wq->sq + - Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2))->wr_id; + *cookie = wq->sq[Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2)].wr_id; wq->sq_rptr++; } else { PDBG("%s completing rq idx %ld\n", __func__, Q_PTR2IDX(wq->rq_rptr, wq->rq_size_log2)); - *cookie = *(wq->rq + Q_PTR2IDX(wq->rq_rptr, wq->rq_size_log2)); + *cookie = wq->rq[Q_PTR2IDX(wq->rq_rptr, wq->rq_size_log2)].wr_id; + if (wq->rq[Q_PTR2IDX(wq->rq_rptr, wq->rq_size_log2)].pbl_addr) + cxio_hal_pblpool_free(wq->rdev, + wq->rq[Q_PTR2IDX(wq->rq_rptr, + wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE); wq->rq_rptr++; } diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index de760e9..04618f7 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h @@ -39,6 +39,9 @@ #define T3_MAX_SGE 4 #define T3_MAX_INLINE 64 +#define T3_STAG0_PBL_SIZE (2 * T3_MAX_SGE << 3) +#define T3_STAG0_MAX_PBE_LEN (128 * 1024 * 1024) +#define T3_STAG0_PAGE_SHIFT 15 #define Q_EMPTY(rptr,wptr) ((rptr)==(wptr)) #define Q_FULL(rptr,wptr,size_log2) ( (((wptr)-(rptr))>>(size_log2)) && \ @@ -665,6 +668,11 @@ struct t3_swsq { int signaled; }; +struct t3_swrq { + __u64 wr_id; + __u32 pbl_addr; +}; + /* * A T3 WQ implements both the SQ and RQ. */ @@ -681,14 +689,15 @@ struct t3_wq { u32 sq_wptr; /* sq_wptr - sq_rptr == count of */ u32 sq_rptr; /* pending wrs */ u32 sq_size_log2; /* sq size */ - u64 *rq; /* SW RQ (holds consumer wr_ids */ + struct t3_swrq *rq; /* SW RQ (holds consumer wr_ids */ u32 rq_wptr; /* rq_wptr - rq_rptr == count of */ u32 rq_rptr; /* pending wrs */ - u64 *rq_oldest_wr; /* oldest wr on the SW RQ */ + struct t3_swrq *rq_oldest_wr; /* oldest wr on the SW RQ */ u32 rq_size_log2; /* rq size */ u32 rq_addr; /* rq adapter address */ void __iomem *doorbell; /* kernel db */ u64 udb; /* user db if any */ + struct cxio_rdev *rdev; }; struct t3_cq { diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 7ecfd4d..b89640a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1007,10 +1007,10 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd, qhp->ibqp.qp_num = qhp->wq.qpid; init_timer(&(qhp->timer)); PDBG("%s sq_num_entries %d, rq_num_entries %d " - "qpid 0x%0x qhp %p dma_addr 0x%llx size %d\n", + "qpid 0x%0x qhp %p dma_addr 0x%llx size %d rq_addr 0x%x\n", __func__, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, qhp->wq.qpid, qhp, (unsigned long long) qhp->wq.dma_addr, - 1 << qhp->wq.size_log2); + 1 << qhp->wq.size_log2, qhp->wq.rq_addr); return &qhp->ibqp; } diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 3b44300..9a3be3a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c @@ -33,10 +33,11 @@ #include "iwch.h" #include "iwch_cm.h" #include "cxio_hal.h" +#include "cxio_resource.h" #define NO_SUPPORT -1 -static int iwch_build_rdma_send(union t3_wr *wqe, struct ib_send_wr *wr, +static int build_rdma_send(union t3_wr *wqe, struct ib_send_wr *wr, u8 * flit_cnt) { int i; @@ -81,7 +82,7 @@ static int iwch_build_rdma_send(union t3_wr *wqe, struct ib_send_wr *wr, return 0; } -static int iwch_build_rdma_write(union t3_wr *wqe, struct ib_send_wr *wr, +static int build_rdma_write(union t3_wr *wqe, struct ib_send_wr *wr, u8 *flit_cnt) { int i; @@ -122,7 +123,7 @@ static int iwch_build_rdma_write(union t3_wr *wqe, struct ib_send_wr *wr, return 0; } -static int iwch_build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr, +static int build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr, u8 *flit_cnt) { if (wr->num_sge > 1) @@ -143,7 +144,7 @@ static int iwch_build_rdma_read(union t3_wr *wqe, struct ib_send_wr *wr, return 0; } -static int iwch_build_fastreg(union t3_wr *wqe, struct ib_send_wr *wr, +static int build_fastreg(union t3_wr *wqe, struct ib_send_wr *wr, u8 *flit_cnt, int *wr_cnt, struct t3_wq *wq) { int i; @@ -185,7 +186,7 @@ static int iwch_build_fastreg(union t3_wr *wqe, struct ib_send_wr *wr, return 0; } -static int iwch_build_inv_stag(union t3_wr *wqe, struct ib_send_wr *wr, +static int build_inv_stag(union t3_wr *wqe, struct ib_send_wr *wr, u8 *flit_cnt) { wqe->local_inv.stag = cpu_to_be32(wr->ex.invalidate_rkey); @@ -244,23 +245,106 @@ static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list, return 0; } -static int iwch_build_rdma_recv(struct iwch_dev *rhp, union t3_wr *wqe, +static int build_rdma_recv(struct iwch_qp *qhp, union t3_wr *wqe, struct ib_recv_wr *wr) { - int i; - if (wr->num_sge > T3_MAX_SGE) - return -EINVAL; + int i, err = 0; + u32 pbl_addr[T3_MAX_SGE]; + u8 page_size[T3_MAX_SGE]; + + err = iwch_sgl2pbl_map(qhp->rhp, wr->sg_list, wr->num_sge, pbl_addr, + page_size); + if (err) + return err; + wqe->recv.pagesz[0] = page_size[0]; + wqe->recv.pagesz[1] = page_size[1]; + wqe->recv.pagesz[2] = page_size[2]; + wqe->recv.pagesz[3] = page_size[3]; wqe->recv.num_sgle = cpu_to_be32(wr->num_sge); for (i = 0; i < wr->num_sge; i++) { wqe->recv.sgl[i].stag = cpu_to_be32(wr->sg_list[i].lkey); wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length); + + /* to in the WQE == the offset into the page */ + wqe->recv.sgl[i].to = cpu_to_be64(((u32) wr->sg_list[i].addr) % + (1UL << (12 + page_size[i]))); + + /* pbl_addr is the adapters address in the PBL */ + wqe->recv.pbl_addr[i] = cpu_to_be32(pbl_addr[i]); + } + for (; i < T3_MAX_SGE; i++) { + wqe->recv.sgl[i].stag = 0; + wqe->recv.sgl[i].len = 0; + wqe->recv.sgl[i].to = 0; + wqe->recv.pbl_addr[i] = 0; + } + qhp->wq.rq[Q_PTR2IDX(qhp->wq.rq_wptr, + qhp->wq.rq_size_log2)].wr_id = wr->wr_id; + qhp->wq.rq[Q_PTR2IDX(qhp->wq.rq_wptr, + qhp->wq.rq_size_log2)].pbl_addr = 0; + return 0; +} + +static int build_zero_stag_recv(struct iwch_qp *qhp, union t3_wr *wqe, + struct ib_recv_wr *wr) +{ + int i; + u32 pbl_addr; + u32 pbl_offset; + + + /* + * The T3 HW requires the PBL in the HW recv descriptor to reference + * a PBL entry. So we allocate the max needed PBL memory here and pass + * it to the uP in the recv WR. The uP will build the PBL and setup + * the HW recv descriptor. + */ + pbl_addr = cxio_hal_pblpool_alloc(&qhp->rhp->rdev, T3_STAG0_PBL_SIZE); + if (!pbl_addr) + return -ENOMEM; + + /* + * Compute the 8B aligned offset. + */ + pbl_offset = (pbl_addr - qhp->rhp->rdev.rnic_info.pbl_base) >> 3; + + wqe->recv.num_sgle = cpu_to_be32(wr->num_sge); + + for (i = 0; i < wr->num_sge; i++) { + + /* + * Use a 128MB page size. This and an imposed 128MB + * sge length limit allows us to require only a 2-entry HW + * PBL for each SGE. This restriction is acceptable since + * since it is not possible to allocate 128MB of contiguous + * DMA coherent memory! + */ + if (wr->sg_list[i].length > T3_STAG0_MAX_PBE_LEN) + return -EINVAL; + wqe->recv.pagesz[i] = T3_STAG0_PAGE_SHIFT; + + /* + * T3 restricts a recv to all zero-stag or all non-zero-stag. + */ + if (wr->sg_list[i].lkey != 0) + return -EINVAL; + wqe->recv.sgl[i].stag = 0; + wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length); wqe->recv.sgl[i].to = cpu_to_be64(wr->sg_list[i].addr); + wqe->recv.pbl_addr[i] = cpu_to_be32(pbl_offset); + pbl_offset += 2; } for (; i < T3_MAX_SGE; i++) { + wqe->recv.pagesz[i] = 0; wqe->recv.sgl[i].stag = 0; wqe->recv.sgl[i].len = 0; wqe->recv.sgl[i].to = 0; + wqe->recv.pbl_addr[i] = 0; } + qhp->wq.rq[Q_PTR2IDX(qhp->wq.rq_wptr, + qhp->wq.rq_size_log2)].wr_id = wr->wr_id; + qhp->wq.rq[Q_PTR2IDX(qhp->wq.rq_wptr, + qhp->wq.rq_size_log2)].pbl_addr = pbl_addr; return 0; } @@ -312,18 +396,18 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, if (wr->send_flags & IB_SEND_FENCE) t3_wr_flags |= T3_READ_FENCE_FLAG; t3_wr_opcode = T3_WR_SEND; - err = iwch_build_rdma_send(wqe, wr, &t3_wr_flit_cnt); + err = build_rdma_send(wqe, wr, &t3_wr_flit_cnt); break; case IB_WR_RDMA_WRITE: case IB_WR_RDMA_WRITE_WITH_IMM: t3_wr_opcode = T3_WR_WRITE; - err = iwch_build_rdma_write(wqe, wr, &t3_wr_flit_cnt); + err = build_rdma_write(wqe, wr, &t3_wr_flit_cnt); break; case IB_WR_RDMA_READ: case IB_WR_RDMA_READ_WITH_INV: t3_wr_opcode = T3_WR_READ; t3_wr_flags = 0; /* T3 reads are always signaled */ - err = iwch_build_rdma_read(wqe, wr, &t3_wr_flit_cnt); + err = build_rdma_read(wqe, wr, &t3_wr_flit_cnt); if (err) break; sqp->read_len = wqe->read.local_len; @@ -332,14 +416,14 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, break; case IB_WR_FAST_REG_MR: t3_wr_opcode = T3_WR_FASTREG; - err = iwch_build_fastreg(wqe, wr, &t3_wr_flit_cnt, + err = build_fastreg(wqe, wr, &t3_wr_flit_cnt, &wr_cnt, &qhp->wq); break; case IB_WR_LOCAL_INV: if (wr->send_flags & IB_SEND_FENCE) t3_wr_flags |= T3_LOCAL_FENCE_FLAG; t3_wr_opcode = T3_WR_INV_STAG; - err = iwch_build_inv_stag(wqe, wr, &t3_wr_flit_cnt); + err = build_inv_stag(wqe, wr, &t3_wr_flit_cnt); break; default: PDBG("%s post of type=%d TBD!\n", __func__, @@ -398,18 +482,24 @@ int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, return -EINVAL; } while (wr) { + if (wr->num_sge > T3_MAX_SGE) { + err = -EINVAL; + *bad_wr = wr; + break; + } idx = Q_PTR2IDX(qhp->wq.wptr, qhp->wq.size_log2); wqe = (union t3_wr *) (qhp->wq.queue + idx); if (num_wrs) - err = iwch_build_rdma_recv(qhp->rhp, wqe, wr); + if (wr->sg_list[0].lkey) + err = build_rdma_recv(qhp, wqe, wr); + else + err = build_zero_stag_recv(qhp, wqe, wr); else err = -ENOMEM; if (err) { *bad_wr = wr; break; } - qhp->wq.rq[Q_PTR2IDX(qhp->wq.rq_wptr, qhp->wq.rq_size_log2)] = - wr->wr_id; build_fw_riwrh((void *) wqe, T3_WR_RCV, T3_COMPLETION_FLAG, Q_GENBIT(qhp->wq.wptr, qhp->wq.size_log2), 0, sizeof(struct t3_receive_wr) >> 3, T3_SOPEOP); @@ -810,7 +900,8 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); init_attr.rqe_count = iwch_rqes_posted(qhp); init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0; - init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; + if (!qhp->ibqp.uobject) + init_attr.flags |= PRIV_QP; if (peer2peer) { init_attr.rtr_type = RTR_READ; if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator) diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h index a0177fc..29db711 100644 --- a/drivers/net/cxgb3/version.h +++ b/drivers/net/cxgb3/version.h @@ -38,7 +38,7 @@ #define DRV_VERSION "1.0-ko" /* Firmware version */ -#define FW_VERSION_MAJOR 6 +#define FW_VERSION_MAJOR 7 #define FW_VERSION_MINOR 0 #define FW_VERSION_MICRO 0 #endif /* __CHELSIO_VERSION_H */ -- cgit v0.10.2 From 64c5e613b9dd34ef1281ed6d22478609667ae36a Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: RDMA/addr: Keep pointer to netdevice in struct rdma_dev_addr Keep a pointer to the local (src) netdevice in struct rdma_dev_addr, and copy it in as part of rdma_copy_addr(). Use rdma_translate_ip() in cma_new_conn_id() to reduce some code duplication and also make sure the src_dev member gets set. In a high-availability configuration the netdevice pointer can be used by the RDMA CM to align RDMA sessions to use the same links as the IP stack does under fail-over and route change cases. Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index e4eb8be..09a2bec 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -105,6 +105,7 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN); if (dst_dev_addr) memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN); + dev_addr->src_dev = dev; return 0; } EXPORT_SYMBOL(rdma_copy_addr); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 44d190f..5fb506a 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1002,6 +1002,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, union cma_ip_addr *src, *dst; __be16 port; u8 ip_ver; + int ret; if (cma_get_net_info(ib_event->private_data, listen_id->ps, &ip_ver, &port, &src, &dst)) @@ -1026,10 +1027,11 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, if (rt->num_paths == 2) rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; - ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); - ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); - rt->addr.dev_addr.dev_type = RDMA_NODE_IB_CA; + ret = rdma_translate_ip(&id->route.addr.src_addr, + &id->route.addr.dev_addr); + if (ret) + goto destroy_id; id_priv = container_of(id, struct rdma_id_private, id); id_priv->state = CMA_CONNECT; diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index b42bdd00..483057b 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -61,6 +61,7 @@ struct rdma_dev_addr { unsigned char dst_dev_addr[MAX_ADDR_LEN]; unsigned char broadcast[MAX_ADDR_LEN]; enum rdma_node_type dev_type; + struct net_device *src_dev; }; /** -- cgit v0.10.2 From de910bd92137005b5e1ecaf2ce68053d7d7d5350 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: RDMA/cma: Simplify locking needed for serialization of callbacks The RDMA CM has some logic in place to make sure that callbacks on a given CM ID are delivered to the consumer in a serialized manner. Specifically it has code to protect against a device removal racing with a running callback function. This patch simplifies this logic by using a mutex per ID instead of a wait queue and atomic variable. This means that cma_disable_remove() now is more properly named to cma_disable_callback(), and cma_enable_remove() can now be removed because it just would become a trivial wrapper around mutex_unlock(). Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 5fb506a..ae11d5c 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -130,8 +130,7 @@ struct rdma_id_private { struct completion comp; atomic_t refcount; - wait_queue_head_t wait_remove; - atomic_t dev_remove; + struct mutex handler_mutex; int backlog; int timeout_ms; @@ -355,26 +354,15 @@ static void cma_deref_id(struct rdma_id_private *id_priv) complete(&id_priv->comp); } -static int cma_disable_remove(struct rdma_id_private *id_priv, +static int cma_disable_callback(struct rdma_id_private *id_priv, enum cma_state state) { - unsigned long flags; - int ret; - - spin_lock_irqsave(&id_priv->lock, flags); - if (id_priv->state == state) { - atomic_inc(&id_priv->dev_remove); - ret = 0; - } else - ret = -EINVAL; - spin_unlock_irqrestore(&id_priv->lock, flags); - return ret; -} - -static void cma_enable_remove(struct rdma_id_private *id_priv) -{ - if (atomic_dec_and_test(&id_priv->dev_remove)) - wake_up(&id_priv->wait_remove); + mutex_lock(&id_priv->handler_mutex); + if (id_priv->state != state) { + mutex_unlock(&id_priv->handler_mutex); + return -EINVAL; + } + return 0; } static int cma_has_cm_dev(struct rdma_id_private *id_priv) @@ -399,8 +387,7 @@ struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler, mutex_init(&id_priv->qp_mutex); init_completion(&id_priv->comp); atomic_set(&id_priv->refcount, 1); - init_waitqueue_head(&id_priv->wait_remove); - atomic_set(&id_priv->dev_remove, 0); + mutex_init(&id_priv->handler_mutex); INIT_LIST_HEAD(&id_priv->listen_list); INIT_LIST_HEAD(&id_priv->mc_list); get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num); @@ -927,7 +914,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) struct rdma_cm_event event; int ret = 0; - if (cma_disable_remove(id_priv, CMA_CONNECT)) + if (cma_disable_callback(id_priv, CMA_CONNECT)) return 0; memset(&event, 0, sizeof event); @@ -984,12 +971,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) /* Destroy the CM ID by returning a non-zero value. */ id_priv->cm_id.ib = NULL; cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); rdma_destroy_id(&id_priv->id); return ret; } out: - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); return ret; } @@ -1101,7 +1088,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) int offset, ret; listen_id = cm_id->context; - if (cma_disable_remove(listen_id, CMA_LISTEN)) + if (cma_disable_callback(listen_id, CMA_LISTEN)) return -ECONNABORTED; memset(&event, 0, sizeof event); @@ -1122,7 +1109,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) goto out; } - atomic_inc(&conn_id->dev_remove); + mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); mutex_lock(&lock); ret = cma_acquire_dev(conn_id); mutex_unlock(&lock); @@ -1144,7 +1131,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) !cma_is_ud_ps(conn_id->id.ps)) ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); mutex_unlock(&lock); - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); goto out; } @@ -1153,11 +1140,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) release_conn_id: cma_exch(conn_id, CMA_DESTROYING); - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(&conn_id->id); out: - cma_enable_remove(listen_id); + mutex_unlock(&listen_id->handler_mutex); return ret; } @@ -1223,7 +1210,7 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) struct sockaddr_in *sin; int ret = 0; - if (cma_disable_remove(id_priv, CMA_CONNECT)) + if (cma_disable_callback(id_priv, CMA_CONNECT)) return 0; memset(&event, 0, sizeof event); @@ -1267,12 +1254,12 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) /* Destroy the CM ID by returning a non-zero value. */ id_priv->cm_id.iw = NULL; cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); rdma_destroy_id(&id_priv->id); return ret; } - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); return ret; } @@ -1288,7 +1275,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, struct ib_device_attr attr; listen_id = cm_id->context; - if (cma_disable_remove(listen_id, CMA_LISTEN)) + if (cma_disable_callback(listen_id, CMA_LISTEN)) return -ECONNABORTED; /* Create a new RDMA id for the new IW CM ID */ @@ -1300,19 +1287,19 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, goto out; } conn_id = container_of(new_cm_id, struct rdma_id_private, id); - atomic_inc(&conn_id->dev_remove); + mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); conn_id->state = CMA_CONNECT; dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr); if (!dev) { ret = -EADDRNOTAVAIL; - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(new_cm_id); goto out; } ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL); if (ret) { - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(new_cm_id); goto out; } @@ -1321,7 +1308,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, ret = cma_acquire_dev(conn_id); mutex_unlock(&lock); if (ret) { - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(new_cm_id); goto out; } @@ -1337,7 +1324,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, ret = ib_query_device(conn_id->id.device, &attr); if (ret) { - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(new_cm_id); goto out; } @@ -1353,14 +1340,17 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, /* User wants to destroy the CM ID */ conn_id->cm_id.iw = NULL; cma_exch(conn_id, CMA_DESTROYING); - cma_enable_remove(conn_id); + mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(&conn_id->id); + goto out; } + mutex_unlock(&conn_id->handler_mutex); + out: if (dev) dev_put(dev); - cma_enable_remove(listen_id); + mutex_unlock(&listen_id->handler_mutex); return ret; } @@ -1592,7 +1582,7 @@ static void cma_work_handler(struct work_struct *_work) struct rdma_id_private *id_priv = work->id; int destroy = 0; - atomic_inc(&id_priv->dev_remove); + mutex_lock(&id_priv->handler_mutex); if (!cma_comp_exch(id_priv, work->old_state, work->new_state)) goto out; @@ -1601,7 +1591,7 @@ static void cma_work_handler(struct work_struct *_work) destroy = 1; } out: - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); cma_deref_id(id_priv); if (destroy) rdma_destroy_id(&id_priv->id); @@ -1764,7 +1754,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, struct rdma_cm_event event; memset(&event, 0, sizeof event); - atomic_inc(&id_priv->dev_remove); + mutex_lock(&id_priv->handler_mutex); /* * Grab mutex to block rdma_destroy_id() from removing the device while @@ -1793,13 +1783,13 @@ static void addr_handler(int status, struct sockaddr *src_addr, if (id_priv->id.event_handler(&id_priv->id, &event)) { cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); cma_deref_id(id_priv); rdma_destroy_id(&id_priv->id); return; } out: - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); cma_deref_id(id_priv); } @@ -2126,7 +2116,7 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; int ret = 0; - if (cma_disable_remove(id_priv, CMA_CONNECT)) + if (cma_disable_callback(id_priv, CMA_CONNECT)) return 0; memset(&event, 0, sizeof event); @@ -2167,12 +2157,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, /* Destroy the CM ID by returning a non-zero value. */ id_priv->cm_id.ib = NULL; cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); rdma_destroy_id(&id_priv->id); return ret; } out: - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); return ret; } @@ -2570,8 +2560,8 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) int ret; id_priv = mc->id_priv; - if (cma_disable_remove(id_priv, CMA_ADDR_BOUND) && - cma_disable_remove(id_priv, CMA_ADDR_RESOLVED)) + if (cma_disable_callback(id_priv, CMA_ADDR_BOUND) && + cma_disable_callback(id_priv, CMA_ADDR_RESOLVED)) return 0; mutex_lock(&id_priv->qp_mutex); @@ -2596,12 +2586,12 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) ret = id_priv->id.event_handler(&id_priv->id, &event); if (ret) { cma_exch(id_priv, CMA_DESTROYING); - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); rdma_destroy_id(&id_priv->id); return 0; } - cma_enable_remove(id_priv); + mutex_unlock(&id_priv->handler_mutex); return 0; } @@ -2760,6 +2750,7 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv) { struct rdma_cm_event event; enum cma_state state; + int ret = 0; /* Record that we want to remove the device */ state = cma_exch(id_priv, CMA_DEVICE_REMOVAL); @@ -2767,15 +2758,18 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv) return 0; cma_cancel_operation(id_priv, state); - wait_event(id_priv->wait_remove, !atomic_read(&id_priv->dev_remove)); + mutex_lock(&id_priv->handler_mutex); /* Check for destruction from another callback. */ if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL)) - return 0; + goto out; memset(&event, 0, sizeof event); event.event = RDMA_CM_EVENT_DEVICE_REMOVAL; - return id_priv->id.event_handler(&id_priv->id, &event); + ret = id_priv->id.event_handler(&id_priv->id, &event); +out: + mutex_unlock(&id_priv->handler_mutex); + return ret; } static void cma_process_remove(struct cma_device *cma_dev) -- cgit v0.10.2 From 2d92865158d0e21ef4350703af64bc2a610d81d3 Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: mlx4_core: Use MOD_STAT_CFG command to get minimal page size There was a bug in some versions of the mlx4 driver in mlx4_alloc_fmr(), which hardcoded the minimum acceptable page_shift to be 12. However, new ConnectX firmware can support a minimum page_shift of 9 (log_pg_sz of 9 returned by QUERY_DEV_LIM) -- so with old drivers, ib_fmr_alloc() would fail for ULPs using the device minimum when creating FMRs. To preserve firmware compatibility with released mlx4 drivers, the firmware will continue to return 12 as before for log_page_sz in QUERY_DEV_CAP for these drivers. However, to enable new drivers to take advantage of the available smaller page size, the mlx4 driver now first sets the log_pg_sz to the device minimum by setting a log_page_sz value to 0 via the MOD_STAT_CFG command and then reading the real minimum via QUERY_DEV_CAP. Signed-off-by: Jack Morgenstein Signed-off-by: Vladimir Sokolovsky Signed-off-by: Roland Dreier diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index d82f275..2b5006b 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -101,6 +101,34 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags) mlx4_dbg(dev, " %s\n", fname[i]); } +int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg) +{ + struct mlx4_cmd_mailbox *mailbox; + u32 *inbox; + int err = 0; + +#define MOD_STAT_CFG_IN_SIZE 0x100 + +#define MOD_STAT_CFG_PG_SZ_M_OFFSET 0x002 +#define MOD_STAT_CFG_PG_SZ_OFFSET 0x003 + + mailbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + inbox = mailbox->buf; + + memset(inbox, 0, MOD_STAT_CFG_IN_SIZE); + + MLX4_PUT(inbox, cfg->log_pg_sz, MOD_STAT_CFG_PG_SZ_OFFSET); + MLX4_PUT(inbox, cfg->log_pg_sz_m, MOD_STAT_CFG_PG_SZ_M_OFFSET); + + err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_MOD_STAT_CFG, + MLX4_CMD_TIME_CLASS_A); + + mlx4_free_cmd_mailbox(dev, mailbox); + return err; +} + int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) { struct mlx4_cmd_mailbox *mailbox; diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h index 306cb9b..a0e046c 100644 --- a/drivers/net/mlx4/fw.h +++ b/drivers/net/mlx4/fw.h @@ -38,6 +38,11 @@ #include "mlx4.h" #include "icm.h" +struct mlx4_mod_stat_cfg { + u8 log_pg_sz; + u8 log_pg_sz_m; +}; + struct mlx4_dev_cap { int max_srq_sz; int max_qp_sz; @@ -162,5 +167,6 @@ int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, u64 *aux_pages); int mlx4_MAP_ICM_AUX(struct mlx4_dev *dev, struct mlx4_icm *icm); int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev); int mlx4_NOP(struct mlx4_dev *dev); +int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg); #endif /* MLX4_FW_H */ diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index a6aa49f..d373601 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -485,6 +485,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_adapter adapter; struct mlx4_dev_cap dev_cap; + struct mlx4_mod_stat_cfg mlx4_cfg; struct mlx4_profile profile; struct mlx4_init_hca_param init_hca; u64 icm_size; @@ -502,6 +503,12 @@ static int mlx4_init_hca(struct mlx4_dev *dev) return err; } + mlx4_cfg.log_pg_sz_m = 1; + mlx4_cfg.log_pg_sz = 0; + err = mlx4_MOD_STAT_CFG(dev, &mlx4_cfg); + if (err) + mlx4_warn(dev, "Failed to override log_pg_sz parameter\n"); + err = mlx4_dev_cap(dev, &dev_cap); if (err) { mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n"); -- cgit v0.10.2 From f507d28bff0601f1a8a96b7939fa3855c50d25b6 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 14 Jul 2008 23:48:53 -0700 Subject: IB/mlx4: Use kzalloc() for new QPs so flags are initialized to 0 Current code uses kmalloc() and then just does a bitwise OR operation on qp->flags in create_qp_common(), which means that qp->flags may potentially have some unintended bits set. This patch uses kzalloc() and avoids further explicit clearing of structure members, which also shrinks the code: add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-65 (-65) function old new delta create_qp_common 2024 1959 -65 Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 91590e7..89eb6cb 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -454,19 +454,8 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, spin_lock_init(&qp->rq.lock); qp->state = IB_QPS_RESET; - qp->atomic_rd_en = 0; - qp->resp_depth = 0; - - qp->rq.head = 0; - qp->rq.tail = 0; - qp->sq.head = 0; - qp->sq.tail = 0; - qp->sq_next_wqe = 0; - if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE); - else - qp->sq_signal_bits = 0; err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp); if (err) @@ -704,7 +693,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, case IB_QPT_UC: case IB_QPT_UD: { - qp = kmalloc(sizeof *qp, GFP_KERNEL); + qp = kzalloc(sizeof *qp, GFP_KERNEL); if (!qp) return ERR_PTR(-ENOMEM); @@ -725,7 +714,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, if (pd->uobject) return ERR_PTR(-EINVAL); - sqp = kmalloc(sizeof *sqp, GFP_KERNEL); + sqp = kzalloc(sizeof *sqp, GFP_KERNEL); if (!sqp) return ERR_PTR(-ENOMEM); -- cgit v0.10.2 From 089be43e403a78cd6889cde2fba164fefe9dfd89 Mon Sep 17 00:00:00 2001 From: James Morris Date: Tue, 15 Jul 2008 18:32:49 +1000 Subject: Revert "SELinux: allow fstype unknown to policy to use xattrs if present" This reverts commit 811f3799279e567aa354c649ce22688d949ac7a9. From Eric Paris: "Please drop this patch for now. It deadlocks on ntfs-3g. I need to rework it to handle fuse filesystems better. (casey was right)" diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 91200fe..63f131f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -555,15 +555,13 @@ static int selinux_set_mnt_opts(struct super_block *sb, struct task_security_struct *tsec = current->security; struct superblock_security_struct *sbsec = sb->s_security; const char *name = sb->s_type->name; - struct dentry *root = sb->s_root; - struct inode *root_inode = root->d_inode; - struct inode_security_struct *root_isec = root_inode->i_security; + struct inode *inode = sbsec->sb->s_root->d_inode; + struct inode_security_struct *root_isec = inode->i_security; u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; u32 defcontext_sid = 0; char **mount_options = opts->mnt_opts; int *flags = opts->mnt_opts_flags; int num_opts = opts->num_mnt_opts; - bool can_xattr = false; mutex_lock(&sbsec->lock); @@ -667,24 +665,14 @@ static int selinux_set_mnt_opts(struct super_block *sb, goto out; } - if (strcmp(name, "proc") == 0) + if (strcmp(sb->s_type->name, "proc") == 0) sbsec->proc = 1; - /* - * test if the fs supports xattrs, fs_use might make use of this if the - * fs has no definition in policy. - */ - if (root_inode->i_op->getxattr) { - rc = root_inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0); - if (rc >= 0 || rc == -ENODATA) - can_xattr = true; - } - /* Determine the labeling behavior to use for this filesystem type. */ - rc = security_fs_use(name, &sbsec->behavior, &sbsec->sid, can_xattr); + rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); if (rc) { printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", - __func__, name, rc); + __func__, sb->s_type->name, rc); goto out; } diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 44cba2e..7c54300 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -136,7 +136,7 @@ int security_get_allow_unknown(void); #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ int security_fs_use(const char *fstype, unsigned int *behavior, - u32 *sid, bool can_xattr); + u32 *sid); int security_genfs_sid(const char *fstype, char *name, u16 sclass, u32 *sid); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8e42da1..b52f923 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1934,8 +1934,7 @@ out: int security_fs_use( const char *fstype, unsigned int *behavior, - u32 *sid, - bool can_xattr) + u32 *sid) { int rc = 0; struct ocontext *c; @@ -1949,7 +1948,6 @@ int security_fs_use( c = c->next; } - /* look for labeling behavior defined in policy */ if (c) { *behavior = c->v.behavior; if (!c->sid[0]) { @@ -1960,23 +1958,14 @@ int security_fs_use( goto out; } *sid = c->sid[0]; - goto out; - } - - /* labeling behavior not in policy, use xattrs if possible */ - if (can_xattr) { - *behavior = SECURITY_FS_USE_XATTR; - *sid = SECINITSID_FS; - goto out; - } - - /* no behavior in policy and can't use xattrs, try GENFS */ - rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); - if (rc) { - *behavior = SECURITY_FS_USE_NONE; - rc = 0; } else { - *behavior = SECURITY_FS_USE_GENFS; + rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); + if (rc) { + *behavior = SECURITY_FS_USE_NONE; + rc = 0; + } else { + *behavior = SECURITY_FS_USE_GENFS; + } } out: -- cgit v0.10.2 From c9b74c5b8fb807187f6b1db09012828fcd2d7e73 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 18 Apr 2008 20:41:49 +0200 Subject: sdhci: don't check block count for progress The specification is insufficiently strict when it comes to how the hardware should update the block count register, making it useless for checking transfer progress. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b413aa6..9b06c60 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -567,7 +567,6 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, static void sdhci_finish_data(struct sdhci_host *host) { struct mmc_data *data; - u16 blocks; BUG_ON(!host->data); @@ -580,20 +579,16 @@ static void sdhci_finish_data(struct sdhci_host *host) } /* - * Controller doesn't count down when in single block mode. + * The specification states that the block count register must + * be updated, but it does not specify at what point in the + * data flow. That makes the register entirely useless to read + * back so we have to assume that nothing made it to the card + * in the event of an error. */ - if (data->blocks == 1) - blocks = (data->error == 0) ? 0 : 1; + if (data->error) + data->bytes_xfered = 0; else - blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); - data->bytes_xfered = data->blksz * (data->blocks - blocks); - - if (!data->error && blocks) { - printk(KERN_ERR "%s: Controller signalled completion even " - "though there were blocks left.\n", - mmc_hostname(host->mmc)); - data->error = -EIO; - } + data->bytes_xfered = data->blksz * data->blocks; if (data->stop) { /* @@ -1466,7 +1461,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) mmc->ops = &sdhci_ops; mmc->f_min = host->max_clk / 256; mmc->f_max = host->max_clk; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; if (caps & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED; -- cgit v0.10.2 From b8c86fc5d8deaa5a6dc49c2c1ed144e6838bf0f3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Mar 2008 17:35:49 +0100 Subject: sdhci: move pci stuff to separate module The SDHCI interface is not PCI specific, yet the Linux driver was intimitely connected to the PCI bus. This patch properly separates the PCI specific portion from the bus independent code. This patch is based on work by Ben Dooks but he did not have time to complete it. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index dead617..f9cbcb8 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -26,18 +26,31 @@ config MMC_PXA config MMC_SDHCI tristate "Secure Digital Host Controller Interface support" - depends on PCI + depends on HAS_DMA help - This select the generic Secure Digital Host Controller Interface. + This selects the generic Secure Digital Host Controller Interface. It is used by manufacturers such as Texas Instruments(R), Ricoh(R) and Toshiba(R). Most controllers found in laptops are of this type. + + If you have a controller with this interface, say Y or M here. You + also need to enable an appropriate bus interface. + + If unsure, say N. + +config MMC_SDHCI_PCI + tristate "SDHCI support on PCI bus" + depends on MMC_SDHCI && PCI + help + This selects the PCI Secure Digital Host Controller Interface. + Most controllers found today are PCI devices. + 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 PCI && EXPERIMENTAL && MMC_SDHCI + depends on MMC_SDHCI_PCI help This selects the disabler for the Ricoh MMC Controller. This proprietary controller is unnecessary because the SDHCI driver diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 3877c87..3027250 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_MMC_ARMMMCI) += mmci.o obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_IMX) += imxmmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o +obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c new file mode 100644 index 0000000..2a3dd6c --- /dev/null +++ b/drivers/mmc/host/sdhci-pci.c @@ -0,0 +1,486 @@ +/* linux/drivers/mmc/host/sdhci-pci.c - SDHCI on PCI bus interface + * + * Copyright (C) 2005-2008 Pierre Ossman, 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. + * + * Thanks to the following companies for their support: + * + * - JMicron (hardware and technical support) + */ + +#include +#include +#include +#include + +#include + +#include +#include + +#include "sdhci.h" + +/* + * PCI registers + */ + +#define PCI_SDHCI_IFPIO 0x00 +#define PCI_SDHCI_IFDMA 0x01 +#define PCI_SDHCI_IFVENDOR 0x02 + +#define PCI_SLOT_INFO 0x40 /* 8 bits */ +#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) +#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 + +#define MAX_SLOTS 8 + +static const struct pci_device_id pci_ids[] __devinitdata = { + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_VENDOR_ID_IBM, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET | + SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_VENDOR_ID_SAMSUNG, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA | + SDHCI_QUIRK_NO_CARD_NO_RESET, + }, + + { + .vendor = PCI_VENDOR_ID_RICOH, + .device = PCI_DEVICE_ID_RICOH_R5C822, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_FORCE_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_BROKEN_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_BROKEN_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB714_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | + SDHCI_QUIRK_BROKEN_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB714_SD_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | + SDHCI_QUIRK_BROKEN_DMA, + }, + + { + .vendor = PCI_VENDOR_ID_MARVELL, + .device = PCI_DEVICE_ID_MARVELL_CAFE_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | + SDHCI_QUIRK_INCR_TIMEOUT_CONTROL, + }, + + { + .vendor = PCI_VENDOR_ID_JMICRON, + .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_RESET_AFTER_REQUEST, + }, + + { /* Generic SD host controller */ + PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) + }, + + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(pci, pci_ids); + +struct sdhci_pci_chip; + +struct sdhci_pci_slot { + struct sdhci_pci_chip *chip; + struct sdhci_host *host; + + int pci_bar; +}; + +struct sdhci_pci_chip { + struct pci_dev *pdev; + unsigned int quirks; + + int num_slots; /* Slots on controller */ + struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */ +}; + +/*****************************************************************************\ + * * + * SDHCI core callbacks * + * * +\*****************************************************************************/ + +static int sdhci_pci_enable_dma(struct sdhci_host *host) +{ + struct sdhci_pci_slot *slot; + struct pci_dev *pdev; + int ret; + + slot = sdhci_priv(host); + pdev = slot->chip->pdev; + + if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) && + ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && + (host->flags & SDHCI_USE_DMA)) { + dev_warn(&pdev->dev, "Will use DMA mode even though HW " + "doesn't fully claim to support it.\n"); + } + + ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (ret) + return ret; + + pci_set_master(pdev); + + return 0; +} + +static struct sdhci_ops sdhci_pci_ops = { + .enable_dma = sdhci_pci_enable_dma, +}; + +/*****************************************************************************\ + * * + * Suspend/resume * + * * +\*****************************************************************************/ + +#ifdef CONFIG_PM + +static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) +{ + struct sdhci_pci_chip *chip; + struct sdhci_pci_slot *slot; + int i, ret; + + chip = pci_get_drvdata(pdev); + if (!chip) + return 0; + + for (i = 0;i < chip->num_slots;i++) { + slot = chip->slots[i]; + if (!slot) + continue; + + ret = sdhci_suspend_host(slot->host, state); + + if (ret) { + for (i--;i >= 0;i--) + sdhci_resume_host(chip->slots[i]->host); + return ret; + } + } + + pci_save_state(pdev); + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int sdhci_pci_resume (struct pci_dev *pdev) +{ + struct sdhci_pci_chip *chip; + struct sdhci_pci_slot *slot; + int i, ret; + + chip = pci_get_drvdata(pdev); + if (!chip) + return 0; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + + for (i = 0;i < chip->num_slots;i++) { + slot = chip->slots[i]; + if (!slot) + continue; + + ret = sdhci_resume_host(slot->host); + if (ret) + return ret; + } + + return 0; +} + +#else /* CONFIG_PM */ + +#define sdhci_pci_suspend NULL +#define sdhci_pci_resume NULL + +#endif /* CONFIG_PM */ + +/*****************************************************************************\ + * * + * Device probing/removal * + * * +\*****************************************************************************/ + +static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( + struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar) +{ + struct sdhci_pci_slot *slot; + struct sdhci_host *host; + + resource_size_t addr; + + int ret; + + if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { + dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); + return ERR_PTR(-ENODEV); + } + + if (pci_resource_len(pdev, bar) != 0x100) { + dev_err(&pdev->dev, "Invalid iomem size. You may " + "experience problems.\n"); + } + + if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { + dev_err(&pdev->dev, "Vendor specific interface. Aborting.\n"); + return ERR_PTR(-ENODEV); + } + + if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) { + dev_err(&pdev->dev, "Unknown interface. Aborting.\n"); + return ERR_PTR(-ENODEV); + } + + host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot)); + if (IS_ERR(host)) { + ret = PTR_ERR(host); + goto unmap; + } + + slot = sdhci_priv(host); + + slot->chip = chip; + slot->host = host; + slot->pci_bar = bar; + + host->hw_name = "PCI"; + host->ops = &sdhci_pci_ops; + host->quirks = chip->quirks; + + host->irq = pdev->irq; + + ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); + if (ret) { + dev_err(&pdev->dev, "cannot request region\n"); + return ERR_PTR(ret); + } + + addr = pci_resource_start(pdev, bar); + host->ioaddr = ioremap_nocache(addr, pci_resource_len(pdev, bar)); + if (!host->ioaddr) { + dev_err(&pdev->dev, "failed to remap registers\n"); + goto release; + } + + ret = sdhci_add_host(host); + if (ret) + goto unmap; + + return slot; + +unmap: + iounmap(host->ioaddr); + +release: + pci_release_region(pdev, bar); + sdhci_free_host(host); + + return ERR_PTR(ret); +} + +static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) +{ + sdhci_remove_host(slot->host); + pci_release_region(slot->chip->pdev, slot->pci_bar); + sdhci_free_host(slot->host); +} + +static int __devinit sdhci_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct sdhci_pci_chip *chip; + struct sdhci_pci_slot *slot; + + u8 slots, rev, first_bar; + int ret, i; + + BUG_ON(pdev == NULL); + BUG_ON(ent == NULL); + + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); + + dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n", + (int)pdev->vendor, (int)pdev->device, (int)rev); + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); + if (ret) + return ret; + + slots = PCI_SLOT_INFO_SLOTS(slots) + 1; + dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); + if (slots == 0) + return -ENODEV; + + BUG_ON(slots > MAX_SLOTS); + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); + if (ret) + return ret; + + first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + + if (first_bar > 5) { + dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n"); + return -ENODEV; + } + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + chip = kzalloc(sizeof(struct sdhci_pci_chip), GFP_KERNEL); + if (!chip) { + ret = -ENOMEM; + goto err; + } + + chip->pdev = pdev; + chip->quirks = ent->driver_data; + chip->num_slots = slots; + + pci_set_drvdata(pdev, chip); + + for (i = 0;i < slots;i++) { + slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i); + if (IS_ERR(slot)) { + for (i--;i >= 0;i--) + sdhci_pci_remove_slot(chip->slots[i]); + ret = PTR_ERR(slot); + goto free; + } + + chip->slots[i] = slot; + } + + return 0; + +free: + pci_set_drvdata(pdev, NULL); + kfree(chip); + +err: + pci_disable_device(pdev); + return ret; +} + +static void __devexit sdhci_pci_remove(struct pci_dev *pdev) +{ + int i; + struct sdhci_pci_chip *chip; + + chip = pci_get_drvdata(pdev); + + if (chip) { + for (i = 0;i < chip->num_slots; i++) + sdhci_pci_remove_slot(chip->slots[i]); + + pci_set_drvdata(pdev, NULL); + kfree(chip); + } + + pci_disable_device(pdev); +} + +static struct pci_driver sdhci_driver = { + .name = "sdhci-pci", + .id_table = pci_ids, + .probe = sdhci_pci_probe, + .remove = __devexit_p(sdhci_pci_remove), + .suspend = sdhci_pci_suspend, + .resume = sdhci_pci_resume, +}; + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int __init sdhci_drv_init(void) +{ + return pci_register_driver(&sdhci_driver); +} + +static void __exit sdhci_drv_exit(void) +{ + pci_unregister_driver(&sdhci_driver); +} + +module_init(sdhci_drv_init); +module_exit(sdhci_drv_exit); + +MODULE_AUTHOR("Pierre Ossman "); +MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9b06c60..8ce01d4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include @@ -32,135 +32,6 @@ static unsigned int debug_quirks = 0; -/* - * Different quirks to handle when the hardware deviates from a strict - * interpretation of the SDHCI specification. - */ - -/* Controller doesn't honor resets unless we touch the clock register */ -#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) -/* Controller has bad caps bits, but really supports DMA */ -#define SDHCI_QUIRK_FORCE_DMA (1<<1) -/* Controller doesn't like to be reset when there is no card inserted. */ -#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) -/* Controller doesn't like clearing the power reg before a change */ -#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) -/* Controller has flaky internal state so reset it on each ios change */ -#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) -/* Controller has an unusable DMA engine */ -#define SDHCI_QUIRK_BROKEN_DMA (1<<5) -/* Controller can only DMA from 32-bit aligned addresses */ -#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) -/* Controller can only DMA chunk sizes that are a multiple of 32 bits */ -#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) -/* Controller needs to be reset after each request to stay stable */ -#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) -/* Controller needs voltage and power writes to happen separately */ -#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<9) -/* Controller has an off-by-one issue with timeout value */ -#define SDHCI_QUIRK_INCR_TIMEOUT_CONTROL (1<<10) - -static const struct pci_device_id pci_ids[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_RICOH, - .device = PCI_DEVICE_ID_RICOH_R5C822, - .subvendor = PCI_VENDOR_ID_IBM, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET | - SDHCI_QUIRK_FORCE_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_RICOH, - .device = PCI_DEVICE_ID_RICOH_R5C822, - .subvendor = PCI_VENDOR_ID_SAMSUNG, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_FORCE_DMA | - SDHCI_QUIRK_NO_CARD_NO_RESET, - }, - - { - .vendor = PCI_VENDOR_ID_RICOH, - .device = PCI_DEVICE_ID_RICOH_R5C822, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_FORCE_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_TI, - .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_FORCE_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_ENE, - .device = PCI_DEVICE_ID_ENE_CB712_SD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_BROKEN_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_ENE, - .device = PCI_DEVICE_ID_ENE_CB712_SD_2, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_BROKEN_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_ENE, - .device = PCI_DEVICE_ID_ENE_CB714_SD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | - SDHCI_QUIRK_BROKEN_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_ENE, - .device = PCI_DEVICE_ID_ENE_CB714_SD_2, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | - SDHCI_QUIRK_BROKEN_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_MARVELL, - .device = PCI_DEVICE_ID_MARVELL_CAFE_SD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | - SDHCI_QUIRK_INCR_TIMEOUT_CONTROL, - }, - - { - .vendor = PCI_VENDOR_ID_JMICRON, - .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR | - SDHCI_QUIRK_32BIT_DMA_SIZE | - SDHCI_QUIRK_RESET_AFTER_REQUEST, - }, - - { /* Generic SD host controller */ - PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) - }, - - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(pci, pci_ids); - static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); static void sdhci_finish_data(struct sdhci_host *); @@ -215,7 +86,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) { unsigned long timeout; - if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { + if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) return; @@ -488,7 +359,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) * Compensate for an off-by-one error in the CaFe hardware; otherwise, * a too-small count gives us interrupt timeouts. */ - if ((host->chip->quirks & SDHCI_QUIRK_INCR_TIMEOUT_CONTROL)) + if ((host->quirks & SDHCI_QUIRK_INCR_TIMEOUT_CONTROL)) count++; if (count >= 0xF) { @@ -503,7 +374,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) host->flags |= SDHCI_REQ_USE_DMA; if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && - (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) && + (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) && ((data->blksz * data->blocks) & 0x3))) { DBG("Reverting to PIO because of transfer size (%d)\n", data->blksz * data->blocks); @@ -515,7 +386,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) * translation to device address space. */ if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && - (host->chip->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && + (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && (data->sg->offset & 0x3))) { DBG("Reverting to PIO because of bad alignment\n"); host->flags &= ~SDHCI_REQ_USE_DMA; @@ -524,11 +395,13 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) if (host->flags & SDHCI_REQ_USE_DMA) { int count; - count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len, - (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); - BUG_ON(count != 1); + count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : DMA_TO_DEVICE); + WARN_ON(count != 1); - writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); + writel(sg_dma_address(data->sg), + host->ioaddr + SDHCI_DMA_ADDRESS); } else { host->cur_sg = data->sg; host->num_sg = data->sg_len; @@ -574,8 +447,9 @@ static void sdhci_finish_data(struct sdhci_host *host) host->data = NULL; if (host->flags & SDHCI_REQ_USE_DMA) { - pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len, - (data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : DMA_TO_DEVICE); } /* @@ -770,7 +644,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) * Spec says that we should clear the power reg before setting * a new value. Some controllers don't seem to like this though. */ - if (!(host->chip->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) + if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); pwr = SDHCI_POWER_ON; @@ -795,7 +669,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) * At least the CaFe chip gets confused if we set the voltage * and set turn on power at the same time, so set the voltage first. */ - if ((host->chip->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) + if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) writeb(pwr & ~SDHCI_POWER_ON, host->ioaddr + SDHCI_POWER_CONTROL); @@ -883,7 +757,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * signalling timeout and CRC errors even on CMD0. Resetting * it on each ios seems to solve the problem. */ - if(host->chip->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) + if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); mmiowb(); @@ -994,10 +868,10 @@ static void sdhci_tasklet_finish(unsigned long param) if (mrq->cmd->error || (mrq->data && (mrq->data->error || (mrq->data->stop && mrq->data->stop->error))) || - (host->chip->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { + (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { /* Some controllers need this kick or reset won't work here */ - if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { + if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { unsigned int clock; /* This is to force an update */ @@ -1229,165 +1103,90 @@ out: #ifdef CONFIG_PM -static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state) +int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) { - struct sdhci_chip *chip; - int i, ret; - - chip = pci_get_drvdata(pdev); - if (!chip) - return 0; - - DBG("Suspending...\n"); - - for (i = 0;i < chip->num_slots;i++) { - if (!chip->hosts[i]) - continue; - ret = mmc_suspend_host(chip->hosts[i]->mmc, state); - if (ret) { - for (i--;i >= 0;i--) - mmc_resume_host(chip->hosts[i]->mmc); - return ret; - } - } - - pci_save_state(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + int ret; - for (i = 0;i < chip->num_slots;i++) { - if (!chip->hosts[i]) - continue; - free_irq(chip->hosts[i]->irq, chip->hosts[i]); - } + ret = mmc_suspend_host(host->mmc, state); + if (ret) + return ret; - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + free_irq(host->irq, host); return 0; } -static int sdhci_resume (struct pci_dev *pdev) -{ - struct sdhci_chip *chip; - int i, ret; +EXPORT_SYMBOL_GPL(sdhci_suspend_host); - chip = pci_get_drvdata(pdev); - if (!chip) - return 0; +int sdhci_resume_host(struct sdhci_host *host) +{ + int ret; - DBG("Resuming...\n"); + if (host->flags & SDHCI_USE_DMA) { + if (host->ops->enable_dma) + host->ops->enable_dma(host); + } - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - ret = pci_enable_device(pdev); + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, + mmc_hostname(host->mmc), host); if (ret) return ret; - for (i = 0;i < chip->num_slots;i++) { - if (!chip->hosts[i]) - continue; - if (chip->hosts[i]->flags & SDHCI_USE_DMA) - pci_set_master(pdev); - ret = request_irq(chip->hosts[i]->irq, sdhci_irq, - IRQF_SHARED, mmc_hostname(chip->hosts[i]->mmc), - chip->hosts[i]); - if (ret) - return ret; - sdhci_init(chip->hosts[i]); - mmiowb(); - ret = mmc_resume_host(chip->hosts[i]->mmc); - if (ret) - return ret; - } + sdhci_init(host); + mmiowb(); + + ret = mmc_resume_host(host->mmc); + if (ret) + return ret; return 0; } -#else /* CONFIG_PM */ - -#define sdhci_suspend NULL -#define sdhci_resume NULL +EXPORT_SYMBOL_GPL(sdhci_resume_host); #endif /* CONFIG_PM */ /*****************************************************************************\ * * - * Device probing/removal * + * Device allocation/registration * * * \*****************************************************************************/ -static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) +struct sdhci_host *sdhci_alloc_host(struct device *dev, + size_t priv_size) { - int ret; - unsigned int version; - struct sdhci_chip *chip; struct mmc_host *mmc; struct sdhci_host *host; - u8 first_bar; - unsigned int caps; - - chip = pci_get_drvdata(pdev); - BUG_ON(!chip); - - ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); - if (ret) - return ret; - - first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + WARN_ON(dev == NULL); - if (first_bar > 5) { - printk(KERN_ERR DRIVER_NAME ": Invalid first BAR. Aborting.\n"); - return -ENODEV; - } - - if (!(pci_resource_flags(pdev, first_bar + slot) & IORESOURCE_MEM)) { - printk(KERN_ERR DRIVER_NAME ": BAR is not iomem. Aborting.\n"); - return -ENODEV; - } - - if (pci_resource_len(pdev, first_bar + slot) != 0x100) { - printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. " - "You may experience problems.\n"); - } - - if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) { - printk(KERN_ERR DRIVER_NAME ": Vendor specific interface. Aborting.\n"); - return -ENODEV; - } - - if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) { - printk(KERN_ERR DRIVER_NAME ": Unknown interface. Aborting.\n"); - return -ENODEV; - } - - mmc = mmc_alloc_host(sizeof(struct sdhci_host), &pdev->dev); + mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev); if (!mmc) - return -ENOMEM; + return ERR_PTR(-ENOMEM); host = mmc_priv(mmc); host->mmc = mmc; - host->chip = chip; - chip->hosts[slot] = host; + return host; +} - host->bar = first_bar + slot; +EXPORT_SYMBOL_GPL(sdhci_alloc_host); - host->addr = pci_resource_start(pdev, host->bar); - host->irq = pdev->irq; +int sdhci_add_host(struct sdhci_host *host) +{ + struct mmc_host *mmc; + unsigned int caps; + unsigned int version; + int ret; - DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq); + WARN_ON(host == NULL); + if (host == NULL) + return -EINVAL; - ret = pci_request_region(pdev, host->bar, mmc_hostname(mmc)); - if (ret) - goto free; + mmc = host->mmc; - host->ioaddr = ioremap_nocache(host->addr, - pci_resource_len(pdev, host->bar)); - if (!host->ioaddr) { - ret = -ENOMEM; - goto release; - } + if (debug_quirks) + host->quirks = debug_quirks; sdhci_reset(host, SDHCI_RESET_ALL); @@ -1401,46 +1200,40 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) caps = readl(host->ioaddr + SDHCI_CAPABILITIES); - if (chip->quirks & SDHCI_QUIRK_FORCE_DMA) + if (host->quirks & SDHCI_QUIRK_FORCE_DMA) host->flags |= SDHCI_USE_DMA; else if (!(caps & SDHCI_CAN_DO_DMA)) DBG("Controller doesn't have DMA capability\n"); else host->flags |= SDHCI_USE_DMA; - if ((chip->quirks & SDHCI_QUIRK_BROKEN_DMA) && + if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) && (host->flags & SDHCI_USE_DMA)) { DBG("Disabling DMA as it is marked broken\n"); host->flags &= ~SDHCI_USE_DMA; } - if (((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && - (host->flags & SDHCI_USE_DMA)) { - printk(KERN_WARNING "%s: Will use DMA " - "mode even though HW doesn't fully " - "claim to support it.\n", mmc_hostname(mmc)); - } - if (host->flags & SDHCI_USE_DMA) { - if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { - printk(KERN_WARNING "%s: No suitable DMA available. " - "Falling back to PIO.\n", mmc_hostname(mmc)); - host->flags &= ~SDHCI_USE_DMA; + if (host->ops->enable_dma) { + if (host->ops->enable_dma(host)) { + printk(KERN_WARNING "%s: No suitable DMA " + "available. Falling back to PIO.\n", + mmc_hostname(mmc)); + host->flags &= ~SDHCI_USE_DMA; + } } } - if (host->flags & SDHCI_USE_DMA) - pci_set_master(pdev); - else /* XXX: Hack to get MMC layer to avoid highmem */ - pdev->dma_mask = 0; + /* XXX: Hack to get MMC layer to avoid highmem */ + if (!(host->flags & SDHCI_USE_DMA)) + mmc_dev(host->mmc)->dma_mask = 0; host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; if (host->max_clk == 0) { printk(KERN_ERR "%s: Hardware doesn't specify base clock " "frequency.\n", mmc_hostname(mmc)); - ret = -ENODEV; - goto unmap; + return -ENODEV; } host->max_clk *= 1000000; @@ -1449,8 +1242,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) if (host->timeout_clk == 0) { printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " "frequency.\n", mmc_hostname(mmc)); - ret = -ENODEV; - goto unmap; + return -ENODEV; } if (caps & SDHCI_TIMEOUT_CLK_UNIT) host->timeout_clk *= 1000; @@ -1477,8 +1269,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) if (mmc->ocr_avail == 0) { printk(KERN_ERR "%s: Hardware doesn't report any " "support voltages.\n", mmc_hostname(mmc)); - ret = -ENODEV; - goto unmap; + return -ENODEV; } spin_lock_init(&host->lock); @@ -1548,7 +1339,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) host->led.default_trigger = mmc_hostname(mmc); host->led.brightness_set = sdhci_led_control; - ret = led_classdev_register(&pdev->dev, &host->led); + ret = led_classdev_register(mmc_dev(mmc), &host->led); if (ret) goto reset; #endif @@ -1557,8 +1348,8 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) mmc_add_host(mmc); - printk(KERN_INFO "%s: SDHCI at 0x%08lx irq %d %s\n", - mmc_hostname(mmc), host->addr, host->irq, + printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n", + mmc_hostname(mmc), host->hw_name, mmc_dev(mmc)->bus_id, (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); return 0; @@ -1571,29 +1362,15 @@ reset: untasklet: tasklet_kill(&host->card_tasklet); tasklet_kill(&host->finish_tasklet); -unmap: - iounmap(host->ioaddr); -release: - pci_release_region(pdev, host->bar); -free: - mmc_free_host(mmc); return ret; } -static void sdhci_remove_slot(struct pci_dev *pdev, int slot) -{ - struct sdhci_chip *chip; - struct mmc_host *mmc; - struct sdhci_host *host; - - chip = pci_get_drvdata(pdev); - host = chip->hosts[slot]; - mmc = host->mmc; - - chip->hosts[slot] = NULL; +EXPORT_SYMBOL_GPL(sdhci_add_host); - mmc_remove_host(mmc); +void sdhci_remove_host(struct sdhci_host *host) +{ + mmc_remove_host(host->mmc); #ifdef CONFIG_LEDS_CLASS led_classdev_unregister(&host->led); @@ -1607,107 +1384,16 @@ static void sdhci_remove_slot(struct pci_dev *pdev, int slot) tasklet_kill(&host->card_tasklet); tasklet_kill(&host->finish_tasklet); - - iounmap(host->ioaddr); - - pci_release_region(pdev, host->bar); - - mmc_free_host(mmc); } -static int __devinit sdhci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int ret, i; - u8 slots, rev; - struct sdhci_chip *chip; - - BUG_ON(pdev == NULL); - BUG_ON(ent == NULL); - - pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); - - printk(KERN_INFO DRIVER_NAME - ": SDHCI controller found at %s [%04x:%04x] (rev %x)\n", - pci_name(pdev), (int)pdev->vendor, (int)pdev->device, - (int)rev); - - ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); - if (ret) - return ret; - - slots = PCI_SLOT_INFO_SLOTS(slots) + 1; - DBG("found %d slot(s)\n", slots); - if (slots == 0) - return -ENODEV; +EXPORT_SYMBOL_GPL(sdhci_remove_host); - ret = pci_enable_device(pdev); - if (ret) - return ret; - - chip = kzalloc(sizeof(struct sdhci_chip) + - sizeof(struct sdhci_host*) * slots, GFP_KERNEL); - if (!chip) { - ret = -ENOMEM; - goto err; - } - - chip->pdev = pdev; - chip->quirks = ent->driver_data; - - if (debug_quirks) - chip->quirks = debug_quirks; - - chip->num_slots = slots; - pci_set_drvdata(pdev, chip); - - for (i = 0;i < slots;i++) { - ret = sdhci_probe_slot(pdev, i); - if (ret) { - for (i--;i >= 0;i--) - sdhci_remove_slot(pdev, i); - goto free; - } - } - - return 0; - -free: - pci_set_drvdata(pdev, NULL); - kfree(chip); - -err: - pci_disable_device(pdev); - return ret; -} - -static void __devexit sdhci_remove(struct pci_dev *pdev) +void sdhci_free_host(struct sdhci_host *host) { - int i; - struct sdhci_chip *chip; - - chip = pci_get_drvdata(pdev); - - if (chip) { - for (i = 0;i < chip->num_slots;i++) - sdhci_remove_slot(pdev, i); - - pci_set_drvdata(pdev, NULL); - - kfree(chip); - } - - pci_disable_device(pdev); + mmc_free_host(host->mmc); } -static struct pci_driver sdhci_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = sdhci_probe, - .remove = __devexit_p(sdhci_remove), - .suspend = sdhci_suspend, - .resume = sdhci_resume, -}; +EXPORT_SYMBOL_GPL(sdhci_free_host); /*****************************************************************************\ * * @@ -1721,14 +1407,11 @@ static int __init sdhci_drv_init(void) ": Secure Digital Host Controller Interface driver\n"); printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); - return pci_register_driver(&sdhci_driver); + return 0; } static void __exit sdhci_drv_exit(void) { - DBG("Exiting\n"); - - pci_unregister_driver(&sdhci_driver); } module_init(sdhci_drv_init); @@ -1737,7 +1420,7 @@ module_exit(sdhci_drv_exit); module_param(debug_quirks, uint, 0444); MODULE_AUTHOR("Pierre Ossman "); -MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver"); +MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver"); MODULE_LICENSE("GPL"); MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 299118d..22fc258 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -10,18 +10,6 @@ */ /* - * PCI registers - */ - -#define PCI_SDHCI_IFPIO 0x00 -#define PCI_SDHCI_IFDMA 0x01 -#define PCI_SDHCI_IFVENDOR 0x02 - -#define PCI_SLOT_INFO 0x40 /* 8 bits */ -#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7) -#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07 - -/* * Controller registers */ @@ -162,10 +150,43 @@ #define SDHCI_SPEC_VER_MASK 0x00FF #define SDHCI_SPEC_VER_SHIFT 0 -struct sdhci_chip; +struct sdhci_ops; struct sdhci_host { - struct sdhci_chip *chip; + /* Data set by hardware interface driver */ + const char *hw_name; /* Hardware bus name */ + + unsigned int quirks; /* Deviations from spec. */ + +/* Controller doesn't honor resets unless we touch the clock register */ +#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) +/* Controller has bad caps bits, but really supports DMA */ +#define SDHCI_QUIRK_FORCE_DMA (1<<1) +/* Controller doesn't like to be reset when there is no card inserted. */ +#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) +/* Controller doesn't like clearing the power reg before a change */ +#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) +/* Controller has flaky internal state so reset it on each ios change */ +#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) +/* Controller has an unusable DMA engine */ +#define SDHCI_QUIRK_BROKEN_DMA (1<<5) +/* Controller can only DMA from 32-bit aligned addresses */ +#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) +/* Controller can only DMA chunk sizes that are a multiple of 32 bits */ +#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) +/* Controller needs to be reset after each request to stay stable */ +#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) +/* Controller needs voltage and power writes to happen separately */ +#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<9) +/* Controller has an off-by-one issue with timeout value */ +#define SDHCI_QUIRK_INCR_TIMEOUT_CONTROL (1<<10) + + int irq; /* Device IRQ */ + void __iomem * ioaddr; /* Mapped address */ + + const struct sdhci_ops *ops; /* Low level hw interface */ + + /* Internal data */ struct mmc_host *mmc; /* MMC structure */ #ifdef CONFIG_LEDS_CLASS @@ -194,22 +215,33 @@ struct sdhci_host { int offset; /* Offset into current sg */ int remain; /* Bytes left in current */ - int irq; /* Device IRQ */ - int bar; /* PCI BAR index */ - unsigned long addr; /* Bus address */ - void __iomem * ioaddr; /* Mapped address */ - struct tasklet_struct card_tasklet; /* Tasklet structures */ struct tasklet_struct finish_tasklet; struct timer_list timer; /* Timer for timeouts */ -}; -struct sdhci_chip { - struct pci_dev *pdev; + unsigned long private[0] ____cacheline_aligned; +}; - unsigned long quirks; - int num_slots; /* Slots on controller */ - struct sdhci_host *hosts[0]; /* Pointers to hosts */ +struct sdhci_ops { + int (*enable_dma)(struct sdhci_host *host); }; + + +extern struct sdhci_host *sdhci_alloc_host(struct device *dev, + size_t priv_size); +extern void sdhci_free_host(struct sdhci_host *host); + +static inline void *sdhci_priv(struct sdhci_host *host) +{ + return (void *)host->private; +} + +extern int sdhci_add_host(struct sdhci_host *host); +extern void sdhci_remove_host(struct sdhci_host *host); + +#ifdef CONFIG_PM +extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); +extern int sdhci_resume_host(struct sdhci_host *host); +#endif -- cgit v0.10.2 From 3815a0ebab678c20d0d9c66af5ee9e68807b6681 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 22 Mar 2008 22:05:40 +0100 Subject: sdhci: remove forced dma quirks Remove the quirk to force DMA on the Ricoh and TI controllers as it is no longer needed. The only bug they have is that they use an incorrect PCI interface value, and that is not respected anymore. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 2a3dd6c..51798ec 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -44,8 +44,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_RICOH_R5C822, .subvendor = PCI_VENDOR_ID_IBM, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET | - SDHCI_QUIRK_FORCE_DMA, + .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET, }, { @@ -53,24 +52,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_RICOH_R5C822, .subvendor = PCI_VENDOR_ID_SAMSUNG, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_FORCE_DMA | - SDHCI_QUIRK_NO_CARD_NO_RESET, - }, - - { - .vendor = PCI_VENDOR_ID_RICOH, - .device = PCI_DEVICE_ID_RICOH_R5C822, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_FORCE_DMA, - }, - - { - .vendor = PCI_VENDOR_ID_TI, - .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_FORCE_DMA, + .driver_data = SDHCI_QUIRK_NO_CARD_NO_RESET, }, { -- cgit v0.10.2 From 22606405894a3ca5796eb4454a4b83af611fd201 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 23 Mar 2008 19:33:23 +0100 Subject: sdhci: more complex quirks handling Extend the quirks handling in the PCI driver to be able to have callbacks and not just flags. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 51798ec..5094fe8 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -38,21 +38,82 @@ #define MAX_SLOTS 8 -static const struct pci_device_id pci_ids[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_RICOH, - .device = PCI_DEVICE_ID_RICOH_R5C822, - .subvendor = PCI_VENDOR_ID_IBM, - .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET, - }, +struct sdhci_pci_chip; + +struct sdhci_pci_fixes { + unsigned int quirks; + + int (*probe)(struct sdhci_pci_chip*); +}; + +struct sdhci_pci_slot { + struct sdhci_pci_chip *chip; + struct sdhci_host *host; + int pci_bar; +}; + +struct sdhci_pci_chip { + struct pci_dev *pdev; + + unsigned int quirks; + const struct sdhci_pci_fixes *fixes; + + int num_slots; /* Slots on controller */ + struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */ +}; + + +/*****************************************************************************\ + * * + * Hardware specific quirk handling * + * * +\*****************************************************************************/ + +static int ricoh_probe(struct sdhci_pci_chip *chip) +{ + if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) + chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET; + + if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) + chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; + + return 0; +} + +static const struct sdhci_pci_fixes sdhci_ricoh = { + .probe = ricoh_probe, +}; + +static const struct sdhci_pci_fixes sdhci_ene_712 = { + .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_BROKEN_DMA, +}; + +static const struct sdhci_pci_fixes sdhci_ene_714 = { + .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | + SDHCI_QUIRK_BROKEN_DMA, +}; + +static const struct sdhci_pci_fixes sdhci_cafe = { + .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | + SDHCI_QUIRK_INCR_TIMEOUT_CONTROL, +}; + +static const struct sdhci_pci_fixes sdhci_jmicron = { + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_RESET_AFTER_REQUEST, +}; + +static const struct pci_device_id pci_ids[] __devinitdata = { { .vendor = PCI_VENDOR_ID_RICOH, .device = PCI_DEVICE_ID_RICOH_R5C822, - .subvendor = PCI_VENDOR_ID_SAMSUNG, + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_NO_CARD_NO_RESET, + .driver_data = (kernel_ulong_t)&sdhci_ricoh, }, { @@ -60,8 +121,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_ENE_CB712_SD, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_BROKEN_DMA, + .driver_data = (kernel_ulong_t)&sdhci_ene_712, }, { @@ -69,8 +129,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_ENE_CB712_SD_2, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_BROKEN_DMA, + .driver_data = (kernel_ulong_t)&sdhci_ene_712, }, { @@ -78,9 +137,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_ENE_CB714_SD, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | - SDHCI_QUIRK_BROKEN_DMA, + .driver_data = (kernel_ulong_t)&sdhci_ene_714, }, { @@ -88,9 +145,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_ENE_CB714_SD_2, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS | - SDHCI_QUIRK_BROKEN_DMA, + .driver_data = (kernel_ulong_t)&sdhci_ene_714, }, { @@ -98,8 +153,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_MARVELL_CAFE_SD, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | - SDHCI_QUIRK_INCR_TIMEOUT_CONTROL, + .driver_data = (kernel_ulong_t)&sdhci_cafe, }, { @@ -107,9 +161,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR | - SDHCI_QUIRK_32BIT_DMA_SIZE | - SDHCI_QUIRK_RESET_AFTER_REQUEST, + .driver_data = (kernel_ulong_t)&sdhci_jmicron, }, { /* Generic SD host controller */ @@ -121,23 +173,6 @@ static const struct pci_device_id pci_ids[] __devinitdata = { MODULE_DEVICE_TABLE(pci, pci_ids); -struct sdhci_pci_chip; - -struct sdhci_pci_slot { - struct sdhci_pci_chip *chip; - struct sdhci_host *host; - - int pci_bar; -}; - -struct sdhci_pci_chip { - struct pci_dev *pdev; - unsigned int quirks; - - int num_slots; /* Slots on controller */ - struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */ -}; - /*****************************************************************************\ * * * SDHCI core callbacks * @@ -389,11 +424,19 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, } chip->pdev = pdev; - chip->quirks = ent->driver_data; + chip->fixes = (const struct sdhci_pci_fixes*)ent->driver_data; + if (chip->fixes) + chip->quirks = chip->fixes->quirks; chip->num_slots = slots; pci_set_drvdata(pdev, chip); + if (chip->fixes && chip->fixes->probe) { + ret = chip->fixes->probe(chip); + if (ret) + goto free; + } + for (i = 0;i < slots;i++) { slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i); if (IS_ERR(slot)) { -- cgit v0.10.2 From ee53ab5d73998e502801c024a08de2c39a92c52a Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 5 Jul 2008 00:25:15 +0200 Subject: sdhci: make workaround for timeout bug more general Give the quirk for broken timeout handling a better chance of handling more controllers by simply classifying the system as broken and setting a fixed value. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 5094fe8..856bb2b 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -98,7 +98,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = { static const struct sdhci_pci_fixes sdhci_cafe = { .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | - SDHCI_QUIRK_INCR_TIMEOUT_CONTROL, + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, }; static const struct sdhci_pci_fixes sdhci_jmicron = { diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8ce01d4..95b081a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -314,23 +314,19 @@ static void sdhci_transfer_pio(struct sdhci_host *host) DBG("PIO transfer complete.\n"); } -static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) +static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) { u8 count; unsigned target_timeout, current_timeout; - WARN_ON(host->data); - - if (data == NULL) - return; - - /* Sanity checks */ - BUG_ON(data->blksz * data->blocks > 524288); - BUG_ON(data->blksz > host->mmc->max_blk_size); - BUG_ON(data->blocks > 65535); - - host->data = data; - host->data_early = 0; + /* + * If the host controller provides us with an incorrect timeout + * value, just skip the check and use 0xE. The hardware may take + * longer to time out, but that's much better than having a too-short + * timeout value. + */ + if ((host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)) + return 0xE; /* timeout in us */ target_timeout = data->timeout_ns / 1000 + @@ -355,19 +351,33 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) break; } - /* - * Compensate for an off-by-one error in the CaFe hardware; otherwise, - * a too-small count gives us interrupt timeouts. - */ - if ((host->quirks & SDHCI_QUIRK_INCR_TIMEOUT_CONTROL)) - count++; - if (count >= 0xF) { printk(KERN_WARNING "%s: Too large timeout requested!\n", mmc_hostname(host->mmc)); count = 0xE; } + return count; +} + +static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) +{ + u8 count; + + WARN_ON(host->data); + + if (data == NULL) + return; + + /* Sanity checks */ + BUG_ON(data->blksz * data->blocks > 524288); + BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + + host->data = data; + host->data_early = 0; + + count = sdhci_calc_timeout(host, data); writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); if (host->flags & SDHCI_USE_DMA) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 22fc258..7ce12f3 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -178,8 +178,8 @@ struct sdhci_host { #define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) /* Controller needs voltage and power writes to happen separately */ #define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<9) -/* Controller has an off-by-one issue with timeout value */ -#define SDHCI_QUIRK_INCR_TIMEOUT_CONTROL (1<<10) +/* Controller provides an incorrect timeout value for transfers */ +#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<10) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ -- cgit v0.10.2 From 45211e21598441a32e53cf5032b7faeac143df6d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 24 Mar 2008 13:09:09 +0100 Subject: sdhci: toggle JMicron PMOS setting Some of the JMicron chips requires us to manually enable the power output stages of the chip. Add the necessary hooks and functions to manage this. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 856bb2b..ef77ed1 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -44,6 +44,8 @@ struct sdhci_pci_fixes { unsigned int quirks; int (*probe)(struct sdhci_pci_chip*); + + int (*resume)(struct sdhci_pci_chip*); }; struct sdhci_pci_slot { @@ -101,10 +103,69 @@ static const struct sdhci_pci_fixes sdhci_cafe = { SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, }; +static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) +{ + u8 scratch; + int ret; + + ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); + if (ret) + return ret; + + /* + * Turn PMOS on [bit 0], set over current detection to 2.4 V + * [bit 1:2] and enable over current debouncing [bit 6]. + */ + if (on) + scratch |= 0x47; + else + scratch &= ~0x47; + + ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); + if (ret) + return ret; + + return 0; +} + +static int jmicron_probe(struct sdhci_pci_chip *chip) +{ + int ret; + + /* + * JMicron chips need a bit of a nudge to enable the power + * output pins. + */ + ret = jmicron_pmos(chip, 1); + if (ret) { + dev_err(&chip->pdev->dev, "Failure enabling card power\n"); + return ret; + } + + return 0; +} + +static int jmicron_resume(struct sdhci_pci_chip *chip) +{ + int ret; + + ret = jmicron_pmos(chip, 1); + if (ret) { + dev_err(&chip->pdev->dev, "Failure enabling card power\n"); + return ret; + } + + return 0; +} + static const struct sdhci_pci_fixes sdhci_jmicron = { .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST, + + .probe = jmicron_probe, + + .resume = jmicron_resume, }; static const struct pci_device_id pci_ids[] __devinitdata = { @@ -264,6 +325,12 @@ static int sdhci_pci_resume (struct pci_dev *pdev) if (ret) return ret; + if (chip->fixes && chip->fixes->resume) { + ret = chip->fixes->resume(chip); + if (ret) + return ret; + } + for (i = 0;i < chip->num_slots;i++) { slot = chip->slots[i]; if (!slot) -- cgit v0.10.2 From 4489428ab5a49a6f443d9aa17f1d891417787d7b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 4 Apr 2008 19:36:59 +0200 Subject: sdhci: support JMicron secondary interface JMicron chips sometimes have two interfaces to work around limitations in Microsoft's sdhci driver. This patch allows us to use either interface. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index ef77ed1..5dcb495 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -39,12 +39,18 @@ #define MAX_SLOTS 8 struct sdhci_pci_chip; +struct sdhci_pci_slot; struct sdhci_pci_fixes { unsigned int quirks; int (*probe)(struct sdhci_pci_chip*); + int (*probe_slot)(struct sdhci_pci_slot*); + void (*remove_slot)(struct sdhci_pci_slot*); + + int (*suspend)(struct sdhci_pci_chip*, + pm_message_t); int (*resume)(struct sdhci_pci_chip*); }; @@ -133,6 +139,38 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) int ret; /* + * JMicron chips can have two interfaces to the same hardware + * in order to work around limitations in Microsoft's driver. + * We need to make sure we only bind to one of them. + * + * This code assumes two things: + * + * 1. The PCI code adds subfunctions in order. + * + * 2. The MMC interface has a lower subfunction number + * than the SD interface. + */ + if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD) { + struct pci_dev *sd_dev; + + sd_dev = NULL; + while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON, + PCI_DEVICE_ID_JMICRON_JMB38X_MMC, sd_dev)) != NULL) { + if ((PCI_SLOT(chip->pdev->devfn) == + PCI_SLOT(sd_dev->devfn)) && + (chip->pdev->bus == sd_dev->bus)) + break; + } + + if (sd_dev) { + pci_dev_put(sd_dev); + dev_info(&chip->pdev->dev, "Refusing to bind to " + "secondary interface.\n"); + return -ENODEV; + } + } + + /* * JMicron chips need a bit of a nudge to enable the power * output pins. */ @@ -145,9 +183,58 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) return 0; } +static void jmicron_enable_mmc(struct sdhci_host *host, int on) +{ + u8 scratch; + + scratch = readb(host->ioaddr + 0xC0); + + if (on) + scratch |= 0x01; + else + scratch &= ~0x01; + + writeb(scratch, host->ioaddr + 0xC0); +} + +static int jmicron_probe_slot(struct sdhci_pci_slot *slot) +{ + /* + * The secondary interface requires a bit set to get the + * interrupts. + */ + if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) + jmicron_enable_mmc(slot->host, 1); + + return 0; +} + +static void jmicron_remove_slot(struct sdhci_pci_slot *slot) +{ + if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) + jmicron_enable_mmc(slot->host, 0); +} + +static int jmicron_suspend(struct sdhci_pci_chip *chip, pm_message_t state) +{ + int i; + + if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) { + for (i = 0;i < chip->num_slots;i++) + jmicron_enable_mmc(chip->slots[i]->host, 0); + } + + return 0; +} + static int jmicron_resume(struct sdhci_pci_chip *chip) { - int ret; + int ret, i; + + if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) { + for (i = 0;i < chip->num_slots;i++) + jmicron_enable_mmc(chip->slots[i]->host, 1); + } ret = jmicron_pmos(chip, 1); if (ret) { @@ -165,6 +252,10 @@ static const struct sdhci_pci_fixes sdhci_jmicron = { .probe = jmicron_probe, + .probe_slot = jmicron_probe_slot, + .remove_slot = jmicron_remove_slot, + + .suspend = jmicron_suspend, .resume = jmicron_resume, }; @@ -225,6 +316,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = { .driver_data = (kernel_ulong_t)&sdhci_jmicron, }, + { + .vendor = PCI_VENDOR_ID_JMICRON, + .device = PCI_DEVICE_ID_JMICRON_JMB38X_MMC, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_jmicron, + }, + { /* Generic SD host controller */ PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) }, @@ -301,6 +400,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) } } + if (chip->fixes && chip->fixes->suspend) { + ret = chip->fixes->suspend(chip, state); + if (ret) { + for (i = chip->num_slots - 1;i >= 0;i--) + sdhci_resume_host(chip->slots[i]->host); + return ret; + } + } + pci_save_state(pdev); pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); pci_disable_device(pdev); @@ -418,12 +526,22 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( goto release; } + if (chip->fixes && chip->fixes->probe_slot) { + ret = chip->fixes->probe_slot(slot); + if (ret) + goto unmap; + } + ret = sdhci_add_host(host); if (ret) - goto unmap; + goto remove; return slot; +remove: + if (chip->fixes && chip->fixes->remove_slot) + chip->fixes->remove_slot(slot); + unmap: iounmap(host->ioaddr); @@ -437,7 +555,12 @@ release: static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) { sdhci_remove_host(slot->host); + + if (slot->chip->fixes && slot->chip->fixes->remove_slot) + slot->chip->fixes->remove_slot(slot); + pci_release_region(slot->chip->pdev, slot->pci_bar); + sdhci_free_host(slot->host); } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6595382..3015347 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2188,6 +2188,7 @@ #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 #define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 #define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 +#define PCI_DEVICE_ID_JMICRON_JMB38X_MMC 0x2382 #define PCI_DEVICE_ID_JMICRON_JMB38X_MS 0x2383 #define PCI_VENDOR_ID_KORENIX 0x1982 -- cgit v0.10.2 From 1e72859e3ae16346d4007024b20d2d4ef387dcc3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 16 Apr 2008 19:13:13 +0200 Subject: sdhci: handle hot-remove Gracefully handle when the device is suddenly removed. Do a test read and avoid any further access if that read returns -1. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 5dcb495..8554466 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -47,7 +47,7 @@ struct sdhci_pci_fixes { int (*probe)(struct sdhci_pci_chip*); int (*probe_slot)(struct sdhci_pci_slot*); - void (*remove_slot)(struct sdhci_pci_slot*); + void (*remove_slot)(struct sdhci_pci_slot*, int); int (*suspend)(struct sdhci_pci_chip*, pm_message_t); @@ -209,8 +209,11 @@ static int jmicron_probe_slot(struct sdhci_pci_slot *slot) return 0; } -static void jmicron_remove_slot(struct sdhci_pci_slot *slot) +static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead) { + if (dead) + return; + if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) jmicron_enable_mmc(slot->host, 0); } @@ -540,7 +543,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( remove: if (chip->fixes && chip->fixes->remove_slot) - chip->fixes->remove_slot(slot); + chip->fixes->remove_slot(slot, 0); unmap: iounmap(host->ioaddr); @@ -554,10 +557,18 @@ release: static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) { - sdhci_remove_host(slot->host); + int dead; + u32 scratch; + + dead = 0; + scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); + if (scratch == (u32)-1) + dead = 1; + + sdhci_remove_host(slot->host, dead); if (slot->chip->fixes && slot->chip->fixes->remove_slot) - slot->chip->fixes->remove_slot(slot); + slot->chip->fixes->remove_slot(slot, dead); pci_release_region(slot->chip->pdev, slot->pci_bar); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 95b081a..0ab582e 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -712,7 +712,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->mrq = mrq; - if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + 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 @@ -732,6 +733,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) spin_lock_irqsave(&host->lock, flags); + if (host->flags & SDHCI_DEVICE_DEAD) + goto out; + /* * Reset the chip on each power off. * Should clear out any weird states. @@ -770,6 +774,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); +out: mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } @@ -784,7 +789,10 @@ static int sdhci_get_ro(struct mmc_host *mmc) spin_lock_irqsave(&host->lock, flags); - present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + if (host->flags & SDHCI_DEVICE_DEAD) + present = 0; + else + present = readl(host->ioaddr + SDHCI_PRESENT_STATE); spin_unlock_irqrestore(&host->lock, flags); @@ -801,6 +809,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) spin_lock_irqsave(&host->lock, flags); + if (host->flags & SDHCI_DEVICE_DEAD) + goto out; + ier = readl(host->ioaddr + SDHCI_INT_ENABLE); ier &= ~SDHCI_INT_CARD_INT; @@ -810,6 +821,7 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) writel(ier, host->ioaddr + SDHCI_INT_ENABLE); writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); +out: mmiowb(); spin_unlock_irqrestore(&host->lock, flags); @@ -875,10 +887,11 @@ static void sdhci_tasklet_finish(unsigned long param) * The controller needs a reset of internal state machines * upon error conditions. */ - if (mrq->cmd->error || - (mrq->data && (mrq->data->error || - (mrq->data->stop && mrq->data->stop->error))) || - (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST)) { + if (!(host->flags & SDHCI_DEVICE_DEAD) && + (mrq->cmd->error || + (mrq->data && (mrq->data->error || + (mrq->data->stop && mrq->data->stop->error))) || + (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { /* Some controllers need this kick or reset won't work here */ if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { @@ -1378,15 +1391,34 @@ untasklet: EXPORT_SYMBOL_GPL(sdhci_add_host); -void sdhci_remove_host(struct sdhci_host *host) +void sdhci_remove_host(struct sdhci_host *host, int dead) { + unsigned long flags; + + if (dead) { + spin_lock_irqsave(&host->lock, flags); + + host->flags |= SDHCI_DEVICE_DEAD; + + if (host->mrq) { + printk(KERN_ERR "%s: Controller removed during " + " transfer!\n", mmc_hostname(host->mmc)); + + host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } + + spin_unlock_irqrestore(&host->lock, flags); + } + mmc_remove_host(host->mmc); #ifdef CONFIG_LEDS_CLASS led_classdev_unregister(&host->led); #endif - sdhci_reset(host, SDHCI_RESET_ALL); + if (!dead) + sdhci_reset(host, SDHCI_RESET_ALL); free_irq(host->irq, host); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 7ce12f3..7c30251 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -198,6 +198,7 @@ struct sdhci_host { int flags; /* Host attributes */ #define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */ #define SDHCI_REQ_USE_DMA (1<<1) /* Use DMA for this req. */ +#define SDHCI_DEVICE_DEAD (1<<2) /* Device unresponsive */ unsigned int max_clk; /* Max possible freq (MHz) */ unsigned int timeout_clk; /* Timeout freq (KHz) */ @@ -239,7 +240,7 @@ static inline void *sdhci_priv(struct sdhci_host *host) } extern int sdhci_add_host(struct sdhci_host *host); -extern void sdhci_remove_host(struct sdhci_host *host); +extern void sdhci_remove_host(struct sdhci_host *host, int dead); #ifdef CONFIG_PM extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); -- cgit v0.10.2 From fd8c326cadd2f781d5c4d6bcee79bb17b3745bb0 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 24 May 2008 22:36:31 +0200 Subject: mmc_test: add test case control Add the ability to run just a single test case by writing the test case number into the sysfs "test" file. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index ffadee5..371d922 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -743,7 +743,7 @@ static const struct mmc_test_case mmc_test_cases[] = { static struct mutex mmc_test_lock; -static void mmc_test_run(struct mmc_test_card *test) +static void mmc_test_run(struct mmc_test_card *test, int testcase) { int i, ret; @@ -753,6 +753,9 @@ static void mmc_test_run(struct mmc_test_card *test) mmc_claim_host(test->card->host); for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) { + if (testcase && ((i + 1) != testcase)) + continue; + printk(KERN_INFO "%s: Test case %d. %s...\n", mmc_hostname(test->card->host), i + 1, mmc_test_cases[i].name); @@ -824,9 +827,12 @@ static ssize_t mmc_test_store(struct device *dev, { struct mmc_card *card; struct mmc_test_card *test; + int testcase; card = container_of(dev, struct mmc_card, dev); + testcase = simple_strtol(buf, NULL, 10); + test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL); if (!test) return -ENOMEM; @@ -836,7 +842,7 @@ static ssize_t mmc_test_store(struct device *dev, test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); if (test->buffer) { mutex_lock(&mmc_test_lock); - mmc_test_run(test); + mmc_test_run(test, testcase); mutex_unlock(&mmc_test_lock); } -- cgit v0.10.2 From 309d9736a903527d8bc41787b07573a054439bf6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 28 May 2008 09:54:50 +0200 Subject: sdhci-pci: unaligned data with ricoh controllers The Ricoh controllers cannot handle unaligned data blocks. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 8554466..c0fbf48 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -91,6 +91,7 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) static const struct sdhci_pci_fixes sdhci_ricoh = { .probe = ricoh_probe, + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, }; static const struct sdhci_pci_fixes sdhci_ene_712 = { -- cgit v0.10.2 From 150a55683b6b0ccb66aae75a10a3a514340c7c03 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 May 2008 00:57:27 +0300 Subject: include/linux/mmc/mmc.h: remove CVS tags This patch removes a CVS tag that wasn't updated for a long time. Signed-off-by: Adrian Bunk Signed-off-by: Pierre Ossman diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 4236fbf..14b81f3 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -16,7 +16,6 @@ * Based strongly on code by: * * Author: Yong-iL Joh - * Date : $Date: 2002/06/18 12:37:30 $ * * Author: Andrew Christian * 15 May 2002 -- cgit v0.10.2 From 28f52482b41edc88cdf575aa6ed414c6e116ce10 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 17 Jun 2008 18:17:15 +0400 Subject: mmc: add support for card-detection polling Some hosts (and boards that use mmc_spi) do not use interrupts on the CD line, so they can't trigger mmc_detect_change. We want to poll the card and see if there was a change. 1 second poll interval seems resonable. This patch also implements .get_cd() host operation, that could be used by the hosts that are able to report card-detect status without need to talk MMC. Signed-off-by: Anton Vorontsov Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 01ced4c..ede5d1e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -638,6 +638,9 @@ void mmc_rescan(struct work_struct *work) */ mmc_bus_put(host); + if (host->ops->get_cd && host->ops->get_cd(host) == 0) + goto out; + mmc_claim_host(host); mmc_power_up(host); @@ -652,7 +655,7 @@ void mmc_rescan(struct work_struct *work) if (!err) { if (mmc_attach_sdio(host, ocr)) mmc_power_off(host); - return; + goto out; } /* @@ -662,7 +665,7 @@ void mmc_rescan(struct work_struct *work) if (!err) { if (mmc_attach_sd(host, ocr)) mmc_power_off(host); - return; + goto out; } /* @@ -672,7 +675,7 @@ void mmc_rescan(struct work_struct *work) if (!err) { if (mmc_attach_mmc(host, ocr)) mmc_power_off(host); - return; + goto out; } mmc_release_host(host); @@ -683,6 +686,9 @@ void mmc_rescan(struct work_struct *work) mmc_bus_put(host); } +out: + if (host->caps & MMC_CAP_NEEDS_POLL) + mmc_schedule_delayed_work(&host->detect, HZ); } void mmc_start_host(struct mmc_host *host) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 7ab962f..6188e19 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -51,8 +51,18 @@ struct mmc_ios { struct mmc_host_ops { void (*request)(struct mmc_host *host, struct mmc_request *req); + /* + * Avoid calling these three functions too often or in a "fast path", + * since underlaying controller might implement them in an expensive + * and/or slow way. + * + * Also note that these functions might sleep, so don't call them + * in the atomic contexts! + */ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); int (*get_ro)(struct mmc_host *host); + int (*get_cd)(struct mmc_host *host); + void (*enable_sdio_irq)(struct mmc_host *host, int enable); }; @@ -94,6 +104,7 @@ struct mmc_host { #define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */ #define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */ #define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */ +#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ -- cgit v0.10.2 From 619ef4b42128709de4d89d209b2c874f560deecd Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 17 Jun 2008 18:17:21 +0400 Subject: mmc_spi: add support for card-detection polling This patch adds new platform data variable "caps", so platforms could pass theirs capabilities into MMC core (for example, platforms without interrupt on the CD line will most probably want to pass MMC_CAP_NEEDS_POLL). New platform get_cd() callback provided to optimize polling. Signed-off-by: Anton Vorontsov Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 3550858..547eb85 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1131,11 +1131,20 @@ static int mmc_spi_get_ro(struct mmc_host *mmc) return 0; } +static int mmc_spi_get_cd(struct mmc_host *mmc) +{ + struct mmc_spi_host *host = mmc_priv(mmc); + + if (host->pdata && host->pdata->get_cd) + return !!host->pdata->get_cd(mmc->parent); + return -ENOSYS; +} static const struct mmc_host_ops mmc_spi_ops = { .request = mmc_spi_request, .set_ios = mmc_spi_set_ios, .get_ro = mmc_spi_get_ro, + .get_cd = mmc_spi_get_cd, }; @@ -1319,17 +1328,23 @@ static int mmc_spi_probe(struct spi_device *spi) goto fail_glue_init; } + /* pass platform capabilities, if any */ + if (host->pdata) + mmc->caps |= host->pdata->caps; + status = mmc_add_host(mmc); if (status != 0) goto fail_add_host; - dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n", + dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", mmc->class_dev.bus_id, host->dma_dev ? "" : ", no DMA", (host->pdata && host->pdata->get_ro) ? "" : ", no WP", (host->pdata && host->pdata->setpower) - ? "" : ", no poweroff"); + ? "" : ", no poweroff", + (mmc->caps & MMC_CAP_NEEDS_POLL) + ? ", cd polling" : ""); return 0; fail_add_host: diff --git a/include/linux/spi/mmc_spi.h b/include/linux/spi/mmc_spi.h index d5ca78b..a3626ae 100644 --- a/include/linux/spi/mmc_spi.h +++ b/include/linux/spi/mmc_spi.h @@ -23,6 +23,15 @@ struct mmc_spi_platform_data { /* sense switch on sd cards */ int (*get_ro)(struct device *); + /* + * If board does not use CD interrupts, driver can optimize polling + * using this function. + */ + int (*get_cd)(struct device *); + + /* Capabilities to pass into mmc core (e.g. MMC_CAP_NEEDS_POLL). */ + unsigned long caps; + /* how long to debounce card detect, in msecs */ u16 detect_delay; -- cgit v0.10.2 From 08f80bb5196517a0dfe50dc7c10f234c0ff2f0e8 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 17 Jun 2008 18:17:39 +0400 Subject: mmc: change .get_ro() callback semantics Now get_ro() callback must return 0/1 values for its logical states, and negative errno values in case of error. If particular host instance doesn't support RO/WP switch, it should return -ENOSYS. This patch changes some hosts in two ways: 1. Now functions should be smart to not return negative values in "RO asserted" case (particularly gpio_ calls could return negative values for the outermost GPIOs). Also, board code usually passes get_ro() callbacks that directly return gpioreg & bit result, so at91_mci, imxmmc, pxamci and mmc_spi's get_ro() handlers need take special care when returning platform's values to the mmc core. 2. In case of host instance didn't implement get_ro() callback, it should really return -ENOSYS and let the mmc core decide what to do about it (mmc core thinks the same way as the hosts, so it isn't functional change). Signed-off-by: Anton Vorontsov Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 7ef3b15..b122eb9 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -494,13 +494,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, * Check if read-only switch is active. */ if (!oldcard) { - if (!host->ops->get_ro) { + if (!host->ops->get_ro || host->ops->get_ro(host) < 0) { printk(KERN_WARNING "%s: host does not " "support reading read-only " "switch. assuming write-enable.\n", mmc_hostname(host)); } else { - if (host->ops->get_ro(host)) + if (host->ops->get_ro(host) > 0) mmc_card_set_readonly(card); } } diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 8979ad3..b9d4ed6 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -793,19 +793,15 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host) static int at91_mci_get_ro(struct mmc_host *mmc) { - int read_only = 0; struct at91mci_host *host = mmc_priv(mmc); - if (host->board->wp_pin) { - read_only = gpio_get_value(host->board->wp_pin); - printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc), - (read_only ? "read-only" : "read-write") ); - } - else { - printk(KERN_WARNING "%s: host does not support reading read-only " - "switch. Assuming write-enable.\n", mmc_hostname(mmc)); - } - return read_only; + if (host->board->wp_pin) + return !!gpio_get_value(host->board->wp_pin); + /* + * Board doesn't support read only detection; let the mmc core + * decide what to do. + */ + return -ENOSYS; } static const struct mmc_host_ops at91_mci_ops = { diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index eed211b..5e880c0 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -892,9 +892,12 @@ static int imxmci_get_ro(struct mmc_host *mmc) struct imxmci_host *host = mmc_priv(mmc); if (host->pdata && host->pdata->get_ro) - return host->pdata->get_ro(mmc_dev(mmc)); - /* Host doesn't support read only detection so assume writeable */ - return 0; + 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; } diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 547eb85..4e82f64 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1126,9 +1126,12 @@ static int mmc_spi_get_ro(struct mmc_host *mmc) struct mmc_spi_host *host = mmc_priv(mmc); if (host->pdata && host->pdata->get_ro) - return host->pdata->get_ro(mmc->parent); - /* board doesn't support read only detection; assume writeable */ - return 0; + return !!host->pdata->get_ro(mmc->parent); + /* + * Board doesn't support read only detection; let the mmc core + * decide what to do. + */ + return -ENOSYS; } static int mmc_spi_get_cd(struct mmc_host *mmc) diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index d89475d..d39f597 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -374,9 +374,12 @@ static int pxamci_get_ro(struct mmc_host *mmc) struct pxamci_host *host = mmc_priv(mmc); if (host->pdata && host->pdata->get_ro) - return host->pdata->get_ro(mmc_dev(mmc)); - /* Host doesn't support read only detection so assume writeable */ - return 0; + 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 void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index c303e7f..67e5a9b 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -939,7 +939,7 @@ static int wbsd_get_ro(struct mmc_host *mmc) spin_unlock_bh(&host->lock); - return csr & WBSD_WRPT; + return !!(csr & WBSD_WRPT); } static const struct mmc_host_ops wbsd_ops = { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6188e19..753b723 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -58,6 +58,18 @@ struct mmc_host_ops { * * Also note that these functions might sleep, so don't call them * in the atomic contexts! + * + * 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 + * + * Return values for the get_ro callback should be: + * 0 for a absent card + * 1 for a present card + * -ENOSYS when not supported (equal to NULL callback) + * or a negative errno value when something bad happened */ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); int (*get_ro)(struct mmc_host *host); -- cgit v0.10.2 From 8769392b1918ec70ab62eebc82e06c47c12f8304 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Mon, 16 Jun 2008 19:20:57 -0700 Subject: MMC: Trivial comment cleanup Make the variable name in the comments match the actual name of the variable. Signed-off-by: Deepak Saxena Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 3da29ee..fdd7c76 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -288,7 +288,7 @@ static struct device_type mmc_type = { /* * Handle the detection and initialisation of a card. * - * In the case of a resume, "curcard" will contain the card + * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index b122eb9..26fc098 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -326,7 +326,7 @@ static struct device_type sd_type = { /* * Handle the detection and initialisation of a card. * - * In the case of a resume, "curcard" will contain the card + * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, -- cgit v0.10.2 From 80f9254668c63ae73c1359d8de50ad94aa1aa94a Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:05:24 +0200 Subject: mmc: at91_mci: support for block size not modulo 4 Implement transfer with size not modulo 4 for at91sam9*. Please note that the at91rm9200 simply can't handle this. Signed-off-by: Marc Pignat Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b9d4ed6..e40340f 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -233,11 +233,11 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host) if (i == 0) { at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address); - at91_mci_write(host, ATMEL_PDC_RCR, sg->length / 4); + at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); } else { at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address); - at91_mci_write(host, ATMEL_PDC_RNCR, sg->length / 4); + at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); } } @@ -430,7 +430,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command if (data) { - if ( data->blksz & 0x3 ) { + if ( cpu_is_at91rm9200() && (data->blksz & 0x3) ) { pr_debug("Unsupported block size\n"); cmd->error = -EINVAL; mmc_request_done(host->mmc, host->request); @@ -482,7 +482,10 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command } else { /* zero block length and PDC mode */ mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; - at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); + mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0; + mr |= (block_length << 16); + mr |= AT91_MCI_PDCMODE; + at91_mci_write(host, AT91_MCI_MR, mr); /* * Disable the PDC controller @@ -517,7 +520,9 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command pr_debug("Transmitting %d bytes\n", host->total_length); at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); - at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4); + at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ? + host->total_length : host->total_length / 4); + ier = AT91_MCI_CMDRDY; } } -- cgit v0.10.2 From e181dce8acab4f7d7c4772d2a8281510d503ab21 Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:06:32 +0200 Subject: mmc: at91_mci: show timeouts Detect command timeout (or mci controller hangs). Signed-off-by: Marc Pignat Signed-off-by: Hans J Koch Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e40340f..fce171c 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -125,8 +125,33 @@ struct at91mci_host /* Latest in the scatterlist that has been enabled for transfer */ int transfer_index; + + /* Timer for timeouts */ + struct timer_list timer; }; +static void at91_timeout_timer(unsigned long data) +{ + struct at91mci_host *host; + + host = (struct at91mci_host *)data; + + if (host->request) { + dev_err(host->mmc->parent, "Timeout waiting end of packet\n"); + + if (host->cmd && host->cmd->data) { + host->cmd->data->error = -ETIMEDOUT; + } else { + if (host->cmd) + host->cmd->error = -ETIMEDOUT; + else + host->request->cmd->error = -ETIMEDOUT; + } + + mmc_request_done(host->mmc, host->request); + } +} + /* * Copy from sg to a dma block - used for transfers */ @@ -557,9 +582,10 @@ static void at91_mci_process_next(struct at91mci_host *host) else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) { host->flags |= FL_SENT_STOP; at91_mci_send_command(host, host->request->stop); - } - else + } else { + del_timer(&host->timer); mmc_request_done(host->mmc, host->request); + } } /* @@ -618,6 +644,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->request = mrq; host->flags = 0; + mod_timer(&host->timer, jiffies + HZ); + at91_mci_process_next(host); } @@ -936,6 +964,8 @@ static int __init at91_mci_probe(struct platform_device *pdev) mmc_add_host(mmc); + setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host); + /* * monitor card insertion/removal if we can */ @@ -996,6 +1026,7 @@ static int __exit at91_mci_remove(struct platform_device *pdev) } at91_mci_disable(host); + del_timer_sync(&host->timer); mmc_remove_host(mmc); free_irq(host->irq, host); -- cgit v0.10.2 From c5a89c6c0805959f813e8342d6f4040860f6d7db Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:07:47 +0200 Subject: mmc: at91_mci: avoid timeouts The at91 mci controller internal state machine seems to often crash. This can be fixed by resetting the controller after each command for at91rm9200 and by setting the MCI_BLKR register on at91sam926*. Signed-off-by: Marc Pignat Signed-off-by: Hans J Koch Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index fce171c..e924211 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -130,6 +130,43 @@ struct at91mci_host struct timer_list timer; }; +/* + * Reset the controller and restore most of the state + */ +static void at91_reset_host(struct at91mci_host *host) +{ + unsigned long flags; + u32 mr; + u32 sdcr; + u32 dtor; + u32 imr; + + local_irq_save(flags); + imr = at91_mci_read(host, AT91_MCI_IMR); + + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); + + /* save current state */ + mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; + sdcr = at91_mci_read(host, AT91_MCI_SDCR); + dtor = at91_mci_read(host, AT91_MCI_DTOR); + + /* reset the controller */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); + + /* restore state */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); + at91_mci_write(host, AT91_MCI_MR, mr); + at91_mci_write(host, AT91_MCI_SDCR, sdcr); + at91_mci_write(host, AT91_MCI_DTOR, dtor); + at91_mci_write(host, AT91_MCI_IER, imr); + + /* make sure sdio interrupts will fire */ + at91_mci_read(host, AT91_MCI_SR); + + local_irq_restore(flags); +} + static void at91_timeout_timer(unsigned long data) { struct at91mci_host *host; @@ -148,6 +185,7 @@ static void at91_timeout_timer(unsigned long data) host->request->cmd->error = -ETIMEDOUT; } + at91_reset_host(host); mmc_request_done(host->mmc, host->request); } } @@ -512,6 +550,11 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command mr |= AT91_MCI_PDCMODE; at91_mci_write(host, AT91_MCI_MR, mr); + if (!cpu_is_at91rm9200()) + at91_mci_write(host, AT91_MCI_BLKR, + AT91_MCI_BLKR_BCNT(blocks) | + AT91_MCI_BLKR_BLKLEN(block_length)); + /* * Disable the PDC controller */ @@ -584,6 +627,11 @@ static void at91_mci_process_next(struct at91mci_host *host) at91_mci_send_command(host, host->request->stop); } else { del_timer(&host->timer); + /* the at91rm9200 mci controller hangs after some transfers, + * and the workaround is to reset it after each transfer. + */ + if (cpu_is_at91rm9200()) + at91_reset_host(host); mmc_request_done(host->mmc, host->request); } } diff --git a/include/asm-arm/arch-at91/at91_mci.h b/include/asm-arm/arch-at91/at91_mci.h index 1551fc2..400ec10 100644 --- a/include/asm-arm/arch-at91/at91_mci.h +++ b/include/asm-arm/arch-at91/at91_mci.h @@ -75,6 +75,10 @@ #define AT91_MCI_TRTYP_MULTIPLE (1 << 19) #define AT91_MCI_TRTYP_STREAM (2 << 19) +#define AT91_MCI_BLKR 0x18 /* Block Register */ +#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ +#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block lenght */ + #define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */ #define AT91_MCR_RDR 0x30 /* Receive Data Register */ #define AT91_MCR_TDR 0x34 /* Transmit Data Register */ -- cgit v0.10.2 From 4ac24a8722b97d5b4cfc48a4fbd0b2489e358d4d Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 30 May 2008 14:18:57 +0200 Subject: mmc: at91_mci: update bytes_xfered value once xfer done Modify bytes_xfered value after a write. That will report, as accurately as possible, the amount of sectors that are effectively written. This update introduces the check of the busy signal given by the card. Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e924211..b5a6e25 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -340,8 +340,6 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); - data->bytes_xfered += sg->length; - if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ unsigned int *buffer; int index; @@ -357,6 +355,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) } flush_dcache_page(sg_page(sg)); + + data->bytes_xfered += sg->length; } /* Is there another transfer to trigger? */ @@ -397,10 +397,32 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE); } else at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); +} + +/* + * Update bytes tranfered count during a write operation + */ +static void at91_mci_update_bytes_xfered(struct at91mci_host *host) +{ + struct mmc_data *data; - data->bytes_xfered = host->total_length; + /* always deal with the effective request (and not the current cmd) */ + + if (host->request->cmd && host->request->cmd->error != 0) + return; + + if (host->request->data) { + data = host->request->data; + if (data->flags & MMC_DATA_WRITE) { + /* card is in IDLE mode now */ + pr_debug("-> bytes_xfered %d, total_length = %d\n", + data->bytes_xfered, host->total_length); + data->bytes_xfered = host->total_length; + } + } } + /*Handle after command sent ready*/ static int at91_mci_handle_cmdrdy(struct at91mci_host *host) { @@ -413,8 +435,7 @@ static int at91_mci_handle_cmdrdy(struct at91mci_host *host) } else return 1; } else if (host->cmd->data->flags & MMC_DATA_WRITE) { /*After sendding multi-block-write command, start DMA transfer*/ - at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE); - at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE); at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); } @@ -817,6 +838,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (int_status & AT91_MCI_NOTBUSY) { pr_debug("Card is ready\n"); + at91_mci_update_bytes_xfered(host); completed = 1; } @@ -825,7 +847,13 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (int_status & AT91_MCI_BLKE) { pr_debug("Block transfer has ended\n"); - completed = 1; + if (host->request->data && host->request->data->blocks > 1) { + /* multi block write : complete multi write + * command and send stop */ + completed = 1; + } else { + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); + } } if (int_status & AT91_MCI_TXRDY) -- cgit v0.10.2 From 3eb99a7bff3d7459a695f45124a6bbabf31cb4b5 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 30 May 2008 14:08:56 +0200 Subject: mmc: at91_mci: add multiwrite switch at91_mci is capable of multiwrite. Enable it before it disappears. Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b5a6e25..b2bb79e 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -947,6 +947,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->caps = MMC_CAP_MULTIWRITE; mmc->max_blk_size = 4095; mmc->max_blk_count = mmc->max_req_size; -- cgit v0.10.2 From 7a6588ba20aed4505da912f9dd73616e9bd9ba67 Mon Sep 17 00:00:00 2001 From: Eric Benard Date: Fri, 30 May 2008 14:26:05 +0200 Subject: mmc: at91_mci: add sdio irq management Enable SDIO interrupt handling. Signed-off-by: Eric Benard Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index b2bb79e..9b546a9 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -665,7 +665,7 @@ static void at91_mci_completed_command(struct at91mci_host *host) struct mmc_command *cmd = host->cmd; unsigned int status; - at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0)); cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1)); @@ -856,6 +856,12 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) } } + if (int_status & AT91_MCI_SDIOIRQA) + mmc_signal_sdio_irq(host->mmc); + + if (int_status & AT91_MCI_SDIOIRQB) + mmc_signal_sdio_irq(host->mmc); + if (int_status & AT91_MCI_TXRDY) pr_debug("Ready to transmit\n"); @@ -870,10 +876,10 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (completed) { pr_debug("Completed command\n"); - at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); at91_mci_completed_command(host); } else - at91_mci_write(host, AT91_MCI_IDR, int_status); + at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); return IRQ_HANDLED; } @@ -913,10 +919,22 @@ static int at91_mci_get_ro(struct mmc_host *mmc) return -ENOSYS; } +static void at91_mci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct at91mci_host *host = mmc_priv(mmc); + + pr_debug("%s: sdio_irq %c : %s\n", mmc_hostname(host->mmc), + host->board->slot_b ? 'B':'A', enable ? "enable" : "disable"); + at91_mci_write(host, enable ? AT91_MCI_IER : AT91_MCI_IDR, + host->board->slot_b ? AT91_MCI_SDIOIRQB : AT91_MCI_SDIOIRQA); + +} + static const struct mmc_host_ops at91_mci_ops = { .request = at91_mci_request, .set_ios = at91_mci_set_ios, .get_ro = at91_mci_get_ro, + .enable_sdio_irq = at91_mci_enable_sdio_irq, }; /* @@ -947,7 +965,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = MMC_CAP_MULTIWRITE; + mmc->caps = MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ; mmc->max_blk_size = 4095; mmc->max_blk_count = mmc->max_req_size; -- cgit v0.10.2 From ba7deeed96ca1855c153ad81c45baf6efe1a3362 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 30 May 2008 14:28:45 +0200 Subject: mmc: at91_mci: do not read irq status twice as it will forget some errors Reading AT91_MCI_SR again at the end of transfer can corrupt the error reporting. Some fields in the SR register are read-and-clear. Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 9b546a9..e1f91a4 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -660,10 +660,9 @@ static void at91_mci_process_next(struct at91mci_host *host) /* * Handle a command that has been completed */ -static void at91_mci_completed_command(struct at91mci_host *host) +static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status) { struct mmc_command *cmd = host->cmd; - unsigned int status; at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); @@ -677,10 +676,9 @@ static void at91_mci_completed_command(struct at91mci_host *host) host->buffer = NULL; } - status = at91_mci_read(host, AT91_MCI_SR); - - pr_debug("Status = %08X [%08X %08X %08X %08X]\n", - status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", + status, at91_mci_read(host, AT91_MCI_SR), + cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); if (status & AT91_MCI_ERRORS) { if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) { @@ -877,7 +875,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (completed) { pr_debug("Completed command\n"); at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); - at91_mci_completed_command(host); + at91_mci_completed_command(host, int_status); } else at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); -- cgit v0.10.2 From fa1fe010c126ee69f2f75e3a4efc2f6252281ff8 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 10 Jun 2008 11:27:29 +0200 Subject: at91_mci: manage cmd error and data error independently In at91_mci_completed_command() function, this patch distinguishes command error and data error. It reports it in the corresponding error field. Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e1f91a4..e4d018b 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -663,6 +663,7 @@ static void at91_mci_process_next(struct at91mci_host *host) static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status) { struct mmc_command *cmd = host->cmd; + struct mmc_data *data = cmd->data; at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); @@ -685,15 +686,25 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s cmd->error = 0; } else { - if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE)) - cmd->error = -ETIMEDOUT; - else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE)) - cmd->error = -EILSEQ; - else - cmd->error = -EIO; + if (status & (AT91_MCI_DTOE | AT91_MCI_DCRCE)) { + if (data) { + if (status & AT91_MCI_DTOE) + data->error = -ETIMEDOUT; + else if (status & AT91_MCI_DCRCE) + data->error = -EILSEQ; + } + } else { + if (status & AT91_MCI_RTOE) + cmd->error = -ETIMEDOUT; + else if (status & AT91_MCI_RCRCE) + cmd->error = -EILSEQ; + else + cmd->error = -EIO; + } - pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n", - cmd->error, cmd->opcode, cmd->retries); + pr_debug("Error detected and set to %d/%d (cmd = %d, retries = %d)\n", + cmd->error, data ? data->error : 0, + cmd->opcode, cmd->retries); } } else -- cgit v0.10.2 From 5385edc50063a2175383ef5e90aa67fb6ab1beae Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Sat, 14 Jun 2008 20:27:20 +0300 Subject: at91_mci: AT91SAM9260/9263 12 byte write erratum (v2) AT91SAM926[0/3] PDC must write at least 12 bytes. The code compiles and runs but the actual condition for this erratum did not trigger in my tests so it's unclear if it actually works as intended. Signed-off-by: Ville Syrjala Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index e4d018b..d3e96ff 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -198,9 +198,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data unsigned int len, i, size; unsigned *dmabuf = host->buffer; - size = host->total_length; + size = data->blksz * data->blocks; len = data->sg_len; + /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */ + if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) + if (host->total_length == 12) + memset(dmabuf, 0, 12); + /* * Just loop through all entries. Size might not * be the entire list though so make sure that @@ -222,9 +227,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data for (index = 0; index < (amount / 4); index++) *dmabuf++ = swab32(sgbuffer[index]); - } - else + } else { memcpy(dmabuf, sgbuffer, amount); + dmabuf += amount; + } kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); @@ -417,7 +423,7 @@ static void at91_mci_update_bytes_xfered(struct at91mci_host *host) /* card is in IDLE mode now */ pr_debug("-> bytes_xfered %d, total_length = %d\n", data->bytes_xfered, host->total_length); - data->bytes_xfered = host->total_length; + data->bytes_xfered = data->blksz * data->blocks; } } } @@ -600,6 +606,13 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command * Handle a write */ host->total_length = block_length * blocks; + /* + * AT91SAM926[0/3] Data Write Operation and + * number of bytes erratum + */ + if (cpu_is_at91sam9260 () || cpu_is_at91sam9263()) + if (host->total_length < 12) + host->total_length = 12; host->buffer = dma_alloc_coherent(NULL, host->total_length, &host->physical_address, GFP_KERNEL); -- cgit v0.10.2 From 9da3cbaf2881df97e502593c49c93f55eb696091 Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Mon, 9 Jun 2008 22:06:44 +0300 Subject: at91_mci: Cover more AT91RM9200 and AT91SAM9261 errata. According to the documentation the AT91SAM9261 MCI shares the block size limitations of the AT91RM9200 MCI. Also the errata documentation for AT91RM9200 and AT91SAM9261 state that stream commands are not supported. This has not been tested on actual hardware. Signed-off-by: Ville Syrjala Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index d3e96ff..f8c3f7c 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -520,11 +520,19 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command if (data) { - if ( cpu_is_at91rm9200() && (data->blksz & 0x3) ) { - pr_debug("Unsupported block size\n"); - cmd->error = -EINVAL; - mmc_request_done(host->mmc, host->request); - return; + if (cpu_is_at91rm9200() || cpu_is_at91sam9261()) { + if (data->blksz & 0x3) { + pr_debug("Unsupported block size\n"); + cmd->error = -EINVAL; + mmc_request_done(host->mmc, host->request); + return; + } + if (data->flags & MMC_DATA_STREAM) { + pr_debug("Stream commands not supported\n"); + cmd->error = -EINVAL; + mmc_request_done(host->mmc, host->request); + return; + } } block_length = data->blksz; @@ -577,7 +585,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command mr |= AT91_MCI_PDCMODE; at91_mci_write(host, AT91_MCI_MR, mr); - if (!cpu_is_at91rm9200()) + if (!(cpu_is_at91rm9200() || cpu_is_at91sam9261())) at91_mci_write(host, AT91_MCI_BLKR, AT91_MCI_BLKR_BCNT(blocks) | AT91_MCI_BLKR_BLKLEN(block_length)); -- cgit v0.10.2 From 12bd257532708a4d5be4b8548ff121a45ff88f5d Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Mon, 9 Jun 2008 22:06:45 +0300 Subject: at91_mci: Fix byte mode transitions. The byte mode support fails to clear the byte mode bit in the command register, possibly leaving byte mode enabled with the counters programmed in non-byte mode. Signed-off-by: Ville Syrjala Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index f8c3f7c..16df235 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -579,7 +579,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command ier = AT91_MCI_CMDRDY; } else { /* zero block length and PDC mode */ - mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; + mr = at91_mci_read(host, AT91_MCI_MR) & 0x5fff; mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0; mr |= (block_length << 16); mr |= AT91_MCI_PDCMODE; -- cgit v0.10.2 From c4223c2c91fa9e5addd6eadd804e57a925ac5e5e Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:36:13 +0200 Subject: au1xmmc: remove db1200 board code, rewrite probe. Remove the DB1200 board-specific functions (card present, read-only, activity LED methods) and instead add platform data which is passed to the driver. This also allows for platforms to implement other carddetect schemes (e.g. dedicated irq) without having to pollute the driver code. The poll timer (used for pb1200) is kept for compatibility. With the board-specific stuff gone, the driver's ->probe() code can be cleaned up considerably. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index cc5f7bc..d8776d6 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -41,8 +41,9 @@ #include #include #include - +#include #include + #include #include #include @@ -54,6 +55,7 @@ #define DRIVER_NAME "au1xxx-mmc" /* Set this to enable special debugging macros */ +/* #define DEBUG */ #ifdef DEBUG #define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) @@ -61,32 +63,6 @@ #define DBG(fmt, idx, args...) #endif -const struct { - u32 iobase; - u32 tx_devid, rx_devid; - u16 bcsrpwr; - u16 bcsrstatus; - u16 wpstatus; -} au1xmmc_card_table[] = { - { SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0, - BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP }, -#ifndef CONFIG_MIPS_DB1200 - { SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1, - BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP } -#endif -}; - -#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table)) - -/* This array stores pointers for the hosts (used by the IRQ handler) */ -struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT]; -static int dma = 1; - -#ifdef MODULE -module_param(dma, bool, 0); -MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)"); -#endif - static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) { u32 val = au_readl(HOST_CONFIG(host)); @@ -135,26 +111,33 @@ static inline void SEND_STOP(struct au1xmmc_host *host) static void au1xmmc_set_power(struct au1xmmc_host *host, int state) { - - u32 val = au1xmmc_card_table[host->id].bcsrpwr; - - bcsr->board &= ~val; - if (state) bcsr->board |= val; - - au_sync_delay(1); + if (host->platdata && host->platdata->set_power) + host->platdata->set_power(host->mmc, state); } -static inline int au1xmmc_card_inserted(struct au1xmmc_host *host) +static int au1xmmc_card_inserted(struct au1xmmc_host *host) { - return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus) - ? 1 : 0; + int ret; + + if (host->platdata && host->platdata->card_inserted) + ret = host->platdata->card_inserted(host->mmc); + else + ret = 1; /* assume there is a card */ + + return ret; } static int au1xmmc_card_readonly(struct mmc_host *mmc) { struct au1xmmc_host *host = mmc_priv(mmc); - return (bcsr->status & au1xmmc_card_table[host->id].wpstatus) - ? 1 : 0; + int ret; + + if (host->platdata && host->platdata->card_readonly) + ret = host->platdata->card_readonly(mmc); + else + ret = 0; /* assume card is read-write */ + + return ret; } static void au1xmmc_finish_request(struct au1xmmc_host *host) @@ -163,7 +146,7 @@ static void au1xmmc_finish_request(struct au1xmmc_host *host) struct mmc_request *mrq = host->mrq; host->mrq = NULL; - host->flags &= HOST_F_ACTIVE; + host->flags &= HOST_F_ACTIVE | HOST_F_DMA; host->dma.len = 0; host->dma.dir = 0; @@ -174,8 +157,6 @@ static void au1xmmc_finish_request(struct au1xmmc_host *host) host->status = HOST_S_IDLE; - bcsr->disk_leds |= (1 << 8); - mmc_request_done(host->mmc, mrq); } @@ -299,11 +280,13 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) if (!data->error) { if (host->flags & HOST_F_DMA) { +#ifdef CONFIG_SOC_AU1200 /* DBDMA */ u32 chan = DMA_CHANNEL(host); chan_tab_t *c = *((chan_tab_t **) chan); au1x_dma_chan_t *cp = c->chan_ptr; data->bytes_xfered = cp->ddma_bytecnt; +#endif } else data->bytes_xfered = @@ -420,18 +403,18 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) break; if (status & SD_STATUS_RC) { - DBG("RX CRC Error [%d + %d].\n", host->id, + DBG("RX CRC Error [%d + %d].\n", host->pdev->id, host->pio.len, count); break; } if (status & SD_STATUS_RO) { - DBG("RX Overrun [%d + %d]\n", host->id, + DBG("RX Overrun [%d + %d]\n", host->pdev->id, host->pio.len, count); break; } else if (status & SD_STATUS_RU) { - DBG("RX Underrun [%d + %d]\n", host->id, + DBG("RX Underrun [%d + %d]\n", host->pdev->id, host->pio.len, count); break; } @@ -528,6 +511,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) host->status = HOST_S_DATA; if (host->flags & HOST_F_DMA) { +#ifdef CONFIG_SOC_AU1200 /* DBDMA */ u32 channel = DMA_CHANNEL(host); /* Start the DMA as soon as the buffer gets something in it */ @@ -540,6 +524,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) } au1xxx_dbdma_start(channel); +#endif } } @@ -571,12 +556,8 @@ static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) static int au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) { - int datalen = data->blocks * data->blksz; - if (dma != 0) - host->flags |= HOST_F_DMA; - if (data->flags & MMC_DATA_READ) host->flags |= HOST_F_RECV; else @@ -596,6 +577,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) au_writel(data->blksz - 1, HOST_BLKSIZE(host)); if (host->flags & HOST_F_DMA) { +#ifdef CONFIG_SOC_AU1200 /* DBDMA */ int i; u32 channel = DMA_CHANNEL(host); @@ -621,11 +603,12 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) len, flags); } - if (!ret) + if (!ret) goto dataerr; datalen -= len; } +#endif } else { host->pio.index = 0; @@ -641,8 +624,9 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) return 0; - dataerr: - dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir); +dataerr: + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma.dir); return -ETIMEDOUT; } @@ -663,8 +647,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) host->mrq = mrq; host->status = HOST_S_CMD; - bcsr->disk_leds &= ~(1 << 8); - if (mrq->data) { FLUSH_FIFO(host); flags = mrq->data->flags; @@ -728,149 +710,145 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) } } -static void au1xmmc_dma_callback(int irq, void *dev_id) -{ - struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id; - - /* Avoid spurious interrupts */ - - if (!host->mrq) - return; - - if (host->flags & HOST_F_STOP) - SEND_STOP(host); - - tasklet_schedule(&host->data_task); -} - #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) #define STATUS_DATA_IN (SD_STATUS_NE) #define STATUS_DATA_OUT (SD_STATUS_TH) static irqreturn_t au1xmmc_irq(int irq, void *dev_id) { - + struct au1xmmc_host *host = dev_id; u32 status; - int i, ret = 0; - - disable_irq(AU1100_SD_IRQ); - for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { - struct au1xmmc_host * host = au1xmmc_hosts[i]; - u32 handled = 1; - - status = au_readl(HOST_STATUS(host)); + status = au_readl(HOST_STATUS(host)); - if (host->mrq && (status & STATUS_TIMEOUT)) { - if (status & SD_STATUS_RAT) - host->mrq->cmd->error = -ETIMEDOUT; + if (!(status & SD_STATUS_I)) + return IRQ_NONE; /* not ours */ - else if (status & SD_STATUS_DT) - host->mrq->data->error = -ETIMEDOUT; + if (host->mrq && (status & STATUS_TIMEOUT)) { + if (status & SD_STATUS_RAT) + host->mrq->cmd->error = -ETIMEDOUT; + else if (status & SD_STATUS_DT) + host->mrq->data->error = -ETIMEDOUT; - /* In PIO mode, interrupts might still be enabled */ - IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH); + /* In PIO mode, interrupts might still be enabled */ + IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH); - //IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF); - tasklet_schedule(&host->finish_task); - } + /* IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA | SD_CONFIG_RF); */ + tasklet_schedule(&host->finish_task); + } #if 0 - else if (status & SD_STATUS_DD) { - - /* Sometimes we get a DD before a NE in PIO mode */ - - if (!(host->flags & HOST_F_DMA) && - (status & SD_STATUS_NE)) - au1xmmc_receive_pio(host); - else { - au1xmmc_data_complete(host, status); - //tasklet_schedule(&host->data_task); - } - } -#endif - else if (status & (SD_STATUS_CR)) { - if (host->status == HOST_S_CMD) - au1xmmc_cmd_complete(host,status); - } - else if (!(host->flags & HOST_F_DMA)) { - if ((host->flags & HOST_F_XMIT) && - (status & STATUS_DATA_OUT)) - au1xmmc_send_pio(host); - else if ((host->flags & HOST_F_RECV) && - (status & STATUS_DATA_IN)) - au1xmmc_receive_pio(host); - } - else if (status & 0x203FBC70) { - DBG("Unhandled status %8.8x\n", host->id, status); - handled = 0; + else if (status & SD_STATUS_DD) { + /* Sometimes we get a DD before a NE in PIO mode */ + if (!(host->flags & HOST_F_DMA) && (status & SD_STATUS_NE)) + au1xmmc_receive_pio(host); + else { + au1xmmc_data_complete(host, status); + /* tasklet_schedule(&host->data_task); */ } - - au_writel(status, HOST_STATUS(host)); - au_sync(); - - ret |= handled; } - - enable_irq(AU1100_SD_IRQ); - return ret; -} - -static void au1xmmc_poll_event(unsigned long arg) -{ - struct au1xmmc_host *host = (struct au1xmmc_host *) arg; - - int card = au1xmmc_card_inserted(host); - int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0; - - if (card != controller) { - host->flags &= ~HOST_F_ACTIVE; - if (card) host->flags |= HOST_F_ACTIVE; - mmc_detect_change(host->mmc, 0); +#endif + else if (status & SD_STATUS_CR) { + if (host->status == HOST_S_CMD) + au1xmmc_cmd_complete(host, status); + + } else if (!(host->flags & HOST_F_DMA)) { + if ((host->flags & HOST_F_XMIT) && (status & STATUS_DATA_OUT)) + au1xmmc_send_pio(host); + else if ((host->flags & HOST_F_RECV) && (status & STATUS_DATA_IN)) + au1xmmc_receive_pio(host); + + } else if (status & 0x203F3C70) { + DBG("Unhandled status %8.8x\n", host->pdev->id, + status); } - if (host->mrq != NULL) { - u32 status = au_readl(HOST_STATUS(host)); - DBG("PENDING - %8.8x\n", host->id, status); - } + au_writel(status, HOST_STATUS(host)); + au_sync(); - mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); + return IRQ_HANDLED; } -static dbdev_tab_t au1xmmc_mem_dbdev = -{ - DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0 +#ifdef CONFIG_SOC_AU1200 +/* 8bit memory DMA device */ +static dbdev_tab_t au1xmmc_mem_dbdev = { + .dev_id = DSCR_CMD0_ALWAYS, + .dev_flags = DEV_FLAGS_ANYUSE, + .dev_tsize = 0, + .dev_devwidth = 8, + .dev_physaddr = 0x00000000, + .dev_intlevel = 0, + .dev_intpolarity = 0, }; +static int memid; -static void au1xmmc_init_dma(struct au1xmmc_host *host) +static void au1xmmc_dbdma_callback(int irq, void *dev_id) { + struct au1xmmc_host *host = (struct au1xmmc_host *)dev_id; - u32 rxchan, txchan; + /* Avoid spurious interrupts */ + if (!host->mrq) + return; - int txid = au1xmmc_card_table[host->id].tx_devid; - int rxid = au1xmmc_card_table[host->id].rx_devid; + if (host->flags & HOST_F_STOP) + SEND_STOP(host); - /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride - of 8 bits. And since devices are shared, we need to create - our own to avoid freaking out other devices - */ + tasklet_schedule(&host->data_task); +} - int memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev); +static int au1xmmc_dbdma_init(struct au1xmmc_host *host) +{ + struct resource *res; + int txid, rxid; + + res = platform_get_resource(host->pdev, IORESOURCE_DMA, 0); + if (!res) + return -ENODEV; + txid = res->start; + + res = platform_get_resource(host->pdev, IORESOURCE_DMA, 1); + if (!res) + return -ENODEV; + rxid = res->start; + + if (!memid) + return -ENODEV; + + host->tx_chan = au1xxx_dbdma_chan_alloc(memid, txid, + au1xmmc_dbdma_callback, (void *)host); + if (!host->tx_chan) { + dev_err(&host->pdev->dev, "cannot allocate TX DMA\n"); + return -ENODEV; + } + + host->rx_chan = au1xxx_dbdma_chan_alloc(rxid, memid, + au1xmmc_dbdma_callback, (void *)host); + if (!host->rx_chan) { + dev_err(&host->pdev->dev, "cannot allocate RX DMA\n"); + au1xxx_dbdma_chan_free(host->tx_chan); + return -ENODEV; + } - txchan = au1xxx_dbdma_chan_alloc(memid, txid, - au1xmmc_dma_callback, (void *) host); + au1xxx_dbdma_set_devwidth(host->tx_chan, 8); + au1xxx_dbdma_set_devwidth(host->rx_chan, 8); - rxchan = au1xxx_dbdma_chan_alloc(rxid, memid, - au1xmmc_dma_callback, (void *) host); + au1xxx_dbdma_ring_alloc(host->tx_chan, AU1XMMC_DESCRIPTOR_COUNT); + au1xxx_dbdma_ring_alloc(host->rx_chan, AU1XMMC_DESCRIPTOR_COUNT); - au1xxx_dbdma_set_devwidth(txchan, 8); - au1xxx_dbdma_set_devwidth(rxchan, 8); + /* DBDMA is good to go */ + host->flags |= HOST_F_DMA; - au1xxx_dbdma_ring_alloc(txchan, AU1XMMC_DESCRIPTOR_COUNT); - au1xxx_dbdma_ring_alloc(rxchan, AU1XMMC_DESCRIPTOR_COUNT); + return 0; +} - host->tx_chan = txchan; - host->rx_chan = rxchan; +static void au1xmmc_dbdma_shutdown(struct au1xmmc_host *host) +{ + if (host->flags & HOST_F_DMA) { + host->flags &= ~HOST_F_DMA; + au1xxx_dbdma_chan_free(host->tx_chan); + au1xxx_dbdma_chan_free(host->rx_chan); + } } +#endif static const struct mmc_host_ops au1xmmc_ops = { .request = au1xmmc_request, @@ -878,116 +856,235 @@ static const struct mmc_host_ops au1xmmc_ops = { .get_ro = au1xmmc_card_readonly, }; -static int __devinit au1xmmc_probe(struct platform_device *pdev) +static void au1xmmc_poll_event(unsigned long arg) { + struct au1xmmc_host *host = (struct au1xmmc_host *)arg; + int card = au1xmmc_card_inserted(host); + int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0; + + if (card != controller) { + host->flags &= ~HOST_F_ACTIVE; + if (card) + host->flags |= HOST_F_ACTIVE; + mmc_detect_change(host->mmc, 0); + } - int i, ret = 0; +#ifdef DEBUG + if (host->mrq != NULL) { + u32 status = au_readl(HOST_STATUS(host)); + DBG("PENDING - %8.8x\n", host->pdev->id, status); + } +#endif + mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); +} - /* THe interrupt is shared among all controllers */ - ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, IRQF_DISABLED, "MMC", 0); +static void au1xmmc_init_cd_poll_timer(struct au1xmmc_host *host) +{ + init_timer(&host->timer); + host->timer.function = au1xmmc_poll_event; + host->timer.data = (unsigned long)host; + host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT; +} - if (ret) { - printk(DRIVER_NAME "ERROR: Couldn't get int %d: %d\n", - AU1100_SD_IRQ, ret); - return -ENXIO; +static int __devinit au1xmmc_probe(struct platform_device *pdev) +{ + struct mmc_host *mmc; + struct au1xmmc_host *host; + struct resource *r; + int ret; + + mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); + if (!mmc) { + dev_err(&pdev->dev, "no memory for mmc_host\n"); + ret = -ENOMEM; + goto out0; } - disable_irq(AU1100_SD_IRQ); + host = mmc_priv(mmc); + host->mmc = mmc; + host->platdata = pdev->dev.platform_data; + host->pdev = pdev; - for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { - struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); - struct au1xmmc_host *host = 0; + ret = -ENODEV; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no mmio defined\n"); + goto out1; + } - if (!mmc) { - printk(DRIVER_NAME "ERROR: no mem for host %d\n", i); - au1xmmc_hosts[i] = 0; - continue; - } + host->ioarea = request_mem_region(r->start, r->end - r->start + 1, + pdev->name); + if (!host->ioarea) { + dev_err(&pdev->dev, "mmio already in use\n"); + goto out1; + } - mmc->ops = &au1xmmc_ops; + host->iobase = (unsigned long)ioremap(r->start, 0x3c); + if (!host->iobase) { + dev_err(&pdev->dev, "cannot remap mmio\n"); + goto out2; + } + + r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!r) { + dev_err(&pdev->dev, "no IRQ defined\n"); + goto out3; + } - mmc->f_min = 450000; - mmc->f_max = 24000000; + host->irq = r->start; + /* IRQ is shared among both SD controllers */ + ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED, + DRIVER_NAME, host); + if (ret) { + dev_err(&pdev->dev, "cannot grab IRQ\n"); + goto out3; + } - mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE; - mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT; + mmc->ops = &au1xmmc_ops; - mmc->max_blk_size = 2048; - mmc->max_blk_count = 512; + mmc->f_min = 450000; + mmc->f_max = 24000000; - mmc->ocr_avail = AU1XMMC_OCR; + mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE; + mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT; - host = mmc_priv(mmc); - host->mmc = mmc; + mmc->max_blk_size = 2048; + mmc->max_blk_count = 512; - host->id = i; - host->iobase = au1xmmc_card_table[host->id].iobase; - host->clock = 0; - host->power_mode = MMC_POWER_OFF; + mmc->ocr_avail = AU1XMMC_OCR; + mmc->caps = 0; - host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0; - host->status = HOST_S_IDLE; + host->status = HOST_S_IDLE; - init_timer(&host->timer); + /* board-specific carddetect setup, if any */ + if (host->platdata && host->platdata->cd_setup) { + ret = host->platdata->cd_setup(mmc, 1); + if (ret) { + dev_err(&pdev->dev, "board CD setup failed\n"); + goto out4; + } + } else { + /* poll the board-specific is-card-in-socket-? method */ + au1xmmc_init_cd_poll_timer(host); + } - host->timer.function = au1xmmc_poll_event; - host->timer.data = (unsigned long) host; - host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT; + tasklet_init(&host->data_task, au1xmmc_tasklet_data, + (unsigned long)host); - tasklet_init(&host->data_task, au1xmmc_tasklet_data, - (unsigned long) host); + tasklet_init(&host->finish_task, au1xmmc_tasklet_finish, + (unsigned long)host); - tasklet_init(&host->finish_task, au1xmmc_tasklet_finish, - (unsigned long) host); +#ifdef CONFIG_SOC_AU1200 + ret = au1xmmc_dbdma_init(host); + if (ret) + printk(KERN_INFO DRIVER_NAME ": DBDMA init failed; using PIO\n"); +#endif - spin_lock_init(&host->lock); +#ifdef CONFIG_LEDS_CLASS + if (host->platdata && host->platdata->led) { + struct led_classdev *led = host->platdata->led; + led->name = mmc_hostname(mmc); + led->brightness = LED_OFF; + led->default_trigger = mmc_hostname(mmc); + ret = led_classdev_register(mmc_dev(mmc), led); + if (ret) + goto out5; + } +#endif - if (dma != 0) - au1xmmc_init_dma(host); + au1xmmc_reset_controller(host); - au1xmmc_reset_controller(host); + ret = mmc_add_host(mmc); + if (ret) { + dev_err(&pdev->dev, "cannot add mmc host\n"); + goto out6; + } - mmc_add_host(mmc); - au1xmmc_hosts[i] = host; + platform_set_drvdata(pdev, mmc); + /* start the carddetect poll timer if necessary */ + if (!(host->platdata && host->platdata->cd_setup)) add_timer(&host->timer); - printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n", - host->id, host->iobase, dma ? "dma" : "pio"); - } + printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X" + " (mode=%s)\n", pdev->id, host->iobase, + host->flags & HOST_F_DMA ? "dma" : "pio"); - enable_irq(AU1100_SD_IRQ); + return 0; /* all ok */ - return 0; +out6: +#ifdef CONFIG_LEDS_CLASS + if (host->platdata && host->platdata->led) + led_classdev_unregister(host->platdata->led); +out5: +#endif + au_writel(0, HOST_ENABLE(host)); + au_writel(0, HOST_CONFIG(host)); + au_writel(0, HOST_CONFIG2(host)); + au_sync(); + +#ifdef CONFIG_SOC_AU1200 + au1xmmc_dbdma_shutdown(host); +#endif + + tasklet_kill(&host->data_task); + tasklet_kill(&host->finish_task); + + if (host->platdata && host->platdata->cd_setup) + host->platdata->cd_setup(mmc, 0); +out4: + free_irq(host->irq, host); +out3: + iounmap((void *)host->iobase); +out2: + release_resource(host->ioarea); + kfree(host->ioarea); +out1: + mmc_free_host(mmc); +out0: + return ret; } static int __devexit au1xmmc_remove(struct platform_device *pdev) { + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct au1xmmc_host *host; + + if (mmc) { + host = mmc_priv(mmc); + + mmc_remove_host(mmc); - int i; +#ifdef CONFIG_LEDS_CLASS + if (host->platdata && host->platdata->led) + led_classdev_unregister(host->platdata->led); +#endif - disable_irq(AU1100_SD_IRQ); + if (host->platdata && host->platdata->cd_setup) + host->platdata->cd_setup(mmc, 0); + else + del_timer_sync(&host->timer); - for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { - struct au1xmmc_host *host = au1xmmc_hosts[i]; - if (!host) continue; + au_writel(0, HOST_ENABLE(host)); + au_writel(0, HOST_CONFIG(host)); + au_writel(0, HOST_CONFIG2(host)); + au_sync(); tasklet_kill(&host->data_task); tasklet_kill(&host->finish_task); - del_timer_sync(&host->timer); +#ifdef CONFIG_SOC_AU1200 + au1xmmc_dbdma_shutdown(host); +#endif au1xmmc_set_power(host, 0); - mmc_remove_host(host->mmc); + free_irq(host->irq, host); + iounmap((void *)host->iobase); + release_resource(host->ioarea); + kfree(host->ioarea); - au1xxx_dbdma_chan_free(host->tx_chan); - au1xxx_dbdma_chan_free(host->rx_chan); - - au_writel(0x0, HOST_ENABLE(host)); - au_sync(); + mmc_free_host(mmc); } - - free_irq(AU1100_SD_IRQ, 0); return 0; } @@ -1004,21 +1101,31 @@ static struct platform_driver au1xmmc_driver = { static int __init au1xmmc_init(void) { +#ifdef CONFIG_SOC_AU1200 + /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride + * of 8 bits. And since devices are shared, we need to create + * our own to avoid freaking out other devices. + */ + memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev); + if (!memid) + printk(KERN_ERR "au1xmmc: cannot add memory dbdma dev\n"); +#endif return platform_driver_register(&au1xmmc_driver); } static void __exit au1xmmc_exit(void) { +#ifdef CONFIG_SOC_AU1200 + if (memid) + au1xxx_ddma_del_device(memid); +#endif platform_driver_unregister(&au1xmmc_driver); } module_init(au1xmmc_init); module_exit(au1xmmc_exit); -#ifdef MODULE MODULE_AUTHOR("Advanced Micro Devices, Inc"); MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:au1xxx-mmc"); -#endif - diff --git a/drivers/mmc/host/au1xmmc.h b/drivers/mmc/host/au1xmmc.h index 341cbdf..3b40065 100644 --- a/drivers/mmc/host/au1xmmc.h +++ b/drivers/mmc/host/au1xmmc.h @@ -49,8 +49,6 @@ struct au1xmmc_host { struct mmc_host *mmc; struct mmc_request *mrq; - u32 id; - u32 flags; u32 iobase; u32 clock; @@ -73,11 +71,14 @@ struct au1xmmc_host { u32 tx_chan; u32 rx_chan; + int irq; + struct timer_list timer; struct tasklet_struct finish_task; struct tasklet_struct data_task; - - spinlock_t lock; + struct au1xmmc_platform_data *platdata; + struct platform_device *pdev; + struct resource *ioarea; }; /* Status flags used by the host structure */ diff --git a/include/asm-mips/mach-au1x00/au1100_mmc.h b/include/asm-mips/mach-au1x00/au1100_mmc.h index 9e0028f..c35e209 100644 --- a/include/asm-mips/mach-au1x00/au1100_mmc.h +++ b/include/asm-mips/mach-au1x00/au1100_mmc.h @@ -38,15 +38,15 @@ #ifndef __ASM_AU1100_MMC_H #define __ASM_AU1100_MMC_H - -#define NUM_AU1100_MMC_CONTROLLERS 2 - -#if defined(CONFIG_SOC_AU1100) -#define AU1100_SD_IRQ AU1100_SD_INT -#elif defined(CONFIG_SOC_AU1200) -#define AU1100_SD_IRQ AU1200_SD_INT -#endif - +#include + +struct au1xmmc_platform_data { + int(*cd_setup)(void *mmc_host, int on); + int(*card_inserted)(void *mmc_host); + int(*card_readonly)(void *mmc_host); + void(*set_power)(void *mmc_host, int state); + struct led_classdev *led; +}; #define SD0_BASE 0xB0600000 #define SD1_BASE 0xB0680000 -- cgit v0.10.2 From 281dd23ea03e9893c02d237d9e35a7d20d412452 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:37:33 +0200 Subject: au1xmmc: enable 4 bit transfer mode Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index d8776d6..2bd4cf4 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -95,14 +95,13 @@ static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask) static inline void SEND_STOP(struct au1xmmc_host *host) { - - /* We know the value of CONFIG2, so avoid a read we don't need */ - u32 mask = SD_CONFIG2_EN; + u32 config2; WARN_ON(host->status != HOST_S_DATA); host->status = HOST_S_STOP; - au_writel(mask | SD_CONFIG2_DF, HOST_CONFIG2(host)); + config2 = au_readl(HOST_CONFIG2(host)); + au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); au_sync(); /* Send the stop commmand */ @@ -697,6 +696,7 @@ static void au1xmmc_reset_controller(struct au1xmmc_host *host) static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) { struct au1xmmc_host *host = mmc_priv(mmc); + u32 config2; if (ios->power_mode == MMC_POWER_OFF) au1xmmc_set_power(host, 0); @@ -708,6 +708,18 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) au1xmmc_set_clock(host, ios->clock); host->clock = ios->clock; } + + config2 = au_readl(HOST_CONFIG2(host)); + switch (ios->bus_width) { + case MMC_BUS_WIDTH_4: + config2 |= SD_CONFIG2_WB; + break; + case MMC_BUS_WIDTH_1: + config2 &= ~SD_CONFIG2_WB; + break; + } + au_writel(config2, HOST_CONFIG2(host)); + au_sync(); } #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) @@ -952,7 +964,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) mmc->max_blk_count = 512; mmc->ocr_avail = AU1XMMC_OCR; - mmc->caps = 0; + mmc->caps = MMC_CAP_4_BIT_DATA; host->status = HOST_S_IDLE; -- cgit v0.10.2 From 20f522ff5583a818922b3f650f6f7ef0e3e1aa68 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:38:03 +0200 Subject: au1xmmc: SDIO IRQ support. Wire up the SD controllers' SDIO IRQ capability. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 2bd4cf4..16b5640 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -736,6 +736,9 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) if (!(status & SD_STATUS_I)) return IRQ_NONE; /* not ours */ + if (status & SD_STATUS_SI) /* SDIO */ + mmc_signal_sdio_irq(host->mmc); + if (host->mrq && (status & STATUS_TIMEOUT)) { if (status & SD_STATUS_RAT) host->mrq->cmd->error = -ETIMEDOUT; @@ -862,10 +865,21 @@ static void au1xmmc_dbdma_shutdown(struct au1xmmc_host *host) } #endif +static void au1xmmc_enable_sdio_irq(struct mmc_host *mmc, int en) +{ + struct au1xmmc_host *host = mmc_priv(mmc); + + if (en) + IRQ_ON(host, SD_CONFIG_SI); + else + IRQ_OFF(host, SD_CONFIG_SI); +} + static const struct mmc_host_ops au1xmmc_ops = { .request = au1xmmc_request, .set_ios = au1xmmc_set_ios, .get_ro = au1xmmc_card_readonly, + .enable_sdio_irq = au1xmmc_enable_sdio_irq, }; static void au1xmmc_poll_event(unsigned long arg) @@ -964,7 +978,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) mmc->max_blk_count = 512; mmc->ocr_avail = AU1XMMC_OCR; - mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; host->status = HOST_S_IDLE; -- cgit v0.10.2 From 5c0a889df56c9f6c5a68ec7aa222082569b35fd9 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:38:35 +0200 Subject: au1xmmc: codingstyle tidying. Clean up the codebase, no functional changes. - merge the au1xmmc.h header contents into the driver file, - indentation, spelling and style fixes. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 16b5640..fcbaf40 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -49,20 +49,104 @@ #include #include -#include -#include "au1xmmc.h" - #define DRIVER_NAME "au1xxx-mmc" /* Set this to enable special debugging macros */ /* #define DEBUG */ #ifdef DEBUG -#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) +#define DBG(fmt, idx, args...) \ + printk(KERN_DEBUG "au1xmmc(%d): DEBUG: " fmt, idx, ##args) #else -#define DBG(fmt, idx, args...) +#define DBG(fmt, idx, args...) do {} while (0) #endif +/* Hardware definitions */ +#define AU1XMMC_DESCRIPTOR_COUNT 1 +#define AU1XMMC_DESCRIPTOR_SIZE 2048 + +#define AU1XMMC_OCR (MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \ + MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \ + MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36) + +/* This gives us a hard value for the stop command that we can write directly + * to the command register. + */ +#define STOP_CMD \ + (SD_CMD_RT_1B | SD_CMD_CT_7 | (0xC << SD_CMD_CI_SHIFT) | SD_CMD_GO) + +/* This is the set of interrupts that we configure by default. */ +#define AU1XMMC_INTERRUPTS \ + (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_RAT | \ + SD_CONFIG_CR | SD_CONFIG_I) + +/* The poll event (looking for insert/remove events runs twice a second. */ +#define AU1XMMC_DETECT_TIMEOUT (HZ/2) + +struct au1xmmc_host { + struct mmc_host *mmc; + struct mmc_request *mrq; + + u32 flags; + u32 iobase; + u32 clock; + u32 bus_width; + u32 power_mode; + + int status; + + struct { + int len; + int dir; + } dma; + + struct { + int index; + int offset; + int len; + } pio; + + u32 tx_chan; + u32 rx_chan; + + int irq; + + struct timer_list timer; + struct tasklet_struct finish_task; + struct tasklet_struct data_task; + struct au1xmmc_platform_data *platdata; + struct platform_device *pdev; + struct resource *ioarea; +}; + +/* Status flags used by the host structure */ +#define HOST_F_XMIT 0x0001 +#define HOST_F_RECV 0x0002 +#define HOST_F_DMA 0x0010 +#define HOST_F_ACTIVE 0x0100 +#define HOST_F_STOP 0x1000 + +#define HOST_S_IDLE 0x0001 +#define HOST_S_CMD 0x0002 +#define HOST_S_DATA 0x0003 +#define HOST_S_STOP 0x0004 + +/* Easy access macros */ +#define HOST_STATUS(h) ((h)->iobase + SD_STATUS) +#define HOST_CONFIG(h) ((h)->iobase + SD_CONFIG) +#define HOST_ENABLE(h) ((h)->iobase + SD_ENABLE) +#define HOST_TXPORT(h) ((h)->iobase + SD_TXPORT) +#define HOST_RXPORT(h) ((h)->iobase + SD_RXPORT) +#define HOST_CMDARG(h) ((h)->iobase + SD_CMDARG) +#define HOST_BLKSIZE(h) ((h)->iobase + SD_BLKSIZE) +#define HOST_CMD(h) ((h)->iobase + SD_CMD) +#define HOST_CONFIG2(h) ((h)->iobase + SD_CONFIG2) +#define HOST_TIMEOUT(h) ((h)->iobase + SD_TIMEOUT) +#define HOST_DEBUG(h) ((h)->iobase + SD_DEBUG) + +#define DMA_CHANNEL(h) \ + (((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan) + static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) { u32 val = au_readl(HOST_CONFIG(host)); @@ -141,7 +225,6 @@ static int au1xmmc_card_readonly(struct mmc_host *mmc) static void au1xmmc_finish_request(struct au1xmmc_host *host) { - struct mmc_request *mrq = host->mrq; host->mrq = NULL; @@ -215,18 +298,14 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, au_sync(); /* Wait for the command to go on the line */ - - while(1) { - if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO)) - break; - } + while (au_readl(HOST_CMD(host)) & SD_CMD_GO) + /* nop */; /* Wait for the command to come back */ - if (wait) { u32 status = au_readl(HOST_STATUS(host)); - while(!(status & SD_STATUS_CR)) + while (!(status & SD_STATUS_CR)) status = au_readl(HOST_STATUS(host)); /* Clear the CR status */ @@ -240,12 +319,11 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) { - struct mmc_request *mrq = host->mrq; struct mmc_data *data; u32 crc; - WARN_ON(host->status != HOST_S_DATA && host->status != HOST_S_STOP); + WARN_ON((host->status != HOST_S_DATA) && (host->status != HOST_S_STOP)); if (host->mrq == NULL) return; @@ -256,15 +334,13 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) status = au_readl(HOST_STATUS(host)); /* The transaction is really over when the SD_STATUS_DB bit is clear */ - - while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) + while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) status = au_readl(HOST_STATUS(host)); data->error = 0; dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); /* Process any errors */ - crc = (status & (SD_STATUS_WC | SD_STATUS_RC)); if (host->flags & HOST_F_XMIT) crc |= ((status & 0x07) == 0x02) ? 0 : 1; @@ -282,15 +358,13 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) #ifdef CONFIG_SOC_AU1200 /* DBDMA */ u32 chan = DMA_CHANNEL(host); - chan_tab_t *c = *((chan_tab_t **) chan); + chan_tab_t *c = *((chan_tab_t **)chan); au1x_dma_chan_t *cp = c->chan_ptr; data->bytes_xfered = cp->ddma_bytecnt; #endif - } - else + } else data->bytes_xfered = - (data->blocks * data->blksz) - - host->pio.len; + (data->blocks * data->blksz) - host->pio.len; } au1xmmc_finish_request(host); @@ -298,7 +372,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) static void au1xmmc_tasklet_data(unsigned long param) { - struct au1xmmc_host *host = (struct au1xmmc_host *) param; + struct au1xmmc_host *host = (struct au1xmmc_host *)param; u32 status = au_readl(HOST_STATUS(host)); au1xmmc_data_complete(host, status); @@ -308,11 +382,10 @@ static void au1xmmc_tasklet_data(unsigned long param) static void au1xmmc_send_pio(struct au1xmmc_host *host) { - - struct mmc_data *data = 0; - int sg_len, max, count = 0; - unsigned char *sg_ptr; - u32 status = 0; + struct mmc_data *data; + int sg_len, max, count; + unsigned char *sg_ptr, val; + u32 status; struct scatterlist *sg; data = host->mrq->data; @@ -327,14 +400,12 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) /* This is the space left inside the buffer */ sg_len = data->sg[host->pio.index].length - host->pio.offset; - /* Check to if we need less then the size of the sg_buffer */ - + /* Check if we need less than the size of the sg_buffer */ max = (sg_len > host->pio.len) ? host->pio.len : sg_len; - if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER; - - for(count = 0; count < max; count++ ) { - unsigned char val; + if (max > AU1XMMC_MAX_TRANSFER) + max = AU1XMMC_MAX_TRANSFER; + for (count = 0; count < max; count++) { status = au_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_TH)) @@ -342,7 +413,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) val = *sg_ptr++; - au_writel((unsigned long) val, HOST_TXPORT(host)); + au_writel((unsigned long)val, HOST_TXPORT(host)); au_sync(); } @@ -366,11 +437,10 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) static void au1xmmc_receive_pio(struct au1xmmc_host *host) { - - struct mmc_data *data = 0; - int sg_len = 0, max = 0, count = 0; - unsigned char *sg_ptr = 0; - u32 status = 0; + struct mmc_data *data; + int max, count, sg_len = 0; + unsigned char *sg_ptr = NULL; + u32 status, val; struct scatterlist *sg; data = host->mrq->data; @@ -387,15 +457,15 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) /* This is the space left inside the buffer */ sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; - /* Check to if we need less then the size of the sg_buffer */ - if (sg_len < max) max = sg_len; + /* Check if we need less than the size of the sg_buffer */ + if (sg_len < max) + max = sg_len; } if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER; - for(count = 0; count < max; count++ ) { - u32 val; + for (count = 0; count < max; count++) { status = au_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_NE)) @@ -421,7 +491,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) val = au_readl(HOST_RXPORT(host)); if (sg_ptr) - *sg_ptr++ = (unsigned char) (val & 0xFF); + *sg_ptr++ = (unsigned char)(val & 0xFF); } host->pio.len -= count; @@ -433,7 +503,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) } if (host->pio.len == 0) { - //IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF); + /* IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF); */ IRQ_OFF(host, SD_CONFIG_NE); if (host->flags & HOST_F_STOP) @@ -443,17 +513,15 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) } } -/* static void au1xmmc_cmd_complete - This is called when a command has been completed - grab the response - and check for errors. Then start the data transfer if it is indicated. -*/ - +/* This is called when a command has been completed - grab the response + * and check for errors. Then start the data transfer if it is indicated. + */ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) { - struct mmc_request *mrq = host->mrq; struct mmc_command *cmd; - int trans; + u32 r[4]; + int i, trans; if (!host->mrq) return; @@ -463,9 +531,6 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { - u32 r[4]; - int i; - r[0] = au_readl(host->iobase + SD_RESP3); r[1] = au_readl(host->iobase + SD_RESP2); r[2] = au_readl(host->iobase + SD_RESP1); @@ -473,10 +538,9 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) /* The CRC is omitted from the response, so really * we only got 120 bytes, but the engine expects - * 128 bits, so we have to shift things up + * 128 bits, so we have to shift things up. */ - - for(i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; @@ -487,22 +551,20 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) * our response omits the CRC, our data ends up * being shifted 8 bits to the right. In this case, * that means that the OSR data starts at bit 31, - * so we can just read RESP0 and return that + * so we can just read RESP0 and return that. */ cmd->resp[0] = au_readl(host->iobase + SD_RESP0); } } /* Figure out errors */ - if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC)) cmd->error = -EILSEQ; trans = host->flags & (HOST_F_XMIT | HOST_F_RECV); if (!trans || cmd->error) { - - IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF); + IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA | SD_CONFIG_RF); tasklet_schedule(&host->finish_task); return; } @@ -529,18 +591,15 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) { - unsigned int pbus = get_au1x00_speed(); unsigned int divisor; u32 config; /* From databook: - divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1 - */ - + * divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1 + */ pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2); pbus /= 2; - divisor = ((pbus / rate) / 2) - 1; config = au_readl(HOST_CONFIG(host)); @@ -552,8 +611,8 @@ static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) au_sync(); } -static int -au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) +static int au1xmmc_prepare_data(struct au1xmmc_host *host, + struct mmc_data *data) { int datalen = data->blocks * data->blksz; @@ -582,7 +641,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) au1xxx_dbdma_stop(channel); - for(i = 0; i < host->dma.len; i++) { + for (i = 0; i < host->dma.len; i++) { u32 ret = 0, flags = DDMA_FLAGS_NOIE; struct scatterlist *sg = &data->sg[i]; int sg_len = sg->length; @@ -592,14 +651,12 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) if (i == host->dma.len - 1) flags = DDMA_FLAGS_IE; - if (host->flags & HOST_F_XMIT){ - ret = au1xxx_dbdma_put_source_flags(channel, - (void *) sg_virt(sg), len, flags); - } - else { - ret = au1xxx_dbdma_put_dest_flags(channel, - (void *) sg_virt(sg), - len, flags); + if (host->flags & HOST_F_XMIT) { + ret = au1xxx_dbdma_put_source_flags(channel, + (void *)sg_virt(sg), len, flags); + } else { + ret = au1xxx_dbdma_put_dest_flags(channel, + (void *)sg_virt(sg), len, flags); } if (!ret) @@ -608,8 +665,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) datalen -= len; } #endif - } - else { + } else { host->pio.index = 0; host->pio.offset = 0; host->pio.len = datalen; @@ -618,7 +674,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) IRQ_ON(host, SD_CONFIG_TH); else IRQ_ON(host, SD_CONFIG_NE); - //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF); + /* IRQ_ON(host, SD_CONFIG_RA | SD_CONFIG_RF); */ } return 0; @@ -629,15 +685,10 @@ dataerr: return -ETIMEDOUT; } -/* static void au1xmmc_request - This actually starts a command or data transaction -*/ - +/* This actually starts a command or data transaction */ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) { - struct au1xmmc_host *host = mmc_priv(mmc); - unsigned int flags = 0; int ret = 0; WARN_ON(irqs_disabled()); @@ -648,7 +699,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) if (mrq->data) { FLUSH_FIFO(host); - flags = mrq->data->flags; ret = au1xmmc_prepare_data(host, mrq->data); } @@ -663,7 +713,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) static void au1xmmc_reset_controller(struct au1xmmc_host *host) { - /* Apply the clock */ au_writel(SD_ENABLE_CE, HOST_ENABLE(host)); au_sync_delay(1); @@ -693,7 +742,7 @@ static void au1xmmc_reset_controller(struct au1xmmc_host *host) } -static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) +static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct au1xmmc_host *host = mmc_priv(mmc); u32 config2; diff --git a/drivers/mmc/host/au1xmmc.h b/drivers/mmc/host/au1xmmc.h deleted file mode 100644 index 3b40065..0000000 --- a/drivers/mmc/host/au1xmmc.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef _AU1XMMC_H_ -#define _AU1XMMC_H_ - -/* Hardware definitions */ - -#define AU1XMMC_DESCRIPTOR_COUNT 1 -#define AU1XMMC_DESCRIPTOR_SIZE 2048 - -#define AU1XMMC_OCR ( MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \ - MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \ - MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36) - -/* Easy access macros */ - -#define HOST_STATUS(h) ((h)->iobase + SD_STATUS) -#define HOST_CONFIG(h) ((h)->iobase + SD_CONFIG) -#define HOST_ENABLE(h) ((h)->iobase + SD_ENABLE) -#define HOST_TXPORT(h) ((h)->iobase + SD_TXPORT) -#define HOST_RXPORT(h) ((h)->iobase + SD_RXPORT) -#define HOST_CMDARG(h) ((h)->iobase + SD_CMDARG) -#define HOST_BLKSIZE(h) ((h)->iobase + SD_BLKSIZE) -#define HOST_CMD(h) ((h)->iobase + SD_CMD) -#define HOST_CONFIG2(h) ((h)->iobase + SD_CONFIG2) -#define HOST_TIMEOUT(h) ((h)->iobase + SD_TIMEOUT) -#define HOST_DEBUG(h) ((h)->iobase + SD_DEBUG) - -#define DMA_CHANNEL(h) \ - ( ((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan) - -/* This gives us a hard value for the stop command that we can write directly - * to the command register - */ - -#define STOP_CMD (SD_CMD_RT_1B|SD_CMD_CT_7|(0xC << SD_CMD_CI_SHIFT)|SD_CMD_GO) - -/* This is the set of interrupts that we configure by default */ - -#if 0 -#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_DD | \ - SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I) -#endif - -#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | \ - SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I) -/* The poll event (looking for insert/remove events runs twice a second */ -#define AU1XMMC_DETECT_TIMEOUT (HZ/2) - -struct au1xmmc_host { - struct mmc_host *mmc; - struct mmc_request *mrq; - - u32 flags; - u32 iobase; - u32 clock; - u32 bus_width; - u32 power_mode; - - int status; - - struct { - int len; - int dir; - } dma; - - struct { - int index; - int offset; - int len; - } pio; - - u32 tx_chan; - u32 rx_chan; - - int irq; - - struct timer_list timer; - struct tasklet_struct finish_task; - struct tasklet_struct data_task; - struct au1xmmc_platform_data *platdata; - struct platform_device *pdev; - struct resource *ioarea; -}; - -/* Status flags used by the host structure */ - -#define HOST_F_XMIT 0x0001 -#define HOST_F_RECV 0x0002 -#define HOST_F_DMA 0x0010 -#define HOST_F_ACTIVE 0x0100 -#define HOST_F_STOP 0x1000 - -#define HOST_S_IDLE 0x0001 -#define HOST_S_CMD 0x0002 -#define HOST_S_DATA 0x0003 -#define HOST_S_STOP 0x0004 - -#endif -- cgit v0.10.2 From 88b8d9a83431237bf3eec1f2968f763607811171 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:39:11 +0200 Subject: au1xmmc: abort requests early if no card is present. Don't process an MMC request if no card is present. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index fcbaf40..718eb87 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -697,6 +697,13 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) host->mrq = mrq; host->status = HOST_S_CMD; + /* fail request immediately if no card is present */ + if (0 == au1xmmc_card_inserted(host)) { + mrq->cmd->error = -ENOMEDIUM; + au1xmmc_finish_request(host); + return; + } + if (mrq->data) { FLUSH_FIFO(host); ret = au1xmmc_prepare_data(host, mrq->data); -- cgit v0.10.2 From 08fcb7208c4a8913232e48931783270262ece954 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:40:35 +0200 Subject: au1xmmc: new maintainer. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/MAINTAINERS b/MAINTAINERS index 1528e58..f140449 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -348,7 +348,9 @@ W: http://www.linux-usb.org/SpeedTouch/ S: Maintained ALCHEMY AU1XX0 MMC DRIVER -S: Orphan +P: Manuel Lauss +M: manuel.lauss@gmail.com +S: Maintained ALI1563 I2C DRIVER P: Rudolf Marek -- cgit v0.10.2 From e2d2647702702ea08cb78cdc9eca8c24242aa9be Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Fri, 27 Jun 2008 18:25:18 +0200 Subject: au1xmmc: remove custom carddetect poll implementation. The MMC core provides a carddetect poll feature, time to remove the driver's own implementation of it. Signed-off-by: Manuel Lauss Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 718eb87..3f15eb2 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -21,7 +21,7 @@ * published by the Free Software Foundation. */ -/* Why is a timer used to detect insert events? +/* Why don't we use the SD controllers' carddetect feature? * * From the AU1100 MMC application guide: * If the Au1100-based design is intended to support both MultiMediaCards @@ -30,8 +30,6 @@ * In doing so, a MMC card never enters SPI-mode communications, * but now the SecureDigital card-detect feature of CD/DAT3 is ineffective * (the low to high transition will not occur). - * - * So we use the timer to check the status manually. */ #include @@ -111,7 +109,6 @@ struct au1xmmc_host { int irq; - struct timer_list timer; struct tasklet_struct finish_task; struct tasklet_struct data_task; struct au1xmmc_platform_data *platdata; @@ -198,29 +195,24 @@ static void au1xmmc_set_power(struct au1xmmc_host *host, int state) host->platdata->set_power(host->mmc, state); } -static int au1xmmc_card_inserted(struct au1xmmc_host *host) +static int au1xmmc_card_inserted(struct mmc_host *mmc) { - int ret; + struct au1xmmc_host *host = mmc_priv(mmc); if (host->platdata && host->platdata->card_inserted) - ret = host->platdata->card_inserted(host->mmc); - else - ret = 1; /* assume there is a card */ + return !!host->platdata->card_inserted(host->mmc); - return ret; + return -ENOSYS; } static int au1xmmc_card_readonly(struct mmc_host *mmc) { struct au1xmmc_host *host = mmc_priv(mmc); - int ret; if (host->platdata && host->platdata->card_readonly) - ret = host->platdata->card_readonly(mmc); - else - ret = 0; /* assume card is read-write */ + return !!host->platdata->card_readonly(mmc); - return ret; + return -ENOSYS; } static void au1xmmc_finish_request(struct au1xmmc_host *host) @@ -698,7 +690,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) host->status = HOST_S_CMD; /* fail request immediately if no card is present */ - if (0 == au1xmmc_card_inserted(host)) { + if (0 == au1xmmc_card_inserted(mmc)) { mrq->cmd->error = -ENOMEDIUM; au1xmmc_finish_request(host); return; @@ -935,39 +927,10 @@ static const struct mmc_host_ops au1xmmc_ops = { .request = au1xmmc_request, .set_ios = au1xmmc_set_ios, .get_ro = au1xmmc_card_readonly, + .get_cd = au1xmmc_card_inserted, .enable_sdio_irq = au1xmmc_enable_sdio_irq, }; -static void au1xmmc_poll_event(unsigned long arg) -{ - struct au1xmmc_host *host = (struct au1xmmc_host *)arg; - int card = au1xmmc_card_inserted(host); - int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0; - - if (card != controller) { - host->flags &= ~HOST_F_ACTIVE; - if (card) - host->flags |= HOST_F_ACTIVE; - mmc_detect_change(host->mmc, 0); - } - -#ifdef DEBUG - if (host->mrq != NULL) { - u32 status = au_readl(HOST_STATUS(host)); - DBG("PENDING - %8.8x\n", host->pdev->id, status); - } -#endif - mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); -} - -static void au1xmmc_init_cd_poll_timer(struct au1xmmc_host *host) -{ - init_timer(&host->timer); - host->timer.function = au1xmmc_poll_event; - host->timer.data = (unsigned long)host; - host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT; -} - static int __devinit au1xmmc_probe(struct platform_device *pdev) { struct mmc_host *mmc; @@ -1042,13 +1005,11 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) if (host->platdata && host->platdata->cd_setup) { ret = host->platdata->cd_setup(mmc, 1); if (ret) { - dev_err(&pdev->dev, "board CD setup failed\n"); - goto out4; + dev_warn(&pdev->dev, "board CD setup failed\n"); + mmc->caps |= MMC_CAP_NEEDS_POLL; } - } else { - /* poll the board-specific is-card-in-socket-? method */ - au1xmmc_init_cd_poll_timer(host); - } + } else + mmc->caps |= MMC_CAP_NEEDS_POLL; tasklet_init(&host->data_task, au1xmmc_tasklet_data, (unsigned long)host); @@ -1084,10 +1045,6 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mmc); - /* start the carddetect poll timer if necessary */ - if (!(host->platdata && host->platdata->cd_setup)) - add_timer(&host->timer); - printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X" " (mode=%s)\n", pdev->id, host->iobase, host->flags & HOST_F_DMA ? "dma" : "pio"); @@ -1112,9 +1069,10 @@ out5: tasklet_kill(&host->data_task); tasklet_kill(&host->finish_task); - if (host->platdata && host->platdata->cd_setup) + if (host->platdata && host->platdata->cd_setup && + !(mmc->caps & MMC_CAP_NEEDS_POLL)) host->platdata->cd_setup(mmc, 0); -out4: + free_irq(host->irq, host); out3: iounmap((void *)host->iobase); @@ -1142,10 +1100,9 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev) led_classdev_unregister(host->platdata->led); #endif - if (host->platdata && host->platdata->cd_setup) + if (host->platdata && host->platdata->cd_setup && + !(mmc->caps & MMC_CAP_NEEDS_POLL)) host->platdata->cd_setup(mmc, 0); - else - del_timer_sync(&host->timer); au_writel(0, HOST_ENABLE(host)); au_writel(0, HOST_CONFIG(host)); -- cgit v0.10.2 From ad3868b2ec96ec14a1549c9e33f5f9a2a3c6ab15 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 12:52:45 +0200 Subject: mmc,sdio: helper function for transfer padding There are a lot of crappy controllers out there that cannot handle all the request sizes that the MMC/SD/SDIO specifications require. In case the card driver can pad the data to overcome the problems, this commit adds a helper that calculates how much that padding should be. A corresponding helper is also added for SDIO, but it can also deal with all the complexities of splitting up a large transfer efficiently. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ede5d1e..3ee5b8c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2004 Russell King, All Rights Reserved. * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. - * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. + * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. * * This program is free software; you can redistribute it and/or modify @@ -295,6 +295,33 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) EXPORT_SYMBOL(mmc_set_data_timeout); /** + * mmc_align_data_size - pads a transfer size to a more optimal value + * @card: the MMC card associated with the data transfer + * @sz: original transfer size + * + * Pads the original data size with a number of extra bytes in + * order to avoid controller bugs and/or performance hits + * (e.g. some controllers revert to PIO for certain sizes). + * + * Returns the improved size, which might be unmodified. + * + * Note that this function is only relevant when issuing a + * single scatter gather entry. + */ +unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) +{ + /* + * FIXME: We don't have a system for the controller to tell + * the core about its problems yet, so for now we just 32-bit + * align the size. + */ + sz = ((sz + 3) / 4) * 4; + + return sz; +} +EXPORT_SYMBOL(mmc_align_data_size); + +/** * __mmc_claim_host - exclusively claim a host * @host: mmc host to claim * @abort: whether or not the operation should be aborted diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 625b92c..6ee7861 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -1,7 +1,7 @@ /* * linux/drivers/mmc/core/sdio_io.c * - * Copyright 2007 Pierre Ossman + * Copyright 2007-2008 Pierre Ossman * * 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 @@ -189,6 +189,103 @@ int sdio_set_block_size(struct sdio_func *func, unsigned blksz) EXPORT_SYMBOL_GPL(sdio_set_block_size); +/** + * sdio_align_size - pads a transfer size to a more optimal value + * @func: SDIO function + * @sz: original transfer size + * + * Pads the original data size with a number of extra bytes in + * order to avoid controller bugs and/or performance hits + * (e.g. some controllers revert to PIO for certain sizes). + * + * If possible, it will also adjust the size so that it can be + * handled in just a single request. + * + * Returns the improved size, which might be unmodified. + */ +unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz) +{ + unsigned int orig_sz; + unsigned int blk_sz, byte_sz; + unsigned chunk_sz; + + orig_sz = sz; + + /* + * Do a first check with the controller, in case it + * wants to increase the size up to a point where it + * might need more than one block. + */ + sz = mmc_align_data_size(func->card, sz); + + /* + * If we can still do this with just a byte transfer, then + * we're done. + */ + if ((sz <= func->cur_blksize) && (sz <= 512)) + return sz; + + if (func->card->cccr.multi_block) { + /* + * Check if the transfer is already block aligned + */ + if ((sz % func->cur_blksize) == 0) + return sz; + + /* + * Realign it so that it can be done with one request, + * and recheck if the controller still likes it. + */ + blk_sz = ((sz + func->cur_blksize - 1) / + func->cur_blksize) * func->cur_blksize; + blk_sz = mmc_align_data_size(func->card, blk_sz); + + /* + * This value is only good if it is still just + * one request. + */ + if ((blk_sz % func->cur_blksize) == 0) + return blk_sz; + + /* + * We failed to do one request, but at least try to + * pad the remainder properly. + */ + byte_sz = mmc_align_data_size(func->card, + sz % func->cur_blksize); + if ((byte_sz <= func->cur_blksize) && (byte_sz <= 512)) { + blk_sz = sz / func->cur_blksize; + return blk_sz * func->cur_blksize + byte_sz; + } + } else { + /* + * We need multiple requests, so first check that the + * controller can handle the chunk size; + */ + chunk_sz = mmc_align_data_size(func->card, + min(func->cur_blksize, 512u)); + if (chunk_sz == min(func->cur_blksize, 512u)) { + /* + * Fix up the size of the remainder (if any) + */ + byte_sz = orig_sz % chunk_sz; + if (byte_sz) { + byte_sz = mmc_align_data_size(func->card, + byte_sz); + } + + return (orig_sz / chunk_sz) * chunk_sz + byte_sz; + } + } + + /* + * The controller is simply incapable of transferring the size + * we want in decent manner, so just return the original size. + */ + return orig_sz; +} +EXPORT_SYMBOL_GPL(sdio_align_size); + /* Split an arbitrarily sized data transfer into several * IO_RW_EXTENDED commands. */ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 3dd537b..b54e2ea 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1,7 +1,7 @@ /* * linux/drivers/net/wireless/libertas/if_sdio.c * - * Copyright 2007 Pierre Ossman + * Copyright 2007-2008 Pierre Ossman * * Inspired by if_cs.c, Copyright 2007 Holger Schurig * @@ -266,13 +266,10 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) /* * The transfer must be in one transaction or the firmware - * goes suicidal. + * goes suicidal. There's no way to guarantee that for all + * controllers, but we can at least try. */ - chunk = size; - if ((chunk > card->func->cur_blksize) || (chunk > 512)) { - chunk = (chunk + card->func->cur_blksize - 1) / - card->func->cur_blksize * card->func->cur_blksize; - } + chunk = sdio_align_size(card->func, size); ret = sdio_readsb(card->func, card->buffer, card->ioport, chunk); if (ret) @@ -696,13 +693,10 @@ static int if_sdio_host_to_card(struct lbs_private *priv, /* * The transfer must be in one transaction or the firmware - * goes suicidal. + * goes suicidal. There's no way to guarantee that for all + * controllers, but we can at least try. */ - size = nb + 4; - if ((size > card->func->cur_blksize) || (size > 512)) { - size = (size + card->func->cur_blksize - 1) / - card->func->cur_blksize * card->func->cur_blksize; - } + size = sdio_align_size(card->func, nb + 4); packet = kzalloc(sizeof(struct if_sdio_packet) + size, GFP_ATOMIC); diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index d0c3abe..143cebf 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -135,6 +135,7 @@ extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); +extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); extern void mmc_release_host(struct mmc_host *host); diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index b050f4d..f57f22b 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -1,7 +1,7 @@ /* * include/linux/mmc/sdio_func.h * - * Copyright 2007 Pierre Ossman + * Copyright 2007-2008 Pierre Ossman * * 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 @@ -120,6 +120,8 @@ extern int sdio_set_block_size(struct sdio_func *func, unsigned blksz); extern int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler); extern int sdio_release_irq(struct sdio_func *func); +extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz); + extern unsigned char sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret); extern unsigned short sdio_readw(struct sdio_func *func, -- cgit v0.10.2 From eea0f581c4e596e02250df230f8d385827977964 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 13:22:40 +0200 Subject: sdio: clean up handling of byte mode transfer size Make sure that the maximum size for a byte mode transfer is identical in all places. Also tweak the transfer helper so that a single byte mode transfer is preferred over (possibly multiple) block mode request(s). Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 6ee7861..cc42a41 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -186,9 +186,20 @@ int sdio_set_block_size(struct sdio_func *func, unsigned blksz) func->cur_blksize = blksz; return 0; } - EXPORT_SYMBOL_GPL(sdio_set_block_size); +/* + * Calculate the maximum byte mode transfer size + */ +static inline unsigned int sdio_max_byte_size(struct sdio_func *func) +{ + return min(min(min( + func->card->host->max_seg_size, + func->card->host->max_blk_size), + func->max_blksize), + 512u); /* maximum size for byte mode */ +} + /** * sdio_align_size - pads a transfer size to a more optimal value * @func: SDIO function @@ -222,7 +233,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz) * If we can still do this with just a byte transfer, then * we're done. */ - if ((sz <= func->cur_blksize) && (sz <= 512)) + if (sz <= sdio_max_byte_size(func)) return sz; if (func->card->cccr.multi_block) { @@ -253,7 +264,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz) */ byte_sz = mmc_align_data_size(func->card, sz % func->cur_blksize); - if ((byte_sz <= func->cur_blksize) && (byte_sz <= 512)) { + if (byte_sz <= sdio_max_byte_size(func)) { blk_sz = sz / func->cur_blksize; return blk_sz * func->cur_blksize + byte_sz; } @@ -263,8 +274,8 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz) * controller can handle the chunk size; */ chunk_sz = mmc_align_data_size(func->card, - min(func->cur_blksize, 512u)); - if (chunk_sz == min(func->cur_blksize, 512u)) { + sdio_max_byte_size(func)); + if (chunk_sz == sdio_max_byte_size(func)) { /* * Fix up the size of the remainder (if any) */ @@ -296,7 +307,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, int ret; /* Do the bulk of the transfer using block mode (if supported). */ - if (func->card->cccr.multi_block) { + if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) { /* Blocks per command is limited by host count, host transfer * size (we only use a single sg entry) and the maximum for * IO_RW_EXTENDED of 511 blocks. */ @@ -328,11 +339,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, /* Write the remainder using byte mode. */ while (remainder > 0) { - size = remainder; - if (size > func->cur_blksize) - size = func->cur_blksize; - if (size > 512) - size = 512; /* maximum size for byte mode */ + size = min(remainder, sdio_max_byte_size(func)); ret = mmc_io_rw_extended(func->card, write, func->num, addr, incr_addr, buf, 1, size); -- cgit v0.10.2 From 0121a9829bf28c65e1a05cc881899c10d82b8de2 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 17:51:27 +0200 Subject: mmc_test: only bind to supported cards We can only perform the tests on MMC and SD cards, so avoid binding to any other type. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 371d922..8e0bb12 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -1,7 +1,7 @@ /* * linux/drivers/mmc/card/mmc_test.c * - * Copyright 2007 Pierre Ossman + * Copyright 2007-2008 Pierre Ossman * * 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 @@ -858,6 +858,9 @@ static int mmc_test_probe(struct mmc_card *card) { int ret; + if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD)) + return -ENODEV; + mutex_init(&mmc_test_lock); ret = device_create_file(&card->dev, &dev_attr_test); -- cgit v0.10.2 From 93fc48c785f6266e67663b3cbbf24579b53fe5cf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 18:21:41 +0200 Subject: sdhci-pci: don't penalize newer jmicron chips The upcoming JMicron chips will have solved all the currently known bugs, so don't penalize them for older problems. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index c0fbf48..0716dcf 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -139,6 +139,12 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) { int ret; + if (chip->pdev->revision == 0) { + chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_RESET_AFTER_REQUEST; + } + /* * JMicron chips can have two interfaces to the same hardware * in order to work around limitations in Microsoft's driver. @@ -250,10 +256,6 @@ static int jmicron_resume(struct sdhci_pci_chip *chip) } static const struct sdhci_pci_fixes sdhci_jmicron = { - .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | - SDHCI_QUIRK_32BIT_DMA_SIZE | - SDHCI_QUIRK_RESET_AFTER_REQUEST, - .probe = jmicron_probe, .probe_slot = jmicron_probe_slot, -- cgit v0.10.2 From 2134a922c6e75c779983cad5d8aae832275f5a0d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 28 Jun 2008 18:28:51 +0200 Subject: sdhci: scatter-gather (ADMA) support Add support for the scatter-gather DMA mode present on newer controllers. As the mode requires 32-bit alignment, non-aligned chunks are handled by using a bounce buffer. Also add some new quirks to handle controllers that have bugs in the ADMA engine. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 0716dcf..deb607c 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -142,6 +142,7 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) if (chip->pdev->revision == 0) { chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST; } @@ -206,6 +207,22 @@ static void jmicron_enable_mmc(struct sdhci_host *host, int on) static int jmicron_probe_slot(struct sdhci_pci_slot *slot) { + if (slot->chip->pdev->revision == 0) { + u16 version; + + version = readl(slot->host->ioaddr + SDHCI_HOST_VERSION); + version = (version & SDHCI_VENDOR_VER_MASK) >> + SDHCI_VENDOR_VER_SHIFT; + + /* + * Older versions of the chip have lots of nasty glitches + * in the ADMA engine. It's best just to avoid it + * completely. + */ + if (version < 0xAC) + slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; + } + /* * The secondary interface requires a bit set to get the * interrupts. diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0ab582e..b802044 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -124,7 +124,8 @@ static void sdhci_init(struct sdhci_host *host) SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT | SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | - SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE; + SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE | + SDHCI_INT_ADMA_ERROR; writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); @@ -314,6 +315,196 @@ static void sdhci_transfer_pio(struct sdhci_host *host) DBG("PIO transfer complete.\n"); } +static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) +{ + local_irq_save(*flags); + return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; +} + +static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) +{ + kunmap_atomic(buffer, KM_BIO_SRC_IRQ); + local_irq_restore(*flags); +} + +static void sdhci_adma_table_pre(struct sdhci_host *host, + struct mmc_data *data) +{ + int direction; + + u8 *desc; + u8 *align; + dma_addr_t addr; + dma_addr_t align_addr; + int len, offset; + + struct scatterlist *sg; + int i; + char *buffer; + unsigned long flags; + + /* + * The spec does not specify endianness of descriptor table. + * We currently guess that it is LE. + */ + + if (data->flags & MMC_DATA_READ) + direction = DMA_FROM_DEVICE; + else + direction = DMA_TO_DEVICE; + + /* + * The ADMA descriptor table is mapped further down as we + * need to fill it with data first. + */ + + host->align_addr = dma_map_single(mmc_dev(host->mmc), + host->align_buffer, 128 * 4, direction); + BUG_ON(host->align_addr & 0x3); + + host->sg_count = dma_map_sg(mmc_dev(host->mmc), + data->sg, data->sg_len, direction); + + desc = host->adma_desc; + align = host->align_buffer; + + align_addr = host->align_addr; + + for_each_sg(data->sg, sg, host->sg_count, i) { + addr = sg_dma_address(sg); + len = sg_dma_len(sg); + + /* + * The SDHCI specification states that ADMA + * addresses must be 32-bit aligned. If they + * aren't, then we use a bounce buffer for + * the (up to three) bytes that screw up the + * alignment. + */ + offset = (4 - (addr & 0x3)) & 0x3; + if (offset) { + if (data->flags & MMC_DATA_WRITE) { + buffer = sdhci_kmap_atomic(sg, &flags); + memcpy(align, buffer, offset); + sdhci_kunmap_atomic(buffer, &flags); + } + + desc[7] = (align_addr >> 24) & 0xff; + desc[6] = (align_addr >> 16) & 0xff; + desc[5] = (align_addr >> 8) & 0xff; + desc[4] = (align_addr >> 0) & 0xff; + + BUG_ON(offset > 65536); + + desc[3] = (offset >> 8) & 0xff; + desc[2] = (offset >> 0) & 0xff; + + desc[1] = 0x00; + desc[0] = 0x21; /* tran, valid */ + + align += 4; + align_addr += 4; + + desc += 8; + + addr += offset; + len -= offset; + } + + desc[7] = (addr >> 24) & 0xff; + desc[6] = (addr >> 16) & 0xff; + desc[5] = (addr >> 8) & 0xff; + desc[4] = (addr >> 0) & 0xff; + + BUG_ON(len > 65536); + + desc[3] = (len >> 8) & 0xff; + desc[2] = (len >> 0) & 0xff; + + desc[1] = 0x00; + desc[0] = 0x21; /* tran, valid */ + + desc += 8; + + /* + * If this triggers then we have a calculation bug + * somewhere. :/ + */ + WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4); + } + + /* + * Add a terminating entry. + */ + desc[7] = 0; + desc[6] = 0; + desc[5] = 0; + desc[4] = 0; + + desc[3] = 0; + desc[2] = 0; + + desc[1] = 0x00; + desc[0] = 0x03; /* nop, end, valid */ + + /* + * Resync align buffer as we might have changed it. + */ + if (data->flags & MMC_DATA_WRITE) { + dma_sync_single_for_device(mmc_dev(host->mmc), + host->align_addr, 128 * 4, direction); + } + + host->adma_addr = dma_map_single(mmc_dev(host->mmc), + host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); + BUG_ON(host->adma_addr & 0x3); +} + +static void sdhci_adma_table_post(struct sdhci_host *host, + struct mmc_data *data) +{ + int direction; + + struct scatterlist *sg; + int i, size; + u8 *align; + char *buffer; + unsigned long flags; + + if (data->flags & MMC_DATA_READ) + direction = DMA_FROM_DEVICE; + else + direction = DMA_TO_DEVICE; + + dma_unmap_single(mmc_dev(host->mmc), host->adma_addr, + (128 * 2 + 1) * 4, DMA_TO_DEVICE); + + dma_unmap_single(mmc_dev(host->mmc), host->align_addr, + 128 * 4, direction); + + if (data->flags & MMC_DATA_READ) { + dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg, + data->sg_len, direction); + + align = host->align_buffer; + + for_each_sg(data->sg, sg, host->sg_count, i) { + if (sg_dma_address(sg) & 0x3) { + size = 4 - (sg_dma_address(sg) & 0x3); + + buffer = sdhci_kmap_atomic(sg, &flags); + memcpy(buffer, align, size); + sdhci_kunmap_atomic(buffer, &flags); + + align += 4; + } + } + } + + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, direction); +} + static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) { u8 count; @@ -363,6 +554,7 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) { u8 count; + u8 ctrl; WARN_ON(host->data); @@ -383,35 +575,104 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) if (host->flags & SDHCI_USE_DMA) host->flags |= SDHCI_REQ_USE_DMA; - if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && - (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) && - ((data->blksz * data->blocks) & 0x3))) { - DBG("Reverting to PIO because of transfer size (%d)\n", - data->blksz * data->blocks); - host->flags &= ~SDHCI_REQ_USE_DMA; + /* + * FIXME: This doesn't account for merging when mapping the + * scatterlist. + */ + if (host->flags & SDHCI_REQ_USE_DMA) { + int broken, i; + struct scatterlist *sg; + + broken = 0; + if (host->flags & SDHCI_USE_ADMA) { + if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) + broken = 1; + } else { + if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) + broken = 1; + } + + if (unlikely(broken)) { + for_each_sg(data->sg, sg, data->sg_len, i) { + if (sg->length & 0x3) { + DBG("Reverting to PIO because of " + "transfer size (%d)\n", + sg->length); + host->flags &= ~SDHCI_REQ_USE_DMA; + break; + } + } + } } /* * The assumption here being that alignment is the same after * translation to device address space. */ - if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && - (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && - (data->sg->offset & 0x3))) { - DBG("Reverting to PIO because of bad alignment\n"); - host->flags &= ~SDHCI_REQ_USE_DMA; + if (host->flags & SDHCI_REQ_USE_DMA) { + int broken, i; + struct scatterlist *sg; + + broken = 0; + if (host->flags & SDHCI_USE_ADMA) { + /* + * As we use 3 byte chunks to work around + * alignment problems, we need to check this + * quirk. + */ + if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) + broken = 1; + } else { + if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) + broken = 1; + } + + if (unlikely(broken)) { + for_each_sg(data->sg, sg, data->sg_len, i) { + if (sg->offset & 0x3) { + DBG("Reverting to PIO because of " + "bad alignment\n"); + host->flags &= ~SDHCI_REQ_USE_DMA; + break; + } + } + } + } + + /* + * Always adjust the DMA selection as some controllers + * (e.g. JMicron) can't do PIO properly when the selection + * is ADMA. + */ + if (host->version >= SDHCI_SPEC_200) { + ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl &= ~SDHCI_CTRL_DMA_MASK; + if ((host->flags & SDHCI_REQ_USE_DMA) && + (host->flags & SDHCI_USE_ADMA)) + ctrl |= SDHCI_CTRL_ADMA32; + else + ctrl |= SDHCI_CTRL_SDMA; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); } if (host->flags & SDHCI_REQ_USE_DMA) { - int count; + if (host->flags & SDHCI_USE_ADMA) { + sdhci_adma_table_pre(host, data); + writel(host->adma_addr, + host->ioaddr + SDHCI_ADMA_ADDRESS); + } else { + int count; - count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, - (data->flags & MMC_DATA_READ) ? - DMA_FROM_DEVICE : DMA_TO_DEVICE); - WARN_ON(count != 1); + count = dma_map_sg(mmc_dev(host->mmc), + data->sg, data->sg_len, + (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : + DMA_TO_DEVICE); + WARN_ON(count != 1); - writel(sg_dma_address(data->sg), - host->ioaddr + SDHCI_DMA_ADDRESS); + writel(sg_dma_address(data->sg), + host->ioaddr + SDHCI_DMA_ADDRESS); + } } else { host->cur_sg = data->sg; host->num_sg = data->sg_len; @@ -457,9 +718,13 @@ static void sdhci_finish_data(struct sdhci_host *host) host->data = NULL; if (host->flags & SDHCI_REQ_USE_DMA) { - dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, - (data->flags & MMC_DATA_READ) ? - DMA_FROM_DEVICE : DMA_TO_DEVICE); + if (host->flags & SDHCI_USE_ADMA) + sdhci_adma_table_post(host, data); + else { + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : DMA_TO_DEVICE); + } } /* @@ -1008,6 +1273,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) host->data->error = -ETIMEDOUT; else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT)) host->data->error = -EILSEQ; + else if (intmask & SDHCI_INT_ADMA_ERROR) + host->data->error = -EIO; if (host->data->error) sdhci_finish_data(host); @@ -1199,7 +1466,6 @@ int sdhci_add_host(struct sdhci_host *host) { struct mmc_host *mmc; unsigned int caps; - unsigned int version; int ret; WARN_ON(host == NULL); @@ -1213,12 +1479,13 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_reset(host, SDHCI_RESET_ALL); - version = readw(host->ioaddr + SDHCI_HOST_VERSION); - version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; - if (version > 1) { + host->version = readw(host->ioaddr + SDHCI_HOST_VERSION); + host->version = (host->version & SDHCI_SPEC_VER_MASK) + >> SDHCI_SPEC_VER_SHIFT; + if (host->version > SDHCI_SPEC_200) { printk(KERN_ERR "%s: Unknown controller version (%d). " "You may experience problems.\n", mmc_hostname(mmc), - version); + host->version); } caps = readl(host->ioaddr + SDHCI_CAPABILITIES); @@ -1237,16 +1504,46 @@ int sdhci_add_host(struct sdhci_host *host) } if (host->flags & SDHCI_USE_DMA) { + if ((host->version >= SDHCI_SPEC_200) && + (caps & SDHCI_CAN_DO_ADMA2)) + host->flags |= SDHCI_USE_ADMA; + } + + if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && + (host->flags & SDHCI_USE_ADMA)) { + DBG("Disabling ADMA as it is marked broken\n"); + host->flags &= ~SDHCI_USE_ADMA; + } + + if (host->flags & SDHCI_USE_DMA) { if (host->ops->enable_dma) { if (host->ops->enable_dma(host)) { printk(KERN_WARNING "%s: No suitable DMA " "available. Falling back to PIO.\n", mmc_hostname(mmc)); - host->flags &= ~SDHCI_USE_DMA; + host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA); } } } + if (host->flags & SDHCI_USE_ADMA) { + /* + * We need to allocate descriptors for all sg entries + * (128) and potentially one alignment transfer for + * each of those entries. + */ + host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL); + host->align_buffer = kmalloc(128 * 4, GFP_KERNEL); + if (!host->adma_desc || !host->align_buffer) { + kfree(host->adma_desc); + kfree(host->align_buffer); + printk(KERN_WARNING "%s: Unable to allocate ADMA " + "buffers. Falling back to standard DMA.\n", + mmc_hostname(mmc)); + host->flags &= ~SDHCI_USE_ADMA; + } + } + /* XXX: Hack to get MMC layer to avoid highmem */ if (!(host->flags & SDHCI_USE_DMA)) mmc_dev(host->mmc)->dma_mask = 0; @@ -1298,13 +1595,16 @@ int sdhci_add_host(struct sdhci_host *host) spin_lock_init(&host->lock); /* - * Maximum number of segments. Hardware cannot do scatter lists. + * Maximum number of segments. Depends on if the hardware + * can do scatter/gather or not. */ - if (host->flags & SDHCI_USE_DMA) + if (host->flags & SDHCI_USE_ADMA) + mmc->max_hw_segs = 128; + else if (host->flags & SDHCI_USE_DMA) mmc->max_hw_segs = 1; - else - mmc->max_hw_segs = 16; - mmc->max_phys_segs = 16; + else /* PIO */ + mmc->max_hw_segs = 128; + mmc->max_phys_segs = 128; /* * Maximum number of sectors in one transfer. Limited by DMA boundary @@ -1314,9 +1614,13 @@ int sdhci_add_host(struct sdhci_host *host) /* * Maximum segment size. Could be one segment with the maximum number - * of bytes. + * of bytes. When doing hardware scatter/gather, each entry cannot + * be larger than 64 KiB though. */ - mmc->max_seg_size = mmc->max_req_size; + if (host->flags & SDHCI_USE_ADMA) + mmc->max_seg_size = 65536; + else + mmc->max_seg_size = mmc->max_req_size; /* * Maximum block size. This varies from controller to controller and @@ -1371,8 +1675,9 @@ int sdhci_add_host(struct sdhci_host *host) mmc_add_host(mmc); - printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n", + printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", mmc_hostname(mmc), host->hw_name, mmc_dev(mmc)->bus_id, + (host->flags & SDHCI_USE_ADMA)?"A":"", (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); return 0; @@ -1426,6 +1731,12 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) tasklet_kill(&host->card_tasklet); tasklet_kill(&host->finish_tasklet); + + kfree(host->adma_desc); + kfree(host->align_buffer); + + host->adma_desc = NULL; + host->align_buffer = NULL; } EXPORT_SYMBOL_GPL(sdhci_remove_host); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 7c30251..5bb3552 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -60,6 +60,11 @@ #define SDHCI_CTRL_LED 0x01 #define SDHCI_CTRL_4BITBUS 0x02 #define SDHCI_CTRL_HISPD 0x04 +#define SDHCI_CTRL_DMA_MASK 0x18 +#define SDHCI_CTRL_SDMA 0x00 +#define SDHCI_CTRL_ADMA1 0x08 +#define SDHCI_CTRL_ADMA32 0x10 +#define SDHCI_CTRL_ADMA64 0x18 #define SDHCI_POWER_CONTROL 0x29 #define SDHCI_POWER_ON 0x01 @@ -105,6 +110,7 @@ #define SDHCI_INT_DATA_END_BIT 0x00400000 #define SDHCI_INT_BUS_POWER 0x00800000 #define SDHCI_INT_ACMD12ERR 0x01000000 +#define SDHCI_INT_ADMA_ERROR 0x02000000 #define SDHCI_INT_NORMAL_MASK 0x00007FFF #define SDHCI_INT_ERROR_MASK 0xFFFF8000 @@ -128,11 +134,14 @@ #define SDHCI_CLOCK_BASE_SHIFT 8 #define SDHCI_MAX_BLOCK_MASK 0x00030000 #define SDHCI_MAX_BLOCK_SHIFT 16 +#define SDHCI_CAN_DO_ADMA2 0x00080000 +#define SDHCI_CAN_DO_ADMA1 0x00100000 #define SDHCI_CAN_DO_HISPD 0x00200000 #define SDHCI_CAN_DO_DMA 0x00400000 #define SDHCI_CAN_VDD_330 0x01000000 #define SDHCI_CAN_VDD_300 0x02000000 #define SDHCI_CAN_VDD_180 0x04000000 +#define SDHCI_CAN_64BIT 0x10000000 /* 44-47 reserved for more caps */ @@ -140,7 +149,16 @@ /* 4C-4F reserved for more max current */ -/* 50-FB reserved */ +#define SDHCI_SET_ACMD12_ERROR 0x50 +#define SDHCI_SET_INT_ERROR 0x52 + +#define SDHCI_ADMA_ERROR 0x54 + +/* 55-57 reserved */ + +#define SDHCI_ADMA_ADDRESS 0x58 + +/* 60-FB reserved */ #define SDHCI_SLOT_INT_STATUS 0xFC @@ -149,6 +167,8 @@ #define SDHCI_VENDOR_VER_SHIFT 8 #define SDHCI_SPEC_VER_MASK 0x00FF #define SDHCI_SPEC_VER_SHIFT 0 +#define SDHCI_SPEC_100 0 +#define SDHCI_SPEC_200 1 struct sdhci_ops; @@ -170,16 +190,20 @@ struct sdhci_host { #define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4) /* Controller has an unusable DMA engine */ #define SDHCI_QUIRK_BROKEN_DMA (1<<5) +/* Controller has an unusable ADMA engine */ +#define SDHCI_QUIRK_BROKEN_ADMA (1<<6) /* Controller can only DMA from 32-bit aligned addresses */ -#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<6) +#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<7) /* Controller can only DMA chunk sizes that are a multiple of 32 bits */ -#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<7) +#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<8) +/* Controller can only ADMA chunks that are a multiple of 32 bits */ +#define SDHCI_QUIRK_32BIT_ADMA_SIZE (1<<9) /* Controller needs to be reset after each request to stay stable */ -#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<8) +#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<10) /* Controller needs voltage and power writes to happen separately */ -#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<9) +#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11) /* Controller provides an incorrect timeout value for transfers */ -#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<10) +#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ @@ -197,8 +221,11 @@ struct sdhci_host { int flags; /* Host attributes */ #define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */ -#define SDHCI_REQ_USE_DMA (1<<1) /* Use DMA for this req. */ -#define SDHCI_DEVICE_DEAD (1<<2) /* Device unresponsive */ +#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ +#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ +#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ + + unsigned int version; /* SDHCI spec. version */ unsigned int max_clk; /* Max possible freq (MHz) */ unsigned int timeout_clk; /* Timeout freq (KHz) */ @@ -216,6 +243,14 @@ struct sdhci_host { int offset; /* Offset into current sg */ int remain; /* Bytes left in current */ + int sg_count; /* Mapped sg entries */ + + u8 *adma_desc; /* ADMA descriptor table */ + u8 *align_buffer; /* Bounce buffer */ + + dma_addr_t adma_addr; /* Mapped ADMA descr. table */ + dma_addr_t align_addr; /* Mapped bounce buffer */ + struct tasklet_struct card_tasklet; /* Tasklet structures */ struct tasklet_struct finish_tasklet; -- cgit v0.10.2 From 979ce7208a679b8d012450610d5d5aa75aab3af9 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 29 Jun 2008 12:19:47 +0200 Subject: mmc_block: wait for card even on failures Many failures are non-permanent, but the card might need some time to finish what it is doing before becoming responsive again. Make sure we wait for it to finish programming before dealing with the error. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f9ad960..4b0f822 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -2,7 +2,7 @@ * Block driver for media (i.e., flash cards) * * Copyright 2002 Hewlett-Packard Company - * Copyright 2005-2007 Pierre Ossman + * Copyright 2005-2008 Pierre Ossman * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is @@ -296,22 +296,24 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) mmc_queue_bounce_post(mq); + /* + * Check for errors here, but don't jump to cmd_err + * until later as we need to wait for the card to leave + * programming mode even when things go wrong. + */ if (brq.cmd.error) { printk(KERN_ERR "%s: error %d sending read/write command\n", req->rq_disk->disk_name, brq.cmd.error); - goto cmd_err; } if (brq.data.error) { printk(KERN_ERR "%s: error %d transferring data\n", req->rq_disk->disk_name, brq.data.error); - goto cmd_err; } if (brq.stop.error) { printk(KERN_ERR "%s: error %d sending stop command\n", req->rq_disk->disk_name, brq.stop.error); - goto cmd_err; } if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { @@ -344,6 +346,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) #endif } + if (brq.cmd.error || brq.data.error || brq.stop.error) + goto cmd_err; + /* * A block was successfully transferred. */ -- cgit v0.10.2 From 6b174931a73177c6519f87e6a8d5ae6ba269cdb5 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 30 Jun 2008 09:09:27 +0200 Subject: mmc_test: cleanup Clean up and reorganise the mmc_test driver so that it (hopefully) is easier to extend with more complex tests. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 8e0bb12..d6b9b48 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -26,13 +26,17 @@ struct mmc_test_card { struct mmc_card *card; + u8 scratch[BUFFER_SIZE]; u8 *buffer; }; /*******************************************************************/ -/* Helper functions */ +/* General helper functions */ /*******************************************************************/ +/* + * Configure correct block size in card + */ static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) { struct mmc_command cmd; @@ -48,117 +52,61 @@ static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) return 0; } -static int __mmc_test_transfer(struct mmc_test_card *test, int write, - unsigned broken_xfer, u8 *buffer, unsigned addr, - unsigned blocks, unsigned blksz) +/* + * Fill in the mmc_request structure given a set of transfer parameters. + */ +static void mmc_test_prepare_mrq(struct mmc_test_card *test, + struct mmc_request *mrq, struct scatterlist *sg, unsigned sg_len, + unsigned dev_addr, unsigned blocks, unsigned blksz, int write) { - int ret, busy; + BUG_ON(!mrq || !mrq->cmd || !mrq->data || !mrq->stop); - struct mmc_request mrq; - struct mmc_command cmd; - struct mmc_command stop; - struct mmc_data data; - - struct scatterlist sg; - - memset(&mrq, 0, sizeof(struct mmc_request)); - - mrq.cmd = &cmd; - mrq.data = &data; - - memset(&cmd, 0, sizeof(struct mmc_command)); - - if (broken_xfer) { - if (blocks > 1) { - cmd.opcode = write ? - MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; - } else { - cmd.opcode = MMC_SEND_STATUS; - } + if (blocks > 1) { + mrq->cmd->opcode = write ? + MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK; } else { - if (blocks > 1) { - cmd.opcode = write ? - MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK; - } else { - cmd.opcode = write ? - MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; - } + mrq->cmd->opcode = write ? + MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; } - if (broken_xfer && blocks == 1) - cmd.arg = test->card->rca << 16; - else - cmd.arg = addr; - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - - memset(&stop, 0, sizeof(struct mmc_command)); - - if (!broken_xfer && (blocks > 1)) { - stop.opcode = MMC_STOP_TRANSMISSION; - stop.arg = 0; - stop.flags = MMC_RSP_R1B | MMC_CMD_AC; + mrq->cmd->arg = dev_addr; + mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC; - mrq.stop = &stop; + if (blocks == 1) + mrq->stop = NULL; + else { + mrq->stop->opcode = MMC_STOP_TRANSMISSION; + mrq->stop->arg = 0; + mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC; } - memset(&data, 0, sizeof(struct mmc_data)); - - data.blksz = blksz; - data.blocks = blocks; - data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - - sg_init_one(&sg, buffer, blocks * blksz); + mrq->data->blksz = blksz; + mrq->data->blocks = blocks; + mrq->data->flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; + mrq->data->sg = sg; + mrq->data->sg_len = sg_len; - mmc_set_data_timeout(&data, test->card); - - mmc_wait_for_req(test->card->host, &mrq); - - ret = 0; - - if (broken_xfer) { - if (!ret && cmd.error) - ret = cmd.error; - if (!ret && data.error == 0) - ret = RESULT_FAIL; - if (!ret && data.error != -ETIMEDOUT) - ret = data.error; - if (!ret && stop.error) - ret = stop.error; - if (blocks > 1) { - if (!ret && data.bytes_xfered > blksz) - ret = RESULT_FAIL; - } else { - if (!ret && data.bytes_xfered > 0) - ret = RESULT_FAIL; - } - } else { - if (!ret && cmd.error) - ret = cmd.error; - if (!ret && data.error) - ret = data.error; - if (!ret && stop.error) - ret = stop.error; - if (!ret && data.bytes_xfered != blocks * blksz) - ret = RESULT_FAIL; - } + mmc_set_data_timeout(mrq->data, test->card); +} - if (ret == -EINVAL) - ret = RESULT_UNSUP_HOST; +/* + * Wait for the card to finish the busy state + */ +static int mmc_test_wait_busy(struct mmc_test_card *test) +{ + int ret, busy; + struct mmc_command cmd; busy = 0; do { - int ret2; - memset(&cmd, 0, sizeof(struct mmc_command)); cmd.opcode = MMC_SEND_STATUS; cmd.arg = test->card->rca << 16; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - ret2 = mmc_wait_for_cmd(test->card->host, &cmd, 0); - if (ret2) + ret = mmc_wait_for_cmd(test->card->host, &cmd, 0); + if (ret) break; if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) { @@ -172,14 +120,57 @@ static int __mmc_test_transfer(struct mmc_test_card *test, int write, return ret; } -static int mmc_test_transfer(struct mmc_test_card *test, int write, - u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) +/* + * Transfer a single sector of kernel addressable data + */ +static int mmc_test_buffer_transfer(struct mmc_test_card *test, + u8 *buffer, unsigned addr, unsigned blksz, int write) { - return __mmc_test_transfer(test, write, 0, buffer, - addr, blocks, blksz); + int ret; + + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_command stop; + struct mmc_data data; + + struct scatterlist sg; + + memset(&mrq, 0, sizeof(struct mmc_request)); + memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&data, 0, sizeof(struct mmc_data)); + memset(&stop, 0, sizeof(struct mmc_command)); + + mrq.cmd = &cmd; + mrq.data = &data; + mrq.stop = &stop; + + sg_init_one(&sg, buffer, blksz); + + mmc_test_prepare_mrq(test, &mrq, &sg, 1, addr, 1, blksz, write); + + mmc_wait_for_req(test->card->host, &mrq); + + if (cmd.error) + return cmd.error; + if (data.error) + return data.error; + + ret = mmc_test_wait_busy(test); + if (ret) + return ret; + + return 0; } -static int mmc_test_prepare_verify(struct mmc_test_card *test, int write) +/*******************************************************************/ +/* Test preparation and cleanup */ +/*******************************************************************/ + +/* + * Fill the first couple of sectors of the card with known data + * so that bad reads/writes can be detected + */ +static int __mmc_test_prepare(struct mmc_test_card *test, int write) { int ret, i; @@ -188,15 +179,14 @@ static int mmc_test_prepare_verify(struct mmc_test_card *test, int write) return ret; if (write) - memset(test->buffer, 0xDF, BUFFER_SIZE); + memset(test->buffer, 0xDF, 512); else { - for (i = 0;i < BUFFER_SIZE;i++) + for (i = 0;i < 512;i++) test->buffer[i] = i; } for (i = 0;i < BUFFER_SIZE / 512;i++) { - ret = mmc_test_transfer(test, 1, test->buffer + i * 512, - i * 512, 1, 512); + ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1); if (ret) return ret; } @@ -204,41 +194,218 @@ static int mmc_test_prepare_verify(struct mmc_test_card *test, int write) return 0; } -static int mmc_test_prepare_verify_write(struct mmc_test_card *test) +static int mmc_test_prepare_write(struct mmc_test_card *test) +{ + return __mmc_test_prepare(test, 1); +} + +static int mmc_test_prepare_read(struct mmc_test_card *test) +{ + return __mmc_test_prepare(test, 0); +} + +static int mmc_test_cleanup(struct mmc_test_card *test) +{ + int ret, i; + + ret = mmc_test_set_blksize(test, 512); + if (ret) + return ret; + + memset(test->buffer, 0, 512); + + for (i = 0;i < BUFFER_SIZE / 512;i++) { + ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1); + if (ret) + return ret; + } + + return 0; +} + +/*******************************************************************/ +/* Test execution helpers */ +/*******************************************************************/ + +/* + * Modifies the mmc_request to perform the "short transfer" tests + */ +static void mmc_test_prepare_broken_mrq(struct mmc_test_card *test, + struct mmc_request *mrq, int write) +{ + BUG_ON(!mrq || !mrq->cmd || !mrq->data); + + if (mrq->data->blocks > 1) { + mrq->cmd->opcode = write ? + MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; + mrq->stop = NULL; + } else { + mrq->cmd->opcode = MMC_SEND_STATUS; + mrq->cmd->arg = test->card->rca << 16; + } +} + +/* + * Checks that a normal transfer didn't have any errors + */ +static int mmc_test_check_result(struct mmc_test_card *test, + struct mmc_request *mrq) { - return mmc_test_prepare_verify(test, 1); + int ret; + + BUG_ON(!mrq || !mrq->cmd || !mrq->data); + + ret = 0; + + if (!ret && mrq->cmd->error) + ret = mrq->cmd->error; + if (!ret && mrq->data->error) + ret = mrq->data->error; + if (!ret && mrq->stop && mrq->stop->error) + ret = mrq->stop->error; + if (!ret && mrq->data->bytes_xfered != + mrq->data->blocks * mrq->data->blksz) + ret = RESULT_FAIL; + + if (ret == -EINVAL) + ret = RESULT_UNSUP_HOST; + + return ret; } -static int mmc_test_prepare_verify_read(struct mmc_test_card *test) +/* + * Checks that a "short transfer" behaved as expected + */ +static int mmc_test_check_broken_result(struct mmc_test_card *test, + struct mmc_request *mrq) { - return mmc_test_prepare_verify(test, 0); + int ret; + + BUG_ON(!mrq || !mrq->cmd || !mrq->data); + + ret = 0; + + if (!ret && mrq->cmd->error) + ret = mrq->cmd->error; + if (!ret && mrq->data->error == 0) + ret = RESULT_FAIL; + if (!ret && mrq->data->error != -ETIMEDOUT) + ret = mrq->data->error; + if (!ret && mrq->stop && mrq->stop->error) + ret = mrq->stop->error; + if (mrq->data->blocks > 1) { + if (!ret && mrq->data->bytes_xfered > mrq->data->blksz) + ret = RESULT_FAIL; + } else { + if (!ret && mrq->data->bytes_xfered > 0) + ret = RESULT_FAIL; + } + + if (ret == -EINVAL) + ret = RESULT_UNSUP_HOST; + + return ret; } -static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, - u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) +/* + * Tests a basic transfer with certain parameters + */ +static int mmc_test_simple_transfer(struct mmc_test_card *test, + struct scatterlist *sg, unsigned sg_len, unsigned dev_addr, + unsigned blocks, unsigned blksz, int write) { - int ret, i, sectors; + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_command stop; + struct mmc_data data; - /* - * It is assumed that the above preparation has been done. - */ + memset(&mrq, 0, sizeof(struct mmc_request)); + memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&data, 0, sizeof(struct mmc_data)); + memset(&stop, 0, sizeof(struct mmc_command)); + + mrq.cmd = &cmd; + mrq.data = &data; + mrq.stop = &stop; + + mmc_test_prepare_mrq(test, &mrq, sg, sg_len, dev_addr, + blocks, blksz, write); + + mmc_wait_for_req(test->card->host, &mrq); - memset(test->buffer, 0, BUFFER_SIZE); + mmc_test_wait_busy(test); + + return mmc_test_check_result(test, &mrq); +} + +/* + * Tests a transfer where the card will fail completely or partly + */ +static int mmc_test_broken_transfer(struct mmc_test_card *test, + unsigned blocks, unsigned blksz, int write) +{ + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_command stop; + struct mmc_data data; + + struct scatterlist sg; + + memset(&mrq, 0, sizeof(struct mmc_request)); + memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&data, 0, sizeof(struct mmc_data)); + memset(&stop, 0, sizeof(struct mmc_command)); + + mrq.cmd = &cmd; + mrq.data = &data; + mrq.stop = &stop; + + sg_init_one(&sg, test->buffer, blocks * blksz); + + mmc_test_prepare_mrq(test, &mrq, &sg, 1, 0, blocks, blksz, write); + mmc_test_prepare_broken_mrq(test, &mrq, write); + + mmc_wait_for_req(test->card->host, &mrq); + + mmc_test_wait_busy(test); + + return mmc_test_check_broken_result(test, &mrq); +} + +/* + * Does a complete transfer test where data is also validated + * + * Note: mmc_test_prepare() must have been done before this call + */ +static int mmc_test_transfer(struct mmc_test_card *test, + struct scatterlist *sg, unsigned sg_len, unsigned dev_addr, + unsigned blocks, unsigned blksz, int write) +{ + int ret, i; + unsigned long flags; if (write) { for (i = 0;i < blocks * blksz;i++) - buffer[i] = i; + test->scratch[i] = i; + } else { + memset(test->scratch, 0, BUFFER_SIZE); } + local_irq_save(flags); + sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); + local_irq_restore(flags); ret = mmc_test_set_blksize(test, blksz); if (ret) return ret; - ret = mmc_test_transfer(test, write, buffer, addr, blocks, blksz); + ret = mmc_test_simple_transfer(test, sg, sg_len, dev_addr, + blocks, blksz, write); if (ret) return ret; if (write) { + int sectors; + ret = mmc_test_set_blksize(test, 512); if (ret) return ret; @@ -253,9 +420,9 @@ static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, memset(test->buffer, 0, sectors * 512); for (i = 0;i < sectors;i++) { - ret = mmc_test_transfer(test, 0, + ret = mmc_test_buffer_transfer(test, test->buffer + i * 512, - addr + i * 512, 1, 512); + dev_addr + i * 512, 512, 0); if (ret) return ret; } @@ -270,8 +437,11 @@ static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, return RESULT_FAIL; } } else { + local_irq_save(flags); + sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); + local_irq_restore(flags); for (i = 0;i < blocks * blksz;i++) { - if (buffer[i] != (u8)i) + if (test->scratch[i] != (u8)i) return RESULT_FAIL; } } @@ -279,26 +449,6 @@ static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, return 0; } -static int mmc_test_cleanup_verify(struct mmc_test_card *test) -{ - int ret, i; - - ret = mmc_test_set_blksize(test, 512); - if (ret) - return ret; - - memset(test->buffer, 0, BUFFER_SIZE); - - for (i = 0;i < BUFFER_SIZE / 512;i++) { - ret = mmc_test_transfer(test, 1, test->buffer + i * 512, - i * 512, 1, 512); - if (ret) - return ret; - } - - return 0; -} - /*******************************************************************/ /* Tests */ /*******************************************************************/ @@ -314,12 +464,15 @@ struct mmc_test_case { static int mmc_test_basic_write(struct mmc_test_card *test) { int ret; + struct scatterlist sg; ret = mmc_test_set_blksize(test, 512); if (ret) return ret; - ret = mmc_test_transfer(test, 1, test->buffer, 0, 1, 512); + sg_init_one(&sg, test->buffer, 512); + + ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); if (ret) return ret; @@ -329,12 +482,15 @@ static int mmc_test_basic_write(struct mmc_test_card *test) static int mmc_test_basic_read(struct mmc_test_card *test) { int ret; + struct scatterlist sg; ret = mmc_test_set_blksize(test, 512); if (ret) return ret; - ret = mmc_test_transfer(test, 0, test->buffer, 0, 1, 512); + sg_init_one(&sg, test->buffer, 512); + + ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); if (ret) return ret; @@ -344,8 +500,11 @@ static int mmc_test_basic_read(struct mmc_test_card *test) static int mmc_test_verify_write(struct mmc_test_card *test) { int ret; + struct scatterlist sg; + + sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, 1, 512); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); if (ret) return ret; @@ -355,8 +514,11 @@ static int mmc_test_verify_write(struct mmc_test_card *test) static int mmc_test_verify_read(struct mmc_test_card *test) { int ret; + struct scatterlist sg; + + sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, 1, 512); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); if (ret) return ret; @@ -367,6 +529,7 @@ static int mmc_test_multi_write(struct mmc_test_card *test) { int ret; unsigned int size; + struct scatterlist sg; if (test->card->host->max_blk_count == 1) return RESULT_UNSUP_HOST; @@ -379,8 +542,9 @@ static int mmc_test_multi_write(struct mmc_test_card *test) if (size < 1024) return RESULT_UNSUP_HOST; - ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, - size / 512, 512); + sg_init_one(&sg, test->buffer, size); + + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); if (ret) return ret; @@ -391,6 +555,7 @@ static int mmc_test_multi_read(struct mmc_test_card *test) { int ret; unsigned int size; + struct scatterlist sg; if (test->card->host->max_blk_count == 1) return RESULT_UNSUP_HOST; @@ -403,8 +568,9 @@ static int mmc_test_multi_read(struct mmc_test_card *test) if (size < 1024) return RESULT_UNSUP_HOST; - ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, - size / 512, 512); + sg_init_one(&sg, test->buffer, size); + + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); if (ret) return ret; @@ -414,13 +580,14 @@ static int mmc_test_multi_read(struct mmc_test_card *test) static int mmc_test_pow2_write(struct mmc_test_card *test) { int ret, i; + struct scatterlist sg; if (!test->card->csd.write_partial) return RESULT_UNSUP_CARD; for (i = 1; i < 512;i <<= 1) { - ret = mmc_test_verified_transfer(test, 1, - test->buffer, 0, 1, i); + sg_init_one(&sg, test->buffer, i); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1); if (ret) return ret; } @@ -431,13 +598,14 @@ static int mmc_test_pow2_write(struct mmc_test_card *test) static int mmc_test_pow2_read(struct mmc_test_card *test) { int ret, i; + struct scatterlist sg; if (!test->card->csd.read_partial) return RESULT_UNSUP_CARD; for (i = 1; i < 512;i <<= 1) { - ret = mmc_test_verified_transfer(test, 0, - test->buffer, 0, 1, i); + sg_init_one(&sg, test->buffer, i); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0); if (ret) return ret; } @@ -448,13 +616,14 @@ static int mmc_test_pow2_read(struct mmc_test_card *test) static int mmc_test_weird_write(struct mmc_test_card *test) { int ret, i; + struct scatterlist sg; if (!test->card->csd.write_partial) return RESULT_UNSUP_CARD; for (i = 3; i < 512;i += 7) { - ret = mmc_test_verified_transfer(test, 1, - test->buffer, 0, 1, i); + sg_init_one(&sg, test->buffer, i); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1); if (ret) return ret; } @@ -465,13 +634,14 @@ static int mmc_test_weird_write(struct mmc_test_card *test) static int mmc_test_weird_read(struct mmc_test_card *test) { int ret, i; + struct scatterlist sg; if (!test->card->csd.read_partial) return RESULT_UNSUP_CARD; for (i = 3; i < 512;i += 7) { - ret = mmc_test_verified_transfer(test, 0, - test->buffer, 0, 1, i); + sg_init_one(&sg, test->buffer, i); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0); if (ret) return ret; } @@ -482,10 +652,11 @@ static int mmc_test_weird_read(struct mmc_test_card *test) static int mmc_test_align_write(struct mmc_test_card *test) { int ret, i; + struct scatterlist sg; for (i = 1;i < 4;i++) { - ret = mmc_test_verified_transfer(test, 1, test->buffer + i, - 0, 1, 512); + sg_init_one(&sg, test->buffer + i, 512); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); if (ret) return ret; } @@ -496,10 +667,11 @@ static int mmc_test_align_write(struct mmc_test_card *test) static int mmc_test_align_read(struct mmc_test_card *test) { int ret, i; + struct scatterlist sg; for (i = 1;i < 4;i++) { - ret = mmc_test_verified_transfer(test, 0, test->buffer + i, - 0, 1, 512); + sg_init_one(&sg, test->buffer + i, 512); + ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); if (ret) return ret; } @@ -511,6 +683,7 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test) { int ret, i; unsigned int size; + struct scatterlist sg; if (test->card->host->max_blk_count == 1) return RESULT_UNSUP_HOST; @@ -524,8 +697,8 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test) return RESULT_UNSUP_HOST; for (i = 1;i < 4;i++) { - ret = mmc_test_verified_transfer(test, 1, test->buffer + i, - 0, size / 512, 512); + sg_init_one(&sg, test->buffer + i, size); + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); if (ret) return ret; } @@ -537,6 +710,7 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test) { int ret, i; unsigned int size; + struct scatterlist sg; if (test->card->host->max_blk_count == 1) return RESULT_UNSUP_HOST; @@ -550,8 +724,8 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test) return RESULT_UNSUP_HOST; for (i = 1;i < 4;i++) { - ret = mmc_test_verified_transfer(test, 0, test->buffer + i, - 0, size / 512, 512); + sg_init_one(&sg, test->buffer + i, size); + ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); if (ret) return ret; } @@ -567,7 +741,7 @@ static int mmc_test_xfersize_write(struct mmc_test_card *test) if (ret) return ret; - ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 1, 512); + ret = mmc_test_broken_transfer(test, 1, 512, 1); if (ret) return ret; @@ -582,7 +756,7 @@ static int mmc_test_xfersize_read(struct mmc_test_card *test) if (ret) return ret; - ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 1, 512); + ret = mmc_test_broken_transfer(test, 1, 512, 0); if (ret) return ret; @@ -600,7 +774,7 @@ static int mmc_test_multi_xfersize_write(struct mmc_test_card *test) if (ret) return ret; - ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 2, 512); + ret = mmc_test_broken_transfer(test, 2, 512, 1); if (ret) return ret; @@ -618,7 +792,7 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test) if (ret) return ret; - ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 2, 512); + ret = mmc_test_broken_transfer(test, 2, 512, 0); if (ret) return ret; @@ -638,86 +812,86 @@ static const struct mmc_test_case mmc_test_cases[] = { { .name = "Basic write (with data verification)", - .prepare = mmc_test_prepare_verify_write, + .prepare = mmc_test_prepare_write, .run = mmc_test_verify_write, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Basic read (with data verification)", - .prepare = mmc_test_prepare_verify_read, + .prepare = mmc_test_prepare_read, .run = mmc_test_verify_read, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Multi-block write", - .prepare = mmc_test_prepare_verify_write, + .prepare = mmc_test_prepare_write, .run = mmc_test_multi_write, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Multi-block read", - .prepare = mmc_test_prepare_verify_read, + .prepare = mmc_test_prepare_read, .run = mmc_test_multi_read, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Power of two block writes", - .prepare = mmc_test_prepare_verify_write, + .prepare = mmc_test_prepare_write, .run = mmc_test_pow2_write, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Power of two block reads", - .prepare = mmc_test_prepare_verify_read, + .prepare = mmc_test_prepare_read, .run = mmc_test_pow2_read, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Weird sized block writes", - .prepare = mmc_test_prepare_verify_write, + .prepare = mmc_test_prepare_write, .run = mmc_test_weird_write, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Weird sized block reads", - .prepare = mmc_test_prepare_verify_read, + .prepare = mmc_test_prepare_read, .run = mmc_test_weird_read, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Badly aligned write", - .prepare = mmc_test_prepare_verify_write, + .prepare = mmc_test_prepare_write, .run = mmc_test_align_write, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Badly aligned read", - .prepare = mmc_test_prepare_verify_read, + .prepare = mmc_test_prepare_read, .run = mmc_test_align_read, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Badly aligned multi-block write", - .prepare = mmc_test_prepare_verify_write, + .prepare = mmc_test_prepare_write, .run = mmc_test_align_multi_write, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { .name = "Badly aligned multi-block read", - .prepare = mmc_test_prepare_verify_read, + .prepare = mmc_test_prepare_read, .run = mmc_test_align_multi_read, - .cleanup = mmc_test_cleanup_verify, + .cleanup = mmc_test_cleanup, }, { -- cgit v0.10.2 From 8f1934ce784bd8f2eaf06f190526500f7f3f9c74 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 30 Jun 2008 21:15:49 +0200 Subject: sdhci: graceful handling of bad addresses Be a bit more robust and fall back to PIO if someone is feeding us bogus addresses. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b802044..d3e4a39 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -327,7 +327,7 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) local_irq_restore(*flags); } -static void sdhci_adma_table_pre(struct sdhci_host *host, +static int sdhci_adma_table_pre(struct sdhci_host *host, struct mmc_data *data) { int direction; @@ -360,10 +360,14 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, host->align_addr = dma_map_single(mmc_dev(host->mmc), host->align_buffer, 128 * 4, direction); + if (dma_mapping_error(host->align_addr)) + goto fail; BUG_ON(host->align_addr & 0x3); host->sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, direction); + if (host->sg_count == 0) + goto unmap_align; desc = host->adma_desc; align = host->align_buffer; @@ -457,7 +461,20 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, host->adma_addr = dma_map_single(mmc_dev(host->mmc), host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); + if (dma_mapping_error(host->align_addr)) + goto unmap_entries; BUG_ON(host->adma_addr & 0x3); + + return 0; + +unmap_entries: + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, direction); +unmap_align: + dma_unmap_single(mmc_dev(host->mmc), host->align_addr, + 128 * 4, direction); +fail: + return -EINVAL; } static void sdhci_adma_table_post(struct sdhci_host *host, @@ -555,6 +572,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) { u8 count; u8 ctrl; + int ret; WARN_ON(host->data); @@ -639,6 +657,43 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) } } + if (host->flags & SDHCI_REQ_USE_DMA) { + if (host->flags & SDHCI_USE_ADMA) { + ret = sdhci_adma_table_pre(host, data); + if (ret) { + /* + * This only happens when someone fed + * us an invalid request. + */ + WARN_ON(1); + host->flags &= ~SDHCI_USE_DMA; + } else { + writel(host->adma_addr, + host->ioaddr + SDHCI_ADMA_ADDRESS); + } + } else { + int count; + + count = dma_map_sg(mmc_dev(host->mmc), + data->sg, data->sg_len, + (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : + DMA_TO_DEVICE); + if (count == 0) { + /* + * This only happens when someone fed + * us an invalid request. + */ + WARN_ON(1); + host->flags &= ~SDHCI_USE_DMA; + } else { + WARN_ON(count != 1); + writel(sg_dma_address(data->sg), + host->ioaddr + SDHCI_DMA_ADDRESS); + } + } + } + /* * Always adjust the DMA selection as some controllers * (e.g. JMicron) can't do PIO properly when the selection @@ -655,25 +710,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); } - if (host->flags & SDHCI_REQ_USE_DMA) { - if (host->flags & SDHCI_USE_ADMA) { - sdhci_adma_table_pre(host, data); - writel(host->adma_addr, - host->ioaddr + SDHCI_ADMA_ADDRESS); - } else { - int count; - - count = dma_map_sg(mmc_dev(host->mmc), - data->sg, data->sg_len, - (data->flags & MMC_DATA_READ) ? - DMA_FROM_DEVICE : - DMA_TO_DEVICE); - WARN_ON(count != 1); - - writel(sg_dma_address(data->sg), - host->ioaddr + SDHCI_DMA_ADDRESS); - } - } else { + if (!(host->flags & SDHCI_REQ_USE_DMA)) { host->cur_sg = data->sg; host->num_sg = data->sg_len; -- cgit v0.10.2 From be518018c6b9224c02284fb243207ef741c31ec6 Mon Sep 17 00:00:00 2001 From: Thomas Kleffel Date: Mon, 30 Jun 2008 22:40:24 +0100 Subject: MMC: S3C24XX MMC/SD driver. This is the latest S3C MMC/SD driver by Thomas Kleffel with cleanups as suggested by AKPM done by Ben Dooks. Signed-off-by: Ben Dooks Signed-off-by: Thomas Kleffel Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index f9cbcb8..dc88c03 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -143,3 +143,14 @@ config MMC_SPI If unsure, or if your system has no SPI master driver, say N. +config MMC_S3C + tristate "Samsung S3C SD/MMC Card Interface support" + depends on ARCH_S3C2410 && MMC + help + This selects a driver for the MCI interface found in + Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. + If you have a board based on one of those and a MMC/SD + slot, say Y or M here. + + If unsure, say N. + diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 3027250..b3e023b 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,4 +18,4 @@ obj-$(CONFIG_MMC_OMAP) += omap.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o - +obj-$(CONFIG_MMC_S3C) += s3cmci.o diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c new file mode 100644 index 0000000..c6a4d3c --- /dev/null +++ b/drivers/mmc/host/s3cmci.c @@ -0,0 +1,1343 @@ +/* + * linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver + * + * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "s3cmci.h" + +#define DRIVER_NAME "s3c-mci" + +enum dbg_channels { + dbg_err = (1 << 0), + dbg_debug = (1 << 1), + dbg_info = (1 << 2), + dbg_irq = (1 << 3), + dbg_sg = (1 << 4), + dbg_dma = (1 << 5), + dbg_pio = (1 << 6), + dbg_fail = (1 << 7), + dbg_conf = (1 << 8), +}; + +static const int dbgmap_err = dbg_err | dbg_fail; +static const int dbgmap_info = dbg_info | dbg_conf; +static const int dbgmap_debug = dbg_debug; + +#define dbg(host, channels, args...) \ + do { \ + if (dbgmap_err & channels) \ + dev_err(&host->pdev->dev, args); \ + else if (dbgmap_info & channels) \ + dev_info(&host->pdev->dev, args); \ + else if (dbgmap_debug & channels) \ + dev_dbg(&host->pdev->dev, args); \ + } while (0) + +#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1) + +static struct s3c2410_dma_client s3cmci_dma_client = { + .name = "s3c-mci", +}; + +static void finalize_request(struct s3cmci_host *host); +static void s3cmci_send_request(struct mmc_host *mmc); +static void s3cmci_reset(struct s3cmci_host *host); + +#ifdef CONFIG_MMC_DEBUG + +static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) +{ + u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize; + u32 datcon, datcnt, datsta, fsta, imask; + + con = readl(host->base + S3C2410_SDICON); + pre = readl(host->base + S3C2410_SDIPRE); + cmdarg = readl(host->base + S3C2410_SDICMDARG); + cmdcon = readl(host->base + S3C2410_SDICMDCON); + cmdsta = readl(host->base + S3C2410_SDICMDSTAT); + r0 = readl(host->base + S3C2410_SDIRSP0); + r1 = readl(host->base + S3C2410_SDIRSP1); + r2 = readl(host->base + S3C2410_SDIRSP2); + r3 = readl(host->base + S3C2410_SDIRSP3); + timer = readl(host->base + S3C2410_SDITIMER); + bsize = readl(host->base + S3C2410_SDIBSIZE); + datcon = readl(host->base + S3C2410_SDIDCON); + datcnt = readl(host->base + S3C2410_SDIDCNT); + datsta = readl(host->base + S3C2410_SDIDSTA); + fsta = readl(host->base + S3C2410_SDIFSTA); + imask = readl(host->base + host->sdiimsk); + + dbg(host, dbg_debug, "%s CON:[%08x] PRE:[%08x] TMR:[%08x]\n", + prefix, con, pre, timer); + + dbg(host, dbg_debug, "%s CCON:[%08x] CARG:[%08x] CSTA:[%08x]\n", + prefix, cmdcon, cmdarg, cmdsta); + + dbg(host, dbg_debug, "%s DCON:[%08x] FSTA:[%08x]" + " DSTA:[%08x] DCNT:[%08x]\n", + prefix, datcon, fsta, datsta, datcnt); + + dbg(host, dbg_debug, "%s R0:[%08x] R1:[%08x]" + " R2:[%08x] R3:[%08x]\n", + prefix, r0, r1, r2, r3); +} + +static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd, + int stop) +{ + snprintf(host->dbgmsg_cmd, 300, + "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u", + host->ccnt, (stop ? " (STOP)" : ""), + cmd->opcode, cmd->arg, cmd->flags, cmd->retries); + + if (cmd->data) { + snprintf(host->dbgmsg_dat, 300, + "#%u bsize:%u blocks:%u bytes:%u", + host->dcnt, cmd->data->blksz, + cmd->data->blocks, + cmd->data->blocks * cmd->data->blksz); + } else { + host->dbgmsg_dat[0] = '\0'; + } +} + +static void dbg_dumpcmd(struct s3cmci_host *host, struct mmc_command *cmd, + int fail) +{ + unsigned int dbglvl = fail ? dbg_fail : dbg_debug; + + if (!cmd) + return; + + if (cmd->error == 0) { + dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n", + host->dbgmsg_cmd, cmd->resp[0]); + } else { + dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n", + cmd->error, host->dbgmsg_cmd, host->status); + } + + if (!cmd->data) + return; + + if (cmd->data->error == 0) { + dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat); + } else { + dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n", + cmd->data->error, host->dbgmsg_dat, + readl(host->base + S3C2410_SDIDCNT)); + } +} +#else +static void dbg_dumpcmd(struct s3cmci_host *host, + struct mmc_command *cmd, int fail) { } + +static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd, + int stop) { } + +static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { } + +#endif /* CONFIG_MMC_DEBUG */ + +static inline u32 enable_imask(struct s3cmci_host *host, u32 imask) +{ + u32 newmask; + + newmask = readl(host->base + host->sdiimsk); + newmask |= imask; + + writel(newmask, host->base + host->sdiimsk); + + return newmask; +} + +static inline u32 disable_imask(struct s3cmci_host *host, u32 imask) +{ + u32 newmask; + + newmask = readl(host->base + host->sdiimsk); + newmask &= ~imask; + + writel(newmask, host->base + host->sdiimsk); + + return newmask; +} + +static inline void clear_imask(struct s3cmci_host *host) +{ + writel(0, host->base + host->sdiimsk); +} + +static inline int get_data_buffer(struct s3cmci_host *host, + u32 *words, u32 **pointer) +{ + struct scatterlist *sg; + + 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) { + dbg(host, dbg_debug, "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 >> 2; + *pointer = sg_virt(sg); + + host->pio_sgptr++; + + dbg(host, dbg_sg, "new buffer (%i/%i)\n", + host->pio_sgptr, host->mrq->data->sg_len); + + return 0; +} + +static inline u32 fifo_count(struct s3cmci_host *host) +{ + u32 fifostat = readl(host->base + S3C2410_SDIFSTA); + + fifostat &= S3C2410_SDIFSTA_COUNTMASK; + return fifostat >> 2; +} + +static inline u32 fifo_free(struct s3cmci_host *host) +{ + u32 fifostat = readl(host->base + S3C2410_SDIFSTA); + + fifostat &= S3C2410_SDIFSTA_COUNTMASK; + return (63 - fifostat) >> 2; +} + +static void do_pio_read(struct s3cmci_host *host) +{ + int res; + u32 fifo; + void __iomem *from_ptr; + + /* write real prescaler to host, it might be set slow to fix */ + writel(host->prescaler, host->base + S3C2410_SDIPRE); + + from_ptr = host->base + host->sdidata; + + while ((fifo = fifo_count(host))) { + if (!host->pio_words) { + res = get_data_buffer(host, &host->pio_words, + &host->pio_ptr); + if (res) { + host->pio_active = XFER_NONE; + host->complete_what = COMPLETION_FINALIZE; + + dbg(host, dbg_pio, "pio_read(): " + "complete (no more data).\n"); + return; + } + + dbg(host, dbg_pio, + "pio_read(): new target: [%i]@[%p]\n", + host->pio_words, host->pio_ptr); + } + + dbg(host, dbg_pio, + "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", + fifo, host->pio_words, + readl(host->base + S3C2410_SDIDCNT)); + + if (fifo > host->pio_words) + fifo = host->pio_words; + + host->pio_words -= fifo; + host->pio_count += fifo; + + while (fifo--) + *(host->pio_ptr++) = readl(from_ptr); + } + + if (!host->pio_words) { + res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); + if (res) { + dbg(host, dbg_pio, + "pio_read(): complete (no more buffers).\n"); + host->pio_active = XFER_NONE; + host->complete_what = COMPLETION_FINALIZE; + + return; + } + } + + enable_imask(host, + S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST); +} + +static void do_pio_write(struct s3cmci_host *host) +{ + void __iomem *to_ptr; + int res; + u32 fifo; + + to_ptr = host->base + host->sdidata; + + while ((fifo = fifo_free(host))) { + if (!host->pio_words) { + res = get_data_buffer(host, &host->pio_words, + &host->pio_ptr); + if (res) { + dbg(host, dbg_pio, + "pio_write(): complete (no more data).\n"); + host->pio_active = XFER_NONE; + + return; + } + + dbg(host, dbg_pio, + "pio_write(): new source: [%i]@[%p]\n", + host->pio_words, host->pio_ptr); + + } + + if (fifo > host->pio_words) + fifo = host->pio_words; + + host->pio_words -= fifo; + host->pio_count += fifo; + + while (fifo--) + writel(*(host->pio_ptr++), to_ptr); + } + + enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); +} + +static void pio_tasklet(unsigned long data) +{ + struct s3cmci_host *host = (struct s3cmci_host *) data; + + + if (host->pio_active == XFER_WRITE) + do_pio_write(host); + + if (host->pio_active == XFER_READ) + do_pio_read(host); + + if (host->complete_what == COMPLETION_FINALIZE) { + clear_imask(host); + if (host->pio_active != XFER_NONE) { + dbg(host, dbg_err, "unfinished %s " + "- pio_count:[%u] pio_words:[%u]\n", + (host->pio_active == XFER_READ) ? "read" : "write", + host->pio_count, host->pio_words); + + host->mrq->data->error = -EINVAL; + } + + disable_irq(host->irq); + finalize_request(host); + } +} + +/* + * ISR for SDI Interface IRQ + * Communication between driver and ISR works as follows: + * host->mrq points to current request + * host->complete_what Indicates when the request is considered done + * COMPLETION_CMDSENT when the command was sent + * COMPLETION_RSPFIN when a response was received + * COMPLETION_XFERFINISH when the data transfer is finished + * COMPLETION_XFERFINISH_RSPFIN both of the above. + * host->complete_request is the completion-object the driver waits for + * + * 1) Driver sets up host->mrq and host->complete_what + * 2) Driver prepares the transfer + * 3) Driver enables interrupts + * 4) Driver starts transfer + * 5) Driver waits for host->complete_rquest + * 6) ISR checks for request status (errors and success) + * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error + * 7) ISR completes host->complete_request + * 8) ISR disables interrupts + * 9) Driver wakes up and takes care of the request + * + * Note: "->error"-fields are expected to be set to 0 before the request + * was issued by mmc.c - therefore they are only set, when an error + * contition comes up + */ + +static irqreturn_t s3cmci_irq(int irq, void *dev_id) +{ + struct s3cmci_host *host = dev_id; + struct mmc_command *cmd; + u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk; + u32 mci_cclear, mci_dclear; + unsigned long iflags; + + spin_lock_irqsave(&host->complete_lock, iflags); + + mci_csta = readl(host->base + S3C2410_SDICMDSTAT); + mci_dsta = readl(host->base + S3C2410_SDIDSTA); + mci_dcnt = readl(host->base + S3C2410_SDIDCNT); + mci_fsta = readl(host->base + S3C2410_SDIFSTA); + mci_imsk = readl(host->base + host->sdiimsk); + mci_cclear = 0; + mci_dclear = 0; + + if ((host->complete_what == COMPLETION_NONE) || + (host->complete_what == COMPLETION_FINALIZE)) { + host->status = "nothing to complete"; + clear_imask(host); + goto irq_out; + } + + if (!host->mrq) { + host->status = "no active mrq"; + clear_imask(host); + goto irq_out; + } + + cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd; + + if (!cmd) { + host->status = "no active cmd"; + clear_imask(host); + goto irq_out; + } + + if (!host->dodma) { + if ((host->pio_active == XFER_WRITE) && + (mci_fsta & S3C2410_SDIFSTA_TFDET)) { + + disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); + tasklet_schedule(&host->pio_tasklet); + host->status = "pio tx"; + } + + if ((host->pio_active == XFER_READ) && + (mci_fsta & S3C2410_SDIFSTA_RFDET)) { + + disable_imask(host, + S3C2410_SDIIMSK_RXFIFOHALF | + S3C2410_SDIIMSK_RXFIFOLAST); + + tasklet_schedule(&host->pio_tasklet); + host->status = "pio rx"; + } + } + + if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) { + cmd->error = -ETIMEDOUT; + host->status = "error: command timeout"; + goto fail_transfer; + } + + if (mci_csta & S3C2410_SDICMDSTAT_CMDSENT) { + if (host->complete_what == COMPLETION_CMDSENT) { + host->status = "ok: command sent"; + goto close_transfer; + } + + mci_cclear |= S3C2410_SDICMDSTAT_CMDSENT; + } + + if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) { + if (cmd->flags & MMC_RSP_CRC) { + cmd->error = -EILSEQ; + host->status = "error: bad command crc"; + goto fail_transfer; + } + + mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL; + } + + if (mci_csta & S3C2410_SDICMDSTAT_RSPFIN) { + if (host->complete_what == COMPLETION_RSPFIN) { + host->status = "ok: command response received"; + goto close_transfer; + } + + if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) + host->complete_what = COMPLETION_XFERFINISH; + + mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN; + } + + /* errors handled after this point are only relevant + when a data transfer is in progress */ + + if (!cmd->data) + goto clear_status_bits; + + /* Check for FIFO failure */ + if (host->is2440) { + if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) { + host->mrq->data->error = -EILSEQ; + host->status = "error: 2440 fifo failure"; + goto fail_transfer; + } + } else { + if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) { + cmd->data->error = -EILSEQ; + host->status = "error: fifo failure"; + goto fail_transfer; + } + } + + if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) { + cmd->data->error = -EILSEQ; + host->status = "error: bad data crc (outgoing)"; + goto fail_transfer; + } + + if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) { + cmd->data->error = -EILSEQ; + host->status = "error: bad data crc (incoming)"; + goto fail_transfer; + } + + if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) { + cmd->data->error = -ETIMEDOUT; + host->status = "error: data timeout"; + goto fail_transfer; + } + + if (mci_dsta & S3C2410_SDIDSTA_XFERFINISH) { + if (host->complete_what == COMPLETION_XFERFINISH) { + host->status = "ok: data transfer completed"; + goto close_transfer; + } + + if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) + host->complete_what = COMPLETION_RSPFIN; + + mci_dclear |= S3C2410_SDIDSTA_XFERFINISH; + } + +clear_status_bits: + writel(mci_cclear, host->base + S3C2410_SDICMDSTAT); + writel(mci_dclear, host->base + S3C2410_SDIDSTA); + + goto irq_out; + +fail_transfer: + host->pio_active = XFER_NONE; + +close_transfer: + host->complete_what = COMPLETION_FINALIZE; + + clear_imask(host); + tasklet_schedule(&host->pio_tasklet); + + goto irq_out; + +irq_out: + dbg(host, dbg_irq, + "csta:0x%08x dsta:0x%08x fsta:0x%08x dcnt:0x%08x status:%s.\n", + mci_csta, mci_dsta, mci_fsta, mci_dcnt, host->status); + + spin_unlock_irqrestore(&host->complete_lock, iflags); + return IRQ_HANDLED; + +} + +/* + * ISR for the CardDetect Pin +*/ + +static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id) +{ + struct s3cmci_host *host = (struct s3cmci_host *)dev_id; + + dbg(host, dbg_irq, "card detect\n"); + + mmc_detect_change(host->mmc, 500); + + return IRQ_HANDLED; +} + +void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch, void *buf_id, + int size, enum s3c2410_dma_buffresult result) +{ + struct s3cmci_host *host = buf_id; + unsigned long iflags; + u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt; + + mci_csta = readl(host->base + S3C2410_SDICMDSTAT); + mci_dsta = readl(host->base + S3C2410_SDIDSTA); + mci_fsta = readl(host->base + S3C2410_SDIFSTA); + mci_dcnt = readl(host->base + S3C2410_SDIDCNT); + + BUG_ON(!host->mrq); + BUG_ON(!host->mrq->data); + BUG_ON(!host->dmatogo); + + spin_lock_irqsave(&host->complete_lock, iflags); + + if (result != S3C2410_RES_OK) { + dbg(host, dbg_fail, "DMA FAILED: csta=0x%08x dsta=0x%08x " + "fsta=0x%08x dcnt:0x%08x result:0x%08x toGo:%u\n", + mci_csta, mci_dsta, mci_fsta, + mci_dcnt, result, host->dmatogo); + + goto fail_request; + } + + host->dmatogo--; + if (host->dmatogo) { + dbg(host, dbg_dma, "DMA DONE Size:%i DSTA:[%08x] " + "DCNT:[%08x] toGo:%u\n", + size, mci_dsta, mci_dcnt, host->dmatogo); + + goto out; + } + + dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n", + size, mci_dsta, mci_dcnt); + + host->complete_what = COMPLETION_FINALIZE; + +out: + tasklet_schedule(&host->pio_tasklet); + spin_unlock_irqrestore(&host->complete_lock, iflags); + return; + + +fail_request: + host->mrq->data->error = -EINVAL; + host->complete_what = COMPLETION_FINALIZE; + writel(0, host->base + host->sdiimsk); + goto out; + +} + +static void finalize_request(struct s3cmci_host *host) +{ + struct mmc_request *mrq = host->mrq; + struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; + int debug_as_failure = 0; + + if (host->complete_what != COMPLETION_FINALIZE) + return; + + if (!mrq) + return; + + if (cmd->data && (cmd->error == 0) && + (cmd->data->error == 0)) { + if (host->dodma && (!host->dma_complete)) { + dbg(host, dbg_dma, "DMA Missing!\n"); + return; + } + } + + /* Read response from controller. */ + cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0); + cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1); + cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2); + cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3); + + writel(host->prescaler, host->base + S3C2410_SDIPRE); + + if (cmd->error) + debug_as_failure = 1; + + if (cmd->data && cmd->data->error) + debug_as_failure = 1; + + dbg_dumpcmd(host, cmd, debug_as_failure); + + /* Cleanup controller */ + writel(0, host->base + S3C2410_SDICMDARG); + writel(0, host->base + S3C2410_SDIDCON); + writel(0, host->base + S3C2410_SDICMDCON); + writel(0, host->base + host->sdiimsk); + + if (cmd->data && cmd->error) + cmd->data->error = cmd->error; + + if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) { + host->cmd_is_stop = 1; + s3cmci_send_request(host->mmc); + return; + } + + /* If we have no data transfer we are finished here */ + if (!mrq->data) + goto request_done; + + /* Calulate the amout of bytes transfer if there was no error */ + if (mrq->data->error == 0) { + mrq->data->bytes_xfered = + (mrq->data->blocks * mrq->data->blksz); + } else { + mrq->data->bytes_xfered = 0; + } + + /* If we had an error while transfering data we flush the + * DMA channel and the fifo to clear out any garbage. */ + if (mrq->data->error != 0) { + if (host->dodma) + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); + + if (host->is2440) { + /* Clear failure register and reset fifo. */ + writel(S3C2440_SDIFSTA_FIFORESET | + S3C2440_SDIFSTA_FIFOFAIL, + host->base + S3C2410_SDIFSTA); + } else { + u32 mci_con; + + /* reset fifo */ + mci_con = readl(host->base + S3C2410_SDICON); + mci_con |= S3C2410_SDICON_FIFORESET; + + writel(mci_con, host->base + S3C2410_SDICON); + } + } + +request_done: + host->complete_what = COMPLETION_NONE; + host->mrq = NULL; + mmc_request_done(host->mmc, mrq); +} + + +void s3cmci_dma_setup(struct s3cmci_host *host, enum s3c2410_dmasrc source) +{ + static enum s3c2410_dmasrc last_source = -1; + static int setup_ok; + + if (last_source == source) + return; + + last_source = source; + + s3c2410_dma_devconfig(host->dma, source, 3, + host->mem->start + host->sdidata); + + if (!setup_ok) { + 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); + setup_ok = 1; + } +} + +static void s3cmci_send_command(struct s3cmci_host *host, + struct mmc_command *cmd) +{ + u32 ccon, imsk; + + imsk = S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_CMDTIMEOUT | + S3C2410_SDIIMSK_RESPONSEND | S3C2410_SDIIMSK_CMDSENT | + S3C2410_SDIIMSK_RESPONSECRC; + + enable_imask(host, imsk); + + if (cmd->data) + host->complete_what = COMPLETION_XFERFINISH_RSPFIN; + else if (cmd->flags & MMC_RSP_PRESENT) + host->complete_what = COMPLETION_RSPFIN; + else + host->complete_what = COMPLETION_CMDSENT; + + writel(cmd->arg, host->base + S3C2410_SDICMDARG); + + ccon = cmd->opcode & S3C2410_SDICMDCON_INDEX; + ccon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART; + + if (cmd->flags & MMC_RSP_PRESENT) + ccon |= S3C2410_SDICMDCON_WAITRSP; + + if (cmd->flags & MMC_RSP_136) + ccon |= S3C2410_SDICMDCON_LONGRSP; + + writel(ccon, host->base + S3C2410_SDICMDCON); +} + +static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) +{ + u32 dcon, imsk, stoptries = 3; + + /* write DCON register */ + + if (!data) { + writel(0, host->base + S3C2410_SDIDCON); + return 0; + } + + while (readl(host->base + S3C2410_SDIDSTA) & + (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) { + + dbg(host, dbg_err, + "mci_setup_data() transfer stillin progress.\n"); + + writel(0, host->base + S3C2410_SDIDCON); + s3cmci_reset(host); + + if ((stoptries--) == 0) { + dbg_dumpregs(host, "DRF"); + return -EINVAL; + } + } + + dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK; + + if (host->dodma) + dcon |= S3C2410_SDIDCON_DMAEN; + + if (host->bus_width == MMC_BUS_WIDTH_4) + dcon |= S3C2410_SDIDCON_WIDEBUS; + + if (!(data->flags & MMC_DATA_STREAM)) + dcon |= S3C2410_SDIDCON_BLOCKMODE; + + if (data->flags & MMC_DATA_WRITE) { + dcon |= S3C2410_SDIDCON_TXAFTERRESP; + dcon |= S3C2410_SDIDCON_XFER_TXSTART; + } + + if (data->flags & MMC_DATA_READ) { + dcon |= S3C2410_SDIDCON_RXAFTERCMD; + dcon |= S3C2410_SDIDCON_XFER_RXSTART; + } + + if (host->is2440) { + dcon |= S3C2440_SDIDCON_DS_WORD; + dcon |= S3C2440_SDIDCON_DATSTART; + } + + writel(dcon, host->base + S3C2410_SDIDCON); + + /* write BSIZE register */ + + writel(data->blksz, host->base + S3C2410_SDIBSIZE); + + /* add to IMASK register */ + imsk = S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC | + S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH; + + enable_imask(host, imsk); + + /* write TIMER register */ + + if (host->is2440) { + writel(0x007FFFFF, host->base + S3C2410_SDITIMER); + } else { + writel(0x0000FFFF, host->base + S3C2410_SDITIMER); + + /* FIX: set slow clock to prevent timeouts on read */ + if (data->flags & MMC_DATA_READ) + writel(0xFF, host->base + S3C2410_SDIPRE); + } + + return 0; +} + +#define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ) + +static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data) +{ + int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; + + BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); + + host->pio_sgptr = 0; + host->pio_words = 0; + host->pio_count = 0; + host->pio_active = rw ? XFER_WRITE : XFER_READ; + + if (rw) { + do_pio_write(host); + enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); + } else { + enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF + | S3C2410_SDIIMSK_RXFIFOLAST); + } + + return 0; +} + +static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data) +{ + int dma_len, i; + int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; + + BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); + + s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW); + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); + + dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + (rw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + + if (dma_len == 0) + return -ENOMEM; + + host->dma_complete = 0; + host->dmatogo = dma_len; + + for (i = 0; i < dma_len; i++) { + int res; + + dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i, + sg_dma_address(&data->sg[i]), + sg_dma_len(&data->sg[i])); + + res = s3c2410_dma_enqueue(host->dma, (void *) host, + sg_dma_address(&data->sg[i]), + sg_dma_len(&data->sg[i])); + + if (res) { + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); + return -EBUSY; + } + } + + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START); + + return 0; +} + +static void s3cmci_send_request(struct mmc_host *mmc) +{ + struct s3cmci_host *host = mmc_priv(mmc); + struct mmc_request *mrq = host->mrq; + struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; + + host->ccnt++; + prepare_dbgmsg(host, cmd, host->cmd_is_stop); + + /* Clear command, data and fifo status registers + Fifo clear only necessary on 2440, but doesn't hurt on 2410 + */ + writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT); + writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA); + writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA); + + if (cmd->data) { + int res = s3cmci_setup_data(host, cmd->data); + + host->dcnt++; + + if (res) { + cmd->error = -EINVAL; + cmd->data->error = -EINVAL; + + mmc_request_done(mmc, mrq); + return; + } + + if (host->dodma) + res = s3cmci_prepare_dma(host, cmd->data); + else + res = s3cmci_prepare_pio(host, cmd->data); + + if (res) { + cmd->error = res; + cmd->data->error = res; + + mmc_request_done(mmc, mrq); + return; + } + } + + /* Send command */ + s3cmci_send_command(host, cmd); + + /* Enable Interrupt */ + enable_irq(host->irq); +} + +static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct s3cmci_host *host = mmc_priv(mmc); + + host->status = "mmc request"; + host->cmd_is_stop = 0; + host->mrq = mrq; + + s3cmci_send_request(mmc); +} + +static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct s3cmci_host *host = mmc_priv(mmc); + u32 mci_psc, mci_con; + + /* Set the power state */ + + mci_con = readl(host->base + S3C2410_SDICON); + + switch (ios->power_mode) { + case MMC_POWER_ON: + case MMC_POWER_UP: + s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD); + s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0); + s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1); + s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2); + s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3); + + if (!host->is2440) + mci_con |= S3C2410_SDICON_FIFORESET; + + break; + + case MMC_POWER_OFF: + default: + s3c2410_gpio_setpin(S3C2410_GPE5, 0); + s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP); + + if (host->is2440) + mci_con |= S3C2440_SDICON_SDRESET; + + break; + } + + /* Set clock */ + for (mci_psc = 0; mci_psc < 255; mci_psc++) { + host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); + + if (host->real_rate <= ios->clock) + break; + } + + if (mci_psc > 255) + mci_psc = 255; + + host->prescaler = mci_psc; + writel(host->prescaler, host->base + S3C2410_SDIPRE); + + /* If requested clock is 0, real_rate will be 0, too */ + if (ios->clock == 0) + host->real_rate = 0; + + /* Set CLOCK_ENABLE */ + if (ios->clock) + mci_con |= S3C2410_SDICON_CLOCKTYPE; + else + mci_con &= ~S3C2410_SDICON_CLOCKTYPE; + + writel(mci_con, host->base + S3C2410_SDICON); + + if ((ios->power_mode == MMC_POWER_ON) || + (ios->power_mode == MMC_POWER_UP)) { + dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n", + host->real_rate/1000, ios->clock/1000); + } else { + dbg(host, dbg_conf, "powered down.\n"); + } + + host->bus_width = ios->bus_width; +} + +static void s3cmci_reset(struct s3cmci_host *host) +{ + u32 con = readl(host->base + S3C2410_SDICON); + + con |= S3C2440_SDICON_SDRESET; + writel(con, host->base + S3C2410_SDICON); +} + +static struct mmc_host_ops s3cmci_ops = { + .request = s3cmci_request, + .set_ios = s3cmci_set_ios, +}; + +static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) +{ + struct s3cmci_host *host; + struct mmc_host *mmc; + int ret; + + mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); + if (!mmc) { + ret = -ENOMEM; + goto probe_out; + } + + host = mmc_priv(mmc); + host->mmc = mmc; + host->pdev = pdev; + host->is2440 = is2440; + + spin_lock_init(&host->complete_lock); + tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); + + if (is2440) { + host->sdiimsk = S3C2440_SDIIMSK; + host->sdidata = S3C2440_SDIDATA; + host->clk_div = 1; + } else { + host->sdiimsk = S3C2410_SDIIMSK; + host->sdidata = S3C2410_SDIDATA; + host->clk_div = 2; + } + + host->dodma = 0; + host->complete_what = COMPLETION_NONE; + host->pio_active = XFER_NONE; + + host->dma = S3CMCI_DMA; + host->irq_cd = IRQ_EINT2; + + 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 == 0) { + dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); + ret = -EINVAL; + goto probe_free_mem_region; + } + + host->irq = platform_get_irq(pdev, 0); + if (host->irq == 0) { + dev_err(&pdev->dev, "failed to get interrupt resouce.\n"); + ret = -EINVAL; + goto probe_iounmap; + } + + if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) { + dev_err(&pdev->dev, "failed to request mci interrupt.\n"); + ret = -ENOENT; + goto probe_iounmap; + } + + /* We get spurious interrupts even when we have set the IMSK + * register to ignore everything, so use disable_irq() to make + * ensure we don't lock the system with un-serviceable requests. */ + + disable_irq(host->irq); + + s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2); + set_irq_type(host->irq_cd, IRQT_BOTHEDGE); + + if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { + dev_err(&pdev->dev, + "failed to request card detect interrupt.\n"); + ret = -ENOENT; + goto probe_free_irq; + } + + if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) { + dev_err(&pdev->dev, "unable to get DMA channel.\n"); + ret = -EBUSY; + goto probe_free_irq_cd; + } + + host->clk = clk_get(&pdev->dev, "sdi"); + if (IS_ERR(host->clk)) { + dev_err(&pdev->dev, "failed to find clock source.\n"); + ret = PTR_ERR(host->clk); + host->clk = NULL; + goto probe_free_host; + } + + ret = clk_enable(host->clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock source.\n"); + goto clk_free; + } + + host->clk_rate = clk_get_rate(host->clk); + + mmc->ops = &s3cmci_ops; + mmc->ocr_avail = MMC_VDD_32_33; + mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->f_min = host->clk_rate / (host->clk_div * 256); + mmc->f_max = host->clk_rate / host->clk_div; + + mmc->max_blk_count = 4095; + mmc->max_blk_size = 4095; + mmc->max_req_size = 4095 * 512; + mmc->max_seg_size = mmc->max_req_size; + + mmc->max_phys_segs = 128; + mmc->max_hw_segs = 128; + + dbg(host, dbg_debug, + "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n", + (host->is2440?"2440":""), + host->base, host->irq, host->irq_cd, host->dma); + + ret = mmc_add_host(mmc); + if (ret) { + dev_err(&pdev->dev, "failed to add mmc host.\n"); + goto free_dmabuf; + } + + platform_set_drvdata(pdev, mmc); + dev_info(&pdev->dev, "initialisation done.\n"); + + return 0; + + free_dmabuf: + clk_disable(host->clk); + + clk_free: + clk_put(host->clk); + + probe_free_irq_cd: + free_irq(host->irq_cd, host); + + probe_free_irq: + free_irq(host->irq, host); + + 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 __devexit s3cmci_remove(struct platform_device *pdev) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct s3cmci_host *host = mmc_priv(mmc); + + mmc_remove_host(mmc); + + clk_disable(host->clk); + clk_put(host->clk); + + tasklet_disable(&host->pio_tasklet); + + free_irq(host->irq_cd, host); + free_irq(host->irq, host); + + iounmap(host->base); + release_mem_region(host->mem->start, RESSIZE(host->mem)); + + mmc_free_host(mmc); + return 0; +} + +static int __devinit s3cmci_probe_2410(struct platform_device *dev) +{ + return s3cmci_probe(dev, 0); +} + +static int __devinit s3cmci_probe_2412(struct platform_device *dev) +{ + return s3cmci_probe(dev, 1); +} + +static int __devinit s3cmci_probe_2440(struct platform_device *dev) +{ + return s3cmci_probe(dev, 1); +} + +#ifdef CONFIG_PM + +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); +} + +static int s3cmci_resume(struct platform_device *dev) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + + return mmc_resume_host(mmc); +} + +#else /* CONFIG_PM */ +#define s3cmci_suspend NULL +#define s3cmci_resume NULL +#endif /* CONFIG_PM */ + + +static struct platform_driver s3cmci_driver_2410 = { + .driver.name = "s3c2410-sdi", + .driver.owner = THIS_MODULE, + .probe = s3cmci_probe_2410, + .remove = __devexit_p(s3cmci_remove), + .suspend = s3cmci_suspend, + .resume = s3cmci_resume, +}; + +static struct platform_driver s3cmci_driver_2412 = { + .driver.name = "s3c2412-sdi", + .driver.owner = THIS_MODULE, + .probe = s3cmci_probe_2412, + .remove = __devexit_p(s3cmci_remove), + .suspend = s3cmci_suspend, + .resume = s3cmci_resume, +}; + +static struct platform_driver s3cmci_driver_2440 = { + .driver.name = "s3c2440-sdi", + .driver.owner = THIS_MODULE, + .probe = s3cmci_probe_2440, + .remove = __devexit_p(s3cmci_remove), + .suspend = s3cmci_suspend, + .resume = s3cmci_resume, +}; + + +static int __init s3cmci_init(void) +{ + platform_driver_register(&s3cmci_driver_2410); + platform_driver_register(&s3cmci_driver_2412); + platform_driver_register(&s3cmci_driver_2440); + return 0; +} + +static void __exit s3cmci_exit(void) +{ + platform_driver_unregister(&s3cmci_driver_2410); + platform_driver_unregister(&s3cmci_driver_2412); + platform_driver_unregister(&s3cmci_driver_2440); +} + +module_init(s3cmci_init); +module_exit(s3cmci_exit); + +MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Thomas Kleffel "); diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h new file mode 100644 index 0000000..90b8af7 --- /dev/null +++ b/drivers/mmc/host/s3cmci.h @@ -0,0 +1,69 @@ +/* + * linux/drivers/mmc/s3cmci.h - Samsung S3C MCI 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. + */ + +/* FIXME: DMA Resource management ?! */ +#define S3CMCI_DMA 0 + +enum s3cmci_waitfor { + COMPLETION_NONE, + COMPLETION_FINALIZE, + COMPLETION_CMDSENT, + COMPLETION_RSPFIN, + COMPLETION_XFERFINISH, + COMPLETION_XFERFINISH_RSPFIN, +}; + +struct s3cmci_host { + struct platform_device *pdev; + struct mmc_host *mmc; + struct resource *mem; + struct clk *clk; + void __iomem *base; + int irq; + int irq_cd; + int dma; + + unsigned long clk_rate; + unsigned long clk_div; + unsigned long real_rate; + u8 prescaler; + + int is2440; + unsigned sdiimsk; + unsigned sdidata; + int dodma; + int dmatogo; + + struct mmc_request *mrq; + int cmd_is_stop; + + spinlock_t complete_lock; + enum s3cmci_waitfor complete_what; + + int dma_complete; + + u32 pio_sgptr; + u32 pio_words; + u32 pio_count; + u32 *pio_ptr; +#define XFER_NONE 0 +#define XFER_READ 1 +#define XFER_WRITE 2 + u32 pio_active; + + int bus_width; + + char dbgmsg_cmd[301]; + char dbgmsg_dat[301]; + char *status; + + unsigned int ccnt, dcnt; + struct tasklet_struct pio_tasklet; +}; diff --git a/include/asm-arm/arch-s3c2410/regs-sdi.h b/include/asm-arm/arch-s3c2410/regs-sdi.h index bb9d30b..bfb222f 100644 --- a/include/asm-arm/arch-s3c2410/regs-sdi.h +++ b/include/asm-arm/arch-s3c2410/regs-sdi.h @@ -28,9 +28,15 @@ #define S3C2410_SDIDCNT (0x30) #define S3C2410_SDIDSTA (0x34) #define S3C2410_SDIFSTA (0x38) + #define S3C2410_SDIDATA (0x3C) #define S3C2410_SDIIMSK (0x40) +#define S3C2440_SDIDATA (0x40) +#define S3C2440_SDIIMSK (0x3C) + +#define S3C2440_SDICON_SDRESET (1<<8) +#define S3C2440_SDICON_MMCCLOCK (1<<5) #define S3C2410_SDICON_BYTEORDER (1<<4) #define S3C2410_SDICON_SDIOIRQ (1<<3) #define S3C2410_SDICON_RWAITEN (1<<2) @@ -42,7 +48,8 @@ #define S3C2410_SDICMDCON_LONGRSP (1<<10) #define S3C2410_SDICMDCON_WAITRSP (1<<9) #define S3C2410_SDICMDCON_CMDSTART (1<<8) -#define S3C2410_SDICMDCON_INDEX (0xff) +#define S3C2410_SDICMDCON_SENDERHOST (1<<6) +#define S3C2410_SDICMDCON_INDEX (0x3f) #define S3C2410_SDICMDSTAT_CRCFAIL (1<<12) #define S3C2410_SDICMDSTAT_CMDSENT (1<<11) @@ -51,6 +58,9 @@ #define S3C2410_SDICMDSTAT_XFERING (1<<8) #define S3C2410_SDICMDSTAT_INDEX (0xff) +#define S3C2440_SDIDCON_DS_BYTE (0<<22) +#define S3C2440_SDIDCON_DS_HALFWORD (1<<22) +#define S3C2440_SDIDCON_DS_WORD (2<<22) #define S3C2410_SDIDCON_IRQPERIOD (1<<21) #define S3C2410_SDIDCON_TXAFTERRESP (1<<20) #define S3C2410_SDIDCON_RXAFTERCMD (1<<19) @@ -59,6 +69,7 @@ #define S3C2410_SDIDCON_WIDEBUS (1<<16) #define S3C2410_SDIDCON_DMAEN (1<<15) #define S3C2410_SDIDCON_STOP (1<<14) +#define S3C2440_SDIDCON_DATSTART (1<<14) #define S3C2410_SDIDCON_DATMODE (3<<12) #define S3C2410_SDIDCON_BLKNUM (0x7ff) @@ -68,6 +79,7 @@ #define S3C2410_SDIDCON_XFER_RXSTART (2<<12) #define S3C2410_SDIDCON_XFER_TXSTART (3<<12) +#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) #define S3C2410_SDIDCNT_BLKNUM_SHIFT (12) #define S3C2410_SDIDSTA_RDYWAITREQ (1<<10) @@ -82,10 +94,12 @@ #define S3C2410_SDIDSTA_TXDATAON (1<<1) #define S3C2410_SDIDSTA_RXDATAON (1<<0) +#define S3C2440_SDIFSTA_FIFORESET (1<<16) +#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */ #define S3C2410_SDIFSTA_TFDET (1<<13) #define S3C2410_SDIFSTA_RFDET (1<<12) -#define S3C2410_SDIFSTA_TXHALF (1<<11) -#define S3C2410_SDIFSTA_TXEMPTY (1<<10) +#define S3C2410_SDIFSTA_TFHALF (1<<11) +#define S3C2410_SDIFSTA_TFEMPTY (1<<10) #define S3C2410_SDIFSTA_RFLAST (1<<9) #define S3C2410_SDIFSTA_RFFULL (1<<8) #define S3C2410_SDIFSTA_RFHALF (1<<7) -- cgit v0.10.2 From 679f0f8abd7187baaff40a47fe4733ae4c24cc9a Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 30 Jun 2008 22:40:25 +0100 Subject: MMC: S3C24XX MMC/SD driver write fixes This patch is a workaround of some S3C2410 MMC chip bug Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index c6a4d3c..4db5bd7 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -461,9 +461,19 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id) if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) { if (cmd->flags & MMC_RSP_CRC) { - cmd->error = -EILSEQ; - host->status = "error: bad command crc"; - goto fail_transfer; + if (host->mrq->cmd->flags & MMC_RSP_136) { + dbg(host, dbg_irq, + "fixup: ignore CRC fail with long rsp\n"); + } else { + /* note, we used to fail the transfer + * here, but it seems that this is just + * the hardware getting it wrong. + * + * cmd->error = -EILSEQ; + * host->status = "error: bad command crc"; + * goto fail_transfer; + */ + } } mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL; -- cgit v0.10.2 From ceb3ac252519f9ab318050c8ee842e62820d6731 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 30 Jun 2008 22:40:26 +0100 Subject: MMC: DMA free fix for S3C24XX SD/MMC driver Bugfix to ensure DMA channel allocated is freed on exit. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 4db5bd7..6070f36 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1254,6 +1254,7 @@ static int __devexit s3cmci_remove(struct platform_device *pdev) clk_put(host->clk); tasklet_disable(&host->pio_tasklet); + s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client); free_irq(host->irq_cd, host); free_irq(host->irq, host); -- cgit v0.10.2 From bdbc9c3a8f7a7956611c970e262693faa95081a5 Mon Sep 17 00:00:00 2001 From: Thomas Kleffel Date: Mon, 30 Jun 2008 22:40:27 +0100 Subject: Fix the request finalisation by ensuring the controller is stopped. Signed-off-by: Ben Dooks Signed-off-by: Harald Welte Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6070f36..8c68b2e 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -677,7 +677,7 @@ static void finalize_request(struct s3cmci_host *host) /* Cleanup controller */ writel(0, host->base + S3C2410_SDICMDARG); - writel(0, host->base + S3C2410_SDIDCON); + writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON); writel(0, host->base + S3C2410_SDICMDCON); writel(0, host->base + host->sdiimsk); @@ -803,7 +803,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) dbg(host, dbg_err, "mci_setup_data() transfer stillin progress.\n"); - writel(0, host->base + S3C2410_SDIDCON); + writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON); s3cmci_reset(host); if ((stoptries--) == 0) { -- cgit v0.10.2 From d643b5f7e0793ef7828a35a5ea049d675ad2ad8c Mon Sep 17 00:00:00 2001 From: Roman Moracik Date: Mon, 30 Jun 2008 22:40:28 +0100 Subject: MMC: Fix S3C24XX IRQ enable during PIO transfers Fix Bug #677 - I/O errors on heavy microSD writes for 2.6.22.x. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 8c68b2e..774af3d 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -335,6 +335,8 @@ static void pio_tasklet(unsigned long data) struct s3cmci_host *host = (struct s3cmci_host *) data; + disable_irq(host->irq); + if (host->pio_active == XFER_WRITE) do_pio_write(host); @@ -352,9 +354,9 @@ static void pio_tasklet(unsigned long data) host->mrq->data->error = -EINVAL; } - disable_irq(host->irq); finalize_request(host); - } + } else + enable_irq(host->irq); } /* @@ -630,7 +632,6 @@ out: spin_unlock_irqrestore(&host->complete_lock, iflags); return; - fail_request: host->mrq->data->error = -EINVAL; host->complete_what = COMPLETION_FINALIZE; -- cgit v0.10.2 From edb5a98e43682d66c98ddd1dee863d867807546e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:29 +0100 Subject: MMC: S3C24XX: Add platform data for MMC/SD driver This patch adds platform data support to the s3mci driver. This allows flexible board-specific configuration of set_power, card detect and read only pins. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 774af3d..684a10c 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -21,6 +21,8 @@ #include #include +#include + #include "s3cmci.h" #define DRIVER_NAME "s3c-mci" @@ -1011,6 +1013,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2); s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3); + if (host->pdata->set_power) + host->pdata->set_power(ios->power_mode, ios->vdd); + if (!host->is2440) mci_con |= S3C2410_SDICON_FIFORESET; @@ -1024,6 +1029,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->is2440) mci_con |= S3C2440_SDICON_SDRESET; + if (host->pdata->set_power) + host->pdata->set_power(ios->power_mode, ios->vdd); + break; } @@ -1072,9 +1080,25 @@ static void s3cmci_reset(struct s3cmci_host *host) writel(con, host->base + S3C2410_SDICON); } +static int s3cmci_get_ro(struct mmc_host *mmc) +{ + struct s3cmci_host *host = mmc_priv(mmc); + + if (host->pdata->gpio_wprotect == 0) + return 0; + + return s3c2410_gpio_getpin(host->pdata->gpio_wprotect); +} + static struct mmc_host_ops s3cmci_ops = { .request = s3cmci_request, .set_ios = s3cmci_set_ios, + .get_ro = s3cmci_get_ro, +}; + +static struct s3c24xx_mci_pdata s3cmci_def_pdata = { + /* This is currently here to avoid a number of if (host->pdata) + * checks. Any zero fields to ensure reaonable defaults are picked. */ }; static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) @@ -1094,6 +1118,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->pdev = pdev; host->is2440 = is2440; + host->pdata = pdev->dev.platform_data; + if (!host->pdata) { + pdev->dev.platform_data = &s3cmci_def_pdata; + host->pdata = &s3cmci_def_pdata; + } + spin_lock_init(&host->complete_lock); tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); @@ -1112,7 +1142,8 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->pio_active = XFER_NONE; host->dma = S3CMCI_DMA; - host->irq_cd = IRQ_EINT2; + host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); + s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!host->mem) { @@ -1158,7 +1189,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) disable_irq(host->irq); - s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2); + s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); set_irq_type(host->irq_cd, IRQT_BOTHEDGE); if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { @@ -1168,6 +1199,10 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) goto probe_free_irq; } + if (host->pdata->gpio_wprotect) + s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect, + S3C2410_GPIO_INPUT); + if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) { dev_err(&pdev->dev, "unable to get DMA channel.\n"); ret = -EBUSY; @@ -1191,11 +1226,14 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->clk_rate = clk_get_rate(host->clk); mmc->ops = &s3cmci_ops; - mmc->ocr_avail = MMC_VDD_32_33; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->caps = MMC_CAP_4_BIT_DATA; mmc->f_min = host->clk_rate / (host->clk_div * 256); mmc->f_max = host->clk_rate / host->clk_div; + if (host->pdata->ocr_avail) + mmc->ocr_avail = host->pdata->ocr_avail; + mmc->max_blk_count = 4095; mmc->max_blk_size = 4095; mmc->max_req_size = 4095 * 512; diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h index 90b8af7..37d9c60 100644 --- a/drivers/mmc/host/s3cmci.h +++ b/drivers/mmc/host/s3cmci.h @@ -22,6 +22,7 @@ enum s3cmci_waitfor { struct s3cmci_host { struct platform_device *pdev; + struct s3c24xx_mci_pdata *pdata; struct mmc_host *mmc; struct resource *mem; struct clk *clk; diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h new file mode 100644 index 0000000..5be2c14 --- /dev/null +++ b/include/asm-arm/plat-s3c24xx/mci.h @@ -0,0 +1,12 @@ +#ifndef _ARCH_MCI_H +#define _ARCH_MCI_H + +struct s3c24xx_mci_pdata { + unsigned int gpio_detect; + unsigned int gpio_wprotect; + unsigned long ocr_avail; + void (*set_power)(unsigned char power_mode, + unsigned short vdd); +}; + +#endif /* _ARCH_NCI_H */ -- cgit v0.10.2 From cf0984c8edf63017fcc2ead212ca057877e345df Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:30 +0100 Subject: MMC: S3C24XX: Add support to invert write protect line Support for inverting the sense of the MMC driver's write protect detection line. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 684a10c..4fd11d8 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1083,11 +1083,18 @@ static void s3cmci_reset(struct s3cmci_host *host) static int s3cmci_get_ro(struct mmc_host *mmc) { struct s3cmci_host *host = mmc_priv(mmc); + struct s3c24xx_mci_pdata *pdata = host->pdata; + int ret; - if (host->pdata->gpio_wprotect == 0) + if (pdata->gpio_wprotect == 0) return 0; - return s3c2410_gpio_getpin(host->pdata->gpio_wprotect); + ret = s3c2410_gpio_getpin(pdata->gpio_wprotect); + + if (pdata->wprotect_invert) + ret = !ret; + + return ret; } static struct mmc_host_ops s3cmci_ops = { diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h index 5be2c14..4f4ccd1 100644 --- a/include/asm-arm/plat-s3c24xx/mci.h +++ b/include/asm-arm/plat-s3c24xx/mci.h @@ -2,6 +2,8 @@ #define _ARCH_MCI_H struct s3c24xx_mci_pdata { + unsigned int wprotect_invert : 1; + unsigned int gpio_detect; unsigned int gpio_wprotect; unsigned long ocr_avail; -- cgit v0.10.2 From 7c14450ed6ab4ed453b2bf216ca3aaa7a5402af3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:31 +0100 Subject: MMC: S3C24XX: Ensure host->mrq->data is valid Fix a crash if host->mrq->data is NULL on ending a transfer. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 4fd11d8..ffd9269 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -353,7 +353,8 @@ static void pio_tasklet(unsigned long data) (host->pio_active == XFER_READ) ? "read" : "write", host->pio_count, host->pio_words); - host->mrq->data->error = -EINVAL; + if (host->mrq->data) + host->mrq->data->error = -EINVAL; } finalize_request(host); -- cgit v0.10.2 From 55d70f5a7b25800fc8376cdd81d42d6c201fa91d Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:32 +0100 Subject: MMC: S3C24XX: Allow card-detect on non-IRQ capable pin Add support to the S3C24XX MMC driver to have the card detect be on a pin that is not IRQ capable. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index ffd9269..aa9a8b4 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1150,8 +1150,6 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->pio_active = XFER_NONE; host->dma = S3CMCI_DMA; - host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); - s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!host->mem) { @@ -1197,14 +1195,20 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) disable_irq(host->irq); - s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); - set_irq_type(host->irq_cd, IRQT_BOTHEDGE); + host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); - if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { - dev_err(&pdev->dev, - "failed to request card detect interrupt.\n"); - ret = -ENOENT; - goto probe_free_irq; + if (host->irq_cd >= 0) { + if (request_irq(host->irq_cd, s3cmci_irq_cd, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + DRIVER_NAME, host)) { + dev_err(&pdev->dev, "can't get card detect irq.\n"); + ret = -ENOENT; + goto probe_free_irq; + } + } else { + dev_warn(&pdev->dev, "host detect has no irq available\n"); + s3c2410_gpio_cfgpin(host->pdata->gpio_detect, + S3C2410_GPIO_INPUT); } if (host->pdata->gpio_wprotect) @@ -1273,7 +1277,8 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) clk_put(host->clk); probe_free_irq_cd: - free_irq(host->irq_cd, host); + if (host->irq_cd >= 0) + free_irq(host->irq_cd, host); probe_free_irq: free_irq(host->irq, host); @@ -1303,7 +1308,8 @@ static int __devexit s3cmci_remove(struct platform_device *pdev) tasklet_disable(&host->pio_tasklet); s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client); - free_irq(host->irq_cd, host); + if (host->irq_cd >= 0) + free_irq(host->irq_cd, host); free_irq(host->irq, host); iounmap(host->base); -- cgit v0.10.2 From 3886ff5f63f33c801ed3af265ac0df20d3a8dcf5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:33 +0100 Subject: MMC: S3C24XX: Fix s3c2410_dma_request() return code check. The driver should be checking for a negative error code from s3c2410_dma_request(), not non-zero. Newer kernels now return the DMA channel number that was allocated by the request. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index aa9a8b4..8389107 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1215,7 +1215,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect, S3C2410_GPIO_INPUT); - if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) { + if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) { dev_err(&pdev->dev, "unable to get DMA channel.\n"); ret = -EBUSY; goto probe_free_irq_cd; -- cgit v0.10.2 From 318f905f02b427b8df33d724b7392a0597b40bdd Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:34 +0100 Subject: MMC: S3C24XX: Add MODULE_ALIAS() entries for the platform devices Add MODULE_ALIAS() declerations for all the supported platform devices for this driver. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 8389107..a6224f9 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1405,3 +1405,6 @@ module_exit(s3cmci_exit); MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Thomas Kleffel "); +MODULE_ALIAS("platform:s3c2410-sdi"); +MODULE_ALIAS("platform:s3c2412-sdi"); +MODULE_ALIAS("platform:s3c2440-sdi"); -- cgit v0.10.2 From 2de5f79d4dfcb1be16f0b873bc77d6ec74b0426d Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:35 +0100 Subject: MMC: S3C24XX: Fix use of msecs where jiffies are needed mmc_detect_change() takes jiffies, not msecs. Convert the previous value of msecs into jiffies before calling. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index a6224f9..6f1b474 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -584,7 +584,7 @@ static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id) dbg(host, dbg_irq, "card detect\n"); - mmc_detect_change(host->mmc, 500); + mmc_detect_change(host->mmc, msecs_to_jiffies(500)); return IRQ_HANDLED; } -- cgit v0.10.2 From 50a845700b3b55f825b0eb901b03d6091f66d9f4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:36 +0100 Subject: MMC: S3C24XX: Add media presence test to request handling. Ensure that we have physical media present before attempting to send a request to a card. This ensures that we do not get flooded by errors from commands that can never be completed timing out. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6f1b474..62d73d3 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -984,6 +984,18 @@ static void s3cmci_send_request(struct mmc_host *mmc) enable_irq(host->irq); } +static int s3cmci_card_present(struct s3cmci_host *host) +{ + struct s3c24xx_mci_pdata *pdata = host->pdata; + int ret; + + if (pdata->gpio_detect == 0) + return -ENOSYS; + + ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1; + return ret ^ pdata->detect_invert; +} + static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct s3cmci_host *host = mmc_priv(mmc); @@ -992,7 +1004,12 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->cmd_is_stop = 0; host->mrq = mrq; - s3cmci_send_request(mmc); + if (s3cmci_card_present(host) == 0) { + dbg(host, dbg_err, "%s: no medium present\n", __func__); + host->mrq->cmd->error = -ENOMEDIUM; + mmc_request_done(mmc, mrq); + } else + s3cmci_send_request(mmc); } static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h index 4f4ccd1..2d0852a 100644 --- a/include/asm-arm/plat-s3c24xx/mci.h +++ b/include/asm-arm/plat-s3c24xx/mci.h @@ -3,6 +3,7 @@ struct s3c24xx_mci_pdata { unsigned int wprotect_invert : 1; + unsigned int detect_invert : 1; /* set => detect active high. */ unsigned int gpio_detect; unsigned int gpio_wprotect; -- cgit v0.10.2 From ff8c804f1fdecb198c4be57155c61800e0d37bd2 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:37 +0100 Subject: MMC: S3C24XX: Update error debugging. Add better debugging to show where errors are being generated, as some error codes can come from several different code paths. Also fix the error return path from s3cmci_setup_data() to return the error it returned to the request. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 62d73d3..2b48395 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -450,6 +450,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id) } if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) { + dbg(host, dbg_err, "CMDSTAT: error CMDTIMEOUT\n"); cmd->error = -ETIMEDOUT; host->status = "error: command timeout"; goto fail_transfer; @@ -505,12 +506,14 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id) /* Check for FIFO failure */ if (host->is2440) { if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) { + dbg(host, dbg_err, "FIFO failure\n"); host->mrq->data->error = -EILSEQ; host->status = "error: 2440 fifo failure"; goto fail_transfer; } } else { if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) { + dbg(host, dbg_err, "FIFO failure\n"); cmd->data->error = -EILSEQ; host->status = "error: fifo failure"; goto fail_transfer; @@ -518,18 +521,21 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id) } if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) { + dbg(host, dbg_err, "bad data crc (outgoing)\n"); cmd->data->error = -EILSEQ; host->status = "error: bad data crc (outgoing)"; goto fail_transfer; } if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) { + dbg(host, dbg_err, "bad data crc (incoming)\n"); cmd->data->error = -EILSEQ; host->status = "error: bad data crc (incoming)"; goto fail_transfer; } if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) { + dbg(host, dbg_err, "data timeout\n"); cmd->data->error = -ETIMEDOUT; host->status = "error: data timeout"; goto fail_transfer; @@ -956,8 +962,9 @@ static void s3cmci_send_request(struct mmc_host *mmc) host->dcnt++; if (res) { - cmd->error = -EINVAL; - cmd->data->error = -EINVAL; + dbg(host, dbg_err, "setup data error %d\n", res); + cmd->error = res; + cmd->data->error = res; mmc_request_done(mmc, mrq); return; @@ -969,6 +976,7 @@ static void s3cmci_send_request(struct mmc_host *mmc) res = s3cmci_prepare_pio(host, cmd->data); if (res) { + dbg(host, dbg_err, "data prepare error %d\n", res); cmd->error = res; cmd->data->error = res; -- cgit v0.10.2 From 4dde7f755211fd58105c989a99a3a9f2f1238fba Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:38 +0100 Subject: MMC: S3C24XX: Add maintainer entry Add Ben Dooks as S3C24XX SD/MMC driver maintainer. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/MAINTAINERS b/MAINTAINERS index f140449..9def20a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3530,6 +3530,13 @@ L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ S: Supported +S3C24XX SD/MMC Driver +P: Ben Dooks +M: ben-linux@fluff.org +L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) +L: linux-kernel@vger.kernel.org +S: Supported + SAA7146 VIDEO4LINUX-2 DRIVER P: Michael Hunold M: michael@mihu.de -- cgit v0.10.2 From 7e9c7b64022b7faff6022df64baec8ab467d0bfd Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:39 +0100 Subject: MMC: S3C24XX: Refuse incorrectly aligned transfers The hardware does not support any multi-block transfers with an block-size that is not 32bit aligned. Also the driver itself does not support single block non-32bit transfers either. Ensure that the s3cmci_setup_data() returns the appropriate error if we encounter this. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 2b48395..6a1e499 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -807,6 +807,17 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) return 0; } + if ((data->blksz & 3) != 0) { + /* We cannot deal with unaligned blocks with more than + * one block being transfered. */ + + if (data->blocks > 1) + return -EINVAL; + + /* No support yet for non-word block transfers. */ + return -EINVAL; + } + while (readl(host->base + S3C2410_SDIDSTA) & (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) { -- cgit v0.10.2 From 9eeebd22ca757fee8dc10ffe6fa6992f33a3c5ec Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 30 Jun 2008 10:50:23 +0300 Subject: mmc: wbsd.c fix shadowing of 'dma' variable This patch fix warning :shadowing dma variable and made use of module_param_named instead of module_param Signed-off-by: Tomas Winkler Acked-by: Marcel Holtmann Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 67e5a9b..c2b6160 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -68,16 +68,16 @@ static const int unlock_codes[] = { 0x83, 0x87 }; static const int valid_ids[] = { 0x7112, - }; +}; #ifdef CONFIG_PNP -static unsigned int nopnp = 0; +static unsigned int param_nopnp = 0; #else -static const unsigned int nopnp = 1; +static const unsigned int param_nopnp = 1; #endif -static unsigned int io = 0x248; -static unsigned int irq = 6; -static int dma = 2; +static unsigned int param_io = 0x248; +static unsigned int param_irq = 6; +static int param_dma = 2; /* * Basic functions @@ -1765,7 +1765,7 @@ static void __devexit wbsd_shutdown(struct device *dev, int pnp) static int __devinit wbsd_probe(struct platform_device *dev) { /* Use the module parameters for resources */ - return wbsd_init(&dev->dev, io, irq, dma, 0); + return wbsd_init(&dev->dev, param_io, param_irq, param_dma, 0); } static int __devexit wbsd_remove(struct platform_device *dev) @@ -1979,14 +1979,14 @@ static int __init wbsd_drv_init(void) #ifdef CONFIG_PNP - if (!nopnp) { + if (!param_nopnp) { result = pnp_register_driver(&wbsd_pnp_driver); if (result < 0) return result; } #endif /* CONFIG_PNP */ - if (nopnp) { + if (param_nopnp) { result = platform_driver_register(&wbsd_driver); if (result < 0) return result; @@ -2012,12 +2012,12 @@ static void __exit wbsd_drv_exit(void) { #ifdef CONFIG_PNP - if (!nopnp) + if (!param_nopnp) pnp_unregister_driver(&wbsd_pnp_driver); #endif /* CONFIG_PNP */ - if (nopnp) { + if (param_nopnp) { platform_device_unregister(wbsd_device); platform_driver_unregister(&wbsd_driver); @@ -2029,11 +2029,11 @@ static void __exit wbsd_drv_exit(void) module_init(wbsd_drv_init); module_exit(wbsd_drv_exit); #ifdef CONFIG_PNP -module_param(nopnp, uint, 0444); +module_param_named(nopnp, param_nopnp, uint, 0444); #endif -module_param(io, uint, 0444); -module_param(irq, uint, 0444); -module_param(dma, int, 0444); +module_param_named(io, param_io, uint, 0444); +module_param_named(irq, param_irq, uint, 0444); +module_param_named(dma, param_dma, int, 0444); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Pierre Ossman "); -- cgit v0.10.2 From 6d37333163025b46afbcad434ec9a5f2e88e7254 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 30 Jun 2008 10:50:24 +0300 Subject: mmc: fix sdio_io sparse errors This patch fixes sdio_io sparse errors. This fix changes signature of API functions, changing unsigned char -> u8 unsigned short -> u16 unsigned long -> u32 - this was probably a bug in 64 bit platforms Signed-off-by: Tomas Winkler Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c old mode 100644 new mode 100755 index cc42a41..3ccf691 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -167,10 +167,8 @@ int sdio_set_block_size(struct sdio_func *func, unsigned blksz) return -EINVAL; if (blksz == 0) { - blksz = min(min( - func->max_blksize, - func->card->host->max_blk_size), - 512u); + blksz = min(func->max_blksize, func->card->host->max_blk_size); + blksz = min(blksz, 512u); } ret = mmc_io_rw_direct(func->card, 1, 0, @@ -311,10 +309,9 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, /* Blocks per command is limited by host count, host transfer * size (we only use a single sg entry) and the maximum for * IO_RW_EXTENDED of 511 blocks. */ - max_blocks = min(min( - func->card->host->max_blk_count, - func->card->host->max_seg_size / func->cur_blksize), - 511u); + max_blocks = min(func->card->host->max_blk_count, + func->card->host->max_seg_size / func->cur_blksize); + max_blocks = min(max_blocks, 511u); while (remainder > func->cur_blksize) { unsigned blocks; @@ -364,11 +361,10 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, * function. If there is a problem reading the address, 0xff * is returned and @err_ret will contain the error code. */ -unsigned char sdio_readb(struct sdio_func *func, unsigned int addr, - int *err_ret) +u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret) { int ret; - unsigned char val; + u8 val; BUG_ON(!func); @@ -397,8 +393,7 @@ EXPORT_SYMBOL_GPL(sdio_readb); * function. @err_ret will contain the status of the actual * transfer. */ -void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, - int *err_ret) +void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret) { int ret; @@ -459,7 +454,6 @@ int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr, { return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count); } - EXPORT_SYMBOL_GPL(sdio_readsb); /** @@ -489,8 +483,7 @@ EXPORT_SYMBOL_GPL(sdio_writesb); * function. If there is a problem reading the address, 0xffff * is returned and @err_ret will contain the error code. */ -unsigned short sdio_readw(struct sdio_func *func, unsigned int addr, - int *err_ret) +u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret) { int ret; @@ -504,7 +497,7 @@ unsigned short sdio_readw(struct sdio_func *func, unsigned int addr, return 0xFFFF; } - return le16_to_cpu(*(u16*)func->tmpbuf); + return le16_to_cpup((__le16 *)func->tmpbuf); } EXPORT_SYMBOL_GPL(sdio_readw); @@ -519,12 +512,11 @@ EXPORT_SYMBOL_GPL(sdio_readw); * function. @err_ret will contain the status of the actual * transfer. */ -void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr, - int *err_ret) +void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret) { int ret; - *(u16*)func->tmpbuf = cpu_to_le16(b); + *(__le16 *)func->tmpbuf = cpu_to_le16(b); ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2); if (err_ret) @@ -543,8 +535,7 @@ EXPORT_SYMBOL_GPL(sdio_writew); * 0xffffffff is returned and @err_ret will contain the error * code. */ -unsigned long sdio_readl(struct sdio_func *func, unsigned int addr, - int *err_ret) +u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret) { int ret; @@ -558,7 +549,7 @@ unsigned long sdio_readl(struct sdio_func *func, unsigned int addr, return 0xFFFFFFFF; } - return le32_to_cpu(*(u32*)func->tmpbuf); + return le32_to_cpup((__le32 *)func->tmpbuf); } EXPORT_SYMBOL_GPL(sdio_readl); @@ -573,12 +564,11 @@ EXPORT_SYMBOL_GPL(sdio_readl); * function. @err_ret will contain the status of the actual * transfer. */ -void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr, - int *err_ret) +void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret) { int ret; - *(u32*)func->tmpbuf = cpu_to_le32(b); + *(__le32 *)func->tmpbuf = cpu_to_le32(b); ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4); if (err_ret) diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h old mode 100644 new mode 100755 index f57f22b..28fb0a3 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -122,23 +122,20 @@ extern int sdio_release_irq(struct sdio_func *func); extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz); -extern unsigned char sdio_readb(struct sdio_func *func, - unsigned int addr, int *err_ret); -extern unsigned short sdio_readw(struct sdio_func *func, - unsigned int addr, int *err_ret); -extern unsigned long sdio_readl(struct sdio_func *func, - unsigned int addr, int *err_ret); +extern u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret); +extern u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret); +extern u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret); extern int sdio_memcpy_fromio(struct sdio_func *func, void *dst, unsigned int addr, int count); extern int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr, int count); -extern void sdio_writeb(struct sdio_func *func, unsigned char b, +extern void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret); -extern void sdio_writew(struct sdio_func *func, unsigned short b, +extern void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret); -extern void sdio_writel(struct sdio_func *func, unsigned long b, +extern void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret); extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr, -- cgit v0.10.2 From 7d2be0749a59096a334c94dc48f43294193cb8ed Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 30 Jun 2008 18:35:03 +0200 Subject: atmel-mci: Driver for Atmel on-chip MMC controllers This is a driver for the MMC controller on the AP7000 chips from Atmel. It should in theory work on AT91 systems too with some tweaking, but since the DMA interface is quite different, it's not entirely clear if it's worth merging this with the at91_mci driver. This driver has been around for a while in BSPs and kernel sources provided by Atmel, but this particular version uses the generic DMA Engine framework (with the slave extensions) instead of an avr32-only DMA controller framework. This driver can also use PIO transfers when no DMA channels are available, and for transfers where using DMA may be difficult or impractical for some reason (e.g. the DMA setup overhead is usually not worth it for very short transfers, and badly aligned buffers or lengths are difficult to handle.) Currently, the driver only support PIO transfers. DMA support has been split out to a separate patch to hopefully make it easier to review. The driver has been tested using mmc-block and ext3fs on several SD, SDHC and MMC+ cards. Reads and writes work fine, with read transfer rates up to 3.5 MiB/s on fast cards with debugging disabled. The driver has also been tested using the mmc_test module on the same cards. All tests except 7, 9, 15 and 17 succeed. The first two are unsupported by all the cards I have, so I don't know if the driver handles this correctly. The last two fail because the hardware flags a Data CRC Error instead of a Data Timeout error. I'm not sure how to deal with that. Documentation for this controller can be found in many data sheets from Atmel, including the AT32AP7000 data sheet which can be found here: http://www.atmel.com/dyn/products/datasheets.asp?family_id=682 Signed-off-by: Haavard Skinnemoen Signed-off-by: Pierre Ossman diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index a51bb9f..c7fe94d 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -51,6 +52,11 @@ static struct spi_board_info spi0_board_info[] __initdata = { }, }; +static struct mci_platform_data __initdata mci0_data = { + .detect_pin = GPIO_PIN_PC(25), + .wp_pin = GPIO_PIN_PE(0), +}; + /* * The next two functions should go away as the boot loader is * supposed to initialize the macb address registers with a valid @@ -170,6 +176,7 @@ static int __init atngw100_init(void) set_hw_addr(at32_add_device_eth(1, ð_data[1])); at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); + at32_add_device_mci(0, &mci0_data); at32_add_device_usba(0, NULL); for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) { diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 86b363c..e11659b 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -234,6 +234,9 @@ static int __init atstk1002_init(void) #ifdef CONFIG_BOARD_ATSTK100X_SPI1 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif +#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM + at32_add_device_mci(0, NULL); +#endif #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM set_hw_addr(at32_add_device_eth(1, ð_data[1])); #else diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 07b21b1..021d512 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -1278,20 +1279,32 @@ static struct clk atmel_mci0_pclk = { .index = 9, }; -struct platform_device *__init at32_add_device_mci(unsigned int id) +struct platform_device *__init +at32_add_device_mci(unsigned int id, struct mci_platform_data *data) { - struct platform_device *pdev; + struct mci_platform_data _data; + struct platform_device *pdev; + struct dw_dma_slave *dws; if (id != 0) return NULL; pdev = platform_device_alloc("atmel_mci", id); if (!pdev) - return NULL; + goto fail; if (platform_device_add_resources(pdev, atmel_mci0_resource, ARRAY_SIZE(atmel_mci0_resource))) - goto err_add_resources; + goto fail; + + if (!data) { + data = &_data; + memset(data, 0, sizeof(struct mci_platform_data)); + } + + if (platform_device_add_data(pdev, data, + sizeof(struct mci_platform_data))) + goto fail; select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ @@ -1300,12 +1313,19 @@ struct platform_device *__init at32_add_device_mci(unsigned int id) select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ + if (data) { + if (data->detect_pin != GPIO_PIN_NONE) + at32_select_gpio(data->detect_pin, 0); + if (data->wp_pin != GPIO_PIN_NONE) + at32_select_gpio(data->wp_pin, 0); + } + atmel_mci0_pclk.dev = &pdev->dev; platform_device_add(pdev); return pdev; -err_add_resources: +fail: platform_device_put(pdev); return NULL; } diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index dc88c03..198df42 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -104,6 +104,16 @@ config MMC_AT91 If unsure, say N. +config MMC_ATMELMCI + tristate "Atmel Multimedia Card Interface support" + depends on AVR32 + help + This selects the Atmel Multimedia Card Interface driver. If + you have an AT32 (AVR32) platform with a Multimedia Card + slot, say Y or M here. + + If unsure, say N. + config MMC_IMX tristate "Motorola i.MX Multimedia Card Interface support" depends on ARCH_IMX diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index b3e023b..2dc9ff2 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o obj-$(CONFIG_MMC_AT91) += at91_mci.o +obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o obj-$(CONFIG_MMC_S3C) += s3cmci.o diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h new file mode 100644 index 0000000..a9a5657 --- /dev/null +++ b/drivers/mmc/host/atmel-mci-regs.h @@ -0,0 +1,91 @@ +/* + * Atmel MultiMedia Card Interface driver + * + * Copyright (C) 2004-2006 Atmel Corporation + * + * 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 __DRIVERS_MMC_ATMEL_MCI_H__ +#define __DRIVERS_MMC_ATMEL_MCI_H__ + +/* MCI Register Definitions */ +#define MCI_CR 0x0000 /* Control */ +# define MCI_CR_MCIEN ( 1 << 0) /* MCI Enable */ +# define MCI_CR_MCIDIS ( 1 << 1) /* MCI Disable */ +# define MCI_CR_SWRST ( 1 << 7) /* Software Reset */ +#define MCI_MR 0x0004 /* Mode */ +# define MCI_MR_CLKDIV(x) ((x) << 0) /* Clock Divider */ +# define MCI_MR_RDPROOF ( 1 << 11) /* Read Proof */ +# define MCI_MR_WRPROOF ( 1 << 12) /* Write Proof */ +#define MCI_DTOR 0x0008 /* Data Timeout */ +# define MCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ +# define MCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ +#define MCI_SDCR 0x000c /* SD Card / SDIO */ +# define MCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */ +# define MCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */ +# define MCI_SDCBUS_1BIT ( 0 << 7) /* 1-bit data bus */ +# define MCI_SDCBUS_4BIT ( 1 << 7) /* 4-bit data bus */ +#define MCI_ARGR 0x0010 /* Command Argument */ +#define MCI_CMDR 0x0014 /* Command */ +# define MCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */ +# define MCI_CMDR_RSPTYP_NONE ( 0 << 6) /* No response */ +# define MCI_CMDR_RSPTYP_48BIT ( 1 << 6) /* 48-bit response */ +# define MCI_CMDR_RSPTYP_136BIT ( 2 << 6) /* 136-bit response */ +# define MCI_CMDR_SPCMD_INIT ( 1 << 8) /* Initialization command */ +# define MCI_CMDR_SPCMD_SYNC ( 2 << 8) /* Synchronized command */ +# define MCI_CMDR_SPCMD_INT ( 4 << 8) /* Interrupt command */ +# define MCI_CMDR_SPCMD_INTRESP ( 5 << 8) /* Interrupt response */ +# define MCI_CMDR_OPDCMD ( 1 << 11) /* Open Drain */ +# define MCI_CMDR_MAXLAT_5CYC ( 0 << 12) /* Max latency 5 cycles */ +# define MCI_CMDR_MAXLAT_64CYC ( 1 << 12) /* Max latency 64 cycles */ +# define MCI_CMDR_START_XFER ( 1 << 16) /* Start data transfer */ +# define MCI_CMDR_STOP_XFER ( 2 << 16) /* Stop data transfer */ +# define MCI_CMDR_TRDIR_WRITE ( 0 << 18) /* Write data */ +# define MCI_CMDR_TRDIR_READ ( 1 << 18) /* Read data */ +# define MCI_CMDR_BLOCK ( 0 << 19) /* Single-block transfer */ +# define MCI_CMDR_MULTI_BLOCK ( 1 << 19) /* Multi-block transfer */ +# define MCI_CMDR_STREAM ( 2 << 19) /* MMC Stream transfer */ +# define MCI_CMDR_SDIO_BYTE ( 4 << 19) /* SDIO Byte transfer */ +# define MCI_CMDR_SDIO_BLOCK ( 5 << 19) /* SDIO Block transfer */ +# define MCI_CMDR_SDIO_SUSPEND ( 1 << 24) /* SDIO Suspend Command */ +# define MCI_CMDR_SDIO_RESUME ( 2 << 24) /* SDIO Resume Command */ +#define MCI_BLKR 0x0018 /* Block */ +# define MCI_BCNT(x) ((x) << 0) /* Data Block Count */ +# define MCI_BLKLEN(x) ((x) << 16) /* Data Block Length */ +#define MCI_RSPR 0x0020 /* Response 0 */ +#define MCI_RSPR1 0x0024 /* Response 1 */ +#define MCI_RSPR2 0x0028 /* Response 2 */ +#define MCI_RSPR3 0x002c /* Response 3 */ +#define MCI_RDR 0x0030 /* Receive Data */ +#define MCI_TDR 0x0034 /* Transmit Data */ +#define MCI_SR 0x0040 /* Status */ +#define MCI_IER 0x0044 /* Interrupt Enable */ +#define MCI_IDR 0x0048 /* Interrupt Disable */ +#define MCI_IMR 0x004c /* Interrupt Mask */ +# define MCI_CMDRDY ( 1 << 0) /* Command Ready */ +# define MCI_RXRDY ( 1 << 1) /* Receiver Ready */ +# define MCI_TXRDY ( 1 << 2) /* Transmitter Ready */ +# define MCI_BLKE ( 1 << 3) /* Data Block Ended */ +# define MCI_DTIP ( 1 << 4) /* Data Transfer In Progress */ +# define MCI_NOTBUSY ( 1 << 5) /* Data Not Busy */ +# define MCI_SDIOIRQA ( 1 << 8) /* SDIO IRQ in slot A */ +# define MCI_SDIOIRQB ( 1 << 9) /* SDIO IRQ in slot B */ +# define MCI_RINDE ( 1 << 16) /* Response Index Error */ +# define MCI_RDIRE ( 1 << 17) /* Response Direction Error */ +# define MCI_RCRCE ( 1 << 18) /* Response CRC Error */ +# define MCI_RENDE ( 1 << 19) /* Response End Bit Error */ +# define MCI_RTOE ( 1 << 20) /* Response Time-Out Error */ +# define MCI_DCRCE ( 1 << 21) /* Data CRC Error */ +# define MCI_DTOE ( 1 << 22) /* Data Time-Out Error */ +# define MCI_OVRE ( 1 << 30) /* RX Overrun Error */ +# define MCI_UNRE ( 1 << 31) /* TX Underrun Error */ + +/* Register access macros */ +#define mci_readl(port,reg) \ + __raw_readl((port)->regs + MCI_##reg) +#define mci_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + MCI_##reg) + +#endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c new file mode 100644 index 0000000..25d5324a --- /dev/null +++ b/drivers/mmc/host/atmel-mci.c @@ -0,0 +1,981 @@ +/* + * Atmel MultiMedia Card Interface driver + * + * Copyright (C) 2004-2008 Atmel Corporation + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include "atmel-mci-regs.h" + +#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE) + +enum { + EVENT_CMD_COMPLETE = 0, + EVENT_DATA_ERROR, + EVENT_DATA_COMPLETE, + EVENT_STOP_SENT, + EVENT_STOP_COMPLETE, + EVENT_XFER_COMPLETE, +}; + +struct atmel_mci { + struct mmc_host *mmc; + void __iomem *regs; + + struct scatterlist *sg; + unsigned int pio_offset; + + struct mmc_request *mrq; + struct mmc_command *cmd; + struct mmc_data *data; + + u32 cmd_status; + u32 data_status; + u32 stop_status; + u32 stop_cmdr; + + u32 mode_reg; + u32 sdc_reg; + + struct tasklet_struct tasklet; + unsigned long pending_events; + unsigned long completed_events; + + int present; + int detect_pin; + int wp_pin; + + /* For detect pin debouncing */ + struct timer_list detect_timer; + + unsigned long bus_hz; + unsigned long mapbase; + struct clk *mck; + struct platform_device *pdev; +}; + +#define atmci_is_completed(host, event) \ + test_bit(event, &host->completed_events) +#define atmci_test_and_clear_pending(host, event) \ + test_and_clear_bit(event, &host->pending_events) +#define atmci_test_and_set_completed(host, event) \ + test_and_set_bit(event, &host->completed_events) +#define atmci_set_completed(host, event) \ + set_bit(event, &host->completed_events) +#define atmci_set_pending(host, event) \ + set_bit(event, &host->pending_events) +#define atmci_clear_pending(host, event) \ + clear_bit(event, &host->pending_events) + + +static void atmci_enable(struct atmel_mci *host) +{ + clk_enable(host->mck); + mci_writel(host, CR, MCI_CR_MCIEN); + mci_writel(host, MR, host->mode_reg); + mci_writel(host, SDCR, host->sdc_reg); +} + +static void atmci_disable(struct atmel_mci *host) +{ + mci_writel(host, CR, MCI_CR_SWRST); + + /* Stall until write is complete, then disable the bus clock */ + mci_readl(host, SR); + clk_disable(host->mck); +} + +static inline unsigned int ns_to_clocks(struct atmel_mci *host, + unsigned int ns) +{ + return (ns * (host->bus_hz / 1000000) + 999) / 1000; +} + +static void atmci_set_timeout(struct atmel_mci *host, + struct mmc_data *data) +{ + static unsigned dtomul_to_shift[] = { + 0, 4, 7, 8, 10, 12, 16, 20 + }; + unsigned timeout; + unsigned dtocyc; + unsigned dtomul; + + timeout = ns_to_clocks(host, data->timeout_ns) + data->timeout_clks; + + for (dtomul = 0; dtomul < 8; dtomul++) { + unsigned shift = dtomul_to_shift[dtomul]; + dtocyc = (timeout + (1 << shift) - 1) >> shift; + if (dtocyc < 15) + break; + } + + if (dtomul >= 8) { + dtomul = 7; + dtocyc = 15; + } + + dev_vdbg(&host->mmc->class_dev, "setting timeout to %u cycles\n", + dtocyc << dtomul_to_shift[dtomul]); + mci_writel(host, DTOR, (MCI_DTOMUL(dtomul) | MCI_DTOCYC(dtocyc))); +} + +/* + * Return mask with command flags to be enabled for this command. + */ +static u32 atmci_prepare_command(struct mmc_host *mmc, + struct mmc_command *cmd) +{ + struct mmc_data *data; + u32 cmdr; + + cmd->error = -EINPROGRESS; + + cmdr = MCI_CMDR_CMDNB(cmd->opcode); + + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) + cmdr |= MCI_CMDR_RSPTYP_136BIT; + else + cmdr |= MCI_CMDR_RSPTYP_48BIT; + } + + /* + * This should really be MAXLAT_5 for CMD2 and ACMD41, but + * it's too difficult to determine whether this is an ACMD or + * not. Better make it 64. + */ + cmdr |= MCI_CMDR_MAXLAT_64CYC; + + if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN) + cmdr |= MCI_CMDR_OPDCMD; + + data = cmd->data; + if (data) { + cmdr |= MCI_CMDR_START_XFER; + if (data->flags & MMC_DATA_STREAM) + cmdr |= MCI_CMDR_STREAM; + else if (data->blocks > 1) + cmdr |= MCI_CMDR_MULTI_BLOCK; + else + cmdr |= MCI_CMDR_BLOCK; + + if (data->flags & MMC_DATA_READ) + cmdr |= MCI_CMDR_TRDIR_READ; + } + + return cmdr; +} + +static void atmci_start_command(struct atmel_mci *host, + struct mmc_command *cmd, + u32 cmd_flags) +{ + /* Must read host->cmd after testing event flags */ + smp_rmb(); + WARN_ON(host->cmd); + host->cmd = cmd; + + dev_vdbg(&host->mmc->class_dev, + "start command: ARGR=0x%08x CMDR=0x%08x\n", + cmd->arg, cmd_flags); + + mci_writel(host, ARGR, cmd->arg); + mci_writel(host, CMDR, cmd_flags); +} + +static void send_stop_cmd(struct mmc_host *mmc, struct mmc_data *data) +{ + struct atmel_mci *host = mmc_priv(mmc); + + atmci_start_command(host, data->stop, host->stop_cmdr); + mci_writel(host, IER, MCI_CMDRDY); +} + +static void atmci_request_end(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct atmel_mci *host = mmc_priv(mmc); + + WARN_ON(host->cmd || host->data); + host->mrq = NULL; + + atmci_disable(host); + + mmc_request_done(mmc, mrq); +} + +/* + * Returns a mask of interrupt flags to be enabled after the whole + * request has been prepared. + */ +static u32 atmci_submit_data(struct mmc_host *mmc, struct mmc_data *data) +{ + struct atmel_mci *host = mmc_priv(mmc); + u32 iflags; + + data->error = -EINPROGRESS; + + WARN_ON(host->data); + host->sg = NULL; + host->data = data; + + mci_writel(host, BLKR, MCI_BCNT(data->blocks) + | MCI_BLKLEN(data->blksz)); + dev_vdbg(&mmc->class_dev, "BLKR=0x%08x\n", + MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); + + iflags = ATMCI_DATA_ERROR_FLAGS; + host->sg = data->sg; + host->pio_offset = 0; + if (data->flags & MMC_DATA_READ) + iflags |= MCI_RXRDY; + else + iflags |= MCI_TXRDY; + + return iflags; +} + +static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct atmel_mci *host = mmc_priv(mmc); + struct mmc_data *data; + struct mmc_command *cmd; + u32 iflags; + u32 cmdflags = 0; + + iflags = mci_readl(host, IMR); + if (iflags) + dev_warn(&mmc->class_dev, "WARNING: IMR=0x%08x\n", + mci_readl(host, IMR)); + + WARN_ON(host->mrq != NULL); + + /* + * We may "know" the card is gone even though there's still an + * electrical connection. If so, we really need to communicate + * this to the MMC core since there won't be any more + * interrupts as the card is completely removed. Otherwise, + * the MMC core might believe the card is still there even + * though the card was just removed very slowly. + */ + if (!host->present) { + mrq->cmd->error = -ENOMEDIUM; + mmc_request_done(mmc, mrq); + return; + } + + host->mrq = mrq; + host->pending_events = 0; + host->completed_events = 0; + + atmci_enable(host); + + /* We don't support multiple blocks of weird lengths. */ + data = mrq->data; + if (data) { + if (data->blocks > 1 && data->blksz & 3) + goto fail; + atmci_set_timeout(host, data); + } + + iflags = MCI_CMDRDY; + cmd = mrq->cmd; + cmdflags = atmci_prepare_command(mmc, cmd); + atmci_start_command(host, cmd, cmdflags); + + if (data) + iflags |= atmci_submit_data(mmc, data); + + if (mrq->stop) { + host->stop_cmdr = atmci_prepare_command(mmc, mrq->stop); + host->stop_cmdr |= MCI_CMDR_STOP_XFER; + if (!(data->flags & MMC_DATA_WRITE)) + host->stop_cmdr |= MCI_CMDR_TRDIR_READ; + if (data->flags & MMC_DATA_STREAM) + host->stop_cmdr |= MCI_CMDR_STREAM; + else + host->stop_cmdr |= MCI_CMDR_MULTI_BLOCK; + } + + /* + * We could have enabled interrupts earlier, but I suspect + * that would open up a nice can of interesting race + * conditions (e.g. command and data complete, but stop not + * prepared yet.) + */ + mci_writel(host, IER, iflags); + + return; + +fail: + atmci_disable(host); + host->mrq = NULL; + mrq->cmd->error = -EINVAL; + mmc_request_done(mmc, mrq); +} + +static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct atmel_mci *host = mmc_priv(mmc); + + if (ios->clock) { + u32 clkdiv; + + /* Set clock rate */ + clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1; + if (clkdiv > 255) { + dev_warn(&mmc->class_dev, + "clock %u too slow; using %lu\n", + ios->clock, host->bus_hz / (2 * 256)); + clkdiv = 255; + } + + host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF + | MCI_MR_RDPROOF; + } + + switch (ios->bus_width) { + case MMC_BUS_WIDTH_1: + host->sdc_reg = 0; + break; + case MMC_BUS_WIDTH_4: + host->sdc_reg = MCI_SDCBUS_4BIT; + break; + } + + switch (ios->power_mode) { + case MMC_POWER_ON: + /* Send init sequence (74 clock cycles) */ + atmci_enable(host); + mci_writel(host, CMDR, MCI_CMDR_SPCMD_INIT); + while (!(mci_readl(host, SR) & MCI_CMDRDY)) + cpu_relax(); + atmci_disable(host); + break; + default: + /* + * TODO: None of the currently available AVR32-based + * boards allow MMC power to be turned off. Implement + * power control when this can be tested properly. + */ + break; + } +} + +static int atmci_get_ro(struct mmc_host *mmc) +{ + int read_only = 0; + struct atmel_mci *host = mmc_priv(mmc); + + if (host->wp_pin >= 0) { + read_only = gpio_get_value(host->wp_pin); + dev_dbg(&mmc->class_dev, "card is %s\n", + read_only ? "read-only" : "read-write"); + } else { + dev_dbg(&mmc->class_dev, + "no pin for checking read-only switch." + " Assuming write-enable.\n"); + } + + return read_only; +} + +static struct mmc_host_ops atmci_ops = { + .request = atmci_request, + .set_ios = atmci_set_ios, + .get_ro = atmci_get_ro, +}; + +static void atmci_command_complete(struct atmel_mci *host, + struct mmc_command *cmd, u32 status) +{ + /* Read the response from the card (up to 16 bytes) */ + cmd->resp[0] = mci_readl(host, RSPR); + cmd->resp[1] = mci_readl(host, RSPR); + cmd->resp[2] = mci_readl(host, RSPR); + cmd->resp[3] = mci_readl(host, RSPR); + + if (status & MCI_RTOE) + cmd->error = -ETIMEDOUT; + else if ((cmd->flags & MMC_RSP_CRC) && (status & MCI_RCRCE)) + cmd->error = -EILSEQ; + else if (status & (MCI_RINDE | MCI_RDIRE | MCI_RENDE)) + cmd->error = -EIO; + else + cmd->error = 0; + + if (cmd->error) { + dev_dbg(&host->mmc->class_dev, + "command error: status=0x%08x\n", status); + + if (cmd->data) { + host->data = NULL; + mci_writel(host, IDR, MCI_NOTBUSY + | MCI_TXRDY | MCI_RXRDY + | ATMCI_DATA_ERROR_FLAGS); + } + } +} + +static void atmci_detect_change(unsigned long data) +{ + struct atmel_mci *host = (struct atmel_mci *)data; + struct mmc_request *mrq = host->mrq; + int present; + + /* + * atmci_remove() sets detect_pin to -1 before freeing the + * interrupt. We must not re-enable the interrupt if it has + * been freed. + */ + smp_rmb(); + if (host->detect_pin < 0) + return; + + enable_irq(gpio_to_irq(host->detect_pin)); + present = !gpio_get_value(host->detect_pin); + + dev_vdbg(&host->pdev->dev, "detect change: %d (was %d)\n", + present, host->present); + + if (present != host->present) { + dev_dbg(&host->mmc->class_dev, "card %s\n", + present ? "inserted" : "removed"); + host->present = present; + + /* Reset controller if card is gone */ + if (!present) { + mci_writel(host, CR, MCI_CR_SWRST); + mci_writel(host, IDR, ~0UL); + mci_writel(host, CR, MCI_CR_MCIEN); + } + + /* Clean up queue if present */ + if (mrq) { + /* + * Reset controller to terminate any ongoing + * commands or data transfers. + */ + mci_writel(host, CR, MCI_CR_SWRST); + + if (!atmci_is_completed(host, EVENT_CMD_COMPLETE)) + mrq->cmd->error = -ENOMEDIUM; + + if (mrq->data && !atmci_is_completed(host, + EVENT_DATA_COMPLETE)) { + host->data = NULL; + mrq->data->error = -ENOMEDIUM; + } + if (mrq->stop && !atmci_is_completed(host, + EVENT_STOP_COMPLETE)) + mrq->stop->error = -ENOMEDIUM; + + host->cmd = NULL; + atmci_request_end(host->mmc, mrq); + } + + mmc_detect_change(host->mmc, 0); + } +} + +static void atmci_tasklet_func(unsigned long priv) +{ + struct mmc_host *mmc = (struct mmc_host *)priv; + struct atmel_mci *host = mmc_priv(mmc); + struct mmc_request *mrq = host->mrq; + struct mmc_data *data = host->data; + + dev_vdbg(&mmc->class_dev, + "tasklet: pending/completed/mask %lx/%lx/%x\n", + host->pending_events, host->completed_events, + mci_readl(host, IMR)); + + if (atmci_test_and_clear_pending(host, EVENT_CMD_COMPLETE)) { + /* + * host->cmd must be set to NULL before the interrupt + * handler sees EVENT_CMD_COMPLETE + */ + host->cmd = NULL; + smp_wmb(); + atmci_set_completed(host, EVENT_CMD_COMPLETE); + atmci_command_complete(host, mrq->cmd, host->cmd_status); + + if (!mrq->cmd->error && mrq->stop + && atmci_is_completed(host, EVENT_XFER_COMPLETE) + && !atmci_test_and_set_completed(host, + EVENT_STOP_SENT)) + send_stop_cmd(host->mmc, mrq->data); + } + if (atmci_test_and_clear_pending(host, EVENT_STOP_COMPLETE)) { + /* + * host->cmd must be set to NULL before the interrupt + * handler sees EVENT_STOP_COMPLETE + */ + host->cmd = NULL; + smp_wmb(); + atmci_set_completed(host, EVENT_STOP_COMPLETE); + atmci_command_complete(host, mrq->stop, host->stop_status); + } + if (atmci_test_and_clear_pending(host, EVENT_DATA_ERROR)) { + u32 status = host->data_status; + + dev_vdbg(&mmc->class_dev, "data error: status=%08x\n", status); + + atmci_set_completed(host, EVENT_DATA_ERROR); + atmci_set_completed(host, EVENT_DATA_COMPLETE); + + if (status & MCI_DTOE) { + dev_dbg(&mmc->class_dev, + "data timeout error\n"); + data->error = -ETIMEDOUT; + } else if (status & MCI_DCRCE) { + dev_dbg(&mmc->class_dev, "data CRC error\n"); + data->error = -EILSEQ; + } else { + dev_dbg(&mmc->class_dev, + "data FIFO error (status=%08x)\n", + status); + data->error = -EIO; + } + + if (host->present && data->stop + && atmci_is_completed(host, EVENT_CMD_COMPLETE) + && !atmci_test_and_set_completed( + host, EVENT_STOP_SENT)) + send_stop_cmd(host->mmc, data); + + host->data = NULL; + } + if (atmci_test_and_clear_pending(host, EVENT_DATA_COMPLETE)) { + atmci_set_completed(host, EVENT_DATA_COMPLETE); + + if (!atmci_is_completed(host, EVENT_DATA_ERROR)) { + data->bytes_xfered = data->blocks * data->blksz; + data->error = 0; + } + + host->data = NULL; + } + + if (host->mrq && !host->cmd && !host->data) + atmci_request_end(mmc, host->mrq); +} + +static void atmci_read_data_pio(struct atmel_mci *host) +{ + struct scatterlist *sg = host->sg; + void *buf = sg_virt(sg); + unsigned int offset = host->pio_offset; + struct mmc_data *data = host->data; + u32 value; + u32 status; + unsigned int nbytes = 0; + + do { + value = mci_readl(host, RDR); + if (likely(offset + 4 <= sg->length)) { + put_unaligned(value, (u32 *)(buf + offset)); + + offset += 4; + nbytes += 4; + + if (offset == sg->length) { + host->sg = sg = sg_next(sg); + if (!sg) + goto done; + + offset = 0; + buf = sg_virt(sg); + } + } else { + unsigned int remaining = sg->length - offset; + memcpy(buf + offset, &value, remaining); + nbytes += remaining; + + flush_dcache_page(sg_page(sg)); + host->sg = sg = sg_next(sg); + if (!sg) + goto done; + + offset = 4 - remaining; + buf = sg_virt(sg); + memcpy(buf, (u8 *)&value + remaining, offset); + nbytes += offset; + } + + status = mci_readl(host, SR); + if (status & ATMCI_DATA_ERROR_FLAGS) { + mci_writel(host, IDR, (MCI_NOTBUSY | MCI_RXRDY + | ATMCI_DATA_ERROR_FLAGS)); + host->data_status = status; + atmci_set_pending(host, EVENT_DATA_ERROR); + tasklet_schedule(&host->tasklet); + break; + } + } while (status & MCI_RXRDY); + + host->pio_offset = offset; + data->bytes_xfered += nbytes; + + return; + +done: + mci_writel(host, IDR, MCI_RXRDY); + mci_writel(host, IER, MCI_NOTBUSY); + data->bytes_xfered += nbytes; + atmci_set_completed(host, EVENT_XFER_COMPLETE); + if (data->stop && atmci_is_completed(host, EVENT_CMD_COMPLETE) + && !atmci_test_and_set_completed(host, EVENT_STOP_SENT)) + send_stop_cmd(host->mmc, data); +} + +static void atmci_write_data_pio(struct atmel_mci *host) +{ + struct scatterlist *sg = host->sg; + void *buf = sg_virt(sg); + unsigned int offset = host->pio_offset; + struct mmc_data *data = host->data; + u32 value; + u32 status; + unsigned int nbytes = 0; + + do { + if (likely(offset + 4 <= sg->length)) { + value = get_unaligned((u32 *)(buf + offset)); + mci_writel(host, TDR, value); + + offset += 4; + nbytes += 4; + if (offset == sg->length) { + host->sg = sg = sg_next(sg); + if (!sg) + goto done; + + offset = 0; + buf = sg_virt(sg); + } + } else { + unsigned int remaining = sg->length - offset; + + value = 0; + memcpy(&value, buf + offset, remaining); + nbytes += remaining; + + host->sg = sg = sg_next(sg); + if (!sg) { + mci_writel(host, TDR, value); + goto done; + } + + offset = 4 - remaining; + buf = sg_virt(sg); + memcpy((u8 *)&value + remaining, buf, offset); + mci_writel(host, TDR, value); + nbytes += offset; + } + + status = mci_readl(host, SR); + if (status & ATMCI_DATA_ERROR_FLAGS) { + mci_writel(host, IDR, (MCI_NOTBUSY | MCI_TXRDY + | ATMCI_DATA_ERROR_FLAGS)); + host->data_status = status; + atmci_set_pending(host, EVENT_DATA_ERROR); + tasklet_schedule(&host->tasklet); + break; + } + } while (status & MCI_TXRDY); + + host->pio_offset = offset; + data->bytes_xfered += nbytes; + + return; + +done: + mci_writel(host, IDR, MCI_TXRDY); + mci_writel(host, IER, MCI_NOTBUSY); + data->bytes_xfered += nbytes; + atmci_set_completed(host, EVENT_XFER_COMPLETE); + if (data->stop && atmci_is_completed(host, EVENT_CMD_COMPLETE) + && !atmci_test_and_set_completed(host, EVENT_STOP_SENT)) + send_stop_cmd(host->mmc, data); +} + +static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status) +{ + struct atmel_mci *host = mmc_priv(mmc); + + mci_writel(host, IDR, MCI_CMDRDY); + + if (atmci_is_completed(host, EVENT_STOP_SENT)) { + host->stop_status = status; + atmci_set_pending(host, EVENT_STOP_COMPLETE); + } else { + host->cmd_status = status; + atmci_set_pending(host, EVENT_CMD_COMPLETE); + } + + tasklet_schedule(&host->tasklet); +} + +static irqreturn_t atmci_interrupt(int irq, void *dev_id) +{ + struct mmc_host *mmc = dev_id; + struct atmel_mci *host = mmc_priv(mmc); + u32 status, mask, pending; + unsigned int pass_count = 0; + + spin_lock(&mmc->lock); + + do { + status = mci_readl(host, SR); + mask = mci_readl(host, IMR); + pending = status & mask; + if (!pending) + break; + + if (pending & ATMCI_DATA_ERROR_FLAGS) { + mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS + | MCI_RXRDY | MCI_TXRDY); + pending &= mci_readl(host, IMR); + host->data_status = status; + atmci_set_pending(host, EVENT_DATA_ERROR); + tasklet_schedule(&host->tasklet); + } + if (pending & MCI_NOTBUSY) { + mci_writel(host, IDR, (MCI_NOTBUSY + | ATMCI_DATA_ERROR_FLAGS)); + atmci_set_pending(host, EVENT_DATA_COMPLETE); + tasklet_schedule(&host->tasklet); + } + if (pending & MCI_RXRDY) + atmci_read_data_pio(host); + if (pending & MCI_TXRDY) + atmci_write_data_pio(host); + + if (pending & MCI_CMDRDY) + atmci_cmd_interrupt(mmc, status); + } while (pass_count++ < 5); + + spin_unlock(&mmc->lock); + + return pass_count ? IRQ_HANDLED : IRQ_NONE; +} + +static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) +{ + struct mmc_host *mmc = dev_id; + struct atmel_mci *host = mmc_priv(mmc); + + /* + * Disable interrupts until the pin has stabilized and check + * the state then. Use mod_timer() since we may be in the + * middle of the timer routine when this interrupt triggers. + */ + disable_irq_nosync(irq); + mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(20)); + + return IRQ_HANDLED; +} + +static int __init atmci_probe(struct platform_device *pdev) +{ + struct mci_platform_data *pdata; + struct atmel_mci *host; + struct mmc_host *mmc; + struct resource *regs; + int irq; + int ret; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) + return -ENXIO; + pdata = pdev->dev.platform_data; + if (!pdata) + return -ENXIO; + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + mmc = mmc_alloc_host(sizeof(struct atmel_mci), &pdev->dev); + if (!mmc) + return -ENOMEM; + + host = mmc_priv(mmc); + host->pdev = pdev; + host->mmc = mmc; + host->detect_pin = pdata->detect_pin; + host->wp_pin = pdata->wp_pin; + + host->mck = clk_get(&pdev->dev, "mci_clk"); + if (IS_ERR(host->mck)) { + ret = PTR_ERR(host->mck); + goto err_clk_get; + } + + ret = -ENOMEM; + host->regs = ioremap(regs->start, regs->end - regs->start + 1); + if (!host->regs) + goto err_ioremap; + + clk_enable(host->mck); + mci_writel(host, CR, MCI_CR_SWRST); + host->bus_hz = clk_get_rate(host->mck); + clk_disable(host->mck); + + host->mapbase = regs->start; + + mmc->ops = &atmci_ops; + mmc->f_min = (host->bus_hz + 511) / 512; + mmc->f_max = host->bus_hz / 2; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; + + mmc->max_hw_segs = 64; + mmc->max_phys_segs = 64; + mmc->max_req_size = 32768 * 512; + mmc->max_blk_size = 32768; + mmc->max_blk_count = 512; + + tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)mmc); + + ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, mmc); + if (ret) + goto err_request_irq; + + /* Assume card is present if we don't have a detect pin */ + host->present = 1; + if (host->detect_pin >= 0) { + if (gpio_request(host->detect_pin, "mmc_detect")) { + dev_dbg(&mmc->class_dev, "no detect pin available\n"); + host->detect_pin = -1; + } else { + host->present = !gpio_get_value(host->detect_pin); + } + } + if (host->wp_pin >= 0) { + if (gpio_request(host->wp_pin, "mmc_wp")) { + dev_dbg(&mmc->class_dev, "no WP pin available\n"); + host->wp_pin = -1; + } + } + + platform_set_drvdata(pdev, host); + + mmc_add_host(mmc); + + if (host->detect_pin >= 0) { + setup_timer(&host->detect_timer, atmci_detect_change, + (unsigned long)host); + + ret = request_irq(gpio_to_irq(host->detect_pin), + atmci_detect_interrupt, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "mmc-detect", mmc); + if (ret) { + dev_dbg(&mmc->class_dev, + "could not request IRQ %d for detect pin\n", + gpio_to_irq(host->detect_pin)); + gpio_free(host->detect_pin); + host->detect_pin = -1; + } + } + + dev_info(&mmc->class_dev, + "Atmel MCI controller at 0x%08lx irq %d\n", + host->mapbase, irq); + + return 0; + +err_request_irq: + iounmap(host->regs); +err_ioremap: + clk_put(host->mck); +err_clk_get: + mmc_free_host(mmc); + return ret; +} + +static int __exit atmci_remove(struct platform_device *pdev) +{ + struct atmel_mci *host = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + if (host) { + if (host->detect_pin >= 0) { + int pin = host->detect_pin; + + /* Make sure the timer doesn't enable the interrupt */ + host->detect_pin = -1; + smp_wmb(); + + free_irq(gpio_to_irq(pin), host->mmc); + del_timer_sync(&host->detect_timer); + gpio_free(pin); + } + + mmc_remove_host(host->mmc); + + clk_enable(host->mck); + mci_writel(host, IDR, ~0UL); + mci_writel(host, CR, MCI_CR_MCIDIS); + mci_readl(host, SR); + clk_disable(host->mck); + + if (host->wp_pin >= 0) + gpio_free(host->wp_pin); + + free_irq(platform_get_irq(pdev, 0), host->mmc); + iounmap(host->regs); + + clk_put(host->mck); + + mmc_free_host(host->mmc); + } + return 0; +} + +static struct platform_driver atmci_driver = { + .remove = __exit_p(atmci_remove), + .driver = { + .name = "atmel_mci", + }, +}; + +static int __init atmci_init(void) +{ + return platform_driver_probe(&atmci_driver, atmci_probe); +} + +static void __exit atmci_exit(void) +{ + platform_driver_unregister(&atmci_driver); +} + +module_init(atmci_init); +module_exit(atmci_exit); + +MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); +MODULE_AUTHOR("Haavard Skinnemoen "); +MODULE_LICENSE("GPL v2"); diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index b4cddfa..a378386 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h @@ -77,7 +77,11 @@ struct i2c_board_info; struct platform_device *at32_add_device_twi(unsigned int id, struct i2c_board_info *b, unsigned int n); -struct platform_device *at32_add_device_mci(unsigned int id); + +struct mci_platform_data; +struct platform_device * +at32_add_device_mci(unsigned int id, struct mci_platform_data *data); + struct platform_device *at32_add_device_ac97c(unsigned int id); struct platform_device *at32_add_device_abdac(unsigned int id); struct platform_device *at32_add_device_psif(unsigned int id); diff --git a/include/asm-avr32/atmel-mci.h b/include/asm-avr32/atmel-mci.h new file mode 100644 index 0000000..c2ea6e1 --- /dev/null +++ b/include/asm-avr32/atmel-mci.h @@ -0,0 +1,9 @@ +#ifndef __ASM_AVR32_ATMEL_MCI_H +#define __ASM_AVR32_ATMEL_MCI_H + +struct mci_platform_data { + int detect_pin; + int wp_pin; +}; + +#endif /* __ASM_AVR32_ATMEL_MCI_H */ -- cgit v0.10.2 From 97067d5581ec831a75a45a52e417bee0f7943dbf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 6 Jul 2008 00:51:07 +0200 Subject: wbsd: fix bad dma_addr_t conversion DMA addresses are not pointers, so don't treat them as such. Avoids compiler warnings when using 64-bit DMA addresses on a 32-bit system. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index c2b6160..f7dcd8e 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -1420,7 +1420,7 @@ kfree: dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); - host->dma_addr = (dma_addr_t)NULL; + host->dma_addr = 0; kfree(host->dma_buffer); host->dma_buffer = NULL; @@ -1445,7 +1445,7 @@ static void wbsd_release_dma(struct wbsd_host *host) host->dma = -1; host->dma_buffer = NULL; - host->dma_addr = (dma_addr_t)NULL; + host->dma_addr = 0; } /* -- cgit v0.10.2 From 23af60398af2f5033e2f53665538a09f498dbc03 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 6 Jul 2008 01:10:27 +0200 Subject: mmc: remove multiwrite capability Relax requirements on host controllers and only require that they do not report a transfer count than is larger than the actual one (i.e. a lower value is okay). This is how many other parts of the kernel behaves so upper layers should already be prepared to handle that scenario. This gives us a performance boost on MMC cards. Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 4b0f822..66e5a54 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -237,17 +237,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) if (brq.data.blocks > card->host->max_blk_count) brq.data.blocks = card->host->max_blk_count; - /* - * If the host doesn't support multiple block writes, force - * block writes to single block. SD cards are excepted from - * this rule as they support querying the number of - * successfully written sectors. - */ - if (rq_data_dir(req) != READ && - !(card->host->caps & MMC_CAP_MULTIWRITE) && - !mmc_card_sd(card)) - brq.data.blocks = 1; - if (brq.data.blocks > 1) { /* SPI multiblock writes terminate using a special * token, not a STOP_TRANSMISSION request. @@ -367,30 +356,32 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * mark the known good sectors as ok. * * If the card is not SD, we can still ok written sectors - * if the controller can do proper error reporting. + * as reported by the controller (which might be less than + * the real number of written sectors, but never more). * * For reads we just fail the entire chunk as that should * be safe in all cases. */ - if (rq_data_dir(req) != READ && mmc_card_sd(card)) { - u32 blocks; - unsigned int bytes; - - blocks = mmc_sd_num_wr_blocks(card); - if (blocks != (u32)-1) { - if (card->csd.write_partial) - bytes = blocks << md->block_bits; - else - bytes = blocks << 9; + if (rq_data_dir(req) != READ) { + if (mmc_card_sd(card)) { + u32 blocks; + unsigned int bytes; + + blocks = mmc_sd_num_wr_blocks(card); + if (blocks != (u32)-1) { + if (card->csd.write_partial) + bytes = blocks << md->block_bits; + else + bytes = blocks << 9; + spin_lock_irq(&md->lock); + ret = __blk_end_request(req, 0, bytes); + spin_unlock_irq(&md->lock); + } + } else { spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, bytes); + ret = __blk_end_request(req, 0, brq.data.bytes_xfered); spin_unlock_irq(&md->lock); } - } else if (rq_data_dir(req) != READ && - (card->host->caps & MMC_CAP_MULTIWRITE)) { - spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, brq.data.bytes_xfered); - spin_unlock_irq(&md->lock); } mmc_release_host(card->host); diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 16df235..f15e206 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -995,7 +995,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ; + mmc->caps = MMC_CAP_SDIO_IRQ; mmc->max_blk_size = 4095; mmc->max_blk_count = mmc->max_req_size; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 25d5324a..cce873c 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -849,7 +849,7 @@ static int __init atmci_probe(struct platform_device *pdev) mmc->f_min = (host->bus_hz + 511) / 512; mmc->f_max = host->bus_hz / 2; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; + mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->max_hw_segs = 64; mmc->max_phys_segs = 64; diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 4e82f64..41cc633 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1252,10 +1252,7 @@ static int mmc_spi_probe(struct spi_device *spi) mmc->ops = &mmc_spi_ops; mmc->max_blk_size = MMC_SPI_BLOCKSIZE; - /* As long as we keep track of the number of successfully - * transmitted blocks, we're good for multiwrite. - */ - mmc->caps = MMC_CAP_SPI | MMC_CAP_MULTIWRITE; + mmc->caps = MMC_CAP_SPI; /* SPI doesn't need the lowspeed device identification thing for * MMC or SD cards, since it never comes up in open drain mode. diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index da5feca..696cf36 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -535,7 +535,6 @@ static int mmci_probe(struct amba_device *dev, void *id) mmc->f_min = (host->mclk + 511) / 512; mmc->f_max = min(host->mclk, fmax); mmc->ocr_avail = plat->ocr_mask; - mmc->caps = MMC_CAP_MULTIWRITE; /* * We can do SGIO diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 549517c..dbc26eb 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) host->slots[id] = slot; - mmc->caps = MMC_CAP_MULTIWRITE; + mmc->caps = 0; if (host->pdata->conf.wire4) mmc->caps |= MMC_CAP_4_BIT_DATA; diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 1c14a18..1384484 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c @@ -973,7 +973,7 @@ static int tifm_sd_probe(struct tifm_dev *sock) mmc->ops = &tifm_sd_ops; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; + mmc->caps = MMC_CAP_4_BIT_DATA; mmc->f_min = 20000000 / 60; mmc->f_max = 24000000; diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index f7dcd8e..adda379 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -1219,7 +1219,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev) mmc->f_min = 375000; mmc->f_max = 24000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; + mmc->caps = MMC_CAP_4_BIT_DATA; spin_lock_init(&host->lock); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 753b723..10a2080 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -111,12 +111,11 @@ struct mmc_host { unsigned long caps; /* Host capabilities */ #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ -#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */ -#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */ -#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */ -#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */ -#define MMC_CAP_SPI (1 << 5) /* Talks only SPI protocols */ -#define MMC_CAP_NEEDS_POLL (1 << 6) /* Needs polling for card-detection */ +#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */ +#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */ +#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */ +#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ +#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ -- cgit v0.10.2 From c8b3e02eb250ceb661437e9b198757eff0eb6fd2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sat, 5 Jul 2008 19:52:04 +0300 Subject: mmc: fix spares errors of sdhci.c 1. sdhci_prepare_data: fix shadowing of count variable u8 count int count -> sg_cnt; 2. sdhci_add_host: assignment of integer to pointer dma_mask = 0 -> dma_mask = NULL; Signed-off-by: Tomas Winkler Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d3e4a39..13bd681 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -672,14 +672,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) host->ioaddr + SDHCI_ADMA_ADDRESS); } } else { - int count; + int sg_cnt; - count = dma_map_sg(mmc_dev(host->mmc), + sg_cnt = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, (data->flags & MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); - if (count == 0) { + if (sg_cnt == 0) { /* * This only happens when someone fed * us an invalid request. @@ -1583,7 +1583,7 @@ int sdhci_add_host(struct sdhci_host *host) /* XXX: Hack to get MMC layer to avoid highmem */ if (!(host->flags & SDHCI_USE_DMA)) - mmc_dev(host->mmc)->dma_mask = 0; + mmc_dev(host->mmc)->dma_mask = NULL; host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; -- cgit v0.10.2 From c71f65129a1fb67bc6b9b8d03b493675b5c9302b Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 7 Jul 2008 17:25:56 -0400 Subject: mmc: OLPC: update vdd/powerup quirk comment This comment update got lost in the great floo^Wmerge. As Pierre pointed out, no one knows what 'CaFe' is. Signed-off-by: Andres Salomon Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 13bd681..17701c3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -978,7 +978,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) } /* - * At least the CaFe chip gets confused if we set the voltage + * At least the Marvell CaFe chip gets confused if we set the voltage * and set turn on power at the same time, so set the voltage first. */ if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) -- cgit v0.10.2 From aba3728ce2e8ce85e1e5f6b275131e9332256789 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 Jul 2008 14:48:48 +0200 Subject: x86: sanitize Kconfig Set default n for MEMTEST and MTRR_SANITIZER and fix the help texts. Signed-off-by: Thomas Gleixner diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6958d6b..2642b4b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -447,7 +447,6 @@ config PARAVIRT_DEBUG config MEMTEST bool "Memtest" depends on X86_64 - default y help This option adds a kernel parameter 'memtest', which allows memtest to be set. @@ -455,7 +454,7 @@ config MEMTEST memtest=1, mean do 1 test pattern; ... memtest=4, mean do 4 test patterns. - If you are unsure how to answer this question, answer Y. + If you are unsure how to answer this question, answer N. config X86_SUMMIT_NUMA def_bool y @@ -1135,21 +1134,18 @@ config MTRR See for more information. config MTRR_SANITIZER - def_bool y + bool prompt "MTRR cleanup support" depends on MTRR help - Convert MTRR layout from continuous to discrete, so some X driver - could add WB entries. + Convert MTRR layout from continuous to discrete, so X drivers can + add writeback entries. - Say N here if you see bootup problems (boot crash, boot hang, - spontaneous reboots). + Can be disabled with disable_mtrr_cleanup on the kernel command line. + The largest mtrr entry size for a continous block can be set with + mtrr_chunk_size. - Could be disabled with disable_mtrr_cleanup. Also mtrr_chunk_size - could be used to send largest mtrr entry size for continuous block - to hold holes (aka. UC entries) - - If unsure, say Y. + If unsure, say N. config MTRR_SANITIZER_ENABLE_DEFAULT int "MTRR cleanup enable value (0-1)" @@ -1166,7 +1162,7 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT depends on MTRR_SANITIZER help mtrr cleanup spare entries default, it can be changed via - mtrr_spare_reg_nr= + mtrr_spare_reg_nr=N on the kernel command line. config X86_PAT bool -- cgit v0.10.2 From d3af01f18bf18e9b2a95711894fc239daeab5e2e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 Jul 2008 15:04:56 +0200 Subject: Documentation: document debugpat commandline option Signed-off-by: Thomas Gleixner diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b3a5aad..681d615 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -571,6 +571,8 @@ and is between 256 and 4096 characters. It is defined in the file debug_objects [KNL] Enable object debugging + debugpat [X86] Enable PAT debugging + decnet.addr= [HW,NET] Format: [,] See also Documentation/networking/decnet.txt. -- cgit v0.10.2 From 3f1c38723eb467d34d704d0ee6e7b796ba4981ee Mon Sep 17 00:00:00 2001 From: Kevin Winchester Date: Mon, 14 Jul 2008 21:36:13 -0300 Subject: x86: Fix compile error with CONFIG_AS_CFI=n AS arch/x86/lib/csum-copy_64.o arch/x86/lib/csum-copy_64.S: Assembler messages: arch/x86/lib/csum-copy_64.S:48: Error: Macro `ignore' was already defined make[1]: *** [arch/x86/lib/csum-copy_64.o] Error 1 make: *** [arch/x86/lib] Error 2 It appears that csum-copy_64.S and dwarf2.h both define an ignore macro. I would expect one of them can be renamed quite easily, unless they are references elsewhere. Caused-by-commit: 392a0fc96bd059b38564f5f8fb58327460cb5a9d x86: merge dwarf2 headers Signed-off-by: Thomas Gleixner diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h index 0bfe250..738bb9f 100644 --- a/include/asm-x86/dwarf2.h +++ b/include/asm-x86/dwarf2.h @@ -38,23 +38,23 @@ /* Due to the structure of pre-exisiting code, don't use assembler line comment character # to ignore the arguments. Instead, use a dummy macro. */ -.macro ignore a=0, b=0, c=0, d=0 +.macro cfi_ignore a=0, b=0, c=0, d=0 .endm -#define CFI_STARTPROC ignore -#define CFI_ENDPROC ignore -#define CFI_DEF_CFA ignore -#define CFI_DEF_CFA_REGISTER ignore -#define CFI_DEF_CFA_OFFSET ignore -#define CFI_ADJUST_CFA_OFFSET ignore -#define CFI_OFFSET ignore -#define CFI_REL_OFFSET ignore -#define CFI_REGISTER ignore -#define CFI_RESTORE ignore -#define CFI_REMEMBER_STATE ignore -#define CFI_RESTORE_STATE ignore -#define CFI_UNDEFINED ignore -#define CFI_SIGNAL_FRAME ignore +#define CFI_STARTPROC cfi_ignore +#define CFI_ENDPROC cfi_ignore +#define CFI_DEF_CFA cfi_ignore +#define CFI_DEF_CFA_REGISTER cfi_ignore +#define CFI_DEF_CFA_OFFSET cfi_ignore +#define CFI_ADJUST_CFA_OFFSET cfi_ignore +#define CFI_OFFSET cfi_ignore +#define CFI_REL_OFFSET cfi_ignore +#define CFI_REGISTER cfi_ignore +#define CFI_RESTORE cfi_ignore +#define CFI_REMEMBER_STATE cfi_ignore +#define CFI_RESTORE_STATE cfi_ignore +#define CFI_UNDEFINED cfi_ignore +#define CFI_SIGNAL_FRAME cfi_ignore #endif -- cgit v0.10.2 From 62a7573ee9f31d4fdb330b3e68ebf6efaba1d57c Mon Sep 17 00:00:00 2001 From: Benzi Zbit Date: Thu, 10 Jul 2008 02:41:43 +0300 Subject: sdio: fix the use of hard coded timeout value. This adds reading and using of enable_timeout from the CIS Signed-off-by: Benzi Zbit Signed-off-by: Tomas Winkler Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index d5e51b1..956bd76 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -129,6 +129,12 @@ static int cistpl_funce_func(struct sdio_func *func, /* TPLFE_MAX_BLK_SIZE */ func->max_blksize = buf[12] | (buf[13] << 8); + /* TPLFE_ENABLE_TIMEOUT_VAL, present in ver 1.1 and above */ + if (vsn > SDIO_SDIO_REV_1_00) + func->enable_timeout = (buf[28] | (buf[29] << 8)) * 10; + else + func->enable_timeout = jiffies_to_msecs(HZ); + return 0; } diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 3ccf691..0888df6 100755 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -76,11 +76,7 @@ int sdio_enable_func(struct sdio_func *func) if (ret) goto err; - /* - * FIXME: This should timeout based on information in the CIS, - * but we don't have card to parse that yet. - */ - timeout = jiffies + HZ; + timeout = jiffies + msecs_to_jiffies(func->enable_timeout); while (1) { ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, ®); diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index 28fb0a3..07bee4a 100755 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -46,6 +46,8 @@ struct sdio_func { unsigned max_blksize; /* maximum block size */ unsigned cur_blksize; /* current block size */ + unsigned enable_timeout; /* max enable timeout in msec */ + unsigned int state; /* function state */ #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ -- cgit v0.10.2 From ea901300cd8b809285fa5cbced18124f127e0ac6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 10 Jul 2008 03:01:56 +0300 Subject: sdio: sdio_io.c Fix sparse warnings Unfold nested macros it creates not readable code and sparse warnings sdio_io.c:190:9: warning: symbol '_min1' shadows an earlier one Signed-off-by: Tomas Winkler Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 0888df6..f61fc2d 100755 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -187,11 +187,10 @@ EXPORT_SYMBOL_GPL(sdio_set_block_size); */ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) { - return min(min(min( - func->card->host->max_seg_size, - func->card->host->max_blk_size), - func->max_blksize), - 512u); /* maximum size for byte mode */ + unsigned mval = min(func->card->host->max_seg_size, + func->card->host->max_blk_size); + mval = min(mval, func->max_blksize); + return min(mval, 512u); /* maximum size for byte mode */ } /** -- cgit v0.10.2 From 6a36913a33cf3d366e124f25c486a71212d02bce Mon Sep 17 00:00:00 2001 From: Sascha Sommer Date: Tue, 15 Jul 2008 14:21:29 +0200 Subject: mmc: host driver for Ricoh Bay1Controllers Signed-off-by: Sascha Sommer Signed-off-by: Pierre Ossman diff --git a/MAINTAINERS b/MAINTAINERS index 9def20a..c16b986 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3609,6 +3609,12 @@ P: Jim Cromie M: jim.cromie@gmail.com S: Maintained +SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER +P: Sascha Sommer +M: saschasommer@freenet.de +L: sdricohcs-devel@lists.sourceforge.net (subscribers-only) +S: Maintained + SECURITY CONTACT P: Security Officers M: security@kernel.org diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 198df42..dc6f257 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -164,3 +164,13 @@ config MMC_S3C If unsure, say N. +config MMC_SDRICOH_CS + tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" + depends on EXPERIMENTAL && MMC && PCI && PCMCIA + help + Say Y here if your Notebook reports a Ricoh Bay1Controller PCMCIA + card whenever you insert a MMC or SD card into the card slot. + + To compile this driver as a module, choose M here: the + module will be called sdricoh_cs. + diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 2dc9ff2..db52eeb 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -20,3 +20,5 @@ obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o obj-$(CONFIG_MMC_S3C) += s3cmci.o +obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o + diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c new file mode 100644 index 0000000..f99e9f7 --- /dev/null +++ b/drivers/mmc/host/sdricoh_cs.c @@ -0,0 +1,575 @@ +/* + * sdricoh_cs.c - driver for Ricoh Secure Digital Card Readers that can be + * found on some Ricoh RL5c476 II cardbus bridge + * + * Copyright (C) 2006 - 2008 Sascha Sommer + * + * 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. + * + */ + +/* +#define DEBUG +#define VERBOSE_DEBUG +*/ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "sdricoh_cs" + +static unsigned int switchlocked; + +/* i/o region */ +#define SDRICOH_PCI_REGION 0 +#define SDRICOH_PCI_REGION_SIZE 0x1000 + +/* registers */ +#define R104_VERSION 0x104 +#define R200_CMD 0x200 +#define R204_CMD_ARG 0x204 +#define R208_DATAIO 0x208 +#define R20C_RESP 0x20c +#define R21C_STATUS 0x21c +#define R2E0_INIT 0x2e0 +#define R2E4_STATUS_RESP 0x2e4 +#define R2F0_RESET 0x2f0 +#define R224_MODE 0x224 +#define R226_BLOCKSIZE 0x226 +#define R228_POWER 0x228 +#define R230_DATA 0x230 + +/* flags for the R21C_STATUS register */ +#define STATUS_CMD_FINISHED 0x00000001 +#define STATUS_TRANSFER_FINISHED 0x00000004 +#define STATUS_CARD_INSERTED 0x00000020 +#define STATUS_CARD_LOCKED 0x00000080 +#define STATUS_CMD_TIMEOUT 0x00400000 +#define STATUS_READY_TO_READ 0x01000000 +#define STATUS_READY_TO_WRITE 0x02000000 +#define STATUS_BUSY 0x40000000 + +/* timeouts */ +#define INIT_TIMEOUT 100 +#define CMD_TIMEOUT 100000 +#define TRANSFER_TIMEOUT 100000 +#define BUSY_TIMEOUT 32767 + +/* list of supported pcmcia devices */ +static struct pcmcia_device_id pcmcia_ids[] = { + /* vendor and device strings followed by their crc32 hashes */ + PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay1Controller", 0xd9f522ed, + 0xc3901202), + PCMCIA_DEVICE_NULL, +}; + +MODULE_DEVICE_TABLE(pcmcia, pcmcia_ids); + +/* mmc privdata */ +struct sdricoh_host { + struct device *dev; + struct mmc_host *mmc; /* MMC structure */ + unsigned char __iomem *iobase; + struct pci_dev *pci_dev; + int app_cmd; +}; + +/***************** register i/o helper functions *****************************/ + +static inline unsigned int sdricoh_readl(struct sdricoh_host *host, + unsigned int reg) +{ + unsigned int value = readl(host->iobase + reg); + dev_vdbg(host->dev, "rl %x 0x%x\n", reg, value); + return value; +} + +static inline void sdricoh_writel(struct sdricoh_host *host, unsigned int reg, + unsigned int value) +{ + writel(value, host->iobase + reg); + dev_vdbg(host->dev, "wl %x 0x%x\n", reg, value); + +} + +static inline unsigned int sdricoh_readw(struct sdricoh_host *host, + unsigned int reg) +{ + unsigned int value = readw(host->iobase + reg); + dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value); + return value; +} + +static inline void sdricoh_writew(struct sdricoh_host *host, unsigned int reg, + unsigned short value) +{ + writew(value, host->iobase + reg); + dev_vdbg(host->dev, "ww %x 0x%x\n", reg, value); +} + +static inline unsigned int sdricoh_readb(struct sdricoh_host *host, + unsigned int reg) +{ + unsigned int value = readb(host->iobase + reg); + dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value); + return value; +} + +static int sdricoh_query_status(struct sdricoh_host *host, unsigned int wanted, + unsigned int timeout){ + unsigned int loop; + unsigned int status = 0; + struct device *dev = host->dev; + for (loop = 0; loop < timeout; loop++) { + status = sdricoh_readl(host, R21C_STATUS); + sdricoh_writel(host, R2E4_STATUS_RESP, status); + if (status & wanted) + break; + } + + if (loop == timeout) { + dev_err(dev, "query_status: timeout waiting for %x\n", wanted); + return -ETIMEDOUT; + } + + /* do not do this check in the loop as some commands fail otherwise */ + if (status & 0x7F0000) { + dev_err(dev, "waiting for status bit %x failed\n", wanted); + return -EINVAL; + } + return 0; + +} + +static int sdricoh_mmc_cmd(struct sdricoh_host *host, unsigned char opcode, + unsigned int arg) +{ + unsigned int status; + int result = 0; + unsigned int loop = 0; + /* reset status reg? */ + sdricoh_writel(host, R21C_STATUS, 0x18); + /* fill parameters */ + sdricoh_writel(host, R204_CMD_ARG, arg); + sdricoh_writel(host, R200_CMD, (0x10000 << 8) | opcode); + /* wait for command completion */ + if (opcode) { + for (loop = 0; loop < CMD_TIMEOUT; loop++) { + status = sdricoh_readl(host, R21C_STATUS); + sdricoh_writel(host, R2E4_STATUS_RESP, status); + if (status & STATUS_CMD_FINISHED) + break; + } + /* don't check for timeout in the loop it is not always + reset correctly + */ + if (loop == CMD_TIMEOUT || status & STATUS_CMD_TIMEOUT) + result = -ETIMEDOUT; + + } + + return result; + +} + +static int sdricoh_reset(struct sdricoh_host *host) +{ + dev_dbg(host->dev, "reset\n"); + sdricoh_writel(host, R2F0_RESET, 0x10001); + sdricoh_writel(host, R2E0_INIT, 0x10000); + if (sdricoh_readl(host, R2E0_INIT) != 0x10000) + return -EIO; + sdricoh_writel(host, R2E0_INIT, 0x10007); + + sdricoh_writel(host, R224_MODE, 0x2000000); + sdricoh_writel(host, R228_POWER, 0xe0); + + + /* status register ? */ + sdricoh_writel(host, R21C_STATUS, 0x18); + + return 0; +} + +static int sdricoh_blockio(struct sdricoh_host *host, int read, + u8 *buf, int len) +{ + int size; + u32 data = 0; + /* wait until the data is available */ + if (read) { + if (sdricoh_query_status(host, STATUS_READY_TO_READ, + TRANSFER_TIMEOUT)) + return -ETIMEDOUT; + sdricoh_writel(host, R21C_STATUS, 0x18); + /* read data */ + while (len) { + data = sdricoh_readl(host, R230_DATA); + size = min(len, 4); + len -= size; + while (size) { + *buf = data & 0xFF; + buf++; + data >>= 8; + size--; + } + } + } else { + if (sdricoh_query_status(host, STATUS_READY_TO_WRITE, + TRANSFER_TIMEOUT)) + return -ETIMEDOUT; + sdricoh_writel(host, R21C_STATUS, 0x18); + /* write data */ + while (len) { + size = min(len, 4); + len -= size; + while (size) { + data >>= 8; + data |= (u32)*buf << 24; + buf++; + size--; + } + sdricoh_writel(host, R230_DATA, data); + } + } + + if (len) + return -EIO; + + return 0; +} + +static void sdricoh_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct sdricoh_host *host = mmc_priv(mmc); + struct mmc_command *cmd = mrq->cmd; + struct mmc_data *data = cmd->data; + struct device *dev = host->dev; + unsigned char opcode = cmd->opcode; + int i; + + dev_dbg(dev, "=============================\n"); + dev_dbg(dev, "sdricoh_request opcode=%i\n", opcode); + + sdricoh_writel(host, R21C_STATUS, 0x18); + + /* MMC_APP_CMDs need some special handling */ + if (host->app_cmd) { + opcode |= 64; + host->app_cmd = 0; + } else if (opcode == 55) + host->app_cmd = 1; + + /* read/write commands seem to require this */ + if (data) { + sdricoh_writew(host, R226_BLOCKSIZE, data->blksz); + sdricoh_writel(host, R208_DATAIO, 0); + } + + cmd->error = sdricoh_mmc_cmd(host, opcode, cmd->arg); + + /* read response buffer */ + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) { + /* CRC is stripped so we need to do some shifting. */ + for (i = 0; i < 4; i++) { + cmd->resp[i] = + sdricoh_readl(host, + R20C_RESP + (3 - i) * 4) << 8; + if (i != 3) + cmd->resp[i] |= + sdricoh_readb(host, R20C_RESP + + (3 - i) * 4 - 1); + } + } else + cmd->resp[0] = sdricoh_readl(host, R20C_RESP); + } + + /* transfer data */ + if (data && cmd->error == 0) { + dev_dbg(dev, "transfer: blksz %i blocks %i sg_len %i " + "sg length %i\n", data->blksz, data->blocks, + data->sg_len, data->sg->length); + + /* enter data reading mode */ + sdricoh_writel(host, R21C_STATUS, 0x837f031e); + for (i = 0; i < data->blocks; i++) { + size_t len = data->blksz; + u8 *buf; + struct page *page; + int result; + page = sg_page(data->sg); + + buf = kmap(page) + data->sg->offset + (len * i); + result = + sdricoh_blockio(host, + data->flags & MMC_DATA_READ, buf, len); + kunmap(page); + flush_dcache_page(page); + if (result) { + dev_err(dev, "sdricoh_request: cmd %i " + "block transfer failed\n", cmd->opcode); + cmd->error = result; + break; + } else + data->bytes_xfered += len; + } + + sdricoh_writel(host, R208_DATAIO, 1); + + if (sdricoh_query_status(host, STATUS_TRANSFER_FINISHED, + TRANSFER_TIMEOUT)) { + dev_err(dev, "sdricoh_request: transfer end error\n"); + cmd->error = -EINVAL; + } + } + /* FIXME check busy flag */ + + mmc_request_done(mmc, mrq); + dev_dbg(dev, "=============================\n"); +} + +static void sdricoh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdricoh_host *host = mmc_priv(mmc); + dev_dbg(host->dev, "set_ios\n"); + + if (ios->power_mode == MMC_POWER_ON) { + sdricoh_writel(host, R228_POWER, 0xc0e0); + + if (ios->bus_width == MMC_BUS_WIDTH_4) { + sdricoh_writel(host, R224_MODE, 0x2000300); + sdricoh_writel(host, R228_POWER, 0x40e0); + } else { + sdricoh_writel(host, R224_MODE, 0x2000340); + } + + } else if (ios->power_mode == MMC_POWER_UP) { + sdricoh_writel(host, R224_MODE, 0x2000320); + sdricoh_writel(host, R228_POWER, 0xe0); + } +} + +static int sdricoh_get_ro(struct mmc_host *mmc) +{ + struct sdricoh_host *host = mmc_priv(mmc); + unsigned int status; + + status = sdricoh_readl(host, R21C_STATUS); + sdricoh_writel(host, R2E4_STATUS_RESP, status); + + /* some notebooks seem to have the locked flag switched */ + if (switchlocked) + return !(status & STATUS_CARD_LOCKED); + + return (status & STATUS_CARD_LOCKED); +} + +static struct mmc_host_ops sdricoh_ops = { + .request = sdricoh_request, + .set_ios = sdricoh_set_ios, + .get_ro = sdricoh_get_ro, +}; + +/* initialize the control and register it to the mmc framework */ +static int sdricoh_init_mmc(struct pci_dev *pci_dev, + struct pcmcia_device *pcmcia_dev) +{ + int result = 0; + void __iomem *iobase = NULL; + struct mmc_host *mmc = NULL; + struct sdricoh_host *host = NULL; + struct device *dev = &pcmcia_dev->dev; + /* map iomem */ + if (pci_resource_len(pci_dev, SDRICOH_PCI_REGION) != + SDRICOH_PCI_REGION_SIZE) { + dev_dbg(dev, "unexpected pci resource len\n"); + return -ENODEV; + } + iobase = + pci_iomap(pci_dev, SDRICOH_PCI_REGION, SDRICOH_PCI_REGION_SIZE); + if (!iobase) { + dev_err(dev, "unable to map iobase\n"); + return -ENODEV; + } + /* check version? */ + if (readl(iobase + R104_VERSION) != 0x4000) { + dev_dbg(dev, "no supported mmc controller found\n"); + result = -ENODEV; + goto err; + } + /* allocate privdata */ + mmc = pcmcia_dev->priv = + mmc_alloc_host(sizeof(struct sdricoh_host), &pcmcia_dev->dev); + if (!mmc) { + dev_err(dev, "mmc_alloc_host failed\n"); + result = -ENOMEM; + goto err; + } + host = mmc_priv(mmc); + + host->iobase = iobase; + host->dev = dev; + host->pci_dev = pci_dev; + + mmc->ops = &sdricoh_ops; + + /* FIXME: frequency and voltage handling is done by the controller + */ + mmc->f_min = 450000; + mmc->f_max = 24000000; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->caps |= MMC_CAP_4_BIT_DATA; + + mmc->max_seg_size = 1024 * 512; + mmc->max_blk_size = 512; + + /* reset the controler */ + if (sdricoh_reset(host)) { + dev_dbg(dev, "could not reset\n"); + result = -EIO; + goto err; + + } + + result = mmc_add_host(mmc); + + if (!result) { + dev_dbg(dev, "mmc host registered\n"); + return 0; + } + +err: + if (iobase) + iounmap(iobase); + if (mmc) + mmc_free_host(mmc); + + return result; +} + +/* search for supported mmc controllers */ +static int sdricoh_pcmcia_probe(struct pcmcia_device *pcmcia_dev) +{ + struct pci_dev *pci_dev = NULL; + + dev_info(&pcmcia_dev->dev, "Searching MMC controller for pcmcia device" + " %s %s ...\n", pcmcia_dev->prod_id[0], pcmcia_dev->prod_id[1]); + + /* search pci cardbus bridge that contains the mmc controler */ + /* the io region is already claimed by yenta_socket... */ + while ((pci_dev = + pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, + pci_dev))) { + /* try to init the device */ + if (!sdricoh_init_mmc(pci_dev, pcmcia_dev)) { + dev_info(&pcmcia_dev->dev, "MMC controller found\n"); + return 0; + } + + } + dev_err(&pcmcia_dev->dev, "No MMC controller was found.\n"); + return -ENODEV; +} + +static void sdricoh_pcmcia_detach(struct pcmcia_device *link) +{ + struct mmc_host *mmc = link->priv; + + dev_dbg(&link->dev, "detach\n"); + + /* remove mmc host */ + if (mmc) { + struct sdricoh_host *host = mmc_priv(mmc); + mmc_remove_host(mmc); + pci_iounmap(host->pci_dev, host->iobase); + pci_dev_put(host->pci_dev); + mmc_free_host(mmc); + } + pcmcia_disable_device(link); + +} + +#ifdef CONFIG_PM +static int sdricoh_pcmcia_suspend(struct pcmcia_device *link) +{ + struct mmc_host *mmc = link->priv; + dev_dbg(&link->dev, "suspend\n"); + mmc_suspend_host(mmc, PMSG_SUSPEND); + return 0; +} + +static int sdricoh_pcmcia_resume(struct pcmcia_device *link) +{ + struct mmc_host *mmc = link->priv; + dev_dbg(&link->dev, "resume\n"); + sdricoh_reset(mmc_priv(mmc)); + mmc_resume_host(mmc); + return 0; +} +#else +#define sdricoh_pcmcia_suspend NULL +#define sdricoh_pcmcia_resume NULL +#endif + +static struct pcmcia_driver sdricoh_driver = { + .drv = { + .name = DRIVER_NAME, + }, + .probe = sdricoh_pcmcia_probe, + .remove = sdricoh_pcmcia_detach, + .id_table = pcmcia_ids, + .suspend = sdricoh_pcmcia_suspend, + .resume = sdricoh_pcmcia_resume, +}; + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int __init sdricoh_drv_init(void) +{ + return pcmcia_register_driver(&sdricoh_driver); +} + +static void __exit sdricoh_drv_exit(void) +{ + pcmcia_unregister_driver(&sdricoh_driver); +} + +module_init(sdricoh_drv_init); +module_exit(sdricoh_drv_exit); + +module_param(switchlocked, uint, 0444); + +MODULE_AUTHOR("Sascha Sommer "); +MODULE_DESCRIPTION("Ricoh PCMCIA Secure Digital Interface driver"); +MODULE_LICENSE("GPL"); + +MODULE_PARM_DESC(switchlocked, "Switch the cards locked status." + "Use this when unlocked cards are shown readonly (default 0)"); -- cgit v0.10.2 From c43d8636971c39da993e94082fd65bfff421618e Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 10 Jul 2008 12:28:48 +0100 Subject: sdio_uart: Fix SDIO break control to now return success or an error This is a consequence of patch 9ea761bfef52c116fed4715d4043392c2503fe6a. Signed-off-by: David Howells Signed-off-by: Pierre Ossman diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index eeea84c..78ad487 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -885,12 +885,14 @@ static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_t sdio_uart_release_func(port); } -static void sdio_uart_break_ctl(struct tty_struct *tty, int break_state) +static int sdio_uart_break_ctl(struct tty_struct *tty, int break_state) { struct sdio_uart_port *port = tty->driver_data; + int result; - if (sdio_uart_claim_func(port) != 0) - return; + result = sdio_uart_claim_func(port); + if (result != 0) + return result; if (break_state == -1) port->lcr |= UART_LCR_SBC; @@ -899,6 +901,7 @@ static void sdio_uart_break_ctl(struct tty_struct *tty, int break_state) sdio_out(port, UART_LCR, port->lcr); sdio_uart_release_func(port); + return 0; } static int sdio_uart_tiocmget(struct tty_struct *tty, struct file *file) -- cgit v0.10.2 From fe9233fb6914a0eb20166c967e3020f7f0fba2c9 Mon Sep 17 00:00:00 2001 From: Chandra Seetharaman Date: Fri, 23 May 2008 18:16:40 -0700 Subject: [SCSI] scsi_dh: fix kconfig related build errors Do not automatically "select" SCSI_DH for dm-multipath. If SCSI_DH doesn't exist,just do not allow hardware handlers to be used. Handle SCSI_DH being a module also. Make sure it doesn't allow DM_MULTIPATH to be compiled in when SCSI_DH is a module. [jejb: added comment for Kconfig syntax] Signed-off-by: Chandra Seetharaman Reported-by: Randy Dunlap Reported-by: Andrew Morton Signed-off-by: James Bottomley diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index b4a3c7d..07d92c1 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -252,7 +252,11 @@ config DM_ZERO config DM_MULTIPATH tristate "Multipath target" depends on BLK_DEV_DM - select SCSI_DH + # nasty syntax but means make DM_MULTIPATH independent + # of SCSI_DH if the latter isn't defined but if + # it is, DM_MULTIPATH must depend on it. We get a build + # error if SCSI_DH=m and DM_MULTIPATH=y + depends on SCSI_DH || !SCSI_DH ---help--- Allow volume managers to support multipath hardware. diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index e8f704a..9f7302d 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -664,6 +664,8 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) request_module("scsi_dh_%s", m->hw_handler_name); if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { ti->error = "unknown hardware handler type"; + kfree(m->hw_handler_name); + m->hw_handler_name = NULL; return -EINVAL; } consume(as, hw_argc - 1); diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h index 04d0d84..3ad2303 100644 --- a/include/scsi/scsi_dh.h +++ b/include/scsi/scsi_dh.h @@ -54,6 +54,16 @@ enum { SCSI_DH_NOSYS, SCSI_DH_DRIVER_MAX, }; - +#if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE) extern int scsi_dh_activate(struct request_queue *); extern int scsi_dh_handler_exist(const char *); +#else +static inline int scsi_dh_activate(struct request_queue *req) +{ + return 0; +} +static inline int scsi_dh_handler_exist(const char *name) +{ + return 0; +} +#endif -- cgit v0.10.2 From 1e51764a3c2ac05a23a22b2a95ddee4d9bffb16d Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 19:08:37 +0300 Subject: UBIFS: add new flash file system This is a new flash file system. See http://www.linux-mtd.infradead.org/doc/ubifs.html Signed-off-by: Artem Bityutskiy Signed-off-by: Adrian Hunter diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c new file mode 100644 index 0000000..d81fb9e --- /dev/null +++ b/fs/ubifs/budget.c @@ -0,0 +1,731 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements the budgeting sub-system which is responsible for UBIFS + * space management. + * + * Factors such as compression, wasted space at the ends of LEBs, space in other + * journal heads, the effect of updates on the index, and so on, make it + * impossible to accurately predict the amount of space needed. Consequently + * approximations are used. + */ + +#include "ubifs.h" +#include +#include + +/* + * When pessimistic budget calculations say that there is no enough space, + * UBIFS starts writing back dirty inodes and pages, doing garbage collection, + * or committing. The below constants define maximum number of times UBIFS + * repeats the operations. + */ +#define MAX_SHRINK_RETRIES 8 +#define MAX_GC_RETRIES 4 +#define MAX_CMT_RETRIES 2 +#define MAX_NOSPC_RETRIES 1 + +/* + * The below constant defines amount of dirty pages which should be written + * back at when trying to shrink the liability. + */ +#define NR_TO_WRITE 16 + +/** + * struct retries_info - information about re-tries while making free space. + * @prev_liability: previous liability + * @shrink_cnt: how many times the liability was shrinked + * @shrink_retries: count of liability shrink re-tries (increased when + * liability does not shrink) + * @try_gc: GC should be tried first + * @gc_retries: how many times GC was run + * @cmt_retries: how many times commit has been done + * @nospc_retries: how many times GC returned %-ENOSPC + * + * Since we consider budgeting to be the fast-path, and this structure has to + * be allocated on stack and zeroed out, we make it smaller using bit-fields. + */ +struct retries_info { + long long prev_liability; + unsigned int shrink_cnt; + unsigned int shrink_retries:5; + unsigned int try_gc:1; + unsigned int gc_retries:4; + unsigned int cmt_retries:3; + unsigned int nospc_retries:1; +}; + +/** + * shrink_liability - write-back some dirty pages/inodes. + * @c: UBIFS file-system description object + * @nr_to_write: how many dirty pages to write-back + * + * This function shrinks UBIFS liability by means of writing back some amount + * of dirty inodes and their pages. Returns the amount of pages which were + * written back. The returned value does not include dirty inodes which were + * synchronized. + * + * Note, this function synchronizes even VFS inodes which are locked + * (@i_mutex) by the caller of the budgeting function, because write-back does + * not touch @i_mutex. + */ +static int shrink_liability(struct ubifs_info *c, int nr_to_write) +{ + int nr_written; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_NONE, + .range_end = LLONG_MAX, + .nr_to_write = nr_to_write, + }; + + generic_sync_sb_inodes(c->vfs_sb, &wbc); + nr_written = nr_to_write - wbc.nr_to_write; + + if (!nr_written) { + /* + * Re-try again but wait on pages/inodes which are being + * written-back concurrently (e.g., by pdflush). + */ + memset(&wbc, 0, sizeof(struct writeback_control)); + wbc.sync_mode = WB_SYNC_ALL; + wbc.range_end = LLONG_MAX; + wbc.nr_to_write = nr_to_write; + generic_sync_sb_inodes(c->vfs_sb, &wbc); + nr_written = nr_to_write - wbc.nr_to_write; + } + + dbg_budg("%d pages were written back", nr_written); + return nr_written; +} + + +/** + * run_gc - run garbage collector. + * @c: UBIFS file-system description object + * + * This function runs garbage collector to make some more free space. Returns + * zero if a free LEB has been produced, %-EAGAIN if commit is required, and a + * negative error code in case of failure. + */ +static int run_gc(struct ubifs_info *c) +{ + int err, lnum; + + /* Make some free space by garbage-collecting dirty space */ + down_read(&c->commit_sem); + lnum = ubifs_garbage_collect(c, 1); + up_read(&c->commit_sem); + if (lnum < 0) + return lnum; + + /* GC freed one LEB, return it to lprops */ + dbg_budg("GC freed LEB %d", lnum); + err = ubifs_return_leb(c, lnum); + if (err) + return err; + return 0; +} + +/** + * make_free_space - make more free space on the file-system. + * @c: UBIFS file-system description object + * @ri: information about previous invocations of this function + * + * This function is called when an operation cannot be budgeted because there + * is supposedly no free space. But in most cases there is some free space: + * o budgeting is pessimistic, so it always budgets more then it is actually + * needed, so shrinking the liability is one way to make free space - the + * cached data will take less space then it was budgeted for; + * o GC may turn some dark space into free space (budgeting treats dark space + * as not available); + * o commit may free some LEB, i.e., turn freeable LEBs into free LEBs. + * + * So this function tries to do the above. Returns %-EAGAIN if some free space + * was presumably made and the caller has to re-try budgeting the operation. + * Returns %-ENOSPC if it couldn't do more free space, and other negative error + * codes on failures. + */ +static int make_free_space(struct ubifs_info *c, struct retries_info *ri) +{ + int err; + + /* + * If we have some dirty pages and inodes (liability), try to write + * them back unless this was tried too many times without effect + * already. + */ + if (ri->shrink_retries < MAX_SHRINK_RETRIES && !ri->try_gc) { + long long liability; + + spin_lock(&c->space_lock); + liability = c->budg_idx_growth + c->budg_data_growth + + c->budg_dd_growth; + spin_unlock(&c->space_lock); + + if (ri->prev_liability >= liability) { + /* Liability does not shrink, next time try GC then */ + ri->shrink_retries += 1; + if (ri->gc_retries < MAX_GC_RETRIES) + ri->try_gc = 1; + dbg_budg("liability did not shrink: retries %d of %d", + ri->shrink_retries, MAX_SHRINK_RETRIES); + } + + dbg_budg("force write-back (count %d)", ri->shrink_cnt); + shrink_liability(c, NR_TO_WRITE + ri->shrink_cnt); + + ri->prev_liability = liability; + ri->shrink_cnt += 1; + return -EAGAIN; + } + + /* + * Try to run garbage collector unless it was already tried too many + * times. + */ + if (ri->gc_retries < MAX_GC_RETRIES) { + ri->gc_retries += 1; + dbg_budg("run GC, retries %d of %d", + ri->gc_retries, MAX_GC_RETRIES); + + ri->try_gc = 0; + err = run_gc(c); + if (!err) + return -EAGAIN; + + if (err == -EAGAIN) { + dbg_budg("GC asked to commit"); + err = ubifs_run_commit(c); + if (err) + return err; + return -EAGAIN; + } + + if (err != -ENOSPC) + return err; + + /* + * GC could not make any progress. If this is the first time, + * then it makes sense to try to commit, because it might make + * some dirty space. + */ + dbg_budg("GC returned -ENOSPC, retries %d", + ri->nospc_retries); + if (ri->nospc_retries >= MAX_NOSPC_RETRIES) + return err; + ri->nospc_retries += 1; + } + + /* Neither GC nor write-back helped, try to commit */ + if (ri->cmt_retries < MAX_CMT_RETRIES) { + ri->cmt_retries += 1; + dbg_budg("run commit, retries %d of %d", + ri->cmt_retries, MAX_CMT_RETRIES); + err = ubifs_run_commit(c); + if (err) + return err; + return -EAGAIN; + } + return -ENOSPC; +} + +/** + * ubifs_calc_min_idx_lebs - calculate amount of eraseblocks for the index. + * @c: UBIFS file-system description object + * + * This function calculates and returns the number of eraseblocks which should + * be kept for index usage. + */ +int ubifs_calc_min_idx_lebs(struct ubifs_info *c) +{ + int ret; + uint64_t idx_size; + + idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; + + /* And make sure we have twice the index size of space reserved */ + idx_size <<= 1; + + /* + * We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes' + * pair, nor similarly the two variables for the new index size, so we + * have to do this costly 64-bit division on fast-path. + */ + if (do_div(idx_size, c->leb_size - c->max_idx_node_sz)) + ret = idx_size + 1; + else + ret = idx_size; + /* + * The index head is not available for the in-the-gaps method, so add an + * extra LEB to compensate. + */ + ret += 1; + /* + * At present the index needs at least 2 LEBs: one for the index head + * and one for in-the-gaps method (which currently does not cater for + * the index head and so excludes it from consideration). + */ + if (ret < 2) + ret = 2; + return ret; +} + +/** + * ubifs_calc_available - calculate available FS space. + * @c: UBIFS file-system description object + * @min_idx_lebs: minimum number of LEBs reserved for the index + * + * This function calculates and returns amount of FS space available for use. + */ +long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs) +{ + int subtract_lebs; + long long available; + + /* + * Force the amount available to the total size reported if the used + * space is zero. + */ + if (c->lst.total_used <= UBIFS_INO_NODE_SZ && + c->budg_data_growth + c->budg_dd_growth == 0) { + /* Do the same calculation as for c->block_cnt */ + available = c->main_lebs - 2; + available *= c->leb_size - c->dark_wm; + return available; + } + + available = c->main_bytes - c->lst.total_used; + + /* + * Now 'available' contains theoretically available flash space + * assuming there is no index, so we have to subtract the space which + * is reserved for the index. + */ + subtract_lebs = min_idx_lebs; + + /* Take into account that GC reserves one LEB for its own needs */ + subtract_lebs += 1; + + /* + * The GC journal head LEB is not really accessible. And since + * different write types go to different heads, we may count only on + * one head's space. + */ + subtract_lebs += c->jhead_cnt - 1; + + /* We also reserve one LEB for deletions, which bypass budgeting */ + subtract_lebs += 1; + + available -= (long long)subtract_lebs * c->leb_size; + + /* Subtract the dead space which is not available for use */ + available -= c->lst.total_dead; + + /* + * Subtract dark space, which might or might not be usable - it depends + * on the data which we have on the media and which will be written. If + * this is a lot of uncompressed or not-compressible data, the dark + * space cannot be used. + */ + available -= c->lst.total_dark; + + /* + * However, there is more dark space. The index may be bigger than + * @min_idx_lebs. Those extra LEBs are assumed to be available, but + * their dark space is not included in total_dark, so it is subtracted + * here. + */ + if (c->lst.idx_lebs > min_idx_lebs) { + subtract_lebs = c->lst.idx_lebs - min_idx_lebs; + available -= subtract_lebs * c->dark_wm; + } + + /* The calculations are rough and may end up with a negative number */ + return available > 0 ? available : 0; +} + +/** + * can_use_rp - check whether the user is allowed to use reserved pool. + * @c: UBIFS file-system description object + * + * UBIFS has so-called "reserved pool" which is flash space reserved + * for the superuser and for uses whose UID/GID is recorded in UBIFS superblock. + * This function checks whether current user is allowed to use reserved pool. + * Returns %1 current user is allowed to use reserved pool and %0 otherwise. + */ +static int can_use_rp(struct ubifs_info *c) +{ + if (current->fsuid == c->rp_uid || capable(CAP_SYS_RESOURCE) || + (c->rp_gid != 0 && in_group_p(c->rp_gid))) + return 1; + return 0; +} + +/** + * do_budget_space - reserve flash space for index and data growth. + * @c: UBIFS file-system description object + * + * This function makes sure UBIFS has enough free eraseblocks for index growth + * and data. + * + * When budgeting index space, UBIFS reserves twice as more LEBs as the index + * would take if it was consolidated and written to the flash. This guarantees + * that the "in-the-gaps" commit method always succeeds and UBIFS will always + * be able to commit dirty index. So this function basically adds amount of + * budgeted index space to the size of the current index, multiplies this by 2, + * and makes sure this does not exceed the amount of free eraseblocks. + * + * Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables: + * o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might + * be large, because UBIFS does not do any index consolidation as long as + * there is free space. IOW, the index may take a lot of LEBs, but the LEBs + * will contain a lot of dirt. + * o @c->min_idx_lebs is the the index presumably takes. IOW, the index may be + * consolidated to take up to @c->min_idx_lebs LEBs. + * + * This function returns zero in case of success, and %-ENOSPC in case of + * failure. + */ +static int do_budget_space(struct ubifs_info *c) +{ + long long outstanding, available; + int lebs, rsvd_idx_lebs, min_idx_lebs; + + /* First budget index space */ + min_idx_lebs = ubifs_calc_min_idx_lebs(c); + + /* Now 'min_idx_lebs' contains number of LEBs to reserve */ + if (min_idx_lebs > c->lst.idx_lebs) + rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs; + else + rsvd_idx_lebs = 0; + + /* + * The number of LEBs that are available to be used by the index is: + * + * @c->lst.empty_lebs + @c->freeable_cnt + @c->idx_gc_cnt - + * @c->lst.taken_empty_lebs + * + * @empty_lebs are available because they are empty. @freeable_cnt are + * available because they contain only free and dirty space and the + * index allocation always occurs after wbufs are synch'ed. + * @idx_gc_cnt are available because they are index LEBs that have been + * garbage collected (including trivial GC) and are awaiting the commit + * before they can be unmapped - note that the in-the-gaps method will + * grab these if it needs them. @taken_empty_lebs are empty_lebs that + * have already been allocated for some purpose (also includes those + * LEBs on the @idx_gc list). + * + * Note, @taken_empty_lebs may temporarily be higher by one because of + * the way we serialize LEB allocations and budgeting. See a comment in + * 'ubifs_find_free_space()'. + */ + lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - + c->lst.taken_empty_lebs; + if (unlikely(rsvd_idx_lebs > lebs)) { + dbg_budg("out of indexing space: min_idx_lebs %d (old %d), " + "rsvd_idx_lebs %d", min_idx_lebs, c->min_idx_lebs, + rsvd_idx_lebs); + return -ENOSPC; + } + + available = ubifs_calc_available(c, min_idx_lebs); + outstanding = c->budg_data_growth + c->budg_dd_growth; + + if (unlikely(available < outstanding)) { + dbg_budg("out of data space: available %lld, outstanding %lld", + available, outstanding); + return -ENOSPC; + } + + if (available - outstanding <= c->rp_size && !can_use_rp(c)) + return -ENOSPC; + + c->min_idx_lebs = min_idx_lebs; + return 0; +} + +/** + * calc_idx_growth - calculate approximate index growth from budgeting request. + * @c: UBIFS file-system description object + * @req: budgeting request + * + * For now we assume each new node adds one znode. But this is rather poor + * approximation, though. + */ +static int calc_idx_growth(const struct ubifs_info *c, + const struct ubifs_budget_req *req) +{ + int znodes; + + znodes = req->new_ino + (req->new_page << UBIFS_BLOCKS_PER_PAGE_SHIFT) + + req->new_dent; + return znodes * c->max_idx_node_sz; +} + +/** + * calc_data_growth - calculate approximate amount of new data from budgeting + * request. + * @c: UBIFS file-system description object + * @req: budgeting request + */ +static int calc_data_growth(const struct ubifs_info *c, + const struct ubifs_budget_req *req) +{ + int data_growth; + + data_growth = req->new_ino ? c->inode_budget : 0; + if (req->new_page) + data_growth += c->page_budget; + if (req->new_dent) + data_growth += c->dent_budget; + data_growth += req->new_ino_d; + return data_growth; +} + +/** + * calc_dd_growth - calculate approximate amount of data which makes other data + * dirty from budgeting request. + * @c: UBIFS file-system description object + * @req: budgeting request + */ +static int calc_dd_growth(const struct ubifs_info *c, + const struct ubifs_budget_req *req) +{ + int dd_growth; + + dd_growth = req->dirtied_page ? c->page_budget : 0; + + if (req->dirtied_ino) + dd_growth += c->inode_budget << (req->dirtied_ino - 1); + if (req->mod_dent) + dd_growth += c->dent_budget; + dd_growth += req->dirtied_ino_d; + return dd_growth; +} + +/** + * ubifs_budget_space - ensure there is enough space to complete an operation. + * @c: UBIFS file-system description object + * @req: budget request + * + * This function allocates budget for an operation. It uses pessimistic + * approximation of how much flash space the operation needs. The goal of this + * function is to make sure UBIFS always has flash space to flush all dirty + * pages, dirty inodes, and dirty znodes (liability). This function may force + * commit, garbage-collection or write-back. Returns zero in case of success, + * %-ENOSPC if there is no free space and other negative error codes in case of + * failures. + */ +int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) +{ + int uninitialized_var(cmt_retries), uninitialized_var(wb_retries); + int err, idx_growth, data_growth, dd_growth; + struct retries_info ri; + + ubifs_assert(req->dirtied_ino <= 4); + ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); + + data_growth = calc_data_growth(c, req); + dd_growth = calc_dd_growth(c, req); + if (!data_growth && !dd_growth) + return 0; + idx_growth = calc_idx_growth(c, req); + memset(&ri, 0, sizeof(struct retries_info)); + +again: + spin_lock(&c->space_lock); + ubifs_assert(c->budg_idx_growth >= 0); + ubifs_assert(c->budg_data_growth >= 0); + ubifs_assert(c->budg_dd_growth >= 0); + + if (unlikely(c->nospace) && (c->nospace_rp || !can_use_rp(c))) { + dbg_budg("no space"); + spin_unlock(&c->space_lock); + return -ENOSPC; + } + + c->budg_idx_growth += idx_growth; + c->budg_data_growth += data_growth; + c->budg_dd_growth += dd_growth; + + err = do_budget_space(c); + if (likely(!err)) { + req->idx_growth = idx_growth; + req->data_growth = data_growth; + req->dd_growth = dd_growth; + spin_unlock(&c->space_lock); + return 0; + } + + /* Restore the old values */ + c->budg_idx_growth -= idx_growth; + c->budg_data_growth -= data_growth; + c->budg_dd_growth -= dd_growth; + spin_unlock(&c->space_lock); + + if (req->fast) { + dbg_budg("no space for fast budgeting"); + return err; + } + + err = make_free_space(c, &ri); + if (err == -EAGAIN) { + dbg_budg("try again"); + cond_resched(); + goto again; + } else if (err == -ENOSPC) { + dbg_budg("FS is full, -ENOSPC"); + c->nospace = 1; + if (can_use_rp(c) || c->rp_size == 0) + c->nospace_rp = 1; + smp_wmb(); + } else + ubifs_err("cannot budget space, error %d", err); + return err; +} + +/** + * ubifs_release_budget - release budgeted free space. + * @c: UBIFS file-system description object + * @req: budget request + * + * This function releases the space budgeted by 'ubifs_budget_space()'. Note, + * since the index changes (which were budgeted for in @req->idx_growth) will + * only be written to the media on commit, this function moves the index budget + * from @c->budg_idx_growth to @c->budg_uncommitted_idx. The latter will be + * zeroed by the commit operation. + */ +void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req) +{ + ubifs_assert(req->dirtied_ino <= 4); + ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); + if (!req->recalculate) { + ubifs_assert(req->idx_growth >= 0); + ubifs_assert(req->data_growth >= 0); + ubifs_assert(req->dd_growth >= 0); + } + + if (req->recalculate) { + req->data_growth = calc_data_growth(c, req); + req->dd_growth = calc_dd_growth(c, req); + req->idx_growth = calc_idx_growth(c, req); + } + + if (!req->data_growth && !req->dd_growth) + return; + + c->nospace = c->nospace_rp = 0; + smp_wmb(); + + spin_lock(&c->space_lock); + c->budg_idx_growth -= req->idx_growth; + c->budg_uncommitted_idx += req->idx_growth; + c->budg_data_growth -= req->data_growth; + c->budg_dd_growth -= req->dd_growth; + c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); + + ubifs_assert(c->budg_idx_growth >= 0); + ubifs_assert(c->budg_data_growth >= 0); + ubifs_assert(c->min_idx_lebs < c->main_lebs); + spin_unlock(&c->space_lock); +} + +/** + * ubifs_convert_page_budget - convert budget of a new page. + * @c: UBIFS file-system description object + * + * This function converts budget which was allocated for a new page of data to + * the budget of changing an existing page of data. The latter is smaller then + * the former, so this function only does simple re-calculation and does not + * involve any write-back. + */ +void ubifs_convert_page_budget(struct ubifs_info *c) +{ + spin_lock(&c->space_lock); + /* Release the index growth reservation */ + c->budg_idx_growth -= c->max_idx_node_sz << UBIFS_BLOCKS_PER_PAGE_SHIFT; + /* Release the data growth reservation */ + c->budg_data_growth -= c->page_budget; + /* Increase the dirty data growth reservation instead */ + c->budg_dd_growth += c->page_budget; + /* And re-calculate the indexing space reservation */ + c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); + spin_unlock(&c->space_lock); +} + +/** + * ubifs_release_dirty_inode_budget - release dirty inode budget. + * @c: UBIFS file-system description object + * @ui: UBIFS inode to release the budget for + * + * This function releases budget corresponding to a dirty inode. It is usually + * called when after the inode has been written to the media and marked as + * clean. + */ +void ubifs_release_dirty_inode_budget(struct ubifs_info *c, + struct ubifs_inode *ui) +{ + struct ubifs_budget_req req = {.dd_growth = c->inode_budget, + .dirtied_ino_d = ui->data_len}; + + ubifs_release_budget(c, &req); +} + +/** + * ubifs_budg_get_free_space - return amount of free space. + * @c: UBIFS file-system description object + * + * This function returns amount of free space on the file-system. + */ +long long ubifs_budg_get_free_space(struct ubifs_info *c) +{ + int min_idx_lebs, rsvd_idx_lebs; + long long available, outstanding, free; + + /* Do exactly the same calculations as in 'do_budget_space()' */ + spin_lock(&c->space_lock); + min_idx_lebs = ubifs_calc_min_idx_lebs(c); + + if (min_idx_lebs > c->lst.idx_lebs) + rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs; + else + rsvd_idx_lebs = 0; + + if (rsvd_idx_lebs > c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt + - c->lst.taken_empty_lebs) { + spin_unlock(&c->space_lock); + return 0; + } + + available = ubifs_calc_available(c, min_idx_lebs); + outstanding = c->budg_data_growth + c->budg_dd_growth; + c->min_idx_lebs = min_idx_lebs; + spin_unlock(&c->space_lock); + + if (available > outstanding) + free = ubifs_reported_space(c, available - outstanding); + else + free = 0; + return free; +} diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c new file mode 100644 index 0000000..3b51631 --- /dev/null +++ b/fs/ubifs/commit.c @@ -0,0 +1,677 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements functions that manage the running of the commit process. + * Each affected module has its own functions to accomplish their part in the + * commit and those functions are called here. + * + * The commit is the process whereby all updates to the index and LEB properties + * are written out together and the journal becomes empty. This keeps the + * file system consistent - at all times the state can be recreated by reading + * the index and LEB properties and then replaying the journal. + * + * The commit is split into two parts named "commit start" and "commit end". + * During commit start, the commit process has exclusive access to the journal + * by holding the commit semaphore down for writing. As few I/O operations as + * possible are performed during commit start, instead the nodes that are to be + * written are merely identified. During commit end, the commit semaphore is no + * longer held and the journal is again in operation, allowing users to continue + * to use the file system while the bulk of the commit I/O is performed. The + * purpose of this two-step approach is to prevent the commit from causing any + * latency blips. Note that in any case, the commit does not prevent lookups + * (as permitted by the TNC mutex), or access to VFS data structures e.g. page + * cache. + */ + +#include +#include +#include "ubifs.h" + +/** + * do_commit - commit the journal. + * @c: UBIFS file-system description object + * + * This function implements UBIFS commit. It has to be called with commit lock + * locked. Returns zero in case of success and a negative error code in case of + * failure. + */ +static int do_commit(struct ubifs_info *c) +{ + int err, new_ltail_lnum, old_ltail_lnum, i; + struct ubifs_zbranch zroot; + struct ubifs_lp_stats lst; + + dbg_cmt("start"); + if (c->ro_media) { + err = -EROFS; + goto out_up; + } + + /* Sync all write buffers (necessary for recovery) */ + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + goto out_up; + } + + err = ubifs_gc_start_commit(c); + if (err) + goto out_up; + err = dbg_check_lprops(c); + if (err) + goto out_up; + err = ubifs_log_start_commit(c, &new_ltail_lnum); + if (err) + goto out_up; + err = ubifs_tnc_start_commit(c, &zroot); + if (err) + goto out_up; + err = ubifs_lpt_start_commit(c); + if (err) + goto out_up; + err = ubifs_orphan_start_commit(c); + if (err) + goto out_up; + + ubifs_get_lp_stats(c, &lst); + + up_write(&c->commit_sem); + + err = ubifs_tnc_end_commit(c); + if (err) + goto out; + err = ubifs_lpt_end_commit(c); + if (err) + goto out; + err = ubifs_orphan_end_commit(c); + if (err) + goto out; + old_ltail_lnum = c->ltail_lnum; + err = ubifs_log_end_commit(c, new_ltail_lnum); + if (err) + goto out; + err = dbg_check_old_index(c, &zroot); + if (err) + goto out; + + mutex_lock(&c->mst_mutex); + c->mst_node->cmt_no = cpu_to_le64(++c->cmt_no); + c->mst_node->log_lnum = cpu_to_le32(new_ltail_lnum); + c->mst_node->root_lnum = cpu_to_le32(zroot.lnum); + c->mst_node->root_offs = cpu_to_le32(zroot.offs); + c->mst_node->root_len = cpu_to_le32(zroot.len); + c->mst_node->ihead_lnum = cpu_to_le32(c->ihead_lnum); + c->mst_node->ihead_offs = cpu_to_le32(c->ihead_offs); + c->mst_node->index_size = cpu_to_le64(c->old_idx_sz); + c->mst_node->lpt_lnum = cpu_to_le32(c->lpt_lnum); + c->mst_node->lpt_offs = cpu_to_le32(c->lpt_offs); + c->mst_node->nhead_lnum = cpu_to_le32(c->nhead_lnum); + c->mst_node->nhead_offs = cpu_to_le32(c->nhead_offs); + c->mst_node->ltab_lnum = cpu_to_le32(c->ltab_lnum); + c->mst_node->ltab_offs = cpu_to_le32(c->ltab_offs); + c->mst_node->lsave_lnum = cpu_to_le32(c->lsave_lnum); + c->mst_node->lsave_offs = cpu_to_le32(c->lsave_offs); + c->mst_node->lscan_lnum = cpu_to_le32(c->lscan_lnum); + c->mst_node->empty_lebs = cpu_to_le32(lst.empty_lebs); + c->mst_node->idx_lebs = cpu_to_le32(lst.idx_lebs); + c->mst_node->total_free = cpu_to_le64(lst.total_free); + c->mst_node->total_dirty = cpu_to_le64(lst.total_dirty); + c->mst_node->total_used = cpu_to_le64(lst.total_used); + c->mst_node->total_dead = cpu_to_le64(lst.total_dead); + c->mst_node->total_dark = cpu_to_le64(lst.total_dark); + if (c->no_orphs) + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); + else + c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_NO_ORPHS); + err = ubifs_write_master(c); + mutex_unlock(&c->mst_mutex); + if (err) + goto out; + + err = ubifs_log_post_commit(c, old_ltail_lnum); + if (err) + goto out; + err = ubifs_gc_end_commit(c); + if (err) + goto out; + err = ubifs_lpt_post_commit(c); + if (err) + goto out; + + spin_lock(&c->cs_lock); + c->cmt_state = COMMIT_RESTING; + wake_up(&c->cmt_wq); + dbg_cmt("commit end"); + spin_unlock(&c->cs_lock); + + return 0; + +out_up: + up_write(&c->commit_sem); +out: + ubifs_err("commit failed, error %d", err); + spin_lock(&c->cs_lock); + c->cmt_state = COMMIT_BROKEN; + wake_up(&c->cmt_wq); + spin_unlock(&c->cs_lock); + ubifs_ro_mode(c, err); + return err; +} + +/** + * run_bg_commit - run background commit if it is needed. + * @c: UBIFS file-system description object + * + * This function runs background commit if it is needed. Returns zero in case + * of success and a negative error code in case of failure. + */ +static int run_bg_commit(struct ubifs_info *c) +{ + spin_lock(&c->cs_lock); + /* + * Run background commit only if background commit was requested or if + * commit is required. + */ + if (c->cmt_state != COMMIT_BACKGROUND && + c->cmt_state != COMMIT_REQUIRED) + goto out; + spin_unlock(&c->cs_lock); + + down_write(&c->commit_sem); + spin_lock(&c->cs_lock); + if (c->cmt_state == COMMIT_REQUIRED) + c->cmt_state = COMMIT_RUNNING_REQUIRED; + else if (c->cmt_state == COMMIT_BACKGROUND) + c->cmt_state = COMMIT_RUNNING_BACKGROUND; + else + goto out_cmt_unlock; + spin_unlock(&c->cs_lock); + + return do_commit(c); + +out_cmt_unlock: + up_write(&c->commit_sem); +out: + spin_unlock(&c->cs_lock); + return 0; +} + +/** + * ubifs_bg_thread - UBIFS background thread function. + * @info: points to the file-system description object + * + * This function implements various file-system background activities: + * o when a write-buffer timer expires it synchronizes the appropriate + * write-buffer; + * o when the journal is about to be full, it starts in-advance commit. + * + * Note, other stuff like background garbage collection may be added here in + * future. + */ +int ubifs_bg_thread(void *info) +{ + int err; + struct ubifs_info *c = info; + + ubifs_msg("background thread \"%s\" started, PID %d", + c->bgt_name, current->pid); + set_freezable(); + + while (1) { + if (kthread_should_stop()) + break; + + if (try_to_freeze()) + continue; + + set_current_state(TASK_INTERRUPTIBLE); + /* Check if there is something to do */ + if (!c->need_bgt) { + /* + * Nothing prevents us from going sleep now and + * be never woken up and block the task which + * could wait in 'kthread_stop()' forever. + */ + if (kthread_should_stop()) + break; + schedule(); + continue; + } else + __set_current_state(TASK_RUNNING); + + c->need_bgt = 0; + err = ubifs_bg_wbufs_sync(c); + if (err) + ubifs_ro_mode(c, err); + + run_bg_commit(c); + cond_resched(); + } + + dbg_msg("background thread \"%s\" stops", c->bgt_name); + return 0; +} + +/** + * ubifs_commit_required - set commit state to "required". + * @c: UBIFS file-system description object + * + * This function is called if a commit is required but cannot be done from the + * calling function, so it is just flagged instead. + */ +void ubifs_commit_required(struct ubifs_info *c) +{ + spin_lock(&c->cs_lock); + switch (c->cmt_state) { + case COMMIT_RESTING: + case COMMIT_BACKGROUND: + dbg_cmt("old: %s, new: %s", dbg_cstate(c->cmt_state), + dbg_cstate(COMMIT_REQUIRED)); + c->cmt_state = COMMIT_REQUIRED; + break; + case COMMIT_RUNNING_BACKGROUND: + dbg_cmt("old: %s, new: %s", dbg_cstate(c->cmt_state), + dbg_cstate(COMMIT_RUNNING_REQUIRED)); + c->cmt_state = COMMIT_RUNNING_REQUIRED; + break; + case COMMIT_REQUIRED: + case COMMIT_RUNNING_REQUIRED: + case COMMIT_BROKEN: + break; + } + spin_unlock(&c->cs_lock); +} + +/** + * ubifs_request_bg_commit - notify the background thread to do a commit. + * @c: UBIFS file-system description object + * + * This function is called if the journal is full enough to make a commit + * worthwhile, so background thread is kicked to start it. + */ +void ubifs_request_bg_commit(struct ubifs_info *c) +{ + spin_lock(&c->cs_lock); + if (c->cmt_state == COMMIT_RESTING) { + dbg_cmt("old: %s, new: %s", dbg_cstate(c->cmt_state), + dbg_cstate(COMMIT_BACKGROUND)); + c->cmt_state = COMMIT_BACKGROUND; + spin_unlock(&c->cs_lock); + ubifs_wake_up_bgt(c); + } else + spin_unlock(&c->cs_lock); +} + +/** + * wait_for_commit - wait for commit. + * @c: UBIFS file-system description object + * + * This function sleeps until the commit operation is no longer running. + */ +static int wait_for_commit(struct ubifs_info *c) +{ + dbg_cmt("pid %d goes sleep", current->pid); + + /* + * The following sleeps if the condition is false, and will be woken + * when the commit ends. It is possible, although very unlikely, that we + * will wake up and see the subsequent commit running, rather than the + * one we were waiting for, and go back to sleep. However, we will be + * woken again, so there is no danger of sleeping forever. + */ + wait_event(c->cmt_wq, c->cmt_state != COMMIT_RUNNING_BACKGROUND && + c->cmt_state != COMMIT_RUNNING_REQUIRED); + dbg_cmt("commit finished, pid %d woke up", current->pid); + return 0; +} + +/** + * ubifs_run_commit - run or wait for commit. + * @c: UBIFS file-system description object + * + * This function runs commit and returns zero in case of success and a negative + * error code in case of failure. + */ +int ubifs_run_commit(struct ubifs_info *c) +{ + int err = 0; + + spin_lock(&c->cs_lock); + if (c->cmt_state == COMMIT_BROKEN) { + err = -EINVAL; + goto out; + } + + if (c->cmt_state == COMMIT_RUNNING_BACKGROUND) + /* + * We set the commit state to 'running required' to indicate + * that we want it to complete as quickly as possible. + */ + c->cmt_state = COMMIT_RUNNING_REQUIRED; + + if (c->cmt_state == COMMIT_RUNNING_REQUIRED) { + spin_unlock(&c->cs_lock); + return wait_for_commit(c); + } + spin_unlock(&c->cs_lock); + + /* Ok, the commit is indeed needed */ + + down_write(&c->commit_sem); + spin_lock(&c->cs_lock); + /* + * Since we unlocked 'c->cs_lock', the state may have changed, so + * re-check it. + */ + if (c->cmt_state == COMMIT_BROKEN) { + err = -EINVAL; + goto out_cmt_unlock; + } + + if (c->cmt_state == COMMIT_RUNNING_BACKGROUND) + c->cmt_state = COMMIT_RUNNING_REQUIRED; + + if (c->cmt_state == COMMIT_RUNNING_REQUIRED) { + up_write(&c->commit_sem); + spin_unlock(&c->cs_lock); + return wait_for_commit(c); + } + c->cmt_state = COMMIT_RUNNING_REQUIRED; + spin_unlock(&c->cs_lock); + + err = do_commit(c); + return err; + +out_cmt_unlock: + up_write(&c->commit_sem); +out: + spin_unlock(&c->cs_lock); + return err; +} + +/** + * ubifs_gc_should_commit - determine if it is time for GC to run commit. + * @c: UBIFS file-system description object + * + * This function is called by garbage collection to determine if commit should + * be run. If commit state is @COMMIT_BACKGROUND, which means that the journal + * is full enough to start commit, this function returns true. It is not + * absolutely necessary to commit yet, but it feels like this should be better + * then to keep doing GC. This function returns %1 if GC has to initiate commit + * and %0 if not. + */ +int ubifs_gc_should_commit(struct ubifs_info *c) +{ + int ret = 0; + + spin_lock(&c->cs_lock); + if (c->cmt_state == COMMIT_BACKGROUND) { + dbg_cmt("commit required now"); + c->cmt_state = COMMIT_REQUIRED; + } else + dbg_cmt("commit not requested"); + if (c->cmt_state == COMMIT_REQUIRED) + ret = 1; + spin_unlock(&c->cs_lock); + return ret; +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +/** + * struct idx_node - hold index nodes during index tree traversal. + * @list: list + * @iip: index in parent (slot number of this indexing node in the parent + * indexing node) + * @upper_key: all keys in this indexing node have to be less or equivalent to + * this key + * @idx: index node (8-byte aligned because all node structures must be 8-byte + * aligned) + */ +struct idx_node { + struct list_head list; + int iip; + union ubifs_key upper_key; + struct ubifs_idx_node idx __attribute__((aligned(8))); +}; + +/** + * dbg_old_index_check_init - get information for the next old index check. + * @c: UBIFS file-system description object + * @zroot: root of the index + * + * This function records information about the index that will be needed for the + * next old index check i.e. 'dbg_check_old_index()'. + * + * This function returns %0 on success and a negative error code on failure. + */ +int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot) +{ + struct ubifs_idx_node *idx; + int lnum, offs, len, err = 0; + + c->old_zroot = *zroot; + + lnum = c->old_zroot.lnum; + offs = c->old_zroot.offs; + len = c->old_zroot.len; + + idx = kmalloc(c->max_idx_node_sz, GFP_NOFS); + if (!idx) + return -ENOMEM; + + err = ubifs_read_node(c, idx, UBIFS_IDX_NODE, len, lnum, offs); + if (err) + goto out; + + c->old_zroot_level = le16_to_cpu(idx->level); + c->old_zroot_sqnum = le64_to_cpu(idx->ch.sqnum); +out: + kfree(idx); + return err; +} + +/** + * dbg_check_old_index - check the old copy of the index. + * @c: UBIFS file-system description object + * @zroot: root of the new index + * + * In order to be able to recover from an unclean unmount, a complete copy of + * the index must exist on flash. This is the "old" index. The commit process + * must write the "new" index to flash without overwriting or destroying any + * part of the old index. This function is run at commit end in order to check + * that the old index does indeed exist completely intact. + * + * This function returns %0 on success and a negative error code on failure. + */ +int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) +{ + int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt; + int first = 1, iip; + union ubifs_key lower_key, upper_key, l_key, u_key; + unsigned long long uninitialized_var(last_sqnum); + struct ubifs_idx_node *idx; + struct list_head list; + struct idx_node *i; + size_t sz; + + if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX)) + goto out; + + INIT_LIST_HEAD(&list); + + sz = sizeof(struct idx_node) + ubifs_idx_node_sz(c, c->fanout) - + UBIFS_IDX_NODE_SZ; + + /* Start at the old zroot */ + lnum = c->old_zroot.lnum; + offs = c->old_zroot.offs; + len = c->old_zroot.len; + iip = 0; + + /* + * Traverse the index tree preorder depth-first i.e. do a node and then + * its subtrees from left to right. + */ + while (1) { + struct ubifs_branch *br; + + /* Get the next index node */ + i = kmalloc(sz, GFP_NOFS); + if (!i) { + err = -ENOMEM; + goto out_free; + } + i->iip = iip; + /* Keep the index nodes on our path in a linked list */ + list_add_tail(&i->list, &list); + /* Read the index node */ + idx = &i->idx; + err = ubifs_read_node(c, idx, UBIFS_IDX_NODE, len, lnum, offs); + if (err) + goto out_free; + /* Validate index node */ + child_cnt = le16_to_cpu(idx->child_cnt); + if (child_cnt < 1 || child_cnt > c->fanout) { + err = 1; + goto out_dump; + } + if (first) { + first = 0; + /* Check root level and sqnum */ + if (le16_to_cpu(idx->level) != c->old_zroot_level) { + err = 2; + goto out_dump; + } + if (le64_to_cpu(idx->ch.sqnum) != c->old_zroot_sqnum) { + err = 3; + goto out_dump; + } + /* Set last values as though root had a parent */ + last_level = le16_to_cpu(idx->level) + 1; + last_sqnum = le64_to_cpu(idx->ch.sqnum) + 1; + key_read(c, ubifs_idx_key(c, idx), &lower_key); + highest_ino_key(c, &upper_key, INUM_WATERMARK); + } + key_copy(c, &upper_key, &i->upper_key); + if (le16_to_cpu(idx->level) != last_level - 1) { + err = 3; + goto out_dump; + } + /* + * The index is always written bottom up hence a child's sqnum + * is always less than the parents. + */ + if (le64_to_cpu(idx->ch.sqnum) >= last_sqnum) { + err = 4; + goto out_dump; + } + /* Check key range */ + key_read(c, ubifs_idx_key(c, idx), &l_key); + br = ubifs_idx_branch(c, idx, child_cnt - 1); + key_read(c, &br->key, &u_key); + if (keys_cmp(c, &lower_key, &l_key) > 0) { + err = 5; + goto out_dump; + } + if (keys_cmp(c, &upper_key, &u_key) < 0) { + err = 6; + goto out_dump; + } + if (keys_cmp(c, &upper_key, &u_key) == 0) + if (!is_hash_key(c, &u_key)) { + err = 7; + goto out_dump; + } + /* Go to next index node */ + if (le16_to_cpu(idx->level) == 0) { + /* At the bottom, so go up until can go right */ + while (1) { + /* Drop the bottom of the list */ + list_del(&i->list); + kfree(i); + /* No more list means we are done */ + if (list_empty(&list)) + goto out; + /* Look at the new bottom */ + i = list_entry(list.prev, struct idx_node, + list); + idx = &i->idx; + /* Can we go right */ + if (iip + 1 < le16_to_cpu(idx->child_cnt)) { + iip = iip + 1; + break; + } else + /* Nope, so go up again */ + iip = i->iip; + } + } else + /* Go down left */ + iip = 0; + /* + * We have the parent in 'idx' and now we set up for reading the + * child pointed to by slot 'iip'. + */ + last_level = le16_to_cpu(idx->level); + last_sqnum = le64_to_cpu(idx->ch.sqnum); + br = ubifs_idx_branch(c, idx, iip); + lnum = le32_to_cpu(br->lnum); + offs = le32_to_cpu(br->offs); + len = le32_to_cpu(br->len); + key_read(c, &br->key, &lower_key); + if (iip + 1 < le16_to_cpu(idx->child_cnt)) { + br = ubifs_idx_branch(c, idx, iip + 1); + key_read(c, &br->key, &upper_key); + } else + key_copy(c, &i->upper_key, &upper_key); + } +out: + err = dbg_old_index_check_init(c, zroot); + if (err) + goto out_free; + + return 0; + +out_dump: + dbg_err("dumping index node (iip=%d)", i->iip); + dbg_dump_node(c, idx); + list_del(&i->list); + kfree(i); + if (!list_empty(&list)) { + i = list_entry(list.prev, struct idx_node, list); + dbg_err("dumping parent index node"); + dbg_dump_node(c, &i->idx); + } +out_free: + while (!list_empty(&list)) { + i = list_entry(list.next, struct idx_node, list); + list_del(&i->list); + kfree(i); + } + ubifs_err("failed, error %d", err); + if (err > 0) + err = -EINVAL; + return err; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/compress.c b/fs/ubifs/compress.c new file mode 100644 index 0000000..5bb51da --- /dev/null +++ b/fs/ubifs/compress.c @@ -0,0 +1,253 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * Copyright (C) 2006, 2007 University of Szeged, Hungary + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + * Zoltan Sogor + */ + +/* + * This file provides a single place to access to compression and + * decompression. + */ + +#include +#include "ubifs.h" + +/* Fake description object for the "none" compressor */ +static struct ubifs_compressor none_compr = { + .compr_type = UBIFS_COMPR_NONE, + .name = "no compression", + .capi_name = "", +}; + +#ifdef CONFIG_UBIFS_FS_LZO +static DEFINE_MUTEX(lzo_mutex); + +static struct ubifs_compressor lzo_compr = { + .compr_type = UBIFS_COMPR_LZO, + .comp_mutex = &lzo_mutex, + .name = "LZO", + .capi_name = "lzo", +}; +#else +static struct ubifs_compressor lzo_compr = { + .compr_type = UBIFS_COMPR_LZO, + .name = "LZO", +}; +#endif + +#ifdef CONFIG_UBIFS_FS_ZLIB +static DEFINE_MUTEX(deflate_mutex); +static DEFINE_MUTEX(inflate_mutex); + +static struct ubifs_compressor zlib_compr = { + .compr_type = UBIFS_COMPR_ZLIB, + .comp_mutex = &deflate_mutex, + .decomp_mutex = &inflate_mutex, + .name = "zlib", + .capi_name = "deflate", +}; +#else +static struct ubifs_compressor zlib_compr = { + .compr_type = UBIFS_COMPR_ZLIB, + .name = "zlib", +}; +#endif + +/* All UBIFS compressors */ +struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; + +/** + * ubifs_compress - compress data. + * @in_buf: data to compress + * @in_len: length of the data to compress + * @out_buf: output buffer where compressed data should be stored + * @out_len: output buffer length is returned here + * @compr_type: type of compression to use on enter, actually used compression + * type on exit + * + * This function compresses input buffer @in_buf of length @in_len and stores + * the result in the output buffer @out_buf and the resulting length in + * @out_len. If the input buffer does not compress, it is just copied to the + * @out_buf. The same happens if @compr_type is %UBIFS_COMPR_NONE or if + * compression error occurred. + * + * Note, if the input buffer was not compressed, it is copied to the output + * buffer and %UBIFS_COMPR_NONE is returned in @compr_type. + * + * This functions returns %0 on success or a negative error code on failure. + */ +void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, + int *compr_type) +{ + int err; + struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; + + if (*compr_type == UBIFS_COMPR_NONE) + goto no_compr; + + /* If the input data is small, do not even try to compress it */ + if (in_len < UBIFS_MIN_COMPR_LEN) + goto no_compr; + + if (compr->comp_mutex) + mutex_lock(compr->comp_mutex); + err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf, + out_len); + if (compr->comp_mutex) + mutex_unlock(compr->comp_mutex); + if (unlikely(err)) { + ubifs_warn("cannot compress %d bytes, compressor %s, " + "error %d, leave data uncompressed", + in_len, compr->name, err); + goto no_compr; + } + + /* + * Presently, we just require that compression results in less data, + * rather than any defined minimum compression ratio or amount. + */ + if (ALIGN(*out_len, 8) >= ALIGN(in_len, 8)) + goto no_compr; + + return; + +no_compr: + memcpy(out_buf, in_buf, in_len); + *out_len = in_len; + *compr_type = UBIFS_COMPR_NONE; +} + +/** + * ubifs_decompress - decompress data. + * @in_buf: data to decompress + * @in_len: length of the data to decompress + * @out_buf: output buffer where decompressed data should + * @out_len: output length is returned here + * @compr_type: type of compression + * + * This function decompresses data from buffer @in_buf into buffer @out_buf. + * The length of the uncompressed data is returned in @out_len. This functions + * returns %0 on success or a negative error code on failure. + */ +int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, + int *out_len, int compr_type) +{ + int err; + struct ubifs_compressor *compr; + + if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { + ubifs_err("invalid compression type %d", compr_type); + return -EINVAL; + } + + compr = ubifs_compressors[compr_type]; + + if (unlikely(!compr->capi_name)) { + ubifs_err("%s compression is not compiled in", compr->name); + return -EINVAL; + } + + if (compr_type == UBIFS_COMPR_NONE) { + memcpy(out_buf, in_buf, in_len); + *out_len = in_len; + return 0; + } + + if (compr->decomp_mutex) + mutex_lock(compr->decomp_mutex); + err = crypto_comp_decompress(compr->cc, in_buf, in_len, out_buf, + out_len); + if (compr->decomp_mutex) + mutex_unlock(compr->decomp_mutex); + if (err) + ubifs_err("cannot decompress %d bytes, compressor %s, " + "error %d", in_len, compr->name, err); + + return err; +} + +/** + * compr_init - initialize a compressor. + * @compr: compressor description object + * + * This function initializes the requested compressor and returns zero in case + * of success or a negative error code in case of failure. + */ +static int __init compr_init(struct ubifs_compressor *compr) +{ + if (compr->capi_name) { + compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0); + if (IS_ERR(compr->cc)) { + ubifs_err("cannot initialize compressor %s, error %ld", + compr->name, PTR_ERR(compr->cc)); + return PTR_ERR(compr->cc); + } + } + + ubifs_compressors[compr->compr_type] = compr; + return 0; +} + +/** + * compr_exit - de-initialize a compressor. + * @compr: compressor description object + */ +static void compr_exit(struct ubifs_compressor *compr) +{ + if (compr->capi_name) + crypto_free_comp(compr->cc); + return; +} + +/** + * ubifs_compressors_init - initialize UBIFS compressors. + * + * This function initializes the compressor which were compiled in. Returns + * zero in case of success and a negative error code in case of failure. + */ +int __init ubifs_compressors_init(void) +{ + int err; + + err = compr_init(&lzo_compr); + if (err) + return err; + + err = compr_init(&zlib_compr); + if (err) + goto out_lzo; + + ubifs_compressors[UBIFS_COMPR_NONE] = &none_compr; + return 0; + +out_lzo: + compr_exit(&lzo_compr); + return err; +} + +/** + * ubifs_compressors_exit - de-initialize UBIFS compressors. + */ +void __exit ubifs_compressors_exit(void) +{ + compr_exit(&lzo_compr); + compr_exit(&zlib_compr); +} diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c new file mode 100644 index 0000000..4e3aaeb --- /dev/null +++ b/fs/ubifs/debug.c @@ -0,0 +1,2289 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements most of the debugging stuff which is compiled in only + * when it is enabled. But some debugging check functions are implemented in + * corresponding subsystem, just because they are closely related and utilize + * various local functions of those subsystems. + */ + +#define UBIFS_DBG_PRESERVE_UBI + +#include "ubifs.h" +#include +#include + +#ifdef CONFIG_UBIFS_FS_DEBUG + +DEFINE_SPINLOCK(dbg_lock); + +static char dbg_key_buf0[128]; +static char dbg_key_buf1[128]; + +unsigned int ubifs_msg_flags = UBIFS_MSG_FLAGS_DEFAULT; +unsigned int ubifs_chk_flags = UBIFS_CHK_FLAGS_DEFAULT; +unsigned int ubifs_tst_flags; + +module_param_named(debug_msgs, ubifs_msg_flags, uint, S_IRUGO | S_IWUSR); +module_param_named(debug_chks, ubifs_chk_flags, uint, S_IRUGO | S_IWUSR); +module_param_named(debug_tsts, ubifs_tst_flags, uint, S_IRUGO | S_IWUSR); + +MODULE_PARM_DESC(debug_msgs, "Debug message type flags"); +MODULE_PARM_DESC(debug_chks, "Debug check flags"); +MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); + +static const char *get_key_fmt(int fmt) +{ + switch (fmt) { + case UBIFS_SIMPLE_KEY_FMT: + return "simple"; + default: + return "unknown/invalid format"; + } +} + +static const char *get_key_hash(int hash) +{ + switch (hash) { + case UBIFS_KEY_HASH_R5: + return "R5"; + case UBIFS_KEY_HASH_TEST: + return "test"; + default: + return "unknown/invalid name hash"; + } +} + +static const char *get_key_type(int type) +{ + switch (type) { + case UBIFS_INO_KEY: + return "inode"; + case UBIFS_DENT_KEY: + return "direntry"; + case UBIFS_XENT_KEY: + return "xentry"; + case UBIFS_DATA_KEY: + return "data"; + case UBIFS_TRUN_KEY: + return "truncate"; + default: + return "unknown/invalid key"; + } +} + +static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key, + char *buffer) +{ + char *p = buffer; + int type = key_type(c, key); + + if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) { + switch (type) { + case UBIFS_INO_KEY: + sprintf(p, "(%lu, %s)", key_inum(c, key), + get_key_type(type)); + break; + case UBIFS_DENT_KEY: + case UBIFS_XENT_KEY: + sprintf(p, "(%lu, %s, %#08x)", key_inum(c, key), + get_key_type(type), key_hash(c, key)); + break; + case UBIFS_DATA_KEY: + sprintf(p, "(%lu, %s, %u)", key_inum(c, key), + get_key_type(type), key_block(c, key)); + break; + case UBIFS_TRUN_KEY: + sprintf(p, "(%lu, %s)", + key_inum(c, key), get_key_type(type)); + break; + default: + sprintf(p, "(bad key type: %#08x, %#08x)", + key->u32[0], key->u32[1]); + } + } else + sprintf(p, "bad key format %d", c->key_fmt); +} + +const char *dbg_key_str0(const struct ubifs_info *c, const union ubifs_key *key) +{ + /* dbg_lock must be held */ + sprintf_key(c, key, dbg_key_buf0); + return dbg_key_buf0; +} + +const char *dbg_key_str1(const struct ubifs_info *c, const union ubifs_key *key) +{ + /* dbg_lock must be held */ + sprintf_key(c, key, dbg_key_buf1); + return dbg_key_buf1; +} + +const char *dbg_ntype(int type) +{ + switch (type) { + case UBIFS_PAD_NODE: + return "padding node"; + case UBIFS_SB_NODE: + return "superblock node"; + case UBIFS_MST_NODE: + return "master node"; + case UBIFS_REF_NODE: + return "reference node"; + case UBIFS_INO_NODE: + return "inode node"; + case UBIFS_DENT_NODE: + return "direntry node"; + case UBIFS_XENT_NODE: + return "xentry node"; + case UBIFS_DATA_NODE: + return "data node"; + case UBIFS_TRUN_NODE: + return "truncate node"; + case UBIFS_IDX_NODE: + return "indexing node"; + case UBIFS_CS_NODE: + return "commit start node"; + case UBIFS_ORPH_NODE: + return "orphan node"; + default: + return "unknown node"; + } +} + +static const char *dbg_gtype(int type) +{ + switch (type) { + case UBIFS_NO_NODE_GROUP: + return "no node group"; + case UBIFS_IN_NODE_GROUP: + return "in node group"; + case UBIFS_LAST_OF_NODE_GROUP: + return "last of node group"; + default: + return "unknown"; + } +} + +const char *dbg_cstate(int cmt_state) +{ + switch (cmt_state) { + case COMMIT_RESTING: + return "commit resting"; + case COMMIT_BACKGROUND: + return "background commit requested"; + case COMMIT_REQUIRED: + return "commit required"; + case COMMIT_RUNNING_BACKGROUND: + return "BACKGROUND commit running"; + case COMMIT_RUNNING_REQUIRED: + return "commit running and required"; + case COMMIT_BROKEN: + return "broken commit"; + default: + return "unknown commit state"; + } +} + +static void dump_ch(const struct ubifs_ch *ch) +{ + printk(KERN_DEBUG "\tmagic %#x\n", le32_to_cpu(ch->magic)); + printk(KERN_DEBUG "\tcrc %#x\n", le32_to_cpu(ch->crc)); + printk(KERN_DEBUG "\tnode_type %d (%s)\n", ch->node_type, + dbg_ntype(ch->node_type)); + printk(KERN_DEBUG "\tgroup_type %d (%s)\n", ch->group_type, + dbg_gtype(ch->group_type)); + printk(KERN_DEBUG "\tsqnum %llu\n", + (unsigned long long)le64_to_cpu(ch->sqnum)); + printk(KERN_DEBUG "\tlen %u\n", le32_to_cpu(ch->len)); +} + +void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode) +{ + const struct ubifs_inode *ui = ubifs_inode(inode); + + printk(KERN_DEBUG "inode %lu\n", inode->i_ino); + printk(KERN_DEBUG "size %llu\n", + (unsigned long long)i_size_read(inode)); + printk(KERN_DEBUG "nlink %u\n", inode->i_nlink); + printk(KERN_DEBUG "uid %u\n", (unsigned int)inode->i_uid); + printk(KERN_DEBUG "gid %u\n", (unsigned int)inode->i_gid); + printk(KERN_DEBUG "atime %u.%u\n", + (unsigned int)inode->i_atime.tv_sec, + (unsigned int)inode->i_atime.tv_nsec); + printk(KERN_DEBUG "mtime %u.%u\n", + (unsigned int)inode->i_mtime.tv_sec, + (unsigned int)inode->i_mtime.tv_nsec); + printk(KERN_DEBUG "ctime %u.%u\n", + (unsigned int)inode->i_ctime.tv_sec, + (unsigned int)inode->i_ctime.tv_nsec); + printk(KERN_DEBUG "creat_sqnum %llu\n", ui->creat_sqnum); + printk(KERN_DEBUG "xattr_size %u\n", ui->xattr_size); + printk(KERN_DEBUG "xattr_cnt %u\n", ui->xattr_cnt); + printk(KERN_DEBUG "xattr_names %u\n", ui->xattr_names); + printk(KERN_DEBUG "dirty %u\n", ui->dirty); + printk(KERN_DEBUG "xattr %u\n", ui->xattr); + printk(KERN_DEBUG "flags %d\n", ui->flags); + printk(KERN_DEBUG "compr_type %d\n", ui->compr_type); + printk(KERN_DEBUG "data_len %d\n", ui->data_len); +} + +void dbg_dump_node(const struct ubifs_info *c, const void *node) +{ + int i, n; + union ubifs_key key; + const struct ubifs_ch *ch = node; + + if (dbg_failure_mode) + return; + + /* If the magic is incorrect, just hexdump the first bytes */ + if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) { + printk(KERN_DEBUG "Not a node, first %zu bytes:", UBIFS_CH_SZ); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + (void *)node, UBIFS_CH_SZ, 1); + return; + } + + spin_lock(&dbg_lock); + dump_ch(node); + + switch (ch->node_type) { + case UBIFS_PAD_NODE: + { + const struct ubifs_pad_node *pad = node; + + printk(KERN_DEBUG "\tpad_len %u\n", + le32_to_cpu(pad->pad_len)); + break; + } + case UBIFS_SB_NODE: + { + const struct ubifs_sb_node *sup = node; + unsigned int sup_flags = le32_to_cpu(sup->flags); + + printk(KERN_DEBUG "\tkey_hash %d (%s)\n", + (int)sup->key_hash, get_key_hash(sup->key_hash)); + printk(KERN_DEBUG "\tkey_fmt %d (%s)\n", + (int)sup->key_fmt, get_key_fmt(sup->key_fmt)); + printk(KERN_DEBUG "\tflags %#x\n", sup_flags); + printk(KERN_DEBUG "\t big_lpt %u\n", + !!(sup_flags & UBIFS_FLG_BIGLPT)); + printk(KERN_DEBUG "\tmin_io_size %u\n", + le32_to_cpu(sup->min_io_size)); + printk(KERN_DEBUG "\tleb_size %u\n", + le32_to_cpu(sup->leb_size)); + printk(KERN_DEBUG "\tleb_cnt %u\n", + le32_to_cpu(sup->leb_cnt)); + printk(KERN_DEBUG "\tmax_leb_cnt %u\n", + le32_to_cpu(sup->max_leb_cnt)); + printk(KERN_DEBUG "\tmax_bud_bytes %llu\n", + (unsigned long long)le64_to_cpu(sup->max_bud_bytes)); + printk(KERN_DEBUG "\tlog_lebs %u\n", + le32_to_cpu(sup->log_lebs)); + printk(KERN_DEBUG "\tlpt_lebs %u\n", + le32_to_cpu(sup->lpt_lebs)); + printk(KERN_DEBUG "\torph_lebs %u\n", + le32_to_cpu(sup->orph_lebs)); + printk(KERN_DEBUG "\tjhead_cnt %u\n", + le32_to_cpu(sup->jhead_cnt)); + printk(KERN_DEBUG "\tfanout %u\n", + le32_to_cpu(sup->fanout)); + printk(KERN_DEBUG "\tlsave_cnt %u\n", + le32_to_cpu(sup->lsave_cnt)); + printk(KERN_DEBUG "\tdefault_compr %u\n", + (int)le16_to_cpu(sup->default_compr)); + printk(KERN_DEBUG "\trp_size %llu\n", + (unsigned long long)le64_to_cpu(sup->rp_size)); + printk(KERN_DEBUG "\trp_uid %u\n", + le32_to_cpu(sup->rp_uid)); + printk(KERN_DEBUG "\trp_gid %u\n", + le32_to_cpu(sup->rp_gid)); + printk(KERN_DEBUG "\tfmt_version %u\n", + le32_to_cpu(sup->fmt_version)); + printk(KERN_DEBUG "\ttime_gran %u\n", + le32_to_cpu(sup->time_gran)); + printk(KERN_DEBUG "\tUUID %02X%02X%02X%02X-%02X%02X" + "-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", + sup->uuid[0], sup->uuid[1], sup->uuid[2], sup->uuid[3], + sup->uuid[4], sup->uuid[5], sup->uuid[6], sup->uuid[7], + sup->uuid[8], sup->uuid[9], sup->uuid[10], sup->uuid[11], + sup->uuid[12], sup->uuid[13], sup->uuid[14], + sup->uuid[15]); + break; + } + case UBIFS_MST_NODE: + { + const struct ubifs_mst_node *mst = node; + + printk(KERN_DEBUG "\thighest_inum %llu\n", + (unsigned long long)le64_to_cpu(mst->highest_inum)); + printk(KERN_DEBUG "\tcommit number %llu\n", + (unsigned long long)le64_to_cpu(mst->cmt_no)); + printk(KERN_DEBUG "\tflags %#x\n", + le32_to_cpu(mst->flags)); + printk(KERN_DEBUG "\tlog_lnum %u\n", + le32_to_cpu(mst->log_lnum)); + printk(KERN_DEBUG "\troot_lnum %u\n", + le32_to_cpu(mst->root_lnum)); + printk(KERN_DEBUG "\troot_offs %u\n", + le32_to_cpu(mst->root_offs)); + printk(KERN_DEBUG "\troot_len %u\n", + le32_to_cpu(mst->root_len)); + printk(KERN_DEBUG "\tgc_lnum %u\n", + le32_to_cpu(mst->gc_lnum)); + printk(KERN_DEBUG "\tihead_lnum %u\n", + le32_to_cpu(mst->ihead_lnum)); + printk(KERN_DEBUG "\tihead_offs %u\n", + le32_to_cpu(mst->ihead_offs)); + printk(KERN_DEBUG "\tindex_size %u\n", + le32_to_cpu(mst->index_size)); + printk(KERN_DEBUG "\tlpt_lnum %u\n", + le32_to_cpu(mst->lpt_lnum)); + printk(KERN_DEBUG "\tlpt_offs %u\n", + le32_to_cpu(mst->lpt_offs)); + printk(KERN_DEBUG "\tnhead_lnum %u\n", + le32_to_cpu(mst->nhead_lnum)); + printk(KERN_DEBUG "\tnhead_offs %u\n", + le32_to_cpu(mst->nhead_offs)); + printk(KERN_DEBUG "\tltab_lnum %u\n", + le32_to_cpu(mst->ltab_lnum)); + printk(KERN_DEBUG "\tltab_offs %u\n", + le32_to_cpu(mst->ltab_offs)); + printk(KERN_DEBUG "\tlsave_lnum %u\n", + le32_to_cpu(mst->lsave_lnum)); + printk(KERN_DEBUG "\tlsave_offs %u\n", + le32_to_cpu(mst->lsave_offs)); + printk(KERN_DEBUG "\tlscan_lnum %u\n", + le32_to_cpu(mst->lscan_lnum)); + printk(KERN_DEBUG "\tleb_cnt %u\n", + le32_to_cpu(mst->leb_cnt)); + printk(KERN_DEBUG "\tempty_lebs %u\n", + le32_to_cpu(mst->empty_lebs)); + printk(KERN_DEBUG "\tidx_lebs %u\n", + le32_to_cpu(mst->idx_lebs)); + printk(KERN_DEBUG "\ttotal_free %llu\n", + (unsigned long long)le64_to_cpu(mst->total_free)); + printk(KERN_DEBUG "\ttotal_dirty %llu\n", + (unsigned long long)le64_to_cpu(mst->total_dirty)); + printk(KERN_DEBUG "\ttotal_used %llu\n", + (unsigned long long)le64_to_cpu(mst->total_used)); + printk(KERN_DEBUG "\ttotal_dead %llu\n", + (unsigned long long)le64_to_cpu(mst->total_dead)); + printk(KERN_DEBUG "\ttotal_dark %llu\n", + (unsigned long long)le64_to_cpu(mst->total_dark)); + break; + } + case UBIFS_REF_NODE: + { + const struct ubifs_ref_node *ref = node; + + printk(KERN_DEBUG "\tlnum %u\n", + le32_to_cpu(ref->lnum)); + printk(KERN_DEBUG "\toffs %u\n", + le32_to_cpu(ref->offs)); + printk(KERN_DEBUG "\tjhead %u\n", + le32_to_cpu(ref->jhead)); + break; + } + case UBIFS_INO_NODE: + { + const struct ubifs_ino_node *ino = node; + + key_read(c, &ino->key, &key); + printk(KERN_DEBUG "\tkey %s\n", DBGKEY(&key)); + printk(KERN_DEBUG "\tcreat_sqnum %llu\n", + (unsigned long long)le64_to_cpu(ino->creat_sqnum)); + printk(KERN_DEBUG "\tsize %llu\n", + (unsigned long long)le64_to_cpu(ino->size)); + printk(KERN_DEBUG "\tnlink %u\n", + le32_to_cpu(ino->nlink)); + printk(KERN_DEBUG "\tatime %lld.%u\n", + (long long)le64_to_cpu(ino->atime_sec), + le32_to_cpu(ino->atime_nsec)); + printk(KERN_DEBUG "\tmtime %lld.%u\n", + (long long)le64_to_cpu(ino->mtime_sec), + le32_to_cpu(ino->mtime_nsec)); + printk(KERN_DEBUG "\tctime %lld.%u\n", + (long long)le64_to_cpu(ino->ctime_sec), + le32_to_cpu(ino->ctime_nsec)); + printk(KERN_DEBUG "\tuid %u\n", + le32_to_cpu(ino->uid)); + printk(KERN_DEBUG "\tgid %u\n", + le32_to_cpu(ino->gid)); + printk(KERN_DEBUG "\tmode %u\n", + le32_to_cpu(ino->mode)); + printk(KERN_DEBUG "\tflags %#x\n", + le32_to_cpu(ino->flags)); + printk(KERN_DEBUG "\txattr_cnt %u\n", + le32_to_cpu(ino->xattr_cnt)); + printk(KERN_DEBUG "\txattr_size %u\n", + le32_to_cpu(ino->xattr_size)); + printk(KERN_DEBUG "\txattr_names %u\n", + le32_to_cpu(ino->xattr_names)); + printk(KERN_DEBUG "\tcompr_type %#x\n", + (int)le16_to_cpu(ino->compr_type)); + printk(KERN_DEBUG "\tdata len %u\n", + le32_to_cpu(ino->data_len)); + break; + } + case UBIFS_DENT_NODE: + case UBIFS_XENT_NODE: + { + const struct ubifs_dent_node *dent = node; + int nlen = le16_to_cpu(dent->nlen); + + key_read(c, &dent->key, &key); + printk(KERN_DEBUG "\tkey %s\n", DBGKEY(&key)); + printk(KERN_DEBUG "\tinum %llu\n", + (unsigned long long)le64_to_cpu(dent->inum)); + printk(KERN_DEBUG "\ttype %d\n", (int)dent->type); + printk(KERN_DEBUG "\tnlen %d\n", nlen); + printk(KERN_DEBUG "\tname "); + + if (nlen > UBIFS_MAX_NLEN) + printk(KERN_DEBUG "(bad name length, not printing, " + "bad or corrupted node)"); + else { + for (i = 0; i < nlen && dent->name[i]; i++) + printk("%c", dent->name[i]); + } + printk("\n"); + + break; + } + case UBIFS_DATA_NODE: + { + const struct ubifs_data_node *dn = node; + int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ; + + key_read(c, &dn->key, &key); + printk(KERN_DEBUG "\tkey %s\n", DBGKEY(&key)); + printk(KERN_DEBUG "\tsize %u\n", + le32_to_cpu(dn->size)); + printk(KERN_DEBUG "\tcompr_typ %d\n", + (int)le16_to_cpu(dn->compr_type)); + printk(KERN_DEBUG "\tdata size %d\n", + dlen); + printk(KERN_DEBUG "\tdata:\n"); + print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_OFFSET, 32, 1, + (void *)&dn->data, dlen, 0); + break; + } + case UBIFS_TRUN_NODE: + { + const struct ubifs_trun_node *trun = node; + + printk(KERN_DEBUG "\tinum %u\n", + le32_to_cpu(trun->inum)); + printk(KERN_DEBUG "\told_size %llu\n", + (unsigned long long)le64_to_cpu(trun->old_size)); + printk(KERN_DEBUG "\tnew_size %llu\n", + (unsigned long long)le64_to_cpu(trun->new_size)); + break; + } + case UBIFS_IDX_NODE: + { + const struct ubifs_idx_node *idx = node; + + n = le16_to_cpu(idx->child_cnt); + printk(KERN_DEBUG "\tchild_cnt %d\n", n); + printk(KERN_DEBUG "\tlevel %d\n", + (int)le16_to_cpu(idx->level)); + printk(KERN_DEBUG "\tBranches:\n"); + + for (i = 0; i < n && i < c->fanout - 1; i++) { + const struct ubifs_branch *br; + + br = ubifs_idx_branch(c, idx, i); + key_read(c, &br->key, &key); + printk(KERN_DEBUG "\t%d: LEB %d:%d len %d key %s\n", + i, le32_to_cpu(br->lnum), le32_to_cpu(br->offs), + le32_to_cpu(br->len), DBGKEY(&key)); + } + break; + } + case UBIFS_CS_NODE: + break; + case UBIFS_ORPH_NODE: + { + const struct ubifs_orph_node *orph = node; + + printk(KERN_DEBUG "\tcommit number %llu\n", + (unsigned long long) + le64_to_cpu(orph->cmt_no) & LLONG_MAX); + printk(KERN_DEBUG "\tlast node flag %llu\n", + (unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63); + n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3; + printk(KERN_DEBUG "\t%d orphan inode numbers:\n", n); + for (i = 0; i < n; i++) + printk(KERN_DEBUG "\t ino %llu\n", + le64_to_cpu(orph->inos[i])); + break; + } + default: + printk(KERN_DEBUG "node type %d was not recognized\n", + (int)ch->node_type); + } + spin_unlock(&dbg_lock); +} + +void dbg_dump_budget_req(const struct ubifs_budget_req *req) +{ + spin_lock(&dbg_lock); + printk(KERN_DEBUG "Budgeting request: new_ino %d, dirtied_ino %d\n", + req->new_ino, req->dirtied_ino); + printk(KERN_DEBUG "\tnew_ino_d %d, dirtied_ino_d %d\n", + req->new_ino_d, req->dirtied_ino_d); + printk(KERN_DEBUG "\tnew_page %d, dirtied_page %d\n", + req->new_page, req->dirtied_page); + printk(KERN_DEBUG "\tnew_dent %d, mod_dent %d\n", + req->new_dent, req->mod_dent); + printk(KERN_DEBUG "\tidx_growth %d\n", req->idx_growth); + printk(KERN_DEBUG "\tdata_growth %d dd_growth %d\n", + req->data_growth, req->dd_growth); + spin_unlock(&dbg_lock); +} + +void dbg_dump_lstats(const struct ubifs_lp_stats *lst) +{ + spin_lock(&dbg_lock); + printk(KERN_DEBUG "Lprops statistics: empty_lebs %d, idx_lebs %d\n", + lst->empty_lebs, lst->idx_lebs); + printk(KERN_DEBUG "\ttaken_empty_lebs %d, total_free %lld, " + "total_dirty %lld\n", lst->taken_empty_lebs, lst->total_free, + lst->total_dirty); + printk(KERN_DEBUG "\ttotal_used %lld, total_dark %lld, " + "total_dead %lld\n", lst->total_used, lst->total_dark, + lst->total_dead); + spin_unlock(&dbg_lock); +} + +void dbg_dump_budg(struct ubifs_info *c) +{ + int i; + struct rb_node *rb; + struct ubifs_bud *bud; + struct ubifs_gced_idx_leb *idx_gc; + + spin_lock(&dbg_lock); + printk(KERN_DEBUG "Budgeting info: budg_data_growth %lld, " + "budg_dd_growth %lld, budg_idx_growth %lld\n", + c->budg_data_growth, c->budg_dd_growth, c->budg_idx_growth); + printk(KERN_DEBUG "\tdata budget sum %lld, total budget sum %lld, " + "freeable_cnt %d\n", c->budg_data_growth + c->budg_dd_growth, + c->budg_data_growth + c->budg_dd_growth + c->budg_idx_growth, + c->freeable_cnt); + printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %lld, " + "calc_idx_sz %lld, idx_gc_cnt %d\n", c->min_idx_lebs, + c->old_idx_sz, c->calc_idx_sz, c->idx_gc_cnt); + printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, " + "clean_zn_cnt %ld\n", atomic_long_read(&c->dirty_pg_cnt), + atomic_long_read(&c->dirty_zn_cnt), + atomic_long_read(&c->clean_zn_cnt)); + printk(KERN_DEBUG "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n", + 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); + 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); + } + list_for_each_entry(bud, &c->old_buds, list) + printk(KERN_DEBUG "\told bud LEB %d\n", bud->lnum); + list_for_each_entry(idx_gc, &c->idx_gc, list) + printk(KERN_DEBUG "\tGC'ed idx LEB %d unmap %d\n", + idx_gc->lnum, idx_gc->unmap); + printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state); + spin_unlock(&dbg_lock); +} + +void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp) +{ + printk(KERN_DEBUG "LEB %d lprops: free %d, dirty %d (used %d), " + "flags %#x\n", lp->lnum, lp->free, lp->dirty, + c->leb_size - lp->free - lp->dirty, lp->flags); +} + +void dbg_dump_lprops(struct ubifs_info *c) +{ + int lnum, err; + struct ubifs_lprops lp; + struct ubifs_lp_stats lst; + + printk(KERN_DEBUG "Dumping LEB properties\n"); + ubifs_get_lp_stats(c, &lst); + dbg_dump_lstats(&lst); + + for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) { + err = ubifs_read_one_lp(c, lnum, &lp); + if (err) + ubifs_err("cannot read lprops for LEB %d", lnum); + + dbg_dump_lprop(c, &lp); + } +} + +void dbg_dump_leb(const struct ubifs_info *c, int lnum) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + + if (dbg_failure_mode) + return; + + printk(KERN_DEBUG "Dumping LEB %d\n", lnum); + + sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); + if (IS_ERR(sleb)) { + ubifs_err("scan error %d", (int)PTR_ERR(sleb)); + return; + } + + printk(KERN_DEBUG "LEB %d has %d nodes ending at %d\n", lnum, + sleb->nodes_cnt, sleb->endpt); + + list_for_each_entry(snod, &sleb->nodes, list) { + cond_resched(); + printk(KERN_DEBUG "Dumping node at LEB %d:%d len %d\n", lnum, + snod->offs, snod->len); + dbg_dump_node(c, snod->node); + } + + ubifs_scan_destroy(sleb); + return; +} + +void dbg_dump_znode(const struct ubifs_info *c, + const struct ubifs_znode *znode) +{ + int n; + const struct ubifs_zbranch *zbr; + + spin_lock(&dbg_lock); + if (znode->parent) + zbr = &znode->parent->zbranch[znode->iip]; + else + zbr = &c->zroot; + + printk(KERN_DEBUG "znode %p, LEB %d:%d len %d parent %p iip %d level %d" + " child_cnt %d flags %lx\n", znode, zbr->lnum, zbr->offs, + zbr->len, znode->parent, znode->iip, znode->level, + znode->child_cnt, znode->flags); + + if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) { + spin_unlock(&dbg_lock); + return; + } + + printk(KERN_DEBUG "zbranches:\n"); + for (n = 0; n < znode->child_cnt; n++) { + zbr = &znode->zbranch[n]; + if (znode->level > 0) + printk(KERN_DEBUG "\t%d: znode %p LEB %d:%d len %d key " + "%s\n", n, zbr->znode, zbr->lnum, + zbr->offs, zbr->len, + DBGKEY(&zbr->key)); + else + printk(KERN_DEBUG "\t%d: LNC %p LEB %d:%d len %d key " + "%s\n", n, zbr->znode, zbr->lnum, + zbr->offs, zbr->len, + DBGKEY(&zbr->key)); + } + spin_unlock(&dbg_lock); +} + +void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat) +{ + int i; + + printk(KERN_DEBUG "Dumping heap cat %d (%d elements)\n", + cat, heap->cnt); + for (i = 0; i < heap->cnt; i++) { + struct ubifs_lprops *lprops = heap->arr[i]; + + printk(KERN_DEBUG "\t%d. LEB %d hpos %d free %d dirty %d " + "flags %d\n", i, lprops->lnum, lprops->hpos, + lprops->free, lprops->dirty, lprops->flags); + } +} + +void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, + struct ubifs_nnode *parent, int iip) +{ + int i; + + printk(KERN_DEBUG "Dumping pnode:\n"); + printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n", + (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); + printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n", + pnode->flags, iip, pnode->level, pnode->num); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_lprops *lp = &pnode->lprops[i]; + + printk(KERN_DEBUG "\t%d: free %d dirty %d flags %d lnum %d\n", + i, lp->free, lp->dirty, lp->flags, lp->lnum); + } +} + +void dbg_dump_tnc(struct ubifs_info *c) +{ + struct ubifs_znode *znode; + int level; + + printk(KERN_DEBUG "\n"); + printk(KERN_DEBUG "Dumping the TNC tree\n"); + znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); + level = znode->level; + printk(KERN_DEBUG "== Level %d ==\n", level); + while (znode) { + if (level != znode->level) { + level = znode->level; + printk(KERN_DEBUG "== Level %d ==\n", level); + } + dbg_dump_znode(c, znode); + znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); + } + + printk(KERN_DEBUG "\n"); +} + +static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode, + void *priv) +{ + dbg_dump_znode(c, znode); + return 0; +} + +/** + * dbg_dump_index - dump the on-flash index. + * @c: UBIFS file-system description object + * + * This function dumps whole UBIFS indexing B-tree, unlike 'dbg_dump_tnc()' + * which dumps only in-memory znodes and does not read znodes which from flash. + */ +void dbg_dump_index(struct ubifs_info *c) +{ + dbg_walk_index(c, NULL, dump_znode, NULL); +} + +/** + * dbg_check_synced_i_size - check synchronized inode size. + * @inode: inode to check + * + * If inode is clean, synchronized inode size has to be equivalent to current + * inode size. This function has to be called only for locked inodes (@i_mutex + * has to be locked). Returns %0 if synchronized inode size if correct, and + * %-EINVAL if not. + */ +int dbg_check_synced_i_size(struct inode *inode) +{ + int err = 0; + struct ubifs_inode *ui = ubifs_inode(inode); + + if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) + return 0; + if (!S_ISREG(inode->i_mode)) + return 0; + + mutex_lock(&ui->ui_mutex); + spin_lock(&ui->ui_lock); + if (ui->ui_size != ui->synced_i_size && !ui->dirty) { + ubifs_err("ui_size is %lld, synced_i_size is %lld, but inode " + "is clean", ui->ui_size, ui->synced_i_size); + ubifs_err("i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino, + inode->i_mode, i_size_read(inode)); + dbg_dump_stack(); + err = -EINVAL; + } + spin_unlock(&ui->ui_lock); + mutex_unlock(&ui->ui_mutex); + return err; +} + +/* + * dbg_check_dir - check directory inode size and link count. + * @c: UBIFS file-system description object + * @dir: the directory to calculate size for + * @size: the result is returned here + * + * This function makes sure that directory size and link count are correct. + * Returns zero in case of success and a negative error code in case of + * failure. + * + * Note, it is good idea to make sure the @dir->i_mutex is locked before + * calling this function. + */ +int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir) +{ + unsigned int nlink = 2; + union ubifs_key key; + struct ubifs_dent_node *dent, *pdent = NULL; + struct qstr nm = { .name = NULL }; + loff_t size = UBIFS_INO_NODE_SZ; + + if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) + return 0; + + if (!S_ISDIR(dir->i_mode)) + return 0; + + lowest_dent_key(c, &key, dir->i_ino); + while (1) { + int err; + + dent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(dent)) { + err = PTR_ERR(dent); + if (err == -ENOENT) + break; + return err; + } + + nm.name = dent->name; + nm.len = le16_to_cpu(dent->nlen); + size += CALC_DENT_SIZE(nm.len); + if (dent->type == UBIFS_ITYPE_DIR) + nlink += 1; + kfree(pdent); + pdent = dent; + key_read(c, &dent->key, &key); + } + kfree(pdent); + + if (i_size_read(dir) != size) { + ubifs_err("directory inode %lu has size %llu, " + "but calculated size is %llu", dir->i_ino, + (unsigned long long)i_size_read(dir), + (unsigned long long)size); + dump_stack(); + return -EINVAL; + } + if (dir->i_nlink != nlink) { + ubifs_err("directory inode %lu has nlink %u, but calculated " + "nlink is %u", dir->i_ino, dir->i_nlink, nlink); + dump_stack(); + return -EINVAL; + } + + return 0; +} + +/** + * dbg_check_key_order - make sure that colliding keys are properly ordered. + * @c: UBIFS file-system description object + * @zbr1: first zbranch + * @zbr2: following zbranch + * + * In UBIFS indexing B-tree colliding keys has to be sorted in binary order of + * names of the direntries/xentries which are referred by the keys. This + * function reads direntries/xentries referred by @zbr1 and @zbr2 and makes + * sure the name of direntry/xentry referred by @zbr1 is less than + * direntry/xentry referred by @zbr2. Returns zero if this is true, %1 if not, + * and a negative error code in case of failure. + */ +static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, + struct ubifs_zbranch *zbr2) +{ + int err, nlen1, nlen2, cmp; + struct ubifs_dent_node *dent1, *dent2; + union ubifs_key key; + + ubifs_assert(!keys_cmp(c, &zbr1->key, &zbr2->key)); + dent1 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); + if (!dent1) + return -ENOMEM; + dent2 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); + if (!dent2) { + err = -ENOMEM; + goto out_free; + } + + err = ubifs_tnc_read_node(c, zbr1, dent1); + if (err) + goto out_free; + err = ubifs_validate_entry(c, dent1); + if (err) + goto out_free; + + err = ubifs_tnc_read_node(c, zbr2, dent2); + if (err) + goto out_free; + err = ubifs_validate_entry(c, dent2); + if (err) + goto out_free; + + /* Make sure node keys are the same as in zbranch */ + err = 1; + key_read(c, &dent1->key, &key); + if (keys_cmp(c, &zbr1->key, &key)) { + dbg_err("1st entry at %d:%d has key %s", zbr1->lnum, + zbr1->offs, DBGKEY(&key)); + dbg_err("but it should have key %s according to tnc", + DBGKEY(&zbr1->key)); + dbg_dump_node(c, dent1); + goto out_free; + } + + key_read(c, &dent2->key, &key); + if (keys_cmp(c, &zbr2->key, &key)) { + dbg_err("2nd entry at %d:%d has key %s", zbr1->lnum, + zbr1->offs, DBGKEY(&key)); + dbg_err("but it should have key %s according to tnc", + DBGKEY(&zbr2->key)); + dbg_dump_node(c, dent2); + goto out_free; + } + + nlen1 = le16_to_cpu(dent1->nlen); + nlen2 = le16_to_cpu(dent2->nlen); + + cmp = memcmp(dent1->name, dent2->name, min_t(int, nlen1, nlen2)); + if (cmp < 0 || (cmp == 0 && nlen1 < nlen2)) { + err = 0; + goto out_free; + } + if (cmp == 0 && nlen1 == nlen2) + dbg_err("2 xent/dent nodes with the same name"); + else + dbg_err("bad order of colliding key %s", + DBGKEY(&key)); + + dbg_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs); + dbg_dump_node(c, dent1); + dbg_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs); + dbg_dump_node(c, dent2); + +out_free: + kfree(dent2); + kfree(dent1); + return err; +} + +/** + * dbg_check_znode - check if znode is all right. + * @c: UBIFS file-system description object + * @zbr: zbranch which points to this znode + * + * This function makes sure that znode referred to by @zbr is all right. + * Returns zero if it is, and %-EINVAL if it is not. + */ +static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr) +{ + struct ubifs_znode *znode = zbr->znode; + struct ubifs_znode *zp = znode->parent; + int n, err, cmp; + + if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) { + err = 1; + goto out; + } + if (znode->level < 0) { + err = 2; + goto out; + } + if (znode->iip < 0 || znode->iip >= c->fanout) { + err = 3; + goto out; + } + + if (zbr->len == 0) + /* Only dirty zbranch may have no on-flash nodes */ + if (!ubifs_zn_dirty(znode)) { + err = 4; + goto out; + } + + if (ubifs_zn_dirty(znode)) { + /* + * If znode is dirty, its parent has to be dirty as well. The + * order of the operation is important, so we have to have + * memory barriers. + */ + smp_mb(); + if (zp && !ubifs_zn_dirty(zp)) { + /* + * The dirty flag is atomic and is cleared outside the + * TNC mutex, so znode's dirty flag may now have + * been cleared. The child is always cleared before the + * parent, so we just need to check again. + */ + smp_mb(); + if (ubifs_zn_dirty(znode)) { + err = 5; + goto out; + } + } + } + + if (zp) { + const union ubifs_key *min, *max; + + if (znode->level != zp->level - 1) { + err = 6; + goto out; + } + + /* Make sure the 'parent' pointer in our znode is correct */ + err = ubifs_search_zbranch(c, zp, &zbr->key, &n); + if (!err) { + /* This zbranch does not exist in the parent */ + err = 7; + goto out; + } + + if (znode->iip >= zp->child_cnt) { + err = 8; + goto out; + } + + if (znode->iip != n) { + /* This may happen only in case of collisions */ + if (keys_cmp(c, &zp->zbranch[n].key, + &zp->zbranch[znode->iip].key)) { + err = 9; + goto out; + } + n = znode->iip; + } + + /* + * Make sure that the first key in our znode is greater than or + * equal to the key in the pointing zbranch. + */ + min = &zbr->key; + cmp = keys_cmp(c, min, &znode->zbranch[0].key); + if (cmp == 1) { + err = 10; + goto out; + } + + if (n + 1 < zp->child_cnt) { + max = &zp->zbranch[n + 1].key; + + /* + * Make sure the last key in our znode is less or + * equivalent than the the key in zbranch which goes + * after our pointing zbranch. + */ + cmp = keys_cmp(c, max, + &znode->zbranch[znode->child_cnt - 1].key); + if (cmp == -1) { + err = 11; + goto out; + } + } + } else { + /* This may only be root znode */ + if (zbr != &c->zroot) { + err = 12; + goto out; + } + } + + /* + * Make sure that next key is greater or equivalent then the previous + * one. + */ + for (n = 1; n < znode->child_cnt; n++) { + cmp = keys_cmp(c, &znode->zbranch[n - 1].key, + &znode->zbranch[n].key); + if (cmp > 0) { + err = 13; + goto out; + } + if (cmp == 0) { + /* This can only be keys with colliding hash */ + if (!is_hash_key(c, &znode->zbranch[n].key)) { + err = 14; + goto out; + } + + if (znode->level != 0 || c->replaying) + continue; + + /* + * Colliding keys should follow binary order of + * corresponding xentry/dentry names. + */ + err = dbg_check_key_order(c, &znode->zbranch[n - 1], + &znode->zbranch[n]); + if (err < 0) + return err; + if (err) { + err = 15; + goto out; + } + } + } + + for (n = 0; n < znode->child_cnt; n++) { + if (!znode->zbranch[n].znode && + (znode->zbranch[n].lnum == 0 || + znode->zbranch[n].len == 0)) { + err = 16; + goto out; + } + + if (znode->zbranch[n].lnum != 0 && + znode->zbranch[n].len == 0) { + err = 17; + goto out; + } + + if (znode->zbranch[n].lnum == 0 && + znode->zbranch[n].len != 0) { + err = 18; + goto out; + } + + if (znode->zbranch[n].lnum == 0 && + znode->zbranch[n].offs != 0) { + err = 19; + goto out; + } + + if (znode->level != 0 && znode->zbranch[n].znode) + if (znode->zbranch[n].znode->parent != znode) { + err = 20; + goto out; + } + } + + return 0; + +out: + ubifs_err("failed, error %d", err); + ubifs_msg("dump of the znode"); + dbg_dump_znode(c, znode); + if (zp) { + ubifs_msg("dump of the parent znode"); + dbg_dump_znode(c, zp); + } + dump_stack(); + return -EINVAL; +} + +/** + * dbg_check_tnc - check TNC tree. + * @c: UBIFS file-system description object + * @extra: do extra checks that are possible at start commit + * + * This function traverses whole TNC tree and checks every znode. Returns zero + * if everything is all right and %-EINVAL if something is wrong with TNC. + */ +int dbg_check_tnc(struct ubifs_info *c, int extra) +{ + struct ubifs_znode *znode; + long clean_cnt = 0, dirty_cnt = 0; + int err, last; + + if (!(ubifs_chk_flags & UBIFS_CHK_TNC)) + return 0; + + ubifs_assert(mutex_is_locked(&c->tnc_mutex)); + if (!c->zroot.znode) + return 0; + + znode = ubifs_tnc_postorder_first(c->zroot.znode); + while (1) { + struct ubifs_znode *prev; + struct ubifs_zbranch *zbr; + + if (!znode->parent) + zbr = &c->zroot; + else + zbr = &znode->parent->zbranch[znode->iip]; + + err = dbg_check_znode(c, zbr); + if (err) + return err; + + if (extra) { + if (ubifs_zn_dirty(znode)) + dirty_cnt += 1; + else + clean_cnt += 1; + } + + prev = znode; + znode = ubifs_tnc_postorder_next(znode); + if (!znode) + break; + + /* + * If the last key of this znode is equivalent to the first key + * of the next znode (collision), then check order of the keys. + */ + last = prev->child_cnt - 1; + if (prev->level == 0 && znode->level == 0 && !c->replaying && + !keys_cmp(c, &prev->zbranch[last].key, + &znode->zbranch[0].key)) { + err = dbg_check_key_order(c, &prev->zbranch[last], + &znode->zbranch[0]); + if (err < 0) + return err; + if (err) { + ubifs_msg("first znode"); + dbg_dump_znode(c, prev); + ubifs_msg("second znode"); + dbg_dump_znode(c, znode); + return -EINVAL; + } + } + } + + if (extra) { + if (clean_cnt != atomic_long_read(&c->clean_zn_cnt)) { + ubifs_err("incorrect clean_zn_cnt %ld, calculated %ld", + atomic_long_read(&c->clean_zn_cnt), + clean_cnt); + return -EINVAL; + } + if (dirty_cnt != atomic_long_read(&c->dirty_zn_cnt)) { + ubifs_err("incorrect dirty_zn_cnt %ld, calculated %ld", + atomic_long_read(&c->dirty_zn_cnt), + dirty_cnt); + return -EINVAL; + } + } + + return 0; +} + +/** + * dbg_walk_index - walk the on-flash index. + * @c: UBIFS file-system description object + * @leaf_cb: called for each leaf node + * @znode_cb: called for each indexing node + * @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 + * and a negative error code in case of failure. + * + * It would be better if this function removed every znode it pulled to into + * the TNC, so that the behavior more closely matched the non-debugging + * behavior. + */ +int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, + dbg_znode_callback znode_cb, void *priv) +{ + int err; + struct ubifs_zbranch *zbr; + struct ubifs_znode *znode, *child; + + mutex_lock(&c->tnc_mutex); + /* If the root indexing node is not in TNC - pull it */ + if (!c->zroot.znode) { + c->zroot.znode = ubifs_load_znode(c, &c->zroot, NULL, 0); + if (IS_ERR(c->zroot.znode)) { + err = PTR_ERR(c->zroot.znode); + c->zroot.znode = NULL; + goto out_unlock; + } + } + + /* + * We are going to traverse the indexing tree in the postorder manner. + * Go down and find the leftmost indexing node where we are going to + * start from. + */ + znode = c->zroot.znode; + while (znode->level > 0) { + zbr = &znode->zbranch[0]; + child = zbr->znode; + if (!child) { + child = ubifs_load_znode(c, zbr, znode, 0); + if (IS_ERR(child)) { + err = PTR_ERR(child); + goto out_unlock; + } + zbr->znode = child; + } + + znode = child; + } + + /* Iterate over all indexing nodes */ + while (1) { + int idx; + + cond_resched(); + + if (znode_cb) { + err = znode_cb(c, znode, priv); + if (err) { + ubifs_err("znode checking function returned " + "error %d", err); + dbg_dump_znode(c, znode); + goto out_dump; + } + } + if (leaf_cb && znode->level == 0) { + for (idx = 0; idx < znode->child_cnt; idx++) { + zbr = &znode->zbranch[idx]; + err = leaf_cb(c, zbr, priv); + if (err) { + ubifs_err("leaf checking function " + "returned error %d, for leaf " + "at LEB %d:%d", + err, zbr->lnum, zbr->offs); + goto out_dump; + } + } + } + + if (!znode->parent) + break; + + idx = znode->iip + 1; + znode = znode->parent; + if (idx < znode->child_cnt) { + /* Switch to the next index in the parent */ + zbr = &znode->zbranch[idx]; + child = zbr->znode; + if (!child) { + child = ubifs_load_znode(c, zbr, znode, idx); + if (IS_ERR(child)) { + err = PTR_ERR(child); + goto out_unlock; + } + zbr->znode = child; + } + znode = child; + } else + /* + * This is the last child, switch to the parent and + * continue. + */ + continue; + + /* Go to the lowest leftmost znode in the new sub-tree */ + while (znode->level > 0) { + zbr = &znode->zbranch[0]; + child = zbr->znode; + if (!child) { + child = ubifs_load_znode(c, zbr, znode, 0); + if (IS_ERR(child)) { + err = PTR_ERR(child); + goto out_unlock; + } + zbr->znode = child; + } + znode = child; + } + } + + mutex_unlock(&c->tnc_mutex); + return 0; + +out_dump: + if (znode->parent) + zbr = &znode->parent->zbranch[znode->iip]; + else + zbr = &c->zroot; + ubifs_msg("dump of znode at LEB %d:%d", zbr->lnum, zbr->offs); + dbg_dump_znode(c, znode); +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * add_size - add znode size to partially calculated index size. + * @c: UBIFS file-system description object + * @znode: znode to add size for + * @priv: partially calculated index size + * + * This is a helper function for 'dbg_check_idx_size()' which is called for + * every indexing node and adds its size to the 'long long' variable pointed to + * by @priv. + */ +static int add_size(struct ubifs_info *c, struct ubifs_znode *znode, void *priv) +{ + long long *idx_size = priv; + int add; + + add = ubifs_idx_node_sz(c, znode->child_cnt); + add = ALIGN(add, 8); + *idx_size += add; + return 0; +} + +/** + * dbg_check_idx_size - check index size. + * @c: UBIFS file-system description object + * @idx_size: size to check + * + * This function walks the UBIFS index, calculates its size and checks that the + * size is equivalent to @idx_size. Returns zero in case of success and a + * negative error code in case of failure. + */ +int dbg_check_idx_size(struct ubifs_info *c, long long idx_size) +{ + int err; + long long calc = 0; + + if (!(ubifs_chk_flags & UBIFS_CHK_IDX_SZ)) + return 0; + + err = dbg_walk_index(c, NULL, add_size, &calc); + if (err) { + ubifs_err("error %d while walking the index", err); + return err; + } + + if (calc != idx_size) { + ubifs_err("index size check failed: calculated size is %lld, " + "should be %lld", calc, idx_size); + dump_stack(); + return -EINVAL; + } + + return 0; +} + +/** + * struct fsck_inode - information about an inode used when checking the file-system. + * @rb: link in the RB-tree of inodes + * @inum: inode number + * @mode: inode type, permissions, etc + * @nlink: inode link count + * @xattr_cnt: count of extended attributes + * @references: how many directory/xattr entries refer this inode (calculated + * while walking the index) + * @calc_cnt: for directory inode count of child directories + * @size: inode size (read from on-flash inode) + * @xattr_sz: summary size of all extended attributes (read from on-flash + * inode) + * @calc_sz: for directories calculated directory size + * @calc_xcnt: count of extended attributes + * @calc_xsz: calculated summary size of all extended attributes + * @xattr_nms: sum of lengths of all extended attribute names belonging to this + * inode (read from on-flash inode) + * @calc_xnms: calculated sum of lengths of all extended attribute names + */ +struct fsck_inode { + struct rb_node rb; + ino_t inum; + umode_t mode; + unsigned int nlink; + unsigned int xattr_cnt; + int references; + int calc_cnt; + long long size; + unsigned int xattr_sz; + long long calc_sz; + long long calc_xcnt; + long long calc_xsz; + unsigned int xattr_nms; + long long calc_xnms; +}; + +/** + * struct fsck_data - private FS checking information. + * @inodes: RB-tree of all inodes (contains @struct fsck_inode objects) + */ +struct fsck_data { + struct rb_root inodes; +}; + +/** + * add_inode - add inode information to RB-tree of inodes. + * @c: UBIFS file-system description object + * @fsckd: FS checking information + * @ino: raw UBIFS inode to add + * + * This is a helper function for 'check_leaf()' which adds information about + * inode @ino to the RB-tree of inodes. Returns inode information pointer in + * case of success and a negative error code in case of failure. + */ +static struct fsck_inode *add_inode(struct ubifs_info *c, + struct fsck_data *fsckd, + struct ubifs_ino_node *ino) +{ + struct rb_node **p, *parent = NULL; + struct fsck_inode *fscki; + ino_t inum = key_inum_flash(c, &ino->key); + + p = &fsckd->inodes.rb_node; + while (*p) { + parent = *p; + fscki = rb_entry(parent, struct fsck_inode, rb); + if (inum < fscki->inum) + p = &(*p)->rb_left; + else if (inum > fscki->inum) + p = &(*p)->rb_right; + else + return fscki; + } + + if (inum > c->highest_inum) { + ubifs_err("too high inode number, max. is %lu", + c->highest_inum); + return ERR_PTR(-EINVAL); + } + + fscki = kzalloc(sizeof(struct fsck_inode), GFP_NOFS); + if (!fscki) + return ERR_PTR(-ENOMEM); + + fscki->inum = inum; + fscki->nlink = le32_to_cpu(ino->nlink); + fscki->size = le64_to_cpu(ino->size); + fscki->xattr_cnt = le32_to_cpu(ino->xattr_cnt); + fscki->xattr_sz = le32_to_cpu(ino->xattr_size); + fscki->xattr_nms = le32_to_cpu(ino->xattr_names); + fscki->mode = le32_to_cpu(ino->mode); + if (S_ISDIR(fscki->mode)) { + fscki->calc_sz = UBIFS_INO_NODE_SZ; + fscki->calc_cnt = 2; + } + rb_link_node(&fscki->rb, parent, p); + rb_insert_color(&fscki->rb, &fsckd->inodes); + return fscki; +} + +/** + * search_inode - search inode in the RB-tree of inodes. + * @fsckd: FS checking information + * @inum: inode number to search + * + * This is a helper function for 'check_leaf()' which searches inode @inum in + * the RB-tree of inodes and returns an inode information pointer or %NULL if + * the inode was not found. + */ +static struct fsck_inode *search_inode(struct fsck_data *fsckd, ino_t inum) +{ + struct rb_node *p; + struct fsck_inode *fscki; + + p = fsckd->inodes.rb_node; + while (p) { + fscki = rb_entry(p, struct fsck_inode, rb); + if (inum < fscki->inum) + p = p->rb_left; + else if (inum > fscki->inum) + p = p->rb_right; + else + return fscki; + } + return NULL; +} + +/** + * read_add_inode - read inode node and add it to RB-tree of inodes. + * @c: UBIFS file-system description object + * @fsckd: FS checking information + * @inum: inode number to read + * + * This is a helper function for 'check_leaf()' which finds inode node @inum in + * the index, reads it, and adds it to the RB-tree of inodes. Returns inode + * information pointer in case of success and a negative error code in case of + * failure. + */ +static struct fsck_inode *read_add_inode(struct ubifs_info *c, + struct fsck_data *fsckd, ino_t inum) +{ + int n, err; + union ubifs_key key; + struct ubifs_znode *znode; + struct ubifs_zbranch *zbr; + struct ubifs_ino_node *ino; + struct fsck_inode *fscki; + + fscki = search_inode(fsckd, inum); + if (fscki) + return fscki; + + ino_key_init(c, &key, inum); + err = ubifs_lookup_level0(c, &key, &znode, &n); + if (!err) { + ubifs_err("inode %lu not found in index", inum); + return ERR_PTR(-ENOENT); + } else if (err < 0) { + ubifs_err("error %d while looking up inode %lu", err, inum); + return ERR_PTR(err); + } + + zbr = &znode->zbranch[n]; + if (zbr->len < UBIFS_INO_NODE_SZ) { + ubifs_err("bad node %lu node length %d", inum, zbr->len); + return ERR_PTR(-EINVAL); + } + + ino = kmalloc(zbr->len, GFP_NOFS); + if (!ino) + return ERR_PTR(-ENOMEM); + + err = ubifs_tnc_read_node(c, zbr, ino); + if (err) { + ubifs_err("cannot read inode node at LEB %d:%d, error %d", + zbr->lnum, zbr->offs, err); + kfree(ino); + return ERR_PTR(err); + } + + fscki = add_inode(c, fsckd, ino); + kfree(ino); + if (IS_ERR(fscki)) { + ubifs_err("error %ld while adding inode %lu node", + PTR_ERR(fscki), inum); + return fscki; + } + + return fscki; +} + +/** + * check_leaf - check leaf node. + * @c: UBIFS file-system description object + * @zbr: zbranch of the leaf node to check + * @priv: FS checking information + * + * This is a helper function for 'dbg_check_filesystem()' which is called for + * every single leaf node while walking the indexing tree. It checks that the + * leaf node referred from the indexing tree exists, has correct CRC, and does + * some other basic validation. This function is also responsible for building + * an RB-tree of inodes - it adds all inodes into the RB-tree. It also + * calculates reference count, size, etc for each inode in order to later + * compare them to the information stored inside the inodes and detect possible + * inconsistencies. Returns zero in case of success and a negative error code + * in case of failure. + */ +static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *priv) +{ + ino_t inum; + void *node; + struct ubifs_ch *ch; + int err, type = key_type(c, &zbr->key); + struct fsck_inode *fscki; + + if (zbr->len < UBIFS_CH_SZ) { + ubifs_err("bad leaf length %d (LEB %d:%d)", + zbr->len, zbr->lnum, zbr->offs); + return -EINVAL; + } + + node = kmalloc(zbr->len, GFP_NOFS); + if (!node) + return -ENOMEM; + + err = ubifs_tnc_read_node(c, zbr, node); + if (err) { + ubifs_err("cannot read leaf node at LEB %d:%d, error %d", + zbr->lnum, zbr->offs, err); + goto out_free; + } + + /* If this is an inode node, add it to RB-tree of inodes */ + if (type == UBIFS_INO_KEY) { + fscki = add_inode(c, priv, node); + if (IS_ERR(fscki)) { + err = PTR_ERR(fscki); + ubifs_err("error %d while adding inode node", err); + goto out_dump; + } + goto out; + } + + if (type != UBIFS_DENT_KEY && type != UBIFS_XENT_KEY && + type != UBIFS_DATA_KEY) { + ubifs_err("unexpected node type %d at LEB %d:%d", + type, zbr->lnum, zbr->offs); + err = -EINVAL; + goto out_free; + } + + ch = node; + if (le64_to_cpu(ch->sqnum) > c->max_sqnum) { + ubifs_err("too high sequence number, max. is %llu", + c->max_sqnum); + err = -EINVAL; + goto out_dump; + } + + if (type == UBIFS_DATA_KEY) { + long long blk_offs; + struct ubifs_data_node *dn = node; + + /* + * Search the inode node this data node belongs to and insert + * it to the RB-tree of inodes. + */ + inum = key_inum_flash(c, &dn->key); + fscki = read_add_inode(c, priv, inum); + if (IS_ERR(fscki)) { + err = PTR_ERR(fscki); + ubifs_err("error %d while processing data node and " + "trying to find inode node %lu", err, inum); + goto out_dump; + } + + /* Make sure the data node is within inode size */ + blk_offs = key_block_flash(c, &dn->key); + blk_offs <<= UBIFS_BLOCK_SHIFT; + blk_offs += le32_to_cpu(dn->size); + if (blk_offs > fscki->size) { + ubifs_err("data node at LEB %d:%d is not within inode " + "size %lld", zbr->lnum, zbr->offs, + fscki->size); + err = -EINVAL; + goto out_dump; + } + } else { + int nlen; + struct ubifs_dent_node *dent = node; + struct fsck_inode *fscki1; + + err = ubifs_validate_entry(c, dent); + if (err) + goto out_dump; + + /* + * Search the inode node this entry refers to and the parent + * inode node and insert them to the RB-tree of inodes. + */ + inum = le64_to_cpu(dent->inum); + fscki = read_add_inode(c, priv, inum); + if (IS_ERR(fscki)) { + err = PTR_ERR(fscki); + ubifs_err("error %d while processing entry node and " + "trying to find inode node %lu", err, inum); + goto out_dump; + } + + /* Count how many direntries or xentries refers this inode */ + fscki->references += 1; + + inum = key_inum_flash(c, &dent->key); + fscki1 = read_add_inode(c, priv, inum); + if (IS_ERR(fscki1)) { + err = PTR_ERR(fscki); + ubifs_err("error %d while processing entry node and " + "trying to find parent inode node %lu", + err, inum); + goto out_dump; + } + + nlen = le16_to_cpu(dent->nlen); + if (type == UBIFS_XENT_KEY) { + fscki1->calc_xcnt += 1; + fscki1->calc_xsz += CALC_DENT_SIZE(nlen); + fscki1->calc_xsz += CALC_XATTR_BYTES(fscki->size); + fscki1->calc_xnms += nlen; + } else { + fscki1->calc_sz += CALC_DENT_SIZE(nlen); + if (dent->type == UBIFS_ITYPE_DIR) + fscki1->calc_cnt += 1; + } + } + +out: + kfree(node); + return 0; + +out_dump: + ubifs_msg("dump of node at LEB %d:%d", zbr->lnum, zbr->offs); + dbg_dump_node(c, node); +out_free: + kfree(node); + return err; +} + +/** + * free_inodes - free RB-tree of inodes. + * @fsckd: FS checking information + */ +static void free_inodes(struct fsck_data *fsckd) +{ + struct rb_node *this = fsckd->inodes.rb_node; + struct fsck_inode *fscki; + + while (this) { + if (this->rb_left) + this = this->rb_left; + else if (this->rb_right) + this = this->rb_right; + else { + fscki = rb_entry(this, struct fsck_inode, rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &fscki->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + kfree(fscki); + } + } +} + +/** + * check_inodes - checks all inodes. + * @c: UBIFS file-system description object + * @fsckd: FS checking information + * + * This is a helper function for 'dbg_check_filesystem()' which walks the + * RB-tree of inodes after the index scan has been finished, and checks that + * inode nlink, size, etc are correct. Returns zero if inodes are fine, + * %-EINVAL if not, and a negative error code in case of failure. + */ +static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd) +{ + int n, err; + union ubifs_key key; + struct ubifs_znode *znode; + struct ubifs_zbranch *zbr; + struct ubifs_ino_node *ino; + struct fsck_inode *fscki; + struct rb_node *this = rb_first(&fsckd->inodes); + + while (this) { + fscki = rb_entry(this, struct fsck_inode, rb); + this = rb_next(this); + + if (S_ISDIR(fscki->mode)) { + /* + * Directories have to have exactly one reference (they + * cannot have hardlinks), although root inode is an + * exception. + */ + if (fscki->inum != UBIFS_ROOT_INO && + fscki->references != 1) { + ubifs_err("directory inode %lu has %d " + "direntries which refer it, but " + "should be 1", fscki->inum, + fscki->references); + goto out_dump; + } + if (fscki->inum == UBIFS_ROOT_INO && + fscki->references != 0) { + ubifs_err("root inode %lu has non-zero (%d) " + "direntries which refer it", + fscki->inum, fscki->references); + goto out_dump; + } + if (fscki->calc_sz != fscki->size) { + ubifs_err("directory inode %lu size is %lld, " + "but calculated size is %lld", + fscki->inum, fscki->size, + fscki->calc_sz); + goto out_dump; + } + if (fscki->calc_cnt != fscki->nlink) { + ubifs_err("directory inode %lu nlink is %d, " + "but calculated nlink is %d", + fscki->inum, fscki->nlink, + fscki->calc_cnt); + goto out_dump; + } + } else { + if (fscki->references != fscki->nlink) { + ubifs_err("inode %lu nlink is %d, but " + "calculated nlink is %d", fscki->inum, + fscki->nlink, fscki->references); + goto out_dump; + } + } + if (fscki->xattr_sz != fscki->calc_xsz) { + ubifs_err("inode %lu has xattr size %u, but " + "calculated size is %lld", + fscki->inum, fscki->xattr_sz, + fscki->calc_xsz); + goto out_dump; + } + if (fscki->xattr_cnt != fscki->calc_xcnt) { + ubifs_err("inode %lu has %u xattrs, but " + "calculated count is %lld", fscki->inum, + fscki->xattr_cnt, fscki->calc_xcnt); + goto out_dump; + } + if (fscki->xattr_nms != fscki->calc_xnms) { + ubifs_err("inode %lu has xattr names' size %u, but " + "calculated names' size is %lld", + fscki->inum, fscki->xattr_nms, + fscki->calc_xnms); + goto out_dump; + } + } + + return 0; + +out_dump: + /* Read the bad inode and dump it */ + ino_key_init(c, &key, fscki->inum); + err = ubifs_lookup_level0(c, &key, &znode, &n); + if (!err) { + ubifs_err("inode %lu not found in index", fscki->inum); + return -ENOENT; + } else if (err < 0) { + ubifs_err("error %d while looking up inode %lu", + err, fscki->inum); + return err; + } + + zbr = &znode->zbranch[n]; + ino = kmalloc(zbr->len, GFP_NOFS); + if (!ino) + return -ENOMEM; + + err = ubifs_tnc_read_node(c, zbr, ino); + if (err) { + ubifs_err("cannot read inode node at LEB %d:%d, error %d", + zbr->lnum, zbr->offs, err); + kfree(ino); + return err; + } + + ubifs_msg("dump of the inode %lu sitting in LEB %d:%d", + fscki->inum, zbr->lnum, zbr->offs); + dbg_dump_node(c, ino); + kfree(ino); + return -EINVAL; +} + +/** + * dbg_check_filesystem - check the file-system. + * @c: UBIFS file-system description object + * + * This function checks the file system, namely: + * o makes sure that all leaf nodes exist and their CRCs are correct; + * o makes sure inode nlink, size, xattr size/count are correct (for all + * inodes). + * + * The function reads whole indexing tree and all nodes, so it is pretty + * heavy-weight. Returns zero if the file-system is consistent, %-EINVAL if + * not, and a negative error code in case of failure. + */ +int dbg_check_filesystem(struct ubifs_info *c) +{ + int err; + struct fsck_data fsckd; + + if (!(ubifs_chk_flags & UBIFS_CHK_FS)) + return 0; + + fsckd.inodes = RB_ROOT; + err = dbg_walk_index(c, check_leaf, NULL, &fsckd); + if (err) + goto out_free; + + err = check_inodes(c, &fsckd); + if (err) + goto out_free; + + free_inodes(&fsckd); + return 0; + +out_free: + ubifs_err("file-system check failed with error %d", err); + dump_stack(); + free_inodes(&fsckd); + return err; +} + +static int invocation_cnt; + +int dbg_force_in_the_gaps(void) +{ + if (!dbg_force_in_the_gaps_enabled) + return 0; + /* Force in-the-gaps every 8th commit */ + return !((invocation_cnt++) & 0x7); +} + +/* Failure mode for recovery testing */ + +#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d)) + +struct failure_mode_info { + struct list_head list; + struct ubifs_info *c; +}; + +static LIST_HEAD(fmi_list); +static DEFINE_SPINLOCK(fmi_lock); + +static unsigned int next; + +static int simple_rand(void) +{ + if (next == 0) + next = current->pid; + next = next * 1103515245 + 12345; + return (next >> 16) & 32767; +} + +void dbg_failure_mode_registration(struct ubifs_info *c) +{ + struct failure_mode_info *fmi; + + fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS); + if (!fmi) { + dbg_err("Failed to register failure mode - no memory"); + return; + } + fmi->c = c; + spin_lock(&fmi_lock); + list_add_tail(&fmi->list, &fmi_list); + spin_unlock(&fmi_lock); +} + +void dbg_failure_mode_deregistration(struct ubifs_info *c) +{ + struct failure_mode_info *fmi, *tmp; + + spin_lock(&fmi_lock); + list_for_each_entry_safe(fmi, tmp, &fmi_list, list) + if (fmi->c == c) { + list_del(&fmi->list); + kfree(fmi); + } + spin_unlock(&fmi_lock); +} + +static struct ubifs_info *dbg_find_info(struct ubi_volume_desc *desc) +{ + struct failure_mode_info *fmi; + + spin_lock(&fmi_lock); + list_for_each_entry(fmi, &fmi_list, list) + if (fmi->c->ubi == desc) { + struct ubifs_info *c = fmi->c; + + spin_unlock(&fmi_lock); + return c; + } + spin_unlock(&fmi_lock); + return NULL; +} + +static int in_failure_mode(struct ubi_volume_desc *desc) +{ + struct ubifs_info *c = dbg_find_info(desc); + + if (c && dbg_failure_mode) + return c->failure_mode; + return 0; +} + +static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) +{ + struct ubifs_info *c = dbg_find_info(desc); + + if (!c || !dbg_failure_mode) + return 0; + if (c->failure_mode) + return 1; + if (!c->fail_cnt) { + /* First call - decide delay to failure */ + if (chance(1, 2)) { + unsigned int delay = 1 << (simple_rand() >> 11); + + if (chance(1, 2)) { + c->fail_delay = 1; + c->fail_timeout = jiffies + + msecs_to_jiffies(delay); + dbg_rcvry("failing after %ums", delay); + } else { + c->fail_delay = 2; + c->fail_cnt_max = delay; + dbg_rcvry("failing after %u calls", delay); + } + } + c->fail_cnt += 1; + } + /* Determine if failure delay has expired */ + if (c->fail_delay == 1) { + if (time_before(jiffies, c->fail_timeout)) + return 0; + } else if (c->fail_delay == 2) + if (c->fail_cnt++ < c->fail_cnt_max) + return 0; + if (lnum == UBIFS_SB_LNUM) { + if (write) { + if (chance(1, 2)) + return 0; + } else if (chance(19, 20)) + return 0; + dbg_rcvry("failing in super block LEB %d", lnum); + } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) { + if (chance(19, 20)) + return 0; + dbg_rcvry("failing in master LEB %d", lnum); + } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) { + if (write) { + if (chance(99, 100)) + return 0; + } else if (chance(399, 400)) + return 0; + dbg_rcvry("failing in log LEB %d", lnum); + } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) { + if (write) { + if (chance(7, 8)) + return 0; + } else if (chance(19, 20)) + return 0; + dbg_rcvry("failing in LPT LEB %d", lnum); + } else if (lnum >= c->orph_first && lnum <= c->orph_last) { + if (write) { + if (chance(1, 2)) + return 0; + } else if (chance(9, 10)) + return 0; + dbg_rcvry("failing in orphan LEB %d", lnum); + } else if (lnum == c->ihead_lnum) { + if (chance(99, 100)) + return 0; + dbg_rcvry("failing in index head LEB %d", lnum); + } else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) { + if (chance(9, 10)) + return 0; + dbg_rcvry("failing in GC head LEB %d", lnum); + } else if (write && !RB_EMPTY_ROOT(&c->buds) && + !ubifs_search_bud(c, lnum)) { + if (chance(19, 20)) + return 0; + dbg_rcvry("failing in non-bud LEB %d", lnum); + } else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND || + c->cmt_state == COMMIT_RUNNING_REQUIRED) { + if (chance(999, 1000)) + return 0; + dbg_rcvry("failing in bud LEB %d commit running", lnum); + } else { + if (chance(9999, 10000)) + return 0; + dbg_rcvry("failing in bud LEB %d commit not running", lnum); + } + ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); + c->failure_mode = 1; + dump_stack(); + return 1; +} + +static void cut_data(const void *buf, int len) +{ + int flen, i; + unsigned char *p = (void *)buf; + + flen = (len * (long long)simple_rand()) >> 15; + for (i = flen; i < len; i++) + p[i] = 0xff; +} + +int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, + int len, int check) +{ + if (in_failure_mode(desc)) + return -EIO; + return ubi_leb_read(desc, lnum, buf, offset, len, check); +} + +int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, + int offset, int len, int dtype) +{ + int err; + + if (in_failure_mode(desc)) + return -EIO; + if (do_fail(desc, lnum, 1)) + cut_data(buf, len); + err = ubi_leb_write(desc, lnum, buf, offset, len, dtype); + if (err) + return err; + if (in_failure_mode(desc)) + return -EIO; + return 0; +} + +int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, + int len, int dtype) +{ + int err; + + if (do_fail(desc, lnum, 1)) + return -EIO; + err = ubi_leb_change(desc, lnum, buf, len, dtype); + if (err) + return err; + if (do_fail(desc, lnum, 1)) + return -EIO; + return 0; +} + +int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum) +{ + int err; + + if (do_fail(desc, lnum, 0)) + return -EIO; + err = ubi_leb_erase(desc, lnum); + if (err) + return err; + if (do_fail(desc, lnum, 0)) + return -EIO; + return 0; +} + +int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum) +{ + int err; + + if (do_fail(desc, lnum, 0)) + return -EIO; + err = ubi_leb_unmap(desc, lnum); + if (err) + return err; + if (do_fail(desc, lnum, 0)) + return -EIO; + return 0; +} + +int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum) +{ + if (in_failure_mode(desc)) + return -EIO; + return ubi_is_mapped(desc, lnum); +} + +int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) +{ + int err; + + if (do_fail(desc, lnum, 0)) + return -EIO; + err = ubi_leb_map(desc, lnum, dtype); + if (err) + return err; + if (do_fail(desc, lnum, 0)) + return -EIO; + return 0; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h new file mode 100644 index 0000000..3c4f1e9 --- /dev/null +++ b/fs/ubifs/debug.h @@ -0,0 +1,403 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +#ifndef __UBIFS_DEBUG_H__ +#define __UBIFS_DEBUG_H__ + +#ifdef CONFIG_UBIFS_FS_DEBUG + +#define UBIFS_DBG(op) op + +#define ubifs_assert(expr) do { \ + if (unlikely(!(expr))) { \ + printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \ + __func__, __LINE__, current->pid); \ + dbg_dump_stack(); \ + } \ +} while (0) + +#define ubifs_assert_cmt_locked(c) do { \ + if (unlikely(down_write_trylock(&(c)->commit_sem))) { \ + up_write(&(c)->commit_sem); \ + printk(KERN_CRIT "commit lock is not locked!\n"); \ + ubifs_assert(0); \ + } \ +} while (0) + +#define dbg_dump_stack() do { \ + if (!dbg_failure_mode) \ + dump_stack(); \ +} while (0) + +/* Generic debugging messages */ +#define dbg_msg(fmt, ...) do { \ + spin_lock(&dbg_lock); \ + printk(KERN_DEBUG "UBIFS DBG (pid %d): %s: " fmt "\n", current->pid, \ + __func__, ##__VA_ARGS__); \ + spin_unlock(&dbg_lock); \ +} while (0) + +#define dbg_do_msg(typ, fmt, ...) do { \ + if (ubifs_msg_flags & typ) \ + dbg_msg(fmt, ##__VA_ARGS__); \ +} while (0) + +#define dbg_err(fmt, ...) do { \ + spin_lock(&dbg_lock); \ + ubifs_err(fmt, ##__VA_ARGS__); \ + spin_unlock(&dbg_lock); \ +} while (0) + +const char *dbg_key_str0(const struct ubifs_info *c, + const union ubifs_key *key); +const char *dbg_key_str1(const struct ubifs_info *c, + const union ubifs_key *key); + +/* + * DBGKEY macros require dbg_lock to be held, which it is in the dbg message + * macros. + */ +#define DBGKEY(key) dbg_key_str0(c, (key)) +#define DBGKEY1(key) dbg_key_str1(c, (key)) + +/* General messages */ +#define dbg_gen(fmt, ...) dbg_do_msg(UBIFS_MSG_GEN, fmt, ##__VA_ARGS__) + +/* Additional journal messages */ +#define dbg_jnl(fmt, ...) dbg_do_msg(UBIFS_MSG_JNL, fmt, ##__VA_ARGS__) + +/* Additional TNC messages */ +#define dbg_tnc(fmt, ...) dbg_do_msg(UBIFS_MSG_TNC, fmt, ##__VA_ARGS__) + +/* Additional lprops messages */ +#define dbg_lp(fmt, ...) dbg_do_msg(UBIFS_MSG_LP, fmt, ##__VA_ARGS__) + +/* Additional LEB find messages */ +#define dbg_find(fmt, ...) dbg_do_msg(UBIFS_MSG_FIND, fmt, ##__VA_ARGS__) + +/* Additional mount messages */ +#define dbg_mnt(fmt, ...) dbg_do_msg(UBIFS_MSG_MNT, fmt, ##__VA_ARGS__) + +/* Additional I/O messages */ +#define dbg_io(fmt, ...) dbg_do_msg(UBIFS_MSG_IO, fmt, ##__VA_ARGS__) + +/* Additional commit messages */ +#define dbg_cmt(fmt, ...) dbg_do_msg(UBIFS_MSG_CMT, fmt, ##__VA_ARGS__) + +/* Additional budgeting messages */ +#define dbg_budg(fmt, ...) dbg_do_msg(UBIFS_MSG_BUDG, fmt, ##__VA_ARGS__) + +/* Additional log messages */ +#define dbg_log(fmt, ...) dbg_do_msg(UBIFS_MSG_LOG, fmt, ##__VA_ARGS__) + +/* Additional gc messages */ +#define dbg_gc(fmt, ...) dbg_do_msg(UBIFS_MSG_GC, fmt, ##__VA_ARGS__) + +/* Additional scan messages */ +#define dbg_scan(fmt, ...) dbg_do_msg(UBIFS_MSG_SCAN, fmt, ##__VA_ARGS__) + +/* Additional recovery messages */ +#define dbg_rcvry(fmt, ...) dbg_do_msg(UBIFS_MSG_RCVRY, fmt, ##__VA_ARGS__) + +/* + * Debugging message type flags (must match msg_type_names in debug.c). + * + * UBIFS_MSG_GEN: general messages + * UBIFS_MSG_JNL: journal messages + * UBIFS_MSG_MNT: mount messages + * UBIFS_MSG_CMT: commit messages + * UBIFS_MSG_FIND: LEB find messages + * UBIFS_MSG_BUDG: budgeting messages + * UBIFS_MSG_GC: garbage collection messages + * UBIFS_MSG_TNC: TNC messages + * UBIFS_MSG_LP: lprops messages + * UBIFS_MSG_IO: I/O messages + * UBIFS_MSG_LOG: log messages + * UBIFS_MSG_SCAN: scan messages + * UBIFS_MSG_RCVRY: recovery messages + */ +enum { + UBIFS_MSG_GEN = 0x1, + UBIFS_MSG_JNL = 0x2, + UBIFS_MSG_MNT = 0x4, + UBIFS_MSG_CMT = 0x8, + UBIFS_MSG_FIND = 0x10, + UBIFS_MSG_BUDG = 0x20, + UBIFS_MSG_GC = 0x40, + UBIFS_MSG_TNC = 0x80, + UBIFS_MSG_LP = 0x100, + UBIFS_MSG_IO = 0x200, + UBIFS_MSG_LOG = 0x400, + UBIFS_MSG_SCAN = 0x800, + UBIFS_MSG_RCVRY = 0x1000, +}; + +/* Debugging message type flags for each default debug message level */ +#define UBIFS_MSG_LVL_0 0 +#define UBIFS_MSG_LVL_1 0x1 +#define UBIFS_MSG_LVL_2 0x7f +#define UBIFS_MSG_LVL_3 0xffff + +/* + * Debugging check flags (must match chk_names in debug.c). + * + * UBIFS_CHK_GEN: general checks + * UBIFS_CHK_TNC: check TNC + * UBIFS_CHK_IDX_SZ: check index size + * UBIFS_CHK_ORPH: check orphans + * UBIFS_CHK_OLD_IDX: check the old index + * UBIFS_CHK_LPROPS: check lprops + * UBIFS_CHK_FS: check the file-system + */ +enum { + UBIFS_CHK_GEN = 0x1, + UBIFS_CHK_TNC = 0x2, + UBIFS_CHK_IDX_SZ = 0x4, + UBIFS_CHK_ORPH = 0x8, + UBIFS_CHK_OLD_IDX = 0x10, + UBIFS_CHK_LPROPS = 0x20, + UBIFS_CHK_FS = 0x40, +}; + +/* + * Special testing flags (must match tst_names in debug.c). + * + * UBIFS_TST_FORCE_IN_THE_GAPS: force the use of in-the-gaps method + * UBIFS_TST_RCVRY: failure mode for recovery testing + */ +enum { + UBIFS_TST_FORCE_IN_THE_GAPS = 0x2, + UBIFS_TST_RCVRY = 0x4, +}; + +#if CONFIG_UBIFS_FS_DEBUG_MSG_LVL == 1 +#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_1 +#elif CONFIG_UBIFS_FS_DEBUG_MSG_LVL == 2 +#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_2 +#elif CONFIG_UBIFS_FS_DEBUG_MSG_LVL == 3 +#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_3 +#else +#define UBIFS_MSG_FLAGS_DEFAULT UBIFS_MSG_LVL_0 +#endif + +#ifdef CONFIG_UBIFS_FS_DEBUG_CHKS +#define UBIFS_CHK_FLAGS_DEFAULT 0xffffffff +#else +#define UBIFS_CHK_FLAGS_DEFAULT 0 +#endif + +extern spinlock_t dbg_lock; + +extern unsigned int ubifs_msg_flags; +extern unsigned int ubifs_chk_flags; +extern unsigned int ubifs_tst_flags; + +/* Dump functions */ + +const char *dbg_ntype(int type); +const char *dbg_cstate(int cmt_state); +const char *dbg_get_key_dump(const struct ubifs_info *c, + const union ubifs_key *key); +void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode); +void dbg_dump_node(const struct ubifs_info *c, const void *node); +void dbg_dump_budget_req(const struct ubifs_budget_req *req); +void dbg_dump_lstats(const struct ubifs_lp_stats *lst); +void dbg_dump_budg(struct ubifs_info *c); +void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp); +void dbg_dump_lprops(struct ubifs_info *c); +void dbg_dump_leb(const struct ubifs_info *c, int lnum); +void dbg_dump_znode(const struct ubifs_info *c, + const struct ubifs_znode *znode); +void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat); +void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, + struct ubifs_nnode *parent, int iip); +void dbg_dump_tnc(struct ubifs_info *c); +void dbg_dump_index(struct ubifs_info *c); + +/* Checking helper functions */ + +typedef int (*dbg_leaf_callback)(struct ubifs_info *c, + struct ubifs_zbranch *zbr, void *priv); +typedef int (*dbg_znode_callback)(struct ubifs_info *c, + struct ubifs_znode *znode, void *priv); + +int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, + dbg_znode_callback znode_cb, void *priv); + +/* Checking functions */ + +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); + +int dbg_check_cats(struct ubifs_info *c); + +int dbg_check_ltab(struct ubifs_info *c); + +int dbg_check_synced_i_size(struct inode *inode); + +int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir); + +int dbg_check_tnc(struct ubifs_info *c, int extra); + +int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); + +int dbg_check_filesystem(struct ubifs_info *c); + +void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, + int add_pos); + +int dbg_check_lprops(struct ubifs_info *c); +int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, + int row, int col); + +/* Force the use of in-the-gaps method for testing */ + +#define dbg_force_in_the_gaps_enabled \ + (ubifs_tst_flags & UBIFS_TST_FORCE_IN_THE_GAPS) + +int dbg_force_in_the_gaps(void); + +/* Failure mode for recovery testing */ + +#define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY) + +void dbg_failure_mode_registration(struct ubifs_info *c); +void dbg_failure_mode_deregistration(struct ubifs_info *c); + +#ifndef UBIFS_DBG_PRESERVE_UBI + +#define ubi_leb_read dbg_leb_read +#define ubi_leb_write dbg_leb_write +#define ubi_leb_change dbg_leb_change +#define ubi_leb_erase dbg_leb_erase +#define ubi_leb_unmap dbg_leb_unmap +#define ubi_is_mapped dbg_is_mapped +#define ubi_leb_map dbg_leb_map + +#endif + +int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, + int len, int check); +int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, + int offset, int len, int dtype); +int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, + int len, int dtype); +int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum); +int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum); +int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum); +int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype); + +static inline int dbg_read(struct ubi_volume_desc *desc, int lnum, char *buf, + int offset, int len) +{ + return dbg_leb_read(desc, lnum, buf, offset, len, 0); +} + +static inline int dbg_write(struct ubi_volume_desc *desc, int lnum, + const void *buf, int offset, int len) +{ + return dbg_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN); +} + +static inline int dbg_change(struct ubi_volume_desc *desc, int lnum, + const void *buf, int len) +{ + return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN); +} + +#else /* !CONFIG_UBIFS_FS_DEBUG */ + +#define UBIFS_DBG(op) +#define ubifs_assert(expr) ({}) +#define ubifs_assert_cmt_locked(c) +#define dbg_dump_stack() +#define dbg_err(fmt, ...) ({}) +#define dbg_msg(fmt, ...) ({}) +#define dbg_key(c, key, fmt, ...) ({}) + +#define dbg_gen(fmt, ...) ({}) +#define dbg_jnl(fmt, ...) ({}) +#define dbg_tnc(fmt, ...) ({}) +#define dbg_lp(fmt, ...) ({}) +#define dbg_find(fmt, ...) ({}) +#define dbg_mnt(fmt, ...) ({}) +#define dbg_io(fmt, ...) ({}) +#define dbg_cmt(fmt, ...) ({}) +#define dbg_budg(fmt, ...) ({}) +#define dbg_log(fmt, ...) ({}) +#define dbg_gc(fmt, ...) ({}) +#define dbg_scan(fmt, ...) ({}) +#define dbg_rcvry(fmt, ...) ({}) + +#define dbg_ntype(type) "" +#define dbg_cstate(cmt_state) "" +#define dbg_get_key_dump(c, key) ({}) +#define dbg_dump_inode(c, inode) ({}) +#define dbg_dump_node(c, node) ({}) +#define dbg_dump_budget_req(req) ({}) +#define dbg_dump_lstats(lst) ({}) +#define dbg_dump_budg(c) ({}) +#define dbg_dump_lprop(c, lp) ({}) +#define dbg_dump_lprops(c) ({}) +#define dbg_dump_leb(c, lnum) ({}) +#define dbg_dump_znode(c, znode) ({}) +#define dbg_dump_heap(c, heap, cat) ({}) +#define dbg_dump_pnode(c, pnode, parent, iip) ({}) +#define dbg_dump_tnc(c) ({}) +#define dbg_dump_index(c) ({}) + +#define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 + +#define dbg_old_index_check_init(c, zroot) 0 +#define dbg_check_old_index(c, zroot) 0 + +#define dbg_check_cats(c) 0 + +#define dbg_check_ltab(c) 0 + +#define dbg_check_synced_i_size(inode) 0 + +#define dbg_check_dir_size(c, dir) 0 + +#define dbg_check_tnc(c, x) 0 + +#define dbg_check_idx_size(c, idx_size) 0 + +#define dbg_check_filesystem(c) 0 + +#define dbg_check_heap(c, heap, cat, add_pos) ({}) + +#define dbg_check_lprops(c) 0 +#define dbg_check_lpt_nodes(c, cnode, row, col) 0 + +#define dbg_force_in_the_gaps_enabled 0 +#define dbg_force_in_the_gaps() 0 + +#define dbg_failure_mode 0 +#define dbg_failure_mode_registration(c) ({}) +#define dbg_failure_mode_deregistration(c) ({}) + +#endif /* !CONFIG_UBIFS_FS_DEBUG */ + +#endif /* !__UBIFS_DEBUG_H__ */ diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c new file mode 100644 index 0000000..e90374b --- /dev/null +++ b/fs/ubifs/dir.c @@ -0,0 +1,1240 @@ +/* * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * Copyright (C) 2006, 2007 University of Szeged, Hungary + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + * Zoltan Sogor + */ + +/* + * This file implements directory operations. + * + * All FS operations in this file allocate budget before writing anything to the + * media. If they fail to allocate it, the error is returned. The only + * exceptions are 'ubifs_unlink()' and 'ubifs_rmdir()' which keep working even + * if they unable to allocate the budget, because deletion %-ENOSPC failure is + * not what users are usually ready to get. UBIFS budgeting subsystem has some + * space reserved for these purposes. + * + * All operations in this file write all inodes which they change straight + * away, instead of marking them dirty. For example, 'ubifs_link()' changes + * @i_size of the parent inode and writes the parent inode together with the + * target inode. This was done to simplify file-system recovery which would + * otherwise be very difficult to do. The only exception is rename which marks + * the re-named inode dirty (because its @i_ctime is updated) but does not + * write it, but just marks it as dirty. + */ + +#include "ubifs.h" + +/** + * inherit_flags - inherit flags of the parent inode. + * @dir: parent inode + * @mode: new inode mode flags + * + * This is a helper function for 'ubifs_new_inode()' which inherits flag of the + * parent directory inode @dir. UBIFS inodes inherit the following flags: + * o %UBIFS_COMPR_FL, which is useful to switch compression on/of on + * sub-directory basis; + * o %UBIFS_SYNC_FL - useful for the same reasons; + * o %UBIFS_DIRSYNC_FL - similar, but relevant only to directories. + * + * This function returns the inherited flags. + */ +static int inherit_flags(const struct inode *dir, int mode) +{ + int flags; + const struct ubifs_inode *ui = ubifs_inode(dir); + + if (!S_ISDIR(dir->i_mode)) + /* + * The parent is not a directory, which means that an extended + * attribute inode is being created. No flags. + */ + return 0; + + flags = ui->flags & (UBIFS_COMPR_FL | UBIFS_SYNC_FL | UBIFS_DIRSYNC_FL); + if (!S_ISDIR(mode)) + /* The "DIRSYNC" flag only applies to directories */ + flags &= ~UBIFS_DIRSYNC_FL; + return flags; +} + +/** + * ubifs_new_inode - allocate new UBIFS inode object. + * @c: UBIFS file-system description object + * @dir: parent directory inode + * @mode: inode mode flags + * + * This function finds an unused inode number, allocates new inode and + * initializes it. Returns new inode in case of success and an error code in + * case of failure. + */ +struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, + int mode) +{ + struct inode *inode; + struct ubifs_inode *ui; + + inode = new_inode(c->vfs_sb); + ui = ubifs_inode(inode); + if (!inode) + return ERR_PTR(-ENOMEM); + + /* + * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and + * marking them dirty in file write path (see 'file_update_time()'). + * UBIFS has to fully control "clean <-> dirty" transitions of inodes + * to make budgeting work. + */ + inode->i_flags |= (S_NOCMTIME); + + inode->i_uid = current->fsuid; + if (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_mode = mode; + inode->i_mtime = inode->i_atime = inode->i_ctime = + ubifs_current_time(inode); + inode->i_mapping->nrpages = 0; + /* Disable readahead */ + inode->i_mapping->backing_dev_info = &c->bdi; + + switch (mode & S_IFMT) { + case S_IFREG: + inode->i_mapping->a_ops = &ubifs_file_address_operations; + inode->i_op = &ubifs_file_inode_operations; + inode->i_fop = &ubifs_file_operations; + break; + case S_IFDIR: + inode->i_op = &ubifs_dir_inode_operations; + inode->i_fop = &ubifs_dir_operations; + inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ; + break; + case S_IFLNK: + inode->i_op = &ubifs_symlink_inode_operations; + break; + case S_IFSOCK: + case S_IFIFO: + case S_IFBLK: + case S_IFCHR: + inode->i_op = &ubifs_file_inode_operations; + break; + default: + BUG(); + } + + ui->flags = inherit_flags(dir, mode); + ubifs_set_inode_flags(inode); + if (S_ISREG(mode)) + ui->compr_type = c->default_compr; + else + ui->compr_type = UBIFS_COMPR_NONE; + ui->synced_i_size = 0; + + spin_lock(&c->cnt_lock); + /* Inode number overflow is currently not supported */ + if (c->highest_inum >= INUM_WARN_WATERMARK) { + if (c->highest_inum >= INUM_WATERMARK) { + spin_unlock(&c->cnt_lock); + ubifs_err("out of inode numbers"); + make_bad_inode(inode); + iput(inode); + return ERR_PTR(-EINVAL); + } + ubifs_warn("running out of inode numbers (current %lu, max %d)", + c->highest_inum, INUM_WATERMARK); + } + + inode->i_ino = ++c->highest_inum; + inode->i_generation = ++c->vfs_gen; + /* + * The creation sequence number remains with this inode for its + * lifetime. All nodes for this inode have a greater sequence number, + * and so it is possible to distinguish obsolete nodes belonging to a + * previous incarnation of the same inode number - for example, for the + * purpose of rebuilding the index. + */ + ui->creat_sqnum = ++c->max_sqnum; + spin_unlock(&c->cnt_lock); + return inode; +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm) +{ + if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) + return 0; + if (le16_to_cpu(dent->nlen) != nm->len) + return -EINVAL; + if (memcmp(dent->name, nm->name, nm->len)) + return -EINVAL; + return 0; +} + +#else + +#define dbg_check_name(dent, nm) 0 + +#endif + +static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + int err; + union ubifs_key key; + struct inode *inode = NULL; + struct ubifs_dent_node *dent; + struct ubifs_info *c = dir->i_sb->s_fs_info; + + dbg_gen("'%.*s' in dir ino %lu", + dentry->d_name.len, dentry->d_name.name, dir->i_ino); + + if (dentry->d_name.len > UBIFS_MAX_NLEN) + return ERR_PTR(-ENAMETOOLONG); + + dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); + if (!dent) + return ERR_PTR(-ENOMEM); + + dent_key_init(c, &key, dir->i_ino, &dentry->d_name); + + err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name); + if (err) { + /* + * Do not hash the direntry if parent 'i_nlink' is zero, because + * this has side-effects - '->delete_inode()' call will not be + * called for the parent orphan inode, because 'd_count' of its + * direntry will stay 1 (it'll be negative direntry I guess) + * and prevent 'iput_final()' until the dentry is destroyed due + * to unmount or memory pressure. + */ + if (err == -ENOENT && dir->i_nlink != 0) { + dbg_gen("not found"); + goto done; + } + goto out; + } + + if (dbg_check_name(dent, &dentry->d_name)) { + err = -EINVAL; + goto out; + } + + inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum)); + if (IS_ERR(inode)) { + /* + * This should not happen. Probably the file-system needs + * checking. + */ + err = PTR_ERR(inode); + ubifs_err("dead directory entry '%.*s', error %d", + dentry->d_name.len, dentry->d_name.name, err); + ubifs_ro_mode(c, err); + goto out; + } + +done: + kfree(dent); + /* + * Note, d_splice_alias() would be required instead if we supported + * NFS. + */ + d_add(dentry, inode); + return NULL; + +out: + kfree(dent); + return ERR_PTR(err); +} + +static int ubifs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + struct inode *inode; + struct ubifs_info *c = dir->i_sb->s_fs_info; + int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, + .dirtied_ino = 1 }; + struct ubifs_inode *dir_ui = ubifs_inode(dir); + + /* + * Budget request settings: new inode, new direntry, changing the + * parent directory inode. + */ + + dbg_gen("dent '%.*s', mode %#x in dir ino %lu", + dentry->d_name.len, dentry->d_name.name, mode, dir->i_ino); + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + inode = ubifs_new_inode(c, dir, mode); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_budg; + } + + mutex_lock(&dir_ui->ui_mutex); + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); + if (err) + goto out_cancel; + mutex_unlock(&dir_ui->ui_mutex); + + ubifs_release_budget(c, &req); + insert_inode_hash(inode); + d_instantiate(dentry, inode); + return 0; + +out_cancel: + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + mutex_unlock(&dir_ui->ui_mutex); + make_bad_inode(inode); + iput(inode); +out_budg: + ubifs_release_budget(c, &req); + ubifs_err("cannot create regular file, error %d", err); + return err; +} + +/** + * vfs_dent_type - get VFS directory entry type. + * @type: UBIFS directory entry type + * + * This function converts UBIFS directory entry type into VFS directory entry + * type. + */ +static unsigned int vfs_dent_type(uint8_t type) +{ + switch (type) { + case UBIFS_ITYPE_REG: + return DT_REG; + case UBIFS_ITYPE_DIR: + return DT_DIR; + case UBIFS_ITYPE_LNK: + return DT_LNK; + case UBIFS_ITYPE_BLK: + return DT_BLK; + case UBIFS_ITYPE_CHR: + return DT_CHR; + case UBIFS_ITYPE_FIFO: + return DT_FIFO; + case UBIFS_ITYPE_SOCK: + return DT_SOCK; + default: + BUG(); + } + return 0; +} + +/* + * The classical Unix view for directory is that it is a linear array of + * (name, inode number) entries. Linux/VFS assumes this model as well. + * Particularly, 'readdir()' call wants us to return a directory entry offset + * which later may be used to continue 'readdir()'ing the directory or to + * 'seek()' to that specific direntry. Obviously UBIFS does not really fit this + * model because directory entries are identified by keys, which may collide. + * + * UBIFS uses directory entry hash value for directory offsets, so + * 'seekdir()'/'telldir()' may not always work because of possible key + * collisions. But UBIFS guarantees that consecutive 'readdir()' calls work + * properly by means of saving full directory entry name in the private field + * of the file description object. + * + * This means that UBIFS cannot support NFS which requires full + * 'seekdir()'/'telldir()' support. + */ +static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int err, over = 0; + struct qstr nm; + union ubifs_key key; + struct ubifs_dent_node *dent; + struct inode *dir = file->f_path.dentry->d_inode; + struct ubifs_info *c = dir->i_sb->s_fs_info; + + dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, file->f_pos); + + if (file->f_pos > UBIFS_S_KEY_HASH_MASK || file->f_pos == 2) + /* + * The directory was seek'ed to a senseless position or there + * are no more entries. + */ + return 0; + + /* File positions 0 and 1 correspond to "." and ".." */ + if (file->f_pos == 0) { + ubifs_assert(!file->private_data); + over = filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR); + if (over) + return 0; + file->f_pos = 1; + } + + if (file->f_pos == 1) { + ubifs_assert(!file->private_data); + over = filldir(dirent, "..", 2, 1, + parent_ino(file->f_path.dentry), DT_DIR); + if (over) + return 0; + + /* Find the first entry in TNC and save it */ + lowest_dent_key(c, &key, dir->i_ino); + nm.name = NULL; + dent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(dent)) { + err = PTR_ERR(dent); + goto out; + } + + file->f_pos = key_hash_flash(c, &dent->key); + file->private_data = dent; + } + + dent = file->private_data; + if (!dent) { + /* + * The directory was seek'ed to and is now readdir'ed. + * Find the entry corresponding to @file->f_pos or the + * closest one. + */ + dent_key_init_hash(c, &key, dir->i_ino, file->f_pos); + nm.name = NULL; + dent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(dent)) { + err = PTR_ERR(dent); + goto out; + } + file->f_pos = key_hash_flash(c, &dent->key); + file->private_data = dent; + } + + while (1) { + dbg_gen("feed '%s', ino %llu, new f_pos %#x", + dent->name, le64_to_cpu(dent->inum), + key_hash_flash(c, &dent->key)); + ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum); + + nm.len = le16_to_cpu(dent->nlen); + over = filldir(dirent, dent->name, nm.len, file->f_pos, + le64_to_cpu(dent->inum), + vfs_dent_type(dent->type)); + if (over) + return 0; + + /* Switch to the next entry */ + key_read(c, &dent->key, &key); + nm.name = dent->name; + dent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(dent)) { + err = PTR_ERR(dent); + goto out; + } + + kfree(file->private_data); + file->f_pos = key_hash_flash(c, &dent->key); + file->private_data = dent; + cond_resched(); + } + +out: + if (err != -ENOENT) { + ubifs_err("cannot find next direntry, error %d", err); + return err; + } + + kfree(file->private_data); + file->private_data = NULL; + file->f_pos = 2; + return 0; +} + +/* If a directory is seeked, we have to free saved readdir() state */ +static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin) +{ + kfree(file->private_data); + file->private_data = NULL; + return generic_file_llseek(file, offset, origin); +} + +/* Free saved readdir() state when the directory is closed */ +static int ubifs_dir_release(struct inode *dir, struct file *file) +{ + kfree(file->private_data); + file->private_data = NULL; + return 0; +} + +/** + * lock_2_inodes - lock two UBIFS inodes. + * @inode1: first inode + * @inode2: second inode + */ +static void lock_2_inodes(struct inode *inode1, struct inode *inode2) +{ + 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 - 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(inode1)->ui_mutex); + mutex_unlock(&ubifs_inode(inode2)->ui_mutex); +} + +static int ubifs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry) +{ + struct ubifs_info *c = dir->i_sb->s_fs_info; + struct inode *inode = old_dentry->d_inode; + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_inode *dir_ui = ubifs_inode(dir); + int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); + struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2, + .dirtied_ino_d = ui->data_len }; + + /* + * Budget request settings: new direntry, changing the target inode, + * changing the parent inode. + */ + + 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); + err = dbg_check_synced_i_size(inode); + if (err) + return err; + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + lock_2_inodes(dir, inode); + inc_nlink(inode); + atomic_inc(&inode->i_count); + inode->i_ctime = ubifs_current_time(inode); + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); + if (err) + goto out_cancel; + unlock_2_inodes(dir, inode); + + ubifs_release_budget(c, &req); + d_instantiate(dentry, inode); + return 0; + +out_cancel: + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + drop_nlink(inode); + unlock_2_inodes(dir, inode); + ubifs_release_budget(c, &req); + iput(inode); + return err; +} + +static int ubifs_unlink(struct inode *dir, struct dentry *dentry) +{ + struct ubifs_info *c = dir->i_sb->s_fs_info; + struct inode *inode = dentry->d_inode; + struct ubifs_inode *dir_ui = ubifs_inode(dir); + int sz_change = CALC_DENT_SIZE(dentry->d_name.len); + int err, budgeted = 1; + struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; + + /* + * Budget request settings: deletion direntry, deletion inode (+1 for + * @dirtied_ino), changing the parent directory inode. If budgeting + * fails, go ahead anyway because we have extra space reserved for + * deletions. + */ + + 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); + err = dbg_check_synced_i_size(inode); + if (err) + return err; + + err = ubifs_budget_space(c, &req); + if (err) { + if (err != -ENOSPC) + return err; + err = 0; + budgeted = 0; + } + + lock_2_inodes(dir, inode); + inode->i_ctime = ubifs_current_time(dir); + drop_nlink(inode); + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0); + if (err) + goto out_cancel; + unlock_2_inodes(dir, inode); + + if (budgeted) + ubifs_release_budget(c, &req); + else { + /* We've deleted something - clean the "no space" flags */ + c->nospace = c->nospace_rp = 0; + smp_wmb(); + } + return 0; + +out_cancel: + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + inc_nlink(inode); + unlock_2_inodes(dir, inode); + if (budgeted) + ubifs_release_budget(c, &req); + return err; +} + +/** + * check_dir_empty - check if a directory is empty or not. + * @c: UBIFS file-system description object + * @dir: VFS inode object of the directory to check + * + * This function checks if directory @dir is empty. Returns zero if the + * directory is empty, %-ENOTEMPTY if it is not, and other negative error codes + * in case of of errors. + */ +static int check_dir_empty(struct ubifs_info *c, struct inode *dir) +{ + struct qstr nm = { .name = NULL }; + struct ubifs_dent_node *dent; + union ubifs_key key; + int err; + + lowest_dent_key(c, &key, dir->i_ino); + dent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(dent)) { + err = PTR_ERR(dent); + if (err == -ENOENT) + err = 0; + } else { + kfree(dent); + err = -ENOTEMPTY; + } + return err; +} + +static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct ubifs_info *c = dir->i_sb->s_fs_info; + struct inode *inode = dentry->d_inode; + int sz_change = CALC_DENT_SIZE(dentry->d_name.len); + int err, budgeted = 1; + struct ubifs_inode *dir_ui = ubifs_inode(dir); + struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; + + /* + * Budget request settings: deletion direntry, deletion inode and + * changing the parent inode. If budgeting fails, go ahead anyway + * because we have extra space reserved for deletions. + */ + + dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len, + dentry->d_name.name, inode->i_ino, dir->i_ino); + + err = check_dir_empty(c, dentry->d_inode); + if (err) + return err; + + err = ubifs_budget_space(c, &req); + if (err) { + if (err != -ENOSPC) + return err; + budgeted = 0; + } + + lock_2_inodes(dir, inode); + inode->i_ctime = ubifs_current_time(dir); + clear_nlink(inode); + drop_nlink(dir); + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0); + if (err) + goto out_cancel; + unlock_2_inodes(dir, inode); + + if (budgeted) + ubifs_release_budget(c, &req); + else { + /* We've deleted something - clean the "no space" flags */ + c->nospace = c->nospace_rp = 0; + smp_wmb(); + } + return 0; + +out_cancel: + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + inc_nlink(dir); + inc_nlink(inode); + inc_nlink(inode); + unlock_2_inodes(dir, inode); + if (budgeted) + ubifs_release_budget(c, &req); + return err; +} + +static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + struct inode *inode; + struct ubifs_inode *dir_ui = ubifs_inode(dir); + struct ubifs_info *c = dir->i_sb->s_fs_info; + int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, + .dirtied_ino_d = 1 }; + + /* + * Budget request settings: new inode, new direntry and changing parent + * directory inode. + */ + + dbg_gen("dent '%.*s', mode %#x in dir ino %lu", + dentry->d_name.len, dentry->d_name.name, mode, dir->i_ino); + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + inode = ubifs_new_inode(c, dir, S_IFDIR | mode); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_budg; + } + + mutex_lock(&dir_ui->ui_mutex); + insert_inode_hash(inode); + inc_nlink(inode); + inc_nlink(dir); + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); + if (err) { + ubifs_err("cannot create directory, error %d", err); + goto out_cancel; + } + mutex_unlock(&dir_ui->ui_mutex); + + ubifs_release_budget(c, &req); + d_instantiate(dentry, inode); + return 0; + +out_cancel: + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + drop_nlink(dir); + mutex_unlock(&dir_ui->ui_mutex); + make_bad_inode(inode); + iput(inode); +out_budg: + ubifs_release_budget(c, &req); + return err; +} + +static int ubifs_mknod(struct inode *dir, struct dentry *dentry, + int mode, dev_t rdev) +{ + struct inode *inode; + struct ubifs_inode *ui; + struct ubifs_inode *dir_ui = ubifs_inode(dir); + struct ubifs_info *c = dir->i_sb->s_fs_info; + union ubifs_dev_desc *dev = NULL; + int sz_change = CALC_DENT_SIZE(dentry->d_name.len); + int err, devlen = 0; + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, + .new_ino_d = devlen, .dirtied_ino = 1 }; + + /* + * Budget request settings: new inode, new direntry and changing parent + * directory inode. + */ + + dbg_gen("dent '%.*s' in dir ino %lu", + dentry->d_name.len, dentry->d_name.name, dir->i_ino); + + if (!new_valid_dev(rdev)) + return -EINVAL; + + if (S_ISBLK(mode) || S_ISCHR(mode)) { + dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); + if (!dev) + return -ENOMEM; + devlen = ubifs_encode_dev(dev, rdev); + } + + err = ubifs_budget_space(c, &req); + if (err) { + kfree(dev); + return err; + } + + inode = ubifs_new_inode(c, dir, mode); + if (IS_ERR(inode)) { + kfree(dev); + err = PTR_ERR(inode); + goto out_budg; + } + + init_special_inode(inode, inode->i_mode, rdev); + inode->i_size = ubifs_inode(inode)->ui_size = devlen; + ui = ubifs_inode(inode); + ui->data = dev; + ui->data_len = devlen; + + mutex_lock(&dir_ui->ui_mutex); + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); + if (err) + goto out_cancel; + mutex_unlock(&dir_ui->ui_mutex); + + ubifs_release_budget(c, &req); + insert_inode_hash(inode); + d_instantiate(dentry, inode); + return 0; + +out_cancel: + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + mutex_unlock(&dir_ui->ui_mutex); + make_bad_inode(inode); + iput(inode); +out_budg: + ubifs_release_budget(c, &req); + return err; +} + +static int ubifs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname) +{ + struct inode *inode; + struct ubifs_inode *ui; + struct ubifs_inode *dir_ui = ubifs_inode(dir); + struct ubifs_info *c = dir->i_sb->s_fs_info; + int err, len = strlen(symname); + int sz_change = CALC_DENT_SIZE(dentry->d_name.len); + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, + .new_ino_d = len, .dirtied_ino = 1 }; + + /* + * Budget request settings: new inode, new direntry and changing parent + * directory inode. + */ + + dbg_gen("dent '%.*s', target '%s' in dir ino %lu", dentry->d_name.len, + dentry->d_name.name, symname, dir->i_ino); + + if (len > UBIFS_MAX_INO_DATA) + return -ENAMETOOLONG; + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_budg; + } + + ui = ubifs_inode(inode); + ui->data = kmalloc(len + 1, GFP_NOFS); + if (!ui->data) { + err = -ENOMEM; + goto out_inode; + } + + memcpy(ui->data, symname, len); + ((char *)ui->data)[len] = '\0'; + /* + * The terminating zero byte is not written to the flash media and it + * is put just to make later in-memory string processing simpler. Thus, + * data length is @len, not @len + %1. + */ + ui->data_len = len; + inode->i_size = ubifs_inode(inode)->ui_size = len; + + mutex_lock(&dir_ui->ui_mutex); + dir->i_size += sz_change; + dir_ui->ui_size = dir->i_size; + dir->i_mtime = dir->i_ctime = inode->i_ctime; + err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 0, 0); + if (err) + goto out_cancel; + mutex_unlock(&dir_ui->ui_mutex); + + ubifs_release_budget(c, &req); + insert_inode_hash(inode); + d_instantiate(dentry, inode); + return 0; + +out_cancel: + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + mutex_unlock(&dir_ui->ui_mutex); +out_inode: + make_bad_inode(inode); + iput(inode); +out_budg: + ubifs_release_budget(c, &req); + return err; +} + +/** + * lock_3_inodes - lock three UBIFS inodes for rename. + * @inode1: first inode + * @inode2: second inode + * @inode3: third inode + * + * 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) +{ + 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 - unlock three UBIFS inodes for rename. + * @inode1: first inode + * @inode2: second inode + * @inode3: third inode + */ +static void unlock_3_inodes(struct inode *inode1, struct inode *inode2, + struct inode *inode3) +{ + mutex_unlock(&ubifs_inode(inode1)->ui_mutex); + if (inode1 != inode2) + mutex_unlock(&ubifs_inode(inode2)->ui_mutex); + if (inode3) + mutex_unlock(&ubifs_inode(inode3)->ui_mutex); +} + +static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct ubifs_info *c = old_dir->i_sb->s_fs_info; + struct inode *old_inode = old_dentry->d_inode; + struct inode *new_inode = new_dentry->d_inode; + struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode); + int err, release, sync = 0, move = (new_dir != old_dir); + int is_dir = S_ISDIR(old_inode->i_mode); + int unlink = !!new_inode; + int new_sz = CALC_DENT_SIZE(new_dentry->d_name.len); + int old_sz = CALC_DENT_SIZE(old_dentry->d_name.len); + struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1, + .dirtied_ino = 3 }; + struct ubifs_budget_req ino_req = { .dirtied_ino = 1, + .dirtied_ino_d = old_inode_ui->data_len }; + struct timespec time; + + /* + * Budget request settings: deletion direntry, new direntry, removing + * the old inode, and changing old and new parent directory inodes. + * + * However, this operation also marks the target inode as dirty and + * does not write it, so we allocate budget for the target inode + * separately. + */ + + dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in " + "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); + + if (unlink && is_dir) { + err = check_dir_empty(c, new_inode); + if (err) + return err; + } + + err = ubifs_budget_space(c, &req); + if (err) + return err; + err = ubifs_budget_space(c, &ino_req); + if (err) { + ubifs_release_budget(c, &req); + return err; + } + + lock_3_inodes(old_dir, new_dir, new_inode); + + /* + * Like most other Unix systems, set the @i_ctime for inodes on a + * rename. + */ + time = ubifs_current_time(old_dir); + old_inode->i_ctime = time; + + /* We must adjust parent link count when renaming directories */ + if (is_dir) { + if (move) { + /* + * @old_dir loses a link because we are moving + * @old_inode to a different directory. + */ + drop_nlink(old_dir); + /* + * @new_dir only gains a link if we are not also + * overwriting an existing directory. + */ + if (!unlink) + inc_nlink(new_dir); + } else { + /* + * @old_inode is not moving to a different directory, + * but @old_dir still loses a link if we are + * overwriting an existing directory. + */ + if (unlink) + drop_nlink(old_dir); + } + } + + old_dir->i_size -= old_sz; + ubifs_inode(old_dir)->ui_size = old_dir->i_size; + old_dir->i_mtime = old_dir->i_ctime = time; + new_dir->i_mtime = new_dir->i_ctime = time; + + /* + * And finally, if we unlinked a direntry which happened to have the + * same name as the moved direntry, we have to decrement @i_nlink of + * the unlinked inode and change its ctime. + */ + if (unlink) { + /* + * Directories cannot have hard-links, so if this is a + * directory, decrement its @i_nlink twice because an empty + * directory has @i_nlink 2. + */ + if (is_dir) + drop_nlink(new_inode); + new_inode->i_ctime = time; + drop_nlink(new_inode); + } else { + new_dir->i_size += new_sz; + ubifs_inode(new_dir)->ui_size = new_dir->i_size; + } + + /* + * Do not ask 'ubifs_jnl_rename()' to flush write-buffer if @old_inode + * is dirty, because this will be done later on at the end of + * 'ubifs_rename()'. + */ + if (IS_SYNC(old_inode)) { + sync = IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir); + if (unlink && IS_SYNC(new_inode)) + sync = 1; + } + err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry, + sync); + if (err) + goto out_cancel; + + unlock_3_inodes(old_dir, new_dir, new_inode); + ubifs_release_budget(c, &req); + + mutex_lock(&old_inode_ui->ui_mutex); + release = old_inode_ui->dirty; + mark_inode_dirty_sync(old_inode); + mutex_unlock(&old_inode_ui->ui_mutex); + + if (release) + ubifs_release_budget(c, &ino_req); + if (IS_SYNC(old_inode)) + err = old_inode->i_sb->s_op->write_inode(old_inode, 1); + return err; + +out_cancel: + if (unlink) { + if (is_dir) + inc_nlink(new_inode); + inc_nlink(new_inode); + } else { + new_dir->i_size -= new_sz; + ubifs_inode(new_dir)->ui_size = new_dir->i_size; + } + old_dir->i_size += old_sz; + ubifs_inode(old_dir)->ui_size = old_dir->i_size; + if (is_dir) { + if (move) { + inc_nlink(old_dir); + if (!unlink) + drop_nlink(new_dir); + } else { + if (unlink) + inc_nlink(old_dir); + } + } + unlock_3_inodes(old_dir, new_dir, new_inode); + ubifs_release_budget(c, &ino_req); + ubifs_release_budget(c, &req); + return err; +} + +int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) +{ + loff_t size; + struct inode *inode = dentry->d_inode; + struct ubifs_inode *ui = ubifs_inode(inode); + + mutex_lock(&ui->ui_mutex); + stat->dev = inode->i_sb->s_dev; + stat->ino = inode->i_ino; + stat->mode = inode->i_mode; + stat->nlink = inode->i_nlink; + stat->uid = inode->i_uid; + stat->gid = inode->i_gid; + stat->rdev = inode->i_rdev; + stat->atime = inode->i_atime; + stat->mtime = inode->i_mtime; + stat->ctime = inode->i_ctime; + stat->blksize = UBIFS_BLOCK_SIZE; + stat->size = ui->ui_size; + + /* + * Unfortunately, the 'stat()' system call was designed for block + * device based file systems, and it is not appropriate for UBIFS, + * because UBIFS does not have notion of "block". For example, it is + * difficult to tell how many block a directory takes - it actually + * takes less than 300 bytes, but we have to round it to block size, + * which introduces large mistake. This makes utilities like 'du' to + * report completely senseless numbers. This is the reason why UBIFS + * goes the same way as JFFS2 - it reports zero blocks for everything + * but regular files, which makes more sense than reporting completely + * wrong sizes. + */ + if (S_ISREG(inode->i_mode)) { + size = ui->xattr_size; + size += stat->size; + size = ALIGN(size, UBIFS_BLOCK_SIZE); + /* + * Note, user-space expects 512-byte blocks count irrespectively + * of what was reported in @stat->size. + */ + stat->blocks = size >> 9; + } else + stat->blocks = 0; + mutex_unlock(&ui->ui_mutex); + return 0; +} + +struct inode_operations ubifs_dir_inode_operations = { + .lookup = ubifs_lookup, + .create = ubifs_create, + .link = ubifs_link, + .symlink = ubifs_symlink, + .unlink = ubifs_unlink, + .mkdir = ubifs_mkdir, + .rmdir = ubifs_rmdir, + .mknod = ubifs_mknod, + .rename = ubifs_rename, + .setattr = ubifs_setattr, + .getattr = ubifs_getattr, +#ifdef CONFIG_UBIFS_FS_XATTR + .setxattr = ubifs_setxattr, + .getxattr = ubifs_getxattr, + .listxattr = ubifs_listxattr, + .removexattr = ubifs_removexattr, +#endif +}; + +struct file_operations ubifs_dir_operations = { + .llseek = ubifs_dir_llseek, + .release = ubifs_dir_release, + .read = generic_read_dir, + .readdir = ubifs_readdir, + .fsync = ubifs_fsync, + .unlocked_ioctl = ubifs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ubifs_compat_ioctl, +#endif +}; diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c new file mode 100644 index 0000000..005a3b8 --- /dev/null +++ b/fs/ubifs/file.c @@ -0,0 +1,1275 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements VFS file and inode operations of regular files, device + * nodes and symlinks as well as address space operations. + * + * UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the + * page is dirty and is used for budgeting purposes - dirty pages should not be + * budgeted. The PG_checked flag is set if full budgeting is required for the + * page e.g., when it corresponds to a file hole or it is just beyond the file + * size. The budgeting is done in 'ubifs_write_begin()', because it is OK to + * fail in this function, and the budget is released in 'ubifs_write_end()'. So + * the PG_private and PG_checked flags carry the information about how the page + * was budgeted, to make it possible to release the budget properly. + * + * A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations + * we implement. However, this is not true for '->writepage()', which might be + * called with 'i_mutex' unlocked. For example, when pdflush is performing + * write-back, it calls 'writepage()' with unlocked 'i_mutex', although the + * inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is + * locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim + * path'. So, in '->writepage()' we are only guaranteed that the page is + * locked. + * + * Similarly, 'i_mutex' does not have to be locked in readpage(), e.g., + * readahead path does not have it locked ("sys_read -> generic_file_aio_read + * -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is + * not set as well. However, UBIFS disables readahead. + * + * This, for example means that there might be 2 concurrent '->writepage()' + * calls for the same inode, but different inode dirty pages. + */ + +#include "ubifs.h" +#include + +static int read_block(struct inode *inode, void *addr, unsigned int block, + struct ubifs_data_node *dn) +{ + struct ubifs_info *c = inode->i_sb->s_fs_info; + int err, len, out_len; + union ubifs_key key; + unsigned int dlen; + + data_key_init(c, &key, inode->i_ino, block); + err = ubifs_tnc_lookup(c, &key, dn); + if (err) { + if (err == -ENOENT) + /* Not found, so it must be a hole */ + memset(addr, 0, UBIFS_BLOCK_SIZE); + return err; + } + + ubifs_assert(dn->ch.sqnum > ubifs_inode(inode)->creat_sqnum); + + len = le32_to_cpu(dn->size); + if (len <= 0 || len > UBIFS_BLOCK_SIZE) + goto dump; + + dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; + out_len = UBIFS_BLOCK_SIZE; + err = ubifs_decompress(&dn->data, dlen, addr, &out_len, + le16_to_cpu(dn->compr_type)); + if (err || len != out_len) + goto dump; + + /* + * Data length can be less than a full block, even for blocks that are + * not the last in the file (e.g., as a result of making a hole and + * appending data). Ensure that the remainder is zeroed out. + */ + if (len < UBIFS_BLOCK_SIZE) + memset(addr + len, 0, UBIFS_BLOCK_SIZE - len); + + return 0; + +dump: + ubifs_err("bad data node (block %u, inode %lu)", + block, inode->i_ino); + dbg_dump_node(c, dn); + return -EINVAL; +} + +static int do_readpage(struct page *page) +{ + void *addr; + int err = 0, i; + unsigned int block, beyond; + struct ubifs_data_node *dn; + struct inode *inode = page->mapping->host; + loff_t i_size = i_size_read(inode); + + dbg_gen("ino %lu, pg %lu, i_size %lld, flags %#lx", + inode->i_ino, page->index, i_size, page->flags); + ubifs_assert(!PageChecked(page)); + ubifs_assert(!PagePrivate(page)); + + addr = kmap(page); + + block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT; + beyond = (i_size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; + if (block >= beyond) { + /* Reading beyond inode */ + SetPageChecked(page); + memset(addr, 0, PAGE_CACHE_SIZE); + goto out; + } + + dn = kmalloc(UBIFS_MAX_DATA_NODE_SZ, GFP_NOFS); + if (!dn) { + err = -ENOMEM; + goto error; + } + + i = 0; + while (1) { + int ret; + + if (block >= beyond) { + /* Reading beyond inode */ + err = -ENOENT; + memset(addr, 0, UBIFS_BLOCK_SIZE); + } else { + ret = read_block(inode, addr, block, dn); + if (ret) { + err = ret; + if (err != -ENOENT) + break; + } + } + if (++i >= UBIFS_BLOCKS_PER_PAGE) + break; + block += 1; + addr += UBIFS_BLOCK_SIZE; + } + if (err) { + if (err == -ENOENT) { + /* Not found, so it must be a hole */ + SetPageChecked(page); + dbg_gen("hole"); + goto out_free; + } + ubifs_err("cannot read page %lu of inode %lu, error %d", + page->index, inode->i_ino, err); + goto error; + } + +out_free: + kfree(dn); +out: + SetPageUptodate(page); + ClearPageError(page); + flush_dcache_page(page); + kunmap(page); + return 0; + +error: + kfree(dn); + ClearPageUptodate(page); + SetPageError(page); + flush_dcache_page(page); + kunmap(page); + return err; +} + +/** + * release_new_page_budget - release budget of a new page. + * @c: UBIFS file-system description object + * + * This is a helper function which releases budget corresponding to the budget + * of one new page of data. + */ +static void release_new_page_budget(struct ubifs_info *c) +{ + struct ubifs_budget_req req = { .recalculate = 1, .new_page = 1 }; + + ubifs_release_budget(c, &req); +} + +/** + * release_existing_page_budget - release budget of an existing page. + * @c: UBIFS file-system description object + * + * This is a helper function which releases budget corresponding to the budget + * of changing one one page of data which already exists on the flash media. + */ +static void release_existing_page_budget(struct ubifs_info *c) +{ + struct ubifs_budget_req req = { .dd_growth = c->page_budget}; + + ubifs_release_budget(c, &req); +} + +static int write_begin_slow(struct address_space *mapping, + loff_t pos, unsigned len, struct page **pagep) +{ + struct inode *inode = mapping->host; + struct ubifs_info *c = inode->i_sb->s_fs_info; + pgoff_t index = pos >> PAGE_CACHE_SHIFT; + struct ubifs_budget_req req = { .new_page = 1 }; + int uninitialized_var(err), appending = !!(pos + len > inode->i_size); + struct page *page; + + dbg_gen("ino %lu, pos %llu, len %u, i_size %lld", + inode->i_ino, pos, len, inode->i_size); + + /* + * At the slow path we have to budget before locking the page, because + * budgeting may force write-back, which would wait on locked pages and + * deadlock if we had the page locked. At this point we do not know + * anything about the page, so assume that this is a new page which is + * written to a hole. This corresponds to largest budget. Later the + * budget will be amended if this is not true. + */ + if (appending) + /* We are appending data, budget for inode change */ + req.dirtied_ino = 1; + + err = ubifs_budget_space(c, &req); + if (unlikely(err)) + return err; + + page = __grab_cache_page(mapping, index); + if (unlikely(!page)) { + ubifs_release_budget(c, &req); + return -ENOMEM; + } + + if (!PageUptodate(page)) { + if (!(pos & PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) + SetPageChecked(page); + else { + err = do_readpage(page); + if (err) { + unlock_page(page); + page_cache_release(page); + return err; + } + } + + SetPageUptodate(page); + ClearPageError(page); + } + + if (PagePrivate(page)) + /* + * The page is dirty, which means it was budgeted twice: + * o first time the budget was allocated by the task which + * made the page dirty and set the PG_private flag; + * o and then we budgeted for it for the second time at the + * very beginning of this function. + * + * So what we have to do is to release the page budget we + * allocated. + */ + release_new_page_budget(c); + else if (!PageChecked(page)) + /* + * We are changing a page which already exists on the media. + * This means that changing the page does not make the amount + * of indexing information larger, and this part of the budget + * which we have already acquired may be released. + */ + ubifs_convert_page_budget(c); + + if (appending) { + struct ubifs_inode *ui = ubifs_inode(inode); + + /* + * 'ubifs_write_end()' is optimized from the fast-path part of + * 'ubifs_write_begin()' and expects the @ui_mutex to be locked + * if data is appended. + */ + mutex_lock(&ui->ui_mutex); + if (ui->dirty) + /* + * The inode is dirty already, so we may free the + * budget we allocated. + */ + ubifs_release_dirty_inode_budget(c, ui); + } + + *pagep = page; + return 0; +} + +/** + * allocate_budget - allocate budget for 'ubifs_write_begin()'. + * @c: UBIFS file-system description object + * @page: page to allocate budget for + * @ui: UBIFS inode object the page belongs to + * @appending: non-zero if the page is appended + * + * This is a helper function for 'ubifs_write_begin()' which allocates budget + * for the operation. The budget is allocated differently depending on whether + * this is appending, whether the page is dirty or not, and so on. This + * function leaves the @ui->ui_mutex locked in case of appending. Returns zero + * in case of success and %-ENOSPC in case of failure. + */ +static int allocate_budget(struct ubifs_info *c, struct page *page, + struct ubifs_inode *ui, int appending) +{ + struct ubifs_budget_req req = { .fast = 1 }; + + if (PagePrivate(page)) { + if (!appending) + /* + * The page is dirty and we are not appending, which + * means no budget is needed at all. + */ + return 0; + + mutex_lock(&ui->ui_mutex); + if (ui->dirty) + /* + * The page is dirty and we are appending, so the inode + * has to be marked as dirty. However, it is already + * dirty, so we do not need any budget. We may return, + * but @ui->ui_mutex hast to be left locked because we + * should prevent write-back from flushing the inode + * and freeing the budget. The lock will be released in + * 'ubifs_write_end()'. + */ + return 0; + + /* + * The page is dirty, we are appending, the inode is clean, so + * we need to budget the inode change. + */ + req.dirtied_ino = 1; + } else { + if (PageChecked(page)) + /* + * The page corresponds to a hole and does not + * exist on the media. So changing it makes + * make the amount of indexing information + * larger, and we have to budget for a new + * page. + */ + req.new_page = 1; + else + /* + * Not a hole, the change will not add any new + * indexing information, budget for page + * change. + */ + req.dirtied_page = 1; + + if (appending) { + mutex_lock(&ui->ui_mutex); + if (!ui->dirty) + /* + * The inode is clean but we will have to mark + * it as dirty because we are appending. This + * needs a budget. + */ + req.dirtied_ino = 1; + } + } + + return ubifs_budget_space(c, &req); +} + +/* + * This function is called when a page of data is going to be written. Since + * the page of data will not necessarily go to the flash straight away, UBIFS + * has to reserve space on the media for it, which is done by means of + * budgeting. + * + * This is the hot-path of the file-system and we are trying to optimize it as + * much as possible. For this reasons it is split on 2 parts - slow and fast. + * + * There many budgeting cases: + * o a new page is appended - we have to budget for a new page and for + * changing the inode; however, if the inode is already dirty, there is + * no need to budget for it; + * o an existing clean page is changed - we have budget for it; if the page + * does not exist on the media (a hole), we have to budget for a new + * page; otherwise, we may budget for changing an existing page; the + * difference between these cases is that changing an existing page does + * not introduce anything new to the FS indexing information, so it does + * not grow, and smaller budget is acquired in this case; + * o an existing dirty page is changed - no need to budget at all, because + * the page budget has been acquired by earlier, when the page has been + * marked dirty. + * + * UBIFS budgeting sub-system may force write-back if it thinks there is no + * space to reserve. This imposes some locking restrictions and makes it + * impossible to take into account the above cases, and makes it impossible to + * optimize budgeting. + * + * The solution for this is that the fast path of 'ubifs_write_begin()' assumes + * there is a plenty of flash space and the budget will be acquired quickly, + * without forcing write-back. The slow path does not make this assumption. + */ +static int ubifs_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + struct inode *inode = mapping->host; + struct ubifs_info *c = inode->i_sb->s_fs_info; + struct ubifs_inode *ui = ubifs_inode(inode); + pgoff_t index = pos >> PAGE_CACHE_SHIFT; + 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)) + return -EROFS; + + /* Try out the fast-path part first */ + page = __grab_cache_page(mapping, index); + if (unlikely(!page)) + return -ENOMEM; + + if (!PageUptodate(page)) { + /* The page is not loaded from the flash */ + if (!(pos & PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) + /* + * We change whole page so no need to load it. But we + * have to set the @PG_checked flag to make the further + * code the page is new. This might be not true, but it + * is better to budget more that to read the page from + * the media. + */ + SetPageChecked(page); + else { + err = do_readpage(page); + if (err) { + unlock_page(page); + page_cache_release(page); + return err; + } + } + + SetPageUptodate(page); + ClearPageError(page); + } + + err = allocate_budget(c, page, ui, appending); + if (unlikely(err)) { + ubifs_assert(err == -ENOSPC); + /* + * Budgeting failed which means it would have to force + * write-back but didn't, because we set the @fast flag in the + * request. Write-back cannot be done now, while we have the + * page locked, because it would deadlock. Unlock and free + * everything and fall-back to slow-path. + */ + if (appending) { + ubifs_assert(mutex_is_locked(&ui->ui_mutex)); + mutex_unlock(&ui->ui_mutex); + } + unlock_page(page); + page_cache_release(page); + + return write_begin_slow(mapping, pos, len, pagep); + } + + /* + * Whee, we aquired budgeting quickly - without involving + * garbage-collection, committing or forceing write-back. We return + * with @ui->ui_mutex locked if we are appending pages, and unlocked + * otherwise. This is an optimization (slightly hacky though). + */ + *pagep = page; + return 0; + +} + +/** + * cancel_budget - cancel budget. + * @c: UBIFS file-system description object + * @page: page to cancel budget for + * @ui: UBIFS inode object the page belongs to + * @appending: non-zero if the page is appended + * + * This is a helper function for a page write operation. It unlocks the + * @ui->ui_mutex in case of appending. + */ +static void cancel_budget(struct ubifs_info *c, struct page *page, + struct ubifs_inode *ui, int appending) +{ + if (appending) { + if (!ui->dirty) + ubifs_release_dirty_inode_budget(c, ui); + mutex_unlock(&ui->ui_mutex); + } + if (!PagePrivate(page)) { + if (PageChecked(page)) + release_new_page_budget(c); + else + release_existing_page_budget(c); + } +} + +static int ubifs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ + struct inode *inode = mapping->host; + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_info *c = inode->i_sb->s_fs_info; + loff_t end_pos = pos + len; + int appending = !!(end_pos > inode->i_size); + + dbg_gen("ino %lu, pos %llu, pg %lu, len %u, copied %d, i_size %lld", + inode->i_ino, pos, page->index, len, copied, inode->i_size); + + if (unlikely(copied < len && len == PAGE_CACHE_SIZE)) { + /* + * VFS copied less data to the page that it intended and + * declared in its '->write_begin()' call via the @len + * argument. If the page was not up-to-date, and @len was + * @PAGE_CACHE_SIZE, the 'ubifs_write_begin()' function did + * not load it from the media (for optimization reasons). This + * means that part of the page contains garbage. So read the + * page now. + */ + dbg_gen("copied %d instead of %d, read page and repeat", + copied, len); + cancel_budget(c, page, ui, appending); + + /* + * Return 0 to force VFS to repeat the whole operation, or the + * error code if 'do_readpage()' failes. + */ + copied = do_readpage(page); + goto out; + } + + if (!PagePrivate(page)) { + SetPagePrivate(page); + atomic_long_inc(&c->dirty_pg_cnt); + __set_page_dirty_nobuffers(page); + } + + if (appending) { + i_size_write(inode, end_pos); + ui->ui_size = end_pos; + /* + * Note, we do not set @I_DIRTY_PAGES (which means that the + * inode has dirty pages), this has been done in + * '__set_page_dirty_nobuffers()'. + */ + __mark_inode_dirty(inode, I_DIRTY_DATASYNC); + ubifs_assert(mutex_is_locked(&ui->ui_mutex)); + mutex_unlock(&ui->ui_mutex); + } + +out: + unlock_page(page); + page_cache_release(page); + return copied; +} + +static int ubifs_readpage(struct file *file, struct page *page) +{ + do_readpage(page); + unlock_page(page); + return 0; +} + +static int do_writepage(struct page *page, int len) +{ + int err = 0, i, blen; + unsigned int block; + void *addr; + union ubifs_key key; + struct inode *inode = page->mapping->host; + struct ubifs_info *c = inode->i_sb->s_fs_info; + +#ifdef UBIFS_DEBUG + spin_lock(&ui->ui_lock); + ubifs_assert(page->index <= ui->synced_i_size << PAGE_CACHE_SIZE); + spin_unlock(&ui->ui_lock); +#endif + + /* Update radix tree tags */ + set_page_writeback(page); + + addr = kmap(page); + block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT; + i = 0; + while (len) { + blen = min_t(int, len, UBIFS_BLOCK_SIZE); + data_key_init(c, &key, inode->i_ino, block); + err = ubifs_jnl_write_data(c, inode, &key, addr, blen); + if (err) + break; + if (++i >= UBIFS_BLOCKS_PER_PAGE) + break; + block += 1; + addr += blen; + len -= blen; + } + if (err) { + SetPageError(page); + ubifs_err("cannot write page %lu of inode %lu, error %d", + page->index, inode->i_ino, err); + ubifs_ro_mode(c, err); + } + + ubifs_assert(PagePrivate(page)); + if (PageChecked(page)) + release_new_page_budget(c); + else + release_existing_page_budget(c); + + atomic_long_dec(&c->dirty_pg_cnt); + ClearPagePrivate(page); + ClearPageChecked(page); + + kunmap(page); + unlock_page(page); + end_page_writeback(page); + return err; +} + +/* + * When writing-back dirty inodes, VFS first writes-back pages belonging to the + * inode, then the inode itself. For UBIFS this may cause a problem. Consider a + * situation when a we have an inode with size 0, then a megabyte of data is + * appended to the inode, then write-back starts and flushes some amount of the + * dirty pages, the journal becomes full, commit happens and finishes, and then + * an unclean reboot happens. When the file system is mounted next time, the + * inode size would still be 0, but there would be many pages which are beyond + * the inode size, they would be indexed and consume flash space. Because the + * journal has been committed, the replay would not be able to detect this + * situation and correct the inode size. This means UBIFS would have to scan + * whole index and correct all inode sizes, which is long an unacceptable. + * + * To prevent situations like this, UBIFS writes pages back only if they are + * within last synchronized inode size, i.e. the the size which has been + * written to the flash media last time. Otherwise, UBIFS forces inode + * write-back, thus making sure the on-flash inode contains current inode size, + * and then keeps writing pages back. + * + * Some locking issues explanation. 'ubifs_writepage()' first is called with + * the page locked, and it locks @ui_mutex. However, write-back does take inode + * @i_mutex, which means other VFS operations may be run on this inode at the + * same time. And the problematic one is truncation to smaller size, from where + * we have to call 'vmtruncate()', which first changes @inode->i_size, then + * drops the truncated pages. And while dropping the pages, it takes the page + * lock. This means that 'do_truncation()' cannot call 'vmtruncate()' with + * @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This + * means that @inode->i_size is changed while @ui_mutex is unlocked. + * + * But in 'ubifs_writepage()' we have to guarantee that we do not write beyond + * inode size. How do we do this if @inode->i_size may became smaller while we + * are in the middle of 'ubifs_writepage()'? The UBIFS solution is the + * @ui->ui_isize "shadow" field which UBIFS uses instead of @inode->i_size + * internally and updates it under @ui_mutex. + * + * Q: why we do not worry that if we race with truncation, we may end up with a + * situation when the inode is truncated while we are in the middle of + * 'do_writepage()', so we do write beyond inode size? + * A: If we are in the middle of 'do_writepage()', truncation would be locked + * on the page lock and it would not write the truncated inode node to the + * journal before we have finished. + */ +static int ubifs_writepage(struct page *page, struct writeback_control *wbc) +{ + struct inode *inode = page->mapping->host; + struct ubifs_inode *ui = ubifs_inode(inode); + loff_t i_size = i_size_read(inode), synced_i_size; + pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; + int err, len = i_size & (PAGE_CACHE_SIZE - 1); + void *kaddr; + + dbg_gen("ino %lu, pg %lu, pg flags %#lx", + inode->i_ino, page->index, page->flags); + ubifs_assert(PagePrivate(page)); + + /* Is the page fully outside @i_size? (truncate in progress) */ + if (page->index > end_index || (page->index == end_index && !len)) { + err = 0; + goto out_unlock; + } + + spin_lock(&ui->ui_lock); + synced_i_size = ui->synced_i_size; + spin_unlock(&ui->ui_lock); + + /* Is the page fully inside @i_size? */ + if (page->index < end_index) { + if (page->index >= synced_i_size >> PAGE_CACHE_SHIFT) { + err = inode->i_sb->s_op->write_inode(inode, 1); + if (err) + goto out_unlock; + /* + * The inode has been written, but the write-buffer has + * not been synchronized, so in case of an unclean + * reboot we may end up with some pages beyond inode + * size, but they would be in the journal (because + * commit flushes write buffers) and recovery would deal + * with this. + */ + } + return do_writepage(page, PAGE_CACHE_SIZE); + } + + /* + * The page straddles @i_size. It must be zeroed out on each and every + * writepage invocation because it may be mmapped. "A file is mapped + * in multiples of the page size. For a file that is not a multiple of + * the page size, the remaining memory is zeroed when mapped, and + * writes to that region are not written out to the file." + */ + kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + len, 0, PAGE_CACHE_SIZE - len); + flush_dcache_page(page); + kunmap_atomic(kaddr, KM_USER0); + + if (i_size > synced_i_size) { + err = inode->i_sb->s_op->write_inode(inode, 1); + if (err) + goto out_unlock; + } + + return do_writepage(page, len); + +out_unlock: + unlock_page(page); + return err; +} + +/** + * do_attr_changes - change inode attributes. + * @inode: inode to change attributes for + * @attr: describes attributes to change + */ +static void do_attr_changes(struct inode *inode, const struct iattr *attr) +{ + if (attr->ia_valid & ATTR_UID) + inode->i_uid = attr->ia_uid; + if (attr->ia_valid & ATTR_GID) + inode->i_gid = attr->ia_gid; + if (attr->ia_valid & ATTR_ATIME) + inode->i_atime = timespec_trunc(attr->ia_atime, + inode->i_sb->s_time_gran); + if (attr->ia_valid & ATTR_MTIME) + inode->i_mtime = timespec_trunc(attr->ia_mtime, + inode->i_sb->s_time_gran); + if (attr->ia_valid & ATTR_CTIME) + inode->i_ctime = timespec_trunc(attr->ia_ctime, + inode->i_sb->s_time_gran); + if (attr->ia_valid & ATTR_MODE) { + umode_t mode = attr->ia_mode; + + if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) + mode &= ~S_ISGID; + inode->i_mode = mode; + } +} + +/** + * do_truncation - truncate an inode. + * @c: UBIFS file-system description object + * @inode: inode to truncate + * @attr: inode attribute changes description + * + * This function implements VFS '->setattr()' call when the inode is truncated + * to a smaller size. Returns zero in case of success and a negative error code + * in case of failure. + */ +static int do_truncation(struct ubifs_info *c, struct inode *inode, + const struct iattr *attr) +{ + int err; + struct ubifs_budget_req req; + loff_t old_size = inode->i_size, new_size = attr->ia_size; + int offset = new_size & (UBIFS_BLOCK_SIZE - 1); + struct ubifs_inode *ui = ubifs_inode(inode); + + dbg_gen("ino %lu, size %lld -> %lld", inode->i_ino, old_size, new_size); + memset(&req, 0, sizeof(struct ubifs_budget_req)); + + /* + * If this is truncation to a smaller size, and we do not truncate on a + * block boundary, budget for changing one data block, because the last + * block will be re-written. + */ + if (new_size & (UBIFS_BLOCK_SIZE - 1)) + req.dirtied_page = 1; + + req.dirtied_ino = 1; + /* A funny way to budget for truncation node */ + req.dirtied_ino_d = UBIFS_TRUN_NODE_SZ; + err = ubifs_budget_space(c, &req); + if (err) + return err; + + err = vmtruncate(inode, new_size); + if (err) + goto out_budg; + + if (offset) { + pgoff_t index = new_size >> PAGE_CACHE_SHIFT; + struct page *page; + + page = find_lock_page(inode->i_mapping, index); + if (page) { + if (PageDirty(page)) { + /* + * 'ubifs_jnl_truncate()' will try to truncate + * the last data node, but it contains + * out-of-date data because the page is dirty. + * Write the page now, so that + * 'ubifs_jnl_truncate()' will see an already + * truncated (and up to date) data node. + */ + ubifs_assert(PagePrivate(page)); + + clear_page_dirty_for_io(page); + if (UBIFS_BLOCKS_PER_PAGE_SHIFT) + offset = new_size & + (PAGE_CACHE_SIZE - 1); + err = do_writepage(page, offset); + page_cache_release(page); + if (err) + goto out_budg; + /* + * We could now tell 'ubifs_jnl_truncate()' not + * to read the last block. + */ + } else { + /* + * We could 'kmap()' the page and pass the data + * to 'ubifs_jnl_truncate()' to save it from + * having to read it. + */ + unlock_page(page); + page_cache_release(page); + } + } + } + + mutex_lock(&ui->ui_mutex); + ui->ui_size = inode->i_size; + /* Truncation changes inode [mc]time */ + inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); + /* The other attributes may be changed at the same time as well */ + do_attr_changes(inode, attr); + + err = ubifs_jnl_truncate(c, inode, old_size, new_size); + mutex_unlock(&ui->ui_mutex); +out_budg: + ubifs_release_budget(c, &req); + return err; +} + +/** + * do_setattr - change inode attributes. + * @c: UBIFS file-system description object + * @inode: inode to change attributes for + * @attr: inode attribute changes description + * + * This function implements VFS '->setattr()' call for all cases except + * truncations to smaller size. Returns zero in case of success and a negative + * error code in case of failure. + */ +static int do_setattr(struct ubifs_info *c, struct inode *inode, + const struct iattr *attr) +{ + int err, release; + loff_t new_size = attr->ia_size; + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_budget_req req = { .dirtied_ino = 1, + .dirtied_ino_d = ui->data_len }; + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + if (attr->ia_valid & ATTR_SIZE) { + dbg_gen("size %lld -> %lld", inode->i_size, new_size); + err = vmtruncate(inode, new_size); + if (err) + goto out; + } + + mutex_lock(&ui->ui_mutex); + if (attr->ia_valid & ATTR_SIZE) { + /* Truncation changes inode [mc]time */ + inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); + /* 'vmtruncate()' changed @i_size, update @ui_size */ + ui->ui_size = inode->i_size; + } + + do_attr_changes(inode, attr); + + release = ui->dirty; + if (attr->ia_valid & ATTR_SIZE) + /* + * Inode length changed, so we have to make sure + * @I_DIRTY_DATASYNC is set. + */ + __mark_inode_dirty(inode, I_DIRTY_SYNC | I_DIRTY_DATASYNC); + else + mark_inode_dirty_sync(inode); + mutex_unlock(&ui->ui_mutex); + + if (release) + ubifs_release_budget(c, &req); + if (IS_SYNC(inode)) + err = inode->i_sb->s_op->write_inode(inode, 1); + return err; + +out: + ubifs_release_budget(c, &req); + return err; +} + +int ubifs_setattr(struct dentry *dentry, struct iattr *attr) +{ + int err; + struct inode *inode = dentry->d_inode; + struct ubifs_info *c = inode->i_sb->s_fs_info; + + dbg_gen("ino %lu, ia_valid %#x", inode->i_ino, attr->ia_valid); + err = inode_change_ok(inode, attr); + if (err) + return err; + + err = dbg_check_synced_i_size(inode); + if (err) + return err; + + if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size < inode->i_size) + /* Truncation to a smaller size */ + err = do_truncation(c, inode, attr); + else + err = do_setattr(c, inode, attr); + + return err; +} + +static void ubifs_invalidatepage(struct page *page, unsigned long offset) +{ + struct inode *inode = page->mapping->host; + struct ubifs_info *c = inode->i_sb->s_fs_info; + + ubifs_assert(PagePrivate(page)); + if (offset) + /* Partial page remains dirty */ + return; + + if (PageChecked(page)) + release_new_page_budget(c); + else + release_existing_page_budget(c); + + atomic_long_dec(&c->dirty_pg_cnt); + ClearPagePrivate(page); + ClearPageChecked(page); +} + +static void *ubifs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + struct ubifs_inode *ui = ubifs_inode(dentry->d_inode); + + nd_set_link(nd, ui->data); + return NULL; +} + +int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + struct inode *inode = dentry->d_inode; + struct ubifs_info *c = inode->i_sb->s_fs_info; + int err; + + dbg_gen("syncing inode %lu", inode->i_ino); + + /* + * VFS has already synchronized dirty pages for this inode. Synchronize + * the inode unless this is a 'datasync()' call. + */ + if (!datasync || (inode->i_state & I_DIRTY_DATASYNC)) { + err = inode->i_sb->s_op->write_inode(inode, 1); + if (err) + return err; + } + + /* + * Nodes related to this inode may still sit in a write-buffer. Flush + * them. + */ + err = ubifs_sync_wbufs_by_inode(c, inode); + if (err) + return err; + + return 0; +} + +/** + * mctime_update_needed - check if mtime or ctime update is needed. + * @inode: the inode to do the check for + * @now: current time + * + * This helper function checks if the inode mtime/ctime should be updated or + * not. If current values of the time-stamps are within the UBIFS inode time + * granularity, they are not updated. This is an optimization. + */ +static inline int mctime_update_needed(const struct inode *inode, + const struct timespec *now) +{ + if (!timespec_equal(&inode->i_mtime, now) || + !timespec_equal(&inode->i_ctime, now)) + return 1; + return 0; +} + +/** + * update_ctime - update mtime and ctime of an inode. + * @c: UBIFS file-system description object + * @inode: inode to update + * + * This function updates mtime and ctime of the inode if it is not equivalent to + * current time. Returns zero in case of success and a negative error code in + * case of failure. + */ +static int update_mctime(struct ubifs_info *c, struct inode *inode) +{ + struct timespec now = ubifs_current_time(inode); + struct ubifs_inode *ui = ubifs_inode(inode); + + if (mctime_update_needed(inode, &now)) { + int err, release; + struct ubifs_budget_req req = { .dirtied_ino = 1, + .dirtied_ino_d = ui->data_len }; + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + mutex_lock(&ui->ui_mutex); + inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); + release = ui->dirty; + mark_inode_dirty_sync(inode); + mutex_unlock(&ui->ui_mutex); + if (release) + ubifs_release_budget(c, &req); + } + + return 0; +} + +static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + int err; + ssize_t ret; + struct inode *inode = iocb->ki_filp->f_mapping->host; + struct ubifs_info *c = inode->i_sb->s_fs_info; + + err = update_mctime(c, inode); + if (err) + return err; + + ret = generic_file_aio_write(iocb, iov, nr_segs, pos); + if (ret < 0) + return ret; + + if (ret > 0 && (IS_SYNC(inode) || iocb->ki_filp->f_flags & O_SYNC)) { + err = ubifs_sync_wbufs_by_inode(c, inode); + if (err) + return err; + } + + return ret; +} + +static int ubifs_set_page_dirty(struct page *page) +{ + int ret; + + ret = __set_page_dirty_nobuffers(page); + /* + * An attempt to dirty a page without budgeting for it - should not + * happen. + */ + ubifs_assert(ret == 0); + return ret; +} + +static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags) +{ + /* + * An attempt to release a dirty page without budgeting for it - should + * not happen. + */ + if (PageWriteback(page)) + return 0; + ubifs_assert(PagePrivate(page)); + ubifs_assert(0); + ClearPagePrivate(page); + ClearPageChecked(page); + return 1; +} + +/* + * mmap()d file has taken write protection fault and is being made + * writable. UBIFS must ensure page is budgeted for. + */ +static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) +{ + struct inode *inode = vma->vm_file->f_path.dentry->d_inode; + struct ubifs_info *c = inode->i_sb->s_fs_info; + struct timespec now = ubifs_current_time(inode); + struct ubifs_budget_req req = { .new_page = 1 }; + int err, update_time; + + dbg_gen("ino %lu, pg %lu, i_size %lld", inode->i_ino, page->index, + i_size_read(inode)); + ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY)); + + if (unlikely(c->ro_media)) + return -EROFS; + + /* + * We have not locked @page so far so we may budget for changing the + * page. Note, we cannot do this after we locked the page, because + * budgeting may cause write-back which would cause deadlock. + * + * At the moment we do not know whether the page is dirty or not, so we + * assume that it is not and budget for a new page. We could look at + * the @PG_private flag and figure this out, but we may race with write + * back and the page state may change by the time we lock it, so this + * would need additional care. We do not bother with this at the + * moment, although it might be good idea to do. Instead, we allocate + * budget for a new page and amend it later on if the page was in fact + * dirty. + * + * The budgeting-related logic of this function is similar to what we + * do in 'ubifs_write_begin()' and 'ubifs_write_end()'. Glance there + * for more comments. + */ + update_time = mctime_update_needed(inode, &now); + if (update_time) + /* + * We have to change inode time stamp which requires extra + * budgeting. + */ + req.dirtied_ino = 1; + + err = ubifs_budget_space(c, &req); + if (unlikely(err)) { + if (err == -ENOSPC) + ubifs_warn("out of space for mmapped file " + "(inode number %lu)", inode->i_ino); + return err; + } + + lock_page(page); + if (unlikely(page->mapping != inode->i_mapping || + page_offset(page) > i_size_read(inode))) { + /* Page got truncated out from underneath us */ + err = -EINVAL; + goto out_unlock; + } + + if (PagePrivate(page)) + release_new_page_budget(c); + else { + if (!PageChecked(page)) + ubifs_convert_page_budget(c); + SetPagePrivate(page); + atomic_long_inc(&c->dirty_pg_cnt); + __set_page_dirty_nobuffers(page); + } + + if (update_time) { + int release; + struct ubifs_inode *ui = ubifs_inode(inode); + + mutex_lock(&ui->ui_mutex); + inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); + release = ui->dirty; + mark_inode_dirty_sync(inode); + mutex_unlock(&ui->ui_mutex); + if (release) + ubifs_release_dirty_inode_budget(c, ui); + } + + unlock_page(page); + return 0; + +out_unlock: + unlock_page(page); + ubifs_release_budget(c, &req); + return err; +} + +static struct vm_operations_struct ubifs_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = ubifs_vm_page_mkwrite, +}; + +static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err; + + /* 'generic_file_mmap()' takes care of NOMMU case */ + err = generic_file_mmap(file, vma); + if (err) + return err; + vma->vm_ops = &ubifs_file_vm_ops; + return 0; +} + +struct address_space_operations ubifs_file_address_operations = { + .readpage = ubifs_readpage, + .writepage = ubifs_writepage, + .write_begin = ubifs_write_begin, + .write_end = ubifs_write_end, + .invalidatepage = ubifs_invalidatepage, + .set_page_dirty = ubifs_set_page_dirty, + .releasepage = ubifs_releasepage, +}; + +struct inode_operations ubifs_file_inode_operations = { + .setattr = ubifs_setattr, + .getattr = ubifs_getattr, +#ifdef CONFIG_UBIFS_FS_XATTR + .setxattr = ubifs_setxattr, + .getxattr = ubifs_getxattr, + .listxattr = ubifs_listxattr, + .removexattr = ubifs_removexattr, +#endif +}; + +struct inode_operations ubifs_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = ubifs_follow_link, + .setattr = ubifs_setattr, + .getattr = ubifs_getattr, +}; + +struct file_operations ubifs_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = generic_file_aio_read, + .aio_write = ubifs_aio_write, + .mmap = ubifs_file_mmap, + .fsync = ubifs_fsync, + .unlocked_ioctl = ubifs_ioctl, + .splice_read = generic_file_splice_read, +#ifdef CONFIG_COMPAT + .compat_ioctl = ubifs_compat_ioctl, +#endif +}; diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c new file mode 100644 index 0000000..10394c5 --- /dev/null +++ b/fs/ubifs/find.c @@ -0,0 +1,975 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file contains functions for finding LEBs for various purposes e.g. + * garbage collection. In general, lprops category heaps and lists are used + * for fast access, falling back on scanning the LPT as a last resort. + */ + +#include +#include "ubifs.h" + +/** + * struct scan_data - data provided to scan callback functions + * @min_space: minimum number of bytes for which to scan + * @pick_free: whether it is OK to scan for empty LEBs + * @lnum: LEB number found is returned here + * @exclude_index: whether to exclude index LEBs + */ +struct scan_data { + int min_space; + int pick_free; + int lnum; + int exclude_index; +}; + +/** + * valuable - determine whether LEB properties are valuable. + * @c: the UBIFS file-system description object + * @lprops: LEB properties + * + * This function return %1 if the LEB properties should be added to the LEB + * properties tree in memory. Otherwise %0 is returned. + */ +static int valuable(struct ubifs_info *c, const struct ubifs_lprops *lprops) +{ + int n, cat = lprops->flags & LPROPS_CAT_MASK; + struct ubifs_lpt_heap *heap; + + switch (cat) { + case LPROPS_DIRTY: + case LPROPS_DIRTY_IDX: + case LPROPS_FREE: + heap = &c->lpt_heap[cat - 1]; + if (heap->cnt < heap->max_cnt) + return 1; + if (lprops->free + lprops->dirty >= c->dark_wm) + return 1; + return 0; + case LPROPS_EMPTY: + n = c->lst.empty_lebs + c->freeable_cnt - + c->lst.taken_empty_lebs; + if (n < c->lsave_cnt) + return 1; + return 0; + case LPROPS_FREEABLE: + return 1; + case LPROPS_FRDI_IDX: + return 1; + } + return 0; +} + +/** + * scan_for_dirty_cb - dirty space scan callback. + * @c: the UBIFS file-system description object + * @lprops: LEB properties to scan + * @in_tree: whether the LEB properties are in main memory + * @data: information passed to and from the caller of the scan + * + * This function returns a code that indicates whether the scan should continue + * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree + * in main memory (%LPT_SCAN_ADD), or whether the scan should stop + * (%LPT_SCAN_STOP). + */ +static int scan_for_dirty_cb(struct ubifs_info *c, + const struct ubifs_lprops *lprops, int in_tree, + struct scan_data *data) +{ + int ret = LPT_SCAN_CONTINUE; + + /* Exclude LEBs that are currently in use */ + if (lprops->flags & LPROPS_TAKEN) + return LPT_SCAN_CONTINUE; + /* Determine whether to add these LEB properties to the tree */ + if (!in_tree && valuable(c, lprops)) + ret |= LPT_SCAN_ADD; + /* Exclude LEBs with too little space */ + if (lprops->free + lprops->dirty < data->min_space) + return ret; + /* If specified, exclude index LEBs */ + if (data->exclude_index && lprops->flags & LPROPS_INDEX) + return ret; + /* If specified, exclude empty or freeable LEBs */ + if (lprops->free + lprops->dirty == c->leb_size) { + if (!data->pick_free) + return ret; + /* Exclude LEBs with too little dirty space (unless it is empty) */ + } else if (lprops->dirty < c->dead_wm) + return ret; + /* Finally we found space */ + data->lnum = lprops->lnum; + return LPT_SCAN_ADD | LPT_SCAN_STOP; +} + +/** + * scan_for_dirty - find a data LEB with free space. + * @c: the UBIFS file-system description object + * @min_space: minimum amount free plus dirty space the returned LEB has to + * have + * @pick_free: if it is OK to return a free or freeable LEB + * @exclude_index: whether to exclude index LEBs + * + * This function returns a pointer to the LEB properties found or a negative + * error code. + */ +static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c, + int min_space, int pick_free, + int exclude_index) +{ + const struct ubifs_lprops *lprops; + struct ubifs_lpt_heap *heap; + struct scan_data data; + int err, i; + + /* There may be an LEB with enough dirty space on the free heap */ + heap = &c->lpt_heap[LPROPS_FREE - 1]; + for (i = 0; i < heap->cnt; i++) { + lprops = heap->arr[i]; + if (lprops->free + lprops->dirty < min_space) + continue; + if (lprops->dirty < c->dead_wm) + continue; + return lprops; + } + /* + * A LEB may have fallen off of the bottom of the dirty heap, and ended + * up as uncategorized even though it has enough dirty space for us now, + * so check the uncategorized list. N.B. neither empty nor freeable LEBs + * can end up as uncategorized because they are kept on lists not + * finite-sized heaps. + */ + list_for_each_entry(lprops, &c->uncat_list, list) { + if (lprops->flags & LPROPS_TAKEN) + continue; + if (lprops->free + lprops->dirty < min_space) + continue; + if (exclude_index && (lprops->flags & LPROPS_INDEX)) + continue; + if (lprops->dirty < c->dead_wm) + continue; + return lprops; + } + /* We have looked everywhere in main memory, now scan the flash */ + if (c->pnodes_have >= c->pnode_cnt) + /* All pnodes are in memory, so skip scan */ + return ERR_PTR(-ENOSPC); + data.min_space = min_space; + data.pick_free = pick_free; + data.lnum = -1; + data.exclude_index = exclude_index; + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, + (ubifs_lpt_scan_callback)scan_for_dirty_cb, + &data); + if (err) + return ERR_PTR(err); + ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); + c->lscan_lnum = data.lnum; + lprops = ubifs_lpt_lookup_dirty(c, data.lnum); + if (IS_ERR(lprops)) + return lprops; + ubifs_assert(lprops->lnum == data.lnum); + ubifs_assert(lprops->free + lprops->dirty >= min_space); + ubifs_assert(lprops->dirty >= c->dead_wm || + (pick_free && + lprops->free + lprops->dirty == c->leb_size)); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert(!exclude_index || !(lprops->flags & LPROPS_INDEX)); + return lprops; +} + +/** + * ubifs_find_dirty_leb - find a dirty LEB for the Garbage Collector. + * @c: the UBIFS file-system description object + * @ret_lp: LEB properties are returned here on exit + * @min_space: minimum amount free plus dirty space the returned LEB has to + * have + * @pick_free: controls whether it is OK to pick empty or index LEBs + * + * This function tries to find a dirty logical eraseblock which has at least + * @min_space free and dirty space. It prefers to take an LEB from the dirty or + * dirty index heap, and it falls-back to LPT scanning if the heaps are empty + * or do not have an LEB which satisfies the @min_space criteria. + * + * Note: + * o LEBs which have less than dead watermark of dirty space are never picked + * by this function; + * + * Returns zero and the LEB properties of + * found dirty LEB in case of success, %-ENOSPC if no dirty LEB was found and a + * negative error code in case of other failures. The returned LEB is marked as + * "taken". + * + * The additional @pick_free argument controls if this function has to return a + * free or freeable LEB if one is present. For example, GC must to set it to %1, + * when called from the journal space reservation function, because the + * appearance of free space may coincide with the loss of enough dirty space + * for GC to succeed anyway. + * + * In contrast, if the Garbage Collector is called from budgeting, it should + * just make free space, not return LEBs which are already free or freeable. + * + * In addition @pick_free is set to %2 by the recovery process in order to + * recover gc_lnum in which case an index LEB must not be returned. + */ +int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, + int min_space, int pick_free) +{ + int err = 0, sum, exclude_index = pick_free == 2 ? 1 : 0; + const struct ubifs_lprops *lp = NULL, *idx_lp = NULL; + struct ubifs_lpt_heap *heap, *idx_heap; + + ubifs_get_lprops(c); + + if (pick_free) { + int lebs, rsvd_idx_lebs = 0; + + spin_lock(&c->space_lock); + lebs = c->lst.empty_lebs; + lebs += c->freeable_cnt - c->lst.taken_empty_lebs; + + /* + * Note, the index may consume more LEBs than have been reserved + * for it. It is OK because it might be consolidated by GC. + * But if the index takes fewer LEBs than it is reserved for it, + * this function must avoid picking those reserved LEBs. + */ + if (c->min_idx_lebs >= c->lst.idx_lebs) { + rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs; + exclude_index = 1; + } + spin_unlock(&c->space_lock); + + /* Check if there are enough free LEBs for the index */ + if (rsvd_idx_lebs < lebs) { + /* OK, try to find an empty LEB */ + lp = ubifs_fast_find_empty(c); + if (lp) + goto found; + + /* Or a freeable LEB */ + lp = ubifs_fast_find_freeable(c); + if (lp) + goto found; + } else + /* + * We cannot pick free/freeable LEBs in the below code. + */ + pick_free = 0; + } else { + spin_lock(&c->space_lock); + exclude_index = (c->min_idx_lebs >= c->lst.idx_lebs); + spin_unlock(&c->space_lock); + } + + /* Look on the dirty and dirty index heaps */ + heap = &c->lpt_heap[LPROPS_DIRTY - 1]; + idx_heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1]; + + if (idx_heap->cnt && !exclude_index) { + idx_lp = idx_heap->arr[0]; + sum = idx_lp->free + idx_lp->dirty; + /* + * Since we reserve twice as more space for the index than it + * actually takes, it does not make sense to pick indexing LEBs + * with less than half LEB of dirty space. + */ + if (sum < min_space || sum < c->half_leb_size) + idx_lp = NULL; + } + + if (heap->cnt) { + lp = heap->arr[0]; + if (lp->dirty + lp->free < min_space) + lp = NULL; + } + + /* Pick the LEB with most space */ + if (idx_lp && lp) { + if (idx_lp->free + idx_lp->dirty >= lp->free + lp->dirty) + lp = idx_lp; + } else if (idx_lp && !lp) + lp = idx_lp; + + if (lp) { + ubifs_assert(lp->dirty >= c->dead_wm); + goto found; + } + + /* Did not find a dirty LEB on the dirty heaps, have to scan */ + dbg_find("scanning LPT for a dirty LEB"); + lp = scan_for_dirty(c, min_space, pick_free, exclude_index); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + ubifs_assert(lp->dirty >= c->dead_wm || + (pick_free && lp->free + lp->dirty == c->leb_size)); + +found: + dbg_find("found LEB %d, free %d, dirty %d, flags %#x", + lp->lnum, lp->free, lp->dirty, lp->flags); + + lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC, + lp->flags | LPROPS_TAKEN, 0); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + + memcpy(ret_lp, lp, sizeof(struct ubifs_lprops)); + +out: + ubifs_release_lprops(c); + return err; +} + +/** + * scan_for_free_cb - free space scan callback. + * @c: the UBIFS file-system description object + * @lprops: LEB properties to scan + * @in_tree: whether the LEB properties are in main memory + * @data: information passed to and from the caller of the scan + * + * This function returns a code that indicates whether the scan should continue + * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree + * in main memory (%LPT_SCAN_ADD), or whether the scan should stop + * (%LPT_SCAN_STOP). + */ +static int scan_for_free_cb(struct ubifs_info *c, + const struct ubifs_lprops *lprops, int in_tree, + struct scan_data *data) +{ + int ret = LPT_SCAN_CONTINUE; + + /* Exclude LEBs that are currently in use */ + if (lprops->flags & LPROPS_TAKEN) + return LPT_SCAN_CONTINUE; + /* Determine whether to add these LEB properties to the tree */ + if (!in_tree && valuable(c, lprops)) + ret |= LPT_SCAN_ADD; + /* Exclude index LEBs */ + if (lprops->flags & LPROPS_INDEX) + return ret; + /* Exclude LEBs with too little space */ + if (lprops->free < data->min_space) + return ret; + /* If specified, exclude empty LEBs */ + if (!data->pick_free && lprops->free == c->leb_size) + return ret; + /* + * LEBs that have only free and dirty space must not be allocated + * because they may have been unmapped already or they may have data + * that is obsolete only because of nodes that are still sitting in a + * wbuf. + */ + if (lprops->free + lprops->dirty == c->leb_size && lprops->dirty > 0) + return ret; + /* Finally we found space */ + data->lnum = lprops->lnum; + return LPT_SCAN_ADD | LPT_SCAN_STOP; +} + +/** + * do_find_free_space - find a data LEB with free space. + * @c: the UBIFS file-system description object + * @min_space: minimum amount of free space required + * @pick_free: whether it is OK to scan for empty LEBs + * @squeeze: whether to try to find space in a non-empty LEB first + * + * This function returns a pointer to the LEB properties found or a negative + * error code. + */ +static +const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c, + int min_space, int pick_free, + int squeeze) +{ + const struct ubifs_lprops *lprops; + struct ubifs_lpt_heap *heap; + struct scan_data data; + int err, i; + + if (squeeze) { + lprops = ubifs_fast_find_free(c); + if (lprops && lprops->free >= min_space) + return lprops; + } + if (pick_free) { + lprops = ubifs_fast_find_empty(c); + if (lprops) + return lprops; + } + if (!squeeze) { + lprops = ubifs_fast_find_free(c); + if (lprops && lprops->free >= min_space) + return lprops; + } + /* There may be an LEB with enough free space on the dirty heap */ + heap = &c->lpt_heap[LPROPS_DIRTY - 1]; + for (i = 0; i < heap->cnt; i++) { + lprops = heap->arr[i]; + if (lprops->free >= min_space) + return lprops; + } + /* + * A LEB may have fallen off of the bottom of the free heap, and ended + * up as uncategorized even though it has enough free space for us now, + * so check the uncategorized list. N.B. neither empty nor freeable LEBs + * can end up as uncategorized because they are kept on lists not + * finite-sized heaps. + */ + list_for_each_entry(lprops, &c->uncat_list, list) { + if (lprops->flags & LPROPS_TAKEN) + continue; + if (lprops->flags & LPROPS_INDEX) + continue; + if (lprops->free >= min_space) + return lprops; + } + /* We have looked everywhere in main memory, now scan the flash */ + if (c->pnodes_have >= c->pnode_cnt) + /* All pnodes are in memory, so skip scan */ + return ERR_PTR(-ENOSPC); + data.min_space = min_space; + data.pick_free = pick_free; + data.lnum = -1; + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, + (ubifs_lpt_scan_callback)scan_for_free_cb, + &data); + if (err) + return ERR_PTR(err); + ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); + c->lscan_lnum = data.lnum; + lprops = ubifs_lpt_lookup_dirty(c, data.lnum); + if (IS_ERR(lprops)) + return lprops; + ubifs_assert(lprops->lnum == data.lnum); + ubifs_assert(lprops->free >= min_space); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert(!(lprops->flags & LPROPS_INDEX)); + return lprops; +} + +/** + * ubifs_find_free_space - find a data LEB with free space. + * @c: the UBIFS file-system description object + * @min_space: minimum amount of required free space + * @free: contains amount of free space in the LEB on exit + * @squeeze: whether to try to find space in a non-empty LEB first + * + * This function looks for an LEB with at least @min_space bytes of free space. + * It tries to find an empty LEB if possible. If no empty LEBs are available, + * this function searches for a non-empty data LEB. The returned LEB is marked + * as "taken". + * + * This function returns found LEB number in case of success, %-ENOSPC if it + * failed to find a LEB with @min_space bytes of free space and other a negative + * error codes in case of failure. + */ +int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, + int squeeze) +{ + const struct ubifs_lprops *lprops; + int lebs, rsvd_idx_lebs, pick_free = 0, err, lnum, flags; + + dbg_find("min_space %d", min_space); + ubifs_get_lprops(c); + + /* Check if there are enough empty LEBs for commit */ + spin_lock(&c->space_lock); + if (c->min_idx_lebs > c->lst.idx_lebs) + rsvd_idx_lebs = c->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; + ubifs_assert(lebs + c->lst.idx_lebs >= c->min_idx_lebs); + if (rsvd_idx_lebs < lebs) + /* + * OK to allocate an empty LEB, but we still don't want to go + * looking for one if there aren't any. + */ + if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { + pick_free = 1; + /* + * Because we release the space lock, we must account + * for this allocation here. After the LEB properties + * flags have been updated, we subtract one. Note, the + * result of this is that lprops also decreases + * @taken_empty_lebs in 'ubifs_change_lp()', so it is + * off by one for a short period of time which may + * introduce a small disturbance to budgeting + * calculations, but this is harmless because at the + * worst case this would make the budgeting subsystem + * be more pessimistic than needed. + * + * Fundamentally, this is about serialization of the + * budgeting and lprops subsystems. We could make the + * @space_lock a mutex and avoid dropping it before + * calling 'ubifs_change_lp()', but mutex is more + * heavy-weight, and we want budgeting to be as fast as + * possible. + */ + c->lst.taken_empty_lebs += 1; + } + spin_unlock(&c->space_lock); + + lprops = do_find_free_space(c, min_space, pick_free, squeeze); + if (IS_ERR(lprops)) { + err = PTR_ERR(lprops); + goto out; + } + + lnum = lprops->lnum; + flags = lprops->flags | LPROPS_TAKEN; + + lprops = ubifs_change_lp(c, lprops, LPROPS_NC, LPROPS_NC, flags, 0); + if (IS_ERR(lprops)) { + err = PTR_ERR(lprops); + goto out; + } + + if (pick_free) { + spin_lock(&c->space_lock); + c->lst.taken_empty_lebs -= 1; + spin_unlock(&c->space_lock); + } + + *free = lprops->free; + ubifs_release_lprops(c); + + if (*free == c->leb_size) { + /* + * Ensure that empty LEBs have been unmapped. They may not have + * been, for example, because of an unclean unmount. Also + * LEBs that were freeable LEBs (free + dirty == leb_size) will + * not have been unmapped. + */ + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + + dbg_find("found LEB %d, free %d", lnum, *free); + ubifs_assert(*free >= min_space); + return lnum; + +out: + if (pick_free) { + spin_lock(&c->space_lock); + c->lst.taken_empty_lebs -= 1; + spin_unlock(&c->space_lock); + } + ubifs_release_lprops(c); + return err; +} + +/** + * scan_for_idx_cb - callback used by the scan for a free LEB for the index. + * @c: the UBIFS file-system description object + * @lprops: LEB properties to scan + * @in_tree: whether the LEB properties are in main memory + * @data: information passed to and from the caller of the scan + * + * This function returns a code that indicates whether the scan should continue + * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree + * in main memory (%LPT_SCAN_ADD), or whether the scan should stop + * (%LPT_SCAN_STOP). + */ +static int scan_for_idx_cb(struct ubifs_info *c, + const struct ubifs_lprops *lprops, int in_tree, + struct scan_data *data) +{ + int ret = LPT_SCAN_CONTINUE; + + /* Exclude LEBs that are currently in use */ + if (lprops->flags & LPROPS_TAKEN) + return LPT_SCAN_CONTINUE; + /* Determine whether to add these LEB properties to the tree */ + if (!in_tree && valuable(c, lprops)) + ret |= LPT_SCAN_ADD; + /* Exclude index LEBS */ + if (lprops->flags & LPROPS_INDEX) + return ret; + /* Exclude LEBs that cannot be made empty */ + if (lprops->free + lprops->dirty != c->leb_size) + return ret; + /* + * We are allocating for the index so it is safe to allocate LEBs with + * only free and dirty space, because write buffers are sync'd at commit + * start. + */ + data->lnum = lprops->lnum; + return LPT_SCAN_ADD | LPT_SCAN_STOP; +} + +/** + * scan_for_leb_for_idx - scan for a free LEB for the index. + * @c: the UBIFS file-system description object + */ +static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + struct scan_data data; + int err; + + data.lnum = -1; + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, + (ubifs_lpt_scan_callback)scan_for_idx_cb, + &data); + if (err) + return ERR_PTR(err); + ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); + c->lscan_lnum = data.lnum; + lprops = ubifs_lpt_lookup_dirty(c, data.lnum); + if (IS_ERR(lprops)) + return lprops; + ubifs_assert(lprops->lnum == data.lnum); + ubifs_assert(lprops->free + lprops->dirty == c->leb_size); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert(!(lprops->flags & LPROPS_INDEX)); + return lprops; +} + +/** + * ubifs_find_free_leb_for_idx - find a free LEB for the index. + * @c: the UBIFS file-system description object + * + * This function looks for a free LEB and returns that LEB number. The returned + * LEB is marked as "taken", "index". + * + * Only empty LEBs are allocated. This is for two reasons. First, the commit + * calculates the number of LEBs to allocate based on the assumption that they + * will be empty. Secondly, free space at the end of an index LEB is not + * guaranteed to be empty because it may have been used by the in-the-gaps + * method prior to an unclean unmount. + * + * If no LEB is found %-ENOSPC is returned. For other failures another negative + * error code is returned. + */ +int ubifs_find_free_leb_for_idx(struct ubifs_info *c) +{ + const struct ubifs_lprops *lprops; + int lnum = -1, err, flags; + + ubifs_get_lprops(c); + + lprops = ubifs_fast_find_empty(c); + if (!lprops) { + lprops = ubifs_fast_find_freeable(c); + if (!lprops) { + ubifs_assert(c->freeable_cnt == 0); + if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { + lprops = scan_for_leb_for_idx(c); + if (IS_ERR(lprops)) { + err = PTR_ERR(lprops); + goto out; + } + } + } + } + + if (!lprops) { + err = -ENOSPC; + goto out; + } + + lnum = lprops->lnum; + + dbg_find("found LEB %d, free %d, dirty %d, flags %#x", + lnum, lprops->free, lprops->dirty, lprops->flags); + + flags = lprops->flags | LPROPS_TAKEN | LPROPS_INDEX; + lprops = ubifs_change_lp(c, lprops, c->leb_size, 0, flags, 0); + if (IS_ERR(lprops)) { + err = PTR_ERR(lprops); + goto out; + } + + ubifs_release_lprops(c); + + /* + * Ensure that empty LEBs have been unmapped. They may not have been, + * for example, because of an unclean unmount. Also LEBs that were + * freeable LEBs (free + dirty == leb_size) will not have been unmapped. + */ + err = ubifs_leb_unmap(c, lnum); + if (err) { + ubifs_change_one_lp(c, lnum, LPROPS_NC, LPROPS_NC, 0, + LPROPS_TAKEN | LPROPS_INDEX, 0); + return err; + } + + return lnum; + +out: + ubifs_release_lprops(c); + return err; +} + +static int cmp_dirty_idx(const struct ubifs_lprops **a, + const struct ubifs_lprops **b) +{ + const struct ubifs_lprops *lpa = *a; + const struct ubifs_lprops *lpb = *b; + + return lpa->dirty + lpa->free - lpb->dirty - lpb->free; +} + +static void swap_dirty_idx(struct ubifs_lprops **a, struct ubifs_lprops **b, + int size) +{ + struct ubifs_lprops *t = *a; + + *a = *b; + *b = t; +} + +/** + * ubifs_save_dirty_idx_lnums - save an array of the most dirty index LEB nos. + * @c: the UBIFS file-system description object + * + * This function is called each commit to create an array of LEB numbers of + * dirty index LEBs sorted in order of dirty and free space. This is used by + * the in-the-gaps method of TNC commit. + */ +int ubifs_save_dirty_idx_lnums(struct ubifs_info *c) +{ + int i; + + ubifs_get_lprops(c); + /* Copy the LPROPS_DIRTY_IDX heap */ + c->dirty_idx.cnt = c->lpt_heap[LPROPS_DIRTY_IDX - 1].cnt; + memcpy(c->dirty_idx.arr, c->lpt_heap[LPROPS_DIRTY_IDX - 1].arr, + sizeof(void *) * c->dirty_idx.cnt); + /* Sort it so that the dirtiest is now at the end */ + sort(c->dirty_idx.arr, c->dirty_idx.cnt, sizeof(void *), + (int (*)(const void *, const void *))cmp_dirty_idx, + (void (*)(void *, void *, int))swap_dirty_idx); + dbg_find("found %d dirty index LEBs", c->dirty_idx.cnt); + if (c->dirty_idx.cnt) + dbg_find("dirtiest index LEB is %d with dirty %d and free %d", + c->dirty_idx.arr[c->dirty_idx.cnt - 1]->lnum, + c->dirty_idx.arr[c->dirty_idx.cnt - 1]->dirty, + c->dirty_idx.arr[c->dirty_idx.cnt - 1]->free); + /* Replace the lprops pointers with LEB numbers */ + for (i = 0; i < c->dirty_idx.cnt; i++) + c->dirty_idx.arr[i] = (void *)(size_t)c->dirty_idx.arr[i]->lnum; + ubifs_release_lprops(c); + return 0; +} + +/** + * scan_dirty_idx_cb - callback used by the scan for a dirty index LEB. + * @c: the UBIFS file-system description object + * @lprops: LEB properties to scan + * @in_tree: whether the LEB properties are in main memory + * @data: information passed to and from the caller of the scan + * + * This function returns a code that indicates whether the scan should continue + * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree + * in main memory (%LPT_SCAN_ADD), or whether the scan should stop + * (%LPT_SCAN_STOP). + */ +static int scan_dirty_idx_cb(struct ubifs_info *c, + const struct ubifs_lprops *lprops, int in_tree, + struct scan_data *data) +{ + int ret = LPT_SCAN_CONTINUE; + + /* Exclude LEBs that are currently in use */ + if (lprops->flags & LPROPS_TAKEN) + return LPT_SCAN_CONTINUE; + /* Determine whether to add these LEB properties to the tree */ + if (!in_tree && valuable(c, lprops)) + ret |= LPT_SCAN_ADD; + /* Exclude non-index LEBs */ + if (!(lprops->flags & LPROPS_INDEX)) + return ret; + /* Exclude LEBs with too little space */ + if (lprops->free + lprops->dirty < c->min_idx_node_sz) + return ret; + /* Finally we found space */ + data->lnum = lprops->lnum; + return LPT_SCAN_ADD | LPT_SCAN_STOP; +} + +/** + * find_dirty_idx_leb - find a dirty index LEB. + * @c: the UBIFS file-system description object + * + * This function returns LEB number upon success and a negative error code upon + * failure. In particular, -ENOSPC is returned if a dirty index LEB is not + * found. + * + * Note that this function scans the entire LPT but it is called very rarely. + */ +static int find_dirty_idx_leb(struct ubifs_info *c) +{ + const struct ubifs_lprops *lprops; + struct ubifs_lpt_heap *heap; + struct scan_data data; + int err, i, ret; + + /* Check all structures in memory first */ + data.lnum = -1; + heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1]; + for (i = 0; i < heap->cnt; i++) { + lprops = heap->arr[i]; + ret = scan_dirty_idx_cb(c, lprops, 1, &data); + if (ret & LPT_SCAN_STOP) + goto found; + } + list_for_each_entry(lprops, &c->frdi_idx_list, list) { + ret = scan_dirty_idx_cb(c, lprops, 1, &data); + if (ret & LPT_SCAN_STOP) + goto found; + } + list_for_each_entry(lprops, &c->uncat_list, list) { + ret = scan_dirty_idx_cb(c, lprops, 1, &data); + if (ret & LPT_SCAN_STOP) + goto found; + } + if (c->pnodes_have >= c->pnode_cnt) + /* All pnodes are in memory, so skip scan */ + return -ENOSPC; + err = ubifs_lpt_scan_nolock(c, -1, c->lscan_lnum, + (ubifs_lpt_scan_callback)scan_dirty_idx_cb, + &data); + if (err) + return err; +found: + ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); + c->lscan_lnum = data.lnum; + lprops = ubifs_lpt_lookup_dirty(c, data.lnum); + if (IS_ERR(lprops)) + return PTR_ERR(lprops); + ubifs_assert(lprops->lnum == data.lnum); + ubifs_assert(lprops->free + lprops->dirty >= c->min_idx_node_sz); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert((lprops->flags & LPROPS_INDEX)); + + dbg_find("found dirty LEB %d, free %d, dirty %d, flags %#x", + lprops->lnum, lprops->free, lprops->dirty, lprops->flags); + + lprops = ubifs_change_lp(c, lprops, LPROPS_NC, LPROPS_NC, + lprops->flags | LPROPS_TAKEN, 0); + if (IS_ERR(lprops)) + return PTR_ERR(lprops); + + return lprops->lnum; +} + +/** + * get_idx_gc_leb - try to get a LEB number from trivial GC. + * @c: the UBIFS file-system description object + */ +static int get_idx_gc_leb(struct ubifs_info *c) +{ + const struct ubifs_lprops *lp; + int err, lnum; + + err = ubifs_get_idx_gc_leb(c); + if (err < 0) + return err; + lnum = err; + /* + * The LEB was due to be unmapped after the commit but + * it is needed now for this commit. + */ + lp = ubifs_lpt_lookup_dirty(c, lnum); + if (unlikely(IS_ERR(lp))) + return PTR_ERR(lp); + lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC, + lp->flags | LPROPS_INDEX, -1); + if (unlikely(IS_ERR(lp))) + return PTR_ERR(lp); + dbg_find("LEB %d, dirty %d and free %d flags %#x", + lp->lnum, lp->dirty, lp->free, lp->flags); + return lnum; +} + +/** + * find_dirtiest_idx_leb - find dirtiest index LEB from dirtiest array. + * @c: the UBIFS file-system description object + */ +static int find_dirtiest_idx_leb(struct ubifs_info *c) +{ + const struct ubifs_lprops *lp; + int lnum; + + while (1) { + if (!c->dirty_idx.cnt) + return -ENOSPC; + /* The lprops pointers were replaced by LEB numbers */ + lnum = (size_t)c->dirty_idx.arr[--c->dirty_idx.cnt]; + lp = ubifs_lpt_lookup(c, lnum); + if (IS_ERR(lp)) + return PTR_ERR(lp); + if ((lp->flags & LPROPS_TAKEN) || !(lp->flags & LPROPS_INDEX)) + continue; + lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC, + lp->flags | LPROPS_TAKEN, 0); + if (IS_ERR(lp)) + return PTR_ERR(lp); + break; + } + dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty, + lp->free, lp->flags); + ubifs_assert(lp->flags | LPROPS_TAKEN); + ubifs_assert(lp->flags | LPROPS_INDEX); + return lnum; +} + +/** + * ubifs_find_dirty_idx_leb - try to find dirtiest index LEB as at last commit. + * @c: the UBIFS file-system description object + * + * This function attempts to find an untaken index LEB with the most free and + * dirty space that can be used without overwriting index nodes that were in the + * last index committed. + */ +int ubifs_find_dirty_idx_leb(struct ubifs_info *c) +{ + int err; + + ubifs_get_lprops(c); + + /* + * We made an array of the dirtiest index LEB numbers as at the start of + * last commit. Try that array first. + */ + err = find_dirtiest_idx_leb(c); + + /* Next try scanning the entire LPT */ + if (err == -ENOSPC) + err = find_dirty_idx_leb(c); + + /* Finally take any index LEBs awaiting trivial GC */ + if (err == -ENOSPC) + err = get_idx_gc_leb(c); + + ubifs_release_lprops(c); + return err; +} diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c new file mode 100644 index 0000000..d0f3dac --- /dev/null +++ b/fs/ubifs/gc.c @@ -0,0 +1,773 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements garbage collection. The procedure for garbage collection + * is different depending on whether a LEB as an index LEB (contains index + * nodes) or not. For non-index LEBs, garbage collection finds a LEB which + * contains a lot of dirty space (obsolete nodes), and copies the non-obsolete + * nodes to the journal, at which point the garbage-collected LEB is free to be + * reused. For index LEBs, garbage collection marks the non-obsolete index nodes + * dirty in the TNC, and after the next commit, the garbage-collected LEB is + * 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. + */ + +#include +#include "ubifs.h" + +/* + * GC tries to optimize the way it fit nodes to available space, and it sorts + * nodes a little. The below constants are watermarks which define "large", + * "medium", and "small" nodes. + */ +#define MEDIUM_NODE_WM (UBIFS_BLOCK_SIZE / 4) +#define SMALL_NODE_WM UBIFS_MAX_DENT_NODE_SZ + +/* + * GC may need to move more then one LEB to make progress. The below constants + * define "soft" and "hard" limits on the number of LEBs the garbage collector + * may move. + */ +#define SOFT_LEBS_LIMIT 4 +#define HARD_LEBS_LIMIT 32 + +/** + * switch_gc_head - switch the garbage collection journal head. + * @c: UBIFS file-system description object + * @buf: buffer to write + * @len: length of the buffer to write + * @lnum: LEB number written is returned here + * @offs: offset written is returned here + * + * This function switch the GC head to the next LEB which is reserved in + * @c->gc_lnum. Returns %0 in case of success, %-EAGAIN if commit is required, + * and other negative error code in case of failures. + */ +static int switch_gc_head(struct ubifs_info *c) +{ + int err, gc_lnum = c->gc_lnum; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + + ubifs_assert(gc_lnum != -1); + dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)", + wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum, + c->leb_size - wbuf->offs - wbuf->used); + + err = ubifs_wbuf_sync_nolock(wbuf); + if (err) + return err; + + /* + * The GC write-buffer was synchronized, we may safely unmap + * 'c->gc_lnum'. + */ + err = ubifs_leb_unmap(c, gc_lnum); + if (err) + return err; + + err = ubifs_add_bud_to_log(c, GCHD, gc_lnum, 0); + if (err) + return err; + + c->gc_lnum = -1; + err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0, UBI_LONGTERM); + return err; +} + +/** + * move_nodes - move nodes. + * @c: UBIFS file-system description object + * @sleb: describes nodes to move + * + * This function moves valid nodes from data LEB described by @sleb to the GC + * journal head. The obsolete nodes are dropped. + * + * When moving nodes we have to deal with classical bin-packing problem: the + * space in the current GC journal head LEB and in @c->gc_lnum are the "bins", + * where the nodes in the @sleb->nodes list are the elements which should be + * fit optimally to the bins. This function uses the "first fit decreasing" + * strategy, although it does not really sort the nodes but just split them on + * 3 classes - large, medium, and small, so they are roughly sorted. + * + * This function returns zero in case of success, %-EAGAIN if commit is + * required, and other negative error codes in case of other failures. + */ +static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) +{ + struct ubifs_scan_node *snod, *tmp; + struct list_head large, medium, small; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + int avail, err, min = INT_MAX; + + INIT_LIST_HEAD(&large); + INIT_LIST_HEAD(&medium); + INIT_LIST_HEAD(&small); + + list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { + struct list_head *lst; + + ubifs_assert(snod->type != UBIFS_IDX_NODE); + ubifs_assert(snod->type != UBIFS_REF_NODE); + ubifs_assert(snod->type != UBIFS_CS_NODE); + + err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum, + snod->offs, 0); + if (err < 0) + goto out; + + lst = &snod->list; + list_del(lst); + if (!err) { + /* The node is obsolete, remove it from the list */ + kfree(snod); + continue; + } + + /* + * Sort the list of nodes so that large nodes go first, and + * small nodes go last. + */ + if (snod->len > MEDIUM_NODE_WM) + list_add(lst, &large); + else if (snod->len > SMALL_NODE_WM) + list_add(lst, &medium); + else + list_add(lst, &small); + + /* And find the smallest node */ + if (snod->len < min) + min = snod->len; + } + + /* + * Join the tree lists so that we'd have one roughly sorted list + * ('large' will be the head of the joined list). + */ + list_splice(&medium, large.prev); + list_splice(&small, large.prev); + + if (wbuf->lnum == -1) { + /* + * The GC journal head is not set, because it is the first GC + * invocation since mount. + */ + err = switch_gc_head(c); + if (err) + goto out; + } + + /* Write nodes to their new location. Use the first-fit strategy */ + while (1) { + avail = c->leb_size - wbuf->offs - wbuf->used; + list_for_each_entry_safe(snod, tmp, &large, list) { + int new_lnum, new_offs; + + if (avail < min) + break; + + if (snod->len > avail) + /* This node does not fit */ + continue; + + cond_resched(); + + new_lnum = wbuf->lnum; + new_offs = wbuf->offs + wbuf->used; + err = ubifs_wbuf_write_nolock(wbuf, snod->node, + snod->len); + if (err) + goto out; + err = ubifs_tnc_replace(c, &snod->key, sleb->lnum, + snod->offs, new_lnum, new_offs, + snod->len); + if (err) + goto out; + + avail = c->leb_size - wbuf->offs - wbuf->used; + list_del(&snod->list); + kfree(snod); + } + + if (list_empty(&large)) + break; + + /* + * Waste the rest of the space in the LEB and switch to the + * next LEB. + */ + err = switch_gc_head(c); + if (err) + goto out; + } + + return 0; + +out: + list_for_each_entry_safe(snod, tmp, &large, list) { + list_del(&snod->list); + kfree(snod); + } + return err; +} + +/** + * gc_sync_wbufs - sync write-buffers for GC. + * @c: UBIFS file-system description object + * + * We must guarantee that obsoleting nodes are on flash. Unfortunately they may + * be in a write-buffer instead. That is, a node could be written to a + * write-buffer, obsoleting another node in a LEB that is GC'd. If that LEB is + * erased before the write-buffer is sync'd and then there is an unclean + * unmount, then an existing node is lost. To avoid this, we sync all + * write-buffers. + * + * This function returns %0 on success or a negative error code on failure. + */ +static int gc_sync_wbufs(struct ubifs_info *c) +{ + int err, i; + + for (i = 0; i < c->jhead_cnt; i++) { + if (i == GCHD) + continue; + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + return err; + } + return 0; +} + +/** + * ubifs_garbage_collect_leb - garbage-collect a logical eraseblock. + * @c: UBIFS file-system description object + * @lp: describes the LEB to garbage collect + * + * This function garbage-collects an LEB and returns one of the @LEB_FREED, + * @LEB_RETAINED, etc positive codes in case of success, %-EAGAIN if commit is + * required, and other negative error codes in case of failures. + */ +int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + int err = 0, lnum = lp->lnum; + + ubifs_assert(c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 || + c->need_recovery); + ubifs_assert(c->gc_lnum != lnum); + ubifs_assert(wbuf->lnum != lnum); + + /* + * We scan the entire LEB even though we only really need to scan up to + * (c->leb_size - lp->free). + */ + sleb = ubifs_scan(c, lnum, 0, c->sbuf); + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + + ubifs_assert(!list_empty(&sleb->nodes)); + snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list); + + if (snod->type == UBIFS_IDX_NODE) { + struct ubifs_gced_idx_leb *idx_gc; + + dbg_gc("indexing LEB %d (free %d, dirty %d)", + lnum, lp->free, lp->dirty); + list_for_each_entry(snod, &sleb->nodes, list) { + struct ubifs_idx_node *idx = snod->node; + int level = le16_to_cpu(idx->level); + + ubifs_assert(snod->type == UBIFS_IDX_NODE); + key_read(c, ubifs_idx_key(c, idx), &snod->key); + err = ubifs_dirty_idx_node(c, &snod->key, level, lnum, + snod->offs); + if (err) + goto out; + } + + idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS); + if (!idx_gc) { + err = -ENOMEM; + goto out; + } + + idx_gc->lnum = lnum; + idx_gc->unmap = 0; + list_add(&idx_gc->list, &c->idx_gc); + + /* + * Don't release the LEB until after the next commit, because + * it may contain date which is needed for recovery. So + * although we freed this LEB, it will become usable only after + * the commit. + */ + err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, + LPROPS_INDEX, 1); + if (err) + goto out; + err = LEB_FREED_IDX; + } else { + dbg_gc("data LEB %d (free %d, dirty %d)", + lnum, lp->free, lp->dirty); + + err = move_nodes(c, sleb); + if (err) + goto out; + + err = gc_sync_wbufs(c); + if (err) + goto out; + + err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0); + if (err) + goto out; + + if (c->gc_lnum == -1) { + c->gc_lnum = lnum; + err = LEB_RETAINED; + } else { + err = ubifs_wbuf_sync_nolock(wbuf); + if (err) + goto out; + + err = ubifs_leb_unmap(c, lnum); + if (err) + goto out; + + err = LEB_FREED; + } + } + +out: + ubifs_scan_destroy(sleb); + return err; +} + +/** + * ubifs_garbage_collect - UBIFS garbage collector. + * @c: UBIFS file-system description object + * @anyway: do GC even if there are free LEBs + * + * This function does out-of-place garbage collection. The return codes are: + * o positive LEB number if the LEB has been freed and may be used; + * o %-EAGAIN if the caller has to run commit; + * o %-ENOSPC if GC failed to make any progress; + * o other negative error codes in case of other errors. + * + * Garbage collector writes data to the journal when GC'ing data LEBs, and just + * marking indexing nodes dirty when GC'ing indexing LEBs. Thus, at some point + * commit may be required. But commit cannot be run from inside GC, because the + * caller might be holding the commit lock, so %-EAGAIN is returned instead; + * And this error code means that the caller has to run commit, and re-run GC + * if there is still no free space. + * + * There are many reasons why this function may return %-EAGAIN: + * o the log is full and there is no space to write an LEB reference for + * @c->gc_lnum; + * o the journal is too large and exceeds size limitations; + * o GC moved indexing LEBs, but they can be used only after the commit; + * o the shrinker fails to find clean znodes to free and requests the commit; + * o etc. + * + * Note, if the file-system is close to be full, this function may return + * %-EAGAIN infinitely, so the caller has to limit amount of re-invocations of + * the function. E.g., this happens if the limits on the journal size are too + * tough and GC writes too much to the journal before an LEB is freed. This + * might also mean that the journal is too large, and the TNC becomes to big, + * so that the shrinker is constantly called, finds not clean znodes to free, + * and requests commit. Well, this may also happen if the journal is all right, + * but another kernel process consumes too much memory. Anyway, infinite + * %-EAGAIN may happen, but in some extreme/misconfiguration cases. + */ +int ubifs_garbage_collect(struct ubifs_info *c, int anyway) +{ + int i, err, ret, min_space = c->dead_wm; + struct ubifs_lprops lp; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + + ubifs_assert_cmt_locked(c); + + if (ubifs_gc_should_commit(c)) + return -EAGAIN; + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + + if (c->ro_media) { + ret = -EROFS; + goto out_unlock; + } + + /* We expect the write-buffer to be empty on entry */ + ubifs_assert(!wbuf->used); + + for (i = 0; ; i++) { + int space_before = c->leb_size - wbuf->offs - wbuf->used; + int space_after; + + cond_resched(); + + /* Give the commit an opportunity to run */ + if (ubifs_gc_should_commit(c)) { + ret = -EAGAIN; + break; + } + + if (i > SOFT_LEBS_LIMIT && !list_empty(&c->idx_gc)) { + /* + * We've done enough iterations. Indexing LEBs were + * moved and will be available after the commit. + */ + dbg_gc("soft limit, some index LEBs GC'ed, -EAGAIN"); + ubifs_commit_required(c); + ret = -EAGAIN; + break; + } + + if (i > HARD_LEBS_LIMIT) { + /* + * We've moved too many LEBs and have not made + * progress, give up. + */ + dbg_gc("hard limit, -ENOSPC"); + ret = -ENOSPC; + break; + } + + /* + * Empty and freeable LEBs can turn up while we waited for + * the wbuf lock, or while we have been running GC. In that + * case, we should just return one of those instead of + * continuing to GC dirty LEBs. Hence we request + * 'ubifs_find_dirty_leb()' to return an empty LEB if it can. + */ + ret = ubifs_find_dirty_leb(c, &lp, min_space, anyway ? 0 : 1); + if (ret) { + if (ret == -ENOSPC) + dbg_gc("no more dirty LEBs"); + break; + } + + dbg_gc("found LEB %d: free %d, dirty %d, sum %d " + "(min. space %d)", lp.lnum, lp.free, lp.dirty, + lp.free + lp.dirty, min_space); + + if (lp.free + lp.dirty == c->leb_size) { + /* An empty LEB was returned */ + dbg_gc("LEB %d is free, return it", lp.lnum); + /* + * ubifs_find_dirty_leb() doesn't return freeable index + * LEBs. + */ + ubifs_assert(!(lp.flags & LPROPS_INDEX)); + if (lp.free != c->leb_size) { + /* + * Write buffers must be sync'd before + * unmapping freeable LEBs, because one of them + * may contain data which obsoletes something + * in 'lp.pnum'. + */ + ret = gc_sync_wbufs(c); + if (ret) + goto out; + ret = ubifs_change_one_lp(c, lp.lnum, + c->leb_size, 0, 0, 0, + 0); + if (ret) + goto out; + } + ret = ubifs_leb_unmap(c, lp.lnum); + if (ret) + goto out; + ret = lp.lnum; + break; + } + + space_before = c->leb_size - wbuf->offs - wbuf->used; + if (wbuf->lnum == -1) + space_before = 0; + + ret = ubifs_garbage_collect_leb(c, &lp); + if (ret < 0) { + if (ret == -EAGAIN || ret == -ENOSPC) { + /* + * These codes are not errors, so we have to + * return the LEB to lprops. But if the + * 'ubifs_return_leb()' function fails, its + * failure code is propagated to the caller + * instead of the original '-EAGAIN' or + * '-ENOSPC'. + */ + err = ubifs_return_leb(c, lp.lnum); + if (err) + ret = err; + break; + } + goto out; + } + + if (ret == LEB_FREED) { + /* An LEB has been freed and is ready for use */ + dbg_gc("LEB %d freed, return", lp.lnum); + ret = lp.lnum; + break; + } + + if (ret == LEB_FREED_IDX) { + /* + * This was an indexing LEB and it cannot be + * immediately used. And instead of requesting the + * commit straight away, we try to garbage collect some + * more. + */ + dbg_gc("indexing LEB %d freed, continue", lp.lnum); + continue; + } + + ubifs_assert(ret == LEB_RETAINED); + space_after = c->leb_size - wbuf->offs - wbuf->used; + dbg_gc("LEB %d retained, freed %d bytes", lp.lnum, + space_after - space_before); + + if (space_after > space_before) { + /* GC makes progress, keep working */ + min_space >>= 1; + if (min_space < c->dead_wm) + min_space = c->dead_wm; + continue; + } + + dbg_gc("did not make progress"); + + /* + * GC moved an LEB bud have not done any progress. This means + * that the previous GC head LEB contained too few free space + * and the LEB which was GC'ed contained only large nodes which + * did not fit that space. + * + * We can do 2 things: + * 1. pick another LEB in a hope it'll contain a small node + * which will fit the space we have at the end of current GC + * head LEB, but there is no guarantee, so we try this out + * unless we have already been working for too long; + * 2. request an LEB with more dirty space, which will force + * 'ubifs_find_dirty_leb()' to start scanning the lprops + * table, instead of just picking one from the heap + * (previously it already picked the dirtiest LEB). + */ + if (i < SOFT_LEBS_LIMIT) { + dbg_gc("try again"); + continue; + } + + min_space <<= 1; + if (min_space > c->dark_wm) + min_space = c->dark_wm; + dbg_gc("set min. space to %d", min_space); + } + + if (ret == -ENOSPC && !list_empty(&c->idx_gc)) { + dbg_gc("no space, some index LEBs GC'ed, -EAGAIN"); + ubifs_commit_required(c); + ret = -EAGAIN; + } + + err = ubifs_wbuf_sync_nolock(wbuf); + if (!err) + err = ubifs_leb_unmap(c, c->gc_lnum); + if (err) { + ret = err; + goto out; + } +out_unlock: + mutex_unlock(&wbuf->io_mutex); + return ret; + +out: + ubifs_assert(ret < 0); + ubifs_assert(ret != -ENOSPC && ret != -EAGAIN); + ubifs_ro_mode(c, ret); + ubifs_wbuf_sync_nolock(wbuf); + mutex_unlock(&wbuf->io_mutex); + ubifs_return_leb(c, lp.lnum); + return ret; +} + +/** + * ubifs_gc_start_commit - garbage collection at start of commit. + * @c: UBIFS file-system description object + * + * If a LEB has only dirty and free space, then we may safely unmap it and make + * it free. Note, we cannot do this with indexing LEBs because dirty space may + * correspond index nodes that are required for recovery. In that case, the + * LEB cannot be unmapped until after the next commit. + * + * This function returns %0 upon success and a negative error code upon failure. + */ +int ubifs_gc_start_commit(struct ubifs_info *c) +{ + struct ubifs_gced_idx_leb *idx_gc; + const struct ubifs_lprops *lp; + int err = 0, flags; + + ubifs_get_lprops(c); + + /* + * Unmap (non-index) freeable LEBs. Note that recovery requires that all + * wbufs are sync'd before this, which is done in 'do_commit()'. + */ + while (1) { + lp = ubifs_fast_find_freeable(c); + if (unlikely(IS_ERR(lp))) { + err = PTR_ERR(lp); + goto out; + } + if (!lp) + break; + ubifs_assert(!(lp->flags & LPROPS_TAKEN)); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + err = ubifs_leb_unmap(c, lp->lnum); + if (err) + goto out; + lp = ubifs_change_lp(c, lp, c->leb_size, 0, lp->flags, 0); + if (unlikely(IS_ERR(lp))) { + err = PTR_ERR(lp); + goto out; + } + ubifs_assert(!(lp->flags & LPROPS_TAKEN)); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + } + + /* Mark GC'd index LEBs OK to unmap after this commit finishes */ + list_for_each_entry(idx_gc, &c->idx_gc, list) + idx_gc->unmap = 1; + + /* Record index freeable LEBs for unmapping after commit */ + while (1) { + lp = ubifs_fast_find_frdi_idx(c); + if (unlikely(IS_ERR(lp))) { + err = PTR_ERR(lp); + goto out; + } + if (!lp) + break; + idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS); + if (!idx_gc) { + err = -ENOMEM; + goto out; + } + ubifs_assert(!(lp->flags & LPROPS_TAKEN)); + ubifs_assert(lp->flags & LPROPS_INDEX); + /* Don't release the LEB until after the next commit */ + flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX; + lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1); + if (unlikely(IS_ERR(lp))) { + err = PTR_ERR(lp); + kfree(idx_gc); + goto out; + } + ubifs_assert(lp->flags & LPROPS_TAKEN); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + idx_gc->lnum = lp->lnum; + idx_gc->unmap = 1; + list_add(&idx_gc->list, &c->idx_gc); + } +out: + ubifs_release_lprops(c); + return err; +} + +/** + * ubifs_gc_end_commit - garbage collection at end of commit. + * @c: UBIFS file-system description object + * + * This function completes out-of-place garbage collection of index LEBs. + */ +int ubifs_gc_end_commit(struct ubifs_info *c) +{ + struct ubifs_gced_idx_leb *idx_gc, *tmp; + struct ubifs_wbuf *wbuf; + int err = 0; + + wbuf = &c->jheads[GCHD].wbuf; + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + list_for_each_entry_safe(idx_gc, tmp, &c->idx_gc, list) + if (idx_gc->unmap) { + dbg_gc("LEB %d", idx_gc->lnum); + err = ubifs_leb_unmap(c, idx_gc->lnum); + if (err) + goto out; + err = ubifs_change_one_lp(c, idx_gc->lnum, LPROPS_NC, + LPROPS_NC, 0, LPROPS_TAKEN, -1); + if (err) + goto out; + list_del(&idx_gc->list); + kfree(idx_gc); + } +out: + mutex_unlock(&wbuf->io_mutex); + return err; +} + +/** + * ubifs_destroy_idx_gc - destroy idx_gc list. + * @c: UBIFS file-system description object + * + * 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) +{ + while (!list_empty(&c->idx_gc)) { + struct ubifs_gced_idx_leb *idx_gc; + + idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, + list); + c->idx_gc_cnt -= 1; + list_del(&idx_gc->list); + kfree(idx_gc); + } + +} + +/** + * ubifs_get_idx_gc_leb - get a LEB from GC'd index LEB list. + * @c: UBIFS file-system description object + * + * Called during start commit so locks are not needed. + */ +int ubifs_get_idx_gc_leb(struct ubifs_info *c) +{ + struct ubifs_gced_idx_leb *idx_gc; + int lnum; + + if (list_empty(&c->idx_gc)) + return -ENOSPC; + idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, list); + lnum = idx_gc->lnum; + /* c->idx_gc_cnt is updated by the caller when lprops are updated */ + list_del(&idx_gc->list); + kfree(idx_gc); + return lnum; +} diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c new file mode 100644 index 0000000..3374f91 --- /dev/null +++ b/fs/ubifs/io.c @@ -0,0 +1,914 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * Copyright (C) 2006, 2007 University of Szeged, Hungary + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + * Zoltan Sogor + */ + +/* + * This file implements UBIFS I/O subsystem which provides various I/O-related + * helper functions (reading/writing/checking/validating nodes) and implements + * write-buffering support. Write buffers help to save space which otherwise + * 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 + * 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 + * has to lock the write-buffer (e.g. journal space reservation code), many + * functions related to write-buffers have "nolock" suffix which means that the + * caller has to lock the write-buffer before calling this function. + * + * UBIFS stores nodes at 64 bit-aligned addresses. If the node length is not + * aligned, UBIFS starts the next node from the aligned address, and the padded + * bytes may contain any rubbish. In other words, UBIFS does not put padding + * bytes in those small gaps. Common headers of nodes store real node lengths, + * not aligned lengths. Indexing nodes also store real lengths in branches. + * + * UBIFS uses padding when it pads to the next min. I/O unit. In this case it + * uses padding nodes or padding bytes, if the padding node does not fit. + * + * All UBIFS nodes are protected by CRC checksums and UBIFS checks all nodes + * every time they are read from the flash media. + */ + +#include +#include "ubifs.h" + +/** + * ubifs_check_node - check node. + * @c: UBIFS file-system description object + * @buf: node to check + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * @quiet: print no messages + * + * This function checks node magic number and CRC checksum. This function also + * validates node length to prevent UBIFS from becoming crazy when an attacker + * feeds it a file-system image with incorrect nodes. For example, too large + * node length in the common header could cause UBIFS to read memory outside of + * allocated buffer when checking the CRC checksum. + * + * 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 err = -EINVAL, type, node_len; + uint32_t crc, node_crc, magic; + const struct ubifs_ch *ch = buf; + + ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); + ubifs_assert(!(offs & 7) && offs < c->leb_size); + + magic = le32_to_cpu(ch->magic); + if (magic != UBIFS_NODE_MAGIC) { + if (!quiet) + ubifs_err("bad magic %#08x, expected %#08x", + magic, UBIFS_NODE_MAGIC); + err = -EUCLEAN; + goto out; + } + + type = ch->node_type; + if (type < 0 || type >= UBIFS_NODE_TYPES_CNT) { + if (!quiet) + ubifs_err("bad node type %d", type); + goto out; + } + + node_len = le32_to_cpu(ch->len); + if (node_len + offs > c->leb_size) + goto out_len; + + if (c->ranges[type].max_len == 0) { + if (node_len != c->ranges[type].len) + goto out_len; + } else if (node_len < c->ranges[type].min_len || + node_len > c->ranges[type].max_len) + goto out_len; + + crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); + node_crc = le32_to_cpu(ch->crc); + if (crc != node_crc) { + if (!quiet) + ubifs_err("bad CRC: calculated %#08x, read %#08x", + crc, node_crc); + err = -EUCLEAN; + goto out; + } + + return 0; + +out_len: + if (!quiet) + ubifs_err("bad node length %d", node_len); +out: + if (!quiet) { + ubifs_err("bad node at LEB %d:%d", lnum, offs); + dbg_dump_node(c, buf); + dbg_dump_stack(); + } + return err; +} + +/** + * ubifs_pad - pad flash space. + * @c: UBIFS file-system description object + * @buf: buffer to put padding to + * @pad: how many bytes to pad + * + * The flash media obliges us to write only in chunks of %c->min_io_size and + * when we have to write less data we add padding node to the write-buffer and + * pad it to the next minimal I/O unit's boundary. Padding nodes help when the + * media is being scanned. If the amount of wasted space is not enough to fit a + * padding node which takes %UBIFS_PAD_NODE_SZ bytes, we write padding bytes + * pattern (%UBIFS_PADDING_BYTE). + * + * Padding nodes are also used to fill gaps when the "commit-in-gaps" method is + * used. + */ +void ubifs_pad(const struct ubifs_info *c, void *buf, int pad) +{ + uint32_t crc; + + ubifs_assert(pad >= 0 && !(pad & 7)); + + if (pad >= UBIFS_PAD_NODE_SZ) { + struct ubifs_ch *ch = buf; + struct ubifs_pad_node *pad_node = buf; + + ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); + ch->node_type = UBIFS_PAD_NODE; + ch->group_type = UBIFS_NO_NODE_GROUP; + ch->padding[0] = ch->padding[1] = 0; + ch->sqnum = 0; + ch->len = cpu_to_le32(UBIFS_PAD_NODE_SZ); + pad -= UBIFS_PAD_NODE_SZ; + pad_node->pad_len = cpu_to_le32(pad); + crc = crc32(UBIFS_CRC32_INIT, buf + 8, UBIFS_PAD_NODE_SZ - 8); + ch->crc = cpu_to_le32(crc); + memset(buf + UBIFS_PAD_NODE_SZ, 0, pad); + } else if (pad > 0) + /* Too little space, padding node won't fit */ + memset(buf, UBIFS_PADDING_BYTE, pad); +} + +/** + * next_sqnum - get next sequence number. + * @c: UBIFS file-system description object + */ +static unsigned long long next_sqnum(struct ubifs_info *c) +{ + unsigned long long sqnum; + + spin_lock(&c->cnt_lock); + sqnum = ++c->max_sqnum; + spin_unlock(&c->cnt_lock); + + if (unlikely(sqnum >= SQNUM_WARN_WATERMARK)) { + if (sqnum >= SQNUM_WATERMARK) { + ubifs_err("sequence number overflow %llu, end of life", + sqnum); + ubifs_ro_mode(c, -EINVAL); + } + ubifs_warn("running out of sequence numbers, end of life soon"); + } + + return sqnum; +} + +/** + * ubifs_prepare_node - prepare node to be written to flash. + * @c: UBIFS file-system description object + * @node: the node to pad + * @len: node length + * @pad: if the buffer has to be padded + * + * This function prepares node at @node to be written to the media - it + * calculates node CRC, fills the common header, and adds proper padding up to + * the next minimum I/O unit if @pad is not zero. + */ +void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad) +{ + uint32_t crc; + struct ubifs_ch *ch = node; + unsigned long long sqnum = next_sqnum(c); + + ubifs_assert(len >= UBIFS_CH_SZ); + + ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); + ch->len = cpu_to_le32(len); + ch->group_type = UBIFS_NO_NODE_GROUP; + ch->sqnum = cpu_to_le64(sqnum); + ch->padding[0] = ch->padding[1] = 0; + crc = crc32(UBIFS_CRC32_INIT, node + 8, len - 8); + ch->crc = cpu_to_le32(crc); + + if (pad) { + len = ALIGN(len, 8); + pad = ALIGN(len, c->min_io_size) - len; + ubifs_pad(c, node + len, pad); + } +} + +/** + * ubifs_prep_grp_node - prepare node of a group to be written to flash. + * @c: UBIFS file-system description object + * @node: the node to pad + * @len: node length + * @last: indicates the last node of the group + * + * This function prepares node at @node to be written to the media - it + * calculates node CRC and fills the common header. + */ +void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last) +{ + uint32_t crc; + struct ubifs_ch *ch = node; + unsigned long long sqnum = next_sqnum(c); + + ubifs_assert(len >= UBIFS_CH_SZ); + + ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); + ch->len = cpu_to_le32(len); + if (last) + ch->group_type = UBIFS_LAST_OF_NODE_GROUP; + else + ch->group_type = UBIFS_IN_NODE_GROUP; + ch->sqnum = cpu_to_le64(sqnum); + ch->padding[0] = ch->padding[1] = 0; + crc = crc32(UBIFS_CRC32_INIT, node + 8, len - 8); + ch->crc = cpu_to_le32(crc); +} + +/** + * wbuf_timer_callback - write-buffer timer callback function. + * @data: timer data (write-buffer descriptor) + * + * This function is called when the write-buffer timer expires. + */ +static void wbuf_timer_callback_nolock(unsigned long data) +{ + struct ubifs_wbuf *wbuf = (struct ubifs_wbuf *)data; + + wbuf->need_sync = 1; + wbuf->c->need_wbuf_sync = 1; + ubifs_wake_up_bgt(wbuf->c); +} + +/** + * new_wbuf_timer - start new write-buffer timer. + * @wbuf: write-buffer descriptor + */ +static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) +{ + ubifs_assert(!timer_pending(&wbuf->timer)); + + if (!wbuf->timeout) + return; + + wbuf->timer.expires = jiffies + wbuf->timeout; + add_timer(&wbuf->timer); +} + +/** + * cancel_wbuf_timer - cancel write-buffer timer. + * @wbuf: write-buffer descriptor + */ +static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) +{ + /* + * If the syncer is waiting for the lock (from the background thread's + * context) and another task is changing write-buffer then the syncing + * should be canceled. + */ + wbuf->need_sync = 0; + del_timer(&wbuf->timer); +} + +/** + * ubifs_wbuf_sync_nolock - synchronize write-buffer. + * @wbuf: write-buffer to synchronize + * + * This function synchronizes write-buffer @buf and returns zero in case of + * success or a negative error code in case of failure. + */ +int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) +{ + struct ubifs_info *c = wbuf->c; + int err, dirt; + + cancel_wbuf_timer_nolock(wbuf); + if (!wbuf->used || wbuf->lnum == -1) + /* Write-buffer is empty or not seeked */ + return 0; + + dbg_io("LEB %d:%d, %d bytes", + wbuf->lnum, wbuf->offs, wbuf->used); + ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); + ubifs_assert(!(wbuf->avail & 7)); + ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); + + if (c->ro_media) + return -EROFS; + + ubifs_pad(c, wbuf->buf + wbuf->used, wbuf->avail); + err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, + c->min_io_size, wbuf->dtype); + if (err) { + ubifs_err("cannot write %d bytes to LEB %d:%d", + c->min_io_size, wbuf->lnum, wbuf->offs); + dbg_dump_stack(); + return err; + } + + dirt = wbuf->avail; + + spin_lock(&wbuf->lock); + wbuf->offs += c->min_io_size; + wbuf->avail = c->min_io_size; + wbuf->used = 0; + wbuf->next_ino = 0; + spin_unlock(&wbuf->lock); + + if (wbuf->sync_callback) + err = wbuf->sync_callback(c, wbuf->lnum, + c->leb_size - wbuf->offs, dirt); + return err; +} + +/** + * ubifs_wbuf_seek_nolock - seek write-buffer. + * @wbuf: write-buffer + * @lnum: logical eraseblock number to seek to + * @offs: logical eraseblock offset to seek to + * @dtype: data type + * + * This function targets the write buffer to logical eraseblock @lnum:@offs. + * The write-buffer is synchronized if it is not empty. Returns zero in case of + * success and a negative error code in case of failure. + */ +int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, + int dtype) +{ + const struct ubifs_info *c = wbuf->c; + + dbg_io("LEB %d:%d", lnum, offs); + ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); + ubifs_assert(offs >= 0 && offs <= c->leb_size); + ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); + ubifs_assert(lnum != wbuf->lnum); + + if (wbuf->used > 0) { + int err = ubifs_wbuf_sync_nolock(wbuf); + + if (err) + return err; + } + + spin_lock(&wbuf->lock); + wbuf->lnum = lnum; + wbuf->offs = offs; + wbuf->avail = c->min_io_size; + wbuf->used = 0; + spin_unlock(&wbuf->lock); + wbuf->dtype = dtype; + + return 0; +} + +/** + * ubifs_bg_wbufs_sync - synchronize write-buffers. + * @c: UBIFS file-system description object + * + * This function is called by background thread to synchronize write-buffers. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +int ubifs_bg_wbufs_sync(struct ubifs_info *c) +{ + int err, i; + + if (!c->need_wbuf_sync) + return 0; + c->need_wbuf_sync = 0; + + if (c->ro_media) { + err = -EROFS; + goto out_timers; + } + + dbg_io("synchronize"); + for (i = 0; i < c->jhead_cnt; i++) { + struct ubifs_wbuf *wbuf = &c->jheads[i].wbuf; + + cond_resched(); + + /* + * If the mutex is locked then wbuf is being changed, so + * synchronization is not necessary. + */ + if (mutex_is_locked(&wbuf->io_mutex)) + continue; + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + if (!wbuf->need_sync) { + mutex_unlock(&wbuf->io_mutex); + continue; + } + + err = ubifs_wbuf_sync_nolock(wbuf); + mutex_unlock(&wbuf->io_mutex); + if (err) { + ubifs_err("cannot sync write-buffer, error %d", err); + ubifs_ro_mode(c, err); + goto out_timers; + } + } + + return 0; + +out_timers: + /* Cancel all timers to prevent repeated errors */ + for (i = 0; i < c->jhead_cnt; i++) { + struct ubifs_wbuf *wbuf = &c->jheads[i].wbuf; + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + cancel_wbuf_timer_nolock(wbuf); + mutex_unlock(&wbuf->io_mutex); + } + return err; +} + +/** + * ubifs_wbuf_write_nolock - write data to flash via write-buffer. + * @wbuf: write-buffer + * @buf: node to write + * @len: node length + * + * This function writes data to flash via write-buffer @wbuf. This means that + * the last piece of the node won't reach the flash media immediately if it + * does not take whole minimal I/O unit. Instead, the node will sit in RAM + * until the write-buffer is synchronized (e.g., by timer). + * + * This function returns zero in case of success and a negative error code in + * case of failure. If the node cannot be written because there is no more + * space in this logical eraseblock, %-ENOSPC is returned. + */ +int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) +{ + struct ubifs_info *c = wbuf->c; + int err, written, n, aligned_len = ALIGN(len, 8), offs; + + dbg_io("%d bytes (%s) to wbuf at LEB %d:%d", len, + dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->lnum, + wbuf->offs + wbuf->used); + ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); + ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); + ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); + ubifs_assert(wbuf->avail > 0 && wbuf->avail <= c->min_io_size); + ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); + + if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) { + err = -ENOSPC; + goto out; + } + + cancel_wbuf_timer_nolock(wbuf); + + if (c->ro_media) + return -EROFS; + + if (aligned_len <= wbuf->avail) { + /* + * The node is not very large and fits entirely within + * write-buffer. + */ + memcpy(wbuf->buf + wbuf->used, buf, len); + + if (aligned_len == wbuf->avail) { + dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, + wbuf->offs); + err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, + wbuf->offs, c->min_io_size, + wbuf->dtype); + if (err) + goto out; + + spin_lock(&wbuf->lock); + wbuf->offs += c->min_io_size; + wbuf->avail = c->min_io_size; + wbuf->used = 0; + wbuf->next_ino = 0; + spin_unlock(&wbuf->lock); + } else { + spin_lock(&wbuf->lock); + wbuf->avail -= aligned_len; + wbuf->used += aligned_len; + spin_unlock(&wbuf->lock); + } + + goto exit; + } + + /* + * The node is large enough and does not fit entirely within current + * minimal I/O unit. We have to fill and flush write-buffer and switch + * to the next min. I/O unit. + */ + dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, wbuf->offs); + memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); + err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, + c->min_io_size, wbuf->dtype); + if (err) + goto out; + + offs = wbuf->offs + c->min_io_size; + len -= wbuf->avail; + aligned_len -= wbuf->avail; + written = wbuf->avail; + + /* + * The remaining data may take more whole min. I/O units, so write the + * remains multiple to min. I/O unit size directly to the flash media. + * We align node length to 8-byte boundary because we anyway flash wbuf + * if the remaining space is less than 8 bytes. + */ + n = aligned_len >> c->min_io_shift; + if (n) { + n <<= c->min_io_shift; + dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum, offs); + err = ubi_leb_write(c->ubi, wbuf->lnum, buf + written, offs, n, + wbuf->dtype); + if (err) + goto out; + offs += n; + aligned_len -= n; + len -= n; + written += n; + } + + spin_lock(&wbuf->lock); + if (aligned_len) + /* + * And now we have what's left and what does not take whole + * min. I/O unit, so write it to the write-buffer and we are + * done. + */ + memcpy(wbuf->buf, buf + written, len); + + wbuf->offs = offs; + wbuf->used = aligned_len; + wbuf->avail = c->min_io_size - aligned_len; + wbuf->next_ino = 0; + spin_unlock(&wbuf->lock); + +exit: + if (wbuf->sync_callback) { + int free = c->leb_size - wbuf->offs - wbuf->used; + + err = wbuf->sync_callback(c, wbuf->lnum, free, 0); + if (err) + goto out; + } + + if (wbuf->used) + new_wbuf_timer_nolock(wbuf); + + return 0; + +out: + ubifs_err("cannot write %d bytes to LEB %d:%d, error %d", + len, wbuf->lnum, wbuf->offs, err); + dbg_dump_node(c, buf); + dbg_dump_stack(); + dbg_dump_leb(c, wbuf->lnum); + return err; +} + +/** + * ubifs_write_node - write node to the media. + * @c: UBIFS file-system description object + * @buf: the node to write + * @len: node length + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * @dtype: node life-time hint (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) + * + * This function automatically fills node magic number, assigns sequence + * number, and calculates node CRC checksum. The length of the @buf buffer has + * to be aligned to the minimal I/O unit size. This function automatically + * appends padding node and padding bytes if needed. Returns zero in case of + * success and a negative error code in case of failure. + */ +int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, + int offs, int dtype) +{ + int err, buf_len = ALIGN(len, c->min_io_size); + + dbg_io("LEB %d:%d, %s, length %d (aligned %d)", + lnum, offs, dbg_ntype(((struct ubifs_ch *)buf)->node_type), len, + buf_len); + ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); + ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); + + if (c->ro_media) + return -EROFS; + + ubifs_prepare_node(c, buf, len, 1); + err = ubi_leb_write(c->ubi, lnum, buf, offs, buf_len, dtype); + if (err) { + ubifs_err("cannot write %d bytes to LEB %d:%d, error %d", + buf_len, lnum, offs, err); + dbg_dump_node(c, buf); + dbg_dump_stack(); + } + + return err; +} + +/** + * ubifs_read_node_wbuf - read node from the media or write-buffer. + * @wbuf: wbuf to check for un-written data + * @buf: buffer to read to + * @type: node type + * @len: node length + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * + * This function reads a node of known type and length, checks it and stores + * in @buf. If the node partially or fully sits in the write-buffer, this + * function takes data from the buffer, otherwise it reads the flash media. + * Returns zero in case of success, %-EUCLEAN if CRC mismatched and a negative + * error code in case of failure. + */ +int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, + int lnum, int offs) +{ + const struct ubifs_info *c = wbuf->c; + int err, rlen, overlap; + struct ubifs_ch *ch = buf; + + dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); + ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); + ubifs_assert(!(offs & 7) && offs < c->leb_size); + ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); + + spin_lock(&wbuf->lock); + overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs); + if (!overlap) { + /* We may safely unlock the write-buffer and read the data */ + spin_unlock(&wbuf->lock); + return ubifs_read_node(c, buf, type, len, lnum, offs); + } + + /* Don't read under wbuf */ + rlen = wbuf->offs - offs; + if (rlen < 0) + rlen = 0; + + /* Copy the rest from the write-buffer */ + memcpy(buf + rlen, wbuf->buf + offs + rlen - wbuf->offs, len - rlen); + spin_unlock(&wbuf->lock); + + if (rlen > 0) { + /* Read everything that goes before write-buffer */ + err = ubi_read(c->ubi, lnum, buf, offs, rlen); + if (err && err != -EBADMSG) { + ubifs_err("failed to read node %d from LEB %d:%d, " + "error %d", type, lnum, offs, err); + dbg_dump_stack(); + return err; + } + } + + if (type != ch->node_type) { + ubifs_err("bad node type (%d but expected %d)", + ch->node_type, type); + goto out; + } + + err = ubifs_check_node(c, buf, lnum, offs, 0); + if (err) { + ubifs_err("expected node type %d", type); + return err; + } + + rlen = le32_to_cpu(ch->len); + if (rlen != len) { + ubifs_err("bad node length %d, expected %d", rlen, len); + goto out; + } + + return 0; + +out: + ubifs_err("bad node at LEB %d:%d", lnum, offs); + dbg_dump_node(c, buf); + dbg_dump_stack(); + return -EINVAL; +} + +/** + * ubifs_read_node - read node. + * @c: UBIFS file-system description object + * @buf: buffer to read to + * @type: node type + * @len: node length (not aligned) + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * + * This function reads a node of known type and and length, checks it and + * stores in @buf. Returns zero in case of success, %-EUCLEAN if CRC mismatched + * and a negative error code in case of failure. + */ +int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, + int lnum, int offs) +{ + int err, l; + struct ubifs_ch *ch = buf; + + dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); + ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); + ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size); + ubifs_assert(!(offs & 7) && offs < c->leb_size); + ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); + + err = ubi_read(c->ubi, lnum, buf, offs, len); + if (err && err != -EBADMSG) { + ubifs_err("cannot read node %d from LEB %d:%d, error %d", + type, lnum, offs, err); + return err; + } + + if (type != ch->node_type) { + ubifs_err("bad node type (%d but expected %d)", + ch->node_type, type); + goto out; + } + + err = ubifs_check_node(c, buf, lnum, offs, 0); + if (err) { + ubifs_err("expected node type %d", type); + return err; + } + + l = le32_to_cpu(ch->len); + if (l != len) { + ubifs_err("bad node length %d, expected %d", l, len); + goto out; + } + + return 0; + +out: + ubifs_err("bad node at LEB %d:%d", lnum, offs); + dbg_dump_node(c, buf); + dbg_dump_stack(); + return -EINVAL; +} + +/** + * ubifs_wbuf_init - initialize write-buffer. + * @c: UBIFS file-system description object + * @wbuf: write-buffer to initialize + * + * This function initializes write buffer. Returns zero in case of success + * %-ENOMEM in case of failure. + */ +int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) +{ + size_t size; + + wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); + if (!wbuf->buf) + return -ENOMEM; + + size = (c->min_io_size / UBIFS_CH_SZ + 1) * sizeof(ino_t); + wbuf->inodes = kmalloc(size, GFP_KERNEL); + if (!wbuf->inodes) { + kfree(wbuf->buf); + wbuf->buf = NULL; + return -ENOMEM; + } + + wbuf->used = 0; + wbuf->lnum = wbuf->offs = -1; + wbuf->avail = c->min_io_size; + wbuf->dtype = UBI_UNKNOWN; + wbuf->sync_callback = NULL; + mutex_init(&wbuf->io_mutex); + spin_lock_init(&wbuf->lock); + + wbuf->c = c; + init_timer(&wbuf->timer); + wbuf->timer.function = wbuf_timer_callback_nolock; + wbuf->timer.data = (unsigned long)wbuf; + wbuf->timeout = DEFAULT_WBUF_TIMEOUT; + wbuf->next_ino = 0; + + return 0; +} + +/** + * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. + * @wbuf: the write-buffer whereto add + * @inum: the inode number + * + * This function adds an inode number to the inode array of the write-buffer. + */ +void ubifs_wbuf_add_ino_nolock(struct ubifs_wbuf *wbuf, ino_t inum) +{ + if (!wbuf->buf) + /* NOR flash or something similar */ + return; + + spin_lock(&wbuf->lock); + if (wbuf->used) + wbuf->inodes[wbuf->next_ino++] = inum; + spin_unlock(&wbuf->lock); +} + +/** + * wbuf_has_ino - returns if the wbuf contains data from the inode. + * @wbuf: the write-buffer + * @inum: the inode number + * + * This function returns with %1 if the write-buffer contains some data from the + * given inode otherwise it returns with %0. + */ +static int wbuf_has_ino(struct ubifs_wbuf *wbuf, ino_t inum) +{ + int i, ret = 0; + + spin_lock(&wbuf->lock); + for (i = 0; i < wbuf->next_ino; i++) + if (inum == wbuf->inodes[i]) { + ret = 1; + break; + } + spin_unlock(&wbuf->lock); + + return ret; +} + +/** + * ubifs_sync_wbufs_by_inode - synchronize write-buffers for an inode. + * @c: UBIFS file-system description object + * @inode: inode to synchronize + * + * This function synchronizes write-buffers which contain nodes belonging to + * @inode. Returns zero in case of success and a negative error code in case of + * failure. + */ +int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode) +{ + int i, err = 0; + + for (i = 0; i < c->jhead_cnt; i++) { + struct ubifs_wbuf *wbuf = &c->jheads[i].wbuf; + + if (i == GCHD) + /* + * GC head is special, do not look at it. Even if the + * head contains something related to this inode, it is + * a _copy_ of corresponding on-flash node which sits + * somewhere else. + */ + continue; + + if (!wbuf_has_ino(wbuf, inode->i_ino)) + continue; + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + if (wbuf_has_ino(wbuf, inode->i_ino)) + err = ubifs_wbuf_sync_nolock(wbuf); + mutex_unlock(&wbuf->io_mutex); + + if (err) { + ubifs_ro_mode(c, err); + return err; + } + } + return 0; +} diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c new file mode 100644 index 0000000..5e82cff --- /dev/null +++ b/fs/ubifs/ioctl.c @@ -0,0 +1,204 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * Copyright (C) 2006, 2007 University of Szeged, Hungary + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Zoltan Sogor + * Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* This file implements EXT2-compatible extended attribute ioctl() calls */ + +#include +#include +#include +#include "ubifs.h" + +/** + * ubifs_set_inode_flags - set VFS inode flags. + * @inode: VFS inode to set flags for + * + * This function propagates flags from UBIFS inode object to VFS inode object. + */ +void ubifs_set_inode_flags(struct inode *inode) +{ + unsigned int flags = ubifs_inode(inode)->flags; + + inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_DIRSYNC); + if (flags & UBIFS_SYNC_FL) + inode->i_flags |= S_SYNC; + if (flags & UBIFS_APPEND_FL) + inode->i_flags |= S_APPEND; + if (flags & UBIFS_IMMUTABLE_FL) + inode->i_flags |= S_IMMUTABLE; + if (flags & UBIFS_DIRSYNC_FL) + inode->i_flags |= S_DIRSYNC; +} + +/* + * ioctl2ubifs - convert ioctl inode flags to UBIFS inode flags. + * @ioctl_flags: flags to convert + * + * This function convert ioctl flags (@FS_COMPR_FL, etc) to UBIFS inode flags + * (@UBIFS_COMPR_FL, etc). + */ +static int ioctl2ubifs(int ioctl_flags) +{ + int ubifs_flags = 0; + + if (ioctl_flags & FS_COMPR_FL) + ubifs_flags |= UBIFS_COMPR_FL; + if (ioctl_flags & FS_SYNC_FL) + ubifs_flags |= UBIFS_SYNC_FL; + if (ioctl_flags & FS_APPEND_FL) + ubifs_flags |= UBIFS_APPEND_FL; + if (ioctl_flags & FS_IMMUTABLE_FL) + ubifs_flags |= UBIFS_IMMUTABLE_FL; + if (ioctl_flags & FS_DIRSYNC_FL) + ubifs_flags |= UBIFS_DIRSYNC_FL; + + return ubifs_flags; +} + +/* + * ubifs2ioctl - convert UBIFS inode flags to ioctl inode flags. + * @ubifs_flags: flags to convert + * + * This function convert UBIFS (@UBIFS_COMPR_FL, etc) to ioctl flags + * (@FS_COMPR_FL, etc). + */ +static int ubifs2ioctl(int ubifs_flags) +{ + int ioctl_flags = 0; + + if (ubifs_flags & UBIFS_COMPR_FL) + ioctl_flags |= FS_COMPR_FL; + if (ubifs_flags & UBIFS_SYNC_FL) + ioctl_flags |= FS_SYNC_FL; + if (ubifs_flags & UBIFS_APPEND_FL) + ioctl_flags |= FS_APPEND_FL; + if (ubifs_flags & UBIFS_IMMUTABLE_FL) + ioctl_flags |= FS_IMMUTABLE_FL; + if (ubifs_flags & UBIFS_DIRSYNC_FL) + ioctl_flags |= FS_DIRSYNC_FL; + + return ioctl_flags; +} + +static int setflags(struct inode *inode, int flags) +{ + int oldflags, err, release; + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_info *c = inode->i_sb->s_fs_info; + struct ubifs_budget_req req = { .dirtied_ino = 1, + .dirtied_ino_d = ui->data_len }; + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + /* + * The IMMUTABLE and APPEND_ONLY flags can only be changed by + * the relevant capability. + */ + mutex_lock(&ui->ui_mutex); + oldflags = ubifs2ioctl(ui->flags); + if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) { + if (!capable(CAP_LINUX_IMMUTABLE)) { + err = -EPERM; + goto out_unlock; + } + } + + ui->flags = ioctl2ubifs(flags); + ubifs_set_inode_flags(inode); + inode->i_ctime = ubifs_current_time(inode); + release = ui->dirty; + mark_inode_dirty_sync(inode); + mutex_unlock(&ui->ui_mutex); + + if (release) + ubifs_release_budget(c, &req); + if (IS_SYNC(inode)) + err = write_inode_now(inode, 1); + return err; + +out_unlock: + ubifs_err("can't modify inode %lu attributes", inode->i_ino); + mutex_unlock(&ui->ui_mutex); + ubifs_release_budget(c, &req); + return err; +} + +long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int flags, err; + struct inode *inode = file->f_path.dentry->d_inode; + + switch (cmd) { + case FS_IOC_GETFLAGS: + flags = ubifs2ioctl(ubifs_inode(inode)->flags); + + return put_user(flags, (int __user *) arg); + + case FS_IOC_SETFLAGS: { + if (IS_RDONLY(inode)) + return -EROFS; + + if (!is_owner_or_cap(inode)) + return -EACCES; + + if (get_user(flags, (int __user *) arg)) + return -EFAULT; + + if (!S_ISDIR(inode->i_mode)) + flags &= ~FS_DIRSYNC_FL; + + /* + * Make sure the file-system is read-write and make sure it + * will not become read-only while we are changing the flags. + */ + err = mnt_want_write(file->f_path.mnt); + if (err) + return err; + err = setflags(inode, flags); + mnt_drop_write(file->f_path.mnt); + return err; + } + + default: + return -ENOTTY; + } +} + +#ifdef CONFIG_COMPAT +long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case FS_IOC32_GETFLAGS: + cmd = FS_IOC_GETFLAGS; + break; + case FS_IOC32_SETFLAGS: + cmd = FS_IOC_SETFLAGS; + break; + default: + return -ENOIOCTLCMD; + } + return ubifs_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c new file mode 100644 index 0000000..283155a --- /dev/null +++ b/fs/ubifs/journal.c @@ -0,0 +1,1387 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements UBIFS journal. + * + * The journal consists of 2 parts - the log and bud LEBs. The log has fixed + * length and position, while a bud logical eraseblock is any LEB in the main + * area. Buds contain file system data - data nodes, inode nodes, etc. The log + * contains only references to buds and some other stuff like commit + * start node. The idea is that when we commit the journal, we do + * not copy the data, the buds just become indexed. Since after the commit the + * nodes in bud eraseblocks become leaf nodes of the file system index tree, we + * use term "bud". Analogy is obvious, bud eraseblocks contain nodes which will + * become leafs in the future. + * + * The journal is multi-headed because we want to write data to the journal as + * optimally as possible. It is nice to have nodes belonging to the same inode + * in one LEB, so we may write data owned by different inodes to different + * journal heads, although at present only one data head is used. + * + * For recovery reasons, the base head contains all inode nodes, all directory + * entry nodes and all truncate nodes. This means that the other heads contain + * only data nodes. + * + * Bud LEBs may be half-indexed. For example, if the bud was not full at the + * time of commit, the bud is retained to continue to be used in the journal, + * even though the "front" of the LEB is now indexed. In that case, the log + * reference contains the offset where the bud starts for the purposes of the + * journal. + * + * The journal size has to be limited, because the larger is the journal, the + * longer it takes to mount UBIFS (scanning the journal) and the more memory it + * takes (indexing in the TNC). + * + * All the journal write operations like 'ubifs_jnl_update()' here, which write + * multiple UBIFS nodes to the journal at one go, are atomic with respect to + * unclean reboots. Should the unclean reboot happen, the recovery code drops + * all the nodes. + */ + +#include "ubifs.h" + +/** + * zero_ino_node_unused - zero out unused fields of an on-flash inode node. + * @ino: the inode to zero out + */ +static inline void zero_ino_node_unused(struct ubifs_ino_node *ino) +{ + memset(ino->padding1, 0, 4); + memset(ino->padding2, 0, 26); +} + +/** + * zero_dent_node_unused - zero out unused fields of an on-flash directory + * entry node. + * @dent: the directory entry to zero out + */ +static inline void zero_dent_node_unused(struct ubifs_dent_node *dent) +{ + dent->padding1 = 0; + memset(dent->padding2, 0, 4); +} + +/** + * zero_data_node_unused - zero out unused fields of an on-flash data node. + * @data: the data node to zero out + */ +static inline void zero_data_node_unused(struct ubifs_data_node *data) +{ + memset(data->padding, 0, 2); +} + +/** + * zero_trun_node_unused - zero out unused fields of an on-flash truncation + * node. + * @trun: the truncation node to zero out + */ +static inline void zero_trun_node_unused(struct ubifs_trun_node *trun) +{ + memset(trun->padding, 0, 12); +} + +/** + * reserve_space - reserve space in the journal. + * @c: UBIFS file-system description object + * @jhead: journal head number + * @len: node length + * + * This function reserves space in journal head @head. If the reservation + * succeeded, the journal head stays locked and later has to be unlocked using + * 'release_head()'. 'write_node()' and 'write_head()' functions also unlock + * it. Returns zero in case of success, %-EAGAIN if commit has to be done, and + * other negative error codes in case of other failures. + */ +static int reserve_space(struct ubifs_info *c, int jhead, int len) +{ + int err = 0, err1, retries = 0, avail, lnum, offs, free, squeeze; + struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; + + /* + * Typically, the base head has smaller nodes written to it, so it is + * better to try to allocate space at the ends of eraseblocks. This is + * what the squeeze parameter does. + */ + squeeze = (jhead == BASEHD); +again: + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + + if (c->ro_media) { + err = -EROFS; + goto out_unlock; + } + + avail = c->leb_size - wbuf->offs - wbuf->used; + if (wbuf->lnum != -1 && avail >= len) + return 0; + + /* + * Write buffer wasn't seek'ed or there is no enough space - look for an + * LEB with some empty space. + */ + lnum = ubifs_find_free_space(c, len, &free, squeeze); + if (lnum >= 0) { + /* Found an LEB, add it to the journal head */ + offs = c->leb_size - free; + err = ubifs_add_bud_to_log(c, jhead, lnum, offs); + if (err) + goto out_return; + /* A new bud was successfully allocated and added to the log */ + goto out; + } + + err = lnum; + if (err != -ENOSPC) + goto out_unlock; + + /* + * No free space, we have to run garbage collector to make + * some. But the write-buffer mutex has to be unlocked because + * GC also takes it. + */ + dbg_jnl("no free space jhead %d, run GC", jhead); + mutex_unlock(&wbuf->io_mutex); + + lnum = ubifs_garbage_collect(c, 0); + if (lnum < 0) { + err = lnum; + if (err != -ENOSPC) + return err; + + /* + * GC could not make a free LEB. But someone else may + * have allocated new bud for this journal head, + * because we dropped @wbuf->io_mutex, so try once + * again. + */ + dbg_jnl("GC couldn't make a free LEB for jhead %d", jhead); + if (retries++ < 2) { + dbg_jnl("retry (%d)", retries); + goto again; + } + + dbg_jnl("return -ENOSPC"); + return err; + } + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + dbg_jnl("got LEB %d for jhead %d", lnum, jhead); + avail = c->leb_size - wbuf->offs - wbuf->used; + + if (wbuf->lnum != -1 && avail >= len) { + /* + * Someone else has switched the journal head and we have + * enough space now. This happens when more then one process is + * trying to write to the same journal head at the same time. + */ + dbg_jnl("return LEB %d back, already have LEB %d:%d", + lnum, wbuf->lnum, wbuf->offs + wbuf->used); + err = ubifs_return_leb(c, lnum); + if (err) + goto out_unlock; + return 0; + } + + err = ubifs_add_bud_to_log(c, jhead, lnum, 0); + if (err) + goto out_return; + offs = 0; + +out: + err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, UBI_SHORTTERM); + if (err) + goto out_unlock; + + return 0; + +out_unlock: + mutex_unlock(&wbuf->io_mutex); + return err; + +out_return: + /* An error occurred and the LEB has to be returned to lprops */ + ubifs_assert(err < 0); + err1 = ubifs_return_leb(c, lnum); + if (err1 && err == -EAGAIN) + /* + * Return original error code only if it is not %-EAGAIN, + * which is not really an error. Otherwise, return the error + * code of 'ubifs_return_leb()'. + */ + err = err1; + mutex_unlock(&wbuf->io_mutex); + return err; +} + +/** + * write_node - write node to a journal head. + * @c: UBIFS file-system description object + * @jhead: journal head + * @node: node to write + * @len: node length + * @lnum: LEB number written is returned here + * @offs: offset written is returned here + * + * This function writes a node to reserved space of journal head @jhead. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +static int write_node(struct ubifs_info *c, int jhead, void *node, int len, + int *lnum, int *offs) +{ + struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; + + ubifs_assert(jhead != GCHD); + + *lnum = c->jheads[jhead].wbuf.lnum; + *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; + + dbg_jnl("jhead %d, LEB %d:%d, len %d", jhead, *lnum, *offs, len); + ubifs_prepare_node(c, node, len, 0); + + return ubifs_wbuf_write_nolock(wbuf, node, len); +} + +/** + * write_head - write data to a journal head. + * @c: UBIFS file-system description object + * @jhead: journal head + * @buf: buffer to write + * @len: length to write + * @lnum: LEB number written is returned here + * @offs: offset written is returned here + * @sync: non-zero if the write-buffer has to by synchronized + * + * This function is the same as 'write_node()' but it does not assume the + * buffer it is writing is a node, so it does not prepare it (which means + * initializing common header and calculating CRC). + */ +static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, + int *lnum, int *offs, int sync) +{ + int err; + struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; + + ubifs_assert(jhead != GCHD); + + *lnum = c->jheads[jhead].wbuf.lnum; + *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; + dbg_jnl("jhead %d, LEB %d:%d, len %d", jhead, *lnum, *offs, len); + + err = ubifs_wbuf_write_nolock(wbuf, buf, len); + if (err) + return err; + if (sync) + err = ubifs_wbuf_sync_nolock(wbuf); + return err; +} + +/** + * make_reservation - reserve journal space. + * @c: UBIFS file-system description object + * @jhead: journal head + * @len: how many bytes to reserve + * + * This function makes space reservation in journal head @jhead. The function + * takes the commit lock and locks the journal head, and the caller has to + * unlock the head and finish the reservation with 'finish_reservation()'. + * Returns zero in case of success and a negative error code in case of + * failure. + * + * Note, the journal head may be unlocked as soon as the data is written, while + * the commit lock has to be released after the data has been added to the + * TNC. + */ +static int make_reservation(struct ubifs_info *c, int jhead, int len) +{ + int err, cmt_retries = 0, nospc_retries = 0; + +again: + down_read(&c->commit_sem); + err = reserve_space(c, jhead, len); + if (!err) + return 0; + up_read(&c->commit_sem); + + if (err == -ENOSPC) { + /* + * GC could not make any progress. We should try to commit + * once because it could make some dirty space and GC would + * make progress, so make the error -EAGAIN so that the below + * will commit and re-try. + */ + if (nospc_retries++ < 2) { + dbg_jnl("no space, retry"); + err = -EAGAIN; + } + + /* + * This means that the budgeting is incorrect. We always have + * to be able to write to the media, because all operations are + * budgeted. Deletions are not budgeted, though, but we reserve + * an extra LEB for them. + */ + } + + if (err != -EAGAIN) + goto out; + + /* + * -EAGAIN means that the journal is full or too large, or the above + * code wants to do one commit. Do this and re-try. + */ + if (cmt_retries > 128) { + /* + * This should not happen unless the journal size limitations + * are too tough. + */ + ubifs_err("stuck in space allocation"); + err = -ENOSPC; + goto out; + } else if (cmt_retries > 32) + ubifs_warn("too many space allocation re-tries (%d)", + cmt_retries); + + dbg_jnl("-EAGAIN, commit and retry (retried %d times)", + cmt_retries); + cmt_retries += 1; + + err = ubifs_run_commit(c); + if (err) + return err; + goto again; + +out: + ubifs_err("cannot reserve %d bytes in jhead %d, error %d", + len, jhead, err); + if (err == -ENOSPC) { + /* This are some budgeting problems, print useful information */ + down_write(&c->commit_sem); + spin_lock(&c->space_lock); + dbg_dump_stack(); + dbg_dump_budg(c); + spin_unlock(&c->space_lock); + dbg_dump_lprops(c); + cmt_retries = dbg_check_lprops(c); + up_write(&c->commit_sem); + } + return err; +} + +/** + * release_head - release a journal head. + * @c: UBIFS file-system description object + * @jhead: journal head + * + * This function releases journal head @jhead which was locked by + * the 'make_reservation()' function. It has to be called after each successful + * 'make_reservation()' invocation. + */ +static inline void release_head(struct ubifs_info *c, int jhead) +{ + mutex_unlock(&c->jheads[jhead].wbuf.io_mutex); +} + +/** + * finish_reservation - finish a reservation. + * @c: UBIFS file-system description object + * + * This function finishes journal space reservation. It must be called after + * 'make_reservation()'. + */ +static void finish_reservation(struct ubifs_info *c) +{ + up_read(&c->commit_sem); +} + +/** + * get_dent_type - translate VFS inode mode to UBIFS directory entry type. + * @mode: inode mode + */ +static int get_dent_type(int mode) +{ + switch (mode & S_IFMT) { + case S_IFREG: + return UBIFS_ITYPE_REG; + case S_IFDIR: + return UBIFS_ITYPE_DIR; + case S_IFLNK: + return UBIFS_ITYPE_LNK; + case S_IFBLK: + return UBIFS_ITYPE_BLK; + case S_IFCHR: + return UBIFS_ITYPE_CHR; + case S_IFIFO: + return UBIFS_ITYPE_FIFO; + case S_IFSOCK: + return UBIFS_ITYPE_SOCK; + default: + BUG(); + } + return 0; +} + +/** + * pack_inode - pack an inode node. + * @c: UBIFS file-system description object + * @ino: buffer in which to pack inode node + * @inode: inode to pack + * @last: indicates the last node of the group + * @last_reference: non-zero if this is a deletion inode + */ +static void pack_inode(struct ubifs_info *c, struct ubifs_ino_node *ino, + const struct inode *inode, int last, + int last_reference) +{ + int data_len = 0; + struct ubifs_inode *ui = ubifs_inode(inode); + + ino->ch.node_type = UBIFS_INO_NODE; + ino_key_init_flash(c, &ino->key, inode->i_ino); + ino->creat_sqnum = cpu_to_le64(ui->creat_sqnum); + ino->atime_sec = cpu_to_le64(inode->i_atime.tv_sec); + ino->atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); + ino->ctime_sec = cpu_to_le64(inode->i_ctime.tv_sec); + ino->ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); + ino->mtime_sec = cpu_to_le64(inode->i_mtime.tv_sec); + ino->mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); + ino->uid = cpu_to_le32(inode->i_uid); + ino->gid = cpu_to_le32(inode->i_gid); + ino->mode = cpu_to_le32(inode->i_mode); + ino->flags = cpu_to_le32(ui->flags); + ino->size = cpu_to_le64(ui->ui_size); + ino->nlink = cpu_to_le32(inode->i_nlink); + ino->compr_type = cpu_to_le16(ui->compr_type); + ino->data_len = cpu_to_le32(ui->data_len); + ino->xattr_cnt = cpu_to_le32(ui->xattr_cnt); + ino->xattr_size = cpu_to_le32(ui->xattr_size); + ino->xattr_names = cpu_to_le32(ui->xattr_names); + zero_ino_node_unused(ino); + + /* + * Drop the attached data if this is a deletion inode, the data is not + * needed anymore. + */ + if (!last_reference) { + memcpy(ino->data, ui->data, ui->data_len); + data_len = ui->data_len; + } + + ubifs_prep_grp_node(c, ino, UBIFS_INO_NODE_SZ + data_len, last); +} + +/** + * mark_inode_clean - mark UBIFS inode as clean. + * @c: UBIFS file-system description object + * @ui: UBIFS inode to mark as clean + * + * This helper function marks UBIFS inode @ui as clean by cleaning the + * @ui->dirty flag and releasing its budget. Note, VFS may still treat the + * inode as dirty and try to write it back, but 'ubifs_write_inode()' would + * just do nothing. + */ +static void mark_inode_clean(struct ubifs_info *c, struct ubifs_inode *ui) +{ + if (ui->dirty) + ubifs_release_dirty_inode_budget(c, ui); + ui->dirty = 0; +} + +/** + * ubifs_jnl_update - update inode. + * @c: UBIFS file-system description object + * @dir: parent inode or host inode in case of extended attributes + * @nm: directory entry name + * @inode: inode to update + * @deletion: indicates a directory entry deletion i.e unlink or rmdir + * @xent: non-zero if the directory entry is an extended attribute entry + * + * This function updates an inode by writing a directory entry (or extended + * attribute entry), the inode itself, and the parent directory inode (or the + * host inode) to the journal. + * + * The function writes the host inode @dir last, which is important in case of + * extended attributes. Indeed, then we guarantee that if the host inode gets + * synchronized (with 'fsync()'), and the write-buffer it sits in gets flushed, + * the extended attribute inode gets flushed too. And this is exactly what the + * user expects - synchronizing the host inode synchronizes its extended + * attributes. Similarly, this guarantees that if @dir is synchronized, its + * directory entry corresponding to @nm gets synchronized too. + * + * If the inode (@inode) or the parent directory (@dir) are synchronous, this + * function synchronizes the write-buffer. + * + * This function marks the @dir and @inode inodes as clean and returns zero on + * success. In case of failure, a negative error code is returned. + */ +int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, + const struct qstr *nm, const struct inode *inode, + int deletion, int xent) +{ + int err, dlen, ilen, len, lnum, ino_offs, dent_offs; + int aligned_dlen, aligned_ilen, sync = IS_DIRSYNC(dir); + int last_reference = !!(deletion && inode->i_nlink == 0); + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_inode *dir_ui = ubifs_inode(dir); + struct ubifs_dent_node *dent; + struct ubifs_ino_node *ino; + union ubifs_key dent_key, ino_key; + + dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu", + inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino); + ubifs_assert(dir_ui->data_len == 0); + ubifs_assert(mutex_is_locked(&dir_ui->ui_mutex)); + + dlen = UBIFS_DENT_NODE_SZ + nm->len + 1; + ilen = UBIFS_INO_NODE_SZ; + + /* + * If the last reference to the inode is being deleted, then there is + * no need to attach and write inode data, it is being deleted anyway. + * And if the inode is being deleted, no need to synchronize + * write-buffer even if the inode is synchronous. + */ + if (!last_reference) { + ilen += ui->data_len; + sync |= IS_SYNC(inode); + } + + aligned_dlen = ALIGN(dlen, 8); + aligned_ilen = ALIGN(ilen, 8); + len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ; + dent = kmalloc(len, GFP_NOFS); + if (!dent) + return -ENOMEM; + + /* Make reservation before allocating sequence numbers */ + err = make_reservation(c, BASEHD, len); + if (err) + goto out_free; + + if (!xent) { + dent->ch.node_type = UBIFS_DENT_NODE; + dent_key_init(c, &dent_key, dir->i_ino, nm); + } else { + dent->ch.node_type = UBIFS_XENT_NODE; + xent_key_init(c, &dent_key, dir->i_ino, nm); + } + + key_write(c, &dent_key, dent->key); + dent->inum = deletion ? 0 : cpu_to_le64(inode->i_ino); + dent->type = get_dent_type(inode->i_mode); + dent->nlen = cpu_to_le16(nm->len); + memcpy(dent->name, nm->name, nm->len); + dent->name[nm->len] = '\0'; + zero_dent_node_unused(dent); + ubifs_prep_grp_node(c, dent, dlen, 0); + + ino = (void *)dent + aligned_dlen; + pack_inode(c, ino, inode, 0, last_reference); + ino = (void *)ino + aligned_ilen; + pack_inode(c, ino, dir, 1, 0); + + if (last_reference) { + err = ubifs_add_orphan(c, inode->i_ino); + if (err) { + release_head(c, BASEHD); + goto out_finish; + } + } + + err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); + if (err) + goto out_release; + if (!sync) { + struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; + + ubifs_wbuf_add_ino_nolock(wbuf, inode->i_ino); + ubifs_wbuf_add_ino_nolock(wbuf, dir->i_ino); + } + release_head(c, BASEHD); + kfree(dent); + + if (deletion) { + err = ubifs_tnc_remove_nm(c, &dent_key, nm); + if (err) + goto out_ro; + err = ubifs_add_dirt(c, lnum, dlen); + } else + err = ubifs_tnc_add_nm(c, &dent_key, lnum, dent_offs, dlen, nm); + if (err) + goto out_ro; + + /* + * Note, we do not remove the inode from TNC even if the last reference + * to it has just been deleted, because the inode may still be opened. + * Instead, the inode has been added to orphan lists and the orphan + * subsystem will take further care about it. + */ + ino_key_init(c, &ino_key, inode->i_ino); + ino_offs = dent_offs + aligned_dlen; + err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, ilen); + if (err) + goto out_ro; + + ino_key_init(c, &ino_key, dir->i_ino); + ino_offs += aligned_ilen; + err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, UBIFS_INO_NODE_SZ); + if (err) + goto out_ro; + + finish_reservation(c); + spin_lock(&ui->ui_lock); + ui->synced_i_size = ui->ui_size; + spin_unlock(&ui->ui_lock); + mark_inode_clean(c, ui); + mark_inode_clean(c, dir_ui); + return 0; + +out_finish: + finish_reservation(c); +out_free: + kfree(dent); + return err; + +out_release: + release_head(c, BASEHD); +out_ro: + ubifs_ro_mode(c, err); + if (last_reference) + ubifs_delete_orphan(c, inode->i_ino); + finish_reservation(c); + return err; +} + +/** + * ubifs_jnl_write_data - write a data node to the journal. + * @c: UBIFS file-system description object + * @inode: inode the data node belongs to + * @key: node key + * @buf: buffer to write + * @len: data length (must not exceed %UBIFS_BLOCK_SIZE) + * + * This function writes a data node to the journal. Returns %0 if the data node + * was successfully written, and a negative error code in case of failure. + */ +int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, + const union ubifs_key *key, const void *buf, int len) +{ + struct ubifs_data_node *data; + int err, lnum, offs, compr_type, out_len; + int dlen = UBIFS_DATA_NODE_SZ + UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR; + struct ubifs_inode *ui = ubifs_inode(inode); + + dbg_jnl("ino %lu, blk %u, len %d, key %s", key_inum(c, key), + key_block(c, key), len, DBGKEY(key)); + ubifs_assert(len <= UBIFS_BLOCK_SIZE); + + data = kmalloc(dlen, GFP_NOFS); + if (!data) + return -ENOMEM; + + data->ch.node_type = UBIFS_DATA_NODE; + key_write(c, key, &data->key); + data->size = cpu_to_le32(len); + zero_data_node_unused(data); + + if (!(ui->flags && UBIFS_COMPR_FL)) + /* Compression is disabled for this inode */ + compr_type = UBIFS_COMPR_NONE; + else + compr_type = ui->compr_type; + + out_len = dlen - UBIFS_DATA_NODE_SZ; + ubifs_compress(buf, len, &data->data, &out_len, &compr_type); + ubifs_assert(out_len <= UBIFS_BLOCK_SIZE); + + dlen = UBIFS_DATA_NODE_SZ + out_len; + data->compr_type = cpu_to_le16(compr_type); + + /* Make reservation before allocating sequence numbers */ + err = make_reservation(c, DATAHD, dlen); + if (err) + goto out_free; + + err = write_node(c, DATAHD, data, dlen, &lnum, &offs); + if (err) + goto out_release; + ubifs_wbuf_add_ino_nolock(&c->jheads[DATAHD].wbuf, key_inum(c, key)); + release_head(c, DATAHD); + + err = ubifs_tnc_add(c, key, lnum, offs, dlen); + if (err) + goto out_ro; + + finish_reservation(c); + kfree(data); + return 0; + +out_release: + release_head(c, DATAHD); +out_ro: + ubifs_ro_mode(c, err); + finish_reservation(c); +out_free: + kfree(data); + return err; +} + +/** + * ubifs_jnl_write_inode - flush inode to the journal. + * @c: UBIFS file-system description object + * @inode: inode to flush + * @deletion: inode has been deleted + * + * This function writes inode @inode to the journal. If the inode is + * synchronous, it also synchronizes the write-buffer. Returns zero in case of + * success and a negative error code in case of failure. + */ +int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode, + int deletion) +{ + int err, len, lnum, offs, sync = 0; + struct ubifs_ino_node *ino; + struct ubifs_inode *ui = ubifs_inode(inode); + + dbg_jnl("ino %lu%s", inode->i_ino, + deletion ? " (last reference)" : ""); + if (deletion) + ubifs_assert(inode->i_nlink == 0); + + len = UBIFS_INO_NODE_SZ; + /* + * If the inode is being deleted, do not write the attached data. No + * need to synchronize the write-buffer either. + */ + if (!deletion) { + len += ui->data_len; + sync = IS_SYNC(inode); + } + ino = kmalloc(len, GFP_NOFS); + if (!ino) + return -ENOMEM; + + /* Make reservation before allocating sequence numbers */ + err = make_reservation(c, BASEHD, len); + if (err) + goto out_free; + + pack_inode(c, ino, inode, 1, deletion); + err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); + if (err) + goto out_release; + if (!sync) + ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, + inode->i_ino); + release_head(c, BASEHD); + + if (deletion) { + err = ubifs_tnc_remove_ino(c, inode->i_ino); + if (err) + goto out_ro; + ubifs_delete_orphan(c, inode->i_ino); + err = ubifs_add_dirt(c, lnum, len); + } else { + union ubifs_key key; + + ino_key_init(c, &key, inode->i_ino); + err = ubifs_tnc_add(c, &key, lnum, offs, len); + } + if (err) + goto out_ro; + + finish_reservation(c); + spin_lock(&ui->ui_lock); + ui->synced_i_size = ui->ui_size; + spin_unlock(&ui->ui_lock); + kfree(ino); + return 0; + +out_release: + release_head(c, BASEHD); +out_ro: + ubifs_ro_mode(c, err); + finish_reservation(c); +out_free: + kfree(ino); + return err; +} + +/** + * ubifs_jnl_rename - rename a directory entry. + * @c: UBIFS file-system description object + * @old_dir: parent inode of directory entry to rename + * @old_dentry: directory entry to rename + * @new_dir: parent inode of directory entry to rename + * @new_dentry: new directory entry (or directory entry to replace) + * @sync: non-zero if the write-buffer has to be synchronized + * + * This function implements the re-name operation which may involve writing up + * to 3 inodes and 2 directory entries. It marks the written inodes as clean + * and returns zero on success. In case of failure, a negative error code is + * returned. + */ +int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, + const struct dentry *old_dentry, + const struct inode *new_dir, + const struct dentry *new_dentry, int sync) +{ + void *p; + union ubifs_key key; + struct ubifs_dent_node *dent, *dent2; + int err, dlen1, dlen2, ilen, lnum, offs, len; + const struct inode *old_inode = old_dentry->d_inode; + const struct inode *new_inode = new_dentry->d_inode; + int aligned_dlen1, aligned_dlen2, plen = UBIFS_INO_NODE_SZ; + int last_reference = !!(new_inode && new_inode->i_nlink == 0); + int move = (old_dir != new_dir); + struct ubifs_inode *uninitialized_var(new_ui); + + dbg_jnl("dent '%.*s' in dir ino %lu to dent '%.*s' in dir ino %lu", + old_dentry->d_name.len, old_dentry->d_name.name, + old_dir->i_ino, new_dentry->d_name.len, + new_dentry->d_name.name, new_dir->i_ino); + ubifs_assert(ubifs_inode(old_dir)->data_len == 0); + ubifs_assert(ubifs_inode(new_dir)->data_len == 0); + ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex)); + ubifs_assert(mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex)); + + dlen1 = UBIFS_DENT_NODE_SZ + new_dentry->d_name.len + 1; + dlen2 = UBIFS_DENT_NODE_SZ + old_dentry->d_name.len + 1; + if (new_inode) { + new_ui = ubifs_inode(new_inode); + ubifs_assert(mutex_is_locked(&new_ui->ui_mutex)); + ilen = UBIFS_INO_NODE_SZ; + if (!last_reference) + ilen += new_ui->data_len; + } else + ilen = 0; + + aligned_dlen1 = ALIGN(dlen1, 8); + aligned_dlen2 = ALIGN(dlen2, 8); + len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); + if (old_dir != new_dir) + len += plen; + dent = kmalloc(len, GFP_NOFS); + if (!dent) + return -ENOMEM; + + /* Make reservation before allocating sequence numbers */ + err = make_reservation(c, BASEHD, len); + if (err) + goto out_free; + + /* Make new dent */ + dent->ch.node_type = UBIFS_DENT_NODE; + dent_key_init_flash(c, &dent->key, new_dir->i_ino, &new_dentry->d_name); + dent->inum = cpu_to_le64(old_inode->i_ino); + dent->type = get_dent_type(old_inode->i_mode); + dent->nlen = cpu_to_le16(new_dentry->d_name.len); + memcpy(dent->name, new_dentry->d_name.name, new_dentry->d_name.len); + dent->name[new_dentry->d_name.len] = '\0'; + zero_dent_node_unused(dent); + ubifs_prep_grp_node(c, dent, dlen1, 0); + + /* Make deletion dent */ + dent2 = (void *)dent + aligned_dlen1; + dent2->ch.node_type = UBIFS_DENT_NODE; + dent_key_init_flash(c, &dent2->key, old_dir->i_ino, + &old_dentry->d_name); + dent2->inum = 0; + dent2->type = DT_UNKNOWN; + dent2->nlen = cpu_to_le16(old_dentry->d_name.len); + memcpy(dent2->name, old_dentry->d_name.name, old_dentry->d_name.len); + dent2->name[old_dentry->d_name.len] = '\0'; + zero_dent_node_unused(dent2); + ubifs_prep_grp_node(c, dent2, dlen2, 0); + + p = (void *)dent2 + aligned_dlen2; + if (new_inode) { + pack_inode(c, p, new_inode, 0, last_reference); + p += ALIGN(ilen, 8); + } + + if (!move) + pack_inode(c, p, old_dir, 1, 0); + else { + pack_inode(c, p, old_dir, 0, 0); + p += ALIGN(plen, 8); + pack_inode(c, p, new_dir, 1, 0); + } + + if (last_reference) { + err = ubifs_add_orphan(c, new_inode->i_ino); + if (err) { + release_head(c, BASEHD); + goto out_finish; + } + } + + err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); + if (err) + goto out_release; + if (!sync) { + struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; + + ubifs_wbuf_add_ino_nolock(wbuf, new_dir->i_ino); + ubifs_wbuf_add_ino_nolock(wbuf, old_dir->i_ino); + if (new_inode) + ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, + new_inode->i_ino); + } + release_head(c, BASEHD); + + dent_key_init(c, &key, new_dir->i_ino, &new_dentry->d_name); + err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen1, &new_dentry->d_name); + if (err) + goto out_ro; + + err = ubifs_add_dirt(c, lnum, dlen2); + if (err) + goto out_ro; + + dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name); + err = ubifs_tnc_remove_nm(c, &key, &old_dentry->d_name); + if (err) + goto out_ro; + + offs += aligned_dlen1 + aligned_dlen2; + if (new_inode) { + ino_key_init(c, &key, new_inode->i_ino); + err = ubifs_tnc_add(c, &key, lnum, offs, ilen); + if (err) + goto out_ro; + offs += ALIGN(ilen, 8); + } + + ino_key_init(c, &key, old_dir->i_ino); + err = ubifs_tnc_add(c, &key, lnum, offs, plen); + if (err) + goto out_ro; + + if (old_dir != new_dir) { + offs += ALIGN(plen, 8); + ino_key_init(c, &key, new_dir->i_ino); + err = ubifs_tnc_add(c, &key, lnum, offs, plen); + if (err) + goto out_ro; + } + + finish_reservation(c); + if (new_inode) { + mark_inode_clean(c, new_ui); + spin_lock(&new_ui->ui_lock); + new_ui->synced_i_size = new_ui->ui_size; + spin_unlock(&new_ui->ui_lock); + } + mark_inode_clean(c, ubifs_inode(old_dir)); + if (move) + mark_inode_clean(c, ubifs_inode(new_dir)); + kfree(dent); + return 0; + +out_release: + release_head(c, BASEHD); +out_ro: + ubifs_ro_mode(c, err); + if (last_reference) + ubifs_delete_orphan(c, new_inode->i_ino); +out_finish: + finish_reservation(c); +out_free: + kfree(dent); + return err; +} + +/** + * recomp_data_node - re-compress a truncated data node. + * @dn: data node to re-compress + * @new_len: new length + * + * This function is used when an inode is truncated and the last data node of + * the inode has to be re-compressed and re-written. + */ +static int recomp_data_node(struct ubifs_data_node *dn, int *new_len) +{ + void *buf; + int err, len, compr_type, out_len; + + out_len = le32_to_cpu(dn->size); + buf = kmalloc(out_len * WORST_COMPR_FACTOR, GFP_NOFS); + if (!buf) + return -ENOMEM; + + len = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; + compr_type = le16_to_cpu(dn->compr_type); + err = ubifs_decompress(&dn->data, len, buf, &out_len, compr_type); + if (err) + goto out; + + ubifs_compress(buf, *new_len, &dn->data, &out_len, &compr_type); + ubifs_assert(out_len <= UBIFS_BLOCK_SIZE); + dn->compr_type = cpu_to_le16(compr_type); + dn->size = cpu_to_le32(*new_len); + *new_len = UBIFS_DATA_NODE_SZ + out_len; +out: + kfree(buf); + return err; +} + +/** + * ubifs_jnl_truncate - update the journal for a truncation. + * @c: UBIFS file-system description object + * @inode: inode to truncate + * @old_size: old size + * @new_size: new size + * + * When the size of a file decreases due to truncation, a truncation node is + * written, the journal tree is updated, and the last data block is re-written + * if it has been affected. The inode is also updated in order to synchronize + * the new inode size. + * + * This function marks the inode as clean and returns zero on success. In case + * of failure, a negative error code is returned. + */ +int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, + loff_t old_size, loff_t new_size) +{ + union ubifs_key key, to_key; + struct ubifs_ino_node *ino; + struct ubifs_trun_node *trun; + struct ubifs_data_node *uninitialized_var(dn); + int err, dlen, len, lnum, offs, bit, sz, sync = IS_SYNC(inode); + struct ubifs_inode *ui = ubifs_inode(inode); + ino_t inum = inode->i_ino; + unsigned int blk; + + dbg_jnl("ino %lu, size %lld -> %lld", inum, old_size, new_size); + ubifs_assert(!ui->data_len); + ubifs_assert(S_ISREG(inode->i_mode)); + ubifs_assert(mutex_is_locked(&ui->ui_mutex)); + + sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + + UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; + ino = kmalloc(sz, GFP_NOFS); + if (!ino) + return -ENOMEM; + + trun = (void *)ino + UBIFS_INO_NODE_SZ; + trun->ch.node_type = UBIFS_TRUN_NODE; + trun->inum = cpu_to_le32(inum); + trun->old_size = cpu_to_le64(old_size); + trun->new_size = cpu_to_le64(new_size); + zero_trun_node_unused(trun); + + dlen = new_size & (UBIFS_BLOCK_SIZE - 1); + if (dlen) { + /* Get last data block so it can be truncated */ + dn = (void *)trun + UBIFS_TRUN_NODE_SZ; + blk = new_size >> UBIFS_BLOCK_SHIFT; + data_key_init(c, &key, inum, blk); + dbg_jnl("last block key %s", DBGKEY(&key)); + err = ubifs_tnc_lookup(c, &key, dn); + if (err == -ENOENT) + dlen = 0; /* Not found (so it is a hole) */ + else if (err) + goto out_free; + else { + if (le32_to_cpu(dn->size) <= dlen) + dlen = 0; /* Nothing to do */ + else { + int compr_type = le16_to_cpu(dn->compr_type); + + if (compr_type != UBIFS_COMPR_NONE) { + err = recomp_data_node(dn, &dlen); + if (err) + goto out_free; + } else { + dn->size = cpu_to_le32(dlen); + dlen += UBIFS_DATA_NODE_SZ; + } + zero_data_node_unused(dn); + } + } + } + + /* Must make reservation before allocating sequence numbers */ + len = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ; + if (dlen) + len += dlen; + err = make_reservation(c, BASEHD, len); + if (err) + goto out_free; + + pack_inode(c, ino, inode, 0, 0); + ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); + if (dlen) + ubifs_prep_grp_node(c, dn, dlen, 1); + + err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); + if (err) + goto out_release; + if (!sync) + ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, inum); + release_head(c, BASEHD); + + if (dlen) { + sz = offs + UBIFS_INO_NODE_SZ + UBIFS_TRUN_NODE_SZ; + err = ubifs_tnc_add(c, &key, lnum, sz, dlen); + if (err) + goto out_ro; + } + + ino_key_init(c, &key, inum); + err = ubifs_tnc_add(c, &key, lnum, offs, UBIFS_INO_NODE_SZ); + if (err) + goto out_ro; + + err = ubifs_add_dirt(c, lnum, UBIFS_TRUN_NODE_SZ); + if (err) + goto out_ro; + + bit = new_size & (UBIFS_BLOCK_SIZE - 1); + blk = (new_size >> UBIFS_BLOCK_SHIFT) + (bit ? 1 : 0); + data_key_init(c, &key, inum, blk); + + bit = old_size & (UBIFS_BLOCK_SIZE - 1); + blk = (old_size >> UBIFS_BLOCK_SHIFT) - (bit ? 0: 1); + data_key_init(c, &to_key, inum, blk); + + err = ubifs_tnc_remove_range(c, &key, &to_key); + if (err) + goto out_ro; + + finish_reservation(c); + spin_lock(&ui->ui_lock); + ui->synced_i_size = ui->ui_size; + spin_unlock(&ui->ui_lock); + mark_inode_clean(c, ui); + kfree(ino); + return 0; + +out_release: + release_head(c, BASEHD); +out_ro: + ubifs_ro_mode(c, err); + finish_reservation(c); +out_free: + kfree(ino); + return err; +} + +#ifdef CONFIG_UBIFS_FS_XATTR + +/** + * ubifs_jnl_delete_xattr - delete an extended attribute. + * @c: UBIFS file-system description object + * @host: host inode + * @inode: extended attribute inode + * @nm: extended attribute entry name + * + * This function delete an extended attribute which is very similar to + * un-linking regular files - it writes a deletion xentry, a deletion inode and + * updates the target inode. Returns zero in case of success and a negative + * error code in case of failure. + */ +int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, + const struct inode *inode, const struct qstr *nm) +{ + int err, xlen, hlen, len, lnum, xent_offs, aligned_xlen; + struct ubifs_dent_node *xent; + struct ubifs_ino_node *ino; + union ubifs_key xent_key, key1, key2; + int sync = IS_DIRSYNC(host); + struct ubifs_inode *host_ui = ubifs_inode(host); + + dbg_jnl("host %lu, xattr ino %lu, name '%s', data len %d", + host->i_ino, inode->i_ino, nm->name, + ubifs_inode(inode)->data_len); + ubifs_assert(inode->i_nlink == 0); + ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); + + /* + * Since we are deleting the inode, we do not bother to attach any data + * to it and assume its length is %UBIFS_INO_NODE_SZ. + */ + xlen = UBIFS_DENT_NODE_SZ + nm->len + 1; + aligned_xlen = ALIGN(xlen, 8); + hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; + len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); + + xent = kmalloc(len, GFP_NOFS); + if (!xent) + return -ENOMEM; + + /* Make reservation before allocating sequence numbers */ + err = make_reservation(c, BASEHD, len); + if (err) { + kfree(xent); + return err; + } + + xent->ch.node_type = UBIFS_XENT_NODE; + xent_key_init(c, &xent_key, host->i_ino, nm); + key_write(c, &xent_key, xent->key); + xent->inum = 0; + xent->type = get_dent_type(inode->i_mode); + xent->nlen = cpu_to_le16(nm->len); + memcpy(xent->name, nm->name, nm->len); + xent->name[nm->len] = '\0'; + zero_dent_node_unused(xent); + ubifs_prep_grp_node(c, xent, xlen, 0); + + ino = (void *)xent + aligned_xlen; + pack_inode(c, ino, inode, 0, 1); + ino = (void *)ino + UBIFS_INO_NODE_SZ; + pack_inode(c, ino, host, 1, 0); + + err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); + if (!sync && !err) + ubifs_wbuf_add_ino_nolock(&c->jheads[BASEHD].wbuf, host->i_ino); + release_head(c, BASEHD); + kfree(xent); + if (err) + goto out_ro; + + /* Remove the extended attribute entry from TNC */ + err = ubifs_tnc_remove_nm(c, &xent_key, nm); + if (err) + goto out_ro; + err = ubifs_add_dirt(c, lnum, xlen); + if (err) + goto out_ro; + + /* + * Remove all nodes belonging to the extended attribute inode from TNC. + * Well, there actually must be only one node - the inode itself. + */ + lowest_ino_key(c, &key1, inode->i_ino); + highest_ino_key(c, &key2, inode->i_ino); + err = ubifs_tnc_remove_range(c, &key1, &key2); + if (err) + goto out_ro; + err = ubifs_add_dirt(c, lnum, UBIFS_INO_NODE_SZ); + if (err) + goto out_ro; + + /* And update TNC with the new host inode position */ + ino_key_init(c, &key1, host->i_ino); + err = ubifs_tnc_add(c, &key1, lnum, xent_offs + len - hlen, hlen); + if (err) + goto out_ro; + + finish_reservation(c); + spin_lock(&host_ui->ui_lock); + host_ui->synced_i_size = host_ui->ui_size; + spin_unlock(&host_ui->ui_lock); + mark_inode_clean(c, host_ui); + return 0; + +out_ro: + ubifs_ro_mode(c, err); + finish_reservation(c); + return err; +} + +/** + * ubifs_jnl_change_xattr - change an extended attribute. + * @c: UBIFS file-system description object + * @inode: extended attribute inode + * @host: host inode + * + * This function writes the updated version of an extended attribute inode and + * the host inode tho the journal (to the base head). The host inode is written + * after the extended attribute inode in order to guarantee that the extended + * attribute will be flushed when the inode is synchronized by 'fsync()' and + * consequently, the write-buffer is synchronized. This function returns zero + * in case of success and a negative error code in case of failure. + */ +int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, + const struct inode *host) +{ + int err, len1, len2, aligned_len, aligned_len1, lnum, offs; + struct ubifs_inode *host_ui = ubifs_inode(inode); + struct ubifs_ino_node *ino; + union ubifs_key key; + int sync = IS_DIRSYNC(host); + + dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); + ubifs_assert(host->i_nlink > 0); + ubifs_assert(inode->i_nlink > 0); + ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); + + len1 = UBIFS_INO_NODE_SZ + host_ui->data_len; + len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode)->data_len; + aligned_len1 = ALIGN(len1, 8); + aligned_len = aligned_len1 + ALIGN(len2, 8); + + ino = kmalloc(aligned_len, GFP_NOFS); + if (!ino) + return -ENOMEM; + + /* Make reservation before allocating sequence numbers */ + err = make_reservation(c, BASEHD, aligned_len); + if (err) + goto out_free; + + pack_inode(c, ino, host, 0, 0); + pack_inode(c, (void *)ino + aligned_len1, inode, 1, 0); + + err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); + if (!sync && !err) { + struct ubifs_wbuf *wbuf = &c->jheads[BASEHD].wbuf; + + ubifs_wbuf_add_ino_nolock(wbuf, host->i_ino); + ubifs_wbuf_add_ino_nolock(wbuf, inode->i_ino); + } + release_head(c, BASEHD); + if (err) + goto out_ro; + + ino_key_init(c, &key, host->i_ino); + err = ubifs_tnc_add(c, &key, lnum, offs, len1); + if (err) + goto out_ro; + + ino_key_init(c, &key, inode->i_ino); + err = ubifs_tnc_add(c, &key, lnum, offs + aligned_len1, len2); + if (err) + goto out_ro; + + finish_reservation(c); + spin_lock(&host_ui->ui_lock); + host_ui->synced_i_size = host_ui->ui_size; + spin_unlock(&host_ui->ui_lock); + mark_inode_clean(c, host_ui); + kfree(ino); + return 0; + +out_ro: + ubifs_ro_mode(c, err); + finish_reservation(c); +out_free: + kfree(ino); + return err; +} + +#endif /* CONFIG_UBIFS_FS_XATTR */ diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h new file mode 100644 index 0000000..8f74760 --- /dev/null +++ b/fs/ubifs/key.h @@ -0,0 +1,533 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This header contains various key-related definitions and helper function. + * UBIFS allows several key schemes, so we access key fields only via these + * helpers. At the moment only one key scheme is supported. + * + * Simple key scheme + * ~~~~~~~~~~~~~~~~~ + * + * Keys are 64-bits long. First 32-bits are inode number (parent inode number + * in case of direntry key). Next 3 bits are node type. The last 29 bits are + * 4KiB offset in case of inode node, and direntry hash in case of a direntry + * node. We use "r5" hash borrowed from reiserfs. + */ + +#ifndef __UBIFS_KEY_H__ +#define __UBIFS_KEY_H__ + +/** + * key_r5_hash - R5 hash function (borrowed from reiserfs). + * @s: direntry name + * @len: name length + */ +static inline uint32_t key_r5_hash(const char *s, int len) +{ + uint32_t a = 0; + const signed char *str = (const signed char *)s; + + while (*str) { + a += *str << 4; + a += *str >> 4; + a *= 11; + str++; + } + + a &= UBIFS_S_KEY_HASH_MASK; + + /* + * We use hash values as offset in directories, so values %0 and %1 are + * reserved for "." and "..". %2 is reserved for "end of readdir" + * marker. + */ + if (unlikely(a >= 0 && a <= 2)) + a += 3; + return a; +} + +/** + * key_test_hash - testing hash function. + * @str: direntry name + * @len: name length + */ +static inline uint32_t key_test_hash(const char *str, int len) +{ + uint32_t a = 0; + + len = min_t(uint32_t, len, 4); + memcpy(&a, str, len); + a &= UBIFS_S_KEY_HASH_MASK; + if (unlikely(a >= 0 && a <= 2)) + a += 3; + return a; +} + +/** + * ino_key_init - initialize inode key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: inode number + */ +static inline void ino_key_init(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum) +{ + key->u32[0] = inum; + key->u32[1] = UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS; +} + +/** + * ino_key_init_flash - initialize on-flash inode key. + * @c: UBIFS file-system description object + * @k: key to initialize + * @inum: inode number + */ +static inline void ino_key_init_flash(const struct ubifs_info *c, void *k, + ino_t inum) +{ + union ubifs_key *key = k; + + key->j32[0] = cpu_to_le32(inum); + key->j32[1] = cpu_to_le32(UBIFS_INO_KEY << UBIFS_S_KEY_BLOCK_BITS); + memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); +} + +/** + * lowest_ino_key - get the lowest possible inode key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: inode number + */ +static inline void lowest_ino_key(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum) +{ + key->u32[0] = inum; + key->u32[1] = 0; +} + +/** + * highest_ino_key - get the highest possible inode key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: inode number + */ +static inline void highest_ino_key(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum) +{ + key->u32[0] = inum; + key->u32[1] = 0xffffffff; +} + +/** + * dent_key_init - initialize directory entry key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: parent inode number + * @nm: direntry name and length + */ +static inline void dent_key_init(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum, + const struct qstr *nm) +{ + uint32_t hash = c->key_hash(nm->name, nm->len); + + ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + key->u32[0] = inum; + key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); +} + +/** + * dent_key_init_hash - initialize directory entry key without re-calculating + * hash function. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: parent inode number + * @hash: direntry name hash + */ +static inline void dent_key_init_hash(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum, + uint32_t hash) +{ + ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + key->u32[0] = inum; + key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); +} + +/** + * dent_key_init_flash - initialize on-flash directory entry key. + * @c: UBIFS file-system description object + * @k: key to initialize + * @inum: parent inode number + * @nm: direntry name and length + */ +static inline void dent_key_init_flash(const struct ubifs_info *c, void *k, + ino_t inum, const struct qstr *nm) +{ + union ubifs_key *key = k; + uint32_t hash = c->key_hash(nm->name, nm->len); + + ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + key->j32[0] = cpu_to_le32(inum); + key->j32[1] = cpu_to_le32(hash | + (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS)); + memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); +} + +/** + * lowest_dent_key - get the lowest possible directory entry key. + * @c: UBIFS file-system description object + * @key: where to store the lowest key + * @inum: parent inode number + */ +static inline void lowest_dent_key(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum) +{ + key->u32[0] = inum; + key->u32[1] = UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS; +} + +/** + * xent_key_init - initialize extended attribute entry key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: host inode number + * @nm: extended attribute entry name and length + */ +static inline void xent_key_init(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum, + const struct qstr *nm) +{ + uint32_t hash = c->key_hash(nm->name, nm->len); + + ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + key->u32[0] = inum; + key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS); +} + +/** + * xent_key_init_hash - initialize extended attribute entry key without + * re-calculating hash function. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: host inode number + * @hash: extended attribute entry name hash + */ +static inline void xent_key_init_hash(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum, + uint32_t hash) +{ + ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + key->u32[0] = inum; + key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS); +} + +/** + * xent_key_init_flash - initialize on-flash extended attribute entry key. + * @c: UBIFS file-system description object + * @k: key to initialize + * @inum: host inode number + * @nm: extended attribute entry name and length + */ +static inline void xent_key_init_flash(const struct ubifs_info *c, void *k, + ino_t inum, const struct qstr *nm) +{ + union ubifs_key *key = k; + uint32_t hash = c->key_hash(nm->name, nm->len); + + ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + key->j32[0] = cpu_to_le32(inum); + key->j32[1] = cpu_to_le32(hash | + (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS)); + memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); +} + +/** + * lowest_xent_key - get the lowest possible extended attribute entry key. + * @c: UBIFS file-system description object + * @key: where to store the lowest key + * @inum: host inode number + */ +static inline void lowest_xent_key(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum) +{ + key->u32[0] = inum; + key->u32[1] = UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS; +} + +/** + * data_key_init - initialize data key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: inode number + * @block: block number + */ +static inline void data_key_init(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum, + unsigned int block) +{ + ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK)); + key->u32[0] = inum; + key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS); +} + +/** + * data_key_init_flash - initialize on-flash data key. + * @c: UBIFS file-system description object + * @k: key to initialize + * @inum: inode number + * @block: block number + */ +static inline void data_key_init_flash(const struct ubifs_info *c, void *k, + ino_t inum, unsigned int block) +{ + union ubifs_key *key = k; + + ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK)); + key->j32[0] = cpu_to_le32(inum); + key->j32[1] = cpu_to_le32(block | + (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS)); + memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); +} + +/** + * trun_key_init - initialize truncation node key. + * @c: UBIFS file-system description object + * @key: key to initialize + * @inum: inode number + * + * Note, UBIFS does not have truncation keys on the media and this function is + * only used for purposes of replay. + */ +static inline void trun_key_init(const struct ubifs_info *c, + union ubifs_key *key, ino_t inum) +{ + key->u32[0] = inum; + key->u32[1] = UBIFS_TRUN_KEY << UBIFS_S_KEY_BLOCK_BITS; +} + +/** + * key_type - get key type. + * @c: UBIFS file-system description object + * @key: key to get type of + */ +static inline int key_type(const struct ubifs_info *c, + const union ubifs_key *key) +{ + return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS; +} + +/** + * key_type_flash - get type of a on-flash formatted key. + * @c: UBIFS file-system description object + * @k: key to get type of + */ +static inline int key_type_flash(const struct ubifs_info *c, const void *k) +{ + const union ubifs_key *key = k; + + return le32_to_cpu(key->u32[1]) >> UBIFS_S_KEY_BLOCK_BITS; +} + +/** + * key_inum - fetch inode number from key. + * @c: UBIFS file-system description object + * @k: key to fetch inode number from + */ +static inline ino_t key_inum(const struct ubifs_info *c, const void *k) +{ + const union ubifs_key *key = k; + + return key->u32[0]; +} + +/** + * key_inum_flash - fetch inode number from an on-flash formatted key. + * @c: UBIFS file-system description object + * @k: key to fetch inode number from + */ +static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k) +{ + const union ubifs_key *key = k; + + return le32_to_cpu(key->j32[0]); +} + +/** + * key_hash - get directory entry hash. + * @c: UBIFS file-system description object + * @key: the key to get hash from + */ +static inline int key_hash(const struct ubifs_info *c, + const union ubifs_key *key) +{ + return key->u32[1] & UBIFS_S_KEY_HASH_MASK; +} + +/** + * key_hash_flash - get directory entry hash from an on-flash formatted key. + * @c: UBIFS file-system description object + * @k: the key to get hash from + */ +static inline int key_hash_flash(const struct ubifs_info *c, const void *k) +{ + const union ubifs_key *key = k; + + return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_HASH_MASK; +} + +/** + * key_block - get data block number. + * @c: UBIFS file-system description object + * @key: the key to get the block number from + */ +static inline unsigned int key_block(const struct ubifs_info *c, + const union ubifs_key *key) +{ + return key->u32[1] & UBIFS_S_KEY_BLOCK_MASK; +} + +/** + * key_block_flash - get data block number from an on-flash formatted key. + * @c: UBIFS file-system description object + * @k: the key to get the block number from + */ +static inline unsigned int key_block_flash(const struct ubifs_info *c, + const void *k) +{ + const union ubifs_key *key = k; + + return le32_to_cpu(key->u32[1]) & UBIFS_S_KEY_BLOCK_MASK; +} + +/** + * key_read - transform a key to in-memory format. + * @c: UBIFS file-system description object + * @from: the key to transform + * @to: the key to store the result + */ +static inline void key_read(const struct ubifs_info *c, const void *from, + union ubifs_key *to) +{ + const union ubifs_key *f = from; + + to->u32[0] = le32_to_cpu(f->j32[0]); + to->u32[1] = le32_to_cpu(f->j32[1]); +} + +/** + * key_write - transform a key from in-memory format. + * @c: UBIFS file-system description object + * @from: the key to transform + * @to: the key to store the result + */ +static inline void key_write(const struct ubifs_info *c, + const union ubifs_key *from, void *to) +{ + union ubifs_key *t = to; + + t->j32[0] = cpu_to_le32(from->u32[0]); + t->j32[1] = cpu_to_le32(from->u32[1]); + memset(to + 8, 0, UBIFS_MAX_KEY_LEN - 8); +} + +/** + * key_write_idx - transform a key from in-memory format for the index. + * @c: UBIFS file-system description object + * @from: the key to transform + * @to: the key to store the result + */ +static inline void key_write_idx(const struct ubifs_info *c, + const union ubifs_key *from, void *to) +{ + union ubifs_key *t = to; + + t->j32[0] = cpu_to_le32(from->u32[0]); + t->j32[1] = cpu_to_le32(from->u32[1]); +} + +/** + * key_copy - copy a key. + * @c: UBIFS file-system description object + * @from: the key to copy from + * @to: the key to copy to + */ +static inline void key_copy(const struct ubifs_info *c, + const union ubifs_key *from, union ubifs_key *to) +{ + to->u64[0] = from->u64[0]; +} + +/** + * keys_cmp - compare keys. + * @c: UBIFS file-system description object + * @key1: the first key to compare + * @key2: the second key to compare + * + * This function compares 2 keys and returns %-1 if @key1 is less than + * @key2, 0 if the keys are equivalent and %1 if @key1 is greater than @key2. + */ +static inline int keys_cmp(const struct ubifs_info *c, + const union ubifs_key *key1, + const union ubifs_key *key2) +{ + if (key1->u32[0] < key2->u32[0]) + return -1; + if (key1->u32[0] > key2->u32[0]) + return 1; + if (key1->u32[1] < key2->u32[1]) + return -1; + if (key1->u32[1] > key2->u32[1]) + return 1; + + return 0; +} + +/** + * is_hash_key - is a key vulnerable to hash collisions. + * @c: UBIFS file-system description object + * @key: key + * + * This function returns %1 if @key is a hashed key or %0 otherwise. + */ +static inline int is_hash_key(const struct ubifs_info *c, + const union ubifs_key *key) +{ + int type = key_type(c, key); + + return type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY; +} + +/** + * key_max_inode_size - get maximum file size allowed by current key format. + * @c: UBIFS file-system description object + */ +static inline unsigned long long key_max_inode_size(const struct ubifs_info *c) +{ + switch (c->key_fmt) { + case UBIFS_SIMPLE_KEY_FMT: + return (1ULL << UBIFS_S_KEY_BLOCK_BITS) * UBIFS_BLOCK_SIZE; + default: + return 0; + } +} +#endif /* !__UBIFS_KEY_H__ */ diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c new file mode 100644 index 0000000..36857b9 --- /dev/null +++ b/fs/ubifs/log.c @@ -0,0 +1,805 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file is a part of UBIFS journal implementation and contains various + * functions which manipulate the log. The log is a fixed area on the flash + * which does not contain any data but refers to buds. The log is a part of the + * journal. + */ + +#include "ubifs.h" + +#ifdef CONFIG_UBIFS_FS_DEBUG +static int dbg_check_bud_bytes(struct ubifs_info *c); +#else +#define dbg_check_bud_bytes(c) 0 +#endif + +/** + * ubifs_search_bud - search bud LEB. + * @c: UBIFS file-system description object + * @lnum: logical eraseblock number to search + * + * This function searches bud LEB @lnum. Returns bud description object in case + * of success and %NULL if there is no bud with this LEB number. + */ +struct ubifs_bud *ubifs_search_bud(struct ubifs_info *c, int lnum) +{ + struct rb_node *p; + struct ubifs_bud *bud; + + spin_lock(&c->buds_lock); + p = c->buds.rb_node; + while (p) { + bud = rb_entry(p, struct ubifs_bud, rb); + if (lnum < bud->lnum) + p = p->rb_left; + else if (lnum > bud->lnum) + p = p->rb_right; + else { + spin_unlock(&c->buds_lock); + return bud; + } + } + spin_unlock(&c->buds_lock); + return NULL; +} + +/** + * ubifs_get_wbuf - get the wbuf associated with a LEB, if there is one. + * @c: UBIFS file-system description object + * @lnum: logical eraseblock number to search + * + * This functions returns the wbuf for @lnum or %NULL if there is not one. + */ +struct ubifs_wbuf *ubifs_get_wbuf(struct ubifs_info *c, int lnum) +{ + struct rb_node *p; + struct ubifs_bud *bud; + int jhead; + + if (!c->jheads) + return NULL; + + spin_lock(&c->buds_lock); + p = c->buds.rb_node; + while (p) { + bud = rb_entry(p, struct ubifs_bud, rb); + if (lnum < bud->lnum) + p = p->rb_left; + else if (lnum > bud->lnum) + p = p->rb_right; + else { + jhead = bud->jhead; + spin_unlock(&c->buds_lock); + return &c->jheads[jhead].wbuf; + } + } + spin_unlock(&c->buds_lock); + return NULL; +} + +/** + * next_log_lnum - switch to the next log LEB. + * @c: UBIFS file-system description object + * @lnum: current log LEB + */ +static inline int next_log_lnum(const struct ubifs_info *c, int lnum) +{ + lnum += 1; + if (lnum > c->log_last) + lnum = UBIFS_LOG_LNUM; + + return lnum; +} + +/** + * empty_log_bytes - calculate amount of empty space in the log. + * @c: UBIFS file-system description object + */ +static inline long long empty_log_bytes(const struct ubifs_info *c) +{ + long long h, t; + + h = (long long)c->lhead_lnum * c->leb_size + c->lhead_offs; + t = (long long)c->ltail_lnum * c->leb_size; + + if (h >= t) + return c->log_bytes - h + t; + else + return t - h; +} + +/** + * ubifs_add_bud - add bud LEB to the tree of buds and its journal head list. + * @c: UBIFS file-system description object + * @bud: the bud to add + */ +void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud) +{ + struct rb_node **p, *parent = NULL; + struct ubifs_bud *b; + struct ubifs_jhead *jhead; + + spin_lock(&c->buds_lock); + p = &c->buds.rb_node; + while (*p) { + parent = *p; + b = rb_entry(parent, struct ubifs_bud, rb); + ubifs_assert(bud->lnum != b->lnum); + if (bud->lnum < b->lnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + rb_link_node(&bud->rb, parent, p); + rb_insert_color(&bud->rb, &c->buds); + if (c->jheads) { + jhead = &c->jheads[bud->jhead]; + list_add_tail(&bud->list, &jhead->buds_list); + } else + ubifs_assert(c->replaying && (c->vfs_sb->s_flags & MS_RDONLY)); + + /* + * Note, although this is a new bud, we anyway account this space now, + * before any data has been written to it, because this is about to + * guarantee fixed mount time, and this bud will anyway be read and + * scanned. + */ + c->bud_bytes += c->leb_size - bud->start; + + dbg_log("LEB %d:%d, jhead %d, bud_bytes %lld", bud->lnum, + bud->start, bud->jhead, c->bud_bytes); + spin_unlock(&c->buds_lock); +} + +/** + * ubifs_create_buds_lists - create journal head buds lists for remount rw. + * @c: UBIFS file-system description object + */ +void ubifs_create_buds_lists(struct ubifs_info *c) +{ + struct rb_node *p; + + spin_lock(&c->buds_lock); + p = rb_first(&c->buds); + while (p) { + struct ubifs_bud *bud = rb_entry(p, struct ubifs_bud, rb); + struct ubifs_jhead *jhead = &c->jheads[bud->jhead]; + + list_add_tail(&bud->list, &jhead->buds_list); + p = rb_next(p); + } + spin_unlock(&c->buds_lock); +} + +/** + * ubifs_add_bud_to_log - add a new bud to the log. + * @c: UBIFS file-system description object + * @jhead: journal head the bud belongs to + * @lnum: LEB number of the bud + * @offs: starting offset of the bud + * + * This function writes reference node for the new bud LEB @lnum it to the log, + * and adds it to the buds tress. It also makes sure that log size does not + * exceed the 'c->max_bud_bytes' limit. Returns zero in case of success, + * %-EAGAIN if commit is required, and a negative error codes in case of + * failure. + */ +int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) +{ + int err; + struct ubifs_bud *bud; + struct ubifs_ref_node *ref; + + bud = kmalloc(sizeof(struct ubifs_bud), GFP_NOFS); + if (!bud) + return -ENOMEM; + ref = kzalloc(c->ref_node_alsz, GFP_NOFS); + if (!ref) { + kfree(bud); + return -ENOMEM; + } + + mutex_lock(&c->log_mutex); + + if (c->ro_media) { + err = -EROFS; + goto out_unlock; + } + + /* Make sure we have enough space in the log */ + if (empty_log_bytes(c) - c->ref_node_alsz < c->min_log_bytes) { + dbg_log("not enough log space - %lld, required %d", + empty_log_bytes(c), c->min_log_bytes); + ubifs_commit_required(c); + err = -EAGAIN; + goto out_unlock; + } + + /* + * Make sure the the amount of space in buds will not exceed + * 'c->max_bud_bytes' limit, because we want to guarantee mount time + * limits. + * + * It is not necessary to hold @c->buds_lock when reading @c->bud_bytes + * because we are holding @c->log_mutex. All @c->bud_bytes take place + * when both @c->log_mutex and @c->bud_bytes are locked. + */ + if (c->bud_bytes + c->leb_size - offs > c->max_bud_bytes) { + dbg_log("bud bytes %lld (%lld max), require commit", + c->bud_bytes, c->max_bud_bytes); + ubifs_commit_required(c); + err = -EAGAIN; + goto out_unlock; + } + + /* + * If the journal is full enough - start background commit. Note, it is + * OK to read 'c->cmt_state' without spinlock because integer reads + * are atomic in the kernel. + */ + if (c->bud_bytes >= c->bg_bud_bytes && + c->cmt_state == COMMIT_RESTING) { + dbg_log("bud bytes %lld (%lld max), initiate BG commit", + c->bud_bytes, c->max_bud_bytes); + ubifs_request_bg_commit(c); + } + + bud->lnum = lnum; + bud->start = offs; + bud->jhead = jhead; + + ref->ch.node_type = UBIFS_REF_NODE; + ref->lnum = cpu_to_le32(bud->lnum); + ref->offs = cpu_to_le32(bud->start); + ref->jhead = cpu_to_le32(jhead); + + if (c->lhead_offs > c->leb_size - c->ref_node_alsz) { + c->lhead_lnum = next_log_lnum(c, c->lhead_lnum); + c->lhead_offs = 0; + } + + if (c->lhead_offs == 0) { + /* Must ensure next log LEB has been unmapped */ + err = ubifs_leb_unmap(c, c->lhead_lnum); + if (err) + goto out_unlock; + } + + if (bud->start == 0) { + /* + * Before writing the LEB reference which refers an empty LEB + * to the log, we have to make sure it is mapped, because + * otherwise we'd risk to refer an LEB with garbage in case of + * an unclean reboot, because the target LEB might have been + * unmapped, but not yet physically erased. + */ + err = ubi_leb_map(c->ubi, bud->lnum, UBI_SHORTTERM); + if (err) + goto out_unlock; + } + + dbg_log("write ref LEB %d:%d", + c->lhead_lnum, c->lhead_offs); + err = ubifs_write_node(c, ref, UBIFS_REF_NODE_SZ, c->lhead_lnum, + c->lhead_offs, UBI_SHORTTERM); + if (err) + goto out_unlock; + + c->lhead_offs += c->ref_node_alsz; + + ubifs_add_bud(c, bud); + + mutex_unlock(&c->log_mutex); + kfree(ref); + return 0; + +out_unlock: + mutex_unlock(&c->log_mutex); + kfree(ref); + kfree(bud); + return err; +} + +/** + * remove_buds - remove used buds. + * @c: UBIFS file-system description object + * + * This function removes use buds from the buds tree. It does not remove the + * buds which are pointed to by journal heads. + */ +static void remove_buds(struct ubifs_info *c) +{ + struct rb_node *p; + + ubifs_assert(list_empty(&c->old_buds)); + c->cmt_bud_bytes = 0; + spin_lock(&c->buds_lock); + p = rb_first(&c->buds); + while (p) { + struct rb_node *p1 = p; + struct ubifs_bud *bud; + struct ubifs_wbuf *wbuf; + + p = rb_next(p); + bud = rb_entry(p1, struct ubifs_bud, rb); + wbuf = &c->jheads[bud->jhead].wbuf; + + if (wbuf->lnum == bud->lnum) { + /* + * Do not remove buds which are pointed to by journal + * heads (non-closed buds). + */ + c->cmt_bud_bytes += wbuf->offs - bud->start; + dbg_log("preserve %d:%d, jhead %d, bud bytes %d, " + "cmt_bud_bytes %lld", bud->lnum, bud->start, + bud->jhead, wbuf->offs - bud->start, + c->cmt_bud_bytes); + bud->start = wbuf->offs; + } else { + c->cmt_bud_bytes += c->leb_size - bud->start; + dbg_log("remove %d:%d, jhead %d, bud bytes %d, " + "cmt_bud_bytes %lld", bud->lnum, bud->start, + bud->jhead, c->leb_size - bud->start, + c->cmt_bud_bytes); + rb_erase(p1, &c->buds); + list_del(&bud->list); + /* + * If the commit does not finish, the recovery will need + * to replay the journal, in which case the old buds + * must be unchanged. Do not release them until post + * commit i.e. do not allow them to be garbage + * collected. + */ + list_add(&bud->list, &c->old_buds); + } + } + spin_unlock(&c->buds_lock); +} + +/** + * ubifs_log_start_commit - start commit. + * @c: UBIFS file-system description object + * @ltail_lnum: return new log tail LEB number + * + * The commit operation starts with writing "commit start" node to the log and + * reference nodes for all journal heads which will define new journal after + * the commit has been finished. The commit start and reference nodes are + * written in one go to the nearest empty log LEB (hence, when commit is + * finished UBIFS may safely unmap all the previous log LEBs). This function + * returns zero in case of success and a negative error code in case of + * failure. + */ +int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) +{ + void *buf; + struct ubifs_cs_node *cs; + struct ubifs_ref_node *ref; + int err, i, max_len, len; + + err = dbg_check_bud_bytes(c); + if (err) + return err; + + max_len = UBIFS_CS_NODE_SZ + c->jhead_cnt * UBIFS_REF_NODE_SZ; + max_len = ALIGN(max_len, c->min_io_size); + buf = cs = kmalloc(max_len, GFP_NOFS); + if (!buf) + return -ENOMEM; + + cs->ch.node_type = UBIFS_CS_NODE; + cs->cmt_no = cpu_to_le64(c->cmt_no + 1); + ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); + + /* + * Note, we do not lock 'c->log_mutex' because this is the commit start + * phase and we are exclusively using the log. And we do not lock + * write-buffer because nobody can write to the file-system at this + * phase. + */ + + len = UBIFS_CS_NODE_SZ; + for (i = 0; i < c->jhead_cnt; i++) { + int lnum = c->jheads[i].wbuf.lnum; + int offs = c->jheads[i].wbuf.offs; + + if (lnum == -1 || offs == c->leb_size) + continue; + + dbg_log("add ref to LEB %d:%d for jhead %d", lnum, offs, i); + ref = buf + len; + ref->ch.node_type = UBIFS_REF_NODE; + ref->lnum = cpu_to_le32(lnum); + ref->offs = cpu_to_le32(offs); + ref->jhead = cpu_to_le32(i); + + ubifs_prepare_node(c, ref, UBIFS_REF_NODE_SZ, 0); + len += UBIFS_REF_NODE_SZ; + } + + ubifs_pad(c, buf + len, ALIGN(len, c->min_io_size) - len); + + /* Switch to the next log LEB */ + if (c->lhead_offs) { + c->lhead_lnum = next_log_lnum(c, c->lhead_lnum); + c->lhead_offs = 0; + } + + if (c->lhead_offs == 0) { + /* Must ensure next LEB has been unmapped */ + err = ubifs_leb_unmap(c, c->lhead_lnum); + if (err) + goto out; + } + + len = ALIGN(len, c->min_io_size); + dbg_log("writing commit start at LEB %d:0, len %d", c->lhead_lnum, len); + err = ubifs_leb_write(c, c->lhead_lnum, cs, 0, len, UBI_SHORTTERM); + if (err) + goto out; + + *ltail_lnum = c->lhead_lnum; + + c->lhead_offs += len; + if (c->lhead_offs == c->leb_size) { + c->lhead_lnum = next_log_lnum(c, c->lhead_lnum); + c->lhead_offs = 0; + } + + remove_buds(c); + + /* + * We have started the commit and now users may use the rest of the log + * for new writes. + */ + c->min_log_bytes = 0; + +out: + kfree(buf); + return err; +} + +/** + * ubifs_log_end_commit - end commit. + * @c: UBIFS file-system description object + * @ltail_lnum: new log tail LEB number + * + * This function is called on when the commit operation was finished. It + * moves log tail to new position and unmaps LEBs which contain obsolete data. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum) +{ + int err; + + /* + * At this phase we have to lock 'c->log_mutex' because UBIFS allows FS + * writes during commit. Its only short "commit" start phase when + * writers are blocked. + */ + mutex_lock(&c->log_mutex); + + dbg_log("old tail was LEB %d:0, new tail is LEB %d:0", + c->ltail_lnum, ltail_lnum); + + c->ltail_lnum = ltail_lnum; + /* + * The commit is finished and from now on it must be guaranteed that + * there is always enough space for the next commit. + */ + c->min_log_bytes = c->leb_size; + + spin_lock(&c->buds_lock); + c->bud_bytes -= c->cmt_bud_bytes; + spin_unlock(&c->buds_lock); + + err = dbg_check_bud_bytes(c); + + mutex_unlock(&c->log_mutex); + return err; +} + +/** + * ubifs_log_post_commit - things to do after commit is completed. + * @c: UBIFS file-system description object + * @old_ltail_lnum: old log tail LEB number + * + * Release buds only after commit is completed, because they must be unchanged + * if recovery is needed. + * + * Unmap log LEBs only after commit is completed, because they may be needed for + * recovery. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum) +{ + int lnum, err = 0; + + while (!list_empty(&c->old_buds)) { + struct ubifs_bud *bud; + + bud = list_entry(c->old_buds.next, struct ubifs_bud, list); + err = ubifs_return_leb(c, bud->lnum); + if (err) + return err; + list_del(&bud->list); + kfree(bud); + } + mutex_lock(&c->log_mutex); + for (lnum = old_ltail_lnum; lnum != c->ltail_lnum; + lnum = next_log_lnum(c, lnum)) { + dbg_log("unmap log LEB %d", lnum); + err = ubifs_leb_unmap(c, lnum); + if (err) + goto out; + } +out: + mutex_unlock(&c->log_mutex); + return err; +} + +/** + * struct done_ref - references that have been done. + * @rb: rb-tree node + * @lnum: LEB number + */ +struct done_ref { + struct rb_node rb; + int lnum; +}; + +/** + * done_already - determine if a reference has been done already. + * @done_tree: rb-tree to store references that have been done + * @lnum: LEB number of reference + * + * This function returns %1 if the reference has been done, %0 if not, otherwise + * a negative error code is returned. + */ +static int done_already(struct rb_root *done_tree, int lnum) +{ + struct rb_node **p = &done_tree->rb_node, *parent = NULL; + struct done_ref *dr; + + while (*p) { + parent = *p; + dr = rb_entry(parent, struct done_ref, rb); + if (lnum < dr->lnum) + p = &(*p)->rb_left; + else if (lnum > dr->lnum) + p = &(*p)->rb_right; + else + return 1; + } + + dr = kzalloc(sizeof(struct done_ref), GFP_NOFS); + if (!dr) + return -ENOMEM; + + dr->lnum = lnum; + + rb_link_node(&dr->rb, parent, p); + rb_insert_color(&dr->rb, done_tree); + + return 0; +} + +/** + * destroy_done_tree - destroy the done tree. + * @done_tree: done tree to destroy + */ +static void destroy_done_tree(struct rb_root *done_tree) +{ + struct rb_node *this = done_tree->rb_node; + struct done_ref *dr; + + while (this) { + if (this->rb_left) { + this = this->rb_left; + continue; + } else if (this->rb_right) { + this = this->rb_right; + continue; + } + dr = rb_entry(this, struct done_ref, rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &dr->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + kfree(dr); + } +} + +/** + * add_node - add a node to the consolidated log. + * @c: UBIFS file-system description object + * @buf: buffer to which to add + * @lnum: LEB number to which to write is passed and returned here + * @offs: offset to where to write is passed and returned here + * @node: node to add + * + * This function returns %0 on success and a negative error code on failure. + */ +static int add_node(struct ubifs_info *c, void *buf, int *lnum, int *offs, + void *node) +{ + struct ubifs_ch *ch = node; + int len = le32_to_cpu(ch->len), remains = c->leb_size - *offs; + + if (len > remains) { + int sz = ALIGN(*offs, c->min_io_size), err; + + ubifs_pad(c, buf + *offs, sz - *offs); + err = ubifs_leb_change(c, *lnum, buf, sz, UBI_SHORTTERM); + if (err) + return err; + *lnum = next_log_lnum(c, *lnum); + *offs = 0; + } + memcpy(buf + *offs, node, len); + *offs += ALIGN(len, 8); + return 0; +} + +/** + * ubifs_consolidate_log - consolidate the log. + * @c: UBIFS file-system description object + * + * Repeated failed commits could cause the log to be full, but at least 1 LEB is + * needed for commit. This function rewrites the reference nodes in the log + * omitting duplicates, and failed CS nodes, and leaving no gaps. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_consolidate_log(struct ubifs_info *c) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + struct rb_root done_tree = RB_ROOT; + int lnum, err, first = 1, write_lnum, offs = 0; + void *buf; + + dbg_rcvry("log tail LEB %d, log head LEB %d", c->ltail_lnum, + c->lhead_lnum); + buf = vmalloc(c->leb_size); + if (!buf) + return -ENOMEM; + lnum = c->ltail_lnum; + write_lnum = lnum; + while (1) { + sleb = ubifs_scan(c, lnum, 0, c->sbuf); + if (IS_ERR(sleb)) { + err = PTR_ERR(sleb); + goto out_free; + } + list_for_each_entry(snod, &sleb->nodes, list) { + switch (snod->type) { + case UBIFS_REF_NODE: { + struct ubifs_ref_node *ref = snod->node; + int ref_lnum = le32_to_cpu(ref->lnum); + + err = done_already(&done_tree, ref_lnum); + if (err < 0) + goto out_scan; + if (err != 1) { + err = add_node(c, buf, &write_lnum, + &offs, snod->node); + if (err) + goto out_scan; + } + break; + } + case UBIFS_CS_NODE: + if (!first) + break; + err = add_node(c, buf, &write_lnum, &offs, + snod->node); + if (err) + goto out_scan; + first = 0; + break; + } + } + ubifs_scan_destroy(sleb); + if (lnum == c->lhead_lnum) + break; + lnum = next_log_lnum(c, lnum); + } + if (offs) { + int sz = ALIGN(offs, c->min_io_size); + + ubifs_pad(c, buf + offs, sz - offs); + err = ubifs_leb_change(c, write_lnum, buf, sz, UBI_SHORTTERM); + if (err) + goto out_free; + offs = ALIGN(offs, c->min_io_size); + } + destroy_done_tree(&done_tree); + vfree(buf); + if (write_lnum == c->lhead_lnum) { + ubifs_err("log is too full"); + return -EINVAL; + } + /* Unmap remaining LEBs */ + lnum = write_lnum; + do { + lnum = next_log_lnum(c, lnum); + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } while (lnum != c->lhead_lnum); + c->lhead_lnum = write_lnum; + c->lhead_offs = offs; + dbg_rcvry("new log head at %d:%d", c->lhead_lnum, c->lhead_offs); + return 0; + +out_scan: + ubifs_scan_destroy(sleb); +out_free: + destroy_done_tree(&done_tree); + vfree(buf); + return err; +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +/** + * dbg_check_bud_bytes - make sure bud bytes calculation are all right. + * @c: UBIFS file-system description object + * + * This function makes sure the amount of flash space used by closed buds + * ('c->bud_bytes' is correct). Returns zero in case of success and %-EINVAL in + * case of failure. + */ +static int dbg_check_bud_bytes(struct ubifs_info *c) +{ + int i, err = 0; + struct ubifs_bud *bud; + long long bud_bytes = 0; + + if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) + return 0; + + spin_lock(&c->buds_lock); + for (i = 0; i < c->jhead_cnt; i++) + list_for_each_entry(bud, &c->jheads[i].buds_list, list) + bud_bytes += c->leb_size - bud->start; + + if (c->bud_bytes != bud_bytes) { + ubifs_err("bad bud_bytes %lld, calculated %lld", + c->bud_bytes, bud_bytes); + err = -EINVAL; + } + spin_unlock(&c->buds_lock); + + return err; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c new file mode 100644 index 0000000..2ba93da --- /dev/null +++ b/fs/ubifs/lprops.c @@ -0,0 +1,1357 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements the functions that access LEB properties and their + * categories. LEBs are categorized based on the needs of UBIFS, and the + * categories are stored as either heaps or lists to provide a fast way of + * finding a LEB in a particular category. For example, UBIFS may need to find + * an empty LEB for the journal, or a very dirty LEB for garbage collection. + */ + +#include "ubifs.h" + +/** + * get_heap_comp_val - get the LEB properties value for heap comparisons. + * @lprops: LEB properties + * @cat: LEB category + */ +static int get_heap_comp_val(struct ubifs_lprops *lprops, int cat) +{ + switch (cat) { + case LPROPS_FREE: + return lprops->free; + case LPROPS_DIRTY_IDX: + return lprops->free + lprops->dirty; + default: + return lprops->dirty; + } +} + +/** + * move_up_lpt_heap - move a new heap entry up as far as possible. + * @c: UBIFS file-system description object + * @heap: LEB category heap + * @lprops: LEB properties to move + * @cat: LEB category + * + * New entries to a heap are added at the bottom and then moved up until the + * parent's value is greater. In the case of LPT's category heaps, the value + * is either the amount of free space or the amount of dirty space, depending + * on the category. + */ +static void move_up_lpt_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, + struct ubifs_lprops *lprops, int cat) +{ + int val1, val2, hpos; + + hpos = lprops->hpos; + if (!hpos) + return; /* Already top of the heap */ + val1 = get_heap_comp_val(lprops, cat); + /* Compare to parent and, if greater, move up the heap */ + do { + int ppos = (hpos - 1) / 2; + + val2 = get_heap_comp_val(heap->arr[ppos], cat); + if (val2 >= val1) + return; + /* Greater than parent so move up */ + heap->arr[ppos]->hpos = hpos; + heap->arr[hpos] = heap->arr[ppos]; + heap->arr[ppos] = lprops; + lprops->hpos = ppos; + hpos = ppos; + } while (hpos); +} + +/** + * adjust_lpt_heap - move a changed heap entry up or down the heap. + * @c: UBIFS file-system description object + * @heap: LEB category heap + * @lprops: LEB properties to move + * @hpos: heap position of @lprops + * @cat: LEB category + * + * Changed entries in a heap are moved up or down until the parent's value is + * greater. In the case of LPT's category heaps, the value is either the amount + * of free space or the amount of dirty space, depending on the category. + */ +static void adjust_lpt_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, + struct ubifs_lprops *lprops, int hpos, int cat) +{ + int val1, val2, val3, cpos; + + val1 = get_heap_comp_val(lprops, cat); + /* Compare to parent and, if greater than parent, move up the heap */ + if (hpos) { + int ppos = (hpos - 1) / 2; + + val2 = get_heap_comp_val(heap->arr[ppos], cat); + if (val1 > val2) { + /* Greater than parent so move up */ + while (1) { + heap->arr[ppos]->hpos = hpos; + heap->arr[hpos] = heap->arr[ppos]; + heap->arr[ppos] = lprops; + lprops->hpos = ppos; + hpos = ppos; + if (!hpos) + return; + ppos = (hpos - 1) / 2; + val2 = get_heap_comp_val(heap->arr[ppos], cat); + if (val1 <= val2) + return; + /* Still greater than parent so keep going */ + } + } + } + /* Not greater than parent, so compare to children */ + while (1) { + /* Compare to left child */ + cpos = hpos * 2 + 1; + if (cpos >= heap->cnt) + return; + val2 = get_heap_comp_val(heap->arr[cpos], cat); + if (val1 < val2) { + /* Less than left child, so promote biggest child */ + if (cpos + 1 < heap->cnt) { + val3 = get_heap_comp_val(heap->arr[cpos + 1], + cat); + if (val3 > val2) + cpos += 1; /* Right child is bigger */ + } + heap->arr[cpos]->hpos = hpos; + heap->arr[hpos] = heap->arr[cpos]; + heap->arr[cpos] = lprops; + lprops->hpos = cpos; + hpos = cpos; + continue; + } + /* Compare to right child */ + cpos += 1; + if (cpos >= heap->cnt) + return; + val3 = get_heap_comp_val(heap->arr[cpos], cat); + if (val1 < val3) { + /* Less than right child, so promote right child */ + heap->arr[cpos]->hpos = hpos; + heap->arr[hpos] = heap->arr[cpos]; + heap->arr[cpos] = lprops; + lprops->hpos = cpos; + hpos = cpos; + continue; + } + return; + } +} + +/** + * add_to_lpt_heap - add LEB properties to a LEB category heap. + * @c: UBIFS file-system description object + * @lprops: LEB properties to add + * @cat: LEB category + * + * This function returns %1 if @lprops is added to the heap for LEB category + * @cat, otherwise %0 is returned because the heap is full. + */ +static int add_to_lpt_heap(struct ubifs_info *c, struct ubifs_lprops *lprops, + int cat) +{ + struct ubifs_lpt_heap *heap = &c->lpt_heap[cat - 1]; + + if (heap->cnt >= heap->max_cnt) { + const int b = LPT_HEAP_SZ / 2 - 1; + int cpos, val1, val2; + + /* Compare to some other LEB on the bottom of heap */ + /* Pick a position kind of randomly */ + cpos = (((size_t)lprops >> 4) & b) + b; + ubifs_assert(cpos >= b); + ubifs_assert(cpos < LPT_HEAP_SZ); + ubifs_assert(cpos < heap->cnt); + + val1 = get_heap_comp_val(lprops, cat); + val2 = get_heap_comp_val(heap->arr[cpos], cat); + if (val1 > val2) { + struct ubifs_lprops *lp; + + lp = heap->arr[cpos]; + lp->flags &= ~LPROPS_CAT_MASK; + lp->flags |= LPROPS_UNCAT; + list_add(&lp->list, &c->uncat_list); + lprops->hpos = cpos; + heap->arr[cpos] = lprops; + move_up_lpt_heap(c, heap, lprops, cat); + dbg_check_heap(c, heap, cat, lprops->hpos); + return 1; /* Added to heap */ + } + dbg_check_heap(c, heap, cat, -1); + return 0; /* Not added to heap */ + } else { + lprops->hpos = heap->cnt++; + heap->arr[lprops->hpos] = lprops; + move_up_lpt_heap(c, heap, lprops, cat); + dbg_check_heap(c, heap, cat, lprops->hpos); + return 1; /* Added to heap */ + } +} + +/** + * remove_from_lpt_heap - remove LEB properties from a LEB category heap. + * @c: UBIFS file-system description object + * @lprops: LEB properties to remove + * @cat: LEB category + */ +static void remove_from_lpt_heap(struct ubifs_info *c, + struct ubifs_lprops *lprops, int cat) +{ + struct ubifs_lpt_heap *heap; + int hpos = lprops->hpos; + + heap = &c->lpt_heap[cat - 1]; + ubifs_assert(hpos >= 0 && hpos < heap->cnt); + ubifs_assert(heap->arr[hpos] == lprops); + heap->cnt -= 1; + if (hpos < heap->cnt) { + heap->arr[hpos] = heap->arr[heap->cnt]; + heap->arr[hpos]->hpos = hpos; + adjust_lpt_heap(c, heap, heap->arr[hpos], hpos, cat); + } + dbg_check_heap(c, heap, cat, -1); +} + +/** + * lpt_heap_replace - replace lprops in a category heap. + * @c: UBIFS file-system description object + * @old_lprops: LEB properties to replace + * @new_lprops: LEB properties with which to replace + * @cat: LEB category + * + * During commit it is sometimes necessary to copy a pnode (see dirty_cow_pnode) + * and the lprops that the pnode contains. When that happens, references in + * the category heaps to those lprops must be updated to point to the new + * lprops. This function does that. + */ +static void lpt_heap_replace(struct ubifs_info *c, + struct ubifs_lprops *old_lprops, + struct ubifs_lprops *new_lprops, int cat) +{ + struct ubifs_lpt_heap *heap; + int hpos = new_lprops->hpos; + + heap = &c->lpt_heap[cat - 1]; + heap->arr[hpos] = new_lprops; +} + +/** + * ubifs_add_to_cat - add LEB properties to a category list or heap. + * @c: UBIFS file-system description object + * @lprops: LEB properties to add + * @cat: LEB category to which to add + * + * LEB properties are categorized to enable fast find operations. + */ +void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, + int cat) +{ + switch (cat) { + case LPROPS_DIRTY: + case LPROPS_DIRTY_IDX: + case LPROPS_FREE: + if (add_to_lpt_heap(c, lprops, cat)) + break; + /* No more room on heap so make it uncategorized */ + cat = LPROPS_UNCAT; + /* Fall through */ + case LPROPS_UNCAT: + list_add(&lprops->list, &c->uncat_list); + break; + case LPROPS_EMPTY: + list_add(&lprops->list, &c->empty_list); + break; + case LPROPS_FREEABLE: + list_add(&lprops->list, &c->freeable_list); + c->freeable_cnt += 1; + break; + case LPROPS_FRDI_IDX: + list_add(&lprops->list, &c->frdi_idx_list); + break; + default: + ubifs_assert(0); + } + lprops->flags &= ~LPROPS_CAT_MASK; + lprops->flags |= cat; +} + +/** + * ubifs_remove_from_cat - remove LEB properties from a category list or heap. + * @c: UBIFS file-system description object + * @lprops: LEB properties to remove + * @cat: LEB category from which to remove + * + * LEB properties are categorized to enable fast find operations. + */ +static void ubifs_remove_from_cat(struct ubifs_info *c, + struct ubifs_lprops *lprops, int cat) +{ + switch (cat) { + case LPROPS_DIRTY: + case LPROPS_DIRTY_IDX: + case LPROPS_FREE: + remove_from_lpt_heap(c, lprops, cat); + break; + case LPROPS_FREEABLE: + c->freeable_cnt -= 1; + ubifs_assert(c->freeable_cnt >= 0); + /* Fall through */ + case LPROPS_UNCAT: + case LPROPS_EMPTY: + case LPROPS_FRDI_IDX: + ubifs_assert(!list_empty(&lprops->list)); + list_del(&lprops->list); + break; + default: + ubifs_assert(0); + } +} + +/** + * ubifs_replace_cat - replace lprops in a category list or heap. + * @c: UBIFS file-system description object + * @old_lprops: LEB properties to replace + * @new_lprops: LEB properties with which to replace + * + * During commit it is sometimes necessary to copy a pnode (see dirty_cow_pnode) + * and the lprops that the pnode contains. When that happens, references in + * category lists and heaps must be replaced. This function does that. + */ +void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops, + struct ubifs_lprops *new_lprops) +{ + int cat; + + cat = new_lprops->flags & LPROPS_CAT_MASK; + switch (cat) { + case LPROPS_DIRTY: + case LPROPS_DIRTY_IDX: + case LPROPS_FREE: + lpt_heap_replace(c, old_lprops, new_lprops, cat); + break; + case LPROPS_UNCAT: + case LPROPS_EMPTY: + case LPROPS_FREEABLE: + case LPROPS_FRDI_IDX: + list_replace(&old_lprops->list, &new_lprops->list); + break; + default: + ubifs_assert(0); + } +} + +/** + * ubifs_ensure_cat - ensure LEB properties are categorized. + * @c: UBIFS file-system description object + * @lprops: LEB properties + * + * A LEB may have fallen off of the bottom of a heap, and ended up as + * uncategorized even though it has enough space for us now. If that is the case + * this function will put the LEB back onto a heap. + */ +void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops) +{ + int cat = lprops->flags & LPROPS_CAT_MASK; + + if (cat != LPROPS_UNCAT) + return; + cat = ubifs_categorize_lprops(c, lprops); + if (cat == LPROPS_UNCAT) + return; + ubifs_remove_from_cat(c, lprops, LPROPS_UNCAT); + ubifs_add_to_cat(c, lprops, cat); +} + +/** + * ubifs_categorize_lprops - categorize LEB properties. + * @c: UBIFS file-system description object + * @lprops: LEB properties to categorize + * + * LEB properties are categorized to enable fast find operations. This function + * returns the LEB category to which the LEB properties belong. Note however + * that if the LEB category is stored as a heap and the heap is full, the + * LEB properties may have their category changed to %LPROPS_UNCAT. + */ +int ubifs_categorize_lprops(const struct ubifs_info *c, + const struct ubifs_lprops *lprops) +{ + if (lprops->flags & LPROPS_TAKEN) + return LPROPS_UNCAT; + + if (lprops->free == c->leb_size) { + ubifs_assert(!(lprops->flags & LPROPS_INDEX)); + return LPROPS_EMPTY; + } + + if (lprops->free + lprops->dirty == c->leb_size) { + if (lprops->flags & LPROPS_INDEX) + return LPROPS_FRDI_IDX; + else + return LPROPS_FREEABLE; + } + + if (lprops->flags & LPROPS_INDEX) { + if (lprops->dirty + lprops->free >= c->min_idx_node_sz) + return LPROPS_DIRTY_IDX; + } else { + if (lprops->dirty >= c->dead_wm && + lprops->dirty > lprops->free) + return LPROPS_DIRTY; + if (lprops->free > 0) + return LPROPS_FREE; + } + + return LPROPS_UNCAT; +} + +/** + * change_category - change LEB properties category. + * @c: UBIFS file-system description object + * @lprops: LEB properties to recategorize + * + * LEB properties are categorized to enable fast find operations. When the LEB + * properties change they must be recategorized. + */ +static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops) +{ + int old_cat = lprops->flags & LPROPS_CAT_MASK; + int new_cat = ubifs_categorize_lprops(c, lprops); + + if (old_cat == new_cat) { + struct ubifs_lpt_heap *heap = &c->lpt_heap[new_cat - 1]; + + /* lprops on a heap now must be moved up or down */ + if (new_cat < 1 || new_cat > LPROPS_HEAP_CNT) + return; /* Not on a heap */ + heap = &c->lpt_heap[new_cat - 1]; + adjust_lpt_heap(c, heap, lprops, lprops->hpos, new_cat); + } else { + ubifs_remove_from_cat(c, lprops, old_cat); + ubifs_add_to_cat(c, lprops, new_cat); + } +} + +/** + * ubifs_get_lprops - get reference to LEB properties. + * @c: the UBIFS file-system description object + * + * This function locks lprops. Lprops have to be unlocked by + * 'ubifs_release_lprops()'. + */ +void ubifs_get_lprops(struct ubifs_info *c) +{ + mutex_lock(&c->lp_mutex); +} + +/** + * calc_dark - calculate LEB dark space size. + * @c: the UBIFS file-system description object + * @spc: amount of free and dirty space in the LEB + * + * This function calculates amount of dark space in an LEB which has @spc bytes + * of free and dirty space. Returns the calculations result. + * + * Dark space is the space which is not always usable - it depends on which + * nodes are written in which order. E.g., if an LEB has only 512 free bytes, + * it is dark space, because it cannot fit a large data node. So UBIFS cannot + * count on this LEB and treat these 512 bytes as usable because it is not true + * if, for example, only big chunks of uncompressible data will be written to + * the FS. + */ +static int calc_dark(struct ubifs_info *c, int spc) +{ + ubifs_assert(!(spc & 7)); + + if (spc < c->dark_wm) + return spc; + + /* + * If we have slightly more space then the dark space watermark, we can + * anyway safely assume it we'll be able to write a node of the + * smallest size there. + */ + if (spc - c->dark_wm < MIN_WRITE_SZ) + return spc - MIN_WRITE_SZ; + + return c->dark_wm; +} + +/** + * is_lprops_dirty - determine if LEB properties are dirty. + * @c: the UBIFS file-system description object + * @lprops: LEB properties to test + */ +static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops) +{ + struct ubifs_pnode *pnode; + int pos; + + pos = (lprops->lnum - c->main_first) & (UBIFS_LPT_FANOUT - 1); + pnode = (struct ubifs_pnode *)container_of(lprops - pos, + struct ubifs_pnode, + lprops[0]); + return !test_bit(COW_ZNODE, &pnode->flags) && + test_bit(DIRTY_CNODE, &pnode->flags); +} + +/** + * ubifs_change_lp - change LEB properties. + * @c: the UBIFS file-system description object + * @lp: LEB properties to change + * @free: new free space amount + * @dirty: new dirty space amount + * @flags: new flags + * @idx_gc_cnt: change to the count of idx_gc list + * + * This function changes LEB properties. This function does not change a LEB + * property (@free, @dirty or @flag) if the value passed is %LPROPS_NC. + * + * This function returns a pointer to the updated LEB properties on success + * and a negative error code on failure. N.B. the LEB properties may have had to + * be copied (due to COW) and consequently the pointer returned may not be the + * same as the pointer passed. + */ +const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, + const struct ubifs_lprops *lp, + int free, int dirty, int flags, + int idx_gc_cnt) +{ + /* + * This is the only function that is allowed to change lprops, so we + * discard the const qualifier. + */ + struct ubifs_lprops *lprops = (struct ubifs_lprops *)lp; + + dbg_lp("LEB %d, free %d, dirty %d, flags %d", + lprops->lnum, free, dirty, flags); + + ubifs_assert(mutex_is_locked(&c->lp_mutex)); + ubifs_assert(c->lst.empty_lebs >= 0 && + c->lst.empty_lebs <= c->main_lebs); + ubifs_assert(c->freeable_cnt >= 0); + ubifs_assert(c->freeable_cnt <= c->main_lebs); + ubifs_assert(c->lst.taken_empty_lebs >= 0); + ubifs_assert(c->lst.taken_empty_lebs <= c->lst.empty_lebs); + ubifs_assert(!(c->lst.total_free & 7) && !(c->lst.total_dirty & 7)); + ubifs_assert(!(c->lst.total_dead & 7) && !(c->lst.total_dark & 7)); + ubifs_assert(!(c->lst.total_used & 7)); + ubifs_assert(free == LPROPS_NC || free >= 0); + ubifs_assert(dirty == LPROPS_NC || dirty >= 0); + + if (!is_lprops_dirty(c, lprops)) { + lprops = ubifs_lpt_lookup_dirty(c, lprops->lnum); + if (IS_ERR(lprops)) + return lprops; + } else + ubifs_assert(lprops == ubifs_lpt_lookup_dirty(c, lprops->lnum)); + + ubifs_assert(!(lprops->free & 7) && !(lprops->dirty & 7)); + + spin_lock(&c->space_lock); + + if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size) + c->lst.taken_empty_lebs -= 1; + + if (!(lprops->flags & LPROPS_INDEX)) { + int old_spc; + + old_spc = lprops->free + lprops->dirty; + if (old_spc < c->dead_wm) + c->lst.total_dead -= old_spc; + else + c->lst.total_dark -= calc_dark(c, old_spc); + + c->lst.total_used -= c->leb_size - old_spc; + } + + if (free != LPROPS_NC) { + free = ALIGN(free, 8); + c->lst.total_free += free - lprops->free; + + /* Increase or decrease empty LEBs counter if needed */ + if (free == c->leb_size) { + if (lprops->free != c->leb_size) + c->lst.empty_lebs += 1; + } else if (lprops->free == c->leb_size) + c->lst.empty_lebs -= 1; + lprops->free = free; + } + + if (dirty != LPROPS_NC) { + dirty = ALIGN(dirty, 8); + c->lst.total_dirty += dirty - lprops->dirty; + lprops->dirty = dirty; + } + + if (flags != LPROPS_NC) { + /* Take care about indexing LEBs counter if needed */ + if ((lprops->flags & LPROPS_INDEX)) { + if (!(flags & LPROPS_INDEX)) + c->lst.idx_lebs -= 1; + } else if (flags & LPROPS_INDEX) + c->lst.idx_lebs += 1; + lprops->flags = flags; + } + + if (!(lprops->flags & LPROPS_INDEX)) { + int new_spc; + + new_spc = lprops->free + lprops->dirty; + if (new_spc < c->dead_wm) + c->lst.total_dead += new_spc; + else + c->lst.total_dark += calc_dark(c, new_spc); + + c->lst.total_used += c->leb_size - new_spc; + } + + if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size) + c->lst.taken_empty_lebs += 1; + + change_category(c, lprops); + + c->idx_gc_cnt += idx_gc_cnt; + + spin_unlock(&c->space_lock); + + return lprops; +} + +/** + * ubifs_release_lprops - release lprops lock. + * @c: the UBIFS file-system description object + * + * This function has to be called after each 'ubifs_get_lprops()' call to + * unlock lprops. + */ +void ubifs_release_lprops(struct ubifs_info *c) +{ + ubifs_assert(mutex_is_locked(&c->lp_mutex)); + ubifs_assert(c->lst.empty_lebs >= 0 && + c->lst.empty_lebs <= c->main_lebs); + + mutex_unlock(&c->lp_mutex); +} + +/** + * ubifs_get_lp_stats - get lprops statistics. + * @c: UBIFS file-system description object + * @st: return statistics + */ +void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *st) +{ + spin_lock(&c->space_lock); + memcpy(st, &c->lst, sizeof(struct ubifs_lp_stats)); + spin_unlock(&c->space_lock); +} + +/** + * ubifs_change_one_lp - change LEB properties. + * @c: the UBIFS file-system description object + * @lnum: LEB to change properties for + * @free: amount of free space + * @dirty: amount of dirty space + * @flags_set: flags to set + * @flags_clean: flags to clean + * @idx_gc_cnt: change to the count of idx_gc list + * + * This function changes properties of LEB @lnum. It is a helper wrapper over + * 'ubifs_change_lp()' which hides lprops get/release. The arguments are the + * same as in case of 'ubifs_change_lp()'. Returns zero in case of success and + * a negative error code in case of failure. + */ +int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, + int flags_set, int flags_clean, int idx_gc_cnt) +{ + int err = 0, flags; + const struct ubifs_lprops *lp; + + ubifs_get_lprops(c); + + lp = ubifs_lpt_lookup_dirty(c, lnum); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + + flags = (lp->flags | flags_set) & ~flags_clean; + lp = ubifs_change_lp(c, lp, free, dirty, flags, idx_gc_cnt); + if (IS_ERR(lp)) + err = PTR_ERR(lp); + +out: + ubifs_release_lprops(c); + return err; +} + +/** + * ubifs_update_one_lp - update LEB properties. + * @c: the UBIFS file-system description object + * @lnum: LEB to change properties for + * @free: amount of free space + * @dirty: amount of dirty space to add + * @flags_set: flags to set + * @flags_clean: flags to clean + * + * This function is the same as 'ubifs_change_one_lp()' but @dirty is added to + * current dirty space, not substitutes it. + */ +int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, + int flags_set, int flags_clean) +{ + int err = 0, flags; + const struct ubifs_lprops *lp; + + ubifs_get_lprops(c); + + lp = ubifs_lpt_lookup_dirty(c, lnum); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + + flags = (lp->flags | flags_set) & ~flags_clean; + lp = ubifs_change_lp(c, lp, free, lp->dirty + dirty, flags, 0); + if (IS_ERR(lp)) + err = PTR_ERR(lp); + +out: + ubifs_release_lprops(c); + return err; +} + +/** + * ubifs_read_one_lp - read LEB properties. + * @c: the UBIFS file-system description object + * @lnum: LEB to read properties for + * @lp: where to store read properties + * + * This helper function reads properties of a LEB @lnum and stores them in @lp. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp) +{ + int err = 0; + const struct ubifs_lprops *lpp; + + ubifs_get_lprops(c); + + lpp = ubifs_lpt_lookup(c, lnum); + if (IS_ERR(lpp)) { + err = PTR_ERR(lpp); + goto out; + } + + memcpy(lp, lpp, sizeof(struct ubifs_lprops)); + +out: + ubifs_release_lprops(c); + return err; +} + +/** + * ubifs_fast_find_free - try to find a LEB with free space quickly. + * @c: the UBIFS file-system description object + * + * This function returns LEB properties for a LEB with free space or %NULL if + * the function is unable to find a LEB quickly. + */ +const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + struct ubifs_lpt_heap *heap; + + ubifs_assert(mutex_is_locked(&c->lp_mutex)); + + heap = &c->lpt_heap[LPROPS_FREE - 1]; + if (heap->cnt == 0) + return NULL; + + lprops = heap->arr[0]; + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert(!(lprops->flags & LPROPS_INDEX)); + return lprops; +} + +/** + * ubifs_fast_find_empty - try to find an empty LEB quickly. + * @c: the UBIFS file-system description object + * + * This function returns LEB properties for an empty LEB or %NULL if the + * function is unable to find an empty LEB quickly. + */ +const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + + ubifs_assert(mutex_is_locked(&c->lp_mutex)); + + if (list_empty(&c->empty_list)) + return NULL; + + lprops = list_entry(c->empty_list.next, struct ubifs_lprops, list); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert(!(lprops->flags & LPROPS_INDEX)); + ubifs_assert(lprops->free == c->leb_size); + return lprops; +} + +/** + * ubifs_fast_find_freeable - try to find a freeable LEB quickly. + * @c: the UBIFS file-system description object + * + * This function returns LEB properties for a freeable LEB or %NULL if the + * function is unable to find a freeable LEB quickly. + */ +const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + + ubifs_assert(mutex_is_locked(&c->lp_mutex)); + + if (list_empty(&c->freeable_list)) + return NULL; + + lprops = list_entry(c->freeable_list.next, struct ubifs_lprops, list); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert(!(lprops->flags & LPROPS_INDEX)); + ubifs_assert(lprops->free + lprops->dirty == c->leb_size); + ubifs_assert(c->freeable_cnt > 0); + return lprops; +} + +/** + * ubifs_fast_find_frdi_idx - try to find a freeable index LEB quickly. + * @c: the UBIFS file-system description object + * + * This function returns LEB properties for a freeable index LEB or %NULL if the + * function is unable to find a freeable index LEB quickly. + */ +const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + + ubifs_assert(mutex_is_locked(&c->lp_mutex)); + + if (list_empty(&c->frdi_idx_list)) + return NULL; + + lprops = list_entry(c->frdi_idx_list.next, struct ubifs_lprops, list); + ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); + ubifs_assert((lprops->flags & LPROPS_INDEX)); + ubifs_assert(lprops->free + lprops->dirty == c->leb_size); + return lprops; +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +/** + * dbg_check_cats - check category heaps and lists. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +int dbg_check_cats(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + struct list_head *pos; + int i, cat; + + if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS))) + return 0; + + list_for_each_entry(lprops, &c->empty_list, list) { + if (lprops->free != c->leb_size) { + ubifs_err("non-empty LEB %d on empty list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + if (lprops->flags & LPROPS_TAKEN) { + ubifs_err("taken LEB %d on empty list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + } + + i = 0; + list_for_each_entry(lprops, &c->freeable_list, list) { + if (lprops->free + lprops->dirty != c->leb_size) { + ubifs_err("non-freeable LEB %d on freeable list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + if (lprops->flags & LPROPS_TAKEN) { + ubifs_err("taken LEB %d on freeable list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + i += 1; + } + if (i != c->freeable_cnt) { + ubifs_err("freeable list count %d expected %d", i, + c->freeable_cnt); + return -EINVAL; + } + + i = 0; + list_for_each(pos, &c->idx_gc) + i += 1; + if (i != c->idx_gc_cnt) { + ubifs_err("idx_gc list count %d expected %d", i, + c->idx_gc_cnt); + return -EINVAL; + } + + list_for_each_entry(lprops, &c->frdi_idx_list, list) { + if (lprops->free + lprops->dirty != c->leb_size) { + ubifs_err("non-freeable LEB %d on frdi_idx list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + if (lprops->flags & LPROPS_TAKEN) { + ubifs_err("taken LEB %d on frdi_idx list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + if (!(lprops->flags & LPROPS_INDEX)) { + ubifs_err("non-index LEB %d on frdi_idx list " + "(free %d dirty %d flags %d)", lprops->lnum, + lprops->free, lprops->dirty, lprops->flags); + return -EINVAL; + } + } + + for (cat = 1; cat <= LPROPS_HEAP_CNT; cat++) { + struct ubifs_lpt_heap *heap = &c->lpt_heap[cat - 1]; + + for (i = 0; i < heap->cnt; i++) { + lprops = heap->arr[i]; + if (!lprops) { + ubifs_err("null ptr in LPT heap cat %d", cat); + return -EINVAL; + } + if (lprops->hpos != i) { + ubifs_err("bad ptr in LPT heap cat %d", cat); + return -EINVAL; + } + if (lprops->flags & LPROPS_TAKEN) { + ubifs_err("taken LEB in LPT heap cat %d", cat); + return -EINVAL; + } + } + } + + return 0; +} + +void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, + int add_pos) +{ + int i = 0, j, err = 0; + + if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS))) + return; + + for (i = 0; i < heap->cnt; i++) { + struct ubifs_lprops *lprops = heap->arr[i]; + struct ubifs_lprops *lp; + + if (i != add_pos) + if ((lprops->flags & LPROPS_CAT_MASK) != cat) { + err = 1; + goto out; + } + if (lprops->hpos != i) { + err = 2; + goto out; + } + lp = ubifs_lpt_lookup(c, lprops->lnum); + if (IS_ERR(lp)) { + err = 3; + goto out; + } + if (lprops != lp) { + dbg_msg("lprops %zx lp %zx lprops->lnum %d lp->lnum %d", + (size_t)lprops, (size_t)lp, lprops->lnum, + lp->lnum); + err = 4; + goto out; + } + for (j = 0; j < i; j++) { + lp = heap->arr[j]; + if (lp == lprops) { + err = 5; + goto out; + } + if (lp->lnum == lprops->lnum) { + err = 6; + goto out; + } + } + } +out: + if (err) { + dbg_msg("failed cat %d hpos %d err %d", cat, i, err); + dbg_dump_stack(); + dbg_dump_heap(c, heap, cat); + } +} + +/** + * struct scan_check_data - data provided to scan callback function. + * @lst: LEB properties statistics + * @err: error code + */ +struct scan_check_data { + struct ubifs_lp_stats lst; + int err; +}; + +/** + * scan_check_cb - scan callback. + * @c: the UBIFS file-system description object + * @lp: LEB properties to scan + * @in_tree: whether the LEB properties are in main memory + * @data: information passed to and from the caller of the scan + * + * This function returns a code that indicates whether the scan should continue + * (%LPT_SCAN_CONTINUE), whether the LEB properties should be added to the tree + * in main memory (%LPT_SCAN_ADD), or whether the scan should stop + * (%LPT_SCAN_STOP). + */ +static int scan_check_cb(struct ubifs_info *c, + const struct ubifs_lprops *lp, int in_tree, + struct scan_check_data *data) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + struct ubifs_lp_stats *lst = &data->lst; + int cat, lnum = lp->lnum, is_idx = 0, used = 0, free, dirty; + + cat = lp->flags & LPROPS_CAT_MASK; + if (cat != LPROPS_UNCAT) { + cat = ubifs_categorize_lprops(c, lp); + if (cat != (lp->flags & LPROPS_CAT_MASK)) { + ubifs_err("bad LEB category %d expected %d", + (lp->flags & LPROPS_CAT_MASK), cat); + goto out; + } + } + + /* Check lp is on its category list (if it has one) */ + if (in_tree) { + struct list_head *list = NULL; + + switch (cat) { + case LPROPS_EMPTY: + list = &c->empty_list; + break; + case LPROPS_FREEABLE: + list = &c->freeable_list; + break; + case LPROPS_FRDI_IDX: + list = &c->frdi_idx_list; + break; + case LPROPS_UNCAT: + list = &c->uncat_list; + break; + } + if (list) { + struct ubifs_lprops *lprops; + int found = 0; + + list_for_each_entry(lprops, list, list) { + if (lprops == lp) { + found = 1; + break; + } + } + if (!found) { + ubifs_err("bad LPT list (category %d)", cat); + goto out; + } + } + } + + /* Check lp is on its category heap (if it has one) */ + if (in_tree && cat > 0 && cat <= LPROPS_HEAP_CNT) { + struct ubifs_lpt_heap *heap = &c->lpt_heap[cat - 1]; + + if ((lp->hpos != -1 && heap->arr[lp->hpos]->lnum != lnum) || + lp != heap->arr[lp->hpos]) { + ubifs_err("bad LPT heap (category %d)", cat); + goto out; + } + } + + sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); + if (IS_ERR(sleb)) { + /* + * After an unclean unmount, empty and freeable LEBs + * may contain garbage. + */ + if (lp->free == c->leb_size) { + ubifs_err("scan errors were in empty LEB " + "- continuing checking"); + lst->empty_lebs += 1; + lst->total_free += c->leb_size; + lst->total_dark += calc_dark(c, c->leb_size); + return LPT_SCAN_CONTINUE; + } + + if (lp->free + lp->dirty == c->leb_size && + !(lp->flags & LPROPS_INDEX)) { + ubifs_err("scan errors were in freeable LEB " + "- continuing checking"); + lst->total_free += lp->free; + lst->total_dirty += lp->dirty; + lst->total_dark += calc_dark(c, c->leb_size); + return LPT_SCAN_CONTINUE; + } + data->err = PTR_ERR(sleb); + return LPT_SCAN_STOP; + } + + is_idx = -1; + list_for_each_entry(snod, &sleb->nodes, list) { + int found, level = 0; + + cond_resched(); + + if (is_idx == -1) + is_idx = (snod->type == UBIFS_IDX_NODE) ? 1 : 0; + + if (is_idx && snod->type != UBIFS_IDX_NODE) { + ubifs_err("indexing node in data LEB %d:%d", + lnum, snod->offs); + goto out_destroy; + } + + if (snod->type == UBIFS_IDX_NODE) { + struct ubifs_idx_node *idx = snod->node; + + key_read(c, ubifs_idx_key(c, idx), &snod->key); + level = le16_to_cpu(idx->level); + } + + found = ubifs_tnc_has_node(c, &snod->key, level, lnum, + snod->offs, is_idx); + if (found) { + if (found < 0) + goto out_destroy; + used += ALIGN(snod->len, 8); + } + } + + free = c->leb_size - sleb->endpt; + dirty = sleb->endpt - used; + + if (free > c->leb_size || free < 0 || dirty > c->leb_size || + dirty < 0) { + ubifs_err("bad calculated accounting for LEB %d: " + "free %d, dirty %d", lnum, free, dirty); + goto out_destroy; + } + + if (lp->free + lp->dirty == c->leb_size && + free + dirty == c->leb_size) + if ((is_idx && !(lp->flags & LPROPS_INDEX)) || + (!is_idx && free == c->leb_size) || + lp->free == c->leb_size) { + /* + * Empty or freeable LEBs could contain index + * nodes from an uncompleted commit due to an + * unclean unmount. Or they could be empty for + * the same reason. Or it may simply not have been + * unmapped. + */ + free = lp->free; + dirty = lp->dirty; + is_idx = 0; + } + + if (is_idx && lp->free + lp->dirty == free + dirty && + lnum != c->ihead_lnum) { + /* + * After an unclean unmount, an index LEB could have a different + * amount of free space than the value recorded by lprops. That + * is because the in-the-gaps method may use free space or + * create free space (as a side-effect of using ubi_leb_change + * and not writing the whole LEB). The incorrect free space + * value is not a problem because the index is only ever + * allocated empty LEBs, so there will never be an attempt to + * write to the free space at the end of an index LEB - except + * by the in-the-gaps method for which it is not a problem. + */ + free = lp->free; + dirty = lp->dirty; + } + + if (lp->free != free || lp->dirty != dirty) + goto out_print; + + if (is_idx && !(lp->flags & LPROPS_INDEX)) { + if (free == c->leb_size) + /* Free but not unmapped LEB, it's fine */ + is_idx = 0; + else { + ubifs_err("indexing node without indexing " + "flag"); + goto out_print; + } + } + + if (!is_idx && (lp->flags & LPROPS_INDEX)) { + ubifs_err("data node with indexing flag"); + goto out_print; + } + + if (free == c->leb_size) + lst->empty_lebs += 1; + + if (is_idx) + lst->idx_lebs += 1; + + if (!(lp->flags & LPROPS_INDEX)) + lst->total_used += c->leb_size - free - dirty; + lst->total_free += free; + lst->total_dirty += dirty; + + if (!(lp->flags & LPROPS_INDEX)) { + int spc = free + dirty; + + if (spc < c->dead_wm) + lst->total_dead += spc; + else + lst->total_dark += calc_dark(c, spc); + } + + ubifs_scan_destroy(sleb); + + return LPT_SCAN_CONTINUE; + +out_print: + ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, " + "should be free %d, dirty %d", + lnum, lp->free, lp->dirty, lp->flags, free, dirty); + dbg_dump_leb(c, lnum); +out_destroy: + ubifs_scan_destroy(sleb); +out: + data->err = -EINVAL; + return LPT_SCAN_STOP; +} + +/** + * dbg_check_lprops - check all LEB properties. + * @c: UBIFS file-system description object + * + * This function checks all LEB properties and makes sure they are all correct. + * It returns zero if everything is fine, %-EINVAL if there is an inconsistency + * and other negative error codes in case of other errors. This function is + * called while the file system is locked (because of commit start), so no + * additional locking is required. Note that locking the LPT mutex would cause + * a circular lock dependency with the TNC mutex. + */ +int dbg_check_lprops(struct ubifs_info *c) +{ + int i, err; + struct scan_check_data data; + struct ubifs_lp_stats *lst = &data.lst; + + if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) + return 0; + + /* + * As we are going to scan the media, the write buffers have to be + * synchronized. + */ + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + return err; + } + + memset(lst, 0, sizeof(struct ubifs_lp_stats)); + + data.err = 0; + err = ubifs_lpt_scan_nolock(c, c->main_first, c->leb_cnt - 1, + (ubifs_lpt_scan_callback)scan_check_cb, + &data); + if (err && err != -ENOSPC) + goto out; + if (data.err) { + err = data.err; + goto out; + } + + if (lst->empty_lebs != c->lst.empty_lebs || + lst->idx_lebs != c->lst.idx_lebs || + lst->total_free != c->lst.total_free || + lst->total_dirty != c->lst.total_dirty || + lst->total_used != c->lst.total_used) { + ubifs_err("bad overall accounting"); + ubifs_err("calculated: empty_lebs %d, idx_lebs %d, " + "total_free %lld, total_dirty %lld, total_used %lld", + lst->empty_lebs, lst->idx_lebs, lst->total_free, + lst->total_dirty, lst->total_used); + ubifs_err("read from lprops: empty_lebs %d, idx_lebs %d, " + "total_free %lld, total_dirty %lld, total_used %lld", + c->lst.empty_lebs, c->lst.idx_lebs, c->lst.total_free, + c->lst.total_dirty, c->lst.total_used); + err = -EINVAL; + goto out; + } + + if (lst->total_dead != c->lst.total_dead || + lst->total_dark != c->lst.total_dark) { + ubifs_err("bad dead/dark space accounting"); + ubifs_err("calculated: total_dead %lld, total_dark %lld", + lst->total_dead, lst->total_dark); + ubifs_err("read from lprops: total_dead %lld, total_dark %lld", + c->lst.total_dead, c->lst.total_dark); + err = -EINVAL; + goto out; + } + + err = dbg_check_cats(c); +out: + return err; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c new file mode 100644 index 0000000..9ff2463 --- /dev/null +++ b/fs/ubifs/lpt.c @@ -0,0 +1,2243 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements the LEB properties tree (LPT) area. The LPT area + * contains the LEB properties tree, a table of LPT area eraseblocks (ltab), and + * (for the "big" model) a table of saved LEB numbers (lsave). The LPT area sits + * between the log and the orphan area. + * + * The LPT area is like a miniature self-contained file system. It is required + * that it never runs out of space, is fast to access and update, and scales + * logarithmically. The LEB properties tree is implemented as a wandering tree + * much like the TNC, and the LPT area has its own garbage collection. + * + * The LPT has two slightly different forms called the "small model" and the + * "big model". The small model is used when the entire LEB properties table + * can be written into a single eraseblock. In that case, garbage collection + * consists of just writing the whole table, which therefore makes all other + * eraseblocks reusable. In the case of the big model, dirty eraseblocks are + * selected for garbage collection, which consists are marking the nodes in + * that LEB as dirty, and then only the dirty nodes are written out. Also, in + * the case of the big model, a table of LEB numbers is saved so that the entire + * LPT does not to be scanned looking for empty eraseblocks when UBIFS is first + * mounted. + */ + +#include +#include "ubifs.h" + +/** + * do_calc_lpt_geom - calculate sizes for the LPT area. + * @c: the UBIFS file-system description object + * + * Calculate the sizes of LPT bit fields, nodes, and tree, based on the + * properties of the flash and whether LPT is "big" (c->big_lpt). + */ +static void do_calc_lpt_geom(struct ubifs_info *c) +{ + int i, n, bits, per_leb_wastage, max_pnode_cnt; + long long sz, tot_wastage; + + n = c->main_lebs + c->max_leb_cnt - c->leb_cnt; + max_pnode_cnt = DIV_ROUND_UP(n, UBIFS_LPT_FANOUT); + + c->lpt_hght = 1; + n = UBIFS_LPT_FANOUT; + while (n < max_pnode_cnt) { + c->lpt_hght += 1; + n <<= UBIFS_LPT_FANOUT_SHIFT; + } + + c->pnode_cnt = DIV_ROUND_UP(c->main_lebs, UBIFS_LPT_FANOUT); + + n = DIV_ROUND_UP(c->pnode_cnt, UBIFS_LPT_FANOUT); + c->nnode_cnt = n; + for (i = 1; i < c->lpt_hght; i++) { + n = DIV_ROUND_UP(n, UBIFS_LPT_FANOUT); + c->nnode_cnt += n; + } + + c->space_bits = fls(c->leb_size) - 3; + c->lpt_lnum_bits = fls(c->lpt_lebs); + c->lpt_offs_bits = fls(c->leb_size - 1); + c->lpt_spc_bits = fls(c->leb_size); + + n = DIV_ROUND_UP(c->max_leb_cnt, UBIFS_LPT_FANOUT); + c->pcnt_bits = fls(n - 1); + + c->lnum_bits = fls(c->max_leb_cnt - 1); + + bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS + + (c->big_lpt ? c->pcnt_bits : 0) + + (c->space_bits * 2 + 1) * UBIFS_LPT_FANOUT; + c->pnode_sz = (bits + 7) / 8; + + bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS + + (c->big_lpt ? c->pcnt_bits : 0) + + (c->lpt_lnum_bits + c->lpt_offs_bits) * UBIFS_LPT_FANOUT; + c->nnode_sz = (bits + 7) / 8; + + bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS + + c->lpt_lebs * c->lpt_spc_bits * 2; + c->ltab_sz = (bits + 7) / 8; + + bits = UBIFS_LPT_CRC_BITS + UBIFS_LPT_TYPE_BITS + + c->lnum_bits * c->lsave_cnt; + c->lsave_sz = (bits + 7) / 8; + + /* Calculate the minimum LPT size */ + c->lpt_sz = (long long)c->pnode_cnt * c->pnode_sz; + c->lpt_sz += (long long)c->nnode_cnt * c->nnode_sz; + c->lpt_sz += c->ltab_sz; + c->lpt_sz += c->lsave_sz; + + /* Add wastage */ + sz = c->lpt_sz; + per_leb_wastage = max_t(int, c->pnode_sz, c->nnode_sz); + sz += per_leb_wastage; + tot_wastage = per_leb_wastage; + while (sz > c->leb_size) { + sz += per_leb_wastage; + sz -= c->leb_size; + tot_wastage += per_leb_wastage; + } + tot_wastage += ALIGN(sz, c->min_io_size) - sz; + c->lpt_sz += tot_wastage; +} + +/** + * ubifs_calc_lpt_geom - calculate and check sizes for the LPT area. + * @c: the UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_calc_lpt_geom(struct ubifs_info *c) +{ + int lebs_needed; + uint64_t sz; + + do_calc_lpt_geom(c); + + /* Verify that lpt_lebs is big enough */ + sz = c->lpt_sz * 2; /* Must have at least 2 times the size */ + sz += c->leb_size - 1; + do_div(sz, c->leb_size); + lebs_needed = sz; + if (lebs_needed > c->lpt_lebs) { + ubifs_err("too few LPT LEBs"); + return -EINVAL; + } + + /* Verify that ltab fits in a single LEB (since ltab is a single node */ + if (c->ltab_sz > c->leb_size) { + ubifs_err("LPT ltab too big"); + return -EINVAL; + } + + c->check_lpt_free = c->big_lpt; + + return 0; +} + +/** + * calc_dflt_lpt_geom - calculate default LPT geometry. + * @c: the UBIFS file-system description object + * @main_lebs: number of main area LEBs is passed and returned here + * @big_lpt: whether the LPT area is "big" is returned here + * + * The size of the LPT area depends on parameters that themselves are dependent + * on the size of the LPT area. This function, successively recalculates the LPT + * area geometry until the parameters and resultant geometry are consistent. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, + int *big_lpt) +{ + int i, lebs_needed; + uint64_t sz; + + /* Start by assuming the minimum number of LPT LEBs */ + c->lpt_lebs = UBIFS_MIN_LPT_LEBS; + c->main_lebs = *main_lebs - c->lpt_lebs; + if (c->main_lebs <= 0) + return -EINVAL; + + /* And assume we will use the small LPT model */ + c->big_lpt = 0; + + /* + * Calculate the geometry based on assumptions above and then see if it + * makes sense + */ + do_calc_lpt_geom(c); + + /* Small LPT model must have lpt_sz < leb_size */ + if (c->lpt_sz > c->leb_size) { + /* Nope, so try again using big LPT model */ + c->big_lpt = 1; + do_calc_lpt_geom(c); + } + + /* Now check there are enough LPT LEBs */ + for (i = 0; i < 64 ; i++) { + sz = c->lpt_sz * 4; /* Allow 4 times the size */ + sz += c->leb_size - 1; + do_div(sz, c->leb_size); + lebs_needed = sz; + if (lebs_needed > c->lpt_lebs) { + /* Not enough LPT LEBs so try again with more */ + c->lpt_lebs = lebs_needed; + c->main_lebs = *main_lebs - c->lpt_lebs; + if (c->main_lebs <= 0) + return -EINVAL; + do_calc_lpt_geom(c); + continue; + } + if (c->ltab_sz > c->leb_size) { + ubifs_err("LPT ltab too big"); + return -EINVAL; + } + *main_lebs = c->main_lebs; + *big_lpt = c->big_lpt; + return 0; + } + return -EINVAL; +} + +/** + * pack_bits - pack bit fields end-to-end. + * @addr: address at which to pack (passed and next address returned) + * @pos: bit position at which to pack (passed and next position returned) + * @val: value to pack + * @nrbits: number of bits of value to pack (1-32) + */ +static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits) +{ + uint8_t *p = *addr; + int b = *pos; + + ubifs_assert(nrbits > 0); + ubifs_assert(nrbits <= 32); + ubifs_assert(*pos >= 0); + ubifs_assert(*pos < 8); + ubifs_assert((val >> nrbits) == 0 || nrbits == 32); + if (b) { + *p |= ((uint8_t)val) << b; + nrbits += b; + if (nrbits > 8) { + *++p = (uint8_t)(val >>= (8 - b)); + if (nrbits > 16) { + *++p = (uint8_t)(val >>= 8); + if (nrbits > 24) { + *++p = (uint8_t)(val >>= 8); + if (nrbits > 32) + *++p = (uint8_t)(val >>= 8); + } + } + } + } else { + *p = (uint8_t)val; + if (nrbits > 8) { + *++p = (uint8_t)(val >>= 8); + if (nrbits > 16) { + *++p = (uint8_t)(val >>= 8); + if (nrbits > 24) + *++p = (uint8_t)(val >>= 8); + } + } + } + b = nrbits & 7; + if (b == 0) + p++; + *addr = p; + *pos = b; +} + +/** + * ubifs_unpack_bits - unpack bit fields. + * @addr: address at which to unpack (passed and next address returned) + * @pos: bit position at which to unpack (passed and next position returned) + * @nrbits: number of bits of value to unpack (1-32) + * + * This functions returns the value unpacked. + */ +uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits) +{ + const int k = 32 - nrbits; + uint8_t *p = *addr; + int b = *pos; + uint32_t val; + + ubifs_assert(nrbits > 0); + ubifs_assert(nrbits <= 32); + ubifs_assert(*pos >= 0); + ubifs_assert(*pos < 8); + if (b) { + val = p[1] | ((uint32_t)p[2] << 8) | ((uint32_t)p[3] << 16) | + ((uint32_t)p[4] << 24); + val <<= (8 - b); + val |= *p >> b; + nrbits += b; + } else + val = p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | + ((uint32_t)p[3] << 24); + val <<= k; + val >>= k; + b = nrbits & 7; + p += nrbits / 8; + *addr = p; + *pos = b; + ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32); + return val; +} + +/** + * ubifs_pack_pnode - pack all the bit fields of a pnode. + * @c: UBIFS file-system description object + * @buf: buffer into which to pack + * @pnode: pnode to pack + */ +void ubifs_pack_pnode(struct ubifs_info *c, void *buf, + struct ubifs_pnode *pnode) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0; + uint16_t crc; + + pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS); + if (c->big_lpt) + pack_bits(&addr, &pos, pnode->num, c->pcnt_bits); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + pack_bits(&addr, &pos, pnode->lprops[i].free >> 3, + c->space_bits); + pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3, + c->space_bits); + if (pnode->lprops[i].flags & LPROPS_INDEX) + pack_bits(&addr, &pos, 1, 1); + else + pack_bits(&addr, &pos, 0, 1); + } + crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, + c->pnode_sz - UBIFS_LPT_CRC_BYTES); + addr = buf; + pos = 0; + pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); +} + +/** + * ubifs_pack_nnode - pack all the bit fields of a nnode. + * @c: UBIFS file-system description object + * @buf: buffer into which to pack + * @nnode: nnode to pack + */ +void ubifs_pack_nnode(struct ubifs_info *c, void *buf, + struct ubifs_nnode *nnode) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0; + uint16_t crc; + + pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS); + if (c->big_lpt) + pack_bits(&addr, &pos, nnode->num, c->pcnt_bits); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + int lnum = nnode->nbranch[i].lnum; + + if (lnum == 0) + lnum = c->lpt_last + 1; + pack_bits(&addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits); + pack_bits(&addr, &pos, nnode->nbranch[i].offs, + c->lpt_offs_bits); + } + crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, + c->nnode_sz - UBIFS_LPT_CRC_BYTES); + addr = buf; + pos = 0; + pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); +} + +/** + * ubifs_pack_ltab - pack the LPT's own lprops table. + * @c: UBIFS file-system description object + * @buf: buffer into which to pack + * @ltab: LPT's own lprops table to pack + */ +void ubifs_pack_ltab(struct ubifs_info *c, void *buf, + struct ubifs_lpt_lprops *ltab) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0; + uint16_t crc; + + pack_bits(&addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS); + for (i = 0; i < c->lpt_lebs; i++) { + pack_bits(&addr, &pos, ltab[i].free, c->lpt_spc_bits); + pack_bits(&addr, &pos, ltab[i].dirty, c->lpt_spc_bits); + } + crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, + c->ltab_sz - UBIFS_LPT_CRC_BYTES); + addr = buf; + pos = 0; + pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); +} + +/** + * ubifs_pack_lsave - pack the LPT's save table. + * @c: UBIFS file-system description object + * @buf: buffer into which to pack + * @lsave: LPT's save table to pack + */ +void ubifs_pack_lsave(struct ubifs_info *c, void *buf, int *lsave) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0; + uint16_t crc; + + pack_bits(&addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS); + for (i = 0; i < c->lsave_cnt; i++) + pack_bits(&addr, &pos, lsave[i], c->lnum_bits); + crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, + c->lsave_sz - UBIFS_LPT_CRC_BYTES); + addr = buf; + pos = 0; + pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); +} + +/** + * ubifs_add_lpt_dirt - add dirty space to LPT LEB properties. + * @c: UBIFS file-system description object + * @lnum: LEB number to which to add dirty space + * @dirty: amount of dirty space to add + */ +void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty) +{ + if (!dirty || !lnum) + return; + dbg_lp("LEB %d add %d to %d", + lnum, dirty, c->ltab[lnum - c->lpt_first].dirty); + ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); + c->ltab[lnum - c->lpt_first].dirty += dirty; +} + +/** + * set_ltab - set LPT LEB properties. + * @c: UBIFS file-system description object + * @lnum: LEB number + * @free: amount of free space + * @dirty: amount of dirty space + */ +static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty) +{ + dbg_lp("LEB %d free %d dirty %d to %d %d", + lnum, c->ltab[lnum - c->lpt_first].free, + c->ltab[lnum - c->lpt_first].dirty, free, dirty); + ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); + c->ltab[lnum - c->lpt_first].free = free; + c->ltab[lnum - c->lpt_first].dirty = dirty; +} + +/** + * ubifs_add_nnode_dirt - add dirty space to LPT LEB properties. + * @c: UBIFS file-system description object + * @nnode: nnode for which to add dirt + */ +void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode) +{ + struct ubifs_nnode *np = nnode->parent; + + if (np) + ubifs_add_lpt_dirt(c, np->nbranch[nnode->iip].lnum, + c->nnode_sz); + else { + ubifs_add_lpt_dirt(c, c->lpt_lnum, c->nnode_sz); + if (!(c->lpt_drty_flgs & LTAB_DIRTY)) { + c->lpt_drty_flgs |= LTAB_DIRTY; + ubifs_add_lpt_dirt(c, c->ltab_lnum, c->ltab_sz); + } + } +} + +/** + * add_pnode_dirt - add dirty space to LPT LEB properties. + * @c: UBIFS file-system description object + * @pnode: pnode for which to add dirt + */ +static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode) +{ + ubifs_add_lpt_dirt(c, pnode->parent->nbranch[pnode->iip].lnum, + c->pnode_sz); +} + +/** + * calc_nnode_num - calculate nnode number. + * @row: the row in the tree (root is zero) + * @col: the column in the row (leftmost is zero) + * + * The nnode number is a number that uniquely identifies a nnode and can be used + * easily to traverse the tree from the root to that nnode. + * + * This function calculates and returns the nnode number for the nnode at @row + * and @col. + */ +static int calc_nnode_num(int row, int col) +{ + int num, bits; + + num = 1; + while (row--) { + bits = (col & (UBIFS_LPT_FANOUT - 1)); + col >>= UBIFS_LPT_FANOUT_SHIFT; + num <<= UBIFS_LPT_FANOUT_SHIFT; + num |= bits; + } + return num; +} + +/** + * calc_nnode_num_from_parent - calculate nnode number. + * @c: UBIFS file-system description object + * @parent: parent nnode + * @iip: index in parent + * + * The nnode number is a number that uniquely identifies a nnode and can be used + * easily to traverse the tree from the root to that nnode. + * + * This function calculates and returns the nnode number based on the parent's + * nnode number and the index in parent. + */ +static int calc_nnode_num_from_parent(struct ubifs_info *c, + struct ubifs_nnode *parent, int iip) +{ + int num, shft; + + if (!parent) + return 1; + shft = (c->lpt_hght - parent->level) * UBIFS_LPT_FANOUT_SHIFT; + num = parent->num ^ (1 << shft); + num |= (UBIFS_LPT_FANOUT + iip) << shft; + return num; +} + +/** + * calc_pnode_num_from_parent - calculate pnode number. + * @c: UBIFS file-system description object + * @parent: parent nnode + * @iip: index in parent + * + * The pnode number is a number that uniquely identifies a pnode and can be used + * easily to traverse the tree from the root to that pnode. + * + * This function calculates and returns the pnode number based on the parent's + * nnode number and the index in parent. + */ +static int calc_pnode_num_from_parent(struct ubifs_info *c, + struct ubifs_nnode *parent, int iip) +{ + int i, n = c->lpt_hght - 1, pnum = parent->num, num = 0; + + for (i = 0; i < n; i++) { + num <<= UBIFS_LPT_FANOUT_SHIFT; + num |= pnum & (UBIFS_LPT_FANOUT - 1); + pnum >>= UBIFS_LPT_FANOUT_SHIFT; + } + num <<= UBIFS_LPT_FANOUT_SHIFT; + num |= iip; + return num; +} + +/** + * ubifs_create_dflt_lpt - create default LPT. + * @c: UBIFS file-system description object + * @main_lebs: number of main area LEBs is passed and returned here + * @lpt_first: LEB number of first LPT LEB + * @lpt_lebs: number of LEBs for LPT is passed and returned here + * @big_lpt: use big LPT model is passed and returned here + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, + int *lpt_lebs, int *big_lpt) +{ + int lnum, err = 0, node_sz, iopos, i, j, cnt, len, alen, row; + int blnum, boffs, bsz, bcnt; + struct ubifs_pnode *pnode = NULL; + struct ubifs_nnode *nnode = NULL; + void *buf = NULL, *p; + struct ubifs_lpt_lprops *ltab = NULL; + int *lsave = NULL; + + err = calc_dflt_lpt_geom(c, main_lebs, big_lpt); + if (err) + return err; + *lpt_lebs = c->lpt_lebs; + + /* Needed by 'ubifs_pack_nnode()' and 'set_ltab()' */ + c->lpt_first = lpt_first; + /* Needed by 'set_ltab()' */ + c->lpt_last = lpt_first + c->lpt_lebs - 1; + /* Needed by 'ubifs_pack_lsave()' */ + c->main_first = c->leb_cnt - *main_lebs; + + lsave = kmalloc(sizeof(int) * c->lsave_cnt, GFP_KERNEL); + pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_KERNEL); + nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_KERNEL); + buf = vmalloc(c->leb_size); + ltab = vmalloc(sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + if (!pnode || !nnode || !buf || !ltab || !lsave) { + err = -ENOMEM; + goto out; + } + + ubifs_assert(!c->ltab); + c->ltab = ltab; /* Needed by set_ltab */ + + /* Initialize LPT's own lprops */ + for (i = 0; i < c->lpt_lebs; i++) { + ltab[i].free = c->leb_size; + ltab[i].dirty = 0; + ltab[i].tgc = 0; + ltab[i].cmt = 0; + } + + lnum = lpt_first; + p = buf; + /* Number of leaf nodes (pnodes) */ + cnt = c->pnode_cnt; + + /* + * The first pnode contains the LEB properties for the LEBs that contain + * the root inode node and the root index node of the index tree. + */ + node_sz = ALIGN(ubifs_idx_node_sz(c, 1), 8); + iopos = ALIGN(node_sz, c->min_io_size); + pnode->lprops[0].free = c->leb_size - iopos; + pnode->lprops[0].dirty = iopos - node_sz; + pnode->lprops[0].flags = LPROPS_INDEX; + + node_sz = UBIFS_INO_NODE_SZ; + iopos = ALIGN(node_sz, c->min_io_size); + pnode->lprops[1].free = c->leb_size - iopos; + pnode->lprops[1].dirty = iopos - node_sz; + + for (i = 2; i < UBIFS_LPT_FANOUT; i++) + pnode->lprops[i].free = c->leb_size; + + /* Add first pnode */ + ubifs_pack_pnode(c, p, pnode); + p += c->pnode_sz; + len = c->pnode_sz; + pnode->num += 1; + + /* Reset pnode values for remaining pnodes */ + pnode->lprops[0].free = c->leb_size; + pnode->lprops[0].dirty = 0; + pnode->lprops[0].flags = 0; + + pnode->lprops[1].free = c->leb_size; + pnode->lprops[1].dirty = 0; + + /* + * To calculate the internal node branches, we keep information about + * the level below. + */ + blnum = lnum; /* LEB number of level below */ + boffs = 0; /* Offset of level below */ + bcnt = cnt; /* Number of nodes in level below */ + bsz = c->pnode_sz; /* Size of nodes in level below */ + + /* Add all remaining pnodes */ + for (i = 1; i < cnt; i++) { + if (len + c->pnode_sz > c->leb_size) { + alen = ALIGN(len, c->min_io_size); + set_ltab(c, lnum, c->leb_size - alen, alen - len); + memset(p, 0xff, alen - len); + err = ubi_leb_change(c->ubi, lnum++, buf, alen, + UBI_SHORTTERM); + if (err) + goto out; + p = buf; + len = 0; + } + ubifs_pack_pnode(c, p, pnode); + p += c->pnode_sz; + len += c->pnode_sz; + /* + * pnodes are simply numbered left to right starting at zero, + * which means the pnode number can be used easily to traverse + * down the tree to the corresponding pnode. + */ + pnode->num += 1; + } + + row = 0; + for (i = UBIFS_LPT_FANOUT; cnt > i; i <<= UBIFS_LPT_FANOUT_SHIFT) + row += 1; + /* Add all nnodes, one level at a time */ + while (1) { + /* Number of internal nodes (nnodes) at next level */ + cnt = DIV_ROUND_UP(cnt, UBIFS_LPT_FANOUT); + for (i = 0; i < cnt; i++) { + if (len + c->nnode_sz > c->leb_size) { + alen = ALIGN(len, c->min_io_size); + set_ltab(c, lnum, c->leb_size - alen, + alen - len); + memset(p, 0xff, alen - len); + err = ubi_leb_change(c->ubi, lnum++, buf, alen, + UBI_SHORTTERM); + if (err) + goto out; + p = buf; + len = 0; + } + /* Only 1 nnode at this level, so it is the root */ + if (cnt == 1) { + c->lpt_lnum = lnum; + c->lpt_offs = len; + } + /* Set branches to the level below */ + for (j = 0; j < UBIFS_LPT_FANOUT; j++) { + if (bcnt) { + if (boffs + bsz > c->leb_size) { + blnum += 1; + boffs = 0; + } + nnode->nbranch[j].lnum = blnum; + nnode->nbranch[j].offs = boffs; + boffs += bsz; + bcnt--; + } else { + nnode->nbranch[j].lnum = 0; + nnode->nbranch[j].offs = 0; + } + } + nnode->num = calc_nnode_num(row, i); + ubifs_pack_nnode(c, p, nnode); + p += c->nnode_sz; + len += c->nnode_sz; + } + /* Only 1 nnode at this level, so it is the root */ + if (cnt == 1) + break; + /* Update the information about the level below */ + bcnt = cnt; + bsz = c->nnode_sz; + row -= 1; + } + + if (*big_lpt) { + /* Need to add LPT's save table */ + if (len + c->lsave_sz > c->leb_size) { + alen = ALIGN(len, c->min_io_size); + set_ltab(c, lnum, c->leb_size - alen, alen - len); + memset(p, 0xff, alen - len); + err = ubi_leb_change(c->ubi, lnum++, buf, alen, + UBI_SHORTTERM); + if (err) + goto out; + p = buf; + len = 0; + } + + c->lsave_lnum = lnum; + c->lsave_offs = len; + + for (i = 0; i < c->lsave_cnt && i < *main_lebs; i++) + lsave[i] = c->main_first + i; + for (; i < c->lsave_cnt; i++) + lsave[i] = c->main_first; + + ubifs_pack_lsave(c, p, lsave); + p += c->lsave_sz; + len += c->lsave_sz; + } + + /* Need to add LPT's own LEB properties table */ + if (len + c->ltab_sz > c->leb_size) { + alen = ALIGN(len, c->min_io_size); + set_ltab(c, lnum, c->leb_size - alen, alen - len); + memset(p, 0xff, alen - len); + err = ubi_leb_change(c->ubi, lnum++, buf, alen, UBI_SHORTTERM); + if (err) + goto out; + p = buf; + len = 0; + } + + c->ltab_lnum = lnum; + c->ltab_offs = len; + + /* Update ltab before packing it */ + len += c->ltab_sz; + alen = ALIGN(len, c->min_io_size); + set_ltab(c, lnum, c->leb_size - alen, alen - len); + + ubifs_pack_ltab(c, p, ltab); + p += c->ltab_sz; + + /* Write remaining buffer */ + memset(p, 0xff, alen - len); + err = ubi_leb_change(c->ubi, lnum, buf, alen, UBI_SHORTTERM); + if (err) + goto out; + + c->nhead_lnum = lnum; + c->nhead_offs = ALIGN(len, c->min_io_size); + + dbg_lp("space_bits %d", c->space_bits); + dbg_lp("lpt_lnum_bits %d", c->lpt_lnum_bits); + dbg_lp("lpt_offs_bits %d", c->lpt_offs_bits); + dbg_lp("lpt_spc_bits %d", c->lpt_spc_bits); + dbg_lp("pcnt_bits %d", c->pcnt_bits); + dbg_lp("lnum_bits %d", c->lnum_bits); + dbg_lp("pnode_sz %d", c->pnode_sz); + dbg_lp("nnode_sz %d", c->nnode_sz); + dbg_lp("ltab_sz %d", c->ltab_sz); + dbg_lp("lsave_sz %d", c->lsave_sz); + dbg_lp("lsave_cnt %d", c->lsave_cnt); + dbg_lp("lpt_hght %d", c->lpt_hght); + dbg_lp("big_lpt %d", c->big_lpt); + dbg_lp("LPT root is at %d:%d", c->lpt_lnum, c->lpt_offs); + dbg_lp("LPT head is at %d:%d", c->nhead_lnum, c->nhead_offs); + dbg_lp("LPT ltab is at %d:%d", c->ltab_lnum, c->ltab_offs); + if (c->big_lpt) + dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs); +out: + c->ltab = NULL; + kfree(lsave); + vfree(ltab); + vfree(buf); + kfree(nnode); + kfree(pnode); + return err; +} + +/** + * update_cats - add LEB properties of a pnode to LEB category lists and heaps. + * @c: UBIFS file-system description object + * @pnode: pnode + * + * When a pnode is loaded into memory, the LEB properties it contains are added, + * by this function, to the LEB category lists and heaps. + */ +static void update_cats(struct ubifs_info *c, struct ubifs_pnode *pnode) +{ + int i; + + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + int cat = pnode->lprops[i].flags & LPROPS_CAT_MASK; + int lnum = pnode->lprops[i].lnum; + + if (!lnum) + return; + ubifs_add_to_cat(c, &pnode->lprops[i], cat); + } +} + +/** + * replace_cats - add LEB properties of a pnode to LEB category lists and heaps. + * @c: UBIFS file-system description object + * @old_pnode: pnode copied + * @new_pnode: pnode copy + * + * During commit it is sometimes necessary to copy a pnode + * (see dirty_cow_pnode). When that happens, references in + * category lists and heaps must be replaced. This function does that. + */ +static void replace_cats(struct ubifs_info *c, struct ubifs_pnode *old_pnode, + struct ubifs_pnode *new_pnode) +{ + int i; + + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + if (!new_pnode->lprops[i].lnum) + return; + ubifs_replace_cat(c, &old_pnode->lprops[i], + &new_pnode->lprops[i]); + } +} + +/** + * check_lpt_crc - check LPT node crc is correct. + * @c: UBIFS file-system description object + * @buf: buffer containing node + * @len: length of node + * + * This function returns %0 on success and a negative error code on failure. + */ +static int check_lpt_crc(void *buf, int len) +{ + int pos = 0; + uint8_t *addr = buf; + uint16_t crc, calc_crc; + + crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS); + calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, + len - UBIFS_LPT_CRC_BYTES); + if (crc != calc_crc) { + ubifs_err("invalid crc in LPT node: crc %hx calc %hx", crc, + calc_crc); + dbg_dump_stack(); + return -EINVAL; + } + return 0; +} + +/** + * check_lpt_type - check LPT node type is correct. + * @c: UBIFS file-system description object + * @addr: address of type bit field is passed and returned updated here + * @pos: position of type bit field is passed and returned updated here + * @type: expected type + * + * This function returns %0 on success and a negative error code on failure. + */ +static int check_lpt_type(uint8_t **addr, int *pos, int type) +{ + int node_type; + + node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS); + if (node_type != type) { + ubifs_err("invalid type (%d) in LPT node type %d", node_type, + type); + dbg_dump_stack(); + return -EINVAL; + } + return 0; +} + +/** + * unpack_pnode - unpack a pnode. + * @c: UBIFS file-system description object + * @buf: buffer containing packed pnode to unpack + * @pnode: pnode structure to fill + * + * This function returns %0 on success and a negative error code on failure. + */ +static int unpack_pnode(struct ubifs_info *c, void *buf, + struct ubifs_pnode *pnode) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0, err; + + err = check_lpt_type(&addr, &pos, UBIFS_LPT_PNODE); + if (err) + return err; + if (c->big_lpt) + pnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_lprops * const lprops = &pnode->lprops[i]; + + lprops->free = ubifs_unpack_bits(&addr, &pos, c->space_bits); + lprops->free <<= 3; + lprops->dirty = ubifs_unpack_bits(&addr, &pos, c->space_bits); + lprops->dirty <<= 3; + + if (ubifs_unpack_bits(&addr, &pos, 1)) + lprops->flags = LPROPS_INDEX; + else + lprops->flags = 0; + lprops->flags |= ubifs_categorize_lprops(c, lprops); + } + err = check_lpt_crc(buf, c->pnode_sz); + return err; +} + +/** + * unpack_nnode - unpack a nnode. + * @c: UBIFS file-system description object + * @buf: buffer containing packed nnode to unpack + * @nnode: nnode structure to fill + * + * This function returns %0 on success and a negative error code on failure. + */ +static int unpack_nnode(struct ubifs_info *c, void *buf, + struct ubifs_nnode *nnode) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0, err; + + err = check_lpt_type(&addr, &pos, UBIFS_LPT_NNODE); + if (err) + return err; + if (c->big_lpt) + nnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + int lnum; + + lnum = ubifs_unpack_bits(&addr, &pos, c->lpt_lnum_bits) + + c->lpt_first; + if (lnum == c->lpt_last + 1) + lnum = 0; + nnode->nbranch[i].lnum = lnum; + nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos, + c->lpt_offs_bits); + } + err = check_lpt_crc(buf, c->nnode_sz); + return err; +} + +/** + * unpack_ltab - unpack the LPT's own lprops table. + * @c: UBIFS file-system description object + * @buf: buffer from which to unpack + * + * This function returns %0 on success and a negative error code on failure. + */ +static int unpack_ltab(struct ubifs_info *c, void *buf) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0, err; + + err = check_lpt_type(&addr, &pos, UBIFS_LPT_LTAB); + if (err) + return err; + for (i = 0; i < c->lpt_lebs; i++) { + int free = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits); + int dirty = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits); + + if (free < 0 || free > c->leb_size || dirty < 0 || + dirty > c->leb_size || free + dirty > c->leb_size) + return -EINVAL; + + c->ltab[i].free = free; + c->ltab[i].dirty = dirty; + c->ltab[i].tgc = 0; + c->ltab[i].cmt = 0; + } + err = check_lpt_crc(buf, c->ltab_sz); + return err; +} + +/** + * unpack_lsave - unpack the LPT's save table. + * @c: UBIFS file-system description object + * @buf: buffer from which to unpack + * + * This function returns %0 on success and a negative error code on failure. + */ +static int unpack_lsave(struct ubifs_info *c, void *buf) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int i, pos = 0, err; + + err = check_lpt_type(&addr, &pos, UBIFS_LPT_LSAVE); + if (err) + return err; + for (i = 0; i < c->lsave_cnt; i++) { + int lnum = ubifs_unpack_bits(&addr, &pos, c->lnum_bits); + + if (lnum < c->main_first || lnum >= c->leb_cnt) + return -EINVAL; + c->lsave[i] = lnum; + } + err = check_lpt_crc(buf, c->lsave_sz); + return err; +} + +/** + * validate_nnode - validate a nnode. + * @c: UBIFS file-system description object + * @nnode: nnode to validate + * @parent: parent nnode (or NULL for the root nnode) + * @iip: index in parent + * + * This function returns %0 on success and a negative error code on failure. + */ +static int validate_nnode(struct ubifs_info *c, struct ubifs_nnode *nnode, + struct ubifs_nnode *parent, int iip) +{ + int i, lvl, max_offs; + + if (c->big_lpt) { + int num = calc_nnode_num_from_parent(c, parent, iip); + + if (nnode->num != num) + return -EINVAL; + } + lvl = parent ? parent->level - 1 : c->lpt_hght; + if (lvl < 1) + return -EINVAL; + if (lvl == 1) + max_offs = c->leb_size - c->pnode_sz; + else + max_offs = c->leb_size - c->nnode_sz; + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + int lnum = nnode->nbranch[i].lnum; + int offs = nnode->nbranch[i].offs; + + if (lnum == 0) { + if (offs != 0) + return -EINVAL; + continue; + } + if (lnum < c->lpt_first || lnum > c->lpt_last) + return -EINVAL; + if (offs < 0 || offs > max_offs) + return -EINVAL; + } + return 0; +} + +/** + * validate_pnode - validate a pnode. + * @c: UBIFS file-system description object + * @pnode: pnode to validate + * @parent: parent nnode + * @iip: index in parent + * + * This function returns %0 on success and a negative error code on failure. + */ +static int validate_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, + struct ubifs_nnode *parent, int iip) +{ + int i; + + if (c->big_lpt) { + int num = calc_pnode_num_from_parent(c, parent, iip); + + if (pnode->num != num) + return -EINVAL; + } + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + int free = pnode->lprops[i].free; + int dirty = pnode->lprops[i].dirty; + + if (free < 0 || free > c->leb_size || free % c->min_io_size || + (free & 7)) + return -EINVAL; + if (dirty < 0 || dirty > c->leb_size || (dirty & 7)) + return -EINVAL; + if (dirty + free > c->leb_size) + return -EINVAL; + } + return 0; +} + +/** + * set_pnode_lnum - set LEB numbers on a pnode. + * @c: UBIFS file-system description object + * @pnode: pnode to update + * + * This function calculates the LEB numbers for the LEB properties it contains + * based on the pnode number. + */ +static void set_pnode_lnum(struct ubifs_info *c, struct ubifs_pnode *pnode) +{ + int i, lnum; + + lnum = (pnode->num << UBIFS_LPT_FANOUT_SHIFT) + c->main_first; + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + if (lnum >= c->leb_cnt) + return; + pnode->lprops[i].lnum = lnum++; + } +} + +/** + * ubifs_read_nnode - read a nnode from flash and link it to the tree in memory. + * @c: UBIFS file-system description object + * @parent: parent nnode (or NULL for the root) + * @iip: index in parent + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) +{ + struct ubifs_nbranch *branch = NULL; + struct ubifs_nnode *nnode = NULL; + void *buf = c->lpt_nod_buf; + int err, lnum, offs; + + if (parent) { + branch = &parent->nbranch[iip]; + lnum = branch->lnum; + offs = branch->offs; + } else { + lnum = c->lpt_lnum; + offs = c->lpt_offs; + } + nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_NOFS); + if (!nnode) { + err = -ENOMEM; + goto out; + } + if (lnum == 0) { + /* + * This nnode was not written which just means that the LEB + * properties in the subtree below it describe empty LEBs. We + * make the nnode as though we had read it, which in fact means + * doing almost nothing. + */ + if (c->big_lpt) + nnode->num = calc_nnode_num_from_parent(c, parent, iip); + } else { + err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz); + if (err) + goto out; + err = unpack_nnode(c, buf, nnode); + if (err) + goto out; + } + err = validate_nnode(c, nnode, parent, iip); + if (err) + goto out; + if (!c->big_lpt) + nnode->num = calc_nnode_num_from_parent(c, parent, iip); + if (parent) { + branch->nnode = nnode; + nnode->level = parent->level - 1; + } else { + c->nroot = nnode; + nnode->level = c->lpt_hght; + } + nnode->parent = parent; + nnode->iip = iip; + return 0; + +out: + ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs); + kfree(nnode); + return err; +} + +/** + * read_pnode - read a pnode from flash and link it to the tree in memory. + * @c: UBIFS file-system description object + * @parent: parent nnode + * @iip: index in parent + * + * This function returns %0 on success and a negative error code on failure. + */ +static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) +{ + struct ubifs_nbranch *branch; + struct ubifs_pnode *pnode = NULL; + void *buf = c->lpt_nod_buf; + int err, lnum, offs; + + branch = &parent->nbranch[iip]; + lnum = branch->lnum; + offs = branch->offs; + pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS); + if (!pnode) { + err = -ENOMEM; + goto out; + } + if (lnum == 0) { + /* + * This pnode was not written which just means that the LEB + * properties in it describe empty LEBs. We make the pnode as + * though we had read it. + */ + int i; + + if (c->big_lpt) + pnode->num = calc_pnode_num_from_parent(c, parent, iip); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_lprops * const lprops = &pnode->lprops[i]; + + lprops->free = c->leb_size; + lprops->flags = ubifs_categorize_lprops(c, lprops); + } + } else { + err = ubi_read(c->ubi, lnum, buf, offs, c->pnode_sz); + if (err) + goto out; + err = unpack_pnode(c, buf, pnode); + if (err) + goto out; + } + err = validate_pnode(c, pnode, parent, iip); + if (err) + goto out; + if (!c->big_lpt) + pnode->num = calc_pnode_num_from_parent(c, parent, iip); + branch->pnode = pnode; + pnode->parent = parent; + pnode->iip = iip; + set_pnode_lnum(c, pnode); + c->pnodes_have += 1; + return 0; + +out: + ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs); + dbg_dump_pnode(c, pnode, parent, iip); + dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip)); + kfree(pnode); + return err; +} + +/** + * read_ltab - read LPT's own lprops table. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +static int read_ltab(struct ubifs_info *c) +{ + int err; + void *buf; + + buf = vmalloc(c->ltab_sz); + if (!buf) + return -ENOMEM; + err = ubi_read(c->ubi, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz); + if (err) + goto out; + err = unpack_ltab(c, buf); +out: + vfree(buf); + return err; +} + +/** + * read_lsave - read LPT's save table. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +static int read_lsave(struct ubifs_info *c) +{ + int err, i; + void *buf; + + buf = vmalloc(c->lsave_sz); + if (!buf) + return -ENOMEM; + err = ubi_read(c->ubi, c->lsave_lnum, buf, c->lsave_offs, c->lsave_sz); + if (err) + goto out; + err = unpack_lsave(c, buf); + if (err) + goto out; + for (i = 0; i < c->lsave_cnt; i++) { + int lnum = c->lsave[i]; + + /* + * Due to automatic resizing, the values in the lsave table + * could be beyond the volume size - just ignore them. + */ + if (lnum >= c->leb_cnt) + continue; + ubifs_lpt_lookup(c, lnum); + } +out: + vfree(buf); + return err; +} + +/** + * ubifs_get_nnode - get a nnode. + * @c: UBIFS file-system description object + * @parent: parent nnode (or NULL for the root) + * @iip: index in parent + * + * This function returns a pointer to the nnode on success or a negative error + * code on failure. + */ +struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c, + struct ubifs_nnode *parent, int iip) +{ + struct ubifs_nbranch *branch; + struct ubifs_nnode *nnode; + int err; + + branch = &parent->nbranch[iip]; + nnode = branch->nnode; + if (nnode) + return nnode; + err = ubifs_read_nnode(c, parent, iip); + if (err) + return ERR_PTR(err); + return branch->nnode; +} + +/** + * ubifs_get_pnode - get a pnode. + * @c: UBIFS file-system description object + * @parent: parent nnode + * @iip: index in parent + * + * This function returns a pointer to the pnode on success or a negative error + * code on failure. + */ +struct ubifs_pnode *ubifs_get_pnode(struct ubifs_info *c, + struct ubifs_nnode *parent, int iip) +{ + struct ubifs_nbranch *branch; + struct ubifs_pnode *pnode; + int err; + + branch = &parent->nbranch[iip]; + pnode = branch->pnode; + if (pnode) + return pnode; + err = read_pnode(c, parent, iip); + if (err) + return ERR_PTR(err); + update_cats(c, branch->pnode); + return branch->pnode; +} + +/** + * ubifs_lpt_lookup - lookup LEB properties in the LPT. + * @c: UBIFS file-system description object + * @lnum: LEB number to lookup + * + * This function returns a pointer to the LEB properties on success or a + * negative error code on failure. + */ +struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) +{ + int err, i, h, iip, shft; + struct ubifs_nnode *nnode; + struct ubifs_pnode *pnode; + + if (!c->nroot) { + err = ubifs_read_nnode(c, NULL, 0); + if (err) + return ERR_PTR(err); + } + nnode = c->nroot; + i = lnum - c->main_first; + shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; + for (h = 1; h < c->lpt_hght; h++) { + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + nnode = ubifs_get_nnode(c, nnode, iip); + if (IS_ERR(nnode)) + return ERR_PTR(PTR_ERR(nnode)); + } + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + pnode = ubifs_get_pnode(c, nnode, iip); + if (IS_ERR(pnode)) + return ERR_PTR(PTR_ERR(pnode)); + iip = (i & (UBIFS_LPT_FANOUT - 1)); + dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, + pnode->lprops[iip].free, pnode->lprops[iip].dirty, + pnode->lprops[iip].flags); + return &pnode->lprops[iip]; +} + +/** + * dirty_cow_nnode - ensure a nnode is not being committed. + * @c: UBIFS file-system description object + * @nnode: nnode to check + * + * Returns dirtied nnode on success or negative error code on failure. + */ +static struct ubifs_nnode *dirty_cow_nnode(struct ubifs_info *c, + struct ubifs_nnode *nnode) +{ + struct ubifs_nnode *n; + int i; + + if (!test_bit(COW_CNODE, &nnode->flags)) { + /* nnode is not being committed */ + if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) { + c->dirty_nn_cnt += 1; + ubifs_add_nnode_dirt(c, nnode); + } + return nnode; + } + + /* nnode is being committed, so copy it */ + n = kmalloc(sizeof(struct ubifs_nnode), GFP_NOFS); + if (unlikely(!n)) + return ERR_PTR(-ENOMEM); + + memcpy(n, nnode, sizeof(struct ubifs_nnode)); + n->cnext = NULL; + __set_bit(DIRTY_CNODE, &n->flags); + __clear_bit(COW_CNODE, &n->flags); + + /* The children now have new parent */ + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_nbranch *branch = &n->nbranch[i]; + + if (branch->cnode) + branch->cnode->parent = n; + } + + ubifs_assert(!test_bit(OBSOLETE_CNODE, &nnode->flags)); + __set_bit(OBSOLETE_CNODE, &nnode->flags); + + c->dirty_nn_cnt += 1; + ubifs_add_nnode_dirt(c, nnode); + if (nnode->parent) + nnode->parent->nbranch[n->iip].nnode = n; + else + c->nroot = n; + return n; +} + +/** + * dirty_cow_pnode - ensure a pnode is not being committed. + * @c: UBIFS file-system description object + * @pnode: pnode to check + * + * Returns dirtied pnode on success or negative error code on failure. + */ +static struct ubifs_pnode *dirty_cow_pnode(struct ubifs_info *c, + struct ubifs_pnode *pnode) +{ + struct ubifs_pnode *p; + + if (!test_bit(COW_CNODE, &pnode->flags)) { + /* pnode is not being committed */ + if (!test_and_set_bit(DIRTY_CNODE, &pnode->flags)) { + c->dirty_pn_cnt += 1; + add_pnode_dirt(c, pnode); + } + return pnode; + } + + /* pnode is being committed, so copy it */ + p = kmalloc(sizeof(struct ubifs_pnode), GFP_NOFS); + if (unlikely(!p)) + return ERR_PTR(-ENOMEM); + + memcpy(p, pnode, sizeof(struct ubifs_pnode)); + p->cnext = NULL; + __set_bit(DIRTY_CNODE, &p->flags); + __clear_bit(COW_CNODE, &p->flags); + replace_cats(c, pnode, p); + + ubifs_assert(!test_bit(OBSOLETE_CNODE, &pnode->flags)); + __set_bit(OBSOLETE_CNODE, &pnode->flags); + + c->dirty_pn_cnt += 1; + add_pnode_dirt(c, pnode); + pnode->parent->nbranch[p->iip].pnode = p; + return p; +} + +/** + * ubifs_lpt_lookup_dirty - lookup LEB properties in the LPT. + * @c: UBIFS file-system description object + * @lnum: LEB number to lookup + * + * This function returns a pointer to the LEB properties on success or a + * negative error code on failure. + */ +struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) +{ + int err, i, h, iip, shft; + struct ubifs_nnode *nnode; + struct ubifs_pnode *pnode; + + if (!c->nroot) { + err = ubifs_read_nnode(c, NULL, 0); + if (err) + return ERR_PTR(err); + } + nnode = c->nroot; + nnode = dirty_cow_nnode(c, nnode); + if (IS_ERR(nnode)) + return ERR_PTR(PTR_ERR(nnode)); + i = lnum - c->main_first; + shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; + for (h = 1; h < c->lpt_hght; h++) { + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + nnode = ubifs_get_nnode(c, nnode, iip); + if (IS_ERR(nnode)) + return ERR_PTR(PTR_ERR(nnode)); + nnode = dirty_cow_nnode(c, nnode); + if (IS_ERR(nnode)) + return ERR_PTR(PTR_ERR(nnode)); + } + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + pnode = ubifs_get_pnode(c, nnode, iip); + if (IS_ERR(pnode)) + return ERR_PTR(PTR_ERR(pnode)); + pnode = dirty_cow_pnode(c, pnode); + if (IS_ERR(pnode)) + return ERR_PTR(PTR_ERR(pnode)); + iip = (i & (UBIFS_LPT_FANOUT - 1)); + dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, + pnode->lprops[iip].free, pnode->lprops[iip].dirty, + pnode->lprops[iip].flags); + ubifs_assert(test_bit(DIRTY_CNODE, &pnode->flags)); + return &pnode->lprops[iip]; +} + +/** + * lpt_init_rd - initialize the LPT for reading. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +static int lpt_init_rd(struct ubifs_info *c) +{ + int err, i; + + c->ltab = vmalloc(sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + if (!c->ltab) + return -ENOMEM; + + i = max_t(int, c->nnode_sz, c->pnode_sz); + c->lpt_nod_buf = kmalloc(i, GFP_KERNEL); + if (!c->lpt_nod_buf) + return -ENOMEM; + + for (i = 0; i < LPROPS_HEAP_CNT; i++) { + c->lpt_heap[i].arr = kmalloc(sizeof(void *) * LPT_HEAP_SZ, + GFP_KERNEL); + if (!c->lpt_heap[i].arr) + return -ENOMEM; + c->lpt_heap[i].cnt = 0; + c->lpt_heap[i].max_cnt = LPT_HEAP_SZ; + } + + c->dirty_idx.arr = kmalloc(sizeof(void *) * LPT_HEAP_SZ, GFP_KERNEL); + if (!c->dirty_idx.arr) + return -ENOMEM; + c->dirty_idx.cnt = 0; + c->dirty_idx.max_cnt = LPT_HEAP_SZ; + + err = read_ltab(c); + if (err) + return err; + + dbg_lp("space_bits %d", c->space_bits); + dbg_lp("lpt_lnum_bits %d", c->lpt_lnum_bits); + dbg_lp("lpt_offs_bits %d", c->lpt_offs_bits); + dbg_lp("lpt_spc_bits %d", c->lpt_spc_bits); + dbg_lp("pcnt_bits %d", c->pcnt_bits); + dbg_lp("lnum_bits %d", c->lnum_bits); + dbg_lp("pnode_sz %d", c->pnode_sz); + dbg_lp("nnode_sz %d", c->nnode_sz); + dbg_lp("ltab_sz %d", c->ltab_sz); + dbg_lp("lsave_sz %d", c->lsave_sz); + dbg_lp("lsave_cnt %d", c->lsave_cnt); + dbg_lp("lpt_hght %d", c->lpt_hght); + dbg_lp("big_lpt %d", c->big_lpt); + dbg_lp("LPT root is at %d:%d", c->lpt_lnum, c->lpt_offs); + dbg_lp("LPT head is at %d:%d", c->nhead_lnum, c->nhead_offs); + dbg_lp("LPT ltab is at %d:%d", c->ltab_lnum, c->ltab_offs); + if (c->big_lpt) + dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs); + + return 0; +} + +/** + * lpt_init_wr - initialize the LPT for writing. + * @c: UBIFS file-system description object + * + * 'lpt_init_rd()' must have been called already. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int lpt_init_wr(struct ubifs_info *c) +{ + int err, i; + + c->ltab_cmt = vmalloc(sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + if (!c->ltab_cmt) + return -ENOMEM; + + c->lpt_buf = vmalloc(c->leb_size); + if (!c->lpt_buf) + return -ENOMEM; + + if (c->big_lpt) { + c->lsave = kmalloc(sizeof(int) * c->lsave_cnt, GFP_NOFS); + if (!c->lsave) + return -ENOMEM; + err = read_lsave(c); + if (err) + return err; + } + + for (i = 0; i < c->lpt_lebs; i++) + if (c->ltab[i].free == c->leb_size) { + err = ubifs_leb_unmap(c, i + c->lpt_first); + if (err) + return err; + } + + return 0; +} + +/** + * ubifs_lpt_init - initialize the LPT. + * @c: UBIFS file-system description object + * @rd: whether to initialize lpt for reading + * @wr: whether to initialize lpt for writing + * + * For mounting 'rw', @rd and @wr are both true. For mounting 'ro', @rd is true + * and @wr is false. For mounting from 'ro' to 'rw', @rd is false and @wr is + * true. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr) +{ + int err; + + if (rd) { + err = lpt_init_rd(c); + if (err) + return err; + } + + if (wr) { + err = lpt_init_wr(c); + if (err) + return err; + } + + return 0; +} + +/** + * struct lpt_scan_node - somewhere to put nodes while we scan LPT. + * @nnode: where to keep a nnode + * @pnode: where to keep a pnode + * @cnode: where to keep a cnode + * @in_tree: is the node in the tree in memory + * @ptr.nnode: pointer to the nnode (if it is an nnode) which may be here or in + * the tree + * @ptr.pnode: ditto for pnode + * @ptr.cnode: ditto for cnode + */ +struct lpt_scan_node { + union { + struct ubifs_nnode nnode; + struct ubifs_pnode pnode; + struct ubifs_cnode cnode; + }; + int in_tree; + union { + struct ubifs_nnode *nnode; + struct ubifs_pnode *pnode; + struct ubifs_cnode *cnode; + } ptr; +}; + +/** + * scan_get_nnode - for the scan, get a nnode from either the tree or flash. + * @c: the UBIFS file-system description object + * @path: where to put the nnode + * @parent: parent of the nnode + * @iip: index in parent of the nnode + * + * This function returns a pointer to the nnode on success or a negative error + * code on failure. + */ +static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c, + struct lpt_scan_node *path, + struct ubifs_nnode *parent, int iip) +{ + struct ubifs_nbranch *branch; + struct ubifs_nnode *nnode; + void *buf = c->lpt_nod_buf; + int err; + + branch = &parent->nbranch[iip]; + nnode = branch->nnode; + if (nnode) { + path->in_tree = 1; + path->ptr.nnode = nnode; + return nnode; + } + nnode = &path->nnode; + path->in_tree = 0; + path->ptr.nnode = nnode; + memset(nnode, 0, sizeof(struct ubifs_nnode)); + if (branch->lnum == 0) { + /* + * This nnode was not written which just means that the LEB + * properties in the subtree below it describe empty LEBs. We + * make the nnode as though we had read it, which in fact means + * doing almost nothing. + */ + if (c->big_lpt) + nnode->num = calc_nnode_num_from_parent(c, parent, iip); + } else { + err = ubi_read(c->ubi, branch->lnum, buf, branch->offs, + c->nnode_sz); + if (err) + return ERR_PTR(err); + err = unpack_nnode(c, buf, nnode); + if (err) + return ERR_PTR(err); + } + err = validate_nnode(c, nnode, parent, iip); + if (err) + return ERR_PTR(err); + if (!c->big_lpt) + nnode->num = calc_nnode_num_from_parent(c, parent, iip); + nnode->level = parent->level - 1; + nnode->parent = parent; + nnode->iip = iip; + return nnode; +} + +/** + * scan_get_pnode - for the scan, get a pnode from either the tree or flash. + * @c: the UBIFS file-system description object + * @path: where to put the pnode + * @parent: parent of the pnode + * @iip: index in parent of the pnode + * + * This function returns a pointer to the pnode on success or a negative error + * code on failure. + */ +static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c, + struct lpt_scan_node *path, + struct ubifs_nnode *parent, int iip) +{ + struct ubifs_nbranch *branch; + struct ubifs_pnode *pnode; + void *buf = c->lpt_nod_buf; + int err; + + branch = &parent->nbranch[iip]; + pnode = branch->pnode; + if (pnode) { + path->in_tree = 1; + path->ptr.pnode = pnode; + return pnode; + } + pnode = &path->pnode; + path->in_tree = 0; + path->ptr.pnode = pnode; + memset(pnode, 0, sizeof(struct ubifs_pnode)); + if (branch->lnum == 0) { + /* + * This pnode was not written which just means that the LEB + * properties in it describe empty LEBs. We make the pnode as + * though we had read it. + */ + int i; + + if (c->big_lpt) + pnode->num = calc_pnode_num_from_parent(c, parent, iip); + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_lprops * const lprops = &pnode->lprops[i]; + + lprops->free = c->leb_size; + lprops->flags = ubifs_categorize_lprops(c, lprops); + } + } else { + ubifs_assert(branch->lnum >= c->lpt_first && + branch->lnum <= c->lpt_last); + ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size); + err = ubi_read(c->ubi, branch->lnum, buf, branch->offs, + c->pnode_sz); + if (err) + return ERR_PTR(err); + err = unpack_pnode(c, buf, pnode); + if (err) + return ERR_PTR(err); + } + err = validate_pnode(c, pnode, parent, iip); + if (err) + return ERR_PTR(err); + if (!c->big_lpt) + pnode->num = calc_pnode_num_from_parent(c, parent, iip); + pnode->parent = parent; + pnode->iip = iip; + set_pnode_lnum(c, pnode); + return pnode; +} + +/** + * ubifs_lpt_scan_nolock - scan the LPT. + * @c: the UBIFS file-system description object + * @start_lnum: LEB number from which to start scanning + * @end_lnum: LEB number at which to stop scanning + * @scan_cb: callback function called for each lprops + * @data: data to be passed to the callback function + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum, + ubifs_lpt_scan_callback scan_cb, void *data) +{ + int err = 0, i, h, iip, shft; + struct ubifs_nnode *nnode; + struct ubifs_pnode *pnode; + struct lpt_scan_node *path; + + if (start_lnum == -1) { + start_lnum = end_lnum + 1; + if (start_lnum >= c->leb_cnt) + start_lnum = c->main_first; + } + + ubifs_assert(start_lnum >= c->main_first && start_lnum < c->leb_cnt); + ubifs_assert(end_lnum >= c->main_first && end_lnum < c->leb_cnt); + + if (!c->nroot) { + err = ubifs_read_nnode(c, NULL, 0); + if (err) + return err; + } + + path = kmalloc(sizeof(struct lpt_scan_node) * (c->lpt_hght + 1), + GFP_NOFS); + if (!path) + return -ENOMEM; + + path[0].ptr.nnode = c->nroot; + path[0].in_tree = 1; +again: + /* Descend to the pnode containing start_lnum */ + nnode = c->nroot; + i = start_lnum - c->main_first; + shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; + for (h = 1; h < c->lpt_hght; h++) { + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + nnode = scan_get_nnode(c, path + h, nnode, iip); + if (IS_ERR(nnode)) { + err = PTR_ERR(nnode); + goto out; + } + } + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + pnode = scan_get_pnode(c, path + h, nnode, iip); + if (IS_ERR(pnode)) { + err = PTR_ERR(pnode); + goto out; + } + iip = (i & (UBIFS_LPT_FANOUT - 1)); + + /* Loop for each lprops */ + while (1) { + struct ubifs_lprops *lprops = &pnode->lprops[iip]; + int ret, lnum = lprops->lnum; + + ret = scan_cb(c, lprops, path[h].in_tree, data); + if (ret < 0) { + err = ret; + goto out; + } + if (ret & LPT_SCAN_ADD) { + /* Add all the nodes in path to the tree in memory */ + for (h = 1; h < c->lpt_hght; h++) { + const size_t sz = sizeof(struct ubifs_nnode); + struct ubifs_nnode *parent; + + if (path[h].in_tree) + continue; + nnode = kmalloc(sz, GFP_NOFS); + if (!nnode) { + err = -ENOMEM; + goto out; + } + memcpy(nnode, &path[h].nnode, sz); + parent = nnode->parent; + parent->nbranch[nnode->iip].nnode = nnode; + path[h].ptr.nnode = nnode; + path[h].in_tree = 1; + path[h + 1].cnode.parent = nnode; + } + if (path[h].in_tree) + ubifs_ensure_cat(c, lprops); + else { + const size_t sz = sizeof(struct ubifs_pnode); + struct ubifs_nnode *parent; + + pnode = kmalloc(sz, GFP_NOFS); + if (!pnode) { + err = -ENOMEM; + goto out; + } + memcpy(pnode, &path[h].pnode, sz); + parent = pnode->parent; + parent->nbranch[pnode->iip].pnode = pnode; + path[h].ptr.pnode = pnode; + path[h].in_tree = 1; + update_cats(c, pnode); + c->pnodes_have += 1; + } + err = dbg_check_lpt_nodes(c, (struct ubifs_cnode *) + c->nroot, 0, 0); + if (err) + goto out; + err = dbg_check_cats(c); + if (err) + goto out; + } + if (ret & LPT_SCAN_STOP) { + err = 0; + break; + } + /* Get the next lprops */ + if (lnum == end_lnum) { + /* + * We got to the end without finding what we were + * looking for + */ + err = -ENOSPC; + goto out; + } + if (lnum + 1 >= c->leb_cnt) { + /* Wrap-around to the beginning */ + start_lnum = c->main_first; + goto again; + } + if (iip + 1 < UBIFS_LPT_FANOUT) { + /* Next lprops is in the same pnode */ + iip += 1; + continue; + } + /* We need to get the next pnode. Go up until we can go right */ + iip = pnode->iip; + while (1) { + h -= 1; + ubifs_assert(h >= 0); + nnode = path[h].ptr.nnode; + if (iip + 1 < UBIFS_LPT_FANOUT) + break; + iip = nnode->iip; + } + /* Go right */ + iip += 1; + /* Descend to the pnode */ + h += 1; + for (; h < c->lpt_hght; h++) { + nnode = scan_get_nnode(c, path + h, nnode, iip); + if (IS_ERR(nnode)) { + err = PTR_ERR(nnode); + goto out; + } + iip = 0; + } + pnode = scan_get_pnode(c, path + h, nnode, iip); + if (IS_ERR(pnode)) { + err = PTR_ERR(pnode); + goto out; + } + iip = 0; + } +out: + kfree(path); + return err; +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +/** + * dbg_chk_pnode - check a pnode. + * @c: the UBIFS file-system description object + * @pnode: pnode to check + * @col: pnode column + * + * This function returns %0 on success and a negative error code on failure. + */ +static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, + int col) +{ + int i; + + if (pnode->num != col) { + dbg_err("pnode num %d expected %d parent num %d iip %d", + pnode->num, col, pnode->parent->num, pnode->iip); + return -EINVAL; + } + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_lprops *lp, *lprops = &pnode->lprops[i]; + int lnum = (pnode->num << UBIFS_LPT_FANOUT_SHIFT) + i + + c->main_first; + int found, cat = lprops->flags & LPROPS_CAT_MASK; + struct ubifs_lpt_heap *heap; + struct list_head *list = NULL; + + if (lnum >= c->leb_cnt) + continue; + if (lprops->lnum != lnum) { + dbg_err("bad LEB number %d expected %d", + lprops->lnum, lnum); + return -EINVAL; + } + if (lprops->flags & LPROPS_TAKEN) { + if (cat != LPROPS_UNCAT) { + dbg_err("LEB %d taken but not uncat %d", + lprops->lnum, cat); + return -EINVAL; + } + continue; + } + if (lprops->flags & LPROPS_INDEX) { + switch (cat) { + case LPROPS_UNCAT: + case LPROPS_DIRTY_IDX: + case LPROPS_FRDI_IDX: + break; + default: + dbg_err("LEB %d index but cat %d", + lprops->lnum, cat); + return -EINVAL; + } + } else { + switch (cat) { + case LPROPS_UNCAT: + case LPROPS_DIRTY: + case LPROPS_FREE: + case LPROPS_EMPTY: + case LPROPS_FREEABLE: + break; + default: + dbg_err("LEB %d not index but cat %d", + lprops->lnum, cat); + return -EINVAL; + } + } + switch (cat) { + case LPROPS_UNCAT: + list = &c->uncat_list; + break; + case LPROPS_EMPTY: + list = &c->empty_list; + break; + case LPROPS_FREEABLE: + list = &c->freeable_list; + break; + case LPROPS_FRDI_IDX: + list = &c->frdi_idx_list; + break; + } + found = 0; + switch (cat) { + case LPROPS_DIRTY: + case LPROPS_DIRTY_IDX: + case LPROPS_FREE: + heap = &c->lpt_heap[cat - 1]; + if (lprops->hpos < heap->cnt && + heap->arr[lprops->hpos] == lprops) + found = 1; + break; + case LPROPS_UNCAT: + case LPROPS_EMPTY: + case LPROPS_FREEABLE: + case LPROPS_FRDI_IDX: + list_for_each_entry(lp, list, list) + if (lprops == lp) { + found = 1; + break; + } + break; + } + if (!found) { + dbg_err("LEB %d cat %d not found in cat heap/list", + lprops->lnum, cat); + return -EINVAL; + } + switch (cat) { + case LPROPS_EMPTY: + if (lprops->free != c->leb_size) { + dbg_err("LEB %d cat %d free %d dirty %d", + lprops->lnum, cat, lprops->free, + lprops->dirty); + return -EINVAL; + } + case LPROPS_FREEABLE: + case LPROPS_FRDI_IDX: + if (lprops->free + lprops->dirty != c->leb_size) { + dbg_err("LEB %d cat %d free %d dirty %d", + lprops->lnum, cat, lprops->free, + lprops->dirty); + return -EINVAL; + } + } + } + return 0; +} + +/** + * dbg_check_lpt_nodes - check nnodes and pnodes. + * @c: the UBIFS file-system description object + * @cnode: next cnode (nnode or pnode) to check + * @row: row of cnode (root is zero) + * @col: column of cnode (leftmost is zero) + * + * This function returns %0 on success and a negative error code on failure. + */ +int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, + int row, int col) +{ + struct ubifs_nnode *nnode, *nn; + struct ubifs_cnode *cn; + int num, iip = 0, err; + + if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) + return 0; + + while (cnode) { + ubifs_assert(row >= 0); + nnode = cnode->parent; + if (cnode->level) { + /* cnode is a nnode */ + num = calc_nnode_num(row, col); + if (cnode->num != num) { + dbg_err("nnode num %d expected %d " + "parent num %d iip %d", cnode->num, num, + (nnode ? nnode->num : 0), cnode->iip); + return -EINVAL; + } + nn = (struct ubifs_nnode *)cnode; + while (iip < UBIFS_LPT_FANOUT) { + cn = nn->nbranch[iip].cnode; + if (cn) { + /* Go down */ + row += 1; + col <<= UBIFS_LPT_FANOUT_SHIFT; + col += iip; + iip = 0; + cnode = cn; + break; + } + /* Go right */ + iip += 1; + } + if (iip < UBIFS_LPT_FANOUT) + continue; + } else { + struct ubifs_pnode *pnode; + + /* cnode is a pnode */ + pnode = (struct ubifs_pnode *)cnode; + err = dbg_chk_pnode(c, pnode, col); + if (err) + return err; + } + /* Go up and to the right */ + row -= 1; + col >>= UBIFS_LPT_FANOUT_SHIFT; + iip = cnode->iip + 1; + cnode = (struct ubifs_cnode *)nnode; + } + return 0; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c new file mode 100644 index 0000000..5f0b83e --- /dev/null +++ b/fs/ubifs/lpt_commit.c @@ -0,0 +1,1648 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements commit-related functionality of the LEB properties + * subsystem. + */ + +#include +#include "ubifs.h" + +/** + * first_dirty_cnode - find first dirty cnode. + * @c: UBIFS file-system description object + * @nnode: nnode at which to start + * + * This function returns the first dirty cnode or %NULL if there is not one. + */ +static struct ubifs_cnode *first_dirty_cnode(struct ubifs_nnode *nnode) +{ + ubifs_assert(nnode); + while (1) { + int i, cont = 0; + + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + struct ubifs_cnode *cnode; + + cnode = nnode->nbranch[i].cnode; + if (cnode && + test_bit(DIRTY_CNODE, &cnode->flags)) { + if (cnode->level == 0) + return cnode; + nnode = (struct ubifs_nnode *)cnode; + cont = 1; + break; + } + } + if (!cont) + return (struct ubifs_cnode *)nnode; + } +} + +/** + * next_dirty_cnode - find next dirty cnode. + * @cnode: cnode from which to begin searching + * + * This function returns the next dirty cnode or %NULL if there is not one. + */ +static struct ubifs_cnode *next_dirty_cnode(struct ubifs_cnode *cnode) +{ + struct ubifs_nnode *nnode; + int i; + + ubifs_assert(cnode); + nnode = cnode->parent; + if (!nnode) + return NULL; + for (i = cnode->iip + 1; i < UBIFS_LPT_FANOUT; i++) { + cnode = nnode->nbranch[i].cnode; + if (cnode && test_bit(DIRTY_CNODE, &cnode->flags)) { + if (cnode->level == 0) + return cnode; /* cnode is a pnode */ + /* cnode is a nnode */ + return first_dirty_cnode((struct ubifs_nnode *)cnode); + } + } + return (struct ubifs_cnode *)nnode; +} + +/** + * get_cnodes_to_commit - create list of dirty cnodes to commit. + * @c: UBIFS file-system description object + * + * This function returns the number of cnodes to commit. + */ +static int get_cnodes_to_commit(struct ubifs_info *c) +{ + struct ubifs_cnode *cnode, *cnext; + int cnt = 0; + + if (!c->nroot) + return 0; + + if (!test_bit(DIRTY_CNODE, &c->nroot->flags)) + return 0; + + c->lpt_cnext = first_dirty_cnode(c->nroot); + cnode = c->lpt_cnext; + if (!cnode) + return 0; + cnt += 1; + while (1) { + ubifs_assert(!test_bit(COW_ZNODE, &cnode->flags)); + __set_bit(COW_ZNODE, &cnode->flags); + cnext = next_dirty_cnode(cnode); + if (!cnext) { + cnode->cnext = c->lpt_cnext; + break; + } + cnode->cnext = cnext; + cnode = cnext; + cnt += 1; + } + dbg_cmt("committing %d cnodes", cnt); + dbg_lp("committing %d cnodes", cnt); + ubifs_assert(cnt == c->dirty_nn_cnt + c->dirty_pn_cnt); + return cnt; +} + +/** + * upd_ltab - update LPT LEB properties. + * @c: UBIFS file-system description object + * @lnum: LEB number + * @free: amount of free space + * @dirty: amount of dirty space to add + */ +static void upd_ltab(struct ubifs_info *c, int lnum, int free, int dirty) +{ + dbg_lp("LEB %d free %d dirty %d to %d +%d", + lnum, c->ltab[lnum - c->lpt_first].free, + c->ltab[lnum - c->lpt_first].dirty, free, dirty); + ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); + c->ltab[lnum - c->lpt_first].free = free; + c->ltab[lnum - c->lpt_first].dirty += dirty; +} + +/** + * alloc_lpt_leb - allocate an LPT LEB that is empty. + * @c: UBIFS file-system description object + * @lnum: LEB number is passed and returned here + * + * This function finds the next empty LEB in the ltab starting from @lnum. If a + * an empty LEB is found it is returned in @lnum and the function returns %0. + * Otherwise the function returns -ENOSPC. Note however, that LPT is designed + * never to run out of space. + */ +static int alloc_lpt_leb(struct ubifs_info *c, int *lnum) +{ + int i, n; + + n = *lnum - c->lpt_first + 1; + for (i = n; i < c->lpt_lebs; i++) { + if (c->ltab[i].tgc || c->ltab[i].cmt) + continue; + if (c->ltab[i].free == c->leb_size) { + c->ltab[i].cmt = 1; + *lnum = i + c->lpt_first; + return 0; + } + } + + for (i = 0; i < n; i++) { + if (c->ltab[i].tgc || c->ltab[i].cmt) + continue; + if (c->ltab[i].free == c->leb_size) { + c->ltab[i].cmt = 1; + *lnum = i + c->lpt_first; + return 0; + } + } + dbg_err("last LEB %d", *lnum); + dump_stack(); + return -ENOSPC; +} + +/** + * layout_cnodes - layout cnodes for commit. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +static int layout_cnodes(struct ubifs_info *c) +{ + int lnum, offs, len, alen, done_lsave, done_ltab, err; + struct ubifs_cnode *cnode; + + cnode = c->lpt_cnext; + if (!cnode) + return 0; + lnum = c->nhead_lnum; + offs = c->nhead_offs; + /* Try to place lsave and ltab nicely */ + done_lsave = !c->big_lpt; + done_ltab = 0; + if (!done_lsave && offs + c->lsave_sz <= c->leb_size) { + done_lsave = 1; + c->lsave_lnum = lnum; + c->lsave_offs = offs; + offs += c->lsave_sz; + } + + if (offs + c->ltab_sz <= c->leb_size) { + done_ltab = 1; + c->ltab_lnum = lnum; + c->ltab_offs = offs; + offs += c->ltab_sz; + } + + do { + if (cnode->level) { + len = c->nnode_sz; + c->dirty_nn_cnt -= 1; + } else { + len = c->pnode_sz; + c->dirty_pn_cnt -= 1; + } + while (offs + len > c->leb_size) { + alen = ALIGN(offs, c->min_io_size); + upd_ltab(c, lnum, c->leb_size - alen, alen - offs); + err = alloc_lpt_leb(c, &lnum); + if (err) + return err; + offs = 0; + ubifs_assert(lnum >= c->lpt_first && + lnum <= c->lpt_last); + /* Try to place lsave and ltab nicely */ + if (!done_lsave) { + done_lsave = 1; + c->lsave_lnum = lnum; + c->lsave_offs = offs; + offs += c->lsave_sz; + continue; + } + if (!done_ltab) { + done_ltab = 1; + c->ltab_lnum = lnum; + c->ltab_offs = offs; + offs += c->ltab_sz; + continue; + } + break; + } + if (cnode->parent) { + cnode->parent->nbranch[cnode->iip].lnum = lnum; + cnode->parent->nbranch[cnode->iip].offs = offs; + } else { + c->lpt_lnum = lnum; + c->lpt_offs = offs; + } + offs += len; + cnode = cnode->cnext; + } while (cnode && cnode != c->lpt_cnext); + + /* Make sure to place LPT's save table */ + if (!done_lsave) { + if (offs + c->lsave_sz > c->leb_size) { + alen = ALIGN(offs, c->min_io_size); + upd_ltab(c, lnum, c->leb_size - alen, alen - offs); + err = alloc_lpt_leb(c, &lnum); + if (err) + return err; + offs = 0; + ubifs_assert(lnum >= c->lpt_first && + lnum <= c->lpt_last); + } + done_lsave = 1; + c->lsave_lnum = lnum; + c->lsave_offs = offs; + offs += c->lsave_sz; + } + + /* Make sure to place LPT's own lprops table */ + if (!done_ltab) { + if (offs + c->ltab_sz > c->leb_size) { + alen = ALIGN(offs, c->min_io_size); + upd_ltab(c, lnum, c->leb_size - alen, alen - offs); + err = alloc_lpt_leb(c, &lnum); + if (err) + return err; + offs = 0; + ubifs_assert(lnum >= c->lpt_first && + lnum <= c->lpt_last); + } + done_ltab = 1; + c->ltab_lnum = lnum; + c->ltab_offs = offs; + offs += c->ltab_sz; + } + + alen = ALIGN(offs, c->min_io_size); + upd_ltab(c, lnum, c->leb_size - alen, alen - offs); + return 0; +} + +/** + * realloc_lpt_leb - allocate an LPT LEB that is empty. + * @c: UBIFS file-system description object + * @lnum: LEB number is passed and returned here + * + * This function duplicates exactly the results of the function alloc_lpt_leb. + * It is used during end commit to reallocate the same LEB numbers that were + * allocated by alloc_lpt_leb during start commit. + * + * This function finds the next LEB that was allocated by the alloc_lpt_leb + * function starting from @lnum. If a LEB is found it is returned in @lnum and + * the function returns %0. Otherwise the function returns -ENOSPC. + * Note however, that LPT is designed never to run out of space. + */ +static int realloc_lpt_leb(struct ubifs_info *c, int *lnum) +{ + int i, n; + + n = *lnum - c->lpt_first + 1; + for (i = n; i < c->lpt_lebs; i++) + if (c->ltab[i].cmt) { + c->ltab[i].cmt = 0; + *lnum = i + c->lpt_first; + return 0; + } + + for (i = 0; i < n; i++) + if (c->ltab[i].cmt) { + c->ltab[i].cmt = 0; + *lnum = i + c->lpt_first; + return 0; + } + dbg_err("last LEB %d", *lnum); + dump_stack(); + return -ENOSPC; +} + +/** + * write_cnodes - write cnodes for commit. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +static int write_cnodes(struct ubifs_info *c) +{ + int lnum, offs, len, from, err, wlen, alen, done_ltab, done_lsave; + struct ubifs_cnode *cnode; + void *buf = c->lpt_buf; + + cnode = c->lpt_cnext; + if (!cnode) + return 0; + lnum = c->nhead_lnum; + offs = c->nhead_offs; + from = offs; + /* Ensure empty LEB is unmapped */ + if (offs == 0) { + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + /* Try to place lsave and ltab nicely */ + done_lsave = !c->big_lpt; + done_ltab = 0; + if (!done_lsave && offs + c->lsave_sz <= c->leb_size) { + done_lsave = 1; + ubifs_pack_lsave(c, buf + offs, c->lsave); + offs += c->lsave_sz; + } + + if (offs + c->ltab_sz <= c->leb_size) { + done_ltab = 1; + ubifs_pack_ltab(c, buf + offs, c->ltab_cmt); + offs += c->ltab_sz; + } + + /* Loop for each cnode */ + do { + if (cnode->level) + len = c->nnode_sz; + else + len = c->pnode_sz; + while (offs + len > c->leb_size) { + wlen = offs - from; + if (wlen) { + alen = ALIGN(wlen, c->min_io_size); + memset(buf + offs, 0xff, alen - wlen); + err = ubifs_leb_write(c, lnum, buf + from, from, + alen, UBI_SHORTTERM); + if (err) + return err; + } + err = realloc_lpt_leb(c, &lnum); + if (err) + return err; + offs = 0; + from = 0; + ubifs_assert(lnum >= c->lpt_first && + lnum <= c->lpt_last); + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + /* Try to place lsave and ltab nicely */ + if (!done_lsave) { + done_lsave = 1; + ubifs_pack_lsave(c, buf + offs, c->lsave); + offs += c->lsave_sz; + continue; + } + if (!done_ltab) { + done_ltab = 1; + ubifs_pack_ltab(c, buf + offs, c->ltab_cmt); + offs += c->ltab_sz; + continue; + } + break; + } + if (cnode->level) + ubifs_pack_nnode(c, buf + offs, + (struct ubifs_nnode *)cnode); + else + ubifs_pack_pnode(c, buf + offs, + (struct ubifs_pnode *)cnode); + /* + * The reason for the barriers is the same as in case of TNC. + * See comment in 'write_index()'. 'dirty_cow_nnode()' and + * 'dirty_cow_pnode()' are the functions for which this is + * important. + */ + clear_bit(DIRTY_CNODE, &cnode->flags); + smp_mb__before_clear_bit(); + clear_bit(COW_ZNODE, &cnode->flags); + smp_mb__after_clear_bit(); + offs += len; + cnode = cnode->cnext; + } while (cnode && cnode != c->lpt_cnext); + + /* Make sure to place LPT's save table */ + if (!done_lsave) { + if (offs + c->lsave_sz > c->leb_size) { + wlen = offs - from; + alen = ALIGN(wlen, c->min_io_size); + memset(buf + offs, 0xff, alen - wlen); + err = ubifs_leb_write(c, lnum, buf + from, from, alen, + UBI_SHORTTERM); + if (err) + return err; + err = realloc_lpt_leb(c, &lnum); + if (err) + return err; + offs = 0; + ubifs_assert(lnum >= c->lpt_first && + lnum <= c->lpt_last); + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + done_lsave = 1; + ubifs_pack_lsave(c, buf + offs, c->lsave); + offs += c->lsave_sz; + } + + /* Make sure to place LPT's own lprops table */ + if (!done_ltab) { + if (offs + c->ltab_sz > c->leb_size) { + wlen = offs - from; + alen = ALIGN(wlen, c->min_io_size); + memset(buf + offs, 0xff, alen - wlen); + err = ubifs_leb_write(c, lnum, buf + from, from, alen, + UBI_SHORTTERM); + if (err) + return err; + err = realloc_lpt_leb(c, &lnum); + if (err) + return err; + offs = 0; + ubifs_assert(lnum >= c->lpt_first && + lnum <= c->lpt_last); + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + done_ltab = 1; + ubifs_pack_ltab(c, buf + offs, c->ltab_cmt); + offs += c->ltab_sz; + } + + /* Write remaining data in buffer */ + wlen = offs - from; + alen = ALIGN(wlen, c->min_io_size); + memset(buf + offs, 0xff, alen - wlen); + err = ubifs_leb_write(c, lnum, buf + from, from, alen, UBI_SHORTTERM); + if (err) + return err; + c->nhead_lnum = lnum; + c->nhead_offs = ALIGN(offs, c->min_io_size); + + dbg_lp("LPT root is at %d:%d", c->lpt_lnum, c->lpt_offs); + dbg_lp("LPT head is at %d:%d", c->nhead_lnum, c->nhead_offs); + dbg_lp("LPT ltab is at %d:%d", c->ltab_lnum, c->ltab_offs); + if (c->big_lpt) + dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs); + return 0; +} + +/** + * next_pnode - find next pnode. + * @c: UBIFS file-system description object + * @pnode: pnode + * + * This function returns the next pnode or %NULL if there are no more pnodes. + */ +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; + 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); + else + return NULL; + } + + /* Go up while can't go right */ + do { + iip = nnode->iip + 1; + nnode = nnode->parent; + if (!nnode) + return NULL; + /* 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); + if (IS_ERR(nnode)) + return (void *)nnode; + + /* Go down to level 1 */ + while (nnode->level > 1) { + nnode = ubifs_get_nnode(c, nnode, 0); + if (IS_ERR(nnode)) + return (void *)nnode; + } + + return ubifs_get_pnode(c, nnode, 0); +} + +/** + * pnode_lookup - lookup a pnode in the LPT. + * @c: UBIFS file-system description object + * @i: pnode number (0 to main_lebs - 1) + * + * This function returns a pointer to the pnode on success or a negative + * error code on failure. + */ +static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i) +{ + int err, h, iip, shft; + struct ubifs_nnode *nnode; + + if (!c->nroot) { + err = ubifs_read_nnode(c, NULL, 0); + if (err) + return ERR_PTR(err); + } + i <<= UBIFS_LPT_FANOUT_SHIFT; + nnode = c->nroot; + shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT; + for (h = 1; h < c->lpt_hght; h++) { + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + shft -= UBIFS_LPT_FANOUT_SHIFT; + nnode = ubifs_get_nnode(c, nnode, iip); + if (IS_ERR(nnode)) + return ERR_PTR(PTR_ERR(nnode)); + } + iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); + return ubifs_get_pnode(c, nnode, iip); +} + +/** + * add_pnode_dirt - add dirty space to LPT LEB properties. + * @c: UBIFS file-system description object + * @pnode: pnode for which to add dirt + */ +static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode) +{ + ubifs_add_lpt_dirt(c, pnode->parent->nbranch[pnode->iip].lnum, + c->pnode_sz); +} + +/** + * do_make_pnode_dirty - mark a pnode dirty. + * @c: UBIFS file-system description object + * @pnode: pnode to mark dirty + */ +static void do_make_pnode_dirty(struct ubifs_info *c, struct ubifs_pnode *pnode) +{ + /* Assumes cnext list is empty i.e. not called during commit */ + if (!test_and_set_bit(DIRTY_CNODE, &pnode->flags)) { + struct ubifs_nnode *nnode; + + c->dirty_pn_cnt += 1; + add_pnode_dirt(c, pnode); + /* Mark parent and ancestors dirty too */ + nnode = pnode->parent; + while (nnode) { + if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) { + c->dirty_nn_cnt += 1; + ubifs_add_nnode_dirt(c, nnode); + nnode = nnode->parent; + } else + break; + } + } +} + +/** + * make_tree_dirty - mark the entire LEB properties tree dirty. + * @c: UBIFS file-system description object + * + * This function is used by the "small" LPT model to cause the entire LEB + * properties tree to be written. The "small" LPT model does not use LPT + * garbage collection because it is more efficient to write the entire tree + * (because it is small). + * + * This function returns %0 on success and a negative error code on failure. + */ +static int make_tree_dirty(struct ubifs_info *c) +{ + struct ubifs_pnode *pnode; + + pnode = pnode_lookup(c, 0); + while (pnode) { + do_make_pnode_dirty(c, pnode); + pnode = next_pnode(c, pnode); + if (IS_ERR(pnode)) + return PTR_ERR(pnode); + } + return 0; +} + +/** + * need_write_all - determine if the LPT area is running out of free space. + * @c: UBIFS file-system description object + * + * This function returns %1 if the LPT area is running out of free space and %0 + * if it is not. + */ +static int need_write_all(struct ubifs_info *c) +{ + long long free = 0; + int i; + + for (i = 0; i < c->lpt_lebs; i++) { + if (i + c->lpt_first == c->nhead_lnum) + free += c->leb_size - c->nhead_offs; + else if (c->ltab[i].free == c->leb_size) + free += c->leb_size; + else if (c->ltab[i].free + c->ltab[i].dirty == c->leb_size) + free += c->leb_size; + } + /* Less than twice the size left */ + if (free <= c->lpt_sz * 2) + return 1; + return 0; +} + +/** + * lpt_tgc_start - start trivial garbage collection of LPT LEBs. + * @c: UBIFS file-system description object + * + * LPT trivial garbage collection is where a LPT LEB contains only dirty and + * free space and so may be reused as soon as the next commit is completed. + * This function is called during start commit to mark LPT LEBs for trivial GC. + */ +static void lpt_tgc_start(struct ubifs_info *c) +{ + int i; + + for (i = 0; i < c->lpt_lebs; i++) { + if (i + c->lpt_first == c->nhead_lnum) + continue; + if (c->ltab[i].dirty > 0 && + c->ltab[i].free + c->ltab[i].dirty == c->leb_size) { + c->ltab[i].tgc = 1; + c->ltab[i].free = c->leb_size; + c->ltab[i].dirty = 0; + dbg_lp("LEB %d", i + c->lpt_first); + } + } +} + +/** + * lpt_tgc_end - end trivial garbage collection of LPT LEBs. + * @c: UBIFS file-system description object + * + * LPT trivial garbage collection is where a LPT LEB contains only dirty and + * free space and so may be reused as soon as the next commit is completed. + * This function is called after the commit is completed (master node has been + * written) and unmaps LPT LEBs that were marked for trivial GC. + */ +static int lpt_tgc_end(struct ubifs_info *c) +{ + int i, err; + + for (i = 0; i < c->lpt_lebs; i++) + if (c->ltab[i].tgc) { + err = ubifs_leb_unmap(c, i + c->lpt_first); + if (err) + return err; + c->ltab[i].tgc = 0; + dbg_lp("LEB %d", i + c->lpt_first); + } + return 0; +} + +/** + * populate_lsave - fill the lsave array with important LEB numbers. + * @c: the UBIFS file-system description object + * + * This function is only called for the "big" model. It records a small number + * of LEB numbers of important LEBs. Important LEBs are ones that are (from + * most important to least important): empty, freeable, freeable index, dirty + * index, dirty or free. Upon mount, we read this list of LEB numbers and bring + * their pnodes into memory. That will stop us from having to scan the LPT + * straight away. For the "small" model we assume that scanning the LPT is no + * big deal. + */ +static void populate_lsave(struct ubifs_info *c) +{ + struct ubifs_lprops *lprops; + struct ubifs_lpt_heap *heap; + int i, cnt = 0; + + ubifs_assert(c->big_lpt); + if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) { + c->lpt_drty_flgs |= LSAVE_DIRTY; + ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz); + } + list_for_each_entry(lprops, &c->empty_list, list) { + c->lsave[cnt++] = lprops->lnum; + if (cnt >= c->lsave_cnt) + return; + } + list_for_each_entry(lprops, &c->freeable_list, list) { + c->lsave[cnt++] = lprops->lnum; + if (cnt >= c->lsave_cnt) + return; + } + list_for_each_entry(lprops, &c->frdi_idx_list, list) { + c->lsave[cnt++] = lprops->lnum; + if (cnt >= c->lsave_cnt) + return; + } + heap = &c->lpt_heap[LPROPS_DIRTY_IDX - 1]; + for (i = 0; i < heap->cnt; i++) { + c->lsave[cnt++] = heap->arr[i]->lnum; + if (cnt >= c->lsave_cnt) + return; + } + heap = &c->lpt_heap[LPROPS_DIRTY - 1]; + for (i = 0; i < heap->cnt; i++) { + c->lsave[cnt++] = heap->arr[i]->lnum; + if (cnt >= c->lsave_cnt) + return; + } + heap = &c->lpt_heap[LPROPS_FREE - 1]; + for (i = 0; i < heap->cnt; i++) { + c->lsave[cnt++] = heap->arr[i]->lnum; + if (cnt >= c->lsave_cnt) + return; + } + /* Fill it up completely */ + while (cnt < c->lsave_cnt) + c->lsave[cnt++] = c->main_first; +} + +/** + * nnode_lookup - lookup a nnode in the LPT. + * @c: UBIFS file-system description object + * @i: nnode number + * + * This function returns a pointer to the nnode on success or a negative + * error code on failure. + */ +static struct ubifs_nnode *nnode_lookup(struct ubifs_info *c, int i) +{ + int err, iip; + struct ubifs_nnode *nnode; + + if (!c->nroot) { + err = ubifs_read_nnode(c, NULL, 0); + if (err) + return ERR_PTR(err); + } + nnode = c->nroot; + while (1) { + iip = i & (UBIFS_LPT_FANOUT - 1); + i >>= UBIFS_LPT_FANOUT_SHIFT; + if (!i) + break; + nnode = ubifs_get_nnode(c, nnode, iip); + if (IS_ERR(nnode)) + return nnode; + } + return nnode; +} + +/** + * make_nnode_dirty - find a nnode and, if found, make it dirty. + * @c: UBIFS file-system description object + * @node_num: nnode number of nnode to make dirty + * @lnum: LEB number where nnode was written + * @offs: offset where nnode was written + * + * This function is used by LPT garbage collection. LPT garbage collection is + * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection + * simply involves marking all the nodes in the LEB being garbage-collected as + * dirty. The dirty nodes are written next commit, after which the LEB is free + * to be reused. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int make_nnode_dirty(struct ubifs_info *c, int node_num, int lnum, + int offs) +{ + struct ubifs_nnode *nnode; + + nnode = nnode_lookup(c, node_num); + if (IS_ERR(nnode)) + return PTR_ERR(nnode); + if (nnode->parent) { + struct ubifs_nbranch *branch; + + branch = &nnode->parent->nbranch[nnode->iip]; + if (branch->lnum != lnum || branch->offs != offs) + return 0; /* nnode is obsolete */ + } else if (c->lpt_lnum != lnum || c->lpt_offs != offs) + return 0; /* nnode is obsolete */ + /* Assumes cnext list is empty i.e. not called during commit */ + if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) { + c->dirty_nn_cnt += 1; + ubifs_add_nnode_dirt(c, nnode); + /* Mark parent and ancestors dirty too */ + nnode = nnode->parent; + while (nnode) { + if (!test_and_set_bit(DIRTY_CNODE, &nnode->flags)) { + c->dirty_nn_cnt += 1; + ubifs_add_nnode_dirt(c, nnode); + nnode = nnode->parent; + } else + break; + } + } + return 0; +} + +/** + * make_pnode_dirty - find a pnode and, if found, make it dirty. + * @c: UBIFS file-system description object + * @node_num: pnode number of pnode to make dirty + * @lnum: LEB number where pnode was written + * @offs: offset where pnode was written + * + * This function is used by LPT garbage collection. LPT garbage collection is + * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection + * simply involves marking all the nodes in the LEB being garbage-collected as + * dirty. The dirty nodes are written next commit, after which the LEB is free + * to be reused. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int make_pnode_dirty(struct ubifs_info *c, int node_num, int lnum, + int offs) +{ + struct ubifs_pnode *pnode; + struct ubifs_nbranch *branch; + + pnode = pnode_lookup(c, node_num); + if (IS_ERR(pnode)) + return PTR_ERR(pnode); + branch = &pnode->parent->nbranch[pnode->iip]; + if (branch->lnum != lnum || branch->offs != offs) + return 0; + do_make_pnode_dirty(c, pnode); + return 0; +} + +/** + * make_ltab_dirty - make ltab node dirty. + * @c: UBIFS file-system description object + * @lnum: LEB number where ltab was written + * @offs: offset where ltab was written + * + * This function is used by LPT garbage collection. LPT garbage collection is + * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection + * simply involves marking all the nodes in the LEB being garbage-collected as + * dirty. The dirty nodes are written next commit, after which the LEB is free + * to be reused. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int make_ltab_dirty(struct ubifs_info *c, int lnum, int offs) +{ + if (lnum != c->ltab_lnum || offs != c->ltab_offs) + return 0; /* This ltab node is obsolete */ + if (!(c->lpt_drty_flgs & LTAB_DIRTY)) { + c->lpt_drty_flgs |= LTAB_DIRTY; + ubifs_add_lpt_dirt(c, c->ltab_lnum, c->ltab_sz); + } + return 0; +} + +/** + * make_lsave_dirty - make lsave node dirty. + * @c: UBIFS file-system description object + * @lnum: LEB number where lsave was written + * @offs: offset where lsave was written + * + * This function is used by LPT garbage collection. LPT garbage collection is + * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection + * simply involves marking all the nodes in the LEB being garbage-collected as + * dirty. The dirty nodes are written next commit, after which the LEB is free + * to be reused. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int make_lsave_dirty(struct ubifs_info *c, int lnum, int offs) +{ + if (lnum != c->lsave_lnum || offs != c->lsave_offs) + return 0; /* This lsave node is obsolete */ + if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) { + c->lpt_drty_flgs |= LSAVE_DIRTY; + ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz); + } + return 0; +} + +/** + * make_node_dirty - make node dirty. + * @c: UBIFS file-system description object + * @node_type: LPT node type + * @node_num: node number + * @lnum: LEB number where node was written + * @offs: offset where node was written + * + * This function is used by LPT garbage collection. LPT garbage collection is + * used only for the "big" LPT model (c->big_lpt == 1). Garbage collection + * simply involves marking all the nodes in the LEB being garbage-collected as + * dirty. The dirty nodes are written next commit, after which the LEB is free + * to be reused. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int make_node_dirty(struct ubifs_info *c, int node_type, int node_num, + int lnum, int offs) +{ + switch (node_type) { + case UBIFS_LPT_NNODE: + return make_nnode_dirty(c, node_num, lnum, offs); + case UBIFS_LPT_PNODE: + return make_pnode_dirty(c, node_num, lnum, offs); + case UBIFS_LPT_LTAB: + return make_ltab_dirty(c, lnum, offs); + case UBIFS_LPT_LSAVE: + return make_lsave_dirty(c, lnum, offs); + } + return -EINVAL; +} + +/** + * get_lpt_node_len - return the length of a node based on its type. + * @c: UBIFS file-system description object + * @node_type: LPT node type + */ +static int get_lpt_node_len(struct ubifs_info *c, int node_type) +{ + switch (node_type) { + case UBIFS_LPT_NNODE: + return c->nnode_sz; + case UBIFS_LPT_PNODE: + return c->pnode_sz; + case UBIFS_LPT_LTAB: + return c->ltab_sz; + case UBIFS_LPT_LSAVE: + return c->lsave_sz; + } + return 0; +} + +/** + * get_pad_len - return the length of padding in a buffer. + * @c: UBIFS file-system description object + * @buf: buffer + * @len: length of buffer + */ +static int get_pad_len(struct ubifs_info *c, uint8_t *buf, int len) +{ + int offs, pad_len; + + if (c->min_io_size == 1) + return 0; + offs = c->leb_size - len; + pad_len = ALIGN(offs, c->min_io_size) - offs; + return pad_len; +} + +/** + * get_lpt_node_type - return type (and node number) of a node in a buffer. + * @c: UBIFS file-system description object + * @buf: buffer + * @node_num: node number is returned here + */ +static int get_lpt_node_type(struct ubifs_info *c, uint8_t *buf, int *node_num) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int pos = 0, node_type; + + node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS); + *node_num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits); + return node_type; +} + +/** + * is_a_node - determine if a buffer contains a node. + * @c: UBIFS file-system description object + * @buf: buffer + * @len: length of buffer + * + * This function returns %1 if the buffer contains a node or %0 if it does not. + */ +static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len) +{ + uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; + int pos = 0, node_type, node_len; + uint16_t crc, calc_crc; + + node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS); + if (node_type == UBIFS_LPT_NOT_A_NODE) + return 0; + node_len = get_lpt_node_len(c, node_type); + if (!node_len || node_len > len) + return 0; + pos = 0; + addr = buf; + crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS); + calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, + node_len - UBIFS_LPT_CRC_BYTES); + if (crc != calc_crc) + return 0; + return 1; +} + + +/** + * lpt_gc_lnum - garbage collect a LPT LEB. + * @c: UBIFS file-system description object + * @lnum: LEB number to garbage collect + * + * LPT garbage collection is used only for the "big" LPT model + * (c->big_lpt == 1). Garbage collection simply involves marking all the nodes + * in the LEB being garbage-collected as dirty. The dirty nodes are written + * next commit, after which the LEB is free to be reused. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int lpt_gc_lnum(struct ubifs_info *c, int lnum) +{ + int err, len = c->leb_size, node_type, node_num, node_len, offs; + void *buf = c->lpt_buf; + + dbg_lp("LEB %d", lnum); + err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); + if (err) { + ubifs_err("cannot read LEB %d, error %d", lnum, err); + return err; + } + while (1) { + if (!is_a_node(c, buf, len)) { + int pad_len; + + pad_len = get_pad_len(c, buf, len); + if (pad_len) { + buf += pad_len; + len -= pad_len; + continue; + } + return 0; + } + node_type = get_lpt_node_type(c, buf, &node_num); + node_len = get_lpt_node_len(c, node_type); + offs = c->leb_size - len; + ubifs_assert(node_len != 0); + mutex_lock(&c->lp_mutex); + err = make_node_dirty(c, node_type, node_num, lnum, offs); + mutex_unlock(&c->lp_mutex); + if (err) + return err; + buf += node_len; + len -= node_len; + } + return 0; +} + +/** + * lpt_gc - LPT garbage collection. + * @c: UBIFS file-system description object + * + * Select a LPT LEB for LPT garbage collection and call 'lpt_gc_lnum()'. + * Returns %0 on success and a negative error code on failure. + */ +static int lpt_gc(struct ubifs_info *c) +{ + int i, lnum = -1, dirty = 0; + + mutex_lock(&c->lp_mutex); + for (i = 0; i < c->lpt_lebs; i++) { + ubifs_assert(!c->ltab[i].tgc); + if (i + c->lpt_first == c->nhead_lnum || + c->ltab[i].free + c->ltab[i].dirty == c->leb_size) + continue; + if (c->ltab[i].dirty > dirty) { + dirty = c->ltab[i].dirty; + lnum = i + c->lpt_first; + } + } + mutex_unlock(&c->lp_mutex); + if (lnum == -1) + return -ENOSPC; + return lpt_gc_lnum(c, lnum); +} + +/** + * ubifs_lpt_start_commit - UBIFS commit starts. + * @c: the UBIFS file-system description object + * + * This function has to be called when UBIFS starts the commit operation. + * This function "freezes" all currently dirty LEB properties and does not + * change them anymore. Further changes are saved and tracked separately + * because they are not part of this commit. This function returns zero in case + * of success and a negative error code in case of failure. + */ +int ubifs_lpt_start_commit(struct ubifs_info *c) +{ + int err, cnt; + + dbg_lp(""); + + mutex_lock(&c->lp_mutex); + err = dbg_check_ltab(c); + if (err) + goto out; + + if (c->check_lpt_free) { + /* + * We ensure there is enough free space in + * ubifs_lpt_post_commit() by marking nodes dirty. That + * information is lost when we unmount, so we also need + * to check free space once after mounting also. + */ + c->check_lpt_free = 0; + while (need_write_all(c)) { + mutex_unlock(&c->lp_mutex); + err = lpt_gc(c); + if (err) + return err; + mutex_lock(&c->lp_mutex); + } + } + + lpt_tgc_start(c); + + if (!c->dirty_pn_cnt) { + dbg_cmt("no cnodes to commit"); + err = 0; + goto out; + } + + if (!c->big_lpt && need_write_all(c)) { + /* If needed, write everything */ + err = make_tree_dirty(c); + if (err) + goto out; + lpt_tgc_start(c); + } + + if (c->big_lpt) + populate_lsave(c); + + cnt = get_cnodes_to_commit(c); + ubifs_assert(cnt != 0); + + err = layout_cnodes(c); + if (err) + goto out; + + /* Copy the LPT's own lprops for end commit to write */ + memcpy(c->ltab_cmt, c->ltab, + sizeof(struct ubifs_lpt_lprops) * c->lpt_lebs); + c->lpt_drty_flgs &= ~(LTAB_DIRTY | LSAVE_DIRTY); + +out: + mutex_unlock(&c->lp_mutex); + return err; +} + +/** + * free_obsolete_cnodes - free obsolete cnodes for commit end. + * @c: UBIFS file-system description object + */ +static void free_obsolete_cnodes(struct ubifs_info *c) +{ + struct ubifs_cnode *cnode, *cnext; + + cnext = c->lpt_cnext; + if (!cnext) + return; + do { + cnode = cnext; + cnext = cnode->cnext; + if (test_bit(OBSOLETE_CNODE, &cnode->flags)) + kfree(cnode); + else + cnode->cnext = NULL; + } while (cnext != c->lpt_cnext); + c->lpt_cnext = NULL; +} + +/** + * ubifs_lpt_end_commit - finish the commit operation. + * @c: the UBIFS file-system description object + * + * This function has to be called when the commit operation finishes. It + * flushes the changes which were "frozen" by 'ubifs_lprops_start_commit()' to + * the media. Returns zero in case of success and a negative error code in case + * of failure. + */ +int ubifs_lpt_end_commit(struct ubifs_info *c) +{ + int err; + + dbg_lp(""); + + if (!c->lpt_cnext) + return 0; + + err = write_cnodes(c); + if (err) + return err; + + mutex_lock(&c->lp_mutex); + free_obsolete_cnodes(c); + mutex_unlock(&c->lp_mutex); + + return 0; +} + +/** + * ubifs_lpt_post_commit - post commit LPT trivial GC and LPT GC. + * @c: UBIFS file-system description object + * + * LPT trivial GC is completed after a commit. Also LPT GC is done after a + * commit for the "big" LPT model. + */ +int ubifs_lpt_post_commit(struct ubifs_info *c) +{ + int err; + + mutex_lock(&c->lp_mutex); + err = lpt_tgc_end(c); + if (err) + goto out; + if (c->big_lpt) + while (need_write_all(c)) { + mutex_unlock(&c->lp_mutex); + err = lpt_gc(c); + if (err) + return err; + mutex_lock(&c->lp_mutex); + } +out: + mutex_unlock(&c->lp_mutex); + return err; +} + +/** + * first_nnode - find the first nnode in memory. + * @c: UBIFS file-system description object + * @hght: height of tree where nnode found is returned here + * + * This function returns a pointer to the nnode found or %NULL if no nnode is + * found. This function is a helper to 'ubifs_lpt_free()'. + */ +static struct ubifs_nnode *first_nnode(struct ubifs_info *c, int *hght) +{ + struct ubifs_nnode *nnode; + int h, i, found; + + nnode = c->nroot; + *hght = 0; + if (!nnode) + return NULL; + for (h = 1; h < c->lpt_hght; h++) { + found = 0; + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + if (nnode->nbranch[i].nnode) { + found = 1; + nnode = nnode->nbranch[i].nnode; + *hght = h; + break; + } + } + if (!found) + break; + } + return nnode; +} + +/** + * next_nnode - find the next nnode in memory. + * @c: UBIFS file-system description object + * @nnode: nnode from which to start. + * @hght: height of tree where nnode is, is passed and returned here + * + * This function returns a pointer to the nnode found or %NULL if no nnode is + * found. This function is a helper to 'ubifs_lpt_free()'. + */ +static struct ubifs_nnode *next_nnode(struct ubifs_info *c, + struct ubifs_nnode *nnode, int *hght) +{ + struct ubifs_nnode *parent; + int iip, h, i, found; + + parent = nnode->parent; + if (!parent) + return NULL; + if (nnode->iip == UBIFS_LPT_FANOUT - 1) { + *hght -= 1; + return parent; + } + for (iip = nnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) { + nnode = parent->nbranch[iip].nnode; + if (nnode) + break; + } + if (!nnode) { + *hght -= 1; + return parent; + } + for (h = *hght + 1; h < c->lpt_hght; h++) { + found = 0; + for (i = 0; i < UBIFS_LPT_FANOUT; i++) { + if (nnode->nbranch[i].nnode) { + found = 1; + nnode = nnode->nbranch[i].nnode; + *hght = h; + break; + } + } + if (!found) + break; + } + return nnode; +} + +/** + * ubifs_lpt_free - free resources owned by the LPT. + * @c: UBIFS file-system description object + * @wr_only: free only resources used for writing + */ +void ubifs_lpt_free(struct ubifs_info *c, int wr_only) +{ + struct ubifs_nnode *nnode; + int i, hght; + + /* Free write-only things first */ + + free_obsolete_cnodes(c); /* Leftover from a failed commit */ + + vfree(c->ltab_cmt); + c->ltab_cmt = NULL; + vfree(c->lpt_buf); + c->lpt_buf = NULL; + kfree(c->lsave); + c->lsave = NULL; + + if (wr_only) + return; + + /* Now free the rest */ + + nnode = first_nnode(c, &hght); + while (nnode) { + for (i = 0; i < UBIFS_LPT_FANOUT; i++) + kfree(nnode->nbranch[i].nnode); + nnode = next_nnode(c, nnode, &hght); + } + for (i = 0; i < LPROPS_HEAP_CNT; i++) + kfree(c->lpt_heap[i].arr); + kfree(c->dirty_idx.arr); + kfree(c->nroot); + vfree(c->ltab); + kfree(c->lpt_nod_buf); +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +/** + * dbg_is_all_ff - determine if a buffer contains only 0xff bytes. + * @buf: buffer + * @len: buffer length + */ +static int dbg_is_all_ff(uint8_t *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) + if (buf[i] != 0xff) + return 0; + return 1; +} + +/** + * dbg_is_nnode_dirty - determine if a nnode is dirty. + * @c: the UBIFS file-system description object + * @lnum: LEB number where nnode was written + * @offs: offset where nnode was written + */ +static int dbg_is_nnode_dirty(struct ubifs_info *c, int lnum, int offs) +{ + struct ubifs_nnode *nnode; + int hght; + + /* Entire tree is in memory so first_nnode / next_nnode are ok */ + nnode = first_nnode(c, &hght); + for (; nnode; nnode = next_nnode(c, nnode, &hght)) { + struct ubifs_nbranch *branch; + + cond_resched(); + if (nnode->parent) { + branch = &nnode->parent->nbranch[nnode->iip]; + if (branch->lnum != lnum || branch->offs != offs) + continue; + if (test_bit(DIRTY_CNODE, &nnode->flags)) + return 1; + return 0; + } else { + if (c->lpt_lnum != lnum || c->lpt_offs != offs) + continue; + if (test_bit(DIRTY_CNODE, &nnode->flags)) + return 1; + return 0; + } + } + return 1; +} + +/** + * dbg_is_pnode_dirty - determine if a pnode is dirty. + * @c: the UBIFS file-system description object + * @lnum: LEB number where pnode was written + * @offs: offset where pnode was written + */ +static int dbg_is_pnode_dirty(struct ubifs_info *c, int lnum, int offs) +{ + int i, cnt; + + cnt = DIV_ROUND_UP(c->main_lebs, UBIFS_LPT_FANOUT); + for (i = 0; i < cnt; i++) { + struct ubifs_pnode *pnode; + struct ubifs_nbranch *branch; + + cond_resched(); + pnode = pnode_lookup(c, i); + if (IS_ERR(pnode)) + return PTR_ERR(pnode); + branch = &pnode->parent->nbranch[pnode->iip]; + if (branch->lnum != lnum || branch->offs != offs) + continue; + if (test_bit(DIRTY_CNODE, &pnode->flags)) + return 1; + return 0; + } + return 1; +} + +/** + * dbg_is_ltab_dirty - determine if a ltab node is dirty. + * @c: the UBIFS file-system description object + * @lnum: LEB number where ltab node was written + * @offs: offset where ltab node was written + */ +static int dbg_is_ltab_dirty(struct ubifs_info *c, int lnum, int offs) +{ + if (lnum != c->ltab_lnum || offs != c->ltab_offs) + return 1; + return (c->lpt_drty_flgs & LTAB_DIRTY) != 0; +} + +/** + * dbg_is_lsave_dirty - determine if a lsave node is dirty. + * @c: the UBIFS file-system description object + * @lnum: LEB number where lsave node was written + * @offs: offset where lsave node was written + */ +static int dbg_is_lsave_dirty(struct ubifs_info *c, int lnum, int offs) +{ + if (lnum != c->lsave_lnum || offs != c->lsave_offs) + return 1; + return (c->lpt_drty_flgs & LSAVE_DIRTY) != 0; +} + +/** + * dbg_is_node_dirty - determine if a node is dirty. + * @c: the UBIFS file-system description object + * @node_type: node type + * @lnum: LEB number where node was written + * @offs: offset where node was written + */ +static int dbg_is_node_dirty(struct ubifs_info *c, int node_type, int lnum, + int offs) +{ + switch (node_type) { + case UBIFS_LPT_NNODE: + return dbg_is_nnode_dirty(c, lnum, offs); + case UBIFS_LPT_PNODE: + return dbg_is_pnode_dirty(c, lnum, offs); + case UBIFS_LPT_LTAB: + return dbg_is_ltab_dirty(c, lnum, offs); + case UBIFS_LPT_LSAVE: + return dbg_is_lsave_dirty(c, lnum, offs); + } + return 1; +} + +/** + * dbg_check_ltab_lnum - check the ltab for a LPT LEB number. + * @c: the UBIFS file-system description object + * @lnum: LEB number where node was written + * @offs: offset where node was written + * + * This function returns %0 on success and a negative error code on failure. + */ +static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) +{ + int err, len = c->leb_size, dirty = 0, node_type, node_num, node_len; + int ret; + void *buf = c->dbg_buf; + + dbg_lp("LEB %d", lnum); + err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); + if (err) { + dbg_msg("ubi_read failed, LEB %d, error %d", lnum, err); + return err; + } + while (1) { + if (!is_a_node(c, buf, len)) { + int i, pad_len; + + pad_len = get_pad_len(c, buf, len); + if (pad_len) { + buf += pad_len; + len -= pad_len; + dirty += pad_len; + continue; + } + if (!dbg_is_all_ff(buf, len)) { + dbg_msg("invalid empty space in LEB %d at %d", + lnum, c->leb_size - len); + err = -EINVAL; + } + i = lnum - c->lpt_first; + if (len != c->ltab[i].free) { + dbg_msg("invalid free space in LEB %d " + "(free %d, expected %d)", + lnum, len, c->ltab[i].free); + err = -EINVAL; + } + if (dirty != c->ltab[i].dirty) { + dbg_msg("invalid dirty space in LEB %d " + "(dirty %d, expected %d)", + lnum, dirty, c->ltab[i].dirty); + err = -EINVAL; + } + return err; + } + node_type = get_lpt_node_type(c, buf, &node_num); + node_len = get_lpt_node_len(c, node_type); + ret = dbg_is_node_dirty(c, node_type, lnum, c->leb_size - len); + if (ret == 1) + dirty += node_len; + buf += node_len; + len -= node_len; + } +} + +/** + * dbg_check_ltab - check the free and dirty space in the ltab. + * @c: the UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +int dbg_check_ltab(struct ubifs_info *c) +{ + int lnum, err, i, cnt; + + if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) + return 0; + + /* Bring the entire tree into memory */ + cnt = DIV_ROUND_UP(c->main_lebs, UBIFS_LPT_FANOUT); + for (i = 0; i < cnt; i++) { + struct ubifs_pnode *pnode; + + pnode = pnode_lookup(c, i); + if (IS_ERR(pnode)) + return PTR_ERR(pnode); + cond_resched(); + } + + /* Check nodes */ + err = dbg_check_lpt_nodes(c, (struct ubifs_cnode *)c->nroot, 0, 0); + if (err) + return err; + + /* Check each LEB */ + for (lnum = c->lpt_first; lnum <= c->lpt_last; lnum++) { + err = dbg_check_ltab_lnum(c, lnum); + if (err) { + dbg_err("failed at LEB %d", lnum); + return err; + } + } + + dbg_lp("succeeded"); + return 0; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c new file mode 100644 index 0000000..71d5493 --- /dev/null +++ b/fs/ubifs/master.c @@ -0,0 +1,387 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* This file implements reading and writing the master node */ + +#include "ubifs.h" + +/** + * scan_for_master - search the valid master node. + * @c: UBIFS file-system description object + * + * This function scans the master node LEBs and search for the latest master + * node. Returns zero in case of success and a negative error code in case of + * failure. + */ +static int scan_for_master(struct ubifs_info *c) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + int lnum, offs = 0, nodes_cnt; + + lnum = UBIFS_MST_LNUM; + + sleb = ubifs_scan(c, lnum, 0, c->sbuf); + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + nodes_cnt = sleb->nodes_cnt; + if (nodes_cnt > 0) { + snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, + list); + if (snod->type != UBIFS_MST_NODE) + goto out; + memcpy(c->mst_node, snod->node, snod->len); + offs = snod->offs; + } + ubifs_scan_destroy(sleb); + + lnum += 1; + + sleb = ubifs_scan(c, lnum, 0, c->sbuf); + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + if (sleb->nodes_cnt != nodes_cnt) + goto out; + if (!sleb->nodes_cnt) + goto out; + snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list); + if (snod->type != UBIFS_MST_NODE) + goto out; + if (snod->offs != offs) + goto out; + if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, + (void *)snod->node + UBIFS_CH_SZ, + UBIFS_MST_NODE_SZ - UBIFS_CH_SZ)) + goto out; + c->mst_offs = offs; + ubifs_scan_destroy(sleb); + return 0; + +out: + ubifs_scan_destroy(sleb); + return -EINVAL; +} + +/** + * validate_master - validate master node. + * @c: UBIFS file-system description object + * + * This function validates data which was read from master node. Returns zero + * if the data is all right and %-EINVAL if not. + */ +static int validate_master(const struct ubifs_info *c) +{ + long long main_sz; + int err; + + if (c->max_sqnum >= SQNUM_WATERMARK) { + err = 1; + goto out; + } + + if (c->cmt_no >= c->max_sqnum) { + err = 2; + goto out; + } + + if (c->highest_inum >= INUM_WATERMARK) { + err = 3; + goto out; + } + + if (c->lhead_lnum < UBIFS_LOG_LNUM || + c->lhead_lnum >= UBIFS_LOG_LNUM + c->log_lebs || + c->lhead_offs < 0 || c->lhead_offs >= c->leb_size || + c->lhead_offs & (c->min_io_size - 1)) { + err = 4; + goto out; + } + + if (c->zroot.lnum >= c->leb_cnt || c->zroot.lnum < c->main_first || + c->zroot.offs >= c->leb_size || c->zroot.offs & 7) { + err = 5; + goto out; + } + + if (c->zroot.len < c->ranges[UBIFS_IDX_NODE].min_len || + c->zroot.len > c->ranges[UBIFS_IDX_NODE].max_len) { + err = 6; + goto out; + } + + if (c->gc_lnum >= c->leb_cnt || c->gc_lnum < c->main_first) { + err = 7; + goto out; + } + + if (c->ihead_lnum >= c->leb_cnt || c->ihead_lnum < c->main_first || + c->ihead_offs % c->min_io_size || c->ihead_offs < 0 || + c->ihead_offs > c->leb_size || c->ihead_offs & 7) { + err = 8; + goto out; + } + + main_sz = (long long)c->main_lebs * c->leb_size; + if (c->old_idx_sz & 7 || c->old_idx_sz >= main_sz) { + err = 9; + goto out; + } + + if (c->lpt_lnum < c->lpt_first || c->lpt_lnum > c->lpt_last || + c->lpt_offs < 0 || c->lpt_offs + c->nnode_sz > c->leb_size) { + err = 10; + goto out; + } + + if (c->nhead_lnum < c->lpt_first || c->nhead_lnum > c->lpt_last || + c->nhead_offs < 0 || c->nhead_offs % c->min_io_size || + c->nhead_offs > c->leb_size) { + err = 11; + goto out; + } + + if (c->ltab_lnum < c->lpt_first || c->ltab_lnum > c->lpt_last || + c->ltab_offs < 0 || + c->ltab_offs + c->ltab_sz > c->leb_size) { + err = 12; + goto out; + } + + if (c->big_lpt && (c->lsave_lnum < c->lpt_first || + c->lsave_lnum > c->lpt_last || c->lsave_offs < 0 || + c->lsave_offs + c->lsave_sz > c->leb_size)) { + err = 13; + goto out; + } + + if (c->lscan_lnum < c->main_first || c->lscan_lnum >= c->leb_cnt) { + err = 14; + goto out; + } + + if (c->lst.empty_lebs < 0 || c->lst.empty_lebs > c->main_lebs - 2) { + err = 15; + goto out; + } + + if (c->lst.idx_lebs < 0 || c->lst.idx_lebs > c->main_lebs - 1) { + err = 16; + goto out; + } + + if (c->lst.total_free < 0 || c->lst.total_free > main_sz || + c->lst.total_free & 7) { + err = 17; + goto out; + } + + if (c->lst.total_dirty < 0 || (c->lst.total_dirty & 7)) { + err = 18; + goto out; + } + + if (c->lst.total_used < 0 || (c->lst.total_used & 7)) { + err = 19; + goto out; + } + + if (c->lst.total_free + c->lst.total_dirty + + c->lst.total_used > main_sz) { + err = 20; + goto out; + } + + if (c->lst.total_dead + c->lst.total_dark + + c->lst.total_used + c->old_idx_sz > main_sz) { + err = 21; + goto out; + } + + if (c->lst.total_dead < 0 || + c->lst.total_dead > c->lst.total_free + c->lst.total_dirty || + c->lst.total_dead & 7) { + err = 22; + goto out; + } + + if (c->lst.total_dark < 0 || + c->lst.total_dark > c->lst.total_free + c->lst.total_dirty || + c->lst.total_dark & 7) { + err = 23; + goto out; + } + + return 0; + +out: + ubifs_err("bad master node at offset %d error %d", c->mst_offs, err); + dbg_dump_node(c, c->mst_node); + return -EINVAL; +} + +/** + * ubifs_read_master - read master node. + * @c: UBIFS file-system description object + * + * This function finds and reads the master node during file-system mount. If + * the flash is empty, it creates default master node as well. Returns zero in + * case of success and a negative error code in case of failure. + */ +int ubifs_read_master(struct ubifs_info *c) +{ + int err, old_leb_cnt; + + c->mst_node = kzalloc(c->mst_node_alsz, GFP_KERNEL); + if (!c->mst_node) + return -ENOMEM; + + err = scan_for_master(c); + if (err) { + err = ubifs_recover_master_node(c); + if (err) + /* + * Note, we do not free 'c->mst_node' here because the + * unmount routine will take care of this. + */ + return err; + } + + /* Make sure that the recovery flag is clear */ + c->mst_node->flags &= cpu_to_le32(~UBIFS_MST_RCVRY); + + c->max_sqnum = le64_to_cpu(c->mst_node->ch.sqnum); + c->highest_inum = le64_to_cpu(c->mst_node->highest_inum); + c->cmt_no = le64_to_cpu(c->mst_node->cmt_no); + c->zroot.lnum = le32_to_cpu(c->mst_node->root_lnum); + c->zroot.offs = le32_to_cpu(c->mst_node->root_offs); + c->zroot.len = le32_to_cpu(c->mst_node->root_len); + c->lhead_lnum = le32_to_cpu(c->mst_node->log_lnum); + c->gc_lnum = le32_to_cpu(c->mst_node->gc_lnum); + c->ihead_lnum = le32_to_cpu(c->mst_node->ihead_lnum); + c->ihead_offs = le32_to_cpu(c->mst_node->ihead_offs); + c->old_idx_sz = le64_to_cpu(c->mst_node->index_size); + c->lpt_lnum = le32_to_cpu(c->mst_node->lpt_lnum); + c->lpt_offs = le32_to_cpu(c->mst_node->lpt_offs); + c->nhead_lnum = le32_to_cpu(c->mst_node->nhead_lnum); + c->nhead_offs = le32_to_cpu(c->mst_node->nhead_offs); + c->ltab_lnum = le32_to_cpu(c->mst_node->ltab_lnum); + c->ltab_offs = le32_to_cpu(c->mst_node->ltab_offs); + c->lsave_lnum = le32_to_cpu(c->mst_node->lsave_lnum); + c->lsave_offs = le32_to_cpu(c->mst_node->lsave_offs); + c->lscan_lnum = le32_to_cpu(c->mst_node->lscan_lnum); + c->lst.empty_lebs = le32_to_cpu(c->mst_node->empty_lebs); + c->lst.idx_lebs = le32_to_cpu(c->mst_node->idx_lebs); + old_leb_cnt = le32_to_cpu(c->mst_node->leb_cnt); + c->lst.total_free = le64_to_cpu(c->mst_node->total_free); + c->lst.total_dirty = le64_to_cpu(c->mst_node->total_dirty); + c->lst.total_used = le64_to_cpu(c->mst_node->total_used); + c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead); + c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark); + + c->calc_idx_sz = c->old_idx_sz; + + if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS)) + c->no_orphs = 1; + + if (old_leb_cnt != c->leb_cnt) { + /* The file system has been resized */ + int growth = c->leb_cnt - old_leb_cnt; + + if (c->leb_cnt < old_leb_cnt || + c->leb_cnt < UBIFS_MIN_LEB_CNT) { + ubifs_err("bad leb_cnt on master node"); + dbg_dump_node(c, c->mst_node); + return -EINVAL; + } + + dbg_mnt("Auto resizing (master) from %d LEBs to %d LEBs", + old_leb_cnt, c->leb_cnt); + c->lst.empty_lebs += growth; + c->lst.total_free += growth * (long long)c->leb_size; + c->lst.total_dark += growth * (long long)c->dark_wm; + + /* + * Reflect changes back onto the master node. N.B. the master + * node gets written immediately whenever mounting (or + * remounting) in read-write mode, so we do not need to write it + * here. + */ + c->mst_node->leb_cnt = cpu_to_le32(c->leb_cnt); + c->mst_node->empty_lebs = cpu_to_le32(c->lst.empty_lebs); + c->mst_node->total_free = cpu_to_le64(c->lst.total_free); + c->mst_node->total_dark = cpu_to_le64(c->lst.total_dark); + } + + err = validate_master(c); + if (err) + return err; + + err = dbg_old_index_check_init(c, &c->zroot); + + return err; +} + +/** + * ubifs_write_master - write master node. + * @c: UBIFS file-system description object + * + * This function writes the master node. The caller has to take the + * @c->mst_mutex lock before calling this function. Returns zero in case of + * success and a negative error code in case of failure. The master node is + * written twice to enable recovery. + */ +int ubifs_write_master(struct ubifs_info *c) +{ + int err, lnum, offs, len; + + if (c->ro_media) + return -EINVAL; + + lnum = UBIFS_MST_LNUM; + offs = c->mst_offs + c->mst_node_alsz; + len = UBIFS_MST_NODE_SZ; + + if (offs + UBIFS_MST_NODE_SZ > c->leb_size) { + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + offs = 0; + } + + c->mst_offs = offs; + c->mst_node->highest_inum = cpu_to_le64(c->highest_inum); + + err = ubifs_write_node(c, c->mst_node, len, lnum, offs, UBI_SHORTTERM); + if (err) + return err; + + lnum += 1; + + if (offs == 0) { + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + err = ubifs_write_node(c, c->mst_node, len, lnum, offs, UBI_SHORTTERM); + + return err; +} diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h new file mode 100644 index 0000000..4beccfc --- /dev/null +++ b/fs/ubifs/misc.h @@ -0,0 +1,342 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file contains miscellaneous helper functions. + */ + +#ifndef __UBIFS_MISC_H__ +#define __UBIFS_MISC_H__ + +/** + * ubifs_zn_dirty - check if znode is dirty. + * @znode: znode to check + * + * This helper function returns %1 if @znode is dirty and %0 otherwise. + */ +static inline int ubifs_zn_dirty(const struct ubifs_znode *znode) +{ + return !!test_bit(DIRTY_ZNODE, &znode->flags); +} + +/** + * ubifs_wake_up_bgt - wake up background thread. + * @c: UBIFS file-system description object + */ +static inline void ubifs_wake_up_bgt(struct ubifs_info *c) +{ + if (c->bgt && !c->need_bgt) { + c->need_bgt = 1; + wake_up_process(c->bgt); + } +} + +/** + * ubifs_tnc_find_child - find next child in znode. + * @znode: znode to search at + * @start: the zbranch index to start at + * + * This helper function looks for znode child starting at index @start. Returns + * the child or %NULL if no children were found. + */ +static inline struct ubifs_znode * +ubifs_tnc_find_child(struct ubifs_znode *znode, int start) +{ + while (start < znode->child_cnt) { + if (znode->zbranch[start].znode) + return znode->zbranch[start].znode; + start += 1; + } + + return NULL; +} + +/** + * ubifs_inode - get UBIFS inode information by VFS 'struct inode' object. + * @inode: the VFS 'struct inode' pointer + */ +static inline struct ubifs_inode *ubifs_inode(const struct inode *inode) +{ + return container_of(inode, struct ubifs_inode, vfs_inode); +} + +/** + * ubifs_ro_mode - switch UBIFS to read read-only mode. + * @c: UBIFS file-system description object + * @err: error code which is the reason of switching to R/O mode + */ +static inline void ubifs_ro_mode(struct ubifs_info *c, int err) +{ + if (!c->ro_media) { + c->ro_media = 1; + ubifs_warn("switched to read-only mode, error %d", err); + dbg_dump_stack(); + } +} + +/** + * ubifs_compr_present - check if compressor was compiled in. + * @compr_type: compressor type to check + * + * This function returns %1 of compressor of type @compr_type is present, and + * %0 if not. + */ +static inline int ubifs_compr_present(int compr_type) +{ + ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); + return !!ubifs_compressors[compr_type]->capi_name; +} + +/** + * ubifs_compr_name - get compressor name string by its type. + * @compr_type: compressor type + * + * This function returns compressor type string. + */ +static inline const char *ubifs_compr_name(int compr_type) +{ + ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); + return ubifs_compressors[compr_type]->name; +} + +/** + * ubifs_wbuf_sync - synchronize write-buffer. + * @wbuf: write-buffer to synchronize + * + * This is the same as as 'ubifs_wbuf_sync_nolock()' but it does not assume + * that the write-buffer is already locked. + */ +static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf) +{ + int err; + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + err = ubifs_wbuf_sync_nolock(wbuf); + mutex_unlock(&wbuf->io_mutex); + return err; +} + +/** + * ubifs_leb_unmap - unmap an LEB. + * @c: UBIFS file-system description object + * @lnum: LEB number to unmap + * + * This function returns %0 on success and a negative error code on failure. + */ +static inline int ubifs_leb_unmap(const struct ubifs_info *c, int lnum) +{ + int err; + + if (c->ro_media) + return -EROFS; + err = ubi_leb_unmap(c->ubi, lnum); + if (err) { + ubifs_err("unmap LEB %d failed, error %d", lnum, err); + return err; + } + + return 0; +} + +/** + * ubifs_leb_write - write to a LEB. + * @c: UBIFS file-system description object + * @lnum: LEB number to write + * @buf: buffer to write from + * @offs: offset within LEB to write to + * @len: length to write + * @dtype: data type + * + * This function returns %0 on success and a negative error code on failure. + */ +static inline int ubifs_leb_write(const struct ubifs_info *c, int lnum, + const void *buf, int offs, int len, int dtype) +{ + int err; + + if (c->ro_media) + return -EROFS; + err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype); + if (err) { + ubifs_err("writing %d bytes at %d:%d, error %d", + len, lnum, offs, err); + return err; + } + + return 0; +} + +/** + * ubifs_leb_change - atomic LEB change. + * @c: UBIFS file-system description object + * @lnum: LEB number to write + * @buf: buffer to write from + * @len: length to write + * @dtype: data type + * + * This function returns %0 on success and a negative error code on failure. + */ +static inline int ubifs_leb_change(const struct ubifs_info *c, int lnum, + const void *buf, int len, int dtype) +{ + int err; + + if (c->ro_media) + return -EROFS; + err = ubi_leb_change(c->ubi, lnum, buf, len, dtype); + if (err) { + ubifs_err("changing %d bytes in LEB %d, error %d", + len, lnum, err); + return err; + } + + return 0; +} + +/** + * ubifs_encode_dev - encode device node IDs. + * @dev: UBIFS device node information + * @rdev: device IDs to encode + * + * This is a helper function which encodes major/minor numbers of a device node + * into UBIFS device node description. We use standard Linux "new" and "huge" + * encodings. + */ +static inline int ubifs_encode_dev(union ubifs_dev_desc *dev, dev_t rdev) +{ + if (new_valid_dev(rdev)) { + dev->new = cpu_to_le32(new_encode_dev(rdev)); + return sizeof(dev->new); + } else { + dev->huge = cpu_to_le64(huge_encode_dev(rdev)); + return sizeof(dev->huge); + } +} + +/** + * ubifs_add_dirt - add dirty space to LEB properties. + * @c: the UBIFS file-system description object + * @lnum: LEB to add dirty space for + * @dirty: dirty space to add + * + * This is a helper function which increased amount of dirty LEB space. Returns + * zero in case of success and a negative error code in case of failure. + */ +static inline int ubifs_add_dirt(struct ubifs_info *c, int lnum, int dirty) +{ + return ubifs_update_one_lp(c, lnum, LPROPS_NC, dirty, 0, 0); +} + +/** + * ubifs_return_leb - return LEB to lprops. + * @c: the UBIFS file-system description object + * @lnum: LEB to return + * + * This helper function cleans the "taken" flag of a logical eraseblock in the + * lprops. Returns zero in case of success and a negative error code in case of + * failure. + */ +static inline int ubifs_return_leb(struct ubifs_info *c, int lnum) +{ + return ubifs_change_one_lp(c, lnum, LPROPS_NC, LPROPS_NC, 0, + LPROPS_TAKEN, 0); +} + +/** + * ubifs_idx_node_sz - return index node size. + * @c: the UBIFS file-system description object + * @child_cnt: number of children of this index node + */ +static inline int ubifs_idx_node_sz(const struct ubifs_info *c, int child_cnt) +{ + return UBIFS_IDX_NODE_SZ + (UBIFS_BRANCH_SZ + c->key_len) * child_cnt; +} + +/** + * ubifs_idx_branch - return pointer to an index branch. + * @c: the UBIFS file-system description object + * @idx: index node + * @bnum: branch number + */ +static inline +struct ubifs_branch *ubifs_idx_branch(const struct ubifs_info *c, + const struct ubifs_idx_node *idx, + int bnum) +{ + return (struct ubifs_branch *)((void *)idx->branches + + (UBIFS_BRANCH_SZ + c->key_len) * bnum); +} + +/** + * ubifs_idx_key - return pointer to an index key. + * @c: the UBIFS file-system description object + * @idx: index node + */ +static inline void *ubifs_idx_key(const struct ubifs_info *c, + const struct ubifs_idx_node *idx) +{ + return (void *)((struct ubifs_branch *)idx->branches)->key; +} + +/** + * ubifs_reported_space - calculate reported free space. + * @c: the UBIFS file-system description object + * @free: amount of free space + * + * This function calculates amount of free space which will be reported to + * user-space. User-space application tend to expect that if the file-system + * (e.g., via the 'statfs()' call) reports that it has N bytes available, they + * are able to write a file of size N. UBIFS attaches node headers to each data + * node and it has to write indexind nodes as well. This introduces additional + * overhead, and UBIFS it has to report sligtly less free space to meet the + * above expectetion. + * + * This function assumes free space is made up of uncompressed data nodes and + * full index nodes (one per data node, doubled because we always allow enough + * space to write the index twice). + * + * Note, the calculation is pessimistic, which means that most of the time + * UBIFS reports less space than it actually has. + */ +static inline long long ubifs_reported_space(const struct ubifs_info *c, + uint64_t free) +{ + int divisor, factor; + + divisor = UBIFS_MAX_DATA_NODE_SZ + (c->max_idx_node_sz << 1); + factor = UBIFS_MAX_DATA_NODE_SZ - UBIFS_DATA_NODE_SZ; + do_div(free, divisor); + + return free * factor; +} + +/** + * ubifs_current_time - round current time to time granularity. + * @inode: inode + */ +static inline struct timespec ubifs_current_time(struct inode *inode) +{ + return (inode->i_sb->s_time_gran < NSEC_PER_SEC) ? + current_fs_time(inode->i_sb) : CURRENT_TIME_SEC; +} + +#endif /* __UBIFS_MISC_H__ */ diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c new file mode 100644 index 0000000..3afeb92 --- /dev/null +++ b/fs/ubifs/orphan.c @@ -0,0 +1,958 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Adrian Hunter + */ + +#include "ubifs.h" + +/* + * An orphan is an inode number whose inode node has been committed to the index + * with a link count of zero. That happens when an open file is deleted + * (unlinked) and then a commit is run. In the normal course of events the inode + * would be deleted when the file is closed. However in the case of an unclean + * unmount, orphans need to be accounted for. After an unclean unmount, the + * orphans' inodes must be deleted which means either scanning the entire index + * looking for them, or keeping a list on flash somewhere. This unit implements + * the latter approach. + * + * The orphan area is a fixed number of LEBs situated between the LPT area and + * the main area. The number of orphan area LEBs is specified when the file + * system is created. The minimum number is 1. The size of the orphan area + * should be so that it can hold the maximum number of orphans that are expected + * to ever exist at one time. + * + * The number of orphans that can fit in a LEB is: + * + * (c->leb_size - UBIFS_ORPH_NODE_SZ) / sizeof(__le64) + * + * For example: a 15872 byte LEB can fit 1980 orphans so 1 LEB may be enough. + * + * 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 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. + */ + +#ifdef CONFIG_UBIFS_FS_DEBUG +static int dbg_check_orphans(struct ubifs_info *c); +#else +#define dbg_check_orphans(c) 0 +#endif + +/** + * ubifs_add_orphan - add an orphan. + * @c: UBIFS file-system description object + * @inum: orphan inode number + * + * Add an orphan. This function is called when an inodes link count drops to + * zero. + */ +int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) +{ + struct ubifs_orphan *orphan, *o; + struct rb_node **p, *parent = NULL; + + orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS); + if (!orphan) + return -ENOMEM; + orphan->inum = inum; + orphan->new = 1; + + spin_lock(&c->orphan_lock); + if (c->tot_orphans >= c->max_orphans) { + spin_unlock(&c->orphan_lock); + kfree(orphan); + return -ENFILE; + } + p = &c->orph_tree.rb_node; + while (*p) { + parent = *p; + o = rb_entry(parent, struct ubifs_orphan, rb); + if (inum < o->inum) + p = &(*p)->rb_left; + else if (inum > o->inum) + p = &(*p)->rb_right; + else { + dbg_err("orphaned twice"); + spin_unlock(&c->orphan_lock); + kfree(orphan); + return 0; + } + } + c->tot_orphans += 1; + c->new_orphans += 1; + rb_link_node(&orphan->rb, parent, p); + rb_insert_color(&orphan->rb, &c->orph_tree); + list_add_tail(&orphan->list, &c->orph_list); + list_add_tail(&orphan->new_list, &c->orph_new); + spin_unlock(&c->orphan_lock); + dbg_gen("ino %lu", inum); + return 0; +} + +/** + * ubifs_delete_orphan - delete an orphan. + * @c: UBIFS file-system description object + * @inum: orphan inode number + * + * Delete an orphan. This function is called when an inode is deleted. + */ +void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) +{ + struct ubifs_orphan *o; + struct rb_node *p; + + spin_lock(&c->orphan_lock); + p = c->orph_tree.rb_node; + while (p) { + o = rb_entry(p, struct ubifs_orphan, rb); + if (inum < o->inum) + p = p->rb_left; + else if (inum > o->inum) + p = p->rb_right; + else { + if (o->dnext) { + spin_unlock(&c->orphan_lock); + dbg_gen("deleted twice ino %lu", inum); + return; + } + if (o->cnext) { + o->dnext = c->orph_dnext; + c->orph_dnext = o; + spin_unlock(&c->orphan_lock); + dbg_gen("delete later ino %lu", inum); + return; + } + rb_erase(p, &c->orph_tree); + list_del(&o->list); + c->tot_orphans -= 1; + if (o->new) { + list_del(&o->new_list); + c->new_orphans -= 1; + } + spin_unlock(&c->orphan_lock); + kfree(o); + dbg_gen("inum %lu", inum); + return; + } + } + spin_unlock(&c->orphan_lock); + dbg_err("missing orphan ino %lu", inum); + dbg_dump_stack(); +} + +/** + * ubifs_orphan_start_commit - start commit of orphans. + * @c: UBIFS file-system description object + * + * Start commit of orphans. + */ +int ubifs_orphan_start_commit(struct ubifs_info *c) +{ + struct ubifs_orphan *orphan, **last; + + spin_lock(&c->orphan_lock); + last = &c->orph_cnext; + list_for_each_entry(orphan, &c->orph_new, new_list) { + ubifs_assert(orphan->new); + orphan->new = 0; + *last = orphan; + last = &orphan->cnext; + } + *last = orphan->cnext; + c->cmt_orphans = c->new_orphans; + c->new_orphans = 0; + dbg_cmt("%d orphans to commit", c->cmt_orphans); + INIT_LIST_HEAD(&c->orph_new); + if (c->tot_orphans == 0) + c->no_orphs = 1; + else + c->no_orphs = 0; + spin_unlock(&c->orphan_lock); + return 0; +} + +/** + * avail_orphs - calculate available space. + * @c: UBIFS file-system description object + * + * This function returns the number of orphans that can be written in the + * available space. + */ +static int avail_orphs(struct ubifs_info *c) +{ + int avail_lebs, avail, gap; + + avail_lebs = c->orph_lebs - (c->ohead_lnum - c->orph_first) - 1; + avail = avail_lebs * + ((c->leb_size - UBIFS_ORPH_NODE_SZ) / sizeof(__le64)); + gap = c->leb_size - c->ohead_offs; + if (gap >= UBIFS_ORPH_NODE_SZ + sizeof(__le64)) + avail += (gap - UBIFS_ORPH_NODE_SZ) / sizeof(__le64); + return avail; +} + +/** + * tot_avail_orphs - calculate total space. + * @c: UBIFS file-system description object + * + * This function returns the number of orphans that can be written in half + * the total space. That leaves half the space for adding new orphans. + */ +static int tot_avail_orphs(struct ubifs_info *c) +{ + int avail_lebs, avail; + + avail_lebs = c->orph_lebs; + avail = avail_lebs * + ((c->leb_size - UBIFS_ORPH_NODE_SZ) / sizeof(__le64)); + return avail / 2; +} + +/** + * do_write_orph_node - write a node + * @c: UBIFS file-system description object + * @len: length of node + * @atomic: write atomically + * + * This function writes a node to the orphan head from the orphan buffer. If + * %atomic is not zero, then the write is done atomically. On success, %0 is + * returned, otherwise a negative error code is returned. + */ +static int do_write_orph_node(struct ubifs_info *c, int len, int atomic) +{ + int err = 0; + + if (atomic) { + ubifs_assert(c->ohead_offs == 0); + ubifs_prepare_node(c, c->orph_buf, len, 1); + len = ALIGN(len, c->min_io_size); + err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len, + UBI_SHORTTERM); + } else { + if (c->ohead_offs == 0) { + /* Ensure LEB has been unmapped */ + err = ubifs_leb_unmap(c, c->ohead_lnum); + if (err) + return err; + } + err = ubifs_write_node(c, c->orph_buf, len, c->ohead_lnum, + c->ohead_offs, UBI_SHORTTERM); + } + return err; +} + +/** + * write_orph_node - write an orph node + * @c: UBIFS file-system description object + * @atomic: write atomically + * + * 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. + */ +static int write_orph_node(struct ubifs_info *c, int atomic) +{ + struct ubifs_orphan *orphan, *cnext; + struct ubifs_orph_node *orph; + int gap, err, len, cnt, i; + + ubifs_assert(c->cmt_orphans > 0); + gap = c->leb_size - c->ohead_offs; + if (gap < UBIFS_ORPH_NODE_SZ + sizeof(__le64)) { + c->ohead_lnum += 1; + c->ohead_offs = 0; + gap = c->leb_size; + if (c->ohead_lnum > c->orph_last) { + /* + * We limit the number of orphans so that this should + * never happen. + */ + ubifs_err("out of space in orphan area"); + return -EINVAL; + } + } + cnt = (gap - UBIFS_ORPH_NODE_SZ) / sizeof(__le64); + if (cnt > c->cmt_orphans) + cnt = c->cmt_orphans; + len = UBIFS_ORPH_NODE_SZ + cnt * sizeof(__le64); + ubifs_assert(c->orph_buf); + orph = c->orph_buf; + orph->ch.node_type = UBIFS_ORPH_NODE; + spin_lock(&c->orphan_lock); + cnext = c->orph_cnext; + for (i = 0; i < cnt; i++) { + orphan = cnext; + orph->inos[i] = cpu_to_le64(orphan->inum); + cnext = orphan->cnext; + orphan->cnext = NULL; + } + c->orph_cnext = cnext; + c->cmt_orphans -= cnt; + spin_unlock(&c->orphan_lock); + if (c->cmt_orphans) + orph->cmt_no = cpu_to_le64(c->cmt_no + 1); + else + /* Mark the last node of the commit */ + orph->cmt_no = cpu_to_le64((c->cmt_no + 1) | (1ULL << 63)); + ubifs_assert(c->ohead_offs + len <= c->leb_size); + ubifs_assert(c->ohead_lnum >= c->orph_first); + ubifs_assert(c->ohead_lnum <= c->orph_last); + err = do_write_orph_node(c, len, atomic); + c->ohead_offs += ALIGN(len, c->min_io_size); + c->ohead_offs = ALIGN(c->ohead_offs, 8); + return err; +} + +/** + * 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 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) +{ + int err; + + while (c->cmt_orphans > 0) { + err = write_orph_node(c, atomic); + if (err) + return err; + } + if (atomic) { + int lnum; + + /* Unmap any unused LEBs after consolidation */ + lnum = c->ohead_lnum + 1; + for (lnum = c->ohead_lnum + 1; lnum <= c->orph_last; lnum++) { + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + } + return 0; +} + +/** + * consolidate - consolidate the orphan area. + * @c: UBIFS file-system description object + * + * This function enables consolidation by putting all the orphans into the list + * to commit. The list is in the order that the orphans were added, and the + * LEBs are written atomically in order, so at no time can orphans be lost by + * an unclean unmount. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int consolidate(struct ubifs_info *c) +{ + int tot_avail = tot_avail_orphs(c), err = 0; + + spin_lock(&c->orphan_lock); + dbg_cmt("there is space for %d orphans and there are %d", + tot_avail, c->tot_orphans); + if (c->tot_orphans - c->new_orphans <= tot_avail) { + struct ubifs_orphan *orphan, **last; + int cnt = 0; + + /* Change the cnext list to include all non-new orphans */ + last = &c->orph_cnext; + list_for_each_entry(orphan, &c->orph_list, list) { + if (orphan->new) + continue; + *last = orphan; + last = &orphan->cnext; + cnt += 1; + } + *last = orphan->cnext; + ubifs_assert(cnt == c->tot_orphans - c->new_orphans); + c->cmt_orphans = cnt; + c->ohead_lnum = c->orph_first; + c->ohead_offs = 0; + } else { + /* + * We limit the number of orphans so that this should + * never happen. + */ + ubifs_err("out of space in orphan area"); + err = -EINVAL; + } + spin_unlock(&c->orphan_lock); + return err; +} + +/** + * commit_orphans - commit orphans. + * @c: UBIFS file-system description object + * + * This function commits orphans to flash. On success, %0 is returned, + * otherwise a negative error code is returned. + */ +static int commit_orphans(struct ubifs_info *c) +{ + int avail, atomic = 0, err; + + ubifs_assert(c->cmt_orphans > 0); + avail = avail_orphs(c); + if (avail < c->cmt_orphans) { + /* Not enough space to write new orphans, so consolidate */ + err = consolidate(c); + if (err) + return err; + atomic = 1; + } + err = write_orph_nodes(c, atomic); + return err; +} + +/** + * erase_deleted - erase the orphans marked for deletion. + * @c: UBIFS file-system description object + * + * During commit, the orphans being committed cannot be deleted, so they are + * marked for deletion and deleted by this function. Also, the recovery + * adds killed orphans to the deletion list, and therefore they are deleted + * here too. + */ +static void erase_deleted(struct ubifs_info *c) +{ + struct ubifs_orphan *orphan, *dnext; + + spin_lock(&c->orphan_lock); + dnext = c->orph_dnext; + while (dnext) { + orphan = dnext; + dnext = orphan->dnext; + ubifs_assert(!orphan->new); + rb_erase(&orphan->rb, &c->orph_tree); + list_del(&orphan->list); + c->tot_orphans -= 1; + dbg_gen("deleting orphan ino %lu", orphan->inum); + kfree(orphan); + } + c->orph_dnext = NULL; + spin_unlock(&c->orphan_lock); +} + +/** + * ubifs_orphan_end_commit - end commit of orphans. + * @c: UBIFS file-system description object + * + * End commit of orphans. + */ +int ubifs_orphan_end_commit(struct ubifs_info *c) +{ + int err; + + if (c->cmt_orphans != 0) { + err = commit_orphans(c); + if (err) + return err; + } + erase_deleted(c); + err = dbg_check_orphans(c); + return err; +} + +/** + * 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. + */ +static int clear_orphans(struct ubifs_info *c) +{ + int lnum, err; + + for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } + c->ohead_lnum = c->orph_first; + c->ohead_offs = 0; + return 0; +} + +/** + * insert_dead_orphan - insert an orphan. + * @c: UBIFS file-system description object + * @inum: orphan inode number + * + * This function is a helper to the 'do_kill_orphans()' function. The orphan + * must be kept until the next commit, so it is added to the rb-tree and the + * deletion list. + */ +static int insert_dead_orphan(struct ubifs_info *c, ino_t inum) +{ + struct ubifs_orphan *orphan, *o; + struct rb_node **p, *parent = NULL; + + orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_KERNEL); + if (!orphan) + return -ENOMEM; + orphan->inum = inum; + + p = &c->orph_tree.rb_node; + while (*p) { + parent = *p; + o = rb_entry(parent, struct ubifs_orphan, rb); + if (inum < o->inum) + p = &(*p)->rb_left; + else if (inum > o->inum) + p = &(*p)->rb_right; + else { + /* Already added - no problem */ + kfree(orphan); + return 0; + } + } + c->tot_orphans += 1; + rb_link_node(&orphan->rb, parent, p); + rb_insert_color(&orphan->rb, &c->orph_tree); + list_add_tail(&orphan->list, &c->orph_list); + orphan->dnext = c->orph_dnext; + c->orph_dnext = orphan; + dbg_mnt("ino %lu, new %d, tot %d", + inum, c->new_orphans, c->tot_orphans); + return 0; +} + +/** + * 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 orph node read is passed and returned here + * @outofdate: whether the LEB is out of date is returned here + * @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 + * all keys for that inode from the TNC. + */ +static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, + unsigned long long *last_cmt_no, int *outofdate, + int *last_flagged) +{ + struct ubifs_scan_node *snod; + struct ubifs_orph_node *orph; + unsigned long long cmt_no; + ino_t inum; + int i, n, err, first = 1; + + list_for_each_entry(snod, &sleb->nodes, list) { + if (snod->type != UBIFS_ORPH_NODE) { + ubifs_err("invalid node type %d in orphan area at " + "%d:%d", snod->type, sleb->lnum, snod->offs); + dbg_dump_node(c, snod->node); + return -EINVAL; + } + + orph = snod->node; + + /* Check commit number */ + cmt_no = le64_to_cpu(orph->cmt_no) & LLONG_MAX; + /* + * 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 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. + */ + if (cmt_no > c->cmt_no) + c->cmt_no = cmt_no; + if (cmt_no < *last_cmt_no && *last_flagged) { + /* + * 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 " + "orphan node at %d:%d", + cmt_no, sleb->lnum, snod->offs); + dbg_dump_node(c, snod->node); + return -EINVAL; + } + dbg_rcvry("out of date LEB %d", sleb->lnum); + *outofdate = 1; + return 0; + } + + if (first) + first = 0; + + n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; + for (i = 0; i < n; i++) { + inum = le64_to_cpu(orph->inos[i]); + dbg_rcvry("deleting orphaned inode %lu", inum); + err = ubifs_tnc_remove_ino(c, inum); + if (err) + return err; + err = insert_dead_orphan(c, inum); + if (err) + return err; + } + + *last_cmt_no = cmt_no; + if (le64_to_cpu(orph->cmt_no) & (1ULL << 63)) { + dbg_rcvry("last orph node for commit %llu at %d:%d", + cmt_no, sleb->lnum, snod->offs); + *last_flagged = 1; + } else + *last_flagged = 0; + } + + return 0; +} + +/** + * kill_orphans - remove all orphan inodes from the index. + * @c: UBIFS file-system description object + * + * If recovery is required, then orphan inodes recorded during the previous + * session (which ended with an unclean unmount) must be deleted from the index. + * This is done by updating the TNC, but since the index is not updated until + * the next commit, the LEBs where the orphan information is recorded are not + * erased until the next commit. + */ +static int kill_orphans(struct ubifs_info *c) +{ + unsigned long long last_cmt_no = 0; + int lnum, err = 0, outofdate = 0, last_flagged = 0; + + c->ohead_lnum = c->orph_first; + c->ohead_offs = 0; + /* Check no-orphans flag and skip this if no orphans */ + if (c->no_orphs) { + dbg_rcvry("no orphans"); + return 0; + } + /* + * 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 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 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. + */ + for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { + struct ubifs_scan_leb *sleb; + + dbg_rcvry("LEB %d", lnum); + sleb = ubifs_scan(c, lnum, 0, c->sbuf); + if (IS_ERR(sleb)) { + sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0); + if (IS_ERR(sleb)) { + err = PTR_ERR(sleb); + break; + } + } + err = do_kill_orphans(c, sleb, &last_cmt_no, &outofdate, + &last_flagged); + if (err || outofdate) { + ubifs_scan_destroy(sleb); + break; + } + if (sleb->endpt) { + c->ohead_lnum = lnum; + c->ohead_offs = sleb->endpt; + } + ubifs_scan_destroy(sleb); + } + return err; +} + +/** + * ubifs_mount_orphans - delete orphan inodes and erase LEBs that recorded them. + * @c: UBIFS file-system description object + * @unclean: indicates recovery from unclean unmount + * @read_only: indicates read only mount + * + * This function is called when mounting to erase orphans from the previous + * session. If UBIFS was not unmounted cleanly, then the inodes recorded as + * orphans are deleted. + */ +int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only) +{ + int err = 0; + + c->max_orphans = tot_avail_orphs(c); + + if (!read_only) { + c->orph_buf = vmalloc(c->leb_size); + if (!c->orph_buf) + return -ENOMEM; + } + + if (unclean) + err = kill_orphans(c); + else if (!read_only) + err = clear_orphans(c); + + return err; +} + +#ifdef CONFIG_UBIFS_FS_DEBUG + +struct check_orphan { + struct rb_node rb; + ino_t inum; +}; + +struct check_info { + unsigned long last_ino; + unsigned long tot_inos; + unsigned long missing; + unsigned long long leaf_cnt; + struct ubifs_ino_node *node; + struct rb_root root; +}; + +static int dbg_find_orphan(struct ubifs_info *c, ino_t inum) +{ + struct ubifs_orphan *o; + struct rb_node *p; + + spin_lock(&c->orphan_lock); + p = c->orph_tree.rb_node; + while (p) { + o = rb_entry(p, struct ubifs_orphan, rb); + if (inum < o->inum) + p = p->rb_left; + else if (inum > o->inum) + p = p->rb_right; + else { + spin_unlock(&c->orphan_lock); + return 1; + } + } + spin_unlock(&c->orphan_lock); + return 0; +} + +static int dbg_ins_check_orphan(struct rb_root *root, ino_t inum) +{ + struct check_orphan *orphan, *o; + struct rb_node **p, *parent = NULL; + + orphan = kzalloc(sizeof(struct check_orphan), GFP_NOFS); + if (!orphan) + return -ENOMEM; + orphan->inum = inum; + + p = &root->rb_node; + while (*p) { + parent = *p; + o = rb_entry(parent, struct check_orphan, rb); + if (inum < o->inum) + p = &(*p)->rb_left; + else if (inum > o->inum) + p = &(*p)->rb_right; + else { + kfree(orphan); + return 0; + } + } + rb_link_node(&orphan->rb, parent, p); + rb_insert_color(&orphan->rb, root); + return 0; +} + +static int dbg_find_check_orphan(struct rb_root *root, ino_t inum) +{ + struct check_orphan *o; + struct rb_node *p; + + p = root->rb_node; + while (p) { + o = rb_entry(p, struct check_orphan, rb); + if (inum < o->inum) + p = p->rb_left; + else if (inum > o->inum) + p = p->rb_right; + else + return 1; + } + return 0; +} + +static void dbg_free_check_tree(struct rb_root *root) +{ + struct rb_node *this = root->rb_node; + struct check_orphan *o; + + while (this) { + if (this->rb_left) { + this = this->rb_left; + continue; + } else if (this->rb_right) { + this = this->rb_right; + continue; + } + o = rb_entry(this, struct check_orphan, rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &o->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + kfree(o); + } +} + +static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *priv) +{ + struct check_info *ci = priv; + ino_t inum; + int err; + + inum = key_inum(c, &zbr->key); + if (inum != ci->last_ino) { + /* Lowest node type is the inode node, so it comes first */ + if (key_type(c, &zbr->key) != UBIFS_INO_KEY) + ubifs_err("found orphan node ino %lu, type %d", inum, + key_type(c, &zbr->key)); + ci->last_ino = inum; + ci->tot_inos += 1; + err = ubifs_tnc_read_node(c, zbr, ci->node); + if (err) { + ubifs_err("node read failed, error %d", err); + return err; + } + if (ci->node->nlink == 0) + /* Must be recorded as an orphan */ + if (!dbg_find_check_orphan(&ci->root, inum) && + !dbg_find_orphan(c, inum)) { + ubifs_err("missing orphan, ino %lu", inum); + ci->missing += 1; + } + } + ci->leaf_cnt += 1; + return 0; +} + +static int dbg_read_orphans(struct check_info *ci, struct ubifs_scan_leb *sleb) +{ + struct ubifs_scan_node *snod; + struct ubifs_orph_node *orph; + ino_t inum; + int i, n, err; + + list_for_each_entry(snod, &sleb->nodes, list) { + cond_resched(); + if (snod->type != UBIFS_ORPH_NODE) + continue; + orph = snod->node; + n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; + for (i = 0; i < n; i++) { + inum = le64_to_cpu(orph->inos[i]); + err = dbg_ins_check_orphan(&ci->root, inum); + if (err) + return err; + } + } + return 0; +} + +static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci) +{ + int lnum, err = 0; + + /* Check no-orphans flag and skip this if no orphans */ + if (c->no_orphs) + return 0; + + for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { + struct ubifs_scan_leb *sleb; + + sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); + if (IS_ERR(sleb)) { + err = PTR_ERR(sleb); + break; + } + + err = dbg_read_orphans(ci, sleb); + ubifs_scan_destroy(sleb); + if (err) + break; + } + + return err; +} + +static int dbg_check_orphans(struct ubifs_info *c) +{ + struct check_info ci; + int err; + + if (!(ubifs_chk_flags & UBIFS_CHK_ORPH)) + return 0; + + ci.last_ino = 0; + ci.tot_inos = 0; + ci.missing = 0; + ci.leaf_cnt = 0; + ci.root = RB_ROOT; + ci.node = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS); + if (!ci.node) { + ubifs_err("out of memory"); + return -ENOMEM; + } + + err = dbg_scan_orphans(c, &ci); + if (err) + goto out; + + err = dbg_walk_index(c, &dbg_orphan_check, NULL, &ci); + if (err) { + ubifs_err("cannot scan TNC, error %d", err); + goto out; + } + + if (ci.missing) { + ubifs_err("%lu missing orphan(s)", ci.missing); + err = -EINVAL; + goto out; + } + + dbg_cmt("last inode number is %lu", ci.last_ino); + dbg_cmt("total number of inodes is %lu", ci.tot_inos); + dbg_cmt("total number of leaf nodes is %llu", ci.leaf_cnt); + +out: + dbg_free_check_tree(&ci.root); + kfree(ci.node); + return err; +} + +#endif /* CONFIG_UBIFS_FS_DEBUG */ diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c new file mode 100644 index 0000000..77d26c1 --- /dev/null +++ b/fs/ubifs/recovery.c @@ -0,0 +1,1519 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements functions needed to recover from unclean un-mounts. + * When UBIFS is mounted, it checks a flag on the master node to determine if + * an un-mount was completed sucessfully. If not, the process of mounting + * incorparates additional checking and fixing of on-flash data structures. + * UBIFS always cleans away all remnants of an unclean un-mount, so that + * errors do not accumulate. However UBIFS defers recovery if it is mounted + * read-only, and the flash is not modified in that case. + */ + +#include +#include "ubifs.h" + +/** + * is_empty - determine whether a buffer is empty (contains all 0xff). + * @buf: buffer to clean + * @len: length of buffer + * + * This function returns %1 if the buffer is empty (contains all 0xff) otherwise + * %0 is returned. + */ +static int is_empty(void *buf, int len) +{ + uint8_t *p = buf; + int i; + + for (i = 0; i < len; i++) + if (*p++ != 0xff) + return 0; + return 1; +} + +/** + * get_master_node - get the last valid master node allowing for corruption. + * @c: UBIFS file-system description object + * @lnum: LEB number + * @pbuf: buffer containing the LEB read, is returned here + * @mst: master node, if found, is returned here + * @cor: corruption, if found, is returned here + * + * This function allocates a buffer, reads the LEB into it, and finds and + * returns the last valid master node allowing for one area of corruption. + * The corrupt area, if there is one, must be consistent with the assumption + * that it is the result of an unclean unmount while the master node was being + * written. Under those circumstances, it is valid to use the previously written + * master node. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int get_master_node(const struct ubifs_info *c, int lnum, void **pbuf, + struct ubifs_mst_node **mst, void **cor) +{ + const int sz = c->mst_node_alsz; + int err, offs, len; + void *sbuf, *buf; + + sbuf = vmalloc(c->leb_size); + if (!sbuf) + return -ENOMEM; + + err = ubi_read(c->ubi, lnum, sbuf, 0, c->leb_size); + if (err && err != -EBADMSG) + goto out_free; + + /* Find the first position that is definitely not a node */ + offs = 0; + buf = sbuf; + len = c->leb_size; + while (offs + UBIFS_MST_NODE_SZ <= c->leb_size) { + struct ubifs_ch *ch = buf; + + if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) + break; + offs += sz; + buf += sz; + len -= sz; + } + /* See if there was a valid master node before that */ + if (offs) { + int ret; + + offs -= sz; + buf -= sz; + len += sz; + ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); + if (ret != SCANNED_A_NODE && offs) { + /* Could have been corruption so check one place back */ + offs -= sz; + buf -= sz; + len += sz; + ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); + if (ret != SCANNED_A_NODE) + /* + * We accept only one area of corruption because + * we are assuming that it was caused while + * trying to write a master node. + */ + goto out_err; + } + if (ret == SCANNED_A_NODE) { + struct ubifs_ch *ch = buf; + + if (ch->node_type != UBIFS_MST_NODE) + goto out_err; + dbg_rcvry("found a master node at %d:%d", lnum, offs); + *mst = buf; + offs += sz; + buf += sz; + len -= sz; + } + } + /* Check for corruption */ + if (offs < c->leb_size) { + if (!is_empty(buf, min_t(int, len, sz))) { + *cor = buf; + dbg_rcvry("found corruption at %d:%d", lnum, offs); + } + offs += sz; + buf += sz; + len -= sz; + } + /* Check remaining empty space */ + if (offs < c->leb_size) + if (!is_empty(buf, len)) + goto out_err; + *pbuf = sbuf; + return 0; + +out_err: + err = -EINVAL; +out_free: + vfree(sbuf); + *mst = NULL; + *cor = NULL; + return err; +} + +/** + * write_rcvrd_mst_node - write recovered master node. + * @c: UBIFS file-system description object + * @mst: master node + * + * This function returns %0 on success and a negative error code on failure. + */ +static int write_rcvrd_mst_node(struct ubifs_info *c, + struct ubifs_mst_node *mst) +{ + int err = 0, lnum = UBIFS_MST_LNUM, sz = c->mst_node_alsz; + uint32_t save_flags; + + dbg_rcvry("recovery"); + + save_flags = mst->flags; + mst->flags = cpu_to_le32(le32_to_cpu(mst->flags) | UBIFS_MST_RCVRY); + + ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1); + err = ubi_leb_change(c->ubi, lnum, mst, sz, UBI_SHORTTERM); + if (err) + goto out; + err = ubi_leb_change(c->ubi, lnum + 1, mst, sz, UBI_SHORTTERM); + if (err) + goto out; +out: + mst->flags = save_flags; + return err; +} + +/** + * ubifs_recover_master_node - recover the master node. + * @c: UBIFS file-system description object + * + * This function recovers the master node from corruption that may occur due to + * an unclean unmount. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_recover_master_node(struct ubifs_info *c) +{ + void *buf1 = NULL, *buf2 = NULL, *cor1 = NULL, *cor2 = NULL; + struct ubifs_mst_node *mst1 = NULL, *mst2 = NULL, *mst; + const int sz = c->mst_node_alsz; + int err, offs1, offs2; + + dbg_rcvry("recovery"); + + err = get_master_node(c, UBIFS_MST_LNUM, &buf1, &mst1, &cor1); + if (err) + goto out_free; + + err = get_master_node(c, UBIFS_MST_LNUM + 1, &buf2, &mst2, &cor2); + if (err) + goto out_free; + + if (mst1) { + offs1 = (void *)mst1 - buf1; + if ((le32_to_cpu(mst1->flags) & UBIFS_MST_RCVRY) && + (offs1 == 0 && !cor1)) { + /* + * mst1 was written by recovery at offset 0 with no + * corruption. + */ + dbg_rcvry("recovery recovery"); + mst = mst1; + } else if (mst2) { + offs2 = (void *)mst2 - buf2; + if (offs1 == offs2) { + /* Same offset, so must be the same */ + if (memcmp((void *)mst1 + UBIFS_CH_SZ, + (void *)mst2 + UBIFS_CH_SZ, + UBIFS_MST_NODE_SZ - UBIFS_CH_SZ)) + goto out_err; + mst = mst1; + } else if (offs2 + sz == offs1) { + /* 1st LEB was written, 2nd was not */ + if (cor1) + goto out_err; + mst = mst1; + } else if (offs1 == 0 && offs2 + sz >= c->leb_size) { + /* 1st LEB was unmapped and written, 2nd not */ + if (cor1) + goto out_err; + mst = mst1; + } else + goto out_err; + } else { + /* + * 2nd LEB was unmapped and about to be written, so + * there must be only one master node in the first LEB + * and no corruption. + */ + if (offs1 != 0 || cor1) + goto out_err; + mst = mst1; + } + } else { + if (!mst2) + goto out_err; + /* + * 1st LEB was unmapped and about to be written, so there must + * be no room left in 2nd LEB. + */ + offs2 = (void *)mst2 - buf2; + if (offs2 + sz + sz <= c->leb_size) + goto out_err; + mst = mst2; + } + + dbg_rcvry("recovered master node from LEB %d", + (mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1)); + + memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ); + + if ((c->vfs_sb->s_flags & MS_RDONLY)) { + /* Read-only mode. Keep a copy for switching to rw mode */ + c->rcvrd_mst_node = kmalloc(sz, GFP_KERNEL); + if (!c->rcvrd_mst_node) { + err = -ENOMEM; + goto out_free; + } + memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ); + } else { + /* Write the recovered master node */ + c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1; + err = write_rcvrd_mst_node(c, c->mst_node); + if (err) + goto out_free; + } + + vfree(buf2); + vfree(buf1); + + return 0; + +out_err: + err = -EINVAL; +out_free: + ubifs_err("failed to recover master node"); + if (mst1) { + dbg_err("dumping first master node"); + dbg_dump_node(c, mst1); + } + if (mst2) { + dbg_err("dumping second master node"); + dbg_dump_node(c, mst2); + } + vfree(buf2); + vfree(buf1); + return err; +} + +/** + * ubifs_write_rcvrd_mst_node - write the recovered master node. + * @c: UBIFS file-system description object + * + * This function writes the master node that was recovered during mounting in + * read-only mode and must now be written because we are remounting rw. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_write_rcvrd_mst_node(struct ubifs_info *c) +{ + int err; + + if (!c->rcvrd_mst_node) + return 0; + c->rcvrd_mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); + err = write_rcvrd_mst_node(c, c->rcvrd_mst_node); + if (err) + return err; + kfree(c->rcvrd_mst_node); + c->rcvrd_mst_node = NULL; + return 0; +} + +/** + * is_last_write - determine if an offset was in the last write to a LEB. + * @c: UBIFS file-system description object + * @buf: buffer to check + * @offs: offset to check + * + * This function returns %1 if @offs was in the last write to the LEB whose data + * is in @buf, otherwise %0 is returned. The determination is made by checking + * for subsequent empty space starting from the next min_io_size boundary (or a + * bit less than the common header size if min_io_size is one). + */ +static int is_last_write(const struct ubifs_info *c, void *buf, int offs) +{ + int empty_offs; + int check_len; + uint8_t *p; + + if (c->min_io_size == 1) { + check_len = c->leb_size - offs; + p = buf + check_len; + for (; check_len > 0; check_len--) + if (*--p != 0xff) + break; + /* + * 'check_len' is the size of the corruption which cannot be + * more than the size of 1 node if it was caused by an unclean + * unmount. + */ + if (check_len > UBIFS_MAX_NODE_SZ) + return 0; + return 1; + } + + /* + * Round up to the next c->min_io_size boundary i.e. 'offs' is in the + * last wbuf written. After that should be empty space. + */ + empty_offs = ALIGN(offs + 1, c->min_io_size); + check_len = c->leb_size - empty_offs; + p = buf + empty_offs - offs; + + for (; check_len > 0; check_len--) + if (*p++ != 0xff) + return 0; + return 1; +} + +/** + * clean_buf - clean the data from an LEB sitting in a buffer. + * @c: UBIFS file-system description object + * @buf: buffer to clean + * @lnum: LEB number to clean + * @offs: offset from which to clean + * @len: length of buffer + * + * This function pads up to the next min_io_size boundary (if there is one) and + * sets empty space to all 0xff. @buf, @offs and @len are updated to the next + * min_io_size boundary (if there is one). + */ +static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, + int *offs, int *len) +{ + int empty_offs, pad_len; + + lnum = lnum; + dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); + + if (c->min_io_size == 1) { + memset(*buf, 0xff, c->leb_size - *offs); + return; + } + + ubifs_assert(!(*offs & 7)); + empty_offs = ALIGN(*offs, c->min_io_size); + pad_len = empty_offs - *offs; + ubifs_pad(c, *buf, pad_len); + *offs += pad_len; + *buf += pad_len; + *len -= pad_len; + memset(*buf, 0xff, c->leb_size - empty_offs); +} + +/** + * no_more_nodes - determine if there are no more nodes in a buffer. + * @c: UBIFS file-system description object + * @buf: buffer to check + * @len: length of buffer + * @lnum: LEB number of the LEB from which @buf was read + * @offs: offset from which @buf was read + * + * This function scans @buf for more nodes and returns %0 is a node is found and + * %1 if no more nodes are found. + */ +static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, + int lnum, int offs) +{ + int skip, next_offs = 0; + + if (len > UBIFS_DATA_NODE_SZ) { + struct ubifs_ch *ch = buf; + int dlen = le32_to_cpu(ch->len); + + if (ch->node_type == UBIFS_DATA_NODE && dlen >= UBIFS_CH_SZ && + dlen <= UBIFS_MAX_DATA_NODE_SZ) + /* The corrupt node looks like a data node */ + next_offs = ALIGN(offs + dlen, 8); + } + + if (c->min_io_size == 1) + skip = 8; + else + skip = ALIGN(offs + 1, c->min_io_size) - offs; + + offs += skip; + buf += skip; + len -= skip; + while (len > 8) { + struct ubifs_ch *ch = buf; + uint32_t magic = le32_to_cpu(ch->magic); + int ret; + + if (magic == UBIFS_NODE_MAGIC) { + ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); + if (ret == SCANNED_A_NODE || ret > 0) { + /* + * There is a small chance this is just data in + * a data node, so check that possibility. e.g. + * this is part of a file that itself contains + * a UBIFS image. + */ + if (next_offs && offs + le32_to_cpu(ch->len) <= + next_offs) + continue; + dbg_rcvry("unexpected node at %d:%d", lnum, + offs); + return 0; + } + } + offs += 8; + buf += 8; + len -= 8; + } + return 1; +} + +/** + * fix_unclean_leb - fix an unclean LEB. + * @c: UBIFS file-system description object + * @sleb: scanned LEB information + * @start: offset where scan started + */ +static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, + int start) +{ + int lnum = sleb->lnum, endpt = start; + + /* Get the end offset of the last node we are keeping */ + if (!list_empty(&sleb->nodes)) { + struct ubifs_scan_node *snod; + + snod = list_entry(sleb->nodes.prev, + struct ubifs_scan_node, list); + endpt = snod->offs + snod->len; + } + + if ((c->vfs_sb->s_flags & MS_RDONLY) && !c->remounting_rw) { + /* Add to recovery list */ + struct ubifs_unclean_leb *ucleb; + + dbg_rcvry("need to fix LEB %d start %d endpt %d", + lnum, start, sleb->endpt); + ucleb = kzalloc(sizeof(struct ubifs_unclean_leb), GFP_NOFS); + if (!ucleb) + return -ENOMEM; + ucleb->lnum = lnum; + ucleb->endpt = endpt; + list_add_tail(&ucleb->list, &c->unclean_leb_list); + } else { + /* Write the fixed LEB back to flash */ + int err; + + dbg_rcvry("fixing LEB %d start %d endpt %d", + lnum, start, sleb->endpt); + if (endpt == 0) { + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + } else { + int len = ALIGN(endpt, c->min_io_size); + + if (start) { + err = ubi_read(c->ubi, lnum, sleb->buf, 0, + start); + if (err) + return err; + } + /* Pad to min_io_size */ + if (len > endpt) { + int pad_len = len - ALIGN(endpt, 8); + + if (pad_len > 0) { + void *buf = sleb->buf + len - pad_len; + + ubifs_pad(c, buf, pad_len); + } + } + err = ubi_leb_change(c->ubi, lnum, sleb->buf, len, + UBI_UNKNOWN); + if (err) + return err; + } + } + return 0; +} + +/** + * drop_incomplete_group - drop nodes from an incomplete group. + * @sleb: scanned LEB information + * @offs: offset of dropped nodes is returned here + * + * This function returns %1 if nodes are dropped and %0 otherwise. + */ +static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs) +{ + int dropped = 0; + + while (!list_empty(&sleb->nodes)) { + struct ubifs_scan_node *snod; + struct ubifs_ch *ch; + + snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, + list); + ch = snod->node; + if (ch->group_type != UBIFS_IN_NODE_GROUP) + return dropped; + dbg_rcvry("dropping node at %d:%d", sleb->lnum, snod->offs); + *offs = snod->offs; + list_del(&snod->list); + kfree(snod); + sleb->nodes_cnt -= 1; + dropped = 1; + } + return dropped; +} + +/** + * ubifs_recover_leb - scan and recover a LEB. + * @c: UBIFS file-system description object + * @lnum: LEB number + * @offs: offset + * @sbuf: LEB-sized buffer to use + * @grouped: nodes may be grouped for recovery + * + * This function does a scan of a LEB, but caters for errors that might have + * been caused by the unclean unmount from which we are attempting to recover. + * + * This function returns %0 on success and a negative error code on failure. + */ +struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, + int offs, void *sbuf, int grouped) +{ + int err, len = c->leb_size - offs, need_clean = 0, quiet = 1; + int empty_chkd = 0, start = offs; + struct ubifs_scan_leb *sleb; + void *buf = sbuf + offs; + + dbg_rcvry("%d:%d", lnum, offs); + + sleb = ubifs_start_scan(c, lnum, offs, sbuf); + if (IS_ERR(sleb)) + return sleb; + + if (sleb->ecc) + need_clean = 1; + + while (len >= 8) { + int ret; + + dbg_scan("look at LEB %d:%d (%d bytes left)", + lnum, offs, len); + + cond_resched(); + + /* + * Scan quietly until there is an error from which we cannot + * recover + */ + ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet); + + if (ret == SCANNED_A_NODE) { + /* A valid node, and not a padding node */ + struct ubifs_ch *ch = buf; + int node_len; + + err = ubifs_add_snod(c, sleb, buf, offs); + if (err) + goto error; + node_len = ALIGN(le32_to_cpu(ch->len), 8); + offs += node_len; + buf += node_len; + len -= node_len; + continue; + } + + if (ret > 0) { + /* Padding bytes or a valid padding node */ + offs += ret; + buf += ret; + len -= ret; + continue; + } + + if (ret == SCANNED_EMPTY_SPACE) { + if (!is_empty(buf, len)) { + if (!is_last_write(c, buf, offs)) + break; + clean_buf(c, &buf, lnum, &offs, &len); + need_clean = 1; + } + empty_chkd = 1; + break; + } + + if (ret == SCANNED_GARBAGE || ret == SCANNED_A_BAD_PAD_NODE) + if (is_last_write(c, buf, offs)) { + clean_buf(c, &buf, lnum, &offs, &len); + need_clean = 1; + empty_chkd = 1; + break; + } + + if (ret == SCANNED_A_CORRUPT_NODE) + if (no_more_nodes(c, buf, len, lnum, offs)) { + clean_buf(c, &buf, lnum, &offs, &len); + need_clean = 1; + empty_chkd = 1; + break; + } + + if (quiet) { + /* Redo the last scan but noisily */ + quiet = 0; + continue; + } + + switch (ret) { + case SCANNED_GARBAGE: + dbg_err("garbage"); + goto corrupted; + case SCANNED_A_CORRUPT_NODE: + case SCANNED_A_BAD_PAD_NODE: + dbg_err("bad node"); + goto corrupted; + default: + dbg_err("unknown"); + goto corrupted; + } + } + + if (!empty_chkd && !is_empty(buf, len)) { + if (is_last_write(c, buf, offs)) { + clean_buf(c, &buf, lnum, &offs, &len); + need_clean = 1; + } else { + ubifs_err("corrupt empty space at LEB %d:%d", + lnum, offs); + goto corrupted; + } + } + + /* Drop nodes from incomplete group */ + if (grouped && drop_incomplete_group(sleb, &offs)) { + buf = sbuf + offs; + len = c->leb_size - offs; + clean_buf(c, &buf, lnum, &offs, &len); + need_clean = 1; + } + + if (offs % c->min_io_size) { + clean_buf(c, &buf, lnum, &offs, &len); + need_clean = 1; + } + + ubifs_end_scan(c, sleb, lnum, offs); + + if (need_clean) { + err = fix_unclean_leb(c, sleb, start); + if (err) + goto error; + } + + return sleb; + +corrupted: + ubifs_scanned_corruption(c, lnum, offs, buf); + err = -EUCLEAN; +error: + ubifs_err("LEB %d scanning failed", lnum); + ubifs_scan_destroy(sleb); + return ERR_PTR(err); +} + +/** + * get_cs_sqnum - get commit start sequence number. + * @c: UBIFS file-system description object + * @lnum: LEB number of commit start node + * @offs: offset of commit start node + * @cs_sqnum: commit start sequence number is returned here + * + * This function returns %0 on success and a negative error code on failure. + */ +static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs, + unsigned long long *cs_sqnum) +{ + struct ubifs_cs_node *cs_node = NULL; + int err, ret; + + dbg_rcvry("at %d:%d", lnum, offs); + cs_node = kmalloc(UBIFS_CS_NODE_SZ, GFP_KERNEL); + if (!cs_node) + return -ENOMEM; + if (c->leb_size - offs < UBIFS_CS_NODE_SZ) + goto out_err; + err = ubi_read(c->ubi, lnum, (void *)cs_node, offs, UBIFS_CS_NODE_SZ); + if (err && err != -EBADMSG) + goto out_free; + ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0); + if (ret != SCANNED_A_NODE) { + dbg_err("Not a valid node"); + goto out_err; + } + if (cs_node->ch.node_type != UBIFS_CS_NODE) { + dbg_err("Node a CS node, type is %d", cs_node->ch.node_type); + goto out_err; + } + if (le64_to_cpu(cs_node->cmt_no) != c->cmt_no) { + dbg_err("CS node cmt_no %llu != current cmt_no %llu", + (unsigned long long)le64_to_cpu(cs_node->cmt_no), + c->cmt_no); + goto out_err; + } + *cs_sqnum = le64_to_cpu(cs_node->ch.sqnum); + dbg_rcvry("commit start sqnum %llu", *cs_sqnum); + kfree(cs_node); + return 0; + +out_err: + err = -EINVAL; +out_free: + ubifs_err("failed to get CS sqnum"); + kfree(cs_node); + return err; +} + +/** + * ubifs_recover_log_leb - scan and recover a log LEB. + * @c: UBIFS file-system description object + * @lnum: LEB number + * @offs: offset + * @sbuf: LEB-sized buffer to use + * + * This function does a scan of a LEB, but caters for errors that might have + * been caused by the unclean unmount from which we are attempting to recover. + * + * This function returns %0 on success and a negative error code on failure. + */ +struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, + int offs, void *sbuf) +{ + struct ubifs_scan_leb *sleb; + int next_lnum; + + dbg_rcvry("LEB %d", lnum); + next_lnum = lnum + 1; + if (next_lnum >= UBIFS_LOG_LNUM + c->log_lebs) + next_lnum = UBIFS_LOG_LNUM; + if (next_lnum != c->ltail_lnum) { + /* + * We can only recover at the end of the log, so check that the + * next log LEB is empty or out of date. + */ + sleb = ubifs_scan(c, next_lnum, 0, sbuf); + if (IS_ERR(sleb)) + return sleb; + if (sleb->nodes_cnt) { + struct ubifs_scan_node *snod; + unsigned long long cs_sqnum = c->cs_sqnum; + + snod = list_entry(sleb->nodes.next, + struct ubifs_scan_node, list); + if (cs_sqnum == 0) { + int err; + + err = get_cs_sqnum(c, lnum, offs, &cs_sqnum); + if (err) { + ubifs_scan_destroy(sleb); + return ERR_PTR(err); + } + } + if (snod->sqnum > cs_sqnum) { + ubifs_err("unrecoverable log corruption " + "in LEB %d", lnum); + ubifs_scan_destroy(sleb); + return ERR_PTR(-EUCLEAN); + } + } + ubifs_scan_destroy(sleb); + } + return ubifs_recover_leb(c, lnum, offs, sbuf, 0); +} + +/** + * recover_head - recover a head. + * @c: UBIFS file-system description object + * @lnum: LEB number of head to recover + * @offs: offset of head to recover + * @sbuf: LEB-sized buffer to use + * + * This function ensures that there is no data on the flash at a head location. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int recover_head(const struct ubifs_info *c, int lnum, int offs, + void *sbuf) +{ + int len, err, need_clean = 0; + + if (c->min_io_size > 1) + len = c->min_io_size; + else + len = 512; + if (offs + len > c->leb_size) + len = c->leb_size - offs; + + if (!len) + return 0; + + /* Read at the head location and check it is empty flash */ + err = ubi_read(c->ubi, lnum, sbuf, offs, len); + if (err) + need_clean = 1; + else { + uint8_t *p = sbuf; + + while (len--) + if (*p++ != 0xff) { + need_clean = 1; + break; + } + } + + if (need_clean) { + dbg_rcvry("cleaning head at %d:%d", lnum, offs); + if (offs == 0) + return ubifs_leb_unmap(c, lnum); + err = ubi_read(c->ubi, lnum, sbuf, 0, offs); + if (err) + return err; + return ubi_leb_change(c->ubi, lnum, sbuf, offs, UBI_UNKNOWN); + } + + return 0; +} + +/** + * ubifs_recover_inl_heads - recover index and LPT heads. + * @c: UBIFS file-system description object + * @sbuf: LEB-sized buffer to use + * + * This function ensures that there is no data on the flash at the index and + * LPT head locations. + * + * This deals with the recovery of a half-completed journal commit. UBIFS is + * careful never to overwrite the last version of the index or the LPT. Because + * the index and LPT are wandering trees, data from a half-completed commit will + * not be referenced anywhere in UBIFS. The data will be either in LEBs that are + * assumed to be empty and will be unmapped anyway before use, or in the index + * and LPT heads. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf) +{ + int err; + + ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY) || c->remounting_rw); + + dbg_rcvry("checking index head at %d:%d", c->ihead_lnum, c->ihead_offs); + err = recover_head(c, c->ihead_lnum, c->ihead_offs, sbuf); + if (err) + return err; + + dbg_rcvry("checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs); + err = recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf); + if (err) + return err; + + return 0; +} + +/** + * clean_an_unclean_leb - read and write a LEB to remove corruption. + * @c: UBIFS file-system description object + * @ucleb: unclean LEB information + * @sbuf: LEB-sized buffer to use + * + * This function reads a LEB up to a point pre-determined by the mount recovery, + * checks the nodes, and writes the result back to the flash, thereby cleaning + * off any following corruption, or non-fatal ECC errors. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int clean_an_unclean_leb(const struct ubifs_info *c, + struct ubifs_unclean_leb *ucleb, void *sbuf) +{ + int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1; + void *buf = sbuf; + + dbg_rcvry("LEB %d len %d", lnum, len); + + if (len == 0) { + /* Nothing to read, just unmap it */ + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + return 0; + } + + err = ubi_read(c->ubi, lnum, buf, offs, len); + if (err && err != -EBADMSG) + return err; + + while (len >= 8) { + int ret; + + cond_resched(); + + /* Scan quietly until there is an error */ + ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet); + + if (ret == SCANNED_A_NODE) { + /* A valid node, and not a padding node */ + struct ubifs_ch *ch = buf; + int node_len; + + node_len = ALIGN(le32_to_cpu(ch->len), 8); + offs += node_len; + buf += node_len; + len -= node_len; + continue; + } + + if (ret > 0) { + /* Padding bytes or a valid padding node */ + offs += ret; + buf += ret; + len -= ret; + continue; + } + + if (ret == SCANNED_EMPTY_SPACE) { + ubifs_err("unexpected empty space at %d:%d", + lnum, offs); + return -EUCLEAN; + } + + if (quiet) { + /* Redo the last scan but noisily */ + quiet = 0; + continue; + } + + ubifs_scanned_corruption(c, lnum, offs, buf); + return -EUCLEAN; + } + + /* Pad to min_io_size */ + len = ALIGN(ucleb->endpt, c->min_io_size); + if (len > ucleb->endpt) { + int pad_len = len - ALIGN(ucleb->endpt, 8); + + if (pad_len > 0) { + buf = c->sbuf + len - pad_len; + ubifs_pad(c, buf, pad_len); + } + } + + /* Write back the LEB atomically */ + err = ubi_leb_change(c->ubi, lnum, sbuf, len, UBI_UNKNOWN); + if (err) + return err; + + dbg_rcvry("cleaned LEB %d", lnum); + + return 0; +} + +/** + * ubifs_clean_lebs - clean LEBs recovered during read-only mount. + * @c: UBIFS file-system description object + * @sbuf: LEB-sized buffer to use + * + * This function cleans a LEB identified during recovery that needs to be + * written but was not because UBIFS was mounted read-only. This happens when + * remounting to read-write mode. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf) +{ + dbg_rcvry("recovery"); + while (!list_empty(&c->unclean_leb_list)) { + struct ubifs_unclean_leb *ucleb; + int err; + + ucleb = list_entry(c->unclean_leb_list.next, + struct ubifs_unclean_leb, list); + err = clean_an_unclean_leb(c, ucleb, sbuf); + if (err) + return err; + list_del(&ucleb->list); + kfree(ucleb); + } + return 0; +} + +/** + * ubifs_rcvry_gc_commit - recover the GC LEB number and run the commit. + * @c: UBIFS file-system description object + * + * Out-of-place garbage collection requires always one empty LEB with which to + * start garbage collection. The LEB number is recorded in c->gc_lnum and is + * written to the master node on unmounting. In the case of an unclean unmount + * the value of gc_lnum recorded in the master node is out of date and cannot + * be used. Instead, recovery must allocate an empty LEB for this purpose. + * However, there may not be enough empty space, in which case it must be + * possible to GC the dirtiest LEB into the GC head LEB. + * + * This function also runs the commit which causes the TNC updates from + * size-recovery and orphans to be written to the flash. That is important to + * ensure correct replay order for subsequent mounts. + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_rcvry_gc_commit(struct ubifs_info *c) +{ + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + struct ubifs_lprops lp; + int lnum, err; + + c->gc_lnum = -1; + if (wbuf->lnum == -1) { + dbg_rcvry("no GC head LEB"); + goto find_free; + } + /* + * See whether the used space in the dirtiest LEB fits in the GC head + * LEB. + */ + if (wbuf->offs == c->leb_size) { + dbg_rcvry("no room in GC head LEB"); + goto find_free; + } + err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2); + if (err) { + if (err == -ENOSPC) + dbg_err("could not find a dirty LEB"); + return err; + } + ubifs_assert(!(lp.flags & LPROPS_INDEX)); + lnum = lp.lnum; + if (lp.free + lp.dirty == c->leb_size) { + /* An empty LEB was returned */ + if (lp.free != c->leb_size) { + err = ubifs_change_one_lp(c, lnum, c->leb_size, + 0, 0, 0, 0); + if (err) + return err; + } + err = ubifs_leb_unmap(c, lnum); + if (err) + return err; + c->gc_lnum = lnum; + dbg_rcvry("allocated LEB %d for GC", lnum); + /* Run the commit */ + dbg_rcvry("committing"); + return ubifs_run_commit(c); + } + /* + * There was no empty LEB so the used space in the dirtiest LEB must fit + * in the GC head LEB. + */ + if (lp.free + lp.dirty < wbuf->offs) { + dbg_rcvry("LEB %d doesn't fit in GC head LEB %d:%d", + lnum, wbuf->lnum, wbuf->offs); + err = ubifs_return_leb(c, lnum); + if (err) + return err; + goto find_free; + } + /* + * We run the commit before garbage collection otherwise subsequent + * mounts will see the GC and orphan deletion in a different order. + */ + dbg_rcvry("committing"); + err = ubifs_run_commit(c); + if (err) + return err; + /* + * The data in the dirtiest LEB fits in the GC head LEB, so do the GC + * - use locking to keep 'ubifs_assert()' happy. + */ + dbg_rcvry("GC'ing LEB %d", lnum); + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + err = ubifs_garbage_collect_leb(c, &lp); + if (err >= 0) { + int err2 = ubifs_wbuf_sync_nolock(wbuf); + + if (err2) + err = err2; + } + mutex_unlock(&wbuf->io_mutex); + if (err < 0) { + dbg_err("GC failed, error %d", err); + if (err == -EAGAIN) + err = -EINVAL; + return err; + } + if (err != LEB_RETAINED) { + dbg_err("GC returned %d", err); + return -EINVAL; + } + err = ubifs_leb_unmap(c, c->gc_lnum); + if (err) + return err; + dbg_rcvry("allocated LEB %d for GC", lnum); + return 0; + +find_free: + /* + * There is no GC head LEB or the free space in the GC head LEB is too + * small. Allocate gc_lnum by calling 'ubifs_find_free_leb_for_idx()' so + * GC is not run. + */ + lnum = ubifs_find_free_leb_for_idx(c); + if (lnum < 0) { + dbg_err("could not find an empty LEB"); + return lnum; + } + /* And reset the index flag */ + err = ubifs_change_one_lp(c, lnum, LPROPS_NC, LPROPS_NC, 0, + LPROPS_INDEX, 0); + if (err) + return err; + c->gc_lnum = lnum; + dbg_rcvry("allocated LEB %d for GC", lnum); + /* Run the commit */ + dbg_rcvry("committing"); + return ubifs_run_commit(c); +} + +/** + * struct size_entry - inode size information for recovery. + * @rb: link in the RB-tree of sizes + * @inum: inode number + * @i_size: size on inode + * @d_size: maximum size based on data nodes + * @exists: indicates whether the inode exists + * @inode: inode if pinned in memory awaiting rw mode to fix it + */ +struct size_entry { + struct rb_node rb; + ino_t inum; + loff_t i_size; + loff_t d_size; + int exists; + struct inode *inode; +}; + +/** + * add_ino - add an entry to the size tree. + * @c: UBIFS file-system description object + * @inum: inode number + * @i_size: size on inode + * @d_size: maximum size based on data nodes + * @exists: indicates whether the inode exists + */ +static int add_ino(struct ubifs_info *c, ino_t inum, loff_t i_size, + loff_t d_size, int exists) +{ + struct rb_node **p = &c->size_tree.rb_node, *parent = NULL; + struct size_entry *e; + + while (*p) { + parent = *p; + e = rb_entry(parent, struct size_entry, rb); + if (inum < e->inum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + e = kzalloc(sizeof(struct size_entry), GFP_KERNEL); + if (!e) + return -ENOMEM; + + e->inum = inum; + e->i_size = i_size; + e->d_size = d_size; + e->exists = exists; + + rb_link_node(&e->rb, parent, p); + rb_insert_color(&e->rb, &c->size_tree); + + return 0; +} + +/** + * find_ino - find an entry on the size tree. + * @c: UBIFS file-system description object + * @inum: inode number + */ +static struct size_entry *find_ino(struct ubifs_info *c, ino_t inum) +{ + struct rb_node *p = c->size_tree.rb_node; + struct size_entry *e; + + while (p) { + e = rb_entry(p, struct size_entry, rb); + if (inum < e->inum) + p = p->rb_left; + else if (inum > e->inum) + p = p->rb_right; + else + return e; + } + return NULL; +} + +/** + * remove_ino - remove an entry from the size tree. + * @c: UBIFS file-system description object + * @inum: inode number + */ +static void remove_ino(struct ubifs_info *c, ino_t inum) +{ + struct size_entry *e = find_ino(c, inum); + + if (!e) + return; + rb_erase(&e->rb, &c->size_tree); + kfree(e); +} + +/** + * ubifs_destroy_size_tree - free resources related to the size tree. + * @c: UBIFS file-system description object + */ +void ubifs_destroy_size_tree(struct ubifs_info *c) +{ + struct rb_node *this = c->size_tree.rb_node; + struct size_entry *e; + + while (this) { + if (this->rb_left) { + this = this->rb_left; + continue; + } else if (this->rb_right) { + this = this->rb_right; + continue; + } + e = rb_entry(this, struct size_entry, rb); + if (e->inode) + iput(e->inode); + this = rb_parent(this); + if (this) { + if (this->rb_left == &e->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + kfree(e); + } + c->size_tree = RB_ROOT; +} + +/** + * ubifs_recover_size_accum - accumulate inode sizes for recovery. + * @c: UBIFS file-system description object + * @key: node key + * @deletion: node is for a deletion + * @new_size: inode size + * + * This function has two purposes: + * 1) to ensure there are no data nodes that fall outside the inode size + * 2) to ensure there are no data nodes for inodes that do not exist + * To accomplish those purposes, a rb-tree is constructed containing an entry + * for each inode number in the journal that has not been deleted, and recording + * the size from the inode node, the maximum size of any data node (also altered + * by truncations) and a flag indicating a inode number for which no inode node + * was present in the journal. + * + * Note that there is still the possibility that there are data nodes that have + * been committed that are beyond the inode size, however the only way to find + * them would be to scan the entire index. Alternatively, some provision could + * be made to record the size of inodes at the start of commit, which would seem + * very cumbersome for a scenario that is quite unlikely and the only negative + * consequence of which is wasted space. + * + * This functions returns %0 on success and a negative error code on failure. + */ +int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, + int deletion, loff_t new_size) +{ + ino_t inum = key_inum(c, key); + struct size_entry *e; + int err; + + switch (key_type(c, key)) { + case UBIFS_INO_KEY: + if (deletion) + remove_ino(c, inum); + else { + e = find_ino(c, inum); + if (e) { + e->i_size = new_size; + e->exists = 1; + } else { + err = add_ino(c, inum, new_size, 0, 1); + if (err) + return err; + } + } + break; + case UBIFS_DATA_KEY: + e = find_ino(c, inum); + if (e) { + if (new_size > e->d_size) + e->d_size = new_size; + } else { + err = add_ino(c, inum, 0, new_size, 0); + if (err) + return err; + } + break; + case UBIFS_TRUN_KEY: + e = find_ino(c, inum); + if (e) + e->d_size = new_size; + break; + } + return 0; +} + +/** + * fix_size_in_place - fix inode size in place on flash. + * @c: UBIFS file-system description object + * @e: inode size information for recovery + */ +static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) +{ + struct ubifs_ino_node *ino = c->sbuf; + unsigned char *p; + union ubifs_key key; + int err, lnum, offs, len; + loff_t i_size; + uint32_t crc; + + /* Locate the inode node LEB number and offset */ + ino_key_init(c, &key, e->inum); + err = ubifs_tnc_locate(c, &key, ino, &lnum, &offs); + if (err) + goto out; + /* + * If the size recorded on the inode node is greater than the size that + * was calculated from nodes in the journal then don't change the inode. + */ + i_size = le64_to_cpu(ino->size); + if (i_size >= e->d_size) + return 0; + /* Read the LEB */ + err = ubi_read(c->ubi, lnum, c->sbuf, 0, c->leb_size); + if (err) + goto out; + /* Change the size field and recalculate the CRC */ + ino = c->sbuf + offs; + ino->size = cpu_to_le64(e->d_size); + len = le32_to_cpu(ino->ch.len); + crc = crc32(UBIFS_CRC32_INIT, (void *)ino + 8, len - 8); + ino->ch.crc = cpu_to_le32(crc); + /* Work out where data in the LEB ends and free space begins */ + p = c->sbuf; + len = c->leb_size - 1; + while (p[len] == 0xff) + len -= 1; + len = ALIGN(len + 1, c->min_io_size); + /* Atomically write the fixed LEB back again */ + err = ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN); + if (err) + goto out; + dbg_rcvry("inode %lu at %d:%d size %lld -> %lld ", e->inum, lnum, offs, + i_size, e->d_size); + return 0; + +out: + ubifs_warn("inode %lu failed to fix size %lld -> %lld error %d", + e->inum, e->i_size, e->d_size, err); + return err; +} + +/** + * ubifs_recover_size - recover inode size. + * @c: UBIFS file-system description object + * + * This function attempts to fix inode size discrepancies identified by the + * 'ubifs_recover_size_accum()' function. + * + * This functions returns %0 on success and a negative error code on failure. + */ +int ubifs_recover_size(struct ubifs_info *c) +{ + struct rb_node *this = rb_first(&c->size_tree); + + while (this) { + struct size_entry *e; + int err; + + e = rb_entry(this, struct size_entry, rb); + if (!e->exists) { + union ubifs_key key; + + ino_key_init(c, &key, e->inum); + err = ubifs_tnc_lookup(c, &key, c->sbuf); + if (err && err != -ENOENT) + return err; + if (err == -ENOENT) { + /* Remove data nodes that have no inode */ + dbg_rcvry("removing ino %lu", e->inum); + err = ubifs_tnc_remove_ino(c, e->inum); + if (err) + return err; + } else { + struct ubifs_ino_node *ino = c->sbuf; + + e->exists = 1; + e->i_size = le64_to_cpu(ino->size); + } + } + if (e->exists && e->i_size < e->d_size) { + if (!e->inode && (c->vfs_sb->s_flags & MS_RDONLY)) { + /* Fix the inode size and pin it in memory */ + struct inode *inode; + + inode = ubifs_iget(c->vfs_sb, e->inum); + if (IS_ERR(inode)) + return PTR_ERR(inode); + if (inode->i_size < e->d_size) { + dbg_rcvry("ino %lu size %lld -> %lld", + e->inum, e->d_size, + inode->i_size); + inode->i_size = e->d_size; + ubifs_inode(inode)->ui_size = e->d_size; + e->inode = inode; + this = rb_next(this); + continue; + } + iput(inode); + } else { + /* Fix the size in place */ + err = fix_size_in_place(c, e); + if (err) + return err; + if (e->inode) + iput(e->inode); + } + } + this = rb_next(this); + rb_erase(&e->rb, &c->size_tree); + kfree(e); + } + return 0; +} diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c new file mode 100644 index 0000000..7399692 --- /dev/null +++ b/fs/ubifs/replay.c @@ -0,0 +1,1075 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file contains journal replay code. It runs when the file-system is being + * mounted and requires no locking. + * + * The larger is the journal, the longer it takes to scan it, so the longer it + * takes to mount UBIFS. This is why the journal has limited size which may be + * changed depending on the system requirements. But a larger journal gives + * faster I/O speed because it writes the index less frequently. So this is a + * trade-off. Also, the journal is indexed by the in-memory index (TNC), so the + * larger is the journal, the more memory its index may consume. + */ + +#include "ubifs.h" + +/* + * Replay flags. + * + * REPLAY_DELETION: node was deleted + * REPLAY_REF: node is a reference node + */ +enum { + REPLAY_DELETION = 1, + REPLAY_REF = 2, +}; + +/** + * struct replay_entry - replay tree entry. + * @lnum: logical eraseblock number of the node + * @offs: node offset + * @len: node length + * @sqnum: node sequence number + * @flags: replay flags + * @rb: links the replay tree + * @key: node key + * @nm: directory entry name + * @old_size: truncation old size + * @new_size: truncation new size + * @free: amount of free space in a bud + * @dirty: amount of dirty space in a bud from padding and deletion nodes + * + * UBIFS journal replay must compare node sequence numbers, which means it must + * build a tree of node information to insert into the TNC. + */ +struct replay_entry { + int lnum; + int offs; + int len; + unsigned long long sqnum; + int flags; + struct rb_node rb; + union ubifs_key key; + union { + struct qstr nm; + struct { + loff_t old_size; + loff_t new_size; + }; + struct { + int free; + int dirty; + }; + }; +}; + +/** + * struct bud_entry - entry in the list of buds to replay. + * @list: next bud in the list + * @bud: bud description object + * @free: free bytes in the bud + * @sqnum: reference node sequence number + */ +struct bud_entry { + struct list_head list; + struct ubifs_bud *bud; + int free; + unsigned long long sqnum; +}; + +/** + * set_bud_lprops - set free and dirty space used by a bud. + * @c: UBIFS file-system description object + * @r: replay entry of bud + */ +static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r) +{ + const struct ubifs_lprops *lp; + int err = 0, dirty; + + ubifs_get_lprops(c); + + lp = ubifs_lpt_lookup_dirty(c, r->lnum); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + + dirty = lp->dirty; + if (r->offs == 0 && (lp->free != c->leb_size || lp->dirty != 0)) { + /* + * The LEB was added to the journal with a starting offset of + * zero which means the LEB must have been empty. The LEB + * property values should be lp->free == c->leb_size and + * lp->dirty == 0, but that is not the case. The reason is that + * the LEB was garbage collected. The garbage collector resets + * the free and dirty space without recording it anywhere except + * lprops, so if there is not a commit then lprops does not have + * that information next time the file system is mounted. + * + * We do not need to adjust free space because the scan has told + * us the exact value which is recorded in the replay entry as + * r->free. + * + * However we do need to subtract from the dirty space the + * amount of space that the garbage collector reclaimed, which + * is the whole LEB minus the amount of space that was free. + */ + dbg_mnt("bud LEB %d was GC'd (%d free, %d dirty)", r->lnum, + lp->free, lp->dirty); + dbg_gc("bud LEB %d was GC'd (%d free, %d dirty)", r->lnum, + lp->free, lp->dirty); + dirty -= c->leb_size - lp->free; + /* + * If the replay order was perfect the dirty space would now be + * zero. The order is not perfect because the the journal heads + * race with eachother. This is not a problem but is does mean + * that the dirty space may temporarily exceed c->leb_size + * during the replay. + */ + if (dirty != 0) + dbg_msg("LEB %d lp: %d free %d dirty " + "replay: %d free %d dirty", r->lnum, lp->free, + lp->dirty, r->free, r->dirty); + } + lp = ubifs_change_lp(c, lp, r->free, dirty + r->dirty, + lp->flags | LPROPS_TAKEN, 0); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } +out: + ubifs_release_lprops(c); + return err; +} + +/** + * trun_remove_range - apply a replay entry for a truncation to the TNC. + * @c: UBIFS file-system description object + * @r: replay entry of truncation + */ +static int trun_remove_range(struct ubifs_info *c, struct replay_entry *r) +{ + unsigned min_blk, max_blk; + union ubifs_key min_key, max_key; + ino_t ino; + + min_blk = r->new_size / UBIFS_BLOCK_SIZE; + if (r->new_size & (UBIFS_BLOCK_SIZE - 1)) + min_blk += 1; + + max_blk = r->old_size / UBIFS_BLOCK_SIZE; + if ((r->old_size & (UBIFS_BLOCK_SIZE - 1)) == 0) + max_blk -= 1; + + ino = key_inum(c, &r->key); + + data_key_init(c, &min_key, ino, min_blk); + data_key_init(c, &max_key, ino, max_blk); + + return ubifs_tnc_remove_range(c, &min_key, &max_key); +} + +/** + * apply_replay_entry - apply a replay entry to the TNC. + * @c: UBIFS file-system description object + * @r: replay entry to apply + * + * Apply a replay entry to the TNC. + */ +static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r) +{ + int err, deletion = ((r->flags & REPLAY_DELETION) != 0); + + dbg_mnt("LEB %d:%d len %d flgs %d sqnum %llu %s", r->lnum, + r->offs, r->len, r->flags, r->sqnum, DBGKEY(&r->key)); + + /* Set c->replay_sqnum to help deal with dangling branches. */ + c->replay_sqnum = r->sqnum; + + if (r->flags & REPLAY_REF) + err = set_bud_lprops(c, r); + else if (is_hash_key(c, &r->key)) { + if (deletion) + err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); + else + err = ubifs_tnc_add_nm(c, &r->key, r->lnum, r->offs, + r->len, &r->nm); + } else { + if (deletion) + switch (key_type(c, &r->key)) { + case UBIFS_INO_KEY: + { + ino_t inum = key_inum(c, &r->key); + + err = ubifs_tnc_remove_ino(c, inum); + break; + } + case UBIFS_TRUN_KEY: + err = trun_remove_range(c, r); + break; + default: + err = ubifs_tnc_remove(c, &r->key); + break; + } + else + err = ubifs_tnc_add(c, &r->key, r->lnum, r->offs, + r->len); + if (err) + return err; + + if (c->need_recovery) + err = ubifs_recover_size_accum(c, &r->key, deletion, + r->new_size); + } + + return err; +} + +/** + * destroy_replay_tree - destroy the replay. + * @c: UBIFS file-system description object + * + * Destroy the replay tree. + */ +static void destroy_replay_tree(struct ubifs_info *c) +{ + struct rb_node *this = c->replay_tree.rb_node; + struct replay_entry *r; + + while (this) { + if (this->rb_left) { + this = this->rb_left; + continue; + } else if (this->rb_right) { + this = this->rb_right; + continue; + } + r = rb_entry(this, struct replay_entry, rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &r->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + if (is_hash_key(c, &r->key)) + kfree(r->nm.name); + kfree(r); + } + c->replay_tree = RB_ROOT; +} + +/** + * apply_replay_tree - apply the replay tree to the TNC. + * @c: UBIFS file-system description object + * + * Apply the replay tree. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +static int apply_replay_tree(struct ubifs_info *c) +{ + struct rb_node *this = rb_first(&c->replay_tree); + + while (this) { + struct replay_entry *r; + int err; + + cond_resched(); + + r = rb_entry(this, struct replay_entry, rb); + err = apply_replay_entry(c, r); + if (err) + return err; + this = rb_next(this); + } + return 0; +} + +/** + * insert_node - insert a node to the replay tree. + * @c: UBIFS file-system description object + * @lnum: node logical eraseblock number + * @offs: node offset + * @len: node length + * @key: node key + * @sqnum: sequence number + * @deletion: non-zero if this is a deletion + * @used: number of bytes in use in a LEB + * @old_size: truncation old size + * @new_size: truncation new size + * + * This function inserts a scanned non-direntry node to the replay tree. The + * replay tree is an RB-tree containing @struct replay_entry elements which are + * indexed by the sequence number. The replay tree is applied at the very end + * of the replay process. Since the tree is sorted in sequence number order, + * the older modifications are applied first. This function returns zero in + * case of success and a negative error code in case of failure. + */ +static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, + union ubifs_key *key, unsigned long long sqnum, + int deletion, int *used, loff_t old_size, + loff_t new_size) +{ + struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; + struct replay_entry *r; + + if (key_inum(c, key) >= c->highest_inum) + c->highest_inum = key_inum(c, key); + + dbg_mnt("add LEB %d:%d, key %s", lnum, offs, DBGKEY(key)); + while (*p) { + parent = *p; + r = rb_entry(parent, struct replay_entry, rb); + if (sqnum < r->sqnum) { + p = &(*p)->rb_left; + continue; + } else if (sqnum > r->sqnum) { + p = &(*p)->rb_right; + continue; + } + ubifs_err("duplicate sqnum in replay"); + return -EINVAL; + } + + r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); + if (!r) + return -ENOMEM; + + if (!deletion) + *used += ALIGN(len, 8); + r->lnum = lnum; + r->offs = offs; + r->len = len; + r->sqnum = sqnum; + r->flags = (deletion ? REPLAY_DELETION : 0); + r->old_size = old_size; + r->new_size = new_size; + key_copy(c, key, &r->key); + + rb_link_node(&r->rb, parent, p); + rb_insert_color(&r->rb, &c->replay_tree); + return 0; +} + +/** + * insert_dent - insert a directory entry node into the replay tree. + * @c: UBIFS file-system description object + * @lnum: node logical eraseblock number + * @offs: node offset + * @len: node length + * @key: node key + * @name: directory entry name + * @nlen: directory entry name length + * @sqnum: sequence number + * @deletion: non-zero if this is a deletion + * @used: number of bytes in use in a LEB + * + * This function inserts a scanned directory entry node to the replay tree. + * Returns zero in case of success and a negative error code in case of + * failure. + * + * This function is also used for extended attribute entries because they are + * implemented as directory entry nodes. + */ +static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, + union ubifs_key *key, const char *name, int nlen, + unsigned long long sqnum, int deletion, int *used) +{ + struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; + struct replay_entry *r; + char *nbuf; + + if (key_inum(c, key) >= c->highest_inum) + c->highest_inum = key_inum(c, key); + + dbg_mnt("add LEB %d:%d, key %s", lnum, offs, DBGKEY(key)); + while (*p) { + parent = *p; + r = rb_entry(parent, struct replay_entry, rb); + if (sqnum < r->sqnum) { + p = &(*p)->rb_left; + continue; + } + if (sqnum > r->sqnum) { + p = &(*p)->rb_right; + continue; + } + ubifs_err("duplicate sqnum in replay"); + return -EINVAL; + } + + r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); + if (!r) + return -ENOMEM; + nbuf = kmalloc(nlen + 1, GFP_KERNEL); + if (!nbuf) { + kfree(r); + return -ENOMEM; + } + + if (!deletion) + *used += ALIGN(len, 8); + r->lnum = lnum; + r->offs = offs; + r->len = len; + r->sqnum = sqnum; + r->nm.len = nlen; + memcpy(nbuf, name, nlen); + nbuf[nlen] = '\0'; + r->nm.name = nbuf; + r->flags = (deletion ? REPLAY_DELETION : 0); + key_copy(c, key, &r->key); + + ubifs_assert(!*p); + rb_link_node(&r->rb, parent, p); + rb_insert_color(&r->rb, &c->replay_tree); + return 0; +} + +/** + * ubifs_validate_entry - validate directory or extended attribute entry node. + * @c: UBIFS file-system description object + * @dent: the node to validate + * + * This function validates directory or extended attribute entry node @dent. + * Returns zero if the node is all right and a %-EINVAL if not. + */ +int ubifs_validate_entry(struct ubifs_info *c, + const struct ubifs_dent_node *dent) +{ + int key_type = key_type_flash(c, dent->key); + int nlen = le16_to_cpu(dent->nlen); + + if (le32_to_cpu(dent->ch.len) != nlen + UBIFS_DENT_NODE_SZ + 1 || + dent->type >= UBIFS_ITYPES_CNT || + nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 || + strnlen(dent->name, nlen) != nlen || + le64_to_cpu(dent->inum) > MAX_INUM) { + ubifs_err("bad %s node", key_type == UBIFS_DENT_KEY ? + "directory entry" : "extended attribute entry"); + return -EINVAL; + } + + if (key_type != UBIFS_DENT_KEY && key_type != UBIFS_XENT_KEY) { + ubifs_err("bad key type %d", key_type); + return -EINVAL; + } + + return 0; +} + +/** + * replay_bud - replay a bud logical eraseblock. + * @c: UBIFS file-system description object + * @lnum: bud logical eraseblock number to replay + * @offs: bud start offset + * @jhead: journal head to which this bud belongs + * @free: amount of free space in the bud is returned here + * @dirty: amount of dirty space from padding and deletion nodes is returned + * here + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, + int *free, int *dirty) +{ + int err = 0, used = 0; + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + struct ubifs_bud *bud; + + dbg_mnt("replay bud LEB %d, head %d", lnum, jhead); + if (c->need_recovery) + sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, jhead != GCHD); + else + sleb = ubifs_scan(c, lnum, offs, c->sbuf); + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + + /* + * The bud does not have to start from offset zero - the beginning of + * the 'lnum' LEB may contain previously committed data. One of the + * things we have to do in replay is to correctly update lprops with + * newer information about this LEB. + * + * At this point lprops thinks that this LEB has 'c->leb_size - offs' + * bytes of free space because it only contain information about + * committed data. + * + * But we know that real amount of free space is 'c->leb_size - + * sleb->endpt', and the space in the 'lnum' LEB between 'offs' and + * 'sleb->endpt' is used by bud data. We have to correctly calculate + * how much of these data are dirty and update lprops with this + * information. + * + * The dirt in that LEB region is comprised of padding nodes, deletion + * nodes, truncation nodes and nodes which are obsoleted by subsequent + * nodes in this LEB. So instead of calculating clean space, we + * calculate used space ('used' variable). + */ + + list_for_each_entry(snod, &sleb->nodes, list) { + int deletion = 0; + + cond_resched(); + + if (snod->sqnum >= SQNUM_WATERMARK) { + ubifs_err("file system's life ended"); + goto out_dump; + } + + if (snod->sqnum > c->max_sqnum) + c->max_sqnum = snod->sqnum; + + switch (snod->type) { + case UBIFS_INO_NODE: + { + struct ubifs_ino_node *ino = snod->node; + loff_t new_size = le64_to_cpu(ino->size); + + if (le32_to_cpu(ino->nlink) == 0) + deletion = 1; + err = insert_node(c, lnum, snod->offs, snod->len, + &snod->key, snod->sqnum, deletion, + &used, 0, new_size); + break; + } + case UBIFS_DATA_NODE: + { + struct ubifs_data_node *dn = snod->node; + loff_t new_size = le32_to_cpu(dn->size) + + key_block(c, &snod->key) * + UBIFS_BLOCK_SIZE; + + err = insert_node(c, lnum, snod->offs, snod->len, + &snod->key, snod->sqnum, deletion, + &used, 0, new_size); + break; + } + case UBIFS_DENT_NODE: + case UBIFS_XENT_NODE: + { + struct ubifs_dent_node *dent = snod->node; + + err = ubifs_validate_entry(c, dent); + if (err) + goto out_dump; + + err = insert_dent(c, lnum, snod->offs, snod->len, + &snod->key, dent->name, + le16_to_cpu(dent->nlen), snod->sqnum, + !le64_to_cpu(dent->inum), &used); + break; + } + case UBIFS_TRUN_NODE: + { + struct ubifs_trun_node *trun = snod->node; + loff_t old_size = le64_to_cpu(trun->old_size); + loff_t new_size = le64_to_cpu(trun->new_size); + union ubifs_key key; + + /* Validate truncation node */ + if (old_size < 0 || old_size > c->max_inode_sz || + new_size < 0 || new_size > c->max_inode_sz || + old_size <= new_size) { + ubifs_err("bad truncation node"); + goto out_dump; + } + + /* + * Create a fake truncation key just to use the same + * functions which expect nodes to have keys. + */ + trun_key_init(c, &key, le32_to_cpu(trun->inum)); + err = insert_node(c, lnum, snod->offs, snod->len, + &key, snod->sqnum, 1, &used, + old_size, new_size); + break; + } + default: + ubifs_err("unexpected node type %d in bud LEB %d:%d", + snod->type, lnum, snod->offs); + err = -EINVAL; + goto out_dump; + } + if (err) + goto out; + } + + bud = ubifs_search_bud(c, lnum); + if (!bud) + BUG(); + + ubifs_assert(sleb->endpt - offs >= used); + ubifs_assert(sleb->endpt % c->min_io_size == 0); + + if (sleb->endpt + c->min_io_size <= c->leb_size && + !(c->vfs_sb->s_flags & MS_RDONLY)) + err = ubifs_wbuf_seek_nolock(&c->jheads[jhead].wbuf, lnum, + sleb->endpt, UBI_SHORTTERM); + + *dirty = sleb->endpt - offs - used; + *free = c->leb_size - sleb->endpt; + +out: + ubifs_scan_destroy(sleb); + return err; + +out_dump: + ubifs_err("bad node is at LEB %d:%d", lnum, snod->offs); + dbg_dump_node(c, snod->node); + ubifs_scan_destroy(sleb); + return -EINVAL; +} + +/** + * insert_ref_node - insert a reference node to the replay tree. + * @c: UBIFS file-system description object + * @lnum: node logical eraseblock number + * @offs: node offset + * @sqnum: sequence number + * @free: amount of free space in bud + * @dirty: amount of dirty space from padding and deletion nodes + * + * This function inserts a reference node to the replay tree and returns zero + * in case of success ort a negative error code in case of failure. + */ +static int insert_ref_node(struct ubifs_info *c, int lnum, int offs, + unsigned long long sqnum, int free, int dirty) +{ + struct rb_node **p = &c->replay_tree.rb_node, *parent = NULL; + struct replay_entry *r; + + dbg_mnt("add ref LEB %d:%d", lnum, offs); + while (*p) { + parent = *p; + r = rb_entry(parent, struct replay_entry, rb); + if (sqnum < r->sqnum) { + p = &(*p)->rb_left; + continue; + } else if (sqnum > r->sqnum) { + p = &(*p)->rb_right; + continue; + } + ubifs_err("duplicate sqnum in replay tree"); + return -EINVAL; + } + + r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); + if (!r) + return -ENOMEM; + + r->lnum = lnum; + r->offs = offs; + r->sqnum = sqnum; + r->flags = REPLAY_REF; + r->free = free; + r->dirty = dirty; + + rb_link_node(&r->rb, parent, p); + rb_insert_color(&r->rb, &c->replay_tree); + return 0; +} + +/** + * replay_buds - replay all buds. + * @c: UBIFS file-system description object + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int replay_buds(struct ubifs_info *c) +{ + struct bud_entry *b; + int err, uninitialized_var(free), uninitialized_var(dirty); + + list_for_each_entry(b, &c->replay_buds, list) { + err = replay_bud(c, b->bud->lnum, b->bud->start, b->bud->jhead, + &free, &dirty); + if (err) + return err; + err = insert_ref_node(c, b->bud->lnum, b->bud->start, b->sqnum, + free, dirty); + if (err) + return err; + } + + return 0; +} + +/** + * destroy_bud_list - destroy the list of buds to replay. + * @c: UBIFS file-system description object + */ +static void destroy_bud_list(struct ubifs_info *c) +{ + struct bud_entry *b; + + while (!list_empty(&c->replay_buds)) { + b = list_entry(c->replay_buds.next, struct bud_entry, list); + list_del(&b->list); + kfree(b); + } +} + +/** + * add_replay_bud - add a bud to the list of buds to replay. + * @c: UBIFS file-system description object + * @lnum: bud logical eraseblock number to replay + * @offs: bud start offset + * @jhead: journal head to which this bud belongs + * @sqnum: reference node sequence number + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int add_replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, + unsigned long long sqnum) +{ + struct ubifs_bud *bud; + struct bud_entry *b; + + dbg_mnt("add replay bud LEB %d:%d, head %d", lnum, offs, jhead); + + bud = kmalloc(sizeof(struct ubifs_bud), GFP_KERNEL); + if (!bud) + return -ENOMEM; + + b = kmalloc(sizeof(struct bud_entry), GFP_KERNEL); + if (!b) { + kfree(bud); + return -ENOMEM; + } + + bud->lnum = lnum; + bud->start = offs; + bud->jhead = jhead; + ubifs_add_bud(c, bud); + + b->bud = bud; + b->sqnum = sqnum; + list_add_tail(&b->list, &c->replay_buds); + + return 0; +} + +/** + * validate_ref - validate a reference node. + * @c: UBIFS file-system description object + * @ref: the reference node to validate + * @ref_lnum: LEB number of the reference node + * @ref_offs: reference node offset + * + * This function returns %1 if a bud reference already exists for the LEB. %0 is + * returned if the reference node is new, otherwise %-EINVAL is returned if + * validation failed. + */ +static int validate_ref(struct ubifs_info *c, const struct ubifs_ref_node *ref) +{ + struct ubifs_bud *bud; + int lnum = le32_to_cpu(ref->lnum); + unsigned int offs = le32_to_cpu(ref->offs); + unsigned int jhead = le32_to_cpu(ref->jhead); + + /* + * ref->offs may point to the end of LEB when the journal head points + * to the end of LEB and we write reference node for it during commit. + * So this is why we require 'offs > c->leb_size'. + */ + if (jhead >= c->jhead_cnt || lnum >= c->leb_cnt || + lnum < c->main_first || offs > c->leb_size || + offs & (c->min_io_size - 1)) + return -EINVAL; + + /* Make sure we have not already looked at this bud */ + bud = ubifs_search_bud(c, lnum); + if (bud) { + if (bud->jhead == jhead && bud->start <= offs) + return 1; + ubifs_err("bud at LEB %d:%d was already referred", lnum, offs); + return -EINVAL; + } + + return 0; +} + +/** + * replay_log_leb - replay a log logical eraseblock. + * @c: UBIFS file-system description object + * @lnum: log logical eraseblock to replay + * @offs: offset to start replaying from + * @sbuf: scan buffer + * + * This function replays a log LEB and returns zero in case of success, %1 if + * this is the last LEB in the log, and a negative error code in case of + * failure. + */ +static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) +{ + int err; + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + const struct ubifs_cs_node *node; + + dbg_mnt("replay log LEB %d:%d", lnum, offs); + sleb = ubifs_scan(c, lnum, offs, sbuf); + if (IS_ERR(sleb)) { + if (c->need_recovery) + sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + } + + if (sleb->nodes_cnt == 0) { + err = 1; + goto out; + } + + node = sleb->buf; + + snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list); + if (c->cs_sqnum == 0) { + /* + * This is the first log LEB we are looking at, make sure that + * the first node is a commit start node. Also record its + * sequence number so that UBIFS can determine where the log + * ends, because all nodes which were have higher sequence + * numbers. + */ + if (snod->type != UBIFS_CS_NODE) { + dbg_err("first log node at LEB %d:%d is not CS node", + lnum, offs); + goto out_dump; + } + if (le64_to_cpu(node->cmt_no) != c->cmt_no) { + dbg_err("first CS node at LEB %d:%d has wrong " + "commit number %llu expected %llu", + lnum, offs, + (unsigned long long)le64_to_cpu(node->cmt_no), + c->cmt_no); + goto out_dump; + } + + c->cs_sqnum = le64_to_cpu(node->ch.sqnum); + dbg_mnt("commit start sqnum %llu", c->cs_sqnum); + } + + if (snod->sqnum < c->cs_sqnum) { + /* + * This means that we reached end of log and now + * look to the older log data, which was already + * committed but the eraseblock was not erased (UBIFS + * only unmaps it). So this basically means we have to + * exit with "end of log" code. + */ + err = 1; + goto out; + } + + /* Make sure the first node sits at offset zero of the LEB */ + if (snod->offs != 0) { + dbg_err("first node is not at zero offset"); + goto out_dump; + } + + list_for_each_entry(snod, &sleb->nodes, list) { + + cond_resched(); + + if (snod->sqnum >= SQNUM_WATERMARK) { + ubifs_err("file system's life ended"); + goto out_dump; + } + + if (snod->sqnum < c->cs_sqnum) { + dbg_err("bad sqnum %llu, commit sqnum %llu", + snod->sqnum, c->cs_sqnum); + goto out_dump; + } + + if (snod->sqnum > c->max_sqnum) + c->max_sqnum = snod->sqnum; + + switch (snod->type) { + case UBIFS_REF_NODE: { + const struct ubifs_ref_node *ref = snod->node; + + err = validate_ref(c, ref); + if (err == 1) + break; /* Already have this bud */ + if (err) + goto out_dump; + + err = add_replay_bud(c, le32_to_cpu(ref->lnum), + le32_to_cpu(ref->offs), + le32_to_cpu(ref->jhead), + snod->sqnum); + if (err) + goto out; + + break; + } + case UBIFS_CS_NODE: + /* Make sure it sits at the beginning of LEB */ + if (snod->offs != 0) { + ubifs_err("unexpected node in log"); + goto out_dump; + } + break; + default: + ubifs_err("unexpected node in log"); + goto out_dump; + } + } + + if (sleb->endpt || c->lhead_offs >= c->leb_size) { + c->lhead_lnum = lnum; + c->lhead_offs = sleb->endpt; + } + + err = !sleb->endpt; +out: + ubifs_scan_destroy(sleb); + return err; + +out_dump: + ubifs_err("log error detected while replying the log at LEB %d:%d", + lnum, offs + snod->offs); + dbg_dump_node(c, snod->node); + ubifs_scan_destroy(sleb); + return -EINVAL; +} + +/** + * take_ihead - update the status of the index head in lprops to 'taken'. + * @c: UBIFS file-system description object + * + * This function returns the amount of free space in the index head LEB or a + * negative error code. + */ +static int take_ihead(struct ubifs_info *c) +{ + const struct ubifs_lprops *lp; + int err, free; + + ubifs_get_lprops(c); + + lp = ubifs_lpt_lookup_dirty(c, c->ihead_lnum); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + + free = lp->free; + + lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC, + lp->flags | LPROPS_TAKEN, 0); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + + err = free; +out: + ubifs_release_lprops(c); + return err; +} + +/** + * ubifs_replay_journal - replay journal. + * @c: UBIFS file-system description object + * + * This function scans the journal, replays and cleans it up. It makes sure all + * memory data structures related to uncommitted journal are built (dirty TNC + * tree, tree of buds, modified lprops, etc). + */ +int ubifs_replay_journal(struct ubifs_info *c) +{ + int err, i, lnum, offs, free; + void *sbuf = NULL; + + BUILD_BUG_ON(UBIFS_TRUN_KEY > 5); + + /* Update the status of the index head in lprops to 'taken' */ + free = take_ihead(c); + if (free < 0) + return free; /* Error code */ + + if (c->ihead_offs != c->leb_size - free) { + ubifs_err("bad index head LEB %d:%d", c->ihead_lnum, + c->ihead_offs); + return -EINVAL; + } + + sbuf = vmalloc(c->leb_size); + if (!sbuf) + return -ENOMEM; + + dbg_mnt("start replaying the journal"); + + c->replaying = 1; + + lnum = c->ltail_lnum = c->lhead_lnum; + offs = c->lhead_offs; + + for (i = 0; i < c->log_lebs; i++, lnum++) { + if (lnum >= UBIFS_LOG_LNUM + c->log_lebs) { + /* + * The log is logically circular, we reached the last + * LEB, switch to the first one. + */ + lnum = UBIFS_LOG_LNUM; + offs = 0; + } + err = replay_log_leb(c, lnum, offs, sbuf); + if (err == 1) + /* We hit the end of the log */ + break; + if (err) + goto out; + offs = 0; + } + + err = replay_buds(c); + if (err) + goto out; + + err = apply_replay_tree(c); + if (err) + goto out; + + ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); + dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, " + "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum, + c->highest_inum); +out: + destroy_replay_tree(c); + destroy_bud_list(c); + vfree(sbuf); + c->replaying = 0; + return err; +} diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c new file mode 100644 index 0000000..2bf753b --- /dev/null +++ b/fs/ubifs/sb.c @@ -0,0 +1,629 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements UBIFS superblock. The superblock is stored at the first + * LEB of the volume and is never changed by UBIFS. Only user-space tools may + * change it. The superblock node mostly contains geometry information. + */ + +#include "ubifs.h" +#include + +/* + * Default journal size in logical eraseblocks as a percent of total + * flash size. + */ +#define DEFAULT_JNL_PERCENT 5 + +/* Default maximum journal size in bytes */ +#define DEFAULT_MAX_JNL (32*1024*1024) + +/* Default indexing tree fanout */ +#define DEFAULT_FANOUT 8 + +/* Default number of data journal heads */ +#define DEFAULT_JHEADS_CNT 1 + +/* Default positions of different LEBs in the main area */ +#define DEFAULT_IDX_LEB 0 +#define DEFAULT_DATA_LEB 1 +#define DEFAULT_GC_LEB 2 + +/* Default number of LEB numbers in LPT's save table */ +#define DEFAULT_LSAVE_CNT 256 + +/* Default reserved pool size as a percent of maximum free space */ +#define DEFAULT_RP_PERCENT 5 + +/* The default maximum size of reserved pool in bytes */ +#define DEFAULT_MAX_RP_SIZE (5*1024*1024) + +/* Default time granularity in nanoseconds */ +#define DEFAULT_TIME_GRAN 1000000000 + +/** + * create_default_filesystem - format empty UBI volume. + * @c: UBIFS file-system description object + * + * This function creates default empty file-system. Returns zero in case of + * success and a negative error code in case of failure. + */ +static int create_default_filesystem(struct ubifs_info *c) +{ + struct ubifs_sb_node *sup; + struct ubifs_mst_node *mst; + struct ubifs_idx_node *idx; + struct ubifs_branch *br; + struct ubifs_ino_node *ino; + struct ubifs_cs_node *cs; + union ubifs_key key; + int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; + int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; + int min_leb_cnt = UBIFS_MIN_LEB_CNT; + uint64_t tmp64, main_bytes; + + /* Some functions called from here depend on the @c->key_len filed */ + c->key_len = UBIFS_SK_LEN; + + /* + * First of all, we have to calculate default file-system geometry - + * log size, journal size, etc. + */ + if (c->leb_cnt < 0x7FFFFFFF / DEFAULT_JNL_PERCENT) + /* We can first multiply then divide and have no overflow */ + jnl_lebs = c->leb_cnt * DEFAULT_JNL_PERCENT / 100; + else + jnl_lebs = (c->leb_cnt / 100) * DEFAULT_JNL_PERCENT; + + if (jnl_lebs < UBIFS_MIN_JNL_LEBS) + jnl_lebs = UBIFS_MIN_JNL_LEBS; + if (jnl_lebs * c->leb_size > DEFAULT_MAX_JNL) + jnl_lebs = DEFAULT_MAX_JNL / c->leb_size; + + /* + * The log should be large enough to fit reference nodes for all bud + * LEBs. Because buds do not have to start from the beginning of LEBs + * (half of the LEB may contain committed data), the log should + * generally be larger, make it twice as large. + */ + tmp = 2 * (c->ref_node_alsz * jnl_lebs) + c->leb_size - 1; + log_lebs = tmp / c->leb_size; + /* Plus one LEB reserved for commit */ + log_lebs += 1; + if (c->leb_cnt - min_leb_cnt > 8) { + /* And some extra space to allow writes while committing */ + log_lebs += 1; + min_leb_cnt += 1; + } + + max_buds = jnl_lebs - log_lebs; + if (max_buds < UBIFS_MIN_BUD_LEBS) + max_buds = UBIFS_MIN_BUD_LEBS; + + /* + * Orphan nodes are stored in a separate area. One node can store a lot + * of orphan inode numbers, but when new orphan comes we just add a new + * orphan node. At some point the nodes are consolidated into one + * orphan node. + */ + orph_lebs = UBIFS_MIN_ORPH_LEBS; +#ifdef CONFIG_UBIFS_FS_DEBUG + if (c->leb_cnt - min_leb_cnt > 1) + /* + * For debugging purposes it is better to have at least 2 + * orphan LEBs, because the orphan subsystem would need to do + * consolidations and would be stressed more. + */ + orph_lebs += 1; +#endif + + main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS - log_lebs; + main_lebs -= orph_lebs; + + lpt_first = UBIFS_LOG_LNUM + log_lebs; + c->lsave_cnt = DEFAULT_LSAVE_CNT; + c->max_leb_cnt = c->leb_cnt; + err = ubifs_create_dflt_lpt(c, &main_lebs, lpt_first, &lpt_lebs, + &big_lpt); + if (err) + return err; + + dbg_gen("LEB Properties Tree created (LEBs %d-%d)", lpt_first, + lpt_first + lpt_lebs - 1); + + main_first = c->leb_cnt - main_lebs; + + /* Create default superblock */ + tmp = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); + sup = kzalloc(tmp, GFP_KERNEL); + if (!sup) + return -ENOMEM; + + tmp64 = (uint64_t)max_buds * c->leb_size; + if (big_lpt) + sup_flags |= UBIFS_FLG_BIGLPT; + + sup->ch.node_type = UBIFS_SB_NODE; + sup->key_hash = UBIFS_KEY_HASH_R5; + sup->flags = cpu_to_le32(sup_flags); + sup->min_io_size = cpu_to_le32(c->min_io_size); + sup->leb_size = cpu_to_le32(c->leb_size); + sup->leb_cnt = cpu_to_le32(c->leb_cnt); + sup->max_leb_cnt = cpu_to_le32(c->max_leb_cnt); + sup->max_bud_bytes = cpu_to_le64(tmp64); + sup->log_lebs = cpu_to_le32(log_lebs); + sup->lpt_lebs = cpu_to_le32(lpt_lebs); + sup->orph_lebs = cpu_to_le32(orph_lebs); + sup->jhead_cnt = cpu_to_le32(DEFAULT_JHEADS_CNT); + sup->fanout = cpu_to_le32(DEFAULT_FANOUT); + sup->lsave_cnt = cpu_to_le32(c->lsave_cnt); + sup->fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION); + sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO); + sup->time_gran = cpu_to_le32(DEFAULT_TIME_GRAN); + + generate_random_uuid(sup->uuid); + + main_bytes = (uint64_t)main_lebs * c->leb_size; + tmp64 = main_bytes * DEFAULT_RP_PERCENT; + do_div(tmp64, 100); + if (tmp64 > DEFAULT_MAX_RP_SIZE) + tmp64 = DEFAULT_MAX_RP_SIZE; + sup->rp_size = cpu_to_le64(tmp64); + + err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM); + kfree(sup); + if (err) + return err; + + dbg_gen("default superblock created at LEB 0:0"); + + /* Create default master node */ + mst = kzalloc(c->mst_node_alsz, GFP_KERNEL); + if (!mst) + return -ENOMEM; + + mst->ch.node_type = UBIFS_MST_NODE; + mst->log_lnum = cpu_to_le32(UBIFS_LOG_LNUM); + mst->highest_inum = cpu_to_le64(UBIFS_FIRST_INO); + mst->cmt_no = 0; + mst->root_lnum = cpu_to_le32(main_first + DEFAULT_IDX_LEB); + mst->root_offs = 0; + tmp = ubifs_idx_node_sz(c, 1); + mst->root_len = cpu_to_le32(tmp); + mst->gc_lnum = cpu_to_le32(main_first + DEFAULT_GC_LEB); + mst->ihead_lnum = cpu_to_le32(main_first + DEFAULT_IDX_LEB); + mst->ihead_offs = cpu_to_le32(ALIGN(tmp, c->min_io_size)); + mst->index_size = cpu_to_le64(ALIGN(tmp, 8)); + mst->lpt_lnum = cpu_to_le32(c->lpt_lnum); + mst->lpt_offs = cpu_to_le32(c->lpt_offs); + mst->nhead_lnum = cpu_to_le32(c->nhead_lnum); + mst->nhead_offs = cpu_to_le32(c->nhead_offs); + mst->ltab_lnum = cpu_to_le32(c->ltab_lnum); + mst->ltab_offs = cpu_to_le32(c->ltab_offs); + mst->lsave_lnum = cpu_to_le32(c->lsave_lnum); + mst->lsave_offs = cpu_to_le32(c->lsave_offs); + mst->lscan_lnum = cpu_to_le32(main_first); + mst->empty_lebs = cpu_to_le32(main_lebs - 2); + mst->idx_lebs = cpu_to_le32(1); + mst->leb_cnt = cpu_to_le32(c->leb_cnt); + + /* Calculate lprops statistics */ + tmp64 = main_bytes; + tmp64 -= ALIGN(ubifs_idx_node_sz(c, 1), c->min_io_size); + tmp64 -= ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size); + mst->total_free = cpu_to_le64(tmp64); + + tmp64 = ALIGN(ubifs_idx_node_sz(c, 1), c->min_io_size); + ino_waste = ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size) - + UBIFS_INO_NODE_SZ; + tmp64 += ino_waste; + tmp64 -= ALIGN(ubifs_idx_node_sz(c, 1), 8); + mst->total_dirty = cpu_to_le64(tmp64); + + /* The indexing LEB does not contribute to dark space */ + tmp64 = (c->main_lebs - 1) * c->dark_wm; + mst->total_dark = cpu_to_le64(tmp64); + + mst->total_used = cpu_to_le64(UBIFS_INO_NODE_SZ); + + err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM, 0, + UBI_UNKNOWN); + if (err) { + kfree(mst); + return err; + } + err = ubifs_write_node(c, mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1, 0, + UBI_UNKNOWN); + kfree(mst); + if (err) + return err; + + dbg_gen("default master node created at LEB %d:0", UBIFS_MST_LNUM); + + /* Create the root indexing node */ + tmp = ubifs_idx_node_sz(c, 1); + idx = kzalloc(ALIGN(tmp, c->min_io_size), GFP_KERNEL); + if (!idx) + return -ENOMEM; + + c->key_fmt = UBIFS_SIMPLE_KEY_FMT; + c->key_hash = key_r5_hash; + + idx->ch.node_type = UBIFS_IDX_NODE; + idx->child_cnt = cpu_to_le16(1); + ino_key_init(c, &key, UBIFS_ROOT_INO); + br = ubifs_idx_branch(c, idx, 0); + key_write_idx(c, &key, &br->key); + br->lnum = cpu_to_le32(main_first + DEFAULT_DATA_LEB); + br->len = cpu_to_le32(UBIFS_INO_NODE_SZ); + err = ubifs_write_node(c, idx, tmp, main_first + DEFAULT_IDX_LEB, 0, + UBI_UNKNOWN); + kfree(idx); + if (err) + return err; + + dbg_gen("default root indexing node created LEB %d:0", + main_first + DEFAULT_IDX_LEB); + + /* Create default root inode */ + tmp = ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size); + ino = kzalloc(tmp, GFP_KERNEL); + if (!ino) + return -ENOMEM; + + ino_key_init_flash(c, &ino->key, UBIFS_ROOT_INO); + ino->ch.node_type = UBIFS_INO_NODE; + ino->creat_sqnum = cpu_to_le64(++c->max_sqnum); + ino->nlink = cpu_to_le32(2); + tmp = cpu_to_le64(CURRENT_TIME_SEC.tv_sec); + ino->atime_sec = tmp; + ino->ctime_sec = tmp; + ino->mtime_sec = tmp; + ino->atime_nsec = 0; + ino->ctime_nsec = 0; + ino->mtime_nsec = 0; + ino->mode = cpu_to_le32(S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO); + ino->size = cpu_to_le64(UBIFS_INO_NODE_SZ); + + /* Set compression enabled by default */ + ino->flags = cpu_to_le32(UBIFS_COMPR_FL); + + err = ubifs_write_node(c, ino, UBIFS_INO_NODE_SZ, + main_first + DEFAULT_DATA_LEB, 0, + UBI_UNKNOWN); + kfree(ino); + if (err) + return err; + + dbg_gen("root inode created at LEB %d:0", + main_first + DEFAULT_DATA_LEB); + + /* + * The first node in the log has to be the commit start node. This is + * always the case during normal file-system operation. Write a fake + * commit start node to the log. + */ + tmp = ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size); + cs = kzalloc(tmp, GFP_KERNEL); + if (!cs) + return -ENOMEM; + + cs->ch.node_type = UBIFS_CS_NODE; + err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, + 0, UBI_UNKNOWN); + kfree(cs); + + ubifs_msg("default file-system created"); + return 0; +} + +/** + * validate_sb - validate superblock node. + * @c: UBIFS file-system description object + * @sup: superblock node + * + * This function validates superblock node @sup. Since most of data was read + * from the superblock and stored in @c, the function validates fields in @c + * instead. Returns zero in case of success and %-EINVAL in case of validation + * failure. + */ +static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) +{ + long long max_bytes; + int err = 1, min_leb_cnt; + + if (!c->key_hash) { + err = 2; + goto failed; + } + + if (sup->key_fmt != UBIFS_SIMPLE_KEY_FMT) { + err = 3; + goto failed; + } + + if (le32_to_cpu(sup->min_io_size) != c->min_io_size) { + ubifs_err("min. I/O unit mismatch: %d in superblock, %d real", + le32_to_cpu(sup->min_io_size), c->min_io_size); + goto failed; + } + + if (le32_to_cpu(sup->leb_size) != c->leb_size) { + ubifs_err("LEB size mismatch: %d in superblock, %d real", + le32_to_cpu(sup->leb_size), c->leb_size); + goto failed; + } + + if (c->log_lebs < UBIFS_MIN_LOG_LEBS || + c->lpt_lebs < UBIFS_MIN_LPT_LEBS || + c->orph_lebs < UBIFS_MIN_ORPH_LEBS || + c->main_lebs < UBIFS_MIN_MAIN_LEBS) { + err = 4; + goto failed; + } + + /* + * Calculate minimum allowed amount of main area LEBs. This is very + * similar to %UBIFS_MIN_LEB_CNT, but we take into account real what we + * have just read from the superblock. + */ + min_leb_cnt = UBIFS_SB_LEBS + UBIFS_MST_LEBS + c->log_lebs; + min_leb_cnt += c->lpt_lebs + c->orph_lebs + c->jhead_cnt + 6; + + if (c->leb_cnt < min_leb_cnt || c->leb_cnt > c->vi.size) { + ubifs_err("bad LEB count: %d in superblock, %d on UBI volume, " + "%d minimum required", c->leb_cnt, c->vi.size, + min_leb_cnt); + goto failed; + } + + if (c->max_leb_cnt < c->leb_cnt) { + ubifs_err("max. LEB count %d less than LEB count %d", + c->max_leb_cnt, c->leb_cnt); + goto failed; + } + + if (c->main_lebs < UBIFS_MIN_MAIN_LEBS) { + err = 7; + goto failed; + } + + if (c->max_bud_bytes < (long long)c->leb_size * UBIFS_MIN_BUD_LEBS || + c->max_bud_bytes > (long long)c->leb_size * c->main_lebs) { + err = 8; + goto failed; + } + + if (c->jhead_cnt < NONDATA_JHEADS_CNT + 1 || + c->jhead_cnt > NONDATA_JHEADS_CNT + UBIFS_MAX_JHEADS) { + err = 9; + goto failed; + } + + if (c->fanout < UBIFS_MIN_FANOUT || + ubifs_idx_node_sz(c, c->fanout) > c->leb_size) { + err = 10; + goto failed; + } + + if (c->lsave_cnt < 0 || (c->lsave_cnt > DEFAULT_LSAVE_CNT && + c->lsave_cnt > c->max_leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS - + c->log_lebs - c->lpt_lebs - c->orph_lebs)) { + err = 11; + goto failed; + } + + if (UBIFS_SB_LEBS + UBIFS_MST_LEBS + c->log_lebs + c->lpt_lebs + + c->orph_lebs + c->main_lebs != c->leb_cnt) { + err = 12; + goto failed; + } + + if (c->default_compr < 0 || c->default_compr >= UBIFS_COMPR_TYPES_CNT) { + err = 13; + goto failed; + } + + max_bytes = c->main_lebs * (long long)c->leb_size; + if (c->rp_size < 0 || max_bytes < c->rp_size) { + err = 14; + goto failed; + } + + if (le32_to_cpu(sup->time_gran) > 1000000000 || + le32_to_cpu(sup->time_gran) < 1) { + err = 15; + goto failed; + } + + return 0; + +failed: + ubifs_err("bad superblock, error %d", err); + dbg_dump_node(c, sup); + return -EINVAL; +} + +/** + * ubifs_read_sb_node - read superblock node. + * @c: UBIFS file-system description object + * + * This function returns a pointer to the superblock node or a negative error + * code. + */ +struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c) +{ + struct ubifs_sb_node *sup; + int err; + + sup = kmalloc(ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size), GFP_NOFS); + if (!sup) + return ERR_PTR(-ENOMEM); + + err = ubifs_read_node(c, sup, UBIFS_SB_NODE, UBIFS_SB_NODE_SZ, + UBIFS_SB_LNUM, 0); + if (err) { + kfree(sup); + return ERR_PTR(err); + } + + return sup; +} + +/** + * ubifs_write_sb_node - write superblock node. + * @c: UBIFS file-system description object + * @sup: superblock node read with 'ubifs_read_sb_node()' + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) +{ + int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size); + + ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 1); + return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len, UBI_LONGTERM); +} + +/** + * ubifs_read_superblock - read superblock. + * @c: UBIFS file-system description object + * + * This function finds, reads and checks the superblock. If an empty UBI volume + * is being mounted, this function creates default superblock. Returns zero in + * case of success, and a negative error code in case of failure. + */ +int ubifs_read_superblock(struct ubifs_info *c) +{ + int err, sup_flags; + struct ubifs_sb_node *sup; + + if (c->empty) { + err = create_default_filesystem(c); + if (err) + return err; + } + + sup = ubifs_read_sb_node(c); + if (IS_ERR(sup)) + return PTR_ERR(sup); + + /* + * The software supports all previous versions but not future versions, + * due to the unavailability of time-travelling equipment. + */ + c->fmt_version = le32_to_cpu(sup->fmt_version); + if (c->fmt_version > UBIFS_FORMAT_VERSION) { + ubifs_err("on-flash format version is %d, but software only " + "supports up to version %d", c->fmt_version, + UBIFS_FORMAT_VERSION); + err = -EINVAL; + goto out; + } + + if (c->fmt_version < 3) { + ubifs_err("on-flash format version %d is not supported", + c->fmt_version); + err = -EINVAL; + goto out; + } + + switch (sup->key_hash) { + case UBIFS_KEY_HASH_R5: + c->key_hash = key_r5_hash; + c->key_hash_type = UBIFS_KEY_HASH_R5; + break; + + case UBIFS_KEY_HASH_TEST: + c->key_hash = key_test_hash; + c->key_hash_type = UBIFS_KEY_HASH_TEST; + break; + }; + + c->key_fmt = sup->key_fmt; + + switch (c->key_fmt) { + case UBIFS_SIMPLE_KEY_FMT: + c->key_len = UBIFS_SK_LEN; + break; + default: + ubifs_err("unsupported key format"); + err = -EINVAL; + goto out; + } + + c->leb_cnt = le32_to_cpu(sup->leb_cnt); + c->max_leb_cnt = le32_to_cpu(sup->max_leb_cnt); + c->max_bud_bytes = le64_to_cpu(sup->max_bud_bytes); + c->log_lebs = le32_to_cpu(sup->log_lebs); + c->lpt_lebs = le32_to_cpu(sup->lpt_lebs); + c->orph_lebs = le32_to_cpu(sup->orph_lebs); + c->jhead_cnt = le32_to_cpu(sup->jhead_cnt) + NONDATA_JHEADS_CNT; + c->fanout = le32_to_cpu(sup->fanout); + c->lsave_cnt = le32_to_cpu(sup->lsave_cnt); + c->default_compr = le16_to_cpu(sup->default_compr); + c->rp_size = le64_to_cpu(sup->rp_size); + c->rp_uid = le32_to_cpu(sup->rp_uid); + c->rp_gid = le32_to_cpu(sup->rp_gid); + sup_flags = le32_to_cpu(sup->flags); + + c->vfs_sb->s_time_gran = le32_to_cpu(sup->time_gran); + + memcpy(&c->uuid, &sup->uuid, 16); + + c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); + + /* Automatically increase file system size to the maximum size */ + c->old_leb_cnt = c->leb_cnt; + if (c->leb_cnt < c->vi.size && c->leb_cnt < c->max_leb_cnt) { + c->leb_cnt = min_t(int, c->max_leb_cnt, c->vi.size); + if (c->vfs_sb->s_flags & MS_RDONLY) + dbg_mnt("Auto resizing (ro) from %d LEBs to %d LEBs", + c->old_leb_cnt, c->leb_cnt); + else { + dbg_mnt("Auto resizing (sb) from %d LEBs to %d LEBs", + c->old_leb_cnt, c->leb_cnt); + sup->leb_cnt = cpu_to_le32(c->leb_cnt); + err = ubifs_write_sb_node(c, sup); + if (err) + goto out; + c->old_leb_cnt = c->leb_cnt; + } + } + + c->log_bytes = (long long)c->log_lebs * c->leb_size; + c->log_last = UBIFS_LOG_LNUM + c->log_lebs - 1; + c->lpt_first = UBIFS_LOG_LNUM + c->log_lebs; + c->lpt_last = c->lpt_first + c->lpt_lebs - 1; + c->orph_first = c->lpt_last + 1; + c->orph_last = c->orph_first + c->orph_lebs - 1; + c->main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS; + c->main_lebs -= c->log_lebs + c->lpt_lebs + c->orph_lebs; + c->main_first = c->leb_cnt - c->main_lebs; + c->report_rp_size = ubifs_reported_space(c, c->rp_size); + + err = validate_sb(c, sup); +out: + kfree(sup); + return err; +} diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c new file mode 100644 index 0000000..acf5c5f --- /dev/null +++ b/fs/ubifs/scan.c @@ -0,0 +1,362 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements the scan which is a general-purpose function for + * determining what nodes are in an eraseblock. The scan is used to replay the + * journal, to do garbage collection. for the TNC in-the-gaps method, and by + * debugging functions. + */ + +#include "ubifs.h" + +/** + * scan_padding_bytes - scan for padding bytes. + * @buf: buffer to scan + * @len: length of buffer + * + * This function returns the number of padding bytes on success and + * %SCANNED_GARBAGE on failure. + */ +static int scan_padding_bytes(void *buf, int len) +{ + int pad_len = 0, max_pad_len = min_t(int, UBIFS_PAD_NODE_SZ, len); + uint8_t *p = buf; + + dbg_scan("not a node"); + + while (pad_len < max_pad_len && *p++ == UBIFS_PADDING_BYTE) + pad_len += 1; + + if (!pad_len || (pad_len & 7)) + return SCANNED_GARBAGE; + + dbg_scan("%d padding bytes", pad_len); + + return pad_len; +} + +/** + * ubifs_scan_a_node - scan for a node or padding. + * @c: UBIFS file-system description object + * @buf: buffer to scan + * @len: length of buffer + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * @quiet: print no messages + * + * This function returns a scanning code to indicate what was scanned. + */ +int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, + int offs, int quiet) +{ + struct ubifs_ch *ch = buf; + uint32_t magic; + + magic = le32_to_cpu(ch->magic); + + if (magic == 0xFFFFFFFF) { + dbg_scan("hit empty space"); + return SCANNED_EMPTY_SPACE; + } + + if (magic != UBIFS_NODE_MAGIC) + return scan_padding_bytes(buf, len); + + if (len < UBIFS_CH_SZ) + return SCANNED_GARBAGE; + + dbg_scan("scanning %s", dbg_ntype(ch->node_type)); + + if (ubifs_check_node(c, buf, lnum, offs, quiet)) + return SCANNED_A_CORRUPT_NODE; + + if (ch->node_type == UBIFS_PAD_NODE) { + struct ubifs_pad_node *pad = buf; + int pad_len = le32_to_cpu(pad->pad_len); + int node_len = le32_to_cpu(ch->len); + + /* Validate the padding node */ + if (pad_len < 0 || + offs + node_len + pad_len > c->leb_size) { + if (!quiet) { + ubifs_err("bad pad node at LEB %d:%d", + lnum, offs); + dbg_dump_node(c, pad); + } + return SCANNED_A_BAD_PAD_NODE; + } + + /* Make the node pads to 8-byte boundary */ + if ((node_len + pad_len) & 7) { + if (!quiet) { + dbg_err("bad padding length %d - %d", + offs, offs + node_len + pad_len); + } + return SCANNED_A_BAD_PAD_NODE; + } + + dbg_scan("%d bytes padded, offset now %d", + pad_len, ALIGN(offs + node_len + pad_len, 8)); + + return node_len + pad_len; + } + + return SCANNED_A_NODE; +} + +/** + * ubifs_start_scan - create LEB scanning information at start of scan. + * @c: UBIFS file-system description object + * @lnum: logical eraseblock number + * @offs: offset to start at (usually zero) + * @sbuf: scan buffer (must be c->leb_size) + * + * This function returns %0 on success and a negative error code on failure. + */ +struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, + int offs, void *sbuf) +{ + struct ubifs_scan_leb *sleb; + int err; + + dbg_scan("scan LEB %d:%d", lnum, offs); + + sleb = kzalloc(sizeof(struct ubifs_scan_leb), GFP_NOFS); + if (!sleb) + return ERR_PTR(-ENOMEM); + + sleb->lnum = lnum; + INIT_LIST_HEAD(&sleb->nodes); + sleb->buf = sbuf; + + err = ubi_read(c->ubi, lnum, sbuf + offs, offs, c->leb_size - offs); + if (err && err != -EBADMSG) { + ubifs_err("cannot read %d bytes from LEB %d:%d," + " error %d", c->leb_size - offs, lnum, offs, err); + kfree(sleb); + return ERR_PTR(err); + } + + if (err == -EBADMSG) + sleb->ecc = 1; + + return sleb; +} + +/** + * ubifs_end_scan - update LEB scanning information at end of scan. + * @c: UBIFS file-system description object + * @sleb: scanning information + * @lnum: logical eraseblock number + * @offs: offset to start at (usually zero) + * + * This function returns %0 on success and a negative error code on failure. + */ +void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, + int lnum, int offs) +{ + lnum = lnum; + dbg_scan("stop scanning LEB %d at offset %d", lnum, offs); + ubifs_assert(offs % c->min_io_size == 0); + + sleb->endpt = ALIGN(offs, c->min_io_size); +} + +/** + * ubifs_add_snod - add a scanned node to LEB scanning information. + * @c: UBIFS file-system description object + * @sleb: scanning information + * @buf: buffer containing node + * @offs: offset of node on flash + * + * This function returns %0 on success and a negative error code on failure. + */ +int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, + void *buf, int offs) +{ + struct ubifs_ch *ch = buf; + struct ubifs_ino_node *ino = buf; + struct ubifs_scan_node *snod; + + snod = kzalloc(sizeof(struct ubifs_scan_node), GFP_NOFS); + if (!snod) + return -ENOMEM; + + snod->sqnum = le64_to_cpu(ch->sqnum); + snod->type = ch->node_type; + snod->offs = offs; + snod->len = le32_to_cpu(ch->len); + snod->node = buf; + + switch (ch->node_type) { + case UBIFS_INO_NODE: + case UBIFS_DENT_NODE: + case UBIFS_XENT_NODE: + case UBIFS_DATA_NODE: + case UBIFS_TRUN_NODE: + /* + * The key is in the same place in all keyed + * nodes. + */ + key_read(c, &ino->key, &snod->key); + break; + } + list_add_tail(&snod->list, &sleb->nodes); + sleb->nodes_cnt += 1; + return 0; +} + +/** + * ubifs_scanned_corruption - print information after UBIFS scanned corruption. + * @c: UBIFS file-system description object + * @lnum: LEB number of corruption + * @offs: offset of corruption + * @buf: buffer containing corruption + */ +void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, + void *buf) +{ + int len; + + ubifs_err("corrupted data at LEB %d:%d", lnum, offs); + if (dbg_failure_mode) + return; + len = c->leb_size - offs; + if (len > 4096) + len = 4096; + dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); +} + +/** + * ubifs_scan - scan a logical eraseblock. + * @c: UBIFS file-system description object + * @lnum: logical eraseblock number + * @offs: offset to start at (usually zero) + * @sbuf: scan buffer (must be c->leb_size) + * + * This function scans LEB number @lnum and returns complete information about + * its contents. Returns an error code in case of failure. + */ +struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, + int offs, void *sbuf) +{ + void *buf = sbuf + offs; + int err, len = c->leb_size - offs; + struct ubifs_scan_leb *sleb; + + sleb = ubifs_start_scan(c, lnum, offs, sbuf); + if (IS_ERR(sleb)) + return sleb; + + while (len >= 8) { + struct ubifs_ch *ch = buf; + int node_len, ret; + + dbg_scan("look at LEB %d:%d (%d bytes left)", + lnum, offs, len); + + cond_resched(); + + ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); + + if (ret > 0) { + /* Padding bytes or a valid padding node */ + offs += ret; + buf += ret; + len -= ret; + continue; + } + + if (ret == SCANNED_EMPTY_SPACE) + /* Empty space is checked later */ + break; + + switch (ret) { + case SCANNED_GARBAGE: + dbg_err("garbage"); + goto corrupted; + case SCANNED_A_NODE: + break; + case SCANNED_A_CORRUPT_NODE: + case SCANNED_A_BAD_PAD_NODE: + dbg_err("bad node"); + goto corrupted; + default: + dbg_err("unknown"); + goto corrupted; + } + + err = ubifs_add_snod(c, sleb, buf, offs); + if (err) + goto error; + + node_len = ALIGN(le32_to_cpu(ch->len), 8); + offs += node_len; + buf += node_len; + len -= node_len; + } + + if (offs % c->min_io_size) + goto corrupted; + + ubifs_end_scan(c, sleb, lnum, offs); + + for (; len > 4; offs += 4, buf = buf + 4, len -= 4) + if (*(uint32_t *)buf != 0xffffffff) + break; + for (; len; offs++, buf++, len--) + if (*(uint8_t *)buf != 0xff) { + ubifs_err("corrupt empty space at LEB %d:%d", + lnum, offs); + goto corrupted; + } + + return sleb; + +corrupted: + ubifs_scanned_corruption(c, lnum, offs, buf); + err = -EUCLEAN; +error: + ubifs_err("LEB %d scanning failed", lnum); + ubifs_scan_destroy(sleb); + return ERR_PTR(err); +} + +/** + * ubifs_scan_destroy - destroy LEB scanning information. + * @sleb: scanning information to free + */ +void ubifs_scan_destroy(struct ubifs_scan_leb *sleb) +{ + struct ubifs_scan_node *node; + struct list_head *head; + + head = &sleb->nodes; + while (!list_empty(head)) { + node = list_entry(head->next, struct ubifs_scan_node, list); + list_del(&node->list); + kfree(node); + } + kfree(sleb); +} diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c new file mode 100644 index 0000000..f248533 --- /dev/null +++ b/fs/ubifs/shrinker.c @@ -0,0 +1,322 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements UBIFS shrinker which evicts clean znodes from the TNC + * tree when Linux VM needs more RAM. + * + * We do not implement any LRU lists to find oldest znodes to free because it + * would add additional overhead to the file system fast paths. So the shrinker + * just walks the TNC tree when searching for znodes to free. + * + * If the root of a TNC sub-tree is clean and old enough, then the children are + * also clean and old enough. So the shrinker walks the TNC in level order and + * dumps entire sub-trees. + * + * The age of znodes is just the time-stamp when they were last looked at. + * The current shrinker first tries to evict old znodes, then young ones. + * + * Since the shrinker is global, it has to protect against races with FS + * un-mounts, which is done by the 'ubifs_infos_lock' and 'c->umount_mutex'. + */ + +#include "ubifs.h" + +/* List of all UBIFS file-system instances */ +LIST_HEAD(ubifs_infos); + +/* + * We number each shrinker run and record the number on the ubifs_info structure + * so that we can easily work out which ubifs_info structures have already been + * done by the current run. + */ +static unsigned int shrinker_run_no; + +/* Protects 'ubifs_infos' list */ +DEFINE_SPINLOCK(ubifs_infos_lock); + +/* Global clean znode counter (for all mounted UBIFS instances) */ +atomic_long_t ubifs_clean_zn_cnt; + +/** + * shrink_tnc - shrink TNC tree. + * @c: UBIFS file-system description object + * @nr: number of znodes to free + * @age: the age of znodes to free + * @contention: if any contention, this is set to %1 + * + * This function traverses TNC tree and frees clean znodes. It does not free + * clean znodes which younger then @age. Returns number of freed znodes. + */ +static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention) +{ + int total_freed = 0; + struct ubifs_znode *znode, *zprev; + int time = get_seconds(); + + ubifs_assert(mutex_is_locked(&c->umount_mutex)); + ubifs_assert(mutex_is_locked(&c->tnc_mutex)); + + if (!c->zroot.znode || atomic_long_read(&c->clean_zn_cnt) == 0) + return 0; + + /* + * Traverse the TNC tree in levelorder manner, so that it is possible + * to destroy large sub-trees. Indeed, if a znode is old, then all its + * children are older or of the same age. + * + * Note, we are holding 'c->tnc_mutex', so we do not have to lock the + * 'c->space_lock' when _reading_ 'c->clean_zn_cnt', because it is + * changed only when the 'c->tnc_mutex' is held. + */ + zprev = NULL; + znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); + while (znode && total_freed < nr && + atomic_long_read(&c->clean_zn_cnt) > 0) { + int freed; + + /* + * If the znode is clean, but it is in the 'c->cnext' list, this + * means that this znode has just been written to flash as a + * part of commit and was marked clean. They will be removed + * from the list at end commit. We cannot change the list, + * because it is not protected by any mutex (design decision to + * make commit really independent and parallel to main I/O). So + * we just skip these znodes. + * + * Note, the 'clean_zn_cnt' counters are not updated until + * after the commit, so the UBIFS shrinker does not report + * the znodes which are in the 'c->cnext' list as freeable. + * + * Also note, if the root of a sub-tree is not in 'c->cnext', + * then the whole sub-tree is not in 'c->cnext' as well, so it + * is safe to dump whole sub-tree. + */ + + if (znode->cnext) { + /* + * Very soon these znodes will be removed from the list + * and become freeable. + */ + *contention = 1; + } else if (!ubifs_zn_dirty(znode) && + abs(time - znode->time) >= age) { + if (znode->parent) + znode->parent->zbranch[znode->iip].znode = NULL; + else + c->zroot.znode = NULL; + + freed = ubifs_destroy_tnc_subtree(znode); + atomic_long_sub(freed, &ubifs_clean_zn_cnt); + atomic_long_sub(freed, &c->clean_zn_cnt); + ubifs_assert(atomic_long_read(&c->clean_zn_cnt) >= 0); + total_freed += freed; + znode = zprev; + } + + if (unlikely(!c->zroot.znode)) + break; + + zprev = znode; + znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); + cond_resched(); + } + + return total_freed; +} + +/** + * shrink_tnc_trees - shrink UBIFS TNC trees. + * @nr: number of znodes to free + * @age: the age of znodes to free + * @contention: if any contention, this is set to %1 + * + * This function walks the list of mounted UBIFS file-systems and frees clean + * znodes which are older then @age, until at least @nr znodes are freed. + * Returns the number of freed znodes. + */ +static int shrink_tnc_trees(int nr, int age, int *contention) +{ + struct ubifs_info *c; + struct list_head *p; + unsigned int run_no; + int freed = 0; + + spin_lock(&ubifs_infos_lock); + do { + run_no = ++shrinker_run_no; + } while (run_no == 0); + /* Iterate over all mounted UBIFS file-systems and try to shrink them */ + p = ubifs_infos.next; + while (p != &ubifs_infos) { + c = list_entry(p, struct ubifs_info, infos_list); + /* + * We move the ones we do to the end of the list, so we stop + * when we see one we have already done. + */ + if (c->shrinker_run_no == run_no) + break; + if (!mutex_trylock(&c->umount_mutex)) { + /* Some un-mount is in progress, try next FS */ + *contention = 1; + p = p->next; + continue; + } + /* + * We're holding 'c->umount_mutex', so the file-system won't go + * away. + */ + if (!mutex_trylock(&c->tnc_mutex)) { + mutex_unlock(&c->umount_mutex); + *contention = 1; + p = p->next; + continue; + } + spin_unlock(&ubifs_infos_lock); + /* + * OK, now we have TNC locked, the file-system cannot go away - + * it is safe to reap the cache. + */ + c->shrinker_run_no = run_no; + freed += shrink_tnc(c, nr, age, contention); + mutex_unlock(&c->tnc_mutex); + spin_lock(&ubifs_infos_lock); + /* Get the next list element before we move this one */ + p = p->next; + /* + * Move this one to the end of the list to provide some + * fairness. + */ + list_del(&c->infos_list); + list_add_tail(&c->infos_list, &ubifs_infos); + mutex_unlock(&c->umount_mutex); + if (freed >= nr) + break; + } + spin_unlock(&ubifs_infos_lock); + return freed; +} + +/** + * kick_a_thread - kick a background thread to start commit. + * + * This function kicks a background thread to start background commit. Returns + * %-1 if a thread was kicked or there is another reason to assume the memory + * will soon be freed or become freeable. If there are no dirty znodes, returns + * %0. + */ +static int kick_a_thread(void) +{ + int i; + struct ubifs_info *c; + + /* + * Iterate over all mounted UBIFS file-systems and find out if there is + * already an ongoing commit operation there. If no, then iterate for + * the second time and initiate background commit. + */ + spin_lock(&ubifs_infos_lock); + for (i = 0; i < 2; i++) { + list_for_each_entry(c, &ubifs_infos, infos_list) { + long dirty_zn_cnt; + + if (!mutex_trylock(&c->umount_mutex)) { + /* + * Some un-mount is in progress, it will + * certainly free memory, so just return. + */ + spin_unlock(&ubifs_infos_lock); + return -1; + } + + dirty_zn_cnt = atomic_long_read(&c->dirty_zn_cnt); + + if (!dirty_zn_cnt || c->cmt_state == COMMIT_BROKEN || + c->ro_media) { + mutex_unlock(&c->umount_mutex); + continue; + } + + if (c->cmt_state != COMMIT_RESTING) { + spin_unlock(&ubifs_infos_lock); + mutex_unlock(&c->umount_mutex); + return -1; + } + + if (i == 1) { + list_del(&c->infos_list); + list_add_tail(&c->infos_list, &ubifs_infos); + spin_unlock(&ubifs_infos_lock); + + ubifs_request_bg_commit(c); + mutex_unlock(&c->umount_mutex); + return -1; + } + mutex_unlock(&c->umount_mutex); + } + } + spin_unlock(&ubifs_infos_lock); + + return 0; +} + +int ubifs_shrinker(int nr, gfp_t gfp_mask) +{ + int freed, contention = 0; + long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt); + + if (nr == 0) + return clean_zn_cnt; + + if (!clean_zn_cnt) { + /* + * No clean znodes, nothing to reap. All we can do in this case + * is to kick background threads to start commit, which will + * probably make clean znodes which, in turn, will be freeable. + * And we return -1 which means will make VM call us again + * later. + */ + dbg_tnc("no clean znodes, kick a thread"); + return kick_a_thread(); + } + + freed = shrink_tnc_trees(nr, OLD_ZNODE_AGE, &contention); + if (freed >= nr) + goto out; + + dbg_tnc("not enough old znodes, try to free young ones"); + freed += shrink_tnc_trees(nr - freed, YOUNG_ZNODE_AGE, &contention); + if (freed >= nr) + goto out; + + dbg_tnc("not enough young znodes, free all"); + freed += shrink_tnc_trees(nr - freed, 0, &contention); + + if (!freed && contention) { + dbg_tnc("freed nothing, but contention"); + return -1; + } + +out: + dbg_tnc("%d znodes were freed, requested %d", freed, nr); + return freed; +} diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c new file mode 100644 index 0000000..00eb9c6 --- /dev/null +++ b/fs/ubifs/super.c @@ -0,0 +1,1951 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements UBIFS initialization and VFS superblock operations. Some + * initialization stuff which is rather large and complex is placed at + * corresponding subsystems, but most of it is here. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ubifs.h" + +/* Slab cache for UBIFS inodes */ +struct kmem_cache *ubifs_inode_slab; + +/* UBIFS TNC shrinker description */ +static struct shrinker ubifs_shrinker_info = { + .shrink = ubifs_shrinker, + .seeks = DEFAULT_SEEKS, +}; + +/** + * validate_inode - validate inode. + * @c: UBIFS file-system description object + * @inode: the inode to validate + * + * This is a helper function for 'ubifs_iget()' which validates various fields + * of a newly built inode to make sure they contain sane values and prevent + * possible vulnerabilities. Returns zero if the inode is all right and + * a non-zero error code if not. + */ +static int validate_inode(struct ubifs_info *c, const struct inode *inode) +{ + int err; + const struct ubifs_inode *ui = ubifs_inode(inode); + + if (inode->i_size > c->max_inode_sz) { + ubifs_err("inode is too large (%lld)", + (long long)inode->i_size); + return 1; + } + + if (ui->compr_type < 0 || ui->compr_type >= UBIFS_COMPR_TYPES_CNT) { + ubifs_err("unknown compression type %d", ui->compr_type); + return 2; + } + + if (ui->xattr_names + ui->xattr_cnt > XATTR_LIST_MAX) + return 3; + + if (ui->data_len < 0 || ui->data_len > UBIFS_MAX_INO_DATA) + return 4; + + if (ui->xattr && (inode->i_mode & S_IFMT) != S_IFREG) + return 5; + + if (!ubifs_compr_present(ui->compr_type)) { + ubifs_warn("inode %lu uses '%s' compression, but it was not " + "compiled in", inode->i_ino, + ubifs_compr_name(ui->compr_type)); + } + + err = dbg_check_dir_size(c, inode); + return err; +} + +struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) +{ + int err; + union ubifs_key key; + struct ubifs_ino_node *ino; + struct ubifs_info *c = sb->s_fs_info; + struct inode *inode; + struct ubifs_inode *ui; + + dbg_gen("inode %lu", inum); + + inode = iget_locked(sb, inum); + if (!inode) + return ERR_PTR(-ENOMEM); + if (!(inode->i_state & I_NEW)) + return inode; + ui = ubifs_inode(inode); + + ino = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS); + if (!ino) { + err = -ENOMEM; + goto out; + } + + ino_key_init(c, &key, inode->i_ino); + + err = ubifs_tnc_lookup(c, &key, ino); + if (err) + goto out_ino; + + inode->i_flags |= (S_NOCMTIME | S_NOATIME); + inode->i_nlink = le32_to_cpu(ino->nlink); + inode->i_uid = le32_to_cpu(ino->uid); + inode->i_gid = le32_to_cpu(ino->gid); + inode->i_atime.tv_sec = (int64_t)le64_to_cpu(ino->atime_sec); + inode->i_atime.tv_nsec = le32_to_cpu(ino->atime_nsec); + inode->i_mtime.tv_sec = (int64_t)le64_to_cpu(ino->mtime_sec); + inode->i_mtime.tv_nsec = le32_to_cpu(ino->mtime_nsec); + inode->i_ctime.tv_sec = (int64_t)le64_to_cpu(ino->ctime_sec); + inode->i_ctime.tv_nsec = le32_to_cpu(ino->ctime_nsec); + inode->i_mode = le32_to_cpu(ino->mode); + inode->i_size = le64_to_cpu(ino->size); + + ui->data_len = le32_to_cpu(ino->data_len); + ui->flags = le32_to_cpu(ino->flags); + ui->compr_type = le16_to_cpu(ino->compr_type); + ui->creat_sqnum = le64_to_cpu(ino->creat_sqnum); + ui->xattr_cnt = le32_to_cpu(ino->xattr_cnt); + ui->xattr_size = le32_to_cpu(ino->xattr_size); + ui->xattr_names = le32_to_cpu(ino->xattr_names); + ui->synced_i_size = ui->ui_size = inode->i_size; + + ui->xattr = (ui->flags & UBIFS_XATTR_FL) ? 1 : 0; + + err = validate_inode(c, inode); + if (err) + goto out_invalid; + + /* Disable readahead */ + inode->i_mapping->backing_dev_info = &c->bdi; + + switch (inode->i_mode & S_IFMT) { + case S_IFREG: + inode->i_mapping->a_ops = &ubifs_file_address_operations; + inode->i_op = &ubifs_file_inode_operations; + inode->i_fop = &ubifs_file_operations; + if (ui->xattr) { + ui->data = kmalloc(ui->data_len + 1, GFP_NOFS); + if (!ui->data) { + err = -ENOMEM; + goto out_ino; + } + memcpy(ui->data, ino->data, ui->data_len); + ((char *)ui->data)[ui->data_len] = '\0'; + } else if (ui->data_len != 0) { + err = 10; + goto out_invalid; + } + break; + case S_IFDIR: + inode->i_op = &ubifs_dir_inode_operations; + inode->i_fop = &ubifs_dir_operations; + if (ui->data_len != 0) { + err = 11; + goto out_invalid; + } + break; + case S_IFLNK: + inode->i_op = &ubifs_symlink_inode_operations; + if (ui->data_len <= 0 || ui->data_len > UBIFS_MAX_INO_DATA) { + err = 12; + goto out_invalid; + } + ui->data = kmalloc(ui->data_len + 1, GFP_NOFS); + if (!ui->data) { + err = -ENOMEM; + goto out_ino; + } + memcpy(ui->data, ino->data, ui->data_len); + ((char *)ui->data)[ui->data_len] = '\0'; + break; + case S_IFBLK: + case S_IFCHR: + { + dev_t rdev; + union ubifs_dev_desc *dev; + + ui->data = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); + if (!ui->data) { + err = -ENOMEM; + goto out_ino; + } + + dev = (union ubifs_dev_desc *)ino->data; + if (ui->data_len == sizeof(dev->new)) + rdev = new_decode_dev(le32_to_cpu(dev->new)); + else if (ui->data_len == sizeof(dev->huge)) + rdev = huge_decode_dev(le64_to_cpu(dev->huge)); + else { + err = 13; + goto out_invalid; + } + memcpy(ui->data, ino->data, ui->data_len); + inode->i_op = &ubifs_file_inode_operations; + init_special_inode(inode, inode->i_mode, rdev); + break; + } + case S_IFSOCK: + case S_IFIFO: + inode->i_op = &ubifs_file_inode_operations; + init_special_inode(inode, inode->i_mode, 0); + if (ui->data_len != 0) { + err = 14; + goto out_invalid; + } + break; + default: + err = 15; + goto out_invalid; + } + + kfree(ino); + ubifs_set_inode_flags(inode); + unlock_new_inode(inode); + return inode; + +out_invalid: + ubifs_err("inode %lu validation failed, error %d", inode->i_ino, err); + dbg_dump_node(c, ino); + dbg_dump_inode(c, inode); + err = -EINVAL; +out_ino: + kfree(ino); +out: + ubifs_err("failed to read inode %lu, error %d", inode->i_ino, err); + iget_failed(inode); + return ERR_PTR(err); +} + +static struct inode *ubifs_alloc_inode(struct super_block *sb) +{ + struct ubifs_inode *ui; + + ui = kmem_cache_alloc(ubifs_inode_slab, GFP_NOFS); + if (!ui) + return NULL; + + memset((void *)ui + sizeof(struct inode), 0, + sizeof(struct ubifs_inode) - sizeof(struct inode)); + mutex_init(&ui->ui_mutex); + spin_lock_init(&ui->ui_lock); + return &ui->vfs_inode; +}; + +static void ubifs_destroy_inode(struct inode *inode) +{ + struct ubifs_inode *ui = ubifs_inode(inode); + + kfree(ui->data); + kmem_cache_free(ubifs_inode_slab, inode); +} + +/* + * Note, Linux write-back code calls this without 'i_mutex'. + */ +static int ubifs_write_inode(struct inode *inode, int wait) +{ + int err; + struct ubifs_info *c = inode->i_sb->s_fs_info; + struct ubifs_inode *ui = ubifs_inode(inode); + + ubifs_assert(!ui->xattr); + if (is_bad_inode(inode)) + return 0; + + mutex_lock(&ui->ui_mutex); + /* + * Due to races between write-back forced by budgeting + * (see 'sync_some_inodes()') and pdflush write-back, the inode may + * have already been synchronized, do not do this again. This might + * also happen if it was synchronized in an VFS operation, e.g. + * 'ubifs_link()'. + */ + if (!ui->dirty) { + mutex_unlock(&ui->ui_mutex); + return 0; + } + + dbg_gen("inode %lu", inode->i_ino); + err = ubifs_jnl_write_inode(c, inode, 0); + if (err) + ubifs_err("can't write inode %lu, error %d", inode->i_ino, err); + + ui->dirty = 0; + mutex_unlock(&ui->ui_mutex); + ubifs_release_dirty_inode_budget(c, ui); + return err; +} + +static void ubifs_delete_inode(struct inode *inode) +{ + int err; + struct ubifs_info *c = inode->i_sb->s_fs_info; + + if (ubifs_inode(inode)->xattr) + /* + * Extended attribute inode deletions are fully handled in + * 'ubifs_removexattr()'. These inodes are special and have + * limited usage, so there is nothing to do here. + */ + goto out; + + dbg_gen("inode %lu", inode->i_ino); + ubifs_assert(!atomic_read(&inode->i_count)); + ubifs_assert(inode->i_nlink == 0); + + truncate_inode_pages(&inode->i_data, 0); + if (is_bad_inode(inode)) + goto out; + + ubifs_inode(inode)->ui_size = inode->i_size = 0; + err = ubifs_jnl_write_inode(c, inode, 1); + if (err) + /* + * Worst case we have a lost orphan inode wasting space, so a + * simple error message is ok here. + */ + ubifs_err("can't write inode %lu, error %d", inode->i_ino, err); +out: + clear_inode(inode); +} + +static void ubifs_dirty_inode(struct inode *inode) +{ + struct ubifs_inode *ui = ubifs_inode(inode); + + ubifs_assert(mutex_is_locked(&ui->ui_mutex)); + if (!ui->dirty) { + ui->dirty = 1; + dbg_gen("inode %lu", inode->i_ino); + } +} + +static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct ubifs_info *c = dentry->d_sb->s_fs_info; + unsigned long long free; + + free = ubifs_budg_get_free_space(c); + dbg_gen("free space %lld bytes (%lld blocks)", + free, free >> UBIFS_BLOCK_SHIFT); + + buf->f_type = UBIFS_SUPER_MAGIC; + buf->f_bsize = UBIFS_BLOCK_SIZE; + buf->f_blocks = c->block_cnt; + buf->f_bfree = free >> UBIFS_BLOCK_SHIFT; + if (free > c->report_rp_size) + buf->f_bavail = (free - c->report_rp_size) >> UBIFS_BLOCK_SHIFT; + else + buf->f_bavail = 0; + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_namelen = UBIFS_MAX_NLEN; + + return 0; +} + +static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt) +{ + struct ubifs_info *c = mnt->mnt_sb->s_fs_info; + + if (c->mount_opts.unmount_mode == 2) + seq_printf(s, ",fast_unmount"); + else if (c->mount_opts.unmount_mode == 1) + seq_printf(s, ",norm_unmount"); + + return 0; +} + +static int ubifs_sync_fs(struct super_block *sb, int wait) +{ + struct ubifs_info *c = sb->s_fs_info; + int i, ret = 0, err; + + if (c->jheads) + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err && !ret) + ret = err; + } + /* + * We ought to call sync for c->ubi but it does not have one. If it had + * it would in turn call mtd->sync, however mtd operations are + * synchronous anyway, so we don't lose any sleep here. + */ + return ret; +} + +/** + * init_constants_early - initialize UBIFS constants. + * @c: UBIFS file-system description object + * + * This function initialize UBIFS constants which do not need the superblock to + * be read. It also checks that the UBI volume satisfies basic UBIFS + * requirements. Returns zero in case of success and a negative error code in + * case of failure. + */ +static int init_constants_early(struct ubifs_info *c) +{ + if (c->vi.corrupted) { + ubifs_warn("UBI volume is corrupted - read-only mode"); + c->ro_media = 1; + } + + if (c->di.ro_mode) { + ubifs_msg("read-only UBI device"); + c->ro_media = 1; + } + + if (c->vi.vol_type == UBI_STATIC_VOLUME) { + ubifs_msg("static UBI volume - read-only mode"); + c->ro_media = 1; + } + + c->leb_cnt = c->vi.size; + c->leb_size = c->vi.usable_leb_size; + c->half_leb_size = c->leb_size / 2; + c->min_io_size = c->di.min_io_size; + c->min_io_shift = fls(c->min_io_size) - 1; + + if (c->leb_size < UBIFS_MIN_LEB_SZ) { + ubifs_err("too small LEBs (%d bytes), min. is %d bytes", + c->leb_size, UBIFS_MIN_LEB_SZ); + return -EINVAL; + } + + if (c->leb_cnt < UBIFS_MIN_LEB_CNT) { + ubifs_err("too few LEBs (%d), min. is %d", + c->leb_cnt, UBIFS_MIN_LEB_CNT); + return -EINVAL; + } + + if (!is_power_of_2(c->min_io_size)) { + ubifs_err("bad min. I/O size %d", c->min_io_size); + return -EINVAL; + } + + /* + * UBIFS aligns all node to 8-byte boundary, so to make function in + * io.c simpler, assume minimum I/O unit size to be 8 bytes if it is + * less than 8. + */ + if (c->min_io_size < 8) { + c->min_io_size = 8; + c->min_io_shift = 3; + } + + c->ref_node_alsz = ALIGN(UBIFS_REF_NODE_SZ, c->min_io_size); + c->mst_node_alsz = ALIGN(UBIFS_MST_NODE_SZ, c->min_io_size); + + /* + * Initialize node length ranges which are mostly needed for node + * length validation. + */ + c->ranges[UBIFS_PAD_NODE].len = UBIFS_PAD_NODE_SZ; + c->ranges[UBIFS_SB_NODE].len = UBIFS_SB_NODE_SZ; + c->ranges[UBIFS_MST_NODE].len = UBIFS_MST_NODE_SZ; + c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ; + c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ; + c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ; + + c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ; + c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ; + c->ranges[UBIFS_ORPH_NODE].min_len = + UBIFS_ORPH_NODE_SZ + sizeof(__le64); + c->ranges[UBIFS_ORPH_NODE].max_len = c->leb_size; + c->ranges[UBIFS_DENT_NODE].min_len = UBIFS_DENT_NODE_SZ; + c->ranges[UBIFS_DENT_NODE].max_len = UBIFS_MAX_DENT_NODE_SZ; + c->ranges[UBIFS_XENT_NODE].min_len = UBIFS_XENT_NODE_SZ; + c->ranges[UBIFS_XENT_NODE].max_len = UBIFS_MAX_XENT_NODE_SZ; + c->ranges[UBIFS_DATA_NODE].min_len = UBIFS_DATA_NODE_SZ; + c->ranges[UBIFS_DATA_NODE].max_len = UBIFS_MAX_DATA_NODE_SZ; + /* + * Minimum indexing node size is amended later when superblock is + * read and the key length is known. + */ + c->ranges[UBIFS_IDX_NODE].min_len = UBIFS_IDX_NODE_SZ + UBIFS_BRANCH_SZ; + /* + * Maximum indexing node size is amended later when superblock is + * read and the fanout is known. + */ + c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX; + + /* + * 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); + + return 0; +} + +/** + * bud_wbuf_callback - bud LEB write-buffer synchronization call-back. + * @c: UBIFS file-system description object + * @lnum: LEB the write-buffer was synchronized to + * @free: how many free bytes left in this LEB + * @pad: how many bytes were padded + * + * This is a callback function which is called by the I/O unit when the + * write-buffer is synchronized. We need this to correctly maintain space + * accounting in bud logical eraseblocks. This function returns zero in case of + * success and a negative error code in case of failure. + * + * This function actually belongs to the journal, but we keep it here because + * we want to keep it static. + */ +static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad) +{ + return ubifs_update_one_lp(c, lnum, free, pad, 0, 0); +} + +/* + * init_constants_late - initialize UBIFS constants. + * @c: UBIFS file-system description object + * + * This is a helper function which initializes various UBIFS constants after + * the superblock has been read. It also checks various UBIFS parameters and + * makes sure they are all right. Returns zero in case of success and a + * negative error code in case of failure. + */ +static int init_constants_late(struct ubifs_info *c) +{ + int tmp, err; + uint64_t tmp64; + + c->main_bytes = (long long)c->main_lebs * c->leb_size; + c->max_znode_sz = sizeof(struct ubifs_znode) + + c->fanout * sizeof(struct ubifs_zbranch); + + tmp = ubifs_idx_node_sz(c, 1); + c->ranges[UBIFS_IDX_NODE].min_len = tmp; + c->min_idx_node_sz = ALIGN(tmp, 8); + + tmp = ubifs_idx_node_sz(c, c->fanout); + c->ranges[UBIFS_IDX_NODE].max_len = tmp; + c->max_idx_node_sz = ALIGN(tmp, 8); + + /* Make sure LEB size is large enough to fit full commit */ + tmp = UBIFS_CS_NODE_SZ + UBIFS_REF_NODE_SZ * c->jhead_cnt; + tmp = ALIGN(tmp, c->min_io_size); + if (tmp > c->leb_size) { + dbg_err("too small LEB size %d, at least %d needed", + c->leb_size, tmp); + return -EINVAL; + } + + /* + * Make sure that the log is large enough to fit reference nodes for + * all buds plus one reserved LEB. + */ + tmp64 = c->max_bud_bytes; + tmp = do_div(tmp64, c->leb_size); + c->max_bud_cnt = tmp64 + !!tmp; + tmp = (c->ref_node_alsz * c->max_bud_cnt + c->leb_size - 1); + tmp /= c->leb_size; + tmp += 1; + if (c->log_lebs < tmp) { + dbg_err("too small log %d LEBs, required min. %d LEBs", + c->log_lebs, tmp); + return -EINVAL; + } + + /* + * When budgeting we assume worst-case scenarios when the pages are not + * be compressed and direntries are of the maximum size. + * + * Note, data, which may be stored in inodes is budgeted separately, so + * it is not included into 'c->inode_budget'. + */ + c->page_budget = UBIFS_MAX_DATA_NODE_SZ * UBIFS_BLOCKS_PER_PAGE; + c->inode_budget = UBIFS_INO_NODE_SZ; + c->dent_budget = UBIFS_MAX_DENT_NODE_SZ; + + /* + * When the amount of flash space used by buds becomes + * 'c->max_bud_bytes', UBIFS just blocks all writers and starts commit. + * The writers are unblocked when the commit is finished. To avoid + * writers to be blocked UBIFS initiates background commit in advance, + * when number of bud bytes becomes above the limit defined below. + */ + c->bg_bud_bytes = (c->max_bud_bytes * 13) >> 4; + + /* + * Ensure minimum journal size. All the bytes in the journal heads are + * considered to be used, when calculating the current journal usage. + * Consequently, if the journal is too small, UBIFS will treat it as + * always full. + */ + tmp64 = (uint64_t)(c->jhead_cnt + 1) * c->leb_size + 1; + if (c->bg_bud_bytes < tmp64) + c->bg_bud_bytes = tmp64; + if (c->max_bud_bytes < tmp64 + c->leb_size) + c->max_bud_bytes = tmp64 + c->leb_size; + + err = ubifs_calc_lpt_geom(c); + if (err) + return err; + + c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); + + /* + * Calculate total amount of FS blocks. This number is not used + * internally because it does not make much sense for UBIFS, but it is + * necessary to report something for the 'statfs()' call. + * + * Subtract the LEB reserved for GC and the LEB which is reserved for + * deletions. + * + * Review 'ubifs_calc_available()' if changing this calculation. + */ + tmp64 = c->main_lebs - 2; + tmp64 *= (uint64_t)c->leb_size - c->dark_wm; + tmp64 = ubifs_reported_space(c, tmp64); + c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT; + + return 0; +} + +/** + * take_gc_lnum - reserve GC LEB. + * @c: UBIFS file-system description object + * + * 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) +{ + int err; + + if (c->gc_lnum == -1) { + ubifs_err("no LEB for GC"); + 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); + return err; +} + +/** + * alloc_wbufs - allocate write-buffers. + * @c: UBIFS file-system description object + * + * This helper function allocates and initializes UBIFS write-buffers. Returns + * zero in case of success and %-ENOMEM in case of failure. + */ +static int alloc_wbufs(struct ubifs_info *c) +{ + int i, err; + + c->jheads = kzalloc(c->jhead_cnt * sizeof(struct ubifs_jhead), + GFP_KERNEL); + if (!c->jheads) + return -ENOMEM; + + /* Initialize journal heads */ + for (i = 0; i < c->jhead_cnt; i++) { + INIT_LIST_HEAD(&c->jheads[i].buds_list); + err = ubifs_wbuf_init(c, &c->jheads[i].wbuf); + if (err) + return err; + + c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; + c->jheads[i].wbuf.jhead = i; + } + + c->jheads[BASEHD].wbuf.dtype = UBI_SHORTTERM; + /* + * Garbage Collector head likely contains long-term data and + * does not need to be synchronized by timer. + */ + c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; + c->jheads[GCHD].wbuf.timeout = 0; + + return 0; +} + +/** + * free_wbufs - free write-buffers. + * @c: UBIFS file-system description object + */ +static void free_wbufs(struct ubifs_info *c) +{ + int i; + + if (c->jheads) { + for (i = 0; i < c->jhead_cnt; i++) { + kfree(c->jheads[i].wbuf.buf); + kfree(c->jheads[i].wbuf.inodes); + } + kfree(c->jheads); + c->jheads = NULL; + } +} + +/** + * free_orphans - free orphans. + * @c: UBIFS file-system description object + */ +static void free_orphans(struct ubifs_info *c) +{ + struct ubifs_orphan *orph; + + while (c->orph_dnext) { + orph = c->orph_dnext; + c->orph_dnext = orph->dnext; + list_del(&orph->list); + kfree(orph); + } + + while (!list_empty(&c->orph_list)) { + orph = list_entry(c->orph_list.next, struct ubifs_orphan, list); + list_del(&orph->list); + kfree(orph); + dbg_err("orphan list not empty at unmount"); + } + + vfree(c->orph_buf); + c->orph_buf = NULL; +} + +/** + * free_buds - free per-bud objects. + * @c: UBIFS file-system description object + */ +static void free_buds(struct ubifs_info *c) +{ + struct rb_node *this = c->buds.rb_node; + struct ubifs_bud *bud; + + while (this) { + if (this->rb_left) + this = this->rb_left; + else if (this->rb_right) + this = this->rb_right; + else { + bud = rb_entry(this, struct ubifs_bud, rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &bud->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + kfree(bud); + } + } +} + +/** + * check_volume_empty - check if the UBI volume is empty. + * @c: UBIFS file-system description object + * + * This function checks if the UBIFS volume is empty by looking if its LEBs are + * mapped or not. The result of checking is stored in the @c->empty variable. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +static int check_volume_empty(struct ubifs_info *c) +{ + int lnum, err; + + c->empty = 1; + for (lnum = 0; lnum < c->leb_cnt; lnum++) { + err = ubi_is_mapped(c->ubi, lnum); + if (unlikely(err < 0)) + return err; + if (err == 1) { + c->empty = 0; + break; + } + + cond_resched(); + } + + return 0; +} + +/* + * UBIFS mount options. + * + * Opt_fast_unmount: do not run a journal commit before un-mounting + * Opt_norm_unmount: run a journal commit before un-mounting + * Opt_err: just end of array marker + */ +enum { + Opt_fast_unmount, + Opt_norm_unmount, + Opt_err, +}; + +static match_table_t tokens = { + {Opt_fast_unmount, "fast_unmount"}, + {Opt_norm_unmount, "norm_unmount"}, + {Opt_err, NULL}, +}; + +/** + * ubifs_parse_options - parse mount parameters. + * @c: UBIFS file-system description object + * @options: parameters to parse + * @is_remount: non-zero if this is FS re-mount + * + * This function parses UBIFS mount options and returns zero in case success + * and a negative error code in case of failure. + */ +static int ubifs_parse_options(struct ubifs_info *c, char *options, + int is_remount) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + + if (!options) + return 0; + + while ((p = strsep(&options, ","))) { + int token; + + if (!*p) + continue; + + token = match_token(p, tokens, args); + switch (token) { + 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; + default: + ubifs_err("unrecognized mount option \"%s\" " + "or missing value", p); + return -EINVAL; + } + } + + return 0; +} + +/** + * destroy_journal - destroy journal data structures. + * @c: UBIFS file-system description object + * + * This function destroys journal data structures including those that may have + * been created by recovery functions. + */ +static void destroy_journal(struct ubifs_info *c) +{ + while (!list_empty(&c->unclean_leb_list)) { + struct ubifs_unclean_leb *ucleb; + + ucleb = list_entry(c->unclean_leb_list.next, + struct ubifs_unclean_leb, list); + list_del(&ucleb->list); + kfree(ucleb); + } + while (!list_empty(&c->old_buds)) { + struct ubifs_bud *bud; + + bud = list_entry(c->old_buds.next, struct ubifs_bud, list); + list_del(&bud->list); + kfree(bud); + } + ubifs_destroy_idx_gc(c); + ubifs_destroy_size_tree(c); + ubifs_tnc_close(c); + free_buds(c); +} + +/** + * mount_ubifs - mount UBIFS file-system. + * @c: UBIFS file-system description object + * + * This function mounts UBIFS file system. Returns zero in case of success and + * a negative error code in case of failure. + * + * Note, the function does not de-allocate resources it it fails half way + * through, and the caller has to do this instead. + */ +static int mount_ubifs(struct ubifs_info *c) +{ + struct super_block *sb = c->vfs_sb; + int err, mounted_read_only = (sb->s_flags & MS_RDONLY); + long long x; + size_t sz; + + err = init_constants_early(c); + if (err) + return err; + +#ifdef CONFIG_UBIFS_FS_DEBUG + c->dbg_buf = vmalloc(c->leb_size); + if (!c->dbg_buf) + return -ENOMEM; +#endif + + err = check_volume_empty(c); + if (err) + goto out_free; + + if (c->empty && (mounted_read_only || c->ro_media)) { + /* + * This UBI volume is empty, and read-only, or the file system + * is mounted read-only - we cannot format it. + */ + ubifs_err("can't format empty UBI volume: read-only %s", + c->ro_media ? "UBI volume" : "mount"); + err = -EROFS; + goto out_free; + } + + if (c->ro_media && !mounted_read_only) { + ubifs_err("cannot mount read-write - read-only media"); + err = -EROFS; + goto out_free; + } + + /* + * The requirement for the buffer is that it should fit indexing B-tree + * height amount of integers. We assume the height if the TNC tree will + * never exceed 64. + */ + err = -ENOMEM; + c->bottom_up_buf = kmalloc(BOTTOM_UP_HEIGHT * sizeof(int), GFP_KERNEL); + if (!c->bottom_up_buf) + goto out_free; + + c->sbuf = vmalloc(c->leb_size); + if (!c->sbuf) + goto out_free; + + if (!mounted_read_only) { + c->ileb_buf = vmalloc(c->leb_size); + if (!c->ileb_buf) + goto out_free; + } + + err = ubifs_read_superblock(c); + if (err) + goto out_free; + + /* + * Make sure the compressor which is set as the default on in the + * superblock was actually compiled in. + */ + if (!ubifs_compr_present(c->default_compr)) { + ubifs_warn("'%s' compressor is set by superblock, but not " + "compiled in", ubifs_compr_name(c->default_compr)); + c->default_compr = UBIFS_COMPR_NONE; + } + + dbg_failure_mode_registration(c); + + err = init_constants_late(c); + if (err) + goto out_dereg; + + sz = ALIGN(c->max_idx_node_sz, c->min_io_size); + sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size); + c->cbuf = kmalloc(sz, GFP_NOFS); + if (!c->cbuf) { + err = -ENOMEM; + goto out_dereg; + } + + if (!mounted_read_only) { + err = alloc_wbufs(c); + if (err) + goto out_cbuf; + + /* Create background thread */ + sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, + c->vi.vol_id); + c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); + if (!c->bgt) + c->bgt = ERR_PTR(-EINVAL); + if (IS_ERR(c->bgt)) { + err = PTR_ERR(c->bgt); + c->bgt = NULL; + ubifs_err("cannot spawn \"%s\", error %d", + c->bgt_name, err); + goto out_wbufs; + } + wake_up_process(c->bgt); + } + + err = ubifs_read_master(c); + if (err) + goto out_master; + + if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { + ubifs_msg("recovery needed"); + c->need_recovery = 1; + if (!mounted_read_only) { + err = ubifs_recover_inl_heads(c, c->sbuf); + if (err) + goto out_master; + } + } else if (!mounted_read_only) { + /* + * Set the "dirty" flag so that if we reboot uncleanly we + * will notice this immediately on the next mount. + */ + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); + err = ubifs_write_master(c); + if (err) + goto out_master; + } + + err = ubifs_lpt_init(c, 1, !mounted_read_only); + if (err) + goto out_lpt; + + err = dbg_check_idx_size(c, c->old_idx_sz); + if (err) + goto out_lpt; + + err = ubifs_replay_journal(c); + if (err) + goto out_journal; + + err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); + if (err) + goto out_orphans; + + if (!mounted_read_only) { + int lnum; + + /* Check for enough free space */ + if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { + ubifs_err("insufficient available space"); + err = -EINVAL; + goto out_orphans; + } + + /* Check for enough log space */ + lnum = c->lhead_lnum + 1; + if (lnum >= UBIFS_LOG_LNUM + c->log_lebs) + lnum = UBIFS_LOG_LNUM; + if (lnum == c->ltail_lnum) { + err = ubifs_consolidate_log(c); + if (err) + goto out_orphans; + } + + if (c->need_recovery) { + err = ubifs_recover_size(c); + if (err) + goto out_orphans; + err = ubifs_rcvry_gc_commit(c); + } else + err = take_gc_lnum(c); + if (err) + goto out_orphans; + + err = dbg_check_lprops(c); + if (err) + goto out_orphans; + } else if (c->need_recovery) { + err = ubifs_recover_size(c); + if (err) + goto out_orphans; + } + + spin_lock(&ubifs_infos_lock); + list_add_tail(&c->infos_list, &ubifs_infos); + spin_unlock(&ubifs_infos_lock); + + if (c->need_recovery) { + if (mounted_read_only) + ubifs_msg("recovery deferred"); + else { + c->need_recovery = 0; + ubifs_msg("recovery completed"); + } + } + + err = dbg_check_filesystem(c); + if (err) + goto out_infos; + + ubifs_msg("mounted UBI device %d, volume %d", c->vi.ubi_num, + c->vi.vol_id); + if (mounted_read_only) + ubifs_msg("mounted read-only"); + x = (long long)c->main_lebs * c->leb_size; + ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)", + x, x >> 10, x >> 20, c->main_lebs); + x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; + ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)", + x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); + ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); + ubifs_msg("media format %d, latest format %d", + c->fmt_version, UBIFS_FORMAT_VERSION); + + dbg_msg("compiled on: " __DATE__ " at " __TIME__); + dbg_msg("min. I/O unit size: %d bytes", c->min_io_size); + dbg_msg("LEB size: %d bytes (%d KiB)", + c->leb_size, c->leb_size / 1024); + dbg_msg("data journal heads: %d", + c->jhead_cnt - NONDATA_JHEADS_CNT); + dbg_msg("UUID: %02X%02X%02X%02X-%02X%02X" + "-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + c->uuid[0], c->uuid[1], c->uuid[2], c->uuid[3], + 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); + dbg_msg("LPT area LEBs: %d (%d - %d)", + c->lpt_lebs, c->lpt_first, c->lpt_last); + dbg_msg("orphan area LEBs: %d (%d - %d)", + c->orph_lebs, c->orph_first, c->orph_last); + dbg_msg("main area LEBs: %d (%d - %d)", + c->main_lebs, c->main_first, c->leb_cnt - 1); + dbg_msg("index LEBs: %d", c->lst.idx_lebs); + dbg_msg("total index bytes: %lld (%lld KiB, %lld MiB)", + c->old_idx_sz, c->old_idx_sz >> 10, c->old_idx_sz >> 20); + dbg_msg("key hash type: %d", c->key_hash_type); + dbg_msg("tree fanout: %d", c->fanout); + dbg_msg("reserved GC LEB: %d", c->gc_lnum); + dbg_msg("first main LEB: %d", c->main_first); + dbg_msg("dead watermark: %d", c->dead_wm); + dbg_msg("dark watermark: %d", c->dark_wm); + x = (long long)c->main_lebs * c->dark_wm; + dbg_msg("max. dark space: %lld (%lld KiB, %lld MiB)", + x, x >> 10, x >> 20); + dbg_msg("maximum bud bytes: %lld (%lld KiB, %lld MiB)", + c->max_bud_bytes, c->max_bud_bytes >> 10, + c->max_bud_bytes >> 20); + dbg_msg("BG commit bud bytes: %lld (%lld KiB, %lld MiB)", + c->bg_bud_bytes, c->bg_bud_bytes >> 10, + c->bg_bud_bytes >> 20); + dbg_msg("current bud bytes %lld (%lld KiB, %lld MiB)", + c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20); + dbg_msg("max. seq. number: %llu", c->max_sqnum); + dbg_msg("commit number: %llu", c->cmt_no); + + return 0; + +out_infos: + spin_lock(&ubifs_infos_lock); + list_del(&c->infos_list); + spin_unlock(&ubifs_infos_lock); +out_orphans: + free_orphans(c); +out_journal: + destroy_journal(c); +out_lpt: + ubifs_lpt_free(c, 0); +out_master: + kfree(c->mst_node); + kfree(c->rcvrd_mst_node); + if (c->bgt) + kthread_stop(c->bgt); +out_wbufs: + free_wbufs(c); +out_cbuf: + kfree(c->cbuf); +out_dereg: + dbg_failure_mode_deregistration(c); +out_free: + vfree(c->ileb_buf); + vfree(c->sbuf); + kfree(c->bottom_up_buf); + UBIFS_DBG(vfree(c->dbg_buf)); + return err; +} + +/** + * ubifs_umount - un-mount UBIFS file-system. + * @c: UBIFS file-system description object + * + * Note, this function is called to free allocated resourced when un-mounting, + * as well as free resources when an error occurred while we were half way + * through mounting (error path cleanup function). So it has to make sure the + * resource was actually allocated before freeing it. + */ +static void ubifs_umount(struct ubifs_info *c) +{ + dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num, + c->vi.vol_id); + + spin_lock(&ubifs_infos_lock); + list_del(&c->infos_list); + spin_unlock(&ubifs_infos_lock); + + if (c->bgt) + kthread_stop(c->bgt); + + destroy_journal(c); + free_wbufs(c); + free_orphans(c); + ubifs_lpt_free(c, 0); + + kfree(c->cbuf); + kfree(c->rcvrd_mst_node); + kfree(c->mst_node); + vfree(c->sbuf); + kfree(c->bottom_up_buf); + UBIFS_DBG(vfree(c->dbg_buf)); + vfree(c->ileb_buf); + dbg_failure_mode_deregistration(c); +} + +/** + * ubifs_remount_rw - re-mount in read-write mode. + * @c: UBIFS file-system description object + * + * UBIFS avoids allocating many unnecessary resources when mounted in read-only + * mode. This function allocates the needed resources and re-mounts UBIFS in + * read-write mode. + */ +static int ubifs_remount_rw(struct ubifs_info *c) +{ + int err, lnum; + + if (c->ro_media) + return -EINVAL; + + mutex_lock(&c->umount_mutex); + c->remounting_rw = 1; + + /* Check for enough free space */ + if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { + ubifs_err("insufficient available space"); + err = -EINVAL; + goto out; + } + + if (c->old_leb_cnt != c->leb_cnt) { + struct ubifs_sb_node *sup; + + sup = ubifs_read_sb_node(c); + if (IS_ERR(sup)) { + err = PTR_ERR(sup); + goto out; + } + sup->leb_cnt = cpu_to_le32(c->leb_cnt); + err = ubifs_write_sb_node(c, sup); + if (err) + goto out; + } + + if (c->need_recovery) { + ubifs_msg("completing deferred recovery"); + err = ubifs_write_rcvrd_mst_node(c); + if (err) + goto out; + err = ubifs_recover_size(c); + if (err) + goto out; + err = ubifs_clean_lebs(c, c->sbuf); + if (err) + goto out; + err = ubifs_recover_inl_heads(c, c->sbuf); + if (err) + goto out; + } + + if (!(c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY))) { + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); + err = ubifs_write_master(c); + if (err) + goto out; + } + + c->ileb_buf = vmalloc(c->leb_size); + if (!c->ileb_buf) { + err = -ENOMEM; + goto out; + } + + err = ubifs_lpt_init(c, 0, 1); + if (err) + goto out; + + err = alloc_wbufs(c); + if (err) + goto out; + + ubifs_create_buds_lists(c); + + /* Create background thread */ + c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); + if (!c->bgt) + c->bgt = ERR_PTR(-EINVAL); + if (IS_ERR(c->bgt)) { + err = PTR_ERR(c->bgt); + c->bgt = NULL; + ubifs_err("cannot spawn \"%s\", error %d", + c->bgt_name, err); + return err; + } + wake_up_process(c->bgt); + + c->orph_buf = vmalloc(c->leb_size); + if (!c->orph_buf) + return -ENOMEM; + + /* Check for enough log space */ + lnum = c->lhead_lnum + 1; + if (lnum >= UBIFS_LOG_LNUM + c->log_lebs) + lnum = UBIFS_LOG_LNUM; + if (lnum == c->ltail_lnum) { + err = ubifs_consolidate_log(c); + if (err) + goto out; + } + + if (c->need_recovery) + err = ubifs_rcvry_gc_commit(c); + else + err = take_gc_lnum(c); + if (err) + goto out; + + if (c->need_recovery) { + c->need_recovery = 0; + ubifs_msg("deferred recovery completed"); + } + + dbg_gen("re-mounted read-write"); + c->vfs_sb->s_flags &= ~MS_RDONLY; + c->remounting_rw = 0; + mutex_unlock(&c->umount_mutex); + return 0; + +out: + vfree(c->orph_buf); + c->orph_buf = NULL; + if (c->bgt) { + kthread_stop(c->bgt); + c->bgt = NULL; + } + free_wbufs(c); + vfree(c->ileb_buf); + c->ileb_buf = NULL; + ubifs_lpt_free(c, 1); + c->remounting_rw = 0; + mutex_unlock(&c->umount_mutex); + return err; +} + +/** + * commit_on_unmount - commit the journal when un-mounting. + * @c: UBIFS file-system description object + * + * This function is called during un-mounting and it commits the journal unless + * the "fast unmount" mode is enabled. It also avoids committing the journal if + * it contains too few data. + * + * Sometimes recovery requires the journal to be committed at least once, and + * this function takes care about this. + */ +static void commit_on_unmount(struct ubifs_info *c) +{ + if (!c->fast_unmount) { + long long bud_bytes; + + spin_lock(&c->buds_lock); + bud_bytes = c->bud_bytes; + spin_unlock(&c->buds_lock); + if (bud_bytes > c->leb_size) + ubifs_run_commit(c); + } +} + +/** + * ubifs_remount_ro - re-mount in read-only mode. + * @c: UBIFS file-system description object + * + * 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); + commit_on_unmount(c); + + mutex_lock(&c->umount_mutex); + if (c->bgt) { + kthread_stop(c->bgt); + c->bgt = NULL; + } + + for (i = 0; i < c->jhead_cnt; i++) { + ubifs_wbuf_sync(&c->jheads[i].wbuf); + del_timer_sync(&c->jheads[i].wbuf.timer); + } + + 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); + mutex_unlock(&c->umount_mutex); +} + +static void ubifs_put_super(struct super_block *sb) +{ + int i; + struct ubifs_info *c = sb->s_fs_info; + + ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num, + c->vi.vol_id); + /* + * The following asserts are only valid if there has not been a failure + * of the media. For example, there will be dirty inodes if we failed + * to write them back because of I/O errors. + */ + ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); + ubifs_assert(c->budg_idx_growth == 0); + ubifs_assert(c->budg_data_growth == 0); + + /* + * The 'c->umount_lock' prevents races between UBIFS memory shrinker + * and file system un-mount. Namely, it prevents the shrinker from + * picking this superblock for shrinking - it will be just skipped if + * the mutex is locked. + */ + mutex_lock(&c->umount_mutex); + if (!(c->vfs_sb->s_flags & MS_RDONLY)) { + /* + * First of all kill the background thread to make sure it does + * not interfere with un-mounting and freeing resources. + */ + if (c->bgt) { + kthread_stop(c->bgt); + c->bgt = NULL; + } + + /* Synchronize write-buffers */ + if (c->jheads) + for (i = 0; i < c->jhead_cnt; i++) { + ubifs_wbuf_sync(&c->jheads[i].wbuf); + del_timer_sync(&c->jheads[i].wbuf.timer); + } + + /* + * On fatal errors c->ro_media is set to 1, in which case we do + * not write the master node. + */ + if (!c->ro_media) { + /* + * We are being cleanly unmounted which means the + * orphans were killed - indicate this in the master + * node. Also save the reserved GC LEB number. + */ + int err; + + 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) + /* + * Recovery will attempt to fix the master area + * next mount, so we just print a message and + * continue to unmount normally. + */ + ubifs_err("failed to write master node, " + "error %d", err); + } + } + + ubifs_umount(c); + bdi_destroy(&c->bdi); + ubi_close_volume(c->ubi); + mutex_unlock(&c->umount_mutex); + kfree(c); +} + +static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + int err; + struct ubifs_info *c = sb->s_fs_info; + + dbg_gen("old flags %#lx, new flags %#x", sb->s_flags, *flags); + + err = ubifs_parse_options(c, data, 1); + if (err) { + ubifs_err("invalid or unknown remount parameter"); + return err; + } + if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { + err = ubifs_remount_rw(c); + if (err) + return err; + } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) + ubifs_remount_ro(c); + + return 0; +} + +struct super_operations ubifs_super_operations = { + .alloc_inode = ubifs_alloc_inode, + .destroy_inode = ubifs_destroy_inode, + .put_super = ubifs_put_super, + .write_inode = ubifs_write_inode, + .delete_inode = ubifs_delete_inode, + .statfs = ubifs_statfs, + .dirty_inode = ubifs_dirty_inode, + .remount_fs = ubifs_remount_fs, + .show_options = ubifs_show_options, + .sync_fs = ubifs_sync_fs, +}; + +/** + * open_ubi - parse UBI device name string and open the UBI device. + * @name: UBI volume name + * @mode: UBI volume open mode + * + * There are several ways to specify UBI volumes when mounting UBIFS: + * o ubiX_Y - UBI device number X, volume Y; + * o ubiY - UBI device number 0, volume Y; + * o ubiX:NAME - mount UBI device X, volume with name NAME; + * o ubi:NAME - mount UBI device 0, volume with name NAME. + * + * Alternative '!' separator may be used instead of ':' (because some shells + * like busybox may interpret ':' as an NFS host name separator). This function + * returns ubi volume object in case of success and a negative error code in + * case of failure. + */ +static struct ubi_volume_desc *open_ubi(const char *name, int mode) +{ + int dev, vol; + char *endptr; + + if (name[0] != 'u' || name[1] != 'b' || name[2] != 'i') + return ERR_PTR(-EINVAL); + + /* ubi:NAME method */ + if ((name[3] == ':' || name[3] == '!') && name[4] != '\0') + return ubi_open_volume_nm(0, name + 4, mode); + + if (!isdigit(name[3])) + return ERR_PTR(-EINVAL); + + dev = simple_strtoul(name + 3, &endptr, 0); + + /* ubiY method */ + if (*endptr == '\0') + return ubi_open_volume(0, dev, mode); + + /* ubiX_Y method */ + if (*endptr == '_' && isdigit(endptr[1])) { + vol = simple_strtoul(endptr + 1, &endptr, 0); + if (*endptr != '\0') + return ERR_PTR(-EINVAL); + return ubi_open_volume(dev, vol, mode); + } + + /* ubiX:NAME method */ + if ((*endptr == ':' || *endptr == '!') && endptr[1] != '\0') + return ubi_open_volume_nm(dev, ++endptr, mode); + + return ERR_PTR(-EINVAL); +} + +static int ubifs_fill_super(struct super_block *sb, void *data, int silent) +{ + struct ubi_volume_desc *ubi = sb->s_fs_info; + struct ubifs_info *c; + struct inode *root; + int err; + + c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); + if (!c) + return -ENOMEM; + + spin_lock_init(&c->cnt_lock); + spin_lock_init(&c->cs_lock); + spin_lock_init(&c->buds_lock); + spin_lock_init(&c->space_lock); + spin_lock_init(&c->orphan_lock); + init_rwsem(&c->commit_sem); + mutex_init(&c->lp_mutex); + mutex_init(&c->tnc_mutex); + mutex_init(&c->log_mutex); + mutex_init(&c->mst_mutex); + mutex_init(&c->umount_mutex); + init_waitqueue_head(&c->cmt_wq); + c->buds = RB_ROOT; + c->old_idx = RB_ROOT; + c->size_tree = RB_ROOT; + c->orph_tree = RB_ROOT; + INIT_LIST_HEAD(&c->infos_list); + INIT_LIST_HEAD(&c->idx_gc); + INIT_LIST_HEAD(&c->replay_list); + INIT_LIST_HEAD(&c->replay_buds); + INIT_LIST_HEAD(&c->uncat_list); + INIT_LIST_HEAD(&c->empty_list); + INIT_LIST_HEAD(&c->freeable_list); + INIT_LIST_HEAD(&c->frdi_idx_list); + INIT_LIST_HEAD(&c->unclean_leb_list); + INIT_LIST_HEAD(&c->old_buds); + INIT_LIST_HEAD(&c->orph_list); + INIT_LIST_HEAD(&c->orph_new); + + c->highest_inum = UBIFS_FIRST_INO; + get_random_bytes(&c->vfs_gen, sizeof(int)); + c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; + + ubi_get_volume_info(ubi, &c->vi); + ubi_get_device_info(c->vi.ubi_num, &c->di); + + /* Re-open the UBI device in read-write mode */ + c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READWRITE); + if (IS_ERR(c->ubi)) { + err = PTR_ERR(c->ubi); + goto out_free; + } + + /* + * UBIFS provids 'backing_dev_info' in order to disable readahead. For + * UBIFS, I/O is not deferred, it is done immediately in readpage, + * which means the user would have to wait not just for their own I/O + * but the readahead I/O as well i.e. completely pointless. + * + * Read-ahead will be disabled because @c->bdi.ra_pages is 0. + */ + c->bdi.capabilities = BDI_CAP_MAP_COPY; + c->bdi.unplug_io_fn = default_unplug_io_fn; + err = bdi_init(&c->bdi); + if (err) + goto out_close; + + err = ubifs_parse_options(c, data, 0); + if (err) + goto out_bdi; + + c->vfs_sb = sb; + + sb->s_fs_info = c; + sb->s_magic = UBIFS_SUPER_MAGIC; + sb->s_blocksize = UBIFS_BLOCK_SIZE; + sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT; + sb->s_dev = c->vi.cdev; + sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c); + if (c->max_inode_sz > MAX_LFS_FILESIZE) + sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; + sb->s_op = &ubifs_super_operations; + + mutex_lock(&c->umount_mutex); + err = mount_ubifs(c); + if (err) { + ubifs_assert(err < 0); + goto out_unlock; + } + + /* Read the root inode */ + root = ubifs_iget(sb, UBIFS_ROOT_INO); + if (IS_ERR(root)) { + err = PTR_ERR(root); + goto out_umount; + } + + sb->s_root = d_alloc_root(root); + if (!sb->s_root) + goto out_iput; + + mutex_unlock(&c->umount_mutex); + + return 0; + +out_iput: + iput(root); +out_umount: + ubifs_umount(c); +out_unlock: + mutex_unlock(&c->umount_mutex); +out_bdi: + bdi_destroy(&c->bdi); +out_close: + ubi_close_volume(c->ubi); +out_free: + kfree(c); + return err; +} + +static int sb_test(struct super_block *sb, void *data) +{ + dev_t *dev = data; + + return sb->s_dev == *dev; +} + +static int sb_set(struct super_block *sb, void *data) +{ + dev_t *dev = data; + + sb->s_dev = *dev; + return 0; +} + +static int ubifs_get_sb(struct file_system_type *fs_type, int flags, + const char *name, void *data, struct vfsmount *mnt) +{ + struct ubi_volume_desc *ubi; + struct ubi_volume_info vi; + struct super_block *sb; + int err; + + dbg_gen("name %s, flags %#x", name, flags); + + /* + * Get UBI device number and volume ID. Mount it read-only so far + * because this might be a new mount point, and UBI allows only one + * read-write user at a time. + */ + ubi = open_ubi(name, UBI_READONLY); + if (IS_ERR(ubi)) { + ubifs_err("cannot open \"%s\", error %d", + name, (int)PTR_ERR(ubi)); + return PTR_ERR(ubi); + } + ubi_get_volume_info(ubi, &vi); + + dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); + + sb = sget(fs_type, &sb_test, &sb_set, &vi.cdev); + if (IS_ERR(sb)) { + err = PTR_ERR(sb); + goto out_close; + } + + if (sb->s_root) { + /* A new mount point for already mounted UBIFS */ + dbg_gen("this ubi volume is already mounted"); + if ((flags ^ sb->s_flags) & MS_RDONLY) { + err = -EBUSY; + goto out_deact; + } + } else { + sb->s_flags = flags; + /* + * Pass 'ubi' to 'fill_super()' in sb->s_fs_info where it is + * replaced by 'c'. + */ + sb->s_fs_info = ubi; + err = ubifs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); + if (err) + goto out_deact; + /* We do not support atime */ + sb->s_flags |= MS_ACTIVE | MS_NOATIME; + } + + /* 'fill_super()' opens ubi again so we must close it here */ + ubi_close_volume(ubi); + + return simple_set_mnt(mnt, sb); + +out_deact: + up_write(&sb->s_umount); + deactivate_super(sb); +out_close: + ubi_close_volume(ubi); + return err; +} + +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 && !(sb->s_flags & MS_RDONLY)) + commit_on_unmount(c); + /* The un-mount routine is actually done in put_super() */ + generic_shutdown_super(sb); +} + +static struct file_system_type ubifs_fs_type = { + .name = "ubifs", + .owner = THIS_MODULE, + .get_sb = ubifs_get_sb, + .kill_sb = ubifs_kill_sb +}; + +/* + * Inode slab cache constructor. + */ +static void inode_slab_ctor(struct kmem_cache *cachep, void *obj) +{ + struct ubifs_inode *ui = obj; + inode_init_once(&ui->vfs_inode); +} + +static int __init ubifs_init(void) +{ + int err; + + BUILD_BUG_ON(sizeof(struct ubifs_ch) != 24); + + /* Make sure node sizes are 8-byte aligned */ + BUILD_BUG_ON(UBIFS_CH_SZ & 7); + BUILD_BUG_ON(UBIFS_INO_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_DENT_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_XENT_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_DATA_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_TRUN_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_SB_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_MST_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_REF_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_CS_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_ORPH_NODE_SZ & 7); + + BUILD_BUG_ON(UBIFS_MAX_DENT_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_MAX_XENT_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_MAX_DATA_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_MAX_INO_NODE_SZ & 7); + BUILD_BUG_ON(UBIFS_MAX_NODE_SZ & 7); + BUILD_BUG_ON(MIN_WRITE_SZ & 7); + + /* Check min. node size */ + BUILD_BUG_ON(UBIFS_INO_NODE_SZ < MIN_WRITE_SZ); + BUILD_BUG_ON(UBIFS_DENT_NODE_SZ < MIN_WRITE_SZ); + BUILD_BUG_ON(UBIFS_XENT_NODE_SZ < MIN_WRITE_SZ); + BUILD_BUG_ON(UBIFS_TRUN_NODE_SZ < MIN_WRITE_SZ); + + BUILD_BUG_ON(UBIFS_MAX_DENT_NODE_SZ > UBIFS_MAX_NODE_SZ); + BUILD_BUG_ON(UBIFS_MAX_XENT_NODE_SZ > UBIFS_MAX_NODE_SZ); + BUILD_BUG_ON(UBIFS_MAX_DATA_NODE_SZ > UBIFS_MAX_NODE_SZ); + BUILD_BUG_ON(UBIFS_MAX_INO_NODE_SZ > UBIFS_MAX_NODE_SZ); + + /* Defined node sizes */ + BUILD_BUG_ON(UBIFS_SB_NODE_SZ != 4096); + BUILD_BUG_ON(UBIFS_MST_NODE_SZ != 512); + BUILD_BUG_ON(UBIFS_INO_NODE_SZ != 160); + BUILD_BUG_ON(UBIFS_REF_NODE_SZ != 64); + + /* + * We require that PAGE_CACHE_SIZE is greater-than-or-equal-to + * UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2. + */ + if (PAGE_CACHE_SIZE < UBIFS_BLOCK_SIZE) { + ubifs_err("VFS page cache size is %u bytes, but UBIFS requires" + " at least 4096 bytes", + (unsigned int)PAGE_CACHE_SIZE); + return -EINVAL; + } + + err = register_filesystem(&ubifs_fs_type); + if (err) { + ubifs_err("cannot register file system, error %d", err); + return err; + } + + err = -ENOMEM; + ubifs_inode_slab = kmem_cache_create("ubifs_inode_slab", + sizeof(struct ubifs_inode), 0, + SLAB_MEM_SPREAD | SLAB_RECLAIM_ACCOUNT, + &inode_slab_ctor); + if (!ubifs_inode_slab) + goto out_reg; + + register_shrinker(&ubifs_shrinker_info); + + err = ubifs_compressors_init(); + if (err) + goto out_compr; + + return 0; + +out_compr: + unregister_shrinker(&ubifs_shrinker_info); + kmem_cache_destroy(ubifs_inode_slab); +out_reg: + unregister_filesystem(&ubifs_fs_type); + return err; +} +/* late_initcall to let compressors initialize first */ +late_initcall(ubifs_init); + +static void __exit ubifs_exit(void) +{ + ubifs_assert(list_empty(&ubifs_infos)); + ubifs_assert(atomic_long_read(&ubifs_clean_zn_cnt) == 0); + + ubifs_compressors_exit(); + unregister_shrinker(&ubifs_shrinker_info); + kmem_cache_destroy(ubifs_inode_slab); + unregister_filesystem(&ubifs_fs_type); +} +module_exit(ubifs_exit); + +MODULE_LICENSE("GPL"); +MODULE_VERSION(__stringify(UBIFS_VERSION)); +MODULE_AUTHOR("Artem Bityutskiy, Adrian Hunter"); +MODULE_DESCRIPTION("UBIFS - UBI File System"); diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c new file mode 100644 index 0000000..e909f4a --- /dev/null +++ b/fs/ubifs/tnc.c @@ -0,0 +1,2956 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements TNC (Tree Node Cache) which caches indexing nodes of + * the UBIFS B-tree. + * + * At the moment the locking rules of the TNC tree are quite simple and + * straightforward. We just have a mutex and lock it when we traverse the + * tree. If a znode is not in memory, we read it from flash while still having + * the mutex locked. + */ + +#include +#include "ubifs.h" + +/* + * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions. + * @NAME_LESS: name corresponding to the first argument is less than second + * @NAME_MATCHES: names match + * @NAME_GREATER: name corresponding to the second argument is greater than + * first + * @NOT_ON_MEDIA: node referred by zbranch does not exist on the media + * + * These constants were introduce to improve readability. + */ +enum { + NAME_LESS = 0, + NAME_MATCHES = 1, + NAME_GREATER = 2, + NOT_ON_MEDIA = 3, +}; + +/** + * insert_old_idx - record an index node obsoleted since the last commit start. + * @c: UBIFS file-system description object + * @lnum: LEB number of obsoleted index node + * @offs: offset of obsoleted index node + * + * Returns %0 on success, and a negative error code on failure. + * + * For recovery, there must always be a complete intact version of the index on + * flash at all times. That is called the "old index". It is the index as at the + * time of the last successful commit. Many of the index nodes in the old index + * may be dirty, but they must not be erased until the next successful commit + * (at which point that index becomes the old index). + * + * That means that the garbage collection and the in-the-gaps method of + * committing must be able to determine if an index node is in the old index. + * Most of the old index nodes can be found by looking up the TNC using the + * 'lookup_znode()' function. However, some of the old index nodes may have + * been deleted from the current index or may have been changed so much that + * they cannot be easily found. In those cases, an entry is added to an RB-tree. + * That is what this function does. The RB-tree is ordered by LEB number and + * offset because they uniquely identify the old index node. + */ +static int insert_old_idx(struct ubifs_info *c, int lnum, int offs) +{ + struct ubifs_old_idx *old_idx, *o; + struct rb_node **p, *parent = NULL; + + old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); + if (unlikely(!old_idx)) + return -ENOMEM; + old_idx->lnum = lnum; + old_idx->offs = offs; + + p = &c->old_idx.rb_node; + while (*p) { + parent = *p; + o = rb_entry(parent, struct ubifs_old_idx, rb); + if (lnum < o->lnum) + p = &(*p)->rb_left; + else if (lnum > o->lnum) + p = &(*p)->rb_right; + else if (offs < o->offs) + p = &(*p)->rb_left; + else if (offs > o->offs) + p = &(*p)->rb_right; + else { + ubifs_err("old idx added twice!"); + kfree(old_idx); + return 0; + } + } + rb_link_node(&old_idx->rb, parent, p); + rb_insert_color(&old_idx->rb, &c->old_idx); + return 0; +} + +/** + * insert_old_idx_znode - record a znode obsoleted since last commit start. + * @c: UBIFS file-system description object + * @znode: znode of obsoleted index node + * + * Returns %0 on success, and a negative error code on failure. + */ +int insert_old_idx_znode(struct ubifs_info *c, struct ubifs_znode *znode) +{ + if (znode->parent) { + struct ubifs_zbranch *zbr; + + zbr = &znode->parent->zbranch[znode->iip]; + if (zbr->len) + return insert_old_idx(c, zbr->lnum, zbr->offs); + } else + if (c->zroot.len) + return insert_old_idx(c, c->zroot.lnum, + c->zroot.offs); + return 0; +} + +/** + * ins_clr_old_idx_znode - record a znode obsoleted since last commit start. + * @c: UBIFS file-system description object + * @znode: znode of obsoleted index node + * + * Returns %0 on success, and a negative error code on failure. + */ +static int ins_clr_old_idx_znode(struct ubifs_info *c, + struct ubifs_znode *znode) +{ + int err; + + if (znode->parent) { + struct ubifs_zbranch *zbr; + + zbr = &znode->parent->zbranch[znode->iip]; + if (zbr->len) { + err = insert_old_idx(c, zbr->lnum, zbr->offs); + if (err) + return err; + zbr->lnum = 0; + zbr->offs = 0; + zbr->len = 0; + } + } else + if (c->zroot.len) { + err = insert_old_idx(c, c->zroot.lnum, c->zroot.offs); + if (err) + return err; + c->zroot.lnum = 0; + c->zroot.offs = 0; + c->zroot.len = 0; + } + return 0; +} + +/** + * destroy_old_idx - destroy the old_idx RB-tree. + * @c: UBIFS file-system description object + * + * During start commit, the old_idx RB-tree is used to avoid overwriting index + * nodes that were in the index last commit but have since been deleted. This + * is necessary for recovery i.e. the old index must be kept intact until the + * new index is successfully written. The old-idx RB-tree is used for the + * in-the-gaps method of writing index nodes and is destroyed every commit. + */ +void destroy_old_idx(struct ubifs_info *c) +{ + struct rb_node *this = c->old_idx.rb_node; + struct ubifs_old_idx *old_idx; + + while (this) { + if (this->rb_left) { + this = this->rb_left; + continue; + } else if (this->rb_right) { + this = this->rb_right; + continue; + } + old_idx = rb_entry(this, struct ubifs_old_idx, rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &old_idx->rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + kfree(old_idx); + } + c->old_idx = RB_ROOT; +} + +/** + * copy_znode - copy a dirty znode. + * @c: UBIFS file-system description object + * @znode: znode to copy + * + * A dirty znode being committed may not be changed, so it is copied. + */ +static struct ubifs_znode *copy_znode(struct ubifs_info *c, + struct ubifs_znode *znode) +{ + struct ubifs_znode *zn; + + zn = kmalloc(c->max_znode_sz, GFP_NOFS); + if (unlikely(!zn)) + return ERR_PTR(-ENOMEM); + + memcpy(zn, znode, c->max_znode_sz); + zn->cnext = NULL; + __set_bit(DIRTY_ZNODE, &zn->flags); + __clear_bit(COW_ZNODE, &zn->flags); + + ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags)); + __set_bit(OBSOLETE_ZNODE, &znode->flags); + + if (znode->level != 0) { + int i; + const int n = zn->child_cnt; + + /* The children now have new parent */ + for (i = 0; i < n; i++) { + struct ubifs_zbranch *zbr = &zn->zbranch[i]; + + if (zbr->znode) + zbr->znode->parent = zn; + } + } + + atomic_long_inc(&c->dirty_zn_cnt); + return zn; +} + +/** + * add_idx_dirt - add dirt due to a dirty znode. + * @c: UBIFS file-system description object + * @lnum: LEB number of index node + * @dirt: size of index node + * + * This function updates lprops dirty space and the new size of the index. + */ +static int add_idx_dirt(struct ubifs_info *c, int lnum, int dirt) +{ + c->calc_idx_sz -= ALIGN(dirt, 8); + return ubifs_add_dirt(c, lnum, dirt); +} + +/** + * dirty_cow_znode - ensure a znode is not being committed. + * @c: UBIFS file-system description object + * @zbr: branch of znode to check + * + * Returns dirtied znode on success or negative error code on failure. + */ +static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, + struct ubifs_zbranch *zbr) +{ + struct ubifs_znode *znode = zbr->znode; + struct ubifs_znode *zn; + int err; + + if (!test_bit(COW_ZNODE, &znode->flags)) { + /* znode is not being committed */ + if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) { + atomic_long_inc(&c->dirty_zn_cnt); + atomic_long_dec(&c->clean_zn_cnt); + atomic_long_dec(&ubifs_clean_zn_cnt); + err = add_idx_dirt(c, zbr->lnum, zbr->len); + if (unlikely(err)) + return ERR_PTR(err); + } + return znode; + } + + zn = copy_znode(c, znode); + if (unlikely(IS_ERR(zn))) + return zn; + + if (zbr->len) { + err = insert_old_idx(c, zbr->lnum, zbr->offs); + if (unlikely(err)) + return ERR_PTR(err); + err = add_idx_dirt(c, zbr->lnum, zbr->len); + } else + err = 0; + + zbr->znode = zn; + zbr->lnum = 0; + zbr->offs = 0; + zbr->len = 0; + + if (unlikely(err)) + return ERR_PTR(err); + return zn; +} + +/** + * lnc_add - add a leaf node to the leaf node cache. + * @c: UBIFS file-system description object + * @zbr: zbranch of leaf node + * @node: leaf node + * + * Leaf nodes are non-index nodes directory entry nodes or data nodes. The + * purpose of the leaf node cache is to save re-reading the same leaf node over + * and over again. Most things are cached by VFS, however the file system must + * cache directory entries for readdir and for resolving hash collisions. The + * present implementation of the leaf node cache is extremely simple, and + * allows for error returns that are not used but that may be needed if a more + * complex implementation is created. + * + * Note, this function does not add the @node object to LNC directly, but + * allocates a copy of the object and adds the copy to LNC. The reason for this + * is that @node has been allocated outside of the TNC subsystem and will be + * used with @c->tnc_mutex unlock upon return from the TNC subsystem. But LNC + * may be changed at any time, e.g. freed by the shrinker. + */ +static int lnc_add(struct ubifs_info *c, struct ubifs_zbranch *zbr, + const void *node) +{ + int err; + void *lnc_node; + const struct ubifs_dent_node *dent = node; + + ubifs_assert(!zbr->leaf); + ubifs_assert(zbr->len != 0); + ubifs_assert(is_hash_key(c, &zbr->key)); + + err = ubifs_validate_entry(c, dent); + if (err) { + dbg_dump_stack(); + dbg_dump_node(c, dent); + return err; + } + + lnc_node = kmalloc(zbr->len, GFP_NOFS); + if (!lnc_node) + /* We don't have to have the cache, so no error */ + return 0; + + memcpy(lnc_node, node, zbr->len); + zbr->leaf = lnc_node; + return 0; +} + + /** + * lnc_add_directly - add a leaf node to the leaf-node-cache. + * @c: UBIFS file-system description object + * @zbr: zbranch of leaf node + * @node: leaf node + * + * This function is similar to 'lnc_add()', but it does not create a copy of + * @node but inserts @node to TNC directly. + */ +static int lnc_add_directly(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *node) +{ + int err; + + ubifs_assert(!zbr->leaf); + ubifs_assert(zbr->len != 0); + + err = ubifs_validate_entry(c, node); + if (err) { + dbg_dump_stack(); + dbg_dump_node(c, node); + return err; + } + + zbr->leaf = node; + return 0; +} + +/** + * lnc_free - remove a leaf node from the leaf node cache. + * @zbr: zbranch of leaf node + * @node: leaf node + */ +static void lnc_free(struct ubifs_zbranch *zbr) +{ + if (!zbr->leaf) + return; + kfree(zbr->leaf); + zbr->leaf = NULL; +} + +/** + * tnc_read_node_nm - read a "hashed" leaf node. + * @c: UBIFS file-system description object + * @zbr: key and position of the node + * @node: node is returned here + * + * This function reads a "hashed" node defined by @zbr from the leaf node cache + * (in it is there) or from the hash media, in which case the node is also + * added to LNC. Returns zero in case of success or a negative negative error + * code in case of failure. + */ +static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *node) +{ + int err; + + ubifs_assert(is_hash_key(c, &zbr->key)); + + if (zbr->leaf) { + /* Read from the leaf node cache */ + ubifs_assert(zbr->len != 0); + memcpy(node, zbr->leaf, zbr->len); + return 0; + } + + err = ubifs_tnc_read_node(c, zbr, node); + if (err) + return err; + + /* Add the node to the leaf node cache */ + err = lnc_add(c, zbr, node); + return err; +} + +/** + * try_read_node - read a node if it is a node. + * @c: UBIFS file-system description object + * @buf: buffer to read to + * @type: node type + * @len: node length (not aligned) + * @lnum: LEB number of node to read + * @offs: offset of node to read + * + * This function tries to read a node of known type and length, checks it and + * stores it in @buf. This function returns %1 if a node is present and %0 if + * a node is not present. A negative error code is returned for I/O errors. + * 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. + */ +static int try_read_node(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs) +{ + int err, node_len; + struct ubifs_ch *ch = buf; + uint32_t crc, node_crc; + + dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); + + err = ubi_read(c->ubi, lnum, buf, offs, len); + if (err) { + ubifs_err("cannot read node type %d from LEB %d:%d, error %d", + type, lnum, offs, err); + return err; + } + + if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) + return 0; + + if (ch->node_type != type) + return 0; + + node_len = le32_to_cpu(ch->len); + if (node_len != len) + return 0; + + crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); + node_crc = le32_to_cpu(ch->crc); + if (crc != node_crc) + return 0; + + return 1; +} + +/** + * fallible_read_node - try to read a leaf node. + * @c: UBIFS file-system description object + * @key: key of node to read + * @zbr: position of node + * @node: node returned + * + * This function tries to read a node and returns %1 if the node is read, %0 + * if the node is not present, and a negative error code in the case of error. + */ +static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_zbranch *zbr, void *node) +{ + int ret; + + dbg_tnc("LEB %d:%d, key %s", zbr->lnum, zbr->offs, DBGKEY(key)); + + ret = try_read_node(c, node, key_type(c, key), zbr->len, zbr->lnum, + zbr->offs); + if (ret == 1) { + union ubifs_key node_key; + struct ubifs_dent_node *dent = node; + + /* All nodes have key in the same place */ + key_read(c, &dent->key, &node_key); + if (keys_cmp(c, key, &node_key) != 0) + ret = 0; + } + if (ret == 0) + dbg_mnt("dangling branch LEB %d:%d len %d, key %s", + zbr->lnum, zbr->offs, zbr->len, DBGKEY(key)); + return ret; +} + +/** + * matches_name - determine if a direntry or xattr entry matches a given name. + * @c: UBIFS file-system description object + * @zbr: zbranch of dent + * @nm: name to match + * + * This function checks if xentry/direntry referred by zbranch @zbr matches name + * @nm. Returns %NAME_MATCHES if it does, %NAME_LESS if the name referred by + * @zbr is less than @nm, and %NAME_GREATER if it is greater than @nm. In case + * of failure, a negative error code is returned. + */ +static int matches_name(struct ubifs_info *c, struct ubifs_zbranch *zbr, + const struct qstr *nm) +{ + struct ubifs_dent_node *dent; + int nlen, err; + + /* If possible, match against the dent in the leaf node cache */ + if (!zbr->leaf) { + dent = kmalloc(zbr->len, GFP_NOFS); + if (!dent) + return -ENOMEM; + + err = ubifs_tnc_read_node(c, zbr, dent); + if (err) + goto out_free; + + /* Add the node to the leaf node cache */ + err = lnc_add_directly(c, zbr, dent); + if (err) + goto out_free; + } else + dent = zbr->leaf; + + nlen = le16_to_cpu(dent->nlen); + err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len)); + if (err == 0) { + if (nlen == nm->len) + return NAME_MATCHES; + else if (nlen < nm->len) + return NAME_LESS; + else + return NAME_GREATER; + } else if (err < 0) + return NAME_LESS; + else + return NAME_GREATER; + +out_free: + kfree(dent); + return err; +} + +/** + * get_znode - get a TNC znode that may not be loaded yet. + * @c: UBIFS file-system description object + * @znode: parent znode + * @n: znode branch slot number + * + * This function returns the znode or a negative error code. + */ +static struct ubifs_znode *get_znode(struct ubifs_info *c, + struct ubifs_znode *znode, int n) +{ + struct ubifs_zbranch *zbr; + + zbr = &znode->zbranch[n]; + if (zbr->znode) + znode = zbr->znode; + else + znode = ubifs_load_znode(c, zbr, znode, n); + return znode; +} + +/** + * tnc_next - find next TNC entry. + * @c: UBIFS file-system description object + * @zn: znode is passed and returned here + * @n: znode branch slot number is passed and returned here + * + * This function returns %0 if the next TNC entry is found, %-ENOENT if there is + * no next entry, or a negative error code otherwise. + */ +static int tnc_next(struct ubifs_info *c, struct ubifs_znode **zn, int *n) +{ + struct ubifs_znode *znode = *zn; + int nn = *n; + + nn += 1; + if (nn < znode->child_cnt) { + *n = nn; + return 0; + } + while (1) { + struct ubifs_znode *zp; + + zp = znode->parent; + if (!zp) + return -ENOENT; + nn = znode->iip + 1; + znode = zp; + if (nn < znode->child_cnt) { + znode = get_znode(c, znode, nn); + if (IS_ERR(znode)) + return PTR_ERR(znode); + while (znode->level != 0) { + znode = get_znode(c, znode, 0); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + nn = 0; + break; + } + } + *zn = znode; + *n = nn; + return 0; +} + +/** + * tnc_prev - find previous TNC entry. + * @c: UBIFS file-system description object + * @zn: znode is returned here + * @n: znode branch slot number is passed and returned here + * + * This function returns %0 if the previous TNC entry is found, %-ENOENT if + * there is no next entry, or a negative error code otherwise. + */ +static int tnc_prev(struct ubifs_info *c, struct ubifs_znode **zn, int *n) +{ + struct ubifs_znode *znode = *zn; + int nn = *n; + + if (nn > 0) { + *n = nn - 1; + return 0; + } + while (1) { + struct ubifs_znode *zp; + + zp = znode->parent; + if (!zp) + return -ENOENT; + nn = znode->iip - 1; + znode = zp; + if (nn >= 0) { + znode = get_znode(c, znode, nn); + if (IS_ERR(znode)) + return PTR_ERR(znode); + while (znode->level != 0) { + nn = znode->child_cnt - 1; + znode = get_znode(c, znode, nn); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + nn = znode->child_cnt - 1; + break; + } + } + *zn = znode; + *n = nn; + return 0; +} + +/** + * resolve_collision - resolve a collision. + * @c: UBIFS file-system description object + * @key: key of a directory or extended attribute entry + * @zn: znode is returned here + * @n: zbranch number is passed and returned here + * @nm: name of the entry + * + * This function is called for "hashed" keys to make sure that the found key + * really corresponds to the looked up node (directory or extended attribute + * entry). It returns %1 and sets @zn and @n if the collision is resolved. + * %0 is returned if @nm is not found and @zn and @n are set to the previous + * entry, i.e. to the entry after which @nm could follow if it were in TNC. + * This means that @n may be set to %-1 if the leftmost key in @zn is the + * previous one. A negative error code is returned on failures. + */ +static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_znode **zn, int *n, + const struct qstr *nm) +{ + int err; + + err = matches_name(c, &(*zn)->zbranch[*n], nm); + if (unlikely(err < 0)) + return err; + if (err == NAME_MATCHES) + return 1; + + if (err == NAME_GREATER) { + /* Look left */ + while (1) { + err = tnc_prev(c, zn, n); + if (err == -ENOENT) { + ubifs_assert(*n == 0); + *n = -1; + return 0; + } + if (err < 0) + return err; + if (keys_cmp(c, &(*zn)->zbranch[*n].key, key)) { + /* + * We have found the branch after which we would + * like to insert, but inserting in this znode + * may still be wrong. Consider the following 3 + * znodes, in the case where we are resolving a + * collision with Key2. + * + * znode zp + * ---------------------- + * level 1 | Key0 | Key1 | + * ----------------------- + * | | + * znode za | | znode zb + * ------------ ------------ + * level 0 | Key0 | | Key2 | + * ------------ ------------ + * + * The lookup finds Key2 in znode zb. Lets say + * there is no match and the name is greater so + * we look left. When we find Key0, we end up + * here. If we return now, we will insert into + * znode za at slot n = 1. But that is invalid + * according to the parent's keys. Key2 must + * be inserted into znode zb. + * + * Note, this problem is not relevant for the + * case when we go right, because + * 'tnc_insert()' would correct the parent key. + */ + if (*n == (*zn)->child_cnt - 1) { + err = tnc_next(c, zn, n); + if (err) { + /* Should be impossible */ + ubifs_assert(0); + if (err == -ENOENT) + err = -EINVAL; + return err; + } + ubifs_assert(*n == 0); + *n = -1; + } + return 0; + } + err = matches_name(c, &(*zn)->zbranch[*n], nm); + if (err < 0) + return err; + if (err == NAME_LESS) + return 0; + if (err == NAME_MATCHES) + return 1; + ubifs_assert(err == NAME_GREATER); + } + } else { + int nn = *n; + struct ubifs_znode *znode = *zn; + + /* Look right */ + while (1) { + err = tnc_next(c, &znode, &nn); + if (err == -ENOENT) + return 0; + if (err < 0) + return err; + if (keys_cmp(c, &znode->zbranch[nn].key, key)) + return 0; + err = matches_name(c, &znode->zbranch[nn], nm); + if (err < 0) + return err; + if (err == NAME_GREATER) + return 0; + *zn = znode; + *n = nn; + if (err == NAME_MATCHES) + return 1; + ubifs_assert(err == NAME_LESS); + } + } +} + +/** + * fallible_matches_name - determine if a dent matches a given name. + * @c: UBIFS file-system description object + * @zbr: zbranch of dent + * @nm: name to match + * + * This is a "fallible" version of 'matches_name()' function which does not + * panic if the direntry/xentry referred by @zbr does not exist on the media. + * + * This function checks if xentry/direntry referred by zbranch @zbr matches name + * @nm. Returns %NAME_MATCHES it does, %NAME_LESS if the name referred by @zbr + * is less than @nm, %NAME_GREATER if it is greater than @nm, and @NOT_ON_MEDIA + * if xentry/direntry referred by @zbr does not exist on the media. A negative + * error code is returned in case of failure. + */ +static int fallible_matches_name(struct ubifs_info *c, + struct ubifs_zbranch *zbr, + const struct qstr *nm) +{ + struct ubifs_dent_node *dent; + int nlen, err; + + /* If possible, match against the dent in the leaf node cache */ + if (!zbr->leaf) { + dent = kmalloc(zbr->len, GFP_NOFS); + if (!dent) + return -ENOMEM; + + err = fallible_read_node(c, &zbr->key, zbr, dent); + if (err < 0) + goto out_free; + if (err == 0) { + /* The node was not present */ + err = NOT_ON_MEDIA; + goto out_free; + } + ubifs_assert(err == 1); + + err = lnc_add_directly(c, zbr, dent); + if (err) + goto out_free; + } else + dent = zbr->leaf; + + nlen = le16_to_cpu(dent->nlen); + err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len)); + if (err == 0) { + if (nlen == nm->len) + return NAME_MATCHES; + else if (nlen < nm->len) + return NAME_LESS; + else + return NAME_GREATER; + } else if (err < 0) + return NAME_LESS; + else + return NAME_GREATER; + +out_free: + kfree(dent); + return err; +} + +/** + * fallible_resolve_collision - resolve a collision even if nodes are missing. + * @c: UBIFS file-system description object + * @key: key + * @zn: znode is returned here + * @n: branch number is passed and returned here + * @nm: name of directory entry + * @adding: indicates caller is adding a key to the TNC + * + * This is a "fallible" version of the 'resolve_collision()' function which + * does not panic if one of the nodes referred to by TNC does not exist on the + * media. This may happen when replaying the journal if a deleted node was + * Garbage-collected and the commit was not done. A branch that refers to a node + * that is not present is called a dangling branch. The following are the return + * codes for this function: + * o if @nm was found, %1 is returned and @zn and @n are set to the found + * branch; + * o if we are @adding and @nm was not found, %0 is returned; + * o if we are not @adding and @nm was not found, but a dangling branch was + * found, then %1 is returned and @zn and @n are set to the dangling branch; + * o a negative error code is returned in case of failure. + */ +static int fallible_resolve_collision(struct ubifs_info *c, + const union ubifs_key *key, + struct ubifs_znode **zn, int *n, + const struct qstr *nm, int adding) +{ + struct ubifs_znode *o_znode = NULL, *znode = *zn; + int uninitialized_var(o_n), err, cmp, unsure = 0, nn = *n; + + cmp = fallible_matches_name(c, &znode->zbranch[nn], nm); + if (unlikely(cmp < 0)) + return cmp; + if (cmp == NAME_MATCHES) + return 1; + if (cmp == NOT_ON_MEDIA) { + o_znode = znode; + o_n = nn; + /* + * We are unlucky and hit a dangling branch straight away. + * Now we do not really know where to go to find the needed + * branch - to the left or to the right. Well, let's try left. + */ + unsure = 1; + } else if (!adding) + unsure = 1; /* Remove a dangling branch wherever it is */ + + if (cmp == NAME_GREATER || unsure) { + /* Look left */ + while (1) { + err = tnc_prev(c, zn, n); + if (err == -ENOENT) { + ubifs_assert(*n == 0); + *n = -1; + break; + } + if (err < 0) + return err; + if (keys_cmp(c, &(*zn)->zbranch[*n].key, key)) { + /* See comments in 'resolve_collision()' */ + if (*n == (*zn)->child_cnt - 1) { + err = tnc_next(c, zn, n); + if (err) { + /* Should be impossible */ + ubifs_assert(0); + if (err == -ENOENT) + err = -EINVAL; + return err; + } + ubifs_assert(*n == 0); + *n = -1; + } + break; + } + err = fallible_matches_name(c, &(*zn)->zbranch[*n], nm); + if (err < 0) + return err; + if (err == NAME_MATCHES) + return 1; + if (err == NOT_ON_MEDIA) { + o_znode = *zn; + o_n = *n; + continue; + } + if (!adding) + continue; + if (err == NAME_LESS) + break; + else + unsure = 0; + } + } + + if (cmp == NAME_LESS || unsure) { + /* Look right */ + *zn = znode; + *n = nn; + while (1) { + err = tnc_next(c, &znode, &nn); + if (err == -ENOENT) + break; + if (err < 0) + return err; + if (keys_cmp(c, &znode->zbranch[nn].key, key)) + break; + err = fallible_matches_name(c, &znode->zbranch[nn], nm); + if (err < 0) + return err; + if (err == NAME_GREATER) + break; + *zn = znode; + *n = nn; + if (err == NAME_MATCHES) + return 1; + if (err == NOT_ON_MEDIA) { + o_znode = znode; + o_n = nn; + } + } + } + + /* Never match a dangling branch when adding */ + if (adding || !o_znode) + return 0; + + dbg_mnt("dangling match LEB %d:%d len %d %s", + o_znode->zbranch[o_n].lnum, o_znode->zbranch[o_n].offs, + o_znode->zbranch[o_n].len, DBGKEY(key)); + *zn = o_znode; + *n = o_n; + return 1; +} + +/** + * matches_position - determine if a zbranch matches a given position. + * @zbr: zbranch of dent + * @lnum: LEB number of dent to match + * @offs: offset of dent to match + * + * This function returns %1 if @lnum:@offs matches, and %0 otherwise. + */ +static int matches_position(struct ubifs_zbranch *zbr, int lnum, int offs) +{ + if (zbr->lnum == lnum && zbr->offs == offs) + return 1; + else + return 0; +} + +/** + * resolve_collision_directly - resolve a collision directly. + * @c: UBIFS file-system description object + * @key: key of directory entry + * @zn: znode is passed and returned here + * @n: zbranch number is passed and returned here + * @lnum: LEB number of dent node to match + * @offs: offset of dent node to match + * + * This function is used for "hashed" keys to make sure the found directory or + * extended attribute entry node is what was looked for. It is used when the + * flash address of the right node is known (@lnum:@offs) which makes it much + * easier to resolve collisions (no need to read entries and match full + * names). This function returns %1 and sets @zn and @n if the collision is + * resolved, %0 if @lnum:@offs is not found and @zn and @n are set to the + * previous directory entry. Otherwise a negative error code is returned. + */ +static int resolve_collision_directly(struct ubifs_info *c, + const union ubifs_key *key, + struct ubifs_znode **zn, int *n, + int lnum, int offs) +{ + struct ubifs_znode *znode; + int nn, err; + + znode = *zn; + nn = *n; + if (matches_position(&znode->zbranch[nn], lnum, offs)) + return 1; + + /* Look left */ + while (1) { + err = tnc_prev(c, &znode, &nn); + if (err == -ENOENT) + break; + if (err < 0) + return err; + if (keys_cmp(c, &znode->zbranch[nn].key, key)) + break; + if (matches_position(&znode->zbranch[nn], lnum, offs)) { + *zn = znode; + *n = nn; + return 1; + } + } + + /* Look right */ + znode = *zn; + nn = *n; + while (1) { + err = tnc_next(c, &znode, &nn); + if (err == -ENOENT) + return 0; + if (err < 0) + return err; + if (keys_cmp(c, &znode->zbranch[nn].key, key)) + return 0; + *zn = znode; + *n = nn; + if (matches_position(&znode->zbranch[nn], lnum, offs)) + return 1; + } +} + +/** + * dirty_cow_bottom_up - dirty a znode and its ancestors. + * @c: UBIFS file-system description object + * @znode: znode to dirty + * + * If we do not have a unique key that resides in a znode, then we cannot + * dirty that znode from the top down (i.e. by using lookup_level0_dirty) + * This function records the path back to the last dirty ancestor, and then + * dirties the znodes on that path. + */ +static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c, + struct ubifs_znode *znode) +{ + struct ubifs_znode *zp; + int *path = c->bottom_up_buf, p = 0; + + ubifs_assert(c->zroot.znode); + ubifs_assert(znode); + if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) { + kfree(c->bottom_up_buf); + c->bottom_up_buf = kmalloc(c->zroot.znode->level * sizeof(int), + GFP_NOFS); + if (!c->bottom_up_buf) + return ERR_PTR(-ENOMEM); + path = c->bottom_up_buf; + } + if (c->zroot.znode->level) { + /* Go up until parent is dirty */ + while (1) { + int n; + + zp = znode->parent; + if (!zp) + break; + n = znode->iip; + ubifs_assert(p < c->zroot.znode->level); + path[p++] = n; + if (!zp->cnext && ubifs_zn_dirty(znode)) + break; + znode = zp; + } + } + + /* Come back down, dirtying as we go */ + while (1) { + struct ubifs_zbranch *zbr; + + zp = znode->parent; + if (zp) { + ubifs_assert(path[p - 1] >= 0); + ubifs_assert(path[p - 1] < zp->child_cnt); + zbr = &zp->zbranch[path[--p]]; + znode = dirty_cow_znode(c, zbr); + } else { + ubifs_assert(znode == c->zroot.znode); + znode = dirty_cow_znode(c, &c->zroot); + } + if (unlikely(IS_ERR(znode)) || !p) + break; + ubifs_assert(path[p - 1] >= 0); + ubifs_assert(path[p - 1] < znode->child_cnt); + znode = znode->zbranch[path[p - 1]].znode; + } + + return znode; +} + +/** + * ubifs_lookup_level0 - search for zero-level znode. + * @c: UBIFS file-system description object + * @key: key to lookup + * @zn: znode is returned here + * @n: znode branch slot number is returned here + * + * This function looks up the TNC tree and search for zero-level znode which + * refers key @key. The found zero-level znode is returned in @zn. There are 3 + * cases: + * o exact match, i.e. the found zero-level znode contains key @key, then %1 + * is returned and slot number of the matched branch is stored in @n; + * o not exact match, which means that zero-level znode does not contain + * @key, then %0 is returned and slot number of the closed branch is stored + * in @n; + * o @key is so small that it is even less than the lowest key of the + * leftmost zero-level node, then %0 is returned and %0 is stored in @n. + * + * Note, when the TNC tree is traversed, some znodes may be absent, then this + * function reads corresponding indexing nodes and inserts them to TNC. In + * case of failure, a negative error code is returned. + */ +int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_znode **zn, int *n) +{ + int err, exact; + struct ubifs_znode *znode; + unsigned long time = get_seconds(); + + dbg_tnc("search key %s", DBGKEY(key)); + + znode = c->zroot.znode; + if (unlikely(!znode)) { + znode = ubifs_load_znode(c, &c->zroot, NULL, 0); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + + znode->time = time; + + while (1) { + struct ubifs_zbranch *zbr; + + exact = ubifs_search_zbranch(c, znode, key, n); + + if (znode->level == 0) + break; + + if (*n < 0) + *n = 0; + zbr = &znode->zbranch[*n]; + + if (zbr->znode) { + znode->time = time; + znode = zbr->znode; + continue; + } + + /* znode is not in TNC cache, load it from the media */ + znode = ubifs_load_znode(c, zbr, znode, *n); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + + *zn = znode; + if (exact || !is_hash_key(c, key) || *n != -1) { + dbg_tnc("found %d, lvl %d, n %d", exact, znode->level, *n); + return exact; + } + + /* + * Here is a tricky place. We have not found the key and this is a + * "hashed" key, which may collide. The rest of the code deals with + * situations like this: + * + * | 3 | 5 | + * / \ + * | 3 | 5 | | 6 | 7 | (x) + * + * Or more a complex example: + * + * | 1 | 5 | + * / \ + * | 1 | 3 | | 5 | 8 | + * \ / + * | 5 | 5 | | 6 | 7 | (x) + * + * In the examples, if we are looking for key "5", we may reach nodes + * marked with "(x)". In this case what we have do is to look at the + * left and see if there is "5" key there. If there is, we have to + * return it. + * + * Note, this whole situation is possible because we allow to have + * elements which are equivalent to the next key in the parent in the + * children of current znode. For example, this happens if we split a + * znode like this: | 3 | 5 | 5 | 6 | 7 |, which results in something + * like this: + * | 3 | 5 | + * / \ + * | 3 | 5 | | 5 | 6 | 7 | + * ^ + * And this becomes what is at the first "picture" after key "5" marked + * with "^" is removed. What could be done is we could prohibit + * splitting in the middle of the colliding sequence. Also, when + * removing the leftmost key, we would have to correct the key of the + * parent node, which would introduce additional complications. Namely, + * if we changed the the leftmost key of the parent znode, the garbage + * collector would be unable to find it (GC is doing this when GC'ing + * indexing LEBs). Although we already have an additional RB-tree where + * we save such changed znodes (see 'ins_clr_old_idx_znode()') until + * after the commit. But anyway, this does not look easy to implement + * so we did not try this. + */ + err = tnc_prev(c, &znode, n); + if (err == -ENOENT) { + dbg_tnc("found 0, lvl %d, n -1", znode->level); + *n = -1; + return 0; + } + if (unlikely(err < 0)) + return err; + if (keys_cmp(c, key, &znode->zbranch[*n].key)) { + dbg_tnc("found 0, lvl %d, n -1", znode->level); + *n = -1; + return 0; + } + + dbg_tnc("found 1, lvl %d, n %d", znode->level, *n); + *zn = znode; + return 1; +} + +/** + * lookup_level0_dirty - search for zero-level znode dirtying. + * @c: UBIFS file-system description object + * @key: key to lookup + * @zn: znode is returned here + * @n: znode branch slot number is returned here + * + * This function looks up the TNC tree and search for zero-level znode which + * refers key @key. The found zero-level znode is returned in @zn. There are 3 + * cases: + * o exact match, i.e. the found zero-level znode contains key @key, then %1 + * is returned and slot number of the matched branch is stored in @n; + * o not exact match, which means that zero-level znode does not contain @key + * then %0 is returned and slot number of the closed branch is stored in + * @n; + * o @key is so small that it is even less than the lowest key of the + * leftmost zero-level node, then %0 is returned and %-1 is stored in @n. + * + * Additionally all znodes in the path from the root to the located zero-level + * znode are marked as dirty. + * + * Note, when the TNC tree is traversed, some znodes may be absent, then this + * function reads corresponding indexing nodes and inserts them to TNC. In + * case of failure, a negative error code is returned. + */ +static int lookup_level0_dirty(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_znode **zn, int *n) +{ + int err, exact; + struct ubifs_znode *znode; + unsigned long time = get_seconds(); + + dbg_tnc("search and dirty key %s", DBGKEY(key)); + + znode = c->zroot.znode; + if (unlikely(!znode)) { + znode = ubifs_load_znode(c, &c->zroot, NULL, 0); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + + znode = dirty_cow_znode(c, &c->zroot); + if (IS_ERR(znode)) + return PTR_ERR(znode); + + znode->time = time; + + while (1) { + struct ubifs_zbranch *zbr; + + exact = ubifs_search_zbranch(c, znode, key, n); + + if (znode->level == 0) + break; + + if (*n < 0) + *n = 0; + zbr = &znode->zbranch[*n]; + + if (zbr->znode) { + znode->time = time; + znode = dirty_cow_znode(c, zbr); + if (IS_ERR(znode)) + return PTR_ERR(znode); + continue; + } + + /* znode is not in TNC cache, load it from the media */ + znode = ubifs_load_znode(c, zbr, znode, *n); + if (IS_ERR(znode)) + return PTR_ERR(znode); + znode = dirty_cow_znode(c, zbr); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + + *zn = znode; + if (exact || !is_hash_key(c, key) || *n != -1) { + dbg_tnc("found %d, lvl %d, n %d", exact, znode->level, *n); + return exact; + } + + /* + * See huge comment at 'lookup_level0_dirty()' what is the rest of the + * code. + */ + err = tnc_prev(c, &znode, n); + if (err == -ENOENT) { + *n = -1; + dbg_tnc("found 0, lvl %d, n -1", znode->level); + return 0; + } + if (unlikely(err < 0)) + return err; + if (keys_cmp(c, key, &znode->zbranch[*n].key)) { + *n = -1; + dbg_tnc("found 0, lvl %d, n -1", znode->level); + return 0; + } + + if (znode->cnext || !ubifs_zn_dirty(znode)) { + znode = dirty_cow_bottom_up(c, znode); + if (IS_ERR(znode)) + return PTR_ERR(znode); + } + + dbg_tnc("found 1, lvl %d, n %d", znode->level, *n); + *zn = znode; + return 1; +} + +/** + * ubifs_tnc_lookup - look up a file-system node. + * @c: UBIFS file-system description object + * @key: node key to lookup + * @node: the node is returned here + * + * This function look up and reads node with key @key. The caller has to make + * sure the @node buffer is large enough to fit the node. Returns zero in case + * of success, %-ENOENT if the node was not found, and a negative error code in + * case of failure. + */ +int ubifs_tnc_lookup(struct ubifs_info *c, const union ubifs_key *key, + void *node) +{ + int found, n, err; + struct ubifs_znode *znode; + struct ubifs_zbranch zbr, *zt; + + mutex_lock(&c->tnc_mutex); + found = ubifs_lookup_level0(c, key, &znode, &n); + if (!found) { + err = -ENOENT; + goto out; + } else if (found < 0) { + err = found; + goto out; + } + zt = &znode->zbranch[n]; + if (is_hash_key(c, key)) { + /* + * In this case the leaf node cache gets used, so we pass the + * address of the zbranch and keep the mutex locked + */ + err = tnc_read_node_nm(c, zt, node); + goto out; + } + zbr = znode->zbranch[n]; + mutex_unlock(&c->tnc_mutex); + + err = ubifs_tnc_read_node(c, &zbr, node); + return err; + +out: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_tnc_locate - look up a file-system node and return it and its location. + * @c: UBIFS file-system description object + * @key: node key to lookup + * @node: the node is returned here + * @lnum: LEB number is returned here + * @offs: offset is returned here + * + * This function is the same as 'ubifs_tnc_lookup()' but it returns the node + * location also. See 'ubifs_tnc_lookup()'. + */ +int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, + void *node, int *lnum, int *offs) +{ + int found, n, err; + struct ubifs_znode *znode; + struct ubifs_zbranch zbr, *zt; + + mutex_lock(&c->tnc_mutex); + found = ubifs_lookup_level0(c, key, &znode, &n); + if (!found) { + err = -ENOENT; + goto out; + } else if (found < 0) { + err = found; + goto out; + } + zt = &znode->zbranch[n]; + if (is_hash_key(c, key)) { + /* + * In this case the leaf node cache gets used, so we pass the + * address of the zbranch and keep the mutex locked + */ + *lnum = zt->lnum; + *offs = zt->offs; + err = tnc_read_node_nm(c, zt, node); + goto out; + } + zbr = znode->zbranch[n]; + mutex_unlock(&c->tnc_mutex); + + *lnum = zbr.lnum; + *offs = zbr.offs; + + err = ubifs_tnc_read_node(c, &zbr, node); + return err; + +out: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * do_lookup_nm- look up a "hashed" node. + * @c: UBIFS file-system description object + * @key: node key to lookup + * @node: the node is returned here + * @nm: node name + * + * This function look up and reads a node which contains name hash in the key. + * Since the hash may have collisions, there may be many nodes with the same + * key, so we have to sequentially look to all of them until the needed one is + * found. This function returns zero in case of success, %-ENOENT if the node + * was not found, and a negative error code in case of failure. + */ +static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, + void *node, const struct qstr *nm) +{ + int found, n, err; + struct ubifs_znode *znode; + struct ubifs_zbranch zbr; + + dbg_tnc("name '%.*s' key %s", nm->len, nm->name, DBGKEY(key)); + mutex_lock(&c->tnc_mutex); + found = ubifs_lookup_level0(c, key, &znode, &n); + if (!found) { + err = -ENOENT; + goto out_unlock; + } else if (found < 0) { + err = found; + goto out_unlock; + } + + ubifs_assert(n >= 0); + + err = resolve_collision(c, key, &znode, &n, nm); + dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); + if (unlikely(err < 0)) + goto out_unlock; + if (err == 0) { + err = -ENOENT; + goto out_unlock; + } + + zbr = znode->zbranch[n]; + mutex_unlock(&c->tnc_mutex); + + err = tnc_read_node_nm(c, &zbr, node); + return err; + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_tnc_lookup_nm - look up a "hashed" node. + * @c: UBIFS file-system description object + * @key: node key to lookup + * @node: the node is returned here + * @nm: node name + * + * This function look up and reads a node which contains name hash in the key. + * Since the hash may have collisions, there may be many nodes with the same + * key, so we have to sequentially look to all of them until the needed one is + * found. This function returns zero in case of success, %-ENOENT if the node + * was not found, and a negative error code in case of failure. + */ +int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, + void *node, const struct qstr *nm) +{ + int err, len; + const struct ubifs_dent_node *dent = node; + + /* + * We assume that in most of the cases there are no name collisions and + * 'ubifs_tnc_lookup()' returns us the right direntry. + */ + err = ubifs_tnc_lookup(c, key, node); + if (err) + return err; + + len = le16_to_cpu(dent->nlen); + if (nm->len == len && !memcmp(dent->name, nm->name, len)) + return 0; + + /* + * Unluckily, there are hash collisions and we have to iterate over + * them look at each direntry with colliding name hash sequentially. + */ + return do_lookup_nm(c, key, node, nm); +} + +/** + * correct_parent_keys - correct parent znodes' keys. + * @c: UBIFS file-system description object + * @znode: znode to correct parent znodes for + * + * This is a helper function for 'tnc_insert()'. When the key of the leftmost + * zbranch changes, keys of parent znodes have to be corrected. This helper + * function is called in such situations and corrects the keys if needed. + */ +static void correct_parent_keys(const struct ubifs_info *c, + struct ubifs_znode *znode) +{ + union ubifs_key *key, *key1; + + ubifs_assert(znode->parent); + ubifs_assert(znode->iip == 0); + + key = &znode->zbranch[0].key; + key1 = &znode->parent->zbranch[0].key; + + while (keys_cmp(c, key, key1) < 0) { + key_copy(c, key, key1); + znode = znode->parent; + znode->alt = 1; + if (!znode->parent || znode->iip) + break; + key1 = &znode->parent->zbranch[0].key; + } +} + +/** + * insert_zbranch - insert a zbranch into a znode. + * @znode: znode into which to insert + * @zbr: zbranch to insert + * @n: slot number to insert to + * + * This is a helper function for 'tnc_insert()'. UBIFS does not allow "gaps" in + * znode's array of zbranches and keeps zbranches consolidated, so when a new + * zbranch has to be inserted to the @znode->zbranches[]' array at the @n-th + * slot, zbranches starting from @n have to be moved right. + */ +static void insert_zbranch(struct ubifs_znode *znode, + const struct ubifs_zbranch *zbr, int n) +{ + int i; + + ubifs_assert(ubifs_zn_dirty(znode)); + + if (znode->level) { + for (i = znode->child_cnt; i > n; i--) { + znode->zbranch[i] = znode->zbranch[i - 1]; + if (znode->zbranch[i].znode) + znode->zbranch[i].znode->iip = i; + } + if (zbr->znode) + zbr->znode->iip = n; + } else + for (i = znode->child_cnt; i > n; i--) + znode->zbranch[i] = znode->zbranch[i - 1]; + + znode->zbranch[n] = *zbr; + znode->child_cnt += 1; + + /* + * After inserting at slot zero, the lower bound of the key range of + * this znode may have changed. If this znode is subsequently split + * then the upper bound of the key range may change, and furthermore + * it could change to be lower than the original lower bound. If that + * happens, then it will no longer be possible to find this znode in the + * TNC using the key from the index node on flash. That is bad because + * if it is not found, we will assume it is obsolete and may overwrite + * it. Then if there is an unclean unmount, we will start using the + * old index which will be broken. + * + * So we first mark znodes that have insertions at slot zero, and then + * if they are split we add their lnum/offs to the old_idx tree. + */ + if (n == 0) + znode->alt = 1; +} + +/** + * tnc_insert - insert a node into TNC. + * @c: UBIFS file-system description object + * @znode: znode to insert into + * @zbr: branch to insert + * @n: slot number to insert new zbranch to + * + * This function inserts a new node described by @zbr into znode @znode. If + * znode does not have a free slot for new zbranch, it is split. Parent znodes + * are splat as well if needed. Returns zero in case of success or a negative + * error code in case of failure. + */ +static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode, + struct ubifs_zbranch *zbr, int n) +{ + struct ubifs_znode *zn, *zi, *zp; + int i, keep, move, appending = 0; + union ubifs_key *key = &zbr->key; + + ubifs_assert(n >= 0 && n <= c->fanout); + + /* Implement naive insert for now */ +again: + zp = znode->parent; + if (znode->child_cnt < c->fanout) { + ubifs_assert(n != c->fanout); + dbg_tnc("inserted at %d level %d, key %s", n, znode->level, + DBGKEY(key)); + + insert_zbranch(znode, zbr, n); + + /* Ensure parent's key is correct */ + if (n == 0 && zp && znode->iip == 0) + correct_parent_keys(c, znode); + + return 0; + } + + /* + * Unfortunately, @znode does not have more empty slots and we have to + * split it. + */ + dbg_tnc("splitting level %d, key %s", znode->level, DBGKEY(key)); + + if (znode->alt) + /* + * We can no longer be sure of finding this znode by key, so we + * record it in the old_idx tree. + */ + ins_clr_old_idx_znode(c, znode); + + zn = kzalloc(c->max_znode_sz, GFP_NOFS); + if (!zn) + return -ENOMEM; + zn->parent = zp; + zn->level = znode->level; + + /* Decide where to split */ + if (znode->level == 0 && n == c->fanout && + key_type(c, key) == UBIFS_DATA_KEY) { + union ubifs_key *key1; + + /* + * If this is an inode which is being appended - do not split + * it because no other zbranches can be inserted between + * zbranches of consecutive data nodes anyway. + */ + key1 = &znode->zbranch[n - 1].key; + if (key_inum(c, key1) == key_inum(c, key) && + key_type(c, key1) == UBIFS_DATA_KEY && + key_block(c, key1) == key_block(c, key) - 1) + appending = 1; + } + + if (appending) { + keep = c->fanout; + move = 0; + } else { + keep = (c->fanout + 1) / 2; + move = c->fanout - keep; + } + + /* + * Although we don't at present, we could look at the neighbors and see + * if we can move some zbranches there. + */ + + if (n < keep) { + /* Insert into existing znode */ + zi = znode; + move += 1; + keep -= 1; + } else { + /* Insert into new znode */ + zi = zn; + n -= keep; + /* Re-parent */ + if (zn->level != 0) + zbr->znode->parent = zn; + } + + __set_bit(DIRTY_ZNODE, &zn->flags); + atomic_long_inc(&c->dirty_zn_cnt); + + zn->child_cnt = move; + znode->child_cnt = keep; + + dbg_tnc("moving %d, keeping %d", move, keep); + + /* Move zbranch */ + for (i = 0; i < move; i++) { + zn->zbranch[i] = znode->zbranch[keep + i]; + /* Re-parent */ + if (zn->level != 0) + if (zn->zbranch[i].znode) { + zn->zbranch[i].znode->parent = zn; + zn->zbranch[i].znode->iip = i; + } + } + + /* Insert new key and branch */ + dbg_tnc("inserting at %d level %d, key %s", n, zn->level, DBGKEY(key)); + + insert_zbranch(zi, zbr, n); + + /* Insert new znode (produced by spitting) into the parent */ + if (zp) { + i = n; + /* Locate insertion point */ + n = znode->iip + 1; + if (appending && n != c->fanout) + appending = 0; + + if (i == 0 && zi == znode && znode->iip == 0) + correct_parent_keys(c, znode); + + /* Tail recursion */ + zbr->key = zn->zbranch[0].key; + zbr->znode = zn; + zbr->lnum = 0; + zbr->offs = 0; + zbr->len = 0; + znode = zp; + + goto again; + } + + /* We have to split root znode */ + dbg_tnc("creating new zroot at level %d", znode->level + 1); + + zi = kzalloc(c->max_znode_sz, GFP_NOFS); + if (!zi) + return -ENOMEM; + + zi->child_cnt = 2; + zi->level = znode->level + 1; + + __set_bit(DIRTY_ZNODE, &zi->flags); + atomic_long_inc(&c->dirty_zn_cnt); + + zi->zbranch[0].key = znode->zbranch[0].key; + zi->zbranch[0].znode = znode; + zi->zbranch[0].lnum = c->zroot.lnum; + zi->zbranch[0].offs = c->zroot.offs; + zi->zbranch[0].len = c->zroot.len; + zi->zbranch[1].key = zn->zbranch[0].key; + zi->zbranch[1].znode = zn; + + c->zroot.lnum = 0; + c->zroot.offs = 0; + c->zroot.len = 0; + c->zroot.znode = zi; + + zn->parent = zi; + zn->iip = 1; + znode->parent = zi; + znode->iip = 0; + + return 0; +} + +/** + * ubifs_tnc_add - add a node to TNC. + * @c: UBIFS file-system description object + * @key: key to add + * @lnum: LEB number of node + * @offs: node offset + * @len: node length + * + * This function adds a node with key @key to TNC. The node may be new or it may + * obsolete some existing one. Returns %0 on success or negative error code on + * failure. + */ +int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, + int offs, int len) +{ + int found, n, err = 0; + struct ubifs_znode *znode; + + mutex_lock(&c->tnc_mutex); + dbg_tnc("%d:%d, len %d, key %s", lnum, offs, len, DBGKEY(key)); + found = lookup_level0_dirty(c, key, &znode, &n); + if (!found) { + struct ubifs_zbranch zbr; + + zbr.znode = NULL; + zbr.lnum = lnum; + zbr.offs = offs; + zbr.len = len; + key_copy(c, key, &zbr.key); + err = tnc_insert(c, znode, &zbr, n + 1); + } else if (found == 1) { + struct ubifs_zbranch *zbr = &znode->zbranch[n]; + + lnc_free(zbr); + err = ubifs_add_dirt(c, zbr->lnum, zbr->len); + zbr->lnum = lnum; + zbr->offs = offs; + zbr->len = len; + } else + err = found; + if (!err) + err = dbg_check_tnc(c, 0); + mutex_unlock(&c->tnc_mutex); + + return err; +} + +/** + * ubifs_tnc_replace - replace a node in the TNC only if the old node is found. + * @c: UBIFS file-system description object + * @key: key to add + * @old_lnum: LEB number of old node + * @old_offs: old node offset + * @lnum: LEB number of node + * @offs: node offset + * @len: node length + * + * This function replaces a node with key @key in the TNC only if the old node + * is found. This function is called by garbage collection when node are moved. + * Returns %0 on success or negative error code on failure. + */ +int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, + int old_lnum, int old_offs, int lnum, int offs, int len) +{ + int found, n, err = 0; + struct ubifs_znode *znode; + + mutex_lock(&c->tnc_mutex); + dbg_tnc("old LEB %d:%d, new LEB %d:%d, len %d, key %s", old_lnum, + old_offs, lnum, offs, len, DBGKEY(key)); + found = lookup_level0_dirty(c, key, &znode, &n); + if (found < 0) { + err = found; + goto out_unlock; + } + + if (found == 1) { + struct ubifs_zbranch *zbr = &znode->zbranch[n]; + + found = 0; + if (zbr->lnum == old_lnum && zbr->offs == old_offs) { + lnc_free(zbr); + err = ubifs_add_dirt(c, zbr->lnum, zbr->len); + if (err) + goto out_unlock; + zbr->lnum = lnum; + zbr->offs = offs; + zbr->len = len; + found = 1; + } else if (is_hash_key(c, key)) { + found = resolve_collision_directly(c, key, &znode, &n, + old_lnum, old_offs); + dbg_tnc("rc returned %d, znode %p, n %d, LEB %d:%d", + found, znode, n, old_lnum, old_offs); + if (found < 0) { + err = found; + goto out_unlock; + } + + if (found) { + /* Ensure the znode is dirtied */ + if (znode->cnext || !ubifs_zn_dirty(znode)) { + znode = dirty_cow_bottom_up(c, + znode); + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + } + zbr = &znode->zbranch[n]; + lnc_free(zbr); + err = ubifs_add_dirt(c, zbr->lnum, + zbr->len); + if (err) + goto out_unlock; + zbr->lnum = lnum; + zbr->offs = offs; + zbr->len = len; + } + } + } + + if (!found) + err = ubifs_add_dirt(c, lnum, len); + + if (!err) + err = dbg_check_tnc(c, 0); + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_tnc_add_nm - add a "hashed" node to TNC. + * @c: UBIFS file-system description object + * @key: key to add + * @lnum: LEB number of node + * @offs: node offset + * @len: node length + * @nm: node name + * + * This is the same as 'ubifs_tnc_add()' but it should be used with keys which + * may have collisions, like directory entry keys. + */ +int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, + int lnum, int offs, int len, const struct qstr *nm) +{ + int found, n, err = 0; + struct ubifs_znode *znode; + + mutex_lock(&c->tnc_mutex); + dbg_tnc("LEB %d:%d, name '%.*s', key %s", lnum, offs, nm->len, nm->name, + DBGKEY(key)); + found = lookup_level0_dirty(c, key, &znode, &n); + if (found < 0) { + err = found; + goto out_unlock; + } + + if (found == 1) { + if (c->replaying) + found = fallible_resolve_collision(c, key, &znode, &n, + nm, 1); + else + found = resolve_collision(c, key, &znode, &n, nm); + dbg_tnc("rc returned %d, znode %p, n %d", found, znode, n); + if (found < 0) { + err = found; + goto out_unlock; + } + + /* Ensure the znode is dirtied */ + if (znode->cnext || !ubifs_zn_dirty(znode)) { + znode = dirty_cow_bottom_up(c, znode); + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + } + + if (found == 1) { + struct ubifs_zbranch *zbr = &znode->zbranch[n]; + + lnc_free(zbr); + err = ubifs_add_dirt(c, zbr->lnum, zbr->len); + zbr->lnum = lnum; + zbr->offs = offs; + zbr->len = len; + goto out_unlock; + } + } + + if (!found) { + struct ubifs_zbranch zbr; + + zbr.znode = NULL; + zbr.lnum = lnum; + zbr.offs = offs; + zbr.len = len; + key_copy(c, key, &zbr.key); + err = tnc_insert(c, znode, &zbr, n + 1); + if (err) + goto out_unlock; + if (c->replaying) { + /* + * We did not find it in the index so there may be a + * dangling branch still in the index. So we remove it + * by passing 'ubifs_tnc_remove_nm()' the same key but + * an unmatchable name. + */ + struct qstr noname = { .len = 0, .name = "" }; + + err = dbg_check_tnc(c, 0); + mutex_unlock(&c->tnc_mutex); + if (err) + return err; + return ubifs_tnc_remove_nm(c, key, &noname); + } + } + +out_unlock: + if (!err) + err = dbg_check_tnc(c, 0); + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * tnc_delete - delete a znode form TNC. + * @c: UBIFS file-system description object + * @znode: znode to delete from + * @n: zbranch slot number to delete + * + * This function deletes a leaf node from @n-th slot of @znode. Returns zero in + * case of success and a negative error code in case of failure. + */ +static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n) +{ + struct ubifs_zbranch *zbr; + struct ubifs_znode *zp; + int i, err; + + /* Delete without merge for now */ + ubifs_assert(znode->level == 0); + ubifs_assert(n >= 0 && n < c->fanout); + dbg_tnc("deleting %s", DBGKEY(&znode->zbranch[n].key)); + + zbr = &znode->zbranch[n]; + lnc_free(zbr); + + err = ubifs_add_dirt(c, zbr->lnum, zbr->len); + if (err) { + dbg_dump_znode(c, znode); + return err; + } + + /* We do not "gap" zbranch slots */ + for (i = n; i < znode->child_cnt - 1; i++) + znode->zbranch[i] = znode->zbranch[i + 1]; + znode->child_cnt -= 1; + + if (znode->child_cnt > 0) + return 0; + + /* + * This was the last zbranch, we have to delete this znode from the + * parent. + */ + + do { + ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags)); + ubifs_assert(ubifs_zn_dirty(znode)); + + zp = znode->parent; + n = znode->iip; + + atomic_long_dec(&c->dirty_zn_cnt); + + err = insert_old_idx_znode(c, znode); + if (err) + return err; + + if (znode->cnext) { + __set_bit(OBSOLETE_ZNODE, &znode->flags); + atomic_long_inc(&c->clean_zn_cnt); + atomic_long_inc(&ubifs_clean_zn_cnt); + } else + kfree(znode); + znode = zp; + } while (znode->child_cnt == 1); /* while removing last child */ + + /* Remove from znode, entry n - 1 */ + znode->child_cnt -= 1; + ubifs_assert(znode->level != 0); + for (i = n; i < znode->child_cnt; i++) { + znode->zbranch[i] = znode->zbranch[i + 1]; + if (znode->zbranch[i].znode) + znode->zbranch[i].znode->iip = i; + } + + /* + * If this is the root and it has only 1 child then + * collapse the tree. + */ + if (!znode->parent) { + while (znode->child_cnt == 1 && znode->level != 0) { + zp = znode; + zbr = &znode->zbranch[0]; + znode = get_znode(c, znode, 0); + if (IS_ERR(znode)) + return PTR_ERR(znode); + znode = dirty_cow_znode(c, zbr); + if (IS_ERR(znode)) + return PTR_ERR(znode); + znode->parent = NULL; + znode->iip = 0; + if (c->zroot.len) { + err = insert_old_idx(c, c->zroot.lnum, + c->zroot.offs); + if (err) + return err; + } + c->zroot.lnum = zbr->lnum; + c->zroot.offs = zbr->offs; + c->zroot.len = zbr->len; + c->zroot.znode = znode; + ubifs_assert(!test_bit(OBSOLETE_ZNODE, + &zp->flags)); + ubifs_assert(test_bit(DIRTY_ZNODE, &zp->flags)); + atomic_long_dec(&c->dirty_zn_cnt); + + if (zp->cnext) { + __set_bit(OBSOLETE_ZNODE, &zp->flags); + atomic_long_inc(&c->clean_zn_cnt); + atomic_long_inc(&ubifs_clean_zn_cnt); + } else + kfree(zp); + } + } + + return 0; +} + +/** + * ubifs_tnc_remove - remove an index entry of a node. + * @c: UBIFS file-system description object + * @key: key of node + * + * Returns %0 on success or negative error code on failure. + */ +int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key) +{ + int found, n, err = 0; + struct ubifs_znode *znode; + + mutex_lock(&c->tnc_mutex); + dbg_tnc("key %s", DBGKEY(key)); + found = lookup_level0_dirty(c, key, &znode, &n); + if (found < 0) { + err = found; + goto out_unlock; + } + if (found == 1) + err = tnc_delete(c, znode, n); + if (!err) + err = dbg_check_tnc(c, 0); + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_tnc_remove_nm - remove an index entry for a "hashed" node. + * @c: UBIFS file-system description object + * @key: key of node + * @nm: directory entry name + * + * Returns %0 on success or negative error code on failure. + */ +int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, + const struct qstr *nm) +{ + int n, err; + struct ubifs_znode *znode; + + mutex_lock(&c->tnc_mutex); + dbg_tnc("%.*s, key %s", nm->len, nm->name, DBGKEY(key)); + err = lookup_level0_dirty(c, key, &znode, &n); + if (err < 0) + goto out_unlock; + + if (err) { + if (c->replaying) + err = fallible_resolve_collision(c, key, &znode, &n, + nm, 0); + else + err = resolve_collision(c, key, &znode, &n, nm); + dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); + if (err < 0) + goto out_unlock; + if (err) { + /* Ensure the znode is dirtied */ + if (znode->cnext || !ubifs_zn_dirty(znode)) { + znode = dirty_cow_bottom_up(c, znode); + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + } + err = tnc_delete(c, znode, n); + } + } + +out_unlock: + if (!err) + err = dbg_check_tnc(c, 0); + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * key_in_range - determine if a key falls within a range of keys. + * @c: UBIFS file-system description object + * @key: key to check + * @from_key: lowest key in range + * @to_key: highest key in range + * + * This function returns %1 if the key is in range and %0 otherwise. + */ +static int key_in_range(struct ubifs_info *c, union ubifs_key *key, + union ubifs_key *from_key, union ubifs_key *to_key) +{ + if (keys_cmp(c, key, from_key) < 0) + return 0; + if (keys_cmp(c, key, to_key) > 0) + return 0; + return 1; +} + +/** + * ubifs_tnc_remove_range - remove index entries in range. + * @c: UBIFS file-system description object + * @from_key: lowest key to remove + * @to_key: highest key to remove + * + * This function removes index entries starting at @from_key and ending at + * @to_key. This function returns zero in case of success and a negative error + * code in case of failure. + */ +int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, + union ubifs_key *to_key) +{ + int i, n, k, err = 0; + struct ubifs_znode *znode; + union ubifs_key *key; + + mutex_lock(&c->tnc_mutex); + while (1) { + /* Find first level 0 znode that contains keys to remove */ + err = ubifs_lookup_level0(c, from_key, &znode, &n); + if (err < 0) + goto out_unlock; + + if (err) + key = from_key; + else { + err = tnc_next(c, &znode, &n); + if (err == -ENOENT) { + err = 0; + goto out_unlock; + } + if (err < 0) + goto out_unlock; + key = &znode->zbranch[n].key; + if (!key_in_range(c, key, from_key, to_key)) { + err = 0; + goto out_unlock; + } + } + + /* Ensure the znode is dirtied */ + if (znode->cnext || !ubifs_zn_dirty(znode)) { + znode = dirty_cow_bottom_up(c, znode); + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + } + + /* Remove all keys in range except the first */ + for (i = n + 1, k = 0; i < znode->child_cnt; i++, k++) { + key = &znode->zbranch[i].key; + if (!key_in_range(c, key, from_key, to_key)) + break; + lnc_free(&znode->zbranch[i]); + err = ubifs_add_dirt(c, znode->zbranch[i].lnum, + znode->zbranch[i].len); + if (err) { + dbg_dump_znode(c, znode); + goto out_unlock; + } + dbg_tnc("removing %s", DBGKEY(key)); + } + if (k) { + for (i = n + 1 + k; i < znode->child_cnt; i++) + znode->zbranch[i - k] = znode->zbranch[i]; + znode->child_cnt -= k; + } + + /* Now delete the first */ + err = tnc_delete(c, znode, n); + if (err) + goto out_unlock; + } + +out_unlock: + if (!err) + err = dbg_check_tnc(c, 0); + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_tnc_remove_ino - remove an inode from TNC. + * @c: UBIFS file-system description object + * @inum: inode number to remove + * + * This function remove inode @inum and all the extended attributes associated + * with the anode from TNC and returns zero in case of success or a negative + * error code in case of failure. + */ +int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum) +{ + union ubifs_key key1, key2; + struct ubifs_dent_node *xent, *pxent = NULL; + struct qstr nm = { .name = NULL }; + + dbg_tnc("ino %lu", inum); + + /* + * Walk all extended attribute entries and remove them together with + * corresponding extended attribute inodes. + */ + lowest_xent_key(c, &key1, inum); + while (1) { + ino_t xattr_inum; + int err; + + xent = ubifs_tnc_next_ent(c, &key1, &nm); + if (IS_ERR(xent)) { + err = PTR_ERR(xent); + if (err == -ENOENT) + break; + return err; + } + + xattr_inum = le64_to_cpu(xent->inum); + dbg_tnc("xent '%s', ino %lu", xent->name, xattr_inum); + + nm.name = xent->name; + nm.len = le16_to_cpu(xent->nlen); + err = ubifs_tnc_remove_nm(c, &key1, &nm); + if (err) { + kfree(xent); + return err; + } + + lowest_ino_key(c, &key1, xattr_inum); + highest_ino_key(c, &key2, xattr_inum); + err = ubifs_tnc_remove_range(c, &key1, &key2); + if (err) { + kfree(xent); + return err; + } + + kfree(pxent); + pxent = xent; + key_read(c, &xent->key, &key1); + } + + kfree(pxent); + lowest_ino_key(c, &key1, inum); + highest_ino_key(c, &key2, inum); + + return ubifs_tnc_remove_range(c, &key1, &key2); +} + +/** + * ubifs_tnc_next_ent - walk directory or extended attribute entries. + * @c: UBIFS file-system description object + * @key: key of last entry + * @nm: name of last entry found or %NULL + * + * This function finds and reads the next directory or extended attribute entry + * after the given key (@key) if there is one. @nm is used to resolve + * collisions. + * + * If the name of the current entry is not known and only the key is known, + * @nm->name has to be %NULL. In this case the semantics of this function is a + * little bit different and it returns the entry corresponding to this key, not + * the next one. If the key was not found, the closest "right" entry is + * returned. + * + * If the fist entry has to be found, @key has to contain the lowest possible + * key value for this inode and @name has to be %NULL. + * + * This function returns the found directory or extended attribute entry node + * in case of success, %-ENOENT is returned if no entry was found, and a + * negative error code is returned in case of failure. + */ +struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, + union ubifs_key *key, + const struct qstr *nm) +{ + int n, err, type = key_type(c, key); + struct ubifs_znode *znode; + struct ubifs_dent_node *dent; + struct ubifs_zbranch *zbr; + union ubifs_key *dkey; + + dbg_tnc("%s %s", nm->name ? (char *)nm->name : "(lowest)", DBGKEY(key)); + ubifs_assert(is_hash_key(c, key)); + + mutex_lock(&c->tnc_mutex); + err = ubifs_lookup_level0(c, key, &znode, &n); + if (unlikely(err < 0)) + goto out_unlock; + + if (nm->name) { + if (err) { + /* Handle collisions */ + err = resolve_collision(c, key, &znode, &n, nm); + dbg_tnc("rc returned %d, znode %p, n %d", + err, znode, n); + if (unlikely(err < 0)) + goto out_unlock; + } + + /* Now find next entry */ + err = tnc_next(c, &znode, &n); + if (unlikely(err)) + goto out_unlock; + } else { + /* + * The full name of the entry was not given, in which case the + * behavior of this function is a little different and it + * returns current entry, not the next one. + */ + if (!err) { + /* + * However, the given key does not exist in the TNC + * tree and @znode/@n variables contain the closest + * "preceding" element. Switch to the next one. + */ + err = tnc_next(c, &znode, &n); + if (err) + goto out_unlock; + } + } + + zbr = &znode->zbranch[n]; + dent = kmalloc(zbr->len, GFP_NOFS); + if (unlikely(!dent)) { + err = -ENOMEM; + goto out_unlock; + } + + /* + * The above 'tnc_next()' call could lead us to the next inode, check + * this. + */ + dkey = &zbr->key; + if (key_inum(c, dkey) != key_inum(c, key) || + key_type(c, dkey) != type) { + err = -ENOENT; + goto out_free; + } + + err = tnc_read_node_nm(c, zbr, dent); + if (unlikely(err)) + goto out_free; + + mutex_unlock(&c->tnc_mutex); + return dent; + +out_free: + kfree(dent); +out_unlock: + mutex_unlock(&c->tnc_mutex); + return ERR_PTR(err); +} + +/** + * tnc_destroy_cnext - destroy left-over obsolete znodes from a failed commit. + * @c: UBIFS file-system description object + * + * Destroy left-over obsolete znodes from a failed commit. + */ +static void tnc_destroy_cnext(struct ubifs_info *c) +{ + struct ubifs_znode *cnext; + + if (!c->cnext) + return; + ubifs_assert(c->cmt_state == COMMIT_BROKEN); + cnext = c->cnext; + do { + struct ubifs_znode *znode = cnext; + + cnext = cnext->cnext; + if (test_bit(OBSOLETE_ZNODE, &znode->flags)) + kfree(znode); + } while (cnext && cnext != c->cnext); +} + +/** + * ubifs_tnc_close - close TNC subsystem and free all related resources. + * @c: UBIFS file-system description object + */ +void ubifs_tnc_close(struct ubifs_info *c) +{ + long clean_freed; + + tnc_destroy_cnext(c); + if (c->zroot.znode) { + clean_freed = ubifs_destroy_tnc_subtree(c->zroot.znode); + atomic_long_sub(clean_freed, &ubifs_clean_zn_cnt); + } + kfree(c->gap_lebs); + kfree(c->ilebs); + destroy_old_idx(c); +} + +/** + * left_znode - get the znode to the left. + * @c: UBIFS file-system description object + * @znode: znode + * + * This function returns a pointer to the znode to the left of @znode or NULL if + * there is not one. A negative error code is returned on failure. + */ +static struct ubifs_znode *left_znode(struct ubifs_info *c, + struct ubifs_znode *znode) +{ + int level = znode->level; + + while (1) { + int n = znode->iip - 1; + + /* Go up until we can go left */ + znode = znode->parent; + if (!znode) + return NULL; + if (n >= 0) { + /* Now go down the rightmost branch to 'level' */ + znode = get_znode(c, znode, n); + if (IS_ERR(znode)) + return znode; + while (znode->level != level) { + n = znode->child_cnt - 1; + znode = get_znode(c, znode, n); + if (IS_ERR(znode)) + return znode; + } + break; + } + } + return znode; +} + +/** + * right_znode - get the znode to the right. + * @c: UBIFS file-system description object + * @znode: znode + * + * This function returns a pointer to the znode to the right of @znode or NULL + * if there is not one. A negative error code is returned on failure. + */ +static struct ubifs_znode *right_znode(struct ubifs_info *c, + struct ubifs_znode *znode) +{ + int level = znode->level; + + while (1) { + int n = znode->iip + 1; + + /* Go up until we can go right */ + znode = znode->parent; + if (!znode) + return NULL; + if (n < znode->child_cnt) { + /* Now go down the leftmost branch to 'level' */ + znode = get_znode(c, znode, n); + if (IS_ERR(znode)) + return znode; + while (znode->level != level) { + znode = get_znode(c, znode, 0); + if (IS_ERR(znode)) + return znode; + } + break; + } + } + return znode; +} + +/** + * lookup_znode - find a particular indexing node from TNC. + * @c: UBIFS file-system description object + * @key: index node key to lookup + * @level: index node level + * @lnum: index node LEB number + * @offs: index node offset + * + * This function searches an indexing node by its first key @key and its + * address @lnum:@offs. It looks up the indexing tree by pulling all indexing + * nodes it traverses to TNC. This function is called fro indexing nodes which + * were found on the media by scanning, for example when garbage-collecting or + * when doing in-the-gaps commit. This means that the indexing node which is + * looked for does not have to have exactly the same leftmost key @key, because + * the leftmost key may have been changed, in which case TNC will contain a + * dirty znode which still refers the same @lnum:@offs. This function is clever + * enough to recognize such indexing nodes. + * + * Note, if a znode was deleted or changed too much, then this function will + * not find it. For situations like this UBIFS has the old index RB-tree + * (indexed by @lnum:@offs). + * + * This function returns a pointer to the znode found or %NULL if it is not + * found. A negative error code is returned on failure. + */ +static struct ubifs_znode *lookup_znode(struct ubifs_info *c, + union ubifs_key *key, int level, + int lnum, int offs) +{ + struct ubifs_znode *znode, *zn; + int n, nn; + + /* + * The arguments have probably been read off flash, so don't assume + * they are valid. + */ + if (level < 0) + return ERR_PTR(-EINVAL); + + /* Get the root znode */ + znode = c->zroot.znode; + if (!znode) { + znode = ubifs_load_znode(c, &c->zroot, NULL, 0); + if (IS_ERR(znode)) + return znode; + } + /* Check if it is the one we are looking for */ + if (c->zroot.lnum == lnum && c->zroot.offs == offs) + return znode; + /* Descend to the parent level i.e. (level + 1) */ + if (level >= znode->level) + return NULL; + while (1) { + ubifs_search_zbranch(c, znode, key, &n); + if (n < 0) { + /* + * We reached a znode where the leftmost key is greater + * than the key we are searching for. This is the same + * situation as the one described in a huge comment at + * the end of the 'ubifs_lookup_level0()' function. And + * for exactly the same reasons we have to try to look + * left before giving up. + */ + znode = left_znode(c, znode); + if (!znode) + return NULL; + if (IS_ERR(znode)) + return znode; + ubifs_search_zbranch(c, znode, key, &n); + ubifs_assert(n >= 0); + } + if (znode->level == level + 1) + break; + znode = get_znode(c, znode, n); + if (IS_ERR(znode)) + return znode; + } + /* Check if the child is the one we are looking for */ + if (znode->zbranch[n].lnum == lnum && znode->zbranch[n].offs == offs) + return get_znode(c, znode, n); + /* If the key is unique, there is nowhere else to look */ + if (!is_hash_key(c, key)) + return NULL; + /* + * The key is not unique and so may be also in the znodes to either + * side. + */ + zn = znode; + nn = n; + /* Look left */ + while (1) { + /* Move one branch to the left */ + if (n) + n -= 1; + else { + znode = left_znode(c, znode); + if (!znode) + break; + if (IS_ERR(znode)) + return znode; + n = znode->child_cnt - 1; + } + /* Check it */ + if (znode->zbranch[n].lnum == lnum && + znode->zbranch[n].offs == offs) + return get_znode(c, znode, n); + /* Stop if the key is less than the one we are looking for */ + if (keys_cmp(c, &znode->zbranch[n].key, key) < 0) + break; + } + /* Back to the middle */ + znode = zn; + n = nn; + /* Look right */ + while (1) { + /* Move one branch to the right */ + if (++n >= znode->child_cnt) { + znode = right_znode(c, znode); + if (!znode) + break; + if (IS_ERR(znode)) + return znode; + n = 0; + } + /* Check it */ + if (znode->zbranch[n].lnum == lnum && + znode->zbranch[n].offs == offs) + return get_znode(c, znode, n); + /* Stop if the key is greater than the one we are looking for */ + if (keys_cmp(c, &znode->zbranch[n].key, key) > 0) + break; + } + return NULL; +} + +/** + * is_idx_node_in_tnc - determine if an index node is in the TNC. + * @c: UBIFS file-system description object + * @key: key of index node + * @level: index node level + * @lnum: LEB number of index node + * @offs: offset of index node + * + * This function returns %0 if the index node is not referred to in the TNC, %1 + * if the index node is referred to in the TNC and the corresponding znode is + * dirty, %2 if an index node is referred to in the TNC and the corresponding + * znode is clean, and a negative error code in case of failure. + * + * Note, the @key argument has to be the key of the first child. Also note, + * this function relies on the fact that 0:0 is never a valid LEB number and + * offset for a main-area node. + */ +int is_idx_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs) +{ + struct ubifs_znode *znode; + + znode = lookup_znode(c, key, level, lnum, offs); + if (!znode) + return 0; + if (IS_ERR(znode)) + return PTR_ERR(znode); + + return ubifs_zn_dirty(znode) ? 1 : 2; +} + +/** + * is_leaf_node_in_tnc - determine if a non-indexing not is in the TNC. + * @c: UBIFS file-system description object + * @key: node key + * @lnum: node LEB number + * @offs: node offset + * + * This function returns %1 if the node is referred to in the TNC, %0 if it is + * not, and a negative error code in case of failure. + * + * Note, this function relies on the fact that 0:0 is never a valid LEB number + * and offset for a main-area node. + */ +static int is_leaf_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, + int lnum, int offs) +{ + struct ubifs_zbranch *zbr; + struct ubifs_znode *znode, *zn; + int n, found, err, nn; + const int unique = !is_hash_key(c, key); + + found = ubifs_lookup_level0(c, key, &znode, &n); + if (found < 0) + return found; /* Error code */ + if (!found) + return 0; + zbr = &znode->zbranch[n]; + if (lnum == zbr->lnum && offs == zbr->offs) + return 1; /* Found it */ + if (unique) + return 0; + /* + * Because the key is not unique, we have to look left + * and right as well + */ + zn = znode; + nn = n; + /* Look left */ + while (1) { + err = tnc_prev(c, &znode, &n); + if (err == -ENOENT) + break; + if (err) + return err; + if (keys_cmp(c, key, &znode->zbranch[n].key)) + break; + zbr = &znode->zbranch[n]; + if (lnum == zbr->lnum && offs == zbr->offs) + return 1; /* Found it */ + } + /* Look right */ + znode = zn; + n = nn; + while (1) { + err = tnc_next(c, &znode, &n); + if (err) { + if (err == -ENOENT) + return 0; + return err; + } + if (keys_cmp(c, key, &znode->zbranch[n].key)) + break; + zbr = &znode->zbranch[n]; + if (lnum == zbr->lnum && offs == zbr->offs) + return 1; /* Found it */ + } + return 0; +} + +/** + * ubifs_tnc_has_node - determine whether a node is in the TNC. + * @c: UBIFS file-system description object + * @key: node key + * @level: index node level (if it is an index node) + * @lnum: node LEB number + * @offs: node offset + * @is_idx: non-zero if the node is an index node + * + * This function returns %1 if the node is in the TNC, %0 if it is not, and a + * negative error code in case of failure. For index nodes, @key has to be the + * key of the first child. An index node is considered to be in the TNC only if + * the corresponding znode is clean or has not been loaded. + */ +int ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs, int is_idx) +{ + int err; + + mutex_lock(&c->tnc_mutex); + if (is_idx) { + err = is_idx_node_in_tnc(c, key, level, lnum, offs); + if (err < 0) + goto out_unlock; + if (err == 1) + /* The index node was found but it was dirty */ + err = 0; + else if (err == 2) + /* The index node was found and it was clean */ + err = 1; + else + BUG_ON(err != 0); + } else + err = is_leaf_node_in_tnc(c, key, lnum, offs); + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_dirty_idx_node - dirty an index node. + * @c: UBIFS file-system description object + * @key: index node key + * @level: index node level + * @lnum: index node LEB number + * @offs: index node offset + * + * This function loads and dirties an index node so that it can be garbage + * collected. The @key argument has to be the key of the first child. This + * function relies on the fact that 0:0 is never a valid LEB number and offset + * for a main-area node. Returns %0 on success and a negative error code on + * failure. + */ +int ubifs_dirty_idx_node(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs) +{ + struct ubifs_znode *znode; + int err = 0; + + mutex_lock(&c->tnc_mutex); + znode = lookup_znode(c, key, level, lnum, offs); + if (!znode) + goto out_unlock; + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + znode = dirty_cow_bottom_up(c, znode); + if (IS_ERR(znode)) { + err = PTR_ERR(znode); + goto out_unlock; + } + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c new file mode 100644 index 0000000..8117e65 --- /dev/null +++ b/fs/ubifs/tnc_commit.c @@ -0,0 +1,1103 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* This file implements TNC functions for committing */ + +#include "ubifs.h" + +/** + * make_idx_node - make an index node for fill-the-gaps method of TNC commit. + * @c: UBIFS file-system description object + * @idx: buffer in which to place new index node + * @znode: znode from which to make new index node + * @lnum: LEB number where new index node will be written + * @offs: offset where new index node will be written + * @len: length of new index node + */ +static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx, + struct ubifs_znode *znode, int lnum, int offs, int len) +{ + struct ubifs_znode *zp; + int i, err; + + /* Make index node */ + idx->ch.node_type = UBIFS_IDX_NODE; + idx->child_cnt = cpu_to_le16(znode->child_cnt); + idx->level = cpu_to_le16(znode->level); + for (i = 0; i < znode->child_cnt; i++) { + struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); + struct ubifs_zbranch *zbr = &znode->zbranch[i]; + + key_write_idx(c, &zbr->key, &br->key); + br->lnum = cpu_to_le32(zbr->lnum); + br->offs = cpu_to_le32(zbr->offs); + br->len = cpu_to_le32(zbr->len); + if (!zbr->lnum || !zbr->len) { + ubifs_err("bad ref in znode"); + dbg_dump_znode(c, znode); + if (zbr->znode) + dbg_dump_znode(c, zbr->znode); + } + } + ubifs_prepare_node(c, idx, len, 0); + +#ifdef CONFIG_UBIFS_FS_DEBUG + znode->lnum = lnum; + znode->offs = offs; + znode->len = len; +#endif + + err = insert_old_idx_znode(c, znode); + + /* Update the parent */ + zp = znode->parent; + if (zp) { + struct ubifs_zbranch *zbr; + + zbr = &zp->zbranch[znode->iip]; + zbr->lnum = lnum; + zbr->offs = offs; + zbr->len = len; + } else { + c->zroot.lnum = lnum; + c->zroot.offs = offs; + c->zroot.len = len; + } + c->calc_idx_sz += ALIGN(len, 8); + + atomic_long_dec(&c->dirty_zn_cnt); + + ubifs_assert(ubifs_zn_dirty(znode)); + ubifs_assert(test_bit(COW_ZNODE, &znode->flags)); + + __clear_bit(DIRTY_ZNODE, &znode->flags); + __clear_bit(COW_ZNODE, &znode->flags); + + return err; +} + +/** + * fill_gap - make index nodes in gaps in dirty index LEBs. + * @c: UBIFS file-system description object + * @lnum: LEB number that gap appears in + * @gap_start: offset of start of gap + * @gap_end: offset of end of gap + * @dirt: adds dirty space to this + * + * This function returns the number of index nodes written into the gap. + */ +static int fill_gap(struct ubifs_info *c, int lnum, int gap_start, int gap_end, + int *dirt) +{ + int len, gap_remains, gap_pos, written, pad_len; + + ubifs_assert((gap_start & 7) == 0); + ubifs_assert((gap_end & 7) == 0); + ubifs_assert(gap_end >= gap_start); + + gap_remains = gap_end - gap_start; + if (!gap_remains) + return 0; + gap_pos = gap_start; + written = 0; + while (c->enext) { + len = ubifs_idx_node_sz(c, c->enext->child_cnt); + if (len < gap_remains) { + struct ubifs_znode *znode = c->enext; + const int alen = ALIGN(len, 8); + int err; + + ubifs_assert(alen <= gap_remains); + err = make_idx_node(c, c->ileb_buf + gap_pos, znode, + lnum, gap_pos, len); + if (err) + return err; + gap_remains -= alen; + gap_pos += alen; + c->enext = znode->cnext; + if (c->enext == c->cnext) + c->enext = NULL; + written += 1; + } else + break; + } + if (gap_end == c->leb_size) { + c->ileb_len = ALIGN(gap_pos, c->min_io_size); + /* Pad to end of min_io_size */ + pad_len = c->ileb_len - gap_pos; + } else + /* Pad to end of gap */ + pad_len = gap_remains; + dbg_gc("LEB %d:%d to %d len %d nodes written %d wasted bytes %d", + lnum, gap_start, gap_end, gap_end - gap_start, written, pad_len); + ubifs_pad(c, c->ileb_buf + gap_pos, pad_len); + *dirt += pad_len; + return written; +} + +/** + * find_old_idx - find an index node obsoleted since the last commit start. + * @c: UBIFS file-system description object + * @lnum: LEB number of obsoleted index node + * @offs: offset of obsoleted index node + * + * Returns %1 if found and %0 otherwise. + */ +static int find_old_idx(struct ubifs_info *c, int lnum, int offs) +{ + struct ubifs_old_idx *o; + struct rb_node *p; + + p = c->old_idx.rb_node; + while (p) { + o = rb_entry(p, struct ubifs_old_idx, rb); + if (lnum < o->lnum) + p = p->rb_left; + else if (lnum > o->lnum) + p = p->rb_right; + else if (offs < o->offs) + p = p->rb_left; + else if (offs > o->offs) + p = p->rb_right; + else + return 1; + } + return 0; +} + +/** + * is_idx_node_in_use - determine if an index node can be overwritten. + * @c: UBIFS file-system description object + * @key: key of index node + * @level: index node level + * @lnum: LEB number of index node + * @offs: offset of index node + * + * If @key / @lnum / @offs identify an index node that was not part of the old + * index, then this function returns %0 (obsolete). Else if the index node was + * part of the old index but is now dirty %1 is returned, else if it is clean %2 + * is returned. A negative error code is returned on failure. + */ +static int is_idx_node_in_use(struct ubifs_info *c, union ubifs_key *key, + int level, int lnum, int offs) +{ + int ret; + + ret = is_idx_node_in_tnc(c, key, level, lnum, offs); + if (ret < 0) + return ret; /* Error code */ + if (ret == 0) + if (find_old_idx(c, lnum, offs)) + return 1; + return ret; +} + +/** + * layout_leb_in_gaps - layout index nodes using in-the-gaps method. + * @c: UBIFS file-system description object + * @p: return LEB number here + * + * This function lays out new index nodes for dirty znodes using in-the-gaps + * method of TNC commit. + * This function merely puts the next znode into the next gap, making no attempt + * to try to maximise the number of znodes that fit. + * This function returns the number of index nodes written into the gaps, or a + * negative error code on failure. + */ +static int layout_leb_in_gaps(struct ubifs_info *c, int *p) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + int lnum, dirt = 0, gap_start, gap_end, err, written, tot_written; + + tot_written = 0; + /* Get an index LEB with lots of obsolete index nodes */ + lnum = ubifs_find_dirty_idx_leb(c); + if (lnum < 0) + /* + * There also may be dirt in the index head that could be + * filled, however we do not check there at present. + */ + return lnum; /* Error code */ + *p = lnum; + dbg_gc("LEB %d", lnum); + /* + * Scan the index LEB. We use the generic scan for this even though + * it is more comprehensive and less efficient than is needed for this + * purpose. + */ + sleb = ubifs_scan(c, lnum, 0, c->ileb_buf); + c->ileb_len = 0; + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + gap_start = 0; + list_for_each_entry(snod, &sleb->nodes, list) { + struct ubifs_idx_node *idx; + int in_use, level; + + ubifs_assert(snod->type == UBIFS_IDX_NODE); + idx = snod->node; + key_read(c, ubifs_idx_key(c, idx), &snod->key); + level = le16_to_cpu(idx->level); + /* Determine if the index node is in use (not obsolete) */ + in_use = is_idx_node_in_use(c, &snod->key, level, lnum, + snod->offs); + if (in_use < 0) { + ubifs_scan_destroy(sleb); + return in_use; /* Error code */ + } + if (in_use) { + if (in_use == 1) + dirt += ALIGN(snod->len, 8); + /* + * The obsolete index nodes form gaps that can be + * overwritten. This gap has ended because we have + * found an index node that is still in use + * i.e. not obsolete + */ + gap_end = snod->offs; + /* Try to fill gap */ + written = fill_gap(c, lnum, gap_start, gap_end, &dirt); + if (written < 0) { + ubifs_scan_destroy(sleb); + return written; /* Error code */ + } + tot_written += written; + gap_start = ALIGN(snod->offs + snod->len, 8); + } + } + ubifs_scan_destroy(sleb); + c->ileb_len = c->leb_size; + gap_end = c->leb_size; + /* Try to fill gap */ + written = fill_gap(c, lnum, gap_start, gap_end, &dirt); + if (written < 0) + return written; /* Error code */ + tot_written += written; + if (tot_written == 0) { + struct ubifs_lprops lp; + + dbg_gc("LEB %d wrote %d index nodes", lnum, tot_written); + err = ubifs_read_one_lp(c, lnum, &lp); + if (err) + return err; + if (lp.free == c->leb_size) { + /* + * We must have snatched this LEB from the idx_gc list + * so we need to correct the free and dirty space. + */ + err = ubifs_change_one_lp(c, lnum, + c->leb_size - c->ileb_len, + dirt, 0, 0, 0); + if (err) + return err; + } + return 0; + } + err = ubifs_change_one_lp(c, lnum, c->leb_size - c->ileb_len, dirt, + 0, 0, 0); + if (err) + return err; + err = ubifs_leb_change(c, lnum, c->ileb_buf, c->ileb_len, + UBI_SHORTTERM); + if (err) + return err; + dbg_gc("LEB %d wrote %d index nodes", lnum, tot_written); + return tot_written; +} + +/** + * get_leb_cnt - calculate the number of empty LEBs needed to commit. + * @c: UBIFS file-system description object + * @cnt: number of znodes to commit + * + * This function returns the number of empty LEBs needed to commit @cnt znodes + * to the current index head. The number is not exact and may be more than + * needed. + */ +static int get_leb_cnt(struct ubifs_info *c, int cnt) +{ + int d; + + /* Assume maximum index node size (i.e. overestimate space needed) */ + cnt -= (c->leb_size - c->ihead_offs) / c->max_idx_node_sz; + if (cnt < 0) + cnt = 0; + d = c->leb_size / c->max_idx_node_sz; + return DIV_ROUND_UP(cnt, d); +} + +/** + * layout_in_gaps - in-the-gaps method of committing TNC. + * @c: UBIFS file-system description object + * @cnt: number of dirty znodes to commit. + * + * This function lays out new index nodes for dirty znodes using in-the-gaps + * method of TNC commit. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int layout_in_gaps(struct ubifs_info *c, int cnt) +{ + int err, leb_needed_cnt, written, *p; + + dbg_gc("%d znodes to write", cnt); + + c->gap_lebs = kmalloc(sizeof(int) * (c->lst.idx_lebs + 1), GFP_NOFS); + if (!c->gap_lebs) + return -ENOMEM; + + p = c->gap_lebs; + do { + ubifs_assert(p < c->gap_lebs + sizeof(int) * c->lst.idx_lebs); + written = layout_leb_in_gaps(c, p); + if (written < 0) { + err = written; + if (err == -ENOSPC) { + if (!dbg_force_in_the_gaps_enabled) { + /* + * Do not print scary warnings if the + * debugging option which forces + * in-the-gaps is enabled. + */ + ubifs_err("out of space"); + spin_lock(&c->space_lock); + dbg_dump_budg(c); + spin_unlock(&c->space_lock); + dbg_dump_lprops(c); + } + /* Try to commit anyway */ + err = 0; + break; + } + kfree(c->gap_lebs); + c->gap_lebs = NULL; + return err; + } + p++; + cnt -= written; + leb_needed_cnt = get_leb_cnt(c, cnt); + dbg_gc("%d znodes remaining, need %d LEBs, have %d", cnt, + leb_needed_cnt, c->ileb_cnt); + } while (leb_needed_cnt > c->ileb_cnt); + + *p = -1; + return 0; +} + +/** + * layout_in_empty_space - layout index nodes in empty space. + * @c: UBIFS file-system description object + * + * This function lays out new index nodes for dirty znodes using empty LEBs. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int layout_in_empty_space(struct ubifs_info *c) +{ + struct ubifs_znode *znode, *cnext, *zp; + int lnum, offs, len, next_len, buf_len, buf_offs, used, avail; + int wlen, blen, err; + + cnext = c->enext; + if (!cnext) + return 0; + + lnum = c->ihead_lnum; + buf_offs = c->ihead_offs; + + buf_len = ubifs_idx_node_sz(c, c->fanout); + buf_len = ALIGN(buf_len, c->min_io_size); + used = 0; + avail = buf_len; + + /* Ensure there is enough room for first write */ + next_len = ubifs_idx_node_sz(c, cnext->child_cnt); + if (buf_offs + next_len > c->leb_size) + lnum = -1; + + while (1) { + znode = cnext; + + len = ubifs_idx_node_sz(c, znode->child_cnt); + + /* Determine the index node position */ + if (lnum == -1) { + if (c->ileb_nxt >= c->ileb_cnt) { + ubifs_err("out of space"); + return -ENOSPC; + } + lnum = c->ilebs[c->ileb_nxt++]; + buf_offs = 0; + used = 0; + avail = buf_len; + } + + offs = buf_offs + used; + +#ifdef CONFIG_UBIFS_FS_DEBUG + znode->lnum = lnum; + znode->offs = offs; + znode->len = len; +#endif + + /* Update the parent */ + zp = znode->parent; + if (zp) { + struct ubifs_zbranch *zbr; + int i; + + i = znode->iip; + zbr = &zp->zbranch[i]; + zbr->lnum = lnum; + zbr->offs = offs; + zbr->len = len; + } else { + c->zroot.lnum = lnum; + c->zroot.offs = offs; + c->zroot.len = len; + } + c->calc_idx_sz += ALIGN(len, 8); + + /* + * Once lprops is updated, we can decrease the dirty znode count + * but it is easier to just do it here. + */ + atomic_long_dec(&c->dirty_zn_cnt); + + /* + * Calculate the next index node length to see if there is + * enough room for it + */ + cnext = znode->cnext; + if (cnext == c->cnext) + next_len = 0; + else + next_len = ubifs_idx_node_sz(c, cnext->child_cnt); + + if (c->min_io_size == 1) { + buf_offs += ALIGN(len, 8); + if (next_len) { + if (buf_offs + next_len <= c->leb_size) + continue; + err = ubifs_update_one_lp(c, lnum, 0, + c->leb_size - buf_offs, 0, 0); + if (err) + return err; + lnum = -1; + continue; + } + err = ubifs_update_one_lp(c, lnum, + c->leb_size - buf_offs, 0, 0, 0); + if (err) + return err; + break; + } + + /* Update buffer positions */ + wlen = used + len; + used += ALIGN(len, 8); + avail -= ALIGN(len, 8); + + if (next_len != 0 && + buf_offs + used + next_len <= c->leb_size && + avail > 0) + continue; + + if (avail <= 0 && next_len && + buf_offs + used + next_len <= c->leb_size) + blen = buf_len; + else + blen = ALIGN(wlen, c->min_io_size); + + /* The buffer is full or there are no more znodes to do */ + buf_offs += blen; + if (next_len) { + if (buf_offs + next_len > c->leb_size) { + err = ubifs_update_one_lp(c, lnum, + c->leb_size - buf_offs, blen - used, + 0, 0); + if (err) + return err; + lnum = -1; + } + used -= blen; + if (used < 0) + used = 0; + avail = buf_len - used; + continue; + } + err = ubifs_update_one_lp(c, lnum, c->leb_size - buf_offs, + blen - used, 0, 0); + if (err) + return err; + break; + } + +#ifdef CONFIG_UBIFS_FS_DEBUG + c->new_ihead_lnum = lnum; + c->new_ihead_offs = buf_offs; +#endif + + return 0; +} + +/** + * layout_commit - determine positions of index nodes to commit. + * @c: UBIFS file-system description object + * @no_space: indicates that insufficient empty LEBs were allocated + * @cnt: number of znodes to commit + * + * Calculate and update the positions of index nodes to commit. If there were + * an insufficient number of empty LEBs allocated, then index nodes are placed + * into the gaps created by obsolete index nodes in non-empty index LEBs. For + * this purpose, an obsolete index node is one that was not in the index as at + * the end of the last commit. To write "in-the-gaps" requires that those index + * LEBs are updated atomically in-place. + */ +static int layout_commit(struct ubifs_info *c, int no_space, int cnt) +{ + int err; + + if (no_space) { + err = layout_in_gaps(c, cnt); + if (err) + return err; + } + err = layout_in_empty_space(c); + return err; +} + +/** + * find_first_dirty - find first dirty znode. + * @znode: znode to begin searching from + */ +static struct ubifs_znode *find_first_dirty(struct ubifs_znode *znode) +{ + int i, cont; + + if (!znode) + return NULL; + + while (1) { + if (znode->level == 0) { + if (ubifs_zn_dirty(znode)) + return znode; + return NULL; + } + cont = 0; + for (i = 0; i < znode->child_cnt; i++) { + struct ubifs_zbranch *zbr = &znode->zbranch[i]; + + if (zbr->znode && ubifs_zn_dirty(zbr->znode)) { + znode = zbr->znode; + cont = 1; + break; + } + } + if (!cont) { + if (ubifs_zn_dirty(znode)) + return znode; + return NULL; + } + } +} + +/** + * find_next_dirty - find next dirty znode. + * @znode: znode to begin searching from + */ +static struct ubifs_znode *find_next_dirty(struct ubifs_znode *znode) +{ + int n = znode->iip + 1; + + znode = znode->parent; + if (!znode) + return NULL; + for (; n < znode->child_cnt; n++) { + struct ubifs_zbranch *zbr = &znode->zbranch[n]; + + if (zbr->znode && ubifs_zn_dirty(zbr->znode)) + return find_first_dirty(zbr->znode); + } + return znode; +} + +/** + * get_znodes_to_commit - create list of dirty znodes to commit. + * @c: UBIFS file-system description object + * + * This function returns the number of znodes to commit. + */ +static int get_znodes_to_commit(struct ubifs_info *c) +{ + struct ubifs_znode *znode, *cnext; + int cnt = 0; + + c->cnext = find_first_dirty(c->zroot.znode); + znode = c->enext = c->cnext; + if (!znode) { + dbg_cmt("no znodes to commit"); + return 0; + } + cnt += 1; + while (1) { + ubifs_assert(!test_bit(COW_ZNODE, &znode->flags)); + __set_bit(COW_ZNODE, &znode->flags); + znode->alt = 0; + cnext = find_next_dirty(znode); + if (!cnext) { + znode->cnext = c->cnext; + break; + } + znode->cnext = cnext; + znode = cnext; + cnt += 1; + } + dbg_cmt("committing %d znodes", cnt); + ubifs_assert(cnt == atomic_long_read(&c->dirty_zn_cnt)); + return cnt; +} + +/** + * alloc_idx_lebs - allocate empty LEBs to be used to commit. + * @c: UBIFS file-system description object + * @cnt: number of znodes to commit + * + * This function returns %-ENOSPC if it cannot allocate a sufficient number of + * empty LEBs. %0 is returned on success, otherwise a negative error code + * is returned. + */ +static int alloc_idx_lebs(struct ubifs_info *c, int cnt) +{ + int i, leb_cnt, lnum; + + c->ileb_cnt = 0; + c->ileb_nxt = 0; + leb_cnt = get_leb_cnt(c, cnt); + dbg_cmt("need about %d empty LEBS for TNC commit", leb_cnt); + if (!leb_cnt) + return 0; + c->ilebs = kmalloc(leb_cnt * sizeof(int), GFP_NOFS); + if (!c->ilebs) + return -ENOMEM; + for (i = 0; i < leb_cnt; i++) { + lnum = ubifs_find_free_leb_for_idx(c); + if (lnum < 0) + return lnum; + c->ilebs[c->ileb_cnt++] = lnum; + dbg_cmt("LEB %d", lnum); + } + if (dbg_force_in_the_gaps()) + return -ENOSPC; + return 0; +} + +/** + * free_unused_idx_lebs - free unused LEBs that were allocated for the commit. + * @c: UBIFS file-system description object + * + * It is possible that we allocate more empty LEBs for the commit than we need. + * This functions frees the surplus. + * + * This function returns %0 on success and a negative error code on failure. + */ +static int free_unused_idx_lebs(struct ubifs_info *c) +{ + int i, err = 0, lnum, er; + + for (i = c->ileb_nxt; i < c->ileb_cnt; i++) { + lnum = c->ilebs[i]; + dbg_cmt("LEB %d", lnum); + er = ubifs_change_one_lp(c, lnum, LPROPS_NC, LPROPS_NC, 0, + LPROPS_INDEX | LPROPS_TAKEN, 0); + if (!err) + err = er; + } + return err; +} + +/** + * free_idx_lebs - free unused LEBs after commit end. + * @c: UBIFS file-system description object + * + * This function returns %0 on success and a negative error code on failure. + */ +static int free_idx_lebs(struct ubifs_info *c) +{ + int err; + + err = free_unused_idx_lebs(c); + kfree(c->ilebs); + c->ilebs = NULL; + return err; +} + +/** + * ubifs_tnc_start_commit - start TNC commit. + * @c: UBIFS file-system description object + * @zroot: new index root position is returned here + * + * This function prepares the list of indexing nodes to commit and lays out + * their positions on flash. If there is not enough free space it uses the + * in-gap commit method. Returns zero in case of success and a negative error + * code in case of failure. + */ +int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot) +{ + int err = 0, cnt; + + mutex_lock(&c->tnc_mutex); + err = dbg_check_tnc(c, 1); + if (err) + goto out; + cnt = get_znodes_to_commit(c); + if (cnt != 0) { + int no_space = 0; + + err = alloc_idx_lebs(c, cnt); + if (err == -ENOSPC) + no_space = 1; + else if (err) + goto out_free; + err = layout_commit(c, no_space, cnt); + if (err) + goto out_free; + ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0); + err = free_unused_idx_lebs(c); + if (err) + goto out; + } + destroy_old_idx(c); + memcpy(zroot, &c->zroot, sizeof(struct ubifs_zbranch)); + + err = ubifs_save_dirty_idx_lnums(c); + if (err) + goto out; + + spin_lock(&c->space_lock); + /* + * Although we have not finished committing yet, update size of the + * committed index ('c->old_idx_sz') and zero out the index growth + * budget. It is OK to do this now, because we've reserved all the + * space which is needed to commit the index, and it is save for the + * budgeting subsystem to assume the index is already committed, + * even though it is not. + */ + c->old_idx_sz = c->calc_idx_sz; + c->budg_uncommitted_idx = 0; + spin_unlock(&c->space_lock); + mutex_unlock(&c->tnc_mutex); + + dbg_cmt("number of index LEBs %d", c->lst.idx_lebs); + dbg_cmt("size of index %llu", c->calc_idx_sz); + return err; + +out_free: + free_idx_lebs(c); +out: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * write_index - write index nodes. + * @c: UBIFS file-system description object + * + * This function writes the index nodes whose positions were laid out in the + * layout_in_empty_space function. + */ +static int write_index(struct ubifs_info *c) +{ + struct ubifs_idx_node *idx; + struct ubifs_znode *znode, *cnext; + int i, lnum, offs, len, next_len, buf_len, buf_offs, used; + int avail, wlen, err, lnum_pos = 0; + + cnext = c->enext; + if (!cnext) + return 0; + + /* + * Always write index nodes to the index head so that index nodes and + * other types of nodes are never mixed in the same erase block. + */ + lnum = c->ihead_lnum; + buf_offs = c->ihead_offs; + + /* Allocate commit buffer */ + buf_len = ALIGN(c->max_idx_node_sz, c->min_io_size); + used = 0; + avail = buf_len; + + /* Ensure there is enough room for first write */ + next_len = ubifs_idx_node_sz(c, cnext->child_cnt); + if (buf_offs + next_len > c->leb_size) { + err = ubifs_update_one_lp(c, lnum, LPROPS_NC, 0, 0, + LPROPS_TAKEN); + if (err) + return err; + lnum = -1; + } + + while (1) { + cond_resched(); + + znode = cnext; + idx = c->cbuf + used; + + /* Make index node */ + idx->ch.node_type = UBIFS_IDX_NODE; + idx->child_cnt = cpu_to_le16(znode->child_cnt); + idx->level = cpu_to_le16(znode->level); + for (i = 0; i < znode->child_cnt; i++) { + struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); + struct ubifs_zbranch *zbr = &znode->zbranch[i]; + + key_write_idx(c, &zbr->key, &br->key); + br->lnum = cpu_to_le32(zbr->lnum); + br->offs = cpu_to_le32(zbr->offs); + br->len = cpu_to_le32(zbr->len); + if (!zbr->lnum || !zbr->len) { + ubifs_err("bad ref in znode"); + dbg_dump_znode(c, znode); + if (zbr->znode) + dbg_dump_znode(c, zbr->znode); + } + } + len = ubifs_idx_node_sz(c, znode->child_cnt); + ubifs_prepare_node(c, idx, len, 0); + + /* Determine the index node position */ + if (lnum == -1) { + lnum = c->ilebs[lnum_pos++]; + buf_offs = 0; + used = 0; + avail = buf_len; + } + offs = buf_offs + used; + +#ifdef CONFIG_UBIFS_FS_DEBUG + if (lnum != znode->lnum || offs != znode->offs || + len != znode->len) { + ubifs_err("inconsistent znode posn"); + return -EINVAL; + } +#endif + + /* Grab some stuff from znode while we still can */ + cnext = znode->cnext; + + ubifs_assert(ubifs_zn_dirty(znode)); + ubifs_assert(test_bit(COW_ZNODE, &znode->flags)); + + /* + * It is important that other threads should see %DIRTY_ZNODE + * flag cleared before %COW_ZNODE. Specifically, it matters in + * the 'dirty_cow_znode()' function. This is the reason for the + * first barrier. Also, we want the bit changes to be seen to + * other threads ASAP, to avoid unnecesarry copying, which is + * the reason for the second barrier. + */ + clear_bit(DIRTY_ZNODE, &znode->flags); + smp_mb__before_clear_bit(); + clear_bit(COW_ZNODE, &znode->flags); + smp_mb__after_clear_bit(); + + /* Do not access znode from this point on */ + + /* Update buffer positions */ + wlen = used + len; + used += ALIGN(len, 8); + avail -= ALIGN(len, 8); + + /* + * Calculate the next index node length to see if there is + * enough room for it + */ + if (cnext == c->cnext) + next_len = 0; + else + next_len = ubifs_idx_node_sz(c, cnext->child_cnt); + + if (c->min_io_size == 1) { + /* + * Write the prepared index node immediately if there is + * no minimum IO size + */ + err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, + wlen, UBI_SHORTTERM); + if (err) + return err; + buf_offs += ALIGN(wlen, 8); + if (next_len) { + used = 0; + avail = buf_len; + if (buf_offs + next_len > c->leb_size) { + err = ubifs_update_one_lp(c, lnum, + LPROPS_NC, 0, 0, LPROPS_TAKEN); + if (err) + return err; + lnum = -1; + } + continue; + } + } else { + int blen, nxt_offs = buf_offs + used + next_len; + + if (next_len && nxt_offs <= c->leb_size) { + if (avail > 0) + continue; + else + blen = buf_len; + } else { + wlen = ALIGN(wlen, 8); + blen = ALIGN(wlen, c->min_io_size); + ubifs_pad(c, c->cbuf + wlen, blen - wlen); + } + /* + * The buffer is full or there are no more znodes + * to do + */ + err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, + blen, UBI_SHORTTERM); + if (err) + return err; + buf_offs += blen; + if (next_len) { + if (nxt_offs > c->leb_size) { + err = ubifs_update_one_lp(c, lnum, + LPROPS_NC, 0, 0, LPROPS_TAKEN); + if (err) + return err; + lnum = -1; + } + used -= blen; + if (used < 0) + used = 0; + avail = buf_len - used; + memmove(c->cbuf, c->cbuf + blen, used); + continue; + } + } + break; + } + +#ifdef CONFIG_UBIFS_FS_DEBUG + if (lnum != c->new_ihead_lnum || buf_offs != c->new_ihead_offs) { + ubifs_err("inconsistent ihead"); + return -EINVAL; + } +#endif + + c->ihead_lnum = lnum; + c->ihead_offs = buf_offs; + + return 0; +} + +/** + * free_obsolete_znodes - free obsolete znodes. + * @c: UBIFS file-system description object + * + * At the end of commit end, obsolete znodes are freed. + */ +static void free_obsolete_znodes(struct ubifs_info *c) +{ + struct ubifs_znode *znode, *cnext; + + cnext = c->cnext; + do { + znode = cnext; + cnext = znode->cnext; + if (test_bit(OBSOLETE_ZNODE, &znode->flags)) + kfree(znode); + else { + znode->cnext = NULL; + atomic_long_inc(&c->clean_zn_cnt); + atomic_long_inc(&ubifs_clean_zn_cnt); + } + } while (cnext != c->cnext); +} + +/** + * return_gap_lebs - return LEBs used by the in-gap commit method. + * @c: UBIFS file-system description object + * + * This function clears the "taken" flag for the LEBs which were used by the + * "commit in-the-gaps" method. + */ +static int return_gap_lebs(struct ubifs_info *c) +{ + int *p, err; + + if (!c->gap_lebs) + return 0; + + dbg_cmt(""); + for (p = c->gap_lebs; *p != -1; p++) { + err = ubifs_change_one_lp(c, *p, LPROPS_NC, LPROPS_NC, 0, + LPROPS_TAKEN, 0); + if (err) + return err; + } + + kfree(c->gap_lebs); + c->gap_lebs = NULL; + return 0; +} + +/** + * ubifs_tnc_end_commit - update the TNC for commit end. + * @c: UBIFS file-system description object + * + * Write the dirty znodes. + */ +int ubifs_tnc_end_commit(struct ubifs_info *c) +{ + int err; + + if (!c->cnext) + return 0; + + err = return_gap_lebs(c); + if (err) + return err; + + err = write_index(c); + if (err) + return err; + + mutex_lock(&c->tnc_mutex); + + dbg_cmt("TNC height is %d", c->zroot.znode->level + 1); + + free_obsolete_znodes(c); + + c->cnext = NULL; + kfree(c->ilebs); + c->ilebs = NULL; + + mutex_unlock(&c->tnc_mutex); + + return 0; +} diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c new file mode 100644 index 0000000..a25c1cc --- /dev/null +++ b/fs/ubifs/tnc_misc.c @@ -0,0 +1,494 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file contains miscelanious TNC-related functions shared betweend + * different files. This file does not form any logically separate TNC + * sub-system. The file was created because there is a lot of TNC code and + * putting it all in one file would make that file too big and unreadable. + */ + +#include "ubifs.h" + +/** + * ubifs_tnc_levelorder_next - next TNC tree element in levelorder traversal. + * @zr: root of the subtree to traverse + * @znode: previous znode + * + * This function implements levelorder TNC traversal. The LNC is ignored. + * Returns the next element or %NULL if @znode is already the last one. + */ +struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr, + struct ubifs_znode *znode) +{ + int level, iip, level_search = 0; + struct ubifs_znode *zn; + + ubifs_assert(zr); + + if (unlikely(!znode)) + return zr; + + if (unlikely(znode == zr)) { + if (znode->level == 0) + return NULL; + return ubifs_tnc_find_child(zr, 0); + } + + level = znode->level; + + iip = znode->iip; + while (1) { + ubifs_assert(znode->level <= zr->level); + + /* + * First walk up until there is a znode with next branch to + * look at. + */ + while (znode->parent != zr && iip >= znode->parent->child_cnt) { + znode = znode->parent; + iip = znode->iip; + } + + if (unlikely(znode->parent == zr && + iip >= znode->parent->child_cnt)) { + /* This level is done, switch to the lower one */ + level -= 1; + if (level_search || level < 0) + /* + * We were already looking for znode at lower + * level ('level_search'). As we are here + * again, it just does not exist. Or all levels + * were finished ('level < 0'). + */ + return NULL; + + level_search = 1; + iip = -1; + znode = ubifs_tnc_find_child(zr, 0); + ubifs_assert(znode); + } + + /* Switch to the next index */ + zn = ubifs_tnc_find_child(znode->parent, iip + 1); + if (!zn) { + /* No more children to look at, we have walk up */ + iip = znode->parent->child_cnt; + continue; + } + + /* Walk back down to the level we came from ('level') */ + while (zn->level != level) { + znode = zn; + zn = ubifs_tnc_find_child(zn, 0); + if (!zn) { + /* + * This path is not too deep so it does not + * reach 'level'. Try next path. + */ + iip = znode->iip; + break; + } + } + + if (zn) { + ubifs_assert(zn->level >= 0); + return zn; + } + } +} + +/** + * ubifs_search_zbranch - search znode branch. + * @c: UBIFS file-system description object + * @znode: znode to search in + * @key: key to search for + * @n: znode branch slot number is returned here + * + * This is a helper function which search branch with key @key in @znode using + * binary search. The result of the search may be: + * o exact match, then %1 is returned, and the slot number of the branch is + * stored in @n; + * o no exact match, then %0 is returned and the slot number of the left + * closest branch is returned in @n; the slot if all keys in this znode are + * greater than @key, then %-1 is returned in @n. + */ +int ubifs_search_zbranch(const struct ubifs_info *c, + const struct ubifs_znode *znode, + const union ubifs_key *key, int *n) +{ + int beg = 0, end = znode->child_cnt, uninitialized_var(mid); + int uninitialized_var(cmp); + const struct ubifs_zbranch *zbr = &znode->zbranch[0]; + + ubifs_assert(end > beg); + + while (end > beg) { + mid = (beg + end) >> 1; + cmp = keys_cmp(c, key, &zbr[mid].key); + if (cmp > 0) + beg = mid + 1; + else if (cmp < 0) + end = mid; + else { + *n = mid; + return 1; + } + } + + *n = end - 1; + + /* The insert point is after *n */ + ubifs_assert(*n >= -1 && *n < znode->child_cnt); + if (*n == -1) + ubifs_assert(keys_cmp(c, key, &zbr[0].key) < 0); + else + ubifs_assert(keys_cmp(c, key, &zbr[*n].key) > 0); + if (*n + 1 < znode->child_cnt) + ubifs_assert(keys_cmp(c, key, &zbr[*n + 1].key) < 0); + + return 0; +} + +/** + * ubifs_tnc_postorder_first - find first znode to do postorder tree traversal. + * @znode: znode to start at (root of the sub-tree to traverse) + * + * Find the lowest leftmost znode in a subtree of the TNC tree. The LNC is + * ignored. + */ +struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode) +{ + if (unlikely(!znode)) + return NULL; + + while (znode->level > 0) { + struct ubifs_znode *child; + + child = ubifs_tnc_find_child(znode, 0); + if (!child) + return znode; + znode = child; + } + + return znode; +} + +/** + * ubifs_tnc_postorder_next - next TNC tree element in postorder traversal. + * @znode: previous znode + * + * This function implements postorder TNC traversal. The LNC is ignored. + * Returns the next element or %NULL if @znode is already the last one. + */ +struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode) +{ + struct ubifs_znode *zn; + + ubifs_assert(znode); + if (unlikely(!znode->parent)) + return NULL; + + /* Switch to the next index in the parent */ + zn = ubifs_tnc_find_child(znode->parent, znode->iip + 1); + if (!zn) + /* This is in fact the last child, return parent */ + return znode->parent; + + /* Go to the first znode in this new subtree */ + return ubifs_tnc_postorder_first(zn); +} + +/** + * ubifs_destroy_tnc_subtree - destroy all znodes connected to a subtree. + * @znode: znode defining subtree to destroy + * + * This function destroys subtree of the TNC tree. Returns number of clean + * znodes in the subtree. + */ +long ubifs_destroy_tnc_subtree(struct ubifs_znode *znode) +{ + struct ubifs_znode *zn = ubifs_tnc_postorder_first(znode); + long clean_freed = 0; + int n; + + ubifs_assert(zn); + while (1) { + for (n = 0; n < zn->child_cnt; n++) { + if (!zn->zbranch[n].znode) + continue; + + if (zn->level > 0 && + !ubifs_zn_dirty(zn->zbranch[n].znode)) + clean_freed += 1; + + cond_resched(); + kfree(zn->zbranch[n].znode); + } + + if (zn == znode) { + if (!ubifs_zn_dirty(zn)) + clean_freed += 1; + kfree(zn); + return clean_freed; + } + + zn = ubifs_tnc_postorder_next(zn); + } +} + +/** + * read_znode - read an indexing node from flash and fill znode. + * @c: UBIFS file-system description object + * @lnum: LEB of the indexing node to read + * @offs: node offset + * @len: node length + * @znode: znode to read to + * + * This function reads an indexing node from the flash media and fills znode + * with the read data. Returns zero in case of success and a negative error + * code in case of failure. The read indexing node is validated and if anything + * is wrong with it, this function prints complaint messages and returns + * %-EINVAL. + */ +static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, + struct ubifs_znode *znode) +{ + int i, err, type, cmp; + struct ubifs_idx_node *idx; + + idx = kmalloc(c->max_idx_node_sz, GFP_NOFS); + if (!idx) + return -ENOMEM; + + err = ubifs_read_node(c, idx, UBIFS_IDX_NODE, len, lnum, offs); + if (err < 0) { + kfree(idx); + return err; + } + + znode->child_cnt = le16_to_cpu(idx->child_cnt); + znode->level = le16_to_cpu(idx->level); + + dbg_tnc("LEB %d:%d, level %d, %d branch", + lnum, offs, znode->level, znode->child_cnt); + + if (znode->child_cnt > c->fanout || znode->level > UBIFS_MAX_LEVELS) { + dbg_err("current fanout %d, branch count %d", + c->fanout, znode->child_cnt); + dbg_err("max levels %d, znode level %d", + UBIFS_MAX_LEVELS, znode->level); + err = 1; + goto out_dump; + } + + for (i = 0; i < znode->child_cnt; i++) { + const struct ubifs_branch *br = ubifs_idx_branch(c, idx, i); + struct ubifs_zbranch *zbr = &znode->zbranch[i]; + + key_read(c, &br->key, &zbr->key); + zbr->lnum = le32_to_cpu(br->lnum); + zbr->offs = le32_to_cpu(br->offs); + zbr->len = le32_to_cpu(br->len); + zbr->znode = NULL; + + /* Validate branch */ + + if (zbr->lnum < c->main_first || + zbr->lnum >= c->leb_cnt || zbr->offs < 0 || + zbr->offs + zbr->len > c->leb_size || zbr->offs & 7) { + dbg_err("bad branch %d", i); + err = 2; + goto out_dump; + } + + switch (key_type(c, &zbr->key)) { + case UBIFS_INO_KEY: + case UBIFS_DATA_KEY: + case UBIFS_DENT_KEY: + case UBIFS_XENT_KEY: + break; + default: + dbg_msg("bad key type at slot %d: %s", i, + DBGKEY(&zbr->key)); + err = 3; + goto out_dump; + } + + if (znode->level) + continue; + + type = key_type(c, &zbr->key); + if (c->ranges[type].max_len == 0) { + if (zbr->len != c->ranges[type].len) { + dbg_err("bad target node (type %d) length (%d)", + type, zbr->len); + dbg_err("have to be %d", c->ranges[type].len); + err = 4; + goto out_dump; + } + } else if (zbr->len < c->ranges[type].min_len || + zbr->len > c->ranges[type].max_len) { + dbg_err("bad target node (type %d) length (%d)", + type, zbr->len); + dbg_err("have to be in range of %d-%d", + c->ranges[type].min_len, + c->ranges[type].max_len); + err = 5; + goto out_dump; + } + } + + /* + * Ensure that the next key is greater or equivalent to the + * previous one. + */ + for (i = 0; i < znode->child_cnt - 1; i++) { + const union ubifs_key *key1, *key2; + + key1 = &znode->zbranch[i].key; + key2 = &znode->zbranch[i + 1].key; + + cmp = keys_cmp(c, key1, key2); + if (cmp > 0) { + dbg_err("bad key order (keys %d and %d)", i, i + 1); + err = 6; + goto out_dump; + } else if (cmp == 0 && !is_hash_key(c, key1)) { + /* These can only be keys with colliding hash */ + dbg_err("keys %d and %d are not hashed but equivalent", + i, i + 1); + err = 7; + goto out_dump; + } + } + + kfree(idx); + return 0; + +out_dump: + ubifs_err("bad indexing node at LEB %d:%d, error %d", lnum, offs, err); + dbg_dump_node(c, idx); + kfree(idx); + return -EINVAL; +} + +/** + * ubifs_load_znode - load znode to TNC cache. + * @c: UBIFS file-system description object + * @zbr: znode branch + * @parent: znode's parent + * @iip: index in parent + * + * This function loads znode pointed to by @zbr into the TNC cache and + * returns pointer to it in case of success and a negative error code in case + * of failure. + */ +struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c, + struct ubifs_zbranch *zbr, + struct ubifs_znode *parent, int iip) +{ + int err; + struct ubifs_znode *znode; + + ubifs_assert(!zbr->znode); + /* + * A slab cache is not presently used for znodes because the znode size + * depends on the fanout which is stored in the superblock. + */ + znode = kzalloc(c->max_znode_sz, GFP_NOFS); + if (!znode) + return ERR_PTR(-ENOMEM); + + err = read_znode(c, zbr->lnum, zbr->offs, zbr->len, znode); + if (err) + goto out; + + atomic_long_inc(&c->clean_zn_cnt); + + /* + * Increment the global clean znode counter as well. It is OK that + * global and per-FS clean znode counters may be inconsistent for some + * short time (because we might be preempted at this point), the global + * one is only used in shrinker. + */ + atomic_long_inc(&ubifs_clean_zn_cnt); + + zbr->znode = znode; + znode->parent = parent; + znode->time = get_seconds(); + znode->iip = iip; + + return znode; + +out: + kfree(znode); + return ERR_PTR(err); +} + +/** + * ubifs_tnc_read_node - read a leaf node from the flash media. + * @c: UBIFS file-system description object + * @zbr: key and position of the node + * @node: node is returned here + * + * This function reads a node defined by @zbr from the flash media. Returns + * zero in case of success or a negative negative error code in case of + * failure. + */ +int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *node) +{ + union ubifs_key key1, *key = &zbr->key; + int err, type = key_type(c, key); + struct ubifs_wbuf *wbuf; + + /* + * 'zbr' has to point to on-flash node. The node may sit in a bud and + * may even be in a write buffer, so we have to take care about this. + */ + wbuf = ubifs_get_wbuf(c, zbr->lnum); + if (wbuf) + err = ubifs_read_node_wbuf(wbuf, node, type, zbr->len, + zbr->lnum, zbr->offs); + else + err = ubifs_read_node(c, node, type, zbr->len, zbr->lnum, + zbr->offs); + + if (err) { + dbg_tnc("key %s", DBGKEY(key)); + return err; + } + + /* Make sure the key of the read node is correct */ + key_read(c, key, &key1); + if (memcmp(node + UBIFS_KEY_OFFSET, &key1, c->key_len)) { + ubifs_err("bad key in node at LEB %d:%d", + zbr->lnum, zbr->offs); + dbg_tnc("looked for key %s found node's key %s", + DBGKEY(key), DBGKEY1(&key1)); + dbg_dump_node(c, node); + return -EINVAL; + } + + return 0; +} diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h new file mode 100644 index 0000000..0cc7da9 --- /dev/null +++ b/fs/ubifs/ubifs-media.h @@ -0,0 +1,745 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file describes UBIFS on-flash format and contains definitions of all the + * relevant data structures and constants. + * + * All UBIFS on-flash objects are stored in the form of nodes. All nodes start + * with the UBIFS node magic number and have the same common header. Nodes + * always sit at 8-byte aligned positions on the media and node header sizes are + * also 8-byte aligned (except for the indexing node and the padding node). + */ + +#ifndef __UBIFS_MEDIA_H__ +#define __UBIFS_MEDIA_H__ + +/* UBIFS node magic number (must not have the padding byte first or last) */ +#define UBIFS_NODE_MAGIC 0x06101831 + +/* UBIFS on-flash format version */ +#define UBIFS_FORMAT_VERSION 4 + +/* Minimum logical eraseblock size in bytes */ +#define UBIFS_MIN_LEB_SZ (15*1024) + +/* Initial CRC32 value used when calculating CRC checksums */ +#define UBIFS_CRC32_INIT 0xFFFFFFFFU + +/* + * UBIFS does not try to compress data if its length is less than the below + * constant. + */ +#define UBIFS_MIN_COMPR_LEN 128 + +/* Root inode number */ +#define UBIFS_ROOT_INO 1 + +/* Lowest inode number used for regular inodes (not UBIFS-only internal ones) */ +#define UBIFS_FIRST_INO 64 + +/* + * Maximum file name and extended attribute length (must be a multiple of 8, + * minus 1). + */ +#define UBIFS_MAX_NLEN 255 + +/* Maximum number of data journal heads */ +#define UBIFS_MAX_JHEADS 1 + +/* + * Size of UBIFS data block. Note, UBIFS is not a block oriented file-system, + * which means that it does not treat the underlying media as consisting of + * blocks like in case of hard drives. Do not be confused. UBIFS block is just + * the maximum amount of data which one data node can have or which can be + * attached to an inode node. + */ +#define UBIFS_BLOCK_SIZE 4096 +#define UBIFS_BLOCK_SHIFT 12 +#define UBIFS_BLOCK_MASK 0x00000FFF + +/* UBIFS padding byte pattern (must not be first or last byte of node magic) */ +#define UBIFS_PADDING_BYTE 0xCE + +/* Maximum possible key length */ +#define UBIFS_MAX_KEY_LEN 16 + +/* Key length ("simple" format) */ +#define UBIFS_SK_LEN 8 + +/* Minimum index tree fanout */ +#define UBIFS_MIN_FANOUT 2 + +/* Maximum number of levels in UBIFS indexing B-tree */ +#define UBIFS_MAX_LEVELS 512 + +/* Maximum amount of data attached to an inode in bytes */ +#define UBIFS_MAX_INO_DATA UBIFS_BLOCK_SIZE + +/* LEB Properties Tree fanout (must be power of 2) and fanout shift */ +#define UBIFS_LPT_FANOUT 4 +#define UBIFS_LPT_FANOUT_SHIFT 2 + +/* LEB Properties Tree bit field sizes */ +#define UBIFS_LPT_CRC_BITS 16 +#define UBIFS_LPT_CRC_BYTES 2 +#define UBIFS_LPT_TYPE_BITS 4 + +/* The key is always at the same position in all keyed nodes */ +#define UBIFS_KEY_OFFSET offsetof(struct ubifs_ino_node, key) + +/* + * LEB Properties Tree node types. + * + * UBIFS_LPT_PNODE: LPT leaf node (contains LEB properties) + * UBIFS_LPT_NNODE: LPT internal node + * UBIFS_LPT_LTAB: LPT's own lprops table + * UBIFS_LPT_LSAVE: LPT's save table (big model only) + * UBIFS_LPT_NODE_CNT: count of LPT node types + * UBIFS_LPT_NOT_A_NODE: all ones (15 for 4 bits) is never a valid node type + */ +enum { + UBIFS_LPT_PNODE, + UBIFS_LPT_NNODE, + UBIFS_LPT_LTAB, + UBIFS_LPT_LSAVE, + UBIFS_LPT_NODE_CNT, + UBIFS_LPT_NOT_A_NODE = (1 << UBIFS_LPT_TYPE_BITS) - 1, +}; + +/* + * UBIFS inode types. + * + * UBIFS_ITYPE_REG: regular file + * UBIFS_ITYPE_DIR: directory + * UBIFS_ITYPE_LNK: soft link + * UBIFS_ITYPE_BLK: block device node + * UBIFS_ITYPE_CHR: character device node + * UBIFS_ITYPE_FIFO: fifo + * UBIFS_ITYPE_SOCK: socket + * UBIFS_ITYPES_CNT: count of supported file types + */ +enum { + UBIFS_ITYPE_REG, + UBIFS_ITYPE_DIR, + UBIFS_ITYPE_LNK, + UBIFS_ITYPE_BLK, + UBIFS_ITYPE_CHR, + UBIFS_ITYPE_FIFO, + UBIFS_ITYPE_SOCK, + UBIFS_ITYPES_CNT, +}; + +/* + * Supported key hash functions. + * + * UBIFS_KEY_HASH_R5: R5 hash + * UBIFS_KEY_HASH_TEST: test hash which just returns first 4 bytes of the name + */ +enum { + UBIFS_KEY_HASH_R5, + UBIFS_KEY_HASH_TEST, +}; + +/* + * Supported key formats. + * + * UBIFS_SIMPLE_KEY_FMT: simple key format + */ +enum { + UBIFS_SIMPLE_KEY_FMT, +}; + +/* + * The simple key format uses 29 bits for storing UBIFS block number and hash + * value. + */ +#define UBIFS_S_KEY_BLOCK_BITS 29 +#define UBIFS_S_KEY_BLOCK_MASK 0x1FFFFFFF +#define UBIFS_S_KEY_HASH_BITS UBIFS_S_KEY_BLOCK_BITS +#define UBIFS_S_KEY_HASH_MASK UBIFS_S_KEY_BLOCK_MASK + +/* + * Key types. + * + * UBIFS_INO_KEY: inode node key + * UBIFS_DATA_KEY: data node key + * UBIFS_DENT_KEY: directory entry node key + * UBIFS_XENT_KEY: extended attribute entry key + * UBIFS_KEY_TYPES_CNT: number of supported key types + */ +enum { + UBIFS_INO_KEY, + UBIFS_DATA_KEY, + UBIFS_DENT_KEY, + UBIFS_XENT_KEY, + UBIFS_KEY_TYPES_CNT, +}; + +/* Count of LEBs reserved for the superblock area */ +#define UBIFS_SB_LEBS 1 +/* Count of LEBs reserved for the master area */ +#define UBIFS_MST_LEBS 2 + +/* First LEB of the superblock area */ +#define UBIFS_SB_LNUM 0 +/* First LEB of the master area */ +#define UBIFS_MST_LNUM (UBIFS_SB_LNUM + UBIFS_SB_LEBS) +/* First LEB of the log area */ +#define UBIFS_LOG_LNUM (UBIFS_MST_LNUM + UBIFS_MST_LEBS) + +/* + * The below constants define the absolute minimum values for various UBIFS + * media areas. Many of them actually depend of flash geometry and the FS + * configuration (number of journal heads, orphan LEBs, etc). This means that + * the smallest volume size which can be used for UBIFS cannot be pre-defined + * by these constants. The file-system that meets the below limitation will not + * necessarily mount. UBIFS does run-time calculations and validates the FS + * size. + */ + +/* Minimum number of logical eraseblocks in the log */ +#define UBIFS_MIN_LOG_LEBS 2 +/* Minimum number of bud logical eraseblocks (one for each head) */ +#define UBIFS_MIN_BUD_LEBS 3 +/* Minimum number of journal logical eraseblocks */ +#define UBIFS_MIN_JNL_LEBS (UBIFS_MIN_LOG_LEBS + UBIFS_MIN_BUD_LEBS) +/* Minimum number of LPT area logical eraseblocks */ +#define UBIFS_MIN_LPT_LEBS 2 +/* Minimum number of orphan area logical eraseblocks */ +#define UBIFS_MIN_ORPH_LEBS 1 +/* + * Minimum number of main area logical eraseblocks (buds, 2 for the index, 1 + * for GC, 1 for deletions, and at least 1 for committed data). + */ +#define UBIFS_MIN_MAIN_LEBS (UBIFS_MIN_BUD_LEBS + 5) + +/* Minimum number of logical eraseblocks */ +#define UBIFS_MIN_LEB_CNT (UBIFS_SB_LEBS + UBIFS_MST_LEBS + \ + UBIFS_MIN_LOG_LEBS + UBIFS_MIN_LPT_LEBS + \ + UBIFS_MIN_ORPH_LEBS + UBIFS_MIN_MAIN_LEBS) + +/* Node sizes (N.B. these are guaranteed to be multiples of 8) */ +#define UBIFS_CH_SZ sizeof(struct ubifs_ch) +#define UBIFS_INO_NODE_SZ sizeof(struct ubifs_ino_node) +#define UBIFS_DATA_NODE_SZ sizeof(struct ubifs_data_node) +#define UBIFS_DENT_NODE_SZ sizeof(struct ubifs_dent_node) +#define UBIFS_TRUN_NODE_SZ sizeof(struct ubifs_trun_node) +#define UBIFS_PAD_NODE_SZ sizeof(struct ubifs_pad_node) +#define UBIFS_SB_NODE_SZ sizeof(struct ubifs_sb_node) +#define UBIFS_MST_NODE_SZ sizeof(struct ubifs_mst_node) +#define UBIFS_REF_NODE_SZ sizeof(struct ubifs_ref_node) +#define UBIFS_IDX_NODE_SZ sizeof(struct ubifs_idx_node) +#define UBIFS_CS_NODE_SZ sizeof(struct ubifs_cs_node) +#define UBIFS_ORPH_NODE_SZ sizeof(struct ubifs_orph_node) +/* Extended attribute entry nodes are identical to directory entry nodes */ +#define UBIFS_XENT_NODE_SZ UBIFS_DENT_NODE_SZ +/* Only this does not have to be multiple of 8 bytes */ +#define UBIFS_BRANCH_SZ sizeof(struct ubifs_branch) + +/* Maximum node sizes (N.B. these are guaranteed to be multiples of 8) */ +#define UBIFS_MAX_DATA_NODE_SZ (UBIFS_DATA_NODE_SZ + UBIFS_BLOCK_SIZE) +#define UBIFS_MAX_INO_NODE_SZ (UBIFS_INO_NODE_SZ + UBIFS_MAX_INO_DATA) +#define UBIFS_MAX_DENT_NODE_SZ (UBIFS_DENT_NODE_SZ + UBIFS_MAX_NLEN + 1) +#define UBIFS_MAX_XENT_NODE_SZ UBIFS_MAX_DENT_NODE_SZ + +/* The largest UBIFS node */ +#define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ + +/* + * On-flash inode flags. + * + * UBIFS_COMPR_FL: use compression for this inode + * UBIFS_SYNC_FL: I/O on this inode has to be synchronous + * UBIFS_IMMUTABLE_FL: inode is immutable + * UBIFS_APPEND_FL: writes to the inode may only append data + * UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous + * UBIFS_XATTR_FL: this inode is the inode for an extended attribute value + * + * Note, these are on-flash flags which correspond to ioctl flags + * (@FS_COMPR_FL, etc). They have the same values now, but generally, do not + * have to be the same. + */ +enum { + UBIFS_COMPR_FL = 0x01, + UBIFS_SYNC_FL = 0x02, + UBIFS_IMMUTABLE_FL = 0x04, + UBIFS_APPEND_FL = 0x08, + UBIFS_DIRSYNC_FL = 0x10, + UBIFS_XATTR_FL = 0x20, +}; + +/* Inode flag bits used by UBIFS */ +#define UBIFS_FL_MASK 0x0000001F + +/* + * UBIFS compression algorithms. + * + * UBIFS_COMPR_NONE: no compression + * UBIFS_COMPR_LZO: LZO compression + * UBIFS_COMPR_ZLIB: ZLIB compression + * UBIFS_COMPR_TYPES_CNT: count of supported compression types + */ +enum { + UBIFS_COMPR_NONE, + UBIFS_COMPR_LZO, + UBIFS_COMPR_ZLIB, + UBIFS_COMPR_TYPES_CNT, +}; + +/* + * UBIFS node types. + * + * UBIFS_INO_NODE: inode node + * UBIFS_DATA_NODE: data node + * UBIFS_DENT_NODE: directory entry node + * UBIFS_XENT_NODE: extended attribute node + * UBIFS_TRUN_NODE: truncation node + * UBIFS_PAD_NODE: padding node + * UBIFS_SB_NODE: superblock node + * UBIFS_MST_NODE: master node + * UBIFS_REF_NODE: LEB reference node + * UBIFS_IDX_NODE: index node + * UBIFS_CS_NODE: commit start node + * UBIFS_ORPH_NODE: orphan node + * UBIFS_NODE_TYPES_CNT: count of supported node types + * + * Note, we index arrays by these numbers, so keep them low and contiguous. + * Node type constants for inodes, direntries and so on have to be the same as + * corresponding key type constants. + */ +enum { + UBIFS_INO_NODE, + UBIFS_DATA_NODE, + UBIFS_DENT_NODE, + UBIFS_XENT_NODE, + UBIFS_TRUN_NODE, + UBIFS_PAD_NODE, + UBIFS_SB_NODE, + UBIFS_MST_NODE, + UBIFS_REF_NODE, + UBIFS_IDX_NODE, + UBIFS_CS_NODE, + UBIFS_ORPH_NODE, + UBIFS_NODE_TYPES_CNT, +}; + +/* + * Master node flags. + * + * UBIFS_MST_DIRTY: rebooted uncleanly - master node is dirty + * UBIFS_MST_NO_ORPHS: no orphan inodes present + * UBIFS_MST_RCVRY: written by recovery + */ +enum { + UBIFS_MST_DIRTY = 1, + UBIFS_MST_NO_ORPHS = 2, + UBIFS_MST_RCVRY = 4, +}; + +/* + * Node group type (used by recovery to recover whole group or none). + * + * UBIFS_NO_NODE_GROUP: this node is not part of a group + * UBIFS_IN_NODE_GROUP: this node is a part of a group + * UBIFS_LAST_OF_NODE_GROUP: this node is the last in a group + */ +enum { + UBIFS_NO_NODE_GROUP = 0, + UBIFS_IN_NODE_GROUP, + UBIFS_LAST_OF_NODE_GROUP, +}; + +/* + * Superblock flags. + * + * UBIFS_FLG_BIGLPT: if "big" LPT model is used if set + */ +enum { + UBIFS_FLG_BIGLPT = 0x02, +}; + +/** + * struct ubifs_ch - common header node. + * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC) + * @crc: CRC-32 checksum of the node header + * @sqnum: sequence number + * @len: full node length + * @node_type: node type + * @group_type: node group type + * @padding: reserved for future, zeroes + * + * Every UBIFS node starts with this common part. If the node has a key, the + * key always goes next. + */ +struct ubifs_ch { + __le32 magic; + __le32 crc; + __le64 sqnum; + __le32 len; + __u8 node_type; + __u8 group_type; + __u8 padding[2]; +} __attribute__ ((packed)); + +/** + * union ubifs_dev_desc - device node descriptor. + * @new: new type device descriptor + * @huge: huge type device descriptor + * + * This data structure describes major/minor numbers of a device node. In an + * inode is a device node then its data contains an object of this type. UBIFS + * uses standard Linux "new" and "huge" device node encodings. + */ +union ubifs_dev_desc { + __le32 new; + __le64 huge; +} __attribute__ ((packed)); + +/** + * struct ubifs_ino_node - inode node. + * @ch: common header + * @key: node key + * @creat_sqnum: sequence number at time of creation + * @size: inode size in bytes (amount of uncompressed data) + * @atime_sec: access time seconds + * @ctime_sec: creation time seconds + * @mtime_sec: modification time seconds + * @atime_nsec: access time nanoseconds + * @ctime_nsec: creation time nanoseconds + * @mtime_nsec: modification time nanoseconds + * @nlink: number of hard links + * @uid: owner ID + * @gid: group ID + * @mode: access flags + * @flags: per-inode flags (%UBIFS_COMPR_FL, %UBIFS_SYNC_FL, etc) + * @data_len: inode data length + * @xattr_cnt: count of extended attributes this inode has + * @xattr_size: summarized size of all extended attributes in bytes + * @padding1: reserved for future, zeroes + * @xattr_names: sum of lengths of all extended attribute names belonging to + * this inode + * @compr_type: compression type used for this inode + * @padding2: reserved for future, zeroes + * @data: data attached to the inode + * + * Note, even though inode compression type is defined by @compr_type, some + * nodes of this inode may be compressed with different compressor - this + * happens if compression type is changed while the inode already has data + * nodes. But @compr_type will be use for further writes to the inode. + * + * Note, do not forget to amend 'zero_ino_node_unused()' function when changing + * the padding fields. + */ +struct ubifs_ino_node { + struct ubifs_ch ch; + __u8 key[UBIFS_MAX_KEY_LEN]; + __le64 creat_sqnum; + __le64 size; + __le64 atime_sec; + __le64 ctime_sec; + __le64 mtime_sec; + __le32 atime_nsec; + __le32 ctime_nsec; + __le32 mtime_nsec; + __le32 nlink; + __le32 uid; + __le32 gid; + __le32 mode; + __le32 flags; + __le32 data_len; + __le32 xattr_cnt; + __le32 xattr_size; + __u8 padding1[4]; /* Watch 'zero_ino_node_unused()' if changing! */ + __le32 xattr_names; + __le16 compr_type; + __u8 padding2[26]; /* Watch 'zero_ino_node_unused()' if changing! */ + __u8 data[]; +} __attribute__ ((packed)); + +/** + * struct ubifs_dent_node - directory entry node. + * @ch: common header + * @key: node key + * @inum: target inode number + * @padding1: reserved for future, zeroes + * @type: type of the target inode (%UBIFS_ITYPE_REG, %UBIFS_ITYPE_DIR, etc) + * @nlen: name length + * @padding2: reserved for future, zeroes + * @name: zero-terminated name + * + * Note, do not forget to amend 'zero_dent_node_unused()' function when + * changing the padding fields. + */ +struct ubifs_dent_node { + struct ubifs_ch ch; + __u8 key[UBIFS_MAX_KEY_LEN]; + __le64 inum; + __u8 padding1; + __u8 type; + __le16 nlen; + __u8 padding2[4]; /* Watch 'zero_dent_node_unused()' if changing! */ + __u8 name[]; +} __attribute__ ((packed)); + +/** + * struct ubifs_data_node - data node. + * @ch: common header + * @key: node key + * @size: uncompressed data size in bytes + * @compr_type: compression type (%UBIFS_COMPR_NONE, %UBIFS_COMPR_LZO, etc) + * @padding: reserved for future, zeroes + * @data: data + * + * Note, do not forget to amend 'zero_data_node_unused()' function when + * changing the padding fields. + */ +struct ubifs_data_node { + struct ubifs_ch ch; + __u8 key[UBIFS_MAX_KEY_LEN]; + __le32 size; + __le16 compr_type; + __u8 padding[2]; /* Watch 'zero_data_node_unused()' if changing! */ + __u8 data[]; +} __attribute__ ((packed)); + +/** + * struct ubifs_trun_node - truncation node. + * @ch: common header + * @inum: truncated inode number + * @padding: reserved for future, zeroes + * @old_size: size before truncation + * @new_size: size after truncation + * + * This node exists only in the journal and never goes to the main area. Note, + * do not forget to amend 'zero_trun_node_unused()' function when changing the + * padding fields. + */ +struct ubifs_trun_node { + struct ubifs_ch ch; + __le32 inum; + __u8 padding[12]; /* Watch 'zero_trun_node_unused()' if changing! */ + __le64 old_size; + __le64 new_size; +} __attribute__ ((packed)); + +/** + * struct ubifs_pad_node - padding node. + * @ch: common header + * @pad_len: how many bytes after this node are unused (because padded) + * @padding: reserved for future, zeroes + */ +struct ubifs_pad_node { + struct ubifs_ch ch; + __le32 pad_len; +} __attribute__ ((packed)); + +/** + * struct ubifs_sb_node - superblock node. + * @ch: common header + * @padding: reserved for future, zeroes + * @key_hash: type of hash function used in keys + * @key_fmt: format of the key + * @flags: file-system flags (%UBIFS_FLG_BIGLPT, etc) + * @min_io_size: minimal input/output unit size + * @leb_size: logical eraseblock size in bytes + * @leb_cnt: count of LEBs used by file-system + * @max_leb_cnt: maximum count of LEBs used by file-system + * @max_bud_bytes: maximum amount of data stored in buds + * @log_lebs: log size in logical eraseblocks + * @lpt_lebs: number of LEBs used for lprops table + * @orph_lebs: number of LEBs used for recording orphans + * @jhead_cnt: count of journal heads + * @fanout: tree fanout (max. number of links per indexing node) + * @lsave_cnt: number of LEB numbers in LPT's save table + * @fmt_version: UBIFS on-flash format version + * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) + * @padding1: reserved for future, zeroes + * @rp_uid: reserve pool UID + * @rp_gid: reserve pool GID + * @rp_size: size of the reserved pool in bytes + * @padding2: reserved for future, zeroes + * @time_gran: time granularity in nanoseconds + * @uuid: UUID generated when the file system image was created + */ +struct ubifs_sb_node { + struct ubifs_ch ch; + __u8 padding[2]; + __u8 key_hash; + __u8 key_fmt; + __le32 flags; + __le32 min_io_size; + __le32 leb_size; + __le32 leb_cnt; + __le32 max_leb_cnt; + __le64 max_bud_bytes; + __le32 log_lebs; + __le32 lpt_lebs; + __le32 orph_lebs; + __le32 jhead_cnt; + __le32 fanout; + __le32 lsave_cnt; + __le32 fmt_version; + __le16 default_compr; + __u8 padding1[2]; + __le32 rp_uid; + __le32 rp_gid; + __le64 rp_size; + __le32 time_gran; + __u8 uuid[16]; + __u8 padding2[3972]; +} __attribute__ ((packed)); + +/** + * struct ubifs_mst_node - master node. + * @ch: common header + * @highest_inum: highest inode number in the committed index + * @cmt_no: commit number + * @flags: various flags (%UBIFS_MST_DIRTY, etc) + * @log_lnum: start of the log + * @root_lnum: LEB number of the root indexing node + * @root_offs: offset within @root_lnum + * @root_len: root indexing node length + * @gc_lnum: LEB reserved for garbage collection (%-1 value means the LEB was + * not reserved and should be reserved on mount) + * @ihead_lnum: LEB number of index head + * @ihead_offs: offset of index head + * @index_size: size of index on flash + * @total_free: total free space in bytes + * @total_dirty: total dirty space in bytes + * @total_used: total used space in bytes (includes only data LEBs) + * @total_dead: total dead space in bytes (includes only data LEBs) + * @total_dark: total dark space in bytes (includes only data LEBs) + * @lpt_lnum: LEB number of LPT root nnode + * @lpt_offs: offset of LPT root nnode + * @nhead_lnum: LEB number of LPT head + * @nhead_offs: offset of LPT head + * @ltab_lnum: LEB number of LPT's own lprops table + * @ltab_offs: offset of LPT's own lprops table + * @lsave_lnum: LEB number of LPT's save table (big model only) + * @lsave_offs: offset of LPT's save table (big model only) + * @lscan_lnum: LEB number of last LPT scan + * @empty_lebs: number of empty logical eraseblocks + * @idx_lebs: number of indexing logical eraseblocks + * @leb_cnt: count of LEBs used by file-system + * @padding: reserved for future, zeroes + */ +struct ubifs_mst_node { + struct ubifs_ch ch; + __le64 highest_inum; + __le64 cmt_no; + __le32 flags; + __le32 log_lnum; + __le32 root_lnum; + __le32 root_offs; + __le32 root_len; + __le32 gc_lnum; + __le32 ihead_lnum; + __le32 ihead_offs; + __le64 index_size; + __le64 total_free; + __le64 total_dirty; + __le64 total_used; + __le64 total_dead; + __le64 total_dark; + __le32 lpt_lnum; + __le32 lpt_offs; + __le32 nhead_lnum; + __le32 nhead_offs; + __le32 ltab_lnum; + __le32 ltab_offs; + __le32 lsave_lnum; + __le32 lsave_offs; + __le32 lscan_lnum; + __le32 empty_lebs; + __le32 idx_lebs; + __le32 leb_cnt; + __u8 padding[344]; +} __attribute__ ((packed)); + +/** + * struct ubifs_ref_node - logical eraseblock reference node. + * @ch: common header + * @lnum: the referred logical eraseblock number + * @offs: start offset in the referred LEB + * @jhead: journal head number + * @padding: reserved for future, zeroes + */ +struct ubifs_ref_node { + struct ubifs_ch ch; + __le32 lnum; + __le32 offs; + __le32 jhead; + __u8 padding[28]; +} __attribute__ ((packed)); + +/** + * struct ubifs_branch - key/reference/length branch + * @lnum: LEB number of the target node + * @offs: offset within @lnum + * @len: target node length + * @key: key + */ +struct ubifs_branch { + __le32 lnum; + __le32 offs; + __le32 len; + __u8 key[]; +} __attribute__ ((packed)); + +/** + * struct ubifs_idx_node - indexing node. + * @ch: common header + * @child_cnt: number of child index nodes + * @level: tree level + * @branches: LEB number / offset / length / key branches + */ +struct ubifs_idx_node { + struct ubifs_ch ch; + __le16 child_cnt; + __le16 level; + __u8 branches[]; +} __attribute__ ((packed)); + +/** + * struct ubifs_cs_node - commit start node. + * @ch: common header + * @cmt_no: commit number + */ +struct ubifs_cs_node { + struct ubifs_ch ch; + __le64 cmt_no; +} __attribute__ ((packed)); + +/** + * struct ubifs_orph_node - orphan node. + * @ch: common header + * @cmt_no: commit number (also top bit is set on the last node of the commit) + * @inos: inode numbers of orphans + */ +struct ubifs_orph_node { + struct ubifs_ch ch; + __le64 cmt_no; + __le64 inos[]; +} __attribute__ ((packed)); + +#endif /* __UBIFS_MEDIA_H__ */ diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h new file mode 100644 index 0000000..e4f89f2 --- /dev/null +++ b/fs/ubifs/ubifs.h @@ -0,0 +1,1649 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* Implementation version 0.7 */ + +#ifndef __UBIFS_H__ +#define __UBIFS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ubifs-media.h" + +/* Version of this UBIFS implementation */ +#define UBIFS_VERSION 1 + +/* Normal UBIFS messages */ +#define ubifs_msg(fmt, ...) \ + printk(KERN_NOTICE "UBIFS: " fmt "\n", ##__VA_ARGS__) +/* UBIFS error messages */ +#define ubifs_err(fmt, ...) \ + printk(KERN_ERR "UBIFS error (pid %d): %s: " fmt "\n", current->pid, \ + __func__, ##__VA_ARGS__) +/* UBIFS warning messages */ +#define ubifs_warn(fmt, ...) \ + printk(KERN_WARNING "UBIFS warning (pid %d): %s: " fmt "\n", \ + current->pid, __func__, ##__VA_ARGS__) + +/* UBIFS file system VFS magic number */ +#define UBIFS_SUPER_MAGIC 0x24051905 + +/* Number of UBIFS blocks per VFS page */ +#define UBIFS_BLOCKS_PER_PAGE (PAGE_CACHE_SIZE / UBIFS_BLOCK_SIZE) +#define UBIFS_BLOCKS_PER_PAGE_SHIFT (PAGE_CACHE_SHIFT - UBIFS_BLOCK_SHIFT) + +/* "File system end of life" sequence number watermark */ +#define SQNUM_WARN_WATERMARK 0xFFFFFFFF00000000ULL +#define SQNUM_WATERMARK 0xFFFFFFFFFF000000ULL + +/* Minimum amount of data UBIFS writes to the flash */ +#define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8) + +/* + * Currently we do not support inode number overlapping and re-using, so this + * watermark defines dangerous inode number level. This should be fixed later, + * although it is difficult to exceed current limit. Another option is to use + * 64-bit inode numbers, but this means more overhead. + */ +#define INUM_WARN_WATERMARK 0xFFF00000 +#define INUM_WATERMARK 0xFFFFFF00 + +/* Largest key size supported in this implementation */ +#define CUR_MAX_KEY_LEN UBIFS_SK_LEN + +/* Maximum number of entries in each LPT (LEB category) heap */ +#define LPT_HEAP_SZ 256 + +/* + * Background thread name pattern. The numbers are UBI device and volume + * numbers. + */ +#define BGT_NAME_PATTERN "ubifs_bgt%d_%d" + +/* Default write-buffer synchronization timeout (5 secs) */ +#define DEFAULT_WBUF_TIMEOUT (5 * HZ) + +/* Maximum possible inode number (only 32-bit inodes are supported now) */ +#define MAX_INUM 0xFFFFFFFF + +/* Number of non-data journal heads */ +#define NONDATA_JHEADS_CNT 2 + +/* Garbage collector head */ +#define GCHD 0 +/* Base journal head number */ +#define BASEHD 1 +/* First "general purpose" journal head */ +#define DATAHD 2 + +/* 'No change' value for 'ubifs_change_lp()' */ +#define LPROPS_NC 0x80000001 + +/* + * There is no notion of truncation key because truncation nodes do not exist + * in TNC. However, when replaying, it is handy to introduce fake "truncation" + * keys for truncation nodes because the code becomes simpler. So we define + * %UBIFS_TRUN_KEY type. + */ +#define UBIFS_TRUN_KEY UBIFS_KEY_TYPES_CNT + +/* + * How much a directory entry/extended attribute entry adds to the parent/host + * inode. + */ +#define CALC_DENT_SIZE(name_len) ALIGN(UBIFS_DENT_NODE_SZ + (name_len) + 1, 8) + +/* How much an extended attribute adds to the host inode */ +#define CALC_XATTR_BYTES(data_len) ALIGN(UBIFS_INO_NODE_SZ + (data_len) + 1, 8) + +/* + * Znodes which were not touched for 'OLD_ZNODE_AGE' seconds are considered + * "old", and znode which were touched last 'YOUNG_ZNODE_AGE' seconds ago are + * considered "young". This is used by shrinker when selecting znode to trim + * off. + */ +#define OLD_ZNODE_AGE 20 +#define YOUNG_ZNODE_AGE 5 + +/* + * Some compressors, like LZO, may end up with more data then the input buffer. + * So UBIFS always allocates larger output buffer, to be sure the compressor + * will not corrupt memory in case of worst case compression. + */ +#define WORST_COMPR_FACTOR 2 + +/* Maximum expected tree height for use by bottom_up_buf */ +#define BOTTOM_UP_HEIGHT 64 + +/* + * Lockdep classes for UBIFS inode @ui_mutex. + */ +enum { + WB_MUTEX_1 = 0, + WB_MUTEX_2 = 1, + WB_MUTEX_3 = 2, +}; + +/* + * Znode flags (actually, bit numbers which store the flags). + * + * DIRTY_ZNODE: znode is dirty + * COW_ZNODE: znode is being committed and a new instance of this znode has to + * be created before changing this znode + * OBSOLETE_ZNODE: znode is obsolete, which means it was deleted, but it is + * still in the commit list and the ongoing commit operation + * will commit it, and delete this znode after it is done + */ +enum { + DIRTY_ZNODE = 0, + COW_ZNODE = 1, + OBSOLETE_ZNODE = 2, +}; + +/* + * Commit states. + * + * COMMIT_RESTING: commit is not wanted + * COMMIT_BACKGROUND: background commit has been requested + * COMMIT_REQUIRED: commit is required + * COMMIT_RUNNING_BACKGROUND: background commit is running + * COMMIT_RUNNING_REQUIRED: commit is running and it is required + * COMMIT_BROKEN: commit failed + */ +enum { + COMMIT_RESTING = 0, + COMMIT_BACKGROUND, + COMMIT_REQUIRED, + COMMIT_RUNNING_BACKGROUND, + COMMIT_RUNNING_REQUIRED, + COMMIT_BROKEN, +}; + +/* + * 'ubifs_scan_a_node()' return values. + * + * SCANNED_GARBAGE: scanned garbage + * SCANNED_EMPTY_SPACE: scanned empty space + * SCANNED_A_NODE: scanned a valid node + * SCANNED_A_CORRUPT_NODE: scanned a corrupted node + * SCANNED_A_BAD_PAD_NODE: scanned a padding node with invalid pad length + * + * Greater than zero means: 'scanned that number of padding bytes' + */ +enum { + SCANNED_GARBAGE = 0, + SCANNED_EMPTY_SPACE = -1, + SCANNED_A_NODE = -2, + SCANNED_A_CORRUPT_NODE = -3, + SCANNED_A_BAD_PAD_NODE = -4, +}; + +/* + * LPT cnode flag bits. + * + * DIRTY_CNODE: cnode is dirty + * COW_CNODE: cnode is being committed and must be copied before writing + * OBSOLETE_CNODE: cnode is being committed and has been copied (or deleted), + * so it can (and must) be freed when the commit is finished + */ +enum { + DIRTY_CNODE = 0, + COW_CNODE = 1, + OBSOLETE_CNODE = 2, +}; + +/* + * Dirty flag bits (lpt_drty_flgs) for LPT special nodes. + * + * LTAB_DIRTY: ltab node is dirty + * LSAVE_DIRTY: lsave node is dirty + */ +enum { + LTAB_DIRTY = 1, + LSAVE_DIRTY = 2, +}; + +/* + * Return codes used by the garbage collector. + * @LEB_FREED: the logical eraseblock was freed and is ready to use + * @LEB_FREED_IDX: indexing LEB was freed and can be used only after the commit + * @LEB_RETAINED: the logical eraseblock was freed and retained for GC purposes + */ +enum { + LEB_FREED, + LEB_FREED_IDX, + LEB_RETAINED, +}; + +/** + * struct ubifs_old_idx - index node obsoleted since last commit start. + * @rb: rb-tree node + * @lnum: LEB number of obsoleted index node + * @offs: offset of obsoleted index node + */ +struct ubifs_old_idx { + struct rb_node rb; + int lnum; + int offs; +}; + +/* The below union makes it easier to deal with keys */ +union ubifs_key { + uint8_t u8[CUR_MAX_KEY_LEN]; + uint32_t u32[CUR_MAX_KEY_LEN/4]; + uint64_t u64[CUR_MAX_KEY_LEN/8]; + __le32 j32[CUR_MAX_KEY_LEN/4]; +}; + +/** + * struct ubifs_scan_node - UBIFS scanned node information. + * @list: list of scanned nodes + * @key: key of node scanned (if it has one) + * @sqnum: sequence number + * @type: type of node scanned + * @offs: offset with LEB of node scanned + * @len: length of node scanned + * @node: raw node + */ +struct ubifs_scan_node { + struct list_head list; + union ubifs_key key; + unsigned long long sqnum; + int type; + int offs; + int len; + void *node; +}; + +/** + * struct ubifs_scan_leb - UBIFS scanned LEB information. + * @lnum: logical eraseblock number + * @nodes_cnt: number of nodes scanned + * @nodes: list of struct ubifs_scan_node + * @endpt: end point (and therefore the start of empty space) + * @ecc: read returned -EBADMSG + * @buf: buffer containing entire LEB scanned + */ +struct ubifs_scan_leb { + int lnum; + int nodes_cnt; + struct list_head nodes; + int endpt; + int ecc; + void *buf; +}; + +/** + * struct ubifs_gced_idx_leb - garbage-collected indexing LEB. + * @list: list + * @lnum: LEB number + * @unmap: OK to unmap this LEB + * + * This data structure is used to temporary store garbage-collected indexing + * LEBs - they are not released immediately, but only after the next commit. + * This is needed to guarantee recoverability. + */ +struct ubifs_gced_idx_leb { + struct list_head list; + int lnum; + int unmap; +}; + +/** + * struct ubifs_inode - UBIFS in-memory inode description. + * @vfs_inode: VFS inode description object + * @creat_sqnum: sequence number at time of creation + * @xattr_size: summarized size of all extended attributes in bytes + * @xattr_cnt: count of extended attributes this inode has + * @xattr_names: sum of lengths of all extended attribute names belonging to + * this inode + * @dirty: non-zero if the inode is dirty + * @xattr: non-zero if this is an extended attribute inode + * @ui_mutex: serializes inode write-back with the rest of VFS operations, + * serializes "clean <-> dirty" state changes, protects @dirty, + * @ui_size, and @xattr_size + * @ui_lock: protects @synced_i_size + * @synced_i_size: synchronized size of inode, i.e. the value of inode size + * currently stored on the flash; used only for regular file + * inodes + * @ui_size: inode size used by UBIFS when writing to flash + * @flags: inode flags (@UBIFS_COMPR_FL, etc) + * @compr_type: default compression type used for this inode + * @data_len: length of the data attached to the inode + * @data: inode's data + * + * @ui_mutex exists for two main reasons. At first it prevents inodes from + * being written back while UBIFS changing them, being in the middle of an VFS + * operation. This way UBIFS makes sure the inode fields are consistent. For + * example, in 'ubifs_rename()' we change 3 inodes simultaneously, and + * write-back must not write any of them before we have finished. + * + * The second reason is budgeting - UBIFS has to budget all operations. If an + * operation is going to mark an inode dirty, it has to allocate budget for + * this. It cannot just mark it dirty because there is no guarantee there will + * be enough flash space to write the inode back later. This means UBIFS has + * to have full control over inode "clean <-> dirty" transitions (and pages + * actually). But unfortunately, VFS marks inodes dirty in many places, and it + * does not ask the file-system if it is allowed to do so (there is a notifier, + * but it is not enough), i.e., there is no mechanism to synchronize with this. + * So UBIFS has its own inode dirty flag and its own mutex to serialize + * "clean <-> dirty" transitions. + * + * The @synced_i_size field is used to make sure we never write pages which are + * beyond last synchronized inode size. See 'ubifs_writepage()' for more + * information. + * + * The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses + * @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot + * make sure @inode->i_size is always changed under @ui_mutex, because it + * cannot call 'vmtruncate()' with @ui_mutex locked, because it would deadlock + * with 'ubifs_writepage()' (see file.c). All the other inode fields are + * changed under @ui_mutex, so they do not need "shadow" fields. Note, one + * could consider to rework locking and base it on "shadow" fields. + */ +struct ubifs_inode { + struct inode vfs_inode; + unsigned long long creat_sqnum; + unsigned int xattr_size; + unsigned int xattr_cnt; + unsigned int xattr_names; + unsigned int dirty:1; + unsigned int xattr:1; + struct mutex ui_mutex; + spinlock_t ui_lock; + loff_t synced_i_size; + loff_t ui_size; + int flags; + int compr_type; + int data_len; + void *data; +}; + +/** + * struct ubifs_unclean_leb - records a LEB recovered under read-only mode. + * @list: list + * @lnum: LEB number of recovered LEB + * @endpt: offset where recovery ended + * + * This structure records a LEB identified during recovery that needs to be + * cleaned but was not because UBIFS was mounted read-only. The information + * is used to clean the LEB when remounting to read-write mode. + */ +struct ubifs_unclean_leb { + struct list_head list; + int lnum; + int endpt; +}; + +/* + * LEB properties flags. + * + * LPROPS_UNCAT: not categorized + * LPROPS_DIRTY: dirty > 0, not index + * LPROPS_DIRTY_IDX: dirty + free > UBIFS_CH_SZ and 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 + * LPROPS_FRDI_IDX: free + dirty == leb_size and index, may be taken + * LPROPS_CAT_MASK: mask for the LEB categories above + * LPROPS_TAKEN: LEB was taken (this flag is not saved on the media) + * LPROPS_INDEX: LEB contains indexing nodes (this flag also exists on flash) + */ +enum { + LPROPS_UNCAT = 0, + LPROPS_DIRTY = 1, + LPROPS_DIRTY_IDX = 2, + LPROPS_FREE = 3, + LPROPS_HEAP_CNT = 3, + LPROPS_EMPTY = 4, + LPROPS_FREEABLE = 5, + LPROPS_FRDI_IDX = 6, + LPROPS_CAT_MASK = 15, + LPROPS_TAKEN = 16, + LPROPS_INDEX = 32, +}; + +/** + * struct ubifs_lprops - logical eraseblock properties. + * @free: amount of free space in bytes + * @dirty: amount of dirty space in bytes + * @flags: LEB properties flags (see above) + * @lnum: LEB number + * @list: list of same-category lprops (for LPROPS_EMPTY and LPROPS_FREEABLE) + * @hpos: heap position in heap of same-category lprops (other categories) + */ +struct ubifs_lprops { + int free; + int dirty; + int flags; + int lnum; + union { + struct list_head list; + int hpos; + }; +}; + +/** + * struct ubifs_lpt_lprops - LPT logical eraseblock properties. + * @free: amount of free space in bytes + * @dirty: amount of dirty space in bytes + * @tgc: trivial GC flag (1 => unmap after commit end) + * @cmt: commit flag (1 => reserved for commit) + */ +struct ubifs_lpt_lprops { + int free; + int dirty; + unsigned tgc : 1; + unsigned cmt : 1; +}; + +/** + * struct ubifs_lp_stats - statistics of eraseblocks in the main area. + * @empty_lebs: number of empty LEBs + * @taken_empty_lebs: number of taken LEBs + * @idx_lebs: number of indexing LEBs + * @total_free: total free space in bytes + * @total_dirty: total dirty space in bytes + * @total_used: total used space in bytes (includes only data LEBs) + * @total_dead: total dead space in bytes (includes only data LEBs) + * @total_dark: total dark space in bytes (includes only data LEBs) + * + * N.B. total_dirty and total_used are different to other total_* fields, + * because they account _all_ LEBs, not just data LEBs. + * + * 'taken_empty_lebs' counts the LEBs that are in the transient state of having + * been 'taken' for use but not yet written to. 'taken_empty_lebs' is needed + * to account correctly for gc_lnum, otherwise 'empty_lebs' could be used + * by itself (in which case 'unused_lebs' would be a better name). In the case + * of gc_lnum, it is 'taken' at mount time or whenever a LEB is retained by GC, + * but unlike other empty LEBs that are 'taken', it may not be written straight + * away (i.e. before the next commit start or unmount), so either gc_lnum must + * be specially accounted for, or the current approach followed i.e. count it + * under 'taken_empty_lebs'. + */ +struct ubifs_lp_stats { + int empty_lebs; + int taken_empty_lebs; + int idx_lebs; + long long total_free; + long long total_dirty; + long long total_used; + long long total_dead; + long long total_dark; +}; + +struct ubifs_nnode; + +/** + * struct ubifs_cnode - LEB Properties Tree common node. + * @parent: parent nnode + * @cnext: next cnode to commit + * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE) + * @iip: index in parent + * @level: level in the tree (zero for pnodes, greater than zero for nnodes) + * @num: node number + */ +struct ubifs_cnode { + struct ubifs_nnode *parent; + struct ubifs_cnode *cnext; + unsigned long flags; + int iip; + int level; + int num; +}; + +/** + * struct ubifs_pnode - LEB Properties Tree leaf node. + * @parent: parent nnode + * @cnext: next cnode to commit + * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE) + * @iip: index in parent + * @level: level in the tree (always zero for pnodes) + * @num: node number + * @lprops: LEB properties array + */ +struct ubifs_pnode { + struct ubifs_nnode *parent; + struct ubifs_cnode *cnext; + unsigned long flags; + int iip; + int level; + int num; + struct ubifs_lprops lprops[UBIFS_LPT_FANOUT]; +}; + +/** + * struct ubifs_nbranch - LEB Properties Tree internal node branch. + * @lnum: LEB number of child + * @offs: offset of child + * @nnode: nnode child + * @pnode: pnode child + * @cnode: cnode child + */ +struct ubifs_nbranch { + int lnum; + int offs; + union { + struct ubifs_nnode *nnode; + struct ubifs_pnode *pnode; + struct ubifs_cnode *cnode; + }; +}; + +/** + * struct ubifs_nnode - LEB Properties Tree internal node. + * @parent: parent nnode + * @cnext: next cnode to commit + * @flags: flags (%DIRTY_LPT_NODE or %OBSOLETE_LPT_NODE) + * @iip: index in parent + * @level: level in the tree (always greater than zero for nnodes) + * @num: node number + * @nbranch: branches to child nodes + */ +struct ubifs_nnode { + struct ubifs_nnode *parent; + struct ubifs_cnode *cnext; + unsigned long flags; + int iip; + int level; + int num; + struct ubifs_nbranch nbranch[UBIFS_LPT_FANOUT]; +}; + +/** + * struct ubifs_lpt_heap - heap of categorized lprops. + * @arr: heap array + * @cnt: number in heap + * @max_cnt: maximum number allowed in heap + * + * There are %LPROPS_HEAP_CNT heaps. + */ +struct ubifs_lpt_heap { + struct ubifs_lprops **arr; + int cnt; + int max_cnt; +}; + +/* + * Return codes for LPT scan callback function. + * + * LPT_SCAN_CONTINUE: continue scanning + * LPT_SCAN_ADD: add the LEB properties scanned to the tree in memory + * LPT_SCAN_STOP: stop scanning + */ +enum { + LPT_SCAN_CONTINUE = 0, + LPT_SCAN_ADD = 1, + LPT_SCAN_STOP = 2, +}; + +struct ubifs_info; + +/* Callback used by the 'ubifs_lpt_scan_nolock()' function */ +typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, + const struct ubifs_lprops *lprops, + int in_tree, void *data); + +/** + * struct ubifs_wbuf - UBIFS write-buffer. + * @c: UBIFS file-system description object + * @buf: write-buffer (of min. flash I/O unit size) + * @lnum: logical eraseblock number the write-buffer points to + * @offs: write-buffer offset in this logical eraseblock + * @avail: number of bytes available in the write-buffer + * @used: number of used bytes in the write-buffer + * @dtype: type of data stored in this LEB (%UBI_LONGTERM, %UBI_SHORTTERM, + * %UBI_UNKNOWN) + * @jhead: journal head the mutex belongs to (note, needed only to shut lockdep + * up by 'mutex_lock_nested()). + * @sync_callback: write-buffer synchronization callback + * @io_mutex: serializes write-buffer I/O + * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes + * fields + * @timer: write-buffer timer + * @timeout: timer expire interval in jiffies + * @need_sync: it is set if its timer expired and needs sync + * @next_ino: points to the next position of the following inode number + * @inodes: stores the inode numbers of the nodes which are in wbuf + * + * The write-buffer synchronization callback is called when the write-buffer is + * synchronized in order to notify how much space was wasted due to + * write-buffer padding and how much free space is left in the LEB. + * + * Note: the fields @buf, @lnum, @offs, @avail and @used can be read under + * spin-lock or mutex because they are written under both mutex and spin-lock. + * @buf is appended to under mutex but overwritten under both mutex and + * spin-lock. Thus the data between @buf and @buf + @used can be read under + * spinlock. + */ +struct ubifs_wbuf { + struct ubifs_info *c; + void *buf; + int lnum; + int offs; + int avail; + int used; + int dtype; + int jhead; + int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); + struct mutex io_mutex; + spinlock_t lock; + struct timer_list timer; + int timeout; + int need_sync; + int next_ino; + ino_t *inodes; +}; + +/** + * struct ubifs_bud - bud logical eraseblock. + * @lnum: logical eraseblock number + * @start: where the (uncommitted) bud data starts + * @jhead: journal head number this bud belongs to + * @list: link in the list buds belonging to the same journal head + * @rb: link in the tree of all buds + */ +struct ubifs_bud { + int lnum; + int start; + int jhead; + struct list_head list; + struct rb_node rb; +}; + +/** + * struct ubifs_jhead - journal head. + * @wbuf: head's write-buffer + * @buds_list: list of bud LEBs belonging to this journal head + * + * Note, the @buds list is protected by the @c->buds_lock. + */ +struct ubifs_jhead { + struct ubifs_wbuf wbuf; + struct list_head buds_list; +}; + +/** + * struct ubifs_zbranch - key/coordinate/length branch stored in znodes. + * @key: key + * @znode: znode address in memory + * @lnum: LEB number of the indexing node + * @offs: offset of the indexing node within @lnum + * @len: target node length + */ +struct ubifs_zbranch { + union ubifs_key key; + union { + struct ubifs_znode *znode; + void *leaf; + }; + int lnum; + int offs; + int len; +}; + +/** + * struct ubifs_znode - in-memory representation of an indexing node. + * @parent: parent znode or NULL if it is the root + * @cnext: next znode to commit + * @flags: znode flags (%DIRTY_ZNODE, %COW_ZNODE or %OBSOLETE_ZNODE) + * @time: last access time (seconds) + * @level: level of the entry in the TNC tree + * @child_cnt: count of child znodes + * @iip: index in parent's zbranch array + * @alt: lower bound of key range has altered i.e. child inserted at slot 0 + * @lnum: LEB number of the corresponding indexing node + * @offs: offset of the corresponding indexing node + * @len: length of the corresponding indexing node + * @zbranch: array of znode branches (@c->fanout elements) + */ +struct ubifs_znode { + struct ubifs_znode *parent; + struct ubifs_znode *cnext; + unsigned long flags; + unsigned long time; + int level; + int child_cnt; + int iip; + int alt; +#ifdef CONFIG_UBIFS_FS_DEBUG + int lnum, offs, len; +#endif + struct ubifs_zbranch zbranch[]; +}; + +/** + * struct ubifs_node_range - node length range description data structure. + * @len: fixed node length + * @min_len: minimum possible node length + * @max_len: maximum possible node length + * + * If @max_len is %0, the node has fixed length @len. + */ +struct ubifs_node_range { + union { + int len; + int min_len; + }; + int max_len; +}; + +/** + * struct ubifs_compressor - UBIFS compressor description structure. + * @compr_type: compressor type (%UBIFS_COMPR_LZO, etc) + * @cc: cryptoapi compressor handle + * @comp_mutex: mutex used during compression + * @decomp_mutex: mutex used during decompression + * @name: compressor name + * @capi_name: cryptoapi compressor name + */ +struct ubifs_compressor { + int compr_type; + struct crypto_comp *cc; + struct mutex *comp_mutex; + struct mutex *decomp_mutex; + const char *name; + const char *capi_name; +}; + +/** + * struct ubifs_budget_req - budget requirements of an operation. + * + * @fast: non-zero if the budgeting should try to aquire budget quickly and + * should not try to call write-back + * @recalculate: non-zero if @idx_growth, @data_growth, and @dd_growth fields + * have to be re-calculated + * @new_page: non-zero if the operation adds a new page + * @dirtied_page: non-zero if the operation makes a page dirty + * @new_dent: non-zero if the operation adds a new directory entry + * @mod_dent: non-zero if the operation removes or modifies an existing + * directory entry + * @new_ino: non-zero if the operation adds a new inode + * @new_ino_d: now much data newly created inode contains + * @dirtied_ino: how many inodes the operation makes dirty + * @dirtied_ino_d: now much data dirtied inode contains + * @idx_growth: how much the index will supposedly grow + * @data_growth: how much new data the operation will supposedly add + * @dd_growth: how much data that makes other data dirty the operation will + * supposedly add + * + * @idx_growth, @data_growth and @dd_growth are not used in budget request. The + * budgeting subsystem caches index and data growth values there to avoid + * re-calculating them when the budget is released. However, if @idx_growth is + * %-1, it is calculated by the release function using other fields. + * + * An inode may contain 4KiB of data at max., thus the widths of @new_ino_d + * is 13 bits, and @dirtied_ino_d - 15, because up to 4 inodes may be made + * dirty by the re-name operation. + */ +struct ubifs_budget_req { + unsigned int fast:1; + unsigned int recalculate:1; + unsigned int new_page:1; + unsigned int dirtied_page:1; + unsigned int new_dent:1; + unsigned int mod_dent:1; + unsigned int new_ino:1; + unsigned int new_ino_d:13; +#ifndef UBIFS_DEBUG + unsigned int dirtied_ino:4; + unsigned int dirtied_ino_d:15; +#else + /* Not bit-fields to check for overflows */ + unsigned int dirtied_ino; + unsigned int dirtied_ino_d; +#endif + int idx_growth; + int data_growth; + int dd_growth; +}; + +/** + * struct ubifs_orphan - stores the inode number of an orphan. + * @rb: rb-tree node of rb-tree of orphans sorted by inode number + * @list: list head of list of orphans in order added + * @new_list: list head of list of orphans added since the last commit + * @cnext: next orphan to commit + * @dnext: next orphan to delete + * @inum: inode number + * @new: %1 => added since the last commit, otherwise %0 + */ +struct ubifs_orphan { + struct rb_node rb; + struct list_head list; + struct list_head new_list; + struct ubifs_orphan *cnext; + struct ubifs_orphan *dnext; + ino_t inum; + int new; +}; + +/** + * struct ubifs_mount_opts - UBIFS-specific mount options information. + * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast) + */ +struct ubifs_mount_opts { + unsigned int unmount_mode:2; +}; + +/** + * struct ubifs_info - UBIFS file-system description data structure + * (per-superblock). + * @vfs_sb: VFS @struct super_block object + * @bdi: backing device info object to make VFS happy and disable readahead + * + * @highest_inum: highest used inode number + * @vfs_gen: VFS inode generation counter + * @max_sqnum: current global sequence number + * @cmt_no: commit number (last successfully completed commit) + * @cnt_lock: protects @highest_inum, @vfs_gen, and @max_sqnum counters + * @fmt_version: UBIFS on-flash format version + * @uuid: UUID from super block + * + * @lhead_lnum: log head logical eraseblock number + * @lhead_offs: log head offset + * @ltail_lnum: log tail logical eraseblock number (offset is always 0) + * @log_mutex: protects the log, @lhead_lnum, @lhead_offs, @ltail_lnum, and + * @bud_bytes + * @min_log_bytes: minimum required number of bytes in the log + * @cmt_bud_bytes: used during commit to temporarily amount of bytes in + * committed buds + * + * @buds: tree of all buds indexed by bud LEB number + * @bud_bytes: how many bytes of flash is used by buds + * @buds_lock: protects the @buds tree, @bud_bytes, and per-journal head bud + * lists + * @jhead_cnt: count of journal heads + * @jheads: journal heads (head zero is base head) + * @max_bud_bytes: maximum number of bytes allowed in buds + * @bg_bud_bytes: number of bud bytes when background commit is initiated + * @old_buds: buds to be released after commit ends + * @max_bud_cnt: maximum number of buds + * + * @commit_sem: synchronizes committer with other processes + * @cmt_state: commit state + * @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 + * @check_lpt_free: flag that indicates LPT GC may be needed + * @nospace: non-zero if the file-system does not have flash space (used as + * optimization) + * @nospace_rp: the same as @nospace, but additionally means that even reserved + * pool is full + * + * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and + * @calc_idx_sz + * @zroot: zbranch which points to the root index node and znode + * @cnext: next znode to commit + * @enext: next znode to commit to empty space + * @gap_lebs: array of LEBs used by the in-gaps commit method + * @cbuf: commit buffer + * @ileb_buf: buffer for commit in-the-gaps method + * @ileb_len: length of data in ileb_buf + * @ihead_lnum: LEB number of index head + * @ihead_offs: offset of index head + * @ilebs: pre-allocated index LEBs + * @ileb_cnt: number of pre-allocated index LEBs + * @ileb_nxt: next pre-allocated index LEBs + * @old_idx: tree of index nodes obsoleted since the last commit start + * @bottom_up_buf: a buffer which is used by 'dirty_cow_bottom_up()' in tnc.c + * @new_ihead_lnum: used by debugging to check ihead_lnum + * @new_ihead_offs: used by debugging to check ihead_offs + * + * @mst_node: master node + * @mst_offs: offset of valid master node + * @mst_mutex: protects the master node area, @mst_node, and @mst_offs + * + * @log_lebs: number of logical eraseblocks in the log + * @log_bytes: log size in bytes + * @log_last: last LEB of the log + * @lpt_lebs: number of LEBs used for lprops table + * @lpt_first: first LEB of the lprops table area + * @lpt_last: last LEB of the lprops table area + * @orph_lebs: number of LEBs used for the orphan area + * @orph_first: first LEB of the orphan area + * @orph_last: last LEB of the orphan area + * @main_lebs: count of LEBs in the main area + * @main_first: first LEB of the main area + * @main_bytes: main area size in bytes + * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) + * + * @key_hash_type: type of the key hash + * @key_hash: direntry key hash function + * @key_fmt: key format + * @key_len: key length + * @fanout: fanout of the index tree (number of links per indexing node) + * + * @min_io_size: minimal input/output unit size + * @min_io_shift: number of bits in @min_io_size minus one + * @leb_size: logical eraseblock size in bytes + * @half_leb_size: half LEB size + * @leb_cnt: count of logical eraseblocks + * @max_leb_cnt: maximum count of logical eraseblocks + * @old_leb_cnt: count of logical eraseblocks before re-size + * @ro_media: the underlying UBI volume is read-only + * + * @dirty_pg_cnt: number of dirty pages (not used) + * @dirty_zn_cnt: number of dirty znodes + * @clean_zn_cnt: number of clean znodes + * + * @budg_idx_growth: amount of bytes budgeted for index growth + * @budg_data_growth: amount of bytes budgeted for cached data + * @budg_dd_growth: amount of bytes budgeted for cached data that will make + * other data dirty + * @budg_uncommitted_idx: amount of bytes were budgeted for growth of the index, + * but which still have to be taken into account because + * the index has not been committed so far + * @space_lock: protects @budg_idx_growth, @budg_data_growth, @budg_dd_growth, + * @budg_uncommited_idx, @min_idx_lebs, @old_idx_sz, and @lst; + * @min_idx_lebs: minimum number of LEBs required for the index + * @old_idx_sz: size of index on flash + * @calc_idx_sz: temporary variable which is used to calculate new index size + * (contains accurate new index size at end of TNC commit start) + * @lst: lprops statistics + * + * @page_budget: budget for a page + * @inode_budget: budget for an inode + * @dent_budget: budget for a directory entry + * + * @ref_node_alsz: size of the LEB reference node aligned to the min. flash + * I/O unit + * @mst_node_alsz: master node aligned size + * @min_idx_node_sz: minimum indexing node aligned on 8-bytes boundary + * @max_idx_node_sz: maximum indexing node aligned on 8-bytes boundary + * @max_inode_sz: maximum possible inode size in bytes + * @max_znode_sz: size of znode in bytes + * @dead_wm: LEB dead space watermark + * @dark_wm: LEB dark space watermark + * @block_cnt: count of 4KiB blocks on the FS + * + * @ranges: UBIFS node length ranges + * @ubi: UBI volume descriptor + * @di: UBI device information + * @vi: UBI volume information + * + * @orph_tree: rb-tree of orphan inode numbers + * @orph_list: list of orphan inode numbers in order added + * @orph_new: list of orphan inode numbers added since last commit + * @orph_cnext: next orphan to commit + * @orph_dnext: next orphan to delete + * @orphan_lock: lock for orph_tree and orph_new + * @orph_buf: buffer for orphan nodes + * @new_orphans: number of orphans since last commit + * @cmt_orphans: number of orphans being committed + * @tot_orphans: number of orphans in the rb_tree + * @max_orphans: maximum number of orphans allowed + * @ohead_lnum: orphan head LEB number + * @ohead_offs: orphan head offset + * @no_orphs: non-zero if there are no orphans + * + * @bgt: UBIFS background thread + * @bgt_name: background thread name + * @need_bgt: if background thread should run + * @need_wbuf_sync: if write-buffers have to be synchronized + * + * @gc_lnum: LEB number used for garbage collection + * @sbuf: a buffer of LEB size used by GC and replay for scanning + * @idx_gc: list of index LEBs that have been garbage collected + * @idx_gc_cnt: number of elements on the idx_gc list + * + * @infos_list: links all 'ubifs_info' objects + * @umount_mutex: serializes shrinker and un-mount + * @shrinker_run_no: shrinker run number + * + * @space_bits: number of bits needed to record free or dirty space + * @lpt_lnum_bits: number of bits needed to record a LEB number in the LPT + * @lpt_offs_bits: number of bits needed to record an offset in the LPT + * @lpt_spc_bits: number of bits needed to space in the LPT + * @pcnt_bits: number of bits needed to record pnode or nnode number + * @lnum_bits: number of bits needed to record LEB number + * @nnode_sz: size of on-flash nnode + * @pnode_sz: size of on-flash pnode + * @ltab_sz: size of on-flash LPT lprops table + * @lsave_sz: size of on-flash LPT save table + * @pnode_cnt: number of pnodes + * @nnode_cnt: number of nnodes + * @lpt_hght: height of the LPT + * @pnodes_have: number of pnodes in memory + * + * @lp_mutex: protects lprops table and all the other lprops-related fields + * @lpt_lnum: LEB number of the root nnode of the LPT + * @lpt_offs: offset of the root nnode of the LPT + * @nhead_lnum: LEB number of LPT head + * @nhead_offs: offset of LPT head + * @lpt_drty_flgs: dirty flags for LPT special nodes e.g. ltab + * @dirty_nn_cnt: number of dirty nnodes + * @dirty_pn_cnt: number of dirty pnodes + * @lpt_sz: LPT size + * @lpt_nod_buf: buffer for an on-flash nnode or pnode + * @lpt_buf: buffer of LEB size used by LPT + * @nroot: address in memory of the root nnode of the LPT + * @lpt_cnext: next LPT node to commit + * @lpt_heap: array of heaps of categorized lprops + * @dirty_idx: a (reverse sorted) copy of the LPROPS_DIRTY_IDX heap as at + * previous commit start + * @uncat_list: list of un-categorized LEBs + * @empty_list: list of empty LEBs + * @freeable_list: list of freeable non-index LEBs (free + dirty == leb_size) + * @frdi_idx_list: list of freeable index LEBs (free + dirty == leb_size) + * @freeable_cnt: number of freeable LEBs in @freeable_list + * + * @ltab_lnum: LEB number of LPT's own lprops table + * @ltab_offs: offset of LPT's own lprops table + * @ltab: LPT's own lprops table + * @ltab_cmt: LPT's own lprops table (commit copy) + * @lsave_cnt: number of LEB numbers in LPT's save table + * @lsave_lnum: LEB number of LPT's save table + * @lsave_offs: offset of LPT's save table + * @lsave: LPT's save table + * @lscan_lnum: LEB number of last LPT scan + * + * @rp_size: size of the reserved pool in bytes + * @report_rp_size: size of the reserved pool reported to user-space + * @rp_uid: reserved pool user ID + * @rp_gid: reserved pool group ID + * + * @empty: if the UBI device is empty + * @replay_tree: temporary tree used during journal replay + * @replay_list: temporary list used during journal replay + * @replay_buds: list of buds to replay + * @cs_sqnum: sequence number of first node in the log (commit start node) + * @replay_sqnum: sequence number of node currently being replayed + * @need_recovery: file-system needs recovery + * @replaying: set to %1 during journal replay + * @unclean_leb_list: LEBs to recover when mounting ro to rw + * @rcvrd_mst_node: recovered master node to write when mounting ro to rw + * @size_tree: inode size information for recovery + * @remounting_rw: set while remounting from ro to rw (sb flags have MS_RDONLY) + * @mount_opts: UBIFS-specific mount options + * + * @dbg_buf: a buffer of LEB size used for debugging purposes + * @old_zroot: old index root - used by 'dbg_check_old_index()' + * @old_zroot_level: old index root level - used by 'dbg_check_old_index()' + * @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()' + * @failure_mode: failure mode for recovery testing + * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls + * @fail_timeout: time in jiffies when delay of failure mode expires + * @fail_cnt: current number of calls to failure mode I/O functions + * @fail_cnt_max: number of calls by which to delay failure mode + */ +struct ubifs_info { + struct super_block *vfs_sb; + struct backing_dev_info bdi; + + ino_t highest_inum; + unsigned int vfs_gen; + unsigned long long max_sqnum; + unsigned long long cmt_no; + spinlock_t cnt_lock; + int fmt_version; + unsigned char uuid[16]; + + int lhead_lnum; + int lhead_offs; + int ltail_lnum; + struct mutex log_mutex; + int min_log_bytes; + long long cmt_bud_bytes; + + struct rb_root buds; + long long bud_bytes; + spinlock_t buds_lock; + int jhead_cnt; + struct ubifs_jhead *jheads; + long long max_bud_bytes; + long long bg_bud_bytes; + struct list_head old_buds; + int max_bud_cnt; + + struct rw_semaphore commit_sem; + int cmt_state; + spinlock_t cs_lock; + wait_queue_head_t cmt_wq; + unsigned int fast_unmount:1; + unsigned int big_lpt:1; + unsigned int check_lpt_free:1; + unsigned int nospace:1; + unsigned int nospace_rp:1; + + struct mutex tnc_mutex; + struct ubifs_zbranch zroot; + struct ubifs_znode *cnext; + struct ubifs_znode *enext; + int *gap_lebs; + void *cbuf; + void *ileb_buf; + int ileb_len; + int ihead_lnum; + int ihead_offs; + int *ilebs; + int ileb_cnt; + int ileb_nxt; + struct rb_root old_idx; + int *bottom_up_buf; +#ifdef CONFIG_UBIFS_FS_DEBUG + int new_ihead_lnum; + int new_ihead_offs; +#endif + + struct ubifs_mst_node *mst_node; + int mst_offs; + struct mutex mst_mutex; + + int log_lebs; + long long log_bytes; + int log_last; + int lpt_lebs; + int lpt_first; + int lpt_last; + int orph_lebs; + int orph_first; + int orph_last; + int main_lebs; + int main_first; + long long main_bytes; + int default_compr; + + uint8_t key_hash_type; + uint32_t (*key_hash)(const char *str, int len); + int key_fmt; + int key_len; + int fanout; + + int min_io_size; + int min_io_shift; + int leb_size; + int half_leb_size; + int leb_cnt; + int max_leb_cnt; + int old_leb_cnt; + int ro_media; + + atomic_long_t dirty_pg_cnt; + atomic_long_t dirty_zn_cnt; + atomic_long_t clean_zn_cnt; + + long long budg_idx_growth; + long long budg_data_growth; + long long budg_dd_growth; + long long budg_uncommitted_idx; + spinlock_t space_lock; + int min_idx_lebs; + unsigned long long old_idx_sz; + unsigned long long calc_idx_sz; + struct ubifs_lp_stats lst; + + int page_budget; + int inode_budget; + int dent_budget; + + int ref_node_alsz; + int mst_node_alsz; + int min_idx_node_sz; + int max_idx_node_sz; + long long max_inode_sz; + int max_znode_sz; + int dead_wm; + int dark_wm; + int block_cnt; + + struct ubifs_node_range ranges[UBIFS_NODE_TYPES_CNT]; + struct ubi_volume_desc *ubi; + struct ubi_device_info di; + struct ubi_volume_info vi; + + struct rb_root orph_tree; + struct list_head orph_list; + struct list_head orph_new; + struct ubifs_orphan *orph_cnext; + struct ubifs_orphan *orph_dnext; + spinlock_t orphan_lock; + void *orph_buf; + int new_orphans; + int cmt_orphans; + int tot_orphans; + int max_orphans; + int ohead_lnum; + int ohead_offs; + int no_orphs; + + struct task_struct *bgt; + char bgt_name[sizeof(BGT_NAME_PATTERN) + 9]; + int need_bgt; + int need_wbuf_sync; + + int gc_lnum; + void *sbuf; + struct list_head idx_gc; + int idx_gc_cnt; + + struct list_head infos_list; + struct mutex umount_mutex; + unsigned int shrinker_run_no; + + int space_bits; + int lpt_lnum_bits; + int lpt_offs_bits; + int lpt_spc_bits; + int pcnt_bits; + int lnum_bits; + int nnode_sz; + int pnode_sz; + int ltab_sz; + int lsave_sz; + int pnode_cnt; + int nnode_cnt; + int lpt_hght; + int pnodes_have; + + struct mutex lp_mutex; + int lpt_lnum; + int lpt_offs; + int nhead_lnum; + int nhead_offs; + int lpt_drty_flgs; + int dirty_nn_cnt; + int dirty_pn_cnt; + long long lpt_sz; + void *lpt_nod_buf; + void *lpt_buf; + struct ubifs_nnode *nroot; + struct ubifs_cnode *lpt_cnext; + struct ubifs_lpt_heap lpt_heap[LPROPS_HEAP_CNT]; + struct ubifs_lpt_heap dirty_idx; + struct list_head uncat_list; + struct list_head empty_list; + struct list_head freeable_list; + struct list_head frdi_idx_list; + int freeable_cnt; + + int ltab_lnum; + int ltab_offs; + struct ubifs_lpt_lprops *ltab; + struct ubifs_lpt_lprops *ltab_cmt; + int lsave_cnt; + int lsave_lnum; + int lsave_offs; + int *lsave; + int lscan_lnum; + + long long rp_size; + long long report_rp_size; + uid_t rp_uid; + gid_t rp_gid; + + /* The below fields are used only during mounting and re-mounting */ + int empty; + struct rb_root replay_tree; + struct list_head replay_list; + struct list_head replay_buds; + unsigned long long cs_sqnum; + unsigned long long replay_sqnum; + int need_recovery; + int replaying; + struct list_head unclean_leb_list; + struct ubifs_mst_node *rcvrd_mst_node; + struct rb_root size_tree; + int remounting_rw; + struct ubifs_mount_opts mount_opts; + +#ifdef CONFIG_UBIFS_FS_DEBUG + void *dbg_buf; + struct ubifs_zbranch old_zroot; + int old_zroot_level; + unsigned long long old_zroot_sqnum; + int failure_mode; + int fail_delay; + unsigned long fail_timeout; + unsigned int fail_cnt; + unsigned int fail_cnt_max; +#endif +}; + +extern struct list_head ubifs_infos; +extern spinlock_t ubifs_infos_lock; +extern atomic_long_t ubifs_clean_zn_cnt; +extern struct kmem_cache *ubifs_inode_slab; +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]; + +/* io.c */ +int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); +int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, + int dtype); +int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf); +int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, + int lnum, int offs); +int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, + int lnum, int offs); +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); +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); +void ubifs_pad(const struct ubifs_info *c, void *buf, int pad); +int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf); +int ubifs_bg_wbufs_sync(struct ubifs_info *c); +void ubifs_wbuf_add_ino_nolock(struct ubifs_wbuf *wbuf, ino_t inum); +int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode); + +/* scan.c */ +struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, + int offs, void *sbuf); +void ubifs_scan_destroy(struct ubifs_scan_leb *sleb); +int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, + int offs, int quiet); +struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, + int offs, void *sbuf); +void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, + int lnum, int offs); +int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, + void *buf, int offs); +void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, + void *buf); + +/* log.c */ +void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud); +void ubifs_create_buds_lists(struct ubifs_info *c); +int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs); +struct ubifs_bud *ubifs_search_bud(struct ubifs_info *c, int lnum); +struct ubifs_wbuf *ubifs_get_wbuf(struct ubifs_info *c, int lnum); +int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum); +int ubifs_log_end_commit(struct ubifs_info *c, int new_ltail_lnum); +int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum); +int ubifs_consolidate_log(struct ubifs_info *c); + +/* journal.c */ +int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, + const struct qstr *nm, const struct inode *inode, + int deletion, int xent); +int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, + const union ubifs_key *key, const void *buf, int len); +int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode, + int last_reference); +int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, + const struct dentry *old_dentry, + const struct inode *new_dir, + const struct dentry *new_dentry, int sync); +int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, + loff_t old_size, loff_t new_size); +int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, + const struct inode *inode, const struct qstr *nm); +int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode1, + const struct inode *inode2); + +/* budget.c */ +int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req); +void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req); +void ubifs_release_dirty_inode_budget(struct ubifs_info *c, + struct ubifs_inode *ui); +int ubifs_budget_inode_op(struct ubifs_info *c, struct inode *inode, + struct ubifs_budget_req *req); +void ubifs_release_ino_dirty(struct ubifs_info *c, struct inode *inode, + struct ubifs_budget_req *req); +void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode, + struct ubifs_budget_req *req); +long long ubifs_budg_get_free_space(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_calc_available(const struct ubifs_info *c, int min_idx_lebs); + +/* find.c */ +int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, + int squeeze); +int ubifs_find_free_leb_for_idx(struct ubifs_info *c); +int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, + int min_space, int pick_free); +int ubifs_find_dirty_idx_leb(struct ubifs_info *c); +int ubifs_save_dirty_idx_lnums(struct ubifs_info *c); + +/* tnc.c */ +int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_znode **zn, int *n); +int ubifs_tnc_lookup(struct ubifs_info *c, const union ubifs_key *key, + void *node); +int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, + void *node, const struct qstr *nm); +int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, + void *node, int *lnum, int *offs); +int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, + int offs, int len); +int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, + int old_lnum, int old_offs, int lnum, int offs, int len); +int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, + int lnum, int offs, int len, const struct qstr *nm); +int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); +int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, + const struct qstr *nm); +int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, + union ubifs_key *to_key); +int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum); +struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, + union ubifs_key *key, + const struct qstr *nm); +void ubifs_tnc_close(struct ubifs_info *c); +int ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs, int is_idx); +int ubifs_dirty_idx_node(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs); +/* Shared by tnc.c for tnc_commit.c */ +void destroy_old_idx(struct ubifs_info *c); +int is_idx_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs); +int insert_old_idx_znode(struct ubifs_info *c, struct ubifs_znode *znode); + +/* tnc_misc.c */ +struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr, + struct ubifs_znode *znode); +int ubifs_search_zbranch(const struct ubifs_info *c, + const struct ubifs_znode *znode, + const union ubifs_key *key, int *n); +struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode); +struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode); +long ubifs_destroy_tnc_subtree(struct ubifs_znode *zr); +struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c, + struct ubifs_zbranch *zbr, + struct ubifs_znode *parent, int iip); +int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *node); + +/* tnc_commit.c */ +int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot); +int ubifs_tnc_end_commit(struct ubifs_info *c); + +/* shrinker.c */ +int ubifs_shrinker(int nr_to_scan, gfp_t gfp_mask); + +/* commit.c */ +int ubifs_bg_thread(void *info); +void ubifs_commit_required(struct ubifs_info *c); +void ubifs_request_bg_commit(struct ubifs_info *c); +int ubifs_run_commit(struct ubifs_info *c); +void ubifs_recovery_commit(struct ubifs_info *c); +int ubifs_gc_should_commit(struct ubifs_info *c); +void ubifs_wait_for_commit(struct ubifs_info *c); + +/* master.c */ +int ubifs_read_master(struct ubifs_info *c); +int ubifs_write_master(struct ubifs_info *c); + +/* sb.c */ +int ubifs_read_superblock(struct ubifs_info *c); +struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c); +int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup); + +/* replay.c */ +int ubifs_validate_entry(struct ubifs_info *c, + const struct ubifs_dent_node *dent); +int ubifs_replay_journal(struct ubifs_info *c); + +/* gc.c */ +int ubifs_garbage_collect(struct ubifs_info *c, int anyway); +int ubifs_gc_start_commit(struct ubifs_info *c); +int ubifs_gc_end_commit(struct ubifs_info *c); +void ubifs_destroy_idx_gc(struct ubifs_info *c); +int ubifs_get_idx_gc_leb(struct ubifs_info *c); +int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp); + +/* orphan.c */ +int ubifs_add_orphan(struct ubifs_info *c, ino_t inum); +void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum); +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); + +/* lpt.c */ +int ubifs_calc_lpt_geom(struct ubifs_info *c); +int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, + int *lpt_lebs, int *big_lpt); +int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr); +struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum); +struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum); +int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum, + ubifs_lpt_scan_callback scan_cb, void *data); + +/* Shared by lpt.c for lpt_commit.c */ +void ubifs_pack_lsave(struct ubifs_info *c, void *buf, int *lsave); +void ubifs_pack_ltab(struct ubifs_info *c, void *buf, + struct ubifs_lpt_lprops *ltab); +void ubifs_pack_pnode(struct ubifs_info *c, void *buf, + struct ubifs_pnode *pnode); +void ubifs_pack_nnode(struct ubifs_info *c, void *buf, + struct ubifs_nnode *nnode); +struct ubifs_pnode *ubifs_get_pnode(struct ubifs_info *c, + struct ubifs_nnode *parent, int iip); +struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c, + struct ubifs_nnode *parent, int iip); +int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip); +void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); +void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); +uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits); +struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght); + +/* lpt_commit.c */ +int ubifs_lpt_start_commit(struct ubifs_info *c); +int ubifs_lpt_end_commit(struct ubifs_info *c); +int ubifs_lpt_post_commit(struct ubifs_info *c); +void ubifs_lpt_free(struct ubifs_info *c, int wr_only); + +/* lprops.c */ +void ubifs_get_lprops(struct ubifs_info *c); +const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, + const struct ubifs_lprops *lp, + int free, int dirty, int flags, + int idx_gc_cnt); +void ubifs_release_lprops(struct ubifs_info *c); +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, + struct ubifs_lprops *new_lprops); +void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops); +int ubifs_categorize_lprops(const struct ubifs_info *c, + const struct ubifs_lprops *lprops); +int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, + int flags_set, int flags_clean, int idx_gc_cnt); +int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, + int flags_set, int flags_clean); +int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp); +const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c); +const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c); +const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c); +const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c); + +/* file.c */ +int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync); +int ubifs_setattr(struct dentry *dentry, struct iattr *attr); + +/* dir.c */ +struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, + int mode); +int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat); + +/* xattr.c */ +int ubifs_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); +ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, + size_t size); +ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); +int ubifs_removexattr(struct dentry *dentry, const char *name); + +/* super.c */ +struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); + +/* recovery.c */ +int ubifs_recover_master_node(struct ubifs_info *c); +int ubifs_write_rcvrd_mst_node(struct ubifs_info *c); +struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, + int offs, void *sbuf, int grouped); +struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, + int offs, void *sbuf); +int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); +int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf); +int ubifs_rcvry_gc_commit(struct ubifs_info *c); +int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, + int deletion, loff_t new_size); +int ubifs_recover_size(struct ubifs_info *c); +void ubifs_destroy_size_tree(struct ubifs_info *c); + +/* ioctl.c */ +long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +void ubifs_set_inode_flags(struct inode *inode); +#ifdef CONFIG_COMPAT +long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#endif + +/* compressor.c */ +int __init ubifs_compressors_init(void); +void __exit ubifs_compressors_exit(void); +void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, + int *compr_type); +int ubifs_decompress(const void *buf, int len, void *out, int *out_len, + int compr_type); + +#include "debug.h" +#include "misc.h" +#include "key.h" + +#endif /* !__UBIFS_H__ */ diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c new file mode 100644 index 0000000..1388a07 --- /dev/null +++ b/fs/ubifs/xattr.c @@ -0,0 +1,581 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * 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., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +/* + * This file implements UBIFS extended attributes support. + * + * Extended attributes are implemented as regular inodes with attached data, + * which limits extended attribute size to UBIFS block size (4KiB). Names of + * extended attributes are described by extended attribute entries (xentries), + * which are almost identical to directory entries, but have different key type. + * + * In other words, the situation with extended attributes is very similar to + * directories. Indeed, any inode (but of course not xattr inodes) may have a + * number of associated xentries, just like directory inodes have associated + * directory entries. Extended attribute entries store the name of the extended + * attribute, the host inode number, and the extended attribute inode number. + * Similarly, direntries store the name, the parent and the target inode + * numbers. Thus, most of the common UBIFS mechanisms may be re-used for + * extended attributes. + * + * The number of extended attributes is not limited, but there is Linux + * limitation on the maximum possible size of the list of all extended + * attributes associated with an inode (%XATTR_LIST_MAX), so UBIFS makes sure + * the sum of all extended attribute names of the inode does not exceed that + * limit. + * + * Extended attributes are synchronous, which means they are written to the + * flash media synchronously and there is no write-back for extended attribute + * inodes. The extended attribute values are not stored in compressed form on + * the media. + * + * Since extended attributes are represented by regular inodes, they are cached + * in the VFS inode cache. The xentries are cached in the LNC cache (see + * tnc.c). + * + * ACL support is not implemented. + */ + +#include +#include +#include "ubifs.h" + +/* + * Limit the number of extended attributes per inode so that the total size + * (xattr_size) is guaranteeded to fit in an 'unsigned int'. + */ +#define MAX_XATTRS_PER_INODE 65535 + +/* + * Extended attribute type constants. + * + * USER_XATTR: user extended attribute ("user.*") + * TRUSTED_XATTR: trusted extended attribute ("trusted.*) + * SECURITY_XATTR: security extended attribute ("security.*") + */ +enum { + USER_XATTR, + TRUSTED_XATTR, + SECURITY_XATTR, +}; + +static struct inode_operations none_inode_operations; +static struct address_space_operations none_address_operations; +static struct file_operations none_file_operations; + +/** + * create_xattr - create an extended attribute. + * @c: UBIFS file-system description object + * @host: host inode + * @nm: extended attribute name + * @value: extended attribute value + * @size: size of extended attribute value + * + * This is a helper function which creates an extended attribute of name @nm + * and value @value for inode @host. The host inode is also updated on flash + * because the ctime and extended attribute accounting data changes. This + * function returns zero in case of success and a negative error code in case + * of failure. + */ +static int create_xattr(struct ubifs_info *c, struct inode *host, + const struct qstr *nm, const void *value, int size) +{ + int err; + struct inode *inode; + struct ubifs_inode *ui, *host_ui = ubifs_inode(host); + struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, + .new_ino_d = size, .dirtied_ino = 1, + .dirtied_ino_d = host_ui->data_len}; + + if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) + return -ENOSPC; + /* + * Linux limits the maximum size of the extended attribute names list + * to %XATTR_LIST_MAX. This means we should not allow creating more* + * extended attributes if the name list becomes larger. This limitation + * is artificial for UBIFS, though. + */ + if (host_ui->xattr_names + host_ui->xattr_cnt + + nm->len + 1 > XATTR_LIST_MAX) + return -ENOSPC; + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + inode = ubifs_new_inode(c, host, S_IFREG | S_IRWXUGO); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_budg; + } + + mutex_lock(&host_ui->ui_mutex); + /* Re-define all operations to be "nothing" */ + inode->i_mapping->a_ops = &none_address_operations; + inode->i_op = &none_inode_operations; + inode->i_fop = &none_file_operations; + + inode->i_flags |= S_SYNC | S_NOATIME | S_NOCMTIME | S_NOQUOTA; + ui = ubifs_inode(inode); + ui->xattr = 1; + ui->flags |= UBIFS_XATTR_FL; + ui->data = kmalloc(size, GFP_NOFS); + if (!ui->data) { + err = -ENOMEM; + goto out_unlock; + } + + memcpy(ui->data, value, size); + host->i_ctime = ubifs_current_time(host); + host_ui->xattr_cnt += 1; + host_ui->xattr_size += CALC_DENT_SIZE(nm->len); + host_ui->xattr_size += CALC_XATTR_BYTES(size); + host_ui->xattr_names += nm->len; + + /* + * We do not use i_size_write() because nobody can race with us as we + * are holding host @host->i_mutex - every xattr operation for this + * inode is serialized by it. + */ + inode->i_size = ui->ui_size = size; + ui->data_len = size; + err = ubifs_jnl_update(c, host, nm, inode, 0, 1); + if (err) + goto out_cancel; + mutex_unlock(&host_ui->ui_mutex); + + ubifs_release_budget(c, &req); + insert_inode_hash(inode); + iput(inode); + return 0; + +out_cancel: + host_ui->xattr_cnt -= 1; + host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); + host_ui->xattr_size -= CALC_XATTR_BYTES(size); +out_unlock: + mutex_unlock(&host_ui->ui_mutex); + make_bad_inode(inode); + iput(inode); +out_budg: + ubifs_release_budget(c, &req); + return err; +} + +/** + * change_xattr - change an extended attribute. + * @c: UBIFS file-system description object + * @host: host inode + * @inode: extended attribute inode + * @value: extended attribute value + * @size: size of extended attribute value + * + * This helper function changes the value of extended attribute @inode with new + * data from @value. Returns zero in case of success and a negative error code + * in case of failure. + */ +static int change_xattr(struct ubifs_info *c, struct inode *host, + struct inode *inode, const void *value, int size) +{ + int err; + struct ubifs_inode *host_ui = ubifs_inode(host); + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_budget_req req = { .dirtied_ino = 2, + .dirtied_ino_d = size + host_ui->data_len }; + + ubifs_assert(ui->data_len == inode->i_size); + err = ubifs_budget_space(c, &req); + if (err) + return err; + + mutex_lock(&host_ui->ui_mutex); + host->i_ctime = ubifs_current_time(host); + host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len); + host_ui->xattr_size += CALC_XATTR_BYTES(size); + + kfree(ui->data); + ui->data = kmalloc(size, GFP_NOFS); + if (!ui->data) { + err = -ENOMEM; + goto out_unlock; + } + + memcpy(ui->data, value, size); + inode->i_size = ui->ui_size = size; + ui->data_len = size; + + /* + * It is important to write the host inode after the xattr inode + * because if the host inode gets synchronized (via 'fsync()'), then + * the extended attribute inode gets synchronized, because it goes + * before the host inode in the write-buffer. + */ + err = ubifs_jnl_change_xattr(c, inode, host); + if (err) + goto out_cancel; + mutex_unlock(&host_ui->ui_mutex); + + ubifs_release_budget(c, &req); + return 0; + +out_cancel: + host_ui->xattr_size -= CALC_XATTR_BYTES(size); + host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); + make_bad_inode(inode); +out_unlock: + mutex_unlock(&host_ui->ui_mutex); + ubifs_release_budget(c, &req); + return err; +} + +/** + * check_namespace - check extended attribute name-space. + * @nm: extended attribute name + * + * This function makes sure the extended attribute name belongs to one of the + * supported extended attribute name-spaces. Returns name-space index in case + * of success and a negative error code in case of failure. + */ +static int check_namespace(const struct qstr *nm) +{ + int type; + + if (nm->len > UBIFS_MAX_NLEN) + return -ENAMETOOLONG; + + if (!strncmp(nm->name, XATTR_TRUSTED_PREFIX, + XATTR_TRUSTED_PREFIX_LEN)) { + if (nm->name[sizeof(XATTR_TRUSTED_PREFIX) - 1] == '\0') + return -EINVAL; + type = TRUSTED_XATTR; + } else if (!strncmp(nm->name, XATTR_USER_PREFIX, + XATTR_USER_PREFIX_LEN)) { + if (nm->name[XATTR_USER_PREFIX_LEN] == '\0') + return -EINVAL; + type = USER_XATTR; + } else if (!strncmp(nm->name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN)) { + if (nm->name[sizeof(XATTR_SECURITY_PREFIX) - 1] == '\0') + return -EINVAL; + type = SECURITY_XATTR; + } else + return -EOPNOTSUPP; + + return type; +} + +static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum) +{ + struct inode *inode; + + inode = ubifs_iget(c->vfs_sb, inum); + if (IS_ERR(inode)) { + ubifs_err("dead extended attribute entry, error %d", + (int)PTR_ERR(inode)); + return inode; + } + if (ubifs_inode(inode)->xattr) + return inode; + ubifs_err("corrupt extended attribute entry"); + iput(inode); + return ERR_PTR(-EINVAL); +} + +int ubifs_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + struct inode *inode, *host = dentry->d_inode; + struct ubifs_info *c = host->i_sb->s_fs_info; + struct qstr nm = { .name = name, .len = strlen(name) }; + struct ubifs_dent_node *xent; + union ubifs_key key; + int err, type; + + dbg_gen("xattr '%s', host ino %lu ('%.*s'), size %zd", name, + host->i_ino, dentry->d_name.len, dentry->d_name.name, size); + + if (size > UBIFS_MAX_INO_DATA) + return -ERANGE; + + type = check_namespace(&nm); + if (type < 0) + return type; + + xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS); + if (!xent) + return -ENOMEM; + + /* + * The extended attribute entries are stored in LNC, so multiple + * look-ups do not involve reading the flash. + */ + xent_key_init(c, &key, host->i_ino, &nm); + err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); + if (err) { + if (err != -ENOENT) + goto out_free; + + if (flags & XATTR_REPLACE) + /* We are asked not to create the xattr */ + err = -ENODATA; + else + err = create_xattr(c, host, &nm, value, size); + goto out_free; + } + + if (flags & XATTR_CREATE) { + /* We are asked not to replace the xattr */ + err = -EEXIST; + goto out_free; + } + + inode = iget_xattr(c, le64_to_cpu(xent->inum)); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_free; + } + + err = change_xattr(c, host, inode, value, size); + iput(inode); + +out_free: + kfree(xent); + return err; +} + +ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, + size_t size) +{ + struct inode *inode, *host = dentry->d_inode; + struct ubifs_info *c = host->i_sb->s_fs_info; + struct qstr nm = { .name = name, .len = strlen(name) }; + struct ubifs_inode *ui; + struct ubifs_dent_node *xent; + union ubifs_key key; + int err; + + dbg_gen("xattr '%s', ino %lu ('%.*s'), buf size %zd", name, + host->i_ino, dentry->d_name.len, dentry->d_name.name, size); + + err = check_namespace(&nm); + if (err < 0) + return err; + + xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS); + if (!xent) + return -ENOMEM; + + mutex_lock(&host->i_mutex); + xent_key_init(c, &key, host->i_ino, &nm); + err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); + if (err) { + if (err == -ENOENT) + err = -ENODATA; + goto out_unlock; + } + + inode = iget_xattr(c, le64_to_cpu(xent->inum)); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_unlock; + } + + ui = ubifs_inode(inode); + ubifs_assert(inode->i_size == ui->data_len); + ubifs_assert(ubifs_inode(host)->xattr_size > ui->data_len); + + if (buf) { + /* If @buf is %NULL we are supposed to return the length */ + if (ui->data_len > size) { + dbg_err("buffer size %zd, xattr len %d", + size, ui->data_len); + err = -ERANGE; + goto out_iput; + } + + memcpy(buf, ui->data, ui->data_len); + } + err = ui->data_len; + +out_iput: + iput(inode); +out_unlock: + mutex_unlock(&host->i_mutex); + kfree(xent); + return err; +} + +ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size) +{ + union ubifs_key key; + struct inode *host = dentry->d_inode; + struct ubifs_info *c = host->i_sb->s_fs_info; + struct ubifs_inode *host_ui = ubifs_inode(host); + struct ubifs_dent_node *xent, *pxent = NULL; + int err, len, written = 0; + struct qstr nm = { .name = NULL }; + + dbg_gen("ino %lu ('%.*s'), buffer size %zd", host->i_ino, + dentry->d_name.len, dentry->d_name.name, size); + + len = host_ui->xattr_names + host_ui->xattr_cnt; + if (!buffer) + /* + * We should return the minimum buffer size which will fit a + * null-terminated list of all the extended attribute names. + */ + return len; + + if (len > size) + return -ERANGE; + + lowest_xent_key(c, &key, host->i_ino); + + mutex_lock(&host->i_mutex); + while (1) { + int type; + + xent = ubifs_tnc_next_ent(c, &key, &nm); + if (unlikely(IS_ERR(xent))) { + err = PTR_ERR(xent); + break; + } + + nm.name = xent->name; + nm.len = le16_to_cpu(xent->nlen); + + type = check_namespace(&nm); + if (unlikely(type < 0)) { + err = type; + break; + } + + /* Show trusted namespace only for "power" users */ + if (type != TRUSTED_XATTR || capable(CAP_SYS_ADMIN)) { + memcpy(buffer + written, nm.name, nm.len + 1); + written += nm.len + 1; + } + + kfree(pxent); + pxent = xent; + key_read(c, &xent->key, &key); + } + mutex_unlock(&host->i_mutex); + + kfree(pxent); + if (err != -ENOENT) { + ubifs_err("cannot find next direntry, error %d", err); + return err; + } + + ubifs_assert(written <= size); + return written; +} + +static int remove_xattr(struct ubifs_info *c, struct inode *host, + struct inode *inode, const struct qstr *nm) +{ + int err; + struct ubifs_inode *host_ui = ubifs_inode(host); + struct ubifs_inode *ui = ubifs_inode(inode); + struct ubifs_budget_req req = { .dirtied_ino = 1, .mod_dent = 1, + .dirtied_ino_d = host_ui->data_len }; + + ubifs_assert(ui->data_len == inode->i_size); + + err = ubifs_budget_space(c, &req); + if (err) + return err; + + mutex_lock(&host_ui->ui_mutex); + host->i_ctime = ubifs_current_time(host); + host_ui->xattr_cnt -= 1; + host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); + host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len); + host_ui->xattr_names -= nm->len; + + err = ubifs_jnl_delete_xattr(c, host, inode, nm); + if (err) + goto out_cancel; + mutex_unlock(&host_ui->ui_mutex); + + ubifs_release_budget(c, &req); + return 0; + +out_cancel: + host_ui->xattr_cnt += 1; + host_ui->xattr_size += CALC_DENT_SIZE(nm->len); + host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); + mutex_unlock(&host_ui->ui_mutex); + ubifs_release_budget(c, &req); + make_bad_inode(inode); + return err; +} + +int ubifs_removexattr(struct dentry *dentry, const char *name) +{ + struct inode *inode, *host = dentry->d_inode; + struct ubifs_info *c = host->i_sb->s_fs_info; + struct qstr nm = { .name = name, .len = strlen(name) }; + struct ubifs_dent_node *xent; + union ubifs_key key; + int err; + + dbg_gen("xattr '%s', ino %lu ('%.*s')", name, + host->i_ino, dentry->d_name.len, dentry->d_name.name); + ubifs_assert(mutex_is_locked(&host->i_mutex)); + + err = check_namespace(&nm); + if (err < 0) + return err; + + xent = kmalloc(UBIFS_MAX_XENT_NODE_SZ, GFP_NOFS); + if (!xent) + return -ENOMEM; + + xent_key_init(c, &key, host->i_ino, &nm); + err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); + if (err) { + if (err == -ENOENT) + err = -ENODATA; + goto out_free; + } + + inode = iget_xattr(c, le64_to_cpu(xent->inum)); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out_free; + } + + ubifs_assert(inode->i_nlink == 1); + inode->i_nlink = 0; + err = remove_xattr(c, host, inode, &nm); + if (err) + inode->i_nlink = 1; + + /* If @i_nlink is 0, 'iput()' will delete the inode */ + iput(inode); + +out_free: + kfree(xent); + return err; +} -- cgit v0.10.2 From 0d7eff873caaeac84de01a1acdca983d2c7ba3fe Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 Jul 2008 19:08:38 +0300 Subject: UBIFS: include to compilation Add UBIFS to Makefile and Kbuild. Signed-off-by: Artem Bityutskiy Signed-off-by: Adrian Hunter diff --git a/fs/Kconfig b/fs/Kconfig index 2694648..a52cf62 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1375,6 +1375,9 @@ config JFFS2_CMODE_FAVOURLZO endchoice +# UBIFS File system configuration +source "fs/ubifs/Kconfig" + config CRAMFS tristate "Compressed ROM file system support (cramfs)" depends on BLOCK diff --git a/fs/Makefile b/fs/Makefile index 1e7a11b..fcae06a 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -100,6 +100,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs/ obj-$(CONFIG_UFS_FS) += ufs/ obj-$(CONFIG_EFS_FS) += efs/ obj-$(CONFIG_JFFS2_FS) += jffs2/ +obj-$(CONFIG_UBIFS_FS) += ubifs/ obj-$(CONFIG_AFFS_FS) += affs/ obj-$(CONFIG_ROMFS_FS) += romfs/ obj-$(CONFIG_QNX4FS_FS) += qnx4/ diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig new file mode 100644 index 0000000..91ceeda --- /dev/null +++ b/fs/ubifs/Kconfig @@ -0,0 +1,72 @@ +config UBIFS_FS + tristate "UBIFS file system support" + select CRC16 + select CRC32 + select CRYPTO if UBIFS_FS_ADVANCED_COMPR + select CRYPTO if UBIFS_FS_LZO + select CRYPTO if UBIFS_FS_ZLIB + select CRYPTO_LZO if UBIFS_FS_LZO + select CRYPTO_DEFLATE if UBIFS_FS_ZLIB + depends on MTD_UBI + help + UBIFS is a file system for flash devices which works on top of UBI. + +config UBIFS_FS_XATTR + bool "Extended attributes support" + depends on UBIFS_FS + help + This option enables support of extended attributes. + +config UBIFS_FS_ADVANCED_COMPR + bool "Advanced compression options" + depends on UBIFS_FS + help + This option allows to explicitly choose which compressions, if any, + are enabled in UBIFS. Removing compressors means inbility to read + existing file systems. + + If unsure, say 'N'. + +config UBIFS_FS_LZO + bool "LZO compression support" if UBIFS_FS_ADVANCED_COMPR + depends on UBIFS_FS + default y + help + LZO compressor is generally faster then zlib but compresses worse. + Say 'Y' if unsure. + +config UBIFS_FS_ZLIB + bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR + depends on UBIFS_FS + default y + help + Zlib copresses better then LZO but it is slower. Say 'Y' if unsure. + +# Debugging-related stuff +config UBIFS_FS_DEBUG + bool "Enable debugging" + depends on UBIFS_FS + select DEBUG_FS + select KALLSYMS_ALL + help + This option enables UBIFS debugging. + +config UBIFS_FS_DEBUG_MSG_LVL + int "Default message level (0 = no extra messages, 3 = lots)" + depends on UBIFS_FS_DEBUG + default "0" + help + This controls the amount of debugging messages produced by UBIFS. + If reporting bugs, please try to have available a full dump of the + messages at level 1 while the misbehaviour was occurring. Level 2 + may become necessary if level 1 messages were not enough to find the + bug. Generally Level 3 should be avoided. + +config UBIFS_FS_DEBUG_CHKS + bool "Enable extra checks" + depends on UBIFS_FS_DEBUG + help + If extra checks are enabled UBIFS will check the consistency of its + internal data structures during operation. However, UBIFS performance + is dramatically slower when this option is selected especially if the + file system is large. diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile new file mode 100644 index 0000000..80e93c3 --- /dev/null +++ b/fs/ubifs/Makefile @@ -0,0 +1,9 @@ +obj-$(CONFIG_UBIFS_FS) += ubifs.o + +ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o +ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o +ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o +ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o + +ubifs-$(CONFIG_UBIFS_FS_DEBUG) += debug.o +ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o -- cgit v0.10.2 From 7890ea1f95fa8968fa6f5bb5860e6632932abfd3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 15 Jul 2008 23:46:24 +0800 Subject: Revert crypto: prng - Deterministic CPRNG This patch is clearly not ready yet for prime time. Signed-off-by: Herbert Xu diff --git a/crypto/Kconfig b/crypto/Kconfig index ea50357..d831859 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -666,15 +666,6 @@ config CRYPTO_LZO help This is the LZO algorithm. -comment "Random Number Generation" - -config CRYPTO_PRNG - tristate "Pseudo Random Number Generation for Cryptographic modules" - help - This option enables the generic pseudo random number generator - for cryptographic modules. Uses the Algorithm specified in - ANSI X9.31 A.2.4 - source "drivers/crypto/Kconfig" endif # if CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index ef61b3b..d4f3ed8 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -69,7 +69,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o obj-$(CONFIG_CRYPTO_LZO) += lzo.o -obj-$(CONFIG_CRYPTO_PRNG) += prng.o + obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o # diff --git a/crypto/prng.c b/crypto/prng.c deleted file mode 100644 index 24e4f32..0000000 --- a/crypto/prng.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * PRNG: Pseudo Random Number Generator - * Based on NIST Recommended PRNG From ANSI X9.31 Appendix A.2.4 using - * AES 128 cipher in RFC3686 ctr mode - * - * (C) Neil Horman - * - * 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 - * any later version. - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "prng.h" - -#define TEST_PRNG_ON_START 0 - -#define DEFAULT_PRNG_KEY "0123456789abcdef1011" -#define DEFAULT_PRNG_KSZ 20 -#define DEFAULT_PRNG_IV "defaultv" -#define DEFAULT_PRNG_IVSZ 8 -#define DEFAULT_BLK_SZ 16 -#define DEFAULT_V_SEED "zaybxcwdveuftgsh" - -/* - * Flags for the prng_context flags field - */ - -#define PRNG_FIXED_SIZE 0x1 -#define PRNG_NEED_RESET 0x2 - -/* - * Note: DT is our counter value - * I is our intermediate value - * V is our seed vector - * See http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf - * for implementation details - */ - - -struct prng_context { - char *prng_key; - char *prng_iv; - spinlock_t prng_lock; - unsigned char rand_data[DEFAULT_BLK_SZ]; - unsigned char last_rand_data[DEFAULT_BLK_SZ]; - unsigned char DT[DEFAULT_BLK_SZ]; - unsigned char I[DEFAULT_BLK_SZ]; - unsigned char V[DEFAULT_BLK_SZ]; - u32 rand_data_valid; - struct crypto_blkcipher *tfm; - u32 flags; -}; - -static int dbg; - -static void hexdump(char *note, unsigned char *buf, unsigned int len) -{ - if (dbg) { - printk(KERN_CRIT "%s", note); - print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, - 16, 1, - buf, len, false); - } -} - -#define dbgprint(format, args...) do {if(dbg) printk(format, ##args);} while(0) - -static void xor_vectors(unsigned char *in1, unsigned char *in2, - unsigned char *out, unsigned int size) -{ - int i; - - for (i=0;itfm; - desc.flags = 0; - - - dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",ctx); - - hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ); - hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ); - hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ); - - /* - * This algorithm is a 3 stage state machine - */ - for (i=0;i<3;i++) { - - desc.tfm = ctx->tfm; - desc.flags = 0; - switch (i) { - case 0: - /* - * Start by encrypting the counter value - * This gives us an intermediate value I - */ - memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ); - sg_init_one(&sg_out, &ctx->I[0], DEFAULT_BLK_SZ); - hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ); - break; - case 1: - - /* - * Next xor I with our secret vector V - * encrypt that result to obtain our - * pseudo random data which we output - */ - xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ); - sg_init_one(&sg_out, &ctx->rand_data[0], DEFAULT_BLK_SZ); - hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ); - break; - case 2: - /* - * First check that we didn't produce the same random data - * that we did last time around through this - */ - if (!memcmp(ctx->rand_data, ctx->last_rand_data, DEFAULT_BLK_SZ)) { - printk(KERN_ERR "ctx %p Failed repetition check!\n", - ctx); - ctx->flags |= PRNG_NEED_RESET; - return -1; - } - memcpy(ctx->last_rand_data, ctx->rand_data, DEFAULT_BLK_SZ); - - /* - * Lastly xor the random data with I - * and encrypt that to obtain a new secret vector V - */ - xor_vectors(ctx->rand_data, ctx->I, tmp, DEFAULT_BLK_SZ); - sg_init_one(&sg_out, &ctx->V[0], DEFAULT_BLK_SZ); - hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ); - break; - } - - /* Initialize our input buffer */ - sg_init_one(&sg_in, &tmp[0], DEFAULT_BLK_SZ); - - /* do the encryption */ - ret = crypto_blkcipher_encrypt(&desc, &sg_out, &sg_in, DEFAULT_BLK_SZ); - - /* And check the result */ - if (ret) { - dbgprint(KERN_CRIT "Encryption of new block failed for context %p\n",ctx); - ctx->rand_data_valid = DEFAULT_BLK_SZ; - return -1; - } - - } - - /* - * Now update our DT value - */ - for (i=DEFAULT_BLK_SZ-1;i>0;i--) { - ctx->DT[i] = ctx->DT[i-1]; - } - ctx->DT[0] += 1; - - dbgprint("Returning new block for context %p\n",ctx); - ctx->rand_data_valid = 0; - - hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ); - hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ); - hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ); - hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ); - - return 0; -} - -/* Our exported functions */ -int get_prng_bytes(char *buf, int nbytes, struct prng_context *ctx) -{ - unsigned long flags; - unsigned char *ptr = buf; - unsigned int byte_count = (unsigned int)nbytes; - int err; - - - if (nbytes < 0) - return -EINVAL; - - spin_lock_irqsave(&ctx->prng_lock, flags); - - err = -EFAULT; - if (ctx->flags & PRNG_NEED_RESET) - goto done; - - /* - * If the FIXED_SIZE flag is on, only return whole blocks of - * pseudo random data - */ - err = -EINVAL; - if (ctx->flags & PRNG_FIXED_SIZE) { - if (nbytes < DEFAULT_BLK_SZ) - goto done; - byte_count = DEFAULT_BLK_SZ; - } - - err = byte_count; - - dbgprint(KERN_CRIT "getting %d random bytes for context %p\n",byte_count, ctx); - - -remainder: - if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { - if (_get_more_prng_bytes(ctx) < 0) { - memset(buf, 0, nbytes); - err = -EFAULT; - goto done; - } - } - - /* - * Copy up to the next whole block size - */ - if (byte_count < DEFAULT_BLK_SZ) { - for (;ctx->rand_data_valid < DEFAULT_BLK_SZ; ctx->rand_data_valid++) { - *ptr = ctx->rand_data[ctx->rand_data_valid]; - ptr++; - byte_count--; - if (byte_count == 0) - goto done; - } - } - - /* - * Now copy whole blocks - */ - for(;byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { - if (_get_more_prng_bytes(ctx) < 0) { - memset(buf, 0, nbytes); - err = -1; - goto done; - } - memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ); - ctx->rand_data_valid += DEFAULT_BLK_SZ; - ptr += DEFAULT_BLK_SZ; - } - - /* - * Now copy any extra partial data - */ - if (byte_count) - goto remainder; - -done: - spin_unlock_irqrestore(&ctx->prng_lock, flags); - dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n",err, ctx); - return err; -} -EXPORT_SYMBOL_GPL(get_prng_bytes); - -struct prng_context *alloc_prng_context(void) -{ - struct prng_context *ctx=kzalloc(sizeof(struct prng_context), GFP_KERNEL); - - spin_lock_init(&ctx->prng_lock); - - if (reset_prng_context(ctx, NULL, NULL, NULL, NULL)) { - kfree(ctx); - ctx = NULL; - } - - dbgprint(KERN_CRIT "returning context %p\n",ctx); - return ctx; -} - -EXPORT_SYMBOL_GPL(alloc_prng_context); - -void free_prng_context(struct prng_context *ctx) -{ - crypto_free_blkcipher(ctx->tfm); - kfree(ctx); -} -EXPORT_SYMBOL_GPL(free_prng_context); - -int reset_prng_context(struct prng_context *ctx, - unsigned char *key, unsigned char *iv, - unsigned char *V, unsigned char *DT) -{ - int ret; - int iv_len; - int rc = -EFAULT; - - spin_lock(&ctx->prng_lock); - ctx->flags |= PRNG_NEED_RESET; - - if (key) - memcpy(ctx->prng_key,key,strlen(ctx->prng_key)); - else - ctx->prng_key = DEFAULT_PRNG_KEY; - - if (iv) - memcpy(ctx->prng_iv,iv, strlen(ctx->prng_iv)); - else - ctx->prng_iv = DEFAULT_PRNG_IV; - - if (V) - memcpy(ctx->V,V,DEFAULT_BLK_SZ); - else - memcpy(ctx->V,DEFAULT_V_SEED,DEFAULT_BLK_SZ); - - if (DT) - memcpy(ctx->DT, DT, DEFAULT_BLK_SZ); - else - memset(ctx->DT, 0, DEFAULT_BLK_SZ); - - memset(ctx->rand_data,0,DEFAULT_BLK_SZ); - memset(ctx->last_rand_data,0,DEFAULT_BLK_SZ); - - if (ctx->tfm) - crypto_free_blkcipher(ctx->tfm); - - ctx->tfm = crypto_alloc_blkcipher("rfc3686(ctr(aes))",0,0); - if (!ctx->tfm) { - dbgprint(KERN_CRIT "Failed to alloc crypto tfm for context %p\n",ctx->tfm); - goto out; - } - - ctx->rand_data_valid = DEFAULT_BLK_SZ; - - ret = crypto_blkcipher_setkey(ctx->tfm, ctx->prng_key, strlen(ctx->prng_key)); - if (ret) { - dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n", - crypto_blkcipher_get_flags(ctx->tfm)); - crypto_free_blkcipher(ctx->tfm); - goto out; - } - - iv_len = crypto_blkcipher_ivsize(ctx->tfm); - if (iv_len) { - crypto_blkcipher_set_iv(ctx->tfm, ctx->prng_iv, iv_len); - } - rc = 0; - ctx->flags &= ~PRNG_NEED_RESET; -out: - spin_unlock(&ctx->prng_lock); - - return rc; - -} -EXPORT_SYMBOL_GPL(reset_prng_context); - -/* Module initalization */ -static int __init prng_mod_init(void) -{ - -#ifdef TEST_PRNG_ON_START - int i; - unsigned char tmpbuf[DEFAULT_BLK_SZ]; - - struct prng_context *ctx = alloc_prng_context(); - if (ctx == NULL) - return -EFAULT; - for (i=0;i<16;i++) { - if (get_prng_bytes(tmpbuf, DEFAULT_BLK_SZ, ctx) < 0) { - free_prng_context(ctx); - return -EFAULT; - } - } - free_prng_context(ctx); -#endif - - return 0; -} - -static void __exit prng_mod_fini(void) -{ - return; -} - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Software Pseudo Random Number Generator"); -MODULE_AUTHOR("Neil Horman "); -module_param(dbg, int, 0); -MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)"); -module_init(prng_mod_init); -module_exit(prng_mod_fini); diff --git a/crypto/prng.h b/crypto/prng.h deleted file mode 100644 index 1ac9be5..0000000 --- a/crypto/prng.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * PRNG: Pseudo Random Number Generator - * - * (C) Neil Horman - * - * 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 - * any later version. - * - * - */ - -#ifndef _PRNG_H_ -#define _PRNG_H_ -struct prng_context; - -int get_prng_bytes(char *buf, int nbytes, struct prng_context *ctx); -struct prng_context *alloc_prng_context(void); -int reset_prng_context(struct prng_context *ctx, - unsigned char *key, unsigned char *iv, - unsigned char *V, - unsigned char *DT); -void free_prng_context(struct prng_context *ctx); - -#endif - -- cgit v0.10.2 From 0937502af7c9b648ed4e884ccb7f504b01a005a1 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 28 May 2008 10:32:22 -0700 Subject: slub: Add check for kfree() of non slab objects. We can detect kfree()s on non slab objects by checking for PageCompound(). Works in the same way as for ksize. This helped me catch an invalid kfree(). Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg diff --git a/mm/slub.c b/mm/slub.c index 5f6e2c4..b3f2e71 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2766,6 +2766,7 @@ void kfree(const void *x) page = virt_to_head_page(x); if (unlikely(!PageSlab(page))) { + BUG_ON(!PageCompound(page)); put_page(page); return; } -- cgit v0.10.2 From 88e4ccf294ca62c2da998012a83533ce150c8dce Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 23 Jun 2008 02:58:37 +0400 Subject: slub: current is always valid Acked-by: Christoph Lameter Signed-off-by: Alexey Dobriyan Signed-off-by: Pekka Enberg diff --git a/mm/slub.c b/mm/slub.c index b3f2e71..488400d 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -411,7 +411,7 @@ static void set_track(struct kmem_cache *s, void *object, if (addr) { p->addr = addr; p->cpu = smp_processor_id(); - p->pid = current ? current->pid : -1; + p->pid = current->pid; p->when = jiffies; } else memset(p, 0, sizeof(struct track)); -- cgit v0.10.2 From e79aec291da55aa322ddb5d8f3bb04cdf69470d5 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 4 Jul 2008 00:40:32 +0530 Subject: slab: rename slab_destroy_objs With the removal of destructors, slab_destroy_objs no longer actually destroys any objects, making the kernel doc incorrect and the function name misleading. In keeping with the other debug functions, rename it to slab_destroy_debugcheck and drop the kernel doc. Signed-off-by: Rabin Vincent Signed-off-by: Pekka Enberg diff --git a/mm/slab.c b/mm/slab.c index 046607f..b4aa4c8 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1901,15 +1901,7 @@ static void check_poison_obj(struct kmem_cache *cachep, void *objp) #endif #if DEBUG -/** - * slab_destroy_objs - destroy a slab and its objects - * @cachep: cache pointer being destroyed - * @slabp: slab pointer being destroyed - * - * Call the registered destructor for each object in a slab that is being - * destroyed. - */ -static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) +static void slab_destroy_debugcheck(struct kmem_cache *cachep, struct slab *slabp) { int i; for (i = 0; i < cachep->num; i++) { @@ -1938,7 +1930,7 @@ static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) } } #else -static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) +static void slab_destroy_debugcheck(struct kmem_cache *cachep, struct slab *slabp) { } #endif @@ -1956,7 +1948,7 @@ static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp) { void *addr = slabp->s_mem - slabp->colouroff; - slab_destroy_objs(cachep, slabp); + slab_destroy_debugcheck(cachep, slabp); if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) { struct slab_rcu *slab_rcu; -- cgit v0.10.2 From 2954c02a884dc0ba9e91882c0aba13bcb9d22e6c Mon Sep 17 00:00:00 2001 From: "Chen, Huacai" Date: Tue, 10 Jun 2008 09:05:08 +0800 Subject: [MIPS] modify the MIPS CPU classfication Signed-off-by: Huacai Chen Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index 1c35cac..229a786 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -66,8 +66,10 @@ #define PRID_IMP_RM7000 0x2700 #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ #define PRID_IMP_RM9000 0x3400 +#define PRID_IMP_LOONGSON1 0x4200 #define PRID_IMP_R5432 0x5400 #define PRID_IMP_R5500 0x5500 +#define PRID_IMP_LOONGSON2 0x6300 #define PRID_IMP_UNKNOWN 0xff00 @@ -90,8 +92,6 @@ #define PRID_IMP_24KE 0x9600 #define PRID_IMP_74K 0x9700 #define PRID_IMP_1004K 0x9900 -#define PRID_IMP_LOONGSON1 0x4200 -#define PRID_IMP_LOONGSON2 0x6300 /* * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE -- cgit v0.10.2 From cb11dfa0247df479e384c4a7ab6846f3a6bf1570 Mon Sep 17 00:00:00 2001 From: David Daney Date: Mon, 9 Jun 2008 16:30:03 -0700 Subject: [MIPS] Remove board_watchpoint_handler It is not used anywhere in tree. Signed-off-by: David Daney Signed-off-by: Andrew Morton Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index f9165d1..6e7e4a2 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -71,7 +71,6 @@ extern asmlinkage void handle_reserved(void); extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, int has_fpu); -void (*board_watchpoint_handler)(struct pt_regs *regs); void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); void (*board_nmi_handler_setup)(void); @@ -892,11 +891,6 @@ asmlinkage void do_mdmx(struct pt_regs *regs) asmlinkage void do_watch(struct pt_regs *regs) { - if (board_watchpoint_handler) { - (*board_watchpoint_handler)(regs); - return; - } - /* * We use the watch exception where available to detect stack * overflows. diff --git a/include/asm-mips/traps.h b/include/asm-mips/traps.h index e5dbde6..90ff2f4 100644 --- a/include/asm-mips/traps.h +++ b/include/asm-mips/traps.h @@ -24,6 +24,5 @@ extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup); extern void (*board_nmi_handler_setup)(void); extern void (*board_ejtag_handler_setup)(void); extern void (*board_bind_eic_interrupt)(int irq, int regset); -extern void (*board_watchpoint_handler)(struct pt_regs *regs); #endif /* _ASM_TRAPS_H */ -- cgit v0.10.2 From c88a8b4ab0e1a1f06938939d9ba42e9da6144ccb Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 9 Jun 2008 17:19:53 +0100 Subject: [MIPS] Remove obsolete isa_slot_offset The isa_slot_offset variable and its __ISA_IO_base macro is not used anywhere anymore. It does not look like a decent interface per today's standards either. Remove both including all places of initialization. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index a794719..f136c8a 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -79,7 +79,6 @@ void __init plat_mem_setup(void) if (mips_machtype == MACH_MIPS_MAGNUM_4000) EISA_bus = 1; #endif - isa_slot_offset = 0xe3000000; /* request I/O space for devices used on all i[345]86 PCs */ for (i = 0; i < ARRAY_SIZE(jazz_io_resources); i++) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index c6a063b..c04e4e3 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -68,13 +68,6 @@ static char command_line[CL_SIZE]; const unsigned long mips_io_port_base __read_mostly = -1; EXPORT_SYMBOL(mips_io_port_base); -/* - * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped - * for the processor. - */ -unsigned long isa_slot_offset; -EXPORT_SYMBOL(isa_slot_offset); - static struct resource code_resource = { .name = "Kernel code", }; static struct resource data_resource = { .name = "Kernel data", }; diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index 87e2c8f..d19d262 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -254,8 +254,6 @@ static int __init bcm1480_pcibios_init(void) ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536); bcm1480_controller.io_map_base -= bcm1480_controller.io_offset; set_io_port_base(bcm1480_controller.io_map_base); - isa_slot_offset = (unsigned long) - ioremap(A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES, 1024*1024); register_pci_controller(&bcm1480_controller); diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c index 2a09ad9..9bc102a 100644 --- a/arch/mips/pci/pci-sb1250.c +++ b/arch/mips/pci/pci-sb1250.c @@ -254,9 +254,6 @@ static int __init sb1250_pcibios_init(void) * works correctly with most of Linux's drivers. * XXX ehs: Should this happen in PCI Device mode? */ - isa_slot_offset = (unsigned long) - ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024 * 1024); - io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024); sb1250_controller.io_map_base = io_map_base; set_io_port_base((unsigned long)io_map_base); diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index 5484e1c..a49272c 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -116,7 +116,6 @@ void __init plat_mem_setup(void) /* * Setup (E)ISA I/O memory access stuff */ - isa_slot_offset = CKSEG1ADDR(0xb0000000); #ifdef CONFIG_EISA EISA_bus = 1; #endif diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index f18d281..501a40b 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -161,13 +161,6 @@ static inline void * isa_bus_to_virt(unsigned long address) #define bus_to_virt phys_to_virt /* - * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped - * for the processor. This implies the assumption that there is only - * one of these busses. - */ -extern unsigned long isa_slot_offset; - -/* * Change "struct page" to physical address. */ #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) @@ -528,16 +521,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int } /* - * ISA space is 'always mapped' on currently supported MIPS systems, no need - * to explicitly ioremap() it. The fact that the ISA IO space is mapped - * to PAGE_OFFSET is pure coincidence - it does not mean ISA values - * are physical addresses. The following constant pointer can be - * used as the IO-area pointer (it can be iounmapped as well, so the - * analogy with PCI is quite large): - */ -#define __ISA_IO_base ((char *)(isa_slot_offset)) - -/* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that * can be applied to dma buffers. -- cgit v0.10.2 From 07cdb78436d52416a582e645b9afb6e26f986bc9 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Thu, 29 May 2008 17:57:08 +0300 Subject: [MIPS] fix sparse warning about setup_early_printk() This patch fixes the following sparse warning: <<<<<<<< arch/mips/kernel/early_printk.c:35:13: warning: symbol 'setup_early_printk' was not declared. Should it be static? <<<<<<<< The fix is to define a prototype of the setup_early_printk() function and to include the appropriate header into arch/mips/kernel/early_printk.c. [Ralf: Sorted includes again] Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c index 9dccfa4..9ae813e 100644 --- a/arch/mips/kernel/early_printk.c +++ b/arch/mips/kernel/early_printk.c @@ -10,6 +10,8 @@ #include #include +#include + extern void prom_putchar(char); static void __init diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index c04e4e3..8af8486 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -550,11 +550,7 @@ void __init setup_arch(char **cmdline_p) prom_init(); #ifdef CONFIG_EARLY_PRINTK - { - extern void setup_early_printk(void); - - setup_early_printk(); - } + setup_early_printk(); #endif cpu_report(); check_bugs_early(); diff --git a/include/asm-mips/setup.h b/include/asm-mips/setup.h index 70009a9..883f59b 100644 --- a/include/asm-mips/setup.h +++ b/include/asm-mips/setup.h @@ -3,4 +3,6 @@ #define COMMAND_LINE_SIZE 256 +extern void setup_early_printk(void); + #endif /* __SETUP_H */ -- cgit v0.10.2 From 17f61e61b4a1d3ca254668cf12c1c5d828d892fd Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Thu, 29 May 2008 17:57:09 +0300 Subject: [MIPS] Make two functions static The following routines uasm_rel_highest() uasm_rel_higher() are needlessly defined global. This patch makes them static. Compile-tested using a customized config for the Malta board. Booting the same board up to the shell prompt was also successful with this patch applied. Spotted by sparse. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 1655aa6..f467199 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -396,7 +396,7 @@ int __cpuinit uasm_in_compat_space_p(long addr) #endif } -int __cpuinit uasm_rel_highest(long val) +static int __cpuinit uasm_rel_highest(long val) { #ifdef CONFIG_64BIT return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; @@ -405,7 +405,7 @@ int __cpuinit uasm_rel_highest(long val) #endif } -int __cpuinit uasm_rel_higher(long val) +static int __cpuinit uasm_rel_higher(long val) { #ifdef CONFIG_64BIT return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h index 0d6a66f..c6d1e3d 100644 --- a/arch/mips/mm/uasm.h +++ b/arch/mips/mm/uasm.h @@ -103,8 +103,6 @@ struct uasm_label { void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid); #ifdef CONFIG_64BIT int uasm_in_compat_space_p(long addr); -int uasm_rel_highest(long val); -int uasm_rel_higher(long val); #endif int uasm_rel_hi(long val); int uasm_rel_lo(long val); -- cgit v0.10.2 From f366e2085f28358a5294b8cdc847a377c02eb22d Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Thu, 29 May 2008 17:57:11 +0300 Subject: [MIPS] unexport {allocate,free}_irqno The following routines allocate_irqno() free_irqno() seem not to be used outside of the core kernel code, hence exporting these functions is pointless. This patch removes the export. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index e3309ff..6045b9a 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -44,8 +44,6 @@ again: return irq; } -EXPORT_SYMBOL_GPL(allocate_irqno); - /* * Allocate the 16 legacy interrupts for i8259 devices. This happens early * in the kernel initialization so treating allocation failure as BUG() is @@ -66,8 +64,6 @@ void free_irqno(unsigned int irq) smp_mb__after_clear_bit(); } -EXPORT_SYMBOL_GPL(free_irqno); - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. -- cgit v0.10.2 From 4b62220b608ab71876d8920d5590f1db4ee2eb4a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:29 +0100 Subject: [MIPS] Alchemy, PNX: Use symbolic constants for DMA masks. Signed-off-by: Ralf Baechle diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 74d6d4a..dc8a67e 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c @@ -11,6 +11,7 @@ * warranty of any kind, whether express or implied. */ +#include #include #include #include @@ -77,14 +78,14 @@ static struct resource au1xxx_usb_ohci_resources[] = { }; /* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = ~(u32)0; +static u64 ohci_dmamask = DMA_32BIT_MASK; static struct platform_device au1xxx_usb_ohci_device = { .name = "au1xxx-ohci", .id = 0, .dev = { .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources), .resource = au1xxx_usb_ohci_resources, @@ -106,14 +107,14 @@ static struct resource au1100_lcd_resources[] = { } }; -static u64 au1100_lcd_dmamask = ~(u32)0; +static u64 au1100_lcd_dmamask = DMA_32BIT_MASK; static struct platform_device au1100_lcd_device = { .name = "au1100-lcd", .id = 0, .dev = { .dma_mask = &au1100_lcd_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1100_lcd_resources), .resource = au1100_lcd_resources, @@ -135,14 +136,14 @@ static struct resource au1xxx_usb_ehci_resources[] = { }, }; -static u64 ehci_dmamask = ~(u32)0; +static u64 ehci_dmamask = DMA_32BIT_MASK; static struct platform_device au1xxx_usb_ehci_device = { .name = "au1xxx-ehci", .id = 0, .dev = { .dma_mask = &ehci_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), .resource = au1xxx_usb_ehci_resources, @@ -180,14 +181,14 @@ static struct resource au1xxx_mmc_resources[] = { } }; -static u64 udc_dmamask = ~(u32)0; +static u64 udc_dmamask = DMA_32BIT_MASK; static struct platform_device au1xxx_usb_gdt_device = { .name = "au1xxx-udc", .id = 0, .dev = { .dma_mask = &udc_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources), .resource = au1xxx_usb_gdt_resources, @@ -207,14 +208,14 @@ static struct resource au1xxx_usb_otg_resources[] = { }, }; -static u64 uoc_dmamask = ~(u32)0; +static u64 uoc_dmamask = DMA_32BIT_MASK; static struct platform_device au1xxx_usb_otg_device = { .name = "au1xxx-uoc", .id = 0, .dev = { .dma_mask = &uoc_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources), .resource = au1xxx_usb_otg_resources, @@ -233,27 +234,27 @@ static struct resource au1200_lcd_resources[] = { } }; -static u64 au1200_lcd_dmamask = ~(u32)0; +static u64 au1200_lcd_dmamask = DMA_32BIT_MASK; static struct platform_device au1200_lcd_device = { .name = "au1200-lcd", .id = 0, .dev = { .dma_mask = &au1200_lcd_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1200_lcd_resources), .resource = au1200_lcd_resources, }; -static u64 au1xxx_mmc_dmamask = ~(u32)0; +static u64 au1xxx_mmc_dmamask = DMA_32BIT_MASK; static struct platform_device au1xxx_mmc_device = { .name = "au1xxx-mmc", .id = 0, .dev = { .dma_mask = &au1xxx_mmc_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(au1xxx_mmc_resources), .resource = au1xxx_mmc_resources, diff --git a/arch/mips/au1000/pb1200/platform.c b/arch/mips/au1000/pb1200/platform.c index 5930110..f8fb0ae 100644 --- a/arch/mips/au1000/pb1200/platform.c +++ b/arch/mips/au1000/pb1200/platform.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include @@ -36,14 +37,14 @@ static struct resource ide_resources[] = { } }; -static u64 ide_dmamask = ~(u32)0; +static u64 ide_dmamask = DMA_32BIT_MASK; static struct platform_device ide_device = { .name = "au1200-ide", .id = 0, .dev = { .dma_mask = &ide_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(ide_resources), .resource = ide_resources diff --git a/arch/mips/nxp/pnx8550/common/platform.c b/arch/mips/nxp/pnx8550/common/platform.c index c7c763d..21d2955 100644 --- a/arch/mips/nxp/pnx8550/common/platform.c +++ b/arch/mips/nxp/pnx8550/common/platform.c @@ -13,6 +13,7 @@ * warranty of any kind, whether express or implied. */ #include +#include #include #include #include @@ -91,16 +92,16 @@ struct pnx8xxx_port pnx8xxx_ports[] = { }; /* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = ~(u32)0; +static u64 ohci_dmamask = DMA_32BIT_MASK; -static u64 uart_dmamask = ~(u32)0; +static u64 uart_dmamask = DMA_32BIT_MASK; static struct platform_device pnx8550_usb_ohci_device = { .name = "pnx8550-ohci", .id = -1, .dev = { .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, }, .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources), .resource = pnx8550_usb_ohci_resources, @@ -111,7 +112,7 @@ static struct platform_device pnx8550_uart_device = { .id = -1, .dev = { .dma_mask = &uart_dmamask, - .coherent_dma_mask = 0xffffffff, + .coherent_dma_mask = DMA_32BIT_MASK, .platform_data = pnx8xxx_ports, }, .num_resources = ARRAY_SIZE(pnx8550_uart_resources), -- cgit v0.10.2 From 997288517ec839b7639fcba77111256b13a66000 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 9 Jun 2008 08:39:58 +0200 Subject: [MIPS] Alchemy: remove unused MMC macros from db1x00 header. Signed-off-by: Manuel Lauss Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h index 612ae90..1a515b8 100644 --- a/include/asm-mips/mach-db1x00/db1x00.h +++ b/include/asm-mips/mach-db1x00/db1x00.h @@ -146,51 +146,6 @@ typedef volatile struct ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8)) /* - * SD controller macros - */ - -/* Detect card. */ -#define mmc_card_inserted(_n_, _res_) \ - do { \ - BCSR * const bcsr = (BCSR *)0xAE000000; \ - unsigned long mmc_wp, board_specific; \ - if ((_n_)) { \ - mmc_wp = BCSR_BOARD_SD1_WP; \ - } else { \ - mmc_wp = BCSR_BOARD_SD0_WP; \ - } \ - board_specific = au_readl((unsigned long)(&bcsr->specific)); \ - if (!(board_specific & mmc_wp)) {/* low means card present */ \ - *(int *)(_res_) = 1; \ - } else { \ - *(int *)(_res_) = 0; \ - } \ - } while (0) - -/* - * Apply power to card slot(s). - */ -#define mmc_power_on(_n_) \ - do { \ - BCSR * const bcsr = (BCSR *)0xAE000000; \ - unsigned long mmc_pwr, mmc_wp, board_specific; \ - if ((_n_)) { \ - mmc_pwr = BCSR_BOARD_SD1_PWR; \ - mmc_wp = BCSR_BOARD_SD1_WP; \ - } else { \ - mmc_pwr = BCSR_BOARD_SD0_PWR; \ - mmc_wp = BCSR_BOARD_SD0_WP; \ - } \ - board_specific = au_readl((unsigned long)(&bcsr->specific)); \ - if (!(board_specific & mmc_wp)) {/* low means card present */ \ - board_specific |= mmc_pwr; \ - au_writel(board_specific, (int)(&bcsr->specific)); \ - au_sync(); \ - } \ - } while (0) - - -/* * NAND defines * * Timing values as described in databook, * ns value stripped of the -- cgit v0.10.2 From 2957c9e61ee9c37e7ebf2c8acab03e073fe942fd Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:30 +0100 Subject: [MIPS] IRIX: Goodbye and thanks for all the fish Never terribly functional or popular, plagued by hard to fix bugs the time to say goodbye has more than arrived. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 24c5dee..21d6ec1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2064,10 +2064,6 @@ source "fs/Kconfig.binfmt" config TRAD_SIGNALS bool -config BINFMT_IRIX - bool "Include IRIX binary compatibility" - depends on CPU_BIG_ENDIAN && 32BIT && BROKEN - config MIPS32_COMPAT bool "Kernel support for Linux/MIPS 32-bit binary compatibility" depends on 64BIT diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 65e46a6..48ae915 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -20,9 +20,6 @@ obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o obj-$(CONFIG_SYNC_R4K) += sync-r4k.o -binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ - irix5sys.o sysirix.o - obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o @@ -70,7 +67,6 @@ obj-$(CONFIG_IRQ_GIC) += irq-gic.o obj-$(CONFIG_32BIT) += scall32-o32.o obj-$(CONFIG_64BIT) += scall64-64.o -obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o diff --git a/arch/mips/kernel/irix5sys.S b/arch/mips/kernel/irix5sys.S deleted file mode 100644 index eeef891..0000000 --- a/arch/mips/kernel/irix5sys.S +++ /dev/null @@ -1,1041 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * 32-bit IRIX5 ABI system call table derived from original file 'irix5sys.h' - * created by David S. Miller. - * - * Copyright (C) 1996 - 2004 David S. Miller - * Copyright (C) 2004 Steven J. Hill - */ -#include - - /* - * Key: - * V == Valid and should work as expected for most cases. - * HV == Half Valid, some things will work, some likely will not - * IV == InValid, certainly will not work at all yet - * ?V == ?'ably Valid, I have not done enough looking into it - * DC == Don't Care, a rats ass we couldn't give - */ - - .macro irix5syscalltable - - sys sys_syscall 0 /* 1000 sysindir() V*/ - sys sys_exit 1 /* 1001 exit() V*/ - sys sys_fork 0 /* 1002 fork() V*/ - sys sys_read 3 /* 1003 read() V*/ - sys sys_write 3 /* 1004 write() V*/ - sys sys_open 3 /* 1005 open() V*/ - sys sys_close 1 /* 1006 close() V*/ - sys irix_unimp 0 /* 1007 (XXX IRIX 4 wait) V*/ - sys sys_creat 2 /* 1008 creat() V*/ - sys sys_link 2 /* 1009 link() V*/ - sys sys_unlink 1 /* 1010 unlink() V*/ - sys irix_exec 0 /* 1011 exec() V*/ - sys sys_chdir 1 /* 1012 chdir() V*/ - sys irix_gtime 0 /* 1013 time() V*/ - sys irix_unimp 0 /* 1014 (XXX IRIX 4 mknod) V*/ - sys sys_chmod 2 /* 1015 chmod() V*/ - sys sys_chown 3 /* 1016 chown() V*/ - sys irix_brk 1 /* 1017 break() V*/ - sys irix_unimp 0 /* 1018 (XXX IRIX 4 stat) V*/ - sys sys_lseek 3 /* 1019 lseek() XXX64bit HV*/ - sys irix_getpid 0 /* 1020 getpid() V*/ - sys irix_mount 6 /* 1021 mount() IV*/ - sys sys_umount 1 /* 1022 umount() V*/ - sys sys_setuid 1 /* 1023 setuid() V*/ - sys irix_getuid 0 /* 1024 getuid() V*/ - sys irix_stime 1 /* 1025 stime() V*/ - sys irix_unimp 4 /* 1026 XXX ptrace() IV*/ - sys irix_alarm 1 /* 1027 alarm() V*/ - sys irix_unimp 0 /* 1028 (XXX IRIX 4 fstat) V*/ - sys irix_pause 0 /* 1029 pause() V*/ - sys sys_utime 2 /* 1030 utime() V*/ - sys irix_unimp 0 /* 1031 nuthin' V*/ - sys irix_unimp 0 /* 1032 nobody home man... V*/ - sys sys_access 2 /* 1033 access() V*/ - sys sys_nice 1 /* 1034 nice() V*/ - sys irix_statfs 2 /* 1035 statfs() V*/ - sys sys_sync 0 /* 1036 sync() V*/ - sys sys_kill 2 /* 1037 kill() V*/ - sys irix_fstatfs 2 /* 1038 fstatfs() V*/ - sys irix_setpgrp 1 /* 1039 setpgrp() V*/ - sys irix_syssgi 0 /* 1040 syssgi() HV*/ - sys sys_dup 1 /* 1041 dup() V*/ - sys sys_pipe 0 /* 1042 pipe() V*/ - sys irix_times 1 /* 1043 times() V*/ - sys irix_unimp 0 /* 1044 XXX profil() IV*/ - sys irix_unimp 0 /* 1045 XXX lock() IV*/ - sys sys_setgid 1 /* 1046 setgid() V*/ - sys irix_getgid 0 /* 1047 getgid() V*/ - sys irix_unimp 0 /* 1048 (XXX IRIX 4 ssig) V*/ - sys irix_msgsys 6 /* 1049 sys_msgsys V*/ - sys sys_sysmips 4 /* 1050 sysmips() HV*/ - sys irix_unimp 0 /* 1051 XXX sysacct() IV*/ - sys irix_shmsys 5 /* 1052 sys_shmsys V*/ - sys irix_semsys 0 /* 1053 sys_semsys V*/ - sys irix_ioctl 3 /* 1054 ioctl() HV*/ - sys irix_uadmin 0 /* 1055 XXX sys_uadmin() HC*/ - sys irix_sysmp 0 /* 1056 sysmp() HV*/ - sys irix_utssys 4 /* 1057 sys_utssys() HV*/ - sys irix_unimp 0 /* 1058 nada enchilada V*/ - sys irix_exece 0 /* 1059 exece() V*/ - sys sys_umask 1 /* 1060 umask() V*/ - sys sys_chroot 1 /* 1061 chroot() V*/ - sys irix_fcntl 3 /* 1062 fcntl() ?V*/ - sys irix_ulimit 2 /* 1063 ulimit() HV*/ - sys irix_unimp 0 /* 1064 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1065 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1066 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1067 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1068 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1069 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1070 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1071 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1072 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1073 XXX AFS shit DC*/ - sys irix_unimp 0 /* 1074 nuttin' V*/ - sys irix_unimp 0 /* 1075 XXX sys_getrlimit64()IV*/ - sys irix_unimp 0 /* 1076 XXX sys_setrlimit64()IV*/ - sys sys_nanosleep 2 /* 1077 nanosleep() V*/ - sys irix_lseek64 5 /* 1078 lseek64() ?V*/ - sys sys_rmdir 1 /* 1079 rmdir() V*/ - sys sys_mkdir 2 /* 1080 mkdir() V*/ - sys sys_getdents 3 /* 1081 getdents() V*/ - sys irix_sginap 1 /* 1082 sys_sginap() V*/ - sys irix_sgikopt 3 /* 1083 sys_sgikopt() DC*/ - sys sys_sysfs 3 /* 1084 sysfs() ?V*/ - sys irix_unimp 0 /* 1085 XXX sys_getmsg() DC*/ - sys irix_unimp 0 /* 1086 XXX sys_putmsg() DC*/ - sys sys_poll 3 /* 1087 poll() V*/ - sys irix_sigreturn 0 /* 1088 sigreturn() ?V*/ - sys sys_accept 3 /* 1089 accept() V*/ - sys sys_bind 3 /* 1090 bind() V*/ - sys sys_connect 3 /* 1091 connect() V*/ - sys irix_gethostid 0 /* 1092 sys_gethostid() ?V*/ - sys sys_getpeername 3 /* 1093 getpeername() V*/ - sys sys_getsockname 3 /* 1094 getsockname() V*/ - sys sys_getsockopt 5 /* 1095 getsockopt() V*/ - sys sys_listen 2 /* 1096 listen() V*/ - sys sys_recv 4 /* 1097 recv() V*/ - sys sys_recvfrom 6 /* 1098 recvfrom() V*/ - sys sys_recvmsg 3 /* 1099 recvmsg() V*/ - sys sys_select 5 /* 1100 select() V*/ - sys sys_send 4 /* 1101 send() V*/ - sys sys_sendmsg 3 /* 1102 sendmsg() V*/ - sys sys_sendto 6 /* 1103 sendto() V*/ - sys irix_sethostid 1 /* 1104 sys_sethostid() ?V*/ - sys sys_setsockopt 5 /* 1105 setsockopt() V*/ - sys sys_shutdown 2 /* 1106 shutdown() ?V*/ - sys irix_socket 3 /* 1107 socket() V*/ - sys sys_gethostname 2 /* 1108 sys_gethostname() ?V*/ - sys sys_sethostname 2 /* 1109 sethostname() ?V*/ - sys irix_getdomainname 2 /* 1110 sys_getdomainname() ?V*/ - sys sys_setdomainname 2 /* 1111 setdomainname() ?V*/ - sys sys_truncate 2 /* 1112 truncate() V*/ - sys sys_ftruncate 2 /* 1113 ftruncate() V*/ - sys sys_rename 2 /* 1114 rename() V*/ - sys sys_symlink 2 /* 1115 symlink() V*/ - sys sys_readlink 3 /* 1116 readlink() V*/ - sys irix_unimp 0 /* 1117 XXX IRIX 4 lstat() DC*/ - sys irix_unimp 0 /* 1118 nothin' V*/ - sys irix_unimp 0 /* 1119 XXX nfs_svc() DC*/ - sys irix_unimp 0 /* 1120 XXX nfs_getfh() DC*/ - sys irix_unimp 0 /* 1121 XXX async_daemon() DC*/ - sys irix_unimp 0 /* 1122 XXX exportfs() DC*/ - sys sys_setregid 2 /* 1123 setregid() V*/ - sys sys_setreuid 2 /* 1124 setreuid() V*/ - sys sys_getitimer 2 /* 1125 getitimer() V*/ - sys sys_setitimer 3 /* 1126 setitimer() V*/ - sys irix_unimp 1 /* 1127 XXX adjtime() IV*/ - sys irix_gettimeofday 1 /* 1128 gettimeofday() V*/ - sys irix_unimp 0 /* 1129 XXX sproc() IV*/ - sys irix_prctl 0 /* 1130 prctl() HV*/ - sys irix_unimp 0 /* 1131 XXX procblk() IV*/ - sys irix_unimp 0 /* 1132 XXX sprocsp() IV*/ - sys irix_unimp 0 /* 1133 XXX sgigsc() IV*/ - sys irix_mmap32 6 /* 1134 mmap() XXXflags? ?V*/ - sys sys_munmap 2 /* 1135 munmap() V*/ - sys sys_mprotect 3 /* 1136 mprotect() V*/ - sys sys_msync 4 /* 1137 msync() V*/ - sys irix_madvise 3 /* 1138 madvise() DC*/ - sys irix_pagelock 3 /* 1139 pagelock() IV*/ - sys irix_getpagesize 0 /* 1140 getpagesize() V*/ - sys irix_quotactl 0 /* 1141 quotactl() V*/ - sys irix_unimp 0 /* 1142 nobody home man V*/ - sys sys_getpgid 1 /* 1143 BSD getpgrp() V*/ - sys irix_BSDsetpgrp 2 /* 1143 BSD setpgrp() V*/ - sys sys_vhangup 0 /* 1144 vhangup() V*/ - sys sys_fsync 1 /* 1145 fsync() V*/ - sys sys_fchdir 1 /* 1146 fchdir() V*/ - sys sys_getrlimit 2 /* 1147 getrlimit() ?V*/ - sys sys_setrlimit 2 /* 1148 setrlimit() ?V*/ - sys sys_cacheflush 3 /* 1150 cacheflush() HV*/ - sys sys_cachectl 3 /* 1151 cachectl() HV*/ - sys sys_fchown 3 /* 1152 fchown() ?V*/ - sys sys_fchmod 2 /* 1153 fchmod() ?V*/ - sys irix_unimp 0 /* 1154 XXX IRIX 4 wait3() V*/ - sys sys_socketpair 4 /* 1155 socketpair() V*/ - sys irix_systeminfo 3 /* 1156 systeminfo() IV*/ - sys irix_uname 1 /* 1157 uname() IV*/ - sys irix_xstat 3 /* 1158 xstat() V*/ - sys irix_lxstat 3 /* 1159 lxstat() V*/ - sys irix_fxstat 3 /* 1160 fxstat() V*/ - sys irix_xmknod 0 /* 1161 xmknod() ?V*/ - sys irix_sigaction 4 /* 1162 sigaction() ?V*/ - sys irix_sigpending 1 /* 1163 sigpending() ?V*/ - sys irix_sigprocmask 3 /* 1164 sigprocmask() ?V*/ - sys irix_sigsuspend 0 /* 1165 sigsuspend() ?V*/ - sys irix_sigpoll_sys 3 /* 1166 sigpoll_sys() IV*/ - sys irix_swapctl 2 /* 1167 swapctl() IV*/ - sys irix_getcontext 0 /* 1168 getcontext() HV*/ - sys irix_setcontext 0 /* 1169 setcontext() HV*/ - sys irix_waitsys 5 /* 1170 waitsys() IV*/ - sys irix_sigstack 2 /* 1171 sigstack() HV*/ - sys irix_sigaltstack 2 /* 1172 sigaltstack() HV*/ - sys irix_sigsendset 2 /* 1173 sigsendset() IV*/ - sys irix_statvfs 2 /* 1174 statvfs() V*/ - sys irix_fstatvfs 2 /* 1175 fstatvfs() V*/ - sys irix_unimp 0 /* 1176 XXX getpmsg() DC*/ - sys irix_unimp 0 /* 1177 XXX putpmsg() DC*/ - sys sys_lchown 3 /* 1178 lchown() V*/ - sys irix_priocntl 0 /* 1179 priocntl() DC*/ - sys irix_sigqueue 4 /* 1180 sigqueue() IV*/ - sys sys_readv 3 /* 1181 readv() V*/ - sys sys_writev 3 /* 1182 writev() V*/ - sys irix_truncate64 4 /* 1183 truncate64() XX32bit HV*/ - sys irix_ftruncate64 4 /* 1184 ftruncate64()XX32bit HV*/ - sys irix_mmap64 0 /* 1185 mmap64() XX32bit HV*/ - sys irix_dmi 0 /* 1186 dmi() DC*/ - sys irix_pread 6 /* 1187 pread() IV*/ - sys irix_pwrite 6 /* 1188 pwrite() IV*/ - sys sys_fsync 1 /* 1189 fdatasync() XXPOSIX HV*/ - sys irix_sgifastpath 7 /* 1190 sgifastpath() WHEEE IV*/ - sys irix_unimp 0 /* 1191 XXX attr_get() DC*/ - sys irix_unimp 0 /* 1192 XXX attr_getf() DC*/ - sys irix_unimp 0 /* 1193 XXX attr_set() DC*/ - sys irix_unimp 0 /* 1194 XXX attr_setf() DC*/ - sys irix_unimp 0 /* 1195 XXX attr_remove() DC*/ - sys irix_unimp 0 /* 1196 XXX attr_removef() DC*/ - sys irix_unimp 0 /* 1197 XXX attr_list() DC*/ - sys irix_unimp 0 /* 1198 XXX attr_listf() DC*/ - sys irix_unimp 0 /* 1199 XXX attr_multi() DC*/ - sys irix_unimp 0 /* 1200 XXX attr_multif() DC*/ - sys irix_statvfs64 2 /* 1201 statvfs64() V*/ - sys irix_fstatvfs64 2 /* 1202 fstatvfs64() V*/ - sys irix_getmountid 2 /* 1203 getmountid()XXXfsids HV*/ - sys irix_nsproc 5 /* 1204 nsproc() IV*/ - sys irix_getdents64 3 /* 1205 getdents64() HV*/ - sys irix_unimp 0 /* 1206 XXX DFS garbage DC*/ - sys irix_ngetdents 4 /* 1207 ngetdents() XXXeop HV*/ - sys irix_ngetdents64 4 /* 1208 ngetdents64() XXXeop HV*/ - sys irix_unimp 0 /* 1209 nothin' V*/ - sys irix_unimp 0 /* 1210 XXX pidsprocsp() */ - sys irix_unimp 0 /* 1211 XXX rexec() */ - sys irix_unimp 0 /* 1212 XXX timer_create() */ - sys irix_unimp 0 /* 1213 XXX timer_delete() */ - sys irix_unimp 0 /* 1214 XXX timer_settime() */ - sys irix_unimp 0 /* 1215 XXX timer_gettime() */ - sys irix_unimp 0 /* 1216 XXX timer_setoverrun() */ - sys sys_sched_rr_get_interval 2 /* 1217 sched_rr_get_interval()V*/ - sys sys_sched_yield 0 /* 1218 sched_yield() V*/ - sys sys_sched_getscheduler 1 /* 1219 sched_getscheduler() V*/ - sys sys_sched_setscheduler 3 /* 1220 sched_setscheduler() V*/ - sys sys_sched_getparam 2 /* 1221 sched_getparam() V*/ - sys sys_sched_setparam 2 /* 1222 sched_setparam() V*/ - sys irix_unimp 0 /* 1223 XXX usync_cntl() */ - sys irix_unimp 0 /* 1224 XXX psema_cntl() */ - sys irix_unimp 0 /* 1225 XXX restartreturn() */ - - /* Just to pad things out nicely. */ - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - sys irix_unimp 0 - - .endm - - /* - * Pre-compute the number of _instruction_ bytes needed to load - * or store the arguments 6-8. Negative values are ignored. - */ - .macro sys function, nargs - PTR \function - LONG (\nargs << 2) - (5 << 2) - .endm - - .align 4 -EXPORT(sys_call_table_irix5) - irix5syscalltable diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c deleted file mode 100644 index 469c723..0000000 --- a/arch/mips/kernel/irixelf.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * irixelf.c: Code to load IRIX ELF executables conforming to the MIPS ABI. - * Based off of work by Eric Youngdale. - * - * Copyright (C) 1993 - 1994 Eric Youngdale - * Copyright (C) 1996 - 2004 David S. Miller - * Copyright (C) 2004 - 2005 Steven J. Hill - */ -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define DLINFO_ITEMS 12 - -#include - -static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs); -static int load_irix_library(struct file *); -static int irix_core_dump(long signr, struct pt_regs * regs, - struct file *file, unsigned long limit); - -static struct linux_binfmt irix_format = { - .module = THIS_MODULE, - .load_binary = load_irix_binary, - .load_shlib = load_irix_library, - .core_dump = irix_core_dump, - .min_coredump = PAGE_SIZE, -}; - -/* Debugging routines. */ -static char *get_elf_p_type(Elf32_Word p_type) -{ -#ifdef DEBUG - switch (p_type) { - case PT_NULL: - return "PT_NULL"; - break; - - case PT_LOAD: - return "PT_LOAD"; - break; - - case PT_DYNAMIC: - return "PT_DYNAMIC"; - break; - - case PT_INTERP: - return "PT_INTERP"; - break; - - case PT_NOTE: - return "PT_NOTE"; - break; - - case PT_SHLIB: - return "PT_SHLIB"; - break; - - case PT_PHDR: - return "PT_PHDR"; - break; - - case PT_LOPROC: - return "PT_LOPROC/REGINFO"; - break; - - case PT_HIPROC: - return "PT_HIPROC"; - break; - - default: - return "PT_BOGUS"; - break; - } -#endif -} - -static void print_elfhdr(struct elfhdr *ehp) -{ - int i; - - pr_debug("ELFHDR: e_ident<"); - for (i = 0; i < (EI_NIDENT - 1); i++) - pr_debug("%x ", ehp->e_ident[i]); - pr_debug("%x>\n", ehp->e_ident[i]); - pr_debug(" e_type[%04x] e_machine[%04x] e_version[%08lx]\n", - (unsigned short) ehp->e_type, (unsigned short) ehp->e_machine, - (unsigned long) ehp->e_version); - pr_debug(" e_entry[%08lx] e_phoff[%08lx] e_shoff[%08lx] " - "e_flags[%08lx]\n", - (unsigned long) ehp->e_entry, (unsigned long) ehp->e_phoff, - (unsigned long) ehp->e_shoff, (unsigned long) ehp->e_flags); - pr_debug(" e_ehsize[%04x] e_phentsize[%04x] e_phnum[%04x]\n", - (unsigned short) ehp->e_ehsize, - (unsigned short) ehp->e_phentsize, - (unsigned short) ehp->e_phnum); - pr_debug(" e_shentsize[%04x] e_shnum[%04x] e_shstrndx[%04x]\n", - (unsigned short) ehp->e_shentsize, - (unsigned short) ehp->e_shnum, - (unsigned short) ehp->e_shstrndx); -} - -static void print_phdr(int i, struct elf_phdr *ep) -{ - pr_debug("PHDR[%d]: p_type[%s] p_offset[%08lx] p_vaddr[%08lx] " - "p_paddr[%08lx]\n", i, get_elf_p_type(ep->p_type), - (unsigned long) ep->p_offset, (unsigned long) ep->p_vaddr, - (unsigned long) ep->p_paddr); - pr_debug(" p_filesz[%08lx] p_memsz[%08lx] p_flags[%08lx] " - "p_align[%08lx]\n", (unsigned long) ep->p_filesz, - (unsigned long) ep->p_memsz, (unsigned long) ep->p_flags, - (unsigned long) ep->p_align); -} - -static void dump_phdrs(struct elf_phdr *ep, int pnum) -{ - int i; - - for (i = 0; i < pnum; i++, ep++) { - if ((ep->p_type == PT_LOAD) || - (ep->p_type == PT_INTERP) || - (ep->p_type == PT_PHDR)) - print_phdr(i, ep); - } -} - -static void set_brk(unsigned long start, unsigned long end) -{ - start = PAGE_ALIGN(start); - end = PAGE_ALIGN(end); - if (end <= start) - return; - down_write(¤t->mm->mmap_sem); - do_brk(start, end - start); - up_write(¤t->mm->mmap_sem); -} - - -/* We need to explicitly zero any fractional pages - * after the data section (i.e. bss). This would - * contain the junk from the file that should not - * be in memory. - */ -static void padzero(unsigned long elf_bss) -{ - unsigned long nbyte; - - nbyte = elf_bss & (PAGE_SIZE-1); - if (nbyte) { - nbyte = PAGE_SIZE - nbyte; - clear_user((void __user *) elf_bss, nbyte); - } -} - -static unsigned long * create_irix_tables(char * p, int argc, int envc, - struct elfhdr * exec, unsigned int load_addr, - unsigned int interp_load_addr, struct pt_regs *regs, - struct elf_phdr *ephdr) -{ - elf_addr_t *argv; - elf_addr_t *envp; - elf_addr_t *sp, *csp; - - pr_debug("create_irix_tables: p[%p] argc[%d] envc[%d] " - "load_addr[%08x] interp_load_addr[%08x]\n", - p, argc, envc, load_addr, interp_load_addr); - - sp = (elf_addr_t *) (~15UL & (unsigned long) p); - csp = sp; - csp -= exec ? DLINFO_ITEMS*2 : 2; - csp -= envc+1; - csp -= argc+1; - csp -= 1; /* argc itself */ - if ((unsigned long)csp & 15UL) { - sp -= (16UL - ((unsigned long)csp & 15UL)) / sizeof(*sp); - } - - /* - * Put the ELF interpreter info on the stack - */ -#define NEW_AUX_ENT(nr, id, val) \ - __put_user((id), sp+(nr*2)); \ - __put_user((val), sp+(nr*2+1)); \ - - sp -= 2; - NEW_AUX_ENT(0, AT_NULL, 0); - - if (exec) { - sp -= 11*2; - - NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff); - NEW_AUX_ENT(1, AT_PHENT, sizeof(struct elf_phdr)); - NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum); - NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE); - NEW_AUX_ENT(4, AT_BASE, interp_load_addr); - NEW_AUX_ENT(5, AT_FLAGS, 0); - NEW_AUX_ENT(6, AT_ENTRY, (elf_addr_t) exec->e_entry); - NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid); - NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid); - NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid); - NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid); - } -#undef NEW_AUX_ENT - - sp -= envc+1; - envp = sp; - sp -= argc+1; - argv = sp; - - __put_user((elf_addr_t)argc, --sp); - current->mm->arg_start = (unsigned long) p; - while (argc-->0) { - __put_user((unsigned long)p, argv++); - p += strlen_user(p); - } - __put_user((unsigned long) NULL, argv); - current->mm->arg_end = current->mm->env_start = (unsigned long) p; - while (envc-->0) { - __put_user((unsigned long)p, envp++); - p += strlen_user(p); - } - __put_user((unsigned long) NULL, envp); - current->mm->env_end = (unsigned long) p; - return sp; -} - - -/* This is much more generalized than the library routine read function, - * so we keep this separate. Technically the library read function - * is only provided so that we can read a.out libraries that have - * an ELF header. - */ -static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, - struct file * interpreter, - unsigned int *interp_load_addr) -{ - struct elf_phdr *elf_phdata = NULL; - struct elf_phdr *eppnt; - unsigned int len; - unsigned int load_addr; - int elf_bss; - int retval; - unsigned int last_bss; - int error; - int i; - unsigned int k; - - elf_bss = 0; - last_bss = 0; - error = load_addr = 0; - - print_elfhdr(interp_elf_ex); - - /* First of all, some simple consistency checks */ - if ((interp_elf_ex->e_type != ET_EXEC && - interp_elf_ex->e_type != ET_DYN) || - !interpreter->f_op->mmap) { - printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type); - return 0xffffffff; - } - - /* Now read in all of the header information */ - if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE) { - printk("IRIX interp header bigger than a page (%d)\n", - (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum)); - return 0xffffffff; - } - - elf_phdata = kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, - GFP_KERNEL); - - if (!elf_phdata) { - printk("Cannot kmalloc phdata for IRIX interp.\n"); - return 0xffffffff; - } - - /* If the size of this structure has changed, then punt, since - * we will be doing the wrong thing. - */ - if (interp_elf_ex->e_phentsize != 32) { - printk("IRIX interp e_phentsize == %d != 32 ", - interp_elf_ex->e_phentsize); - kfree(elf_phdata); - return 0xffffffff; - } - - retval = kernel_read(interpreter, interp_elf_ex->e_phoff, - (char *) elf_phdata, - sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); - - dump_phdrs(elf_phdata, interp_elf_ex->e_phnum); - - eppnt = elf_phdata; - for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { - if (eppnt->p_type == PT_LOAD) { - int elf_type = MAP_PRIVATE | MAP_DENYWRITE; - int elf_prot = 0; - unsigned long vaddr = 0; - if (eppnt->p_flags & PF_R) - elf_prot = PROT_READ; - if (eppnt->p_flags & PF_W) - elf_prot |= PROT_WRITE; - if (eppnt->p_flags & PF_X) - elf_prot |= PROT_EXEC; - elf_type |= MAP_FIXED; - vaddr = eppnt->p_vaddr; - - pr_debug("INTERP do_mmap" - "(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ", - interpreter, vaddr, - (unsigned long) - (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)), - (unsigned long) - elf_prot, (unsigned long) elf_type, - (unsigned long) - (eppnt->p_offset & 0xfffff000)); - - down_write(¤t->mm->mmap_sem); - error = do_mmap(interpreter, vaddr, - eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), - elf_prot, elf_type, - eppnt->p_offset & 0xfffff000); - up_write(¤t->mm->mmap_sem); - - if (error < 0 && error > -1024) { - printk("Aieee IRIX interp mmap error=%d\n", - error); - break; /* Real error */ - } - pr_debug("error=%08lx ", (unsigned long) error); - if (!load_addr && interp_elf_ex->e_type == ET_DYN) { - load_addr = error; - pr_debug("load_addr = error "); - } - - /* - * Find the end of the file mapping for this phdr, and - * keep track of the largest address we see for this. - */ - k = eppnt->p_vaddr + eppnt->p_filesz; - if (k > elf_bss) - elf_bss = k; - - /* Do the same thing for the memory mapping - between - * elf_bss and last_bss is the bss section. - */ - k = eppnt->p_memsz + eppnt->p_vaddr; - if (k > last_bss) - last_bss = k; - pr_debug("\n"); - } - } - - /* Now use mmap to map the library into memory. */ - if (error < 0 && error > -1024) { - pr_debug("got error %d\n", error); - kfree(elf_phdata); - return 0xffffffff; - } - - /* Now fill out the bss section. First pad the last page up - * to the page boundary, and then perform a mmap to make sure - * that there are zero-mapped pages up to and including the - * last bss page. - */ - pr_debug("padzero(%08lx) ", (unsigned long) (elf_bss)); - padzero(elf_bss); - len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */ - - pr_debug("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss, - (unsigned long) len); - - /* Map the last of the bss segment */ - if (last_bss > len) { - down_write(¤t->mm->mmap_sem); - do_brk(len, (last_bss - len)); - up_write(¤t->mm->mmap_sem); - } - kfree(elf_phdata); - - *interp_load_addr = load_addr; - return ((unsigned int) interp_elf_ex->e_entry); -} - -/* Check sanity of IRIX elf executable header. */ -static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm) -{ - if (memcmp(ehp->e_ident, ELFMAG, SELFMAG) != 0) - return -ENOEXEC; - - /* First of all, some simple consistency checks */ - if ((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || - !bprm->file->f_op->mmap) { - return -ENOEXEC; - } - - /* XXX Don't support N32 or 64bit binaries yet because they can - * XXX and do execute 64 bit instructions and expect all registers - * XXX to be 64 bit as well. We need to make the kernel save - * XXX all registers as 64bits on cpu's capable of this at - * XXX exception time plus frob the XTLB exception vector. - */ - if ((ehp->e_flags & EF_MIPS_ABI2)) - return -ENOEXEC; - - return 0; -} - -/* - * This is where the detailed check is performed. Irix binaries - * use interpreters with 'libc.so' in the name, so this function - * can differentiate between Linux and Irix binaries. - */ -static inline int look_for_irix_interpreter(char **name, - struct file **interpreter, - struct elfhdr *interp_elf_ex, - struct elf_phdr *epp, - struct linux_binprm *bprm, int pnum) -{ - int i; - int retval = -EINVAL; - struct file *file = NULL; - - *name = NULL; - for (i = 0; i < pnum; i++, epp++) { - if (epp->p_type != PT_INTERP) - continue; - - /* It is illegal to have two interpreters for one executable. */ - if (*name != NULL) - goto out; - - *name = kmalloc(epp->p_filesz + strlen(IRIX_EMUL), GFP_KERNEL); - if (!*name) - return -ENOMEM; - - strcpy(*name, IRIX_EMUL); - retval = kernel_read(bprm->file, epp->p_offset, (*name + 16), - epp->p_filesz); - if (retval < 0) - goto out; - - file = open_exec(*name); - if (IS_ERR(file)) { - retval = PTR_ERR(file); - goto out; - } - retval = kernel_read(file, 0, bprm->buf, 128); - if (retval < 0) - goto dput_and_out; - - *interp_elf_ex = *(struct elfhdr *) bprm->buf; - } - *interpreter = file; - return 0; - -dput_and_out: - fput(file); -out: - kfree(*name); - return retval; -} - -static inline int verify_irix_interpreter(struct elfhdr *ihp) -{ - if (memcmp(ihp->e_ident, ELFMAG, SELFMAG) != 0) - return -ELIBBAD; - return 0; -} - -#define EXEC_MAP_FLAGS (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE) - -static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnum, - unsigned int *estack, unsigned int *laddr, - unsigned int *scode, unsigned int *ebss, - unsigned int *ecode, unsigned int *edata, - unsigned int *ebrk) -{ - unsigned int tmp; - int i, prot; - - for (i = 0; i < pnum; i++, epp++) { - if (epp->p_type != PT_LOAD) - continue; - - /* Map it. */ - prot = (epp->p_flags & PF_R) ? PROT_READ : 0; - prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0; - prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0; - down_write(¤t->mm->mmap_sem); - (void) do_mmap(fp, (epp->p_vaddr & 0xfffff000), - (epp->p_filesz + (epp->p_vaddr & 0xfff)), - prot, EXEC_MAP_FLAGS, - (epp->p_offset & 0xfffff000)); - up_write(¤t->mm->mmap_sem); - - /* Fixup location tracking vars. */ - if ((epp->p_vaddr & 0xfffff000) < *estack) - *estack = (epp->p_vaddr & 0xfffff000); - if (!*laddr) - *laddr = epp->p_vaddr - epp->p_offset; - if (epp->p_vaddr < *scode) - *scode = epp->p_vaddr; - - tmp = epp->p_vaddr + epp->p_filesz; - if (tmp > *ebss) - *ebss = tmp; - if ((epp->p_flags & PF_X) && *ecode < tmp) - *ecode = tmp; - if (*edata < tmp) - *edata = tmp; - - tmp = epp->p_vaddr + epp->p_memsz; - if (tmp > *ebrk) - *ebrk = tmp; - } - -} - -static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp, - struct file *interp, unsigned int *iladdr, - int pnum, mm_segment_t old_fs, - unsigned int *eentry) -{ - int i; - - *eentry = 0xffffffff; - for (i = 0; i < pnum; i++, epp++) { - if (epp->p_type != PT_INTERP) - continue; - - /* We should have fielded this error elsewhere... */ - if (*eentry != 0xffffffff) - return -1; - - set_fs(old_fs); - *eentry = load_irix_interp(ihp, interp, iladdr); - old_fs = get_fs(); - set_fs(get_ds()); - - fput(interp); - - if (*eentry == 0xffffffff) - return -1; - } - return 0; -} - -/* - * IRIX maps a page at 0x200000 that holds information about the - * process and the system, here we map the page and fill the - * structure - */ -static int irix_map_prda_page(void) -{ - unsigned long v; - struct prda *pp; - - down_write(¤t->mm->mmap_sem); - v = do_brk(PRDA_ADDRESS, PAGE_SIZE); - up_write(¤t->mm->mmap_sem); - - if (v != PRDA_ADDRESS) - return v; /* v must be an error code */ - - pp = (struct prda *) v; - pp->prda_sys.t_pid = task_pid_vnr(current); - pp->prda_sys.t_prid = read_c0_prid(); - pp->prda_sys.t_rpid = task_pid_vnr(current); - - /* We leave the rest set to zero */ - - return 0; -} - - - -/* These are the functions used to load ELF style executables and shared - * libraries. There is no binary dependent code anywhere else. - */ -static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs) -{ - struct elfhdr elf_ex, interp_elf_ex; - struct file *interpreter; - struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr; - unsigned int load_addr, elf_bss, elf_brk; - unsigned int elf_entry, interp_load_addr = 0; - unsigned int start_code, end_code, end_data, elf_stack; - int retval, has_interp, has_ephdr, size, i; - char *elf_interpreter; - mm_segment_t old_fs; - - load_addr = 0; - has_interp = has_ephdr = 0; - elf_ihdr = elf_ephdr = NULL; - elf_ex = *((struct elfhdr *) bprm->buf); - retval = -ENOEXEC; - - if (verify_binary(&elf_ex, bprm)) - goto out; - - /* - * Telling -o32 static binaries from Linux and Irix apart from each - * other is difficult. There are 2 differences to be noted for static - * binaries from the 2 operating systems: - * - * 1) Irix binaries have their .text section before their .init - * section. Linux binaries are just the opposite. - * - * 2) Irix binaries usually have <= 12 sections and Linux - * binaries have > 20. - * - * We will use Method #2 since Method #1 would require us to read in - * the section headers which is way too much overhead. This appears - * to work for everything we have ran into so far. If anyone has a - * better method to tell the binaries apart, I'm listening. - */ - if (elf_ex.e_shnum > 20) - goto out; - - print_elfhdr(&elf_ex); - - /* Now read in all of the header information */ - size = elf_ex.e_phentsize * elf_ex.e_phnum; - if (size > 65536) - goto out; - elf_phdata = kmalloc(size, GFP_KERNEL); - if (elf_phdata == NULL) { - retval = -ENOMEM; - goto out; - } - - retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size); - if (retval < 0) - goto out_free_ph; - - dump_phdrs(elf_phdata, elf_ex.e_phnum); - - /* Set some things for later. */ - for (i = 0; i < elf_ex.e_phnum; i++) { - switch (elf_phdata[i].p_type) { - case PT_INTERP: - has_interp = 1; - elf_ihdr = &elf_phdata[i]; - break; - case PT_PHDR: - has_ephdr = 1; - elf_ephdr = &elf_phdata[i]; - break; - }; - } - - pr_debug("\n"); - - elf_bss = 0; - elf_brk = 0; - - elf_stack = 0xffffffff; - elf_interpreter = NULL; - start_code = 0xffffffff; - end_code = 0; - end_data = 0; - - /* - * If we get a return value, we change the value to be ENOEXEC - * so that we can exit gracefully and the main binary format - * search loop in 'fs/exec.c' will move onto the next handler - * which should be the normal ELF binary handler. - */ - retval = look_for_irix_interpreter(&elf_interpreter, &interpreter, - &interp_elf_ex, elf_phdata, bprm, - elf_ex.e_phnum); - if (retval) { - retval = -ENOEXEC; - goto out_free_file; - } - - if (elf_interpreter) { - retval = verify_irix_interpreter(&interp_elf_ex); - if (retval) - goto out_free_interp; - } - - /* OK, we are done with that, now set up the arg stuff, - * and then start this sucker up. - */ - retval = -E2BIG; - if (!bprm->sh_bang && !bprm->p) - goto out_free_interp; - - /* Flush all traces of the currently running executable */ - retval = flush_old_exec(bprm); - if (retval) - goto out_free_dentry; - - /* OK, This is the point of no return */ - current->mm->end_data = 0; - current->mm->end_code = 0; - current->mm->mmap = NULL; - current->flags &= ~PF_FORKNOEXEC; - elf_entry = (unsigned int) elf_ex.e_entry; - - /* Do this so that we can load the interpreter, if need be. We will - * change some of these later. - */ - setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); - current->mm->start_stack = bprm->p; - - /* At this point, we assume that the image should be loaded at - * fixed address, not at a variable address. - */ - old_fs = get_fs(); - set_fs(get_ds()); - - map_executable(bprm->file, elf_phdata, elf_ex.e_phnum, &elf_stack, - &load_addr, &start_code, &elf_bss, &end_code, - &end_data, &elf_brk); - - if (elf_interpreter) { - retval = map_interpreter(elf_phdata, &interp_elf_ex, - interpreter, &interp_load_addr, - elf_ex.e_phnum, old_fs, &elf_entry); - kfree(elf_interpreter); - if (retval) { - set_fs(old_fs); - printk("Unable to load IRIX ELF interpreter\n"); - send_sig(SIGSEGV, current, 0); - retval = 0; - goto out_free_file; - } - } - - set_fs(old_fs); - - kfree(elf_phdata); - set_personality(PER_IRIX32); - set_binfmt(&irix_format); - compute_creds(bprm); - current->flags &= ~PF_FORKNOEXEC; - bprm->p = (unsigned long) - create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc, - (elf_interpreter ? &elf_ex : NULL), - load_addr, interp_load_addr, regs, elf_ephdr); - current->mm->start_brk = current->mm->brk = elf_brk; - current->mm->end_code = end_code; - current->mm->start_code = start_code; - current->mm->end_data = end_data; - current->mm->start_stack = bprm->p; - - /* Calling set_brk effectively mmaps the pages that we need for the - * bss and break sections. - */ - set_brk(elf_bss, elf_brk); - - /* - * IRIX maps a page at 0x200000 which holds some system - * information. Programs depend on this. - */ - if (irix_map_prda_page()) - goto out_free_dentry; - - padzero(elf_bss); - - pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk); - pr_debug("(end_code) %lx\n" , (long) current->mm->end_code); - pr_debug("(start_code) %lx\n" , (long) current->mm->start_code); - pr_debug("(end_data) %lx\n" , (long) current->mm->end_data); - pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack); - pr_debug("(brk) %lx\n" , (long) current->mm->brk); - -#if 0 /* XXX No fucking way dude... */ - /* Why this, you ask??? Well SVr4 maps page 0 as read-only, - * and some applications "depend" upon this behavior. - * Since we do not have the power to recompile these, we - * emulate the SVr4 behavior. Sigh. - */ - down_write(¤t->mm->mmap_sem); - (void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE, 0); - up_write(¤t->mm->mmap_sem); -#endif - - start_thread(regs, elf_entry, bprm->p); - if (current->ptrace & PT_PTRACED) - send_sig(SIGTRAP, current, 0); - return 0; -out: - return retval; - -out_free_dentry: - allow_write_access(interpreter); - fput(interpreter); -out_free_interp: - kfree(elf_interpreter); -out_free_file: -out_free_ph: - kfree(elf_phdata); - goto out; -} - -/* This is really simpleminded and specialized - we are loading an - * a.out library that is given an ELF header. - */ -static int load_irix_library(struct file *file) -{ - struct elfhdr elf_ex; - struct elf_phdr *elf_phdata = NULL; - unsigned int len = 0; - int elf_bss = 0; - int retval; - unsigned int bss; - int error; - int i, j, k; - - error = kernel_read(file, 0, (char *) &elf_ex, sizeof(elf_ex)); - if (error != sizeof(elf_ex)) - return -ENOEXEC; - - if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0) - return -ENOEXEC; - - /* First of all, some simple consistency checks. */ - if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || - !file->f_op->mmap) - return -ENOEXEC; - - /* Now read in all of the header information. */ - if (sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) - return -ENOEXEC; - - elf_phdata = kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL); - if (elf_phdata == NULL) - return -ENOMEM; - - retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata, - sizeof(struct elf_phdr) * elf_ex.e_phnum); - - j = 0; - for (i=0; ip_type == PT_LOAD) j++; - - if (j != 1) { - kfree(elf_phdata); - return -ENOEXEC; - } - - while (elf_phdata->p_type != PT_LOAD) elf_phdata++; - - /* Now use mmap to map the library into memory. */ - down_write(¤t->mm->mmap_sem); - error = do_mmap(file, - elf_phdata->p_vaddr & 0xfffff000, - elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff), - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, - elf_phdata->p_offset & 0xfffff000); - up_write(¤t->mm->mmap_sem); - - k = elf_phdata->p_vaddr + elf_phdata->p_filesz; - if (k > elf_bss) elf_bss = k; - - if (error != (elf_phdata->p_vaddr & 0xfffff000)) { - kfree(elf_phdata); - return error; - } - - padzero(elf_bss); - - len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000; - bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; - if (bss > len) { - down_write(¤t->mm->mmap_sem); - do_brk(len, bss-len); - up_write(¤t->mm->mmap_sem); - } - kfree(elf_phdata); - return 0; -} - -/* Called through irix_syssgi() to map an elf image given an FD, - * a phdr ptr USER_PHDRP in userspace, and a count CNT telling how many - * phdrs there are in the USER_PHDRP array. We return the vaddr the - * first phdr was successfully mapped to. - */ -unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt) -{ - unsigned long type, vaddr, filesz, offset, flags; - struct elf_phdr __user *hp; - struct file *filp; - int i, retval; - - pr_debug("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n", - fd, user_phdrp, cnt); - - /* First get the verification out of the way. */ - hp = user_phdrp; - if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) { - pr_debug("irix_mapelf: bad pointer to ELF PHDR!\n"); - - return -EFAULT; - } - - dump_phdrs(user_phdrp, cnt); - - for (i = 0; i < cnt; i++, hp++) { - if (__get_user(type, &hp->p_type)) - return -EFAULT; - if (type != PT_LOAD) { - printk("irix_mapelf: One section is not PT_LOAD!\n"); - return -ENOEXEC; - } - } - - filp = fget(fd); - if (!filp) - return -EACCES; - if (!filp->f_op) { - printk("irix_mapelf: Bogon filp!\n"); - fput(filp); - return -EACCES; - } - - hp = user_phdrp; - for (i = 0; i < cnt; i++, hp++) { - int prot; - - retval = __get_user(vaddr, &hp->p_vaddr); - retval |= __get_user(filesz, &hp->p_filesz); - retval |= __get_user(offset, &hp->p_offset); - retval |= __get_user(flags, &hp->p_flags); - if (retval) - return retval; - - prot = (flags & PF_R) ? PROT_READ : 0; - prot |= (flags & PF_W) ? PROT_WRITE : 0; - prot |= (flags & PF_X) ? PROT_EXEC : 0; - - down_write(¤t->mm->mmap_sem); - retval = do_mmap(filp, (vaddr & 0xfffff000), - (filesz + (vaddr & 0xfff)), - prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), - (offset & 0xfffff000)); - up_write(¤t->mm->mmap_sem); - - if (retval != (vaddr & 0xfffff000)) { - printk("irix_mapelf: do_mmap fails with %d!\n", retval); - fput(filp); - return retval; - } - } - - pr_debug("irix_mapelf: Success, returning %08lx\n", - (unsigned long) user_phdrp->p_vaddr); - - fput(filp); - - if (__get_user(vaddr, &user_phdrp->p_vaddr)) - return -EFAULT; - - return vaddr; -} - -/* - * ELF core dumper - * - * Modelled on fs/exec.c:aout_core_dump() - * Jeremy Fitzhardinge - */ - -/* These are the only things you should do on a core-file: use only these - * functions to write out all the necessary info. - */ -static int dump_write(struct file *file, const void __user *addr, int nr) -{ - return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr; -} - -static int dump_seek(struct file *file, off_t off) -{ - if (file->f_op->llseek) { - if (file->f_op->llseek(file, off, 0) != off) - return 0; - } else - file->f_pos = off; - return 1; -} - -/* Decide whether a segment is worth dumping; default is yes to be - * sure (missing info is worse than too much; etc). - * Personally I'd include everything, and use the coredump limit... - * - * I think we should skip something. But I am not sure how. H.J. - */ -static inline int maydump(struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC))) - return 0; -#if 1 - if (vma->vm_flags & (VM_WRITE|VM_GROWSUP|VM_GROWSDOWN)) - return 1; - if (vma->vm_flags & (VM_READ|VM_EXEC|VM_EXECUTABLE|VM_SHARED)) - return 0; -#endif - return 1; -} - -/* An ELF note in memory. */ -struct memelfnote -{ - const char *name; - int type; - unsigned int datasz; - void *data; -}; - -static int notesize(struct memelfnote *en) -{ - int sz; - - sz = sizeof(struct elf_note); - sz += roundup(strlen(en->name) + 1, 4); - sz += roundup(en->datasz, 4); - - return sz; -} - -#define DUMP_WRITE(addr, nr) \ - if (!dump_write(file, (addr), (nr))) \ - goto end_coredump; -#define DUMP_SEEK(off) \ - if (!dump_seek(file, (off))) \ - goto end_coredump; - -static int writenote(struct memelfnote *men, struct file *file) -{ - struct elf_note en; - - en.n_namesz = strlen(men->name) + 1; - en.n_descsz = men->datasz; - en.n_type = men->type; - - DUMP_WRITE(&en, sizeof(en)); - DUMP_WRITE(men->name, en.n_namesz); - /* XXX - cast from long long to long to avoid need for libgcc.a */ - DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ - DUMP_WRITE(men->data, men->datasz); - DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ - - return 1; - -end_coredump: - return 0; -} -#undef DUMP_WRITE -#undef DUMP_SEEK - -#define DUMP_WRITE(addr, nr) \ - if (!dump_write(file, (addr), (nr))) \ - goto end_coredump; -#define DUMP_SEEK(off) \ - if (!dump_seek(file, (off))) \ - goto end_coredump; - -/* Actual dumper. - * - * This is a two-pass process; first we find the offsets of the bits, - * and then they are actually written out. If we run out of core limit - * we just truncate. - */ -static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) -{ - int has_dumped = 0; - mm_segment_t fs; - int segs; - int i; - size_t size; - struct vm_area_struct *vma; - struct elfhdr elf; - off_t offset = 0, dataoff; - int numnote = 3; - struct memelfnote notes[3]; - struct elf_prstatus prstatus; /* NT_PRSTATUS */ - elf_fpregset_t fpu; /* NT_PRFPREG */ - struct elf_prpsinfo psinfo; /* NT_PRPSINFO */ - - /* Count what's needed to dump, up to the limit of coredump size. */ - segs = 0; - size = 0; - for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { - if (maydump(vma)) - { - int sz = vma->vm_end-vma->vm_start; - - if (size+sz >= limit) - break; - else - size += sz; - } - - segs++; - } - pr_debug("irix_core_dump: %d segs taking %d bytes\n", segs, size); - - /* Set up header. */ - memcpy(elf.e_ident, ELFMAG, SELFMAG); - elf.e_ident[EI_CLASS] = ELFCLASS32; - elf.e_ident[EI_DATA] = ELFDATA2LSB; - elf.e_ident[EI_VERSION] = EV_CURRENT; - elf.e_ident[EI_OSABI] = ELF_OSABI; - memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); - - elf.e_type = ET_CORE; - elf.e_machine = ELF_ARCH; - elf.e_version = EV_CURRENT; - elf.e_entry = 0; - elf.e_phoff = sizeof(elf); - elf.e_shoff = 0; - elf.e_flags = 0; - elf.e_ehsize = sizeof(elf); - elf.e_phentsize = sizeof(struct elf_phdr); - elf.e_phnum = segs+1; /* Include notes. */ - elf.e_shentsize = 0; - elf.e_shnum = 0; - elf.e_shstrndx = 0; - - fs = get_fs(); - set_fs(KERNEL_DS); - - has_dumped = 1; - current->flags |= PF_DUMPCORE; - - DUMP_WRITE(&elf, sizeof(elf)); - offset += sizeof(elf); /* Elf header. */ - offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers. */ - - /* Set up the notes in similar form to SVR4 core dumps made - * with info from their /proc. - */ - memset(&psinfo, 0, sizeof(psinfo)); - memset(&prstatus, 0, sizeof(prstatus)); - - notes[0].name = "CORE"; - notes[0].type = NT_PRSTATUS; - notes[0].datasz = sizeof(prstatus); - notes[0].data = &prstatus; - prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; - prstatus.pr_sigpend = current->pending.signal.sig[0]; - prstatus.pr_sighold = current->blocked.sig[0]; - psinfo.pr_pid = prstatus.pr_pid = task_pid_vnr(current); - psinfo.pr_ppid = prstatus.pr_ppid = task_pid_vnr(current->parent); - psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_vnr(current); - psinfo.pr_sid = prstatus.pr_sid = task_session_vnr(current); - if (thread_group_leader(current)) { - /* - * This is the record for the group leader. Add in the - * cumulative times of previous dead threads. This total - * won't include the time of each live thread whose state - * is included in the core dump. The final total reported - * to our parent process when it calls wait4 will include - * those sums as well as the little bit more time it takes - * this and each other thread to finish dying after the - * core dump synchronization phase. - */ - jiffies_to_timeval(current->utime + current->signal->utime, - &prstatus.pr_utime); - jiffies_to_timeval(current->stime + current->signal->stime, - &prstatus.pr_stime); - } else { - jiffies_to_timeval(current->utime, &prstatus.pr_utime); - jiffies_to_timeval(current->stime, &prstatus.pr_stime); - } - jiffies_to_timeval(current->signal->cutime, &prstatus.pr_cutime); - jiffies_to_timeval(current->signal->cstime, &prstatus.pr_cstime); - - if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { - printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) " - "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); - } else { - *(struct pt_regs *)&prstatus.pr_reg = *regs; - } - - notes[1].name = "CORE"; - notes[1].type = NT_PRPSINFO; - notes[1].datasz = sizeof(psinfo); - notes[1].data = &psinfo; - i = current->state ? ffz(~current->state) + 1 : 0; - psinfo.pr_state = i; - psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; - psinfo.pr_zomb = psinfo.pr_sname == 'Z'; - psinfo.pr_nice = task_nice(current); - psinfo.pr_flag = current->flags; - psinfo.pr_uid = current->uid; - psinfo.pr_gid = current->gid; - { - int i, len; - - set_fs(fs); - - len = current->mm->arg_end - current->mm->arg_start; - len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; - (void *) copy_from_user(&psinfo.pr_psargs, - (const char __user *)current->mm->arg_start, len); - for (i = 0; i < len; i++) - if (psinfo.pr_psargs[i] == 0) - psinfo.pr_psargs[i] = ' '; - psinfo.pr_psargs[len] = 0; - - set_fs(KERNEL_DS); - } - strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname)); - - /* Try to dump the FPU. */ - prstatus.pr_fpvalid = dump_fpu(regs, &fpu); - if (!prstatus.pr_fpvalid) { - numnote--; - } else { - notes[2].name = "CORE"; - notes[2].type = NT_PRFPREG; - notes[2].datasz = sizeof(fpu); - notes[2].data = &fpu; - } - - /* Write notes phdr entry. */ - { - struct elf_phdr phdr; - int sz = 0; - - for (i = 0; i < numnote; i++) - sz += notesize(¬es[i]); - - phdr.p_type = PT_NOTE; - phdr.p_offset = offset; - phdr.p_vaddr = 0; - phdr.p_paddr = 0; - phdr.p_filesz = sz; - phdr.p_memsz = 0; - phdr.p_flags = 0; - phdr.p_align = 0; - - offset += phdr.p_filesz; - DUMP_WRITE(&phdr, sizeof(phdr)); - } - - /* Page-align dumped data. */ - dataoff = offset = roundup(offset, PAGE_SIZE); - - /* Write program headers for segments dump. */ - for (vma = current->mm->mmap, i = 0; - i < segs && vma != NULL; vma = vma->vm_next) { - struct elf_phdr phdr; - size_t sz; - - i++; - - sz = vma->vm_end - vma->vm_start; - - phdr.p_type = PT_LOAD; - phdr.p_offset = offset; - phdr.p_vaddr = vma->vm_start; - phdr.p_paddr = 0; - phdr.p_filesz = maydump(vma) ? sz : 0; - phdr.p_memsz = sz; - offset += phdr.p_filesz; - phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; - if (vma->vm_flags & VM_WRITE) - phdr.p_flags |= PF_W; - if (vma->vm_flags & VM_EXEC) - phdr.p_flags |= PF_X; - phdr.p_align = PAGE_SIZE; - - DUMP_WRITE(&phdr, sizeof(phdr)); - } - - for (i = 0; i < numnote; i++) - if (!writenote(¬es[i], file)) - goto end_coredump; - - set_fs(fs); - - DUMP_SEEK(dataoff); - - for (i = 0, vma = current->mm->mmap; - i < segs && vma != NULL; - vma = vma->vm_next) { - unsigned long addr = vma->vm_start; - unsigned long len = vma->vm_end - vma->vm_start; - - if (!maydump(vma)) - continue; - i++; - pr_debug("elf_core_dump: writing %08lx %lx\n", addr, len); - DUMP_WRITE((void __user *)addr, len); - } - - if ((off_t) file->f_pos != offset) { - /* Sanity check. */ - printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", - (off_t) file->f_pos, offset); - } - -end_coredump: - set_fs(fs); - return has_dumped; -} - -static int __init init_irix_binfmt(void) -{ - extern int init_inventory(void); - extern asmlinkage unsigned long sys_call_table; - extern asmlinkage unsigned long sys_call_table_irix5; - - init_inventory(); - - /* - * Copy the IRIX5 syscall table (8000 bytes) into the main syscall - * table. The IRIX5 calls are located by an offset of 8000 bytes - * from the beginning of the main table. - */ - memcpy((void *) ((unsigned long) &sys_call_table + 8000), - &sys_call_table_irix5, 8000); - - return register_binfmt(&irix_format); -} - -static void __exit exit_irix_binfmt(void) -{ - /* - * Remove the Irix ELF loader. - */ - unregister_binfmt(&irix_format); -} - -module_init(init_irix_binfmt) -module_exit(exit_irix_binfmt) diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c deleted file mode 100644 index cf2dcd3..0000000 --- a/arch/mips/kernel/irixinv.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Support the inventory interface for IRIX binaries - * This is invoked before the mm layer is working, so we do not - * use the linked lists for the inventory yet. - * - * Miguel de Icaza, 1997. - */ -#include -#include -#include - -#define MAX_INVENTORY 50 -int inventory_items = 0; - -static inventory_t inventory [MAX_INVENTORY]; - -void add_to_inventory(int class, int type, int controller, int unit, int state) -{ - inventory_t *ni = &inventory [inventory_items]; - - if (inventory_items == MAX_INVENTORY) - return; - - ni->inv_class = class; - ni->inv_type = type; - ni->inv_controller = controller; - ni->inv_unit = unit; - ni->inv_state = state; - ni->inv_next = ni; - inventory_items++; -} - -int dump_inventory_to_user(void __user *userbuf, int size) -{ - inventory_t *inv = &inventory [0]; - inventory_t __user *user = userbuf; - int v; - - if (!access_ok(VERIFY_WRITE, userbuf, size)) - return -EFAULT; - - for (v = 0; v < inventory_items; v++){ - inv = &inventory [v]; - if (copy_to_user (user, inv, sizeof (inventory_t))) - return -EFAULT; - user++; - } - return inventory_items * sizeof(inventory_t); -} - -int __init init_inventory(void) -{ - /* - * gross hack while we put the right bits all over the kernel - * most likely this will not let just anyone run the X server - * until we put the right values all over the place - */ - add_to_inventory(10, 3, 0, 0, 16400); - add_to_inventory(1, 1, 150, -1, 12); - add_to_inventory(1, 3, 0, 0, 8976); - add_to_inventory(1, 2, 0, 0, 8976); - add_to_inventory(4, 8, 0, 0, 2); - add_to_inventory(5, 5, 0, 0, 1); - add_to_inventory(3, 3, 0, 0, 32768); - add_to_inventory(3, 4, 0, 0, 32768); - add_to_inventory(3, 8, 0, 0, 524288); - add_to_inventory(3, 9, 0, 0, 64); - add_to_inventory(3, 1, 0, 0, 67108864); - add_to_inventory(12, 3, 0, 0, 16); - add_to_inventory(8, 7, 17, 0, 16777472); - add_to_inventory(8, 0, 0, 0, 1); - add_to_inventory(2, 1, 0, 13, 2); - add_to_inventory(2, 2, 0, 2, 0); - add_to_inventory(2, 2, 0, 1, 0); - add_to_inventory(7, 14, 0, 0, 6); - - return 0; -} diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c deleted file mode 100644 index b39bdba..0000000 --- a/arch/mips/kernel/irixioctl.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * irixioctl.c: A fucking mess... - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#undef DEBUG_IOCTLS -#undef DEBUG_MISSING_IOCTL - -struct irix_termios { - tcflag_t c_iflag, c_oflag, c_cflag, c_lflag; - cc_t c_cc[NCCS]; -}; - -asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg) -{ - struct tty_struct *tp, *rtp; - mm_segment_t old_fs; - int i, error = 0; - -#ifdef DEBUG_IOCTLS - printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd); -#endif - switch(cmd) { - case 0x00005401: -#ifdef DEBUG_IOCTLS - printk("TCGETA, %08lx) ", arg); -#endif - error = sys_ioctl(fd, TCGETA, arg); - break; - - case 0x0000540d: { - struct termios kt; - struct irix_termios __user *it = - (struct irix_termios __user *) arg; - -#ifdef DEBUG_IOCTLS - printk("TCGETS, %08lx) ", arg); -#endif - if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) { - error = -EFAULT; - break; - } - old_fs = get_fs(); set_fs(get_ds()); - error = sys_ioctl(fd, TCGETS, (unsigned long) &kt); - set_fs(old_fs); - if (error) - break; - - error = __put_user(kt.c_iflag, &it->c_iflag); - error |= __put_user(kt.c_oflag, &it->c_oflag); - error |= __put_user(kt.c_cflag, &it->c_cflag); - error |= __put_user(kt.c_lflag, &it->c_lflag); - - for (i = 0; i < NCCS; i++) - error |= __put_user(kt.c_cc[i], &it->c_cc[i]); - break; - } - - case 0x0000540e: { - struct termios kt; - struct irix_termios *it = (struct irix_termios *) arg; - -#ifdef DEBUG_IOCTLS - printk("TCSETS, %08lx) ", arg); -#endif - if (!access_ok(VERIFY_READ, it, sizeof(*it))) { - error = -EFAULT; - break; - } - old_fs = get_fs(); set_fs(get_ds()); - error = sys_ioctl(fd, TCGETS, (unsigned long) &kt); - set_fs(old_fs); - if (error) - break; - - error = __get_user(kt.c_iflag, &it->c_iflag); - error |= __get_user(kt.c_oflag, &it->c_oflag); - error |= __get_user(kt.c_cflag, &it->c_cflag); - error |= __get_user(kt.c_lflag, &it->c_lflag); - - for (i = 0; i < NCCS; i++) - error |= __get_user(kt.c_cc[i], &it->c_cc[i]); - - if (error) - break; - old_fs = get_fs(); set_fs(get_ds()); - error = sys_ioctl(fd, TCSETS, (unsigned long) &kt); - set_fs(old_fs); - break; - } - - case 0x0000540f: -#ifdef DEBUG_IOCTLS - printk("TCSETSW, %08lx) ", arg); -#endif - error = sys_ioctl(fd, TCSETSW, arg); - break; - - case 0x00005471: -#ifdef DEBUG_IOCTLS - printk("TIOCNOTTY, %08lx) ", arg); -#endif - error = sys_ioctl(fd, TIOCNOTTY, arg); - break; - - case 0x00007416: { - pid_t pid; -#ifdef DEBUG_IOCTLS - printk("TIOCGSID, %08lx) ", arg); -#endif - old_fs = get_fs(); set_fs(get_ds()); - error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid); - set_fs(old_fs); - if (!error) - error = put_user(pid, (unsigned long __user *) arg); - break; - } - case 0x746e: - /* TIOCSTART, same effect as hitting ^Q */ -#ifdef DEBUG_IOCTLS - printk("TIOCSTART, %08lx) ", arg); -#endif - error = sys_ioctl(fd, TCXONC, TCOON); - break; - - case 0x20006968: -#ifdef DEBUG_IOCTLS - printk("SIOCGETLABEL, %08lx) ", arg); -#endif - error = -ENOPKG; - break; - - case 0x40047477: -#ifdef DEBUG_IOCTLS - printk("TIOCGPGRP, %08lx) ", arg); -#endif - error = sys_ioctl(fd, TIOCGPGRP, arg); -#ifdef DEBUG_IOCTLS - printk("arg=%d ", *(int *)arg); -#endif - break; - - case 0x40087468: -#ifdef DEBUG_IOCTLS - printk("TIOCGWINSZ, %08lx) ", arg); -#endif - error = sys_ioctl(fd, TIOCGWINSZ, arg); - break; - - case 0x8004667e: - error = sys_ioctl(fd, FIONBIO, arg); - break; - - case 0x80047476: - error = sys_ioctl(fd, TIOCSPGRP, arg); - break; - - case 0x8020690c: - error = sys_ioctl(fd, SIOCSIFADDR, arg); - break; - - case 0x80206910: - error = sys_ioctl(fd, SIOCSIFFLAGS, arg); - break; - - case 0xc0206911: - error = sys_ioctl(fd, SIOCGIFFLAGS, arg); - break; - - case 0xc020691b: - error = sys_ioctl(fd, SIOCGIFMETRIC, arg); - break; - - default: { -#ifdef DEBUG_MISSING_IOCTL - char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n"; - -#ifdef DEBUG_IOCTLS - printk("UNIMP_IOCTL, %08lx)\n", arg); -#endif - old_fs = get_fs(); set_fs(get_ds()); - sys_write(2, msg, strlen(msg)); - set_fs(old_fs); - printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n", - current->comm, current->pid, cmd); - do_exit(255); -#else - error = sys_ioctl(fd, cmd, arg); -#endif - } - - }; -#ifdef DEBUG_IOCTLS - printk("error=%d\n", error); -#endif - return error; -} diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c deleted file mode 100644 index 0215c80..0000000 --- a/arch/mips/kernel/irixsig.c +++ /dev/null @@ -1,888 +0,0 @@ -/* - * irixsig.c: WHEEE, IRIX signals! YOW, am I compatible or what?!?! - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997 - 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#undef DEBUG_SIG - -#define _S(nr) (1<<((nr)-1)) - -#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) - -#define _IRIX_NSIG 128 -#define _IRIX_NSIG_BPW BITS_PER_LONG -#define _IRIX_NSIG_WORDS (_IRIX_NSIG / _IRIX_NSIG_BPW) - -typedef struct { - unsigned long sig[_IRIX_NSIG_WORDS]; -} irix_sigset_t; - -struct sigctx_irix5 { - u32 rmask, cp0_status; - u64 pc; - u64 regs[32]; - u64 fpregs[32]; - u32 usedfp, fpcsr, fpeir, sstk_flags; - u64 hi, lo; - u64 cp0_cause, cp0_badvaddr, _unused0; - irix_sigset_t sigset; - u64 weird_fpu_thing; - u64 _unused1[31]; -}; - -#ifdef DEBUG_SIG -/* Debugging */ -static inline void dump_irix5_sigctx(struct sigctx_irix5 *c) -{ - int i; - - printk("misc: rmask[%08lx] status[%08lx] pc[%08lx]\n", - (unsigned long) c->rmask, - (unsigned long) c->cp0_status, - (unsigned long) c->pc); - printk("regs: "); - for(i = 0; i < 16; i++) - printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]); - printk("\nregs: "); - for(i = 16; i < 32; i++) - printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]); - printk("\nfpregs: "); - for(i = 0; i < 16; i++) - printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]); - printk("\nfpregs: "); - for(i = 16; i < 32; i++) - printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]); - printk("misc: usedfp[%d] fpcsr[%08lx] fpeir[%08lx] stk_flgs[%08lx]\n", - (int) c->usedfp, (unsigned long) c->fpcsr, - (unsigned long) c->fpeir, (unsigned long) c->sstk_flags); - printk("misc: hi[%08lx] lo[%08lx] cause[%08lx] badvaddr[%08lx]\n", - (unsigned long) c->hi, (unsigned long) c->lo, - (unsigned long) c->cp0_cause, (unsigned long) c->cp0_badvaddr); - printk("misc: sigset<0>[%08lx] sigset<1>[%08lx] sigset<2>[%08lx] " - "sigset<3>[%08lx]\n", (unsigned long) c->sigset.sig[0], - (unsigned long) c->sigset.sig[1], - (unsigned long) c->sigset.sig[2], - (unsigned long) c->sigset.sig[3]); -} -#endif - -static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, - int signr, sigset_t *oldmask) -{ - struct sigctx_irix5 __user *ctx; - unsigned long sp; - int error, i; - - sp = regs->regs[29]; - sp -= sizeof(struct sigctx_irix5); - sp &= ~(0xf); - ctx = (struct sigctx_irix5 __user *) sp; - if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) - goto segv_and_exit; - - error = __put_user(0, &ctx->weird_fpu_thing); - error |= __put_user(~(0x00000001), &ctx->rmask); - error |= __put_user(0, &ctx->regs[0]); - for(i = 1; i < 32; i++) - error |= __put_user((u64) regs->regs[i], &ctx->regs[i]); - - error |= __put_user((u64) regs->hi, &ctx->hi); - error |= __put_user((u64) regs->lo, &ctx->lo); - error |= __put_user((u64) regs->cp0_epc, &ctx->pc); - error |= __put_user(!!used_math(), &ctx->usedfp); - error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); - error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); - - error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ - - error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0; - - if (error) - goto segv_and_exit; - -#ifdef DEBUG_SIG - dump_irix5_sigctx(ctx); -#endif - - regs->regs[4] = (unsigned long) signr; - regs->regs[5] = 0; /* XXX sigcode XXX */ - regs->regs[6] = regs->regs[29] = sp; - regs->regs[7] = (unsigned long) ka->sa.sa_handler; - regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; - - return 1; - -segv_and_exit: - force_sigsegv(signr, current); - return 0; -} - -static int inline -setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *oldmask, siginfo_t *info) -{ - printk("Aiee: setup_tr_frame wants to be written"); - do_exit(SIGSEGV); -} - -static inline int handle_signal(unsigned long sig, siginfo_t *info, - struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) -{ - int ret; - - switch(regs->regs[0]) { - case ERESTARTNOHAND: - regs->regs[2] = EINTR; - break; - case ERESTARTSYS: - if(!(ka->sa.sa_flags & SA_RESTART)) { - regs->regs[2] = EINTR; - break; - } - /* fallthrough */ - case ERESTARTNOINTR: /* Userland will reload $v0. */ - regs->cp0_epc -= 8; - } - - regs->regs[0] = 0; /* Don't deal with this again. */ - - if (ka->sa.sa_flags & SA_SIGINFO) - ret = setup_irix_rt_frame(ka, regs, sig, oldset, info); - else - ret = setup_irix_frame(ka, regs, sig, oldset); - - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - return ret; -} - -void do_irix_signal(struct pt_regs *regs) -{ - struct k_sigaction ka; - siginfo_t info; - int signr; - sigset_t *oldset; - - /* - * We want the common case to go fast, which is why we may in certain - * cases get here from kernel mode. Just return without doing anything - * if so. - */ - if (!user_mode(regs)) - return; - - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - - return; - } - - /* - * Who's code doesn't conform to the restartable syscall convention - * dies here!!! The li instruction, a single machine instruction, - * must directly be followed by the syscall instruction. - */ - if (regs->regs[0]) { - if (regs->regs[2] == ERESTARTNOHAND || - regs->regs[2] == ERESTARTSYS || - regs->regs[2] == ERESTARTNOINTR) { - regs->cp0_epc -= 8; - } - if (regs->regs[2] == ERESTART_RESTARTBLOCK) { - regs->regs[2] = __NR_restart_syscall; - regs->regs[7] = regs->regs[26]; - regs->cp0_epc -= 4; - } - regs->regs[0] = 0; /* Don't deal with this again. */ - } - - /* - * If there's no signal to deliver, we just put the saved sigmask - * back - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } -} - -asmlinkage void -irix_sigreturn(struct pt_regs *regs) -{ - struct sigctx_irix5 __user *context, *magic; - unsigned long umask, mask; - u64 *fregs; - u32 usedfp; - int error, sig, i, base = 0; - sigset_t blocked; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - if (regs->regs[2] == 1000) - base = 1; - - context = (struct sigctx_irix5 __user *) regs->regs[base + 4]; - magic = (struct sigctx_irix5 __user *) regs->regs[base + 5]; - sig = (int) regs->regs[base + 6]; -#ifdef DEBUG_SIG - printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", - current->comm, current->pid, context, magic, sig); -#endif - if (!context) - context = magic; - if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5))) - goto badframe; - -#ifdef DEBUG_SIG - dump_irix5_sigctx(context); -#endif - - error = __get_user(regs->cp0_epc, &context->pc); - error |= __get_user(umask, &context->rmask); - - mask = 2; - for (i = 1; i < 32; i++, mask <<= 1) { - if (umask & mask) - error |= __get_user(regs->regs[i], &context->regs[i]); - } - error |= __get_user(regs->hi, &context->hi); - error |= __get_user(regs->lo, &context->lo); - - error |= __get_user(usedfp, &context->usedfp); - if ((umask & 1) && usedfp) { - fregs = (u64 *) ¤t->thread.fpu; - - for(i = 0; i < 32; i++) - error |= __get_user(fregs[i], &context->fpregs[i]); - error |= __get_user(current->thread.fpu.fcr31, &context->fpcsr); - } - - /* XXX do sigstack crapola here... XXX */ - - error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0; - - if (error) - goto badframe; - - sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = blocked; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - /* - * Don't let your children do this ... - */ - __asm__ __volatile__( - "move\t$29,%0\n\t" - "j\tsyscall_exit" - :/* no outputs */ - :"r" (®s)); - /* Unreached */ - -badframe: - force_sig(SIGSEGV, current); -} - -struct sigact_irix5 { - int flags; - void (*handler)(int); - u32 sigset[4]; - int _unused0[2]; -}; - -#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: - set only the low 32 bit of the sigset. */ - -#ifdef DEBUG_SIG -static inline void dump_sigact_irix5(struct sigact_irix5 *p) -{ - printk("", p->flags, - (unsigned long) p->handler, - (unsigned long) p->sigset[0]); -} -#endif - -asmlinkage int -irix_sigaction(int sig, const struct sigaction __user *act, - struct sigaction __user *oact, void __user *trampoline) -{ - struct k_sigaction new_ka, old_ka; - int ret; - -#ifdef DEBUG_SIG - printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"), - (!old ? "0" : "OLD"), trampoline); - if(new) { - dump_sigact_irix5(new); printk(" "); - } -#endif - if (act) { - sigset_t mask; - int err; - - if (!access_ok(VERIFY_READ, act, sizeof(*act))) - return -EFAULT; - err = __get_user(new_ka.sa.sa_handler, &act->sa_handler); - err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); - - err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0; - if (err) - return err; - - /* - * Hmmm... methinks IRIX libc always passes a valid trampoline - * value for all invocations of sigaction. Will have to - * investigate. POSIX POSIX, die die die... - */ - new_ka.sa_restorer = trampoline; - } - -/* XXX Implement SIG_SETMASK32 for IRIX compatibility */ - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - int err; - - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) - return -EFAULT; - - err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler); - err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, - sizeof(sigset_t)) ? -EFAULT : 0; - if (err) - return -EFAULT; - } - - return ret; -} - -asmlinkage int irix_sigpending(irix_sigset_t __user *set) -{ - return do_sigpending(set, sizeof(*set)); -} - -asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, - irix_sigset_t __user *old) -{ - sigset_t oldbits, newbits; - - if (new) { - if (!access_ok(VERIFY_READ, new, sizeof(*new))) - return -EFAULT; - if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4)) - return -EFAULT; - sigdelsetmask(&newbits, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - oldbits = current->blocked; - - switch(how) { - case 1: - sigorsets(&newbits, &oldbits, &newbits); - break; - - case 2: - sigandsets(&newbits, &oldbits, &newbits); - break; - - case 3: - break; - - case 256: - siginitset(&newbits, newbits.sig[0]); - break; - - default: - spin_unlock_irq(¤t->sighand->siglock); - return -EINVAL; - } - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - if (old) - return copy_to_user(old, ¤t->blocked, - sizeof(unsigned long)*4) ? -EFAULT : 0; - - return 0; -} - -asmlinkage int irix_sigsuspend(struct pt_regs *regs) -{ - sigset_t newset; - sigset_t __user *uset; - - uset = (sigset_t __user *) regs->regs[4]; - if (copy_from_user(&newset, uset, sizeof(sigset_t))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; -} - -/* hate hate hate... */ -struct irix5_siginfo { - int sig, code, error; - union { - char unused[128 - (3 * 4)]; /* Safety net. */ - struct { - int pid; - union { - int uid; - struct { - int utime, status, stime; - } child; - } procdata; - } procinfo; - - unsigned long fault_addr; - - struct { - int fd; - long band; - } fileinfo; - - unsigned long sigval; - } stuff; -}; - -asmlinkage int irix_sigpoll_sys(unsigned long __user *set, - struct irix5_siginfo __user *info, struct timespec __user *tp) -{ - long expire = MAX_SCHEDULE_TIMEOUT; - sigset_t kset; - int i, sig, error, timeo = 0; - struct timespec ktp; - -#ifdef DEBUG_SIG - printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n", - current->comm, current->pid, set, info, tp); -#endif - - /* Must always specify the signal set. */ - if (!set) - return -EINVAL; - - if (copy_from_user(&kset, set, sizeof(set))) - return -EFAULT; - - if (info && clear_user(info, sizeof(*info))) { - error = -EFAULT; - goto out; - } - - if (tp) { - if (copy_from_user(&ktp, tp, sizeof(*tp))) - return -EFAULT; - - if (!ktp.tv_sec && !ktp.tv_nsec) - return -EINVAL; - - expire = timespec_to_jiffies(&ktp) + - (ktp.tv_sec || ktp.tv_nsec); - } - - while(1) { - long tmp = 0; - - expire = schedule_timeout_interruptible(expire); - - for (i=0; i < _IRIX_NSIG_WORDS; i++) - tmp |= (current->pending.signal.sig[i] & kset.sig[i]); - - if (tmp) - break; - if (!expire) { - timeo = 1; - break; - } - if (signal_pending(current)) - return -EINTR; - } - if (timeo) - return -EAGAIN; - - for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { - if (sigismember (&kset, sig)) - continue; - if (sigismember (¤t->pending.signal, sig)) { - /* XXX need more than this... */ - if (info) - return copy_to_user(&info->sig, &sig, sizeof(sig)); - return 0; - } - } - - /* Should not get here, but do something sane if we do. */ - error = -EINTR; - -out: - return error; -} - -/* This is here because of irix5_siginfo definition. */ -#define IRIX_P_PID 0 -#define IRIX_P_PGID 2 -#define IRIX_P_ALL 7 - -#define W_EXITED 1 -#define W_TRAPPED 2 -#define W_STOPPED 4 -#define W_CONT 8 -#define W_NOHANG 64 - -#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG) - -asmlinkage int irix_waitsys(int type, int upid, - struct irix5_siginfo __user *info, int options, - struct rusage __user *ru) -{ - struct pid *pid = NULL; - int flag, retval; - DECLARE_WAITQUEUE(wait, current); - struct task_struct *tsk; - struct task_struct *p; - struct list_head *_p; - - if (!info) - return -EINVAL; - - if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) - return -EFAULT; - - if (ru) - if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) - return -EFAULT; - - if (options & ~W_MASK) - return -EINVAL; - - if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) - return -EINVAL; - - if (type != IRIX_P_ALL) - pid = find_get_pid(upid); - add_wait_queue(¤t->signal->wait_chldexit, &wait); -repeat: - flag = 0; - current->state = TASK_INTERRUPTIBLE; - read_lock(&tasklist_lock); - tsk = current; - list_for_each(_p, &tsk->children) { - p = list_entry(_p, struct task_struct, sibling); - if ((type == IRIX_P_PID) && task_pid(p) != pid) - continue; - if ((type == IRIX_P_PGID) && task_pgrp(p) != pid) - continue; - if ((p->exit_signal != SIGCHLD)) - continue; - flag = 1; - switch (p->state) { - case TASK_STOPPED: - if (!p->exit_code) - continue; - if (!(options & (W_TRAPPED|W_STOPPED)) && - !(p->ptrace & PT_PTRACED)) - continue; - read_unlock(&tasklist_lock); - - /* move to end of parent's list to avoid starvation */ - write_lock_irq(&tasklist_lock); - remove_parent(p); - add_parent(p); - write_unlock_irq(&tasklist_lock); - retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; - if (retval) - goto end_waitsys; - - retval = __put_user(SIGCHLD, &info->sig); - retval |= __put_user(0, &info->code); - retval |= __put_user(task_pid_vnr(p), &info->stuff.procinfo.pid); - retval |= __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); - retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); - if (retval) - goto end_waitsys; - - p->exit_code = 0; - goto end_waitsys; - - case EXIT_ZOMBIE: - current->signal->cutime += p->utime + p->signal->cutime; - current->signal->cstime += p->stime + p->signal->cstime; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - retval = __put_user(SIGCHLD, &info->sig); - retval |= __put_user(1, &info->code); /* CLD_EXITED */ - retval |= __put_user(task_pid_vnr(p), &info->stuff.procinfo.pid); - retval |= __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - retval |= __put_user(p->utime, - &info->stuff.procinfo.procdata.child.utime); - retval |= __put_user(p->stime, - &info->stuff.procinfo.procdata.child.stime); - if (retval) - goto end_waitsys; - - if (p->real_parent != p->parent) { - write_lock_irq(&tasklist_lock); - remove_parent(p); - p->parent = p->real_parent; - add_parent(p); - do_notify_parent(p, SIGCHLD); - write_unlock_irq(&tasklist_lock); - } else - release_task(p); - goto end_waitsys; - default: - continue; - } - tsk = next_thread(tsk); - } - read_unlock(&tasklist_lock); - if (flag) { - retval = 0; - if (options & W_NOHANG) - goto end_waitsys; - retval = -ERESTARTSYS; - if (signal_pending(current)) - goto end_waitsys; - current->state = TASK_INTERRUPTIBLE; - schedule(); - goto repeat; - } - retval = -ECHILD; -end_waitsys: - current->state = TASK_RUNNING; - remove_wait_queue(¤t->signal->wait_chldexit, &wait); - put_pid(pid); - - return retval; -} - -struct irix5_context { - u32 flags; - u32 link; - u32 sigmask[4]; - struct { u32 sp, size, flags; } stack; - int regs[36]; - u32 fpregs[32]; - u32 fpcsr; - u32 _unused0; - u32 _unused1[47]; - u32 weird_graphics_thing; -}; - -asmlinkage int irix_getcontext(struct pt_regs *regs) -{ - int error, i, base = 0; - struct irix5_context __user *ctx; - unsigned long flags; - - if (regs->regs[2] == 1000) - base = 1; - ctx = (struct irix5_context __user *) regs->regs[base + 4]; - -#ifdef DEBUG_SIG - printk("[%s:%d] irix_getcontext(%p)\n", - current->comm, current->pid, ctx); -#endif - - if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) - return -EFAULT; - - error = __put_user(current->thread.irix_oldctx, &ctx->link); - - error |= __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0; - - /* XXX Do sigstack stuff someday... */ - error |= __put_user(0, &ctx->stack.sp); - error |= __put_user(0, &ctx->stack.size); - error |= __put_user(0, &ctx->stack.flags); - - error |= __put_user(0, &ctx->weird_graphics_thing); - error |= __put_user(0, &ctx->regs[0]); - for (i = 1; i < 32; i++) - error |= __put_user(regs->regs[i], &ctx->regs[i]); - error |= __put_user(regs->lo, &ctx->regs[32]); - error |= __put_user(regs->hi, &ctx->regs[33]); - error |= __put_user(regs->cp0_cause, &ctx->regs[34]); - error |= __put_user(regs->cp0_epc, &ctx->regs[35]); - - flags = 0x0f; - if (!used_math()) { - flags &= ~(0x08); - } else { - /* XXX wheee... */ - printk("Wheee, no code for saving IRIX FPU context yet.\n"); - } - error |= __put_user(flags, &ctx->flags); - - return error; -} - -asmlinkage void irix_setcontext(struct pt_regs *regs) -{ - struct irix5_context __user *ctx; - int err, base = 0; - u32 flags; - - if (regs->regs[2] == 1000) - base = 1; - ctx = (struct irix5_context __user *) regs->regs[base + 4]; - -#ifdef DEBUG_SIG - printk("[%s:%d] irix_setcontext(%p)\n", - current->comm, current->pid, ctx); -#endif - - if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) - goto segv_and_exit; - - err = __get_user(flags, &ctx->flags); - if (flags & 0x02) { - /* XXX sigstack garbage, todo... */ - printk("Wheee, cannot do sigstack stuff in setcontext\n"); - } - - if (flags & 0x04) { - int i; - - /* XXX extra control block stuff... todo... */ - for (i = 1; i < 32; i++) - err |= __get_user(regs->regs[i], &ctx->regs[i]); - err |= __get_user(regs->lo, &ctx->regs[32]); - err |= __get_user(regs->hi, &ctx->regs[33]); - err |= __get_user(regs->cp0_epc, &ctx->regs[35]); - } - - if (flags & 0x08) - /* XXX fpu context, blah... */ - printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n"); - - err |= __get_user(current->thread.irix_oldctx, &ctx->link); - if (err) - goto segv_and_exit; - - /* - * Don't let your children do this ... - */ - __asm__ __volatile__( - "move\t$29,%0\n\t" - "j\tsyscall_exit" - :/* no outputs */ - :"r" (®s)); - /* Unreached */ - -segv_and_exit: - force_sigsegv(SIGSEGV, current); -} - -struct irix_sigstack { - unsigned long sp; - int status; -}; - -asmlinkage int irix_sigstack(struct irix_sigstack __user *new, - struct irix_sigstack __user *old) -{ -#ifdef DEBUG_SIG - printk("[%s:%d] irix_sigstack(%p,%p)\n", - current->comm, current->pid, new, old); -#endif - if (new) { - if (!access_ok(VERIFY_READ, new, sizeof(*new))) - return -EFAULT; - } - - if (old) { - if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) - return -EFAULT; - } - - return 0; -} - -struct irix_sigaltstack { unsigned long sp; int size; int status; }; - -asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new, - struct irix_sigaltstack __user *old) -{ -#ifdef DEBUG_SIG - printk("[%s:%d] irix_sigaltstack(%p,%p)\n", - current->comm, current->pid, new, old); -#endif - if (new) - if (!access_ok(VERIFY_READ, new, sizeof(*new))) - return -EFAULT; - - if (old) { - if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) - return -EFAULT; - } - - return 0; -} - -struct irix_procset { - int cmd, ltype, lid, rtype, rid; -}; - -asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig) -{ - if (!access_ok(VERIFY_READ, pset, sizeof(*pset))) - return -EFAULT; -#ifdef DEBUG_SIG - printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n", - current->comm, current->pid, - pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid, - sig); -#endif - return -EINVAL; -} diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 2c09a44..c06f5b5 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -125,13 +125,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ -#if defined(CONFIG_BINFMT_IRIX) - if (current->personality != PER_LINUX) { - /* Under IRIX things are a little different. */ - childregs->regs[3] = 1; - regs->regs[3] = 0; - } -#endif childregs->regs[2] = 0; /* Child gets zero as return value */ regs->regs[2] = p->pid; diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 08a9c50..c058c0b 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -34,12 +34,8 @@ NESTED(handle_sys, PT_SIZE, sp) lw t1, PT_EPC(sp) # skip syscall on return -#if defined(CONFIG_BINFMT_IRIX) - sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number -#else subu v0, v0, __NR_O32_Linux # check syscall number sltiu t0, v0, __NR_O32_Linux_syscalls + 1 -#endif addiu t1, 4 # skip to next instruction sw t1, PT_EPC(sp) beqz t0, illegal_syscall @@ -264,22 +260,14 @@ bad_alignment: END(sys_sysmips) LEAF(sys_syscall) -#if defined(CONFIG_BINFMT_IRIX) - sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number -#else subu t0, a0, __NR_O32_Linux # check syscall number sltiu v0, t0, __NR_O32_Linux_syscalls + 1 -#endif sll t1, t0, 3 beqz v0, einval lw t2, sys_call_table(t1) # syscall routine -#if defined(CONFIG_BINFMT_IRIX) - li v1, 4000 # nr of sys_syscall -#else li v1, 4000 - __NR_O32_Linux # index of sys_syscall -#endif beq t0, v1, einval # do not recurse /* Some syscalls like execve get their arguments from struct pt_regs @@ -324,13 +312,6 @@ einval: li v0, -EINVAL .endm .macro syscalltable -#if defined(CONFIG_BINFMT_IRIX) - mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */ - mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */ - mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */ - mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */ -#endif - sys sys_syscall 8 /* 4000 */ sys sys_exit 1 sys sys_fork 0 diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c deleted file mode 100644 index c357762..0000000 --- a/arch/mips/kernel/sysirix.c +++ /dev/null @@ -1,2140 +0,0 @@ -/* - * sysirix.c: IRIX system call emulation. - * - * Copyright (C) 1996 David S. Miller - * Copyright (C) 1997 Miguel de Icaza - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* 2,191 lines of complete and utter shit coming up... */ - -extern int max_threads; - -/* The sysmp commands supported thus far. */ -#define MP_NPROCS 1 /* # processor in complex */ -#define MP_NAPROCS 2 /* # active processors in complex */ -#define MP_PGSIZE 14 /* Return system page size in v1. */ - -asmlinkage int irix_sysmp(struct pt_regs *regs) -{ - unsigned long cmd; - int base = 0; - int error = 0; - - if(regs->regs[2] == 1000) - base = 1; - cmd = regs->regs[base + 4]; - switch(cmd) { - case MP_PGSIZE: - error = PAGE_SIZE; - break; - case MP_NPROCS: - case MP_NAPROCS: - error = num_online_cpus(); - break; - default: - printk("SYSMP[%s:%d]: Unsupported opcode %d\n", - current->comm, current->pid, (int)cmd); - error = -EINVAL; - break; - } - - return error; -} - -/* The prctl commands. */ -#define PR_MAXPROCS 1 /* Tasks/user. */ -#define PR_ISBLOCKED 2 /* If blocked, return 1. */ -#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */ -#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */ -#define PR_MAXPPROCS 5 /* Num parallel tasks. */ -#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */ -#define PR_SETEXITSIG 8 /* When task exit's, set signal. */ -#define PR_RESIDENT 9 /* Make task unswappable. */ -#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */ -#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */ -#define PR_TERMCHILD 12 /* Kill child if the parent dies. */ -#define PR_GETSHMASK 13 /* Get the sproc() share mask. */ -#define PR_GETNSHARE 14 /* Number of share group members. */ -#define PR_COREPID 15 /* Add task pid to name when it core. */ -#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */ -#define PR_PTHREADEXIT 17 /* Kill a pthread, only for IRIX 6.[234] */ - -asmlinkage int irix_prctl(unsigned option, ...) -{ - va_list args; - int error = 0; - - va_start(args, option); - switch (option) { - case PR_MAXPROCS: - printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n", - current->comm, current->pid); - error = max_threads; - break; - - case PR_ISBLOCKED: { - struct task_struct *task; - - printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", - current->comm, current->pid); - read_lock(&tasklist_lock); - task = find_task_by_vpid(va_arg(args, pid_t)); - error = -ESRCH; - if (error) - error = (task->run_list.next != NULL); - read_unlock(&tasklist_lock); - /* Can _your_ OS find this out that fast? */ - break; - } - - case PR_SETSTACKSIZE: { - long value = va_arg(args, long); - - printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n", - current->comm, current->pid, (unsigned long) value); - if (value > RLIM_INFINITY) - value = RLIM_INFINITY; - if (capable(CAP_SYS_ADMIN)) { - task_lock(current->group_leader); - current->signal->rlim[RLIMIT_STACK].rlim_max = - current->signal->rlim[RLIMIT_STACK].rlim_cur = value; - task_unlock(current->group_leader); - error = value; - break; - } - task_lock(current->group_leader); - if (value > current->signal->rlim[RLIMIT_STACK].rlim_max) { - error = -EINVAL; - task_unlock(current->group_leader); - break; - } - current->signal->rlim[RLIMIT_STACK].rlim_cur = value; - task_unlock(current->group_leader); - error = value; - break; - } - - case PR_GETSTACKSIZE: - printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n", - current->comm, current->pid); - error = current->signal->rlim[RLIMIT_STACK].rlim_cur; - break; - - case PR_MAXPPROCS: - printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n", - current->comm, current->pid); - error = 1; - break; - - case PR_UNBLKONEXEC: - printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n", - current->comm, current->pid); - error = -EINVAL; - break; - - case PR_SETEXITSIG: - printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n", - current->comm, current->pid); - - /* We can probably play some game where we set the task - * exit_code to some non-zero value when this is requested, - * and check whether exit_code is already set in do_exit(). - */ - error = -EINVAL; - break; - - case PR_RESIDENT: - printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n", - current->comm, current->pid); - error = 0; /* Compatibility indeed. */ - break; - - case PR_ATTACHADDR: - printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n", - current->comm, current->pid); - error = -EINVAL; - break; - - case PR_DETACHADDR: - printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n", - current->comm, current->pid); - error = -EINVAL; - break; - - case PR_TERMCHILD: - printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n", - current->comm, current->pid); - error = -EINVAL; - break; - - case PR_GETSHMASK: - printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n", - current->comm, current->pid); - error = -EINVAL; /* Until I have the sproc() stuff in. */ - break; - - case PR_GETNSHARE: - error = 0; /* Until I have the sproc() stuff in. */ - break; - - case PR_COREPID: - printk("irix_prctl[%s:%d]: Wants PR_COREPID\n", - current->comm, current->pid); - error = -EINVAL; - break; - - case PR_ATTACHADDRPERM: - printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n", - current->comm, current->pid); - error = -EINVAL; - break; - - default: - printk("irix_prctl[%s:%d]: Non-existant opcode %d\n", - current->comm, current->pid, option); - error = -EINVAL; - break; - } - va_end(args); - - return error; -} - -#undef DEBUG_PROCGRPS - -extern unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt); -extern char *prom_getenv(char *name); -extern long prom_setenv(char *name, char *value); - -/* The syssgi commands supported thus far. */ -#define SGI_SYSID 1 /* Return unique per-machine identifier. */ -#define SGI_INVENT 5 /* Fetch inventory */ -# define SGI_INV_SIZEOF 1 -# define SGI_INV_READ 2 -#define SGI_RDNAME 6 /* Return string name of a process. */ -#define SGI_SETNVRAM 8 /* Set PROM variable. */ -#define SGI_GETNVRAM 9 /* Get PROM variable. */ -#define SGI_SETPGID 21 /* Set process group id. */ -#define SGI_SYSCONF 22 /* POSIX sysconf garbage. */ -#define SGI_PATHCONF 24 /* POSIX sysconf garbage. */ -#define SGI_SETGROUPS 40 /* POSIX sysconf garbage. */ -#define SGI_GETGROUPS 41 /* POSIX sysconf garbage. */ -#define SGI_RUSAGE 56 /* BSD style rusage(). */ -#define SGI_SSYNC 62 /* Synchronous fs sync. */ -#define SGI_GETSID 65 /* SysVr4 get session id. */ -#define SGI_ELFMAP 68 /* Map an elf image. */ -#define SGI_TOSSTSAVE 108 /* Toss saved vma's. */ -#define SGI_FP_BCOPY 129 /* Should FPU bcopy be used on this machine? */ -#define SGI_PHYSP 1011 /* Translate virtual into physical page. */ - -asmlinkage int irix_syssgi(struct pt_regs *regs) -{ - unsigned long cmd; - int retval, base = 0; - - if (regs->regs[2] == 1000) - base = 1; - - cmd = regs->regs[base + 4]; - switch(cmd) { - case SGI_SYSID: { - char __user *buf = (char __user *) regs->regs[base + 5]; - - /* XXX Use ethernet addr.... */ - retval = clear_user(buf, 64) ? -EFAULT : 0; - break; - } -#if 0 - case SGI_RDNAME: { - int pid = (int) regs->regs[base + 5]; - char __user *buf = (char __user *) regs->regs[base + 6]; - struct task_struct *p; - char tcomm[sizeof(current->comm)]; - - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (!p) { - read_unlock(&tasklist_lock); - retval = -ESRCH; - break; - } - get_task_comm(tcomm, p); - read_unlock(&tasklist_lock); - - /* XXX Need to check sizes. */ - retval = copy_to_user(buf, tcomm, sizeof(tcomm)) ? -EFAULT : 0; - break; - } - - case SGI_GETNVRAM: { - char __user *name = (char __user *) regs->regs[base+5]; - char __user *buf = (char __user *) regs->regs[base+6]; - char *value; - return -EINVAL; /* til I fix it */ - value = prom_getenv(name); /* PROM lock? */ - if (!value) { - retval = -EINVAL; - break; - } - /* Do I strlen() for the length? */ - retval = copy_to_user(buf, value, 128) ? -EFAULT : 0; - break; - } - - case SGI_SETNVRAM: { - char __user *name = (char __user *) regs->regs[base+5]; - char __user *value = (char __user *) regs->regs[base+6]; - return -EINVAL; /* til I fix it */ - retval = prom_setenv(name, value); - /* XXX make sure retval conforms to syssgi(2) */ - printk("[%s:%d] setnvram(\"%s\", \"%s\"): retval %d", - current->comm, current->pid, name, value, retval); -/* if (retval == PROM_ENOENT) - retval = -ENOENT; */ - break; - } -#endif - - case SGI_SETPGID: { -#ifdef DEBUG_PROCGRPS - printk("[%s:%d] setpgid(%d, %d) ", - current->comm, current->pid, - (int) regs->regs[base + 5], (int)regs->regs[base + 6]); -#endif - retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]); - -#ifdef DEBUG_PROCGRPS - printk("retval=%d\n", retval); -#endif - } - - case SGI_SYSCONF: { - switch(regs->regs[base + 5]) { - case 1: - retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */ - goto out; - case 2: - retval = max_threads; - goto out; - case 3: - retval = HZ; - goto out; - case 4: - retval = NGROUPS_MAX; - goto out; - case 5: - retval = sysctl_nr_open; - goto out; - case 6: - retval = 1; - goto out; - case 7: - retval = 1; - goto out; - case 8: - retval = 199009; - goto out; - case 11: - retval = PAGE_SIZE; - goto out; - case 12: - retval = 4; - goto out; - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - retval = 0; - goto out; - case 31: - retval = 32; - goto out; - default: - retval = -EINVAL; - goto out; - }; - } - - case SGI_SETGROUPS: - retval = sys_setgroups((int) regs->regs[base + 5], - (gid_t __user *) regs->regs[base + 6]); - break; - - case SGI_GETGROUPS: - retval = sys_getgroups((int) regs->regs[base + 5], - (gid_t __user *) regs->regs[base + 6]); - break; - - case SGI_RUSAGE: { - struct rusage __user *ru = (struct rusage __user *) regs->regs[base + 6]; - - switch((int) regs->regs[base + 5]) { - case 0: - /* rusage self */ - retval = getrusage(current, RUSAGE_SELF, ru); - goto out; - - case -1: - /* rusage children */ - retval = getrusage(current, RUSAGE_CHILDREN, ru); - goto out; - - default: - retval = -EINVAL; - goto out; - }; - } - - case SGI_SSYNC: - sys_sync(); - retval = 0; - break; - - case SGI_GETSID: -#ifdef DEBUG_PROCGRPS - printk("[%s:%d] getsid(%d) ", current->comm, current->pid, - (int) regs->regs[base + 5]); -#endif - retval = sys_getsid(regs->regs[base + 5]); -#ifdef DEBUG_PROCGRPS - printk("retval=%d\n", retval); -#endif - break; - - case SGI_ELFMAP: - retval = irix_mapelf((int) regs->regs[base + 5], - (struct elf_phdr __user *) regs->regs[base + 6], - (int) regs->regs[base + 7]); - break; - - case SGI_TOSSTSAVE: - /* XXX We don't need to do anything? */ - retval = 0; - break; - - case SGI_FP_BCOPY: - retval = 0; - break; - - case SGI_PHYSP: { - unsigned long addr = regs->regs[base + 5]; - int __user *pageno = (int __user *) (regs->regs[base + 6]); - struct mm_struct *mm = current->mm; - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - - down_read(&mm->mmap_sem); - pgdp = pgd_offset(mm, addr); - pudp = pud_offset(pgdp, addr); - pmdp = pmd_offset(pudp, addr); - ptep = pte_offset(pmdp, addr); - retval = -EINVAL; - if (ptep) { - pte_t pte = *ptep; - - if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) { - /* b0rked on 64-bit */ - retval = put_user((pte_val(pte) & PAGE_MASK) >> - PAGE_SHIFT, pageno); - } - } - up_read(&mm->mmap_sem); - break; - } - - case SGI_INVENT: { - int arg1 = (int) regs->regs [base + 5]; - void __user *buffer = (void __user *) regs->regs [base + 6]; - int count = (int) regs->regs [base + 7]; - - switch (arg1) { - case SGI_INV_SIZEOF: - retval = sizeof(inventory_t); - break; - case SGI_INV_READ: - retval = dump_inventory_to_user(buffer, count); - break; - default: - retval = -EINVAL; - } - break; - } - - default: - printk("irix_syssgi: Unsupported command %d\n", (int)cmd); - retval = -EINVAL; - break; - }; - -out: - return retval; -} - -asmlinkage int irix_gtime(struct pt_regs *regs) -{ - return get_seconds(); -} - -/* - * IRIX is completely broken... it returns 0 on success, otherwise - * ENOMEM. - */ -asmlinkage int irix_brk(unsigned long brk) -{ - unsigned long rlim; - unsigned long newbrk, oldbrk; - struct mm_struct *mm = current->mm; - int ret; - - down_write(&mm->mmap_sem); - if (brk < mm->end_code) { - ret = -ENOMEM; - goto out; - } - - newbrk = PAGE_ALIGN(brk); - oldbrk = PAGE_ALIGN(mm->brk); - if (oldbrk == newbrk) { - mm->brk = brk; - ret = 0; - goto out; - } - - /* - * Always allow shrinking brk - */ - if (brk <= mm->brk) { - mm->brk = brk; - do_munmap(mm, newbrk, oldbrk-newbrk); - ret = 0; - goto out; - } - /* - * Check against rlimit and stack.. - */ - rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; - if (rlim >= RLIM_INFINITY) - rlim = ~0; - if (brk - mm->end_code > rlim) { - ret = -ENOMEM; - goto out; - } - - /* - * Check against existing mmap mappings. - */ - if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) { - ret = -ENOMEM; - goto out; - } - - /* - * Ok, looks good - let it rip. - */ - if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) { - ret = -ENOMEM; - goto out; - } - mm->brk = brk; - ret = 0; - -out: - up_write(&mm->mmap_sem); - return ret; -} - -asmlinkage int irix_getpid(struct pt_regs *regs) -{ - regs->regs[3] = task_pid_vnr(current->real_parent); - return task_pid_vnr(current); -} - -asmlinkage int irix_getuid(struct pt_regs *regs) -{ - regs->regs[3] = current->euid; - return current->uid; -} - -asmlinkage int irix_getgid(struct pt_regs *regs) -{ - regs->regs[3] = current->egid; - return current->gid; -} - -asmlinkage int irix_stime(int value) -{ - int err; - struct timespec tv; - - tv.tv_sec = value; - tv.tv_nsec = 0; - err = security_settime(&tv, NULL); - if (err) - return err; - - write_seqlock_irq(&xtime_lock); - xtime.tv_sec = value; - xtime.tv_nsec = 0; - ntp_clear(); - write_sequnlock_irq(&xtime_lock); - - return 0; -} - -static inline void jiffiestotv(unsigned long jiffies, struct timeval *value) -{ - value->tv_usec = (jiffies % HZ) * (1000000 / HZ); - value->tv_sec = jiffies / HZ; -} - -static inline void getitimer_real(struct itimerval *value) -{ - register unsigned long val, interval; - - interval = current->it_real_incr; - val = 0; - if (del_timer(¤t->real_timer)) { - unsigned long now = jiffies; - val = current->real_timer.expires; - add_timer(¤t->real_timer); - /* look out for negative/zero itimer.. */ - if (val <= now) - val = now+1; - val -= now; - } - jiffiestotv(val, &value->it_value); - jiffiestotv(interval, &value->it_interval); -} - -asmlinkage unsigned int irix_alarm(unsigned int seconds) -{ - return alarm_setitimer(seconds); -} - -asmlinkage int irix_pause(void) -{ - current->state = TASK_INTERRUPTIBLE; - schedule(); - - return -EINTR; -} - -/* XXX need more than this... */ -asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name, - unsigned long flags, char __user *type, void __user *data, int datalen) -{ - printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n", - current->comm, current->pid, - dev_name, dir_name, flags, type, data, datalen); - - return sys_mount(dev_name, dir_name, type, flags, data); -} - -struct irix_statfs { - short f_type; - long f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree; - char f_fname[6], f_fpack[6]; -}; - -asmlinkage int irix_statfs(const char __user *path, - struct irix_statfs __user *buf, int len, int fs_type) -{ - struct nameidata nd; - struct kstatfs kbuf; - int error, i; - - /* We don't support this feature yet. */ - if (fs_type) { - error = -EINVAL; - goto out; - } - if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) { - error = -EFAULT; - goto out; - } - - error = user_path_walk(path, &nd); - if (error) - goto out; - - error = vfs_statfs(nd.path.dentry, &kbuf); - if (error) - goto dput_and_out; - - error = __put_user(kbuf.f_type, &buf->f_type); - error |= __put_user(kbuf.f_bsize, &buf->f_bsize); - error |= __put_user(kbuf.f_frsize, &buf->f_frsize); - error |= __put_user(kbuf.f_blocks, &buf->f_blocks); - error |= __put_user(kbuf.f_bfree, &buf->f_bfree); - error |= __put_user(kbuf.f_files, &buf->f_files); - error |= __put_user(kbuf.f_ffree, &buf->f_ffree); - for (i = 0; i < 6; i++) { - error |= __put_user(0, &buf->f_fname[i]); - error |= __put_user(0, &buf->f_fpack[i]); - } - -dput_and_out: - path_put(&nd.path); -out: - return error; -} - -asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf) -{ - struct kstatfs kbuf; - struct file *file; - int error, i; - - if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) { - error = -EFAULT; - goto out; - } - - if (!(file = fget(fd))) { - error = -EBADF; - goto out; - } - - error = vfs_statfs(file->f_path.dentry, &kbuf); - if (error) - goto out_f; - - error = __put_user(kbuf.f_type, &buf->f_type); - error |= __put_user(kbuf.f_bsize, &buf->f_bsize); - error |= __put_user(kbuf.f_frsize, &buf->f_frsize); - error |= __put_user(kbuf.f_blocks, &buf->f_blocks); - error |= __put_user(kbuf.f_bfree, &buf->f_bfree); - error |= __put_user(kbuf.f_files, &buf->f_files); - error |= __put_user(kbuf.f_ffree, &buf->f_ffree); - - for (i = 0; i < 6; i++) { - error |= __put_user(0, &buf->f_fname[i]); - error |= __put_user(0, &buf->f_fpack[i]); - } - -out_f: - fput(file); -out: - return error; -} - -asmlinkage int irix_setpgrp(int flags) -{ - int error; - -#ifdef DEBUG_PROCGRPS - printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags); -#endif - if(!flags) - error = task_pgrp_vnr(current); - else - error = sys_setsid(); -#ifdef DEBUG_PROCGRPS - printk("returning %d\n", error); -#endif - - return error; -} - -asmlinkage int irix_times(struct tms __user *tbuf) -{ - int err = 0; - - if (tbuf) { - if (!access_ok(VERIFY_WRITE, tbuf, sizeof *tbuf)) - return -EFAULT; - - err = __put_user(current->utime, &tbuf->tms_utime); - err |= __put_user(current->stime, &tbuf->tms_stime); - err |= __put_user(current->signal->cutime, &tbuf->tms_cutime); - err |= __put_user(current->signal->cstime, &tbuf->tms_cstime); - } - - return err; -} - -asmlinkage int irix_exec(struct pt_regs *regs) -{ - int error, base = 0; - char *filename; - - if(regs->regs[2] == 1000) - base = 1; - filename = getname((char __user *) (long)regs->regs[base + 4]); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - return error; - - error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5], - NULL, regs); - putname(filename); - - return error; -} - -asmlinkage int irix_exece(struct pt_regs *regs) -{ - int error, base = 0; - char *filename; - - if (regs->regs[2] == 1000) - base = 1; - filename = getname((char __user *) (long)regs->regs[base + 4]); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - return error; - error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5], - (char __user * __user *) (long)regs->regs[base + 6], regs); - putname(filename); - - return error; -} - -asmlinkage unsigned long irix_gethostid(void) -{ - printk("[%s:%d]: irix_gethostid() called...\n", - current->comm, current->pid); - - return -EINVAL; -} - -asmlinkage unsigned long irix_sethostid(unsigned long val) -{ - printk("[%s:%d]: irix_sethostid(%08lx) called...\n", - current->comm, current->pid, val); - - return -EINVAL; -} - -asmlinkage int irix_socket(int family, int type, int protocol) -{ - switch(type) { - case 1: - type = SOCK_DGRAM; - break; - - case 2: - type = SOCK_STREAM; - break; - - case 3: - type = 9; /* Invalid... */ - break; - - case 4: - type = SOCK_RAW; - break; - - case 5: - type = SOCK_RDM; - break; - - case 6: - type = SOCK_SEQPACKET; - break; - - default: - break; - } - - return sys_socket(family, type, protocol); -} - -asmlinkage int irix_getdomainname(char __user *name, int len) -{ - int err; - - down_read(&uts_sem); - if (len > __NEW_UTS_LEN) - len = __NEW_UTS_LEN; - err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0; - up_read(&uts_sem); - - return err; -} - -asmlinkage unsigned long irix_getpagesize(void) -{ - return PAGE_SIZE; -} - -asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1, - unsigned long arg2, unsigned long arg3, - unsigned long arg4) -{ - switch (opcode) { - case 0: - return sys_msgget((key_t) arg0, (int) arg1); - case 1: - return sys_msgctl((int) arg0, (int) arg1, - (struct msqid_ds __user *)arg2); - case 2: - return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1, - (size_t) arg2, (long) arg3, (int) arg4); - case 3: - return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1, - (size_t) arg2, (int) arg3); - default: - return -EINVAL; - } -} - -asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1, - unsigned long arg2, unsigned long arg3) -{ - switch (opcode) { - case 0: - return do_shmat((int) arg0, (char __user *) arg1, (int) arg2, - (unsigned long *) arg3); - case 1: - return sys_shmctl((int)arg0, (int)arg1, - (struct shmid_ds __user *)arg2); - case 2: - return sys_shmdt((char __user *)arg0); - case 3: - return sys_shmget((key_t) arg0, (int) arg1, (int) arg2); - default: - return -EINVAL; - } -} - -asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1, - unsigned long arg2, int arg3) -{ - switch (opcode) { - case 0: - return sys_semctl((int) arg0, (int) arg1, (int) arg2, - (union semun) arg3); - case 1: - return sys_semget((key_t) arg0, (int) arg1, (int) arg2); - case 2: - return sys_semop((int) arg0, (struct sembuf __user *)arg1, - (unsigned int) arg2); - default: - return -EINVAL; - } -} - -static inline loff_t llseek(struct file *file, loff_t offset, int origin) -{ - loff_t (*fn)(struct file *, loff_t, int); - loff_t retval; - - fn = default_llseek; - if (file->f_op && file->f_op->llseek) - fn = file->f_op->llseek; - lock_kernel(); - retval = fn(file, offset, origin); - unlock_kernel(); - - return retval; -} - -asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow, - int origin) -{ - struct file * file; - loff_t offset; - int retval; - - retval = -EBADF; - file = fget(fd); - if (!file) - goto bad; - retval = -EINVAL; - if (origin > 2) - goto out_putf; - - offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin); - retval = (int) offset; - -out_putf: - fput(file); -bad: - return retval; -} - -asmlinkage int irix_sginap(int ticks) -{ - schedule_timeout_interruptible(ticks); - return 0; -} - -asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len) -{ - return -EINVAL; -} - -asmlinkage int irix_gettimeofday(struct timeval __user *tv) -{ - time_t sec; - long nsec, seq; - int err; - - if (!access_ok(VERIFY_WRITE, tv, sizeof(struct timeval))) - return -EFAULT; - - do { - seq = read_seqbegin(&xtime_lock); - sec = xtime.tv_sec; - nsec = xtime.tv_nsec; - } while (read_seqretry(&xtime_lock, seq)); - - err = __put_user(sec, &tv->tv_sec); - err |= __put_user((nsec / 1000), &tv->tv_usec); - - return err; -} - -#define IRIX_MAP_AUTOGROW 0x40 - -asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, - int flags, int fd, off_t offset) -{ - struct file *file = NULL; - unsigned long retval; - - if (!(flags & MAP_ANONYMOUS)) { - if (!(file = fget(fd))) - return -EBADF; - - /* Ok, bad taste hack follows, try to think in something else - * when reading this. */ - if (flags & IRIX_MAP_AUTOGROW) { - unsigned long old_pos; - long max_size = offset + len; - - if (max_size > file->f_path.dentry->d_inode->i_size) { - old_pos = sys_lseek(fd, max_size - 1, 0); - sys_write(fd, (void __user *) "", 1); - sys_lseek(fd, old_pos, 0); - } - } - } - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - - down_write(¤t->mm->mmap_sem); - retval = do_mmap(file, addr, len, prot, flags, offset); - up_write(¤t->mm->mmap_sem); - if (file) - fput(file); - - return retval; -} - -asmlinkage int irix_madvise(unsigned long addr, int len, int behavior) -{ - printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n", - current->comm, current->pid, addr, len, behavior); - - return -EINVAL; -} - -asmlinkage int irix_pagelock(char __user *addr, int len, int op) -{ - printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n", - current->comm, current->pid, addr, len, op); - - return -EINVAL; -} - -asmlinkage int irix_quotactl(struct pt_regs *regs) -{ - printk("[%s:%d] Wheee.. irix_quotactl()\n", - current->comm, current->pid); - - return -EINVAL; -} - -asmlinkage int irix_BSDsetpgrp(int pid, int pgrp) -{ - int error; - -#ifdef DEBUG_PROCGRPS - printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid, - pid, pgrp); -#endif - if(!pid) - pid = task_pid_vnr(current); - - /* Wheee, weird sysv thing... */ - if ((pgrp == 0) && (pid == task_pid_vnr(current))) - error = sys_setsid(); - else - error = sys_setpgid(pid, pgrp); - -#ifdef DEBUG_PROCGRPS - printk("error = %d\n", error); -#endif - - return error; -} - -asmlinkage int irix_systeminfo(int cmd, char __user *buf, int cnt) -{ - printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n", - current->comm, current->pid, cmd, buf, cnt); - - return -EINVAL; -} - -struct iuname { - char sysname[257], nodename[257], release[257]; - char version[257], machine[257]; - char m_type[257], base_rel[257]; - char _unused0[257], _unused1[257], _unused2[257]; - char _unused3[257], _unused4[257], _unused5[257]; -}; - -asmlinkage int irix_uname(struct iuname __user *buf) -{ - down_read(&uts_sem); - if (copy_from_user(utsname()->sysname, buf->sysname, 65) - || copy_from_user(utsname()->nodename, buf->nodename, 65) - || copy_from_user(utsname()->release, buf->release, 65) - || copy_from_user(utsname()->version, buf->version, 65) - || copy_from_user(utsname()->machine, buf->machine, 65)) { - return -EFAULT; - } - up_read(&uts_sem); - - return 1; -} - -#undef DEBUG_XSTAT - -static int irix_xstat32_xlate(struct kstat *stat, void __user *ubuf) -{ - struct xstat32 { - u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid; - u32 st_rdev, st_pad2[2], st_size, st_pad3; - u32 st_atime0, st_atime1; - u32 st_mtime0, st_mtime1; - u32 st_ctime0, st_ctime1; - u32 st_blksize, st_blocks; - char st_fstype[16]; - u32 st_pad4[8]; - } ub; - - if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev)) - return -EOVERFLOW; - ub.st_dev = sysv_encode_dev(stat->dev); - ub.st_ino = stat->ino; - ub.st_mode = stat->mode; - ub.st_nlink = stat->nlink; - SET_UID(ub.st_uid, stat->uid); - SET_GID(ub.st_gid, stat->gid); - ub.st_rdev = sysv_encode_dev(stat->rdev); -#if BITS_PER_LONG == 32 - if (stat->size > MAX_NON_LFS) - return -EOVERFLOW; -#endif - ub.st_size = stat->size; - ub.st_atime0 = stat->atime.tv_sec; - ub.st_atime1 = stat->atime.tv_nsec; - ub.st_mtime0 = stat->mtime.tv_sec; - ub.st_mtime1 = stat->atime.tv_nsec; - ub.st_ctime0 = stat->ctime.tv_sec; - ub.st_ctime1 = stat->atime.tv_nsec; - ub.st_blksize = stat->blksize; - ub.st_blocks = stat->blocks; - strcpy(ub.st_fstype, "efs"); - - return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0; -} - -static int irix_xstat64_xlate(struct kstat *stat, void __user *ubuf) -{ - struct xstat64 { - u32 st_dev; s32 st_pad1[3]; - unsigned long long st_ino; - u32 st_mode; - u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev; - s32 st_pad2[2]; - long long st_size; - s32 st_pad3; - struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime; - s32 st_blksize; - long long st_blocks; - char st_fstype[16]; - s32 st_pad4[8]; - } ks; - - if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev)) - return -EOVERFLOW; - - ks.st_dev = sysv_encode_dev(stat->dev); - ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0; - ks.st_ino = (unsigned long long) stat->ino; - ks.st_mode = (u32) stat->mode; - ks.st_nlink = (u32) stat->nlink; - ks.st_uid = (s32) stat->uid; - ks.st_gid = (s32) stat->gid; - ks.st_rdev = sysv_encode_dev(stat->rdev); - ks.st_pad2[0] = ks.st_pad2[1] = 0; - ks.st_size = (long long) stat->size; - ks.st_pad3 = 0; - - /* XXX hackety hack... */ - ks.st_atime.tv_sec = (s32) stat->atime.tv_sec; - ks.st_atime.tv_nsec = stat->atime.tv_nsec; - ks.st_mtime.tv_sec = (s32) stat->mtime.tv_sec; - ks.st_mtime.tv_nsec = stat->mtime.tv_nsec; - ks.st_ctime.tv_sec = (s32) stat->ctime.tv_sec; - ks.st_ctime.tv_nsec = stat->ctime.tv_nsec; - - ks.st_blksize = (s32) stat->blksize; - ks.st_blocks = (long long) stat->blocks; - memset(ks.st_fstype, 0, 16); - ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0; - ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0; - - /* Now write it all back. */ - return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0; -} - -asmlinkage int irix_xstat(int version, char __user *filename, struct stat __user *statbuf) -{ - int retval; - struct kstat stat; - -#ifdef DEBUG_XSTAT - printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ", - current->comm, current->pid, version, filename, statbuf); -#endif - - retval = vfs_stat(filename, &stat); - if (!retval) { - switch(version) { - case 2: - retval = irix_xstat32_xlate(&stat, statbuf); - break; - case 3: - retval = irix_xstat64_xlate(&stat, statbuf); - break; - default: - retval = -EINVAL; - } - } - return retval; -} - -asmlinkage int irix_lxstat(int version, char __user *filename, struct stat __user *statbuf) -{ - int error; - struct kstat stat; - -#ifdef DEBUG_XSTAT - printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ", - current->comm, current->pid, version, filename, statbuf); -#endif - - error = vfs_lstat(filename, &stat); - - if (!error) { - switch (version) { - case 2: - error = irix_xstat32_xlate(&stat, statbuf); - break; - case 3: - error = irix_xstat64_xlate(&stat, statbuf); - break; - default: - error = -EINVAL; - } - } - return error; -} - -asmlinkage int irix_fxstat(int version, int fd, struct stat __user *statbuf) -{ - int error; - struct kstat stat; - -#ifdef DEBUG_XSTAT - printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ", - current->comm, current->pid, version, fd, statbuf); -#endif - - error = vfs_fstat(fd, &stat); - if (!error) { - switch (version) { - case 2: - error = irix_xstat32_xlate(&stat, statbuf); - break; - case 3: - error = irix_xstat64_xlate(&stat, statbuf); - break; - default: - error = -EINVAL; - } - } - return error; -} - -asmlinkage int irix_xmknod(int ver, char __user *filename, int mode, unsigned dev) -{ - int retval; - printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n", - current->comm, current->pid, ver, filename, mode, dev); - - switch(ver) { - case 2: - /* shouldn't we convert here as well as on stat()? */ - retval = sys_mknod(filename, mode, dev); - break; - - default: - retval = -EINVAL; - break; - }; - - return retval; -} - -asmlinkage int irix_swapctl(int cmd, char __user *arg) -{ - printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n", - current->comm, current->pid, cmd, arg); - - return -EINVAL; -} - -struct irix_statvfs { - u32 f_bsize; u32 f_frsize; u32 f_blocks; - u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail; - u32 f_fsid; char f_basetype[16]; - u32 f_flag; u32 f_namemax; - char f_fstr[32]; u32 f_filler[16]; -}; - -asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf) -{ - struct nameidata nd; - struct kstatfs kbuf; - int error, i; - - printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n", - current->comm, current->pid, fname, buf); - if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) - return -EFAULT; - - error = user_path_walk(fname, &nd); - if (error) - goto out; - error = vfs_statfs(nd.path.dentry, &kbuf); - if (error) - goto dput_and_out; - - error |= __put_user(kbuf.f_bsize, &buf->f_bsize); - error |= __put_user(kbuf.f_frsize, &buf->f_frsize); - error |= __put_user(kbuf.f_blocks, &buf->f_blocks); - error |= __put_user(kbuf.f_bfree, &buf->f_bfree); - error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */ - error |= __put_user(kbuf.f_files, &buf->f_files); - error |= __put_user(kbuf.f_ffree, &buf->f_ffree); - error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */ -#ifdef __MIPSEB__ - error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); -#else - error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); -#endif - for (i = 0; i < 16; i++) - error |= __put_user(0, &buf->f_basetype[i]); - error |= __put_user(0, &buf->f_flag); - error |= __put_user(kbuf.f_namelen, &buf->f_namemax); - for (i = 0; i < 32; i++) - error |= __put_user(0, &buf->f_fstr[i]); - -dput_and_out: - path_put(&nd.path); -out: - return error; -} - -asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf) -{ - struct kstatfs kbuf; - struct file *file; - int error, i; - - printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n", - current->comm, current->pid, fd, buf); - - if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) - return -EFAULT; - - if (!(file = fget(fd))) { - error = -EBADF; - goto out; - } - error = vfs_statfs(file->f_path.dentry, &kbuf); - if (error) - goto out_f; - - error = __put_user(kbuf.f_bsize, &buf->f_bsize); - error |= __put_user(kbuf.f_frsize, &buf->f_frsize); - error |= __put_user(kbuf.f_blocks, &buf->f_blocks); - error |= __put_user(kbuf.f_bfree, &buf->f_bfree); - error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */ - error |= __put_user(kbuf.f_files, &buf->f_files); - error |= __put_user(kbuf.f_ffree, &buf->f_ffree); - error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */ -#ifdef __MIPSEB__ - error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); -#else - error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); -#endif - for(i = 0; i < 16; i++) - error |= __put_user(0, &buf->f_basetype[i]); - error |= __put_user(0, &buf->f_flag); - error |= __put_user(kbuf.f_namelen, &buf->f_namemax); - error |= __clear_user(&buf->f_fstr, sizeof(buf->f_fstr)) ? -EFAULT : 0; - -out_f: - fput(file); -out: - return error; -} - -asmlinkage int irix_priocntl(struct pt_regs *regs) -{ - printk("[%s:%d] Wheee.. irix_priocntl()\n", - current->comm, current->pid); - - return -EINVAL; -} - -asmlinkage int irix_sigqueue(int pid, int sig, int code, int val) -{ - printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n", - current->comm, current->pid, pid, sig, code, val); - - return -EINVAL; -} - -asmlinkage int irix_truncate64(char __user *name, int pad, int size1, int size2) -{ - int retval; - - if (size1) { - retval = -EINVAL; - goto out; - } - retval = sys_truncate(name, size2); - -out: - return retval; -} - -asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2) -{ - int retval; - - if (size1) { - retval = -EINVAL; - goto out; - } - retval = sys_ftruncate(fd, size2); - -out: - return retval; -} - -asmlinkage int irix_mmap64(struct pt_regs *regs) -{ - int len, prot, flags, fd, off1, off2, error, base = 0; - unsigned long addr, pgoff, *sp; - struct file *file = NULL; - int err; - - if (regs->regs[2] == 1000) - base = 1; - sp = (unsigned long *) (regs->regs[29] + 16); - addr = regs->regs[base + 4]; - len = regs->regs[base + 5]; - prot = regs->regs[base + 6]; - if (!base) { - flags = regs->regs[base + 7]; - if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) - return -EFAULT; - fd = sp[0]; - err = __get_user(off1, &sp[1]); - err |= __get_user(off2, &sp[2]); - } else { - if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) - return -EFAULT; - err = __get_user(flags, &sp[0]); - err |= __get_user(fd, &sp[1]); - err |= __get_user(off1, &sp[2]); - err |= __get_user(off2, &sp[3]); - } - - if (err) - return err; - - if (off1 & PAGE_MASK) - return -EOVERFLOW; - - pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT); - - if (!(flags & MAP_ANONYMOUS)) { - if (!(file = fget(fd))) - return -EBADF; - - /* Ok, bad taste hack follows, try to think in something else - when reading this */ - if (flags & IRIX_MAP_AUTOGROW) { - unsigned long old_pos; - long max_size = off2 + len; - - if (max_size > file->f_path.dentry->d_inode->i_size) { - old_pos = sys_lseek(fd, max_size - 1, 0); - sys_write(fd, (void __user *) "", 1); - sys_lseek(fd, old_pos, 0); - } - } - } - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - - down_write(¤t->mm->mmap_sem); - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) - fput(file); - - return error; -} - -asmlinkage int irix_dmi(struct pt_regs *regs) -{ - printk("[%s:%d] Wheee.. irix_dmi()\n", - current->comm, current->pid); - - return -EINVAL; -} - -asmlinkage int irix_pread(int fd, char __user *buf, int cnt, int off64, - int off1, int off2) -{ - printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n", - current->comm, current->pid, fd, buf, cnt, off64, off1, off2); - - return -EINVAL; -} - -asmlinkage int irix_pwrite(int fd, char __user *buf, int cnt, int off64, - int off1, int off2) -{ - printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n", - current->comm, current->pid, fd, buf, cnt, off64, off1, off2); - - return -EINVAL; -} - -asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1, - unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) -{ - printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx," - "%08lx,%08lx)\n", - current->comm, current->pid, cmd, arg0, arg1, arg2, - arg3, arg4, arg5); - - return -EINVAL; -} - -struct irix_statvfs64 { - u32 f_bsize; u32 f_frsize; - u64 f_blocks; u64 f_bfree; u64 f_bavail; - u64 f_files; u64 f_ffree; u64 f_favail; - u32 f_fsid; - char f_basetype[16]; - u32 f_flag; u32 f_namemax; - char f_fstr[32]; - u32 f_filler[16]; -}; - -asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user *buf) -{ - struct nameidata nd; - struct kstatfs kbuf; - int error, i; - - printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n", - current->comm, current->pid, fname, buf); - if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64))) { - error = -EFAULT; - goto out; - } - - error = user_path_walk(fname, &nd); - if (error) - goto out; - error = vfs_statfs(nd.path.dentry, &kbuf); - if (error) - goto dput_and_out; - - error = __put_user(kbuf.f_bsize, &buf->f_bsize); - error |= __put_user(kbuf.f_frsize, &buf->f_frsize); - error |= __put_user(kbuf.f_blocks, &buf->f_blocks); - error |= __put_user(kbuf.f_bfree, &buf->f_bfree); - error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */ - error |= __put_user(kbuf.f_files, &buf->f_files); - error |= __put_user(kbuf.f_ffree, &buf->f_ffree); - error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */ -#ifdef __MIPSEB__ - error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); -#else - error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); -#endif - for(i = 0; i < 16; i++) - error |= __put_user(0, &buf->f_basetype[i]); - error |= __put_user(0, &buf->f_flag); - error |= __put_user(kbuf.f_namelen, &buf->f_namemax); - for(i = 0; i < 32; i++) - error |= __put_user(0, &buf->f_fstr[i]); - -dput_and_out: - path_put(&nd.path); -out: - return error; -} - -asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf) -{ - struct kstatfs kbuf; - struct file *file; - int error, i; - - printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n", - current->comm, current->pid, fd, buf); - - if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) { - error = -EFAULT; - goto out; - } - if (!(file = fget(fd))) { - error = -EBADF; - goto out; - } - error = vfs_statfs(file->f_path.dentry, &kbuf); - if (error) - goto out_f; - - error = __put_user(kbuf.f_bsize, &buf->f_bsize); - error |= __put_user(kbuf.f_frsize, &buf->f_frsize); - error |= __put_user(kbuf.f_blocks, &buf->f_blocks); - error |= __put_user(kbuf.f_bfree, &buf->f_bfree); - error |= __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */ - error |= __put_user(kbuf.f_files, &buf->f_files); - error |= __put_user(kbuf.f_ffree, &buf->f_ffree); - error |= __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */ -#ifdef __MIPSEB__ - error |= __put_user(kbuf.f_fsid.val[1], &buf->f_fsid); -#else - error |= __put_user(kbuf.f_fsid.val[0], &buf->f_fsid); -#endif - for(i = 0; i < 16; i++) - error |= __put_user(0, &buf->f_basetype[i]); - error |= __put_user(0, &buf->f_flag); - error |= __put_user(kbuf.f_namelen, &buf->f_namemax); - error |= __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i])) ? -EFAULT : 0; - -out_f: - fput(file); -out: - return error; -} - -asmlinkage int irix_getmountid(char __user *fname, unsigned long __user *midbuf) -{ - int err; - - printk("[%s:%d] irix_getmountid(%s, %p)\n", - current->comm, current->pid, fname, midbuf); - if (!access_ok(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4))) - return -EFAULT; - - /* - * The idea with this system call is that when trying to determine - * 'pwd' and it's a toss-up for some reason, userland can use the - * fsid of the filesystem to try and make the right decision, but - * we don't have this so for now. XXX - */ - err = __put_user(0, &midbuf[0]); - err |= __put_user(0, &midbuf[1]); - err |= __put_user(0, &midbuf[2]); - err |= __put_user(0, &midbuf[3]); - - return err; -} - -asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask, - unsigned long arg, unsigned long sp, int slen) -{ - printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n", - current->comm, current->pid, entry, mask, arg, sp, slen); - - return -EINVAL; -} - -#undef DEBUG_GETDENTS - -struct irix_dirent32 { - u32 d_ino; - u32 d_off; - unsigned short d_reclen; - char d_name[1]; -}; - -struct irix_dirent32_callback { - struct irix_dirent32 __user *current_dir; - struct irix_dirent32 __user *previous; - int count; - int error; -}; - -#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de))) -#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) - -static int irix_filldir32(void *__buf, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int d_type) -{ - struct irix_dirent32 __user *dirent; - struct irix_dirent32_callback *buf = __buf; - unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); - int err = 0; - u32 d_ino; - -#ifdef DEBUG_GETDENTS - printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", - reclen, namlen, buf->count); -#endif - buf->error = -EINVAL; /* only used if we fail.. */ - if (reclen > buf->count) - return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; - dirent = buf->previous; - if (dirent) - err = __put_user(offset, &dirent->d_off); - dirent = buf->current_dir; - err |= __put_user(dirent, &buf->previous); - err |= __put_user(d_ino, &dirent->d_ino); - err |= __put_user(reclen, &dirent->d_reclen); - err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; - err |= __put_user(0, &dirent->d_name[namlen]); - dirent = (struct irix_dirent32 __user *) ((char __user *) dirent + reclen); - - buf->current_dir = dirent; - buf->count -= reclen; - - return err; -} - -asmlinkage int irix_ngetdents(unsigned int fd, void __user * dirent, - unsigned int count, int __user *eob) -{ - struct file *file; - struct irix_dirent32 __user *lastdirent; - struct irix_dirent32_callback buf; - int error; - -#ifdef DEBUG_GETDENTS - printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm, - current->pid, fd, dirent, count, eob); -#endif - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - - buf.current_dir = (struct irix_dirent32 __user *) dirent; - buf.previous = NULL; - buf.count = count; - buf.error = 0; - - error = vfs_readdir(file, irix_filldir32, &buf); - if (error < 0) - goto out_putf; - - error = buf.error; - lastdirent = buf.previous; - if (lastdirent) { - put_user(file->f_pos, &lastdirent->d_off); - error = count - buf.count; - } - - if (put_user(0, eob) < 0) { - error = -EFAULT; - goto out_putf; - } - -#ifdef DEBUG_GETDENTS - printk("eob=%d returning %d\n", *eob, count - buf.count); -#endif - error = count - buf.count; - -out_putf: - fput(file); -out: - return error; -} - -struct irix_dirent64 { - u64 d_ino; - u64 d_off; - unsigned short d_reclen; - char d_name[1]; -}; - -struct irix_dirent64_callback { - struct irix_dirent64 __user *curr; - struct irix_dirent64 __user *previous; - int count; - int error; -}; - -#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de))) -#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) - -static int irix_filldir64(void *__buf, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int d_type) -{ - struct irix_dirent64 __user *dirent; - struct irix_dirent64_callback * buf = __buf; - unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1); - int err = 0; - - if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))) - return -EFAULT; - - if (__put_user(-EINVAL, &buf->error)) /* only used if we fail.. */ - return -EFAULT; - if (reclen > buf->count) - return -EINVAL; - dirent = buf->previous; - if (dirent) - err = __put_user(offset, &dirent->d_off); - dirent = buf->curr; - buf->previous = dirent; - err |= __put_user(ino, &dirent->d_ino); - err |= __put_user(reclen, &dirent->d_reclen); - err |= __copy_to_user((char __user *)dirent->d_name, name, namlen) - ? -EFAULT : 0; - err |= __put_user(0, &dirent->d_name[namlen]); - - dirent = (struct irix_dirent64 __user *) ((char __user *) dirent + reclen); - - buf->curr = dirent; - buf->count -= reclen; - - return err; -} - -asmlinkage int irix_getdents64(int fd, void __user *dirent, int cnt) -{ - struct file *file; - struct irix_dirent64 __user *lastdirent; - struct irix_dirent64_callback buf; - int error; - -#ifdef DEBUG_GETDENTS - printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm, - current->pid, fd, dirent, cnt); -#endif - error = -EBADF; - if (!(file = fget(fd))) - goto out; - - error = -EFAULT; - if (!access_ok(VERIFY_WRITE, dirent, cnt)) - goto out_f; - - error = -EINVAL; - if (cnt < (sizeof(struct irix_dirent64) + 255)) - goto out_f; - - buf.curr = (struct irix_dirent64 __user *) dirent; - buf.previous = NULL; - buf.count = cnt; - buf.error = 0; - error = vfs_readdir(file, irix_filldir64, &buf); - if (error < 0) - goto out_f; - lastdirent = buf.previous; - if (!lastdirent) { - error = buf.error; - goto out_f; - } - if (put_user(file->f_pos, &lastdirent->d_off)) - return -EFAULT; -#ifdef DEBUG_GETDENTS - printk("returning %d\n", cnt - buf.count); -#endif - error = cnt - buf.count; - -out_f: - fput(file); -out: - return error; -} - -asmlinkage int irix_ngetdents64(int fd, void __user *dirent, int cnt, int *eob) -{ - struct file *file; - struct irix_dirent64 __user *lastdirent; - struct irix_dirent64_callback buf; - int error; - -#ifdef DEBUG_GETDENTS - printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm, - current->pid, fd, dirent, cnt); -#endif - error = -EBADF; - if (!(file = fget(fd))) - goto out; - - error = -EFAULT; - if (!access_ok(VERIFY_WRITE, dirent, cnt) || - !access_ok(VERIFY_WRITE, eob, sizeof(*eob))) - goto out_f; - - error = -EINVAL; - if (cnt < (sizeof(struct irix_dirent64) + 255)) - goto out_f; - - *eob = 0; - buf.curr = (struct irix_dirent64 __user *) dirent; - buf.previous = NULL; - buf.count = cnt; - buf.error = 0; - error = vfs_readdir(file, irix_filldir64, &buf); - if (error < 0) - goto out_f; - lastdirent = buf.previous; - if (!lastdirent) { - error = buf.error; - goto out_f; - } - if (put_user(file->f_pos, &lastdirent->d_off)) - return -EFAULT; -#ifdef DEBUG_GETDENTS - printk("eob=%d returning %d\n", *eob, cnt - buf.count); -#endif - error = cnt - buf.count; - -out_f: - fput(file); -out: - return error; -} - -asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg) -{ - int retval; - - switch (op) { - case 1: - /* Reboot */ - printk("[%s:%d] irix_uadmin: Wants to reboot...\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 2: - /* Shutdown */ - printk("[%s:%d] irix_uadmin: Wants to shutdown...\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 4: - /* Remount-root */ - printk("[%s:%d] irix_uadmin: Wants to remount root...\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 8: - /* Kill all tasks. */ - printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 256: - /* Set magic mushrooms... */ - printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n", - current->comm, current->pid, (int) func); - retval = -EINVAL; - goto out; - - default: - printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n", - current->comm, current->pid, (int) op); - retval = -EINVAL; - goto out; - }; - -out: - return retval; -} - -asmlinkage int irix_utssys(char __user *inbuf, int arg, int type, char __user *outbuf) -{ - int retval; - - switch(type) { - case 0: - /* uname() */ - retval = irix_uname((struct iuname __user *)inbuf); - goto out; - - case 2: - /* ustat() */ - printk("[%s:%d] irix_utssys: Wants to do ustat()\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 3: - /* fusers() */ - printk("[%s:%d] irix_utssys: Wants to do fusers()\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - default: - printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n", - current->comm, current->pid, (int) type); - retval = -EINVAL; - goto out; - } - -out: - return retval; -} - -#undef DEBUG_FCNTL - -#define IRIX_F_ALLOCSP 10 - -asmlinkage int irix_fcntl(int fd, int cmd, int arg) -{ - int retval; - -#ifdef DEBUG_FCNTL - printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm, - current->pid, fd, cmd, arg); -#endif - if (cmd == IRIX_F_ALLOCSP){ - return 0; - } - retval = sys_fcntl(fd, cmd, arg); -#ifdef DEBUG_FCNTL - printk("%d\n", retval); -#endif - return retval; -} - -asmlinkage int irix_ulimit(int cmd, int arg) -{ - int retval; - - switch(cmd) { - case 1: - printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 2: - printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 3: - printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - case 4: -#if 0 - printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; -#endif - retval = current->signal->rlim[RLIMIT_NOFILE].rlim_cur; - goto out; - - case 5: - printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n", - current->comm, current->pid); - retval = -EINVAL; - goto out; - - default: - printk("[%s:%d] irix_ulimit: Unknown command [%d].\n", - current->comm, current->pid, cmd); - retval = -EINVAL; - goto out; - } -out: - return retval; -} - -asmlinkage int irix_unimp(struct pt_regs *regs) -{ - printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx " - "a3=%08lx\n", current->comm, current->pid, - (int) regs->regs[2], (int) regs->regs[3], - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - - return -ENOSYS; -} diff --git a/include/asm-mips/inventory.h b/include/asm-mips/inventory.h deleted file mode 100644 index cc88aed..0000000 --- a/include/asm-mips/inventory.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Miguel de Icaza - */ -#ifndef __ASM_INVENTORY_H -#define __ASM_INVENTORY_H - -#include - -typedef struct inventory_s { - struct inventory_s *inv_next; - int inv_class; - int inv_type; - int inv_controller; - int inv_unit; - int inv_state; -} inventory_t; - -extern int inventory_items; - -extern void add_to_inventory(int class, int type, int controller, int unit, int state); -extern int dump_inventory_to_user(void __user *userbuf, int size); -extern int __init init_inventory(void); - -#endif /* __ASM_INVENTORY_H */ diff --git a/include/asm-mips/namei.h b/include/asm-mips/namei.h index c94d12d..a6605a7 100644 --- a/include/asm-mips/namei.h +++ b/include/asm-mips/namei.h @@ -1,26 +1,11 @@ #ifndef _ASM_NAMEI_H #define _ASM_NAMEI_H -#include -#include +/* + * This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + */ -#define IRIX_EMUL "/usr/gnemul/irix/" -#define RISCOS_EMUL "/usr/gnemul/riscos/" - -static inline char *__emul_prefix(void) -{ - switch (current->personality) { - case PER_IRIX32: - case PER_IRIXN32: - case PER_IRIX64: - return IRIX_EMUL; - - case PER_RISCOS: - return RISCOS_EMUL; - - default: - return NULL; - } -} +#define __emul_prefix() NULL #endif /* _ASM_NAMEI_H */ diff --git a/include/asm-mips/prctl.h b/include/asm-mips/prctl.h deleted file mode 100644 index 8121a9a..0000000 --- a/include/asm-mips/prctl.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * IRIX prctl interface - * - * The IRIX kernel maps a page at PRDA_ADDRESS with the - * contents of prda and fills it the bits on prda_sys. - */ - -#ifndef __PRCTL_H__ -#define __PRCTL_H__ - -#define PRDA_ADDRESS 0x200000L -#define PRDA ((struct prda *) PRDA_ADDRESS) - -struct prda_sys { - pid_t t_pid; - u32 t_hint; - u32 t_dlactseq; - u32 t_fpflags; - u32 t_prid; /* processor type, $prid CP0 register */ - u32 t_dlendseq; - u64 t_unused1[5]; - pid_t t_rpid; - s32 t_resched; - u32 t_unused[8]; - u32 t_cpu; /* current/last cpu */ - - /* FIXME: The signal information, not supported by Linux now */ - u32 t_flags; /* if true, then the sigprocmask is in userspace */ - u32 t_sigprocmask [1]; /* the sigprocmask */ -}; - -struct prda { - char fill [0xe00]; - struct prda_sys prda_sys; -}; - -#define t_sys prda_sys - -ptrdiff_t prctl(int op, int v1, int v2); - -#endif diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 7a28989..bee5153 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -119,9 +119,6 @@ struct sigaction { struct k_sigaction { struct sigaction sa; -#ifdef CONFIG_BINFMT_IRIX - void (*sa_restorer)(void); -#endif }; /* IRIX compatible stack_t */ -- cgit v0.10.2 From 52f4f6bbcff5510f662a002ec1219660ea25af62 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 12 Jun 2008 15:20:05 -0400 Subject: [MIPS] Use kernel-supplied ARRAY_SIZE() macro. Signed-off-by: Robert P. J. Day Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 8c49510..4b5694e 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -527,7 +527,7 @@ void __init arch_init_irq(void) .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3 } }; -#define NIPI (sizeof(ipiirq)/sizeof(ipiirq[0])) +#define NIPI ARRAY_SIZE(ipiirq) fill_ipi_map(); gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); if (!gcmp_present) { diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index 30e12e2..fee7a2e 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c @@ -412,7 +412,7 @@ static int ip28_be_interrupt(const struct pt_regs *regs) * Now we have an asynchronous bus error, speculatively or DMA caused. * Need to search all DMA descriptors for the error address. */ - for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) { + for (i = 0; i < ARRAY_SIZE(hpc3); ++i) { struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; if ((cpu_err_stat & CPU_ERRMASK) && (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp)) @@ -421,7 +421,7 @@ static int ip28_be_interrupt(const struct pt_regs *regs) (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp)) break; } - if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) { + if (i < ARRAY_SIZE(hpc3)) { struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i; printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:" " ctl %08x, ndp %08x, cbp %08x\n", -- cgit v0.10.2 From 043ebd6c9de7500a399017643bbc5cafd4e37060 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 13 Jun 2008 00:25:36 +0100 Subject: [MIPS] DECstation: Document more MB ASIC register bits Document a few more register bits provided by the MB ASIC used on R4000SC (KN04) and R4400SC (KN05) CPU daughtercards with the DECstation. Reverse-engineered and not documented anywhere else to the best of my knowledge. Bit names appended to the last underscore the same as reported by the firmware in register dumps. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/dec/kn05.h b/include/asm-mips/dec/kn05.h index 15fe8f8..56d22dc 100644 --- a/include/asm-mips/dec/kn05.h +++ b/include/asm-mips/dec/kn05.h @@ -6,7 +6,7 @@ * KN04-CA) and DECsystem 5900/260 (KN05) R4k CPU card MB ASIC * definitions. * - * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki + * Copyright (C) 2002, 2003, 2005, 2008 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -54,11 +54,11 @@ */ #define KN4K_MB_INT_TC (1<<0) /* TURBOchannel? */ #define KN4K_MB_INT_RTC (1<<1) /* RTC? */ -#define KN4K_MB_INT_MT (1<<3) /* ??? */ +#define KN4K_MB_INT_MT (1<<3) /* I/O ASIC cascade */ /* * Bits for the MB control & status register. - * Set to 0x00bf8001 on my system by the ROM. + * Set to 0x00bf8001 for KN05 and to 0x003f8000 for KN04 by the firmware. */ #define KN4K_MB_CSR_PF (1<<0) /* PreFetching enable? */ #define KN4K_MB_CSR_F (1<<1) /* ??? */ @@ -69,7 +69,8 @@ #define KN4K_MB_CSR_IM (1<<13) /* ??? */ #define KN4K_MB_CSR_NC (1<<14) /* ??? */ #define KN4K_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */ -#define KN4K_MB_CSR_MSK (0x1f<<16) /* ??? */ +#define KN4K_MB_CSR_MSK (0x1f<<16) /* CPU Int[4:0] mask */ #define KN4K_MB_CSR_FW (1<<21) /* ??? */ +#define KN4K_MB_CSR_W (1<<31) /* ??? */ #endif /* __ASM_MIPS_DEC_KN05_H */ -- cgit v0.10.2 From 94daeb90698c56a85ed219eeb18d4a8cddde7b03 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 11 Jun 2008 10:04:25 -0700 Subject: [MIPS] Fix asm constraints for 'ins' instructions. The third operand to 'ins' must be a constant int, not a register. [Ralf: The bug was actually intensional. Some versions used to throw an error under certain circumstances for code like: static inline void f(unsigned nr, unsigned *p) { unsigned short bit = nr & 5; if (__builtin_constant_p(bit)) { __asm__ __volatile__ (" foo %0, %1" : "=m" (*p) : "i" (bit)); } else { /* Do something else. */ } } because gcc was not able to figure out that the "i" constraint was possibly at the early stage when the constraint are getting verified. The solution was using "ri" instead of "i". The "ri" would keep gcc happy but in the end for code generation always the "i" constraint would be satisfied. The problem afair originally appeared in the i386 io.h and also hit it's mips equivalent. From there the workaround spread to many of the inline assembler functions.] Signed-off-by: David Daney Signed-off-by: Ralf Baechle diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 6427247..9a7274b 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -82,7 +82,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) "2: b 1b \n" " .previous \n" : "=&r" (temp), "=m" (*m) - : "ir" (bit), "m" (*m), "r" (~0)); + : "i" (bit), "m" (*m), "r" (~0)); #endif /* CONFIG_CPU_MIPSR2 */ } else if (cpu_has_llsc) { __asm__ __volatile__( @@ -147,7 +147,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) "2: b 1b \n" " .previous \n" : "=&r" (temp), "=m" (*m) - : "ir" (bit), "m" (*m)); + : "i" (bit), "m" (*m)); #endif /* CONFIG_CPU_MIPSR2 */ } else if (cpu_has_llsc) { __asm__ __volatile__( @@ -428,7 +428,7 @@ static inline int test_and_clear_bit(unsigned long nr, "2: b 1b \n" " .previous \n" : "=&r" (temp), "=m" (*m), "=&r" (res) - : "ri" (bit), "m" (*m) + : "i" (bit), "m" (*m) : "memory"); #endif } else if (cpu_has_llsc) { -- cgit v0.10.2 From f2bc713f15103372c0efab5fc09dd813655c5096 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 26 Jun 2008 21:52:51 +0900 Subject: [MIPS] Cobalt: Register new LCD platform device. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index d73833b..2379262 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile @@ -2,7 +2,7 @@ # Makefile for the Cobalt micro systems family specific parts of the kernel # -obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o time.o +obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_EARLY_PRINTK) += console.o diff --git a/arch/mips/cobalt/lcd.c b/arch/mips/cobalt/lcd.c new file mode 100644 index 0000000..0720e4f --- /dev/null +++ b/arch/mips/cobalt/lcd.c @@ -0,0 +1,55 @@ +/* + * Registration of Cobalt LCD platform device. + * + * Copyright (C) 2008 Yoichi Yuasa + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include + +static struct resource cobalt_lcd_resource __initdata = { + .start = 0x1f000000, + .end = 0x1f00001f, + .flags = IORESOURCE_MEM, +}; + +static __init int cobalt_lcd_add(void) +{ + struct platform_device *pdev; + int retval; + + pdev = platform_device_alloc("cobalt-lcd", -1); + if (!pdev) + return -ENOMEM; + + retval = platform_device_add_resources(pdev, &cobalt_lcd_resource, 1); + if (retval) + goto err_free_device; + + retval = platform_device_add(pdev); + if (retval) + goto err_free_device; + + return 0; + +err_free_device: + platform_device_put(pdev); + + return retval; +} +device_initcall(cobalt_lcd_add); -- cgit v0.10.2 From 8736595bb2b0ce6188ca31308c40921f3f02f35b Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 2 Jul 2008 21:06:03 +0200 Subject: [MIPS] Enable FAST-20 for onboard scsi Both onboard controller of the O2 support FAST-20 transfer speeds, but the bit, which signals that to the aic driver, isn't set. Instead of adding detection code to the scsi driver, we just fake the missing bit in the PCI config space of the scsi chips. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c index e958818..1cfb558 100644 --- a/arch/mips/pci/ops-mace.c +++ b/arch/mips/pci/ops-mace.c @@ -61,6 +61,13 @@ mace_pci_read_config(struct pci_bus *bus, unsigned int devfn, /* ack possible master abort */ mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT; mace->pci.control = control; + /* + * someone forgot to set the ultra bit for the onboard + * scsi chips; we fake it here + */ + if (bus->number == 0 && reg == 0x40 && size == 4 && + (devfn == (1 << 3) || devfn == (2 << 3))) + *val |= 0x1000; DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val); -- cgit v0.10.2 From 1ea6428cbdbb0fd1a6e7e8c3044253eab9aff4c7 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:19 +0300 Subject: [MIPS] i8253: make the pit_clockevent variable static The pit_clockevent symbol is needlessly defined global. This patch makes that variable static. Spotted by sparse. Compile-tested using Malta defconfig. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index 38fa1a1..b6ac551 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -80,7 +80,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - * !using_apic_timer decisions in do_timer_interrupt_hook() */ -struct clock_event_device pit_clockevent = { +static struct clock_event_device pit_clockevent = { .name = "pit", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_mode = init_pit_timer, -- cgit v0.10.2 From d58eaab5a01b9cf1819ec57271ac214a39bf6278 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:20 +0300 Subject: [MIPS] Namespace clean-up in arch/mips/pci/pci.c The following symbols hose_head hose_tail are needlessly defined global in arch/mips/pci/pci.c, and this patch makes them static. The variable pci_isa_hose is not used, and is removed by this patch. Spotted by namespacecheck. Tested by booting a Malta 4Kc board up to the shell prompt. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 358ad62..d7d6cb0 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -29,8 +29,7 @@ unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES; * The PCI controller list. */ -struct pci_controller *hose_head, **hose_tail = &hose_head; -struct pci_controller *pci_isa_hose; +static struct pci_controller *hose_head, **hose_tail = &hose_head; unsigned long PCIBIOS_MIN_IO = 0x0000; unsigned long PCIBIOS_MIN_MEM = 0; -- cgit v0.10.2 From 7afed6a6c92fadedde8474bbfd92d6debc5e23b0 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:21 +0300 Subject: [MIPS] A few cleanups in malta_int.c Both the fill_ipi_map() routine and the gic_intr_map array defined in arch/mips/mips-boards/malta/malta_int.c are not used outside of the latter file. Thus, these objects can become static. Moreover, these two objects are used by the MT code only, which is why this patch adds the appropriate ifdef. While at it, this patch removes an unnecessary preprocessing macro in favor of the commonly used ARRAY_SIZE. Successfully tested using a Qemu-emulated Malta board for both SMP and UP kernels. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 4b5694e..b393982 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -363,6 +363,7 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = { static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); +#if defined(CONFIG_MIPS_MT_SMP) /* * This GIC specific tabular array defines the association between External * Interrupts and CPUs/Core Interrupts. The nature of the External @@ -394,6 +395,7 @@ static struct gic_intr_map gic_intr_map[] = { { GIC_EXT_INTR(22), 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, { GIC_EXT_INTR(23), 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, }; +#endif /* * GCMP needs to be detected before any SMP initialisation @@ -412,7 +414,8 @@ int __init gcmp_probe(unsigned long addr, unsigned long size) return gcmp_present; } -void __init fill_ipi_map(void) +#if defined(CONFIG_MIPS_MT_SMP) +static void __init fill_ipi_map(void) { int i; @@ -422,6 +425,7 @@ void __init fill_ipi_map(void) (1 << (gic_intr_map[i].pin + 2)); } } +#endif void __init arch_init_irq(void) { @@ -527,7 +531,6 @@ void __init arch_init_irq(void) .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3 } }; -#define NIPI ARRAY_SIZE(ipiirq) fill_ipi_map(); gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); if (!gcmp_present) { @@ -549,7 +552,7 @@ void __init arch_init_irq(void) printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); write_c0_status(0x1100dc00); printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); - for (i = 0; i < NIPI; i++) { + for (i = 0; i < ARRAY_SIZE(ipiirq); i++) { setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, &irq_resched); setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].call, &irq_call); -- cgit v0.10.2 From 6ccab43b49beced70d8663b47ab471c4a23cb580 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:22 +0300 Subject: [MIPS] Make gcmp_probe() static The gcmp_probe() function is needlessly defined global, and this patch makes it static. Tested by booting a Malta 4Kc board up to the shell prompt. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index b393982..ea17611 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -400,7 +400,7 @@ static struct gic_intr_map gic_intr_map[] = { /* * GCMP needs to be detected before any SMP initialisation */ -int __init gcmp_probe(unsigned long addr, unsigned long size) +static int __init gcmp_probe(unsigned long addr, unsigned long size) { if (gcmp_present >= 0) return gcmp_present; -- cgit v0.10.2 From c3dd3de789630b9b1ac8f5175f1c21bbf1cca939 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Wed, 18 Jun 2008 10:18:23 +0300 Subject: [MIPS] Add an appropriate header into display.c The following errors were caught by sparse: >>>>>>>>>>> arch/mips/mips-boards/generic/display.c:30:6: warning: symbol 'mips_display_message' was not declared. Should it be static? arch/mips/mips-boards/generic/display.c:58:6: warning: symbol 'mips_scroll_message' was not declared. Should it be static? >>>>>>>>>>> This patch includes the asm/mips-boards/prom.h header file into arch/mips/mips-boards/generic/display.c. This adds the needed function declarations, and the errors are gone. Compile-tested using defconfigs for Malta, Atlas and SEAD boards. Runtime test was successfully performed by booting a Malta 4Kc board up to the shell prompt. Signed-off-by: Dmitri Vorobiev Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c index 2a0057c..7c8828f 100644 --- a/arch/mips/mips-boards/generic/display.c +++ b/arch/mips/mips-boards/generic/display.c @@ -22,6 +22,7 @@ #include #include #include +#include extern const char display_string[]; static unsigned int display_count; -- cgit v0.10.2 From 7a2852e49fe2d19296812c0f0f833b0ee3043bbb Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 18 Mar 2008 22:47:56 +0100 Subject: [MIPS] IP28: switch to "normal" mode after PROM no longer needed SGI-IP28 is running in so called slow mode, when kernel is started from the PROM. PROM calls must be done in slow mode otherwise the PROM will issue an error. To get better memory performance we now switch to normal mode, when the PROM is no longer needed. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 3f35d63..5268ac1 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c @@ -208,4 +208,30 @@ void __init sgimc_init(void) void __init prom_meminit(void) {} void __init prom_free_prom_memory(void) { +#ifdef CONFIG_SGI_IP28 + u32 mconfig1; + unsigned long flags; + spinlock_t lock; + + /* + * because ARCS accesses memory uncached we wait until ARCS + * isn't needed any longer, before we switch from slow to + * normal mode + */ + spin_lock_irqsave(&lock, flags); + mconfig1 = sgimc->mconfig1; + /* map ECC register */ + sgimc->mconfig1 = (mconfig1 & 0xffff0000) | 0x2060; + iob(); + /* switch to normal mode */ + *(unsigned long *)PHYS_TO_XKSEG_UNCACHED(0x60000000) = 0; + iob(); + /* reduce WR_COL */ + sgimc->cmacc = (sgimc->cmacc & ~0xf) | 4; + iob(); + /* restore old config */ + sgimc->mconfig1 = mconfig1; + iob(); + spin_unlock_irqrestore(&lock, flags); +#endif } diff --git a/include/asm-mips/barrier.h b/include/asm-mips/barrier.h index 9d8cfbb..8e9ac31 100644 --- a/include/asm-mips/barrier.h +++ b/include/asm-mips/barrier.h @@ -92,11 +92,25 @@ #define fast_wmb() __sync() #define fast_rmb() __sync() #define fast_mb() __sync() +#ifdef CONFIG_SGI_IP28 +#define fast_iob() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "lw $0,%0\n\t" \ + "sync\n\t" \ + "lw $0,%0\n\t" \ + ".set pop" \ + : /* no output */ \ + : "m" (*(int *)CKSEG1ADDR(0x1fa00004)) \ + : "memory") +#else #define fast_iob() \ do { \ __sync(); \ __fast_iob(); \ } while (0) +#endif #ifdef CONFIG_CPU_HAS_WB -- cgit v0.10.2 From 8fa9cc16f820915fbe8ab6047c420703a87c307e Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 5 Jul 2008 01:12:13 +0200 Subject: [MIPS] IP32: Add platform devices for audio and volume button Create platform devices for audio and volume button driver. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 89a71f4..2ee401b 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -65,6 +65,42 @@ static __init int meth_devinit(void) device_initcall(meth_devinit); +static __init int sgio2audio_devinit(void) +{ + struct platform_device *pd; + int ret; + + pd = platform_device_alloc("sgio2audio", -1); + if (!pd) + return -ENOMEM; + + ret = platform_device_add(pd); + if (ret) + platform_device_put(pd); + + return ret; +} + +device_initcall(sgio2audio_devinit); + +static __init int sgio2btns_devinit(void) +{ + struct platform_device *pd; + int ret; + + pd = platform_device_alloc("sgio2btns", -1); + if (!pd) + return -ENOMEM; + + ret = platform_device_add(pd); + if (ret) + platform_device_put(pd); + + return ret; +} + +device_initcall(sgio2btns_devinit); + MODULE_AUTHOR("Ralf Baechle "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2"); -- cgit v0.10.2 From af3e69cfc9644c742a22647a5091779b9dfb9653 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 4 Jul 2008 00:59:40 +0900 Subject: [MIPS] Declare some pci variables in header file Declare pci_probe_only, etc. in asm-mips/pci.h file. This will fix some sparse warnings. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c index de5e5f6..34e651b 100644 --- a/arch/mips/pci/fixup-vr4133.c +++ b/arch/mips/pci/fixup-vr4133.c @@ -171,7 +171,6 @@ void i8259_init(void) int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - extern int pci_probe_only; pci_probe_only = 1; #ifdef CONFIG_ROCKHOPPER diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index d19d262..a9060c7 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -202,7 +202,6 @@ static int __init bcm1480_pcibios_init(void) { uint32_t cmdreg; uint64_t reg; - extern int pci_probe_only; /* CFE will assign PCI resources */ pci_probe_only = 1; diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index a185169..ce92f82 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -47,7 +47,6 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) static int num_bridges = 0; bridge_t *bridge; int slot; - extern int pci_probe_only; pci_probe_only = 1; diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c index 9bc102a..bf63959 100644 --- a/arch/mips/pci/pci-sb1250.c +++ b/arch/mips/pci/pci-sb1250.c @@ -210,7 +210,6 @@ static int __init sb1250_pcibios_init(void) void __iomem *io_map_base; uint32_t cmdreg; uint64_t reg; - extern int pci_probe_only; /* CFE will assign PCI resources */ pci_probe_only = 1; diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 301ff2f..d3be834 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -172,4 +172,7 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } +extern int pci_probe_only; +extern unsigned int pcibios_max_latency; + #endif /* _ASM_PCI_H */ -- cgit v0.10.2 From b29eee4935d9e5952a7ea8543ea499f06fb86808 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 16 Apr 2008 02:00:45 +0900 Subject: [MIPS] rbtx4927: misc cleanups * Merge tx4927_pci.h into tx4927.h * Kill (broken) external PCI clock frequency reporting * Kill unnecessary wbflush() * Kill unnecessary includes * Kill debug garbages Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 7450c33..2d234ca 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -38,7 +38,6 @@ #include #include -#include #undef DEBUG #ifdef DEBUG diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 150419c..1bbafeb 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -40,10 +40,7 @@ #include #include #include - -#include -#include -#include +#include /* initialize in setup */ struct resource pci_io_resource = { diff --git a/arch/mips/tx4927/common/tx4927_dbgio.c b/arch/mips/tx4927/common/tx4927_dbgio.c index d8423e0..ea1ff23 100644 --- a/arch/mips/tx4927/common/tx4927_dbgio.c +++ b/arch/mips/tx4927/common/tx4927_dbgio.c @@ -28,9 +28,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include +#include u8 getDebugChar(void) { @@ -38,7 +36,6 @@ u8 getDebugChar(void) return (txx9_sio_kdbg_rd()); } - int putDebugChar(u8 byte) { extern int txx9_sio_kdbg_wr( u8 ch ); diff --git a/arch/mips/tx4927/common/tx4927_prom.c b/arch/mips/tx4927/common/tx4927_prom.c index 6eed53d..cc2aa9d 100644 --- a/arch/mips/tx4927/common/tx4927_prom.c +++ b/arch/mips/tx4927/common/tx4927_prom.c @@ -30,12 +30,8 @@ */ #include -#include -#include -#include - -#include -#include +#include +#include #include static unsigned int __init tx4927_process_sdccr(unsigned long addr) diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 6d31f2a..c18901a 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -28,8 +28,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - - /* IRQ Device 00 RBTX4927-ISA/00 @@ -112,76 +110,14 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB */ #include -#include #include -#include -#include -#include -#include #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include #ifdef CONFIG_TOSHIBA_FPCIB0 #include -#include #endif #include - -#undef TOSHIBA_RBTX4927_IRQ_DEBUG - -#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG -#define TOSHIBA_RBTX4927_IRQ_NONE 0x00000000 - -#define TOSHIBA_RBTX4927_IRQ_INFO ( 1 << 0 ) -#define TOSHIBA_RBTX4927_IRQ_WARN ( 1 << 1 ) -#define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) - -#define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) -#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) -#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) - -#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff -#endif - - -#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG -static const u32 toshiba_rbtx4927_irq_debug_flag = - (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | - TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR -// | TOSHIBA_RBTX4927_IRQ_IOC_INIT -// | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE -// | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE - ); -#endif - - -#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG -#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) \ - if ( (toshiba_rbtx4927_irq_debug_flag) & (flag) ) \ - { \ - char tmp[100]; \ - sprintf( tmp, str ); \ - printk( "%s(%s:%u)::%s", __func__, __FILE__, __LINE__, tmp ); \ - } -#else -#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag, str...) -#endif - - - - #define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 #define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 @@ -207,39 +143,22 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { #define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL #define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL - -u32 bit2num(u32 num) -{ - u32 i; - - for (i = 0; i < (sizeof(num) * 8); i++) { - if (num & (1 << i)) { - return (i); - } - } - return (0); -} - int toshiba_rbtx4927_irq_nested(int sw_irq) { - u32 level3; + u8 level3; level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; if (level3) { - sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + bit2num(level3); - if (sw_irq != TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC) { - goto RETURN; - } - } + sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1; #ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) { - int irq = i8259_irq(); - if (irq >= 0) - sw_irq = irq; - } + if (sw_irq == TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC && + tx4927_using_backplane) { + int irq = i8259_irq(); + if (irq >= 0) + sw_irq = irq; + } #endif - - RETURN: + } return (sw_irq); } @@ -250,21 +169,10 @@ static struct irqaction toshiba_rbtx4927_irq_ioc_action = { .name = TOSHIBA_RBTX4927_IOC_NAME }; - -/**********************************************************************************/ -/* Functions for ioc */ -/**********************************************************************************/ - - static void __init toshiba_rbtx4927_irq_ioc_init(void) { int i; - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_INIT, - "beg=%d end=%d\n", - TOSHIBA_RBTX4927_IRQ_IOC_BEG, - TOSHIBA_RBTX4927_IRQ_IOC_END); - for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, @@ -276,37 +184,16 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) { - volatile unsigned char v; - - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG - || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } + unsigned char v; v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); } - static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) { - volatile unsigned char v; - - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG - || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } + unsigned char v; v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); @@ -314,7 +201,6 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) mmiowb(); } - void __init arch_init_irq(void) { extern void tx4927_irq_init(void); @@ -327,102 +213,4 @@ void __init arch_init_irq(void) #endif /* Onboard 10M Ether: High Active */ set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); - - wbflush(); -} - -void toshiba_rbtx4927_irq_dump(char *key) -{ -#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG - { - u32 i, j = 0; - for (i = 0; i < NR_IRQS; i++) { - if (strcmp(irq_desc[i].chip->name, "none") - == 0) - continue; - - if ((i >= 1) - && (irq_desc[i - 1].chip->name == - irq_desc[i].chip->name)) { - j++; - } else { - j = 0; - } - TOSHIBA_RBTX4927_IRQ_DPRINTK - (TOSHIBA_RBTX4927_IRQ_INFO, - "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", - key, i, i, irq_desc[i].status, - (u32) irq_desc[i].chip, - (u32) irq_desc[i].action, - (u32) (irq_desc[i].action ? irq_desc[i]. - action->handler : 0), - irq_desc[i].depth, - irq_desc[i].chip->name, j); - } - } -#endif -} - -void toshiba_rbtx4927_irq_dump_pics(char *s) -{ - u32 level0_m; - u32 level0_s; - u32 level1_m; - u32 level1_s; - u32 level2; - u32 level2_p; - u32 level2_s; - u32 level3_m; - u32 level3_s; - u32 level4_m; - u32 level4_s; - u32 level5_m; - u32 level5_s; - - if (s == NULL) - s = "null"; - - level0_m = (read_c0_status() & 0x0000ff00) >> 8; - level0_s = (read_c0_cause() & 0x0000ff00) >> 8; - - level1_m = level0_m; - level1_s = level0_s & 0x87; - - level2 = __raw_readl((void __iomem *)0xff1ff6a0UL); - level2_p = (((level2 & 0x10000)) ? 0 : 1); - level2_s = (((level2 & 0x1f) == 0x1f) ? 0 : (level2 & 0x1f)); - - level3_m = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB) & 0x1f; - level3_s = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; - - level4_m = inb(0x21); - outb(0x0A, 0x20); - level4_s = inb(0x20); - - level5_m = inb(0xa1); - outb(0x0A, 0xa0); - level5_s = inb(0xa0); - - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "dump_raw_pic() "); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "cp0:m=0x%02x/s=0x%02x ", level0_m, - level0_s); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "cp0:m=0x%02x/s=0x%02x ", level1_m, - level1_s); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "pic:e=0x%02x/s=0x%02x ", level2_p, - level2_s); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "ioc:m=0x%02x/s=0x%02x ", level3_m, - level3_s); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "sbm:m=0x%02x/s=0x%02x ", level4_m, - level4_s); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, - "sbs:m=0x%02x/s=0x%02x ", level5_m, - level5_s); - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", - s); } diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c index f3f8685..fdbad4b 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c @@ -30,13 +30,10 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include -#include -#include - -#include +#include #include #include +#include #include void __init prom_init_cmdline(void) diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index 2203c77..185f303 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -62,43 +62,10 @@ #include #endif #include -#ifdef CONFIG_PCI -#include -#endif #ifdef CONFIG_SERIAL_TXX9 #include #endif -#undef TOSHIBA_RBTX4927_SETUP_DEBUG - -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG -#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) -#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) -#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) -#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) - -#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff -#endif - -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG -static const u32 toshiba_rbtx4927_setup_debug_flag = - (TOSHIBA_RBTX4927_SETUP_SETUP | - | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | - TOSHIBA_RBTX4927_SETUP_PCI2); -#endif - -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG -#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \ - if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \ - { \ - char tmp[100]; \ - sprintf( tmp, str ); \ - printk( "%s(%s:%u)::%s", __func__, __FILE__, __LINE__, tmp ); \ - } -#else -#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag, str...) -#endif - /* These functions are used for rebooting or halting the machine*/ extern void toshiba_rbtx4927_restart(char *command); extern void toshiba_rbtx4927_halt(void); @@ -124,7 +91,6 @@ unsigned long mips_memory_upper; static int tx4927_ccfg_toeon = 1; static int tx4927_pcic_trdyto = 0; /* default: disabled */ unsigned long tx4927_ce_base[8]; -void tx4927_reset_pci_pcic(void); int tx4927_pci66 = 0; /* 0:auto */ #endif @@ -172,9 +138,6 @@ static int __init tx4927_pcibios_init(void) int busno = 0; /* One bus on the Toshiba */ struct pci_controller *hose = &tx4927_controller; - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, - "-\n"); - for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { early_read_config_dword(hose, busno, busno, pci_devfn, PCI_VENDOR_ID, &id); @@ -187,13 +150,6 @@ static int __init tx4927_pcibios_init(void) u8 v08_64; u32 v32_b0; u8 v08_e1; -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG - char *s = " sb/isa --"; -#endif - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", - s); early_read_config_byte(hose, busno, busno, pci_devfn, 0x64, &v08_64); @@ -202,16 +158,6 @@ static int __init tx4927_pcibios_init(void) early_read_config_byte(hose, busno, busno, pci_devfn, 0xe1, &v08_e1); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0x64 = 0x%02x\n", s, v08_64); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0xb0 = 0x%02x\n", s, v32_b0); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0xe1 = 0x%02x\n", s, v08_e1); - /* serial irq control */ v08_64 = 0xd0; @@ -222,50 +168,12 @@ static int __init tx4927_pcibios_init(void) v08_e1 &= 0xf0; v08_e1 |= 0x0d; - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0x64 = 0x%02x\n", s, v08_64); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0xb0 = 0x%02x\n", s, v32_b0); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0xe1 = 0x%02x\n", s, v08_e1); - early_write_config_byte(hose, busno, busno, pci_devfn, 0x64, v08_64); early_write_config_dword(hose, busno, busno, pci_devfn, 0xb0, v32_b0); early_write_config_byte(hose, busno, busno, pci_devfn, 0xe1, v08_e1); - -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG - { - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x64, - &v08_64); - early_read_config_dword(hose, busno, busno, - pci_devfn, 0xb0, - &v32_b0); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0xe1, - &v08_e1); - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0x64 = 0x%02x\n", s, v08_64); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0xb0 = 0x%02x\n", s, v32_b0); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0xe1 = 0x%02x\n", s, v08_e1); - } -#endif - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", - s); } if (id == 0x91301055) { @@ -274,13 +182,6 @@ static int __init tx4927_pcibios_init(void) u8 v08_41; u8 v08_43; u8 v08_5c; -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG - char *s = " sb/ide --"; -#endif - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", - s); early_read_config_byte(hose, busno, busno, pci_devfn, 0x04, &v08_04); @@ -293,22 +194,6 @@ static int __init tx4927_pcibios_init(void) early_read_config_byte(hose, busno, busno, pci_devfn, 0x5c, &v08_5c); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0x04 = 0x%02x\n", s, v08_04); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0x09 = 0x%02x\n", s, v08_09); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0x41 = 0x%02x\n", s, v08_41); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0x43 = 0x%02x\n", s, v08_43); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s beg 0x5c = 0x%02x\n", s, v08_5c); - /* enable ide master/io */ v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); @@ -332,22 +217,6 @@ static int __init tx4927_pcibios_init(void) */ v08_5c |= 0x01; - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0x04 = 0x%02x\n", s, v08_04); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0x09 = 0x%02x\n", s, v08_09); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0x41 = 0x%02x\n", s, v08_41); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0x43 = 0x%02x\n", s, v08_43); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s mid 0x5c = 0x%02x\n", s, v08_5c); - early_write_config_byte(hose, busno, busno, pci_devfn, 0x5c, v08_5c); early_write_config_byte(hose, busno, busno, @@ -358,54 +227,11 @@ static int __init tx4927_pcibios_init(void) pci_devfn, 0x41, v08_41); early_write_config_byte(hose, busno, busno, pci_devfn, 0x43, v08_43); - -#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG - { - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x04, - &v08_04); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x09, - &v08_09); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x41, - &v08_41); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x43, - &v08_43); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x5c, - &v08_5c); - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0x04 = 0x%02x\n", s, v08_04); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0x09 = 0x%02x\n", s, v08_09); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0x41 = 0x%02x\n", s, v08_41); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0x43 = 0x%02x\n", s, v08_43); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, - ":%s end 0x5c = 0x%02x\n", s, v08_5c); - } -#endif - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", - s); } } register_pci_controller(&tx4927_controller); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, - "+\n"); - return 0; } @@ -419,45 +245,13 @@ void __init tx4927_pci_setup(void) static int called = 0; extern unsigned int tx4927_get_mem_size(void); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "-\n"); - mips_memory_upper = tx4927_get_mem_size() << 20; mips_memory_upper += KSEG0; - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=mips_memory_upper\n", - mips_memory_upper); mips_pci_io_base = TX4927_PCIIO; mips_pci_io_size = TX4927_PCIIO_SIZE; mips_pci_mem_base = TX4927_PCIMEM; mips_pci_mem_size = TX4927_PCIMEM_SIZE; - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=mips_pci_io_base\n", - mips_pci_io_base); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=mips_pci_io_size\n", - mips_pci_io_size); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=mips_pci_mem_base\n", - mips_pci_mem_base); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=mips_pci_mem_size\n", - mips_pci_mem_size); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=pci_io_resource.start\n", - pci_io_resource.start); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=pci_io_resource.end\n", - pci_io_resource.end); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=pci_mem_resource.start\n", - pci_mem_resource.start); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=pci_mem_resource.end\n", - pci_mem_resource.end); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - "0x%08lx=mips_io_port_base", - mips_io_port_base); if (!called) { printk ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", @@ -521,29 +315,10 @@ void __init tx4927_pci_setup(void) } printk("Internal(%dMHz)", pciclk / 1000000); - } else { - int pciclk = 0; - int pciclk_setting = *tx4927_pci_clk_ptr; - switch (pciclk_setting & TX4927_PCI_CLK_MASK) { - case TX4927_PCI_CLK_33: - pciclk = 33333333; - break; - case TX4927_PCI_CLK_25: - pciclk = 25000000; - break; - case TX4927_PCI_CLK_66: - pciclk = 66666666; - break; - case TX4927_PCI_CLK_50: - pciclk = 50000000; - break; - } - printk("External(%dMHz)", pciclk / 1000000); - } + } else + printk("External"); printk("\n"); - - /* GB->PCI mappings */ tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; tx4927_pcicptr->g2piogbase = mips_pci_io_base | @@ -644,12 +419,7 @@ void __init tx4927_pci_setup(void) tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, - ":pci setup complete:\n"); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "+\n"); } - #endif /* CONFIG_PCI */ static void __noreturn wait_forever(void) @@ -679,7 +449,6 @@ void toshiba_rbtx4927_restart(char *command) /* no return */ } - void toshiba_rbtx4927_halt(void) { printk(KERN_NOTICE "System Halted\n"); @@ -702,33 +471,19 @@ void __init plat_mem_setup(void) printk("CPU is %s\n", toshiba_name); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - "-\n"); - /* f/w leaves this on at startup */ - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - ":Clearing STO_ERL.\n"); clear_c0_status(ST0_ERL); /* enable caches -- HCP5 does this, pmon does not */ - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - ":Enabling TX49_CONF_IC,TX49_CONF_DC.\n"); cp0_config = read_c0_config(); cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); write_c0_config(cp0_config); set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - ":mips_io_port_base=0x%08lx\n", - mips_io_port_base); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - ":Resource\n"); ioport_resource.end = 0xffffffff; iomem_resource.end = 0xffffffff; - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - ":ResetRoutines\n"); _machine_restart = toshiba_rbtx4927_restart; _machine_halt = toshiba_rbtx4927_halt; pm_power_off = toshiba_rbtx4927_power_off; @@ -761,23 +516,6 @@ void __init plat_mem_setup(void) * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) * */ - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, - "ccfg is %lx, PCIDIVMODE is %x\n", - (unsigned long) tx4927_ccfgptr->ccfg, - (unsigned long) tx4927_ccfgptr->ccfg & - (mips_machtype == MACH_TOSHIBA_RBTX4937 ? - TX4937_CCFG_PCIDIVMODE_MASK : - TX4927_CCFG_PCIDIVMODE_MASK)); - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, - "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", - (unsigned long) tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCI66, - (unsigned long) tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIMIDE, - (unsigned long) tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIXARB); - if (mips_machtype == MACH_TOSHIBA_RBTX4937) switch ((unsigned long)tx4927_ccfgptr-> ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { @@ -818,49 +556,18 @@ void __init plat_mem_setup(void) /* this is on ISA bus behind PCI bus, so need PCI up first */ #ifdef CONFIG_TOSHIBA_FPCIB0 - { - if (tx4927_using_backplane) { - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, - ":fpcibo=yes\n"); - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, - ":smsc_fdc37m81x_init()\n"); - smsc_fdc37m81x_init(0x3f0); - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, - ":smsc_fdc37m81x_config_beg()\n"); - smsc_fdc37m81x_config_beg(); - - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, - ":smsc_fdc37m81x_config_set(KBD)\n"); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, - SMSC_FDC37M81X_KBD); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, - 1); - - smsc_fdc37m81x_config_end(); - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, - ":smsc_fdc37m81x_config_end()\n"); - } else { - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, - ":fpcibo=not_found\n"); - } - } -#else - { - TOSHIBA_RBTX4927_SETUP_DPRINTK - (TOSHIBA_RBTX4927_SETUP_SETUP, ":fpcibo=no\n"); + if (tx4927_using_backplane) { + smsc_fdc37m81x_init(0x3f0); + smsc_fdc37m81x_config_beg(); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + smsc_fdc37m81x_config_end(); } #endif - #endif /* CONFIG_PCI */ #ifdef CONFIG_SERIAL_TXX9 @@ -894,17 +601,12 @@ void __init plat_mem_setup(void) } #endif - #ifdef CONFIG_IP_PNP argptr = prom_getcmdline(); if (strstr(argptr, "ip=") == NULL) { strcat(argptr, " ip=any"); } #endif - - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, - "+\n"); } void __init plat_time_init(void) diff --git a/include/asm-mips/tx4927/toshiba_rbtx4927.h b/include/asm-mips/tx4927/toshiba_rbtx4927.h index b188a65..d6b32ac 100644 --- a/include/asm-mips/tx4927/toshiba_rbtx4927.h +++ b/include/asm-mips/tx4927/toshiba_rbtx4927.h @@ -28,9 +28,6 @@ #define __ASM_TX4927_TOSHIBA_RBTX4927_H #include -#ifdef CONFIG_PCI -#include -#endif #ifdef CONFIG_PCI #define TBTX4927_ISA_IO_OFFSET TX4927_PCIIO @@ -44,7 +41,6 @@ #define RBTX4927_SW_RESET_ENABLE (void __iomem *)0xbc00f002UL #define RBTX4927_SW_RESET_ENABLE_SET 0x01 - #define RBTX4927_RTL_8019_BASE (0x1c020280-TBTX4927_ISA_IO_OFFSET) #define RBTX4927_RTL_8019_IRQ (TX4927_IRQ_PIC_BEG + 5) diff --git a/include/asm-mips/tx4927/tx4927.h b/include/asm-mips/tx4927/tx4927.h index 193e80a..1d4816f 100644 --- a/include/asm-mips/tx4927/tx4927.h +++ b/include/asm-mips/tx4927/tx4927.h @@ -36,11 +36,245 @@ #define TX4927_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) -#define TX4927_IRQ_USER0 (TX4927_IRQ_CP0_BEG+0) -#define TX4927_IRQ_USER1 (TX4927_IRQ_CP0_BEG+1) +#define TX4927_IRQ_USER0 (TX4927_IRQ_CP0_BEG+0) +#define TX4927_IRQ_USER1 (TX4927_IRQ_CP0_BEG+1) #define TX4927_IRQ_NEST_PIC_ON_CP0 (TX4927_IRQ_CP0_BEG+2) -#define TX4927_IRQ_CPU_TIMER (TX4927_IRQ_CP0_BEG+7) +#define TX4927_IRQ_CPU_TIMER (TX4927_IRQ_CP0_BEG+7) #define TX4927_IRQ_NEST_EXT_ON_PIC (TX4927_IRQ_PIC_BEG+3) +#define TX4927_CCFG_TOE 0x00004000 +#define TX4927_CCFG_WR 0x00008000 +#define TX4927_CCFG_TINTDIS 0x01000000 + +#define TX4927_PCIMEM 0x08000000 +#define TX4927_PCIMEM_SIZE 0x08000000 +#define TX4927_PCIIO 0x16000000 +#define TX4927_PCIIO_SIZE 0x01000000 + +#define TX4927_SDRAMC_REG 0xff1f8000 +#define TX4927_EBUSC_REG 0xff1f9000 +#define TX4927_PCIC_REG 0xff1fd000 +#define TX4927_CCFG_REG 0xff1fe000 +#define TX4927_IRC_REG 0xff1ff600 +#define TX4927_NR_TMR 3 +#define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) + +/* bits for ISTAT3/IMASK3/IMSTAT3 */ +#define TX4927_INT3B_PCID 0 +#define TX4927_INT3B_PCIC 1 +#define TX4927_INT3B_PCIB 2 +#define TX4927_INT3B_PCIA 3 +#define TX4927_INT3F_PCID (1 << TX4927_INT3B_PCID) +#define TX4927_INT3F_PCIC (1 << TX4927_INT3B_PCIC) +#define TX4927_INT3F_PCIB (1 << TX4927_INT3B_PCIB) +#define TX4927_INT3F_PCIA (1 << TX4927_INT3B_PCIA) + +#define TX4927_NR_IRQ_LOCAL TX4927_IRQ_PIC_BEG +#define TX4927_NR_IRQ_IRC 32 /* On-Chip IRC */ + +#define TX4927_IR_PCIC 16 +#define TX4927_IR_PCIERR 22 +#define TX4927_IR_PCIPMA 23 +#define TX4927_IRQ_IRC_PCIC (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIC) +#define TX4927_IRQ_IRC_PCIERR (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIERR) +#define TX4927_IRQ_IOC1 (TX4927_NR_IRQ_LOCAL + TX4927_NR_IRQ_IRC) +#define TX4927_IRQ_IOC_PCID (TX4927_IRQ_IOC1 + TX4927_INT3B_PCID) +#define TX4927_IRQ_IOC_PCIC (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIC) +#define TX4927_IRQ_IOC_PCIB (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIB) +#define TX4927_IRQ_IOC_PCIA (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIA) + +#ifdef _LANGUAGE_ASSEMBLY +#define _CONST64(c) c +#else +#define _CONST64(c) c##ull + +#include + +struct tx4927_sdramc_reg { + volatile unsigned long long cr[4]; + volatile unsigned long long unused0[4]; + volatile unsigned long long tr; + volatile unsigned long long unused1[2]; + volatile unsigned long long cmd; +}; + +struct tx4927_ebusc_reg { + volatile unsigned long long cr[8]; +}; + +struct tx4927_ccfg_reg { + volatile unsigned long long ccfg; + volatile unsigned long long crir; + volatile unsigned long long pcfg; + volatile unsigned long long tear; + volatile unsigned long long clkctr; + volatile unsigned long long unused0; + volatile unsigned long long garbc; + volatile unsigned long long unused1; + volatile unsigned long long unused2; + volatile unsigned long long ramp; +}; + +struct tx4927_pcic_reg { + volatile unsigned long pciid; + volatile unsigned long pcistatus; + volatile unsigned long pciccrev; + volatile unsigned long pcicfg1; + volatile unsigned long p2gm0plbase; /* +10 */ + volatile unsigned long p2gm0pubase; + volatile unsigned long p2gm1plbase; + volatile unsigned long p2gm1pubase; + volatile unsigned long p2gm2pbase; /* +20 */ + volatile unsigned long p2giopbase; + volatile unsigned long unused0; + volatile unsigned long pcisid; + volatile unsigned long unused1; /* +30 */ + volatile unsigned long pcicapptr; + volatile unsigned long unused2; + volatile unsigned long pcicfg2; + volatile unsigned long g2ptocnt; /* +40 */ + volatile unsigned long unused3[15]; + volatile unsigned long g2pstatus; /* +80 */ + volatile unsigned long g2pmask; + volatile unsigned long pcisstatus; + volatile unsigned long pcimask; + volatile unsigned long p2gcfg; /* +90 */ + volatile unsigned long p2gstatus; + volatile unsigned long p2gmask; + volatile unsigned long p2gccmd; + volatile unsigned long unused4[24]; /* +a0 */ + volatile unsigned long pbareqport; /* +100 */ + volatile unsigned long pbacfg; + volatile unsigned long pbastatus; + volatile unsigned long pbamask; + volatile unsigned long pbabm; /* +110 */ + volatile unsigned long pbacreq; + volatile unsigned long pbacgnt; + volatile unsigned long pbacstate; + volatile unsigned long long g2pmgbase[3]; /* +120 */ + volatile unsigned long long g2piogbase; + volatile unsigned long g2pmmask[3]; /* +140 */ + volatile unsigned long g2piomask; + volatile unsigned long long g2pmpbase[3]; /* +150 */ + volatile unsigned long long g2piopbase; + volatile unsigned long pciccfg; /* +170 */ + volatile unsigned long pcicstatus; + volatile unsigned long pcicmask; + volatile unsigned long unused5; + volatile unsigned long long p2gmgbase[3]; /* +180 */ + volatile unsigned long long p2giogbase; + volatile unsigned long g2pcfgadrs; /* +1a0 */ + volatile unsigned long g2pcfgdata; + volatile unsigned long unused6[8]; + volatile unsigned long g2pintack; + volatile unsigned long g2pspc; + volatile unsigned long unused7[12]; /* +1d0 */ + volatile unsigned long long pdmca; /* +200 */ + volatile unsigned long long pdmga; + volatile unsigned long long pdmpa; + volatile unsigned long long pdmcut; + volatile unsigned long long pdmcnt; /* +220 */ + volatile unsigned long long pdmsts; + volatile unsigned long long unused8[2]; + volatile unsigned long long pdmdb[4]; /* +240 */ + volatile unsigned long long pdmtdh; /* +260 */ + volatile unsigned long long pdmdms; +}; + +#endif /* _LANGUAGE_ASSEMBLY */ + +/* + * PCIC + */ + +/* bits for G2PSTATUS/G2PMASK */ +#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 +#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 +#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 + +/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ +#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 + +/* bits for PBACFG */ +#define TX4927_PCIC_PBACFG_RPBA 0x00000004 +#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 +#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 + +/* bits for G2PMnGBASE */ +#define TX4927_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for G2PIOGBASE */ +#define TX4927_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for PCICSTATUS/PCICMASK */ +#define TX4927_PCIC_PCICSTATUS_ALL 0x000007dc + +/* bits for PCICCFG */ +#define TX4927_PCIC_PCICCFG_LBWC_MASK 0x0fff0000 +#define TX4927_PCIC_PCICCFG_HRST 0x00000800 +#define TX4927_PCIC_PCICCFG_SRST 0x00000400 +#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 +#define TX4927_PCIC_PCICCFG_IMSE0 0x00000100 +#define TX4927_PCIC_PCICCFG_IMSE1 0x00000080 +#define TX4927_PCIC_PCICCFG_IMSE2 0x00000040 +#define TX4927_PCIC_PCICCFG_IISE 0x00000020 +#define TX4927_PCIC_PCICCFG_ATR 0x00000010 +#define TX4927_PCIC_PCICCFG_ICAE 0x00000008 + +/* bits for P2GMnGBASE */ +#define TX4927_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) +#define TX4927_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) + +/* bits for P2GIOGBASE */ +#define TX4927_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) +#define TX4927_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) + +#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX4927_CCFG_PCI66 0x00800000 +#define TX4927_CCFG_PCIMIDE 0x00400000 +#define TX4927_CCFG_PCIXARB 0x00002000 +#define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800 +#define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000 +#define TX4927_CCFG_PCIDIVMODE_3 0x00000800 +#define TX4927_CCFG_PCIDIVMODE_5 0x00001000 +#define TX4927_CCFG_PCIDIVMODE_6 0x00001800 + +#define TX4937_CCFG_PCIDIVMODE_MASK 0x00001c00 +#define TX4937_CCFG_PCIDIVMODE_8 0x00000000 +#define TX4937_CCFG_PCIDIVMODE_4 0x00000400 +#define TX4937_CCFG_PCIDIVMODE_9 0x00000800 +#define TX4937_CCFG_PCIDIVMODE_4_5 0x00000c00 +#define TX4937_CCFG_PCIDIVMODE_10 0x00001000 +#define TX4937_CCFG_PCIDIVMODE_5 0x00001400 +#define TX4937_CCFG_PCIDIVMODE_11 0x00001800 +#define TX4937_CCFG_PCIDIVMODE_5_5 0x00001c00 + +/* PCFG : Pin Configuration */ +#define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 +#define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) + +/* CLKCTR : Clock Control */ +#define TX4927_CLKCTR_PCICKD 0x00400000 +#define TX4927_CLKCTR_PCIRST 0x00000040 + +#ifndef _LANGUAGE_ASSEMBLY + +#define tx4927_sdramcptr ((struct tx4927_sdramc_reg *)TX4927_SDRAMC_REG) +#define tx4927_pcicptr ((struct tx4927_pcic_reg *)TX4927_PCIC_REG) +#define tx4927_ccfgptr ((struct tx4927_ccfg_reg *)TX4927_CCFG_REG) +#define tx4927_ebuscptr ((struct tx4927_ebusc_reg *)TX4927_EBUSC_REG) + +#endif /* _LANGUAGE_ASSEMBLY */ + #endif /* __ASM_TX4927_TX4927_H */ diff --git a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h deleted file mode 100644 index 0be77df..0000000 --- a/include/asm-mips/tx4927/tx4927_pci.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2001 Toshiba Corporation - */ -#ifndef __ASM_TX4927_TX4927_PCI_H -#define __ASM_TX4927_TX4927_PCI_H - -#define TX4927_CCFG_TOE 0x00004000 -#define TX4927_CCFG_WR 0x00008000 -#define TX4927_CCFG_TINTDIS 0x01000000 - -#define TX4927_PCIMEM 0x08000000 -#define TX4927_PCIMEM_SIZE 0x08000000 -#define TX4927_PCIIO 0x16000000 -#define TX4927_PCIIO_SIZE 0x01000000 - -#define TX4927_SDRAMC_REG 0xff1f8000 -#define TX4927_EBUSC_REG 0xff1f9000 -#define TX4927_PCIC_REG 0xff1fd000 -#define TX4927_CCFG_REG 0xff1fe000 -#define TX4927_IRC_REG 0xff1ff600 -#define TX4927_NR_TMR 3 -#define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) -#define TX4927_CE3 0x17f00000 /* 1M */ -#define TX4927_PCIRESET_ADDR 0xbc00f006 -#define TX4927_PCI_CLK_ADDR (KSEG1 + TX4927_CE3 + 0x00040020) - -#define TX4927_IMSTAT_ADDR(n) (KSEG1 + TX4927_CE3 + 0x0004001a + (n)) -#define tx4927_imstat_ptr(n) \ - ((volatile unsigned char *)TX4927_IMSTAT_ADDR(n)) - -/* bits for ISTAT3/IMASK3/IMSTAT3 */ -#define TX4927_INT3B_PCID 0 -#define TX4927_INT3B_PCIC 1 -#define TX4927_INT3B_PCIB 2 -#define TX4927_INT3B_PCIA 3 -#define TX4927_INT3F_PCID (1 << TX4927_INT3B_PCID) -#define TX4927_INT3F_PCIC (1 << TX4927_INT3B_PCIC) -#define TX4927_INT3F_PCIB (1 << TX4927_INT3B_PCIB) -#define TX4927_INT3F_PCIA (1 << TX4927_INT3B_PCIA) - -/* bits for PCI_CLK (S6) */ -#define TX4927_PCI_CLK_HOST 0x80 -#define TX4927_PCI_CLK_MASK (0x0f << 3) -#define TX4927_PCI_CLK_33 (0x01 << 3) -#define TX4927_PCI_CLK_25 (0x04 << 3) -#define TX4927_PCI_CLK_66 (0x09 << 3) -#define TX4927_PCI_CLK_50 (0x0c << 3) -#define TX4927_PCI_CLK_ACK 0x04 -#define TX4927_PCI_CLK_ACE 0x02 -#define TX4927_PCI_CLK_ENDIAN 0x01 -#define TX4927_NR_IRQ_LOCAL TX4927_IRQ_PIC_BEG -#define TX4927_NR_IRQ_IRC 32 /* On-Chip IRC */ - -#define TX4927_IR_PCIC 16 -#define TX4927_IR_PCIERR 22 -#define TX4927_IR_PCIPMA 23 -#define TX4927_IRQ_IRC_PCIC (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIC) -#define TX4927_IRQ_IRC_PCIERR (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIERR) -#define TX4927_IRQ_IOC1 (TX4927_NR_IRQ_LOCAL + TX4927_NR_IRQ_IRC) -#define TX4927_IRQ_IOC_PCID (TX4927_IRQ_IOC1 + TX4927_INT3B_PCID) -#define TX4927_IRQ_IOC_PCIC (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIC) -#define TX4927_IRQ_IOC_PCIB (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIB) -#define TX4927_IRQ_IOC_PCIA (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIA) - -#ifdef _LANGUAGE_ASSEMBLY -#define _CONST64(c) c -#else -#define _CONST64(c) c##ull - -#include - -#define tx4927_pcireset_ptr \ - ((volatile unsigned char *)TX4927_PCIRESET_ADDR) -#define tx4927_pci_clk_ptr \ - ((volatile unsigned char *)TX4927_PCI_CLK_ADDR) - -struct tx4927_sdramc_reg { - volatile unsigned long long cr[4]; - volatile unsigned long long unused0[4]; - volatile unsigned long long tr; - volatile unsigned long long unused1[2]; - volatile unsigned long long cmd; -}; - -struct tx4927_ebusc_reg { - volatile unsigned long long cr[8]; -}; - -struct tx4927_ccfg_reg { - volatile unsigned long long ccfg; - volatile unsigned long long crir; - volatile unsigned long long pcfg; - volatile unsigned long long tear; - volatile unsigned long long clkctr; - volatile unsigned long long unused0; - volatile unsigned long long garbc; - volatile unsigned long long unused1; - volatile unsigned long long unused2; - volatile unsigned long long ramp; -}; - -struct tx4927_pcic_reg { - volatile unsigned long pciid; - volatile unsigned long pcistatus; - volatile unsigned long pciccrev; - volatile unsigned long pcicfg1; - volatile unsigned long p2gm0plbase; /* +10 */ - volatile unsigned long p2gm0pubase; - volatile unsigned long p2gm1plbase; - volatile unsigned long p2gm1pubase; - volatile unsigned long p2gm2pbase; /* +20 */ - volatile unsigned long p2giopbase; - volatile unsigned long unused0; - volatile unsigned long pcisid; - volatile unsigned long unused1; /* +30 */ - volatile unsigned long pcicapptr; - volatile unsigned long unused2; - volatile unsigned long pcicfg2; - volatile unsigned long g2ptocnt; /* +40 */ - volatile unsigned long unused3[15]; - volatile unsigned long g2pstatus; /* +80 */ - volatile unsigned long g2pmask; - volatile unsigned long pcisstatus; - volatile unsigned long pcimask; - volatile unsigned long p2gcfg; /* +90 */ - volatile unsigned long p2gstatus; - volatile unsigned long p2gmask; - volatile unsigned long p2gccmd; - volatile unsigned long unused4[24]; /* +a0 */ - volatile unsigned long pbareqport; /* +100 */ - volatile unsigned long pbacfg; - volatile unsigned long pbastatus; - volatile unsigned long pbamask; - volatile unsigned long pbabm; /* +110 */ - volatile unsigned long pbacreq; - volatile unsigned long pbacgnt; - volatile unsigned long pbacstate; - volatile unsigned long long g2pmgbase[3]; /* +120 */ - volatile unsigned long long g2piogbase; - volatile unsigned long g2pmmask[3]; /* +140 */ - volatile unsigned long g2piomask; - volatile unsigned long long g2pmpbase[3]; /* +150 */ - volatile unsigned long long g2piopbase; - volatile unsigned long pciccfg; /* +170 */ - volatile unsigned long pcicstatus; - volatile unsigned long pcicmask; - volatile unsigned long unused5; - volatile unsigned long long p2gmgbase[3]; /* +180 */ - volatile unsigned long long p2giogbase; - volatile unsigned long g2pcfgadrs; /* +1a0 */ - volatile unsigned long g2pcfgdata; - volatile unsigned long unused6[8]; - volatile unsigned long g2pintack; - volatile unsigned long g2pspc; - volatile unsigned long unused7[12]; /* +1d0 */ - volatile unsigned long long pdmca; /* +200 */ - volatile unsigned long long pdmga; - volatile unsigned long long pdmpa; - volatile unsigned long long pdmcut; - volatile unsigned long long pdmcnt; /* +220 */ - volatile unsigned long long pdmsts; - volatile unsigned long long unused8[2]; - volatile unsigned long long pdmdb[4]; /* +240 */ - volatile unsigned long long pdmtdh; /* +260 */ - volatile unsigned long long pdmdms; -}; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* - * PCIC - */ - -/* bits for G2PSTATUS/G2PMASK */ -#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 -#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 -#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 - -/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ -#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 - -/* bits for PBACFG */ -#define TX4927_PCIC_PBACFG_RPBA 0x00000004 -#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 -#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 - -/* bits for G2PMnGBASE */ -#define TX4927_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for G2PIOGBASE */ -#define TX4927_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for PCICSTATUS/PCICMASK */ -#define TX4927_PCIC_PCICSTATUS_ALL 0x000007dc - -/* bits for PCICCFG */ -#define TX4927_PCIC_PCICCFG_LBWC_MASK 0x0fff0000 -#define TX4927_PCIC_PCICCFG_HRST 0x00000800 -#define TX4927_PCIC_PCICCFG_SRST 0x00000400 -#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 -#define TX4927_PCIC_PCICCFG_IMSE0 0x00000100 -#define TX4927_PCIC_PCICCFG_IMSE1 0x00000080 -#define TX4927_PCIC_PCICCFG_IMSE2 0x00000040 -#define TX4927_PCIC_PCICCFG_IISE 0x00000020 -#define TX4927_PCIC_PCICCFG_ATR 0x00000010 -#define TX4927_PCIC_PCICCFG_ICAE 0x00000008 - -/* bits for P2GMnGBASE */ -#define TX4927_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) -#define TX4927_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) - -/* bits for P2GIOGBASE */ -#define TX4927_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) -#define TX4927_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) - -#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) -#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) - -/* - * CCFG - */ -/* CCFG : Chip Configuration */ -#define TX4927_CCFG_PCI66 0x00800000 -#define TX4927_CCFG_PCIMIDE 0x00400000 -#define TX4927_CCFG_PCIXARB 0x00002000 -#define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800 -#define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000 -#define TX4927_CCFG_PCIDIVMODE_3 0x00000800 -#define TX4927_CCFG_PCIDIVMODE_5 0x00001000 -#define TX4927_CCFG_PCIDIVMODE_6 0x00001800 - -#define TX4937_CCFG_PCIDIVMODE_MASK 0x00001c00 -#define TX4937_CCFG_PCIDIVMODE_8 0x00000000 -#define TX4937_CCFG_PCIDIVMODE_4 0x00000400 -#define TX4937_CCFG_PCIDIVMODE_9 0x00000800 -#define TX4937_CCFG_PCIDIVMODE_4_5 0x00000c00 -#define TX4937_CCFG_PCIDIVMODE_10 0x00001000 -#define TX4937_CCFG_PCIDIVMODE_5 0x00001400 -#define TX4937_CCFG_PCIDIVMODE_11 0x00001800 -#define TX4937_CCFG_PCIDIVMODE_5_5 0x00001c00 - -/* PCFG : Pin Configuration */ -#define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 -#define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) - -/* CLKCTR : Clock Control */ -#define TX4927_CLKCTR_PCICKD 0x00400000 -#define TX4927_CLKCTR_PCIRST 0x00000040 - - -#ifndef _LANGUAGE_ASSEMBLY - -#define tx4927_sdramcptr ((struct tx4927_sdramc_reg *)TX4927_SDRAMC_REG) -#define tx4927_pcicptr ((struct tx4927_pcic_reg *)TX4927_PCIC_REG) -#define tx4927_ccfgptr ((struct tx4927_ccfg_reg *)TX4927_CCFG_REG) -#define tx4927_ebuscptr ((struct tx4927_ebusc_reg *)TX4927_EBUSC_REG) - -#endif /* _LANGUAGE_ASSEMBLY */ - -#endif /* __ASM_TX4927_TX4927_PCI_H */ -- cgit v0.10.2 From b012cffe7f6971e9ba5afca034a3d80e1cf1435c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [MIPS] Replace use of print_symbol with new %sP pointer format. Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index 640fb0c..d01665a 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -4,7 +4,6 @@ */ #include -#include #include #include #include @@ -84,9 +83,9 @@ void mips_mt_regdump(unsigned long mvpctl) read_vpe_c0_vpeconf0()); printk(" VPE%d.Status : %08lx\n", i, read_vpe_c0_status()); - printk(" VPE%d.EPC : %08lx ", - i, read_vpe_c0_epc()); - print_symbol("%s\n", read_vpe_c0_epc()); + printk(" VPE%d.EPC : %08lx %pS\n", + i, read_vpe_c0_epc(), + (void *) read_vpe_c0_epc()); printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); printk(" VPE%d.Config7 : %08lx\n", @@ -111,8 +110,8 @@ void mips_mt_regdump(unsigned long mvpctl) } printk(" TCStatus : %08lx\n", tcstatval); printk(" TCBind : %08lx\n", read_tc_c0_tcbind()); - printk(" TCRestart : %08lx ", read_tc_c0_tcrestart()); - print_symbol("%s\n", read_tc_c0_tcrestart()); + printk(" TCRestart : %08lx %pS\n", + read_tc_c0_tcrestart(), (void *) read_tc_c0_tcrestart()); printk(" TCHalt : %08lx\n", haltval); printk(" TCContext : %08lx\n", read_tc_c0_tccontext()); if (!haltval) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6e7e4a2..b8ea4e9 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -248,11 +248,11 @@ static void __show_regs(const struct pt_regs *regs) /* * Saved cp0 registers */ - printk("epc : %0*lx ", field, regs->cp0_epc); - print_symbol("%s ", regs->cp0_epc); + printk("epc : %0*lx %pS\n", field, regs->cp0_epc, + (void *) regs->cp0_epc); printk(" %s\n", print_tainted()); - printk("ra : %0*lx ", field, regs->regs[31]); - print_symbol("%s\n", regs->regs[31]); + printk("ra : %0*lx %pS\n", field, regs->regs[31], + (void *) regs->regs[31]); printk("Status: %08x ", (uint32_t) regs->cp0_status); diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c index b0a25e1..64459e7 100644 --- a/arch/mips/sgi-ip27/ip27-nmi.c +++ b/arch/mips/sgi-ip27/ip27-nmi.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -84,13 +83,10 @@ void nmi_cpu_eframe_save(nasid_t nasid, int slice) /* * Saved cp0 registers */ - printk("epc : %016lx ", nr->epc); - print_symbol("%s ", nr->epc); + printk("epc : %016lx %pS\n", nr->epc, (void *) nr->epc); printk("%s\n", print_tainted()); - printk("ErrEPC: %016lx ", nr->error_epc); - print_symbol("%s\n", nr->error_epc); - printk("ra : %016lx ", nr->gpr[31]); - print_symbol("%s\n", nr->gpr[31]); + printk("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc); + printk("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]); printk("Status: %08lx ", nr->sr); if (nr->sr & ST0_KX) -- cgit v0.10.2 From 74c8494eeb7b321e5922ee43120f91c7c9b7317f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [MIPS] Bigsur: Make defconfig a bit more useful. Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 3b42cea..2b4ad5f 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc7 -# Mon Mar 31 08:11:19 2008 +# Linux kernel version: 2.6.26-rc8 +# Wed Jul 2 17:02:55 2008 # CONFIG_MIPS=y @@ -148,6 +148,7 @@ 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_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=0 @@ -156,6 +157,7 @@ CONFIG_SMP=y CONFIG_SYS_SUPPORTS_SMP=y CONFIG_NR_CPUS_DEFAULT_4=y CONFIG_NR_CPUS=4 +# CONFIG_MIPS_CMP is not set CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -223,6 +225,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y @@ -241,12 +244,14 @@ CONFIG_SLAB=y CONFIG_HAVE_OPROFILE=y # 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=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_MODVERSIONS=y @@ -302,7 +307,6 @@ CONFIG_BINFMT_ELF32=y # Power management options # CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # @@ -399,9 +403,11 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y +# CONFIG_IPV6_MROUTE is not set CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -600,7 +606,7 @@ CONFIG_BLK_DEV_IT8213=m CONFIG_BLK_DEV_TC86C001=m # CONFIG_BLK_DEV_IDE_SWARM is not set CONFIG_BLK_DEV_IDEDMA=y -CONFIG_IDE_ARCH_OBSOLETE_INIT=y +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_DEV_HD is not set # @@ -617,11 +623,12 @@ CONFIG_SCSI_PROC_FS=y # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set +CONFIG_CHR_DEV_ST=m # CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -650,6 +657,7 @@ CONFIG_SCSI_LOWLEVEL=y # 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 @@ -675,7 +683,10 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_SRP is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y # CONFIG_SATA_AHCI is not set +CONFIG_SATA_SIL24=y +CONFIG_ATA_SFF=y # CONFIG_SATA_SVW is not set # CONFIG_ATA_PIIX is not set # CONFIG_SATA_MV is not set @@ -685,7 +696,6 @@ CONFIG_ATA=y # CONFIG_SATA_PROMISE is not set # CONFIG_SATA_SX4 is not set # CONFIG_SATA_SIL is not set -CONFIG_SATA_SIL24=y # CONFIG_SATA_SIS is not set # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set @@ -730,12 +740,17 @@ CONFIG_PATA_SIL680=y # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_SCH is not set # CONFIG_MD is not set # CONFIG_FUSION 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 @@ -797,7 +812,6 @@ CONFIG_SB1250_MAC=y # 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 @@ -815,6 +829,7 @@ CONFIG_NETXEN_NIC=m # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_SFC is not set # CONFIG_TR is not set # @@ -822,6 +837,7 @@ CONFIG_NETXEN_NIC=m # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -867,6 +883,7 @@ CONFIG_SERIO_RAW=m # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -903,7 +920,6 @@ CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set @@ -914,13 +930,6 @@ CONFIG_I2C_BOARDINFO=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 @@ -946,6 +955,7 @@ CONFIG_I2C_SIBYTE=y # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_PLATFORM is not set # # Miscellaneous I2C Chip support @@ -955,23 +965,18 @@ CONFIG_SENSORS_EEPROM=y CONFIG_SENSORS_PCF8574=y # CONFIG_PCF8575 is not set CONFIG_SENSORS_PCF8591=y -# CONFIG_TPS65010 is not set CONFIG_SENSORS_MAX6875=y # CONFIG_SENSORS_TSL2550 is not set CONFIG_I2C_DEBUG_CORE=y CONFIG_I2C_DEBUG_ALGO=y CONFIG_I2C_DEBUG_BUS=y CONFIG_I2C_DEBUG_CHIP=y - -# -# 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 # @@ -984,12 +989,22 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 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 # @@ -1015,6 +1030,8 @@ 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 # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -1023,13 +1040,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y # 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 is not set - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -1123,7 +1137,6 @@ CONFIG_NFS_FS=y 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_ROOT_NFS=y CONFIG_LOCKD=y @@ -1194,6 +1207,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y # 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 @@ -1204,6 +1218,7 @@ CONFIG_DETECT_SOFTLOCKUP=y 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 @@ -1217,6 +1232,7 @@ CONFIG_DEBUG_MUTEXES=y # 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_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_BOOT_PRINTK_DELAY is not set @@ -1237,53 +1253,82 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y + +# +# Crypto core or helper +# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=y + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CCM=m -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -# CONFIG_CRYPTO_CRC32C is not set -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_AUTHENC=m # CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set @@ -1292,9 +1337,10 @@ CONFIG_CRYPTO_HW=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m -- cgit v0.10.2 From 372a775f50347f5c1dd87752b16e5c05ea965790 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [MIPS] Enable -ffunction-sections sections. -ffunction-sections serves as a workaround for the problems caused by the limited branch range in some inline assembler fragments for very large compilation units. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ad36c94..0b8d82d 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -14,7 +14,7 @@ KBUILD_DEFCONFIG := ip22_defconfig -cflags-y := +cflags-y := -ffunction-sections # # Select the object file format to substitute into the linker script. -- cgit v0.10.2 From 2157bc68711bf0e69f9aca4d310bd863298fbb3f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [MIPS] Atlas: Remove support code. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 21d6ec1..6383c70 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -181,38 +181,6 @@ config LEMOTE_FULONG Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and an FPGA northbridge -config MIPS_ATLAS - bool "MIPS Atlas board" - select BOOT_ELF32 - select BOOT_RAW - select CEVT_R4K - select CSRC_R4K - select DMA_NONCOHERENT - select SYS_HAS_EARLY_PRINTK - select IRQ_CPU - select HW_HAS_PCI - select MIPS_BOARDS_GEN - select MIPS_BONITO64 - select PCI_GT64XXX_PCI0 - select MIPS_MSC - select RM7000_CPU_SCACHE - select SWAP_IO_SPACE - select SYS_HAS_CPU_MIPS32_R1 - select SYS_HAS_CPU_MIPS32_R2 - select SYS_HAS_CPU_MIPS64_R1 - select SYS_HAS_CPU_NEVADA - select SYS_HAS_CPU_RM7000 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL - select SYS_SUPPORTS_SMARTMIPS - select GENERIC_HARDIRQS_NO__DO_IRQ - help - This enables support for the MIPS Technologies Atlas evaluation - board. - config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0b8d82d..9bc2c76 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -310,15 +310,6 @@ cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote core-$(CONFIG_MIPS_BOARDS_GEN) += arch/mips/mips-boards/generic/ # -# MIPS Atlas board -# -core-$(CONFIG_MIPS_ATLAS) += arch/mips/mips-boards/atlas/ -cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-atlas -cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-mips -load-$(CONFIG_MIPS_ATLAS) += 0xffffffff80100000 -all-$(CONFIG_MIPS_ATLAS) := vmlinux.bin - -# # MIPS Malta board # core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/ diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig deleted file mode 100644 index 3443f6c..0000000 --- a/arch/mips/configs/atlas_defconfig +++ /dev/null @@ -1,1472 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Sun Feb 18 21:27:35 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_ATLAS=y -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD 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 is not set -# 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=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_MIPS_BONITO64=y -CONFIG_MIPS_MSC=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_MIPS_BOARDS_GEN=y -CONFIG_MIPS_GT64120=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_BOOT_ELF32=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -CONFIG_CPU_MIPS32_R1=y -# 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 is not set -# 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_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_CPU_MIPS64_R1=y -CONFIG_SYS_HAS_CPU_NEVADA=y -CONFIG_SYS_HAS_CPU_RM7000=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_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_BOARD_SCACHE=y -CONFIG_RM7000_CPU_SCACHE=y -CONFIG_CPU_HAS_PREFETCH=y -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_SYS_SUPPORTS_MULTITHREADING=y -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -# CONFIG_CPU_HAS_SMARTMIPS is not set -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_SMARTMIPS=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=y -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=100 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# 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_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 is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -# 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 is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# 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=m -# 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=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -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=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -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=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -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_NF_CT_NETLINK=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_PHYSDEV=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=m -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 is not set -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=m -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 - -# -# Bridge: Netfilter Configuration -# -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_ULOG=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=m -CONFIG_VLAN_8021Q=m -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y -# 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=y -CONFIG_NET_SCH_FIFO=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_INGRESS=m - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_POLICE=y -CONFIG_NET_CLS_IND=y -CONFIG_NET_ESTIMATOR=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=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_WIRELESS_EXT=y -CONFIG_FIB_RULES=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=m - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# 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=m -# 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_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m - -# -# Misc devices -# -CONFIG_SGI_IOC4=m -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_BLK_DEV_IDEPCI is not set -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=y -CONFIG_SCSI_TGT=m -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=m -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=m -CONFIG_CHR_DEV_SCH=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y -CONFIG_SCSI_SCAN_ASYNC=y - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y -CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_SAS_ATTRS=m -CONFIG_SCSI_SAS_LIBSAS=m -CONFIG_SCSI_SAS_LIBSAS_DEBUG=y - -# -# SCSI low-level drivers -# -CONFIG_ISCSI_TCP=m -# 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=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y -# 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=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_RAID5_RESHAPE=y -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -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=m -CONFIG_DM_MULTIPATH_EMC=m - -# -# 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=m -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY 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=y -# 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_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# 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_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_LAN_SAA9730=y -# 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 is not set -# CONFIG_SLIP is not set -# 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=m -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_TSDEV 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=y -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_SERIAL=m -# CONFIG_MOUSE_VSXXXAA 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=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_RAW=y -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=m -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 is not set -# 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 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 is not set -# CONFIG_HWMON_VID 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 - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG 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 is not set -# CONFIG_EXT2_FS_XIP is not set -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_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -CONFIG_JFS_FS=m -CONFIG_JFS_POSIX_ACL=y -CONFIG_JFS_SECURITY=y -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_XFS_FS=m -CONFIG_XFS_QUOTA=y -CONFIG_XFS_SECURITY=y -CONFIG_XFS_POSIX_ACL=y -# CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=m -CONFIG_ROMFS_FS=m -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=y -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m -CONFIG_GENERIC_ACL=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS 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=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_CRAMFS=m -CONFIG_VXFS_FS=m -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set - -# -# 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_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_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS 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=m -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -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=m -CONFIG_NLS_ISO8859_1=m -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 - -# -# 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="" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -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_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=m -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -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 --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index c0e42e7..10d83e4 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -16,7 +16,6 @@ CONFIG_BCM47XX=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index 2b4ad5f..a992686 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index a94f14b..ee8a7fc 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index b7295e9..ce31a47 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 3657896..f99b6f8 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 5a90740..0d6ba9e 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 76f37a1..0c6f2a4 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 508c919..02db28f 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index 0c2c70d..a0f19f2 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 58c2cd6..c1ab8a2 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set CONFIG_MACH_DECSTATION=y # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 90d81f5..88c2420 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index f9a003c..03f0baa 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index 15efacc..873597a 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -27,7 +27,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig index 5887a17..13e1ef2 100644 --- a/arch/mips/configs/fulong_defconfig +++ b/arch/mips/configs/fulong_defconfig @@ -14,7 +14,6 @@ CONFIG_LEMOTE_FULONG=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 4f5e56c..7daf203 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -15,7 +15,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index f40e437..83d769f 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig index ec188be..3c5090a 100644 --- a/arch/mips/configs/ip28_defconfig +++ b/arch/mips/configs/ip28_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 2c5c624..f8d1cf3 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 5614874..72ff710 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set CONFIG_MACH_JAZZ=y -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index a7cd677..8dc8bef 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig index e6aef99..a8fa205 100644 --- a/arch/mips/configs/lasat_defconfig +++ b/arch/mips/configs/lasat_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set CONFIG_LASAT=y # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 3d0da95..9a8ed74 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -15,7 +15,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set CONFIG_MIPS_MALTA=y # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 4f6bce9..1d20544 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set CONFIG_MIPS_SIM=y diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 27e23fc..0c7f35a 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index b12b73f..2dd2a4f 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index fa3aa39..17d6652 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -14,7 +14,6 @@ CONFIG_MACH_ALCHEMY=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 1d0157d..eaf608c 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index d0491a0..62c5a70 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 16d78d3..29c8548 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -27,7 +27,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 780c7fc..c714f43 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index 267f21e..c1adcfa 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index 470f6f4..9e10836 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 5a39f56..462a652 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 56371b8..2562f35 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 4b87998..ff89765 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index 3ee75b1..d3db59b 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set CONFIG_MIPS_SEAD=y # CONFIG_WR_PPMC is not set diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index 8dd3ae3..34ce11d 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index 2ba240e..e5ae6b1 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index a5d0f3c..2fdfd66 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index edf90b3..ee41121 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -14,7 +14,6 @@ CONFIG_MIPS=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 2e3c683..66d3c11 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set CONFIG_WR_PPMC=y diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index b6178ff..daa4e48 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -26,7 +26,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set diff --git a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile deleted file mode 100644 index f71c2dd..0000000 --- a/arch/mips/mips-boards/atlas/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# - -obj-y := atlas_int.o atlas_setup.o -obj-$(CONFIG_KGDB) += atlas_gdb.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mips-boards/atlas/atlas_gdb.c b/arch/mips/mips-boards/atlas/atlas_gdb.c deleted file mode 100644 index 00c98cf..0000000 --- a/arch/mips/mips-boards/atlas/atlas_gdb.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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 is the interface to the remote debugger stub. - */ -#include -#include -#include - -#define INB(a) inb((unsigned long)a) -#define OUTB(x, a) outb(x, (unsigned long)a) - -/* - * This is the interface to the remote debugger stub - * if the Philips part is used for the debug port, - * called from the platform setup code. - */ -void *saa9730_base = (void *)ATLAS_SAA9730_REG; - -static int saa9730_kgdb_active = 0; - -#define SAA9730_BAUDCLOCK(baud) (((ATLAS_SAA9730_BAUDCLOCK/(baud))/16)-1) - -int saa9730_kgdb_hook(int speed) -{ - int baudclock; - t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); - - /* - * Clear all interrupts - */ - (void) INB(&kgdb_uart->Lsr); - (void) INB(&kgdb_uart->Msr); - (void) INB(&kgdb_uart->Thr_Rbr); - (void) INB(&kgdb_uart->Iir_Fcr); - - /* - * Now, initialize the UART - */ - /* 8 data bits, one stop bit, no parity */ - OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr); - - baudclock = SAA9730_BAUDCLOCK(speed); - - OUTB((baudclock >> 16) & 0xff, &kgdb_uart->BaudDivMsb); - OUTB( baudclock & 0xff, &kgdb_uart->BaudDivLsb); - - /* Set RTS/DTR active */ - OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr); - saa9730_kgdb_active = 1; - - return speed; -} - -int saa9730_putDebugChar(char c) -{ - t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); - - if (!saa9730_kgdb_active) { /* need to init device first */ - return 0; - } - - while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE)) - ; - OUTB(c, &kgdb_uart->Thr_Rbr); - - return 1; -} - -char saa9730_getDebugChar(void) -{ - t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); - char c; - - if (!saa9730_kgdb_active) { /* need to init device first */ - return 0; - } - while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR)) - ; - - c = INB(&kgdb_uart->Thr_Rbr); - return(c); -} diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c deleted file mode 100644 index 6fb29c3..0000000 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * ######################################################################## - * - * Routines for generic manipulation of the interrupts found on the MIPS - * Atlas board. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -static struct atlas_ictrl_regs *atlas_hw0_icregs; - -#if 0 -#define DEBUG_INT(x...) printk(x) -#else -#define DEBUG_INT(x...) -#endif - -void disable_atlas_irq(unsigned int irq_nr) -{ - atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE); - iob(); -} - -void enable_atlas_irq(unsigned int irq_nr) -{ - atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE); - iob(); -} - -static void end_atlas_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_atlas_irq(irq); -} - -static struct irq_chip atlas_irq_type = { - .name = "Atlas", - .ack = disable_atlas_irq, - .mask = disable_atlas_irq, - .mask_ack = disable_atlas_irq, - .unmask = enable_atlas_irq, - .eoi = enable_atlas_irq, - .end = end_atlas_irq, -}; - -static inline int ls1bit32(unsigned int x) -{ - int b = 31, s; - - s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; - s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; - s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; - s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; - s = 1; if (x << 1 == 0) s = 0; b -= s; - - return b; -} - -static inline void atlas_hw0_irqdispatch(void) -{ - unsigned long int_status; - int irq; - - int_status = atlas_hw0_icregs->intstatus; - - /* if int_status == 0, then the interrupt has already been cleared */ - if (unlikely(int_status == 0)) - return; - - irq = ATLAS_INT_BASE + ls1bit32(int_status); - - DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); - - do_IRQ(irq); -} - -static inline int clz(unsigned long x) -{ - __asm__( - " .set push \n" - " .set mips32 \n" - " clz %0, %1 \n" - " .set pop \n" - : "=r" (x) - : "r" (x)); - - return x; -} - -/* - * Version of ffs that only looks at bits 12..15. - */ -static inline unsigned int irq_ffs(unsigned int pending) -{ -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - return -clz(pending) + 31 - CAUSEB_IP; -#else - unsigned int a0 = 7; - unsigned int t0; - - t0 = s0 & 0xf000; - t0 = t0 < 1; - t0 = t0 << 2; - a0 = a0 - t0; - s0 = s0 << t0; - - t0 = s0 & 0xc000; - t0 = t0 < 1; - t0 = t0 << 1; - a0 = a0 - t0; - s0 = s0 << t0; - - t0 = s0 & 0x8000; - t0 = t0 < 1; - //t0 = t0 << 2; - a0 = a0 - t0; - //s0 = s0 << t0; - - return a0; -#endif -} - -/* - * IRQs on the Atlas board look basically like (all external interrupt - * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)): - * - * MIPS IRQ Source - * -------- ------ - * 0 Software 0 (reschedule IPI on MT) - * 1 Software 1 (remote call IPI on MT) - * 2 Combined Atlas hardware interrupt (hw0) - * 3 Hardware (ignored) - * 4 Hardware (ignored) - * 5 Hardware (ignored) - * 6 Hardware (ignored) - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Lowest ---- Software 0 - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - irq = irq_ffs(pending); - - if (irq == MIPSCPU_INT_ATLAS) - atlas_hw0_irqdispatch(); - else if (irq >= 0) - do_IRQ(MIPS_CPU_IRQ_BASE + irq); - else - spurious_interrupt(); -} - -static inline void init_atlas_irqs(int base) -{ - int i; - - atlas_hw0_icregs = (struct atlas_ictrl_regs *) - ioremap(ATLAS_ICTRL_REGS_BASE, - sizeof(struct atlas_ictrl_regs *)); - - /* - * Mask out all interrupt by writing "1" to all bit position in - * the interrupt reset reg. - */ - atlas_hw0_icregs->intrsten = 0xffffffff; - - for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) - set_irq_chip_and_handler(i, &atlas_irq_type, handle_level_irq); -} - -static struct irqaction atlasirq = { - .handler = no_action, - .name = "Atlas cascade" -}; - -msc_irqmap_t __initdata msc_irqmap[] = { - {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, -}; -int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap); - -msc_irqmap_t __initdata msc_eicirqmap[] = { - {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_ATLAS, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} -}; -int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); - -void __init arch_init_irq(void) -{ - init_atlas_irqs(ATLAS_INT_BASE); - - if (!cpu_has_veic) - mips_cpu_irq_init(); - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_FPGA4: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: - if (cpu_has_veic) - init_msc_irqs(MSC01E_INT_BASE, MSC01E_INT_BASE, - msc_eicirqmap, msc_nr_eicirqs); - else - init_msc_irqs(MSC01E_INT_BASE, MSC01C_INT_BASE, - msc_irqmap, msc_nr_irqs); - } - - if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_ATLAS, atlas_hw0_irqdispatch); - setup_irq(MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq); - } else if (cpu_has_vint) { - set_vi_handler(MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch); -#ifdef CONFIG_MIPS_MT_SMTC - setup_irq_smtc(MIPS_CPU_IRQ_BASE + MIPSCPU_INT_ATLAS, - &atlasirq, (0x100 << MIPSCPU_INT_ATLAS)); -#else /* Not SMTC */ - setup_irq(MIPS_CPU_IRQ_BASE + MIPSCPU_INT_ATLAS, &atlasirq); -#endif /* CONFIG_MIPS_MT_SMTC */ - } else - setup_irq(MIPS_CPU_IRQ_BASE + MIPSCPU_INT_ATLAS, &atlasirq); -} diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c deleted file mode 100644 index 5c50080..0000000 --- a/arch/mips/mips-boards/atlas/atlas_setup.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void __init serial_init(void); - -const char *get_system_type(void) -{ - return "MIPS Atlas"; -} - -const char display_string[] = " LINUX ON ATLAS "; - -void __init plat_mem_setup(void) -{ - mips_pcibios_init(); - - ioport_resource.end = 0x7fffffff; - - serial_init(); - -#ifdef CONFIG_KGDB - kgdb_config(); -#endif - mips_reboot_setup(); -} - -static void __init serial_init(void) -{ -#ifdef CONFIG_SERIAL_8250 - struct uart_port s; - - memset(&s, 0, sizeof(s)); - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - s.iobase = ATLAS_UART_REGS_BASE; -#else - s.iobase = ATLAS_UART_REGS_BASE+3; -#endif - s.irq = ATLAS_INT_UART; - s.uartclk = ATLAS_BASE_BAUD * 16; - s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; - s.iotype = UPIO_PORT; - s.regshift = 3; - - if (early_serial_setup(&s) != 0) { - printk(KERN_ERR "Serial setup failed!\n"); - } -#endif -} diff --git a/arch/mips/mips-boards/generic/console.c b/arch/mips/mips-boards/generic/console.c index 4d8ab99..4a2aecc 100644 --- a/arch/mips/mips-boards/generic/console.c +++ b/arch/mips/mips-boards/generic/console.c @@ -22,16 +22,7 @@ #include #include -#ifdef CONFIG_MIPS_ATLAS -#include - -#ifdef CONFIG_CPU_LITTLE_ENDIAN -#define PORT(offset) (ATLAS_UART_REGS_BASE + ((offset)<<3)) -#else -#define PORT(offset) (ATLAS_UART_REGS_BASE + 3 + ((offset)<<3)) -#endif - -#elif defined(CONFIG_MIPS_SEAD) +#if defined(CONFIG_MIPS_SEAD) #include diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index 83b9dc7..bac23b5 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c @@ -197,14 +197,6 @@ void __init kgdb_config(void) while ((c = *++argptr) && ('0' <= c && c <= '9')) speed = speed * 10 + c - '0'; } -#ifdef CONFIG_MIPS_ATLAS - if (line == 1) { - speed = saa9730_kgdb_hook(speed); - generic_putDebugChar = saa9730_putDebugChar; - generic_getDebugChar = saa9730_getDebugChar; - } - else -#endif { speed = rs_kgdb_hook(line, speed); generic_putDebugChar = rs_putDebugChar; diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c index 583d468..5f73ff6 100644 --- a/arch/mips/mips-boards/generic/reset.c +++ b/arch/mips/mips-boards/generic/reset.c @@ -27,15 +27,9 @@ #include #include #include -#if defined(CONFIG_MIPS_ATLAS) -#include -#endif static void mips_machine_restart(char *command); static void mips_machine_halt(void); -#if defined(CONFIG_MIPS_ATLAS) -static void atlas_machine_power_off(void); -#endif static void mips_machine_restart(char *command) { @@ -53,22 +47,11 @@ static void mips_machine_halt(void) __raw_writel(GORESET, softres_reg); } -#if defined(CONFIG_MIPS_ATLAS) -static void atlas_machine_power_off(void) -{ - unsigned int __iomem *psustby_reg = ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int)); - - writew(ATLAS_GOSTBY, psustby_reg); -} -#endif void mips_reboot_setup(void) { _machine_restart = mips_machine_restart; _machine_halt = mips_machine_halt; -#if defined(CONFIG_MIPS_ATLAS) - pm_power_off = atlas_machine_power_off; -#endif #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD) pm_power_off = mips_machine_halt; #endif diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index fe2cac1..d224267 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -42,9 +42,6 @@ #include #include -#ifdef CONFIG_MIPS_ATLAS -#include -#endif #ifdef CONFIG_MIPS_MALTA #include #endif @@ -89,7 +86,7 @@ static unsigned int __init estimate_cpu_frequency(void) else count = 6000000; #endif -#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) +#ifdef CONFIG_MIPS_MALTA unsigned long flags; unsigned int start; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index ed0c076..80fa5ab 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o # obj-$(CONFIG_BASLER_EXCITE) += ops-titan.o pci-excite.o fixup-excite.o obj-$(CONFIG_LASAT) += pci-lasat.o -obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c deleted file mode 100644 index 506e883..0000000 --- a/arch/mips/pci/fixup-atlas.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. - * Author: Maciej W. Rozycki - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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 -#include - -#include - -#define PCIA ATLAS_INT_PCIA -#define PCIB ATLAS_INT_PCIB -#define PCIC ATLAS_INT_PCIC -#define PCID ATLAS_INT_PCID -#define INTA ATLAS_INT_INTA -#define INTB ATLAS_INT_INTB -#define ETH ATLAS_INT_ETH -#define INTC ATLAS_INT_INTC -#define SCSI ATLAS_INT_SCSI -#define INTD ATLAS_INT_INTD - -static char irq_tab[][5] __initdata = { - /* INTA INTB INTC INTD */ - {0, 0, 0, 0, 0 }, /* 0: Unused */ - {0, 0, 0, 0, 0 }, /* 1: Unused */ - {0, 0, 0, 0, 0 }, /* 2: Unused */ - {0, 0, 0, 0, 0 }, /* 3: Unused */ - {0, 0, 0, 0, 0 }, /* 4: Unused */ - {0, 0, 0, 0, 0 }, /* 5: Unused */ - {0, 0, 0, 0, 0 }, /* 6: Unused */ - {0, 0, 0, 0, 0 }, /* 7: Unused */ - {0, 0, 0, 0, 0 }, /* 8: Unused */ - {0, 0, 0, 0, 0 }, /* 9: Unused */ - {0, 0, 0, 0, 0 }, /* 10: Unused */ - {0, 0, 0, 0, 0 }, /* 11: Unused */ - {0, 0, 0, 0, 0 }, /* 12: Unused */ - {0, 0, 0, 0, 0 }, /* 13: Unused */ - {0, 0, 0, 0, 0 }, /* 14: Unused */ - {0, PCIA, PCIB, PCIC, PCID }, /* 15: cPCI (behind 21150) */ - {0, SCSI, 0, 0, 0 }, /* 16: SYM53C810A SCSI */ - {0, 0, 0, 0, 0 }, /* 17: Core */ - {0, INTA, INTB, INTC, INTD }, /* 18: PCI Slot */ - {0, ETH, 0, 0, 0 }, /* 19: SAA9730 Eth. et al. */ - {0, 0, 0, 0, 0 }, /* 20: Unused */ - {0, 0, 0, 0, 0 } /* 21: Unused */ -}; - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - return irq_tab[slot][pin]; -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} - -#ifdef CONFIG_KGDB -/* - * The PCI scan may have moved the saa9730 I/O address, so reread - * the address here. - * This does mean that it's not possible to debug the PCI bus configuration - * code, but it is better than nothing... - */ - -static void atlas_saa9730_base_fixup(struct pci_dev *pdev) -{ - extern void *saa9730_base; - if (pdev->bus == 0 && PCI_SLOT(pdev->devfn) == 19) - (void) pci_read_config_dword(pdev, 0x14, (u32 *)&saa9730_base); - printk("saa9730_base = %x\n", saa9730_base); -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730, - atlas_saa9730_base_fixup); - -#endif diff --git a/include/asm-mips/mach-atlas/mc146818rtc.h b/include/asm-mips/mach-atlas/mc146818rtc.h deleted file mode 100644 index 51d337e..0000000 --- a/include/asm-mips/mach-atlas/mc146818rtc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2005 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki - * Copyright (C) 2003, 05 Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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_MACH_ATLAS_MC146818RTC_H -#define __ASM_MACH_ATLAS_MC146818RTC_H - -#include - -#include - -#include -#include - -#define ARCH_RTC_LOCATION - -#define RTC_PORT(x) (ATLAS_RTC_ADR_REG + (x) * 8) -#define RTC_IO_EXTENT 0x100 -#define RTC_IOMAPPED 0 -#define RTC_IRQ ATLAS_INT_RTC - -static inline unsigned char CMOS_READ(unsigned long addr) -{ - volatile u32 *ireg = (void *)CKSEG1ADDR(RTC_PORT(0)); - volatile u32 *dreg = (void *)CKSEG1ADDR(RTC_PORT(1)); - - *ireg = addr; - return *dreg; -} - -static inline void CMOS_WRITE(unsigned char data, unsigned long addr) -{ - volatile u32 *ireg = (void *)CKSEG1ADDR(RTC_PORT(0)); - volatile u32 *dreg = (void *)CKSEG1ADDR(RTC_PORT(1)); - - *ireg = addr; - *dreg = data; -} - -#define RTC_ALWAYS_BCD 0 - -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) - -#endif /* __ASM_MACH_ATLAS_MC146818RTC_H */ -- cgit v0.10.2 From 1398ddb2ebdb41e8efe6ba42505fd452704c8405 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:33 +0100 Subject: [MIPS] SEAD: Remove support code. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6383c70..a038142 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -217,26 +217,6 @@ config MIPS_MALTA This enables support for the MIPS Technologies Malta evaluation board. -config MIPS_SEAD - bool "MIPS SEAD board" - select CEVT_R4K - select CSRC_R4K - select IRQ_CPU - select DMA_NONCOHERENT - select SYS_HAS_EARLY_PRINTK - select MIPS_BOARDS_GEN - select SYS_HAS_CPU_MIPS32_R1 - select SYS_HAS_CPU_MIPS32_R2 - select SYS_HAS_CPU_MIPS64_R1 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_SMARTMIPS - help - This enables support for the MIPS Technologies SEAD evaluation - board. - config MIPS_SIM bool 'MIPS simulator (MIPSsim)' select CEVT_R4K diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9bc2c76..800a73d 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -318,14 +318,6 @@ load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 all-$(CONFIG_MIPS_MALTA) := vmlinux.bin # -# MIPS SEAD board -# -core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/ -cflags-$(CONFIG_MIPS_SEAD) += -Iinclude/asm-mips/mach-mips -load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000 -all-$(CONFIG_MIPS_SEAD) := vmlinux.srec - -# # MIPS SIM # core-$(CONFIG_MIPS_SIM) += arch/mips/mipssim/ diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 10d83e4..d869433 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -17,7 +17,6 @@ CONFIG_BCM47XX=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index a992686..a3bbbf0 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index ee8a7fc..185df23 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index ce31a47..2678b7e 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS_COBALT=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index f99b6f8..ebb8ad6 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 0d6ba9e..ad4e5ef 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 0c6f2a4..d0dc2e8 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 02db28f..9155082 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index a0f19f2..e4e3244 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index c1ab8a2..9e65e6a 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y CONFIG_MACH_DECSTATION=y # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 88c2420..1bd84d4 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index 03f0baa..634bb4e 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index 873597a..3572e80 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -28,7 +28,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig index 13e1ef2..6209800 100644 --- a/arch/mips/configs/fulong_defconfig +++ b/arch/mips/configs/fulong_defconfig @@ -15,7 +15,6 @@ CONFIG_LEMOTE_FULONG=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_PNX8550_JBS is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 7daf203..cc8e6bf 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -16,7 +16,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 83d769f..138c575 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig index 3c5090a..822b01f 100644 --- a/arch/mips/configs/ip28_defconfig +++ b/arch/mips/configs/ip28_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index f8d1cf3..fe4699d 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 72ff710..bbacc35 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set CONFIG_MACH_JAZZ=y # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 8dc8bef..92000a3 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig index a8fa205..bc9159f 100644 --- a/arch/mips/configs/lasat_defconfig +++ b/arch/mips/configs/lasat_defconfig @@ -16,7 +16,6 @@ CONFIG_MIPS=y CONFIG_LASAT=y # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 9a8ed74..55288cf 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -16,7 +16,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set CONFIG_MIPS_MALTA=y -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 1d20544..2c0a631 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set CONFIG_MIPS_SIM=y # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 0c7f35a..8c720e5 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig index 2dd2a4f..59d1947 100644 --- a/arch/mips/configs/msp71xx_defconfig +++ b/arch/mips/configs/msp71xx_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 17d6652..bacf0dd 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -15,7 +15,6 @@ CONFIG_MACH_ALCHEMY=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index eaf608c..6dfe6f7 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index 62c5a70..c965a87 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 29c8548..0778996 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -28,7 +28,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index c714f43..37c7b5f 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index c1adcfa..893e5c4 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index 9e10836..f89482a 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 462a652..70cf697 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index 2562f35..0f4da03 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index ff89765..1ea9786 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set # CONFIG_MACH_VR41XX is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig deleted file mode 100644 index d3db59b..0000000 --- a/arch/mips/configs/sead_defconfig +++ /dev/null @@ -1,641 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Sun Feb 18 21:28:10 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_MIPS_SEAD=y -# 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 is not set -# 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 is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_MIPS_BOARDS_GEN=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -CONFIG_CPU_MIPS32_R1=y -# 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 is not set -# 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_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_CPU_MIPS64_R1=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_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_CPU_HAS_PREFETCH=y -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_SMARTMIPS is not set -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_SMARTMIPS=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=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# 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_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_UTS_NS is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -CONFIG_INITRAMFS_SOURCE="" -# 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 is not set -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 is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# 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_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# - -# -# 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 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=18432 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set - -# -# Misc devices -# - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=y -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK 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 - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# ISDN subsystem -# - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT 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_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_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 is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C 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 is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# - -# -# 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 - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI 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 -# - -# -# 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 is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_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_XFS_FS is not set -# CONFIG_GFS2_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=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=y - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# 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_CRAMFS is not set -# 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 - -# -# 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 is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS 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="" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=y -# CONFIG_CRC32 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig index 34ce11d..b505988 100644 --- a/arch/mips/configs/tb0219_defconfig +++ b/arch/mips/configs/tb0219_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index e5ae6b1..b06a716 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index 2fdfd66..46512cf 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -17,7 +17,6 @@ CONFIG_MIPS=y # CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index ee41121..b437eb7 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -15,7 +15,6 @@ CONFIG_MIPS=y # CONFIG_MACH_JAZZ is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_MIPS_SIM is not set # CONFIG_MARKEINS is not set CONFIG_MACH_VR41XX=y diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 66d3c11..fc2c567 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set CONFIG_WR_PPMC=y # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index daa4e48..7f86c43 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -27,7 +27,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set # CONFIG_WR_PPMC is not set # CONFIG_MIPS_SIM is not set # CONFIG_MOMENCO_JAGUAR_ATX is not set diff --git a/arch/mips/mips-boards/generic/console.c b/arch/mips/mips-boards/generic/console.c index 4a2aecc..43bcfb4 100644 --- a/arch/mips/mips-boards/generic/console.c +++ b/arch/mips/mips-boards/generic/console.c @@ -22,21 +22,9 @@ #include #include -#if defined(CONFIG_MIPS_SEAD) - -#include - -#ifdef CONFIG_CPU_LITTLE_ENDIAN -#define PORT(offset) (SEAD_UART0_REGS_BASE + ((offset)<<3)) -#else -#define PORT(offset) (SEAD_UART0_REGS_BASE + 3 + ((offset)<<3)) -#endif - -#else #define PORT(offset) (0x3f8 + (offset)) -#endif static inline unsigned int serial_in(int offset) { diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index bac23b5..c065302 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c @@ -252,9 +252,6 @@ void __init prom_init(void) mips_display_message("LINUX"); -#ifdef CONFIG_MIPS_SEAD - set_io_port_base(KSEG1); -#else /* * early setup of _pcictrl_bonito so that we can determine * the system controller on a CORE_EMUL board @@ -406,7 +403,6 @@ void __init prom_init(void) mips_display_message("SC Error"); while (1); /* We die here... */ } -#endif board_nmi_handler_setup = mips_nmi_setup; board_ejtag_handler_setup = mips_ejtag_setup; diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c index 5f73ff6..ea932b8 100644 --- a/arch/mips/mips-boards/generic/reset.c +++ b/arch/mips/mips-boards/generic/reset.c @@ -52,7 +52,7 @@ void mips_reboot_setup(void) { _machine_restart = mips_machine_restart; _machine_halt = mips_machine_halt; -#if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD) +#ifdef CONFIG_MIPS_MALTA pm_power_off = mips_machine_halt; #endif } diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index d224267..637897e 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -45,9 +45,6 @@ #ifdef CONFIG_MIPS_MALTA #include #endif -#ifdef CONFIG_MIPS_SEAD -#include -#endif unsigned long cpu_khz; @@ -73,7 +70,7 @@ static unsigned int __init estimate_cpu_frequency(void) unsigned int prid = read_c0_prid() & 0xffff00; unsigned int count; -#if defined(CONFIG_MIPS_SEAD) || defined(CONFIG_MIPS_SIM) +#ifdef CONFIG_MIPS_SIM /* * The SEAD board doesn't have a real time clock, so we can't * really calculate the timer frequency diff --git a/arch/mips/mips-boards/sead/Makefile b/arch/mips/mips-boards/sead/Makefile deleted file mode 100644 index 3682fe2..0000000 --- a/arch/mips/mips-boards/sead/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. -# -# ######################################################################## -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# ####################################################################### -# -# Makefile for the MIPS SEAD specific kernel interface routines -# under Linux. -# - -obj-y := sead_int.o sead_setup.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c deleted file mode 100644 index ec6dd19..0000000 --- a/arch/mips/mips-boards/sead/sead_int.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2004 Maciej W. Rozycki - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Routines for generic manipulation of the interrupts found on the MIPS - * Sead board. - */ -#include -#include - -#include -#include -#include - -#include - -static inline int clz(unsigned long x) -{ - __asm__( - " .set push \n" - " .set mips32 \n" - " clz %0, %1 \n" - " .set pop \n" - : "=r" (x) - : "r" (x)); - - return x; -} - -/* - * Version of ffs that only looks at bits 12..15. - */ -static inline unsigned int irq_ffs(unsigned int pending) -{ -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - return -clz(pending) + 31 - CAUSEB_IP; -#else - unsigned int a0 = 7; - unsigned int t0; - - t0 = s0 & 0xf000; - t0 = t0 < 1; - t0 = t0 << 2; - a0 = a0 - t0; - s0 = s0 << t0; - - t0 = s0 & 0xc000; - t0 = t0 < 1; - t0 = t0 << 1; - a0 = a0 - t0; - s0 = s0 << t0; - - t0 = s0 & 0x8000; - t0 = t0 < 1; - //t0 = t0 << 2; - a0 = a0 - t0; - //s0 = s0 << t0; - - return a0; -#endif -} - -/* - * IRQs on the SEAD board look basically are combined together on hardware - * interrupt 0 (MIPS IRQ 2)) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 UART0 (hw0) - * 3 UART1 (hw1) - * 4 Hardware (ignored) - * 5 Hardware (ignored) - * 6 Hardware (ignored) - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Lowest ---- Combined hardware interrupt - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - irq = irq_ffs(pending); - - if (irq >= 0) - do_IRQ(MIPS_CPU_IRQ_BASE + irq); - else - spurious_interrupt(); -} - -void __init arch_init_irq(void) -{ - mips_cpu_irq_init(); -} diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c deleted file mode 100644 index 8aa8e5b..0000000 --- a/arch/mips/mips-boards/sead/sead_setup.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * SEAD specific setup. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static void __init serial_init(void); - -const char *get_system_type(void) -{ - return "MIPS SEAD"; -} - -const char display_string[] = " LINUX ON SEAD "; - -void __init plat_mem_setup(void) -{ - ioport_resource.end = 0x7fffffff; - - serial_init(); - - mips_reboot_setup(); -} - -static void __init serial_init(void) -{ -#ifdef CONFIG_SERIAL_8250 - struct uart_port s; - - memset(&s, 0, sizeof(s)); - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - s.iobase = SEAD_UART0_REGS_BASE; -#else - s.iobase = SEAD_UART0_REGS_BASE+3; -#endif - s.irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_UART0; - s.uartclk = SEAD_BASE_BAUD * 16; - s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; - s.iotype = UPIO_PORT; - s.regshift = 3; - - if (early_serial_setup(&s) != 0) { - printk(KERN_ERR "Serial setup failed!\n"); - } -#endif -} diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h index 33407be..7f0b034 100644 --- a/include/asm-mips/mips-boards/generic.h +++ b/include/asm-mips/mips-boards/generic.h @@ -27,12 +27,8 @@ /* * Display register base. */ -#ifdef CONFIG_MIPS_SEAD -#define ASCII_DISPLAY_POS_BASE 0x1f0005c0 -#else #define ASCII_DISPLAY_WORD_BASE 0x1f000410 #define ASCII_DISPLAY_POS_BASE 0x1f000418 -#endif /* @@ -44,13 +40,8 @@ /* * Reset register. */ -#ifdef CONFIG_MIPS_SEAD -#define SOFTRES_REG 0x1e800050 -#define GORESET 0x4d -#else #define SOFTRES_REG 0x1f000500 #define GORESET 0x42 -#endif /* * Revision register. -- cgit v0.10.2 From 6da5e30b879394f0c55b2bbf3353d797097c8f0f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [MIPS] Remove impossible ifdef and code wrapped by it. Signed-off-by: Ralf Baechle diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 637897e..744dbfc 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -70,19 +70,6 @@ static unsigned int __init estimate_cpu_frequency(void) unsigned int prid = read_c0_prid() & 0xffff00; unsigned int count; -#ifdef CONFIG_MIPS_SIM - /* - * The SEAD board doesn't have a real time clock, so we can't - * really calculate the timer frequency - * For now we hardwire the SEAD board frequency to 12MHz. - */ - - if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) || - (prid == (PRID_COMP_MIPS | PRID_IMP_25KF))) - count = 12000000; - else - count = 6000000; -#endif #ifdef CONFIG_MIPS_MALTA unsigned long flags; unsigned int start; -- cgit v0.10.2 From d5deda6fa1ca434d36c2daffb63127e92c6470f5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [MIPS] MSC01: Cleanup configuration. This shouldn't depend on CONFIG_MIPS_BOARDS_GEN which is about to go away. Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 48ae915..0fd3197 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -60,7 +60,7 @@ obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o -obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o +obj-$(CONFIG_MIPS_MSC) += irq-msc01.o obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o obj-$(CONFIG_IRQ_GIC) += irq-gic.o -- cgit v0.10.2 From eda49eeebf263f3a34f6968959fc2e4825b42beb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [MIPS] Remove always true ifdef conditions. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 800a73d..ed8821a 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -305,14 +305,10 @@ load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000 cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote # -# For all MIPS, Inc. eval boards -# -core-$(CONFIG_MIPS_BOARDS_GEN) += arch/mips/mips-boards/generic/ - -# # MIPS Malta board # -core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/ +core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/generic/ \ + arch/mips/mips-boards/malta/ cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 all-$(CONFIG_MIPS_MALTA) := vmlinux.bin diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 55288cf..74daa0c 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -66,7 +66,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_IRQ_CPU=y -CONFIG_MIPS_BOARDS_GEN=y CONFIG_PCI_GT64XXX_PCI0=y CONFIG_SWAP_IO_SPACE=y CONFIG_BOOT_ELF32=y diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index 5e443bb..61888ff 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c @@ -97,7 +97,6 @@ static struct prom_pmemblock * __init prom_getmdesc(void) mdesc[1].base = 0x00001000; mdesc[1].size = 0x000ef000; -#ifdef CONFIG_MIPS_MALTA /* * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the * south bridge and PCI access always forwarded to the ISA Bus and @@ -108,11 +107,6 @@ static struct prom_pmemblock * __init prom_getmdesc(void) mdesc[2].type = yamon_dontuse; mdesc[2].base = 0x000f0000; mdesc[2].size = 0x00010000; -#else - mdesc[2].type = yamon_prom; - mdesc[2].base = 0x000f0000; - mdesc[2].size = 0x00010000; -#endif mdesc[3].type = yamon_dontuse; mdesc[3].base = 0x00100000; diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c index ea932b8..42dee4d 100644 --- a/arch/mips/mips-boards/generic/reset.c +++ b/arch/mips/mips-boards/generic/reset.c @@ -52,7 +52,5 @@ void mips_reboot_setup(void) { _machine_restart = mips_machine_restart; _machine_halt = mips_machine_halt; -#ifdef CONFIG_MIPS_MALTA pm_power_off = mips_machine_halt; -#endif } diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 744dbfc..0b97d47 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -42,9 +42,7 @@ #include #include -#ifdef CONFIG_MIPS_MALTA #include -#endif unsigned long cpu_khz; @@ -70,7 +68,6 @@ static unsigned int __init estimate_cpu_frequency(void) unsigned int prid = read_c0_prid() & 0xffff00; unsigned int count; -#ifdef CONFIG_MIPS_MALTA unsigned long flags; unsigned int start; @@ -91,7 +88,6 @@ static unsigned int __init estimate_cpu_frequency(void) /* restore interrupts */ local_irq_restore(flags); -#endif mips_hpt_frequency = count; if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && -- cgit v0.10.2 From 315806cb19f9d375dccbc2d60fa14e16afdcd5ac Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 15 Jul 2008 18:44:34 +0100 Subject: [MIPS] Malta: Cleanup organization of code into directories. Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ed8821a..36aa690 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -307,9 +307,8 @@ cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote # # MIPS Malta board # -core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/generic/ \ - arch/mips/mips-boards/malta/ -cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips +core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/ +cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-malta load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 all-$(CONFIG_MIPS_MALTA) := vmlinux.bin diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile deleted file mode 100644 index f7f87fc..0000000 --- a/arch/mips/mips-boards/generic/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# Makefile for the MIPS boards generic routines under Linux. -# - -obj-y := reset.o display.o init.o memory.o \ - cmdline.o time.o -obj-y += amon.o - -obj-$(CONFIG_EARLY_PRINTK) += console.o -obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_KGDB) += gdb_hook.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mips-boards/generic/amon.c b/arch/mips/mips-boards/generic/amon.c deleted file mode 100644 index 96236bf..0000000 --- a/arch/mips/mips-boards/generic/amon.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2007 MIPS Technologies, Inc. - * All rights reserved. - - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Arbitrary Monitor interface - */ - -#include -#include -#include - -#include -#include -#include - -int amon_cpu_avail(int cpu) -{ - struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); - - if (cpu < 0 || cpu >= NCPULAUNCH) { - pr_debug("avail: cpu%d is out of range\n", cpu); - return 0; - } - - launch += cpu; - if (!(launch->flags & LAUNCH_FREADY)) { - pr_debug("avail: cpu%d is not ready\n", cpu); - return 0; - } - if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) { - pr_debug("avail: too late.. cpu%d is already gone\n", cpu); - return 0; - } - - return 1; -} - -void amon_cpu_start(int cpu, - unsigned long pc, unsigned long sp, - unsigned long gp, unsigned long a0) -{ - volatile struct cpulaunch *launch = - (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); - - if (!amon_cpu_avail(cpu)) - return; - if (cpu == smp_processor_id()) { - pr_debug("launch: I am cpu%d!\n", cpu); - return; - } - launch += cpu; - - pr_debug("launch: starting cpu%d\n", cpu); - - launch->pc = pc; - launch->gp = gp; - launch->sp = sp; - launch->a0 = a0; - - /* Make sure target sees parameters before the go bit */ - smp_mb(); - - launch->flags |= LAUNCH_FGO; - while ((launch->flags & LAUNCH_FGONE) == 0) - ; - pr_debug("launch: cpu%d gone!\n", cpu); -} diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c deleted file mode 100644 index 1871c30..0000000 --- a/arch/mips/mips-boards/generic/cmdline.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Kernel command line creation using the prom monitor (YAMON) argc/argv. - */ -#include -#include - -#include - -extern int prom_argc; -extern int *_prom_argv; - -/* - * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. - * This macro take care of sign extension. - */ -#define prom_argv(index) ((char *)(long)_prom_argv[(index)]) - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - - -void __init prom_init_cmdline(void) -{ - char *cp; - int actr; - - actr = 1; /* Always ignore argv[0] */ - - cp = &(arcs_cmdline[0]); - while(actr < prom_argc) { - strcpy(cp, prom_argv(actr)); - cp += strlen(prom_argv(actr)); - *cp++ = ' '; - actr++; - } - if (cp != &(arcs_cmdline[0])) { - /* get rid of trailing space */ - --cp; - *cp = '\0'; - } -} diff --git a/arch/mips/mips-boards/generic/console.c b/arch/mips/mips-boards/generic/console.c deleted file mode 100644 index 43bcfb4..0000000 --- a/arch/mips/mips-boards/generic/console.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Putting things on the screen/serial line using YAMONs facilities. - */ -#include -#include -#include -#include - - -#define PORT(offset) (0x3f8 + (offset)) - - -static inline unsigned int serial_in(int offset) -{ - return inb(PORT(offset)); -} - -static inline void serial_out(int offset, int value) -{ - outb(value, PORT(offset)); -} - -int prom_putchar(char c) -{ - while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) - ; - - serial_out(UART_TX, c); - - return 1; -} diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c deleted file mode 100644 index 7c8828f..0000000 --- a/arch/mips/mips-boards/generic/display.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Display routines for display messages in MIPS boards ascii display. - */ - -#include -#include -#include -#include -#include - -extern const char display_string[]; -static unsigned int display_count; -static unsigned int max_display_count; - -void mips_display_message(const char *str) -{ - static unsigned int __iomem *display = NULL; - int i; - - if (unlikely(display == NULL)) - display = ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); - - for (i = 0; i <= 14; i=i+2) { - if (*str) - __raw_writel(*str++, display + i); - else - __raw_writel(' ', display + i); - } -} - -static void scroll_display_message(unsigned long data); -static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0); - -static void scroll_display_message(unsigned long data) -{ - mips_display_message(&display_string[display_count++]); - if (display_count == max_display_count) - display_count = 0; - - mod_timer(&mips_scroll_timer, jiffies + HZ); -} - -void mips_scroll_message(void) -{ - del_timer_sync(&mips_scroll_timer); - max_display_count = strlen(display_string) + 1 - 8; - mod_timer(&mips_scroll_timer, jiffies + 1); -} diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c deleted file mode 100644 index 6a1854d..0000000 --- a/arch/mips/mips-boards/generic/gdb_hook.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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 is the interface to the remote debugger stub. - */ -#include -#include -#include -#include - -#include -#include - -static struct serial_state rs_table[] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -static struct async_struct kdb_port_info = {0}; - -int (*generic_putDebugChar)(char); -char (*generic_getDebugChar)(void); - -static __inline__ unsigned int serial_in(struct async_struct *info, int offset) -{ - return inb(info->port + offset); -} - -static __inline__ void serial_out(struct async_struct *info, int offset, - int value) -{ - outb(value, info->port+offset); -} - -int rs_kgdb_hook(int tty_no, int speed) { - int t; - struct serial_state *ser = &rs_table[tty_no]; - - kdb_port_info.state = ser; - kdb_port_info.magic = SERIAL_MAGIC; - kdb_port_info.port = ser->port; - kdb_port_info.flags = ser->flags; - - /* - * Clear all interrupts - */ - serial_in(&kdb_port_info, UART_LSR); - serial_in(&kdb_port_info, UART_RX); - serial_in(&kdb_port_info, UART_IIR); - serial_in(&kdb_port_info, UART_MSR); - - /* - * Now, initialize the UART - */ - serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ - if (kdb_port_info.flags & ASYNC_FOURPORT) { - kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS; - t = UART_MCR_DTR | UART_MCR_OUT1; - } else { - kdb_port_info.MCR - = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - t = UART_MCR_DTR | UART_MCR_RTS; - } - - kdb_port_info.MCR = t; /* no interrupts, please */ - serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR); - - /* - * and set the speed of the serial port - */ - if (speed == 0) - speed = 9600; - - t = kdb_port_info.state->baud_base / speed; - /* set DLAB */ - serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB); - serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */ - serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */ - /* reset DLAB */ - serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); - - return speed; -} - -int putDebugChar(char c) -{ - return generic_putDebugChar(c); -} - -char getDebugChar(void) -{ - return generic_getDebugChar(); -} - -int rs_putDebugChar(char c) -{ - - if (!kdb_port_info.state) { /* need to init device first */ - return 0; - } - - while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0) - ; - - serial_out(&kdb_port_info, UART_TX, c); - - return 1; -} - -char rs_getDebugChar(void) -{ - if (!kdb_port_info.state) { /* need to init device first */ - return 0; - } - - while (!(serial_in(&kdb_port_info, UART_LSR) & 1)) - ; - - return serial_in(&kdb_port_info, UART_RX); -} diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c deleted file mode 100644 index c065302..0000000 --- a/arch/mips/mips-boards/generic/init.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * PROM library initialisation code. - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#ifdef CONFIG_KGDB -extern int rs_kgdb_hook(int, int); -extern int rs_putDebugChar(char); -extern char rs_getDebugChar(void); -extern int saa9730_kgdb_hook(int); -extern int saa9730_putDebugChar(char); -extern char saa9730_getDebugChar(void); -#endif - -int prom_argc; -int *_prom_argv, *_prom_envp; - -/* - * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. - * This macro take care of sign extension, if running in 64-bit mode. - */ -#define prom_envp(index) ((char *)(long)_prom_envp[(index)]) - -int init_debug = 0; - -int mips_revision_corid; -int mips_revision_sconid; - -/* Bonito64 system controller register base. */ -unsigned long _pcictrl_bonito; -unsigned long _pcictrl_bonito_pcicfg; - -/* GT64120 system controller register base */ -unsigned long _pcictrl_gt64120; - -/* MIPS System controller register base */ -unsigned long _pcictrl_msc; - -char *prom_getenv(char *envname) -{ - /* - * Return a pointer to the given environment variable. - * In 64-bit mode: we're using 64-bit pointers, but all pointers - * in the PROM structures are only 32-bit, so we need some - * workarounds, if we are running in 64-bit mode. - */ - int i, index=0; - - i = strlen(envname); - - while (prom_envp(index)) { - if(strncmp(envname, prom_envp(index), i) == 0) { - return(prom_envp(index+1)); - } - index += 2; - } - - return NULL; -} - -static inline unsigned char str2hexnum(unsigned char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0; /* foo */ -} - -static inline void str2eaddr(unsigned char *ea, unsigned char *str) -{ - int i; - - for (i = 0; i < 6; i++) { - unsigned char num; - - if((*str == '.') || (*str == ':')) - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; - } -} - -int get_ethernet_addr(char *ethernet_addr) -{ - char *ethaddr_str; - - ethaddr_str = prom_getenv("ethaddr"); - if (!ethaddr_str) { - printk("ethaddr not set in boot prom\n"); - return -1; - } - str2eaddr(ethernet_addr, ethaddr_str); - - if (init_debug > 1) { - int i; - printk("get_ethernet_addr: "); - for (i=0; i<5; i++) - printk("%02x:", (unsigned char)*(ethernet_addr+i)); - printk("%02x\n", *(ethernet_addr+i)); - } - - return 0; -} - -#ifdef CONFIG_SERIAL_8250_CONSOLE -static void __init console_config(void) -{ - char console_string[40]; - int baud = 0; - char parity = '\0', bits = '\0', flow = '\0'; - char *s; - - if ((strstr(prom_getcmdline(), "console=")) == NULL) { - s = prom_getenv("modetty0"); - if (s) { - while (*s >= '0' && *s <= '9') - baud = baud*10 + *s++ - '0'; - if (*s == ',') s++; - if (*s) parity = *s++; - if (*s == ',') s++; - if (*s) bits = *s++; - if (*s == ',') s++; - if (*s == 'h') flow = 'r'; - } - if (baud == 0) - baud = 38400; - if (parity != 'n' && parity != 'o' && parity != 'e') - parity = 'n'; - if (bits != '7' && bits != '8') - bits = '8'; - if (flow == '\0') - flow = 'r'; - sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); - strcat(prom_getcmdline(), console_string); - pr_info("Config serial console:%s\n", console_string); - } -} -#endif - -#ifdef CONFIG_KGDB -void __init kgdb_config(void) -{ - extern int (*generic_putDebugChar)(char); - extern char (*generic_getDebugChar)(void); - char *argptr; - int line, speed; - - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { - argptr += strlen("kgdb=ttyS"); - if (*argptr != '0' && *argptr != '1') - printk("KGDB: Unknown serial line /dev/ttyS%c, " - "falling back to /dev/ttyS1\n", *argptr); - line = *argptr == '0' ? 0 : 1; - printk("KGDB: Using serial line /dev/ttyS%d for session\n", line); - - speed = 0; - if (*++argptr == ',') - { - int c; - while ((c = *++argptr) && ('0' <= c && c <= '9')) - speed = speed * 10 + c - '0'; - } - { - speed = rs_kgdb_hook(line, speed); - generic_putDebugChar = rs_putDebugChar; - generic_getDebugChar = rs_getDebugChar; - } - - pr_info("KGDB: Using serial line /dev/ttyS%d at %d for " - "session, please connect your debugger\n", - line ? 1 : 0, speed); - - { - char *s; - for (s = "Please connect GDB to this port\r\n"; *s; ) - generic_putDebugChar(*s++); - } - - /* Breakpoint is invoked after interrupts are initialised */ - } -} -#endif - -static void __init mips_nmi_setup(void) -{ - void *base; - extern char except_vec_nmi; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa80) : - (void *)(CAC_BASE + 0x380); - memcpy(base, &except_vec_nmi, 0x80); - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -static void __init mips_ejtag_setup(void) -{ - void *base; - extern char except_vec_ejtag_debug; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa00) : - (void *)(CAC_BASE + 0x300); - memcpy(base, &except_vec_ejtag_debug, 0x80); - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -extern struct plat_smp_ops msmtc_smp_ops; - -void __init prom_init(void) -{ - prom_argc = fw_arg0; - _prom_argv = (int *) fw_arg1; - _prom_envp = (int *) fw_arg2; - - mips_display_message("LINUX"); - - /* - * early setup of _pcictrl_bonito so that we can determine - * the system controller on a CORE_EMUL board - */ - _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE); - - mips_revision_corid = MIPS_REVISION_CORID; - - if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) { - if (BONITO_PCIDID == 0x0001df53 || - BONITO_PCIDID == 0x0003df53) - mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON; - else - mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; - } - - mips_revision_sconid = MIPS_REVISION_SCONID; - if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) { - switch (mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_FPGAR2: - mips_revision_sconid = MIPS_REVISION_SCON_GT64120; - break; - case MIPS_REVISION_CORID_CORE_EMUL_BON: - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - mips_revision_sconid = MIPS_REVISION_SCON_BONITO; - break; - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_24K: - /* - * SOCit/ROCit support is essentially identical - * but make an attempt to distinguish them - */ - mips_revision_sconid = MIPS_REVISION_SCON_SOCIT; - break; - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_FPGA4: - case MIPS_REVISION_CORID_CORE_FPGA5: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: - default: - /* See above */ - mips_revision_sconid = MIPS_REVISION_SCON_ROCIT; - break; - } - } - - switch (mips_revision_sconid) { - u32 start, map, mask, data; - - case MIPS_REVISION_SCON_GT64120: - /* - * Setup the North bridge to do Master byte-lane swapping - * when running in bigendian. - */ - _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000); - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | - GT_PCI0_CMD_SBYTESWAP_BIT); -#else - GT_WRITE(GT_PCI0_CMD_OFS, 0); -#endif - /* Fix up PCI I/O mapping if necessary (for Atlas). */ - start = GT_READ(GT_PCI0IOLD_OFS); - map = GT_READ(GT_PCI0IOREMAP_OFS); - if ((start & map) != 0) { - map &= ~start; - GT_WRITE(GT_PCI0IOREMAP_OFS, map); - } - - set_io_port_base(MALTA_GT_PORT_BASE); - break; - - case MIPS_REVISION_SCON_BONITO: - _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); - - /* - * Disable Bonito IOBC. - */ - BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & - ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | - BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); - - /* - * Setup the North bridge to do Master byte-lane swapping - * when running in bigendian. - */ -#ifdef CONFIG_CPU_LITTLE_ENDIAN - BONITO_BONGENCFG = BONITO_BONGENCFG & - ~(BONITO_BONGENCFG_MSTRBYTESWAP | - BONITO_BONGENCFG_BYTESWAP); -#else - BONITO_BONGENCFG = BONITO_BONGENCFG | - BONITO_BONGENCFG_MSTRBYTESWAP | - BONITO_BONGENCFG_BYTESWAP; -#endif - - set_io_port_base(MALTA_BONITO_PORT_BASE); - break; - - case MIPS_REVISION_SCON_SOCIT: - case MIPS_REVISION_SCON_ROCIT: - _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); - mips_pci_controller: - mb(); - MSC_READ(MSC01_PCI_CFG, data); - MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); - wmb(); - - /* Fix up lane swapping. */ -#ifdef CONFIG_CPU_LITTLE_ENDIAN - MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); -#else - MSC_WRITE(MSC01_PCI_SWAP, - MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF | - MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | - MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); -#endif - /* Fix up target memory mapping. */ - MSC_READ(MSC01_PCI_BAR0, mask); - MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK); - - /* Don't handle target retries indefinitely. */ - if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == - MSC01_PCI_CFG_MAXRTRY_MSK) - data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK << - MSC01_PCI_CFG_MAXRTRY_SHF)) | - ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) << - MSC01_PCI_CFG_MAXRTRY_SHF); - - wmb(); - MSC_WRITE(MSC01_PCI_CFG, data); - mb(); - - set_io_port_base(MALTA_MSC_PORT_BASE); - break; - - case MIPS_REVISION_SCON_SOCITSC: - case MIPS_REVISION_SCON_SOCITSCP: - _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000); - goto mips_pci_controller; - - default: - /* Unknown system controller */ - mips_display_message("SC Error"); - while (1); /* We die here... */ - } - board_nmi_handler_setup = mips_nmi_setup; - board_ejtag_handler_setup = mips_ejtag_setup; - - pr_info("\nLINUX started...\n"); - prom_init_cmdline(); - prom_meminit(); -#ifdef CONFIG_SERIAL_8250_CONSOLE - console_config(); -#endif -#ifdef CONFIG_MIPS_CMP - register_smp_ops(&cmp_smp_ops); -#endif -#ifdef CONFIG_MIPS_MT_SMP - register_smp_ops(&vsmp_smp_ops); -#endif -#ifdef CONFIG_MIPS_MT_SMTC - register_smp_ops(&msmtc_smp_ops); -#endif -} diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c deleted file mode 100644 index 61888ff..0000000 --- a/arch/mips/mips-boards/generic/memory.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * PROM library functions for acquiring/using memory descriptors given to - * us from the YAMON. - */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -/*#define DEBUG*/ - -enum yamon_memtypes { - yamon_dontuse, - yamon_prom, - yamon_free, -}; -static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; - -#ifdef DEBUG -static char *mtypes[3] = { - "Dont use memory", - "YAMON PROM memory", - "Free memmory", -}; -#endif - -/* determined physical memory size, not overridden by command line args */ -unsigned long physical_memsize = 0L; - -static struct prom_pmemblock * __init prom_getmdesc(void) -{ - char *memsize_str; - unsigned int memsize; - char cmdline[CL_SIZE], *ptr; - - /* otherwise look in the environment */ - memsize_str = prom_getenv("memsize"); - if (!memsize_str) { - printk(KERN_WARNING - "memsize not set in boot prom, set to default (32Mb)\n"); - physical_memsize = 0x02000000; - } else { -#ifdef DEBUG - pr_debug("prom_memsize = %s\n", memsize_str); -#endif - physical_memsize = simple_strtol(memsize_str, NULL, 0); - } - -#ifdef CONFIG_CPU_BIG_ENDIAN - /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last - word of physical memory */ - physical_memsize -= PAGE_SIZE; -#endif - - /* Check the command line for a memsize directive that overrides - the physical/default amount */ - strcpy(cmdline, arcs_cmdline); - ptr = strstr(cmdline, "memsize="); - if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) - ptr = strstr(ptr, " memsize="); - - if (ptr) - memsize = memparse(ptr + 8, &ptr); - else - memsize = physical_memsize; - - memset(mdesc, 0, sizeof(mdesc)); - - mdesc[0].type = yamon_dontuse; - mdesc[0].base = 0x00000000; - mdesc[0].size = 0x00001000; - - mdesc[1].type = yamon_prom; - mdesc[1].base = 0x00001000; - mdesc[1].size = 0x000ef000; - - /* - * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the - * south bridge and PCI access always forwarded to the ISA Bus and - * BIOSCS# is always generated. - * This mean that this area can't be used as DMA memory for PCI - * devices. - */ - mdesc[2].type = yamon_dontuse; - mdesc[2].base = 0x000f0000; - mdesc[2].size = 0x00010000; - - mdesc[3].type = yamon_dontuse; - mdesc[3].base = 0x00100000; - mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; - - mdesc[4].type = yamon_free; - mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); - mdesc[4].size = memsize - mdesc[4].base; - - return &mdesc[0]; -} - -static int __init prom_memtype_classify(unsigned int type) -{ - switch (type) { - case yamon_free: - return BOOT_MEM_RAM; - case yamon_prom: - return BOOT_MEM_ROM_DATA; - default: - return BOOT_MEM_RESERVED; - } -} - -void __init prom_meminit(void) -{ - struct prom_pmemblock *p; - -#ifdef DEBUG - pr_debug("YAMON MEMORY DESCRIPTOR dump:\n"); - p = prom_getmdesc(); - while (p->size) { - int i = 0; - pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", - i, p, p->base, p->size, mtypes[p->type]); - p++; - i++; - } -#endif - p = prom_getmdesc(); - - while (p->size) { - long type; - unsigned long base, size; - - type = prom_memtype_classify(p->type); - base = p->base; - size = p->size; - - add_memory_region(base, size, type); - p++; - } -} - -void __init prom_free_prom_memory(void) -{ - unsigned long addr; - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) - continue; - - addr = boot_mem_map.map[i].addr; - free_init_pages("prom memory", - addr, addr + boot_mem_map.map[i].size); - } -} diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c deleted file mode 100644 index b974319..0000000 --- a/arch/mips/mips-boards/generic/pci.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki - * - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * MIPS boards specific PCI support. - */ -#include -#include -#include -#include - -#include - -#include -#include -#include - -static struct resource bonito64_mem_resource = { - .name = "Bonito PCI MEM", - .flags = IORESOURCE_MEM, -}; - -static struct resource bonito64_io_resource = { - .name = "Bonito PCI I/O", - .start = 0x00000000UL, - .end = 0x000fffffUL, - .flags = IORESOURCE_IO, -}; - -static struct resource gt64120_mem_resource = { - .name = "GT-64120 PCI MEM", - .flags = IORESOURCE_MEM, -}; - -static struct resource gt64120_io_resource = { - .name = "GT-64120 PCI I/O", - .flags = IORESOURCE_IO, -}; - -static struct resource msc_mem_resource = { - .name = "MSC PCI MEM", - .flags = IORESOURCE_MEM, -}; - -static struct resource msc_io_resource = { - .name = "MSC PCI I/O", - .flags = IORESOURCE_IO, -}; - -extern struct pci_ops bonito64_pci_ops; -extern struct pci_ops gt64xxx_pci0_ops; -extern struct pci_ops msc_pci_ops; - -static struct pci_controller bonito64_controller = { - .pci_ops = &bonito64_pci_ops, - .io_resource = &bonito64_io_resource, - .mem_resource = &bonito64_mem_resource, - .io_offset = 0x00000000UL, -}; - -static struct pci_controller gt64120_controller = { - .pci_ops = >64xxx_pci0_ops, - .io_resource = >64120_io_resource, - .mem_resource = >64120_mem_resource, -}; - -static struct pci_controller msc_controller = { - .pci_ops = &msc_pci_ops, - .io_resource = &msc_io_resource, - .mem_resource = &msc_mem_resource, -}; - -void __init mips_pcibios_init(void) -{ - struct pci_controller *controller; - resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; - - switch (mips_revision_sconid) { - case MIPS_REVISION_SCON_GT64120: - /* - * Due to a bug in the Galileo system controller, we need - * to setup the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be - * fixed in a later revision of YAMON (the MIPS boards - * boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ - GT_PCI0_CFGADDR_CONFIGEN_BIT); - - /* Perform the write */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); - - /* Set up resource ranges from the controller's registers. */ - start = GT_READ(GT_PCI0M0LD_OFS); - end = GT_READ(GT_PCI0M0HD_OFS); - map = GT_READ(GT_PCI0M0REMAP_OFS); - end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK); - start1 = GT_READ(GT_PCI0M1LD_OFS); - end1 = GT_READ(GT_PCI0M1HD_OFS); - map1 = GT_READ(GT_PCI0M1REMAP_OFS); - end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK); - /* Cannot support multiple windows, use the wider. */ - if (end1 - start1 > end - start) { - start = start1; - end = end1; - map = map1; - } - mask = ~(start ^ end); - /* We don't support remapping with a discontiguous mask. */ - BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) && - mask != ~((mask & -mask) - 1)); - gt64120_mem_resource.start = start; - gt64120_mem_resource.end = end; - gt64120_controller.mem_offset = (start & mask) - (map & mask); - /* Addresses are 36-bit, so do shifts in the destinations. */ - gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF; - gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF; - gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1; - gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF; - - start = GT_READ(GT_PCI0IOLD_OFS); - end = GT_READ(GT_PCI0IOHD_OFS); - map = GT_READ(GT_PCI0IOREMAP_OFS); - end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK); - mask = ~(start ^ end); - /* We don't support remapping with a discontiguous mask. */ - BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) && - mask != ~((mask & -mask) - 1)); - gt64120_io_resource.start = map & mask; - gt64120_io_resource.end = (map & mask) | ~mask; - gt64120_controller.io_offset = 0; - /* Addresses are 36-bit, so do shifts in the destinations. */ - gt64120_io_resource.start <<= GT_PCI_DCRM_SHF; - gt64120_io_resource.end <<= GT_PCI_DCRM_SHF; - gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1; - - controller = >64120_controller; - break; - - case MIPS_REVISION_SCON_BONITO: - /* Set up resource ranges from the controller's registers. */ - map = BONITO_PCIMAP; - map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >> - BONITO_PCIMAP_PCIMAP_LO0_SHIFT; - map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >> - BONITO_PCIMAP_PCIMAP_LO1_SHIFT; - map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >> - BONITO_PCIMAP_PCIMAP_LO2_SHIFT; - /* Combine as many adjacent windows as possible. */ - map = map1; - start = BONITO_PCILO0_BASE; - end = 1; - if (map3 == map2 + 1) { - map = map2; - start = BONITO_PCILO1_BASE; - end++; - } - if (map2 == map1 + 1) { - map = map1; - start = BONITO_PCILO0_BASE; - end++; - } - bonito64_mem_resource.start = start; - bonito64_mem_resource.end = start + - BONITO_PCIMAP_WINBASE(end) - 1; - bonito64_controller.mem_offset = start - - BONITO_PCIMAP_WINBASE(map); - - controller = &bonito64_controller; - break; - - case MIPS_REVISION_SCON_SOCIT: - case MIPS_REVISION_SCON_ROCIT: - case MIPS_REVISION_SCON_SOCITSC: - case MIPS_REVISION_SCON_SOCITSCP: - /* Set up resource ranges from the controller's registers. */ - MSC_READ(MSC01_PCI_SC2PMBASL, start); - MSC_READ(MSC01_PCI_SC2PMMSKL, mask); - MSC_READ(MSC01_PCI_SC2PMMAPL, map); - msc_mem_resource.start = start & mask; - msc_mem_resource.end = (start & mask) | ~mask; - msc_controller.mem_offset = (start & mask) - (map & mask); - - MSC_READ(MSC01_PCI_SC2PIOBASL, start); - MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); - MSC_READ(MSC01_PCI_SC2PIOMAPL, map); - msc_io_resource.start = map & mask; - msc_io_resource.end = (map & mask) | ~mask; - msc_controller.io_offset = 0; - ioport_resource.end = ~mask; - - /* If ranges overlap I/O takes precedence. */ - start = start & mask; - end = start | ~mask; - if ((start >= msc_mem_resource.start && - start <= msc_mem_resource.end) || - (end >= msc_mem_resource.start && - end <= msc_mem_resource.end)) { - /* Use the larger space. */ - start = max(start, msc_mem_resource.start); - end = min(end, msc_mem_resource.end); - if (start - msc_mem_resource.start >= - msc_mem_resource.end - end) - msc_mem_resource.end = start - 1; - else - msc_mem_resource.start = end + 1; - } - - controller = &msc_controller; - break; - default: - return; - } - - if (controller->io_resource->start < 0x00001000UL) /* FIXME */ - controller->io_resource->start = 0x00001000UL; - - iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ - ioport_resource.end = controller->io_resource->end; - - register_pci_controller(controller); -} diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c deleted file mode 100644 index 42dee4d..0000000 --- a/arch/mips/mips-boards/generic/reset.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * ######################################################################## - * - * Reset the MIPS boards. - * - */ -#include - -#include -#include -#include - -static void mips_machine_restart(char *command); -static void mips_machine_halt(void); - -static void mips_machine_restart(char *command) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - -static void mips_machine_halt(void) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - - -void mips_reboot_setup(void) -{ - _machine_restart = mips_machine_restart; - _machine_halt = mips_machine_halt; - pm_power_off = mips_machine_halt; -} diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c deleted file mode 100644 index 0b97d47..0000000 --- a/arch/mips/mips-boards/generic/time.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Setting up the clock on the MIPS boards. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -unsigned long cpu_khz; - -static int mips_cpu_timer_irq; -static int mips_cpu_perf_irq; -extern int cp0_perfcount_irq; - -static void mips_timer_dispatch(void) -{ - do_IRQ(mips_cpu_timer_irq); -} - -static void mips_perf_dispatch(void) -{ - do_IRQ(mips_cpu_perf_irq); -} - -/* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect - */ -static unsigned int __init estimate_cpu_frequency(void) -{ - unsigned int prid = read_c0_prid() & 0xffff00; - unsigned int count; - - unsigned long flags; - unsigned int start; - - local_irq_save(flags); - - /* Start counter exactly on falling edge of update flag */ - while (CMOS_READ(RTC_REG_A) & RTC_UIP); - while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - - /* Start r4k counter. */ - start = read_c0_count(); - - /* Read counter exactly on falling edge of update flag */ - while (CMOS_READ(RTC_REG_A) & RTC_UIP); - while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - - count = read_c0_count() - start; - - /* restore interrupts */ - local_irq_restore(flags); - - mips_hpt_frequency = count; - if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && - (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) - count *= 2; - - count += 5000; /* round */ - count -= count%10000; - - return count; -} - -unsigned long read_persistent_clock(void) -{ - return mc146818_get_cmos_time(); -} - -static void __init plat_perf_setup(void) -{ -#ifdef MSC01E_INT_BASE - if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); - mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; - } else -#endif - if (cp0_perfcount_irq >= 0) { - if (cpu_has_vint) - set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); - mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; -#ifdef CONFIG_SMP - set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq); -#endif - } -} - -unsigned int __cpuinit get_c0_compare_int(void) -{ -#ifdef MSC01E_INT_BASE - if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); - mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } else -#endif - { - if (cpu_has_vint) - set_vi_handler(cp0_compare_irq, mips_timer_dispatch); - mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; - } - - return mips_cpu_timer_irq; -} - -void __init plat_time_init(void) -{ - unsigned int est_freq; - - /* Set Data mode - binary. */ - CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); - - est_freq = estimate_cpu_frequency(); - - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, - (est_freq%1000000)*100/1000000); - - cpu_khz = est_freq / 1000; - - mips_scroll_message(); -#ifdef CONFIG_I8253 /* Only Malta has a PIT */ - setup_pit_timer(); -#endif - - plat_perf_setup(); -} diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile deleted file mode 100644 index db4ad65..0000000 --- a/arch/mips/mips-boards/malta/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# Makefile for the MIPS Malta specific kernel interface routines -# under Linux. -# - -obj-y := malta_int.o malta_mtd.o malta_platform.o malta_setup.o - -# FIXME FIXME FIXME -obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c deleted file mode 100644 index ea17611..0000000 --- a/arch/mips/mips-boards/malta/malta_int.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. - * Copyright (C) 2001 Ralf Baechle - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * Routines for generic manipulation of the interrupts found on the MIPS - * Malta board. - * The interrupt controller is located in the South Bridge a PIIX4 device - * with two internal 82C95 interrupt controllers. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int gcmp_present = -1; -int gic_present; -static unsigned long _msc01_biu_base; -static unsigned long _gcmp_base; -static unsigned int ipi_map[NR_CPUS]; - -static DEFINE_SPINLOCK(mips_irq_lock); - -static inline int mips_pcibios_iack(void) -{ - int irq; - u32 dummy; - - /* - * Determine highest priority pending interrupt by performing - * a PCI Interrupt Acknowledge cycle. - */ - switch (mips_revision_sconid) { - case MIPS_REVISION_SCON_SOCIT: - case MIPS_REVISION_SCON_ROCIT: - case MIPS_REVISION_SCON_SOCITSC: - case MIPS_REVISION_SCON_SOCITSCP: - MSC_READ(MSC01_PCI_IACK, irq); - irq &= 0xff; - break; - case MIPS_REVISION_SCON_GT64120: - irq = GT_READ(GT_PCI0_IACK_OFS); - irq &= 0xff; - break; - case MIPS_REVISION_SCON_BONITO: - /* The following will generate a PCI IACK cycle on the - * Bonito controller. It's a little bit kludgy, but it - * was the easiest way to implement it in hardware at - * the given time. - */ - BONITO_PCIMAP_CFG = 0x20000; - - /* Flush Bonito register block */ - dummy = BONITO_PCIMAP_CFG; - iob(); /* sync */ - - irq = readl((u32 *)_pcictrl_bonito_pcicfg); - iob(); /* sync */ - irq &= 0xff; - BONITO_PCIMAP_CFG = 0; - break; - default: - printk(KERN_WARNING "Unknown system controller.\n"); - return -1; - } - return irq; -} - -static inline int get_int(void) -{ - unsigned long flags; - int irq; - spin_lock_irqsave(&mips_irq_lock, flags); - - irq = mips_pcibios_iack(); - - /* - * The only way we can decide if an interrupt is spurious - * is by checking the 8259 registers. This needs a spinlock - * on an SMP system, so leave it up to the generic code... - */ - - spin_unlock_irqrestore(&mips_irq_lock, flags); - - return irq; -} - -static void malta_hw0_irqdispatch(void) -{ - int irq; - - irq = get_int(); - if (irq < 0) { - /* interrupt has already been cleared */ - return; - } - - do_IRQ(MALTA_INT_BASE + irq); -} - -static void malta_ipi_irqdispatch(void) -{ - int irq; - - irq = gic_get_int(); - if (irq < 0) - return; /* interrupt has already been cleared */ - - do_IRQ(MIPS_GIC_IRQ_BASE + irq); -} - -static void corehi_irqdispatch(void) -{ - unsigned int intedge, intsteer, pcicmd, pcibadaddr; - unsigned int pcimstat, intisr, inten, intpol; - unsigned int intrcause, datalo, datahi; - struct pt_regs *regs = get_irq_regs(); - - printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n"); - printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n" - "Cause : %08lx\nbadVaddr : %08lx\n", - regs->cp0_epc, regs->cp0_status, - regs->cp0_cause, regs->cp0_badvaddr); - - /* Read all the registers and then print them as there is a - problem with interspersed printk's upsetting the Bonito controller. - Do it for the others too. - */ - - switch (mips_revision_sconid) { - case MIPS_REVISION_SCON_SOCIT: - case MIPS_REVISION_SCON_ROCIT: - case MIPS_REVISION_SCON_SOCITSC: - case MIPS_REVISION_SCON_SOCITSCP: - ll_msc_irq(); - break; - case MIPS_REVISION_SCON_GT64120: - intrcause = GT_READ(GT_INTRCAUSE_OFS); - datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); - datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); - printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause); - printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n", - datahi, datalo); - break; - case MIPS_REVISION_SCON_BONITO: - pcibadaddr = BONITO_PCIBADADDR; - pcimstat = BONITO_PCIMSTAT; - intisr = BONITO_INTISR; - inten = BONITO_INTEN; - intpol = BONITO_INTPOL; - intedge = BONITO_INTEDGE; - intsteer = BONITO_INTSTEER; - pcicmd = BONITO_PCICMD; - printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr); - printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten); - printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol); - printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge); - printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer); - printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd); - printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr); - printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat); - break; - } - - die("CoreHi interrupt", regs); -} - -static inline int clz(unsigned long x) -{ - __asm__( - " .set push \n" - " .set mips32 \n" - " clz %0, %1 \n" - " .set pop \n" - : "=r" (x) - : "r" (x)); - - return x; -} - -/* - * Version of ffs that only looks at bits 12..15. - */ -static inline unsigned int irq_ffs(unsigned int pending) -{ -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - return -clz(pending) + 31 - CAUSEB_IP; -#else - unsigned int a0 = 7; - unsigned int t0; - - t0 = pending & 0xf000; - t0 = t0 < 1; - t0 = t0 << 2; - a0 = a0 - t0; - pending = pending << t0; - - t0 = pending & 0xc000; - t0 = t0 < 1; - t0 = t0 << 1; - a0 = a0 - t0; - pending = pending << t0; - - t0 = pending & 0x8000; - t0 = t0 < 1; - /* t0 = t0 << 2; */ - a0 = a0 - t0; - /* pending = pending << t0; */ - - return a0; -#endif -} - -/* - * IRQs on the Malta board look basically (barring software IRQs which we - * don't use at all and all external interrupt sources are combined together - * on hardware interrupt 0 (MIPS IRQ 2)) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Combined hardware interrupt (hw0) - * 3 Hardware (ignored) - * 4 Hardware (ignored) - * 5 Hardware (ignored) - * 6 Hardware (ignored) - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Lowest ---- Combined hardware interrupt - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - irq = irq_ffs(pending); - - if (irq == MIPSCPU_INT_I8259A) - malta_hw0_irqdispatch(); - else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) - malta_ipi_irqdispatch(); - else if (irq >= 0) - do_IRQ(MIPS_CPU_IRQ_BASE + irq); - else - spurious_interrupt(); -} - -#ifdef CONFIG_MIPS_MT_SMP - - -#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 -#define GIC_MIPS_CPU_IPI_CALL_IRQ 4 - -#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ -#define C_RESCHED C_SW0 -#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ -#define C_CALL C_SW1 -static int cpu_ipi_resched_irq, cpu_ipi_call_irq; - -static void ipi_resched_dispatch(void) -{ - do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); -} - -static void ipi_call_dispatch(void) -{ - do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); -} - -static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) -{ - return IRQ_HANDLED; -} - -static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) -{ - smp_call_function_interrupt(); - - return IRQ_HANDLED; -} - -static struct irqaction irq_resched = { - .handler = ipi_resched_interrupt, - .flags = IRQF_DISABLED|IRQF_PERCPU, - .name = "IPI_resched" -}; - -static struct irqaction irq_call = { - .handler = ipi_call_interrupt, - .flags = IRQF_DISABLED|IRQF_PERCPU, - .name = "IPI_call" -}; -#endif /* CONFIG_MIPS_MT_SMP */ - -static struct irqaction i8259irq = { - .handler = no_action, - .name = "XT-PIC cascade" -}; - -static struct irqaction corehi_irqaction = { - .handler = no_action, - .name = "CoreHi" -}; - -static msc_irqmap_t __initdata msc_irqmap[] = { - {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, -}; -static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap); - -static msc_irqmap_t __initdata msc_eicirqmap[] = { - {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} -}; - -static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); - -#if defined(CONFIG_MIPS_MT_SMP) -/* - * This GIC specific tabular array defines the association between External - * Interrupts and CPUs/Core Interrupts. The nature of the External - * Interrupts is also defined here - polarity/trigger. - */ -static struct gic_intr_map gic_intr_map[] = { - { GIC_EXT_INTR(0), X, X, X, X, 0 }, - { GIC_EXT_INTR(1), X, X, X, X, 0 }, - { GIC_EXT_INTR(2), X, X, X, X, 0 }, - { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(10), X, X, X, X, 0 }, - { GIC_EXT_INTR(11), X, X, X, X, 0 }, - { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, - { GIC_EXT_INTR(15), X, X, X, X, 0 }, - { GIC_EXT_INTR(16), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(17), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(18), 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(19), 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(20), 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(21), 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(22), 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, - { GIC_EXT_INTR(23), 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, -}; -#endif - -/* - * GCMP needs to be detected before any SMP initialisation - */ -static int __init gcmp_probe(unsigned long addr, unsigned long size) -{ - if (gcmp_present >= 0) - return gcmp_present; - - _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); - _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); - gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; - - if (gcmp_present) - printk(KERN_DEBUG "GCMP present\n"); - return gcmp_present; -} - -#if defined(CONFIG_MIPS_MT_SMP) -static void __init fill_ipi_map(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) { - if (gic_intr_map[i].ipiflag && (gic_intr_map[i].cpunum != X)) - ipi_map[gic_intr_map[i].cpunum] |= - (1 << (gic_intr_map[i].pin + 2)); - } -} -#endif - -void __init arch_init_irq(void) -{ - int gic_present, gcmp_present; - - init_i8259_irqs(); - - if (!cpu_has_veic) - mips_cpu_irq_init(); - - gcmp_present = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); - if (gcmp_present) { - GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; - gic_present = 1; - } else { - _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); - gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & - MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; - } - if (gic_present) - printk(KERN_DEBUG "GIC present\n"); - - switch (mips_revision_sconid) { - case MIPS_REVISION_SCON_SOCIT: - case MIPS_REVISION_SCON_ROCIT: - if (cpu_has_veic) - init_msc_irqs(MIPS_MSC01_IC_REG_BASE, - MSC01E_INT_BASE, msc_eicirqmap, - msc_nr_eicirqs); - else - init_msc_irqs(MIPS_MSC01_IC_REG_BASE, - MSC01C_INT_BASE, msc_irqmap, - msc_nr_irqs); - break; - - case MIPS_REVISION_SCON_SOCITSC: - case MIPS_REVISION_SCON_SOCITSCP: - if (cpu_has_veic) - init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, - MSC01E_INT_BASE, msc_eicirqmap, - msc_nr_eicirqs); - else - init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, - MSC01C_INT_BASE, msc_irqmap, - msc_nr_irqs); - } - - if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); - set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); - setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); - setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); - } else if (cpu_has_vint) { - set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); - set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); -#ifdef CONFIG_MIPS_MT_SMTC - setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq, - (0x100 << MIPSCPU_INT_I8259A)); - setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, - &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); - /* - * Temporary hack to ensure that the subsidiary device - * interrupts coing in via the i8259A, but associated - * with low IRQ numbers, will restore the Status.IM - * value associated with the i8259A. - */ - { - int i; - - for (i = 0; i < 16; i++) - irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A); - } -#else /* Not SMTC */ - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, - &corehi_irqaction); -#endif /* CONFIG_MIPS_MT_SMTC */ - } else { - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); - setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, - &corehi_irqaction); - } - -#if defined(CONFIG_MIPS_MT_SMP) - if (gic_present) { - /* FIXME */ - int i; - struct { - unsigned int resched; - unsigned int call; - } ipiirq[] = { - { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE0, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE0}, - { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE1, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE1 - }, { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE2, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE2 - }, { - .resched = GIC_IPI_EXT_INTR_RESCHED_VPE3, - .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3 - } - }; - fill_ipi_map(); - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); - if (!gcmp_present) { - /* Enable the GIC */ - i = REG(_msc01_biu_base, MSC01_SC_CFG); - REG(_msc01_biu_base, MSC01_SC_CFG) = - (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); - pr_debug("GIC Enabled\n"); - } - - /* set up ipi interrupts */ - if (cpu_has_vint) { - set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); - set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); - } - /* Argh.. this really needs sorting out.. */ - printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status()); - write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); - printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); - write_c0_status(0x1100dc00); - printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); - for (i = 0; i < ARRAY_SIZE(ipiirq); i++) { - setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, &irq_resched); - setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].call, &irq_call); - - set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, handle_percpu_irq); - set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].call, handle_percpu_irq); - } - } else { - /* set up ipi interrupts */ - if (cpu_has_veic) { - set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); - set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); - cpu_ipi_resched_irq = MSC01E_INT_SW0; - cpu_ipi_call_irq = MSC01E_INT_SW1; - } else { - if (cpu_has_vint) { - set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); - set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); - } - cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; - cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; - } - - setup_irq(cpu_ipi_resched_irq, &irq_resched); - setup_irq(cpu_ipi_call_irq, &irq_call); - - set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); - set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); - } -#endif -} - -void malta_be_init(void) -{ - if (gcmp_present) { - /* Could change CM error mask register */ - } -} - - -static char *tr[8] = { - "mem", "gcr", "gic", "mmio", - "0x04", "0x05", "0x06", "0x07" -}; - -static char *mcmd[32] = { - [0x00] = "0x00", - [0x01] = "Legacy Write", - [0x02] = "Legacy Read", - [0x03] = "0x03", - [0x04] = "0x04", - [0x05] = "0x05", - [0x06] = "0x06", - [0x07] = "0x07", - [0x08] = "Coherent Read Own", - [0x09] = "Coherent Read Share", - [0x0a] = "Coherent Read Discard", - [0x0b] = "Coherent Ready Share Always", - [0x0c] = "Coherent Upgrade", - [0x0d] = "Coherent Writeback", - [0x0e] = "0x0e", - [0x0f] = "0x0f", - [0x10] = "Coherent Copyback", - [0x11] = "Coherent Copyback Invalidate", - [0x12] = "Coherent Invalidate", - [0x13] = "Coherent Write Invalidate", - [0x14] = "Coherent Completion Sync", - [0x15] = "0x15", - [0x16] = "0x16", - [0x17] = "0x17", - [0x18] = "0x18", - [0x19] = "0x19", - [0x1a] = "0x1a", - [0x1b] = "0x1b", - [0x1c] = "0x1c", - [0x1d] = "0x1d", - [0x1e] = "0x1e", - [0x1f] = "0x1f" -}; - -static char *core[8] = { - "Invalid/OK", "Invalid/Data", - "Shared/OK", "Shared/Data", - "Modified/OK", "Modified/Data", - "Exclusive/OK", "Exclusive/Data" -}; - -static char *causes[32] = { - "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR", - "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", - "0x08", "0x09", "0x0a", "0x0b", - "0x0c", "0x0d", "0x0e", "0x0f", - "0x10", "0x11", "0x12", "0x13", - "0x14", "0x15", "0x16", "INTVN_WR_ERR", - "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", - "0x1c", "0x1d", "0x1e", "0x1f" -}; - -int malta_be_handler(struct pt_regs *regs, int is_fixup) -{ - /* This duplicates the handling in do_be which seems wrong */ - int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; - - if (gcmp_present) { - unsigned long cm_error = GCMPGCB(GCMEC); - unsigned long cm_addr = GCMPGCB(GCMEA); - unsigned long cm_other = GCMPGCB(GCMEO); - unsigned long cause, ocause; - char buf[256]; - - cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK); - if (cause != 0) { - cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF; - if (cause < 16) { - unsigned long cca_bits = (cm_error >> 15) & 7; - unsigned long tr_bits = (cm_error >> 12) & 7; - unsigned long mcmd_bits = (cm_error >> 7) & 0x1f; - unsigned long stag_bits = (cm_error >> 3) & 15; - unsigned long sport_bits = (cm_error >> 0) & 7; - - snprintf(buf, sizeof(buf), - "CCA=%lu TR=%s MCmd=%s STag=%lu " - "SPort=%lu\n", - cca_bits, tr[tr_bits], mcmd[mcmd_bits], - stag_bits, sport_bits); - } else { - /* glob state & sresp together */ - unsigned long c3_bits = (cm_error >> 18) & 7; - unsigned long c2_bits = (cm_error >> 15) & 7; - unsigned long c1_bits = (cm_error >> 12) & 7; - unsigned long c0_bits = (cm_error >> 9) & 7; - unsigned long sc_bit = (cm_error >> 8) & 1; - unsigned long mcmd_bits = (cm_error >> 3) & 0x1f; - unsigned long sport_bits = (cm_error >> 0) & 7; - snprintf(buf, sizeof(buf), - "C3=%s C2=%s C1=%s C0=%s SC=%s " - "MCmd=%s SPort=%lu\n", - core[c3_bits], core[c2_bits], - core[c1_bits], core[c0_bits], - sc_bit ? "True" : "False", - mcmd[mcmd_bits], sport_bits); - } - - ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >> - GCMP_GCB_GMEO_ERROR_2ND_SHF; - - printk("CM_ERROR=%08lx %s <%s>\n", cm_error, - causes[cause], buf); - printk("CM_ADDR =%08lx\n", cm_addr); - printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]); - - /* reprime cause register */ - GCMPGCB(GCMEC) = 0; - } - } - - return retval; -} diff --git a/arch/mips/mips-boards/malta/malta_mtd.c b/arch/mips/mips-boards/malta/malta_mtd.c deleted file mode 100644 index 8ad9bdf..0000000 --- a/arch/mips/mips-boards/malta/malta_mtd.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 MIPS Technologies, Inc. - * written by Ralf Baechle - */ - -#include -#include -#include -#include -#include - -static struct mtd_partition malta_mtd_partitions[] = { - { - .name = "YAMON", - .offset = 0x0, - .size = 0x100000, - .mask_flags = MTD_WRITEABLE - }, { - .name = "User FS", - .offset = 0x100000, - .size = 0x2e0000 - }, { - .name = "Board Config", - .offset = 0x3e0000, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE - } -}; - -static struct physmap_flash_data malta_flash_data = { - .width = 4, - .nr_parts = ARRAY_SIZE(malta_mtd_partitions), - .parts = malta_mtd_partitions -}; - -static struct resource malta_flash_resource = { - .start = 0x1e000000, - .end = 0x1e3fffff, - .flags = IORESOURCE_MEM -}; - -static struct platform_device malta_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &malta_flash_data, - }, - .num_resources = 1, - .resource = &malta_flash_resource, -}; - -static int __init malta_mtd_init(void) -{ - platform_device_register(&malta_flash); - - return 0; -} - -module_init(malta_mtd_init) diff --git a/arch/mips/mips-boards/malta/malta_platform.c b/arch/mips/mips-boards/malta/malta_platform.c deleted file mode 100644 index 83b9bab..0000000 --- a/arch/mips/mips-boards/malta/malta_platform.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2007 MIPS Technologies, Inc. - * written by Ralf Baechle (ralf@linux-mips.org) - * - * Probe driver for the Malta's UART ports: - * - * o 2 ports in the SMC SuperIO - * o 1 port in the CBUS UART, a discrete 16550 which normally is only used - * for bringups. - * - * We don't use 8250_platform.c on Malta as it would result in the CBUS - * UART becoming ttyS0. - */ -#include -#include -#include - -#define SMC_PORT(base, int) \ -{ \ - .iobase = base, \ - .irq = int, \ - .uartclk = 1843200, \ - .iotype = UPIO_PORT, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ - .regshift = 0, \ -} - -#define CBUS_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) - -static struct plat_serial8250_port uart8250_data[] = { - SMC_PORT(0x3F8, 4), - SMC_PORT(0x2F8, 3), - { - .mapbase = 0x1f000900, /* The CBUS UART */ - .irq = MIPS_CPU_IRQ_BASE + 2, - .uartclk = 3686400, /* Twice the usual clk! */ - .iotype = UPIO_MEM32, - .flags = CBUS_UART_FLAGS, - .regshift = 3, - }, - { }, -}; - -static struct platform_device uart8250_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM2, - .dev = { - .platform_data = uart8250_data, - }, -}; - -static int __init uart8250_init(void) -{ - return platform_device_register(&uart8250_device); -} - -module_init(uart8250_init); - -MODULE_AUTHOR("Ralf Baechle "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("8250 UART probe driver for the Malta CBUS UART"); diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c deleted file mode 100644 index e7cad54..0000000 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2008 Dmitri Vorobiev - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_VT -#include -#endif - -extern void malta_be_init(void); -extern int malta_be_handler(struct pt_regs *regs, int is_fixup); - -static struct resource standard_io_resources[] = { - { - .name = "dma1", - .start = 0x00, - .end = 0x1f, - .flags = IORESOURCE_BUSY - }, - { - .name = "timer", - .start = 0x40, - .end = 0x5f, - .flags = IORESOURCE_BUSY - }, - { - .name = "keyboard", - .start = 0x60, - .end = 0x6f, - .flags = IORESOURCE_BUSY - }, - { - .name = "dma page reg", - .start = 0x80, - .end = 0x8f, - .flags = IORESOURCE_BUSY - }, - { - .name = "dma2", - .start = 0xc0, - .end = 0xdf, - .flags = IORESOURCE_BUSY - }, -}; - -const char *get_system_type(void) -{ - return "MIPS Malta"; -} - -#if defined(CONFIG_MIPS_MT_SMTC) -const char display_string[] = " SMTC LINUX ON MALTA "; -#else -const char display_string[] = " LINUX ON MALTA "; -#endif /* CONFIG_MIPS_MT_SMTC */ - -#ifdef CONFIG_BLK_DEV_FD -static void __init fd_activate(void) -{ - /* - * Activate Floppy Controller in the SMSC FDC37M817 Super I/O - * Controller. - * Done by YAMON 2.00 onwards - */ - /* Entering config state. */ - SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); - - /* Activate floppy controller. */ - SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); - SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); - SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); - SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); - - /* Exit config state. */ - SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); -} -#endif - -#ifdef CONFIG_BLK_DEV_IDE -static void __init pci_clock_check(void) -{ - unsigned int __iomem *jmpr_p = - (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); - int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; - static const int pciclocks[] __initdata = { - 33, 20, 25, 30, 12, 16, 37, 10 - }; - int pciclock = pciclocks[jmpr]; - char *argptr = prom_getcmdline(); - - if (pciclock != 33 && !strstr(argptr, "idebus=")) { - printk(KERN_WARNING "WARNING: PCI clock is %dMHz, " - "setting idebus\n", pciclock); - argptr += strlen(argptr); - sprintf(argptr, " idebus=%d", pciclock); - if (pciclock < 20 || pciclock > 66) - printk(KERN_WARNING "WARNING: IDE timing " - "calculations will be incorrect\n"); - } -} -#endif - -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) -static void __init screen_info_setup(void) -{ - screen_info = (struct screen_info) { - .orig_x = 0, - .orig_y = 25, - .ext_mem_k = 0, - .orig_video_page = 0, - .orig_video_mode = 0, - .orig_video_cols = 80, - .unused2 = 0, - .orig_video_ega_bx = 0, - .unused3 = 0, - .orig_video_lines = 25, - .orig_video_isVGA = VIDEO_TYPE_VGAC, - .orig_video_points = 16 - }; -} -#endif - -static void __init bonito_quirks_setup(void) -{ - char *argptr; - - argptr = prom_getcmdline(); - if (strstr(argptr, "debug")) { - BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE; - printk(KERN_INFO "Enabled Bonito debug mode\n"); - } else - BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE; - -#ifdef CONFIG_DMA_COHERENT - if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { - BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; - printk(KERN_INFO "Enabled Bonito CPU coherency\n"); - - argptr = prom_getcmdline(); - if (strstr(argptr, "iobcuncached")) { - BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; - BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & - ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | - BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); - printk(KERN_INFO "Disabled Bonito IOBC coherency\n"); - } else { - BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; - BONITO_PCIMEMBASECFG |= - (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | - BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); - printk(KERN_INFO "Enabled Bonito IOBC coherency\n"); - } - } else - panic("Hardware DMA cache coherency not supported"); -#endif -} - -void __init plat_mem_setup(void) -{ - unsigned int i; - - mips_pcibios_init(); - - /* Request I/O space for devices used on the Malta board. */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, standard_io_resources+i); - - /* - * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. - */ - enable_dma(4); - -#ifdef CONFIG_KGDB - kgdb_config(); -#endif - -#ifdef CONFIG_DMA_COHERENT - if (mips_revision_sconid != MIPS_REVISION_SCON_BONITO) - panic("Hardware DMA cache coherency not supported"); -#endif - - if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) - bonito_quirks_setup(); - -#ifdef CONFIG_BLK_DEV_IDE - pci_clock_check(); -#endif - -#ifdef CONFIG_BLK_DEV_FD - fd_activate(); -#endif - -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - screen_info_setup(); -#endif - mips_reboot_setup(); - - board_be_init = malta_be_init; - board_be_handler = malta_be_handler; -} diff --git a/arch/mips/mips-boards/malta/malta_smtc.c b/arch/mips/mips-boards/malta/malta_smtc.c deleted file mode 100644 index 5ea705e..0000000 --- a/arch/mips/mips-boards/malta/malta_smtc.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Malta Platform-specific hooks for SMP operation - */ -#include -#include - -#include -#include -#include -#include - -/* VPE/SMP Prototype implements platform interfaces directly */ - -/* - * Cause the specified action to be performed on a targeted "CPU" - */ - -static void msmtc_send_ipi_single(int cpu, unsigned int action) -{ - /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ - smtc_send_ipi(cpu, LINUX_SMP_IPI, action); -} - -static void msmtc_send_ipi_mask(cpumask_t mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu_mask(i, mask) - msmtc_send_ipi_single(i, action); -} - -/* - * Post-config but pre-boot cleanup entry point - */ -static void __cpuinit msmtc_init_secondary(void) -{ - void smtc_init_secondary(void); - int myvpe; - - /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ - myvpe = read_c0_tcbind() & TCBIND_CURVPE; - if (myvpe != 0) { - /* Ideally, this should be done only once per VPE, but... */ - clear_c0_status(ST0_IM); - set_c0_status((0x100 << cp0_compare_irq) - | (0x100 << MIPS_CPU_IPI_IRQ)); - if (cp0_perfcount_irq >= 0) - set_c0_status(0x100 << cp0_perfcount_irq); - } - - smtc_init_secondary(); -} - -/* - * Platform "CPU" startup hook - */ -static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle) -{ - smtc_boot_secondary(cpu, idle); -} - -/* - * SMP initialization finalization entry point - */ -static void __cpuinit msmtc_smp_finish(void) -{ - smtc_smp_finish(); -} - -/* - * Hook for after all CPUs are online - */ - -static void msmtc_cpus_done(void) -{ -} - -/* - * Platform SMP pre-initialization - * - * As noted above, we can assume a single CPU for now - * but it may be multithreaded. - */ - -static void __init msmtc_smp_setup(void) -{ - mipsmt_build_cpu_map(0); -} - -static void __init msmtc_prepare_cpus(unsigned int max_cpus) -{ - mipsmt_prepare_cpus(); -} - -struct plat_smp_ops msmtc_smp_ops = { - .send_ipi_single = msmtc_send_ipi_single, - .send_ipi_mask = msmtc_send_ipi_mask, - .init_secondary = msmtc_init_secondary, - .smp_finish = msmtc_smp_finish, - .cpus_done = msmtc_cpus_done, - .boot_secondary = msmtc_boot_secondary, - .smp_setup = msmtc_smp_setup, - .prepare_cpus = msmtc_prepare_cpus, -}; - -#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF -/* - * IRQ affinity hook - */ - - -void plat_set_irq_affinity(unsigned int irq, cpumask_t affinity) -{ - cpumask_t tmask = affinity; - int cpu = 0; - void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff); - - /* - * On the legacy Malta development board, all I/O interrupts - * are routed through the 8259 and combined in a single signal - * to the CPU daughterboard, and on the CoreFPGA2/3 34K models, - * that signal is brought to IP2 of both VPEs. To avoid racing - * concurrent interrupt service events, IP2 is enabled only on - * one VPE, by convention VPE0. So long as no bits are ever - * cleared in the affinity mask, there will never be any - * interrupt forwarding. But as soon as a program or operator - * sets affinity for one of the related IRQs, we need to make - * sure that we don't ever try to forward across the VPE boundry, - * at least not until we engineer a system where the interrupt - * _ack() or _end() function can somehow know that it corresponds - * to an interrupt taken on another VPE, and perform the appropriate - * restoration of Status.IM state using MFTR/MTTR instead of the - * normal local behavior. We also ensure that no attempt will - * be made to forward to an offline "CPU". - */ - - for_each_cpu_mask(cpu, affinity) { - if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu)) - cpu_clear(cpu, tmask); - } - irq_desc[irq].affinity = tmask; - - if (cpus_empty(tmask)) - /* - * We could restore a default mask here, but the - * runtime code can anyway deal with the null set - */ - printk(KERN_WARNING - "IRQ affinity leaves no legal CPU for IRQ %d\n", irq); - - /* Do any generic SMTC IRQ affinity setup */ - smtc_set_irq_affinity(irq, tmask); -} -#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile new file mode 100644 index 0000000..f806444 --- /dev/null +++ b/arch/mips/mti-malta/Makefile @@ -0,0 +1,21 @@ +# +# Carsten Langgaard, carstenl@mips.com +# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. +# +# Copyright (C) 2008 Wind River Systems, Inc. +# written by Ralf Baechle +# +obj-y := malta-amon.o malta-cmdline.o \ + malta-display.o malta-init.o malta-int.o \ + malta-memory.o malta-mtd.o \ + malta-platform.o malta-reset.o \ + malta-setup.o malta-time.o + +obj-$(CONFIG_EARLY_PRINTK) += malta-console.o +obj-$(CONFIG_PCI) += malta-pci.o +obj-$(CONFIG_KGDB) += malta-kgdb.o + +# FIXME FIXME FIXME +obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mti-malta/malta-amon.c b/arch/mips/mti-malta/malta-amon.c new file mode 100644 index 0000000..96236bf --- /dev/null +++ b/arch/mips/mti-malta/malta-amon.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007 MIPS Technologies, Inc. + * All rights reserved. + + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Arbitrary Monitor interface + */ + +#include +#include +#include + +#include +#include +#include + +int amon_cpu_avail(int cpu) +{ + struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); + + if (cpu < 0 || cpu >= NCPULAUNCH) { + pr_debug("avail: cpu%d is out of range\n", cpu); + return 0; + } + + launch += cpu; + if (!(launch->flags & LAUNCH_FREADY)) { + pr_debug("avail: cpu%d is not ready\n", cpu); + return 0; + } + if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) { + pr_debug("avail: too late.. cpu%d is already gone\n", cpu); + return 0; + } + + return 1; +} + +void amon_cpu_start(int cpu, + unsigned long pc, unsigned long sp, + unsigned long gp, unsigned long a0) +{ + volatile struct cpulaunch *launch = + (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); + + if (!amon_cpu_avail(cpu)) + return; + if (cpu == smp_processor_id()) { + pr_debug("launch: I am cpu%d!\n", cpu); + return; + } + launch += cpu; + + pr_debug("launch: starting cpu%d\n", cpu); + + launch->pc = pc; + launch->gp = gp; + launch->sp = sp; + launch->a0 = a0; + + /* Make sure target sees parameters before the go bit */ + smp_mb(); + + launch->flags |= LAUNCH_FGO; + while ((launch->flags & LAUNCH_FGONE) == 0) + ; + pr_debug("launch: cpu%d gone!\n", cpu); +} diff --git a/arch/mips/mti-malta/malta-cmdline.c b/arch/mips/mti-malta/malta-cmdline.c new file mode 100644 index 0000000..1871c30 --- /dev/null +++ b/arch/mips/mti-malta/malta-cmdline.c @@ -0,0 +1,59 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Kernel command line creation using the prom monitor (YAMON) argc/argv. + */ +#include +#include + +#include + +extern int prom_argc; +extern int *_prom_argv; + +/* + * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. + * This macro take care of sign extension. + */ +#define prom_argv(index) ((char *)(long)_prom_argv[(index)]) + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv(actr)); + cp += strlen(prom_argv(actr)); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) { + /* get rid of trailing space */ + --cp; + *cp = '\0'; + } +} diff --git a/arch/mips/mti-malta/malta-console.c b/arch/mips/mti-malta/malta-console.c new file mode 100644 index 0000000..43bcfb4 --- /dev/null +++ b/arch/mips/mti-malta/malta-console.c @@ -0,0 +1,47 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Putting things on the screen/serial line using YAMONs facilities. + */ +#include +#include +#include +#include + + +#define PORT(offset) (0x3f8 + (offset)) + + +static inline unsigned int serial_in(int offset) +{ + return inb(PORT(offset)); +} + +static inline void serial_out(int offset, int value) +{ + outb(value, PORT(offset)); +} + +int prom_putchar(char c) +{ + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) + ; + + serial_out(UART_TX, c); + + return 1; +} diff --git a/arch/mips/mti-malta/malta-display.c b/arch/mips/mti-malta/malta-display.c new file mode 100644 index 0000000..7c8828f --- /dev/null +++ b/arch/mips/mti-malta/malta-display.c @@ -0,0 +1,64 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Display routines for display messages in MIPS boards ascii display. + */ + +#include +#include +#include +#include +#include + +extern const char display_string[]; +static unsigned int display_count; +static unsigned int max_display_count; + +void mips_display_message(const char *str) +{ + static unsigned int __iomem *display = NULL; + int i; + + if (unlikely(display == NULL)) + display = ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); + + for (i = 0; i <= 14; i=i+2) { + if (*str) + __raw_writel(*str++, display + i); + else + __raw_writel(' ', display + i); + } +} + +static void scroll_display_message(unsigned long data); +static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0); + +static void scroll_display_message(unsigned long data) +{ + mips_display_message(&display_string[display_count++]); + if (display_count == max_display_count) + display_count = 0; + + mod_timer(&mips_scroll_timer, jiffies + HZ); +} + +void mips_scroll_message(void) +{ + del_timer_sync(&mips_scroll_timer); + max_display_count = strlen(display_string) + 1 - 8; + mod_timer(&mips_scroll_timer, jiffies + 1); +} diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c new file mode 100644 index 0000000..c065302 --- /dev/null +++ b/arch/mips/mti-malta/malta-init.c @@ -0,0 +1,424 @@ +/* + * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * PROM library initialisation code. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_KGDB +extern int rs_kgdb_hook(int, int); +extern int rs_putDebugChar(char); +extern char rs_getDebugChar(void); +extern int saa9730_kgdb_hook(int); +extern int saa9730_putDebugChar(char); +extern char saa9730_getDebugChar(void); +#endif + +int prom_argc; +int *_prom_argv, *_prom_envp; + +/* + * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. + * This macro take care of sign extension, if running in 64-bit mode. + */ +#define prom_envp(index) ((char *)(long)_prom_envp[(index)]) + +int init_debug = 0; + +int mips_revision_corid; +int mips_revision_sconid; + +/* Bonito64 system controller register base. */ +unsigned long _pcictrl_bonito; +unsigned long _pcictrl_bonito_pcicfg; + +/* GT64120 system controller register base */ +unsigned long _pcictrl_gt64120; + +/* MIPS System controller register base */ +unsigned long _pcictrl_msc; + +char *prom_getenv(char *envname) +{ + /* + * Return a pointer to the given environment variable. + * In 64-bit mode: we're using 64-bit pointers, but all pointers + * in the PROM structures are only 32-bit, so we need some + * workarounds, if we are running in 64-bit mode. + */ + int i, index=0; + + i = strlen(envname); + + while (prom_envp(index)) { + if(strncmp(envname, prom_envp(index), i) == 0) { + return(prom_envp(index+1)); + } + index += 2; + } + + return NULL; +} + +static inline unsigned char str2hexnum(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; /* foo */ +} + +static inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for (i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + + if (init_debug > 1) { + int i; + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } + + return 0; +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static void __init console_config(void) +{ + char console_string[40]; + int baud = 0; + char parity = '\0', bits = '\0', flow = '\0'; + char *s; + + if ((strstr(prom_getcmdline(), "console=")) == NULL) { + s = prom_getenv("modetty0"); + if (s) { + while (*s >= '0' && *s <= '9') + baud = baud*10 + *s++ - '0'; + if (*s == ',') s++; + if (*s) parity = *s++; + if (*s == ',') s++; + if (*s) bits = *s++; + if (*s == ',') s++; + if (*s == 'h') flow = 'r'; + } + if (baud == 0) + baud = 38400; + if (parity != 'n' && parity != 'o' && parity != 'e') + parity = 'n'; + if (bits != '7' && bits != '8') + bits = '8'; + if (flow == '\0') + flow = 'r'; + sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); + strcat(prom_getcmdline(), console_string); + pr_info("Config serial console:%s\n", console_string); + } +} +#endif + +#ifdef CONFIG_KGDB +void __init kgdb_config(void) +{ + extern int (*generic_putDebugChar)(char); + extern char (*generic_getDebugChar)(void); + char *argptr; + int line, speed; + + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { + argptr += strlen("kgdb=ttyS"); + if (*argptr != '0' && *argptr != '1') + printk("KGDB: Unknown serial line /dev/ttyS%c, " + "falling back to /dev/ttyS1\n", *argptr); + line = *argptr == '0' ? 0 : 1; + printk("KGDB: Using serial line /dev/ttyS%d for session\n", line); + + speed = 0; + if (*++argptr == ',') + { + int c; + while ((c = *++argptr) && ('0' <= c && c <= '9')) + speed = speed * 10 + c - '0'; + } + { + speed = rs_kgdb_hook(line, speed); + generic_putDebugChar = rs_putDebugChar; + generic_getDebugChar = rs_getDebugChar; + } + + pr_info("KGDB: Using serial line /dev/ttyS%d at %d for " + "session, please connect your debugger\n", + line ? 1 : 0, speed); + + { + char *s; + for (s = "Please connect GDB to this port\r\n"; *s; ) + generic_putDebugChar(*s++); + } + + /* Breakpoint is invoked after interrupts are initialised */ + } +} +#endif + +static void __init mips_nmi_setup(void) +{ + void *base; + extern char except_vec_nmi; + + base = cpu_has_veic ? + (void *)(CAC_BASE + 0xa80) : + (void *)(CAC_BASE + 0x380); + memcpy(base, &except_vec_nmi, 0x80); + flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); +} + +static void __init mips_ejtag_setup(void) +{ + void *base; + extern char except_vec_ejtag_debug; + + base = cpu_has_veic ? + (void *)(CAC_BASE + 0xa00) : + (void *)(CAC_BASE + 0x300); + memcpy(base, &except_vec_ejtag_debug, 0x80); + flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); +} + +extern struct plat_smp_ops msmtc_smp_ops; + +void __init prom_init(void) +{ + prom_argc = fw_arg0; + _prom_argv = (int *) fw_arg1; + _prom_envp = (int *) fw_arg2; + + mips_display_message("LINUX"); + + /* + * early setup of _pcictrl_bonito so that we can determine + * the system controller on a CORE_EMUL board + */ + _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE); + + mips_revision_corid = MIPS_REVISION_CORID; + + if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) { + if (BONITO_PCIDID == 0x0001df53 || + BONITO_PCIDID == 0x0003df53) + mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON; + else + mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; + } + + mips_revision_sconid = MIPS_REVISION_SCONID; + if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) { + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_FPGAR2: + mips_revision_sconid = MIPS_REVISION_SCON_GT64120; + break; + case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + mips_revision_sconid = MIPS_REVISION_SCON_BONITO; + break; + case MIPS_REVISION_CORID_CORE_MSC: + case MIPS_REVISION_CORID_CORE_FPGA2: + case MIPS_REVISION_CORID_CORE_24K: + /* + * SOCit/ROCit support is essentially identical + * but make an attempt to distinguish them + */ + mips_revision_sconid = MIPS_REVISION_SCON_SOCIT; + break; + case MIPS_REVISION_CORID_CORE_FPGA3: + case MIPS_REVISION_CORID_CORE_FPGA4: + case MIPS_REVISION_CORID_CORE_FPGA5: + case MIPS_REVISION_CORID_CORE_EMUL_MSC: + default: + /* See above */ + mips_revision_sconid = MIPS_REVISION_SCON_ROCIT; + break; + } + } + + switch (mips_revision_sconid) { + u32 start, map, mask, data; + + case MIPS_REVISION_SCON_GT64120: + /* + * Setup the North bridge to do Master byte-lane swapping + * when running in bigendian. + */ + _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000); + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | + GT_PCI0_CMD_SBYTESWAP_BIT); +#else + GT_WRITE(GT_PCI0_CMD_OFS, 0); +#endif + /* Fix up PCI I/O mapping if necessary (for Atlas). */ + start = GT_READ(GT_PCI0IOLD_OFS); + map = GT_READ(GT_PCI0IOREMAP_OFS); + if ((start & map) != 0) { + map &= ~start; + GT_WRITE(GT_PCI0IOREMAP_OFS, map); + } + + set_io_port_base(MALTA_GT_PORT_BASE); + break; + + case MIPS_REVISION_SCON_BONITO: + _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); + + /* + * Disable Bonito IOBC. + */ + BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & + ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | + BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); + + /* + * Setup the North bridge to do Master byte-lane swapping + * when running in bigendian. + */ +#ifdef CONFIG_CPU_LITTLE_ENDIAN + BONITO_BONGENCFG = BONITO_BONGENCFG & + ~(BONITO_BONGENCFG_MSTRBYTESWAP | + BONITO_BONGENCFG_BYTESWAP); +#else + BONITO_BONGENCFG = BONITO_BONGENCFG | + BONITO_BONGENCFG_MSTRBYTESWAP | + BONITO_BONGENCFG_BYTESWAP; +#endif + + set_io_port_base(MALTA_BONITO_PORT_BASE); + break; + + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); + mips_pci_controller: + mb(); + MSC_READ(MSC01_PCI_CFG, data); + MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); + wmb(); + + /* Fix up lane swapping. */ +#ifdef CONFIG_CPU_LITTLE_ENDIAN + MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); +#else + MSC_WRITE(MSC01_PCI_SWAP, + MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF | + MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | + MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); +#endif + /* Fix up target memory mapping. */ + MSC_READ(MSC01_PCI_BAR0, mask); + MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK); + + /* Don't handle target retries indefinitely. */ + if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == + MSC01_PCI_CFG_MAXRTRY_MSK) + data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK << + MSC01_PCI_CFG_MAXRTRY_SHF)) | + ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) << + MSC01_PCI_CFG_MAXRTRY_SHF); + + wmb(); + MSC_WRITE(MSC01_PCI_CFG, data); + mb(); + + set_io_port_base(MALTA_MSC_PORT_BASE); + break; + + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: + _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000); + goto mips_pci_controller; + + default: + /* Unknown system controller */ + mips_display_message("SC Error"); + while (1); /* We die here... */ + } + board_nmi_handler_setup = mips_nmi_setup; + board_ejtag_handler_setup = mips_ejtag_setup; + + pr_info("\nLINUX started...\n"); + prom_init_cmdline(); + prom_meminit(); +#ifdef CONFIG_SERIAL_8250_CONSOLE + console_config(); +#endif +#ifdef CONFIG_MIPS_CMP + register_smp_ops(&cmp_smp_ops); +#endif +#ifdef CONFIG_MIPS_MT_SMP + register_smp_ops(&vsmp_smp_ops); +#endif +#ifdef CONFIG_MIPS_MT_SMTC + register_smp_ops(&msmtc_smp_ops); +#endif +} diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c new file mode 100644 index 0000000..ea17611 --- /dev/null +++ b/arch/mips/mti-malta/malta-int.c @@ -0,0 +1,712 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. + * Copyright (C) 2001 Ralf Baechle + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Routines for generic manipulation of the interrupts found on the MIPS + * Malta board. + * The interrupt controller is located in the South Bridge a PIIX4 device + * with two internal 82C95 interrupt controllers. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int gcmp_present = -1; +int gic_present; +static unsigned long _msc01_biu_base; +static unsigned long _gcmp_base; +static unsigned int ipi_map[NR_CPUS]; + +static DEFINE_SPINLOCK(mips_irq_lock); + +static inline int mips_pcibios_iack(void) +{ + int irq; + u32 dummy; + + /* + * Determine highest priority pending interrupt by performing + * a PCI Interrupt Acknowledge cycle. + */ + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: + MSC_READ(MSC01_PCI_IACK, irq); + irq &= 0xff; + break; + case MIPS_REVISION_SCON_GT64120: + irq = GT_READ(GT_PCI0_IACK_OFS); + irq &= 0xff; + break; + case MIPS_REVISION_SCON_BONITO: + /* The following will generate a PCI IACK cycle on the + * Bonito controller. It's a little bit kludgy, but it + * was the easiest way to implement it in hardware at + * the given time. + */ + BONITO_PCIMAP_CFG = 0x20000; + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + irq = readl((u32 *)_pcictrl_bonito_pcicfg); + iob(); /* sync */ + irq &= 0xff; + BONITO_PCIMAP_CFG = 0; + break; + default: + printk(KERN_WARNING "Unknown system controller.\n"); + return -1; + } + return irq; +} + +static inline int get_int(void) +{ + unsigned long flags; + int irq; + spin_lock_irqsave(&mips_irq_lock, flags); + + irq = mips_pcibios_iack(); + + /* + * The only way we can decide if an interrupt is spurious + * is by checking the 8259 registers. This needs a spinlock + * on an SMP system, so leave it up to the generic code... + */ + + spin_unlock_irqrestore(&mips_irq_lock, flags); + + return irq; +} + +static void malta_hw0_irqdispatch(void) +{ + int irq; + + irq = get_int(); + if (irq < 0) { + /* interrupt has already been cleared */ + return; + } + + do_IRQ(MALTA_INT_BASE + irq); +} + +static void malta_ipi_irqdispatch(void) +{ + int irq; + + irq = gic_get_int(); + if (irq < 0) + return; /* interrupt has already been cleared */ + + do_IRQ(MIPS_GIC_IRQ_BASE + irq); +} + +static void corehi_irqdispatch(void) +{ + unsigned int intedge, intsteer, pcicmd, pcibadaddr; + unsigned int pcimstat, intisr, inten, intpol; + unsigned int intrcause, datalo, datahi; + struct pt_regs *regs = get_irq_regs(); + + printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n"); + printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n" + "Cause : %08lx\nbadVaddr : %08lx\n", + regs->cp0_epc, regs->cp0_status, + regs->cp0_cause, regs->cp0_badvaddr); + + /* Read all the registers and then print them as there is a + problem with interspersed printk's upsetting the Bonito controller. + Do it for the others too. + */ + + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: + ll_msc_irq(); + break; + case MIPS_REVISION_SCON_GT64120: + intrcause = GT_READ(GT_INTRCAUSE_OFS); + datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); + datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); + printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause); + printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n", + datahi, datalo); + break; + case MIPS_REVISION_SCON_BONITO: + pcibadaddr = BONITO_PCIBADADDR; + pcimstat = BONITO_PCIMSTAT; + intisr = BONITO_INTISR; + inten = BONITO_INTEN; + intpol = BONITO_INTPOL; + intedge = BONITO_INTEDGE; + intsteer = BONITO_INTSTEER; + pcicmd = BONITO_PCICMD; + printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr); + printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten); + printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol); + printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge); + printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer); + printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd); + printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr); + printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat); + break; + } + + die("CoreHi interrupt", regs); +} + +static inline int clz(unsigned long x) +{ + __asm__( + " .set push \n" + " .set mips32 \n" + " clz %0, %1 \n" + " .set pop \n" + : "=r" (x) + : "r" (x)); + + return x; +} + +/* + * Version of ffs that only looks at bits 12..15. + */ +static inline unsigned int irq_ffs(unsigned int pending) +{ +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + return -clz(pending) + 31 - CAUSEB_IP; +#else + unsigned int a0 = 7; + unsigned int t0; + + t0 = pending & 0xf000; + t0 = t0 < 1; + t0 = t0 << 2; + a0 = a0 - t0; + pending = pending << t0; + + t0 = pending & 0xc000; + t0 = t0 < 1; + t0 = t0 << 1; + a0 = a0 - t0; + pending = pending << t0; + + t0 = pending & 0x8000; + t0 = t0 < 1; + /* t0 = t0 << 2; */ + a0 = a0 - t0; + /* pending = pending << t0; */ + + return a0; +#endif +} + +/* + * IRQs on the Malta board look basically (barring software IRQs which we + * don't use at all and all external interrupt sources are combined together + * on hardware interrupt 0 (MIPS IRQ 2)) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Combined hardware interrupt (hw0) + * 3 Hardware (ignored) + * 4 Hardware (ignored) + * 5 Hardware (ignored) + * 6 Hardware (ignored) + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Lowest ---- Combined hardware interrupt + * + * then we just return, if multiple IRQs are pending then we will just take + * another exception, big deal. + */ + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + int irq; + + irq = irq_ffs(pending); + + if (irq == MIPSCPU_INT_I8259A) + malta_hw0_irqdispatch(); + else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) + malta_ipi_irqdispatch(); + else if (irq >= 0) + do_IRQ(MIPS_CPU_IRQ_BASE + irq); + else + spurious_interrupt(); +} + +#ifdef CONFIG_MIPS_MT_SMP + + +#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 +#define GIC_MIPS_CPU_IPI_CALL_IRQ 4 + +#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ +#define C_RESCHED C_SW0 +#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ +#define C_CALL C_SW1 +static int cpu_ipi_resched_irq, cpu_ipi_call_irq; + +static void ipi_resched_dispatch(void) +{ + do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); +} + +static void ipi_call_dispatch(void) +{ + do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); +} + +static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) +{ + smp_call_function_interrupt(); + + return IRQ_HANDLED; +} + +static struct irqaction irq_resched = { + .handler = ipi_resched_interrupt, + .flags = IRQF_DISABLED|IRQF_PERCPU, + .name = "IPI_resched" +}; + +static struct irqaction irq_call = { + .handler = ipi_call_interrupt, + .flags = IRQF_DISABLED|IRQF_PERCPU, + .name = "IPI_call" +}; +#endif /* CONFIG_MIPS_MT_SMP */ + +static struct irqaction i8259irq = { + .handler = no_action, + .name = "XT-PIC cascade" +}; + +static struct irqaction corehi_irqaction = { + .handler = no_action, + .name = "CoreHi" +}; + +static msc_irqmap_t __initdata msc_irqmap[] = { + {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, + {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, +}; +static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap); + +static msc_irqmap_t __initdata msc_eicirqmap[] = { + {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, + {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, + {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} +}; + +static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); + +#if defined(CONFIG_MIPS_MT_SMP) +/* + * This GIC specific tabular array defines the association between External + * Interrupts and CPUs/Core Interrupts. The nature of the External + * Interrupts is also defined here - polarity/trigger. + */ +static struct gic_intr_map gic_intr_map[] = { + { GIC_EXT_INTR(0), X, X, X, X, 0 }, + { GIC_EXT_INTR(1), X, X, X, X, 0 }, + { GIC_EXT_INTR(2), X, X, X, X, 0 }, + { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(10), X, X, X, X, 0 }, + { GIC_EXT_INTR(11), X, X, X, X, 0 }, + { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, + { GIC_EXT_INTR(15), X, X, X, X, 0 }, + { GIC_EXT_INTR(16), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(17), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(18), 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(19), 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(20), 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(21), 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(22), 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(23), 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, +}; +#endif + +/* + * GCMP needs to be detected before any SMP initialisation + */ +static int __init gcmp_probe(unsigned long addr, unsigned long size) +{ + if (gcmp_present >= 0) + return gcmp_present; + + _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); + _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); + gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; + + if (gcmp_present) + printk(KERN_DEBUG "GCMP present\n"); + return gcmp_present; +} + +#if defined(CONFIG_MIPS_MT_SMP) +static void __init fill_ipi_map(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) { + if (gic_intr_map[i].ipiflag && (gic_intr_map[i].cpunum != X)) + ipi_map[gic_intr_map[i].cpunum] |= + (1 << (gic_intr_map[i].pin + 2)); + } +} +#endif + +void __init arch_init_irq(void) +{ + int gic_present, gcmp_present; + + init_i8259_irqs(); + + if (!cpu_has_veic) + mips_cpu_irq_init(); + + gcmp_present = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); + if (gcmp_present) { + GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; + gic_present = 1; + } else { + _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); + gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & + MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; + } + if (gic_present) + printk(KERN_DEBUG "GIC present\n"); + + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + if (cpu_has_veic) + init_msc_irqs(MIPS_MSC01_IC_REG_BASE, + MSC01E_INT_BASE, msc_eicirqmap, + msc_nr_eicirqs); + else + init_msc_irqs(MIPS_MSC01_IC_REG_BASE, + MSC01C_INT_BASE, msc_irqmap, + msc_nr_irqs); + break; + + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: + if (cpu_has_veic) + init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, + MSC01E_INT_BASE, msc_eicirqmap, + msc_nr_eicirqs); + else + init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, + MSC01C_INT_BASE, msc_irqmap, + msc_nr_irqs); + } + + if (cpu_has_veic) { + set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); + set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); + setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); + setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); + } else if (cpu_has_vint) { + set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); + set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); +#ifdef CONFIG_MIPS_MT_SMTC + setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq, + (0x100 << MIPSCPU_INT_I8259A)); + setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, + &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); + /* + * Temporary hack to ensure that the subsidiary device + * interrupts coing in via the i8259A, but associated + * with low IRQ numbers, will restore the Status.IM + * value associated with the i8259A. + */ + { + int i; + + for (i = 0; i < 16; i++) + irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A); + } +#else /* Not SMTC */ + setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); + setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, + &corehi_irqaction); +#endif /* CONFIG_MIPS_MT_SMTC */ + } else { + setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); + setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, + &corehi_irqaction); + } + +#if defined(CONFIG_MIPS_MT_SMP) + if (gic_present) { + /* FIXME */ + int i; + struct { + unsigned int resched; + unsigned int call; + } ipiirq[] = { + { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE0, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE0}, + { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE1, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE1 + }, { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE2, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE2 + }, { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE3, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3 + } + }; + fill_ipi_map(); + gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); + if (!gcmp_present) { + /* Enable the GIC */ + i = REG(_msc01_biu_base, MSC01_SC_CFG); + REG(_msc01_biu_base, MSC01_SC_CFG) = + (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); + pr_debug("GIC Enabled\n"); + } + + /* set up ipi interrupts */ + if (cpu_has_vint) { + set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); + set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); + } + /* Argh.. this really needs sorting out.. */ + printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status()); + write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); + printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); + write_c0_status(0x1100dc00); + printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); + for (i = 0; i < ARRAY_SIZE(ipiirq); i++) { + setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, &irq_resched); + setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].call, &irq_call); + + set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, handle_percpu_irq); + set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].call, handle_percpu_irq); + } + } else { + /* set up ipi interrupts */ + if (cpu_has_veic) { + set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); + set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); + cpu_ipi_resched_irq = MSC01E_INT_SW0; + cpu_ipi_call_irq = MSC01E_INT_SW1; + } else { + if (cpu_has_vint) { + set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); + set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); + } + cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; + cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; + } + + setup_irq(cpu_ipi_resched_irq, &irq_resched); + setup_irq(cpu_ipi_call_irq, &irq_call); + + set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); + set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); + } +#endif +} + +void malta_be_init(void) +{ + if (gcmp_present) { + /* Could change CM error mask register */ + } +} + + +static char *tr[8] = { + "mem", "gcr", "gic", "mmio", + "0x04", "0x05", "0x06", "0x07" +}; + +static char *mcmd[32] = { + [0x00] = "0x00", + [0x01] = "Legacy Write", + [0x02] = "Legacy Read", + [0x03] = "0x03", + [0x04] = "0x04", + [0x05] = "0x05", + [0x06] = "0x06", + [0x07] = "0x07", + [0x08] = "Coherent Read Own", + [0x09] = "Coherent Read Share", + [0x0a] = "Coherent Read Discard", + [0x0b] = "Coherent Ready Share Always", + [0x0c] = "Coherent Upgrade", + [0x0d] = "Coherent Writeback", + [0x0e] = "0x0e", + [0x0f] = "0x0f", + [0x10] = "Coherent Copyback", + [0x11] = "Coherent Copyback Invalidate", + [0x12] = "Coherent Invalidate", + [0x13] = "Coherent Write Invalidate", + [0x14] = "Coherent Completion Sync", + [0x15] = "0x15", + [0x16] = "0x16", + [0x17] = "0x17", + [0x18] = "0x18", + [0x19] = "0x19", + [0x1a] = "0x1a", + [0x1b] = "0x1b", + [0x1c] = "0x1c", + [0x1d] = "0x1d", + [0x1e] = "0x1e", + [0x1f] = "0x1f" +}; + +static char *core[8] = { + "Invalid/OK", "Invalid/Data", + "Shared/OK", "Shared/Data", + "Modified/OK", "Modified/Data", + "Exclusive/OK", "Exclusive/Data" +}; + +static char *causes[32] = { + "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR", + "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", + "0x08", "0x09", "0x0a", "0x0b", + "0x0c", "0x0d", "0x0e", "0x0f", + "0x10", "0x11", "0x12", "0x13", + "0x14", "0x15", "0x16", "INTVN_WR_ERR", + "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", + "0x1c", "0x1d", "0x1e", "0x1f" +}; + +int malta_be_handler(struct pt_regs *regs, int is_fixup) +{ + /* This duplicates the handling in do_be which seems wrong */ + int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; + + if (gcmp_present) { + unsigned long cm_error = GCMPGCB(GCMEC); + unsigned long cm_addr = GCMPGCB(GCMEA); + unsigned long cm_other = GCMPGCB(GCMEO); + unsigned long cause, ocause; + char buf[256]; + + cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK); + if (cause != 0) { + cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF; + if (cause < 16) { + unsigned long cca_bits = (cm_error >> 15) & 7; + unsigned long tr_bits = (cm_error >> 12) & 7; + unsigned long mcmd_bits = (cm_error >> 7) & 0x1f; + unsigned long stag_bits = (cm_error >> 3) & 15; + unsigned long sport_bits = (cm_error >> 0) & 7; + + snprintf(buf, sizeof(buf), + "CCA=%lu TR=%s MCmd=%s STag=%lu " + "SPort=%lu\n", + cca_bits, tr[tr_bits], mcmd[mcmd_bits], + stag_bits, sport_bits); + } else { + /* glob state & sresp together */ + unsigned long c3_bits = (cm_error >> 18) & 7; + unsigned long c2_bits = (cm_error >> 15) & 7; + unsigned long c1_bits = (cm_error >> 12) & 7; + unsigned long c0_bits = (cm_error >> 9) & 7; + unsigned long sc_bit = (cm_error >> 8) & 1; + unsigned long mcmd_bits = (cm_error >> 3) & 0x1f; + unsigned long sport_bits = (cm_error >> 0) & 7; + snprintf(buf, sizeof(buf), + "C3=%s C2=%s C1=%s C0=%s SC=%s " + "MCmd=%s SPort=%lu\n", + core[c3_bits], core[c2_bits], + core[c1_bits], core[c0_bits], + sc_bit ? "True" : "False", + mcmd[mcmd_bits], sport_bits); + } + + ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >> + GCMP_GCB_GMEO_ERROR_2ND_SHF; + + printk("CM_ERROR=%08lx %s <%s>\n", cm_error, + causes[cause], buf); + printk("CM_ADDR =%08lx\n", cm_addr); + printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]); + + /* reprime cause register */ + GCMPGCB(GCMEC) = 0; + } + } + + return retval; +} diff --git a/arch/mips/mti-malta/malta-kgdb.c b/arch/mips/mti-malta/malta-kgdb.c new file mode 100644 index 0000000..6a1854d --- /dev/null +++ b/arch/mips/mti-malta/malta-kgdb.c @@ -0,0 +1,133 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 is the interface to the remote debugger stub. + */ +#include +#include +#include +#include + +#include +#include + +static struct serial_state rs_table[] = { + SERIAL_PORT_DFNS /* Defined in serial.h */ +}; + +static struct async_struct kdb_port_info = {0}; + +int (*generic_putDebugChar)(char); +char (*generic_getDebugChar)(void); + +static __inline__ unsigned int serial_in(struct async_struct *info, int offset) +{ + return inb(info->port + offset); +} + +static __inline__ void serial_out(struct async_struct *info, int offset, + int value) +{ + outb(value, info->port+offset); +} + +int rs_kgdb_hook(int tty_no, int speed) { + int t; + struct serial_state *ser = &rs_table[tty_no]; + + kdb_port_info.state = ser; + kdb_port_info.magic = SERIAL_MAGIC; + kdb_port_info.port = ser->port; + kdb_port_info.flags = ser->flags; + + /* + * Clear all interrupts + */ + serial_in(&kdb_port_info, UART_LSR); + serial_in(&kdb_port_info, UART_RX); + serial_in(&kdb_port_info, UART_IIR); + serial_in(&kdb_port_info, UART_MSR); + + /* + * Now, initialize the UART + */ + serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ + if (kdb_port_info.flags & ASYNC_FOURPORT) { + kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS; + t = UART_MCR_DTR | UART_MCR_OUT1; + } else { + kdb_port_info.MCR + = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; + t = UART_MCR_DTR | UART_MCR_RTS; + } + + kdb_port_info.MCR = t; /* no interrupts, please */ + serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR); + + /* + * and set the speed of the serial port + */ + if (speed == 0) + speed = 9600; + + t = kdb_port_info.state->baud_base / speed; + /* set DLAB */ + serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB); + serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */ + serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */ + /* reset DLAB */ + serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); + + return speed; +} + +int putDebugChar(char c) +{ + return generic_putDebugChar(c); +} + +char getDebugChar(void) +{ + return generic_getDebugChar(); +} + +int rs_putDebugChar(char c) +{ + + if (!kdb_port_info.state) { /* need to init device first */ + return 0; + } + + while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0) + ; + + serial_out(&kdb_port_info, UART_TX, c); + + return 1; +} + +char rs_getDebugChar(void) +{ + if (!kdb_port_info.state) { /* need to init device first */ + return 0; + } + + while (!(serial_in(&kdb_port_info, UART_LSR) & 1)) + ; + + return serial_in(&kdb_port_info, UART_RX); +} diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c new file mode 100644 index 0000000..61888ff --- /dev/null +++ b/arch/mips/mti-malta/malta-memory.c @@ -0,0 +1,177 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * PROM library functions for acquiring/using memory descriptors given to + * us from the YAMON. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/*#define DEBUG*/ + +enum yamon_memtypes { + yamon_dontuse, + yamon_prom, + yamon_free, +}; +static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; + +#ifdef DEBUG +static char *mtypes[3] = { + "Dont use memory", + "YAMON PROM memory", + "Free memmory", +}; +#endif + +/* determined physical memory size, not overridden by command line args */ +unsigned long physical_memsize = 0L; + +static struct prom_pmemblock * __init prom_getmdesc(void) +{ + char *memsize_str; + unsigned int memsize; + char cmdline[CL_SIZE], *ptr; + + /* otherwise look in the environment */ + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + printk(KERN_WARNING + "memsize not set in boot prom, set to default (32Mb)\n"); + physical_memsize = 0x02000000; + } else { +#ifdef DEBUG + pr_debug("prom_memsize = %s\n", memsize_str); +#endif + physical_memsize = simple_strtol(memsize_str, NULL, 0); + } + +#ifdef CONFIG_CPU_BIG_ENDIAN + /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last + word of physical memory */ + physical_memsize -= PAGE_SIZE; +#endif + + /* Check the command line for a memsize directive that overrides + the physical/default amount */ + strcpy(cmdline, arcs_cmdline); + ptr = strstr(cmdline, "memsize="); + if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) + ptr = strstr(ptr, " memsize="); + + if (ptr) + memsize = memparse(ptr + 8, &ptr); + else + memsize = physical_memsize; + + memset(mdesc, 0, sizeof(mdesc)); + + mdesc[0].type = yamon_dontuse; + mdesc[0].base = 0x00000000; + mdesc[0].size = 0x00001000; + + mdesc[1].type = yamon_prom; + mdesc[1].base = 0x00001000; + mdesc[1].size = 0x000ef000; + + /* + * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the + * south bridge and PCI access always forwarded to the ISA Bus and + * BIOSCS# is always generated. + * This mean that this area can't be used as DMA memory for PCI + * devices. + */ + mdesc[2].type = yamon_dontuse; + mdesc[2].base = 0x000f0000; + mdesc[2].size = 0x00010000; + + mdesc[3].type = yamon_dontuse; + mdesc[3].base = 0x00100000; + mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; + + mdesc[4].type = yamon_free; + mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); + mdesc[4].size = memsize - mdesc[4].base; + + return &mdesc[0]; +} + +static int __init prom_memtype_classify(unsigned int type) +{ + switch (type) { + case yamon_free: + return BOOT_MEM_RAM; + case yamon_prom: + return BOOT_MEM_ROM_DATA; + default: + return BOOT_MEM_RESERVED; + } +} + +void __init prom_meminit(void) +{ + struct prom_pmemblock *p; + +#ifdef DEBUG + pr_debug("YAMON MEMORY DESCRIPTOR dump:\n"); + p = prom_getmdesc(); + while (p->size) { + int i = 0; + pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", + i, p, p->base, p->size, mtypes[p->type]); + p++; + i++; + } +#endif + p = prom_getmdesc(); + + while (p->size) { + long type; + unsigned long base, size; + + type = prom_memtype_classify(p->type); + base = p->base; + size = p->size; + + add_memory_region(base, size, type); + p++; + } +} + +void __init prom_free_prom_memory(void) +{ + unsigned long addr; + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) + continue; + + addr = boot_mem_map.map[i].addr; + free_init_pages("prom memory", + addr, addr + boot_mem_map.map[i].size); + } +} diff --git a/arch/mips/mti-malta/malta-mtd.c b/arch/mips/mti-malta/malta-mtd.c new file mode 100644 index 0000000..8ad9bdf --- /dev/null +++ b/arch/mips/mti-malta/malta-mtd.c @@ -0,0 +1,63 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2006 MIPS Technologies, Inc. + * written by Ralf Baechle + */ + +#include +#include +#include +#include +#include + +static struct mtd_partition malta_mtd_partitions[] = { + { + .name = "YAMON", + .offset = 0x0, + .size = 0x100000, + .mask_flags = MTD_WRITEABLE + }, { + .name = "User FS", + .offset = 0x100000, + .size = 0x2e0000 + }, { + .name = "Board Config", + .offset = 0x3e0000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE + } +}; + +static struct physmap_flash_data malta_flash_data = { + .width = 4, + .nr_parts = ARRAY_SIZE(malta_mtd_partitions), + .parts = malta_mtd_partitions +}; + +static struct resource malta_flash_resource = { + .start = 0x1e000000, + .end = 0x1e3fffff, + .flags = IORESOURCE_MEM +}; + +static struct platform_device malta_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &malta_flash_data, + }, + .num_resources = 1, + .resource = &malta_flash_resource, +}; + +static int __init malta_mtd_init(void) +{ + platform_device_register(&malta_flash); + + return 0; +} + +module_init(malta_mtd_init) diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c new file mode 100644 index 0000000..b974319 --- /dev/null +++ b/arch/mips/mti-malta/malta-pci.c @@ -0,0 +1,243 @@ +/* + * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki + * + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * MIPS boards specific PCI support. + */ +#include +#include +#include +#include + +#include + +#include +#include +#include + +static struct resource bonito64_mem_resource = { + .name = "Bonito PCI MEM", + .flags = IORESOURCE_MEM, +}; + +static struct resource bonito64_io_resource = { + .name = "Bonito PCI I/O", + .start = 0x00000000UL, + .end = 0x000fffffUL, + .flags = IORESOURCE_IO, +}; + +static struct resource gt64120_mem_resource = { + .name = "GT-64120 PCI MEM", + .flags = IORESOURCE_MEM, +}; + +static struct resource gt64120_io_resource = { + .name = "GT-64120 PCI I/O", + .flags = IORESOURCE_IO, +}; + +static struct resource msc_mem_resource = { + .name = "MSC PCI MEM", + .flags = IORESOURCE_MEM, +}; + +static struct resource msc_io_resource = { + .name = "MSC PCI I/O", + .flags = IORESOURCE_IO, +}; + +extern struct pci_ops bonito64_pci_ops; +extern struct pci_ops gt64xxx_pci0_ops; +extern struct pci_ops msc_pci_ops; + +static struct pci_controller bonito64_controller = { + .pci_ops = &bonito64_pci_ops, + .io_resource = &bonito64_io_resource, + .mem_resource = &bonito64_mem_resource, + .io_offset = 0x00000000UL, +}; + +static struct pci_controller gt64120_controller = { + .pci_ops = >64xxx_pci0_ops, + .io_resource = >64120_io_resource, + .mem_resource = >64120_mem_resource, +}; + +static struct pci_controller msc_controller = { + .pci_ops = &msc_pci_ops, + .io_resource = &msc_io_resource, + .mem_resource = &msc_mem_resource, +}; + +void __init mips_pcibios_init(void) +{ + struct pci_controller *controller; + resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; + + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_GT64120: + /* + * Due to a bug in the Galileo system controller, we need + * to setup the PCI BAR for the Galileo internal registers. + * This should be done in the bios/bootprom and will be + * fixed in a later revision of YAMON (the MIPS boards + * boot prom). + */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ + (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ + ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + /* Perform the write */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); + + /* Set up resource ranges from the controller's registers. */ + start = GT_READ(GT_PCI0M0LD_OFS); + end = GT_READ(GT_PCI0M0HD_OFS); + map = GT_READ(GT_PCI0M0REMAP_OFS); + end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK); + start1 = GT_READ(GT_PCI0M1LD_OFS); + end1 = GT_READ(GT_PCI0M1HD_OFS); + map1 = GT_READ(GT_PCI0M1REMAP_OFS); + end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK); + /* Cannot support multiple windows, use the wider. */ + if (end1 - start1 > end - start) { + start = start1; + end = end1; + map = map1; + } + mask = ~(start ^ end); + /* We don't support remapping with a discontiguous mask. */ + BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) && + mask != ~((mask & -mask) - 1)); + gt64120_mem_resource.start = start; + gt64120_mem_resource.end = end; + gt64120_controller.mem_offset = (start & mask) - (map & mask); + /* Addresses are 36-bit, so do shifts in the destinations. */ + gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF; + gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF; + gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1; + gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF; + + start = GT_READ(GT_PCI0IOLD_OFS); + end = GT_READ(GT_PCI0IOHD_OFS); + map = GT_READ(GT_PCI0IOREMAP_OFS); + end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK); + mask = ~(start ^ end); + /* We don't support remapping with a discontiguous mask. */ + BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) && + mask != ~((mask & -mask) - 1)); + gt64120_io_resource.start = map & mask; + gt64120_io_resource.end = (map & mask) | ~mask; + gt64120_controller.io_offset = 0; + /* Addresses are 36-bit, so do shifts in the destinations. */ + gt64120_io_resource.start <<= GT_PCI_DCRM_SHF; + gt64120_io_resource.end <<= GT_PCI_DCRM_SHF; + gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1; + + controller = >64120_controller; + break; + + case MIPS_REVISION_SCON_BONITO: + /* Set up resource ranges from the controller's registers. */ + map = BONITO_PCIMAP; + map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >> + BONITO_PCIMAP_PCIMAP_LO0_SHIFT; + map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >> + BONITO_PCIMAP_PCIMAP_LO1_SHIFT; + map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >> + BONITO_PCIMAP_PCIMAP_LO2_SHIFT; + /* Combine as many adjacent windows as possible. */ + map = map1; + start = BONITO_PCILO0_BASE; + end = 1; + if (map3 == map2 + 1) { + map = map2; + start = BONITO_PCILO1_BASE; + end++; + } + if (map2 == map1 + 1) { + map = map1; + start = BONITO_PCILO0_BASE; + end++; + } + bonito64_mem_resource.start = start; + bonito64_mem_resource.end = start + + BONITO_PCIMAP_WINBASE(end) - 1; + bonito64_controller.mem_offset = start - + BONITO_PCIMAP_WINBASE(map); + + controller = &bonito64_controller; + break; + + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: + /* Set up resource ranges from the controller's registers. */ + MSC_READ(MSC01_PCI_SC2PMBASL, start); + MSC_READ(MSC01_PCI_SC2PMMSKL, mask); + MSC_READ(MSC01_PCI_SC2PMMAPL, map); + msc_mem_resource.start = start & mask; + msc_mem_resource.end = (start & mask) | ~mask; + msc_controller.mem_offset = (start & mask) - (map & mask); + + MSC_READ(MSC01_PCI_SC2PIOBASL, start); + MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); + MSC_READ(MSC01_PCI_SC2PIOMAPL, map); + msc_io_resource.start = map & mask; + msc_io_resource.end = (map & mask) | ~mask; + msc_controller.io_offset = 0; + ioport_resource.end = ~mask; + + /* If ranges overlap I/O takes precedence. */ + start = start & mask; + end = start | ~mask; + if ((start >= msc_mem_resource.start && + start <= msc_mem_resource.end) || + (end >= msc_mem_resource.start && + end <= msc_mem_resource.end)) { + /* Use the larger space. */ + start = max(start, msc_mem_resource.start); + end = min(end, msc_mem_resource.end); + if (start - msc_mem_resource.start >= + msc_mem_resource.end - end) + msc_mem_resource.end = start - 1; + else + msc_mem_resource.start = end + 1; + } + + controller = &msc_controller; + break; + default: + return; + } + + if (controller->io_resource->start < 0x00001000UL) /* FIXME */ + controller->io_resource->start = 0x00001000UL; + + iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ + ioport_resource.end = controller->io_resource->end; + + register_pci_controller(controller); +} diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c new file mode 100644 index 0000000..83b9bab --- /dev/null +++ b/arch/mips/mti-malta/malta-platform.c @@ -0,0 +1,65 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 MIPS Technologies, Inc. + * written by Ralf Baechle (ralf@linux-mips.org) + * + * Probe driver for the Malta's UART ports: + * + * o 2 ports in the SMC SuperIO + * o 1 port in the CBUS UART, a discrete 16550 which normally is only used + * for bringups. + * + * We don't use 8250_platform.c on Malta as it would result in the CBUS + * UART becoming ttyS0. + */ +#include +#include +#include + +#define SMC_PORT(base, int) \ +{ \ + .iobase = base, \ + .irq = int, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +#define CBUS_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) + +static struct plat_serial8250_port uart8250_data[] = { + SMC_PORT(0x3F8, 4), + SMC_PORT(0x2F8, 3), + { + .mapbase = 0x1f000900, /* The CBUS UART */ + .irq = MIPS_CPU_IRQ_BASE + 2, + .uartclk = 3686400, /* Twice the usual clk! */ + .iotype = UPIO_MEM32, + .flags = CBUS_UART_FLAGS, + .regshift = 3, + }, + { }, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM2, + .dev = { + .platform_data = uart8250_data, + }, +}; + +static int __init uart8250_init(void) +{ + return platform_device_register(&uart8250_device); +} + +module_init(uart8250_init); + +MODULE_AUTHOR("Ralf Baechle "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("8250 UART probe driver for the Malta CBUS UART"); diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c new file mode 100644 index 0000000..42dee4d --- /dev/null +++ b/arch/mips/mti-malta/malta-reset.c @@ -0,0 +1,56 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * ######################################################################## + * + * Reset the MIPS boards. + * + */ +#include + +#include +#include +#include + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ + unsigned int __iomem *softres_reg = + ioremap(SOFTRES_REG, sizeof(unsigned int)); + + __raw_writel(GORESET, softres_reg); +} + +static void mips_machine_halt(void) +{ + unsigned int __iomem *softres_reg = + ioremap(SOFTRES_REG, sizeof(unsigned int)); + + __raw_writel(GORESET, softres_reg); +} + + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; + pm_power_off = mips_machine_halt; +} diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c new file mode 100644 index 0000000..e7cad54 --- /dev/null +++ b/arch/mips/mti-malta/malta-setup.c @@ -0,0 +1,229 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2008 Dmitri Vorobiev + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_VT +#include +#endif + +extern void malta_be_init(void); +extern int malta_be_handler(struct pt_regs *regs, int is_fixup); + +static struct resource standard_io_resources[] = { + { + .name = "dma1", + .start = 0x00, + .end = 0x1f, + .flags = IORESOURCE_BUSY + }, + { + .name = "timer", + .start = 0x40, + .end = 0x5f, + .flags = IORESOURCE_BUSY + }, + { + .name = "keyboard", + .start = 0x60, + .end = 0x6f, + .flags = IORESOURCE_BUSY + }, + { + .name = "dma page reg", + .start = 0x80, + .end = 0x8f, + .flags = IORESOURCE_BUSY + }, + { + .name = "dma2", + .start = 0xc0, + .end = 0xdf, + .flags = IORESOURCE_BUSY + }, +}; + +const char *get_system_type(void) +{ + return "MIPS Malta"; +} + +#if defined(CONFIG_MIPS_MT_SMTC) +const char display_string[] = " SMTC LINUX ON MALTA "; +#else +const char display_string[] = " LINUX ON MALTA "; +#endif /* CONFIG_MIPS_MT_SMTC */ + +#ifdef CONFIG_BLK_DEV_FD +static void __init fd_activate(void) +{ + /* + * Activate Floppy Controller in the SMSC FDC37M817 Super I/O + * Controller. + * Done by YAMON 2.00 onwards + */ + /* Entering config state. */ + SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); + + /* Activate floppy controller. */ + SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); + SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); + SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); + SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); + + /* Exit config state. */ + SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); +} +#endif + +#ifdef CONFIG_BLK_DEV_IDE +static void __init pci_clock_check(void) +{ + unsigned int __iomem *jmpr_p = + (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); + int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; + static const int pciclocks[] __initdata = { + 33, 20, 25, 30, 12, 16, 37, 10 + }; + int pciclock = pciclocks[jmpr]; + char *argptr = prom_getcmdline(); + + if (pciclock != 33 && !strstr(argptr, "idebus=")) { + printk(KERN_WARNING "WARNING: PCI clock is %dMHz, " + "setting idebus\n", pciclock); + argptr += strlen(argptr); + sprintf(argptr, " idebus=%d", pciclock); + if (pciclock < 20 || pciclock > 66) + printk(KERN_WARNING "WARNING: IDE timing " + "calculations will be incorrect\n"); + } +} +#endif + +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) +static void __init screen_info_setup(void) +{ + screen_info = (struct screen_info) { + .orig_x = 0, + .orig_y = 25, + .ext_mem_k = 0, + .orig_video_page = 0, + .orig_video_mode = 0, + .orig_video_cols = 80, + .unused2 = 0, + .orig_video_ega_bx = 0, + .unused3 = 0, + .orig_video_lines = 25, + .orig_video_isVGA = VIDEO_TYPE_VGAC, + .orig_video_points = 16 + }; +} +#endif + +static void __init bonito_quirks_setup(void) +{ + char *argptr; + + argptr = prom_getcmdline(); + if (strstr(argptr, "debug")) { + BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE; + printk(KERN_INFO "Enabled Bonito debug mode\n"); + } else + BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE; + +#ifdef CONFIG_DMA_COHERENT + if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { + BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; + printk(KERN_INFO "Enabled Bonito CPU coherency\n"); + + argptr = prom_getcmdline(); + if (strstr(argptr, "iobcuncached")) { + BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; + BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & + ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | + BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); + printk(KERN_INFO "Disabled Bonito IOBC coherency\n"); + } else { + BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; + BONITO_PCIMEMBASECFG |= + (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | + BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); + printk(KERN_INFO "Enabled Bonito IOBC coherency\n"); + } + } else + panic("Hardware DMA cache coherency not supported"); +#endif +} + +void __init plat_mem_setup(void) +{ + unsigned int i; + + mips_pcibios_init(); + + /* Request I/O space for devices used on the Malta board. */ + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + request_resource(&ioport_resource, standard_io_resources+i); + + /* + * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. + */ + enable_dma(4); + +#ifdef CONFIG_KGDB + kgdb_config(); +#endif + +#ifdef CONFIG_DMA_COHERENT + if (mips_revision_sconid != MIPS_REVISION_SCON_BONITO) + panic("Hardware DMA cache coherency not supported"); +#endif + + if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) + bonito_quirks_setup(); + +#ifdef CONFIG_BLK_DEV_IDE + pci_clock_check(); +#endif + +#ifdef CONFIG_BLK_DEV_FD + fd_activate(); +#endif + +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) + screen_info_setup(); +#endif + mips_reboot_setup(); + + board_be_init = malta_be_init; + board_be_handler = malta_be_handler; +} diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c new file mode 100644 index 0000000..5ea705e --- /dev/null +++ b/arch/mips/mti-malta/malta-smtc.c @@ -0,0 +1,154 @@ +/* + * Malta Platform-specific hooks for SMP operation + */ +#include +#include + +#include +#include +#include +#include + +/* VPE/SMP Prototype implements platform interfaces directly */ + +/* + * Cause the specified action to be performed on a targeted "CPU" + */ + +static void msmtc_send_ipi_single(int cpu, unsigned int action) +{ + /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ + smtc_send_ipi(cpu, LINUX_SMP_IPI, action); +} + +static void msmtc_send_ipi_mask(cpumask_t mask, unsigned int action) +{ + unsigned int i; + + for_each_cpu_mask(i, mask) + msmtc_send_ipi_single(i, action); +} + +/* + * Post-config but pre-boot cleanup entry point + */ +static void __cpuinit msmtc_init_secondary(void) +{ + void smtc_init_secondary(void); + int myvpe; + + /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ + myvpe = read_c0_tcbind() & TCBIND_CURVPE; + if (myvpe != 0) { + /* Ideally, this should be done only once per VPE, but... */ + clear_c0_status(ST0_IM); + set_c0_status((0x100 << cp0_compare_irq) + | (0x100 << MIPS_CPU_IPI_IRQ)); + if (cp0_perfcount_irq >= 0) + set_c0_status(0x100 << cp0_perfcount_irq); + } + + smtc_init_secondary(); +} + +/* + * Platform "CPU" startup hook + */ +static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle) +{ + smtc_boot_secondary(cpu, idle); +} + +/* + * SMP initialization finalization entry point + */ +static void __cpuinit msmtc_smp_finish(void) +{ + smtc_smp_finish(); +} + +/* + * Hook for after all CPUs are online + */ + +static void msmtc_cpus_done(void) +{ +} + +/* + * Platform SMP pre-initialization + * + * As noted above, we can assume a single CPU for now + * but it may be multithreaded. + */ + +static void __init msmtc_smp_setup(void) +{ + mipsmt_build_cpu_map(0); +} + +static void __init msmtc_prepare_cpus(unsigned int max_cpus) +{ + mipsmt_prepare_cpus(); +} + +struct plat_smp_ops msmtc_smp_ops = { + .send_ipi_single = msmtc_send_ipi_single, + .send_ipi_mask = msmtc_send_ipi_mask, + .init_secondary = msmtc_init_secondary, + .smp_finish = msmtc_smp_finish, + .cpus_done = msmtc_cpus_done, + .boot_secondary = msmtc_boot_secondary, + .smp_setup = msmtc_smp_setup, + .prepare_cpus = msmtc_prepare_cpus, +}; + +#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF +/* + * IRQ affinity hook + */ + + +void plat_set_irq_affinity(unsigned int irq, cpumask_t affinity) +{ + cpumask_t tmask = affinity; + int cpu = 0; + void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff); + + /* + * On the legacy Malta development board, all I/O interrupts + * are routed through the 8259 and combined in a single signal + * to the CPU daughterboard, and on the CoreFPGA2/3 34K models, + * that signal is brought to IP2 of both VPEs. To avoid racing + * concurrent interrupt service events, IP2 is enabled only on + * one VPE, by convention VPE0. So long as no bits are ever + * cleared in the affinity mask, there will never be any + * interrupt forwarding. But as soon as a program or operator + * sets affinity for one of the related IRQs, we need to make + * sure that we don't ever try to forward across the VPE boundry, + * at least not until we engineer a system where the interrupt + * _ack() or _end() function can somehow know that it corresponds + * to an interrupt taken on another VPE, and perform the appropriate + * restoration of Status.IM state using MFTR/MTTR instead of the + * normal local behavior. We also ensure that no attempt will + * be made to forward to an offline "CPU". + */ + + for_each_cpu_mask(cpu, affinity) { + if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu)) + cpu_clear(cpu, tmask); + } + irq_desc[irq].affinity = tmask; + + if (cpus_empty(tmask)) + /* + * We could restore a default mask here, but the + * runtime code can anyway deal with the null set + */ + printk(KERN_WARNING + "IRQ affinity leaves no legal CPU for IRQ %d\n", irq); + + /* Do any generic SMTC IRQ affinity setup */ + smtc_set_irq_affinity(irq, tmask); +} +#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c new file mode 100644 index 0000000..0b97d47 --- /dev/null +++ b/arch/mips/mti-malta/malta-time.c @@ -0,0 +1,163 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Setting up the clock on the MIPS boards. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +unsigned long cpu_khz; + +static int mips_cpu_timer_irq; +static int mips_cpu_perf_irq; +extern int cp0_perfcount_irq; + +static void mips_timer_dispatch(void) +{ + do_IRQ(mips_cpu_timer_irq); +} + +static void mips_perf_dispatch(void) +{ + do_IRQ(mips_cpu_perf_irq); +} + +/* + * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect + */ +static unsigned int __init estimate_cpu_frequency(void) +{ + unsigned int prid = read_c0_prid() & 0xffff00; + unsigned int count; + + unsigned long flags; + unsigned int start; + + local_irq_save(flags); + + /* Start counter exactly on falling edge of update flag */ + while (CMOS_READ(RTC_REG_A) & RTC_UIP); + while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); + + /* Start r4k counter. */ + start = read_c0_count(); + + /* Read counter exactly on falling edge of update flag */ + while (CMOS_READ(RTC_REG_A) & RTC_UIP); + while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); + + count = read_c0_count() - start; + + /* restore interrupts */ + local_irq_restore(flags); + + mips_hpt_frequency = count; + if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && + (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) + count *= 2; + + count += 5000; /* round */ + count -= count%10000; + + return count; +} + +unsigned long read_persistent_clock(void) +{ + return mc146818_get_cmos_time(); +} + +static void __init plat_perf_setup(void) +{ +#ifdef MSC01E_INT_BASE + if (cpu_has_veic) { + set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); + mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; + } else +#endif + if (cp0_perfcount_irq >= 0) { + if (cpu_has_vint) + set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); + mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; +#ifdef CONFIG_SMP + set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq); +#endif + } +} + +unsigned int __cpuinit get_c0_compare_int(void) +{ +#ifdef MSC01E_INT_BASE + if (cpu_has_veic) { + set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); + mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; + } else +#endif + { + if (cpu_has_vint) + set_vi_handler(cp0_compare_irq, mips_timer_dispatch); + mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + } + + return mips_cpu_timer_irq; +} + +void __init plat_time_init(void) +{ + unsigned int est_freq; + + /* Set Data mode - binary. */ + CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); + + est_freq = estimate_cpu_frequency(); + + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000); + + cpu_khz = est_freq / 1000; + + mips_scroll_message(); +#ifdef CONFIG_I8253 /* Only Malta has a PIT */ + setup_pit_timer(); +#endif + + plat_perf_setup(); +} diff --git a/include/asm-mips/mach-malta/cpu-feature-overrides.h b/include/asm-mips/mach-malta/cpu-feature-overrides.h new file mode 100644 index 0000000..7f3e3f9 --- /dev/null +++ b/include/asm-mips/mach-malta/cpu-feature-overrides.h @@ -0,0 +1,72 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003, 2004 Chris Dearman + * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) + */ +#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H + + +/* + * CPU feature overrides for MIPS boards + */ +#ifdef CONFIG_CPU_MIPS32 +#define cpu_has_tlb 1 +#define cpu_has_4kex 1 +#define cpu_has_4k_cache 1 +/* #define cpu_has_fpu ? */ +/* #define cpu_has_32fpr ? */ +#define cpu_has_counter 1 +/* #define cpu_has_watch ? */ +#define cpu_has_divec 1 +#define cpu_has_vce 0 +/* #define cpu_has_cache_cdex_p ? */ +/* #define cpu_has_cache_cdex_s ? */ +/* #define cpu_has_prefetch ? */ +#define cpu_has_mcheck 1 +/* #define cpu_has_ejtag ? */ +#ifdef CONFIG_CPU_HAS_LLSC +#define cpu_has_llsc 1 +#else +#define cpu_has_llsc 0 +#endif +/* #define cpu_has_vtag_icache ? */ +/* #define cpu_has_dc_aliases ? */ +/* #define cpu_has_ic_fills_f_dc ? */ +#define cpu_has_nofpuex 0 +/* #define cpu_has_64bits ? */ +/* #define cpu_has_64bit_zero_reg ? */ +/* #define cpu_has_inclusive_pcaches ? */ +#define cpu_icache_snoops_remote_store 1 +#endif + +#ifdef CONFIG_CPU_MIPS64 +#define cpu_has_tlb 1 +#define cpu_has_4kex 1 +#define cpu_has_4k_cache 1 +/* #define cpu_has_fpu ? */ +/* #define cpu_has_32fpr ? */ +#define cpu_has_counter 1 +/* #define cpu_has_watch ? */ +#define cpu_has_divec 1 +#define cpu_has_vce 0 +/* #define cpu_has_cache_cdex_p ? */ +/* #define cpu_has_cache_cdex_s ? */ +/* #define cpu_has_prefetch ? */ +#define cpu_has_mcheck 1 +/* #define cpu_has_ejtag ? */ +#define cpu_has_llsc 1 +/* #define cpu_has_vtag_icache ? */ +/* #define cpu_has_dc_aliases ? */ +/* #define cpu_has_ic_fills_f_dc ? */ +#define cpu_has_nofpuex 0 +/* #define cpu_has_64bits ? */ +/* #define cpu_has_64bit_zero_reg ? */ +/* #define cpu_has_inclusive_pcaches ? */ +#define cpu_icache_snoops_remote_store 1 +#endif + +#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */ diff --git a/include/asm-mips/mach-malta/irq.h b/include/asm-mips/mach-malta/irq.h new file mode 100644 index 0000000..9b9da26 --- /dev/null +++ b/include/asm-mips/mach-malta/irq.h @@ -0,0 +1,9 @@ +#ifndef __ASM_MACH_MIPS_IRQ_H +#define __ASM_MACH_MIPS_IRQ_H + + +#define NR_IRQS 256 + +#include_next + +#endif /* __ASM_MACH_MIPS_IRQ_H */ diff --git a/include/asm-mips/mach-malta/kernel-entry-init.h b/include/asm-mips/mach-malta/kernel-entry-init.h new file mode 100644 index 0000000..0b793e7 --- /dev/null +++ b/include/asm-mips/mach-malta/kernel-entry-init.h @@ -0,0 +1,52 @@ +/* + * 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. + * + * Chris Dearman (chris@mips.com) + * Copyright (C) 2007 Mips Technologies, Inc. + */ +#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H +#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H + + .macro kernel_entry_setup +#ifdef CONFIG_MIPS_MT_SMTC + mfc0 t0, CP0_CONFIG + bgez t0, 9f + mfc0 t0, CP0_CONFIG, 1 + bgez t0, 9f + mfc0 t0, CP0_CONFIG, 2 + bgez t0, 9f + mfc0 t0, CP0_CONFIG, 3 + and t0, 1<<2 + bnez t0, 0f +9: + /* Assume we came from YAMON... */ + PTR_LA v0, 0x9fc00534 /* YAMON print */ + lw v0, (v0) + move a0, zero + PTR_LA a1, nonmt_processor + jal v0 + + PTR_LA v0, 0x9fc00520 /* YAMON exit */ + lw v0, (v0) + li a0, 1 + jal v0 + +1: b 1b + + __INITDATA +nonmt_processor: + .asciz "SMTC kernel requires the MT ASE to run\n" + __FINIT +0: +#endif + .endm + +/* + * Do SMP slave processor setup necessary before we can safely execute C code. + */ + .macro smp_slave_setup + .endm + +#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */ diff --git a/include/asm-mips/mach-malta/mach-gt64120.h b/include/asm-mips/mach-malta/mach-gt64120.h new file mode 100644 index 0000000..0f86314 --- /dev/null +++ b/include/asm-mips/mach-malta/mach-gt64120.h @@ -0,0 +1,19 @@ +/* + * This is a direct copy of the ev96100.h file, with a global + * search and replace. The numbers are the same. + * + * The reason I'm duplicating this is so that the 64120/96100 + * defines won't be confusing in the source code. + */ +#ifndef _ASM_MACH_MIPS_MACH_GT64120_DEP_H +#define _ASM_MACH_MIPS_MACH_GT64120_DEP_H + +#define MIPS_GT_BASE 0x1be00000 + +extern unsigned long _pcictrl_gt64120; +/* + * GT64120 config space base address + */ +#define GT64120_BASE _pcictrl_gt64120 + +#endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */ diff --git a/include/asm-mips/mach-malta/mc146818rtc.h b/include/asm-mips/mach-malta/mc146818rtc.h new file mode 100644 index 0000000..ea612f3 --- /dev/null +++ b/include/asm-mips/mach-malta/mc146818rtc.h @@ -0,0 +1,48 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2003 by Ralf Baechle + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * RTC routines for Malta style attached PIIX4 device, which contains a + * Motorola MC146818A-compatible Real Time Clock. + */ +#ifndef __ASM_MACH_MALTA_MC146818RTC_H +#define __ASM_MACH_MALTA_MC146818RTC_H + +#include +#include +#include + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +static inline unsigned char CMOS_READ(unsigned long addr) +{ + outb(addr, MALTA_RTC_ADR_REG); + return inb(MALTA_RTC_DAT_REG); +} + +static inline void CMOS_WRITE(unsigned char data, unsigned long addr) +{ + outb(addr, MALTA_RTC_ADR_REG); + outb(data, MALTA_RTC_DAT_REG); +} + +#define RTC_ALWAYS_BCD 0 + +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) + +#endif /* __ASM_MACH_MALTA_MC146818RTC_H */ diff --git a/include/asm-mips/mach-malta/war.h b/include/asm-mips/mach-malta/war.h new file mode 100644 index 0000000..7c6931d --- /dev/null +++ b/include/asm-mips/mach-malta/war.h @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MACH_MIPS_WAR_H +#define __ASM_MIPS_MACH_MIPS_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 1 +#define MIPS_CACHE_SYNC_WAR 1 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 1 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */ diff --git a/include/asm-mips/mach-mips/cpu-feature-overrides.h b/include/asm-mips/mach-mips/cpu-feature-overrides.h deleted file mode 100644 index 7f3e3f9..0000000 --- a/include/asm-mips/mach-mips/cpu-feature-overrides.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 2004 Chris Dearman - * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H - - -/* - * CPU feature overrides for MIPS boards - */ -#ifdef CONFIG_CPU_MIPS32 -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_4k_cache 1 -/* #define cpu_has_fpu ? */ -/* #define cpu_has_32fpr ? */ -#define cpu_has_counter 1 -/* #define cpu_has_watch ? */ -#define cpu_has_divec 1 -#define cpu_has_vce 0 -/* #define cpu_has_cache_cdex_p ? */ -/* #define cpu_has_cache_cdex_s ? */ -/* #define cpu_has_prefetch ? */ -#define cpu_has_mcheck 1 -/* #define cpu_has_ejtag ? */ -#ifdef CONFIG_CPU_HAS_LLSC -#define cpu_has_llsc 1 -#else -#define cpu_has_llsc 0 -#endif -/* #define cpu_has_vtag_icache ? */ -/* #define cpu_has_dc_aliases ? */ -/* #define cpu_has_ic_fills_f_dc ? */ -#define cpu_has_nofpuex 0 -/* #define cpu_has_64bits ? */ -/* #define cpu_has_64bit_zero_reg ? */ -/* #define cpu_has_inclusive_pcaches ? */ -#define cpu_icache_snoops_remote_store 1 -#endif - -#ifdef CONFIG_CPU_MIPS64 -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_4k_cache 1 -/* #define cpu_has_fpu ? */ -/* #define cpu_has_32fpr ? */ -#define cpu_has_counter 1 -/* #define cpu_has_watch ? */ -#define cpu_has_divec 1 -#define cpu_has_vce 0 -/* #define cpu_has_cache_cdex_p ? */ -/* #define cpu_has_cache_cdex_s ? */ -/* #define cpu_has_prefetch ? */ -#define cpu_has_mcheck 1 -/* #define cpu_has_ejtag ? */ -#define cpu_has_llsc 1 -/* #define cpu_has_vtag_icache ? */ -/* #define cpu_has_dc_aliases ? */ -/* #define cpu_has_ic_fills_f_dc ? */ -#define cpu_has_nofpuex 0 -/* #define cpu_has_64bits ? */ -/* #define cpu_has_64bit_zero_reg ? */ -/* #define cpu_has_inclusive_pcaches ? */ -#define cpu_icache_snoops_remote_store 1 -#endif - -#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */ diff --git a/include/asm-mips/mach-mips/irq.h b/include/asm-mips/mach-mips/irq.h deleted file mode 100644 index 9b9da26..0000000 --- a/include/asm-mips/mach-mips/irq.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_MACH_MIPS_IRQ_H -#define __ASM_MACH_MIPS_IRQ_H - - -#define NR_IRQS 256 - -#include_next - -#endif /* __ASM_MACH_MIPS_IRQ_H */ diff --git a/include/asm-mips/mach-mips/kernel-entry-init.h b/include/asm-mips/mach-mips/kernel-entry-init.h deleted file mode 100644 index 0b793e7..0000000 --- a/include/asm-mips/mach-mips/kernel-entry-init.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Chris Dearman (chris@mips.com) - * Copyright (C) 2007 Mips Technologies, Inc. - */ -#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H -#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H - - .macro kernel_entry_setup -#ifdef CONFIG_MIPS_MT_SMTC - mfc0 t0, CP0_CONFIG - bgez t0, 9f - mfc0 t0, CP0_CONFIG, 1 - bgez t0, 9f - mfc0 t0, CP0_CONFIG, 2 - bgez t0, 9f - mfc0 t0, CP0_CONFIG, 3 - and t0, 1<<2 - bnez t0, 0f -9: - /* Assume we came from YAMON... */ - PTR_LA v0, 0x9fc00534 /* YAMON print */ - lw v0, (v0) - move a0, zero - PTR_LA a1, nonmt_processor - jal v0 - - PTR_LA v0, 0x9fc00520 /* YAMON exit */ - lw v0, (v0) - li a0, 1 - jal v0 - -1: b 1b - - __INITDATA -nonmt_processor: - .asciz "SMTC kernel requires the MT ASE to run\n" - __FINIT -0: -#endif - .endm - -/* - * Do SMP slave processor setup necessary before we can safely execute C code. - */ - .macro smp_slave_setup - .endm - -#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */ diff --git a/include/asm-mips/mach-mips/mach-gt64120.h b/include/asm-mips/mach-mips/mach-gt64120.h deleted file mode 100644 index 0f86314..0000000 --- a/include/asm-mips/mach-mips/mach-gt64120.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This is a direct copy of the ev96100.h file, with a global - * search and replace. The numbers are the same. - * - * The reason I'm duplicating this is so that the 64120/96100 - * defines won't be confusing in the source code. - */ -#ifndef _ASM_MACH_MIPS_MACH_GT64120_DEP_H -#define _ASM_MACH_MIPS_MACH_GT64120_DEP_H - -#define MIPS_GT_BASE 0x1be00000 - -extern unsigned long _pcictrl_gt64120; -/* - * GT64120 config space base address - */ -#define GT64120_BASE _pcictrl_gt64120 - -#endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */ diff --git a/include/asm-mips/mach-mips/mc146818rtc.h b/include/asm-mips/mach-mips/mc146818rtc.h deleted file mode 100644 index ea612f3..0000000 --- a/include/asm-mips/mach-mips/mc146818rtc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2003 by Ralf Baechle - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * RTC routines for Malta style attached PIIX4 device, which contains a - * Motorola MC146818A-compatible Real Time Clock. - */ -#ifndef __ASM_MACH_MALTA_MC146818RTC_H -#define __ASM_MACH_MALTA_MC146818RTC_H - -#include -#include -#include - -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_IRQ 8 - -static inline unsigned char CMOS_READ(unsigned long addr) -{ - outb(addr, MALTA_RTC_ADR_REG); - return inb(MALTA_RTC_DAT_REG); -} - -static inline void CMOS_WRITE(unsigned char data, unsigned long addr) -{ - outb(addr, MALTA_RTC_ADR_REG); - outb(data, MALTA_RTC_DAT_REG); -} - -#define RTC_ALWAYS_BCD 0 - -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) - -#endif /* __ASM_MACH_MALTA_MC146818RTC_H */ diff --git a/include/asm-mips/mach-mips/war.h b/include/asm-mips/mach-mips/war.h deleted file mode 100644 index 7c6931d..0000000 --- a/include/asm-mips/mach-mips/war.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle - */ -#ifndef __ASM_MIPS_MACH_MIPS_WAR_H -#define __ASM_MIPS_MACH_MIPS_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 1 -#define MIPS_CACHE_SYNC_WAR 1 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */ -- cgit v0.10.2 From 14476007c90005c8992b786c15a59cca31f53268 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 10 Jul 2008 01:02:08 +0900 Subject: [MIPS] txx9: Make gpio_txx9 entirely spinlock-safe TXx9 GPIO set/get routines are spinlock-safe. This patch make gpio_direction_{input,output} routines also spinlock-safe so that they can be used during early board setup. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c index b1436a8..c6854d9 100644 --- a/arch/mips/kernel/gpio_txx9.c +++ b/arch/mips/kernel/gpio_txx9.c @@ -47,23 +47,25 @@ static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset, static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset) { - spin_lock_irq(&txx9_gpio_lock); + unsigned long flags; + spin_lock_irqsave(&txx9_gpio_lock, flags); __raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset), &txx9_pioptr->dir); mmiowb(); - spin_unlock_irq(&txx9_gpio_lock); + spin_unlock_irqrestore(&txx9_gpio_lock, flags); return 0; } static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset, int value) { - spin_lock_irq(&txx9_gpio_lock); + unsigned long flags; + spin_lock_irqsave(&txx9_gpio_lock, flags); txx9_gpio_set_raw(offset, value); __raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset), &txx9_pioptr->dir); mmiowb(); - spin_unlock_irq(&txx9_gpio_lock); + spin_unlock_irqrestore(&txx9_gpio_lock, flags); return 0; } -- cgit v0.10.2 From 22b1d707ffc99faebd86257ad19d5bb9fc624734 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 00:31:36 +0900 Subject: [MIPS] TXx9: Reorganize code Move arch/mips/{jmr3927,tx4927,tx4938} into arch/mips/txx9/ tree. This will help more code sharing and maintainance. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a038142..3202960 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -642,8 +642,7 @@ source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" -source "arch/mips/tx4927/Kconfig" -source "arch/mips/tx4938/Kconfig" +source "arch/mips/txx9/Kconfig" source "arch/mips/vr41xx/Kconfig" endmenu diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 36aa690..8e1e49c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -553,8 +553,8 @@ all-$(CONFIG_SNI_RM) := vmlinux.ecoff # # Toshiba JMR-TX3927 board # -core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/jmr3927/rbhma3100/ \ - arch/mips/jmr3927/common/ +core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/ \ + arch/mips/txx9/generic/ cflags-$(CONFIG_TOSHIBA_JMR3927) += -Iinclude/asm-mips/mach-jmr3927 load-$(CONFIG_TOSHIBA_JMR3927) += 0xffffffff80050000 @@ -562,16 +562,16 @@ load-$(CONFIG_TOSHIBA_JMR3927) += 0xffffffff80050000 # Toshiba RBTX4927 board or # Toshiba RBTX4937 board # -core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/ -core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/ +core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/rbtx4927/ +core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/generic/ cflags-$(CONFIG_TOSHIBA_RBTX4927) += -Iinclude/asm-mips/mach-tx49xx load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 # # Toshiba RBTX4938 board # -core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/ -core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/ +core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/ +core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/generic/ cflags-$(CONFIG_TOSHIBA_RBTX4938) += -Iinclude/asm-mips/mach-tx49xx load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000 diff --git a/arch/mips/jmr3927/common/Makefile b/arch/mips/jmr3927/common/Makefile deleted file mode 100644 index 8fd4fcc..0000000 --- a/arch/mips/jmr3927/common/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the common code of TOSHIBA JMR-TX3927 board -# - -obj-y += prom.o puts.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/jmr3927/common/prom.c b/arch/mips/jmr3927/common/prom.c deleted file mode 100644 index 5398813..0000000 --- a/arch/mips/jmr3927/common/prom.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * PROM library initialisation code, assuming a version of - * pmon is the boot code. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * Based on arch/mips/au1000/common/prom.c - * - * This file was derived from Carsten Langgaard's - * arch/mips/mips-boards/xx files. - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include - -#include - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - -void __init prom_init_cmdline(void) -{ - char *cp; - int actr; - int prom_argc = fw_arg0; - char **prom_argv = (char **) fw_arg1; - - actr = 1; /* Always ignore argv[0] */ - - cp = &(arcs_cmdline[0]); - while(actr < prom_argc) { - strcpy(cp, prom_argv[actr]); - cp += strlen(prom_argv[actr]); - *cp++ = ' '; - actr++; - } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ - --cp; - *cp = '\0'; -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/jmr3927/common/puts.c b/arch/mips/jmr3927/common/puts.c deleted file mode 100644 index c611ab4..0000000 --- a/arch/mips/jmr3927/common/puts.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Low level uart routines to directly access a TX[34]927 SIO. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com or source@mvista.com - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * Based on arch/mips/au1000/common/puts.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#define TIMEOUT 0xffffff - -void -prom_putchar(char c) -{ - int i = 0; - - do { - i++; - if (i>TIMEOUT) - break; - } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); - tx3927_sioptr(1)->tfifo = c; - return; -} - -void -puts(const char *cp) -{ - while (*cp) - prom_putchar(*cp++); - prom_putchar('\r'); - prom_putchar('\n'); -} diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile deleted file mode 100644 index d86e30d..0000000 --- a/arch/mips/jmr3927/rbhma3100/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for TOSHIBA JMR-TX3927 board -# - -obj-y += init.o irq.o setup.o -obj-$(CONFIG_KGDB) += kgdb_io.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/jmr3927/rbhma3100/init.c b/arch/mips/jmr3927/rbhma3100/init.c deleted file mode 100644 index 700b9cf..0000000 --- a/arch/mips/jmr3927/rbhma3100/init.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * arch/mips/jmr3927/common/init.c - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include - -extern void __init prom_init_cmdline(void); - -const char *get_system_type(void) -{ - return "Toshiba" -#ifdef CONFIG_TOSHIBA_JMR3927 - " JMR_TX3927" -#endif - ; -} - -extern void puts(const char *cp); - -void __init prom_init(void) -{ -#ifdef CONFIG_TOSHIBA_JMR3927 - /* CCFG */ - if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) - puts("Warning: TX3927 TLB off\n"); -#endif - - prom_init_cmdline(); - add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); -} diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c deleted file mode 100644 index 3a47e8c..0000000 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#if JMR3927_IRQ_END > NR_IRQS -#error JMR3927_IRQ_END > NR_IRQS -#endif - -static unsigned char irc_level[TX3927_NUM_IR] = { - 5, 5, 5, 5, 5, 5, /* INT[5:0] */ - 7, 7, /* SIO */ - 5, 5, 5, 0, 0, /* DMA, PIO, PCI */ - 6, 6, 6 /* TMR */ -}; - -/* - * CP0_STATUS is a thread's resource (saved/restored on context switch). - * So disable_irq/enable_irq MUST handle IOC/IRC registers. - */ -static void mask_irq_ioc(unsigned int irq) -{ - /* 0: mask */ - unsigned int irq_nr = irq - JMR3927_IRQ_IOC; - unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); - unsigned int bit = 1 << irq_nr; - jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); - /* flush write buffer */ - (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); -} -static void unmask_irq_ioc(unsigned int irq) -{ - /* 0: mask */ - unsigned int irq_nr = irq - JMR3927_IRQ_IOC; - unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); - unsigned int bit = 1 << irq_nr; - jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); - /* flush write buffer */ - (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned long cp0_cause = read_c0_cause(); - int irq; - - if ((cp0_cause & CAUSEF_IP7) == 0) - return; - irq = (cp0_cause >> CAUSEB_IP2) & 0x0f; - - do_IRQ(irq + JMR3927_IRQ_IRC); -} - -static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id) -{ - unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); - int i; - - for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) { - if (istat & (1 << i)) { - irq = JMR3927_IRQ_IOC + i; - do_IRQ(irq); - } - } - return IRQ_HANDLED; -} - -static struct irqaction ioc_action = { - .handler = jmr3927_ioc_interrupt, - .mask = CPU_MASK_NONE, - .name = "IOC", -}; - -static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) -{ - printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); - printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n", - tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); - - return IRQ_HANDLED; -} -static struct irqaction pcierr_action = { - .handler = jmr3927_pcierr_interrupt, - .mask = CPU_MASK_NONE, - .name = "PCI error", -}; - -static void __init jmr3927_irq_init(void); - -void __init arch_init_irq(void) -{ - /* Now, interrupt control disabled, */ - /* all IRC interrupts are masked, */ - /* all IRC interrupt mode are Low Active. */ - - /* mask all IOC interrupts */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR); - /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */ - jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR); - - /* clear PCI Soft interrupts */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR); - /* clear PCI Reset interrupts */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - - jmr3927_irq_init(); - - /* setup IOC interrupt 1 (PCI, MODEM) */ - setup_irq(JMR3927_IRQ_IOCINT, &ioc_action); - -#ifdef CONFIG_PCI - setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action); -#endif - - /* enable all CPU interrupt bits. */ - set_c0_status(ST0_IM); /* IE bit is still 0. */ -} - -static struct irq_chip jmr3927_irq_ioc = { - .name = "jmr3927_ioc", - .ack = mask_irq_ioc, - .mask = mask_irq_ioc, - .mask_ack = mask_irq_ioc, - .unmask = unmask_irq_ioc, -}; - -static void __init jmr3927_irq_init(void) -{ - u32 i; - - txx9_irq_init(TX3927_IRC_REG); - for (i = 0; i < TXx9_MAX_IR; i++) - txx9_irq_set_pri(i, irc_level[i]); - for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++) - set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq); -} diff --git a/arch/mips/jmr3927/rbhma3100/kgdb_io.c b/arch/mips/jmr3927/rbhma3100/kgdb_io.c deleted file mode 100644 index 342579c..0000000 --- a/arch/mips/jmr3927/rbhma3100/kgdb_io.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Low level uart routines to directly access a TX[34]927 SIO. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com or source@mvista.com - * - * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#define TIMEOUT 0xffffff - -static int remoteDebugInitialized = 0; -static void debugInit(int baud); - -int putDebugChar(unsigned char c) -{ - int i = 0; - - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(38400); - } - - do { - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS)); - tx3927_sioptr(0)->tfifo = c; - - return 1; -} - -unsigned char getDebugChar(void) -{ - int i = 0; - int dicr; - char c; - - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(38400); - } - - /* diable RX int. */ - dicr = tx3927_sioptr(0)->dicr; - tx3927_sioptr(0)->dicr = 0; - - do { - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID) - ; - c = tx3927_sioptr(0)->rfifo; - - /* clear RX int. status */ - tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS; - /* enable RX int. */ - tx3927_sioptr(0)->dicr = dicr; - - return c; -} - -static void debugInit(int baud) -{ - tx3927_sioptr(0)->lcr = 0x020; - tx3927_sioptr(0)->dicr = 0; - tx3927_sioptr(0)->disr = 0x4100; - tx3927_sioptr(0)->cisr = 0x014; - tx3927_sioptr(0)->fcr = 0; - tx3927_sioptr(0)->flcr = 0x02; - tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) | - TXx927_SIBGR_BCLK_T0; -} diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c deleted file mode 100644 index f39c444..0000000 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * Copyright (C) 2000-2001 Toshiba Corporation - * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_SERIAL_TXX9 -#include -#endif - -#include -#include -#include -#include -#include - -extern void puts(const char *cp); - -/* don't enable - see errata */ -static int jmr3927_ccfg_toeon; - -static inline void do_reset(void) -{ -#if 1 /* Resetting PCI bus */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR); - (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */ - mdelay(1); - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); -#endif - jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR); -} - -static void jmr3927_machine_restart(char *command) -{ - local_irq_disable(); - puts("Rebooting..."); - do_reset(); -} - -static void jmr3927_machine_halt(void) -{ - puts("JMR-TX3927 halted.\n"); - while (1); -} - -static void jmr3927_machine_power_off(void) -{ - puts("JMR-TX3927 halted. Please turn off the power.\n"); - while (1); -} - -void __init plat_time_init(void) -{ - txx9_clockevent_init(TX3927_TMR_REG(0), - TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0), - JMR3927_IMCLK); - txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK); -} - -#define DO_WRITE_THROUGH -#define DO_ENABLE_CACHE - -extern char * __init prom_getcmdline(void); -static void jmr3927_board_init(void); -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; - -void __init plat_mem_setup(void) -{ - char *argptr; - - set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO); - - _machine_restart = jmr3927_machine_restart; - _machine_halt = jmr3927_machine_halt; - pm_power_off = jmr3927_machine_power_off; - - /* - * IO/MEM resources. - */ - ioport_resource.start = pci_io_resource.start; - ioport_resource.end = pci_io_resource.end; - iomem_resource.start = 0; - iomem_resource.end = 0xffffffff; - - /* Reboot on panic */ - panic_timeout = 180; - - /* cache setup */ - { - unsigned int conf; -#ifdef DO_ENABLE_CACHE - int mips_ic_disable = 0, mips_dc_disable = 0; -#else - int mips_ic_disable = 1, mips_dc_disable = 1; -#endif -#ifdef DO_WRITE_THROUGH - int mips_config_cwfon = 0; - int mips_config_wbon = 0; -#else - int mips_config_cwfon = 1; - int mips_config_wbon = 1; -#endif - - conf = read_c0_conf(); - conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON); - conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; - conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; - conf |= mips_config_wbon ? TX39_CONF_WBON : 0; - conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; - - write_c0_conf(conf); - write_c0_cache(0); - } - - /* initialize board */ - jmr3927_board_init(); - - argptr = prom_getcmdline(); - - if ((argptr = strstr(argptr, "toeon")) != NULL) - jmr3927_ccfg_toeon = 1; - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "ip=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " ip=bootp"); - } - -#ifdef CONFIG_SERIAL_TXX9 - { - extern int early_serial_txx9_setup(struct uart_port *port); - int i; - struct uart_port req; - for(i = 0; i < 2; i++) { - memset(&req, 0, sizeof(req)); - req.line = i; - req.iotype = UPIO_MEM; - req.membase = (unsigned char __iomem *)TX3927_SIO_REG(i); - req.mapbase = TX3927_SIO_REG(i); - req.irq = i == 0 ? - JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1; - if (i == 0) - req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; - req.uartclk = JMR3927_IMCLK; - early_serial_txx9_setup(&req); - } - } -#ifdef CONFIG_SERIAL_TXX9_CONSOLE - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS1,115200"); - } -#endif -#endif -} - -static void tx3927_setup(void); - -static void __init jmr3927_board_init(void) -{ - tx3927_setup(); - - /* SIO0 DTR on */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); - - jmr3927_led_set(0); - - printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", - jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, - jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK, - jmr3927_dipsw1(), jmr3927_dipsw2(), - jmr3927_dipsw3(), jmr3927_dipsw4()); -} - -static void __init tx3927_setup(void) -{ - int i; -#ifdef CONFIG_PCI - unsigned long mips_pci_io_base = JMR3927_PCIIO; - unsigned long mips_pci_io_size = JMR3927_PCIIO_SIZE; - unsigned long mips_pci_mem_base = JMR3927_PCIMEM; - unsigned long mips_pci_mem_size = JMR3927_PCIMEM_SIZE; - /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ - unsigned long mips_pci_io_pciaddr = 0; -#endif - - /* SDRAMC are configured by PROM */ - - /* ROMC */ - tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048; - tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8; - tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698; - tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218; - - /* CCFG */ - /* enable Timeout BusError */ - if (jmr3927_ccfg_toeon) - tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE; - - /* clear BusErrorOnWrite flag */ - tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW; - /* Disable PCI snoop */ - tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP; - /* do reset on watchdog */ - tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR; - -#ifdef DO_WRITE_THROUGH - /* Enable PCI SNOOP - with write through only */ - tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP; -#endif - - /* Pin selection */ - tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL; - tx3927_ccfgptr->pcfg |= - TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL | - (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1)); - - printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n", - tx3927_ccfgptr->crir, - tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg); - - /* TMR */ - for (i = 0; i < TX3927_NR_TMR; i++) - txx9_tmr_init(TX3927_TMR_REG(i)); - - /* DMA */ - tx3927_dmaptr->mcr = 0; - for (i = 0; i < ARRAY_SIZE(tx3927_dmaptr->ch); i++) { - /* reset channel */ - tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST; - tx3927_dmaptr->ch[i].ccr = 0; - } - /* enable DMA */ -#ifdef __BIG_ENDIAN - tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN; -#else - tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE; -#endif - -#ifdef CONFIG_PCI - /* PCIC */ - printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:", - tx3927_pcicptr->did, tx3927_pcicptr->vid, - tx3927_pcicptr->rid); - if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) { - printk("External\n"); - /* XXX */ - } else { - printk("Internal\n"); - - /* Reset PCI Bus */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - udelay(100); - jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, - JMR3927_IOC_RESET_ADDR); - udelay(100); - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - - - /* Disable External PCI Config. Access */ - tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; -#ifdef __BIG_ENDIAN - tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | - TX3927_PCIC_LBC_TIBSE | - TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; -#endif - /* LB->PCI mappings */ - tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1); - tx3927_pcicptr->ilbioma = mips_pci_io_base; - tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr; - tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1); - tx3927_pcicptr->ilbmma = mips_pci_mem_base; - tx3927_pcicptr->ipbmma = mips_pci_mem_base; - /* PCI->LB mappings */ - tx3927_pcicptr->iobas = 0xffffffff; - tx3927_pcicptr->ioba = 0; - tx3927_pcicptr->tlbioma = 0; - tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1); - tx3927_pcicptr->mba = 0; - tx3927_pcicptr->tlbmma = 0; - /* Enable Direct mapping Address Space Decoder */ - tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; - - /* Clear All Local Bus Status */ - tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; - /* Enable All Local Bus Interrupts */ - tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; - /* Clear All PCI Status Error */ - tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; - /* Enable All PCI Status Error Interrupts */ - tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; - - /* PCIC Int => IRC IRQ10 */ - tx3927_pcicptr->il = TX3927_IR_PCI; - /* Target Control (per errata) */ - tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; - - /* Enable Bus Arbiter */ - tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; - - tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_IO | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; - } -#endif /* CONFIG_PCI */ - - /* PIO */ - /* PIO[15:12] connected to LEDs */ - __raw_writel(0x0000f000, &tx3927_pioptr->dir); - __raw_writel(0, &tx3927_pioptr->maskcpu); - __raw_writel(0, &tx3927_pioptr->maskext); - txx9_gpio_init(TX3927_PIO_REG, 0, 16); - gpio_request(11, "dipsw1"); - gpio_request(10, "dipsw2"); - { - unsigned int conf; - - conf = read_c0_conf(); - if (!(conf & TX39_CONF_ICE)) - printk("TX3927 I-Cache disabled.\n"); - if (!(conf & TX39_CONF_DCE)) - printk("TX3927 D-Cache disabled.\n"); - else if (!(conf & TX39_CONF_WBON)) - printk("TX3927 D-Cache WriteThrough.\n"); - else if (!(conf & TX39_CONF_CWFON)) - printk("TX3927 D-Cache WriteBack.\n"); - else - printk("TX3927 D-Cache WriteBack (CWF) .\n"); - } -} - -/* This trick makes rtc-ds1742 driver usable as is. */ -unsigned long __swizzle_addr_b(unsigned long port) -{ - if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR) - return port; - port = (port & 0xffff0000) | (port & 0x7fff << 1); -#ifdef __BIG_ENDIAN - return port; -#else - return port | 1; -#endif -} -EXPORT_SYMBOL(__swizzle_addr_b); - -static int __init jmr3927_rtc_init(void) -{ - static struct resource __initdata res = { - .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE, - .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1, - .flags = IORESOURCE_MEM, - }; - struct platform_device *dev; - dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} -device_initcall(jmr3927_rtc_init); - -/* Watchdog support */ - -static int __init txx9_wdt_init(unsigned long base) -{ - struct resource res = { - .start = base, - .end = base + 0x100 - 1, - .flags = IORESOURCE_MEM, - }; - struct platform_device *dev = - platform_device_register_simple("txx9wdt", -1, &res, 1); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} - -static int __init jmr3927_wdt_init(void) -{ - return txx9_wdt_init(TX3927_TMR_REG(2)); -} -device_initcall(jmr3927_wdt_init); - -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "imbus_clk")) - return (struct clk *)JMR3927_IMCLK; - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 80fa5ab..4608e43 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o -obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o +obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o ops-tx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index e974394..41dcd6a 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -31,7 +31,7 @@ #include #include -#include +#include int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 2d234ca..26013ba 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -37,7 +37,7 @@ #include #include -#include +#include #undef DEBUG #ifdef DEBUG diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c new file mode 100644 index 0000000..64d4510 --- /dev/null +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -0,0 +1,92 @@ +/* + * Toshiba rbtx4938 pci routines + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#include +#include +#include +#include + +#include + +extern struct pci_controller tx4938_pci_controller[]; + +static int pci_get_irq(const struct pci_dev *dev, int pin) +{ + int irq = pin; + u8 slot = PCI_SLOT(dev->devfn); + struct pci_controller *controller = (struct pci_controller *)dev->sysdata; + + if (controller == &tx4938_pci_controller[1]) { + /* TX4938 PCIC1 */ + switch (slot) { + case TX4938_PCIC_IDSEL_AD_TO_SLOT(31): + if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL) + return RBTX4938_IRQ_IRC + TX4938_IR_ETH0; + break; + case TX4938_PCIC_IDSEL_AD_TO_SLOT(30): + if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL) + return RBTX4938_IRQ_IRC + TX4938_IR_ETH1; + break; + } + return 0; + } + + /* IRQ rotation */ + irq--; /* 0-3 */ + if (dev->bus->parent == NULL && + (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) { + /* PCI CardSlot (IDSEL=A23) */ + /* PCIA => PCIA (IDSEL=A23) */ + irq = (irq + 0 + slot) % 4; + } else { + /* PCI Backplane */ + irq = (irq + 33 - slot) % 4; + } + irq++; /* 1-4 */ + + switch (irq) { + case 1: + irq = RBTX4938_IRQ_IOC_PCIA; + break; + case 2: + irq = RBTX4938_IRQ_IOC_PCIB; + break; + case 3: + irq = RBTX4938_IRQ_IOC_PCIC; + break; + case 4: + irq = RBTX4938_IRQ_IOC_PCID; + break; + } + return irq; +} + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + unsigned char irq = 0; + + irq = pci_get_irq(dev, pin); + + printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", + dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), irq); + + return irq; +} + +/* + * Do platform specific device initialization at pci_enable_device() time + */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c deleted file mode 100644 index f2ba06e..0000000 --- a/arch/mips/pci/fixup-tx4938.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Toshiba rbtx4938 pci routines - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include - -#include - -extern struct pci_controller tx4938_pci_controller[]; - -static int pci_get_irq(const struct pci_dev *dev, int pin) -{ - int irq = pin; - u8 slot = PCI_SLOT(dev->devfn); - struct pci_controller *controller = (struct pci_controller *)dev->sysdata; - - if (controller == &tx4938_pci_controller[1]) { - /* TX4938 PCIC1 */ - switch (slot) { - case TX4938_PCIC_IDSEL_AD_TO_SLOT(31): - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL) - return RBTX4938_IRQ_IRC + TX4938_IR_ETH0; - break; - case TX4938_PCIC_IDSEL_AD_TO_SLOT(30): - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL) - return RBTX4938_IRQ_IRC + TX4938_IR_ETH1; - break; - } - return 0; - } - - /* IRQ rotation */ - irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) { - /* PCI CardSlot (IDSEL=A23) */ - /* PCIA => PCIA (IDSEL=A23) */ - irq = (irq + 0 + slot) % 4; - } else { - /* PCI Backplane */ - irq = (irq + 33 - slot) % 4; - } - irq++; /* 1-4 */ - - switch (irq) { - case 1: - irq = RBTX4938_IRQ_IOC_PCIA; - break; - case 2: - irq = RBTX4938_IRQ_IOC_PCIB; - break; - case 3: - irq = RBTX4938_IRQ_IOC_PCIC; - break; - case 4: - irq = RBTX4938_IRQ_IOC_PCID; - break; - } - return irq; -} - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char irq = 0; - - irq = pci_get_irq(dev, pin); - - printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", - dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), irq); - - return irq; -} - -/* - * Do platform specific device initialization at pci_enable_device() time - */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} - diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index aa698bd..5d398f6 100644 --- a/arch/mips/pci/ops-tx3927.c +++ b/arch/mips/pci/ops-tx3927.c @@ -39,7 +39,7 @@ #include #include -#include +#include static inline int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where) diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 1bbafeb..54730ee 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include /* initialize in setup */ struct resource pci_io_resource = { diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c index a450c40..34494b8 100644 --- a/arch/mips/pci/ops-tx4938.c +++ b/arch/mips/pci/ops-tx4938.c @@ -15,7 +15,7 @@ #include #include -#include +#include /* initialize in setup */ struct resource pci_io_resource = { diff --git a/arch/mips/pci/pci-jmr3927.c b/arch/mips/pci/pci-jmr3927.c index cb84f4e..7fb6bd7 100644 --- a/arch/mips/pci/pci-jmr3927.c +++ b/arch/mips/pci/pci-jmr3927.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include struct resource pci_io_resource = { diff --git a/arch/mips/tx4927/Kconfig b/arch/mips/tx4927/Kconfig deleted file mode 100644 index 5fbbe12..0000000 --- a/arch/mips/tx4927/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -config TOSHIBA_FPCIB0 - bool "FPCIB0 Backplane Support" - depends on TOSHIBA_RBTX4927 diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile deleted file mode 100644 index a7fe76a..0000000 --- a/arch/mips/tx4927/common/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for common code for Toshiba TX4927 based systems -# - -obj-y += tx4927_prom.o tx4927_irq.o - -obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o -obj-$(CONFIG_KGDB) += tx4927_dbgio.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/tx4927/common/smsc_fdc37m81x.c b/arch/mips/tx4927/common/smsc_fdc37m81x.c deleted file mode 100644 index 33f517b..0000000 --- a/arch/mips/tx4927/common/smsc_fdc37m81x.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Interface for smsc fdc48m81x Super IO chip - * - * Author: MontaVista Software, Inc. source@mvista.com - * - * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Copyright 2004 (c) MontaVista Software, Inc. - */ -#include -#include -#include -#include - -#define DEBUG - -/* Common Registers */ -#define SMSC_FDC37M81X_CONFIG_INDEX 0x00 -#define SMSC_FDC37M81X_CONFIG_DATA 0x01 -#define SMSC_FDC37M81X_CONF 0x02 -#define SMSC_FDC37M81X_INDEX 0x03 -#define SMSC_FDC37M81X_DNUM 0x07 -#define SMSC_FDC37M81X_DID 0x20 -#define SMSC_FDC37M81X_DREV 0x21 -#define SMSC_FDC37M81X_PCNT 0x22 -#define SMSC_FDC37M81X_PMGT 0x23 -#define SMSC_FDC37M81X_OSC 0x24 -#define SMSC_FDC37M81X_CONFPA0 0x26 -#define SMSC_FDC37M81X_CONFPA1 0x27 -#define SMSC_FDC37M81X_TEST4 0x2B -#define SMSC_FDC37M81X_TEST5 0x2C -#define SMSC_FDC37M81X_TEST1 0x2D -#define SMSC_FDC37M81X_TEST2 0x2E -#define SMSC_FDC37M81X_TEST3 0x2F - -/* Logical device numbers */ -#define SMSC_FDC37M81X_FDD 0x00 -#define SMSC_FDC37M81X_SERIAL1 0x04 -#define SMSC_FDC37M81X_SERIAL2 0x05 -#define SMSC_FDC37M81X_KBD 0x07 - -/* Logical device Config Registers */ -#define SMSC_FDC37M81X_ACTIVE 0x30 -#define SMSC_FDC37M81X_BASEADDR0 0x60 -#define SMSC_FDC37M81X_BASEADDR1 0x61 -#define SMSC_FDC37M81X_INT 0x70 -#define SMSC_FDC37M81X_INT2 0x72 -#define SMSC_FDC37M81X_MODE 0xF0 - -/* Chip Config Values */ -#define SMSC_FDC37M81X_CONFIG_ENTER 0x55 -#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa -#define SMSC_FDC37M81X_CHIP_ID 0x4d - -static unsigned long g_smsc_fdc37m81x_base = 0; - -static inline unsigned char smsc_fdc37m81x_rd(unsigned char index) -{ - outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); - - return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); -} - -static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data) -{ - outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); - outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); -} - -void smsc_fdc37m81x_config_beg(void) -{ - if (g_smsc_fdc37m81x_base) { - outb(SMSC_FDC37M81X_CONFIG_ENTER, - g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); - } -} - -void smsc_fdc37m81x_config_end(void) -{ - if (g_smsc_fdc37m81x_base) - outb(SMSC_FDC37M81X_CONFIG_EXIT, - g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); -} - -u8 smsc_fdc37m81x_config_get(u8 reg) -{ - u8 val = 0; - - if (g_smsc_fdc37m81x_base) - val = smsc_fdc37m81x_rd(reg); - - return val; -} - -void smsc_fdc37m81x_config_set(u8 reg, u8 val) -{ - if (g_smsc_fdc37m81x_base) - smsc_dc37m81x_wr(reg, val); -} - -unsigned long __init smsc_fdc37m81x_init(unsigned long port) -{ - const int field = sizeof(unsigned long) * 2; - u8 chip_id; - - if (g_smsc_fdc37m81x_base) - printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n", - field, g_smsc_fdc37m81x_base); - - g_smsc_fdc37m81x_base = port; - - smsc_fdc37m81x_config_beg(); - - chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); - if (chip_id == SMSC_FDC37M81X_CHIP_ID) - smsc_fdc37m81x_config_end(); - else { - printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n", - chip_id); - g_smsc_fdc37m81x_base = 0; - } - - return g_smsc_fdc37m81x_base; -} - -#ifdef DEBUG -void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg) -{ - printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg, - smsc_fdc37m81x_rd(reg)); -} - -void smsc_fdc37m81x_config_dump(void) -{ - u8 orig; - char *fname = "smsc_fdc37m81x_config_dump()"; - - smsc_fdc37m81x_config_beg(); - - orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); - - printk("%s: common\n", fname); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_DNUM); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_DID); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_DREV); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_PCNT); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, - SMSC_FDC37M81X_PMGT); - - printk("%s: keyboard\n", fname); - smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_ACTIVE); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_INT); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_INT2); - smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, - SMSC_FDC37M81X_LDCR_F0); - - smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); - - smsc_fdc37m81x_config_end(); -} -#endif diff --git a/arch/mips/tx4927/common/tx4927_dbgio.c b/arch/mips/tx4927/common/tx4927_dbgio.c deleted file mode 100644 index ea1ff23..0000000 --- a/arch/mips/tx4927/common/tx4927_dbgio.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/arch/mips/tx4927/common/tx4927_dbgio.c - * - * kgdb interface for gdb - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2002 MontaVista Software 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -u8 getDebugChar(void) -{ - extern u8 txx9_sio_kdbg_rd(void); - return (txx9_sio_kdbg_rd()); -} - -int putDebugChar(u8 byte) -{ - extern int txx9_sio_kdbg_wr( u8 ch ); - return (txx9_sio_kdbg_wr(byte)); -} diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c deleted file mode 100644 index 0aabd57..0000000 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Common tx4927 irq handler - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#ifdef CONFIG_TOSHIBA_RBTX4927 -#include -#endif - -void __init tx4927_irq_init(void) -{ - mips_cpu_irq_init(); - txx9_irq_init(TX4927_IRC_REG); - set_irq_chained_handler(TX4927_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP7) /* cpu timer */ - do_IRQ(TX4927_IRQ_CPU_TIMER); - else if (pending & STATUSF_IP2) { /* tx4927 pic */ - int irq = txx9_irq(); -#ifdef CONFIG_TOSHIBA_RBTX4927 - if (irq == TX4927_IRQ_NEST_EXT_ON_PIC) - irq = toshiba_rbtx4927_irq_nested(irq); -#endif - if (unlikely(irq < 0)) { - spurious_interrupt(); - return; - } - do_IRQ(irq); - } else if (pending & STATUSF_IP0) /* user line 0 */ - do_IRQ(TX4927_IRQ_USER0); - else if (pending & STATUSF_IP1) /* user line 1 */ - do_IRQ(TX4927_IRQ_USER1); - else - spurious_interrupt(); -} diff --git a/arch/mips/tx4927/common/tx4927_prom.c b/arch/mips/tx4927/common/tx4927_prom.c deleted file mode 100644 index cc2aa9d..0000000 --- a/arch/mips/tx4927/common/tx4927_prom.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * linux/arch/mips/tx4927/common/tx4927_prom.c - * - * common tx4927 memory interface - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2002 MontaVista Software 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -static unsigned int __init tx4927_process_sdccr(unsigned long addr) -{ - u64 val; - unsigned int sdccr_ce; - unsigned int sdccr_bs; - unsigned int sdccr_rs; - unsigned int sdccr_cs; - unsigned int sdccr_mw; - unsigned int bs = 0; - unsigned int rs = 0; - unsigned int cs = 0; - unsigned int mw = 0; - unsigned int msize = 0; - - val = __raw_readq((void __iomem *)addr); - - /* MVMCP -- need #defs for these bits masks */ - sdccr_ce = ((val & (1 << 10)) >> 10); - sdccr_bs = ((val & (1 << 8)) >> 8); - sdccr_rs = ((val & (3 << 5)) >> 5); - sdccr_cs = ((val & (3 << 2)) >> 2); - sdccr_mw = ((val & (1 << 0)) >> 0); - - if (sdccr_ce) { - switch (sdccr_bs) { - case 0:{ - bs = 2; - break; - } - case 1:{ - bs = 4; - break; - } - } - switch (sdccr_rs) { - case 0:{ - rs = 2048; - break; - } - case 1:{ - rs = 4096; - break; - } - case 2:{ - rs = 8192; - break; - } - case 3:{ - rs = 0; - break; - } - } - switch (sdccr_cs) { - case 0:{ - cs = 256; - break; - } - case 1:{ - cs = 512; - break; - } - case 2:{ - cs = 1024; - break; - } - case 3:{ - cs = 2048; - break; - } - } - switch (sdccr_mw) { - case 0:{ - mw = 8; - break; - } /* 8 bytes = 64 bits */ - case 1:{ - mw = 4; - break; - } /* 4 bytes = 32 bits */ - } - } - - /* bytes per chip MB per chip num chips */ - msize = (((rs * cs * mw) / (1024 * 1024)) * bs); - - return (msize); -} - - -unsigned int __init tx4927_get_mem_size(void) -{ - unsigned int c0; - unsigned int c1; - unsigned int c2; - unsigned int c3; - unsigned int total; - - /* MVMCP -- need #defs for these registers */ - c0 = tx4927_process_sdccr(0xff1f8000); - c1 = tx4927_process_sdccr(0xff1f8008); - c2 = tx4927_process_sdccr(0xff1f8010); - c3 = tx4927_process_sdccr(0xff1f8018); - total = c0 + c1 + c2 + c3; - - return (total); -} diff --git a/arch/mips/tx4927/toshiba_rbtx4927/Makefile b/arch/mips/tx4927/toshiba_rbtx4927/Makefile deleted file mode 100644 index 13f9672..0000000 --- a/arch/mips/tx4927/toshiba_rbtx4927/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-y += toshiba_rbtx4927_prom.o -obj-y += toshiba_rbtx4927_setup.o -obj-y += toshiba_rbtx4927_irq.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c deleted file mode 100644 index c18901a..0000000 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c - * - * Toshiba RBTX4927 specific interrupt handlers - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2002 MontaVista Software 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* -IRQ Device -00 RBTX4927-ISA/00 -01 RBTX4927-ISA/01 PS2/Keyboard -02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) -03 RBTX4927-ISA/03 -04 RBTX4927-ISA/04 -05 RBTX4927-ISA/05 -06 RBTX4927-ISA/06 -07 RBTX4927-ISA/07 -08 RBTX4927-ISA/08 -09 RBTX4927-ISA/09 -10 RBTX4927-ISA/10 -11 RBTX4927-ISA/11 -12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) -13 RBTX4927-ISA/13 -14 RBTX4927-ISA/14 IDE -15 RBTX4927-ISA/15 - -16 TX4927-CP0/00 Software 0 -17 TX4927-CP0/01 Software 1 -18 TX4927-CP0/02 Cascade TX4927-CP0 -19 TX4927-CP0/03 Multiplexed -- do not use -20 TX4927-CP0/04 Multiplexed -- do not use -21 TX4927-CP0/05 Multiplexed -- do not use -22 TX4927-CP0/06 Multiplexed -- do not use -23 TX4927-CP0/07 CPU TIMER - -24 TX4927-PIC/00 -25 TX4927-PIC/01 -26 TX4927-PIC/02 -27 TX4927-PIC/03 Cascade RBTX4927-IOC -28 TX4927-PIC/04 -29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet -30 TX4927-PIC/06 -31 TX4927-PIC/07 -32 TX4927-PIC/08 TX4927 SerialIO Channel 0 -33 TX4927-PIC/09 TX4927 SerialIO Channel 1 -34 TX4927-PIC/10 -35 TX4927-PIC/11 -36 TX4927-PIC/12 -37 TX4927-PIC/13 -38 TX4927-PIC/14 -39 TX4927-PIC/15 -40 TX4927-PIC/16 TX4927 PCI PCI-C -41 TX4927-PIC/17 -42 TX4927-PIC/18 -43 TX4927-PIC/19 -44 TX4927-PIC/20 -45 TX4927-PIC/21 -46 TX4927-PIC/22 TX4927 PCI PCI-ERR -47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) -48 TX4927-PIC/24 -49 TX4927-PIC/25 -50 TX4927-PIC/26 -51 TX4927-PIC/27 -52 TX4927-PIC/28 -53 TX4927-PIC/29 -54 TX4927-PIC/30 -55 TX4927-PIC/31 - -56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] -57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] -58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] -59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] -60 RBTX4927-IOC/04 -61 RBTX4927-IOC/05 -62 RBTX4927-IOC/06 -63 RBTX4927-IOC/07 - -NOTES: -SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 -SouthBridge/ISA/pin=0 no pci irq used by this device -SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 -SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 -SouthBridge/PMC/pin=0 no pci irq used by this device -SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 -SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) -JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6 -*/ - -#include -#include -#include -#include -#ifdef CONFIG_TOSHIBA_FPCIB0 -#include -#endif -#include - -#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 -#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 - -#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ -#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ - -#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC -#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) - -extern int tx4927_using_backplane; - -static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); -static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); - -#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" -static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { - .name = TOSHIBA_RBTX4927_IOC_NAME, - .ack = toshiba_rbtx4927_irq_ioc_disable, - .mask = toshiba_rbtx4927_irq_ioc_disable, - .mask_ack = toshiba_rbtx4927_irq_ioc_disable, - .unmask = toshiba_rbtx4927_irq_ioc_enable, -}; -#define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL -#define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL - -int toshiba_rbtx4927_irq_nested(int sw_irq) -{ - u8 level3; - - level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; - if (level3) { - sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1; -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (sw_irq == TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC && - tx4927_using_backplane) { - int irq = i8259_irq(); - if (irq >= 0) - sw_irq = irq; - } -#endif - } - return (sw_irq); -} - -static struct irqaction toshiba_rbtx4927_irq_ioc_action = { - .handler = no_action, - .flags = IRQF_SHARED, - .mask = CPU_MASK_NONE, - .name = TOSHIBA_RBTX4927_IOC_NAME -}; - -static void __init toshiba_rbtx4927_irq_ioc_init(void) -{ - int i; - - for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, - handle_level_irq); - - setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, - &toshiba_rbtx4927_irq_ioc_action); -} - -static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) -{ - unsigned char v; - - v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); - v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); - writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); -} - -static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) -{ - unsigned char v; - - v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); - v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); - writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); - mmiowb(); -} - -void __init arch_init_irq(void) -{ - extern void tx4927_irq_init(void); - - tx4927_irq_init(); - toshiba_rbtx4927_irq_ioc_init(); -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) - init_i8259_irqs(); -#endif - /* Onboard 10M Ether: High Active */ - set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); -} diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c deleted file mode 100644 index fdbad4b..0000000 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * rbtx4927 specific prom routines - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2002 MontaVista Software Inc. - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include - -void __init prom_init_cmdline(void) -{ - int argc = (int) fw_arg0; - char **argv = (char **) fw_arg1; - int i; /* Always ignore the "-c" at argv[0] */ - - /* ignore all built-in args if any f/w args given */ - if (argc > 1) { - *arcs_cmdline = '\0'; - } - - for (i = 1; i < argc; i++) { - if (i != 1) { - strcat(arcs_cmdline, " "); - } - strcat(arcs_cmdline, argv[i]); - } -} - -void __init prom_init(void) -{ - extern int tx4927_get_mem_size(void); - extern char* toshiba_name; - int msize; - - prom_init_cmdline(); - - if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) { - mips_machtype = MACH_TOSHIBA_RBTX4927; - toshiba_name = "TX4927"; - } else { - mips_machtype = MACH_TOSHIBA_RBTX4937; - toshiba_name = "TX4937"; - } - - msize = tx4927_get_mem_size(); - add_memory_region(0, msize << 20, BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ -} - -const char *get_system_type(void) -{ - return "Toshiba RBTX4927/RBTX4937"; -} - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c deleted file mode 100644 index 185f303..0000000 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Toshiba rbtx4927 specific setup - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2002 MontaVista Software Inc. - * - * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright 2002 MontaVista Software Inc. - * Author: Michael Pruznick, michael_pruznick@mvista.com - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * Copyright (C) 2004 MontaVista Software Inc. - * Author: Manish Lachwani, mlachwani@mvista.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_TOSHIBA_FPCIB0 -#include -#endif -#include -#ifdef CONFIG_SERIAL_TXX9 -#include -#endif - -/* These functions are used for rebooting or halting the machine*/ -extern void toshiba_rbtx4927_restart(char *command); -extern void toshiba_rbtx4927_halt(void); -extern void toshiba_rbtx4927_power_off(void); - -int tx4927_using_backplane = 0; - -extern void toshiba_rbtx4927_irq_setup(void); - -char *prom_getcmdline(void); - -#ifdef CONFIG_PCI -#undef TX4927_SUPPORT_COMMAND_IO -#undef TX4927_SUPPORT_PCI_66 -int tx4927_cpu_clock = 100000000; /* 100MHz */ -unsigned long mips_pci_io_base; -unsigned long mips_pci_io_size; -unsigned long mips_pci_mem_base; -unsigned long mips_pci_mem_size; -/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ -unsigned long mips_pci_io_pciaddr = 0; -unsigned long mips_memory_upper; -static int tx4927_ccfg_toeon = 1; -static int tx4927_pcic_trdyto = 0; /* default: disabled */ -unsigned long tx4927_ce_base[8]; -int tx4927_pci66 = 0; /* 0:auto */ -#endif - -char *toshiba_name = ""; - -#ifdef CONFIG_PCI -extern struct pci_controller tx4927_controller; - -static struct pci_dev *fake_pci_dev(struct pci_controller *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.sysdata = (void *)hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.parent = NULL; - dev.bus = &bus; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_controller *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, dword, u32) - -static int __init tx4927_pcibios_init(void) -{ - unsigned int id; - u32 pci_devfn; - int devfn_start = 0; - int devfn_stop = 0xff; - int busno = 0; /* One bus on the Toshiba */ - struct pci_controller *hose = &tx4927_controller; - - for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { - early_read_config_dword(hose, busno, busno, pci_devfn, - PCI_VENDOR_ID, &id); - - if (id == 0xffffffff) { - continue; - } - - if (id == 0x94601055) { - u8 v08_64; - u32 v32_b0; - u8 v08_e1; - - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x64, &v08_64); - early_read_config_dword(hose, busno, busno, - pci_devfn, 0xb0, &v32_b0); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0xe1, &v08_e1); - - /* serial irq control */ - v08_64 = 0xd0; - - /* serial irq pin */ - v32_b0 |= 0x00010000; - - /* ide irq on isa14 */ - v08_e1 &= 0xf0; - v08_e1 |= 0x0d; - - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x64, v08_64); - early_write_config_dword(hose, busno, busno, - pci_devfn, 0xb0, v32_b0); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0xe1, v08_e1); - } - - if (id == 0x91301055) { - u8 v08_04; - u8 v08_09; - u8 v08_41; - u8 v08_43; - u8 v08_5c; - - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x04, &v08_04); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x09, &v08_09); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x41, &v08_41); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x43, &v08_43); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x5c, &v08_5c); - - /* enable ide master/io */ - v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); - - /* enable ide native mode */ - v08_09 |= 0x05; - - /* enable primary ide */ - v08_41 |= 0x80; - - /* enable secondary ide */ - v08_43 |= 0x80; - - /* - * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! - * - * This line of code is intended to provide the user with a work - * around solution to the anomalies cited in SMSC's anomaly sheet - * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". - * - * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! - */ - v08_5c |= 0x01; - - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x5c, v08_5c); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x04, v08_04); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x09, v08_09); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x41, v08_41); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x43, v08_43); - } - - } - - register_pci_controller(&tx4927_controller); - return 0; -} - -arch_initcall(tx4927_pcibios_init); - -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; - -void __init tx4927_pci_setup(void) -{ - static int called = 0; - extern unsigned int tx4927_get_mem_size(void); - - mips_memory_upper = tx4927_get_mem_size() << 20; - mips_memory_upper += KSEG0; - mips_pci_io_base = TX4927_PCIIO; - mips_pci_io_size = TX4927_PCIIO_SIZE; - mips_pci_mem_base = TX4927_PCIMEM; - mips_pci_mem_size = TX4927_PCIMEM_SIZE; - - if (!called) { - printk - ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", - toshiba_name, - (unsigned short) (tx4927_pcicptr->pciid >> 16), - (unsigned short) (tx4927_pcicptr->pciid & 0xffff), - (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), - (!(tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIXARB)) ? "External" : - "Internal"); - called = 1; - } - printk("%s PCIC --%s PCICLK:", toshiba_name, - (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); - if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { - int pciclk = 0; - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long) tx4927_ccfgptr-> - ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { - case TX4937_CCFG_PCIDIVMODE_4: - pciclk = tx4927_cpu_clock / 4; - break; - case TX4937_CCFG_PCIDIVMODE_4_5: - pciclk = tx4927_cpu_clock * 2 / 9; - break; - case TX4937_CCFG_PCIDIVMODE_5: - pciclk = tx4927_cpu_clock / 5; - break; - case TX4937_CCFG_PCIDIVMODE_5_5: - pciclk = tx4927_cpu_clock * 2 / 11; - break; - case TX4937_CCFG_PCIDIVMODE_8: - pciclk = tx4927_cpu_clock / 8; - break; - case TX4937_CCFG_PCIDIVMODE_9: - pciclk = tx4927_cpu_clock / 9; - break; - case TX4937_CCFG_PCIDIVMODE_10: - pciclk = tx4927_cpu_clock / 10; - break; - case TX4937_CCFG_PCIDIVMODE_11: - pciclk = tx4927_cpu_clock / 11; - break; - } - - else - switch ((unsigned long) tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { - case TX4927_CCFG_PCIDIVMODE_2_5: - pciclk = tx4927_cpu_clock * 2 / 5; - break; - case TX4927_CCFG_PCIDIVMODE_3: - pciclk = tx4927_cpu_clock / 3; - break; - case TX4927_CCFG_PCIDIVMODE_5: - pciclk = tx4927_cpu_clock / 5; - break; - case TX4927_CCFG_PCIDIVMODE_6: - pciclk = tx4927_cpu_clock / 6; - break; - } - - printk("Internal(%dMHz)", pciclk / 1000000); - } else - printk("External"); - printk("\n"); - - /* GB->PCI mappings */ - tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; - tx4927_pcicptr->g2piogbase = mips_pci_io_base | -#ifdef __BIG_ENDIAN - TX4927_PCIC_G2PIOGBASE_ECHG -#else - TX4927_PCIC_G2PIOGBASE_BSDIS -#endif - ; - - tx4927_pcicptr->g2piopbase = 0; - - tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; - tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | -#ifdef __BIG_ENDIAN - TX4927_PCIC_G2PMnGBASE_ECHG -#else - TX4927_PCIC_G2PMnGBASE_BSDIS -#endif - ; - tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; - - tx4927_pcicptr->g2pmmask[1] = 0; - tx4927_pcicptr->g2pmgbase[1] = 0; - tx4927_pcicptr->g2pmpbase[1] = 0; - tx4927_pcicptr->g2pmmask[2] = 0; - tx4927_pcicptr->g2pmgbase[2] = 0; - tx4927_pcicptr->g2pmpbase[2] = 0; - - - /* PCI->GB mappings (I/O 256B) */ - tx4927_pcicptr->p2giopbase = 0; /* 256B */ - - /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ - tx4927_pcicptr->p2gm0plbase = 0; - tx4927_pcicptr->p2gm0pubase = 0; - tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | -#ifdef __BIG_ENDIAN - TX4927_PCIC_P2GMnGBASE_TECHG -#else - TX4927_PCIC_P2GMnGBASE_TBSDIS -#endif - ; - - /* PCI->GB mappings (MEM 16MB) -not used */ - tx4927_pcicptr->p2gm1plbase = 0xffffffff; - tx4927_pcicptr->p2gm1pubase = 0xffffffff; - tx4927_pcicptr->p2gmgbase[1] = 0; - - /* PCI->GB mappings (MEM 1MB) -not used */ - tx4927_pcicptr->p2gm2pbase = 0xffffffff; - tx4927_pcicptr->p2gmgbase[2] = 0; - - - /* Enable Initiator Memory 0 Space, I/O Space, Config */ - tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; - tx4927_pcicptr->pciccfg |= - TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | - TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; - - - /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ - tx4927_pcicptr->pcicfg1 = 0; - - if (tx4927_pcic_trdyto >= 0) { - tx4927_pcicptr->g2ptocnt &= ~0xff; - tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); - } - - /* Clear All Local Bus Status */ - tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; - /* Enable All Local Bus Interrupts */ - tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; - /* Clear All Initiator Status */ - tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; - /* Enable All Initiator Interrupts */ - tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; - /* Clear All PCI Status Error */ - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr->pcistatus & 0x0000ffff) | - (TX4927_PCIC_PCISTATUS_ALL << 16); - /* Enable All PCI Status Error Interrupts */ - tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; - - /* PCIC Int => IRC IRQ16 */ - tx4927_pcicptr->pcicfg2 = - (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; - - if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { - /* XXX */ - } else { - /* Reset Bus Arbiter */ - tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; - /* Enable Bus Arbiter */ - tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; - } - - tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -} -#endif /* CONFIG_PCI */ - -static void __noreturn wait_forever(void) -{ - while (1) - if (cpu_wait) - (*cpu_wait)(); -} - -void toshiba_rbtx4927_restart(char *command) -{ - printk(KERN_NOTICE "System Rebooting...\n"); - - /* enable the s/w reset register */ - writeb(RBTX4927_SW_RESET_ENABLE_SET, RBTX4927_SW_RESET_ENABLE); - - /* wait for enable to be seen */ - while ((readb(RBTX4927_SW_RESET_ENABLE) & - RBTX4927_SW_RESET_ENABLE_SET) == 0x00); - - /* do a s/w reset */ - writeb(RBTX4927_SW_RESET_DO_SET, RBTX4927_SW_RESET_DO); - - /* do something passive while waiting for reset */ - local_irq_disable(); - wait_forever(); - /* no return */ -} - -void toshiba_rbtx4927_halt(void) -{ - printk(KERN_NOTICE "System Halted\n"); - local_irq_disable(); - wait_forever(); - /* no return */ -} - -void toshiba_rbtx4927_power_off(void) -{ - toshiba_rbtx4927_halt(); - /* no return */ -} - -void __init plat_mem_setup(void) -{ - int i; - u32 cp0_config; - char *argptr; - - printk("CPU is %s\n", toshiba_name); - - /* f/w leaves this on at startup */ - clear_c0_status(ST0_ERL); - - /* enable caches -- HCP5 does this, pmon does not */ - cp0_config = read_c0_config(); - cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); - write_c0_config(cp0_config); - - set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); - - ioport_resource.end = 0xffffffff; - iomem_resource.end = 0xffffffff; - - _machine_restart = toshiba_rbtx4927_restart; - _machine_halt = toshiba_rbtx4927_halt; - pm_power_off = toshiba_rbtx4927_power_off; - - for (i = 0; i < TX4927_NR_TMR; i++) - txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL); - -#ifdef CONFIG_PCI - - /* PCIC */ - /* - * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. - * - * For TX4927: - * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1). - * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) - * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) - * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) - * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) - * i.e. S9[3]: ON (83MHz), OFF (100MHz) - * - * For TX4937: - * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1) - * PCIDIVMODE[10] is 0. - * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8) - * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4) - * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9) - * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5) - * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10) - * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) - * - */ - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long)tx4927_ccfgptr-> - ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { - case TX4937_CCFG_PCIDIVMODE_8: - case TX4937_CCFG_PCIDIVMODE_4: - tx4927_cpu_clock = 266666666; /* 266MHz */ - break; - case TX4937_CCFG_PCIDIVMODE_9: - case TX4937_CCFG_PCIDIVMODE_4_5: - tx4927_cpu_clock = 300000000; /* 300MHz */ - break; - default: - tx4927_cpu_clock = 333333333; /* 333MHz */ - } - else - switch ((unsigned long)tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { - case TX4927_CCFG_PCIDIVMODE_2_5: - case TX4927_CCFG_PCIDIVMODE_5: - tx4927_cpu_clock = 166666666; /* 166MHz */ - break; - default: - tx4927_cpu_clock = 200000000; /* 200MHz */ - } - - /* CCFG */ - /* do reset on watchdog */ - tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR; - /* enable Timeout BusError */ - if (tx4927_ccfg_toeon) - tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; - - tx4927_pci_setup(); - if (tx4927_using_backplane == 1) - printk("backplane board IS installed\n"); - else - printk("No Backplane \n"); - - /* this is on ISA bus behind PCI bus, so need PCI up first */ -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) { - smsc_fdc37m81x_init(0x3f0); - smsc_fdc37m81x_config_beg(); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, - SMSC_FDC37M81X_KBD); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, - 1); - smsc_fdc37m81x_config_end(); - } -#endif -#endif /* CONFIG_PCI */ - -#ifdef CONFIG_SERIAL_TXX9 - { - extern int early_serial_txx9_setup(struct uart_port *port); - struct uart_port req; - for(i = 0; i < 2; i++) { - memset(&req, 0, sizeof(req)); - req.line = i; - req.iotype = UPIO_MEM; - req.membase = (char *)(0xff1ff300 + i * 0x100); - req.mapbase = 0xff1ff300 + i * 0x100; - req.irq = TX4927_IRQ_PIC_BEG + 8 + i; - req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; - req.uartclk = 50000000; - early_serial_txx9_setup(&req); - } - } -#ifdef CONFIG_SERIAL_TXX9_CONSOLE - argptr = prom_getcmdline(); - if (strstr(argptr, "console=") == NULL) { - strcat(argptr, " console=ttyS0,38400"); - } -#endif -#endif - -#ifdef CONFIG_ROOT_NFS - argptr = prom_getcmdline(); - if (strstr(argptr, "root=") == NULL) { - strcat(argptr, " root=/dev/nfs rw"); - } -#endif - -#ifdef CONFIG_IP_PNP - argptr = prom_getcmdline(); - if (strstr(argptr, "ip=") == NULL) { - strcat(argptr, " ip=any"); - } -#endif -} - -void __init plat_time_init(void) -{ - mips_hpt_frequency = tx4927_cpu_clock / 2; - if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) - txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, - TXX9_IRQ_BASE + 17, - 50000000); -} - -static int __init toshiba_rbtx4927_rtc_init(void) -{ - static struct resource __initdata res = { - .start = 0x1c010000, - .end = 0x1c010000 + 0x800 - 1, - .flags = IORESOURCE_MEM, - }; - struct platform_device *dev = - platform_device_register_simple("rtc-ds1742", -1, &res, 1); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} -device_initcall(toshiba_rbtx4927_rtc_init); - -static int __init rbtx4927_ne_init(void) -{ - static struct resource __initdata res[] = { - { - .start = RBTX4927_RTL_8019_BASE, - .end = RBTX4927_RTL_8019_BASE + 0x20 - 1, - .flags = IORESOURCE_IO, - }, { - .start = RBTX4927_RTL_8019_IRQ, - .flags = IORESOURCE_IRQ, - } - }; - struct platform_device *dev = - platform_device_register_simple("ne", -1, - res, ARRAY_SIZE(res)); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} -device_initcall(rbtx4927_ne_init); - -/* Watchdog support */ - -static int __init txx9_wdt_init(unsigned long base) -{ - struct resource res = { - .start = base, - .end = base + 0x100 - 1, - .flags = IORESOURCE_MEM, - }; - struct platform_device *dev = - platform_device_register_simple("txx9wdt", -1, &res, 1); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} - -static int __init rbtx4927_wdt_init(void) -{ - return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); -} -device_initcall(rbtx4927_wdt_init); - -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "imbus_clk")) - return (struct clk *)50000000; - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/tx4938/Kconfig b/arch/mips/tx4938/Kconfig deleted file mode 100644 index d90e9cd..0000000 --- a/arch/mips/tx4938/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -if TOSHIBA_RBTX4938 - -comment "Multiplex Pin Select" -choice - prompt "PIO[58:61]" - default TOSHIBA_RBTX4938_MPLEX_PIO58_61 - -config TOSHIBA_RBTX4938_MPLEX_PIO58_61 - bool "PIO" -config TOSHIBA_RBTX4938_MPLEX_NAND - bool "NAND" -config TOSHIBA_RBTX4938_MPLEX_ATA - bool "ATA" - -endchoice - -config TX4938_NAND_BOOT - depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND - bool "NAND Boot Support (EXPERIMENTAL)" - help - This is only for Toshiba RBTX4938 reference board, which has NAND IPL. - Select this option if you need to use NAND boot. - -endif diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile deleted file mode 100644 index 56aa1ed..0000000 --- a/arch/mips/tx4938/common/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for common code for Toshiba TX4927 based systems -# - -obj-y += prom.o irq.o -obj-$(CONFIG_KGDB) += dbgio.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c deleted file mode 100644 index 33b9c67..0000000 --- a/arch/mips/tx4938/common/dbgio.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/arch/mips/tx4938/common/dbgio.c - * - * kgdb interface for gdb - * - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2005 MontaVista Software 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Support for TX4938 in 2.6 - Hiroshi DOYU - */ - -#include - -extern u8 txx9_sio_kdbg_rd(void); -extern int txx9_sio_kdbg_wr( u8 ch ); - -u8 getDebugChar(void) -{ - return (txx9_sio_kdbg_rd()); -} - -int putDebugChar(u8 byte) -{ - return (txx9_sio_kdbg_wr(byte)); -} - diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c deleted file mode 100644 index c059b89..0000000 --- a/arch/mips/tx4938/common/irq.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/arch/mips/tx4938/common/irq.c - * - * Common tx4938 irq handler - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include - -void __init -tx4938_irq_init(void) -{ - mips_cpu_irq_init(); - txx9_irq_init(TX4938_IRC_REG); - set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); -} - -int toshiba_rbtx4938_irq_nested(int irq); - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status(); - - if (pending & STATUSF_IP7) - do_IRQ(TX4938_IRQ_CPU_TIMER); - else if (pending & STATUSF_IP2) { - int irq = txx9_irq(); - if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0)) - irq = toshiba_rbtx4938_irq_nested(irq); - if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); - } else if (pending & STATUSF_IP1) - do_IRQ(TX4938_IRQ_USER1); - else if (pending & STATUSF_IP0) - do_IRQ(TX4938_IRQ_USER0); -} diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c deleted file mode 100644 index 20baeae..0000000 --- a/arch/mips/tx4938/common/prom.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * linux/arch/mips/tx4938/common/prom.c - * - * common tx4938 memory interface - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ - -#include -#include -#include - -static unsigned int __init -tx4938_process_sdccr(u64 * addr) -{ - u64 val; - unsigned int sdccr_ce; - unsigned int sdccr_rs; - unsigned int sdccr_cs; - unsigned int sdccr_mw; - unsigned int rs = 0; - unsigned int cs = 0; - unsigned int mw = 0; - unsigned int bc = 4; - unsigned int msize = 0; - - val = ____raw_readq((void __iomem *)addr); - - /* MVMCP -- need #defs for these bits masks */ - sdccr_ce = ((val & (1 << 10)) >> 10); - sdccr_rs = ((val & (3 << 5)) >> 5); - sdccr_cs = ((val & (7 << 2)) >> 2); - sdccr_mw = ((val & (1 << 0)) >> 0); - - if (sdccr_ce) { - switch (sdccr_rs) { - case 0:{ - rs = 2048; - break; - } - case 1:{ - rs = 4096; - break; - } - case 2:{ - rs = 8192; - break; - } - default:{ - rs = 0; - break; - } - } - switch (sdccr_cs) { - case 0:{ - cs = 256; - break; - } - case 1:{ - cs = 512; - break; - } - case 2:{ - cs = 1024; - break; - } - case 3:{ - cs = 2048; - break; - } - case 4:{ - cs = 4096; - break; - } - default:{ - cs = 0; - break; - } - } - switch (sdccr_mw) { - case 0:{ - mw = 8; - break; - } /* 8 bytes = 64 bits */ - case 1:{ - mw = 4; - break; - } /* 4 bytes = 32 bits */ - } - } - - /* bytes per chip MB per chip bank count */ - msize = (((rs * cs * mw) / (1024 * 1024)) * (bc)); - - /* MVMCP -- bc hard coded to 4 from table 9.3.1 */ - /* boad supports bc=2 but no way to detect */ - - return (msize); -} - -unsigned int __init -tx4938_get_mem_size(void) -{ - unsigned int c0; - unsigned int c1; - unsigned int c2; - unsigned int c3; - unsigned int total; - - /* MVMCP -- need #defs for these registers */ - c0 = tx4938_process_sdccr((u64 *) 0xff1f8000); - c1 = tx4938_process_sdccr((u64 *) 0xff1f8008); - c2 = tx4938_process_sdccr((u64 *) 0xff1f8010); - c3 = tx4938_process_sdccr((u64 *) 0xff1f8018); - total = c0 + c1 + c2 + c3; - - return (total); -} diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile deleted file mode 100644 index 2316dd7..0000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for common code for Toshiba TX4927 based systems -# - -obj-y += prom.o setup.o irq.o spi_eeprom.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c deleted file mode 100644 index 4d6a8dc..0000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c - * - * Toshiba RBTX4938 specific interrupt handlers - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ - -/* -IRQ Device - -16 TX4938-CP0/00 Software 0 -17 TX4938-CP0/01 Software 1 -18 TX4938-CP0/02 Cascade TX4938-CP0 -19 TX4938-CP0/03 Multiplexed -- do not use -20 TX4938-CP0/04 Multiplexed -- do not use -21 TX4938-CP0/05 Multiplexed -- do not use -22 TX4938-CP0/06 Multiplexed -- do not use -23 TX4938-CP0/07 CPU TIMER - -24 TX4938-PIC/00 -25 TX4938-PIC/01 -26 TX4938-PIC/02 Cascade RBTX4938-IOC -27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet -28 TX4938-PIC/04 -29 TX4938-PIC/05 TX4938 ETH1 -30 TX4938-PIC/06 TX4938 ETH0 -31 TX4938-PIC/07 -32 TX4938-PIC/08 TX4938 SIO 0 -33 TX4938-PIC/09 TX4938 SIO 1 -34 TX4938-PIC/10 TX4938 DMA0 -35 TX4938-PIC/11 TX4938 DMA1 -36 TX4938-PIC/12 TX4938 DMA2 -37 TX4938-PIC/13 TX4938 DMA3 -38 TX4938-PIC/14 -39 TX4938-PIC/15 -40 TX4938-PIC/16 TX4938 PCIC -41 TX4938-PIC/17 TX4938 TMR0 -42 TX4938-PIC/18 TX4938 TMR1 -43 TX4938-PIC/19 TX4938 TMR2 -44 TX4938-PIC/20 -45 TX4938-PIC/21 -46 TX4938-PIC/22 TX4938 PCIERR -47 TX4938-PIC/23 -48 TX4938-PIC/24 -49 TX4938-PIC/25 -50 TX4938-PIC/26 -51 TX4938-PIC/27 -52 TX4938-PIC/28 -53 TX4938-PIC/29 -54 TX4938-PIC/30 -55 TX4938-PIC/31 TX4938 SPI - -56 RBTX4938-IOC/00 PCI-D -57 RBTX4938-IOC/01 PCI-C -58 RBTX4938-IOC/02 PCI-B -59 RBTX4938-IOC/03 PCI-A -60 RBTX4938-IOC/04 RTC -61 RBTX4938-IOC/05 ATA -62 RBTX4938-IOC/06 MODEM -63 RBTX4938-IOC/07 SWINT -*/ -#include -#include -#include - -static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); -static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); - -#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" -static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { - .name = TOSHIBA_RBTX4938_IOC_NAME, - .ack = toshiba_rbtx4938_irq_ioc_disable, - .mask = toshiba_rbtx4938_irq_ioc_disable, - .mask_ack = toshiba_rbtx4938_irq_ioc_disable, - .unmask = toshiba_rbtx4938_irq_ioc_enable, -}; - -int -toshiba_rbtx4938_irq_nested(int sw_irq) -{ - u8 level3; - - level3 = readb(rbtx4938_imstat_addr); - if (level3) - /* must use fls so onboard ATA has priority */ - sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1; - - return sw_irq; -} - -static struct irqaction toshiba_rbtx4938_irq_ioc_action = { - .handler = no_action, - .flags = 0, - .mask = CPU_MASK_NONE, - .name = TOSHIBA_RBTX4938_IOC_NAME, -}; - -/**********************************************************************************/ -/* Functions for ioc */ -/**********************************************************************************/ -static void __init -toshiba_rbtx4938_irq_ioc_init(void) -{ - int i; - - for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, - handle_level_irq); - - setup_irq(RBTX4938_IRQ_IOCINT, - &toshiba_rbtx4938_irq_ioc_action); -} - -static void -toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) -{ - unsigned char v; - - v = readb(rbtx4938_imask_addr); - v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); - writeb(v, rbtx4938_imask_addr); - mmiowb(); -} - -static void -toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) -{ - unsigned char v; - - v = readb(rbtx4938_imask_addr); - v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); - writeb(v, rbtx4938_imask_addr); - mmiowb(); -} - -void __init arch_init_irq(void) -{ - extern void tx4938_irq_init(void); - - /* Now, interrupt control disabled, */ - /* all IRC interrupts are masked, */ - /* all IRC interrupt mode are Low Active. */ - - /* mask all IOC interrupts */ - writeb(0, rbtx4938_imask_addr); - - /* clear SoftInt interrupts */ - writeb(0, rbtx4938_softint_addr); - tx4938_irq_init(); - toshiba_rbtx4938_irq_ioc_init(); - /* Onboard 10M Ether: High Active */ - set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); -} diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c deleted file mode 100644 index 1644bff..0000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/prom.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c - * - * rbtx4938 specific prom routines - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ - -#include -#include -#include -#include - -#include -#include -#include - -void __init prom_init_cmdline(void) -{ - int argc = (int) fw_arg0; - char **argv = (char **) fw_arg1; - int i; - - /* ignore all built-in args if any f/w args given */ - if (argc > 1) { - *arcs_cmdline = '\0'; - } - - for (i = 1; i < argc; i++) { - if (i != 1) { - strcat(arcs_cmdline, " "); - } - strcat(arcs_cmdline, argv[i]); - } -} - -void __init prom_init(void) -{ - extern int tx4938_get_mem_size(void); - int msize; -#ifndef CONFIG_TX4938_NAND_BOOT - prom_init_cmdline(); -#endif - - msize = tx4938_get_mem_size(); - add_memory_region(0, msize << 20, BOOT_MEM_RAM); - - return; -} - -void __init prom_free_prom_memory(void) -{ -} - -void __init prom_fixup_mem_map(unsigned long start, unsigned long end) -{ - return; -} - -const char *get_system_type(void) -{ - return "Toshiba RBTX4938"; -} - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c deleted file mode 100644 index 3a3659e..0000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c - * - * Setup pointers to hardware-dependent routines. - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_SERIAL_TXX9 -#include -#endif -#include -#include -#include - -extern char * __init prom_getcmdline(void); -static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); - -/* These functions are used for rebooting or halting the machine*/ -extern void rbtx4938_machine_restart(char *command); -extern void rbtx4938_machine_halt(void); -extern void rbtx4938_machine_power_off(void); - -/* clocks */ -unsigned int txx9_master_clock; -unsigned int txx9_cpu_clock; -unsigned int txx9_gbus_clock; - -unsigned long rbtx4938_ce_base[8]; -unsigned long rbtx4938_ce_size[8]; -int txboard_pci66_mode; -static int tx4938_pcic_trdyto; /* default: disabled */ -static int tx4938_pcic_retryto; /* default: disabled */ -static int tx4938_ccfg_toeon = 1; - -struct tx4938_pcic_reg *pcicptrs[4] = { - tx4938_pcicptr /* default setting for TX4938 */ -}; - -static struct { - unsigned long base; - unsigned long size; -} phys_regions[16] __initdata; -static int num_phys_regions __initdata; - -#define PHYS_REGION_MINSIZE 0x10000 - -void rbtx4938_machine_halt(void) -{ - printk(KERN_NOTICE "System Halted\n"); - local_irq_disable(); - - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); -} - -void rbtx4938_machine_power_off(void) -{ - rbtx4938_machine_halt(); - /* no return */ -} - -void rbtx4938_machine_restart(char *command) -{ - local_irq_disable(); - - printk("Rebooting..."); - writeb(1, rbtx4938_softresetlock_addr); - writeb(1, rbtx4938_sfvol_addr); - writeb(1, rbtx4938_softreset_addr); - while(1) - ; -} - -void __init -txboard_add_phys_region(unsigned long base, unsigned long size) -{ - if (num_phys_regions >= ARRAY_SIZE(phys_regions)) { - printk("phys_region overflow\n"); - return; - } - phys_regions[num_phys_regions].base = base; - phys_regions[num_phys_regions].size = size; - num_phys_regions++; -} -unsigned long __init -txboard_find_free_phys_region(unsigned long begin, unsigned long end, - unsigned long size) -{ - unsigned long base; - int i; - - for (base = begin / size * size; base < end; base += size) { - for (i = 0; i < num_phys_regions; i++) { - if (phys_regions[i].size && - base <= phys_regions[i].base + (phys_regions[i].size - 1) && - base + (size - 1) >= phys_regions[i].base) - break; - } - if (i == num_phys_regions) - return base; - } - return 0; -} -unsigned long __init -txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end, - unsigned long *size) -{ - unsigned long sz, base; - for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) { - base = txboard_find_free_phys_region(begin, end, sz); - if (base) { - *size = sz; - return base; - } - } - return 0; -} -unsigned long __init -txboard_request_phys_region_range(unsigned long begin, unsigned long end, - unsigned long size) -{ - unsigned long base; - base = txboard_find_free_phys_region(begin, end, size); - if (base) - txboard_add_phys_region(base, size); - return base; -} -unsigned long __init -txboard_request_phys_region(unsigned long size) -{ - unsigned long base; - unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ - base = txboard_find_free_phys_region(begin, end, size); - if (base) - txboard_add_phys_region(base, size); - return base; -} -unsigned long __init -txboard_request_phys_region_shrink(unsigned long *size) -{ - unsigned long base; - unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ - base = txboard_find_free_phys_region_shrink(begin, end, size); - if (base) - txboard_add_phys_region(base, *size); - return base; -} - -#ifdef CONFIG_PCI -void __init -tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr, - struct pci_controller *channel, - unsigned long pci_io_base, - int extarb) -{ - int i; - - /* Disable All Initiator Space */ - pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)| - TX4938_PCIC_PCICCFG_G2PMEN(1)| - TX4938_PCIC_PCICCFG_G2PMEN(2)| - TX4938_PCIC_PCICCFG_G2PIOEN); - - /* GB->PCI mappings */ - pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4; - pcicptr->g2piogbase = pci_io_base | -#ifdef __BIG_ENDIAN - TX4938_PCIC_G2PIOGBASE_ECHG -#else - TX4938_PCIC_G2PIOGBASE_BSDIS -#endif - ; - pcicptr->g2piopbase = 0; - for (i = 0; i < 3; i++) { - pcicptr->g2pmmask[i] = 0; - pcicptr->g2pmgbase[i] = 0; - pcicptr->g2pmpbase[i] = 0; - } - if (channel->mem_resource->end) { - pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4; - pcicptr->g2pmgbase[0] = channel->mem_resource->start | -#ifdef __BIG_ENDIAN - TX4938_PCIC_G2PMnGBASE_ECHG -#else - TX4938_PCIC_G2PMnGBASE_BSDIS -#endif - ; - pcicptr->g2pmpbase[0] = channel->mem_resource->start; - } - /* PCI->GB mappings (I/O 256B) */ - pcicptr->p2giopbase = 0; /* 256B */ - pcicptr->p2giogbase = 0; - /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ - pcicptr->p2gm0plbase = 0; - pcicptr->p2gm0pubase = 0; - pcicptr->p2gmgbase[0] = 0 | - TX4938_PCIC_P2GMnGBASE_TMEMEN | -#ifdef __BIG_ENDIAN - TX4938_PCIC_P2GMnGBASE_TECHG -#else - TX4938_PCIC_P2GMnGBASE_TBSDIS -#endif - ; - /* PCI->GB mappings (MEM 16MB) */ - pcicptr->p2gm1plbase = 0xffffffff; - pcicptr->p2gm1pubase = 0xffffffff; - pcicptr->p2gmgbase[1] = 0; - /* PCI->GB mappings (MEM 1MB) */ - pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */ - pcicptr->p2gmgbase[2] = 0; - - pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK; - /* Enable Initiator Memory Space */ - if (channel->mem_resource->end) - pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0); - /* Enable Initiator I/O Space */ - if (channel->io_resource->end) - pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN; - /* Enable Initiator Config */ - pcicptr->pciccfg |= - TX4938_PCIC_PCICCFG_ICAEN | - TX4938_PCIC_PCICCFG_TCAR; - - /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ - pcicptr->pcicfg1 = 0; - - pcicptr->g2ptocnt &= ~0xffff; - - if (tx4938_pcic_trdyto >= 0) { - pcicptr->g2ptocnt &= ~0xff; - pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff); - } - - if (tx4938_pcic_retryto >= 0) { - pcicptr->g2ptocnt &= ~0xff00; - pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00); - } - - /* Clear All Local Bus Status */ - pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL; - /* Enable All Local Bus Interrupts */ - pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL; - /* Clear All Initiator Status */ - pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL; - /* Enable All Initiator Interrupts */ - pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL; - /* Clear All PCI Status Error */ - pcicptr->pcistatus = - (pcicptr->pcistatus & 0x0000ffff) | - (TX4938_PCIC_PCISTATUS_ALL << 16); - /* Enable All PCI Status Error Interrupts */ - pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL; - - if (!extarb) { - /* Reset Bus Arbiter */ - pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA; - pcicptr->pbabm = 0; - /* Enable Bus Arbiter */ - pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN; - } - - /* PCIC Int => IRC IRQ16 */ - pcicptr->pcicfg2 = - (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC; - - pcicptr->pcistatus = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -} - -int __init -tx4938_report_pciclk(void) -{ - unsigned long pcode = TX4938_REV_PCODE(); - int pciclk = 0; - printk("TX%lx PCIC --%s PCICLK:", - pcode, - (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : ""); - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { - - switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) { - case TX4938_CCFG_PCIDIVMODE_4: - pciclk = txx9_cpu_clock / 4; break; - case TX4938_CCFG_PCIDIVMODE_4_5: - pciclk = txx9_cpu_clock * 2 / 9; break; - case TX4938_CCFG_PCIDIVMODE_5: - pciclk = txx9_cpu_clock / 5; break; - case TX4938_CCFG_PCIDIVMODE_5_5: - pciclk = txx9_cpu_clock * 2 / 11; break; - case TX4938_CCFG_PCIDIVMODE_8: - pciclk = txx9_cpu_clock / 8; break; - case TX4938_CCFG_PCIDIVMODE_9: - pciclk = txx9_cpu_clock / 9; break; - case TX4938_CCFG_PCIDIVMODE_10: - pciclk = txx9_cpu_clock / 10; break; - case TX4938_CCFG_PCIDIVMODE_11: - pciclk = txx9_cpu_clock / 11; break; - } - printk("Internal(%dMHz)", pciclk / 1000000); - } else { - printk("External"); - pciclk = -1; - } - printk("\n"); - return pciclk; -} - -void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr) -{ - pcicptrs[ch] = pcicptr; -} - -struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch) -{ - return pcicptrs[ch]; -} - -static struct pci_dev *fake_pci_dev(struct pci_controller *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.sysdata = bus.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.parent = NULL; - dev.bus = &bus; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_controller *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, word, u16 *) - -int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus) -{ - u32 pci_devfn; - unsigned short vid; - int devfn_start = 0; - int devfn_stop = 0xff; - int cap66 = -1; - u16 stat; - - printk("PCI: Checking 66MHz capabilities...\n"); - - for (pci_devfn=devfn_start; pci_devfn 0; -} - -int __init -tx4938_pciclk66_setup(void) -{ - int pciclk; - - /* Assert M66EN */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; - /* Double PCICLK (if possible) */ - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { - unsigned int pcidivmode = - tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK; - switch (pcidivmode) { - case TX4938_CCFG_PCIDIVMODE_8: - case TX4938_CCFG_PCIDIVMODE_4: - pcidivmode = TX4938_CCFG_PCIDIVMODE_4; - pciclk = txx9_cpu_clock / 4; - break; - case TX4938_CCFG_PCIDIVMODE_9: - case TX4938_CCFG_PCIDIVMODE_4_5: - pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; - pciclk = txx9_cpu_clock * 2 / 9; - break; - case TX4938_CCFG_PCIDIVMODE_10: - case TX4938_CCFG_PCIDIVMODE_5: - pcidivmode = TX4938_CCFG_PCIDIVMODE_5; - pciclk = txx9_cpu_clock / 5; - break; - case TX4938_CCFG_PCIDIVMODE_11: - case TX4938_CCFG_PCIDIVMODE_5_5: - default: - pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; - pciclk = txx9_cpu_clock * 2 / 11; - break; - } - tx4938_ccfgptr->ccfg = - (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) - | pcidivmode; - printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", - (unsigned long)tx4938_ccfgptr->ccfg); - } else { - pciclk = -1; - } - return pciclk; -} - -extern struct pci_controller tx4938_pci_controller[]; -static int __init tx4938_pcibios_init(void) -{ - unsigned long mem_base[2]; - unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ - unsigned long io_base[2]; - unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ - /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ - int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); - - PCIBIOS_MIN_IO = 0x00001000UL; - - mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); - io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); - - printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", - (unsigned short)(tx4938_pcicptr->pciid >> 16), - (unsigned short)(tx4938_pcicptr->pciid & 0xffff), - (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), - extarb ? "External" : "Internal"); - - /* setup PCI area */ - tx4938_pci_controller[0].io_resource->start = io_base[0]; - tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; - tx4938_pci_controller[0].mem_resource->start = mem_base[0]; - tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; - - set_tx4938_pcicptr(0, tx4938_pcicptr); - - register_pci_controller(&tx4938_pci_controller[0]); - - if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { - printk("TX4938_CCFG_PCI66 already configured\n"); - txboard_pci66_mode = -1; /* already configured */ - } - - /* Reset PCI Bus */ - writeb(0, rbtx4938_pcireset_addr); - /* Reset PCIC */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; - if (txboard_pci66_mode > 0) - tx4938_pciclk66_setup(); - mdelay(10); - /* clear PCIC reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; - writeb(1, rbtx4938_pcireset_addr); - mmiowb(); - tx4938_report_pcic_status1(tx4938_pcicptr); - - tx4938_report_pciclk(); - tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); - if (txboard_pci66_mode == 0 && - txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { - /* Reset PCI Bus */ - writeb(0, rbtx4938_pcireset_addr); - /* Reset PCIC */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; - tx4938_pciclk66_setup(); - mdelay(10); - /* clear PCIC reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; - writeb(1, rbtx4938_pcireset_addr); - mmiowb(); - /* Reinitialize PCIC */ - tx4938_report_pciclk(); - tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); - } - - mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); - io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); - /* Reset PCIC1 */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; - /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ - if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) - tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; - else - tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; - mdelay(10); - /* clear PCIC1 reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; - tx4938_report_pcic_status1(tx4938_pcic1ptr); - - printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", - (unsigned short)(tx4938_pcic1ptr->pciid >> 16), - (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), - (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); - printk("%s PCICLK:%dMHz\n", - (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", - txx9_gbus_clock / - ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / - 1000000); - - /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ - tx4938_pci_controller[1].io_resource->start = - io_base[1] - io_base[0]; - tx4938_pci_controller[1].io_resource->end = - io_base[1] - io_base[0] + io_size[1] - 1; - tx4938_pci_controller[1].mem_resource->start = mem_base[1]; - tx4938_pci_controller[1].mem_resource->end = - mem_base[1] + mem_size[1] - 1; - set_tx4938_pcicptr(1, tx4938_pcic1ptr); - - register_pci_controller(&tx4938_pci_controller[1]); - - tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); - - /* map ioport 0 to PCI I/O space address 0 */ - set_io_port_base(KSEG1 + io_base[0]); - - return 0; -} - -arch_initcall(tx4938_pcibios_init); - -#endif /* CONFIG_PCI */ - -/* SPI support */ - -/* chip select for SPI devices */ -#define SEEPROM1_CS 7 /* PIO7 */ -#define SEEPROM2_CS 0 /* IOC */ -#define SEEPROM3_CS 1 /* IOC */ -#define SRTC_CS 2 /* IOC */ - -#ifdef CONFIG_PCI -static int __init rbtx4938_ethaddr_init(void) -{ - unsigned char dat[17]; - unsigned char sum; - int i; - - /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ - if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { - printk(KERN_ERR "seeprom: read error.\n"); - return -ENODEV; - } else { - if (strcmp(dat, "MAC") != 0) - printk(KERN_WARNING "seeprom: bad signature.\n"); - for (i = 0, sum = 0; i < sizeof(dat); i++) - sum += dat[i]; - if (sum) - printk(KERN_WARNING "seeprom: bad checksum.\n"); - } - for (i = 0; i < 2; i++) { - unsigned int id = - TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); - struct platform_device *pdev; - if (!(tx4938_ccfgptr->pcfg & - (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) - continue; - pdev = platform_device_alloc("tc35815-mac", id); - if (!pdev || - platform_device_add_data(pdev, &dat[4 + 6 * i], 6) || - platform_device_add(pdev)) - platform_device_put(pdev); - } - return 0; -} -device_initcall(rbtx4938_ethaddr_init); -#endif /* CONFIG_PCI */ - -static void __init rbtx4938_spi_setup(void) -{ - /* set SPI_SEL */ - tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; -} - -static struct resource rbtx4938_fpga_resource; - -static char pcode_str[8]; -static struct resource tx4938_reg_resource = { - .start = TX4938_REG_BASE, - .end = TX4938_REG_BASE + TX4938_REG_SIZE, - .name = pcode_str, - .flags = IORESOURCE_MEM -}; - -void __init tx4938_board_setup(void) -{ - int i; - unsigned long divmode; - int cpuclk = 0; - unsigned long pcode = TX4938_REV_PCODE(); - - ioport_resource.start = 0x1000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x1000; - iomem_resource.end = 0xffffffff; /* expand to 4GB */ - - sprintf(pcode_str, "TX%lx", pcode); - /* SDRAMC,EBUSC are configured by PROM */ - for (i = 0; i < 8; i++) { - if (!(tx4938_ebuscptr->cr[i] & 0x8)) - continue; /* disabled */ - rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); - txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); - } - - /* clocks */ - if (txx9_master_clock) { - /* calculate gbus_clock and cpu_clock_freq from master_clock */ - divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; - switch (divmode) { - case TX4938_CCFG_DIVMODE_8: - case TX4938_CCFG_DIVMODE_10: - case TX4938_CCFG_DIVMODE_12: - case TX4938_CCFG_DIVMODE_16: - case TX4938_CCFG_DIVMODE_18: - txx9_gbus_clock = txx9_master_clock * 4; break; - default: - txx9_gbus_clock = txx9_master_clock; - } - switch (divmode) { - case TX4938_CCFG_DIVMODE_2: - case TX4938_CCFG_DIVMODE_8: - cpuclk = txx9_gbus_clock * 2; break; - case TX4938_CCFG_DIVMODE_2_5: - case TX4938_CCFG_DIVMODE_10: - cpuclk = txx9_gbus_clock * 5 / 2; break; - case TX4938_CCFG_DIVMODE_3: - case TX4938_CCFG_DIVMODE_12: - cpuclk = txx9_gbus_clock * 3; break; - case TX4938_CCFG_DIVMODE_4: - case TX4938_CCFG_DIVMODE_16: - cpuclk = txx9_gbus_clock * 4; break; - case TX4938_CCFG_DIVMODE_4_5: - case TX4938_CCFG_DIVMODE_18: - cpuclk = txx9_gbus_clock * 9 / 2; break; - } - txx9_cpu_clock = cpuclk; - } else { - if (txx9_cpu_clock == 0) { - txx9_cpu_clock = 300000000; /* 300MHz */ - } - /* calculate gbus_clock and master_clock from cpu_clock_freq */ - cpuclk = txx9_cpu_clock; - divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; - switch (divmode) { - case TX4938_CCFG_DIVMODE_2: - case TX4938_CCFG_DIVMODE_8: - txx9_gbus_clock = cpuclk / 2; break; - case TX4938_CCFG_DIVMODE_2_5: - case TX4938_CCFG_DIVMODE_10: - txx9_gbus_clock = cpuclk * 2 / 5; break; - case TX4938_CCFG_DIVMODE_3: - case TX4938_CCFG_DIVMODE_12: - txx9_gbus_clock = cpuclk / 3; break; - case TX4938_CCFG_DIVMODE_4: - case TX4938_CCFG_DIVMODE_16: - txx9_gbus_clock = cpuclk / 4; break; - case TX4938_CCFG_DIVMODE_4_5: - case TX4938_CCFG_DIVMODE_18: - txx9_gbus_clock = cpuclk * 2 / 9; break; - } - switch (divmode) { - case TX4938_CCFG_DIVMODE_8: - case TX4938_CCFG_DIVMODE_10: - case TX4938_CCFG_DIVMODE_12: - case TX4938_CCFG_DIVMODE_16: - case TX4938_CCFG_DIVMODE_18: - txx9_master_clock = txx9_gbus_clock / 4; break; - default: - txx9_master_clock = txx9_gbus_clock; - } - } - /* change default value to udelay/mdelay take reasonable time */ - loops_per_jiffy = txx9_cpu_clock / HZ / 2; - - /* CCFG */ - /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; - /* do reset on watchdog */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR; - /* clear PCIC1 reset */ - if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; - - /* enable Timeout BusError */ - if (tx4938_ccfg_toeon) - tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; - - /* DMA selection */ - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; - - /* Use external clock for external arbiter */ - if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; - - printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", - pcode_str, - cpuclk / 1000000, txx9_master_clock / 1000000, - (unsigned long)tx4938_ccfgptr->crir, - tx4938_ccfgptr->ccfg, - tx4938_ccfgptr->pcfg); - - printk("%s SDRAMC --", pcode_str); - for (i = 0; i < 4; i++) { - unsigned long long cr = tx4938_sdramcptr->cr[i]; - unsigned long ram_base, ram_size; - if (!((unsigned long)cr & 0x00000400)) - continue; /* disabled */ - ram_base = (unsigned long)(cr >> 49) << 21; - ram_size = ((unsigned long)(cr >> 33) + 1) << 21; - if (ram_base >= 0x20000000) - continue; /* high memory (ignore) */ - printk(" CR%d:%016Lx", i, cr); - txboard_add_phys_region(ram_base, ram_size); - } - printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); - - /* SRAM */ - if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { - unsigned int size = 0x800; - unsigned long base = - (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); - txboard_add_phys_region(base, size); - } - - /* TMR */ - for (i = 0; i < TX4938_NR_TMR; i++) - txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); - - /* enable DMA */ - for (i = 0; i < 2; i++) - ____raw_writeq(TX4938_DMA_MCR_MSTEN, - (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); - - /* PIO */ - __raw_writel(0, &tx4938_pioptr->maskcpu); - __raw_writel(0, &tx4938_pioptr->maskext); - - /* TX4938 internal registers */ - if (request_resource(&iomem_resource, &tx4938_reg_resource)) - printk("request resource for internal registers failed\n"); -} - -#ifdef CONFIG_PCI -static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr) -{ - unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16); - unsigned long g2pstatus = pcicptr->g2pstatus; - unsigned long pcicstatus = pcicptr->pcicstatus; - static struct { - unsigned long flag; - const char *str; - } pcistat_tbl[] = { - { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, - { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, - { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, - { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, - { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, - { PCI_STATUS_PARITY, "MasterParityError" }, - }, g2pstat_tbl[] = { - { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" }, - { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" }, - }, pcicstat_tbl[] = { - { TX4938_PCIC_PCICSTATUS_PME, "PME" }, - { TX4938_PCIC_PCICSTATUS_TLB, "TLB" }, - { TX4938_PCIC_PCICSTATUS_NIB, "NIB" }, - { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" }, - { TX4938_PCIC_PCICSTATUS_PERR, "PERR" }, - { TX4938_PCIC_PCICSTATUS_SERR, "SERR" }, - { TX4938_PCIC_PCICSTATUS_GBE, "GBE" }, - { TX4938_PCIC_PCICSTATUS_IWB, "IWB" }, - }; - int i; - - printk("pcistat:%04x(", pcistatus); - for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++) - if (pcistatus & pcistat_tbl[i].flag) - printk("%s ", pcistat_tbl[i].str); - printk("), g2pstatus:%08lx(", g2pstatus); - for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) - if (g2pstatus & g2pstat_tbl[i].flag) - printk("%s ", g2pstat_tbl[i].str); - printk("), pcicstatus:%08lx(", pcicstatus); - for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) - if (pcicstatus & pcicstat_tbl[i].flag) - printk("%s ", pcicstat_tbl[i].str); - printk(")\n"); -} - -void tx4938_report_pcic_status(void) -{ - int i; - struct tx4938_pcic_reg *pcicptr; - for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++) - tx4938_report_pcic_status1(pcicptr); -} - -#endif /* CONFIG_PCI */ - -void __init plat_time_init(void) -{ - mips_hpt_frequency = txx9_cpu_clock / 2; - if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS) - txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, - TXX9_IRQ_BASE + TX4938_IR_TMR(0), - txx9_gbus_clock / 2); -} - -void __init plat_mem_setup(void) -{ - unsigned long long pcfg; - char *argptr; - - iomem_resource.end = 0xffffffff; /* 4GB */ - - if (txx9_master_clock == 0) - txx9_master_clock = 25000000; /* 25MHz */ - tx4938_board_setup(); -#ifndef CONFIG_PCI - set_io_port_base(RBTX4938_ETHER_BASE); -#endif - -#ifdef CONFIG_SERIAL_TXX9 - { - extern int early_serial_txx9_setup(struct uart_port *port); - int i; - struct uart_port req; - for(i = 0; i < 2; i++) { - memset(&req, 0, sizeof(req)); - req.line = i; - req.iotype = UPIO_MEM; - req.membase = (char *)(0xff1ff300 + i * 0x100); - req.mapbase = 0xff1ff300 + i * 0x100; - req.irq = RBTX4938_IRQ_IRC_SIO(i); - req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; - req.uartclk = 50000000; - early_serial_txx9_setup(&req); - } - } -#ifdef CONFIG_SERIAL_TXX9_CONSOLE - argptr = prom_getcmdline(); - if (strstr(argptr, "console=") == NULL) { - strcat(argptr, " console=ttyS0,38400"); - } -#endif -#endif - -#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 - printk("PIOSEL: disabling both ata and nand selection\n"); - local_irq_disable(); - tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); -#endif - -#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND - printk("PIOSEL: enabling nand selection\n"); - tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL; - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL; -#endif - -#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA - printk("PIOSEL: enabling ata selection\n"); - tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL; - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL; -#endif - -#ifdef CONFIG_IP_PNP - argptr = prom_getcmdline(); - if (strstr(argptr, "ip=") == NULL) { - strcat(argptr, " ip=any"); - } -#endif - - -#ifdef CONFIG_FB - { - conswitchp = &dummy_con; - } -#endif - - rbtx4938_spi_setup(); - pcfg = tx4938_ccfgptr->pcfg; /* updated */ - /* fixup piosel */ - if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == - TX4938_PCFG_ATA_SEL) - writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04, - rbtx4938_piosel_addr); - else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == - TX4938_PCFG_NDF_SEL) - writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08, - rbtx4938_piosel_addr); - else - writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04), - rbtx4938_piosel_addr); - - rbtx4938_fpga_resource.name = "FPGA Registers"; - rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); - rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; - rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; - if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) - printk("request resource for fpga failed\n"); - - _machine_restart = rbtx4938_machine_restart; - _machine_halt = rbtx4938_machine_halt; - pm_power_off = rbtx4938_machine_power_off; - - writeb(0xff, rbtx4938_led_addr); - printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", - readb(rbtx4938_fpga_rev_addr), - readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr)); -} - -static int __init rbtx4938_ne_init(void) -{ - struct resource res[] = { - { - .start = RBTX4938_RTL_8019_BASE, - .end = RBTX4938_RTL_8019_BASE + 0x20 - 1, - .flags = IORESOURCE_IO, - }, { - .start = RBTX4938_RTL_8019_IRQ, - .flags = IORESOURCE_IRQ, - } - }; - struct platform_device *dev = - platform_device_register_simple("ne", -1, - res, ARRAY_SIZE(res)); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} -device_initcall(rbtx4938_ne_init); - -/* GPIO support */ - -int gpio_to_irq(unsigned gpio) -{ - return -EINVAL; -} - -int irq_to_gpio(unsigned irq) -{ - return -EINVAL; -} - -static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); - -static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset, - int value) -{ - u8 val; - unsigned long flags; - spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); - val = readb(rbtx4938_spics_addr); - if (value) - val |= 1 << offset; - else - val &= ~(1 << offset); - writeb(val, rbtx4938_spics_addr); - mmiowb(); - spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); -} - -static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip, - unsigned int offset, int value) -{ - rbtx4938_spi_gpio_set(chip, offset, value); - return 0; -} - -static struct gpio_chip rbtx4938_spi_gpio_chip = { - .set = rbtx4938_spi_gpio_set, - .direction_output = rbtx4938_spi_gpio_dir_out, - .label = "RBTX4938-SPICS", - .base = 16, - .ngpio = 3, -}; - -/* SPI support */ - -static void __init txx9_spi_init(unsigned long base, int irq) -{ - struct resource res[] = { - { - .start = base, - .end = base + 0x20 - 1, - .flags = IORESOURCE_MEM, - }, { - .start = irq, - .flags = IORESOURCE_IRQ, - }, - }; - platform_device_register_simple("spi_txx9", 0, - res, ARRAY_SIZE(res)); -} - -static int __init rbtx4938_spi_init(void) -{ - struct spi_board_info srtc_info = { - .modalias = "rtc-rs5c348", - .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ - .bus_num = 0, - .chip_select = 16 + SRTC_CS, - /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ - .mode = SPI_MODE_1 | SPI_CS_HIGH, - }; - spi_register_board_info(&srtc_info, 1); - spi_eeprom_register(SEEPROM1_CS); - spi_eeprom_register(16 + SEEPROM2_CS); - spi_eeprom_register(16 + SEEPROM3_CS); - gpio_request(16 + SRTC_CS, "rtc-rs5c348"); - gpio_direction_output(16 + SRTC_CS, 0); - gpio_request(SEEPROM1_CS, "seeprom1"); - gpio_direction_output(SEEPROM1_CS, 1); - gpio_request(16 + SEEPROM2_CS, "seeprom2"); - gpio_direction_output(16 + SEEPROM2_CS, 1); - gpio_request(16 + SEEPROM3_CS, "seeprom3"); - gpio_direction_output(16 + SEEPROM3_CS, 1); - txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); - return 0; -} - -static int __init rbtx4938_arch_init(void) -{ - txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); - gpiochip_add(&rbtx4938_spi_gpio_chip); - return rbtx4938_spi_init(); -} -arch_initcall(rbtx4938_arch_init); - -/* Watchdog support */ - -static int __init txx9_wdt_init(unsigned long base) -{ - struct resource res = { - .start = base, - .end = base + 0x100 - 1, - .flags = IORESOURCE_MEM, - }; - struct platform_device *dev = - platform_device_register_simple("txx9wdt", -1, &res, 1); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} - -static int __init rbtx4938_wdt_init(void) -{ - return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); -} -device_initcall(rbtx4938_wdt_init); - -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "spi-baseclk")) - return (struct clk *)(txx9_gbus_clock / 2 / 4); - if (!strcmp(id, "imbus_clk")) - return (struct clk *)(txx9_gbus_clock / 2); - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c deleted file mode 100644 index 4d6b4ad..0000000 --- a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include - -#define AT250X0_PAGE_SIZE 8 - -/* register board information for at25 driver */ -int __init spi_eeprom_register(int chipid) -{ - static struct spi_eeprom eeprom = { - .name = "at250x0", - .byte_len = 128, - .page_size = AT250X0_PAGE_SIZE, - .flags = EE_ADDR1, - }; - struct spi_board_info info = { - .modalias = "at25", - .max_speed_hz = 1500000, /* 1.5Mbps */ - .bus_num = 0, - .chip_select = chipid, - .platform_data = &eeprom, - /* Mode 0: High-Active, Sample-Then-Shift */ - }; - - return spi_register_board_info(&info, 1); -} - -/* simple temporary spi driver to provide early access to seeprom. */ - -static struct read_param { - int chipid; - int address; - unsigned char *buf; - int len; -} *read_param; - -static int __init early_seeprom_probe(struct spi_device *spi) -{ - int stat = 0; - u8 cmd[2]; - int len = read_param->len; - char *buf = read_param->buf; - int address = read_param->address; - - dev_info(&spi->dev, "spiclk %u KHz.\n", - (spi->max_speed_hz + 500) / 1000); - if (read_param->chipid != spi->chip_select) - return -ENODEV; - while (len > 0) { - /* spi_write_then_read can only work with small chunk */ - int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE; - cmd[0] = 0x03; /* AT25_READ */ - cmd[1] = address; - stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c); - buf += c; - len -= c; - address += c; - } - return stat; -} - -static struct spi_driver early_seeprom_driver __initdata = { - .driver = { - .name = "at25", - .owner = THIS_MODULE, - }, - .probe = early_seeprom_probe, -}; - -int __init spi_eeprom_read(int chipid, int address, - unsigned char *buf, int len) -{ - int ret; - struct read_param param = { - .chipid = chipid, - .address = address, - .buf = buf, - .len = len - }; - - read_param = ¶m; - ret = spi_register_driver(&early_seeprom_driver); - if (!ret) - spi_unregister_driver(&early_seeprom_driver); - return ret; -} diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig new file mode 100644 index 0000000..98d1034 --- /dev/null +++ b/arch/mips/txx9/Kconfig @@ -0,0 +1,28 @@ +config TOSHIBA_FPCIB0 + bool "FPCIB0 Backplane Support" + depends on TOSHIBA_RBTX4927 + +if TOSHIBA_RBTX4938 + +comment "Multiplex Pin Select" +choice + prompt "PIO[58:61]" + default TOSHIBA_RBTX4938_MPLEX_PIO58_61 + +config TOSHIBA_RBTX4938_MPLEX_PIO58_61 + bool "PIO" +config TOSHIBA_RBTX4938_MPLEX_NAND + bool "NAND" +config TOSHIBA_RBTX4938_MPLEX_ATA + bool "ATA" + +endchoice + +config TX4938_NAND_BOOT + depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND + bool "NAND Boot Support (EXPERIMENTAL)" + help + This is only for Toshiba RBTX4938 reference board, which has NAND IPL. + Select this option if you need to use NAND boot. + +endif diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile new file mode 100644 index 0000000..8cb4a7e --- /dev/null +++ b/arch/mips/txx9/generic/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for common code for TXx9 based systems +# + +obj-$(CONFIG_TOSHIBA_RBTX4927) += mem_tx4927.o irq_tx4927.o +obj-$(CONFIG_TOSHIBA_RBTX4938) += mem_tx4938.o irq_tx4938.o +obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o +obj-$(CONFIG_KGDB) += dbgio.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/generic/dbgio.c b/arch/mips/txx9/generic/dbgio.c new file mode 100644 index 0000000..33b9c67 --- /dev/null +++ b/arch/mips/txx9/generic/dbgio.c @@ -0,0 +1,48 @@ +/* + * linux/arch/mips/tx4938/common/dbgio.c + * + * kgdb interface for gdb + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2005 MontaVista Software 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Support for TX4938 in 2.6 - Hiroshi DOYU + */ + +#include + +extern u8 txx9_sio_kdbg_rd(void); +extern int txx9_sio_kdbg_wr( u8 ch ); + +u8 getDebugChar(void) +{ + return (txx9_sio_kdbg_rd()); +} + +int putDebugChar(u8 byte) +{ + return (txx9_sio_kdbg_wr(byte)); +} + diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c new file mode 100644 index 0000000..685ecc2 --- /dev/null +++ b/arch/mips/txx9/generic/irq_tx4927.c @@ -0,0 +1,64 @@ +/* + * Common tx4927 irq handler + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#ifdef CONFIG_TOSHIBA_RBTX4927 +#include +#endif + +void __init tx4927_irq_init(void) +{ + mips_cpu_irq_init(); + txx9_irq_init(TX4927_IRC_REG); + set_irq_chained_handler(TX4927_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; + + if (pending & STATUSF_IP7) /* cpu timer */ + do_IRQ(TX4927_IRQ_CPU_TIMER); + else if (pending & STATUSF_IP2) { /* tx4927 pic */ + int irq = txx9_irq(); +#ifdef CONFIG_TOSHIBA_RBTX4927 + if (irq == TX4927_IRQ_NEST_EXT_ON_PIC) + irq = toshiba_rbtx4927_irq_nested(irq); +#endif + if (unlikely(irq < 0)) { + spurious_interrupt(); + return; + } + do_IRQ(irq); + } else if (pending & STATUSF_IP0) /* user line 0 */ + do_IRQ(TX4927_IRQ_USER0); + else if (pending & STATUSF_IP1) /* user line 1 */ + do_IRQ(TX4927_IRQ_USER1); + else + spurious_interrupt(); +} diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c new file mode 100644 index 0000000..0886d91 --- /dev/null +++ b/arch/mips/txx9/generic/irq_tx4938.c @@ -0,0 +1,48 @@ +/* + * linux/arch/mips/tx4938/common/irq.c + * + * Common tx4938 irq handler + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#include +#include +#include +#include +#include + +void __init +tx4938_irq_init(void) +{ + mips_cpu_irq_init(); + txx9_irq_init(TX4938_IRC_REG); + set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); +} + +int toshiba_rbtx4938_irq_nested(int irq); + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status(); + + if (pending & STATUSF_IP7) + do_IRQ(TX4938_IRQ_CPU_TIMER); + else if (pending & STATUSF_IP2) { + int irq = txx9_irq(); + if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0)) + irq = toshiba_rbtx4938_irq_nested(irq); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); + } else if (pending & STATUSF_IP1) + do_IRQ(TX4938_IRQ_USER1); + else if (pending & STATUSF_IP0) + do_IRQ(TX4938_IRQ_USER0); +} diff --git a/arch/mips/txx9/generic/mem_tx4927.c b/arch/mips/txx9/generic/mem_tx4927.c new file mode 100644 index 0000000..12dfc37 --- /dev/null +++ b/arch/mips/txx9/generic/mem_tx4927.c @@ -0,0 +1,141 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_prom.c + * + * common tx4927 memory interface + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +static unsigned int __init tx4927_process_sdccr(unsigned long addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_bs; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int bs = 0; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int msize = 0; + + val = __raw_readq((void __iomem *)addr); + + /* MVMCP -- need #defs for these bits masks */ + sdccr_ce = ((val & (1 << 10)) >> 10); + sdccr_bs = ((val & (1 << 8)) >> 8); + sdccr_rs = ((val & (3 << 5)) >> 5); + sdccr_cs = ((val & (3 << 2)) >> 2); + sdccr_mw = ((val & (1 << 0)) >> 0); + + if (sdccr_ce) { + switch (sdccr_bs) { + case 0:{ + bs = 2; + break; + } + case 1:{ + bs = 4; + break; + } + } + switch (sdccr_rs) { + case 0:{ + rs = 2048; + break; + } + case 1:{ + rs = 4096; + break; + } + case 2:{ + rs = 8192; + break; + } + case 3:{ + rs = 0; + break; + } + } + switch (sdccr_cs) { + case 0:{ + cs = 256; + break; + } + case 1:{ + cs = 512; + break; + } + case 2:{ + cs = 1024; + break; + } + case 3:{ + cs = 2048; + break; + } + } + switch (sdccr_mw) { + case 0:{ + mw = 8; + break; + } /* 8 bytes = 64 bits */ + case 1:{ + mw = 4; + break; + } /* 4 bytes = 32 bits */ + } + } + + /* bytes per chip MB per chip num chips */ + msize = (((rs * cs * mw) / (1024 * 1024)) * bs); + + return (msize); +} + + +unsigned int __init tx4927_get_mem_size(void) +{ + unsigned int c0; + unsigned int c1; + unsigned int c2; + unsigned int c3; + unsigned int total; + + /* MVMCP -- need #defs for these registers */ + c0 = tx4927_process_sdccr(0xff1f8000); + c1 = tx4927_process_sdccr(0xff1f8008); + c2 = tx4927_process_sdccr(0xff1f8010); + c3 = tx4927_process_sdccr(0xff1f8018); + total = c0 + c1 + c2 + c3; + + return (total); +} diff --git a/arch/mips/txx9/generic/mem_tx4938.c b/arch/mips/txx9/generic/mem_tx4938.c new file mode 100644 index 0000000..20baeae --- /dev/null +++ b/arch/mips/txx9/generic/mem_tx4938.c @@ -0,0 +1,124 @@ +/* + * linux/arch/mips/tx4938/common/prom.c + * + * common tx4938 memory interface + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ + +#include +#include +#include + +static unsigned int __init +tx4938_process_sdccr(u64 * addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int bc = 4; + unsigned int msize = 0; + + val = ____raw_readq((void __iomem *)addr); + + /* MVMCP -- need #defs for these bits masks */ + sdccr_ce = ((val & (1 << 10)) >> 10); + sdccr_rs = ((val & (3 << 5)) >> 5); + sdccr_cs = ((val & (7 << 2)) >> 2); + sdccr_mw = ((val & (1 << 0)) >> 0); + + if (sdccr_ce) { + switch (sdccr_rs) { + case 0:{ + rs = 2048; + break; + } + case 1:{ + rs = 4096; + break; + } + case 2:{ + rs = 8192; + break; + } + default:{ + rs = 0; + break; + } + } + switch (sdccr_cs) { + case 0:{ + cs = 256; + break; + } + case 1:{ + cs = 512; + break; + } + case 2:{ + cs = 1024; + break; + } + case 3:{ + cs = 2048; + break; + } + case 4:{ + cs = 4096; + break; + } + default:{ + cs = 0; + break; + } + } + switch (sdccr_mw) { + case 0:{ + mw = 8; + break; + } /* 8 bytes = 64 bits */ + case 1:{ + mw = 4; + break; + } /* 4 bytes = 32 bits */ + } + } + + /* bytes per chip MB per chip bank count */ + msize = (((rs * cs * mw) / (1024 * 1024)) * (bc)); + + /* MVMCP -- bc hard coded to 4 from table 9.3.1 */ + /* boad supports bc=2 but no way to detect */ + + return (msize); +} + +unsigned int __init +tx4938_get_mem_size(void) +{ + unsigned int c0; + unsigned int c1; + unsigned int c2; + unsigned int c3; + unsigned int total; + + /* MVMCP -- need #defs for these registers */ + c0 = tx4938_process_sdccr((u64 *) 0xff1f8000); + c1 = tx4938_process_sdccr((u64 *) 0xff1f8008); + c2 = tx4938_process_sdccr((u64 *) 0xff1f8010); + c3 = tx4938_process_sdccr((u64 *) 0xff1f8018); + total = c0 + c1 + c2 + c3; + + return (total); +} diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c new file mode 100644 index 0000000..69e4874 --- /dev/null +++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c @@ -0,0 +1,172 @@ +/* + * Interface for smsc fdc48m81x Super IO chip + * + * Author: MontaVista Software, Inc. source@mvista.com + * + * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright 2004 (c) MontaVista Software, Inc. + */ +#include +#include +#include +#include + +#define DEBUG + +/* Common Registers */ +#define SMSC_FDC37M81X_CONFIG_INDEX 0x00 +#define SMSC_FDC37M81X_CONFIG_DATA 0x01 +#define SMSC_FDC37M81X_CONF 0x02 +#define SMSC_FDC37M81X_INDEX 0x03 +#define SMSC_FDC37M81X_DNUM 0x07 +#define SMSC_FDC37M81X_DID 0x20 +#define SMSC_FDC37M81X_DREV 0x21 +#define SMSC_FDC37M81X_PCNT 0x22 +#define SMSC_FDC37M81X_PMGT 0x23 +#define SMSC_FDC37M81X_OSC 0x24 +#define SMSC_FDC37M81X_CONFPA0 0x26 +#define SMSC_FDC37M81X_CONFPA1 0x27 +#define SMSC_FDC37M81X_TEST4 0x2B +#define SMSC_FDC37M81X_TEST5 0x2C +#define SMSC_FDC37M81X_TEST1 0x2D +#define SMSC_FDC37M81X_TEST2 0x2E +#define SMSC_FDC37M81X_TEST3 0x2F + +/* Logical device numbers */ +#define SMSC_FDC37M81X_FDD 0x00 +#define SMSC_FDC37M81X_SERIAL1 0x04 +#define SMSC_FDC37M81X_SERIAL2 0x05 +#define SMSC_FDC37M81X_KBD 0x07 + +/* Logical device Config Registers */ +#define SMSC_FDC37M81X_ACTIVE 0x30 +#define SMSC_FDC37M81X_BASEADDR0 0x60 +#define SMSC_FDC37M81X_BASEADDR1 0x61 +#define SMSC_FDC37M81X_INT 0x70 +#define SMSC_FDC37M81X_INT2 0x72 +#define SMSC_FDC37M81X_MODE 0xF0 + +/* Chip Config Values */ +#define SMSC_FDC37M81X_CONFIG_ENTER 0x55 +#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa +#define SMSC_FDC37M81X_CHIP_ID 0x4d + +static unsigned long g_smsc_fdc37m81x_base = 0; + +static inline unsigned char smsc_fdc37m81x_rd(unsigned char index) +{ + outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); + + return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); +} + +static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data) +{ + outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); + outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); +} + +void smsc_fdc37m81x_config_beg(void) +{ + if (g_smsc_fdc37m81x_base) { + outb(SMSC_FDC37M81X_CONFIG_ENTER, + g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); + } +} + +void smsc_fdc37m81x_config_end(void) +{ + if (g_smsc_fdc37m81x_base) + outb(SMSC_FDC37M81X_CONFIG_EXIT, + g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); +} + +u8 smsc_fdc37m81x_config_get(u8 reg) +{ + u8 val = 0; + + if (g_smsc_fdc37m81x_base) + val = smsc_fdc37m81x_rd(reg); + + return val; +} + +void smsc_fdc37m81x_config_set(u8 reg, u8 val) +{ + if (g_smsc_fdc37m81x_base) + smsc_dc37m81x_wr(reg, val); +} + +unsigned long __init smsc_fdc37m81x_init(unsigned long port) +{ + const int field = sizeof(unsigned long) * 2; + u8 chip_id; + + if (g_smsc_fdc37m81x_base) + printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n", + field, g_smsc_fdc37m81x_base); + + g_smsc_fdc37m81x_base = port; + + smsc_fdc37m81x_config_beg(); + + chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); + if (chip_id == SMSC_FDC37M81X_CHIP_ID) + smsc_fdc37m81x_config_end(); + else { + printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n", + chip_id); + g_smsc_fdc37m81x_base = 0; + } + + return g_smsc_fdc37m81x_base; +} + +#ifdef DEBUG +void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg) +{ + printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg, + smsc_fdc37m81x_rd(reg)); +} + +void smsc_fdc37m81x_config_dump(void) +{ + u8 orig; + char *fname = "smsc_fdc37m81x_config_dump()"; + + smsc_fdc37m81x_config_beg(); + + orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); + + printk("%s: common\n", fname); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_DNUM); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_DID); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_DREV); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_PCNT); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_PMGT); + + printk("%s: keyboard\n", fname); + smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_ACTIVE); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_INT); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_INT2); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_LDCR_F0); + + smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); + + smsc_fdc37m81x_config_end(); +} +#endif diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile new file mode 100644 index 0000000..5f83ea3 --- /dev/null +++ b/arch/mips/txx9/jmr3927/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for TOSHIBA JMR-TX3927 board +# + +obj-y += prom.o init.o irq.o setup.o +obj-$(CONFIG_KGDB) += kgdb_io.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/jmr3927/init.c b/arch/mips/txx9/jmr3927/init.c new file mode 100644 index 0000000..1bbb534 --- /dev/null +++ b/arch/mips/txx9/jmr3927/init.c @@ -0,0 +1,57 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * arch/mips/jmr3927/common/init.c + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include + +extern void __init prom_init_cmdline(void); + +const char *get_system_type(void) +{ + return "Toshiba" +#ifdef CONFIG_TOSHIBA_JMR3927 + " JMR_TX3927" +#endif + ; +} + +extern void puts(const char *cp); + +void __init prom_init(void) +{ +#ifdef CONFIG_TOSHIBA_JMR3927 + /* CCFG */ + if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) + puts("Warning: TX3927 TLB off\n"); +#endif + + prom_init_cmdline(); + add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); +} diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c new file mode 100644 index 0000000..85e1daf --- /dev/null +++ b/arch/mips/txx9/jmr3927/irq.c @@ -0,0 +1,174 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#if JMR3927_IRQ_END > NR_IRQS +#error JMR3927_IRQ_END > NR_IRQS +#endif + +static unsigned char irc_level[TX3927_NUM_IR] = { + 5, 5, 5, 5, 5, 5, /* INT[5:0] */ + 7, 7, /* SIO */ + 5, 5, 5, 0, 0, /* DMA, PIO, PCI */ + 6, 6, 6 /* TMR */ +}; + +/* + * CP0_STATUS is a thread's resource (saved/restored on context switch). + * So disable_irq/enable_irq MUST handle IOC/IRC registers. + */ +static void mask_irq_ioc(unsigned int irq) +{ + /* 0: mask */ + unsigned int irq_nr = irq - JMR3927_IRQ_IOC; + unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); + unsigned int bit = 1 << irq_nr; + jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); + /* flush write buffer */ + (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); +} +static void unmask_irq_ioc(unsigned int irq) +{ + /* 0: mask */ + unsigned int irq_nr = irq - JMR3927_IRQ_IOC; + unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); + unsigned int bit = 1 << irq_nr; + jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); + /* flush write buffer */ + (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned long cp0_cause = read_c0_cause(); + int irq; + + if ((cp0_cause & CAUSEF_IP7) == 0) + return; + irq = (cp0_cause >> CAUSEB_IP2) & 0x0f; + + do_IRQ(irq + JMR3927_IRQ_IRC); +} + +static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id) +{ + unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); + int i; + + for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) { + if (istat & (1 << i)) { + irq = JMR3927_IRQ_IOC + i; + do_IRQ(irq); + } + } + return IRQ_HANDLED; +} + +static struct irqaction ioc_action = { + .handler = jmr3927_ioc_interrupt, + .mask = CPU_MASK_NONE, + .name = "IOC", +}; + +static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) +{ + printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); + printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n", + tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); + + return IRQ_HANDLED; +} +static struct irqaction pcierr_action = { + .handler = jmr3927_pcierr_interrupt, + .mask = CPU_MASK_NONE, + .name = "PCI error", +}; + +static void __init jmr3927_irq_init(void); + +void __init arch_init_irq(void) +{ + /* Now, interrupt control disabled, */ + /* all IRC interrupts are masked, */ + /* all IRC interrupt mode are Low Active. */ + + /* mask all IOC interrupts */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR); + /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */ + jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR); + + /* clear PCI Soft interrupts */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR); + /* clear PCI Reset interrupts */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + + jmr3927_irq_init(); + + /* setup IOC interrupt 1 (PCI, MODEM) */ + setup_irq(JMR3927_IRQ_IOCINT, &ioc_action); + +#ifdef CONFIG_PCI + setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action); +#endif + + /* enable all CPU interrupt bits. */ + set_c0_status(ST0_IM); /* IE bit is still 0. */ +} + +static struct irq_chip jmr3927_irq_ioc = { + .name = "jmr3927_ioc", + .ack = mask_irq_ioc, + .mask = mask_irq_ioc, + .mask_ack = mask_irq_ioc, + .unmask = unmask_irq_ioc, +}; + +static void __init jmr3927_irq_init(void) +{ + u32 i; + + txx9_irq_init(TX3927_IRC_REG); + for (i = 0; i < TXx9_MAX_IR; i++) + txx9_irq_set_pri(i, irc_level[i]); + for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++) + set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq); +} diff --git a/arch/mips/txx9/jmr3927/kgdb_io.c b/arch/mips/txx9/jmr3927/kgdb_io.c new file mode 100644 index 0000000..5bd757e --- /dev/null +++ b/arch/mips/txx9/jmr3927/kgdb_io.c @@ -0,0 +1,105 @@ +/* + * BRIEF MODULE DESCRIPTION + * Low level uart routines to directly access a TX[34]927 SIO. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com or source@mvista.com + * + * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#define TIMEOUT 0xffffff + +static int remoteDebugInitialized = 0; +static void debugInit(int baud); + +int putDebugChar(unsigned char c) +{ + int i = 0; + + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(38400); + } + + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS)); + tx3927_sioptr(0)->tfifo = c; + + return 1; +} + +unsigned char getDebugChar(void) +{ + int i = 0; + int dicr; + char c; + + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(38400); + } + + /* diable RX int. */ + dicr = tx3927_sioptr(0)->dicr; + tx3927_sioptr(0)->dicr = 0; + + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID) + ; + c = tx3927_sioptr(0)->rfifo; + + /* clear RX int. status */ + tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS; + /* enable RX int. */ + tx3927_sioptr(0)->dicr = dicr; + + return c; +} + +static void debugInit(int baud) +{ + tx3927_sioptr(0)->lcr = 0x020; + tx3927_sioptr(0)->dicr = 0; + tx3927_sioptr(0)->disr = 0x4100; + tx3927_sioptr(0)->cisr = 0x014; + tx3927_sioptr(0)->fcr = 0; + tx3927_sioptr(0)->flcr = 0x02; + tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) | + TXx927_SIBGR_BCLK_T0; +} diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c new file mode 100644 index 0000000..8bc1049 --- /dev/null +++ b/arch/mips/txx9/jmr3927/prom.c @@ -0,0 +1,98 @@ +/* + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, assuming a version of + * pmon is the boot code. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Based on arch/mips/au1000/common/prom.c + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include + +#include +#include + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + int prom_argc = fw_arg0; + char **prom_argv = (char **) fw_arg1; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +void __init prom_free_prom_memory(void) +{ +} + +#define TIMEOUT 0xffffff + +void +prom_putchar(char c) +{ + int i = 0; + + do { + i++; + if (i>TIMEOUT) + break; + } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); + tx3927_sioptr(1)->tfifo = c; + return; +} + +void +puts(const char *cp) +{ + while (*cp) + prom_putchar(*cp++); + prom_putchar('\r'); + prom_putchar('\n'); +} diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c new file mode 100644 index 0000000..41e0f3b --- /dev/null +++ b/arch/mips/txx9/jmr3927/setup.c @@ -0,0 +1,445 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TXX9 +#include +#endif + +#include +#include +#include +#include +#include + +extern void puts(const char *cp); + +/* don't enable - see errata */ +static int jmr3927_ccfg_toeon; + +static inline void do_reset(void) +{ +#if 1 /* Resetting PCI bus */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR); + (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */ + mdelay(1); + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); +#endif + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR); +} + +static void jmr3927_machine_restart(char *command) +{ + local_irq_disable(); + puts("Rebooting..."); + do_reset(); +} + +static void jmr3927_machine_halt(void) +{ + puts("JMR-TX3927 halted.\n"); + while (1); +} + +static void jmr3927_machine_power_off(void) +{ + puts("JMR-TX3927 halted. Please turn off the power.\n"); + while (1); +} + +void __init plat_time_init(void) +{ + txx9_clockevent_init(TX3927_TMR_REG(0), + TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0), + JMR3927_IMCLK); + txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK); +} + +#define DO_WRITE_THROUGH +#define DO_ENABLE_CACHE + +extern char * __init prom_getcmdline(void); +static void jmr3927_board_init(void); +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void __init plat_mem_setup(void) +{ + char *argptr; + + set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO); + + _machine_restart = jmr3927_machine_restart; + _machine_halt = jmr3927_machine_halt; + pm_power_off = jmr3927_machine_power_off; + + /* + * IO/MEM resources. + */ + ioport_resource.start = pci_io_resource.start; + ioport_resource.end = pci_io_resource.end; + iomem_resource.start = 0; + iomem_resource.end = 0xffffffff; + + /* Reboot on panic */ + panic_timeout = 180; + + /* cache setup */ + { + unsigned int conf; +#ifdef DO_ENABLE_CACHE + int mips_ic_disable = 0, mips_dc_disable = 0; +#else + int mips_ic_disable = 1, mips_dc_disable = 1; +#endif +#ifdef DO_WRITE_THROUGH + int mips_config_cwfon = 0; + int mips_config_wbon = 0; +#else + int mips_config_cwfon = 1; + int mips_config_wbon = 1; +#endif + + conf = read_c0_conf(); + conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON); + conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; + conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; + conf |= mips_config_wbon ? TX39_CONF_WBON : 0; + conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; + + write_c0_conf(conf); + write_c0_cache(0); + } + + /* initialize board */ + jmr3927_board_init(); + + argptr = prom_getcmdline(); + + if ((argptr = strstr(argptr, "toeon")) != NULL) + jmr3927_ccfg_toeon = 1; + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "ip=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " ip=bootp"); + } + +#ifdef CONFIG_SERIAL_TXX9 + { + extern int early_serial_txx9_setup(struct uart_port *port); + int i; + struct uart_port req; + for(i = 0; i < 2; i++) { + memset(&req, 0, sizeof(req)); + req.line = i; + req.iotype = UPIO_MEM; + req.membase = (unsigned char __iomem *)TX3927_SIO_REG(i); + req.mapbase = TX3927_SIO_REG(i); + req.irq = i == 0 ? + JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1; + if (i == 0) + req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; + req.uartclk = JMR3927_IMCLK; + early_serial_txx9_setup(&req); + } + } +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS1,115200"); + } +#endif +#endif +} + +static void tx3927_setup(void); + +static void __init jmr3927_board_init(void) +{ + tx3927_setup(); + + /* SIO0 DTR on */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); + + jmr3927_led_set(0); + + printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", + jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, + jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK, + jmr3927_dipsw1(), jmr3927_dipsw2(), + jmr3927_dipsw3(), jmr3927_dipsw4()); +} + +static void __init tx3927_setup(void) +{ + int i; +#ifdef CONFIG_PCI + unsigned long mips_pci_io_base = JMR3927_PCIIO; + unsigned long mips_pci_io_size = JMR3927_PCIIO_SIZE; + unsigned long mips_pci_mem_base = JMR3927_PCIMEM; + unsigned long mips_pci_mem_size = JMR3927_PCIMEM_SIZE; + /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ + unsigned long mips_pci_io_pciaddr = 0; +#endif + + /* SDRAMC are configured by PROM */ + + /* ROMC */ + tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048; + tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8; + tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698; + tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218; + + /* CCFG */ + /* enable Timeout BusError */ + if (jmr3927_ccfg_toeon) + tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE; + + /* clear BusErrorOnWrite flag */ + tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW; + /* Disable PCI snoop */ + tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP; + /* do reset on watchdog */ + tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR; + +#ifdef DO_WRITE_THROUGH + /* Enable PCI SNOOP - with write through only */ + tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP; +#endif + + /* Pin selection */ + tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL; + tx3927_ccfgptr->pcfg |= + TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL | + (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1)); + + printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n", + tx3927_ccfgptr->crir, + tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg); + + /* TMR */ + for (i = 0; i < TX3927_NR_TMR; i++) + txx9_tmr_init(TX3927_TMR_REG(i)); + + /* DMA */ + tx3927_dmaptr->mcr = 0; + for (i = 0; i < ARRAY_SIZE(tx3927_dmaptr->ch); i++) { + /* reset channel */ + tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST; + tx3927_dmaptr->ch[i].ccr = 0; + } + /* enable DMA */ +#ifdef __BIG_ENDIAN + tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN; +#else + tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE; +#endif + +#ifdef CONFIG_PCI + /* PCIC */ + printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:", + tx3927_pcicptr->did, tx3927_pcicptr->vid, + tx3927_pcicptr->rid); + if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) { + printk("External\n"); + /* XXX */ + } else { + printk("Internal\n"); + + /* Reset PCI Bus */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, + JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + + + /* Disable External PCI Config. Access */ + tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; +#ifdef __BIG_ENDIAN + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | + TX3927_PCIC_LBC_TIBSE | + TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; +#endif + /* LB->PCI mappings */ + tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1); + tx3927_pcicptr->ilbioma = mips_pci_io_base; + tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr; + tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1); + tx3927_pcicptr->ilbmma = mips_pci_mem_base; + tx3927_pcicptr->ipbmma = mips_pci_mem_base; + /* PCI->LB mappings */ + tx3927_pcicptr->iobas = 0xffffffff; + tx3927_pcicptr->ioba = 0; + tx3927_pcicptr->tlbioma = 0; + tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1); + tx3927_pcicptr->mba = 0; + tx3927_pcicptr->tlbmma = 0; + /* Enable Direct mapping Address Space Decoder */ + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; + + /* Clear All Local Bus Status */ + tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; + /* Enable All Local Bus Interrupts */ + tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; + /* Clear All PCI Status Error */ + tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; + /* Enable All PCI Status Error Interrupts */ + tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; + + /* PCIC Int => IRC IRQ10 */ + tx3927_pcicptr->il = TX3927_IR_PCI; + /* Target Control (per errata) */ + tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; + + /* Enable Bus Arbiter */ + tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; + + tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_IO | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + } +#endif /* CONFIG_PCI */ + + /* PIO */ + /* PIO[15:12] connected to LEDs */ + __raw_writel(0x0000f000, &tx3927_pioptr->dir); + __raw_writel(0, &tx3927_pioptr->maskcpu); + __raw_writel(0, &tx3927_pioptr->maskext); + txx9_gpio_init(TX3927_PIO_REG, 0, 16); + gpio_request(11, "dipsw1"); + gpio_request(10, "dipsw2"); + { + unsigned int conf; + + conf = read_c0_conf(); + if (!(conf & TX39_CONF_ICE)) + printk("TX3927 I-Cache disabled.\n"); + if (!(conf & TX39_CONF_DCE)) + printk("TX3927 D-Cache disabled.\n"); + else if (!(conf & TX39_CONF_WBON)) + printk("TX3927 D-Cache WriteThrough.\n"); + else if (!(conf & TX39_CONF_CWFON)) + printk("TX3927 D-Cache WriteBack.\n"); + else + printk("TX3927 D-Cache WriteBack (CWF) .\n"); + } +} + +/* This trick makes rtc-ds1742 driver usable as is. */ +unsigned long __swizzle_addr_b(unsigned long port) +{ + if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR) + return port; + port = (port & 0xffff0000) | (port & 0x7fff << 1); +#ifdef __BIG_ENDIAN + return port; +#else + return port | 1; +#endif +} +EXPORT_SYMBOL(__swizzle_addr_b); + +static int __init jmr3927_rtc_init(void) +{ + static struct resource __initdata res = { + .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE, + .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev; + dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} +device_initcall(jmr3927_rtc_init); + +/* Watchdog support */ + +static int __init txx9_wdt_init(unsigned long base) +{ + struct resource res = { + .start = base, + .end = base + 0x100 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev = + platform_device_register_simple("txx9wdt", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} + +static int __init jmr3927_wdt_init(void) +{ + return txx9_wdt_init(TX3927_TMR_REG(2)); +} +device_initcall(jmr3927_wdt_init); + +/* Minimum CLK support */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "imbus_clk")) + return (struct clk *)JMR3927_IMCLK; + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile new file mode 100644 index 0000000..f3e1f59 --- /dev/null +++ b/arch/mips/txx9/rbtx4927/Makefile @@ -0,0 +1,3 @@ +obj-y += prom.o setup.o irq.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c new file mode 100644 index 0000000..936e50e --- /dev/null +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -0,0 +1,214 @@ +/* + * Toshiba RBTX4927 specific interrupt handlers + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* +IRQ Device +00 RBTX4927-ISA/00 +01 RBTX4927-ISA/01 PS2/Keyboard +02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) +03 RBTX4927-ISA/03 +04 RBTX4927-ISA/04 +05 RBTX4927-ISA/05 +06 RBTX4927-ISA/06 +07 RBTX4927-ISA/07 +08 RBTX4927-ISA/08 +09 RBTX4927-ISA/09 +10 RBTX4927-ISA/10 +11 RBTX4927-ISA/11 +12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) +13 RBTX4927-ISA/13 +14 RBTX4927-ISA/14 IDE +15 RBTX4927-ISA/15 + +16 TX4927-CP0/00 Software 0 +17 TX4927-CP0/01 Software 1 +18 TX4927-CP0/02 Cascade TX4927-CP0 +19 TX4927-CP0/03 Multiplexed -- do not use +20 TX4927-CP0/04 Multiplexed -- do not use +21 TX4927-CP0/05 Multiplexed -- do not use +22 TX4927-CP0/06 Multiplexed -- do not use +23 TX4927-CP0/07 CPU TIMER + +24 TX4927-PIC/00 +25 TX4927-PIC/01 +26 TX4927-PIC/02 +27 TX4927-PIC/03 Cascade RBTX4927-IOC +28 TX4927-PIC/04 +29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet +30 TX4927-PIC/06 +31 TX4927-PIC/07 +32 TX4927-PIC/08 TX4927 SerialIO Channel 0 +33 TX4927-PIC/09 TX4927 SerialIO Channel 1 +34 TX4927-PIC/10 +35 TX4927-PIC/11 +36 TX4927-PIC/12 +37 TX4927-PIC/13 +38 TX4927-PIC/14 +39 TX4927-PIC/15 +40 TX4927-PIC/16 TX4927 PCI PCI-C +41 TX4927-PIC/17 +42 TX4927-PIC/18 +43 TX4927-PIC/19 +44 TX4927-PIC/20 +45 TX4927-PIC/21 +46 TX4927-PIC/22 TX4927 PCI PCI-ERR +47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) +48 TX4927-PIC/24 +49 TX4927-PIC/25 +50 TX4927-PIC/26 +51 TX4927-PIC/27 +52 TX4927-PIC/28 +53 TX4927-PIC/29 +54 TX4927-PIC/30 +55 TX4927-PIC/31 + +56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] +57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] +58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] +59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] +60 RBTX4927-IOC/04 +61 RBTX4927-IOC/05 +62 RBTX4927-IOC/06 +63 RBTX4927-IOC/07 + +NOTES: +SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 +SouthBridge/ISA/pin=0 no pci irq used by this device +SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 +SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 +SouthBridge/PMC/pin=0 no pci irq used by this device +SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 +SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) +JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6 +*/ + +#include +#include +#include +#include +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#endif +#include + +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 + +#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ +#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ + +#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) + +extern int tx4927_using_backplane; + +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); + +#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" +static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { + .name = TOSHIBA_RBTX4927_IOC_NAME, + .ack = toshiba_rbtx4927_irq_ioc_disable, + .mask = toshiba_rbtx4927_irq_ioc_disable, + .mask_ack = toshiba_rbtx4927_irq_ioc_disable, + .unmask = toshiba_rbtx4927_irq_ioc_enable, +}; +#define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL +#define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL + +int toshiba_rbtx4927_irq_nested(int sw_irq) +{ + u8 level3; + + level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + if (level3) { + sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1; +#ifdef CONFIG_TOSHIBA_FPCIB0 + if (sw_irq == TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC && + tx4927_using_backplane) { + int irq = i8259_irq(); + if (irq >= 0) + sw_irq = irq; + } +#endif + } + return (sw_irq); +} + +static struct irqaction toshiba_rbtx4927_irq_ioc_action = { + .handler = no_action, + .flags = IRQF_SHARED, + .mask = CPU_MASK_NONE, + .name = TOSHIBA_RBTX4927_IOC_NAME +}; + +static void __init toshiba_rbtx4927_irq_ioc_init(void) +{ + int i; + + for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) + set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, + handle_level_irq); + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, + &toshiba_rbtx4927_irq_ioc_action); +} + +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +{ + unsigned char v; + + v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); +} + +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +{ + unsigned char v; + + v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); + mmiowb(); +} + +void __init arch_init_irq(void) +{ + extern void tx4927_irq_init(void); + + tx4927_irq_init(); + toshiba_rbtx4927_irq_ioc_init(); +#ifdef CONFIG_TOSHIBA_FPCIB0 + if (tx4927_using_backplane) + init_i8259_irqs(); +#endif + /* Onboard 10M Ether: High Active */ + set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); +} diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c new file mode 100644 index 0000000..0020bbe --- /dev/null +++ b/arch/mips/txx9/rbtx4927/prom.c @@ -0,0 +1,91 @@ +/* + * rbtx4927 specific prom routines + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 2004 MontaVista Software Inc. + * Author: Manish Lachwani, mlachwani@mvista.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +void __init prom_init_cmdline(void) +{ + int argc = (int) fw_arg0; + char **argv = (char **) fw_arg1; + int i; /* Always ignore the "-c" at argv[0] */ + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) { + *arcs_cmdline = '\0'; + } + + for (i = 1; i < argc; i++) { + if (i != 1) { + strcat(arcs_cmdline, " "); + } + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(void) +{ + extern int tx4927_get_mem_size(void); + extern char* toshiba_name; + int msize; + + prom_init_cmdline(); + + if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) { + mips_machtype = MACH_TOSHIBA_RBTX4927; + toshiba_name = "TX4927"; + } else { + mips_machtype = MACH_TOSHIBA_RBTX4937; + toshiba_name = "TX4937"; + } + + msize = tx4927_get_mem_size(); + add_memory_region(0, msize << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return "Toshiba RBTX4927/RBTX4937"; +} + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c new file mode 100644 index 0000000..df1b6e9 --- /dev/null +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -0,0 +1,703 @@ +/* + * Toshiba rbtx4927 specific setup + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2002 MontaVista Software Inc. + * Author: Michael Pruznick, michael_pruznick@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Copyright (C) 2004 MontaVista Software Inc. + * Author: Manish Lachwani, mlachwani@mvista.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#endif +#include +#ifdef CONFIG_SERIAL_TXX9 +#include +#endif + +/* These functions are used for rebooting or halting the machine*/ +extern void toshiba_rbtx4927_restart(char *command); +extern void toshiba_rbtx4927_halt(void); +extern void toshiba_rbtx4927_power_off(void); + +int tx4927_using_backplane = 0; + +extern void toshiba_rbtx4927_irq_setup(void); + +char *prom_getcmdline(void); + +#ifdef CONFIG_PCI +#undef TX4927_SUPPORT_COMMAND_IO +#undef TX4927_SUPPORT_PCI_66 +int tx4927_cpu_clock = 100000000; /* 100MHz */ +unsigned long mips_pci_io_base; +unsigned long mips_pci_io_size; +unsigned long mips_pci_mem_base; +unsigned long mips_pci_mem_size; +/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ +unsigned long mips_pci_io_pciaddr = 0; +unsigned long mips_memory_upper; +static int tx4927_ccfg_toeon = 1; +static int tx4927_pcic_trdyto = 0; /* default: disabled */ +unsigned long tx4927_ce_base[8]; +int tx4927_pci66 = 0; /* 0:auto */ +#endif + +char *toshiba_name = ""; + +#ifdef CONFIG_PCI +extern struct pci_controller tx4927_controller; + +static struct pci_dev *fake_pci_dev(struct pci_controller *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.sysdata = (void *)hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + bus.parent = NULL; + dev.bus = &bus; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +static int early_##rw##_config_##size(struct pci_controller *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, dword, u32) + +static int __init tx4927_pcibios_init(void) +{ + unsigned int id; + u32 pci_devfn; + int devfn_start = 0; + int devfn_stop = 0xff; + int busno = 0; /* One bus on the Toshiba */ + struct pci_controller *hose = &tx4927_controller; + + for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { + early_read_config_dword(hose, busno, busno, pci_devfn, + PCI_VENDOR_ID, &id); + + if (id == 0xffffffff) { + continue; + } + + if (id == 0x94601055) { + u8 v08_64; + u32 v32_b0; + u8 v08_e1; + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, &v08_e1); + + /* serial irq control */ + v08_64 = 0xd0; + + /* serial irq pin */ + v32_b0 |= 0x00010000; + + /* ide irq on isa14 */ + v08_e1 &= 0xf0; + v08_e1 |= 0x0d; + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x64, v08_64); + early_write_config_dword(hose, busno, busno, + pci_devfn, 0xb0, v32_b0); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0xe1, v08_e1); + } + + if (id == 0x91301055) { + u8 v08_04; + u8 v08_09; + u8 v08_41; + u8 v08_43; + u8 v08_5c; + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, &v08_5c); + + /* enable ide master/io */ + v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* enable ide native mode */ + v08_09 |= 0x05; + + /* enable primary ide */ + v08_41 |= 0x80; + + /* enable secondary ide */ + v08_43 |= 0x80; + + /* + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + * + * This line of code is intended to provide the user with a work + * around solution to the anomalies cited in SMSC's anomaly sheet + * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". + * + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + */ + v08_5c |= 0x01; + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x5c, v08_5c); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x04, v08_04); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x09, v08_09); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x41, v08_41); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x43, v08_43); + } + + } + + register_pci_controller(&tx4927_controller); + return 0; +} + +arch_initcall(tx4927_pcibios_init); + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void __init tx4927_pci_setup(void) +{ + static int called = 0; + extern unsigned int tx4927_get_mem_size(void); + + mips_memory_upper = tx4927_get_mem_size() << 20; + mips_memory_upper += KSEG0; + mips_pci_io_base = TX4927_PCIIO; + mips_pci_io_size = TX4927_PCIIO_SIZE; + mips_pci_mem_base = TX4927_PCIMEM; + mips_pci_mem_size = TX4927_PCIMEM_SIZE; + + if (!called) { + printk + ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + toshiba_name, + (unsigned short) (tx4927_pcicptr->pciid >> 16), + (unsigned short) (tx4927_pcicptr->pciid & 0xffff), + (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), + (!(tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB)) ? "External" : + "Internal"); + called = 1; + } + printk("%s PCIC --%s PCICLK:", toshiba_name, + (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + int pciclk = 0; + if (mips_machtype == MACH_TOSHIBA_RBTX4937) + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { + case TX4937_CCFG_PCIDIVMODE_4: + pciclk = tx4927_cpu_clock / 4; + break; + case TX4937_CCFG_PCIDIVMODE_4_5: + pciclk = tx4927_cpu_clock * 2 / 9; + break; + case TX4937_CCFG_PCIDIVMODE_5: + pciclk = tx4927_cpu_clock / 5; + break; + case TX4937_CCFG_PCIDIVMODE_5_5: + pciclk = tx4927_cpu_clock * 2 / 11; + break; + case TX4937_CCFG_PCIDIVMODE_8: + pciclk = tx4927_cpu_clock / 8; + break; + case TX4937_CCFG_PCIDIVMODE_9: + pciclk = tx4927_cpu_clock / 9; + break; + case TX4937_CCFG_PCIDIVMODE_10: + pciclk = tx4927_cpu_clock / 10; + break; + case TX4937_CCFG_PCIDIVMODE_11: + pciclk = tx4927_cpu_clock / 11; + break; + } + + else + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + pciclk = tx4927_cpu_clock * 2 / 5; + break; + case TX4927_CCFG_PCIDIVMODE_3: + pciclk = tx4927_cpu_clock / 3; + break; + case TX4927_CCFG_PCIDIVMODE_5: + pciclk = tx4927_cpu_clock / 5; + break; + case TX4927_CCFG_PCIDIVMODE_6: + pciclk = tx4927_cpu_clock / 6; + break; + } + + printk("Internal(%dMHz)", pciclk / 1000000); + } else + printk("External"); + printk("\n"); + + /* GB->PCI mappings */ + tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; + tx4927_pcicptr->g2piogbase = mips_pci_io_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PIOGBASE_ECHG +#else + TX4927_PCIC_G2PIOGBASE_BSDIS +#endif + ; + + tx4927_pcicptr->g2piopbase = 0; + + tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; + tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PMnGBASE_ECHG +#else + TX4927_PCIC_G2PMnGBASE_BSDIS +#endif + ; + tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; + + tx4927_pcicptr->g2pmmask[1] = 0; + tx4927_pcicptr->g2pmgbase[1] = 0; + tx4927_pcicptr->g2pmpbase[1] = 0; + tx4927_pcicptr->g2pmmask[2] = 0; + tx4927_pcicptr->g2pmgbase[2] = 0; + tx4927_pcicptr->g2pmpbase[2] = 0; + + + /* PCI->GB mappings (I/O 256B) */ + tx4927_pcicptr->p2giopbase = 0; /* 256B */ + + /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ + tx4927_pcicptr->p2gm0plbase = 0; + tx4927_pcicptr->p2gm0pubase = 0; + tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GMnGBASE_TECHG +#else + TX4927_PCIC_P2GMnGBASE_TBSDIS +#endif + ; + + /* PCI->GB mappings (MEM 16MB) -not used */ + tx4927_pcicptr->p2gm1plbase = 0xffffffff; + tx4927_pcicptr->p2gm1pubase = 0xffffffff; + tx4927_pcicptr->p2gmgbase[1] = 0; + + /* PCI->GB mappings (MEM 1MB) -not used */ + tx4927_pcicptr->p2gm2pbase = 0xffffffff; + tx4927_pcicptr->p2gmgbase[2] = 0; + + + /* Enable Initiator Memory 0 Space, I/O Space, Config */ + tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; + tx4927_pcicptr->pciccfg |= + TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | + TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; + + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + tx4927_pcicptr->pcicfg1 = 0; + + if (tx4927_pcic_trdyto >= 0) { + tx4927_pcicptr->g2ptocnt &= ~0xff; + tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); + } + + /* Clear All Local Bus Status */ + tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; + /* Enable All Local Bus Interrupts */ + tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; + /* Clear All Initiator Status */ + tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; + /* Enable All Initiator Interrupts */ + tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; + /* Clear All PCI Status Error */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (TX4927_PCIC_PCISTATUS_ALL << 16); + /* Enable All PCI Status Error Interrupts */ + tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; + + /* PCIC Int => IRC IRQ16 */ + tx4927_pcicptr->pcicfg2 = + (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; + + if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { + /* XXX */ + } else { + /* Reset Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; + /* Enable Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; + } + + tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; +} +#endif /* CONFIG_PCI */ + +static void __noreturn wait_forever(void) +{ + while (1) + if (cpu_wait) + (*cpu_wait)(); +} + +void toshiba_rbtx4927_restart(char *command) +{ + printk(KERN_NOTICE "System Rebooting...\n"); + + /* enable the s/w reset register */ + writeb(RBTX4927_SW_RESET_ENABLE_SET, RBTX4927_SW_RESET_ENABLE); + + /* wait for enable to be seen */ + while ((readb(RBTX4927_SW_RESET_ENABLE) & + RBTX4927_SW_RESET_ENABLE_SET) == 0x00); + + /* do a s/w reset */ + writeb(RBTX4927_SW_RESET_DO_SET, RBTX4927_SW_RESET_DO); + + /* do something passive while waiting for reset */ + local_irq_disable(); + wait_forever(); + /* no return */ +} + +void toshiba_rbtx4927_halt(void) +{ + printk(KERN_NOTICE "System Halted\n"); + local_irq_disable(); + wait_forever(); + /* no return */ +} + +void toshiba_rbtx4927_power_off(void) +{ + toshiba_rbtx4927_halt(); + /* no return */ +} + +void __init plat_mem_setup(void) +{ + int i; + u32 cp0_config; + char *argptr; + + printk("CPU is %s\n", toshiba_name); + + /* f/w leaves this on at startup */ + clear_c0_status(ST0_ERL); + + /* enable caches -- HCP5 does this, pmon does not */ + cp0_config = read_c0_config(); + cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); + write_c0_config(cp0_config); + + set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); + + ioport_resource.end = 0xffffffff; + iomem_resource.end = 0xffffffff; + + _machine_restart = toshiba_rbtx4927_restart; + _machine_halt = toshiba_rbtx4927_halt; + pm_power_off = toshiba_rbtx4927_power_off; + + for (i = 0; i < TX4927_NR_TMR; i++) + txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL); + +#ifdef CONFIG_PCI + + /* PCIC */ + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. + * + * For TX4927: + * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1). + * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) + * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) + * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) + * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) + * i.e. S9[3]: ON (83MHz), OFF (100MHz) + * + * For TX4937: + * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1) + * PCIDIVMODE[10] is 0. + * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8) + * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4) + * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9) + * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5) + * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10) + * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) + * + */ + if (mips_machtype == MACH_TOSHIBA_RBTX4937) + switch ((unsigned long)tx4927_ccfgptr-> + ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { + case TX4937_CCFG_PCIDIVMODE_8: + case TX4937_CCFG_PCIDIVMODE_4: + tx4927_cpu_clock = 266666666; /* 266MHz */ + break; + case TX4937_CCFG_PCIDIVMODE_9: + case TX4937_CCFG_PCIDIVMODE_4_5: + tx4927_cpu_clock = 300000000; /* 300MHz */ + break; + default: + tx4927_cpu_clock = 333333333; /* 333MHz */ + } + else + switch ((unsigned long)tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + tx4927_cpu_clock = 166666666; /* 166MHz */ + break; + default: + tx4927_cpu_clock = 200000000; /* 200MHz */ + } + + /* CCFG */ + /* do reset on watchdog */ + tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR; + /* enable Timeout BusError */ + if (tx4927_ccfg_toeon) + tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; + + tx4927_pci_setup(); + if (tx4927_using_backplane == 1) + printk("backplane board IS installed\n"); + else + printk("No Backplane \n"); + + /* this is on ISA bus behind PCI bus, so need PCI up first */ +#ifdef CONFIG_TOSHIBA_FPCIB0 + if (tx4927_using_backplane) { + smsc_fdc37m81x_init(0x3f0); + smsc_fdc37m81x_config_beg(); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + smsc_fdc37m81x_config_end(); + } +#endif +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_SERIAL_TXX9 + { + extern int early_serial_txx9_setup(struct uart_port *port); + struct uart_port req; + for(i = 0; i < 2; i++) { + memset(&req, 0, sizeof(req)); + req.line = i; + req.iotype = UPIO_MEM; + req.membase = (char *)(0xff1ff300 + i * 0x100); + req.mapbase = 0xff1ff300 + i * 0x100; + req.irq = TX4927_IRQ_PIC_BEG + 8 + i; + req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; + req.uartclk = 50000000; + early_serial_txx9_setup(&req); + } + } +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + argptr = prom_getcmdline(); + if (strstr(argptr, "console=") == NULL) { + strcat(argptr, " console=ttyS0,38400"); + } +#endif +#endif + +#ifdef CONFIG_ROOT_NFS + argptr = prom_getcmdline(); + if (strstr(argptr, "root=") == NULL) { + strcat(argptr, " root=/dev/nfs rw"); + } +#endif + +#ifdef CONFIG_IP_PNP + argptr = prom_getcmdline(); + if (strstr(argptr, "ip=") == NULL) { + strcat(argptr, " ip=any"); + } +#endif +} + +void __init plat_time_init(void) +{ + mips_hpt_frequency = tx4927_cpu_clock / 2; + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) + txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, + TXX9_IRQ_BASE + 17, + 50000000); +} + +static int __init toshiba_rbtx4927_rtc_init(void) +{ + static struct resource __initdata res = { + .start = 0x1c010000, + .end = 0x1c010000 + 0x800 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev = + platform_device_register_simple("rtc-ds1742", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} +device_initcall(toshiba_rbtx4927_rtc_init); + +static int __init rbtx4927_ne_init(void) +{ + static struct resource __initdata res[] = { + { + .start = RBTX4927_RTL_8019_BASE, + .end = RBTX4927_RTL_8019_BASE + 0x20 - 1, + .flags = IORESOURCE_IO, + }, { + .start = RBTX4927_RTL_8019_IRQ, + .flags = IORESOURCE_IRQ, + } + }; + struct platform_device *dev = + platform_device_register_simple("ne", -1, + res, ARRAY_SIZE(res)); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} +device_initcall(rbtx4927_ne_init); + +/* Watchdog support */ + +static int __init txx9_wdt_init(unsigned long base) +{ + struct resource res = { + .start = base, + .end = base + 0x100 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev = + platform_device_register_simple("txx9wdt", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} + +static int __init rbtx4927_wdt_init(void) +{ + return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); +} +device_initcall(rbtx4927_wdt_init); + +/* Minimum CLK support */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "imbus_clk")) + return (struct clk *)50000000; + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile new file mode 100644 index 0000000..9dcc52a --- /dev/null +++ b/arch/mips/txx9/rbtx4938/Makefile @@ -0,0 +1,3 @@ +obj-y += prom.o setup.o irq.o spi_eeprom.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c new file mode 100644 index 0000000..f498482 --- /dev/null +++ b/arch/mips/txx9/rbtx4938/irq.c @@ -0,0 +1,159 @@ +/* + * Toshiba RBTX4938 specific interrupt handlers + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ + +/* +IRQ Device + +16 TX4938-CP0/00 Software 0 +17 TX4938-CP0/01 Software 1 +18 TX4938-CP0/02 Cascade TX4938-CP0 +19 TX4938-CP0/03 Multiplexed -- do not use +20 TX4938-CP0/04 Multiplexed -- do not use +21 TX4938-CP0/05 Multiplexed -- do not use +22 TX4938-CP0/06 Multiplexed -- do not use +23 TX4938-CP0/07 CPU TIMER + +24 TX4938-PIC/00 +25 TX4938-PIC/01 +26 TX4938-PIC/02 Cascade RBTX4938-IOC +27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet +28 TX4938-PIC/04 +29 TX4938-PIC/05 TX4938 ETH1 +30 TX4938-PIC/06 TX4938 ETH0 +31 TX4938-PIC/07 +32 TX4938-PIC/08 TX4938 SIO 0 +33 TX4938-PIC/09 TX4938 SIO 1 +34 TX4938-PIC/10 TX4938 DMA0 +35 TX4938-PIC/11 TX4938 DMA1 +36 TX4938-PIC/12 TX4938 DMA2 +37 TX4938-PIC/13 TX4938 DMA3 +38 TX4938-PIC/14 +39 TX4938-PIC/15 +40 TX4938-PIC/16 TX4938 PCIC +41 TX4938-PIC/17 TX4938 TMR0 +42 TX4938-PIC/18 TX4938 TMR1 +43 TX4938-PIC/19 TX4938 TMR2 +44 TX4938-PIC/20 +45 TX4938-PIC/21 +46 TX4938-PIC/22 TX4938 PCIERR +47 TX4938-PIC/23 +48 TX4938-PIC/24 +49 TX4938-PIC/25 +50 TX4938-PIC/26 +51 TX4938-PIC/27 +52 TX4938-PIC/28 +53 TX4938-PIC/29 +54 TX4938-PIC/30 +55 TX4938-PIC/31 TX4938 SPI + +56 RBTX4938-IOC/00 PCI-D +57 RBTX4938-IOC/01 PCI-C +58 RBTX4938-IOC/02 PCI-B +59 RBTX4938-IOC/03 PCI-A +60 RBTX4938-IOC/04 RTC +61 RBTX4938-IOC/05 ATA +62 RBTX4938-IOC/06 MODEM +63 RBTX4938-IOC/07 SWINT +*/ +#include +#include +#include + +static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); +static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); + +#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" +static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { + .name = TOSHIBA_RBTX4938_IOC_NAME, + .ack = toshiba_rbtx4938_irq_ioc_disable, + .mask = toshiba_rbtx4938_irq_ioc_disable, + .mask_ack = toshiba_rbtx4938_irq_ioc_disable, + .unmask = toshiba_rbtx4938_irq_ioc_enable, +}; + +int +toshiba_rbtx4938_irq_nested(int sw_irq) +{ + u8 level3; + + level3 = readb(rbtx4938_imstat_addr); + if (level3) + /* must use fls so onboard ATA has priority */ + sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1; + + return sw_irq; +} + +static struct irqaction toshiba_rbtx4938_irq_ioc_action = { + .handler = no_action, + .flags = 0, + .mask = CPU_MASK_NONE, + .name = TOSHIBA_RBTX4938_IOC_NAME, +}; + +/**********************************************************************************/ +/* Functions for ioc */ +/**********************************************************************************/ +static void __init +toshiba_rbtx4938_irq_ioc_init(void) +{ + int i; + + for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG; + i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) + set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, + handle_level_irq); + + setup_irq(RBTX4938_IRQ_IOCINT, + &toshiba_rbtx4938_irq_ioc_action); +} + +static void +toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) +{ + unsigned char v; + + v = readb(rbtx4938_imask_addr); + v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); + writeb(v, rbtx4938_imask_addr); + mmiowb(); +} + +static void +toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) +{ + unsigned char v; + + v = readb(rbtx4938_imask_addr); + v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); + writeb(v, rbtx4938_imask_addr); + mmiowb(); +} + +void __init arch_init_irq(void) +{ + extern void tx4938_irq_init(void); + + /* Now, interrupt control disabled, */ + /* all IRC interrupts are masked, */ + /* all IRC interrupt mode are Low Active. */ + + /* mask all IOC interrupts */ + writeb(0, rbtx4938_imask_addr); + + /* clear SoftInt interrupts */ + writeb(0, rbtx4938_softint_addr); + tx4938_irq_init(); + toshiba_rbtx4938_irq_ioc_init(); + /* Onboard 10M Ether: High Active */ + set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); +} diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c new file mode 100644 index 0000000..134fcc2 --- /dev/null +++ b/arch/mips/txx9/rbtx4938/prom.c @@ -0,0 +1,72 @@ +/* + * rbtx4938 specific prom routines + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ + +#include +#include +#include +#include + +#include +#include +#include + +void __init prom_init_cmdline(void) +{ + int argc = (int) fw_arg0; + char **argv = (char **) fw_arg1; + int i; + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) { + *arcs_cmdline = '\0'; + } + + for (i = 1; i < argc; i++) { + if (i != 1) { + strcat(arcs_cmdline, " "); + } + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(void) +{ + extern int tx4938_get_mem_size(void); + int msize; +#ifndef CONFIG_TX4938_NAND_BOOT + prom_init_cmdline(); +#endif + + msize = tx4938_get_mem_size(); + add_memory_region(0, msize << 20, BOOT_MEM_RAM); + + return; +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ + return; +} + +const char *get_system_type(void) +{ + return "Toshiba RBTX4938"; +} + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c new file mode 100644 index 0000000..bbd572c --- /dev/null +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -0,0 +1,1122 @@ +/* + * Setup pointers to hardware-dependent routines. + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_TXX9 +#include +#endif +#include +#include +#include + +extern char * __init prom_getcmdline(void); +static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); + +/* These functions are used for rebooting or halting the machine*/ +extern void rbtx4938_machine_restart(char *command); +extern void rbtx4938_machine_halt(void); +extern void rbtx4938_machine_power_off(void); + +/* clocks */ +unsigned int txx9_master_clock; +unsigned int txx9_cpu_clock; +unsigned int txx9_gbus_clock; + +unsigned long rbtx4938_ce_base[8]; +unsigned long rbtx4938_ce_size[8]; +int txboard_pci66_mode; +static int tx4938_pcic_trdyto; /* default: disabled */ +static int tx4938_pcic_retryto; /* default: disabled */ +static int tx4938_ccfg_toeon = 1; + +struct tx4938_pcic_reg *pcicptrs[4] = { + tx4938_pcicptr /* default setting for TX4938 */ +}; + +static struct { + unsigned long base; + unsigned long size; +} phys_regions[16] __initdata; +static int num_phys_regions __initdata; + +#define PHYS_REGION_MINSIZE 0x10000 + +void rbtx4938_machine_halt(void) +{ + printk(KERN_NOTICE "System Halted\n"); + local_irq_disable(); + + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void rbtx4938_machine_power_off(void) +{ + rbtx4938_machine_halt(); + /* no return */ +} + +void rbtx4938_machine_restart(char *command) +{ + local_irq_disable(); + + printk("Rebooting..."); + writeb(1, rbtx4938_softresetlock_addr); + writeb(1, rbtx4938_sfvol_addr); + writeb(1, rbtx4938_softreset_addr); + while(1) + ; +} + +void __init +txboard_add_phys_region(unsigned long base, unsigned long size) +{ + if (num_phys_regions >= ARRAY_SIZE(phys_regions)) { + printk("phys_region overflow\n"); + return; + } + phys_regions[num_phys_regions].base = base; + phys_regions[num_phys_regions].size = size; + num_phys_regions++; +} +unsigned long __init +txboard_find_free_phys_region(unsigned long begin, unsigned long end, + unsigned long size) +{ + unsigned long base; + int i; + + for (base = begin / size * size; base < end; base += size) { + for (i = 0; i < num_phys_regions; i++) { + if (phys_regions[i].size && + base <= phys_regions[i].base + (phys_regions[i].size - 1) && + base + (size - 1) >= phys_regions[i].base) + break; + } + if (i == num_phys_regions) + return base; + } + return 0; +} +unsigned long __init +txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end, + unsigned long *size) +{ + unsigned long sz, base; + for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) { + base = txboard_find_free_phys_region(begin, end, sz); + if (base) { + *size = sz; + return base; + } + } + return 0; +} +unsigned long __init +txboard_request_phys_region_range(unsigned long begin, unsigned long end, + unsigned long size) +{ + unsigned long base; + base = txboard_find_free_phys_region(begin, end, size); + if (base) + txboard_add_phys_region(base, size); + return base; +} +unsigned long __init +txboard_request_phys_region(unsigned long size) +{ + unsigned long base; + unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ + base = txboard_find_free_phys_region(begin, end, size); + if (base) + txboard_add_phys_region(base, size); + return base; +} +unsigned long __init +txboard_request_phys_region_shrink(unsigned long *size) +{ + unsigned long base; + unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ + base = txboard_find_free_phys_region_shrink(begin, end, size); + if (base) + txboard_add_phys_region(base, *size); + return base; +} + +#ifdef CONFIG_PCI +void __init +tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr, + struct pci_controller *channel, + unsigned long pci_io_base, + int extarb) +{ + int i; + + /* Disable All Initiator Space */ + pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)| + TX4938_PCIC_PCICCFG_G2PMEN(1)| + TX4938_PCIC_PCICCFG_G2PMEN(2)| + TX4938_PCIC_PCICCFG_G2PIOEN); + + /* GB->PCI mappings */ + pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4; + pcicptr->g2piogbase = pci_io_base | +#ifdef __BIG_ENDIAN + TX4938_PCIC_G2PIOGBASE_ECHG +#else + TX4938_PCIC_G2PIOGBASE_BSDIS +#endif + ; + pcicptr->g2piopbase = 0; + for (i = 0; i < 3; i++) { + pcicptr->g2pmmask[i] = 0; + pcicptr->g2pmgbase[i] = 0; + pcicptr->g2pmpbase[i] = 0; + } + if (channel->mem_resource->end) { + pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4; + pcicptr->g2pmgbase[0] = channel->mem_resource->start | +#ifdef __BIG_ENDIAN + TX4938_PCIC_G2PMnGBASE_ECHG +#else + TX4938_PCIC_G2PMnGBASE_BSDIS +#endif + ; + pcicptr->g2pmpbase[0] = channel->mem_resource->start; + } + /* PCI->GB mappings (I/O 256B) */ + pcicptr->p2giopbase = 0; /* 256B */ + pcicptr->p2giogbase = 0; + /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ + pcicptr->p2gm0plbase = 0; + pcicptr->p2gm0pubase = 0; + pcicptr->p2gmgbase[0] = 0 | + TX4938_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4938_PCIC_P2GMnGBASE_TECHG +#else + TX4938_PCIC_P2GMnGBASE_TBSDIS +#endif + ; + /* PCI->GB mappings (MEM 16MB) */ + pcicptr->p2gm1plbase = 0xffffffff; + pcicptr->p2gm1pubase = 0xffffffff; + pcicptr->p2gmgbase[1] = 0; + /* PCI->GB mappings (MEM 1MB) */ + pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */ + pcicptr->p2gmgbase[2] = 0; + + pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK; + /* Enable Initiator Memory Space */ + if (channel->mem_resource->end) + pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0); + /* Enable Initiator I/O Space */ + if (channel->io_resource->end) + pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN; + /* Enable Initiator Config */ + pcicptr->pciccfg |= + TX4938_PCIC_PCICCFG_ICAEN | + TX4938_PCIC_PCICCFG_TCAR; + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + pcicptr->pcicfg1 = 0; + + pcicptr->g2ptocnt &= ~0xffff; + + if (tx4938_pcic_trdyto >= 0) { + pcicptr->g2ptocnt &= ~0xff; + pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff); + } + + if (tx4938_pcic_retryto >= 0) { + pcicptr->g2ptocnt &= ~0xff00; + pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00); + } + + /* Clear All Local Bus Status */ + pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL; + /* Enable All Local Bus Interrupts */ + pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL; + /* Clear All Initiator Status */ + pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL; + /* Enable All Initiator Interrupts */ + pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL; + /* Clear All PCI Status Error */ + pcicptr->pcistatus = + (pcicptr->pcistatus & 0x0000ffff) | + (TX4938_PCIC_PCISTATUS_ALL << 16); + /* Enable All PCI Status Error Interrupts */ + pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL; + + if (!extarb) { + /* Reset Bus Arbiter */ + pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA; + pcicptr->pbabm = 0; + /* Enable Bus Arbiter */ + pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN; + } + + /* PCIC Int => IRC IRQ16 */ + pcicptr->pcicfg2 = + (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC; + + pcicptr->pcistatus = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; +} + +int __init +tx4938_report_pciclk(void) +{ + unsigned long pcode = TX4938_REV_PCODE(); + int pciclk = 0; + printk("TX%lx PCIC --%s PCICLK:", + pcode, + (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : ""); + if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { + + switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_4: + pciclk = txx9_cpu_clock / 4; break; + case TX4938_CCFG_PCIDIVMODE_4_5: + pciclk = txx9_cpu_clock * 2 / 9; break; + case TX4938_CCFG_PCIDIVMODE_5: + pciclk = txx9_cpu_clock / 5; break; + case TX4938_CCFG_PCIDIVMODE_5_5: + pciclk = txx9_cpu_clock * 2 / 11; break; + case TX4938_CCFG_PCIDIVMODE_8: + pciclk = txx9_cpu_clock / 8; break; + case TX4938_CCFG_PCIDIVMODE_9: + pciclk = txx9_cpu_clock / 9; break; + case TX4938_CCFG_PCIDIVMODE_10: + pciclk = txx9_cpu_clock / 10; break; + case TX4938_CCFG_PCIDIVMODE_11: + pciclk = txx9_cpu_clock / 11; break; + } + printk("Internal(%dMHz)", pciclk / 1000000); + } else { + printk("External"); + pciclk = -1; + } + printk("\n"); + return pciclk; +} + +void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr) +{ + pcicptrs[ch] = pcicptr; +} + +struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch) +{ + return pcicptrs[ch]; +} + +static struct pci_dev *fake_pci_dev(struct pci_controller *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.sysdata = bus.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + bus.parent = NULL; + dev.bus = &bus; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +static int early_##rw##_config_##size(struct pci_controller *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, word, u16 *) + +int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus) +{ + u32 pci_devfn; + unsigned short vid; + int devfn_start = 0; + int devfn_stop = 0xff; + int cap66 = -1; + u16 stat; + + printk("PCI: Checking 66MHz capabilities...\n"); + + for (pci_devfn=devfn_start; pci_devfn 0; +} + +int __init +tx4938_pciclk66_setup(void) +{ + int pciclk; + + /* Assert M66EN */ + tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; + /* Double PCICLK (if possible) */ + if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = + tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK; + switch (pcidivmode) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + pcidivmode = TX4938_CCFG_PCIDIVMODE_4; + pciclk = txx9_cpu_clock / 4; + break; + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; + pciclk = txx9_cpu_clock * 2 / 9; + break; + case TX4938_CCFG_PCIDIVMODE_10: + case TX4938_CCFG_PCIDIVMODE_5: + pcidivmode = TX4938_CCFG_PCIDIVMODE_5; + pciclk = txx9_cpu_clock / 5; + break; + case TX4938_CCFG_PCIDIVMODE_11: + case TX4938_CCFG_PCIDIVMODE_5_5: + default: + pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; + pciclk = txx9_cpu_clock * 2 / 11; + break; + } + tx4938_ccfgptr->ccfg = + (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) + | pcidivmode; + printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", + (unsigned long)tx4938_ccfgptr->ccfg); + } else { + pciclk = -1; + } + return pciclk; +} + +extern struct pci_controller tx4938_pci_controller[]; +static int __init tx4938_pcibios_init(void) +{ + unsigned long mem_base[2]; + unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ + unsigned long io_base[2]; + unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ + /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ + int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); + + PCIBIOS_MIN_IO = 0x00001000UL; + + mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); + io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); + + printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + (unsigned short)(tx4938_pcicptr->pciid >> 16), + (unsigned short)(tx4938_pcicptr->pciid & 0xffff), + (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), + extarb ? "External" : "Internal"); + + /* setup PCI area */ + tx4938_pci_controller[0].io_resource->start = io_base[0]; + tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; + tx4938_pci_controller[0].mem_resource->start = mem_base[0]; + tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; + + set_tx4938_pcicptr(0, tx4938_pcicptr); + + register_pci_controller(&tx4938_pci_controller[0]); + + if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { + printk("TX4938_CCFG_PCI66 already configured\n"); + txboard_pci66_mode = -1; /* already configured */ + } + + /* Reset PCI Bus */ + writeb(0, rbtx4938_pcireset_addr); + /* Reset PCIC */ + tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; + if (txboard_pci66_mode > 0) + tx4938_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; + writeb(1, rbtx4938_pcireset_addr); + mmiowb(); + tx4938_report_pcic_status1(tx4938_pcicptr); + + tx4938_report_pciclk(); + tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); + if (txboard_pci66_mode == 0 && + txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { + /* Reset PCI Bus */ + writeb(0, rbtx4938_pcireset_addr); + /* Reset PCIC */ + tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; + tx4938_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; + writeb(1, rbtx4938_pcireset_addr); + mmiowb(); + /* Reinitialize PCIC */ + tx4938_report_pciclk(); + tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); + } + + mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); + io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); + /* Reset PCIC1 */ + tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; + /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ + if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) + tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; + else + tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; + mdelay(10); + /* clear PCIC1 reset */ + tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; + tx4938_report_pcic_status1(tx4938_pcic1ptr); + + printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", + (unsigned short)(tx4938_pcic1ptr->pciid >> 16), + (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), + (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); + printk("%s PCICLK:%dMHz\n", + (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", + txx9_gbus_clock / + ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / + 1000000); + + /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ + tx4938_pci_controller[1].io_resource->start = + io_base[1] - io_base[0]; + tx4938_pci_controller[1].io_resource->end = + io_base[1] - io_base[0] + io_size[1] - 1; + tx4938_pci_controller[1].mem_resource->start = mem_base[1]; + tx4938_pci_controller[1].mem_resource->end = + mem_base[1] + mem_size[1] - 1; + set_tx4938_pcicptr(1, tx4938_pcic1ptr); + + register_pci_controller(&tx4938_pci_controller[1]); + + tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); + + /* map ioport 0 to PCI I/O space address 0 */ + set_io_port_base(KSEG1 + io_base[0]); + + return 0; +} + +arch_initcall(tx4938_pcibios_init); + +#endif /* CONFIG_PCI */ + +/* SPI support */ + +/* chip select for SPI devices */ +#define SEEPROM1_CS 7 /* PIO7 */ +#define SEEPROM2_CS 0 /* IOC */ +#define SEEPROM3_CS 1 /* IOC */ +#define SRTC_CS 2 /* IOC */ + +#ifdef CONFIG_PCI +static int __init rbtx4938_ethaddr_init(void) +{ + unsigned char dat[17]; + unsigned char sum; + int i; + + /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ + if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { + printk(KERN_ERR "seeprom: read error.\n"); + return -ENODEV; + } else { + if (strcmp(dat, "MAC") != 0) + printk(KERN_WARNING "seeprom: bad signature.\n"); + for (i = 0, sum = 0; i < sizeof(dat); i++) + sum += dat[i]; + if (sum) + printk(KERN_WARNING "seeprom: bad checksum.\n"); + } + for (i = 0; i < 2; i++) { + unsigned int id = + TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); + struct platform_device *pdev; + if (!(tx4938_ccfgptr->pcfg & + (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) + continue; + pdev = platform_device_alloc("tc35815-mac", id); + if (!pdev || + platform_device_add_data(pdev, &dat[4 + 6 * i], 6) || + platform_device_add(pdev)) + platform_device_put(pdev); + } + return 0; +} +device_initcall(rbtx4938_ethaddr_init); +#endif /* CONFIG_PCI */ + +static void __init rbtx4938_spi_setup(void) +{ + /* set SPI_SEL */ + tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; +} + +static struct resource rbtx4938_fpga_resource; + +static char pcode_str[8]; +static struct resource tx4938_reg_resource = { + .start = TX4938_REG_BASE, + .end = TX4938_REG_BASE + TX4938_REG_SIZE, + .name = pcode_str, + .flags = IORESOURCE_MEM +}; + +void __init tx4938_board_setup(void) +{ + int i; + unsigned long divmode; + int cpuclk = 0; + unsigned long pcode = TX4938_REV_PCODE(); + + ioport_resource.start = 0x1000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x1000; + iomem_resource.end = 0xffffffff; /* expand to 4GB */ + + sprintf(pcode_str, "TX%lx", pcode); + /* SDRAMC,EBUSC are configured by PROM */ + for (i = 0; i < 8; i++) { + if (!(tx4938_ebuscptr->cr[i] & 0x8)) + continue; /* disabled */ + rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); + txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); + } + + /* clocks */ + if (txx9_master_clock) { + /* calculate gbus_clock and cpu_clock_freq from master_clock */ + divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; + switch (divmode) { + case TX4938_CCFG_DIVMODE_8: + case TX4938_CCFG_DIVMODE_10: + case TX4938_CCFG_DIVMODE_12: + case TX4938_CCFG_DIVMODE_16: + case TX4938_CCFG_DIVMODE_18: + txx9_gbus_clock = txx9_master_clock * 4; break; + default: + txx9_gbus_clock = txx9_master_clock; + } + switch (divmode) { + case TX4938_CCFG_DIVMODE_2: + case TX4938_CCFG_DIVMODE_8: + cpuclk = txx9_gbus_clock * 2; break; + case TX4938_CCFG_DIVMODE_2_5: + case TX4938_CCFG_DIVMODE_10: + cpuclk = txx9_gbus_clock * 5 / 2; break; + case TX4938_CCFG_DIVMODE_3: + case TX4938_CCFG_DIVMODE_12: + cpuclk = txx9_gbus_clock * 3; break; + case TX4938_CCFG_DIVMODE_4: + case TX4938_CCFG_DIVMODE_16: + cpuclk = txx9_gbus_clock * 4; break; + case TX4938_CCFG_DIVMODE_4_5: + case TX4938_CCFG_DIVMODE_18: + cpuclk = txx9_gbus_clock * 9 / 2; break; + } + txx9_cpu_clock = cpuclk; + } else { + if (txx9_cpu_clock == 0) { + txx9_cpu_clock = 300000000; /* 300MHz */ + } + /* calculate gbus_clock and master_clock from cpu_clock_freq */ + cpuclk = txx9_cpu_clock; + divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; + switch (divmode) { + case TX4938_CCFG_DIVMODE_2: + case TX4938_CCFG_DIVMODE_8: + txx9_gbus_clock = cpuclk / 2; break; + case TX4938_CCFG_DIVMODE_2_5: + case TX4938_CCFG_DIVMODE_10: + txx9_gbus_clock = cpuclk * 2 / 5; break; + case TX4938_CCFG_DIVMODE_3: + case TX4938_CCFG_DIVMODE_12: + txx9_gbus_clock = cpuclk / 3; break; + case TX4938_CCFG_DIVMODE_4: + case TX4938_CCFG_DIVMODE_16: + txx9_gbus_clock = cpuclk / 4; break; + case TX4938_CCFG_DIVMODE_4_5: + case TX4938_CCFG_DIVMODE_18: + txx9_gbus_clock = cpuclk * 2 / 9; break; + } + switch (divmode) { + case TX4938_CCFG_DIVMODE_8: + case TX4938_CCFG_DIVMODE_10: + case TX4938_CCFG_DIVMODE_12: + case TX4938_CCFG_DIVMODE_16: + case TX4938_CCFG_DIVMODE_18: + txx9_master_clock = txx9_gbus_clock / 4; break; + default: + txx9_master_clock = txx9_gbus_clock; + } + } + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; + + /* CCFG */ + /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ + tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; + /* do reset on watchdog */ + tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR; + /* clear PCIC1 reset */ + if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) + tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; + + /* enable Timeout BusError */ + if (tx4938_ccfg_toeon) + tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; + + /* DMA selection */ + tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; + + /* Use external clock for external arbiter */ + if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) + tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; + + printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", + pcode_str, + cpuclk / 1000000, txx9_master_clock / 1000000, + (unsigned long)tx4938_ccfgptr->crir, + tx4938_ccfgptr->ccfg, + tx4938_ccfgptr->pcfg); + + printk("%s SDRAMC --", pcode_str); + for (i = 0; i < 4; i++) { + unsigned long long cr = tx4938_sdramcptr->cr[i]; + unsigned long ram_base, ram_size; + if (!((unsigned long)cr & 0x00000400)) + continue; /* disabled */ + ram_base = (unsigned long)(cr >> 49) << 21; + ram_size = ((unsigned long)(cr >> 33) + 1) << 21; + if (ram_base >= 0x20000000) + continue; /* high memory (ignore) */ + printk(" CR%d:%016Lx", i, cr); + txboard_add_phys_region(ram_base, ram_size); + } + printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); + + /* SRAM */ + if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { + unsigned int size = 0x800; + unsigned long base = + (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); + txboard_add_phys_region(base, size); + } + + /* TMR */ + for (i = 0; i < TX4938_NR_TMR; i++) + txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); + + /* enable DMA */ + for (i = 0; i < 2; i++) + ____raw_writeq(TX4938_DMA_MCR_MSTEN, + (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); + + /* PIO */ + __raw_writel(0, &tx4938_pioptr->maskcpu); + __raw_writel(0, &tx4938_pioptr->maskext); + + /* TX4938 internal registers */ + if (request_resource(&iomem_resource, &tx4938_reg_resource)) + printk("request resource for internal registers failed\n"); +} + +#ifdef CONFIG_PCI +static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr) +{ + unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16); + unsigned long g2pstatus = pcicptr->g2pstatus; + unsigned long pcicstatus = pcicptr->pcicstatus; + static struct { + unsigned long flag; + const char *str; + } pcistat_tbl[] = { + { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, + { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, + { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, + { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, + { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, + { PCI_STATUS_PARITY, "MasterParityError" }, + }, g2pstat_tbl[] = { + { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" }, + { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" }, + }, pcicstat_tbl[] = { + { TX4938_PCIC_PCICSTATUS_PME, "PME" }, + { TX4938_PCIC_PCICSTATUS_TLB, "TLB" }, + { TX4938_PCIC_PCICSTATUS_NIB, "NIB" }, + { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" }, + { TX4938_PCIC_PCICSTATUS_PERR, "PERR" }, + { TX4938_PCIC_PCICSTATUS_SERR, "SERR" }, + { TX4938_PCIC_PCICSTATUS_GBE, "GBE" }, + { TX4938_PCIC_PCICSTATUS_IWB, "IWB" }, + }; + int i; + + printk("pcistat:%04x(", pcistatus); + for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++) + if (pcistatus & pcistat_tbl[i].flag) + printk("%s ", pcistat_tbl[i].str); + printk("), g2pstatus:%08lx(", g2pstatus); + for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) + if (g2pstatus & g2pstat_tbl[i].flag) + printk("%s ", g2pstat_tbl[i].str); + printk("), pcicstatus:%08lx(", pcicstatus); + for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) + if (pcicstatus & pcicstat_tbl[i].flag) + printk("%s ", pcicstat_tbl[i].str); + printk(")\n"); +} + +void tx4938_report_pcic_status(void) +{ + int i; + struct tx4938_pcic_reg *pcicptr; + for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++) + tx4938_report_pcic_status1(pcicptr); +} + +#endif /* CONFIG_PCI */ + +void __init plat_time_init(void) +{ + mips_hpt_frequency = txx9_cpu_clock / 2; + if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS) + txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, + TXX9_IRQ_BASE + TX4938_IR_TMR(0), + txx9_gbus_clock / 2); +} + +void __init plat_mem_setup(void) +{ + unsigned long long pcfg; + char *argptr; + + iomem_resource.end = 0xffffffff; /* 4GB */ + + if (txx9_master_clock == 0) + txx9_master_clock = 25000000; /* 25MHz */ + tx4938_board_setup(); +#ifndef CONFIG_PCI + set_io_port_base(RBTX4938_ETHER_BASE); +#endif + +#ifdef CONFIG_SERIAL_TXX9 + { + extern int early_serial_txx9_setup(struct uart_port *port); + int i; + struct uart_port req; + for(i = 0; i < 2; i++) { + memset(&req, 0, sizeof(req)); + req.line = i; + req.iotype = UPIO_MEM; + req.membase = (char *)(0xff1ff300 + i * 0x100); + req.mapbase = 0xff1ff300 + i * 0x100; + req.irq = RBTX4938_IRQ_IRC_SIO(i); + req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; + req.uartclk = 50000000; + early_serial_txx9_setup(&req); + } + } +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + argptr = prom_getcmdline(); + if (strstr(argptr, "console=") == NULL) { + strcat(argptr, " console=ttyS0,38400"); + } +#endif +#endif + +#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 + printk("PIOSEL: disabling both ata and nand selection\n"); + local_irq_disable(); + tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); +#endif + +#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND + printk("PIOSEL: enabling nand selection\n"); + tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL; + tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL; +#endif + +#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA + printk("PIOSEL: enabling ata selection\n"); + tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL; + tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL; +#endif + +#ifdef CONFIG_IP_PNP + argptr = prom_getcmdline(); + if (strstr(argptr, "ip=") == NULL) { + strcat(argptr, " ip=any"); + } +#endif + + +#ifdef CONFIG_FB + { + conswitchp = &dummy_con; + } +#endif + + rbtx4938_spi_setup(); + pcfg = tx4938_ccfgptr->pcfg; /* updated */ + /* fixup piosel */ + if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == + TX4938_PCFG_ATA_SEL) + writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04, + rbtx4938_piosel_addr); + else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == + TX4938_PCFG_NDF_SEL) + writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08, + rbtx4938_piosel_addr); + else + writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04), + rbtx4938_piosel_addr); + + rbtx4938_fpga_resource.name = "FPGA Registers"; + rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR); + rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff; + rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, &rbtx4938_fpga_resource)) + printk("request resource for fpga failed\n"); + + _machine_restart = rbtx4938_machine_restart; + _machine_halt = rbtx4938_machine_halt; + pm_power_off = rbtx4938_machine_power_off; + + writeb(0xff, rbtx4938_led_addr); + printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", + readb(rbtx4938_fpga_rev_addr), + readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr)); +} + +static int __init rbtx4938_ne_init(void) +{ + struct resource res[] = { + { + .start = RBTX4938_RTL_8019_BASE, + .end = RBTX4938_RTL_8019_BASE + 0x20 - 1, + .flags = IORESOURCE_IO, + }, { + .start = RBTX4938_RTL_8019_IRQ, + .flags = IORESOURCE_IRQ, + } + }; + struct platform_device *dev = + platform_device_register_simple("ne", -1, + res, ARRAY_SIZE(res)); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} +device_initcall(rbtx4938_ne_init); + +/* GPIO support */ + +int gpio_to_irq(unsigned gpio) +{ + return -EINVAL; +} + +int irq_to_gpio(unsigned irq) +{ + return -EINVAL; +} + +static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); + +static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + u8 val; + unsigned long flags; + spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags); + val = readb(rbtx4938_spics_addr); + if (value) + val |= 1 << offset; + else + val &= ~(1 << offset); + writeb(val, rbtx4938_spics_addr); + mmiowb(); + spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags); +} + +static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip, + unsigned int offset, int value) +{ + rbtx4938_spi_gpio_set(chip, offset, value); + return 0; +} + +static struct gpio_chip rbtx4938_spi_gpio_chip = { + .set = rbtx4938_spi_gpio_set, + .direction_output = rbtx4938_spi_gpio_dir_out, + .label = "RBTX4938-SPICS", + .base = 16, + .ngpio = 3, +}; + +/* SPI support */ + +static void __init txx9_spi_init(unsigned long base, int irq) +{ + struct resource res[] = { + { + .start = base, + .end = base + 0x20 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = irq, + .flags = IORESOURCE_IRQ, + }, + }; + platform_device_register_simple("spi_txx9", 0, + res, ARRAY_SIZE(res)); +} + +static int __init rbtx4938_spi_init(void) +{ + struct spi_board_info srtc_info = { + .modalias = "rtc-rs5c348", + .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ + .bus_num = 0, + .chip_select = 16 + SRTC_CS, + /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ + .mode = SPI_MODE_1 | SPI_CS_HIGH, + }; + spi_register_board_info(&srtc_info, 1); + spi_eeprom_register(SEEPROM1_CS); + spi_eeprom_register(16 + SEEPROM2_CS); + spi_eeprom_register(16 + SEEPROM3_CS); + gpio_request(16 + SRTC_CS, "rtc-rs5c348"); + gpio_direction_output(16 + SRTC_CS, 0); + gpio_request(SEEPROM1_CS, "seeprom1"); + gpio_direction_output(SEEPROM1_CS, 1); + gpio_request(16 + SEEPROM2_CS, "seeprom2"); + gpio_direction_output(16 + SEEPROM2_CS, 1); + gpio_request(16 + SEEPROM3_CS, "seeprom3"); + gpio_direction_output(16 + SEEPROM3_CS, 1); + txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); + return 0; +} + +static int __init rbtx4938_arch_init(void) +{ + txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); + gpiochip_add(&rbtx4938_spi_gpio_chip); + return rbtx4938_spi_init(); +} +arch_initcall(rbtx4938_arch_init); + +/* Watchdog support */ + +static int __init txx9_wdt_init(unsigned long base) +{ + struct resource res = { + .start = base, + .end = base + 0x100 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev = + platform_device_register_simple("txx9wdt", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} + +static int __init rbtx4938_wdt_init(void) +{ + return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); +} +device_initcall(rbtx4938_wdt_init); + +/* Minimum CLK support */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "spi-baseclk")) + return (struct clk *)(txx9_gbus_clock / 2 / 4); + if (!strcmp(id, "imbus_clk")) + return (struct clk *)(txx9_gbus_clock / 2); + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/txx9/rbtx4938/spi_eeprom.c b/arch/mips/txx9/rbtx4938/spi_eeprom.c new file mode 100644 index 0000000..a7ea8b0 --- /dev/null +++ b/arch/mips/txx9/rbtx4938/spi_eeprom.c @@ -0,0 +1,99 @@ +/* + * spi_eeprom.c + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#include +#include +#include +#include +#include + +#define AT250X0_PAGE_SIZE 8 + +/* register board information for at25 driver */ +int __init spi_eeprom_register(int chipid) +{ + static struct spi_eeprom eeprom = { + .name = "at250x0", + .byte_len = 128, + .page_size = AT250X0_PAGE_SIZE, + .flags = EE_ADDR1, + }; + struct spi_board_info info = { + .modalias = "at25", + .max_speed_hz = 1500000, /* 1.5Mbps */ + .bus_num = 0, + .chip_select = chipid, + .platform_data = &eeprom, + /* Mode 0: High-Active, Sample-Then-Shift */ + }; + + return spi_register_board_info(&info, 1); +} + +/* simple temporary spi driver to provide early access to seeprom. */ + +static struct read_param { + int chipid; + int address; + unsigned char *buf; + int len; +} *read_param; + +static int __init early_seeprom_probe(struct spi_device *spi) +{ + int stat = 0; + u8 cmd[2]; + int len = read_param->len; + char *buf = read_param->buf; + int address = read_param->address; + + dev_info(&spi->dev, "spiclk %u KHz.\n", + (spi->max_speed_hz + 500) / 1000); + if (read_param->chipid != spi->chip_select) + return -ENODEV; + while (len > 0) { + /* spi_write_then_read can only work with small chunk */ + int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE; + cmd[0] = 0x03; /* AT25_READ */ + cmd[1] = address; + stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c); + buf += c; + len -= c; + address += c; + } + return stat; +} + +static struct spi_driver early_seeprom_driver __initdata = { + .driver = { + .name = "at25", + .owner = THIS_MODULE, + }, + .probe = early_seeprom_probe, +}; + +int __init spi_eeprom_read(int chipid, int address, + unsigned char *buf, int len) +{ + int ret; + struct read_param param = { + .chipid = chipid, + .address = address, + .buf = buf, + .len = len + }; + + read_param = ¶m; + ret = spi_register_driver(&early_seeprom_driver); + if (!ret) + spi_unregister_driver(&early_seeprom_driver); + return ret; +} diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h deleted file mode 100644 index a162268..0000000 --- a/include/asm-mips/jmr3927/jmr3927.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Defines for the TJSYS JMR-TX3927 - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000-2001 Toshiba Corporation - */ -#ifndef __ASM_TX3927_JMR3927_H -#define __ASM_TX3927_JMR3927_H - -#include -#include -#include -#include - -/* CS */ -#define JMR3927_ROMCE0 0x1fc00000 /* 4M */ -#define JMR3927_ROMCE1 0x1e000000 /* 4M */ -#define JMR3927_ROMCE2 0x14000000 /* 16M */ -#define JMR3927_ROMCE3 0x10000000 /* 64M */ -#define JMR3927_ROMCE5 0x1d000000 /* 4M */ -#define JMR3927_SDCS0 0x00000000 /* 32M */ -#define JMR3927_SDCS1 0x02000000 /* 32M */ -/* PCI Direct Mappings */ - -#define JMR3927_PCIMEM 0x08000000 -#define JMR3927_PCIMEM_SIZE 0x08000000 /* 128M */ -#define JMR3927_PCIIO 0x15000000 -#define JMR3927_PCIIO_SIZE 0x01000000 /* 16M */ - -#define JMR3927_SDRAM_SIZE 0x02000000 /* 32M */ -#define JMR3927_PORT_BASE KSEG1 - -/* Address map (virtual address) */ -#define JMR3927_ROM0_BASE (KSEG1 + JMR3927_ROMCE0) -#define JMR3927_ROM1_BASE (KSEG1 + JMR3927_ROMCE1) -#define JMR3927_IOC_BASE (KSEG1 + JMR3927_ROMCE2) -#define JMR3927_PCIMEM_BASE (KSEG1 + JMR3927_PCIMEM) -#define JMR3927_PCIIO_BASE (KSEG1 + JMR3927_PCIIO) - -#define JMR3927_IOC_REV_ADDR (JMR3927_IOC_BASE + 0x00000000) -#define JMR3927_IOC_NVRAMB_ADDR (JMR3927_IOC_BASE + 0x00010000) -#define JMR3927_IOC_LED_ADDR (JMR3927_IOC_BASE + 0x00020000) -#define JMR3927_IOC_DIPSW_ADDR (JMR3927_IOC_BASE + 0x00030000) -#define JMR3927_IOC_BREV_ADDR (JMR3927_IOC_BASE + 0x00040000) -#define JMR3927_IOC_DTR_ADDR (JMR3927_IOC_BASE + 0x00050000) -#define JMR3927_IOC_INTS1_ADDR (JMR3927_IOC_BASE + 0x00080000) -#define JMR3927_IOC_INTS2_ADDR (JMR3927_IOC_BASE + 0x00090000) -#define JMR3927_IOC_INTM_ADDR (JMR3927_IOC_BASE + 0x000a0000) -#define JMR3927_IOC_INTP_ADDR (JMR3927_IOC_BASE + 0x000b0000) -#define JMR3927_IOC_RESET_ADDR (JMR3927_IOC_BASE + 0x000f0000) - -/* Flash ROM */ -#define JMR3927_FLASH_BASE (JMR3927_ROM0_BASE) -#define JMR3927_FLASH_SIZE 0x00400000 - -/* bits for IOC_REV/IOC_BREV (high byte) */ -#define JMR3927_IDT_MASK 0xfc -#define JMR3927_REV_MASK 0x03 -#define JMR3927_IOC_IDT 0xe0 - -/* bits for IOC_INTS1/IOC_INTS2/IOC_INTM/IOC_INTP (high byte) */ -#define JMR3927_IOC_INTB_PCIA 0 -#define JMR3927_IOC_INTB_PCIB 1 -#define JMR3927_IOC_INTB_PCIC 2 -#define JMR3927_IOC_INTB_PCID 3 -#define JMR3927_IOC_INTB_MODEM 4 -#define JMR3927_IOC_INTB_INT6 5 -#define JMR3927_IOC_INTB_INT7 6 -#define JMR3927_IOC_INTB_SOFT 7 -#define JMR3927_IOC_INTF_PCIA (1 << JMR3927_IOC_INTF_PCIA) -#define JMR3927_IOC_INTF_PCIB (1 << JMR3927_IOC_INTB_PCIB) -#define JMR3927_IOC_INTF_PCIC (1 << JMR3927_IOC_INTB_PCIC) -#define JMR3927_IOC_INTF_PCID (1 << JMR3927_IOC_INTB_PCID) -#define JMR3927_IOC_INTF_MODEM (1 << JMR3927_IOC_INTB_MODEM) -#define JMR3927_IOC_INTF_INT6 (1 << JMR3927_IOC_INTB_INT6) -#define JMR3927_IOC_INTF_INT7 (1 << JMR3927_IOC_INTB_INT7) -#define JMR3927_IOC_INTF_SOFT (1 << JMR3927_IOC_INTB_SOFT) - -/* bits for IOC_RESET (high byte) */ -#define JMR3927_IOC_RESET_CPU 1 -#define JMR3927_IOC_RESET_PCI 2 - -#if defined(__BIG_ENDIAN) -#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)(a)) = (d)) -#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)(a)) -#elif defined(__LITTLE_ENDIAN) -#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)((a)^1)) = (d)) -#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)((a)^1)) -#else -#error "No Endian" -#endif - -/* LED macro */ -#define jmr3927_led_set(n/*0-16*/) jmr3927_ioc_reg_out(~(n), JMR3927_IOC_LED_ADDR) - -#define jmr3927_led_and_set(n/*0-16*/) jmr3927_ioc_reg_out((~(n)) & jmr3927_ioc_reg_in(JMR3927_IOC_LED_ADDR), JMR3927_IOC_LED_ADDR) - -/* DIPSW4 macro */ -#define jmr3927_dipsw1() (gpio_get_value(11) == 0) -#define jmr3927_dipsw2() (gpio_get_value(10) == 0) -#define jmr3927_dipsw3() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 2) == 0) -#define jmr3927_dipsw4() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 1) == 0) - -/* - * IRQ mappings - */ - -/* These are the virtual IRQ numbers, we divide all IRQ's into - * 'spaces', the 'space' determines where and how to enable/disable - * that particular IRQ on an JMR machine. Add new 'spaces' as new - * IRQ hardware is supported. - */ -#define JMR3927_NR_IRQ_IRC 16 /* On-Chip IRC */ -#define JMR3927_NR_IRQ_IOC 8 /* PCI/MODEM/INT[6:7] */ - -#define JMR3927_IRQ_IRC TXX9_IRQ_BASE -#define JMR3927_IRQ_IOC (JMR3927_IRQ_IRC + JMR3927_NR_IRQ_IRC) -#define JMR3927_IRQ_END (JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC) - -#define JMR3927_IRQ_IRC_INT0 (JMR3927_IRQ_IRC + TX3927_IR_INT0) -#define JMR3927_IRQ_IRC_INT1 (JMR3927_IRQ_IRC + TX3927_IR_INT1) -#define JMR3927_IRQ_IRC_INT2 (JMR3927_IRQ_IRC + TX3927_IR_INT2) -#define JMR3927_IRQ_IRC_INT3 (JMR3927_IRQ_IRC + TX3927_IR_INT3) -#define JMR3927_IRQ_IRC_INT4 (JMR3927_IRQ_IRC + TX3927_IR_INT4) -#define JMR3927_IRQ_IRC_INT5 (JMR3927_IRQ_IRC + TX3927_IR_INT5) -#define JMR3927_IRQ_IRC_SIO0 (JMR3927_IRQ_IRC + TX3927_IR_SIO0) -#define JMR3927_IRQ_IRC_SIO1 (JMR3927_IRQ_IRC + TX3927_IR_SIO1) -#define JMR3927_IRQ_IRC_SIO(ch) (JMR3927_IRQ_IRC + TX3927_IR_SIO(ch)) -#define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA) -#define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO) -#define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI) -#define JMR3927_IRQ_IRC_TMR(ch) (JMR3927_IRQ_IRC + TX3927_IR_TMR(ch)) -#define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA) -#define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB) -#define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC) -#define JMR3927_IRQ_IOC_PCID (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCID) -#define JMR3927_IRQ_IOC_MODEM (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_MODEM) -#define JMR3927_IRQ_IOC_INT6 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT6) -#define JMR3927_IRQ_IOC_INT7 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT7) -#define JMR3927_IRQ_IOC_SOFT (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_SOFT) - -/* IOC (PCI, MODEM) */ -#define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1 -/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */ -#define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3 - -/* Clocks */ -#define JMR3927_CORECLK 132710400 /* 132.7MHz */ -#define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */ -#define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */ - -/* - * TX3927 Pin Configuration: - * - * PCFG bits Avail Dead - * SELSIO[1:0]:11 RXD[1:0], TXD[1:0] PIO[6:3] - * SELSIOC[0]:1 CTS[0], RTS[0] INT[5:4] - * SELSIOC[1]:0,SELDSF:0, GSDAO[0],GPCST[3] CTS[1], RTS[1],DSF, - * GDBGE* PIO[2:1] - * SELDMA[2]:1 DMAREQ[2],DMAACK[2] PIO[13:12] - * SELTMR[2:0]:000 TIMER[1:0] - * SELCS:0,SELDMA[1]:0 PIO[11;10] SDCS_CE[7:6], - * DMAREQ[1],DMAACK[1] - * SELDMA[0]:1 DMAREQ[0],DMAACK[0] PIO[9:8] - * SELDMA[3]:1 DMAREQ[3],DMAACK[3] PIO[15:14] - * SELDONE:1 DMADONE PIO[7] - * - * Usable pins are: - * RXD[1;0],TXD[1:0],CTS[0],RTS[0], - * DMAREQ[0,2,3],DMAACK[0,2,3],DMADONE,PIO[0,10,11] - * INT[3:0] - */ - -#endif /* __ASM_TX3927_JMR3927_H */ diff --git a/include/asm-mips/jmr3927/tx3927.h b/include/asm-mips/jmr3927/tx3927.h deleted file mode 100644 index fb58033..0000000 --- a/include/asm-mips/jmr3927/tx3927.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Toshiba Corporation - */ -#ifndef __ASM_TX3927_H -#define __ASM_TX3927_H - -#include - -#define TX3927_SDRAMC_REG 0xfffe8000 -#define TX3927_ROMC_REG 0xfffe9000 -#define TX3927_DMA_REG 0xfffeb000 -#define TX3927_IRC_REG 0xfffec000 -#define TX3927_PCIC_REG 0xfffed000 -#define TX3927_CCFG_REG 0xfffee000 -#define TX3927_NR_TMR 3 -#define TX3927_TMR_REG(ch) (0xfffef000 + (ch) * 0x100) -#define TX3927_NR_SIO 2 -#define TX3927_SIO_REG(ch) (0xfffef300 + (ch) * 0x100) -#define TX3927_PIO_REG 0xfffef500 - -struct tx3927_sdramc_reg { - volatile unsigned long cr[8]; - volatile unsigned long tr[3]; - volatile unsigned long cmd; - volatile unsigned long smrs[2]; -}; - -struct tx3927_romc_reg { - volatile unsigned long cr[8]; -}; - -struct tx3927_dma_reg { - struct tx3927_dma_ch_reg { - volatile unsigned long cha; - volatile unsigned long sar; - volatile unsigned long dar; - volatile unsigned long cntr; - volatile unsigned long sair; - volatile unsigned long dair; - volatile unsigned long ccr; - volatile unsigned long csr; - } ch[4]; - volatile unsigned long dbr[8]; - volatile unsigned long tdhr; - volatile unsigned long mcr; - volatile unsigned long unused0; -}; - -#include - -#ifdef __BIG_ENDIAN -#define endian_def_s2(e1, e2) \ - volatile unsigned short e1, e2 -#define endian_def_sb2(e1, e2, e3) \ - volatile unsigned short e1;volatile unsigned char e2, e3 -#define endian_def_b2s(e1, e2, e3) \ - volatile unsigned char e1, e2;volatile unsigned short e3 -#define endian_def_b4(e1, e2, e3, e4) \ - volatile unsigned char e1, e2, e3, e4 -#else -#define endian_def_s2(e1, e2) \ - volatile unsigned short e2, e1 -#define endian_def_sb2(e1, e2, e3) \ - volatile unsigned char e3, e2;volatile unsigned short e1 -#define endian_def_b2s(e1, e2, e3) \ - volatile unsigned short e3;volatile unsigned char e2, e1 -#define endian_def_b4(e1, e2, e3, e4) \ - volatile unsigned char e4, e3, e2, e1 -#endif - -struct tx3927_pcic_reg { - endian_def_s2(did, vid); - endian_def_s2(pcistat, pcicmd); - endian_def_b4(cc, scc, rpli, rid); - endian_def_b4(unused0, ht, mlt, cls); - volatile unsigned long ioba; /* +10 */ - volatile unsigned long mba; - volatile unsigned long unused1[5]; - endian_def_s2(svid, ssvid); - volatile unsigned long unused2; /* +30 */ - endian_def_sb2(unused3, unused4, capptr); - volatile unsigned long unused5; - endian_def_b4(ml, mg, ip, il); - volatile unsigned long unused6; /* +40 */ - volatile unsigned long istat; - volatile unsigned long iim; - volatile unsigned long rrt; - volatile unsigned long unused7[3]; /* +50 */ - volatile unsigned long ipbmma; - volatile unsigned long ipbioma; /* +60 */ - volatile unsigned long ilbmma; - volatile unsigned long ilbioma; - volatile unsigned long unused8[9]; - volatile unsigned long tc; /* +90 */ - volatile unsigned long tstat; - volatile unsigned long tim; - volatile unsigned long tccmd; - volatile unsigned long pcirrt; /* +a0 */ - volatile unsigned long pcirrt_cmd; - volatile unsigned long pcirrdt; - volatile unsigned long unused9[3]; - volatile unsigned long tlboap; - volatile unsigned long tlbiap; - volatile unsigned long tlbmma; /* +c0 */ - volatile unsigned long tlbioma; - volatile unsigned long sc_msg; - volatile unsigned long sc_be; - volatile unsigned long tbl; /* +d0 */ - volatile unsigned long unused10[3]; - volatile unsigned long pwmng; /* +e0 */ - volatile unsigned long pwmngs; - volatile unsigned long unused11[6]; - volatile unsigned long req_trace; /* +100 */ - volatile unsigned long pbapmc; - volatile unsigned long pbapms; - volatile unsigned long pbapmim; - volatile unsigned long bm; /* +110 */ - volatile unsigned long cpcibrs; - volatile unsigned long cpcibgs; - volatile unsigned long pbacs; - volatile unsigned long iobas; /* +120 */ - volatile unsigned long mbas; - volatile unsigned long lbc; - volatile unsigned long lbstat; - volatile unsigned long lbim; /* +130 */ - volatile unsigned long pcistatim; - volatile unsigned long ica; - volatile unsigned long icd; - volatile unsigned long iiadp; /* +140 */ - volatile unsigned long iscdp; - volatile unsigned long mmas; - volatile unsigned long iomas; - volatile unsigned long ipciaddr; /* +150 */ - volatile unsigned long ipcidata; - volatile unsigned long ipcibe; -}; - -struct tx3927_ccfg_reg { - volatile unsigned long ccfg; - volatile unsigned long crir; - volatile unsigned long pcfg; - volatile unsigned long tear; - volatile unsigned long pdcr; -}; - -/* - * SDRAMC - */ - -/* - * ROMC - */ - -/* - * DMA - */ -/* bits for MCR */ -#define TX3927_DMA_MCR_EIS(ch) (0x10000000<<(ch)) -#define TX3927_DMA_MCR_DIS(ch) (0x01000000<<(ch)) -#define TX3927_DMA_MCR_RSFIF 0x00000080 -#define TX3927_DMA_MCR_FIFUM(ch) (0x00000008<<(ch)) -#define TX3927_DMA_MCR_LE 0x00000004 -#define TX3927_DMA_MCR_RPRT 0x00000002 -#define TX3927_DMA_MCR_MSTEN 0x00000001 - -/* bits for CCRn */ -#define TX3927_DMA_CCR_DBINH 0x04000000 -#define TX3927_DMA_CCR_SBINH 0x02000000 -#define TX3927_DMA_CCR_CHRST 0x01000000 -#define TX3927_DMA_CCR_RVBYTE 0x00800000 -#define TX3927_DMA_CCR_ACKPOL 0x00400000 -#define TX3927_DMA_CCR_REQPL 0x00200000 -#define TX3927_DMA_CCR_EGREQ 0x00100000 -#define TX3927_DMA_CCR_CHDN 0x00080000 -#define TX3927_DMA_CCR_DNCTL 0x00060000 -#define TX3927_DMA_CCR_EXTRQ 0x00010000 -#define TX3927_DMA_CCR_INTRQD 0x0000e000 -#define TX3927_DMA_CCR_INTENE 0x00001000 -#define TX3927_DMA_CCR_INTENC 0x00000800 -#define TX3927_DMA_CCR_INTENT 0x00000400 -#define TX3927_DMA_CCR_CHNEN 0x00000200 -#define TX3927_DMA_CCR_XFACT 0x00000100 -#define TX3927_DMA_CCR_SNOP 0x00000080 -#define TX3927_DMA_CCR_DSTINC 0x00000040 -#define TX3927_DMA_CCR_SRCINC 0x00000020 -#define TX3927_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c) -#define TX3927_DMA_CCR_XFSZ_1W TX3927_DMA_CCR_XFSZ(2) -#define TX3927_DMA_CCR_XFSZ_4W TX3927_DMA_CCR_XFSZ(4) -#define TX3927_DMA_CCR_XFSZ_8W TX3927_DMA_CCR_XFSZ(5) -#define TX3927_DMA_CCR_XFSZ_16W TX3927_DMA_CCR_XFSZ(6) -#define TX3927_DMA_CCR_XFSZ_32W TX3927_DMA_CCR_XFSZ(7) -#define TX3927_DMA_CCR_MEMIO 0x00000002 -#define TX3927_DMA_CCR_ONEAD 0x00000001 - -/* bits for CSRn */ -#define TX3927_DMA_CSR_CHNACT 0x00000100 -#define TX3927_DMA_CSR_ABCHC 0x00000080 -#define TX3927_DMA_CSR_NCHNC 0x00000040 -#define TX3927_DMA_CSR_NTRNFC 0x00000020 -#define TX3927_DMA_CSR_EXTDN 0x00000010 -#define TX3927_DMA_CSR_CFERR 0x00000008 -#define TX3927_DMA_CSR_CHERR 0x00000004 -#define TX3927_DMA_CSR_DESERR 0x00000002 -#define TX3927_DMA_CSR_SORERR 0x00000001 - -/* - * IRC - */ -#define TX3927_IR_INT0 0 -#define TX3927_IR_INT1 1 -#define TX3927_IR_INT2 2 -#define TX3927_IR_INT3 3 -#define TX3927_IR_INT4 4 -#define TX3927_IR_INT5 5 -#define TX3927_IR_SIO0 6 -#define TX3927_IR_SIO1 7 -#define TX3927_IR_SIO(ch) (6 + (ch)) -#define TX3927_IR_DMA 8 -#define TX3927_IR_PIO 9 -#define TX3927_IR_PCI 10 -#define TX3927_IR_TMR(ch) (13 + (ch)) -#define TX3927_NUM_IR 16 - -/* - * PCIC - */ -/* bits for PCICMD */ -/* see PCI_COMMAND_XXX in linux/pci.h */ - -/* bits for PCISTAT */ -/* see PCI_STATUS_XXX in linux/pci.h */ -#define PCI_STATUS_NEW_CAP 0x0010 - -/* bits for TC */ -#define TX3927_PCIC_TC_OF16E 0x00000020 -#define TX3927_PCIC_TC_IF8E 0x00000010 -#define TX3927_PCIC_TC_OF8E 0x00000008 - -/* bits for IOBA/MBA */ -/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */ - -/* bits for PBAPMC */ -#define TX3927_PCIC_PBAPMC_RPBA 0x00000004 -#define TX3927_PCIC_PBAPMC_PBAEN 0x00000002 -#define TX3927_PCIC_PBAPMC_BMCEN 0x00000001 - -/* bits for LBSTAT/LBIM */ -#define TX3927_PCIC_LBIM_ALL 0x0000003e - -/* bits for PCISTATIM (see also PCI_STATUS_XXX in linux/pci.h */ -#define TX3927_PCIC_PCISTATIM_ALL 0x0000f900 - -/* bits for LBC */ -#define TX3927_PCIC_LBC_IBSE 0x00004000 -#define TX3927_PCIC_LBC_TIBSE 0x00002000 -#define TX3927_PCIC_LBC_TMFBSE 0x00001000 -#define TX3927_PCIC_LBC_HRST 0x00000800 -#define TX3927_PCIC_LBC_SRST 0x00000400 -#define TX3927_PCIC_LBC_EPCAD 0x00000200 -#define TX3927_PCIC_LBC_MSDSE 0x00000100 -#define TX3927_PCIC_LBC_CRR 0x00000080 -#define TX3927_PCIC_LBC_ILMDE 0x00000040 -#define TX3927_PCIC_LBC_ILIDE 0x00000020 - -#define TX3927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) -#define TX3927_PCIC_MAX_DEVNU TX3927_PCIC_IDSEL_AD_TO_SLOT(32) - -/* - * CCFG - */ -/* CCFG : Chip Configuration */ -#define TX3927_CCFG_TLBOFF 0x00020000 -#define TX3927_CCFG_BEOW 0x00010000 -#define TX3927_CCFG_WR 0x00008000 -#define TX3927_CCFG_TOE 0x00004000 -#define TX3927_CCFG_PCIXARB 0x00002000 -#define TX3927_CCFG_PCI3 0x00001000 -#define TX3927_CCFG_PSNP 0x00000800 -#define TX3927_CCFG_PPRI 0x00000400 -#define TX3927_CCFG_PLLM 0x00000030 -#define TX3927_CCFG_ENDIAN 0x00000004 -#define TX3927_CCFG_HALT 0x00000002 -#define TX3927_CCFG_ACEHOLD 0x00000001 - -/* PCFG : Pin Configuration */ -#define TX3927_PCFG_SYSCLKEN 0x08000000 -#define TX3927_PCFG_SDRCLKEN_ALL 0x07c00000 -#define TX3927_PCFG_SDRCLKEN(ch) (0x00400000<<(ch)) -#define TX3927_PCFG_PCICLKEN_ALL 0x003c0000 -#define TX3927_PCFG_PCICLKEN(ch) (0x00040000<<(ch)) -#define TX3927_PCFG_SELALL 0x0003ffff -#define TX3927_PCFG_SELCS 0x00020000 -#define TX3927_PCFG_SELDSF 0x00010000 -#define TX3927_PCFG_SELSIOC_ALL 0x0000c000 -#define TX3927_PCFG_SELSIOC(ch) (0x00004000<<(ch)) -#define TX3927_PCFG_SELSIO_ALL 0x00003000 -#define TX3927_PCFG_SELSIO(ch) (0x00001000<<(ch)) -#define TX3927_PCFG_SELTMR_ALL 0x00000e00 -#define TX3927_PCFG_SELTMR(ch) (0x00000200<<(ch)) -#define TX3927_PCFG_SELDONE 0x00000100 -#define TX3927_PCFG_INTDMA_ALL 0x000000f0 -#define TX3927_PCFG_INTDMA(ch) (0x00000010<<(ch)) -#define TX3927_PCFG_SELDMA_ALL 0x0000000f -#define TX3927_PCFG_SELDMA(ch) (0x00000001<<(ch)) - -#define tx3927_sdramcptr ((struct tx3927_sdramc_reg *)TX3927_SDRAMC_REG) -#define tx3927_romcptr ((struct tx3927_romc_reg *)TX3927_ROMC_REG) -#define tx3927_dmaptr ((struct tx3927_dma_reg *)TX3927_DMA_REG) -#define tx3927_pcicptr ((struct tx3927_pcic_reg *)TX3927_PCIC_REG) -#define tx3927_ccfgptr ((struct tx3927_ccfg_reg *)TX3927_CCFG_REG) -#define tx3927_tmrptr(ch) ((struct txx927_tmr_reg *)TX3927_TMR_REG(ch)) -#define tx3927_sioptr(ch) ((struct txx927_sio_reg *)TX3927_SIO_REG(ch)) -#define tx3927_pioptr ((struct txx9_pio_reg __iomem *)TX3927_PIO_REG) - -#endif /* __ASM_TX3927_H */ diff --git a/include/asm-mips/jmr3927/txx927.h b/include/asm-mips/jmr3927/txx927.h deleted file mode 100644 index 25dcf2f..0000000 --- a/include/asm-mips/jmr3927/txx927.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Common definitions for TX3927/TX4927 - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Toshiba Corporation - */ -#ifndef __ASM_TXX927_H -#define __ASM_TXX927_H - -struct txx927_sio_reg { - volatile unsigned long lcr; - volatile unsigned long dicr; - volatile unsigned long disr; - volatile unsigned long cisr; - volatile unsigned long fcr; - volatile unsigned long flcr; - volatile unsigned long bgr; - volatile unsigned long tfifo; - volatile unsigned long rfifo; -}; - -/* - * SIO - */ -/* SILCR : Line Control */ -#define TXx927_SILCR_SCS_MASK 0x00000060 -#define TXx927_SILCR_SCS_IMCLK 0x00000000 -#define TXx927_SILCR_SCS_IMCLK_BG 0x00000020 -#define TXx927_SILCR_SCS_SCLK 0x00000040 -#define TXx927_SILCR_SCS_SCLK_BG 0x00000060 -#define TXx927_SILCR_UEPS 0x00000010 -#define TXx927_SILCR_UPEN 0x00000008 -#define TXx927_SILCR_USBL_MASK 0x00000004 -#define TXx927_SILCR_USBL_1BIT 0x00000004 -#define TXx927_SILCR_USBL_2BIT 0x00000000 -#define TXx927_SILCR_UMODE_MASK 0x00000003 -#define TXx927_SILCR_UMODE_8BIT 0x00000000 -#define TXx927_SILCR_UMODE_7BIT 0x00000001 - -/* SIDICR : DMA/Int. Control */ -#define TXx927_SIDICR_TDE 0x00008000 -#define TXx927_SIDICR_RDE 0x00004000 -#define TXx927_SIDICR_TIE 0x00002000 -#define TXx927_SIDICR_RIE 0x00001000 -#define TXx927_SIDICR_SPIE 0x00000800 -#define TXx927_SIDICR_CTSAC 0x00000600 -#define TXx927_SIDICR_STIE_MASK 0x0000003f -#define TXx927_SIDICR_STIE_OERS 0x00000020 -#define TXx927_SIDICR_STIE_CTSS 0x00000010 -#define TXx927_SIDICR_STIE_RBRKD 0x00000008 -#define TXx927_SIDICR_STIE_TRDY 0x00000004 -#define TXx927_SIDICR_STIE_TXALS 0x00000002 -#define TXx927_SIDICR_STIE_UBRKD 0x00000001 - -/* SIDISR : DMA/Int. Status */ -#define TXx927_SIDISR_UBRK 0x00008000 -#define TXx927_SIDISR_UVALID 0x00004000 -#define TXx927_SIDISR_UFER 0x00002000 -#define TXx927_SIDISR_UPER 0x00001000 -#define TXx927_SIDISR_UOER 0x00000800 -#define TXx927_SIDISR_ERI 0x00000400 -#define TXx927_SIDISR_TOUT 0x00000200 -#define TXx927_SIDISR_TDIS 0x00000100 -#define TXx927_SIDISR_RDIS 0x00000080 -#define TXx927_SIDISR_STIS 0x00000040 -#define TXx927_SIDISR_RFDN_MASK 0x0000001f - -/* SICISR : Change Int. Status */ -#define TXx927_SICISR_OERS 0x00000020 -#define TXx927_SICISR_CTSS 0x00000010 -#define TXx927_SICISR_RBRKD 0x00000008 -#define TXx927_SICISR_TRDY 0x00000004 -#define TXx927_SICISR_TXALS 0x00000002 -#define TXx927_SICISR_UBRKD 0x00000001 - -/* SIFCR : FIFO Control */ -#define TXx927_SIFCR_SWRST 0x00008000 -#define TXx927_SIFCR_RDIL_MASK 0x00000180 -#define TXx927_SIFCR_RDIL_1 0x00000000 -#define TXx927_SIFCR_RDIL_4 0x00000080 -#define TXx927_SIFCR_RDIL_8 0x00000100 -#define TXx927_SIFCR_RDIL_12 0x00000180 -#define TXx927_SIFCR_RDIL_MAX 0x00000180 -#define TXx927_SIFCR_TDIL_MASK 0x00000018 -#define TXx927_SIFCR_TDIL_MASK 0x00000018 -#define TXx927_SIFCR_TDIL_1 0x00000000 -#define TXx927_SIFCR_TDIL_4 0x00000001 -#define TXx927_SIFCR_TDIL_8 0x00000010 -#define TXx927_SIFCR_TDIL_MAX 0x00000010 -#define TXx927_SIFCR_TFRST 0x00000004 -#define TXx927_SIFCR_RFRST 0x00000002 -#define TXx927_SIFCR_FRSTE 0x00000001 -#define TXx927_SIO_TX_FIFO 8 -#define TXx927_SIO_RX_FIFO 16 - -/* SIFLCR : Flow Control */ -#define TXx927_SIFLCR_RCS 0x00001000 -#define TXx927_SIFLCR_TES 0x00000800 -#define TXx927_SIFLCR_RTSSC 0x00000200 -#define TXx927_SIFLCR_RSDE 0x00000100 -#define TXx927_SIFLCR_TSDE 0x00000080 -#define TXx927_SIFLCR_RTSTL_MASK 0x0000001e -#define TXx927_SIFLCR_RTSTL_MAX 0x0000001e -#define TXx927_SIFLCR_TBRK 0x00000001 - -/* SIBGR : Baudrate Control */ -#define TXx927_SIBGR_BCLK_MASK 0x00000300 -#define TXx927_SIBGR_BCLK_T0 0x00000000 -#define TXx927_SIBGR_BCLK_T2 0x00000100 -#define TXx927_SIBGR_BCLK_T4 0x00000200 -#define TXx927_SIBGR_BCLK_T6 0x00000300 -#define TXx927_SIBGR_BRD_MASK 0x000000ff - -/* - * PIO - */ - -#endif /* __ASM_TXX927_H */ diff --git a/include/asm-mips/tx4927/smsc_fdc37m81x.h b/include/asm-mips/tx4927/smsc_fdc37m81x.h deleted file mode 100644 index 5d93bab..0000000 --- a/include/asm-mips/tx4927/smsc_fdc37m81x.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * linux/include/asm-mips/tx4927/smsc_fdc37m81x.h - * - * Interface for smsc fdc48m81x Super IO chip - * - * Author: MontaVista Software, Inc. source@mvista.com - * - * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Copyright (C) 2004 MontaVista Software Inc. - * Manish Lachwani, mlachwani@mvista.com - */ - -#ifndef _SMSC_FDC37M81X_H_ -#define _SMSC_FDC37M81X_H_ - -/* Common Registers */ -#define SMSC_FDC37M81X_CONFIG_INDEX 0x00 -#define SMSC_FDC37M81X_CONFIG_DATA 0x01 -#define SMSC_FDC37M81X_CONF 0x02 -#define SMSC_FDC37M81X_INDEX 0x03 -#define SMSC_FDC37M81X_DNUM 0x07 -#define SMSC_FDC37M81X_DID 0x20 -#define SMSC_FDC37M81X_DREV 0x21 -#define SMSC_FDC37M81X_PCNT 0x22 -#define SMSC_FDC37M81X_PMGT 0x23 -#define SMSC_FDC37M81X_OSC 0x24 -#define SMSC_FDC37M81X_CONFPA0 0x26 -#define SMSC_FDC37M81X_CONFPA1 0x27 -#define SMSC_FDC37M81X_TEST4 0x2B -#define SMSC_FDC37M81X_TEST5 0x2C -#define SMSC_FDC37M81X_TEST1 0x2D -#define SMSC_FDC37M81X_TEST2 0x2E -#define SMSC_FDC37M81X_TEST3 0x2F - -/* Logical device numbers */ -#define SMSC_FDC37M81X_FDD 0x00 -#define SMSC_FDC37M81X_PARALLEL 0x03 -#define SMSC_FDC37M81X_SERIAL1 0x04 -#define SMSC_FDC37M81X_SERIAL2 0x05 -#define SMSC_FDC37M81X_KBD 0x07 -#define SMSC_FDC37M81X_AUXIO 0x08 -#define SMSC_FDC37M81X_NONE 0xff - -/* Logical device Config Registers */ -#define SMSC_FDC37M81X_ACTIVE 0x30 -#define SMSC_FDC37M81X_BASEADDR0 0x60 -#define SMSC_FDC37M81X_BASEADDR1 0x61 -#define SMSC_FDC37M81X_INT 0x70 -#define SMSC_FDC37M81X_INT2 0x72 -#define SMSC_FDC37M81X_LDCR_F0 0xF0 - -/* Chip Config Values */ -#define SMSC_FDC37M81X_CONFIG_ENTER 0x55 -#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa -#define SMSC_FDC37M81X_CHIP_ID 0x4d - -unsigned long __init smsc_fdc37m81x_init(unsigned long port); - -void smsc_fdc37m81x_config_beg(void); - -void smsc_fdc37m81x_config_end(void); - -void smsc_fdc37m81x_config_set(u8 reg, u8 val); - -#endif diff --git a/include/asm-mips/tx4927/toshiba_rbtx4927.h b/include/asm-mips/tx4927/toshiba_rbtx4927.h deleted file mode 100644 index d6b32ac..0000000 --- a/include/asm-mips/tx4927/toshiba_rbtx4927.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2002 MontaVista Software 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __ASM_TX4927_TOSHIBA_RBTX4927_H -#define __ASM_TX4927_TOSHIBA_RBTX4927_H - -#include - -#ifdef CONFIG_PCI -#define TBTX4927_ISA_IO_OFFSET TX4927_PCIIO -#else -#define TBTX4927_ISA_IO_OFFSET 0 -#endif - -#define RBTX4927_SW_RESET_DO (void __iomem *)0xbc00f000UL -#define RBTX4927_SW_RESET_DO_SET 0x01 - -#define RBTX4927_SW_RESET_ENABLE (void __iomem *)0xbc00f002UL -#define RBTX4927_SW_RESET_ENABLE_SET 0x01 - -#define RBTX4927_RTL_8019_BASE (0x1c020280-TBTX4927_ISA_IO_OFFSET) -#define RBTX4927_RTL_8019_IRQ (TX4927_IRQ_PIC_BEG + 5) - -int toshiba_rbtx4927_irq_nested(int sw_irq); - -#endif /* __ASM_TX4927_TOSHIBA_RBTX4927_H */ diff --git a/include/asm-mips/tx4927/tx4927.h b/include/asm-mips/tx4927/tx4927.h deleted file mode 100644 index 1d4816f..0000000 --- a/include/asm-mips/tx4927/tx4927.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Author: MontaVista Software, Inc. - * source@mvista.com - * - * Copyright 2001-2006 MontaVista Software 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __ASM_TX4927_TX4927_H -#define __ASM_TX4927_TX4927_H - -#include - -#define TX4927_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE -#define TX4927_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) - -#define TX4927_IRQ_PIC_BEG TXX9_IRQ_BASE -#define TX4927_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) - - -#define TX4927_IRQ_USER0 (TX4927_IRQ_CP0_BEG+0) -#define TX4927_IRQ_USER1 (TX4927_IRQ_CP0_BEG+1) -#define TX4927_IRQ_NEST_PIC_ON_CP0 (TX4927_IRQ_CP0_BEG+2) -#define TX4927_IRQ_CPU_TIMER (TX4927_IRQ_CP0_BEG+7) - -#define TX4927_IRQ_NEST_EXT_ON_PIC (TX4927_IRQ_PIC_BEG+3) - -#define TX4927_CCFG_TOE 0x00004000 -#define TX4927_CCFG_WR 0x00008000 -#define TX4927_CCFG_TINTDIS 0x01000000 - -#define TX4927_PCIMEM 0x08000000 -#define TX4927_PCIMEM_SIZE 0x08000000 -#define TX4927_PCIIO 0x16000000 -#define TX4927_PCIIO_SIZE 0x01000000 - -#define TX4927_SDRAMC_REG 0xff1f8000 -#define TX4927_EBUSC_REG 0xff1f9000 -#define TX4927_PCIC_REG 0xff1fd000 -#define TX4927_CCFG_REG 0xff1fe000 -#define TX4927_IRC_REG 0xff1ff600 -#define TX4927_NR_TMR 3 -#define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) - -/* bits for ISTAT3/IMASK3/IMSTAT3 */ -#define TX4927_INT3B_PCID 0 -#define TX4927_INT3B_PCIC 1 -#define TX4927_INT3B_PCIB 2 -#define TX4927_INT3B_PCIA 3 -#define TX4927_INT3F_PCID (1 << TX4927_INT3B_PCID) -#define TX4927_INT3F_PCIC (1 << TX4927_INT3B_PCIC) -#define TX4927_INT3F_PCIB (1 << TX4927_INT3B_PCIB) -#define TX4927_INT3F_PCIA (1 << TX4927_INT3B_PCIA) - -#define TX4927_NR_IRQ_LOCAL TX4927_IRQ_PIC_BEG -#define TX4927_NR_IRQ_IRC 32 /* On-Chip IRC */ - -#define TX4927_IR_PCIC 16 -#define TX4927_IR_PCIERR 22 -#define TX4927_IR_PCIPMA 23 -#define TX4927_IRQ_IRC_PCIC (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIC) -#define TX4927_IRQ_IRC_PCIERR (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIERR) -#define TX4927_IRQ_IOC1 (TX4927_NR_IRQ_LOCAL + TX4927_NR_IRQ_IRC) -#define TX4927_IRQ_IOC_PCID (TX4927_IRQ_IOC1 + TX4927_INT3B_PCID) -#define TX4927_IRQ_IOC_PCIC (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIC) -#define TX4927_IRQ_IOC_PCIB (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIB) -#define TX4927_IRQ_IOC_PCIA (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIA) - -#ifdef _LANGUAGE_ASSEMBLY -#define _CONST64(c) c -#else -#define _CONST64(c) c##ull - -#include - -struct tx4927_sdramc_reg { - volatile unsigned long long cr[4]; - volatile unsigned long long unused0[4]; - volatile unsigned long long tr; - volatile unsigned long long unused1[2]; - volatile unsigned long long cmd; -}; - -struct tx4927_ebusc_reg { - volatile unsigned long long cr[8]; -}; - -struct tx4927_ccfg_reg { - volatile unsigned long long ccfg; - volatile unsigned long long crir; - volatile unsigned long long pcfg; - volatile unsigned long long tear; - volatile unsigned long long clkctr; - volatile unsigned long long unused0; - volatile unsigned long long garbc; - volatile unsigned long long unused1; - volatile unsigned long long unused2; - volatile unsigned long long ramp; -}; - -struct tx4927_pcic_reg { - volatile unsigned long pciid; - volatile unsigned long pcistatus; - volatile unsigned long pciccrev; - volatile unsigned long pcicfg1; - volatile unsigned long p2gm0plbase; /* +10 */ - volatile unsigned long p2gm0pubase; - volatile unsigned long p2gm1plbase; - volatile unsigned long p2gm1pubase; - volatile unsigned long p2gm2pbase; /* +20 */ - volatile unsigned long p2giopbase; - volatile unsigned long unused0; - volatile unsigned long pcisid; - volatile unsigned long unused1; /* +30 */ - volatile unsigned long pcicapptr; - volatile unsigned long unused2; - volatile unsigned long pcicfg2; - volatile unsigned long g2ptocnt; /* +40 */ - volatile unsigned long unused3[15]; - volatile unsigned long g2pstatus; /* +80 */ - volatile unsigned long g2pmask; - volatile unsigned long pcisstatus; - volatile unsigned long pcimask; - volatile unsigned long p2gcfg; /* +90 */ - volatile unsigned long p2gstatus; - volatile unsigned long p2gmask; - volatile unsigned long p2gccmd; - volatile unsigned long unused4[24]; /* +a0 */ - volatile unsigned long pbareqport; /* +100 */ - volatile unsigned long pbacfg; - volatile unsigned long pbastatus; - volatile unsigned long pbamask; - volatile unsigned long pbabm; /* +110 */ - volatile unsigned long pbacreq; - volatile unsigned long pbacgnt; - volatile unsigned long pbacstate; - volatile unsigned long long g2pmgbase[3]; /* +120 */ - volatile unsigned long long g2piogbase; - volatile unsigned long g2pmmask[3]; /* +140 */ - volatile unsigned long g2piomask; - volatile unsigned long long g2pmpbase[3]; /* +150 */ - volatile unsigned long long g2piopbase; - volatile unsigned long pciccfg; /* +170 */ - volatile unsigned long pcicstatus; - volatile unsigned long pcicmask; - volatile unsigned long unused5; - volatile unsigned long long p2gmgbase[3]; /* +180 */ - volatile unsigned long long p2giogbase; - volatile unsigned long g2pcfgadrs; /* +1a0 */ - volatile unsigned long g2pcfgdata; - volatile unsigned long unused6[8]; - volatile unsigned long g2pintack; - volatile unsigned long g2pspc; - volatile unsigned long unused7[12]; /* +1d0 */ - volatile unsigned long long pdmca; /* +200 */ - volatile unsigned long long pdmga; - volatile unsigned long long pdmpa; - volatile unsigned long long pdmcut; - volatile unsigned long long pdmcnt; /* +220 */ - volatile unsigned long long pdmsts; - volatile unsigned long long unused8[2]; - volatile unsigned long long pdmdb[4]; /* +240 */ - volatile unsigned long long pdmtdh; /* +260 */ - volatile unsigned long long pdmdms; -}; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* - * PCIC - */ - -/* bits for G2PSTATUS/G2PMASK */ -#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 -#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 -#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 - -/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ -#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 - -/* bits for PBACFG */ -#define TX4927_PCIC_PBACFG_RPBA 0x00000004 -#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 -#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 - -/* bits for G2PMnGBASE */ -#define TX4927_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for G2PIOGBASE */ -#define TX4927_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for PCICSTATUS/PCICMASK */ -#define TX4927_PCIC_PCICSTATUS_ALL 0x000007dc - -/* bits for PCICCFG */ -#define TX4927_PCIC_PCICCFG_LBWC_MASK 0x0fff0000 -#define TX4927_PCIC_PCICCFG_HRST 0x00000800 -#define TX4927_PCIC_PCICCFG_SRST 0x00000400 -#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 -#define TX4927_PCIC_PCICCFG_IMSE0 0x00000100 -#define TX4927_PCIC_PCICCFG_IMSE1 0x00000080 -#define TX4927_PCIC_PCICCFG_IMSE2 0x00000040 -#define TX4927_PCIC_PCICCFG_IISE 0x00000020 -#define TX4927_PCIC_PCICCFG_ATR 0x00000010 -#define TX4927_PCIC_PCICCFG_ICAE 0x00000008 - -/* bits for P2GMnGBASE */ -#define TX4927_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) -#define TX4927_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) - -/* bits for P2GIOGBASE */ -#define TX4927_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) -#define TX4927_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) - -#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) -#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) - -/* - * CCFG - */ -/* CCFG : Chip Configuration */ -#define TX4927_CCFG_PCI66 0x00800000 -#define TX4927_CCFG_PCIMIDE 0x00400000 -#define TX4927_CCFG_PCIXARB 0x00002000 -#define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800 -#define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000 -#define TX4927_CCFG_PCIDIVMODE_3 0x00000800 -#define TX4927_CCFG_PCIDIVMODE_5 0x00001000 -#define TX4927_CCFG_PCIDIVMODE_6 0x00001800 - -#define TX4937_CCFG_PCIDIVMODE_MASK 0x00001c00 -#define TX4937_CCFG_PCIDIVMODE_8 0x00000000 -#define TX4937_CCFG_PCIDIVMODE_4 0x00000400 -#define TX4937_CCFG_PCIDIVMODE_9 0x00000800 -#define TX4937_CCFG_PCIDIVMODE_4_5 0x00000c00 -#define TX4937_CCFG_PCIDIVMODE_10 0x00001000 -#define TX4937_CCFG_PCIDIVMODE_5 0x00001400 -#define TX4937_CCFG_PCIDIVMODE_11 0x00001800 -#define TX4937_CCFG_PCIDIVMODE_5_5 0x00001c00 - -/* PCFG : Pin Configuration */ -#define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 -#define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) - -/* CLKCTR : Clock Control */ -#define TX4927_CLKCTR_PCICKD 0x00400000 -#define TX4927_CLKCTR_PCIRST 0x00000040 - -#ifndef _LANGUAGE_ASSEMBLY - -#define tx4927_sdramcptr ((struct tx4927_sdramc_reg *)TX4927_SDRAMC_REG) -#define tx4927_pcicptr ((struct tx4927_pcic_reg *)TX4927_PCIC_REG) -#define tx4927_ccfgptr ((struct tx4927_ccfg_reg *)TX4927_CCFG_REG) -#define tx4927_ebuscptr ((struct tx4927_ebusc_reg *)TX4927_EBUSC_REG) - -#endif /* _LANGUAGE_ASSEMBLY */ - -#endif /* __ASM_TX4927_TX4927_H */ diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h deleted file mode 100644 index dfed7be..0000000 --- a/include/asm-mips/tx4938/rbtx4938.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * linux/include/asm-mips/tx4938/rbtx4938.h - * Definitions for TX4937/TX4938 - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#ifndef __ASM_TX_BOARDS_RBTX4938_H -#define __ASM_TX_BOARDS_RBTX4938_H - -#include -#include -#include - -/* CS */ -#define RBTX4938_CE0 0x1c000000 /* 64M */ -#define RBTX4938_CE2 0x17f00000 /* 1M */ - -/* Address map */ -#define RBTX4938_FPGA_REG_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000000) -#define RBTX4938_FPGA_REV_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000002) -#define RBTX4938_CONFIG1_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000004) -#define RBTX4938_CONFIG2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000006) -#define RBTX4938_CONFIG3_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000008) -#define RBTX4938_LED_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001000) -#define RBTX4938_DIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001002) -#define RBTX4938_BDIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001004) -#define RBTX4938_IMASK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002000) -#define RBTX4938_IMASK2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002002) -#define RBTX4938_INTPOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002004) -#define RBTX4938_ISTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002006) -#define RBTX4938_ISTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002008) -#define RBTX4938_IMSTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200a) -#define RBTX4938_IMSTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200c) -#define RBTX4938_SOFTINT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00003000) -#define RBTX4938_PIOSEL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005000) -#define RBTX4938_SPICS_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005002) -#define RBTX4938_SFPWR_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005008) -#define RBTX4938_SFVOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000500a) -#define RBTX4938_SOFTRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007000) -#define RBTX4938_SOFTRESETLOCK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007002) -#define RBTX4938_PCIRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007004) -#define RBTX4938_ETHER_BASE (KSEG1 + RBTX4938_CE2 + 0x00020000) - -/* Ethernet port address (Jumperless Mode (W12:Open)) */ -#define RBTX4938_ETHER_ADDR (RBTX4938_ETHER_BASE + 0x280) - -/* bits for ISTAT/IMASK/IMSTAT */ -#define RBTX4938_INTB_PCID 0 -#define RBTX4938_INTB_PCIC 1 -#define RBTX4938_INTB_PCIB 2 -#define RBTX4938_INTB_PCIA 3 -#define RBTX4938_INTB_RTC 4 -#define RBTX4938_INTB_ATA 5 -#define RBTX4938_INTB_MODEM 6 -#define RBTX4938_INTB_SWINT 7 -#define RBTX4938_INTF_PCID (1 << RBTX4938_INTB_PCID) -#define RBTX4938_INTF_PCIC (1 << RBTX4938_INTB_PCIC) -#define RBTX4938_INTF_PCIB (1 << RBTX4938_INTB_PCIB) -#define RBTX4938_INTF_PCIA (1 << RBTX4938_INTB_PCIA) -#define RBTX4938_INTF_RTC (1 << RBTX4938_INTB_RTC) -#define RBTX4938_INTF_ATA (1 << RBTX4938_INTB_ATA) -#define RBTX4938_INTF_MODEM (1 << RBTX4938_INTB_MODEM) -#define RBTX4938_INTF_SWINT (1 << RBTX4938_INTB_SWINT) - -#define rbtx4938_fpga_rev_addr ((__u8 __iomem *)RBTX4938_FPGA_REV_ADDR) -#define rbtx4938_led_addr ((__u8 __iomem *)RBTX4938_LED_ADDR) -#define rbtx4938_dipsw_addr ((__u8 __iomem *)RBTX4938_DIPSW_ADDR) -#define rbtx4938_bdipsw_addr ((__u8 __iomem *)RBTX4938_BDIPSW_ADDR) -#define rbtx4938_imask_addr ((__u8 __iomem *)RBTX4938_IMASK_ADDR) -#define rbtx4938_imask2_addr ((__u8 __iomem *)RBTX4938_IMASK2_ADDR) -#define rbtx4938_intpol_addr ((__u8 __iomem *)RBTX4938_INTPOL_ADDR) -#define rbtx4938_istat_addr ((__u8 __iomem *)RBTX4938_ISTAT_ADDR) -#define rbtx4938_istat2_addr ((__u8 __iomem *)RBTX4938_ISTAT2_ADDR) -#define rbtx4938_imstat_addr ((__u8 __iomem *)RBTX4938_IMSTAT_ADDR) -#define rbtx4938_imstat2_addr ((__u8 __iomem *)RBTX4938_IMSTAT2_ADDR) -#define rbtx4938_softint_addr ((__u8 __iomem *)RBTX4938_SOFTINT_ADDR) -#define rbtx4938_piosel_addr ((__u8 __iomem *)RBTX4938_PIOSEL_ADDR) -#define rbtx4938_spics_addr ((__u8 __iomem *)RBTX4938_SPICS_ADDR) -#define rbtx4938_sfpwr_addr ((__u8 __iomem *)RBTX4938_SFPWR_ADDR) -#define rbtx4938_sfvol_addr ((__u8 __iomem *)RBTX4938_SFVOL_ADDR) -#define rbtx4938_softreset_addr ((__u8 __iomem *)RBTX4938_SOFTRESET_ADDR) -#define rbtx4938_softresetlock_addr \ - ((__u8 __iomem *)RBTX4938_SOFTRESETLOCK_ADDR) -#define rbtx4938_pcireset_addr ((__u8 __iomem *)RBTX4938_PCIRESET_ADDR) - -/* - * IRQ mappings - */ - -#define RBTX4938_SOFT_INT0 0 /* not used */ -#define RBTX4938_SOFT_INT1 1 /* not used */ -#define RBTX4938_IRC_INT 2 -#define RBTX4938_TIMER_INT 7 - -/* These are the virtual IRQ numbers, we divide all IRQ's into - * 'spaces', the 'space' determines where and how to enable/disable - * that particular IRQ on an RBTX4938 machine. Add new 'spaces' as new - * IRQ hardware is supported. - */ -#define RBTX4938_NR_IRQ_LOCAL 8 -#define RBTX4938_NR_IRQ_IRC 32 /* On-Chip IRC */ -#define RBTX4938_NR_IRQ_IOC 8 - -#define TX4938_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE -#define TX4938_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) - -#define TX4938_IRQ_PIC_BEG TXX9_IRQ_BASE -#define TX4938_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) -#define TX4938_IRQ_NEST_EXT_ON_PIC (TX4938_IRQ_PIC_BEG+2) -#define TX4938_IRQ_NEST_PIC_ON_CP0 (TX4938_IRQ_CP0_BEG+2) -#define TX4938_IRQ_USER0 (TX4938_IRQ_CP0_BEG+0) -#define TX4938_IRQ_USER1 (TX4938_IRQ_CP0_BEG+1) -#define TX4938_IRQ_CPU_TIMER (TX4938_IRQ_CP0_BEG+7) - -#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG 0 -#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END 7 - -#define TOSHIBA_RBTX4938_IRQ_IOC_BEG ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */ -#define TOSHIBA_RBTX4938_IRQ_IOC_END ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */ -#define RBTX4938_IRQ_LOCAL TX4938_IRQ_CP0_BEG -#define RBTX4938_IRQ_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL) -#define RBTX4938_IRQ_IOC (RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC) -#define RBTX4938_IRQ_END (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC) - -#define RBTX4938_IRQ_LOCAL_SOFT0 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0) -#define RBTX4938_IRQ_LOCAL_SOFT1 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1) -#define RBTX4938_IRQ_LOCAL_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT) -#define RBTX4938_IRQ_LOCAL_TIMER (RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT) -#define RBTX4938_IRQ_IRC_ECCERR (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR) -#define RBTX4938_IRQ_IRC_WTOERR (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR) -#define RBTX4938_IRQ_IRC_INT(n) (RBTX4938_IRQ_IRC + TX4938_IR_INT(n)) -#define RBTX4938_IRQ_IRC_SIO(n) (RBTX4938_IRQ_IRC + TX4938_IR_SIO(n)) -#define RBTX4938_IRQ_IRC_DMA(ch, n) (RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch, n)) -#define RBTX4938_IRQ_IRC_PIO (RBTX4938_IRQ_IRC + TX4938_IR_PIO) -#define RBTX4938_IRQ_IRC_PDMAC (RBTX4938_IRQ_IRC + TX4938_IR_PDMAC) -#define RBTX4938_IRQ_IRC_PCIC (RBTX4938_IRQ_IRC + TX4938_IR_PCIC) -#define RBTX4938_IRQ_IRC_TMR(n) (RBTX4938_IRQ_IRC + TX4938_IR_TMR(n)) -#define RBTX4938_IRQ_IRC_NDFMC (RBTX4938_IRQ_IRC + TX4938_IR_NDFMC) -#define RBTX4938_IRQ_IRC_PCIERR (RBTX4938_IRQ_IRC + TX4938_IR_PCIERR) -#define RBTX4938_IRQ_IRC_PCIPME (RBTX4938_IRQ_IRC + TX4938_IR_PCIPME) -#define RBTX4938_IRQ_IRC_ACLC (RBTX4938_IRQ_IRC + TX4938_IR_ACLC) -#define RBTX4938_IRQ_IRC_ACLCPME (RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME) -#define RBTX4938_IRQ_IRC_PCIC1 (RBTX4938_IRQ_IRC + TX4938_IR_PCIC1) -#define RBTX4938_IRQ_IRC_SPI (RBTX4938_IRQ_IRC + TX4938_IR_SPI) -#define RBTX4938_IRQ_IOC_PCID (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID) -#define RBTX4938_IRQ_IOC_PCIC (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC) -#define RBTX4938_IRQ_IOC_PCIB (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB) -#define RBTX4938_IRQ_IOC_PCIA (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA) -#define RBTX4938_IRQ_IOC_RTC (RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC) -#define RBTX4938_IRQ_IOC_ATA (RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA) -#define RBTX4938_IRQ_IOC_MODEM (RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM) -#define RBTX4938_IRQ_IOC_SWINT (RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT) - - -/* IOC (PCI, etc) */ -#define RBTX4938_IRQ_IOCINT (TX4938_IRQ_NEST_EXT_ON_PIC) -/* Onboard 10M Ether */ -#define RBTX4938_IRQ_ETHER (TX4938_IRQ_NEST_EXT_ON_PIC + 1) - -#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base) -#define RBTX4938_RTL_8019_IRQ (RBTX4938_IRQ_ETHER) - -#endif /* __ASM_TX_BOARDS_RBTX4938_H */ diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h deleted file mode 100644 index 6a60c83..0000000 --- a/include/asm-mips/tx4938/spi.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/include/asm-mips/tx4938/spi.h - * Definitions for TX4937/TX4938 SPI - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#ifndef __ASM_TX_BOARDS_TX4938_SPI_H -#define __ASM_TX_BOARDS_TX4938_SPI_H - -extern int spi_eeprom_register(int chipid); -extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); - -#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */ diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h deleted file mode 100644 index e8807f5..0000000 --- a/include/asm-mips/tx4938/tx4938.h +++ /dev/null @@ -1,628 +0,0 @@ -/* - * linux/include/asm-mips/tx4938/tx4938.h - * Definitions for TX4937/TX4938 - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#ifndef __ASM_TX_BOARDS_TX4938_H -#define __ASM_TX_BOARDS_TX4938_H - -#define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr)) -#define tx4938_write_nfmc(b, addr) (*(volatile unsigned int *)(addr)) = (b) - -#define TX4938_NR_IRQ_LOCAL TX4938_IRQ_PIC_BEG - -#define TX4938_IRQ_IRC_PCIC (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC) -#define TX4938_IRQ_IRC_PCIERR (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR) - -#define TX4938_PCIIO_0 0x10000000 -#define TX4938_PCIIO_1 0x01010000 -#define TX4938_PCIMEM_0 0x08000000 -#define TX4938_PCIMEM_1 0x11000000 - -#define TX4938_PCIIO_SIZE_0 0x01000000 -#define TX4938_PCIIO_SIZE_1 0x00010000 -#define TX4938_PCIMEM_SIZE_0 0x08000000 -#define TX4938_PCIMEM_SIZE_1 0x00010000 - -#define TX4938_REG_BASE 0xff1f0000 /* == TX4937_REG_BASE */ -#define TX4938_REG_SIZE 0x00010000 /* == TX4937_REG_SIZE */ - -/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */ -#define TX4938_NDFMC_REG (TX4938_REG_BASE + 0x5000) -#define TX4938_SRAMC_REG (TX4938_REG_BASE + 0x6000) -#define TX4938_PCIC1_REG (TX4938_REG_BASE + 0x7000) -#define TX4938_SDRAMC_REG (TX4938_REG_BASE + 0x8000) -#define TX4938_EBUSC_REG (TX4938_REG_BASE + 0x9000) -#define TX4938_DMA_REG(ch) (TX4938_REG_BASE + 0xb000 + (ch) * 0x800) -#define TX4938_PCIC_REG (TX4938_REG_BASE + 0xd000) -#define TX4938_CCFG_REG (TX4938_REG_BASE + 0xe000) -#define TX4938_NR_TMR 3 -#define TX4938_TMR_REG(ch) ((TX4938_REG_BASE + 0xf000) + (ch) * 0x100) -#define TX4938_NR_SIO 2 -#define TX4938_SIO_REG(ch) ((TX4938_REG_BASE + 0xf300) + (ch) * 0x100) -#define TX4938_PIO_REG (TX4938_REG_BASE + 0xf500) -#define TX4938_IRC_REG (TX4938_REG_BASE + 0xf600) -#define TX4938_ACLC_REG (TX4938_REG_BASE + 0xf700) -#define TX4938_SPI_REG (TX4938_REG_BASE + 0xf800) - -#ifdef __ASSEMBLY__ -#define _CONST64(c) c -#else -#define _CONST64(c) c##ull - -#include - -#ifdef __BIG_ENDIAN -#define endian_def_l2(e1, e2) \ - volatile unsigned long e1, e2 -#define endian_def_s2(e1, e2) \ - volatile unsigned short e1, e2 -#define endian_def_sb2(e1, e2, e3) \ - volatile unsigned short e1;volatile unsigned char e2, e3 -#define endian_def_b2s(e1, e2, e3) \ - volatile unsigned char e1, e2;volatile unsigned short e3 -#define endian_def_b4(e1, e2, e3, e4) \ - volatile unsigned char e1, e2, e3, e4 -#else -#define endian_def_l2(e1, e2) \ - volatile unsigned long e2, e1 -#define endian_def_s2(e1, e2) \ - volatile unsigned short e2, e1 -#define endian_def_sb2(e1, e2, e3) \ - volatile unsigned char e3, e2;volatile unsigned short e1 -#define endian_def_b2s(e1, e2, e3) \ - volatile unsigned short e3;volatile unsigned char e2, e1 -#define endian_def_b4(e1, e2, e3, e4) \ - volatile unsigned char e4, e3, e2, e1 -#endif - - -struct tx4938_sdramc_reg { - volatile unsigned long long cr[4]; - volatile unsigned long long unused0[4]; - volatile unsigned long long tr; - volatile unsigned long long unused1[2]; - volatile unsigned long long cmd; - volatile unsigned long long sfcmd; -}; - -struct tx4938_ebusc_reg { - volatile unsigned long long cr[8]; -}; - -struct tx4938_dma_reg { - struct tx4938_dma_ch_reg { - volatile unsigned long long cha; - volatile unsigned long long sar; - volatile unsigned long long dar; - endian_def_l2(unused0, cntr); - endian_def_l2(unused1, sair); - endian_def_l2(unused2, dair); - endian_def_l2(unused3, ccr); - endian_def_l2(unused4, csr); - } ch[4]; - volatile unsigned long long dbr[8]; - volatile unsigned long long tdhr; - volatile unsigned long long midr; - endian_def_l2(unused0, mcr); -}; - -struct tx4938_pcic_reg { - volatile unsigned long pciid; - volatile unsigned long pcistatus; - volatile unsigned long pciccrev; - volatile unsigned long pcicfg1; - volatile unsigned long p2gm0plbase; /* +10 */ - volatile unsigned long p2gm0pubase; - volatile unsigned long p2gm1plbase; - volatile unsigned long p2gm1pubase; - volatile unsigned long p2gm2pbase; /* +20 */ - volatile unsigned long p2giopbase; - volatile unsigned long unused0; - volatile unsigned long pcisid; - volatile unsigned long unused1; /* +30 */ - volatile unsigned long pcicapptr; - volatile unsigned long unused2; - volatile unsigned long pcicfg2; - volatile unsigned long g2ptocnt; /* +40 */ - volatile unsigned long unused3[15]; - volatile unsigned long g2pstatus; /* +80 */ - volatile unsigned long g2pmask; - volatile unsigned long pcisstatus; - volatile unsigned long pcimask; - volatile unsigned long p2gcfg; /* +90 */ - volatile unsigned long p2gstatus; - volatile unsigned long p2gmask; - volatile unsigned long p2gccmd; - volatile unsigned long unused4[24]; /* +a0 */ - volatile unsigned long pbareqport; /* +100 */ - volatile unsigned long pbacfg; - volatile unsigned long pbastatus; - volatile unsigned long pbamask; - volatile unsigned long pbabm; /* +110 */ - volatile unsigned long pbacreq; - volatile unsigned long pbacgnt; - volatile unsigned long pbacstate; - volatile unsigned long long g2pmgbase[3]; /* +120 */ - volatile unsigned long long g2piogbase; - volatile unsigned long g2pmmask[3]; /* +140 */ - volatile unsigned long g2piomask; - volatile unsigned long long g2pmpbase[3]; /* +150 */ - volatile unsigned long long g2piopbase; - volatile unsigned long pciccfg; /* +170 */ - volatile unsigned long pcicstatus; - volatile unsigned long pcicmask; - volatile unsigned long unused5; - volatile unsigned long long p2gmgbase[3]; /* +180 */ - volatile unsigned long long p2giogbase; - volatile unsigned long g2pcfgadrs; /* +1a0 */ - volatile unsigned long g2pcfgdata; - volatile unsigned long unused6[8]; - volatile unsigned long g2pintack; - volatile unsigned long g2pspc; - volatile unsigned long unused7[12]; /* +1d0 */ - volatile unsigned long long pdmca; /* +200 */ - volatile unsigned long long pdmga; - volatile unsigned long long pdmpa; - volatile unsigned long long pdmctr; - volatile unsigned long long pdmcfg; /* +220 */ - volatile unsigned long long pdmsts; -}; - -struct tx4938_aclc_reg { - volatile unsigned long acctlen; - volatile unsigned long acctldis; - volatile unsigned long acregacc; - volatile unsigned long unused0; - volatile unsigned long acintsts; - volatile unsigned long acintmsts; - volatile unsigned long acinten; - volatile unsigned long acintdis; - volatile unsigned long acsemaph; - volatile unsigned long unused1[7]; - volatile unsigned long acgpidat; - volatile unsigned long acgpodat; - volatile unsigned long acslten; - volatile unsigned long acsltdis; - volatile unsigned long acfifosts; - volatile unsigned long unused2[11]; - volatile unsigned long acdmasts; - volatile unsigned long acdmasel; - volatile unsigned long unused3[6]; - volatile unsigned long acaudodat; - volatile unsigned long acsurrdat; - volatile unsigned long accentdat; - volatile unsigned long aclfedat; - volatile unsigned long acaudiat; - volatile unsigned long unused4; - volatile unsigned long acmodoat; - volatile unsigned long acmodidat; - volatile unsigned long unused5[15]; - volatile unsigned long acrevid; -}; - - -struct tx4938_tmr_reg { - volatile unsigned long tcr; - volatile unsigned long tisr; - volatile unsigned long cpra; - volatile unsigned long cprb; - volatile unsigned long itmr; - volatile unsigned long unused0[3]; - volatile unsigned long ccdr; - volatile unsigned long unused1[3]; - volatile unsigned long pgmr; - volatile unsigned long unused2[3]; - volatile unsigned long wtmr; - volatile unsigned long unused3[43]; - volatile unsigned long trr; -}; - -struct tx4938_sio_reg { - volatile unsigned long lcr; - volatile unsigned long dicr; - volatile unsigned long disr; - volatile unsigned long cisr; - volatile unsigned long fcr; - volatile unsigned long flcr; - volatile unsigned long bgr; - volatile unsigned long tfifo; - volatile unsigned long rfifo; -}; - -struct tx4938_ndfmc_reg { - endian_def_l2(unused0, dtr); - endian_def_l2(unused1, mcr); - endian_def_l2(unused2, sr); - endian_def_l2(unused3, isr); - endian_def_l2(unused4, imr); - endian_def_l2(unused5, spr); - endian_def_l2(unused6, rstr); -}; - -struct tx4938_spi_reg { - volatile unsigned long mcr; - volatile unsigned long cr0; - volatile unsigned long cr1; - volatile unsigned long fs; - volatile unsigned long unused1; - volatile unsigned long sr; - volatile unsigned long dr; - volatile unsigned long unused2; -}; - -struct tx4938_sramc_reg { - volatile unsigned long long cr; -}; - -struct tx4938_ccfg_reg { - volatile unsigned long long ccfg; - volatile unsigned long long crir; - volatile unsigned long long pcfg; - volatile unsigned long long tear; - volatile unsigned long long clkctr; - volatile unsigned long long unused0; - volatile unsigned long long garbc; - volatile unsigned long long unused1; - volatile unsigned long long unused2; - volatile unsigned long long ramp; - volatile unsigned long long unused3; - volatile unsigned long long jmpadr; -}; - -#undef endian_def_l2 -#undef endian_def_s2 -#undef endian_def_sb2 -#undef endian_def_b2s -#undef endian_def_b4 - -#endif /* __ASSEMBLY__ */ - -/* - * NDFMC - */ - -/* NDFMCR : NDFMC Mode Control */ -#define TX4938_NDFMCR_WE 0x80 -#define TX4938_NDFMCR_ECC_ALL 0x60 -#define TX4938_NDFMCR_ECC_RESET 0x60 -#define TX4938_NDFMCR_ECC_READ 0x40 -#define TX4938_NDFMCR_ECC_ON 0x20 -#define TX4938_NDFMCR_ECC_OFF 0x00 -#define TX4938_NDFMCR_CE 0x10 -#define TX4938_NDFMCR_BSPRT 0x04 -#define TX4938_NDFMCR_ALE 0x02 -#define TX4938_NDFMCR_CLE 0x01 - -/* NDFMCR : NDFMC Status */ -#define TX4938_NDFSR_BUSY 0x80 - -/* NDFMCR : NDFMC Reset */ -#define TX4938_NDFRSTR_RST 0x01 - -/* - * IRC - */ - -#define TX4938_IR_ECCERR 0 -#define TX4938_IR_WTOERR 1 -#define TX4938_NUM_IR_INT 6 -#define TX4938_IR_INT(n) (2 + (n)) -#define TX4938_NUM_IR_SIO 2 -#define TX4938_IR_SIO(n) (8 + (n)) -#define TX4938_NUM_IR_DMA 4 -#define TX4938_IR_DMA(ch, n) ((ch ? 27 : 10) + (n)) /* 10-13, 27-30 */ -#define TX4938_IR_PIO 14 -#define TX4938_IR_PDMAC 15 -#define TX4938_IR_PCIC 16 -#define TX4938_NUM_IR_TMR 3 -#define TX4938_IR_TMR(n) (17 + (n)) -#define TX4938_IR_NDFMC 21 -#define TX4938_IR_PCIERR 22 -#define TX4938_IR_PCIPME 23 -#define TX4938_IR_ACLC 24 -#define TX4938_IR_ACLCPME 25 -#define TX4938_IR_PCIC1 26 -#define TX4938_IR_SPI 31 -#define TX4938_NUM_IR 32 -/* multiplex */ -#define TX4938_IR_ETH0 TX4938_IR_INT(4) -#define TX4938_IR_ETH1 TX4938_IR_INT(3) - -/* - * CCFG - */ -/* CCFG : Chip Configuration */ -#define TX4938_CCFG_WDRST _CONST64(0x0000020000000000) -#define TX4938_CCFG_WDREXEN _CONST64(0x0000010000000000) -#define TX4938_CCFG_BCFG_MASK _CONST64(0x000000ff00000000) -#define TX4938_CCFG_TINTDIS 0x01000000 -#define TX4938_CCFG_PCI66 0x00800000 -#define TX4938_CCFG_PCIMODE 0x00400000 -#define TX4938_CCFG_PCI1_66 0x00200000 -#define TX4938_CCFG_DIVMODE_MASK 0x001e0000 -#define TX4938_CCFG_DIVMODE_2 (0x4 << 17) -#define TX4938_CCFG_DIVMODE_2_5 (0xf << 17) -#define TX4938_CCFG_DIVMODE_3 (0x5 << 17) -#define TX4938_CCFG_DIVMODE_4 (0x6 << 17) -#define TX4938_CCFG_DIVMODE_4_5 (0xd << 17) -#define TX4938_CCFG_DIVMODE_8 (0x0 << 17) -#define TX4938_CCFG_DIVMODE_10 (0xb << 17) -#define TX4938_CCFG_DIVMODE_12 (0x1 << 17) -#define TX4938_CCFG_DIVMODE_16 (0x2 << 17) -#define TX4938_CCFG_DIVMODE_18 (0x9 << 17) -#define TX4938_CCFG_BEOW 0x00010000 -#define TX4938_CCFG_WR 0x00008000 -#define TX4938_CCFG_TOE 0x00004000 -#define TX4938_CCFG_PCIXARB 0x00002000 -#define TX4938_CCFG_PCIDIVMODE_MASK 0x00001c00 -#define TX4938_CCFG_PCIDIVMODE_4 (0x1 << 10) -#define TX4938_CCFG_PCIDIVMODE_4_5 (0x3 << 10) -#define TX4938_CCFG_PCIDIVMODE_5 (0x5 << 10) -#define TX4938_CCFG_PCIDIVMODE_5_5 (0x7 << 10) -#define TX4938_CCFG_PCIDIVMODE_8 (0x0 << 10) -#define TX4938_CCFG_PCIDIVMODE_9 (0x2 << 10) -#define TX4938_CCFG_PCIDIVMODE_10 (0x4 << 10) -#define TX4938_CCFG_PCIDIVMODE_11 (0x6 << 10) -#define TX4938_CCFG_PCI1DMD 0x00000100 -#define TX4938_CCFG_SYSSP_MASK 0x000000c0 -#define TX4938_CCFG_ENDIAN 0x00000004 -#define TX4938_CCFG_HALT 0x00000002 -#define TX4938_CCFG_ACEHOLD 0x00000001 - -/* PCFG : Pin Configuration */ -#define TX4938_PCFG_ETH0_SEL _CONST64(0x8000000000000000) -#define TX4938_PCFG_ETH1_SEL _CONST64(0x4000000000000000) -#define TX4938_PCFG_ATA_SEL _CONST64(0x2000000000000000) -#define TX4938_PCFG_ISA_SEL _CONST64(0x1000000000000000) -#define TX4938_PCFG_SPI_SEL _CONST64(0x0800000000000000) -#define TX4938_PCFG_NDF_SEL _CONST64(0x0400000000000000) -#define TX4938_PCFG_SDCLKDLY_MASK 0x30000000 -#define TX4938_PCFG_SDCLKDLY(d) ((d)<<28) -#define TX4938_PCFG_SYSCLKEN 0x08000000 -#define TX4938_PCFG_SDCLKEN_ALL 0x07800000 -#define TX4938_PCFG_SDCLKEN(ch) (0x00800000<<(ch)) -#define TX4938_PCFG_PCICLKEN_ALL 0x003f0000 -#define TX4938_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) -#define TX4938_PCFG_SEL2 0x00000200 -#define TX4938_PCFG_SEL1 0x00000100 -#define TX4938_PCFG_DMASEL_ALL 0x0000000f -#define TX4938_PCFG_DMASEL0_DRQ0 0x00000000 -#define TX4938_PCFG_DMASEL0_SIO1 0x00000001 -#define TX4938_PCFG_DMASEL1_DRQ1 0x00000000 -#define TX4938_PCFG_DMASEL1_SIO1 0x00000002 -#define TX4938_PCFG_DMASEL2_DRQ2 0x00000000 -#define TX4938_PCFG_DMASEL2_SIO0 0x00000004 -#define TX4938_PCFG_DMASEL3_DRQ3 0x00000000 -#define TX4938_PCFG_DMASEL3_SIO0 0x00000008 - -/* CLKCTR : Clock Control */ -#define TX4938_CLKCTR_NDFCKD _CONST64(0x0001000000000000) -#define TX4938_CLKCTR_NDFRST _CONST64(0x0000000100000000) -#define TX4938_CLKCTR_ETH1CKD 0x80000000 -#define TX4938_CLKCTR_ETH0CKD 0x40000000 -#define TX4938_CLKCTR_SPICKD 0x20000000 -#define TX4938_CLKCTR_SRAMCKD 0x10000000 -#define TX4938_CLKCTR_PCIC1CKD 0x08000000 -#define TX4938_CLKCTR_DMA1CKD 0x04000000 -#define TX4938_CLKCTR_ACLCKD 0x02000000 -#define TX4938_CLKCTR_PIOCKD 0x01000000 -#define TX4938_CLKCTR_DMACKD 0x00800000 -#define TX4938_CLKCTR_PCICKD 0x00400000 -#define TX4938_CLKCTR_TM0CKD 0x00100000 -#define TX4938_CLKCTR_TM1CKD 0x00080000 -#define TX4938_CLKCTR_TM2CKD 0x00040000 -#define TX4938_CLKCTR_SIO0CKD 0x00020000 -#define TX4938_CLKCTR_SIO1CKD 0x00010000 -#define TX4938_CLKCTR_ETH1RST 0x00008000 -#define TX4938_CLKCTR_ETH0RST 0x00004000 -#define TX4938_CLKCTR_SPIRST 0x00002000 -#define TX4938_CLKCTR_SRAMRST 0x00001000 -#define TX4938_CLKCTR_PCIC1RST 0x00000800 -#define TX4938_CLKCTR_DMA1RST 0x00000400 -#define TX4938_CLKCTR_ACLRST 0x00000200 -#define TX4938_CLKCTR_PIORST 0x00000100 -#define TX4938_CLKCTR_DMARST 0x00000080 -#define TX4938_CLKCTR_PCIRST 0x00000040 -#define TX4938_CLKCTR_TM0RST 0x00000010 -#define TX4938_CLKCTR_TM1RST 0x00000008 -#define TX4938_CLKCTR_TM2RST 0x00000004 -#define TX4938_CLKCTR_SIO0RST 0x00000002 -#define TX4938_CLKCTR_SIO1RST 0x00000001 - -/* bits for G2PSTATUS/G2PMASK */ -#define TX4938_PCIC_G2PSTATUS_ALL 0x00000003 -#define TX4938_PCIC_G2PSTATUS_TTOE 0x00000002 -#define TX4938_PCIC_G2PSTATUS_RTOE 0x00000001 - -/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ -#define TX4938_PCIC_PCISTATUS_ALL 0x0000f900 - -/* bits for PBACFG */ -#define TX4938_PCIC_PBACFG_FIXPA 0x00000008 -#define TX4938_PCIC_PBACFG_RPBA 0x00000004 -#define TX4938_PCIC_PBACFG_PBAEN 0x00000002 -#define TX4938_PCIC_PBACFG_BMCEN 0x00000001 - -/* bits for G2PMnGBASE */ -#define TX4938_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for G2PIOGBASE */ -#define TX4938_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for PCICSTATUS/PCICMASK */ -#define TX4938_PCIC_PCICSTATUS_ALL 0x000007b8 -#define TX4938_PCIC_PCICSTATUS_PME 0x00000400 -#define TX4938_PCIC_PCICSTATUS_TLB 0x00000200 -#define TX4938_PCIC_PCICSTATUS_NIB 0x00000100 -#define TX4938_PCIC_PCICSTATUS_ZIB 0x00000080 -#define TX4938_PCIC_PCICSTATUS_PERR 0x00000020 -#define TX4938_PCIC_PCICSTATUS_SERR 0x00000010 -#define TX4938_PCIC_PCICSTATUS_GBE 0x00000008 -#define TX4938_PCIC_PCICSTATUS_IWB 0x00000002 -#define TX4938_PCIC_PCICSTATUS_E2PDONE 0x00000001 - -/* bits for PCICCFG */ -#define TX4938_PCIC_PCICCFG_GBWC_MASK 0x0fff0000 -#define TX4938_PCIC_PCICCFG_HRST 0x00000800 -#define TX4938_PCIC_PCICCFG_SRST 0x00000400 -#define TX4938_PCIC_PCICCFG_IRBER 0x00000200 -#define TX4938_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch)) -#define TX4938_PCIC_PCICCFG_G2PM0EN 0x00000100 -#define TX4938_PCIC_PCICCFG_G2PM1EN 0x00000080 -#define TX4938_PCIC_PCICCFG_G2PM2EN 0x00000040 -#define TX4938_PCIC_PCICCFG_G2PIOEN 0x00000020 -#define TX4938_PCIC_PCICCFG_TCAR 0x00000010 -#define TX4938_PCIC_PCICCFG_ICAEN 0x00000008 - -/* bits for P2GMnGBASE */ -#define TX4938_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) -#define TX4938_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) - -/* bits for P2GIOGBASE */ -#define TX4938_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) -#define TX4938_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) - -#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) -#define TX4938_PCIC_MAX_DEVNU TX4938_PCIC_IDSEL_AD_TO_SLOT(32) - -/* bits for PDMCFG */ -#define TX4938_PCIC_PDMCFG_RSTFIFO 0x00200000 -#define TX4938_PCIC_PDMCFG_EXFER 0x00100000 -#define TX4938_PCIC_PDMCFG_REQDLY_MASK 0x00003800 -#define TX4938_PCIC_PDMCFG_REQDLY_NONE (0 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_16 (1 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_32 (2 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_64 (3 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_128 (4 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_256 (5 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_512 (6 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_1024 (7 << 11) -#define TX4938_PCIC_PDMCFG_ERRIE 0x00000400 -#define TX4938_PCIC_PDMCFG_NCCMPIE 0x00000200 -#define TX4938_PCIC_PDMCFG_NTCMPIE 0x00000100 -#define TX4938_PCIC_PDMCFG_CHNEN 0x00000080 -#define TX4938_PCIC_PDMCFG_XFRACT 0x00000040 -#define TX4938_PCIC_PDMCFG_BSWAP 0x00000020 -#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c -#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000 -#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004 -#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008 -#define TX4938_PCIC_PDMCFG_XFRDIRC 0x00000002 -#define TX4938_PCIC_PDMCFG_CHRST 0x00000001 - -/* bits for PDMSTS */ -#define TX4938_PCIC_PDMSTS_REQCNT_MASK 0x3f000000 -#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000 -#define TX4938_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000 -#define TX4938_PCIC_PDMSTS_FIFORP_MASK 0x00030000 -#define TX4938_PCIC_PDMSTS_ERRINT 0x00000800 -#define TX4938_PCIC_PDMSTS_DONEINT 0x00000400 -#define TX4938_PCIC_PDMSTS_CHNEN 0x00000200 -#define TX4938_PCIC_PDMSTS_XFRACT 0x00000100 -#define TX4938_PCIC_PDMSTS_ACCMP 0x00000080 -#define TX4938_PCIC_PDMSTS_NCCMP 0x00000040 -#define TX4938_PCIC_PDMSTS_NTCMP 0x00000020 -#define TX4938_PCIC_PDMSTS_CFGERR 0x00000008 -#define TX4938_PCIC_PDMSTS_PCIERR 0x00000004 -#define TX4938_PCIC_PDMSTS_CHNERR 0x00000002 -#define TX4938_PCIC_PDMSTS_DATAERR 0x00000001 -#define TX4938_PCIC_PDMSTS_ALL_CMP 0x000000e0 -#define TX4938_PCIC_PDMSTS_ALL_ERR 0x0000000f - -/* - * DMA - */ -/* bits for MCR */ -#define TX4938_DMA_MCR_EIS(ch) (0x10000000<<(ch)) -#define TX4938_DMA_MCR_DIS(ch) (0x01000000<<(ch)) -#define TX4938_DMA_MCR_RSFIF 0x00000080 -#define TX4938_DMA_MCR_FIFUM(ch) (0x00000008<<(ch)) -#define TX4938_DMA_MCR_RPRT 0x00000002 -#define TX4938_DMA_MCR_MSTEN 0x00000001 - -/* bits for CCRn */ -#define TX4938_DMA_CCR_IMMCHN 0x20000000 -#define TX4938_DMA_CCR_USEXFSZ 0x10000000 -#define TX4938_DMA_CCR_LE 0x08000000 -#define TX4938_DMA_CCR_DBINH 0x04000000 -#define TX4938_DMA_CCR_SBINH 0x02000000 -#define TX4938_DMA_CCR_CHRST 0x01000000 -#define TX4938_DMA_CCR_RVBYTE 0x00800000 -#define TX4938_DMA_CCR_ACKPOL 0x00400000 -#define TX4938_DMA_CCR_REQPL 0x00200000 -#define TX4938_DMA_CCR_EGREQ 0x00100000 -#define TX4938_DMA_CCR_CHDN 0x00080000 -#define TX4938_DMA_CCR_DNCTL 0x00060000 -#define TX4938_DMA_CCR_EXTRQ 0x00010000 -#define TX4938_DMA_CCR_INTRQD 0x0000e000 -#define TX4938_DMA_CCR_INTENE 0x00001000 -#define TX4938_DMA_CCR_INTENC 0x00000800 -#define TX4938_DMA_CCR_INTENT 0x00000400 -#define TX4938_DMA_CCR_CHNEN 0x00000200 -#define TX4938_DMA_CCR_XFACT 0x00000100 -#define TX4938_DMA_CCR_SMPCHN 0x00000020 -#define TX4938_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c) -#define TX4938_DMA_CCR_XFSZ_1W TX4938_DMA_CCR_XFSZ(2) -#define TX4938_DMA_CCR_XFSZ_2W TX4938_DMA_CCR_XFSZ(3) -#define TX4938_DMA_CCR_XFSZ_4W TX4938_DMA_CCR_XFSZ(4) -#define TX4938_DMA_CCR_XFSZ_8W TX4938_DMA_CCR_XFSZ(5) -#define TX4938_DMA_CCR_XFSZ_16W TX4938_DMA_CCR_XFSZ(6) -#define TX4938_DMA_CCR_XFSZ_32W TX4938_DMA_CCR_XFSZ(7) -#define TX4938_DMA_CCR_MEMIO 0x00000002 -#define TX4938_DMA_CCR_SNGAD 0x00000001 - -/* bits for CSRn */ -#define TX4938_DMA_CSR_CHNEN 0x00000400 -#define TX4938_DMA_CSR_STLXFER 0x00000200 -#define TX4938_DMA_CSR_CHNACT 0x00000100 -#define TX4938_DMA_CSR_ABCHC 0x00000080 -#define TX4938_DMA_CSR_NCHNC 0x00000040 -#define TX4938_DMA_CSR_NTRNFC 0x00000020 -#define TX4938_DMA_CSR_EXTDN 0x00000010 -#define TX4938_DMA_CSR_CFERR 0x00000008 -#define TX4938_DMA_CSR_CHERR 0x00000004 -#define TX4938_DMA_CSR_DESERR 0x00000002 -#define TX4938_DMA_CSR_SORERR 0x00000001 - -#ifndef __ASSEMBLY__ - -#define tx4938_sdramcptr ((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG) -#define tx4938_ebuscptr ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG) -#define tx4938_dmaptr(ch) ((struct tx4938_dma_reg *)TX4938_DMA_REG(ch)) -#define tx4938_ndfmcptr ((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG) -#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG) -#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG) -#define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG) -#define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch)) -#define tx4938_pioptr ((struct txx9_pio_reg __iomem *)TX4938_PIO_REG) -#define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG) -#define tx4938_spiptr ((struct tx4938_spi_reg *)TX4938_SPI_REG) -#define tx4938_sramcptr ((struct tx4938_sramc_reg *)TX4938_SRAMC_REG) - - -#define TX4938_REV_MAJ_MIN() ((unsigned long)tx4938_ccfgptr->crir & 0x00ff) -#define TX4938_REV_PCODE() ((unsigned long)tx4938_ccfgptr->crir >> 16) - -#define TX4938_SDRAMC_BA(ch) ((tx4938_sdramcptr->cr[ch] >> 49) << 21) -#define TX4938_SDRAMC_SIZE(ch) (((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21) - -#define TX4938_EBUSC_BA(ch) ((tx4938_ebuscptr->cr[ch] >> 48) << 20) -#define TX4938_EBUSC_SIZE(ch) \ - (0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf)) - - -#endif /* !__ASSEMBLY__ */ - -#endif diff --git a/include/asm-mips/txx9/jmr3927.h b/include/asm-mips/txx9/jmr3927.h new file mode 100644 index 0000000..29e5498 --- /dev/null +++ b/include/asm-mips/txx9/jmr3927.h @@ -0,0 +1,177 @@ +/* + * Defines for the TJSYS JMR-TX3927 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2001 Toshiba Corporation + */ +#ifndef __ASM_TXX9_JMR3927_H +#define __ASM_TXX9_JMR3927_H + +#include +#include +#include +#include + +/* CS */ +#define JMR3927_ROMCE0 0x1fc00000 /* 4M */ +#define JMR3927_ROMCE1 0x1e000000 /* 4M */ +#define JMR3927_ROMCE2 0x14000000 /* 16M */ +#define JMR3927_ROMCE3 0x10000000 /* 64M */ +#define JMR3927_ROMCE5 0x1d000000 /* 4M */ +#define JMR3927_SDCS0 0x00000000 /* 32M */ +#define JMR3927_SDCS1 0x02000000 /* 32M */ +/* PCI Direct Mappings */ + +#define JMR3927_PCIMEM 0x08000000 +#define JMR3927_PCIMEM_SIZE 0x08000000 /* 128M */ +#define JMR3927_PCIIO 0x15000000 +#define JMR3927_PCIIO_SIZE 0x01000000 /* 16M */ + +#define JMR3927_SDRAM_SIZE 0x02000000 /* 32M */ +#define JMR3927_PORT_BASE KSEG1 + +/* Address map (virtual address) */ +#define JMR3927_ROM0_BASE (KSEG1 + JMR3927_ROMCE0) +#define JMR3927_ROM1_BASE (KSEG1 + JMR3927_ROMCE1) +#define JMR3927_IOC_BASE (KSEG1 + JMR3927_ROMCE2) +#define JMR3927_PCIMEM_BASE (KSEG1 + JMR3927_PCIMEM) +#define JMR3927_PCIIO_BASE (KSEG1 + JMR3927_PCIIO) + +#define JMR3927_IOC_REV_ADDR (JMR3927_IOC_BASE + 0x00000000) +#define JMR3927_IOC_NVRAMB_ADDR (JMR3927_IOC_BASE + 0x00010000) +#define JMR3927_IOC_LED_ADDR (JMR3927_IOC_BASE + 0x00020000) +#define JMR3927_IOC_DIPSW_ADDR (JMR3927_IOC_BASE + 0x00030000) +#define JMR3927_IOC_BREV_ADDR (JMR3927_IOC_BASE + 0x00040000) +#define JMR3927_IOC_DTR_ADDR (JMR3927_IOC_BASE + 0x00050000) +#define JMR3927_IOC_INTS1_ADDR (JMR3927_IOC_BASE + 0x00080000) +#define JMR3927_IOC_INTS2_ADDR (JMR3927_IOC_BASE + 0x00090000) +#define JMR3927_IOC_INTM_ADDR (JMR3927_IOC_BASE + 0x000a0000) +#define JMR3927_IOC_INTP_ADDR (JMR3927_IOC_BASE + 0x000b0000) +#define JMR3927_IOC_RESET_ADDR (JMR3927_IOC_BASE + 0x000f0000) + +/* Flash ROM */ +#define JMR3927_FLASH_BASE (JMR3927_ROM0_BASE) +#define JMR3927_FLASH_SIZE 0x00400000 + +/* bits for IOC_REV/IOC_BREV (high byte) */ +#define JMR3927_IDT_MASK 0xfc +#define JMR3927_REV_MASK 0x03 +#define JMR3927_IOC_IDT 0xe0 + +/* bits for IOC_INTS1/IOC_INTS2/IOC_INTM/IOC_INTP (high byte) */ +#define JMR3927_IOC_INTB_PCIA 0 +#define JMR3927_IOC_INTB_PCIB 1 +#define JMR3927_IOC_INTB_PCIC 2 +#define JMR3927_IOC_INTB_PCID 3 +#define JMR3927_IOC_INTB_MODEM 4 +#define JMR3927_IOC_INTB_INT6 5 +#define JMR3927_IOC_INTB_INT7 6 +#define JMR3927_IOC_INTB_SOFT 7 +#define JMR3927_IOC_INTF_PCIA (1 << JMR3927_IOC_INTF_PCIA) +#define JMR3927_IOC_INTF_PCIB (1 << JMR3927_IOC_INTB_PCIB) +#define JMR3927_IOC_INTF_PCIC (1 << JMR3927_IOC_INTB_PCIC) +#define JMR3927_IOC_INTF_PCID (1 << JMR3927_IOC_INTB_PCID) +#define JMR3927_IOC_INTF_MODEM (1 << JMR3927_IOC_INTB_MODEM) +#define JMR3927_IOC_INTF_INT6 (1 << JMR3927_IOC_INTB_INT6) +#define JMR3927_IOC_INTF_INT7 (1 << JMR3927_IOC_INTB_INT7) +#define JMR3927_IOC_INTF_SOFT (1 << JMR3927_IOC_INTB_SOFT) + +/* bits for IOC_RESET (high byte) */ +#define JMR3927_IOC_RESET_CPU 1 +#define JMR3927_IOC_RESET_PCI 2 + +#if defined(__BIG_ENDIAN) +#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)(a)) = (d)) +#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)(a)) +#elif defined(__LITTLE_ENDIAN) +#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)((a)^1)) = (d)) +#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)((a)^1)) +#else +#error "No Endian" +#endif + +/* LED macro */ +#define jmr3927_led_set(n/*0-16*/) jmr3927_ioc_reg_out(~(n), JMR3927_IOC_LED_ADDR) + +#define jmr3927_led_and_set(n/*0-16*/) jmr3927_ioc_reg_out((~(n)) & jmr3927_ioc_reg_in(JMR3927_IOC_LED_ADDR), JMR3927_IOC_LED_ADDR) + +/* DIPSW4 macro */ +#define jmr3927_dipsw1() (gpio_get_value(11) == 0) +#define jmr3927_dipsw2() (gpio_get_value(10) == 0) +#define jmr3927_dipsw3() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 2) == 0) +#define jmr3927_dipsw4() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 1) == 0) + +/* + * IRQ mappings + */ + +/* These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an JMR machine. Add new 'spaces' as new + * IRQ hardware is supported. + */ +#define JMR3927_NR_IRQ_IRC 16 /* On-Chip IRC */ +#define JMR3927_NR_IRQ_IOC 8 /* PCI/MODEM/INT[6:7] */ + +#define JMR3927_IRQ_IRC TXX9_IRQ_BASE +#define JMR3927_IRQ_IOC (JMR3927_IRQ_IRC + JMR3927_NR_IRQ_IRC) +#define JMR3927_IRQ_END (JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC) + +#define JMR3927_IRQ_IRC_INT0 (JMR3927_IRQ_IRC + TX3927_IR_INT0) +#define JMR3927_IRQ_IRC_INT1 (JMR3927_IRQ_IRC + TX3927_IR_INT1) +#define JMR3927_IRQ_IRC_INT2 (JMR3927_IRQ_IRC + TX3927_IR_INT2) +#define JMR3927_IRQ_IRC_INT3 (JMR3927_IRQ_IRC + TX3927_IR_INT3) +#define JMR3927_IRQ_IRC_INT4 (JMR3927_IRQ_IRC + TX3927_IR_INT4) +#define JMR3927_IRQ_IRC_INT5 (JMR3927_IRQ_IRC + TX3927_IR_INT5) +#define JMR3927_IRQ_IRC_SIO0 (JMR3927_IRQ_IRC + TX3927_IR_SIO0) +#define JMR3927_IRQ_IRC_SIO1 (JMR3927_IRQ_IRC + TX3927_IR_SIO1) +#define JMR3927_IRQ_IRC_SIO(ch) (JMR3927_IRQ_IRC + TX3927_IR_SIO(ch)) +#define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA) +#define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO) +#define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI) +#define JMR3927_IRQ_IRC_TMR(ch) (JMR3927_IRQ_IRC + TX3927_IR_TMR(ch)) +#define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA) +#define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB) +#define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC) +#define JMR3927_IRQ_IOC_PCID (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCID) +#define JMR3927_IRQ_IOC_MODEM (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_MODEM) +#define JMR3927_IRQ_IOC_INT6 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT6) +#define JMR3927_IRQ_IOC_INT7 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT7) +#define JMR3927_IRQ_IOC_SOFT (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_SOFT) + +/* IOC (PCI, MODEM) */ +#define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1 +/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */ +#define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3 + +/* Clocks */ +#define JMR3927_CORECLK 132710400 /* 132.7MHz */ +#define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */ +#define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */ + +/* + * TX3927 Pin Configuration: + * + * PCFG bits Avail Dead + * SELSIO[1:0]:11 RXD[1:0], TXD[1:0] PIO[6:3] + * SELSIOC[0]:1 CTS[0], RTS[0] INT[5:4] + * SELSIOC[1]:0,SELDSF:0, GSDAO[0],GPCST[3] CTS[1], RTS[1],DSF, + * GDBGE* PIO[2:1] + * SELDMA[2]:1 DMAREQ[2],DMAACK[2] PIO[13:12] + * SELTMR[2:0]:000 TIMER[1:0] + * SELCS:0,SELDMA[1]:0 PIO[11;10] SDCS_CE[7:6], + * DMAREQ[1],DMAACK[1] + * SELDMA[0]:1 DMAREQ[0],DMAACK[0] PIO[9:8] + * SELDMA[3]:1 DMAREQ[3],DMAACK[3] PIO[15:14] + * SELDONE:1 DMADONE PIO[7] + * + * Usable pins are: + * RXD[1;0],TXD[1:0],CTS[0],RTS[0], + * DMAREQ[0,2,3],DMAACK[0,2,3],DMADONE,PIO[0,10,11] + * INT[3:0] + */ + +#endif /* __ASM_TXX9_JMR3927_H */ diff --git a/include/asm-mips/txx9/rbtx4927.h b/include/asm-mips/txx9/rbtx4927.h new file mode 100644 index 0000000..5531342 --- /dev/null +++ b/include/asm-mips/txx9/rbtx4927.h @@ -0,0 +1,49 @@ +/* + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __ASM_TXX9_RBTX4927_H +#define __ASM_TXX9_RBTX4927_H + +#include + +#ifdef CONFIG_PCI +#define TBTX4927_ISA_IO_OFFSET TX4927_PCIIO +#else +#define TBTX4927_ISA_IO_OFFSET 0 +#endif + +#define RBTX4927_SW_RESET_DO (void __iomem *)0xbc00f000UL +#define RBTX4927_SW_RESET_DO_SET 0x01 + +#define RBTX4927_SW_RESET_ENABLE (void __iomem *)0xbc00f002UL +#define RBTX4927_SW_RESET_ENABLE_SET 0x01 + +#define RBTX4927_RTL_8019_BASE (0x1c020280-TBTX4927_ISA_IO_OFFSET) +#define RBTX4927_RTL_8019_IRQ (TX4927_IRQ_PIC_BEG + 5) + +int toshiba_rbtx4927_irq_nested(int sw_irq); + +#endif /* __ASM_TXX9_RBTX4927_H */ diff --git a/include/asm-mips/txx9/rbtx4938.h b/include/asm-mips/txx9/rbtx4938.h new file mode 100644 index 0000000..8450f73 --- /dev/null +++ b/include/asm-mips/txx9/rbtx4938.h @@ -0,0 +1,167 @@ +/* + * Definitions for TX4937/TX4938 + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#ifndef __ASM_TXX9_RBTX4938_H +#define __ASM_TXX9_RBTX4938_H + +#include +#include +#include + +/* CS */ +#define RBTX4938_CE0 0x1c000000 /* 64M */ +#define RBTX4938_CE2 0x17f00000 /* 1M */ + +/* Address map */ +#define RBTX4938_FPGA_REG_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000000) +#define RBTX4938_FPGA_REV_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000002) +#define RBTX4938_CONFIG1_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000004) +#define RBTX4938_CONFIG2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000006) +#define RBTX4938_CONFIG3_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000008) +#define RBTX4938_LED_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001000) +#define RBTX4938_DIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001002) +#define RBTX4938_BDIPSW_ADDR (KSEG1 + RBTX4938_CE2 + 0x00001004) +#define RBTX4938_IMASK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002000) +#define RBTX4938_IMASK2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002002) +#define RBTX4938_INTPOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002004) +#define RBTX4938_ISTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002006) +#define RBTX4938_ISTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x00002008) +#define RBTX4938_IMSTAT_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200a) +#define RBTX4938_IMSTAT2_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000200c) +#define RBTX4938_SOFTINT_ADDR (KSEG1 + RBTX4938_CE2 + 0x00003000) +#define RBTX4938_PIOSEL_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005000) +#define RBTX4938_SPICS_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005002) +#define RBTX4938_SFPWR_ADDR (KSEG1 + RBTX4938_CE2 + 0x00005008) +#define RBTX4938_SFVOL_ADDR (KSEG1 + RBTX4938_CE2 + 0x0000500a) +#define RBTX4938_SOFTRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007000) +#define RBTX4938_SOFTRESETLOCK_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007002) +#define RBTX4938_PCIRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007004) +#define RBTX4938_ETHER_BASE (KSEG1 + RBTX4938_CE2 + 0x00020000) + +/* Ethernet port address (Jumperless Mode (W12:Open)) */ +#define RBTX4938_ETHER_ADDR (RBTX4938_ETHER_BASE + 0x280) + +/* bits for ISTAT/IMASK/IMSTAT */ +#define RBTX4938_INTB_PCID 0 +#define RBTX4938_INTB_PCIC 1 +#define RBTX4938_INTB_PCIB 2 +#define RBTX4938_INTB_PCIA 3 +#define RBTX4938_INTB_RTC 4 +#define RBTX4938_INTB_ATA 5 +#define RBTX4938_INTB_MODEM 6 +#define RBTX4938_INTB_SWINT 7 +#define RBTX4938_INTF_PCID (1 << RBTX4938_INTB_PCID) +#define RBTX4938_INTF_PCIC (1 << RBTX4938_INTB_PCIC) +#define RBTX4938_INTF_PCIB (1 << RBTX4938_INTB_PCIB) +#define RBTX4938_INTF_PCIA (1 << RBTX4938_INTB_PCIA) +#define RBTX4938_INTF_RTC (1 << RBTX4938_INTB_RTC) +#define RBTX4938_INTF_ATA (1 << RBTX4938_INTB_ATA) +#define RBTX4938_INTF_MODEM (1 << RBTX4938_INTB_MODEM) +#define RBTX4938_INTF_SWINT (1 << RBTX4938_INTB_SWINT) + +#define rbtx4938_fpga_rev_addr ((__u8 __iomem *)RBTX4938_FPGA_REV_ADDR) +#define rbtx4938_led_addr ((__u8 __iomem *)RBTX4938_LED_ADDR) +#define rbtx4938_dipsw_addr ((__u8 __iomem *)RBTX4938_DIPSW_ADDR) +#define rbtx4938_bdipsw_addr ((__u8 __iomem *)RBTX4938_BDIPSW_ADDR) +#define rbtx4938_imask_addr ((__u8 __iomem *)RBTX4938_IMASK_ADDR) +#define rbtx4938_imask2_addr ((__u8 __iomem *)RBTX4938_IMASK2_ADDR) +#define rbtx4938_intpol_addr ((__u8 __iomem *)RBTX4938_INTPOL_ADDR) +#define rbtx4938_istat_addr ((__u8 __iomem *)RBTX4938_ISTAT_ADDR) +#define rbtx4938_istat2_addr ((__u8 __iomem *)RBTX4938_ISTAT2_ADDR) +#define rbtx4938_imstat_addr ((__u8 __iomem *)RBTX4938_IMSTAT_ADDR) +#define rbtx4938_imstat2_addr ((__u8 __iomem *)RBTX4938_IMSTAT2_ADDR) +#define rbtx4938_softint_addr ((__u8 __iomem *)RBTX4938_SOFTINT_ADDR) +#define rbtx4938_piosel_addr ((__u8 __iomem *)RBTX4938_PIOSEL_ADDR) +#define rbtx4938_spics_addr ((__u8 __iomem *)RBTX4938_SPICS_ADDR) +#define rbtx4938_sfpwr_addr ((__u8 __iomem *)RBTX4938_SFPWR_ADDR) +#define rbtx4938_sfvol_addr ((__u8 __iomem *)RBTX4938_SFVOL_ADDR) +#define rbtx4938_softreset_addr ((__u8 __iomem *)RBTX4938_SOFTRESET_ADDR) +#define rbtx4938_softresetlock_addr \ + ((__u8 __iomem *)RBTX4938_SOFTRESETLOCK_ADDR) +#define rbtx4938_pcireset_addr ((__u8 __iomem *)RBTX4938_PCIRESET_ADDR) + +/* + * IRQ mappings + */ + +#define RBTX4938_SOFT_INT0 0 /* not used */ +#define RBTX4938_SOFT_INT1 1 /* not used */ +#define RBTX4938_IRC_INT 2 +#define RBTX4938_TIMER_INT 7 + +/* These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an RBTX4938 machine. Add new 'spaces' as new + * IRQ hardware is supported. + */ +#define RBTX4938_NR_IRQ_LOCAL 8 +#define RBTX4938_NR_IRQ_IRC 32 /* On-Chip IRC */ +#define RBTX4938_NR_IRQ_IOC 8 + +#define TX4938_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE +#define TX4938_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) + +#define TX4938_IRQ_PIC_BEG TXX9_IRQ_BASE +#define TX4938_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) +#define TX4938_IRQ_NEST_EXT_ON_PIC (TX4938_IRQ_PIC_BEG+2) +#define TX4938_IRQ_NEST_PIC_ON_CP0 (TX4938_IRQ_CP0_BEG+2) +#define TX4938_IRQ_USER0 (TX4938_IRQ_CP0_BEG+0) +#define TX4938_IRQ_USER1 (TX4938_IRQ_CP0_BEG+1) +#define TX4938_IRQ_CPU_TIMER (TX4938_IRQ_CP0_BEG+7) + +#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG 0 +#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END 7 + +#define TOSHIBA_RBTX4938_IRQ_IOC_BEG ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */ +#define TOSHIBA_RBTX4938_IRQ_IOC_END ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */ +#define RBTX4938_IRQ_LOCAL TX4938_IRQ_CP0_BEG +#define RBTX4938_IRQ_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL) +#define RBTX4938_IRQ_IOC (RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC) +#define RBTX4938_IRQ_END (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC) + +#define RBTX4938_IRQ_LOCAL_SOFT0 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0) +#define RBTX4938_IRQ_LOCAL_SOFT1 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1) +#define RBTX4938_IRQ_LOCAL_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT) +#define RBTX4938_IRQ_LOCAL_TIMER (RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT) +#define RBTX4938_IRQ_IRC_ECCERR (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR) +#define RBTX4938_IRQ_IRC_WTOERR (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR) +#define RBTX4938_IRQ_IRC_INT(n) (RBTX4938_IRQ_IRC + TX4938_IR_INT(n)) +#define RBTX4938_IRQ_IRC_SIO(n) (RBTX4938_IRQ_IRC + TX4938_IR_SIO(n)) +#define RBTX4938_IRQ_IRC_DMA(ch, n) (RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch, n)) +#define RBTX4938_IRQ_IRC_PIO (RBTX4938_IRQ_IRC + TX4938_IR_PIO) +#define RBTX4938_IRQ_IRC_PDMAC (RBTX4938_IRQ_IRC + TX4938_IR_PDMAC) +#define RBTX4938_IRQ_IRC_PCIC (RBTX4938_IRQ_IRC + TX4938_IR_PCIC) +#define RBTX4938_IRQ_IRC_TMR(n) (RBTX4938_IRQ_IRC + TX4938_IR_TMR(n)) +#define RBTX4938_IRQ_IRC_NDFMC (RBTX4938_IRQ_IRC + TX4938_IR_NDFMC) +#define RBTX4938_IRQ_IRC_PCIERR (RBTX4938_IRQ_IRC + TX4938_IR_PCIERR) +#define RBTX4938_IRQ_IRC_PCIPME (RBTX4938_IRQ_IRC + TX4938_IR_PCIPME) +#define RBTX4938_IRQ_IRC_ACLC (RBTX4938_IRQ_IRC + TX4938_IR_ACLC) +#define RBTX4938_IRQ_IRC_ACLCPME (RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME) +#define RBTX4938_IRQ_IRC_PCIC1 (RBTX4938_IRQ_IRC + TX4938_IR_PCIC1) +#define RBTX4938_IRQ_IRC_SPI (RBTX4938_IRQ_IRC + TX4938_IR_SPI) +#define RBTX4938_IRQ_IOC_PCID (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID) +#define RBTX4938_IRQ_IOC_PCIC (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC) +#define RBTX4938_IRQ_IOC_PCIB (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB) +#define RBTX4938_IRQ_IOC_PCIA (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA) +#define RBTX4938_IRQ_IOC_RTC (RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC) +#define RBTX4938_IRQ_IOC_ATA (RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA) +#define RBTX4938_IRQ_IOC_MODEM (RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM) +#define RBTX4938_IRQ_IOC_SWINT (RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT) + + +/* IOC (PCI, etc) */ +#define RBTX4938_IRQ_IOCINT (TX4938_IRQ_NEST_EXT_ON_PIC) +/* Onboard 10M Ether */ +#define RBTX4938_IRQ_ETHER (TX4938_IRQ_NEST_EXT_ON_PIC + 1) + +#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base) +#define RBTX4938_RTL_8019_IRQ (RBTX4938_IRQ_ETHER) + +#endif /* __ASM_TXX9_RBTX4938_H */ diff --git a/include/asm-mips/txx9/smsc_fdc37m81x.h b/include/asm-mips/txx9/smsc_fdc37m81x.h new file mode 100644 index 0000000..9375e4f --- /dev/null +++ b/include/asm-mips/txx9/smsc_fdc37m81x.h @@ -0,0 +1,67 @@ +/* + * Interface for smsc fdc48m81x Super IO chip + * + * Author: MontaVista Software, Inc. source@mvista.com + * + * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright (C) 2004 MontaVista Software Inc. + * Manish Lachwani, mlachwani@mvista.com + */ + +#ifndef _SMSC_FDC37M81X_H_ +#define _SMSC_FDC37M81X_H_ + +/* Common Registers */ +#define SMSC_FDC37M81X_CONFIG_INDEX 0x00 +#define SMSC_FDC37M81X_CONFIG_DATA 0x01 +#define SMSC_FDC37M81X_CONF 0x02 +#define SMSC_FDC37M81X_INDEX 0x03 +#define SMSC_FDC37M81X_DNUM 0x07 +#define SMSC_FDC37M81X_DID 0x20 +#define SMSC_FDC37M81X_DREV 0x21 +#define SMSC_FDC37M81X_PCNT 0x22 +#define SMSC_FDC37M81X_PMGT 0x23 +#define SMSC_FDC37M81X_OSC 0x24 +#define SMSC_FDC37M81X_CONFPA0 0x26 +#define SMSC_FDC37M81X_CONFPA1 0x27 +#define SMSC_FDC37M81X_TEST4 0x2B +#define SMSC_FDC37M81X_TEST5 0x2C +#define SMSC_FDC37M81X_TEST1 0x2D +#define SMSC_FDC37M81X_TEST2 0x2E +#define SMSC_FDC37M81X_TEST3 0x2F + +/* Logical device numbers */ +#define SMSC_FDC37M81X_FDD 0x00 +#define SMSC_FDC37M81X_PARALLEL 0x03 +#define SMSC_FDC37M81X_SERIAL1 0x04 +#define SMSC_FDC37M81X_SERIAL2 0x05 +#define SMSC_FDC37M81X_KBD 0x07 +#define SMSC_FDC37M81X_AUXIO 0x08 +#define SMSC_FDC37M81X_NONE 0xff + +/* Logical device Config Registers */ +#define SMSC_FDC37M81X_ACTIVE 0x30 +#define SMSC_FDC37M81X_BASEADDR0 0x60 +#define SMSC_FDC37M81X_BASEADDR1 0x61 +#define SMSC_FDC37M81X_INT 0x70 +#define SMSC_FDC37M81X_INT2 0x72 +#define SMSC_FDC37M81X_LDCR_F0 0xF0 + +/* Chip Config Values */ +#define SMSC_FDC37M81X_CONFIG_ENTER 0x55 +#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa +#define SMSC_FDC37M81X_CHIP_ID 0x4d + +unsigned long __init smsc_fdc37m81x_init(unsigned long port); + +void smsc_fdc37m81x_config_beg(void); + +void smsc_fdc37m81x_config_end(void); + +void smsc_fdc37m81x_config_set(u8 reg, u8 val); + +#endif diff --git a/include/asm-mips/txx9/spi.h b/include/asm-mips/txx9/spi.h new file mode 100644 index 0000000..ddfb2a0 --- /dev/null +++ b/include/asm-mips/txx9/spi.h @@ -0,0 +1,19 @@ +/* + * Definitions for TX4937/TX4938 SPI + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#ifndef __ASM_TXX9_SPI_H +#define __ASM_TXX9_SPI_H + +extern int spi_eeprom_register(int chipid); +extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); + +#endif /* __ASM_TXX9_SPI_H */ diff --git a/include/asm-mips/txx9/tx3927.h b/include/asm-mips/txx9/tx3927.h new file mode 100644 index 0000000..63b62d6 --- /dev/null +++ b/include/asm-mips/txx9/tx3927.h @@ -0,0 +1,319 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000 Toshiba Corporation + */ +#ifndef __ASM_TXX9_TX3927_H +#define __ASM_TXX9_TX3927_H + +#include + +#define TX3927_SDRAMC_REG 0xfffe8000 +#define TX3927_ROMC_REG 0xfffe9000 +#define TX3927_DMA_REG 0xfffeb000 +#define TX3927_IRC_REG 0xfffec000 +#define TX3927_PCIC_REG 0xfffed000 +#define TX3927_CCFG_REG 0xfffee000 +#define TX3927_NR_TMR 3 +#define TX3927_TMR_REG(ch) (0xfffef000 + (ch) * 0x100) +#define TX3927_NR_SIO 2 +#define TX3927_SIO_REG(ch) (0xfffef300 + (ch) * 0x100) +#define TX3927_PIO_REG 0xfffef500 + +struct tx3927_sdramc_reg { + volatile unsigned long cr[8]; + volatile unsigned long tr[3]; + volatile unsigned long cmd; + volatile unsigned long smrs[2]; +}; + +struct tx3927_romc_reg { + volatile unsigned long cr[8]; +}; + +struct tx3927_dma_reg { + struct tx3927_dma_ch_reg { + volatile unsigned long cha; + volatile unsigned long sar; + volatile unsigned long dar; + volatile unsigned long cntr; + volatile unsigned long sair; + volatile unsigned long dair; + volatile unsigned long ccr; + volatile unsigned long csr; + } ch[4]; + volatile unsigned long dbr[8]; + volatile unsigned long tdhr; + volatile unsigned long mcr; + volatile unsigned long unused0; +}; + +#include + +#ifdef __BIG_ENDIAN +#define endian_def_s2(e1, e2) \ + volatile unsigned short e1, e2 +#define endian_def_sb2(e1, e2, e3) \ + volatile unsigned short e1;volatile unsigned char e2, e3 +#define endian_def_b2s(e1, e2, e3) \ + volatile unsigned char e1, e2;volatile unsigned short e3 +#define endian_def_b4(e1, e2, e3, e4) \ + volatile unsigned char e1, e2, e3, e4 +#else +#define endian_def_s2(e1, e2) \ + volatile unsigned short e2, e1 +#define endian_def_sb2(e1, e2, e3) \ + volatile unsigned char e3, e2;volatile unsigned short e1 +#define endian_def_b2s(e1, e2, e3) \ + volatile unsigned short e3;volatile unsigned char e2, e1 +#define endian_def_b4(e1, e2, e3, e4) \ + volatile unsigned char e4, e3, e2, e1 +#endif + +struct tx3927_pcic_reg { + endian_def_s2(did, vid); + endian_def_s2(pcistat, pcicmd); + endian_def_b4(cc, scc, rpli, rid); + endian_def_b4(unused0, ht, mlt, cls); + volatile unsigned long ioba; /* +10 */ + volatile unsigned long mba; + volatile unsigned long unused1[5]; + endian_def_s2(svid, ssvid); + volatile unsigned long unused2; /* +30 */ + endian_def_sb2(unused3, unused4, capptr); + volatile unsigned long unused5; + endian_def_b4(ml, mg, ip, il); + volatile unsigned long unused6; /* +40 */ + volatile unsigned long istat; + volatile unsigned long iim; + volatile unsigned long rrt; + volatile unsigned long unused7[3]; /* +50 */ + volatile unsigned long ipbmma; + volatile unsigned long ipbioma; /* +60 */ + volatile unsigned long ilbmma; + volatile unsigned long ilbioma; + volatile unsigned long unused8[9]; + volatile unsigned long tc; /* +90 */ + volatile unsigned long tstat; + volatile unsigned long tim; + volatile unsigned long tccmd; + volatile unsigned long pcirrt; /* +a0 */ + volatile unsigned long pcirrt_cmd; + volatile unsigned long pcirrdt; + volatile unsigned long unused9[3]; + volatile unsigned long tlboap; + volatile unsigned long tlbiap; + volatile unsigned long tlbmma; /* +c0 */ + volatile unsigned long tlbioma; + volatile unsigned long sc_msg; + volatile unsigned long sc_be; + volatile unsigned long tbl; /* +d0 */ + volatile unsigned long unused10[3]; + volatile unsigned long pwmng; /* +e0 */ + volatile unsigned long pwmngs; + volatile unsigned long unused11[6]; + volatile unsigned long req_trace; /* +100 */ + volatile unsigned long pbapmc; + volatile unsigned long pbapms; + volatile unsigned long pbapmim; + volatile unsigned long bm; /* +110 */ + volatile unsigned long cpcibrs; + volatile unsigned long cpcibgs; + volatile unsigned long pbacs; + volatile unsigned long iobas; /* +120 */ + volatile unsigned long mbas; + volatile unsigned long lbc; + volatile unsigned long lbstat; + volatile unsigned long lbim; /* +130 */ + volatile unsigned long pcistatim; + volatile unsigned long ica; + volatile unsigned long icd; + volatile unsigned long iiadp; /* +140 */ + volatile unsigned long iscdp; + volatile unsigned long mmas; + volatile unsigned long iomas; + volatile unsigned long ipciaddr; /* +150 */ + volatile unsigned long ipcidata; + volatile unsigned long ipcibe; +}; + +struct tx3927_ccfg_reg { + volatile unsigned long ccfg; + volatile unsigned long crir; + volatile unsigned long pcfg; + volatile unsigned long tear; + volatile unsigned long pdcr; +}; + +/* + * SDRAMC + */ + +/* + * ROMC + */ + +/* + * DMA + */ +/* bits for MCR */ +#define TX3927_DMA_MCR_EIS(ch) (0x10000000<<(ch)) +#define TX3927_DMA_MCR_DIS(ch) (0x01000000<<(ch)) +#define TX3927_DMA_MCR_RSFIF 0x00000080 +#define TX3927_DMA_MCR_FIFUM(ch) (0x00000008<<(ch)) +#define TX3927_DMA_MCR_LE 0x00000004 +#define TX3927_DMA_MCR_RPRT 0x00000002 +#define TX3927_DMA_MCR_MSTEN 0x00000001 + +/* bits for CCRn */ +#define TX3927_DMA_CCR_DBINH 0x04000000 +#define TX3927_DMA_CCR_SBINH 0x02000000 +#define TX3927_DMA_CCR_CHRST 0x01000000 +#define TX3927_DMA_CCR_RVBYTE 0x00800000 +#define TX3927_DMA_CCR_ACKPOL 0x00400000 +#define TX3927_DMA_CCR_REQPL 0x00200000 +#define TX3927_DMA_CCR_EGREQ 0x00100000 +#define TX3927_DMA_CCR_CHDN 0x00080000 +#define TX3927_DMA_CCR_DNCTL 0x00060000 +#define TX3927_DMA_CCR_EXTRQ 0x00010000 +#define TX3927_DMA_CCR_INTRQD 0x0000e000 +#define TX3927_DMA_CCR_INTENE 0x00001000 +#define TX3927_DMA_CCR_INTENC 0x00000800 +#define TX3927_DMA_CCR_INTENT 0x00000400 +#define TX3927_DMA_CCR_CHNEN 0x00000200 +#define TX3927_DMA_CCR_XFACT 0x00000100 +#define TX3927_DMA_CCR_SNOP 0x00000080 +#define TX3927_DMA_CCR_DSTINC 0x00000040 +#define TX3927_DMA_CCR_SRCINC 0x00000020 +#define TX3927_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c) +#define TX3927_DMA_CCR_XFSZ_1W TX3927_DMA_CCR_XFSZ(2) +#define TX3927_DMA_CCR_XFSZ_4W TX3927_DMA_CCR_XFSZ(4) +#define TX3927_DMA_CCR_XFSZ_8W TX3927_DMA_CCR_XFSZ(5) +#define TX3927_DMA_CCR_XFSZ_16W TX3927_DMA_CCR_XFSZ(6) +#define TX3927_DMA_CCR_XFSZ_32W TX3927_DMA_CCR_XFSZ(7) +#define TX3927_DMA_CCR_MEMIO 0x00000002 +#define TX3927_DMA_CCR_ONEAD 0x00000001 + +/* bits for CSRn */ +#define TX3927_DMA_CSR_CHNACT 0x00000100 +#define TX3927_DMA_CSR_ABCHC 0x00000080 +#define TX3927_DMA_CSR_NCHNC 0x00000040 +#define TX3927_DMA_CSR_NTRNFC 0x00000020 +#define TX3927_DMA_CSR_EXTDN 0x00000010 +#define TX3927_DMA_CSR_CFERR 0x00000008 +#define TX3927_DMA_CSR_CHERR 0x00000004 +#define TX3927_DMA_CSR_DESERR 0x00000002 +#define TX3927_DMA_CSR_SORERR 0x00000001 + +/* + * IRC + */ +#define TX3927_IR_INT0 0 +#define TX3927_IR_INT1 1 +#define TX3927_IR_INT2 2 +#define TX3927_IR_INT3 3 +#define TX3927_IR_INT4 4 +#define TX3927_IR_INT5 5 +#define TX3927_IR_SIO0 6 +#define TX3927_IR_SIO1 7 +#define TX3927_IR_SIO(ch) (6 + (ch)) +#define TX3927_IR_DMA 8 +#define TX3927_IR_PIO 9 +#define TX3927_IR_PCI 10 +#define TX3927_IR_TMR(ch) (13 + (ch)) +#define TX3927_NUM_IR 16 + +/* + * PCIC + */ +/* bits for PCICMD */ +/* see PCI_COMMAND_XXX in linux/pci.h */ + +/* bits for PCISTAT */ +/* see PCI_STATUS_XXX in linux/pci.h */ +#define PCI_STATUS_NEW_CAP 0x0010 + +/* bits for TC */ +#define TX3927_PCIC_TC_OF16E 0x00000020 +#define TX3927_PCIC_TC_IF8E 0x00000010 +#define TX3927_PCIC_TC_OF8E 0x00000008 + +/* bits for IOBA/MBA */ +/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */ + +/* bits for PBAPMC */ +#define TX3927_PCIC_PBAPMC_RPBA 0x00000004 +#define TX3927_PCIC_PBAPMC_PBAEN 0x00000002 +#define TX3927_PCIC_PBAPMC_BMCEN 0x00000001 + +/* bits for LBSTAT/LBIM */ +#define TX3927_PCIC_LBIM_ALL 0x0000003e + +/* bits for PCISTATIM (see also PCI_STATUS_XXX in linux/pci.h */ +#define TX3927_PCIC_PCISTATIM_ALL 0x0000f900 + +/* bits for LBC */ +#define TX3927_PCIC_LBC_IBSE 0x00004000 +#define TX3927_PCIC_LBC_TIBSE 0x00002000 +#define TX3927_PCIC_LBC_TMFBSE 0x00001000 +#define TX3927_PCIC_LBC_HRST 0x00000800 +#define TX3927_PCIC_LBC_SRST 0x00000400 +#define TX3927_PCIC_LBC_EPCAD 0x00000200 +#define TX3927_PCIC_LBC_MSDSE 0x00000100 +#define TX3927_PCIC_LBC_CRR 0x00000080 +#define TX3927_PCIC_LBC_ILMDE 0x00000040 +#define TX3927_PCIC_LBC_ILIDE 0x00000020 + +#define TX3927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX3927_PCIC_MAX_DEVNU TX3927_PCIC_IDSEL_AD_TO_SLOT(32) + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX3927_CCFG_TLBOFF 0x00020000 +#define TX3927_CCFG_BEOW 0x00010000 +#define TX3927_CCFG_WR 0x00008000 +#define TX3927_CCFG_TOE 0x00004000 +#define TX3927_CCFG_PCIXARB 0x00002000 +#define TX3927_CCFG_PCI3 0x00001000 +#define TX3927_CCFG_PSNP 0x00000800 +#define TX3927_CCFG_PPRI 0x00000400 +#define TX3927_CCFG_PLLM 0x00000030 +#define TX3927_CCFG_ENDIAN 0x00000004 +#define TX3927_CCFG_HALT 0x00000002 +#define TX3927_CCFG_ACEHOLD 0x00000001 + +/* PCFG : Pin Configuration */ +#define TX3927_PCFG_SYSCLKEN 0x08000000 +#define TX3927_PCFG_SDRCLKEN_ALL 0x07c00000 +#define TX3927_PCFG_SDRCLKEN(ch) (0x00400000<<(ch)) +#define TX3927_PCFG_PCICLKEN_ALL 0x003c0000 +#define TX3927_PCFG_PCICLKEN(ch) (0x00040000<<(ch)) +#define TX3927_PCFG_SELALL 0x0003ffff +#define TX3927_PCFG_SELCS 0x00020000 +#define TX3927_PCFG_SELDSF 0x00010000 +#define TX3927_PCFG_SELSIOC_ALL 0x0000c000 +#define TX3927_PCFG_SELSIOC(ch) (0x00004000<<(ch)) +#define TX3927_PCFG_SELSIO_ALL 0x00003000 +#define TX3927_PCFG_SELSIO(ch) (0x00001000<<(ch)) +#define TX3927_PCFG_SELTMR_ALL 0x00000e00 +#define TX3927_PCFG_SELTMR(ch) (0x00000200<<(ch)) +#define TX3927_PCFG_SELDONE 0x00000100 +#define TX3927_PCFG_INTDMA_ALL 0x000000f0 +#define TX3927_PCFG_INTDMA(ch) (0x00000010<<(ch)) +#define TX3927_PCFG_SELDMA_ALL 0x0000000f +#define TX3927_PCFG_SELDMA(ch) (0x00000001<<(ch)) + +#define tx3927_sdramcptr ((struct tx3927_sdramc_reg *)TX3927_SDRAMC_REG) +#define tx3927_romcptr ((struct tx3927_romc_reg *)TX3927_ROMC_REG) +#define tx3927_dmaptr ((struct tx3927_dma_reg *)TX3927_DMA_REG) +#define tx3927_pcicptr ((struct tx3927_pcic_reg *)TX3927_PCIC_REG) +#define tx3927_ccfgptr ((struct tx3927_ccfg_reg *)TX3927_CCFG_REG) +#define tx3927_tmrptr(ch) ((struct txx927_tmr_reg *)TX3927_TMR_REG(ch)) +#define tx3927_sioptr(ch) ((struct txx927_sio_reg *)TX3927_SIO_REG(ch)) +#define tx3927_pioptr ((struct txx9_pio_reg __iomem *)TX3927_PIO_REG) + +#endif /* __ASM_TXX9_TX3927_H */ diff --git a/include/asm-mips/txx9/tx4927.h b/include/asm-mips/txx9/tx4927.h new file mode 100644 index 0000000..f21a7b1 --- /dev/null +++ b/include/asm-mips/txx9/tx4927.h @@ -0,0 +1,280 @@ +/* + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2006 MontaVista Software 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __ASM_TXX9_TX4927_H +#define __ASM_TXX9_TX4927_H + +#include + +#define TX4927_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE +#define TX4927_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) + +#define TX4927_IRQ_PIC_BEG TXX9_IRQ_BASE +#define TX4927_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) + + +#define TX4927_IRQ_USER0 (TX4927_IRQ_CP0_BEG+0) +#define TX4927_IRQ_USER1 (TX4927_IRQ_CP0_BEG+1) +#define TX4927_IRQ_NEST_PIC_ON_CP0 (TX4927_IRQ_CP0_BEG+2) +#define TX4927_IRQ_CPU_TIMER (TX4927_IRQ_CP0_BEG+7) + +#define TX4927_IRQ_NEST_EXT_ON_PIC (TX4927_IRQ_PIC_BEG+3) + +#define TX4927_CCFG_TOE 0x00004000 +#define TX4927_CCFG_WR 0x00008000 +#define TX4927_CCFG_TINTDIS 0x01000000 + +#define TX4927_PCIMEM 0x08000000 +#define TX4927_PCIMEM_SIZE 0x08000000 +#define TX4927_PCIIO 0x16000000 +#define TX4927_PCIIO_SIZE 0x01000000 + +#define TX4927_SDRAMC_REG 0xff1f8000 +#define TX4927_EBUSC_REG 0xff1f9000 +#define TX4927_PCIC_REG 0xff1fd000 +#define TX4927_CCFG_REG 0xff1fe000 +#define TX4927_IRC_REG 0xff1ff600 +#define TX4927_NR_TMR 3 +#define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) + +/* bits for ISTAT3/IMASK3/IMSTAT3 */ +#define TX4927_INT3B_PCID 0 +#define TX4927_INT3B_PCIC 1 +#define TX4927_INT3B_PCIB 2 +#define TX4927_INT3B_PCIA 3 +#define TX4927_INT3F_PCID (1 << TX4927_INT3B_PCID) +#define TX4927_INT3F_PCIC (1 << TX4927_INT3B_PCIC) +#define TX4927_INT3F_PCIB (1 << TX4927_INT3B_PCIB) +#define TX4927_INT3F_PCIA (1 << TX4927_INT3B_PCIA) + +#define TX4927_NR_IRQ_LOCAL TX4927_IRQ_PIC_BEG +#define TX4927_NR_IRQ_IRC 32 /* On-Chip IRC */ + +#define TX4927_IR_PCIC 16 +#define TX4927_IR_PCIERR 22 +#define TX4927_IR_PCIPMA 23 +#define TX4927_IRQ_IRC_PCIC (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIC) +#define TX4927_IRQ_IRC_PCIERR (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIERR) +#define TX4927_IRQ_IOC1 (TX4927_NR_IRQ_LOCAL + TX4927_NR_IRQ_IRC) +#define TX4927_IRQ_IOC_PCID (TX4927_IRQ_IOC1 + TX4927_INT3B_PCID) +#define TX4927_IRQ_IOC_PCIC (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIC) +#define TX4927_IRQ_IOC_PCIB (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIB) +#define TX4927_IRQ_IOC_PCIA (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIA) + +#ifdef _LANGUAGE_ASSEMBLY +#define _CONST64(c) c +#else +#define _CONST64(c) c##ull + +#include + +struct tx4927_sdramc_reg { + volatile unsigned long long cr[4]; + volatile unsigned long long unused0[4]; + volatile unsigned long long tr; + volatile unsigned long long unused1[2]; + volatile unsigned long long cmd; +}; + +struct tx4927_ebusc_reg { + volatile unsigned long long cr[8]; +}; + +struct tx4927_ccfg_reg { + volatile unsigned long long ccfg; + volatile unsigned long long crir; + volatile unsigned long long pcfg; + volatile unsigned long long tear; + volatile unsigned long long clkctr; + volatile unsigned long long unused0; + volatile unsigned long long garbc; + volatile unsigned long long unused1; + volatile unsigned long long unused2; + volatile unsigned long long ramp; +}; + +struct tx4927_pcic_reg { + volatile unsigned long pciid; + volatile unsigned long pcistatus; + volatile unsigned long pciccrev; + volatile unsigned long pcicfg1; + volatile unsigned long p2gm0plbase; /* +10 */ + volatile unsigned long p2gm0pubase; + volatile unsigned long p2gm1plbase; + volatile unsigned long p2gm1pubase; + volatile unsigned long p2gm2pbase; /* +20 */ + volatile unsigned long p2giopbase; + volatile unsigned long unused0; + volatile unsigned long pcisid; + volatile unsigned long unused1; /* +30 */ + volatile unsigned long pcicapptr; + volatile unsigned long unused2; + volatile unsigned long pcicfg2; + volatile unsigned long g2ptocnt; /* +40 */ + volatile unsigned long unused3[15]; + volatile unsigned long g2pstatus; /* +80 */ + volatile unsigned long g2pmask; + volatile unsigned long pcisstatus; + volatile unsigned long pcimask; + volatile unsigned long p2gcfg; /* +90 */ + volatile unsigned long p2gstatus; + volatile unsigned long p2gmask; + volatile unsigned long p2gccmd; + volatile unsigned long unused4[24]; /* +a0 */ + volatile unsigned long pbareqport; /* +100 */ + volatile unsigned long pbacfg; + volatile unsigned long pbastatus; + volatile unsigned long pbamask; + volatile unsigned long pbabm; /* +110 */ + volatile unsigned long pbacreq; + volatile unsigned long pbacgnt; + volatile unsigned long pbacstate; + volatile unsigned long long g2pmgbase[3]; /* +120 */ + volatile unsigned long long g2piogbase; + volatile unsigned long g2pmmask[3]; /* +140 */ + volatile unsigned long g2piomask; + volatile unsigned long long g2pmpbase[3]; /* +150 */ + volatile unsigned long long g2piopbase; + volatile unsigned long pciccfg; /* +170 */ + volatile unsigned long pcicstatus; + volatile unsigned long pcicmask; + volatile unsigned long unused5; + volatile unsigned long long p2gmgbase[3]; /* +180 */ + volatile unsigned long long p2giogbase; + volatile unsigned long g2pcfgadrs; /* +1a0 */ + volatile unsigned long g2pcfgdata; + volatile unsigned long unused6[8]; + volatile unsigned long g2pintack; + volatile unsigned long g2pspc; + volatile unsigned long unused7[12]; /* +1d0 */ + volatile unsigned long long pdmca; /* +200 */ + volatile unsigned long long pdmga; + volatile unsigned long long pdmpa; + volatile unsigned long long pdmcut; + volatile unsigned long long pdmcnt; /* +220 */ + volatile unsigned long long pdmsts; + volatile unsigned long long unused8[2]; + volatile unsigned long long pdmdb[4]; /* +240 */ + volatile unsigned long long pdmtdh; /* +260 */ + volatile unsigned long long pdmdms; +}; + +#endif /* _LANGUAGE_ASSEMBLY */ + +/* + * PCIC + */ + +/* bits for G2PSTATUS/G2PMASK */ +#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 +#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 +#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 + +/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ +#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 + +/* bits for PBACFG */ +#define TX4927_PCIC_PBACFG_RPBA 0x00000004 +#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 +#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 + +/* bits for G2PMnGBASE */ +#define TX4927_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for G2PIOGBASE */ +#define TX4927_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for PCICSTATUS/PCICMASK */ +#define TX4927_PCIC_PCICSTATUS_ALL 0x000007dc + +/* bits for PCICCFG */ +#define TX4927_PCIC_PCICCFG_LBWC_MASK 0x0fff0000 +#define TX4927_PCIC_PCICCFG_HRST 0x00000800 +#define TX4927_PCIC_PCICCFG_SRST 0x00000400 +#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 +#define TX4927_PCIC_PCICCFG_IMSE0 0x00000100 +#define TX4927_PCIC_PCICCFG_IMSE1 0x00000080 +#define TX4927_PCIC_PCICCFG_IMSE2 0x00000040 +#define TX4927_PCIC_PCICCFG_IISE 0x00000020 +#define TX4927_PCIC_PCICCFG_ATR 0x00000010 +#define TX4927_PCIC_PCICCFG_ICAE 0x00000008 + +/* bits for P2GMnGBASE */ +#define TX4927_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) +#define TX4927_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) + +/* bits for P2GIOGBASE */ +#define TX4927_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) +#define TX4927_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) + +#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX4927_CCFG_PCI66 0x00800000 +#define TX4927_CCFG_PCIMIDE 0x00400000 +#define TX4927_CCFG_PCIXARB 0x00002000 +#define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800 +#define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000 +#define TX4927_CCFG_PCIDIVMODE_3 0x00000800 +#define TX4927_CCFG_PCIDIVMODE_5 0x00001000 +#define TX4927_CCFG_PCIDIVMODE_6 0x00001800 + +#define TX4937_CCFG_PCIDIVMODE_MASK 0x00001c00 +#define TX4937_CCFG_PCIDIVMODE_8 0x00000000 +#define TX4937_CCFG_PCIDIVMODE_4 0x00000400 +#define TX4937_CCFG_PCIDIVMODE_9 0x00000800 +#define TX4937_CCFG_PCIDIVMODE_4_5 0x00000c00 +#define TX4937_CCFG_PCIDIVMODE_10 0x00001000 +#define TX4937_CCFG_PCIDIVMODE_5 0x00001400 +#define TX4937_CCFG_PCIDIVMODE_11 0x00001800 +#define TX4937_CCFG_PCIDIVMODE_5_5 0x00001c00 + +/* PCFG : Pin Configuration */ +#define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 +#define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) + +/* CLKCTR : Clock Control */ +#define TX4927_CLKCTR_PCICKD 0x00400000 +#define TX4927_CLKCTR_PCIRST 0x00000040 + +#ifndef _LANGUAGE_ASSEMBLY + +#define tx4927_sdramcptr ((struct tx4927_sdramc_reg *)TX4927_SDRAMC_REG) +#define tx4927_pcicptr ((struct tx4927_pcic_reg *)TX4927_PCIC_REG) +#define tx4927_ccfgptr ((struct tx4927_ccfg_reg *)TX4927_CCFG_REG) +#define tx4927_ebuscptr ((struct tx4927_ebusc_reg *)TX4927_EBUSC_REG) + +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* __ASM_TXX9_TX4927_H */ diff --git a/include/asm-mips/txx9/tx4938.h b/include/asm-mips/txx9/tx4938.h new file mode 100644 index 0000000..7f9cfef --- /dev/null +++ b/include/asm-mips/txx9/tx4938.h @@ -0,0 +1,627 @@ +/* + * Definitions for TX4937/TX4938 + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#ifndef __ASM_TXX9_TX4938_H +#define __ASM_TXX9_TX4938_H + +#define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr)) +#define tx4938_write_nfmc(b, addr) (*(volatile unsigned int *)(addr)) = (b) + +#define TX4938_NR_IRQ_LOCAL TX4938_IRQ_PIC_BEG + +#define TX4938_IRQ_IRC_PCIC (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC) +#define TX4938_IRQ_IRC_PCIERR (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR) + +#define TX4938_PCIIO_0 0x10000000 +#define TX4938_PCIIO_1 0x01010000 +#define TX4938_PCIMEM_0 0x08000000 +#define TX4938_PCIMEM_1 0x11000000 + +#define TX4938_PCIIO_SIZE_0 0x01000000 +#define TX4938_PCIIO_SIZE_1 0x00010000 +#define TX4938_PCIMEM_SIZE_0 0x08000000 +#define TX4938_PCIMEM_SIZE_1 0x00010000 + +#define TX4938_REG_BASE 0xff1f0000 /* == TX4937_REG_BASE */ +#define TX4938_REG_SIZE 0x00010000 /* == TX4937_REG_SIZE */ + +/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */ +#define TX4938_NDFMC_REG (TX4938_REG_BASE + 0x5000) +#define TX4938_SRAMC_REG (TX4938_REG_BASE + 0x6000) +#define TX4938_PCIC1_REG (TX4938_REG_BASE + 0x7000) +#define TX4938_SDRAMC_REG (TX4938_REG_BASE + 0x8000) +#define TX4938_EBUSC_REG (TX4938_REG_BASE + 0x9000) +#define TX4938_DMA_REG(ch) (TX4938_REG_BASE + 0xb000 + (ch) * 0x800) +#define TX4938_PCIC_REG (TX4938_REG_BASE + 0xd000) +#define TX4938_CCFG_REG (TX4938_REG_BASE + 0xe000) +#define TX4938_NR_TMR 3 +#define TX4938_TMR_REG(ch) ((TX4938_REG_BASE + 0xf000) + (ch) * 0x100) +#define TX4938_NR_SIO 2 +#define TX4938_SIO_REG(ch) ((TX4938_REG_BASE + 0xf300) + (ch) * 0x100) +#define TX4938_PIO_REG (TX4938_REG_BASE + 0xf500) +#define TX4938_IRC_REG (TX4938_REG_BASE + 0xf600) +#define TX4938_ACLC_REG (TX4938_REG_BASE + 0xf700) +#define TX4938_SPI_REG (TX4938_REG_BASE + 0xf800) + +#ifdef __ASSEMBLY__ +#define _CONST64(c) c +#else +#define _CONST64(c) c##ull + +#include + +#ifdef __BIG_ENDIAN +#define endian_def_l2(e1, e2) \ + volatile unsigned long e1, e2 +#define endian_def_s2(e1, e2) \ + volatile unsigned short e1, e2 +#define endian_def_sb2(e1, e2, e3) \ + volatile unsigned short e1;volatile unsigned char e2, e3 +#define endian_def_b2s(e1, e2, e3) \ + volatile unsigned char e1, e2;volatile unsigned short e3 +#define endian_def_b4(e1, e2, e3, e4) \ + volatile unsigned char e1, e2, e3, e4 +#else +#define endian_def_l2(e1, e2) \ + volatile unsigned long e2, e1 +#define endian_def_s2(e1, e2) \ + volatile unsigned short e2, e1 +#define endian_def_sb2(e1, e2, e3) \ + volatile unsigned char e3, e2;volatile unsigned short e1 +#define endian_def_b2s(e1, e2, e3) \ + volatile unsigned short e3;volatile unsigned char e2, e1 +#define endian_def_b4(e1, e2, e3, e4) \ + volatile unsigned char e4, e3, e2, e1 +#endif + + +struct tx4938_sdramc_reg { + volatile unsigned long long cr[4]; + volatile unsigned long long unused0[4]; + volatile unsigned long long tr; + volatile unsigned long long unused1[2]; + volatile unsigned long long cmd; + volatile unsigned long long sfcmd; +}; + +struct tx4938_ebusc_reg { + volatile unsigned long long cr[8]; +}; + +struct tx4938_dma_reg { + struct tx4938_dma_ch_reg { + volatile unsigned long long cha; + volatile unsigned long long sar; + volatile unsigned long long dar; + endian_def_l2(unused0, cntr); + endian_def_l2(unused1, sair); + endian_def_l2(unused2, dair); + endian_def_l2(unused3, ccr); + endian_def_l2(unused4, csr); + } ch[4]; + volatile unsigned long long dbr[8]; + volatile unsigned long long tdhr; + volatile unsigned long long midr; + endian_def_l2(unused0, mcr); +}; + +struct tx4938_pcic_reg { + volatile unsigned long pciid; + volatile unsigned long pcistatus; + volatile unsigned long pciccrev; + volatile unsigned long pcicfg1; + volatile unsigned long p2gm0plbase; /* +10 */ + volatile unsigned long p2gm0pubase; + volatile unsigned long p2gm1plbase; + volatile unsigned long p2gm1pubase; + volatile unsigned long p2gm2pbase; /* +20 */ + volatile unsigned long p2giopbase; + volatile unsigned long unused0; + volatile unsigned long pcisid; + volatile unsigned long unused1; /* +30 */ + volatile unsigned long pcicapptr; + volatile unsigned long unused2; + volatile unsigned long pcicfg2; + volatile unsigned long g2ptocnt; /* +40 */ + volatile unsigned long unused3[15]; + volatile unsigned long g2pstatus; /* +80 */ + volatile unsigned long g2pmask; + volatile unsigned long pcisstatus; + volatile unsigned long pcimask; + volatile unsigned long p2gcfg; /* +90 */ + volatile unsigned long p2gstatus; + volatile unsigned long p2gmask; + volatile unsigned long p2gccmd; + volatile unsigned long unused4[24]; /* +a0 */ + volatile unsigned long pbareqport; /* +100 */ + volatile unsigned long pbacfg; + volatile unsigned long pbastatus; + volatile unsigned long pbamask; + volatile unsigned long pbabm; /* +110 */ + volatile unsigned long pbacreq; + volatile unsigned long pbacgnt; + volatile unsigned long pbacstate; + volatile unsigned long long g2pmgbase[3]; /* +120 */ + volatile unsigned long long g2piogbase; + volatile unsigned long g2pmmask[3]; /* +140 */ + volatile unsigned long g2piomask; + volatile unsigned long long g2pmpbase[3]; /* +150 */ + volatile unsigned long long g2piopbase; + volatile unsigned long pciccfg; /* +170 */ + volatile unsigned long pcicstatus; + volatile unsigned long pcicmask; + volatile unsigned long unused5; + volatile unsigned long long p2gmgbase[3]; /* +180 */ + volatile unsigned long long p2giogbase; + volatile unsigned long g2pcfgadrs; /* +1a0 */ + volatile unsigned long g2pcfgdata; + volatile unsigned long unused6[8]; + volatile unsigned long g2pintack; + volatile unsigned long g2pspc; + volatile unsigned long unused7[12]; /* +1d0 */ + volatile unsigned long long pdmca; /* +200 */ + volatile unsigned long long pdmga; + volatile unsigned long long pdmpa; + volatile unsigned long long pdmctr; + volatile unsigned long long pdmcfg; /* +220 */ + volatile unsigned long long pdmsts; +}; + +struct tx4938_aclc_reg { + volatile unsigned long acctlen; + volatile unsigned long acctldis; + volatile unsigned long acregacc; + volatile unsigned long unused0; + volatile unsigned long acintsts; + volatile unsigned long acintmsts; + volatile unsigned long acinten; + volatile unsigned long acintdis; + volatile unsigned long acsemaph; + volatile unsigned long unused1[7]; + volatile unsigned long acgpidat; + volatile unsigned long acgpodat; + volatile unsigned long acslten; + volatile unsigned long acsltdis; + volatile unsigned long acfifosts; + volatile unsigned long unused2[11]; + volatile unsigned long acdmasts; + volatile unsigned long acdmasel; + volatile unsigned long unused3[6]; + volatile unsigned long acaudodat; + volatile unsigned long acsurrdat; + volatile unsigned long accentdat; + volatile unsigned long aclfedat; + volatile unsigned long acaudiat; + volatile unsigned long unused4; + volatile unsigned long acmodoat; + volatile unsigned long acmodidat; + volatile unsigned long unused5[15]; + volatile unsigned long acrevid; +}; + + +struct tx4938_tmr_reg { + volatile unsigned long tcr; + volatile unsigned long tisr; + volatile unsigned long cpra; + volatile unsigned long cprb; + volatile unsigned long itmr; + volatile unsigned long unused0[3]; + volatile unsigned long ccdr; + volatile unsigned long unused1[3]; + volatile unsigned long pgmr; + volatile unsigned long unused2[3]; + volatile unsigned long wtmr; + volatile unsigned long unused3[43]; + volatile unsigned long trr; +}; + +struct tx4938_sio_reg { + volatile unsigned long lcr; + volatile unsigned long dicr; + volatile unsigned long disr; + volatile unsigned long cisr; + volatile unsigned long fcr; + volatile unsigned long flcr; + volatile unsigned long bgr; + volatile unsigned long tfifo; + volatile unsigned long rfifo; +}; + +struct tx4938_ndfmc_reg { + endian_def_l2(unused0, dtr); + endian_def_l2(unused1, mcr); + endian_def_l2(unused2, sr); + endian_def_l2(unused3, isr); + endian_def_l2(unused4, imr); + endian_def_l2(unused5, spr); + endian_def_l2(unused6, rstr); +}; + +struct tx4938_spi_reg { + volatile unsigned long mcr; + volatile unsigned long cr0; + volatile unsigned long cr1; + volatile unsigned long fs; + volatile unsigned long unused1; + volatile unsigned long sr; + volatile unsigned long dr; + volatile unsigned long unused2; +}; + +struct tx4938_sramc_reg { + volatile unsigned long long cr; +}; + +struct tx4938_ccfg_reg { + volatile unsigned long long ccfg; + volatile unsigned long long crir; + volatile unsigned long long pcfg; + volatile unsigned long long tear; + volatile unsigned long long clkctr; + volatile unsigned long long unused0; + volatile unsigned long long garbc; + volatile unsigned long long unused1; + volatile unsigned long long unused2; + volatile unsigned long long ramp; + volatile unsigned long long unused3; + volatile unsigned long long jmpadr; +}; + +#undef endian_def_l2 +#undef endian_def_s2 +#undef endian_def_sb2 +#undef endian_def_b2s +#undef endian_def_b4 + +#endif /* __ASSEMBLY__ */ + +/* + * NDFMC + */ + +/* NDFMCR : NDFMC Mode Control */ +#define TX4938_NDFMCR_WE 0x80 +#define TX4938_NDFMCR_ECC_ALL 0x60 +#define TX4938_NDFMCR_ECC_RESET 0x60 +#define TX4938_NDFMCR_ECC_READ 0x40 +#define TX4938_NDFMCR_ECC_ON 0x20 +#define TX4938_NDFMCR_ECC_OFF 0x00 +#define TX4938_NDFMCR_CE 0x10 +#define TX4938_NDFMCR_BSPRT 0x04 +#define TX4938_NDFMCR_ALE 0x02 +#define TX4938_NDFMCR_CLE 0x01 + +/* NDFMCR : NDFMC Status */ +#define TX4938_NDFSR_BUSY 0x80 + +/* NDFMCR : NDFMC Reset */ +#define TX4938_NDFRSTR_RST 0x01 + +/* + * IRC + */ + +#define TX4938_IR_ECCERR 0 +#define TX4938_IR_WTOERR 1 +#define TX4938_NUM_IR_INT 6 +#define TX4938_IR_INT(n) (2 + (n)) +#define TX4938_NUM_IR_SIO 2 +#define TX4938_IR_SIO(n) (8 + (n)) +#define TX4938_NUM_IR_DMA 4 +#define TX4938_IR_DMA(ch, n) ((ch ? 27 : 10) + (n)) /* 10-13, 27-30 */ +#define TX4938_IR_PIO 14 +#define TX4938_IR_PDMAC 15 +#define TX4938_IR_PCIC 16 +#define TX4938_NUM_IR_TMR 3 +#define TX4938_IR_TMR(n) (17 + (n)) +#define TX4938_IR_NDFMC 21 +#define TX4938_IR_PCIERR 22 +#define TX4938_IR_PCIPME 23 +#define TX4938_IR_ACLC 24 +#define TX4938_IR_ACLCPME 25 +#define TX4938_IR_PCIC1 26 +#define TX4938_IR_SPI 31 +#define TX4938_NUM_IR 32 +/* multiplex */ +#define TX4938_IR_ETH0 TX4938_IR_INT(4) +#define TX4938_IR_ETH1 TX4938_IR_INT(3) + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX4938_CCFG_WDRST _CONST64(0x0000020000000000) +#define TX4938_CCFG_WDREXEN _CONST64(0x0000010000000000) +#define TX4938_CCFG_BCFG_MASK _CONST64(0x000000ff00000000) +#define TX4938_CCFG_TINTDIS 0x01000000 +#define TX4938_CCFG_PCI66 0x00800000 +#define TX4938_CCFG_PCIMODE 0x00400000 +#define TX4938_CCFG_PCI1_66 0x00200000 +#define TX4938_CCFG_DIVMODE_MASK 0x001e0000 +#define TX4938_CCFG_DIVMODE_2 (0x4 << 17) +#define TX4938_CCFG_DIVMODE_2_5 (0xf << 17) +#define TX4938_CCFG_DIVMODE_3 (0x5 << 17) +#define TX4938_CCFG_DIVMODE_4 (0x6 << 17) +#define TX4938_CCFG_DIVMODE_4_5 (0xd << 17) +#define TX4938_CCFG_DIVMODE_8 (0x0 << 17) +#define TX4938_CCFG_DIVMODE_10 (0xb << 17) +#define TX4938_CCFG_DIVMODE_12 (0x1 << 17) +#define TX4938_CCFG_DIVMODE_16 (0x2 << 17) +#define TX4938_CCFG_DIVMODE_18 (0x9 << 17) +#define TX4938_CCFG_BEOW 0x00010000 +#define TX4938_CCFG_WR 0x00008000 +#define TX4938_CCFG_TOE 0x00004000 +#define TX4938_CCFG_PCIXARB 0x00002000 +#define TX4938_CCFG_PCIDIVMODE_MASK 0x00001c00 +#define TX4938_CCFG_PCIDIVMODE_4 (0x1 << 10) +#define TX4938_CCFG_PCIDIVMODE_4_5 (0x3 << 10) +#define TX4938_CCFG_PCIDIVMODE_5 (0x5 << 10) +#define TX4938_CCFG_PCIDIVMODE_5_5 (0x7 << 10) +#define TX4938_CCFG_PCIDIVMODE_8 (0x0 << 10) +#define TX4938_CCFG_PCIDIVMODE_9 (0x2 << 10) +#define TX4938_CCFG_PCIDIVMODE_10 (0x4 << 10) +#define TX4938_CCFG_PCIDIVMODE_11 (0x6 << 10) +#define TX4938_CCFG_PCI1DMD 0x00000100 +#define TX4938_CCFG_SYSSP_MASK 0x000000c0 +#define TX4938_CCFG_ENDIAN 0x00000004 +#define TX4938_CCFG_HALT 0x00000002 +#define TX4938_CCFG_ACEHOLD 0x00000001 + +/* PCFG : Pin Configuration */ +#define TX4938_PCFG_ETH0_SEL _CONST64(0x8000000000000000) +#define TX4938_PCFG_ETH1_SEL _CONST64(0x4000000000000000) +#define TX4938_PCFG_ATA_SEL _CONST64(0x2000000000000000) +#define TX4938_PCFG_ISA_SEL _CONST64(0x1000000000000000) +#define TX4938_PCFG_SPI_SEL _CONST64(0x0800000000000000) +#define TX4938_PCFG_NDF_SEL _CONST64(0x0400000000000000) +#define TX4938_PCFG_SDCLKDLY_MASK 0x30000000 +#define TX4938_PCFG_SDCLKDLY(d) ((d)<<28) +#define TX4938_PCFG_SYSCLKEN 0x08000000 +#define TX4938_PCFG_SDCLKEN_ALL 0x07800000 +#define TX4938_PCFG_SDCLKEN(ch) (0x00800000<<(ch)) +#define TX4938_PCFG_PCICLKEN_ALL 0x003f0000 +#define TX4938_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) +#define TX4938_PCFG_SEL2 0x00000200 +#define TX4938_PCFG_SEL1 0x00000100 +#define TX4938_PCFG_DMASEL_ALL 0x0000000f +#define TX4938_PCFG_DMASEL0_DRQ0 0x00000000 +#define TX4938_PCFG_DMASEL0_SIO1 0x00000001 +#define TX4938_PCFG_DMASEL1_DRQ1 0x00000000 +#define TX4938_PCFG_DMASEL1_SIO1 0x00000002 +#define TX4938_PCFG_DMASEL2_DRQ2 0x00000000 +#define TX4938_PCFG_DMASEL2_SIO0 0x00000004 +#define TX4938_PCFG_DMASEL3_DRQ3 0x00000000 +#define TX4938_PCFG_DMASEL3_SIO0 0x00000008 + +/* CLKCTR : Clock Control */ +#define TX4938_CLKCTR_NDFCKD _CONST64(0x0001000000000000) +#define TX4938_CLKCTR_NDFRST _CONST64(0x0000000100000000) +#define TX4938_CLKCTR_ETH1CKD 0x80000000 +#define TX4938_CLKCTR_ETH0CKD 0x40000000 +#define TX4938_CLKCTR_SPICKD 0x20000000 +#define TX4938_CLKCTR_SRAMCKD 0x10000000 +#define TX4938_CLKCTR_PCIC1CKD 0x08000000 +#define TX4938_CLKCTR_DMA1CKD 0x04000000 +#define TX4938_CLKCTR_ACLCKD 0x02000000 +#define TX4938_CLKCTR_PIOCKD 0x01000000 +#define TX4938_CLKCTR_DMACKD 0x00800000 +#define TX4938_CLKCTR_PCICKD 0x00400000 +#define TX4938_CLKCTR_TM0CKD 0x00100000 +#define TX4938_CLKCTR_TM1CKD 0x00080000 +#define TX4938_CLKCTR_TM2CKD 0x00040000 +#define TX4938_CLKCTR_SIO0CKD 0x00020000 +#define TX4938_CLKCTR_SIO1CKD 0x00010000 +#define TX4938_CLKCTR_ETH1RST 0x00008000 +#define TX4938_CLKCTR_ETH0RST 0x00004000 +#define TX4938_CLKCTR_SPIRST 0x00002000 +#define TX4938_CLKCTR_SRAMRST 0x00001000 +#define TX4938_CLKCTR_PCIC1RST 0x00000800 +#define TX4938_CLKCTR_DMA1RST 0x00000400 +#define TX4938_CLKCTR_ACLRST 0x00000200 +#define TX4938_CLKCTR_PIORST 0x00000100 +#define TX4938_CLKCTR_DMARST 0x00000080 +#define TX4938_CLKCTR_PCIRST 0x00000040 +#define TX4938_CLKCTR_TM0RST 0x00000010 +#define TX4938_CLKCTR_TM1RST 0x00000008 +#define TX4938_CLKCTR_TM2RST 0x00000004 +#define TX4938_CLKCTR_SIO0RST 0x00000002 +#define TX4938_CLKCTR_SIO1RST 0x00000001 + +/* bits for G2PSTATUS/G2PMASK */ +#define TX4938_PCIC_G2PSTATUS_ALL 0x00000003 +#define TX4938_PCIC_G2PSTATUS_TTOE 0x00000002 +#define TX4938_PCIC_G2PSTATUS_RTOE 0x00000001 + +/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ +#define TX4938_PCIC_PCISTATUS_ALL 0x0000f900 + +/* bits for PBACFG */ +#define TX4938_PCIC_PBACFG_FIXPA 0x00000008 +#define TX4938_PCIC_PBACFG_RPBA 0x00000004 +#define TX4938_PCIC_PBACFG_PBAEN 0x00000002 +#define TX4938_PCIC_PBACFG_BMCEN 0x00000001 + +/* bits for G2PMnGBASE */ +#define TX4938_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4938_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for G2PIOGBASE */ +#define TX4938_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4938_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for PCICSTATUS/PCICMASK */ +#define TX4938_PCIC_PCICSTATUS_ALL 0x000007b8 +#define TX4938_PCIC_PCICSTATUS_PME 0x00000400 +#define TX4938_PCIC_PCICSTATUS_TLB 0x00000200 +#define TX4938_PCIC_PCICSTATUS_NIB 0x00000100 +#define TX4938_PCIC_PCICSTATUS_ZIB 0x00000080 +#define TX4938_PCIC_PCICSTATUS_PERR 0x00000020 +#define TX4938_PCIC_PCICSTATUS_SERR 0x00000010 +#define TX4938_PCIC_PCICSTATUS_GBE 0x00000008 +#define TX4938_PCIC_PCICSTATUS_IWB 0x00000002 +#define TX4938_PCIC_PCICSTATUS_E2PDONE 0x00000001 + +/* bits for PCICCFG */ +#define TX4938_PCIC_PCICCFG_GBWC_MASK 0x0fff0000 +#define TX4938_PCIC_PCICCFG_HRST 0x00000800 +#define TX4938_PCIC_PCICCFG_SRST 0x00000400 +#define TX4938_PCIC_PCICCFG_IRBER 0x00000200 +#define TX4938_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch)) +#define TX4938_PCIC_PCICCFG_G2PM0EN 0x00000100 +#define TX4938_PCIC_PCICCFG_G2PM1EN 0x00000080 +#define TX4938_PCIC_PCICCFG_G2PM2EN 0x00000040 +#define TX4938_PCIC_PCICCFG_G2PIOEN 0x00000020 +#define TX4938_PCIC_PCICCFG_TCAR 0x00000010 +#define TX4938_PCIC_PCICCFG_ICAEN 0x00000008 + +/* bits for P2GMnGBASE */ +#define TX4938_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) +#define TX4938_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4938_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) + +/* bits for P2GIOGBASE */ +#define TX4938_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) +#define TX4938_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4938_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) + +#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX4938_PCIC_MAX_DEVNU TX4938_PCIC_IDSEL_AD_TO_SLOT(32) + +/* bits for PDMCFG */ +#define TX4938_PCIC_PDMCFG_RSTFIFO 0x00200000 +#define TX4938_PCIC_PDMCFG_EXFER 0x00100000 +#define TX4938_PCIC_PDMCFG_REQDLY_MASK 0x00003800 +#define TX4938_PCIC_PDMCFG_REQDLY_NONE (0 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_16 (1 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_32 (2 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_64 (3 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_128 (4 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_256 (5 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_512 (6 << 11) +#define TX4938_PCIC_PDMCFG_REQDLY_1024 (7 << 11) +#define TX4938_PCIC_PDMCFG_ERRIE 0x00000400 +#define TX4938_PCIC_PDMCFG_NCCMPIE 0x00000200 +#define TX4938_PCIC_PDMCFG_NTCMPIE 0x00000100 +#define TX4938_PCIC_PDMCFG_CHNEN 0x00000080 +#define TX4938_PCIC_PDMCFG_XFRACT 0x00000040 +#define TX4938_PCIC_PDMCFG_BSWAP 0x00000020 +#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c +#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000 +#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004 +#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008 +#define TX4938_PCIC_PDMCFG_XFRDIRC 0x00000002 +#define TX4938_PCIC_PDMCFG_CHRST 0x00000001 + +/* bits for PDMSTS */ +#define TX4938_PCIC_PDMSTS_REQCNT_MASK 0x3f000000 +#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000 +#define TX4938_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000 +#define TX4938_PCIC_PDMSTS_FIFORP_MASK 0x00030000 +#define TX4938_PCIC_PDMSTS_ERRINT 0x00000800 +#define TX4938_PCIC_PDMSTS_DONEINT 0x00000400 +#define TX4938_PCIC_PDMSTS_CHNEN 0x00000200 +#define TX4938_PCIC_PDMSTS_XFRACT 0x00000100 +#define TX4938_PCIC_PDMSTS_ACCMP 0x00000080 +#define TX4938_PCIC_PDMSTS_NCCMP 0x00000040 +#define TX4938_PCIC_PDMSTS_NTCMP 0x00000020 +#define TX4938_PCIC_PDMSTS_CFGERR 0x00000008 +#define TX4938_PCIC_PDMSTS_PCIERR 0x00000004 +#define TX4938_PCIC_PDMSTS_CHNERR 0x00000002 +#define TX4938_PCIC_PDMSTS_DATAERR 0x00000001 +#define TX4938_PCIC_PDMSTS_ALL_CMP 0x000000e0 +#define TX4938_PCIC_PDMSTS_ALL_ERR 0x0000000f + +/* + * DMA + */ +/* bits for MCR */ +#define TX4938_DMA_MCR_EIS(ch) (0x10000000<<(ch)) +#define TX4938_DMA_MCR_DIS(ch) (0x01000000<<(ch)) +#define TX4938_DMA_MCR_RSFIF 0x00000080 +#define TX4938_DMA_MCR_FIFUM(ch) (0x00000008<<(ch)) +#define TX4938_DMA_MCR_RPRT 0x00000002 +#define TX4938_DMA_MCR_MSTEN 0x00000001 + +/* bits for CCRn */ +#define TX4938_DMA_CCR_IMMCHN 0x20000000 +#define TX4938_DMA_CCR_USEXFSZ 0x10000000 +#define TX4938_DMA_CCR_LE 0x08000000 +#define TX4938_DMA_CCR_DBINH 0x04000000 +#define TX4938_DMA_CCR_SBINH 0x02000000 +#define TX4938_DMA_CCR_CHRST 0x01000000 +#define TX4938_DMA_CCR_RVBYTE 0x00800000 +#define TX4938_DMA_CCR_ACKPOL 0x00400000 +#define TX4938_DMA_CCR_REQPL 0x00200000 +#define TX4938_DMA_CCR_EGREQ 0x00100000 +#define TX4938_DMA_CCR_CHDN 0x00080000 +#define TX4938_DMA_CCR_DNCTL 0x00060000 +#define TX4938_DMA_CCR_EXTRQ 0x00010000 +#define TX4938_DMA_CCR_INTRQD 0x0000e000 +#define TX4938_DMA_CCR_INTENE 0x00001000 +#define TX4938_DMA_CCR_INTENC 0x00000800 +#define TX4938_DMA_CCR_INTENT 0x00000400 +#define TX4938_DMA_CCR_CHNEN 0x00000200 +#define TX4938_DMA_CCR_XFACT 0x00000100 +#define TX4938_DMA_CCR_SMPCHN 0x00000020 +#define TX4938_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c) +#define TX4938_DMA_CCR_XFSZ_1W TX4938_DMA_CCR_XFSZ(2) +#define TX4938_DMA_CCR_XFSZ_2W TX4938_DMA_CCR_XFSZ(3) +#define TX4938_DMA_CCR_XFSZ_4W TX4938_DMA_CCR_XFSZ(4) +#define TX4938_DMA_CCR_XFSZ_8W TX4938_DMA_CCR_XFSZ(5) +#define TX4938_DMA_CCR_XFSZ_16W TX4938_DMA_CCR_XFSZ(6) +#define TX4938_DMA_CCR_XFSZ_32W TX4938_DMA_CCR_XFSZ(7) +#define TX4938_DMA_CCR_MEMIO 0x00000002 +#define TX4938_DMA_CCR_SNGAD 0x00000001 + +/* bits for CSRn */ +#define TX4938_DMA_CSR_CHNEN 0x00000400 +#define TX4938_DMA_CSR_STLXFER 0x00000200 +#define TX4938_DMA_CSR_CHNACT 0x00000100 +#define TX4938_DMA_CSR_ABCHC 0x00000080 +#define TX4938_DMA_CSR_NCHNC 0x00000040 +#define TX4938_DMA_CSR_NTRNFC 0x00000020 +#define TX4938_DMA_CSR_EXTDN 0x00000010 +#define TX4938_DMA_CSR_CFERR 0x00000008 +#define TX4938_DMA_CSR_CHERR 0x00000004 +#define TX4938_DMA_CSR_DESERR 0x00000002 +#define TX4938_DMA_CSR_SORERR 0x00000001 + +#ifndef __ASSEMBLY__ + +#define tx4938_sdramcptr ((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG) +#define tx4938_ebuscptr ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG) +#define tx4938_dmaptr(ch) ((struct tx4938_dma_reg *)TX4938_DMA_REG(ch)) +#define tx4938_ndfmcptr ((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG) +#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG) +#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG) +#define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG) +#define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch)) +#define tx4938_pioptr ((struct txx9_pio_reg __iomem *)TX4938_PIO_REG) +#define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG) +#define tx4938_spiptr ((struct tx4938_spi_reg *)TX4938_SPI_REG) +#define tx4938_sramcptr ((struct tx4938_sramc_reg *)TX4938_SRAMC_REG) + + +#define TX4938_REV_MAJ_MIN() ((unsigned long)tx4938_ccfgptr->crir & 0x00ff) +#define TX4938_REV_PCODE() ((unsigned long)tx4938_ccfgptr->crir >> 16) + +#define TX4938_SDRAMC_BA(ch) ((tx4938_sdramcptr->cr[ch] >> 49) << 21) +#define TX4938_SDRAMC_SIZE(ch) (((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21) + +#define TX4938_EBUSC_BA(ch) ((tx4938_ebuscptr->cr[ch] >> 48) << 20) +#define TX4938_EBUSC_SIZE(ch) \ + (0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf)) + + +#endif /* !__ASSEMBLY__ */ + +#endif diff --git a/include/asm-mips/txx9/txx927.h b/include/asm-mips/txx9/txx927.h new file mode 100644 index 0000000..97dd7ad --- /dev/null +++ b/include/asm-mips/txx9/txx927.h @@ -0,0 +1,121 @@ +/* + * Common definitions for TX3927/TX4927 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000 Toshiba Corporation + */ +#ifndef __ASM_TXX9_TXX927_H +#define __ASM_TXX9_TXX927_H + +struct txx927_sio_reg { + volatile unsigned long lcr; + volatile unsigned long dicr; + volatile unsigned long disr; + volatile unsigned long cisr; + volatile unsigned long fcr; + volatile unsigned long flcr; + volatile unsigned long bgr; + volatile unsigned long tfifo; + volatile unsigned long rfifo; +}; + +/* + * SIO + */ +/* SILCR : Line Control */ +#define TXx927_SILCR_SCS_MASK 0x00000060 +#define TXx927_SILCR_SCS_IMCLK 0x00000000 +#define TXx927_SILCR_SCS_IMCLK_BG 0x00000020 +#define TXx927_SILCR_SCS_SCLK 0x00000040 +#define TXx927_SILCR_SCS_SCLK_BG 0x00000060 +#define TXx927_SILCR_UEPS 0x00000010 +#define TXx927_SILCR_UPEN 0x00000008 +#define TXx927_SILCR_USBL_MASK 0x00000004 +#define TXx927_SILCR_USBL_1BIT 0x00000004 +#define TXx927_SILCR_USBL_2BIT 0x00000000 +#define TXx927_SILCR_UMODE_MASK 0x00000003 +#define TXx927_SILCR_UMODE_8BIT 0x00000000 +#define TXx927_SILCR_UMODE_7BIT 0x00000001 + +/* SIDICR : DMA/Int. Control */ +#define TXx927_SIDICR_TDE 0x00008000 +#define TXx927_SIDICR_RDE 0x00004000 +#define TXx927_SIDICR_TIE 0x00002000 +#define TXx927_SIDICR_RIE 0x00001000 +#define TXx927_SIDICR_SPIE 0x00000800 +#define TXx927_SIDICR_CTSAC 0x00000600 +#define TXx927_SIDICR_STIE_MASK 0x0000003f +#define TXx927_SIDICR_STIE_OERS 0x00000020 +#define TXx927_SIDICR_STIE_CTSS 0x00000010 +#define TXx927_SIDICR_STIE_RBRKD 0x00000008 +#define TXx927_SIDICR_STIE_TRDY 0x00000004 +#define TXx927_SIDICR_STIE_TXALS 0x00000002 +#define TXx927_SIDICR_STIE_UBRKD 0x00000001 + +/* SIDISR : DMA/Int. Status */ +#define TXx927_SIDISR_UBRK 0x00008000 +#define TXx927_SIDISR_UVALID 0x00004000 +#define TXx927_SIDISR_UFER 0x00002000 +#define TXx927_SIDISR_UPER 0x00001000 +#define TXx927_SIDISR_UOER 0x00000800 +#define TXx927_SIDISR_ERI 0x00000400 +#define TXx927_SIDISR_TOUT 0x00000200 +#define TXx927_SIDISR_TDIS 0x00000100 +#define TXx927_SIDISR_RDIS 0x00000080 +#define TXx927_SIDISR_STIS 0x00000040 +#define TXx927_SIDISR_RFDN_MASK 0x0000001f + +/* SICISR : Change Int. Status */ +#define TXx927_SICISR_OERS 0x00000020 +#define TXx927_SICISR_CTSS 0x00000010 +#define TXx927_SICISR_RBRKD 0x00000008 +#define TXx927_SICISR_TRDY 0x00000004 +#define TXx927_SICISR_TXALS 0x00000002 +#define TXx927_SICISR_UBRKD 0x00000001 + +/* SIFCR : FIFO Control */ +#define TXx927_SIFCR_SWRST 0x00008000 +#define TXx927_SIFCR_RDIL_MASK 0x00000180 +#define TXx927_SIFCR_RDIL_1 0x00000000 +#define TXx927_SIFCR_RDIL_4 0x00000080 +#define TXx927_SIFCR_RDIL_8 0x00000100 +#define TXx927_SIFCR_RDIL_12 0x00000180 +#define TXx927_SIFCR_RDIL_MAX 0x00000180 +#define TXx927_SIFCR_TDIL_MASK 0x00000018 +#define TXx927_SIFCR_TDIL_MASK 0x00000018 +#define TXx927_SIFCR_TDIL_1 0x00000000 +#define TXx927_SIFCR_TDIL_4 0x00000001 +#define TXx927_SIFCR_TDIL_8 0x00000010 +#define TXx927_SIFCR_TDIL_MAX 0x00000010 +#define TXx927_SIFCR_TFRST 0x00000004 +#define TXx927_SIFCR_RFRST 0x00000002 +#define TXx927_SIFCR_FRSTE 0x00000001 +#define TXx927_SIO_TX_FIFO 8 +#define TXx927_SIO_RX_FIFO 16 + +/* SIFLCR : Flow Control */ +#define TXx927_SIFLCR_RCS 0x00001000 +#define TXx927_SIFLCR_TES 0x00000800 +#define TXx927_SIFLCR_RTSSC 0x00000200 +#define TXx927_SIFLCR_RSDE 0x00000100 +#define TXx927_SIFLCR_TSDE 0x00000080 +#define TXx927_SIFLCR_RTSTL_MASK 0x0000001e +#define TXx927_SIFLCR_RTSTL_MAX 0x0000001e +#define TXx927_SIFLCR_TBRK 0x00000001 + +/* SIBGR : Baudrate Control */ +#define TXx927_SIBGR_BCLK_MASK 0x00000300 +#define TXx927_SIBGR_BCLK_T0 0x00000000 +#define TXx927_SIBGR_BCLK_T2 0x00000100 +#define TXx927_SIBGR_BCLK_T4 0x00000200 +#define TXx927_SIBGR_BCLK_T6 0x00000300 +#define TXx927_SIBGR_BRD_MASK 0x000000ff + +/* + * PIO + */ + +#endif /* __ASM_TXX9_TXX927_H */ -- cgit v0.10.2 From 89d63fe179520b11f54de1f26755b7444c79e73a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 00:33:08 +0900 Subject: [MIPS] TXx9: Reorganize PCI code Split out PCIC dependent code and SoC dependent code from board dependent code. Now TX4927 PCIC code is independent from TX4927/TX4938 SoC code. Also fix some build problems on CONFIG_PCI=n. As a bonus, "FPCIB0 Backplane Support" is available for all TX39/TX49 boards and PCI66 support is available for all TX49 boards. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3202960..2ea6fff 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -575,7 +575,7 @@ config TOSHIBA_RBTX4927 select HW_HAS_PCI select IRQ_CPU select IRQ_TXX9 - select I8259 if TOSHIBA_FPCIB0 + select PCI_TX4927 select SWAP_IO_SPACE select SYS_HAS_CPU_TX49XX select SYS_SUPPORTS_32BIT_KERNEL @@ -598,6 +598,7 @@ config TOSHIBA_RBTX4938 select HW_HAS_PCI select IRQ_CPU select IRQ_TXX9 + select PCI_TX4927 select SWAP_IO_SPACE select SYS_HAS_CPU_TX49XX select SYS_SUPPORTS_32BIT_KERNEL diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 4608e43..9087648 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -15,6 +15,8 @@ obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o +obj-$(CONFIG_PCI_TX3927) += ops-tx3927.o +obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o # # These are still pretty much in the old state, watch, go blind. @@ -41,9 +43,9 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o -obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o -obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o -obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o ops-tx4938.o +obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o +obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o pci-tx4927.o pci-tx4938.o +obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o pci-tx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index 41dcd6a..d5edaf2 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -28,36 +28,31 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include -#include - +#include #include int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; - /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ - if (dev->vendor == PCI_VENDOR_ID_EFAR && - dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1) - return irq; /* IRQ rotation (PICMG) */ irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) { + if (slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) { /* PCI CardSlot (IDSEL=A23, DevNu=12) */ /* PCIA => PCIC (IDSEL=A23) */ /* NOTE: JMR3927 JP1 must be set to OPEN */ irq = (irq + 2) % 4; - } else if (dev->bus->parent == NULL && - slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) { + } else if (slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) { /* PCI CardSlot (IDSEL=A22, DevNu=11) */ /* PCIA => PCIA (IDSEL=A22) */ /* NOTE: JMR3927 JP1 must be set to OPEN */ irq = (irq + 0) % 4; } else { /* PCI Backplane */ - irq = (irq + 3 + slot) % 4; + if (txx9_pci_option & TXX9_PCI_OPT_PICMG) + irq = (irq + 33 - slot) % 4; + else + irq = (irq + 3 + slot) % 4; } irq++; /* 1-4 */ @@ -66,15 +61,13 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) irq = JMR3927_IRQ_IOC_PCIA; break; case 2: - // wrong for backplane irq = JMR3927_IRQ_IOC_PCIB; - irq = JMR3927_IRQ_IOC_PCID; + irq = JMR3927_IRQ_IOC_PCIB; break; case 3: irq = JMR3927_IRQ_IOC_PCIC; break; case 4: - // wrong for backplane irq = JMR3927_IRQ_IOC_PCID; - irq = JMR3927_IRQ_IOC_PCIB; + irq = JMR3927_IRQ_IOC_PCID; break; } diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 26013ba..abab485 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -33,102 +33,42 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include -#include -#include +#include +#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* look up table for backplane pci irq for slots 17-20 by pin # */ -static unsigned char backplane_pci_irq[4][4] = { - /* PJ6 SLOT: 17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA, - /* PJ6 SLOT: 17, PIN: 2 */ - TX4927_IRQ_IOC_PCIB, - /* PJ6 SLOT: 17, PIN: 3 */ - TX4927_IRQ_IOC_PCIC, - /* PJ6 SLOT: 17, PIN: 4 */ - TX4927_IRQ_IOC_PCID}, - /* SB SLOT: 18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB, - /* SB SLOT: 18, PIN: 2 */ - TX4927_IRQ_IOC_PCIC, - /* SB SLOT: 18, PIN: 3 */ - TX4927_IRQ_IOC_PCID, - /* SB SLOT: 18, PIN: 4 */ - TX4927_IRQ_IOC_PCIA}, - /* PJ5 SLOT: 19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC, - /* PJ5 SLOT: 19, PIN: 2 */ - TX4927_IRQ_IOC_PCID, - /* PJ5 SLOT: 19, PIN: 3 */ - TX4927_IRQ_IOC_PCIA, - /* PJ5 SLOT: 19, PIN: 4 */ - TX4927_IRQ_IOC_PCIB}, - /* PJ4 SLOT: 20, PIN: 1 */ {TX4927_IRQ_IOC_PCID, - /* PJ4 SLOT: 20, PIN: 2 */ - TX4927_IRQ_IOC_PCIA, - /* PJ4 SLOT: 20, PIN: 3 */ - TX4927_IRQ_IOC_PCIB, - /* PJ4 SLOT: 20, PIN: 4 */ - TX4927_IRQ_IOC_PCIC} -}; - -static int pci_get_irq(const struct pci_dev *dev, int pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; - DBG("pci_get_irq: pin is %d\n", pin); /* IRQ rotation */ irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { - printk("Onboard PCI_SLOT(dev->devfn) is %d\n", - PCI_SLOT(dev->devfn)); - /* IDSEL=A23 is tx4927 onboard pci slot */ - irq = (irq + PCI_SLOT(dev->devfn)) % 4; - irq++; /* 1-4 */ - DBG("irq is now %d\n", irq); - - switch (irq) { - case 1: - irq = TX4927_IRQ_IOC_PCIA; - break; - case 2: - irq = TX4927_IRQ_IOC_PCIB; - break; - case 3: - irq = TX4927_IRQ_IOC_PCIC; - break; - case 4: - irq = TX4927_IRQ_IOC_PCID; - break; - } + if (slot == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { + /* PCI CardSlot (IDSEL=A23) */ + /* PCIA => PCIA */ + irq = (irq + 0 + slot) % 4; } else { /* PCI Backplane */ - DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n", - PCI_SLOT(dev->devfn)); - irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq]; + if (txx9_pci_option & TXX9_PCI_OPT_PICMG) + irq = (irq + 33 - slot) % 4; + else + irq = (irq + 3 + slot) % 4; } - DBG("assigned irq %d\n", irq); - return irq; -} - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char irq; - - printk("PCI Setup for pin %d \n", pin); - - if (dev->device == 0x9130) /* IDE */ - irq = 14; - else - irq = pci_get_irq(dev, pin); + irq++; /* 1-4 */ + switch (irq) { + case 1: + irq = RBTX4927_IRQ_IOC_PCIA; + break; + case 2: + irq = RBTX4927_IRQ_IOC_PCIB; + break; + case 3: + irq = RBTX4927_IRQ_IOC_PCIC; + break; + case 4: + irq = RBTX4927_IRQ_IOC_PCID; + break; + } return irq; } diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c index 64d4510..39c9958 100644 --- a/arch/mips/pci/fixup-rbtx4938.c +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -10,45 +10,28 @@ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ #include -#include -#include -#include - +#include #include -extern struct pci_controller tx4938_pci_controller[]; - -static int pci_get_irq(const struct pci_dev *dev, int pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - int irq = pin; - u8 slot = PCI_SLOT(dev->devfn); - struct pci_controller *controller = (struct pci_controller *)dev->sysdata; - - if (controller == &tx4938_pci_controller[1]) { - /* TX4938 PCIC1 */ - switch (slot) { - case TX4938_PCIC_IDSEL_AD_TO_SLOT(31): - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL) - return RBTX4938_IRQ_IRC + TX4938_IR_ETH0; - break; - case TX4938_PCIC_IDSEL_AD_TO_SLOT(30): - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL) - return RBTX4938_IRQ_IRC + TX4938_IR_ETH1; - break; - } - return 0; - } + int irq = tx4938_pcic1_map_irq(dev, slot); + if (irq >= 0) + return irq; + irq = pin; /* IRQ rotation */ irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) { + if (slot == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { /* PCI CardSlot (IDSEL=A23) */ /* PCIA => PCIA (IDSEL=A23) */ irq = (irq + 0 + slot) % 4; } else { /* PCI Backplane */ - irq = (irq + 33 - slot) % 4; + if (txx9_pci_option & TXX9_PCI_OPT_PICMG) + irq = (irq + 33 - slot) % 4; + else + irq = (irq + 3 + slot) % 4; } irq++; /* 1-4 */ @@ -69,19 +52,6 @@ static int pci_get_irq(const struct pci_dev *dev, int pin) return irq; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char irq = 0; - - irq = pci_get_irq(dev, pin); - - printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", - dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), irq); - - return irq; -} - /* * Do platform specific device initialization at pci_enable_device() time */ diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index 5d398f6..8a17a39 100644 --- a/arch/mips/pci/ops-tx3927.c +++ b/arch/mips/pci/ops-tx3927.c @@ -8,7 +8,7 @@ * * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c * - * Define the pci_ops for JMR3927. + * Define the pci_ops for TX3927. * * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven @@ -39,7 +39,7 @@ #include #include -#include +#include static inline int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where) @@ -68,7 +68,7 @@ static inline int check_abort(void) return PCIBIOS_SUCCESSFUL; } -static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, +static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { int ret; @@ -94,7 +94,7 @@ static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, return check_abort(); } -static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, +static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { int ret; @@ -125,7 +125,80 @@ static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, return check_abort(); } -struct pci_ops jmr3927_pci_ops = { - jmr3927_pci_read_config, - jmr3927_pci_write_config, +static struct pci_ops tx3927_pci_ops = { + .read = tx3927_pci_read_config, + .write = tx3927_pci_write_config, }; + +void __init tx3927_pcic_setup(struct pci_controller *channel, + unsigned long sdram_size, int extarb) +{ + unsigned long flags; + unsigned long io_base = + channel->io_resource->start + mips_io_port_base - IO_BASE; + unsigned long io_size = + channel->io_resource->end - channel->io_resource->start; + unsigned long io_pciaddr = + channel->io_resource->start - channel->io_offset; + unsigned long mem_base = + channel->mem_resource->start; + unsigned long mem_size = + channel->mem_resource->end - channel->mem_resource->start; + unsigned long mem_pciaddr = + channel->mem_resource->start - channel->mem_offset; + + printk(KERN_INFO "TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s", + tx3927_pcicptr->did, tx3927_pcicptr->vid, + tx3927_pcicptr->rid, + extarb ? "External" : "Internal"); + channel->pci_ops = &tx3927_pci_ops; + + local_irq_save(flags); + /* Disable External PCI Config. Access */ + tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; +#ifdef __BIG_ENDIAN + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | + TX3927_PCIC_LBC_TIBSE | + TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; +#endif + /* LB->PCI mappings */ + tx3927_pcicptr->iomas = ~(io_size - 1); + tx3927_pcicptr->ilbioma = io_base; + tx3927_pcicptr->ipbioma = io_pciaddr; + tx3927_pcicptr->mmas = ~(mem_size - 1); + tx3927_pcicptr->ilbmma = mem_base; + tx3927_pcicptr->ipbmma = mem_pciaddr; + /* PCI->LB mappings */ + tx3927_pcicptr->iobas = 0xffffffff; + tx3927_pcicptr->ioba = 0; + tx3927_pcicptr->tlbioma = 0; + tx3927_pcicptr->mbas = ~(sdram_size - 1); + tx3927_pcicptr->mba = 0; + tx3927_pcicptr->tlbmma = 0; + /* Enable Direct mapping Address Space Decoder */ + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; + + /* Clear All Local Bus Status */ + tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; + /* Enable All Local Bus Interrupts */ + tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; + /* Clear All PCI Status Error */ + tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; + /* Enable All PCI Status Error Interrupts */ + tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; + + /* PCIC Int => IRC IRQ10 */ + tx3927_pcicptr->il = TX3927_IR_PCI; + /* Target Control (per errata) */ + tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; + + /* Enable Bus Arbiter */ + if (!extarb) + tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; + + tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_IO | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + local_irq_restore(flags); +} diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 54730ee..c6b49bc 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -1,206 +1,408 @@ /* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * Define the pci_ops for the PCIC on Toshiba TX4927, TX4938, etc. * - * Copyright (C) 2000-2001 Toshiba Corporation - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) - * - * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c - * - * Define the pci_ops for the Toshiba rbtx4927 - * - * Much of the code is derived from the original DDB5074 port by - * Geert Uytterhoeven - * - * Copyright 2004 MontaVista Software Inc. - * Author: Manish Lachwani (mlachwani@mvista.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. + * Based on linux/arch/mips/pci/ops-tx4938.c, + * linux/arch/mips/pci/fixup-rbtx4938.c, + * linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 2003-2005 (c) MontaVista Software, Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * This 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 -#include #include -#include -#include - -/* initialize in setup */ -struct resource pci_io_resource = { - .name = "TX4927 PCI IO SPACE", - .start = 0x1000, - .end = (0x1000 + (TX4927_PCIIO_SIZE)) - 1, - .flags = IORESOURCE_IO -}; +#include -/* initialize in setup */ -struct resource pci_mem_resource = { - .name = "TX4927 PCI MEM SPACE", - .start = TX4927_PCIMEM, - .end = TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; +static struct { + struct pci_controller *channel; + struct tx4927_pcic_reg __iomem *pcicptr; +} pcicptrs[2]; /* TX4938 has 2 pcic */ + +static void __init set_tx4927_pcicptr(struct pci_controller *channel, + struct tx4927_pcic_reg __iomem *pcicptr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (pcicptrs[i].channel == channel) { + pcicptrs[i].pcicptr = pcicptr; + return; + } + } + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (!pcicptrs[i].channel) { + pcicptrs[i].channel = channel; + pcicptrs[i].pcicptr = pcicptr; + return; + } + } + BUG(); +} -static int mkaddr(int bus, int dev_fn, int where, int *flagsp) +struct tx4927_pcic_reg __iomem *get_tx4927_pcicptr( + struct pci_controller *channel) { - if (bus > 0) { - /* Type 1 configuration */ - tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; - } else { - if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) - return -1; + int i; - /* Type 0 configuration */ - tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (pcicptrs[i].channel == channel) + return pcicptrs[i].pcicptr; } + return NULL; +} + +static int mkaddr(struct pci_bus *bus, unsigned int devfn, int where, + struct tx4927_pcic_reg __iomem *pcicptr) +{ + if (bus->parent == NULL && + devfn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) + return -1; + __raw_writel(((bus->number & 0xff) << 0x10) + | ((devfn & 0xff) << 0x08) | (where & 0xfc) + | (bus->parent ? 1 : 0), + &pcicptr->g2pcfgadrs); /* clear M_ABORT and Disable M_ABORT Int. */ - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr->pcistatus & 0x0000ffff) | - (PCI_STATUS_REC_MASTER_ABORT << 16); - tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) + | (PCI_STATUS_REC_MASTER_ABORT << 16), + &pcicptr->pcistatus); return 0; } -static int check_abort(int flags) +static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr) { int code = PCIBIOS_SUCCESSFUL; - if (tx4927_pcicptr-> - pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr-> - pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT - << 16); - tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + + /* wait write cycle completion before checking error status */ + while (__raw_readl(&pcicptr->pcicstatus) & TX4927_PCIC_PCICSTATUS_IWB) + ; + if (__raw_readl(&pcicptr->pcistatus) + & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) + | (PCI_STATUS_REC_MASTER_ABORT << 16), + &pcicptr->pcistatus); code = PCIBIOS_DEVICE_NOT_FOUND; } return code; } -static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) +static u8 icd_readb(int offset, struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 3; +#endif + return __raw_readb((void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static u16 icd_readw(int offset, struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 2; +#endif + return __raw_readw((void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static u32 icd_readl(struct tx4927_pcic_reg __iomem *pcicptr) +{ + return __raw_readl(&pcicptr->g2pcfgdata); +} +static void icd_writeb(u8 val, int offset, + struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 3; +#endif + __raw_writeb(val, (void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static void icd_writew(u16 val, int offset, + struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 2; +#endif + __raw_writew(val, (void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static void icd_writel(u32 val, struct tx4927_pcic_reg __iomem *pcicptr) { - int flags, retval, dev, busno, func; + __raw_writel(val, &pcicptr->g2pcfgdata); +} - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); +static struct tx4927_pcic_reg __iomem *pci_bus_to_pcicptr(struct pci_bus *bus) +{ + struct pci_controller *channel = bus->sysdata; + return get_tx4927_pcicptr(channel); +} - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busno = bus->number; - } else { - busno = 0; - } +static int tx4927_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus); - if (mkaddr(busno, devfn, where, &flags)) + if (mkaddr(bus, devfn, where, pcicptr)) { + *val = 0xffffffff; return -1; - + } switch (size) { case 1: - *val = *(volatile u8 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)); -#else - ((where & 0x3) ^ 0x3)); -#endif + *val = icd_readb(where & 3, pcicptr); break; case 2: - *val = *(volatile u16 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)); -#else - ((where & 0x3) ^ 0x2)); -#endif - break; - case 4: - *val = tx4927_pcicptr->g2pcfgdata; + *val = icd_readw(where & 3, pcicptr); break; + default: + *val = icd_readl(pcicptr); } + return check_abort(pcicptr); +} - retval = check_abort(flags); - if (retval == PCIBIOS_DEVICE_NOT_FOUND) - *val = 0xffffffff; +static int tx4927_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus); - return retval; + if (mkaddr(bus, devfn, where, pcicptr)) + return -1; + switch (size) { + case 1: + icd_writeb(val, where & 3, pcicptr); + break; + case 2: + icd_writew(val, where & 3, pcicptr); + break; + default: + icd_writel(val, pcicptr); + } + return check_abort(pcicptr); } -static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) +static struct pci_ops tx4927_pci_ops = { + .read = tx4927_pci_config_read, + .write = tx4927_pci_config_write, +}; + +static struct { + u8 trdyto; + u8 retryto; + u16 gbwc; +} tx4927_pci_opts __devinitdata = { + .trdyto = 0, + .retryto = 0, + .gbwc = 0xfe0, /* 4064 GBUSCLK for CCFG.GTOT=0b11 */ +}; + +void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr, + struct pci_controller *channel, int extarb) { - int flags, dev, busno, func; - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); + int i; + unsigned long flags; - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busno = bus->number; - } else { - busno = 0; - } + set_tx4927_pcicptr(channel, pcicptr); - if (mkaddr(busno, devfn, where, &flags)) - return -1; + if (!channel->pci_ops) + printk(KERN_INFO + "PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + __raw_readl(&pcicptr->pciid) >> 16, + __raw_readl(&pcicptr->pciid) & 0xffff, + __raw_readl(&pcicptr->pciccrev) & 0xff, + extarb ? "External" : "Internal"); + channel->pci_ops = &tx4927_pci_ops; - switch (size) { - case 1: - *(volatile u8 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)) = val; + local_irq_save(flags); + + /* Disable All Initiator Space */ + __raw_writel(__raw_readl(&pcicptr->pciccfg) + & ~(TX4927_PCIC_PCICCFG_G2PMEN(0) + | TX4927_PCIC_PCICCFG_G2PMEN(1) + | TX4927_PCIC_PCICCFG_G2PMEN(2) + | TX4927_PCIC_PCICCFG_G2PIOEN), + &pcicptr->pciccfg); + + /* GB->PCI mappings */ + __raw_writel((channel->io_resource->end - channel->io_resource->start) + >> 4, + &pcicptr->g2piomask); + ____raw_writeq((channel->io_resource->start + + channel->io_map_base - IO_BASE) | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PIOGBASE_ECHG #else - ((where & 0x3) ^ 0x3)) = val; + TX4927_PCIC_G2PIOGBASE_BSDIS #endif - break; - - case 2: - *(volatile u16 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)) = val; + , &pcicptr->g2piogbase); + ____raw_writeq(channel->io_resource->start - channel->io_offset, + &pcicptr->g2piopbase); + for (i = 0; i < 3; i++) { + __raw_writel(0, &pcicptr->g2pmmask[i]); + ____raw_writeq(0, &pcicptr->g2pmgbase[i]); + ____raw_writeq(0, &pcicptr->g2pmpbase[i]); + } + if (channel->mem_resource->end) { + __raw_writel((channel->mem_resource->end + - channel->mem_resource->start) >> 4, + &pcicptr->g2pmmask[0]); + ____raw_writeq(channel->mem_resource->start | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PMnGBASE_ECHG #else - ((where & 0x3) ^ 0x2)) = val; + TX4927_PCIC_G2PMnGBASE_BSDIS #endif - break; - case 4: - tx4927_pcicptr->g2pcfgdata = val; - break; + , &pcicptr->g2pmgbase[0]); + ____raw_writeq(channel->mem_resource->start - + channel->mem_offset, + &pcicptr->g2pmpbase[0]); + } + /* PCI->GB mappings (I/O 256B) */ + __raw_writel(0, &pcicptr->p2giopbase); /* 256B */ + ____raw_writeq(0, &pcicptr->p2giogbase); + /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ + __raw_writel(0, &pcicptr->p2gm0plbase); + __raw_writel(0, &pcicptr->p2gm0pubase); + ____raw_writeq(TX4927_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GMnGBASE_TECHG +#else + TX4927_PCIC_P2GMnGBASE_TBSDIS +#endif + , &pcicptr->p2gmgbase[0]); + /* PCI->GB mappings (MEM 16MB) */ + __raw_writel(0xffffffff, &pcicptr->p2gm1plbase); + __raw_writel(0xffffffff, &pcicptr->p2gm1pubase); + ____raw_writeq(0, &pcicptr->p2gmgbase[1]); + /* PCI->GB mappings (MEM 1MB) */ + __raw_writel(0xffffffff, &pcicptr->p2gm2pbase); /* 1MB */ + ____raw_writeq(0, &pcicptr->p2gmgbase[2]); + + /* Clear all (including IRBER) except for GBWC */ + __raw_writel((tx4927_pci_opts.gbwc << 16) + & TX4927_PCIC_PCICCFG_GBWC_MASK, + &pcicptr->pciccfg); + /* Enable Initiator Memory Space */ + if (channel->mem_resource->end) + __raw_writel(__raw_readl(&pcicptr->pciccfg) + | TX4927_PCIC_PCICCFG_G2PMEN(0), + &pcicptr->pciccfg); + /* Enable Initiator I/O Space */ + if (channel->io_resource->end) + __raw_writel(__raw_readl(&pcicptr->pciccfg) + | TX4927_PCIC_PCICCFG_G2PIOEN, + &pcicptr->pciccfg); + /* Enable Initiator Config */ + __raw_writel(__raw_readl(&pcicptr->pciccfg) + | TX4927_PCIC_PCICCFG_ICAEN | TX4927_PCIC_PCICCFG_TCAR, + &pcicptr->pciccfg); + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + __raw_writel(0, &pcicptr->pcicfg1); + + __raw_writel((__raw_readl(&pcicptr->g2ptocnt) & ~0xffff) + | (tx4927_pci_opts.trdyto & 0xff) + | ((tx4927_pci_opts.retryto & 0xff) << 8), + &pcicptr->g2ptocnt); + + /* Clear All Local Bus Status */ + __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicstatus); + /* Enable All Local Bus Interrupts */ + __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicmask); + /* Clear All Initiator Status */ + __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pstatus); + /* Enable All Initiator Interrupts */ + __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pmask); + /* Clear All PCI Status Error */ + __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) + | (TX4927_PCIC_PCISTATUS_ALL << 16), + &pcicptr->pcistatus); + /* Enable All PCI Status Error Interrupts */ + __raw_writel(TX4927_PCIC_PCISTATUS_ALL, &pcicptr->pcimask); + + if (!extarb) { + /* Reset Bus Arbiter */ + __raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg); + __raw_writel(0, &pcicptr->pbabm); + /* Enable Bus Arbiter */ + __raw_writel(TX4927_PCIC_PBACFG_PBAEN, &pcicptr->pbacfg); } - return check_abort(flags); + __raw_writel(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR, + &pcicptr->pcistatus); + local_irq_restore(flags); + + printk(KERN_DEBUG + "PCI: COMMAND=%04x,PCIMASK=%04x," + "TRDYTO=%02x,RETRYTO=%02x,GBWC=%03x\n", + __raw_readl(&pcicptr->pcistatus) & 0xffff, + __raw_readl(&pcicptr->pcimask) & 0xffff, + __raw_readl(&pcicptr->g2ptocnt) & 0xff, + (__raw_readl(&pcicptr->g2ptocnt) & 0xff00) >> 8, + (__raw_readl(&pcicptr->pciccfg) >> 16) & 0xfff); } -struct pci_ops tx4927_pci_ops = { - tx4927_pcibios_read_config, - tx4927_pcibios_write_config -}; +static void tx4927_report_pcic_status1(struct tx4927_pcic_reg __iomem *pcicptr) +{ + __u16 pcistatus = (__u16)(__raw_readl(&pcicptr->pcistatus) >> 16); + __u32 g2pstatus = __raw_readl(&pcicptr->g2pstatus); + __u32 pcicstatus = __raw_readl(&pcicptr->pcicstatus); + static struct { + __u32 flag; + const char *str; + } pcistat_tbl[] = { + { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, + { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, + { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, + { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, + { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, + { PCI_STATUS_PARITY, "MasterParityError" }, + }, g2pstat_tbl[] = { + { TX4927_PCIC_G2PSTATUS_TTOE, "TIOE" }, + { TX4927_PCIC_G2PSTATUS_RTOE, "RTOE" }, + }, pcicstat_tbl[] = { + { TX4927_PCIC_PCICSTATUS_PME, "PME" }, + { TX4927_PCIC_PCICSTATUS_TLB, "TLB" }, + { TX4927_PCIC_PCICSTATUS_NIB, "NIB" }, + { TX4927_PCIC_PCICSTATUS_ZIB, "ZIB" }, + { TX4927_PCIC_PCICSTATUS_PERR, "PERR" }, + { TX4927_PCIC_PCICSTATUS_SERR, "SERR" }, + { TX4927_PCIC_PCICSTATUS_GBE, "GBE" }, + { TX4927_PCIC_PCICSTATUS_IWB, "IWB" }, + }; + int i, cont; -/* - * h/w only supports devices 0x00 to 0x14 - */ -struct pci_controller tx4927_controller = { - .pci_ops = &tx4927_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, -}; + printk(KERN_ERR ""); + if (pcistatus & TX4927_PCIC_PCISTATUS_ALL) { + printk(KERN_CONT "pcistat:%04x(", pcistatus); + for (i = 0, cont = 0; i < ARRAY_SIZE(pcistat_tbl); i++) + if (pcistatus & pcistat_tbl[i].flag) + printk(KERN_CONT "%s%s", + cont++ ? " " : "", pcistat_tbl[i].str); + printk(KERN_CONT ") "); + } + if (g2pstatus & TX4927_PCIC_G2PSTATUS_ALL) { + printk(KERN_CONT "g2pstatus:%08x(", g2pstatus); + for (i = 0, cont = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) + if (g2pstatus & g2pstat_tbl[i].flag) + printk(KERN_CONT "%s%s", + cont++ ? " " : "", g2pstat_tbl[i].str); + printk(KERN_CONT ") "); + } + if (pcicstatus & TX4927_PCIC_PCICSTATUS_ALL) { + printk(KERN_CONT "pcicstatus:%08x(", pcicstatus); + for (i = 0, cont = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) + if (pcicstatus & pcicstat_tbl[i].flag) + printk(KERN_CONT "%s%s", + cont++ ? " " : "", pcicstat_tbl[i].str); + printk(KERN_CONT ")"); + } + printk(KERN_CONT "\n"); +} + +void tx4927_report_pcic_status(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (pcicptrs[i].pcicptr) + tx4927_report_pcic_status1(pcicptrs[i].pcicptr); + } +} diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c deleted file mode 100644 index 34494b8..0000000 --- a/arch/mips/pci/ops-tx4938.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Define the pci_ops for the Toshiba rbtx4938 - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include - -#include -#include - -/* initialize in setup */ -struct resource pci_io_resource = { - .name = "pci IO space", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO -}; - -/* initialize in setup */ -struct resource pci_mem_resource = { - .name = "pci memory space", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM -}; - -struct resource tx4938_pcic1_pci_io_resource = { - .name = "PCI1 IO", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO -}; -struct resource tx4938_pcic1_pci_mem_resource = { - .name = "PCI1 mem", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM -}; - -static int mkaddr(int bus, int dev_fn, int where, - struct tx4938_pcic_reg *pcicptr) -{ - if (bus > 0) { - /* Type 1 configuration */ - pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; - } else { - if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) - return -1; - - /* Type 0 configuration */ - pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc); - } - /* clear M_ABORT and Disable M_ABORT Int. */ - pcicptr->pcistatus = - (pcicptr->pcistatus & 0x0000ffff) | - (PCI_STATUS_REC_MASTER_ABORT << 16); - pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; - - return 0; -} - -static int check_abort(struct tx4938_pcic_reg *pcicptr) -{ - int code = PCIBIOS_SUCCESSFUL; - /* wait write cycle completion before checking error status */ - while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) - ; - if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { - pcicptr->pcistatus = - (pcicptr-> - pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT - << 16); - pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; - code = PCIBIOS_DEVICE_NOT_FOUND; - } - return code; -} - -extern struct pci_controller tx4938_pci_controller[]; -extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch); - -static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus) -{ - struct pci_controller *channel = bus->sysdata; - return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]); -} - -static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - int retval, dev, busno, func; - struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); - void __iomem *cfgdata = - (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* check if the bus is top-level */ - if (bus->parent != NULL) - busno = bus->number; - else { - busno = 0; - } - - if (mkaddr(busno, devfn, where, pcicptr)) - return -1; - - switch (size) { - case 1: -#ifdef __BIG_ENDIAN - cfgdata += (where & 3) ^ 3; -#else - cfgdata += where & 3; -#endif - *val = __raw_readb(cfgdata); - break; - case 2: -#ifdef __BIG_ENDIAN - cfgdata += (where & 2) ^ 2; -#else - cfgdata += where & 2; -#endif - *val = __raw_readw(cfgdata); - break; - case 4: - *val = __raw_readl(cfgdata); - break; - } - - retval = check_abort(pcicptr); - if (retval == PCIBIOS_DEVICE_NOT_FOUND) - *val = 0xffffffff; - - return retval; -} - -static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - int dev, busno, func; - struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); - void __iomem *cfgdata = - (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; - - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busno = bus->number; - } else { - busno = 0; - } - - if (mkaddr(busno, devfn, where, pcicptr)) - return -1; - - switch (size) { - case 1: -#ifdef __BIG_ENDIAN - cfgdata += (where & 3) ^ 3; -#else - cfgdata += where & 3; -#endif - __raw_writeb(val, cfgdata); - break; - case 2: -#ifdef __BIG_ENDIAN - cfgdata += (where & 2) ^ 2; -#else - cfgdata += where & 2; -#endif - __raw_writew(val, cfgdata); - break; - case 4: - __raw_writel(val, cfgdata); - break; - } - - return check_abort(pcicptr); -} - -struct pci_ops tx4938_pci_ops = { - tx4938_pcibios_read_config, - tx4938_pcibios_write_config -}; - -struct pci_controller tx4938_pci_controller[] = { - /* h/w only supports devices 0x00 to 0x14 */ - { - .pci_ops = &tx4938_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, - }, - /* h/w only supports devices 0x00 to 0x14 */ - { - .pci_ops = &tx4938_pci_ops, - .io_resource = &tx4938_pcic1_pci_io_resource, - .mem_resource = &tx4938_pcic1_pci_mem_resource, - } -}; diff --git a/arch/mips/pci/pci-jmr3927.c b/arch/mips/pci/pci-jmr3927.c deleted file mode 100644 index 7fb6bd7..0000000 --- a/arch/mips/pci/pci-jmr3927.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * Copyright (C) 2000-2001 Toshiba Corporation - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include - -#include -#include - -struct resource pci_io_resource = { - .name = "IO MEM", - .start = 0x1000, /* reserve regacy I/O space */ - .end = 0x1000 + JMR3927_PCIIO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -struct resource pci_mem_resource = { - .name = "PCI MEM", - .start = JMR3927_PCIMEM, - .end = JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops jmr3927_pci_ops; - -struct pci_controller jmr3927_controller = { - .pci_ops = &jmr3927_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, - .mem_offset = JMR3927_PCIMEM -}; diff --git a/arch/mips/pci/pci-tx4927.c b/arch/mips/pci/pci-tx4927.c new file mode 100644 index 0000000..27e86a0 --- /dev/null +++ b/arch/mips/pci/pci-tx4927.c @@ -0,0 +1,83 @@ +/* + * linux/arch/mips/pci/pci-tx4927.c + * + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001, 2003-2005 MontaVista Software Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * 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. + */ +#include +#include +#include +#include +#include + +int __init tx4927_report_pciclk(void) +{ + int pciclk = 0; + + printk(KERN_INFO "PCIC --%s PCICLK:", + (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66) ? + " PCI66" : ""); + if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) { + u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg); + switch ((unsigned long)ccfg & + TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + pciclk = txx9_cpu_clock * 2 / 5; break; + case TX4927_CCFG_PCIDIVMODE_3: + pciclk = txx9_cpu_clock / 3; break; + case TX4927_CCFG_PCIDIVMODE_5: + pciclk = txx9_cpu_clock / 5; break; + case TX4927_CCFG_PCIDIVMODE_6: + pciclk = txx9_cpu_clock / 6; break; + } + printk("Internal(%u.%uMHz)", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); + } else { + printk("External"); + pciclk = -1; + } + printk("\n"); + return pciclk; +} + +int __init tx4927_pciclk66_setup(void) +{ + int pciclk; + + /* Assert M66EN */ + tx4927_ccfg_set(TX4927_CCFG_PCI66); + /* Double PCICLK (if possible) */ + if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg); + pcidivmode = (unsigned long)ccfg & + TX4927_CCFG_PCIDIVMODE_MASK; + switch (pcidivmode) { + case TX4927_CCFG_PCIDIVMODE_5: + case TX4927_CCFG_PCIDIVMODE_2_5: + pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5; + pciclk = txx9_cpu_clock * 2 / 5; + break; + case TX4927_CCFG_PCIDIVMODE_6: + case TX4927_CCFG_PCIDIVMODE_3: + default: + pcidivmode = TX4927_CCFG_PCIDIVMODE_3; + pciclk = txx9_cpu_clock / 3; + } + tx4927_ccfg_change(TX4927_CCFG_PCIDIVMODE_MASK, + pcidivmode); + printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", + (unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg)); + } else + pciclk = -1; + return pciclk; +} diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c new file mode 100644 index 0000000..e537551 --- /dev/null +++ b/arch/mips/pci/pci-tx4938.c @@ -0,0 +1,134 @@ +/* + * linux/arch/mips/pci/pci-tx4938.c + * + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001, 2003-2005 MontaVista Software Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * 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. + */ +#include +#include +#include +#include +#include + +int __init tx4938_report_pciclk(void) +{ + int pciclk = 0; + + printk(KERN_INFO "PCIC --%s PCICLK:", + (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ? + " PCI66" : ""); + if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { + u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); + switch ((unsigned long)ccfg & + TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_4: + pciclk = txx9_cpu_clock / 4; break; + case TX4938_CCFG_PCIDIVMODE_4_5: + pciclk = txx9_cpu_clock * 2 / 9; break; + case TX4938_CCFG_PCIDIVMODE_5: + pciclk = txx9_cpu_clock / 5; break; + case TX4938_CCFG_PCIDIVMODE_5_5: + pciclk = txx9_cpu_clock * 2 / 11; break; + case TX4938_CCFG_PCIDIVMODE_8: + pciclk = txx9_cpu_clock / 8; break; + case TX4938_CCFG_PCIDIVMODE_9: + pciclk = txx9_cpu_clock / 9; break; + case TX4938_CCFG_PCIDIVMODE_10: + pciclk = txx9_cpu_clock / 10; break; + case TX4938_CCFG_PCIDIVMODE_11: + pciclk = txx9_cpu_clock / 11; break; + } + printk("Internal(%u.%uMHz)", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); + } else { + printk("External"); + pciclk = -1; + } + printk("\n"); + return pciclk; +} + +void __init tx4938_report_pci1clk(void) +{ + __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); + unsigned int pciclk = + txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2); + + printk(KERN_INFO "PCIC1 -- %sPCICLK:%u.%uMHz\n", + (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); +} + +int __init tx4938_pciclk66_setup(void) +{ + int pciclk; + + /* Assert M66EN */ + tx4938_ccfg_set(TX4938_CCFG_PCI66); + /* Double PCICLK (if possible) */ + if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); + pcidivmode = (unsigned long)ccfg & + TX4938_CCFG_PCIDIVMODE_MASK; + switch (pcidivmode) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + pcidivmode = TX4938_CCFG_PCIDIVMODE_4; + pciclk = txx9_cpu_clock / 4; + break; + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; + pciclk = txx9_cpu_clock * 2 / 9; + break; + case TX4938_CCFG_PCIDIVMODE_10: + case TX4938_CCFG_PCIDIVMODE_5: + pcidivmode = TX4938_CCFG_PCIDIVMODE_5; + pciclk = txx9_cpu_clock / 5; + break; + case TX4938_CCFG_PCIDIVMODE_11: + case TX4938_CCFG_PCIDIVMODE_5_5: + default: + pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; + pciclk = txx9_cpu_clock * 2 / 11; + break; + } + tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK, + pcidivmode); + printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", + (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg)); + } else + pciclk = -1; + return pciclk; +} + +int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +{ + if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { + switch (slot) { + case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): + if (__raw_readq(&tx4938_ccfgptr->pcfg) & + TX4938_PCFG_ETH0_SEL) + return TXX9_IRQ_BASE + TX4938_IR_ETH0; + break; + case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): + if (__raw_readq(&tx4938_ccfgptr->pcfg) & + TX4938_PCFG_ETH1_SEL) + return TXX9_IRQ_BASE + TX4938_IR_ETH1; + break; + } + return 0; + } + return -1; +} diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 98d1034..b8cdb19 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -1,6 +1,12 @@ config TOSHIBA_FPCIB0 bool "FPCIB0 Backplane Support" - depends on TOSHIBA_RBTX4927 + depends on PCI && (SYS_HAS_CPU_TX49XX || SYS_HAS_CPU_TX39XX) + select I8259 + +config PICMG_PCI_BACKPLANE_DEFAULT + bool "Support for PICMG PCI Backplane" + depends on PCI && (SYS_HAS_CPU_TX49XX || SYS_HAS_CPU_TX39XX) + default y if !TOSHIBA_FPCIB0 if TOSHIBA_RBTX4938 @@ -26,3 +32,6 @@ config TX4938_NAND_BOOT Select this option if you need to use NAND boot. endif + +config PCI_TX4927 + bool diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 8cb4a7e..b80b6e0 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -2,6 +2,8 @@ # Makefile for common code for TXx9 based systems # +obj-y += setup.o +obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_TOSHIBA_RBTX4927) += mem_tx4927.o irq_tx4927.o obj-$(CONFIG_TOSHIBA_RBTX4938) += mem_tx4938.o irq_tx4938.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c new file mode 100644 index 0000000..8173faa --- /dev/null +++ b/arch/mips/txx9/generic/pci.c @@ -0,0 +1,377 @@ +/* + * linux/arch/mips/txx9/pci.c + * + * Based on linux/arch/mips/txx9/rbtx4927/setup.c, + * linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001-2005 MontaVista Software Inc. + * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * 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. + */ +#include +#include +#include +#include +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#include +#include +#endif + +static int __init +early_read_config_word(struct pci_controller *hose, + int top_bus, int bus, int devfn, int offset, u16 *value) +{ + struct pci_dev fake_dev; + struct pci_bus fake_bus; + + fake_dev.bus = &fake_bus; + fake_dev.sysdata = hose; + fake_dev.devfn = devfn; + fake_bus.number = bus; + fake_bus.sysdata = hose; + fake_bus.ops = hose->pci_ops; + + if (bus != top_bus) + /* Fake a parent bus structure. */ + fake_bus.parent = &fake_bus; + else + fake_bus.parent = NULL; + + return pci_read_config_word(&fake_dev, offset, value); +} + +int __init txx9_pci66_check(struct pci_controller *hose, int top_bus, + int current_bus) +{ + u32 pci_devfn; + unsigned short vid; + int cap66 = -1; + u16 stat; + + /* It seems SLC90E66 needs some time after PCI reset... */ + mdelay(80); + + printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n"); + + for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { + if (PCI_FUNC(pci_devfn)) + continue; + if (early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_VENDOR_ID, &vid) != + PCIBIOS_SUCCESSFUL) + continue; + if (vid == 0xffff) + continue; + + /* check 66MHz capability */ + if (cap66 < 0) + cap66 = 1; + if (cap66) { + early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_STATUS, &stat); + if (!(stat & PCI_STATUS_66MHZ)) { + printk(KERN_DEBUG + "PCI: %02x:%02x not 66MHz capable.\n", + current_bus, pci_devfn); + cap66 = 0; + break; + } + } + } + return cap66 > 0; +} + +static struct resource primary_pci_mem_res[2] = { + { .name = "PCI MEM" }, + { .name = "PCI MMIO" }, +}; +static struct resource primary_pci_io_res = { .name = "PCI IO" }; +struct pci_controller txx9_primary_pcic = { + .mem_resource = &primary_pci_mem_res[0], + .io_resource = &primary_pci_io_res, +}; + +#ifdef CONFIG_64BIT +int txx9_pci_mem_high __initdata = 1; +#else +int txx9_pci_mem_high __initdata; +#endif + +/* + * allocate pci_controller and resources. + * mem_base, io_base: physical addresss. 0 for auto assignment. + * mem_size and io_size means max size on auto assignment. + * pcic must be &txx9_primary_pcic or NULL. + */ +struct pci_controller *__init +txx9_alloc_pci_controller(struct pci_controller *pcic, + unsigned long mem_base, unsigned long mem_size, + unsigned long io_base, unsigned long io_size) +{ + struct pcic { + struct pci_controller c; + struct resource r_mem[2]; + struct resource r_io; + } *new = NULL; + int min_size = 0x10000; + + if (!pcic) { + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + new->r_mem[0].name = "PCI mem"; + new->r_mem[1].name = "PCI mmio"; + new->r_io.name = "PCI io"; + new->c.mem_resource = new->r_mem; + new->c.io_resource = &new->r_io; + pcic = &new->c; + } else + BUG_ON(pcic != &txx9_primary_pcic); + pcic->io_resource->flags = IORESOURCE_IO; + + /* + * for auto assignment, first search a (big) region for PCI + * MEM, then search a region for PCI IO. + */ + if (mem_base) { + pcic->mem_resource[0].start = mem_base; + pcic->mem_resource[0].end = mem_base + mem_size - 1; + if (request_resource(&iomem_resource, &pcic->mem_resource[0])) + goto free_and_exit; + } else { + unsigned long min = 0, max = 0x20000000; /* low 512MB */ + if (!mem_size) { + /* default size for auto assignment */ + if (txx9_pci_mem_high) + mem_size = 0x20000000; /* mem:512M(max) */ + else + mem_size = 0x08000000; /* mem:128M(max) */ + } + if (txx9_pci_mem_high) { + min = 0x20000000; + max = 0xe0000000; + } + /* search free region for PCI MEM */ + for (; mem_size >= min_size; mem_size /= 2) { + if (allocate_resource(&iomem_resource, + &pcic->mem_resource[0], + mem_size, min, max, + mem_size, NULL, NULL) == 0) + break; + } + if (mem_size < min_size) + goto free_and_exit; + } + + pcic->mem_resource[1].flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (io_base) { + pcic->mem_resource[1].start = io_base; + pcic->mem_resource[1].end = io_base + io_size - 1; + if (request_resource(&iomem_resource, &pcic->mem_resource[1])) + goto release_and_exit; + } else { + if (!io_size) + /* default size for auto assignment */ + io_size = 0x01000000; /* io:16M(max) */ + /* search free region for PCI IO in low 512MB */ + for (; io_size >= min_size; io_size /= 2) { + if (allocate_resource(&iomem_resource, + &pcic->mem_resource[1], + io_size, 0, 0x20000000, + io_size, NULL, NULL) == 0) + break; + } + if (io_size < min_size) + goto release_and_exit; + io_base = pcic->mem_resource[1].start; + } + + pcic->mem_resource[0].flags = IORESOURCE_MEM; + if (pcic == &txx9_primary_pcic && + mips_io_port_base == (unsigned long)-1) { + /* map ioport 0 to PCI I/O space address 0 */ + set_io_port_base(IO_BASE + pcic->mem_resource[1].start); + pcic->io_resource->start = 0; + pcic->io_offset = 0; /* busaddr == ioaddr */ + pcic->io_map_base = IO_BASE + pcic->mem_resource[1].start; + } else { + /* physaddr to ioaddr */ + pcic->io_resource->start = + io_base - (mips_io_port_base - IO_BASE); + pcic->io_offset = io_base - (mips_io_port_base - IO_BASE); + pcic->io_map_base = mips_io_port_base; + } + pcic->io_resource->end = pcic->io_resource->start + io_size - 1; + + pcic->mem_offset = 0; /* busaddr == physaddr */ + + printk(KERN_INFO "PCI: IO 0x%08llx-0x%08llx MEM 0x%08llx-0x%08llx\n", + (unsigned long long)pcic->mem_resource[1].start, + (unsigned long long)pcic->mem_resource[1].end, + (unsigned long long)pcic->mem_resource[0].start, + (unsigned long long)pcic->mem_resource[0].end); + + /* register_pci_controller() will request MEM resource */ + release_resource(&pcic->mem_resource[0]); + return pcic; + release_and_exit: + release_resource(&pcic->mem_resource[0]); + free_and_exit: + kfree(new); + printk(KERN_ERR "PCI: Failed to allocate resources.\n"); + return NULL; +} + +static int __init +txx9_arch_pci_init(void) +{ + PCIBIOS_MIN_IO = 0x8000; /* reseve legacy I/O space */ + return 0; +} +arch_initcall(txx9_arch_pci_init); + +/* IRQ/IDSEL mapping */ +int txx9_pci_option = +#ifdef CONFIG_PICMG_PCI_BACKPLANE_DEFAULT + TXX9_PCI_OPT_PICMG | +#endif + TXX9_PCI_OPT_CLK_AUTO; + +enum txx9_pci_err_action txx9_pci_err_action = TXX9_PCI_ERR_REPORT; + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static irqreturn_t i8259_interrupt(int irq, void *dev_id) +{ + int isairq; + + isairq = i8259_irq(); + if (unlikely(isairq <= I8259A_IRQ_BASE)) + return IRQ_NONE; + generic_handle_irq(isairq); + return IRQ_HANDLED; +} + +static int __init +txx9_i8259_irq_setup(int irq) +{ + int err; + + init_i8259_irqs(); + err = request_irq(irq, &i8259_interrupt, IRQF_DISABLED|IRQF_SHARED, + "cascade(i8259)", (void *)(long)irq); + if (!err) + printk(KERN_INFO "PCI-ISA bridge PIC (irq %d)\n", irq); + return err; +} + +static void __init quirk_slc90e66_bridge(struct pci_dev *dev) +{ + int irq; /* PCI/ISA Bridge interrupt */ + u8 reg_64; + u32 reg_b0; + u8 reg_e1; + irq = pcibios_map_irq(dev, PCI_SLOT(dev->devfn), 1); /* INTA */ + if (!irq) + return; + txx9_i8259_irq_setup(irq); + pci_read_config_byte(dev, 0x64, ®_64); + pci_read_config_dword(dev, 0xb0, ®_b0); + pci_read_config_byte(dev, 0xe1, ®_e1); + /* serial irq control */ + reg_64 = 0xd0; + /* serial irq pin */ + reg_b0 |= 0x00010000; + /* ide irq on isa14 */ + reg_e1 &= 0xf0; + reg_e1 |= 0x0d; + pci_write_config_byte(dev, 0x64, reg_64); + pci_write_config_dword(dev, 0xb0, reg_b0); + pci_write_config_byte(dev, 0xe1, reg_e1); + + smsc_fdc37m81x_init(0x3f0); + smsc_fdc37m81x_config_beg(); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + smsc_fdc37m81x_config_end(); +} + +static void quirk_slc90e66_ide(struct pci_dev *dev) +{ + unsigned char dat; + int regs[2] = {0x41, 0x43}; + int i; + + /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14); + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &dat); + printk(KERN_INFO "PCI: %s: IRQ %02x", pci_name(dev), dat); + /* enable SMSC SLC90E66 IDE */ + for (i = 0; i < ARRAY_SIZE(regs); i++) { + pci_read_config_byte(dev, regs[i], &dat); + pci_write_config_byte(dev, regs[i], dat | 0x80); + pci_read_config_byte(dev, regs[i], &dat); + printk(KERN_CONT " IDETIM%d %02x", i, dat); + } + pci_read_config_byte(dev, 0x5c, &dat); + /* + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + * + * This line of code is intended to provide the user with a work + * around solution to the anomalies cited in SMSC's anomaly sheet + * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". + * + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + */ + dat |= 0x01; + pci_write_config_byte(dev, regs[i], dat); + pci_read_config_byte(dev, 0x5c, &dat); + printk(KERN_CONT " REG5C %02x", dat); + printk(KERN_CONT "\n"); +} +#endif /* CONFIG_TOSHIBA_FPCIB0 */ + +static void final_fixup(struct pci_dev *dev) +{ + unsigned char bist; + + /* Do build-in self test */ + if (pci_read_config_byte(dev, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL && + (bist & PCI_BIST_CAPABLE)) { + unsigned long timeout; + pci_set_power_state(dev, PCI_D0); + printk(KERN_INFO "PCI: %s BIST...", pci_name(dev)); + pci_write_config_byte(dev, PCI_BIST, PCI_BIST_START); + timeout = jiffies + HZ * 2; /* timeout after 2 sec */ + do { + pci_read_config_byte(dev, PCI_BIST, &bist); + if (time_after(jiffies, timeout)) + break; + } while (bist & PCI_BIST_START); + if (bist & (PCI_BIST_CODE_MASK | PCI_BIST_START)) + printk(KERN_CONT "failed. (0x%x)\n", bist); + else + printk(KERN_CONT "OK.\n"); + } +} + +#ifdef CONFIG_TOSHIBA_FPCIB0 +#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0, + quirk_slc90e66_bridge); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, + quirk_slc90e66_ide); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, + quirk_slc90e66_ide); +#endif +DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup); +DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup); diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c new file mode 100644 index 0000000..46a6311 --- /dev/null +++ b/arch/mips/txx9/generic/setup.c @@ -0,0 +1,51 @@ +/* + * linux/arch/mips/txx9/generic/setup.c + * + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * 2003-2005 (c) MontaVista Software, Inc. + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * 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. + */ +#include +#include +#include +#include + +/* EBUSC settings of TX4927, etc. */ +struct resource txx9_ce_res[8]; +static char txx9_ce_res_name[8][4]; /* "CEn" */ + +/* pcode, internal register */ +char txx9_pcode_str[8]; +static struct resource txx9_reg_res = { + .name = txx9_pcode_str, + .flags = IORESOURCE_MEM, +}; +void __init +txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) { + sprintf(txx9_ce_res_name[i], "CE%d", i); + txx9_ce_res[i].flags = IORESOURCE_MEM; + txx9_ce_res[i].name = txx9_ce_res_name[i]; + } + + sprintf(txx9_pcode_str, "TX%x", pcode); + if (base) { + txx9_reg_res.start = base & 0xfffffffffULL; + txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1); + request_resource(&iomem_resource, &txx9_reg_res); + } +} + +/* clocks */ +unsigned int txx9_master_clock; +unsigned int txx9_cpu_clock; +unsigned int txx9_gbus_clock; diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c index 85e1daf..b97d22e 100644 --- a/arch/mips/txx9/jmr3927/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c @@ -109,6 +109,7 @@ static struct irqaction ioc_action = { .name = "IOC", }; +#ifdef CONFIG_PCI static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) { printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); @@ -122,6 +123,7 @@ static struct irqaction pcierr_action = { .mask = CPU_MASK_NONE, .name = "PCI error", }; +#endif static void __init jmr3927_irq_init(void); diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 41e0f3b..baa8c8d 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #include @@ -96,8 +96,6 @@ void __init plat_time_init(void) extern char * __init prom_getcmdline(void); static void jmr3927_board_init(void); -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; void __init plat_mem_setup(void) { @@ -112,8 +110,8 @@ void __init plat_mem_setup(void) /* * IO/MEM resources. */ - ioport_resource.start = pci_io_resource.start; - ioport_resource.end = pci_io_resource.end; + ioport_resource.start = 0; + ioport_resource.end = 0xffffffff; iomem_resource.start = 0; iomem_resource.end = 0xffffffff; @@ -191,9 +189,33 @@ void __init plat_mem_setup(void) static void tx3927_setup(void); +static void __init jmr3927_pci_setup(void) +{ +#ifdef CONFIG_PCI + int extarb = !(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB); + struct pci_controller *c; + + c = txx9_alloc_pci_controller(&txx9_primary_pcic, + JMR3927_PCIMEM, JMR3927_PCIMEM_SIZE, + JMR3927_PCIIO, JMR3927_PCIIO_SIZE); + register_pci_controller(c); + if (!extarb) { + /* Reset PCI Bus */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, + JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + } + tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb); +#endif /* CONFIG_PCI */ +} + static void __init jmr3927_board_init(void) { tx3927_setup(); + jmr3927_pci_setup(); /* SIO0 DTR on */ jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); @@ -210,14 +232,6 @@ static void __init jmr3927_board_init(void) static void __init tx3927_setup(void) { int i; -#ifdef CONFIG_PCI - unsigned long mips_pci_io_base = JMR3927_PCIIO; - unsigned long mips_pci_io_size = JMR3927_PCIIO_SIZE; - unsigned long mips_pci_mem_base = JMR3927_PCIMEM; - unsigned long mips_pci_mem_size = JMR3927_PCIMEM_SIZE; - /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ - unsigned long mips_pci_io_pciaddr = 0; -#endif /* SDRAMC are configured by PROM */ @@ -272,74 +286,6 @@ static void __init tx3927_setup(void) tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE; #endif -#ifdef CONFIG_PCI - /* PCIC */ - printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:", - tx3927_pcicptr->did, tx3927_pcicptr->vid, - tx3927_pcicptr->rid); - if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) { - printk("External\n"); - /* XXX */ - } else { - printk("Internal\n"); - - /* Reset PCI Bus */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - udelay(100); - jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, - JMR3927_IOC_RESET_ADDR); - udelay(100); - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - - - /* Disable External PCI Config. Access */ - tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; -#ifdef __BIG_ENDIAN - tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | - TX3927_PCIC_LBC_TIBSE | - TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; -#endif - /* LB->PCI mappings */ - tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1); - tx3927_pcicptr->ilbioma = mips_pci_io_base; - tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr; - tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1); - tx3927_pcicptr->ilbmma = mips_pci_mem_base; - tx3927_pcicptr->ipbmma = mips_pci_mem_base; - /* PCI->LB mappings */ - tx3927_pcicptr->iobas = 0xffffffff; - tx3927_pcicptr->ioba = 0; - tx3927_pcicptr->tlbioma = 0; - tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1); - tx3927_pcicptr->mba = 0; - tx3927_pcicptr->tlbmma = 0; - /* Enable Direct mapping Address Space Decoder */ - tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; - - /* Clear All Local Bus Status */ - tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; - /* Enable All Local Bus Interrupts */ - tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; - /* Clear All PCI Status Error */ - tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; - /* Enable All PCI Status Error Interrupts */ - tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; - - /* PCIC Int => IRC IRQ10 */ - tx3927_pcicptr->il = TX3927_IR_PCI; - /* Target Control (per errata) */ - tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; - - /* Enable Bus Arbiter */ - tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; - - tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_IO | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; - } -#endif /* CONFIG_PCI */ - /* PIO */ /* PIO[15:12] connected to LEDs */ __raw_writel(0x0000f000, &tx3927_pioptr->dir); diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index 936e50e..bef1447 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -111,9 +111,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #include #include #include -#ifdef CONFIG_TOSHIBA_FPCIB0 -#include -#endif #include #define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 @@ -125,8 +122,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC #define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) -extern int tx4927_using_backplane; - static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); @@ -146,17 +141,8 @@ int toshiba_rbtx4927_irq_nested(int sw_irq) u8 level3; level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; - if (level3) { + if (level3) sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1; -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (sw_irq == TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC && - tx4927_using_backplane) { - int irq = i8259_irq(); - if (irq >= 0) - sw_irq = irq; - } -#endif - } return (sw_irq); } @@ -205,10 +191,6 @@ void __init arch_init_irq(void) tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) - init_i8259_irqs(); -#endif /* Onboard 10M Ether: High Active */ set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); } diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index df1b6e9..86b870a 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -47,10 +47,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -58,10 +58,10 @@ #include #include #include -#ifdef CONFIG_TOSHIBA_FPCIB0 -#include -#endif +#include +#include #include +#include /* for TX4937 */ #ifdef CONFIG_SERIAL_TXX9 #include #endif @@ -70,356 +70,116 @@ extern void toshiba_rbtx4927_restart(char *command); extern void toshiba_rbtx4927_halt(void); extern void toshiba_rbtx4927_power_off(void); - -int tx4927_using_backplane = 0; - extern void toshiba_rbtx4927_irq_setup(void); char *prom_getcmdline(void); -#ifdef CONFIG_PCI -#undef TX4927_SUPPORT_COMMAND_IO -#undef TX4927_SUPPORT_PCI_66 -int tx4927_cpu_clock = 100000000; /* 100MHz */ -unsigned long mips_pci_io_base; -unsigned long mips_pci_io_size; -unsigned long mips_pci_mem_base; -unsigned long mips_pci_mem_size; -/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ -unsigned long mips_pci_io_pciaddr = 0; -unsigned long mips_memory_upper; static int tx4927_ccfg_toeon = 1; -static int tx4927_pcic_trdyto = 0; /* default: disabled */ -unsigned long tx4927_ce_base[8]; -int tx4927_pci66 = 0; /* 0:auto */ -#endif char *toshiba_name = ""; #ifdef CONFIG_PCI -extern struct pci_controller tx4927_controller; - -static struct pci_dev *fake_pci_dev(struct pci_controller *hose, - int top_bus, int busnr, int devfn) +static void __init tx4927_pci_setup(void) { - static struct pci_dev dev; - static struct pci_bus bus; - - dev.sysdata = (void *)hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.parent = NULL; - dev.bus = &bus; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_controller *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ + int extarb = !(__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; + + register_pci_controller(c); + + if (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66) + txx9_pci_option = + (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | + TXX9_PCI_OPT_CLK_66; /* already configured */ + + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_66) + tx4927_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + + tx4927_report_pciclk(); + tx4927_pcic_setup(tx4927_pcicptr, c, extarb); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_AUTO && + txx9_pci66_check(c, 0, 0)) { + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + tx4927_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + /* Reinitialize PCIC */ + tx4927_report_pciclk(); + tx4927_pcic_setup(tx4927_pcicptr, c, extarb); + } } -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, dword, u32) - -static int __init tx4927_pcibios_init(void) +static void __init tx4937_pci_setup(void) { - unsigned int id; - u32 pci_devfn; - int devfn_start = 0; - int devfn_stop = 0xff; - int busno = 0; /* One bus on the Toshiba */ - struct pci_controller *hose = &tx4927_controller; - - for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { - early_read_config_dword(hose, busno, busno, pci_devfn, - PCI_VENDOR_ID, &id); - - if (id == 0xffffffff) { - continue; - } - - if (id == 0x94601055) { - u8 v08_64; - u32 v32_b0; - u8 v08_e1; - - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x64, &v08_64); - early_read_config_dword(hose, busno, busno, - pci_devfn, 0xb0, &v32_b0); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0xe1, &v08_e1); - - /* serial irq control */ - v08_64 = 0xd0; - - /* serial irq pin */ - v32_b0 |= 0x00010000; - - /* ide irq on isa14 */ - v08_e1 &= 0xf0; - v08_e1 |= 0x0d; - - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x64, v08_64); - early_write_config_dword(hose, busno, busno, - pci_devfn, 0xb0, v32_b0); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0xe1, v08_e1); - } - - if (id == 0x91301055) { - u8 v08_04; - u8 v08_09; - u8 v08_41; - u8 v08_43; - u8 v08_5c; - - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x04, &v08_04); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x09, &v08_09); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x41, &v08_41); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x43, &v08_43); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x5c, &v08_5c); - - /* enable ide master/io */ - v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); - - /* enable ide native mode */ - v08_09 |= 0x05; - - /* enable primary ide */ - v08_41 |= 0x80; - - /* enable secondary ide */ - v08_43 |= 0x80; - - /* - * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! - * - * This line of code is intended to provide the user with a work - * around solution to the anomalies cited in SMSC's anomaly sheet - * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". - * - * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! - */ - v08_5c |= 0x01; - - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x5c, v08_5c); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x04, v08_04); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x09, v08_09); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x41, v08_41); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x43, v08_43); - } - + int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; + + register_pci_controller(c); + + if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) + txx9_pci_option = + (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | + TXX9_PCI_OPT_CLK_66; /* already configured */ + + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_66) + tx4938_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + + tx4938_report_pciclk(); + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_AUTO && + txx9_pci66_check(c, 0, 0)) { + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + tx4938_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + /* Reinitialize PCIC */ + tx4938_report_pciclk(); + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); } - - register_pci_controller(&tx4927_controller); - return 0; } -arch_initcall(tx4927_pcibios_init); - -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; - -void __init tx4927_pci_setup(void) +static int __init rbtx4927_arch_init(void) { - static int called = 0; - extern unsigned int tx4927_get_mem_size(void); - - mips_memory_upper = tx4927_get_mem_size() << 20; - mips_memory_upper += KSEG0; - mips_pci_io_base = TX4927_PCIIO; - mips_pci_io_size = TX4927_PCIIO_SIZE; - mips_pci_mem_base = TX4927_PCIMEM; - mips_pci_mem_size = TX4927_PCIMEM_SIZE; - - if (!called) { - printk - ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", - toshiba_name, - (unsigned short) (tx4927_pcicptr->pciid >> 16), - (unsigned short) (tx4927_pcicptr->pciid & 0xffff), - (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), - (!(tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIXARB)) ? "External" : - "Internal"); - called = 1; - } - printk("%s PCIC --%s PCICLK:", toshiba_name, - (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); - if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { - int pciclk = 0; - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long) tx4927_ccfgptr-> - ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { - case TX4937_CCFG_PCIDIVMODE_4: - pciclk = tx4927_cpu_clock / 4; - break; - case TX4937_CCFG_PCIDIVMODE_4_5: - pciclk = tx4927_cpu_clock * 2 / 9; - break; - case TX4937_CCFG_PCIDIVMODE_5: - pciclk = tx4927_cpu_clock / 5; - break; - case TX4937_CCFG_PCIDIVMODE_5_5: - pciclk = tx4927_cpu_clock * 2 / 11; - break; - case TX4937_CCFG_PCIDIVMODE_8: - pciclk = tx4927_cpu_clock / 8; - break; - case TX4937_CCFG_PCIDIVMODE_9: - pciclk = tx4927_cpu_clock / 9; - break; - case TX4937_CCFG_PCIDIVMODE_10: - pciclk = tx4927_cpu_clock / 10; - break; - case TX4937_CCFG_PCIDIVMODE_11: - pciclk = tx4927_cpu_clock / 11; - break; - } - - else - switch ((unsigned long) tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { - case TX4927_CCFG_PCIDIVMODE_2_5: - pciclk = tx4927_cpu_clock * 2 / 5; - break; - case TX4927_CCFG_PCIDIVMODE_3: - pciclk = tx4927_cpu_clock / 3; - break; - case TX4927_CCFG_PCIDIVMODE_5: - pciclk = tx4927_cpu_clock / 5; - break; - case TX4927_CCFG_PCIDIVMODE_6: - pciclk = tx4927_cpu_clock / 6; - break; - } - - printk("Internal(%dMHz)", pciclk / 1000000); - } else - printk("External"); - printk("\n"); - - /* GB->PCI mappings */ - tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; - tx4927_pcicptr->g2piogbase = mips_pci_io_base | -#ifdef __BIG_ENDIAN - TX4927_PCIC_G2PIOGBASE_ECHG -#else - TX4927_PCIC_G2PIOGBASE_BSDIS -#endif - ; - - tx4927_pcicptr->g2piopbase = 0; - - tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; - tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | -#ifdef __BIG_ENDIAN - TX4927_PCIC_G2PMnGBASE_ECHG -#else - TX4927_PCIC_G2PMnGBASE_BSDIS -#endif - ; - tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; - - tx4927_pcicptr->g2pmmask[1] = 0; - tx4927_pcicptr->g2pmgbase[1] = 0; - tx4927_pcicptr->g2pmpbase[1] = 0; - tx4927_pcicptr->g2pmmask[2] = 0; - tx4927_pcicptr->g2pmgbase[2] = 0; - tx4927_pcicptr->g2pmpbase[2] = 0; - - - /* PCI->GB mappings (I/O 256B) */ - tx4927_pcicptr->p2giopbase = 0; /* 256B */ - - /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ - tx4927_pcicptr->p2gm0plbase = 0; - tx4927_pcicptr->p2gm0pubase = 0; - tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | -#ifdef __BIG_ENDIAN - TX4927_PCIC_P2GMnGBASE_TECHG -#else - TX4927_PCIC_P2GMnGBASE_TBSDIS -#endif - ; - - /* PCI->GB mappings (MEM 16MB) -not used */ - tx4927_pcicptr->p2gm1plbase = 0xffffffff; - tx4927_pcicptr->p2gm1pubase = 0xffffffff; - tx4927_pcicptr->p2gmgbase[1] = 0; - - /* PCI->GB mappings (MEM 1MB) -not used */ - tx4927_pcicptr->p2gm2pbase = 0xffffffff; - tx4927_pcicptr->p2gmgbase[2] = 0; - - - /* Enable Initiator Memory 0 Space, I/O Space, Config */ - tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; - tx4927_pcicptr->pciccfg |= - TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | - TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; - - - /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ - tx4927_pcicptr->pcicfg1 = 0; - - if (tx4927_pcic_trdyto >= 0) { - tx4927_pcicptr->g2ptocnt &= ~0xff; - tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); - } - - /* Clear All Local Bus Status */ - tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; - /* Enable All Local Bus Interrupts */ - tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; - /* Clear All Initiator Status */ - tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; - /* Enable All Initiator Interrupts */ - tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; - /* Clear All PCI Status Error */ - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr->pcistatus & 0x0000ffff) | - (TX4927_PCIC_PCISTATUS_ALL << 16); - /* Enable All PCI Status Error Interrupts */ - tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; - - /* PCIC Int => IRC IRQ16 */ - tx4927_pcicptr->pcicfg2 = - (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; - - if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { - /* XXX */ - } else { - /* Reset Bus Arbiter */ - tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; - /* Enable Bus Arbiter */ - tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; - } - - tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + if (mips_machtype == MACH_TOSHIBA_RBTX4937) + tx4937_pci_setup(); + else + tx4927_pci_setup(); + return 0; } +arch_initcall(rbtx4927_arch_init); #endif /* CONFIG_PCI */ static void __noreturn wait_forever(void) @@ -479,8 +239,6 @@ void __init plat_mem_setup(void) cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); write_c0_config(cp0_config); - set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); - ioport_resource.end = 0xffffffff; iomem_resource.end = 0xffffffff; @@ -492,8 +250,13 @@ void __init plat_mem_setup(void) txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL); #ifdef CONFIG_PCI + txx9_alloc_pci_controller(&txx9_primary_pcic, + RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE, + RBTX4927_PCIIO, RBTX4927_PCIIO_SIZE); +#else + set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); +#endif - /* PCIC */ /* * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. * @@ -517,58 +280,38 @@ void __init plat_mem_setup(void) * */ if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long)tx4927_ccfgptr-> - ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { - case TX4937_CCFG_PCIDIVMODE_8: - case TX4937_CCFG_PCIDIVMODE_4: - tx4927_cpu_clock = 266666666; /* 266MHz */ + switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) & + TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + txx9_cpu_clock = 266666666; /* 266MHz */ break; - case TX4937_CCFG_PCIDIVMODE_9: - case TX4937_CCFG_PCIDIVMODE_4_5: - tx4927_cpu_clock = 300000000; /* 300MHz */ + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + txx9_cpu_clock = 300000000; /* 300MHz */ break; default: - tx4927_cpu_clock = 333333333; /* 333MHz */ + txx9_cpu_clock = 333333333; /* 333MHz */ } else - switch ((unsigned long)tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) & + TX4927_CCFG_PCIDIVMODE_MASK) { case TX4927_CCFG_PCIDIVMODE_2_5: case TX4927_CCFG_PCIDIVMODE_5: - tx4927_cpu_clock = 166666666; /* 166MHz */ + txx9_cpu_clock = 166666666; /* 166MHz */ break; default: - tx4927_cpu_clock = 200000000; /* 200MHz */ + txx9_cpu_clock = 200000000; /* 200MHz */ } + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; /* CCFG */ /* do reset on watchdog */ - tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR; + tx4927_ccfg_set(TX4927_CCFG_WR); /* enable Timeout BusError */ if (tx4927_ccfg_toeon) - tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; - - tx4927_pci_setup(); - if (tx4927_using_backplane == 1) - printk("backplane board IS installed\n"); - else - printk("No Backplane \n"); - - /* this is on ISA bus behind PCI bus, so need PCI up first */ -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) { - smsc_fdc37m81x_init(0x3f0); - smsc_fdc37m81x_config_beg(); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, - SMSC_FDC37M81X_KBD); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, - 1); - smsc_fdc37m81x_config_end(); - } -#endif -#endif /* CONFIG_PCI */ + tx4927_ccfg_set(TX4927_CCFG_TOE); #ifdef CONFIG_SERIAL_TXX9 { @@ -611,8 +354,8 @@ void __init plat_mem_setup(void) void __init plat_time_init(void) { - mips_hpt_frequency = tx4927_cpu_clock / 2; - if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) + mips_hpt_frequency = txx9_cpu_clock / 2; + if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, TXX9_IRQ_BASE + 17, 50000000); diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index bbd572c..144d2ca 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -26,6 +25,8 @@ #include #include #include +#include +#include #include #ifdef CONFIG_SERIAL_TXX9 #include @@ -35,37 +36,13 @@ #include extern char * __init prom_getcmdline(void); -static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); - /* These functions are used for rebooting or halting the machine*/ extern void rbtx4938_machine_restart(char *command); extern void rbtx4938_machine_halt(void); extern void rbtx4938_machine_power_off(void); -/* clocks */ -unsigned int txx9_master_clock; -unsigned int txx9_cpu_clock; -unsigned int txx9_gbus_clock; - -unsigned long rbtx4938_ce_base[8]; -unsigned long rbtx4938_ce_size[8]; -int txboard_pci66_mode; -static int tx4938_pcic_trdyto; /* default: disabled */ -static int tx4938_pcic_retryto; /* default: disabled */ static int tx4938_ccfg_toeon = 1; -struct tx4938_pcic_reg *pcicptrs[4] = { - tx4938_pcicptr /* default setting for TX4938 */ -}; - -static struct { - unsigned long base; - unsigned long size; -} phys_regions[16] __initdata; -static int num_phys_regions __initdata; - -#define PHYS_REGION_MINSIZE 0x10000 - void rbtx4938_machine_halt(void) { printk(KERN_NOTICE "System Halted\n"); @@ -95,473 +72,72 @@ void rbtx4938_machine_restart(char *command) ; } -void __init -txboard_add_phys_region(unsigned long base, unsigned long size) -{ - if (num_phys_regions >= ARRAY_SIZE(phys_regions)) { - printk("phys_region overflow\n"); - return; - } - phys_regions[num_phys_regions].base = base; - phys_regions[num_phys_regions].size = size; - num_phys_regions++; -} -unsigned long __init -txboard_find_free_phys_region(unsigned long begin, unsigned long end, - unsigned long size) -{ - unsigned long base; - int i; - - for (base = begin / size * size; base < end; base += size) { - for (i = 0; i < num_phys_regions; i++) { - if (phys_regions[i].size && - base <= phys_regions[i].base + (phys_regions[i].size - 1) && - base + (size - 1) >= phys_regions[i].base) - break; - } - if (i == num_phys_regions) - return base; - } - return 0; -} -unsigned long __init -txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end, - unsigned long *size) -{ - unsigned long sz, base; - for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) { - base = txboard_find_free_phys_region(begin, end, sz); - if (base) { - *size = sz; - return base; - } - } - return 0; -} -unsigned long __init -txboard_request_phys_region_range(unsigned long begin, unsigned long end, - unsigned long size) -{ - unsigned long base; - base = txboard_find_free_phys_region(begin, end, size); - if (base) - txboard_add_phys_region(base, size); - return base; -} -unsigned long __init -txboard_request_phys_region(unsigned long size) +static void __init rbtx4938_pci_setup(void) { - unsigned long base; - unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ - base = txboard_find_free_phys_region(begin, end, size); - if (base) - txboard_add_phys_region(base, size); - return base; -} -unsigned long __init -txboard_request_phys_region_shrink(unsigned long *size) -{ - unsigned long base; - unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ - base = txboard_find_free_phys_region_shrink(begin, end, size); - if (base) - txboard_add_phys_region(base, *size); - return base; -} - #ifdef CONFIG_PCI -void __init -tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr, - struct pci_controller *channel, - unsigned long pci_io_base, - int extarb) -{ - int i; + int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; - /* Disable All Initiator Space */ - pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)| - TX4938_PCIC_PCICCFG_G2PMEN(1)| - TX4938_PCIC_PCICCFG_G2PMEN(2)| - TX4938_PCIC_PCICCFG_G2PIOEN); - - /* GB->PCI mappings */ - pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4; - pcicptr->g2piogbase = pci_io_base | -#ifdef __BIG_ENDIAN - TX4938_PCIC_G2PIOGBASE_ECHG -#else - TX4938_PCIC_G2PIOGBASE_BSDIS -#endif - ; - pcicptr->g2piopbase = 0; - for (i = 0; i < 3; i++) { - pcicptr->g2pmmask[i] = 0; - pcicptr->g2pmgbase[i] = 0; - pcicptr->g2pmpbase[i] = 0; - } - if (channel->mem_resource->end) { - pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4; - pcicptr->g2pmgbase[0] = channel->mem_resource->start | -#ifdef __BIG_ENDIAN - TX4938_PCIC_G2PMnGBASE_ECHG -#else - TX4938_PCIC_G2PMnGBASE_BSDIS -#endif - ; - pcicptr->g2pmpbase[0] = channel->mem_resource->start; - } - /* PCI->GB mappings (I/O 256B) */ - pcicptr->p2giopbase = 0; /* 256B */ - pcicptr->p2giogbase = 0; - /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ - pcicptr->p2gm0plbase = 0; - pcicptr->p2gm0pubase = 0; - pcicptr->p2gmgbase[0] = 0 | - TX4938_PCIC_P2GMnGBASE_TMEMEN | -#ifdef __BIG_ENDIAN - TX4938_PCIC_P2GMnGBASE_TECHG -#else - TX4938_PCIC_P2GMnGBASE_TBSDIS -#endif - ; - /* PCI->GB mappings (MEM 16MB) */ - pcicptr->p2gm1plbase = 0xffffffff; - pcicptr->p2gm1pubase = 0xffffffff; - pcicptr->p2gmgbase[1] = 0; - /* PCI->GB mappings (MEM 1MB) */ - pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */ - pcicptr->p2gmgbase[2] = 0; - - pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK; - /* Enable Initiator Memory Space */ - if (channel->mem_resource->end) - pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0); - /* Enable Initiator I/O Space */ - if (channel->io_resource->end) - pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN; - /* Enable Initiator Config */ - pcicptr->pciccfg |= - TX4938_PCIC_PCICCFG_ICAEN | - TX4938_PCIC_PCICCFG_TCAR; - - /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ - pcicptr->pcicfg1 = 0; - - pcicptr->g2ptocnt &= ~0xffff; - - if (tx4938_pcic_trdyto >= 0) { - pcicptr->g2ptocnt &= ~0xff; - pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff); - } - - if (tx4938_pcic_retryto >= 0) { - pcicptr->g2ptocnt &= ~0xff00; - pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00); - } - - /* Clear All Local Bus Status */ - pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL; - /* Enable All Local Bus Interrupts */ - pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL; - /* Clear All Initiator Status */ - pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL; - /* Enable All Initiator Interrupts */ - pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL; - /* Clear All PCI Status Error */ - pcicptr->pcistatus = - (pcicptr->pcistatus & 0x0000ffff) | - (TX4938_PCIC_PCISTATUS_ALL << 16); - /* Enable All PCI Status Error Interrupts */ - pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL; - - if (!extarb) { - /* Reset Bus Arbiter */ - pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA; - pcicptr->pbabm = 0; - /* Enable Bus Arbiter */ - pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN; - } - - /* PCIC Int => IRC IRQ16 */ - pcicptr->pcicfg2 = - (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC; - - pcicptr->pcistatus = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -} - -int __init -tx4938_report_pciclk(void) -{ - unsigned long pcode = TX4938_REV_PCODE(); - int pciclk = 0; - printk("TX%lx PCIC --%s PCICLK:", - pcode, - (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : ""); - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { - - switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) { - case TX4938_CCFG_PCIDIVMODE_4: - pciclk = txx9_cpu_clock / 4; break; - case TX4938_CCFG_PCIDIVMODE_4_5: - pciclk = txx9_cpu_clock * 2 / 9; break; - case TX4938_CCFG_PCIDIVMODE_5: - pciclk = txx9_cpu_clock / 5; break; - case TX4938_CCFG_PCIDIVMODE_5_5: - pciclk = txx9_cpu_clock * 2 / 11; break; - case TX4938_CCFG_PCIDIVMODE_8: - pciclk = txx9_cpu_clock / 8; break; - case TX4938_CCFG_PCIDIVMODE_9: - pciclk = txx9_cpu_clock / 9; break; - case TX4938_CCFG_PCIDIVMODE_10: - pciclk = txx9_cpu_clock / 10; break; - case TX4938_CCFG_PCIDIVMODE_11: - pciclk = txx9_cpu_clock / 11; break; - } - printk("Internal(%dMHz)", pciclk / 1000000); - } else { - printk("External"); - pciclk = -1; - } - printk("\n"); - return pciclk; -} - -void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr) -{ - pcicptrs[ch] = pcicptr; -} - -struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch) -{ - return pcicptrs[ch]; -} - -static struct pci_dev *fake_pci_dev(struct pci_controller *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; + register_pci_controller(c); - dev.sysdata = bus.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.parent = NULL; - dev.bus = &bus; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_controller *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, word, u16 *) - -int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus) -{ - u32 pci_devfn; - unsigned short vid; - int devfn_start = 0; - int devfn_stop = 0xff; - int cap66 = -1; - u16 stat; - - printk("PCI: Checking 66MHz capabilities...\n"); - - for (pci_devfn=devfn_start; pci_devfn 0; -} - -int __init -tx4938_pciclk66_setup(void) -{ - int pciclk; - - /* Assert M66EN */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; - /* Double PCICLK (if possible) */ - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { - unsigned int pcidivmode = - tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK; - switch (pcidivmode) { - case TX4938_CCFG_PCIDIVMODE_8: - case TX4938_CCFG_PCIDIVMODE_4: - pcidivmode = TX4938_CCFG_PCIDIVMODE_4; - pciclk = txx9_cpu_clock / 4; - break; - case TX4938_CCFG_PCIDIVMODE_9: - case TX4938_CCFG_PCIDIVMODE_4_5: - pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; - pciclk = txx9_cpu_clock * 2 / 9; - break; - case TX4938_CCFG_PCIDIVMODE_10: - case TX4938_CCFG_PCIDIVMODE_5: - pcidivmode = TX4938_CCFG_PCIDIVMODE_5; - pciclk = txx9_cpu_clock / 5; - break; - case TX4938_CCFG_PCIDIVMODE_11: - case TX4938_CCFG_PCIDIVMODE_5_5: - default: - pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; - pciclk = txx9_cpu_clock * 2 / 11; - break; - } - tx4938_ccfgptr->ccfg = - (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) - | pcidivmode; - printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", - (unsigned long)tx4938_ccfgptr->ccfg); - } else { - pciclk = -1; - } - return pciclk; -} - -extern struct pci_controller tx4938_pci_controller[]; -static int __init tx4938_pcibios_init(void) -{ - unsigned long mem_base[2]; - unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ - unsigned long io_base[2]; - unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ - /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ - int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); - - PCIBIOS_MIN_IO = 0x00001000UL; - - mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); - io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); - - printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", - (unsigned short)(tx4938_pcicptr->pciid >> 16), - (unsigned short)(tx4938_pcicptr->pciid & 0xffff), - (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), - extarb ? "External" : "Internal"); - - /* setup PCI area */ - tx4938_pci_controller[0].io_resource->start = io_base[0]; - tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; - tx4938_pci_controller[0].mem_resource->start = mem_base[0]; - tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; - - set_tx4938_pcicptr(0, tx4938_pcicptr); - - register_pci_controller(&tx4938_pci_controller[0]); - - if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { - printk("TX4938_CCFG_PCI66 already configured\n"); - txboard_pci66_mode = -1; /* already configured */ - } + if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) + txx9_pci_option = + (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | + TXX9_PCI_OPT_CLK_66; /* already configured */ /* Reset PCI Bus */ writeb(0, rbtx4938_pcireset_addr); /* Reset PCIC */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; - if (txboard_pci66_mode > 0) + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_66) tx4938_pciclk66_setup(); mdelay(10); /* clear PCIC reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); writeb(1, rbtx4938_pcireset_addr); - mmiowb(); - tx4938_report_pcic_status1(tx4938_pcicptr); + iob(); tx4938_report_pciclk(); - tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); - if (txboard_pci66_mode == 0 && - txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_AUTO && + txx9_pci66_check(c, 0, 0)) { /* Reset PCI Bus */ writeb(0, rbtx4938_pcireset_addr); /* Reset PCIC */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); tx4938_pciclk66_setup(); mdelay(10); /* clear PCIC reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); writeb(1, rbtx4938_pcireset_addr); - mmiowb(); + iob(); /* Reinitialize PCIC */ tx4938_report_pciclk(); - tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); } - mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); - io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); - /* Reset PCIC1 */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; - /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ - if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) - tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; - else - tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; - mdelay(10); - /* clear PCIC1 reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; - tx4938_report_pcic_status1(tx4938_pcic1ptr); - - printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", - (unsigned short)(tx4938_pcic1ptr->pciid >> 16), - (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), - (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); - printk("%s PCICLK:%dMHz\n", - (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", - txx9_gbus_clock / - ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / - 1000000); - - /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ - tx4938_pci_controller[1].io_resource->start = - io_base[1] - io_base[0]; - tx4938_pci_controller[1].io_resource->end = - io_base[1] - io_base[0] + io_size[1] - 1; - tx4938_pci_controller[1].mem_resource->start = mem_base[1]; - tx4938_pci_controller[1].mem_resource->end = - mem_base[1] + mem_size[1] - 1; - set_tx4938_pcicptr(1, tx4938_pcic1ptr); - - register_pci_controller(&tx4938_pci_controller[1]); - - tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); - - /* map ioport 0 to PCI I/O space address 0 */ - set_io_port_base(KSEG1 + io_base[0]); - - return 0; -} - -arch_initcall(tx4938_pcibios_init); - + if (__raw_readq(&tx4938_ccfgptr->pcfg) & + (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) { + /* Reset PCIC1 */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); + /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ + if (!(__raw_readq(&tx4938_ccfgptr->ccfg) + & TX4938_CCFG_PCI1DMD)) + tx4938_ccfg_set(TX4938_CCFG_PCI1_66); + mdelay(10); + /* clear PCIC1 reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); + tx4938_report_pci1clk(); + + /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */ + c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000); + register_pci_controller(c); + tx4927_pcic_setup(tx4938_pcic1ptr, c, 0); + } #endif /* CONFIG_PCI */ +} /* SPI support */ @@ -594,7 +170,7 @@ static int __init rbtx4938_ethaddr_init(void) unsigned int id = TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); struct platform_device *pdev; - if (!(tx4938_ccfgptr->pcfg & + if (!(__raw_readq(&tx4938_ccfgptr->pcfg) & (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) continue; pdev = platform_device_alloc("tc35815-mac", id); @@ -611,18 +187,12 @@ device_initcall(rbtx4938_ethaddr_init); static void __init rbtx4938_spi_setup(void) { /* set SPI_SEL */ - tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; + txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL); } static struct resource rbtx4938_fpga_resource; - -static char pcode_str[8]; -static struct resource tx4938_reg_resource = { - .start = TX4938_REG_BASE, - .end = TX4938_REG_BASE + TX4938_REG_SIZE, - .name = pcode_str, - .flags = IORESOURCE_MEM -}; +static struct resource tx4938_sdram_resource[4]; +static struct resource tx4938_sram_resource; void __init tx4938_board_setup(void) { @@ -631,24 +201,28 @@ void __init tx4938_board_setup(void) int cpuclk = 0; unsigned long pcode = TX4938_REV_PCODE(); - ioport_resource.start = 0x1000; + ioport_resource.start = 0; ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x1000; + iomem_resource.start = 0; iomem_resource.end = 0xffffffff; /* expand to 4GB */ - sprintf(pcode_str, "TX%lx", pcode); + txx9_reg_res_init(pcode, TX4938_REG_BASE, + TX4938_REG_SIZE); /* SDRAMC,EBUSC are configured by PROM */ for (i = 0; i < 8; i++) { - if (!(tx4938_ebuscptr->cr[i] & 0x8)) + if (!(TX4938_EBUSC_CR(i) & 0x8)) continue; /* disabled */ - rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); - txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); + txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i); + txx9_ce_res[i].end = + txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1; + request_resource(&iomem_resource, &txx9_ce_res[i]); } /* clocks */ if (txx9_master_clock) { + u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); /* calculate gbus_clock and cpu_clock_freq from master_clock */ - divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; + divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; switch (divmode) { case TX4938_CCFG_DIVMODE_8: case TX4938_CCFG_DIVMODE_10: @@ -678,12 +252,13 @@ void __init tx4938_board_setup(void) } txx9_cpu_clock = cpuclk; } else { + u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); if (txx9_cpu_clock == 0) { txx9_cpu_clock = 300000000; /* 300MHz */ } /* calculate gbus_clock and master_clock from cpu_clock_freq */ cpuclk = txx9_cpu_clock; - divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; + divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; switch (divmode) { case TX4938_CCFG_DIVMODE_2: case TX4938_CCFG_DIVMODE_8: @@ -717,32 +292,32 @@ void __init tx4938_board_setup(void) /* CCFG */ /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; + tx4938_ccfg_set(TX4938_CCFG_WDRST | TX4938_CCFG_BEOW); /* do reset on watchdog */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR; + tx4938_ccfg_set(TX4938_CCFG_WR); /* clear PCIC1 reset */ - if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); /* enable Timeout BusError */ if (tx4938_ccfg_toeon) - tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; + tx4938_ccfg_set(TX4938_CCFG_TOE); /* DMA selection */ - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL); /* Use external clock for external arbiter */ - if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; - - printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", - pcode_str, - cpuclk / 1000000, txx9_master_clock / 1000000, - (unsigned long)tx4938_ccfgptr->crir, - tx4938_ccfgptr->ccfg, - tx4938_ccfgptr->pcfg); - - printk("%s SDRAMC --", pcode_str); + if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB)) + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL); + + printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", + txx9_pcode_str, + (cpuclk + 500000) / 1000000, + (txx9_master_clock + 500000) / 1000000, + (__u32)____raw_readq(&tx4938_ccfgptr->crir), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg)); + + printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); for (i = 0; i < 4; i++) { unsigned long long cr = tx4938_sdramcptr->cr[i]; unsigned long ram_base, ram_size; @@ -753,16 +328,24 @@ void __init tx4938_board_setup(void) if (ram_base >= 0x20000000) continue; /* high memory (ignore) */ printk(" CR%d:%016Lx", i, cr); - txboard_add_phys_region(ram_base, ram_size); + tx4938_sdram_resource[i].name = "SDRAM"; + tx4938_sdram_resource[i].start = ram_base; + tx4938_sdram_resource[i].end = ram_base + ram_size - 1; + tx4938_sdram_resource[i].flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4938_sdram_resource[i]); } printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); /* SRAM */ - if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { + if (tx4938_sramcptr->cr & 1) { unsigned int size = 0x800; unsigned long base = (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); - txboard_add_phys_region(base, size); + tx4938_sram_resource.name = "SRAM"; + tx4938_sram_resource.start = base; + tx4938_sram_resource.end = base + size - 1; + tx4938_sram_resource.flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4938_sram_resource); } /* TMR */ @@ -778,71 +361,15 @@ void __init tx4938_board_setup(void) __raw_writel(0, &tx4938_pioptr->maskcpu); __raw_writel(0, &tx4938_pioptr->maskext); - /* TX4938 internal registers */ - if (request_resource(&iomem_resource, &tx4938_reg_resource)) - printk("request resource for internal registers failed\n"); -} - #ifdef CONFIG_PCI -static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr) -{ - unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16); - unsigned long g2pstatus = pcicptr->g2pstatus; - unsigned long pcicstatus = pcicptr->pcicstatus; - static struct { - unsigned long flag; - const char *str; - } pcistat_tbl[] = { - { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, - { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, - { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, - { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, - { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, - { PCI_STATUS_PARITY, "MasterParityError" }, - }, g2pstat_tbl[] = { - { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" }, - { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" }, - }, pcicstat_tbl[] = { - { TX4938_PCIC_PCICSTATUS_PME, "PME" }, - { TX4938_PCIC_PCICSTATUS_TLB, "TLB" }, - { TX4938_PCIC_PCICSTATUS_NIB, "NIB" }, - { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" }, - { TX4938_PCIC_PCICSTATUS_PERR, "PERR" }, - { TX4938_PCIC_PCICSTATUS_SERR, "SERR" }, - { TX4938_PCIC_PCICSTATUS_GBE, "GBE" }, - { TX4938_PCIC_PCICSTATUS_IWB, "IWB" }, - }; - int i; - - printk("pcistat:%04x(", pcistatus); - for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++) - if (pcistatus & pcistat_tbl[i].flag) - printk("%s ", pcistat_tbl[i].str); - printk("), g2pstatus:%08lx(", g2pstatus); - for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) - if (g2pstatus & g2pstat_tbl[i].flag) - printk("%s ", g2pstat_tbl[i].str); - printk("), pcicstatus:%08lx(", pcicstatus); - for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) - if (pcicstatus & pcicstat_tbl[i].flag) - printk("%s ", pcicstat_tbl[i].str); - printk(")\n"); -} - -void tx4938_report_pcic_status(void) -{ - int i; - struct tx4938_pcic_reg *pcicptr; - for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++) - tx4938_report_pcic_status1(pcicptr); + txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); +#endif } -#endif /* CONFIG_PCI */ - void __init plat_time_init(void) { mips_hpt_frequency = txx9_cpu_clock / 2; - if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS) + if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, TXX9_IRQ_BASE + TX4938_IR_TMR(0), txx9_gbus_clock / 2); @@ -890,19 +417,20 @@ void __init plat_mem_setup(void) #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 printk("PIOSEL: disabling both ata and nand selection\n"); local_irq_disable(); - tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); + txx9_clear64(&tx4938_ccfgptr->pcfg, + TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND printk("PIOSEL: enabling nand selection\n"); - tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL; - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL; + txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA printk("PIOSEL: enabling ata selection\n"); - tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL; - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL; + txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); #endif #ifdef CONFIG_IP_PNP @@ -920,7 +448,7 @@ void __init plat_mem_setup(void) #endif rbtx4938_spi_setup(); - pcfg = tx4938_ccfgptr->pcfg; /* updated */ + pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */ /* fixup piosel */ if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == TX4938_PCFG_ATA_SEL) @@ -1063,6 +591,7 @@ static int __init rbtx4938_arch_init(void) { txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); gpiochip_add(&rbtx4938_spi_gpio_chip); + rbtx4938_pci_setup(); return rbtx4938_spi_init(); } arch_initcall(rbtx4938_arch_init); diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h new file mode 100644 index 0000000..2ff6c20 --- /dev/null +++ b/include/asm-mips/txx9/generic.h @@ -0,0 +1,23 @@ +/* + * linux/include/asm-mips/txx9/generic.h + * + * 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. + */ +#ifndef __ASM_TXX9_GENERIC_H +#define __ASM_TXX9_GENERIC_H + +#include +#include /* for struct resource */ + +extern struct resource txx9_ce_res[]; +extern char txx9_pcode_str[8]; +void txx9_reg_res_init(unsigned int pcode, unsigned long base, + unsigned long size); + +extern unsigned int txx9_master_clock; +extern unsigned int txx9_cpu_clock; +extern unsigned int txx9_gbus_clock; + +#endif /* __ASM_TXX9_GENERIC_H */ diff --git a/include/asm-mips/txx9/pci.h b/include/asm-mips/txx9/pci.h new file mode 100644 index 0000000..d89a450 --- /dev/null +++ b/include/asm-mips/txx9/pci.h @@ -0,0 +1,36 @@ +/* + * 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. + */ +#ifndef __ASM_TXX9_PCI_H +#define __ASM_TXX9_PCI_H + +#include + +extern struct pci_controller txx9_primary_pcic; +struct pci_controller * +txx9_alloc_pci_controller(struct pci_controller *pcic, + unsigned long mem_base, unsigned long mem_size, + unsigned long io_base, unsigned long io_size); + +int txx9_pci66_check(struct pci_controller *hose, int top_bus, + int current_bus); +extern int txx9_pci_mem_high __initdata; + +extern int txx9_pci_option; +#define TXX9_PCI_OPT_PICMG 0x0002 +#define TXX9_PCI_OPT_CLK_33 0x0008 +#define TXX9_PCI_OPT_CLK_66 0x0010 +#define TXX9_PCI_OPT_CLK_MASK \ + (TXX9_PCI_OPT_CLK_33 | TXX9_PCI_OPT_CLK_66) +#define TXX9_PCI_OPT_CLK_AUTO TXX9_PCI_OPT_CLK_MASK + +enum txx9_pci_err_action { + TXX9_PCI_ERR_REPORT, + TXX9_PCI_ERR_IGNORE, + TXX9_PCI_ERR_PANIC, +}; +extern enum txx9_pci_err_action txx9_pci_err_action; + +#endif /* __ASM_TXX9_PCI_H */ diff --git a/include/asm-mips/txx9/rbtx4927.h b/include/asm-mips/txx9/rbtx4927.h index 5531342..5b6f488 100644 --- a/include/asm-mips/txx9/rbtx4927.h +++ b/include/asm-mips/txx9/rbtx4927.h @@ -29,10 +29,33 @@ #include +#define RBTX4927_PCIMEM 0x08000000 +#define RBTX4927_PCIMEM_SIZE 0x08000000 +#define RBTX4927_PCIIO 0x16000000 +#define RBTX4927_PCIIO_SIZE 0x01000000 + +#define rbtx4927_pcireset_addr ((__u8 __iomem *)0xbc00f006UL) + +/* bits for ISTAT/IMASK/IMSTAT */ +#define RBTX4927_INTB_PCID 0 +#define RBTX4927_INTB_PCIC 1 +#define RBTX4927_INTB_PCIB 2 +#define RBTX4927_INTB_PCIA 3 +#define RBTX4927_INTF_PCID (1 << RBTX4927_INTB_PCID) +#define RBTX4927_INTF_PCIC (1 << RBTX4927_INTB_PCIC) +#define RBTX4927_INTF_PCIB (1 << RBTX4927_INTB_PCIB) +#define RBTX4927_INTF_PCIA (1 << RBTX4927_INTB_PCIA) + +#define RBTX4927_IRQ_IOC (TX4927_IRQ_PIC_BEG + TX4927_NUM_IR) +#define RBTX4927_IRQ_IOC_PCID (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCID) +#define RBTX4927_IRQ_IOC_PCIC (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIC) +#define RBTX4927_IRQ_IOC_PCIB (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIB) +#define RBTX4927_IRQ_IOC_PCIA (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIA) + #ifdef CONFIG_PCI -#define TBTX4927_ISA_IO_OFFSET TX4927_PCIIO +#define RBTX4927_ISA_IO_OFFSET RBTX4927_PCIIO #else -#define TBTX4927_ISA_IO_OFFSET 0 +#define RBTX4927_ISA_IO_OFFSET 0 #endif #define RBTX4927_SW_RESET_DO (void __iomem *)0xbc00f000UL @@ -41,7 +64,7 @@ #define RBTX4927_SW_RESET_ENABLE (void __iomem *)0xbc00f002UL #define RBTX4927_SW_RESET_ENABLE_SET 0x01 -#define RBTX4927_RTL_8019_BASE (0x1c020280-TBTX4927_ISA_IO_OFFSET) +#define RBTX4927_RTL_8019_BASE (0x1c020280 - RBTX4927_ISA_IO_OFFSET) #define RBTX4927_RTL_8019_IRQ (TX4927_IRQ_PIC_BEG + 5) int toshiba_rbtx4927_irq_nested(int sw_irq); diff --git a/include/asm-mips/txx9/tx3927.h b/include/asm-mips/txx9/tx3927.h index 63b62d6..ca414c7 100644 --- a/include/asm-mips/txx9/tx3927.h +++ b/include/asm-mips/txx9/tx3927.h @@ -316,4 +316,8 @@ struct tx3927_ccfg_reg { #define tx3927_sioptr(ch) ((struct txx927_sio_reg *)TX3927_SIO_REG(ch)) #define tx3927_pioptr ((struct txx9_pio_reg __iomem *)TX3927_PIO_REG) +struct pci_controller; +void __init tx3927_pcic_setup(struct pci_controller *channel, + unsigned long sdram_size, int extarb); + #endif /* __ASM_TXX9_TX3927_H */ diff --git a/include/asm-mips/txx9/tx4927.h b/include/asm-mips/txx9/tx4927.h index f21a7b1..c0382fd 100644 --- a/include/asm-mips/txx9/tx4927.h +++ b/include/asm-mips/txx9/tx4927.h @@ -27,7 +27,10 @@ #ifndef __ASM_TXX9_TX4927_H #define __ASM_TXX9_TX4927_H +#include +#include #include +#include #define TX4927_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE #define TX4927_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) @@ -43,15 +46,6 @@ #define TX4927_IRQ_NEST_EXT_ON_PIC (TX4927_IRQ_PIC_BEG+3) -#define TX4927_CCFG_TOE 0x00004000 -#define TX4927_CCFG_WR 0x00008000 -#define TX4927_CCFG_TINTDIS 0x01000000 - -#define TX4927_PCIMEM 0x08000000 -#define TX4927_PCIMEM_SIZE 0x08000000 -#define TX4927_PCIIO 0x16000000 -#define TX4927_PCIIO_SIZE 0x01000000 - #define TX4927_SDRAMC_REG 0xff1f8000 #define TX4927_EBUSC_REG 0xff1f9000 #define TX4927_PCIC_REG 0xff1fd000 @@ -60,36 +54,9 @@ #define TX4927_NR_TMR 3 #define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) -/* bits for ISTAT3/IMASK3/IMSTAT3 */ -#define TX4927_INT3B_PCID 0 -#define TX4927_INT3B_PCIC 1 -#define TX4927_INT3B_PCIB 2 -#define TX4927_INT3B_PCIA 3 -#define TX4927_INT3F_PCID (1 << TX4927_INT3B_PCID) -#define TX4927_INT3F_PCIC (1 << TX4927_INT3B_PCIC) -#define TX4927_INT3F_PCIB (1 << TX4927_INT3B_PCIB) -#define TX4927_INT3F_PCIA (1 << TX4927_INT3B_PCIA) - -#define TX4927_NR_IRQ_LOCAL TX4927_IRQ_PIC_BEG -#define TX4927_NR_IRQ_IRC 32 /* On-Chip IRC */ - #define TX4927_IR_PCIC 16 #define TX4927_IR_PCIERR 22 -#define TX4927_IR_PCIPMA 23 -#define TX4927_IRQ_IRC_PCIC (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIC) -#define TX4927_IRQ_IRC_PCIERR (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIERR) -#define TX4927_IRQ_IOC1 (TX4927_NR_IRQ_LOCAL + TX4927_NR_IRQ_IRC) -#define TX4927_IRQ_IOC_PCID (TX4927_IRQ_IOC1 + TX4927_INT3B_PCID) -#define TX4927_IRQ_IOC_PCIC (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIC) -#define TX4927_IRQ_IOC_PCIB (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIB) -#define TX4927_IRQ_IOC_PCIA (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIA) - -#ifdef _LANGUAGE_ASSEMBLY -#define _CONST64(c) c -#else -#define _CONST64(c) c##ull - -#include +#define TX4927_NUM_IR 32 struct tx4927_sdramc_reg { volatile unsigned long long cr[4]; @@ -104,177 +71,158 @@ struct tx4927_ebusc_reg { }; struct tx4927_ccfg_reg { - volatile unsigned long long ccfg; - volatile unsigned long long crir; - volatile unsigned long long pcfg; - volatile unsigned long long tear; - volatile unsigned long long clkctr; - volatile unsigned long long unused0; - volatile unsigned long long garbc; - volatile unsigned long long unused1; - volatile unsigned long long unused2; - volatile unsigned long long ramp; -}; - -struct tx4927_pcic_reg { - volatile unsigned long pciid; - volatile unsigned long pcistatus; - volatile unsigned long pciccrev; - volatile unsigned long pcicfg1; - volatile unsigned long p2gm0plbase; /* +10 */ - volatile unsigned long p2gm0pubase; - volatile unsigned long p2gm1plbase; - volatile unsigned long p2gm1pubase; - volatile unsigned long p2gm2pbase; /* +20 */ - volatile unsigned long p2giopbase; - volatile unsigned long unused0; - volatile unsigned long pcisid; - volatile unsigned long unused1; /* +30 */ - volatile unsigned long pcicapptr; - volatile unsigned long unused2; - volatile unsigned long pcicfg2; - volatile unsigned long g2ptocnt; /* +40 */ - volatile unsigned long unused3[15]; - volatile unsigned long g2pstatus; /* +80 */ - volatile unsigned long g2pmask; - volatile unsigned long pcisstatus; - volatile unsigned long pcimask; - volatile unsigned long p2gcfg; /* +90 */ - volatile unsigned long p2gstatus; - volatile unsigned long p2gmask; - volatile unsigned long p2gccmd; - volatile unsigned long unused4[24]; /* +a0 */ - volatile unsigned long pbareqport; /* +100 */ - volatile unsigned long pbacfg; - volatile unsigned long pbastatus; - volatile unsigned long pbamask; - volatile unsigned long pbabm; /* +110 */ - volatile unsigned long pbacreq; - volatile unsigned long pbacgnt; - volatile unsigned long pbacstate; - volatile unsigned long long g2pmgbase[3]; /* +120 */ - volatile unsigned long long g2piogbase; - volatile unsigned long g2pmmask[3]; /* +140 */ - volatile unsigned long g2piomask; - volatile unsigned long long g2pmpbase[3]; /* +150 */ - volatile unsigned long long g2piopbase; - volatile unsigned long pciccfg; /* +170 */ - volatile unsigned long pcicstatus; - volatile unsigned long pcicmask; - volatile unsigned long unused5; - volatile unsigned long long p2gmgbase[3]; /* +180 */ - volatile unsigned long long p2giogbase; - volatile unsigned long g2pcfgadrs; /* +1a0 */ - volatile unsigned long g2pcfgdata; - volatile unsigned long unused6[8]; - volatile unsigned long g2pintack; - volatile unsigned long g2pspc; - volatile unsigned long unused7[12]; /* +1d0 */ - volatile unsigned long long pdmca; /* +200 */ - volatile unsigned long long pdmga; - volatile unsigned long long pdmpa; - volatile unsigned long long pdmcut; - volatile unsigned long long pdmcnt; /* +220 */ - volatile unsigned long long pdmsts; - volatile unsigned long long unused8[2]; - volatile unsigned long long pdmdb[4]; /* +240 */ - volatile unsigned long long pdmtdh; /* +260 */ - volatile unsigned long long pdmdms; + u64 ccfg; + u64 crir; + u64 pcfg; + u64 toea; + u64 clkctr; + u64 unused0; + u64 garbc; + u64 unused1; + u64 unused2; + u64 ramp; }; -#endif /* _LANGUAGE_ASSEMBLY */ - -/* - * PCIC - */ - -/* bits for G2PSTATUS/G2PMASK */ -#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 -#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 -#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 - -/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ -#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 - -/* bits for PBACFG */ -#define TX4927_PCIC_PBACFG_RPBA 0x00000004 -#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 -#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 - -/* bits for G2PMnGBASE */ -#define TX4927_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for G2PIOGBASE */ -#define TX4927_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for PCICSTATUS/PCICMASK */ -#define TX4927_PCIC_PCICSTATUS_ALL 0x000007dc - -/* bits for PCICCFG */ -#define TX4927_PCIC_PCICCFG_LBWC_MASK 0x0fff0000 -#define TX4927_PCIC_PCICCFG_HRST 0x00000800 -#define TX4927_PCIC_PCICCFG_SRST 0x00000400 -#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 -#define TX4927_PCIC_PCICCFG_IMSE0 0x00000100 -#define TX4927_PCIC_PCICCFG_IMSE1 0x00000080 -#define TX4927_PCIC_PCICCFG_IMSE2 0x00000040 -#define TX4927_PCIC_PCICCFG_IISE 0x00000020 -#define TX4927_PCIC_PCICCFG_ATR 0x00000010 -#define TX4927_PCIC_PCICCFG_ICAE 0x00000008 - -/* bits for P2GMnGBASE */ -#define TX4927_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) -#define TX4927_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) - -/* bits for P2GIOGBASE */ -#define TX4927_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) -#define TX4927_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4927_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) - -#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) -#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) - /* * CCFG */ /* CCFG : Chip Configuration */ +#define TX4927_CCFG_WDRST 0x0000020000000000ULL +#define TX4927_CCFG_WDREXEN 0x0000010000000000ULL +#define TX4927_CCFG_BCFG_MASK 0x000000ff00000000ULL +#define TX4927_CCFG_TINTDIS 0x01000000 #define TX4927_CCFG_PCI66 0x00800000 -#define TX4927_CCFG_PCIMIDE 0x00400000 -#define TX4927_CCFG_PCIXARB 0x00002000 +#define TX4927_CCFG_PCIMODE 0x00400000 +#define TX4927_CCFG_DIVMODE_MASK 0x000e0000 +#define TX4927_CCFG_DIVMODE_8 (0x0 << 17) +#define TX4927_CCFG_DIVMODE_12 (0x1 << 17) +#define TX4927_CCFG_DIVMODE_16 (0x2 << 17) +#define TX4927_CCFG_DIVMODE_10 (0x3 << 17) +#define TX4927_CCFG_DIVMODE_2 (0x4 << 17) +#define TX4927_CCFG_DIVMODE_3 (0x5 << 17) +#define TX4927_CCFG_DIVMODE_4 (0x6 << 17) +#define TX4927_CCFG_DIVMODE_2_5 (0x7 << 17) +#define TX4927_CCFG_BEOW 0x00010000 +#define TX4927_CCFG_WR 0x00008000 +#define TX4927_CCFG_TOE 0x00004000 +#define TX4927_CCFG_PCIARB 0x00002000 #define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800 #define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000 #define TX4927_CCFG_PCIDIVMODE_3 0x00000800 #define TX4927_CCFG_PCIDIVMODE_5 0x00001000 #define TX4927_CCFG_PCIDIVMODE_6 0x00001800 - -#define TX4937_CCFG_PCIDIVMODE_MASK 0x00001c00 -#define TX4937_CCFG_PCIDIVMODE_8 0x00000000 -#define TX4937_CCFG_PCIDIVMODE_4 0x00000400 -#define TX4937_CCFG_PCIDIVMODE_9 0x00000800 -#define TX4937_CCFG_PCIDIVMODE_4_5 0x00000c00 -#define TX4937_CCFG_PCIDIVMODE_10 0x00001000 -#define TX4937_CCFG_PCIDIVMODE_5 0x00001400 -#define TX4937_CCFG_PCIDIVMODE_11 0x00001800 -#define TX4937_CCFG_PCIDIVMODE_5_5 0x00001c00 +#define TX4927_CCFG_SYSSP_MASK 0x000000c0 +#define TX4927_CCFG_ENDIAN 0x00000004 +#define TX4927_CCFG_HALT 0x00000002 +#define TX4927_CCFG_ACEHOLD 0x00000001 +#define TX4927_CCFG_W1CBITS (TX4927_CCFG_WDRST | TX4927_CCFG_BEOW) /* PCFG : Pin Configuration */ +#define TX4927_PCFG_SDCLKDLY_MASK 0x30000000 +#define TX4927_PCFG_SDCLKDLY(d) ((d)<<28) +#define TX4927_PCFG_SYSCLKEN 0x08000000 +#define TX4927_PCFG_SDCLKEN_ALL 0x07800000 +#define TX4927_PCFG_SDCLKEN(ch) (0x00800000<<(ch)) #define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 #define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) +#define TX4927_PCFG_SEL2 0x00000200 +#define TX4927_PCFG_SEL1 0x00000100 +#define TX4927_PCFG_DMASEL_ALL 0x000000ff +#define TX4927_PCFG_DMASEL0_MASK 0x00000003 +#define TX4927_PCFG_DMASEL1_MASK 0x0000000c +#define TX4927_PCFG_DMASEL2_MASK 0x00000030 +#define TX4927_PCFG_DMASEL3_MASK 0x000000c0 +#define TX4927_PCFG_DMASEL0_DRQ0 0x00000000 +#define TX4927_PCFG_DMASEL0_SIO1 0x00000001 +#define TX4927_PCFG_DMASEL0_ACL0 0x00000002 +#define TX4927_PCFG_DMASEL0_ACL2 0x00000003 +#define TX4927_PCFG_DMASEL1_DRQ1 0x00000000 +#define TX4927_PCFG_DMASEL1_SIO1 0x00000004 +#define TX4927_PCFG_DMASEL1_ACL1 0x00000008 +#define TX4927_PCFG_DMASEL1_ACL3 0x0000000c +#define TX4927_PCFG_DMASEL2_DRQ2 0x00000000 /* SEL2=0 */ +#define TX4927_PCFG_DMASEL2_SIO0 0x00000010 /* SEL2=0 */ +#define TX4927_PCFG_DMASEL2_ACL1 0x00000000 /* SEL2=1 */ +#define TX4927_PCFG_DMASEL2_ACL2 0x00000020 /* SEL2=1 */ +#define TX4927_PCFG_DMASEL2_ACL0 0x00000030 /* SEL2=1 */ +#define TX4927_PCFG_DMASEL3_DRQ3 0x00000000 +#define TX4927_PCFG_DMASEL3_SIO0 0x00000040 +#define TX4927_PCFG_DMASEL3_ACL3 0x00000080 +#define TX4927_PCFG_DMASEL3_ACL1 0x000000c0 /* CLKCTR : Clock Control */ +#define TX4927_CLKCTR_ACLCKD 0x02000000 +#define TX4927_CLKCTR_PIOCKD 0x01000000 +#define TX4927_CLKCTR_DMACKD 0x00800000 #define TX4927_CLKCTR_PCICKD 0x00400000 +#define TX4927_CLKCTR_TM0CKD 0x00100000 +#define TX4927_CLKCTR_TM1CKD 0x00080000 +#define TX4927_CLKCTR_TM2CKD 0x00040000 +#define TX4927_CLKCTR_SIO0CKD 0x00020000 +#define TX4927_CLKCTR_SIO1CKD 0x00010000 +#define TX4927_CLKCTR_ACLRST 0x00000200 +#define TX4927_CLKCTR_PIORST 0x00000100 +#define TX4927_CLKCTR_DMARST 0x00000080 #define TX4927_CLKCTR_PCIRST 0x00000040 - -#ifndef _LANGUAGE_ASSEMBLY +#define TX4927_CLKCTR_TM0RST 0x00000010 +#define TX4927_CLKCTR_TM1RST 0x00000008 +#define TX4927_CLKCTR_TM2RST 0x00000004 +#define TX4927_CLKCTR_SIO0RST 0x00000002 +#define TX4927_CLKCTR_SIO1RST 0x00000001 #define tx4927_sdramcptr ((struct tx4927_sdramc_reg *)TX4927_SDRAMC_REG) -#define tx4927_pcicptr ((struct tx4927_pcic_reg *)TX4927_PCIC_REG) -#define tx4927_ccfgptr ((struct tx4927_ccfg_reg *)TX4927_CCFG_REG) +#define tx4927_pcicptr \ + ((struct tx4927_pcic_reg __iomem *)TX4927_PCIC_REG) +#define tx4927_ccfgptr \ + ((struct tx4927_ccfg_reg __iomem *)TX4927_CCFG_REG) #define tx4927_ebuscptr ((struct tx4927_ebusc_reg *)TX4927_EBUSC_REG) -#endif /* _LANGUAGE_ASSEMBLY */ +/* utilities */ +static inline void txx9_clear64(__u64 __iomem *adr, __u64 bits) +{ +#ifdef CONFIG_32BIT + unsigned long flags; + local_irq_save(flags); +#endif + ____raw_writeq(____raw_readq(adr) & ~bits, adr); +#ifdef CONFIG_32BIT + local_irq_restore(flags); +#endif +} +static inline void txx9_set64(__u64 __iomem *adr, __u64 bits) +{ +#ifdef CONFIG_32BIT + unsigned long flags; + local_irq_save(flags); +#endif + ____raw_writeq(____raw_readq(adr) | bits, adr); +#ifdef CONFIG_32BIT + local_irq_restore(flags); +#endif +} + +/* These functions are not interrupt safe. */ +static inline void tx4927_ccfg_clear(__u64 bits) +{ + ____raw_writeq(____raw_readq(&tx4927_ccfgptr->ccfg) + & ~(TX4927_CCFG_W1CBITS | bits), + &tx4927_ccfgptr->ccfg); +} +static inline void tx4927_ccfg_set(__u64 bits) +{ + ____raw_writeq((____raw_readq(&tx4927_ccfgptr->ccfg) + & ~TX4927_CCFG_W1CBITS) | bits, + &tx4927_ccfgptr->ccfg); +} +static inline void tx4927_ccfg_change(__u64 change, __u64 new) +{ + ____raw_writeq((____raw_readq(&tx4927_ccfgptr->ccfg) + & ~(TX4927_CCFG_W1CBITS | change)) | + new, + &tx4927_ccfgptr->ccfg); +} + +int tx4927_report_pciclk(void); +int tx4927_pciclk66_setup(void); #endif /* __ASM_TXX9_TX4927_H */ diff --git a/include/asm-mips/txx9/tx4927pcic.h b/include/asm-mips/txx9/tx4927pcic.h new file mode 100644 index 0000000..d61c3d0 --- /dev/null +++ b/include/asm-mips/txx9/tx4927pcic.h @@ -0,0 +1,199 @@ +/* + * include/asm-mips/txx9/tx4927pcic.h + * TX4927 PCI controller definitions. + * + * 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. + */ +#ifndef __ASM_TXX9_TX4927PCIC_H +#define __ASM_TXX9_TX4927PCIC_H + +#include + +struct tx4927_pcic_reg { + u32 pciid; + u32 pcistatus; + u32 pciccrev; + u32 pcicfg1; + u32 p2gm0plbase; /* +10 */ + u32 p2gm0pubase; + u32 p2gm1plbase; + u32 p2gm1pubase; + u32 p2gm2pbase; /* +20 */ + u32 p2giopbase; + u32 unused0; + u32 pcisid; + u32 unused1; /* +30 */ + u32 pcicapptr; + u32 unused2; + u32 pcicfg2; + u32 g2ptocnt; /* +40 */ + u32 unused3[15]; + u32 g2pstatus; /* +80 */ + u32 g2pmask; + u32 pcisstatus; + u32 pcimask; + u32 p2gcfg; /* +90 */ + u32 p2gstatus; + u32 p2gmask; + u32 p2gccmd; + u32 unused4[24]; /* +a0 */ + u32 pbareqport; /* +100 */ + u32 pbacfg; + u32 pbastatus; + u32 pbamask; + u32 pbabm; /* +110 */ + u32 pbacreq; + u32 pbacgnt; + u32 pbacstate; + u64 g2pmgbase[3]; /* +120 */ + u64 g2piogbase; + u32 g2pmmask[3]; /* +140 */ + u32 g2piomask; + u64 g2pmpbase[3]; /* +150 */ + u64 g2piopbase; + u32 pciccfg; /* +170 */ + u32 pcicstatus; + u32 pcicmask; + u32 unused5; + u64 p2gmgbase[3]; /* +180 */ + u64 p2giogbase; + u32 g2pcfgadrs; /* +1a0 */ + u32 g2pcfgdata; + u32 unused6[8]; + u32 g2pintack; + u32 g2pspc; + u32 unused7[12]; /* +1d0 */ + u64 pdmca; /* +200 */ + u64 pdmga; + u64 pdmpa; + u64 pdmctr; + u64 pdmcfg; /* +220 */ + u64 pdmsts; +}; + +/* bits for PCICMD */ +/* see PCI_COMMAND_XXX in linux/pci_regs.h */ + +/* bits for PCISTAT */ +/* see PCI_STATUS_XXX in linux/pci_regs.h */ + +/* bits for IOBA/MBA */ +/* see PCI_BASE_ADDRESS_XXX in linux/pci_regs.h */ + +/* bits for G2PSTATUS/G2PMASK */ +#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 +#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 +#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 + +/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci_regs.h */ +#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 + +/* bits for PBACFG */ +#define TX4927_PCIC_PBACFG_FIXPA 0x00000008 +#define TX4927_PCIC_PBACFG_RPBA 0x00000004 +#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 +#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 + +/* bits for PBASTATUS/PBAMASK */ +#define TX4927_PCIC_PBASTATUS_ALL 0x00000001 +#define TX4927_PCIC_PBASTATUS_BM 0x00000001 + +/* bits for G2PMnGBASE */ +#define TX4927_PCIC_G2PMnGBASE_BSDIS 0x0000002000000000ULL +#define TX4927_PCIC_G2PMnGBASE_ECHG 0x0000001000000000ULL + +/* bits for G2PIOGBASE */ +#define TX4927_PCIC_G2PIOGBASE_BSDIS 0x0000002000000000ULL +#define TX4927_PCIC_G2PIOGBASE_ECHG 0x0000001000000000ULL + +/* bits for PCICSTATUS/PCICMASK */ +#define TX4927_PCIC_PCICSTATUS_ALL 0x000007b8 +#define TX4927_PCIC_PCICSTATUS_PME 0x00000400 +#define TX4927_PCIC_PCICSTATUS_TLB 0x00000200 +#define TX4927_PCIC_PCICSTATUS_NIB 0x00000100 +#define TX4927_PCIC_PCICSTATUS_ZIB 0x00000080 +#define TX4927_PCIC_PCICSTATUS_PERR 0x00000020 +#define TX4927_PCIC_PCICSTATUS_SERR 0x00000010 +#define TX4927_PCIC_PCICSTATUS_GBE 0x00000008 +#define TX4927_PCIC_PCICSTATUS_IWB 0x00000002 +#define TX4927_PCIC_PCICSTATUS_E2PDONE 0x00000001 + +/* bits for PCICCFG */ +#define TX4927_PCIC_PCICCFG_GBWC_MASK 0x0fff0000 +#define TX4927_PCIC_PCICCFG_HRST 0x00000800 +#define TX4927_PCIC_PCICCFG_SRST 0x00000400 +#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 +#define TX4927_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch)) +#define TX4927_PCIC_PCICCFG_G2PM0EN 0x00000100 +#define TX4927_PCIC_PCICCFG_G2PM1EN 0x00000080 +#define TX4927_PCIC_PCICCFG_G2PM2EN 0x00000040 +#define TX4927_PCIC_PCICCFG_G2PIOEN 0x00000020 +#define TX4927_PCIC_PCICCFG_TCAR 0x00000010 +#define TX4927_PCIC_PCICCFG_ICAEN 0x00000008 + +/* bits for P2GMnGBASE */ +#define TX4927_PCIC_P2GMnGBASE_TMEMEN 0x0000004000000000ULL +#define TX4927_PCIC_P2GMnGBASE_TBSDIS 0x0000002000000000ULL +#define TX4927_PCIC_P2GMnGBASE_TECHG 0x0000001000000000ULL + +/* bits for P2GIOGBASE */ +#define TX4927_PCIC_P2GIOGBASE_TIOEN 0x0000004000000000ULL +#define TX4927_PCIC_P2GIOGBASE_TBSDIS 0x0000002000000000ULL +#define TX4927_PCIC_P2GIOGBASE_TECHG 0x0000001000000000ULL + +#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) + +/* bits for PDMCFG */ +#define TX4927_PCIC_PDMCFG_RSTFIFO 0x00200000 +#define TX4927_PCIC_PDMCFG_EXFER 0x00100000 +#define TX4927_PCIC_PDMCFG_REQDLY_MASK 0x00003800 +#define TX4927_PCIC_PDMCFG_REQDLY_NONE (0 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_16 (1 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_32 (2 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_64 (3 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_128 (4 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_256 (5 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_512 (6 << 11) +#define TX4927_PCIC_PDMCFG_REQDLY_1024 (7 << 11) +#define TX4927_PCIC_PDMCFG_ERRIE 0x00000400 +#define TX4927_PCIC_PDMCFG_NCCMPIE 0x00000200 +#define TX4927_PCIC_PDMCFG_NTCMPIE 0x00000100 +#define TX4927_PCIC_PDMCFG_CHNEN 0x00000080 +#define TX4927_PCIC_PDMCFG_XFRACT 0x00000040 +#define TX4927_PCIC_PDMCFG_BSWAP 0x00000020 +#define TX4927_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c +#define TX4927_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000 +#define TX4927_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004 +#define TX4927_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008 +#define TX4927_PCIC_PDMCFG_XFRDIRC 0x00000002 +#define TX4927_PCIC_PDMCFG_CHRST 0x00000001 + +/* bits for PDMSTS */ +#define TX4927_PCIC_PDMSTS_REQCNT_MASK 0x3f000000 +#define TX4927_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000 +#define TX4927_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000 +#define TX4927_PCIC_PDMSTS_FIFORP_MASK 0x00030000 +#define TX4927_PCIC_PDMSTS_ERRINT 0x00000800 +#define TX4927_PCIC_PDMSTS_DONEINT 0x00000400 +#define TX4927_PCIC_PDMSTS_CHNEN 0x00000200 +#define TX4927_PCIC_PDMSTS_XFRACT 0x00000100 +#define TX4927_PCIC_PDMSTS_ACCMP 0x00000080 +#define TX4927_PCIC_PDMSTS_NCCMP 0x00000040 +#define TX4927_PCIC_PDMSTS_NTCMP 0x00000020 +#define TX4927_PCIC_PDMSTS_CFGERR 0x00000008 +#define TX4927_PCIC_PDMSTS_PCIERR 0x00000004 +#define TX4927_PCIC_PDMSTS_CHNERR 0x00000002 +#define TX4927_PCIC_PDMSTS_DATAERR 0x00000001 +#define TX4927_PCIC_PDMSTS_ALL_CMP 0x000000e0 +#define TX4927_PCIC_PDMSTS_ALL_ERR 0x0000000f + +struct tx4927_pcic_reg __iomem *get_tx4927_pcicptr( + struct pci_controller *channel); +void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr, + struct pci_controller *channel, int extarb); +void tx4927_report_pcic_status(void); + +#endif /* __ASM_TXX9_TX4927PCIC_H */ diff --git a/include/asm-mips/txx9/tx4938.h b/include/asm-mips/txx9/tx4938.h index 7f9cfef..0bb8919 100644 --- a/include/asm-mips/txx9/tx4938.h +++ b/include/asm-mips/txx9/tx4938.h @@ -12,6 +12,9 @@ #ifndef __ASM_TXX9_TX4938_H #define __ASM_TXX9_TX4938_H +/* some controllers are compatible with 4927 */ +#include + #define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr)) #define tx4938_write_nfmc(b, addr) (*(volatile unsigned int *)(addr)) = (b) @@ -51,9 +54,6 @@ #define TX4938_ACLC_REG (TX4938_REG_BASE + 0xf700) #define TX4938_SPI_REG (TX4938_REG_BASE + 0xf800) -#ifdef __ASSEMBLY__ -#define _CONST64(c) c -#else #define _CONST64(c) c##ull #include @@ -113,68 +113,6 @@ struct tx4938_dma_reg { endian_def_l2(unused0, mcr); }; -struct tx4938_pcic_reg { - volatile unsigned long pciid; - volatile unsigned long pcistatus; - volatile unsigned long pciccrev; - volatile unsigned long pcicfg1; - volatile unsigned long p2gm0plbase; /* +10 */ - volatile unsigned long p2gm0pubase; - volatile unsigned long p2gm1plbase; - volatile unsigned long p2gm1pubase; - volatile unsigned long p2gm2pbase; /* +20 */ - volatile unsigned long p2giopbase; - volatile unsigned long unused0; - volatile unsigned long pcisid; - volatile unsigned long unused1; /* +30 */ - volatile unsigned long pcicapptr; - volatile unsigned long unused2; - volatile unsigned long pcicfg2; - volatile unsigned long g2ptocnt; /* +40 */ - volatile unsigned long unused3[15]; - volatile unsigned long g2pstatus; /* +80 */ - volatile unsigned long g2pmask; - volatile unsigned long pcisstatus; - volatile unsigned long pcimask; - volatile unsigned long p2gcfg; /* +90 */ - volatile unsigned long p2gstatus; - volatile unsigned long p2gmask; - volatile unsigned long p2gccmd; - volatile unsigned long unused4[24]; /* +a0 */ - volatile unsigned long pbareqport; /* +100 */ - volatile unsigned long pbacfg; - volatile unsigned long pbastatus; - volatile unsigned long pbamask; - volatile unsigned long pbabm; /* +110 */ - volatile unsigned long pbacreq; - volatile unsigned long pbacgnt; - volatile unsigned long pbacstate; - volatile unsigned long long g2pmgbase[3]; /* +120 */ - volatile unsigned long long g2piogbase; - volatile unsigned long g2pmmask[3]; /* +140 */ - volatile unsigned long g2piomask; - volatile unsigned long long g2pmpbase[3]; /* +150 */ - volatile unsigned long long g2piopbase; - volatile unsigned long pciccfg; /* +170 */ - volatile unsigned long pcicstatus; - volatile unsigned long pcicmask; - volatile unsigned long unused5; - volatile unsigned long long p2gmgbase[3]; /* +180 */ - volatile unsigned long long p2giogbase; - volatile unsigned long g2pcfgadrs; /* +1a0 */ - volatile unsigned long g2pcfgdata; - volatile unsigned long unused6[8]; - volatile unsigned long g2pintack; - volatile unsigned long g2pspc; - volatile unsigned long unused7[12]; /* +1d0 */ - volatile unsigned long long pdmca; /* +200 */ - volatile unsigned long long pdmga; - volatile unsigned long long pdmpa; - volatile unsigned long long pdmctr; - volatile unsigned long long pdmcfg; /* +220 */ - volatile unsigned long long pdmsts; -}; - struct tx4938_aclc_reg { volatile unsigned long acctlen; volatile unsigned long acctldis; @@ -262,18 +200,18 @@ struct tx4938_sramc_reg { }; struct tx4938_ccfg_reg { - volatile unsigned long long ccfg; - volatile unsigned long long crir; - volatile unsigned long long pcfg; - volatile unsigned long long tear; - volatile unsigned long long clkctr; - volatile unsigned long long unused0; - volatile unsigned long long garbc; - volatile unsigned long long unused1; - volatile unsigned long long unused2; - volatile unsigned long long ramp; - volatile unsigned long long unused3; - volatile unsigned long long jmpadr; + u64 ccfg; + u64 crir; + u64 pcfg; + u64 toea; + u64 clkctr; + u64 unused0; + u64 garbc; + u64 unused1; + u64 unused2; + u64 ramp; + u64 unused3; + u64 jmpadr; }; #undef endian_def_l2 @@ -282,8 +220,6 @@ struct tx4938_ccfg_reg { #undef endian_def_b2s #undef endian_def_b4 -#endif /* __ASSEMBLY__ */ - /* * NDFMC */ @@ -360,7 +296,7 @@ struct tx4938_ccfg_reg { #define TX4938_CCFG_BEOW 0x00010000 #define TX4938_CCFG_WR 0x00008000 #define TX4938_CCFG_TOE 0x00004000 -#define TX4938_CCFG_PCIXARB 0x00002000 +#define TX4938_CCFG_PCIARB 0x00002000 #define TX4938_CCFG_PCIDIVMODE_MASK 0x00001c00 #define TX4938_CCFG_PCIDIVMODE_4 (0x1 << 10) #define TX4938_CCFG_PCIDIVMODE_4_5 (0x3 << 10) @@ -436,110 +372,6 @@ struct tx4938_ccfg_reg { #define TX4938_CLKCTR_SIO0RST 0x00000002 #define TX4938_CLKCTR_SIO1RST 0x00000001 -/* bits for G2PSTATUS/G2PMASK */ -#define TX4938_PCIC_G2PSTATUS_ALL 0x00000003 -#define TX4938_PCIC_G2PSTATUS_TTOE 0x00000002 -#define TX4938_PCIC_G2PSTATUS_RTOE 0x00000001 - -/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ -#define TX4938_PCIC_PCISTATUS_ALL 0x0000f900 - -/* bits for PBACFG */ -#define TX4938_PCIC_PBACFG_FIXPA 0x00000008 -#define TX4938_PCIC_PBACFG_RPBA 0x00000004 -#define TX4938_PCIC_PBACFG_PBAEN 0x00000002 -#define TX4938_PCIC_PBACFG_BMCEN 0x00000001 - -/* bits for G2PMnGBASE */ -#define TX4938_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for G2PIOGBASE */ -#define TX4938_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) - -/* bits for PCICSTATUS/PCICMASK */ -#define TX4938_PCIC_PCICSTATUS_ALL 0x000007b8 -#define TX4938_PCIC_PCICSTATUS_PME 0x00000400 -#define TX4938_PCIC_PCICSTATUS_TLB 0x00000200 -#define TX4938_PCIC_PCICSTATUS_NIB 0x00000100 -#define TX4938_PCIC_PCICSTATUS_ZIB 0x00000080 -#define TX4938_PCIC_PCICSTATUS_PERR 0x00000020 -#define TX4938_PCIC_PCICSTATUS_SERR 0x00000010 -#define TX4938_PCIC_PCICSTATUS_GBE 0x00000008 -#define TX4938_PCIC_PCICSTATUS_IWB 0x00000002 -#define TX4938_PCIC_PCICSTATUS_E2PDONE 0x00000001 - -/* bits for PCICCFG */ -#define TX4938_PCIC_PCICCFG_GBWC_MASK 0x0fff0000 -#define TX4938_PCIC_PCICCFG_HRST 0x00000800 -#define TX4938_PCIC_PCICCFG_SRST 0x00000400 -#define TX4938_PCIC_PCICCFG_IRBER 0x00000200 -#define TX4938_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch)) -#define TX4938_PCIC_PCICCFG_G2PM0EN 0x00000100 -#define TX4938_PCIC_PCICCFG_G2PM1EN 0x00000080 -#define TX4938_PCIC_PCICCFG_G2PM2EN 0x00000040 -#define TX4938_PCIC_PCICCFG_G2PIOEN 0x00000020 -#define TX4938_PCIC_PCICCFG_TCAR 0x00000010 -#define TX4938_PCIC_PCICCFG_ICAEN 0x00000008 - -/* bits for P2GMnGBASE */ -#define TX4938_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) -#define TX4938_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) - -/* bits for P2GIOGBASE */ -#define TX4938_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) -#define TX4938_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) -#define TX4938_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) - -#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) -#define TX4938_PCIC_MAX_DEVNU TX4938_PCIC_IDSEL_AD_TO_SLOT(32) - -/* bits for PDMCFG */ -#define TX4938_PCIC_PDMCFG_RSTFIFO 0x00200000 -#define TX4938_PCIC_PDMCFG_EXFER 0x00100000 -#define TX4938_PCIC_PDMCFG_REQDLY_MASK 0x00003800 -#define TX4938_PCIC_PDMCFG_REQDLY_NONE (0 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_16 (1 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_32 (2 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_64 (3 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_128 (4 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_256 (5 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_512 (6 << 11) -#define TX4938_PCIC_PDMCFG_REQDLY_1024 (7 << 11) -#define TX4938_PCIC_PDMCFG_ERRIE 0x00000400 -#define TX4938_PCIC_PDMCFG_NCCMPIE 0x00000200 -#define TX4938_PCIC_PDMCFG_NTCMPIE 0x00000100 -#define TX4938_PCIC_PDMCFG_CHNEN 0x00000080 -#define TX4938_PCIC_PDMCFG_XFRACT 0x00000040 -#define TX4938_PCIC_PDMCFG_BSWAP 0x00000020 -#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c -#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000 -#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004 -#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008 -#define TX4938_PCIC_PDMCFG_XFRDIRC 0x00000002 -#define TX4938_PCIC_PDMCFG_CHRST 0x00000001 - -/* bits for PDMSTS */ -#define TX4938_PCIC_PDMSTS_REQCNT_MASK 0x3f000000 -#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000 -#define TX4938_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000 -#define TX4938_PCIC_PDMSTS_FIFORP_MASK 0x00030000 -#define TX4938_PCIC_PDMSTS_ERRINT 0x00000800 -#define TX4938_PCIC_PDMSTS_DONEINT 0x00000400 -#define TX4938_PCIC_PDMSTS_CHNEN 0x00000200 -#define TX4938_PCIC_PDMSTS_XFRACT 0x00000100 -#define TX4938_PCIC_PDMSTS_ACCMP 0x00000080 -#define TX4938_PCIC_PDMSTS_NCCMP 0x00000040 -#define TX4938_PCIC_PDMSTS_NTCMP 0x00000020 -#define TX4938_PCIC_PDMSTS_CFGERR 0x00000008 -#define TX4938_PCIC_PDMSTS_PCIERR 0x00000004 -#define TX4938_PCIC_PDMSTS_CHNERR 0x00000002 -#define TX4938_PCIC_PDMSTS_DATAERR 0x00000001 -#define TX4938_PCIC_PDMSTS_ALL_CMP 0x000000e0 -#define TX4938_PCIC_PDMSTS_ALL_ERR 0x0000000f - /* * DMA */ @@ -595,15 +427,15 @@ struct tx4938_ccfg_reg { #define TX4938_DMA_CSR_DESERR 0x00000002 #define TX4938_DMA_CSR_SORERR 0x00000001 -#ifndef __ASSEMBLY__ - #define tx4938_sdramcptr ((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG) #define tx4938_ebuscptr ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG) #define tx4938_dmaptr(ch) ((struct tx4938_dma_reg *)TX4938_DMA_REG(ch)) #define tx4938_ndfmcptr ((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG) -#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG) -#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG) -#define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG) +#define tx4938_pcicptr tx4927_pcicptr +#define tx4938_pcic1ptr \ + ((struct tx4927_pcic_reg __iomem *)TX4938_PCIC1_REG) +#define tx4938_ccfgptr \ + ((struct tx4938_ccfg_reg __iomem *)TX4938_CCFG_REG) #define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch)) #define tx4938_pioptr ((struct txx9_pio_reg __iomem *)TX4938_PIO_REG) #define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG) @@ -611,17 +443,25 @@ struct tx4938_ccfg_reg { #define tx4938_sramcptr ((struct tx4938_sramc_reg *)TX4938_SRAMC_REG) -#define TX4938_REV_MAJ_MIN() ((unsigned long)tx4938_ccfgptr->crir & 0x00ff) -#define TX4938_REV_PCODE() ((unsigned long)tx4938_ccfgptr->crir >> 16) +#define TX4938_REV_PCODE() \ + ((__u32)__raw_readq(&tx4938_ccfgptr->crir) >> 16) + +#define tx4938_ccfg_clear(bits) tx4927_ccfg_clear(bits) +#define tx4938_ccfg_set(bits) tx4927_ccfg_set(bits) +#define tx4938_ccfg_change(change, new) tx4927_ccfg_change(change, new) #define TX4938_SDRAMC_BA(ch) ((tx4938_sdramcptr->cr[ch] >> 49) << 21) #define TX4938_SDRAMC_SIZE(ch) (((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21) +#define TX4938_EBUSC_CR(ch) __raw_readq(&tx4938_ebuscptr->cr[(ch)]) #define TX4938_EBUSC_BA(ch) ((tx4938_ebuscptr->cr[ch] >> 48) << 20) #define TX4938_EBUSC_SIZE(ch) \ (0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf)) - -#endif /* !__ASSEMBLY__ */ +int tx4938_report_pciclk(void); +void tx4938_report_pci1clk(void); +int tx4938_pciclk66_setup(void); +struct pci_dev; +int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot); #endif -- cgit v0.10.2 From 766891565bdaf605ea4aebe3e75de77e848254d0 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 00:33:21 +0900 Subject: [MIPS] TXx9: Update defconfigs Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 92000a3..ab16e67 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-rc1 -# Thu Aug 2 23:07:36 2007 +# Linux kernel version: 2.6.26-rc9 +# Fri Jul 11 00:25:19 2008 # CONFIG_MIPS=y @@ -10,9 +10,11 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set @@ -24,6 +26,7 @@ CONFIG_MIPS=y # CONFIG_PMC_YOSEMITE is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CARMEL is not set @@ -38,18 +41,27 @@ CONFIG_TOSHIBA_JMR3927=y # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set # CONFIG_WR_PPMC is not set +# CONFIG_TOSHIBA_FPCIB0 is not set +CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=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_HOTPLUG_CPU is not set # CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=y CONFIG_CPU_BIG_ENDIAN=y # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y @@ -102,13 +114,20 @@ CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ARCH_FLATMEM_ENABLE=y +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_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=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 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set @@ -142,18 +161,25 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 +# 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=y 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 CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y @@ -166,6 +192,14 @@ 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_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 @@ -187,20 +221,19 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y CONFIG_MMU=y # -# PCCARD (PCMCIA/CardBus) support -# - -# # Executable file formats # CONFIG_BINFMT_ELF=y @@ -210,6 +243,7 @@ CONFIG_TRAD_SIGNALS=y # # Power management options # +CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PM is not set # @@ -243,25 +277,21 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # 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 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 # @@ -269,6 +299,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # 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 @@ -277,6 +308,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # 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 @@ -305,6 +337,7 @@ CONFIG_BLK_DEV=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -316,10 +349,6 @@ CONFIG_BLK_DEV=y # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set # CONFIG_MD is not set - -# -# Fusion MPT device support -# # CONFIG_FUSION is not set # @@ -327,7 +356,7 @@ CONFIG_BLK_DEV=y # # -# An alternative FireWire stack is available with EXPERIMENTAL=y +# A new alternative FireWire stack is available with EXPERIMENTAL=y # # CONFIG_IEEE1394 is not set # CONFIG_I2O is not set @@ -337,10 +366,27 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_ARCNET is not set -# CONFIG_PHYLIB 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_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 @@ -349,6 +395,10 @@ CONFIG_MII=y # CONFIG_DM9000 is not set # CONFIG_NET_TULIP 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_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set @@ -356,13 +406,13 @@ CONFIG_NET_PCI=y # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set CONFIG_TC35815=y -# CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139TOO is not set +# CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -377,6 +427,7 @@ CONFIG_TC35815=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_PPP is not set @@ -398,7 +449,6 @@ CONFIG_INPUT=y # # 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 @@ -422,6 +472,7 @@ CONFIG_INPUT=y # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -429,7 +480,6 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_DIGIEPCA is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set -# CONFIG_MOXA_SMARTIO_NEW is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set # CONFIG_SYNCLINK_GT is not set @@ -461,22 +511,30 @@ CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set CONFIG_DEVPORT=y # CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_HAVE_GPIO_LIB=y # -# SPI support +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: # -# 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=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -493,29 +551,46 @@ CONFIG_TXX9_WDT=y # CONFIG_WDTPCI is not set # +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 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_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 # # Sound @@ -524,7 +599,9 @@ CONFIG_TXX9_WDT=y # 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 is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y @@ -549,9 +626,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 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_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set @@ -559,23 +637,6 @@ CONFIG_RTC_DRV_DS1742=y # # on-CPU RTC drivers # - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -588,12 +649,10 @@ CONFIG_RTC_DRV_DS1742=y # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -620,7 +679,7 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -628,17 +687,15 @@ CONFIG_RAMFS=y # 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 - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -654,10 +711,6 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set # @@ -665,13 +718,15 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # 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 is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_CROSSCOMPILE=y +# CONFIG_SAMPLES is not set CONFIG_CMDLINE="" # @@ -685,6 +740,7 @@ CONFIG_CMDLINE="" # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig index f89482a..e0af6a9 100644 --- a/arch/mips/configs/rbhma4200_defconfig +++ b/arch/mips/configs/rbhma4200_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-rc1 -# Thu Aug 2 22:55:57 2007 +# Linux kernel version: 2.6.26-rc9 +# Thu Jul 10 23:52:40 2008 # CONFIG_MIPS=y @@ -10,9 +10,11 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set @@ -24,6 +26,7 @@ CONFIG_MIPS=y # CONFIG_PMC_YOSEMITE is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CARMEL is not set @@ -39,17 +42,26 @@ CONFIG_TOSHIBA_RBTX4927=y # CONFIG_TOSHIBA_RBTX4938 is not set # CONFIG_WR_PPMC is not set # CONFIG_TOSHIBA_FPCIB0 is not set +CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y +CONFIG_PCI_TX4927=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_TXX9=y +CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set # CONFIG_NO_IOPORT is not set CONFIG_CPU_BIG_ENDIAN=y # CONFIG_CPU_LITTLE_ENDIAN is not set @@ -107,13 +119,20 @@ CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ARCH_FLATMEM_ENABLE=y +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_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set @@ -148,19 +167,26 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# 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=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y 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 CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set CONFIG_ANON_INODES=y @@ -173,9 +199,18 @@ 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_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 is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set @@ -197,20 +232,19 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_LEGACY is not set CONFIG_MMU=y # -# PCCARD (PCMCIA/CardBus) support -# - -# # Executable file formats # CONFIG_BINFMT_ELF=y @@ -220,6 +254,7 @@ CONFIG_TRAD_SIGNALS=y # # Power management options # +CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PM is not set # @@ -254,26 +289,22 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set +# 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_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 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 # @@ -281,6 +312,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # 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 @@ -289,6 +321,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # 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 @@ -317,10 +350,11 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -332,10 +366,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set # CONFIG_MD is not set - -# -# Fusion MPT device support -# # CONFIG_FUSION is not set # @@ -343,7 +373,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # -# An alternative FireWire stack is available with EXPERIMENTAL=y +# A new alternative FireWire stack is available with EXPERIMENTAL=y # # CONFIG_IEEE1394 is not set # CONFIG_I2O is not set @@ -353,6 +383,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -366,7 +397,12 @@ CONFIG_NET_ETHERNET=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NE2000=y +# 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_NET_PCI is not set +# CONFIG_B44 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set @@ -376,6 +412,7 @@ CONFIG_NE2000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_PPP is not set @@ -405,6 +442,7 @@ CONFIG_SERIO_LIBPS2=y # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -428,22 +466,17 @@ CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM 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=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -451,7 +484,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_TXX9_WDT=m +CONFIG_TXX9_WDT=y # # PCI-based Watchdog Cards @@ -460,29 +493,46 @@ CONFIG_TXX9_WDT=m # CONFIG_WDTPCI is not set # +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 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_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 # # Sound @@ -490,7 +540,9 @@ CONFIG_TXX9_WDT=m # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT 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 @@ -515,9 +567,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 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_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set @@ -525,23 +578,6 @@ CONFIG_RTC_DRV_DS1742=y # # on-CPU RTC drivers # - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -554,12 +590,10 @@ CONFIG_RTC_DRV_DS1742=y CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_DNOTIFY 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 @@ -588,7 +622,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -596,18 +630,16 @@ CONFIG_RAMFS=y # 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 - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -624,10 +656,6 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set # @@ -635,13 +663,15 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # 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 is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_CROSSCOMPILE=y +# CONFIG_SAMPLES is not set CONFIG_CMDLINE="" CONFIG_SYS_SUPPORTS_KGDB=y @@ -656,6 +686,7 @@ CONFIG_SYS_SUPPORTS_KGDB=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index 70cf697..50aa1b6 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-rc1 -# Thu Aug 2 22:59:53 2007 +# Linux kernel version: 2.6.26-rc9 +# Thu Jul 10 23:53:27 2008 # CONFIG_MIPS=y @@ -10,9 +10,11 @@ CONFIG_MIPS=y # # CONFIG_MACH_ALCHEMY is not set # CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set # CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set @@ -24,6 +26,7 @@ CONFIG_MIPS=y # CONFIG_PMC_YOSEMITE is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CARMEL is not set @@ -38,6 +41,8 @@ CONFIG_MIPS=y # CONFIG_TOSHIBA_RBTX4927 is not set CONFIG_TOSHIBA_RBTX4938=y # CONFIG_WR_PPMC is not set +# CONFIG_TOSHIBA_FPCIB0 is not set +CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y # # Multiplex Pin Select @@ -45,21 +50,30 @@ CONFIG_TOSHIBA_RBTX4938=y CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y # CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set # CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set +CONFIG_PCI_TX4927=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_TXX9=y +CONFIG_CSRC_R4K=y +CONFIG_GPIO_TXX9=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set # CONFIG_NO_IOPORT is not set CONFIG_GENERIC_GPIO=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=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 @@ -113,13 +127,20 @@ CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ARCH_FLATMEM_ENABLE=y +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_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set @@ -154,19 +175,26 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# 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=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y 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 CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set CONFIG_ANON_INODES=y @@ -179,9 +207,18 @@ 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_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 is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set @@ -203,20 +240,19 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_LEGACY is not set CONFIG_MMU=y # -# PCCARD (PCMCIA/CardBus) support -# - -# # Executable file formats # CONFIG_BINFMT_ELF=y @@ -226,6 +262,7 @@ CONFIG_TRAD_SIGNALS=y # # Power management options # +CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PM is not set # @@ -260,26 +297,22 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set +# 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_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 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 # @@ -287,6 +320,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # 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 @@ -295,6 +329,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # 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 @@ -323,10 +358,11 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -338,10 +374,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set # CONFIG_MD is not set - -# -# Fusion MPT device support -# # CONFIG_FUSION is not set # @@ -349,7 +381,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # -# An alternative FireWire stack is available with EXPERIMENTAL=y +# A new alternative FireWire stack is available with EXPERIMENTAL=y # # CONFIG_IEEE1394 is not set # CONFIG_I2O is not set @@ -359,10 +391,27 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_ARCNET is not set -# CONFIG_PHYLIB 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_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 @@ -372,6 +421,10 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NE2000=y +# 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_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set @@ -379,13 +432,13 @@ CONFIG_NET_PCI=y # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set CONFIG_TC35815=y -# CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139TOO is not set +# CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -400,6 +453,7 @@ CONFIG_TC35815=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_PPP is not set @@ -424,6 +478,7 @@ CONFIG_TC35815=y # Character devices # # CONFIG_VT is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -447,17 +502,11 @@ CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM 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=y CONFIG_SPI_MASTER=y @@ -471,9 +520,25 @@ CONFIG_SPI_TXX9=y # CONFIG_SPI_AT25=y # CONFIG_SPI_TLE62X0 is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MCP23S08 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=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -490,29 +555,46 @@ CONFIG_TXX9_WDT=m # CONFIG_WDTPCI is not set # +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 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_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 # # Sound @@ -520,7 +602,9 @@ CONFIG_TXX9_WDT=m # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT 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 @@ -540,16 +624,18 @@ CONFIG_RTC_INTF_DEV_UIE_EMUL=y # # SPI RTC drivers # -CONFIG_RTC_DRV_RS5C348=y # CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +CONFIG_RTC_DRV_RS5C348=y # # Platform RTC drivers # # CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 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_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set @@ -557,23 +643,6 @@ CONFIG_RTC_DRV_RS5C348=y # # on-CPU RTC drivers # - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Userspace I/O -# # CONFIG_UIO is not set # @@ -586,12 +655,10 @@ CONFIG_RTC_DRV_RS5C348=y CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_DNOTIFY 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 @@ -620,7 +687,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -628,18 +695,16 @@ CONFIG_RAMFS=y # 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 - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -656,10 +721,6 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set # @@ -667,13 +728,15 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # 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 is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_CROSSCOMPILE=y +# CONFIG_SAMPLES is not set CONFIG_CMDLINE="" CONFIG_SYS_SUPPORTS_KGDB=y @@ -688,6 +751,7 @@ CONFIG_SYS_SUPPORTS_KGDB=y # Library routines # CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set -- cgit v0.10.2 From edcaf1a6a77315562e9781245cc8e028c9a921dc Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 23:27:54 +0900 Subject: [MIPS] TXx9: Make single kernel can support multiple boards Make single kernel can be used on RBTX4927/37/38. Also make some SoC-specific code independent from board-specific code. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2ea6fff..72baa1a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -550,66 +550,11 @@ config SNI_RM Technology and now in turn merged with Fujitsu. Say Y here to support this machine type. -config TOSHIBA_JMR3927 - bool "Toshiba JMR-TX3927 board" - select CEVT_TXX9 - select DMA_NONCOHERENT - select HW_HAS_PCI - select MIPS_TX3927 - select IRQ_TXX9 - select SWAP_IO_SPACE - select SYS_HAS_CPU_TX39XX - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_BIG_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ - select GPIO_TXX9 +config MACH_TX39XX + bool "Toshiba TX39 series based machines" -config TOSHIBA_RBTX4927 - bool "Toshiba RBTX49[23]7 board" - select CEVT_R4K - select CSRC_R4K - select CEVT_TXX9 - select DMA_NONCOHERENT - select HAS_TXX9_SERIAL - select HW_HAS_PCI - select IRQ_CPU - select IRQ_TXX9 - select PCI_TX4927 - select SWAP_IO_SPACE - select SYS_HAS_CPU_TX49XX - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_KGDB - select GENERIC_HARDIRQS_NO__DO_IRQ - help - This Toshiba board is based on the TX4927 processor. Say Y here to - support this machine type - -config TOSHIBA_RBTX4938 - bool "Toshiba RBTX4938 board" - select CEVT_R4K - select CSRC_R4K - select CEVT_TXX9 - select DMA_NONCOHERENT - select HAS_TXX9_SERIAL - select HW_HAS_PCI - select IRQ_CPU - select IRQ_TXX9 - select PCI_TX4927 - select SWAP_IO_SPACE - select SYS_HAS_CPU_TX49XX - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_KGDB - select GENERIC_HARDIRQS_NO__DO_IRQ - select GPIO_TXX9 - help - This Toshiba board is based on the TX4938 processor. Say Y here to - support this machine type +config MACH_TX49XX + bool "Toshiba TX49 series based machines" config WR_PPMC bool "Wind River PPMC board" @@ -887,10 +832,6 @@ config PCI_GT64XXX_PCI0 config NO_EXCEPT_FILL bool -config MIPS_TX3927 - bool - select HAS_TXX9_SERIAL - config MIPS_RM9122 bool select SERIAL_RM9000 diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 8e1e49c..d319cd6 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -551,29 +551,30 @@ endif all-$(CONFIG_SNI_RM) := vmlinux.ecoff # +# Common TXx9 +# +core-$(CONFIG_MACH_TX39XX) += arch/mips/txx9/generic/ +cflags-$(CONFIG_MACH_TX39XX) += -Iinclude/asm-mips/mach-jmr3927 +load-$(CONFIG_MACH_TX39XX) += 0xffffffff80050000 +core-$(CONFIG_MACH_TX49XX) += arch/mips/txx9/generic/ +cflags-$(CONFIG_MACH_TX49XX) += -Iinclude/asm-mips/mach-tx49xx +load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000 + +# # Toshiba JMR-TX3927 board # -core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/ \ - arch/mips/txx9/generic/ -cflags-$(CONFIG_TOSHIBA_JMR3927) += -Iinclude/asm-mips/mach-jmr3927 -load-$(CONFIG_TOSHIBA_JMR3927) += 0xffffffff80050000 +core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/ # # Toshiba RBTX4927 board or # Toshiba RBTX4937 board # core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/rbtx4927/ -core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/generic/ -cflags-$(CONFIG_TOSHIBA_RBTX4927) += -Iinclude/asm-mips/mach-tx49xx -load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 # # Toshiba RBTX4938 board # core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/ -core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/generic/ -cflags-$(CONFIG_TOSHIBA_RBTX4938) += -Iinclude/asm-mips/mach-tx49xx -load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000 cflags-y += -Iinclude/asm-mips/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 9087648..875b643 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -11,11 +11,10 @@ obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o -obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o +obj-$(CONFIG_SOC_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o -obj-$(CONFIG_PCI_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o # @@ -44,8 +43,10 @@ obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o -obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o pci-tx4927.o pci-tx4938.o -obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o pci-tx4938.o +obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o +obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o +obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o +obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index d5edaf2..0f10695 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -31,7 +31,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int __init jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; @@ -77,9 +77,3 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) irq = JMR3927_IRQ_ETHER0; return irq; } - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index abab485..321db26 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -36,7 +36,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int __init rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; @@ -71,9 +71,3 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } return irq; } - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c index 39c9958..a80579a 100644 --- a/arch/mips/pci/fixup-rbtx4938.c +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -13,7 +13,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int __init rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = tx4938_pcic1_map_irq(dev, slot); @@ -51,12 +51,3 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } return irq; } - -/* - * Do platform specific device initialization at pci_enable_device() time - */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} - diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index b8cdb19..b92a134 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -1,11 +1,89 @@ +config TOSHIBA_JMR3927 + bool "Toshiba JMR-TX3927 board" + depends on MACH_TX39XX + select SOC_TX3927 + +config TOSHIBA_RBTX4927 + bool "Toshiba RBTX49[23]7 board" + depends on MACH_TX49XX + select SOC_TX4927 + help + This Toshiba board is based on the TX4927 processor. Say Y here to + support this machine type + +config TOSHIBA_RBTX4938 + bool "Toshiba RBTX4938 board" + depends on MACH_TX49XX + select SOC_TX4938 + help + This Toshiba board is based on the TX4938 processor. Say Y here to + support this machine type + +config SOC_TX3927 + bool + select CEVT_TXX9 + select DMA_NONCOHERENT + select HAS_TXX9_SERIAL + select HW_HAS_PCI + select IRQ_TXX9 + select SWAP_IO_SPACE + select SYS_HAS_CPU_TX39XX + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_BIG_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ + select GPIO_TXX9 + +config SOC_TX4927 + bool + select CEVT_R4K + select CSRC_R4K + select CEVT_TXX9 + select DMA_NONCOHERENT + select HAS_TXX9_SERIAL + select HW_HAS_PCI + select IRQ_CPU + select IRQ_TXX9 + select PCI_TX4927 + select SWAP_IO_SPACE + select SYS_HAS_CPU_TX49XX + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB + select GENERIC_HARDIRQS_NO__DO_IRQ + select GPIO_TXX9 + +config SOC_TX4938 + bool + select CEVT_R4K + select CSRC_R4K + select CEVT_TXX9 + select DMA_NONCOHERENT + select HAS_TXX9_SERIAL + select HW_HAS_PCI + select IRQ_CPU + select IRQ_TXX9 + select PCI_TX4927 + select SWAP_IO_SPACE + select SYS_HAS_CPU_TX49XX + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_KGDB + select GENERIC_HARDIRQS_NO__DO_IRQ + select GPIO_TXX9 + config TOSHIBA_FPCIB0 bool "FPCIB0 Backplane Support" - depends on PCI && (SYS_HAS_CPU_TX49XX || SYS_HAS_CPU_TX39XX) + depends on PCI && (MACH_TX39XX || MACH_TX49XX) select I8259 config PICMG_PCI_BACKPLANE_DEFAULT bool "Support for PICMG PCI Backplane" - depends on PCI && (SYS_HAS_CPU_TX49XX || SYS_HAS_CPU_TX39XX) + depends on PCI && (MACH_TX39XX || MACH_TX49XX) default y if !TOSHIBA_FPCIB0 if TOSHIBA_RBTX4938 diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index b80b6e0..668fdaa 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -4,8 +4,8 @@ obj-y += setup.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_TOSHIBA_RBTX4927) += mem_tx4927.o irq_tx4927.o -obj-$(CONFIG_TOSHIBA_RBTX4938) += mem_tx4938.o irq_tx4938.o +obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o irq_tx4927.o +obj-$(CONFIG_SOC_TX4938) += mem_tx4938.o irq_tx4938.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o obj-$(CONFIG_KGDB) += dbgio.o diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c index 685ecc2..6377bd8 100644 --- a/arch/mips/txx9/generic/irq_tx4927.c +++ b/arch/mips/txx9/generic/irq_tx4927.c @@ -26,39 +26,12 @@ #include #include #include -#include -#ifdef CONFIG_TOSHIBA_RBTX4927 -#include -#endif +#include void __init tx4927_irq_init(void) { mips_cpu_irq_init(); txx9_irq_init(TX4927_IRC_REG); - set_irq_chained_handler(TX4927_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP7) /* cpu timer */ - do_IRQ(TX4927_IRQ_CPU_TIMER); - else if (pending & STATUSF_IP2) { /* tx4927 pic */ - int irq = txx9_irq(); -#ifdef CONFIG_TOSHIBA_RBTX4927 - if (irq == TX4927_IRQ_NEST_EXT_ON_PIC) - irq = toshiba_rbtx4927_irq_nested(irq); -#endif - if (unlikely(irq < 0)) { - spurious_interrupt(); - return; - } - do_IRQ(irq); - } else if (pending & STATUSF_IP0) /* user line 0 */ - do_IRQ(TX4927_IRQ_USER0); - else if (pending & STATUSF_IP1) /* user line 1 */ - do_IRQ(TX4927_IRQ_USER1); - else - spurious_interrupt(); + set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, + handle_simple_irq); } diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c index 0886d91..5fc86c9 100644 --- a/arch/mips/txx9/generic/irq_tx4938.c +++ b/arch/mips/txx9/generic/irq_tx4938.c @@ -14,35 +14,12 @@ #include #include #include -#include -#include +#include -void __init -tx4938_irq_init(void) +void __init tx4938_irq_init(void) { mips_cpu_irq_init(); txx9_irq_init(TX4938_IRC_REG); - set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); -} - -int toshiba_rbtx4938_irq_nested(int irq); - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_cause() & read_c0_status(); - - if (pending & STATUSF_IP7) - do_IRQ(TX4938_IRQ_CPU_TIMER); - else if (pending & STATUSF_IP2) { - int irq = txx9_irq(); - if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0)) - irq = toshiba_rbtx4938_irq_nested(irq); - if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); - } else if (pending & STATUSF_IP1) - do_IRQ(TX4938_IRQ_USER1); - else if (pending & STATUSF_IP0) - do_IRQ(TX4938_IRQ_USER0); + set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, + handle_simple_irq); } diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 8173faa..0b92d8c 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifdef CONFIG_TOSHIBA_FPCIB0 #include @@ -375,3 +376,13 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, #endif DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup); DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup); + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return txx9_board_vec->pci_map_irq(dev, slot, pin); +} diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 46a6311..66ff74f 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -14,7 +14,16 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include +#ifdef CONFIG_CPU_TX49XX +#include +#endif /* EBUSC settings of TX4927, etc. */ struct resource txx9_ce_res[8]; @@ -49,3 +58,163 @@ txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size) unsigned int txx9_master_clock; unsigned int txx9_cpu_clock; unsigned int txx9_gbus_clock; + + +/* Minimum CLK support */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "spi-baseclk")) + return (struct clk *)(txx9_gbus_clock / 2 / 4); + if (!strcmp(id, "imbus_clk")) + return (struct clk *)(txx9_gbus_clock / 2); + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +extern struct txx9_board_vec jmr3927_vec; +extern struct txx9_board_vec rbtx4927_vec; +extern struct txx9_board_vec rbtx4937_vec; +extern struct txx9_board_vec rbtx4938_vec; + +/* board definitions */ +static struct txx9_board_vec *board_vecs[] __initdata = { +#ifdef CONFIG_TOSHIBA_JMR3927 + &jmr3927_vec, +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 + &rbtx4927_vec, + &rbtx4937_vec, +#endif +#ifdef CONFIG_TOSHIBA_RBTX4938 + &rbtx4938_vec, +#endif +}; +struct txx9_board_vec *txx9_board_vec __initdata; +static char txx9_system_type[32]; + +void __init prom_init_cmdline(void) +{ + int argc = (int)fw_arg0; + char **argv = (char **)fw_arg1; + int i; /* Always ignore the "-c" at argv[0] */ + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) + *arcs_cmdline = '\0'; + + for (i = 1; i < argc; i++) { + if (i != 1) + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(void) +{ + int i; + +#ifdef CONFIG_CPU_TX39XX + mips_machtype = MACH_TOSHIBA_JMR3927; +#endif +#ifdef CONFIG_CPU_TX49XX + switch (TX4938_REV_PCODE()) { + case 0x4927: + mips_machtype = MACH_TOSHIBA_RBTX4927; + break; + case 0x4937: + mips_machtype = MACH_TOSHIBA_RBTX4937; + break; + case 0x4938: + mips_machtype = MACH_TOSHIBA_RBTX4938; + break; + } +#endif + for (i = 0; i < ARRAY_SIZE(board_vecs); i++) { + if (board_vecs[i]->type == mips_machtype) { + txx9_board_vec = board_vecs[i]; + strcpy(txx9_system_type, txx9_board_vec->system); + return txx9_board_vec->prom_init(); + } + } +} + +void __init prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return txx9_system_type; +} + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +/* wrappers */ +void __init plat_mem_setup(void) +{ + txx9_board_vec->mem_setup(); +} + +void __init arch_init_irq(void) +{ + txx9_board_vec->irq_setup(); +} + +void __init plat_time_init(void) +{ + txx9_board_vec->time_init(); +} + +static int __init _txx9_arch_init(void) +{ + if (txx9_board_vec->arch_init) + txx9_board_vec->arch_init(); + return 0; +} +arch_initcall(_txx9_arch_init); + +static int __init _txx9_device_init(void) +{ + if (txx9_board_vec->device_init) + txx9_board_vec->device_init(); + return 0; +} +device_initcall(_txx9_device_init); + +int (*txx9_irq_dispatch)(int pending); +asmlinkage void plat_irq_dispatch(void) +{ + int pending = read_c0_status() & read_c0_cause() & ST0_IM; + int irq = txx9_irq_dispatch(pending); + + if (likely(irq >= 0)) + do_IRQ(irq); + else + spurious_interrupt(); +} diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile index 5f83ea3..ba292c9 100644 --- a/arch/mips/txx9/jmr3927/Makefile +++ b/arch/mips/txx9/jmr3927/Makefile @@ -2,7 +2,7 @@ # Makefile for TOSHIBA JMR-TX3927 board # -obj-y += prom.o init.o irq.o setup.o +obj-y += prom.o irq.o setup.o obj-$(CONFIG_KGDB) += kgdb_io.o EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/jmr3927/init.c b/arch/mips/txx9/jmr3927/init.c deleted file mode 100644 index 1bbb534..0000000 --- a/arch/mips/txx9/jmr3927/init.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * arch/mips/jmr3927/common/init.c - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include - -extern void __init prom_init_cmdline(void); - -const char *get_system_type(void) -{ - return "Toshiba" -#ifdef CONFIG_TOSHIBA_JMR3927 - " JMR_TX3927" -#endif - ; -} - -extern void puts(const char *cp); - -void __init prom_init(void) -{ -#ifdef CONFIG_TOSHIBA_JMR3927 - /* CCFG */ - if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) - puts("Warning: TX3927 TLB off\n"); -#endif - - prom_init_cmdline(); - add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); -} diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c index b97d22e..070c9a1 100644 --- a/arch/mips/txx9/jmr3927/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c @@ -39,6 +39,7 @@ #include #include +#include #include #if JMR3927_IRQ_END > NR_IRQS @@ -77,37 +78,30 @@ static void unmask_irq_ioc(unsigned int irq) (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } -asmlinkage void plat_irq_dispatch(void) -{ - unsigned long cp0_cause = read_c0_cause(); - int irq; - - if ((cp0_cause & CAUSEF_IP7) == 0) - return; - irq = (cp0_cause >> CAUSEB_IP2) & 0x0f; - - do_IRQ(irq + JMR3927_IRQ_IRC); -} - -static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id) +static int jmr3927_ioc_irqroute(void) { unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); int i; for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) { - if (istat & (1 << i)) { - irq = JMR3927_IRQ_IOC + i; - do_IRQ(irq); - } + if (istat & (1 << i)) + return JMR3927_IRQ_IOC + i; } - return IRQ_HANDLED; + return -1; } -static struct irqaction ioc_action = { - .handler = jmr3927_ioc_interrupt, - .mask = CPU_MASK_NONE, - .name = "IOC", -}; +static int jmr3927_irq_dispatch(int pending) +{ + int irq; + + if ((pending & CAUSEF_IP7) == 0) + return -1; + irq = (pending >> CAUSEB_IP2) & 0x0f; + irq += JMR3927_IRQ_IRC; + if (irq == JMR3927_IRQ_IOCINT) + irq = jmr3927_ioc_irqroute(); + return irq; +} #ifdef CONFIG_PCI static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) @@ -127,8 +121,9 @@ static struct irqaction pcierr_action = { static void __init jmr3927_irq_init(void); -void __init arch_init_irq(void) +void __init jmr3927_irq_setup(void) { + txx9_irq_dispatch = jmr3927_irq_dispatch; /* Now, interrupt control disabled, */ /* all IRC interrupts are masked, */ /* all IRC interrupt mode are Low Active. */ @@ -146,7 +141,7 @@ void __init arch_init_irq(void) jmr3927_irq_init(); /* setup IOC interrupt 1 (PCI, MODEM) */ - setup_irq(JMR3927_IRQ_IOCINT, &ioc_action); + set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq); #ifdef CONFIG_PCI setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action); diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c index 8bc1049..2cadb42 100644 --- a/arch/mips/txx9/jmr3927/prom.c +++ b/arch/mips/txx9/jmr3927/prom.c @@ -35,42 +35,10 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include -#include - #include -#include - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - -void __init prom_init_cmdline(void) -{ - char *cp; - int actr; - int prom_argc = fw_arg0; - char **prom_argv = (char **) fw_arg1; - - actr = 1; /* Always ignore argv[0] */ - - cp = &(arcs_cmdline[0]); - while(actr < prom_argc) { - strcpy(cp, prom_argv[actr]); - cp += strlen(prom_argv[actr]); - *cp++ = ' '; - actr++; - } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ - --cp; - *cp = '\0'; -} - -void __init prom_free_prom_memory(void) -{ -} +#include +#include #define TIMEOUT 0xffffff @@ -96,3 +64,13 @@ puts(const char *cp) prom_putchar('\r'); prom_putchar('\n'); } + +void __init jmr3927_prom_init(void) +{ + /* CCFG */ + if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) + puts("Warning: TX3927 TLB off\n"); + + prom_init_cmdline(); + add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); +} diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index baa8c8d..128a4ae 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -34,15 +34,16 @@ #include #include #include -#include #include #ifdef CONFIG_SERIAL_TXX9 #include #endif +#include #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ static void jmr3927_machine_power_off(void) while (1); } -void __init plat_time_init(void) +static void __init jmr3927_time_init(void) { txx9_clockevent_init(TX3927_TMR_REG(0), TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0), @@ -97,7 +98,7 @@ void __init plat_time_init(void) extern char * __init prom_getcmdline(void); static void jmr3927_board_init(void); -void __init plat_mem_setup(void) +static void __init jmr3927_mem_setup(void) { char *argptr; @@ -233,6 +234,8 @@ static void __init tx3927_setup(void) { int i; + txx9_cpu_clock = JMR3927_CORECLK; + txx9_gbus_clock = JMR3927_GBUSCLK; /* SDRAMC are configured by PROM */ /* ROMC */ @@ -336,7 +339,6 @@ static int __init jmr3927_rtc_init(void) dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } -device_initcall(jmr3927_rtc_init); /* Watchdog support */ @@ -356,36 +358,22 @@ static int __init jmr3927_wdt_init(void) { return txx9_wdt_init(TX3927_TMR_REG(2)); } -device_initcall(jmr3927_wdt_init); -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "imbus_clk")) - return (struct clk *)JMR3927_IMCLK; - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) +static void __init jmr3927_device_init(void) { + jmr3927_rtc_init(); + jmr3927_wdt_init(); } -EXPORT_SYMBOL(clk_disable); -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); +struct txx9_board_vec jmr3927_vec __initdata = { + .type = MACH_TOSHIBA_JMR3927, + .system = "Toshiba JMR_TX3927", + .prom_init = jmr3927_prom_init, + .mem_setup = jmr3927_mem_setup, + .irq_setup = jmr3927_irq_setup, + .time_init = jmr3927_time_init, + .device_init = jmr3927_device_init, +#ifdef CONFIG_PCI + .pci_map_irq = jmr3927_pci_map_irq, +#endif +}; diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index bef1447..70f1321 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -111,17 +111,10 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #include #include #include +#include +#include #include -#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 -#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 - -#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ -#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ - -#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC -#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) - static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); @@ -136,34 +129,25 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { #define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL #define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL -int toshiba_rbtx4927_irq_nested(int sw_irq) +static int toshiba_rbtx4927_irq_nested(int sw_irq) { u8 level3; level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; if (level3) - sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1; + sw_irq = RBTX4927_IRQ_IOC + fls(level3) - 1; return (sw_irq); } -static struct irqaction toshiba_rbtx4927_irq_ioc_action = { - .handler = no_action, - .flags = IRQF_SHARED, - .mask = CPU_MASK_NONE, - .name = TOSHIBA_RBTX4927_IOC_NAME -}; - static void __init toshiba_rbtx4927_irq_ioc_init(void) { int i; - for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) + for (i = RBTX4927_IRQ_IOC; + i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, handle_level_irq); - - setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, - &toshiba_rbtx4927_irq_ioc_action); + set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); } static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) @@ -171,7 +155,7 @@ static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) unsigned char v; v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); - v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + v |= (1 << (irq - RBTX4927_IRQ_IOC)); writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); } @@ -180,15 +164,34 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) unsigned char v; v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB); - v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + v &= ~(1 << (irq - RBTX4927_IRQ_IOC)); writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB); mmiowb(); } -void __init arch_init_irq(void) + +static int rbtx4927_irq_dispatch(int pending) { - extern void tx4927_irq_init(void); + int irq; + + if (pending & STATUSF_IP7) /* cpu timer */ + irq = MIPS_CPU_IRQ_BASE + 7; + else if (pending & STATUSF_IP2) { /* tx4927 pic */ + irq = txx9_irq(); + if (irq == RBTX4927_IRQ_IOCINT) + irq = toshiba_rbtx4927_irq_nested(irq); + } else if (pending & STATUSF_IP0) /* user line 0 */ + irq = MIPS_CPU_IRQ_BASE + 0; + else if (pending & STATUSF_IP1) /* user line 1 */ + irq = MIPS_CPU_IRQ_BASE + 1; + else + irq = -1; + return irq; +} +void __init rbtx4927_irq_setup(void) +{ + txx9_irq_dispatch = rbtx4927_irq_dispatch; tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); /* Onboard 10M Ether: High Active */ diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c index 0020bbe..942e627 100644 --- a/arch/mips/txx9/rbtx4927/prom.c +++ b/arch/mips/txx9/rbtx4927/prom.c @@ -30,62 +30,16 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include #include -#include -#include -#include +#include +#include -void __init prom_init_cmdline(void) -{ - int argc = (int) fw_arg0; - char **argv = (char **) fw_arg1; - int i; /* Always ignore the "-c" at argv[0] */ - - /* ignore all built-in args if any f/w args given */ - if (argc > 1) { - *arcs_cmdline = '\0'; - } - - for (i = 1; i < argc; i++) { - if (i != 1) { - strcat(arcs_cmdline, " "); - } - strcat(arcs_cmdline, argv[i]); - } -} - -void __init prom_init(void) +void __init rbtx4927_prom_init(void) { extern int tx4927_get_mem_size(void); - extern char* toshiba_name; int msize; prom_init_cmdline(); - - if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) { - mips_machtype = MACH_TOSHIBA_RBTX4927; - toshiba_name = "TX4927"; - } else { - mips_machtype = MACH_TOSHIBA_RBTX4937; - toshiba_name = "TX4937"; - } - msize = tx4927_get_mem_size(); add_memory_region(0, msize << 20, BOOT_MEM_RAM); } - -void __init prom_free_prom_memory(void) -{ -} - -const char *get_system_type(void) -{ - return "Toshiba RBTX4927/RBTX4937"; -} - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 86b870a..c3566c3 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include @@ -76,8 +75,6 @@ char *prom_getcmdline(void); static int tx4927_ccfg_toeon = 1; -char *toshiba_name = ""; - #ifdef CONFIG_PCI static void __init tx4927_pci_setup(void) { @@ -171,15 +168,15 @@ static void __init tx4937_pci_setup(void) } } -static int __init rbtx4927_arch_init(void) +static void __init rbtx4927_arch_init(void) { if (mips_machtype == MACH_TOSHIBA_RBTX4937) tx4937_pci_setup(); else tx4927_pci_setup(); - return 0; } -arch_initcall(rbtx4927_arch_init); +#else +#define rbtx4927_arch_init NULL #endif /* CONFIG_PCI */ static void __noreturn wait_forever(void) @@ -223,14 +220,12 @@ void toshiba_rbtx4927_power_off(void) /* no return */ } -void __init plat_mem_setup(void) +static void __init rbtx4927_mem_setup(void) { int i; u32 cp0_config; char *argptr; - printk("CPU is %s\n", toshiba_name); - /* f/w leaves this on at startup */ clear_c0_status(ST0_ERL); @@ -323,7 +318,7 @@ void __init plat_mem_setup(void) req.iotype = UPIO_MEM; req.membase = (char *)(0xff1ff300 + i * 0x100); req.mapbase = 0xff1ff300 + i * 0x100; - req.irq = TX4927_IRQ_PIC_BEG + 8 + i; + req.irq = TXX9_IRQ_BASE + TX4927_IR_SIO(i); req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; req.uartclk = 50000000; early_serial_txx9_setup(&req); @@ -352,7 +347,7 @@ void __init plat_mem_setup(void) #endif } -void __init plat_time_init(void) +static void __init rbtx4927_time_init(void) { mips_hpt_frequency = txx9_cpu_clock / 2; if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) @@ -372,7 +367,6 @@ static int __init toshiba_rbtx4927_rtc_init(void) platform_device_register_simple("rtc-ds1742", -1, &res, 1); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } -device_initcall(toshiba_rbtx4927_rtc_init); static int __init rbtx4927_ne_init(void) { @@ -391,7 +385,6 @@ static int __init rbtx4927_ne_init(void) res, ARRAY_SIZE(res)); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } -device_initcall(rbtx4927_ne_init); /* Watchdog support */ @@ -411,36 +404,37 @@ static int __init rbtx4927_wdt_init(void) { return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); } -device_initcall(rbtx4927_wdt_init); - -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "imbus_clk")) - return (struct clk *)50000000; - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); -void clk_disable(struct clk *clk) +static void __init rbtx4927_device_init(void) { + toshiba_rbtx4927_rtc_init(); + rbtx4927_ne_init(); + rbtx4927_wdt_init(); } -EXPORT_SYMBOL(clk_disable); -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); +struct txx9_board_vec rbtx4927_vec __initdata = { + .type = MACH_TOSHIBA_RBTX4927, + .system = "Toshiba RBTX4927", + .prom_init = rbtx4927_prom_init, + .mem_setup = rbtx4927_mem_setup, + .irq_setup = rbtx4927_irq_setup, + .time_init = rbtx4927_time_init, + .device_init = rbtx4927_device_init, + .arch_init = rbtx4927_arch_init, +#ifdef CONFIG_PCI + .pci_map_irq = rbtx4927_pci_map_irq, +#endif +}; +struct txx9_board_vec rbtx4937_vec __initdata = { + .type = MACH_TOSHIBA_RBTX4937, + .system = "Toshiba RBTX4937", + .prom_init = rbtx4927_prom_init, + .mem_setup = rbtx4927_mem_setup, + .irq_setup = rbtx4927_irq_setup, + .time_init = rbtx4927_time_init, + .device_init = rbtx4927_device_init, + .arch_init = rbtx4927_arch_init, +#ifdef CONFIG_PCI + .pci_map_irq = rbtx4927_pci_map_irq, +#endif +}; diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c index f498482..3971a06 100644 --- a/arch/mips/txx9/rbtx4938/irq.c +++ b/arch/mips/txx9/rbtx4938/irq.c @@ -66,6 +66,8 @@ IRQ Device */ #include #include +#include +#include #include static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); @@ -80,26 +82,17 @@ static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { .unmask = toshiba_rbtx4938_irq_ioc_enable, }; -int -toshiba_rbtx4938_irq_nested(int sw_irq) +static int toshiba_rbtx4938_irq_nested(int sw_irq) { u8 level3; level3 = readb(rbtx4938_imstat_addr); if (level3) /* must use fls so onboard ATA has priority */ - sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1; - + sw_irq = RBTX4938_IRQ_IOC + fls(level3) - 1; return sw_irq; } -static struct irqaction toshiba_rbtx4938_irq_ioc_action = { - .handler = no_action, - .flags = 0, - .mask = CPU_MASK_NONE, - .name = TOSHIBA_RBTX4938_IOC_NAME, -}; - /**********************************************************************************/ /* Functions for ioc */ /**********************************************************************************/ @@ -108,13 +101,12 @@ toshiba_rbtx4938_irq_ioc_init(void) { int i; - for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) + for (i = RBTX4938_IRQ_IOC; + i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, handle_level_irq); - setup_irq(RBTX4938_IRQ_IOCINT, - &toshiba_rbtx4938_irq_ioc_action); + set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); } static void @@ -123,7 +115,7 @@ toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) unsigned char v; v = readb(rbtx4938_imask_addr); - v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); + v |= (1 << (irq - RBTX4938_IRQ_IOC)); writeb(v, rbtx4938_imask_addr); mmiowb(); } @@ -134,15 +126,33 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) unsigned char v; v = readb(rbtx4938_imask_addr); - v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); + v &= ~(1 << (irq - RBTX4938_IRQ_IOC)); writeb(v, rbtx4938_imask_addr); mmiowb(); } -void __init arch_init_irq(void) +static int rbtx4938_irq_dispatch(int pending) { - extern void tx4938_irq_init(void); + int irq; + + if (pending & STATUSF_IP7) + irq = MIPS_CPU_IRQ_BASE + 7; + else if (pending & STATUSF_IP2) { + irq = txx9_irq(); + if (irq == RBTX4938_IRQ_IOCINT) + irq = toshiba_rbtx4938_irq_nested(irq); + } else if (pending & STATUSF_IP1) + irq = MIPS_CPU_IRQ_BASE + 0; + else if (pending & STATUSF_IP0) + irq = MIPS_CPU_IRQ_BASE + 1; + else + irq = -1; + return irq; +} +void __init rbtx4938_irq_setup(void) +{ + txx9_irq_dispatch = rbtx4938_irq_dispatch; /* Now, interrupt control disabled, */ /* all IRC interrupts are masked, */ /* all IRC interrupt mode are Low Active. */ diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c index 134fcc2..fbb3745 100644 --- a/arch/mips/txx9/rbtx4938/prom.c +++ b/arch/mips/txx9/rbtx4938/prom.c @@ -11,34 +11,12 @@ */ #include -#include -#include #include - -#include #include -#include - -void __init prom_init_cmdline(void) -{ - int argc = (int) fw_arg0; - char **argv = (char **) fw_arg1; - int i; - - /* ignore all built-in args if any f/w args given */ - if (argc > 1) { - *arcs_cmdline = '\0'; - } - - for (i = 1; i < argc; i++) { - if (i != 1) { - strcat(arcs_cmdline, " "); - } - strcat(arcs_cmdline, argv[i]); - } -} +#include +#include -void __init prom_init(void) +void __init rbtx4938_prom_init(void) { extern int tx4938_get_mem_size(void); int msize; @@ -48,25 +26,4 @@ void __init prom_init(void) msize = tx4938_get_mem_size(); add_memory_region(0, msize << 20, BOOT_MEM_RAM); - - return; -} - -void __init prom_free_prom_memory(void) -{ -} - -void __init prom_fixup_mem_map(unsigned long start, unsigned long end) -{ - return; -} - -const char *get_system_type(void) -{ - return "Toshiba RBTX4938"; -} - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); } diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 144d2ca..8306ba3 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -147,9 +146,9 @@ static void __init rbtx4938_pci_setup(void) #define SEEPROM3_CS 1 /* IOC */ #define SRTC_CS 2 /* IOC */ -#ifdef CONFIG_PCI static int __init rbtx4938_ethaddr_init(void) { +#ifdef CONFIG_PCI unsigned char dat[17]; unsigned char sum; int i; @@ -179,10 +178,9 @@ static int __init rbtx4938_ethaddr_init(void) platform_device_add(pdev)) platform_device_put(pdev); } +#endif /* CONFIG_PCI */ return 0; } -device_initcall(rbtx4938_ethaddr_init); -#endif /* CONFIG_PCI */ static void __init rbtx4938_spi_setup(void) { @@ -366,7 +364,7 @@ void __init tx4938_board_setup(void) #endif } -void __init plat_time_init(void) +static void __init rbtx4938_time_init(void) { mips_hpt_frequency = txx9_cpu_clock / 2; if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) @@ -375,7 +373,7 @@ void __init plat_time_init(void) txx9_gbus_clock / 2); } -void __init plat_mem_setup(void) +static void __init rbtx4938_mem_setup(void) { unsigned long long pcfg; char *argptr; @@ -496,7 +494,6 @@ static int __init rbtx4938_ne_init(void) res, ARRAY_SIZE(res)); return IS_ERR(dev) ? PTR_ERR(dev) : 0; } -device_initcall(rbtx4938_ne_init); /* GPIO support */ @@ -587,14 +584,13 @@ static int __init rbtx4938_spi_init(void) return 0; } -static int __init rbtx4938_arch_init(void) +static void __init rbtx4938_arch_init(void) { txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); gpiochip_add(&rbtx4938_spi_gpio_chip); rbtx4938_pci_setup(); - return rbtx4938_spi_init(); + rbtx4938_spi_init(); } -arch_initcall(rbtx4938_arch_init); /* Watchdog support */ @@ -614,38 +610,24 @@ static int __init rbtx4938_wdt_init(void) { return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); } -device_initcall(rbtx4938_wdt_init); - -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "spi-baseclk")) - return (struct clk *)(txx9_gbus_clock / 2 / 4); - if (!strcmp(id, "imbus_clk")) - return (struct clk *)(txx9_gbus_clock / 2); - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); -unsigned long clk_get_rate(struct clk *clk) +static void __init rbtx4938_device_init(void) { - return (unsigned long)clk; + rbtx4938_ethaddr_init(); + rbtx4938_ne_init(); + rbtx4938_wdt_init(); } -EXPORT_SYMBOL(clk_get_rate); -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); +struct txx9_board_vec rbtx4938_vec __initdata = { + .type = MACH_TOSHIBA_RBTX4938, + .system = "Toshiba RBTX4938", + .prom_init = rbtx4938_prom_init, + .mem_setup = rbtx4938_mem_setup, + .irq_setup = rbtx4938_irq_setup, + .time_init = rbtx4938_time_init, + .device_init = rbtx4938_device_init, + .arch_init = rbtx4938_arch_init, +#ifdef CONFIG_PCI + .pci_map_irq = rbtx4938_pci_map_irq, +#endif +}; diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 2ff6c20..6cd1477 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -20,4 +20,22 @@ extern unsigned int txx9_master_clock; extern unsigned int txx9_cpu_clock; extern unsigned int txx9_gbus_clock; +struct pci_dev; +struct txx9_board_vec { + unsigned long type; + const char *system; + void (*prom_init)(void); + void (*mem_setup)(void); + void (*irq_setup)(void); + void (*time_init)(void); + void (*arch_init)(void); + void (*device_init)(void); +#ifdef CONFIG_PCI + int (*pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); +#endif +}; +extern struct txx9_board_vec *txx9_board_vec; +extern int (*txx9_irq_dispatch)(int pending); +void prom_init_cmdline(void); + #endif /* __ASM_TXX9_GENERIC_H */ diff --git a/include/asm-mips/txx9/jmr3927.h b/include/asm-mips/txx9/jmr3927.h index 29e5498..d6eb1b6 100644 --- a/include/asm-mips/txx9/jmr3927.h +++ b/include/asm-mips/txx9/jmr3927.h @@ -174,4 +174,9 @@ * INT[3:0] */ +void jmr3927_prom_init(void); +void jmr3927_irq_setup(void); +struct pci_dev; +int jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); + #endif /* __ASM_TXX9_JMR3927_H */ diff --git a/include/asm-mips/txx9/rbtx4927.h b/include/asm-mips/txx9/rbtx4927.h index 5b6f488..bf19458 100644 --- a/include/asm-mips/txx9/rbtx4927.h +++ b/include/asm-mips/txx9/rbtx4927.h @@ -46,12 +46,16 @@ #define RBTX4927_INTF_PCIB (1 << RBTX4927_INTB_PCIB) #define RBTX4927_INTF_PCIA (1 << RBTX4927_INTB_PCIA) -#define RBTX4927_IRQ_IOC (TX4927_IRQ_PIC_BEG + TX4927_NUM_IR) +#define RBTX4927_NR_IRQ_IOC 8 /* IOC */ + +#define RBTX4927_IRQ_IOC (TXX9_IRQ_BASE + TX4927_NUM_IR) #define RBTX4927_IRQ_IOC_PCID (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCID) #define RBTX4927_IRQ_IOC_PCIC (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIC) #define RBTX4927_IRQ_IOC_PCIB (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIB) #define RBTX4927_IRQ_IOC_PCIA (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIA) +#define RBTX4927_IRQ_IOCINT (TXX9_IRQ_BASE + TX4927_IR_INT(1)) + #ifdef CONFIG_PCI #define RBTX4927_ISA_IO_OFFSET RBTX4927_PCIIO #else @@ -65,8 +69,11 @@ #define RBTX4927_SW_RESET_ENABLE_SET 0x01 #define RBTX4927_RTL_8019_BASE (0x1c020280 - RBTX4927_ISA_IO_OFFSET) -#define RBTX4927_RTL_8019_IRQ (TX4927_IRQ_PIC_BEG + 5) +#define RBTX4927_RTL_8019_IRQ (TXX9_IRQ_BASE + TX4927_IR_INT(3)) -int toshiba_rbtx4927_irq_nested(int sw_irq); +void rbtx4927_prom_init(void); +void rbtx4927_irq_setup(void); +struct pci_dev; +int rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); #endif /* __ASM_TXX9_RBTX4927_H */ diff --git a/include/asm-mips/txx9/rbtx4938.h b/include/asm-mips/txx9/rbtx4938.h index 8450f73..2f5d5e7 100644 --- a/include/asm-mips/txx9/rbtx4938.h +++ b/include/asm-mips/txx9/rbtx4938.h @@ -101,35 +101,12 @@ * that particular IRQ on an RBTX4938 machine. Add new 'spaces' as new * IRQ hardware is supported. */ -#define RBTX4938_NR_IRQ_LOCAL 8 -#define RBTX4938_NR_IRQ_IRC 32 /* On-Chip IRC */ #define RBTX4938_NR_IRQ_IOC 8 -#define TX4938_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE -#define TX4938_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) - -#define TX4938_IRQ_PIC_BEG TXX9_IRQ_BASE -#define TX4938_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) -#define TX4938_IRQ_NEST_EXT_ON_PIC (TX4938_IRQ_PIC_BEG+2) -#define TX4938_IRQ_NEST_PIC_ON_CP0 (TX4938_IRQ_CP0_BEG+2) -#define TX4938_IRQ_USER0 (TX4938_IRQ_CP0_BEG+0) -#define TX4938_IRQ_USER1 (TX4938_IRQ_CP0_BEG+1) -#define TX4938_IRQ_CPU_TIMER (TX4938_IRQ_CP0_BEG+7) - -#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG 0 -#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END 7 - -#define TOSHIBA_RBTX4938_IRQ_IOC_BEG ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */ -#define TOSHIBA_RBTX4938_IRQ_IOC_END ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */ -#define RBTX4938_IRQ_LOCAL TX4938_IRQ_CP0_BEG -#define RBTX4938_IRQ_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL) -#define RBTX4938_IRQ_IOC (RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC) +#define RBTX4938_IRQ_IRC TXX9_IRQ_BASE +#define RBTX4938_IRQ_IOC (TXX9_IRQ_BASE + TX4938_NUM_IR) #define RBTX4938_IRQ_END (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC) -#define RBTX4938_IRQ_LOCAL_SOFT0 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0) -#define RBTX4938_IRQ_LOCAL_SOFT1 (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1) -#define RBTX4938_IRQ_LOCAL_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT) -#define RBTX4938_IRQ_LOCAL_TIMER (RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT) #define RBTX4938_IRQ_IRC_ECCERR (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR) #define RBTX4938_IRQ_IRC_WTOERR (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR) #define RBTX4938_IRQ_IRC_INT(n) (RBTX4938_IRQ_IRC + TX4938_IR_INT(n)) @@ -157,11 +134,16 @@ /* IOC (PCI, etc) */ -#define RBTX4938_IRQ_IOCINT (TX4938_IRQ_NEST_EXT_ON_PIC) +#define RBTX4938_IRQ_IOCINT (TXX9_IRQ_BASE + TX4938_IR_INT(0)) /* Onboard 10M Ether */ -#define RBTX4938_IRQ_ETHER (TX4938_IRQ_NEST_EXT_ON_PIC + 1) +#define RBTX4938_IRQ_ETHER (TXX9_IRQ_BASE + TX4938_IR_INT(1)) #define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base) #define RBTX4938_RTL_8019_IRQ (RBTX4938_IRQ_ETHER) +void rbtx4938_prom_init(void); +void rbtx4938_irq_setup(void); +struct pci_dev; +int rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); + #endif /* __ASM_TXX9_RBTX4938_H */ diff --git a/include/asm-mips/txx9/tx4927.h b/include/asm-mips/txx9/tx4927.h index c0382fd..46d60af 100644 --- a/include/asm-mips/txx9/tx4927.h +++ b/include/asm-mips/txx9/tx4927.h @@ -32,20 +32,6 @@ #include #include -#define TX4927_IRQ_CP0_BEG MIPS_CPU_IRQ_BASE -#define TX4927_IRQ_CP0_END (MIPS_CPU_IRQ_BASE + 8 - 1) - -#define TX4927_IRQ_PIC_BEG TXX9_IRQ_BASE -#define TX4927_IRQ_PIC_END (TXX9_IRQ_BASE + TXx9_MAX_IR - 1) - - -#define TX4927_IRQ_USER0 (TX4927_IRQ_CP0_BEG+0) -#define TX4927_IRQ_USER1 (TX4927_IRQ_CP0_BEG+1) -#define TX4927_IRQ_NEST_PIC_ON_CP0 (TX4927_IRQ_CP0_BEG+2) -#define TX4927_IRQ_CPU_TIMER (TX4927_IRQ_CP0_BEG+7) - -#define TX4927_IRQ_NEST_EXT_ON_PIC (TX4927_IRQ_PIC_BEG+3) - #define TX4927_SDRAMC_REG 0xff1f8000 #define TX4927_EBUSC_REG 0xff1f9000 #define TX4927_PCIC_REG 0xff1fd000 @@ -54,10 +40,14 @@ #define TX4927_NR_TMR 3 #define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100) +#define TX4927_IR_INT(n) (2 + (n)) +#define TX4927_IR_SIO(n) (8 + (n)) #define TX4927_IR_PCIC 16 #define TX4927_IR_PCIERR 22 #define TX4927_NUM_IR 32 +#define TX4927_IRC_INT 2 /* IP[2] in Status register */ + struct tx4927_sdramc_reg { volatile unsigned long long cr[4]; volatile unsigned long long unused0[4]; @@ -224,5 +214,6 @@ static inline void tx4927_ccfg_change(__u64 change, __u64 new) int tx4927_report_pciclk(void); int tx4927_pciclk66_setup(void); +void tx4927_irq_init(void); #endif /* __ASM_TXX9_TX4927_H */ diff --git a/include/asm-mips/txx9/tx4938.h b/include/asm-mips/txx9/tx4938.h index 0bb8919..12de68a 100644 --- a/include/asm-mips/txx9/tx4938.h +++ b/include/asm-mips/txx9/tx4938.h @@ -18,11 +18,6 @@ #define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr)) #define tx4938_write_nfmc(b, addr) (*(volatile unsigned int *)(addr)) = (b) -#define TX4938_NR_IRQ_LOCAL TX4938_IRQ_PIC_BEG - -#define TX4938_IRQ_IRC_PCIC (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC) -#define TX4938_IRQ_IRC_PCIERR (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR) - #define TX4938_PCIIO_0 0x10000000 #define TX4938_PCIIO_1 0x01010000 #define TX4938_PCIMEM_0 0x08000000 @@ -271,6 +266,8 @@ struct tx4938_ccfg_reg { #define TX4938_IR_ETH0 TX4938_IR_INT(4) #define TX4938_IR_ETH1 TX4938_IR_INT(3) +#define TX4938_IRC_INT 2 /* IP[2] in Status register */ + /* * CCFG */ @@ -463,5 +460,6 @@ void tx4938_report_pci1clk(void); int tx4938_pciclk66_setup(void); struct pci_dev; int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot); +void tx4938_irq_init(void); #endif -- cgit v0.10.2 From bf744d417ff2fe1e8e386c7ad06e79c34a078642 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 11 Jul 2008 23:28:04 +0900 Subject: [MIPS] TXx9: Update and merge defconfigs Merge rbhma4200(RBTX4927/37) and rbhma4500(RBTX4938) defconfig into single rbtx49xx defconfig. And jmr3927 defconfig is also updated. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index ab16e67..9d5bd2a 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.26-rc9 -# Fri Jul 11 00:25:19 2008 +# Fri Jul 11 23:01:36 2008 # CONFIG_MIPS=y @@ -37,10 +37,11 @@ CONFIG_MIPS=y # CONFIG_SIBYTE_SENTOSA is not set # CONFIG_SIBYTE_BIGSUR is not set # CONFIG_SNI_RM is not set -CONFIG_TOSHIBA_JMR3927=y -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_MACH_TX39XX=y +# CONFIG_MACH_TX49XX is not set # CONFIG_WR_PPMC is not set +CONFIG_TOSHIBA_JMR3927=y +CONFIG_SOC_TX3927=y # CONFIG_TOSHIBA_FPCIB0 is not set CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -67,7 +68,6 @@ CONFIG_CPU_BIG_ENDIAN=y CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y CONFIG_IRQ_TXX9=y -CONFIG_MIPS_TX3927=y CONFIG_SWAP_IO_SPACE=y CONFIG_MIPS_L1_CACHE_SHIFT=5 diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig deleted file mode 100644 index e0af6a9..0000000 --- a/arch/mips/configs/rbhma4200_defconfig +++ /dev/null @@ -1,698 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc9 -# Thu Jul 10 23:52:40 2008 -# -CONFIG_MIPS=y - -# -# Machine selection -# -# CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_BCM47XX is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP28 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -CONFIG_TOSHIBA_RBTX4927=y -# CONFIG_TOSHIBA_RBTX4938 is not set -# CONFIG_WR_PPMC is not set -# CONFIG_TOSHIBA_FPCIB0 is not set -CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y -CONFIG_PCI_TX4927=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_SUPPORTS_OPROFILE=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_CEVT_R4K=y -CONFIG_CEVT_TXX9=y -CONFIG_CSRC_R4K=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_NO_IOPORT is not set -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_IRQ_TXX9=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_LOONGSON2 is not set -# 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=y -# CONFIG_CPU_R5000 is not set -# 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_TX49XX=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_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_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC 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_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_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_SECCOMP is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -# CONFIG_EXPERIMENTAL is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=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=14 -# 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=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -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 -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -# CONFIG_PCSPKR_PLATFORM is not set -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y -# CONFIG_EPOLL is not set -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=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_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 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 - -# -# 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 - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set -CONFIG_MMU=y - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# 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=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# 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_SYN_COOKIES is not set -# 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 is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# 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_IPV6 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 -# CONFIG_NET_SCHED 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 - -# -# 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 - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -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_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# A new 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 -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=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_DM9000 is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NE2000=y -# 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_NET_PCI is not set -# CONFIG_B44 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 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 -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_TXX9=y -CONFIG_HAS_TXX9_SERIAL=y -CONFIG_SERIAL_TXX9_NR_UARTS=6 -CONFIG_SERIAL_TXX9_CONSOLE=y -CONFIG_SERIAL_TXX9_STDSERIAL=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -CONFIG_DEVPORT=y -# CONFIG_I2C is not set -# CONFIG_SPI 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=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_TXX9_WDT=y - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 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_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 - -# -# 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 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 - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_DNOTIFY is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# 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_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS 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_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# 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 is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" -CONFIG_SYS_SUPPORTS_KGDB=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig deleted file mode 100644 index 50aa1b6..0000000 --- a/arch/mips/configs/rbhma4500_defconfig +++ /dev/null @@ -1,763 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc9 -# Thu Jul 10 23:53:27 2008 -# -CONFIG_MIPS=y - -# -# Machine selection -# -# CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_BCM47XX is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP28 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -CONFIG_TOSHIBA_RBTX4938=y -# CONFIG_WR_PPMC is not set -# CONFIG_TOSHIBA_FPCIB0 is not set -CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y - -# -# Multiplex Pin Select -# -CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y -# CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set -# CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set -CONFIG_PCI_TX4927=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_SUPPORTS_OPROFILE=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_CEVT_R4K=y -CONFIG_CEVT_TXX9=y -CONFIG_CSRC_R4K=y -CONFIG_GPIO_TXX9=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_GPIO=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_IRQ_TXX9=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_LOONGSON2 is not set -# 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=y -# CONFIG_CPU_R5000 is not set -# 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_TX49XX=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_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC 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_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_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_SECCOMP is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -# CONFIG_EXPERIMENTAL is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=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=14 -# 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=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -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 -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -# CONFIG_PCSPKR_PLATFORM is not set -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y -# CONFIG_EPOLL is not set -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=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_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 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 - -# -# 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 - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCI_LEGACY is not set -CONFIG_MMU=y - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# 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=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# 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_SYN_COOKIES is not set -# 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 is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# 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_IPV6 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 -# CONFIG_NET_SCHED 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 - -# -# 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 - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -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_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# A new 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 -# CONFIG_TUN is not set -# CONFIG_VETH 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_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=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_DM9000 is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NE2000=y -# 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_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_TC35815=y -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139TOO is not set -# CONFIG_R6040 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_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 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 -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT 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_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_TXX9=y -CONFIG_HAS_TXX9_SERIAL=y -CONFIG_SERIAL_TXX9_NR_UARTS=6 -CONFIG_SERIAL_TXX9_CONSOLE=y -CONFIG_SERIAL_TXX9_STDSERIAL=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -CONFIG_DEVPORT=y -# CONFIG_I2C is not set -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_TXX9=y - -# -# SPI Protocol Masters -# -CONFIG_SPI_AT25=y -# CONFIG_SPI_TLE62X0 is not set -CONFIG_HAVE_GPIO_LIB=y - -# -# GPIO Support -# - -# -# I2C GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MCP23S08 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=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_TXX9_WDT=m - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 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_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 - -# -# 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 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 - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -CONFIG_RTC_INTF_DEV_UIE_EMUL=y -# CONFIG_RTC_DRV_TEST is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -CONFIG_RTC_DRV_RS5C348=y - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_DNOTIFY is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# 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_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS 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_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# 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 is not set -# CONFIG_SAMPLES is not set -CONFIG_CMDLINE="" -CONFIG_SYS_SUPPORTS_KGDB=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig new file mode 100644 index 0000000..e42aed5 --- /dev/null +++ b/arch/mips/configs/rbtx49xx_defconfig @@ -0,0 +1,767 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc9 +# Fri Jul 11 23:03:21 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +CONFIG_MACH_TX49XX=y +# CONFIG_WR_PPMC is not set +CONFIG_TOSHIBA_RBTX4927=y +CONFIG_TOSHIBA_RBTX4938=y +CONFIG_SOC_TX4927=y +CONFIG_SOC_TX4938=y +# CONFIG_TOSHIBA_FPCIB0 is not set +CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y + +# +# Multiplex Pin Select +# +CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y +# CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set +# CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set +CONFIG_PCI_TX4927=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_TXX9=y +CONFIG_CSRC_R4K=y +CONFIG_GPIO_TXX9=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=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_IRQ_TXX9=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +# 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=y +# CONFIG_CPU_R5000 is not set +# 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_TX49XX=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_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_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC 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_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_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=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=14 +# 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=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +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 +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y +# CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=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_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 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 + +# +# 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 + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_LEGACY is not set +CONFIG_MMU=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# 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=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# 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_SYN_COOKIES is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# 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_IPV6 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 +# CONFIG_NET_SCHED 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 + +# +# 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 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +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_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# A new 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 +# CONFIG_TUN is not set +# CONFIG_VETH 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_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=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_DM9000 is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NE2000=y +# 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_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_TC35815=y +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139TOO is not set +# CONFIG_R6040 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_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 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 +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT 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_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_TXX9=y +CONFIG_HAS_TXX9_SERIAL=y +CONFIG_SERIAL_TXX9_NR_UARTS=6 +CONFIG_SERIAL_TXX9_CONSOLE=y +CONFIG_SERIAL_TXX9_STDSERIAL=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_TXX9=y + +# +# SPI Protocol Masters +# +CONFIG_SPI_AT25=y +# CONFIG_SPI_TLE62X0 is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MCP23S08 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=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_TXX9_WDT=m + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 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_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 + +# +# 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 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 + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +CONFIG_RTC_DRV_RS5C348=y + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# 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_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS 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_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# 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 is not set +# CONFIG_SAMPLES is not set +CONFIG_CMDLINE="" +CONFIG_SYS_SUPPORTS_KGDB=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- cgit v0.10.2 From 5b438c44082d9f09fed10f3621fe8d5c93d3676d Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 10 Jul 2008 20:29:55 +0200 Subject: [MIPS] IP22/28: Add platform devices for HAL2 Create platform devices for hal2 and add option for selecting HAL2 alsa driver. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 72baa1a..d23204e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -385,6 +385,8 @@ config SGI_IP28 select SGI_HAS_DS1286 select SGI_HAS_I8042 select SGI_HAS_INDYDOG + select SGI_HAS_HAL2 + select SGI_HAS_HAL2 select SGI_HAS_SEEQ select SGI_HAS_WD93 select SGI_HAS_ZILOG @@ -868,6 +870,9 @@ config SGI_HAS_DS1286 config SGI_HAS_INDYDOG bool +config SGI_HAS_HAL2 + bool + config SGI_HAS_SEEQ bool diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c index 28ffec8..d93d07a 100644 --- a/arch/mips/sgi-ip22/ip22-platform.c +++ b/arch/mips/sgi-ip22/ip22-platform.c @@ -175,3 +175,10 @@ static int __init sgiseeq_devinit(void) } device_initcall(sgiseeq_devinit); + +static int __init sgi_hal2_devinit(void) +{ + return IS_ERR(platform_device_register_simple("sgihal2", 0, NULL, 0)); +} + +device_initcall(sgi_hal2_devinit); -- cgit v0.10.2 From 9ecb1ff1b295a515b21d0ac83d8bd39b07335aab Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:39:14 +0900 Subject: [MIPS] replace inline assembler to cpu_wait() Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/gt64120/wrppmc/reset.c index c355cff..e66c871 100644 --- a/arch/mips/gt64120/wrppmc/reset.c +++ b/arch/mips/gt64120/wrppmc/reset.c @@ -5,10 +5,12 @@ * * Copyright (C) 1997 Ralf Baechle */ +#include #include #include #include +#include void wrppmc_machine_restart(char *command) { @@ -32,11 +34,8 @@ void wrppmc_machine_halt(void) printk(KERN_NOTICE "You can safely turn off the power\n"); while (1) { - __asm__( - ".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0" - ); + if (cpu_wait) + cpu_wait(); } } -- cgit v0.10.2 From 3f16654f36723f5ef1ca38c4e2078ca377a0f86f Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:39:18 +0900 Subject: [MIPS] remove wrppmc_machine_power_off() It can be replace wrppmc_machine_halt(). Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/gt64120/wrppmc/reset.c index e66c871..cc5474b 100644 --- a/arch/mips/gt64120/wrppmc/reset.c +++ b/arch/mips/gt64120/wrppmc/reset.c @@ -38,8 +38,3 @@ void wrppmc_machine_halt(void) cpu_wait(); } } - -void wrppmc_machine_power_off(void) -{ - wrppmc_machine_halt(); -} diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c index 728ef6a..ca65c84 100644 --- a/arch/mips/gt64120/wrppmc/setup.c +++ b/arch/mips/gt64120/wrppmc/setup.c @@ -98,11 +98,10 @@ void __init plat_mem_setup(void) { extern void wrppmc_machine_restart(char *command); extern void wrppmc_machine_halt(void); - extern void wrppmc_machine_power_off(void); _machine_restart = wrppmc_machine_restart; _machine_halt = wrppmc_machine_halt; - pm_power_off = wrppmc_machine_power_off; + pm_power_off = wrppmc_machine_halt; /* This makes the operations of 'in/out[bwl]' to the * physical address ( < KSEG0) can work via KSEG1 -- cgit v0.10.2 From efff4ae259b8f750ea426d3084007f85c0a15a85 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:45:21 +0900 Subject: [MIPS] cmbvr4133: Remove support It cannot be built for a long time and nobody maintains it. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index d319cd6..c4a3098 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -355,12 +355,6 @@ core-$(CONFIG_MACH_VR41XX) += arch/mips/vr41xx/common/ cflags-$(CONFIG_MACH_VR41XX) += -Iinclude/asm-mips/mach-vr41xx # -# NEC VR4133 -# -core-$(CONFIG_NEC_CMBVR4133) += arch/mips/vr41xx/nec-cmbvr4133/ -load-$(CONFIG_NEC_CMBVR4133) += 0xffffffff80100000 - -# # ZAO Networks Capcella (VR4131) # load-$(CONFIG_ZAO_CAPCELLA) += 0xffffffff80000000 diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 875b643..57e34ca 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_SOC_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o -obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c deleted file mode 100644 index 34e651b..0000000 --- a/arch/mips/pci/fixup-vr4133.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * arch/mips/pci/fixup-vr4133.c - * - * The NEC CMB-VR4133 Board specific PCI fixups. - * - * Author: Yoichi Yuasa and - * Alex Sapkov - * - * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Modified for support in 2.6 - * Author: Manish Lachwani (mlachwani@mvista.com) - * - */ -#include -#include -#include - -#include -#include -#include - -extern int vr4133_rockhopper; -extern void ali_m1535plus_init(struct pci_dev *dev); -extern void ali_m5229_init(struct pci_dev *dev); - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - /* - * We have to reset AMD PCnet adapter on Rockhopper since - * PMON leaves it enabled and generating interrupts. This leads - * to a lock if some PCI device driver later enables the IRQ line - * shared with PCnet and there is no AMD PCnet driver to catch its - * interrupts. - */ -#ifdef CONFIG_ROCKHOPPER - if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_LANCE) { - inl(pci_resource_start(dev, 0) + 0x18); - } -#endif - - /* - * we have to open the bridges' windows down to 0 because otherwise - * we cannot access ISA south bridge I/O registers that get mapped from - * 0. for example, 8259 PIC would be unaccessible without that - */ - if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) { - pci_write_config_byte(dev, PCI_IO_BASE, 0); - if(dev->bus->number == 0) { - pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0); - } else { - pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1); - } - } - - return 0; -} - -/* - * M1535 IRQ mapping - * Feel free to change this, although it shouldn't be needed - */ -#define M1535_IRQ_INTA 7 -#define M1535_IRQ_INTB 9 -#define M1535_IRQ_INTC 10 -#define M1535_IRQ_INTD 11 - -#define M1535_IRQ_USB 9 -#define M1535_IRQ_IDE 14 -#define M1535_IRQ_IDE2 15 -#define M1535_IRQ_PS2 12 -#define M1535_IRQ_RTC 8 -#define M1535_IRQ_FDC 6 -#define M1535_IRQ_AUDIO 5 -#define M1535_IRQ_COM1 4 -#define M1535_IRQ_COM2 4 -#define M1535_IRQ_IRDA 3 -#define M1535_IRQ_KBD 1 -#define M1535_IRQ_TMR 0 - -/* Rockhopper "slots" assignment; this is hard-coded ... */ -#define ROCKHOPPER_M5451_SLOT 1 -#define ROCKHOPPER_M1535_SLOT 2 -#define ROCKHOPPER_M5229_SLOT 11 -#define ROCKHOPPER_M5237_SLOT 15 -#define ROCKHOPPER_PMU_SLOT 12 -/* ... and hard-wired. */ -#define ROCKHOPPER_PCI1_SLOT 3 -#define ROCKHOPPER_PCI2_SLOT 4 -#define ROCKHOPPER_PCI3_SLOT 5 -#define ROCKHOPPER_PCI4_SLOT 6 -#define ROCKHOPPER_PCNET_SLOT 1 - -#define M1535_IRQ_MASK(n) (1 << (n)) - -#define M1535_IRQ_EDGE (M1535_IRQ_MASK(M1535_IRQ_TMR) | \ - M1535_IRQ_MASK(M1535_IRQ_KBD) | \ - M1535_IRQ_MASK(M1535_IRQ_COM1) | \ - M1535_IRQ_MASK(M1535_IRQ_COM2) | \ - M1535_IRQ_MASK(M1535_IRQ_IRDA) | \ - M1535_IRQ_MASK(M1535_IRQ_RTC) | \ - M1535_IRQ_MASK(M1535_IRQ_FDC) | \ - M1535_IRQ_MASK(M1535_IRQ_PS2)) - -#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE) | \ - M1535_IRQ_MASK(M1535_IRQ_USB) | \ - M1535_IRQ_MASK(M1535_IRQ_INTA) | \ - M1535_IRQ_MASK(M1535_IRQ_INTB) | \ - M1535_IRQ_MASK(M1535_IRQ_INTC) | \ - M1535_IRQ_MASK(M1535_IRQ_INTD)) - -struct irq_map_entry { - u16 bus; - u8 slot; - u8 irq; -}; -static struct irq_map_entry int_map[] = { - {1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO}, /* Audio controller */ - {1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD}, /* PCI slot #1 */ - {1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC}, /* PCI slot #2 */ - {1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB}, /* USB host controller */ - {1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ}, /* IDE controller */ - {2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD}, /* AMD Am79c973 on-board - ethernet */ - {2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB}, /* PCI slot #3 */ - {2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC} /* PCI slot #4 */ -}; - -static int pci_intlines[] = - { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD }; - -/* Determine the Rockhopper IRQ line number for the PCI device */ -int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot) -{ - struct pci_bus *bus; - int i; - - bus = dev->bus; - if (bus == NULL) - return -1; - - for (i = 0; i < ARRAY_SIZE(int_map); i++) { - if (int_map[i].bus == bus->number && int_map[i].slot == slot) { - int line; - for (line = 0; line < 4; line++) - if (pci_intlines[line] == int_map[i].irq) - break; - if (line < 4) - return pci_intlines[(line + (pin - 1)) % 4]; - else - return int_map[i].irq; - } - } - return -1; -} - -#ifdef CONFIG_ROCKHOPPER -void i8259_init(void) -{ - init_i8259_irqs(); - - outb(0x00, 0x4d0); - outb(0x02, 0x4d1); /* USB IRQ9 is level */ -} -#endif - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - pci_probe_only = 1; - -#ifdef CONFIG_ROCKHOPPER - if( dev->bus->number == 1 && vr4133_rockhopper ) { - if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT) - dev->irq = CMBVR41XX_INTA_IRQ; - else - dev->irq = rockhopper_get_irq(dev, pin, slot); - } else - dev->irq = CMBVR41XX_INTA_IRQ; -#else - dev->irq = CMBVR41XX_INTA_IRQ; -#endif - - return dev->irq; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init); - - diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index 559acc0..c1be6b3 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig @@ -23,16 +23,6 @@ config IBM_WORKPAD select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN -config NEC_CMBVR4133 - bool "NEC CMB-VR4133" - select CEVT_R4K - select CSRC_R4K - select DMA_NONCOHERENT - select IRQ_CPU - select HW_HAS_PCI - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - config TANBAC_TB022X bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM" select CEVT_R4K @@ -73,13 +63,6 @@ config ZAO_CAPCELLA endchoice -config ROCKHOPPER - bool "Support for Rockhopper base board" - depends on NEC_CMBVR4133 - select PCI_VR41XX - select I8259 - select HAVE_STD_PC_SERIAL_PORT - choice prompt "Base board type" depends on TANBAC_TB022X diff --git a/arch/mips/vr41xx/nec-cmbvr4133/Makefile b/arch/mips/vr41xx/nec-cmbvr4133/Makefile deleted file mode 100644 index 5835cae..0000000 --- a/arch/mips/vr41xx/nec-cmbvr4133/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the NEC-CMBVR4133 -# - -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += m1535plus.o -obj-$(CONFIG_ROCKHOPPER) += irq.o diff --git a/arch/mips/vr41xx/nec-cmbvr4133/init.c b/arch/mips/vr41xx/nec-cmbvr4133/init.c deleted file mode 100644 index 7c5e18e..0000000 --- a/arch/mips/vr41xx/nec-cmbvr4133/init.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * arch/mips/vr41xx/nec-cmbvr4133/init.c - * - * PROM library initialisation code for NEC CMB-VR4133 board. - * - * Author: Yoichi Yuasa and - * Jun Sun and - * Alex Sapkov - * - * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for NEC-CMBVR4133 in 2.6 - * Manish Lachwani (mlachwani@mvista.com) - */ - -#ifdef CONFIG_ROCKHOPPER -#include -#include - -#define PCICONFDREG 0xaf000c14 -#define PCICONFAREG 0xaf000c18 - -void disable_pcnet(void) -{ - u32 data; - - /* - * Workaround for the bug in PMON on VR4133. PMON leaves - * AMD PCNet controller (on Rockhopper) initialized and running in - * bus master mode. We have do disable it before doing any - * further initialization. Or we get problems with PCI bus 2 - * and random lockups and crashes. - */ - - writel((2 << 16) | - (PCI_DEVFN(1, 0) << 8) | - (0 & 0xfc) | - 1UL, - PCICONFAREG); - - data = readl(PCICONFDREG); - - writel((2 << 16) | - (PCI_DEVFN(1, 0) << 8) | - (4 & 0xfc) | - 1UL, - PCICONFAREG); - - data = readl(PCICONFDREG); - - writel((2 << 16) | - (PCI_DEVFN(1, 0) << 8) | - (4 & 0xfc) | - 1UL, - PCICONFAREG); - - data &= ~4; - - writel(data, PCICONFDREG); -} -#endif - diff --git a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c deleted file mode 100644 index 7d2d076..0000000 --- a/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * arch/mips/vr41xx/nec-cmbvr4133/irq.c - * - * Interrupt routines for the NEC CMB-VR4133 board. - * - * Author: Yoichi Yuasa and - * Alex Sapkov - * - * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for NEC-CMBVR4133 in 2.6 - * Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include - -#include -#include -#include - -extern int vr4133_rockhopper; - -static int i8259_get_irq_number(int irq) -{ - return i8259_irq(); -} - -void __init rockhopper_init_irq(void) -{ - int i; - - if(!vr4133_rockhopper) { - printk(KERN_ERR "Not a Rockhopper Board \n"); - return; - } - - vr41xx_set_irq_trigger(CMBVR41XX_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(CMBVR41XX_INTC_PIN, LEVEL_HIGH); - vr41xx_cascade_irq(CMBVR41XX_INTC_IRQ, i8259_get_irq_number); -} diff --git a/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c b/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c deleted file mode 100644 index 1341f32..0000000 --- a/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c - * - * Initialize for ALi M1535+(included M5229 and M5237). - * - * Author: Yoichi Yuasa and - * Alex Sapkov - * - * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for NEC-CMBVR4133 in 2.6 - * Author: Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include - -#include -#include -#include - -#define CONFIG_PORT(port) ((port) ? 0x3f0 : 0x370) -#define DATA_PORT(port) ((port) ? 0x3f1 : 0x371) -#define INDEX_PORT(port) CONFIG_PORT(port) - -#define ENTER_CONFIG_MODE(port) \ - do { \ - outb_p(0x51, CONFIG_PORT(port)); \ - outb_p(0x23, CONFIG_PORT(port)); \ - } while(0) - -#define SELECT_LOGICAL_DEVICE(port, dev_no) \ - do { \ - outb_p(0x07, INDEX_PORT(port)); \ - outb_p((dev_no), DATA_PORT(port)); \ - } while(0) - -#define WRITE_CONFIG_DATA(port, index, data) \ - do { \ - outb_p((index), INDEX_PORT(port)); \ - outb_p((data), DATA_PORT(port)); \ - } while(0) - -#define EXIT_CONFIG_MODE(port) outb(0xbb, CONFIG_PORT(port)) - -#define PCI_CONFIG_ADDR KSEG1ADDR(0x0f000c18) -#define PCI_CONFIG_DATA KSEG1ADDR(0x0f000c14) - -#ifdef CONFIG_BLK_DEV_FD - -void __devinit ali_m1535plus_fdc_init(int port) -{ - ENTER_CONFIG_MODE(port); - SELECT_LOGICAL_DEVICE(port, 0); /* FDC */ - WRITE_CONFIG_DATA(port, 0x30, 0x01); /* FDC: enable */ - WRITE_CONFIG_DATA(port, 0x60, 0x03); /* I/O port base: 0x3f0 */ - WRITE_CONFIG_DATA(port, 0x61, 0xf0); - WRITE_CONFIG_DATA(port, 0x70, 0x06); /* IRQ: 6 */ - WRITE_CONFIG_DATA(port, 0x74, 0x02); /* DMA: channel 2 */ - WRITE_CONFIG_DATA(port, 0xf0, 0x08); - WRITE_CONFIG_DATA(port, 0xf1, 0x00); - WRITE_CONFIG_DATA(port, 0xf2, 0xff); - WRITE_CONFIG_DATA(port, 0xf4, 0x00); - EXIT_CONFIG_MODE(port); -} - -#endif - -void __devinit ali_m1535plus_parport_init(int port) -{ - ENTER_CONFIG_MODE(port); - SELECT_LOGICAL_DEVICE(port, 3); /* Parallel Port */ - WRITE_CONFIG_DATA(port, 0x30, 0x01); - WRITE_CONFIG_DATA(port, 0x60, 0x03); /* I/O port base: 0x378 */ - WRITE_CONFIG_DATA(port, 0x61, 0x78); - WRITE_CONFIG_DATA(port, 0x70, 0x07); /* IRQ: 7 */ - WRITE_CONFIG_DATA(port, 0x74, 0x04); /* DMA: None */ - WRITE_CONFIG_DATA(port, 0xf0, 0x8c); /* IRQ polarity: Active Low */ - WRITE_CONFIG_DATA(port, 0xf1, 0xc5); - EXIT_CONFIG_MODE(port); -} - -void __devinit ali_m1535plus_keyboard_init(int port) -{ - ENTER_CONFIG_MODE(port); - SELECT_LOGICAL_DEVICE(port, 7); /* KEYBOARD */ - WRITE_CONFIG_DATA(port, 0x30, 0x01); /* KEYBOARD: eable */ - WRITE_CONFIG_DATA(port, 0x70, 0x01); /* IRQ: 1 */ - WRITE_CONFIG_DATA(port, 0x72, 0x0c); /* PS/2 Mouse IRQ: 12 */ - WRITE_CONFIG_DATA(port, 0xf0, 0x00); - EXIT_CONFIG_MODE(port); -} - -void __devinit ali_m1535plus_hotkey_init(int port) -{ - ENTER_CONFIG_MODE(port); - SELECT_LOGICAL_DEVICE(port, 0xc); /* HOTKEY */ - WRITE_CONFIG_DATA(port, 0x30, 0x00); - WRITE_CONFIG_DATA(port, 0xf0, 0x35); - WRITE_CONFIG_DATA(port, 0xf1, 0x14); - WRITE_CONFIG_DATA(port, 0xf2, 0x11); - WRITE_CONFIG_DATA(port, 0xf3, 0x71); - WRITE_CONFIG_DATA(port, 0xf5, 0x05); - EXIT_CONFIG_MODE(port); -} - -void ali_m1535plus_init(struct pci_dev *dev) -{ - pci_write_config_byte(dev, 0x40, 0x18); /* PCI Interface Control */ - pci_write_config_byte(dev, 0x41, 0xc0); /* PS2 keyb & mouse enable */ - pci_write_config_byte(dev, 0x42, 0x41); /* ISA bus cycle control */ - pci_write_config_byte(dev, 0x43, 0x00); /* ISA bus cycle control 2 */ - pci_write_config_byte(dev, 0x44, 0x5d); /* IDE enable & IRQ 14 */ - pci_write_config_byte(dev, 0x45, 0x0b); /* PCI int polling mode */ - pci_write_config_byte(dev, 0x47, 0x00); /* BIOS chip select control */ - - /* IRQ routing */ - pci_write_config_byte(dev, 0x48, 0x03); /* INTA IRQ10, INTB disable */ - pci_write_config_byte(dev, 0x49, 0x00); /* INTC and INTD disable */ - pci_write_config_byte(dev, 0x4a, 0x00); /* INTE and INTF disable */ - pci_write_config_byte(dev, 0x4b, 0x90); /* Audio IRQ11, Modem disable */ - - pci_write_config_word(dev, 0x50, 0x4000); /* Parity check IDE enable */ - pci_write_config_word(dev, 0x52, 0x0000); /* USB & RTC disable */ - pci_write_config_word(dev, 0x54, 0x0002); /* ??? no info */ - pci_write_config_word(dev, 0x56, 0x0002); /* PCS1J signal disable */ - - pci_write_config_byte(dev, 0x59, 0x00); /* PCSDS */ - pci_write_config_byte(dev, 0x5a, 0x00); - pci_write_config_byte(dev, 0x5b, 0x00); - pci_write_config_word(dev, 0x5c, 0x0000); - pci_write_config_byte(dev, 0x5e, 0x00); - pci_write_config_byte(dev, 0x5f, 0x00); - pci_write_config_word(dev, 0x60, 0x0000); - - pci_write_config_byte(dev, 0x6c, 0x00); - pci_write_config_byte(dev, 0x6d, 0x48); /* ROM address mapping */ - pci_write_config_byte(dev, 0x6e, 0x00); /* ??? what for? */ - - pci_write_config_byte(dev, 0x70, 0x12); /* Serial IRQ control */ - pci_write_config_byte(dev, 0x71, 0xEF); /* DMA channel select */ - pci_write_config_byte(dev, 0x72, 0x03); /* USB IDSEL */ - pci_write_config_byte(dev, 0x73, 0x00); /* ??? no info */ - - /* - * IRQ setup ALi M5237 USB Host Controller - * IRQ: 9 - */ - pci_write_config_byte(dev, 0x74, 0x01); /* USB IRQ9 */ - - pci_write_config_byte(dev, 0x75, 0x1f); /* IDE2 IRQ 15 */ - pci_write_config_byte(dev, 0x76, 0x80); /* ACPI disable */ - pci_write_config_byte(dev, 0x77, 0x40); /* Modem disable */ - pci_write_config_dword(dev, 0x78, 0x20000000); /* Pin select 2 */ - pci_write_config_byte(dev, 0x7c, 0x00); /* Pin select 3 */ - pci_write_config_byte(dev, 0x81, 0x00); /* ID read/write control */ - pci_write_config_byte(dev, 0x90, 0x00); /* PCI PM block control */ - pci_write_config_word(dev, 0xa4, 0x0000); /* PMSCR */ - -#ifdef CONFIG_BLK_DEV_FD - ali_m1535plus_fdc_init(1); -#endif - - ali_m1535plus_keyboard_init(1); - ali_m1535plus_hotkey_init(1); -} - -static inline void ali_config_writeb(u8 reg, u8 val, int devfn) -{ - u32 data; - int shift; - - writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR); - data = readl(PCI_CONFIG_DATA); - - shift = (reg & 3) << 3; - data &= ~(0xff << shift); - data |= (((u32)val) << shift); - - writel(data, PCI_CONFIG_DATA); -} - -static inline u8 ali_config_readb(u8 reg, int devfn) -{ - u32 data; - - writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR); - data = readl(PCI_CONFIG_DATA); - - return (u8)(data >> ((reg & 3) << 3)); -} - -static inline u16 ali_config_readw(u8 reg, int devfn) -{ - u32 data; - - writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR); - data = readl(PCI_CONFIG_DATA); - - return (u16)(data >> ((reg & 2) << 3)); -} - -int vr4133_rockhopper = 0; -void __init ali_m5229_preinit(void) -{ - if (ali_config_readw(PCI_VENDOR_ID, 16) == PCI_VENDOR_ID_AL && - ali_config_readw(PCI_DEVICE_ID, 16) == PCI_DEVICE_ID_AL_M1533) { - printk(KERN_INFO "Found an NEC Rockhopper \n"); - vr4133_rockhopper = 1; - /* - * Enable ALi M5229 IDE Controller (both channels) - * IDSEL: A27 - */ - ali_config_writeb(0x58, 0x4c, 16); - } -} - -void __init ali_m5229_init(struct pci_dev *dev) -{ - /* - * Enable Primary/Secondary Channel Cable Detect 40-Pin - */ - pci_write_config_word(dev, 0x4a, 0xc023); - - /* - * Set only the 3rd byteis for the master IDE's cycle and - * enable Internal IDE Function - */ - pci_write_config_byte(dev, 0x50, 0x23); /* Class code attr register */ - - pci_write_config_byte(dev, 0x09, 0xff); /* Set native mode & stuff */ - pci_write_config_byte(dev, 0x52, 0x00); /* use timing registers */ - pci_write_config_byte(dev, 0x58, 0x02); /* Primary addr setup timing */ - pci_write_config_byte(dev, 0x59, 0x22); /* Primary cmd block timing */ - pci_write_config_byte(dev, 0x5a, 0x22); /* Pr drv 0 R/W timing */ - pci_write_config_byte(dev, 0x5b, 0x22); /* Pr drv 1 R/W timing */ - pci_write_config_byte(dev, 0x5c, 0x02); /* Sec addr setup timing */ - pci_write_config_byte(dev, 0x5d, 0x22); /* Sec cmd block timing */ - pci_write_config_byte(dev, 0x5e, 0x22); /* Sec drv 0 R/W timing */ - pci_write_config_byte(dev, 0x5f, 0x22); /* Sec drv 1 R/W timing */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); - pci_write_config_word(dev, PCI_COMMAND, - PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | - PCI_COMMAND_IO); -} - diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c deleted file mode 100644 index 7723d20..0000000 --- a/arch/mips/vr41xx/nec-cmbvr4133/setup.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * arch/mips/vr41xx/nec-cmbvr4133/setup.c - * - * Setup for the NEC CMB-VR4133. - * - * Author: Yoichi Yuasa and - * Alex Sapkov - * - * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for CMBVR4133 board in 2.6 - * Author: Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include - -#include -#include -#include -#include - -#ifdef CONFIG_MTD -#include -#include -#include -#include - -static struct mtd_partition cmbvr4133_mtd_parts[] = { - { - .name = "User FS", - .size = 0x1be0000, - .offset = 0, - .mask_flags = 0, - }, - { - .name = "PMON", - .size = 0x140000, - .offset = MTDPART_OFS_APPEND, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, - { - .name = "User FS2", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - .mask_flags = 0, - } -}; - -#define number_partitions ARRAY_SIZE(cmbvr4133_mtd_parts) -#endif - -extern void i8259_init(void); - -static void __init nec_cmbvr4133_setup(void) -{ -#ifdef CONFIG_ROCKHOPPER - extern void disable_pcnet(void); - - disable_pcnet(); -#endif - set_io_port_base(KSEG1ADDR(0x16000000)); - -#ifdef CONFIG_PCI -#ifdef CONFIG_ROCKHOPPER - ali_m5229_preinit(); -#endif -#endif - -#ifdef CONFIG_ROCKHOPPER - rockhopper_init_irq(); -#endif - -#ifdef CONFIG_MTD - /* we use generic physmap mapping driver and we use partitions */ - physmap_configure(0x1C000000, 0x02000000, 4, NULL); - physmap_set_partitions(cmbvr4133_mtd_parts, number_partitions); -#endif - - /* 128 MB memory support */ - add_memory_region(0, 0x08000000, BOOT_MEM_RAM); - -#ifdef CONFIG_ROCKHOPPER - i8259_init(); -#endif -} diff --git a/include/asm-mips/mach-vr41xx/irq.h b/include/asm-mips/mach-vr41xx/irq.h index 8488122..862058d 100644 --- a/include/asm-mips/mach-vr41xx/irq.h +++ b/include/asm-mips/mach-vr41xx/irq.h @@ -2,9 +2,6 @@ #define __ASM_MACH_VR41XX_IRQ_H #include /* for MIPS_CPU_IRQ_BASE */ -#ifdef CONFIG_NEC_CMBVR4133 -#include /* for I8259A_IRQ_BASE */ -#endif #include_next diff --git a/include/asm-mips/vr41xx/cmbvr4133.h b/include/asm-mips/vr41xx/cmbvr4133.h deleted file mode 100644 index 4230003..0000000 --- a/include/asm-mips/vr41xx/cmbvr4133.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * include/asm-mips/vr41xx/cmbvr4133.h - * - * Include file for NEC CMB-VR4133. - * - * Author: Yoichi Yuasa and - * Jun Sun and - * Alex Sapkov - * - * 2002-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __NEC_CMBVR4133_H -#define __NEC_CMBVR4133_H - -#include - -/* - * General-Purpose I/O Pin Number - */ -#define CMBVR41XX_INTA_PIN 1 -#define CMBVR41XX_INTB_PIN 1 -#define CMBVR41XX_INTC_PIN 3 -#define CMBVR41XX_INTD_PIN 1 -#define CMBVR41XX_INTE_PIN 1 - -/* - * Interrupt Number - */ -#define CMBVR41XX_INTA_IRQ GIU_IRQ(CMBVR41XX_INTA_PIN) -#define CMBVR41XX_INTB_IRQ GIU_IRQ(CMBVR41XX_INTB_PIN) -#define CMBVR41XX_INTC_IRQ GIU_IRQ(CMBVR41XX_INTC_PIN) -#define CMBVR41XX_INTD_IRQ GIU_IRQ(CMBVR41XX_INTD_PIN) -#define CMBVR41XX_INTE_IRQ GIU_IRQ(CMBVR41XX_INTE_PIN) - -#define I8259A_IRQ_BASE 72 -#define I8259_IRQ(x) (I8259A_IRQ_BASE + (x)) -#define TIMER_IRQ I8259_IRQ(0) -#define KEYBOARD_IRQ I8259_IRQ(1) -#define I8259_SLAVE_IRQ I8259_IRQ(2) -#define UART3_IRQ I8259_IRQ(3) -#define UART1_IRQ I8259_IRQ(4) -#define UART2_IRQ I8259_IRQ(5) -#define FDC_IRQ I8259_IRQ(6) -#define PARPORT_IRQ I8259_IRQ(7) -#define RTC_IRQ I8259_IRQ(8) -#define USB_IRQ I8259_IRQ(9) -#define I8259_INTA_IRQ I8259_IRQ(10) -#define AUDIO_IRQ I8259_IRQ(11) -#define AUX_IRQ I8259_IRQ(12) -#define IDE_PRIMARY_IRQ I8259_IRQ(14) -#define IDE_SECONDARY_IRQ I8259_IRQ(15) - -#endif /* __NEC_CMBVR4133_H */ -- cgit v0.10.2 From b03d7b18fd783f39e31560d568e7db954f3080af Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Fri, 11 Jul 2008 23:03:03 +0200 Subject: [MIPS] IP22: Add platform device for Indy volume buttons Create platform device for Indy volume buttons and remove button handling from ip22-reset.c Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c index d93d07a..fc6df96 100644 --- a/arch/mips/sgi-ip22/ip22-platform.c +++ b/arch/mips/sgi-ip22/ip22-platform.c @@ -182,3 +182,14 @@ static int __init sgi_hal2_devinit(void) } device_initcall(sgi_hal2_devinit); + +static int __init sgi_button_devinit(void) +{ + if (ip22_is_fullhouse()) + return 0; /* full house has no volume buttons */ + + return IS_ERR(platform_device_register_simple("sgiindybtns", + -1, NULL, 0)); +} + +device_initcall(sgi_button_devinit); diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index a435b31..4ad5c33 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c @@ -39,7 +39,7 @@ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) -static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; +static struct timer_list power_timer, blink_timer, debounce_timer; #define MACHINE_PANICED 1 #define MACHINE_SHUTTING_DOWN 2 @@ -139,36 +139,6 @@ static inline void power_button(void) add_timer(&power_timer); } -void (*indy_volume_button)(int) = NULL; - -EXPORT_SYMBOL(indy_volume_button); - -static inline void volume_up_button(unsigned long data) -{ - del_timer(&volume_timer); - - if (indy_volume_button) - indy_volume_button(1); - - if (sgint->istat1 & SGINT_ISTAT1_PWR) { - volume_timer.expires = jiffies + (HZ / 100); - add_timer(&volume_timer); - } -} - -static inline void volume_down_button(unsigned long data) -{ - del_timer(&volume_timer); - - if (indy_volume_button) - indy_volume_button(-1); - - if (sgint->istat1 & SGINT_ISTAT1_PWR) { - volume_timer.expires = jiffies + (HZ / 100); - add_timer(&volume_timer); - } -} - static irqreturn_t panel_int(int irq, void *dev_id) { unsigned int buttons; @@ -190,25 +160,8 @@ static irqreturn_t panel_int(int irq, void *dev_id) * House. Only lowest 2 bits are used. Guiness uses upper four bits * for volume control". This is not true, all bits are pulled high * on fullhouse */ - if (ip22_is_fullhouse() || !(buttons & SGIOC_PANEL_POWERINTR)) { + if (!(buttons & SGIOC_PANEL_POWERINTR)) power_button(); - return IRQ_HANDLED; - } - /* TODO: mute/unmute */ - /* Volume up button was pressed */ - if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { - init_timer(&volume_timer); - volume_timer.function = volume_up_button; - volume_timer.expires = jiffies + (HZ / 100); - add_timer(&volume_timer); - } - /* Volume down button was pressed */ - if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { - init_timer(&volume_timer); - volume_timer.function = volume_down_button; - volume_timer.expires = jiffies + (HZ / 100); - add_timer(&volume_timer); - } return IRQ_HANDLED; } -- cgit v0.10.2 From 7a1fdf1946b641f7c2866b3386414657eeb88084 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 19:51:55 +0900 Subject: [MIPS] txx9_board_vec set directly without mips_machtype Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 66ff74f..517828e 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -99,19 +99,6 @@ extern struct txx9_board_vec rbtx4927_vec; extern struct txx9_board_vec rbtx4937_vec; extern struct txx9_board_vec rbtx4938_vec; -/* board definitions */ -static struct txx9_board_vec *board_vecs[] __initdata = { -#ifdef CONFIG_TOSHIBA_JMR3927 - &jmr3927_vec, -#endif -#ifdef CONFIG_TOSHIBA_RBTX4927 - &rbtx4927_vec, - &rbtx4937_vec, -#endif -#ifdef CONFIG_TOSHIBA_RBTX4938 - &rbtx4938_vec, -#endif -}; struct txx9_board_vec *txx9_board_vec __initdata; static char txx9_system_type[32]; @@ -134,31 +121,26 @@ void __init prom_init_cmdline(void) void __init prom_init(void) { - int i; - #ifdef CONFIG_CPU_TX39XX - mips_machtype = MACH_TOSHIBA_JMR3927; + txx9_board_vec = &jmr3927_vec; #endif #ifdef CONFIG_CPU_TX49XX switch (TX4938_REV_PCODE()) { case 0x4927: - mips_machtype = MACH_TOSHIBA_RBTX4927; + txx9_board_vec = &rbtx4927_vec; break; case 0x4937: - mips_machtype = MACH_TOSHIBA_RBTX4937; + txx9_board_vec = &rbtx4937_vec; break; case 0x4938: - mips_machtype = MACH_TOSHIBA_RBTX4938; + txx9_board_vec = &rbtx4938_vec; break; } #endif - for (i = 0; i < ARRAY_SIZE(board_vecs); i++) { - if (board_vecs[i]->type == mips_machtype) { - txx9_board_vec = board_vecs[i]; - strcpy(txx9_system_type, txx9_board_vec->system); - return txx9_board_vec->prom_init(); - } - } + + strcpy(txx9_system_type, txx9_board_vec->system); + + return txx9_board_vec->prom_init(); } void __init prom_free_prom_memory(void) -- cgit v0.10.2 From a00fb6694f15b3bccf105f34f10bbcb6b47af67c Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 19:54:08 +0900 Subject: [MIPS] txx9_cpu_clock setup move to rbtx4927_time_init() Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index c3566c3..bba6ef9 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -252,55 +252,6 @@ static void __init rbtx4927_mem_setup(void) set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); #endif - /* - * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. - * - * For TX4927: - * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1). - * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) - * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) - * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) - * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) - * i.e. S9[3]: ON (83MHz), OFF (100MHz) - * - * For TX4937: - * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1) - * PCIDIVMODE[10] is 0. - * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8) - * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4) - * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9) - * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5) - * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10) - * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) - * - */ - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) & - TX4938_CCFG_PCIDIVMODE_MASK) { - case TX4938_CCFG_PCIDIVMODE_8: - case TX4938_CCFG_PCIDIVMODE_4: - txx9_cpu_clock = 266666666; /* 266MHz */ - break; - case TX4938_CCFG_PCIDIVMODE_9: - case TX4938_CCFG_PCIDIVMODE_4_5: - txx9_cpu_clock = 300000000; /* 300MHz */ - break; - default: - txx9_cpu_clock = 333333333; /* 333MHz */ - } - else - switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) & - TX4927_CCFG_PCIDIVMODE_MASK) { - case TX4927_CCFG_PCIDIVMODE_2_5: - case TX4927_CCFG_PCIDIVMODE_5: - txx9_cpu_clock = 166666666; /* 166MHz */ - break; - default: - txx9_cpu_clock = 200000000; /* 200MHz */ - } - /* change default value to udelay/mdelay take reasonable time */ - loops_per_jiffy = txx9_cpu_clock / HZ / 2; - /* CCFG */ /* do reset on watchdog */ tx4927_ccfg_set(TX4927_CCFG_WR); @@ -349,6 +300,55 @@ static void __init rbtx4927_mem_setup(void) static void __init rbtx4927_time_init(void) { + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. + * + * For TX4927: + * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1). + * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) + * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) + * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) + * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) + * i.e. S9[3]: ON (83MHz), OFF (100MHz) + * + * For TX4937: + * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1) + * PCIDIVMODE[10] is 0. + * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8) + * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4) + * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9) + * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5) + * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10) + * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) + */ + if (mips_machtype == MACH_TOSHIBA_RBTX4937) + switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) & + TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + txx9_cpu_clock = 266666666; /* 266MHz */ + break; + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + txx9_cpu_clock = 300000000; /* 300MHz */ + break; + default: + txx9_cpu_clock = 333333333; /* 333MHz */ + } + else + switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) & + TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + txx9_cpu_clock = 166666666; /* 166MHz */ + break; + default: + txx9_cpu_clock = 200000000; /* 200MHz */ + } + + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; + mips_hpt_frequency = txx9_cpu_clock / 2; if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, -- cgit v0.10.2 From a38c47519832f22659244fd8437722b7aaa67f9a Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 20:01:04 +0900 Subject: [MIPS] separate rbtx4927_arch_init() and rbtx4937_arch_init() Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index bba6ef9..b4c4178 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -170,13 +170,16 @@ static void __init tx4937_pci_setup(void) static void __init rbtx4927_arch_init(void) { - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - tx4937_pci_setup(); - else - tx4927_pci_setup(); + tx4927_pci_setup(); +} + +static void __init rbtx4937_arch_init(void) +{ + tx4937_pci_setup(); } #else #define rbtx4927_arch_init NULL +#define rbtx4937_arch_init NULL #endif /* CONFIG_PCI */ static void __noreturn wait_forever(void) @@ -433,7 +436,7 @@ struct txx9_board_vec rbtx4937_vec __initdata = { .irq_setup = rbtx4927_irq_setup, .time_init = rbtx4927_time_init, .device_init = rbtx4927_device_init, - .arch_init = rbtx4927_arch_init, + .arch_init = rbtx4937_arch_init, #ifdef CONFIG_PCI .pci_map_irq = rbtx4927_pci_map_irq, #endif -- cgit v0.10.2 From b6c4053610f04011bc0ecbc5a0417afe169b2693 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 20:02:13 +0900 Subject: [MIPS] separate rbtx4927_time_init() and rbtx4937_time_init() Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index b4c4178..adc91c0 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -301,6 +301,18 @@ static void __init rbtx4927_mem_setup(void) #endif } +static void __init rbtx49x7_common_time_init(void) +{ + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; + + mips_hpt_frequency = txx9_cpu_clock / 2; + if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) + txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, + TXX9_IRQ_BASE + 17, + 50000000); +} + static void __init rbtx4927_time_init(void) { /* @@ -313,6 +325,24 @@ static void __init rbtx4927_time_init(void) * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) * i.e. S9[3]: ON (83MHz), OFF (100MHz) + */ + switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) & + TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + txx9_cpu_clock = 166666666; /* 166MHz */ + break; + default: + txx9_cpu_clock = 200000000; /* 200MHz */ + } + + rbtx49x7_common_time_init(); +} + +static void __init rbtx4937_time_init(void) +{ + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. * * For TX4937: * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1) @@ -324,39 +354,21 @@ static void __init rbtx4927_time_init(void) * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10) * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) */ - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) & - TX4938_CCFG_PCIDIVMODE_MASK) { - case TX4938_CCFG_PCIDIVMODE_8: - case TX4938_CCFG_PCIDIVMODE_4: - txx9_cpu_clock = 266666666; /* 266MHz */ - break; - case TX4938_CCFG_PCIDIVMODE_9: - case TX4938_CCFG_PCIDIVMODE_4_5: - txx9_cpu_clock = 300000000; /* 300MHz */ - break; - default: - txx9_cpu_clock = 333333333; /* 333MHz */ - } - else - switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) & - TX4927_CCFG_PCIDIVMODE_MASK) { - case TX4927_CCFG_PCIDIVMODE_2_5: - case TX4927_CCFG_PCIDIVMODE_5: - txx9_cpu_clock = 166666666; /* 166MHz */ - break; - default: - txx9_cpu_clock = 200000000; /* 200MHz */ - } - - /* change default value to udelay/mdelay take reasonable time */ - loops_per_jiffy = txx9_cpu_clock / HZ / 2; + switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) & + TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + txx9_cpu_clock = 266666666; /* 266MHz */ + break; + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + txx9_cpu_clock = 300000000; /* 300MHz */ + break; + default: + txx9_cpu_clock = 333333333; /* 333MHz */ + } - mips_hpt_frequency = txx9_cpu_clock / 2; - if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) - txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, - TXX9_IRQ_BASE + 17, - 50000000); + rbtx49x7_common_time_init(); } static int __init toshiba_rbtx4927_rtc_init(void) @@ -434,7 +446,7 @@ struct txx9_board_vec rbtx4937_vec __initdata = { .prom_init = rbtx4927_prom_init, .mem_setup = rbtx4927_mem_setup, .irq_setup = rbtx4927_irq_setup, - .time_init = rbtx4927_time_init, + .time_init = rbtx4937_time_init, .device_init = rbtx4927_device_init, .arch_init = rbtx4937_arch_init, #ifdef CONFIG_PCI -- cgit v0.10.2 From 6e68665e51b9937b132a990b9ae7f04118e64688 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 13 Jul 2008 20:04:18 +0900 Subject: [MIPS] remove machtype for group Toshiba Signed-off-by: Yoichi Yuasa Acked-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 128a4ae..43a8dad 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -366,7 +366,6 @@ static void __init jmr3927_device_init(void) } struct txx9_board_vec jmr3927_vec __initdata = { - .type = MACH_TOSHIBA_JMR3927, .system = "Toshiba JMR_TX3927", .prom_init = jmr3927_prom_init, .mem_setup = jmr3927_mem_setup, diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index adc91c0..aba11f3 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -428,7 +428,6 @@ static void __init rbtx4927_device_init(void) } struct txx9_board_vec rbtx4927_vec __initdata = { - .type = MACH_TOSHIBA_RBTX4927, .system = "Toshiba RBTX4927", .prom_init = rbtx4927_prom_init, .mem_setup = rbtx4927_mem_setup, @@ -441,7 +440,6 @@ struct txx9_board_vec rbtx4927_vec __initdata = { #endif }; struct txx9_board_vec rbtx4937_vec __initdata = { - .type = MACH_TOSHIBA_RBTX4937, .system = "Toshiba RBTX4937", .prom_init = rbtx4927_prom_init, .mem_setup = rbtx4927_mem_setup, diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 8306ba3..2ef71ad 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -619,7 +619,6 @@ static void __init rbtx4938_device_init(void) } struct txx9_board_vec rbtx4938_vec __initdata = { - .type = MACH_TOSHIBA_RBTX4938, .system = "Toshiba RBTX4938", .prom_init = rbtx4938_prom_init, .mem_setup = rbtx4938_mem_setup, diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index e031bdf..c70848d 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -62,17 +62,6 @@ #define MACH_SGI_IP30 4 /* Octane, Octane2 */ /* - * Valid machtypes for group Toshiba - */ -#define MACH_PALLAS 0 -#define MACH_TOPAS 1 -#define MACH_JMR 2 -#define MACH_TOSHIBA_JMR3927 3 /* JMR-TX3927 CPU/IO board */ -#define MACH_TOSHIBA_RBTX4927 4 -#define MACH_TOSHIBA_RBTX4937 5 -#define MACH_TOSHIBA_RBTX4938 6 - -/* * Valid machtype for group LASAT */ #define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 6cd1477..715d7c8 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -22,7 +22,6 @@ extern unsigned int txx9_gbus_clock; struct pci_dev; struct txx9_board_vec { - unsigned long type; const char *system; void (*prom_init)(void); void (*mem_setup)(void); -- cgit v0.10.2 From 4c642f3f5e9f3f1a2fcce2c3fa1a94bf80142202 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 13 Jul 2008 23:37:56 +0900 Subject: [MIPS] TXx9: rename asm-mips/mach-jmr3927 to asm-mips/mach-tx39xx Rename mach-jmr3927 directory to more proper name to make adding other platforms easier. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/Makefile b/arch/mips/Makefile index c4a3098..3564533 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -548,7 +548,7 @@ all-$(CONFIG_SNI_RM) := vmlinux.ecoff # Common TXx9 # core-$(CONFIG_MACH_TX39XX) += arch/mips/txx9/generic/ -cflags-$(CONFIG_MACH_TX39XX) += -Iinclude/asm-mips/mach-jmr3927 +cflags-$(CONFIG_MACH_TX39XX) += -Iinclude/asm-mips/mach-tx39xx load-$(CONFIG_MACH_TX39XX) += 0xffffffff80050000 core-$(CONFIG_MACH_TX49XX) += arch/mips/txx9/generic/ cflags-$(CONFIG_MACH_TX49XX) += -Iinclude/asm-mips/mach-tx49xx diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 517828e..452cb9e 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -200,3 +200,13 @@ asmlinkage void plat_irq_dispatch(void) else spurious_interrupt(); } + +/* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */ +#ifdef NEEDS_TXX9_SWIZZLE_ADDR_B +static unsigned long __swizzle_addr_none(unsigned long port) +{ + return port; +} +unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none; +EXPORT_SYMBOL(__swizzle_addr_b); +#endif diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 43a8dad..61edc4a 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -315,7 +315,7 @@ static void __init tx3927_setup(void) } /* This trick makes rtc-ds1742 driver usable as is. */ -unsigned long __swizzle_addr_b(unsigned long port) +static unsigned long jmr3927_swizzle_addr_b(unsigned long port) { if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR) return port; @@ -326,7 +326,6 @@ unsigned long __swizzle_addr_b(unsigned long port) return port | 1; #endif } -EXPORT_SYMBOL(__swizzle_addr_b); static int __init jmr3927_rtc_init(void) { @@ -361,6 +360,7 @@ static int __init jmr3927_wdt_init(void) static void __init jmr3927_device_init(void) { + __swizzle_addr_b = jmr3927_swizzle_addr_b; jmr3927_rtc_init(); jmr3927_wdt_init(); } diff --git a/include/asm-mips/mach-jmr3927/ioremap.h b/include/asm-mips/mach-jmr3927/ioremap.h deleted file mode 100644 index 29989ff..0000000 --- a/include/asm-mips/mach-jmr3927/ioremap.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * include/asm-mips/mach-jmr3927/ioremap.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. - */ -#ifndef __ASM_MACH_JMR3927_IOREMAP_H -#define __ASM_MACH_JMR3927_IOREMAP_H - -#include - -/* - * Allow physical addresses to be fixed up to help peripherals located - * outside the low 32-bit range -- generic pass-through version. - */ -static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) -{ - return phys_addr; -} - -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, - unsigned long flags) -{ -#define TXX9_DIRECTMAP_BASE 0xff000000ul - if (offset >= TXX9_DIRECTMAP_BASE && - offset < TXX9_DIRECTMAP_BASE + 0xff0000) - return (void __iomem *)offset; - return NULL; -} - -static inline int plat_iounmap(const volatile void __iomem *addr) -{ - return (unsigned long)addr >= TXX9_DIRECTMAP_BASE; -} - -#endif /* __ASM_MACH_JMR3927_IOREMAP_H */ diff --git a/include/asm-mips/mach-jmr3927/mangle-port.h b/include/asm-mips/mach-jmr3927/mangle-port.h deleted file mode 100644 index 11bffcd..0000000 --- a/include/asm-mips/mach-jmr3927/mangle-port.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __ASM_MACH_JMR3927_MANGLE_PORT_H -#define __ASM_MACH_JMR3927_MANGLE_PORT_H - -extern unsigned long __swizzle_addr_b(unsigned long port); -#define __swizzle_addr_w(port) (port) -#define __swizzle_addr_l(port) (port) -#define __swizzle_addr_q(port) (port) - -#define ioswabb(a, x) (x) -#define __mem_ioswabb(a, x) (x) -#define ioswabw(a, x) le16_to_cpu(x) -#define __mem_ioswabw(a, x) (x) -#define ioswabl(a, x) le32_to_cpu(x) -#define __mem_ioswabl(a, x) (x) -#define ioswabq(a, x) le64_to_cpu(x) -#define __mem_ioswabq(a, x) (x) - -#endif /* __ASM_MACH_JMR3927_MANGLE_PORT_H */ diff --git a/include/asm-mips/mach-jmr3927/war.h b/include/asm-mips/mach-jmr3927/war.h deleted file mode 100644 index 1ff55fb..0000000 --- a/include/asm-mips/mach-jmr3927/war.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle - */ -#ifndef __ASM_MIPS_MACH_JMR3927_WAR_H -#define __ASM_MIPS_MACH_JMR3927_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_JMR3927_WAR_H */ diff --git a/include/asm-mips/mach-tx39xx/ioremap.h b/include/asm-mips/mach-tx39xx/ioremap.h new file mode 100644 index 0000000..93c6c04 --- /dev/null +++ b/include/asm-mips/mach-tx39xx/ioremap.h @@ -0,0 +1,38 @@ +/* + * include/asm-mips/mach-tx39xx/ioremap.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. + */ +#ifndef __ASM_MACH_TX39XX_IOREMAP_H +#define __ASM_MACH_TX39XX_IOREMAP_H + +#include + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, + unsigned long flags) +{ +#define TXX9_DIRECTMAP_BASE 0xff000000ul + if (offset >= TXX9_DIRECTMAP_BASE && + offset < TXX9_DIRECTMAP_BASE + 0xff0000) + return (void __iomem *)offset; + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return (unsigned long)addr >= TXX9_DIRECTMAP_BASE; +} + +#endif /* __ASM_MACH_TX39XX_IOREMAP_H */ diff --git a/include/asm-mips/mach-tx39xx/mangle-port.h b/include/asm-mips/mach-tx39xx/mangle-port.h new file mode 100644 index 0000000..ef0b502 --- /dev/null +++ b/include/asm-mips/mach-tx39xx/mangle-port.h @@ -0,0 +1,23 @@ +#ifndef __ASM_MACH_TX39XX_MANGLE_PORT_H +#define __ASM_MACH_TX39XX_MANGLE_PORT_H + +#if defined(CONFIG_TOSHIBA_JMR3927) +extern unsigned long (*__swizzle_addr_b)(unsigned long port); +#define NEEDS_TXX9_SWIZZLE_ADDR_B +#else +#define __swizzle_addr_b(port) (port) +#endif +#define __swizzle_addr_w(port) (port) +#define __swizzle_addr_l(port) (port) +#define __swizzle_addr_q(port) (port) + +#define ioswabb(a, x) (x) +#define __mem_ioswabb(a, x) (x) +#define ioswabw(a, x) le16_to_cpu(x) +#define __mem_ioswabw(a, x) (x) +#define ioswabl(a, x) le32_to_cpu(x) +#define __mem_ioswabl(a, x) (x) +#define ioswabq(a, x) le64_to_cpu(x) +#define __mem_ioswabq(a, x) (x) + +#endif /* __ASM_MACH_TX39XX_MANGLE_PORT_H */ diff --git a/include/asm-mips/mach-tx39xx/war.h b/include/asm-mips/mach-tx39xx/war.h new file mode 100644 index 0000000..4338146 --- /dev/null +++ b/include/asm-mips/mach-tx39xx/war.h @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MACH_TX39XX_WAR_H +#define __ASM_MIPS_MACH_TX39XX_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_TX39XX_WAR_H */ -- cgit v0.10.2 From 7b22609442a32050e37cec5f6735376af61e68a1 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 14 Jul 2008 00:15:04 +0900 Subject: [MIPS] TXx9: cleanup and fix some sparse warnings * Do not return void value * Make some functions static * Do not include unnecessary bootinfo.h Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 452cb9e..5afc5d5 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -140,7 +140,7 @@ void __init prom_init(void) strcpy(txx9_system_type, txx9_board_vec->system); - return txx9_board_vec->prom_init(); + txx9_board_vec->prom_init(); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 61edc4a..5e35ef7 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -38,8 +38,6 @@ #ifdef CONFIG_SERIAL_TXX9 #include #endif - -#include #include #include #include @@ -95,7 +93,6 @@ static void __init jmr3927_time_init(void) #define DO_WRITE_THROUGH #define DO_ENABLE_CACHE -extern char * __init prom_getcmdline(void); static void jmr3927_board_init(void); static void __init jmr3927_mem_setup(void) diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index aba11f3..1657fd9 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -50,8 +50,6 @@ #include #include #include - -#include #include #include #include @@ -65,14 +63,6 @@ #include #endif -/* These functions are used for rebooting or halting the machine*/ -extern void toshiba_rbtx4927_restart(char *command); -extern void toshiba_rbtx4927_halt(void); -extern void toshiba_rbtx4927_power_off(void); -extern void toshiba_rbtx4927_irq_setup(void); - -char *prom_getcmdline(void); - static int tx4927_ccfg_toeon = 1; #ifdef CONFIG_PCI @@ -189,7 +179,7 @@ static void __noreturn wait_forever(void) (*cpu_wait)(); } -void toshiba_rbtx4927_restart(char *command) +static void toshiba_rbtx4927_restart(char *command) { printk(KERN_NOTICE "System Rebooting...\n"); @@ -209,7 +199,7 @@ void toshiba_rbtx4927_restart(char *command) /* no return */ } -void toshiba_rbtx4927_halt(void) +static void toshiba_rbtx4927_halt(void) { printk(KERN_NOTICE "System Halted\n"); local_irq_disable(); @@ -217,7 +207,7 @@ void toshiba_rbtx4927_halt(void) /* no return */ } -void toshiba_rbtx4927_power_off(void) +static void toshiba_rbtx4927_power_off(void) { toshiba_rbtx4927_halt(); /* no return */ diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 2ef71ad..aaa987a 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -34,15 +33,9 @@ #include #include -extern char * __init prom_getcmdline(void); -/* These functions are used for rebooting or halting the machine*/ -extern void rbtx4938_machine_restart(char *command); -extern void rbtx4938_machine_halt(void); -extern void rbtx4938_machine_power_off(void); - static int tx4938_ccfg_toeon = 1; -void rbtx4938_machine_halt(void) +static void rbtx4938_machine_halt(void) { printk(KERN_NOTICE "System Halted\n"); local_irq_disable(); @@ -53,13 +46,13 @@ void rbtx4938_machine_halt(void) ".set\tmips0"); } -void rbtx4938_machine_power_off(void) +static void rbtx4938_machine_power_off(void) { rbtx4938_machine_halt(); /* no return */ } -void rbtx4938_machine_restart(char *command) +static void rbtx4938_machine_restart(char *command) { local_irq_disable(); diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 715d7c8..d875666 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -36,5 +36,6 @@ struct txx9_board_vec { extern struct txx9_board_vec *txx9_board_vec; extern int (*txx9_irq_dispatch)(int pending); void prom_init_cmdline(void); +char *prom_getcmdline(void); #endif /* __ASM_TXX9_GENERIC_H */ -- cgit v0.10.2 From 9528356308ecd2fb6368472615996a8602c02964 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Fri, 11 Jul 2008 22:34:48 +0900 Subject: [MIPS] MTX-1 flash partition setup move to platform devices registration Signed-off-by: Yoichi Yuasa Acked-By: David Woodhouse Signed-off-by: Ralf Baechle diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c index 9807be3..8b5914d 100644 --- a/arch/mips/au1000/mtx-1/platform.c +++ b/arch/mips/au1000/mtx-1/platform.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include static struct gpio_keys_button mtx1_gpio_button[] = { { @@ -85,10 +88,56 @@ static struct platform_device mtx1_gpio_leds = { } }; +static struct mtd_partition mtx1_mtd_partitions[] = { + { + .name = "filesystem", + .size = 0x01C00000, + .offset = 0, + }, + { + .name = "yamon", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .size = 0x002c0000, + .offset = MTDPART_OFS_APPEND, + }, + { + .name = "yamon env", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + }, +}; + +static struct physmap_flash_data mtx1_flash_data = { + .width = 4, + .nr_parts = 4, + .parts = mtx1_mtd_partitions, +}; + +static struct resource mtx1_mtd_resource = { + .start = 0x1e000000, + .end = 0x1fffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device mtx1_mtd = { + .name = "physmap-flash", + .dev = { + .platform_data = &mtx1_flash_data, + }, + .num_resources = 1, + .resource = &mtx1_mtd_resource, +}; + static struct __initdata platform_device * mtx1_devs[] = { &mtx1_gpio_leds, &mtx1_wdt, - &mtx1_button + &mtx1_button, + &mtx1_mtd, }; static int __init mtx1_register_devices(void) diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 17bc87a..d2fbc29 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -258,13 +258,6 @@ config MTD_ALCHEMY help Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards -config MTD_MTX1 - tristate "4G Systems MTX-1 Flash device" - depends on MIPS_MTX1 && MTD_CFI - help - Flash memory access on 4G Systems MTX-1 Board. If you have one of - these boards and would like to use the flash chips on it, say 'Y'. - config MTD_DILNETPC tristate "CFI Flash device mapped on DIL/Net PC" depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 957fb5f..c6ce867 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -65,5 +65,4 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o -obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c deleted file mode 100644 index 2a8fde9..0000000 --- a/drivers/mtd/maps/mtx-1_flash.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Flash memory access on 4G Systems MTX-1 boards - * - * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $ - * - * (C) 2005 Bruno Randolf - * (C) 2005 Joern Engel - * - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include - -static struct map_info mtx1_map = { - .name = "MTX-1 flash", - .bankwidth = 4, - .size = 0x2000000, - .phys = 0x1E000000, -}; - -static struct mtd_partition mtx1_partitions[] = { - { - .name = "filesystem", - .size = 0x01C00000, - .offset = 0, - },{ - .name = "yamon", - .size = 0x00100000, - .offset = MTDPART_OFS_APPEND, - .mask_flags = MTD_WRITEABLE, - },{ - .name = "kernel", - .size = 0x002c0000, - .offset = MTDPART_OFS_APPEND, - },{ - .name = "yamon env", - .size = 0x00040000, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct mtd_info *mtx1_mtd; - -int __init mtx1_mtd_init(void) -{ - int ret = -ENXIO; - - simple_map_init(&mtx1_map); - - mtx1_map.virt = ioremap(mtx1_map.phys, mtx1_map.size); - if (!mtx1_map.virt) - return -EIO; - - mtx1_mtd = do_map_probe("cfi_probe", &mtx1_map); - if (!mtx1_mtd) - goto err; - - mtx1_mtd->owner = THIS_MODULE; - - ret = add_mtd_partitions(mtx1_mtd, mtx1_partitions, - ARRAY_SIZE(mtx1_partitions)); - if (ret) - goto err; - - return 0; - -err: - iounmap(mtx1_map.virt); - return ret; -} - -static void __exit mtx1_mtd_cleanup(void) -{ - if (mtx1_mtd) { - del_mtd_partitions(mtx1_mtd); - map_destroy(mtx1_mtd); - } - if (mtx1_map.virt) - iounmap(mtx1_map.virt); -} - -module_init(mtx1_mtd_init); -module_exit(mtx1_mtd_cleanup); - -MODULE_AUTHOR("Bruno Randolf "); -MODULE_DESCRIPTION("MTX-1 flash map"); -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From c660729501894e0b88054ad4b66a5f98a1a2a37e Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Jul 2008 15:11:40 +0200 Subject: [MIPS] Remove mips_machtype from ARC based machines This is the ARC part of the mips_machtype removal. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/fw/arc/identify.c b/arch/mips/fw/arc/identify.c index 2306698..0ce9acf 100644 --- a/arch/mips/fw/arc/identify.c +++ b/arch/mips/fw/arc/identify.c @@ -22,7 +22,6 @@ struct smatch { char *arcname; char *liname; - int type; int flags; }; @@ -30,47 +29,38 @@ static struct smatch mach_table[] = { { .arcname = "SGI-IP22", .liname = "SGI Indy", - .type = MACH_SGI_IP22, .flags = PROM_FLAG_ARCS, }, { .arcname = "SGI-IP27", .liname = "SGI Origin", - .type = MACH_SGI_IP27, .flags = PROM_FLAG_ARCS, }, { .arcname = "SGI-IP28", .liname = "SGI IP28", - .type = MACH_SGI_IP28, .flags = PROM_FLAG_ARCS, }, { .arcname = "SGI-IP30", .liname = "SGI Octane", - .type = MACH_SGI_IP30, .flags = PROM_FLAG_ARCS, }, { .arcname = "SGI-IP32", .liname = "SGI O2", - .type = MACH_SGI_IP32, .flags = PROM_FLAG_ARCS, }, { .arcname = "Microsoft-Jazz", .liname = "Jazz MIPS_Magnum_4000", - .type = MACH_MIPS_MAGNUM_4000, .flags = 0, }, { .arcname = "PICA-61", .liname = "Jazz Acer_PICA_61", - .type = MACH_ACER_PICA_61, .flags = 0, }, { .arcname = "RM200PCI", .liname = "SNI RM200_PCI", - .type = MACH_SNI_RM200_PCI, .flags = PROM_FLAG_DONT_FREE_TEMP, }, { .arcname = "RM200PCI-R5K", .liname = "SNI RM200_PCI-R5K", - .type = MACH_SNI_RM200_PCI, .flags = PROM_FLAG_DONT_FREE_TEMP, } }; @@ -121,6 +111,5 @@ void __init prom_identify_arch(void) mach = string_to_mach(iname); system_type = mach->liname; - mips_machtype = mach->type; prom_flags = mach->flags; } diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index f136c8a..f60524e 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -76,8 +76,7 @@ void __init plat_mem_setup(void) set_io_port_base(JAZZ_PORT_BASE); #ifdef CONFIG_EISA - if (mips_machtype == MACH_MIPS_MAGNUM_4000) - EISA_bus = 1; + EISA_bus = 1; #endif /* request I/O space for devices used on all i[345]86 PCs */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index c70848d..653096a 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -26,13 +26,6 @@ #define MACH_UNKNOWN 0 /* whatever... */ /* - * Valid machtype values for group JAZZ - */ -#define MACH_ACER_PICA_61 0 /* Acer PICA-61 (PICA1) */ -#define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ -#define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ - -/* * Valid machtype for group DEC */ #define MACH_DSUNKNOWN 0 @@ -48,20 +41,6 @@ #define MACH_DS5900 10 /* DECsystem 5900 */ /* - * Valid machtype for group SNI_RM - */ -#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ - -/* - * Valid machtype for group SGI - */ -#define MACH_SGI_IP22 0 /* Indy, Indigo2, Challenge S */ -#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */ -#define MACH_SGI_IP28 2 /* Indigo2 Impact */ -#define MACH_SGI_IP32 3 /* O2 */ -#define MACH_SGI_IP30 4 /* Octane, Octane2 */ - -/* * Valid machtype for group LASAT */ #define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ -- cgit v0.10.2 From 0b56fd8c7abbf85baeecb77be25c54d3c7d11587 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Jul 2008 15:54:30 +0200 Subject: [MIPS] Remove mips_machtype from EMMA2RH machines This is the EMMA2RH part of the mips_machtype removal. [Ralf: Fixed to the #error statements] Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/emma2rh/common/prom.c b/arch/mips/emma2rh/common/prom.c index 0f791eb..5e92b3a 100644 --- a/arch/mips/emma2rh/common/prom.c +++ b/arch/mips/emma2rh/common/prom.c @@ -34,12 +34,11 @@ const char *get_system_type(void) { - switch (mips_machtype) { - case MACH_NEC_MARKEINS: - return "NEC EMMA2RH Mark-eins"; - default: - return "Unknown NEC board"; - } +#if defined(CONFIG_MARKEINS) + return "NEC EMMA2RH Mark-eins"; +#else +#error Unknown NEC board +#endif } /* [jsun@junsun.net] PMON passes arguments in C main() style */ @@ -63,10 +62,10 @@ void __init prom_init(void) } #if defined(CONFIG_MARKEINS) - mips_machtype = MACH_NEC_MARKEINS; add_memory_region(0, EMMA2RH_RAM_SIZE, BOOT_MEM_RAM); +#else +#error Unknown NEC board #endif - } void __init prom_free_prom_memory(void) diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 653096a..51dbec9 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -47,11 +47,6 @@ #define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ /* - * Valid machtype for group NEC EMMA2RH - */ -#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ - -/* * Valid machtype for group PMC-MSP */ #define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */ -- cgit v0.10.2 From b27418aa551a153e8bf1bd16cf93e5786f9590a9 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Jul 2008 16:58:47 +0200 Subject: [MIPS] Remove mips_machtype for LASAT machines This is the LASAT part of the mips_machtype removal. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index a56c150..d1ac7a2 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -22,8 +22,8 @@ #include #include -#include #include +#include #include #include @@ -112,23 +112,18 @@ void __init arch_init_irq(void) { int i; - switch (mips_machtype) { - case MACH_LASAT_100: - lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; - lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; - lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; - get_int_status = get_int_status_100; - *lasat_int_mask = 0; - break; - case MACH_LASAT_200: + if (IS_LASAT_200()) { lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; get_int_status = get_int_status_200; *lasat_int_mask &= 0xffff; - break; - default: - panic("arch_init_irq: mips_machtype incorrect"); + } else { + lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; + get_int_status = get_int_status_100; + *lasat_int_mask = 0; } mips_cpu_irq_init(); diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c index 31e328b..577bb46 100644 --- a/arch/mips/lasat/lasat_board.c +++ b/arch/mips/lasat/lasat_board.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "at93c.h" /* New model description table */ @@ -66,7 +65,7 @@ static void init_flash_sizes(void) ls[LASAT_MTD_SERVICE] = 0xC0000; ls[LASAT_MTD_NORMAL] = 0x100000; - if (mips_machtype == MACH_LASAT_100) { + if (!IS_LASAT_200()) { lasat_board_info.li_flash_base = 0x1e000000; lb[LASAT_MTD_BOOTLOADER] = 0x1e400000; diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c index 209edcc..6acc6cb 100644 --- a/arch/mips/lasat/prom.c +++ b/arch/mips/lasat/prom.c @@ -86,18 +86,16 @@ void __init prom_init(void) setup_prom_vectors(); - if (current_cpu_data.cputype == CPU_R5000) { + if (IS_LASAT_200()) { printk(KERN_INFO "LASAT 200 board\n"); - mips_machtype = MACH_LASAT_200; lasat_ndelay_divider = LASAT_200_DIVIDER; + at93c = &at93c_defs[1]; } else { printk(KERN_INFO "LASAT 100 board\n"); - mips_machtype = MACH_LASAT_100; lasat_ndelay_divider = LASAT_100_DIVIDER; + at93c = &at93c_defs[0]; } - at93c = &at93c_defs[mips_machtype]; - lasat_init_board_info(); /* Read info from EEPROM */ /* Get the command line */ diff --git a/arch/mips/lasat/serial.c b/arch/mips/lasat/serial.c index 205bd39..5bcb6e8 100644 --- a/arch/mips/lasat/serial.c +++ b/arch/mips/lasat/serial.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -47,7 +46,7 @@ static __init int lasat_uart_add(void) if (!pdev) return -ENOMEM; - if (mips_machtype == MACH_LASAT_100) { + if (!IS_LASAT_200()) { lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_100); lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_100 * 8 - 1; lasat_serial_res[0].flags = IORESOURCE_MEM; diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c index e072da4..dbd3163 100644 --- a/arch/mips/lasat/setup.c +++ b/arch/mips/lasat/setup.c @@ -127,9 +127,11 @@ void __init plat_time_init(void) void __init plat_mem_setup(void) { int i; - lasat_misc = &lasat_misc_info[mips_machtype]; + int lasat_type = IS_LASAT_200() ? 1 : 0; + + lasat_misc = &lasat_misc_info[lasat_type]; #ifdef CONFIG_PICVUE - picvue = &pvc_defs[mips_machtype]; + picvue = &pvc_defs[lasat_type]; #endif /* Set up panic notifier */ @@ -140,7 +142,7 @@ void __init plat_mem_setup(void) lasat_reboot_setup(); #ifdef CONFIG_DS1603 - ds1603 = &ds_defs[mips_machtype]; + ds1603 = &ds_defs[lasat_type]; #endif #ifdef DYNAMIC_SERIAL_INIT diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index e70ae32..a98e543 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include @@ -39,16 +39,10 @@ static int __init lasat_pci_setup(void) { printk(KERN_DEBUG "PCI: starting\n"); - switch (mips_machtype) { - case MACH_LASAT_100: - lasat_pci_controller.pci_ops = >64xxx_pci0_ops; - break; - case MACH_LASAT_200: + if (IS_LASAT_200()) lasat_pci_controller.pci_ops = &nile4_pci_ops; - break; - default: - panic("pcibios_init: mips_machtype incorrect"); - } + else + lasat_pci_controller.pci_ops = >64xxx_pci0_ops; register_pci_controller(&lasat_pci_controller); diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 51dbec9..d39e143 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -41,12 +41,6 @@ #define MACH_DS5900 10 /* DECsystem 5900 */ /* - * Valid machtype for group LASAT - */ -#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ -#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ - -/* * Valid machtype for group PMC-MSP */ #define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */ diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h index ea04d92..caeba1e 100644 --- a/include/asm-mips/lasat/lasat.h +++ b/include/asm-mips/lasat/lasat.h @@ -240,6 +240,8 @@ static inline void lasat_ndelay(unsigned int ns) __delay(ns / lasat_ndelay_divider); } +#define IS_LASAT_200() (current_cpu_data.cputype == CPU_R5000) + #endif /* !defined (_LANGUAGE_ASSEMBLY) */ #define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef -- cgit v0.10.2 From 14351760e314b8a9720804b11c6bd11d0c0b1258 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 15 Jul 2008 11:01:39 -0700 Subject: Fix printk format warning in clocksource/acpi_pm.c For real, this time. The earlier attempt just moved the warning around. Signed-off-by: Linus Torvalds diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index bcd7d0e..5ca1d80 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -227,7 +227,7 @@ static int __init parse_pmtmr(char *arg) if (strict_strtoul(arg, 16, &base)) return -EINVAL; - printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04x\n", + printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", (unsigned int)pmtmr_ioport, base); pmtmr_ioport = base; -- cgit v0.10.2 From 8c6e46ddb343004e33653f62f0b09c0721cd8c12 Mon Sep 17 00:00:00 2001 From: Mikhail Cherkashin Date: Tue, 15 Jul 2008 21:21:40 +0200 Subject: palm_bk3710: fix tRP for UDMA mode 4 Fix tRP timing for UDMA mode 4 according to the ATA specification. Signed-off-by: Mikhail Cherkashin Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 2f2b4f4..74a05dc 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -83,7 +83,7 @@ static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { {125, 160}, /* UDMA Mode 1 */ {100, 120}, /* UDMA Mode 2 */ {100, 90}, /* UDMA Mode 3 */ - {85, 60}, /* UDMA Mode 4 */ + {100, 60}, /* UDMA Mode 4 */ }; static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, -- cgit v0.10.2 From 5ddee516dae1acc779b36cb7565720a80503196d Mon Sep 17 00:00:00 2001 From: Mikhail Cherkashin Date: Tue, 15 Jul 2008 21:21:40 +0200 Subject: ide: disable drive interrupts in ide_driveid_update() Since ide_driveid_update() uses polling to execute the IDENTIFY DEVICE command but clears nIEN bit in the control register and doesn't mask the IDE interrupt, the latter does happen and lead to the corresponding message to appear: ide0: unexpected interrupt, status=0x58, count=1 when e.g. running hdparm with option -X with a non-PCI IDE driver... Signed-off-by: Mikhail Cherkashin Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 0daf923..c2dd20a 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -689,7 +689,7 @@ int ide_driveid_update(ide_drive_t *drive) */ SELECT_MASK(drive, 1); - ide_set_irq(drive, 1); + ide_set_irq(drive, 0); msleep(50); hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr); timeout = jiffies + WAIT_WORSTCASE; -- cgit v0.10.2 From d6cddd3cac6650f273a2595c9f403aacee01ab05 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: ide: eliminate FIT() macro Replace the FIT() macro with the kernel-provided clamp_val() macro. FIT was always being called with a member of a struct ide_timing, which are shorts, and constant constraints for the min and max. Thus we can use clamp_val, rather than clamp_t. Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index 3b12ffe..2e91c58 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -95,7 +95,6 @@ static struct ide_timing ide_timing[] = { #define IDE_TIMING_UDMA 0x80 #define IDE_TIMING_ALL 0xff -#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin) #define ENOUGH(v,unit) (((v)-1)/(unit)+1) #define EZ(v,unit) ((v)?ENOUGH(v,unit):0) diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index efcf543..a373101 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -53,20 +53,20 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask, u8 t = 0, offset = amd_offset(dev); pci_read_config_byte(dev, AMD_ADDRESS_SETUP + offset, &t); - t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); + t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); pci_write_config_byte(dev, AMD_ADDRESS_SETUP + offset, t); pci_write_config_byte(dev, AMD_8BIT_TIMING + offset + (1 - (dn >> 1)), - ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); + ((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1)); pci_write_config_byte(dev, AMD_DRIVE_TIMING + offset + (3 - dn), - ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); + ((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1)); switch (udma_mask) { - case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; - case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; - case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; - case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; + case ATA_UDMA2: t = timing->udma ? (0xc0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break; + case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 2, 10)]) : 0x03; break; + case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 1, 10)]) : 0x03; break; + case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[clamp_val(timing->udma, 1, 15)]) : 0x03; break; default: return; } diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 566e0ec..e8c2570 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -120,21 +120,21 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) if (~vdev->via_config->flags & VIA_BAD_AST) { pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); - t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); + t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); } pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)), - ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); + ((clamp_val(timing->act8b, 1, 16) - 1) << 4) | (clamp_val(timing->rec8b, 1, 16) - 1)); pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), - ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); + ((clamp_val(timing->active, 1, 16) - 1) << 4) | (clamp_val(timing->recover, 1, 16) - 1)); switch (vdev->via_config->udma_mask) { - case ATA_UDMA2: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; - case ATA_UDMA4: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; - case ATA_UDMA5: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; - case ATA_UDMA6: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; + case ATA_UDMA2: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 5) - 2)) : 0x03; break; + case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break; + case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break; + case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break; default: return; } -- cgit v0.10.2 From a792bd5a407872714942f50bf24083874ce03745 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: ide-tape: use clamp_t() rather than nested min_t()/max_t() Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1e1f263..2d822df 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2746,9 +2746,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) * Ensure that the number we got makes sense; limit it within * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. */ - tape->best_dsc_rw_freq = max_t(unsigned long, - min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), - IDETAPE_DSC_RW_MIN); + tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN, + IDETAPE_DSC_RW_MAX); printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " "%lums tDSC%s\n", drive->name, tape->name, *(u16 *)&tape->caps[14], -- cgit v0.10.2 From 5d0cc8ae29b310ceb6516a6840ca22738aab7820 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: ide: use get_unaligned_* helpers Signed-off-by: Harvey Harrison Cc: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2d822df..1a96cc5 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -538,7 +538,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) if (pc->flags & PC_FLAG_DMA_ERROR) { pc->xferred = pc->req_xfer - tape->blk_size * - be32_to_cpu(get_unaligned((u32 *)&sense[3])); + get_unaligned_be32(&sense[3]); idetape_update_buffers(pc); } -- cgit v0.10.2 From e8a96aa71355edef9f40ce01459acf25c50cb78c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:41 +0200 Subject: ide: set REQ_PREEMPT request flag in ide_do_drive_cmd() users * Set REQ_PREEMPT request flag in ide_do_drive_cmd() users for ide_preempt and ide_head_wait action types. * Remove setting REQ_PREEMPT from ide_do_drive_cmd(). While at it: * Set 'where' variable outside ide_lock. This is a preparation for converting IDE to use blk_execute_rq(). There should be no functional changes caused by this patch. Cc: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 68e7f19..ff88159 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -216,6 +216,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->data_len = 18; rq->cmd_type = REQ_TYPE_SENSE; + rq->cmd_flags |= REQ_PREEMPT; /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index f05fbc2..7d75240 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -289,6 +289,7 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_init_drive_cmd(rq); rq->buffer = (char *) pc; rq->cmd_type = REQ_TYPE_SPECIAL; + rq->cmd_flags |= REQ_PREEMPT; rq->rq_disk = floppy->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 6965253..5aed79e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1600,13 +1600,12 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio rq->end_io = blk_end_sync_rq; } + if (action == ide_preempt || action == ide_head_wait) + where = ELEVATOR_INSERT_FRONT; + spin_lock_irqsave(&ide_lock, flags); if (action == ide_preempt) hwgroup->rq = NULL; - if (action == ide_preempt || action == ide_head_wait) { - where = ELEVATOR_INSERT_FRONT; - rq->cmd_flags |= REQ_PREEMPT; - } __elv_add_request(drive->queue, rq, where, 0); ide_do_request(hwgroup, IDE_NO_IRQ); spin_unlock_irqrestore(&ide_lock, flags); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1a96cc5..d67a178 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -688,6 +688,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, struct ide_tape_obj *tape = drive->driver_data; idetape_init_rq(rq, REQ_IDETAPE_PC1); + rq->cmd_flags |= REQ_PREEMPT; rq->buffer = (char *) pc; rq->rq_disk = tape->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 300431d..c9a0572 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -606,6 +606,7 @@ static int generic_ide_resume(struct device *dev) memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); rq.cmd_type = REQ_TYPE_PM_RESUME; + rq.cmd_flags |= REQ_PREEMPT; rq.special = &args; rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_resume; diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 44d8d51..89ecf01 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -235,6 +235,7 @@ static int idescsi_check_condition(ide_drive_t *drive, pc->c[0] = REQUEST_SENSE; pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE; rq->cmd_type = REQ_TYPE_SENSE; + rq->cmd_flags |= REQ_PREEMPT; pc->timeout = jiffies + WAIT_READY; /* NOTE! Save the failed packet command in "rq->buffer" */ rq->buffer = (void *) failed_cmd->special; -- cgit v0.10.2 From c6866a6ff571eebebda45bf14b5b62188768893a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:42 +0200 Subject: ide: use __generic_unplug_device() in ide_do_drive_cmd() (take 2) * Call __elv_add_request() with 'plug' == 1 (so the device will be plugged) and then use __generic_unplug_device() instead of calling ide_do_request() directly. v2: * For blk_pm_resume_request() requests the queue is stopped so we need to call ->request_fn explicitly. Thanks to: - Rafael for reporting/bisecting the bug - Borislav/Rafael for testing the fix This is a preparation for converting IDE to use blk_execute_rq(). Cc: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Cc: "Rafael J. Wysocki" Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 5aed79e..1eb3f5c 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1606,8 +1606,11 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio spin_lock_irqsave(&ide_lock, flags); if (action == ide_preempt) hwgroup->rq = NULL; - __elv_add_request(drive->queue, rq, where, 0); - ide_do_request(hwgroup, IDE_NO_IRQ); + __elv_add_request(drive->queue, rq, where, 1); + __generic_unplug_device(drive->queue); + /* the queue is stopped so it won't be plugged+unplugged */ + if (blk_pm_resume_request(rq)) + do_ide_request(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); err = 0; -- cgit v0.10.2 From 5f828546e1acb45678e73d3a9a796c1a3a8c7846 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:42 +0200 Subject: ide-cd: convert ide_cd_queue_pc to use blk_execute_rq This converts ide_cd_queue_pc to use blk_execute_rq, necessitating changing the ide_cd_queue_pc prototype into a form that doesn't takes a pointer to request struct. ide_cd_queue_pc works like scsi_execute. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ff88159..792a3cf 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -839,34 +839,54 @@ static void ide_cd_request_sense_fixup(struct request *rq) } } -int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) +int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, + int write, void *buffer, unsigned *bufflen, + struct request_sense *sense, int timeout, + unsigned int cmd_flags) { - struct request_sense sense; + struct cdrom_info *info = drive->driver_data; + struct request_sense local_sense; int retries = 10; - unsigned int flags = rq->cmd_flags; + unsigned int flags = 0; - if (rq->sense == NULL) - rq->sense = &sense; + if (!sense) + sense = &local_sense; /* start of retry loop */ do { + struct request *rq; int error; - unsigned long time = jiffies; - rq->cmd_flags = flags; - error = ide_do_drive_cmd(drive, rq, ide_wait); - time = jiffies - time; + rq = blk_get_request(drive->queue, write, __GFP_WAIT); + + memcpy(rq->cmd, cmd, BLK_MAX_CDB); + rq->cmd_type = REQ_TYPE_ATA_PC; + rq->sense = sense; + rq->cmd_flags |= cmd_flags; + rq->timeout = timeout; + if (buffer) { + rq->data = buffer; + rq->data_len = *bufflen; + } + + error = blk_execute_rq(drive->queue, info->disk, rq, 0); + + if (buffer) + *bufflen = rq->data_len; + + flags = rq->cmd_flags; + blk_put_request(rq); /* * FIXME: we should probably abort/retry or something in case of * failure. */ - if (rq->cmd_flags & REQ_FAILED) { + if (flags & REQ_FAILED) { /* * The request failed. Retry if it was due to a unit * attention status (usually means media was changed). */ - struct request_sense *reqbuf = rq->sense; + struct request_sense *reqbuf = sense; if (reqbuf->sense_key == UNIT_ATTENTION) cdrom_saw_media_change(drive); @@ -886,10 +906,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) } /* end of retry loop */ - } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0); + } while ((flags & REQ_FAILED) && retries >= 0); /* return an error if the command failed */ - return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0; + return (flags & REQ_FAILED) ? -EIO : 0; } /* @@ -1269,23 +1289,20 @@ static void msf_from_bcd(struct atapi_msf *msf) int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) { - struct request req; struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; + unsigned char cmd[BLK_MAX_CDB]; - ide_cd_init_rq(drive, &req); - - req.sense = sense; - req.cmd[0] = GPCMD_TEST_UNIT_READY; - req.cmd_flags |= REQ_QUIET; + memset(cmd, 0, BLK_MAX_CDB); + cmd[0] = GPCMD_TEST_UNIT_READY; /* * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs * instead of supporting the LOAD_UNLOAD opcode. */ - req.cmd[7] = cdi->sanyo_slot % 3; + cmd[7] = cdi->sanyo_slot % 3; - return ide_cd_queue_pc(drive, &req); + return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET); } static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, @@ -1298,17 +1315,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, } capbuf; int stat; - struct request req; - - ide_cd_init_rq(drive, &req); + unsigned char cmd[BLK_MAX_CDB]; + unsigned len = sizeof(capbuf); - req.sense = sense; - req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; - req.data = (char *)&capbuf; - req.data_len = sizeof(capbuf); - req.cmd_flags |= REQ_QUIET; + memset(cmd, 0, BLK_MAX_CDB); + cmd[0] = GPCMD_READ_CDVD_CAPACITY; - stat = ide_cd_queue_pc(drive, &req); + stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, + REQ_QUIET); if (stat == 0) { *capacity = 1 + be32_to_cpu(capbuf.lba); *sectors_per_frame = @@ -1322,24 +1336,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, int format, char *buf, int buflen, struct request_sense *sense) { - struct request req; + unsigned char cmd[BLK_MAX_CDB]; - ide_cd_init_rq(drive, &req); + memset(cmd, 0, BLK_MAX_CDB); - req.sense = sense; - req.data = buf; - req.data_len = buflen; - req.cmd_flags |= REQ_QUIET; - req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; - req.cmd[6] = trackno; - req.cmd[7] = (buflen >> 8); - req.cmd[8] = (buflen & 0xff); - req.cmd[9] = (format << 6); + cmd[0] = GPCMD_READ_TOC_PMA_ATIP; + cmd[6] = trackno; + cmd[7] = (buflen >> 8); + cmd[8] = (buflen & 0xff); + cmd[9] = (format << 6); if (msf_flag) - req.cmd[1] = 2; + cmd[1] = 2; - return ide_cd_queue_pc(drive, &req); + return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET); } /* Try to read the entire TOC for the disk into our internal buffer. */ diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index a58801c..df01cfd 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -144,7 +144,8 @@ void ide_cd_log_error(const char *, struct request *, struct request_sense *); /* ide-cd.c functions used by ide-cd_ioctl.c */ void ide_cd_init_rq(ide_drive_t *, struct request *); -int ide_cd_queue_pc(ide_drive_t *, struct request *); +int ide_cd_queue_pc(ide_drive_t *, const unsigned char *, int, void *, + unsigned *, struct request_sense *, int, unsigned int); int ide_cd_read_toc(ide_drive_t *, struct request_sense *); int ide_cdrom_get_capabilities(ide_drive_t *, u8 *); void ide_cdrom_update_speed(ide_drive_t *, u8 *); diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 6d147ce..8512770 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c @@ -104,8 +104,8 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag, { struct cdrom_info *cd = drive->driver_data; struct cdrom_device_info *cdi = &cd->devinfo; - struct request req; char loej = 0x02; + unsigned char cmd[BLK_MAX_CDB]; if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag) return -EDRIVE_CANT_DO_THIS; @@ -114,17 +114,16 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag, if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag) return 0; - ide_cd_init_rq(drive, &req); - /* only tell drive to close tray if open, if it can do that */ if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) loej = 0; - req.sense = sense; - req.cmd[0] = GPCMD_START_STOP_UNIT; - req.cmd[4] = loej | (ejectflag != 0); + memset(cmd, 0, BLK_MAX_CDB); + + cmd[0] = GPCMD_START_STOP_UNIT; + cmd[4] = loej | (ejectflag != 0); - return ide_cd_queue_pc(drive, &req); + return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, 0); } /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ @@ -134,7 +133,6 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, { struct cdrom_info *cd = drive->driver_data; struct request_sense my_sense; - struct request req; int stat; if (sense == NULL) @@ -144,11 +142,15 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) { stat = 0; } else { - ide_cd_init_rq(drive, &req); - req.sense = sense; - req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; - req.cmd[4] = lockflag ? 1 : 0; - stat = ide_cd_queue_pc(drive, &req); + unsigned char cmd[BLK_MAX_CDB]; + + memset(cmd, 0, BLK_MAX_CDB); + + cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; + cmd[4] = lockflag ? 1 : 0; + + stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0, + sense, 0, 0); } /* If we got an illegal field error, the drive @@ -206,32 +208,30 @@ int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed) { ide_drive_t *drive = cdi->handle; struct cdrom_info *cd = drive->driver_data; - struct request rq; struct request_sense sense; u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; int stat; - - ide_cd_init_rq(drive, &rq); - - rq.sense = &sense; + unsigned char cmd[BLK_MAX_CDB]; if (speed == 0) speed = 0xffff; /* set to max */ else speed *= 177; /* Nx to kbytes/s */ - rq.cmd[0] = GPCMD_SET_SPEED; + memset(cmd, 0, BLK_MAX_CDB); + + cmd[0] = GPCMD_SET_SPEED; /* Read Drive speed in kbytes/second MSB/LSB */ - rq.cmd[2] = (speed >> 8) & 0xff; - rq.cmd[3] = speed & 0xff; + cmd[2] = (speed >> 8) & 0xff; + cmd[3] = speed & 0xff; if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { /* Write Drive speed in kbytes/second MSB/LSB */ - rq.cmd[4] = (speed >> 8) & 0xff; - rq.cmd[5] = speed & 0xff; + cmd[4] = (speed >> 8) & 0xff; + cmd[5] = speed & 0xff; } - stat = ide_cd_queue_pc(drive, &rq); + stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0); if (!ide_cdrom_get_capabilities(drive, buf)) { ide_cdrom_update_speed(drive, buf); @@ -268,21 +268,19 @@ int ide_cdrom_get_mcn(struct cdrom_device_info *cdi, { ide_drive_t *drive = cdi->handle; int stat, mcnlen; - struct request rq; char buf[24]; + unsigned char cmd[BLK_MAX_CDB]; + unsigned len = sizeof(buf); - ide_cd_init_rq(drive, &rq); + memset(cmd, 0, BLK_MAX_CDB); - rq.data = buf; - rq.data_len = sizeof(buf); + cmd[0] = GPCMD_READ_SUBCHANNEL; + cmd[1] = 2; /* MSF addressing */ + cmd[2] = 0x40; /* request subQ data */ + cmd[3] = 2; /* format */ + cmd[8] = len; - rq.cmd[0] = GPCMD_READ_SUBCHANNEL; - rq.cmd[1] = 2; /* MSF addressing */ - rq.cmd[2] = 0x40; /* request subQ data */ - rq.cmd[3] = 2; /* format */ - rq.cmd[8] = sizeof(buf); - - stat = ide_cd_queue_pc(drive, &rq); + stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0); if (stat) return stat; @@ -351,8 +349,8 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) struct atapi_toc_entry *first_toc, *last_toc; unsigned long lba_start, lba_end; int stat; - struct request rq; struct request_sense sense; + unsigned char cmd[BLK_MAX_CDB]; stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc); if (stat) @@ -370,14 +368,13 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) if (lba_end <= lba_start) return -EINVAL; - ide_cd_init_rq(drive, &rq); + memset(cmd, 0, BLK_MAX_CDB); - rq.sense = &sense; - rq.cmd[0] = GPCMD_PLAY_AUDIO_MSF; - lba_to_msf(lba_start, &rq.cmd[3], &rq.cmd[4], &rq.cmd[5]); - lba_to_msf(lba_end - 1, &rq.cmd[6], &rq.cmd[7], &rq.cmd[8]); + cmd[0] = GPCMD_PLAY_AUDIO_MSF; + lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]); + lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]); - return ide_cd_queue_pc(drive, &rq); + return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0); } static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) @@ -447,8 +444,9 @@ int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, int ide_cdrom_packet(struct cdrom_device_info *cdi, struct packet_command *cgc) { - struct request req; ide_drive_t *drive = cdi->handle; + unsigned int flags = 0; + unsigned len = cgc->buflen; if (cgc->timeout <= 0) cgc->timeout = ATAPI_WAIT_PC; @@ -456,24 +454,21 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi, /* here we queue the commands from the uniform CD-ROM layer. the packet must be complete, as we do not touch it at all. */ - ide_cd_init_rq(drive, &req); if (cgc->data_direction == CGC_DATA_WRITE) - req.cmd_flags |= REQ_RW; + flags |= REQ_RW; - memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); if (cgc->sense) memset(cgc->sense, 0, sizeof(struct request_sense)); - req.data = cgc->buffer; - req.data_len = cgc->buflen; - req.timeout = cgc->timeout; if (cgc->quiet) - req.cmd_flags |= REQ_QUIET; + flags |= REQ_QUIET; - req.sense = cgc->sense; - cgc->stat = ide_cd_queue_pc(drive, &req); + cgc->stat = ide_cd_queue_pc(drive, cgc->cmd, + cgc->data_direction == CGC_DATA_WRITE, + cgc->buffer, &len, + cgc->sense, cgc->timeout, flags); if (!cgc->stat) - cgc->buflen -= req.data_len; + cgc->buflen -= len; return cgc->stat; } -- cgit v0.10.2 From 0ef4c4db7faabe4fb8a516e9e991e1e8e87a647f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:42 +0200 Subject: ide-cd: convert ide_do_drive_cmd path to use blk_execute_rq This converts the ide_do_drive_cmd path using ide_wait to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 8512770..24d002a 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c @@ -296,14 +296,14 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi) ide_drive_t *drive = cdi->handle; struct cdrom_info *cd = drive->driver_data; struct request_sense sense; - struct request req; + struct request *rq; int ret; - ide_cd_init_rq(drive, &req); - req.cmd_type = REQ_TYPE_SPECIAL; - req.cmd_flags = REQ_QUIET; - ret = ide_do_drive_cmd(drive, &req, ide_wait); - + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->cmd_flags = REQ_QUIET; + ret = blk_execute_rq(drive->queue, cd->disk, rq, 0); + blk_put_request(rq); /* * A reset will unlock the door. If it was previously locked, * lock it again. -- cgit v0.10.2 From dd47087bc173a84e8c42644b315d38b30dc02263 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: ide-disk: convert ide_do_drive_cmd path to use blk_execute_rq This converts the ide_do_drive_cmd path using ide_wait to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8e08d08..c5f22ef 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -617,7 +617,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) */ static int set_multcount(ide_drive_t *drive, int arg) { - struct request rq; + struct request *rq; + int error; if (arg < 0 || arg > drive->id->max_multsect) return -EINVAL; @@ -625,12 +626,13 @@ static int set_multcount(ide_drive_t *drive, int arg) if (drive->special.b.set_multmode) return -EBUSY; - ide_init_drive_cmd(&rq); - rq.cmd_type = REQ_TYPE_ATA_TASKFILE; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; drive->mult_req = arg; drive->special.b.set_multmode = 1; - (void)ide_do_drive_cmd(drive, &rq, ide_wait); + error = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); return (drive->mult_count == arg) ? 0 : -EIO; } -- cgit v0.10.2 From 6fe162381e547f457252e68521eb42fd36ec1418 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: ide-floppy: convert ide_do_drive_cmd path to use blk_execute_rq This converts the ide_do_drive_cmd path using ide_wait to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 7d75240..b10e9a8 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -887,14 +887,16 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct ide_floppy_obj *floppy = drive->driver_data; - struct request rq; + struct request *rq; + int error; - ide_init_drive_cmd(&rq); - rq.buffer = (char *) pc; - rq.cmd_type = REQ_TYPE_SPECIAL; - rq.rq_disk = floppy->disk; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->buffer = (char *) pc; + rq->cmd_type = REQ_TYPE_SPECIAL; + error = blk_execute_rq(drive->queue, floppy->disk, rq, 0); + blk_put_request(rq); - return ide_do_drive_cmd(drive, &rq, ide_wait); + return error; } /* -- cgit v0.10.2 From 154ed280e3f48995d0689b57f10b7063add63019 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: ide-taskfile: convert ide_do_drive_cmd path to use blk_execute_rq This converts the ide_do_drive_cmd path using ide_wait to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index ab545ff..b6a1c4b 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -492,11 +492,12 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) { - struct request rq; + struct request *rq; + int error; - blk_rq_init(NULL, &rq); - rq.cmd_type = REQ_TYPE_ATA_TASKFILE; - rq.buffer = buf; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; + rq->buffer = buf; /* * (ks) We transfer currently only whole sectors. @@ -504,16 +505,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) * if we would find a solution to transfer any size. * To support special commands like READ LONG. */ - rq.hard_nr_sectors = rq.nr_sectors = nsect; - rq.hard_cur_sectors = rq.current_nr_sectors = nsect; + rq->hard_nr_sectors = rq->nr_sectors = nsect; + rq->hard_cur_sectors = rq->current_nr_sectors = nsect; if (task->tf_flags & IDE_TFLAG_WRITE) - rq.cmd_flags |= REQ_RW; + rq->cmd_flags |= REQ_RW; - rq.special = task; - task->rq = &rq; + rq->special = task; + task->rq = rq; - return ide_do_drive_cmd(drive, &rq, ide_wait); + error = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); + + return error; } EXPORT_SYMBOL(ide_raw_taskfile); @@ -739,12 +743,14 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) struct hd_driveid *id = drive->id; if (NULL == (void *) arg) { - struct request rq; + struct request *rq; - ide_init_drive_cmd(&rq); - rq.cmd_type = REQ_TYPE_ATA_TASKFILE; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; + err = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); - return ide_do_drive_cmd(drive, &rq, ide_wait); + return err; } if (copy_from_user(args, (void __user *)arg, 4)) -- cgit v0.10.2 From 64ea1b4ab7f51c5de601d291a51508c27d445f70 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: ide-tape: convert ide_do_drive_cmd path to use blk_execute_rq This converts the ide_do_drive_cmd path using ide_wait to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d67a178..a5f0b77 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1519,12 +1519,16 @@ static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct ide_tape_obj *tape = drive->driver_data; - struct request rq; + struct request *rq; + int error; - idetape_init_rq(&rq, REQ_IDETAPE_PC1); - rq.buffer = (char *) pc; - rq.rq_disk = tape->disk; - return ide_do_drive_cmd(drive, &rq, ide_wait); + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->cmd[0] = REQ_IDETAPE_PC1; + rq->buffer = (char *)pc; + error = blk_execute_rq(drive->queue, tape->disk, rq, 0); + blk_put_request(rq); + return error; } static void idetape_create_load_unload_cmd(ide_drive_t *drive, @@ -1701,26 +1705,33 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct idetape_bh *bh) { idetape_tape_t *tape = drive->driver_data; - struct request rq; + struct request *rq; + int ret, errors; debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); - idetape_init_rq(&rq, cmd); - rq.rq_disk = tape->disk; - rq.special = (void *)bh; - rq.sector = tape->first_frame; - rq.nr_sectors = blocks; - rq.current_nr_sectors = blocks; - (void) ide_do_drive_cmd(drive, &rq, ide_wait); + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->cmd[0] = cmd; + rq->rq_disk = tape->disk; + rq->special = (void *)bh; + rq->sector = tape->first_frame; + rq->nr_sectors = blocks; + rq->current_nr_sectors = blocks; + blk_execute_rq(drive->queue, tape->disk, rq, 0); + + errors = rq->errors; + ret = tape->blk_size * (blocks - rq->current_nr_sectors); + blk_put_request(rq); if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) return 0; if (tape->merge_bh) idetape_init_merge_buffer(tape); - if (rq.errors == IDETAPE_ERROR_GENERAL) + if (errors == IDETAPE_ERROR_GENERAL) return -EIO; - return (tape->blk_size * (blocks-rq.current_nr_sectors)); + return ret; } static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) -- cgit v0.10.2 From 9a2d43b7566caeeeb414aa628bc2759028897dbb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:43 +0200 Subject: block: handle blk_pm_resume_request() requests in blk_execute_rq_nowait() For blk_pm_resume_request() requests (which are used only by IDE subsystem currently) the queue is stopped so we need to call ->request_fn explicitly. Thanks to: - Rafael for reporting/bisecting the bug - Borislav/Rafael for testing the fix This is a preparation for converting IDE to use blk_execute_rq(). Cc: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Cc: "Rafael J. Wysocki" Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/block/blk-exec.c b/block/blk-exec.c index 391dd62..4f52f27 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -58,6 +58,9 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, spin_lock_irq(q->queue_lock); __elv_add_request(q, rq, where, 1); __generic_unplug_device(q); + /* the queue is stopped so it won't be plugged+unplugged */ + if (blk_pm_resume_request(rq)) + q->request_fn(q); spin_unlock_irq(q->queue_lock); } EXPORT_SYMBOL_GPL(blk_execute_rq_nowait); -- cgit v0.10.2 From 5b114715ed63f3a4fdf790f5df61364fc4adadf1 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:44 +0200 Subject: ide: convert ide_do_drive_cmd path to use blk_execute_rq This converts the ide_do_drive_cmd path using ide_[head_]wait to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index c9a0572..8823df1 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -498,7 +498,7 @@ out: int set_pio_mode(ide_drive_t *drive, int arg) { - struct request rq; + struct request *rq; ide_hwif_t *hwif = drive->hwif; const struct ide_port_ops *port_ops = hwif->port_ops; @@ -512,12 +512,15 @@ int set_pio_mode(ide_drive_t *drive, int arg) if (drive->special.b.set_tune) return -EBUSY; - ide_init_drive_cmd(&rq); - rq.cmd_type = REQ_TYPE_ATA_TASKFILE; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_ATA_TASKFILE; drive->tune_req = (u8) arg; drive->special.b.set_tune = 1; - (void) ide_do_drive_cmd(drive, &rq, ide_wait); + + blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); + return 0; } @@ -555,7 +558,7 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev->driver_data; ide_hwif_t *hwif = HWIF(drive); - struct request rq; + struct request *rq; struct request_pm_state rqpm; ide_task_t args; int ret; @@ -564,18 +567,19 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) if (!(drive->dn % 2)) ide_acpi_get_timing(hwif); - blk_rq_init(NULL, &rq); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); - rq.cmd_type = REQ_TYPE_PM_SUSPEND; - rq.special = &args; - rq.data = &rqpm; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_PM_SUSPEND; + rq->special = &args; + rq->data = &rqpm; rqpm.pm_step = ide_pm_state_start_suspend; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; rqpm.pm_state = mesg.event; - ret = ide_do_drive_cmd(drive, &rq, ide_wait); + ret = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); /* only call ACPI _PS3 after both drivers are suspended */ if (!ret && (((drive->dn % 2) && hwif->drives[0].present && hwif->drives[1].present) @@ -589,7 +593,7 @@ static int generic_ide_resume(struct device *dev) { ide_drive_t *drive = dev->driver_data; ide_hwif_t *hwif = HWIF(drive); - struct request rq; + struct request *rq; struct request_pm_state rqpm; ide_task_t args; int err; @@ -602,17 +606,18 @@ static int generic_ide_resume(struct device *dev) ide_acpi_exec_tfs(drive); - blk_rq_init(NULL, &rq); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); - rq.cmd_type = REQ_TYPE_PM_RESUME; - rq.cmd_flags |= REQ_PREEMPT; - rq.special = &args; - rq.data = &rqpm; + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_PM_RESUME; + rq->cmd_flags |= REQ_PREEMPT; + rq->special = &args; + rq->data = &rqpm; rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_state = PM_EVENT_ON; - err = ide_do_drive_cmd(drive, &rq, ide_head_wait); + err = blk_execute_rq(drive->queue, NULL, rq, 1); + blk_put_request(rq); if (err == 0 && dev->driver) { ide_driver_t *drv = to_ide_driver(dev->driver); -- cgit v0.10.2 From 5f2e1ceef45ac07d7c52d16de2531a56c453bb0f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:44 +0200 Subject: ide: remove ide_wait/head_wait path in ide_do_drive_cmd Now all the users of ide_do_drive_cmd using ide_wait/head_wait are converted to use blk_execute_rq this removes the ide_wait/head_wait path in ide_do_drive_cmd. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1eb3f5c..29f5cc8 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1584,23 +1584,11 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio { unsigned long flags; ide_hwgroup_t *hwgroup = HWGROUP(drive); - DECLARE_COMPLETION_ONSTACK(wait); - int where = ELEVATOR_INSERT_BACK, err; - int must_wait = (action == ide_wait || action == ide_head_wait); + int where = ELEVATOR_INSERT_BACK; rq->errors = 0; - /* - * we need to hold an extra reference to request for safe inspection - * after completion - */ - if (must_wait) { - rq->ref_count++; - rq->end_io_data = &wait; - rq->end_io = blk_end_sync_rq; - } - - if (action == ide_preempt || action == ide_head_wait) + if (action == ide_preempt) where = ELEVATOR_INSERT_FRONT; spin_lock_irqsave(&ide_lock, flags); @@ -1613,16 +1601,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio do_ide_request(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); - err = 0; - if (must_wait) { - wait_for_completion(&wait); - if (rq->errors) - err = -EIO; - - blk_put_request(rq); - } - - return err; + return 0; } EXPORT_SYMBOL(ide_do_drive_cmd); -- cgit v0.10.2 From 124cafc5eb973e748c4ce3dc1caad29274e64613 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:44 +0200 Subject: ide: remove ide_init_drive_cmd ide_init_drive_cmd just calls blk_rq_init. This converts the users of ide_init_drive_cmd to use blk_rq_init directly and removes ide_init_drive_cmd. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 792a3cf..7917cd5 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -193,7 +193,7 @@ void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) { struct cdrom_info *cd = drive->driver_data; - ide_init_drive_cmd(rq); + blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_ATA_PC; rq->rq_disk = cd->disk; } diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index b10e9a8..9161cd9 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -286,7 +286,7 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, { struct ide_floppy_obj *floppy = drive->driver_data; - ide_init_drive_cmd(rq); + blk_rq_init(NULL, rq); rq->buffer = (char *) pc; rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_flags |= REQ_PREEMPT; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 29f5cc8..d8b4d9f 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1539,23 +1539,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) } /** - * ide_init_drive_cmd - initialize a drive command request - * @rq: request object - * - * Initialize a request before we fill it in and send it down to - * ide_do_drive_cmd. Commands must be set up by this function. Right - * now it doesn't do a lot, but if that changes abusers will have a - * nasty surprise. - */ - -void ide_init_drive_cmd (struct request *rq) -{ - blk_rq_init(NULL, rq); -} - -EXPORT_SYMBOL(ide_init_drive_cmd); - -/** * ide_do_drive_cmd - issue IDE special command * @drive: device to issue command * @rq: request to issue diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 89ecf01..da26180 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -228,7 +228,7 @@ static int idescsi_check_condition(ide_drive_t *drive, kfree(pc); return -ENOMEM; } - ide_init_drive_cmd(rq); + blk_rq_init(NULL, rq); rq->special = (char *) pc; pc->rq = rq; pc->buf = buf; @@ -786,7 +786,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, } } - ide_init_drive_cmd (rq); + blk_rq_init(NULL, rq); rq->special = (char *) pc; rq->cmd_type = REQ_TYPE_SPECIAL; spin_unlock_irq(host->host_lock); diff --git a/include/linux/ide.h b/include/linux/ide.h index eddb6da..3261c66 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -857,8 +857,6 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); extern ide_startstop_t ide_do_reset (ide_drive_t *); -extern void ide_init_drive_cmd (struct request *rq); - /* * "action" parameter type for ide_do_drive_cmd() below. */ -- cgit v0.10.2 From ed820f19521de246c5b7978f8f78290733a55b20 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: ide-cd: remove ide_cd_init_rq ide_cd_init_rq is not used by ide-cd_ioctl any more. Only cdrom_queue_request_sense use it. This converts cdrom_queue_request_sense to use blk_rq_init directly and removes ide_cd_init_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 7917cd5..ac542ff 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -188,16 +188,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, ide_cd_log_error(drive->name, failed_command, sense); } -/* Initialize a ide-cd packet command request */ -void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) -{ - struct cdrom_info *cd = drive->driver_data; - - blk_rq_init(NULL, rq); - rq->cmd_type = REQ_TYPE_ATA_PC; - rq->rq_disk = cd->disk; -} - static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct request *failed_command) { @@ -208,7 +198,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, sense = &info->sense_data; /* stuff the sense request in front of our current request */ - ide_cd_init_rq(drive, rq); + blk_rq_init(NULL, rq); + rq->cmd_type = REQ_TYPE_ATA_PC; + rq->rq_disk = info->disk; rq->data = sense; rq->cmd[0] = GPCMD_REQUEST_SENSE; diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index df01cfd..fe0ea36 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -143,7 +143,6 @@ struct cdrom_info { void ide_cd_log_error(const char *, struct request *, struct request_sense *); /* ide-cd.c functions used by ide-cd_ioctl.c */ -void ide_cd_init_rq(ide_drive_t *, struct request *); int ide_cd_queue_pc(ide_drive_t *, const unsigned char *, int, void *, unsigned *, struct request_sense *, int, unsigned int); int ide_cd_read_toc(ide_drive_t *, struct request_sense *); -- cgit v0.10.2 From d79c5a670ddf076a346ddcf3d9e21785ecab963f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: block: convert pd_special_command to use blk_execute_rq pd_special_command uses blk_put_request with struct request on the stack. As a result, blk_put_request needs a hack to catch a NULL request_queue. This converts pd_special_command to use blk_execute_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Signed-off-by: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 570f3b7..5fdfa7c 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -712,19 +712,17 @@ static void do_pd_request(struct request_queue * q) static int pd_special_command(struct pd_unit *disk, enum action (*func)(struct pd_unit *disk)) { - DECLARE_COMPLETION_ONSTACK(wait); - struct request rq; + struct request *rq; int err = 0; - blk_rq_init(NULL, &rq); - rq.rq_disk = disk->gd; - rq.end_io_data = &wait; - rq.end_io = blk_end_sync_rq; - blk_insert_request(disk->gd->queue, &rq, 0, func); - wait_for_completion(&wait); - if (rq.errors) - err = -EIO; - blk_put_request(&rq); + rq = blk_get_request(disk->gd->queue, READ, __GFP_WAIT); + + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->special = func; + + err = blk_execute_rq(disk->gd->queue, disk->gd, rq, 0); + + blk_put_request(rq); return err; } -- cgit v0.10.2 From 52a93ba815737e3877f85b46850cffe993a22429 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: block: remove the checking for NULL queue in blk_put_request Some uses blk_put_request asymmetrically, that is, they uses it with requests that not allocated by blk_get_request. As a result, blk_put_request has a hack to catch a NULL request_queue. Now such callers are fixed (they use blk_get_request properly). So we can safely remove the hack in blk_put_request. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Signed-off-by: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/block/blk-core.c b/block/blk-core.c index 1905aab..ac83cf9 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1042,15 +1042,9 @@ void blk_put_request(struct request *req) unsigned long flags; struct request_queue *q = req->q; - /* - * Gee, IDE calls in w/ NULL q. Fix IDE and remove the - * following if (q) test. - */ - if (q) { - spin_lock_irqsave(q->queue_lock, flags); - __blk_put_request(q, req); - spin_unlock_irqrestore(q->queue_lock, flags); - } + spin_lock_irqsave(q->queue_lock, flags); + __blk_put_request(q, req); + spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_put_request); -- cgit v0.10.2 From 681a561b7ec7fdcd8f35b68e44ac6d6c70aecc04 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:45 +0200 Subject: block: unexport blk_end_sync_rq All the users of blk_end_sync_rq has gone (they are converted to use blk_execute_rq). This unexports blk_end_sync_rq. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Signed-off-by: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/block/blk-exec.c b/block/blk-exec.c index 4f52f27..9bceff7 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -18,7 +18,7 @@ * @rq: request to complete * @error: end io status of the request */ -void blk_end_sync_rq(struct request *rq, int error) +static void blk_end_sync_rq(struct request *rq, int error) { struct completion *waiting = rq->end_io_data; @@ -31,7 +31,6 @@ void blk_end_sync_rq(struct request *rq, int error) */ complete(waiting); } -EXPORT_SYMBOL(blk_end_sync_rq); /** * blk_execute_rq_nowait - insert a request into queue for execution diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d2a1b71..1171abd 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -623,7 +623,6 @@ extern void generic_make_request(struct bio *bio); extern void blk_rq_init(struct request_queue *q, struct request *rq); extern void blk_put_request(struct request *); extern void __blk_put_request(struct request_queue *, struct request *); -extern void blk_end_sync_rq(struct request *rq, int error); extern struct request *blk_get_request(struct request_queue *, int, gfp_t); extern void blk_insert_request(struct request_queue *, struct request *, int, void *); extern void blk_requeue_request(struct request_queue *, struct request *); -- cgit v0.10.2 From 30e5ee4d1a651a0c66e86c6612c003034bd20ba2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:46 +0200 Subject: ide: remove obsoleted "idebus=" kernel parameter * Remove obsoleted "idebus=" kernel parameter. * Remove no longer needed ide_system_bus_speed() and system_bus_clock() (together with idebus_parameter and system_bus_speed variables). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 8823df1..f65be73 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -86,9 +86,6 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; -static int idebus_parameter; /* holds the "idebus=" parameter */ -static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ - DEFINE_MUTEX(ide_cfg_mtx); __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); @@ -189,38 +186,6 @@ static void __init init_ide_data (void) } } -/** - * ide_system_bus_speed - guess bus speed - * - * ide_system_bus_speed() returns what we think is the system VESA/PCI - * bus speed (in MHz). This is used for calculating interface PIO timings. - * The default is 40 for known PCI systems, 50 otherwise. - * The "idebus=xx" parameter can be used to override this value. - * The actual value to be used is computed/displayed the first time - * through. Drivers should only use this as a last resort. - * - * Returns a guessed speed in MHz. - */ - -static int ide_system_bus_speed(void) -{ -#ifdef CONFIG_PCI - static struct pci_device_id pci_default[] = { - { PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) }, - { } - }; -#else -#define pci_default 0 -#endif /* CONFIG_PCI */ - - /* user supplied value */ - if (idebus_parameter) - return idebus_parameter; - - /* safe default value for PCI or VESA and PCI*/ - return pci_dev_present(pci_default) ? 33 : 50; -} - void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) { ide_hwgroup_t *hwgroup = hwif->hwgroup; @@ -540,20 +505,6 @@ static int set_unmaskirq(ide_drive_t *drive, int arg) return 0; } -/** - * system_bus_clock - clock guess - * - * External version of the bus clock guess used by very old IDE drivers - * for things like VLB timings. Should not be used. - */ - -int system_bus_clock (void) -{ - return system_bus_speed; -} - -EXPORT_SYMBOL(system_bus_clock); - static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev->driver_data; @@ -851,7 +802,7 @@ static int __init ide_setup(char *s) if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ return 0; /* driver and not us */ - if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2)) + if (strncmp(s, "ide", 3) && strncmp(s, "hd", 2)) return 0; printk(KERN_INFO "ide_setup: %s", s); @@ -951,21 +902,6 @@ static int __init ide_setup(char *s) } } - if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e') - goto bad_option; - /* - * Look for bus speed option: "idebus=" - */ - if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') { - if (match_parm(&s[6], NULL, vals, 1) != 1) - goto bad_option; - if (vals[0] >= 20 && vals[0] <= 66) { - idebus_parameter = vals[0]; - } else - printk(" -- BAD BUS SPEED! Expected value from 20 to 66"); - goto obsolete_option; - } - bad_option: printk(" -- BAD OPTION\n"); return 1; @@ -1287,11 +1223,6 @@ static int __init ide_init(void) int ret; printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n"); - system_bus_speed = ide_system_bus_speed(); - - printk(KERN_INFO "ide: Assuming %dMHz system bus speed " - "for PIO modes%s\n", system_bus_speed, - idebus_parameter ? "" : "; override with idebus=xx"); ret = bus_register(&ide_bus_type); if (ret < 0) { diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index 90c65cf..052125f 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c @@ -116,7 +116,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) int time1, time2; u8 param1, param2, param3, param4; unsigned long flags; - int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); + int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; /* calculate timing, according to PIO mode */ time1 = ide_pio_cycle_time(drive, pio); diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 4fe516d..dd6dfb3 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -212,7 +212,7 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) { int active_time, recovery_time; int active_cycles, recovery_cycles; - int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); + int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; if (pio) { unsigned int cycle_time; diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 6424af1..51dba82 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -110,7 +110,7 @@ static void qd65xx_select(ide_drive_t *drive) static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time) { - int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); + int clk = ide_vlb_clk ? ide_vlb_clk : 50; u8 act_cyc, rec_cyc; if (clk <= 33) { @@ -132,7 +132,7 @@ static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery static u8 qd6580_compute_timing (int active_time, int recovery_time) { - int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); + int clk = ide_vlb_clk ? ide_vlb_clk : 50; u8 act_cyc, rec_cyc; act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17); diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 7f46c22..ae7a432 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -140,7 +140,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) { - int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); + int bus_speed = ide_pci_clk ? ide_pci_clk : 33; if (bus_speed <= 33) pci_set_drvdata(dev, (void *) aec6xxx_33_base); diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index f2129d5..f2de00ad 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -72,7 +72,7 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) int s_time, a_time, c_time; u8 s_clc, a_clc, r_clc; unsigned long flags; - int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); + int bus_speed = ide_pci_clk ? ide_pci_clk : 33; int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; u8 cd_dma_fifo = 0; diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index a373101..ad22220 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -179,7 +179,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, * Determine the system bus clock. */ - amd_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000; + amd_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000; switch (amd_clock) { case 33000: amd_clock = 33333; break; diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index b38a1980..cd1ba14 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -525,12 +525,10 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; int bus_speed; - if (cmd640_vlb && ide_vlb_clk) - bus_speed = ide_vlb_clk; - else if (!cmd640_vlb && ide_pci_clk) - bus_speed = ide_pci_clk; + if (cmd640_vlb) + bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; else - bus_speed = system_bus_clock(); + bus_speed = ide_pci_clk ? ide_pci_clk : 33; if (pio_mode > 5) pio_mode = 5; diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 0867471..ca4774a 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -69,7 +69,7 @@ static u8 quantize_timing(int timing, int quant) static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); - int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock()); + int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33); u8 cycle_count, active_count, recovery_count, drwtim; static const u8 recovery_values[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; @@ -128,7 +128,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) ide_pio_timings[pio].active_time); setup_count = quantize_timing(ide_pio_timings[pio].setup_time, - 1000 / (ide_pci_clk ? ide_pci_clk : system_bus_clock())); + 1000 / (ide_pci_clk ? ide_pci_clk : 33)); /* * The primary channel has individual address setup timing registers diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 77cc22c..8c534af 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -134,7 +134,7 @@ static int calc_clk(int time, int bus_speed) static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) { int clk1, clk2; - int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); + int bus_speed = ide_pci_clk ? ide_pci_clk : 33; /* we don't check against CY82C693's min and max speed, * so you can play with the idebus=xx parameter diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index e8c2570..3ed9728 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -340,7 +340,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const * Determine system bus clock. */ - via_clock = (ide_pci_clk ? ide_pci_clk : system_bus_clock()) * 1000; + via_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000; switch (via_clock) { case 33000: via_clock = 33333; break; diff --git a/include/linux/ide.h b/include/linux/ide.h index 3261c66..dad5356 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -994,8 +994,6 @@ int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long); int ide_task_ioctl(ide_drive_t *, unsigned int, unsigned long); -extern int system_bus_clock(void); - extern int ide_driveid_update(ide_drive_t *); extern int ide_config_drive_speed(ide_drive_t *, u8); extern u8 eighty_ninty_three (ide_drive_t *); -- cgit v0.10.2 From 232595eaff951e96cabe5e85fed35f66b72ff51e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:46 +0200 Subject: ide: remove obsoleted "hdx=" kernel parameters * Remove obsoleted "hdx=" kernel parameters. * Remove no longer used stridx() and match_parm(). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b52f47d..faeea50 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -722,9 +722,6 @@ and is between 256 and 4096 characters. It is defined in the file hd= [EIDE] (E)IDE hard drive subsystem geometry Format: ,, - hd?= [HW] (E)IDE subsystem - hd?lun= See Documentation/ide/ide.txt. - highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact size of . This works even on boxes that have no highmem otherwise. This also works to reduce highmem diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index f65be73..6f600d8 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -722,89 +722,13 @@ set_val: EXPORT_SYMBOL(generic_ide_ioctl); /* - * stridx() returns the offset of c within s, - * or -1 if c is '\0' or not found within s. - */ -static int __init stridx (const char *s, char c) -{ - char *i = strchr(s, c); - return (i && c) ? i - s : -1; -} - -/* - * match_parm() does parsing for ide_setup(): - * - * 1. the first char of s must be '='. - * 2. if the remainder matches one of the supplied keywords, - * the index (1 based) of the keyword is negated and returned. - * 3. if the remainder is a series of no more than max_vals numbers - * separated by commas, the numbers are saved in vals[] and a - * count of how many were saved is returned. Base10 is assumed, - * and base16 is allowed when prefixed with "0x". - * 4. otherwise, zero is returned. - */ -static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals) -{ - static const char *decimal = "0123456789"; - static const char *hex = "0123456789abcdef"; - int i, n; - - if (*s++ == '=') { - /* - * Try matching against the supplied keywords, - * and return -(index+1) if we match one - */ - if (keywords != NULL) { - for (i = 0; *keywords != NULL; ++i) { - if (!strcmp(s, *keywords++)) - return -(i+1); - } - } - /* - * Look for a series of no more than "max_vals" - * numeric values separated by commas, in base10, - * or base16 when prefixed with "0x". - * Return a count of how many were found. - */ - for (n = 0; (i = stridx(decimal, *s)) >= 0;) { - vals[n] = i; - while ((i = stridx(decimal, *++s)) >= 0) - vals[n] = (vals[n] * 10) + i; - if (*s == 'x' && !vals[n]) { - while ((i = stridx(hex, *++s)) >= 0) - vals[n] = (vals[n] * 0x10) + i; - } - if (++n == max_vals) - break; - if (*s == ',' || *s == ';') - ++s; - } - if (!*s) - return n; - } - return 0; /* zero = nothing matched */ -} - -/* * ide_setup() gets called VERY EARLY during initialization, - * to handle kernel "command line" strings beginning with "hdx=" or "ide". + * to handle kernel "command line" strings beginning with "ide". * * Remember to update Documentation/ide/ide.txt if you change something here. */ static int __init ide_setup(char *s) { - ide_hwif_t *hwif; - ide_drive_t *drive; - unsigned int hw, unit; - int vals[3]; - const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); - - if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ - return 0; /* driver and not us */ - - if (strncmp(s, "ide", 3) && strncmp(s, "hd", 2)) - return 0; - printk(KERN_INFO "ide_setup: %s", s); init_ide_data (); @@ -842,67 +766,6 @@ static int __init ide_setup(char *s) } #endif /* CONFIG_BLK_DEV_IDEACPI */ - /* - * Look for drive options: "hdx=" - */ - if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { - const char *hd_words[] = { - "none", "noprobe", "nowerr", "cdrom", "nodma", - "-6", "-7", "-8", "-9", "-10", - "noflush", "remap", "remap63", "scsi", NULL }; - unit = s[2] - 'a'; - hw = unit / MAX_DRIVES; - unit = unit % MAX_DRIVES; - hwif = &ide_hwifs[hw]; - drive = &hwif->drives[unit]; - if (strncmp(s + 4, "ide-", 4) == 0) { - strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req)); - goto obsolete_option; - } - switch (match_parm(&s[3], hd_words, vals, 3)) { - case -1: /* "none" */ - case -2: /* "noprobe" */ - drive->noprobe = 1; - goto obsolete_option; - case -3: /* "nowerr" */ - drive->bad_wstat = BAD_R_STAT; - goto obsolete_option; - case -4: /* "cdrom" */ - drive->present = 1; - drive->media = ide_cdrom; - /* an ATAPI device ignores DRDY */ - drive->ready_stat = 0; - goto obsolete_option; - case -5: /* nodma */ - drive->nodma = 1; - goto obsolete_option; - case -11: /* noflush */ - drive->noflush = 1; - goto obsolete_option; - case -12: /* "remap" */ - drive->remap_0_to_1 = 1; - goto obsolete_option; - case -13: /* "remap63" */ - drive->sect0 = 63; - goto obsolete_option; - case -14: /* "scsi" */ - drive->scsi = 1; - goto obsolete_option; - case 3: /* cyl,head,sect */ - drive->media = ide_disk; - drive->ready_stat = READY_STAT; - drive->cyl = drive->bios_cyl = vals[0]; - drive->head = drive->bios_head = vals[1]; - drive->sect = drive->bios_sect = vals[2]; - drive->present = 1; - drive->forced_geom = 1; - goto obsolete_option; - default: - goto bad_option; - } - } - -bad_option: printk(" -- BAD OPTION\n"); return 1; obsolete_option: -- cgit v0.10.2 From dbac9f895f628deebc99dee86dfd21c1823013c3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:46 +0200 Subject: ide: cleanup init_ide_data() * Remove no longer need init_ide_data() call from ide_setup(). * Cleanup init_ide_data(). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 6f600d8..e8c88ff2 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -151,32 +151,9 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) } } -/* - * init_ide_data() sets reasonable default values into all fields - * of all instances of the hwifs and drives, but only on the first call. - * Subsequent calls have no effect (they don't wipe out anything). - * - * This routine is normally called at driver initialization time, - * but may also be called MUCH earlier during kernel "command-line" - * parameter processing. As such, we cannot depend on any other parts - * of the kernel (such as memory allocation) to be functioning yet. - * - * This is too bad, as otherwise we could dynamically allocate the - * ide_drive_t structs as needed, rather than always consuming memory - * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them. - * - * FIXME: We should stuff the setup data into __init and copy the - * relevant hwifs/allocate them properly during boot. - */ -#define MAGIC_COOKIE 0x12345678 static void __init init_ide_data (void) { unsigned int index; - static unsigned long magic_cookie = MAGIC_COOKIE; - - if (magic_cookie != MAGIC_COOKIE) - return; /* already initialized */ - magic_cookie = 0; /* Initialise all interface structures */ for (index = 0; index < MAX_HWIFS; ++index) { @@ -730,7 +707,6 @@ EXPORT_SYMBOL(generic_ide_ioctl); static int __init ide_setup(char *s) { printk(KERN_INFO "ide_setup: %s", s); - init_ide_data (); #ifdef CONFIG_BLK_DEV_IDEDOUBLER if (!strcmp(s, "ide=doubler")) { -- cgit v0.10.2 From 931ee0dc5c69e8113233d21942681ab8fecde7f9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: ide: remove obsoleted "ide=" kernel parameters * Remove obsoleted "ide=" kernel parameters. * Remove no longer needed: - ide_setup() - parse_options() - __setup("", ...) - module_param(options, ...) * Use module_{init,exit}() for MODULE=y case and remove MODULE ifdef. * Make ide_*acpi* and ide_doubler variables static. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 9d3601f..6f70462 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -60,15 +60,15 @@ struct ide_acpi_hwif_link { #define DEBPRINT(fmt, args...) do {} while (0) #endif /* DEBUGGING */ -int ide_noacpi; +static int ide_noacpi; module_param_named(noacpi, ide_noacpi, bool, 0); MODULE_PARM_DESC(noacpi, "disable IDE ACPI support"); -int ide_acpigtf; +static int ide_acpigtf; module_param_named(acpigtf, ide_acpigtf, bool, 0); MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support"); -int ide_acpionboot; +static int ide_acpionboot; module_param_named(acpionboot, ide_acpionboot, bool, 0); MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot"); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 653b1ad..174f470 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -692,7 +692,7 @@ static int ide_tune_dma(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 speed; - if (noautodma || drive->nodma || (drive->id->capability & 1) == 0) + if (drive->nodma || (drive->id->capability & 1) == 0) return 0; /* consult the list of known "bad" drives */ diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index e8c88ff2..1defba3 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -87,9 +87,9 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; DEFINE_MUTEX(ide_cfg_mtx); - __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); -int noautodma = 0; +__cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); +EXPORT_SYMBOL(ide_lock); ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ @@ -698,59 +698,6 @@ set_val: EXPORT_SYMBOL(generic_ide_ioctl); -/* - * ide_setup() gets called VERY EARLY during initialization, - * to handle kernel "command line" strings beginning with "ide". - * - * Remember to update Documentation/ide/ide.txt if you change something here. - */ -static int __init ide_setup(char *s) -{ - printk(KERN_INFO "ide_setup: %s", s); - -#ifdef CONFIG_BLK_DEV_IDEDOUBLER - if (!strcmp(s, "ide=doubler")) { - extern int ide_doubler; - - printk(" : Enabled support for IDE doublers\n"); - ide_doubler = 1; - goto obsolete_option; - } -#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ - - if (!strcmp(s, "ide=nodma")) { - printk(" : Prevented DMA\n"); - noautodma = 1; - goto obsolete_option; - } - -#ifdef CONFIG_BLK_DEV_IDEACPI - if (!strcmp(s, "ide=noacpi")) { - //printk(" : Disable IDE ACPI support.\n"); - ide_noacpi = 1; - goto obsolete_option; - } - if (!strcmp(s, "ide=acpigtf")) { - //printk(" : Enable IDE ACPI _GTF support.\n"); - ide_acpigtf = 1; - goto obsolete_option; - } - if (!strcmp(s, "ide=acpionboot")) { - //printk(" : Call IDE ACPI methods on boot.\n"); - ide_acpionboot = 1; - goto obsolete_option; - } -#endif /* CONFIG_BLK_DEV_IDEACPI */ - - printk(" -- BAD OPTION\n"); - return 1; -obsolete_option: - printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n"); - return 1; -} - -EXPORT_SYMBOL(ide_lock); - static int ide_bus_match(struct device *dev, struct device_driver *drv) { return 1; @@ -1087,32 +1034,7 @@ out_port_class: return ret; } -#ifdef MODULE -static char *options = NULL; -module_param(options, charp, 0); -MODULE_LICENSE("GPL"); - -static void __init parse_options (char *line) -{ - char *next = line; - - if (line == NULL || !*line) - return; - while ((line = next) != NULL) { - if ((next = strchr(line,' ')) != NULL) - *next++ = 0; - if (!ide_setup(line)) - printk (KERN_INFO "Unknown option '%s'\n", line); - } -} - -int __init init_module (void) -{ - parse_options(options); - return ide_init(); -} - -void __exit cleanup_module (void) +static void __exit ide_exit(void) { proc_ide_destroy(); @@ -1121,10 +1043,7 @@ void __exit cleanup_module (void) bus_unregister(&ide_bus_type); } -#else /* !MODULE */ - -__setup("", ide_setup); - module_init(ide_init); +module_exit(ide_exit); -#endif /* MODULE */ +MODULE_LICENSE("GPL"); diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index fed7d81..b789416 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c @@ -64,9 +64,7 @@ #define GAYLE_HAS_CONTROL_REG (!ide_doubler) #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) -int ide_doubler = 0; /* support IDE doublers? */ -EXPORT_SYMBOL_GPL(ide_doubler); - +static int ide_doubler; module_param_named(doubler, ide_doubler, bool, 0); MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ diff --git a/include/linux/ide.h b/include/linux/ide.h index dad5356..0fa1812 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -813,10 +813,6 @@ int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsig #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ #endif -extern int ide_noacpi; -extern int ide_acpigtf; -extern int ide_acpionboot; -extern int noautodma; extern int ide_vlb_clk; extern int ide_pci_clk; -- cgit v0.10.2 From 57279a7a401eed844ded4346c5ff512e622ac1de Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: ide: remove try_to_flush_leftover_data() Just use the new & shiny ide_pad_transfer() helper instead. Also remove the superfluous check for 'drive->media == ide_disk' while at it (ide_ata_error() is used only for ide_disk devices). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index d8b4d9f..c22a337 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -358,31 +358,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) EXPORT_SYMBOL(ide_end_drive_cmd); -/** - * try_to_flush_leftover_data - flush junk - * @drive: drive to flush - * - * try_to_flush_leftover_data() is invoked in response to a drive - * unexpectedly having its DRQ_STAT bit set. As an alternative to - * resetting the drive, this routine tries to clear the condition - * by read a sector's worth of data from the drive. Of course, - * this may not help if the drive is *waiting* for data from *us*. - */ -static void try_to_flush_leftover_data (ide_drive_t *drive) -{ - int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS; - - if (drive->media != ide_disk) - return; - while (i > 0) { - u32 buffer[16]; - u32 wcount = (i > 16) ? 16 : i; - - i -= wcount; - drive->hwif->input_data(drive, NULL, buffer, wcount * 4); - } -} - static void ide_kill_rq(ide_drive_t *drive, struct request *rq) { if (rq->rq_disk) { @@ -422,8 +397,11 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 } if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && - (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) - try_to_flush_leftover_data(drive); + (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) { + int nsect = drive->mult_count ? drive->mult_count : 1; + + ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE); + } if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { ide_kill_rq(drive, rq); -- cgit v0.10.2 From 912ef6d94cc07ce5db19a8ed8953676727d4f30c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: sgiioc4: use ->extra_base instead of ->dma_status for dma_handle This is a preparation for removal of ->dma_status field from ide_hwif_t. There should be no functional changes caused by this patch. Acked-by: Jeremy Higdon Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 16a0bce..c1b667c 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -369,8 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) hwif->sg_max_nents = IOC4_PRD_ENTRIES; pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE, - (dma_addr_t *) &(hwif->dma_status)); - + (dma_addr_t *)&hwif->extra_base); if (pad) { ide_set_hwifdata(hwif, pad); return 0; @@ -439,7 +438,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) /* Address of the Ending DMA */ memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); - ending_dma_addr = cpu_to_le32(hwif->dma_status); + ending_dma_addr = cpu_to_le32(hwif->extra_base); writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4)); writel(dma_direction, (void __iomem *)ioc4_dma_addr); -- cgit v0.10.2 From 49e153e68187454e296f1e03442393f1a3f1d69c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:47 +0200 Subject: ide: remove commented out code from ide_config_drive_speed() Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c2dd20a..2de4c8f 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -744,9 +744,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) int error = 0; u8 stat; -// while (HWGROUP(drive)->busy) -// msleep(50); - #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_ops) /* check if host supports DMA */ hwif->dma_ops->dma_host_set(drive, 0); -- cgit v0.10.2 From e81a3bde13343bc36613aff8f864def7171b376a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:48 +0200 Subject: ide: fix do_probe() to use SELECT_DRIVE() Fix one place in do_probe() which used ->OUTB directly instead of calling SELECT_DRIVE() (so ->selectproc method is also used). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 26e68b6..12513c4 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -478,7 +478,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) printk(KERN_ERR "%s: no response (status = 0x%02x), " "resetting drive\n", drive->name, stat); msleep(50); - hwif->OUTB(drive->select.all, io_ports->device_addr); + SELECT_DRIVE(drive); msleep(50); hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr); (void)ide_busy_sleep(hwif); -- cgit v0.10.2 From 9a410e79b552bacb4481f85618aa7333b7776ed7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:48 +0200 Subject: ide: remove IDE_TFLAG_NO_SELECT_MASK taskfile flag Always call SELECT_MASK(..., 0) in ide_tf_load() (needs to be done to match ide_set_irq(..., 1)) and then remove IDE_TFLAG_NO_SELECT_MASK taskfile flag. This change should only affect hpt366 and icside host drivers since ->maskproc(..., 0) for sgiioc4 is equivalent to ide_set_irq(..., 1). Cc: Sergei Shtylyov Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ac542ff..0fbc2d8 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -530,8 +530,8 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, info->dma = !hwif->dma_ops->dma_setup(drive); /* set up the controller registers */ - ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL | - IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma); + ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL, + xferlen, info->dma); if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) { /* waiting for CDB interrupt, not DMA yet. */ diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index c5f22ef..5f49a4a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -198,8 +198,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, } memset(&task, 0, sizeof(task)); - task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */ - task.tf_flags |= (IDE_TFLAG_TF | IDE_TFLAG_DEVICE); + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (drive->select.b.lba) { if (lba48) { diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 9161cd9..1852008 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -667,8 +667,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) dma = !hwif->dma_ops->dma_setup(drive); - ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | - IDE_TFLAG_OUT_DEVICE, bcount, dma); + ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma); if (dma) { /* Begin DMA, if necessary */ diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 2de4c8f..9f9916f 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -121,9 +121,7 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) HIHI = 0xFF; ide_set_irq(drive, 1); - - if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) - SELECT_MASK(drive, 0); + SELECT_MASK(drive, 0); if (task->tf_flags & IDE_TFLAG_OUT_DATA) { u16 data = (tf->hob_data << 8) | tf->data; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a5f0b77..cc7991c 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1046,8 +1046,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) dma_ok = !hwif->dma_ops->dma_setup(drive); - ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | - IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); + ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); if (dma_ok) /* Will begin DMA later */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index da26180..3222aa5 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -564,7 +564,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, hwif->sg_mapped = 0; } - ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma); + ide_pktcmd_tf_load(drive, 0, bcount, dma); if (dma) pc->flags |= PC_FLAG_DMA_OK; diff --git a/include/linux/ide.h b/include/linux/ide.h index 0fa1812..d4a910c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -869,7 +869,6 @@ extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); enum { IDE_TFLAG_LBA48 = (1 << 0), - IDE_TFLAG_NO_SELECT_MASK = (1 << 1), IDE_TFLAG_FLAGGED = (1 << 2), IDE_TFLAG_OUT_DATA = (1 << 3), IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), -- cgit v0.10.2 From ed4af48fd660176680da905817f6e40d51436e4c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:48 +0200 Subject: ide: move IRQ unmasking out from ->tf_load method Move IRQ unmasking out from ->tf_load method to its users. There should be no functional changes caused by this patch (SELECT_MASK() is NOP except for hpt366, icside and sgiioc4). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index ecf53bb..d5afc28 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -52,8 +52,6 @@ static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - ide_set_irq(drive, 1); - if (task->tf_flags & IDE_TFLAG_OUT_DATA) mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c22a337..2083cc0 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1579,6 +1579,8 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) task.tf.lbah = (bcount >> 8) & 0xff; ide_tf_dump(drive->name, &task.tf); + ide_set_irq(drive, 1); + SELECT_MASK(drive, 0); drive->hwif->tf_load(drive, &task); } diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 9f9916f..491980a 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -95,7 +95,7 @@ void SELECT_DRIVE (ide_drive_t *drive) hwif->OUTB(drive->select.all, hwif->io_ports.device_addr); } -static void SELECT_MASK(ide_drive_t *drive, int mask) +void SELECT_MASK(ide_drive_t *drive, int mask) { const struct ide_port_ops *port_ops = drive->hwif->port_ops; @@ -120,9 +120,6 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - ide_set_irq(drive, 1); - SELECT_MASK(drive, 0); - if (task->tf_flags & IDE_TFLAG_OUT_DATA) { u16 data = (tf->hob_data << 8) | tf->data; diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index b6a1c4b..6a17ab5 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -109,6 +109,8 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); + ide_set_irq(drive, 1); + SELECT_MASK(drive, 0); hwif->tf_load(drive, task); } diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 910fb00..37e8cfc 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -662,8 +662,6 @@ static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - ide_set_irq(drive, 1); - if (task->tf_flags & IDE_TFLAG_OUT_DATA) out_be32((void *)io_ports->data_addr, (tf->hob_data << 8) | tf->data); diff --git a/include/linux/ide.h b/include/linux/ide.h index d4a910c..56d0bc2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -973,6 +973,7 @@ typedef struct ide_task_s { void ide_tf_dump(const char *, struct ide_taskfile *); extern void SELECT_DRIVE(ide_drive_t *); +void SELECT_MASK(ide_drive_t *, int); extern int drive_is_ready(ide_drive_t *); -- cgit v0.10.2 From 135721446144af005109c25eeacca4fdddcd9a66 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:49 +0200 Subject: ide: remove ->mmio flag from ide_hwif_t Since scc_pata host driver no longer uses IDE PCI layer / ide_dma_setup() and all other ->mmio users set also IDE_HFLAG_MMIO host flag we can safely remove ->mmio flag. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 74a05dc..3839f57 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -405,7 +405,6 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); - hwif->mmio = 1; default_hwif_mmiops(hwif); idx[0] = i; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 174f470..7ee44f8 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -463,7 +463,7 @@ int ide_dma_setup(ide_drive_t *drive) } /* PRD table */ - if (hwif->mmio) + if (hwif->host_flags & IDE_HFLAG_MMIO) writel(hwif->dmatable_dma, (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); else diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 37e8cfc..133053c 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -793,7 +793,6 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) hwif->dma_base = dma_base; hwif->config_data = ports->ctl; - hwif->mmio = 1; } /** diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 0006b9e..b75e9bb 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -94,7 +94,7 @@ static unsigned long siimage_selreg(ide_hwif_t *hwif, int r) unsigned long base = (unsigned long)hwif->hwif_data; base += 0xA0 + r; - if (hwif->mmio) + if (hwif->host_flags & IDE_HFLAG_MMIO) base += hwif->channel << 6; else base += hwif->channel << 4; @@ -117,7 +117,7 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) unsigned long base = (unsigned long)hwif->hwif_data; base += 0xA0 + r; - if (hwif->mmio) + if (hwif->host_flags & IDE_HFLAG_MMIO) base += hwif->channel << 6; else base += hwif->channel << 4; @@ -190,7 +190,9 @@ static u8 sil_pata_udma_filter(ide_drive_t *drive) unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc, mask = 0; - scsc = sil_ioread8(dev, base + (hwif->mmio ? 0x4A : 0x8A)); + base += (hwif->host_flags & IDE_HFLAG_MMIO) ? 0x4A : 0x8A; + + scsc = sil_ioread8(dev, base); switch (scsc & 0x30) { case 0x10: /* 133 */ @@ -238,8 +240,9 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) unsigned long tfaddr = siimage_selreg(hwif, 0x02); unsigned long base = (unsigned long)hwif->hwif_data; u8 tf_pio = pio; - u8 addr_mask = hwif->channel ? (hwif->mmio ? 0xF4 : 0x84) - : (hwif->mmio ? 0xB4 : 0x80); + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) + : (mmio ? 0xB4 : 0x80); u8 mode = 0; u8 unit = drive->select.b.unit; @@ -290,13 +293,13 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->select.b.unit; unsigned long base = (unsigned long)hwif->hwif_data; - u8 scsc = 0, addr_mask = hwif->channel ? - (hwif->mmio ? 0xF4 : 0x84) : - (hwif->mmio ? 0xB4 : 0x80); + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) + : (mmio ? 0xB4 : 0x80); unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ua = siimage_seldev(drive, 0x0C); - scsc = sil_ioread8 (dev, base + (hwif->mmio ? 0x4A : 0x8A)); + scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A)); mode = sil_ioread8 (dev, base + addr_mask); multi = sil_ioread16(dev, ma); ultra = sil_ioread16(dev, ua); @@ -391,7 +394,7 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive) static int siimage_dma_test_irq(ide_drive_t *drive) { - if (drive->hwif->mmio) + if (drive->hwif->host_flags & IDE_HFLAG_MMIO) return siimage_mmio_dma_test_irq(drive); else return siimage_io_dma_test_irq(drive); @@ -640,8 +643,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) hwif->irq = dev->irq; hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00); - - hwif->mmio = 1; } static int is_dev_seagate_sata(ide_drive_t *drive) diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 5171601..abcfb17 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -87,7 +87,7 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) unsigned long dma_base = 0; u8 dma_stat = 0; - if (hwif->mmio) + if (hwif->host_flags & IDE_HFLAG_MMIO) return hwif->dma_base; if (hwif->mate && hwif->mate->dma_base) { @@ -374,7 +374,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) if (base == 0 || ide_pci_set_master(dev, d->name) < 0) return -1; - if (hwif->mmio) + if (hwif->host_flags & IDE_HFLAG_MMIO) printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); else printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n", diff --git a/include/linux/ide.h b/include/linux/ide.h index 56d0bc2..b01b102 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -532,7 +532,6 @@ typedef struct hwif_s { unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ - unsigned mmio : 1; /* host uses MMIO */ struct device gendev; struct device *portdev; -- cgit v0.10.2 From f8c4bd0ab2b8783c0f080957781e9f70bee48eaa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:49 +0200 Subject: ide: pass 'hwif *' instead of 'drive *' to ->OUTBSYNC method There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2083cc0..c28fcdf 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -437,7 +437,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) /* force an abort */ - hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE, + hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE, hwif->io_ports.command_addr); if (rq->errors >= ERROR_MAX) { diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 491980a..4c32cf0 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -42,7 +42,7 @@ static void ide_outb (u8 val, unsigned long port) outb(val, port); } -static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port) +static void ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port) { outb(addr, port); } @@ -68,7 +68,7 @@ static void ide_mm_outb (u8 value, unsigned long port) writeb(value, (void __iomem *) port); } -static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port) +static void ide_mm_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port) { writeb(value, (void __iomem *) port); } @@ -686,7 +686,7 @@ int ide_driveid_update(ide_drive_t *drive) SELECT_MASK(drive, 1); ide_set_irq(drive, 0); msleep(50); - hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr); + hwif->OUTBSYNC(hwif, WIN_IDENTIFY, hwif->io_ports.command_addr); timeout = jiffies + WAIT_WORSTCASE; do { if (time_after(jiffies, timeout)) { @@ -773,7 +773,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) ide_set_irq(drive, 0); hwif->OUTB(speed, io_ports->nsect_addr); hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr); - hwif->OUTBSYNC(drive, WIN_SETFEATURES, io_ports->command_addr); + hwif->OUTBSYNC(hwif, WIN_SETFEATURES, io_ports->command_addr); if (drive->quirk_list == 2) ide_set_irq(drive, 1); @@ -881,7 +881,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, spin_lock_irqsave(&ide_lock, flags); __ide_set_handler(drive, handler, timeout, expiry); - hwif->OUTBSYNC(drive, cmd, hwif->io_ports.command_addr); + hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr); /* * Drive takes 400nS to respond, we must avoid the IRQ being * serviced before that. @@ -899,7 +899,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) unsigned long flags; spin_lock_irqsave(&ide_lock, flags); - hwif->OUTBSYNC(drive, WIN_PACKETCMD, hwif->io_ports.command_addr); + hwif->OUTBSYNC(hwif, WIN_PACKETCMD, hwif->io_ports.command_addr); ndelay(400); spin_unlock_irqrestore(&ide_lock, flags); } @@ -1094,7 +1094,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) pre_reset(drive); SELECT_DRIVE(drive); udelay (20); - hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr); + hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr); ndelay(400); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->polling = 1; @@ -1125,14 +1125,14 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) * recover from reset very quickly, saving us the first 50ms wait time. */ /* set SRST and nIEN */ - hwif->OUTBSYNC(drive, drive->ctl|6, io_ports->ctl_addr); + hwif->OUTBSYNC(hwif, drive->ctl | 6, io_ports->ctl_addr); /* more than enough time */ udelay(10); if (drive->quirk_list == 2) ctl = drive->ctl; /* clear SRST and nIEN */ else ctl = drive->ctl | 2; /* clear SRST, leave nIEN */ - hwif->OUTBSYNC(drive, ctl, io_ports->ctl_addr); + hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr); /* more than enough time */ udelay(10); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 12513c4..b010633 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -293,7 +293,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) hwif->OUTB(0, io_ports->feature_addr); /* ask drive for ID */ - hwif->OUTBSYNC(drive, cmd, io_ports->command_addr); + hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr); timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; timeout += jiffies; @@ -480,7 +480,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) msleep(50); SELECT_DRIVE(drive); msleep(50); - hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr); + hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr); (void)ide_busy_sleep(hwif); rc = try_to_identify(drive, cmd); } @@ -516,7 +516,7 @@ static void enable_nest (ide_drive_t *drive) printk("%s: enabling %s -- ", hwif->name, drive->id->model); SELECT_DRIVE(drive); msleep(50); - hwif->OUTBSYNC(drive, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr); + hwif->OUTBSYNC(hwif, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr); if (ide_busy_sleep(hwif)) { printk(KERN_CONT "failed (timeout)\n"); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 6a17ab5..cf55a48 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -117,7 +117,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) switch (task->data_phase) { case TASKFILE_MULTI_OUT: case TASKFILE_OUT: - hwif->OUTBSYNC(drive, tf->command, hwif->io_ports.command_addr); + hwif->OUTBSYNC(hwif, tf->command, hwif->io_ports.command_addr); ndelay(400); /* FIXME */ return pre_task_out_intr(drive, task->rq); case TASKFILE_MULTI_IN: diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 133053c..32eb087 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -148,11 +148,8 @@ static void scc_ide_outb(u8 addr, unsigned long port) out_be32((void*)port, addr); } -static void -scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) +static void scc_ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port) { - ide_hwif_t *hwif = HWIF(drive); - out_be32((void*)port, addr); eieio(); in_be32((void*)(hwif->dma_base + 0x01c)); diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ba2d587..dcb2c46 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -480,13 +480,13 @@ pmac_ide_do_update_timings(ide_drive_t *drive) pmac_ide_selectproc(drive); } -static void -pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port) +static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port) { u32 tmp; writeb(value, (void __iomem *) port); - tmp = readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); + tmp = readl((void __iomem *)(hwif->io_ports.data_addr + + IDE_TIMING_CONFIG)); } /* diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 3222aa5..d7fd5e5 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -257,7 +257,7 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) /* force an abort */ - hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE, + hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE, hwif->io_ports.command_addr); rq->errors++; diff --git a/include/linux/ide.h b/include/linux/ide.h index b01b102..1c34314 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -493,7 +493,7 @@ typedef struct hwif_s { void (*ide_dma_clear_irq)(ide_drive_t *drive); void (*OUTB)(u8 addr, unsigned long port); - void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); + void (*OUTBSYNC)(struct hwif_s *hwif, u8 addr, unsigned long port); u8 (*INB)(unsigned long port); -- cgit v0.10.2 From 6a732e11be1355baeeca7c47f19ab20e7baa6ce7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: ide: use ->OUTBSYNC in init_irq() Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index b010633..809362b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1065,7 +1065,7 @@ static int init_irq (ide_hwif_t *hwif) if (io_ports->ctl_addr) /* clear nIEN */ - hwif->OUTB(0x08, io_ports->ctl_addr); + hwif->OUTBSYNC(hwif, 0x08, io_ports->ctl_addr); if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) goto out_unlink; -- cgit v0.10.2 From 0fd04dcc2ebb6ec9088c24b368b0ce1f42a98ef5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: ide: use ->OUTBSYNC in ide_set_irq() Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/include/linux/ide.h b/include/linux/ide.h index 1c34314..4d1c971 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1340,7 +1340,8 @@ static inline void ide_set_irq(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; - hwif->OUTB(drive->ctl | (on ? 0 : 2), hwif->io_ports.ctl_addr); + hwif->OUTBSYNC(hwif, drive->ctl | (on ? 0 : 2), + hwif->io_ports.ctl_addr); } static inline u8 ide_read_status(ide_drive_t *drive) -- cgit v0.10.2 From ff07488346702f554aaeb6aae982540aa0302373 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: ide: remove drive->ctl Remove drive->ctl (it is always equal to 0x08 after init time). While at it: * Use ATA_DEVCTL_OBS define. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index d5afc28..ae37ee5 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -96,7 +96,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) } /* be sure we're looking at the low order bits */ - outb(drive->ctl & ~0x80, io_ports->ctl_addr); + outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = inb(io_ports->nsect_addr); @@ -110,7 +110,7 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) tf->device = inb(io_ports->device_addr); if (task->tf_flags & IDE_TFLAG_LBA48) { - outb(drive->ctl | 0x80, io_ports->ctl_addr); + outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = inb(io_ports->feature_addr); diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 4c32cf0..80ad4f2 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -186,7 +186,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) } /* be sure we're looking at the low order bits */ - tf_outb(drive->ctl & ~0x80, io_ports->ctl_addr); + tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tf_inb(io_ports->nsect_addr); @@ -200,7 +200,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) tf->device = tf_inb(io_ports->device_addr); if (task->tf_flags & IDE_TFLAG_LBA48) { - tf_outb(drive->ctl | 0x80, io_ports->ctl_addr); + tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = tf_inb(io_ports->feature_addr); @@ -1125,13 +1125,13 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) * recover from reset very quickly, saving us the first 50ms wait time. */ /* set SRST and nIEN */ - hwif->OUTBSYNC(hwif, drive->ctl | 6, io_ports->ctl_addr); + hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr); /* more than enough time */ udelay(10); if (drive->quirk_list == 2) - ctl = drive->ctl; /* clear SRST and nIEN */ + ctl = ATA_DEVCTL_OBS; /* clear SRST and nIEN */ else - ctl = drive->ctl | 2; /* clear SRST, leave nIEN */ + ctl = ATA_DEVCTL_OBS | 2; /* clear SRST, leave nIEN */ hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr); /* more than enough time */ udelay(10); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 809362b..d21e51a 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1065,7 +1065,7 @@ static int init_irq (ide_hwif_t *hwif) if (io_ports->ctl_addr) /* clear nIEN */ - hwif->OUTBSYNC(hwif, 0x08, io_ports->ctl_addr); + hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS, io_ports->ctl_addr); if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) goto out_unlink; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 1defba3..2b84535 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -136,7 +136,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) drive->media = ide_disk; drive->select.all = (unit<<4)|0xa0; drive->hwif = hwif; - drive->ctl = 0x08; drive->ready_stat = READY_STAT; drive->bad_wstat = BAD_W_STAT; drive->special.b.recalibrate = 1; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index c929dad..397c6cb 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -759,8 +759,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) enable_irq (hwif->irq); } } else - outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2), - hwif->io_ports.ctl_addr); + outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr); } /* diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index a7a41bb..45ba71a 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -76,7 +76,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) } /* be sure we're looking at the low order bits */ - outb(drive->ctl & ~0x80, io_ports->ctl_addr); + outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = inb(io_ports->nsect_addr); @@ -90,7 +90,7 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) tf->device = superio_ide_inb(io_ports->device_addr); if (task->tf_flags & IDE_TFLAG_LBA48) { - outb(drive->ctl | 0x80, io_ports->ctl_addr); + outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = inb(io_ports->feature_addr); diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 32eb087..1584ebb 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -703,7 +703,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) } /* be sure we're looking at the low order bits */ - scc_ide_outb(drive->ctl & ~0x80, io_ports->ctl_addr); + scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = scc_ide_inb(io_ports->nsect_addr); @@ -717,7 +717,7 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) tf->device = scc_ide_inb(io_ports->device_addr); if (task->tf_flags & IDE_TFLAG_LBA48) { - scc_ide_outb(drive->ctl | 0x80, io_ports->ctl_addr); + scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) tf->hob_feature = scc_ide_inb(io_ports->feature_addr); diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index c1b667c..24513e3 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -111,7 +111,7 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, static void sgiioc4_maskproc(ide_drive_t * drive, int mask) { - writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2), + writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0), (void __iomem *)drive->hwif->io_ports.ctl_addr); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 4d1c971..d8c86f0 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -364,7 +364,6 @@ typedef struct ide_drive_s { u8 wcache; /* status of write cache */ u8 acoustic; /* acoustic management */ u8 media; /* disk, cdrom, tape, floppy, ... */ - u8 ctl; /* "normal" value for Control register */ u8 ready_stat; /* min status value for drive ready */ u8 mult_count; /* current multiple sector setting */ u8 mult_req; /* requested multiple sector setting */ @@ -1340,7 +1339,7 @@ static inline void ide_set_irq(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; - hwif->OUTBSYNC(hwif, drive->ctl | (on ? 0 : 2), + hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | (on ? 0 : 2), hwif->io_ports.ctl_addr); } -- cgit v0.10.2 From 7e12ca11d65f4cb29ed58ea3948f8c5d4f57b35e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:50 +0200 Subject: ide-scsi: replace ide_do_drive_cmd with blk_execute_rq_nowait All the callers of ide_do_drive_cmd() except for ide-scsi use ide_preempt action argument. This converts ide-scsi to use blk_execute_rq_nowait instead of ide_do_drive_cmd so that we can remove the action argument in ide_do_drive_cmd and ide_action_t typedef. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d7fd5e5..58e30ef 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -790,8 +790,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, rq->special = (char *) pc; rq->cmd_type = REQ_TYPE_SPECIAL; spin_unlock_irq(host->host_lock); - rq->rq_disk = scsi->disk; - (void) ide_do_drive_cmd (drive, rq, ide_end); + blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL); spin_lock_irq(host->host_lock); return 0; abort: -- cgit v0.10.2 From 63f5abb0959337db0d5bece9cefba03cdcadec51 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: ide: remove action argument in ide_do_drive_cmd ide_do_drive_cmd is called only with ide_preempt action argument. So we can remove the action argument in ide_do_drive_cmd and ide_action_t typedef. This patch also includes two minor cleanups: 1) ide_do_drive_cmd always succeeds so we don't need the return value; 2) the callers use blk_rq_init before ide_do_drive_cmd so there is no need to initialize rq->errors. Signed-off-by: FUJITA Tomonori Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 0fbc2d8..043129c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -213,7 +213,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; - (void) ide_do_drive_cmd(drive, rq, ide_preempt); + ide_do_drive_cmd(drive, rq); } static void cdrom_end_request(ide_drive_t *drive, int uptodate) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 1852008..53209a4 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -291,7 +291,7 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_flags |= REQ_PREEMPT; rq->rq_disk = floppy->disk; - (void) ide_do_drive_cmd(drive, rq, ide_preempt); + ide_do_drive_cmd(drive, rq); } static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c28fcdf..2805774 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1520,49 +1520,27 @@ irqreturn_t ide_intr (int irq, void *dev_id) * ide_do_drive_cmd - issue IDE special command * @drive: device to issue command * @rq: request to issue - * @action: action for processing * * This function issues a special IDE device request * onto the request queue. * - * If action is ide_wait, then the rq is queued at the end of the - * request queue, and the function sleeps until it has been processed. - * This is for use when invoked from an ioctl handler. - * - * If action is ide_preempt, then the rq is queued at the head of - * the request queue, displacing the currently-being-processed - * request and this function returns immediately without waiting - * for the new rq to be completed. This is VERY DANGEROUS, and is - * intended for careful use by the ATAPI tape/cdrom driver code. - * - * If action is ide_end, then the rq is queued at the end of the - * request queue, and the function returns immediately without waiting - * for the new rq to be completed. This is again intended for careful - * use by the ATAPI tape/cdrom driver code. + * the rq is queued at the head of the request queue, displacing + * the currently-being-processed request and this function + * returns immediately without waiting for the new rq to be + * completed. This is VERY DANGEROUS, and is intended for + * careful use by the ATAPI tape/cdrom driver code. */ - -int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action) + +void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) { unsigned long flags; ide_hwgroup_t *hwgroup = HWGROUP(drive); - int where = ELEVATOR_INSERT_BACK; - - rq->errors = 0; - - if (action == ide_preempt) - where = ELEVATOR_INSERT_FRONT; spin_lock_irqsave(&ide_lock, flags); - if (action == ide_preempt) - hwgroup->rq = NULL; - __elv_add_request(drive->queue, rq, where, 1); + hwgroup->rq = NULL; + __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1); __generic_unplug_device(drive->queue); - /* the queue is stopped so it won't be plugged+unplugged */ - if (blk_pm_resume_request(rq)) - do_ide_request(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); - - return 0; } EXPORT_SYMBOL(ide_do_drive_cmd); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cc7991c..a562df8 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -691,7 +691,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, rq->cmd_flags |= REQ_PREEMPT; rq->buffer = (char *) pc; rq->rq_disk = tape->disk; - (void) ide_do_drive_cmd(drive, rq, ide_preempt); + ide_do_drive_cmd(drive, rq); } /* diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 58e30ef..569ffde 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -245,7 +245,8 @@ static int idescsi_check_condition(ide_drive_t *drive, ide_scsi_hex_dump(pc->c, 6); } rq->rq_disk = scsi->disk; - return ide_do_drive_cmd(drive, rq, ide_preempt); + ide_do_drive_cmd(drive, rq); + return 0; } static int idescsi_end_request(ide_drive_t *, int, int); diff --git a/include/linux/ide.h b/include/linux/ide.h index d8c86f0..04267dc 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -851,17 +851,7 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); extern ide_startstop_t ide_do_reset (ide_drive_t *); -/* - * "action" parameter type for ide_do_drive_cmd() below. - */ -typedef enum { - ide_wait, /* insert rq at end of list, and wait for it */ - ide_preempt, /* insert rq in front of current request */ - ide_head_wait, /* insert rq in front of current request and wait for it */ - ide_end /* insert rq at end of list, but don't wait for it */ -} ide_action_t; - -extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t); +extern void ide_do_drive_cmd(ide_drive_t *, struct request *); extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); -- cgit v0.10.2 From b3d96afccf8b5c67b66a61efb88c53ff029c6611 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: ide-scsi: fix race in idescsi_transfer_pc() Start DMA engine before sending content of packet command (otherwise it is possible that IRQ will happen before DMA engine is started). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 569ffde..2553ef4 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -494,13 +494,14 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) /* Set the interrupt routine */ ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); - /* Send the actual packet */ - hwif->output_data(drive, NULL, scsi->pc->c, 12); - if (pc->flags & PC_FLAG_DMA_OK) { pc->flags |= PC_FLAG_DMA_IN_PROGRESS; hwif->dma_ops->dma_start(drive); } + + /* Send the actual packet */ + hwif->output_data(drive, NULL, scsi->pc->c, 12); + return ide_started; } -- cgit v0.10.2 From e8e25f03e19c2c47834c821511625c0b80567827 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: ide-scsi: fix DRQ checking for DMA transfers in idescsi_pc_intr() If DRQ bit of Status Register is not cleared it is an error condition and should be handled accordingly (disable DMA + reset the device). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2553ef4..e67cf8a 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -388,7 +388,6 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) return ide_stopped; } if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; #if IDESCSI_DEBUG_LOG printk ("ide-scsi: %s: DMA complete\n", drive->name); #endif /* IDESCSI_DEBUG_LOG */ @@ -404,12 +403,20 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) printk(KERN_INFO "Packet command completed, %d bytes" " transferred\n", pc->xferred); + pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; local_irq_enable_in_hardirq(); if (stat & ERR_STAT) rq->errors++; idescsi_end_request (drive, 1, 0); return ide_stopped; } + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { + pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; + printk(KERN_ERR "%s: The device wants to issue more interrupts " + "in DMA mode\n", drive->name); + ide_dma_off(drive); + return ide_do_reset(drive); + } bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | hwif->INB(hwif->io_ports.lbam_addr); ireason = hwif->INB(hwif->io_ports.nsect_addr); -- cgit v0.10.2 From c04bbc812b05b304a9118687d0e0a47e35f00d1d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:51 +0200 Subject: ide-scsi: fix handling of DMA errors in idescsi_pc_intr() Check return value of ->dma_end method and if there was a DMA error handle it accordingly (set PC_FLAG_DMA_ERROR pc flag, don't update pc->xferred and increase rq->errors). Also move debug message in the right place while at it. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index e67cf8a..ed92cf7 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -388,11 +388,13 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) return ide_stopped; } if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { + if (hwif->dma_ops->dma_end(drive)) + pc->flags |= PC_FLAG_DMA_ERROR; + else + pc->xferred = pc->req_xfer; #if IDESCSI_DEBUG_LOG printk ("ide-scsi: %s: DMA complete\n", drive->name); #endif /* IDESCSI_DEBUG_LOG */ - pc->xferred = pc->req_xfer; - (void)hwif->dma_ops->dma_end(drive); } /* Clear the interrupt */ @@ -405,7 +407,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) " transferred\n", pc->xferred); pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; local_irq_enable_in_hardirq(); - if (stat & ERR_STAT) + if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) rq->errors++; idescsi_end_request (drive, 1, 0); return ide_stopped; -- cgit v0.10.2 From 6c60bd8ea7aa536d67830bc8384ef0ebdfb8aad4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: ide-scsi: fix Interrupt Reason checking in idescsi_pc_intr() Set PC_FLAG_WRITING pc flag in idescsi_queue() (if needed) and then fix Interrupt Reason checking in idescsi_pc_intr(). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index ed92cf7..0880707 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -427,7 +427,15 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); return ide_do_reset (drive); } - if (ireason & IO) { + if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { + /* Hopefully, we will never get here */ + printk(KERN_ERR "%s: We wanted to %s, but the device wants us " + "to %s!\n", drive->name, + (ireason & IO) ? "Write" : "Read", + (ireason & IO) ? "Read" : "Write"); + return ide_do_reset(drive); + } + if (!(pc->flags & PC_FLAG_WRITING)) { temp = pc->xferred + bcount; if (temp > pc->req_xfer) { if (temp > pc->buf_size) { @@ -436,7 +444,6 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) "- discarding data\n"); temp = pc->buf_size - pc->xferred; if (temp) { - pc->flags &= ~PC_FLAG_WRITING; if (pc->sg) idescsi_input_buffers(drive, pc, temp); @@ -457,15 +464,11 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n"); #endif /* IDESCSI_DEBUG_LOG */ } - } - if (ireason & IO) { - pc->flags &= ~PC_FLAG_WRITING; if (pc->sg) idescsi_input_buffers(drive, pc, bcount); else hwif->input_data(drive, NULL, pc->cur_pos, bcount); } else { - pc->flags |= PC_FLAG_WRITING; if (pc->sg) idescsi_output_buffers(drive, pc, bcount); else @@ -777,6 +780,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd, memset (pc->c, 0, 12); pc->flags = 0; + if (cmd->sc_data_direction == DMA_TO_DEVICE) + pc->flags |= PC_FLAG_WRITING; pc->rq = rq; memcpy (pc->c, cmd->cmnd, cmd->cmd_len); pc->buf = NULL; -- cgit v0.10.2 From 3e52fb4d1f4cc9630422982b6c5fa571e30f9889 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: ide-scsi: merge idescsi_input_buffers() and idescsi_output_buffers() * Merge idescsi_input_buffers() and idescsi_output_buffers() into ide_scsi_io_buffers() helper. While at it: * Log device name instead of driver name on error. * Use xfer_func_t. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 0880707..36c2c3b 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -129,51 +129,15 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) #define IDESCSI_PC_RQ 90 /* - * PIO data transfer routines using the scatter gather table. + * PIO data transfer routine using the scatter gather table. */ -static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount) +static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, + unsigned int bcount, int write) { ide_hwif_t *hwif = drive->hwif; - int count; + xfer_func_t *xf = write ? hwif->output_data : hwif->input_data; char *buf; - - while (bcount) { - count = min(pc->sg->length - pc->b_count, bcount); - if (PageHighMem(sg_page(pc->sg))) { - unsigned long flags; - - local_irq_save(flags); - buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + - pc->sg->offset; - hwif->input_data(drive, NULL, buf + pc->b_count, count); - kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); - local_irq_restore(flags); - } else { - buf = sg_virt(pc->sg); - hwif->input_data(drive, NULL, buf + pc->b_count, count); - } - bcount -= count; pc->b_count += count; - if (pc->b_count == pc->sg->length) { - if (!--pc->sg_cnt) - break; - pc->sg = sg_next(pc->sg); - pc->b_count = 0; - } - } - - if (bcount) { - printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); - ide_pad_transfer(drive, 0, bcount); - } -} - -static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount) -{ - ide_hwif_t *hwif = drive->hwif; int count; - char *buf; while (bcount) { count = min(pc->sg->length - pc->b_count, bcount); @@ -182,13 +146,13 @@ static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, local_irq_save(flags); buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + - pc->sg->offset; - hwif->output_data(drive, NULL, buf + pc->b_count, count); + pc->sg->offset; + xf(drive, NULL, buf + pc->b_count, count); kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); local_irq_restore(flags); } else { buf = sg_virt(pc->sg); - hwif->output_data(drive, NULL, buf + pc->b_count, count); + xf(drive, NULL, buf + pc->b_count, count); } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { @@ -200,8 +164,10 @@ static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, } if (bcount) { - printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); - ide_pad_transfer(drive, 1, bcount); + printk(KERN_ERR "%s: scatter gather table too small, %s\n", + drive->name, write ? "padding with zeros" + : "discarding data"); + ide_pad_transfer(drive, write, bcount); } } @@ -370,6 +336,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; struct ide_atapi_pc *pc = scsi->pc; struct request *rq = pc->rq; + xfer_func_t *xferfunc; unsigned int temp; u16 bcount; u8 stat, ireason; @@ -445,8 +412,8 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) temp = pc->buf_size - pc->xferred; if (temp) { if (pc->sg) - idescsi_input_buffers(drive, pc, - temp); + ide_scsi_io_buffers(drive, pc, + temp, 0); else hwif->input_data(drive, NULL, pc->cur_pos, temp); @@ -464,16 +431,16 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n"); #endif /* IDESCSI_DEBUG_LOG */ } - if (pc->sg) - idescsi_input_buffers(drive, pc, bcount); - else - hwif->input_data(drive, NULL, pc->cur_pos, bcount); - } else { - if (pc->sg) - idescsi_output_buffers(drive, pc, bcount); - else - hwif->output_data(drive, NULL, pc->cur_pos, bcount); - } + xferfunc = hwif->input_data; + } else + xferfunc = hwif->output_data; + + if (pc->sg) + ide_scsi_io_buffers(drive, pc, bcount, + !!(pc->flags & PC_FLAG_WRITING)); + else + xferfunc(drive, NULL, pc->cur_pos, bcount); + /* Update the current position */ pc->xferred += bcount; pc->cur_pos += bcount; -- cgit v0.10.2 From c8c51129805c0efb32f34afd3af8fe94f5757363 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: ide-scsi: remove superfluous BUG_ON() from idescsi_transfer_pc() ide_set_handler() bugs on ->handler == NULL so no need to do it in idescsi_transfer_pc(). There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 36c2c3b..e9d3dbf 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -469,7 +469,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) "issuing a packet command\n"); return ide_do_reset (drive); } - BUG_ON(HWGROUP(drive)->handler != NULL); + /* Set the interrupt routine */ ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); -- cgit v0.10.2 From 43a2b5b29385a3e0997a47c86f286d3645e5cb44 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:52 +0200 Subject: ide-scsi: add debug_log() macro Add debug_log() macro and convert the driver to use it. [ This makes debug messages to be always prefixed with "ide-scsi: " and use KERN_INFO level. ] While at it: * Change "DMA complete" debug message to "DMA finished" to match other ATAPI device drivers. * Use __func__. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index e9d3dbf..d2dad90 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -60,6 +60,13 @@ #define IDESCSI_DEBUG_LOG 0 +#if IDESCSI_DEBUG_LOG +#define debug_log(fmt, args...) \ + printk(KERN_INFO "ide-scsi: " fmt, ## args) +#else +#define debug_log(fmt, args...) do {} while (0) +#endif + /* * SCSI command transformation layer */ @@ -237,10 +244,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) static ide_startstop_t idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) { -#if IDESCSI_DEBUG_LOG - printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n", + debug_log("%s called for %lu\n", __func__, ((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number); -#endif + rq->errors |= ERROR_MAX; idescsi_end_request(drive, 0, 0); @@ -319,9 +325,9 @@ static int idescsi_expiry(ide_drive_t *drive) idescsi_scsi_t *scsi = drive_to_idescsi(drive); struct ide_atapi_pc *pc = scsi->pc; -#if IDESCSI_DEBUG_LOG - printk(KERN_WARNING "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies); -#endif + debug_log("%s called for %lu at %lu\n", __func__, + pc->scsi_cmd->serial_number, jiffies); + pc->flags |= PC_FLAG_TIMEDOUT; return 0; /* we do not want the ide subsystem to retry */ @@ -341,15 +347,11 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) u16 bcount; u8 stat, ireason; -#if IDESCSI_DEBUG_LOG - printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); -#endif /* IDESCSI_DEBUG_LOG */ + debug_log("Reached %s interrupt handler\n", __func__); if (pc->flags & PC_FLAG_TIMEDOUT) { -#if IDESCSI_DEBUG_LOG - printk(KERN_WARNING "idescsi_pc_intr: got timed out packet %lu at %lu\n", - pc->scsi_cmd->serial_number, jiffies); -#endif + debug_log("%s: got timed out packet %lu at %lu\n", __func__, + pc->scsi_cmd->serial_number, jiffies); /* end this request now - scsi should retry it*/ idescsi_end_request (drive, 1, 0); return ide_stopped; @@ -359,9 +361,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) pc->flags |= PC_FLAG_DMA_ERROR; else pc->xferred = pc->req_xfer; -#if IDESCSI_DEBUG_LOG - printk ("ide-scsi: %s: DMA complete\n", drive->name); -#endif /* IDESCSI_DEBUG_LOG */ + debug_log("%s: DMA finished\n", drive->name); } /* Clear the interrupt */ @@ -427,9 +427,8 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); return ide_started; } -#if IDESCSI_DEBUG_LOG - printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n"); -#endif /* IDESCSI_DEBUG_LOG */ + debug_log("The scsi wants to send us more data than " + "expected - allowing transfer\n"); } xferfunc = hwif->input_data; } else @@ -566,10 +565,10 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, */ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block) { -#if IDESCSI_DEBUG_LOG - printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors); - printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); -#endif /* IDESCSI_DEBUG_LOG */ + debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name, + rq->cmd[0], rq->errors); + debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n", + rq->sector, rq->nr_sectors, rq->current_nr_sectors); if (blk_sense_request(rq) || blk_special_request(rq)) { return idescsi_issue_pc(drive, @@ -976,10 +975,10 @@ static int ide_scsi_probe(ide_drive_t *drive) host->max_id = 1; -#if IDESCSI_DEBUG_LOG if (drive->id->last_lun) - printk(KERN_NOTICE "%s: id->last_lun=%u\n", drive->name, drive->id->last_lun); -#endif + debug_log("%s: id->last_lun=%u\n", drive->name, + drive->id->last_lun); + if ((drive->id->last_lun & 0x7) != 7) host->max_lun = (drive->id->last_lun & 0x7) + 1; else -- cgit v0.10.2 From 87429bdc2e0701fa33a455297de01e79797b4210 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:53 +0200 Subject: ide-tape: idetape_pc_intr() should use local_irq_enable_in_hardirq() Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a562df8..58c5a5a 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -794,7 +794,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) " transferred\n", pc->xferred); pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - local_irq_enable(); + local_irq_enable_in_hardirq(); #if SIMULATE_ERRORS if ((pc->c[0] == WRITE_6 || pc->c[0] == READ_6) && -- cgit v0.10.2 From 1e049a8ea190b7cc22320c7797b36b2c6128c9c5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:53 +0200 Subject: ide-tape: remove superfluous error message from idetape_pc_intr() ide_dma_off() prints info about DMA being disabled. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 58c5a5a..92fadd5 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -842,7 +842,6 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; printk(KERN_ERR "ide-tape: The tape wants to issue more " "interrupts in DMA mode\n"); - printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); ide_dma_off(drive); return ide_do_reset(drive); } -- cgit v0.10.2 From 6bd3b0bfb8fccdcce3b8524d6761e0a3ab6e23f0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:53 +0200 Subject: ide-tape: remove superfluous warning message from idetape_issue_pc() ide_dma_off() prints info about DMA being disabled. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 92fadd5..5aa7e2d 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1038,8 +1038,6 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, if (pc->flags & PC_FLAG_DMA_ERROR) { pc->flags &= ~PC_FLAG_DMA_ERROR; - printk(KERN_WARNING "ide-tape: DMA disabled, " - "reverting to PIO\n"); ide_dma_off(drive); } if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) -- cgit v0.10.2 From 91395a16309596c2e78439aa5f9f6004f0365ef9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: ide-tape: remove unneeded CONFIG_BLK_DEV_IDEDMA ifdef PC_FLAG_DMA_IN_PROGRESS flag is never set if DMA support is disabled. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 5aa7e2d..b8cc0d5 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -973,11 +973,11 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) } /* Set the interrupt routine */ ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); -#ifdef CONFIG_BLK_DEV_IDEDMA + /* Begin DMA, if necessary */ if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) hwif->dma_ops->dma_start(drive); -#endif + /* Send the actual packet */ hwif->output_data(drive, NULL, pc->c, 12); -- cgit v0.10.2 From 531e9e50543ebf562237b8ac64529ae09b344a43 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: ide-tape: remove stale comments from idetape_pc_intr() Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b8cc0d5..41aa8b3 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -758,27 +758,6 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { if (hwif->dma_ops->dma_end(drive) || (stat & ERR_STAT)) { - /* - * A DMA error is sometimes expected. For example, - * if the tape is crossing a filemark during a - * READ command, it will issue an irq and position - * itself before the filemark, so that only a partial - * data transfer will occur (which causes the DMA - * error). In that case, we will later ask the tape - * how much bytes of the original request were - * actually transferred (we can't receive that - * information from the DMA engine on most chipsets). - */ - - /* - * On the contrary, a DMA error is never expected; - * it usually indicates a hardware error or abort. - * If the tape crosses a filemark during a READ - * command, it will issue an irq and position itself - * after the filemark (not before). Only a partial - * data transfer will occur, but no DMA error. - * (AS, 19 Apr 2001) - */ pc->flags |= PC_FLAG_DMA_ERROR; } else { pc->xferred = pc->req_xfer; -- cgit v0.10.2 From 170ee569bbe1005baebf2e9e4c3f4622d14ec851 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: ide-tape: remove SIMULATE_ERRORS debug code Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 41aa8b3..cc70e75 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -144,9 +144,6 @@ enum { /*************************** End of tunable parameters ***********************/ -/* Read/Write error simulation */ -#define SIMULATE_ERRORS 0 - /* tape directions */ enum { IDETAPE_DIR_NONE = (1 << 0), @@ -745,9 +742,6 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) xfer_func_t *xferfunc; idetape_io_buf *iobuf; unsigned int temp; -#if SIMULATE_ERRORS - static int error_sim_count; -#endif u16 bcount; u8 stat, ireason; @@ -775,14 +769,6 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; local_irq_enable_in_hardirq(); -#if SIMULATE_ERRORS - if ((pc->c[0] == WRITE_6 || pc->c[0] == READ_6) && - (++error_sim_count % 100) == 0) { - printk(KERN_INFO "ide-tape: %s: simulating error\n", - tape->name); - stat |= ERR_STAT; - } -#endif if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE) stat &= ~ERR_STAT; if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { -- cgit v0.10.2 From 0b2eea4c5594ceaf13c57eaff7ff226263f1c36f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: ide-floppy: merge idefloppy_transfer_pc() and idefloppy_transfer_pc1() * Check IDEFLOPPY_FLAG_ZIP_DRIVE flag in idefloppy_transfer_pc1() and skip idefloppy_transfer_pc2()-phase if the flag is not set. * Always use idefloppy_transfer_pc1() in idefloppy_issue_pc() and remove no longer needed idefloppy_transfer_pc(). There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 53209a4..8dbb340 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -522,40 +522,6 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) } /* - * This is the original routine that did the packet transfer. - * It fails at high speeds on the Iomega ZIP drive, so there's a slower version - * for that drive below. The algorithm is chosen based on drive type - */ -static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - ide_startstop_t startstop; - idefloppy_floppy_t *floppy = drive->driver_data; - u8 ireason; - - if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { - printk(KERN_ERR "ide-floppy: Strange, packet command " - "initiated yet DRQ isn't asserted\n"); - return startstop; - } - ireason = hwif->INB(hwif->io_ports.nsect_addr); - if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " - "issuing a packet command\n"); - return ide_do_reset(drive); - } - - /* Set the interrupt routine */ - ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); - - /* Send the actual packet */ - hwif->output_data(drive, NULL, floppy->pc->c, 12); - - return ide_started; -} - - -/* * What we have here is a classic case of a top half / bottom half interrupt * service routine. In interrupt mode, the device sends an interrupt to signal * that it is ready to receive a packet. However, we need to delay about 2-3 @@ -580,6 +546,8 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; idefloppy_floppy_t *floppy = drive->driver_data; + ide_expiry_t *expiry; + unsigned int timeout; ide_startstop_t startstop; u8 ireason; @@ -602,9 +570,20 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) * 40 and 50msec work well. idefloppy_pc_intr will not be actually * used until after the packet is moved in about 50 msec. */ + if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) { + timeout = floppy->ticks; + expiry = &idefloppy_transfer_pc2; + } else { + timeout = IDEFLOPPY_WAIT_CMD; + expiry = NULL; + } + + ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry); + + if ((floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) == 0) + /* Send the actual packet */ + hwif->output_data(drive, NULL, floppy->pc->c, 12); - ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks, - &idefloppy_transfer_pc2); return ide_started; } @@ -629,7 +608,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, { idefloppy_floppy_t *floppy = drive->driver_data; ide_hwif_t *hwif = drive->hwif; - ide_handler_t *pkt_xfer_routine; u16 bcount; u8 dma; @@ -675,26 +653,17 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, hwif->dma_ops->dma_start(drive); } - /* Can we transfer the packet when we get the interrupt or wait? */ - if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) { - /* wait */ - pkt_xfer_routine = &idefloppy_transfer_pc1; - } else { - /* immediate */ - pkt_xfer_routine = &idefloppy_transfer_pc; - } - if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) { /* Issue the packet command */ ide_execute_command(drive, WIN_PACKETCMD, - pkt_xfer_routine, + &idefloppy_transfer_pc1, IDEFLOPPY_WAIT_CMD, NULL); return ide_started; } else { /* Issue the packet command */ ide_execute_pkt_cmd(drive); - return (*pkt_xfer_routine) (drive); + return idefloppy_transfer_pc1(drive); } } -- cgit v0.10.2 From 568ca92774d2f6be4a7e2f8357559bfdc9424056 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:54 +0200 Subject: ide-{floppy,tape,scsi}: log device name instead of driver name Log device name instead of driver name in *_pc_intr() and *_transfer_pc*(). While at it: * Merge two consecutive printk()-s in *_pc_intr() together. * Replace "floppy"/"tape"/"scsi" references in printk()-s by "device". Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 8dbb340..dae1c90 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -438,8 +438,8 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) debug_log("%s: I/O error\n", drive->name); rq->errors++; if (pc->c[0] == GPCMD_REQUEST_SENSE) { - printk(KERN_ERR "ide-floppy: I/O error in " - "request sense command\n"); + printk(KERN_ERR "%s: I/O error in request sense" + " command\n", drive->name); return ide_do_reset(drive); } /* Retry operation */ @@ -457,8 +457,8 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - printk(KERN_ERR "ide-floppy: The floppy wants to issue " - "more interrupts in DMA mode\n"); + printk(KERN_ERR "%s: The device wants to issue more interrupts " + "in DMA mode\n", drive->name); ide_dma_off(drive); return ide_do_reset(drive); } @@ -470,14 +470,14 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) ireason = hwif->INB(hwif->io_ports.nsect_addr); if (ireason & CD) { - printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__); + printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); return ide_do_reset(drive); } if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { /* Hopefully, we will never get here */ - printk(KERN_ERR "ide-floppy: We wanted to %s, ", - (ireason & IO) ? "Write" : "Read"); - printk(KERN_ERR "but the floppy wants us to %s !\n", + printk(KERN_ERR "%s: We wanted to %s, but the device wants us " + "to %s!\n", drive->name, + (ireason & IO) ? "Write" : "Read", (ireason & IO) ? "Read" : "Write"); return ide_do_reset(drive); } @@ -486,9 +486,10 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) temp = pc->xferred + bcount; if (temp > pc->req_xfer) { if (temp > pc->buf_size) { - printk(KERN_ERR "ide-floppy: The floppy wants " - "to send us more data than expected " - "- discarding data\n"); + printk(KERN_ERR "%s: The device wants to send " + "us more data than expected - " + "discarding data\n", + drive->name); ide_pad_transfer(drive, 0, bcount); ide_set_handler(drive, @@ -497,8 +498,8 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) NULL); return ide_started; } - debug_log("The floppy wants to send us more data than" - " expected - allowing transfer\n"); + debug_log("The device wants to send us more data than " + "expected - allowing transfer\n"); } } if (pc->flags & PC_FLAG_WRITING) @@ -552,14 +553,14 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) u8 ireason; if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { - printk(KERN_ERR "ide-floppy: Strange, packet command " - "initiated yet DRQ isn't asserted\n"); + printk(KERN_ERR "%s: Strange, packet command initiated yet " + "DRQ isn't asserted\n", drive->name); return startstop; } ireason = hwif->INB(hwif->io_ports.nsect_addr); if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " - "while issuing a packet command\n"); + printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " + "a packet command\n", drive->name); return ide_do_reset(drive); } /* diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cc70e75..8f10211 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -776,8 +776,8 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) debug_log(DBG_ERR, "%s: I/O error\n", tape->name); if (pc->c[0] == REQUEST_SENSE) { - printk(KERN_ERR "ide-tape: I/O error in request" - " sense command\n"); + printk(KERN_ERR "%s: I/O error in request sense" + " command\n", drive->name); return ide_do_reset(drive); } debug_log(DBG_ERR, "[cmd %x]: check condition\n", @@ -805,8 +805,8 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - printk(KERN_ERR "ide-tape: The tape wants to issue more " - "interrupts in DMA mode\n"); + printk(KERN_ERR "%s: The device wants to issue more interrupts " + "in DMA mode\n", drive->name); ide_dma_off(drive); return ide_do_reset(drive); } @@ -817,14 +817,14 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) ireason = hwif->INB(hwif->io_ports.nsect_addr); if (ireason & CD) { - printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__); + printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); return ide_do_reset(drive); } if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { /* Hopefully, we will never get here */ - printk(KERN_ERR "ide-tape: We wanted to %s, ", - (ireason & IO) ? "Write" : "Read"); - printk(KERN_ERR "ide-tape: but the tape wants us to %s !\n", + printk(KERN_ERR "%s: We wanted to %s, but the device wants us " + "to %s!\n", drive->name, + (ireason & IO) ? "Write" : "Read", (ireason & IO) ? "Read" : "Write"); return ide_do_reset(drive); } @@ -833,15 +833,16 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) temp = pc->xferred + bcount; if (temp > pc->req_xfer) { if (temp > pc->buf_size) { - printk(KERN_ERR "ide-tape: The tape wants to " - "send us more data than expected " - "- discarding data\n"); + printk(KERN_ERR "%s: The device wants to send " + "us more data than expected - " + "discarding data\n", + drive->name); ide_pad_transfer(drive, 0, bcount); ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); return ide_started; } - debug_log(DBG_SENSE, "The tape wants to send us more " + debug_log(DBG_SENSE, "The device wants to send us more " "data than expected - allowing transfer\n"); } iobuf = &idetape_input_buffers; @@ -914,26 +915,27 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) u8 ireason; if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { - printk(KERN_ERR "ide-tape: Strange, packet command initiated " - "yet DRQ isn't asserted\n"); + printk(KERN_ERR "%s: Strange, packet command initiated yet " + "DRQ isn't asserted\n", drive->name); return startstop; } ireason = hwif->INB(hwif->io_ports.nsect_addr); while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { - printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing " - "a packet command, retrying\n"); + printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " + "a packet command, retrying\n", drive->name); udelay(100); ireason = hwif->INB(hwif->io_ports.nsect_addr); if (retries == 0) { - printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while " - "issuing a packet command, ignoring\n"); + printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " + "a packet command, ignoring\n", + drive->name); ireason |= CD; ireason &= ~IO; } } if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing " - "a packet command\n"); + printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " + "a packet command\n", drive->name); return ide_do_reset(drive); } /* Set the interrupt routine */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d2dad90..5b8a193 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -391,7 +391,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) ireason = hwif->INB(hwif->io_ports.nsect_addr); if (ireason & CD) { - printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); + printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); return ide_do_reset (drive); } if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { @@ -406,9 +406,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) temp = pc->xferred + bcount; if (temp > pc->req_xfer) { if (temp > pc->buf_size) { - printk(KERN_ERR "ide-scsi: The scsi wants to " - "send us more data than expected " - "- discarding data\n"); + printk(KERN_ERR "%s: The device wants to send " + "us more data than expected - " + "discarding data\n", + drive->name); temp = pc->buf_size - pc->xferred; if (temp) { if (pc->sg) @@ -417,8 +418,9 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) else hwif->input_data(drive, NULL, pc->cur_pos, temp); - printk(KERN_ERR "ide-scsi: transferred" - " %d of %d bytes\n", + printk(KERN_ERR "%s: transferred %d of " + "%d bytes\n", + drive->name, temp, bcount); } pc->xferred += temp; @@ -427,7 +429,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); return ide_started; } - debug_log("The scsi wants to send us more data than " + debug_log("The device wants to send us more data than " "expected - allowing transfer\n"); } xferfunc = hwif->input_data; @@ -458,14 +460,14 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) u8 ireason; if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { - printk(KERN_ERR "ide-scsi: Strange, packet command " - "initiated yet DRQ isn't asserted\n"); + printk(KERN_ERR "%s: Strange, packet command initiated yet " + "DRQ isn't asserted\n", drive->name); return startstop; } ireason = hwif->INB(hwif->io_ports.nsect_addr); if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while " - "issuing a packet command\n"); + printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " + "a packet command\n", drive->name); return ide_do_reset (drive); } -- cgit v0.10.2 From 258ec4113081c2b63117dc2df6d94c3e484e9747 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:55 +0200 Subject: ide-tape: make idetape_retry_pc() void idetape_retry_pc() always returns ide_stopped so make it void. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8f10211..48fccf1 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -696,7 +696,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, * last packet command. We queue a request sense packet command in * the head of the request list. */ -static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) +static void idetape_retry_pc(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc; @@ -708,7 +708,6 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) idetape_create_request_sense_cmd(pc); set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags); idetape_queue_pc_head(drive, pc, rq); - return ide_stopped; } /* @@ -784,7 +783,8 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) pc->c[0]); /* Retry operation */ - return idetape_retry_pc(drive); + idetape_retry_pc(drive); + return ide_stopped; } pc->error = 0; if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && @@ -1078,7 +1078,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: I/O error, ", tape->name); /* Retry operation */ - return idetape_retry_pc(drive); + idetape_retry_pc(drive); + return ide_stopped; } pc->error = 0; if (tape->failed_pc == pc) -- cgit v0.10.2 From 5985e6abbd89f969c17fd80ab864c80f089827a3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:55 +0200 Subject: ide-tape: merge callbacks The appropriate functionality of the callback is established through querying the ATAPI packet command in pc->c[0]. While at it: - add uptodate variable + leave just one idetape_end_request() call - don't use HWGROUP() macro Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 48fccf1..d387aaf 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -503,18 +503,6 @@ static struct request *idetape_next_rq_storage(ide_drive_t *drive) return (&tape->rq_stack[tape->rq_stack_index++]); } -static void idetape_init_pc(struct ide_atapi_pc *pc) -{ - memset(pc->c, 0, 12); - pc->retries = 0; - pc->flags = 0; - pc->req_xfer = 0; - pc->buf = pc->pc_buf; - pc->buf_size = IDETAPE_PC_BUFFER_SIZE; - pc->bh = NULL; - pc->b_data = NULL; -} - /* * called on each failed packet command retry to analyze the request sense. We * currently do not utilize this information. @@ -631,30 +619,85 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) return 0; } -static ide_startstop_t idetape_request_sense_callback(ide_drive_t *drive) +static ide_startstop_t ide_tape_callback(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; + struct ide_atapi_pc *pc = tape->pc; + int uptodate = pc->error ? 0 : 1; debug_log(DBG_PROCS, "Enter %s\n", __func__); - if (!tape->pc->error) { - idetape_analyze_error(drive, tape->pc->buf); - idetape_end_request(drive, 1, 0); - } else { - printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - " - "Aborting request!\n"); - idetape_end_request(drive, 0, 0); + if (pc->c[0] == REQUEST_SENSE) { + if (uptodate) + idetape_analyze_error(drive, pc->buf); + else + printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " + "itself - Aborting request!\n"); + } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { + struct request *rq = drive->hwif->hwgroup->rq; + int blocks = pc->xferred / tape->blk_size; + + tape->avg_size += blocks * tape->blk_size; + + if (time_after_eq(jiffies, tape->avg_time + HZ)) { + tape->avg_speed = tape->avg_size * HZ / + (jiffies - tape->avg_time) / 1024; + tape->avg_size = 0; + tape->avg_time = jiffies; + } + + tape->first_frame += blocks; + rq->current_nr_sectors -= blocks; + + if (pc->error) + uptodate = pc->error; + } else if (pc->c[0] == READ_POSITION && uptodate) { + u8 *readpos = tape->pc->buf; + + debug_log(DBG_SENSE, "BOP - %s\n", + (readpos[0] & 0x80) ? "Yes" : "No"); + debug_log(DBG_SENSE, "EOP - %s\n", + (readpos[0] & 0x40) ? "Yes" : "No"); + + if (readpos[0] & 0x4) { + printk(KERN_INFO "ide-tape: Block location is unknown" + "to the tape\n"); + clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); + uptodate = 0; + } else { + debug_log(DBG_SENSE, "Block Location - %u\n", + be32_to_cpu(*(u32 *)&readpos[4])); + + tape->partition = readpos[1]; + tape->first_frame = be32_to_cpu(*(u32 *)&readpos[4]); + set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); + } } + + idetape_end_request(drive, uptodate, 0); + return ide_stopped; } +static void idetape_init_pc(struct ide_atapi_pc *pc) +{ + memset(pc->c, 0, 12); + pc->retries = 0; + pc->flags = 0; + pc->req_xfer = 0; + pc->buf = pc->pc_buf; + pc->buf_size = IDETAPE_PC_BUFFER_SIZE; + pc->bh = NULL; + pc->b_data = NULL; + pc->idetape_callback = ide_tape_callback; +} + static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) { idetape_init_pc(pc); pc->c[0] = REQUEST_SENSE; pc->c[4] = 20; pc->req_xfer = 20; - pc->idetape_callback = &idetape_request_sense_callback; } static void idetape_init_rq(struct request *rq, u8 cmd) @@ -1025,16 +1068,6 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, } } -static ide_startstop_t idetape_pc_callback(ide_drive_t *drive) -{ - idetape_tape_t *tape = drive->driver_data; - - debug_log(DBG_PROCS, "Enter %s\n", __func__); - - idetape_end_request(drive, tape->pc->error ? 0 : 1, 0); - return ide_stopped; -} - /* A mode sense command is used to "sense" tape parameters. */ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) { @@ -1060,7 +1093,6 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) pc->req_xfer = 24; else pc->req_xfer = 50; - pc->idetape_callback = &idetape_pc_callback; } static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) @@ -1091,32 +1123,6 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) return pc->idetape_callback(drive); } -static ide_startstop_t idetape_rw_callback(ide_drive_t *drive) -{ - idetape_tape_t *tape = drive->driver_data; - struct request *rq = HWGROUP(drive)->rq; - int blocks = tape->pc->xferred / tape->blk_size; - - tape->avg_size += blocks * tape->blk_size; - - if (time_after_eq(jiffies, tape->avg_time + HZ)) { - tape->avg_speed = tape->avg_size * HZ / - (jiffies - tape->avg_time) / 1024; - tape->avg_size = 0; - tape->avg_time = jiffies; - } - debug_log(DBG_PROCS, "Enter %s\n", __func__); - - tape->first_frame += blocks; - rq->current_nr_sectors -= blocks; - - if (!tape->pc->error) - idetape_end_request(drive, 1, 0); - else - idetape_end_request(drive, tape->pc->error, 0); - return ide_stopped; -} - static void idetape_create_read_cmd(idetape_tape_t *tape, struct ide_atapi_pc *pc, unsigned int length, struct idetape_bh *bh) @@ -1125,7 +1131,6 @@ static void idetape_create_read_cmd(idetape_tape_t *tape, pc->c[0] = READ_6; put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->idetape_callback = &idetape_rw_callback; pc->bh = bh; atomic_set(&bh->b_count, 0); pc->buf = NULL; @@ -1143,7 +1148,6 @@ static void idetape_create_write_cmd(idetape_tape_t *tape, pc->c[0] = WRITE_6; put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->idetape_callback = &idetape_rw_callback; pc->flags |= PC_FLAG_WRITING; pc->bh = bh; pc->b_data = bh->b_data; @@ -1412,40 +1416,6 @@ static void idetape_init_merge_buffer(idetape_tape_t *tape) } } -static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive) -{ - idetape_tape_t *tape = drive->driver_data; - u8 *readpos = tape->pc->buf; - - debug_log(DBG_PROCS, "Enter %s\n", __func__); - - if (!tape->pc->error) { - debug_log(DBG_SENSE, "BOP - %s\n", - (readpos[0] & 0x80) ? "Yes" : "No"); - debug_log(DBG_SENSE, "EOP - %s\n", - (readpos[0] & 0x40) ? "Yes" : "No"); - - if (readpos[0] & 0x4) { - printk(KERN_INFO "ide-tape: Block location is unknown" - "to the tape\n"); - clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); - idetape_end_request(drive, 0, 0); - } else { - debug_log(DBG_SENSE, "Block Location - %u\n", - be32_to_cpu(*(u32 *)&readpos[4])); - - tape->partition = readpos[1]; - tape->first_frame = - be32_to_cpu(*(u32 *)&readpos[4]); - set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags); - idetape_end_request(drive, 1, 0); - } - } else { - idetape_end_request(drive, 0, 0); - } - return ide_stopped; -} - /* * Write a filemark if write_filemark=1. Flush the device buffers without * writing a filemark otherwise. @@ -1457,14 +1427,12 @@ static void idetape_create_write_filemark_cmd(ide_drive_t *drive, pc->c[0] = WRITE_FILEMARKS; pc->c[4] = write_filemark; pc->flags |= PC_FLAG_WAIT_FOR_DSC; - pc->idetape_callback = &idetape_pc_callback; } static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) { idetape_init_pc(pc); pc->c[0] = TEST_UNIT_READY; - pc->idetape_callback = &idetape_pc_callback; } /* @@ -1502,7 +1470,6 @@ static void idetape_create_load_unload_cmd(ide_drive_t *drive, pc->c[0] = START_STOP; pc->c[4] = cmd; pc->flags |= PC_FLAG_WAIT_FOR_DSC; - pc->idetape_callback = &idetape_pc_callback; } static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) @@ -1554,7 +1521,6 @@ static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) idetape_init_pc(pc); pc->c[0] = READ_POSITION; pc->req_xfer = 20; - pc->idetape_callback = &idetape_read_position_callback; } static int idetape_read_position(ide_drive_t *drive) @@ -1582,7 +1548,6 @@ static void idetape_create_locate_cmd(ide_drive_t *drive, put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]); pc->c[8] = partition; pc->flags |= PC_FLAG_WAIT_FOR_DSC; - pc->idetape_callback = &idetape_pc_callback; } static int idetape_create_prevent_cmd(ide_drive_t *drive, @@ -1597,7 +1562,6 @@ static int idetape_create_prevent_cmd(ide_drive_t *drive, idetape_init_pc(pc); pc->c[0] = ALLOW_MEDIUM_REMOVAL; pc->c[4] = prevent; - pc->idetape_callback = &idetape_pc_callback; return 1; } @@ -1704,7 +1668,6 @@ static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) pc->c[0] = INQUIRY; pc->c[4] = 254; pc->req_xfer = 254; - pc->idetape_callback = &idetape_pc_callback; } static void idetape_create_rewind_cmd(ide_drive_t *drive, @@ -1713,7 +1676,6 @@ static void idetape_create_rewind_cmd(ide_drive_t *drive, idetape_init_pc(pc); pc->c[0] = REZERO_UNIT; pc->flags |= PC_FLAG_WAIT_FOR_DSC; - pc->idetape_callback = &idetape_pc_callback; } static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) @@ -1722,7 +1684,6 @@ static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) pc->c[0] = ERASE; pc->c[1] = 1; pc->flags |= PC_FLAG_WAIT_FOR_DSC; - pc->idetape_callback = &idetape_pc_callback; } static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) @@ -1732,7 +1693,6 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]); pc->c[1] = cmd; pc->flags |= PC_FLAG_WAIT_FOR_DSC; - pc->idetape_callback = &idetape_pc_callback; } /* Queue up a character device originated write request. */ -- cgit v0.10.2 From 92f5daff2b8439fa4c57c57f47823ffc459c3bd9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:55 +0200 Subject: ide-tape: make pc->idetape_callback void There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d387aaf..88d26ef 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -619,7 +619,7 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) return 0; } -static ide_startstop_t ide_tape_callback(ide_drive_t *drive) +static void ide_tape_callback(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = tape->pc; @@ -675,8 +675,6 @@ static ide_startstop_t ide_tape_callback(ide_drive_t *drive) } idetape_end_request(drive, uptodate, 0); - - return ide_stopped; } static void idetape_init_pc(struct ide_atapi_pc *pc) @@ -843,7 +841,8 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) if (tape->failed_pc == pc) tape->failed_pc = NULL; /* Command finished - Call the callback function */ - return pc->idetape_callback(drive); + pc->idetape_callback(drive); + return ide_stopped; } if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { @@ -1035,7 +1034,8 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->error = IDETAPE_ERROR_GENERAL; } tape->failed_pc = NULL; - return pc->idetape_callback(drive); + pc->idetape_callback(drive); + return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); @@ -1120,7 +1120,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) pc->error = IDETAPE_ERROR_GENERAL; tape->failed_pc = NULL; } - return pc->idetape_callback(drive); + pc->idetape_callback(drive); + return ide_stopped; } static void idetape_create_read_cmd(idetape_tape_t *tape, diff --git a/include/linux/ide.h b/include/linux/ide.h index 04267dc..8936b21 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -641,7 +641,7 @@ struct ide_atapi_pc { */ u8 pc_buf[256]; void (*idefloppy_callback) (ide_drive_t *); - ide_startstop_t (*idetape_callback) (ide_drive_t *); + void (*idetape_callback) (ide_drive_t *); /* idetape only */ struct idetape_bh *bh; -- cgit v0.10.2 From 81f4938239fea86d0a7529194a37fb81041171e0 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: ide-floppy: merge callbacks The appropriate functionality of the callback is established through querying the ATAPI packet command in pc->c[0]. While at it, simplify if (floppy->failed_pc)-branch to be found in the original idefloppy_request_sense_callback(). Bart: - keep handling for blk_pc_request() requests unchanged + add FIXME - add uptodate variable + leave just one idefloppy_end_request() call - add newline to the debug message Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index dae1c90..2058a6f 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -312,50 +312,38 @@ static struct request *idefloppy_next_rq_storage(ide_drive_t *drive) return (&floppy->rq_stack[floppy->rq_stack_index++]); } -static void idefloppy_request_sense_callback(ide_drive_t *drive) +static void ide_floppy_callback(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - u8 *buf = floppy->pc->buf; + struct ide_atapi_pc *pc = floppy->pc; + int uptodate = pc->error ? 0 : 1; debug_log("Reached %s\n", __func__); - if (!floppy->pc->error) { - floppy->sense_key = buf[2] & 0x0F; - floppy->asc = buf[12]; - floppy->ascq = buf[13]; - floppy->progress_indication = buf[15] & 0x80 ? - (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; + if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || + (pc->rq && blk_pc_request(pc->rq))) + uptodate = 1; /* FIXME */ + else if (pc->c[0] == GPCMD_REQUEST_SENSE) { + u8 *buf = floppy->pc->buf; - if (floppy->failed_pc) - debug_log("pc = %x, sense key = %x, asc = %x," - " ascq = %x\n", - floppy->failed_pc->c[0], - floppy->sense_key, - floppy->asc, - floppy->ascq); - else - debug_log("sense key = %x, asc = %x, ascq = %x\n", - floppy->sense_key, - floppy->asc, - floppy->ascq); + if (!pc->error) { + floppy->sense_key = buf[2] & 0x0F; + floppy->asc = buf[12]; + floppy->ascq = buf[13]; + floppy->progress_indication = buf[15] & 0x80 ? + (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; + if (floppy->failed_pc) + debug_log("pc = %x, ", floppy->failed_pc->c[0]); - idefloppy_end_request(drive, 1, 0); - } else { - printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting" - " request!\n"); - idefloppy_end_request(drive, 0, 0); + debug_log("sense key = %x, asc = %x, ascq = %x\n", + floppy->sense_key, floppy->asc, floppy->ascq); + } else + printk(KERN_ERR "Error in REQUEST SENSE itself - " + "Aborting request!\n"); } -} -/* General packet command callback function. */ -static void idefloppy_pc_callback(ide_drive_t *drive) -{ - idefloppy_floppy_t *floppy = drive->driver_data; - - debug_log("Reached %s\n", __func__); - - idefloppy_end_request(drive, floppy->pc->error ? 0 : 1, 0); + idefloppy_end_request(drive, uptodate, 0); } static void idefloppy_init_pc(struct ide_atapi_pc *pc) @@ -366,7 +354,7 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc) pc->req_xfer = 0; pc->buf = pc->pc_buf; pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; - pc->idefloppy_callback = &idefloppy_pc_callback; + pc->idefloppy_callback = &ide_floppy_callback; } static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) @@ -375,7 +363,6 @@ static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) pc->c[0] = GPCMD_REQUEST_SENSE; pc->c[4] = 255; pc->req_xfer = 18; - pc->idefloppy_callback = &idefloppy_request_sense_callback; } /* @@ -668,14 +655,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, } } -static void idefloppy_rw_callback(ide_drive_t *drive) -{ - debug_log("Reached %s\n", __func__); - - idefloppy_end_request(drive, 1, 0); - return; -} - static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) { debug_log("creating prevent removal command, prevent = %d\n", prevent); @@ -770,7 +749,6 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); - pc->idefloppy_callback = &idefloppy_rw_callback; pc->rq = rq; pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; if (rq->cmd_flags & REQ_RW) @@ -784,7 +762,6 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, struct ide_atapi_pc *pc, struct request *rq) { idefloppy_init_pc(pc); - pc->idefloppy_callback = &idefloppy_rw_callback; memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; pc->b_count = rq->data_len; -- cgit v0.10.2 From 1b06e92aa03018e4b3ba281e03a7711d9b71a998 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: ide-{floppy,tape}: merge pc->idefloppy_callback and pc->idetape_callback Merge pc->idefloppy_callback and pc->idetape_callback into pc->callback. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 2058a6f..a9f3127 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -354,7 +354,7 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc) pc->req_xfer = 0; pc->buf = pc->pc_buf; pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; - pc->idefloppy_callback = &ide_floppy_callback; + pc->callback = ide_floppy_callback; } static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) @@ -438,7 +438,7 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) if (floppy->failed_pc == pc) floppy->failed_pc = NULL; /* Command finished - Call the callback function */ - pc->idefloppy_callback(drive); + pc->callback(drive); return ide_stopped; } @@ -612,7 +612,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, pc->error = IDEFLOPPY_ERROR_GENERAL; floppy->failed_pc = NULL; - pc->idefloppy_callback(drive); + pc->callback(drive); return ide_stopped; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 88d26ef..ce9b6d3 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -687,7 +687,7 @@ static void idetape_init_pc(struct ide_atapi_pc *pc) pc->buf_size = IDETAPE_PC_BUFFER_SIZE; pc->bh = NULL; pc->b_data = NULL; - pc->idetape_callback = ide_tape_callback; + pc->callback = ide_tape_callback; } static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc) @@ -841,7 +841,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) if (tape->failed_pc == pc) tape->failed_pc = NULL; /* Command finished - Call the callback function */ - pc->idetape_callback(drive); + pc->callback(drive); return ide_stopped; } @@ -1034,7 +1034,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->error = IDETAPE_ERROR_GENERAL; } tape->failed_pc = NULL; - pc->idetape_callback(drive); + pc->callback(drive); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); @@ -1120,7 +1120,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) pc->error = IDETAPE_ERROR_GENERAL; tape->failed_pc = NULL; } - pc->idetape_callback(drive); + pc->callback(drive); return ide_stopped; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 8936b21..f079456 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -640,8 +640,8 @@ struct ide_atapi_pc { * to change/removal later. */ u8 pc_buf[256]; - void (*idefloppy_callback) (ide_drive_t *); - void (*idetape_callback) (ide_drive_t *); + + void (*callback)(ide_drive_t *); /* idetape only */ struct idetape_bh *bh; -- cgit v0.10.2 From 5e3310958204912f3f00be2592c945fbc37db6ae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: ide-{floppy,tape}: PC_FLAG_DMA_RECOMMENDED -> PC_FLAG_DMA_OK * Use PC_FLAG_DMA_OK flag instead of PC_FLAG_DMA_RECOMMENDED one. * Remove no longer used PC_FLAG_DMA_RECOMMENDED flag. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index a9f3127..dbefe35 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -630,7 +630,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, } dma = 0; - if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) + if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) dma = !hwif->dma_ops->dma_setup(drive); ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma); @@ -755,7 +755,7 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, pc->flags |= PC_FLAG_WRITING; pc->buf = NULL; pc->req_xfer = pc->buf_size = blocks * floppy->block_size; - pc->flags |= PC_FLAG_DMA_RECOMMENDED; + pc->flags |= PC_FLAG_DMA_OK; } static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, @@ -769,7 +769,7 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, pc->flags |= PC_FLAG_WRITING; pc->buf = rq->data; if (rq->bio) - pc->flags |= PC_FLAG_DMA_RECOMMENDED; + pc->flags |= PC_FLAG_DMA_OK; /* * possibly problematic, doesn't look like ide-floppy correctly * handled scattered requests if dma fails... diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ce9b6d3..e8a5852 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1050,7 +1050,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->flags &= ~PC_FLAG_DMA_ERROR; ide_dma_off(drive); } - if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) + if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) dma_ok = !hwif->dma_ops->dma_setup(drive); ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); @@ -1138,7 +1138,7 @@ static void idetape_create_read_cmd(idetape_tape_t *tape, pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; if (pc->req_xfer == tape->buffer_size) - pc->flags |= PC_FLAG_DMA_RECOMMENDED; + pc->flags |= PC_FLAG_DMA_OK; } static void idetape_create_write_cmd(idetape_tape_t *tape, @@ -1157,7 +1157,7 @@ static void idetape_create_write_cmd(idetape_tape_t *tape, pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; if (pc->req_xfer == tape->buffer_size) - pc->flags |= PC_FLAG_DMA_RECOMMENDED; + pc->flags |= PC_FLAG_DMA_OK; } static ide_startstop_t idetape_do_request(ide_drive_t *drive, diff --git a/include/linux/ide.h b/include/linux/ide.h index f079456..63cee29 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -602,12 +602,11 @@ enum { PC_FLAG_SUPPRESS_ERROR = (1 << 1), PC_FLAG_WAIT_FOR_DSC = (1 << 2), PC_FLAG_DMA_OK = (1 << 3), - PC_FLAG_DMA_RECOMMENDED = (1 << 4), - PC_FLAG_DMA_IN_PROGRESS = (1 << 5), - PC_FLAG_DMA_ERROR = (1 << 6), - PC_FLAG_WRITING = (1 << 7), + PC_FLAG_DMA_IN_PROGRESS = (1 << 4), + PC_FLAG_DMA_ERROR = (1 << 5), + PC_FLAG_WRITING = (1 << 6), /* command timed out */ - PC_FLAG_TIMEDOUT = (1 << 8), + PC_FLAG_TIMEDOUT = (1 << 7), }; struct ide_atapi_pc { -- cgit v0.10.2 From 6ffb66410dd9f5f383d9265d51ab667333a8296c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:56 +0200 Subject: ide-floppy: start DMA engine in idefloppy_transfer_pc1() Start DMA engine and set PC_FLAG_DMA_IN_PROGRESS flag in idefloppy_transfer_pc1() instead of idefloppy_issue_pc() so the Status Register and the Interrupt Reason Register are checked first. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index dbefe35..1df6a31 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -534,6 +534,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; idefloppy_floppy_t *floppy = drive->driver_data; + struct ide_atapi_pc *pc = floppy->pc; ide_expiry_t *expiry; unsigned int timeout; ide_startstop_t startstop; @@ -568,6 +569,12 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry); + /* Begin DMA, if necessary */ + if (pc->flags & PC_FLAG_DMA_OK) { + pc->flags |= PC_FLAG_DMA_IN_PROGRESS; + hwif->dma_ops->dma_start(drive); + } + if ((floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) == 0) /* Send the actual packet */ hwif->output_data(drive, NULL, floppy->pc->c, 12); @@ -633,13 +640,10 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) dma = !hwif->dma_ops->dma_setup(drive); - ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma); + if (!dma) + pc->flags &= ~PC_FLAG_DMA_OK; - if (dma) { - /* Begin DMA, if necessary */ - pc->flags |= PC_FLAG_DMA_IN_PROGRESS; - hwif->dma_ops->dma_start(drive); - } + ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma); if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) { /* Issue the packet command */ -- cgit v0.10.2 From 9fd13a27c8a35ff1986793cb96aaedb5e75b5368 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: ide-tape: set PC_FLAG_DMA_IN_PROGRESS flag in idetape_transfer_pc() Set PC_FLAG_DMA_IN_PROGRESS flag in idetape_transfer_pc() instead of idetape_issue_pc() to match the other ATAPI device drivers. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index e8a5852..1ce8b31 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -984,8 +984,10 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Begin DMA, if necessary */ - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) + if (pc->flags & PC_FLAG_DMA_OK) { + pc->flags |= PC_FLAG_DMA_IN_PROGRESS; hwif->dma_ops->dma_start(drive); + } /* Send the actual packet */ hwif->output_data(drive, NULL, pc->c, 12); @@ -1053,11 +1055,11 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) dma_ok = !hwif->dma_ops->dma_setup(drive); + if (!dma_ok) + pc->flags &= ~PC_FLAG_DMA_OK; + ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); - if (dma_ok) - /* Will begin DMA later */ - pc->flags |= PC_FLAG_DMA_IN_PROGRESS; if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags)) { ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); -- cgit v0.10.2 From 5a7b75ab429e9ed568be50cfbf7091f097457cb8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: ide-tape: factor out waiting for good ireason from idetape_transfer_pc() Factor out waiting for good ireason from idetape_transfer_pc() to ide_tape_wait_ireason() as a preparation for adding generic ide_transfer_pc() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1ce8b31..63b837e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -947,21 +947,12 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) * again, the callback function will be called and then we will handle the next * request. */ -static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) + +static u8 ide_tape_wait_ireason(ide_drive_t *drive, u8 ireason) { ide_hwif_t *hwif = drive->hwif; - idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = tape->pc; int retries = 100; - ide_startstop_t startstop; - u8 ireason; - if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { - printk(KERN_ERR "%s: Strange, packet command initiated yet " - "DRQ isn't asserted\n", drive->name); - return startstop; - } - ireason = hwif->INB(hwif->io_ports.nsect_addr); while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " "a packet command, retrying\n", drive->name); @@ -975,6 +966,27 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) ireason &= ~IO; } } + + return ireason; +} + +static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + idetape_tape_t *tape = drive->driver_data; + struct ide_atapi_pc *pc = tape->pc; + ide_startstop_t startstop; + u8 ireason; + + if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { + printk(KERN_ERR "%s: Strange, packet command initiated yet " + "DRQ isn't asserted\n", drive->name); + return startstop; + } + + ireason = hwif->INB(hwif->io_ports.nsect_addr); + ireason = ide_tape_wait_ireason(drive, ireason); + if ((ireason & CD) == 0 || (ireason & IO)) { printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " "a packet command\n", drive->name); -- cgit v0.10.2 From 5d41893c0f9caf94b449eada0279a08c86f0212e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: ide: add PC_FLAG_ZIP_DRIVE pc flag Add PC_FLAG_ZIP_DRIVE pc flag, set it in idefloppy_do_request() and check for it (instead of checking for IDEFLOPPY_FLAG_ZIP_DRIVE) in idefloppy_transfer_pc(). This is a preparation for adding generic ide_transfer_pc() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 1df6a31..cff90c4 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -559,7 +559,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) * 40 and 50msec work well. idefloppy_pc_intr will not be actually * used until after the packet is moved in about 50 msec. */ - if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) { + if (pc->flags & PC_FLAG_ZIP_DRIVE) { timeout = floppy->ticks; expiry = &idefloppy_transfer_pc2; } else { @@ -575,7 +575,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) hwif->dma_ops->dma_start(drive); } - if ((floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) == 0) + if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0) /* Send the actual packet */ hwif->output_data(drive, NULL, floppy->pc->c, 12); @@ -826,7 +826,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, return ide_stopped; } + if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) + pc->flags |= PC_FLAG_ZIP_DRIVE; + pc->rq = rq; + return idefloppy_issue_pc(drive, pc); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 63cee29..89feaea 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -607,6 +607,7 @@ enum { PC_FLAG_WRITING = (1 << 6), /* command timed out */ PC_FLAG_TIMEDOUT = (1 << 7), + PC_FLAG_ZIP_DRIVE = (1 << 8), }; struct ide_atapi_pc { -- cgit v0.10.2 From 794cc6804bb946826b7427d205ac391a5370d361 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:57 +0200 Subject: ide-{cd,floppy,tape}: remove checking for drive->scsi Remove checking for drive->scsi which is no longer set by IDE core code (leave the flag since it will be re-used for generic ATAPI support). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 043129c..d998471 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2106,11 +2106,6 @@ static int ide_cd_probe(ide_drive_t *drive) goto failed; } } - if (drive->scsi) { - printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi " - "emulation.\n", drive->name); - goto failed; - } info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); if (info == NULL) { printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index cff90c4..a7c138d 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -1579,11 +1579,6 @@ static int ide_floppy_probe(ide_drive_t *drive) " of ide-floppy\n", drive->name); goto failed; } - if (drive->scsi) { - printk(KERN_INFO "ide-floppy: passing drive %s to ide-scsi" - " emulation.\n", drive->name); - goto failed; - } floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); if (!floppy) { printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 63b837e..2a36213 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2850,11 +2850,6 @@ static int ide_tape_probe(ide_drive_t *drive) " the driver\n", drive->name); goto failed; } - if (drive->scsi) { - printk(KERN_INFO "ide-tape: passing drive %s to ide-scsi" - " emulation.\n", drive->name); - goto failed; - } tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL); if (tape == NULL) { printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n", -- cgit v0.10.2 From f83cbc77b0d5521b4f0f591ede4870316944481a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:58 +0200 Subject: ide-scsi: set drive->scsi flag for devices handled by the driver This is a preparation for adding generic ide_transfer_pc() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 5b8a193..c9fdf60 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -629,6 +629,8 @@ static void ide_scsi_remove(ide_drive_t *drive) put_disk(g); ide_scsi_put(scsi); + + drive->scsi = 0; } static int ide_scsi_probe(ide_drive_t *); @@ -969,6 +971,8 @@ static int ide_scsi_probe(ide_drive_t *drive) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) return -ENODEV; + drive->scsi = 1; + g = alloc_disk(1 << PARTN_BITS); if (!g) goto out_host_put; @@ -1009,6 +1013,7 @@ static int ide_scsi_probe(ide_drive_t *drive) put_disk(g); out_host_put: + drive->scsi = 0; scsi_host_put(host); return err; } -- cgit v0.10.2 From 594c16d8dd54cd7b1c5ef1ec3ac0f6bf34301dad Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:58 +0200 Subject: ide: add ide_transfer_pc() helper * Add ide-atapi.c file for generic ATAPI support together with CONFIG_IDE_ATAPI config option. * Add generic ide_transfer_pc() helper to ide-atapi.c and then convert ide-{floppy,tape,scsi} device drivers to use it. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1607536..cf707c8 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -98,6 +98,9 @@ if BLK_DEV_IDE comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" +config IDE_ATAPI + bool + config BLK_DEV_IDE_SATA bool "Support for SATA (deprecated; conflicts with libata SATA driver)" default n @@ -201,6 +204,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS config BLK_DEV_IDETAPE tristate "Include IDE/ATAPI TAPE support" + select IDE_ATAPI help If you have an IDE tape drive using the ATAPI protocol, say Y. ATAPI is a newer protocol used by IDE tape and CD-ROM drives, @@ -223,6 +227,7 @@ config BLK_DEV_IDETAPE config BLK_DEV_IDEFLOPPY tristate "Include IDE/ATAPI FLOPPY support" + select IDE_ATAPI ---help--- If you have an IDE floppy drive which uses the ATAPI protocol, answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy @@ -246,6 +251,7 @@ config BLK_DEV_IDEFLOPPY config BLK_DEV_IDESCSI tristate "SCSI emulation support" depends on SCSI + select IDE_ATAPI ---help--- WARNING: ide-scsi is no longer needed for cd writing applications! The 2.6 kernel supports direct writing to ide-cd, which eliminates diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index f94b679..a2b3f84 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -14,6 +14,7 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o # core IDE code +ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c new file mode 100644 index 0000000..25939bc --- /dev/null +++ b/drivers/ide/ide-atapi.c @@ -0,0 +1,70 @@ +/* + * ATAPI support. + */ + +#include +#include +#include + +static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) +{ + ide_hwif_t *hwif = drive->hwif; + int retries = 100; + + while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { + printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " + "a packet command, retrying\n", drive->name); + udelay(100); + ireason = hwif->INB(hwif->io_ports.nsect_addr); + if (retries == 0) { + printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " + "a packet command, ignoring\n", + drive->name); + ireason |= CD; + ireason &= ~IO; + } + } + + return ireason; +} + +ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, + ide_expiry_t *expiry) +{ + ide_hwif_t *hwif = drive->hwif; + ide_startstop_t startstop; + u8 ireason; + + if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { + printk(KERN_ERR "%s: Strange, packet command initiated yet " + "DRQ isn't asserted\n", drive->name); + return startstop; + } + + ireason = hwif->INB(hwif->io_ports.nsect_addr); + if (drive->media == ide_tape && !drive->scsi) + ireason = ide_wait_ireason(drive, ireason); + + if ((ireason & CD) == 0 || (ireason & IO)) { + printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " + "a packet command\n", drive->name); + return ide_do_reset(drive); + } + + /* Set the interrupt routine */ + ide_set_handler(drive, handler, timeout, expiry); + + /* Begin DMA, if necessary */ + if (pc->flags & PC_FLAG_DMA_OK) { + pc->flags |= PC_FLAG_DMA_IN_PROGRESS; + hwif->dma_ops->dma_start(drive); + } + + /* Send the actual packet */ + if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0) + hwif->output_data(drive, NULL, pc->c, 12); + + return ide_started; +} +EXPORT_SYMBOL_GPL(ide_transfer_pc); diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index a7c138d..e7a1025 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -532,25 +532,11 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; idefloppy_floppy_t *floppy = drive->driver_data; struct ide_atapi_pc *pc = floppy->pc; ide_expiry_t *expiry; unsigned int timeout; - ide_startstop_t startstop; - u8 ireason; - if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { - printk(KERN_ERR "%s: Strange, packet command initiated yet " - "DRQ isn't asserted\n", drive->name); - return startstop; - } - ireason = hwif->INB(hwif->io_ports.nsect_addr); - if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " - "a packet command\n", drive->name); - return ide_do_reset(drive); - } /* * The following delay solves a problem with ATAPI Zip 100 drives * where the Busy flag was apparently being deasserted before the @@ -567,19 +553,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) expiry = NULL; } - ide_set_handler(drive, &idefloppy_pc_intr, timeout, expiry); - - /* Begin DMA, if necessary */ - if (pc->flags & PC_FLAG_DMA_OK) { - pc->flags |= PC_FLAG_DMA_IN_PROGRESS; - hwif->dma_ops->dma_start(drive); - } - - if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0) - /* Send the actual packet */ - hwif->output_data(drive, NULL, floppy->pc->c, 12); - - return ide_started; + return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry); } static void ide_floppy_report_error(idefloppy_floppy_t *floppy, diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2a36213..5adc2c9 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -947,64 +947,12 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) * again, the callback function will be called and then we will handle the next * request. */ - -static u8 ide_tape_wait_ireason(ide_drive_t *drive, u8 ireason) -{ - ide_hwif_t *hwif = drive->hwif; - int retries = 100; - - while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { - printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " - "a packet command, retrying\n", drive->name); - udelay(100); - ireason = hwif->INB(hwif->io_ports.nsect_addr); - if (retries == 0) { - printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " - "a packet command, ignoring\n", - drive->name); - ireason |= CD; - ireason &= ~IO; - } - } - - return ireason; -} - static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = tape->pc; - ide_startstop_t startstop; - u8 ireason; - - if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { - printk(KERN_ERR "%s: Strange, packet command initiated yet " - "DRQ isn't asserted\n", drive->name); - return startstop; - } - - ireason = hwif->INB(hwif->io_ports.nsect_addr); - ireason = ide_tape_wait_ireason(drive, ireason); - if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " - "a packet command\n", drive->name); - return ide_do_reset(drive); - } - /* Set the interrupt routine */ - ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); - - /* Begin DMA, if necessary */ - if (pc->flags & PC_FLAG_DMA_OK) { - pc->flags |= PC_FLAG_DMA_IN_PROGRESS; - hwif->dma_ops->dma_start(drive); - } - - /* Send the actual packet */ - hwif->output_data(drive, NULL, pc->c, 12); - - return ide_started; + return ide_transfer_pc(drive, tape->pc, idetape_pc_intr, + IDETAPE_WAIT_CMD, NULL); } static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index c9fdf60..d41348f 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -453,36 +453,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; - ide_startstop_t startstop; - u8 ireason; - - if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { - printk(KERN_ERR "%s: Strange, packet command initiated yet " - "DRQ isn't asserted\n", drive->name); - return startstop; - } - ireason = hwif->INB(hwif->io_ports.nsect_addr); - if ((ireason & CD) == 0 || (ireason & IO)) { - printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " - "a packet command\n", drive->name); - return ide_do_reset (drive); - } - /* Set the interrupt routine */ - ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); - - if (pc->flags & PC_FLAG_DMA_OK) { - pc->flags |= PC_FLAG_DMA_IN_PROGRESS; - hwif->dma_ops->dma_start(drive); - } - - /* Send the actual packet */ - hwif->output_data(drive, NULL, scsi->pc->c, 12); - - return ide_started; + return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr, + get_timeout(scsi->pc), idescsi_expiry); } static inline int idescsi_set_direction(struct ide_atapi_pc *pc) diff --git a/include/linux/ide.h b/include/linux/ide.h index 89feaea..bed3c58 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -967,6 +967,9 @@ extern int drive_is_ready(ide_drive_t *); void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); +ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, + ide_handler_t *, unsigned int, ide_expiry_t *); + ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); void task_end_request(ide_drive_t *, struct request *, u8); -- cgit v0.10.2 From 4cc196897de9e6c02cf86debc5b9f7cf1b69a214 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:58 +0200 Subject: ide-scsi: move idescsi_map_sg() call out from idescsi_issue_pc() Move idescsi_map_sg() call out from idescsi_issue_pc() to idescsi_do_request() as a preparation to adding generic ide_issue_pc() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d41348f..1d26129 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -514,16 +514,16 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, /* Request to transfer the entire buffer at once */ bcount = min(pc->req_xfer, 63 * 1024); - if (drive->using_dma && !idescsi_map_sg(drive, pc)) { + if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { hwif->sg_mapped = 1; dma = !hwif->dma_ops->dma_setup(drive); hwif->sg_mapped = 0; } - ide_pktcmd_tf_load(drive, 0, bcount, dma); + if (!dma) + pc->flags &= ~PC_FLAG_DMA_OK; - if (dma) - pc->flags |= PC_FLAG_DMA_OK; + ide_pktcmd_tf_load(drive, 0, bcount, dma); if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc, @@ -547,8 +547,12 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r rq->sector, rq->nr_sectors, rq->current_nr_sectors); if (blk_sense_request(rq) || blk_special_request(rq)) { - return idescsi_issue_pc(drive, - (struct ide_atapi_pc *) rq->special); + struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; + + if (drive->using_dma && !idescsi_map_sg(drive, pc)) + pc->flags |= PC_FLAG_DMA_OK; + + return idescsi_issue_pc(drive, pc); } blk_dump_rq_flags(rq, "ide-scsi: unsup command"); idescsi_end_request (drive, 0, 0); -- cgit v0.10.2 From 28c7214bd8c2bbd4873b8f1e7f58d86d3731124f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:21:59 +0200 Subject: ide: add PC_FLAG_DRQ_INTERRUPT pc flag Add PC_FLAG_DRQ_INTERRUPT pc flag, set it in ide*_do_request() and check for it (instead of checking for IDE*_FLAG_DRQ_INTERRUPT) in ide*_issue_pc(). This is a preparation for adding generic ide_issue_pc() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index e7a1025..13f650f 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -619,7 +619,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma); - if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) { + if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { /* Issue the packet command */ ide_execute_command(drive, WIN_PACKETCMD, &idefloppy_transfer_pc1, @@ -800,6 +800,9 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, return ide_stopped; } + if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) + pc->flags |= PC_FLAG_DRQ_INTERRUPT; + if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) pc->flags |= PC_FLAG_ZIP_DRIVE; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 5adc2c9..cba18a6 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1020,7 +1020,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); - if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags)) { + if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); return ide_started; @@ -1143,8 +1143,10 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, } /* Retry a failed packet command */ - if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) - return idetape_issue_pc(drive, tape->failed_pc); + if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) { + pc = tape->failed_pc; + goto out; + } if (postponed_rq != NULL) if (rq != postponed_rq) { @@ -1216,6 +1218,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, } BUG(); out: + if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags)) + pc->flags |= PC_FLAG_DRQ_INTERRUPT; + return idetape_issue_pc(drive, pc); } diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 1d26129..b7c5e83 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -525,7 +525,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, ide_pktcmd_tf_load(drive, 0, bcount, dma); - if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { + if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc, get_timeout(pc), idescsi_expiry); return ide_started; @@ -548,6 +548,10 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r if (blk_sense_request(rq) || blk_special_request(rq)) { struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); + + if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) + pc->flags |= PC_FLAG_DRQ_INTERRUPT; if (drive->using_dma && !idescsi_map_sg(drive, pc)) pc->flags |= PC_FLAG_DMA_OK; diff --git a/include/linux/ide.h b/include/linux/ide.h index bed3c58..c2274ad 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -608,6 +608,7 @@ enum { /* command timed out */ PC_FLAG_TIMEDOUT = (1 << 7), PC_FLAG_ZIP_DRIVE = (1 << 8), + PC_FLAG_DRQ_INTERRUPT = (1 << 9), }; struct ide_atapi_pc { -- cgit v0.10.2 From 6bf1641ca1c7554f0da54aaf89788731b541bacc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:00 +0200 Subject: ide: add ide_issue_pc() helper Add generic ide_issue_pc() helper to ide-atapi.c and then convert ide-{floppy,tape,scsi} device drivers to use it. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 25939bc..932a83a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -68,3 +68,52 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, return ide_started; } EXPORT_SYMBOL_GPL(ide_transfer_pc); + +ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, + ide_expiry_t *expiry) +{ + ide_hwif_t *hwif = drive->hwif; + u16 bcount; + u8 dma = 0; + + /* We haven't transferred any data yet */ + pc->xferred = 0; + pc->cur_pos = pc->buf; + + /* Request to transfer the entire buffer at once */ + if (drive->media == ide_tape && !drive->scsi) + bcount = pc->req_xfer; + else + bcount = min(pc->req_xfer, 63 * 1024); + + if (pc->flags & PC_FLAG_DMA_ERROR) { + pc->flags &= ~PC_FLAG_DMA_ERROR; + ide_dma_off(drive); + } + + if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { + if (drive->scsi) + hwif->sg_mapped = 1; + dma = !hwif->dma_ops->dma_setup(drive); + if (drive->scsi) + hwif->sg_mapped = 0; + } + + if (!dma) + pc->flags &= ~PC_FLAG_DMA_OK; + + ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, + bcount, dma); + + /* Issue the packet command */ + if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { + ide_execute_command(drive, WIN_PACKETCMD, handler, + timeout, NULL); + return ide_started; + } else { + ide_execute_pkt_cmd(drive); + return (*handler)(drive); + } +} +EXPORT_SYMBOL_GPL(ide_issue_pc); diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 13f650f..e658aaf 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -576,9 +576,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { idefloppy_floppy_t *floppy = drive->driver_data; - ide_hwif_t *hwif = drive->hwif; - u16 bcount; - u8 dma; if (floppy->failed_pc == NULL && pc->c[0] != GPCMD_REQUEST_SENSE) @@ -600,37 +597,9 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, debug_log("Retry number - %d\n", pc->retries); pc->retries++; - /* We haven't transferred any data yet */ - pc->xferred = 0; - pc->cur_pos = pc->buf; - bcount = min(pc->req_xfer, 63 * 1024); - - if (pc->flags & PC_FLAG_DMA_ERROR) { - pc->flags &= ~PC_FLAG_DMA_ERROR; - ide_dma_off(drive); - } - dma = 0; - if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) - dma = !hwif->dma_ops->dma_setup(drive); - - if (!dma) - pc->flags &= ~PC_FLAG_DMA_OK; - - ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma); - - if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { - /* Issue the packet command */ - ide_execute_command(drive, WIN_PACKETCMD, - &idefloppy_transfer_pc1, - IDEFLOPPY_WAIT_CMD, - NULL); - return ide_started; - } else { - /* Issue the packet command */ - ide_execute_pkt_cmd(drive); - return idefloppy_transfer_pc1(drive); - } + return ide_issue_pc(drive, pc, idefloppy_transfer_pc1, + IDEFLOPPY_WAIT_CMD, NULL); } static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cba18a6..7907a1e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -958,10 +958,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { - ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; - int dma_ok = 0; - u16 bcount; if (tape->pc->c[0] == REQUEST_SENSE && pc->c[0] == REQUEST_SENSE) { @@ -1002,32 +999,9 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); pc->retries++; - /* We haven't transferred any data yet */ - pc->xferred = 0; - pc->cur_pos = pc->buf; - /* Request to transfer the entire buffer at once */ - bcount = pc->req_xfer; - - if (pc->flags & PC_FLAG_DMA_ERROR) { - pc->flags &= ~PC_FLAG_DMA_ERROR; - ide_dma_off(drive); - } - if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) - dma_ok = !hwif->dma_ops->dma_setup(drive); - - if (!dma_ok) - pc->flags &= ~PC_FLAG_DMA_OK; - - ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); - if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { - ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc, - IDETAPE_WAIT_CMD, NULL); - return ide_started; - } else { - ide_execute_pkt_cmd(drive); - return idetape_transfer_pc(drive); - } + return ide_issue_pc(drive, pc, idetape_transfer_pc, + IDETAPE_WAIT_CMD, NULL); } /* A mode sense command is used to "sense" tape parameters. */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index b7c5e83..3241546 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -502,38 +502,12 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); - ide_hwif_t *hwif = drive->hwif; - u16 bcount; - u8 dma = 0; /* Set the current packet command */ scsi->pc = pc; - /* We haven't transferred any data yet */ - pc->xferred = 0; - pc->cur_pos = pc->buf; - /* Request to transfer the entire buffer at once */ - bcount = min(pc->req_xfer, 63 * 1024); - - if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { - hwif->sg_mapped = 1; - dma = !hwif->dma_ops->dma_setup(drive); - hwif->sg_mapped = 0; - } - - if (!dma) - pc->flags &= ~PC_FLAG_DMA_OK; - ide_pktcmd_tf_load(drive, 0, bcount, dma); - - if (pc->flags & PC_FLAG_DRQ_INTERRUPT) { - ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc, - get_timeout(pc), idescsi_expiry); - return ide_started; - } else { - /* Issue the packet command */ - ide_execute_pkt_cmd(drive); - return idescsi_transfer_pc(drive); - } + return ide_issue_pc(drive, pc, idescsi_transfer_pc, + get_timeout(pc), idescsi_expiry); } /* diff --git a/include/linux/ide.h b/include/linux/ide.h index c2274ad..fee07a7 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -970,6 +970,8 @@ void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, ide_handler_t *, unsigned int, ide_expiry_t *); +ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *, + ide_handler_t *, unsigned int, ide_expiry_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -- cgit v0.10.2 From dd2e9a032bc552f6e2ae852e81cde602c09d7d3e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: ide-{floppy,tape}: move checking of ->failed_pc to ->callback Move checking/resetting of ->failed_pc from ide*_pc_intr() to ->callback as a preparation for adding generic ide_pc_intr() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index e658aaf..b1d6905 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -320,6 +320,9 @@ static void ide_floppy_callback(ide_drive_t *drive) debug_log("Reached %s\n", __func__); + if (floppy->failed_pc == pc) + floppy->failed_pc = NULL; + if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || (pc->rq && blk_pc_request(pc->rq))) uptodate = 1; /* FIXME */ @@ -435,8 +438,6 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) return ide_stopped; } pc->error = 0; - if (floppy->failed_pc == pc) - floppy->failed_pc = NULL; /* Command finished - Call the callback function */ pc->callback(drive); return ide_stopped; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7907a1e..0fec58e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -627,6 +627,9 @@ static void ide_tape_callback(ide_drive_t *drive) debug_log(DBG_PROCS, "Enter %s\n", __func__); + if (tape->failed_pc == pc) + tape->failed_pc = NULL; + if (pc->c[0] == REQUEST_SENSE) { if (uptodate) idetape_analyze_error(drive, pc->buf); @@ -838,8 +841,6 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) idetape_postpone_request(drive); return ide_stopped; } - if (tape->failed_pc == pc) - tape->failed_pc = NULL; /* Command finished - Call the callback function */ pc->callback(drive); return ide_stopped; @@ -1050,8 +1051,6 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) return ide_stopped; } pc->error = 0; - if (tape->failed_pc == pc) - tape->failed_pc = NULL; } else { pc->error = IDETAPE_ERROR_GENERAL; tape->failed_pc = NULL; -- cgit v0.10.2 From 74e63e74ea57e06839aa5fcf016eace35da26050 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: ide-tape: factor out DSC handling from idetape_pc_intr() Factor out DSC handling from idetape_pc_intr() to ide_tape_handle_dsc() helper as a preparation for adding generic ide_pc_intr() helper. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0fec58e..b224823 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -768,6 +768,18 @@ static void idetape_postpone_request(ide_drive_t *drive) ide_stall_queue(drive, tape->dsc_poll_freq); } +static void ide_tape_handle_dsc(ide_drive_t *drive) +{ + idetape_tape_t *tape = drive->driver_data; + + /* Media access command */ + tape->dsc_polling_start = jiffies; + tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; + tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; + /* Allow ide.c to handle other requests */ + idetape_postpone_request(drive); +} + typedef void idetape_io_buf(ide_drive_t *, struct ide_atapi_pc *, unsigned int); /* @@ -833,12 +845,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) pc->error = 0; if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & SEEK_STAT) == 0) { - /* Media access command */ - tape->dsc_polling_start = jiffies; - tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; - tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; - /* Allow ide.c to handle other requests */ - idetape_postpone_request(drive); + ide_tape_handle_dsc(drive); return ide_stopped; } /* Command finished - Call the callback function */ -- cgit v0.10.2 From 08424ac24a35b505463919a897b097f27e4dca96 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: ide-tape: add ide_tape_io_buffers() helper * Add ide_tape_io_buffers() helper which is a wrapper for idetape_{in,out}put_buffers() and convert idetape_pc_intr() to use it. * Remove no longer used idetape_io_buf typedef. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b224823..6801c68 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -780,7 +780,14 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) idetape_postpone_request(drive); } -typedef void idetape_io_buf(ide_drive_t *, struct ide_atapi_pc *, unsigned int); +static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, + unsigned int bcount, int write) +{ + if (write) + idetape_output_buffers(drive, pc, bcount); + else + idetape_input_buffers(drive, pc, bcount); +} /* * This is the usual interrupt handler which will be called during a packet @@ -795,7 +802,6 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = tape->pc; xfer_func_t *xferfunc; - idetape_io_buf *iobuf; unsigned int temp; u16 bcount; u8 stat, ireason; @@ -895,15 +901,14 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) debug_log(DBG_SENSE, "The device wants to send us more " "data than expected - allowing transfer\n"); } - iobuf = &idetape_input_buffers; xferfunc = hwif->input_data; } else { - iobuf = &idetape_output_buffers; xferfunc = hwif->output_data; } if (pc->bh) - iobuf(drive, pc, bcount); + ide_tape_io_buffers(drive, pc, bcount, + !!(pc->flags & PC_FLAG_WRITING)); else xferfunc(drive, NULL, pc->cur_pos, bcount); -- cgit v0.10.2 From 3e421d324c003f8f002f402141b15d758adbfaef Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:01 +0200 Subject: ide-tape: always log debug info in idetape_pc_intr() if debugging is enabled Add DBG_PC_INTR debug level and use it to always log debug info in idetape_pc_intr() if debugging is enabled. While at it: * Use drive->name instead of tape->name. * Log device name with "DMA finished" message. This is a preparation for adding generic ide_pc_intr() helper. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 6801c68..10f2d33 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -56,6 +56,8 @@ enum { DBG_PROCS = (1 << 3), /* buffer alloc info (pc_stack & rq_stack) */ DBG_PCRQ_STACK = (1 << 4), + /* IRQ handler (always log debug info if debugging is on) */ + DBG_PC_INTR = (1 << 5), }; /* define to see debug info */ @@ -64,7 +66,7 @@ enum { #if IDETAPE_DEBUG_LOG #define debug_log(lvl, fmt, args...) \ { \ - if (tape->debug_mask & lvl) \ + if ((lvl & DBG_PC_INTR) || (tape->debug_mask & lvl)) \ printk(KERN_INFO "ide-tape: " fmt, ## args); \ } #else @@ -806,7 +808,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) u16 bcount; u8 stat, ireason; - debug_log(DBG_PROCS, "Enter %s - interrupt handler\n", __func__); + debug_log(DBG_PC_INTR, "Enter %s - interrupt handler\n", __func__); /* Clear the interrupt */ stat = ide_read_status(drive); @@ -818,13 +820,12 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) pc->xferred = pc->req_xfer; idetape_update_buffers(pc); } - debug_log(DBG_PROCS, "DMA finished\n"); - + debug_log(DBG_PC_INTR, "%s: DMA finished\n", drive->name); } /* No more interrupts */ if ((stat & DRQ_STAT) == 0) { - debug_log(DBG_SENSE, "Packet command completed, %d bytes" + debug_log(DBG_PC_INTR, "Packet command completed, %d bytes" " transferred\n", pc->xferred); pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; @@ -834,14 +835,14 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) stat &= ~ERR_STAT; if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { /* Error detected */ - debug_log(DBG_ERR, "%s: I/O error\n", tape->name); + debug_log(DBG_PC_INTR, "%s: I/O error\n", drive->name); if (pc->c[0] == REQUEST_SENSE) { printk(KERN_ERR "%s: I/O error in request sense" " command\n", drive->name); return ide_do_reset(drive); } - debug_log(DBG_ERR, "[cmd %x]: check condition\n", + debug_log(DBG_PC_INTR, "[cmd %x]: check condition\n", pc->c[0]); /* Retry operation */ @@ -898,7 +899,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) IDETAPE_WAIT_CMD, NULL); return ide_started; } - debug_log(DBG_SENSE, "The device wants to send us more " + debug_log(DBG_PC_INTR, "The device wants to send us more " "data than expected - allowing transfer\n"); } xferfunc = hwif->input_data; @@ -916,7 +917,7 @@ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) pc->xferred += bcount; pc->cur_pos += bcount; - debug_log(DBG_SENSE, "[cmd %x] transferred %d bytes on that intr.\n", + debug_log(DBG_PC_INTR, "[cmd %x] transferred %d bytes on that intr.\n", pc->c[0], bcount); /* And set the interrupt handler again */ -- cgit v0.10.2 From 4c93067ea9e5eca9d975bec74dae641228ac1bbe Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:02 +0200 Subject: ide-floppy: add more debugging to idefloppy_pc_intr() Add more debugging to idefloppy_pc_intr() to match ide-tape's idetape_pc_intr(). While at it: * Correct the first debug message. * Log device name with "DMA finished" message. This is a preparation for adding generic ide_pc_intr() helper. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index b1d6905..502ef9d 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -397,7 +397,7 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) u16 bcount; u8 stat, ireason; - debug_log("Reached %s interrupt handler\n", __func__); + debug_log("Enter %s - interrupt handler\n", __func__); if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { dma_error = hwif->dma_ops->dma_end(drive); @@ -409,7 +409,7 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) pc->xferred = pc->req_xfer; idefloppy_update_buffers(drive, pc); } - debug_log("DMA finished\n"); + debug_log("%s: DMA finished\n", drive->name); } /* Clear the interrupt */ @@ -432,6 +432,9 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) " command\n", drive->name); return ide_do_reset(drive); } + + debug_log("[cmd %x]: check condition\n", pc->c[0]); + /* Retry operation */ idefloppy_retry_pc(drive); /* queued, but not started */ @@ -505,6 +508,9 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) pc->xferred += bcount; pc->cur_pos += bcount; + debug_log("[cmd %x] transferred %d bytes on that intr.\n", + pc->c[0], bcount); + /* And set the interrupt handler again */ ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); return ide_started; -- cgit v0.10.2 From c6b2d260b5a7a5ed32aa2ce370d81183fc37eeb1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:02 +0200 Subject: ide-scsi: use pc->callback * Add ide_scsi_callback() pc->callback implementation, then update idescsi_check_condition() and idescsi_queue() to setup ->callback. * Convert idescsi_pc_intr() to use pc->callback. This is a preparation for adding generic ide_pc_intr() helper. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 3241546..c0b39b9 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -183,6 +183,24 @@ static void ide_scsi_hex_dump(u8 *data, int len) print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); } +static int idescsi_end_request(ide_drive_t *, int, int); + +static void ide_scsi_callback(ide_drive_t *drive) +{ + idescsi_scsi_t *scsi = drive_to_idescsi(drive); + struct ide_atapi_pc *pc = scsi->pc; + + if (pc->flags & PC_FLAG_TIMEDOUT) + debug_log("%s: got timed out packet %lu at %lu\n", __func__, + pc->scsi_cmd->serial_number, jiffies); + /* end this request now - scsi should retry it*/ + else if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) + printk(KERN_INFO "Packet command completed, %d bytes" + " transferred\n", pc->xferred); + + idescsi_end_request(drive, 1, 0); +} + static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_cmd) { @@ -210,6 +228,7 @@ static int idescsi_check_condition(ide_drive_t *drive, rq->cmd_type = REQ_TYPE_SENSE; rq->cmd_flags |= REQ_PREEMPT; pc->timeout = jiffies + WAIT_READY; + pc->callback = ide_scsi_callback; /* NOTE! Save the failed packet command in "rq->buffer" */ rq->buffer = (void *) failed_cmd->special; pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd; @@ -222,8 +241,6 @@ static int idescsi_check_condition(ide_drive_t *drive, return 0; } -static int idescsi_end_request(ide_drive_t *, int, int); - static ide_startstop_t idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { @@ -350,10 +367,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) debug_log("Reached %s interrupt handler\n", __func__); if (pc->flags & PC_FLAG_TIMEDOUT) { - debug_log("%s: got timed out packet %lu at %lu\n", __func__, - pc->scsi_cmd->serial_number, jiffies); - /* end this request now - scsi should retry it*/ - idescsi_end_request (drive, 1, 0); + pc->callback(drive); return ide_stopped; } if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { @@ -369,14 +383,11 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) if ((stat & DRQ_STAT) == 0) { /* No more interrupts */ - if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) - printk(KERN_INFO "Packet command completed, %d bytes" - " transferred\n", pc->xferred); pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; local_irq_enable_in_hardirq(); if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) rq->errors++; - idescsi_end_request (drive, 1, 0); + pc->callback(drive); return ide_stopped; } if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { @@ -718,6 +729,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, pc->scsi_cmd = cmd; pc->done = done; pc->timeout = jiffies + cmd->timeout_per_command; + pc->callback = ide_scsi_callback; if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); -- cgit v0.10.2 From cdca5c1f3b769eb2cdfc9cadc254cb74ba73c7d6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:02 +0200 Subject: ide-scsi: add more debugging to idescsi_pc_intr() Add more debugging to idescsi_pc_intr() to match ide-tape's idetape_pc_intr(). While at it: * Correct the first debug message. This is a preparation for adding generic ide_pc_intr() helper. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index c0b39b9..ec9a5de 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -364,7 +364,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) u16 bcount; u8 stat, ireason; - debug_log("Reached %s interrupt handler\n", __func__); + debug_log("Enter %s - interrupt handler\n", __func__); if (pc->flags & PC_FLAG_TIMEDOUT) { pc->callback(drive); @@ -383,10 +383,16 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) if ((stat & DRQ_STAT) == 0) { /* No more interrupts */ + debug_log("Packet command completed, %d bytes transferred\n", + pc->xferred); pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; local_irq_enable_in_hardirq(); - if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) + if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { + /* Error detected */ + debug_log("%s: I/O error\n", drive->name); + rq->errors++; + } pc->callback(drive); return ide_stopped; } @@ -457,6 +463,9 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) pc->xferred += bcount; pc->cur_pos += bcount; + debug_log("[cmd %x] transferred %d bytes on that intr.\n", + pc->c[0], bcount); + /* And set the interrupt handler again */ ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); return ide_started; -- cgit v0.10.2 From 55d82bfa6763d6761670d740ab3bac2f1c042d87 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: ide-{floppy,scsi}: read Status Register before stopping DMA engine Read Status Register before stopping DMA engine to match ide-tape device driver - it should be safe and shouldn't affect anything. This is a preparation for adding generic ide_pc_intr() helper. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 502ef9d..70aef97 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -399,6 +399,9 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) debug_log("Enter %s - interrupt handler\n", __func__); + /* Clear the interrupt */ + stat = ide_read_status(drive); + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { dma_error = hwif->dma_ops->dma_end(drive); if (dma_error) { @@ -412,9 +415,6 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) debug_log("%s: DMA finished\n", drive->name); } - /* Clear the interrupt */ - stat = ide_read_status(drive); - /* No more interrupts */ if ((stat & DRQ_STAT) == 0) { debug_log("Packet command completed, %d bytes transferred\n", diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index ec9a5de..ada733c 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -370,6 +370,10 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) pc->callback(drive); return ide_stopped; } + + /* Clear the interrupt */ + stat = ide_read_status(drive); + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { if (hwif->dma_ops->dma_end(drive)) pc->flags |= PC_FLAG_DMA_ERROR; @@ -378,9 +382,6 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) debug_log("%s: DMA finished\n", drive->name); } - /* Clear the interrupt */ - stat = ide_read_status(drive); - if ((stat & DRQ_STAT) == 0) { /* No more interrupts */ debug_log("Packet command completed, %d bytes transferred\n", -- cgit v0.10.2 From 646c0cb6c430f8d3ad3769dd1518fe664ff0ce27 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: ide: add ide_pc_intr() helper * ide-tape.c: add 'drive' argument to idetape_update_buffers(). * Add generic ide_pc_intr() helper to ide-atapi.c and then convert ide-{floppy,tape,scsi} device drivers to use it. * ide-tape.c: remove no longer needed DBG_PC_INTR. There should be no functional changes caused by this patch (unless the debugging is explicitely compiled in). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 932a83a..2802031 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -5,6 +5,183 @@ #include #include #include +#include + +#ifdef DEBUG +#define debug_log(fmt, args...) \ + printk(KERN_INFO "ide: " fmt, ## args) +#else +#define debug_log(fmt, args...) do {} while (0) +#endif + +/* TODO: unify the code thus making some arguments go away */ +ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, + void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), + void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), + void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int)) +{ + ide_hwif_t *hwif = drive->hwif; + xfer_func_t *xferfunc; + unsigned int temp; + u16 bcount; + u8 stat, ireason, scsi = drive->scsi; + + debug_log("Enter %s - interrupt handler\n", __func__); + + if (pc->flags & PC_FLAG_TIMEDOUT) { + pc->callback(drive); + return ide_stopped; + } + + /* Clear the interrupt */ + stat = ide_read_status(drive); + + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { + if (hwif->dma_ops->dma_end(drive) || + (drive->media == ide_tape && !scsi && (stat & ERR_STAT))) { + if (drive->media == ide_floppy && !scsi) + printk(KERN_ERR "%s: DMA %s error\n", + drive->name, rq_data_dir(pc->rq) + ? "write" : "read"); + pc->flags |= PC_FLAG_DMA_ERROR; + } else { + pc->xferred = pc->req_xfer; + if (update_buffers) + update_buffers(drive, pc); + } + debug_log("%s: DMA finished\n", drive->name); + } + + /* No more interrupts */ + if ((stat & DRQ_STAT) == 0) { + debug_log("Packet command completed, %d bytes transferred\n", + pc->xferred); + + pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; + + local_irq_enable_in_hardirq(); + + if (drive->media == ide_tape && !scsi && + (stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE) + stat &= ~ERR_STAT; + if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { + /* Error detected */ + debug_log("%s: I/O error\n", drive->name); + + if (drive->media != ide_tape || scsi) { + pc->rq->errors++; + if (scsi) + goto cmd_finished; + } + + if (pc->c[0] == REQUEST_SENSE) { + printk(KERN_ERR "%s: I/O error in request sense" + " command\n", drive->name); + return ide_do_reset(drive); + } + + debug_log("[cmd %x]: check condition\n", pc->c[0]); + + /* Retry operation */ + retry_pc(drive); + /* queued, but not started */ + return ide_stopped; + } +cmd_finished: + pc->error = 0; + if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && + (stat & SEEK_STAT) == 0) { + dsc_handle(drive); + return ide_stopped; + } + /* Command finished - Call the callback function */ + pc->callback(drive); + return ide_stopped; + } + + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { + pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; + printk(KERN_ERR "%s: The device wants to issue more interrupts " + "in DMA mode\n", drive->name); + ide_dma_off(drive); + return ide_do_reset(drive); + } + /* Get the number of bytes to transfer on this interrupt. */ + bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | + hwif->INB(hwif->io_ports.lbam_addr); + + ireason = hwif->INB(hwif->io_ports.nsect_addr); + + if (ireason & CD) { + printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); + return ide_do_reset(drive); + } + if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { + /* Hopefully, we will never get here */ + printk(KERN_ERR "%s: We wanted to %s, but the device wants us " + "to %s!\n", drive->name, + (ireason & IO) ? "Write" : "Read", + (ireason & IO) ? "Read" : "Write"); + return ide_do_reset(drive); + } + if (!(pc->flags & PC_FLAG_WRITING)) { + /* Reading - Check that we have enough space */ + temp = pc->xferred + bcount; + if (temp > pc->req_xfer) { + if (temp > pc->buf_size) { + printk(KERN_ERR "%s: The device wants to send " + "us more data than expected - " + "discarding data\n", + drive->name); + if (scsi) + temp = pc->buf_size - pc->xferred; + else + temp = 0; + if (temp) { + if (pc->sg) + io_buffers(drive, pc, temp, 0); + else + hwif->input_data(drive, NULL, + pc->cur_pos, temp); + printk(KERN_ERR "%s: transferred %d of " + "%d bytes\n", + drive->name, + temp, bcount); + } + pc->xferred += temp; + pc->cur_pos += temp; + ide_pad_transfer(drive, 0, bcount - temp); + ide_set_handler(drive, handler, timeout, + expiry); + return ide_started; + } + debug_log("The device wants to send us more data than " + "expected - allowing transfer\n"); + } + xferfunc = hwif->input_data; + } else + xferfunc = hwif->output_data; + + if ((drive->media == ide_floppy && !scsi && !pc->buf) || + (drive->media == ide_tape && !scsi && pc->bh) || + (scsi && pc->sg)) + io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING)); + else + xferfunc(drive, NULL, pc->cur_pos, bcount); + + /* Update the current position */ + pc->xferred += bcount; + pc->cur_pos += bcount; + + debug_log("[cmd %x] transferred %d bytes on that intr.\n", + pc->c[0], bcount); + + /* And set the interrupt handler again */ + ide_set_handler(drive, handler, timeout, expiry); + return ide_started; +} +EXPORT_SYMBOL_GPL(ide_pc_intr); static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) { diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 70aef97..0f3602a 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -388,132 +388,10 @@ static void idefloppy_retry_pc(ide_drive_t *drive) static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - ide_hwif_t *hwif = drive->hwif; - struct ide_atapi_pc *pc = floppy->pc; - struct request *rq = pc->rq; - xfer_func_t *xferfunc; - unsigned int temp; - int dma_error = 0; - u16 bcount; - u8 stat, ireason; - - debug_log("Enter %s - interrupt handler\n", __func__); - - /* Clear the interrupt */ - stat = ide_read_status(drive); - - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - dma_error = hwif->dma_ops->dma_end(drive); - if (dma_error) { - printk(KERN_ERR "%s: DMA %s error\n", drive->name, - rq_data_dir(rq) ? "write" : "read"); - pc->flags |= PC_FLAG_DMA_ERROR; - } else { - pc->xferred = pc->req_xfer; - idefloppy_update_buffers(drive, pc); - } - debug_log("%s: DMA finished\n", drive->name); - } - - /* No more interrupts */ - if ((stat & DRQ_STAT) == 0) { - debug_log("Packet command completed, %d bytes transferred\n", - pc->xferred); - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - - local_irq_enable_in_hardirq(); - - if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { - /* Error detected */ - debug_log("%s: I/O error\n", drive->name); - rq->errors++; - if (pc->c[0] == GPCMD_REQUEST_SENSE) { - printk(KERN_ERR "%s: I/O error in request sense" - " command\n", drive->name); - return ide_do_reset(drive); - } - - debug_log("[cmd %x]: check condition\n", pc->c[0]); - - /* Retry operation */ - idefloppy_retry_pc(drive); - /* queued, but not started */ - return ide_stopped; - } - pc->error = 0; - /* Command finished - Call the callback function */ - pc->callback(drive); - return ide_stopped; - } - - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - printk(KERN_ERR "%s: The device wants to issue more interrupts " - "in DMA mode\n", drive->name); - ide_dma_off(drive); - return ide_do_reset(drive); - } - - /* Get the number of bytes to transfer */ - bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | - hwif->INB(hwif->io_ports.lbam_addr); - /* on this interrupt */ - ireason = hwif->INB(hwif->io_ports.nsect_addr); - - if (ireason & CD) { - printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); - return ide_do_reset(drive); - } - if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { - /* Hopefully, we will never get here */ - printk(KERN_ERR "%s: We wanted to %s, but the device wants us " - "to %s!\n", drive->name, - (ireason & IO) ? "Write" : "Read", - (ireason & IO) ? "Read" : "Write"); - return ide_do_reset(drive); - } - if (!(pc->flags & PC_FLAG_WRITING)) { - /* Reading - Check that we have enough space */ - temp = pc->xferred + bcount; - if (temp > pc->req_xfer) { - if (temp > pc->buf_size) { - printk(KERN_ERR "%s: The device wants to send " - "us more data than expected - " - "discarding data\n", - drive->name); - ide_pad_transfer(drive, 0, bcount); - - ide_set_handler(drive, - &idefloppy_pc_intr, - IDEFLOPPY_WAIT_CMD, - NULL); - return ide_started; - } - debug_log("The device wants to send us more data than " - "expected - allowing transfer\n"); - } - } - if (pc->flags & PC_FLAG_WRITING) - xferfunc = hwif->output_data; - else - xferfunc = hwif->input_data; - - if (pc->buf) - xferfunc(drive, NULL, pc->cur_pos, bcount); - else - ide_floppy_io_buffers(drive, pc, bcount, - !!(pc->flags & PC_FLAG_WRITING)); - - /* Update the current position */ - pc->xferred += bcount; - pc->cur_pos += bcount; - - debug_log("[cmd %x] transferred %d bytes on that intr.\n", - pc->c[0], bcount); - /* And set the interrupt handler again */ - ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); - return ide_started; + return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr, + IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers, + idefloppy_retry_pc, NULL, ide_floppy_io_buffers); } /* diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 10f2d33..0afa109 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -56,8 +56,6 @@ enum { DBG_PROCS = (1 << 3), /* buffer alloc info (pc_stack & rq_stack) */ DBG_PCRQ_STACK = (1 << 4), - /* IRQ handler (always log debug info if debugging is on) */ - DBG_PC_INTR = (1 << 5), }; /* define to see debug info */ @@ -66,7 +64,7 @@ enum { #if IDETAPE_DEBUG_LOG #define debug_log(lvl, fmt, args...) \ { \ - if ((lvl & DBG_PC_INTR) || (tape->debug_mask & lvl)) \ + if (tape->debug_mask & lvl) \ printk(KERN_INFO "ide-tape: " fmt, ## args); \ } #else @@ -441,7 +439,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, } } -static void idetape_update_buffers(struct ide_atapi_pc *pc) +static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct idetape_bh *bh = pc->bh; int count; @@ -526,7 +524,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) pc->xferred = pc->req_xfer - tape->blk_size * get_unaligned_be32(&sense[3]); - idetape_update_buffers(pc); + idetape_update_buffers(drive, pc); } /* @@ -800,129 +798,11 @@ static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, */ static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = tape->pc; - xfer_func_t *xferfunc; - unsigned int temp; - u16 bcount; - u8 stat, ireason; - - debug_log(DBG_PC_INTR, "Enter %s - interrupt handler\n", __func__); - - /* Clear the interrupt */ - stat = ide_read_status(drive); - - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - if (hwif->dma_ops->dma_end(drive) || (stat & ERR_STAT)) { - pc->flags |= PC_FLAG_DMA_ERROR; - } else { - pc->xferred = pc->req_xfer; - idetape_update_buffers(pc); - } - debug_log(DBG_PC_INTR, "%s: DMA finished\n", drive->name); - } - - /* No more interrupts */ - if ((stat & DRQ_STAT) == 0) { - debug_log(DBG_PC_INTR, "Packet command completed, %d bytes" - " transferred\n", pc->xferred); - - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - local_irq_enable_in_hardirq(); - - if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE) - stat &= ~ERR_STAT; - if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { - /* Error detected */ - debug_log(DBG_PC_INTR, "%s: I/O error\n", drive->name); - - if (pc->c[0] == REQUEST_SENSE) { - printk(KERN_ERR "%s: I/O error in request sense" - " command\n", drive->name); - return ide_do_reset(drive); - } - debug_log(DBG_PC_INTR, "[cmd %x]: check condition\n", - pc->c[0]); - - /* Retry operation */ - idetape_retry_pc(drive); - return ide_stopped; - } - pc->error = 0; - if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && - (stat & SEEK_STAT) == 0) { - ide_tape_handle_dsc(drive); - return ide_stopped; - } - /* Command finished - Call the callback function */ - pc->callback(drive); - return ide_stopped; - } - - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - printk(KERN_ERR "%s: The device wants to issue more interrupts " - "in DMA mode\n", drive->name); - ide_dma_off(drive); - return ide_do_reset(drive); - } - /* Get the number of bytes to transfer on this interrupt. */ - bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | - hwif->INB(hwif->io_ports.lbam_addr); - - ireason = hwif->INB(hwif->io_ports.nsect_addr); - - if (ireason & CD) { - printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); - return ide_do_reset(drive); - } - if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { - /* Hopefully, we will never get here */ - printk(KERN_ERR "%s: We wanted to %s, but the device wants us " - "to %s!\n", drive->name, - (ireason & IO) ? "Write" : "Read", - (ireason & IO) ? "Read" : "Write"); - return ide_do_reset(drive); - } - if (!(pc->flags & PC_FLAG_WRITING)) { - /* Reading - Check that we have enough space */ - temp = pc->xferred + bcount; - if (temp > pc->req_xfer) { - if (temp > pc->buf_size) { - printk(KERN_ERR "%s: The device wants to send " - "us more data than expected - " - "discarding data\n", - drive->name); - ide_pad_transfer(drive, 0, bcount); - ide_set_handler(drive, &idetape_pc_intr, - IDETAPE_WAIT_CMD, NULL); - return ide_started; - } - debug_log(DBG_PC_INTR, "The device wants to send us more " - "data than expected - allowing transfer\n"); - } - xferfunc = hwif->input_data; - } else { - xferfunc = hwif->output_data; - } - - if (pc->bh) - ide_tape_io_buffers(drive, pc, bcount, - !!(pc->flags & PC_FLAG_WRITING)); - else - xferfunc(drive, NULL, pc->cur_pos, bcount); - - /* Update the current position */ - pc->xferred += bcount; - pc->cur_pos += bcount; - - debug_log(DBG_PC_INTR, "[cmd %x] transferred %d bytes on that intr.\n", - pc->c[0], bcount); - /* And set the interrupt handler again */ - ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); - return ide_started; + return ide_pc_intr(drive, tape->pc, idetape_pc_intr, IDETAPE_WAIT_CMD, + NULL, idetape_update_buffers, idetape_retry_pc, + ide_tape_handle_dsc, ide_tape_io_buffers); } /* diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index ada733c..683bce3 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -356,120 +356,11 @@ static int idescsi_expiry(ide_drive_t *drive) static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); - ide_hwif_t *hwif = drive->hwif; struct ide_atapi_pc *pc = scsi->pc; - struct request *rq = pc->rq; - xfer_func_t *xferfunc; - unsigned int temp; - u16 bcount; - u8 stat, ireason; - - debug_log("Enter %s - interrupt handler\n", __func__); - - if (pc->flags & PC_FLAG_TIMEDOUT) { - pc->callback(drive); - return ide_stopped; - } - - /* Clear the interrupt */ - stat = ide_read_status(drive); - - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - if (hwif->dma_ops->dma_end(drive)) - pc->flags |= PC_FLAG_DMA_ERROR; - else - pc->xferred = pc->req_xfer; - debug_log("%s: DMA finished\n", drive->name); - } - - if ((stat & DRQ_STAT) == 0) { - /* No more interrupts */ - debug_log("Packet command completed, %d bytes transferred\n", - pc->xferred); - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - local_irq_enable_in_hardirq(); - if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { - /* Error detected */ - debug_log("%s: I/O error\n", drive->name); - - rq->errors++; - } - pc->callback(drive); - return ide_stopped; - } - if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; - printk(KERN_ERR "%s: The device wants to issue more interrupts " - "in DMA mode\n", drive->name); - ide_dma_off(drive); - return ide_do_reset(drive); - } - bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | - hwif->INB(hwif->io_ports.lbam_addr); - ireason = hwif->INB(hwif->io_ports.nsect_addr); - - if (ireason & CD) { - printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); - return ide_do_reset (drive); - } - if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { - /* Hopefully, we will never get here */ - printk(KERN_ERR "%s: We wanted to %s, but the device wants us " - "to %s!\n", drive->name, - (ireason & IO) ? "Write" : "Read", - (ireason & IO) ? "Read" : "Write"); - return ide_do_reset(drive); - } - if (!(pc->flags & PC_FLAG_WRITING)) { - temp = pc->xferred + bcount; - if (temp > pc->req_xfer) { - if (temp > pc->buf_size) { - printk(KERN_ERR "%s: The device wants to send " - "us more data than expected - " - "discarding data\n", - drive->name); - temp = pc->buf_size - pc->xferred; - if (temp) { - if (pc->sg) - ide_scsi_io_buffers(drive, pc, - temp, 0); - else - hwif->input_data(drive, NULL, - pc->cur_pos, temp); - printk(KERN_ERR "%s: transferred %d of " - "%d bytes\n", - drive->name, - temp, bcount); - } - pc->xferred += temp; - pc->cur_pos += temp; - ide_pad_transfer(drive, 0, bcount - temp); - ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); - return ide_started; - } - debug_log("The device wants to send us more data than " - "expected - allowing transfer\n"); - } - xferfunc = hwif->input_data; - } else - xferfunc = hwif->output_data; - - if (pc->sg) - ide_scsi_io_buffers(drive, pc, bcount, - !!(pc->flags & PC_FLAG_WRITING)); - else - xferfunc(drive, NULL, pc->cur_pos, bcount); - - /* Update the current position */ - pc->xferred += bcount; - pc->cur_pos += bcount; - - debug_log("[cmd %x] transferred %d bytes on that intr.\n", - pc->c[0], bcount); - /* And set the interrupt handler again */ - ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); - return ide_started; + return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), + idescsi_expiry, NULL, NULL, NULL, + ide_scsi_io_buffers); } static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) diff --git a/include/linux/ide.h b/include/linux/ide.h index fee07a7..ac4eeb2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -968,6 +968,12 @@ extern int drive_is_ready(ide_drive_t *); void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); +ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, + ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, + void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), + void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), + void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, + int)); ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, ide_handler_t *, unsigned int, ide_expiry_t *); ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *, -- cgit v0.10.2 From cd2abbfec84f43db740483daf4ea528d49d8858f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: ide-tape: unify idetape_create_read/write_cmd A straightforward one. There should be no functional change resulting from this change. [bart: minor fixups] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0afa109..6e1233b 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -952,40 +952,29 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) return ide_stopped; } -static void idetape_create_read_cmd(idetape_tape_t *tape, - struct ide_atapi_pc *pc, - unsigned int length, struct idetape_bh *bh) +static void ide_tape_create_rw_cmd(idetape_tape_t *tape, + struct ide_atapi_pc *pc, unsigned int length, + struct idetape_bh *bh, u8 opcode) { idetape_init_pc(pc); - pc->c[0] = READ_6; put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; pc->bh = bh; - atomic_set(&bh->b_count, 0); pc->buf = NULL; pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; if (pc->req_xfer == tape->buffer_size) pc->flags |= PC_FLAG_DMA_OK; -} -static void idetape_create_write_cmd(idetape_tape_t *tape, - struct ide_atapi_pc *pc, - unsigned int length, struct idetape_bh *bh) -{ - idetape_init_pc(pc); - pc->c[0] = WRITE_6; - put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); - pc->c[1] = 1; - pc->flags |= PC_FLAG_WRITING; - pc->bh = bh; - pc->b_data = bh->b_data; - pc->b_count = atomic_read(&bh->b_count); - pc->buf = NULL; - pc->buf_size = length * tape->blk_size; - pc->req_xfer = pc->buf_size; - if (pc->req_xfer == tape->buffer_size) - pc->flags |= PC_FLAG_DMA_OK; + if (opcode == READ_6) { + pc->c[0] = READ_6; + atomic_set(&bh->b_count, 0); + } else if (opcode == WRITE_6) { + pc->c[0] = WRITE_6; + pc->flags |= PC_FLAG_WRITING; + pc->b_data = bh->b_data; + pc->b_count = atomic_read(&bh->b_count); + } } static ide_startstop_t idetape_do_request(ide_drive_t *drive, @@ -1062,14 +1051,16 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, } if (rq->cmd[0] & REQ_IDETAPE_READ) { pc = idetape_next_pc_storage(drive); - idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, - (struct idetape_bh *)rq->special); + ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors, + (struct idetape_bh *)rq->special, + READ_6); goto out; } if (rq->cmd[0] & REQ_IDETAPE_WRITE) { pc = idetape_next_pc_storage(drive); - idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, - (struct idetape_bh *)rq->special); + ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors, + (struct idetape_bh *)rq->special, + WRITE_6); goto out; } if (rq->cmd[0] & REQ_IDETAPE_PC1) { -- cgit v0.10.2 From cbbc4e818de4451cdef75a112b7fc8a523d5d2a0 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 15 Jul 2008 21:22:03 +0200 Subject: ide-floppy: fix unfortunate function naming mv idefloppy_transfer_pc1 idefloppy_start_pc_transfer mv idefloppy_transfer_pc2 idefloppy_transfer_pc which describes their functionality and disambiguates them. There should be no functionality change introduced by this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 0f3602a..b368943 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -399,12 +399,8 @@ static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) * service routine. In interrupt mode, the device sends an interrupt to signal * that it is ready to receive a packet. However, we need to delay about 2-3 * ticks before issuing the packet or we gets in trouble. - * - * So, follow carefully. transfer_pc1 is called as an interrupt (or directly). - * In either case, when the device says it's ready for a packet, we schedule - * the packet transfer to occur about 2-3 ticks later in transfer_pc2. */ -static int idefloppy_transfer_pc2(ide_drive_t *drive) +static int idefloppy_transfer_pc(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; @@ -415,7 +411,13 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) return IDEFLOPPY_WAIT_CMD; } -static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) + +/* + * Called as an interrupt (or directly). When the device says it's ready for a + * packet, we schedule the packet transfer to occur about 2-3 ticks later in + * transfer_pc. + */ +static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; struct ide_atapi_pc *pc = floppy->pc; @@ -432,7 +434,7 @@ static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) */ if (pc->flags & PC_FLAG_ZIP_DRIVE) { timeout = floppy->ticks; - expiry = &idefloppy_transfer_pc2; + expiry = &idefloppy_transfer_pc; } else { timeout = IDEFLOPPY_WAIT_CMD; expiry = NULL; @@ -483,7 +485,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, pc, idefloppy_transfer_pc1, + return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer, IDEFLOPPY_WAIT_CMD, NULL); } -- cgit v0.10.2 From d93c768e66d8c3970187c179a91a2553b077d9e8 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 15 Jul 2008 20:11:21 +0200 Subject: pcmcia: fix return value in cm4000_cs.c should be -EINVAL, not EINVAL. Found by Peter Stuge. Signed-off-by: Dominik Brodowski diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 59ca351..e4a4fbd 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1439,7 +1439,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) DEBUGP(4, dev, "CMM_ABSENT flag set\n"); goto out; } - rc = EINVAL; + rc = -EINVAL; if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) { DEBUGP(4, dev, "ioctype mismatch\n"); -- cgit v0.10.2 From 002b90a1bf5fe9c8de7a8634403a685621841ff3 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 15 Jul 2008 15:26:15 +0200 Subject: pcmcia: fix cisinfo_t removal The cisinfo_t removal patch (c5081d5f4775b2a3f858f91151bbf9163e473075 pcmcia: simplify pccard_validate_cis ) introduced a bug that prevented card detection, for the (info->Chains == MAX_TUPLES) check was replaced by (count), which is always true. Restoring the comparison to MAX_TUPLES makes everybody happy... [linux@dominikbrodowski.net: update changelog comment] Signed-off-by: Marc Zyngier Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 9fcff0c..65129b5 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1490,7 +1490,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) reserved++; } - if ((count) || (reserved > 5) || + if ((count == MAX_TUPLES) || (reserved > 5) || ((!dev_ok || !ident_ok) && (count > 10))) count = 0; -- cgit v0.10.2 From 417e1494fd70715b737428cc3c3d924255f22ba1 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 15 Jul 2008 11:30:00 -0500 Subject: pcmcia: ide-cs: Remove outdated comment There is an outdated version information comment in ide-cs. Signed-off-by: Larry Finger Signed-off-by: Dominik Brodowski diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 8dbf4d9..41a2e25 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -66,8 +66,6 @@ MODULE_LICENSE("Dual MPL/GPL"); #ifdef CONFIG_PCMCIA_DEBUG INT_MODULE_PARM(pc_debug, 0); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -/*static char *version = -"ide-cs.c 1.3 2002/10/26 05:45:31 (David Hinds)";*/ #else #define DEBUG(n, args...) #endif -- cgit v0.10.2 From b3c9816b9fa9a7b75ab36111eb76eca03e5bab78 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Jul 2008 22:03:56 +0200 Subject: generic-ipi: merge fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix merge fallout: arch/x86/pci/amd_bus.c: In function ‘enable_pci_io_ecs': arch/x86/pci/amd_bus.c:581: error: too many arguments to function ‘on_each_cpu' Signed-off-by: Ingo Molnar diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index a18141a..dbf5323 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c @@ -578,7 +578,7 @@ static int __init enable_pci_io_ecs(void) /* assume all cpus from fam10h have IO ECS */ if (boot_cpu_data.x86 < 0x10) return 0; - on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1); + on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1); pci_probe |= PCI_HAS_IO_ECS; return 0; } -- cgit v0.10.2 From f6f88e9bfb6ced9871ed65ebe85c371de3c9e4be Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Jul 2008 22:08:52 +0200 Subject: generic-ipi: more merge fallout fix more API change fallout in recently merged upstream changes. Signed-off-by: Ingo Molnar diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index b40df7d..54759f1 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -313,7 +313,7 @@ static int __init mipsxx_init(void) if (!cpu_has_mipsmt_pertccounters) counters = counters_total_to_per_cpu(counters); #endif - on_each_cpu(reset_counters, (void *)(long)counters, 0, 1); + on_each_cpu(reset_counters, (void *)(long)counters, 1); op_model_mipsxx_ops.num_counters = counters; switch (current_cpu_type()) { @@ -382,7 +382,7 @@ static void mipsxx_exit(void) int counters = op_model_mipsxx_ops.num_counters; counters = counters_per_cpu_to_total(counters); - on_each_cpu(reset_counters, (void *)(long)counters, 0, 1); + on_each_cpu(reset_counters, (void *)(long)counters, 1); perf_irq = save_perf_irq; } diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 0559985..bcab0d2 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -152,7 +152,7 @@ static void stop_this_cpu(void *dummy) void smp_send_stop(void) { - smp_call_function(stop_this_cpu, NULL, 1, 0); + smp_call_function(stop_this_cpu, NULL, 0); } /* diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 8051e93..f2cede3 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -1432,7 +1432,7 @@ static void stp_work_fn(struct work_struct *work) */ memset(&stp_sync, 0, sizeof(stp_sync)); preempt_disable(); - smp_call_function(clock_sync_cpu_start, &stp_sync, 0, 0); + smp_call_function(clock_sync_cpu_start, &stp_sync, 0); local_irq_disable(); enable_sync_clock(); @@ -1465,7 +1465,7 @@ static void stp_work_fn(struct work_struct *work) stp_sync.in_sync = 1; local_irq_enable(); - smp_call_function(clock_sync_cpu_end, NULL, 0, 0); + smp_call_function(clock_sync_cpu_end, NULL, 0); preempt_enable(); } diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index c1ba0db..77082445 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c @@ -55,7 +55,7 @@ static void __booke_wdt_ping(void *data) static void booke_wdt_ping(void) { - on_each_cpu(__booke_wdt_ping, NULL, 0, 0); + on_each_cpu(__booke_wdt_ping, NULL, 0); } static void __booke_wdt_enable(void *data) @@ -131,7 +131,7 @@ static int booke_wdt_open(struct inode *inode, struct file *file) spin_lock(&booke_wdt_lock); if (booke_wdt_enabled == 0) { booke_wdt_enabled = 1; - on_each_cpu(__booke_wdt_enable, NULL, 0, 0); + on_each_cpu(__booke_wdt_enable, NULL, 0); printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " "(wdt_period=%d)\n", booke_wdt_period); } @@ -177,7 +177,7 @@ static int __init booke_wdt_init(void) if (booke_wdt_enabled == 1) { printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " "(wdt_period=%d)\n", booke_wdt_period); - on_each_cpu(__booke_wdt_enable, NULL, 0, 0); + on_each_cpu(__booke_wdt_enable, NULL, 0); } spin_unlock(&booke_wdt_lock); -- cgit v0.10.2 From 431ceb83f703a343bdd14350480a2224fa4bfedf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 15 Jul 2008 22:08:04 +0200 Subject: x86: fix TSC build error on 32bit Dave Hansen reported a build error on 32bit which went unnoticed as newer gcc versions seem to optimize unused static functions away before compiling them. Make vread_tsc() depend on CONFIG_X86_64 Signed-off-by: Thomas Gleixner diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 3c36f92..7603c05 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -358,6 +358,7 @@ static cycle_t read_tsc(void) ret : clocksource_tsc.cycle_last; } +#ifdef CONFIG_X86_64 static cycle_t __vsyscall_fn vread_tsc(void) { cycle_t ret = (cycle_t)vget_cycles(); @@ -365,6 +366,7 @@ static cycle_t __vsyscall_fn vread_tsc(void) return ret >= __vsyscall_gtod_data.clock.cycle_last ? ret : __vsyscall_gtod_data.clock.cycle_last; } +#endif static struct clocksource clocksource_tsc = { .name = "tsc", -- cgit v0.10.2 From de3b69d7d87e1e86c0307f0f15b377dcebeab906 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 15 Jul 2008 13:28:14 -0400 Subject: ftrace: maintainer I'm willing to take responsibility for ftrace, and follow up on any issues that arise due to it. Signed-off-by: Steven Rostedt Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 6198fa3..fc6c005 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1777,6 +1777,11 @@ M: hch@infradead.org W: ftp://ftp.openlinux.org/pub/people/hch/vxfs S: Maintained +FTRACE +P: Steven Rostedt +M: srostedt@redhat.com +S: Maintained + FUJITSU FR-V (FRV) PORT P: David Howells M: dhowells@redhat.com -- cgit v0.10.2 From fe1a6875fcaaac2041945008a9875d2c07be1d9b Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Tue, 15 Jul 2008 22:28:46 +0200 Subject: mm: fix build on non-mmu machines Commit 1ea0704e0d aka "mm: add a ptep_modify_prot transaction abstraction" caused: | CC init/main.o |In file included from include2/asm/pgtable.h:68, | from /home/bigeasy/git/linux-2.6-m68k/include/linux/mm.h:39, | from include2/asm/uaccess.h:8, | from /home/bigeasy/git/linux-2.6-m68k/include/linux/poll.h:13, | from /home/bigeasy/git/linux-2.6-m68k/include/linux/rtc.h:113, | from /home/bigeasy/git/linux-2.6-m68k/include/linux/efi.h:19, | from /home/bigeasy/git/linux-2.6-m68k/init/main.c:43: |/linux-2.6/include/asm-generic/pgtable.h: In function '__ptep_modify_prot_start': |/linux-2.6/include/asm-generic/pgtable.h:209: error: implicit declaration of function 'ptep_get_and_clear' |/linux-2.6/include/asm-generic/pgtable.h:209: error: incompatible types in return |/linux-2.6/include/asm-generic/pgtable.h: In function '__ptep_modify_prot_commit': |/linux-2.6/include/asm-generic/pgtable.h:220: error: implicit declaration of function 'set_pte_at' |make[2]: *** [init/main.o] Error 1 |make[1]: *** [init] Error 2 |make: *** [sub-make] Error 2 on my m68knommu box. Acked-by: Jeremy Fitzhardinge Cc: Linus Torvalds Cc: Hugh Dickins Cc: Ingo Molnar Signed-off-by: Sebastian Siewior Signed-off-by: Linus Torvalds diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 4fce3db..ef87f88 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -195,7 +195,6 @@ static inline int pmd_none_or_clear_bad(pmd_t *pmd) } return 0; } -#endif /* CONFIG_MMU */ static inline pte_t __ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, @@ -253,6 +252,7 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm, __ptep_modify_prot_commit(mm, addr, ptep, pte); } #endif /* __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION */ +#endif /* CONFIG_MMU */ /* * A facility to provide lazy MMU batching. This allows PTE updates and -- cgit v0.10.2 From 63cf13b77ab785e87c867defa8545e6d4a989774 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 15 Jul 2008 13:22:49 -0700 Subject: generic ipi function calls: wait on alloc failure fallback When a GFP_ATOMIC allocation fails, it falls back to allocating the data on the stack and converting it to a waiting call. Make sure we actually wait in this case. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Linus Torvalds diff --git a/kernel/smp.c b/kernel/smp.c index ab10793..462c785 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -312,6 +312,7 @@ int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, if (!data) { data = &d; data->csd.flags = CSD_FLAG_WAIT; + wait = 1; } spin_lock_init(&data->lock); -- cgit v0.10.2 From 987ff954cda2a206f5e694f267b0ccad869c257c Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:15:41 -0400 Subject: Fix endianity in A100U2W SCSI driver Support big endian systems in a100u2w driver. Signed-off-by: Mikulas Patocka Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index ced3eeb..1dd0fcf 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -389,7 +389,7 @@ static u8 orc_load_firmware(struct orc_host * host) outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Enable SRAM programming */ data32_ptr = (u8 *) & data32; - data32 = 0; /* Initial FW address to 0 */ + data32 = cpu_to_le32(0); /* Initial FW address to 0 */ outw(0x0010, host->base + ORC_EBIOSADR0); *data32_ptr = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ outw(0x0011, host->base + ORC_EBIOSADR0); @@ -397,18 +397,18 @@ static u8 orc_load_firmware(struct orc_host * host) outw(0x0012, host->base + ORC_EBIOSADR0); *(data32_ptr + 2) = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ outw(*(data32_ptr + 2), host->base + ORC_EBIOSADR2); - outl(data32, host->base + ORC_FWBASEADR); /* Write FW address */ + outl(le32_to_cpu(data32), host->base + ORC_FWBASEADR); /* Write FW address */ /* Copy the code from the BIOS to the SRAM */ - bios_addr = (u16) data32; /* FW code locate at BIOS address + ? */ + bios_addr = (u16) le32_to_cpu(data32); /* FW code locate at BIOS address + ? */ for (i = 0, data32_ptr = (u8 *) & data32; /* Download the code */ i < 0x1000; /* Firmware code size = 4K */ i++, bios_addr++) { outw(bios_addr, host->base + ORC_EBIOSADR0); *data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ if ((i % 4) == 3) { - outl(data32, host->base + ORC_RISCRAM); /* Write every 4 bytes */ + outl(le32_to_cpu(data32), host->base + ORC_RISCRAM); /* Write every 4 bytes */ data32_ptr = (u8 *) & data32; } } @@ -423,7 +423,7 @@ static u8 orc_load_firmware(struct orc_host * host) outw(bios_addr, host->base + ORC_EBIOSADR0); *data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ if ((i % 4) == 3) { - if (inl(host->base + ORC_RISCRAM) != data32) { + if (inl(host->base + ORC_RISCRAM) != le32_to_cpu(data32)) { outb(PRGMRST, host->base + ORC_RISCCTL); /* Reset program to 0 */ outb(data, host->base + ORC_GCFG); /*Disable EEPROM programming */ return 0; @@ -459,8 +459,8 @@ static void setup_SCBs(struct orc_host * host) for (i = 0; i < ORC_MAXQUEUE; i++) { escb_phys = (host->escb_phys + (sizeof(struct orc_extended_scb) * i)); - scb->sg_addr = (u32) escb_phys; - scb->sense_addr = (u32) escb_phys; + scb->sg_addr = cpu_to_le32((u32) escb_phys); + scb->sense_addr = cpu_to_le32((u32) escb_phys); scb->escb = escb; scb->scbidx = i; scb++; @@ -642,8 +642,8 @@ static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsig scb->link = 0xFF; scb->reserved0 = 0; scb->reserved1 = 0; - scb->xferlen = 0; - scb->sg_len = 0; + scb->xferlen = cpu_to_le32(0); + scb->sg_len = cpu_to_le32(0); escb->srb = NULL; escb->srb = cmd; @@ -858,9 +858,9 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru scb->lun = cmd->device->lun; scb->reserved0 = 0; scb->reserved1 = 0; - scb->sg_len = 0; + scb->sg_len = cpu_to_le32(0); - scb->xferlen = (u32) scsi_bufflen(cmd); + scb->xferlen = cpu_to_le32((u32) scsi_bufflen(cmd)); sgent = (struct orc_sgent *) & escb->sglist[0]; count_sg = scsi_dma_map(cmd); @@ -868,18 +868,18 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru /* Build the scatter gather lists */ if (count_sg) { - scb->sg_len = (u32) (count_sg * 8); + scb->sg_len = cpu_to_le32((u32) (count_sg * 8)); scsi_for_each_sg(cmd, sg, count_sg, i) { - sgent->base = (u32) sg_dma_address(sg); - sgent->length = (u32) sg_dma_len(sg); + sgent->base = cpu_to_le32((u32) sg_dma_address(sg)); + sgent->length = cpu_to_le32((u32) sg_dma_len(sg)); sgent++; } } else { - scb->sg_len = 0; - sgent->base = 0; - sgent->length = 0; + scb->sg_len = cpu_to_le32(0); + sgent->base = cpu_to_le32(0); + sgent->length = cpu_to_le32(0); } - scb->sg_addr = (u32) scb->sense_addr; + scb->sg_addr = (u32) scb->sense_addr; /* sense_addr is already little endian */ scb->hastat = 0; scb->tastat = 0; scb->link = 0xFF; -- cgit v0.10.2 From 56d387ec210049be2fdb0fe26ba6d6de1b3c1b15 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:16:38 -0400 Subject: Add udelay to A100U2W SCSI driver udelay is required on Sun Ultra 5. I don't know any reason or explanation for this, it was found purely experimentally. Signed-off-by: Mikulas Patocka Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 1dd0fcf..1e8bdd4 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -401,6 +401,7 @@ static u8 orc_load_firmware(struct orc_host * host) /* Copy the code from the BIOS to the SRAM */ + udelay(500); /* Required on Sun Ultra 5 ... 350 -> failures */ bios_addr = (u16) le32_to_cpu(data32); /* FW code locate at BIOS address + ? */ for (i = 0, data32_ptr = (u8 *) & data32; /* Download the code */ i < 0x1000; /* Firmware code size = 4K */ -- cgit v0.10.2 From a5db33411ae762e597bfcde6bb9d0c8c2ea9c0eb Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:18:38 -0400 Subject: BUG_ON on kernel misbehavior on A100U2W driver With broken Sparc64 IOMMU accounting, the kernel submits larger requests then allowed. Better to crash on BUG than corrupt memory. Signed-off-by: Mikulas Patocka Acked-by: James Bottomley Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 1e8bdd4..f5051f4 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -866,6 +866,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru count_sg = scsi_dma_map(cmd); BUG_ON(count_sg < 0); + BUG_ON(count_sg > TOTAL_SG_ENTRY); /* Build the scatter gather lists */ if (count_sg) { -- cgit v0.10.2 From 3a628b0fd42f7eaf9d052447784d48ceae9ffb8e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 15 Jul 2008 17:19:55 -0400 Subject: Don't crash on IOMMU overflow in A100U2W driver Handle IOMMU overflow correctly, by retrying. IOMMU errors can happen and drivers must deal with them. Signed-off-by: Mikulas Patocka Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index f5051f4..84bb616 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -840,7 +840,7 @@ static irqreturn_t orc_interrupt(struct orc_host * host) * Build a host adapter control block from the SCSI mid layer command */ -static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd) +static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd) { /* Create corresponding SCB */ struct scatterlist *sg; struct orc_sgent *sgent; /* Pointer to SG list */ @@ -865,7 +865,8 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru sgent = (struct orc_sgent *) & escb->sglist[0]; count_sg = scsi_dma_map(cmd); - BUG_ON(count_sg < 0); + if (count_sg < 0) + return count_sg; BUG_ON(count_sg > TOTAL_SG_ENTRY); /* Build the scatter gather lists */ @@ -898,6 +899,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru scb->tag_msg = 0; /* No tag support */ } memcpy(scb->cdb, cmd->cmnd, scb->cdb_len); + return 0; } /** @@ -921,7 +923,10 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd if ((scb = orc_alloc_scb(host)) == NULL) return SCSI_MLQUEUE_HOST_BUSY; - inia100_build_scb(host, scb, cmd); + if (inia100_build_scb(host, scb, cmd)) { + orc_release_scb(host, scb); + return SCSI_MLQUEUE_HOST_BUSY; + } orc_exec_scb(host, scb); /* Start execute SCB */ return 0; } -- cgit v0.10.2 From 166b88d755f925139af7f7b75aa0a1b896ca0670 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:26 -0400 Subject: SUNRPC: Use correct XDR encoding procedure for rpcbind SET/UNSET The rpcbind versions 3 and 4 SET and UNSET procedures use the same arguments as the GETADDR procedure. While definitely a bug, this hasn't been a problem so far since the kernel hasn't used version 3 or 4 SET and UNSET. But this will change in just a moment. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 24e93e0..0021fad 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -426,6 +426,10 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) map->r_status = status; } +/* + * XDR functions for rpcbind + */ + static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p, struct rpcbind_args *rpcb) { @@ -581,14 +585,14 @@ static struct rpc_procinfo rpcb_procedures2[] = { }; static struct rpc_procinfo rpcb_procedures3[] = { - PROC(SET, mapping, set), - PROC(UNSET, mapping, set), + PROC(SET, getaddr, set), + PROC(UNSET, getaddr, set), PROC(GETADDR, getaddr, getaddr), }; static struct rpc_procinfo rpcb_procedures4[] = { - PROC(SET, mapping, set), - PROC(UNSET, mapping, set), + PROC(SET, getaddr, set), + PROC(UNSET, getaddr, set), PROC(GETADDR, getaddr, getaddr), PROC(GETVERSADDR, getaddr, getaddr), }; -- cgit v0.10.2 From cc5598b78fd320dd6d1f90c14491e08029f3c4f6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:27 -0400 Subject: SUNRPC: Introduce a specific rpcb_create for contacting localhost Add rpcb_create_local() for use by rpcb_register() and upcoming IPv6 registration functions. Ensure any errors encountered by rpcb_create_local() are properly reported. We can also use a statically allocated constant loopback socket address instead of one allocated on the stack and initialized every time the function is called. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 0021fad..35c1ded 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -116,6 +116,29 @@ static void rpcb_map_release(void *data) kfree(map); } +static const struct sockaddr_in rpcb_inaddr_loopback = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + .sin_port = htons(RPCBIND_PORT), +}; + +static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr, + size_t addrlen, u32 version) +{ + struct rpc_create_args args = { + .protocol = XPRT_TRANSPORT_UDP, + .address = addr, + .addrsize = addrlen, + .servername = "localhost", + .program = &rpcb_program, + .version = version, + .authflavor = RPC_AUTH_UNIX, + .flags = RPC_CLNT_CREATE_NOPING, + }; + + return rpc_create(&args); +} + static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, size_t salen, int proto, u32 version, int privileged) @@ -161,10 +184,6 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, */ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) { - struct sockaddr_in sin = { - .sin_family = AF_INET, - .sin_addr.s_addr = htonl(INADDR_LOOPBACK), - }; struct rpcbind_args map = { .r_prog = prog, .r_vers = vers, @@ -184,14 +203,15 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) "rpcbind\n", (port ? "" : "un"), prog, vers, prot, port); - rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin, - sizeof(sin), XPRT_TRANSPORT_UDP, RPCBVERS_2, 1); - if (IS_ERR(rpcb_clnt)) - return PTR_ERR(rpcb_clnt); + rpcb_clnt = rpcb_create_local((struct sockaddr *)&rpcb_inaddr_loopback, + sizeof(rpcb_inaddr_loopback), + RPCBVERS_2); + if (!IS_ERR(rpcb_clnt)) { + error = rpc_call_sync(rpcb_clnt, &msg, 0); + rpc_shutdown_client(rpcb_clnt); + } else + error = PTR_ERR(rpcb_clnt); - error = rpc_call_sync(rpcb_clnt, &msg, 0); - - rpc_shutdown_client(rpcb_clnt); if (error < 0) printk(KERN_WARNING "RPC: failed to contact local rpcbind " "server (errno %d).\n", -error); -- cgit v0.10.2 From 423d8b064771f5cd8b706a4839b18db9bb6c3c59 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:28 -0400 Subject: SUNRPC: None of rpcb_create's callers wants a privileged source port Clean up: Callers that required a privileged source port now use rpcb_create_local(), so we can remove the @privileged argument from rpcb_create(). Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 35c1ded..691bd21 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -140,8 +140,7 @@ static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr, } static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, - size_t salen, int proto, u32 version, - int privileged) + size_t salen, int proto, u32 version) { struct rpc_create_args args = { .protocol = proto, @@ -151,7 +150,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, .program = &rpcb_program, .version = version, .authflavor = RPC_AUTH_UNIX, - .flags = RPC_CLNT_CREATE_NOPING, + .flags = (RPC_CLNT_CREATE_NOPING | + RPC_CLNT_CREATE_NONPRIVPORT), }; switch (srvaddr->sa_family) { @@ -165,8 +165,6 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, return NULL; } - if (!privileged) - args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; return rpc_create(&args); } @@ -255,7 +253,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, - sizeof(*sin), prot, RPCBVERS_2, 0); + sizeof(*sin), prot, RPCBVERS_2); if (IS_ERR(rpcb_clnt)) return PTR_ERR(rpcb_clnt); @@ -365,7 +363,7 @@ void rpcb_getport_async(struct rpc_task *task) task->tk_pid, __func__, bind_version); rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot, - bind_version, 0); + bind_version); if (IS_ERR(rpcb_clnt)) { status = PTR_ERR(rpcb_clnt); dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", -- cgit v0.10.2 From babe80eb4994dfdc97d5be19a68b5af66d667585 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:29 -0400 Subject: SUNRPC: Refactor rpcb_register to make rpcbindv4 support easier rpcbind version 4 registration will reuse part of rpcb_register, so just split it out into a separate function now. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 691bd21..8b75c30 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -168,6 +168,30 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, return rpc_create(&args); } +static int rpcb_register_call(struct sockaddr *addr, size_t addrlen, + u32 version, struct rpc_message *msg, + int *result) +{ + struct rpc_clnt *rpcb_clnt; + int error = 0; + + *result = 0; + + rpcb_clnt = rpcb_create_local(addr, addrlen, version); + if (!IS_ERR(rpcb_clnt)) { + error = rpc_call_sync(rpcb_clnt, msg, 0); + rpc_shutdown_client(rpcb_clnt); + } else + error = PTR_ERR(rpcb_clnt); + + if (error < 0) + printk(KERN_WARNING "RPC: failed to contact local rpcbind " + "server (errno %d).\n", -error); + dprintk("RPC: registration status %d/%d\n", error, *result); + + return error; +} + /** * rpcb_register - set or unset a port registration with the local rpcbind svc * @prog: RPC program number to bind @@ -189,33 +213,21 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) .r_port = port, }; struct rpc_message msg = { - .rpc_proc = &rpcb_procedures2[port ? - RPCBPROC_SET : RPCBPROC_UNSET], .rpc_argp = &map, .rpc_resp = okay, }; - struct rpc_clnt *rpcb_clnt; - int error = 0; dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " "rpcbind\n", (port ? "" : "un"), prog, vers, prot, port); - rpcb_clnt = rpcb_create_local((struct sockaddr *)&rpcb_inaddr_loopback, - sizeof(rpcb_inaddr_loopback), - RPCBVERS_2); - if (!IS_ERR(rpcb_clnt)) { - error = rpc_call_sync(rpcb_clnt, &msg, 0); - rpc_shutdown_client(rpcb_clnt); - } else - error = PTR_ERR(rpcb_clnt); + msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET]; + if (port) + msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET]; - if (error < 0) - printk(KERN_WARNING "RPC: failed to contact local rpcbind " - "server (errno %d).\n", -error); - dprintk("RPC: registration status %d/%d\n", error, *okay); - - return error; + return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback, + sizeof(rpcb_inaddr_loopback), + RPCBVERS_2, &msg, okay); } /** -- cgit v0.10.2 From c2e1b09ff237c0a3687b9a804cc8bf489743cffc Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 14 Jul 2008 16:03:30 -0400 Subject: SUNRPC: Support registering IPv6 interfaces with local rpcbind daemon Introduce a new API to register RPC services on IPv6 interfaces to allow the NFS server and lockd to advertise on IPv6 networks. Unlike rpcb_register(), the new rpcb_v4_register() function uses rpcbind protocol version 4 to contact the local rpcbind daemon. The version 4 SET/UNSET procedures allow services to register address families besides AF_INET, register at specific network interfaces, and register transport protocols besides UDP and TCP. All of this functionality is exposed via the new rpcb_v4_register() kernel API. A user-space rpcbind daemon implementation that supports version 4 of the rpcbind protocol is required in order to make use of this new API. Note that rpcbind version 3 is sufficient to support the new rpcbind facilities listed above, but most extant implementations use version 4. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 764fd4c..e5bfe01 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -125,6 +125,9 @@ void rpc_shutdown_client(struct rpc_clnt *); void rpc_release_client(struct rpc_clnt *); int rpcb_register(u32, u32, int, unsigned short, int *); +int rpcb_v4_register(const u32 program, const u32 version, + const struct sockaddr *address, + const char *netid, int *result); int rpcb_getport_sync(struct sockaddr_in *, u32, u32, int); void rpcb_getport_async(struct rpc_task *); diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 8b75c30..24db2b4 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -87,6 +87,7 @@ struct rpcbind_args { static struct rpc_procinfo rpcb_procedures2[]; static struct rpc_procinfo rpcb_procedures3[]; +static struct rpc_procinfo rpcb_procedures4[]; struct rpcb_info { u32 rpc_vers; @@ -122,6 +123,12 @@ static const struct sockaddr_in rpcb_inaddr_loopback = { .sin_port = htons(RPCBIND_PORT), }; +static const struct sockaddr_in6 rpcb_in6addr_loopback = { + .sin6_family = AF_INET6, + .sin6_addr = IN6ADDR_LOOPBACK_INIT, + .sin6_port = htons(RPCBIND_PORT), +}; + static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr, size_t addrlen, u32 version) { @@ -196,13 +203,38 @@ static int rpcb_register_call(struct sockaddr *addr, size_t addrlen, * rpcb_register - set or unset a port registration with the local rpcbind svc * @prog: RPC program number to bind * @vers: RPC version number to bind - * @prot: transport protocol to use to make this request + * @prot: transport protocol to register * @port: port value to register - * @okay: result code + * @okay: OUT: result code + * + * RPC services invoke this function to advertise their contact + * information via the system's rpcbind daemon. RPC services + * invoke this function once for each [program, version, transport] + * tuple they wish to advertise. + * + * Callers may also unregister RPC services that are no longer + * available by setting the passed-in port to zero. This removes + * all registered transports for [program, version] from the local + * rpcbind database. + * + * Returns zero if the registration request was dispatched + * successfully and a reply was received. The rpcbind daemon's + * boolean result code is stored in *okay. * - * port == 0 means unregister, port != 0 means register. + * Returns an errno value and sets *result to zero if there was + * some problem that prevented the rpcbind request from being + * dispatched, or if the rpcbind daemon did not respond within + * the timeout. * - * This routine supports only rpcbind version 2. + * This function uses rpcbind protocol version 2 to contact the + * local rpcbind daemon. + * + * Registration works over both AF_INET and AF_INET6, and services + * registered via this function are advertised as available for any + * address. If the local rpcbind daemon is listening on AF_INET6, + * services registered via this function will be advertised on + * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6 + * addresses). */ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) { @@ -230,6 +262,144 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) RPCBVERS_2, &msg, okay); } +/* + * Fill in AF_INET family-specific arguments to register + */ +static int rpcb_register_netid4(struct sockaddr_in *address_to_register, + struct rpc_message *msg) +{ + struct rpcbind_args *map = msg->rpc_argp; + unsigned short port = ntohs(address_to_register->sin_port); + char buf[32]; + + /* Construct AF_INET universal address */ + snprintf(buf, sizeof(buf), + NIPQUAD_FMT".%u.%u", + NIPQUAD(address_to_register->sin_addr.s_addr), + port >> 8, port & 0xff); + map->r_addr = buf; + + dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " + "local rpcbind\n", (port ? "" : "un"), + map->r_prog, map->r_vers, + map->r_addr, map->r_netid); + + msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; + if (port) + msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; + + return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback, + sizeof(rpcb_inaddr_loopback), + RPCBVERS_4, msg, msg->rpc_resp); +} + +/* + * Fill in AF_INET6 family-specific arguments to register + */ +static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register, + struct rpc_message *msg) +{ + struct rpcbind_args *map = msg->rpc_argp; + unsigned short port = ntohs(address_to_register->sin6_port); + char buf[64]; + + /* Construct AF_INET6 universal address */ + snprintf(buf, sizeof(buf), + NIP6_FMT".%u.%u", + NIP6(address_to_register->sin6_addr), + port >> 8, port & 0xff); + map->r_addr = buf; + + dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " + "local rpcbind\n", (port ? "" : "un"), + map->r_prog, map->r_vers, + map->r_addr, map->r_netid); + + msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; + if (port) + msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; + + return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback, + sizeof(rpcb_in6addr_loopback), + RPCBVERS_4, msg, msg->rpc_resp); +} + +/** + * rpcb_v4_register - set or unset a port registration with the local rpcbind + * @program: RPC program number of service to (un)register + * @version: RPC version number of service to (un)register + * @address: address family, IP address, and port to (un)register + * @netid: netid of transport protocol to (un)register + * @result: result code from rpcbind RPC call + * + * RPC services invoke this function to advertise their contact + * information via the system's rpcbind daemon. RPC services + * invoke this function once for each [program, version, address, + * netid] tuple they wish to advertise. + * + * Callers may also unregister RPC services that are no longer + * available by setting the port number in the passed-in address + * to zero. Callers pass a netid of "" to unregister all + * transport netids associated with [program, version, address]. + * + * Returns zero if the registration request was dispatched + * successfully and a reply was received. The rpcbind daemon's + * result code is stored in *result. + * + * Returns an errno value and sets *result to zero if there was + * some problem that prevented the rpcbind request from being + * dispatched, or if the rpcbind daemon did not respond within + * the timeout. + * + * This function uses rpcbind protocol version 4 to contact the + * local rpcbind daemon. The local rpcbind daemon must support + * version 4 of the rpcbind protocol in order for these functions + * to register a service successfully. + * + * Supported netids include "udp" and "tcp" for UDP and TCP over + * IPv4, and "udp6" and "tcp6" for UDP and TCP over IPv6, + * respectively. + * + * The contents of @address determine the address family and the + * port to be registered. The usual practice is to pass INADDR_ANY + * as the raw address, but specifying a non-zero address is also + * supported by this API if the caller wishes to advertise an RPC + * service on a specific network interface. + * + * Note that passing in INADDR_ANY does not create the same service + * registration as IN6ADDR_ANY. The former advertises an RPC + * service on any IPv4 address, but not on IPv6. The latter + * advertises the service on all IPv4 and IPv6 addresses. + */ +int rpcb_v4_register(const u32 program, const u32 version, + const struct sockaddr *address, const char *netid, + int *result) +{ + struct rpcbind_args map = { + .r_prog = program, + .r_vers = version, + .r_netid = netid, + .r_owner = RPCB_OWNER_STRING, + }; + struct rpc_message msg = { + .rpc_argp = &map, + .rpc_resp = result, + }; + + *result = 0; + + switch (address->sa_family) { + case AF_INET: + return rpcb_register_netid4((struct sockaddr_in *)address, + &msg); + case AF_INET6: + return rpcb_register_netid6((struct sockaddr_in6 *)address, + &msg); + } + + return -EAFNOSUPPORT; +} + /** * rpcb_getport_sync - obtain the port for an RPC service on a given host * @sin: address of remote peer -- cgit v0.10.2 From d67d1c7bf948341fd8678c8e337ec27f4b46b206 Mon Sep 17 00:00:00 2001 From: Felix Blyakher Date: Tue, 15 Jul 2008 12:40:22 -0500 Subject: nfs: set correct fl_len in nlmclnt_test() fcntl(F_GETLK) on an nfs client incorrectly returns the values for the conflicting lock. fl_len value is always 1. If the conflicting lock is (0, 4095) the F_GETLK request for (1024, 10) returns (0, 1), which doesn't even cover the requested range, and is quite confusing. The fix is trivial, set fl_end from the fl_end value recieved from the nfs server. Signed-off-by: Felix Blyakher Signed-off-by: "J. Bruce Fields" Signed-off-by: Trond Myklebust diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 5df517b..fd7d466 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -430,7 +430,7 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) * Report the conflicting lock back to the application. */ fl->fl_start = req->a_res.lock.fl.fl_start; - fl->fl_end = req->a_res.lock.fl.fl_start; + fl->fl_end = req->a_res.lock.fl.fl_end; fl->fl_type = req->a_res.lock.fl.fl_type; fl->fl_pid = 0; break; -- cgit v0.10.2 From 1b83d707032a1be40a60ed0a9bd841662cc04a5d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:04 -0400 Subject: NFS: Protect inode->i_nlink updates using inode->i_lock Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b194066..d6ec1c8 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -870,6 +870,14 @@ static int nfs_dentry_delete(struct dentry *dentry) } +static void nfs_drop_nlink(struct inode *inode) +{ + spin_lock(&inode->i_lock); + if (inode->i_nlink > 0) + drop_nlink(inode); + spin_unlock(&inode->i_lock); +} + /* * Called when the dentry loses inode. * We use it to clean up silly-renamed files. @@ -1420,7 +1428,7 @@ static int nfs_safe_remove(struct dentry *dentry) error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); /* The VFS may want to delete this inode */ if (error == 0) - drop_nlink(inode); + nfs_drop_nlink(inode); nfs_mark_for_revalidate(inode); } else error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); @@ -1647,7 +1655,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, /* dentry still busy? */ goto out; } else - drop_nlink(new_inode); + nfs_drop_nlink(new_inode); go_ahead: /* -- cgit v0.10.2 From a3d01454bc58b5a211ef64a7670572a40b71e682 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 12:21:19 -0400 Subject: NFS: Remove BKL requirement from attribute updates The main problem is dealing with inode->i_size: we need to set the inode->i_lock on all attribute updates, and so vmtruncate won't cut it. Make an NFS-private version of vmtruncate that has the necessary locking semantics. The result should be that the following inode attribute updates are protected by inode->i_lock nfsi->cache_validity nfsi->read_cache_jiffies nfsi->attrtimeo nfsi->attrtimeo_timestamp nfsi->change_attr nfsi->last_updated nfsi->cache_change_attribute nfsi->access_cache nfsi->access_cache_entry_lru nfsi->access_cache_inode_lru nfsi->acl_access nfsi->acl_default nfsi->nfs_page_tree nfsi->ncommit nfsi->npages nfsi->open_files nfsi->silly_list nfsi->acl nfsi->open_states inode->i_size inode->i_atime inode->i_mtime inode->i_ctime inode->i_nlink inode->i_uid inode->i_gid The following is protected by dir->i_mutex nfsi->cookieverf Signed-off-by: Trond Myklebust diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2c23d06..3adabd1 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -389,6 +389,62 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) } /** + * nfs_vmtruncate - unmap mappings "freed" by truncate() syscall + * @inode: inode of the file used + * @offset: file offset to start truncating + * + * This is a copy of the common vmtruncate, but with the locking + * corrected to take into account the fact that NFS requires + * inode->i_size to be updated under the inode->i_lock. + */ +static int nfs_vmtruncate(struct inode * inode, loff_t offset) +{ + if (i_size_read(inode) < offset) { + unsigned long limit; + + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit != RLIM_INFINITY && offset > limit) + goto out_sig; + if (offset > inode->i_sb->s_maxbytes) + goto out_big; + spin_lock(&inode->i_lock); + i_size_write(inode, offset); + spin_unlock(&inode->i_lock); + } else { + struct address_space *mapping = inode->i_mapping; + + /* + * truncation of in-use swapfiles is disallowed - it would + * cause subsequent swapout to scribble on the now-freed + * blocks. + */ + if (IS_SWAPFILE(inode)) + return -ETXTBSY; + spin_lock(&inode->i_lock); + i_size_write(inode, offset); + spin_unlock(&inode->i_lock); + + /* + * unmap_mapping_range is called twice, first simply for + * efficiency so that truncate_inode_pages does fewer + * single-page unmaps. However after this first call, and + * before truncate_inode_pages finishes, it is possible for + * private pages to be COWed, which remain after + * truncate_inode_pages finishes, hence the second + * unmap_mapping_range call must be made for correctness. + */ + unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); + truncate_inode_pages(mapping, offset); + unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); + } + return 0; +out_sig: + send_sig(SIGXFSZ, current, 0); +out_big: + return -EFBIG; +} + +/** * nfs_setattr_update_inode - Update inode metadata after a setattr call. * @inode: pointer to struct inode * @attr: pointer to struct iattr @@ -414,8 +470,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) } if ((attr->ia_valid & ATTR_SIZE) != 0) { nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); - inode->i_size = attr->ia_size; - vmtruncate(inode, attr->ia_size); + nfs_vmtruncate(inode, attr->ia_size); } } @@ -829,9 +884,9 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) if (S_ISDIR(inode->i_mode)) nfsi->cache_validity |= NFS_INO_INVALID_DATA; } - if (inode->i_size == nfs_size_to_loff_t(fattr->pre_size) && + if (i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) && nfsi->npages == 0) - inode->i_size = nfs_size_to_loff_t(fattr->size); + i_size_write(inode, nfs_size_to_loff_t(fattr->size)); } } @@ -972,7 +1027,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa (fattr->valid & NFS_ATTR_WCC) == 0) { memcpy(&fattr->pre_ctime, &inode->i_ctime, sizeof(fattr->pre_ctime)); memcpy(&fattr->pre_mtime, &inode->i_mtime, sizeof(fattr->pre_mtime)); - fattr->pre_size = inode->i_size; + fattr->pre_size = i_size_read(inode); fattr->valid |= NFS_ATTR_WCC; } return nfs_post_op_update_inode(inode, fattr); @@ -1057,7 +1112,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) /* Do we perhaps have any outstanding writes, or has * the file grown beyond our last write? */ if (nfsi->npages == 0 || new_isize > cur_isize) { - inode->i_size = new_isize; + i_size_write(inode, new_isize); invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; } dprintk("NFS: isize change on server for file %s/%ld\n", diff --git a/fs/nfs/write.c b/fs/nfs/write.c index feca8c6..3229e21 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -133,16 +133,21 @@ static struct nfs_page *nfs_page_find_request(struct page *page) static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) { struct inode *inode = page->mapping->host; - loff_t end, i_size = i_size_read(inode); - pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; + loff_t end, i_size; + pgoff_t end_index; + spin_lock(&inode->i_lock); + i_size = i_size_read(inode); + end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; if (i_size > 0 && page->index < end_index) - return; + goto out; end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + ((loff_t)offset+count); if (i_size >= end) - return; - nfs_inc_stats(inode, NFSIOS_EXTENDWRITE); + goto out; i_size_write(inode, end); + nfs_inc_stats(inode, NFSIOS_EXTENDWRITE); +out: + spin_unlock(&inode->i_lock); } /* A writeback failed: mark the page as bad, and invalidate the page cache */ -- cgit v0.10.2 From fa6dc9dc59c3a76fd209a97c8cf37395980fb903 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:26:14 -0400 Subject: NFS: Remove attribute update related BKL references Signed-off-by: Trond Myklebust diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3adabd1..df23f98 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -370,7 +370,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) if ((attr->ia_valid & ~ATTR_FILE) == 0) return 0; - lock_kernel(); /* Write all dirty data */ if (S_ISREG(inode->i_mode)) { filemap_write_and_wait(inode->i_mapping); @@ -384,7 +383,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr); if (error == 0) nfs_refresh_inode(inode, &fattr); - unlock_kernel(); return error; } @@ -700,7 +698,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) inode->i_sb->s_id, (long long)NFS_FILEID(inode)); nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); - lock_kernel(); if (is_bad_inode(inode)) goto out_nowait; if (NFS_STALE(inode)) @@ -749,7 +746,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) nfs_wake_up_inode(inode); out_nowait: - unlock_kernel(); return status; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 47cf83e..1b94e36 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -374,8 +374,6 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) }; int error; - lock_kernel(); - error = server->nfs_client->rpc_ops->statfs(server, fh, &res); if (error < 0) goto out_err; @@ -407,12 +405,10 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_namelen = server->namelen; - unlock_kernel(); return 0; out_err: dprintk("%s: statfs error = %d\n", __func__, -error); - unlock_kernel(); return error; } -- cgit v0.10.2 From 4d80f2ecd506d9732ad94a6da104580bb47680d6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:18 -0400 Subject: NFS: Remove the BKL from the permission checking code Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d6ec1c8..73e0f97 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1982,8 +1982,6 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) } force_lookup: - lock_kernel(); - if (!NFS_PROTO(inode)->access) goto out_notsup; @@ -1993,7 +1991,6 @@ force_lookup: put_rpccred(cred); } else res = PTR_ERR(cred); - unlock_kernel(); out: dfprintk(VFS, "NFS: permission(%s/%ld), mask=0x%x, res=%d\n", inode->i_sb->s_id, inode->i_ino, mask, res); @@ -2002,7 +1999,6 @@ out_notsup: res = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (res == 0) res = generic_permission(inode, mask, NULL); - unlock_kernel(); goto out; } -- cgit v0.10.2 From b6a2e569e2157509951c9f3f58dfa18b44ce91b3 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:26:16 -0400 Subject: NFS: Remove BKL usage from the write path Signed-off-by: Trond Myklebust diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 509dcb5..f919d9a 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -393,9 +393,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, zero_user_segment(page, pglen, PAGE_CACHE_SIZE); } - lock_kernel(); status = nfs_updatepage(file, page, offset, copied); - unlock_kernel(); unlock_page(page); page_cache_release(page); -- cgit v0.10.2 From bba67e0e3f4caba2b2b90b48ed798fb0461bcb86 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:26:23 -0400 Subject: NFS: Remove BKL usage from open() All the NFSv4 stateful operations are already protected by other locks (in particular by the rpc_sequence locks. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 73e0f97..c68ec44 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -139,10 +139,8 @@ nfs_opendir(struct inode *inode, struct file *filp) nfs_inc_stats(inode, NFSIOS_VFSOPEN); - lock_kernel(); /* Call generic open code in order to cache credentials */ res = nfs_open(inode, filp); - unlock_kernel(); return res; } @@ -1019,9 +1017,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry } /* Open the file on the server */ - lock_kernel(); res = nfs4_atomic_open(dir, dentry, nd); - unlock_kernel(); if (IS_ERR(res)) { error = PTR_ERR(res); switch (error) { @@ -1083,9 +1079,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) * operations that change the directory. We therefore save the * change attribute *before* we do the RPC call. */ - lock_kernel(); ret = nfs4_open_revalidate(dir, dentry, openflags, nd); - unlock_kernel(); out: dput(parent); if (!ret) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index f919d9a..9f1bed9 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -128,9 +128,7 @@ nfs_file_open(struct inode *inode, struct file *filp) return res; nfs_inc_stats(inode, NFSIOS_VFSOPEN); - lock_kernel(); res = nfs_open(inode, filp); - unlock_kernel(); return res; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4451287..c910413 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -451,9 +451,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) /* Save the delegation */ memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data)); rcu_read_unlock(); - lock_kernel(); ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); - unlock_kernel(); if (ret != 0) goto out; ret = -EAGAIN; -- cgit v0.10.2 From f1e2eda23513b68003202bddf1f84158baad8844 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:50:50 -0400 Subject: NFS: Remove the BKL from the inode creation operations nfs_instantiate() does not require the BKL, neither do the attribute updates or the RPC code. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c68ec44..d40e91e 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1232,14 +1232,11 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, if ((nd->flags & LOOKUP_CREATE) != 0) open_flags = nd->intent.open.flags; - lock_kernel(); error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd); if (error != 0) goto out_err; - unlock_kernel(); return 0; out_err: - unlock_kernel(); d_drop(dentry); return error; } @@ -1262,14 +1259,11 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) attr.ia_mode = mode; attr.ia_valid = ATTR_MODE; - lock_kernel(); status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev); if (status != 0) goto out_err; - unlock_kernel(); return 0; out_err: - unlock_kernel(); d_drop(dentry); return status; } @@ -1288,15 +1282,12 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) attr.ia_valid = ATTR_MODE; attr.ia_mode = mode | S_IFDIR; - lock_kernel(); error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr); if (error != 0) goto out_err; - unlock_kernel(); return 0; out_err: d_drop(dentry); - unlock_kernel(); return error; } -- cgit v0.10.2 From fc81af535e462764e17f638d542973fbef13b026 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:52:40 -0400 Subject: NFS: Remove the BKL from nfs_link() Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d40e91e..5ae8ee6 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1549,14 +1549,12 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) old_dentry->d_parent->d_name.name, old_dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name); - lock_kernel(); d_drop(dentry); error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); if (error == 0) { atomic_inc(&inode->i_count); d_add(dentry, inode); } - unlock_kernel(); return error; } -- cgit v0.10.2 From fc0f684c21b5d4b41dc2ec76f7c0897ac98f5b6e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:20 -0400 Subject: NFS: Remove BKL from NFS lookup code All dentry-related operations are already BKL-safe, since they are protected by the VFS locking. No extra locks should be needed in the NFS code. In the case of nfs_revalidate_inode(), we're only doing an attribute update (protected by the inode->i_lock). In the case of nfs_lookup(), we're instantiating a new dentry, so there should be no contention possible until after we call d_materialise_unique. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 5ae8ee6..60da755 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -777,7 +777,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) struct nfs_fattr fattr; parent = dget_parent(dentry); - lock_kernel(); dir = parent->d_inode; nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); inode = dentry->d_inode; @@ -815,7 +814,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out_valid: - unlock_kernel(); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is valid\n", __func__, dentry->d_parent->d_name.name, @@ -834,7 +832,6 @@ out_zap_parent: shrink_dcache_parent(dentry); } d_drop(dentry); - unlock_kernel(); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", __func__, dentry->d_parent->d_name.name, @@ -921,8 +918,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru res = ERR_PTR(-ENOMEM); dentry->d_op = NFS_PROTO(dir)->dentry_ops; - lock_kernel(); - /* * If we're doing an exclusive create, optimize away the lookup * but don't hash the dentry. @@ -930,7 +925,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru if (nfs_is_exclusive_create(dir, nd)) { d_instantiate(dentry, NULL); res = NULL; - goto out_unlock; + goto out; } parent = dentry->d_parent; @@ -958,8 +953,6 @@ no_entry: nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out_unblock_sillyrename: nfs_unblock_sillyrename(parent); -out_unlock: - unlock_kernel(); out: return res; } -- cgit v0.10.2 From bd9bb454b76fb6ca2d00f17313f9f9df5f5c404a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 16:09:59 -0400 Subject: NFS: Remove the BKL from the rename, rmdir and unlink operations Attribute updates are safe, and dentry operations are protected using VFS level locks. Defer removing the BKL from sillyrename until a separate patch. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 60da755..68e0688 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1297,14 +1297,12 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) dfprintk(VFS, "NFS: rmdir(%s/%ld), %s\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); - lock_kernel(); error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); /* Ensure the VFS deletes this inode */ if (error == 0 && dentry->d_inode != NULL) clear_nlink(dentry->d_inode); else if (error == -ENOENT) nfs_dentry_handle_enoent(dentry); - unlock_kernel(); return error; } @@ -1429,7 +1427,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); - lock_kernel(); spin_lock(&dcache_lock); spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1) { @@ -1437,6 +1434,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) spin_unlock(&dcache_lock); /* Start asynchronous writeout of the inode */ write_inode_now(dentry->d_inode, 0); + lock_kernel(); error = nfs_sillyrename(dir, dentry); unlock_kernel(); return error; @@ -1452,7 +1450,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); } else if (need_rehash) d_rehash(dentry); - unlock_kernel(); return error; } @@ -1587,7 +1584,6 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, * To prevent any new references to the target during the rename, * we unhash the dentry and free the inode in advance. */ - lock_kernel(); if (!d_unhashed(new_dentry)) { d_drop(new_dentry); rehash = new_dentry; @@ -1621,7 +1617,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; /* silly-rename the existing target ... */ + lock_kernel(); err = nfs_sillyrename(new_dir, new_dentry); + unlock_kernel(); if (!err) { new_dentry = rehash = dentry; new_inode = NULL; @@ -1665,7 +1663,6 @@ out: /* new dentry created? */ if (dentry) dput(dentry); - unlock_kernel(); return error; } -- cgit v0.10.2 From 52e2e8d37e01edf38ccdccc983fb13ec1456d63d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:21 -0400 Subject: NFS: Remove BKL from the sillydelete operations Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 68e0688..1bdc36b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -884,10 +884,8 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { - lock_kernel(); drop_nlink(inode); nfs_complete_unlink(dentry, inode); - unlock_kernel(); } iput(inode); } @@ -1434,9 +1432,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) spin_unlock(&dcache_lock); /* Start asynchronous writeout of the inode */ write_inode_now(dentry->d_inode, 0); - lock_kernel(); error = nfs_sillyrename(dir, dentry); - unlock_kernel(); return error; } if (!d_unhashed(dentry)) { @@ -1617,9 +1613,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; /* silly-rename the existing target ... */ - lock_kernel(); err = nfs_sillyrename(new_dir, new_dentry); - unlock_kernel(); if (!err) { new_dentry = rehash = dentry; new_inode = NULL; -- cgit v0.10.2 From 76566991f94c206d9c5881edcaf99ba72c9e9d61 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:22 -0400 Subject: NFS: Remove BKL from the symlink code Page cache accesses are serialised using page locks, whereas attribute updates are serialised using inode->i_lock. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 1bdc36b..e5f9502 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1482,13 +1482,9 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym attr.ia_mode = S_IFLNK | S_IRWXUGO; attr.ia_valid = ATTR_MODE; - lock_kernel(); - page = alloc_page(GFP_HIGHUSER); - if (!page) { - unlock_kernel(); + if (!page) return -ENOMEM; - } kaddr = kmap_atomic(page, KM_USER0); memcpy(kaddr, symname, pathlen); @@ -1503,7 +1499,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym dentry->d_name.name, symname, error); d_drop(dentry); __free_page(page); - unlock_kernel(); return error; } @@ -1521,7 +1516,6 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym } else __free_page(page); - unlock_kernel(); return 0; } -- cgit v0.10.2 From c3cc8c019ca09767d7c9b5457d5cf8ac65085f44 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:23 -0400 Subject: NFS: Remove BKL from the readdir code Page accesses are serialised using the page locks, whereas all attribute updates are serialised using the inode->i_lock. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e5f9502..28a238d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -534,8 +534,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) (long long)filp->f_pos); nfs_inc_stats(inode, NFSIOS_VFSGETDENTS); - lock_kernel(); - /* * filp->f_pos points to the dirent entry number. * *desc->dir_cookie has the cookie for the next entry. We have @@ -593,7 +591,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) } out: nfs_unblock_sillyrename(dentry); - unlock_kernel(); if (res > 0) res = 0; dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n", -- cgit v0.10.2 From a86dc496b764ebb1431677b38eab45310e5a2ad4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 13:37:09 -0400 Subject: SUNRPC: Remove the BKL from the callback functions Push it into those callback functions that actually need it. Note that all the NFS operations use their own locking, so don't need the BKL. Ditto for the rpcbind client. Signed-off-by: Trond Myklebust diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index fd7d466..1f6dc51 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -224,7 +224,9 @@ void nlm_release_call(struct nlm_rqst *call) static void nlmclnt_rpc_release(void *data) { + lock_kernel(); nlm_release_call(data); + unlock_kernel(); } static int nlm_wait_on_grace(wait_queue_head_t *queue) @@ -710,7 +712,9 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) die: return; retry_rebind: + lock_kernel(); nlm_rebind_host(req->a_host); + unlock_kernel(); retry_unlock: rpc_restart_call(task); } @@ -788,7 +792,9 @@ retry_cancel: /* Don't ever retry more than 3 times */ if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) goto die; + lock_kernel(); nlm_rebind_host(req->a_host); + unlock_kernel(); rpc_restart_call(task); rpc_delay(task, 30 * HZ); } diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 385437e..2e27176 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -248,7 +248,9 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data) static void nlm4svc_callback_release(void *data) { + lock_kernel(); nlm_release_call(data); + unlock_kernel(); } static const struct rpc_call_ops nlm4svc_callback_ops = { diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 81aca85..56a08ab 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -795,6 +795,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) dprintk("lockd: GRANT_MSG RPC callback\n"); + lock_kernel(); /* if the block is not on a list at this point then it has * been invalidated. Don't try to requeue it. * @@ -804,7 +805,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) * for nlm_blocked? */ if (list_empty(&block->b_list)) - return; + goto out; /* Technically, we should down the file semaphore here. Since we * move the block towards the head of the queue only, no harm @@ -818,13 +819,17 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); +out: + unlock_kernel(); } static void nlmsvc_grant_release(void *data) { struct nlm_rqst *call = data; + lock_kernel(); nlmsvc_release_block(call->a_block); + unlock_kernel(); } static const struct rpc_call_ops nlmsvc_grant_ops = { diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 88379cc..ce6952b 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -278,7 +278,9 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data) static void nlmsvc_callback_release(void *data) { + lock_kernel(); nlm_release_call(data); + unlock_kernel(); } static const struct rpc_call_ops nlmsvc_callback_ops = { diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 6288af0..385f427 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -576,9 +576,7 @@ EXPORT_SYMBOL_GPL(rpc_delay); */ static void rpc_prepare_task(struct rpc_task *task) { - lock_kernel(); task->tk_ops->rpc_call_prepare(task, task->tk_calldata); - unlock_kernel(); } /* @@ -588,9 +586,7 @@ void rpc_exit_task(struct rpc_task *task) { task->tk_action = NULL; if (task->tk_ops->rpc_call_done != NULL) { - lock_kernel(); task->tk_ops->rpc_call_done(task, task->tk_calldata); - unlock_kernel(); if (task->tk_action != NULL) { WARN_ON(RPC_ASSASSINATED(task)); /* Always release the RPC slot and buffer memory */ @@ -602,11 +598,8 @@ EXPORT_SYMBOL_GPL(rpc_exit_task); void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) { - if (ops->rpc_release != NULL) { - lock_kernel(); + if (ops->rpc_release != NULL) ops->rpc_release(calldata); - unlock_kernel(); - } } /* -- cgit v0.10.2 From f839c4c1991cc9b580ae38f98f54554938a7f49c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 Jun 2008 15:44:26 -0400 Subject: NFSv4: Remove BKL from the nfsv4 state recovery Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 856a893..401ef8b 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -940,7 +940,6 @@ static int reclaimer(void *ptr) allow_signal(SIGKILL); /* Ensure exclusive access to NFSv4 state */ - lock_kernel(); down_write(&clp->cl_sem); /* Are there any NFS mounts out there? */ if (list_empty(&clp->cl_superblocks)) @@ -1000,7 +999,6 @@ restart_loop: nfs_delegation_reap_unclaimed(clp); out: up_write(&clp->cl_sem); - unlock_kernel(); if (status == -NFS4ERR_CB_PATH_DOWN) nfs_handle_cb_pathdown(clp); nfs4_clear_recover_bit(clp); -- cgit v0.10.2 From 809d9a8f93bd8504dcc34b16bbfdfd1a8c9bb1ed Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Tue, 15 Jul 2008 11:59:42 -0700 Subject: x86/PCI: ACPI based PCI gap calculation Using ACPI to find free address space allows us to find a gap for the unallocated PCI resources or MMIO resources for hotplug devices within the BIOS allowed PCI regions. It works by evaluating the _CRS object under PCI0 looking for producer resources. Then searches the e820 memory space for a gap within these producer resources. Signed-off-by: Alok N Kataria Cc: Andi Kleen Cc: Len Brown Cc: Ingo Molnar Signed-off-by: Jesse Barnes diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index d95de2f..d1ffb57 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "pci.h" struct pci_root_info { @@ -14,6 +15,11 @@ struct pci_root_info { int busnum; }; +struct gap_info { + unsigned long gapstart; + unsigned long gapsize; +}; + static acpi_status resource_to_addr(struct acpi_resource *resource, struct acpi_resource_address64 *addr) @@ -110,6 +116,78 @@ adjust_transparent_bridge_resources(struct pci_bus *bus) } } +static acpi_status search_gap(struct acpi_resource *resource, void *data) +{ + struct acpi_resource_address64 addr; + acpi_status status; + struct gap_info *gap = data; + unsigned long long start_addr, end_addr; + + status = resource_to_addr(resource, &addr); + if (ACPI_SUCCESS(status) && + addr.resource_type == ACPI_MEMORY_RANGE && + addr.address_length > gap->gapsize) { + start_addr = addr.minimum + addr.translation_offset; + /* + * We want space only in the 32bit address range + */ + if (start_addr < UINT_MAX) { + end_addr = start_addr + addr.address_length; + e820_search_gap(&gap->gapstart, &gap->gapsize, + start_addr, end_addr); + } + } + + return AE_OK; +} + +/* + * Search for a hole in the 32 bit address space for PCI to assign MMIO + * resources, for hotplug or unconfigured resources. + * We query the CRS object of the PCI root device to look for possible producer + * resources in the tree and consider these while calulating the start address + * for this hole. + */ +static void pci_setup_gap(acpi_handle *handle) +{ + struct gap_info gap; + acpi_status status; + + gap.gapstart = 0; + gap.gapsize = 0x400000; + + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + search_gap, &gap); + + if (ACPI_SUCCESS(status)) { + unsigned long round; + + if (!gap.gapstart) { + printk(KERN_ERR "ACPI: Warning: Cannot find a gap " + "in the 32bit address range for PCI\n" + "ACPI: PCI devices may collide with " + "hotpluggable memory address range\n"); + } + /* + * Round the gapstart, uses the same logic as in + * e820_gap_setup + */ + round = 0x100000; + while ((gap.gapsize >> 4) > round) + round += round; + /* Fun with two's complement */ + pci_mem_start = (gap.gapstart + round) & -round; + + printk(KERN_INFO "ACPI: PCI resources should " + "start at %lx (gap: %lx:%lx)\n", + pci_mem_start, gap.gapstart, gap.gapsize); + } else { + printk(KERN_ERR "ACPI: Error while searching for gap in " + "the 32bit address range for PCI\n"); + } +} + + static void get_current_resources(struct acpi_device *device, int busnum, int domain, struct pci_bus *bus) @@ -215,6 +293,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do if (bus && (pci_probe & PCI_USE__CRS)) get_current_resources(device, busnum, domain, bus); + + pci_setup_gap(device->handle); return bus; } -- cgit v0.10.2 From f2d9c740f6b9f92608dfb2a2bdd797e0350cabe4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 15 Jul 2008 10:57:33 -0400 Subject: ftrace: ftrace.txt updates This patch includes ftrace.txt updates that address (mostly) comments from Andrew Morton. It also includes updates that were suggested by Randy Dunlap, John Kacur and David Teigland. Signed-off-by: Steven Rostedt Signed-off-by: Linus Torvalds diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt index 77d3faa..f218f61 100644 --- a/Documentation/ftrace.txt +++ b/Documentation/ftrace.txt @@ -4,9 +4,10 @@ Copyright 2008 Red Hat Inc. Author: Steven Rostedt License: The GNU Free Documentation License, Version 1.2 -Reviewers: Elias Oltmanns and Randy Dunlap +Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton, + John Kacur, and David Teigland. -Writen for: 2.6.26-rc8 linux-2.6-tip.git tip/tracing/ftrace branch +Written for: 2.6.27-rc1 Introduction ------------ @@ -18,10 +19,11 @@ issues that take place outside of user-space. Although ftrace is the function tracer, it also includes an infrastructure that allows for other types of tracing. Some of the -tracers that are currently in ftrace is a tracer to trace +tracers that are currently in ftrace include a tracer to trace context switches, the time it takes for a high priority task to run after it was woken up, the time interrupts are disabled, and -more. +more (ftrace allows for tracer plugins, which means that the list of +tracers can always grow). The File System @@ -35,6 +37,8 @@ To mount the debugfs system: # mkdir /debug # mount -t debugfs nodev /debug +(Note: it is more common to mount at /sys/kernel/debug, but for simplicity + this document will use /debug) That's it! (assuming that you have ftrace configured into your kernel) @@ -50,20 +54,19 @@ of ftrace. Here is a list of some of the key files: available_tracers : This holds the different types of tracers that have been compiled into the kernel. The tracers - listed here can be configured by echoing in their - name into current_tracer. + listed here can be configured by echoing their name + into current_tracer. tracing_enabled : This sets or displays whether the current_tracer is activated and tracing or not. Echo 0 into this - file to disable the tracer or 1 (or non-zero) to - enable it. + file to disable the tracer or 1 to enable it. trace : This file holds the output of the trace in a human readable - format. + format (described below). latency_trace : This file shows the same trace but the information is organized more to display possible latencies - in the system. + in the system (described below). trace_pipe : The output is the same as the "trace" file but this file is meant to be streamed with live tracing. @@ -75,7 +78,7 @@ of ftrace. Here is a list of some of the key files: file, it is consumed, and will not be read again with a sequential read. The "trace" and "latency_trace" files are static, and if the - tracer isn't adding more data, they will display + tracer is not adding more data, they will display the same information every time they are read. iter_ctrl : This file lets the user control the amount of data @@ -92,10 +95,10 @@ of ftrace. Here is a list of some of the key files: trace_entries : This sets or displays the number of trace entries each CPU buffer can hold. The tracer buffers - are the same size for each CPU, so care must be - taken when modifying the trace_entries. The trace - buffers are allocated in pages (blocks of memory that - the kernel uses for allocation, usually 4 KB in size). + are the same size for each CPU. The displayed number + is the size of the CPU buffer and not total size. The + trace buffers are allocated in pages (blocks of memory + that the kernel uses for allocation, usually 4 KB in size). Since each entry is smaller than a page, if the last allocated page has room for more entries than were requested, the rest of the page is used to allocate @@ -112,20 +115,19 @@ of ftrace. Here is a list of some of the key files: on specified CPUS. The format is a hex string representing the CPUS. - set_ftrace_filter : When dynamic ftrace is configured in, the - code is dynamically modified to disable calling - of the function profiler (mcount). This lets - tracing be configured in with practically no overhead - in performance. This also has a side effect of - enabling or disabling specific functions to be - traced. Echoing in names of functions into this - file will limit the trace to only these functions. - - set_ftrace_notrace: This has the opposite effect that - set_ftrace_filter has. Any function that is added - here will not be traced. If a function exists - in both set_ftrace_filter and set_ftrace_notrace, - the function will _not_ be traced. + set_ftrace_filter : When dynamic ftrace is configured in (see the + section below "dynamic ftrace"), the code is dynamically + modified (code text rewrite) to disable calling of the + function profiler (mcount). This lets tracing be configured + in with practically no overhead in performance. This also + has a side effect of enabling or disabling specific functions + to be traced. Echoing names of functions into this file + will limit the trace to only those functions. + + set_ftrace_notrace: This has an effect opposite to that of + set_ftrace_filter. Any function that is added here will not + be traced. If a function exists in both set_ftrace_filter + and set_ftrace_notrace, the function will _not_ be traced. available_filter_functions : When a function is encountered the first time by the dynamic tracer, it is recorded and @@ -133,32 +135,31 @@ of ftrace. Here is a list of some of the key files: lists the functions that have been recorded by the dynamic tracer and these functions can be used to set the ftrace filter by the above - "set_ftrace_filter" file. + "set_ftrace_filter" file. (See the section "dynamic ftrace" + below for more details). The Tracers ----------- -Here are the list of current tracers that can be configured. +Here is the list of current tracers that may be configured. ftrace - function tracer that uses mcount to trace all functions. - It is possible to filter out which functions that are - to be traced when dynamic ftrace is configured in. sched_switch - traces the context switches between tasks. - irqsoff - traces the areas that disable interrupts and saves off + irqsoff - traces the areas that disable interrupts and saves the trace with the longest max latency. See tracing_max_latency. When a new max is recorded, it replaces the old trace. It is best to view this - trace with the latency_trace file. + trace via the latency_trace file. - preemptoff - Similar to irqsoff but traces and records the time - preemption is disabled. + preemptoff - Similar to irqsoff but traces and records the amount of + time for which preemption is disabled. preemptirqsoff - Similar to irqsoff and preemptoff, but traces and - records the largest time irqs and/or preemption is - disabled. + records the largest time for which irqs and/or preemption + is disabled. wakeup - Traces and records the max latency that it takes for the highest priority task to get scheduled after @@ -171,13 +172,13 @@ Here are the list of current tracers that can be configured. Examples of using the tracer ---------------------------- -Here are typical examples of using the tracers with only controlling -them with the debugfs interface (without using any user-land utilities). +Here are typical examples of using the tracers when controlling them only +with the debugfs interface (without using any user-land utilities). Output format: -------------- -Here's an example of the output format of the file "trace" +Here is an example of the output format of the file "trace" -------- # tracer: ftrace @@ -189,14 +190,15 @@ Here's an example of the output format of the file "trace" bash-4251 [01] 10152.583855: _atomic_dec_and_lock <-dput -------- -A header is printed with the trace that is represented. In this case -the tracer is "ftrace". Then a header showing the format. Task name -"bash", the task PID "4251", the CPU that it was running on +A header is printed with the tracer name that is represented by the trace. +In this case the tracer is "ftrace". Then a header showing the format. Task +name "bash", the task PID "4251", the CPU that it was running on "01", the timestamp in . format, the function name that was traced "path_put" and the parent function that called this function -"path_walk". +"path_walk". The timestamp is the time at which the function was +entered. -The sched_switch tracer also includes tracing of task wake ups and +The sched_switch tracer also includes tracing of task wakeups and context switches. ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 2916:115:S @@ -206,7 +208,7 @@ context switches. kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R -Wake ups are represented by a "+" and the context switches show +Wake ups are represented by a "+" and the context switches are shown as "==>". The format is: Context switches: @@ -221,7 +223,7 @@ Wake ups are represented by a "+" and the context switches show :: + :: -The prio is the internal kernel priority, which is inverse to the +The prio is the internal kernel priority, which is the inverse of the priority that is usually displayed by user-space tools. Zero represents the highest priority (99). Prio 100 starts the "nice" priorities with 100 being equal to nice -20 and 139 being nice 19. The prio "140" is @@ -232,7 +234,7 @@ Latency trace format -------------------- For traces that display latency times, the latency_trace file gives -a bit more information to see why a latency happened. Here's a typical +somewhat more information to see why a latency happened. Here is a typical trace. # tracer: irqsoff @@ -260,21 +262,20 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8 -0 0d.s1 98us : trace_hardirqs_on (do_softirq) -vim:ft=help - -This shows that the current tracer is "irqsoff" tracing the time -interrupts are disabled. It gives the trace version and the kernel -this was executed on (2.6.26-rc8). Then it displays the max latency -in microsecs (97 us). The number of trace entries displayed -by the total number recorded (both are three: #3/3). The type of +This shows that the current tracer is "irqsoff" tracing the time for which +interrupts were disabled. It gives the trace version and the version +of the kernel upon which this was executed on (2.6.26-rc8). Then it displays +the max latency in microsecs (97 us). The number of trace entries displayed +and the total number recorded (both are three: #3/3). The type of preemption that was used (PREEMPT). VP, KP, SP, and HP are always zero -and reserved for later use. #P is the number of online CPUS (#P:2). +and are reserved for later use. #P is the number of online CPUS (#P:2). -The task is the process that was running when the latency happened. +The task is the process that was running when the latency occurred. (swapper pid: 0). -The start and stop that caused the latencies: +The start and stop (the functions in which the interrupts were disabled and +enabled respectively) that caused the latencies: apic_timer_interrupt is where the interrupts were disabled. do_softirq is where they were enabled again. @@ -286,14 +287,14 @@ explains which is which. pid: The PID of that process. - CPU#: The CPU that the process was running on. + CPU#: The CPU which the process was running on. irqs-off: 'd' interrupts are disabled. '.' otherwise. need-resched: 'N' task need_resched is set, '.' otherwise. hardirq/softirq: - 'H' - hard irq happened inside a softirq. + 'H' - hard irq occurred inside a softirq. 'h' - hard irq is running 's' - soft irq is running '.' - normal context. @@ -303,7 +304,7 @@ explains which is which. The above is mostly meaningful for kernel developers. time: This differs from the trace file output. The trace file output - included an absolute timestamp. The timestamp used by the + includes an absolute timestamp. The timestamp used by the latency_trace file is relative to the start of the trace. delay: This is just to help catch your eye a bit better. And @@ -385,7 +386,7 @@ Here are the available options: sched_switch ------------ -This tracer simply records schedule switches. Here's an example +This tracer simply records schedule switches. Here is an example of how to use it. # echo sched_switch > /debug/tracing/current_tracer @@ -421,8 +422,8 @@ the name of the trace and points to the options. The "FUNCTION" is a misnomer since here it represents the wake ups and context switches. -The sched_switch only lists the wake ups (represented with '+') -and context switches ('==>') with the previous task or current +The sched_switch file only lists the wake ups (represented with '+') +and context switches ('==>') with the previous task or current task first followed by the next task or task waking up. The format for both of these is PID:KERNEL-PRIO:TASK-STATE. Remember that the KERNEL-PRIO is the inverse of the actual priority with zero (0) being the highest @@ -437,7 +438,8 @@ The task states are: R - running : wants to run, may not actually be running S - sleep : process is waiting to be woken up (handles signals) - D - deep sleep : process must be woken up (ignores signals) + D - disk sleep (uninterruptible sleep) : process must be woken up + (ignores signals) T - stopped : process suspended t - traced : process is being traced (with something like gdb) Z - zombie : process waiting to be cleaned up @@ -447,8 +449,8 @@ The task states are: ftrace_enabled -------------- -The following tracers give different output depending on whether -or not the sysctl ftrace_enabled is set. To set ftrace_enabled, +The following tracers (listed below) give different output depending +on whether or not the sysctl ftrace_enabled is set. To set ftrace_enabled, one can either use the sysctl function or set it via the proc file system interface. @@ -475,13 +477,12 @@ interrupt from triggering or the mouse interrupt from letting the kernel know of a new mouse event. The result is a latency with the reaction time. -The irqsoff tracer tracks the time interrupts are disabled to the time -they are re-enabled. When a new maximum latency is hit, it saves off -the trace so that it may be retrieved at a later time. Every time a -new maximum in reached, the old saved trace is discarded and the new -trace is saved. +The irqsoff tracer tracks the time for which interrupts are disabled. +When a new maximum latency is hit, the tracer saves the trace leading up +to that latency point so that every time a new maximum is reached, the old +saved trace is discarded and the new trace is saved. -To reset the maximum, echo 0 into tracing_max_latency. Here's an +To reset the maximum, echo 0 into tracing_max_latency. Here is an example: # echo irqsoff > /debug/tracing/current_tracer @@ -493,14 +494,14 @@ example: # cat /debug/tracing/latency_trace # tracer: irqsoff # -irqsoff latency trace v1.1.5 on 2.6.26-rc8 +irqsoff latency trace v1.1.5 on 2.6.26 -------------------------------------------------------------------- - latency: 6 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) + latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) ----------------- - | task: bash-4269 (uid:0 nice:0 policy:0 rt_prio:0) + | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0) ----------------- - => started at: copy_page_range - => ended at: copy_page_range + => started at: sys_setpgid + => ended at: sys_setpgid # _------=> CPU# # / _-----=> irqs-off @@ -511,21 +512,19 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8 # ||||| delay # cmd pid ||||| time | caller # \ / ||||| \ | / - bash-4269 1...1 0us+: _spin_lock (copy_page_range) - bash-4269 1...1 7us : _spin_unlock (copy_page_range) - bash-4269 1...2 7us : trace_preempt_on (copy_page_range) - + bash-3730 1d... 0us : _write_lock_irq (sys_setpgid) + bash-3730 1d..1 1us+: _write_unlock_irq (sys_setpgid) + bash-3730 1d..2 14us : trace_hardirqs_on (sys_setpgid) -vim:ft=help -Here we see that that we had a latency of 6 microsecs (which is -very good). The spin_lock in copy_page_range disabled interrupts. -The difference between the 6 and the displayed timestamp 7us is -because the clock must have incremented between the time of recording -the max latency and recording the function that had that latency. +Here we see that that we had a latency of 12 microsecs (which is +very good). The _write_lock_irq in sys_setpgid disabled interrupts. +The difference between the 12 and the displayed timestamp 14us occurred +because the clock was incremented between the time of recording the max +latency and the time of recording the function that had that latency. -Note the above had ftrace_enabled not set. If we set the ftrace_enabled, -we get a much larger output: +Note the above example had ftrace_enabled not set. If we set the +ftrace_enabled, we get a much larger output: # tracer: irqsoff # @@ -571,12 +570,10 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8 ls-4339 0d..2 51us : trace_hardirqs_on (__alloc_pages_internal) -vim:ft=help - Here we traced a 50 microsecond latency. But we also see all the functions that were called during that time. Note that by enabling -function tracing, we endure an added overhead. This overhead may +function tracing, we incur an added overhead. This overhead may extend the latency times. But nevertheless, this trace has provided some very helpful debugging information. @@ -590,8 +587,9 @@ for preemption to be enabled again before it can preempt a lower priority task. The preemptoff tracer traces the places that disable preemption. -Like the irqsoff, it records the maximum latency that preemption -was disabled. The control of preemptoff is much like the irqsoff. +Like the irqsoff tracer, it records the maximum latency for which preemption +was disabled. The control of preemptoff tracer is much like the irqsoff +tracer. # echo preemptoff > /debug/tracing/current_tracer # echo 0 > /debug/tracing/tracing_max_latency @@ -625,8 +623,6 @@ preemptoff latency trace v1.1.5 on 2.6.26-rc8 sshd-4261 0d.s1 30us : trace_preempt_on (__do_softirq) -vim:ft=help - This has some more changes. Preemption was disabled when an interrupt came in (notice the 'h'), and was enabled while doing a softirq. (notice the 's'). But we also see that interrupts have been disabled @@ -694,16 +690,16 @@ The above is an example of the preemptoff trace with ftrace_enabled set. Here we see that interrupts were disabled the entire time. The irq_enter code lets us know that we entered an interrupt 'h'. Before that, the functions being traced still show that it is not -in an interrupt, but we can see by the functions themselves that +in an interrupt, but we can see from the functions themselves that this is not the case. -Notice that the __do_softirq when called doesn't have a preempt_count. -It may seem that we missed a preempt enabled. What really happened -is that the preempt count is held on the threads stack and we +Notice that __do_softirq when called does not have a preempt_count. +It may seem that we missed a preempt enabling. What really happened +is that the preempt count is held on the thread's stack and we switched to the softirq stack (4K stacks in effect). The code does not copy the preempt count, but because interrupts are disabled, -we don't need to worry about it. Having a tracer like this is good -to let people know what really happens inside the kernel. +we do not need to worry about it. Having a tracer like this is good +for letting people know what really happens inside the kernel. preemptirqsoff @@ -713,7 +709,7 @@ Knowing the locations that have interrupts disabled or preemption disabled for the longest times is helpful. But sometimes we would like to know when either preemption and/or interrupts are disabled. -The following code: +Consider the following code: local_irq_disable(); call_function_with_irqs_off(); @@ -769,12 +765,10 @@ preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8 ls-4860 0d.s1 294us : trace_preempt_on (__do_softirq) -vim:ft=help - The trace_hardirqs_off_thunk is called from assembly on x86 when interrupts are disabled in the assembly code. Without the function -tracing, we don't know if interrupts were enabled within the preemption +tracing, we do not know if interrupts were enabled within the preemption points. We do see that it started with preemption enabled. Here is a trace with ftrace_enabled set: @@ -865,19 +859,19 @@ preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8 This is a very interesting trace. It started with the preemption of the ls task. We see that the task had the "need_resched" bit set -with the 'N' in the trace. Interrupts are disabled in the spin_lock -and the trace started. We see that a schedule took place to run +via the 'N' in the trace. Interrupts were disabled before the spin_lock +at the beginning of the trace. We see that a schedule took place to run sshd. When the interrupts were enabled, we took an interrupt. On return from the interrupt handler, the softirq ran. We took another -interrupt while running the softirq as we see with the capital 'H'. +interrupt while running the softirq as we see from the capital 'H'. wakeup ------ -In Real-Time environment it is very important to know the wakeup -time it takes for the highest priority task that wakes up to the -time it executes. This is also known as "schedule latency". +In a Real-Time environment it is very important to know the wakeup +time it takes for the highest priority task that is woken up to the +time that it executes. This is also known as "schedule latency". I stress the point that this is about RT tasks. It is also important to know the scheduling latency of non-RT tasks, but the average schedule latency is better for non-RT tasks. Tools like @@ -926,8 +920,6 @@ wakeup latency trace v1.1.5 on 2.6.26-rc8 -0 1d..4 4us : schedule (cpu_idle) -vim:ft=help - Running this on an idle system, we see that it only took 4 microseconds to perform the task switch. Note, since the trace marker in the @@ -996,15 +988,15 @@ ksoftirq-7 1d..6 49us : sub_preempt_count (_spin_unlock) ksoftirq-7 1d..4 50us : schedule (__cond_resched) The interrupt went off while running ksoftirqd. This task runs at -SCHED_OTHER. Why didn't we see the 'N' set early? This may be +SCHED_OTHER. Why did not we see the 'N' set early? This may be a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K stacks -configured, the interrupt and softirq runs with their own stack. +configured, the interrupt and softirq run with their own stack. Some information is held on the top of the task's stack (need_resched and preempt_count are both stored there). The setting of the NEED_RESCHED bit is done directly to the task's stack, but the reading of the NEED_RESCHED is done by looking at the current stack, which in this case is the stack for the hard interrupt. This hides the fact that NEED_RESCHED -has been set. We don't see the 'N' until we switch back to the task's +has been set. We do not see the 'N' until we switch back to the task's assigned stack. ftrace @@ -1044,14 +1036,14 @@ this tracer is a nop. [...] -Note: It is sometimes better to enable or disable tracing directly from -a program, because the buffer may be overflowed by the echo commands -before you get to the point you want to trace. It is also easier to -stop the tracing at the point that you hit the part that you are -interested in. Since the ftrace buffer is a ring buffer with the -oldest data being overwritten, usually it is sufficient to start the -tracer with an echo command but have you code stop it. Something -like the following is usually appropriate for this. +Note: ftrace uses ring buffers to store the above entries. The newest data +may overwrite the oldest data. Sometimes using echo to stop the trace +is not sufficient because the tracing could have overwritten the data +that you wanted to record. For this reason, it is sometimes better to +disable tracing directly from a program. This allows you to stop the +tracing at the point that you hit the part that you are interested in. +To disable the tracing directly from a C program, something like following +code snippet can be used: int trace_fd; [...] @@ -1060,20 +1052,26 @@ int main(int argc, char *argv[]) { trace_fd = open("/debug/tracing/tracing_enabled", O_WRONLY); [...] if (condition_hit()) { - write(trace_fd, "0", 1); + write(trace_fd, "0", 1); } [...] } +Note: Here we hard coded the path name. The debugfs mount is not +guaranteed to be at /debug (and is more commonly at /sys/kernel/debug). +For simple one time traces, the above is sufficent. For anything else, +a search through /proc/mounts may be needed to find where the debugfs +file-system is mounted. dynamic ftrace -------------- -If CONFIG_DYNAMIC_FTRACE is set, then the system will run with +If CONFIG_DYNAMIC_FTRACE is set, the system will run with virtually no overhead when function tracing is disabled. The way this works is the mcount function call (placed at the start of every kernel function, produced by the -pg switch in gcc), starts -of pointing to a simple return. +of pointing to a simple return. (Enabling FTRACE will include the +-pg switch in the compiling of the kernel.) When dynamic ftrace is initialized, it calls kstop_machine to make the machine act like a uniprocessor so that it can freely modify code @@ -1086,15 +1084,15 @@ Later on the ftraced kernel thread is awoken and will again call kstop_machine if new functions have been recorded. The ftraced thread will change all calls to mcount to "nop". Just calling mcount and having mcount return has shown a 10% overhead. By converting -it to a nop, there is no recordable overhead to the system. +it to a nop, there is no measurable overhead to the system. One special side-effect to the recording of the functions being -traced, is that we can now selectively choose which functions we -want to trace and which ones we want the mcount calls to remain as +traced is that we can now selectively choose which functions we +wish to trace and which ones we want the mcount calls to remain as nops. Two files are used, one for enabling and one for disabling the tracing -of recorded functions. They are: +of specified functions. They are: set_ftrace_filter @@ -1116,7 +1114,7 @@ pick_next_task_fair mutex_lock [...] -If I'm only interested in sys_nanosleep and hrtimer_interrupt: +If I am only interested in sys_nanosleep and hrtimer_interrupt: # echo sys_nanosleep hrtimer_interrupt \ > /debug/tracing/set_ftrace_filter @@ -1133,21 +1131,21 @@ If I'm only interested in sys_nanosleep and hrtimer_interrupt: usleep-4134 [00] 1317.070111: sys_nanosleep <-syscall_call -0 [00] 1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt -To see what functions are being traced, you can cat the file: +To see which functions are being traced, you can cat the file: # cat /debug/tracing/set_ftrace_filter hrtimer_interrupt sys_nanosleep -Perhaps this isn't enough. The filters also allow simple wild cards. +Perhaps this is not enough. The filters also allow simple wild cards. Only the following are currently available * - will match functions that begin with * - will match functions that end with ** - will match functions that have in it -Thats all the wild cards that are allowed. +These are the only wild cards which are supported. * will not work. @@ -1258,15 +1256,15 @@ calls that need to be converted into nops. If there are not any, then it simply goes back to sleep. But if there are some, it will call kstop_machine to convert the calls to nops. -There may be a case that you do not want this added latency. +There may be a case in which you do not want this added latency. Perhaps you are doing some audio recording and this activity might cause skips in the playback. There is an interface to disable -and enable the ftraced kernel thread. +and enable the "ftraced" kernel thread. # echo 0 > /debug/tracing/ftraced_enabled -This will disable the calling of the kstop_machine to update the -mcount calls to nops. Remember that there's a large overhead +This will disable the calling of kstop_machine to update the +mcount calls to nops. Remember that there is a large overhead to calling mcount. Without this kernel thread, that overhead will exist. @@ -1282,8 +1280,8 @@ that uses ftrace function recording. trace_pipe ---------- -The trace_pipe outputs the same as trace, but the effect on the -tracing is different. Every read from trace_pipe is consumed. +The trace_pipe outputs the same content as the trace file, but the effect +on the tracing is different. Every read from trace_pipe is consumed. This means that subsequent reads will be different. The trace is live. @@ -1313,7 +1311,7 @@ is live. bash-4043 [00] 41.267111: select_task_rq_rt <-try_to_wake_up -Note, reading the trace_pipe will block until more input is added. +Note, reading the trace_pipe file will block until more input is added. By changing the tracer, trace_pipe will issue an EOF. We needed to set the ftrace tracer _before_ cating the trace_pipe file. @@ -1322,7 +1320,7 @@ trace entries ------------- Having too much or not enough data can be troublesome in diagnosing -some issue in the kernel. The file trace_entries is used to modify +an issue in the kernel. The file trace_entries is used to modify the size of the internal trace buffers. The number listed is the number of entries that can be recorded per CPU. To know the full size, multiply the number of possible CPUS with the @@ -1332,7 +1330,8 @@ number of entries. 65620 Note, to modify this, you must have tracing completely disabled. To do that, -echo "none" into the current_tracer. +echo "none" into the current_tracer. If the current_tracer is not set +to "none", an EINVAL error will be returned. # echo none > /debug/tracing/current_tracer # echo 100000 > /debug/tracing/trace_entries @@ -1341,18 +1340,18 @@ echo "none" into the current_tracer. Notice that we echoed in 100,000 but the size is 100,045. The entries -are held by individual pages. It allocates the number of pages it takes +are held in individual pages. It allocates the number of pages it takes to fulfill the request. If more entries may fit on the last page -it will add them. +then they will be added. # echo 1 > /debug/tracing/trace_entries # cat /debug/tracing/trace_entries 85 -This shows us that 85 entries can fit on a single page. +This shows us that 85 entries can fit in a single page. -The number of pages that will be allocated is a percentage of available -memory. Allocating too much will produce an error. +The number of pages which will be allocated is limited to a percentage +of available memory. Allocating too much will produce an error. # echo 1000000000000 > /debug/tracing/trace_entries -bash: echo: write error: Cannot allocate memory -- cgit v0.10.2 From d25dc7fd4740decf4c66e2f17dbaa288448fabd5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 15 Jul 2008 22:54:04 -0700 Subject: Fix 'make clean' and .gitignore for firmware/ directory. Provide a .gitignore file, and fix a typo which prevented some of the generated binary files from being removed on 'make clean'. Signed-off-by: David Woodhouse Reported-and-tested-by: Alexey Dobriyan Signed-off-by: Linus Torvalds diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..d9c6901 --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,6 @@ +*.gen.S +*.fw +*.bin +*.csp +*.dsp +ihex2fw diff --git a/firmware/Makefile b/firmware/Makefile index e4f2fb3..9fe8604 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -56,7 +56,7 @@ fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA28X) += keyspan/usa28x.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49W) += keyspan/usa49w.fw fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA49WLC) += keyspan/usa49wlc.fw else -fw-shipped- := keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ +fw-shipped- += keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \ keyspan/usa19qi.fw keyspan/usa19qw.fw keyspan/usa19w.fw \ keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \ keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw -- cgit v0.10.2 From 9fce1bc956c21dfe0f46be028f18c4d5057f2bd7 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 16 Jul 2008 22:54:30 +0800 Subject: PCI: remove unnecessary volatile in PCIe hotplug struct controller Proper memory barriers have been added to order accesses to ->cmd_busy, so volatile declaration for cmd_busy can be removed. Signed-off-by: Ming Lei Signed-off-by: Jesse Barnes diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index d17233a..e3a1e7e 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -97,7 +97,7 @@ struct controller { u32 slot_cap; u8 cap_base; struct timer_list poll_timer; - volatile int cmd_busy; + int cmd_busy; unsigned int no_cmd_complete:1; }; -- cgit v0.10.2 From e22146e610bb7aed63282148740ab1d1b91e1d90 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Wed, 16 Jul 2008 11:11:59 -0500 Subject: x86: fix kernel_physical_mapping_init() for large x86 systems Fix bug in kernel_physical_mapping_init() that causes kernel page table to be built incorrectly for systems with greater than 512GB of memory. Signed-off-by: Jack Steiner Cc: linux-mm@kvack.org Signed-off-by: Ingo Molnar diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 27de243..306049e 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -644,7 +644,7 @@ static unsigned long __init kernel_physical_mapping_init(unsigned long start, unsigned long pud_phys; pud_t *pud; - next = start + PGDIR_SIZE; + next = (start + PGDIR_SIZE) & PGDIR_MASK; if (next > end) next = end; -- cgit v0.10.2 From bd4bc3dbded9cd7b2bdca6bba1aecb4251a8039d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:05 +0200 Subject: i2c: Clear i2c_adapter.dev on adapter removal Clear i2c_adapter.dev on adapter removal. This makes it possible to re-add the adapter at a later point, which some drivers (i2c-amd756-s4882, i2c-nforce2-s4985) actually do. This fixes a bug reported by John Stultz here: http://lkml.org/lkml/2008/7/15/720 and by Ingo Molar there: http://lkml.org/lkml/2008/7/16/78 Signed-off-by: Jean Delvare Cc: John Stultz Cc: Ingo Molnar diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 2f150e3..72872d1 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -155,6 +155,16 @@ static int __init amd756_s4882_init(void) int i, error; union i2c_smbus_data ioconfig; + /* Configure the PCA9556 multiplexer */ + ioconfig.byte = 0x00; /* All I/O to output mode */ + error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, + I2C_SMBUS_BYTE_DATA, &ioconfig); + if (error) { + dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n"); + error = -EIO; + goto ERROR0; + } + /* Unregister physical bus */ error = i2c_del_adapter(&amd756_smbus); if (error) { @@ -198,22 +208,11 @@ static int __init amd756_s4882_init(void) s4882_algo[3].smbus_xfer = amd756_access_virt3; s4882_algo[4].smbus_xfer = amd756_access_virt4; - /* Configure the PCA9556 multiplexer */ - ioconfig.byte = 0x00; /* All I/O to output mode */ - error = amd756_smbus.algo->smbus_xfer(&amd756_smbus, 0x18, 0, - I2C_SMBUS_WRITE, 0x03, - I2C_SMBUS_BYTE_DATA, &ioconfig); - if (error) { - dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n"); - error = -EIO; - goto ERROR3; - } - /* Register virtual adapters */ for (i = 0; i < 5; i++) { error = i2c_add_adapter(s4882_adapter+i); if (error) { - dev_err(&amd756_smbus.dev, + printk(KERN_ERR "i2c-amd756-s4882: " "Virtual adapter %d registration " "failed, module not inserted\n", i); for (i--; i >= 0; i--) @@ -252,8 +251,8 @@ static void __exit amd756_s4882_exit(void) /* Restore physical bus */ if (i2c_add_adapter(&amd756_smbus)) - dev_err(&amd756_smbus.dev, "Physical bus restoration " - "failed\n"); + printk(KERN_ERR "i2c-amd756-s4882: " + "Physical bus restoration failed\n"); } MODULE_AUTHOR("Jean Delvare "); diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c index 6a8995d..d1a4cbc 100644 --- a/drivers/i2c/busses/i2c-nforce2-s4985.c +++ b/drivers/i2c/busses/i2c-nforce2-s4985.c @@ -150,6 +150,16 @@ static int __init nforce2_s4985_init(void) int i, error; union i2c_smbus_data ioconfig; + /* Configure the PCA9556 multiplexer */ + ioconfig.byte = 0x00; /* All I/O to output mode */ + error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, + I2C_SMBUS_BYTE_DATA, &ioconfig); + if (error) { + dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n"); + error = -EIO; + goto ERROR0; + } + /* Unregister physical bus */ if (!nforce2_smbus) return -ENODEV; @@ -191,24 +201,13 @@ static int __init nforce2_s4985_init(void) s4985_algo[3].smbus_xfer = nforce2_access_virt3; s4985_algo[4].smbus_xfer = nforce2_access_virt4; - /* Configure the PCA9556 multiplexer */ - ioconfig.byte = 0x00; /* All I/O to output mode */ - error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0, - I2C_SMBUS_WRITE, 0x03, - I2C_SMBUS_BYTE_DATA, &ioconfig); - if (error) { - dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n"); - error = -EIO; - goto ERROR3; - } - /* Register virtual adapters */ for (i = 0; i < 5; i++) { error = i2c_add_adapter(s4985_adapter + i); if (error) { - dev_err(&nforce2_smbus->dev, - "Virtual adapter %d registration " - "failed, module not inserted\n", i); + printk(KERN_ERR "i2c-nforce2-s4985: " + "Virtual adapter %d registration " + "failed, module not inserted\n", i); for (i--; i >= 0; i--) i2c_del_adapter(s4985_adapter + i); goto ERROR3; @@ -245,8 +244,8 @@ static void __exit nforce2_s4985_exit(void) /* Restore physical bus */ if (i2c_add_adapter(nforce2_smbus)) - dev_err(&nforce2_smbus->dev, "Physical bus restoration " - "failed\n"); + printk(KERN_ERR "i2c-nforce2-s4985: " + "Physical bus restoration failed\n"); } MODULE_AUTHOR("Jean Delvare "); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0a79f76..7608df8 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -654,6 +654,10 @@ int i2c_del_adapter(struct i2c_adapter *adap) dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); + /* Clear the device structure in case this adapter is ever going to be + added again */ + memset(&adap->dev, 0, sizeof(adap->dev)); + out_unlock: mutex_unlock(&core_lock); return res; -- cgit v0.10.2 From 68be3363740e4ac3b4309faebcdf8fe5bf62ed2f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:05 +0200 Subject: i2c: Convert the eeprom driver to a new-style i2c driver The new-style eeprom driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 373ea8d..2c27193 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c @@ -47,7 +47,6 @@ enum eeprom_nature { /* Each client has this additional data */ struct eeprom_data { - struct i2c_client client; struct mutex update_lock; u8 valid; /* bitfield, bit!=0 if slice is valid */ unsigned long last_updated[8]; /* In jiffies, 8 slices */ @@ -56,19 +55,6 @@ struct eeprom_data { }; -static int eeprom_attach_adapter(struct i2c_adapter *adapter); -static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind); -static int eeprom_detach_client(struct i2c_client *client); - -/* This is the driver that will be inserted */ -static struct i2c_driver eeprom_driver = { - .driver = { - .name = "eeprom", - }, - .attach_adapter = eeprom_attach_adapter, - .detach_client = eeprom_detach_client, -}; - static void eeprom_update_client(struct i2c_client *client, u8 slice) { struct eeprom_data *data = i2c_get_clientdata(client); @@ -148,25 +134,17 @@ static struct bin_attribute eeprom_attr = { .read = eeprom_read, }; -static int eeprom_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & (I2C_CLASS_DDC | I2C_CLASS_SPD))) - return 0; - return i2c_probe(adapter, &addr_data, eeprom_detect); -} - -/* This function is called by i2c_probe */ -static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int eeprom_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct eeprom_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all addresses 0x50-0x57, but we only care about 0x50. So decline attaching to addresses >= 0x51 on DDC buses */ - if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51) - goto exit; + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) + return -ENODEV; /* There are four ways we can read the EEPROM data: (1) I2C block reads (faster, but unsupported by most adapters) @@ -177,32 +155,33 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) because all known adapters support one of the first two. */ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) - goto exit; + return -ENODEV; + + strlcpy(info->type, "eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct eeprom_data *data; + int err; if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - client = &data->client; memset(data->data, 0xff, EEPROM_SIZE); i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &eeprom_driver; - - /* Fill in the remaining client fields */ - strlcpy(client->name, "eeprom", I2C_NAME_SIZE); mutex_init(&data->update_lock); data->nature = UNKNOWN; - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - /* Detect the Vaio nature of EEPROMs. We use the "PCG-" or "VGN-" prefix as the signature. */ - if (address == 0x57 + if (client->addr == 0x57 && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { char name[4]; @@ -221,33 +200,42 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) /* create the sysfs eeprom file */ err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); if (err) - goto exit_detach; + goto exit_kfree; return 0; -exit_detach: - i2c_detach_client(client); exit_kfree: kfree(data); exit: return err; } -static int eeprom_detach_client(struct i2c_client *client) +static int eeprom_remove(struct i2c_client *client) { - int err; - sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); - - err = i2c_detach_client(client); - if (err) - return err; - kfree(i2c_get_clientdata(client)); return 0; } +static const struct i2c_device_id eeprom_id[] = { + { "eeprom", 0 }, + { } +}; + +static struct i2c_driver eeprom_driver = { + .driver = { + .name = "eeprom", + }, + .probe = eeprom_probe, + .remove = eeprom_remove, + .id_table = eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = eeprom_detect, + .address_data = &addr_data, +}; + static int __init eeprom_init(void) { return i2c_add_driver(&eeprom_driver); -- cgit v0.10.2 From 8b77e6ac4911a79993e583ece719736a9e035b1d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:06 +0200 Subject: i2c: Convert the pcf8591 driver to a new-style i2c driver The new-style pcf8591 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index db73537..16ce3e1 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c @@ -72,28 +72,15 @@ MODULE_PARM_DESC(input_mode, #define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg)) struct pcf8591_data { - struct i2c_client client; struct mutex update_lock; u8 control; u8 aout; }; -static int pcf8591_attach_adapter(struct i2c_adapter *adapter); -static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind); -static int pcf8591_detach_client(struct i2c_client *client); static void pcf8591_init_client(struct i2c_client *client); static int pcf8591_read_channel(struct device *dev, int channel); -/* This is the driver that will be inserted */ -static struct i2c_driver pcf8591_driver = { - .driver = { - .name = "pcf8591", - }, - .attach_adapter = pcf8591_attach_adapter, - .detach_client = pcf8591_detach_client, -}; - /* following are the sysfs callback functions */ #define show_in_channel(channel) \ static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \ @@ -180,58 +167,46 @@ static const struct attribute_group pcf8591_attr_group_opt = { /* * Real code */ -static int pcf8591_attach_adapter(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, pcf8591_detect); -} -/* This function is called by i2c_probe */ -static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int pcf8591_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct pcf8591_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) - goto exit; + return -ENODEV; + + /* Now, we would do the remaining detection. But the PCF8591 is plainly + impossible to detect! Stupid chip. */ + + strlcpy(info->type, "pcf8591", I2C_NAME_SIZE); + + return 0; +} + +static int pcf8591_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct pcf8591_data *data; + int err; - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. */ if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - client = &data->client; i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &pcf8591_driver; - - /* Now, we would do the remaining detection. But the PCF8591 is plainly - impossible to detect! Stupid chip. */ - - /* Determine the chip type - only one kind supported! */ - if (kind <= 0) - kind = pcf8591; - - /* Fill in the remaining client fields and put it into the global - list */ - strlcpy(client->name, "pcf8591", I2C_NAME_SIZE); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - /* Initialize the PCF8591 chip */ pcf8591_init_client(client); /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group); if (err) - goto exit_detach; + goto exit_kfree; /* Register input2 if not in "two differential inputs" mode */ if (input_mode != 3) { @@ -252,24 +227,16 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) exit_sysfs_remove: sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); -exit_detach: - i2c_detach_client(client); exit_kfree: kfree(data); exit: return err; } -static int pcf8591_detach_client(struct i2c_client *client) +static int pcf8591_remove(struct i2c_client *client) { - int err; - sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt); sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); - - if ((err = i2c_detach_client(client))) - return err; - kfree(i2c_get_clientdata(client)); return 0; } @@ -316,6 +283,25 @@ static int pcf8591_read_channel(struct device *dev, int channel) return (10 * value); } +static const struct i2c_device_id pcf8591_id[] = { + { "pcf8591", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pcf8591_id); + +static struct i2c_driver pcf8591_driver = { + .driver = { + .name = "pcf8591", + }, + .probe = pcf8591_probe, + .remove = pcf8591_remove, + .id_table = pcf8591_id, + + .class = I2C_CLASS_HWMON, /* Nearest choice */ + .detect = pcf8591_detect, + .address_data = &addr_data, +}; + static int __init pcf8591_init(void) { if (input_mode < 0 || input_mode > 3) { -- cgit v0.10.2 From 833bedb813689807385ae73175389c73a3f855c1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:06 +0200 Subject: i2c: Convert the pcf8574 driver to a new-style i2c driver The new-style pcf8574 driver implements the optional detect() callback to cover the use cases of the legacy driver. Warning: users will now have to use the force module parameter to get the driver to attach to their device. That's not a bad thing as these devices can't be detected anyway. Note that this doesn't change the fact that this driver is deprecated in favor of gpio/pcf857x. Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/chips/pcf8574 b/Documentation/i2c/chips/pcf8574 index 5c1ad13..235815c 100644 --- a/Documentation/i2c/chips/pcf8574 +++ b/Documentation/i2c/chips/pcf8574 @@ -4,13 +4,13 @@ Kernel driver pcf8574 Supported chips: * Philips PCF8574 Prefix: 'pcf8574' - Addresses scanned: I2C 0x20 - 0x27 + Addresses scanned: none Datasheet: Publicly available at the Philips Semiconductors website http://www.semiconductors.philips.com/pip/PCF8574P.html * Philips PCF8574A Prefix: 'pcf8574a' - Addresses scanned: I2C 0x38 - 0x3f + Addresses scanned: none Datasheet: Publicly available at the Philips Semiconductors website http://www.semiconductors.philips.com/pip/PCF8574P.html @@ -38,12 +38,10 @@ For more informations see the datasheet. Accessing PCF8574(A) via /sys interface ------------------------------------- -! Be careful ! The PCF8574(A) is plainly impossible to detect ! Stupid chip. -So every chip with address in the interval [20..27] and [38..3f] are -detected as PCF8574(A). If you have other chips in this address -range, the workaround is to load this module after the one -for your others chips. +So, you have to pass the I2C bus and address of the installed PCF857A +and PCF8574A devices explicitly to the driver at load time via the +force=... parameter. On detection (i.e. insmod, modprobe et al.), directories are being created for each detected PCF8574(A): diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index 1b3db2b..6ec3098 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c @@ -38,37 +38,19 @@ #include #include -/* Addresses to scan */ -static const unsigned short normal_i2c[] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - I2C_CLIENT_END -}; +/* Addresses to scan: none, device can't be detected */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a); /* Each client has this additional data */ struct pcf8574_data { - struct i2c_client client; - int write; /* Remember last written value */ }; -static int pcf8574_attach_adapter(struct i2c_adapter *adapter); -static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind); -static int pcf8574_detach_client(struct i2c_client *client); static void pcf8574_init_client(struct i2c_client *client); -/* This is the driver that will be inserted */ -static struct i2c_driver pcf8574_driver = { - .driver = { - .name = "pcf8574", - }, - .attach_adapter = pcf8574_attach_adapter, - .detach_client = pcf8574_detach_client, -}; - /* following are the sysfs callback functions */ static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf) { @@ -119,41 +101,22 @@ static const struct attribute_group pcf8574_attr_group = { * Real code */ -static int pcf8574_attach_adapter(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, pcf8574_detect); -} - -/* This function is called by i2c_probe */ -static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int pcf8574_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct pcf8574_data *data; - int err = 0; - const char *client_name = ""; + struct i2c_adapter *adapter = client->adapter; + const char *client_name; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. */ - if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &pcf8574_driver; + return -ENODEV; /* Now, we would do the remaining detection. But the PCF8574 is plainly impossible to detect! Stupid chip. */ /* Determine the chip type */ if (kind <= 0) { - if (address >= 0x38 && address <= 0x3f) + if (client->addr >= 0x38 && client->addr <= 0x3f) kind = pcf8574a; else kind = pcf8574; @@ -163,40 +126,43 @@ static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind) client_name = "pcf8574a"; else client_name = "pcf8574"; + strlcpy(info->type, client_name, I2C_NAME_SIZE); - /* Fill in the remaining client fields and put it into the global list */ - strlcpy(client->name, client_name, I2C_NAME_SIZE); + return 0; +} + +static int pcf8574_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct pcf8574_data *data; + int err; + + data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; - /* Initialize the PCF8574 chip */ pcf8574_init_client(client); /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &pcf8574_attr_group); if (err) - goto exit_detach; + goto exit_free; return 0; - exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int pcf8574_detach_client(struct i2c_client *client) +static int pcf8574_remove(struct i2c_client *client) { - int err; - sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group); - - if ((err = i2c_detach_client(client))) - return err; - kfree(i2c_get_clientdata(client)); return 0; } @@ -208,6 +174,24 @@ static void pcf8574_init_client(struct i2c_client *client) data->write = -EAGAIN; } +static const struct i2c_device_id pcf8574_id[] = { + { "pcf8574", 0 }, + { "pcf8574a", 0 }, + { } +}; + +static struct i2c_driver pcf8574_driver = { + .driver = { + .name = "pcf8574", + }, + .probe = pcf8574_probe, + .remove = pcf8574_remove, + .id_table = pcf8574_id, + + .detect = pcf8574_detect, + .address_data = &addr_data, +}; + static int __init pcf8574_init(void) { return i2c_add_driver(&pcf8574_driver); -- cgit v0.10.2 From 97addff6def3f8e228a634fa017589f45c69de5c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:06 +0200 Subject: i2c: Convert the pcf8575 driver to a new-style i2c driver The new-style pcf8575 driver implements the optional detect() callback to cover the use cases of the legacy driver. Warning: users will now have to use the force module parameter to get the driver to attach to their device. That's not a bad thing as these devices can't be detected anyway. Note that this doesn't change the fact that this driver is deprecated in favor of gpio/pcf857x. Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/chips/pcf8575 b/Documentation/i2c/chips/pcf8575 index 25f5698..40b268e 100644 --- a/Documentation/i2c/chips/pcf8575 +++ b/Documentation/i2c/chips/pcf8575 @@ -40,12 +40,9 @@ Detection --------- There is no method known to detect whether a chip on a given I2C address is -a PCF8575 or whether it is any other I2C device. So there are two alternatives -to let the driver find the installed PCF8575 devices: -- Load this driver after any other I2C driver for I2C devices with addresses - in the range 0x20 .. 0x27. -- Pass the I2C bus and address of the installed PCF8575 devices explicitly to - the driver at load time via the probe=... or force=... parameters. +a PCF8575 or whether it is any other I2C device, so you have to pass the I2C +bus and address of the installed PCF8575 devices explicitly to the driver at +load time via the force=... parameter. /sys interface -------------- diff --git a/drivers/i2c/chips/pcf8575.c b/drivers/i2c/chips/pcf8575.c index 3ea08ac..07fd7cb 100644 --- a/drivers/i2c/chips/pcf8575.c +++ b/drivers/i2c/chips/pcf8575.c @@ -32,11 +32,8 @@ #include /* kzalloc() */ #include /* sysfs_create_group() */ -/* Addresses to scan */ -static const unsigned short normal_i2c[] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - I2C_CLIENT_END -}; +/* Addresses to scan: none, device can't be detected */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD; @@ -44,24 +41,9 @@ I2C_CLIENT_INSMOD; /* Each client has this additional data */ struct pcf8575_data { - struct i2c_client client; int write; /* last written value, or error code */ }; -static int pcf8575_attach_adapter(struct i2c_adapter *adapter); -static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind); -static int pcf8575_detach_client(struct i2c_client *client); - -/* This is the driver that will be inserted */ -static struct i2c_driver pcf8575_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "pcf8575", - }, - .attach_adapter = pcf8575_attach_adapter, - .detach_client = pcf8575_detach_client, -}; - /* following are the sysfs callback functions */ static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf) @@ -126,75 +108,77 @@ static const struct attribute_group pcf8575_attr_group = { * Real code */ -static int pcf8575_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int pcf8575_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - return i2c_probe(adapter, &addr_data, pcf8575_detect); + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) + return -ENODEV; + + /* This is the place to detect whether the chip at the specified + address really is a PCF8575 chip. However, there is no method known + to detect whether an I2C chip is a PCF8575 or any other I2C chip. */ + + strlcpy(info->type, "pcf8575", I2C_NAME_SIZE); + + return 0; } -/* This function is called by i2c_probe */ -static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind) +static int pcf8575_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct i2c_client *client; struct pcf8575_data *data; - int err = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) - goto exit; + int err; - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. */ data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit; } - client = &data->client; i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &pcf8575_driver; - strlcpy(client->name, "pcf8575", I2C_NAME_SIZE); data->write = -EAGAIN; - /* This is the place to detect whether the chip at the specified - address really is a PCF8575 chip. However, there is no method known - to detect whether an I2C chip is a PCF8575 or any other I2C chip. */ - - /* Tell the I2C layer a new client has arrived */ - err = i2c_attach_client(client); - if (err) - goto exit_free; - /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group); if (err) - goto exit_detach; + goto exit_free; return 0; -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int pcf8575_detach_client(struct i2c_client *client) +static int pcf8575_remove(struct i2c_client *client) { - int err; - sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group); - - err = i2c_detach_client(client); - if (err) - return err; - kfree(i2c_get_clientdata(client)); return 0; } +static const struct i2c_device_id pcf8575_id[] = { + { "pcf8575", 0 }, + { } +}; + +static struct i2c_driver pcf8575_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "pcf8575", + }, + .probe = pcf8575_probe, + .remove = pcf8575_remove, + .id_table = pcf8575_id, + + .detect = pcf8575_detect, + .address_data = &addr_data, +}; + static int __init pcf8575_init(void) { return i2c_add_driver(&pcf8575_driver); -- cgit v0.10.2 From 3d63430a26b91fe3daee0dd933f899c225e66daa Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:07 +0200 Subject: i2c: Convert the pca9539 driver to a new-style i2c driver The new-style pca9539 driver implements the optional detect() callback to cover the use cases of the legacy driver. Warning: users will now have to use the force module parameter to get the driver to attach to their device. That's not a bad thing as these devices can't be detected anyway. Note that this doesn't change the fact that this driver is deprecated in favor of gpio/pca953x. Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/chips/pca9539 b/Documentation/i2c/chips/pca9539 index 1d81c53..6aff890 100644 --- a/Documentation/i2c/chips/pca9539 +++ b/Documentation/i2c/chips/pca9539 @@ -7,7 +7,7 @@ drivers/gpio/pca9539.c instead. Supported chips: * Philips PCA9539 Prefix: 'pca9539' - Addresses scanned: 0x74 - 0x77 + Addresses scanned: none Datasheet: http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf @@ -23,6 +23,14 @@ The input sense can also be inverted. The 16 lines are split between two bytes. +Detection +--------- + +The PCA9539 is difficult to detect and not commonly found in PC machines, +so you have to pass the I2C bus and address of the installed PCA9539 +devices explicitly to the driver at load time via the force=... parameter. + + Sysfs entries ------------- diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c index 58ab7f2..270de4e 100644 --- a/drivers/i2c/chips/pca9539.c +++ b/drivers/i2c/chips/pca9539.c @@ -14,8 +14,8 @@ #include #include -/* Addresses to scan */ -static unsigned short normal_i2c[] = {0x74, 0x75, 0x76, 0x77, I2C_CLIENT_END}; +/* Addresses to scan: none, device is not autodetected */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(pca9539); @@ -32,23 +32,6 @@ enum pca9539_cmd PCA9539_DIRECTION_1 = 7, }; -static int pca9539_attach_adapter(struct i2c_adapter *adapter); -static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind); -static int pca9539_detach_client(struct i2c_client *client); - -/* This is the driver that will be inserted */ -static struct i2c_driver pca9539_driver = { - .driver = { - .name = "pca9539", - }, - .attach_adapter = pca9539_attach_adapter, - .detach_client = pca9539_detach_client, -}; - -struct pca9539_data { - struct i2c_client client; -}; - /* following are the sysfs callback functions */ static ssize_t pca9539_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -105,77 +88,51 @@ static struct attribute_group pca9539_defattr_group = { .attrs = pca9539_attributes, }; -static int pca9539_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int pca9539_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - return i2c_probe(adapter, &addr_data, pca9539_detect); -} - -/* This function is called by i2c_probe */ -static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct pca9539_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. */ - if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &pca9539_driver; - - if (kind < 0) { - /* Detection: the pca9539 only has 8 registers (0-7). - A read of 7 should succeed, but a read of 8 should fail. */ - if ((i2c_smbus_read_byte_data(client, 7) < 0) || - (i2c_smbus_read_byte_data(client, 8) >= 0)) - goto exit_kfree; - } - - strlcpy(client->name, "pca9539", I2C_NAME_SIZE); - - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; + return -ENODEV; - /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, - &pca9539_defattr_group); - if (err) - goto exit_detach; + strlcpy(info->type, "pca9539", I2C_NAME_SIZE); return 0; - -exit_detach: - i2c_detach_client(client); -exit_kfree: - kfree(data); -exit: - return err; } -static int pca9539_detach_client(struct i2c_client *client) +static int pca9539_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int err; + /* Register sysfs hooks */ + return sysfs_create_group(&client->dev.kobj, + &pca9539_defattr_group); +} +static int pca9539_remove(struct i2c_client *client) +{ sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(i2c_get_clientdata(client)); return 0; } +static const struct i2c_device_id pca9539_id[] = { + { "pca9539", 0 }, + { } +}; + +static struct i2c_driver pca9539_driver = { + .driver = { + .name = "pca9539", + }, + .probe = pca9539_probe, + .remove = pca9539_remove, + .id_table = pca9539_id, + + .detect = pca9539_detect, + .address_data = &addr_data, +}; + static int __init pca9539_init(void) { return i2c_add_driver(&pca9539_driver); -- cgit v0.10.2 From bd8d421f7ca9f8da3d820d28379d796500f69529 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:07 +0200 Subject: i2c: Convert the max6875 driver to a new-style i2c driver The new-style max6875 driver implements the optional detect() callback to cover the use cases of the legacy driver. I'm curious if anyone really needs this though, so it might be removed in the feature. Signed-off-by: Jean Delvare diff --git a/Documentation/i2c/chips/max6875 b/Documentation/i2c/chips/max6875 index a0cd8af..10ca43c 100644 --- a/Documentation/i2c/chips/max6875 +++ b/Documentation/i2c/chips/max6875 @@ -49,7 +49,7 @@ $ modprobe max6875 force=0,0x50 The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple addresses. For example, for address 0x50, it also reserves 0x51. -The even-address instance is called 'max6875', the odd one is 'max6875 subclient'. +The even-address instance is called 'max6875', the odd one is 'dummy'. Programming the chip using i2c-dev diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index 5a0285d..033d9d8 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c @@ -53,7 +53,7 @@ I2C_CLIENT_INSMOD_1(max6875); /* Each client has this additional data */ struct max6875_data { - struct i2c_client client; + struct i2c_client *fake_client; struct mutex update_lock; u32 valid; @@ -61,19 +61,6 @@ struct max6875_data { unsigned long last_updated[USER_EEPROM_SLICES]; }; -static int max6875_attach_adapter(struct i2c_adapter *adapter); -static int max6875_detect(struct i2c_adapter *adapter, int address, int kind); -static int max6875_detach_client(struct i2c_client *client); - -/* This is the driver that will be inserted */ -static struct i2c_driver max6875_driver = { - .driver = { - .name = "max6875", - }, - .attach_adapter = max6875_attach_adapter, - .detach_client = max6875_detach_client, -}; - static void max6875_update_slice(struct i2c_client *client, int slice) { struct max6875_data *data = i2c_get_clientdata(client); @@ -159,96 +146,87 @@ static struct bin_attribute user_eeprom_attr = { .read = max6875_read, }; -static int max6875_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int max6875_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - return i2c_probe(adapter, &addr_data, max6875_detect); -} - -/* This function is called by i2c_probe */ -static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *real_client; - struct i2c_client *fake_client; - struct max6875_data *data; - int err; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA | I2C_FUNC_SMBUS_READ_BYTE)) - return 0; + return -ENODEV; /* Only check even addresses */ - if (address & 1) - return 0; + if (client->addr & 1) + return -ENODEV; + + strlcpy(info->type, "max6875", I2C_NAME_SIZE); + + return 0; +} + +static int max6875_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max6875_data *data; + int err; if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) return -ENOMEM; /* A fake client is created on the odd address */ - if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { + data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!data->fake_client) { err = -ENOMEM; - goto exit_kfree1; + goto exit_kfree; } /* Init real i2c_client */ - real_client = &data->client; - i2c_set_clientdata(real_client, data); - real_client->addr = address; - real_client->adapter = adapter; - real_client->driver = &max6875_driver; - strlcpy(real_client->name, "max6875", I2C_NAME_SIZE); + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - /* Init fake client data */ - i2c_set_clientdata(fake_client, NULL); - fake_client->addr = address | 1; - fake_client->adapter = adapter; - fake_client->driver = &max6875_driver; - strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE); - - if ((err = i2c_attach_client(real_client)) != 0) - goto exit_kfree2; - - if ((err = i2c_attach_client(fake_client)) != 0) - goto exit_detach1; - - err = sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr); + err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr); if (err) - goto exit_detach2; + goto exit_remove_fake; return 0; -exit_detach2: - i2c_detach_client(fake_client); -exit_detach1: - i2c_detach_client(real_client); -exit_kfree2: - kfree(fake_client); -exit_kfree1: +exit_remove_fake: + i2c_unregister_device(data->fake_client); +exit_kfree: kfree(data); return err; } -/* Will be called for both the real client and the fake client */ -static int max6875_detach_client(struct i2c_client *client) +static int max6875_remove(struct i2c_client *client) { - int err; struct max6875_data *data = i2c_get_clientdata(client); - /* data is NULL for the fake client */ - if (data) - sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr); + i2c_unregister_device(data->fake_client); - err = i2c_detach_client(client); - if (err) - return err; + sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr); + kfree(data); - if (data) /* real client */ - kfree(data); - else /* fake client */ - kfree(client); return 0; } +static const struct i2c_device_id max6875_id[] = { + { "max6875", 0 }, + { } +}; + +static struct i2c_driver max6875_driver = { + .driver = { + .name = "max6875", + }, + .probe = max6875_probe, + .remove = max6875_remove, + .id_table = max6875_id, + + .detect = max6875_detect, + .address_data = &addr_data, +}; + static int __init max6875_init(void) { return i2c_add_driver(&max6875_driver); -- cgit v0.10.2 From 61c91f7ded640bb2b340cc89d9ca3a3ca0229c74 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:07 +0200 Subject: w1/ds2482: Convert to a new-style driver The new-style ds2482 driver implements the optional detect() callback to cover the use cases of the legacy driver. I'm curious if anyone really needs this though, so it might be removed in the feature. Signed-off-by: Jean Delvare diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index 0fd5820..df52cb3 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c @@ -94,21 +94,31 @@ static const u8 ds2482_chan_rd[8] = #define DS2482_REG_STS_1WB 0x01 -static int ds2482_attach_adapter(struct i2c_adapter *adapter); -static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind); -static int ds2482_detach_client(struct i2c_client *client); +static int ds2482_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int ds2482_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int ds2482_remove(struct i2c_client *client); /** * Driver data (common to all clients) */ +static const struct i2c_device_id ds2482_id[] = { + { "ds2482", 0 }, + { } +}; + static struct i2c_driver ds2482_driver = { .driver = { .owner = THIS_MODULE, .name = "ds2482", }, - .attach_adapter = ds2482_attach_adapter, - .detach_client = ds2482_detach_client, + .probe = ds2482_probe, + .remove = ds2482_remove, + .id_table = ds2482_id, + .detect = ds2482_detect, + .address_data = &addr_data, }; /* @@ -124,7 +134,7 @@ struct ds2482_w1_chan { }; struct ds2482_data { - struct i2c_client client; + struct i2c_client *client; struct mutex access_lock; /* 1-wire interface(s) */ @@ -147,7 +157,7 @@ struct ds2482_data { static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr) { if (pdev->read_prt != read_ptr) { - if (i2c_smbus_write_byte_data(&pdev->client, + if (i2c_smbus_write_byte_data(pdev->client, DS2482_CMD_SET_READ_PTR, read_ptr) < 0) return -1; @@ -167,7 +177,7 @@ static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr) */ static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd) { - if (i2c_smbus_write_byte(&pdev->client, cmd) < 0) + if (i2c_smbus_write_byte(pdev->client, cmd) < 0) return -1; pdev->read_prt = DS2482_PTR_CODE_STATUS; @@ -187,7 +197,7 @@ static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd) static inline int ds2482_send_cmd_data(struct ds2482_data *pdev, u8 cmd, u8 byte) { - if (i2c_smbus_write_byte_data(&pdev->client, cmd, byte) < 0) + if (i2c_smbus_write_byte_data(pdev->client, cmd, byte) < 0) return -1; /* all cmds leave in STATUS, except CONFIG */ @@ -216,7 +226,7 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev) if (!ds2482_select_register(pdev, DS2482_PTR_CODE_STATUS)) { do { - temp = i2c_smbus_read_byte(&pdev->client); + temp = i2c_smbus_read_byte(pdev->client); } while ((temp >= 0) && (temp & DS2482_REG_STS_1WB) && (++retries < DS2482_WAIT_IDLE_TIMEOUT)); } @@ -238,13 +248,13 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev) */ static int ds2482_set_channel(struct ds2482_data *pdev, u8 channel) { - if (i2c_smbus_write_byte_data(&pdev->client, DS2482_CMD_CHANNEL_SELECT, + if (i2c_smbus_write_byte_data(pdev->client, DS2482_CMD_CHANNEL_SELECT, ds2482_chan_wr[channel]) < 0) return -1; pdev->read_prt = DS2482_PTR_CODE_CHANNEL; pdev->channel = -1; - if (i2c_smbus_read_byte(&pdev->client) == ds2482_chan_rd[channel]) { + if (i2c_smbus_read_byte(pdev->client) == ds2482_chan_rd[channel]) { pdev->channel = channel; return 0; } @@ -368,7 +378,7 @@ static u8 ds2482_w1_read_byte(void *data) ds2482_select_register(pdev, DS2482_PTR_CODE_DATA); /* Read the data byte */ - result = i2c_smbus_read_byte(&pdev->client); + result = i2c_smbus_read_byte(pdev->client); mutex_unlock(&pdev->access_lock); @@ -415,47 +425,38 @@ static u8 ds2482_w1_reset_bus(void *data) } -/** - * Called to see if the device exists on an i2c bus. - */ -static int ds2482_attach_adapter(struct i2c_adapter *adapter) +static int ds2482_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - return i2c_probe(adapter, &addr_data, ds2482_detect); -} + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + strlcpy(info->type, "ds2482", I2C_NAME_SIZE); -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind) + return 0; +} + +static int ds2482_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct ds2482_data *data; - struct i2c_client *new_client; - int err = 0; + int err = -ENODEV; int temp1; int idx; - if (!i2c_check_functionality(adapter, - I2C_FUNC_SMBUS_WRITE_BYTE_DATA | - I2C_FUNC_SMBUS_BYTE)) - goto exit; - if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->driver = &ds2482_driver; - new_client->adapter = adapter; + data->client = client; + i2c_set_clientdata(client, data); /* Reset the device (sets the read_ptr to status) */ if (ds2482_send_cmd(data, DS2482_CMD_RESET) < 0) { - dev_dbg(&adapter->dev, "DS2482 reset failed at 0x%02x.\n", - address); + dev_warn(&client->dev, "DS2482 reset failed.\n"); goto exit_free; } @@ -463,10 +464,10 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind) ndelay(525); /* Read the status byte - only reset bit and line should be set */ - temp1 = i2c_smbus_read_byte(new_client); + temp1 = i2c_smbus_read_byte(client); if (temp1 != (DS2482_REG_STS_LL | DS2482_REG_STS_RST)) { - dev_dbg(&adapter->dev, "DS2482 (0x%02x) reset status " - "0x%02X - not a DS2482\n", address, temp1); + dev_warn(&client->dev, "DS2482 reset status " + "0x%02X - not a DS2482\n", temp1); goto exit_free; } @@ -478,16 +479,8 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind) /* Set all config items to 0 (off) */ ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0); - /* We can fill in the remaining client fields */ - snprintf(new_client->name, sizeof(new_client->name), "ds2482-%d00", - data->w1_count); - mutex_init(&data->access_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Register 1-wire interface(s) */ for (idx = 0; idx < data->w1_count; idx++) { data->w1_ch[idx].pdev = data; @@ -511,8 +504,6 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind) return 0; exit_w1_remove: - i2c_detach_client(new_client); - for (idx = 0; idx < data->w1_count; idx++) { if (data->w1_ch[idx].pdev != NULL) w1_remove_master_device(&data->w1_ch[idx].w1_bm); @@ -523,10 +514,10 @@ exit: return err; } -static int ds2482_detach_client(struct i2c_client *client) +static int ds2482_remove(struct i2c_client *client) { struct ds2482_data *data = i2c_get_clientdata(client); - int err, idx; + int idx; /* Unregister the 1-wire bridge(s) */ for (idx = 0; idx < data->w1_count; idx++) { @@ -534,13 +525,6 @@ static int ds2482_detach_client(struct i2c_client *client) w1_remove_master_device(&data->w1_ch[idx].w1_bm); } - /* Detach the i2c device */ - if ((err = i2c_detach_client(client))) { - dev_err(&client->dev, - "Deregistration failed, client not detached.\n"); - return err; - } - /* Free the memory */ kfree(data); return 0; -- cgit v0.10.2 From 369932f6f840aedfbc717dd156bba7668a11d916 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: hwmon: (ad7418) Convert to a new-style i2c driver The ad7418 driver is only used on embedded platforms where i2c devices can easily be declared in platform code. Thus a new-style i2c driver makes perfect sense. This lets us get rid of quirky detection code (these chips have no identification registers) and shrinks the binary driver size by 38%. Signed-off-by: Jean Delvare Cc: Alessandro Zummo diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index 466b9ee..f97b5b3 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c @@ -23,12 +23,9 @@ #include "lm75.h" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.4" -/* Addresses to scan */ -static const unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418); +enum chips { ad7416, ad7417, ad7418 }; /* AD7418 registers */ #define AD7418_REG_TEMP_IN 0x00 @@ -46,7 +43,6 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN, AD7418_REG_TEMP_OS }; struct ad7418_data { - struct i2c_client client; struct device *hwmon_dev; struct attribute_group attrs; enum chips type; @@ -58,16 +54,25 @@ struct ad7418_data { u16 in[4]; }; -static int ad7418_attach_adapter(struct i2c_adapter *adapter); -static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind); -static int ad7418_detach_client(struct i2c_client *client); +static int ad7418_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int ad7418_remove(struct i2c_client *client); + +static const struct i2c_device_id ad7418_id[] = { + { "ad7416", ad7416 }, + { "ad7417", ad7417 }, + { "ad7418", ad7418 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ad7418_id); static struct i2c_driver ad7418_driver = { .driver = { .name = "ad7418", }, - .attach_adapter = ad7418_attach_adapter, - .detach_client = ad7418_detach_client, + .probe = ad7418_probe, + .remove = ad7418_remove, + .id_table = ad7418_id, }; /* All registers are word-sized, except for the configuration registers. @@ -192,13 +197,6 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1); static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2); static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3); -static int ad7418_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, ad7418_detect); -} - static struct attribute *ad7416_attributes[] = { &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, @@ -225,98 +223,46 @@ static struct attribute *ad7418_attributes[] = { NULL }; -static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind) +static int ad7418_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct i2c_client *client; + struct i2c_adapter *adapter = client->adapter; struct ad7418_data *data; - int err = 0; + int err; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) + I2C_FUNC_SMBUS_WORD_DATA)) { + err = -EOPNOTSUPP; goto exit; + } if (!(data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } - client = &data->client; - client->addr = address; - client->adapter = adapter; - client->driver = &ad7418_driver; - i2c_set_clientdata(client, data); mutex_init(&data->lock); - - /* AD7418 has a curious behaviour on registers 6 and 7. They - * both always read 0xC071 and are not documented on the datasheet. - * We use them to detect the chip. - */ - if (kind <= 0) { - int reg, reg6, reg7; - - /* the AD7416 lies within this address range, but I have - * no means to check. - */ - if (address >= 0x48 && address <= 0x4f) { - /* XXX add tests for AD7416 here */ - /* data->type = ad7416; */ - } - /* here we might have AD7417 or AD7418 */ - else if (address >= 0x28 && address <= 0x2f) { - reg6 = i2c_smbus_read_word_data(client, 0x06); - reg7 = i2c_smbus_read_word_data(client, 0x07); - - if (address == 0x28 && reg6 == 0xC071 && reg7 == 0xC071) - data->type = ad7418; - - /* XXX add tests for AD7417 here */ - - - /* both AD7417 and AD7418 have bits 0-5 of - * the CONF2 register at 0 - */ - reg = i2c_smbus_read_byte_data(client, - AD7418_REG_CONF2); - if (reg & 0x3F) - data->type = any_chip; /* detection failed */ - } - } else { - dev_dbg(&adapter->dev, "detection forced\n"); - } - - if (kind > 0) - data->type = kind; - else if (kind < 0 && data->type == any_chip) { - err = -ENODEV; - goto exit_free; - } + data->type = id->driver_data; switch (data->type) { - case any_chip: case ad7416: data->adc_max = 0; data->attrs.attrs = ad7416_attributes; - strlcpy(client->name, "ad7416", I2C_NAME_SIZE); break; case ad7417: data->adc_max = 4; data->attrs.attrs = ad7417_attributes; - strlcpy(client->name, "ad7417", I2C_NAME_SIZE); break; case ad7418: data->adc_max = 1; data->attrs.attrs = ad7418_attributes; - strlcpy(client->name, "ad7418", I2C_NAME_SIZE); break; } - if ((err = i2c_attach_client(client))) - goto exit_free; - dev_info(&client->dev, "%s chip found\n", client->name); /* Initialize the AD7418 chip */ @@ -324,7 +270,7 @@ static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind) /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -336,20 +282,17 @@ static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int ad7418_detach_client(struct i2c_client *client) +static int ad7418_remove(struct i2c_client *client) { struct ad7418_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->attrs); - i2c_detach_client(client); kfree(data); return 0; } -- cgit v0.10.2 From 65817ed8d1376afff21019b5c0e0109e5a7d9cc0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: hwmon: (adm1021) Convert to a new-style i2c driver The new-style adm1021 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index ecbf694..b11e06f 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -78,7 +78,6 @@ clearing it. Weird, ey? --Phil */ /* Each client has this additional data */ struct adm1021_data { - struct i2c_client client; struct device *hwmon_dev; enum chips type; @@ -98,23 +97,42 @@ struct adm1021_data { u8 remote_temp_offset_prec; }; -static int adm1021_attach_adapter(struct i2c_adapter *adapter); -static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); +static int adm1021_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm1021_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void adm1021_init_client(struct i2c_client *client); -static int adm1021_detach_client(struct i2c_client *client); +static int adm1021_remove(struct i2c_client *client); static struct adm1021_data *adm1021_update_device(struct device *dev); /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ static int read_only; +static const struct i2c_device_id adm1021_id[] = { + { "adm1021", adm1021 }, + { "adm1023", adm1023 }, + { "max1617", max1617 }, + { "max1617a", max1617a }, + { "thmc10", thmc10 }, + { "lm84", lm84 }, + { "gl523sm", gl523sm }, + { "mc1066", mc1066 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1021_id); + /* This is the driver that will be inserted */ static struct i2c_driver adm1021_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm1021", }, - .attach_adapter = adm1021_attach_adapter, - .detach_client = adm1021_detach_client, + .probe = adm1021_probe, + .remove = adm1021_remove, + .id_table = adm1021_id, + .detect = adm1021_detect, + .address_data = &addr_data, }; static ssize_t show_temp(struct device *dev, @@ -216,13 +234,6 @@ static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); -static int adm1021_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adm1021_detect); -} - static struct attribute *adm1021_attributes[] = { &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, @@ -243,36 +254,21 @@ static const struct attribute_group adm1021_group = { .attrs = adm1021_attributes, }; -static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm1021_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { + struct i2c_adapter *adapter = client->adapter; int i; - struct i2c_client *client; - struct adm1021_data *data; - int err = 0; const char *type_name = ""; int conv_rate, status, config; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { pr_debug("adm1021: detect failed, " "smbus byte data not supported!\n"); - goto error0; - } - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access adm1021 register values. */ - - if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { - pr_debug("adm1021: detect failed, kzalloc failed!\n"); - err = -ENOMEM; - goto error0; + return -ENODEV; } - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &adm1021_driver; status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS); conv_rate = i2c_smbus_read_byte_data(client, ADM1021_REG_CONV_RATE_R); @@ -284,8 +280,7 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) || (conv_rate & 0xF8) != 0x00) { pr_debug("adm1021: detect failed, " "chip not detected!\n"); - err = -ENODEV; - goto error1; + return -ENODEV; } } @@ -336,24 +331,36 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) type_name = "mc1066"; } pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", - type_name, i2c_adapter_id(adapter), address); + type_name, i2c_adapter_id(adapter), client->addr); + strlcpy(info->type, type_name, I2C_NAME_SIZE); - /* Fill in the remaining client fields */ - strlcpy(client->name, type_name, I2C_NAME_SIZE); - data->type = kind; - mutex_init(&data->update_lock); + return 0; +} - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto error1; +static int adm1021_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adm1021_data *data; + int err; + + data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL); + if (!data) { + pr_debug("adm1021: detect failed, kzalloc failed!\n"); + err = -ENOMEM; + goto error0; + } + + i2c_set_clientdata(client, data); + data->type = id->driver_data; + mutex_init(&data->update_lock); /* Initialize the ADM1021 chip */ - if (kind != lm84 && !read_only) + if (data->type != lm84 && !read_only) adm1021_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group))) - goto error2; + goto error1; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -365,8 +372,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) error3: sysfs_remove_group(&client->dev.kobj, &adm1021_group); -error2: - i2c_detach_client(client); error1: kfree(data); error0: @@ -382,17 +387,13 @@ static void adm1021_init_client(struct i2c_client *client) i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04); } -static int adm1021_detach_client(struct i2c_client *client) +static int adm1021_remove(struct i2c_client *client) { struct adm1021_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1021_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 7dbafe021ba360bf25674a7e290d3e4a5c953981 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: hwmon: (adm1025) Convert to a new-style i2c driver The new-style adm1025 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 1d76de7..4db04d6 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -2,7 +2,7 @@ * adm1025.c * * Copyright (C) 2000 Chen-Yuan Wu - * Copyright (C) 2003-2004 Jean Delvare + * Copyright (C) 2003-2008 Jean Delvare * * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6 * voltages (including its own power source) and up to two temperatures @@ -109,22 +109,35 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 }; * Functions declaration */ -static int adm1025_attach_adapter(struct i2c_adapter *adapter); -static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind); +static int adm1025_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm1025_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void adm1025_init_client(struct i2c_client *client); -static int adm1025_detach_client(struct i2c_client *client); +static int adm1025_remove(struct i2c_client *client); static struct adm1025_data *adm1025_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id adm1025_id[] = { + { "adm1025", adm1025 }, + { "ne1619", ne1619 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1025_id); + static struct i2c_driver adm1025_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm1025", }, - .attach_adapter = adm1025_attach_adapter, - .detach_client = adm1025_detach_client, + .probe = adm1025_probe, + .remove = adm1025_remove, + .id_table = adm1025_id, + .detect = adm1025_detect, + .address_data = &addr_data, }; /* @@ -132,7 +145,6 @@ static struct i2c_driver adm1025_driver = { */ struct adm1025_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -344,13 +356,6 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); * Real code */ -static int adm1025_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adm1025_detect); -} - static struct attribute *adm1025_attributes[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, @@ -403,31 +408,16 @@ static const struct attribute_group adm1025_group_in4 = { .attrs = adm1025_attributes_in4, }; -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm1025_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct adm1025_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; const char *name = ""; u8 config; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &adm1025_driver; + return -ENODEV; /* * Now we do the remaining detection. A negative kind means that @@ -448,8 +438,8 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) ADM1025_REG_STATUS2) & 0xBC) != 0x00) { dev_dbg(&adapter->dev, "ADM1025 detection failed at 0x%02x.\n", - address); - goto exit_free; + client->addr); + return -ENODEV; } } @@ -465,7 +455,7 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) } } else if (man_id == 0xA1) { /* Philips */ - if (address != 0x2E + if (client->addr != 0x2E && (chip_id & 0xF0) == 0x20) { /* NE1619 */ kind = ne1619; } @@ -475,7 +465,7 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, " "chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } @@ -484,23 +474,36 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) } else if (kind == ne1619) { name = "ne1619"; } + strlcpy(info->type, name, I2C_NAME_SIZE); - /* We can fill in the remaining client fields */ - strlcpy(client->name, name, I2C_NAME_SIZE); - mutex_init(&data->update_lock); + return 0; +} - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; +static int adm1025_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adm1025_data *data; + int err; + u8 config; + + data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); /* Initialize the ADM1025 chip */ adm1025_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &adm1025_group))) - goto exit_detach; + goto exit_free; /* Pin 11 is either in4 (+12V) or VID4 */ + config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG); if (!(config & 0x20)) { if ((err = sysfs_create_group(&client->dev.kobj, &adm1025_group_in4))) @@ -518,8 +521,6 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &adm1025_group); sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: @@ -568,18 +569,14 @@ static void adm1025_init_client(struct i2c_client *client) (reg&0x7E)|0x01); } -static int adm1025_detach_client(struct i2c_client *client) +static int adm1025_remove(struct i2c_client *client) { struct adm1025_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1025_group); sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 57f7eb0bcb2316dc264cd26f38b33dd2cf3151c1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:08 +0200 Subject: hwmon: (adm1026) Convert to a new-style i2c driver The new-style adm1026 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 904c6ce..7fe2441 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -259,7 +259,6 @@ struct pwm_data { }; struct adm1026_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; @@ -293,10 +292,11 @@ struct adm1026_data { u8 config3; /* Register value */ }; -static int adm1026_attach_adapter(struct i2c_adapter *adapter); -static int adm1026_detect(struct i2c_adapter *adapter, int address, - int kind); -static int adm1026_detach_client(struct i2c_client *client); +static int adm1026_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm1026_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int adm1026_remove(struct i2c_client *client); static int adm1026_read_value(struct i2c_client *client, u8 reg); static int adm1026_write_value(struct i2c_client *client, u8 reg, int value); static void adm1026_print_gpio(struct i2c_client *client); @@ -305,22 +305,24 @@ static struct adm1026_data *adm1026_update_device(struct device *dev); static void adm1026_init_client(struct i2c_client *client); +static const struct i2c_device_id adm1026_id[] = { + { "adm1026", adm1026 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1026_id); + static struct i2c_driver adm1026_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm1026", }, - .attach_adapter = adm1026_attach_adapter, - .detach_client = adm1026_detach_client, + .probe = adm1026_probe, + .remove = adm1026_remove, + .id_table = adm1026_id, + .detect = adm1026_detect, + .address_data = &addr_data, }; -static int adm1026_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) { - return 0; - } - return i2c_probe(adapter, &addr_data, adm1026_detect); -} - static int adm1026_read_value(struct i2c_client *client, u8 reg) { int res; @@ -1647,48 +1649,32 @@ static const struct attribute_group adm1026_group_in8_9 = { .attrs = adm1026_attributes_in8_9, }; -static int adm1026_detect(struct i2c_adapter *adapter, int address, - int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm1026_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { + struct i2c_adapter *adapter = client->adapter; + int address = client->addr; int company, verstep; - struct i2c_client *client; - struct adm1026_data *data; - int err = 0; - const char *type_name = ""; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { /* We need to be able to do byte I/O */ - goto exit; + return -ENODEV; }; - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access adm1026_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &adm1026_driver; - /* Now, we do the remaining detection. */ company = adm1026_read_value(client, ADM1026_REG_COMPANY); verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); - dev_dbg(&client->dev, "Detecting device at %d,0x%02x with" + dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with" " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", i2c_adapter_id(client->adapter), client->addr, company, verstep); /* If auto-detecting, Determine the chip type. */ if (kind <= 0) { - dev_dbg(&client->dev, "Autodetecting device at %d,0x%02x " + dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x " "...\n", i2c_adapter_id(adapter), address); if (company == ADM1026_COMPANY_ANALOG_DEV && verstep == ADM1026_VERSTEP_ADM1026) { @@ -1704,7 +1690,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, verstep); kind = any_chip; } else { - dev_dbg(&client->dev, ": Autodetection " + dev_dbg(&adapter->dev, ": Autodetection " "failed\n"); /* Not an ADM1026 ... */ if (kind == 0) { /* User used force=x,y */ @@ -1713,33 +1699,29 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, "force_adm1026.\n", i2c_adapter_id(adapter), address); } - goto exitfree; + return -ENODEV; } } + strlcpy(info->type, "adm1026", I2C_NAME_SIZE); - /* Fill in the chip specific driver values */ - switch (kind) { - case any_chip : - type_name = "adm1026"; - break; - case adm1026 : - type_name = "adm1026"; - break; - default : - dev_err(&adapter->dev, ": Internal error, invalid " - "kind (%d)!\n", kind); - err = -EFAULT; - goto exitfree; + return 0; +} + +static int adm1026_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adm1026_data *data; + int err; + + data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; } - strlcpy(client->name, type_name, I2C_NAME_SIZE); - /* Fill in the remaining client fields */ + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exitfree; - /* Set the VRM version */ data->vrm = vid_which_vrm(); @@ -1748,7 +1730,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) - goto exitdetach; + goto exitfree; if (data->config1 & CFG1_AIN8_9) err = sysfs_create_group(&client->dev.kobj, &adm1026_group_in8_9); @@ -1773,15 +1755,13 @@ exitremove: sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); else sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); -exitdetach: - i2c_detach_client(client); exitfree: kfree(data); exit: return err; } -static int adm1026_detach_client(struct i2c_client *client) +static int adm1026_remove(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); @@ -1790,7 +1770,6 @@ static int adm1026_detach_client(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); else sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); - i2c_detach_client(client); kfree(data); return 0; } -- cgit v0.10.2 From 9c97fb4d255fbf6713ee2d77dd8ed8ae770a7e49 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:09 +0200 Subject: hwmon: (adm1029) Convert to a new-style i2c driver The new-style adm1029 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Corentin Labbe diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 2c6608d..ba84ca5 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -115,9 +115,11 @@ static const u8 ADM1029_REG_FAN_DIV[] = { * Functions declaration */ -static int adm1029_attach_adapter(struct i2c_adapter *adapter); -static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind); -static int adm1029_detach_client(struct i2c_client *client); +static int adm1029_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm1029_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int adm1029_remove(struct i2c_client *client); static struct adm1029_data *adm1029_update_device(struct device *dev); static int adm1029_init_client(struct i2c_client *client); @@ -125,12 +127,22 @@ static int adm1029_init_client(struct i2c_client *client); * Driver data (common to all clients) */ +static const struct i2c_device_id adm1029_id[] = { + { "adm1029", adm1029 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1029_id); + static struct i2c_driver adm1029_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm1029", }, - .attach_adapter = adm1029_attach_adapter, - .detach_client = adm1029_detach_client, + .probe = adm1029_probe, + .remove = adm1029_remove, + .id_table = adm1029_id, + .detect = adm1029_detect, + .address_data = &addr_data, }; /* @@ -138,7 +150,6 @@ static struct i2c_driver adm1029_driver = { */ struct adm1029_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -284,37 +295,14 @@ static const struct attribute_group adm1029_group = { * Real code */ -static int adm1029_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm1029_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adm1029_detect); -} + struct i2c_adapter *adapter = client->adapter; -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ - -static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct adm1029_data *data; - int err = 0; - const char *name = ""; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &adm1029_driver; + return -ENODEV; /* Now we do the detection and identification. A negative kind * means that the driver was loaded with no force parameter @@ -362,32 +350,41 @@ static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind) if (kind <= 0) { /* identification failed */ pr_debug("adm1029: Unsupported chip (man_id=0x%02X, " "chip_id=0x%02X)\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } + strlcpy(info->type, "adm1029", I2C_NAME_SIZE); - if (kind == adm1029) { - name = "adm1029"; + return 0; +} + +static int adm1029_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adm1029_data *data; + int err; + + data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; } - /* We can fill in the remaining client fields */ - strlcpy(client->name, name, I2C_NAME_SIZE); + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; - /* * Initialize the ADM1029 chip * Check config register */ - if (adm1029_init_client(client) == 0) - goto exit_detach; + if (adm1029_init_client(client) == 0) { + err = -ENODEV; + goto exit_free; + } /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -399,8 +396,6 @@ static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&client->dev.kobj, &adm1029_group); - exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: @@ -424,17 +419,13 @@ static int adm1029_init_client(struct i2c_client *client) return 1; } -static int adm1029_detach_client(struct i2c_client *client) +static int adm1029_remove(struct i2c_client *client) { struct adm1029_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1029_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From af200f881d2cbf3ba2f4c505fa1ae5cfef36f46a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:09 +0200 Subject: hwmon: (adm1031) Convert to a new-style i2c driver The new-style adm1031 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Alexandre d'Alton diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 2bffcab..7894418 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -70,7 +70,6 @@ typedef u8 auto_chan_table_t[8][2]; /* Each client has this additional data */ struct adm1031_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; int chip_type; @@ -99,19 +98,32 @@ struct adm1031_data { s8 temp_crit[3]; }; -static int adm1031_attach_adapter(struct i2c_adapter *adapter); -static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind); +static int adm1031_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm1031_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void adm1031_init_client(struct i2c_client *client); -static int adm1031_detach_client(struct i2c_client *client); +static int adm1031_remove(struct i2c_client *client); static struct adm1031_data *adm1031_update_device(struct device *dev); +static const struct i2c_device_id adm1031_id[] = { + { "adm1030", adm1030 }, + { "adm1031", adm1031 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm1031_id); + /* This is the driver that will be inserted */ static struct i2c_driver adm1031_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm1031", }, - .attach_adapter = adm1031_attach_adapter, - .detach_client = adm1031_detach_client, + .probe = adm1031_probe, + .remove = adm1031_remove, + .id_table = adm1031_id, + .detect = adm1031_detect, + .address_data = &addr_data, }; static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg) @@ -693,13 +705,6 @@ static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12); static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); -static int adm1031_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adm1031_detect); -} - static struct attribute *adm1031_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, @@ -770,27 +775,15 @@ static const struct attribute_group adm1031_group_opt = { .attrs = adm1031_attributes_opt, }; -/* This function is called by i2c_probe */ -static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm1031_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct adm1031_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; const char *name = ""; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &adm1031_driver; + return -ENODEV; if (kind < 0) { int id, co; @@ -798,7 +791,7 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) co = i2c_smbus_read_byte_data(client, 0x3e); if (!((id == 0x31 || id == 0x30) && co == 0x41)) - goto exit_free; + return -ENODEV; kind = (id == 0x30) ? adm1030 : adm1031; } @@ -809,28 +802,43 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) * auto fan control helper table. */ if (kind == adm1030) { name = "adm1030"; - data->chan_select_table = &auto_channel_select_table_adm1030; } else if (kind == adm1031) { name = "adm1031"; - data->chan_select_table = &auto_channel_select_table_adm1031; } - data->chip_type = kind; + strlcpy(info->type, name, I2C_NAME_SIZE); - strlcpy(client->name, name, I2C_NAME_SIZE); + return 0; +} + +static int adm1031_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adm1031_data *data; + int err; + + data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->chip_type = id->driver_data; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; + if (data->chip_type == adm1030) + data->chan_select_table = &auto_channel_select_table_adm1030; + else + data->chan_select_table = &auto_channel_select_table_adm1031; /* Initialize the ADM1031 chip */ adm1031_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &adm1031_group))) - goto exit_detach; + goto exit_free; - if (kind == adm1031) { + if (data->chip_type == adm1031) { if ((err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt))) goto exit_remove; @@ -847,25 +855,19 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &adm1031_group); sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int adm1031_detach_client(struct i2c_client *client) +static int adm1031_remove(struct i2c_client *client) { struct adm1031_data *data = i2c_get_clientdata(client); - int ret; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1031_group); sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); - if ((ret = i2c_detach_client(client)) != 0) { - return ret; - } kfree(data); return 0; } -- cgit v0.10.2 From 7fae8283109e155467bc1c622178d3a475cdbddf Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:09 +0200 Subject: hwmon: (adm9240) Convert to a new-style i2c driver The new-style adm9240 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Grant Coady diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 149ef25..2444b15 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -130,25 +130,37 @@ static inline unsigned int AOUT_FROM_REG(u8 reg) return SCALE(reg, 1250, 255); } -static int adm9240_attach_adapter(struct i2c_adapter *adapter); -static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind); +static int adm9240_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adm9240_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void adm9240_init_client(struct i2c_client *client); -static int adm9240_detach_client(struct i2c_client *client); +static int adm9240_remove(struct i2c_client *client); static struct adm9240_data *adm9240_update_device(struct device *dev); /* driver data */ +static const struct i2c_device_id adm9240_id[] = { + { "adm9240", adm9240 }, + { "ds1780", ds1780 }, + { "lm81", lm81 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adm9240_id); + static struct i2c_driver adm9240_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adm9240", }, - .attach_adapter = adm9240_attach_adapter, - .detach_client = adm9240_detach_client, + .probe = adm9240_probe, + .remove = adm9240_remove, + .id_table = adm9240_id, + .detect = adm9240_detect, + .address_data = &addr_data, }; /* per client data */ struct adm9240_data { - enum chips type; - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; @@ -532,28 +544,17 @@ static const struct attribute_group adm9240_group = { /*** sensor chip detect and driver install ***/ -static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adm9240_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct adm9240_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; const char *name = ""; + int address = new_client->addr; u8 man_id, die_rev; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &adm9240_driver; - new_client->flags = 0; + return -ENODEV; if (kind == 0) { kind = adm9240; @@ -566,7 +567,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) != address) { dev_err(&adapter->dev, "detect fail: address match, " "0x%02x\n", address); - goto exit_free; + return -ENODEV; } /* check known chip manufacturer */ @@ -581,7 +582,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) } else { dev_err(&adapter->dev, "detect fail: unknown manuf, " "0x%02x\n", man_id); - goto exit_free; + return -ENODEV; } /* successful detect, print chip info */ @@ -600,20 +601,31 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) } else if (kind == lm81) { name = "lm81"; } + strlcpy(info->type, name, I2C_NAME_SIZE); - /* fill in the remaining client fields and attach */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); - data->type = kind; - mutex_init(&data->update_lock); + return 0; +} - if ((err = i2c_attach_client(new_client))) - goto exit_free; +static int adm9240_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct adm9240_data *data; + int err; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); + mutex_init(&data->update_lock); adm9240_init_client(new_client); /* populate sysfs filesystem */ if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -625,32 +637,19 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; } -static int adm9240_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adm9240_detect); -} - -static int adm9240_detach_client(struct i2c_client *client) +static int adm9240_remove(struct i2c_client *client) { struct adm9240_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm9240_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 7347cb388e5aecffc4920bd5ea6a61e4a4690bae Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:10 +0200 Subject: hwmon: (ads7828) Convert to a new-style i2c driver The new-style ads7828 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 5c8b6e0..5c39b4a 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -64,7 +64,6 @@ static unsigned int ads7828_lsb_resol; /* resolution of the ADC sample lsb */ /* Each client has this additional data */ struct ads7828_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; /* mutex protect updates */ char valid; /* !=0 if following fields are valid */ @@ -73,7 +72,10 @@ struct ads7828_data { }; /* Function declaration - necessary due to function dependencies */ -static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind); +static int ads7828_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int ads7828_probe(struct i2c_client *client, + const struct i2c_device_id *id); /* The ADS7828 returns the 12-bit sample in two bytes, these are read as a word then byte-swapped */ @@ -156,58 +158,43 @@ static const struct attribute_group ads7828_group = { .attrs = ads7828_attributes, }; -static int ads7828_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, ads7828_detect); -} - -static int ads7828_detach_client(struct i2c_client *client) +static int ads7828_remove(struct i2c_client *client) { struct ads7828_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ads7828_group); - i2c_detach_client(client); kfree(i2c_get_clientdata(client)); return 0; } +static const struct i2c_device_id ads7828_id[] = { + { "ads7828", ads7828 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ads7828_id); + /* This is the driver that will be inserted */ static struct i2c_driver ads7828_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "ads7828", }, - .attach_adapter = ads7828_attach_adapter, - .detach_client = ads7828_detach_client, + .probe = ads7828_probe, + .remove = ads7828_remove, + .id_table = ads7828_id, + .detect = ads7828_detect, + .address_data = &addr_data, }; -/* This function is called by i2c_probe */ -static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int ads7828_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct ads7828_data *data; - int err = 0; - const char *name = ""; + struct i2c_adapter *adapter = client->adapter; /* Check we have a valid client */ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access ads7828_read_value. */ - data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &ads7828_driver; + return -ENODEV; /* Now, we do the remaining detection. There is no identification dedicated register so attempt to sanity check using knowledge of @@ -225,32 +212,34 @@ static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind) printk(KERN_DEBUG "%s : Doesn't look like an ads7828 device\n", __func__); - goto exit_free; + return -ENODEV; } } } + strlcpy(info->type, "ads7828", I2C_NAME_SIZE); - /* Determine the chip type - only one kind supported! */ - if (kind <= 0) - kind = ads7828; + return 0; +} - if (kind == ads7828) - name = "ads7828"; +static int ads7828_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ads7828_data *data; + int err; - /* Fill in the remaining client fields, put it into the global list */ - strlcpy(client->name, name, I2C_NAME_SIZE); + data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - err = i2c_attach_client(client); - if (err) - goto exit_free; - /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &ads7828_group); if (err) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -262,8 +251,6 @@ static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &ads7828_group); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: -- cgit v0.10.2 From 008f1ca51e4a25ee3e34b8faa901dbeefaf0081a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:10 +0200 Subject: hwmon: (adt7470) Convert to a new-style i2c driver The new-style adt7470 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Darrick J. Wong diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 6b5325f..d368d8f 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -138,7 +138,6 @@ I2C_CLIENT_INSMOD_1(adt7470); #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) struct adt7470_data { - struct i2c_client client; struct device *hwmon_dev; struct attribute_group attrs; struct mutex lock; @@ -164,16 +163,28 @@ struct adt7470_data { u8 pwm_auto_temp[ADT7470_PWM_COUNT]; }; -static int adt7470_attach_adapter(struct i2c_adapter *adapter); -static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind); -static int adt7470_detach_client(struct i2c_client *client); +static int adt7470_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adt7470_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int adt7470_remove(struct i2c_client *client); + +static const struct i2c_device_id adt7470_id[] = { + { "adt7470", adt7470 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adt7470_id); static struct i2c_driver adt7470_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adt7470", }, - .attach_adapter = adt7470_attach_adapter, - .detach_client = adt7470_detach_client, + .probe = adt7470_probe, + .remove = adt7470_remove, + .id_table = adt7470_id, + .detect = adt7470_detect, + .address_data = &addr_data, }; /* @@ -1004,64 +1015,52 @@ static struct attribute *adt7470_attr[] = NULL }; -static int adt7470_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adt7470_detect); -} - -static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adt7470_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct adt7470_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - client->addr = address; - client->adapter = adapter; - client->driver = &adt7470_driver; - - i2c_set_clientdata(client, data); - - mutex_init(&data->lock); + return -ENODEV; if (kind <= 0) { int vendor, device, revision; vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR); - if (vendor != ADT7470_VENDOR) { - err = -ENODEV; - goto exit_free; - } + if (vendor != ADT7470_VENDOR) + return -ENODEV; device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE); - if (device != ADT7470_DEVICE) { - err = -ENODEV; - goto exit_free; - } + if (device != ADT7470_DEVICE) + return -ENODEV; revision = i2c_smbus_read_byte_data(client, ADT7470_REG_REVISION); - if (revision != ADT7470_REVISION) { - err = -ENODEV; - goto exit_free; - } + if (revision != ADT7470_REVISION) + return -ENODEV; } else dev_dbg(&adapter->dev, "detection forced\n"); - strlcpy(client->name, "adt7470", I2C_NAME_SIZE); + strlcpy(info->type, "adt7470", I2C_NAME_SIZE); - if ((err = i2c_attach_client(client))) - goto exit_free; + return 0; +} + +static int adt7470_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt7470_data *data; + int err; + + data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); dev_info(&client->dev, "%s chip found\n", client->name); @@ -1071,7 +1070,7 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) /* Register sysfs hooks */ data->attrs.attrs = adt7470_attr; if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -1083,21 +1082,18 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int adt7470_detach_client(struct i2c_client *client) +static int adt7470_remove(struct i2c_client *client) { struct adt7470_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->attrs); - i2c_detach_client(client); kfree(data); return 0; } -- cgit v0.10.2 From eea54766c6e3f9850affa91061164aeb6bba44b6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:10 +0200 Subject: hwmon: (adt7473) Convert to a new-style i2c driver The new-style adt7473 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Darrick J. Wong diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index 93dbf5e..ce4a7cb 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c @@ -143,7 +143,6 @@ I2C_CLIENT_INSMOD_1(adt7473); #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) struct adt7473_data { - struct i2c_client client; struct device *hwmon_dev; struct attribute_group attrs; struct mutex lock; @@ -178,16 +177,28 @@ struct adt7473_data { u8 max_duty_at_overheat; }; -static int adt7473_attach_adapter(struct i2c_adapter *adapter); -static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind); -static int adt7473_detach_client(struct i2c_client *client); +static int adt7473_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int adt7473_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int adt7473_remove(struct i2c_client *client); + +static const struct i2c_device_id adt7473_id[] = { + { "adt7473", adt7473 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adt7473_id); static struct i2c_driver adt7473_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "adt7473", }, - .attach_adapter = adt7473_attach_adapter, - .detach_client = adt7473_detach_client, + .probe = adt7473_probe, + .remove = adt7473_remove, + .id_table = adt7473_id, + .detect = adt7473_detect, + .address_data = &addr_data, }; /* @@ -1042,66 +1053,52 @@ static struct attribute *adt7473_attr[] = NULL }; -static int adt7473_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int adt7473_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, adt7473_detect); -} - -static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct adt7473_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - client->addr = address; - client->adapter = adapter; - client->driver = &adt7473_driver; - - i2c_set_clientdata(client, data); - - mutex_init(&data->lock); + return -ENODEV; if (kind <= 0) { int vendor, device, revision; vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR); - if (vendor != ADT7473_VENDOR) { - err = -ENODEV; - goto exit_free; - } + if (vendor != ADT7473_VENDOR) + return -ENODEV; device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE); - if (device != ADT7473_DEVICE) { - err = -ENODEV; - goto exit_free; - } + if (device != ADT7473_DEVICE) + return -ENODEV; revision = i2c_smbus_read_byte_data(client, ADT7473_REG_REVISION); - if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69) { - err = -ENODEV; - goto exit_free; - } + if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69) + return -ENODEV; } else dev_dbg(&adapter->dev, "detection forced\n"); - strlcpy(client->name, "adt7473", I2C_NAME_SIZE); + strlcpy(info->type, "adt7473", I2C_NAME_SIZE); - err = i2c_attach_client(client); - if (err) - goto exit_free; + return 0; +} + +static int adt7473_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt7473_data *data; + int err; + + data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); dev_info(&client->dev, "%s chip found\n", client->name); @@ -1112,7 +1109,7 @@ static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind) data->attrs.attrs = adt7473_attr; err = sysfs_create_group(&client->dev.kobj, &data->attrs); if (err) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -1124,21 +1121,18 @@ static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int adt7473_detach_client(struct i2c_client *client) +static int adt7473_remove(struct i2c_client *client) { struct adt7473_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &data->attrs); - i2c_detach_client(client); kfree(data); return 0; } -- cgit v0.10.2 From 063675b15608dfbb8404b3a19546d579bd039d02 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: hwmon: (asb100) Convert to a new-style i2c driver The new-style asb100 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index fe2eea4..8a45a2e 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -176,10 +176,8 @@ static u8 DIV_TO_REG(long val) data is pointed to by client->data. The structure itself is dynamically allocated, at the same time the client itself is allocated. */ struct asb100_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex lock; - enum chips type; struct mutex update_lock; unsigned long last_updated; /* In jiffies */ @@ -206,18 +204,30 @@ struct asb100_data { static int asb100_read_value(struct i2c_client *client, u16 reg); static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val); -static int asb100_attach_adapter(struct i2c_adapter *adapter); -static int asb100_detect(struct i2c_adapter *adapter, int address, int kind); -static int asb100_detach_client(struct i2c_client *client); +static int asb100_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int asb100_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int asb100_remove(struct i2c_client *client); static struct asb100_data *asb100_update_device(struct device *dev); static void asb100_init_client(struct i2c_client *client); +static const struct i2c_device_id asb100_id[] = { + { "asb100", asb100 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, asb100_id); + static struct i2c_driver asb100_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "asb100", }, - .attach_adapter = asb100_attach_adapter, - .detach_client = asb100_detach_client, + .probe = asb100_probe, + .remove = asb100_remove, + .id_table = asb100_id, + .detect = asb100_detect, + .address_data = &addr_data, }; /* 7 Voltages */ @@ -619,35 +629,13 @@ static const struct attribute_group asb100_group = { .attrs = asb100_attributes, }; -/* This function is called when: - asb100_driver is inserted (when this module is loaded), for each - available adapter - when a new adapter is inserted (and asb100_driver is still present) - */ -static int asb100_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, asb100_detect); -} - -static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, - int kind, struct i2c_client *client) +static int asb100_detect_subclients(struct i2c_client *client) { int i, id, err; + int address = client->addr; + unsigned short sc_addr[2]; struct asb100_data *data = i2c_get_clientdata(client); - - data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!(data->lm75[0])) { - err = -ENOMEM; - goto ERROR_SC_0; - } - - data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!(data->lm75[1])) { - err = -ENOMEM; - goto ERROR_SC_1; - } + struct i2c_adapter *adapter = client->adapter; id = i2c_adapter_id(adapter); @@ -665,37 +653,34 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, asb100_write_value(client, ASB100_REG_I2C_SUBADDR, (force_subclients[2] & 0x07) | ((force_subclients[3] & 0x07) << 4)); - data->lm75[0]->addr = force_subclients[2]; - data->lm75[1]->addr = force_subclients[3]; + sc_addr[0] = force_subclients[2]; + sc_addr[1] = force_subclients[3]; } else { int val = asb100_read_value(client, ASB100_REG_I2C_SUBADDR); - data->lm75[0]->addr = 0x48 + (val & 0x07); - data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07); + sc_addr[0] = 0x48 + (val & 0x07); + sc_addr[1] = 0x48 + ((val >> 4) & 0x07); } - if (data->lm75[0]->addr == data->lm75[1]->addr) { + if (sc_addr[0] == sc_addr[1]) { dev_err(&client->dev, "duplicate addresses 0x%x " - "for subclients\n", data->lm75[0]->addr); + "for subclients\n", sc_addr[0]); err = -ENODEV; goto ERROR_SC_2; } - for (i = 0; i <= 1; i++) { - i2c_set_clientdata(data->lm75[i], NULL); - data->lm75[i]->adapter = adapter; - data->lm75[i]->driver = &asb100_driver; - strlcpy(data->lm75[i]->name, "asb100 subclient", I2C_NAME_SIZE); - } - - if ((err = i2c_attach_client(data->lm75[0]))) { + data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]); + if (!data->lm75[0]) { dev_err(&client->dev, "subclient %d registration " - "at address 0x%x failed.\n", i, data->lm75[0]->addr); + "at address 0x%x failed.\n", 1, sc_addr[0]); + err = -ENOMEM; goto ERROR_SC_2; } - if ((err = i2c_attach_client(data->lm75[1]))) { + data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]); + if (!data->lm75[1]) { dev_err(&client->dev, "subclient %d registration " - "at address 0x%x failed.\n", i, data->lm75[1]->addr); + "at address 0x%x failed.\n", 2, sc_addr[1]); + err = -ENOMEM; goto ERROR_SC_3; } @@ -703,55 +688,31 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, /* Undo inits in case of errors */ ERROR_SC_3: - i2c_detach_client(data->lm75[0]); + i2c_unregister_device(data->lm75[0]); ERROR_SC_2: - kfree(data->lm75[1]); -ERROR_SC_1: - kfree(data->lm75[0]); -ERROR_SC_0: return err; } -static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int asb100_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - int err; - struct i2c_client *client; - struct asb100_data *data; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { pr_debug("asb100.o: detect failed, " "smbus byte data not supported!\n"); - err = -ENODEV; - goto ERROR0; + return -ENODEV; } - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access asb100_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL))) { - pr_debug("asb100.o: detect failed, kzalloc failed!\n"); - err = -ENOMEM; - goto ERROR0; - } - - client = &data->client; - mutex_init(&data->lock); - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &asb100_driver; - - /* Now, we do the remaining detection. */ - /* The chip may be stuck in some other bank than bank 0. This may make reading other information impossible. Specify a force=... or force_*=... parameter, and the chip will be reset to the right bank. */ if (kind < 0) { - int val1 = asb100_read_value(client, ASB100_REG_BANK); - int val2 = asb100_read_value(client, ASB100_REG_CHIPMAN); + int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK); + int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN); /* If we're in bank 0 */ if ((!(val1 & 0x07)) && @@ -761,48 +722,60 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ((val1 & 0x80) && (val2 != 0x06)))) { pr_debug("asb100.o: detect failed, " "bad chip id 0x%02x!\n", val2); - err = -ENODEV; - goto ERROR1; + return -ENODEV; } } /* kind < 0 */ /* We have either had a force parameter, or we have already detected Winbond. Put it now into bank 0 and Vendor ID High Byte */ - asb100_write_value(client, ASB100_REG_BANK, - (asb100_read_value(client, ASB100_REG_BANK) & 0x78) | 0x80); + i2c_smbus_write_byte_data(client, ASB100_REG_BANK, + (i2c_smbus_read_byte_data(client, ASB100_REG_BANK) & 0x78) + | 0x80); /* Determine the chip type. */ if (kind <= 0) { - int val1 = asb100_read_value(client, ASB100_REG_WCHIPID); - int val2 = asb100_read_value(client, ASB100_REG_CHIPMAN); + int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID); + int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN); if ((val1 == 0x31) && (val2 == 0x06)) kind = asb100; else { if (kind == 0) - dev_warn(&client->dev, "ignoring " + dev_warn(&adapter->dev, "ignoring " "'force' parameter for unknown chip " "at adapter %d, address 0x%02x.\n", - i2c_adapter_id(adapter), address); - err = -ENODEV; - goto ERROR1; + i2c_adapter_id(adapter), client->addr); + return -ENODEV; } } - /* Fill in remaining client fields and put it into the global list */ - strlcpy(client->name, "asb100", I2C_NAME_SIZE); - data->type = kind; - mutex_init(&data->update_lock); + strlcpy(info->type, "asb100", I2C_NAME_SIZE); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto ERROR1; + return 0; +} + +static int asb100_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + struct asb100_data *data; + + data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL); + if (!data) { + pr_debug("asb100.o: probe failed, kzalloc failed!\n"); + err = -ENOMEM; + goto ERROR0; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + mutex_init(&data->update_lock); /* Attach secondary lm75 clients */ - if ((err = asb100_detect_subclients(adapter, address, kind, - client))) - goto ERROR2; + err = asb100_detect_subclients(client); + if (err) + goto ERROR1; /* Initialize the chip */ asb100_init_client(client); @@ -827,39 +800,25 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ERROR4: sysfs_remove_group(&client->dev.kobj, &asb100_group); ERROR3: - i2c_detach_client(data->lm75[1]); - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[1]); - kfree(data->lm75[0]); -ERROR2: - i2c_detach_client(client); + i2c_unregister_device(data->lm75[1]); + i2c_unregister_device(data->lm75[0]); ERROR1: kfree(data); ERROR0: return err; } -static int asb100_detach_client(struct i2c_client *client) +static int asb100_remove(struct i2c_client *client) { struct asb100_data *data = i2c_get_clientdata(client); - int err; - - /* main client */ - if (data) { - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &asb100_group); - } - if ((err = i2c_detach_client(client))) - return err; + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &asb100_group); - /* main client */ - if (data) - kfree(data); + i2c_unregister_device(data->lm75[1]); + i2c_unregister_device(data->lm75[0]); - /* subclient */ - else - kfree(client); + kfree(data); return 0; } -- cgit v0.10.2 From 71163c7c36fa76bb5a72feca7fb685677444070a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: hwmon: (atxp1) Convert to a new-style i2c driver The new-style atxp1 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 01c17e3..d191118 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -46,21 +46,32 @@ static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; I2C_CLIENT_INSMOD_1(atxp1); -static int atxp1_attach_adapter(struct i2c_adapter * adapter); -static int atxp1_detach_client(struct i2c_client * client); +static int atxp1_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int atxp1_remove(struct i2c_client *client); static struct atxp1_data * atxp1_update_device(struct device *dev); -static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); +static int atxp1_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); + +static const struct i2c_device_id atxp1_id[] = { + { "atxp1", atxp1 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, atxp1_id); static struct i2c_driver atxp1_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "atxp1", }, - .attach_adapter = atxp1_attach_adapter, - .detach_client = atxp1_detach_client, + .probe = atxp1_probe, + .remove = atxp1_remove, + .id_table = atxp1_id, + .detect = atxp1_detect, + .address_data = &addr_data, }; struct atxp1_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; unsigned long last_updated; @@ -263,35 +274,16 @@ static const struct attribute_group atxp1_group = { }; -static int atxp1_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int atxp1_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, &atxp1_detect); -}; + struct i2c_adapter *adapter = new_client->adapter; -static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client * new_client; - struct atxp1_data * data; - int err = 0; u8 temp; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - new_client = &data->client; - i2c_set_clientdata(new_client, data); - - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &atxp1_driver; - new_client->flags = 0; + return -ENODEV; /* Detect ATXP1, checking if vendor ID registers are all zero */ if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && @@ -305,35 +297,46 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) - goto exit_free; + return -ENODEV; } /* Get VRM */ - data->vrm = vid_which_vrm(); + temp = vid_which_vrm(); - if ((data->vrm != 90) && (data->vrm != 91)) { - dev_err(&new_client->dev, "Not supporting VRM %d.%d\n", - data->vrm / 10, data->vrm % 10); - goto exit_free; + if ((temp != 90) && (temp != 91)) { + dev_err(&adapter->dev, "atxp1: Not supporting VRM %d.%d\n", + temp / 10, temp % 10); + return -ENODEV; } - strncpy(new_client->name, "atxp1", I2C_NAME_SIZE); - - data->valid = 0; + strlcpy(info->type, "atxp1", I2C_NAME_SIZE); - mutex_init(&data->update_lock); + return 0; +} - err = i2c_attach_client(new_client); +static int atxp1_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct atxp1_data *data; + int err; - if (err) - { - dev_err(&new_client->dev, "Attach client error.\n"); - goto exit_free; + data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; } + /* Get VRM */ + data->vrm = vid_which_vrm(); + + i2c_set_clientdata(new_client, data); + data->valid = 0; + + mutex_init(&data->update_lock); + /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -348,30 +351,22 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; }; -static int atxp1_detach_client(struct i2c_client * client) +static int atxp1_remove(struct i2c_client *client) { struct atxp1_data * data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &atxp1_group); - err = i2c_detach_client(client); - - if (err) - dev_err(&client->dev, "Failed to detach client.\n"); - else - kfree(data); + kfree(data); - return err; + return 0; }; static int __init atxp1_init(void) -- cgit v0.10.2 From 70313eabfc63ce6aa89b9fa3074129e5c521568a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: hwmon: (ds1621) Convert to a new-style i2c driver The new-style ds1621 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 5f300ff..7415381 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -72,7 +72,6 @@ static const u8 DS1621_REG_TEMP[3] = { /* Each client has this additional data */ struct ds1621_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -82,20 +81,32 @@ struct ds1621_data { u8 conf; /* Register encoding, combined */ }; -static int ds1621_attach_adapter(struct i2c_adapter *adapter); -static int ds1621_detect(struct i2c_adapter *adapter, int address, - int kind); +static int ds1621_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int ds1621_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void ds1621_init_client(struct i2c_client *client); -static int ds1621_detach_client(struct i2c_client *client); +static int ds1621_remove(struct i2c_client *client); static struct ds1621_data *ds1621_update_client(struct device *dev); +static const struct i2c_device_id ds1621_id[] = { + { "ds1621", ds1621 }, + { "ds1625", ds1621 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ds1621_id); + /* This is the driver that will be inserted */ static struct i2c_driver ds1621_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "ds1621", }, - .attach_adapter = ds1621_attach_adapter, - .detach_client = ds1621_detach_client, + .probe = ds1621_probe, + .remove = ds1621_remove, + .id_table = ds1621_id, + .detect = ds1621_detect, + .address_data = &addr_data, }; /* All registers are word-sized, except for the configuration register. @@ -199,40 +210,18 @@ static const struct attribute_group ds1621_group = { }; -static int ds1621_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, ds1621_detect); -} - -/* This function is called by i2c_probe */ -static int ds1621_detect(struct i2c_adapter *adapter, int address, - int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int ds1621_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { + struct i2c_adapter *adapter = client->adapter; int conf, temp; - struct i2c_client *client; - struct ds1621_data *data; - int i, err = 0; + int i; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_WRITE_BYTE)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access ds1621_{read,write}_value. */ - if (!(data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &ds1621_driver; + return -ENODEV; /* Now, we do the remaining detection. It is lousy. */ if (kind < 0) { @@ -241,29 +230,41 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, improbable in our case. */ conf = ds1621_read_value(client, DS1621_REG_CONF); if (conf & DS1621_REG_CONFIG_NVB) - goto exit_free; + return -ENODEV; /* The 7 lowest bits of a temperature should always be 0. */ - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) { temp = ds1621_read_value(client, DS1621_REG_TEMP[i]); if (temp & 0x007f) - goto exit_free; + return -ENODEV; } } - /* Fill in remaining client fields and put it into the global list */ - strlcpy(client->name, "ds1621", I2C_NAME_SIZE); - mutex_init(&data->update_lock); + strlcpy(info->type, "ds1621", I2C_NAME_SIZE); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; + return 0; +} + +static int ds1621_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ds1621_data *data; + int err; + + data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); /* Initialize the DS1621 chip */ ds1621_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -275,25 +276,19 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &ds1621_group); - exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int ds1621_detach_client(struct i2c_client *client) +static int ds1621_remove(struct i2c_client *client) { struct ds1621_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &ds1621_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; -- cgit v0.10.2 From 935ada8c4481f9591caa1b88c83127c5931a8855 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:11 +0200 Subject: hwmon: (f75375s) Drop legacy i2c driver Drop the legacy f75375s i2c driver, and add a detect callback to the new-style i2c driver to achieve the same functionality. Signed-off-by: Jean Delvare Acked-by: Riku Voipio diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index dc1f30e..1692de3 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -87,7 +87,6 @@ I2C_CLIENT_INSMOD_2(f75373, f75375); struct f75375_data { unsigned short addr; - struct i2c_client *client; struct device *hwmon_dev; const char *name; @@ -114,21 +113,12 @@ struct f75375_data { s8 temp_max_hyst[2]; }; -static int f75375_attach_adapter(struct i2c_adapter *adapter); -static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); -static int f75375_detach_client(struct i2c_client *client); +static int f75375_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static int f75375_probe(struct i2c_client *client, const struct i2c_device_id *id); static int f75375_remove(struct i2c_client *client); -static struct i2c_driver f75375_legacy_driver = { - .driver = { - .name = "f75375_legacy", - }, - .attach_adapter = f75375_attach_adapter, - .detach_client = f75375_detach_client, -}; - static const struct i2c_device_id f75375_id[] = { { "f75373", f75373 }, { "f75375", f75375 }, @@ -137,12 +127,15 @@ static const struct i2c_device_id f75375_id[] = { MODULE_DEVICE_TABLE(i2c, f75375_id); static struct i2c_driver f75375_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "f75375", }, .probe = f75375_probe, .remove = f75375_remove, .id_table = f75375_id, + .detect = f75375_detect, + .address_data = &addr_data, }; static inline int f75375_read8(struct i2c_client *client, u8 reg) @@ -607,22 +600,6 @@ static const struct attribute_group f75375_group = { .attrs = f75375_attributes, }; -static int f75375_detach_client(struct i2c_client *client) -{ - int err; - - f75375_remove(client); - err = i2c_detach_client(client); - if (err) { - dev_err(&client->dev, - "Client deregistration failed, " - "client not detached.\n"); - return err; - } - kfree(client); - return 0; -} - static void f75375_init(struct i2c_client *client, struct f75375_data *data, struct f75375s_platform_data *f75375s_pdata) { @@ -651,7 +628,6 @@ static int f75375_probe(struct i2c_client *client, return -ENOMEM; i2c_set_clientdata(client, data); - data->client = client; mutex_init(&data->update_lock); data->kind = id->driver_data; @@ -700,29 +676,13 @@ static int f75375_remove(struct i2c_client *client) return 0; } -static int f75375_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, f75375_detect); -} - -/* This function is called by i2c_probe */ -static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int f75375_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; + struct i2c_adapter *adapter = client->adapter; u8 version = 0; - int err = 0; const char *name = ""; - struct i2c_device_id id; - - if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - client->addr = address; - client->adapter = adapter; - client->driver = &f75375_legacy_driver; if (kind < 0) { u16 vendid = f75375_read16(client, F75375_REG_VENDOR); @@ -736,7 +696,7 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) dev_err(&adapter->dev, "failed,%02X,%02X,%02X\n", chipid, version, vendid); - goto exit_free; + return -ENODEV; } } @@ -746,43 +706,18 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) name = "f75373"; } dev_info(&adapter->dev, "found %s version: %02X\n", name, version); - strlcpy(client->name, name, I2C_NAME_SIZE); - - if ((err = i2c_attach_client(client))) - goto exit_free; - - strlcpy(id.name, name, I2C_NAME_SIZE); - id.driver_data = kind; - if ((err = f75375_probe(client, &id)) < 0) - goto exit_detach; + strlcpy(info->type, name, I2C_NAME_SIZE); return 0; - -exit_detach: - i2c_detach_client(client); -exit_free: - kfree(client); -exit: - return err; } static int __init sensors_f75375_init(void) { - int status; - status = i2c_add_driver(&f75375_driver); - if (status) - return status; - - status = i2c_add_driver(&f75375_legacy_driver); - if (status) - i2c_del_driver(&f75375_driver); - - return status; + return i2c_add_driver(&f75375_driver); } static void __exit sensors_f75375_exit(void) { - i2c_del_driver(&f75375_legacy_driver); i2c_del_driver(&f75375_driver); } -- cgit v0.10.2 From c2df1591df3ea83b4a5890a1131dd821ca07e761 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:12 +0200 Subject: hwmon: (fscher) Convert to a new-style i2c driver The new-style fscher driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Reinhard Nissl diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index ed26b66..12c70e4 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c @@ -106,9 +106,11 @@ I2C_CLIENT_INSMOD_1(fscher); * Functions declaration */ -static int fscher_attach_adapter(struct i2c_adapter *adapter); -static int fscher_detect(struct i2c_adapter *adapter, int address, int kind); -static int fscher_detach_client(struct i2c_client *client); +static int fscher_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int fscher_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int fscher_remove(struct i2c_client *client); static struct fscher_data *fscher_update_device(struct device *dev); static void fscher_init_client(struct i2c_client *client); @@ -119,12 +121,21 @@ static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value); * Driver data (common to all clients) */ +static const struct i2c_device_id fscher_id[] = { + { "fscher", fscher }, + { } +}; + static struct i2c_driver fscher_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "fscher", }, - .attach_adapter = fscher_attach_adapter, - .detach_client = fscher_detach_client, + .probe = fscher_probe, + .remove = fscher_remove, + .id_table = fscher_id, + .detect = fscher_detect, + .address_data = &addr_data, }; /* @@ -132,7 +143,6 @@ static struct i2c_driver fscher_driver = { */ struct fscher_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -283,38 +293,14 @@ static const struct attribute_group fscher_group = { * Real code */ -static int fscher_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, fscher_detect); -} - -static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int fscher_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct fscher_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - * client structure, even though we cannot fill it completely yet. - * But it allows us to access i2c_smbus_read_byte_data. */ - if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - * Hermes-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &fscher_driver; - new_client->flags = 0; + return -ENODEV; /* Do the remaining detection unless force or force_fscher parameter */ if (kind < 0) { @@ -324,24 +310,35 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) FSCHER_REG_IDENT_1) != 0x45) /* 'E' */ || (i2c_smbus_read_byte_data(new_client, FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */ - goto exit_free; + return -ENODEV; + } + + strlcpy(info->type, "fscher", I2C_NAME_SIZE); + + return 0; +} + +static int fscher_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct fscher_data *data; + int err; + + data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; } - /* Fill in the remaining client fields and put it into the - * global list */ - strlcpy(new_client->name, "fscher", I2C_NAME_SIZE); + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - fscher_init_client(new_client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -353,25 +350,19 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &fscher_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; } -static int fscher_detach_client(struct i2c_client *client) +static int fscher_remove(struct i2c_client *client) { struct fscher_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &fscher_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 40ac1994bf988dac05434f856c2a4fa24e22b2ea Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:12 +0200 Subject: hwmon: (fschmd) Convert to a new-style i2c driver The new-style fschmd driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Hans de Goede diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index bd89d27..9671703 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -171,20 +171,37 @@ static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 }; * Functions declarations */ -static int fschmd_attach_adapter(struct i2c_adapter *adapter); -static int fschmd_detach_client(struct i2c_client *client); +static int fschmd_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int fschmd_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int fschmd_remove(struct i2c_client *client); static struct fschmd_data *fschmd_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id fschmd_id[] = { + { "fscpos", fscpos }, + { "fscher", fscher }, + { "fscscy", fscscy }, + { "fschrc", fschrc }, + { "fschmd", fschmd }, + { } +}; +MODULE_DEVICE_TABLE(i2c, fschmd_id); + static struct i2c_driver fschmd_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = FSCHMD_NAME, }, - .attach_adapter = fschmd_attach_adapter, - .detach_client = fschmd_detach_client, + .probe = fschmd_probe, + .remove = fschmd_remove, + .id_table = fschmd_id, + .detect = fschmd_detect, + .address_data = &addr_data, }; /* @@ -192,7 +209,6 @@ static struct i2c_driver fschmd_driver = { */ struct fschmd_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; int kind; @@ -269,7 +285,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute v = SENSORS_LIMIT(v, -128, 127) + 128; mutex_lock(&data->update_lock); - i2c_smbus_write_byte_data(&data->client, + i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_TEMP_LIMIT[data->kind][index], v); data->temp_max[index] = v; mutex_unlock(&data->update_lock); @@ -346,14 +362,14 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute mutex_lock(&data->update_lock); - reg = i2c_smbus_read_byte_data(&data->client, + reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_FAN_RIPPLE[data->kind][index]); /* bits 2..7 reserved => mask with 0x03 */ reg &= ~0x03; reg |= v; - i2c_smbus_write_byte_data(&data->client, + i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg); data->fan_ripple[index] = reg; @@ -416,7 +432,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, mutex_lock(&data->update_lock); - i2c_smbus_write_byte_data(&data->client, + i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_FAN_MIN[data->kind][index], v); data->fan_min[index] = v; @@ -448,14 +464,14 @@ static ssize_t store_alert_led(struct device *dev, mutex_lock(&data->update_lock); - reg = i2c_smbus_read_byte_data(&data->client, FSCHMD_REG_CONTROL); + reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL); if (v) reg |= FSCHMD_CONTROL_ALERT_LED_MASK; else reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK; - i2c_smbus_write_byte_data(&data->client, FSCHMD_REG_CONTROL, reg); + i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg); data->global_control = reg; @@ -600,32 +616,15 @@ static void fschmd_dmi_decode(const struct dmi_header *header) } } -static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind) +static int fschmd_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct fschmd_data *data; - u8 revision; - const char * const names[5] = { "Poseidon", "Hermes", "Scylla", - "Heracles", "Heimdall" }; + struct i2c_adapter *adapter = client->adapter; const char * const client_names[5] = { "fscpos", "fscher", "fscscy", "fschrc", "fschmd" }; - int i, err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - - /* OK. For now, we presume we have a valid client. We now create the - * client structure, even though we cannot fill it completely yet. - * But it allows us to access i2c_smbus_read_byte_data. */ - if (!(data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL))) - return -ENOMEM; - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &fschmd_driver; - mutex_init(&data->update_lock); + return -ENODEV; /* Detect & Identify the chip */ if (kind <= 0) { @@ -650,9 +649,31 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind) else if (!strcmp(id, "HMD")) kind = fschmd; else - goto exit_free; + return -ENODEV; } + strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE); + + return 0; +} + +static int fschmd_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct fschmd_data *data; + u8 revision; + const char * const names[5] = { "Poseidon", "Hermes", "Scylla", + "Heracles", "Heimdall" }; + int i, err; + enum chips kind = id->driver_data; + + data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + if (kind == fscpos) { /* The Poseidon has hardwired temp limits, fill these in for the alarm resetting code */ @@ -674,11 +695,6 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind) /* i2c kind goes from 1-5, we want from 0-4 to address arrays */ data->kind = kind - 1; - strlcpy(client->name, client_names[data->kind], I2C_NAME_SIZE); - - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) { err = device_create_file(&client->dev, @@ -726,25 +742,14 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind) return 0; exit_detach: - fschmd_detach_client(client); /* will also free data for us */ - return err; - -exit_free: - kfree(data); + fschmd_remove(client); /* will also free data for us */ return err; } -static int fschmd_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, fschmd_detect); -} - -static int fschmd_detach_client(struct i2c_client *client) +static int fschmd_remove(struct i2c_client *client) { struct fschmd_data *data = i2c_get_clientdata(client); - int i, err; + int i; /* Check if registered in case we're called from fschmd_detect to cleanup after an error */ @@ -760,9 +765,6 @@ static int fschmd_detach_client(struct i2c_client *client) device_remove_file(&client->dev, &fschmd_fan_attr[i].dev_attr); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From b9e39b1b1b79d3e074ca79b63f548ac48c85ca98 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:12 +0200 Subject: hwmon: (fscpos) Convert to a new-style i2c driver The new-style fscpos driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 00f4848..8a7bcf5 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -87,9 +87,11 @@ static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 }; /* * Functions declaration */ -static int fscpos_attach_adapter(struct i2c_adapter *adapter); -static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind); -static int fscpos_detach_client(struct i2c_client *client); +static int fscpos_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int fscpos_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int fscpos_remove(struct i2c_client *client); static int fscpos_read_value(struct i2c_client *client, u8 reg); static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value); @@ -101,19 +103,27 @@ static void reset_fan_alarm(struct i2c_client *client, int nr); /* * Driver data (common to all clients) */ +static const struct i2c_device_id fscpos_id[] = { + { "fscpos", fscpos }, + { } +}; + static struct i2c_driver fscpos_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "fscpos", }, - .attach_adapter = fscpos_attach_adapter, - .detach_client = fscpos_detach_client, + .probe = fscpos_probe, + .remove = fscpos_remove, + .id_table = fscpos_id, + .detect = fscpos_detect, + .address_data = &addr_data, }; /* * Client data (each client gets its own) */ struct fscpos_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* 0 until following fields are valid */ @@ -470,39 +480,14 @@ static const struct attribute_group fscpos_group = { .attrs = fscpos_attributes, }; -static int fscpos_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, fscpos_detect); -} - -static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int fscpos_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct fscpos_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - /* - * OK. For now, we presume we have a valid client. We now create the - * client structure, even though we cannot fill it completely yet. - * But it allows us to access fscpos_{read,write}_value. - */ - - if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &fscpos_driver; - new_client->flags = 0; + return -ENODEV; /* Do the remaining detection unless force or force_fscpos parameter */ if (kind < 0) { @@ -512,22 +497,30 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) != 0x45) /* 'E' */ || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) != 0x47))/* 'G' */ - { - dev_dbg(&new_client->dev, "fscpos detection failed\n"); - goto exit_free; - } + return -ENODEV; } - /* Fill in the remaining client fields and put it in the global list */ - strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE); + strlcpy(info->type, "fscpos", I2C_NAME_SIZE); + return 0; +} + +static int fscpos_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct fscpos_data *data; + int err; + + data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Inizialize the fscpos chip */ fscpos_init_client(new_client); @@ -536,7 +529,7 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -548,24 +541,19 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &fscpos_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; } -static int fscpos_detach_client(struct i2c_client *client) +static int fscpos_remove(struct i2c_client *client) { struct fscpos_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &fscpos_group); - if ((err = i2c_detach_client(client))) - return err; kfree(data); return 0; } -- cgit v0.10.2 From 95d80e7c834d8742da38e2b9d2f36dec36da03a6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: hwmon: (gl518sm) Convert to a new-style i2c driver The new-style gl518sm driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 33e9e8a..7820df4 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -114,7 +114,6 @@ static inline u8 FAN_TO_REG(long rpm, int div) /* Each client has this additional data */ struct gl518_data { - struct i2c_client client; struct device *hwmon_dev; enum chips type; @@ -138,21 +137,33 @@ struct gl518_data { u8 beep_enable; /* Boolean */ }; -static int gl518_attach_adapter(struct i2c_adapter *adapter); -static int gl518_detect(struct i2c_adapter *adapter, int address, int kind); +static int gl518_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int gl518_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void gl518_init_client(struct i2c_client *client); -static int gl518_detach_client(struct i2c_client *client); +static int gl518_remove(struct i2c_client *client); static int gl518_read_value(struct i2c_client *client, u8 reg); static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value); static struct gl518_data *gl518_update_device(struct device *dev); +static const struct i2c_device_id gl518_id[] = { + { "gl518sm", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, gl518_id); + /* This is the driver that will be inserted */ static struct i2c_driver gl518_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "gl518sm", }, - .attach_adapter = gl518_attach_adapter, - .detach_client = gl518_detach_client, + .probe = gl518_probe, + .remove = gl518_remove, + .id_table = gl518_id, + .detect = gl518_detect, + .address_data = &addr_data, }; /* @@ -472,46 +483,23 @@ static const struct attribute_group gl518_group_r80 = { * Real code */ -static int gl518_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, gl518_detect); -} - -static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int gl518_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { + struct i2c_adapter *adapter = client->adapter; int i; - struct i2c_client *client; - struct gl518_data *data; - int err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access gl518_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - - client->addr = address; - client->adapter = adapter; - client->driver = &gl518_driver; + return -ENODEV; /* Now, we do the remaining detection. */ if (kind < 0) { if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80) || (gl518_read_value(client, GL518_REG_CONF) & 0x80)) - goto exit_free; + return -ENODEV; } /* Determine the chip type. */ @@ -526,19 +514,32 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Ignoring 'force' parameter for unknown " "chip at adapter %d, address 0x%02x\n", - i2c_adapter_id(adapter), address); - goto exit_free; + i2c_adapter_id(adapter), client->addr); + return -ENODEV; } } - /* Fill in the remaining client fields */ - strlcpy(client->name, "gl518sm", I2C_NAME_SIZE); - data->type = kind; - mutex_init(&data->update_lock); + strlcpy(info->type, "gl518sm", I2C_NAME_SIZE); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; + return 0; +} + +static int gl518_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct gl518_data *data; + int err, revision; + + data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + revision = gl518_read_value(client, GL518_REG_REVISION); + data->type = revision == 0x80 ? gl518sm_r80 : gl518sm_r00; + mutex_init(&data->update_lock); /* Initialize the GL518SM chip */ data->alarm_mask = 0xff; @@ -546,7 +547,7 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &gl518_group))) - goto exit_detach; + goto exit_free; if (data->type == gl518sm_r80) if ((err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80))) @@ -564,8 +565,6 @@ exit_remove_files: sysfs_remove_group(&client->dev.kobj, &gl518_group); if (data->type == gl518sm_r80) sysfs_remove_group(&client->dev.kobj, &gl518_group_r80); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: @@ -591,19 +590,15 @@ static void gl518_init_client(struct i2c_client *client) gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue); } -static int gl518_detach_client(struct i2c_client *client) +static int gl518_remove(struct i2c_client *client) { struct gl518_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &gl518_group); if (data->type == gl518sm_r80) sysfs_remove_group(&client->dev.kobj, &gl518_group_r80); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From a23a9fe1d4d725e1624635f49e9790ec32deffd0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: hwmon: (gl520sm) Convert to a new-style i2c driver The new-style gl520sm driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Maarten Deprez diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 8984ef1..19616f2 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -79,26 +79,37 @@ static const u8 GL520_REG_TEMP_MAX_HYST[] = { 0x06, 0x18 }; * Function declarations */ -static int gl520_attach_adapter(struct i2c_adapter *adapter); -static int gl520_detect(struct i2c_adapter *adapter, int address, int kind); +static int gl520_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int gl520_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void gl520_init_client(struct i2c_client *client); -static int gl520_detach_client(struct i2c_client *client); +static int gl520_remove(struct i2c_client *client); static int gl520_read_value(struct i2c_client *client, u8 reg); static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value); static struct gl520_data *gl520_update_device(struct device *dev); /* Driver data */ +static const struct i2c_device_id gl520_id[] = { + { "gl520sm", gl520sm }, + { } +}; +MODULE_DEVICE_TABLE(i2c, gl520_id); + static struct i2c_driver gl520_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "gl520sm", }, - .attach_adapter = gl520_attach_adapter, - .detach_client = gl520_detach_client, + .probe = gl520_probe, + .remove = gl520_remove, + .id_table = gl520_id, + .detect = gl520_detect, + .address_data = &addr_data, }; /* Client data */ struct gl520_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until the following fields are valid */ @@ -669,37 +680,15 @@ static const struct attribute_group gl520_group_opt = { * Real code */ -static int gl520_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, gl520_detect); -} - -static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int gl520_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct gl520_data *data; - int err = 0; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access gl520_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &gl520_driver; + return -ENODEV; /* Determine the chip type. */ if (kind < 0) { @@ -707,24 +696,36 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) || ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) { dev_dbg(&client->dev, "Unknown chip type, skipping\n"); - goto exit_free; + return -ENODEV; } } - /* Fill in the remaining client fields */ - strlcpy(client->name, "gl520sm", I2C_NAME_SIZE); - mutex_init(&data->update_lock); + strlcpy(info->type, "gl520sm", I2C_NAME_SIZE); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; + return 0; +} + +static int gl520_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct gl520_data *data; + int err; + + data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); /* Initialize the GL520SM chip */ gl520_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group))) - goto exit_detach; + goto exit_free; if (data->two_temps) { if ((err = device_create_file(&client->dev, @@ -764,8 +765,6 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&client->dev.kobj, &gl520_group); sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: @@ -811,18 +810,14 @@ static void gl520_init_client(struct i2c_client *client) gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); } -static int gl520_detach_client(struct i2c_client *client) +static int gl520_remove(struct i2c_client *client) { struct gl520_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &gl520_group); sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From d5957be2f1535b1a6c77eabba0781ec7245c5dea Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: hwmon: (lm63) Convert to a new-style i2c driver The new-style lm63 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 1162870..3195a26 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -1,7 +1,7 @@ /* * lm63.c - driver for the National Semiconductor LM63 temperature sensor * with integrated fan control - * Copyright (C) 2004-2006 Jean Delvare + * Copyright (C) 2004-2008 Jean Delvare * Based on the lm90 driver. * * The LM63 is a sensor chip made by National Semiconductor. It measures @@ -128,24 +128,36 @@ I2C_CLIENT_INSMOD_1(lm63); * Functions declaration */ -static int lm63_attach_adapter(struct i2c_adapter *adapter); -static int lm63_detach_client(struct i2c_client *client); +static int lm63_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int lm63_remove(struct i2c_client *client); static struct lm63_data *lm63_update_device(struct device *dev); -static int lm63_detect(struct i2c_adapter *adapter, int address, int kind); +static int lm63_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void lm63_init_client(struct i2c_client *client); /* * Driver data (common to all clients) */ +static const struct i2c_device_id lm63_id[] = { + { "lm63", lm63 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm63_id); + static struct i2c_driver lm63_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm63", }, - .attach_adapter = lm63_attach_adapter, - .detach_client = lm63_detach_client, + .probe = lm63_probe, + .remove = lm63_remove, + .id_table = lm63_id, + .detect = lm63_detect, + .address_data = &addr_data, }; /* @@ -153,7 +165,6 @@ static struct i2c_driver lm63_driver = { */ struct lm63_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -411,43 +422,14 @@ static const struct attribute_group lm63_group_fan1 = { * Real code */ -static int lm63_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm63_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm63_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *new_client; - struct lm63_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - LM63-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm63_driver; - new_client->flags = 0; - - /* Default to an LM63 if forced */ - if (kind == 0) - kind = lm63; + return -ENODEV; if (kind < 0) { /* must identify */ u8 man_id, chip_id, reg_config1, reg_config2; @@ -477,25 +459,38 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) dev_dbg(&adapter->dev, "Unsupported chip " "(man_id=0x%02X, chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } - strlcpy(new_client->name, "lm63", I2C_NAME_SIZE); + strlcpy(info->type, "lm63", I2C_NAME_SIZE); + + return 0; +} + +static int lm63_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct lm63_data *data; + int err; + + data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Initialize the LM63 chip */ lm63_init_client(new_client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm63_group))) - goto exit_detach; + goto exit_free; if (data->config & 0x04) { /* tachometer enabled */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm63_group_fan1))) @@ -513,8 +508,6 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm63_group); sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: @@ -556,18 +549,14 @@ static void lm63_init_client(struct i2c_client *client) (data->config_fan & 0x20) ? "manual" : "auto"); } -static int lm63_detach_client(struct i2c_client *client) +static int lm63_remove(struct i2c_client *client) { struct lm63_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm63_group); sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From a189dd62d328db7bf8ba68de6a948fdbc93dca25 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:13 +0200 Subject: hwmon: (lm77) Convert to a new-style i2c driver The new-style lm77 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Andras Bali diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 36d5a8c..866b401 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -52,7 +52,6 @@ I2C_CLIENT_INSMOD_1(lm77); /* Each client has this additional data */ struct lm77_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; @@ -65,23 +64,35 @@ struct lm77_data { u8 alarms; }; -static int lm77_attach_adapter(struct i2c_adapter *adapter); -static int lm77_detect(struct i2c_adapter *adapter, int address, int kind); +static int lm77_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int lm77_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void lm77_init_client(struct i2c_client *client); -static int lm77_detach_client(struct i2c_client *client); +static int lm77_remove(struct i2c_client *client); static u16 lm77_read_value(struct i2c_client *client, u8 reg); static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value); static struct lm77_data *lm77_update_device(struct device *dev); +static const struct i2c_device_id lm77_id[] = { + { "lm77", lm77 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm77_id); + /* This is the driver that will be inserted */ static struct i2c_driver lm77_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm77", }, - .attach_adapter = lm77_attach_adapter, - .detach_client = lm77_detach_client, + .probe = lm77_probe, + .remove = lm77_remove, + .id_table = lm77_id, + .detect = lm77_detect, + .address_data = &addr_data, }; /* straight from the datasheet */ @@ -215,13 +226,6 @@ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); -static int lm77_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm77_detect); -} - static struct attribute *lm77_attributes[] = { &dev_attr_temp1_input.attr, &dev_attr_temp1_crit.attr, @@ -240,32 +244,15 @@ static const struct attribute_group lm77_group = { .attrs = lm77_attributes, }; -/* This function is called by i2c_probe */ -static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm77_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct lm77_data *data; - int err = 0; - const char *name = ""; + struct i2c_adapter *adapter = new_client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access lm77_{read,write}_value. */ - if (!(data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm77_driver; - new_client->flags = 0; + return -ENODEV; /* Here comes the remaining detection. Since the LM77 has no register dedicated to identification, we have to rely on the @@ -294,7 +281,7 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) || i2c_smbus_read_word_data(new_client, i + 3) != crit || i2c_smbus_read_word_data(new_client, i + 4) != min || i2c_smbus_read_word_data(new_client, i + 5) != max) - goto exit_free; + return -ENODEV; /* sign bits */ if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0) @@ -302,51 +289,55 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0) || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0) || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0)) - goto exit_free; + return -ENODEV; /* unused bits */ if (conf & 0xe0) - goto exit_free; + return -ENODEV; /* 0x06 and 0x07 return the last read value */ cur = i2c_smbus_read_word_data(new_client, 0); if (i2c_smbus_read_word_data(new_client, 6) != cur || i2c_smbus_read_word_data(new_client, 7) != cur) - goto exit_free; + return -ENODEV; hyst = i2c_smbus_read_word_data(new_client, 2); if (i2c_smbus_read_word_data(new_client, 6) != hyst || i2c_smbus_read_word_data(new_client, 7) != hyst) - goto exit_free; + return -ENODEV; min = i2c_smbus_read_word_data(new_client, 4); if (i2c_smbus_read_word_data(new_client, 6) != min || i2c_smbus_read_word_data(new_client, 7) != min) - goto exit_free; + return -ENODEV; } - /* Determine the chip type - only one kind supported! */ - if (kind <= 0) - kind = lm77; + strlcpy(info->type, "lm77", I2C_NAME_SIZE); - if (kind == lm77) { - name = "lm77"; + return 0; +} + +static int lm77_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct lm77_data *data; + int err; + + data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; } - /* Fill in the remaining client fields and put it into the global list */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Initialize the LM77 chip */ lm77_init_client(new_client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -358,20 +349,17 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&new_client->dev.kobj, &lm77_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; } -static int lm77_detach_client(struct i2c_client *client) +static int lm77_remove(struct i2c_client *client) { struct lm77_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm77_group); - i2c_detach_client(client); kfree(data); return 0; } -- cgit v0.10.2 From 8c8bacc883610b672d3f08dc6ebf1f17e495f5b9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:14 +0200 Subject: hwmon: (lm80) Convert to a new-style i2c driver The new-style lm80 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 26c91c9..bcffc18 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -108,7 +108,6 @@ static inline long TEMP_FROM_REG(u16 temp) */ struct lm80_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -132,10 +131,12 @@ struct lm80_data { * Functions declaration */ -static int lm80_attach_adapter(struct i2c_adapter *adapter); -static int lm80_detect(struct i2c_adapter *adapter, int address, int kind); +static int lm80_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int lm80_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void lm80_init_client(struct i2c_client *client); -static int lm80_detach_client(struct i2c_client *client); +static int lm80_remove(struct i2c_client *client); static struct lm80_data *lm80_update_device(struct device *dev); static int lm80_read_value(struct i2c_client *client, u8 reg); static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); @@ -144,12 +145,22 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); * Driver data (common to all clients) */ +static const struct i2c_device_id lm80_id[] = { + { "lm80", lm80 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm80_id); + static struct i2c_driver lm80_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm80", }, - .attach_adapter = lm80_attach_adapter, - .detach_client = lm80_detach_client, + .probe = lm80_probe, + .remove = lm80_remove, + .id_table = lm80_id, + .detect = lm80_detect, + .address_data = &addr_data, }; /* @@ -383,13 +394,6 @@ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 13); * Real code */ -static int lm80_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm80_detect); -} - static struct attribute *lm80_attributes[] = { &sensor_dev_attr_in0_min.dev_attr.attr, &sensor_dev_attr_in1_min.dev_attr.attr, @@ -442,53 +446,46 @@ static const struct attribute_group lm80_group = { .attrs = lm80_attributes, }; -static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm80_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { + struct i2c_adapter *adapter = client->adapter; int i, cur; - struct i2c_client *client; - struct lm80_data *data; - int err = 0; - const char *name; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access lm80_{read,write}_value. */ - if (!(data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &lm80_driver; + return -ENODEV; /* Now, we do the remaining detection. It is lousy. */ if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0) - goto error_free; + return -ENODEV; for (i = 0x2a; i <= 0x3d; i++) { cur = i2c_smbus_read_byte_data(client, i); if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur) || (i2c_smbus_read_byte_data(client, i + 0x80) != cur) || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur)) - goto error_free; + return -ENODEV; } - /* Determine the chip type - only one kind supported! */ - kind = lm80; - name = "lm80"; + strlcpy(info->type, "lm80", I2C_NAME_SIZE); - /* Fill in the remaining client fields */ - strlcpy(client->name, name, I2C_NAME_SIZE); - mutex_init(&data->update_lock); + return 0; +} - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto error_free; +static int lm80_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct lm80_data *data; + int err; + + data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); /* Initialize the LM80 chip */ lm80_init_client(client); @@ -499,7 +496,7 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &lm80_group))) - goto error_detach; + goto error_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -511,23 +508,18 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) error_remove: sysfs_remove_group(&client->dev.kobj, &lm80_group); -error_detach: - i2c_detach_client(client); error_free: kfree(data); exit: return err; } -static int lm80_detach_client(struct i2c_client *client) +static int lm80_remove(struct i2c_client *client) { struct lm80_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm80_group); - if ((err = i2c_detach_client(client))) - return err; kfree(data); return 0; -- cgit v0.10.2 From b6aacdcefac8ed60e77930b6e74129da6478e20e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:14 +0200 Subject: hwmon: (lm83) Convert to a new-style i2c driver The new-style lm83 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 6a8642f..e59e2d1 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -1,7 +1,7 @@ /* * lm83.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring - * Copyright (C) 2003-2006 Jean Delvare + * Copyright (C) 2003-2008 Jean Delvare * * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is * a sensor chip made by National Semiconductor. It reports up to four @@ -118,21 +118,34 @@ static const u8 LM83_REG_W_HIGH[] = { * Functions declaration */ -static int lm83_attach_adapter(struct i2c_adapter *adapter); -static int lm83_detect(struct i2c_adapter *adapter, int address, int kind); -static int lm83_detach_client(struct i2c_client *client); +static int lm83_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info); +static int lm83_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int lm83_remove(struct i2c_client *client); static struct lm83_data *lm83_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id lm83_id[] = { + { "lm83", lm83 }, + { "lm82", lm82 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm83_id); + static struct i2c_driver lm83_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm83", }, - .attach_adapter = lm83_attach_adapter, - .detach_client = lm83_detach_client, + .probe = lm83_probe, + .remove = lm83_remove, + .id_table = lm83_id, + .detect = lm83_detect, + .address_data = &addr_data, }; /* @@ -140,7 +153,6 @@ static struct i2c_driver lm83_driver = { */ struct lm83_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -278,40 +290,15 @@ static const struct attribute_group lm83_group_opt = { * Real code */ -static int lm83_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm83_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm83_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *new_client; - struct lm83_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; const char *name = ""; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right after the - * LM83-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm83_driver; - new_client->flags = 0; + return -ENODEV; /* Now we do the detection and identification. A negative kind * means that the driver was loaded with no force parameter @@ -335,8 +322,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) & 0x41) != 0x00)) { dev_dbg(&adapter->dev, - "LM83 detection failed at 0x%02x.\n", address); - goto exit_free; + "LM83 detection failed at 0x%02x.\n", + new_client->addr); + return -ENODEV; } } @@ -361,7 +349,7 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, " "chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } @@ -372,15 +360,27 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) name = "lm82"; } - /* We can fill in the remaining client fields */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); + strlcpy(info->type, name, I2C_NAME_SIZE); + + return 0; +} + +static int lm83_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct lm83_data *data; + int err; + + data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* * Register sysfs hooks * The LM82 can only monitor one external diode which is @@ -389,9 +389,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group))) - goto exit_detach; + goto exit_free; - if (kind == lm83) { + if (id->driver_data == lm83) { if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group_opt))) goto exit_remove_files; @@ -408,26 +408,20 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm83_group); sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; } -static int lm83_detach_client(struct i2c_client *client) +static int lm83_remove(struct i2c_client *client) { struct lm83_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm83_group); sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From a888420af07b9a26b6d518328baa913fb704e950 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:14 +0200 Subject: hwmon: (lm87) Convert to a new-style i2c driver The new-style lm87 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Ben Hutchings diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index e1c183f..21970f0 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -5,7 +5,7 @@ * Philip Edelbrock * Stephen Rousset * Dan Eaton - * Copyright (C) 2004,2007 Jean Delvare + * Copyright (C) 2004-2008 Jean Delvare * * Original port to Linux 2.6 by Jeff Oliver. * @@ -157,22 +157,35 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; * Functions declaration */ -static int lm87_attach_adapter(struct i2c_adapter *adapter); -static int lm87_detect(struct i2c_adapter *adapter, int address, int kind); +static int lm87_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int lm87_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info); static void lm87_init_client(struct i2c_client *client); -static int lm87_detach_client(struct i2c_client *client); +static int lm87_remove(struct i2c_client *client); static struct lm87_data *lm87_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id lm87_id[] = { + { "lm87", lm87 }, + { "adm1024", adm1024 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm87_id); + static struct i2c_driver lm87_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm87", }, - .attach_adapter = lm87_attach_adapter, - .detach_client = lm87_detach_client, + .probe = lm87_probe, + .remove = lm87_remove, + .id_table = lm87_id, + .detect = lm87_detect, + .address_data = &addr_data, }; /* @@ -180,7 +193,6 @@ static struct i2c_driver lm87_driver = { */ struct lm87_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -562,13 +574,6 @@ static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); * Real code */ -static int lm87_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm87_detect); -} - static struct attribute *lm87_attributes[] = { &dev_attr_in1_input.attr, &dev_attr_in1_min.attr, @@ -656,33 +661,15 @@ static const struct attribute_group lm87_group_opt = { .attrs = lm87_attributes_opt, }; -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm87_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct lm87_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; static const char *names[] = { "lm87", "adm1024" }; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - LM87-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm87_driver; - new_client->flags = 0; + return -ENODEV; /* Default to an LM87 if forced */ if (kind == 0) @@ -704,20 +691,32 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)) { dev_dbg(&adapter->dev, "LM87 detection failed at 0x%02x.\n", - address); - goto exit_free; + new_client->addr); + return -ENODEV; } } - /* We can fill in the remaining client fields */ - strlcpy(new_client->name, names[kind - 1], I2C_NAME_SIZE); + strlcpy(info->type, names[kind - 1], I2C_NAME_SIZE); + + return 0; +} + +static int lm87_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct lm87_data *data; + int err; + + data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Initialize the LM87 chip */ lm87_init_client(new_client); @@ -732,7 +731,7 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group))) - goto exit_detach; + goto exit_free; if (data->channel & CHAN_NO_FAN(0)) { if ((err = device_create_file(&new_client->dev, @@ -832,8 +831,6 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&new_client->dev.kobj, &lm87_group); sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: @@ -877,18 +874,14 @@ static void lm87_init_client(struct i2c_client *client) } } -static int lm87_detach_client(struct i2c_client *client) +static int lm87_remove(struct i2c_client *client) { struct lm87_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm87_group); sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 9b0e85269275159a1f9c3e4a5d254caf5211950b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: hwmon: (lm90) Convert to a new-style i2c driver The new-style lm90 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index d1a3da3..c24fe36 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -187,23 +187,44 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); * Functions declaration */ -static int lm90_attach_adapter(struct i2c_adapter *adapter); -static int lm90_detect(struct i2c_adapter *adapter, int address, - int kind); +static int lm90_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int lm90_probe(struct i2c_client *client, + const struct i2c_device_id *id); static void lm90_init_client(struct i2c_client *client); -static int lm90_detach_client(struct i2c_client *client); +static int lm90_remove(struct i2c_client *client); static struct lm90_data *lm90_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id lm90_id[] = { + { "adm1032", adm1032 }, + { "adt7461", adt7461 }, + { "lm90", lm90 }, + { "lm86", lm86 }, + { "lm89", lm99 }, + { "lm99", lm99 }, /* Missing temperature offset */ + { "max6657", max6657 }, + { "max6658", max6657 }, + { "max6659", max6657 }, + { "max6680", max6680 }, + { "max6681", max6680 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm90_id); + static struct i2c_driver lm90_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm90", }, - .attach_adapter = lm90_attach_adapter, - .detach_client = lm90_detach_client, + .probe = lm90_probe, + .remove = lm90_remove, + .id_table = lm90_id, + .detect = lm90_detect, + .address_data = &addr_data, }; /* @@ -211,7 +232,6 @@ static struct i2c_driver lm90_driver = { */ struct lm90_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -477,40 +497,16 @@ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value) return 0; } -static int lm90_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm90_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm90_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct lm90_data *data; - int err = 0; + struct i2c_adapter *adapter = new_client->adapter; + int address = new_client->addr; const char *name = ""; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - LM90-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm90_driver; - new_client->flags = 0; + return -ENODEV; /* * Now we do the remaining detection. A negative kind means that @@ -538,7 +534,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) LM90_REG_R_CONFIG1)) < 0 || (reg_convrate = i2c_smbus_read_byte_data(new_client, LM90_REG_R_CONVRATE)) < 0) - goto exit_free; + return -ENODEV; if ((address == 0x4C || address == 0x4D) && man_id == 0x01) { /* National Semiconductor */ @@ -546,7 +542,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) if ((reg_config2 = i2c_smbus_read_byte_data(new_client, LM90_REG_R_CONFIG2)) < 0) - goto exit_free; + return -ENODEV; if ((reg_config1 & 0x2A) == 0x00 && (reg_config2 & 0xF8) == 0x00 @@ -610,10 +606,11 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, " "chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } + /* Fill the i2c board info */ if (kind == lm90) { name = "lm90"; } else if (kind == adm1032) { @@ -621,7 +618,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) /* The ADM1032 supports PEC, but only if combined transactions are not used. */ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) - new_client->flags |= I2C_CLIENT_PEC; + info->flags |= I2C_CLIENT_PEC; } else if (kind == lm99) { name = "lm99"; } else if (kind == lm86) { @@ -633,23 +630,39 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) } else if (kind == adt7461) { name = "adt7461"; } + strlcpy(info->type, name, I2C_NAME_SIZE); + + return 0; +} + +static int lm90_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent); + struct lm90_data *data; + int err; - /* We can fill in the remaining client fields */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); - data->valid = 0; - data->kind = kind; + data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + i2c_set_clientdata(new_client, data); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; + /* Set the device type */ + data->kind = id->driver_data; + if (data->kind == adm1032) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) + new_client->flags &= ~I2C_CLIENT_PEC; + } /* Initialize the LM90 chip */ lm90_init_client(new_client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group))) - goto exit_detach; + goto exit_free; if (new_client->flags & I2C_CLIENT_PEC) { if ((err = device_create_file(&new_client->dev, &dev_attr_pec))) @@ -672,8 +685,6 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &lm90_group); device_remove_file(&new_client->dev, &dev_attr_pec); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: @@ -710,10 +721,9 @@ static void lm90_init_client(struct i2c_client *client) i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } -static int lm90_detach_client(struct i2c_client *client) +static int lm90_remove(struct i2c_client *client) { struct lm90_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm90_group); @@ -722,9 +732,6 @@ static int lm90_detach_client(struct i2c_client *client) device_remove_file(&client->dev, &sensor_dev_attr_temp2_offset.dev_attr); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 910e8dcf16dd7afc08dc1791155cc69e07ca4183 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: hwmon: (lm92) Convert to a new-style i2c driver The new-style lm92 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index c31942e..b2e00c5 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -1,6 +1,6 @@ /* * lm92 - Hardware monitoring driver - * Copyright (C) 2005 Jean Delvare + * Copyright (C) 2005-2008 Jean Delvare * * Based on the lm90 driver, with some ideas taken from the lm_sensors * lm92 driver as well. @@ -96,7 +96,6 @@ static struct i2c_driver lm92_driver; /* Client data (each client gets its own) */ struct lm92_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -319,32 +318,15 @@ static const struct attribute_group lm92_group = { .attrs = lm92_attributes, }; -/* The following function does more than just detection. If detection - succeeds, it also registers the new chip. */ -static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm92_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct lm92_data *data; - int err = 0; - char *name; + struct i2c_adapter *adapter = new_client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* Fill in enough client fields so that we can read from the chip, - which is required for identication */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm92_driver; - new_client->flags = 0; + return -ENODEV; /* A negative kind means that the driver was loaded with no force parameter (default), so we must identify the chip. */ @@ -364,34 +346,36 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) kind = lm92; /* No separate prefix */ } else - goto exit_free; - } else - if (kind == 0) /* Default to an LM92 if forced */ - kind = lm92; - - /* Give it the proper name */ - if (kind == lm92) { - name = "lm92"; - } else { /* Supposedly cannot happen */ - dev_dbg(&new_client->dev, "Kind out of range?\n"); - goto exit_free; + return -ENODEV; } - /* Fill in the remaining client fields */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); + strlcpy(info->type, "lm92", I2C_NAME_SIZE); + + return 0; +} + +static int lm92_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct lm92_data *data; + int err; + + data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the i2c subsystem a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Initialize the chipset */ lm92_init_client(new_client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -403,32 +387,19 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&new_client->dev.kobj, &lm92_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: return err; } -static int lm92_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm92_detect); -} - -static int lm92_detach_client(struct i2c_client *client) +static int lm92_remove(struct i2c_client *client) { struct lm92_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm92_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } @@ -438,12 +409,23 @@ static int lm92_detach_client(struct i2c_client *client) * Module and driver stuff */ +static const struct i2c_device_id lm92_id[] = { + { "lm92", lm92 }, + /* max6635 could be added here */ + { } +}; +MODULE_DEVICE_TABLE(i2c, lm92_id); + static struct i2c_driver lm92_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm92", }, - .attach_adapter = lm92_attach_adapter, - .detach_client = lm92_detach_client, + .probe = lm92_probe, + .remove = lm92_remove, + .id_table = lm92_id, + .detect = lm92_detect, + .address_data = &addr_data, }; static int __init sensors_lm92_init(void) -- cgit v0.10.2 From 70b724063f789a443aff1e1a6f0f04d971342116 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: hwmon: (lm93) Convert to a new-style i2c driver The new-style lm93 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Mark M. Hoffman Cc: Eric J. Bowersox Cc: Carsten Emde Cc: Hans J. Koch diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 5e678f5..fc36cad 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -200,7 +200,6 @@ struct block1_t { * Client-specific data */ struct lm93_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; @@ -2501,45 +2500,14 @@ static void lm93_init_client(struct i2c_client *client) "chip to signal ready!\n"); } -static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int lm93_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct lm93_data *data; - struct i2c_client *client; - - int err = -ENODEV, func; - void (*update)(struct lm93_data *, struct i2c_client *); - - /* choose update routine based on bus capabilities */ - func = i2c_get_functionality(adapter); - if ( ((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) && - (!disable_block) ) { - dev_dbg(&adapter->dev,"using SMBus block data transactions\n"); - update = lm93_update_client_full; - } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { - dev_dbg(&adapter->dev,"disabled SMBus block data " - "transactions\n"); - update = lm93_update_client_min; - } else { - dev_dbg(&adapter->dev,"detect failed, " - "smbus byte and/or word data not supported!\n"); - goto err_out; - } + struct i2c_adapter *adapter = client->adapter; - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access lm78_{read,write}_value. */ - - if ( !(data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL))) { - dev_dbg(&adapter->dev,"out of memory!\n"); - err = -ENOMEM; - goto err_out; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &lm93_driver; + if (!i2c_check_functionality(adapter, LM93_SMBUS_FUNC_MIN)) + return -ENODEV; /* detection */ if (kind < 0) { @@ -2548,7 +2516,7 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) if (mfr != 0x01) { dev_dbg(&adapter->dev,"detect failed, " "bad manufacturer id 0x%02x!\n", mfr); - goto err_free; + return -ENODEV; } } @@ -2563,31 +2531,61 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) if (kind == 0) dev_dbg(&adapter->dev, "(ignored 'force' parameter)\n"); - goto err_free; + return -ENODEV; } } - /* fill in remaining client fields */ - strlcpy(client->name, "lm93", I2C_NAME_SIZE); + strlcpy(info->type, "lm93", I2C_NAME_SIZE); dev_dbg(&adapter->dev,"loading %s at %d,0x%02x\n", client->name, i2c_adapter_id(client->adapter), client->addr); + return 0; +} + +static int lm93_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct lm93_data *data; + int err, func; + void (*update)(struct lm93_data *, struct i2c_client *); + + /* choose update routine based on bus capabilities */ + func = i2c_get_functionality(client->adapter); + if (((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) && + (!disable_block)) { + dev_dbg(&client->dev, "using SMBus block data transactions\n"); + update = lm93_update_client_full; + } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { + dev_dbg(&client->dev, "disabled SMBus block data " + "transactions\n"); + update = lm93_update_client_min; + } else { + dev_dbg(&client->dev, "detect failed, " + "smbus byte and/or word data not supported!\n"); + err = -ENODEV; + goto err_out; + } + + data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL); + if (!data) { + dev_dbg(&client->dev, "out of memory!\n"); + err = -ENOMEM; + goto err_out; + } + i2c_set_clientdata(client, data); + /* housekeeping */ data->valid = 0; data->update = update; mutex_init(&data->update_lock); - /* tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto err_free; - /* initialize the chip */ lm93_init_client(client); err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp); if (err) - goto err_detach; + goto err_free; /* Register hwmon driver class */ data->hwmon_dev = hwmon_device_register(&client->dev); @@ -2597,43 +2595,39 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) err = PTR_ERR(data->hwmon_dev); dev_err(&client->dev, "error registering hwmon device.\n"); sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); -err_detach: - i2c_detach_client(client); err_free: kfree(data); err_out: return err; } -/* This function is called when: - * lm93_driver is inserted (when this module is loaded), for each - available adapter - * when a new adapter is inserted (and lm93_driver is still present) */ -static int lm93_attach_adapter(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, lm93_detect); -} - -static int lm93_detach_client(struct i2c_client *client) +static int lm93_remove(struct i2c_client *client) { struct lm93_data *data = i2c_get_clientdata(client); - int err = 0; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); - err = i2c_detach_client(client); - if (!err) - kfree(data); - return err; + kfree(data); + return 0; } +static const struct i2c_device_id lm93_id[] = { + { "lm93", lm93 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm93_id); + static struct i2c_driver lm93_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "lm93", }, - .attach_adapter = lm93_attach_adapter, - .detach_client = lm93_detach_client, + .probe = lm93_probe, + .remove = lm93_remove, + .id_table = lm93_id, + .detect = lm93_detect, + .address_data = &addr_data, }; static int __init lm93_init(void) -- cgit v0.10.2 From c6d3f6fa1b0b984991d6e2a261c7dd7f2685c7bd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:15 +0200 Subject: hwmon: (max1619) Convert to a new-style i2c driver The new-style max1619 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Alexey Fisher diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 7e7267a..1ab1cac 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -79,23 +79,34 @@ I2C_CLIENT_INSMOD_1(max1619); * Functions declaration */ -static int max1619_attach_adapter(struct i2c_adapter *adapter); -static int max1619_detect(struct i2c_adapter *adapter, int address, - int kind); +static int max1619_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int max1619_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static void max1619_init_client(struct i2c_client *client); -static int max1619_detach_client(struct i2c_client *client); +static int max1619_remove(struct i2c_client *client); static struct max1619_data *max1619_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id max1619_id[] = { + { "max1619", max1619 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max1619_id); + static struct i2c_driver max1619_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "max1619", }, - .attach_adapter = max1619_attach_adapter, - .detach_client = max1619_detach_client, + .probe = max1619_probe, + .remove = max1619_remove, + .id_table = max1619_id, + .detect = max1619_detect, + .address_data = &addr_data, }; /* @@ -103,7 +114,6 @@ static struct i2c_driver max1619_driver = { */ struct max1619_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -208,41 +218,15 @@ static const struct attribute_group max1619_group = { * Real code */ -static int max1619_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, max1619_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int max1619_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct max1619_data *data; - int err = 0; - const char *name = ""; + struct i2c_adapter *adapter = new_client->adapter; u8 reg_config=0, reg_convrate=0, reg_status=0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - MAX1619-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &max1619_driver; - new_client->flags = 0; + return -ENODEV; /* * Now we do the remaining detection. A negative kind means that @@ -265,8 +249,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) { dev_dbg(&adapter->dev, "MAX1619 detection failed at 0x%02x.\n", - address); - goto exit_free; + new_client->addr); + return -ENODEV; } } @@ -285,28 +269,37 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, " "chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } - if (kind == max1619) - name = "max1619"; + strlcpy(info->type, "max1619", I2C_NAME_SIZE); + + return 0; +} + +static int max1619_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct max1619_data *data; + int err; + + data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } - /* We can fill in the remaining client fields */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* Initialize the MAX1619 chip */ max1619_init_client(new_client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) - goto exit_detach; + goto exit_free; data->hwmon_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -318,8 +311,6 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove_files: sysfs_remove_group(&new_client->dev.kobj, &max1619_group); -exit_detach: - i2c_detach_client(new_client); exit_free: kfree(data); exit: @@ -341,17 +332,13 @@ static void max1619_init_client(struct i2c_client *client) config & 0xBF); /* run */ } -static int max1619_detach_client(struct i2c_client *client) +static int max1619_remove(struct i2c_client *client) { struct max1619_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &max1619_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; } -- cgit v0.10.2 From 0d57abd5b87e2e82d8d2e8d5c9a3b56743ffa5ab Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:16 +0200 Subject: hwmon: (max6650) Convert to a new-style i2c driver The new-style max6650 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Hans J. Koch diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 52d528b..f27af6a 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -104,22 +104,34 @@ I2C_CLIENT_INSMOD_1(max6650); #define DIV_FROM_REG(reg) (1 << (reg & 7)) -static int max6650_attach_adapter(struct i2c_adapter *adapter); -static int max6650_detect(struct i2c_adapter *adapter, int address, int kind); +static int max6650_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int max6650_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); static int max6650_init_client(struct i2c_client *client); -static int max6650_detach_client(struct i2c_client *client); +static int max6650_remove(struct i2c_client *client); static struct max6650_data *max6650_update_device(struct device *dev); /* * Driver data (common to all clients) */ +static const struct i2c_device_id max6650_id[] = { + { "max6650", max6650 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max6650_id); + static struct i2c_driver max6650_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "max6650", }, - .attach_adapter = max6650_attach_adapter, - .detach_client = max6650_detach_client, + .probe = max6650_probe, + .remove = max6650_remove, + .id_table = max6650_id, + .detect = max6650_detect, + .address_data = &addr_data, }; /* @@ -128,7 +140,6 @@ static struct i2c_driver max6650_driver = { struct max6650_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -437,47 +448,21 @@ static struct attribute_group max6650_attr_grp = { * Real code */ -static int max6650_attach_adapter(struct i2c_adapter *adapter) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int max6650_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) { - dev_dbg(&adapter->dev, - "FATAL: max6650_attach_adapter class HWMON not set\n"); - return 0; - } - - return i2c_probe(adapter, &addr_data, max6650_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ - -static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct max6650_data *data; - int err = -ENODEV; + struct i2c_adapter *adapter = client->adapter; + int address = client->addr; dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " "byte read mode, skipping.\n"); - return 0; - } - - if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { - dev_err(&adapter->dev, "max6650: out of memory.\n"); - return -ENOMEM; + return -ENODEV; } - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &max6650_driver; - /* * Now we do the remaining detection. A negative kind means that * the driver was loaded with no force parameter (default), so we @@ -501,28 +486,40 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { dev_dbg(&adapter->dev, "max6650: detection failed at 0x%02x.\n", address); - goto err_free; + return -ENODEV; } dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); - strlcpy(client->name, "max6650", I2C_NAME_SIZE); - mutex_init(&data->update_lock); + strlcpy(info->type, "max6650", I2C_NAME_SIZE); - if ((err = i2c_attach_client(client))) { - dev_err(&adapter->dev, "max6650: failed to attach client.\n"); - goto err_free; + return 0; +} + +static int max6650_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max6650_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { + dev_err(&client->dev, "out of memory.\n"); + return -ENOMEM; } + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + /* * Initialize the max6650 chip */ - if (max6650_init_client(client)) - goto err_detach; + err = max6650_init_client(client); + if (err) + goto err_free; err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); if (err) - goto err_detach; + goto err_free; data->hwmon_dev = hwmon_device_register(&client->dev); if (!IS_ERR(data->hwmon_dev)) @@ -531,24 +528,19 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) err = PTR_ERR(data->hwmon_dev); dev_err(&client->dev, "error registering hwmon device.\n"); sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); -err_detach: - i2c_detach_client(client); err_free: kfree(data); return err; } -static int max6650_detach_client(struct i2c_client *client) +static int max6650_remove(struct i2c_client *client) { struct max6650_data *data = i2c_get_clientdata(client); - int err; sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); hwmon_device_unregister(data->hwmon_dev); - err = i2c_detach_client(client); - if (!err) - kfree(data); - return err; + kfree(data); + return 0; } static int max6650_init_client(struct i2c_client *client) -- cgit v0.10.2 From 8fb597bb6ec80d53836229bf3576c7b848b909e3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:16 +0200 Subject: hwmon: (smsc47m192) Convert to a new-style i2c driver The new-style smsc47m192 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Hartmut Rick diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 3c9db65..8bb5cb5 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -96,7 +96,6 @@ static inline int TEMP_FROM_REG(s8 val) } struct smsc47m192_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -114,18 +113,29 @@ struct smsc47m192_data { u8 vrm; }; -static int smsc47m192_attach_adapter(struct i2c_adapter *adapter); -static int smsc47m192_detect(struct i2c_adapter *adapter, int address, - int kind); -static int smsc47m192_detach_client(struct i2c_client *client); +static int smsc47m192_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int smsc47m192_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int smsc47m192_remove(struct i2c_client *client); static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); +static const struct i2c_device_id smsc47m192_id[] = { + { "smsc47m192", smsc47m192 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, smsc47m192_id); + static struct i2c_driver smsc47m192_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "smsc47m192", }, - .attach_adapter = smsc47m192_attach_adapter, - .detach_client = smsc47m192_detach_client, + .probe = smsc47m192_probe, + .remove = smsc47m192_remove, + .id_table = smsc47m192_id, + .detect = smsc47m192_detect, + .address_data = &addr_data, }; /* Voltages */ @@ -440,17 +450,6 @@ static const struct attribute_group smsc47m192_group_in4 = { .attrs = smsc47m192_attributes_in4, }; -/* This function is called when: - * smsc47m192_driver is inserted (when this module is loaded), for each - available adapter - * when a new adapter is inserted (and smsc47m192_driver is still present) */ -static int smsc47m192_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, smsc47m192_detect); -} - static void smsc47m192_init_client(struct i2c_client *client) { int i; @@ -481,31 +480,15 @@ static void smsc47m192_init_client(struct i2c_client *client) } } -/* This function is called by i2c_probe */ -static int smsc47m192_detect(struct i2c_adapter *adapter, int address, - int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int smsc47m192_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct smsc47m192_data *data; - int err = 0; - int version, config; + struct i2c_adapter *adapter = client->adapter; + int version; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &smsc47m192_driver; - - if (kind == 0) - kind = smsc47m192; + return -ENODEV; /* Detection criteria from sensors_detect script */ if (kind < 0) { @@ -523,26 +506,39 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, } else { dev_dbg(&adapter->dev, "SMSC47M192 detection failed at 0x%02x\n", - address); - goto exit_free; + client->addr); + return -ENODEV; } } - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); + strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE); + + return 0; +} + +static int smsc47m192_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct smsc47m192_data *data; + int config; + int err; + + data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); data->vrm = vid_which_vrm(); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; - /* Initialize the SMSC47M192 chip */ smsc47m192_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group))) - goto exit_detach; + goto exit_free; /* Pin 110 is either in4 (+12V) or VID4 */ config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); @@ -563,26 +559,20 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, exit_remove_files: sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int smsc47m192_detach_client(struct i2c_client *client) +static int smsc47m192_remove(struct i2c_client *client) { struct smsc47m192_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; -- cgit v0.10.2 From ccf37488322429bf8709f2227f3d48466add2b6b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:16 +0200 Subject: hwmon: (thmc50) Convert to a new-style i2c driver The new-style thmc50 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Krzysztof Helt diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 76a3859..3b01001 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -60,7 +60,6 @@ static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; /* Each client has this additional data */ struct thmc50_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; @@ -77,17 +76,31 @@ struct thmc50_data { u8 alarms; }; -static int thmc50_attach_adapter(struct i2c_adapter *adapter); -static int thmc50_detach_client(struct i2c_client *client); +static int thmc50_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int thmc50_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int thmc50_remove(struct i2c_client *client); static void thmc50_init_client(struct i2c_client *client); static struct thmc50_data *thmc50_update_device(struct device *dev); +static const struct i2c_device_id thmc50_id[] = { + { "adm1022", adm1022 }, + { "thmc50", thmc50 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, thmc50_id); + static struct i2c_driver thmc50_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "thmc50", }, - .attach_adapter = thmc50_attach_adapter, - .detach_client = thmc50_detach_client, + .probe = thmc50_probe, + .remove = thmc50_remove, + .id_table = thmc50_id, + .detect = thmc50_detect, + .address_data = &addr_data, }; static ssize_t show_analog_out(struct device *dev, @@ -250,39 +263,23 @@ static const struct attribute_group temp3_group = { .attrs = temp3_attributes, }; -static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int thmc50_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { unsigned company; unsigned revision; unsigned config; - struct i2c_client *client; - struct thmc50_data *data; - struct device *dev; + struct i2c_adapter *adapter = client->adapter; int err = 0; const char *type_name; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { pr_debug("thmc50: detect failed, " "smbus byte data not supported!\n"); - goto exit; - } - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access thmc50 registers. */ - if (!(data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL))) { - pr_debug("thmc50: detect failed, kzalloc failed!\n"); - err = -ENOMEM; - goto exit; + return -ENODEV; } - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &thmc50_driver; - dev = &client->dev; - pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n", client->addr, i2c_adapter_id(client->adapter)); @@ -307,21 +304,22 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) } if (err == -ENODEV) { pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n"); - goto exit_free; + return err; } - data->type = kind; if (kind == adm1022) { int id = i2c_adapter_id(client->adapter); int i; type_name = "adm1022"; - data->has_temp3 = (config >> 7) & 1; /* config MSB */ for (i = 0; i + 1 < adm1022_temp3_num; i += 2) if (adm1022_temp3[i] == id && - adm1022_temp3[i + 1] == address) { + adm1022_temp3[i + 1] == client->addr) { /* enable 2nd remote temp */ - data->has_temp3 = 1; + config |= (1 << 7); + i2c_smbus_write_byte_data(client, + THMC50_REG_CONF, + config); break; } } else { @@ -330,19 +328,33 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind) pr_debug("thmc50: Detected %s (version %x, revision %x)\n", type_name, (revision >> 4) - 0xc, revision & 0xf); - /* Fill in the remaining client fields & put it into the global list */ - strlcpy(client->name, type_name, I2C_NAME_SIZE); - mutex_init(&data->update_lock); + strlcpy(info->type, type_name, I2C_NAME_SIZE); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; + return 0; +} + +static int thmc50_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct thmc50_data *data; + int err; + + data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL); + if (!data) { + pr_debug("thmc50: detect failed, kzalloc failed!\n"); + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->type = id->driver_data; + mutex_init(&data->update_lock); thmc50_init_client(client); /* Register sysfs hooks */ if ((err = sysfs_create_group(&client->dev.kobj, &thmc50_group))) - goto exit_detach; + goto exit_free; /* Register ADM1022 sysfs hooks */ if (data->has_temp3) @@ -364,34 +376,21 @@ exit_remove_sysfs: sysfs_remove_group(&client->dev.kobj, &temp3_group); exit_remove_sysfs_thmc50: sysfs_remove_group(&client->dev.kobj, &thmc50_group); -exit_detach: - i2c_detach_client(client); exit_free: kfree(data); exit: return err; } -static int thmc50_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, thmc50_detect); -} - -static int thmc50_detach_client(struct i2c_client *client) +static int thmc50_remove(struct i2c_client *client) { struct thmc50_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &thmc50_group); if (data->has_temp3) sysfs_remove_group(&client->dev.kobj, &temp3_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; @@ -412,8 +411,8 @@ static void thmc50_init_client(struct i2c_client *client) } config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF); config |= 0x1; /* start the chip if it is in standby mode */ - if (data->has_temp3) - config |= 0x80; /* enable 2nd remote temp */ + if (data->type == adm1022 && (config & (1 << 7))) + data->has_temp3 = 1; i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config); } -- cgit v0.10.2 From cb0c1af37996f3016e34e9c709e5f727646f7207 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:17 +0200 Subject: hwmon: (w83791d) Convert to a new-style i2c driver The new-style w83791d driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Marc Hulsman diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 85077c4..e4e91c9 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -247,7 +247,6 @@ static u8 div_to_reg(int nr, long val) } struct w83791d_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; @@ -286,9 +285,11 @@ struct w83791d_data { u8 vrm; /* hwmon-vid */ }; -static int w83791d_attach_adapter(struct i2c_adapter *adapter); -static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind); -static int w83791d_detach_client(struct i2c_client *client); +static int w83791d_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int w83791d_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int w83791d_remove(struct i2c_client *client); static int w83791d_read(struct i2c_client *client, u8 register); static int w83791d_write(struct i2c_client *client, u8 register, u8 value); @@ -300,12 +301,22 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev); static void w83791d_init_client(struct i2c_client *client); +static const struct i2c_device_id w83791d_id[] = { + { "w83791d", w83791d }, + { } +}; +MODULE_DEVICE_TABLE(i2c, w83791d_id); + static struct i2c_driver w83791d_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "w83791d", }, - .attach_adapter = w83791d_attach_adapter, - .detach_client = w83791d_detach_client, + .probe = w83791d_probe, + .remove = w83791d_remove, + .id_table = w83791d_id, + .detect = w83791d_detect, + .address_data = &addr_data, }; /* following are the sysfs callback functions */ @@ -905,49 +916,12 @@ static const struct attribute_group w83791d_group = { .attrs = w83791d_attributes, }; -/* This function is called when: - * w83791d_driver is inserted (when this module is loaded), for each - available adapter - * when a new adapter is inserted (and w83791d_driver is still present) */ -static int w83791d_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, w83791d_detect); -} - -static int w83791d_create_subclient(struct i2c_adapter *adapter, - struct i2c_client *client, int addr, - struct i2c_client **sub_cli) -{ - int err; - struct i2c_client *sub_client; - - (*sub_cli) = sub_client = - kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!(sub_client)) { - return -ENOMEM; - } - sub_client->addr = 0x48 + addr; - i2c_set_clientdata(sub_client, NULL); - sub_client->adapter = adapter; - sub_client->driver = &w83791d_driver; - strlcpy(sub_client->name, "w83791d subclient", I2C_NAME_SIZE); - if ((err = i2c_attach_client(sub_client))) { - dev_err(&client->dev, "subclient registration " - "at address 0x%x failed\n", sub_client->addr); - kfree(sub_client); - return err; - } - return 0; -} - - -static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address, - int kind, struct i2c_client *client) +static int w83791d_detect_subclients(struct i2c_client *client) { + struct i2c_adapter *adapter = client->adapter; struct w83791d_data *data = i2c_get_clientdata(client); + int address = client->addr; int i, id, err; u8 val; @@ -971,10 +945,7 @@ static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address, val = w83791d_read(client, W83791D_REG_I2C_SUBADDR); if (!(val & 0x08)) { - err = w83791d_create_subclient(adapter, client, - val & 0x7, &data->lm75[0]); - if (err < 0) - goto error_sc_0; + data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7)); } if (!(val & 0x80)) { if ((data->lm75[0] != NULL) && @@ -986,10 +957,8 @@ static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address, err = -ENODEV; goto error_sc_1; } - err = w83791d_create_subclient(adapter, client, - (val >> 4) & 0x7, &data->lm75[1]); - if (err < 0) - goto error_sc_1; + data->lm75[1] = i2c_new_dummy(adapter, + 0x48 + ((val >> 4) & 0x7)); } return 0; @@ -997,53 +966,31 @@ static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address, /* Undo inits in case of errors */ error_sc_1: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); error_sc_0: return err; } -static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int w83791d_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - struct i2c_client *client; - struct device *dev; - struct w83791d_data *data; - int i, val1, val2; - int err = 0; - const char *client_name = ""; + struct i2c_adapter *adapter = client->adapter; + int val1, val2; + unsigned short address = client->addr; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - goto error0; + return -ENODEV; } - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access w83791d_{read,write}_value. */ - if (!(data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL))) { - err = -ENOMEM; - goto error0; - } - - client = &data->client; - dev = &client->dev; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &w83791d_driver; - mutex_init(&data->update_lock); - - /* Now, we do the remaining detection. */ - /* The w83791d may be stuck in some other bank than bank 0. This may make reading other information impossible. Specify a force=... parameter, and the Winbond will be reset to the right bank. */ if (kind < 0) { if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) { - dev_dbg(dev, "Detection failed at step 1\n"); - goto error1; + return -ENODEV; } val1 = w83791d_read(client, W83791D_REG_BANK); val2 = w83791d_read(client, W83791D_REG_CHIPMAN); @@ -1052,15 +999,13 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) /* yes it is Bank0 */ if (((!(val1 & 0x80)) && (val2 != 0xa3)) || ((val1 & 0x80) && (val2 != 0x5c))) { - dev_dbg(dev, "Detection failed at step 2\n"); - goto error1; + return -ENODEV; } } /* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR should match */ if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) { - dev_dbg(dev, "Detection failed at step 3\n"); - goto error1; + return -ENODEV; } } @@ -1075,30 +1020,33 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) /* get vendor ID */ val2 = w83791d_read(client, W83791D_REG_CHIPMAN); if (val2 != 0x5c) { /* the vendor is NOT Winbond */ - dev_dbg(dev, "Detection failed at step 4\n"); - goto error1; + return -ENODEV; } val1 = w83791d_read(client, W83791D_REG_WCHIPID); if (val1 == 0x71) { kind = w83791d; } else { if (kind == 0) - dev_warn(dev, + dev_warn(&adapter->dev, "w83791d: Ignoring 'force' parameter " "for unknown chip at adapter %d, " "address 0x%02x\n", i2c_adapter_id(adapter), address); - goto error1; + return -ENODEV; } } - if (kind == w83791d) { - client_name = "w83791d"; - } else { - dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n", - kind); - goto error1; - } + strlcpy(info->type, "w83791d", I2C_NAME_SIZE); + + return 0; +} + +static int w83791d_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct w83791d_data *data; + struct device *dev = &client->dev; + int i, val1, err; #ifdef DEBUG val1 = w83791d_read(client, W83791D_REG_DID_VID4); @@ -1106,15 +1054,18 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); #endif - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, client_name, I2C_NAME_SIZE); + data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto error0; + } - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto error1; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); - if ((err = w83791d_detect_subclients(adapter, address, kind, client))) - goto error2; + err = w83791d_detect_subclients(client); + if (err) + goto error1; /* Initialize the chip */ w83791d_init_client(client); @@ -1141,43 +1092,29 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) error4: sysfs_remove_group(&client->dev.kobj, &w83791d_group); error3: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } - if (data->lm75[1] != NULL) { - i2c_detach_client(data->lm75[1]); - kfree(data->lm75[1]); - } -error2: - i2c_detach_client(client); + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); + if (data->lm75[1] != NULL) + i2c_unregister_device(data->lm75[1]); error1: kfree(data); error0: return err; } -static int w83791d_detach_client(struct i2c_client *client) +static int w83791d_remove(struct i2c_client *client) { struct w83791d_data *data = i2c_get_clientdata(client); - int err; - - /* main client */ - if (data) { - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &w83791d_group); - } - if ((err = i2c_detach_client(client))) - return err; + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &w83791d_group); - /* main client */ - if (data) - kfree(data); - /* subclient */ - else - kfree(client); + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); + if (data->lm75[1] != NULL) + i2c_unregister_device(data->lm75[1]); + kfree(data); return 0; } -- cgit v0.10.2 From 31d5d275a118527a2b9b0f68613428f176efbb8f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:17 +0200 Subject: hwmon: (w83792d) Convert to a new-style i2c driver The new-style w83792d driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 299629d..cf94c5b 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -267,9 +267,7 @@ DIV_TO_REG(long val) } struct w83792d_data { - struct i2c_client client; struct device *hwmon_dev; - enum chips type; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -299,9 +297,11 @@ struct w83792d_data { u8 sf2_levels[3][4]; /* Smart FanII: Fan1,2,3 duty cycle levels */ }; -static int w83792d_attach_adapter(struct i2c_adapter *adapter); -static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); -static int w83792d_detach_client(struct i2c_client *client); +static int w83792d_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int w83792d_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int w83792d_remove(struct i2c_client *client); static struct w83792d_data *w83792d_update_device(struct device *dev); #ifdef DEBUG @@ -310,12 +310,22 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev); static void w83792d_init_client(struct i2c_client *client); +static const struct i2c_device_id w83792d_id[] = { + { "w83792d", w83792d }, + { } +}; +MODULE_DEVICE_TABLE(i2c, w83792d_id); + static struct i2c_driver w83792d_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "w83792d", }, - .attach_adapter = w83792d_attach_adapter, - .detach_client = w83792d_detach_client, + .probe = w83792d_probe, + .remove = w83792d_remove, + .id_table = w83792d_id, + .detect = w83792d_detect, + .address_data = &addr_data, }; static inline long in_count_from_reg(int nr, struct w83792d_data *data) @@ -864,53 +874,14 @@ store_sf2_level(struct device *dev, struct device_attribute *attr, return count; } -/* This function is called when: - * w83792d_driver is inserted (when this module is loaded), for each - available adapter - * when a new adapter is inserted (and w83792d_driver is still present) */ -static int -w83792d_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, w83792d_detect); -} - - -static int -w83792d_create_subclient(struct i2c_adapter *adapter, - struct i2c_client *new_client, int addr, - struct i2c_client **sub_cli) -{ - int err; - struct i2c_client *sub_client; - - (*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!(sub_client)) { - return -ENOMEM; - } - sub_client->addr = 0x48 + addr; - i2c_set_clientdata(sub_client, NULL); - sub_client->adapter = adapter; - sub_client->driver = &w83792d_driver; - sub_client->flags = 0; - strlcpy(sub_client->name, "w83792d subclient", I2C_NAME_SIZE); - if ((err = i2c_attach_client(sub_client))) { - dev_err(&new_client->dev, "subclient registration " - "at address 0x%x failed\n", sub_client->addr); - kfree(sub_client); - return err; - } - return 0; -} - static int -w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, - struct i2c_client *new_client) +w83792d_detect_subclients(struct i2c_client *new_client) { int i, id, err; + int address = new_client->addr; u8 val; + struct i2c_adapter *adapter = new_client->adapter; struct w83792d_data *data = i2c_get_clientdata(new_client); id = i2c_adapter_id(adapter); @@ -932,10 +903,7 @@ w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR); if (!(val & 0x08)) { - err = w83792d_create_subclient(adapter, new_client, val & 0x7, - &data->lm75[0]); - if (err < 0) - goto ERROR_SC_0; + data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7)); } if (!(val & 0x80)) { if ((data->lm75[0] != NULL) && @@ -945,10 +913,8 @@ w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, err = -ENODEV; goto ERROR_SC_1; } - err = w83792d_create_subclient(adapter, new_client, - (val >> 4) & 0x7, &data->lm75[1]); - if (err < 0) - goto ERROR_SC_1; + data->lm75[1] = i2c_new_dummy(adapter, + 0x48 + ((val >> 4) & 0x7)); } return 0; @@ -956,10 +922,8 @@ w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, /* Undo inits in case of errors */ ERROR_SC_1: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); ERROR_SC_0: return err; } @@ -1294,47 +1258,25 @@ static const struct attribute_group w83792d_group = { .attrs = w83792d_attributes, }; +/* Return 0 if detection is successful, -ENODEV otherwise */ static int -w83792d_detect(struct i2c_adapter *adapter, int address, int kind) +w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) { - int i = 0, val1 = 0, val2; - struct i2c_client *client; - struct device *dev; - struct w83792d_data *data; - int err = 0; - const char *client_name = ""; + struct i2c_adapter *adapter = client->adapter; + int val1, val2; + unsigned short address = client->addr; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - goto ERROR0; - } - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access w83792d_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) { - err = -ENOMEM; - goto ERROR0; + return -ENODEV; } - client = &data->client; - dev = &client->dev; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &w83792d_driver; - client->flags = 0; - - /* Now, we do the remaining detection. */ - /* The w83792d may be stuck in some other bank than bank 0. This may make reading other information impossible. Specify a force=... or force_*=... parameter, and the Winbond will be reset to the right bank. */ if (kind < 0) { if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) { - dev_dbg(dev, "Detection failed at step 1\n"); - goto ERROR1; + return -ENODEV; } val1 = w83792d_read_value(client, W83792D_REG_BANK); val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); @@ -1342,16 +1284,14 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) if (!(val1 & 0x07)) { /* is Bank0 */ if (((!(val1 & 0x80)) && (val2 != 0xa3)) || ((val1 & 0x80) && (val2 != 0x5c))) { - dev_dbg(dev, "Detection failed at step 2\n"); - goto ERROR1; + return -ENODEV; } } /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR should match */ if (w83792d_read_value(client, W83792D_REG_I2C_ADDR) != address) { - dev_dbg(dev, "Detection failed at step 3\n"); - goto ERROR1; + return -ENODEV; } } @@ -1367,45 +1307,48 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) /* get vendor ID */ val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN); if (val2 != 0x5c) { /* the vendor is NOT Winbond */ - goto ERROR1; + return -ENODEV; } val1 = w83792d_read_value(client, W83792D_REG_WCHIPID); if (val1 == 0x7a) { kind = w83792d; } else { if (kind == 0) - dev_warn(dev, + dev_warn(&adapter->dev, "w83792d: Ignoring 'force' parameter for" " unknown chip at adapter %d, address" " 0x%02x\n", i2c_adapter_id(adapter), address); - goto ERROR1; + return -ENODEV; } } - if (kind == w83792d) { - client_name = "w83792d"; - } else { - dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n", - kind); - goto ERROR1; - } + strlcpy(info->type, "w83792d", I2C_NAME_SIZE); + + return 0; +} + +static int +w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct w83792d_data *data; + struct device *dev = &client->dev; + int i, val1, err; - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, client_name, I2C_NAME_SIZE); - data->type = kind; + data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto ERROR0; + } + i2c_set_clientdata(client, data); data->valid = 0; mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) + err = w83792d_detect_subclients(client); + if (err) goto ERROR1; - if ((err = w83792d_detect_subclients(adapter, address, - kind, client))) - goto ERROR2; - /* Initialize the chip */ w83792d_init_client(client); @@ -1457,16 +1400,10 @@ exit_remove_files: for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]); ERROR3: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } - if (data->lm75[1] != NULL) { - i2c_detach_client(data->lm75[1]); - kfree(data->lm75[1]); - } -ERROR2: - i2c_detach_client(client); + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); + if (data->lm75[1] != NULL) + i2c_unregister_device(data->lm75[1]); ERROR1: kfree(data); ERROR0: @@ -1474,30 +1411,23 @@ ERROR0: } static int -w83792d_detach_client(struct i2c_client *client) +w83792d_remove(struct i2c_client *client) { struct w83792d_data *data = i2c_get_clientdata(client); - int err, i; - - /* main client */ - if (data) { - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &w83792d_group); - for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) - sysfs_remove_group(&client->dev.kobj, - &w83792d_group_fan[i]); - } + int i; - if ((err = i2c_detach_client(client))) - return err; + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &w83792d_group); + for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) + sysfs_remove_group(&client->dev.kobj, + &w83792d_group_fan[i]); - /* main client */ - if (data) - kfree(data); - /* subclient */ - else - kfree(client); + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); + if (data->lm75[1] != NULL) + i2c_unregister_device(data->lm75[1]); + kfree(data); return 0; } -- cgit v0.10.2 From a7f13a6ec40379fe2116c647ac8e569227ba8d4f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:17 +0200 Subject: hwmon: (w83793) Convert to a new-style i2c driver The new-style w83793 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index ed3c019..0a739f1 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -179,7 +179,6 @@ static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) } struct w83793_data { - struct i2c_client client; struct i2c_client *lm75[2]; struct device *hwmon_dev; struct mutex update_lock; @@ -226,19 +225,31 @@ struct w83793_data { static u8 w83793_read_value(struct i2c_client *client, u16 reg); static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); -static int w83793_attach_adapter(struct i2c_adapter *adapter); -static int w83793_detect(struct i2c_adapter *adapter, int address, int kind); -static int w83793_detach_client(struct i2c_client *client); +static int w83793_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int w83793_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int w83793_remove(struct i2c_client *client); static void w83793_init_client(struct i2c_client *client); static void w83793_update_nonvolatile(struct device *dev); static struct w83793_data *w83793_update_device(struct device *dev); +static const struct i2c_device_id w83793_id[] = { + { "w83793", w83793 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, w83793_id); + static struct i2c_driver w83793_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "w83793", }, - .attach_adapter = w83793_attach_adapter, - .detach_client = w83793_detach_client, + .probe = w83793_probe, + .remove = w83793_remove, + .id_table = w83793_id, + .detect = w83793_detect, + .address_data = &addr_data, }; static ssize_t @@ -1053,89 +1064,51 @@ static void w83793_init_client(struct i2c_client *client) } -static int w83793_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, w83793_detect); -} - -static int w83793_detach_client(struct i2c_client *client) +static int w83793_remove(struct i2c_client *client) { struct w83793_data *data = i2c_get_clientdata(client); struct device *dev = &client->dev; - int err, i; + int i; - /* main client */ - if (data) { - hwmon_device_unregister(data->hwmon_dev); + hwmon_device_unregister(data->hwmon_dev); - for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) - device_remove_file(dev, - &w83793_sensor_attr_2[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) + device_remove_file(dev, + &w83793_sensor_attr_2[i].dev_attr); - for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) - device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) + device_remove_file(dev, &sda_single_files[i].dev_attr); - for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) - device_remove_file(dev, &w83793_vid[i].dev_attr); - device_remove_file(dev, &dev_attr_vrm); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + device_remove_file(dev, &dev_attr_vrm); - for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) - device_remove_file(dev, &w83793_left_fan[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) + device_remove_file(dev, &w83793_left_fan[i].dev_attr); - for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) - device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) + device_remove_file(dev, &w83793_left_pwm[i].dev_attr); - for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) - device_remove_file(dev, &w83793_temp[i].dev_attr); - } + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); - if ((err = i2c_detach_client(client))) - return err; + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); + if (data->lm75[1] != NULL) + i2c_unregister_device(data->lm75[1]); - /* main client */ - if (data) - kfree(data); - /* subclient */ - else - kfree(client); + kfree(data); return 0; } static int -w83793_create_subclient(struct i2c_adapter *adapter, - struct i2c_client *client, int addr, - struct i2c_client **sub_cli) -{ - int err = 0; - struct i2c_client *sub_client; - - (*sub_cli) = sub_client = - kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!(sub_client)) { - return -ENOMEM; - } - sub_client->addr = 0x48 + addr; - i2c_set_clientdata(sub_client, NULL); - sub_client->adapter = adapter; - sub_client->driver = &w83793_driver; - strlcpy(sub_client->name, "w83793 subclient", I2C_NAME_SIZE); - if ((err = i2c_attach_client(sub_client))) { - dev_err(&client->dev, "subclient registration " - "at address 0x%x failed\n", sub_client->addr); - kfree(sub_client); - } - return err; -} - -static int -w83793_detect_subclients(struct i2c_adapter *adapter, int address, - int kind, struct i2c_client *client) +w83793_detect_subclients(struct i2c_client *client) { int i, id, err; + int address = client->addr; u8 tmp; + struct i2c_adapter *adapter = client->adapter; struct w83793_data *data = i2c_get_clientdata(client); id = i2c_adapter_id(adapter); @@ -1158,11 +1131,7 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address, tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); if (!(tmp & 0x08)) { - err = - w83793_create_subclient(adapter, client, tmp & 0x7, - &data->lm75[0]); - if (err < 0) - goto ERROR_SC_0; + data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7)); } if (!(tmp & 0x80)) { if ((data->lm75[0] != NULL) @@ -1173,10 +1142,8 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address, err = -ENODEV; goto ERROR_SC_1; } - err = w83793_create_subclient(adapter, client, - (tmp >> 4) & 0x7, &data->lm75[1]); - if (err < 0) - goto ERROR_SC_1; + data->lm75[1] = i2c_new_dummy(adapter, + 0x48 + ((tmp >> 4) & 0x7)); } return 0; @@ -1184,69 +1151,44 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address, /* Undo inits in case of errors */ ERROR_SC_1: - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); ERROR_SC_0: return err; } -static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int w83793_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - int i; - u8 tmp, val; - struct i2c_client *client; - struct device *dev; - struct w83793_data *data; - int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; - int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; - int files_temp = ARRAY_SIZE(w83793_temp) / 6; - int err = 0; + u8 tmp, bank; + struct i2c_adapter *adapter = client->adapter; + unsigned short address = client->addr; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - goto exit; + return -ENODEV; } - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access w83793_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - dev = &client->dev; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &w83793_driver; + bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); - data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); - - /* Now, we do the remaining detection. */ if (kind < 0) { - tmp = data->bank & 0x80 ? 0x5c : 0xa3; + tmp = bank & 0x80 ? 0x5c : 0xa3; /* Check Winbond vendor ID */ if (tmp != i2c_smbus_read_byte_data(client, W83793_REG_VENDORID)) { pr_debug("w83793: Detection failed at check " "vendor id\n"); - err = -ENODEV; - goto free_mem; + return -ENODEV; } /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR should match */ - if ((data->bank & 0x07) == 0 + if ((bank & 0x07) == 0 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != (address << 1)) { pr_debug("w83793: Detection failed at check " "i2c addr\n"); - err = -ENODEV; - goto free_mem; + return -ENODEV; } } @@ -1255,30 +1197,47 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) Winbond. Determine the chip type now */ if (kind <= 0) { - if (0x7b == w83793_read_value(client, W83793_REG_CHIPID)) { + if (0x7b == i2c_smbus_read_byte_data(client, + W83793_REG_CHIPID)) { kind = w83793; } else { if (kind == 0) dev_warn(&adapter->dev, "w83793: Ignoring " "'force' parameter for unknown chip " "at address 0x%02x\n", address); - err = -ENODEV; - goto free_mem; + return -ENODEV; } } - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, "w83793", I2C_NAME_SIZE); + strlcpy(info->type, "w83793", I2C_NAME_SIZE); + + return 0; +} +static int w83793_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct w83793_data *data; + int i, tmp, val, err; + int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; + int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; + int files_temp = ARRAY_SIZE(w83793_temp) / 6; + + data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); mutex_init(&data->update_lock); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) + err = w83793_detect_subclients(client); + if (err) goto free_mem; - if ((err = w83793_detect_subclients(adapter, address, kind, client))) - goto detach_client; - /* Initialize the chip */ w83793_init_client(client); @@ -1459,16 +1418,10 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) device_remove_file(dev, &w83793_temp[i].dev_attr); - if (data->lm75[0] != NULL) { - i2c_detach_client(data->lm75[0]); - kfree(data->lm75[0]); - } - if (data->lm75[1] != NULL) { - i2c_detach_client(data->lm75[1]); - kfree(data->lm75[1]); - } -detach_client: - i2c_detach_client(client); + if (data->lm75[0] != NULL) + i2c_unregister_device(data->lm75[0]); + if (data->lm75[1] != NULL) + i2c_unregister_device(data->lm75[1]); free_mem: kfree(data); exit: -- cgit v0.10.2 From dc18a4184d6794e2e5c6f05142f3f8aaeeaee506 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:18 +0200 Subject: hwmon: (w83l785ts) Convert to a new-style i2c driver The new-style w83l785ts driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 52e268e..ea295b9 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -81,10 +81,11 @@ I2C_CLIENT_INSMOD_1(w83l785ts); * Functions declaration */ -static int w83l785ts_attach_adapter(struct i2c_adapter *adapter); -static int w83l785ts_detect(struct i2c_adapter *adapter, int address, - int kind); -static int w83l785ts_detach_client(struct i2c_client *client); +static int w83l785ts_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int w83l785ts_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int w83l785ts_remove(struct i2c_client *client); static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval); static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); @@ -92,12 +93,22 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); * Driver data (common to all clients) */ +static const struct i2c_device_id w83l785ts_id[] = { + { "w83l785ts", w83l785ts }, + { } +}; +MODULE_DEVICE_TABLE(i2c, w83l785ts_id); + static struct i2c_driver w83l785ts_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "w83l785ts", }, - .attach_adapter = w83l785ts_attach_adapter, - .detach_client = w83l785ts_detach_client, + .probe = w83l785ts_probe, + .remove = w83l785ts_remove, + .id_table = w83l785ts_id, + .detect = w83l785ts_detect, + .address_data = &addr_data, }; /* @@ -105,7 +116,6 @@ static struct i2c_driver w83l785ts_driver = { */ struct w83l785ts_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* zero until following fields are valid */ @@ -135,40 +145,14 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1); * Real code */ -static int w83l785ts_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, w83l785ts_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int w83l785ts_detect(struct i2c_client *new_client, int kind, + struct i2c_board_info *info) { - struct i2c_client *new_client; - struct w83l785ts_data *data; - int err = 0; - + struct i2c_adapter *adapter = new_client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - * W83L785TS-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &w83l785ts_driver; - new_client->flags = 0; + return -ENODEV; /* * Now we do the remaining detection. A negative kind means that @@ -188,8 +172,8 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) { dev_dbg(&adapter->dev, "W83L785TS-S detection failed at 0x%02x.\n", - address); - goto exit_free; + new_client->addr); + return -ENODEV; } } @@ -214,22 +198,34 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Unsupported chip (man_id=0x%04X, " "chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } - /* We can fill in the remaining client fields. */ - strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE); + strlcpy(info->type, "w83l785ts", I2C_NAME_SIZE); + + return 0; +} + +static int w83l785ts_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct w83l785ts_data *data; + int err = 0; + + data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(new_client, data); data->valid = 0; mutex_init(&data->update_lock); /* Default values in case the first read fails (unlikely). */ data->temp[1] = data->temp[0] = 0; - /* Tell the I2C layer a new client has arrived. */ - if ((err = i2c_attach_client(new_client))) - goto exit_free; - /* * Initialize the W83L785TS chip * Nothing yet, assume it is already started. @@ -259,25 +255,20 @@ exit_remove: &sensor_dev_attr_temp1_input.dev_attr); device_remove_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); - i2c_detach_client(new_client); -exit_free: kfree(data); exit: return err; } -static int w83l785ts_detach_client(struct i2c_client *client) +static int w83l785ts_remove(struct i2c_client *client) { struct w83l785ts_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); device_remove_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); device_remove_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); - if ((err = i2c_detach_client(client))) - return err; kfree(data); return 0; @@ -286,6 +277,18 @@ static int w83l785ts_detach_client(struct i2c_client *client) static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) { int value, i; + struct device *dev; + const char *prefix; + + /* We might be called during detection, at which point the client + isn't yet fully initialized, so we can't use dev_dbg on it */ + if (i2c_get_clientdata(client)) { + dev = &client->dev; + prefix = ""; + } else { + dev = &client->adapter->dev; + prefix = "w83l785ts: "; + } /* Frequent read errors have been reported on Asus boards, so we * retry on read errors. If it still fails (unlikely), return the @@ -293,15 +296,15 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) for (i = 1; i <= MAX_RETRIES; i++) { value = i2c_smbus_read_byte_data(client, reg); if (value >= 0) { - dev_dbg(&client->dev, "Read 0x%02x from register " - "0x%02x.\n", value, reg); + dev_dbg(dev, "%sRead 0x%02x from register 0x%02x.\n", + prefix, value, reg); return value; } - dev_dbg(&client->dev, "Read failed, will retry in %d.\n", i); + dev_dbg(dev, "%sRead failed, will retry in %d.\n", prefix, i); msleep(i); } - dev_err(&client->dev, "Couldn't read value from register 0x%02x.\n", + dev_err(dev, "%sCouldn't read value from register 0x%02x.\n", prefix, reg); return defval; } -- cgit v0.10.2 From 33468e7637c53b5516902422d66ca3d3fe64a9c3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 16 Jul 2008 19:30:18 +0200 Subject: hwmon: (w83l786ng) Convert to a new-style i2c driver The new-style w83l786ng driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare Cc: Kevin Lo diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 41e22dd..badca76 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -121,7 +121,6 @@ DIV_TO_REG(long val) } struct w83l786ng_data { - struct i2c_client client; struct device *hwmon_dev; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -146,18 +145,30 @@ struct w83l786ng_data { u8 tolerance[2]; }; -static int w83l786ng_attach_adapter(struct i2c_adapter *adapter); -static int w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind); -static int w83l786ng_detach_client(struct i2c_client *client); +static int w83l786ng_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int w83l786ng_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static int w83l786ng_remove(struct i2c_client *client); static void w83l786ng_init_client(struct i2c_client *client); static struct w83l786ng_data *w83l786ng_update_device(struct device *dev); +static const struct i2c_device_id w83l786ng_id[] = { + { "w83l786ng", w83l786ng }, + { } +}; +MODULE_DEVICE_TABLE(i2c, w83l786ng_id); + static struct i2c_driver w83l786ng_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "w83l786ng", }, - .attach_adapter = w83l786ng_attach_adapter, - .detach_client = w83l786ng_detach_client, + .probe = w83l786ng_probe, + .remove = w83l786ng_remove, + .id_table = w83l786ng_id, + .detect = w83l786ng_detect, + .address_data = &addr_data, }; static u8 @@ -575,42 +586,15 @@ static const struct attribute_group w83l786ng_group = { }; static int -w83l786ng_attach_adapter(struct i2c_adapter *adapter) +w83l786ng_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) { - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, w83l786ng_detect); -} - -static int -w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct device *dev; - struct w83l786ng_data *data; - int i, err = 0; - u8 reg_tmp; + struct i2c_adapter *adapter = client->adapter; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - goto exit; - } - - /* OK. For now, we presume we have a valid client. We now create the - client structure, even though we cannot fill it completely yet. - But it allows us to access w83l786ng_{read,write}_value. */ - - if (!(data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; + return -ENODEV; } - client = &data->client; - dev = &client->dev; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &w83l786ng_driver; - /* * Now we do the remaining detection. A negative kind means that * the driver was loaded with no force parameter (default), so we @@ -627,8 +611,8 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind) W83L786NG_REG_CONFIG) & 0x80) != 0x00)) { dev_dbg(&adapter->dev, "W83L786NG detection failed at 0x%02x.\n", - address); - goto exit_free; + client->addr); + return -ENODEV; } } @@ -651,17 +635,31 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&adapter->dev, "Unsupported chip (man_id=0x%04X, " "chip_id=0x%02X).\n", man_id, chip_id); - goto exit_free; + return -ENODEV; } } - /* Fill in the remaining client fields and put into the global list */ - strlcpy(client->name, "w83l786ng", I2C_NAME_SIZE); - mutex_init(&data->update_lock); + strlcpy(info->type, "w83l786ng", I2C_NAME_SIZE); - /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto exit_free; + return 0; +} + +static int +w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct w83l786ng_data *data; + int i, err = 0; + u8 reg_tmp; + + data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); /* Initialize the chip */ w83l786ng_init_client(client); @@ -693,25 +691,19 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind) exit_remove: sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); - i2c_detach_client(client); -exit_free: kfree(data); exit: return err; } static int -w83l786ng_detach_client(struct i2c_client *client) +w83l786ng_remove(struct i2c_client *client) { struct w83l786ng_data *data = i2c_get_clientdata(client); - int err; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); - if ((err = i2c_detach_client(client))) - return err; - kfree(data); return 0; -- cgit v0.10.2 From 84e0f3f6c1e26588fdcb9f1b0f99d0275229bc99 Mon Sep 17 00:00:00 2001 From: Dimitri Gorokhovik Date: Wed, 16 Jul 2008 20:33:34 +0200 Subject: ide: it821x in pass-through mode segfaults in 2.6.26-stable The driver of ITE8212 in pass-through mode (it8212.noraid=1 on cmndline) attempts to use the field `.dma_host_set' of the struct ide_dma_ops in `ide_config_drive_speed' which is set to NULL by default. So give a value to all fields of the struct ide_dma_ops. Signed-off-by: Dimitri Gorokhovik Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 6ab0411..cbf6472 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -512,8 +512,14 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive) } static struct ide_dma_ops it821x_pass_through_dma_ops = { + .dma_host_set = ide_dma_host_set, + .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = it821x_dma_start, .dma_end = it821x_dma_end, + .dma_test_irq = ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, + .dma_lost_irq = ide_dma_lost_irq, }; /** -- cgit v0.10.2 From 0b6abc17700a7843b165c677da0ac94522f83083 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 16 Jul 2008 20:33:35 +0200 Subject: ide: avoid DMA on the stack for REQ_TYPE_ATA_PC Some REQ_TYPE_ATA_PC commands uses the stack buffers for DMA, which leads to memory corruption on a non-coherent platform. With regard to alignment and padding, ide-cd has the the dma safe check for sg requests and REQ_TYPE_ATA_PC. This adds the stack buffer check to that check. Signed-off-by: FUJITA Tomonori Acked-by: Borislav Petkov Cc: Thomas Bogendoerfer Cc: Tejun Heo Cc: Jens Axboe Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d998471..d6667c3 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1195,6 +1195,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) int mask = drive->queue->dma_alignment; unsigned long addr = (unsigned long)page_address(bio_page(rq->bio)); + unsigned long stack_mask = ~(THREAD_SIZE - 1); info->dma = drive->using_dma; @@ -1206,6 +1207,10 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) */ if ((rq->data_len & 15) || (addr & mask)) info->dma = 0; + + if (!((addr & stack_mask) ^ + ((unsigned long)current->stack & stack_mask))) + info->dma = 0; } /* start sending the command to the drive */ -- cgit v0.10.2 From e5318b531b008c79d2a0c0df06a7b8628da38e2f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 16 Jul 2008 20:33:35 +0200 Subject: ide: use the dma safe check for REQ_TYPE_ATA_PC This uses the dma safe check for REQ_TYPE_ATA_PC. The dma safe check is used for only sg requests but it should be used for other non fs commands. This uses blk_queue_update_dma_pad to make the intention clear though ide don't use the blk APIs so it doesn't change anything. Signed-off-by: FUJITA Tomonori Acked-by: Borislav Petkov Cc: Thomas Bogendoerfer Cc: Tejun Heo Cc: Jens Axboe Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d6667c3..e12d602 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1191,12 +1191,17 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) info->dma = 0; /* sg request */ - if (rq->bio) { - int mask = drive->queue->dma_alignment; - unsigned long addr = - (unsigned long)page_address(bio_page(rq->bio)); + if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { + struct request_queue *q = drive->queue; + unsigned int alignment; + unsigned long addr; unsigned long stack_mask = ~(THREAD_SIZE - 1); + if (rq->bio) + addr = (unsigned long)bio_data(rq->bio); + else + addr = (unsigned long)rq->data; + info->dma = drive->using_dma; /* @@ -1205,7 +1210,8 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) * NOTE! The "len" and "addr" checks should possibly have * separate masks. */ - if ((rq->data_len & 15) || (addr & mask)) + alignment = queue_dma_alignment(q) | q->dma_pad_mask; + if (addr & alignment || rq->data_len & alignment) info->dma = 0; if (!((addr & stack_mask) ^ @@ -1877,6 +1883,7 @@ static int ide_cdrom_setup(ide_drive_t *drive) blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); blk_queue_dma_alignment(drive->queue, 31); + blk_queue_update_dma_pad(drive->queue, 15); drive->queue->unplug_delay = (1 * HZ) / 1000; if (!drive->queue->unplug_delay) drive->queue->unplug_delay = 1; -- cgit v0.10.2 From 96b1dfe8fe02e35f017c885b11f0beb10ff4f316 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 20 Jun 2008 20:53:35 +0200 Subject: BAST: Remove old IDE driver Remove the old BAST IDE driver, as we are now using the platform-pata support. Signed-off-by: Ben Dooks Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index cf707c8..cd08dba 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -829,13 +829,6 @@ config BLK_DEV_IDE_RAPIDE Say Y here if you want to support the Yellowstone RapIDE controller manufactured for use with Acorn computers. -config BLK_DEV_IDE_BAST - tristate "Simtec BAST / Thorcom VR1000 IDE support" - depends on ARM && (ARCH_BAST || MACH_VR1000) - help - Say Y here if you want to support the onboard IDE channels on the - Simtec BAST or the Thorcom VR1000 - config IDE_H8300 tristate "H8300 IDE support" depends on H8300 diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile index 936e7b0..5bc2605 100644 --- a/drivers/ide/arm/Makefile +++ b/drivers/ide/arm/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o -obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o ifeq ($(CONFIG_IDE_ARM), m) diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c deleted file mode 100644 index 8e8c281..0000000 --- a/drivers/ide/arm/bast-ide.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2003-2004 Simtec Electronics - * Ben Dooks - * - * 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 -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#define DRV_NAME "bast-ide" - -static int __init bastide_register(unsigned int base, unsigned int aux, int irq) -{ - ide_hwif_t *hwif; - hw_regs_t hw; - int i; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; - - memset(&hw, 0, sizeof(hw)); - - base += BAST_IDE_CS; - aux += BAST_IDE_CS; - - for (i = 0; i <= 7; i++) { - hw.io_ports_array[i] = (unsigned long)base; - base += 0x20; - } - - hw.io_ports.ctl_addr = aux + (6 * 0x20); - hw.irq = irq; - hw.chipset = ide_generic; - - hwif = ide_find_port(); - if (hwif == NULL) - goto out; - - i = hwif->index; - - ide_init_port_data(hwif, i); - ide_init_port_hw(hwif, &hw); - hwif->port_ops = NULL; - - idx[0] = i; - - ide_device_add(idx, NULL); -out: - return 0; -} - -static int __init bastide_init(void) -{ - unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS; - - /* we can treat the VR1000 and the BAST the same */ - - if (!(machine_is_bast() || machine_is_vr1000())) - return 0; - - printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n"); - - if (!request_mem_region(base, 0x400000, DRV_NAME)) { - printk(KERN_ERR "%s: resources busy\n", DRV_NAME); - return -EBUSY; - } - - bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0); - bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1); - - return 0; -} - -module_init(bastide_init); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Simtec BAST / Thorcom VR1000 IDE driver"); -- cgit v0.10.2 From e4e8d02f56f5c0cefc6713384629e068193d706a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:35 +0200 Subject: ide: remove needless includes from ide-lib.c Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 47af80d..7e053d2 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -1,26 +1,11 @@ -#include #include #include #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include -#include -#include -#include - static const char *udma_str[] = { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; -- cgit v0.10.2 From f0ffc9872e972e9d9fe8f7ae577ff046dbdba51b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: ide: remove unused XFER_UDMA_SLOW Remove unused XFER_UDMA_SLOW from ide_timing[]. While at it: - fix re-defining XFER_PIO_5 (no need to define it in ide-timing.h as it is defined in which is included by ) - fix whitespace damage There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index 2e91c58..a20c4cb 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -28,9 +28,6 @@ #include #include -#define XFER_PIO_5 0x0d -#define XFER_UDMA_SLOW 0x4f - struct ide_timing { short mode; short setup; /* t1 */ @@ -61,12 +58,10 @@ static struct ide_timing ide_timing[] = { { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, - { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, - { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, - + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, -- cgit v0.10.2 From 71d5161426c26742ba053fe93637559cbe2cea37 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: ide: use u8 for xfer modes in ide-timing.h There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index a20c4cb..ebe884d 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -29,7 +29,7 @@ #include struct ide_timing { - short mode; + u8 mode; short setup; /* t1 */ short act8b; /* t2 for 8-bit io */ short rec8b; /* t2i for 8-bit io */ @@ -76,7 +76,7 @@ static struct ide_timing ide_timing[] = { { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, - { -1 } + { 0xff } }; #define IDE_TIMING_SETUP 0x01 @@ -122,17 +122,18 @@ static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct if (what & IDE_TIMING_UDMA ) m->udma = max(a->udma, b->udma); } -static struct ide_timing* ide_timing_find_mode(short speed) +static struct ide_timing *ide_timing_find_mode(u8 speed) { struct ide_timing *t; for (t = ide_timing; t->mode != speed; t++) - if (t->mode < 0) + if (t->mode == 0xff) return NULL; return t; } -static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing *t, int T, int UT) +static int ide_timing_compute(ide_drive_t *drive, u8 speed, + struct ide_timing *t, int T, int UT) { struct hd_driveid *id = drive->id; struct ide_timing *s, p; -- cgit v0.10.2 From 3be53f3f213223f50d8e29b5e1869685bf040a1e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: ide: move some bits from ide-timing.h to Move struct ide_timing and IDE_TIMING_* defines to from drivers/ide/ide-timing.h. While at it: - use u8/u16 instead of short for struct ide_timing fields - use enum for IDE_TIMING_* There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index ebe884d..7248799 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -28,18 +28,6 @@ #include #include -struct ide_timing { - u8 mode; - short setup; /* t1 */ - short act8b; /* t2 for 8-bit io */ - short rec8b; /* t2i for 8-bit io */ - short cyc8b; /* t0 for 8-bit io */ - short active; /* t2 or tD */ - short recover; /* t2i or tK */ - short cycle; /* t0 */ - short udma; /* t2CYCTYP/2 */ -}; - /* * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). * These were taken from ATA/ATAPI-6 standard, rev 0a, except @@ -79,17 +67,6 @@ static struct ide_timing ide_timing[] = { { 0xff } }; -#define IDE_TIMING_SETUP 0x01 -#define IDE_TIMING_ACT8B 0x02 -#define IDE_TIMING_REC8B 0x04 -#define IDE_TIMING_CYC8B 0x08 -#define IDE_TIMING_8BIT 0x0e -#define IDE_TIMING_ACTIVE 0x10 -#define IDE_TIMING_RECOVER 0x20 -#define IDE_TIMING_CYCLE 0x40 -#define IDE_TIMING_UDMA 0x80 -#define IDE_TIMING_ALL 0xff - #define ENOUGH(v,unit) (((v)-1)/(unit)+1) #define EZ(v,unit) ((v)?ENOUGH(v,unit):0) diff --git a/include/linux/ide.h b/include/linux/ide.h index ac4eeb2..81c6ea4 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1271,6 +1271,34 @@ static inline int ide_dev_is_sata(struct hd_driveid *id) u64 ide_get_lba_addr(struct ide_taskfile *, int); u8 ide_dump_status(ide_drive_t *, const char *, u8); +struct ide_timing { + u8 mode; + u8 setup; /* t1 */ + u16 act8b; /* t2 for 8-bit io */ + u16 rec8b; /* t2i for 8-bit io */ + u16 cyc8b; /* t0 for 8-bit io */ + u16 active; /* t2 or tD */ + u16 recover; /* t2i or tK */ + u16 cycle; /* t0 */ + u16 udma; /* t2CYCTYP/2 */ +}; + +enum { + IDE_TIMING_SETUP = (1 << 0), + IDE_TIMING_ACT8B = (1 << 1), + IDE_TIMING_REC8B = (1 << 2), + IDE_TIMING_CYC8B = (1 << 3), + IDE_TIMING_8BIT = IDE_TIMING_ACT8B | IDE_TIMING_REC8B | + IDE_TIMING_CYC8B, + IDE_TIMING_ACTIVE = (1 << 4), + IDE_TIMING_RECOVER = (1 << 5), + IDE_TIMING_CYCLE = (1 << 6), + IDE_TIMING_UDMA = (1 << 7), + IDE_TIMING_ALL = IDE_TIMING_SETUP | IDE_TIMING_8BIT | + IDE_TIMING_ACTIVE | IDE_TIMING_RECOVER | + IDE_TIMING_CYCLE | IDE_TIMING_UDMA, +}; + typedef struct ide_pio_timings_s { int setup_time; /* Address setup (ns) minimum */ int active_time; /* Active pulse (ns) minimum */ -- cgit v0.10.2 From bd887f72d2a28a8202519e67fd9ed93ee3c4e78d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: ide: remove XFER_* masks from ide-timing.h * Check requested xfer mode against xfer modes instead of XFER_* masks in ide_timing_compute() and cs5535.c::cs5535_set_speed(). * Remove XFER_[MODE,MWDMA,EPIO,PIO] masks. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index 7248799..a401d8f 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -70,11 +70,6 @@ static struct ide_timing ide_timing[] = { #define ENOUGH(v,unit) (((v)-1)/(unit)+1) #define EZ(v,unit) ((v)?ENOUGH(v,unit):0) -#define XFER_MODE 0xf0 -#define XFER_MWDMA 0x20 -#define XFER_EPIO 0x01 -#define XFER_PIO 0x00 - static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT) { q->setup = EZ(t->setup * 1000, T); @@ -137,17 +132,12 @@ static int ide_timing_compute(ide_drive_t *drive, u8 speed, memset(&p, 0, sizeof(p)); - switch (speed & XFER_MODE) { - - case XFER_PIO: - if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id->eide_pio; - else p.cycle = p.cyc8b = id->eide_pio_iordy; - break; - - case XFER_MWDMA: - p.cycle = id->eide_dma_min; - break; - } + if (speed <= XFER_PIO_2) + p.cycle = p.cyc8b = id->eide_pio; + else if (speed <= XFER_PIO_5) + p.cycle = p.cyc8b = id->eide_pio_iordy; + else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) + p.cycle = id->eide_dma_min; ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); } @@ -164,7 +154,7 @@ static int ide_timing_compute(ide_drive_t *drive, u8 speed, * slower/equal than the fastest PIO timing. */ - if ((speed & XFER_MODE) != XFER_PIO) { + if (speed >= XFER_SW_DMA_0) { u8 pio = ide_get_best_pio_mode(drive, 255, 5); ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT); ide_timing_merge(&p, t, t, IDE_TIMING_ALL); diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 99fe91a..2a2cb49 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -75,13 +75,11 @@ static unsigned int cs5535_udma_timings[5] = */ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) { - u32 reg = 0, dummy; int unit = drive->select.b.unit; - /* Set the PIO timings */ - if ((speed & XFER_MODE) == XFER_PIO) { + if (speed < XFER_SW_DMA_0) { ide_drive_t *pair = ide_get_paired_drive(drive); u8 cmd, pioa; -- cgit v0.10.2 From 2c139e7a7152f66ff93b173f8770c94ea53a691e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:36 +0200 Subject: ide: checkpatch.pl fixes for ide-timing.h Also fix placement of comments in ide_timing_compute() while at it. There should be no functional changes caused by this patch (md5sum was verified to be the same before/after the patch). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h index a401d8f..98e05f5 100644 --- a/drivers/ide/ide-timing.h +++ b/drivers/ide/ide-timing.h @@ -3,9 +3,7 @@ /* * Copyright (c) 1999-2001 Vojtech Pavlik - */ - -/* + * * 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 @@ -32,7 +30,7 @@ * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). * These were taken from ATA/ATAPI-6 standard, rev 0a, except * for PIO 5, which is a nonstandard extension and UDMA6, which - * is currently supported only by Maxtor drives. + * is currently supported only by Maxtor drives. */ static struct ide_timing ide_timing[] = { @@ -67,10 +65,11 @@ static struct ide_timing ide_timing[] = { { 0xff } }; -#define ENOUGH(v,unit) (((v)-1)/(unit)+1) -#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) +#define ENOUGH(v, unit) (((v) - 1) / (unit) + 1) +#define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0) -static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT) +static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, + int T, int UT) { q->setup = EZ(t->setup * 1000, T); q->act8b = EZ(t->act8b * 1000, T); @@ -82,16 +81,25 @@ static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int q->udma = EZ(t->udma * 1000, UT); } -static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what) +static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, + struct ide_timing *m, unsigned int what) { - if (what & IDE_TIMING_SETUP ) m->setup = max(a->setup, b->setup); - if (what & IDE_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b); - if (what & IDE_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b); - if (what & IDE_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); - if (what & IDE_TIMING_ACTIVE ) m->active = max(a->active, b->active); - if (what & IDE_TIMING_RECOVER) m->recover = max(a->recover, b->recover); - if (what & IDE_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); - if (what & IDE_TIMING_UDMA ) m->udma = max(a->udma, b->udma); + if (what & IDE_TIMING_SETUP) + m->setup = max(a->setup, b->setup); + if (what & IDE_TIMING_ACT8B) + m->act8b = max(a->act8b, b->act8b); + if (what & IDE_TIMING_REC8B) + m->rec8b = max(a->rec8b, b->rec8b); + if (what & IDE_TIMING_CYC8B) + m->cyc8b = max(a->cyc8b, b->cyc8b); + if (what & IDE_TIMING_ACTIVE) + m->active = max(a->active, b->active); + if (what & IDE_TIMING_RECOVER) + m->recover = max(a->recover, b->recover); + if (what & IDE_TIMING_CYCLE) + m->cycle = max(a->cycle, b->cycle); + if (what & IDE_TIMING_UDMA) + m->udma = max(a->udma, b->udma); } static struct ide_timing *ide_timing_find_mode(u8 speed) @@ -101,7 +109,7 @@ static struct ide_timing *ide_timing_find_mode(u8 speed) for (t = ide_timing; t->mode != speed; t++) if (t->mode == 0xff) return NULL; - return t; + return t; } static int ide_timing_compute(ide_drive_t *drive, u8 speed, @@ -110,24 +118,22 @@ static int ide_timing_compute(ide_drive_t *drive, u8 speed, struct hd_driveid *id = drive->id; struct ide_timing *s, p; -/* - * Find the mode. - */ - - if (!(s = ide_timing_find_mode(speed))) + /* + * Find the mode. + */ + s = ide_timing_find_mode(speed); + if (s == NULL) return -EINVAL; -/* - * Copy the timing from the table. - */ - + /* + * Copy the timing from the table. + */ *t = *s; -/* - * If the drive is an EIDE drive, it can tell us it needs extended - * PIO/MWDMA cycle timing. - */ - + /* + * If the drive is an EIDE drive, it can tell us it needs extended + * PIO/MWDMA cycle timing. + */ if (id && id->field_valid & 2) { /* EIDE drive */ memset(&p, 0, sizeof(p)); @@ -142,28 +148,25 @@ static int ide_timing_compute(ide_drive_t *drive, u8 speed, ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); } -/* - * Convert the timing to bus clock counts. - */ - + /* + * Convert the timing to bus clock counts. + */ ide_timing_quantize(t, t, T, UT); -/* - * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T - * and some other commands. We have to ensure that the DMA cycle timing is - * slower/equal than the fastest PIO timing. - */ - + /* + * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, + * S.M.A.R.T and some other commands. We have to ensure that the + * DMA cycle timing is slower/equal than the fastest PIO timing. + */ if (speed >= XFER_SW_DMA_0) { u8 pio = ide_get_best_pio_mode(drive, 255, 5); ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT); ide_timing_merge(&p, t, t, IDE_TIMING_ALL); } -/* - * Lengthen active & recovery time so that cycle time is correct. - */ - + /* + * Lengthen active & recovery time so that cycle time is correct. + */ if (t->act8b + t->rec8b < t->cyc8b) { t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; t->rec8b = t->cyc8b - t->act8b; -- cgit v0.10.2 From f06ab3402aa2d6de060442c1053ea10b24b65076 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: ide: convert ide-timing.h to ide-timings.c library (take 2) * Don't include ide-timing.h in cs5535 and sis5513 host drivers (they don't need it currently). * Convert ide-timing.h to ide-timings.c library and add CONFIG_IDE_TIMINGS config option to be selected by host drivers using the library. While at it: - fix ide_timing_find_mode() placement v2: * Add missing EXPORT_SYMBOLs. (Stephen Rothwell ) There should be no functional changes caused by this patch. Cc: Stephen Rothwell Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index cd08dba..994b6d3 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -98,6 +98,9 @@ if BLK_DEV_IDE comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" +config IDE_TIMINGS + bool + config IDE_ATAPI bool @@ -469,6 +472,7 @@ config BLK_DEV_ALI15X3 config BLK_DEV_AMD74XX tristate "AMD and nVidia IDE support" depends on !ARM + select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help This driver adds explicit support for AMD-7xx and AMD-8111 chips @@ -725,6 +729,7 @@ config BLK_DEV_TRM290 config BLK_DEV_VIA82CXXX tristate "VIA82CXXX chipset support" + select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help This driver adds explicit support for VIA BusMastering IDE chips. @@ -751,6 +756,7 @@ endif config BLK_DEV_IDE_PMAC tristate "PowerMac on-board IDE support" depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y + select IDE_TIMINGS help This driver provides support for the on-board IDE controller on most of the recent Apple Power Macintoshes and PowerBooks. @@ -912,6 +918,7 @@ config BLK_DEV_Q40IDE config BLK_DEV_PALMCHIP_BK3710 tristate "Palmchip bk3710 IDE controller support" depends on ARCH_DAVINCI + select IDE_TIMINGS select BLK_DEV_IDEDMA_SFF help Say Y here if you want to support the onchip IDE controller on the diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index a2b3f84..cb13506 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -14,6 +14,7 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o # core IDE code +ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 3839f57..9b8a45d2 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -74,8 +74,6 @@ struct palm_bk3710_udmatiming { #define BK3710_IORDYTMP 0x78 #define BK3710_IORDYTMS 0x7C -#include "../ide-timing.h" - static unsigned ideclk_period; /* in nanoseconds */ static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h deleted file mode 100644 index 98e05f5..0000000 --- a/drivers/ide/ide-timing.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef _IDE_TIMING_H -#define _IDE_TIMING_H - -/* - * Copyright (c) 1999-2001 Vojtech Pavlik - * - * 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 - * - * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to , or by paper mail: - * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic - */ - -#include -#include - -/* - * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). - * These were taken from ATA/ATAPI-6 standard, rev 0a, except - * for PIO 5, which is a nonstandard extension and UDMA6, which - * is currently supported only by Maxtor drives. - */ - -static struct ide_timing ide_timing[] = { - - { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, - { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, - { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, - { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, - - { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, - { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, - { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, - - { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, - { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, - { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, - - { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, - { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, - { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, - - { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, - { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, - { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, - - { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, - { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, - { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, - - { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, - - { 0xff } -}; - -#define ENOUGH(v, unit) (((v) - 1) / (unit) + 1) -#define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0) - -static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, - int T, int UT) -{ - q->setup = EZ(t->setup * 1000, T); - q->act8b = EZ(t->act8b * 1000, T); - q->rec8b = EZ(t->rec8b * 1000, T); - q->cyc8b = EZ(t->cyc8b * 1000, T); - q->active = EZ(t->active * 1000, T); - q->recover = EZ(t->recover * 1000, T); - q->cycle = EZ(t->cycle * 1000, T); - q->udma = EZ(t->udma * 1000, UT); -} - -static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, - struct ide_timing *m, unsigned int what) -{ - if (what & IDE_TIMING_SETUP) - m->setup = max(a->setup, b->setup); - if (what & IDE_TIMING_ACT8B) - m->act8b = max(a->act8b, b->act8b); - if (what & IDE_TIMING_REC8B) - m->rec8b = max(a->rec8b, b->rec8b); - if (what & IDE_TIMING_CYC8B) - m->cyc8b = max(a->cyc8b, b->cyc8b); - if (what & IDE_TIMING_ACTIVE) - m->active = max(a->active, b->active); - if (what & IDE_TIMING_RECOVER) - m->recover = max(a->recover, b->recover); - if (what & IDE_TIMING_CYCLE) - m->cycle = max(a->cycle, b->cycle); - if (what & IDE_TIMING_UDMA) - m->udma = max(a->udma, b->udma); -} - -static struct ide_timing *ide_timing_find_mode(u8 speed) -{ - struct ide_timing *t; - - for (t = ide_timing; t->mode != speed; t++) - if (t->mode == 0xff) - return NULL; - return t; -} - -static int ide_timing_compute(ide_drive_t *drive, u8 speed, - struct ide_timing *t, int T, int UT) -{ - struct hd_driveid *id = drive->id; - struct ide_timing *s, p; - - /* - * Find the mode. - */ - s = ide_timing_find_mode(speed); - if (s == NULL) - return -EINVAL; - - /* - * Copy the timing from the table. - */ - *t = *s; - - /* - * If the drive is an EIDE drive, it can tell us it needs extended - * PIO/MWDMA cycle timing. - */ - if (id && id->field_valid & 2) { /* EIDE drive */ - - memset(&p, 0, sizeof(p)); - - if (speed <= XFER_PIO_2) - p.cycle = p.cyc8b = id->eide_pio; - else if (speed <= XFER_PIO_5) - p.cycle = p.cyc8b = id->eide_pio_iordy; - else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) - p.cycle = id->eide_dma_min; - - ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); - } - - /* - * Convert the timing to bus clock counts. - */ - ide_timing_quantize(t, t, T, UT); - - /* - * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, - * S.M.A.R.T and some other commands. We have to ensure that the - * DMA cycle timing is slower/equal than the fastest PIO timing. - */ - if (speed >= XFER_SW_DMA_0) { - u8 pio = ide_get_best_pio_mode(drive, 255, 5); - ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT); - ide_timing_merge(&p, t, t, IDE_TIMING_ALL); - } - - /* - * Lengthen active & recovery time so that cycle time is correct. - */ - if (t->act8b + t->rec8b < t->cyc8b) { - t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; - t->rec8b = t->cyc8b - t->act8b; - } - - if (t->active + t->recover < t->cycle) { - t->active += (t->cycle - (t->active + t->recover)) / 2; - t->recover = t->cycle - t->active; - } - - return 0; -} - -#endif diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c new file mode 100644 index 0000000..ebef6d4 --- /dev/null +++ b/drivers/ide/ide-timings.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 1999-2001 Vojtech Pavlik + * + * 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 + * + * Should you need to contact me, the author, you can do so either by + * e-mail - mail your message to , or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic + */ + +#include +#include +#include +#include + +/* + * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). + * These were taken from ATA/ATAPI-6 standard, rev 0a, except + * for PIO 5, which is a nonstandard extension and UDMA6, which + * is currently supported only by Maxtor drives. + */ + +static struct ide_timing ide_timing[] = { + + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, + { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, + { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, + + { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, + { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, + { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, + + { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, + { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, + { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, + + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, + { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, + { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, + + { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, + { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, + { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, + + { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, + { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, + { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, + + { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, + + { 0xff } +}; + +struct ide_timing *ide_timing_find_mode(u8 speed) +{ + struct ide_timing *t; + + for (t = ide_timing; t->mode != speed; t++) + if (t->mode == 0xff) + return NULL; + return t; +} +EXPORT_SYMBOL_GPL(ide_timing_find_mode); + +#define ENOUGH(v, unit) (((v) - 1) / (unit) + 1) +#define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0) + +static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, + int T, int UT) +{ + q->setup = EZ(t->setup * 1000, T); + q->act8b = EZ(t->act8b * 1000, T); + q->rec8b = EZ(t->rec8b * 1000, T); + q->cyc8b = EZ(t->cyc8b * 1000, T); + q->active = EZ(t->active * 1000, T); + q->recover = EZ(t->recover * 1000, T); + q->cycle = EZ(t->cycle * 1000, T); + q->udma = EZ(t->udma * 1000, UT); +} + +void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, + struct ide_timing *m, unsigned int what) +{ + if (what & IDE_TIMING_SETUP) + m->setup = max(a->setup, b->setup); + if (what & IDE_TIMING_ACT8B) + m->act8b = max(a->act8b, b->act8b); + if (what & IDE_TIMING_REC8B) + m->rec8b = max(a->rec8b, b->rec8b); + if (what & IDE_TIMING_CYC8B) + m->cyc8b = max(a->cyc8b, b->cyc8b); + if (what & IDE_TIMING_ACTIVE) + m->active = max(a->active, b->active); + if (what & IDE_TIMING_RECOVER) + m->recover = max(a->recover, b->recover); + if (what & IDE_TIMING_CYCLE) + m->cycle = max(a->cycle, b->cycle); + if (what & IDE_TIMING_UDMA) + m->udma = max(a->udma, b->udma); +} +EXPORT_SYMBOL_GPL(ide_timing_merge); + +int ide_timing_compute(ide_drive_t *drive, u8 speed, + struct ide_timing *t, int T, int UT) +{ + struct hd_driveid *id = drive->id; + struct ide_timing *s, p; + + /* + * Find the mode. + */ + s = ide_timing_find_mode(speed); + if (s == NULL) + return -EINVAL; + + /* + * Copy the timing from the table. + */ + *t = *s; + + /* + * If the drive is an EIDE drive, it can tell us it needs extended + * PIO/MWDMA cycle timing. + */ + if (id && id->field_valid & 2) { /* EIDE drive */ + + memset(&p, 0, sizeof(p)); + + if (speed <= XFER_PIO_2) + p.cycle = p.cyc8b = id->eide_pio; + else if (speed <= XFER_PIO_5) + p.cycle = p.cyc8b = id->eide_pio_iordy; + else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) + p.cycle = id->eide_dma_min; + + ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B); + } + + /* + * Convert the timing to bus clock counts. + */ + ide_timing_quantize(t, t, T, UT); + + /* + * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, + * S.M.A.R.T and some other commands. We have to ensure that the + * DMA cycle timing is slower/equal than the fastest PIO timing. + */ + if (speed >= XFER_SW_DMA_0) { + u8 pio = ide_get_best_pio_mode(drive, 255, 5); + ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT); + ide_timing_merge(&p, t, t, IDE_TIMING_ALL); + } + + /* + * Lengthen active & recovery time so that cycle time is correct. + */ + if (t->act8b + t->rec8b < t->cyc8b) { + t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; + t->rec8b = t->cyc8b - t->act8b; + } + + if (t->active + t->recover < t->cycle) { + t->active += (t->cycle - (t->active + t->recover)) / 2; + t->recover = t->cycle - t->active; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ide_timing_compute); diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index ad22220..0bfcdd0 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -21,8 +21,6 @@ #include #include -#include "ide-timing.h" - enum { AMD_IDE_CONFIG = 0x41, AMD_CABLE_DETECT = 0x42, diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 2a2cb49..dc97c48 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -26,8 +26,6 @@ #include #include -#include "ide-timing.h" - #define MSR_ATAC_BASE 0x51300000 #define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0) #define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index e127eb2..2389945 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -52,8 +52,6 @@ #include #include -#include "ide-timing.h" - /* registers layout and init values are chipset family dependant */ #define ATA_16 0x01 @@ -616,7 +614,6 @@ MODULE_LICENSE("GPL"); /* * TODO: * - CLEANUP - * - Use drivers/ide/ide-timing.h ! * - More checks in the config registers (force values instead of * relying on the BIOS setting them correctly). * - Further optimisations ? diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 3ed9728..e47384c 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -35,8 +35,6 @@ #include #endif -#include "ide-timing.h" - #define VIA_IDE_ENABLE 0x40 #define VIA_IDE_CONFIG 0x41 #define VIA_FIFO_CONFIG 0x43 diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index dcb2c46..5b91d23 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -48,8 +48,6 @@ #include #endif -#include "../ide-timing.h" - #undef IDE_PMAC_DEBUG #define DMA_WAIT_TIMEOUT 50 diff --git a/include/linux/ide.h b/include/linux/ide.h index 81c6ea4..057001f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1299,6 +1299,11 @@ enum { IDE_TIMING_CYCLE | IDE_TIMING_UDMA, }; +struct ide_timing *ide_timing_find_mode(u8); +void ide_timing_merge(struct ide_timing *, struct ide_timing *, + struct ide_timing *, unsigned int); +int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int); + typedef struct ide_pio_timings_s { int setup_time; /* Address setup (ns) minimum */ int active_time; /* Active pulse (ns) minimum */ -- cgit v0.10.2 From cc57ccc03d2a9b5622300f4b59fc8b54408c6e24 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: ali14xx: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 994b6d3..e9afafd 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -981,6 +981,7 @@ config BLK_DEV_4DRIVES config BLK_DEV_ALI14XX tristate "ALI M14xx support" + select IDE_TIMINGS help This driver is enabled at runtime using the "ali14xx.probe" kernel boot parameter. It enables support for the secondary IDE interface diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index 052125f..4ec1973 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c @@ -117,10 +117,11 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) u8 param1, param2, param3, param4; unsigned long flags; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); /* calculate timing, according to PIO mode */ time1 = ide_pio_cycle_time(drive, pio); - time2 = ide_pio_timings[pio].active_time; + time2 = t->active; param3 = param1 = (time2 * bus_speed + 999) / 1000; param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1; if (pio < 3) { -- cgit v0.10.2 From b32b76f72df17de891181b47e714f9f897bb62a1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: ht6560b: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e9afafd..615e0bc0 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -1001,6 +1001,7 @@ config BLK_DEV_DTC2278 config BLK_DEV_HT6560B tristate "Holtek HT6560B support" + select IDE_TIMINGS help This driver is enabled at runtime using the "ht6560b.probe" kernel boot parameter. It enables support for the secondary IDE interface diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index dd6dfb3..bd2f579 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -216,6 +216,7 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) if (pio) { unsigned int cycle_time; + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); cycle_time = ide_pio_cycle_time(drive, pio); @@ -224,10 +225,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) * actual cycle time for recovery and activity * according system bus speed. */ - active_time = ide_pio_timings[pio].active_time; - recovery_time = cycle_time - - active_time - - ide_pio_timings[pio].setup_time; + active_time = t->active; + recovery_time = cycle_time - active_time - t->setup; /* * Cycle times should be Vesa bus cycles */ -- cgit v0.10.2 From 2feecface7fd62be75bd4961324dc279a04bef22 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: qd65xx: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 615e0bc0..86db707 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -1011,6 +1011,7 @@ config BLK_DEV_HT6560B config BLK_DEV_QD65XX tristate "QDI QD65xx support" + select IDE_TIMINGS help This driver is enabled at runtime using the "qd65xx.probe" kernel boot parameter. It permits faster I/O speeds to be set. See the diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 51dba82..63f6c31 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -207,6 +207,7 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); unsigned int cycle_time; int active_time = 175; int recovery_time = 415; /* worst case values from the dos driver */ @@ -236,7 +237,7 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) active_time = 110; recovery_time = cycle_time - 120; } else { - active_time = ide_pio_timings[pio].active_time; + active_time = t->active; recovery_time = cycle_time - active_time; } } -- cgit v0.10.2 From 288911af1209f5aa6119c9ec6d5a9bdb16a385b5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:37 +0200 Subject: alim15x3: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 86db707..cadce92 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -458,6 +458,7 @@ config BLK_DEV_AEC62XX config BLK_DEV_ALI15X3 tristate "ALI M15x3 chipset support" + select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help This driver ensures (U)DMA support for ALI 1533, 1543 and 1543C diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index f2de00ad..80d19c0 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -69,7 +69,8 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - int s_time, a_time, c_time; + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); + int s_time = t->setup, a_time = t->active, c_time = t->cycle; u8 s_clc, a_clc, r_clc; unsigned long flags; int bus_speed = ide_pci_clk ? ide_pci_clk : 33; @@ -78,13 +79,10 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) u8 cd_dma_fifo = 0; int unit = drive->select.b.unit & 1; - s_time = ide_pio_timings[pio].setup_time; - a_time = ide_pio_timings[pio].active_time; if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) s_clc = 0; if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8) a_clc = 0; - c_time = ide_pio_timings[pio].cycle_time; if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { r_clc = 1; -- cgit v0.10.2 From 17b500de0ad79a306a0cd8acfe9a9f086ad28b4c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: cmd640: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index cadce92..e072bde 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -329,6 +329,7 @@ config BLK_DEV_PLATFORM config BLK_DEV_CMD640 tristate "CMD640 chipset bugfix/support" depends on X86 + select IDE_TIMINGS ---help--- The CMD-Technologies CMD640 IDE chip is used on many common 486 and Pentium motherboards, usually in combination with a "Neptune" or diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index cd1ba14..baa26a2 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -521,6 +521,7 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index) static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, u8 pio_mode, unsigned int cycle_time) { + struct ide_timing *t; int setup_time, active_time, recovery_time, clock_time; u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; int bus_speed; @@ -532,8 +533,11 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, if (pio_mode > 5) pio_mode = 5; - setup_time = ide_pio_timings[pio_mode].setup_time; - active_time = ide_pio_timings[pio_mode].active_time; + + t = ide_timing_find_mode(XFER_PIO_0 + pio_mode); + setup_time = t->setup; + active_time = t->active; + recovery_time = cycle_time - (setup_time + active_time); clock_time = 1000 / bus_speed; cycle_count = DIV_ROUND_UP(cycle_time, clock_time); -- cgit v0.10.2 From 86a0e12fcb590a6a84b90ae00e6d6564ce770749 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: cmd64x: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e072bde..d5526d3 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -495,6 +495,7 @@ config BLK_DEV_ATIIXP config BLK_DEV_CMD64X tristate "CMD64{3|6|8|9} chipset support" + select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help Say Y here if you have an IDE controller which uses any of these diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index ca4774a..cfa784b 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -116,6 +116,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); unsigned int cycle_time; u8 setup_count, arttim = 0; @@ -124,10 +125,9 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) cycle_time = ide_pio_cycle_time(drive, pio); - program_cycle_times(drive, cycle_time, - ide_pio_timings[pio].active_time); + program_cycle_times(drive, cycle_time, t->active); - setup_count = quantize_timing(ide_pio_timings[pio].setup_time, + setup_count = quantize_timing(t->setup, 1000 / (ide_pci_clk ? ide_pci_clk : 33)); /* -- cgit v0.10.2 From 713a590dea9a61e84f2837e75c5e9429d95908b5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: cy82c693: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index d5526d3..7446db6 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -510,6 +510,7 @@ config BLK_DEV_TRIFLEX config BLK_DEV_CY82C693 tristate "CY82C693 chipset support" + select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help This driver adds detection and support for the CY82C693 chipset diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 8c534af..e14ad55 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -133,6 +133,7 @@ static int calc_clk(int time, int bus_speed) */ static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) { + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); int clk1, clk2; int bus_speed = ide_pci_clk ? ide_pci_clk : 33; @@ -141,15 +142,13 @@ static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) */ /* let's calc the address setup time clocks */ - p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed); + p_pclk->address_time = (u8)calc_clk(t->setup, bus_speed); /* let's calc the active and recovery time clocks */ - clk1 = calc_clk(ide_pio_timings[pio].active_time, bus_speed); + clk1 = calc_clk(t->active, bus_speed); /* calc recovery timing */ - clk2 = ide_pio_timings[pio].cycle_time - - ide_pio_timings[pio].active_time - - ide_pio_timings[pio].setup_time; + clk2 = t->cycle - t->active - t->setup; clk2 = calc_clk(clk2, bus_speed); -- cgit v0.10.2 From 3f847571a1cf845a338bcd352f31240b3615f40d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: sl82c105: convert to use ide_timing_find_mode() There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 7446db6..5f4d6ea 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -703,6 +703,7 @@ config BLK_DEV_SIS5513 config BLK_DEV_SL82C105 tristate "Winbond SL82c105 support" depends on (PPC || ARM) + select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help If you have a Winbond SL82c105 IDE controller, say Y here to enable diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index ce84fa0..6efbde2 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -47,10 +47,11 @@ */ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) { + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); unsigned int cmd_on, cmd_off; u8 iordy = 0; - cmd_on = (ide_pio_timings[pio].active_time + 29) / 30; + cmd_on = (t->active + 29) / 30; cmd_off = (ide_pio_cycle_time(drive, pio) - 30 * cmd_on + 29) / 30; if (cmd_on == 0) -- cgit v0.10.2 From b96f7384646519da54ad50bfad8d53b915b70cb3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: ide-mpc8xx: convert to use ide_timing_find_mode() Also fix (disabled) debugging code while at it. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c index 236f9c3..33bc699 100644 --- a/drivers/ide/ppc/mpc8xx.c +++ b/drivers/ide/ppc/mpc8xx.c @@ -89,7 +89,7 @@ ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = { #endif /* IDE0_BASE_OFFSET */ }; -ide_pio_timings_t ide_pio_clocks[6]; +struct ide_timing ide_pio_clocks[6]; int hold_time[6] = {30, 20, 15, 10, 10, 10 }; /* PIO Mode 5 with IORDY (nonstandard) */ /* @@ -200,30 +200,23 @@ static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) /* Compute clock cycles for PIO timings */ for (i=0; i<6; ++i) { bd_t *binfo = (bd_t *)__res; + struct ide_timing *t, *n; hold_time[i] = PCMCIA_MK_CLKS (hold_time[i], binfo->bi_busfreq); - ide_pio_clocks[i].setup_time = - PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time, - binfo->bi_busfreq); - ide_pio_clocks[i].active_time = - PCMCIA_MK_CLKS (ide_pio_timings[i].active_time, - binfo->bi_busfreq); - ide_pio_clocks[i].cycle_time = - PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time, - binfo->bi_busfreq); + + t = ide_timing_find_mode(XFER_PIO_0 + i); + n = &ide_pio_clocks[i]; + + n->setup = PCMCIA_MK_CLKS(t->setup, binfo->bi_busfreq); + n->active = PCMCIA_MK_CLKS(t->active, binfo->bi_busfreq); + n->cycle = PCMCIA_MK_CLKS(t->cycle, binfo->bi_busfreq); #if 0 printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n", i, - ide_pio_clocks[i].setup_time, - ide_pio_clocks[i].active_time, - ide_pio_clocks[i].hold_time, - ide_pio_clocks[i].cycle_time, - ide_pio_timings[i].setup_time, - ide_pio_timings[i].active_time, - ide_pio_timings[i].hold_time, - ide_pio_timings[i].cycle_time); + t->setup, t->active, t->cycle, + n->setup, n->active, n->cycle); #endif } } @@ -408,8 +401,8 @@ static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF)); timing = PCMCIA_SHT(hold_time[pio] ) - | PCMCIA_SST(ide_pio_clocks[pio].setup_time ) - | PCMCIA_SL (ide_pio_clocks[pio].active_time) + | PCMCIA_SST(ide_pio_clocks[pio].setup) + | PCMCIA_SL (ide_pio_clocks[pio].active) ; #if 1 -- cgit v0.10.2 From 8a97206e31dc2e2f8f9b4d97e234b5c701fe9894 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:38 +0200 Subject: ide-pmac: convert to use ide_timing_find_mode() Also update my Copyrights while at it. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 5b91d23..cfa103a 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -5,7 +5,7 @@ * for doing DMA. * * Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz + * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -493,6 +493,7 @@ static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port) static void pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) { + struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio); u32 *timings, t; unsigned accessTicks, recTicks; unsigned accessTime, recTime; @@ -524,10 +525,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) } case controller_kl_ata4: /* 66Mhz cell */ - recTime = cycle_time - ide_pio_timings[pio].active_time - - ide_pio_timings[pio].setup_time; + recTime = cycle_time - tim->active - tim->setup; recTime = max(recTime, 150U); - accessTime = ide_pio_timings[pio].active_time; + accessTime = tim->active; accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS_66(accessTime); accessTicks = min(accessTicks, 0x1fU); @@ -540,10 +540,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) default: { /* 33Mhz cell */ int ebit = 0; - recTime = cycle_time - ide_pio_timings[pio].active_time - - ide_pio_timings[pio].setup_time; + recTime = cycle_time - tim->active - tim->setup; recTime = max(recTime, 150U); - accessTime = ide_pio_timings[pio].active_time; + accessTime = tim->active; accessTime = max(accessTime, 150U); accessTicks = SYSCLK_TICKS(accessTime); accessTicks = min(accessTicks, 0x1fU); -- cgit v0.10.2 From c9d6c1a2379373219bb3271bdcbdc0ab2edf349d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: ide: move ide_pio_cycle_time() to ide-timings.c All ide_pio_cycle_time() users already select CONFIG_IDE_TIMINGS so move the function from ide-lib.c to ide-timings.c. While at it: - convert ide_pio_cycle_time() to use ide_timing_find_mode() - cleanup ide_pio_cycle_time() a bit There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 7e053d2..efa5bfa 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -188,29 +188,6 @@ static int ide_scan_pio_blacklist (char *model) return -1; } -unsigned int ide_pio_cycle_time(ide_drive_t *drive, u8 pio) -{ - struct hd_driveid *id = drive->id; - int cycle_time = 0; - - if (id->field_valid & 2) { - if (id->capability & 8) - cycle_time = id->eide_pio_iordy; - else - cycle_time = id->eide_pio; - } - - /* conservative "downgrade" for all pre-ATA2 drives */ - if (pio < 3) { - if (cycle_time && cycle_time < ide_pio_timings[pio].cycle_time) - cycle_time = 0; /* use standard timing */ - } - - return cycle_time ? cycle_time : ide_pio_timings[pio].cycle_time; -} - -EXPORT_SYMBOL_GPL(ide_pio_cycle_time); - /** * ide_get_best_pio_mode - get PIO mode from drive * @drive: drive to consider diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c index ebef6d4..8c2f832 100644 --- a/drivers/ide/ide-timings.c +++ b/drivers/ide/ide-timings.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1999-2001 Vojtech Pavlik + * Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz * * 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 @@ -75,6 +76,27 @@ struct ide_timing *ide_timing_find_mode(u8 speed) } EXPORT_SYMBOL_GPL(ide_timing_find_mode); +u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio) +{ + struct hd_driveid *id = drive->id; + struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); + u16 cycle = 0; + + if (id->field_valid & 2) { + if (id->capability & 8) + cycle = id->eide_pio_iordy; + else + cycle = id->eide_pio; + + /* conservative "downgrade" for all pre-ATA2 drives */ + if (pio < 3 && cycle < t->cycle) + cycle = 0; /* use standard timing */ + } + + return cycle ? cycle : t->cycle; +} +EXPORT_SYMBOL_GPL(ide_pio_cycle_time); + #define ENOUGH(v, unit) (((v) - 1) / (unit) + 1) #define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0) diff --git a/include/linux/ide.h b/include/linux/ide.h index 057001f..3899c76 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1300,6 +1300,7 @@ enum { }; struct ide_timing *ide_timing_find_mode(u8); +u16 ide_pio_cycle_time(ide_drive_t *, u8); void ide_timing_merge(struct ide_timing *, struct ide_timing *, struct ide_timing *, unsigned int); int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int); @@ -1311,7 +1312,6 @@ typedef struct ide_pio_timings_s { /* active + recovery (+ setup for some chips) */ } ide_pio_timings_t; -unsigned int ide_pio_cycle_time(ide_drive_t *, u8); u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8); extern const ide_pio_timings_t ide_pio_timings[6]; -- cgit v0.10.2 From 3e153cfb5e38ae237ff27a10a833946ac95db8a4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: ide: remove no longer used ide_pio_timings[] Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index efa5bfa..3e12f22 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -76,23 +76,6 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) } /* - * Standard (generic) timings for PIO modes, from ATA2 specification. - * These timings are for access to the IDE data port register *only*. - * Some drives may specify a mode, while also specifying a different - * value for cycle_time (from drive identification data). - */ -const ide_pio_timings_t ide_pio_timings[6] = { - { 70, 165, 600 }, /* PIO Mode 0 */ - { 50, 125, 383 }, /* PIO Mode 1 */ - { 30, 100, 240 }, /* PIO Mode 2 */ - { 30, 80, 180 }, /* PIO Mode 3 with IORDY */ - { 25, 70, 120 }, /* PIO Mode 4 with IORDY */ - { 20, 50, 100 } /* PIO Mode 5 with IORDY (nonstandard) */ -}; - -EXPORT_SYMBOL_GPL(ide_pio_timings); - -/* * Shared data/functions for determining best PIO mode for an IDE drive. * Most of this stuff originally lived in cmd640.c, and changes to the * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid diff --git a/include/linux/ide.h b/include/linux/ide.h index 3899c76..4e44525 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1305,15 +1305,7 @@ void ide_timing_merge(struct ide_timing *, struct ide_timing *, struct ide_timing *, unsigned int); int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int); -typedef struct ide_pio_timings_s { - int setup_time; /* Address setup (ns) minimum */ - int active_time; /* Active pulse (ns) minimum */ - int cycle_time; /* Cycle time (ns) minimum = */ - /* active + recovery (+ setup for some chips) */ -} ide_pio_timings_t; - u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8); -extern const ide_pio_timings_t ide_pio_timings[6]; int ide_set_pio_mode(ide_drive_t *, u8); int ide_set_dma_mode(ide_drive_t *, u8); -- cgit v0.10.2 From 9ad540937554a3779c5fe7af13aa390b1d2aeb3e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: ide: move PIO blacklist to ide-pio-blacklist.c Move PIO blacklist to ide-pio-blacklist.c. While at it: - fix comment - fix whitespace damage There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index cb13506..8605536 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -11,7 +11,8 @@ EXTRA_CFLAGS += -Idrivers/ide -ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o +ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o \ + ide-pio-blacklist.o # core IDE code ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 3e12f22..13af72f 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -75,102 +75,6 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) return min(speed, mode); } -/* - * Shared data/functions for determining best PIO mode for an IDE drive. - * Most of this stuff originally lived in cmd640.c, and changes to the - * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid - * breaking the fragile cmd640.c support. - */ - -/* - * Black list. Some drives incorrectly report their maximal PIO mode, - * at least in respect to CMD640. Here we keep info on some known drives. - */ -static struct ide_pio_info { - const char *name; - int pio; -} ide_pio_blacklist [] = { - { "Conner Peripherals 540MB - CFS540A", 3 }, - - { "WDC AC2700", 3 }, - { "WDC AC2540", 3 }, - { "WDC AC2420", 3 }, - { "WDC AC2340", 3 }, - { "WDC AC2250", 0 }, - { "WDC AC2200", 0 }, - { "WDC AC21200", 4 }, - { "WDC AC2120", 0 }, - { "WDC AC2850", 3 }, - { "WDC AC1270", 3 }, - { "WDC AC1170", 1 }, - { "WDC AC1210", 1 }, - { "WDC AC280", 0 }, - { "WDC AC31000", 3 }, - { "WDC AC31200", 3 }, - - { "Maxtor 7131 AT", 1 }, - { "Maxtor 7171 AT", 1 }, - { "Maxtor 7213 AT", 1 }, - { "Maxtor 7245 AT", 1 }, - { "Maxtor 7345 AT", 1 }, - { "Maxtor 7546 AT", 3 }, - { "Maxtor 7540 AV", 3 }, - - { "SAMSUNG SHD-3121A", 1 }, - { "SAMSUNG SHD-3122A", 1 }, - { "SAMSUNG SHD-3172A", 1 }, - - { "ST5660A", 3 }, - { "ST3660A", 3 }, - { "ST3630A", 3 }, - { "ST3655A", 3 }, - { "ST3391A", 3 }, - { "ST3390A", 1 }, - { "ST3600A", 1 }, - { "ST3290A", 0 }, - { "ST3144A", 0 }, - { "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on */ - /* drive) according to Seagates FIND-ATA program */ - - { "QUANTUM ELS127A", 0 }, - { "QUANTUM ELS170A", 0 }, - { "QUANTUM LPS240A", 0 }, - { "QUANTUM LPS210A", 3 }, - { "QUANTUM LPS270A", 3 }, - { "QUANTUM LPS365A", 3 }, - { "QUANTUM LPS540A", 3 }, - { "QUANTUM LIGHTNING 540A", 3 }, - { "QUANTUM LIGHTNING 730A", 3 }, - - { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */ - { "QUANTUM FIREBALL_640", 3 }, - { "QUANTUM FIREBALL_1080", 3 }, - { "QUANTUM FIREBALL_1280", 3 }, - { NULL, 0 } -}; - -/** - * ide_scan_pio_blacklist - check for a blacklisted drive - * @model: Drive model string - * - * This routine searches the ide_pio_blacklist for an entry - * matching the start/whole of the supplied model name. - * - * Returns -1 if no match found. - * Otherwise returns the recommended PIO mode from ide_pio_blacklist[]. - */ - -static int ide_scan_pio_blacklist (char *model) -{ - struct ide_pio_info *p; - - for (p = ide_pio_blacklist; p->name != NULL; p++) { - if (strncmp(p->name, model, strlen(p->name)) == 0) - return p->pio; - } - return -1; -} - /** * ide_get_best_pio_mode - get PIO mode from drive * @drive: drive to consider diff --git a/drivers/ide/ide-pio-blacklist.c b/drivers/ide/ide-pio-blacklist.c new file mode 100644 index 0000000..a8c2c8f8 --- /dev/null +++ b/drivers/ide/ide-pio-blacklist.c @@ -0,0 +1,94 @@ +/* + * PIO blacklist. Some drives incorrectly report their maximal PIO mode, + * at least in respect to CMD640. Here we keep info on some known drives. + * + * Changes to the ide_pio_blacklist[] should be made with EXTREME CAUTION + * to avoid breaking the fragile cmd640.c support. + */ + +#include + +static struct ide_pio_info { + const char *name; + int pio; +} ide_pio_blacklist [] = { + { "Conner Peripherals 540MB - CFS540A", 3 }, + + { "WDC AC2700", 3 }, + { "WDC AC2540", 3 }, + { "WDC AC2420", 3 }, + { "WDC AC2340", 3 }, + { "WDC AC2250", 0 }, + { "WDC AC2200", 0 }, + { "WDC AC21200", 4 }, + { "WDC AC2120", 0 }, + { "WDC AC2850", 3 }, + { "WDC AC1270", 3 }, + { "WDC AC1170", 1 }, + { "WDC AC1210", 1 }, + { "WDC AC280", 0 }, + { "WDC AC31000", 3 }, + { "WDC AC31200", 3 }, + + { "Maxtor 7131 AT", 1 }, + { "Maxtor 7171 AT", 1 }, + { "Maxtor 7213 AT", 1 }, + { "Maxtor 7245 AT", 1 }, + { "Maxtor 7345 AT", 1 }, + { "Maxtor 7546 AT", 3 }, + { "Maxtor 7540 AV", 3 }, + + { "SAMSUNG SHD-3121A", 1 }, + { "SAMSUNG SHD-3122A", 1 }, + { "SAMSUNG SHD-3172A", 1 }, + + { "ST5660A", 3 }, + { "ST3660A", 3 }, + { "ST3630A", 3 }, + { "ST3655A", 3 }, + { "ST3391A", 3 }, + { "ST3390A", 1 }, + { "ST3600A", 1 }, + { "ST3290A", 0 }, + { "ST3144A", 0 }, + { "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on drive) + according to Seagate's FIND-ATA program */ + + { "QUANTUM ELS127A", 0 }, + { "QUANTUM ELS170A", 0 }, + { "QUANTUM LPS240A", 0 }, + { "QUANTUM LPS210A", 3 }, + { "QUANTUM LPS270A", 3 }, + { "QUANTUM LPS365A", 3 }, + { "QUANTUM LPS540A", 3 }, + { "QUANTUM LIGHTNING 540A", 3 }, + { "QUANTUM LIGHTNING 730A", 3 }, + + { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */ + { "QUANTUM FIREBALL_640", 3 }, + { "QUANTUM FIREBALL_1080", 3 }, + { "QUANTUM FIREBALL_1280", 3 }, + { NULL, 0 } +}; + +/** + * ide_scan_pio_blacklist - check for a blacklisted drive + * @model: Drive model string + * + * This routine searches the ide_pio_blacklist for an entry + * matching the start/whole of the supplied model name. + * + * Returns -1 if no match found. + * Otherwise returns the recommended PIO mode from ide_pio_blacklist[]. + */ + +int ide_scan_pio_blacklist(char *model) +{ + struct ide_pio_info *p; + + for (p = ide_pio_blacklist; p->name != NULL; p++) { + if (strncmp(p->name, model, strlen(p->name)) == 0) + return p->pio; + } + return -1; +} diff --git a/include/linux/ide.h b/include/linux/ide.h index 4e44525..535c439 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1305,6 +1305,8 @@ void ide_timing_merge(struct ide_timing *, struct ide_timing *, struct ide_timing *, unsigned int); int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int); +int ide_scan_pio_blacklist(char *); + u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8); int ide_set_pio_mode(ide_drive_t *, u8); -- cgit v0.10.2 From 256c5f8eef7b9a8c8a85c15c58cda9df455f947e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:39 +0200 Subject: ide: fix hwif-s initialization * Add ide_hwifs[] entry initialization to ide_find_port_slot() and remove ide_init_port_data() calls from host drivers. * Unexport ide_init_port_data(). * Remove no longer needed init_ide_data(). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 9b8a45d2..c79b85b 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -400,7 +400,6 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) i = hwif->index; - ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); default_hwif_mmiops(hwif); diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index ae37ee5..dfce105 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -199,7 +199,6 @@ static int __init h8300_ide_init(void) } index = hwif->index; - ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); hwif_setup(hwif); hwif->host_flags = IDE_HFLAG_NO_IO_32BIT; diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index adbd017..fc1e10c 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c @@ -62,7 +62,6 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) u8 index = hwif->index; u8 idx[4] = { index, 0xff, 0xff, 0xff }; - ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index d21e51a..592d424 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1473,22 +1473,26 @@ ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d) for (; i < MAX_HWIFS; i++) { hwif = &ide_hwifs[i]; if (hwif->chipset == ide_unknown) - return hwif; + goto out_found; } } else { for (i = 2; i < MAX_HWIFS; i++) { hwif = &ide_hwifs[i]; if (hwif->chipset == ide_unknown) - return hwif; + goto out_found; } for (i = 0; i < 2 && i < MAX_HWIFS; i++) { hwif = &ide_hwifs[i]; if (hwif->chipset == ide_unknown) - return hwif; + goto out_found; } } return NULL; + +out_found: + ide_init_port_data(hwif, i); + return hwif; } EXPORT_SYMBOL_GPL(ide_find_port_slot); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 2b84535..32d8ee2 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -121,7 +121,6 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) ide_port_init_devices_data(hwif); } -EXPORT_SYMBOL_GPL(ide_init_port_data); static void ide_port_init_devices_data(ide_hwif_t *hwif) { @@ -150,18 +149,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) } } -static void __init init_ide_data (void) -{ - unsigned int index; - - /* Initialise all interface structures */ - for (index = 0; index < MAX_HWIFS; ++index) { - ide_hwif_t *hwif = &ide_hwifs[index]; - - ide_init_port_data(hwif, index); - } -} - void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) { ide_hwgroup_t *hwgroup = hwif->hwgroup; @@ -1021,8 +1008,6 @@ static int __init ide_init(void) goto out_port_class; } - init_ide_data(); - proc_ide_create(); return 0; diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index 9a1d27e..0497e7f 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c @@ -227,7 +227,6 @@ fail_base2: if (hwif) { u8 index = hwif->index; - ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); idx[i] = index; diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index af11028..129a812 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c @@ -111,7 +111,6 @@ static int __init falconide_init(void) u8 index = hwif->index; u8 idx[4] = { index, 0xff, 0xff, 0xff }; - ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); /* Atari has a byte-swapped IDE interface */ diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index b789416..7e74b20 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c @@ -185,7 +185,6 @@ found: if (hwif) { u8 index = hwif->index; - ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); idx[i] = index; diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 8dbf4d9..7c69608 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -187,7 +187,6 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, i = hwif->index; - ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); hwif->port_ops = &idecs_port_ops; diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index 2e84290..0a6195b 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -130,7 +130,6 @@ static int __init macide_init(void) u8 index = hwif->index; u8 idx[4] = { index, 0xff, 0xff, 0xff }; - ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); ide_device_add(idx, NULL); diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 8ff6e2d..9c2b9d0 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c @@ -142,7 +142,6 @@ static int __init q40ide_init(void) hwif = ide_find_port(); if (hwif) { - ide_init_port_data(hwif, hwif->index); ide_init_port_hw(hwif, &hw); /* Q40 has a byte-swapped IDE interface */ diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index af0f300..0106e2a 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c @@ -93,7 +93,6 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) i = hwif->index; - ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); idx[0] = i; -- cgit v0.10.2 From 63b51c6d1d63276fd320615c042f1ff5d94ebab8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: ide: make ide_hwifs[] static Move ide_hwifs[] from ide.c to ide-probe.c and make it static. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 592d424..97dda05 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -39,6 +39,8 @@ #include #include +static ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ + /** * generic_id - add a generic drive id * @drive: drive to make an ID block for diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 32d8ee2..b7855a1 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -91,8 +91,6 @@ DEFINE_MUTEX(ide_cfg_mtx); __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); EXPORT_SYMBOL(ide_lock); -ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ - static void ide_port_init_devices_data(ide_hwif_t *); /* diff --git a/include/linux/ide.h b/include/linux/ide.h index 535c439..15d5668 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -801,18 +801,6 @@ struct ide_driver_s { int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long); -/* - * ide_hwifs[] is the master data structure used to keep track - * of just about everything in ide.c. Whenever possible, routines - * should be using pointers to a drive (ide_drive_t *) or - * pointers to a hwif (ide_hwif_t *), rather than indexing this - * structure directly (the allocation/layout may change!). - * - */ -#ifndef _IDE_C -extern ide_hwif_t ide_hwifs[]; /* master data repository */ -#endif - extern int ide_vlb_clk; extern int ide_pci_clk; -- cgit v0.10.2 From c56c5648a3bd15ff14c50f284b261140cd5b5472 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: ide: set hwif->dev in ide_init_port_hw() (take 2) * Add 'parent' field to hw_regs_t for optional parent device pointer (needed by macio PMAC IDE controllers) and set hwif->dev in ide_init_port_hw(). * Update au1xxx-ide.c, sgiioc4.c, pmac.c and setup-pci.c accordingly. v2: * Update scc_pata.c. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index b7855a1..9240888 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -297,7 +297,8 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); hwif->irq = hw->irq; hwif->chipset = hw->chipset; - hwif->gendev.parent = hw->dev; + hwif->dev = hw->dev; + hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; hwif->ack_intr = hw->ack_intr; } EXPORT_SYMBOL_GPL(ide_init_port_hw); diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 1a6c27b..08c46c3 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -600,8 +600,6 @@ static int au_ide_probe(struct device *dev) ide_init_port_hw(hwif, &hw); - hwif->dev = dev; - /* If the user has selected DDMA assisted copies, then set up a few local I/O function entry points */ diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 1584ebb..71bff31 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -572,7 +572,6 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, hw.dev = &dev->dev; hw.chipset = ide_pci; ide_init_port_hw(hwif, &hw); - hwif->dev = &dev->dev; idx[0] = hwif->index; diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 24513e3..af91cc5 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -625,8 +625,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) hw.dev = &dev->dev; ide_init_port_hw(hwif, &hw); - hwif->dev = &dev->dev; - /* The IOC4 uses MMIO rather than Port IO. */ default_hwif_mmiops(hwif); diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index cfa103a..93fb906 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1148,8 +1148,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) base = ioremap(macio_resource_start(mdev, 0), 0x400); regbase = (unsigned long) base; - hwif->dev = &mdev->bus->pdev->dev; - pmif->mdev = mdev; pmif->node = mdev->ofdev.node; pmif->regbase = regbase; @@ -1171,7 +1169,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) memset(&hw, 0, sizeof(hw)); pmac_ide_init_ports(&hw, pmif->regbase); hw.irq = irq; - hw.dev = &mdev->ofdev.dev; + hw.dev = &mdev->bus->pdev->dev; + hw.parent = &mdev->ofdev.dev; rc = pmac_ide_setup_device(pmif, hwif, &hw); if (rc != 0) { @@ -1271,7 +1270,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) goto out_free_pmif; } - hwif->dev = &pdev->dev; pmif->mdev = NULL; pmif->node = np; diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index abcfb17..3dea5a5 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -346,8 +346,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_init_port_hw(hwif, &hw); - hwif->dev = &dev->dev; - return hwif; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 15d5668..a6a2ecc 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -171,7 +171,7 @@ typedef struct hw_regs_s { int irq; /* our irq number */ ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ hwif_chipset_t chipset; - struct device *dev; + struct device *dev, *parent; } hw_regs_t; void ide_init_port_data(struct hwif_s *, unsigned int); -- cgit v0.10.2 From a536f326a2223c951818e199e23847c2ac5e483b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: au1xxx-ide: don't use hwif->hwif_data * Use &auide_hwif directly instead of using hwif->hwif_data. While at it: * No need to initialize hwif->{select,config}_data. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 08c46c3..48d57ca 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -213,10 +213,8 @@ static int auide_build_dmatable(ide_drive_t *drive) { int i, iswrite, count = 0; ide_hwif_t *hwif = HWIF(drive); - struct request *rq = HWGROUP(drive)->rq; - - _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + _auide_hwif *ahwif = &auide_hwif; struct scatterlist *sg; iswrite = (rq_data_dir(rq) == WRITE); @@ -402,7 +400,7 @@ static const struct ide_dma_ops au1xxx_dma_ops = { static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) { - _auide_hwif *auide = (_auide_hwif *)hwif->hwif_data; + _auide_hwif *auide = &auide_hwif; dbdev_tab_t source_dev_tab, target_dev_tab; u32 dev_id, tsize, devwidth, flags; @@ -463,7 +461,7 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) #else static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) { - _auide_hwif *auide = (_auide_hwif *)hwif->hwif_data; + _auide_hwif *auide = &auide_hwif; dbdev_tab_t source_dev_tab; int flags; @@ -608,11 +606,8 @@ static int au_ide_probe(struct device *dev) hwif->input_data = au1xxx_input_data; hwif->output_data = au1xxx_output_data; #endif - hwif->select_data = 0; /* no chipset-specific code */ - hwif->config_data = 0; /* no chipset-specific code */ auide_hwif.hwif = hwif; - hwif->hwif_data = &auide_hwif; idx[0] = hwif->index; -- cgit v0.10.2 From f333f92bf9040fb63d13c184295629c7a0ff449f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: ide_4drives: use struct ide_port_info Convert the driver to use struct ide_port_info - as a nice side-effect this fixes hwif->channel initialization. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index ecae916..5cd6ce5 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/legacy/ide-4drives.c @@ -11,6 +11,23 @@ static int probe_4drives; module_param_named(probe, probe_4drives, bool, 0); MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); +static void ide_4drives_port_init_devs(ide_hwif_t *hwif) +{ + if (hwif->channel) { + hwif->drives[0].select.all ^= 0x20; + hwif->drives[1].select.all ^= 0x20; + } +} + +static const struct ide_port_ops ide_4drives_port_ops = { + .port_init_devs = ide_4drives_port_init_devs, +}; + +static const struct ide_port_info ide_4drives_port_info = { + .port_ops = &ide_4drives_port_ops, + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, +}; + static int __init ide_4drives_init(void) { ide_hwif_t *hwif, *mate; @@ -49,18 +66,10 @@ static int __init ide_4drives_init(void) mate = ide_find_port(); if (mate) { ide_init_port_hw(mate, &hw); - mate->drives[0].select.all ^= 0x20; - mate->drives[1].select.all ^= 0x20; idx[1] = mate->index; - - if (hwif) { - hwif->mate = mate; - mate->mate = hwif; - hwif->serialized = mate->serialized = 1; - } } - ide_device_add(idx, NULL); + ide_device_add(idx, &ide_4drives_port_info); return 0; } -- cgit v0.10.2 From dccdf527379dc2fe8a4efc5c75601d1d4035a750 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: ide-cs: use struct ide_port_info Convert the driver to use struct ide_port_info. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 7c69608..fc53dcf 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -154,6 +154,11 @@ static const struct ide_port_ops idecs_port_ops = { .quirkproc = ide_undecoded_slave, }; +static const struct ide_port_info idecs_port_info = { + .port_ops = &idecs_port_ops, + .host_flags = IDE_HFLAG_NO_DMA, +}; + static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) { @@ -188,11 +193,10 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, i = hwif->index; ide_init_port_hw(hwif, &hw); - hwif->port_ops = &idecs_port_ops; idx[0] = i; - ide_device_add(idx, NULL); + ide_device_add(idx, &idecs_port_info); if (hwif->present) return hwif; -- cgit v0.10.2 From 26839f09ca2d0f4239e546cd912bc9f4694f3c5e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:40 +0200 Subject: icside: don't use hwif->hwif_data * Move ecard_set_drvdata() from icside_probe() to icside_register_v{5,6}(), then use state->ioc_base instead of hwif->hwif_data in icside_maskproc() and icside_dma_test_irq(). While at it: * Add sel field to struct icside_state, then use state->{sel,ioc_base} instead of ->{select,config}_data in icside_dma_setup(). There should be no functional changes caused by this patch. Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 0614569..7439580 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -68,6 +68,7 @@ struct icside_state { unsigned int enabled; void __iomem *irq_port; void __iomem *ioc_base; + unsigned int sel; unsigned int type; ide_hwif_t *hwif[2]; }; @@ -165,7 +166,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = { static void icside_maskproc(ide_drive_t *drive, int mask) { ide_hwif_t *hwif = HWIF(drive); - struct icside_state *state = hwif->hwif_data; + struct expansion_card *ec = ECARD_DEV(hwif->dev); + struct icside_state *state = ecard_get_drvdata(ec); unsigned long flags; local_irq_save(flags); @@ -308,6 +310,7 @@ static int icside_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct expansion_card *ec = ECARD_DEV(hwif->dev); + struct icside_state *state = ecard_get_drvdata(ec); struct request *rq = hwif->hwgroup->rq; unsigned int dma_mode; @@ -331,7 +334,7 @@ static int icside_dma_setup(ide_drive_t *drive) /* * Route the DMA signals to the correct interface. */ - writeb(hwif->select_data, hwif->config_data); + writeb(state->sel | hwif->channel, state->ioc_base); /* * Select the correct timing for this drive. @@ -359,7 +362,8 @@ static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) static int icside_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - struct icside_state *state = hwif->hwif_data; + struct expansion_card *ec = ECARD_DEV(hwif->dev); + struct icside_state *state = ecard_get_drvdata(ec); return readb(state->irq_port + (hwif->channel ? @@ -472,6 +476,8 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) state->hwif[0] = hwif; + ecard_set_drvdata(ec, state); + idx[0] = hwif->index; ide_device_add(idx, NULL); @@ -525,6 +531,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) state->irq_port = easi_base; state->ioc_base = ioc_base; + state->sel = sel; /* * Be on the safe side - disable interrupts @@ -545,13 +552,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) state->hwif[0] = hwif; state->hwif[1] = mate; - hwif->hwif_data = state; - hwif->config_data = (unsigned long)ioc_base; - hwif->select_data = sel; - - mate->hwif_data = state; - mate->config_data = (unsigned long)ioc_base; - mate->select_data = sel | 1; + ecard_set_drvdata(ec, state); if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) { d.init_dma = icside_dma_init; @@ -627,10 +628,8 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id) break; } - if (ret == 0) { - ecard_set_drvdata(ec, state); + if (ret == 0) goto out; - } kfree(state); release: -- cgit v0.10.2 From b25afdf1336237fb0e4021eb35744e577e19bd14 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: icside: use ide_init_port_hw() * Move ide_find_port() and default_hwif_mmiops() calls from icside_setup() to icside_register_v{5,6}(). * Convert icside_setup() to initialize hw_regs_t instead ide_hwif_t and icside_register_v{5,6}() to use ide_init_port_hw(). * Rename icside_setup() to icside_setup_ports(). There should be no functional changes caused by this patch. Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 7439580..c8d8600 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -415,36 +415,24 @@ static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d) return -EOPNOTSUPP; } -static ide_hwif_t * -icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec) +static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, + struct cardinfo *info, struct expansion_card *ec) { unsigned long port = (unsigned long)base + info->dataoffset; - ide_hwif_t *hwif; - hwif = ide_find_port(); - if (hwif) { - /* - * Ensure we're using MMIO - */ - default_hwif_mmiops(hwif); - - hwif->io_ports.data_addr = port; - hwif->io_ports.error_addr = port + (1 << info->stepping); - hwif->io_ports.nsect_addr = port + (2 << info->stepping); - hwif->io_ports.lbal_addr = port + (3 << info->stepping); - hwif->io_ports.lbam_addr = port + (4 << info->stepping); - hwif->io_ports.lbah_addr = port + (5 << info->stepping); - hwif->io_ports.device_addr = port + (6 << info->stepping); - hwif->io_ports.status_addr = port + (7 << info->stepping); - hwif->io_ports.ctl_addr = - (unsigned long)base + info->ctrloffset; - hwif->irq = ec->irq; - hwif->chipset = ide_acorn; - hwif->gendev.parent = &ec->dev; - hwif->dev = &ec->dev; - } - - return hwif; + hw->io_ports.data_addr = port; + hw->io_ports.error_addr = port + (1 << info->stepping); + hw->io_ports.nsect_addr = port + (2 << info->stepping); + hw->io_ports.lbal_addr = port + (3 << info->stepping); + hw->io_ports.lbam_addr = port + (4 << info->stepping); + hw->io_ports.lbah_addr = port + (5 << info->stepping); + hw->io_ports.device_addr = port + (6 << info->stepping); + hw->io_ports.status_addr = port + (7 << info->stepping); + hw->io_ports.ctl_addr = (unsigned long)base + info->ctrloffset; + + hw->irq = ec->irq; + hw->dev = &ec->dev; + hw->chipset = ide_acorn; } static int __init @@ -453,6 +441,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) ide_hwif_t *hwif; void __iomem *base; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; + hw_regs_t hw; base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); if (!base) @@ -470,10 +459,15 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) */ icside_irqdisable_arcin_v5(ec, 0); - hwif = icside_setup(base, &icside_cardinfo_v5, ec); + icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); + + hwif = ide_find_port(); if (!hwif) return -ENODEV; + ide_init_port_hw(hwif, &hw); + default_hwif_mmiops(hwif); + state->hwif[0] = hwif; ecard_set_drvdata(ec, state); @@ -503,6 +497,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) int ret; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; struct ide_port_info d = icside_v6_port_info; + hw_regs_t hw[2]; ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); if (!ioc_base) { @@ -538,16 +533,25 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) */ icside_irqdisable_arcin_v6(ec, 0); + icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec); + icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec); + /* * Find and register the interfaces. */ - hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec); - mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec); + hwif = ide_find_port(); + if (hwif == NULL) + return -ENODEV; - if (!hwif || !mate) { - ret = -ENODEV; - goto out; - } + ide_init_port_hw(hwif, &hw[0]); + default_hwif_mmiops(hwif); + + mate = ide_find_port(); + if (mate == NULL) + return -ENODEV; + + ide_init_port_hw(mate, &hw[1]); + default_hwif_mmiops(mate); state->hwif[0] = hwif; state->hwif[1] = mate; -- cgit v0.10.2 From 01397012b3129147890bb116431d5a794dfc3990 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: sgiioc4: use driver name for resource allocation Cc: Jeremy Higdon Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index af91cc5..dd0d0f7 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -608,11 +608,11 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) cmd_phys_base = bar0 + IOC4_CMD_OFFSET; if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, - hwif->name)) { + DRV_NAME)) { printk(KERN_ERR "%s : %s -- ERROR, Addresses " "0x%p to 0x%p ALREADY in use\n", - __func__, hwif->name, (void *) cmd_phys_base, + __func__, DRV_NAME, (void *) cmd_phys_base, (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); return -ENOMEM; } -- cgit v0.10.2 From c1da678b5b4d8ce7836ed1ded80109d1db37efe0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: ide: tighten checks on PCI BARs in ide_hwif_configure() Alan has fixed PCI layer handling of PCI IDE in Compatibility mode so PCI BAR 0/1 (and/or 2/3) content reported by kernel should never be zero. Tighten checks on PCI BARs and also fix printk() message while on it. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 3dea5a5..166211f 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -319,18 +319,18 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ctl = pci_resource_start(dev, 2*port+1); base = pci_resource_start(dev, 2*port); - if ((ctl && !base) || (base && !ctl)) { - printk(KERN_ERR "%s: inconsistent baseregs (BIOS) " - "for port %d, skipping\n", d->name, port); - return NULL; - } - } - if (!ctl) { + } else { /* Use default values */ ctl = port ? 0x374 : 0x3f4; base = port ? 0x170 : 0x1f0; } + if (!base || !ctl) { + printk(KERN_ERR "%s: bad PCI BARs for port %d, skipping\n", + d->name, port); + return NULL; + } + hwif = ide_find_port_slot(d); if (hwif == NULL) { printk(KERN_ERR "%s: too many IDE interfaces, no room in " -- cgit v0.10.2 From e48905e9cfffd21861c3521d828ae992a53aac67 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: swarm: use struct ide_port_info Convert the driver to use struct ide_port_info. There should be no functional changes caused by this patch. Acked-by: Maciej W. Rozycki Tested-by: Maciej W. Rozycki Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 52fee3d..57a0138 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -61,6 +61,10 @@ static struct resource swarm_ide_resource = { static struct platform_device *swarm_ide_dev; +static const struct ide_port_info swarm_port_info = { + .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, +}; + /* * swarm_ide_probe - if the board header indicates the existence of * Generic Bus IDE, allocate a HWIF for it. @@ -110,7 +114,6 @@ static int __devinit swarm_ide_probe(struct device *dev) base = ioremap(offset, size); /* Setup MMIO ops. */ - hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); for (i = 0; i <= 7; i++) @@ -125,7 +128,7 @@ static int __devinit swarm_ide_probe(struct device *dev) idx[0] = hwif->index; - ide_device_add(idx, NULL); + ide_device_add(idx, &swarm_port_info); dev_set_drvdata(dev, hwif); -- cgit v0.10.2 From ba1d0de70d64e68f0e035f00dbb041c1e05b49c9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: powerpc/ide: remove mpc8xx-ide driver This driver was only used by arch/ppc code and is obsolete now with the move to common arch/powerpc code. [bart: port it over IDE tree, remove leftover 'choice' from Kconfig] Signed-off-by: Arnd Bergmann Acked-by: Kumar Gala Cc: Paul Mackerras Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 5f4d6ea..21511d4 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -929,46 +929,6 @@ config BLK_DEV_PALMCHIP_BK3710 Say Y here if you want to support the onchip IDE controller on the TI DaVinci SoC - -config BLK_DEV_MPC8xx_IDE - tristate "MPC8xx IDE support" - depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE - help - This option provides support for IDE on Motorola MPC8xx Systems. - Please see 'Type of MPC8xx IDE interface' for details. - - If unsure, say N. - -choice - prompt "Type of MPC8xx IDE interface" - depends on BLK_DEV_MPC8xx_IDE - default IDE_8xx_PCCARD - -config IDE_8xx_PCCARD - bool "8xx_PCCARD" - ---help--- - Select how the IDE devices are connected to the MPC8xx system: - - 8xx_PCCARD uses the 8xx internal PCMCIA interface in combination - with a PC Card (e.g. ARGOSY portable Hard Disk Adapter), - ATA PC Card HDDs or ATA PC Flash Cards (example: TQM8xxL - systems) - - 8xx_DIRECT is used for directly connected IDE devices using the 8xx - internal PCMCIA interface (example: IVMS8 systems) - - EXT_DIRECT is used for IDE devices directly connected to the 8xx - bus using some glue logic, but _not_ the 8xx internal - PCMCIA interface (example: IDIF860 systems) - -config IDE_8xx_DIRECT - bool "8xx_DIRECT" - -config IDE_EXT_DIRECT - bool "EXT_DIRECT" - -endchoice - # no isa -> no vlb if ISA && (ALPHA || X86 || MIPS) diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile index 65af584..74e52ad 100644 --- a/drivers/ide/ppc/Makefile +++ b/drivers/ide/ppc/Makefile @@ -1,3 +1,2 @@ obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o -obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c deleted file mode 100644 index 33bc699..0000000 --- a/drivers/ide/ppc/mpc8xx.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de - * Modified for direct IDE interface - * by Thomas Lange, thomas@corelatus.com - * Modified for direct IDE interface on 8xx without using the PCMCIA - * controller - * by Steven.Scholz@imc-berlin.de - * Moved out of arch/ppc/kernel/m8xx_setup.c, other minor cleanups - * by Mathew Locke - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "ide-mpc8xx" - -static int identify (volatile u8 *p); -static void print_fixed (volatile u8 *p); -static void print_funcid (int func); -static int check_ide_device (unsigned long base); - -static void ide_interrupt_ack (void *dev); -static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio); - -typedef struct ide_ioport_desc { - unsigned long base_off; /* Offset to PCMCIA memory */ - unsigned long reg_off[IDE_NR_PORTS]; /* controller register offsets */ - int irq; /* IRQ */ -} ide_ioport_desc_t; - -ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = { -#ifdef IDE0_BASE_OFFSET - { IDE0_BASE_OFFSET, - { - IDE0_DATA_REG_OFFSET, - IDE0_ERROR_REG_OFFSET, - IDE0_NSECTOR_REG_OFFSET, - IDE0_SECTOR_REG_OFFSET, - IDE0_LCYL_REG_OFFSET, - IDE0_HCYL_REG_OFFSET, - IDE0_SELECT_REG_OFFSET, - IDE0_STATUS_REG_OFFSET, - IDE0_CONTROL_REG_OFFSET, - IDE0_IRQ_REG_OFFSET, - }, - IDE0_INTERRUPT, - }, -#ifdef IDE1_BASE_OFFSET - { IDE1_BASE_OFFSET, - { - IDE1_DATA_REG_OFFSET, - IDE1_ERROR_REG_OFFSET, - IDE1_NSECTOR_REG_OFFSET, - IDE1_SECTOR_REG_OFFSET, - IDE1_LCYL_REG_OFFSET, - IDE1_HCYL_REG_OFFSET, - IDE1_SELECT_REG_OFFSET, - IDE1_STATUS_REG_OFFSET, - IDE1_CONTROL_REG_OFFSET, - IDE1_IRQ_REG_OFFSET, - }, - IDE1_INTERRUPT, - }, -#endif /* IDE1_BASE_OFFSET */ -#endif /* IDE0_BASE_OFFSET */ -}; - -struct ide_timing ide_pio_clocks[6]; -int hold_time[6] = {30, 20, 15, 10, 10, 10 }; /* PIO Mode 5 with IORDY (nonstandard) */ - -/* - * Warning: only 1 (ONE) PCMCIA slot supported here, - * which must be correctly initialized by the firmware (PPCBoot). - */ -static int _slot_ = -1; /* will be read from PCMCIA registers */ - -/* Make clock cycles and always round up */ -#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U ) - -#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4)) -#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4)) - -/* - * The TQM850L hardware has two pins swapped! Grrrrgh! - */ -#ifdef CONFIG_TQM850L -#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXOE -#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXRESET -#else -#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXRESET -#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXOE -#endif - -#if defined(CONFIG_BLK_DEV_MPC8xx_IDE) && defined(CONFIG_IDE_8xx_PCCARD) -#define PCMCIA_SCHLVL IDE0_INTERRUPT /* Status Change Interrupt Level */ -static int pcmcia_schlvl = PCMCIA_SCHLVL; -#endif - -/* - * See include/linux/ide.h for definition of hw_regs_t (p, base) - */ - -/* - * m8xx_ide_init_ports() for a direct IDE interface _using_ - * MPC8xx's internal PCMCIA interface - */ -#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) -static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) -{ - unsigned long *p = hw->io_ports_array; - int i; - - typedef struct { - ulong br; - ulong or; - } pcmcia_win_t; - volatile pcmcia_win_t *win; - volatile pcmconf8xx_t *pcmp; - - uint *pgcrx; - u32 pcmcia_phy_base; - u32 pcmcia_phy_end; - static unsigned long pcmcia_base = 0; - unsigned long base; - - *p = 0; - - pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); - - if (!pcmcia_base) { - /* - * Read out PCMCIA registers. Since the reset values - * are undefined, we sure hope that they have been - * set up by firmware - */ - - /* Scan all registers for valid settings */ - pcmcia_phy_base = 0xFFFFFFFF; - pcmcia_phy_end = 0; - /* br0 is start of brX and orX regs */ - win = (pcmcia_win_t *) \ - (&(((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0)); - for (i = 0; i < 8; i++) { - if (win->or & 1) { /* This bank is marked as valid */ - if (win->br < pcmcia_phy_base) { - pcmcia_phy_base = win->br; - } - if ((win->br + PCMCIA_MEM_SIZE) > pcmcia_phy_end) { - pcmcia_phy_end = win->br + PCMCIA_MEM_SIZE; - } - /* Check which slot that has been defined */ - _slot_ = (win->or >> 2) & 1; - - } /* Valid bank */ - win++; - } /* for */ - - printk ("PCMCIA slot %c: phys mem %08x...%08x (size %08x)\n", - 'A' + _slot_, - pcmcia_phy_base, pcmcia_phy_end, - pcmcia_phy_end - pcmcia_phy_base); - - if (!request_mem_region(pcmcia_phy_base, - pcmcia_phy_end - pcmcia_phy_base, - DRV_NAME)) { - printk(KERN_ERR "%s: resources busy\n", DRV_NAME); - return -EBUSY; - } - - pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base, - pcmcia_phy_end-pcmcia_phy_base); - -#ifdef DEBUG - printk ("PCMCIA virt base: %08lx\n", pcmcia_base); -#endif - /* Compute clock cycles for PIO timings */ - for (i=0; i<6; ++i) { - bd_t *binfo = (bd_t *)__res; - struct ide_timing *t, *n; - - hold_time[i] = - PCMCIA_MK_CLKS (hold_time[i], - binfo->bi_busfreq); - - t = ide_timing_find_mode(XFER_PIO_0 + i); - n = &ide_pio_clocks[i]; - - n->setup = PCMCIA_MK_CLKS(t->setup, binfo->bi_busfreq); - n->active = PCMCIA_MK_CLKS(t->active, binfo->bi_busfreq); - n->cycle = PCMCIA_MK_CLKS(t->cycle, binfo->bi_busfreq); -#if 0 - printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n", - i, - t->setup, t->active, t->cycle, - n->setup, n->active, n->cycle); -#endif - } - } - - if (_slot_ == -1) { - printk ("PCMCIA slot has not been defined! Using A as default\n"); - _slot_ = 0; - } - -#ifdef CONFIG_IDE_8xx_PCCARD - -#ifdef DEBUG - printk ("PIPR = 0x%08X slot %c ==> mask = 0x%X\n", - pcmp->pcmc_pipr, - 'A' + _slot_, - M8XX_PCMCIA_CD1(_slot_) | M8XX_PCMCIA_CD2(_slot_) ); -#endif /* DEBUG */ - - if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) { - printk ("No card in slot %c: PIPR=%08x\n", - 'A' + _slot_, (u32) pcmp->pcmc_pipr); - return -ENODEV; /* No card in slot */ - } - - check_ide_device (pcmcia_base); - -#endif /* CONFIG_IDE_8xx_PCCARD */ - - base = pcmcia_base + ioport_dsc[data_port].base_off; -#ifdef DEBUG - printk ("base: %08x + %08x = %08x\n", - pcmcia_base, ioport_dsc[data_port].base_off, base); -#endif - - for (i = 0; i < IDE_NR_PORTS; ++i) { -#ifdef DEBUG - printk ("port[%d]: %08x + %08x = %08x\n", - i, - base, - ioport_dsc[data_port].reg_off[i], - i, base + ioport_dsc[data_port].reg_off[i]); -#endif - *p++ = base + ioport_dsc[data_port].reg_off[i]; - } - - hw->irq = ioport_dsc[data_port].irq; - hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack; - -#ifdef CONFIG_IDE_8xx_PCCARD - { - unsigned int reg; - - if (_slot_) - pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb; - else - pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcra; - - reg = *pgcrx; - reg |= mk_int_int_mask (pcmcia_schlvl) << 24; - reg |= mk_int_int_mask (pcmcia_schlvl) << 16; - *pgcrx = reg; - } -#endif /* CONFIG_IDE_8xx_PCCARD */ - - /* Enable Harddisk Interrupt, - * and make it edge sensitive - */ - /* (11-18) Set edge detect for irq, no wakeup from low power mode */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |= - (0x80000000 >> ioport_dsc[data_port].irq); - -#ifdef CONFIG_IDE_8xx_PCCARD - /* Make sure we don't get garbage irq */ - ((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF; - - /* Enable falling edge irq */ - pcmp->pcmc_per = 0x100000 >> (16 * _slot_); -#endif /* CONFIG_IDE_8xx_PCCARD */ - - hw->chipset = ide_generic; - - return 0; -} -#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ - -/* - * m8xx_ide_init_ports() for a direct IDE interface _not_ using - * MPC8xx's internal PCMCIA interface - */ -#if defined(CONFIG_IDE_EXT_DIRECT) -static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) -{ - unsigned long *p = hw->io_ports_array; - int i; - - u32 ide_phy_base; - u32 ide_phy_end; - static unsigned long ide_base = 0; - unsigned long base; - - *p = 0; - - if (!ide_base) { - - /* TODO: - * - add code to read ORx, BRx - */ - ide_phy_base = CFG_ATA_BASE_ADDR; - ide_phy_end = CFG_ATA_BASE_ADDR + 0x200; - - printk ("IDE phys mem : %08x...%08x (size %08x)\n", - ide_phy_base, ide_phy_end, - ide_phy_end - ide_phy_base); - - if (!request_mem_region(ide_phy_base, 0x200, DRV_NAME)) { - printk(KERN_ERR "%s: resources busy\n", DRV_NAME); - return -EBUSY; - } - - ide_base=(unsigned long)ioremap(ide_phy_base, - ide_phy_end-ide_phy_base); - -#ifdef DEBUG - printk ("IDE virt base: %08lx\n", ide_base); -#endif - } - - base = ide_base + ioport_dsc[data_port].base_off; -#ifdef DEBUG - printk ("base: %08x + %08x = %08x\n", - ide_base, ioport_dsc[data_port].base_off, base); -#endif - - for (i = 0; i < IDE_NR_PORTS; ++i) { -#ifdef DEBUG - printk ("port[%d]: %08x + %08x = %08x\n", - i, - base, - ioport_dsc[data_port].reg_off[i], - i, base + ioport_dsc[data_port].reg_off[i]); -#endif - *p++ = base + ioport_dsc[data_port].reg_off[i]; - } - - /* direct connected IDE drive, i.e. external IRQ */ - hw->irq = ioport_dsc[data_port].irq; - hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack; - - /* Enable Harddisk Interrupt, - * and make it edge sensitive - */ - /* (11-18) Set edge detect for irq, no wakeup from low power mode */ - ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= - (0x80000000 >> ioport_dsc[data_port].irq); - - hw->chipset = ide_generic; - - return 0; -} -#endif /* CONFIG_IDE_8xx_DIRECT */ - - -/* -------------------------------------------------------------------- */ - - -/* PCMCIA Timing */ -#ifndef PCMCIA_SHT -#define PCMCIA_SHT(t) ((t & 0x0F)<<16) /* Strobe Hold Time */ -#define PCMCIA_SST(t) ((t & 0x0F)<<12) /* Strobe Setup Time */ -#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length */ -#endif - -/* Calculate PIO timings */ -static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ -#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) - volatile pcmconf8xx_t *pcmp; - ulong timing, mask, reg; - - pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); - - mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF)); - - timing = PCMCIA_SHT(hold_time[pio] ) - | PCMCIA_SST(ide_pio_clocks[pio].setup) - | PCMCIA_SL (ide_pio_clocks[pio].active) - ; - -#if 1 - printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing); -#endif - if ((reg = pcmp->pcmc_por0 & mask) != 0) - pcmp->pcmc_por0 = reg | timing; - - if ((reg = pcmp->pcmc_por1 & mask) != 0) - pcmp->pcmc_por1 = reg | timing; - - if ((reg = pcmp->pcmc_por2 & mask) != 0) - pcmp->pcmc_por2 = reg | timing; - - if ((reg = pcmp->pcmc_por3 & mask) != 0) - pcmp->pcmc_por3 = reg | timing; - - if ((reg = pcmp->pcmc_por4 & mask) != 0) - pcmp->pcmc_por4 = reg | timing; - - if ((reg = pcmp->pcmc_por5 & mask) != 0) - pcmp->pcmc_por5 = reg | timing; - - if ((reg = pcmp->pcmc_por6 & mask) != 0) - pcmp->pcmc_por6 = reg | timing; - - if ((reg = pcmp->pcmc_por7 & mask) != 0) - pcmp->pcmc_por7 = reg | timing; - -#elif defined(CONFIG_IDE_EXT_DIRECT) - - printk("%s[%d] %s: not implemented yet!\n", - __FILE__, __LINE__, __func__); -#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */ -} - -static const struct ide_port_ops m8xx_port_ops = { - .set_pio_mode = m8xx_ide_set_pio_mode, -}; - -static void -ide_interrupt_ack (void *dev) -{ -#ifdef CONFIG_IDE_8xx_PCCARD - u_int pscr, pipr; - -#if (PCMCIA_SOCKETS_NO == 2) - u_int _slot_; -#endif - - /* get interrupt sources */ - - pscr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr; - pipr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr; - - /* - * report only if both card detect signals are the same - * not too nice done, - * we depend on that CD2 is the bit to the left of CD1... - */ - - if(_slot_==-1){ - printk("PCMCIA slot has not been defined! Using A as default\n"); - _slot_=0; - } - - if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1) ^ - (pipr & M8XX_PCMCIA_CD1(_slot_)) ) { - printk ("card detect interrupt\n"); - } - /* clear the interrupt sources */ - ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr; - -#else /* ! CONFIG_IDE_8xx_PCCARD */ - /* - * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the - * MPC8xx's PCMCIA controller, so there is nothing to be done here - * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT. - * The interrupt is handled somewhere else. -- Steven - */ -#endif /* CONFIG_IDE_8xx_PCCARD */ -} - - - -/* - * CIS Tupel codes - */ -#define CISTPL_NULL 0x00 -#define CISTPL_DEVICE 0x01 -#define CISTPL_LONGLINK_CB 0x02 -#define CISTPL_INDIRECT 0x03 -#define CISTPL_CONFIG_CB 0x04 -#define CISTPL_CFTABLE_ENTRY_CB 0x05 -#define CISTPL_LONGLINK_MFC 0x06 -#define CISTPL_BAR 0x07 -#define CISTPL_PWR_MGMNT 0x08 -#define CISTPL_EXTDEVICE 0x09 -#define CISTPL_CHECKSUM 0x10 -#define CISTPL_LONGLINK_A 0x11 -#define CISTPL_LONGLINK_C 0x12 -#define CISTPL_LINKTARGET 0x13 -#define CISTPL_NO_LINK 0x14 -#define CISTPL_VERS_1 0x15 -#define CISTPL_ALTSTR 0x16 -#define CISTPL_DEVICE_A 0x17 -#define CISTPL_JEDEC_C 0x18 -#define CISTPL_JEDEC_A 0x19 -#define CISTPL_CONFIG 0x1a -#define CISTPL_CFTABLE_ENTRY 0x1b -#define CISTPL_DEVICE_OC 0x1c -#define CISTPL_DEVICE_OA 0x1d -#define CISTPL_DEVICE_GEO 0x1e -#define CISTPL_DEVICE_GEO_A 0x1f -#define CISTPL_MANFID 0x20 -#define CISTPL_FUNCID 0x21 -#define CISTPL_FUNCE 0x22 -#define CISTPL_SWIL 0x23 -#define CISTPL_END 0xff - -/* - * CIS Function ID codes - */ -#define CISTPL_FUNCID_MULTI 0x00 -#define CISTPL_FUNCID_MEMORY 0x01 -#define CISTPL_FUNCID_SERIAL 0x02 -#define CISTPL_FUNCID_PARALLEL 0x03 -#define CISTPL_FUNCID_FIXED 0x04 -#define CISTPL_FUNCID_VIDEO 0x05 -#define CISTPL_FUNCID_NETWORK 0x06 -#define CISTPL_FUNCID_AIMS 0x07 -#define CISTPL_FUNCID_SCSI 0x08 - -/* - * Fixed Disk FUNCE codes - */ -#define CISTPL_IDE_INTERFACE 0x01 - -#define CISTPL_FUNCE_IDE_IFACE 0x01 -#define CISTPL_FUNCE_IDE_MASTER 0x02 -#define CISTPL_FUNCE_IDE_SLAVE 0x03 - -/* First feature byte */ -#define CISTPL_IDE_SILICON 0x04 -#define CISTPL_IDE_UNIQUE 0x08 -#define CISTPL_IDE_DUAL 0x10 - -/* Second feature byte */ -#define CISTPL_IDE_HAS_SLEEP 0x01 -#define CISTPL_IDE_HAS_STANDBY 0x02 -#define CISTPL_IDE_HAS_IDLE 0x04 -#define CISTPL_IDE_LOW_POWER 0x08 -#define CISTPL_IDE_REG_INHIBIT 0x10 -#define CISTPL_IDE_HAS_INDEX 0x20 -#define CISTPL_IDE_IOIS16 0x40 - - -/* -------------------------------------------------------------------- */ - - -#define MAX_TUPEL_SZ 512 -#define MAX_FEATURES 4 - -static int check_ide_device (unsigned long base) -{ - volatile u8 *ident = NULL; - volatile u8 *feature_p[MAX_FEATURES]; - volatile u8 *p, *start; - int n_features = 0; - u8 func_id = ~0; - u8 code, len; - unsigned short config_base = 0; - int found = 0; - int i; - -#ifdef DEBUG - printk ("PCMCIA MEM: %08lX\n", base); -#endif - start = p = (volatile u8 *) base; - - while ((p - start) < MAX_TUPEL_SZ) { - - code = *p; p += 2; - - if (code == 0xFF) { /* End of chain */ - break; - } - - len = *p; p += 2; -#ifdef DEBUG_PCMCIA - { volatile u8 *q = p; - printk ("\nTuple code %02x length %d\n\tData:", - code, len); - - for (i = 0; i < len; ++i) { - printk (" %02x", *q); - q+= 2; - } - } -#endif /* DEBUG_PCMCIA */ - switch (code) { - case CISTPL_VERS_1: - ident = p + 4; - break; - case CISTPL_FUNCID: - func_id = *p; - break; - case CISTPL_FUNCE: - if (n_features < MAX_FEATURES) - feature_p[n_features++] = p; - break; - case CISTPL_CONFIG: - config_base = (*(p+6) << 8) + (*(p+4)); - default: - break; - } - p += 2 * len; - } - - found = identify (ident); - - if (func_id != ((u8)~0)) { - print_funcid (func_id); - - if (func_id == CISTPL_FUNCID_FIXED) - found = 1; - else - return (1); /* no disk drive */ - } - - for (i=0; i id_str) { - if (*t == ' ') - *t = '\0'; - else - break; - } - printk ("Card ID: %s\n", id_str); - - for (card=known_cards; *card; ++card) { - if (strcmp(*card, id_str) == 0) { /* found! */ - return (1); - } - } - - return (0); /* don't know */ -} - -static int __init mpc8xx_ide_probe(void) -{ - hw_regs_t hw; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; - -#ifdef IDE0_BASE_OFFSET - memset(&hw, 0, sizeof(hw)); - if (!m8xx_ide_init_ports(&hw, 0)) { - ide_hwif_t *hwif = ide_find_port(); - - if (hwif) { - ide_init_port_hw(hwif, &hw); - hwif->pio_mask = ATA_PIO4; - hwif->port_ops = &m8xx_port_ops; - - idx[0] = hwif->index; - } - } -#ifdef IDE1_BASE_OFFSET - memset(&hw, 0, sizeof(hw)); - if (!m8xx_ide_init_ports(&hw, 1)) { - ide_hwif_t *mate = ide_find_port(); - - if (mate) { - ide_init_port_hw(mate, &hw); - mate->pio_mask = ATA_PIO4; - mate->port_ops = &m8xx_port_ops; - - idx[1] = mate->index; - } - } -#endif -#endif - - ide_device_add(idx, NULL); - - return 0; -} - -module_init(mpc8xx_ide_probe); - -MODULE_LICENSE("GPL"); -- cgit v0.10.2 From a698400a1556cf9f0376d1a41e536973dd5c4747 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:41 +0200 Subject: cmd640: fix warm-plug support for the secondary interface Register secondary interface also when user requested not to probe devices. While at it: - remove write-only second_port_toggled variable Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index baa26a2..ab7d727 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -687,9 +687,6 @@ static int cmd640x_init_one(unsigned long base, unsigned long ctl) */ static int __init cmd640x_init(void) { -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - int second_port_toggled = 0; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ int second_port_cmd640 = 0, rc; const char *bus_type, *port2; unsigned int index; @@ -778,46 +775,40 @@ static int __init cmd640x_init(void) put_cmd640_reg(CMDTIM, 0); put_cmd640_reg(BRST, 0x40); - cmd_hwif1 = ide_find_port(); + b = get_cmd640_reg(CNTRL); /* * Try to enable the secondary interface, if not already enabled */ - if (cmd_hwif1 && - cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) { - port2 = "not probed"; + if (secondary_port_responding()) { + if ((b & CNTRL_ENA_2ND)) { + second_port_cmd640 = 1; + port2 = "okay"; + } else if (cmd640_vlb) { + second_port_cmd640 = 1; + port2 = "alive"; + } else + port2 = "not cmd640"; } else { - b = get_cmd640_reg(CNTRL); + put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */ if (secondary_port_responding()) { - if ((b & CNTRL_ENA_2ND)) { - second_port_cmd640 = 1; - port2 = "okay"; - } else if (cmd640_vlb) { - second_port_cmd640 = 1; - port2 = "alive"; - } else - port2 = "not cmd640"; + second_port_cmd640 = 1; + port2 = "enabled"; } else { - put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */ - if (secondary_port_responding()) { - second_port_cmd640 = 1; -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - second_port_toggled = 1; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - port2 = "enabled"; - } else { - put_cmd640_reg(CNTRL, b); /* restore original setting */ - port2 = "not responding"; - } + put_cmd640_reg(CNTRL, b); /* restore original setting */ + port2 = "not responding"; } } /* * Initialize data for secondary cmd640 port, if enabled */ - if (second_port_cmd640 && cmd_hwif1) { - ide_init_port_hw(cmd_hwif1, &hw[1]); - idx[1] = cmd_hwif1->index; + if (second_port_cmd640) { + cmd_hwif1 = ide_find_port(); + if (cmd_hwif1) { + ide_init_port_hw(cmd_hwif1, &hw[1]); + idx[1] = cmd_hwif1->index; + } } printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n", second_port_cmd640 ? "" : "not ", port2); -- cgit v0.10.2 From e6d95bd14928926d6658b5e4ace905e8b83ed27a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: ide: ->port_init_devs -> ->init_dev Change ->port_init_devs method to take 'ide_drive_t *' as an argument instead of 'ide_hwif_t *' and rename it to ->init_dev. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 97dda05..c5dc188 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1320,10 +1320,10 @@ static void ide_port_init_devices(ide_hwif_t *hwif) drive->unmask = 1; if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) drive->no_unmask = 1; - } - if (port_ops && port_ops->port_init_devs) - port_ops->port_init_devs(hwif); + if (port_ops && port_ops->init_dev) + port_ops->init_dev(drive); + } } static void ide_init_port(ide_hwif_t *hwif, unsigned int port, diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index bd2f579..7bc8fd5 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -310,16 +310,16 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) #endif } -static void __init ht6560b_port_init_devs(ide_hwif_t *hwif) +static void __init ht6560b_init_dev(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; /* Setting default configurations for drives. */ int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT; if (hwif->channel) t |= (HT_SECONDARY_IF << 8); - hwif->drives[0].drive_data = t; - hwif->drives[1].drive_data = t; + drive->drive_data = t; } static int probe_ht6560b; @@ -328,7 +328,7 @@ module_param_named(probe, probe_ht6560b, bool, 0); MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); static const struct ide_port_ops ht6560b_port_ops = { - .port_init_devs = ht6560b_port_init_devs, + .init_dev = ht6560b_init_dev, .set_pio_mode = ht6560b_set_pio_mode, .selectproc = ht6560b_selectproc, }; diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index 5cd6ce5..89c8ff0 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/legacy/ide-4drives.c @@ -11,16 +11,14 @@ static int probe_4drives; module_param_named(probe, probe_4drives, bool, 0); MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); -static void ide_4drives_port_init_devs(ide_hwif_t *hwif) +static void ide_4drives_init_dev(ide_drive_t *drive) { - if (hwif->channel) { - hwif->drives[0].select.all ^= 0x20; - hwif->drives[1].select.all ^= 0x20; - } + if (drive->hwif->channel) + drive->select.all ^= 0x20; } static const struct ide_port_ops ide_4drives_port_ops = { - .port_init_devs = ide_4drives_port_init_devs, + .init_dev = ide_4drives_init_dev, }; static const struct ide_port_info ide_4drives_port_info = { diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 63f6c31..2338f34 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -282,17 +282,18 @@ static int __init qd_testreg(int port) return (readreg != QD_TESTVAL); } -static void __init qd6500_port_init_devs(ide_hwif_t *hwif) +static void __init qd6500_init_dev(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; u8 base = (hwif->config_data & 0xff00) >> 8; u8 config = QD_CONFIG(hwif); - hwif->drives[0].drive_data = QD6500_DEF_DATA; - hwif->drives[1].drive_data = QD6500_DEF_DATA; + drive->drive_data = QD6500_DEF_DATA; } -static void __init qd6580_port_init_devs(ide_hwif_t *hwif) +static void __init qd6580_init_dev(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; u16 t1, t2; u8 base = (hwif->config_data & 0xff00) >> 8; u8 config = QD_CONFIG(hwif); @@ -303,18 +304,17 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif) } else t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; - hwif->drives[0].drive_data = t1; - hwif->drives[1].drive_data = t2; + drive->drive_data = drive->select.b.unit ? t2 : t1; } static const struct ide_port_ops qd6500_port_ops = { - .port_init_devs = qd6500_port_init_devs, + .init_dev = qd6500_init_dev, .set_pio_mode = qd6500_set_pio_mode, .selectproc = qd65xx_select, }; static const struct ide_port_ops qd6580_port_ops = { - .port_init_devs = qd6580_port_init_devs, + .init_dev = qd6580_init_dev, .set_pio_mode = qd6580_set_pio_mode, .selectproc = qd65xx_select, }; diff --git a/include/linux/ide.h b/include/linux/ide.h index a6a2ecc..f9cbe93 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -405,8 +405,8 @@ typedef struct ide_drive_s { struct ide_port_info; struct ide_port_ops { - /* host specific initialization of devices on a port */ - void (*port_init_devs)(struct hwif_s *); + /* host specific initialization of a device */ + void (*init_dev)(ide_drive_t *); /* routine to program host for PIO mode */ void (*set_pio_mode)(ide_drive_t *, const u8); /* routine to program host for DMA mode */ -- cgit v0.10.2 From b48c89a9699f451e4e236fa7313461281c00e69b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: cmd640: add ->init_dev method Convert the driver to use ->init_dev method instead of open-coding devices init in cmd640x_init(). While at it: - fix printk()-s to use KERN_INFO level instead of the default KERN_ERR - use DRV_NAME define in printk()-s - set proper ->pio_mask also for CONFIG_BLK_DEV_CMD640_ENHANCED=n There should be no functional changes caused by this patch (except fixing printk()-s levels). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index ab7d727..1ad1e23 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -611,11 +611,40 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) display_clocks(index); } +#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ + +static void cmd640_init_dev(ide_drive_t *drive) +{ + unsigned int i = drive->hwif->channel * 2 + drive->select.b.unit; + +#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED + /* + * Reset timing to the slowest speed and turn off prefetch. + * This way, the drive identify code has a better chance. + */ + setup_counts[i] = 4; /* max possible */ + active_counts[i] = 16; /* max possible */ + recovery_counts[i] = 16; /* max possible */ + program_drive_counts(drive, i); + set_prefetch_mode(drive, i, 0); + printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i); +#else + /* + * Set the drive unmask flags to match the prefetch setting. + */ + check_prefetch(drive, i); + printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n", + i, drive->no_io_32bit ? "off" : "on"); +#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ +} + static const struct ide_port_ops cmd640_port_ops = { + .init_dev = cmd640_init_dev, +#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED .set_pio_mode = cmd640_set_pio_mode, +#endif }; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ static int pci_conf1(void) { @@ -658,10 +687,8 @@ static const struct ide_port_info cmd640_port_info __initdata = { IDE_HFLAG_NO_DMA | IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_ABUSE_FAST_DEVSEL, -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED .port_ops = &cmd640_port_ops, .pio_mask = ATA_PIO5, -#endif }; static int cmd640x_init_one(unsigned long base, unsigned long ctl) @@ -689,7 +716,6 @@ static int __init cmd640x_init(void) { int second_port_cmd640 = 0, rc; const char *bus_type, *port2; - unsigned int index; u8 b, cfr; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; hw_regs_t hw[2]; @@ -813,44 +839,6 @@ static int __init cmd640x_init(void) printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n", second_port_cmd640 ? "" : "not ", port2); - /* - * Establish initial timings/prefetch for all drives. - * Do not unnecessarily disturb any prior BIOS setup of these. - */ - for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) { - ide_drive_t *drive; - - if (index > 1) { - if (cmd_hwif1 == NULL) - continue; - drive = &cmd_hwif1->drives[index & 1]; - } else { - if (cmd_hwif0 == NULL) - continue; - drive = &cmd_hwif0->drives[index & 1]; - } - -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - /* - * Reset timing to the slowest speed and turn off prefetch. - * This way, the drive identify code has a better chance. - */ - setup_counts [index] = 4; /* max possible */ - active_counts [index] = 16; /* max possible */ - recovery_counts [index] = 16; /* max possible */ - program_drive_counts(drive, index); - set_prefetch_mode(drive, index, 0); - printk("cmd640: drive%d timings/prefetch cleared\n", index); -#else - /* - * Set the drive unmask flags to match the prefetch setting - */ - check_prefetch(drive, index); - printk("cmd640: drive%d timings/prefetch(%s) preserved\n", - index, drive->no_io_32bit ? "off" : "on"); -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - } - #ifdef CMD640_DUMP_REGS cmd640_dump_regs(); #endif -- cgit v0.10.2 From 9a5ae1faaaf43933dee48c223b193d5e1c4b8b0c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: rapide: use struct ide_port_info Convert the driver to use struct ide_port_info. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index 1747b23..bb081ad 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c @@ -11,6 +11,10 @@ #include +static struct const ide_port_info rapide_port_info = { + .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, +}; + static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq) { @@ -53,12 +57,11 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) ide_init_port_hw(hwif, &hw); - hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); idx[0] = hwif->index; - ide_device_add(idx, NULL); + ide_device_add(idx, &rapide_port_info); ecard_set_drvdata(ec, hwif); goto out; -- cgit v0.10.2 From f81eb80bbb949f9498980c785ef7dd4c994a4909 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: ide-h8300: use struct ide_port_info Convert the driver to use struct ide_port_info. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index dfce105..ff6a98a 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -176,6 +176,10 @@ static inline void hwif_setup(ide_hwif_t *hwif) hwif->output_data = h8300_output_data; } +static const struct ide_port_info h8300_port_info = { + .host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA, +}; + static int __init h8300_ide_init(void) { hw_regs_t hw; @@ -201,12 +205,11 @@ static int __init h8300_ide_init(void) index = hwif->index; ide_init_port_hw(hwif, &hw); hwif_setup(hwif); - hwif->host_flags = IDE_HFLAG_NO_IO_32BIT; printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index); idx[0] = index; - ide_device_add(idx, NULL); + ide_device_add(idx, &h8300_port_info); return 0; -- cgit v0.10.2 From 7b60fa16ca50b0f8cb9d007faee0dff71b397fb8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: ide_platform: use struct ide_port_info Convert the driver to use struct ide_port_info. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index d3bc3f2..a249562 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c @@ -44,6 +44,10 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw, hw->chipset = ide_generic; } +static const struct ide_port_info platform_ide_port_info = { + .host_flags = IDE_HFLAG_NO_DMA, +}; + static int __devinit plat_ide_probe(struct platform_device *pdev) { struct resource *res_base, *res_alt, *res_irq; @@ -54,6 +58,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) int ret = 0; int mmio = 0; hw_regs_t hw; + struct ide_port_info d = platform_ide_port_info; pdata = pdev->dev.platform_data; @@ -102,13 +107,13 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) ide_init_port_hw(hwif, &hw); if (mmio) { - hwif->host_flags = IDE_HFLAG_MMIO; + d.host_flags |= IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); } idx[0] = hwif->index; - ide_device_add(idx, NULL); + ide_device_add(idx, &d); platform_set_drvdata(pdev, hwif); -- cgit v0.10.2 From eb3aff5530d22eb4be0a99c9d39c9ffde7b9891a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:42 +0200 Subject: ide: print message on error in ide_find_port_slot() * Add DRV_NAME define to ide-h8300.c. * Fix ide-h8300.c, swarm.c and sgiioc4.c to set .name field in struct ide_port_info to DRV_NAME, then convert these host drivers to use ide_find_port_slot() instead of ide_find_port(). * Print message on error in ide_find_port_slot(). Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index ff6a98a..c445298 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -8,6 +8,8 @@ #include #include +#define DRV_NAME "ide-h8300" + #define bswap(d) \ ({ \ u16 r; \ @@ -196,11 +198,9 @@ static int __init h8300_ide_init(void) hw_setup(&hw); - hwif = ide_find_port(); - if (hwif == NULL) { - printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); + hwif = ide_find_port_slot(&h8300_port_info); + if (hwif == NULL) return -ENOENT; - } index = hwif->index; ide_init_port_hw(hwif, &hw); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index c5dc188..235ebdb 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1490,6 +1490,9 @@ ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d) } } + printk(KERN_ERR "%s: no free slot for interface\n", + d ? d->name : "ide"); + return NULL; out_found: diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 57a0138..bae92ac 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -62,6 +62,7 @@ static struct resource swarm_ide_resource = { static struct platform_device *swarm_ide_dev; static const struct ide_port_info swarm_port_info = { + .name = DRV_NAME, .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, }; @@ -81,11 +82,9 @@ static int __devinit swarm_ide_probe(struct device *dev) if (!SIBYTE_HAVE_IDE) return -ENODEV; - hwif = ide_find_port(); - if (hwif == NULL) { - printk(KERN_ERR DRV_NAME ": no free slot for interface\n"); + hwif = ide_find_port_slot(&swarm_port_info); + if (hwif == NULL) return -ENOMEM; - } base = ioremap(A_IO_EXT_BASE, 0x800); offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 71bff31..789c66d 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -558,12 +558,9 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; int i; - hwif = ide_find_port(); - if (hwif == NULL) { - printk(KERN_ERR "%s: too many IDE interfaces, " - "no room in table\n", SCC_PATA_NAME); + hwif = ide_find_port_slot(d); + if (hwif == NULL) return -ENOMEM; - } memset(&hw, 0, sizeof(hw)); for (i = 0; i <= 8; i++) diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index dd0d0f7..be73acb 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -568,6 +568,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = { }; static const struct ide_port_info sgiioc4_port_info __devinitdata = { + .name = DRV_NAME, .chipset = ide_pci, .init_dma = ide_dma_sgiioc4, .port_ops = &sgiioc4_port_ops, @@ -587,12 +588,9 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) hw_regs_t hw; struct ide_port_info d = sgiioc4_port_info; - hwif = ide_find_port(); - if (hwif == NULL) { - printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", - DRV_NAME); + hwif = ide_find_port_slot(&d); + if (hwif == NULL) return -ENOMEM; - } /* Get the CmdBlk and CtrlBlk Base Registers */ bar0 = pci_resource_start(dev, 0); diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 166211f..4321d20 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -332,11 +332,8 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, } hwif = ide_find_port_slot(d); - if (hwif == NULL) { - printk(KERN_ERR "%s: too many IDE interfaces, no room in " - "table\n", d->name); + if (hwif == NULL) return NULL; - } memset(&hw, 0, sizeof(hw)); hw.irq = irq; -- cgit v0.10.2 From 740c397cc64272917a4c4c283649579d2044a836 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: ide-h8300: print driver banner message early Print driver banner message early and without interface number. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index c445298..20fad6d 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -189,6 +189,8 @@ static int __init h8300_ide_init(void) int index; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; + printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n"); + if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) goto out_busy; if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) { @@ -205,7 +207,6 @@ static int __init h8300_ide_init(void) index = hwif->index; ide_init_port_hw(hwif, &hw); hwif_setup(hwif); - printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index); idx[0] = index; -- cgit v0.10.2 From e193c3e141df4b536ed077b29c83a96768333607 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: ide-pnp: print driver banner message early Print driver banner message early and without interface number. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index fc1e10c..03f2ef5 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c @@ -33,6 +33,8 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) ide_hwif_t *hwif; unsigned long base, ctl; + printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n"); + if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) return -1; @@ -64,7 +66,6 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) ide_init_port_hw(hwif, &hw); - printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); pnp_set_drvdata(dev, hwif); ide_device_add(idx, NULL); -- cgit v0.10.2 From 07fe69d5d0b6e476cecaf75e81c0c6093571087b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: ide: allow any command requesting DMA data phase for HDIO_DRIVE_TASKFILE Allow any command requesting DMA data phase for HDIO_DRIVE_TASKFILE ioctl and remove no longer needed task_dma_ok() Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index cf55a48..994a516 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -62,25 +62,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) return ide_raw_taskfile(drive, &args, buf, 1); } -static int inline task_dma_ok(ide_task_t *task) -{ - if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED)) - return 1; - - switch (task->tf.command) { - case WIN_WRITEDMA_ONCE: - case WIN_WRITEDMA: - case WIN_WRITEDMA_EXT: - case WIN_READDMA_ONCE: - case WIN_READDMA: - case WIN_READDMA_EXT: - case WIN_IDENTIFY_DMA: - return 1; - } - - return 0; -} - static ide_startstop_t task_no_data_intr(ide_drive_t *); static ide_startstop_t set_geometry_intr(ide_drive_t *); static ide_startstop_t recal_intr(ide_drive_t *); @@ -139,8 +120,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) WAIT_WORSTCASE, NULL); return ide_started; default: - if (task_dma_ok(task) == 0 || drive->using_dma == 0 || - dma_ops->dma_setup(drive)) + if (drive->using_dma == 0 || dma_ops->dma_setup(drive)) return ide_stopped; dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_start(drive); -- cgit v0.10.2 From 605cfe8270cb182f494575c5a608404bb19fdfc5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: ide: remove superfluous BUG_ON() from set_geometry_intr() ide_set_handler() bugs on ->handler == NULL so no need to do it in set_geometry_intr(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 994a516..0d0bf29 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -163,7 +163,6 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive) if (stat & (ERR_STAT|DRQ_STAT)) return ide_error(drive, "set_geometry_intr", stat); - BUG_ON(HWGROUP(drive)->handler != NULL); ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); return ide_started; } -- cgit v0.10.2 From 61729415e64a1149d4eb36c3fac26a28728ad1d7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:43 +0200 Subject: ide: remove needless includes from ide.c Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9240888..90ae00d 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -50,29 +50,16 @@ #include #include #include -#include -#include #include #include #include #include -#include #include #include #include -#include #include #include -#include -#include -#include #include -#include - -#include -#include -#include -#include /* default maximum number of failures */ -- cgit v0.10.2 From ad15e9fc8913b704978ffdda7d1f31c79ed6814d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: ide: remove needless includes from ide-taskfile.c (take 2) v2: On Sunday 15 June 2008, Geert Uytterhoeven wrote: > As ide-taskfile.c uses scatterlists, it should include . (v1 broke IDE build on m68k, thanks to Geert for finding the bug) Cc: Geert Uytterhoeven Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0d0bf29..1fbdb74 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -8,28 +8,18 @@ * The big the bad and the ugly. */ -#include #include #include #include -#include -#include #include #include -#include #include -#include -#include #include -#include #include #include #include -#include #include -#include -#include #include #include -- cgit v0.10.2 From ff23712e791fd80f3b088d5e1c5733c0944cfe64 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: ide: remove needless includes from setup-pci.c (take 2) v2: * sparc build fix. (From Stephen Rothwell) Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 4321d20..65fc08b 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -6,19 +6,15 @@ * May be copied or modified under the terms of the GNU General Public License */ -#include #include #include #include #include -#include -#include #include #include #include #include -#include /** * ide_setup_pci_baseregs - place a PCI IDE controller native -- cgit v0.10.2 From 47bc7e7425d198ad1f8c4597b0bf28619fcce0fd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: rapide: fix rapide_probe() return value Return -ENOENT on ide_find_port() failure. While at it: - Cleanup rapide_probe() a bit. Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index bb081ad..43057e0 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c @@ -48,24 +48,26 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) goto release; } - hwif = ide_find_port(); - if (hwif) { - memset(&hw, 0, sizeof(hw)); - rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq); - hw.chipset = ide_generic; - hw.dev = &ec->dev; + memset(&hw, 0, sizeof(hw)); + rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq); + hw.chipset = ide_generic; + hw.dev = &ec->dev; - ide_init_port_hw(hwif, &hw); + hwif = ide_find_port(); + if (hwif == NULL) { + ret = -ENOENT; + goto release; + } - default_hwif_mmiops(hwif); + ide_init_port_hw(hwif, &hw); + default_hwif_mmiops(hwif); - idx[0] = hwif->index; + idx[0] = hwif->index; - ide_device_add(idx, &rapide_port_info); + ide_device_add(idx, &rapide_port_info); - ecard_set_drvdata(ec, hwif); - goto out; - } + ecard_set_drvdata(ec, hwif); + goto out; release: ecard_release_resources(ec); -- cgit v0.10.2 From 67717e224181527987cce800fa2ddb5c8c1e9315 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: icside: always try to probe first interface Try to probe first interface even if ide_hwifs[]'s slot for the second interface cannot be obtained. While at it: - Add DRV_NAME define and use it for request_dma() instead of hwif->name. Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index c8d8600..52f58c8 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -21,6 +21,8 @@ #include #include +#define DRV_NAME "icside" + #define ICS_IDENT_OFFSET 0x2280 #define ICS_ARCIN_V5_INTRSTAT 0x0000 @@ -546,27 +548,27 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) ide_init_port_hw(hwif, &hw[0]); default_hwif_mmiops(hwif); + idx[0] = hwif->index; + mate = ide_find_port(); - if (mate == NULL) - return -ENODEV; + if (mate) { + ide_init_port_hw(mate, &hw[1]); + default_hwif_mmiops(mate); - ide_init_port_hw(mate, &hw[1]); - default_hwif_mmiops(mate); + idx[1] = mate->index; + } state->hwif[0] = hwif; state->hwif[1] = mate; ecard_set_drvdata(ec, state); - if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) { + if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { d.init_dma = icside_dma_init; d.port_ops = &icside_v6_port_ops; d.dma_ops = NULL; } - idx[0] = hwif->index; - idx[1] = mate->index; - ide_device_add(idx, &d); return 0; -- cgit v0.10.2 From cb8ea0929c9cb899d61c4e155aace0b34d8cffe3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: swarm: call ide_find_port_slot() later Move ide_find_port_slot() call closer to ide_device_add(). This is basically a preparation for the future changes. Cc: Maciej W. Rozycki Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index bae92ac..9f1212c 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -82,10 +82,6 @@ static int __devinit swarm_ide_probe(struct device *dev) if (!SIBYTE_HAVE_IDE) return -ENODEV; - hwif = ide_find_port_slot(&swarm_port_info); - if (hwif == NULL) - return -ENOMEM; - base = ioremap(A_IO_EXT_BASE, 0x800); offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); @@ -112,9 +108,6 @@ static int __devinit swarm_ide_probe(struct device *dev) base = ioremap(offset, size); - /* Setup MMIO ops. */ - default_hwif_mmiops(hwif); - for (i = 0; i <= 7; i++) hw.io_ports_array[i] = (unsigned long)(base + ((0x1f0 + i) << 5)); @@ -123,8 +116,15 @@ static int __devinit swarm_ide_probe(struct device *dev) hw.irq = K_INT_GB_IDE; hw.chipset = ide_generic; + hwif = ide_find_port_slot(&swarm_port_info); + if (hwif == NULL) + goto err; + ide_init_port_hw(hwif, &hw); + /* Setup MMIO ops. */ + default_hwif_mmiops(hwif); + idx[0] = hwif->index; ide_device_add(idx, &swarm_port_info); @@ -132,6 +132,10 @@ static int __devinit swarm_ide_probe(struct device *dev) dev_set_drvdata(dev, hwif); return 0; +err: + release_resource(&swarm_ide_resource); + iounmap(base); + return -ENOMEM; } static struct device_driver swarm_ide_driver = { -- cgit v0.10.2 From ce30e4015954e281f682aa8d158a47885d8e1262 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 16 Jul 2008 20:33:44 +0200 Subject: sgiioc4: call ide_find_port_slot() later Move ide_find_port_slot() call closer to ide_device_add(). This is basically a preparation for the future changes. Cc: Jeremy Higdon Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index be73acb..c79ff5b 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -588,10 +588,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) hw_regs_t hw; struct ide_port_info d = sgiioc4_port_info; - hwif = ide_find_port_slot(&d); - if (hwif == NULL) - return -ENOMEM; - /* Get the CmdBlk and CtrlBlk Base Registers */ bar0 = pci_resource_start(dev, 0); virt_base = ioremap(bar0, pci_resource_len(dev, 0)); @@ -621,6 +617,11 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) hw.irq = dev->irq; hw.chipset = ide_pci; hw.dev = &dev->dev; + + hwif = ide_find_port_slot(&d); + if (hwif == NULL) + goto err; + ide_init_port_hw(hwif, &hw); /* The IOC4 uses MMIO rather than Port IO. */ @@ -637,6 +638,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) return -EIO; return 0; +err: + release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE); + iounmap(virt_base); + return -ENOMEM; } static unsigned int __devinit -- cgit v0.10.2 From af6765ce9f535f20e6f9975269660fe49594745a Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: ide-cd: remove wait-for-idle-controller bit in cdrom_start_packet_command This is done in the request issue path anyway. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index e12d602..eb4b275 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -517,14 +517,9 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, int xferlen, ide_handler_t *handler) { - ide_startstop_t startstop; struct cdrom_info *info = drive->driver_data; ide_hwif_t *hwif = drive->hwif; - /* wait for the controller to be idle */ - if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY)) - return startstop; - /* FIXME: for Virtual DMA we must check harder */ if (info->dma) info->dma = !hwif->dma_ops->dma_setup(drive); -- cgit v0.10.2 From ae8789f034ffa077105575817ec0cc581fd18d83 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: ide-cd: remove ide_cd_drain_data and ide_cd_pad_transfer Use the generic ide_pad_transfer() helper instead. [bart: fixup ide_cd_drain_data() -> ide_pad_transfer() conversion] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index eb4b275..789b19c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -599,28 +599,6 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, } /* - * Block read functions. - */ -static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len) -{ - while (len > 0) { - int dum = 0; - xf(drive, NULL, &dum, sizeof(dum)); - len -= sizeof(dum); - } -} - -static void ide_cd_drain_data(ide_drive_t *drive, int nsects) -{ - while (nsects > 0) { - static char dum[SECTOR_SIZE]; - - drive->hwif->input_data(drive, NULL, dum, sizeof(dum)); - nsects--; - } -} - -/* * Check the contents of the interrupt reason register from the cdrom * and attempt to recover if there are problems. Returns 0 if everything's * ok; nonzero if the request has been terminated. @@ -635,15 +613,12 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, if (ireason == (!rw << 1)) return 0; else if (ireason == (rw << 1)) { - ide_hwif_t *hwif = drive->hwif; - xfer_func_t *xf; /* whoops... */ printk(KERN_ERR "%s: %s: wrong transfer direction!\n", drive->name, __func__); - xf = rw ? hwif->output_data : hwif->input_data; - ide_cd_pad_transfer(drive, xf, len); + ide_pad_transfer(drive, rw, len); } else if (rw == 0 && ireason == 1) { /* * Some drives (ASUS) seem to tell us that status info is @@ -1006,7 +981,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) - bio_cur_sectors(rq->bio), thislen >> 9); if (nskip > 0) { - ide_cd_drain_data(drive, nskip); + ide_pad_transfer(drive, write, nskip << 9); rq->current_nr_sectors -= nskip; thislen -= (nskip << 9); } @@ -1043,7 +1018,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) * If the buffers are full, pipe the rest into * oblivion. */ - ide_cd_drain_data(drive, thislen >> 9); + ide_pad_transfer(drive, 0, thislen); else { printk(KERN_ERR "%s: confused, missing data\n", drive->name); @@ -1091,7 +1066,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) /* pad, if necessary */ if (!blk_fs_request(rq) && len > 0) - ide_cd_pad_transfer(drive, xferfunc, len); + ide_pad_transfer(drive, write, len); if (blk_pc_request(rq)) { timeout = rq->timeout; -- cgit v0.10.2 From ab9d6e3374d938cf3d941fbed5ba32a19ad263b8 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: ide-cd: ide_do_rw_cdrom: add the catch-all bad request case to the if-else block There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 789b19c..6ade498 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1235,11 +1235,11 @@ static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, /* right now this can only be a reset... */ cdrom_end_request(drive, 1); return ide_stopped; + } else { + blk_dump_rq_flags(rq, "ide-cd bad flags"); + cdrom_end_request(drive, 0); + return ide_stopped; } - - blk_dump_rq_flags(rq, "ide-cd bad flags"); - cdrom_end_request(drive, 0); - return ide_stopped; } -- cgit v0.10.2 From 8ea1d17b962c35401fe26428e25c4652023e2652 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: ide-cd: cdrom_start_seek: remove unused argument block There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 6ade498..ff98222 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -753,7 +753,7 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); } -static ide_startstop_t cdrom_start_seek(ide_drive_t *drive, unsigned int block) +static ide_startstop_t cdrom_start_seek(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; @@ -1223,7 +1223,7 @@ static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) - action = cdrom_start_seek(drive, block); + action = cdrom_start_seek(drive); else action = cdrom_start_rw(drive, rq); info->last_block = block; -- cgit v0.10.2 From 99384aeafe3a78d8a2e66b09b67aa6a219cd7897 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:45 +0200 Subject: ide-cd: mv ide_do_rw_cdrom ide_cd_do_request There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ff98222..a9be4bf 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1197,7 +1197,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) /* * cdrom driver request routine. */ -static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, +static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { ide_startstop_t action; @@ -1936,7 +1936,7 @@ static ide_driver_t ide_cdrom_driver = { .version = IDECD_VERSION, .media = ide_cdrom, .supports_dsc_overlap = 1, - .do_request = ide_do_rw_cdrom, + .do_request = ide_cd_do_request, .end_request = ide_end_request, .error = __ide_error, .abort = __ide_abort, -- cgit v0.10.2 From b6ca440a8ff15e12478ea6f026a52970e7a0c54c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: ide-cd: simplify request issuing path Call cdrom_start_packet_command() only from the ->do_request() routine. As a nice side effect, this improves code readability a bit. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index a9be4bf..b61ce5e 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -753,14 +753,12 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); } -static ide_startstop_t cdrom_start_seek(ide_drive_t *drive) +static void cdrom_start_seek(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; info->dma = 0; info->start_seek = jiffies; - return cdrom_start_packet_command(drive, 0, - cdrom_start_seek_continuation); } /* @@ -1135,8 +1133,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) if (write) cd->devinfo.media_written = 1; - /* start sending the read/write request to the drive */ - return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont); + return ide_started; } static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) @@ -1149,7 +1146,7 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); } -static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) +static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { struct cdrom_info *info = drive->driver_data; @@ -1188,10 +1185,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) ((unsigned long)current->stack & stack_mask))) info->dma = 0; } - - /* start sending the command to the drive */ - return cdrom_start_packet_command(drive, rq->data_len, - cdrom_do_newpc_cont); } /* @@ -1200,8 +1193,9 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { - ide_startstop_t action; struct cdrom_info *info = drive->driver_data; + ide_handler_t *fn; + int xferlen; if (blk_fs_request(rq)) { if (info->cd_flags & IDE_CD_FLAG_SEEKING) { @@ -1221,16 +1215,23 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, } if (rq_data_dir(rq) == READ && IDE_LARGE_SEEK(info->last_block, block, - IDECD_SEEK_THRESHOLD) && - drive->dsc_overlap) - action = cdrom_start_seek(drive); - else - action = cdrom_start_rw(drive, rq); + IDECD_SEEK_THRESHOLD) && + drive->dsc_overlap) { + xferlen = 0; + fn = cdrom_start_seek_continuation; + cdrom_start_seek(drive); + } else { + xferlen = 32768; + fn = cdrom_start_rw_cont; + if (cdrom_start_rw(drive, rq) == ide_stopped) + return ide_stopped; + } info->last_block = block; - return action; } else if (blk_sense_request(rq) || blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { - return cdrom_do_block_pc(drive, rq); + xferlen = rq->data_len; + fn = cdrom_do_newpc_cont; + cdrom_do_block_pc(drive, rq); } else if (blk_special_request(rq)) { /* right now this can only be a reset... */ cdrom_end_request(drive, 1); @@ -1240,6 +1241,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, cdrom_end_request(drive, 0); return ide_stopped; } + + return cdrom_start_packet_command(drive, xferlen, fn); } -- cgit v0.10.2 From 4b01fcbbe69bba34a8494fca6376ac0804f0f51d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: ide-cd: fold cdrom_start_seek into ide_cd_do_request Do what the compiler does anyway: inline a function that is used only once. This saves us the overhead of a function call and the function is small enough to be embedded in the callsite anyways. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index b61ce5e..66d82c1 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -753,14 +753,6 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); } -static void cdrom_start_seek(ide_drive_t *drive) -{ - struct cdrom_info *info = drive->driver_data; - - info->dma = 0; - info->start_seek = jiffies; -} - /* * Fix up a possibly partially-processed request so that we can start it over * entirely, or even put it back on the request queue. @@ -1219,7 +1211,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, drive->dsc_overlap) { xferlen = 0; fn = cdrom_start_seek_continuation; - cdrom_start_seek(drive); + info->dma = 0; + info->start_seek = jiffies; } else { xferlen = 32768; fn = cdrom_start_rw_cont; -- cgit v0.10.2 From e529c6087a845e64a6a36a2d17b8754b20bc7c0d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: ide-cd: move request prep from cdrom_start_seek_continuation to rq issue path ... by factoring out the rq preparation code into a separate function called in the request routine. As a nice side effect, this minimizes the IRQ handler execution time. There should be no functionality change resulting from this patch. [bart: s/HWGROUP()/drive->hwif->hwgroup/ and remove extra newlines] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 66d82c1..275d5ba 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -738,9 +738,8 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) return ide_stopped; } -static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) +static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq) { - struct request *rq = HWGROUP(drive)->rq; sector_t frame = rq->sector; sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS); @@ -750,6 +749,12 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]); rq->timeout = ATAPI_WAIT_PC; +} + +static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) +{ + struct request *rq = drive->hwif->hwgroup->rq; + return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); } @@ -1211,8 +1216,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, drive->dsc_overlap) { xferlen = 0; fn = cdrom_start_seek_continuation; + info->dma = 0; info->start_seek = jiffies; + + ide_cd_prepare_seek_request(drive, rq); } else { xferlen = 32768; fn = cdrom_start_rw_cont; -- cgit v0.10.2 From 90eb808e0fd3cbda8a8b085238930c533f603642 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: ide-cd: move request prep from cdrom_start_rw_cont to rq issue path ... by factoring out the rq preparation code into a separate function called in the request routine. As a nice side effect, this minimizes the IRQ handler execution time. There should be no functionality change resulting from this patch. [bart: s/HWGROUP()/drive->hwif->hwgroup/ and remove extra newline] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 275d5ba..9e593ce 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -666,16 +666,9 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); -/* - * Routine to send a read/write packet command to the drive. This is usually - * called directly from cdrom_start_{read,write}(). However, for drq_interrupt - * devices, it is called from an interrupt when the drive is ready to accept - * the command. - */ -static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) +static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, + struct request *rq) { - struct request *rq = HWGROUP(drive)->rq; - if (rq_data_dir(rq) == READ) { unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; @@ -712,6 +705,19 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) /* set up the command */ rq->timeout = ATAPI_WAIT_PC; + return ide_started; +} + +/* + * Routine to send a read/write packet command to the drive. This is usually + * called directly from cdrom_start_{read,write}(). However, for drq_interrupt + * devices, it is called from an interrupt when the drive is ready to accept + * the command. + */ +static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) +{ + struct request *rq = drive->hwif->hwgroup->rq; + /* send the command to the drive and return */ return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); } @@ -1224,8 +1230,12 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, } else { xferlen = 32768; fn = cdrom_start_rw_cont; + if (cdrom_start_rw(drive, rq) == ide_stopped) return ide_stopped; + + if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped) + return ide_stopped; } info->last_block = block; } else if (blk_sense_request(rq) || blk_pc_request(rq) || -- cgit v0.10.2 From 7fcebda501681080a242733b8db3f09f5ccb5d3f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: ide-cd: move request prep chunk from cdrom_do_newpc_cont to rq issue path As a nice side effect, this minimizes the IRQ handler execution time. There should be no functionality change resulting from this patch. [bart: remove extra newlines from ide_cd_do_request()] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 9e593ce..2b3c69d 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1143,9 +1143,6 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - if (!rq->timeout) - rq->timeout = ATAPI_WAIT_PC; - return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); } @@ -1242,6 +1239,10 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, rq->cmd_type == REQ_TYPE_ATA_PC) { xferlen = rq->data_len; fn = cdrom_do_newpc_cont; + + if (!rq->timeout) + rq->timeout = ATAPI_WAIT_PC; + cdrom_do_block_pc(drive, rq); } else if (blk_special_request(rq)) { /* right now this can only be a reset... */ @@ -1256,8 +1257,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return cdrom_start_packet_command(drive, xferlen, fn); } - - /* * Ioctl handling. * -- cgit v0.10.2 From c96a7df8dba5800c03b0f1edd87b2f3d0473a119 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:46 +0200 Subject: ide-floppy: fold idefloppy_create_test_unit_ready_cmd into idefloppy_open There's no need for this function since it is used only once. [bart: ported it over IDE changes] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index b368943..df19ede 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -561,12 +561,6 @@ static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start) pc->c[4] = start; } -static void idefloppy_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) -{ - idefloppy_init_pc(pc); - pc->c[0] = GPCMD_TEST_UNIT_READY; -} - static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, struct ide_atapi_pc *pc, struct request *rq, unsigned long sector) @@ -1166,7 +1160,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp) floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; /* Just in case */ - idefloppy_create_test_unit_ready_cmd(&pc); + idefloppy_init_pc(&pc); + pc.c[0] = GPCMD_TEST_UNIT_READY; + if (idefloppy_queue_pc_tail(drive, &pc)) { idefloppy_create_start_stop_cmd(&pc, 1); (void) idefloppy_queue_pc_tail(drive, &pc); -- cgit v0.10.2 From 68dc3575e064a5655cbd656fbf32d6ceeb85ac9e Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: ide-floppy: zero out the whole struct ide_atapi_pc on init This is a precaution just to make sure a new pc is clean when allocated. There should be no functional change introduced by this patch. [bart: ported it over IDE changes] Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index df19ede..00948c3 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -351,10 +351,7 @@ static void ide_floppy_callback(ide_drive_t *drive) static void idefloppy_init_pc(struct ide_atapi_pc *pc) { - memset(pc->c, 0, 12); - pc->retries = 0; - pc->flags = 0; - pc->req_xfer = 0; + memset(pc, 0, sizeof(*pc)); pc->buf = pc->pc_buf; pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; pc->callback = ide_floppy_callback; -- cgit v0.10.2 From 85ae98a3dff2da860a4f8f9e4a0de69ad82ce633 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: ide: endian annotations in ide-floppy.c Signed-off-by: Harvey Harrison Cc: Al Viro Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 00948c3..c7e4433 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -702,10 +702,10 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) set_disk_ro(floppy->disk, floppy->wp); page = &pc.buf[8]; - transfer_rate = be16_to_cpu(*(u16 *)&pc.buf[8 + 2]); - sector_size = be16_to_cpu(*(u16 *)&pc.buf[8 + 6]); - cyls = be16_to_cpu(*(u16 *)&pc.buf[8 + 8]); - rpm = be16_to_cpu(*(u16 *)&pc.buf[8 + 28]); + transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]); + sector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]); + cyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]); + rpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]); heads = pc.buf[8 + 4]; sectors = pc.buf[8 + 5]; @@ -780,8 +780,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) for (i = 0; i < desc_cnt; i++) { unsigned int desc_start = 4 + i*8; - blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]); - length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]); + blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); + length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n", i, blocks * length / 1024, blocks, length); @@ -902,8 +902,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) if (u_index >= u_array_size) break; /* User-supplied buffer too small */ - blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]); - length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]); + blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); + length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); if (put_user(blocks, argp)) return(-EFAULT); -- cgit v0.10.2 From ffa793f9bb5b563edb4cacc43a4d6677eec0e36b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: remove BLK_DEV_HD_ONLY After commit 80aa31cb460d12c1e02327b43eceb3eebc6e7090 (ide: remove CONFIG_BLK_DEV_HD_IDE config option (take 2)) the indirection through BLK_DEV_HD_ONLY is no longer required. Signed-off-by: Adrian Bunk Cc: rmk@arm.linux.org.uk Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 21511d4..39b95f9 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -1000,7 +1000,7 @@ config BLK_DEV_IDEDMA endif -config BLK_DEV_HD_ONLY +config BLK_DEV_HD bool "Old hard disk (MFM/RLL/IDE) driver" depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN help @@ -1023,7 +1023,4 @@ config BLK_DEV_HD_ONLY Disk-HOWTO, available from . -config BLK_DEV_HD - def_bool BLK_DEV_HD_ONLY - endif # IDE -- cgit v0.10.2 From 01c22bfc30a3f40fed08cfd2779348edcb6c5e53 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: ide/legacy/hd.c: use late_initcall() Since the later move to drivers/block/ will break the link order, the module_init() has to become a late_initcall(). Signed-off-by: Adrian Bunk Cc: rmk@arm.linux.org.uk Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 8605536..39e99ac 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -62,7 +62,6 @@ endif obj-$(CONFIG_BLK_DEV_IDE) += arm/ mips/ -# old hd driver must be last ifeq ($(CONFIG_BLK_DEV_HD), y) hd-core-y += legacy/hd.o obj-y += hd-core.o diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index abdedf5..00b6956 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -812,4 +812,4 @@ static int __init parse_hd_setup(char *line) } __setup("hd=", parse_hd_setup); -module_init(hd_init); +late_initcall(hd_init); -- cgit v0.10.2 From 453ea3ed0b3e8ad67d4ee9d2fccf3d95a3e1f709 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: move ide/legacy/hd.c to drivers/block/ This patch moves hd.c to drivers/block/ Signed-off-by: Adrian Bunk Cc: rmk@arm.linux.org.uk Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 0d1d213..c390974 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -433,4 +433,28 @@ config VIRTIO_BLK This is the virtual block driver for virtio. It can be used with lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. +config BLK_DEV_HD + bool "Old hard disk (MFM/RLL/IDE) driver" + depends on HAVE_IDE + depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN + help + There are two drivers for MFM/RLL/IDE hard disks. Most people use + the newer enhanced driver, but this old one is still around for two + reasons. Some older systems have strange timing problems and seem to + work only with the old driver (which itself does not work with some + newer systems). The other reason is that the old driver is smaller, + since it lacks the enhanced functionality of the new one. This makes + it a good choice for systems with very tight memory restrictions, or + for systems with only older MFM/RLL/ESDI drives. Choosing the old + driver can save 13 KB or so of kernel memory. + + If you want to use this driver together with the new one you have + to use "hda=noprobe hdb=noprobe" kernel parameters to prevent the new + driver from probing the primary interface. + + If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver + instead of this one. For more detailed information, read the + Disk-HOWTO, available from + . + endif # BLK_DEV diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 5e58430..204332b 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -29,5 +29,6 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o obj-$(CONFIG_VIODASD) += viodasd.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o obj-$(CONFIG_BLK_DEV_UB) += ub.o +obj-$(CONFIG_BLK_DEV_HD) += hd.o obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o diff --git a/drivers/block/hd.c b/drivers/block/hd.c new file mode 100644 index 0000000..00b6956 --- /dev/null +++ b/drivers/block/hd.c @@ -0,0 +1,815 @@ +/* + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This is the low-level hd interrupt support. It traverses the + * request-list, using interrupts to jump between functions. As + * all the functions are called within interrupts, we may not + * sleep. Special care is recommended. + * + * modified by Drew Eckhardt to check nr of hd's from the CMOS. + * + * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug + * in the early extended-partition checks and added DM partitions + * + * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", + * and general streamlining by Mark Lord. + * + * Removed 99% of above. Use Mark's ide driver for those options. + * This is now a lightweight ST-506 driver. (Paul Gortmaker) + * + * Modified 1995 Russell King for ARM processor. + * + * Bugfix: max_sectors must be <= 255 or the wheels tend to come + * off in a hurry once you queue things up - Paul G. 02/2001 + */ + +/* Uncomment the following if you want verbose error reports. */ +/* #define VERBOSE_ERRORS */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* CMOS defines */ +#include +#include +#include + +#define REALLY_SLOW_IO +#include +#include +#include + +#ifdef __arm__ +#undef HD_IRQ +#endif +#include +#ifdef __arm__ +#define HD_IRQ IRQ_HARDDISK +#endif + +/* Hd controller regster ports */ + +#define HD_DATA 0x1f0 /* _CTL when writing */ +#define HD_ERROR 0x1f1 /* see err-bits */ +#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ +#define HD_SECTOR 0x1f3 /* starting sector */ +#define HD_LCYL 0x1f4 /* starting cylinder */ +#define HD_HCYL 0x1f5 /* high byte of starting cyl */ +#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ +#define HD_STATUS 0x1f7 /* see status-bits */ +#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ +#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ +#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ + +#define HD_CMD 0x3f6 /* used for resets */ +#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ + +/* Bits of HD_STATUS */ +#define ERR_STAT 0x01 +#define INDEX_STAT 0x02 +#define ECC_STAT 0x04 /* Corrected error */ +#define DRQ_STAT 0x08 +#define SEEK_STAT 0x10 +#define SERVICE_STAT SEEK_STAT +#define WRERR_STAT 0x20 +#define READY_STAT 0x40 +#define BUSY_STAT 0x80 + +/* Bits for HD_ERROR */ +#define MARK_ERR 0x01 /* Bad address mark */ +#define TRK0_ERR 0x02 /* couldn't find track 0 */ +#define ABRT_ERR 0x04 /* Command aborted */ +#define MCR_ERR 0x08 /* media change request */ +#define ID_ERR 0x10 /* ID field not found */ +#define MC_ERR 0x20 /* media changed */ +#define ECC_ERR 0x40 /* Uncorrectable ECC error */ +#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ +#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ + +static DEFINE_SPINLOCK(hd_lock); +static struct request_queue *hd_queue; + +#define MAJOR_NR HD_MAJOR +#define QUEUE (hd_queue) +#define CURRENT elv_next_request(hd_queue) + +#define TIMEOUT_VALUE (6*HZ) +#define HD_DELAY 0 + +#define MAX_ERRORS 16 /* Max read/write errors/sector */ +#define RESET_FREQ 8 /* Reset controller every 8th retry */ +#define RECAL_FREQ 4 /* Recalibrate every 4th retry */ +#define MAX_HD 2 + +#define STAT_OK (READY_STAT|SEEK_STAT) +#define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK) + +static void recal_intr(void); +static void bad_rw_intr(void); + +static int reset; +static int hd_error; + +/* + * This struct defines the HD's and their types. + */ +struct hd_i_struct { + unsigned int head, sect, cyl, wpcom, lzone, ctl; + int unit; + int recalibrate; + int special_op; +}; + +#ifdef HD_TYPE +static struct hd_i_struct hd_info[] = { HD_TYPE }; +static int NR_HD = ARRAY_SIZE(hd_info); +#else +static struct hd_i_struct hd_info[MAX_HD]; +static int NR_HD; +#endif + +static struct gendisk *hd_gendisk[MAX_HD]; + +static struct timer_list device_timer; + +#define TIMEOUT_VALUE (6*HZ) + +#define SET_TIMER \ + do { \ + mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \ + } while (0) + +static void (*do_hd)(void) = NULL; +#define SET_HANDLER(x) \ +if ((do_hd = (x)) != NULL) \ + SET_TIMER; \ +else \ + del_timer(&device_timer); + + +#if (HD_DELAY > 0) + +#include + +unsigned long last_req; + +unsigned long read_timer(void) +{ + unsigned long t, flags; + int i; + + spin_lock_irqsave(&i8253_lock, flags); + t = jiffies * 11932; + outb_p(0, 0x43); + i = inb_p(0x40); + i |= inb(0x40) << 8; + spin_unlock_irqrestore(&i8253_lock, flags); + return(t - i); +} +#endif + +static void __init hd_setup(char *str, int *ints) +{ + int hdind = 0; + + if (ints[0] != 3) + return; + if (hd_info[0].head != 0) + hdind = 1; + hd_info[hdind].head = ints[2]; + hd_info[hdind].sect = ints[3]; + hd_info[hdind].cyl = ints[1]; + hd_info[hdind].wpcom = 0; + hd_info[hdind].lzone = ints[1]; + hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0); + NR_HD = hdind+1; +} + +static void dump_status(const char *msg, unsigned int stat) +{ + char *name = "hd?"; + if (CURRENT) + name = CURRENT->rq_disk->disk_name; + +#ifdef VERBOSE_ERRORS + printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff); + if (stat & BUSY_STAT) printk("Busy "); + if (stat & READY_STAT) printk("DriveReady "); + if (stat & WRERR_STAT) printk("WriteFault "); + if (stat & SEEK_STAT) printk("SeekComplete "); + if (stat & DRQ_STAT) printk("DataRequest "); + if (stat & ECC_STAT) printk("CorrectedError "); + if (stat & INDEX_STAT) printk("Index "); + if (stat & ERR_STAT) printk("Error "); + printk("}\n"); + if ((stat & ERR_STAT) == 0) { + hd_error = 0; + } else { + hd_error = inb(HD_ERROR); + printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff); + if (hd_error & BBD_ERR) printk("BadSector "); + if (hd_error & ECC_ERR) printk("UncorrectableError "); + if (hd_error & ID_ERR) printk("SectorIdNotFound "); + if (hd_error & ABRT_ERR) printk("DriveStatusError "); + if (hd_error & TRK0_ERR) printk("TrackZeroNotFound "); + if (hd_error & MARK_ERR) printk("AddrMarkNotFound "); + printk("}"); + if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { + printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL), + inb(HD_CURRENT) & 0xf, inb(HD_SECTOR)); + if (CURRENT) + printk(", sector=%ld", CURRENT->sector); + } + printk("\n"); + } +#else + printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff); + if ((stat & ERR_STAT) == 0) { + hd_error = 0; + } else { + hd_error = inb(HD_ERROR); + printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff); + } +#endif +} + +static void check_status(void) +{ + int i = inb_p(HD_STATUS); + + if (!OK_STATUS(i)) { + dump_status("check_status", i); + bad_rw_intr(); + } +} + +static int controller_busy(void) +{ + int retries = 100000; + unsigned char status; + + do { + status = inb_p(HD_STATUS); + } while ((status & BUSY_STAT) && --retries); + return status; +} + +static int status_ok(void) +{ + unsigned char status = inb_p(HD_STATUS); + + if (status & BUSY_STAT) + return 1; /* Ancient, but does it make sense??? */ + if (status & WRERR_STAT) + return 0; + if (!(status & READY_STAT)) + return 0; + if (!(status & SEEK_STAT)) + return 0; + return 1; +} + +static int controller_ready(unsigned int drive, unsigned int head) +{ + int retry = 100; + + do { + if (controller_busy() & BUSY_STAT) + return 0; + outb_p(0xA0 | (drive<<4) | head, HD_CURRENT); + if (status_ok()) + return 1; + } while (--retry); + return 0; +} + +static void hd_out(struct hd_i_struct *disk, + unsigned int nsect, + unsigned int sect, + unsigned int head, + unsigned int cyl, + unsigned int cmd, + void (*intr_addr)(void)) +{ + unsigned short port; + +#if (HD_DELAY > 0) + while (read_timer() - last_req < HD_DELAY) + /* nothing */; +#endif + if (reset) + return; + if (!controller_ready(disk->unit, head)) { + reset = 1; + return; + } + SET_HANDLER(intr_addr); + outb_p(disk->ctl, HD_CMD); + port = HD_DATA; + outb_p(disk->wpcom >> 2, ++port); + outb_p(nsect, ++port); + outb_p(sect, ++port); + outb_p(cyl, ++port); + outb_p(cyl >> 8, ++port); + outb_p(0xA0 | (disk->unit << 4) | head, ++port); + outb_p(cmd, ++port); +} + +static void hd_request (void); + +static int drive_busy(void) +{ + unsigned int i; + unsigned char c; + + for (i = 0; i < 500000 ; i++) { + c = inb_p(HD_STATUS); + if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK) + return 0; + } + dump_status("reset timed out", c); + return 1; +} + +static void reset_controller(void) +{ + int i; + + outb_p(4, HD_CMD); + for (i = 0; i < 1000; i++) barrier(); + outb_p(hd_info[0].ctl & 0x0f, HD_CMD); + for (i = 0; i < 1000; i++) barrier(); + if (drive_busy()) + printk("hd: controller still busy\n"); + else if ((hd_error = inb(HD_ERROR)) != 1) + printk("hd: controller reset failed: %02x\n", hd_error); +} + +static void reset_hd(void) +{ + static int i; + +repeat: + if (reset) { + reset = 0; + i = -1; + reset_controller(); + } else { + check_status(); + if (reset) + goto repeat; + } + if (++i < NR_HD) { + struct hd_i_struct *disk = &hd_info[i]; + disk->special_op = disk->recalibrate = 1; + hd_out(disk, disk->sect, disk->sect, disk->head-1, + disk->cyl, WIN_SPECIFY, &reset_hd); + if (reset) + goto repeat; + } else + hd_request(); +} + +/* + * Ok, don't know what to do with the unexpected interrupts: on some machines + * doing a reset and a retry seems to result in an eternal loop. Right now I + * ignore it, and just set the timeout. + * + * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the + * drive enters "idle", "standby", or "sleep" mode, so if the status looks + * "good", we just ignore the interrupt completely. + */ +static void unexpected_hd_interrupt(void) +{ + unsigned int stat = inb_p(HD_STATUS); + + if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { + dump_status("unexpected interrupt", stat); + SET_TIMER; + } +} + +/* + * bad_rw_intr() now tries to be a bit smarter and does things + * according to the error returned by the controller. + * -Mika Liljeberg (liljeber@cs.Helsinki.FI) + */ +static void bad_rw_intr(void) +{ + struct request *req = CURRENT; + if (req != NULL) { + struct hd_i_struct *disk = req->rq_disk->private_data; + if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { + end_request(req, 0); + disk->special_op = disk->recalibrate = 1; + } else if (req->errors % RESET_FREQ == 0) + reset = 1; + else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0) + disk->special_op = disk->recalibrate = 1; + /* Otherwise just retry */ + } +} + +static inline int wait_DRQ(void) +{ + int retries; + int stat; + + for (retries = 0; retries < 100000; retries++) { + stat = inb_p(HD_STATUS); + if (stat & DRQ_STAT) + return 0; + } + dump_status("wait_DRQ", stat); + return -1; +} + +static void read_intr(void) +{ + struct request *req; + int i, retries = 100000; + + do { + i = (unsigned) inb_p(HD_STATUS); + if (i & BUSY_STAT) + continue; + if (!OK_STATUS(i)) + break; + if (i & DRQ_STAT) + goto ok_to_read; + } while (--retries > 0); + dump_status("read_intr", i); + bad_rw_intr(); + hd_request(); + return; +ok_to_read: + req = CURRENT; + insw(HD_DATA, req->buffer, 256); + req->sector++; + req->buffer += 512; + req->errors = 0; + i = --req->nr_sectors; + --req->current_nr_sectors; +#ifdef DEBUG + printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", + req->rq_disk->disk_name, req->sector, req->nr_sectors, + req->buffer+512); +#endif + if (req->current_nr_sectors <= 0) + end_request(req, 1); + if (i > 0) { + SET_HANDLER(&read_intr); + return; + } + (void) inb_p(HD_STATUS); +#if (HD_DELAY > 0) + last_req = read_timer(); +#endif + if (elv_next_request(QUEUE)) + hd_request(); + return; +} + +static void write_intr(void) +{ + struct request *req = CURRENT; + int i; + int retries = 100000; + + do { + i = (unsigned) inb_p(HD_STATUS); + if (i & BUSY_STAT) + continue; + if (!OK_STATUS(i)) + break; + if ((req->nr_sectors <= 1) || (i & DRQ_STAT)) + goto ok_to_write; + } while (--retries > 0); + dump_status("write_intr", i); + bad_rw_intr(); + hd_request(); + return; +ok_to_write: + req->sector++; + i = --req->nr_sectors; + --req->current_nr_sectors; + req->buffer += 512; + if (!i || (req->bio && req->current_nr_sectors <= 0)) + end_request(req, 1); + if (i > 0) { + SET_HANDLER(&write_intr); + outsw(HD_DATA, req->buffer, 256); + local_irq_enable(); + } else { +#if (HD_DELAY > 0) + last_req = read_timer(); +#endif + hd_request(); + } + return; +} + +static void recal_intr(void) +{ + check_status(); +#if (HD_DELAY > 0) + last_req = read_timer(); +#endif + hd_request(); +} + +/* + * This is another of the error-routines I don't know what to do with. The + * best idea seems to just set reset, and start all over again. + */ +static void hd_times_out(unsigned long dummy) +{ + char *name; + + do_hd = NULL; + + if (!CURRENT) + return; + + disable_irq(HD_IRQ); + local_irq_enable(); + reset = 1; + name = CURRENT->rq_disk->disk_name; + printk("%s: timeout\n", name); + if (++CURRENT->errors >= MAX_ERRORS) { +#ifdef DEBUG + printk("%s: too many errors\n", name); +#endif + end_request(CURRENT, 0); + } + local_irq_disable(); + hd_request(); + enable_irq(HD_IRQ); +} + +static int do_special_op(struct hd_i_struct *disk, struct request *req) +{ + if (disk->recalibrate) { + disk->recalibrate = 0; + hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr); + return reset; + } + if (disk->head > 16) { + printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); + end_request(req, 0); + } + disk->special_op = 0; + return 1; +} + +/* + * The driver enables interrupts as much as possible. In order to do this, + * (a) the device-interrupt is disabled before entering hd_request(), + * and (b) the timeout-interrupt is disabled before the sti(). + * + * Interrupts are still masked (by default) whenever we are exchanging + * data/cmds with a drive, because some drives seem to have very poor + * tolerance for latency during I/O. The IDE driver has support to unmask + * interrupts for non-broken hardware, so use that driver if required. + */ +static void hd_request(void) +{ + unsigned int block, nsect, sec, track, head, cyl; + struct hd_i_struct *disk; + struct request *req; + + if (do_hd) + return; +repeat: + del_timer(&device_timer); + local_irq_enable(); + + req = CURRENT; + if (!req) { + do_hd = NULL; + return; + } + + if (reset) { + local_irq_disable(); + reset_hd(); + return; + } + disk = req->rq_disk->private_data; + block = req->sector; + nsect = req->nr_sectors; + if (block >= get_capacity(req->rq_disk) || + ((block+nsect) > get_capacity(req->rq_disk))) { + printk("%s: bad access: block=%d, count=%d\n", + req->rq_disk->disk_name, block, nsect); + end_request(req, 0); + goto repeat; + } + + if (disk->special_op) { + if (do_special_op(disk, req)) + goto repeat; + return; + } + sec = block % disk->sect + 1; + track = block / disk->sect; + head = track % disk->head; + cyl = track / disk->head; +#ifdef DEBUG + printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", + req->rq_disk->disk_name, + req_data_dir(req) == READ ? "read" : "writ", + cyl, head, sec, nsect, req->buffer); +#endif + if (blk_fs_request(req)) { + switch (rq_data_dir(req)) { + case READ: + hd_out(disk, nsect, sec, head, cyl, WIN_READ, + &read_intr); + if (reset) + goto repeat; + break; + case WRITE: + hd_out(disk, nsect, sec, head, cyl, WIN_WRITE, + &write_intr); + if (reset) + goto repeat; + if (wait_DRQ()) { + bad_rw_intr(); + goto repeat; + } + outsw(HD_DATA, req->buffer, 256); + break; + default: + printk("unknown hd-command\n"); + end_request(req, 0); + break; + } + } +} + +static void do_hd_request(struct request_queue *q) +{ + disable_irq(HD_IRQ); + hd_request(); + enable_irq(HD_IRQ); +} + +static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) +{ + struct hd_i_struct *disk = bdev->bd_disk->private_data; + + geo->heads = disk->head; + geo->sectors = disk->sect; + geo->cylinders = disk->cyl; + return 0; +} + +/* + * Releasing a block device means we sync() it, so that it can safely + * be forgotten about... + */ + +static irqreturn_t hd_interrupt(int irq, void *dev_id) +{ + void (*handler)(void) = do_hd; + + do_hd = NULL; + del_timer(&device_timer); + if (!handler) + handler = unexpected_hd_interrupt; + handler(); + local_irq_enable(); + return IRQ_HANDLED; +} + +static struct block_device_operations hd_fops = { + .getgeo = hd_getgeo, +}; + +/* + * This is the hard disk IRQ description. The IRQF_DISABLED in sa_flags + * means we run the IRQ-handler with interrupts disabled: this is bad for + * interrupt latency, but anything else has led to problems on some + * machines. + * + * We enable interrupts in some of the routines after making sure it's + * safe. + */ + +static int __init hd_init(void) +{ + int drive; + + if (register_blkdev(MAJOR_NR, "hd")) + return -1; + + hd_queue = blk_init_queue(do_hd_request, &hd_lock); + if (!hd_queue) { + unregister_blkdev(MAJOR_NR, "hd"); + return -ENOMEM; + } + + blk_queue_max_sectors(hd_queue, 255); + init_timer(&device_timer); + device_timer.function = hd_times_out; + blk_queue_hardsect_size(hd_queue, 512); + + if (!NR_HD) { + /* + * We don't know anything about the drive. This means + * that you *MUST* specify the drive parameters to the + * kernel yourself. + * + * If we were on an i386, we used to read this info from + * the BIOS or CMOS. This doesn't work all that well, + * since this assumes that this is a primary or secondary + * drive, and if we're using this legacy driver, it's + * probably an auxilliary controller added to recover + * legacy data off an ST-506 drive. Either way, it's + * definitely safest to have the user explicitly specify + * the information. + */ + printk("hd: no drives specified - use hd=cyl,head,sectors" + " on kernel command line\n"); + goto out; + } + + for (drive = 0 ; drive < NR_HD ; drive++) { + struct gendisk *disk = alloc_disk(64); + struct hd_i_struct *p = &hd_info[drive]; + if (!disk) + goto Enomem; + disk->major = MAJOR_NR; + disk->first_minor = drive << 6; + disk->fops = &hd_fops; + sprintf(disk->disk_name, "hd%c", 'a'+drive); + disk->private_data = p; + set_capacity(disk, p->head * p->sect * p->cyl); + disk->queue = hd_queue; + p->unit = drive; + hd_gendisk[drive] = disk; + printk("%s: %luMB, CHS=%d/%d/%d\n", + disk->disk_name, (unsigned long)get_capacity(disk)/2048, + p->cyl, p->head, p->sect); + } + + if (request_irq(HD_IRQ, hd_interrupt, IRQF_DISABLED, "hd", NULL)) { + printk("hd: unable to get IRQ%d for the hard disk driver\n", + HD_IRQ); + goto out1; + } + if (!request_region(HD_DATA, 8, "hd")) { + printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); + goto out2; + } + if (!request_region(HD_CMD, 1, "hd(cmd)")) { + printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD); + goto out3; + } + + /* Let them fly */ + for (drive = 0; drive < NR_HD; drive++) + add_disk(hd_gendisk[drive]); + + return 0; + +out3: + release_region(HD_DATA, 8); +out2: + free_irq(HD_IRQ, NULL); +out1: + for (drive = 0; drive < NR_HD; drive++) + put_disk(hd_gendisk[drive]); + NR_HD = 0; +out: + del_timer(&device_timer); + unregister_blkdev(MAJOR_NR, "hd"); + blk_cleanup_queue(hd_queue); + return -1; +Enomem: + while (drive--) + put_disk(hd_gendisk[drive]); + goto out; +} + +static int __init parse_hd_setup(char *line) +{ + int ints[6]; + + (void) get_options(line, ARRAY_SIZE(ints), ints); + hd_setup(NULL, ints); + + return 1; +} +__setup("hd=", parse_hd_setup); + +late_initcall(hd_init); diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 39b95f9..15b09b8 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -1000,27 +1000,4 @@ config BLK_DEV_IDEDMA endif -config BLK_DEV_HD - bool "Old hard disk (MFM/RLL/IDE) driver" - depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN - help - There are two drivers for MFM/RLL/IDE hard disks. Most people use - the newer enhanced driver, but this old one is still around for two - reasons. Some older systems have strange timing problems and seem to - work only with the old driver (which itself does not work with some - newer systems). The other reason is that the old driver is smaller, - since it lacks the enhanced functionality of the new one. This makes - it a good choice for systems with very tight memory restrictions, or - for systems with only older MFM/RLL/ESDI drives. Choosing the old - driver can save 13 KB or so of kernel memory. - - If you want to use this driver together with the new one you have - to use "hda=noprobe hdb=noprobe" kernel parameters to prevent the new - driver from probing the primary interface. - - If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver - instead of this one. For more detailed information, read the - Disk-HOWTO, available from - . - endif # IDE diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 39e99ac..5d414e3 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -61,8 +61,3 @@ ifeq ($(CONFIG_BLK_DEV_PLATFORM), y) endif obj-$(CONFIG_BLK_DEV_IDE) += arm/ mips/ - -ifeq ($(CONFIG_BLK_DEV_HD), y) - hd-core-y += legacy/hd.o - obj-y += hd-core.o -endif diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c deleted file mode 100644 index 00b6956..0000000 --- a/drivers/ide/legacy/hd.c +++ /dev/null @@ -1,815 +0,0 @@ -/* - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This is the low-level hd interrupt support. It traverses the - * request-list, using interrupts to jump between functions. As - * all the functions are called within interrupts, we may not - * sleep. Special care is recommended. - * - * modified by Drew Eckhardt to check nr of hd's from the CMOS. - * - * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug - * in the early extended-partition checks and added DM partitions - * - * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", - * and general streamlining by Mark Lord. - * - * Removed 99% of above. Use Mark's ide driver for those options. - * This is now a lightweight ST-506 driver. (Paul Gortmaker) - * - * Modified 1995 Russell King for ARM processor. - * - * Bugfix: max_sectors must be <= 255 or the wheels tend to come - * off in a hurry once you queue things up - Paul G. 02/2001 - */ - -/* Uncomment the following if you want verbose error reports. */ -/* #define VERBOSE_ERRORS */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* CMOS defines */ -#include -#include -#include - -#define REALLY_SLOW_IO -#include -#include -#include - -#ifdef __arm__ -#undef HD_IRQ -#endif -#include -#ifdef __arm__ -#define HD_IRQ IRQ_HARDDISK -#endif - -/* Hd controller regster ports */ - -#define HD_DATA 0x1f0 /* _CTL when writing */ -#define HD_ERROR 0x1f1 /* see err-bits */ -#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ -#define HD_SECTOR 0x1f3 /* starting sector */ -#define HD_LCYL 0x1f4 /* starting cylinder */ -#define HD_HCYL 0x1f5 /* high byte of starting cyl */ -#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ -#define HD_STATUS 0x1f7 /* see status-bits */ -#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ -#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ -#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ - -#define HD_CMD 0x3f6 /* used for resets */ -#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ - -/* Bits of HD_STATUS */ -#define ERR_STAT 0x01 -#define INDEX_STAT 0x02 -#define ECC_STAT 0x04 /* Corrected error */ -#define DRQ_STAT 0x08 -#define SEEK_STAT 0x10 -#define SERVICE_STAT SEEK_STAT -#define WRERR_STAT 0x20 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits for HD_ERROR */ -#define MARK_ERR 0x01 /* Bad address mark */ -#define TRK0_ERR 0x02 /* couldn't find track 0 */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* media change request */ -#define ID_ERR 0x10 /* ID field not found */ -#define MC_ERR 0x20 /* media changed */ -#define ECC_ERR 0x40 /* Uncorrectable ECC error */ -#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ -#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ - -static DEFINE_SPINLOCK(hd_lock); -static struct request_queue *hd_queue; - -#define MAJOR_NR HD_MAJOR -#define QUEUE (hd_queue) -#define CURRENT elv_next_request(hd_queue) - -#define TIMEOUT_VALUE (6*HZ) -#define HD_DELAY 0 - -#define MAX_ERRORS 16 /* Max read/write errors/sector */ -#define RESET_FREQ 8 /* Reset controller every 8th retry */ -#define RECAL_FREQ 4 /* Recalibrate every 4th retry */ -#define MAX_HD 2 - -#define STAT_OK (READY_STAT|SEEK_STAT) -#define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK) - -static void recal_intr(void); -static void bad_rw_intr(void); - -static int reset; -static int hd_error; - -/* - * This struct defines the HD's and their types. - */ -struct hd_i_struct { - unsigned int head, sect, cyl, wpcom, lzone, ctl; - int unit; - int recalibrate; - int special_op; -}; - -#ifdef HD_TYPE -static struct hd_i_struct hd_info[] = { HD_TYPE }; -static int NR_HD = ARRAY_SIZE(hd_info); -#else -static struct hd_i_struct hd_info[MAX_HD]; -static int NR_HD; -#endif - -static struct gendisk *hd_gendisk[MAX_HD]; - -static struct timer_list device_timer; - -#define TIMEOUT_VALUE (6*HZ) - -#define SET_TIMER \ - do { \ - mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \ - } while (0) - -static void (*do_hd)(void) = NULL; -#define SET_HANDLER(x) \ -if ((do_hd = (x)) != NULL) \ - SET_TIMER; \ -else \ - del_timer(&device_timer); - - -#if (HD_DELAY > 0) - -#include - -unsigned long last_req; - -unsigned long read_timer(void) -{ - unsigned long t, flags; - int i; - - spin_lock_irqsave(&i8253_lock, flags); - t = jiffies * 11932; - outb_p(0, 0x43); - i = inb_p(0x40); - i |= inb(0x40) << 8; - spin_unlock_irqrestore(&i8253_lock, flags); - return(t - i); -} -#endif - -static void __init hd_setup(char *str, int *ints) -{ - int hdind = 0; - - if (ints[0] != 3) - return; - if (hd_info[0].head != 0) - hdind = 1; - hd_info[hdind].head = ints[2]; - hd_info[hdind].sect = ints[3]; - hd_info[hdind].cyl = ints[1]; - hd_info[hdind].wpcom = 0; - hd_info[hdind].lzone = ints[1]; - hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0); - NR_HD = hdind+1; -} - -static void dump_status(const char *msg, unsigned int stat) -{ - char *name = "hd?"; - if (CURRENT) - name = CURRENT->rq_disk->disk_name; - -#ifdef VERBOSE_ERRORS - printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff); - if (stat & BUSY_STAT) printk("Busy "); - if (stat & READY_STAT) printk("DriveReady "); - if (stat & WRERR_STAT) printk("WriteFault "); - if (stat & SEEK_STAT) printk("SeekComplete "); - if (stat & DRQ_STAT) printk("DataRequest "); - if (stat & ECC_STAT) printk("CorrectedError "); - if (stat & INDEX_STAT) printk("Index "); - if (stat & ERR_STAT) printk("Error "); - printk("}\n"); - if ((stat & ERR_STAT) == 0) { - hd_error = 0; - } else { - hd_error = inb(HD_ERROR); - printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff); - if (hd_error & BBD_ERR) printk("BadSector "); - if (hd_error & ECC_ERR) printk("UncorrectableError "); - if (hd_error & ID_ERR) printk("SectorIdNotFound "); - if (hd_error & ABRT_ERR) printk("DriveStatusError "); - if (hd_error & TRK0_ERR) printk("TrackZeroNotFound "); - if (hd_error & MARK_ERR) printk("AddrMarkNotFound "); - printk("}"); - if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { - printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL), - inb(HD_CURRENT) & 0xf, inb(HD_SECTOR)); - if (CURRENT) - printk(", sector=%ld", CURRENT->sector); - } - printk("\n"); - } -#else - printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff); - if ((stat & ERR_STAT) == 0) { - hd_error = 0; - } else { - hd_error = inb(HD_ERROR); - printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff); - } -#endif -} - -static void check_status(void) -{ - int i = inb_p(HD_STATUS); - - if (!OK_STATUS(i)) { - dump_status("check_status", i); - bad_rw_intr(); - } -} - -static int controller_busy(void) -{ - int retries = 100000; - unsigned char status; - - do { - status = inb_p(HD_STATUS); - } while ((status & BUSY_STAT) && --retries); - return status; -} - -static int status_ok(void) -{ - unsigned char status = inb_p(HD_STATUS); - - if (status & BUSY_STAT) - return 1; /* Ancient, but does it make sense??? */ - if (status & WRERR_STAT) - return 0; - if (!(status & READY_STAT)) - return 0; - if (!(status & SEEK_STAT)) - return 0; - return 1; -} - -static int controller_ready(unsigned int drive, unsigned int head) -{ - int retry = 100; - - do { - if (controller_busy() & BUSY_STAT) - return 0; - outb_p(0xA0 | (drive<<4) | head, HD_CURRENT); - if (status_ok()) - return 1; - } while (--retry); - return 0; -} - -static void hd_out(struct hd_i_struct *disk, - unsigned int nsect, - unsigned int sect, - unsigned int head, - unsigned int cyl, - unsigned int cmd, - void (*intr_addr)(void)) -{ - unsigned short port; - -#if (HD_DELAY > 0) - while (read_timer() - last_req < HD_DELAY) - /* nothing */; -#endif - if (reset) - return; - if (!controller_ready(disk->unit, head)) { - reset = 1; - return; - } - SET_HANDLER(intr_addr); - outb_p(disk->ctl, HD_CMD); - port = HD_DATA; - outb_p(disk->wpcom >> 2, ++port); - outb_p(nsect, ++port); - outb_p(sect, ++port); - outb_p(cyl, ++port); - outb_p(cyl >> 8, ++port); - outb_p(0xA0 | (disk->unit << 4) | head, ++port); - outb_p(cmd, ++port); -} - -static void hd_request (void); - -static int drive_busy(void) -{ - unsigned int i; - unsigned char c; - - for (i = 0; i < 500000 ; i++) { - c = inb_p(HD_STATUS); - if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK) - return 0; - } - dump_status("reset timed out", c); - return 1; -} - -static void reset_controller(void) -{ - int i; - - outb_p(4, HD_CMD); - for (i = 0; i < 1000; i++) barrier(); - outb_p(hd_info[0].ctl & 0x0f, HD_CMD); - for (i = 0; i < 1000; i++) barrier(); - if (drive_busy()) - printk("hd: controller still busy\n"); - else if ((hd_error = inb(HD_ERROR)) != 1) - printk("hd: controller reset failed: %02x\n", hd_error); -} - -static void reset_hd(void) -{ - static int i; - -repeat: - if (reset) { - reset = 0; - i = -1; - reset_controller(); - } else { - check_status(); - if (reset) - goto repeat; - } - if (++i < NR_HD) { - struct hd_i_struct *disk = &hd_info[i]; - disk->special_op = disk->recalibrate = 1; - hd_out(disk, disk->sect, disk->sect, disk->head-1, - disk->cyl, WIN_SPECIFY, &reset_hd); - if (reset) - goto repeat; - } else - hd_request(); -} - -/* - * Ok, don't know what to do with the unexpected interrupts: on some machines - * doing a reset and a retry seems to result in an eternal loop. Right now I - * ignore it, and just set the timeout. - * - * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the - * drive enters "idle", "standby", or "sleep" mode, so if the status looks - * "good", we just ignore the interrupt completely. - */ -static void unexpected_hd_interrupt(void) -{ - unsigned int stat = inb_p(HD_STATUS); - - if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { - dump_status("unexpected interrupt", stat); - SET_TIMER; - } -} - -/* - * bad_rw_intr() now tries to be a bit smarter and does things - * according to the error returned by the controller. - * -Mika Liljeberg (liljeber@cs.Helsinki.FI) - */ -static void bad_rw_intr(void) -{ - struct request *req = CURRENT; - if (req != NULL) { - struct hd_i_struct *disk = req->rq_disk->private_data; - if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { - end_request(req, 0); - disk->special_op = disk->recalibrate = 1; - } else if (req->errors % RESET_FREQ == 0) - reset = 1; - else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0) - disk->special_op = disk->recalibrate = 1; - /* Otherwise just retry */ - } -} - -static inline int wait_DRQ(void) -{ - int retries; - int stat; - - for (retries = 0; retries < 100000; retries++) { - stat = inb_p(HD_STATUS); - if (stat & DRQ_STAT) - return 0; - } - dump_status("wait_DRQ", stat); - return -1; -} - -static void read_intr(void) -{ - struct request *req; - int i, retries = 100000; - - do { - i = (unsigned) inb_p(HD_STATUS); - if (i & BUSY_STAT) - continue; - if (!OK_STATUS(i)) - break; - if (i & DRQ_STAT) - goto ok_to_read; - } while (--retries > 0); - dump_status("read_intr", i); - bad_rw_intr(); - hd_request(); - return; -ok_to_read: - req = CURRENT; - insw(HD_DATA, req->buffer, 256); - req->sector++; - req->buffer += 512; - req->errors = 0; - i = --req->nr_sectors; - --req->current_nr_sectors; -#ifdef DEBUG - printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", - req->rq_disk->disk_name, req->sector, req->nr_sectors, - req->buffer+512); -#endif - if (req->current_nr_sectors <= 0) - end_request(req, 1); - if (i > 0) { - SET_HANDLER(&read_intr); - return; - } - (void) inb_p(HD_STATUS); -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - if (elv_next_request(QUEUE)) - hd_request(); - return; -} - -static void write_intr(void) -{ - struct request *req = CURRENT; - int i; - int retries = 100000; - - do { - i = (unsigned) inb_p(HD_STATUS); - if (i & BUSY_STAT) - continue; - if (!OK_STATUS(i)) - break; - if ((req->nr_sectors <= 1) || (i & DRQ_STAT)) - goto ok_to_write; - } while (--retries > 0); - dump_status("write_intr", i); - bad_rw_intr(); - hd_request(); - return; -ok_to_write: - req->sector++; - i = --req->nr_sectors; - --req->current_nr_sectors; - req->buffer += 512; - if (!i || (req->bio && req->current_nr_sectors <= 0)) - end_request(req, 1); - if (i > 0) { - SET_HANDLER(&write_intr); - outsw(HD_DATA, req->buffer, 256); - local_irq_enable(); - } else { -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - hd_request(); - } - return; -} - -static void recal_intr(void) -{ - check_status(); -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - hd_request(); -} - -/* - * This is another of the error-routines I don't know what to do with. The - * best idea seems to just set reset, and start all over again. - */ -static void hd_times_out(unsigned long dummy) -{ - char *name; - - do_hd = NULL; - - if (!CURRENT) - return; - - disable_irq(HD_IRQ); - local_irq_enable(); - reset = 1; - name = CURRENT->rq_disk->disk_name; - printk("%s: timeout\n", name); - if (++CURRENT->errors >= MAX_ERRORS) { -#ifdef DEBUG - printk("%s: too many errors\n", name); -#endif - end_request(CURRENT, 0); - } - local_irq_disable(); - hd_request(); - enable_irq(HD_IRQ); -} - -static int do_special_op(struct hd_i_struct *disk, struct request *req) -{ - if (disk->recalibrate) { - disk->recalibrate = 0; - hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr); - return reset; - } - if (disk->head > 16) { - printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); - end_request(req, 0); - } - disk->special_op = 0; - return 1; -} - -/* - * The driver enables interrupts as much as possible. In order to do this, - * (a) the device-interrupt is disabled before entering hd_request(), - * and (b) the timeout-interrupt is disabled before the sti(). - * - * Interrupts are still masked (by default) whenever we are exchanging - * data/cmds with a drive, because some drives seem to have very poor - * tolerance for latency during I/O. The IDE driver has support to unmask - * interrupts for non-broken hardware, so use that driver if required. - */ -static void hd_request(void) -{ - unsigned int block, nsect, sec, track, head, cyl; - struct hd_i_struct *disk; - struct request *req; - - if (do_hd) - return; -repeat: - del_timer(&device_timer); - local_irq_enable(); - - req = CURRENT; - if (!req) { - do_hd = NULL; - return; - } - - if (reset) { - local_irq_disable(); - reset_hd(); - return; - } - disk = req->rq_disk->private_data; - block = req->sector; - nsect = req->nr_sectors; - if (block >= get_capacity(req->rq_disk) || - ((block+nsect) > get_capacity(req->rq_disk))) { - printk("%s: bad access: block=%d, count=%d\n", - req->rq_disk->disk_name, block, nsect); - end_request(req, 0); - goto repeat; - } - - if (disk->special_op) { - if (do_special_op(disk, req)) - goto repeat; - return; - } - sec = block % disk->sect + 1; - track = block / disk->sect; - head = track % disk->head; - cyl = track / disk->head; -#ifdef DEBUG - printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", - req->rq_disk->disk_name, - req_data_dir(req) == READ ? "read" : "writ", - cyl, head, sec, nsect, req->buffer); -#endif - if (blk_fs_request(req)) { - switch (rq_data_dir(req)) { - case READ: - hd_out(disk, nsect, sec, head, cyl, WIN_READ, - &read_intr); - if (reset) - goto repeat; - break; - case WRITE: - hd_out(disk, nsect, sec, head, cyl, WIN_WRITE, - &write_intr); - if (reset) - goto repeat; - if (wait_DRQ()) { - bad_rw_intr(); - goto repeat; - } - outsw(HD_DATA, req->buffer, 256); - break; - default: - printk("unknown hd-command\n"); - end_request(req, 0); - break; - } - } -} - -static void do_hd_request(struct request_queue *q) -{ - disable_irq(HD_IRQ); - hd_request(); - enable_irq(HD_IRQ); -} - -static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct hd_i_struct *disk = bdev->bd_disk->private_data; - - geo->heads = disk->head; - geo->sectors = disk->sect; - geo->cylinders = disk->cyl; - return 0; -} - -/* - * Releasing a block device means we sync() it, so that it can safely - * be forgotten about... - */ - -static irqreturn_t hd_interrupt(int irq, void *dev_id) -{ - void (*handler)(void) = do_hd; - - do_hd = NULL; - del_timer(&device_timer); - if (!handler) - handler = unexpected_hd_interrupt; - handler(); - local_irq_enable(); - return IRQ_HANDLED; -} - -static struct block_device_operations hd_fops = { - .getgeo = hd_getgeo, -}; - -/* - * This is the hard disk IRQ description. The IRQF_DISABLED in sa_flags - * means we run the IRQ-handler with interrupts disabled: this is bad for - * interrupt latency, but anything else has led to problems on some - * machines. - * - * We enable interrupts in some of the routines after making sure it's - * safe. - */ - -static int __init hd_init(void) -{ - int drive; - - if (register_blkdev(MAJOR_NR, "hd")) - return -1; - - hd_queue = blk_init_queue(do_hd_request, &hd_lock); - if (!hd_queue) { - unregister_blkdev(MAJOR_NR, "hd"); - return -ENOMEM; - } - - blk_queue_max_sectors(hd_queue, 255); - init_timer(&device_timer); - device_timer.function = hd_times_out; - blk_queue_hardsect_size(hd_queue, 512); - - if (!NR_HD) { - /* - * We don't know anything about the drive. This means - * that you *MUST* specify the drive parameters to the - * kernel yourself. - * - * If we were on an i386, we used to read this info from - * the BIOS or CMOS. This doesn't work all that well, - * since this assumes that this is a primary or secondary - * drive, and if we're using this legacy driver, it's - * probably an auxilliary controller added to recover - * legacy data off an ST-506 drive. Either way, it's - * definitely safest to have the user explicitly specify - * the information. - */ - printk("hd: no drives specified - use hd=cyl,head,sectors" - " on kernel command line\n"); - goto out; - } - - for (drive = 0 ; drive < NR_HD ; drive++) { - struct gendisk *disk = alloc_disk(64); - struct hd_i_struct *p = &hd_info[drive]; - if (!disk) - goto Enomem; - disk->major = MAJOR_NR; - disk->first_minor = drive << 6; - disk->fops = &hd_fops; - sprintf(disk->disk_name, "hd%c", 'a'+drive); - disk->private_data = p; - set_capacity(disk, p->head * p->sect * p->cyl); - disk->queue = hd_queue; - p->unit = drive; - hd_gendisk[drive] = disk; - printk("%s: %luMB, CHS=%d/%d/%d\n", - disk->disk_name, (unsigned long)get_capacity(disk)/2048, - p->cyl, p->head, p->sect); - } - - if (request_irq(HD_IRQ, hd_interrupt, IRQF_DISABLED, "hd", NULL)) { - printk("hd: unable to get IRQ%d for the hard disk driver\n", - HD_IRQ); - goto out1; - } - if (!request_region(HD_DATA, 8, "hd")) { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); - goto out2; - } - if (!request_region(HD_CMD, 1, "hd(cmd)")) { - printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD); - goto out3; - } - - /* Let them fly */ - for (drive = 0; drive < NR_HD; drive++) - add_disk(hd_gendisk[drive]); - - return 0; - -out3: - release_region(HD_DATA, 8); -out2: - free_irq(HD_IRQ, NULL); -out1: - for (drive = 0; drive < NR_HD; drive++) - put_disk(hd_gendisk[drive]); - NR_HD = 0; -out: - del_timer(&device_timer); - unregister_blkdev(MAJOR_NR, "hd"); - blk_cleanup_queue(hd_queue); - return -1; -Enomem: - while (drive--) - put_disk(hd_gendisk[drive]); - goto out; -} - -static int __init parse_hd_setup(char *line) -{ - int ints[6]; - - (void) get_options(line, ARRAY_SIZE(ints), ints); - hd_setup(NULL, ints); - - return 1; -} -__setup("hd=", parse_hd_setup); - -late_initcall(hd_init); -- cgit v0.10.2 From f327c1c33f4882c70f29ff3a9ff7c55c1951d1f6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:47 +0200 Subject: update the BLK_DEV_HD help text Many people will see this option the first time now that it is in drivers/block/ Make it clear that virtually noone needs it. Signed-off-by: Adrian Bunk Cc: rmk@arm.linux.org.uk Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index c390974..61ad8d6 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -434,27 +434,15 @@ config VIRTIO_BLK lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. config BLK_DEV_HD - bool "Old hard disk (MFM/RLL/IDE) driver" + bool "Very old hard disk (MFM/RLL/IDE) driver" depends on HAVE_IDE depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN help - There are two drivers for MFM/RLL/IDE hard disks. Most people use - the newer enhanced driver, but this old one is still around for two - reasons. Some older systems have strange timing problems and seem to - work only with the old driver (which itself does not work with some - newer systems). The other reason is that the old driver is smaller, - since it lacks the enhanced functionality of the new one. This makes - it a good choice for systems with very tight memory restrictions, or - for systems with only older MFM/RLL/ESDI drives. Choosing the old - driver can save 13 KB or so of kernel memory. - - If you want to use this driver together with the new one you have - to use "hda=noprobe hdb=noprobe" kernel parameters to prevent the new - driver from probing the primary interface. - - If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver - instead of this one. For more detailed information, read the - Disk-HOWTO, available from - . + This is a very old hard disk driver that lacks the enhanced + functionality of the newer ones. + + It is required for systems with ancient MFM/RLL/ESDI drives. + + If unsure, say N. endif # BLK_DEV -- cgit v0.10.2 From 72a3d651b2fe341a8ae2ca164c395aa3007350cd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: hd.c: remove the #include The code that needed this #include was removed one year ago. Signed-off-by: Adrian Bunk Cc: rmk@arm.linux.org.uk Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 00b6956..682243b 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -37,7 +37,6 @@ #include #include #include -#include /* CMOS defines */ #include #include #include -- cgit v0.10.2 From 79e36a9f54aaf4a52eb2d9520953aa3960e99294 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: IDE: Fix HDIO_DRIVE_RESET handling Currently, the code path executing an HDIO_DRIVE_RESET ioctl is broken in various ways. Most importantly, it is treated as an out of band request in an illegal way which may very likely lead to system lock ups. Use the drive's request queue to avoid this problem (and fix a locking issue for free along the way). Signed-off-by: Elias Oltmanns Cc: "Alan Cox" Cc: "Randy Dunlap" Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2805774..2b33c12 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -766,6 +766,18 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, return ide_stopped; } +static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) +{ + switch (rq->cmd[0]) { + case REQ_DRIVE_RESET: + return ide_do_reset(drive); + default: + blk_dump_rq_flags(rq, "ide_special_rq - bad request"); + ide_end_request(drive, 0, 0); + return ide_stopped; + } +} + static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) { struct request_pm_state *pm = rq->data; @@ -869,7 +881,16 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) pm->pm_step == ide_pm_state_completed) ide_complete_pm_request(drive, rq); return startstop; - } + } else if (!rq->rq_disk && blk_special_request(rq)) + /* + * TODO: Once all ULDs have been modified to + * check for specific op codes rather than + * blindly accepting any special request, the + * check for ->rq_disk above may be replaced + * by a more suitable mechanism or even + * dropped entirely. + */ + return ide_special_rq(drive, rq); drv = *(ide_driver_t **)rq->rq_disk->private_data; return drv->do_request(drive, rq, block); diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 80ad4f2..96f63eb 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -905,6 +905,14 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) } EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); +static inline void ide_complete_drive_reset(ide_drive_t *drive) +{ + struct request *rq = drive->hwif->hwgroup->rq; + + if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) + ide_end_request(drive, 1, 0); +} + /* needed below */ static ide_startstop_t do_reset1 (ide_drive_t *, int); @@ -940,7 +948,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) } /* done polling */ hwgroup->polling = 0; - hwgroup->resetting = 0; + ide_complete_drive_reset(drive); return ide_stopped; } @@ -961,7 +969,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) if (port_ops->reset_poll(drive)) { printk(KERN_ERR "%s: host reset_poll failure for %s.\n", hwif->name, drive->name); - return ide_stopped; + goto out; } } @@ -1004,7 +1012,8 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) } } hwgroup->polling = 0; /* done polling */ - hwgroup->resetting = 0; /* done reset attempt */ +out: + ide_complete_drive_reset(drive); return ide_stopped; } @@ -1090,7 +1099,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) /* For an ATAPI device, first try an ATAPI SRST. */ if (drive->media != ide_disk && !do_not_try_atapi) { - hwgroup->resetting = 1; pre_reset(drive); SELECT_DRIVE(drive); udelay (20); @@ -1112,10 +1120,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) if (io_ports->ctl_addr == 0) { spin_unlock_irqrestore(&ide_lock, flags); + ide_complete_drive_reset(drive); return ide_stopped; } - hwgroup->resetting = 1; /* * Note that we also set nIEN while resetting the device, * to mask unwanted interrupts from the interface during the reset. diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 90ae00d..1ec983b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -529,6 +529,19 @@ static int generic_ide_resume(struct device *dev) return err; } +static void generic_drive_reset(ide_drive_t *drive) +{ + struct request *rq; + + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->cmd_len = 1; + rq->cmd[0] = REQ_DRIVE_RESET; + rq->cmd_flags |= REQ_SOFTBARRIER; + blk_execute_rq(drive->queue, NULL, rq, 1); + blk_put_request(rq); +} + int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, unsigned int cmd, unsigned long arg) { @@ -603,33 +616,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device if (!capable(CAP_SYS_ADMIN)) return -EACCES; - /* - * Abort the current command on the - * group if there is one, taking - * care not to allow anything else - * to be queued and to die on the - * spot if we miss one somehow - */ - - spin_lock_irqsave(&ide_lock, flags); - - if (HWGROUP(drive)->resetting) { - spin_unlock_irqrestore(&ide_lock, flags); - return -EBUSY; - } - - ide_abort(drive, "drive reset"); - - BUG_ON(HWGROUP(drive)->handler); - - /* Ensure nothing gets queued after we - drop the lock. Reset will clear the busy */ - - HWGROUP(drive)->busy = 1; - spin_unlock_irqrestore(&ide_lock, flags); - (void) ide_do_reset(drive); - + generic_drive_reset(drive); return 0; + case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/include/linux/ide.h b/include/linux/ide.h index f9cbe93..021710c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -139,6 +139,12 @@ struct ide_io_ports { #define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ /* + * Op codes for special requests to be handled by ide_special_rq(). + * Values should be in the range of 0x20 to 0x3f. + */ +#define REQ_DRIVE_RESET 0x20 + +/* * Check for an interrupt and acknowledge the interrupt status */ struct hwif_s; -- cgit v0.10.2 From 3ef5eb424ebf0cd981192a416358fd707a9f959b Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: IDE: Remove unused code Remove some code which has been made obsolete and hasn't worked properly before anyway. Part of the infrastructure may be reintroduced in a follow up patch to implement a working command aborting facility. Signed-off-by: Elias Oltmanns Cc: "Alan Cox" Cc: "Randy Dunlap" Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 2b3c69d..6e29dd5 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1952,7 +1952,6 @@ static ide_driver_t ide_cdrom_driver = { .do_request = ide_cd_do_request, .end_request = ide_end_request, .error = __ide_error, - .abort = __ide_abort, #ifdef CONFIG_IDE_PROC_FS .proc = idecd_proc, #endif diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5f49a4a..3a2e802 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -985,7 +985,6 @@ static ide_driver_t idedisk_driver = { .do_request = ide_do_rw_disk, .end_request = ide_end_request, .error = __ide_error, - .abort = __ide_abort, #ifdef CONFIG_IDE_PROC_FS .proc = idedisk_proc, #endif diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index c7e4433..011d720 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -1129,7 +1129,6 @@ static ide_driver_t idefloppy_driver = { .do_request = idefloppy_do_request, .end_request = idefloppy_end_request, .error = __ide_error, - .abort = __ide_abort, #ifdef CONFIG_IDE_PROC_FS .proc = idefloppy_proc, #endif diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2b33c12..661b75a 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -504,55 +504,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) EXPORT_SYMBOL_GPL(ide_error); -ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq) -{ - if (drive->media != ide_disk) - rq->errors |= ERROR_RESET; - - ide_kill_rq(drive, rq); - - return ide_stopped; -} - -EXPORT_SYMBOL_GPL(__ide_abort); - -/** - * ide_abort - abort pending IDE operations - * @drive: drive the error occurred on - * @msg: message to report - * - * ide_abort kills and cleans up when we are about to do a - * host initiated reset on active commands. Longer term we - * want handlers to have sensible abort handling themselves - * - * This differs fundamentally from ide_error because in - * this case the command is doing just fine when we - * blow it away. - */ - -ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) -{ - struct request *rq; - - if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) - return ide_stopped; - - /* retry only "normal" I/O: */ - if (!blk_fs_request(rq)) { - rq->errors = 1; - ide_end_drive_cmd(drive, BUSY_STAT, 0); - return ide_stopped; - } - - if (rq->rq_disk) { - ide_driver_t *drv; - - drv = *(ide_driver_t **)rq->rq_disk->private_data; - return drv->abort(drive, rq); - } else - return __ide_abort(drive, rq); -} - static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) { tf->nsect = drive->sect; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index f9cf167..b711ab9 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2591,7 +2591,6 @@ static ide_driver_t idetape_driver = { .do_request = idetape_do_request, .end_request = idetape_end_request, .error = __ide_error, - .abort = __ide_abort, #ifdef CONFIG_IDE_PROC_FS .proc = idetape_proc, #endif diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 683bce3..f843c13 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -258,19 +258,6 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) return ide_stopped; } -static ide_startstop_t -idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) -{ - debug_log("%s called for %lu\n", __func__, - ((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number); - - rq->errors |= ERROR_MAX; - - idescsi_end_request(drive, 0, 0); - - return ide_stopped; -} - static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); @@ -524,7 +511,6 @@ static ide_driver_t idescsi_driver = { .do_request = idescsi_do_request, .end_request = idescsi_end_request, .error = idescsi_atapi_error, - .abort = idescsi_atapi_abort, #ifdef CONFIG_IDE_PROC_FS .proc = idescsi_proc, #endif diff --git a/include/linux/ide.h b/include/linux/ide.h index 021710c..4726126 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -571,8 +571,6 @@ typedef struct hwgroup_s { unsigned int sleeping : 1; /* BOOL: polling active & poll_timeout field valid */ unsigned int polling : 1; - /* BOOL: in a polling reset situation. Must not trigger another reset yet */ - unsigned int resetting : 1; /* current drive */ ide_drive_t *drive; @@ -792,7 +790,6 @@ struct ide_driver_s { ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t); int (*end_request)(ide_drive_t *, int, int); ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8); - ide_startstop_t (*abort)(ide_drive_t *, struct request *rq); struct device_driver gen_driver; int (*probe)(ide_drive_t *); void (*remove)(ide_drive_t *); @@ -834,10 +831,6 @@ ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8); ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat); -ide_startstop_t __ide_abort(ide_drive_t *, struct request *); - -extern ide_startstop_t ide_abort(ide_drive_t *, const char *); - extern void ide_fix_driveid(struct hd_driveid *); extern void ide_fixstring(u8 *, const int, const int); -- cgit v0.10.2 From bb7ee9b1ec15358af870a81b0c6a03af29417f99 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: Update documentation of HDIO_DRIVE_RESET ioctl Alter the entry for HDIO_DRIVE_RESET in Documentation/ioctl/hdio.txt to reflect a functional change in the driver. Besides, the entry has been inaccurate before. Signed-off-by: Elias Oltmanns Cc: "Alan Cox" Cc: "Randy Dunlap" Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt index c19efde..44d283d 100644 --- a/Documentation/ioctl/hdio.txt +++ b/Documentation/ioctl/hdio.txt @@ -511,9 +511,8 @@ HDIO_DRIVE_RESET execute a device reset notes: - Abort any current command, prevent anything else from being - queued, execute a reset on the device, and issue BLKRRPART - ioctl on the block device. + Execute a reset on the device as soon as the current IO + operation has completed. Executes an ATAPI soft reset if applicable, otherwise executes an ATA soft reset on the controller. -- cgit v0.10.2 From 64a8f00ff19508b3962c8a932375dbae88bee4d6 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Wed, 16 Jul 2008 20:33:48 +0200 Subject: IDE: Report errors during drive reset back to user space Make sure that each error condition during the execution of an HDIO_DRIVE_RESET ioctl is actually reported to the calling process. Also, unify the exit path of reset_pollfunc() when returning ide_stopped since the need of ->port_ops->reset_poll() to be treated specially has vanished (way back, it seems). Signed-off-by: Elias Oltmanns Cc: "Alan Cox" Cc: "Randy Dunlap" Signed-off-by: Bartlomiej Zolnierkiewicz diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt index 44d283d..91a6ecb 100644 --- a/Documentation/ioctl/hdio.txt +++ b/Documentation/ioctl/hdio.txt @@ -508,6 +508,8 @@ HDIO_DRIVE_RESET execute a device reset error returns: EACCES Access denied: requires CAP_SYS_ADMIN + ENXIO No such device: phy dead or ctl_addr == 0 + EIO I/O error: reset timed out or hardware error notes: diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 96f63eb..44aaec2 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -905,12 +905,12 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) } EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); -static inline void ide_complete_drive_reset(ide_drive_t *drive) +static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) { struct request *rq = drive->hwif->hwgroup->rq; if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) - ide_end_request(drive, 1, 0); + ide_end_request(drive, err ? err : 1, 0); } /* needed below */ @@ -948,7 +948,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) } /* done polling */ hwgroup->polling = 0; - ide_complete_drive_reset(drive); + ide_complete_drive_reset(drive, 0); return ide_stopped; } @@ -964,9 +964,11 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); const struct ide_port_ops *port_ops = hwif->port_ops; u8 tmp; + int err = 0; if (port_ops && port_ops->reset_poll) { - if (port_ops->reset_poll(drive)) { + err = port_ops->reset_poll(drive); + if (err) { printk(KERN_ERR "%s: host reset_poll failure for %s.\n", hwif->name, drive->name); goto out; @@ -983,6 +985,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) } printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); drive->failures++; + err = -EIO; } else { printk("%s: reset: ", hwif->name); tmp = ide_read_error(drive); @@ -1009,11 +1012,12 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) if (tmp & 0x80) printk("; slave: failed"); printk("\n"); + err = -EIO; } } - hwgroup->polling = 0; /* done polling */ out: - ide_complete_drive_reset(drive); + hwgroup->polling = 0; /* done polling */ + ide_complete_drive_reset(drive, err); return ide_stopped; } @@ -1120,7 +1124,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) if (io_ports->ctl_addr == 0) { spin_unlock_irqrestore(&ide_lock, flags); - ide_complete_drive_reset(drive); + ide_complete_drive_reset(drive, -ENXIO); return ide_stopped; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 1ec983b..d4a6b10 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -529,17 +529,20 @@ static int generic_ide_resume(struct device *dev) return err; } -static void generic_drive_reset(ide_drive_t *drive) +static int generic_drive_reset(ide_drive_t *drive) { struct request *rq; + int ret = 0; rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_len = 1; rq->cmd[0] = REQ_DRIVE_RESET; rq->cmd_flags |= REQ_SOFTBARRIER; - blk_execute_rq(drive->queue, NULL, rq, 1); + if (blk_execute_rq(drive->queue, NULL, rq, 1)) + ret = rq->errors; blk_put_request(rq); + return ret; } int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, @@ -616,8 +619,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device if (!capable(CAP_SYS_ADMIN)) return -EACCES; - generic_drive_reset(drive); - return 0; + return generic_drive_reset(drive); case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index b75e9bb..6e9d765 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -421,8 +421,7 @@ static int sil_sata_reset_poll(ide_drive_t *drive) if ((sata_stat & 0x03) != 0x03) { printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", hwif->name, sata_stat); - HWGROUP(drive)->polling = 0; - return ide_started; + return -ENXIO; } } -- cgit v0.10.2 From bef5b54bd7bf8117c75cb943d64549134c6d9a1f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 16 Jul 2008 13:02:24 +0100 Subject: Fix MIPS cross-compile problem Crosscompiling on a Fedora 9 machine running gcc 4.3.0 as its host compiler and gcc 3.4.6 for the mips-linux target results in the following build error: $ make malta_defconfig $ make cc1: error: unrecognized command line option "-fno-stack-protector" scripts/kconfig/conf -s arch/mips/Kconfig cc1: error: unrecognized command line option "-fno-stack-protector" The arch Makefile is included too late so the host compiler is feature tested, not the crosscompiler as intended and thus the Makefile applies adds -fno-stack-protector to crosscompiler's flags which fails for gcc 3.4.6. The bug was introduced by e06b8b98da071f7dd78fb7822991694288047df0 in 2.6.25; 35bb5b1e0e84cfa1a8906f7e6a77f391ff315791 did add more flags testing before the arch Makefile inclusion. Signed-off-by: Ralf Baechle Signed-off-by: Linus Torvalds diff --git a/Makefile b/Makefile index 8a2a275..1564577 100644 --- a/Makefile +++ b/Makefile @@ -508,6 +508,8 @@ else KBUILD_CFLAGS += -O2 endif +include $(srctree)/arch/$(SRCARCH)/Makefile + ifneq (CONFIG_FRAME_WARN,0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif @@ -516,8 +518,6 @@ endif # Arch Makefiles may override this setting KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) -include $(srctree)/arch/$(SRCARCH)/Makefile - ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls else -- cgit v0.10.2 From e3621ee633810be1079d0fa65ac2c904f53b73fa Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 16 Jul 2008 08:39:12 -0500 Subject: powerpc/ep8248e: Fix compile problem if !CONFIG_FS_ENET If we don't enable FS_ENET we get build issues: arch/powerpc/platforms/built-in.o: In function `ep8248e_mdio_probe': arch/powerpc/platforms/82xx/ep8248e.c:129: undefined reference to `alloc_mdio_bitbang' arch/powerpc/platforms/82xx/ep8248e.c:143: undefined reference to `mdiobus_register' Signed-off-by: Kumar Gala Signed-off-by: Linus Torvalds diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index d5770fd..373e993 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -59,6 +59,7 @@ static void __init ep8248e_pic_init(void) of_node_put(np); } +#ifdef CONFIG_FS_ENET_MDIO_FCC static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level) { if (level) @@ -164,6 +165,7 @@ static struct of_platform_driver ep8248e_mdio_driver = { .probe = ep8248e_mdio_probe, .remove = ep8248e_mdio_remove, }; +#endif struct cpm_pin { int port, pin, flags; @@ -296,7 +298,9 @@ static __initdata struct of_device_id of_bus_ids[] = { static int __init declare_of_platform_devices(void) { of_platform_bus_probe(NULL, of_bus_ids, NULL); +#ifdef CONFIG_FS_ENET_MDIO_FCC of_register_platform_driver(&ep8248e_mdio_driver); +#endif return 0; } -- cgit v0.10.2 From 3c3622dcb64c76c9abd2e468f802db9ba523421c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 16 Jul 2008 08:52:00 -0500 Subject: Fix compile issues in fs/compat_ioctl.c when CONFIG_BLOCK is disabled Fix fs/compat_ioctl.c to handle CONFIG_BLOCK=n, CONFIG_SCSI=n to avoid build errors: In file included from include/scsi/scsi.h:12, from fs/compat_ioctl.c:71: include/scsi/scsi_cmnd.h:27:25: warning: "BLK_MAX_CDB" is not defined include/scsi/scsi_cmnd.h:28:3: error: #error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB In file included from include/scsi/scsi.h:12, from fs/compat_ioctl.c:71: include/scsi/scsi_cmnd.h: In function 'scsi_bidi_cmnd': include/scsi/scsi_cmnd.h:182: error: implicit declaration of function 'blk_bidi_rq' include/scsi/scsi_cmnd.h:183: error: dereferencing pointer to incomplete type include/scsi/scsi_cmnd.h: In function 'scsi_in': include/scsi/scsi_cmnd.h:189: error: dereferencing pointer to incomplete type Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 97dba0d..c54eaab 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -69,9 +69,11 @@ #include #include +#ifdef CONFIG_BLOCK #include #include #include +#endif #include #include @@ -2024,6 +2026,7 @@ COMPATIBLE_IOCTL(GIO_UNISCRNMAP) COMPATIBLE_IOCTL(PIO_UNISCRNMAP) COMPATIBLE_IOCTL(PIO_FONTRESET) COMPATIBLE_IOCTL(PIO_UNIMAPCLR) +#ifdef CONFIG_BLOCK /* Big S */ COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK) @@ -2033,6 +2036,7 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER) COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND) COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) +#endif /* Big T */ COMPATIBLE_IOCTL(TUNSETNOCSUM) COMPATIBLE_IOCTL(TUNSETDEBUG) @@ -2103,6 +2107,7 @@ COMPATIBLE_IOCTL(SIOCGIFVLAN) COMPATIBLE_IOCTL(SIOCSIFVLAN) COMPATIBLE_IOCTL(SIOCBRADDBR) COMPATIBLE_IOCTL(SIOCBRDELBR) +#ifdef CONFIG_BLOCK /* SG stuff */ COMPATIBLE_IOCTL(SG_SET_TIMEOUT) COMPATIBLE_IOCTL(SG_GET_TIMEOUT) @@ -2127,6 +2132,7 @@ COMPATIBLE_IOCTL(SG_SCSI_RESET) COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN) COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN) +#endif /* PPP stuff */ COMPATIBLE_IOCTL(PPPIOCGFLAGS) COMPATIBLE_IOCTL(PPPIOCSFLAGS) -- cgit v0.10.2 From 26d46867b7d27f68a446b073dac7817721ae4c8f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Apr 2008 02:35:48 -0400 Subject: fix a deadlock issue when poking "eject" file "/sys/devices/LNXSYSTM:00/.../eject" is used to evaluate _EJx method and eject a device in user space. But system hangs when poking the "eject" file because that the device hot-removal code invoke the driver .remove method which will try to remove the "eject" file as a result. Queues the hot-removal function for deferred execution in this patch. http://bugzilla.kernel.org/show_bug.cgi?id=9772 Signed-off-by: Zhang Rui Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 6d85289..9a84ed2 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include /* for acpi_ex_eisa_id_to_string() */ @@ -92,17 +93,37 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); -static int acpi_eject_operation(acpi_handle handle, int lockable) +static int acpi_bus_hot_remove_device(void *context) { + struct acpi_device *device; + acpi_handle handle = context; struct acpi_object_list arg_list; union acpi_object arg; acpi_status status = AE_OK; - /* - * TBD: evaluate _PS3? - */ + if (acpi_bus_get_device(handle, &device)) + return 0; - if (lockable) { + if (!device) + return 0; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Hot-removing device %s...\n", device->dev.bus_id)); + + + if (acpi_bus_trim(device, 1)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Removing device failed\n")); + return -1; + } + + /* power off device */ + status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Power-off device failed\n")); + + if (device->flags.lockable) { arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; @@ -118,24 +139,19 @@ static int acpi_eject_operation(acpi_handle handle, int lockable) /* * TBD: _EJD support. */ - status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - return (-ENODEV); - } + if (ACPI_FAILURE(status)) + return -ENODEV; - return (0); + return 0; } static ssize_t acpi_eject_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - int result; int ret = count; - int islockable; acpi_status status; - acpi_handle handle; acpi_object_type type = 0; struct acpi_device *acpi_device = to_acpi_device(d); @@ -154,17 +170,9 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, goto err; } - islockable = acpi_device->flags.lockable; - handle = acpi_device->handle; - - result = acpi_bus_trim(acpi_device, 1); - - if (!result) - result = acpi_eject_operation(handle, islockable); - - if (result) { - ret = -EBUSY; - } + /* remove the device in another thread to fix the deadlock issue */ + ret = kernel_thread(acpi_bus_hot_remove_device, + acpi_device->handle, SIGCHLD); err: return ret; } -- cgit v0.10.2 From b62b8ef906cdf7115af579ce7378886ce3e0ce00 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Apr 2008 02:35:56 -0400 Subject: force offline the processor during hot-removal The ACPI device node for the cpu has already been unregistered when acpi_processor_handle_eject is called. Thus we should offline the cpu and continue, rather than a failure here. http://bugzilla.kernel.org/show_bug.cgi?id=9772 Signed-off-by: Zhang Rui Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 9dd0fa9..1c0008e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -1014,9 +1014,9 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) static int acpi_processor_handle_eject(struct acpi_processor *pr) { - if (cpu_online(pr->id)) { - return (-EINVAL); - } + if (cpu_online(pr->id)) + cpu_down(pr->id); + arch_unregister_cpu(pr->id); acpi_unmap_lsapic(pr->id); return (0); diff --git a/kernel/cpu.c b/kernel/cpu.c index b11f06d..cfb1d43 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -299,6 +299,7 @@ int __ref cpu_down(unsigned int cpu) cpu_maps_update_done(); return err; } +EXPORT_SYMBOL(cpu_down); #endif /*CONFIG_HOTPLUG_CPU*/ /* Requires cpu_add_remove_lock to be held */ -- cgit v0.10.2 From 9f1eb99c757939b0b1783f926130993e9c298bae Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 29 Apr 2008 02:36:07 -0400 Subject: create sysfs link from acpi device to sysdev for cpu Sys I/F under acpi device node and sysdev device node are both needed for cpu hot-removal. User space need this link so that they know they are poking the sys I/F for the same cpu. http://bugzilla.kernel.org/show_bug.cgi?id=9772 Signed-off-by: Zhang Rui Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 1c0008e..feddc8e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -621,7 +621,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) int result = 0; acpi_status status = AE_OK; struct acpi_processor *pr; - + struct sys_device *sysdev; pr = acpi_driver_data(device); @@ -652,6 +652,10 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) if (result) goto end; + sysdev = get_cpu_sysdev(pr->id); + if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) + return -EFAULT; + status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, acpi_processor_notify, pr); @@ -810,6 +814,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type) status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, acpi_processor_notify); + sysfs_remove_link(&device->dev.kobj, "sysdev"); + acpi_processor_remove_fs(device); if (pr->cdev) { -- cgit v0.10.2 From 5411552c707f4b7387ad63141ef3a559e7488091 Mon Sep 17 00:00:00 2001 From: Cezary Jackiewicz Date: Mon, 9 Jun 2008 16:22:22 -0700 Subject: misc,acpi,backlight: compal Laptop Extras This is driver for Compal Laptop: FL90/IFL90, based on MSI driver. This driver exports a few files in /sys/devices/platform/compal-laptop/: lcd_level - screen brightness: contains a single integer in the range 0..7 (rw) wlan - wlan subsystem state: contains 0 or 1 (rw) bluetooth - bluetooth subsystem state: contains 0 or 1 (rw) raw - raw value taken from embedded controller register (ro) In addition to these platform device attributes the driver registers itself in the Linux backlight control subsystem and is available to userspace under /sys/class/backlight/compal-laptop/. Signed-off-by: Cezary Jackiewicz Signed-off-by: Andi Kleen Cc: Richard Purdie Cc: Henrique de Moraes Holschuh Cc: Len Brown Cc: Alexey Starikovskiy Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/MAINTAINERS b/MAINTAINERS index ee1c56a..2bfde03 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1160,6 +1160,11 @@ M: scott@spiteful.org L: pcihpd-discuss@lists.sourceforge.net S: Supported +COMPAL LAPTOP SUPPORT +P: Cezary Jackiewicz +M: cezary.jackiewicz@gmail.com +S: Maintained + COMPUTONE INTELLIPORT MULTIPORT CARD P: Michael H. Warfield M: mhw@wittsend.com diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 636af28..7fce0da 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -219,6 +219,23 @@ config MSI_LAPTOP If you have an MSI S270 laptop, say Y or M here. +config COMPAL_LAPTOP + tristate "Compal Laptop Extras" + depends on X86 + depends on ACPI_EC + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is a driver for laptops built by Compal: + + Compal FL90/IFL90 + Compal FL91/IFL91 + Compal FL92/JFL92 + Compal FT00/IFT00 + + It adds support for Bluetooth, WLAN and LCD brightness control. + + If you have an Compal FL9x/IFL9x/FT00 laptop, say Y or M here. + config SONY_LAPTOP tristate "Sony Laptop Extras" depends on X86 && ACPI diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 1952875..a6dac6a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -5,10 +5,11 @@ obj- := misc.o # Dummy rule to force built-in.o to be made obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ -obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o -obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o +obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o +obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o +obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c new file mode 100644 index 0000000..0c1f587 --- /dev/null +++ b/drivers/misc/compal-laptop.c @@ -0,0 +1,437 @@ +/*-*-linux-c-*-*/ + +/* + Copyright (C) 2008 Cezary Jackiewicz + + based on MSI driver + + Copyright (C) 2006 Lennart Poettering + + 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + */ + +/* + * comapl-laptop.c - Compal laptop support. + * + * This driver exports a few files in /sys/devices/platform/compal-laptop/: + * + * lcd_level - Screen brightness: contains a single integer in the + * range 0..7. (rw) + * + * wlan - wlan subsystem state: contains 0 or 1 (rw) + * + * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw) + * + * raw - raw value taken from embedded controller register (ro) + * + * In addition to these platform device attributes the driver + * registers itself in the Linux backlight control subsystem and is + * available to userspace under /sys/class/backlight/compal-laptop/. + * + * This driver might work on other laptops produced by Compal. If you + * want to try it you can pass force=1 as argument to the module which + * will force it to load even when the DMI data doesn't identify the + * laptop as IFL90. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define COMPAL_DRIVER_VERSION "0.2.5" + +#define COMPAL_LCD_LEVEL_MAX 8 + +#define COMPAL_EC_COMMAND_WIRELESS 0xBB +#define COMPAL_EC_COMMAND_LCD_LEVEL 0xB9 + +#define KILLSWITCH_MASK 0x10 +#define WLAN_MASK 0x01 +#define BT_MASK 0x02 + +static int force; +module_param(force, bool, 0); +MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); + +/* Hardware access */ + +static int set_lcd_level(int level) +{ + if (level < 0 || level >= COMPAL_LCD_LEVEL_MAX) + return -EINVAL; + + ec_write(COMPAL_EC_COMMAND_LCD_LEVEL, level); + + return 0; +} + +static int get_lcd_level(void) +{ + u8 result; + + ec_read(COMPAL_EC_COMMAND_LCD_LEVEL, &result); + + return (int) result; +} + +static int set_wlan_state(int state) +{ + u8 result, value; + + ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); + + if ((result & KILLSWITCH_MASK) == 0) + return -EINVAL; + else { + if (state) + value = (u8) (result | WLAN_MASK); + else + value = (u8) (result & ~WLAN_MASK); + ec_write(COMPAL_EC_COMMAND_WIRELESS, value); + } + + return 0; +} + +static int set_bluetooth_state(int state) +{ + u8 result, value; + + ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); + + if ((result & KILLSWITCH_MASK) == 0) + return -EINVAL; + else { + if (state) + value = (u8) (result | BT_MASK); + else + value = (u8) (result & ~BT_MASK); + ec_write(COMPAL_EC_COMMAND_WIRELESS, value); + } + + return 0; +} + +static int get_wireless_state(int *wlan, int *bluetooth) +{ + u8 result; + + ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); + + if (wlan) { + if ((result & KILLSWITCH_MASK) == 0) + *wlan = 0; + else + *wlan = result & WLAN_MASK; + } + + if (bluetooth) { + if ((result & KILLSWITCH_MASK) == 0) + *bluetooth = 0; + else + *bluetooth = (result & BT_MASK) >> 1; + } + + return 0; +} + +/* Backlight device stuff */ + +static int bl_get_brightness(struct backlight_device *b) +{ + return get_lcd_level(); +} + + +static int bl_update_status(struct backlight_device *b) +{ + return set_lcd_level(b->props.brightness); +} + +static struct backlight_ops compalbl_ops = { + .get_brightness = bl_get_brightness, + .update_status = bl_update_status, +}; + +static struct backlight_device *compalbl_device; + +/* Platform device */ + +static ssize_t show_wlan(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret, enabled; + + ret = get_wireless_state(&enabled, NULL); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", enabled); +} + +static ssize_t show_raw(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 result; + + ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); + + return sprintf(buf, "%i\n", result); +} + +static ssize_t show_bluetooth(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret, enabled; + + ret = get_wireless_state(NULL, &enabled); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", enabled); +} + +static ssize_t show_lcd_level(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + ret = get_lcd_level(); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", ret); +} + +static ssize_t store_lcd_level(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int level, ret; + + if (sscanf(buf, "%i", &level) != 1 || + (level < 0 || level >= COMPAL_LCD_LEVEL_MAX)) + return -EINVAL; + + ret = set_lcd_level(level); + if (ret < 0) + return ret; + + return count; +} + +static ssize_t store_wlan_state(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int state, ret; + + if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1)) + return -EINVAL; + + ret = set_wlan_state(state); + if (ret < 0) + return ret; + + return count; +} + +static ssize_t store_bluetooth_state(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int state, ret; + + if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1)) + return -EINVAL; + + ret = set_bluetooth_state(state); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); +static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state); +static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state); +static DEVICE_ATTR(raw, 0444, show_raw, NULL); + +static struct attribute *compal_attributes[] = { + &dev_attr_lcd_level.attr, + &dev_attr_bluetooth.attr, + &dev_attr_wlan.attr, + &dev_attr_raw.attr, + NULL +}; + +static struct attribute_group compal_attribute_group = { + .attrs = compal_attributes +}; + +static struct platform_driver compal_driver = { + .driver = { + .name = "compal-laptop", + .owner = THIS_MODULE, + } +}; + +static struct platform_device *compal_device; + +/* Initialization */ + +static int dmi_check_cb(const struct dmi_system_id *id) +{ + printk(KERN_INFO "compal-laptop: Identified laptop model '%s'.\n", + id->ident); + + return 0; +} + +static struct dmi_system_id __initdata compal_dmi_table[] = { + { + .ident = "FL90/IFL90", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "IFL90"), + DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), + }, + .callback = dmi_check_cb + }, + { + .ident = "FL90/IFL90", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "IFL90"), + DMI_MATCH(DMI_BOARD_VERSION, "REFERENCE"), + }, + .callback = dmi_check_cb + }, + { + .ident = "FL91/IFL91", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "IFL91"), + DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), + }, + .callback = dmi_check_cb + }, + { + .ident = "FL92/JFL92", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "JFL92"), + DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), + }, + .callback = dmi_check_cb + }, + { + .ident = "FT00/IFT00", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "IFT00"), + DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), + }, + .callback = dmi_check_cb + }, + { } +}; + +static int __init compal_init(void) +{ + int ret; + + if (acpi_disabled) + return -ENODEV; + + if (!force && !dmi_check_system(compal_dmi_table)) + return -ENODEV; + + /* Register backlight stuff */ + + compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, + &compalbl_ops); + if (IS_ERR(compalbl_device)) + return PTR_ERR(compalbl_device); + + compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; + + ret = platform_driver_register(&compal_driver); + if (ret) + goto fail_backlight; + + /* Register platform stuff */ + + compal_device = platform_device_alloc("compal-laptop", -1); + if (!compal_device) { + ret = -ENOMEM; + goto fail_platform_driver; + } + + ret = platform_device_add(compal_device); + if (ret) + goto fail_platform_device1; + + ret = sysfs_create_group(&compal_device->dev.kobj, + &compal_attribute_group); + if (ret) + goto fail_platform_device2; + + printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION + " successfully loaded.\n"); + + return 0; + +fail_platform_device2: + + platform_device_del(compal_device); + +fail_platform_device1: + + platform_device_put(compal_device); + +fail_platform_driver: + + platform_driver_unregister(&compal_driver); + +fail_backlight: + + backlight_device_unregister(compalbl_device); + + return ret; +} + +static void __exit compal_cleanup(void) +{ + + sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group); + platform_device_unregister(compal_device); + platform_driver_unregister(&compal_driver); + backlight_device_unregister(compalbl_device); + + printk(KERN_INFO "compal-laptop: driver unloaded.\n"); +} + +module_init(compal_init); +module_exit(compal_cleanup); + +MODULE_AUTHOR("Cezary Jackiewicz"); +MODULE_DESCRIPTION("Compal Laptop Support"); +MODULE_VERSION(COMPAL_DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +MODULE_ALIAS("dmi:*:rnIFL90:rvrIFT00:*"); +MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*"); +MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*"); +MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*"); +MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*"); -- cgit v0.10.2 From 706546d02384b64e083bd9130c56eaa599c66038 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Mon, 9 Jun 2008 16:22:23 -0700 Subject: ACPI: change processors from array to per_cpu variable Change processors from an array sized by NR_CPUS to a per_cpu variable. Signed-off-by: Mike Travis Signed-off-by: Andrew Morton Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index feddc8e..9a803f8 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -118,7 +118,7 @@ static const struct file_operations acpi_processor_info_fops = { .release = single_release, }; -struct acpi_processor *processors[NR_CPUS]; +DEFINE_PER_CPU(struct acpi_processor *, processors); struct acpi_processor_errata errata __read_mostly; /* -------------------------------------------------------------------------- @@ -614,7 +614,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) return 0; } -static void *processor_device_array[NR_CPUS]; +static DEFINE_PER_CPU(void *, processor_device_array); static int __cpuinit acpi_processor_start(struct acpi_device *device) { @@ -638,15 +638,15 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) * ACPI id of processors can be reported wrongly by the BIOS. * Don't trust it blindly */ - if (processor_device_array[pr->id] != NULL && - processor_device_array[pr->id] != device) { + if (per_cpu(processor_device_array, pr->id) != NULL && + per_cpu(processor_device_array, pr->id) != device) { printk(KERN_WARNING "BIOS reported wrong ACPI id " "for the processor\n"); return -ENODEV; } - processor_device_array[pr->id] = device; + per_cpu(processor_device_array, pr->id) = device; - processors[pr->id] = pr; + per_cpu(processors, pr->id) = pr; result = acpi_processor_add_fs(device); if (result) @@ -753,7 +753,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; - struct acpi_processor *pr = processors[cpu]; + struct acpi_processor *pr = per_cpu(processors, cpu); if (action == CPU_ONLINE && pr) { acpi_processor_ppc_has_changed(pr); @@ -825,8 +825,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type) pr->cdev = NULL; } - processors[pr->id] = NULL; - processor_device_array[pr->id] = NULL; + per_cpu(processors, pr->id) = NULL; + per_cpu(processor_device_array, pr->id) = NULL; kfree(pr); return 0; @@ -1074,8 +1074,6 @@ static int __init acpi_processor_init(void) { int result = 0; - - memset(&processors, 0, sizeof(processors)); memset(&errata, 0, sizeof(errata)); #ifdef CONFIG_SMP diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 4976e5d..0fc310e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -401,7 +401,7 @@ static void acpi_processor_idle(void) */ local_irq_disable(); - pr = processors[smp_processor_id()]; + pr = __get_cpu_var(processors); if (!pr) { local_irq_enable(); return; @@ -1431,7 +1431,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); - pr = processors[smp_processor_id()]; + pr = __get_cpu_var(processors); if (unlikely(!pr)) return 0; @@ -1471,7 +1471,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, u32 t1, t2; int sleep_ticks = 0; - pr = processors[smp_processor_id()]; + pr = __get_cpu_var(processors); if (unlikely(!pr)) return 0; @@ -1549,7 +1549,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, u32 t1, t2; int sleep_ticks = 0; - pr = processors[smp_processor_id()]; + pr = __get_cpu_var(processors); if (unlikely(!pr)) return 0; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index d80b2d1..b474996 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -89,7 +89,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, if (event != CPUFREQ_INCOMPATIBLE) goto out; - pr = processors[policy->cpu]; + pr = per_cpu(processors, policy->cpu); if (!pr || !pr->performance) goto out; @@ -572,7 +572,7 @@ int acpi_processor_preregister_performance( /* Call _PSD for all CPUs */ for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr) { /* Look only at processors in ACPI namespace */ continue; @@ -603,7 +603,7 @@ int acpi_processor_preregister_performance( * domain info. */ for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr) continue; @@ -624,7 +624,7 @@ int acpi_processor_preregister_performance( cpus_clear(covered_cpus); for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr) continue; @@ -651,7 +651,7 @@ int acpi_processor_preregister_performance( if (i == j) continue; - match_pr = processors[j]; + match_pr = per_cpu(processors, j); if (!match_pr) continue; @@ -680,7 +680,7 @@ int acpi_processor_preregister_performance( if (i == j) continue; - match_pr = processors[j]; + match_pr = per_cpu(processors, j); if (!match_pr) continue; @@ -697,7 +697,7 @@ int acpi_processor_preregister_performance( err_ret: for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr || !pr->performance) continue; @@ -728,7 +728,7 @@ acpi_processor_register_performance(struct acpi_processor_performance mutex_lock(&performance_mutex); - pr = processors[cpu]; + pr = per_cpu(processors, cpu); if (!pr) { mutex_unlock(&performance_mutex); return -ENODEV; @@ -766,7 +766,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance mutex_lock(&performance_mutex); - pr = processors[cpu]; + pr = per_cpu(processors, cpu); if (!pr) { mutex_unlock(&performance_mutex); return; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index bb06738..8728782 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -71,7 +71,7 @@ static int acpi_processor_update_tsd_coord(void) * coordination between all CPUs. */ for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr) continue; @@ -93,7 +93,7 @@ static int acpi_processor_update_tsd_coord(void) cpus_clear(covered_cpus); for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr) continue; @@ -119,7 +119,7 @@ static int acpi_processor_update_tsd_coord(void) if (i == j) continue; - match_pr = processors[j]; + match_pr = per_cpu(processors, j); if (!match_pr) continue; @@ -152,7 +152,7 @@ static int acpi_processor_update_tsd_coord(void) if (i == j) continue; - match_pr = processors[j]; + match_pr = per_cpu(processors, j); if (!match_pr) continue; @@ -172,7 +172,7 @@ static int acpi_processor_update_tsd_coord(void) err_ret: for_each_possible_cpu(i) { - pr = processors[i]; + pr = per_cpu(processors, i); if (!pr) continue; @@ -214,7 +214,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data) struct acpi_processor_throttling *p_throttling; cpu = p_tstate->cpu; - pr = processors[cpu]; + pr = per_cpu(processors, cpu); if (!pr) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid pr pointer\n")); return 0; @@ -1035,7 +1035,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) * cpus. */ for_each_cpu_mask(i, online_throttling_cpus) { - match_pr = processors[i]; + match_pr = per_cpu(processors, i); /* * If the pointer is invalid, we will report the * error message and continue. diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 06ebb6e..3795590 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -255,7 +255,7 @@ extern void acpi_processor_unregister_performance(struct int acpi_processor_notify_smm(struct module *calling_module); /* for communication between multiple parts of the processor kernel module */ -extern struct acpi_processor *processors[NR_CPUS]; +DECLARE_PER_CPU(struct acpi_processor *, processors); extern struct acpi_processor_errata errata; void arch_acpi_processor_init_pdc(struct acpi_processor *pr); -- cgit v0.10.2 From 20b937343e55c16e37b1a4ad2176760b4a11002c Mon Sep 17 00:00:00 2001 From: Jonathan Woithe Date: Wed, 11 Jun 2008 10:14:56 +0930 Subject: Fujitsu-laptop update Add additional capabilities to the Fujitsu-laptop driver. * Brightness hotkey actions are sent to userspace. This can be disabled using a module parameter if it causes issues with models which handle these keys transparently in the BIOS. * Actions of additional hotkeys found on some Fujitsu models (eg: the suspend key and the dedicated "power on passphrase" keys) are broadcast to userspace. * An alternative brightness control method used by some Fujitsu models (for example, the S6410) is now supported, enabling software brightness controls on models using this method. * DMI-based module aliases are configured for the S6410 and S7020. * The current LCD brightness after booting should now be reflected in the standard backlight interface sysfs file (previously it was always set to 0). The platform brightness sysfs interface has always been fine. Thanks go to Peter Gruber who provided a significant portion of this code and tested various iterations of the patch on his S6410. Signed-off-by: Peter Gruber Signed-off-by: Jonathan Woithe Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/MAINTAINERS b/MAINTAINERS index 2bfde03..ec5c8ee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1792,6 +1792,12 @@ P: David Howells M: dhowells@redhat.com S: Maintained +FUJITSU LAPTOP EXTRAS +P: Jonathan Woithe +M: jwoithe@physics.adelaide.edu.au +L: linux-acpi@vger.kernel.org +S: Maintained + FUSE: FILESYSTEM IN USERSPACE P: Miklos Szeredi M: miklos@szeredi.hu diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 7fce0da..0551d95 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -185,11 +185,22 @@ config FUJITSU_LAPTOP * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks * Possibly other Fujitsu laptop models + * Tested with S6410 and S7020 - It adds support for LCD brightness control. + It adds support for LCD brightness control and some hotkeys. If you have a Fujitsu laptop, say Y or M here. +config FUJITSU_LAPTOP_DEBUG + bool "Verbose debug mode for Fujitsu Laptop Extras" + depends on FUJITSU_LAPTOP + default n + ---help--- + Enables extra debug output from the fujitsu extras driver, at the + expense of a slight increase in driver size. + + If you are not sure, say N here. + config TC1100_WMI tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" depends on X86 && !X86_64 diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c index 6d14e8f..7a1ef6c 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/misc/fujitsu-laptop.c @@ -1,12 +1,14 @@ /*-*-linux-c-*-*/ /* - Copyright (C) 2007 Jonathan Woithe + Copyright (C) 2007,2008 Jonathan Woithe + Copyright (C) 2008 Peter Gruber Based on earlier work: Copyright (C) 2003 Shane Spencer Adrian Yee - Templated from msi-laptop.c which is copyright by its respective authors. + Templated from msi-laptop.c and thinkpad_acpi.c which is copyright + by its respective authors. 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 @@ -39,8 +41,17 @@ * registers itself in the Linux backlight control subsystem and is * available to userspace under /sys/class/backlight/fujitsu-laptop/. * - * This driver has been tested on a Fujitsu Lifebook S7020. It should - * work on most P-series and S-series Lifebooks, but YMMV. + * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are + * also supported by this driver. + * + * This driver has been tested on a Fujitsu Lifebook S6410 and S7020. It + * should work on most P-series and S-series Lifebooks, but YMMV. + * + * The module parameter use_alt_lcd_levels switches between different ACPI + * brightness controls which are used by different Fujitsu laptops. In most + * cases the correct method is automatically detected. "use_alt_lcd_levels=1" + * is applicable for a Fujitsu Lifebook S6410 if autodetection fails. + * */ #include @@ -49,30 +60,105 @@ #include #include #include +#include +#include +#include #include -#define FUJITSU_DRIVER_VERSION "0.3" +#define FUJITSU_DRIVER_VERSION "0.4.2" #define FUJITSU_LCD_N_LEVELS 8 #define ACPI_FUJITSU_CLASS "fujitsu" #define ACPI_FUJITSU_HID "FUJ02B1" -#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI extras driver" +#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver" #define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1" - +#define ACPI_FUJITSU_HOTKEY_HID "FUJ02E3" +#define ACPI_FUJITSU_HOTKEY_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver" +#define ACPI_FUJITSU_HOTKEY_DEVICE_NAME "Fujitsu FUJ02E3" + +#define ACPI_FUJITSU_NOTIFY_CODE1 0x80 + +#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 + +/* Hotkey details */ +#define LOCK_KEY 0x410 /* codes for the keys in the GIRB register */ +#define DISPLAY_KEY 0x411 /* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */ +#define ENERGY_KEY 0x412 /* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */ +#define REST_KEY 0x413 /* KEY_SUSPEND (R key) */ + +#define MAX_HOTKEY_RINGBUFFER_SIZE 100 +#define RINGBUFFERSIZE 40 + +/* Debugging */ +#define FUJLAPTOP_LOG ACPI_FUJITSU_HID ": " +#define FUJLAPTOP_ERR KERN_ERR FUJLAPTOP_LOG +#define FUJLAPTOP_NOTICE KERN_NOTICE FUJLAPTOP_LOG +#define FUJLAPTOP_INFO KERN_INFO FUJLAPTOP_LOG +#define FUJLAPTOP_DEBUG KERN_DEBUG FUJLAPTOP_LOG + +#define FUJLAPTOP_DBG_ALL 0xffff +#define FUJLAPTOP_DBG_ERROR 0x0001 +#define FUJLAPTOP_DBG_WARN 0x0002 +#define FUJLAPTOP_DBG_INFO 0x0004 +#define FUJLAPTOP_DBG_TRACE 0x0008 + +#define dbg_printk(a_dbg_level, format, arg...) \ + do { if (dbg_level & a_dbg_level) \ + printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \ + } while (0) +#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG +#define vdbg_printk(a_dbg_level, format, arg...) \ + dbg_printk(a_dbg_level, format, ## arg) +#else +#define vdbg_printk(a_dbg_level, format, arg...) +#endif + +/* Device controlling the backlight and associated keys */ struct fujitsu_t { acpi_handle acpi_handle; + struct acpi_device *dev; + struct input_dev *input; + char phys[32]; struct backlight_device *bl_device; struct platform_device *pf_device; - unsigned long fuj02b1_state; + unsigned int max_brightness; unsigned int brightness_changed; unsigned int brightness_level; }; static struct fujitsu_t *fujitsu; +static int use_alt_lcd_levels = -1; +static int disable_brightness_keys = -1; +static int disable_brightness_adjust = -1; + +/* Device used to access other hotkeys on the laptop */ +struct fujitsu_hotkey_t { + acpi_handle acpi_handle; + struct acpi_device *dev; + struct input_dev *input; + char phys[32]; + struct platform_device *pf_device; + struct kfifo *fifo; + spinlock_t fifo_lock; + + unsigned int irb; /* info about the pressed buttons */ +}; -/* Hardware access */ +static struct fujitsu_hotkey_t *fujitsu_hotkey; + +static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, + void *data); + +#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG +static u32 dbg_level = 0x03; +#endif + +static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data); + +/* Hardware access for LCD brightness control */ static int set_lcd_level(int level) { @@ -81,7 +167,10 @@ static int set_lcd_level(int level) struct acpi_object_list arg_list = { 1, &arg0 }; acpi_handle handle = NULL; - if (level < 0 || level >= FUJITSU_LCD_N_LEVELS) + vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n", + level); + + if (level < 0 || level >= fujitsu->max_brightness) return -EINVAL; if (!fujitsu) @@ -89,7 +178,38 @@ static int set_lcd_level(int level) status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n")); + vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); + return -ENODEV; + } + + arg0.integer.value = level; + + status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); + if (ACPI_FAILURE(status)) + return -ENODEV; + + return 0; +} + +static int set_lcd_level_alt(int level) +{ + acpi_status status = AE_OK; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list arg_list = { 1, &arg0 }; + acpi_handle handle = NULL; + + vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n", + level); + + if (level < 0 || level >= fujitsu->max_brightness) + return -EINVAL; + + if (!fujitsu) + return -EINVAL; + + status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); + if (ACPI_FAILURE(status)) { + vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); return -ENODEV; } @@ -107,13 +227,52 @@ static int get_lcd_level(void) unsigned long state = 0; acpi_status status = AE_OK; - // Get the Brightness + vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n"); + status = acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); if (status < 0) return status; - fujitsu->fuj02b1_state = state; + fujitsu->brightness_level = state & 0x0fffffff; + + if (state & 0x80000000) + fujitsu->brightness_changed = 1; + else + fujitsu->brightness_changed = 0; + + return fujitsu->brightness_level; +} + +static int get_max_brightness(void) +{ + unsigned long state = 0; + acpi_status status = AE_OK; + + vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n"); + + status = + acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); + if (status < 0) + return status; + + fujitsu->max_brightness = state; + + return fujitsu->max_brightness; +} + +static int get_lcd_level_alt(void) +{ + unsigned long state = 0; + acpi_status status = AE_OK; + + vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n"); + + status = + acpi_evaluate_integer(fujitsu->acpi_handle, "GBLS", NULL, &state); + if (status < 0) + return status; + fujitsu->brightness_level = state & 0x0fffffff; if (state & 0x80000000) @@ -128,12 +287,18 @@ static int get_lcd_level(void) static int bl_get_brightness(struct backlight_device *b) { - return get_lcd_level(); + if (use_alt_lcd_levels) + return get_lcd_level_alt(); + else + return get_lcd_level(); } static int bl_update_status(struct backlight_device *b) { - return set_lcd_level(b->props.brightness); + if (use_alt_lcd_levels) + return set_lcd_level_alt(b->props.brightness); + else + return set_lcd_level(b->props.brightness); } static struct backlight_ops fujitsubl_ops = { @@ -141,7 +306,35 @@ static struct backlight_ops fujitsubl_ops = { .update_status = bl_update_status, }; -/* Platform device */ +/* Platform LCD brightness device */ + +static ssize_t +show_max_brightness(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + int ret; + + ret = get_max_brightness(); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", ret); +} + +static ssize_t +show_brightness_changed(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + int ret; + + ret = fujitsu->brightness_changed; + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", ret); +} static ssize_t show_lcd_level(struct device *dev, struct device_attribute *attr, char *buf) @@ -149,7 +342,10 @@ static ssize_t show_lcd_level(struct device *dev, int ret; - ret = get_lcd_level(); + if (use_alt_lcd_levels) + ret = get_lcd_level_alt(); + else + ret = get_lcd_level(); if (ret < 0) return ret; @@ -164,19 +360,61 @@ static ssize_t store_lcd_level(struct device *dev, int level, ret; if (sscanf(buf, "%i", &level) != 1 - || (level < 0 || level >= FUJITSU_LCD_N_LEVELS)) + || (level < 0 || level >= fujitsu->max_brightness)) return -EINVAL; - ret = set_lcd_level(level); + if (use_alt_lcd_levels) + ret = set_lcd_level_alt(level); + else + ret = set_lcd_level(level); + if (ret < 0) + return ret; + + if (use_alt_lcd_levels) + ret = get_lcd_level_alt(); + else + ret = get_lcd_level(); if (ret < 0) return ret; return count; } +/* Hardware access for hotkey device */ + +static int get_irb(void) +{ + unsigned long state = 0; + acpi_status status = AE_OK; + + vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n"); + + status = + acpi_evaluate_integer(fujitsu_hotkey->acpi_handle, "GIRB", NULL, + &state); + if (status < 0) + return status; + + fujitsu_hotkey->irb = state; + + return fujitsu_hotkey->irb; +} + +static ssize_t +ignore_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + return count; +} + +static DEVICE_ATTR(max_brightness, 0444, show_max_brightness, ignore_store); +static DEVICE_ATTR(brightness_changed, 0444, show_brightness_changed, + ignore_store); static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); static struct attribute *fujitsupf_attributes[] = { + &dev_attr_brightness_changed.attr, + &dev_attr_max_brightness.attr, &dev_attr_lcd_level.attr, NULL }; @@ -192,14 +430,52 @@ static struct platform_driver fujitsupf_driver = { } }; -/* ACPI device */ +static int dmi_check_cb_s6410(const struct dmi_system_id *id) +{ + acpi_handle handle; + int have_blnf; + printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n", + id->ident); + have_blnf = ACPI_SUCCESS + (acpi_get_handle(NULL, "\\_SB.PCI0.GFX0.LCD.BLNF", &handle)); + if (use_alt_lcd_levels == -1) { + vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detecting usealt\n"); + use_alt_lcd_levels = 1; + } + if (disable_brightness_keys == -1) { + vdbg_printk(FUJLAPTOP_DBG_TRACE, + "auto-detecting disable_keys\n"); + disable_brightness_keys = have_blnf ? 1 : 0; + } + if (disable_brightness_adjust == -1) { + vdbg_printk(FUJLAPTOP_DBG_TRACE, + "auto-detecting disable_adjust\n"); + disable_brightness_adjust = have_blnf ? 0 : 1; + } + return 0; +} + +static struct dmi_system_id __initdata fujitsu_dmi_table[] = { + { + .ident = "Fujitsu Siemens", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"), + }, + .callback = dmi_check_cb_s6410}, + {} +}; + +/* ACPI device for LCD brightness control */ static int acpi_fujitsu_add(struct acpi_device *device) { + acpi_status status; + acpi_handle handle; int result = 0; int state = 0; - - ACPI_FUNCTION_TRACE("acpi_fujitsu_add"); + struct input_dev *input; + int error; if (!device) return -EINVAL; @@ -209,10 +485,42 @@ static int acpi_fujitsu_add(struct acpi_device *device) sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); acpi_driver_data(device) = fujitsu; + status = acpi_install_notify_handler(device->handle, + ACPI_DEVICE_NOTIFY, + acpi_fujitsu_notify, fujitsu); + + if (ACPI_FAILURE(status)) { + printk(KERN_ERR "Error installing notify handler\n"); + error = -ENODEV; + goto err_stop; + } + + fujitsu->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; + goto err_uninstall_notify; + } + + snprintf(fujitsu->phys, sizeof(fujitsu->phys), + "%s/video/input0", acpi_device_hid(device)); + + input->name = acpi_device_name(device); + input->phys = fujitsu->phys; + input->id.bustype = BUS_HOST; + input->id.product = 0x06; + input->dev.parent = &device->dev; + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_BRIGHTNESSUP, input->keybit); + set_bit(KEY_BRIGHTNESSDOWN, input->keybit); + set_bit(KEY_UNKNOWN, input->keybit); + + error = input_register_device(input); + if (error) + goto err_free_input_dev; + result = acpi_bus_get_power(fujitsu->acpi_handle, &state); if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading power state\n")); + printk(KERN_ERR "Error reading power state\n"); goto end; } @@ -220,22 +528,373 @@ static int acpi_fujitsu_add(struct acpi_device *device) acpi_device_name(device), acpi_device_bid(device), !device->power.state ? "on" : "off"); - end: + fujitsu->dev = device; + + if (ACPI_SUCCESS + (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) { + vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); + if (ACPI_FAILURE + (acpi_evaluate_object + (device->handle, METHOD_NAME__INI, NULL, NULL))) + printk(KERN_ERR "_INI Method failed\n"); + } + + /* do config (detect defaults) */ + dmi_check_system(fujitsu_dmi_table); + use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; + disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0; + disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; + vdbg_printk(FUJLAPTOP_DBG_INFO, + "config: [alt interface: %d], [key disable: %d], [adjust disable: %d]\n", + use_alt_lcd_levels, disable_brightness_keys, + disable_brightness_adjust); + + if (get_max_brightness() <= 0) + fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS; + if (use_alt_lcd_levels) + get_lcd_level_alt(); + else + get_lcd_level(); + + return result; + +end: +err_free_input_dev: + input_free_device(input); +err_uninstall_notify: + acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, + acpi_fujitsu_notify); +err_stop: return result; } static int acpi_fujitsu_remove(struct acpi_device *device, int type) { - ACPI_FUNCTION_TRACE("acpi_fujitsu_remove"); + acpi_status status; + struct fujitsu_t *fujitsu = NULL; if (!device || !acpi_driver_data(device)) return -EINVAL; + + fujitsu = acpi_driver_data(device); + + status = acpi_remove_notify_handler(fujitsu->acpi_handle, + ACPI_DEVICE_NOTIFY, + acpi_fujitsu_notify); + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + fujitsu->acpi_handle = NULL; return 0; } +/* Brightness notify */ + +static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) +{ + struct input_dev *input; + int keycode; + int oldb, newb; + + input = fujitsu->input; + + switch (event) { + case ACPI_FUJITSU_NOTIFY_CODE1: + keycode = 0; + oldb = fujitsu->brightness_level; + get_lcd_level(); /* the alt version always yields changed */ + newb = fujitsu->brightness_level; + + vdbg_printk(FUJLAPTOP_DBG_TRACE, + "brightness button event [%i -> %i (%i)]\n", + oldb, newb, fujitsu->brightness_changed); + + if (oldb == newb && fujitsu->brightness_changed) { + keycode = 0; + if (disable_brightness_keys != 1) { + if (oldb == 0) { + acpi_bus_generate_proc_event(fujitsu-> + dev, + ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, + 0); + keycode = KEY_BRIGHTNESSDOWN; + } else if (oldb == + (fujitsu->max_brightness) - 1) { + acpi_bus_generate_proc_event(fujitsu-> + dev, + ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, + 0); + keycode = KEY_BRIGHTNESSUP; + } + } + } else if (oldb < newb) { + if (disable_brightness_adjust != 1) { + if (use_alt_lcd_levels) + set_lcd_level_alt(newb); + else + set_lcd_level(newb); + } + if (disable_brightness_keys != 1) { + acpi_bus_generate_proc_event(fujitsu->dev, + ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, + 0); + keycode = KEY_BRIGHTNESSUP; + } + } else if (oldb > newb) { + if (disable_brightness_adjust != 1) { + if (use_alt_lcd_levels) + set_lcd_level_alt(newb); + else + set_lcd_level(newb); + } + if (disable_brightness_keys != 1) { + acpi_bus_generate_proc_event(fujitsu->dev, + ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, + 0); + keycode = KEY_BRIGHTNESSDOWN; + } + } else { + keycode = KEY_UNKNOWN; + } + break; + default: + keycode = KEY_UNKNOWN; + vdbg_printk(FUJLAPTOP_DBG_WARN, + "unsupported event [0x%x]\n", event); + break; + } + + if (keycode != 0) { + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + } + + return; +} + +/* ACPI device for hotkey handling */ + +static int acpi_fujitsu_hotkey_add(struct acpi_device *device) +{ + acpi_status status; + acpi_handle handle; + int result = 0; + int state = 0; + struct input_dev *input; + int error; + int i; + + if (!device) + return -EINVAL; + + fujitsu_hotkey->acpi_handle = device->handle; + sprintf(acpi_device_name(device), "%s", + ACPI_FUJITSU_HOTKEY_DEVICE_NAME); + sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); + acpi_driver_data(device) = fujitsu_hotkey; + + status = acpi_install_notify_handler(device->handle, + ACPI_DEVICE_NOTIFY, + acpi_fujitsu_hotkey_notify, + fujitsu_hotkey); + + if (ACPI_FAILURE(status)) { + printk(KERN_ERR "Error installing notify handler\n"); + error = -ENODEV; + goto err_stop; + } + + /* kfifo */ + spin_lock_init(&fujitsu_hotkey->fifo_lock); + fujitsu_hotkey->fifo = + kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL, + &fujitsu_hotkey->fifo_lock); + if (IS_ERR(fujitsu_hotkey->fifo)) { + printk(KERN_ERR "kfifo_alloc failed\n"); + error = PTR_ERR(fujitsu_hotkey->fifo); + goto err_stop; + } + + fujitsu_hotkey->input = input = input_allocate_device(); + if (!input) { + error = -ENOMEM; + goto err_uninstall_notify; + } + + snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys), + "%s/video/input0", acpi_device_hid(device)); + + input->name = acpi_device_name(device); + input->phys = fujitsu_hotkey->phys; + input->id.bustype = BUS_HOST; + input->id.product = 0x06; + input->dev.parent = &device->dev; + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_SCREENLOCK, input->keybit); + set_bit(KEY_MEDIA, input->keybit); + set_bit(KEY_EMAIL, input->keybit); + set_bit(KEY_SUSPEND, input->keybit); + set_bit(KEY_UNKNOWN, input->keybit); + + error = input_register_device(input); + if (error) + goto err_free_input_dev; + + result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); + if (result) { + printk(KERN_ERR "Error reading power state\n"); + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (%s)\n", + acpi_device_name(device), acpi_device_bid(device), + !device->power.state ? "on" : "off"); + + fujitsu_hotkey->dev = device; + + if (ACPI_SUCCESS + (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) { + vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); + if (ACPI_FAILURE + (acpi_evaluate_object + (device->handle, METHOD_NAME__INI, NULL, NULL))) + printk(KERN_ERR "_INI Method failed\n"); + } + + i = 0; /* Discard hotkey ringbuffer */ + while (get_irb() != 0 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) ; + vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); + + return result; + +end: +err_free_input_dev: + input_free_device(input); +err_uninstall_notify: + acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, + acpi_fujitsu_hotkey_notify); + kfifo_free(fujitsu_hotkey->fifo); +err_stop: + + return result; +} + +static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) +{ + acpi_status status; + struct fujitsu_hotkey_t *fujitsu_hotkey = NULL; + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + + fujitsu_hotkey = acpi_driver_data(device); + + status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle, + ACPI_DEVICE_NOTIFY, + acpi_fujitsu_hotkey_notify); + + fujitsu_hotkey->acpi_handle = NULL; + + kfifo_free(fujitsu_hotkey->fifo); + + return 0; +} + +static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, + void *data) +{ + struct input_dev *input; + int keycode, keycode_r; + unsigned int irb = 1; + int i, status; + + input = fujitsu_hotkey->input; + + vdbg_printk(FUJLAPTOP_DBG_TRACE, "Hotkey event\n"); + + switch (event) { + case ACPI_FUJITSU_NOTIFY_CODE1: + i = 0; + while ((irb = get_irb()) != 0 + && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) { + vdbg_printk(FUJLAPTOP_DBG_TRACE, "GIRB result [%x]\n", + irb); + + switch (irb & 0x4ff) { + case LOCK_KEY: + keycode = KEY_SCREENLOCK; + break; + case DISPLAY_KEY: + keycode = KEY_MEDIA; + break; + case ENERGY_KEY: + keycode = KEY_EMAIL; + break; + case REST_KEY: + keycode = KEY_SUSPEND; + break; + case 0: + keycode = 0; + break; + default: + vdbg_printk(FUJLAPTOP_DBG_WARN, + "Unknown GIRB result [%x]\n", irb); + keycode = -1; + break; + } + if (keycode > 0) { + vdbg_printk(FUJLAPTOP_DBG_TRACE, + "Push keycode into ringbuffer [%d]\n", + keycode); + status = kfifo_put(fujitsu_hotkey->fifo, + (unsigned char *)&keycode, + sizeof(keycode)); + if (status != sizeof(keycode)) { + vdbg_printk(FUJLAPTOP_DBG_WARN, + "Could not push keycode [0x%x]\n", + keycode); + } else { + input_report_key(input, keycode, 1); + input_sync(input); + } + } else if (keycode == 0) { + while ((status = + kfifo_get + (fujitsu_hotkey->fifo, (unsigned char *) + &keycode_r, + sizeof + (keycode_r))) == sizeof(keycode_r)) { + input_report_key(input, keycode_r, 0); + input_sync(input); + vdbg_printk(FUJLAPTOP_DBG_TRACE, + "Pop keycode from ringbuffer [%d]\n", + keycode_r); + } + } + } + + break; + default: + keycode = KEY_UNKNOWN; + vdbg_printk(FUJLAPTOP_DBG_WARN, + "Unsupported event [0x%x]\n", event); + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + break; + } + + return; +} + +/* Initialization */ + static const struct acpi_device_id fujitsu_device_ids[] = { {ACPI_FUJITSU_HID, 0}, {"", 0}, @@ -251,11 +910,24 @@ static struct acpi_driver acpi_fujitsu_driver = { }, }; -/* Initialization */ +static const struct acpi_device_id fujitsu_hotkey_device_ids[] = { + {ACPI_FUJITSU_HOTKEY_HID, 0}, + {"", 0}, +}; + +static struct acpi_driver acpi_fujitsu_hotkey_driver = { + .name = ACPI_FUJITSU_HOTKEY_DRIVER_NAME, + .class = ACPI_FUJITSU_CLASS, + .ids = fujitsu_hotkey_device_ids, + .ops = { + .add = acpi_fujitsu_hotkey_add, + .remove = acpi_fujitsu_hotkey_remove, + }, +}; static int __init fujitsu_init(void) { - int ret, result; + int ret, result, max_brightness; if (acpi_disabled) return -ENODEV; @@ -271,19 +943,6 @@ static int __init fujitsu_init(void) goto fail_acpi; } - /* Register backlight stuff */ - - fujitsu->bl_device = - backlight_device_register("fujitsu-laptop", NULL, NULL, - &fujitsubl_ops); - if (IS_ERR(fujitsu->bl_device)) - return PTR_ERR(fujitsu->bl_device); - - fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1; - ret = platform_driver_register(&fujitsupf_driver); - if (ret) - goto fail_backlight; - /* Register platform stuff */ fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1); @@ -302,28 +961,68 @@ static int __init fujitsu_init(void) if (ret) goto fail_platform_device2; + /* Register backlight stuff */ + + fujitsu->bl_device = + backlight_device_register("fujitsu-laptop", NULL, NULL, + &fujitsubl_ops); + if (IS_ERR(fujitsu->bl_device)) + return PTR_ERR(fujitsu->bl_device); + + max_brightness = fujitsu->max_brightness; + + fujitsu->bl_device->props.max_brightness = max_brightness - 1; + fujitsu->bl_device->props.brightness = fujitsu->brightness_level; + + ret = platform_driver_register(&fujitsupf_driver); + if (ret) + goto fail_backlight; + + /* Register hotkey driver */ + + fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL); + if (!fujitsu_hotkey) { + ret = -ENOMEM; + goto fail_hotkey; + } + memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t)); + + result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver); + if (result < 0) { + ret = -ENODEV; + goto fail_hotkey1; + } + printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION " successfully loaded.\n"); return 0; - fail_platform_device2: +fail_hotkey1: - platform_device_del(fujitsu->pf_device); - - fail_platform_device1: - - platform_device_put(fujitsu->pf_device); + kfree(fujitsu_hotkey); - fail_platform_driver: +fail_hotkey: platform_driver_unregister(&fujitsupf_driver); - fail_backlight: +fail_backlight: backlight_device_unregister(fujitsu->bl_device); - fail_acpi: +fail_platform_device2: + + platform_device_del(fujitsu->pf_device); + +fail_platform_device1: + + platform_device_put(fujitsu->pf_device); + +fail_platform_driver: + + acpi_bus_unregister_driver(&acpi_fujitsu_driver); + +fail_acpi: kfree(fujitsu); @@ -342,19 +1041,43 @@ static void __exit fujitsu_cleanup(void) kfree(fujitsu); + acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); + + kfree(fujitsu_hotkey); + printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); } module_init(fujitsu_init); module_exit(fujitsu_cleanup); -MODULE_AUTHOR("Jonathan Woithe"); +module_param(use_alt_lcd_levels, uint, 0644); +MODULE_PARM_DESC(use_alt_lcd_levels, + "Use alternative interface for lcd_levels (needed for Lifebook s6410)."); +module_param(disable_brightness_keys, uint, 0644); +MODULE_PARM_DESC(disable_brightness_keys, + "Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device)."); +module_param(disable_brightness_adjust, uint, 0644); +MODULE_PARM_DESC(disable_brightness_adjust, "Disable brightness adjustment ."); +#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG +module_param_named(debug, dbg_level, uint, 0644); +MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); +#endif + +MODULE_AUTHOR("Jonathan Woithe, Peter Gruber"); MODULE_DESCRIPTION("Fujitsu laptop extras support"); MODULE_VERSION(FUJITSU_DRIVER_VERSION); MODULE_LICENSE("GPL"); +MODULE_ALIAS + ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"); +MODULE_ALIAS + ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"); + static struct pnp_device_id pnp_ids[] = { { .id = "FUJ02bf" }, + { .id = "FUJ02B1" }, + { .id = "FUJ02E3" }, { .id = "" } }; MODULE_DEVICE_TABLE(pnp, pnp_ids); -- cgit v0.10.2 From 74523c901342a773ddd9f14c14539ec3d4197ecf Mon Sep 17 00:00:00 2001 From: Alok N Kataria Date: Fri, 13 Jun 2008 12:54:24 -0400 Subject: ACPI: fix checkpatch.pl complaints in scan.c http://bugzilla.kernel.org/show_bug.cgi?id=9772 Signed-off-by: Alok N Kataria Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 9a84ed2..5b049cd 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include #include /* for acpi_ex_eisa_id_to_string() */ @@ -154,6 +155,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, acpi_status status; acpi_object_type type = 0; struct acpi_device *acpi_device = to_acpi_device(d); + struct task_struct *task; if ((!count) || (buf[0] != '1')) { return -EINVAL; @@ -171,9 +173,11 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, } /* remove the device in another thread to fix the deadlock issue */ - ret = kernel_thread(acpi_bus_hot_remove_device, - acpi_device->handle, SIGCHLD); - err: + task = kthread_run(acpi_bus_hot_remove_device, + acpi_device->handle, "acpi_hot_remove_device"); + if (IS_ERR(task)) + ret = PTR_ERR(task); +err: return ret; } -- cgit v0.10.2 From 6594d87ebd8371f4b67f7ab4b68f172b139b78d6 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Sat, 14 Jun 2008 00:52:06 -0400 Subject: ACPI: fix acpi fan state set error Under /proc/acpi, there is a fan control interface, a user can set 0 or 3 to /proc/acpi/fan/*/state, 0 denotes D0 state, 3 denotes D3 state, but in current implementation, a user can set a fan to D1 state by any char excluding '1', '2' and '3'. For example: [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: off [root@localhost acpi]# echo "" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: on [root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: off [root@localhost acpi]# echo "xxxxx" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: on Obviously, such inputs as "" and "xxxxx" are invalid for fan state. This patch fixes this issue, it strictly limits fan state only to accept 0, 1, 2 and 3, any other inputs are invalid. Before applying this patch, the test result is: [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: off [root@localhost acpi]# echo "" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: on [root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: off [root@localhost acpi]# echo "xxxxx" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: on [root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: off [root@localhost acpi]# echo "3x" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: off [root@localhost acpi]# echo "-1x" > /proc/acpi/fan/C31B/state [root@localhost acpi]# cat /proc/acpi/fan/C31B/state status: on [root@localhost acpi]# After applying this patch, the test result is: [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: off [root@localhost ~]# echo "" > /proc/acpi/fan/C31B/state -bash: echo: write error: Invalid argument [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: off [root@localhost ~]# echo "3" > /proc/acpi/fan/C31B/state [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: off [root@localhost ~]# echo "xxxxx" > /proc/acpi/fan/C31B/state -bash: echo: write error: Invalid argument [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: off [root@localhost ~]# echo "-1x" > /proc/acpi/fan/C31B/state -bash: echo: write error: Invalid argument [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: off [root@localhost ~]# echo "0" > //proc/acpi/fan/C31B/state [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: on [root@localhost ~]# echo "4" > //proc/acpi/fan/C31B/state -bash: echo: write error: Invalid argument [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: on [root@localhost ~]# echo "3" > //proc/acpi/fan/C31B/state [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: off [root@localhost ~]# echo "0" > //proc/acpi/fan/C31B/state [root@localhost ~]# cat /proc/acpi/fan/C31B/state status: on [root@localhost ~]# echo "3x" > //proc/acpi/fan/C31B/state -bash: echo: write error: Invalid argument [root@localhost ~]# Signed-off-by: Yi Yang Signed-off-by: Andi Kleen Acked-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 6cf10cb..55c17af 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -148,7 +148,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, int result = 0; struct seq_file *m = file->private_data; struct acpi_device *device = m->private; - char state_string[12] = { '\0' }; + char state_string[3] = { '\0' }; if (count > sizeof(state_string) - 1) return -EINVAL; @@ -157,6 +157,12 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, return -EFAULT; state_string[count] = '\0'; + if ((state_string[0] < '0') || (state_string[0] > '3')) + return -EINVAL; + if (state_string[1] == '\n') + state_string[1] = '\0'; + if (state_string[1] != '\0') + return -EINVAL; result = acpi_bus_set_power(device->handle, simple_strtoul(state_string, NULL, 0)); -- cgit v0.10.2 From 3d532d5e3882c1387a2722df2a368c4a9224b12f Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Sat, 14 Jun 2008 00:54:37 -0400 Subject: ACPI: fix processor throttling set error http://bugzilla.kernel.org/show_bug.cgi?id=9704 When echo some invalid values to /proc/acpi/processor/*/throttling, there isn't any error info returned, on the contray, it sets throttling value to some T* successfully, obviously, this is incorrect, a correct way should be to let it fail and return error info. This patch fixed the aforementioned issue, it also enables /proc/acpi/processor/*/throttling to accept such values as 't0' and 'T0', it also strictly limits /proc/acpi/processor/*/throttling only to accept "*", "t*" and "T*", "*" is the throttling state value the processor can support, current, it is 0 - 7. Before applying this patch, the test result is below: [root@localhost acpi]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T1 state available: T0 to T7 states: T0: 100% *T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost acpi]# echo "1xxxxxx" > /proc/acpi/processor/CPU0/throttling [root@localhost acpi]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T1 state available: T0 to T7 states: T0: 100% *T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost acpi]# echo "0" > /proc/acpi/processor/CPU0/throttling [root@localhost acpi]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost acpi]# cd / [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "T0" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "T7" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "T100" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "xxx" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "2xxxx" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T2 state available: T0 to T7 states: T0: 100% T1: 87% *T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost /]# echo "7777" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost /]# echo "7xxx" > /proc/acpi/processor/CPU0/throttling [root@localhost /]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T7 state available: T0 to T7 states: T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% *T7: 12% [root@localhost /]# After applying this patch, the test result is below: [root@localhost linux-2.6.24-rc6]# echo > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "0" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo "t0" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo "T0" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T0 state available: T0 to T7 states: *T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% T7: 12% [root@localhost linux-2.6.24-rc6]# echo "T7" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T7 state available: T0 to T7 states: T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% *T7: 12% [root@localhost linux-2.6.24-rc6]# echo "T8" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# vi drivers/acpi/processor_throttling.c [root@localhost linux-2.6.24-rc6]# echo "T8" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "t7" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo "t70" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "70" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "7000" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "70" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo "xxx" > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo -n > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo -n "" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo $? 0 [root@localhost linux-2.6.24-rc6]# echo -n "" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T7 state available: T0 to T7 states: T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% *T7: 12% [root@localhost linux-2.6.24-rc6]# echo -n "" > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling state count: 8 active state: T7 state available: T0 to T7 states: T0: 100% T1: 87% T2: 75% T3: 62% T4: 50% T5: 37% T6: 25% *T7: 12% [root@localhost linux-2.6.24-rc6]# echo t0 > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo T0 > /proc/acpi/processor/CPU0/throttling [root@localhost linux-2.6.24-rc6]# echo Tt0 > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# echo T > /proc/acpi/processor/CPU0/throttling -bash: echo: write error: Invalid argument [root@localhost linux-2.6.24-rc6]# Signed-off-by: Yi Yang Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 8728782..53345db 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -1232,7 +1232,10 @@ static ssize_t acpi_processor_write_throttling(struct file *file, int result = 0; struct seq_file *m = file->private_data; struct acpi_processor *pr = m->private; - char state_string[12] = { '\0' }; + char state_string[5] = ""; + char *charp = NULL; + size_t state_val = 0; + char tmpbuf[5] = ""; if (!pr || (count > sizeof(state_string) - 1)) return -EINVAL; @@ -1241,10 +1244,23 @@ static ssize_t acpi_processor_write_throttling(struct file *file, return -EFAULT; state_string[count] = '\0'; + if ((count > 0) && (state_string[count-1] == '\n')) + state_string[count-1] = '\0'; - result = acpi_processor_set_throttling(pr, - simple_strtoul(state_string, - NULL, 0)); + charp = state_string; + if ((state_string[0] == 't') || (state_string[0] == 'T')) + charp++; + + state_val = simple_strtoul(charp, NULL, 0); + if (state_val >= pr->throttling.state_count) + return -EINVAL; + + snprintf(tmpbuf, 5, "%d", state_val); + + if (strcmp(tmpbuf, charp) != 0) + return -EINVAL; + + result = acpi_processor_set_throttling(pr, state_val); if (result) return result; -- cgit v0.10.2 From 12b2b34e240a24bdbb2fdacf26a54b24ebf1ed81 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Jun 2008 09:43:41 -0700 Subject: acpi: fix printk format warning Fix printk format warning: linux-next-20080617/drivers/acpi/processor_throttling.c:1258: warning: format '%d' expects type 'int', but argument 4 has type 'size_t' Signed-off-by: Randy Dunlap Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 53345db..0622ace 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -1255,7 +1255,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file, if (state_val >= pr->throttling.state_count) return -EINVAL; - snprintf(tmpbuf, 5, "%d", state_val); + snprintf(tmpbuf, 5, "%zu", state_val); if (strcmp(tmpbuf, charp) != 0) return -EINVAL; -- cgit v0.10.2 From 87dc5e3218ba3d7a9293f9113f58455747a233ac Mon Sep 17 00:00:00 2001 From: Cezary Jackiewicz Date: Thu, 12 Jun 2008 22:08:59 +0200 Subject: compal-laptop: remove unnecessary lcd_level attribute Signed-off-by: Cezary Jackiewicz Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c index 0c1f587..344b790 100644 --- a/drivers/misc/compal-laptop.c +++ b/drivers/misc/compal-laptop.c @@ -28,9 +28,6 @@ * * This driver exports a few files in /sys/devices/platform/compal-laptop/: * - * lcd_level - Screen brightness: contains a single integer in the - * range 0..7. (rw) - * * wlan - wlan subsystem state: contains 0 or 1 (rw) * * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw) @@ -44,7 +41,7 @@ * This driver might work on other laptops produced by Compal. If you * want to try it you can pass force=1 as argument to the module which * will force it to load even when the DMI data doesn't identify the - * laptop as IFL90. + * laptop as FL9x. */ #include @@ -56,7 +53,7 @@ #include #include -#define COMPAL_DRIVER_VERSION "0.2.5" +#define COMPAL_DRIVER_VERSION "0.2.6" #define COMPAL_LCD_LEVEL_MAX 8 @@ -209,34 +206,6 @@ static ssize_t show_bluetooth(struct device *dev, return sprintf(buf, "%i\n", enabled); } -static ssize_t show_lcd_level(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret; - - ret = get_lcd_level(); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", ret); -} - -static ssize_t store_lcd_level(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int level, ret; - - if (sscanf(buf, "%i", &level) != 1 || - (level < 0 || level >= COMPAL_LCD_LEVEL_MAX)) - return -EINVAL; - - ret = set_lcd_level(level); - if (ret < 0) - return ret; - - return count; -} - static ssize_t store_wlan_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -267,13 +236,11 @@ static ssize_t store_bluetooth_state(struct device *dev, return count; } -static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state); static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state); static DEVICE_ATTR(raw, 0444, show_raw, NULL); static struct attribute *compal_attributes[] = { - &dev_attr_lcd_level.attr, &dev_attr_bluetooth.attr, &dev_attr_wlan.attr, &dev_attr_raw.attr, -- cgit v0.10.2 From e38e8a0743b0e996a8a3fbea8908fe75a84f02c7 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 13 Jun 2008 08:28:55 +0800 Subject: Make GPE disable more robust Implemented another change for the GPE disable. We now perform a read-change-write of the enable register instead of simply writing out the cached enable mask. This will prevent inadvertent enabling of GPEs if a rogue GPE is received during initialization (before GPE handlers are installed.) http://bugzilla.kernel.org/show_bug.cgi?id=6217 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index 5354be4..e0339d4 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -256,7 +256,7 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(status); } - /* Mark wake-disabled or HW disable, or both */ + /* Clear the appropriate enabled flags for this GPE */ switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { case ACPI_GPE_TYPE_WAKE: @@ -273,13 +273,23 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) /* Disable the requested runtime GPE */ ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); - - /* fallthrough */ + break; default: - acpi_hw_write_gpe_enable_reg(gpe_event_info); + break; } + /* + * Even if we don't know the GPE type, make sure that we always + * disable it. low_disable_gpe will just clear the enable bit for this + * GPE and write it. It will not write out the current GPE enable mask, + * since this may inadvertently enable GPEs too early, if a rogue GPE has + * come in during ACPICA initialization - possibly as a result of AML or + * other code that has enabled the GPE. + */ + status = acpi_hw_low_disable_gpe(gpe_event_info); + return_ACPI_STATUS(status); + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index 14bc4f4..58347d6 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -55,6 +55,54 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /****************************************************************************** * + * FUNCTION: acpi_hw_low_disable_gpe + * + * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled + * + * RETURN: Status + * + * DESCRIPTION: Disable a single GPE in the enable register. + * + ******************************************************************************/ + +acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + struct acpi_gpe_register_info *gpe_register_info; + acpi_status status; + u32 enable_mask; + + /* Get the info block for the entire GPE register */ + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return (AE_NOT_EXIST); + } + + /* Get current value of the enable register that contains this GPE */ + + status = acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH, &enable_mask, + &gpe_register_info->enable_address); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Clear just the bit that corresponds to this GPE */ + + ACPI_CLEAR_BIT(enable_mask, + ((u32) 1 << + (gpe_event_info->gpe_number - + gpe_register_info->base_gpe_number))); + + /* Write the updated enable mask */ + + status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, enable_mask, + &gpe_register_info->enable_address); + + return (status); +} + +/****************************************************************************** + * * FUNCTION: acpi_hw_write_gpe_enable_reg * * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled @@ -68,7 +116,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ******************************************************************************/ acpi_status -acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) +acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) { struct acpi_gpe_register_info *gpe_register_info; acpi_status status; diff --git a/include/acpi/achware.h b/include/acpi/achware.h index d4fb9bb..45e9859 100644 --- a/include/acpi/achware.h +++ b/include/acpi/achware.h @@ -87,6 +87,8 @@ acpi_status acpi_hw_clear_acpi_status(void); /* * hwgpe - GPE support */ +acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); + acpi_status acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); -- cgit v0.10.2 From 47c00d2bc2ef2cf8a608688144fe2093a2aa9507 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 20 Jun 2008 13:56:56 +0200 Subject: ACPICA: fix mutex names in debug code. Reorder the mutex names to match the preceding #defines Signed-off-by: Vegard Nossum Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index c5cdc32..62d7468 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -98,8 +98,8 @@ union acpi_parse_object; static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { "ACPI_MTX_Interpreter", - "ACPI_MTX_Tables", "ACPI_MTX_Namespace", + "ACPI_MTX_Tables", "ACPI_MTX_Events", "ACPI_MTX_Caches", "ACPI_MTX_Memory", -- cgit v0.10.2 From 141094612d2606395a7b9e8658d10ef5c487cf97 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 25 Jun 2008 19:25:47 +0300 Subject: eeepc-laptop: static make the needlessly global cm_{g,s}etv[] static. Signed-off-by: Adrian Bunk Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c index 6d72760..9e8d79e 100644 --- a/drivers/misc/eeepc-laptop.c +++ b/drivers/misc/eeepc-laptop.c @@ -87,7 +87,7 @@ enum { CM_ASL_LID }; -const char *cm_getv[] = { +static const char *cm_getv[] = { "WLDG", NULL, NULL, NULL, "CAMG", NULL, NULL, NULL, NULL, "PBLG", NULL, NULL, @@ -96,7 +96,7 @@ const char *cm_getv[] = { "CRDG", "LIDG" }; -const char *cm_setv[] = { +static const char *cm_setv[] = { "WLDS", NULL, NULL, NULL, "CAMS", NULL, NULL, NULL, "SDSP", "PBLS", "HDPS", NULL, -- cgit v0.10.2 From a0bbaf83311cd995136c9047f174d79c1075ee2d Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:08 +0100 Subject: acer-wmi: Remove LED colour comment from documentation This should have been removed when the colour was removed from the LED device name. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt index 79b7dbd..69b5dd4 100644 --- a/Documentation/laptops/acer-wmi.txt +++ b/Documentation/laptops/acer-wmi.txt @@ -174,8 +174,6 @@ The LED is exposed through the LED subsystem, and can be found in: The mail LED is autodetected, so if you don't have one, the LED device won't be registered. -If you have a mail LED that is not green, please report this to me. - Backlight ********* -- cgit v0.10.2 From 9991d9f2bc75dc8735932240b67432d4073b8f60 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:22 +0100 Subject: acer-wmi: Blacklist backlight on Acer Aspire 1520 & 1360 series A newer BIOS for these laptops adds ACPI-WMI support to them. However, it does not add support for the backlight via the EC, and we have no way to detect this on older machines, so blacklist it from them. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index dd13a37..b82ff25 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -174,7 +174,7 @@ static struct wmi_interface *interface; struct quirk_entry { u8 wireless; u8 mailled; - u8 brightness; + s8 brightness; u8 bluetooth; }; @@ -198,6 +198,10 @@ static int dmi_matched(const struct dmi_system_id *dmi) static struct quirk_entry quirk_unknown = { }; +static struct quirk_entry quirk_acer_aspire_1520 = { + .brightness = -1, +}; + static struct quirk_entry quirk_acer_travelmate_2490 = { .mailled = 1, }; @@ -210,6 +214,24 @@ static struct quirk_entry quirk_medion_md_98300 = { static struct dmi_system_id acer_quirks[] = { { .callback = dmi_matched, + .ident = "Acer Aspire 1360", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), + }, + .driver_data = &quirk_acer_aspire_1520, + }, + { + .callback = dmi_matched, + .ident = "Acer Aspire 1520", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"), + }, + .driver_data = &quirk_acer_aspire_1520, + }, + { + .callback = dmi_matched, .ident = "Acer Aspire 3100", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -552,7 +574,8 @@ static acpi_status AMW0_set_capabilities(void) * appear to use the same EC register for brightness, even if they * differ for wireless, etc */ - interface->capability |= ACER_CAP_BRIGHTNESS; + if (quirks->brightness >= 0) + interface->capability |= ACER_CAP_BRIGHTNESS; return AE_OK; } @@ -1059,6 +1082,8 @@ static int __init acer_wmi_init(void) printk(ACER_INFO "Acer Laptop ACPI-WMI Extras version %s\n", ACER_WMI_VERSION); + find_quirks(); + /* * Detect which ACPI-WMI interface we're using. */ @@ -1092,8 +1117,6 @@ static int __init acer_wmi_init(void) if (wmi_has_guid(AMW0_GUID1)) AMW0_find_mailled(); - find_quirks(); - if (!interface) { printk(ACER_ERR "No or unsupported WMI interface, unable to " "load\n"); -- cgit v0.10.2 From f2b585b4a31731b17b9769eae523986fa7fddcde Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:27 +0100 Subject: acer-wmi: Respect framebuffer blanking in backlight If the framebuffer has requested blanking, turn the backlight down. Also offer the user the option to do this. Reported-by: Michal Pecio Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index b82ff25..e35825f 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -830,7 +831,15 @@ static int read_brightness(struct backlight_device *bd) static int update_bl_status(struct backlight_device *bd) { - set_u32(bd->props.brightness, ACER_CAP_BRIGHTNESS); + int intensity = bd->props.brightness; + + if (bd->props.power != FB_BLANK_UNBLANK) + intensity = 0; + if (bd->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + + set_u32(intensity, ACER_CAP_BRIGHTNESS); + return 0; } @@ -852,8 +861,9 @@ static int __devinit acer_backlight_init(struct device *dev) acer_backlight_device = bd; + bd->props.power = FB_BLANK_UNBLANK; + bd->props.brightness = max_brightness; bd->props.max_brightness = max_brightness; - bd->props.brightness = read_brightness(NULL); backlight_update_status(bd); return 0; } -- cgit v0.10.2 From 6f061ab5e55d7fe6ce0c36e8954f56f0d95348fb Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:38 +0100 Subject: acer-wmi: Add EC quirk for Fujitsu Siemens Amilo Li 1718 This laptop needs a different EC quirk from the standard Acer one to read the wireless status. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index e35825f..5b7c5fc 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -212,6 +212,10 @@ static struct quirk_entry quirk_medion_md_98300 = { .wireless = 1, }; +static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { + .wireless = 2, +}; + static struct dmi_system_id acer_quirks[] = { { .callback = dmi_matched, @@ -323,6 +327,15 @@ static struct dmi_system_id acer_quirks[] = { }, { .callback = dmi_matched, + .ident = "Fujitsu Siemens Amilo Li 1718", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"), + }, + .driver_data = &quirk_fujitsu_amilo_li_1718, + }, + { + .callback = dmi_matched, .ident = "Medion MD 98300", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), @@ -416,6 +429,12 @@ struct wmi_interface *iface) return AE_ERROR; *value = result & 0x1; return AE_OK; + case 2: + err = ec_read(0x71, &result); + if (err) + return AE_ERROR; + *value = result & 0x1; + return AE_OK; default: err = ec_read(0xA, &result); if (err) -- cgit v0.10.2 From 5753dd539a86d8fc40a25e1a2cd1005a6525f083 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:48 +0100 Subject: acer-wmi: Disable device autodetection on Fujitsu Siemens Amilo Li2732 The AMW0 (V1) device detection method doesn't work properly on this laptop, so disable it, and for other laptops that may have this problem, by switching on a strange GUID. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index 5b7c5fc..dd0b8d8 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -88,6 +88,7 @@ struct acer_quirks { * Acer ACPI method GUIDs */ #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" +#define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" #define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3" #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A" @@ -548,6 +549,15 @@ static acpi_status AMW0_set_capabilities(void) struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; + /* + * On laptops with this strange GUID (non Acer), normal probing doesn't + * work. + */ + if (wmi_has_guid(AMW0_GUID2)) { + interface->capability |= ACER_CAP_WIRELESS; + return AE_OK; + } + args.eax = ACER_AMW0_WRITE; args.ecx = args.edx = 0; -- cgit v0.10.2 From 81143522aa823036c4aa35bdd3b2e41966cf6e15 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:53 +0100 Subject: acer-wmi: Add debugfs file for device detection Add a debugfs file for showing the full results of the method we use to detect devices on WMID laptops. This should be useful in the case that a Linux user gets an Acer laptop with 3G support (and/ or people who enjoy ripping their wireless cards out) so we can get some feedback on how this value changes in these cases. (At the moment, we always enable the wireless and 3G control. In the case of the former, this is fairly safe. In the case of the latter though, trying to toggle this device if it doesn't exist on a laptop causes ACPI warnings/ errors). To summarise: If you have an Acer laptop with a built in 3G card, please report back the value from this file. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index dd0b8d8..d8b8574 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -152,6 +153,12 @@ struct acer_data { int brightness; }; +struct acer_debug { + struct dentry *root; + struct dentry *devices; + u32 wmid_devices; +}; + /* Each low-level interface must define at least some of the following */ struct wmi_interface { /* The WMI device type */ @@ -162,6 +169,9 @@ struct wmi_interface { /* Private data for the current interface */ struct acer_data data; + + /* debugfs entries associated with this interface */ + struct acer_debug debug; }; /* The static interface pointer, points to the currently detected interface */ @@ -956,6 +966,28 @@ static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR, show_interface, NULL); /* + * debugfs functions + */ +static u32 get_wmid_devices(void) +{ + struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; + acpi_status status; + + status = wmi_query_block(WMID_GUID2, 1, &out); + if (ACPI_FAILURE(status)) + return 0; + + obj = (union acpi_object *) out.pointer; + if (obj && obj->type == ACPI_TYPE_BUFFER && + obj->buffer.length == sizeof(u32)) { + return *((u32 *) obj->buffer.pointer); + } else { + return 0; + } +} + +/* * Platform device */ static int __devinit acer_platform_probe(struct platform_device *device) @@ -1114,6 +1146,33 @@ error_sysfs: return retval; } +static void remove_debugfs(void) +{ + debugfs_remove(interface->debug.devices); + debugfs_remove(interface->debug.root); +} + +static int create_debugfs(void) +{ + interface->debug.root = debugfs_create_dir("acer-wmi", NULL); + if (!interface->debug.root) { + printk(ACER_ERR "Failed to create debugfs directory"); + return -ENOMEM; + } + + interface->debug.devices = debugfs_create_u32("devices", S_IRUGO, + interface->debug.root, + &interface->debug.wmid_devices); + if (!interface->debug.devices) + goto error_debugfs; + + return 0; + +error_debugfs: + remove_debugfs(); + return -ENOMEM; +} + static int __init acer_wmi_init(void) { int err; @@ -1173,6 +1232,13 @@ static int __init acer_wmi_init(void) if (err) return err; + if (wmi_has_guid(WMID_GUID2)) { + interface->debug.wmid_devices = get_wmid_devices(); + err = create_debugfs(); + if (err) + return err; + } + /* Override any initial settings with values from the commandline */ acer_commandline_init(); -- cgit v0.10.2 From 860f0c6b3dcaa455894f690647442dc97cab19c8 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 21 Jun 2008 09:09:58 +0100 Subject: acer-wmi: Remove version number It doesn't make much sense these days. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index d8b8574..e7a3fe5 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -22,8 +22,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define ACER_WMI_VERSION "0.1" - #include #include #include @@ -1177,8 +1175,7 @@ static int __init acer_wmi_init(void) { int err; - printk(ACER_INFO "Acer Laptop ACPI-WMI Extras version %s\n", - ACER_WMI_VERSION); + printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n"); find_quirks(); -- cgit v0.10.2 From d1857056904d5f313f11184fcfa624652ff9620a Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 20 Jun 2008 15:39:09 +0200 Subject: ACPI: don't walk tables if ACPI was disabled Ingo Molnar wrote: > -tip auto-testing started triggering this spinlock corruption message > yesterday: > > [ 3.976213] calling acpi_rtc_init+0x0/0xd3 > [ 3.980213] ACPI Exception (utmutex-0263): AE_BAD_PARAMETER, Thread F7C50000 could not acquire Mutex [3] [20080321] > [ 3.992213] BUG: spinlock bad magic on CPU#0, swapper/1 > [ 3.992213] lock: c2508dc4, .magic: 00000000, .owner: swapper/1, .owner_cpu: 0 This is apparently because some parts of ACPI, including mutexes, are not initialized when acpi=off is passed to the kernel. Reported-by: Ingo Molnar Signed-off-by: Vegard Nossum Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 9b227d4..6d18ca3 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -336,6 +336,9 @@ static int __init acpi_rtc_init(void) if (acpi_disabled) return 0; + if (acpi_disabled) + return 0; + if (dev) { rtc_wake_setup(); rtc_info.wake_on = rtc_wake_on; -- cgit v0.10.2 From cc7e51666d82aedfd6b9a033ca1a10d71c21f1ca Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 24 Jun 2008 22:57:12 -0400 Subject: dock: bay: Don't call acpi_walk_namespace() when ACPI is disabled. Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index 61b6c5b..e6caf5d 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c @@ -380,6 +380,9 @@ static int __init bay_init(void) if (acpi_disabled) return -ENODEV; + if (acpi_disabled) + return -ENODEV; + /* look for dockable drive bays */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_bay, &bays, NULL); diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bb7c51f..1e872e7 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -920,6 +920,9 @@ static int __init dock_init(void) if (acpi_disabled) return 0; + if (acpi_disabled) + return 0; + /* look for a dock station */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_dock, &num, NULL); -- cgit v0.10.2 From 2fe2de5f6c283a7d2a82c1b99a19012079cee555 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 5 Jun 2008 01:15:40 +0200 Subject: ACPI PM: acpi_pm_device_sleep_state() cleanup Get rid of a superfluous acpi_pm_device_sleep_state() parameter. The only legitimate value of that parameter must be derived from the first parameter, which is what all the callers already do. (However, this does not address the fact that ACPI still doesn't set up those flags.) Signed-off-by: David Brownell Signed-off-by: Andi Kleen Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 495c63a..b45806d 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -368,8 +368,8 @@ int acpi_suspend(u32 acpi_state) /** * acpi_pm_device_sleep_state - return preferred power state of ACPI device * in the system sleep state given by %acpi_target_sleep_state - * @dev: device to examine - * @wake: if set, the device should be able to wake up the system + * @dev: device to examine; its driver model wakeup flags control + * whether it should be able to wake up the system * @d_min_p: used to store the upper limit of allowed states range * Return value: preferred power state of the device on success, -ENODEV on * failure (ie. if there's no 'struct acpi_device' for @dev) @@ -387,7 +387,7 @@ int acpi_suspend(u32 acpi_state) * via @wake. */ -int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) +int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) { acpi_handle handle = DEVICE_ACPI_HANDLE(dev); struct acpi_device *adev; @@ -426,7 +426,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) * can wake the system. _S0W may be valid, too. */ if (acpi_target_sleep_state == ACPI_STATE_S0 || - (wake && adev->wakeup.state.enabled && + (device_may_wakeup(dev) && adev->wakeup.state.enabled && adev->wakeup.sleep_state <= acpi_target_sleep_state)) { acpi_status status; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 9d6fc8e..caabf05 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -298,8 +298,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev, { int acpi_state; - acpi_state = acpi_pm_device_sleep_state(&pdev->dev, - device_may_wakeup(&pdev->dev), NULL); + acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL); if (acpi_state < 0) return PCI_POWER_ERROR; diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 5090277..c1b9ea3 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -117,9 +117,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) { int power_state; - power_state = acpi_pm_device_sleep_state(&dev->dev, - device_may_wakeup(&dev->dev), - NULL); + power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); if (power_state < 0) power_state = (state.event == PM_EVENT_ON) ? ACPI_STATE_D0 : ACPI_STATE_D3; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 2f1c68c..db90a74 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -376,9 +376,9 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) #ifdef CONFIG_PM_SLEEP -int acpi_pm_device_sleep_state(struct device *, int, int *); +int acpi_pm_device_sleep_state(struct device *, int *); #else /* !CONFIG_PM_SLEEP */ -static inline int acpi_pm_device_sleep_state(struct device *d, int w, int *p) +static inline int acpi_pm_device_sleep_state(struct device *d, int *p) { if (p) *p = ACPI_STATE_D0; -- cgit v0.10.2 From a80a6da145bab8ee77af304961fc926de7a8ac84 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 5 Jun 2008 01:16:37 +0200 Subject: PCI ACPI: Drop the second argument of platform_pci_choose_state Since the second argument of acpi_pci_choose_state() and platform_pci_choose_state() is never used, remove it. Signed-off-by: Rafael J. Wysocki Signed-off-by: Andi Kleen Acked-by: Pavel Machek Signed-off-by: Len Brown diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index caabf05..dab9d47 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -293,8 +293,7 @@ EXPORT_SYMBOL(pci_osc_control_set); * choose highest power _SxD or any lower power */ -static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev, - pm_message_t state) +static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) { int acpi_state; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e4548ab..75c6023 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -508,7 +508,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) return 0; } -pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); +pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev); /** * pci_choose_state - Choose the power state of a PCI device @@ -528,7 +528,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) return PCI_D0; if (platform_pci_choose_state) { - ret = platform_pci_choose_state(dev, state); + ret = platform_pci_choose_state(dev); if (ret != PCI_POWER_ERROR) return ret; } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 00408c9..312daff 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -6,8 +6,7 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); /* Firmware callbacks */ -extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, - pm_message_t state); +extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev); extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); -- cgit v0.10.2 From 741438b5008791327d2183cebcd7ac9cfad64ec6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 5 Jun 2008 01:17:28 +0200 Subject: ACPI PM: Remove obsolete Toshiba workaround Remove the obsolete workaround for a Toshiba Satellite 4030cdt S1 problem from drivers/acpi/sleep/main.c . Signed-off-by: Rafael J. Wysocki Signed-off-by: Andi Kleen Acked-by: Pavel Machek Signed-off-by: Len Brown diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index b45806d..244e352 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -61,8 +61,6 @@ static u32 acpi_suspend_states[] = { [PM_SUSPEND_MAX] = ACPI_STATE_S5 }; -static int init_8259A_after_S1; - /** * acpi_suspend_begin - Set the target system sleep state to the state * associated with given @pm_state, if supported. @@ -185,13 +183,6 @@ static void acpi_suspend_finish(void) acpi_set_firmware_waking_vector((acpi_physical_address) 0); acpi_target_sleep_state = ACPI_STATE_S0; - -#ifdef CONFIG_X86 - if (init_8259A_after_S1) { - printk("Broken toshiba laptop -> kicking interrupts\n"); - init_8259A(0); - } -#endif } /** @@ -231,26 +222,6 @@ static struct platform_suspend_ops acpi_suspend_ops = { .finish = acpi_suspend_finish, .end = acpi_suspend_end, }; - -/* - * Toshiba fails to preserve interrupts over S1, reinitialization - * of 8259 is needed after S1 resume. - */ -static int __init init_ints_after_s1(const struct dmi_system_id *d) -{ - printk(KERN_WARNING "%s with broken S1 detected.\n", d->ident); - init_8259A_after_S1 = 1; - return 0; -} - -static struct dmi_system_id __initdata acpisleep_dmi_table[] = { - { - .callback = init_ints_after_s1, - .ident = "Toshiba Satellite 4030cdt", - .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),}, - }, - {}, -}; #endif /* CONFIG_SUSPEND */ #ifdef CONFIG_HIBERNATION @@ -472,8 +443,6 @@ int __init acpi_sleep_init(void) u8 type_a, type_b; #ifdef CONFIG_SUSPEND int i = 0; - - dmi_check_system(acpisleep_dmi_table); #endif if (acpi_disabled) -- cgit v0.10.2 From d20a4dca47d2cd027ed58a13f91b424affd1f449 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 11 Jun 2008 22:03:10 +0200 Subject: APM emulation: Notify about all suspend events, not just APM invoked ones (v2) This revamps the apm-emulation code to get suspend notifications regardless of what way pm_suspend() was invoked, whether via the apm ioctl or via /sys/power/state. Also do some code cleanup and add comments while at it. Signed-off-by: Johannes Berg Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index da8a165..aaca402 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -59,6 +59,55 @@ struct apm_queue { }; /* + * thread states (for threads using a writable /dev/apm_bios fd): + * + * SUSPEND_NONE: nothing happening + * SUSPEND_PENDING: suspend event queued for thread and pending to be read + * SUSPEND_READ: suspend event read, pending acknowledgement + * SUSPEND_ACKED: acknowledgement received from thread (via ioctl), + * waiting for resume + * SUSPEND_ACKTO: acknowledgement timeout + * SUSPEND_DONE: thread had acked suspend and is now notified of + * resume + * + * SUSPEND_WAIT: this thread invoked suspend and is waiting for resume + * + * A thread migrates in one of three paths: + * NONE -1-> PENDING -2-> READ -3-> ACKED -4-> DONE -5-> NONE + * -6-> ACKTO -7-> NONE + * NONE -8-> WAIT -9-> NONE + * + * While in PENDING or READ, the thread is accounted for in the + * suspend_acks_pending counter. + * + * The transitions are invoked as follows: + * 1: suspend event is signalled from the core PM code + * 2: the suspend event is read from the fd by the userspace thread + * 3: userspace thread issues the APM_IOC_SUSPEND ioctl (as ack) + * 4: core PM code signals that we have resumed + * 5: APM_IOC_SUSPEND ioctl returns + * + * 6: the notifier invoked from the core PM code timed out waiting + * for all relevant threds to enter ACKED state and puts those + * that haven't into ACKTO + * 7: those threads issue APM_IOC_SUSPEND ioctl too late, + * get an error + * + * 8: userspace thread issues the APM_IOC_SUSPEND ioctl (to suspend), + * ioctl code invokes pm_suspend() + * 9: pm_suspend() returns indicating resume + */ +enum apm_suspend_state { + SUSPEND_NONE, + SUSPEND_PENDING, + SUSPEND_READ, + SUSPEND_ACKED, + SUSPEND_ACKTO, + SUSPEND_WAIT, + SUSPEND_DONE, +}; + +/* * The per-file APM data */ struct apm_user { @@ -69,13 +118,7 @@ struct apm_user { unsigned int reader: 1; int suspend_result; - unsigned int suspend_state; -#define SUSPEND_NONE 0 /* no suspend pending */ -#define SUSPEND_PENDING 1 /* suspend pending read */ -#define SUSPEND_READ 2 /* suspend read, pending ack */ -#define SUSPEND_ACKED 3 /* suspend acked */ -#define SUSPEND_WAIT 4 /* waiting for suspend */ -#define SUSPEND_DONE 5 /* suspend completed */ + enum apm_suspend_state suspend_state; struct apm_queue queue; }; @@ -83,7 +126,8 @@ struct apm_user { /* * Local variables */ -static int suspends_pending; +static atomic_t suspend_acks_pending = ATOMIC_INIT(0); +static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0); static int apm_disabled; static struct task_struct *kapmd_tsk; @@ -166,78 +210,6 @@ static void queue_event(apm_event_t event) wake_up_interruptible(&apm_waitqueue); } -/* - * queue_suspend_event - queue an APM suspend event. - * - * Check that we're in a state where we can suspend. If not, - * return -EBUSY. Otherwise, queue an event to all "writer" - * users. If there are no "writer" users, return '1' to - * indicate that we can immediately suspend. - */ -static int queue_suspend_event(apm_event_t event, struct apm_user *sender) -{ - struct apm_user *as; - int ret = 1; - - mutex_lock(&state_lock); - down_read(&user_list_lock); - - /* - * If a thread is still processing, we can't suspend, so reject - * the request. - */ - list_for_each_entry(as, &apm_user_list, list) { - if (as != sender && as->reader && as->writer && as->suser && - as->suspend_state != SUSPEND_NONE) { - ret = -EBUSY; - goto out; - } - } - - list_for_each_entry(as, &apm_user_list, list) { - if (as != sender && as->reader && as->writer && as->suser) { - as->suspend_state = SUSPEND_PENDING; - suspends_pending++; - queue_add_event(&as->queue, event); - ret = 0; - } - } - out: - up_read(&user_list_lock); - mutex_unlock(&state_lock); - wake_up_interruptible(&apm_waitqueue); - return ret; -} - -static void apm_suspend(void) -{ - struct apm_user *as; - int err = pm_suspend(PM_SUSPEND_MEM); - - /* - * Anyone on the APM queues will think we're still suspended. - * Send a message so everyone knows we're now awake again. - */ - queue_event(APM_NORMAL_RESUME); - - /* - * Finally, wake up anyone who is sleeping on the suspend. - */ - mutex_lock(&state_lock); - down_read(&user_list_lock); - list_for_each_entry(as, &apm_user_list, list) { - if (as->suspend_state == SUSPEND_WAIT || - as->suspend_state == SUSPEND_ACKED) { - as->suspend_result = err; - as->suspend_state = SUSPEND_DONE; - } - } - up_read(&user_list_lock); - mutex_unlock(&state_lock); - - wake_up(&apm_suspend_waitqueue); -} - static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) { struct apm_user *as = fp->private_data; @@ -308,25 +280,22 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) as->suspend_result = -EINTR; - if (as->suspend_state == SUSPEND_READ) { - int pending; - + switch (as->suspend_state) { + case SUSPEND_READ: /* * If we read a suspend command from /dev/apm_bios, * then the corresponding APM_IOC_SUSPEND ioctl is * interpreted as an acknowledge. */ as->suspend_state = SUSPEND_ACKED; - suspends_pending--; - pending = suspends_pending == 0; + atomic_dec(&suspend_acks_pending); mutex_unlock(&state_lock); /* - * If there are no further acknowledges required, - * suspend the system. + * suspend_acks_pending changed, the notifier needs to + * be woken up for this */ - if (pending) - apm_suspend(); + wake_up(&apm_suspend_waitqueue); /* * Wait for the suspend/resume to complete. If there @@ -342,35 +311,21 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) * try_to_freeze() in freezer_count() will not trigger */ freezer_count(); - } else { + break; + case SUSPEND_ACKTO: + as->suspend_result = -ETIMEDOUT; + mutex_unlock(&state_lock); + break; + default: as->suspend_state = SUSPEND_WAIT; mutex_unlock(&state_lock); /* * Otherwise it is a request to suspend the system. - * Queue an event for all readers, and expect an - * acknowledge from all writers who haven't already - * acknowledged. - */ - err = queue_suspend_event(APM_USER_SUSPEND, as); - if (err < 0) { - /* - * Avoid taking the lock here - this - * should be fine. - */ - as->suspend_state = SUSPEND_NONE; - break; - } - - if (err > 0) - apm_suspend(); - - /* - * Wait for the suspend/resume to complete. If there - * are pending acknowledges, we wait here for them. + * Just invoke pm_suspend(), we'll handle it from + * there via the notifier. */ - wait_event_freezable(apm_suspend_waitqueue, - as->suspend_state == SUSPEND_DONE); + as->suspend_result = pm_suspend(PM_SUSPEND_MEM); } mutex_lock(&state_lock); @@ -386,7 +341,6 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) static int apm_release(struct inode * inode, struct file * filp) { struct apm_user *as = filp->private_data; - int pending = 0; filp->private_data = NULL; @@ -396,18 +350,15 @@ static int apm_release(struct inode * inode, struct file * filp) /* * We are now unhooked from the chain. As far as new - * events are concerned, we no longer exist. However, we - * need to balance suspends_pending, which means the - * possibility of sleeping. + * events are concerned, we no longer exist. */ mutex_lock(&state_lock); - if (as->suspend_state != SUSPEND_NONE) { - suspends_pending -= 1; - pending = suspends_pending == 0; - } + if (as->suspend_state == SUSPEND_PENDING || + as->suspend_state == SUSPEND_READ) + atomic_dec(&suspend_acks_pending); mutex_unlock(&state_lock); - if (pending) - apm_suspend(); + + wake_up(&apm_suspend_waitqueue); kfree(as); return 0; @@ -545,7 +496,6 @@ static int kapmd(void *arg) { do { apm_event_t event; - int ret; wait_event_interruptible(kapmd_wait, !queue_empty(&kapmd_queue) || kthread_should_stop()); @@ -570,20 +520,13 @@ static int kapmd(void *arg) case APM_USER_SUSPEND: case APM_SYS_SUSPEND: - ret = queue_suspend_event(event, NULL); - if (ret < 0) { - /* - * We were busy. Try again in 50ms. - */ - queue_add_event(&kapmd_queue, event); - msleep(50); - } - if (ret > 0) - apm_suspend(); + pm_suspend(PM_SUSPEND_MEM); break; case APM_CRITICAL_SUSPEND: - apm_suspend(); + atomic_inc(&userspace_notification_inhibit); + pm_suspend(PM_SUSPEND_MEM); + atomic_dec(&userspace_notification_inhibit); break; } } while (1); @@ -591,6 +534,120 @@ static int kapmd(void *arg) return 0; } +static int apm_suspend_notifier(struct notifier_block *nb, + unsigned long event, + void *dummy) +{ + struct apm_user *as; + int err; + + /* short-cut emergency suspends */ + if (atomic_read(&userspace_notification_inhibit)) + return NOTIFY_DONE; + + switch (event) { + case PM_SUSPEND_PREPARE: + /* + * Queue an event to all "writer" users that we want + * to suspend and need their ack. + */ + mutex_lock(&state_lock); + down_read(&user_list_lock); + + list_for_each_entry(as, &apm_user_list, list) { + if (as->suspend_state != SUSPEND_WAIT && as->reader && + as->writer && as->suser) { + as->suspend_state = SUSPEND_PENDING; + atomic_inc(&suspend_acks_pending); + queue_add_event(&as->queue, APM_USER_SUSPEND); + } + } + + up_read(&user_list_lock); + mutex_unlock(&state_lock); + wake_up_interruptible(&apm_waitqueue); + + /* + * Wait for the the suspend_acks_pending variable to drop to + * zero, meaning everybody acked the suspend event (or the + * process was killed.) + * + * If the app won't answer within a short while we assume it + * locked up and ignore it. + */ + err = wait_event_interruptible_timeout( + apm_suspend_waitqueue, + atomic_read(&suspend_acks_pending) == 0, + 5*HZ); + + /* timed out */ + if (err == 0) { + /* + * Move anybody who timed out to "ack timeout" state. + * + * We could time out and the userspace does the ACK + * right after we time out but before we enter the + * locked section here, but that's fine. + */ + mutex_lock(&state_lock); + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + if (as->suspend_state == SUSPEND_PENDING || + as->suspend_state == SUSPEND_READ) { + as->suspend_state = SUSPEND_ACKTO; + atomic_dec(&suspend_acks_pending); + } + } + up_read(&user_list_lock); + mutex_unlock(&state_lock); + } + + /* let suspend proceed */ + if (err >= 0) + return NOTIFY_OK; + + /* interrupted by signal */ + return NOTIFY_BAD; + + case PM_POST_SUSPEND: + /* + * Anyone on the APM queues will think we're still suspended. + * Send a message so everyone knows we're now awake again. + */ + queue_event(APM_NORMAL_RESUME); + + /* + * Finally, wake up anyone who is sleeping on the suspend. + */ + mutex_lock(&state_lock); + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + if (as->suspend_state == SUSPEND_ACKED) { + /* + * TODO: maybe grab error code, needs core + * changes to push the error to the notifier + * chain (could use the second parameter if + * implemented) + */ + as->suspend_result = 0; + as->suspend_state = SUSPEND_DONE; + } + } + up_read(&user_list_lock); + mutex_unlock(&state_lock); + + wake_up(&apm_suspend_waitqueue); + return NOTIFY_OK; + + default: + return NOTIFY_DONE; + } +} + +static struct notifier_block apm_notif_block = { + .notifier_call = apm_suspend_notifier, +}; + static int __init apm_init(void) { int ret; @@ -604,7 +661,7 @@ static int __init apm_init(void) if (IS_ERR(kapmd_tsk)) { ret = PTR_ERR(kapmd_tsk); kapmd_tsk = NULL; - return ret; + goto out; } wake_up_process(kapmd_tsk); @@ -613,16 +670,27 @@ static int __init apm_init(void) #endif ret = misc_register(&apm_device); - if (ret != 0) { - remove_proc_entry("apm", NULL); - kthread_stop(kapmd_tsk); - } + if (ret) + goto out_stop; + ret = register_pm_notifier(&apm_notif_block); + if (ret) + goto out_unregister; + + return 0; + + out_unregister: + misc_deregister(&apm_device); + out_stop: + remove_proc_entry("apm", NULL); + kthread_stop(kapmd_tsk); + out: return ret; } static void __exit apm_exit(void) { + unregister_pm_notifier(&apm_notif_block); misc_deregister(&apm_device); remove_proc_entry("apm", NULL); -- cgit v0.10.2 From ebb12db51f6c13b30752fcf506baad4c617b153c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Jun 2008 22:04:29 +0200 Subject: Freezer: Introduce PF_FREEZER_NOSIG The freezer currently attempts to distinguish kernel threads from user space tasks by checking if their mm pointer is unset and it does not send fake signals to kernel threads. However, there are kernel threads, mostly related to networking, that behave like user space tasks and may want to be sent a fake signal to be frozen. Introduce the new process flag PF_FREEZER_NOSIG that will be set by default for all kernel threads and make the freezer only send fake signals to the tasks having PF_FREEZER_NOSIG unset. Provide the set_freezable_with_signal() function to be called by the kernel threads that want to be sent a fake signal for freezing. This patch should not change the freezer's observable behavior. Signed-off-by: Rafael J. Wysocki Signed-off-by: Andi Kleen Acked-by: Pavel Machek Signed-off-by: Len Brown diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 0893499..deddeed 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -128,6 +128,15 @@ static inline void set_freezable(void) } /* + * Tell the freezer that the current task should be frozen by it and that it + * should send a fake signal to the task to freeze it. + */ +static inline void set_freezable_with_signal(void) +{ + current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG); +} + +/* * Freezer-friendly wrappers around wait_event_interruptible() and * wait_event_interruptible_timeout(), originally defined in */ @@ -174,6 +183,7 @@ static inline void freezer_do_not_count(void) {} static inline void freezer_count(void) {} static inline int freezer_should_skip(struct task_struct *p) { return 0; } static inline void set_freezable(void) {} +static inline void set_freezable_with_signal(void) {} #define wait_event_freezable(wq, condition) \ wait_event_interruptible(wq, condition) diff --git a/include/linux/sched.h b/include/linux/sched.h index 2134917..ba2f859 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1494,6 +1494,7 @@ static inline void put_task_struct(struct task_struct *t) #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ +#define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ /* * Only the _current_ task can read/write to tsk->flags, but other diff --git a/kernel/kthread.c b/kernel/kthread.c index 97747cd..ac3fb73 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -235,7 +235,7 @@ int kthreadd(void *unused) set_user_nice(tsk, KTHREAD_NICE_LEVEL); set_cpus_allowed(tsk, CPU_MASK_ALL); - current->flags |= PF_NOFREEZE; + current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG; for (;;) { set_current_state(TASK_INTERRUPTIBLE); diff --git a/kernel/power/process.c b/kernel/power/process.c index f1d0b34..5fb8765 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -19,9 +19,6 @@ */ #define TIMEOUT (20 * HZ) -#define FREEZER_KERNEL_THREADS 0 -#define FREEZER_USER_SPACE 1 - static inline int freezeable(struct task_struct * p) { if ((p == current) || @@ -84,63 +81,53 @@ static void fake_signal_wake_up(struct task_struct *p) spin_unlock_irqrestore(&p->sighand->siglock, flags); } -static int has_mm(struct task_struct *p) +static inline bool should_send_signal(struct task_struct *p) { - return (p->mm && !(p->flags & PF_BORROWED_MM)); + return !(p->flags & PF_FREEZER_NOSIG); } /** * freeze_task - send a freeze request to given task * @p: task to send the request to - * @with_mm_only: if set, the request will only be sent if the task has its - * own mm - * Return value: 0, if @with_mm_only is set and the task has no mm of its - * own or the task is frozen, 1, otherwise + * @sig_only: if set, the request will only be sent if the task has the + * PF_FREEZER_NOSIG flag unset + * Return value: 'false', if @sig_only is set and the task has + * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise * - * The freeze request is sent by seting the tasks's TIF_FREEZE flag and + * The freeze request is sent by setting the tasks's TIF_FREEZE flag and * either sending a fake signal to it or waking it up, depending on whether - * or not it has its own mm (ie. it is a user land task). If @with_mm_only - * is set and the task has no mm of its own (ie. it is a kernel thread), - * its TIF_FREEZE flag should not be set. - * - * The task_lock() is necessary to prevent races with exit_mm() or - * use_mm()/unuse_mm() from occuring. + * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task + * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its + * TIF_FREEZE flag will not be set. */ -static int freeze_task(struct task_struct *p, int with_mm_only) +static bool freeze_task(struct task_struct *p, bool sig_only) { - int ret = 1; + /* + * We first check if the task is freezing and next if it has already + * been frozen to avoid the race with frozen_process() which first marks + * the task as frozen and next clears its TIF_FREEZE. + */ + if (!freezing(p)) { + rmb(); + if (frozen(p)) + return false; - task_lock(p); - if (freezing(p)) { - if (has_mm(p)) { - if (!signal_pending(p)) - fake_signal_wake_up(p); - } else { - if (with_mm_only) - ret = 0; - else - wake_up_state(p, TASK_INTERRUPTIBLE); - } + if (!sig_only || should_send_signal(p)) + set_freeze_flag(p); + else + return false; + } + + if (should_send_signal(p)) { + if (!signal_pending(p)) + fake_signal_wake_up(p); + } else if (sig_only) { + return false; } else { - rmb(); - if (frozen(p)) { - ret = 0; - } else { - if (has_mm(p)) { - set_freeze_flag(p); - fake_signal_wake_up(p); - } else { - if (with_mm_only) { - ret = 0; - } else { - set_freeze_flag(p); - wake_up_state(p, TASK_INTERRUPTIBLE); - } - } - } + wake_up_state(p, TASK_INTERRUPTIBLE); } - task_unlock(p); - return ret; + + return true; } static void cancel_freezing(struct task_struct *p) @@ -156,7 +143,7 @@ static void cancel_freezing(struct task_struct *p) } } -static int try_to_freeze_tasks(int freeze_user_space) +static int try_to_freeze_tasks(bool sig_only) { struct task_struct *g, *p; unsigned long end_time; @@ -175,7 +162,7 @@ static int try_to_freeze_tasks(int freeze_user_space) if (frozen(p) || !freezeable(p)) continue; - if (!freeze_task(p, freeze_user_space)) + if (!freeze_task(p, sig_only)) continue; /* @@ -235,13 +222,13 @@ int freeze_processes(void) int error; printk("Freezing user space processes ... "); - error = try_to_freeze_tasks(FREEZER_USER_SPACE); + error = try_to_freeze_tasks(true); if (error) goto Exit; printk("done.\n"); printk("Freezing remaining freezable tasks ... "); - error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); + error = try_to_freeze_tasks(false); if (error) goto Exit; printk("done."); @@ -251,7 +238,7 @@ int freeze_processes(void) return error; } -static void thaw_tasks(int thaw_user_space) +static void thaw_tasks(bool nosig_only) { struct task_struct *g, *p; @@ -260,7 +247,7 @@ static void thaw_tasks(int thaw_user_space) if (!freezeable(p)) continue; - if (!p->mm == thaw_user_space) + if (nosig_only && should_send_signal(p)) continue; thaw_process(p); @@ -271,8 +258,8 @@ static void thaw_tasks(int thaw_user_space) void thaw_processes(void) { printk("Restarting tasks ... "); - thaw_tasks(FREEZER_KERNEL_THREADS); - thaw_tasks(FREEZER_USER_SPACE); + thaw_tasks(true); + thaw_tasks(false); schedule(); printk("done.\n"); } -- cgit v0.10.2 From 52d11025dba32bed696eaee1822b26529e764770 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 11 Jun 2008 22:07:52 +0200 Subject: snapshot: Push BKL down into ioctl handlers Push BKL down into ioctl handlers - snapshot device. Signed-off-by: Alan Cox Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/kernel/power/user.c b/kernel/power/user.c index f5512cb..658262b 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -164,8 +165,8 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, return res; } -static int snapshot_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long snapshot_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) { int error = 0; struct snapshot_data *data; @@ -181,6 +182,8 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, data = filp->private_data; + lock_kernel(); + switch (cmd) { case SNAPSHOT_FREEZE: @@ -389,7 +392,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, error = -ENOTTY; } - + unlock_kernel(); return error; } @@ -399,7 +402,7 @@ static const struct file_operations snapshot_fops = { .read = snapshot_read, .write = snapshot_write, .llseek = no_llseek, - .ioctl = snapshot_ioctl, + .unlocked_ioctl = snapshot_ioctl, }; static struct miscdevice snapshot_device = { -- cgit v0.10.2 From 25f2f3daadaf0768a61d02ee3ed3d9a21e9dc46c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Jun 2008 22:09:45 +0200 Subject: snapshot: Use pm_mutex for mutual exclusion We can avoid taking the BKL in snapshot_ioctl() if pm_mutex is used to prevent the ioctls from being executed concurrently. In addition, although it is only possible to open /dev/snapshot once, the task which has done that may spawn a child that will inherit the open descriptor, so in theory they can call snapshot_write(), snapshot_read() and snapshot_release() concurrently. pm_mutex can also be used for mutual exclusion in such cases. Signed-off-by: Rafael J. Wysocki Signed-off-by: Andi Kleen Acked-by: Pavel Machek Signed-off-by: Len Brown diff --git a/kernel/power/user.c b/kernel/power/user.c index 658262b..a6332a3 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -70,16 +70,22 @@ static int snapshot_open(struct inode *inode, struct file *filp) struct snapshot_data *data; int error; - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) - return -EBUSY; + mutex_lock(&pm_mutex); + + if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { + error = -EBUSY; + goto Unlock; + } if ((filp->f_flags & O_ACCMODE) == O_RDWR) { atomic_inc(&snapshot_device_available); - return -ENOSYS; + error = -ENOSYS; + goto Unlock; } if(create_basic_memory_bitmaps()) { atomic_inc(&snapshot_device_available); - return -ENOMEM; + error = -ENOMEM; + goto Unlock; } nonseekable_open(inode, filp); data = &snapshot_state; @@ -99,33 +105,36 @@ static int snapshot_open(struct inode *inode, struct file *filp) if (error) pm_notifier_call_chain(PM_POST_HIBERNATION); } - if (error) { + if (error) atomic_inc(&snapshot_device_available); - return error; - } data->frozen = 0; data->ready = 0; data->platform_support = 0; - return 0; + Unlock: + mutex_unlock(&pm_mutex); + + return error; } static int snapshot_release(struct inode *inode, struct file *filp) { struct snapshot_data *data; + mutex_lock(&pm_mutex); + swsusp_free(); free_basic_memory_bitmaps(); data = filp->private_data; free_all_swap_pages(data->swap); - if (data->frozen) { - mutex_lock(&pm_mutex); + if (data->frozen) thaw_processes(); - mutex_unlock(&pm_mutex); - } pm_notifier_call_chain(data->mode == O_WRONLY ? PM_POST_HIBERNATION : PM_POST_RESTORE); atomic_inc(&snapshot_device_available); + + mutex_unlock(&pm_mutex); + return 0; } @@ -135,9 +144,13 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, struct snapshot_data *data; ssize_t res; + mutex_lock(&pm_mutex); + data = filp->private_data; - if (!data->ready) - return -ENODATA; + if (!data->ready) { + res = -ENODATA; + goto Unlock; + } res = snapshot_read_next(&data->handle, count); if (res > 0) { if (copy_to_user(buf, data_of(data->handle), res)) @@ -145,6 +158,10 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, else *offp = data->handle.offset; } + + Unlock: + mutex_unlock(&pm_mutex); + return res; } @@ -154,6 +171,8 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, struct snapshot_data *data; ssize_t res; + mutex_lock(&pm_mutex); + data = filp->private_data; res = snapshot_write_next(&data->handle, count); if (res > 0) { @@ -162,6 +181,9 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, else *offp = data->handle.offset; } + + mutex_unlock(&pm_mutex); + return res; } @@ -180,16 +202,16 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - data = filp->private_data; + if (!mutex_trylock(&pm_mutex)) + return -EBUSY; - lock_kernel(); + data = filp->private_data; switch (cmd) { case SNAPSHOT_FREEZE: if (data->frozen) break; - mutex_lock(&pm_mutex); printk("Syncing filesystems ... "); sys_sync(); printk("done.\n"); @@ -197,7 +219,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, error = freeze_processes(); if (error) thaw_processes(); - mutex_unlock(&pm_mutex); if (!error) data->frozen = 1; break; @@ -205,9 +226,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, case SNAPSHOT_UNFREEZE: if (!data->frozen || data->ready) break; - mutex_lock(&pm_mutex); thaw_processes(); - mutex_unlock(&pm_mutex); data->frozen = 0; break; @@ -310,16 +329,11 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, error = -EPERM; break; } - if (!mutex_trylock(&pm_mutex)) { - error = -EBUSY; - break; - } /* * Tasks are frozen and the notifiers have been called with * PM_HIBERNATION_PREPARE */ error = suspend_devices_and_enter(PM_SUSPEND_MEM); - mutex_unlock(&pm_mutex); break; case SNAPSHOT_PLATFORM_SUPPORT: @@ -392,7 +406,9 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, error = -ENOTTY; } - unlock_kernel(); + + mutex_unlock(&pm_mutex); + return error; } -- cgit v0.10.2 From c735ab7da3414c3e639d5c5223092b74689e5d87 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Jun 2008 22:27:21 -0400 Subject: fujitsu-laptop: depends on INPUT fujitsu-laptop uses input_* functions, so it should depend on INPUT. drivers/built-in.o: In function `acpi_fujitsu_add': fujitsu-laptop.c:(.text+0xaaec7): undefined reference to `input_allocate_device' fujitsu-laptop.c:(.text+0xaaf39): undefined reference to `input_register_device' fujitsu-laptop.c:(.text+0xab025): undefined reference to `input_free_device' drivers/built-in.o: In function `acpi_fujitsu_notify': fujitsu-laptop.c:(.text+0xab0d8): undefined reference to `input_event' fujitsu-laptop.c:(.text+0xab0e5): undefined reference to `input_event' fujitsu-laptop.c:(.text+0xab0f5): undefined reference to `input_event' fujitsu-laptop.c:(.text+0xab102): undefined reference to `input_event' drivers/built-in.o: In function `acpi_fujitsu_hotkey_notify': fujitsu-laptop.c:(.text+0xab261): undefined reference to `input_event' drivers/built-in.o:fujitsu-laptop.c:(.text+0xab26e): more undefined references to `input_event' follow drivers/built-in.o: In function `acpi_fujitsu_hotkey_add': fujitsu-laptop.c:(.text+0xab49c): undefined reference to `input_allocate_device' fujitsu-laptop.c:(.text+0xab51a): undefined reference to `input_register_device' fujitsu-laptop.c:(.text+0xab5e4): undefined reference to `input_free_device' make[1]: *** [.tmp_vmlinux1] Error 1 Signed-off-by: Randy Dunlap Signed-off-by: Andi Kleen Acked-by: Jonathan Woithe Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 0551d95..1921b8d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -179,6 +179,7 @@ config FUJITSU_LAPTOP tristate "Fujitsu Laptop Extras" depends on X86 depends on ACPI + depends on INPUT depends on BACKLIGHT_CLASS_DEVICE ---help--- This is a driver for laptops built by Fujitsu: -- cgit v0.10.2 From f3454ae8104efb2dbf0d08ec42c6f5d0fe9225bc Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 12:25:42 +0800 Subject: ACPICA: Add argument count checking to control method invocation via acpi_evaluate_object Error if too few arguments, warning if too many. This applies only to external programmatic control method execution, not method-to-method calls within the AML. Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 14bdfa9..d369164 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -138,6 +138,41 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) return_ACPI_STATUS(AE_NULL_OBJECT); } + /* + * Calculate the number of arguments being passed to the method + */ + + info->param_count = 0; + if (info->parameters) { + while (info->parameters[info->param_count]) + info->param_count++; + } + + /* Error if too few arguments were passed in */ + + if (info->param_count < info->obj_desc->method.param_count) { + ACPI_ERROR((AE_INFO, + "Insufficient arguments - " + "method [%4.4s] needs %d, found %d", + acpi_ut_get_node_name(info->resolved_node), + info->obj_desc->method.param_count, + info->param_count)); + return_ACPI_STATUS(AE_MISSING_ARGUMENTS); + } + + /* Just a warning if too many arguments */ + + else if (info->param_count > + info->obj_desc->method.param_count) { + ACPI_WARNING((AE_INFO, + "Excess arguments - " + "method [%4.4s] needs %d, found %d", + acpi_ut_get_node_name(info-> + resolved_node), + info->obj_desc->method.param_count, + info->param_count)); + } + ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", ACPI_LV_INFO, _COMPONENT); diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 1f59117..ea627ed 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -108,8 +108,9 @@ #define AE_BAD_HEX_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER) #define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0008 | AE_CODE_PROGRAMMER) #define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0009 | AE_CODE_PROGRAMMER) +#define AE_MISSING_ARGUMENTS (acpi_status) (0x000A | AE_CODE_PROGRAMMER) -#define AE_CODE_PGM_MAX 0x0009 +#define AE_CODE_PGM_MAX 0x000A /* * Acpi table exceptions @@ -233,7 +234,8 @@ char const *acpi_gbl_exception_names_pgm[] = { "AE_ALIGNMENT", "AE_BAD_HEX_CONSTANT", "AE_BAD_OCTAL_CONSTANT", - "AE_BAD_DECIMAL_CONSTANT" + "AE_BAD_DECIMAL_CONSTANT", + "AE_MISSING_ARGUMENTS" }; char const *acpi_gbl_exception_names_tbl[] = { diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index a907c67..1cc7450 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -189,6 +189,7 @@ struct acpi_evaluate_info { union acpi_operand_object **parameters; struct acpi_namespace_node *resolved_node; union acpi_operand_object *return_object; + u8 param_count; u8 pass_number; u8 parameter_type; u8 return_object_type; -- cgit v0.10.2 From c91d924e3af08d4f98eab6ebf81f2b8ce132448f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 12:38:10 +0800 Subject: ACPICA: Fix for hang on GPE method invocation Fixes problem where the new method argument count validation mechanism will enter an infinite loop when a GPE method is dispatched. Problem fixed be removing the obsolete code that passes GPE block information to the notify handler via the control method parameter pointer. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 2509809..4613b9c 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -377,7 +377,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, } info->parameters = &this_walk_state->operands[0]; - info->parameter_type = ACPI_PARAM_ARGS; status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, obj_desc->method.aml_start, diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 1386ced..bda23ed 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -615,14 +615,8 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, walk_state->pass_number = pass_number; if (info) { - if (info->parameter_type == ACPI_PARAM_GPE) { - walk_state->gpe_event_info = - ACPI_CAST_PTR(struct acpi_gpe_event_info, - info->parameters); - } else { - walk_state->params = info->parameters; - walk_state->caller_return_desc = &info->return_object; - } + walk_state->params = info->parameters; + walk_state->caller_return_desc = &info->return_object; } status = acpi_ps_init_scope(&walk_state->parser_state, op); diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index e0339d4..ca356e5 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -565,10 +565,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) */ info->prefix_node = local_gpe_event_info.dispatch.method_node; - info->parameters = - ACPI_CAST_PTR(union acpi_operand_object *, - gpe_event_info); - info->parameter_type = ACPI_PARAM_GPE; info->flags = ACPI_IGNORE_RETURN_VALUE; status = acpi_ns_evaluate(info); diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 1628f59..5ab4c01 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -219,7 +219,6 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) info->prefix_node = region_obj2->extra.method_REG; info->pathname = NULL; info->parameters = args; - info->parameter_type = ACPI_PARAM_ARGS; info->flags = ACPI_IGNORE_RETURN_VALUE; /* diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index 6d6d930..e4c5751 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c @@ -542,7 +542,6 @@ acpi_ns_init_one_device(acpi_handle obj_handle, info->prefix_node = device_node; info->pathname = METHOD_NAME__INI; info->parameters = NULL; - info->parameter_type = ACPI_PARAM_ARGS; info->flags = ACPI_IGNORE_RETURN_VALUE; /* diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index a8d5491..b4e135e 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -182,7 +182,6 @@ acpi_evaluate_object(acpi_handle handle, } info->pathname = pathname; - info->parameter_type = ACPI_PARAM_ARGS; /* Convert and validate the device handle */ diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 5258145..5ee09e1 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -335,7 +335,7 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) { acpi_native_uint i; - if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) { + if (info->parameters) { /* Update reference count for each parameter */ diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index befe230..90ed83d 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -679,7 +679,6 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, info->prefix_node = node; info->pathname = METHOD_NAME__SRS; info->parameters = args; - info->parameter_type = ACPI_PARAM_ARGS; info->flags = ACPI_IGNORE_RETURN_VALUE; /* diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 05e61be..7f1f634 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c @@ -217,7 +217,6 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, info->prefix_node = prefix_node; info->pathname = path; - info->parameter_type = ACPI_PARAM_ARGS; /* Evaluate the object/method */ diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index 1cc7450..818c24d 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -108,7 +108,6 @@ struct acpi_walk_state { union acpi_operand_object **caller_return_desc; union acpi_generic_state *control_state; /* List of control states (nested IFs) */ struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */ - struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */ union acpi_operand_object *implicit_return_obj; struct acpi_namespace_node *method_call_node; /* Called method Node */ union acpi_parse_object *method_call_op; /* method_call Op if running a method */ @@ -191,16 +190,10 @@ struct acpi_evaluate_info { union acpi_operand_object *return_object; u8 param_count; u8 pass_number; - u8 parameter_type; u8 return_object_type; u8 flags; }; -/* Types for parameter_type above */ - -#define ACPI_PARAM_ARGS 0 -#define ACPI_PARAM_GPE 1 - /* Values for Flags above */ #define ACPI_IGNORE_RETURN_VALUE 1 -- cgit v0.10.2 From 6719561f9b4281491f58ed9f0bbc179dc7db95b7 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 10 Jun 2008 12:49:56 +0800 Subject: ACPICA: Update tracking macros to reduce code/data size Changed ACPI_MODULE_NAME and ACPI_FUNCTION_NAME to use arrays of strings instead of pointers to static strings. Jan Beulich and Bob Moore. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index fb41a3b..5ad6e39 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -414,7 +414,7 @@ struct acpi_integer_overlay { * error messages. The __FILE__ macro is not very useful for this, because it * often includes the entire pathname to the module */ -#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name; +#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR _acpi_module_name[] = name; #else #define ACPI_MODULE_NAME(name) #endif @@ -467,19 +467,17 @@ struct acpi_integer_overlay { /* * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header, * define it now. This is the case where there the compiler does not support - * a __FUNCTION__ macro or equivalent. We save the function name on the - * local stack. + * a __FUNCTION__ macro or equivalent. */ #ifndef ACPI_GET_FUNCTION_NAME #define ACPI_GET_FUNCTION_NAME _acpi_function_name /* * The Name parameter should be the procedure name as a quoted string. - * This is declared as a local string ("MyFunctionName") so that it can - * be also used by the function exit macros below. + * The function name is also used by the function exit macros below. * Note: (const char) is used to be compatible with the debug interfaces * and macros such as __FUNCTION__. */ -#define ACPI_FUNCTION_NAME(name) const char *_acpi_function_name = #name; +#define ACPI_FUNCTION_NAME(name) static const char _acpi_function_name[] = #name; #else /* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */ -- cgit v0.10.2 From 11f2a61ab418305167f9a3f3a31a50449222f64b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 12:53:01 +0800 Subject: ACPICA: Fix possible negative array index in acpi_ut_validate_exception Added NULL fields to the exception string arrays to eliminate the -1 subtraction on the SubStatus field. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 1f057b7..47354d9 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -64,7 +64,7 @@ ACPI_MODULE_NAME("utmisc") ******************************************************************************/ const char *acpi_ut_validate_exception(acpi_status status) { - acpi_status sub_status; + u32 sub_status; const char *exception = NULL; ACPI_FUNCTION_ENTRY(); @@ -85,32 +85,28 @@ const char *acpi_ut_validate_exception(acpi_status status) case AE_CODE_PROGRAMMER: if (sub_status <= AE_CODE_PGM_MAX) { - exception = - acpi_gbl_exception_names_pgm[sub_status - 1]; + exception = acpi_gbl_exception_names_pgm[sub_status]; } break; case AE_CODE_ACPI_TABLES: if (sub_status <= AE_CODE_TBL_MAX) { - exception = - acpi_gbl_exception_names_tbl[sub_status - 1]; + exception = acpi_gbl_exception_names_tbl[sub_status]; } break; case AE_CODE_AML: if (sub_status <= AE_CODE_AML_MAX) { - exception = - acpi_gbl_exception_names_aml[sub_status - 1]; + exception = acpi_gbl_exception_names_aml[sub_status]; } break; case AE_CODE_CONTROL: if (sub_status <= AE_CODE_CTRL_MAX) { - exception = - acpi_gbl_exception_names_ctrl[sub_status - 1]; + exception = acpi_gbl_exception_names_ctrl[sub_status]; } break; diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index ea627ed..e5a890f 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -226,6 +226,7 @@ char const *acpi_gbl_exception_names_env[] = { }; char const *acpi_gbl_exception_names_pgm[] = { + NULL, "AE_BAD_PARAMETER", "AE_BAD_CHARACTER", "AE_BAD_PATHNAME", @@ -239,6 +240,7 @@ char const *acpi_gbl_exception_names_pgm[] = { }; char const *acpi_gbl_exception_names_tbl[] = { + NULL, "AE_BAD_SIGNATURE", "AE_BAD_HEADER", "AE_BAD_CHECKSUM", @@ -248,6 +250,7 @@ char const *acpi_gbl_exception_names_tbl[] = { }; char const *acpi_gbl_exception_names_aml[] = { + NULL, "AE_AML_ERROR", "AE_AML_PARSE", "AE_AML_BAD_OPCODE", @@ -285,6 +288,7 @@ char const *acpi_gbl_exception_names_aml[] = { }; char const *acpi_gbl_exception_names_ctrl[] = { + NULL, "AE_CTRL_RETURN_VALUE", "AE_CTRL_PENDING", "AE_CTRL_TERMINATE", -- cgit v0.10.2 From 67a119f990063f5662574f6d6414fe9bc5ece86a Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:42:13 +0800 Subject: ACPICA: Eliminate acpi_native_uint type v2 No longer needed; replaced mostly with u32, but also acpi_size where a type that changes 32/64 bit on 32/64-bit platforms is required. v2: Fix a cast of a 32-bit int to a pointer in ACPI to avoid a compiler warning. from David Howells Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a6dbcf4..afb3438 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -612,7 +612,7 @@ static int __init acpi_bus_init_irq(void) return 0; } -acpi_native_uint acpi_gbl_permanent_mmap; +u8 acpi_gbl_permanent_mmap; void __init acpi_early_init(void) diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 610b1ee..949f7c7 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c @@ -151,7 +151,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, ******************************************************************************/ acpi_status -acpi_ds_initialize_objects(acpi_native_uint table_index, +acpi_ds_initialize_objects(u32 table_index, struct acpi_namespace_node * start_node) { acpi_status status; diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index a818e0d..ac0bfb1 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -848,7 +848,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, union acpi_operand_object **operand; struct acpi_namespace_node *node; union acpi_parse_object *next_op; - acpi_native_uint table_index; + u32 table_index; struct acpi_table_header *table; ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index bda23ed..b00d4af 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -70,7 +70,7 @@ acpi_status acpi_ds_result_pop(union acpi_operand_object **object, struct acpi_walk_state *walk_state) { - acpi_native_uint index; + u32 index; union acpi_generic_state *state; acpi_status status; @@ -122,7 +122,7 @@ acpi_ds_result_pop(union acpi_operand_object **object, ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object, acpi_ut_get_object_type_name(*object), - (u32) index, walk_state, walk_state->result_count)); + index, walk_state, walk_state->result_count)); return (AE_OK); } @@ -146,7 +146,7 @@ acpi_ds_result_push(union acpi_operand_object * object, { union acpi_generic_state *state; acpi_status status; - acpi_native_uint index; + u32 index; ACPI_FUNCTION_NAME(ds_result_push); @@ -400,7 +400,7 @@ void acpi_ds_obj_stack_pop_and_delete(u32 pop_count, struct acpi_walk_state *walk_state) { - acpi_native_int i; + s32 i; union acpi_operand_object *obj_desc; ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); @@ -409,7 +409,7 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count, return; } - for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) { + for (i = (s32) pop_count - 1; i >= 0; i--) { if (walk_state->num_operands == 0) { return; } diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 5d30e5b..c56c5c6 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -188,7 +188,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void) static acpi_status acpi_ev_fixed_event_initialize(void) { - acpi_native_uint i; + u32 i; acpi_status status; /* @@ -231,7 +231,7 @@ u32 acpi_ev_fixed_event_detect(void) u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u32 fixed_status; u32 fixed_enable; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_NAME(ev_fixed_event_detect); @@ -260,7 +260,7 @@ u32 acpi_ev_fixed_event_detect(void) /* Found an active (signalled) event */ acpi_os_fixed_event_count(i); - int_status |= acpi_ev_fixed_event_dispatch((u32) i); + int_status |= acpi_ev_fixed_event_dispatch(i); } } diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index ca356e5..c5e53aa 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -315,7 +315,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, { union acpi_operand_object *obj_desc; struct acpi_gpe_block_info *gpe_block; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_ENTRY(); @@ -389,8 +389,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) u32 status_reg; u32 enable_reg; acpi_cpu_flags flags; - acpi_native_uint i; - acpi_native_uint j; + u32 i; + u32 j; ACPI_FUNCTION_NAME(ev_gpe_detect); @@ -472,13 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) */ int_status |= acpi_ev_gpe_dispatch(&gpe_block-> - event_info[(i * - ACPI_GPE_REGISTER_WIDTH) - + - j], - (u32) j + - gpe_register_info-> - base_gpe_number); + event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); } } } diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index e6c4d4c..73c058e 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -189,8 +189,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block) { struct acpi_gpe_event_info *gpe_event_info; - acpi_native_uint i; - acpi_native_uint j; + u32 i; + u32 j; ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers); @@ -203,7 +203,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { gpe_event_info = &gpe_block-> - event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j]; + event_info[((acpi_size) i * + ACPI_GPE_REGISTER_WIDTH) + j]; if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) { @@ -744,8 +745,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) struct acpi_gpe_event_info *gpe_event_info = NULL; struct acpi_gpe_event_info *this_event; struct acpi_gpe_register_info *this_register; - acpi_native_uint i; - acpi_native_uint j; + u32 i; + u32 j; acpi_status status; ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks); @@ -983,8 +984,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, struct acpi_gpe_walk_info gpe_info; u32 wake_gpe_count; u32 gpe_enabled_count; - acpi_native_uint i; - acpi_native_uint j; + u32 i; + u32 j; ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); @@ -1033,7 +1034,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, gpe_event_info = &gpe_block-> - event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j]; + event_info[((acpi_size) i * + ACPI_GPE_REGISTER_WIDTH) + j]; if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 2113e58..1d5670b 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -575,7 +575,7 @@ acpi_status acpi_ev_release_global_lock(void) void acpi_ev_terminate(void) { - acpi_native_uint i; + u32 i; acpi_status status; ACPI_FUNCTION_TRACE(ev_terminate); @@ -589,7 +589,7 @@ void acpi_ev_terminate(void) /* Disable all fixed events */ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { - status = acpi_disable_event((u32) i, 0); + status = acpi_disable_event(i, 0); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not disable fixed event %d", diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 5ab4c01..236fbd1 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -81,7 +81,7 @@ acpi_ev_install_handler(acpi_handle obj_handle, acpi_status acpi_ev_install_region_handlers(void) { acpi_status status; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(ev_install_region_handlers); @@ -151,7 +151,7 @@ acpi_status acpi_ev_install_region_handlers(void) acpi_status acpi_ev_initialize_op_regions(void) { acpi_status status; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(ev_initialize_op_regions); diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 2e3d2c5..6b94b38 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -380,7 +380,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) acpi_status status; struct acpica_device_id hid; struct acpi_compatible_id_list *cid; - acpi_native_uint i; + u32 i; /* * Get the _HID and check for a PCI Root Bridge diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 39d7421..2a32c84 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -53,7 +53,7 @@ ACPI_MODULE_NAME("exconfig") /* Local prototypes */ static acpi_status -acpi_ex_add_table(acpi_native_uint table_index, +acpi_ex_add_table(u32 table_index, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle); @@ -73,7 +73,7 @@ acpi_ex_add_table(acpi_native_uint table_index, ******************************************************************************/ static acpi_status -acpi_ex_add_table(acpi_native_uint table_index, +acpi_ex_add_table(u32 table_index, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle) { @@ -96,7 +96,8 @@ acpi_ex_add_table(acpi_native_uint table_index, /* Install the new table into the local data structures */ - obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); + obj_desc->reference.object = ACPI_CAST_PTR(void, + (unsigned long)table_index); /* Add the table to the namespace */ @@ -128,12 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, { acpi_status status; union acpi_operand_object **operand = &walk_state->operands[0]; - acpi_native_uint table_index; struct acpi_namespace_node *parent_node; struct acpi_namespace_node *start_node; struct acpi_namespace_node *parameter_node = NULL; union acpi_operand_object *ddb_handle; struct acpi_table_header *table; + u32 table_index; ACPI_FUNCTION_TRACE(ex_load_table_op); @@ -280,7 +281,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, { union acpi_operand_object *ddb_handle; struct acpi_table_desc table_desc; - acpi_native_uint table_index; + u32 table_index; acpi_status status; u32 length; @@ -437,7 +438,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) { acpi_status status = AE_OK; union acpi_operand_object *table_desc = ddb_handle; - acpi_native_uint table_index; + u32 table_index; struct acpi_table_header *table; ACPI_FUNCTION_TRACE(ex_unload_table); @@ -454,9 +455,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the table index from the ddb_handle */ + /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */ - table_index = (acpi_native_uint) table_desc->reference.object; + table_index = (u32) (acpi_size) table_desc->reference.object; /* Invoke table handler if present */ diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index fd954b4..261d975 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -288,11 +288,11 @@ acpi_ex_convert_to_ascii(acpi_integer integer, u16 base, u8 * string, u8 data_width) { acpi_integer digit; - acpi_native_uint i; - acpi_native_uint j; - acpi_native_uint k = 0; - acpi_native_uint hex_length; - acpi_native_uint decimal_length; + u32 i; + u32 j; + u32 k = 0; + u32 hex_length; + u32 decimal_length; u32 remainder; u8 supress_zeros; @@ -348,7 +348,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, /* hex_length: 2 ascii hex chars per data byte */ - hex_length = (acpi_native_uint) ACPI_MUL_2(data_width); + hex_length = ACPI_MUL_2(data_width); for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) { /* Get one hex digit, most significant digits first */ diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 74f1b22..976016f 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -775,7 +775,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, u32 num_levels, char *note, char *module_name, u32 line_number) { - acpi_native_uint i; + u32 i; ACPI_FUNCTION_NAME(ex_dump_operands); diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index e336b5d..9ff9d1f 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c @@ -153,14 +153,15 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, /* * Slack mode only: We will go ahead and allow access to this * field if it is within the region length rounded up to the next - * access width boundary. + * access width boundary. acpi_size cast for 64-bit compile. */ if (ACPI_ROUND_UP(rgn_desc->region.length, obj_desc->common_field. access_byte_width) >= - (obj_desc->common_field.base_byte_offset + - (acpi_native_uint) obj_desc->common_field. - access_byte_width + field_datum_byte_offset)) { + ((acpi_size) obj_desc->common_field. + base_byte_offset + + obj_desc->common_field.access_byte_width + + field_datum_byte_offset)) { return_ACPI_STATUS(AE_OK); } } diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index cc956a5..731414a 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -329,8 +329,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Result of two Strings is a String */ - return_desc = acpi_ut_create_string_object((acpi_size) - (operand0->string. + return_desc = acpi_ut_create_string_object(((acpi_size) + operand0->string. length + local_operand1-> string.length)); @@ -352,8 +352,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, /* Result of two Buffers is a Buffer */ - return_desc = acpi_ut_create_buffer_object((acpi_size) - (operand0->buffer. + return_desc = acpi_ut_create_buffer_object(((acpi_size) + operand0->buffer. length + local_operand1-> buffer.length)); diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 7cd8bb5..7a41c40 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -156,7 +156,7 @@ acpi_ex_system_memory_space_handler(u32 function, /* Create a new mapping starting at the address given */ mem_info->mapped_logical_address = - acpi_os_map_memory((acpi_native_uint) address, window_size); + acpi_os_map_memory((acpi_physical_address) address, window_size); if (!mem_info->mapped_logical_address) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 5445751..904f951 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -73,7 +73,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, void acpi_ns_print_pathname(u32 num_segments, char *pathname) { - acpi_native_uint i; + u32 i; ACPI_FUNCTION_NAME(ns_print_pathname); diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 2c92f6c..a4a412b 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -71,8 +71,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); ******************************************************************************/ acpi_status -acpi_ns_load_table(acpi_native_uint table_index, - struct acpi_namespace_node *node) +acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) { acpi_status status; diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 46a79b0..a82271a 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c @@ -63,13 +63,13 @@ ACPI_MODULE_NAME("nsparse") * ******************************************************************************/ acpi_status -acpi_ns_one_complete_parse(acpi_native_uint pass_number, - acpi_native_uint table_index, - struct acpi_namespace_node * start_node) +acpi_ns_one_complete_parse(u32 pass_number, + u32 table_index, + struct acpi_namespace_node *start_node) { union acpi_parse_object *parse_root; acpi_status status; - acpi_native_uint aml_length; + u32 aml_length; u8 *aml_start; struct acpi_walk_state *walk_state; struct acpi_table_header *table; @@ -112,8 +112,8 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, aml_start = (u8 *) table + sizeof(struct acpi_table_header); aml_length = table->length - sizeof(struct acpi_table_header); status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, - aml_start, (u32) aml_length, - NULL, (u8) pass_number); + aml_start, aml_length, NULL, + (u8) pass_number); } if (ACPI_FAILURE(status)) { @@ -158,8 +158,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, ******************************************************************************/ acpi_status -acpi_ns_parse_table(acpi_native_uint table_index, - struct acpi_namespace_node *start_node) +acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) { acpi_status status; diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 64c0398..5b5619c 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -365,7 +365,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) char *internal_name = info->internal_name; char *external_name = info->next_external_char; char *result = NULL; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(ns_build_internal_name); @@ -400,12 +400,11 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) result = &internal_name[i]; } else if (num_segments == 2) { internal_name[i] = AML_DUAL_NAME_PREFIX; - result = &internal_name[(acpi_native_uint) (i + 1)]; + result = &internal_name[(acpi_size) i + 1]; } else { internal_name[i] = AML_MULTI_NAME_PREFIX_OP; - internal_name[(acpi_native_uint) (i + 1)] = - (char)num_segments; - result = &internal_name[(acpi_native_uint) (i + 2)]; + internal_name[(acpi_size) i + 1] = (char)num_segments; + result = &internal_name[(acpi_size) i + 2]; } } @@ -531,12 +530,12 @@ acpi_ns_externalize_name(u32 internal_name_length, char *internal_name, u32 * converted_name_length, char **converted_name) { - acpi_native_uint names_index = 0; - acpi_native_uint num_segments = 0; - acpi_native_uint required_length; - acpi_native_uint prefix_length = 0; - acpi_native_uint i = 0; - acpi_native_uint j = 0; + u32 names_index = 0; + u32 num_segments = 0; + u32 required_length; + u32 prefix_length = 0; + u32 i = 0; + u32 j = 0; ACPI_FUNCTION_TRACE(ns_externalize_name); @@ -582,9 +581,8 @@ acpi_ns_externalize_name(u32 internal_name_length, /* 4-byte names */ names_index = prefix_length + 2; - num_segments = (acpi_native_uint) (u8) - internal_name[(acpi_native_uint) - (prefix_length + 1)]; + num_segments = (u8) + internal_name[(acpi_size) prefix_length + 1]; break; case AML_DUAL_NAME_PREFIX: diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index b4e135e..38be586 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -441,7 +441,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, u32 flags; struct acpica_device_id hid; struct acpi_compatible_id_list *cid; - acpi_native_uint i; + u32 i; int found; status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index e944637..d830b29 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -76,7 +76,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) { u8 *aml = parser_state->aml; u32 package_length = 0; - acpi_native_uint byte_count; + u32 byte_count; u8 byte_zero_mask = 0x3F; /* Default [0:5] */ ACPI_FUNCTION_TRACE(ps_get_next_package_length); @@ -86,7 +86,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) * used to encode the package length, either 0,1,2, or 3 */ byte_count = (aml[0] >> 6); - parser_state->aml += (byte_count + 1); + parser_state->aml += ((acpi_size) byte_count + 1); /* Get bytes 3, 2, 1 as needed */ diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 5ee09e1..270469a 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -333,7 +333,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) static void acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) { - acpi_native_uint i; + u32 i; if (info->parameters) { diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 8a112d1..f61ebc6 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -73,7 +73,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length); static u8 acpi_rs_count_set_bits(u16 bit_field) { - acpi_native_uint bits_set; + u8 bits_set; ACPI_FUNCTION_ENTRY(); @@ -84,7 +84,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) bit_field &= (u16) (bit_field - 1); } - return ((u8) bits_set); + return bits_set; } /******************************************************************************* diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index de1ac38..96a6c03 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -82,7 +82,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); - if (((acpi_native_uint) resource) & 0x3) { + if (((acpi_size) resource) & 0x3) { /* Each internal resource struct is expected to be 32-bit aligned */ diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 90ed83d..f7b3bcd 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -62,7 +62,7 @@ ACPI_MODULE_NAME("rsutils") ******************************************************************************/ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) { - acpi_native_uint i; + u8 i; u8 bit_count; ACPI_FUNCTION_ENTRY(); @@ -71,7 +71,7 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) for (i = 0, bit_count = 0; mask; i++) { if (mask & 0x0001) { - list[bit_count] = (u8) i; + list[bit_count] = i; bit_count++; } @@ -96,8 +96,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) u16 acpi_rs_encode_bitmask(u8 * list, u8 count) { - acpi_native_uint i; - acpi_native_uint mask; + u32 i; + u16 mask; ACPI_FUNCTION_ENTRY(); @@ -107,7 +107,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count) mask |= (0x1 << list[i]); } - return ((u16) mask); + return mask; } /******************************************************************************* @@ -130,7 +130,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count) void acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) { - acpi_native_uint i; + u32 i; ACPI_FUNCTION_ENTRY(); diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 949d411..a4a41ba 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c @@ -155,7 +155,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, * ******************************************************************************/ -void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) +void acpi_tb_parse_fadt(u32 table_index, u8 flags) { u32 length; struct acpi_table_header *table; @@ -280,7 +280,7 @@ static void acpi_tb_convert_fadt(void) { u8 pm1_register_length; struct acpi_generic_address *target; - acpi_native_uint i; + u32 i; /* Update the local FADT table header length */ @@ -396,7 +396,7 @@ static void acpi_tb_validate_fadt(void) u32 *address32; struct acpi_generic_address *address64; u8 length; - acpi_native_uint i; + u32 i; /* Examine all of the 64-bit extended address fields (X fields) */ diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c index 9ca3afc..531584d 100644 --- a/drivers/acpi/tables/tbfind.c +++ b/drivers/acpi/tables/tbfind.c @@ -65,10 +65,9 @@ ACPI_MODULE_NAME("tbfind") ******************************************************************************/ acpi_status acpi_tb_find_table(char *signature, - char *oem_id, - char *oem_table_id, acpi_native_uint * table_index) + char *oem_id, char *oem_table_id, u32 *table_index) { - acpi_native_uint i; + u32 i; acpi_status status; struct acpi_table_header header; diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 5336ce8..b22185f 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -107,11 +107,10 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) ******************************************************************************/ acpi_status -acpi_tb_add_table(struct acpi_table_desc *table_desc, - acpi_native_uint * table_index) +acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) { - acpi_native_uint i; - acpi_native_uint length; + u32 i; + u32 length; acpi_status status = AE_OK; ACPI_FUNCTION_TRACE(tb_add_table); @@ -207,8 +206,8 @@ acpi_status acpi_tb_resize_root_table_list(void) /* Increase the Table Array size */ - tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + - ACPI_ROOT_TABLE_SIZE_INCREMENT) + tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. + size + ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc)); if (!tables) { ACPI_ERROR((AE_INFO, @@ -220,7 +219,7 @@ acpi_status acpi_tb_resize_root_table_list(void) if (acpi_gbl_root_table_list.tables) { ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, - acpi_gbl_root_table_list.size * + (acpi_size) acpi_gbl_root_table_list.size * sizeof(struct acpi_table_desc)); if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { @@ -253,7 +252,7 @@ acpi_status acpi_tb_resize_root_table_list(void) acpi_status acpi_tb_store_table(acpi_physical_address address, struct acpi_table_header *table, - u32 length, u8 flags, acpi_native_uint * table_index) + u32 length, u8 flags, u32 *table_index) { acpi_status status = AE_OK; @@ -334,7 +333,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc) void acpi_tb_terminate(void) { - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(tb_terminate); @@ -374,7 +373,7 @@ void acpi_tb_terminate(void) * ******************************************************************************/ -void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) +void acpi_tb_delete_namespace_by_owner(u32 table_index) { acpi_owner_id owner_id; @@ -403,7 +402,7 @@ void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) * ******************************************************************************/ -acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) +acpi_status acpi_tb_allocate_owner_id(u32 table_index) { acpi_status status = AE_BAD_PARAMETER; @@ -431,7 +430,7 @@ acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) * ******************************************************************************/ -acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) +acpi_status acpi_tb_release_owner_id(u32 table_index) { acpi_status status = AE_BAD_PARAMETER; @@ -462,8 +461,7 @@ acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) * ******************************************************************************/ -acpi_status -acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) +acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) { acpi_status status = AE_BAD_PARAMETER; @@ -490,7 +488,7 @@ acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) * ******************************************************************************/ -u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) +u8 acpi_tb_is_table_loaded(u32 table_index) { u8 is_loaded = FALSE; @@ -518,7 +516,7 @@ u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) * ******************************************************************************/ -void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) +void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) { (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index bc019b9..0cc92ef 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -49,8 +49,8 @@ ACPI_MODULE_NAME("tbutils") /* Local prototypes */ static acpi_physical_address -acpi_tb_get_root_table_entry(u8 * table_entry, - acpi_native_uint table_entry_size); +acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); + /******************************************************************************* * * FUNCTION: acpi_tb_check_xsdt @@ -238,7 +238,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) * ******************************************************************************/ -u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) +u8 acpi_tb_checksum(u8 *buffer, u32 length) { u8 sum = 0; u8 *end = buffer + length; @@ -268,7 +268,7 @@ u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) void acpi_tb_install_table(acpi_physical_address address, - u8 flags, char *signature, acpi_native_uint table_index) + u8 flags, char *signature, u32 table_index) { struct acpi_table_header *table; @@ -336,8 +336,7 @@ acpi_tb_install_table(acpi_physical_address address, ******************************************************************************/ static acpi_physical_address -acpi_tb_get_root_table_entry(u8 * table_entry, - acpi_native_uint table_entry_size) +acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) { u64 address64; @@ -395,8 +394,8 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) { struct acpi_table_rsdp *rsdp; - acpi_native_uint table_entry_size; - acpi_native_uint i; + u32 table_entry_size; + u32 i; u32 table_count; struct acpi_table_header *table; acpi_physical_address address; diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 0e31960..fd7770a 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -125,7 +125,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, /* Root Table Array has been statically allocated by the host */ ACPI_MEMSET(initial_table_array, 0, - initial_table_count * + (acpi_size) initial_table_count * sizeof(struct acpi_table_desc)); acpi_gbl_root_table_list.tables = initial_table_array; @@ -183,9 +183,9 @@ acpi_status acpi_reallocate_root_table(void) return_ACPI_STATUS(AE_SUPPORT); } - new_size = - (acpi_gbl_root_table_list.count + - ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); + new_size = ((acpi_size) acpi_gbl_root_table_list.count + + ACPI_ROOT_TABLE_SIZE_INCREMENT) * + sizeof(struct acpi_table_desc); /* Create new array and copy the old array */ @@ -222,7 +222,7 @@ acpi_status acpi_reallocate_root_table(void) acpi_status acpi_load_table(struct acpi_table_header *table_ptr) { acpi_status status; - acpi_native_uint table_index; + u32 table_index; struct acpi_table_desc table_desc; if (!table_ptr) @@ -264,11 +264,10 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) *****************************************************************************/ acpi_status acpi_get_table_header(char *signature, - acpi_native_uint instance, - struct acpi_table_header * out_table_header) + u32 instance, struct acpi_table_header *out_table_header) { - acpi_native_uint i; - acpi_native_uint j; + u32 i; + u32 j; struct acpi_table_header *header; /* Parameter validation */ @@ -378,10 +377,10 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id) *****************************************************************************/ acpi_status acpi_get_table(char *signature, - acpi_native_uint instance, struct acpi_table_header **out_table) + u32 instance, struct acpi_table_header **out_table) { - acpi_native_uint i; - acpi_native_uint j; + u32 i; + u32 j; acpi_status status; /* Parameter validation */ @@ -435,8 +434,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table) * ******************************************************************************/ acpi_status -acpi_get_table_by_index(acpi_native_uint table_index, - struct acpi_table_header ** table) +acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) { acpi_status status; @@ -493,7 +491,7 @@ static acpi_status acpi_tb_load_namespace(void) { acpi_status status; struct acpi_table_header *table; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(tb_load_namespace); diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index b8c0dfa..2d157e0 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -118,7 +118,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) * ******************************************************************************/ -acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) +acpi_status acpi_find_root_pointer(acpi_size *table_address) { u8 *table_ptr; u8 *mem_rover; @@ -153,7 +153,7 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) * 1b) Search EBDA paragraphs (EBDA is required to be a * minimum of 1_k length) */ - table_ptr = acpi_os_map_memory((acpi_native_uint) + table_ptr = acpi_os_map_memory((acpi_physical_address) physical_address, ACPI_EBDA_WINDOW_SIZE); if (!table_ptr) { diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 655c290..53499ac 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -572,7 +572,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, acpi_status status = AE_OK; union acpi_operand_object *package_object; union acpi_operand_object **package_elements; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); @@ -599,7 +599,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, /* Truncate package and delete it */ - package_object->package.count = (u32) i; + package_object->package.count = i; package_elements[i] = NULL; acpi_ut_remove_reference(package_object); return_ACPI_STATUS(status); diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index f938f46..3919fe5 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c @@ -519,8 +519,8 @@ acpi_ut_ptr_exit(u32 line_number, void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) { - acpi_native_uint i = 0; - acpi_native_uint j; + u32 i = 0; + u32 j; u32 temp32; u8 buf_char; @@ -539,7 +539,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) /* Print current offset */ - acpi_os_printf("%6.4X: ", (u32) i); + acpi_os_printf("%6.4X: ", i); /* Print 16 hex chars */ @@ -549,7 +549,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) /* Dump fill spaces */ acpi_os_printf("%*s", ((display * 2) + 1), " "); - j += (acpi_native_uint) display; + j += display; continue; } @@ -557,32 +557,38 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) case DB_BYTE_DISPLAY: default: /* Default is BYTE display */ - acpi_os_printf("%02X ", buffer[i + j]); + acpi_os_printf("%02X ", + buffer[(acpi_size) i + j]); break; case DB_WORD_DISPLAY: - ACPI_MOVE_16_TO_32(&temp32, &buffer[i + j]); + ACPI_MOVE_16_TO_32(&temp32, + &buffer[(acpi_size) i + j]); acpi_os_printf("%04X ", temp32); break; case DB_DWORD_DISPLAY: - ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]); + ACPI_MOVE_32_TO_32(&temp32, + &buffer[(acpi_size) i + j]); acpi_os_printf("%08X ", temp32); break; case DB_QWORD_DISPLAY: - ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]); + ACPI_MOVE_32_TO_32(&temp32, + &buffer[(acpi_size) i + j]); acpi_os_printf("%08X", temp32); - ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j + 4]); + ACPI_MOVE_32_TO_32(&temp32, + &buffer[(acpi_size) i + j + + 4]); acpi_os_printf("%08X ", temp32); break; } - j += (acpi_native_uint) display; + j += display; } /* @@ -596,7 +602,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) return; } - buf_char = buffer[i + j]; + buf_char = buffer[(acpi_size) i + j]; if (ACPI_IS_PRINT(buf_char)) { acpi_os_printf("%c", buf_char); } else { diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 1fbc351..c5c791a 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -442,7 +442,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) union acpi_generic_state *state_list = NULL; union acpi_operand_object *next_object = NULL; union acpi_generic_state *state; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object); diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 7f1f634..352747e 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c @@ -97,7 +97,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) acpi_status status; union acpi_operand_object *string_desc; union acpi_operand_object *return_desc; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(ut_osi_implementation); @@ -513,7 +513,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, u32 count; u32 size; struct acpi_compatible_id_list *cid_list; - acpi_native_uint i; + u32 i; ACPI_FUNCTION_TRACE(ut_execute_CID); diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 47354d9..6175ca5 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -161,9 +161,9 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table) acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) { - acpi_native_uint i; - acpi_native_uint j; - acpi_native_uint k; + u32 i; + u32 j; + u32 k; acpi_status status; ACPI_FUNCTION_TRACE(ut_allocate_owner_id); @@ -269,7 +269,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) { acpi_owner_id owner_id = *owner_id_ptr; acpi_status status; - acpi_native_uint index; + u32 index; u32 bit; ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id); @@ -589,7 +589,7 @@ acpi_ut_display_init_pathname(u8 type, * ******************************************************************************/ -u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) +u8 acpi_ut_valid_acpi_char(char character, u32 position) { if (!((character >= 'A' && character <= 'Z') || @@ -624,7 +624,7 @@ u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) u8 acpi_ut_valid_acpi_name(u32 name) { - acpi_native_uint i; + u32 i; ACPI_FUNCTION_ENTRY(); @@ -653,7 +653,7 @@ u8 acpi_ut_valid_acpi_name(u32 name) acpi_name acpi_ut_repair_name(char *name) { - acpi_native_uint i; + u32 i; char new_name[ACPI_NAME_SIZE]; for (i = 0; i < ACPI_NAME_SIZE; i++) { diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index e68466d..ede6a80 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -175,8 +175,8 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count) * Create the element array. Count+1 allows the array to be null * terminated. */ - package_elements = ACPI_ALLOCATE_ZEROED((acpi_size) - (count + 1) * sizeof(void *)); + package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count + + 1) * sizeof(void *)); if (!package_elements) { acpi_ut_remove_reference(package_desc); return_PTR(NULL); diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h index 910f018..21a73a1 100644 --- a/include/acpi/acdispat.h +++ b/include/acpi/acdispat.h @@ -221,7 +221,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state); * dsinit */ acpi_status -acpi_ds_initialize_objects(acpi_native_uint table_index, +acpi_ds_initialize_objects(u32 table_index, struct acpi_namespace_node *start_node); /* diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index 74ad971..15dda46 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -140,7 +140,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; */ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; -extern acpi_native_uint acpi_gbl_permanent_mmap; +extern u8 acpi_gbl_permanent_mmap; /* These addresses are calculated from FADT address values */ diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 5ad6e39..d0494ea 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -80,12 +80,12 @@ */ #define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p)) #define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p)) -#define ACPI_ADD_PTR(t,a,b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_native_uint)(b))) -#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b))) +#define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_size)(b))) +#define ACPI_PTR_DIFF(a, b) (acpi_size) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b))) /* Pointer/Integer type conversions */ -#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i) +#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL, (acpi_size) i) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) #define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) @@ -296,22 +296,22 @@ struct acpi_integer_overlay { /* * Rounding macros (Power of two boundaries only) */ -#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & \ - (~(((acpi_native_uint) boundary)-1))) +#define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \ + (~(((acpi_size) boundary)-1))) -#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + \ - (((acpi_native_uint) boundary)-1)) & \ - (~(((acpi_native_uint) boundary)-1))) +#define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \ + (((acpi_size) boundary)-1)) & \ + (~(((acpi_size) boundary)-1))) -/* Note: sizeof(acpi_native_uint) evaluates to either 2, 4, or 8 */ +/* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */ #define ACPI_ROUND_DOWN_TO_32BIT(a) ACPI_ROUND_DOWN(a,4) #define ACPI_ROUND_DOWN_TO_64BIT(a) ACPI_ROUND_DOWN(a,8) -#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_native_uint)) +#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_size)) #define ACPI_ROUND_UP_TO_32BIT(a) ACPI_ROUND_UP(a,4) #define ACPI_ROUND_UP_TO_64BIT(a) ACPI_ROUND_UP(a,8) -#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_native_uint)) +#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_size)) #define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7) #define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a)) @@ -322,7 +322,7 @@ struct acpi_integer_overlay { #define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary)) -#define ACPI_IS_MISALIGNED(value) (((acpi_native_uint)value) & (sizeof(acpi_native_uint)-1)) +#define ACPI_IS_MISALIGNED(value) (((acpi_size)value) & (sizeof(acpi_size)-1)) /* * Bitmask creation diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h index 713b309..d622c30 100644 --- a/include/acpi/acnamesp.h +++ b/include/acpi/acnamesp.h @@ -86,8 +86,7 @@ acpi_status acpi_ns_initialize_devices(void); acpi_status acpi_ns_load_namespace(void); acpi_status -acpi_ns_load_table(acpi_native_uint table_index, - struct acpi_namespace_node *node); +acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node); /* * nswalk - walk the namespace @@ -108,12 +107,11 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct * nsparse - table parsing */ acpi_status -acpi_ns_parse_table(acpi_native_uint table_index, - struct acpi_namespace_node *start_node); +acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node); acpi_status -acpi_ns_one_complete_parse(acpi_native_uint pass_number, - acpi_native_uint table_index, +acpi_ns_one_complete_parse(u32 pass_number, + u32 table_index, struct acpi_namespace_node *start_node); /* diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index d4a560d..3f93a6b 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -144,7 +144,7 @@ void acpi_os_release_mutex(acpi_mutex handle); void *acpi_os_allocate(acpi_size size); void __iomem *acpi_os_map_memory(acpi_physical_address where, - acpi_native_uint length); + acpi_size length); void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2c3806e..bd95ecc 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -98,7 +98,7 @@ void acpi_free(void *address); */ acpi_status acpi_reallocate_root_table(void); -acpi_status acpi_find_root_pointer(acpi_native_uint * rsdp_address); +acpi_status acpi_find_root_pointer(acpi_size *rsdp_address); acpi_status acpi_load_tables(void); @@ -108,15 +108,15 @@ acpi_status acpi_unload_table_id(acpi_owner_id id); acpi_status acpi_get_table_header(acpi_string signature, - acpi_native_uint instance, + u32 instance, struct acpi_table_header *out_table_header); acpi_status acpi_get_table(acpi_string signature, - acpi_native_uint instance, struct acpi_table_header **out_table); + u32 instance, struct acpi_table_header **out_table); acpi_status -acpi_get_table_by_index(acpi_native_uint table_index, +acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table); acpi_status diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index 818c24d..7980a26 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -142,7 +142,7 @@ struct acpi_init_walk_info { u16 package_init; u16 object_count; acpi_owner_id owner_id; - acpi_native_uint table_index; + u32 table_index; }; struct acpi_get_devices_info { diff --git a/include/acpi/actables.h b/include/acpi/actables.h index 4b36a55..0cbe1b9 100644 --- a/include/acpi/actables.h +++ b/include/acpi/actables.h @@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count); /* * tbfadt - FADT parse/convert/validate */ -void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags); +void acpi_tb_parse_fadt(u32 table_index, u8 flags); void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); @@ -58,8 +58,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); */ acpi_status acpi_tb_find_table(char *signature, - char *oem_id, - char *oem_table_id, acpi_native_uint * table_index); + char *oem_id, char *oem_table_id, u32 *table_index); /* * tbinstal - Table removal and deletion @@ -69,30 +68,28 @@ acpi_status acpi_tb_resize_root_table_list(void); acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); acpi_status -acpi_tb_add_table(struct acpi_table_desc *table_desc, - acpi_native_uint * table_index); +acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); acpi_status acpi_tb_store_table(acpi_physical_address address, struct acpi_table_header *table, - u32 length, u8 flags, acpi_native_uint * table_index); + u32 length, u8 flags, u32 *table_index); void acpi_tb_delete_table(struct acpi_table_desc *table_desc); void acpi_tb_terminate(void); -void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index); +void acpi_tb_delete_namespace_by_owner(u32 table_index); -acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index); +acpi_status acpi_tb_allocate_owner_id(u32 table_index); -acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index); +acpi_status acpi_tb_release_owner_id(u32 table_index); -acpi_status -acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id); +acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); -u8 acpi_tb_is_table_loaded(acpi_native_uint table_index); +u8 acpi_tb_is_table_loaded(u32 table_index); -void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded); +void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); /* * tbutils - table manager utilities @@ -103,14 +100,14 @@ void acpi_tb_print_table_header(acpi_physical_address address, struct acpi_table_header *header); -u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length); +u8 acpi_tb_checksum(u8 *buffer, u32 length); acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length); void acpi_tb_install_table(acpi_physical_address address, - u8 flags, char *signature, acpi_native_uint table_index); + u8 flags, char *signature, u32 table_index); acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index dfea2d4..4ea4f40 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -110,10 +110,10 @@ * usually used for memory allocation, efficient loop counters, and array * indexes. The types are similar to the size_t type in the C library and are * required because there is no C type that consistently represents the native - * data width. + * data width. ACPI_SIZE is needed because there is no guarantee that a + * kernel-level C library is present. * * ACPI_SIZE 16/32/64-bit unsigned value - * ACPI_NATIVE_UINT 16/32/64-bit unsigned value * ACPI_NATIVE_INT 16/32/64-bit signed value * */ @@ -147,9 +147,9 @@ typedef int INT32; /*! [End] no source code translation !*/ -typedef u64 acpi_native_uint; typedef s64 acpi_native_int; +typedef u64 acpi_size; typedef u64 acpi_io_address; typedef u64 acpi_physical_address; @@ -186,9 +186,9 @@ typedef int INT32; /*! [End] no source code translation !*/ -typedef u32 acpi_native_uint; typedef s32 acpi_native_int; +typedef u32 acpi_size; typedef u32 acpi_io_address; typedef u32 acpi_physical_address; @@ -202,10 +202,6 @@ typedef u32 acpi_physical_address; #error unknown ACPI_MACHINE_WIDTH #endif -/* Variable-width type, used instead of clib size_t */ - -typedef acpi_native_uint acpi_size; - /******************************************************************************* * * OS-dependent and compiler-dependent types @@ -219,7 +215,7 @@ typedef acpi_native_uint acpi_size; /* Value returned by acpi_os_get_thread_id */ #ifndef acpi_thread_id -#define acpi_thread_id acpi_native_uint +#define acpi_thread_id acpi_size #endif /* Object returned from acpi_os_create_lock */ @@ -231,7 +227,7 @@ typedef acpi_native_uint acpi_size; /* Flags for acpi_os_acquire_lock/acpi_os_release_lock */ #ifndef acpi_cpu_flags -#define acpi_cpu_flags acpi_native_uint +#define acpi_cpu_flags acpi_size #endif /* Object returned from acpi_os_create_cache */ diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index b42cadf..3f663a0 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -172,7 +172,7 @@ char *acpi_ut_strstr(char *string1, char *string2); void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count); -void *acpi_ut_memset(void *dest, acpi_native_uint value, acpi_size count); +void *acpi_ut_memset(void *dest, u8 value, acpi_size count); int acpi_ut_to_upper(int c); @@ -476,7 +476,7 @@ u8 acpi_ut_valid_acpi_name(u32 name); acpi_name acpi_ut_repair_name(char *name); -u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position); +u8 acpi_ut_valid_acpi_char(char character, u32 position); acpi_status acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); -- cgit v0.10.2 From d97b4358da9bdaee5789c85415d770e36aebca52 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:43:34 +0800 Subject: ACPICA: Removed unused include files from source files From lint. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 60e62c4..ad09696 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c @@ -45,8 +45,6 @@ #include #include #include -#include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("excreate") -- cgit v0.10.2 From b52437641edf63cee2f2f73a189154989b4a7ff4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:44:48 +0800 Subject: ACPICA: Several lint changes, no functional changes Remove pointer cast warnings and fix for a debug printf. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 3a2f8cd..5d438c3 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c @@ -503,11 +503,11 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) */ second_desc = obj_desc->common.next_object; second_desc->extra.aml_start = - ((union acpi_parse_object *)(info->data_register_node))-> - named.data; + ACPI_CAST_PTR(union acpi_parse_object, + info->data_register_node)->named.data; second_desc->extra.aml_length = - ((union acpi_parse_object *)(info->data_register_node))-> - named.length; + ACPI_CAST_PTR(union acpi_parse_object, + info->data_register_node)->named.length; break; -- cgit v0.10.2 From 4b8ed631679070c183c8ae7519d2bdb9df124ae4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 13:55:53 +0800 Subject: ACPICA: Add const qualifier for appropriate string constants Mostly MODULE_NAME and printf format strings. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 976016f..c94638d 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -771,9 +771,10 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) void acpi_ex_dump_operands(union acpi_operand_object **operands, acpi_interpreter_mode interpreter_mode, - char *ident, + const char *ident, u32 num_levels, - char *note, char *module_name, u32 line_number) + const char *note, + const char *module_name, u32 line_number) { u32 i; diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 5b5619c..b0817e1 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -73,9 +73,9 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); ******************************************************************************/ void -acpi_ns_report_error(char *module_name, +acpi_ns_report_error(const char *module_name, u32 line_number, - char *internal_name, acpi_status lookup_status) + const char *internal_name, acpi_status lookup_status) { acpi_status status; u32 bad_name; @@ -130,11 +130,11 @@ acpi_ns_report_error(char *module_name, ******************************************************************************/ void -acpi_ns_report_method_error(char *module_name, +acpi_ns_report_method_error(const char *module_name, u32 line_number, - char *message, + const char *message, struct acpi_namespace_node *prefix_node, - char *path, acpi_status method_status) + const char *path, acpi_status method_status) { acpi_status status; struct acpi_namespace_node *node = prefix_node; @@ -167,7 +167,8 @@ acpi_ns_report_method_error(char *module_name, ******************************************************************************/ void -acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message) +acpi_ns_print_node_pathname(struct acpi_namespace_node *node, + const char *message) { struct acpi_buffer buffer; acpi_status status; @@ -296,7 +297,7 @@ u32 acpi_ns_local(acpi_object_type type) void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) { - char *next_external_char; + const char *next_external_char; u32 i; ACPI_FUNCTION_ENTRY(); @@ -363,7 +364,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) { u32 num_segments = info->num_segments; char *internal_name = info->internal_name; - char *external_name = info->next_external_char; + const char *external_name = info->next_external_char; char *result = NULL; u32 i; @@ -471,7 +472,8 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) * *******************************************************************************/ -acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) +acpi_status +acpi_ns_internalize_name(const char *external_name, char **converted_name) { char *internal_name; struct acpi_namestring_info info; @@ -527,7 +529,7 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) acpi_status acpi_ns_externalize_name(u32 internal_name_length, - char *internal_name, + const char *internal_name, u32 * converted_name_length, char **converted_name) { u32 names_index = 0; @@ -821,7 +823,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) acpi_status acpi_ns_get_node(struct acpi_namespace_node *prefix_node, - char *pathname, + const char *pathname, u32 flags, struct acpi_namespace_node **return_node) { union acpi_generic_state scope_info; diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index ede0848..3dfb8a4 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -309,7 +309,8 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, * ******************************************************************************/ -void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) +void *acpi_ut_allocate(acpi_size size, + u32 component, const char *module, u32 line) { void *allocation; @@ -353,7 +354,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) ******************************************************************************/ void *acpi_ut_allocate_zeroed(acpi_size size, - u32 component, char *module, u32 line) + u32 component, const char *module, u32 line) { void *allocation; diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index 3919fe5..fd66ecb 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c @@ -157,7 +157,8 @@ void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print(u32 requested_debug_level, u32 line_number, const char *function_name, - char *module_name, u32 component_id, char *format, ...) + const char *module_name, + u32 component_id, const char *format, ...) { acpi_thread_id thread_id; va_list args; @@ -228,7 +229,8 @@ void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print_raw(u32 requested_debug_level, u32 line_number, const char *function_name, - char *module_name, u32 component_id, char *format, ...) + const char *module_name, + u32 component_id, const char *format, ...) { va_list args; @@ -261,7 +263,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) ******************************************************************************/ void acpi_ut_trace(u32 line_number, - const char *function_name, char *module_name, u32 component_id) + const char *function_name, + const char *module_name, u32 component_id) { acpi_gbl_nesting_level++; @@ -293,7 +296,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace) void acpi_ut_trace_ptr(u32 line_number, const char *function_name, - char *module_name, u32 component_id, void *pointer) + const char *module_name, u32 component_id, void *pointer) { acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr(); @@ -324,7 +327,7 @@ acpi_ut_trace_ptr(u32 line_number, void acpi_ut_trace_str(u32 line_number, const char *function_name, - char *module_name, u32 component_id, char *string) + const char *module_name, u32 component_id, char *string) { acpi_gbl_nesting_level++; @@ -356,7 +359,7 @@ acpi_ut_trace_str(u32 line_number, void acpi_ut_trace_u32(u32 line_number, const char *function_name, - char *module_name, u32 component_id, u32 integer) + const char *module_name, u32 component_id, u32 integer) { acpi_gbl_nesting_level++; @@ -386,7 +389,8 @@ acpi_ut_trace_u32(u32 line_number, void acpi_ut_exit(u32 line_number, - const char *function_name, char *module_name, u32 component_id) + const char *function_name, + const char *module_name, u32 component_id) { acpi_ut_debug_print(ACPI_LV_FUNCTIONS, @@ -417,7 +421,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit) void acpi_ut_status_exit(u32 line_number, const char *function_name, - char *module_name, u32 component_id, acpi_status status) + const char *module_name, + u32 component_id, acpi_status status) { if (ACPI_SUCCESS(status)) { @@ -458,7 +463,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) void acpi_ut_value_exit(u32 line_number, const char *function_name, - char *module_name, u32 component_id, acpi_integer value) + const char *module_name, + u32 component_id, acpi_integer value) { acpi_ut_debug_print(ACPI_LV_FUNCTIONS, @@ -490,7 +496,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit) void acpi_ut_ptr_exit(u32 line_number, const char *function_name, - char *module_name, u32 component_id, u8 * ptr) + const char *module_name, u32 component_id, u8 *ptr) { acpi_ut_debug_print(ACPI_LV_FUNCTIONS, diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 6175ca5..f34be67 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -1020,7 +1020,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, ******************************************************************************/ void ACPI_INTERNAL_VAR_XFACE -acpi_ut_error(char *module_name, u32 line_number, char *format, ...) +acpi_ut_error(const char *module_name, u32 line_number, const char *format, ...) { va_list args; @@ -1033,8 +1033,8 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...) } void ACPI_INTERNAL_VAR_XFACE -acpi_ut_exception(char *module_name, - u32 line_number, acpi_status status, char *format, ...) +acpi_ut_exception(const char *module_name, + u32 line_number, acpi_status status, const char *format, ...) { va_list args; @@ -1050,7 +1050,8 @@ acpi_ut_exception(char *module_name, EXPORT_SYMBOL(acpi_ut_exception); void ACPI_INTERNAL_VAR_XFACE -acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) +acpi_ut_warning(const char *module_name, + u32 line_number, const char *format, ...) { va_list args; @@ -1063,7 +1064,7 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) } void ACPI_INTERNAL_VAR_XFACE -acpi_ut_info(char *module_name, u32 line_number, char *format, ...) +acpi_ut_info(const char *module_name, u32 line_number, const char *format, ...) { va_list args; diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index ede6a80..e254844 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -83,7 +83,8 @@ acpi_ut_get_element_length(u8 object_type, * ******************************************************************************/ -union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, +union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char + *module_name, u32 line_number, u32 component_id, acpi_object_type @@ -347,7 +348,7 @@ u8 acpi_ut_valid_internal_object(void *object) * ******************************************************************************/ -void *acpi_ut_allocate_object_desc_dbg(char *module_name, +void *acpi_ut_allocate_object_desc_dbg(const char *module_name, u32 line_number, u32 component_id) { union acpi_operand_object *object; diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index e249ce5..accd120 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -367,9 +367,10 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth); void acpi_ex_dump_operands(union acpi_operand_object **operands, acpi_interpreter_mode interpreter_mode, - char *ident, + const char *ident, u32 num_levels, - char *note, char *module_name, u32 line_number); + const char *note, + const char *module_name, u32 line_number); #ifdef ACPI_FUTURE_USAGE void diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 62d7468..b221c85 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -282,8 +282,8 @@ struct acpi_predefined_names { /* Info structure used to convert external<->internal namestrings */ struct acpi_namestring_info { - char *external_name; - char *next_external_char; + const char *external_name; + const char *next_external_char; char *internal_name; u32 length; u32 num_segments; diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index d0494ea..77439df 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -414,7 +414,7 @@ struct acpi_integer_overlay { * error messages. The __FILE__ macro is not very useful for this, because it * often includes the entire pathname to the module */ -#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR _acpi_module_name[] = name; +#define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name; #else #define ACPI_MODULE_NAME(name) #endif diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h index d622c30..9ed70a0 100644 --- a/include/acpi/acnamesp.h +++ b/include/acpi/acnamesp.h @@ -199,7 +199,7 @@ acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for); acpi_status acpi_ns_get_node(struct acpi_namespace_node *prefix_node, - char *external_pathname, + const char *external_pathname, u32 flags, struct acpi_namespace_node **out_node); acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node); @@ -263,28 +263,30 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node); u32 acpi_ns_local(acpi_object_type type); void -acpi_ns_report_error(char *module_name, +acpi_ns_report_error(const char *module_name, u32 line_number, - char *internal_name, acpi_status lookup_status); + const char *internal_name, acpi_status lookup_status); void -acpi_ns_report_method_error(char *module_name, +acpi_ns_report_method_error(const char *module_name, u32 line_number, - char *message, + const char *message, struct acpi_namespace_node *node, - char *path, acpi_status lookup_status); + const char *path, acpi_status lookup_status); -void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *msg); +void +acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info); -acpi_status acpi_ns_internalize_name(char *dotted_name, char **converted_name); +acpi_status +acpi_ns_internalize_name(const char *dotted_name, char **converted_name); acpi_status acpi_ns_externalize_name(u32 internal_name_length, - char *internal_name, + const char *internal_name, u32 * converted_name_length, char **converted_name); struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle); diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 3f663a0..69f8888 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -245,41 +245,45 @@ void acpi_ut_track_stack_ptr(void); void acpi_ut_trace(u32 line_number, - const char *function_name, char *module_name, u32 component_id); + const char *function_name, + const char *module_name, u32 component_id); void acpi_ut_trace_ptr(u32 line_number, const char *function_name, - char *module_name, u32 component_id, void *pointer); + const char *module_name, u32 component_id, void *pointer); void acpi_ut_trace_u32(u32 line_number, const char *function_name, - char *module_name, u32 component_id, u32 integer); + const char *module_name, u32 component_id, u32 integer); void acpi_ut_trace_str(u32 line_number, const char *function_name, - char *module_name, u32 component_id, char *string); + const char *module_name, u32 component_id, char *string); void acpi_ut_exit(u32 line_number, - const char *function_name, char *module_name, u32 component_id); + const char *function_name, + const char *module_name, u32 component_id); void acpi_ut_status_exit(u32 line_number, const char *function_name, - char *module_name, u32 component_id, acpi_status status); + const char *module_name, + u32 component_id, acpi_status status); void acpi_ut_value_exit(u32 line_number, const char *function_name, - char *module_name, u32 component_id, acpi_integer value); + const char *module_name, + u32 component_id, acpi_integer value); void acpi_ut_ptr_exit(u32 line_number, const char *function_name, - char *module_name, u32 component_id, u8 * ptr); + const char *module_name, u32 component_id, u8 *ptr); void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); @@ -297,33 +301,35 @@ void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print(u32 requested_debug_level, u32 line_number, const char *function_name, - char *module_name, - u32 component_id, char *format, ...) ACPI_PRINTF_LIKE(6); + const char *module_name, + u32 component_id, + const char *format, ...) ACPI_PRINTF_LIKE(6); void ACPI_INTERNAL_VAR_XFACE acpi_ut_debug_print_raw(u32 requested_debug_level, u32 line_number, const char *function_name, - char *module_name, + const char *module_name, u32 component_id, - char *format, ...) ACPI_PRINTF_LIKE(6); + const char *format, ...) ACPI_PRINTF_LIKE(6); void ACPI_INTERNAL_VAR_XFACE -acpi_ut_error(char *module_name, - u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); +acpi_ut_error(const char *module_name, + u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); void ACPI_INTERNAL_VAR_XFACE -acpi_ut_exception(char *module_name, +acpi_ut_exception(const char *module_name, u32 line_number, - acpi_status status, char *format, ...) ACPI_PRINTF_LIKE(4); + acpi_status status, + const char *format, ...) ACPI_PRINTF_LIKE(4); void ACPI_INTERNAL_VAR_XFACE -acpi_ut_warning(char *module_name, - u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); +acpi_ut_warning(const char *module_name, + u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); void ACPI_INTERNAL_VAR_XFACE -acpi_ut_info(char *module_name, - u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); +acpi_ut_info(const char *module_name, + u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3); /* * utdelete - Object deletion and reference counts @@ -376,13 +382,14 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); /* * utobject - internal object create/delete/cache routines */ -union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, +union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char + *module_name, u32 line_number, u32 component_id, acpi_object_type type); -void *acpi_ut_allocate_object_desc_dbg(char *module_name, +void *acpi_ut_allocate_object_desc_dbg(const char *module_name, u32 line_number, u32 component_id); #define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_acpi_module_name,__LINE__,_COMPONENT,t) @@ -543,26 +550,29 @@ acpi_status acpi_ut_initialize_buffer(struct acpi_buffer *buffer, acpi_size required_length); -void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line); +void *acpi_ut_allocate(acpi_size size, + u32 component, const char *module, u32 line); void *acpi_ut_allocate_zeroed(acpi_size size, - u32 component, char *module, u32 line); + u32 component, const char *module, u32 line); #ifdef ACPI_DBG_TRACK_ALLOCATIONS void *acpi_ut_allocate_and_track(acpi_size size, - u32 component, char *module, u32 line); + u32 component, const char *module, u32 line); void *acpi_ut_allocate_zeroed_and_track(acpi_size size, - u32 component, char *module, u32 line); + u32 component, + const char *module, u32 line); void -acpi_ut_free_and_track(void *address, u32 component, char *module, u32 line); +acpi_ut_free_and_track(void *address, + u32 component, const char *module, u32 line); #ifdef ACPI_FUTURE_USAGE void acpi_ut_dump_allocation_info(void); #endif /* ACPI_FUTURE_USAGE */ -void acpi_ut_dump_allocations(u32 component, char *module); +void acpi_ut_dump_allocations(u32 component, const char *module); acpi_status acpi_ut_create_list(char *list_name, -- cgit v0.10.2 From b25d2a470bc9ffef4c34248952d914bd6fc0fcf6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:15:05 +0800 Subject: ACPICA: Update version to 20080514 Update version to 20080514 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 28fe8ba..f81ba60 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20080321 +#define ACPI_CA_VERSION 0x20080514 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, -- cgit v0.10.2 From d0e184abc5983281ef189db2c759d65d56eb1b80 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:16:47 +0800 Subject: ACPICA: Workaround for reversed _PRT entries from BIOS Some BIOSs erroneously reverse the _PRT SourceName and the SourceIndex. Detect and repair this problem. MS ACPI also allows and repairs this problem, thus ACPICA must also. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index faddaee..70c84ec 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -285,6 +285,23 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, } /* + * If the BIOS has erroneously reversed the _PRT source_name (index 2) + * and the source_index (index 3), fix it. _PRT is important enough to + * workaround this BIOS error. This also provides compatibility with + * other ACPI implementations. + */ + obj_desc = sub_object_list[3]; + if (!obj_desc + || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { + sub_object_list[3] = sub_object_list[2]; + sub_object_list[2] = obj_desc; + + ACPI_WARNING((AE_INFO, + "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed", + index)); + } + + /* * 3) Third subobject: Dereference the PRT.source_name * The name may be unresolved (slack mode), so allow a null object */ -- cgit v0.10.2 From 19d0cfe9ddfdf7afa8d1765ab0bd2a7dd30e47c9 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 15:54:40 +0800 Subject: ACPICA: Update DMAR and SRAT table definitions Synchronized tables with current specifications. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c index f41d67f..1eb2973 100644 --- a/arch/x86/mm/srat_32.c +++ b/arch/x86/mm/srat_32.c @@ -156,10 +156,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity) num_memory_chunks++; - printk(KERN_DEBUG "Memory range %08lx to %08lx (type %x)" + printk(KERN_DEBUG "Memory range %08lx to %08lx" " in proximity domain %02x %s\n", start_pfn, end_pfn, - memory_affinity->memory_type, pxm, ((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ? "enabled and removable" : "enabled" ) ); diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 658e5f3..cb9864e 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -120,10 +120,10 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) struct acpi_srat_mem_affinity *p = (struct acpi_srat_mem_affinity *)header; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n", + "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s\n", (unsigned long)p->base_address, (unsigned long)p->length, - p->memory_type, p->proximity_domain, + p->proximity_domain, (p->flags & ACPI_SRAT_MEM_ENABLED)? "enabled" : "disabled", (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 9af239b..dfb0fb5 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -300,6 +300,7 @@ struct acpi_table_dbgp { /******************************************************************************* * * DMAR - DMA Remapping table + * From "Intel Virtualization Technology for Directed I/O", Sept. 2007 * ******************************************************************************/ @@ -382,6 +383,20 @@ struct acpi_dmar_reserved_memory { #define ACPI_DMAR_ALLOW_ALL (1) + +/* 2: Root Port ATS Capability Reporting Structure */ + +struct acpi_dmar_atsr { + struct acpi_dmar_header header; + u8 flags; + u8 reserved; + u16 segment; +}; + +/* Flags */ + +#define ACPI_DMAR_ALL_PORTS (1) + /******************************************************************************* * * ECDT - Embedded Controller Boot Resources Table @@ -1156,9 +1171,9 @@ struct acpi_srat_mem_affinity { u16 reserved; /* Reserved, must be zero */ u64 base_address; u64 length; - u32 memory_type; /* See acpi_address_range_id */ + u32 reserved1; u32 flags; - u64 reserved1; /* Reserved, must be zero */ + u64 reserved2; /* Reserved, must be zero */ }; /* Flags */ -- cgit v0.10.2 From 75e5b5fb778646a93d98adb1ca697435362d2856 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:19:32 +0800 Subject: ACPICA: Update disassembler for DMAR table changes Now supports the 2007 intel Virtualization Technology for Directed I/O specification. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 788f887..f53faca 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h @@ -162,6 +162,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[]; extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[]; extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[]; extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; extern struct acpi_dmtable_info acpi_dm_table_info_einj[]; extern struct acpi_dmtable_info acpi_dm_table_info_einj0[]; diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index dfb0fb5..d38f9be2 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -311,6 +311,10 @@ struct acpi_table_dmar { u8 reserved[10]; }; +/* Flags */ + +#define ACPI_DMAR_INTR_REMAP (1) + /* DMAR subtable header */ struct acpi_dmar_header { -- cgit v0.10.2 From 5a1a57efeb152d6b8a3b2a20f6b192d074e919ec Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:21:05 +0800 Subject: ACPICA: Fix for invalid large array index on 64-bit systems This problem was introduced in 20080514 as a result of the elimination of the acpi_native_uint type. Code uses a negative array index, which should be eliminated. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index c94638d..f337c3f 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -776,7 +776,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, const char *note, const char *module_name, u32 line_number) { - u32 i; + s32 i; ACPI_FUNCTION_NAME(ex_dump_operands); -- cgit v0.10.2 From 71d993e115706a4108bdc7e3cb3cf25309f17aa6 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:25:05 +0800 Subject: ACPICA: Cleanup debug operand dump mechanism Eliminated unnecessary operands; eliminated use of negative index in loop. Operands now displayed in correct order, not backwards. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index ac0bfb1..6a81c44 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -691,12 +691,6 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, status = acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); - - ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, - acpi_ps_get_opcode_name(op->common.aml_opcode), - walk_state->num_operands, - "after AcpiExResolveOperands"); - if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)", acpi_ps_get_opcode_name(op->common.aml_opcode), @@ -785,10 +779,6 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } - ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, - acpi_ps_get_opcode_name(op->common.aml_opcode), - 1, "after AcpiExResolveOperands"); - obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { return_ACPI_STATUS(AE_NOT_EXIST); @@ -882,10 +872,6 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } - ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, - acpi_ps_get_opcode_name(op->common.aml_opcode), - 1, "after AcpiExResolveOperands"); - operand = &walk_state->operands[0]; /* Find the ACPI table */ @@ -1091,10 +1077,8 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } - ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, - acpi_ps_get_opcode_name(op->common.aml_opcode), - 1, "after AcpiExResolveOperands"); - + ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, + acpi_ps_get_opcode_name(op->common.aml_opcode), 1); /* * Get the bank_value operand and save it * (at Top of stack) diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index b246b96..b5072fa 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -408,14 +408,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) [walk_state-> num_operands - 1]), walk_state); - if (ACPI_SUCCESS(status)) { - ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, - ACPI_IMODE_EXECUTE, - acpi_ps_get_opcode_name - (walk_state->opcode), - walk_state->num_operands, - "after ExResolveOperands"); - } } if (ACPI_SUCCESS(status)) { diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index f337c3f..2be2e2b 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -580,25 +580,22 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case ACPI_TYPE_BUFFER: - acpi_os_printf("Buffer len %X @ %p\n", + acpi_os_printf("Buffer length %.2X @ %p\n", obj_desc->buffer.length, obj_desc->buffer.pointer); - length = obj_desc->buffer.length; - if (length > 64) { - length = 64; - } - /* Debug only -- dump the buffer contents */ if (obj_desc->buffer.pointer) { - acpi_os_printf("Buffer Contents: "); - - for (index = 0; index < length; index++) { - acpi_os_printf(" %02x", - obj_desc->buffer.pointer[index]); + length = obj_desc->buffer.length; + if (length > 128) { + length = 128; } - acpi_os_printf("\n"); + + acpi_os_printf + ("Buffer Contents: (displaying length 0x%.2X)\n", + length); + ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length); } break; @@ -756,55 +753,42 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) * * FUNCTION: acpi_ex_dump_operands * - * PARAMETERS: Operands - Operand list - * interpreter_mode - Load or Exec - * Ident - Identification - * num_levels - # of stack entries to dump above line - * Note - Output notation - * module_name - Caller's module name - * line_number - Caller's invocation line number + * PARAMETERS: Operands - A list of Operand objects + * opcode_name - AML opcode name + * num_operands - Operand count for this opcode * - * DESCRIPTION: Dump the object stack + * DESCRIPTION: Dump the operands associated with the opcode * ******************************************************************************/ void acpi_ex_dump_operands(union acpi_operand_object **operands, - acpi_interpreter_mode interpreter_mode, - const char *ident, - u32 num_levels, - const char *note, - const char *module_name, u32 line_number) + const char *opcode_name, u32 num_operands) { - s32 i; - ACPI_FUNCTION_NAME(ex_dump_operands); - if (!ident) { - ident = "?"; - } - - if (!note) { - note = "?"; + if (!opcode_name) { + opcode_name = "UNKNOWN"; } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "************* Operand Stack Contents (Opcode [%s], %d Operands)\n", - ident, num_levels)); + "**** Start operand dump for opcode [%s], %d operands\n", + opcode_name, num_operands)); - if (num_levels == 0) { - num_levels = 1; + if (num_operands == 0) { + num_operands = 1; } - /* Dump the operand stack starting at the top */ + /* Dump the individual operands */ - for (i = 0; num_levels > 0; i--, num_levels--) { - acpi_ex_dump_operand(operands[i], 0); + while (num_operands) { + acpi_ex_dump_operand(*operands, 0); + operands++; + num_operands--; } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "************* Operand Stack dump from %s(%d), %s\n", - module_name, line_number, note)); + "**** End operand dump for [%s]\n", opcode_name)); return; } diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 73e29e5..54085f1 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -698,5 +698,9 @@ acpi_ex_resolve_operands(u16 opcode, } } + ACPI_DUMP_OPERANDS(walk_state->operands, + acpi_ps_get_opcode_name(opcode), + walk_state->num_operands); + return_ACPI_STATUS(status); } diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 76c875b..38b55e3 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -343,12 +343,6 @@ acpi_ex_store(union acpi_operand_object *source_desc, acpi_ut_get_object_type_name(dest_desc), dest_desc)); - ACPI_DUMP_STACK_ENTRY(source_desc); - ACPI_DUMP_STACK_ENTRY(dest_desc); - ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ExStore", - 2, - "Target is not a Reference or Constant object"); - return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 904f951..0ab2200 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -515,12 +515,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, if (obj_type > ACPI_TYPE_LOCAL_MAX) { acpi_os_printf - ("(Ptr to ACPI Object type %X [UNKNOWN])\n", + ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n", obj_type); bytes_to_dump = 32; } else { acpi_os_printf - ("(Ptr to ACPI Object type %X [%s])\n", + ("(Pointer to ACPI Object type %.2X [%s])\n", obj_type, acpi_ut_get_type_name(obj_type)); bytes_to_dump = sizeof(union acpi_operand_object); diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index accd120..e8db7a3 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h @@ -366,11 +366,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth); void acpi_ex_dump_operands(union acpi_operand_object **operands, - acpi_interpreter_mode interpreter_mode, - const char *ident, - u32 num_levels, - const char *note, - const char *module_name, u32 line_number); + const char *opcode_name, u32 num_opcodes); #ifdef ACPI_FUTURE_USAGE void diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 77439df..57ab9e9 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -597,7 +597,7 @@ struct acpi_integer_overlay { /* Stack and buffer dumping */ #define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a),0) -#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_acpi_module_name,__LINE__) +#define ACPI_DUMP_OPERANDS(a,b,c) acpi_ex_dump_operands(a,b,c) #define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b) #define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) @@ -633,7 +633,7 @@ struct acpi_integer_overlay { #define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0) #define ACPI_FUNCTION_ENTRY() do { } while(0) #define ACPI_DUMP_STACK_ENTRY(a) do { } while(0) -#define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0) +#define ACPI_DUMP_OPERANDS(a,b,c) do { } while(0) #define ACPI_DUMP_ENTRY(a,b) do { } while(0) #define ACPI_DUMP_TABLES(a,b) do { } while(0) #define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0) -- cgit v0.10.2 From fd0a43276dc986e186eb27e5755a18e97e07a7eb Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:27:55 +0800 Subject: ACPICA: Cleanup of _PRT parsing code Removed extraneous else clauses, other general cleanup. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 70c84ec..7804a8c 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -181,9 +181,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, } /* - * Loop through the ACPI_INTERNAL_OBJECTS - Each object - * should be a package that in turn contains an - * acpi_integer Address, a u8 Pin, a Name and a u8 source_index. + * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a + * package that in turn contains an acpi_integer Address, a u8 Pin, + * a Name, and a u8 source_index. */ top_object_list = package_object->package.elements; number_of_elements = package_object->package.count; @@ -240,9 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* 1) First subobject: Dereference the PRT.Address */ obj_desc = sub_object_list[0]; - if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - user_prt->address = obj_desc->integer.value; - } else { + if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%X].Address) Need Integer, found %s", index, @@ -250,12 +248,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, return_ACPI_STATUS(AE_BAD_DATA); } + user_prt->address = obj_desc->integer.value; + /* 2) Second subobject: Dereference the PRT.Pin */ obj_desc = sub_object_list[1]; - if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - user_prt->pin = (u32) obj_desc->integer.value; - } else { + if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%X].Pin) Need Integer, found %s", index, @@ -284,6 +282,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, } } + user_prt->pin = (u32) obj_desc->integer.value; + /* * If the BIOS has erroneously reversed the _PRT source_name (index 2) * and the source_index (index 3), fix it. _PRT is important enough to @@ -381,9 +381,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* 4) Fourth subobject: Dereference the PRT.source_index */ obj_desc = sub_object_list[source_index_index]; - if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { - user_prt->source_index = (u32) obj_desc->integer.value; - } else { + if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%X].SourceIndex) Need Integer, found %s", index, @@ -391,6 +389,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, return_ACPI_STATUS(AE_BAD_DATA); } + user_prt->source_index = (u32) obj_desc->integer.value; + /* Point to the next union acpi_operand_object in the top level package */ top_object_list++; -- cgit v0.10.2 From b53ce3f7186e2fc561f02085b5021df10d715ce2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:30:04 +0800 Subject: ACPICA: Fix mutex debug code for wrong loop termination value Loop was terminating one iteration early, missing one of the debugger handshake mutexes. Linn Crosetto. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index f7d602b..7331dde 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c @@ -218,7 +218,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) * the mutex ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) { + for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_ERROR((AE_INFO, @@ -315,7 +315,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) * ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) { + for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { continue; -- cgit v0.10.2 From 9c9f6d052dc6f469431461a97d49cf9c5558b8ad Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 10 Jun 2008 14:37:53 +0800 Subject: ACPICA: Update version to 20080609 Update version to 20080609. Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index f81ba60..4eb75a8 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -63,7 +63,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20080514 +#define ACPI_CA_VERSION 0x20080609 /* * OS name, used for the _OS object. The _OS object is essentially obsolete, -- cgit v0.10.2 From 71b58cbb0c30d1f78636a48c4721529449d6ea37 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 20 Jun 2008 09:42:47 +0800 Subject: ACPI: Enhance /sys/firmware/interrupts to allow enable/disable/clear from user-space Allow users to enable/disable/clear a specific & valid GPE/Fixed Event in user space. This is useful for debugging, especially for some interrupt storm issues. All wakeup GPEs are disabled and they can not be enabled at runtime, and we mark them as invalid. All GPEs that don't have a _Lxx/_Exx method are marked as invalid. All Fixed Events that don't have an event handler are marked as invalid and they can't be enabled until an event handler is registered. Signed-off-by: Zhang Rui Signed-off-by: Ling Ming Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi index 9470ed9..f27be7d 100644 --- a/Documentation/ABI/testing/sysfs-firmware-acpi +++ b/Documentation/ABI/testing/sysfs-firmware-acpi @@ -29,46 +29,46 @@ Description: $ cd /sys/firmware/acpi/interrupts $ grep . * - error:0 - ff_gbl_lock:0 - ff_pmtimer:0 - ff_pwr_btn:0 - ff_rt_clk:0 - ff_slp_btn:0 - gpe00:0 - gpe01:0 - gpe02:0 - gpe03:0 - gpe04:0 - gpe05:0 - gpe06:0 - gpe07:0 - gpe08:0 - gpe09:174 - gpe0A:0 - gpe0B:0 - gpe0C:0 - gpe0D:0 - gpe0E:0 - gpe0F:0 - gpe10:0 - gpe11:60 - gpe12:0 - gpe13:0 - gpe14:0 - gpe15:0 - gpe16:0 - gpe17:0 - gpe18:0 - gpe19:7 - gpe1A:0 - gpe1B:0 - gpe1C:0 - gpe1D:0 - gpe1E:0 - gpe1F:0 - gpe_all:241 - sci:241 + error: 0 + ff_gbl_lock: 0 enable + ff_pmtimer: 0 invalid + ff_pwr_btn: 0 enable + ff_rt_clk: 2 disable + ff_slp_btn: 0 invalid + gpe00: 0 invalid + gpe01: 0 enable + gpe02: 108 enable + gpe03: 0 invalid + gpe04: 0 invalid + gpe05: 0 invalid + gpe06: 0 enable + gpe07: 0 enable + gpe08: 0 invalid + gpe09: 0 invalid + gpe0A: 0 invalid + gpe0B: 0 invalid + gpe0C: 0 invalid + gpe0D: 0 invalid + gpe0E: 0 invalid + gpe0F: 0 invalid + gpe10: 0 invalid + gpe11: 0 invalid + gpe12: 0 invalid + gpe13: 0 invalid + gpe14: 0 invalid + gpe15: 0 invalid + gpe16: 0 invalid + gpe17: 1084 enable + gpe18: 0 enable + gpe19: 0 invalid + gpe1A: 0 invalid + gpe1B: 0 invalid + gpe1C: 0 invalid + gpe1D: 0 invalid + gpe1E: 0 invalid + gpe1F: 0 invalid + gpe_all: 1192 + sci: 1194 sci - The total number of times the ACPI SCI has claimed an interrupt. @@ -89,6 +89,13 @@ Description: error - an interrupt that can't be accounted for above. + invalid: it's either a wakeup GPE or a GPE/Fixed Event that + doesn't have an event handler. + + disable: the GPE/Fixed Event is valid but disabled. + + enable: the GPE/Fixed Event is valid and enabled. + Root has permission to clear any of these counters. Eg. # echo 0 > gpe11 @@ -97,3 +104,43 @@ Description: None of these counters has an effect on the function of the system, they are simply statistics. + + Besides this, user can also write specific strings to these files + to enable/disable/clear ACPI interrupts in user space, which can be + used to debug some ACPI interrupt storm issues. + + Note that only writting to VALID GPE/Fixed Event is allowed, + i.e. user can only change the status of runtime GPE and + Fixed Event with event handler installed. + + Let's take power button fixed event for example, please kill acpid + and other user space applications so that the machine won't shutdown + when pressing the power button. + # cat ff_pwr_btn + 0 + # press the power button for 3 times; + # cat ff_pwr_btn + 3 + # echo disable > ff_pwr_btn + # cat ff_pwr_btn + disable + # press the power button for 3 times; + # cat ff_pwr_btn + disable + # echo enable > ff_pwr_btn + # cat ff_pwr_btn + 4 + /* + * this is because the status bit is set even if the enable bit is cleared, + * and it triggers an ACPI fixed event when the enable bit is set again + */ + # press the power button for 3 times; + # cat ff_pwr_btn + 7 + # echo disable > ff_pwr_btn + # press the power button for 3 times; + # echo clear > ff_pwr_btn /* clear the status bit */ + # echo disable > ff_pwr_btn + # cat ff_pwr_btn + 7 + diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 99a7502..73bfd6b 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -472,7 +472,6 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) } ACPI_EXPORT_SYMBOL(acpi_clear_gpe) -#ifdef ACPI_FUTURE_USAGE /******************************************************************************* * * FUNCTION: acpi_get_event_status @@ -489,6 +488,7 @@ ACPI_EXPORT_SYMBOL(acpi_clear_gpe) acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) { acpi_status status = AE_OK; + u32 value; ACPI_FUNCTION_TRACE(acpi_get_event_status); @@ -506,7 +506,20 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) status = acpi_get_register(acpi_gbl_fixed_event_info[event]. - status_register_id, event_status); + enable_register_id, &value); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + *event_status = value; + + status = + acpi_get_register(acpi_gbl_fixed_event_info[event]. + status_register_id, &value); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + + if (value) + *event_status |= ACPI_EVENT_FLAG_SET; return_ACPI_STATUS(status); } @@ -566,7 +579,6 @@ acpi_get_gpe_status(acpi_handle gpe_device, } ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) -#endif /* ACPI_FUTURE_USAGE */ /******************************************************************************* * * FUNCTION: acpi_install_gpe_block diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index 58347d6..0b80db9 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -186,7 +186,6 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) * ******************************************************************************/ -#ifdef ACPI_FUTURE_USAGE acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, acpi_event_status * event_status) @@ -246,7 +245,6 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, unlock_and_exit: return (status); } -#endif /* ACPI_FUTURE_USAGE */ /****************************************************************************** * diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 5bd2dec..d8e3f15 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -167,7 +167,13 @@ static int acpi_system_sysfs_init(void) #define COUNT_ERROR 2 /* other */ #define NUM_COUNTERS_EXTRA 3 -static u32 *all_counters; +#define ACPI_EVENT_VALID 0x01 +struct event_counter { + u32 count; + u32 flags; +}; + +static struct event_counter *all_counters; static u32 num_gpes; static u32 num_counters; static struct attribute **all_attrs; @@ -202,9 +208,44 @@ static int count_num_gpes(void) return count; } +static int get_gpe_device(int index, acpi_handle *handle) +{ + struct acpi_gpe_xrupt_info *gpe_xrupt_info; + struct acpi_gpe_block_info *gpe_block; + acpi_cpu_flags flags; + struct acpi_namespace_node *node; + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; + while (gpe_xrupt_info) { + gpe_block = gpe_xrupt_info->gpe_block_list_head; + node = gpe_block->node; + while (gpe_block) { + index -= gpe_block->register_count * + ACPI_GPE_REGISTER_WIDTH; + if (index < 0) { + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + /* return NULL if it's FADT GPE */ + if (node->type != ACPI_TYPE_DEVICE) + *handle = NULL; + else + *handle = node; + return 0; + } + node = gpe_block->node; + gpe_block = gpe_block->next; + } + gpe_xrupt_info = gpe_xrupt_info->next; + } + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + + return -ENODEV; +} + static void delete_gpe_attr_array(void) { - u32 *tmp = all_counters; + struct event_counter *tmp = all_counters; all_counters = NULL; kfree(tmp); @@ -230,9 +271,10 @@ void acpi_os_gpe_count(u32 gpe_number) return; if (gpe_number < num_gpes) - all_counters[gpe_number]++; + all_counters[gpe_number].count++; else - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++; + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. + count++; return; } @@ -243,44 +285,144 @@ void acpi_os_fixed_event_count(u32 event_number) return; if (event_number < ACPI_NUM_FIXED_EVENTS) - all_counters[num_gpes + event_number]++; + all_counters[num_gpes + event_number].count++; else - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++; + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. + count++; return; } +static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) +{ + int result = 0; + + if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) + goto end; + + if (index < num_gpes) { + result = get_gpe_device(index, handle); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, + "Invalid GPE 0x%x\n", index)); + goto end; + } + result = acpi_get_gpe_status(*handle, index, + ACPI_NOT_ISR, status); + } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) + result = acpi_get_event_status(index - num_gpes, status); + + /* + * sleep/power button GPE/Fixed Event is enabled after acpi_system_init, + * check the status at runtime and mark it as valid once it's enabled + */ + if (!result && (*status & ACPI_EVENT_FLAG_ENABLED)) + all_counters[index].flags |= ACPI_EVENT_VALID; +end: + return result; +} + static ssize_t counter_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI] = + int index = attr - counter_attrs; + int size; + acpi_handle handle; + acpi_event_status status; + int result = 0; + + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = acpi_irq_handled; - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE] = + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = acpi_gpe_count; - return sprintf(buf, "%d\n", all_counters[attr - counter_attrs]); + size = sprintf(buf, "%8d", all_counters[index].count); + + /* "gpe_all" or "sci" */ + if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) + goto end; + + result = get_status(index, &status, &handle); + if (result) + goto end; + + if (!(all_counters[index].flags & ACPI_EVENT_VALID)) + size += sprintf(buf + size, " invalid"); + else if (status & ACPI_EVENT_FLAG_ENABLED) + size += sprintf(buf + size, " enable"); + else + size += sprintf(buf + size, " disable"); + +end: + size += sprintf(buf + size, "\n"); + return result ? result : size; } /* * counter_set() sets the specified counter. * setting the total "sci" file to any value clears all counters. + * enable/disable/clear a gpe/fixed event in user space. */ static ssize_t counter_set(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t size) { int index = attr - counter_attrs; + acpi_event_status status; + acpi_handle handle; + int result = 0; if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { int i; for (i = 0; i < num_counters; ++i) - all_counters[i] = 0; + all_counters[i].count = 0; acpi_gpe_count = 0; acpi_irq_handled = 0; + goto end; + } + /* show the event status for both GPEs and Fixed Events */ + result = get_status(index, &status, &handle); + if (result) + goto end; + + if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Can not change Invalid GPE/Fixed Event status\n")); + return -EINVAL; + } + + if (index < num_gpes) { + if (!strcmp(buf, "disable\n") && + (status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR); + else if (!strcmp(buf, "enable\n") && + !(status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR); + else if (!strcmp(buf, "clear\n") && + (status & ACPI_EVENT_FLAG_SET)) + result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); + else + all_counters[index].count = strtoul(buf, NULL, 0); + } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { + int event = index - num_gpes; + if (!strcmp(buf, "disable\n") && + (status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_disable_event(event, ACPI_NOT_ISR); + else if (!strcmp(buf, "enable\n") && + !(status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_enable_event(event, ACPI_NOT_ISR); + else if (!strcmp(buf, "clear\n") && + (status & ACPI_EVENT_FLAG_SET)) + result = acpi_clear_event(event); + else + all_counters[index].count = strtoul(buf, NULL, 0); } else - all_counters[index] = strtoul(buf, NULL, 0); + all_counters[index].count = strtoul(buf, NULL, 0); - return size; + if (ACPI_FAILURE(result)) + result = -EINVAL; +end: + return result ? result : size; } void acpi_irq_stats_init(void) @@ -298,7 +440,8 @@ void acpi_irq_stats_init(void) if (all_attrs == NULL) return; - all_counters = kzalloc(sizeof(u32) * (num_counters), GFP_KERNEL); + all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), + GFP_KERNEL); if (all_counters == NULL) goto fail; diff --git a/include/acpi/achware.h b/include/acpi/achware.h index 45e9859..97a72b1 100644 --- a/include/acpi/achware.h +++ b/include/acpi/achware.h @@ -102,11 +102,9 @@ acpi_status acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block); -#ifdef ACPI_FUTURE_USAGE acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, acpi_event_status * event_status); -#endif /* ACPI_FUTURE_USAGE */ acpi_status acpi_hw_disable_all_gpes(void); diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index bd95ecc..94d94e1 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -248,9 +248,7 @@ acpi_status acpi_disable_event(u32 event, u32 flags); acpi_status acpi_clear_event(u32 event); -#ifdef ACPI_FUTURE_USAGE acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); -#endif /* ACPI_FUTURE_USAGE */ acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type); @@ -260,12 +258,10 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); -#ifdef ACPI_FUTURE_USAGE acpi_status acpi_get_gpe_status(acpi_handle gpe_device, u32 gpe_number, u32 flags, acpi_event_status * event_status); -#endif /* ACPI_FUTURE_USAGE */ acpi_status acpi_install_gpe_block(acpi_handle gpe_device, -- cgit v0.10.2 From 5b53496a5ad79e91052f72761a7c5516b069bc99 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 17 Jun 2008 14:39:59 +0800 Subject: ACPI: Disable the C2C3_FFH access mode HW has no MWAIT support 991528d7348667924176f3e29addea0675298944 (ACPI: Processor native C-states using MWAIT) started passing C2C3_FFH to _PDC to tell the BIOS that Linux supports MWAIT for deep C-states. However, we should first double check with the hardware that it actually supports MWAIT before potentially exposing a BIOS bug of an MWAIT _CST on HW that doesn't support MWAIT. Signed-off-by: Zhao Yakui Signed-off-by: Li Shaohua Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index de2d2e4..7c074ee 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c @@ -56,6 +56,12 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) if (cpu_has(c, X86_FEATURE_ACPI)) buf[2] |= ACPI_PDC_T_FFH; + /* + * If mwait/monitor is unsupported, C2/C3_FFH will be disabled + */ + if (!cpu_has(c, X86_FEATURE_MWAIT)) + buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); + obj->type = ACPI_TYPE_BUFFER; obj->buffer.length = 12; obj->buffer.pointer = (u8 *) buf; -- cgit v0.10.2 From c1e3b377ad48febba6f91b8ae42c44ee4d4ab45e Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 Jun 2008 17:58:53 +0800 Subject: ACPI: Create "idle=halt" bootparam "idle=halt" limits the idle loop to using the halt instruction. No MWAIT, no IO accesses, no C-states deeper than C1. If something is broken in the idle code, "idle=halt" is a less severe workaround than "idle=poll" which disables all power savings. Signed-off-by: Zhao Yakui Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 312fe77..65db7f4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -818,7 +818,7 @@ and is between 256 and 4096 characters. It is defined in the file See Documentation/ide/ide.txt. idle= [X86] - Format: idle=poll or idle=mwait + Format: idle=poll or idle=mwait, idle=halt Poll forces a polling idle loop that can slightly improves the performance of waking up a idle CPU, but will use a lot of power and make the system run hot. Not recommended. @@ -826,6 +826,8 @@ and is between 256 and 4096 characters. It is defined in the file to not use it because it doesn't save as much power as a normal idle loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same as idle=poll. + idle=halt. Halt is forced to be used for CPU idle. + In such case C2/C3 won't be used again. ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem Claim all unknown PCI IDE storage controllers. diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index fabaf08..612b3c4 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -55,6 +55,8 @@ void (*ia64_mark_idle)(int); unsigned long boot_option_idle_override = 0; EXPORT_SYMBOL(boot_option_idle_override); +unsigned long idle_halt; +EXPORT_SYMBOL(idle_halt); void ia64_do_show_stack (struct unw_frame_info *info, void *arg) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 7dceea9..7fc7294 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -7,6 +7,10 @@ #include #include #include +#include + +unsigned long idle_halt; +EXPORT_SYMBOL(idle_halt); struct kmem_cache *task_xstate_cachep; @@ -325,7 +329,18 @@ static int __init idle_setup(char *str) pm_idle = poll_idle; } else if (!strcmp(str, "mwait")) force_mwait = 1; - else + else if (!strcmp(str, "halt")) { + /* + * When the boot option of idle=halt is added, halt is + * forced to be used for CPU idle. In such case CPU C2/C3 + * won't be used again. + * To continue to load the CPU idle driver, don't touch + * the boot_option_idle_override. + */ + pm_idle = default_idle; + idle_halt = 1; + return 0; + } else return -1; boot_option_idle_override = 1; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0fc310e..c75c7ac 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * Include the apic definitions for x86 to have the APIC timer related defines @@ -57,6 +58,7 @@ #include #include +#include #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" @@ -955,6 +957,17 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) } else { continue; } + if (cx.type == ACPI_STATE_C1 && idle_halt) { + /* + * In most cases the C1 space_id obtained from + * _CST object is FIXED_HARDWARE access mode. + * But when the option of idle=halt is added, + * the entry_method type should be changed from + * CSTATE_FFH to CSTATE_HALT. + */ + cx.entry_method = ACPI_CSTATE_HALT; + snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); + } } else { snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", cx.address); @@ -1780,6 +1793,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, return 0; if (!first_run) { + if (idle_halt) { + /* + * When the boot option of "idle=halt" is added, halt + * is used for CPU IDLE. + * In such case C2/C3 is meaningless. So the max_cstate + * is set to one. + */ + max_cstate = 1; + } dmi_check_system(processor_power_dmi_table); max_cstate = acpi_processor_cstate_check(max_cstate); if (max_cstate < ACPI_C_STATES_MAX) diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 6aff126..f36e28a 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -763,6 +763,7 @@ prefetchw (const void *x) #define spin_lock_prefetch(x) prefetchw(x) extern unsigned long boot_option_idle_override; +extern unsigned long idle_halt; #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 7f73827..bc22162 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -727,6 +727,7 @@ extern int force_mwait; extern void select_idle_routine(const struct cpuinfo_x86 *c); extern unsigned long boot_option_idle_override; +extern unsigned long idle_halt; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -- cgit v0.10.2 From da5e09a1b3e5a9fc0b15a3feb64e921ccc55ba74 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 Jun 2008 18:01:09 +0800 Subject: ACPI : Create "idle=nomwait" bootparam "idle=nomwait" disables the use of the MWAIT instruction from both C1 (C1_FFH) and deeper (C2C3_FFH) C-states. When MWAIT is unavailable, the BIOS and OS generally negotiate to use the HALT instruction for C1, and use IO accesses for deeper C-states. This option is useful for power and performance comparisons, and also to work around BIOS bugs where broken MWAIT support is advertised. http://bugzilla.kernel.org/show_bug.cgi?id=10807 http://bugzilla.kernel.org/show_bug.cgi?id=10914 Signed-off-by: Zhao Yakui Signed-off-by: Li Shaohua Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 65db7f4..5e497d1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -818,7 +818,7 @@ and is between 256 and 4096 characters. It is defined in the file See Documentation/ide/ide.txt. idle= [X86] - Format: idle=poll or idle=mwait, idle=halt + Format: idle=poll or idle=mwait, idle=halt, idle=nomwait Poll forces a polling idle loop that can slightly improves the performance of waking up a idle CPU, but will use a lot of power and make the system run hot. Not recommended. @@ -828,6 +828,7 @@ and is between 256 and 4096 characters. It is defined in the file as idle=poll. idle=halt. Halt is forced to be used for CPU idle. In such case C2/C3 won't be used again. + idle=nomwait. Disable mwait for CPU C-states ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem Claim all unknown PCI IDE storage controllers. diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 612b3c4..3ab8373 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -57,6 +57,8 @@ unsigned long boot_option_idle_override = 0; EXPORT_SYMBOL(boot_option_idle_override); unsigned long idle_halt; EXPORT_SYMBOL(idle_halt); +unsigned long idle_nomwait; +EXPORT_SYMBOL(idle_nomwait); void ia64_do_show_stack (struct unw_frame_info *info, void *arg) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 7fc7294..4d629c6 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -11,6 +11,8 @@ unsigned long idle_halt; EXPORT_SYMBOL(idle_halt); +unsigned long idle_nomwait; +EXPORT_SYMBOL(idle_nomwait); struct kmem_cache *task_xstate_cachep; @@ -340,6 +342,15 @@ static int __init idle_setup(char *str) pm_idle = default_idle; idle_halt = 1; return 0; + } else if (!strcmp(str, "nomwait")) { + /* + * If the boot option of "idle=nomwait" is added, + * it means that mwait will be disabled for CPU C2/C3 + * states. In such case it won't touch the variable + * of boot_option_idle_override. + */ + idle_nomwait = 1; + return 0; } else return -1; diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 9a803f8..4e1bb89 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -265,7 +265,20 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr) if (!pdc_in) return status; + if (idle_nomwait) { + /* + * If mwait is disabled for CPU C-states, the C2C3_FFH access + * mode will be disabled in the parameter of _PDC object. + * Of course C1_FFH access mode will also be disabled. + */ + union acpi_object *obj; + u32 *buffer = NULL; + obj = pdc_in->pointer; + buffer = (u32 *)(obj->buffer.pointer); + buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + + } status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); if (ACPI_FAILURE(status)) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index c75c7ac..d592dbb 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -957,13 +957,17 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) } else { continue; } - if (cx.type == ACPI_STATE_C1 && idle_halt) { + if (cx.type == ACPI_STATE_C1 && + (idle_halt || idle_nomwait)) { /* * In most cases the C1 space_id obtained from * _CST object is FIXED_HARDWARE access mode. * But when the option of idle=halt is added, * the entry_method type should be changed from * CSTATE_FFH to CSTATE_HALT. + * When the option of idle=nomwait is added, + * the C1 entry_method type should be + * CSTATE_HALT. */ cx.entry_method = ACPI_CSTATE_HALT; snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index f36e28a..f88fa05 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -764,6 +764,7 @@ prefetchw (const void *x) extern unsigned long boot_option_idle_override; extern unsigned long idle_halt; +extern unsigned long idle_nomwait; #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index bc22162..55402d2 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -728,6 +728,7 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); extern unsigned long boot_option_idle_override; extern unsigned long idle_halt; +extern unsigned long idle_nomwait; extern void enable_sep_cpu(void); extern int sysenter_setup(void); -- cgit v0.10.2 From 2a2a64714d9c40f7705c4de1e79a5b855c7211a9 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 24 Jun 2008 18:02:57 +0800 Subject: ACPI: Disable MWAIT via DMI on broken Compal board If a system matches in this DMI table, Linux will disable MWAIT support for idle. ie. "idle=nomwait" is automatically invoked and C1_FFH and C2C3_FFH access mode are disabled. http://bugzilla.kernel.org/show_bug.cgi?id=10807 http://bugzilla.kernel.org/show_bug.cgi?id=10914 Signed-off-by: Zhao Yakui Signed-off-by: Li Shaohua Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 4e1bb89..ec0f2d5 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -120,6 +120,29 @@ static const struct file_operations acpi_processor_info_fops = { DEFINE_PER_CPU(struct acpi_processor *, processors); struct acpi_processor_errata errata __read_mostly; +static int set_no_mwait(const struct dmi_system_id *id) +{ + printk(KERN_NOTICE PREFIX "%s detected - " + "disable mwait for CPU C-stetes\n", id->ident); + idle_nomwait = 1; + return 0; +} + +static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { + { + set_no_mwait, "IFL91 board", { + DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), + DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), + DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, + { + set_no_mwait, "Extensa 5220", { + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "ACER"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, + {}, +}; /* -------------------------------------------------------------------------- Errata Handling @@ -1100,6 +1123,11 @@ static int __init acpi_processor_init(void) return -ENOMEM; acpi_processor_dir->owner = THIS_MODULE; + /* + * Check whether the system is DMI table. If yes, OSPM + * should not use mwait for CPU-states. + */ + dmi_check_system(processor_idle_dmi_table); result = cpuidle_register_driver(&acpi_idle_driver); if (result < 0) goto out_proc; -- cgit v0.10.2 From 65573ee72e34e767a135a0841ac5380a2be1a390 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 27 Jun 2008 11:22:46 -0400 Subject: ACPI: Zhang Rui maintains ACPI THERMAL and FAN Reflect that Zhang-Rui has been the sub-maintainer for ACPI THERMAL and FAN for some time now. Also, the Chinese custom is to speak family name first, so rather than "Rui Zhang", write "Zhang Rui", as he does on e-mail. Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/MAINTAINERS b/MAINTAINERS index ec5c8ee..4e49e9c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -239,8 +239,8 @@ W: http://www.lesswatts.org/projects/acpi/ S: Supported ACPI FAN DRIVER -P: Len Brown -M: len.brown@intel.com +P: Zhang Rui +M: rui.zhang@intel.com L: linux-acpi@vger.kernel.org W: http://www.lesswatts.org/projects/acpi/ S: Supported @@ -252,14 +252,14 @@ L: pcihpd-discuss@lists.sourceforge.net S: Supported ACPI THERMAL DRIVER -P: Len Brown -M: len.brown@intel.com +P: Zhang Rui +M: rui.zhang@intel.com L: linux-acpi@vger.kernel.org W: http://www.lesswatts.org/projects/acpi/ S: Supported ACPI VIDEO DRIVER -P: Rui Zhang +P: Zhang Rui M: rui.zhang@intel.com L: linux-acpi@vger.kernel.org W: http://www.lesswatts.org/projects/acpi/ -- cgit v0.10.2 From 8aa863b8ca0855378e3409b5e55ad57a856f6412 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 27 Jun 2008 11:31:50 -0400 Subject: ACPI: Andi Kleen maintains the ACPI sub-system ...while Len is on sabbatical from Intel Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/MAINTAINERS b/MAINTAINERS index 4e49e9c..633bda6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -216,8 +216,8 @@ W: http://code.google.com/p/aceracpi S: Maintained ACPI -P: Len Brown -M: len.brown@intel.com +P: Andi Kleen +M: ak@linux.intel.com M: lenb@kernel.org L: linux-acpi@vger.kernel.org W: http://www.lesswatts.org/projects/acpi/ -- cgit v0.10.2 From 469778c1740fcf3113498b6fdf4559bdec25c58f Mon Sep 17 00:00:00 2001 From: Julia Jomantaite Date: Mon, 23 Jun 2008 22:50:42 +0100 Subject: ACPI: video: fix brightness allocation Fix use of uninitialized device->brightness. Signed-off-by: Julia Jomantaite Signed-off-by: Andi Kleen Acked-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d089c45..64c8893 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -631,6 +631,76 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) * device : video output device (LCD, CRT, ..) * * Return Value: + * Maximum brightness level + * + * Allocate and initialize device->brightness. + */ + +static int +acpi_video_init_brightness(struct acpi_video_device *device) +{ + union acpi_object *obj = NULL; + int i, max_level = 0, count = 0; + union acpi_object *o; + struct acpi_video_device_brightness *br = NULL; + + if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " + "LCD brightness level\n")); + goto out; + } + + if (obj->package.count < 2) + goto out; + + br = kzalloc(sizeof(*br), GFP_KERNEL); + if (!br) { + printk(KERN_ERR "can't allocate memory\n"); + goto out; + } + + br->levels = kmalloc(obj->package.count * sizeof *(br->levels), + GFP_KERNEL); + if (!br->levels) + goto out_free; + + for (i = 0; i < obj->package.count; i++) { + o = (union acpi_object *)&obj->package.elements[i]; + if (o->type != ACPI_TYPE_INTEGER) { + printk(KERN_ERR PREFIX "Invalid data\n"); + continue; + } + br->levels[count] = (u32) o->integer.value; + + if (br->levels[count] > max_level) + max_level = br->levels[count]; + count++; + } + + if (count < 2) + goto out_free_levels; + + br->count = count; + device->brightness = br; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); + kfree(obj); + return max_level; + +out_free_levels: + kfree(br->levels); +out_free: + kfree(br); +out: + device->brightness = NULL; + kfree(obj); + return 0; +} + +/* + * Arg: + * device : video output device (LCD, CRT, ..) + * + * Return Value: * None * * Find out all required AML methods defined under the output @@ -640,10 +710,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) static void acpi_video_device_find_cap(struct acpi_video_device *device) { acpi_handle h_dummy1; - int i; u32 max_level = 0; - union acpi_object *obj = NULL; - struct acpi_video_device_brightness *br = NULL; memset(&device->cap, 0, sizeof(device->cap)); @@ -672,53 +739,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->cap._DSS = 1; } - if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { - - if (obj->package.count >= 2) { - int count = 0; - union acpi_object *o; - - br = kzalloc(sizeof(*br), GFP_KERNEL); - if (!br) { - printk(KERN_ERR "can't allocate memory\n"); - } else { - br->levels = kmalloc(obj->package.count * - sizeof *(br->levels), GFP_KERNEL); - if (!br->levels) - goto out; - - for (i = 0; i < obj->package.count; i++) { - o = (union acpi_object *)&obj->package. - elements[i]; - if (o->type != ACPI_TYPE_INTEGER) { - printk(KERN_ERR PREFIX "Invalid data\n"); - continue; - } - br->levels[count] = (u32) o->integer.value; - - if (br->levels[count] > max_level) - max_level = br->levels[count]; - count++; - } - out: - if (count < 2) { - kfree(br->levels); - kfree(br); - } else { - br->count = count; - device->brightness = br; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "found %d brightness levels\n", - count)); - } - } - } - - } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n")); - } - - kfree(obj); + max_level = acpi_video_init_brightness(device); if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ int result; @@ -1695,6 +1716,8 @@ static void acpi_video_switch_brightness(struct acpi_video_device *device, int event) { unsigned long level_current, level_next; + if (!device->brightness) + return; acpi_video_device_lcd_get_level_current(device, &level_current); level_next = acpi_video_get_next_level(device, level_current, event); acpi_video_device_lcd_set_level(device, level_next); -- cgit v0.10.2 From b897f46cf7941fff8130ccdaf85f39528bff6a51 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:52 -0600 Subject: PNP: add detail to debug resource dump In the debug resource dump, decode the flags and indicate when a resource is disabled or has been automatically assigned. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 95b076c..7f594cc 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -63,28 +63,46 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) for (i = 0; i < PNP_MAX_IRQ; i++) { res = pnp_get_resource(dev, IORESOURCE_IRQ, i); if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " irq %lld flags %#lx\n", - (unsigned long long) res->start, res->flags); + dev_dbg(&dev->dev, " irq %lld flags %#lx%s%s\n", + (unsigned long long) res->start, res->flags, + res->flags & IORESOURCE_DISABLED ? + " DISABLED" : "", + res->flags & IORESOURCE_AUTO ? + " AUTO" : ""); } for (i = 0; i < PNP_MAX_DMA; i++) { res = pnp_get_resource(dev, IORESOURCE_DMA, i); if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " dma %lld flags %#lx\n", - (unsigned long long) res->start, res->flags); + dev_dbg(&dev->dev, " dma %lld flags %#lx%s%s\n", + (unsigned long long) res->start, res->flags, + res->flags & IORESOURCE_DISABLED ? + " DISABLED" : "", + res->flags & IORESOURCE_AUTO ? + " AUTO" : ""); } for (i = 0; i < PNP_MAX_PORT; i++) { res = pnp_get_resource(dev, IORESOURCE_IO, i); if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n", + dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx" + "%s%s\n", (unsigned long long) res->start, - (unsigned long long) res->end, res->flags); + (unsigned long long) res->end, res->flags, + res->flags & IORESOURCE_DISABLED ? + " DISABLED" : "", + res->flags & IORESOURCE_AUTO ? + " AUTO" : ""); } for (i = 0; i < PNP_MAX_MEM; i++) { res = pnp_get_resource(dev, IORESOURCE_MEM, i); if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n", + dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx" + "%s%s\n", (unsigned long long) res->start, - (unsigned long long) res->end, res->flags); + (unsigned long long) res->end, res->flags, + res->flags & IORESOURCE_DISABLED ? + " DISABLED" : "", + res->flags & IORESOURCE_AUTO ? + " AUTO" : ""); } #endif } -- cgit v0.10.2 From 87e4acf3ebc02c9d0a2f7a37b655c49176c4d765 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:53 -0600 Subject: PNP: remove pnp_resource.index We used pnp_resource.index to keep track of which ISAPNP configuration register a resource should be written to. We needed this only to handle the case where a register is disabled but a subsequent register in the same set is enabled. Rather than explicitly maintaining the pnp_resource.index, this patch adds a resource every time we read an ISAPNP configuration register and marks the resource as IORESOURCE_DISABLED when appropriate. This makes the position in the pnp_resource_table always correspond to the config register index. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 886dac8..6f60097 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -57,7 +57,6 @@ struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, struct pnp_resource { struct resource res; - unsigned int index; /* ISAPNP config register index */ }; struct pnp_resource_table { diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 5695a79..3f8007a 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -320,7 +320,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, const char *ubuf, size_t count) { struct pnp_dev *dev = to_pnp_dev(dmdev); - struct pnp_resource *pnp_res; char *buf = (void *)ubuf; int retval = 0; resource_size_t start, end; @@ -368,7 +367,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, goto done; } if (!strnicmp(buf, "set", 3)) { - int nport = 0, nmem = 0, nirq = 0, ndma = 0; if (dev->active) goto done; buf += 3; @@ -391,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, end = simple_strtoul(buf, &buf, 0); } else end = start; - pnp_res = pnp_add_io_resource(dev, start, end, - 0); - if (pnp_res) - pnp_res->index = nport++; + pnp_add_io_resource(dev, start, end, 0); continue; } if (!strnicmp(buf, "mem", 3)) { @@ -411,10 +406,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, end = simple_strtoul(buf, &buf, 0); } else end = start; - pnp_res = pnp_add_mem_resource(dev, start, end, - 0); - if (pnp_res) - pnp_res->index = nmem++; + pnp_add_mem_resource(dev, start, end, 0); continue; } if (!strnicmp(buf, "irq", 3)) { @@ -422,9 +414,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, while (isspace(*buf)) ++buf; start = simple_strtoul(buf, &buf, 0); - pnp_res = pnp_add_irq_resource(dev, start, 0); - if (pnp_res) - pnp_res->index = nirq++; + pnp_add_irq_resource(dev, start, 0); continue; } if (!strnicmp(buf, "dma", 3)) { @@ -432,9 +422,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, while (isspace(*buf)) ++buf; start = simple_strtoul(buf, &buf, 0); - pnp_res = pnp_add_dma_resource(dev, start, 0); - if (pnp_res) - pnp_res->index = ndma++; + pnp_add_dma_resource(dev, start, 0); continue; } break; diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index f1bccdb..752b51f 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -928,7 +928,6 @@ EXPORT_SYMBOL(isapnp_write_byte); static int isapnp_get_resources(struct pnp_dev *dev) { - struct pnp_resource *pnp_res; int i, ret; dev_dbg(&dev->dev, "get resources\n"); @@ -940,35 +939,23 @@ static int isapnp_get_resources(struct pnp_dev *dev) for (i = 0; i < ISAPNP_MAX_PORT; i++) { ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); - if (ret) { - pnp_res = pnp_add_io_resource(dev, ret, ret, 0); - if (pnp_res) - pnp_res->index = i; - } + pnp_add_io_resource(dev, ret, ret, + ret == 0 ? IORESOURCE_DISABLED : 0); } for (i = 0; i < ISAPNP_MAX_MEM; i++) { ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8; - if (ret) { - pnp_res = pnp_add_mem_resource(dev, ret, ret, 0); - if (pnp_res) - pnp_res->index = i; - } + pnp_add_mem_resource(dev, ret, ret, + ret == 0 ? IORESOURCE_DISABLED : 0); } for (i = 0; i < ISAPNP_MAX_IRQ; i++) { ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8; - if (ret) { - pnp_res = pnp_add_irq_resource(dev, ret, 0); - if (pnp_res) - pnp_res->index = i; - } + pnp_add_irq_resource(dev, ret, + ret == 0 ? IORESOURCE_DISABLED : 0); } for (i = 0; i < ISAPNP_MAX_DMA; i++) { ret = isapnp_read_byte(ISAPNP_CFG_DMA + i); - if (ret != 4) { - pnp_res = pnp_add_dma_resource(dev, ret, 0); - if (pnp_res) - pnp_res->index = i; - } + pnp_add_dma_resource(dev, ret, + ret == 4 ? IORESOURCE_DISABLED : 0); } __end: @@ -978,62 +965,49 @@ __end: static int isapnp_set_resources(struct pnp_dev *dev) { - struct pnp_resource *pnp_res; struct resource *res; - int tmp, index; + int tmp; dev_dbg(&dev->dev, "set resources\n"); isapnp_cfg_begin(dev->card->number, dev->number); dev->active = 1; for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp); - if (!pnp_res) - continue; - res = &pnp_res->res; - if (pnp_resource_valid(res)) { - index = pnp_res->index; + res = pnp_get_resource(dev, IORESOURCE_IO, tmp); + if (res && pnp_resource_valid(res) && + !(res->flags & IORESOURCE_DISABLED)) { dev_dbg(&dev->dev, " set io %d to %#llx\n", - index, (unsigned long long) res->start); - isapnp_write_word(ISAPNP_CFG_PORT + (index << 1), + tmp, (unsigned long long) res->start); + isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), res->start); } } for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp); - if (!pnp_res) - continue; - res = &pnp_res->res; - if (pnp_resource_valid(res)) { + res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp); + if (res && pnp_resource_valid(res) && + !(res->flags & IORESOURCE_DISABLED)) { int irq = res->start; if (irq == 2) irq = 9; - index = pnp_res->index; - dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq); - isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq); + dev_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq); + isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); } } for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp); - if (!pnp_res) - continue; - res = &pnp_res->res; - if (pnp_resource_valid(res)) { - index = pnp_res->index; + res = pnp_get_resource(dev, IORESOURCE_DMA, tmp); + if (res && pnp_resource_valid(res) && + !(res->flags & IORESOURCE_DISABLED)) { dev_dbg(&dev->dev, " set dma %d to %lld\n", - index, (unsigned long long) res->start); - isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start); + tmp, (unsigned long long) res->start); + isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start); } } for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp); - if (!pnp_res) - continue; - res = &pnp_res->res; - if (pnp_resource_valid(res)) { - index = pnp_res->index; + res = pnp_get_resource(dev, IORESOURCE_MEM, tmp); + if (res && pnp_resource_valid(res) && + !(res->flags & IORESOURCE_DISABLED)) { dev_dbg(&dev->dev, " set mem %d to %#llx\n", - index, (unsigned long long) res->start); - isapnp_write_word(ISAPNP_CFG_MEM + (index << 3), + tmp, (unsigned long long) res->start); + isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3), (res->start >> 8) & 0xffff); } } diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index bea0914..90bd9cb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -40,7 +40,6 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) } /* set the initial values */ - pnp_res->index = idx; res->flags |= rule->flags | IORESOURCE_IO; res->flags &= ~IORESOURCE_UNSET; @@ -90,7 +89,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) } /* set the initial values */ - pnp_res->index = idx; res->flags |= rule->flags | IORESOURCE_MEM; res->flags &= ~IORESOURCE_UNSET; @@ -155,7 +153,6 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) } /* set the initial values */ - pnp_res->index = idx; res->flags |= rule->flags | IORESOURCE_IRQ; res->flags &= ~IORESOURCE_UNSET; @@ -214,7 +211,6 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) } /* set the initial values */ - pnp_res->index = idx; res->flags |= rule->flags | IORESOURCE_DMA; res->flags &= ~IORESOURCE_UNSET; -- cgit v0.10.2 From 940e98dbc616f1df7b63b73858a966969baf261d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:54 -0600 Subject: PNP: add pnp_resource_type() internal interface Given a struct resource, this returns the type (IO, MEM, IRQ, DMA). Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 6f60097..4c2a625 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -46,6 +46,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res); void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); void pnp_init_resource(struct resource *res); +int pnp_resource_type(struct resource *res); struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, unsigned int type, unsigned int num); diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 390b500..cce341f 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -499,6 +499,12 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) #endif } +int pnp_resource_type(struct resource *res) +{ + return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | + IORESOURCE_IRQ | IORESOURCE_DMA); +} + struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, unsigned int type, unsigned int num) { -- cgit v0.10.2 From 9fdee4e02e3b214cde8e4f3beb6776075a3d08a7 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:55 -0600 Subject: PNP: add pnp_resource_type_name() helper function This patch adds a "pnp_resource_type_name(struct resource *)" that returns the string resource type. This will be used by the sysfs "show resources" function and the debug resource dump function. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 4c2a625..c913158 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -43,6 +43,7 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res); int pnp_check_irq(struct pnp_dev *dev, struct resource *res); int pnp_check_dma(struct pnp_dev *dev, struct resource *res); +char *pnp_resource_type_name(struct resource *res); void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); void pnp_init_resource(struct resource *res); diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 7f594cc..eb07345 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -52,6 +52,21 @@ void pnp_eisa_id_to_string(u32 id, char *str) str[7] = '\0'; } +char *pnp_resource_type_name(struct resource *res) +{ + switch (pnp_resource_type(res)) { + case IORESOURCE_IO: + return "io"; + case IORESOURCE_MEM: + return "mem"; + case IORESOURCE_IRQ: + return "irq"; + case IORESOURCE_DMA: + return "dma"; + } + return NULL; +} + void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) { #ifdef DEBUG -- cgit v0.10.2 From 20bfdbba7212d19613b93dcea93f26cb65af91fe Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:56 -0600 Subject: PNP: make pnp_{port,mem,etc}_start(), et al work for invalid resources Some callers use pnp_port_start() and similar functions without making sure the resource is valid. This patch makes us fall back to returning the initial values if the resource is not valid or not even present. This mostly preserves the previous behavior, where we would just return the initial values set by pnp_init_resource_table(). The original 2.6.25 code didn't range-check the "bar", so it would return garbage if the bar exceeded the table size. This code returns sensible values instead. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 63b128d..8b607ae 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -40,19 +40,31 @@ static inline resource_size_t pnp_resource_len(struct resource *res) static inline resource_size_t pnp_port_start(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_IO, bar)->start; + struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar); + + if (pnp_resource_valid(res)) + return res->start; + return 0; } static inline resource_size_t pnp_port_end(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_IO, bar)->end; + struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar); + + if (pnp_resource_valid(res)) + return res->end; + return 0; } static inline unsigned long pnp_port_flags(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_IO, bar)->flags; + struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar); + + if (pnp_resource_valid(res)) + return res->flags; + return IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; } static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) @@ -63,25 +75,41 @@ static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) static inline resource_size_t pnp_port_len(struct pnp_dev *dev, unsigned int bar) { - return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_IO, bar)); + struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar); + + if (pnp_resource_valid(res)) + return pnp_resource_len(res); + return 0; } static inline resource_size_t pnp_mem_start(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_MEM, bar)->start; + struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar); + + if (pnp_resource_valid(res)) + return res->start; + return 0; } static inline resource_size_t pnp_mem_end(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_MEM, bar)->end; + struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar); + + if (pnp_resource_valid(res)) + return res->end; + return 0; } static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_MEM, bar)->flags; + struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar); + + if (pnp_resource_valid(res)) + return res->flags; + return IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; } static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) @@ -92,18 +120,30 @@ static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) static inline resource_size_t pnp_mem_len(struct pnp_dev *dev, unsigned int bar) { - return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_MEM, bar)); + struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar); + + if (pnp_resource_valid(res)) + return pnp_resource_len(res); + return 0; } static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->start; + struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar); + + if (pnp_resource_valid(res)) + return res->start; + return -1; } static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->flags; + struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar); + + if (pnp_resource_valid(res)) + return res->flags; + return IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; } static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) @@ -114,12 +154,20 @@ static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_DMA, bar)->start; + struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar); + + if (pnp_resource_valid(res)) + return res->start; + return -1; } static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar) { - return pnp_get_resource(dev, IORESOURCE_DMA, bar)->flags; + struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar); + + if (pnp_resource_valid(res)) + return res->flags; + return IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; } static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) -- cgit v0.10.2 From aee3ad815dd291a7193ab01da0f1a30c84d00061 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:57 -0600 Subject: PNP: replace pnp_resource_table with dynamically allocated resources PNP used to have a fixed-size pnp_resource_table for tracking the resources used by a device. This table often overflowed, so we've had to increase the table size, which wastes memory because most devices have very few resources. This patch replaces the table with a linked list of resources where the entries are allocated on demand. This removes messages like these: pnpacpi: exceeded the max number of IO resources 00:01: too many I/O port resources References: http://bugzilla.kernel.org/show_bug.cgi?id=9535 http://bugzilla.kernel.org/show_bug.cgi?id=9740 http://lkml.org/lkml/2007/11/30/110 This patch also changes the way PNP uses the IORESOURCE_UNSET, IORESOURCE_AUTO, and IORESOURCE_DISABLED flags. Prior to this patch, the pnp_resource_table entries used the flags like this: IORESOURCE_UNSET This table entry is unused and available for use. When this flag is set, we shouldn't look at anything else in the resource structure. This flag is set when a resource table entry is initialized. IORESOURCE_AUTO This resource was assigned automatically by pnp_assign_{io,mem,etc}(). This flag is set when a resource table entry is initialized and cleared whenever we discover a resource setting by reading an ISAPNP config register, parsing a PNPBIOS resource data stream, parsing an ACPI _CRS list, or interpreting a sysfs "set" command. Resources marked IORESOURCE_AUTO are reinitialized and marked as IORESOURCE_UNSET by pnp_clean_resource_table() in these cases: - before we attempt to assign resources automatically, - if we fail to assign resources automatically, - after disabling a device IORESOURCE_DISABLED Set by pnp_assign_{io,mem,etc}() when automatic assignment fails. Also set by PNPBIOS and PNPACPI for: - invalid IRQs or GSI registration failures - invalid DMA channels - I/O ports above 0x10000 - mem ranges with negative length After this patch, there is no pnp_resource_table, and the resource list entries use the flags like this: IORESOURCE_UNSET This flag is no longer used in PNP. Instead of keeping IORESOURCE_UNSET entries in the resource list, we remove entries from the list and free them. IORESOURCE_AUTO No change in meaning: it still means the resource was assigned automatically by pnp_assign_{port,mem,etc}(), but these functions now set the bit explicitly. We still "clean" a device's resource list in the same places, but rather than reinitializing IORESOURCE_AUTO entries, we just remove them from the list. Note that IORESOURCE_AUTO entries are always at the end of the list, so removing them doesn't reorder other list entries. This is because non-IORESOURCE_AUTO entries are added by the ISAPNP, PNPBIOS, or PNPACPI "get resources" methods and by the sysfs "set" command. In each of these cases, we completely free the resource list first. IORESOURCE_DISABLED In addition to the cases where we used to set this flag, ISAPNP now adds an IORESOURCE_DISABLED resource when it reads a configuration register with a "disabled" value. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index c913158..1667ac3 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -46,27 +46,15 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res); char *pnp_resource_type_name(struct resource *res); void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); -void pnp_init_resource(struct resource *res); +void pnp_free_resources(struct pnp_dev *dev); int pnp_resource_type(struct resource *res); -struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, - unsigned int type, unsigned int num); - -#define PNP_MAX_PORT 40 -#define PNP_MAX_MEM 24 -#define PNP_MAX_IRQ 2 -#define PNP_MAX_DMA 2 - struct pnp_resource { + struct list_head list; struct resource res; }; -struct pnp_resource_table { - struct pnp_resource port[PNP_MAX_PORT]; - struct pnp_resource mem[PNP_MAX_MEM]; - struct pnp_resource dma[PNP_MAX_DMA]; - struct pnp_resource irq[PNP_MAX_IRQ]; -}; +void pnp_free_resource(struct pnp_resource *pnp_res); struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, int flags); diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 20771b7..7182da9 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -99,6 +99,21 @@ static void pnp_free_ids(struct pnp_dev *dev) } } +void pnp_free_resource(struct pnp_resource *pnp_res) +{ + list_del(&pnp_res->list); + kfree(pnp_res); +} + +void pnp_free_resources(struct pnp_dev *dev) +{ + struct pnp_resource *pnp_res, *tmp; + + list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) { + pnp_free_resource(pnp_res); + } +} + static void pnp_release_device(struct device *dmdev) { struct pnp_dev *dev = to_pnp_dev(dmdev); @@ -106,7 +121,7 @@ static void pnp_release_device(struct device *dmdev) pnp_free_option(dev->independent); pnp_free_option(dev->dependent); pnp_free_ids(dev); - kfree(dev->res); + pnp_free_resources(dev); kfree(dev); } @@ -119,12 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid if (!dev) return NULL; - dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); - if (!dev->res) { - kfree(dev); - return NULL; - } - + INIT_LIST_HEAD(&dev->resources); dev->protocol = protocol; dev->number = id; dev->dma_mask = DMA_24BIT_MASK; @@ -140,7 +150,6 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid dev_id = pnp_add_id(dev, pnpid); if (!dev_id) { - kfree(dev->res); kfree(dev); return NULL; } diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 3f8007a..7fc86bb 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -269,46 +269,38 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, pnp_printf(buffer, "disabled\n"); for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { - if (pnp_resource_valid(res)) { - pnp_printf(buffer, "io"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " 0x%llx-0x%llx\n", - (unsigned long long) res->start, - (unsigned long long) res->end); - } + pnp_printf(buffer, "io"); + if (res->flags & IORESOURCE_DISABLED) + pnp_printf(buffer, " disabled\n"); + else + pnp_printf(buffer, " 0x%llx-0x%llx\n", + (unsigned long long) res->start, + (unsigned long long) res->end); } for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { - if (pnp_resource_valid(res)) { - pnp_printf(buffer, "mem"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " 0x%llx-0x%llx\n", - (unsigned long long) res->start, - (unsigned long long) res->end); - } + pnp_printf(buffer, "mem"); + if (res->flags & IORESOURCE_DISABLED) + pnp_printf(buffer, " disabled\n"); + else + pnp_printf(buffer, " 0x%llx-0x%llx\n", + (unsigned long long) res->start, + (unsigned long long) res->end); } for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { - if (pnp_resource_valid(res)) { - pnp_printf(buffer, "irq"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " %lld\n", - (unsigned long long) res->start); - } + pnp_printf(buffer, "irq"); + if (res->flags & IORESOURCE_DISABLED) + pnp_printf(buffer, " disabled\n"); + else + pnp_printf(buffer, " %lld\n", + (unsigned long long) res->start); } for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { - if (pnp_resource_valid(res)) { - pnp_printf(buffer, "dma"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " %lld\n", - (unsigned long long) res->start); - } + pnp_printf(buffer, "dma"); + if (res->flags & IORESOURCE_DISABLED) + pnp_printf(buffer, " disabled\n"); + else + pnp_printf(buffer, " %lld\n", + (unsigned long long) res->start); } ret = (buffer->curr - buf); kfree(buffer); diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 752b51f..ca4457e 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -973,8 +973,7 @@ static int isapnp_set_resources(struct pnp_dev *dev) dev->active = 1; for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { res = pnp_get_resource(dev, IORESOURCE_IO, tmp); - if (res && pnp_resource_valid(res) && - !(res->flags & IORESOURCE_DISABLED)) { + if (pnp_resource_enabled(res)) { dev_dbg(&dev->dev, " set io %d to %#llx\n", tmp, (unsigned long long) res->start); isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), @@ -983,8 +982,7 @@ static int isapnp_set_resources(struct pnp_dev *dev) } for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp); - if (res && pnp_resource_valid(res) && - !(res->flags & IORESOURCE_DISABLED)) { + if (pnp_resource_enabled(res)) { int irq = res->start; if (irq == 2) irq = 9; @@ -994,8 +992,7 @@ static int isapnp_set_resources(struct pnp_dev *dev) } for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { res = pnp_get_resource(dev, IORESOURCE_DMA, tmp); - if (res && pnp_resource_valid(res) && - !(res->flags & IORESOURCE_DISABLED)) { + if (pnp_resource_enabled(res)) { dev_dbg(&dev->dev, " set dma %d to %lld\n", tmp, (unsigned long long) res->start); isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start); @@ -1003,8 +1000,7 @@ static int isapnp_set_resources(struct pnp_dev *dev) } for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { res = pnp_get_resource(dev, IORESOURCE_MEM, tmp); - if (res && pnp_resource_valid(res) && - !(res->flags & IORESOURCE_DISABLED)) { + if (pnp_resource_enabled(res)) { dev_dbg(&dev->dev, " set mem %d to %#llx\n", tmp, (unsigned long long) res->start); isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3), diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 90bd9cb..165b624 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -19,40 +19,30 @@ DEFINE_MUTEX(pnp_res_mutex); static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) { - struct pnp_resource *pnp_res; - struct resource *res; + struct resource *res, local_res; - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx); - if (!pnp_res) { - dev_err(&dev->dev, "too many I/O port resources\n"); - /* pretend we were successful so at least the manager won't try again */ - return 1; - } - - res = &pnp_res->res; - - /* check if this resource has been manually set, if so skip */ - if (!(res->flags & IORESOURCE_AUTO)) { + res = pnp_get_resource(dev, IORESOURCE_IO, idx); + if (res) { dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " "flags %#lx\n", idx, (unsigned long long) res->start, (unsigned long long) res->end, res->flags); return 1; } - /* set the initial values */ - res->flags |= rule->flags | IORESOURCE_IO; - res->flags &= ~IORESOURCE_UNSET; + res = &local_res; + res->flags = rule->flags | IORESOURCE_AUTO; + res->start = 0; + res->end = 0; if (!rule->size) { res->flags |= IORESOURCE_DISABLED; dev_dbg(&dev->dev, " io %d disabled\n", idx); - return 1; /* skip disabled resource requests */ + goto __add; } res->start = rule->min; res->end = res->start + rule->size - 1; - /* run through until pnp_check_port is happy */ while (!pnp_check_port(dev, res)) { res->start += rule->align; res->end = res->start + rule->size - 1; @@ -61,38 +51,29 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) return 0; } } - dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx, - (unsigned long long) res->start, (unsigned long long) res->end); + +__add: + pnp_add_io_resource(dev, res->start, res->end, res->flags); return 1; } static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) { - struct pnp_resource *pnp_res; - struct resource *res; + struct resource *res, local_res; - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx); - if (!pnp_res) { - dev_err(&dev->dev, "too many memory resources\n"); - /* pretend we were successful so at least the manager won't try again */ - return 1; - } - - res = &pnp_res->res; - - /* check if this resource has been manually set, if so skip */ - if (!(res->flags & IORESOURCE_AUTO)) { + res = pnp_get_resource(dev, IORESOURCE_MEM, idx); + if (res) { dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " "flags %#lx\n", idx, (unsigned long long) res->start, (unsigned long long) res->end, res->flags); return 1; } - /* set the initial values */ - res->flags |= rule->flags | IORESOURCE_MEM; - res->flags &= ~IORESOURCE_UNSET; + res = &local_res; + res->flags = rule->flags | IORESOURCE_AUTO; + res->start = 0; + res->end = 0; - /* convert pnp flags to standard Linux flags */ if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) res->flags |= IORESOURCE_READONLY; if (rule->flags & IORESOURCE_MEM_CACHEABLE) @@ -105,13 +86,12 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) if (!rule->size) { res->flags |= IORESOURCE_DISABLED; dev_dbg(&dev->dev, " mem %d disabled\n", idx); - return 1; /* skip disabled resource requests */ + goto __add; } res->start = rule->min; res->end = res->start + rule->size - 1; - /* run through until pnp_check_mem is happy */ while (!pnp_check_mem(dev, res)) { res->start += rule->align; res->end = res->start + rule->size - 1; @@ -120,15 +100,15 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) return 0; } } - dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx, - (unsigned long long) res->start, (unsigned long long) res->end); + +__add: + pnp_add_mem_resource(dev, res->start, res->end, res->flags); return 1; } static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) { - struct pnp_resource *pnp_res; - struct resource *res; + struct resource *res, local_res; int i; /* IRQ priority: this table is good for i386 */ @@ -136,58 +116,48 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 }; - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx); - if (!pnp_res) { - dev_err(&dev->dev, "too many IRQ resources\n"); - /* pretend we were successful so at least the manager won't try again */ - return 1; - } - - res = &pnp_res->res; - - /* check if this resource has been manually set, if so skip */ - if (!(res->flags & IORESOURCE_AUTO)) { + res = pnp_get_resource(dev, IORESOURCE_IRQ, idx); + if (res) { dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", idx, (int) res->start, res->flags); return 1; } - /* set the initial values */ - res->flags |= rule->flags | IORESOURCE_IRQ; - res->flags &= ~IORESOURCE_UNSET; + res = &local_res; + res->flags = rule->flags | IORESOURCE_AUTO; + res->start = -1; + res->end = -1; if (bitmap_empty(rule->map, PNP_IRQ_NR)) { res->flags |= IORESOURCE_DISABLED; dev_dbg(&dev->dev, " irq %d disabled\n", idx); - return 1; /* skip disabled resource requests */ + goto __add; } /* TBD: need check for >16 IRQ */ res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16); if (res->start < PNP_IRQ_NR) { res->end = res->start; - dev_dbg(&dev->dev, " assign irq %d %d\n", idx, - (int) res->start); - return 1; + goto __add; } for (i = 0; i < 16; i++) { if (test_bit(xtab[i], rule->map)) { res->start = res->end = xtab[i]; - if (pnp_check_irq(dev, res)) { - dev_dbg(&dev->dev, " assign irq %d %d\n", idx, - (int) res->start); - return 1; - } + if (pnp_check_irq(dev, res)) + goto __add; } } dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); return 0; + +__add: + pnp_add_irq_resource(dev, res->start, res->flags); + return 1; } static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { - struct pnp_resource *pnp_res; - struct resource *res; + struct resource *res, local_res; int i; /* DMA priority: this table is good for i386 */ @@ -195,127 +165,47 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 1, 3, 5, 6, 7, 0, 2, 4 }; - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx); - if (!pnp_res) { - dev_err(&dev->dev, "too many DMA resources\n"); - return; - } - - res = &pnp_res->res; - - /* check if this resource has been manually set, if so skip */ - if (!(res->flags & IORESOURCE_AUTO)) { + res = pnp_get_resource(dev, IORESOURCE_DMA, idx); + if (res) { dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", idx, (int) res->start, res->flags); return; } - /* set the initial values */ - res->flags |= rule->flags | IORESOURCE_DMA; - res->flags &= ~IORESOURCE_UNSET; + res = &local_res; + res->flags = rule->flags | IORESOURCE_AUTO; + res->start = -1; + res->end = -1; for (i = 0; i < 8; i++) { if (rule->map & (1 << xtab[i])) { res->start = res->end = xtab[i]; - if (pnp_check_dma(dev, res)) { - dev_dbg(&dev->dev, " assign dma %d %d\n", idx, - (int) res->start); - return; - } + if (pnp_check_dma(dev, res)) + goto __add; } } #ifdef MAX_DMA_CHANNELS res->start = res->end = MAX_DMA_CHANNELS; #endif - res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; + res->flags |= IORESOURCE_DISABLED; dev_dbg(&dev->dev, " disable dma %d\n", idx); -} -void pnp_init_resource(struct resource *res) -{ - unsigned long type; - - type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM | - IORESOURCE_IRQ | IORESOURCE_DMA); - - res->name = NULL; - res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET; - if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) { - res->start = -1; - res->end = -1; - } else { - res->start = 0; - res->end = 0; - } +__add: + pnp_add_dma_resource(dev, res->start, res->flags); } -/** - * pnp_init_resources - Resets a resource table to default values. - * @table: pointer to the desired resource table - */ void pnp_init_resources(struct pnp_dev *dev) { - struct resource *res; - int idx; - - for (idx = 0; idx < PNP_MAX_IRQ; idx++) { - res = &dev->res->irq[idx].res; - res->flags = IORESOURCE_IRQ; - pnp_init_resource(res); - } - for (idx = 0; idx < PNP_MAX_DMA; idx++) { - res = &dev->res->dma[idx].res; - res->flags = IORESOURCE_DMA; - pnp_init_resource(res); - } - for (idx = 0; idx < PNP_MAX_PORT; idx++) { - res = &dev->res->port[idx].res; - res->flags = IORESOURCE_IO; - pnp_init_resource(res); - } - for (idx = 0; idx < PNP_MAX_MEM; idx++) { - res = &dev->res->mem[idx].res; - res->flags = IORESOURCE_MEM; - pnp_init_resource(res); - } + pnp_free_resources(dev); } -/** - * pnp_clean_resources - clears resources that were not manually set - * @res: the resources to clean - */ static void pnp_clean_resource_table(struct pnp_dev *dev) { - struct resource *res; - int idx; - - for (idx = 0; idx < PNP_MAX_IRQ; idx++) { - res = &dev->res->irq[idx].res; - if (res->flags & IORESOURCE_AUTO) { - res->flags = IORESOURCE_IRQ; - pnp_init_resource(res); - } - } - for (idx = 0; idx < PNP_MAX_DMA; idx++) { - res = &dev->res->dma[idx].res; - if (res->flags & IORESOURCE_AUTO) { - res->flags = IORESOURCE_DMA; - pnp_init_resource(res); - } - } - for (idx = 0; idx < PNP_MAX_PORT; idx++) { - res = &dev->res->port[idx].res; - if (res->flags & IORESOURCE_AUTO) { - res->flags = IORESOURCE_IO; - pnp_init_resource(res); - } - } - for (idx = 0; idx < PNP_MAX_MEM; idx++) { - res = &dev->res->mem[idx].res; - if (res->flags & IORESOURCE_AUTO) { - res->flags = IORESOURCE_MEM; - pnp_init_resource(res); - } + struct pnp_resource *pnp_res, *tmp; + + list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) { + if (pnp_res->res.flags & IORESOURCE_AUTO) + pnp_free_resource(pnp_res); } } diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 46c791a..9a45c25 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -806,6 +806,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, struct acpi_resource_irq *irq = &resource->data.irq; int triggering, polarity, shareable; + if (!pnp_resource_enabled(p)) { + irq->interrupt_count = 0; + dev_dbg(&dev->dev, " encode irq (%s)\n", + p ? "disabled" : "missing"); + return; + } + decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); irq->triggering = triggering; irq->polarity = polarity; @@ -828,6 +835,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; int triggering, polarity, shareable; + if (!pnp_resource_enabled(p)) { + extended_irq->interrupt_count = 0; + dev_dbg(&dev->dev, " encode extended irq (%s)\n", + p ? "disabled" : "missing"); + return; + } + decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->triggering = triggering; @@ -848,6 +862,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev, { struct acpi_resource_dma *dma = &resource->data.dma; + if (!pnp_resource_enabled(p)) { + dma->channel_count = 0; + dev_dbg(&dev->dev, " encode dma (%s)\n", + p ? "disabled" : "missing"); + return; + } + /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { case IORESOURCE_DMA_TYPEA: @@ -889,17 +910,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev, { struct acpi_resource_io *io = &resource->data.io; - /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ - io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? - ACPI_DECODE_16 : ACPI_DECODE_10; - io->minimum = p->start; - io->maximum = p->end; - io->alignment = 0; /* Correct? */ - io->address_length = p->end - p->start + 1; - - dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n", - (unsigned long long) p->start, (unsigned long long) p->end, - io->io_decode); + if (pnp_resource_enabled(p)) { + /* Note: pnp_assign_port copies pnp_port->flags into p->flags */ + io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? + ACPI_DECODE_16 : ACPI_DECODE_10; + io->minimum = p->start; + io->maximum = p->end; + io->alignment = 0; /* Correct? */ + io->address_length = p->end - p->start + 1; + } else { + io->minimum = 0; + io->address_length = 0; + } + + dev_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum, + io->minimum + io->address_length - 1, io->io_decode); } static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, @@ -908,11 +933,16 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, { struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io; - fixed_io->address = p->start; - fixed_io->address_length = p->end - p->start + 1; + if (pnp_resource_enabled(p)) { + fixed_io->address = p->start; + fixed_io->address_length = p->end - p->start + 1; + } else { + fixed_io->address = 0; + fixed_io->address_length = 0; + } - dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", - (unsigned long long) p->start, (unsigned long long) p->end); + dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address, + fixed_io->address + fixed_io->address_length - 1); } static void pnpacpi_encode_mem24(struct pnp_dev *dev, @@ -921,17 +951,22 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev, { struct acpi_resource_memory24 *memory24 = &resource->data.memory24; - /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ - memory24->write_protect = - (p->flags & IORESOURCE_MEM_WRITEABLE) ? - ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; - memory24->minimum = p->start; - memory24->maximum = p->end; - memory24->alignment = 0; - memory24->address_length = p->end - p->start + 1; - - dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n", - (unsigned long long) p->start, (unsigned long long) p->end, + if (pnp_resource_enabled(p)) { + /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */ + memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ? + ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; + memory24->minimum = p->start; + memory24->maximum = p->end; + memory24->alignment = 0; + memory24->address_length = p->end - p->start + 1; + } else { + memory24->minimum = 0; + memory24->address_length = 0; + } + + dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n", + memory24->minimum, + memory24->minimum + memory24->address_length - 1, memory24->write_protect); } @@ -941,16 +976,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev, { struct acpi_resource_memory32 *memory32 = &resource->data.memory32; - memory32->write_protect = - (p->flags & IORESOURCE_MEM_WRITEABLE) ? - ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; - memory32->minimum = p->start; - memory32->maximum = p->end; - memory32->alignment = 0; - memory32->address_length = p->end - p->start + 1; + if (pnp_resource_enabled(p)) { + memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ? + ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; + memory32->minimum = p->start; + memory32->maximum = p->end; + memory32->alignment = 0; + memory32->address_length = p->end - p->start + 1; + } else { + memory32->minimum = 0; + memory32->alignment = 0; + } - dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n", - (unsigned long long) p->start, (unsigned long long) p->end, + dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n", + memory32->minimum, + memory32->minimum + memory32->address_length - 1, memory32->write_protect); } @@ -960,15 +1000,20 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev, { struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32; - fixed_memory32->write_protect = - (p->flags & IORESOURCE_MEM_WRITEABLE) ? - ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; - fixed_memory32->address = p->start; - fixed_memory32->address_length = p->end - p->start + 1; + if (pnp_resource_enabled(p)) { + fixed_memory32->write_protect = + p->flags & IORESOURCE_MEM_WRITEABLE ? + ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; + fixed_memory32->address = p->start; + fixed_memory32->address_length = p->end - p->start + 1; + } else { + fixed_memory32->address = 0; + fixed_memory32->address_length = 0; + } - dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx " - "write_protect %#x\n", - (unsigned long long) p->start, (unsigned long long) p->end, + dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n", + fixed_memory32->address, + fixed_memory32->address + fixed_memory32->address_length - 1, fixed_memory32->write_protect); } diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 5ff9a4c..01f0c3d 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -526,8 +526,16 @@ len_err: static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, struct resource *res) { - unsigned long base = res->start; - unsigned long len = res->end - res->start + 1; + unsigned long base; + unsigned long len; + + if (pnp_resource_enabled(res)) { + base = res->start; + len = res->end - res->start + 1; + } else { + base = 0; + len = 0; + } p[4] = (base >> 8) & 0xff; p[5] = ((base >> 8) >> 8) & 0xff; @@ -536,15 +544,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, p[10] = (len >> 8) & 0xff; p[11] = ((len >> 8) >> 8) & 0xff; - dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n", - (unsigned long long) res->start, (unsigned long long) res->end); + dev_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1); } static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, struct resource *res) { - unsigned long base = res->start; - unsigned long len = res->end - res->start + 1; + unsigned long base; + unsigned long len; + + if (pnp_resource_enabled(res)) { + base = res->start; + len = res->end - res->start + 1; + } else { + base = 0; + len = 0; + } p[4] = base & 0xff; p[5] = (base >> 8) & 0xff; @@ -559,15 +574,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, p[18] = (len >> 16) & 0xff; p[19] = (len >> 24) & 0xff; - dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n", - (unsigned long long) res->start, (unsigned long long) res->end); + dev_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1); } static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, struct resource *res) { - unsigned long base = res->start; - unsigned long len = res->end - res->start + 1; + unsigned long base; + unsigned long len; + + if (pnp_resource_enabled(res)) { + base = res->start; + len = res->end - res->start + 1; + } else { + base = 0; + len = 0; + } p[4] = base & 0xff; p[5] = (base >> 8) & 0xff; @@ -578,40 +600,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, p[10] = (len >> 16) & 0xff; p[11] = (len >> 24) & 0xff; - dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n", - (unsigned long long) res->start, (unsigned long long) res->end); + dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base, + base + len - 1); } static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, struct resource *res) { - unsigned long map = 0; + unsigned long map; + + if (pnp_resource_enabled(res)) + map = 1 << res->start; + else + map = 0; - map = 1 << res->start; p[1] = map & 0xff; p[2] = (map >> 8) & 0xff; - dev_dbg(&dev->dev, " encode irq %llu\n", - (unsigned long long)res->start); + dev_dbg(&dev->dev, " encode irq mask %#lx\n", map); } static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, struct resource *res) { - unsigned long map = 0; + unsigned long map; + + if (pnp_resource_enabled(res)) + map = 1 << res->start; + else + map = 0; - map = 1 << res->start; p[1] = map & 0xff; - dev_dbg(&dev->dev, " encode dma %llu\n", - (unsigned long long)res->start); + dev_dbg(&dev->dev, " encode dma mask %#lx\n", map); } static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, struct resource *res) { - unsigned long base = res->start; - unsigned long len = res->end - res->start + 1; + unsigned long base; + unsigned long len; + + if (pnp_resource_enabled(res)) { + base = res->start; + len = res->end - res->start + 1; + } else { + base = 0; + len = 0; + } p[2] = base & 0xff; p[3] = (base >> 8) & 0xff; @@ -619,8 +655,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, p[5] = (base >> 8) & 0xff; p[7] = len & 0xff; - dev_dbg(&dev->dev, " encode io %#llx-%#llx\n", - (unsigned long long) res->start, (unsigned long long) res->end); + dev_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1); } static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, @@ -629,12 +664,20 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, unsigned long base = res->start; unsigned long len = res->end - res->start + 1; + if (pnp_resource_enabled(res)) { + base = res->start; + len = res->end - res->start + 1; + } else { + base = 0; + len = 0; + } + p[1] = base & 0xff; p[2] = (base >> 8) & 0xff; p[3] = len & 0xff; - dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", - (unsigned long long) res->start, (unsigned long long) res->end); + dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base, + base + len - 1); } static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 1ff3bb5..21acb54 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -248,8 +248,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) for (j = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, j)); j++) { - if (res->flags & IORESOURCE_UNSET || - (res->start == 0 && res->end == 0)) + if (res->start == 0 && res->end == 0) continue; pnp_start = res->start; diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index cce341f..0797a77 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -237,7 +237,7 @@ void pnp_free_option(struct pnp_option *option) !((*(enda) < *(startb)) || (*(endb) < *(starta))) #define cannot_compare(flags) \ -((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) +((flags) & IORESOURCE_DISABLED) int pnp_check_port(struct pnp_dev *dev, struct resource *res) { @@ -505,81 +505,31 @@ int pnp_resource_type(struct resource *res) IORESOURCE_IRQ | IORESOURCE_DMA); } -struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, - unsigned int type, unsigned int num) -{ - struct pnp_resource_table *res = dev->res; - - switch (type) { - case IORESOURCE_IO: - if (num >= PNP_MAX_PORT) - return NULL; - return &res->port[num]; - case IORESOURCE_MEM: - if (num >= PNP_MAX_MEM) - return NULL; - return &res->mem[num]; - case IORESOURCE_IRQ: - if (num >= PNP_MAX_IRQ) - return NULL; - return &res->irq[num]; - case IORESOURCE_DMA: - if (num >= PNP_MAX_DMA) - return NULL; - return &res->dma[num]; - } - return NULL; -} - struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned int type, unsigned int num) { struct pnp_resource *pnp_res; + struct resource *res; - pnp_res = pnp_get_pnp_resource(dev, type, num); - if (pnp_res) - return &pnp_res->res; - + list_for_each_entry(pnp_res, &dev->resources, list) { + res = &pnp_res->res; + if (pnp_resource_type(res) == type && num-- == 0) + return res; + } return NULL; } EXPORT_SYMBOL(pnp_get_resource); -static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) +static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) { struct pnp_resource *pnp_res; - int i; - switch (type) { - case IORESOURCE_IO: - for (i = 0; i < PNP_MAX_PORT; i++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i); - if (pnp_res && !pnp_resource_valid(&pnp_res->res)) - return pnp_res; - } - break; - case IORESOURCE_MEM: - for (i = 0; i < PNP_MAX_MEM; i++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i); - if (pnp_res && !pnp_resource_valid(&pnp_res->res)) - return pnp_res; - } - break; - case IORESOURCE_IRQ: - for (i = 0; i < PNP_MAX_IRQ; i++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i); - if (pnp_res && !pnp_resource_valid(&pnp_res->res)) - return pnp_res; - } - break; - case IORESOURCE_DMA: - for (i = 0; i < PNP_MAX_DMA; i++) { - pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i); - if (pnp_res && !pnp_resource_valid(&pnp_res->res)) - return pnp_res; - } - break; - } - return NULL; + pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL); + if (!pnp_res) + return NULL; + + list_add_tail(&pnp_res->list, &dev->resources); + return pnp_res; } struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, @@ -589,7 +539,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, struct resource *res; static unsigned char warned; - pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); + pnp_res = pnp_new_resource(dev); if (!pnp_res) { if (!warned) { dev_err(&dev->dev, "can't add resource for IRQ %d\n", @@ -615,7 +565,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, struct resource *res; static unsigned char warned; - pnp_res = pnp_new_resource(dev, IORESOURCE_DMA); + pnp_res = pnp_new_resource(dev); if (!pnp_res) { if (!warned) { dev_err(&dev->dev, "can't add resource for DMA %d\n", @@ -642,7 +592,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, struct resource *res; static unsigned char warned; - pnp_res = pnp_new_resource(dev, IORESOURCE_IO); + pnp_res = pnp_new_resource(dev); if (!pnp_res) { if (!warned) { dev_err(&dev->dev, "can't add resource for IO " @@ -671,7 +621,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, struct resource *res; static unsigned char warned; - pnp_res = pnp_new_resource(dev, IORESOURCE_MEM); + pnp_res = pnp_new_resource(dev); if (!pnp_res) { if (!warned) { dev_err(&dev->dev, "can't add resource for MEM " diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index eb07345..1566e4a 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -16,6 +16,10 @@ */ int pnp_is_active(struct pnp_dev *dev) { + /* + * I don't think this is very reliable because pnp_disable_dev() + * only clears out auto-assigned resources. + */ if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) @@ -70,54 +74,41 @@ char *pnp_resource_type_name(struct resource *res) void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) { #ifdef DEBUG + char buf[128]; + int len = 0; + struct pnp_resource *pnp_res; struct resource *res; - int i; dev_dbg(&dev->dev, "current resources: %s\n", desc); + list_for_each_entry(pnp_res, &dev->resources, list) { + res = &pnp_res->res; - for (i = 0; i < PNP_MAX_IRQ; i++) { - res = pnp_get_resource(dev, IORESOURCE_IRQ, i); - if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " irq %lld flags %#lx%s%s\n", - (unsigned long long) res->start, res->flags, - res->flags & IORESOURCE_DISABLED ? - " DISABLED" : "", - res->flags & IORESOURCE_AUTO ? - " AUTO" : ""); - } - for (i = 0; i < PNP_MAX_DMA; i++) { - res = pnp_get_resource(dev, IORESOURCE_DMA, i); - if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " dma %lld flags %#lx%s%s\n", - (unsigned long long) res->start, res->flags, - res->flags & IORESOURCE_DISABLED ? - " DISABLED" : "", - res->flags & IORESOURCE_AUTO ? - " AUTO" : ""); - } - for (i = 0; i < PNP_MAX_PORT; i++) { - res = pnp_get_resource(dev, IORESOURCE_IO, i); - if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx" - "%s%s\n", - (unsigned long long) res->start, - (unsigned long long) res->end, res->flags, - res->flags & IORESOURCE_DISABLED ? - " DISABLED" : "", - res->flags & IORESOURCE_AUTO ? - " AUTO" : ""); - } - for (i = 0; i < PNP_MAX_MEM; i++) { - res = pnp_get_resource(dev, IORESOURCE_MEM, i); - if (res && !(res->flags & IORESOURCE_UNSET)) - dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx" - "%s%s\n", - (unsigned long long) res->start, - (unsigned long long) res->end, res->flags, - res->flags & IORESOURCE_DISABLED ? - " DISABLED" : "", - res->flags & IORESOURCE_AUTO ? - " AUTO" : ""); + len += snprintf(buf + len, sizeof(buf) - len, " %-3s ", + pnp_resource_type_name(res)); + + if (res->flags & IORESOURCE_DISABLED) { + dev_dbg(&dev->dev, "%sdisabled\n", buf); + continue; + } + + switch (pnp_resource_type(res)) { + case IORESOURCE_IO: + case IORESOURCE_MEM: + len += snprintf(buf + len, sizeof(buf) - len, + "%#llx-%#llx flags %#lx", + (unsigned long long) res->start, + (unsigned long long) res->end, + res->flags); + break; + case IORESOURCE_IRQ: + case IORESOURCE_DMA: + len += snprintf(buf + len, sizeof(buf) - len, + "%lld flags %#lx", + (unsigned long long) res->start, + res->flags); + break; + } + dev_dbg(&dev->dev, "%s\n", buf); } #endif } diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c index cf4e07b..764f3a3 100644 --- a/drivers/pnp/system.c +++ b/drivers/pnp/system.c @@ -60,7 +60,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) int i; for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { - if (res->flags & IORESOURCE_UNSET) + if (res->flags & IORESOURCE_DISABLED) continue; if (res->start == 0) continue; /* disabled */ @@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) } for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { - if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) + if (res->flags & IORESOURCE_DISABLED) continue; reserve_range(dev, res->start, res->end, 0); diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 8b607ae..dfaa567 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -15,7 +15,6 @@ struct pnp_protocol; struct pnp_dev; -struct pnp_resource_table; /* * Resource Management @@ -24,7 +23,14 @@ struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int); static inline int pnp_resource_valid(struct resource *res) { - if (res && !(res->flags & IORESOURCE_UNSET)) + if (res) + return 1; + return 0; +} + +static inline int pnp_resource_enabled(struct resource *res) +{ + if (res && !(res->flags & IORESOURCE_DISABLED)) return 1; return 0; } @@ -64,7 +70,7 @@ static inline unsigned long pnp_port_flags(struct pnp_dev *dev, if (pnp_resource_valid(res)) return res->flags; - return IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; + return IORESOURCE_IO | IORESOURCE_AUTO; } static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) @@ -109,7 +115,7 @@ static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar) if (pnp_resource_valid(res)) return res->flags; - return IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; + return IORESOURCE_MEM | IORESOURCE_AUTO; } static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) @@ -143,7 +149,7 @@ static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar) if (pnp_resource_valid(res)) return res->flags; - return IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; + return IORESOURCE_IRQ | IORESOURCE_AUTO; } static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) @@ -167,7 +173,7 @@ static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar) if (pnp_resource_valid(res)) return res->flags; - return IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; + return IORESOURCE_DMA | IORESOURCE_AUTO; } static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) @@ -296,7 +302,7 @@ struct pnp_dev { int capabilities; struct pnp_option *independent; struct pnp_option *dependent; - struct pnp_resource_table *res; + struct list_head resources; char name[PNP_NAME_LEN]; /* contains a human-readable name */ int flags; /* used by protocols */ -- cgit v0.10.2 From 5acf91415799025410cc0d13101340d352f34c89 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:58 -0600 Subject: PNPACPI: keep disabled resources when parsing current config When we parse a device's _CRS data (the current resource settings), we should keep track of everything we find, even if it's currently disabled or invalid. This is what we already do for ISAPNP and PNPBIOS, and it helps keep things matched up when we subsequently re-encode resources. For example, consider a device with (mem, irq0, irq1, io), where irq0 is disabled. If we drop irq0 when parsing the _CRS, we will mistakenly put irq1 in the irq0 slot when we encode resources for an _SRS call. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 9a45c25..595252b 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -98,8 +98,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, int irq, flags; int p, t; - if (!valid_IRQ(gsi)) + if (!valid_IRQ(gsi)) { + pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED); return; + } /* * in IO-APIC mode, use overrided attribute. Two reasons: @@ -248,24 +250,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, * _CRS, but some firmware violates this, so parse them all. */ irq = &res->data.irq; - for (i = 0; i < irq->interrupt_count; i++) { - pnpacpi_parse_allocated_irqresource(dev, - irq->interrupts[i], - irq->triggering, - irq->polarity, - irq->sharable); + if (irq->interrupt_count == 0) + pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); + else { + for (i = 0; i < irq->interrupt_count; i++) { + pnpacpi_parse_allocated_irqresource(dev, + irq->interrupts[i], + irq->triggering, + irq->polarity, + irq->sharable); + } + + /* + * The IRQ encoder puts a single interrupt in each + * descriptor, so if a _CRS descriptor has more than + * one interrupt, we won't be able to re-encode it. + */ + if (pnp_can_write(dev) && irq->interrupt_count > 1) { + dev_warn(&dev->dev, "multiple interrupts in " + "_CRS descriptor; configuration can't " + "be changed\n"); + dev->capabilities &= ~PNP_WRITE; + } } break; case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; - if (dma->channel_count > 0) { + if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) flags = dma_flags(dma->type, dma->bus_master, dma->transfer); - if (dma->channels[0] == (u8) -1) - flags |= IORESOURCE_DISABLED; - pnp_add_dma_resource(dev, dma->channels[0], flags); - } + else + flags = IORESOURCE_DISABLED; + pnp_add_dma_resource(dev, dma->channels[0], flags); break; case ACPI_RESOURCE_TYPE_IO: @@ -331,12 +348,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, if (extended_irq->producer_consumer == ACPI_PRODUCER) return AE_OK; - for (i = 0; i < extended_irq->interrupt_count; i++) { - pnpacpi_parse_allocated_irqresource(dev, - extended_irq->interrupts[i], - extended_irq->triggering, - extended_irq->polarity, - extended_irq->sharable); + if (extended_irq->interrupt_count == 0) + pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); + else { + for (i = 0; i < extended_irq->interrupt_count; i++) { + pnpacpi_parse_allocated_irqresource(dev, + extended_irq->interrupts[i], + extended_irq->triggering, + extended_irq->polarity, + extended_irq->sharable); + } + + /* + * The IRQ encoder puts a single interrupt in each + * descriptor, so if a _CRS descriptor has more than + * one interrupt, we won't be able to re-encode it. + */ + if (pnp_can_write(dev) && + extended_irq->interrupt_count > 1) { + dev_warn(&dev->dev, "multiple interrupts in " + "_CRS descriptor; configuration can't " + "be changed\n"); + dev->capabilities &= ~PNP_WRITE; + } } break; -- cgit v0.10.2 From 25d39c39d82d062f4be685146abd054a3bafdf12 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:56:59 -0600 Subject: PNP: remove ratelimit on add resource failures We used to have a fixed-size resource table. If a device had twenty resources when the table only had space for ten, we didn't need ten warnings, so we added the ratelimit. Now that we can dynamically allocate new resources, we should only get failures if the allocation fails. That should be rare enough that we don't need to ratelimit the messages. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 0797a77..ff79aa6 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -537,15 +537,10 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, { struct pnp_resource *pnp_res; struct resource *res; - static unsigned char warned; pnp_res = pnp_new_resource(dev); if (!pnp_res) { - if (!warned) { - dev_err(&dev->dev, "can't add resource for IRQ %d\n", - irq); - warned = 1; - } + dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq); return NULL; } @@ -563,15 +558,10 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, { struct pnp_resource *pnp_res; struct resource *res; - static unsigned char warned; pnp_res = pnp_new_resource(dev); if (!pnp_res) { - if (!warned) { - dev_err(&dev->dev, "can't add resource for DMA %d\n", - dma); - warned = 1; - } + dev_err(&dev->dev, "can't add resource for DMA %d\n", dma); return NULL; } @@ -590,16 +580,12 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, { struct pnp_resource *pnp_res; struct resource *res; - static unsigned char warned; pnp_res = pnp_new_resource(dev); if (!pnp_res) { - if (!warned) { - dev_err(&dev->dev, "can't add resource for IO " - "%#llx-%#llx\n",(unsigned long long) start, - (unsigned long long) end); - warned = 1; - } + dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n", + (unsigned long long) start, + (unsigned long long) end); return NULL; } @@ -619,16 +605,12 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, { struct pnp_resource *pnp_res; struct resource *res; - static unsigned char warned; pnp_res = pnp_new_resource(dev); if (!pnp_res) { - if (!warned) { - dev_err(&dev->dev, "can't add resource for MEM " - "%#llx-%#llx\n",(unsigned long long) start, - (unsigned long long) end); - warned = 1; - } + dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n", + (unsigned long long) start, + (unsigned long long) end); return NULL; } -- cgit v0.10.2 From f61ed7e32d2d6a0a8c3c101da513ccedd542e14d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:00 -0600 Subject: PNP: dont sort by type in /sys/.../resources Rather than stepping through all IO resources, then stepping through all MMIO resources, etc., we can just iterate over the resource list once directly. This can change the order in /sys, e.g., # cat /sys/devices/pnp0/00:07/resources # OLD state = active io 0x3f8-0x3ff irq 4 # cat /sys/devices/pnp0/00:07/resources # NEW state = active irq 4 io 0x3f8-0x3ff The old code artificially sorted resources by type; the new code just lists them in the order we read them from the ISAPNP hardware or the BIOS. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 7fc86bb..674e8ba 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -248,8 +248,9 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); + struct pnp_resource *pnp_res; struct resource *res; - int i, ret; + int ret; pnp_info_buffer_t *buffer; if (!dev) @@ -262,46 +263,33 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, buffer->buffer = buf; buffer->curr = buffer->buffer; - pnp_printf(buffer, "state = "); - if (dev->active) - pnp_printf(buffer, "active\n"); - else - pnp_printf(buffer, "disabled\n"); + pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled"); - for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { - pnp_printf(buffer, "io"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " 0x%llx-0x%llx\n", - (unsigned long long) res->start, - (unsigned long long) res->end); - } - for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { - pnp_printf(buffer, "mem"); - if (res->flags & IORESOURCE_DISABLED) + list_for_each_entry(pnp_res, &dev->resources, list) { + res = &pnp_res->res; + + pnp_printf(buffer, pnp_resource_type_name(res)); + + if (res->flags & IORESOURCE_DISABLED) { pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " 0x%llx-0x%llx\n", + continue; + } + + switch (pnp_resource_type(res)) { + case IORESOURCE_IO: + case IORESOURCE_MEM: + pnp_printf(buffer, " %#llx-%#llx\n", (unsigned long long) res->start, (unsigned long long) res->end); - } - for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { - pnp_printf(buffer, "irq"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else - pnp_printf(buffer, " %lld\n", - (unsigned long long) res->start); - } - for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { - pnp_printf(buffer, "dma"); - if (res->flags & IORESOURCE_DISABLED) - pnp_printf(buffer, " disabled\n"); - else + break; + case IORESOURCE_IRQ: + case IORESOURCE_DMA: pnp_printf(buffer, " %lld\n", (unsigned long long) res->start); + break; + } } + ret = (buffer->curr - buf); kfree(buffer); return ret; -- cgit v0.10.2 From 57fd51a8be26921b56747ddd09d1d9e01c11c9e0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:01 -0600 Subject: PNP: add pnp_possible_config() -- can a device could be configured this way? As part of a heuristic to identify modem devices, 8250_pnp.c checks to see whether a device can be configured at any of the legacy COM port addresses. This patch moves the code that traverses the PNP "possible resource options" from 8250_pnp.c to the PNP subsystem. This encapsulation is important because a future patch will change the implementation of those resource options. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index ff79aa6..786fd35 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -624,6 +624,68 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, return pnp_res; } +static int pnp_possible_option(struct pnp_option *option, int type, + resource_size_t start, resource_size_t size) +{ + struct pnp_option *tmp; + struct pnp_port *port; + struct pnp_mem *mem; + struct pnp_irq *irq; + struct pnp_dma *dma; + + if (!option) + return 0; + + for (tmp = option; tmp; tmp = tmp->next) { + switch (type) { + case IORESOURCE_IO: + for (port = tmp->port; port; port = port->next) { + if (port->min == start && port->size == size) + return 1; + } + break; + case IORESOURCE_MEM: + for (mem = tmp->mem; mem; mem = mem->next) { + if (mem->min == start && mem->size == size) + return 1; + } + break; + case IORESOURCE_IRQ: + for (irq = tmp->irq; irq; irq = irq->next) { + if (start < PNP_IRQ_NR && + test_bit(start, irq->map)) + return 1; + } + break; + case IORESOURCE_DMA: + for (dma = tmp->dma; dma; dma = dma->next) { + if (dma->map & (1 << start)) + return 1; + } + break; + } + } + + return 0; +} + +/* + * Determine whether the specified resource is a possible configuration + * for this device. + */ +int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, + resource_size_t size) +{ + if (pnp_possible_option(dev->independent, type, start, size)) + return 1; + + if (pnp_possible_option(dev->dependent, type, start, size)) + return 1; + + return 0; +} +EXPORT_SYMBOL(pnp_possible_config); + /* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq(char *str) { diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 97c68d02..638b686 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -383,21 +383,14 @@ static int __devinit check_name(char *name) return 0; } -static int __devinit check_resources(struct pnp_option *option) +static int __devinit check_resources(struct pnp_dev *dev) { - struct pnp_option *tmp; - if (!option) - return 0; + resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8}; + int i; - for (tmp = option; tmp; tmp = tmp->next) { - struct pnp_port *port; - for (port = tmp->port; port; port = port->next) - if ((port->size == 8) && - ((port->min == 0x2f8) || - (port->min == 0x3f8) || - (port->min == 0x2e8) || - (port->min == 0x3e8))) - return 1; + for (i = 0; i < ARRAY_SIZE(base); i++) { + if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8)) + return 1; } return 0; @@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) (dev->card && check_name(dev->card->name)))) return -ENODEV; - if (check_resources(dev->independent)) - return 0; - - if (check_resources(dev->dependent)) + if (check_resources(dev)) return 0; return -ENODEV; diff --git a/include/linux/pnp.h b/include/linux/pnp.h index dfaa567..e033e1b 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -479,6 +479,8 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv); extern struct list_head pnp_cards; /* resource management */ +int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base, + resource_size_t size); int pnp_auto_config_dev(struct pnp_dev *dev); int pnp_start_dev(struct pnp_dev *dev); int pnp_stop_dev(struct pnp_dev *dev); @@ -506,6 +508,9 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { } /* resource management */ +static inline int pnp_possible_config(struct pnp_dev *dev, int type, + resource_size_t base, + resource_size_t size) { return 0; } static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } -- cgit v0.10.2 From b72ee1f11e373179ec703e0e5afaf585ed3a950a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:02 -0600 Subject: PNP: whitespace/coding style fixes No functional change; just make a couple declarations consistent with the rest of the file. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 674e8ba..239923a 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -216,12 +216,12 @@ static ssize_t pnp_show_options(struct device *dmdev, struct device_attribute *attr, char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); + pnp_info_buffer_t *buffer; struct pnp_option *independent = dev->independent; struct pnp_option *dependent = dev->dependent; int ret, dep = 1; - pnp_info_buffer_t *buffer = (pnp_info_buffer_t *) - pnp_alloc(sizeof(pnp_info_buffer_t)); + buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); if (!buffer) return -ENOMEM; @@ -248,17 +248,18 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); + pnp_info_buffer_t *buffer; struct pnp_resource *pnp_res; struct resource *res; int ret; - pnp_info_buffer_t *buffer; if (!dev) return -EINVAL; - buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); + buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); if (!buffer) return -ENOMEM; + buffer->len = PAGE_SIZE; buffer->buffer = buf; buffer->curr = buffer->buffer; @@ -295,9 +296,9 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, return ret; } -static ssize_t -pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, - const char *ubuf, size_t count) +static ssize_t pnp_set_current_resources(struct device *dmdev, + struct device_attribute *attr, + const char *ubuf, size_t count) { struct pnp_dev *dev = to_pnp_dev(dmdev); char *buf = (void *)ubuf; -- cgit v0.10.2 From 08c9f262f268f7948be13bf3a5bda1d635c649b4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:03 -0600 Subject: PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM PNP previously defined PNP_PORT_FLAG_16BITADDR and PNP_PORT_FLAG_FIXED in a private header file, but put those flags in struct resource.flags fields. Better to make them IORESOURCE_IO_* flags like the existing IRQ, DMA, and MEM flags. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 239923a..c172b6d 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -57,7 +57,7 @@ static void pnp_print_port(pnp_info_buffer_t * buffer, char *space, "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", space, port->min, port->max, port->align ? (port->align - 1) : 0, port->size, - port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10); + port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10); } static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index ca4457e..c5b9252 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -486,7 +486,7 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev, port->max = (tmp[4] << 8) | tmp[3]; port->align = tmp[5]; port->size = tmp[6]; - port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0; + port->flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0; pnp_register_port_resource(dev, option, port); } @@ -507,7 +507,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, port->min = port->max = (tmp[1] << 8) | tmp[0]; port->size = tmp[2]; port->align = 0; - port->flags = PNP_PORT_FLAG_FIXED; + port->flags = IORESOURCE_IO_FIXED; pnp_register_port_resource(dev, option, port); } diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 595252b..46069e6 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -180,7 +180,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, u64 end = start + len - 1; if (io_decode == ACPI_DECODE_16) - flags |= PNP_PORT_FLAG_16BITADDR; + flags |= IORESOURCE_IO_16BIT_ADDR; if (len == 0 || end >= 0x10003) flags |= IORESOURCE_DISABLED; @@ -485,7 +485,7 @@ static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, port->align = io->alignment; port->size = io->address_length; port->flags = ACPI_DECODE_16 == io->io_decode ? - PNP_PORT_FLAG_16BITADDR : 0; + IORESOURCE_IO_16BIT_ADDR : 0; pnp_register_port_resource(dev, option, port); } @@ -503,7 +503,7 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, port->min = port->max = io->address; port->size = io->address_length; port->align = 0; - port->flags = PNP_PORT_FLAG_FIXED; + port->flags = IORESOURCE_IO_FIXED; pnp_register_port_resource(dev, option, port); } @@ -609,7 +609,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, port->min = port->max = p->minimum; port->size = p->address_length; port->align = 0; - port->flags = PNP_PORT_FLAG_FIXED; + port->flags = IORESOURCE_IO_FIXED; pnp_register_port_resource(dev, option, port); } } @@ -946,7 +946,7 @@ static void pnpacpi_encode_io(struct pnp_dev *dev, if (pnp_resource_enabled(p)) { /* Note: pnp_assign_port copies pnp_port->flags into p->flags */ - io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? + io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ? ACPI_DECODE_16 : ACPI_DECODE_10; io->minimum = p->start; io->maximum = p->end; diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 01f0c3d..489fec3 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -310,7 +310,7 @@ static __init void pnpbios_parse_port_option(struct pnp_dev *dev, port->max = (p[5] << 8) | p[4]; port->align = p[6]; port->size = p[7]; - port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; + port->flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0; pnp_register_port_resource(dev, option, port); } @@ -326,7 +326,7 @@ static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, port->min = port->max = (p[2] << 8) | p[1]; port->size = p[3]; port->align = 0; - port->flags = PNP_PORT_FLAG_FIXED; + port->flags = IORESOURCE_IO_FIXED; pnp_register_port_resource(dev, option, port); } diff --git a/include/linux/ioport.h b/include/linux/ioport.h index c6801bf..39db059 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -88,6 +88,10 @@ struct resource_list { #define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */ #define IORESOURCE_MEM_EXPANSIONROM (1<<6) +/* PnP I/O specific bits (IORESOURCE_BITS) */ +#define IORESOURCE_IO_16BIT_ADDR (1<<0) +#define IORESOURCE_IO_FIXED (1<<1) + /* PCI ROM control bits (IORESOURCE_BITS) */ #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ diff --git a/include/linux/pnp.h b/include/linux/pnp.h index e033e1b..e1454da 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -182,9 +182,6 @@ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) } -#define PNP_PORT_FLAG_16BITADDR (1<<0) -#define PNP_PORT_FLAG_FIXED (1<<1) - struct pnp_port { unsigned short min; /* min base number */ unsigned short max; /* max base number */ -- cgit v0.10.2 From a1802c42950403657d07e64558eff612d550ce16 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:04 -0600 Subject: PNP: make resource option structures private to PNP subsystem Nothing outside the PNP subsystem should need access to a device's resource options, so this patch moves the option structure declarations to a private header file. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 1667ac3..3126e45 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -19,6 +19,54 @@ void pnp_remove_card(struct pnp_card *card); int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); void pnp_remove_card_device(struct pnp_dev *dev); +struct pnp_port { + unsigned short min; /* min base number */ + unsigned short max; /* max base number */ + unsigned char align; /* align boundary */ + unsigned char size; /* size of range */ + unsigned char flags; /* port flags */ + unsigned char pad; /* pad */ + struct pnp_port *next; /* next port */ +}; + +#define PNP_IRQ_NR 256 +struct pnp_irq { + DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */ + unsigned char flags; /* IRQ flags */ + unsigned char pad; /* pad */ + struct pnp_irq *next; /* next IRQ */ +}; + +struct pnp_dma { + unsigned char map; /* bitmask for DMA channels */ + unsigned char flags; /* DMA flags */ + struct pnp_dma *next; /* next port */ +}; + +struct pnp_mem { + unsigned int min; /* min base number */ + unsigned int max; /* max base number */ + unsigned int align; /* align boundary */ + unsigned int size; /* size of range */ + unsigned char flags; /* memory flags */ + unsigned char pad; /* pad */ + struct pnp_mem *next; /* next memory resource */ +}; + +#define PNP_RES_PRIORITY_PREFERRED 0 +#define PNP_RES_PRIORITY_ACCEPTABLE 1 +#define PNP_RES_PRIORITY_FUNCTIONAL 2 +#define PNP_RES_PRIORITY_INVALID 65535 + +struct pnp_option { + unsigned short priority; /* priority */ + struct pnp_port *port; /* first port */ + struct pnp_irq *irq; /* first IRQ */ + struct pnp_dma *dma; /* first DMA */ + struct pnp_mem *mem; /* first memory resource */ + struct pnp_option *next; /* used to chain dependent resources */ +}; + struct pnp_option *pnp_build_option(int priority); struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, diff --git a/include/linux/pnp.h b/include/linux/pnp.h index e1454da..785126f 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -182,54 +182,6 @@ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) } -struct pnp_port { - unsigned short min; /* min base number */ - unsigned short max; /* max base number */ - unsigned char align; /* align boundary */ - unsigned char size; /* size of range */ - unsigned char flags; /* port flags */ - unsigned char pad; /* pad */ - struct pnp_port *next; /* next port */ -}; - -#define PNP_IRQ_NR 256 -struct pnp_irq { - DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */ - unsigned char flags; /* IRQ flags */ - unsigned char pad; /* pad */ - struct pnp_irq *next; /* next IRQ */ -}; - -struct pnp_dma { - unsigned char map; /* bitmask for DMA channels */ - unsigned char flags; /* DMA flags */ - struct pnp_dma *next; /* next port */ -}; - -struct pnp_mem { - unsigned int min; /* min base number */ - unsigned int max; /* max base number */ - unsigned int align; /* align boundary */ - unsigned int size; /* size of range */ - unsigned char flags; /* memory flags */ - unsigned char pad; /* pad */ - struct pnp_mem *next; /* next memory resource */ -}; - -#define PNP_RES_PRIORITY_PREFERRED 0 -#define PNP_RES_PRIORITY_ACCEPTABLE 1 -#define PNP_RES_PRIORITY_FUNCTIONAL 2 -#define PNP_RES_PRIORITY_INVALID 65535 - -struct pnp_option { - unsigned short priority; /* priority */ - struct pnp_port *port; /* first port */ - struct pnp_irq *irq; /* first IRQ */ - struct pnp_dma *dma; /* first DMA */ - struct pnp_mem *mem; /* first memory resource */ - struct pnp_option *next; /* used to chain dependent resources */ -}; - /* * Device Management */ -- cgit v0.10.2 From 7aefff51854ccd33599c40b4e360d94cb2b7622f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:05 -0600 Subject: PNP: introduce pnp_irq_mask_t typedef This adds a typedef for the IRQ bitmap, which should cause no functional change, but will make it easier to pass a pointer to a bitmap to pnp_register_irq_resource(). Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 3126e45..a9ee0a9 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -30,8 +30,10 @@ struct pnp_port { }; #define PNP_IRQ_NR 256 +typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t; + struct pnp_irq { - DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */ + pnp_irq_mask_t map; /* bitmap for IRQ lines */ unsigned char flags; /* IRQ flags */ unsigned char pad; /* pad */ struct pnp_irq *next; /* next IRQ */ diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index c172b6d..249b407 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -67,7 +67,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, pnp_printf(buffer, "%sirq ", space); for (i = 0; i < PNP_IRQ_NR; i++) - if (test_bit(i, irq->map)) { + if (test_bit(i, irq->map.bits)) { if (!first) { pnp_printf(buffer, ","); } else { @@ -78,7 +78,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, else pnp_printf(buffer, "%i", i); } - if (bitmap_empty(irq->map, PNP_IRQ_NR)) + if (bitmap_empty(irq->map.bits, PNP_IRQ_NR)) pnp_printf(buffer, ""); if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) pnp_printf(buffer, " High-Edge"); diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index c5b9252..e0caa71 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -441,7 +441,7 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, if (!irq) return; bits = (tmp[1] << 8) | tmp[0]; - bitmap_copy(irq->map, &bits, 16); + bitmap_copy(irq->map.bits, &bits, 16); if (size > 2) irq->flags = tmp[2]; else diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 165b624..e758dd2 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -128,20 +128,20 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) res->start = -1; res->end = -1; - if (bitmap_empty(rule->map, PNP_IRQ_NR)) { + if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) { res->flags |= IORESOURCE_DISABLED; dev_dbg(&dev->dev, " irq %d disabled\n", idx); goto __add; } /* TBD: need check for >16 IRQ */ - res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16); + res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16); if (res->start < PNP_IRQ_NR) { res->end = res->start; goto __add; } for (i = 0; i < 16; i++) { - if (test_bit(xtab[i], rule->map)) { + if (test_bit(xtab[i], rule->map.bits)) { res->start = res->end = xtab[i]; if (pnp_check_irq(dev, res)) goto __add; diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 46069e6..ae65454 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -442,7 +442,7 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, for (i = 0; i < p->interrupt_count; i++) if (p->interrupts[i]) - __set_bit(p->interrupts[i], irq->map); + __set_bit(p->interrupts[i], irq->map.bits); irq->flags = irq_flags(p->triggering, p->polarity, p->sharable); pnp_register_irq_resource(dev, option, irq); @@ -463,7 +463,7 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, for (i = 0; i < p->interrupt_count; i++) if (p->interrupts[i]) - __set_bit(p->interrupts[i], irq->map); + __set_bit(p->interrupts[i], irq->map.bits); irq->flags = irq_flags(p->triggering, p->polarity, p->sharable); pnp_register_irq_resource(dev, option, irq); diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 489fec3..dd2ea7b 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -275,7 +275,7 @@ static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, if (!irq) return; bits = (p[2] << 8) | p[1]; - bitmap_copy(irq->map, &bits, 16); + bitmap_copy(irq->map.bits, &bits, 16); if (size > 2) irq->flags = p[3]; else diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 21acb54..48e6017 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -66,15 +66,18 @@ static void quirk_cmi8330_resources(struct pnp_dev *dev) struct pnp_irq *irq; struct pnp_dma *dma; - for (irq = res->irq; irq; irq = irq->next) { // Valid irqs are 5, 7, 10 + for (irq = res->irq; irq; irq = irq->next) { + /* Valid irqs are 5, 7, 10 */ tmp = 0x04A0; - bitmap_copy(irq->map, &tmp, 16); // 0000 0100 1010 0000 + bitmap_copy(irq->map.bits, &tmp, 16); } - for (dma = res->dma; dma; dma = dma->next) // Valid 8bit dma channels are 1,3 + for (dma = res->dma; dma; dma = dma->next) { + /* Valid 8bit dma channels are 1,3 */ if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) == IORESOURCE_DMA_8BIT) dma->map = 0x000A; + } } dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 " "and DMA channels to 1, 3\n"); @@ -187,7 +190,7 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) if (!copy) break; - memcpy(copy->map, irq->map, sizeof copy->map); + bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR); copy->flags = irq->flags; copy->next = res->irq; /* Yes, this is NULL */ diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 786fd35..55a57cd 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -98,13 +98,13 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, int i; for (i = 0; i < 16; i++) - if (test_bit(i, data->map)) + if (test_bit(i, data->map.bits)) pcibios_penalize_isa_irq(i, 0); } #endif #ifdef DEBUG - bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR); + bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR); dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf, data->flags); #endif @@ -653,7 +653,7 @@ static int pnp_possible_option(struct pnp_option *option, int type, case IORESOURCE_IRQ: for (irq = tmp->irq; irq; irq = irq->next) { if (start < PNP_IRQ_NR && - test_bit(start, irq->map)) + test_bit(start, irq->map.bits)) return 1; } break; -- cgit v0.10.2 From 169aaffe885c56745188e7913f212a67beaa3b80 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:06 -0600 Subject: PNP: increase I/O port & memory option address sizes ACPI Address Space Descriptors can be up to 64 bits wide. We should keep track of the whole thing when parsing resource options, so this patch changes PNP port and mem option fields from "unsigned short" and "unsigned int" to "resource_size_t". Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index a9ee0a9..afbeee5 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -20,10 +20,10 @@ int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); void pnp_remove_card_device(struct pnp_dev *dev); struct pnp_port { - unsigned short min; /* min base number */ - unsigned short max; /* max base number */ - unsigned char align; /* align boundary */ - unsigned char size; /* size of range */ + resource_size_t min; /* min base number */ + resource_size_t max; /* max base number */ + resource_size_t align; /* align boundary */ + resource_size_t size; /* size of range */ unsigned char flags; /* port flags */ unsigned char pad; /* pad */ struct pnp_port *next; /* next port */ @@ -46,10 +46,10 @@ struct pnp_dma { }; struct pnp_mem { - unsigned int min; /* min base number */ - unsigned int max; /* max base number */ - unsigned int align; /* align boundary */ - unsigned int size; /* size of range */ + resource_size_t min; /* min base number */ + resource_size_t max; /* max base number */ + resource_size_t align; /* align boundary */ + resource_size_t size; /* size of range */ unsigned char flags; /* memory flags */ unsigned char pad; /* pad */ struct pnp_mem *next; /* next memory resource */ diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 249b407..b09f67d 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -53,10 +53,12 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...) static void pnp_print_port(pnp_info_buffer_t * buffer, char *space, struct pnp_port *port) { - pnp_printf(buffer, - "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", - space, port->min, port->max, - port->align ? (port->align - 1) : 0, port->size, + pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, " + "%i-bit address decoding\n", space, + (unsigned long long) port->min, + (unsigned long long) port->max, + port->align ? ((unsigned long long) port->align - 1) : 0, + (unsigned long long) port->size, port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10); } @@ -148,8 +150,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, { char *s; - pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", - space, mem->min, mem->max, mem->align, mem->size); + pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx", + space, (unsigned long long) mem->min, + (unsigned long long) mem->max, + (unsigned long long) mem->align, + (unsigned long long) mem->size); if (mem->flags & IORESOURCE_MEM_WRITEABLE) pnp_printf(buffer, ", writeable"); if (mem->flags & IORESOURCE_MEM_CACHEABLE) diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 55a57cd..391828c 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -143,8 +143,11 @@ int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, option->port = data; dev_dbg(&dev->dev, " io " - "min %#x max %#x align %d size %d flags %#x\n", - data->min, data->max, data->align, data->size, data->flags); + "min %#llx max %#llx align %lld size %lld flags %#x\n", + (unsigned long long) data->min, + (unsigned long long) data->max, + (unsigned long long) data->align, + (unsigned long long) data->size, data->flags); return 0; } @@ -162,8 +165,11 @@ int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, option->mem = data; dev_dbg(&dev->dev, " mem " - "min %#x max %#x align %d size %d flags %#x\n", - data->min, data->max, data->align, data->size, data->flags); + "min %#llx max %#llx align %lld size %lld flags %#x\n", + (unsigned long long) data->min, + (unsigned long long) data->max, + (unsigned long long) data->align, + (unsigned long long) data->size, data->flags); return 0; } -- cgit v0.10.2 From fcfb7ce3d688d5c15fc9bc0a2a48e1ededdb046f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:07 -0600 Subject: PNP: improve resource assignment debug When we fail to assign an I/O or MEM resource, include the min/max in the debug output to help match it with the options. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index e758dd2..c706dd2 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -47,7 +47,10 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) res->start += rule->align; res->end = res->start + rule->size - 1; if (res->start > rule->max || !rule->align) { - dev_dbg(&dev->dev, " couldn't assign io %d\n", idx); + dev_dbg(&dev->dev, " couldn't assign io %d " + "(min %#llx max %#llx)\n", idx, + (unsigned long long) rule->min, + (unsigned long long) rule->max); return 0; } } @@ -96,7 +99,10 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) res->start += rule->align; res->end = res->start + rule->size - 1; if (res->start > rule->max || !rule->align) { - dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx); + dev_dbg(&dev->dev, " couldn't assign mem %d " + "(min %#llx max %#llx)\n", idx, + (unsigned long long) rule->min, + (unsigned long long) rule->max); return 0; } } -- cgit v0.10.2 From 819beac3806a5e986d81f476b999b7fffce1a233 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:08 -0600 Subject: PNP: in debug resource dump, make empty list obvious If the resource list is empty, say that explicitly. Previously, it was confusing because often the heading was followed by zero resource lines, then some "add resource" lines from auto-assignment, so the "add" lines looked like current resources. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 1566e4a..0ad42db 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -79,7 +79,12 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) struct pnp_resource *pnp_res; struct resource *res; - dev_dbg(&dev->dev, "current resources: %s\n", desc); + if (list_empty(&dev->resources)) { + dev_dbg(&dev->dev, "%s: no current resources\n", desc); + return; + } + + dev_dbg(&dev->dev, "%s: current resources:\n", desc); list_for_each_entry(pnp_res, &dev->resources, list) { res = &pnp_res->res; -- cgit v0.10.2 From 6e906f0e1c8633ed357a64e9861f1822789bee3d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:09 -0600 Subject: PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) This patch doesn't change any behavior; it just makes the return values more conventional. This changes pnp_assign_dma() from a void function to one that returns an int, just like the other assignment functions. For now, at least, pnp_assign_dma() always returns 0 (success), so it appears to never fail, just like before. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index c706dd2..1adc83f 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -26,7 +26,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " "flags %#lx\n", idx, (unsigned long long) res->start, (unsigned long long) res->end, res->flags); - return 1; + return 0; } res = &local_res; @@ -51,13 +51,13 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) "(min %#llx max %#llx)\n", idx, (unsigned long long) rule->min, (unsigned long long) rule->max); - return 0; + return -EBUSY; } } __add: pnp_add_io_resource(dev, res->start, res->end, res->flags); - return 1; + return 0; } static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) @@ -69,7 +69,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " "flags %#lx\n", idx, (unsigned long long) res->start, (unsigned long long) res->end, res->flags); - return 1; + return 0; } res = &local_res; @@ -103,13 +103,13 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) "(min %#llx max %#llx)\n", idx, (unsigned long long) rule->min, (unsigned long long) rule->max); - return 0; + return -EBUSY; } } __add: pnp_add_mem_resource(dev, res->start, res->end, res->flags); - return 1; + return 0; } static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) @@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) if (res) { dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", idx, (int) res->start, res->flags); - return 1; + return 0; } res = &local_res; @@ -154,14 +154,14 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) } } dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); - return 0; + return -EBUSY; __add: pnp_add_irq_resource(dev, res->start, res->flags); - return 1; + return 0; } -static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) +static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { struct resource *res, local_res; int i; @@ -175,7 +175,7 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) if (res) { dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", idx, (int) res->start, res->flags); - return; + return 0; } res = &local_res; @@ -198,6 +198,7 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) __add: pnp_add_dma_resource(dev, res->start, res->flags); + return 0; } void pnp_init_resources(struct pnp_dev *dev) @@ -243,25 +244,26 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) irq = dev->independent->irq; dma = dev->independent->dma; while (port) { - if (!pnp_assign_port(dev, port, nport)) + if (pnp_assign_port(dev, port, nport) < 0) goto fail; nport++; port = port->next; } while (mem) { - if (!pnp_assign_mem(dev, mem, nmem)) + if (pnp_assign_mem(dev, mem, nmem) < 0) goto fail; nmem++; mem = mem->next; } while (irq) { - if (!pnp_assign_irq(dev, irq, nirq)) + if (pnp_assign_irq(dev, irq, nirq) < 0) goto fail; nirq++; irq = irq->next; } while (dma) { - pnp_assign_dma(dev, dma, ndma); + if (pnp_assign_dma(dev, dma, ndma) < 0) + goto fail; ndma++; dma = dma->next; } @@ -281,25 +283,26 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) irq = dep->irq; dma = dep->dma; while (port) { - if (!pnp_assign_port(dev, port, nport)) + if (pnp_assign_port(dev, port, nport) < 0) goto fail; nport++; port = port->next; } while (mem) { - if (!pnp_assign_mem(dev, mem, nmem)) + if (pnp_assign_mem(dev, mem, nmem) < 0) goto fail; nmem++; mem = mem->next; } while (irq) { - if (!pnp_assign_irq(dev, irq, nirq)) + if (pnp_assign_irq(dev, irq, nirq) < 0) goto fail; nirq++; irq = irq->next; } while (dma) { - pnp_assign_dma(dev, dma, ndma); + if (pnp_assign_dma(dev, dma, ndma) < 0) + goto fail; ndma++; dma = dma->next; } -- cgit v0.10.2 From b08395e5038e3337bb85c7246a635a3be6d5a29c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:10 -0600 Subject: PNP: remove redundant pnp_can_configure() check pnp_assign_resources() is static and the only caller checks pnp_can_configure() before calling it, so no need to do it again. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 1adc83f..7ea9e1e 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -231,9 +231,6 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) struct pnp_dma *dma; int nport = 0, nmem = 0, nirq = 0, ndma = 0; - if (!pnp_can_configure(dev)) - return -ENODEV; - dbg_pnp_show_resources(dev, "before pnp_assign_resources"); mutex_lock(&pnp_res_mutex); pnp_clean_resource_table(dev); -- cgit v0.10.2 From c227536b4cc2600fc9d22ba0067f699165f6621f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:11 -0600 Subject: PNP: centralize resource option allocations This patch moves all the option allocations (pnp_mem, pnp_port, etc) into the pnp_register_{mem,port,irq,dma}_resource() functions. This will make it easier to rework the option data structures. The non-trivial part of this patch is the IRQ handling. The backends have to allocate a local pnp_irq_mask_t bitmap, populate it, and pass a pointer to pnp_register_irq_resource(). Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index afbeee5..360c638 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -74,13 +74,17 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, int priority); int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_irq *data); + pnp_irq_mask_t *map, unsigned char flags); int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_dma *data); + unsigned char map, unsigned char flags); int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_port *data); + resource_size_t min, resource_size_t max, + resource_size_t align, resource_size_t size, + unsigned char flags); int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_mem *data); + resource_size_t min, resource_size_t max, + resource_size_t align, resource_size_t size, + unsigned char flags); void pnp_init_resources(struct pnp_dev *dev); void pnp_fixup_device(struct pnp_dev *dev); diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index e0caa71..3f75fdb 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -433,20 +433,20 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, int size) { unsigned char tmp[3]; - struct pnp_irq *irq; unsigned long bits; + pnp_irq_mask_t map; + unsigned char flags = IORESOURCE_IRQ_HIGHEDGE; isapnp_peek(tmp, size); - irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); - if (!irq) - return; bits = (tmp[1] << 8) | tmp[0]; - bitmap_copy(irq->map.bits, &bits, 16); + + bitmap_zero(map.bits, PNP_IRQ_NR); + bitmap_copy(map.bits, &bits, 16); + if (size > 2) - irq->flags = tmp[2]; - else - irq->flags = IORESOURCE_IRQ_HIGHEDGE; - pnp_register_irq_resource(dev, option, irq); + flags = tmp[2]; + + pnp_register_irq_resource(dev, option, &map, flags); } /* @@ -457,15 +457,9 @@ static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, int size) { unsigned char tmp[2]; - struct pnp_dma *dma; isapnp_peek(tmp, size); - dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); - if (!dma) - return; - dma->map = tmp[0]; - dma->flags = tmp[1]; - pnp_register_dma_resource(dev, option, dma); + pnp_register_dma_resource(dev, option, tmp[0], tmp[1]); } /* @@ -476,18 +470,16 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev, int size) { unsigned char tmp[7]; - struct pnp_port *port; + resource_size_t min, max, align, len; + unsigned char flags; isapnp_peek(tmp, size); - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = (tmp[2] << 8) | tmp[1]; - port->max = (tmp[4] << 8) | tmp[3]; - port->align = tmp[5]; - port->size = tmp[6]; - port->flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0; - pnp_register_port_resource(dev, option, port); + min = (tmp[2] << 8) | tmp[1]; + max = (tmp[4] << 8) | tmp[3]; + align = tmp[5]; + len = tmp[6]; + flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0; + pnp_register_port_resource(dev, option, min, max, align, len, flags); } /* @@ -498,17 +490,13 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, int size) { unsigned char tmp[3]; - struct pnp_port *port; + resource_size_t base, len; isapnp_peek(tmp, size); - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = port->max = (tmp[1] << 8) | tmp[0]; - port->size = tmp[2]; - port->align = 0; - port->flags = IORESOURCE_IO_FIXED; - pnp_register_port_resource(dev, option, port); + base = (tmp[1] << 8) | tmp[0]; + len = tmp[2]; + pnp_register_port_resource(dev, option, base, base, 0, len, + IORESOURCE_IO_FIXED); } /* @@ -519,18 +507,16 @@ static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, int size) { unsigned char tmp[9]; - struct pnp_mem *mem; + resource_size_t min, max, align, len; + unsigned char flags; isapnp_peek(tmp, size); - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = ((tmp[2] << 8) | tmp[1]) << 8; - mem->max = ((tmp[4] << 8) | tmp[3]) << 8; - mem->align = (tmp[6] << 8) | tmp[5]; - mem->size = ((tmp[8] << 8) | tmp[7]) << 8; - mem->flags = tmp[0]; - pnp_register_mem_resource(dev, option, mem); + min = ((tmp[2] << 8) | tmp[1]) << 8; + max = ((tmp[4] << 8) | tmp[3]) << 8; + align = (tmp[6] << 8) | tmp[5]; + len = ((tmp[8] << 8) | tmp[7]) << 8; + flags = tmp[0]; + pnp_register_mem_resource(dev, option, min, max, align, len, flags); } /* @@ -541,20 +527,16 @@ static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, int size) { unsigned char tmp[17]; - struct pnp_mem *mem; + resource_size_t min, max, align, len; + unsigned char flags; isapnp_peek(tmp, size); - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; - mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; - mem->align = - (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; - mem->size = - (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; - mem->flags = tmp[0]; - pnp_register_mem_resource(dev, option, mem); + min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; + max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; + align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; + len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; + flags = tmp[0]; + pnp_register_mem_resource(dev, option, min, max, align, len, flags); } /* @@ -565,18 +547,14 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, int size) { unsigned char tmp[9]; - struct pnp_mem *mem; + resource_size_t base, len; + unsigned char flags; isapnp_peek(tmp, size); - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = mem->max = - (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; - mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; - mem->align = 0; - mem->flags = tmp[0]; - pnp_register_mem_resource(dev, option, mem); + base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; + len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; + flags = tmp[0]; + pnp_register_mem_resource(dev, option, base, base, 0, len, flags); } /* diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index ae65454..3aaf406 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -411,20 +411,16 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, struct acpi_resource_dma *p) { int i; - struct pnp_dma *dma; + unsigned char map = 0, flags; if (p->channel_count == 0) return; - dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); - if (!dma) - return; for (i = 0; i < p->channel_count; i++) - dma->map |= 1 << p->channels[i]; - - dma->flags = dma_flags(p->type, p->bus_master, p->transfer); + map |= 1 << p->channels[i]; - pnp_register_dma_resource(dev, option, dma); + flags = dma_flags(p->type, p->bus_master, p->transfer); + pnp_register_dma_resource(dev, option, map, flags); } static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, @@ -432,20 +428,19 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, struct acpi_resource_irq *p) { int i; - struct pnp_irq *irq; + pnp_irq_mask_t map; + unsigned char flags; if (p->interrupt_count == 0) return; - irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); - if (!irq) - return; + bitmap_zero(map.bits, PNP_IRQ_NR); for (i = 0; i < p->interrupt_count; i++) if (p->interrupts[i]) - __set_bit(p->interrupts[i], irq->map.bits); - irq->flags = irq_flags(p->triggering, p->polarity, p->sharable); + __set_bit(p->interrupts[i], map.bits); - pnp_register_irq_resource(dev, option, irq); + flags = irq_flags(p->triggering, p->polarity, p->sharable); + pnp_register_irq_resource(dev, option, &map, flags); } static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, @@ -453,123 +448,90 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, struct acpi_resource_extended_irq *p) { int i; - struct pnp_irq *irq; + pnp_irq_mask_t map; + unsigned char flags; if (p->interrupt_count == 0) return; - irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); - if (!irq) - return; + bitmap_zero(map.bits, PNP_IRQ_NR); for (i = 0; i < p->interrupt_count; i++) if (p->interrupts[i]) - __set_bit(p->interrupts[i], irq->map.bits); - irq->flags = irq_flags(p->triggering, p->polarity, p->sharable); + __set_bit(p->interrupts[i], map.bits); - pnp_register_irq_resource(dev, option, irq); + flags = irq_flags(p->triggering, p->polarity, p->sharable); + pnp_register_irq_resource(dev, option, &map, flags); } static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, struct pnp_option *option, struct acpi_resource_io *io) { - struct pnp_port *port; + unsigned char flags = 0; if (io->address_length == 0) return; - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = io->minimum; - port->max = io->maximum; - port->align = io->alignment; - port->size = io->address_length; - port->flags = ACPI_DECODE_16 == io->io_decode ? - IORESOURCE_IO_16BIT_ADDR : 0; - pnp_register_port_resource(dev, option, port); + + if (io->io_decode == ACPI_DECODE_16) + flags = IORESOURCE_IO_16BIT_ADDR; + pnp_register_port_resource(dev, option, io->minimum, io->maximum, + io->alignment, io->address_length, flags); } static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, struct pnp_option *option, struct acpi_resource_fixed_io *io) { - struct pnp_port *port; - if (io->address_length == 0) return; - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = port->max = io->address; - port->size = io->address_length; - port->align = 0; - port->flags = IORESOURCE_IO_FIXED; - pnp_register_port_resource(dev, option, port); + + pnp_register_port_resource(dev, option, io->address, io->address, 0, + io->address_length, IORESOURCE_IO_FIXED); } static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, struct pnp_option *option, struct acpi_resource_memory24 *p) { - struct pnp_mem *mem; + unsigned char flags = 0; if (p->address_length == 0) return; - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = p->minimum; - mem->max = p->maximum; - mem->align = p->alignment; - mem->size = p->address_length; - mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? - IORESOURCE_MEM_WRITEABLE : 0; - - pnp_register_mem_resource(dev, option, mem); + if (p->write_protect == ACPI_READ_WRITE_MEMORY) + flags = IORESOURCE_MEM_WRITEABLE; + pnp_register_mem_resource(dev, option, p->minimum, p->maximum, + p->alignment, p->address_length, flags); } static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, struct pnp_option *option, struct acpi_resource_memory32 *p) { - struct pnp_mem *mem; + unsigned char flags = 0; if (p->address_length == 0) return; - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = p->minimum; - mem->max = p->maximum; - mem->align = p->alignment; - mem->size = p->address_length; - mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? - IORESOURCE_MEM_WRITEABLE : 0; - - pnp_register_mem_resource(dev, option, mem); + if (p->write_protect == ACPI_READ_WRITE_MEMORY) + flags = IORESOURCE_MEM_WRITEABLE; + pnp_register_mem_resource(dev, option, p->minimum, p->maximum, + p->alignment, p->address_length, flags); } static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, struct pnp_option *option, struct acpi_resource_fixed_memory32 *p) { - struct pnp_mem *mem; + unsigned char flags = 0; if (p->address_length == 0) return; - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = mem->max = p->address; - mem->size = p->address_length; - mem->align = 0; - mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? - IORESOURCE_MEM_WRITEABLE : 0; - - pnp_register_mem_resource(dev, option, mem); + if (p->write_protect == ACPI_READ_WRITE_MEMORY) + flags = IORESOURCE_MEM_WRITEABLE; + pnp_register_mem_resource(dev, option, p->address, p->address, + 0, p->address_length, flags); } static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, @@ -578,8 +540,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, { struct acpi_resource_address64 addr, *p = &addr; acpi_status status; - struct pnp_mem *mem; - struct pnp_port *port; + unsigned char flags = 0; status = acpi_resource_to_address64(r, p); if (!ACPI_SUCCESS(status)) { @@ -592,26 +553,14 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, return; if (p->resource_type == ACPI_MEMORY_RANGE) { - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = mem->max = p->minimum; - mem->size = p->address_length; - mem->align = 0; - mem->flags = (p->info.mem.write_protect == - ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE - : 0; - pnp_register_mem_resource(dev, option, mem); - } else if (p->resource_type == ACPI_IO_RANGE) { - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = port->max = p->minimum; - port->size = p->address_length; - port->align = 0; - port->flags = IORESOURCE_IO_FIXED; - pnp_register_port_resource(dev, option, port); - } + if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) + flags = IORESOURCE_MEM_WRITEABLE; + pnp_register_mem_resource(dev, option, p->minimum, p->minimum, + 0, p->address_length, flags); + } else if (p->resource_type == ACPI_IO_RANGE) + pnp_register_port_resource(dev, option, p->minimum, p->minimum, + 0, p->address_length, + IORESOURCE_IO_FIXED); } struct acpipnp_parse_option_s { diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index dd2ea7b..26fb04c 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -218,116 +218,96 @@ static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_mem *mem; - - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = ((p[5] << 8) | p[4]) << 8; - mem->max = ((p[7] << 8) | p[6]) << 8; - mem->align = (p[9] << 8) | p[8]; - mem->size = ((p[11] << 8) | p[10]) << 8; - mem->flags = p[3]; - pnp_register_mem_resource(dev, option, mem); + resource_size_t min, max, align, len; + unsigned char flags; + + min = ((p[5] << 8) | p[4]) << 8; + max = ((p[7] << 8) | p[6]) << 8; + align = (p[9] << 8) | p[8]; + len = ((p[11] << 8) | p[10]) << 8; + flags = p[3]; + pnp_register_mem_resource(dev, option, min, max, align, len, flags); } static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_mem *mem; - - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; - mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; - mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; - mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; - mem->flags = p[3]; - pnp_register_mem_resource(dev, option, mem); + resource_size_t min, max, align, len; + unsigned char flags; + + min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; + max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; + align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; + len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; + flags = p[3]; + pnp_register_mem_resource(dev, option, min, max, align, len, flags); } static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_mem *mem; - - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) - return; - mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; - mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; - mem->align = 0; - mem->flags = p[3]; - pnp_register_mem_resource(dev, option, mem); + resource_size_t base, len; + unsigned char flags; + + base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; + len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; + flags = p[3]; + pnp_register_mem_resource(dev, option, base, base, 0, len, flags); } static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_irq *irq; unsigned long bits; + pnp_irq_mask_t map; + unsigned char flags = IORESOURCE_IRQ_HIGHEDGE; - irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); - if (!irq) - return; bits = (p[2] << 8) | p[1]; - bitmap_copy(irq->map.bits, &bits, 16); + + bitmap_zero(map.bits, PNP_IRQ_NR); + bitmap_copy(map.bits, &bits, 16); + if (size > 2) - irq->flags = p[3]; - else - irq->flags = IORESOURCE_IRQ_HIGHEDGE; - pnp_register_irq_resource(dev, option, irq); + flags = p[3]; + + pnp_register_irq_resource(dev, option, &map, flags); } static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_dma *dma; - - dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); - if (!dma) - return; - dma->map = p[1]; - dma->flags = p[2]; - pnp_register_dma_resource(dev, option, dma); + pnp_register_dma_resource(dev, option, p[1], p[2]); } static __init void pnpbios_parse_port_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_port *port; - - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = (p[3] << 8) | p[2]; - port->max = (p[5] << 8) | p[4]; - port->align = p[6]; - port->size = p[7]; - port->flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0; - pnp_register_port_resource(dev, option, port); + resource_size_t min, max, align, len; + unsigned char flags; + + min = (p[3] << 8) | p[2]; + max = (p[5] << 8) | p[4]; + align = p[6]; + len = p[7]; + flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0; + pnp_register_port_resource(dev, option, min, max, align, len, flags); } static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, unsigned char *p, int size, struct pnp_option *option) { - struct pnp_port *port; - - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) - return; - port->min = port->max = (p[2] << 8) | p[1]; - port->size = p[3]; - port->align = 0; - port->flags = IORESOURCE_IO_FIXED; - pnp_register_port_resource(dev, option, port); + resource_size_t base, len; + + base = (p[2] << 8) | p[1]; + len = p[3]; + pnp_register_port_resource(dev, option, base, base, 0, len, + IORESOURCE_IO_FIXED); } static __init unsigned char * diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 391828c..6114549 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -78,13 +78,20 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, } int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_irq *data) + pnp_irq_mask_t *map, unsigned char flags) { - struct pnp_irq *ptr; + struct pnp_irq *data, *ptr; #ifdef DEBUG char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */ #endif + data = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->map = *map; + data->flags = flags; + ptr = option->irq; while (ptr && ptr->next) ptr = ptr->next; @@ -112,9 +119,16 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, } int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_dma *data) + unsigned char map, unsigned char flags) { - struct pnp_dma *ptr; + struct pnp_dma *data, *ptr; + + data = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->map = map; + data->flags = flags; ptr = option->dma; while (ptr && ptr->next) @@ -130,9 +144,21 @@ int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, } int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_port *data) + resource_size_t min, resource_size_t max, + resource_size_t align, resource_size_t size, + unsigned char flags) { - struct pnp_port *ptr; + struct pnp_port *data, *ptr; + + data = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->min = min; + data->max = max; + data->align = align; + data->size = size; + data->flags = flags; ptr = option->port; while (ptr && ptr->next) @@ -152,9 +178,21 @@ int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, } int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, - struct pnp_mem *data) + resource_size_t min, resource_size_t max, + resource_size_t align, resource_size_t size, + unsigned char flags) { - struct pnp_mem *ptr; + struct pnp_mem *data, *ptr; + + data = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->min = min; + data->max = max; + data->align = align; + data->size = size; + data->flags = flags; ptr = option->mem; while (ptr && ptr->next) -- cgit v0.10.2 From fe2cf598e6942abd8fb70fee230d74b1a1eae0d1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:12 -0600 Subject: PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR ACPI Extended Interrupt Descriptors can encode 32-bit interrupt numbers, so an interrupt number may exceed the size of the bitmap we use to track possible IRQ settings. To avoid corrupting memory, complain and ignore too-large interrupt numbers. There's similar code in pnpacpi_parse_irq_option(), but I didn't change that because the small IRQ descriptor can only encode IRQs 0-15, which do not exceed bitmap size. In the future, we could handle IRQ numbers greater than PNP_IRQ_NR by replacing the bitmap with a table or list. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3aaf406..851c773 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -455,9 +455,16 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, return; bitmap_zero(map.bits, PNP_IRQ_NR); - for (i = 0; i < p->interrupt_count; i++) - if (p->interrupts[i]) - __set_bit(p->interrupts[i], map.bits); + for (i = 0; i < p->interrupt_count; i++) { + if (p->interrupts[i]) { + if (p->interrupts[i] < PNP_IRQ_NR) + __set_bit(p->interrupts[i], map.bits); + else + dev_err(&dev->dev, "ignoring IRQ %d option " + "(too large for %d entry bitmap)\n", + p->interrupts[i], PNP_IRQ_NR); + } + } flags = irq_flags(p->triggering, p->polarity, p->sharable); pnp_register_irq_resource(dev, option, &map, flags); -- cgit v0.10.2 From 2d29a7a794c5bae982955cd5dd0a76e766e57f39 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:13 -0600 Subject: PNP: rename pnp_register_*_resource() local variables No functional change; just rename "data" to something more descriptive. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 6114549..a795864 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -80,40 +80,40 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, pnp_irq_mask_t *map, unsigned char flags) { - struct pnp_irq *data, *ptr; + struct pnp_irq *irq, *ptr; #ifdef DEBUG char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */ #endif - data = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); - if (!data) + irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); + if (!irq) return -ENOMEM; - data->map = *map; - data->flags = flags; + irq->map = *map; + irq->flags = flags; ptr = option->irq; while (ptr && ptr->next) ptr = ptr->next; if (ptr) - ptr->next = data; + ptr->next = irq; else - option->irq = data; + option->irq = irq; #ifdef CONFIG_PCI { int i; for (i = 0; i < 16; i++) - if (test_bit(i, data->map.bits)) + if (test_bit(i, irq->map.bits)) pcibios_penalize_isa_irq(i, 0); } #endif #ifdef DEBUG - bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR); + bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR); dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf, - data->flags); + irq->flags); #endif return 0; } @@ -121,25 +121,25 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, unsigned char map, unsigned char flags) { - struct pnp_dma *data, *ptr; + struct pnp_dma *dma, *ptr; - data = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); - if (!data) + dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); + if (!dma) return -ENOMEM; - data->map = map; - data->flags = flags; + dma->map = map; + dma->flags = flags; ptr = option->dma; while (ptr && ptr->next) ptr = ptr->next; if (ptr) - ptr->next = data; + ptr->next = dma; else - option->dma = data; + option->dma = dma; - dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map, - data->flags); + dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", dma->map, + dma->flags); return 0; } @@ -148,32 +148,32 @@ int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, resource_size_t align, resource_size_t size, unsigned char flags) { - struct pnp_port *data, *ptr; + struct pnp_port *port, *ptr; - data = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!data) + port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); + if (!port) return -ENOMEM; - data->min = min; - data->max = max; - data->align = align; - data->size = size; - data->flags = flags; + port->min = min; + port->max = max; + port->align = align; + port->size = size; + port->flags = flags; ptr = option->port; while (ptr && ptr->next) ptr = ptr->next; if (ptr) - ptr->next = data; + ptr->next = port; else - option->port = data; + option->port = port; dev_dbg(&dev->dev, " io " "min %#llx max %#llx align %lld size %lld flags %#x\n", - (unsigned long long) data->min, - (unsigned long long) data->max, - (unsigned long long) data->align, - (unsigned long long) data->size, data->flags); + (unsigned long long) port->min, + (unsigned long long) port->max, + (unsigned long long) port->align, + (unsigned long long) port->size, port->flags); return 0; } @@ -182,32 +182,32 @@ int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, resource_size_t align, resource_size_t size, unsigned char flags) { - struct pnp_mem *data, *ptr; + struct pnp_mem *mem, *ptr; - data = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!data) + mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); + if (!mem) return -ENOMEM; - data->min = min; - data->max = max; - data->align = align; - data->size = size; - data->flags = flags; + mem->min = min; + mem->max = max; + mem->align = align; + mem->size = size; + mem->flags = flags; ptr = option->mem; while (ptr && ptr->next) ptr = ptr->next; if (ptr) - ptr->next = data; + ptr->next = mem; else - option->mem = data; + option->mem = mem; dev_dbg(&dev->dev, " mem " "min %#llx max %#llx align %lld size %lld flags %#x\n", - (unsigned long long) data->min, - (unsigned long long) data->max, - (unsigned long long) data->align, - (unsigned long long) data->size, data->flags); + (unsigned long long) mem->min, + (unsigned long long) mem->max, + (unsigned long long) mem->align, + (unsigned long long) mem->size, mem->flags); return 0; } -- cgit v0.10.2 From d5ebde6ef5c2d51828f975a81d7d0e58bccfd833 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:14 -0600 Subject: PNP: support optional IRQ resources This patch adds an IORESOURCE_IRQ_OPTIONAL flag for use when assigning resources to a device. If the flag is set and we are unable to assign an IRQ to the device, we can leave the IRQ disabled but allow the overall resource allocation to succeed. Some devices request an IRQ, but can run without an IRQ (possibly with degraded performance). This flag lets us run the device without the IRQ instead of just leaving the device disabled. This is a reimplementation of this previous change by Rene Herman : http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b73a223661ed137c5d3d2635f954382e94f5a43 I reimplemented this for two reasons: - to prepare for converting all resource options into a single linked list, as opposed to the per-resource-type lists we have now, and - to preserve the order and number of resource options. In PNPBIOS and ACPI, we configure a device by giving firmware a list of resource assignments. It is important that this list has exactly the same number of resources, in the same order, as the "template" list we got from the firmware in the first place. The problem of a sound card MPU401 being left disabled for want of an IRQ was reported by Uwe Bugla . Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index b09f67d..7a9fb55 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -90,6 +90,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, pnp_printf(buffer, " High-Level"); if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) pnp_printf(buffer, " Low-Level"); + if (irq->flags & IORESOURCE_IRQ_OPTIONAL) + pnp_printf(buffer, " (optional)"); pnp_printf(buffer, "\n"); } diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 7ea9e1e..a20accb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -153,6 +153,15 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) goto __add; } } + + if (rule->flags & IORESOURCE_IRQ_OPTIONAL) { + res->start = -1; + res->end = -1; + res->flags |= IORESOURCE_DISABLED; + dev_dbg(&dev->dev, " irq %d disabled (optional)\n", idx); + goto __add; + } + dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); return -EBUSY; diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 48e6017..e8515ce 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -121,34 +121,46 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) struct pnp_option *res; /* - * Build a functional IRQ-less variant of each MPU option. + * Build a functional IRQ-optional variant of each MPU option. */ for (res = dev->dependent; res; res = res->next) { struct pnp_option *curr; struct pnp_port *port; - struct pnp_port *copy; + struct pnp_port *copy_port; + struct pnp_irq *irq; + struct pnp_irq *copy_irq; port = res->port; - if (!port || !res->irq) + irq = res->irq; + if (!port || !irq) continue; - copy = pnp_alloc(sizeof *copy); - if (!copy) + copy_port = pnp_alloc(sizeof *copy_port); + if (!copy_port) + break; + + copy_irq = pnp_alloc(sizeof *copy_irq); + if (!copy_irq) { + kfree(copy_port); break; + } + + *copy_port = *port; + copy_port->next = NULL; - copy->min = port->min; - copy->max = port->max; - copy->align = port->align; - copy->size = port->size; - copy->flags = port->flags; + *copy_irq = *irq; + copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL; + copy_irq->next = NULL; curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); if (!curr) { - kfree(copy); + kfree(copy_port); + kfree(copy_irq); break; } - curr->port = copy; + curr->port = copy_port; + curr->irq = copy_irq; if (prev) prev->next = curr; @@ -157,7 +169,7 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) prev = curr; } if (head) - dev_info(&dev->dev, "adding IRQ-less MPU options\n"); + dev_info(&dev->dev, "adding IRQ-optional MPU options\n"); return head; } @@ -167,10 +179,6 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) struct pnp_option *res; struct pnp_irq *irq; - /* - * Distribute the independent IRQ over the dependent options - */ - res = dev->independent; if (!res) return; @@ -179,33 +187,8 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) if (!irq || irq->next) return; - res = dev->dependent; - if (!res) - return; - - while (1) { - struct pnp_irq *copy; - - copy = pnp_alloc(sizeof *copy); - if (!copy) - break; - - bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR); - copy->flags = irq->flags; - - copy->next = res->irq; /* Yes, this is NULL */ - res->irq = copy; - - if (!res->next) - break; - res = res->next; - } - kfree(irq); - - res->next = quirk_isapnp_mpu_options(dev); - - res = dev->independent; - res->irq = NULL; + irq->flags |= IORESOURCE_IRQ_OPTIONAL; + dev_info(&dev->dev, "made independent IRQ optional\n"); } static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 39db059..2cd07cc 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -59,6 +59,7 @@ struct resource_list { #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) #define IORESOURCE_IRQ_LOWLEVEL (1<<3) #define IORESOURCE_IRQ_SHAREABLE (1<<4) +#define IORESOURCE_IRQ_OPTIONAL (1<<5) /* PnP DMA specific bits (IORESOURCE_BITS) */ #define IORESOURCE_DMA_TYPE_MASK (3<<0) -- cgit v0.10.2 From e2a1a6f1cfaf6ee770a8700e5df8a3708dae503b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:15 -0600 Subject: PNP: remove extra 0x100 bit from option priority When building resource options, ISAPNP and PNPBIOS set the priority to something like "0x100 | PNP_RES_PRIORITY_ACCEPTABLE", but we immediately mask off the 0x100 again in pnp_build_option(), so that bit looks superfluous. Thanks to Rene Herman for pointing this out. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 3f75fdb..90718be 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -582,7 +582,7 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size) static int __init isapnp_create_device(struct pnp_card *card, unsigned short size) { - int number = 0, skip = 0, priority = 0, compat = 0; + int number = 0, skip = 0, priority, compat = 0; unsigned char type, tmp[17]; struct pnp_option *option; struct pnp_dev *dev; @@ -621,7 +621,6 @@ static int __init isapnp_create_device(struct pnp_card *card, } else { skip = 1; } - priority = 0; compat = 0; break; case _STAG_COMPATDEVID: @@ -650,10 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card, case _STAG_STARTDEP: if (size > 1) goto __skip; - priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE; + priority = PNP_RES_PRIORITY_ACCEPTABLE; if (size > 0) { isapnp_peek(tmp, size); - priority = 0x100 | tmp[0]; + priority = tmp[0]; size = 0; } option = pnp_register_dependent_option(dev, priority); @@ -663,7 +662,6 @@ static int __init isapnp_create_device(struct pnp_card *card, case _STAG_ENDDEP: if (size != 0) goto __skip; - priority = 0; dev_dbg(&dev->dev, "end dependent options\n"); break; case _STAG_IOPORT: diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 851c773..e114b3d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -579,7 +579,7 @@ struct acpipnp_parse_option_s { static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, void *data) { - int priority = 0; + int priority; struct acpipnp_parse_option_s *parse_data = data; struct pnp_dev *dev = parse_data->dev; struct pnp_option *option = parse_data->option; diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 26fb04c..db23ba7 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -315,7 +315,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, struct pnp_dev *dev) { unsigned int len, tag; - int priority = 0; + int priority; struct pnp_option *option, *option_independent; if (!p) @@ -389,9 +389,9 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, case SMALL_TAG_STARTDEP: if (len > 1) goto len_err; - priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE; + priority = PNP_RES_PRIORITY_ACCEPTABLE; if (len > 0) - priority = 0x100 | p[1]; + priority = p[1]; option = pnp_register_dependent_option(dev, priority); if (!option) return NULL; -- cgit v0.10.2 From bbe413b4fc7f791248c7ee00ce7b3778491a3700 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:16 -0600 Subject: ISAPNP: handle independent options following dependent ones The ISAPNP spec recommends that independent options precede dependent ones, but this is not actually required. The current ISAPNP code incorrectly puts such trailing independent options at the end of the last dependent option list. This patch fixes that bug by resetting the current option list to the independent list when we see an "End Dependent Functions" tag. PNPBIOS and PNPACPI handle this the same way. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 90718be..53cc4d6 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -584,14 +584,14 @@ static int __init isapnp_create_device(struct pnp_card *card, { int number = 0, skip = 0, priority, compat = 0; unsigned char type, tmp[17]; - struct pnp_option *option; + struct pnp_option *option, *option_independent; struct pnp_dev *dev; u32 eisa_id; char id[8]; if ((dev = isapnp_parse_device(card, size, number++)) == NULL) return 1; - option = pnp_register_independent_option(dev); + option_independent = option = pnp_register_independent_option(dev); if (!option) { kfree(dev); return 1; @@ -613,6 +613,7 @@ static int __init isapnp_create_device(struct pnp_card *card, size = 0; skip = 0; option = pnp_register_independent_option(dev); + option_independent = option; if (!option) { kfree(dev); return 1; @@ -662,6 +663,10 @@ static int __init isapnp_create_device(struct pnp_card *card, case _STAG_ENDDEP: if (size != 0) goto __skip; + if (option_independent == option) + dev_warn(&dev->dev, "missing " + "_STAG_STARTDEP tag\n"); + option = option_independent; dev_dbg(&dev->dev, "end dependent options\n"); break; case _STAG_IOPORT: -- cgit v0.10.2 From 1f32ca31e7409d37c1b25e5f81840fb184380cdf Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:17 -0600 Subject: PNP: convert resource options to single linked list ISAPNP, PNPBIOS, and ACPI describe the "possible resource settings" of a device, i.e., the possibilities an OS bus driver has when it assigns I/O port, MMIO, and other resources to the device. PNP used to maintain this "possible resource setting" information in one independent option structure and a list of dependent option structures for each device. Each of these option structures had lists of I/O, memory, IRQ, and DMA resources, for example: dev independent options ind-io0 -> ind-io1 ... ind-mem0 -> ind-mem1 ... ... dependent option set 0 dep0-io0 -> dep0-io1 ... dep0-mem0 -> dep0-mem1 ... ... dependent option set 1 dep1-io0 -> dep1-io1 ... dep1-mem0 -> dep1-mem1 ... ... ... This data structure was designed for ISAPNP, where the OS configures device resource settings by writing directly to configuration registers. The OS can write the registers in arbitrary order much like it writes PCI BARs. However, for PNPBIOS and ACPI devices, the OS uses firmware interfaces that perform device configuration, and it is important to pass the desired settings to those interfaces in the correct order. The OS learns the correct order by using firmware interfaces that return the "current resource settings" and "possible resource settings," but the option structures above doesn't store the ordering information. This patch replaces the independent and dependent lists with a single list of options. For example, a device might have possible resource settings like this: dev options ind-io0 -> dep0-io0 -> dep1->io0 -> ind-io1 ... All the possible settings are in the same list, in the order they come from the firmware "possible resource settings" list. Each entry is tagged with an independent/dependent flag. Dependent entries also have a "set number" and an optional priority value. All dependent entries must be assigned from the same set. For example, the OS can use all the entries from dependent set 0, or all the entries from dependent set 1, but it cannot mix entries from set 0 with entries from set 1. Prior to this patch PNP didn't keep track of the order of this list, and it assigned all independent options first, then all dependent ones. Using the example above, that resulted in a "desired configuration" list like this: ind->io0 -> ind->io1 -> depN-io0 ... instead of the list the firmware expects, which looks like this: ind->io0 -> depN-io0 -> ind-io1 ... Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Acked-by: Rene Herman Signed-off-by: Len Brown diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 360c638..e3fa9a2 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -1,3 +1,8 @@ +/* + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas + */ + extern spinlock_t pnp_lock; void *pnp_alloc(long size); @@ -25,8 +30,6 @@ struct pnp_port { resource_size_t align; /* align boundary */ resource_size_t size; /* size of range */ unsigned char flags; /* port flags */ - unsigned char pad; /* pad */ - struct pnp_port *next; /* next port */ }; #define PNP_IRQ_NR 256 @@ -35,14 +38,11 @@ typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t; struct pnp_irq { pnp_irq_mask_t map; /* bitmap for IRQ lines */ unsigned char flags; /* IRQ flags */ - unsigned char pad; /* pad */ - struct pnp_irq *next; /* next IRQ */ }; struct pnp_dma { unsigned char map; /* bitmask for DMA channels */ unsigned char flags; /* DMA flags */ - struct pnp_dma *next; /* next port */ }; struct pnp_mem { @@ -51,44 +51,91 @@ struct pnp_mem { resource_size_t align; /* align boundary */ resource_size_t size; /* size of range */ unsigned char flags; /* memory flags */ - unsigned char pad; /* pad */ - struct pnp_mem *next; /* next memory resource */ }; +#define PNP_OPTION_DEPENDENT 0x80000000 +#define PNP_OPTION_SET_MASK 0xffff +#define PNP_OPTION_SET_SHIFT 12 +#define PNP_OPTION_PRIORITY_MASK 0xfff +#define PNP_OPTION_PRIORITY_SHIFT 0 + #define PNP_RES_PRIORITY_PREFERRED 0 #define PNP_RES_PRIORITY_ACCEPTABLE 1 #define PNP_RES_PRIORITY_FUNCTIONAL 2 -#define PNP_RES_PRIORITY_INVALID 65535 +#define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK struct pnp_option { - unsigned short priority; /* priority */ - struct pnp_port *port; /* first port */ - struct pnp_irq *irq; /* first IRQ */ - struct pnp_dma *dma; /* first DMA */ - struct pnp_mem *mem; /* first memory resource */ - struct pnp_option *next; /* used to chain dependent resources */ + struct list_head list; + unsigned int flags; /* independent/dependent, set, priority */ + + unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */ + union { + struct pnp_port port; + struct pnp_irq irq; + struct pnp_dma dma; + struct pnp_mem mem; + } u; }; -struct pnp_option *pnp_build_option(int priority); -struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); -struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, - int priority); -int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, pnp_irq_mask_t *map, unsigned char flags); -int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, unsigned char map, unsigned char flags); -int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t size, unsigned char flags); -int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t size, unsigned char flags); + +static inline int pnp_option_is_dependent(struct pnp_option *option) +{ + return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0; +} + +static inline unsigned int pnp_option_set(struct pnp_option *option) +{ + return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK; +} + +static inline unsigned int pnp_option_priority(struct pnp_option *option) +{ + return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) & + PNP_OPTION_PRIORITY_MASK; +} + +static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev, + int priority) +{ + unsigned int flags; + + if (priority > PNP_RES_PRIORITY_FUNCTIONAL) { + dev_warn(&dev->dev, "invalid dependent option priority %d " + "clipped to %d", priority, + PNP_RES_PRIORITY_INVALID); + priority = PNP_RES_PRIORITY_INVALID; + } + + flags = PNP_OPTION_DEPENDENT | + ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) << + PNP_OPTION_SET_SHIFT) | + ((priority & PNP_OPTION_PRIORITY_MASK) << + PNP_OPTION_PRIORITY_SHIFT); + + dev->num_dependent_sets++; + + return flags; +} + +char *pnp_option_priority_name(struct pnp_option *option); +void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option); + void pnp_init_resources(struct pnp_dev *dev); void pnp_fixup_device(struct pnp_dev *dev); -void pnp_free_option(struct pnp_option *option); +void pnp_free_options(struct pnp_dev *dev); int __pnp_add_device(struct pnp_dev *dev); void __pnp_remove_device(struct pnp_dev *dev); diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 7182da9..a411582 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -118,10 +118,9 @@ static void pnp_release_device(struct device *dmdev) { struct pnp_dev *dev = to_pnp_dev(dmdev); - pnp_free_option(dev->independent); - pnp_free_option(dev->dependent); pnp_free_ids(dev); pnp_free_resources(dev); + pnp_free_options(dev); kfree(dev); } @@ -135,6 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid return NULL; INIT_LIST_HEAD(&dev->resources); + INIT_LIST_HEAD(&dev->options); dev->protocol = protocol; dev->number = id; dev->dma_mask = DMA_24BIT_MASK; diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 7a9fb55..a876ecf 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -3,6 +3,8 @@ * * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela * Copyright 2002 Adam Belay + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas */ #include @@ -184,39 +186,22 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, } static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, - struct pnp_option *option, int dep) + struct pnp_option *option) { - char *s; - struct pnp_port *port; - struct pnp_irq *irq; - struct pnp_dma *dma; - struct pnp_mem *mem; - - if (dep) { - switch (option->priority) { - case PNP_RES_PRIORITY_PREFERRED: - s = "preferred"; - break; - case PNP_RES_PRIORITY_ACCEPTABLE: - s = "acceptable"; - break; - case PNP_RES_PRIORITY_FUNCTIONAL: - s = "functional"; - break; - default: - s = "invalid"; - } - pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s); + switch (option->type) { + case IORESOURCE_IO: + pnp_print_port(buffer, space, &option->u.port); + break; + case IORESOURCE_MEM: + pnp_print_mem(buffer, space, &option->u.mem); + break; + case IORESOURCE_IRQ: + pnp_print_irq(buffer, space, &option->u.irq); + break; + case IORESOURCE_DMA: + pnp_print_dma(buffer, space, &option->u.dma); + break; } - - for (port = option->port; port; port = port->next) - pnp_print_port(buffer, space, port); - for (irq = option->irq; irq; irq = irq->next) - pnp_print_irq(buffer, space, irq); - for (dma = option->dma; dma; dma = dma->next) - pnp_print_dma(buffer, space, dma); - for (mem = option->mem; mem; mem = mem->next) - pnp_print_mem(buffer, space, mem); } static ssize_t pnp_show_options(struct device *dmdev, @@ -224,9 +209,9 @@ static ssize_t pnp_show_options(struct device *dmdev, { struct pnp_dev *dev = to_pnp_dev(dmdev); pnp_info_buffer_t *buffer; - struct pnp_option *independent = dev->independent; - struct pnp_option *dependent = dev->dependent; - int ret, dep = 1; + struct pnp_option *option; + int ret, dep = 0, set = 0; + char *indent; buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); if (!buffer) @@ -235,14 +220,24 @@ static ssize_t pnp_show_options(struct device *dmdev, buffer->len = PAGE_SIZE; buffer->buffer = buf; buffer->curr = buffer->buffer; - if (independent) - pnp_print_option(buffer, "", independent, 0); - while (dependent) { - pnp_print_option(buffer, " ", dependent, dep); - dependent = dependent->next; - dep++; + list_for_each_entry(option, &dev->options, list) { + if (pnp_option_is_dependent(option)) { + indent = " "; + if (!dep || pnp_option_set(option) != set) { + set = pnp_option_set(option); + dep = 1; + pnp_printf(buffer, "Dependent: %02i - " + "Priority %s\n", set, + pnp_option_priority_name(option)); + } + } else { + dep = 0; + indent = ""; + } + pnp_print_option(buffer, indent, option); } + ret = (buffer->curr - buf); kfree(buffer); return ret; diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 53cc4d6..101a835 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -429,7 +429,7 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, * Add IRQ resource to resources list. */ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[3]; @@ -446,27 +446,27 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, if (size > 2) flags = tmp[2]; - pnp_register_irq_resource(dev, option, &map, flags); + pnp_register_irq_resource(dev, option_flags, &map, flags); } /* * Add DMA resource to resources list. */ static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[2]; isapnp_peek(tmp, size); - pnp_register_dma_resource(dev, option, tmp[0], tmp[1]); + pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]); } /* * Add port resource to resources list. */ static void __init isapnp_parse_port_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[7]; @@ -479,14 +479,15 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev, align = tmp[5]; len = tmp[6]; flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0; - pnp_register_port_resource(dev, option, min, max, align, len, flags); + pnp_register_port_resource(dev, option_flags, + min, max, align, len, flags); } /* * Add fixed port resource to resources list. */ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[3]; @@ -495,7 +496,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, isapnp_peek(tmp, size); base = (tmp[1] << 8) | tmp[0]; len = tmp[2]; - pnp_register_port_resource(dev, option, base, base, 0, len, + pnp_register_port_resource(dev, option_flags, base, base, 0, len, IORESOURCE_IO_FIXED); } @@ -503,7 +504,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, * Add memory resource to resources list. */ static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[9]; @@ -516,14 +517,15 @@ static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, align = (tmp[6] << 8) | tmp[5]; len = ((tmp[8] << 8) | tmp[7]) << 8; flags = tmp[0]; - pnp_register_mem_resource(dev, option, min, max, align, len, flags); + pnp_register_mem_resource(dev, option_flags, + min, max, align, len, flags); } /* * Add 32-bit memory resource to resources list. */ static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[17]; @@ -536,14 +538,15 @@ static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; flags = tmp[0]; - pnp_register_mem_resource(dev, option, min, max, align, len, flags); + pnp_register_mem_resource(dev, option_flags, + min, max, align, len, flags); } /* * Add 32-bit fixed memory resource to resources list. */ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, int size) { unsigned char tmp[9]; @@ -554,7 +557,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; flags = tmp[0]; - pnp_register_mem_resource(dev, option, base, base, 0, len, flags); + pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags); } /* @@ -584,18 +587,14 @@ static int __init isapnp_create_device(struct pnp_card *card, { int number = 0, skip = 0, priority, compat = 0; unsigned char type, tmp[17]; - struct pnp_option *option, *option_independent; + unsigned int option_flags; struct pnp_dev *dev; u32 eisa_id; char id[8]; if ((dev = isapnp_parse_device(card, size, number++)) == NULL) return 1; - option_independent = option = pnp_register_independent_option(dev); - if (!option) { - kfree(dev); - return 1; - } + option_flags = 0; pnp_add_card_device(card, dev); while (1) { @@ -612,12 +611,7 @@ static int __init isapnp_create_device(struct pnp_card *card, return 1; size = 0; skip = 0; - option = pnp_register_independent_option(dev); - option_independent = option; - if (!option) { - kfree(dev); - return 1; - } + option_flags = 0; pnp_add_card_device(card, dev); } else { skip = 1; @@ -638,13 +632,13 @@ static int __init isapnp_create_device(struct pnp_card *card, case _STAG_IRQ: if (size < 2 || size > 3) goto __skip; - isapnp_parse_irq_resource(dev, option, size); + isapnp_parse_irq_resource(dev, option_flags, size); size = 0; break; case _STAG_DMA: if (size != 2) goto __skip; - isapnp_parse_dma_resource(dev, option, size); + isapnp_parse_dma_resource(dev, option_flags, size); size = 0; break; case _STAG_STARTDEP: @@ -656,29 +650,24 @@ static int __init isapnp_create_device(struct pnp_card *card, priority = tmp[0]; size = 0; } - option = pnp_register_dependent_option(dev, priority); - if (!option) - return 1; + option_flags = pnp_new_dependent_set(dev, priority); break; case _STAG_ENDDEP: if (size != 0) goto __skip; - if (option_independent == option) - dev_warn(&dev->dev, "missing " - "_STAG_STARTDEP tag\n"); - option = option_independent; - dev_dbg(&dev->dev, "end dependent options\n"); + option_flags = 0; break; case _STAG_IOPORT: if (size != 7) goto __skip; - isapnp_parse_port_resource(dev, option, size); + isapnp_parse_port_resource(dev, option_flags, size); size = 0; break; case _STAG_FIXEDIO: if (size != 3) goto __skip; - isapnp_parse_fixed_port_resource(dev, option, size); + isapnp_parse_fixed_port_resource(dev, option_flags, + size); size = 0; break; case _STAG_VENDOR: @@ -686,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card, case _LTAG_MEMRANGE: if (size != 9) goto __skip; - isapnp_parse_mem_resource(dev, option, size); + isapnp_parse_mem_resource(dev, option_flags, size); size = 0; break; case _LTAG_ANSISTR: @@ -701,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card, case _LTAG_MEM32RANGE: if (size != 17) goto __skip; - isapnp_parse_mem32_resource(dev, option, size); + isapnp_parse_mem32_resource(dev, option_flags, size); size = 0; break; case _LTAG_FIXEDMEM32RANGE: if (size != 9) goto __skip; - isapnp_parse_fixed_mem32_resource(dev, option, size); + isapnp_parse_fixed_mem32_resource(dev, option_flags, + size); size = 0; break; case _STAG_END: diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index a20accb..b526eaa 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -3,6 +3,8 @@ * * based on isapnp.c resource management (c) Jaroslav Kysela * Copyright 2003 Adam Belay + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas */ #include @@ -228,102 +230,51 @@ static void pnp_clean_resource_table(struct pnp_dev *dev) /** * pnp_assign_resources - assigns resources to the device based on the specified dependent number * @dev: pointer to the desired device - * @depnum: the dependent function number - * - * Only set depnum to 0 if the device does not have dependent options. + * @set: the dependent function number */ -static int pnp_assign_resources(struct pnp_dev *dev, int depnum) +static int pnp_assign_resources(struct pnp_dev *dev, int set) { - struct pnp_port *port; - struct pnp_mem *mem; - struct pnp_irq *irq; - struct pnp_dma *dma; + struct pnp_option *option; int nport = 0, nmem = 0, nirq = 0, ndma = 0; + int ret = 0; - dbg_pnp_show_resources(dev, "before pnp_assign_resources"); + dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set); mutex_lock(&pnp_res_mutex); pnp_clean_resource_table(dev); - if (dev->independent) { - dev_dbg(&dev->dev, "assigning independent options\n"); - port = dev->independent->port; - mem = dev->independent->mem; - irq = dev->independent->irq; - dma = dev->independent->dma; - while (port) { - if (pnp_assign_port(dev, port, nport) < 0) - goto fail; - nport++; - port = port->next; - } - while (mem) { - if (pnp_assign_mem(dev, mem, nmem) < 0) - goto fail; - nmem++; - mem = mem->next; - } - while (irq) { - if (pnp_assign_irq(dev, irq, nirq) < 0) - goto fail; - nirq++; - irq = irq->next; - } - while (dma) { - if (pnp_assign_dma(dev, dma, ndma) < 0) - goto fail; - ndma++; - dma = dma->next; - } - } - if (depnum) { - struct pnp_option *dep; - int i; - - dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum); - for (i = 1, dep = dev->dependent; i < depnum; - i++, dep = dep->next) - if (!dep) - goto fail; - port = dep->port; - mem = dep->mem; - irq = dep->irq; - dma = dep->dma; - while (port) { - if (pnp_assign_port(dev, port, nport) < 0) - goto fail; - nport++; - port = port->next; - } - while (mem) { - if (pnp_assign_mem(dev, mem, nmem) < 0) - goto fail; - nmem++; - mem = mem->next; - } - while (irq) { - if (pnp_assign_irq(dev, irq, nirq) < 0) - goto fail; - nirq++; - irq = irq->next; - } - while (dma) { - if (pnp_assign_dma(dev, dma, ndma) < 0) - goto fail; - ndma++; - dma = dma->next; + list_for_each_entry(option, &dev->options, list) { + if (pnp_option_is_dependent(option) && + pnp_option_set(option) != set) + continue; + + switch (option->type) { + case IORESOURCE_IO: + ret = pnp_assign_port(dev, &option->u.port, nport++); + break; + case IORESOURCE_MEM: + ret = pnp_assign_mem(dev, &option->u.mem, nmem++); + break; + case IORESOURCE_IRQ: + ret = pnp_assign_irq(dev, &option->u.irq, nirq++); + break; + case IORESOURCE_DMA: + ret = pnp_assign_dma(dev, &option->u.dma, ndma++); + break; + default: + ret = -EINVAL; + break; } - } else if (dev->dependent) - goto fail; - - mutex_unlock(&pnp_res_mutex); - dbg_pnp_show_resources(dev, "after pnp_assign_resources"); - return 1; + if (ret < 0) + break; + } -fail: - pnp_clean_resource_table(dev); mutex_unlock(&pnp_res_mutex); - dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)"); - return 0; + if (ret < 0) { + dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret); + pnp_clean_resource_table(dev); + } else + dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded"); + return ret; } /** @@ -332,29 +283,25 @@ fail: */ int pnp_auto_config_dev(struct pnp_dev *dev) { - struct pnp_option *dep; - int i = 1; + int i, ret; if (!pnp_can_configure(dev)) { dev_dbg(&dev->dev, "configuration not supported\n"); return -ENODEV; } - if (!dev->dependent) { - if (pnp_assign_resources(dev, 0)) + ret = pnp_assign_resources(dev, 0); + if (ret == 0) + return 0; + + for (i = 1; i < dev->num_dependent_sets; i++) { + ret = pnp_assign_resources(dev, i); + if (ret == 0) return 0; - } else { - dep = dev->dependent; - do { - if (pnp_assign_resources(dev, i)) - return 0; - dep = dep->next; - i++; - } while (dep); } dev_err(&dev->dev, "unable to assign resources\n"); - return -EBUSY; + return ret; } /** diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index e114b3d..c2f59f4 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -407,7 +407,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev) } static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_dma *p) { int i; @@ -420,11 +420,11 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, map |= 1 << p->channels[i]; flags = dma_flags(p->type, p->bus_master, p->transfer); - pnp_register_dma_resource(dev, option, map, flags); + pnp_register_dma_resource(dev, option_flags, map, flags); } static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_irq *p) { int i; @@ -440,11 +440,11 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, __set_bit(p->interrupts[i], map.bits); flags = irq_flags(p->triggering, p->polarity, p->sharable); - pnp_register_irq_resource(dev, option, &map, flags); + pnp_register_irq_resource(dev, option_flags, &map, flags); } static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_extended_irq *p) { int i; @@ -467,11 +467,11 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, } flags = irq_flags(p->triggering, p->polarity, p->sharable); - pnp_register_irq_resource(dev, option, &map, flags); + pnp_register_irq_resource(dev, option_flags, &map, flags); } static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_io *io) { unsigned char flags = 0; @@ -481,23 +481,23 @@ static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, if (io->io_decode == ACPI_DECODE_16) flags = IORESOURCE_IO_16BIT_ADDR; - pnp_register_port_resource(dev, option, io->minimum, io->maximum, + pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum, io->alignment, io->address_length, flags); } static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_fixed_io *io) { if (io->address_length == 0) return; - pnp_register_port_resource(dev, option, io->address, io->address, 0, - io->address_length, IORESOURCE_IO_FIXED); + pnp_register_port_resource(dev, option_flags, io->address, io->address, + 0, io->address_length, IORESOURCE_IO_FIXED); } static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_memory24 *p) { unsigned char flags = 0; @@ -507,12 +507,12 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, if (p->write_protect == ACPI_READ_WRITE_MEMORY) flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option, p->minimum, p->maximum, + pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum, p->alignment, p->address_length, flags); } static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_memory32 *p) { unsigned char flags = 0; @@ -522,12 +522,12 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, if (p->write_protect == ACPI_READ_WRITE_MEMORY) flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option, p->minimum, p->maximum, + pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum, p->alignment, p->address_length, flags); } static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource_fixed_memory32 *p) { unsigned char flags = 0; @@ -537,12 +537,12 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, if (p->write_protect == ACPI_READ_WRITE_MEMORY) flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option, p->address, p->address, + pnp_register_mem_resource(dev, option_flags, p->address, p->address, 0, p->address_length, flags); } static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, - struct pnp_option *option, + unsigned int option_flags, struct acpi_resource *r) { struct acpi_resource_address64 addr, *p = &addr; @@ -562,18 +562,18 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, if (p->resource_type == ACPI_MEMORY_RANGE) { if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option, p->minimum, p->minimum, - 0, p->address_length, flags); + pnp_register_mem_resource(dev, option_flags, p->minimum, + p->minimum, 0, p->address_length, + flags); } else if (p->resource_type == ACPI_IO_RANGE) - pnp_register_port_resource(dev, option, p->minimum, p->minimum, - 0, p->address_length, + pnp_register_port_resource(dev, option_flags, p->minimum, + p->minimum, 0, p->address_length, IORESOURCE_IO_FIXED); } struct acpipnp_parse_option_s { - struct pnp_option *option; - struct pnp_option *option_independent; struct pnp_dev *dev; + unsigned int option_flags; }; static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, @@ -582,15 +582,15 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, int priority; struct acpipnp_parse_option_s *parse_data = data; struct pnp_dev *dev = parse_data->dev; - struct pnp_option *option = parse_data->option; + unsigned int option_flags = parse_data->option_flags; switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: - pnpacpi_parse_irq_option(dev, option, &res->data.irq); + pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq); break; case ACPI_RESOURCE_TYPE_DMA: - pnpacpi_parse_dma_option(dev, option, &res->data.dma); + pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: @@ -610,31 +610,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, priority = PNP_RES_PRIORITY_INVALID; break; } - /* TBD: Consider performance/robustness bits */ - option = pnp_register_dependent_option(dev, priority); - if (!option) - return AE_ERROR; - parse_data->option = option; + parse_data->option_flags = pnp_new_dependent_set(dev, priority); break; case ACPI_RESOURCE_TYPE_END_DEPENDENT: - /*only one EndDependentFn is allowed */ - if (!parse_data->option_independent) { - dev_warn(&dev->dev, "more than one EndDependentFn " - "in _PRS\n"); - return AE_ERROR; - } - parse_data->option = parse_data->option_independent; - parse_data->option_independent = NULL; - dev_dbg(&dev->dev, "end dependent options\n"); + parse_data->option_flags = 0; break; case ACPI_RESOURCE_TYPE_IO: - pnpacpi_parse_port_option(dev, option, &res->data.io); + pnpacpi_parse_port_option(dev, option_flags, &res->data.io); break; case ACPI_RESOURCE_TYPE_FIXED_IO: - pnpacpi_parse_fixed_port_option(dev, option, + pnpacpi_parse_fixed_port_option(dev, option_flags, &res->data.fixed_io); break; @@ -643,29 +631,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, break; case ACPI_RESOURCE_TYPE_MEMORY24: - pnpacpi_parse_mem24_option(dev, option, &res->data.memory24); + pnpacpi_parse_mem24_option(dev, option_flags, + &res->data.memory24); break; case ACPI_RESOURCE_TYPE_MEMORY32: - pnpacpi_parse_mem32_option(dev, option, &res->data.memory32); + pnpacpi_parse_mem32_option(dev, option_flags, + &res->data.memory32); break; case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - pnpacpi_parse_fixed_mem32_option(dev, option, + pnpacpi_parse_fixed_mem32_option(dev, option_flags, &res->data.fixed_memory32); break; case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS64: - pnpacpi_parse_address_option(dev, option, res); + pnpacpi_parse_address_option(dev, option_flags, res); break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - pnpacpi_parse_ext_irq_option(dev, option, + pnpacpi_parse_ext_irq_option(dev, option_flags, &res->data.extended_irq); break; @@ -689,12 +679,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) dev_dbg(&dev->dev, "parse resource options\n"); - parse_data.option = pnp_register_independent_option(dev); - if (!parse_data.option) - return -ENOMEM; - - parse_data.option_independent = parse_data.option; parse_data.dev = dev; + parse_data.option_flags = 0; + status = acpi_walk_resources(handle, METHOD_NAME__PRS, pnpacpi_option_resource, &parse_data); diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index db23ba7..ca56767 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -216,7 +216,7 @@ len_err: static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { resource_size_t min, max, align, len; unsigned char flags; @@ -226,12 +226,13 @@ static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, align = (p[9] << 8) | p[8]; len = ((p[11] << 8) | p[10]) << 8; flags = p[3]; - pnp_register_mem_resource(dev, option, min, max, align, len, flags); + pnp_register_mem_resource(dev, option_flags, min, max, align, len, + flags); } static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { resource_size_t min, max, align, len; unsigned char flags; @@ -241,12 +242,13 @@ static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; flags = p[3]; - pnp_register_mem_resource(dev, option, min, max, align, len, flags); + pnp_register_mem_resource(dev, option_flags, min, max, align, len, + flags); } static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { resource_size_t base, len; unsigned char flags; @@ -254,12 +256,12 @@ static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; flags = p[3]; - pnp_register_mem_resource(dev, option, base, base, 0, len, flags); + pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags); } static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { unsigned long bits; pnp_irq_mask_t map; @@ -273,19 +275,19 @@ static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, if (size > 2) flags = p[3]; - pnp_register_irq_resource(dev, option, &map, flags); + pnp_register_irq_resource(dev, option_flags, &map, flags); } static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { - pnp_register_dma_resource(dev, option, p[1], p[2]); + pnp_register_dma_resource(dev, option_flags, p[1], p[2]); } static __init void pnpbios_parse_port_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { resource_size_t min, max, align, len; unsigned char flags; @@ -295,38 +297,35 @@ static __init void pnpbios_parse_port_option(struct pnp_dev *dev, align = p[6]; len = p[7]; flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0; - pnp_register_port_resource(dev, option, min, max, align, len, flags); + pnp_register_port_resource(dev, option_flags, min, max, align, len, + flags); } static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, unsigned char *p, int size, - struct pnp_option *option) + unsigned int option_flags) { resource_size_t base, len; base = (p[2] << 8) | p[1]; len = p[3]; - pnp_register_port_resource(dev, option, base, base, 0, len, + pnp_register_port_resource(dev, option_flags, base, base, 0, len, IORESOURCE_IO_FIXED); } static __init unsigned char * pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, - struct pnp_dev *dev) + struct pnp_dev *dev) { unsigned int len, tag; int priority; - struct pnp_option *option, *option_independent; + unsigned int option_flags; if (!p) return NULL; dev_dbg(&dev->dev, "parse resource options\n"); - - option_independent = option = pnp_register_independent_option(dev); - if (!option) - return NULL; - + option_flags = 0; while ((char *)p < (char *)end) { /* determine the type of tag */ @@ -343,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, case LARGE_TAG_MEM: if (len != 9) goto len_err; - pnpbios_parse_mem_option(dev, p, len, option); + pnpbios_parse_mem_option(dev, p, len, option_flags); break; case LARGE_TAG_MEM32: if (len != 17) goto len_err; - pnpbios_parse_mem32_option(dev, p, len, option); + pnpbios_parse_mem32_option(dev, p, len, option_flags); break; case LARGE_TAG_FIXEDMEM32: if (len != 9) goto len_err; - pnpbios_parse_fixed_mem32_option(dev, p, len, option); + pnpbios_parse_fixed_mem32_option(dev, p, len, + option_flags); break; case SMALL_TAG_IRQ: if (len < 2 || len > 3) goto len_err; - pnpbios_parse_irq_option(dev, p, len, option); + pnpbios_parse_irq_option(dev, p, len, option_flags); break; case SMALL_TAG_DMA: if (len != 2) goto len_err; - pnpbios_parse_dma_option(dev, p, len, option); + pnpbios_parse_dma_option(dev, p, len, option_flags); break; case SMALL_TAG_PORT: if (len != 7) goto len_err; - pnpbios_parse_port_option(dev, p, len, option); + pnpbios_parse_port_option(dev, p, len, option_flags); break; case SMALL_TAG_VENDOR: @@ -383,7 +383,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, case SMALL_TAG_FIXEDPORT: if (len != 3) goto len_err; - pnpbios_parse_fixed_port_option(dev, p, len, option); + pnpbios_parse_fixed_port_option(dev, p, len, + option_flags); break; case SMALL_TAG_STARTDEP: @@ -392,19 +393,13 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, priority = PNP_RES_PRIORITY_ACCEPTABLE; if (len > 0) priority = p[1]; - option = pnp_register_dependent_option(dev, priority); - if (!option) - return NULL; + option_flags = pnp_new_dependent_set(dev, priority); break; case SMALL_TAG_ENDDEP: if (len != 0) goto len_err; - if (option_independent == option) - dev_warn(&dev->dev, "missing " - "SMALL_TAG_STARTDEP tag\n"); - option = option_independent; - dev_dbg(&dev->dev, "end dependent options\n"); + option_flags = 0; break; case SMALL_TAG_END: diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e8515ce..55f55ed 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -5,6 +5,8 @@ * when building up the resource structure for the first time. * * Copyright (c) 2000 Peter Denison + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas * * Heavily based on PCI quirks handling which is * @@ -20,189 +22,207 @@ #include #include "base.h" +static void quirk_awe32_add_ports(struct pnp_dev *dev, + struct pnp_option *option, + unsigned int offset) +{ + struct pnp_option *new_option; + + new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL); + if (!new_option) { + dev_err(&dev->dev, "couldn't add ioport region to option set " + "%d\n", pnp_option_set(option)); + return; + } + + *new_option = *option; + new_option->u.port.min += offset; + new_option->u.port.max += offset; + list_add(&new_option->list, &option->list); + + dev_info(&dev->dev, "added ioport region %#llx-%#llx to set %d\n", + (unsigned long long) new_option->u.port.min, + (unsigned long long) new_option->u.port.max, + pnp_option_set(option)); +} + static void quirk_awe32_resources(struct pnp_dev *dev) { - struct pnp_port *port, *port2, *port3; - struct pnp_option *res = dev->dependent; + struct pnp_option *option; + unsigned int set = ~0; /* - * Unfortunately the isapnp_add_port_resource is too tightly bound - * into the PnP discovery sequence, and cannot be used. Link in the - * two extra ports (at offset 0x400 and 0x800 from the one given) by - * hand. + * Add two extra ioport regions (at offset 0x400 and 0x800 from the + * one given) to every dependent option set. */ - for (; res; res = res->next) { - port2 = pnp_alloc(sizeof(struct pnp_port)); - if (!port2) - return; - port3 = pnp_alloc(sizeof(struct pnp_port)); - if (!port3) { - kfree(port2); - return; + list_for_each_entry(option, &dev->options, list) { + if (pnp_option_is_dependent(option) && + pnp_option_set(option) != set) { + set = pnp_option_set(option); + quirk_awe32_add_ports(dev, option, 0x800); + quirk_awe32_add_ports(dev, option, 0x400); } - port = res->port; - memcpy(port2, port, sizeof(struct pnp_port)); - memcpy(port3, port, sizeof(struct pnp_port)); - port->next = port2; - port2->next = port3; - port2->min += 0x400; - port2->max += 0x400; - port3->min += 0x800; - port3->max += 0x800; - dev_info(&dev->dev, - "AWE32 quirk - added ioports 0x%lx and 0x%lx\n", - (unsigned long)port2->min, - (unsigned long)port3->min); } } static void quirk_cmi8330_resources(struct pnp_dev *dev) { - struct pnp_option *res = dev->dependent; - unsigned long tmp; - - for (; res; res = res->next) { - - struct pnp_irq *irq; - struct pnp_dma *dma; + struct pnp_option *option; + struct pnp_irq *irq; + struct pnp_dma *dma; - for (irq = res->irq; irq; irq = irq->next) { - /* Valid irqs are 5, 7, 10 */ - tmp = 0x04A0; - bitmap_copy(irq->map.bits, &tmp, 16); - } + list_for_each_entry(option, &dev->options, list) { + if (!pnp_option_is_dependent(option)) + continue; - for (dma = res->dma; dma; dma = dma->next) { - /* Valid 8bit dma channels are 1,3 */ + if (option->type == IORESOURCE_IRQ) { + irq = &option->u.irq; + bitmap_zero(irq->map.bits, PNP_IRQ_NR); + __set_bit(5, irq->map.bits); + __set_bit(7, irq->map.bits); + __set_bit(10, irq->map.bits); + dev_info(&dev->dev, "set possible IRQs in " + "option set %d to 5, 7, 10\n", + pnp_option_set(option)); + } else if (option->type == IORESOURCE_DMA) { + dma = &option->u.dma; if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) == - IORESOURCE_DMA_8BIT) - dma->map = 0x000A; + IORESOURCE_DMA_8BIT && + dma->map != 0x0A) { + dev_info(&dev->dev, "changing possible " + "DMA channel mask in option set %d " + "from %#02x to 0x0A (1, 3)\n", + pnp_option_set(option), dma->map); + dma->map = 0x0A; + } } } - dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 " - "and DMA channels to 1, 3\n"); } static void quirk_sb16audio_resources(struct pnp_dev *dev) { + struct pnp_option *option; + unsigned int prev_option_flags = ~0, n = 0; struct pnp_port *port; - struct pnp_option *res = dev->dependent; - int changed = 0; /* - * The default range on the mpu port for these devices is 0x388-0x388. + * The default range on the OPL port for these devices is 0x388-0x388. * Here we increase that range so that two such cards can be * auto-configured. */ + list_for_each_entry(option, &dev->options, list) { + if (prev_option_flags != option->flags) { + prev_option_flags = option->flags; + n = 0; + } - for (; res; res = res->next) { - port = res->port; - if (!port) - continue; - port = port->next; - if (!port) - continue; - port = port->next; - if (!port) - continue; - if (port->min != port->max) - continue; - port->max += 0x70; - changed = 1; + if (pnp_option_is_dependent(option) && + option->type == IORESOURCE_IO) { + n++; + port = &option->u.port; + if (n == 3 && port->min == port->max) { + port->max += 0x70; + dev_info(&dev->dev, "increased option port " + "range from %#llx-%#llx to " + "%#llx-%#llx\n", + (unsigned long long) port->min, + (unsigned long long) port->min, + (unsigned long long) port->min, + (unsigned long long) port->max); + } + } } - if (changed) - dev_info(&dev->dev, "SB audio device quirk - increased port range\n"); } -static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) +static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev, + unsigned int set) { - struct pnp_option *head = NULL; - struct pnp_option *prev = NULL; - struct pnp_option *res; - - /* - * Build a functional IRQ-optional variant of each MPU option. - */ - - for (res = dev->dependent; res; res = res->next) { - struct pnp_option *curr; - struct pnp_port *port; - struct pnp_port *copy_port; - struct pnp_irq *irq; - struct pnp_irq *copy_irq; - - port = res->port; - irq = res->irq; - if (!port || !irq) - continue; + struct pnp_option *tail = NULL, *first_new_option = NULL; + struct pnp_option *option, *new_option; + unsigned int flags; - copy_port = pnp_alloc(sizeof *copy_port); - if (!copy_port) - break; - - copy_irq = pnp_alloc(sizeof *copy_irq); - if (!copy_irq) { - kfree(copy_port); - break; - } + list_for_each_entry(option, &dev->options, list) { + if (pnp_option_is_dependent(option)) + tail = option; + } + if (!tail) { + dev_err(&dev->dev, "no dependent option sets\n"); + return NULL; + } - *copy_port = *port; - copy_port->next = NULL; + flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL); + list_for_each_entry(option, &dev->options, list) { + if (pnp_option_is_dependent(option) && + pnp_option_set(option) == set) { + new_option = kmalloc(sizeof(struct pnp_option), + GFP_KERNEL); + if (!new_option) { + dev_err(&dev->dev, "couldn't clone dependent " + "set %d\n", set); + return NULL; + } - *copy_irq = *irq; - copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL; - copy_irq->next = NULL; + *new_option = *option; + new_option->flags = flags; + if (!first_new_option) + first_new_option = new_option; - curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); - if (!curr) { - kfree(copy_port); - kfree(copy_irq); - break; + list_add(&new_option->list, &tail->list); + tail = new_option; } - curr->port = copy_port; - curr->irq = copy_irq; - - if (prev) - prev->next = curr; - else - head = curr; - prev = curr; } - if (head) - dev_info(&dev->dev, "adding IRQ-optional MPU options\n"); - return head; + return first_new_option; } -static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) + +static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev) { - struct pnp_option *res; + struct pnp_option *new_option; + unsigned int num_sets, i, set; struct pnp_irq *irq; - res = dev->independent; - if (!res) - return; + num_sets = dev->num_dependent_sets; + for (i = 0; i < num_sets; i++) { + new_option = pnp_clone_dependent_set(dev, i); + if (!new_option) + return; - irq = res->irq; - if (!irq || irq->next) - return; + set = pnp_option_set(new_option); + while (new_option && pnp_option_set(new_option) == set) { + if (new_option->type == IORESOURCE_IRQ) { + irq = &new_option->u.irq; + irq->flags |= IORESOURCE_IRQ_OPTIONAL; + } + dbg_pnp_show_option(dev, new_option); + new_option = list_entry(new_option->list.next, + struct pnp_option, list); + } - irq->flags |= IORESOURCE_IRQ_OPTIONAL; - dev_info(&dev->dev, "made independent IRQ optional\n"); + dev_info(&dev->dev, "added dependent option set %d (same as " + "set %d except IRQ optional)\n", set, i); + } } -static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) +static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) { - struct pnp_option *res; + struct pnp_option *option; + struct pnp_irq *irq = NULL; + unsigned int independent_irqs = 0; + + list_for_each_entry(option, &dev->options, list) { + if (option->type == IORESOURCE_IRQ && + !pnp_option_is_dependent(option)) { + independent_irqs++; + irq = &option->u.irq; + } + } - res = dev->dependent; - if (!res) + if (independent_irqs != 1) return; - while (res->next) - res = res->next; - - res->next = quirk_isapnp_mpu_options(dev); + irq->flags |= IORESOURCE_IRQ_OPTIONAL; + dev_info(&dev->dev, "made independent IRQ optional\n"); } #include @@ -297,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = { {"CTL0043", quirk_sb16audio_resources}, {"CTL0044", quirk_sb16audio_resources}, {"CTL0045", quirk_sb16audio_resources}, - /* Add IRQ-less MPU options */ + /* Add IRQ-optional MPU options */ {"ADS7151", quirk_ad1815_mpu_resources}, - {"ADS7181", quirk_isapnp_mpu_resources}, - {"AZT0002", quirk_isapnp_mpu_resources}, + {"ADS7181", quirk_add_irq_optional_dependent_sets}, + {"AZT0002", quirk_add_irq_optional_dependent_sets}, /* PnP resources that might overlap PCI BARs */ {"PNP0c01", quirk_system_pci_resources}, {"PNP0c02", quirk_system_pci_resources}, diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index a795864..d638897 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -3,6 +3,8 @@ * * based on isapnp.c resource management (c) Jaroslav Kysela * Copyright 2003 Adam Belay + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas */ #include @@ -28,78 +30,36 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some * option registration */ -struct pnp_option *pnp_build_option(int priority) +struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, + unsigned int option_flags) { - struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); + struct pnp_option *option; + option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL); if (!option) return NULL; - option->priority = priority & 0xff; - /* make sure the priority is valid */ - if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL) - option->priority = PNP_RES_PRIORITY_INVALID; - - return option; -} - -struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) -{ - struct pnp_option *option; - - option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED); - - /* this should never happen but if it does we'll try to continue */ - if (dev->independent) - dev_err(&dev->dev, "independent resource already registered\n"); - dev->independent = option; - - dev_dbg(&dev->dev, "new independent option\n"); - return option; -} - -struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, - int priority) -{ - struct pnp_option *option; + option->flags = option_flags; + option->type = type; - option = pnp_build_option(priority); - - if (dev->dependent) { - struct pnp_option *parent = dev->dependent; - while (parent->next) - parent = parent->next; - parent->next = option; - } else - dev->dependent = option; - - dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority); + list_add_tail(&option->list, &dev->options); return option; } -int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, pnp_irq_mask_t *map, unsigned char flags) { - struct pnp_irq *irq, *ptr; -#ifdef DEBUG - char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */ -#endif + struct pnp_option *option; + struct pnp_irq *irq; - irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); - if (!irq) + option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags); + if (!option) return -ENOMEM; + irq = &option->u.irq; irq->map = *map; irq->flags = flags; - ptr = option->irq; - while (ptr && ptr->next) - ptr = ptr->next; - if (ptr) - ptr->next = irq; - else - option->irq = irq; - #ifdef CONFIG_PCI { int i; @@ -110,163 +70,81 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, } #endif -#ifdef DEBUG - bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR); - dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf, - irq->flags); -#endif + dbg_pnp_show_option(dev, option); return 0; } -int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, unsigned char map, unsigned char flags) { - struct pnp_dma *dma, *ptr; + struct pnp_option *option; + struct pnp_dma *dma; - dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); - if (!dma) + option = pnp_build_option(dev, IORESOURCE_DMA, option_flags); + if (!option) return -ENOMEM; + dma = &option->u.dma; dma->map = map; dma->flags = flags; - ptr = option->dma; - while (ptr && ptr->next) - ptr = ptr->next; - if (ptr) - ptr->next = dma; - else - option->dma = dma; - - dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", dma->map, - dma->flags); + dbg_pnp_show_option(dev, option); return 0; } -int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t size, unsigned char flags) { - struct pnp_port *port, *ptr; + struct pnp_option *option; + struct pnp_port *port; - port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); - if (!port) + option = pnp_build_option(dev, IORESOURCE_IO, option_flags); + if (!option) return -ENOMEM; + port = &option->u.port; port->min = min; port->max = max; port->align = align; port->size = size; port->flags = flags; - ptr = option->port; - while (ptr && ptr->next) - ptr = ptr->next; - if (ptr) - ptr->next = port; - else - option->port = port; - - dev_dbg(&dev->dev, " io " - "min %#llx max %#llx align %lld size %lld flags %#x\n", - (unsigned long long) port->min, - (unsigned long long) port->max, - (unsigned long long) port->align, - (unsigned long long) port->size, port->flags); + dbg_pnp_show_option(dev, option); return 0; } -int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, +int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t size, unsigned char flags) { - struct pnp_mem *mem, *ptr; + struct pnp_option *option; + struct pnp_mem *mem; - mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); - if (!mem) + option = pnp_build_option(dev, IORESOURCE_MEM, option_flags); + if (!option) return -ENOMEM; + mem = &option->u.mem; mem->min = min; mem->max = max; mem->align = align; mem->size = size; mem->flags = flags; - ptr = option->mem; - while (ptr && ptr->next) - ptr = ptr->next; - if (ptr) - ptr->next = mem; - else - option->mem = mem; - - dev_dbg(&dev->dev, " mem " - "min %#llx max %#llx align %lld size %lld flags %#x\n", - (unsigned long long) mem->min, - (unsigned long long) mem->max, - (unsigned long long) mem->align, - (unsigned long long) mem->size, mem->flags); + dbg_pnp_show_option(dev, option); return 0; } -static void pnp_free_port(struct pnp_port *port) -{ - struct pnp_port *next; - - while (port) { - next = port->next; - kfree(port); - port = next; - } -} - -static void pnp_free_irq(struct pnp_irq *irq) -{ - struct pnp_irq *next; - - while (irq) { - next = irq->next; - kfree(irq); - irq = next; - } -} - -static void pnp_free_dma(struct pnp_dma *dma) -{ - struct pnp_dma *next; - - while (dma) { - next = dma->next; - kfree(dma); - dma = next; - } -} - -static void pnp_free_mem(struct pnp_mem *mem) +void pnp_free_options(struct pnp_dev *dev) { - struct pnp_mem *next; - - while (mem) { - next = mem->next; - kfree(mem); - mem = next; - } -} + struct pnp_option *option, *tmp; -void pnp_free_option(struct pnp_option *option) -{ - struct pnp_option *next; - - while (option) { - next = option->next; - pnp_free_port(option->port); - pnp_free_irq(option->irq); - pnp_free_dma(option->dma); - pnp_free_mem(option->mem); + list_for_each_entry_safe(option, tmp, &dev->options, list) { + list_del(&option->list); kfree(option); - option = next; } } @@ -668,66 +546,50 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, return pnp_res; } -static int pnp_possible_option(struct pnp_option *option, int type, - resource_size_t start, resource_size_t size) +/* + * Determine whether the specified resource is a possible configuration + * for this device. + */ +int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, + resource_size_t size) { - struct pnp_option *tmp; + struct pnp_option *option; struct pnp_port *port; struct pnp_mem *mem; struct pnp_irq *irq; struct pnp_dma *dma; - if (!option) - return 0; + list_for_each_entry(option, &dev->options, list) { + if (option->type != type) + continue; - for (tmp = option; tmp; tmp = tmp->next) { - switch (type) { + switch (option->type) { case IORESOURCE_IO: - for (port = tmp->port; port; port = port->next) { - if (port->min == start && port->size == size) - return 1; - } + port = &option->u.port; + if (port->min == start && port->size == size) + return 1; break; case IORESOURCE_MEM: - for (mem = tmp->mem; mem; mem = mem->next) { - if (mem->min == start && mem->size == size) - return 1; - } + mem = &option->u.mem; + if (mem->min == start && mem->size == size) + return 1; break; case IORESOURCE_IRQ: - for (irq = tmp->irq; irq; irq = irq->next) { - if (start < PNP_IRQ_NR && - test_bit(start, irq->map.bits)) - return 1; - } + irq = &option->u.irq; + if (start < PNP_IRQ_NR && + test_bit(start, irq->map.bits)) + return 1; break; case IORESOURCE_DMA: - for (dma = tmp->dma; dma; dma = dma->next) { - if (dma->map & (1 << start)) - return 1; - } + dma = &option->u.dma; + if (dma->map & (1 << start)) + return 1; break; } } return 0; } - -/* - * Determine whether the specified resource is a possible configuration - * for this device. - */ -int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, - resource_size_t size) -{ - if (pnp_possible_option(dev->independent, type, start, size)) - return 1; - - if (pnp_possible_option(dev->dependent, type, start, size)) - return 1; - - return 0; -} EXPORT_SYMBOL(pnp_possible_config); /* format is: pnp_reserve_irq=irq1[,irq2] .... */ diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 0ad42db..bbf78ef 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -2,6 +2,8 @@ * support.c - standard functions for the use of pnp protocol drivers * * Copyright 2003 Adam Belay + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas */ #include @@ -117,3 +119,93 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) } #endif } + +char *pnp_option_priority_name(struct pnp_option *option) +{ + switch (pnp_option_priority(option)) { + case PNP_RES_PRIORITY_PREFERRED: + return "preferred"; + case PNP_RES_PRIORITY_ACCEPTABLE: + return "acceptable"; + case PNP_RES_PRIORITY_FUNCTIONAL: + return "functional"; + } + return "invalid"; +} + +void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) +{ +#ifdef DEBUG + char buf[128]; + int len = 0, i; + struct pnp_port *port; + struct pnp_mem *mem; + struct pnp_irq *irq; + struct pnp_dma *dma; + + if (pnp_option_is_dependent(option)) + len += snprintf(buf + len, sizeof(buf) - len, + " dependent set %d (%s) ", + pnp_option_set(option), + pnp_option_priority_name(option)); + else + len += snprintf(buf + len, sizeof(buf) - len, " independent "); + + switch (option->type) { + case IORESOURCE_IO: + port = &option->u.port; + len += snprintf(buf + len, sizeof(buf) - len, "io min %#llx " + "max %#llx align %lld size %lld flags %#x", + (unsigned long long) port->min, + (unsigned long long) port->max, + (unsigned long long) port->align, + (unsigned long long) port->size, port->flags); + break; + case IORESOURCE_MEM: + mem = &option->u.mem; + len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx " + "max %#llx align %lld size %lld flags %#x", + (unsigned long long) mem->min, + (unsigned long long) mem->max, + (unsigned long long) mem->align, + (unsigned long long) mem->size, mem->flags); + break; + case IORESOURCE_IRQ: + irq = &option->u.irq; + len += snprintf(buf + len, sizeof(buf) - len, "irq"); + if (bitmap_empty(irq->map.bits, PNP_IRQ_NR)) + len += snprintf(buf + len, sizeof(buf) - len, + " "); + else { + for (i = 0; i < PNP_IRQ_NR; i++) + if (test_bit(i, irq->map.bits)) + len += snprintf(buf + len, + sizeof(buf) - len, + " %d", i); + } + len += snprintf(buf + len, sizeof(buf) - len, " flags %#x", + irq->flags); + if (irq->flags & IORESOURCE_IRQ_OPTIONAL) + len += snprintf(buf + len, sizeof(buf) - len, + " (optional)"); + break; + case IORESOURCE_DMA: + dma = &option->u.dma; + len += snprintf(buf + len, sizeof(buf) - len, "dma"); + if (!dma->map) + len += snprintf(buf + len, sizeof(buf) - len, + " "); + else { + for (i = 0; i < 8; i++) + if (dma->map & (1 << i)) + len += snprintf(buf + len, + sizeof(buf) - len, + " %d", i); + } + len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) " + "flags %#x", dma->map, dma->flags); + break; + } + dev_dbg(&dev->dev, "%s\n", buf); +#endif +} diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 785126f..1ce54b6 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -1,6 +1,8 @@ /* * Linux Plug and Play Support * Copyright by Adam Belay + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas */ #ifndef _LINUX_PNP_H @@ -249,9 +251,9 @@ struct pnp_dev { int active; int capabilities; - struct pnp_option *independent; - struct pnp_option *dependent; + unsigned int num_dependent_sets; struct list_head resources; + struct list_head options; char name[PNP_NAME_LEN]; /* contains a human-readable name */ int flags; /* used by protocols */ -- cgit v0.10.2 From 84684c7469a2e6fcbf8c808ac5030ba2de14ff77 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:18 -0600 Subject: PNP: avoid legacy IDE IRQs If an IDE controller is in compatibility mode, it expects to use IRQs 14 and 15, so PNP should avoid them. This patch should resolve this problem report: parallel driver grabs IRQ14 preventing legacy SFF ATA controller from working https://bugzilla.novell.com/show_bug.cgi?id=375836 Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index d638897..4cfe3a1 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -286,6 +286,61 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id) return IRQ_HANDLED; } +#ifdef CONFIG_PCI +static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, + unsigned int irq) +{ + u32 class; + u8 progif; + + if (pci->irq == irq) { + dev_dbg(&pnp->dev, "device %s using irq %d\n", + pci_name(pci), irq); + return 1; + } + + /* + * See pci_setup_device() and ata_pci_sff_activate_host() for + * similar IDE legacy detection. + */ + pci_read_config_dword(pci, PCI_CLASS_REVISION, &class); + class >>= 8; /* discard revision ID */ + progif = class & 0xff; + class >>= 8; + + if (class == PCI_CLASS_STORAGE_IDE) { + /* + * Unless both channels are native-PCI mode only, + * treat the compatibility IRQs as busy. + */ + if ((progif & 0x5) != 0x5) + if (pci_get_legacy_ide_irq(pci, 0) == irq || + pci_get_legacy_ide_irq(pci, 1) == irq) { + dev_dbg(&pnp->dev, "legacy IDE device %s " + "using irq %d\n", pci_name(pci), irq); + return 1; + } + } + + return 0; +} +#endif + +static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq) +{ +#ifdef CONFIG_PCI + struct pci_dev *pci = NULL; + + for_each_pci_dev(pci) { + if (pci_dev_uses_irq(pnp, pci, irq)) { + pci_dev_put(pci); + return 1; + } + } +#endif + return 0; +} + int pnp_check_irq(struct pnp_dev *dev, struct resource *res) { int i; @@ -317,18 +372,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res) } } -#ifdef CONFIG_PCI /* check if the resource is being used by a pci device */ - { - struct pci_dev *pci = NULL; - for_each_pci_dev(pci) { - if (pci->irq == *irq) { - pci_dev_put(pci); - return 0; - } - } - } -#endif + if (pci_uses_irq(dev, *irq)) + return 0; /* check if the resource is already in use, skip if the * device is active because it itself may be in use */ -- cgit v0.10.2 From 40ab4f4c1d843362eb26d83425317e91fbd98b17 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 16:57:19 -0600 Subject: PNPACPI: add support for HP vendor-specific CCSR descriptors The HP CCSR descriptor describes MMIO address space that should appear as a MEM resource. This patch adds support for parsing these descriptors in the _CRS data. The visible effect of this is that these MEM resources will appear in /sys/devices/pnp0/.../resources, which means that "lspnp -v" will report it, user applications can use this to locate device CSR space, and kernel drivers can use the normal PNP resource accessors to locate them. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index c2f59f4..d7e9f21 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -3,6 +3,8 @@ * * Copyright (c) 2004 Matthieu Castet * Copyright (c) 2004 Li Shaohua + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas * * 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 @@ -187,6 +189,61 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, pnp_add_io_resource(dev, start, end, flags); } +/* + * Device CSRs that do not appear in PCI config space should be described + * via ACPI. This would normally be done with Address Space Descriptors + * marked as "consumer-only," but old versions of Windows and Linux ignore + * the producer/consumer flag, so HP invented a vendor-defined resource to + * describe the location and size of CSR space. + */ +static struct acpi_vendor_uuid hp_ccsr_uuid = { + .subtype = 2, + .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a, + 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad }, +}; + +static int vendor_resource_matches(struct pnp_dev *dev, + struct acpi_resource_vendor_typed *vendor, + struct acpi_vendor_uuid *match, + int expected_len) +{ + int uuid_len = sizeof(vendor->uuid); + u8 uuid_subtype = vendor->uuid_subtype; + u8 *uuid = vendor->uuid; + int actual_len; + + /* byte_length includes uuid_subtype and uuid */ + actual_len = vendor->byte_length - uuid_len - 1; + + if (uuid_subtype == match->subtype && + uuid_len == sizeof(match->data) && + memcmp(uuid, match->data, uuid_len) == 0) { + if (expected_len && expected_len != actual_len) { + dev_err(&dev->dev, "wrong vendor descriptor size; " + "expected %d, found %d bytes\n", + expected_len, actual_len); + return 0; + } + + return 1; + } + + return 0; +} + +static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, + struct acpi_resource_vendor_typed *vendor) +{ + if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) { + u64 start, length; + + memcpy(&start, vendor->byte_data, sizeof(start)); + memcpy(&length, vendor->byte_data + 8, sizeof(length)); + + pnp_add_mem_resource(dev, start, start + length - 1, 0); + } +} + static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, u64 start, u64 len, int write_protect) @@ -237,6 +294,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, struct acpi_resource_dma *dma; struct acpi_resource_io *io; struct acpi_resource_fixed_io *fixed_io; + struct acpi_resource_vendor_typed *vendor_typed; struct acpi_resource_memory24 *memory24; struct acpi_resource_memory32 *memory32; struct acpi_resource_fixed_memory32 *fixed_memory32; @@ -306,6 +364,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, break; case ACPI_RESOURCE_TYPE_VENDOR: + vendor_typed = &res->data.vendor_typed; + pnpacpi_parse_allocated_vendor(dev, vendor_typed); break; case ACPI_RESOURCE_TYPE_END_TAG: -- cgit v0.10.2 From c83642d5123225a22cccd75adea6e97c245714cb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 27 Jun 2008 08:45:39 -0600 Subject: ACPI: use dev_printk when possible Convert printks to use dev_printk(). The most obvious change will be messages like this: -ACPI: PCI Interrupt 0000:00:04.0[A] -> GSI 31 (level, low) -> IRQ 31 +cciss 0000:00:04.0: PCI INT A -> GSI 31 (level, low) -> IRQ 31 Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andi Kleen diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 89022a7..11acaee 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -162,7 +162,7 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt) !strcmp(prt->source, quirk->source) && strlen(prt->source) >= strlen(quirk->actual_source)) { printk(KERN_WARNING PREFIX "firmware reports " - "%04x:%02x:%02x[%c] connected to %s; " + "%04x:%02x:%02x PCI INT %c connected to %s; " "changing to %s\n", entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin, @@ -429,7 +429,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, { struct pci_dev *bridge = dev; int irq = -1; - u8 bridge_pin = 0; + u8 bridge_pin = 0, orig_pin = pin; if (!dev) @@ -463,8 +463,8 @@ acpi_pci_irq_derive(struct pci_dev *dev, } if (irq < 0) { - printk(KERN_WARNING PREFIX "Unable to derive IRQ for device %s\n", - pci_name(dev)); + dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n", + 'A' + orig_pin); return -1; } @@ -487,6 +487,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) int triggering = ACPI_LEVEL_SENSITIVE; int polarity = ACPI_ACTIVE_LOW; char *link = NULL; + char link_desc[16]; int rc; @@ -503,7 +504,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) pin--; if (!dev->bus) { - printk(KERN_ERR PREFIX "Invalid (NULL) 'bus' field\n"); + dev_err(&dev->dev, "invalid (NULL) 'bus' field\n"); return -ENODEV; } @@ -538,8 +539,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) * driver reported one, then use it. Exit in any case. */ if (irq < 0) { - printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", - pci_name(dev), ('A' + pin)); + dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin); /* Interrupt Line values above 0xF are forbidden */ if (dev->irq > 0 && (dev->irq <= 0xF)) { printk(" - using IRQ %d\n", dev->irq); @@ -554,21 +554,21 @@ int acpi_pci_irq_enable(struct pci_dev *dev) rc = acpi_register_gsi(irq, triggering, polarity); if (rc < 0) { - printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed " - "to register GSI\n", pci_name(dev), ('A' + pin)); + dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", + 'A' + pin); return rc; } dev->irq = rc; - printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ", - pci_name(dev), 'A' + pin); - if (link) - printk("Link [%s] -> ", link); + snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); + else + link_desc[0] = '\0'; - printk("GSI %u (%s, %s) -> IRQ %d\n", irq, - (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", - (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); + dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n", + 'A' + pin, link_desc, irq, + (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", + (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); return 0; } @@ -616,10 +616,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) * (e.g. PCI_UNDEFINED_IRQ). */ - printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n", - pci_name(dev)); - + dev_info(&dev->dev, "PCI INT %c disabled\n", 'A' + pin); acpi_unregister_gsi(gsi); - - return; } -- cgit v0.10.2 From 4d3870431d17346c4fdd80e087b7d76f1b5941d5 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Wed, 16 Jul 2008 23:27:08 +0200 Subject: Add the ability to reset the machine using the RESET_REG in ACPI's FADT table. Signed-off-by: Aaron Durbin Signed-off-by: Andi Kleen Cc: Len Brown Cc: Andi Kleen Signed-off-by: Andrew Morton diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 40b0fca..4efbe598 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_X86) += blacklist.o # # ACPI Core Subsystem (Interpreter) # -obj-y += osl.o utils.o \ +obj-y += osl.o utils.o reboot.o\ dispatcher/ events/ executer/ hardware/ \ namespace/ parser/ resources/ tables/ \ utilities/ diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c new file mode 100644 index 0000000..a6b662c --- /dev/null +++ b/drivers/acpi/reboot.c @@ -0,0 +1,50 @@ + +#include +#include +#include + +void acpi_reboot(void) +{ + struct acpi_generic_address *rr; + struct pci_bus *bus0; + u8 reset_value; + unsigned int devfn; + + if (acpi_disabled) + return; + + rr = &acpi_gbl_FADT.reset_register; + + /* Is the reset register supported? */ + if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || + rr->bit_width != 8 || rr->bit_offset != 0) + return; + + reset_value = acpi_gbl_FADT.reset_value; + + /* The reset register can only exist in I/O, Memory or PCI config space + * on a device on bus 0. */ + switch (rr->space_id) { + case ACPI_ADR_SPACE_PCI_CONFIG: + /* The reset register can only live on bus 0. */ + bus0 = pci_find_bus(0, 0); + if (!bus0) + return; + /* Form PCI device/function pair. */ + devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, + (rr->address >> 16) & 0xffff); + printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); + /* Write the value that resets us. */ + pci_bus_write_config_byte(bus0, devfn, + (rr->address & 0xffff), reset_value); + break; + + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + case ACPI_ADR_SPACE_SYSTEM_IO: + printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); + acpi_hw_low_level_write(8, reset_value, rr); + break; + } + /* Wait ten seconds */ + acpi_os_stall(10000000); +} diff --git a/include/acpi/reboot.h b/include/acpi/reboot.h index 8857f57..0419184 100644 --- a/include/acpi/reboot.h +++ b/include/acpi/reboot.h @@ -1,9 +1,11 @@ +#ifndef __ACPI_REBOOT_H +#define __ACPI_REBOOT_H + +#ifdef CONFIG_ACPI +extern void acpi_reboot(void); +#else +static inline void acpi_reboot(void) { } +#endif -/* - * Dummy placeholder to make the EFI patches apply to the x86 tree. - * Andrew/Len, please just kill this file if you encounter it. - */ -#ifndef acpi_reboot -# define acpi_reboot() do { } while (0) #endif -- cgit v0.10.2 From 01a5bba576b9364b33f61f0cd9fa70c2cf5535e2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 16 Jul 2008 23:27:08 +0200 Subject: Fix FADT parsing The (1.0 inherited) separate length fields in the FADT are byte granular. Further, PM1a/b may have distinct lengths and live in distinct address spaces. acpi_tb_convert_fadt() should account for all of these conditions. Apart from these changes I'm puzzled by the fact that, not just for acpi_gbl_xpm1{a,b}_enable, acpi_hw_low_level_{read,write}() get an explicit size passed rather than using the size found in the passed GAS. What happens on a platform that defines PM1{a,b} wider than 16 bits? Of course, acpi_hw_low_level_{read,write}() at present are entirely un-prepared to deal with sizes other than 8, 16, or 32, not to speak of a non-zero bit_offset or access_width... Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen Cc: Len Brown Signed-off-by: Andrew Morton diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index a4a41ba..ccb5b64 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c @@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = { static void inline acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, - u8 bit_width, u64 address) + u8 byte_width, u64 address) { /* @@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, /* All other fields are byte-wide */ generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; - generic_address->bit_width = bit_width; + generic_address->bit_width = byte_width << 3; generic_address->bit_offset = 0; generic_address->access_width = 0; } @@ -343,9 +343,11 @@ static void acpi_tb_convert_fadt(void) * * The PM event blocks are split into two register blocks, first is the * PM Status Register block, followed immediately by the PM Enable Register - * block. Each is of length (pm1_event_length/2) + * block. Each is of length (xpm1x_event_block.bit_width/2) */ - pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); + WARN_ON(ACPI_MOD_16(acpi_gbl_FADT.xpm1a_event_block.bit_width)); + pm1_register_length = (u8) ACPI_DIV_16(acpi_gbl_FADT + .xpm1a_event_block.bit_width); /* The PM1A register block is required */ @@ -360,14 +362,17 @@ static void acpi_tb_convert_fadt(void) /* The PM1B register block is optional, ignore if not present */ if (acpi_gbl_FADT.xpm1b_event_block.address) { + WARN_ON(ACPI_MOD_16(acpi_gbl_FADT.xpm1b_event_block.bit_width)); + pm1_register_length = (u8) ACPI_DIV_16(acpi_gbl_FADT + .xpm1b_event_block + .bit_width); acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, pm1_register_length, (acpi_gbl_FADT.xpm1b_event_block. address + pm1_register_length)); /* Don't forget to copy space_id of the GAS */ acpi_gbl_xpm1b_enable.space_id = - acpi_gbl_FADT.xpm1a_event_block.space_id; - + acpi_gbl_FADT.xpm1b_event_block.space_id; } } -- cgit v0.10.2 From d442cc44c0db56e84ef6aa244a88427d2efe06cd Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 16 Jul 2008 16:09:06 -0400 Subject: block: Trivial fix for blk_integrity_rq() Fail integrity check gracefully when request does not have a bio attached (BLOCK_PC). Signed-off-by: Martin K. Petersen Signed-off-by: Linus Torvalds diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 32a441b..88d6808 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -985,6 +985,9 @@ static inline int bdev_integrity_enabled(struct block_device *bdev, int rw) static inline int blk_integrity_rq(struct request *rq) { + if (rq->bio == NULL) + return 0; + return bio_integrity(rq->bio); } -- cgit v0.10.2 From c0420ad2ca514551ca086510b0e7d17a05c70492 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Mon, 30 Jun 2008 18:45:45 +0800 Subject: [PATCH] ocfs2: fix oops in mmap_truncate testing This patch fixes a mmap_truncate bug which was found by ocfs2 test suite. In an ocfs2 cluster more than 1 node, run program mmap_truncate, which races mmap writes and truncates from multiple processes. While the test is running, a stat from another node forces writeout, causing an oops in ocfs2_get_block() because it sees a buffer to write which isn't allocated. This patch fixed the bug by clear dirty and uptodate bits in buffer, leave the buffer unmapped and return. Fix is suggested by Mark Fasheh, and I code up the patch. Signed-off-by: Coly Li Signed-off-by: Mark Fasheh diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 17964c0..1db0801 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -174,10 +174,17 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock, * need to use BH_New is when we're extending i_size on a file * system which doesn't support holes, in which case BH_New * allows block_prepare_write() to zero. + * + * If we see this on a sparse file system, then a truncate has + * raced us and removed the cluster. In this case, we clear + * the buffers dirty and uptodate bits and let the buffer code + * ignore it as a hole. */ - mlog_bug_on_msg(create && p_blkno == 0 && ocfs2_sparse_alloc(osb), - "ino %lu, iblock %llu\n", inode->i_ino, - (unsigned long long)iblock); + if (create && p_blkno == 0 && ocfs2_sparse_alloc(osb)) { + clear_buffer_dirty(bh_result); + clear_buffer_uptodate(bh_result); + goto bail; + } /* Treat the unwritten extent as a hole for zeroing purposes. */ if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN)) -- cgit v0.10.2 From 58b6e5538460be358fdf1286d9a2fbcfcc2cfaba Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 16 Jul 2008 16:21:47 -0700 Subject: Revert "x86/PCI: ACPI based PCI gap calculation" This reverts commit 809d9a8f93bd8504dcc34b16bbfdfd1a8c9bb1ed. This one isn't quite ready for prime time. It needs more testing and additional feedback from the ACPI guys. diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index d1ffb57..d95de2f 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "pci.h" struct pci_root_info { @@ -15,11 +14,6 @@ struct pci_root_info { int busnum; }; -struct gap_info { - unsigned long gapstart; - unsigned long gapsize; -}; - static acpi_status resource_to_addr(struct acpi_resource *resource, struct acpi_resource_address64 *addr) @@ -116,78 +110,6 @@ adjust_transparent_bridge_resources(struct pci_bus *bus) } } -static acpi_status search_gap(struct acpi_resource *resource, void *data) -{ - struct acpi_resource_address64 addr; - acpi_status status; - struct gap_info *gap = data; - unsigned long long start_addr, end_addr; - - status = resource_to_addr(resource, &addr); - if (ACPI_SUCCESS(status) && - addr.resource_type == ACPI_MEMORY_RANGE && - addr.address_length > gap->gapsize) { - start_addr = addr.minimum + addr.translation_offset; - /* - * We want space only in the 32bit address range - */ - if (start_addr < UINT_MAX) { - end_addr = start_addr + addr.address_length; - e820_search_gap(&gap->gapstart, &gap->gapsize, - start_addr, end_addr); - } - } - - return AE_OK; -} - -/* - * Search for a hole in the 32 bit address space for PCI to assign MMIO - * resources, for hotplug or unconfigured resources. - * We query the CRS object of the PCI root device to look for possible producer - * resources in the tree and consider these while calulating the start address - * for this hole. - */ -static void pci_setup_gap(acpi_handle *handle) -{ - struct gap_info gap; - acpi_status status; - - gap.gapstart = 0; - gap.gapsize = 0x400000; - - status = acpi_walk_resources(handle, METHOD_NAME__CRS, - search_gap, &gap); - - if (ACPI_SUCCESS(status)) { - unsigned long round; - - if (!gap.gapstart) { - printk(KERN_ERR "ACPI: Warning: Cannot find a gap " - "in the 32bit address range for PCI\n" - "ACPI: PCI devices may collide with " - "hotpluggable memory address range\n"); - } - /* - * Round the gapstart, uses the same logic as in - * e820_gap_setup - */ - round = 0x100000; - while ((gap.gapsize >> 4) > round) - round += round; - /* Fun with two's complement */ - pci_mem_start = (gap.gapstart + round) & -round; - - printk(KERN_INFO "ACPI: PCI resources should " - "start at %lx (gap: %lx:%lx)\n", - pci_mem_start, gap.gapstart, gap.gapsize); - } else { - printk(KERN_ERR "ACPI: Error while searching for gap in " - "the 32bit address range for PCI\n"); - } -} - - static void get_current_resources(struct acpi_device *device, int busnum, int domain, struct pci_bus *bus) @@ -293,8 +215,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do if (bus && (pci_probe & PCI_USE__CRS)) get_current_resources(device, busnum, domain, bus); - - pci_setup_gap(device->handle); return bus; } -- cgit v0.10.2 From 33af79d12e0fa25545d49e86afc67ea8ad5f2f40 Mon Sep 17 00:00:00 2001 From: Chandra Seetharaman Date: Wed, 16 Jul 2008 17:35:08 -0700 Subject: scsi_dh: Verify "dev" is a sdev before accessing it. Before accessing the device data structure in hardware handlers, make sure it is a indeed a sdev device. Yinghai Lu found the bug on Jul 16, 2008, and later tested/verified the following fix. Signed-off-by: Chandra Seetharaman Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index ed53f14..f2467e9 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -416,12 +416,17 @@ static int clariion_bus_notify(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data; - struct scsi_device *sdev = to_scsi_device(dev); + struct scsi_device *sdev; struct scsi_dh_data *scsi_dh_data; struct clariion_dh_data *h; int i, found = 0; unsigned long flags; + if (!scsi_is_sdev_device(dev)) + return 0; + + sdev = to_scsi_device(dev); + if (action == BUS_NOTIFY_ADD_DEVICE) { for (i = 0; clariion_dev_list[i].vendor; i++) { if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor, diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 12ceab7..ae6be87 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -131,11 +131,16 @@ static int hp_sw_bus_notify(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data; - struct scsi_device *sdev = to_scsi_device(dev); + struct scsi_device *sdev; struct scsi_dh_data *scsi_dh_data; int i, found = 0; unsigned long flags; + if (!scsi_is_sdev_device(dev)) + return 0; + + sdev = to_scsi_device(dev); + if (action == BUS_NOTIFY_ADD_DEVICE) { for (i = 0; hp_sw_dh_data_list[i].vendor; i++) { if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor, diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 6fff077..fdf34b0 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -608,12 +608,17 @@ static int rdac_bus_notify(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data; - struct scsi_device *sdev = to_scsi_device(dev); + struct scsi_device *sdev; struct scsi_dh_data *scsi_dh_data; struct rdac_dh_data *h; int i, found = 0; unsigned long flags; + if (!scsi_is_sdev_device(dev)) + return 0; + + sdev = to_scsi_device(dev); + if (action == BUS_NOTIFY_ADD_DEVICE) { for (i = 0; rdac_dev_list[i].vendor; i++) { if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor, -- cgit v0.10.2 From 98abed02007b19bbfd68b6d06a5485afc3eeb01b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 19 Mar 2008 19:24:59 -0700 Subject: do_wait reorganization This breaks out the guts of do_wait into three subfunctions. The control flow is less nonobvious without so much goto. do_wait_thread and ptrace_do_wait contain the main work of the outer loop. wait_consider_task contains the main work of the inner loop. Signed-off-by: Roland McGrath diff --git a/kernel/exit.c b/kernel/exit.c index ceb2587..7453356 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1238,7 +1238,7 @@ static int wait_noreap_copyout(struct task_struct *p, pid_t pid, uid_t uid, * the lock and this task is uninteresting. If we return nonzero, we have * released the lock and the system call should return. */ -static int wait_task_zombie(struct task_struct *p, int noreap, +static int wait_task_zombie(struct task_struct *p, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { @@ -1246,7 +1246,10 @@ static int wait_task_zombie(struct task_struct *p, int noreap, int retval, status, traced; pid_t pid = task_pid_vnr(p); - if (unlikely(noreap)) { + if (!likely(options & WEXITED)) + return 0; + + if (unlikely(options & WNOWAIT)) { uid_t uid = p->uid; int exit_code = p->exit_code; int why, status; @@ -1397,13 +1400,16 @@ static int wait_task_zombie(struct task_struct *p, int noreap, * released the lock and the system call should return. */ static int wait_task_stopped(struct task_struct *p, - int noreap, struct siginfo __user *infop, + int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { int retval, exit_code, why; uid_t uid = 0; /* unneeded, required by compiler */ pid_t pid; + if (!(p->ptrace & PT_PTRACED) && !(options & WUNTRACED)) + return 0; + exit_code = 0; spin_lock_irq(&p->sighand->siglock); @@ -1421,7 +1427,7 @@ static int wait_task_stopped(struct task_struct *p, if (!exit_code) goto unlock_sig; - if (!noreap) + if (!unlikely(options & WNOWAIT)) p->exit_code = 0; uid = p->uid; @@ -1442,7 +1448,7 @@ unlock_sig: why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED; read_unlock(&tasklist_lock); - if (unlikely(noreap)) + if (unlikely(options & WNOWAIT)) return wait_noreap_copyout(p, pid, uid, why, exit_code, infop, ru); @@ -1476,7 +1482,7 @@ unlock_sig: * the lock and this task is uninteresting. If we return nonzero, we have * released the lock and the system call should return. */ -static int wait_task_continued(struct task_struct *p, int noreap, +static int wait_task_continued(struct task_struct *p, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { @@ -1484,6 +1490,9 @@ static int wait_task_continued(struct task_struct *p, int noreap, pid_t pid; uid_t uid; + if (!unlikely(options & WCONTINUED)) + return 0; + if (!(p->signal->flags & SIGNAL_STOP_CONTINUED)) return 0; @@ -1493,7 +1502,7 @@ static int wait_task_continued(struct task_struct *p, int noreap, spin_unlock_irq(&p->sighand->siglock); return 0; } - if (!noreap) + if (!unlikely(options & WNOWAIT)) p->signal->flags &= ~SIGNAL_STOP_CONTINUED; spin_unlock_irq(&p->sighand->siglock); @@ -1519,89 +1528,137 @@ static int wait_task_continued(struct task_struct *p, int noreap, return retval; } +/* + * Consider @p for a wait by @parent. + * + * -ECHILD should be in *@notask_error before the first call. + * Returns nonzero for a final return, when we have unlocked tasklist_lock. + * Returns zero if the search for a child should continue; + * then *@notask_error is 0 if @p is an eligible child, or still -ECHILD. + */ +static int wait_consider_task(struct task_struct *parent, + struct task_struct *p, int *notask_error, + enum pid_type type, struct pid *pid, int options, + struct siginfo __user *infop, + int __user *stat_addr, struct rusage __user *ru) +{ + int ret = eligible_child(type, pid, options, p); + if (ret <= 0) + return ret; + + if (p->exit_state == EXIT_DEAD) + return 0; + + /* + * We don't reap group leaders with subthreads. + */ + if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p)) + return wait_task_zombie(p, options, infop, stat_addr, ru); + + /* + * It's stopped or running now, so it might + * later continue, exit, or stop again. + */ + *notask_error = 0; + + if (task_is_stopped_or_traced(p)) + return wait_task_stopped(p, options, infop, stat_addr, ru); + + return wait_task_continued(p, options, infop, stat_addr, ru); +} + +/* + * Do the work of do_wait() for one thread in the group, @tsk. + * + * -ECHILD should be in *@notask_error before the first call. + * Returns nonzero for a final return, when we have unlocked tasklist_lock. + * Returns zero if the search for a child should continue; then + * *@notask_error is 0 if there were any eligible children, or still -ECHILD. + */ +static int do_wait_thread(struct task_struct *tsk, int *notask_error, + enum pid_type type, struct pid *pid, int options, + struct siginfo __user *infop, int __user *stat_addr, + struct rusage __user *ru) +{ + struct task_struct *p; + + list_for_each_entry(p, &tsk->children, sibling) { + int ret = wait_consider_task(tsk, p, notask_error, + type, pid, options, + infop, stat_addr, ru); + if (ret) + return ret; + } + + return 0; +} + +static int ptrace_do_wait(struct task_struct *tsk, int *notask_error, + enum pid_type type, struct pid *pid, int options, + struct siginfo __user *infop, int __user *stat_addr, + struct rusage __user *ru) +{ + struct task_struct *p; + + /* + * If we never saw an eligile child, check for children stolen by + * ptrace. We don't leave -ECHILD in *@notask_error if there are any, + * because we will eventually be allowed to wait for them again. + */ + if (!*notask_error) + return 0; + + list_for_each_entry(p, &tsk->ptrace_children, ptrace_list) { + int ret = eligible_child(type, pid, options, p); + if (unlikely(ret < 0)) + return ret; + if (ret) { + *notask_error = 0; + return 0; + } + } + + return 0; +} + static long do_wait(enum pid_type type, struct pid *pid, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk; - int flag, retval; + int retval; add_wait_queue(¤t->signal->wait_chldexit,&wait); repeat: - /* If there is nothing that can match our critier just get out */ + /* + * If there is nothing that can match our critiera just get out. + * We will clear @retval to zero if we see any child that might later + * match our criteria, even if we are not able to reap it yet. + */ retval = -ECHILD; if ((type < PIDTYPE_MAX) && (!pid || hlist_empty(&pid->tasks[type]))) goto end; - /* - * We will set this flag if we see any child that might later - * match our criteria, even if we are not able to reap it yet. - */ - flag = retval = 0; current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); tsk = current; do { - struct task_struct *p; - - list_for_each_entry(p, &tsk->children, sibling) { - int ret = eligible_child(type, pid, options, p); - if (!ret) - continue; - - if (unlikely(ret < 0)) { - retval = ret; - } else if (task_is_stopped_or_traced(p)) { - /* - * It's stopped now, so it might later - * continue, exit, or stop again. - */ - flag = 1; - if (!(p->ptrace & PT_PTRACED) && - !(options & WUNTRACED)) - continue; - - retval = wait_task_stopped(p, - (options & WNOWAIT), infop, - stat_addr, ru); - } else if (p->exit_state == EXIT_ZOMBIE && - !delay_group_leader(p)) { - /* - * We don't reap group leaders with subthreads. - */ - if (!likely(options & WEXITED)) - continue; - retval = wait_task_zombie(p, - (options & WNOWAIT), infop, - stat_addr, ru); - } else if (p->exit_state != EXIT_DEAD) { - /* - * It's running now, so it might later - * exit, stop, or stop and then continue. - */ - flag = 1; - if (!unlikely(options & WCONTINUED)) - continue; - retval = wait_task_continued(p, - (options & WNOWAIT), infop, - stat_addr, ru); - } - if (retval != 0) /* tasklist_lock released */ - goto end; - } - if (!flag) { - list_for_each_entry(p, &tsk->ptrace_children, - ptrace_list) { - flag = eligible_child(type, pid, options, p); - if (!flag) - continue; - if (likely(flag > 0)) - break; - retval = flag; - goto end; - } + int tsk_result = do_wait_thread(tsk, &retval, + type, pid, options, + infop, stat_addr, ru); + if (!tsk_result) + tsk_result = ptrace_do_wait(tsk, &retval, + type, pid, options, + infop, stat_addr, ru); + if (tsk_result) { + /* + * tasklist_lock is unlocked and we have a final result. + */ + retval = tsk_result; + goto end; } + if (options & __WNOTHREAD) break; tsk = next_thread(tsk); @@ -1609,16 +1666,14 @@ repeat: } while (tsk != current); read_unlock(&tasklist_lock); - if (flag) { - if (options & WNOHANG) - goto end; + if (!retval && !(options & WNOHANG)) { retval = -ERESTARTSYS; - if (signal_pending(current)) - goto end; - schedule(); - goto repeat; + if (!signal_pending(current)) { + schedule(); + goto repeat; + } } - retval = -ECHILD; + end: current->state = TASK_RUNNING; remove_wait_queue(¤t->signal->wait_chldexit,&wait); -- cgit v0.10.2 From f470021adb9190819c03d6d8c5c860a17480aa6d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 24 Mar 2008 18:36:23 -0700 Subject: ptrace children revamp ptrace no longer fiddles with the children/sibling links, and the old ptrace_children list is gone. Now ptrace, whether of one's own children or another's via PTRACE_ATTACH, just uses the new ptraced list instead. There should be no user-visible difference that matters. The only change is the order in which do_wait() sees multiple stopped children and stopped ptrace attachees. Since wait_task_stopped() was changed earlier so it no longer reorders the children list, we already know this won't cause any new problems. Signed-off-by: Roland McGrath diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 9927a88..93c45ac 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -140,8 +140,8 @@ extern struct group_info init_groups; .nr_cpus_allowed = NR_CPUS, \ }, \ .tasks = LIST_HEAD_INIT(tsk.tasks), \ - .ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \ - .ptrace_list = LIST_HEAD_INIT(tsk.ptrace_list), \ + .ptraced = LIST_HEAD_INIT(tsk.ptraced), \ + .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \ .real_parent = &tsk, \ .parent = &tsk, \ .children = LIST_HEAD_INIT(tsk.children), \ diff --git a/include/linux/sched.h b/include/linux/sched.h index ba2f859..1941d8b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1062,12 +1062,6 @@ struct task_struct { #endif struct list_head tasks; - /* - * ptrace_list/ptrace_children forms the list of my children - * that were stolen by a ptracer. - */ - struct list_head ptrace_children; - struct list_head ptrace_list; struct mm_struct *mm, *active_mm; @@ -1089,18 +1083,25 @@ struct task_struct { /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with - * p->parent->pid) + * p->real_parent->pid) */ - struct task_struct *real_parent; /* real parent process (when being debugged) */ - struct task_struct *parent; /* parent process */ + struct task_struct *real_parent; /* real parent process */ + struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */ /* - * children/sibling forms the list of my children plus the - * tasks I'm ptracing. + * children/sibling forms the list of my natural children */ struct list_head children; /* list of my children */ struct list_head sibling; /* linkage in my parent's children list */ struct task_struct *group_leader; /* threadgroup leader */ + /* + * ptraced is the list of tasks this task is using ptrace on. + * This includes both natural children and PTRACE_ATTACH targets. + * p->ptrace_entry is p's link on the p->parent->ptraced list. + */ + struct list_head ptraced; + struct list_head ptrace_entry; + /* PID/PID hash table linkage. */ struct pid_link pids[PIDTYPE_MAX]; struct list_head thread_group; @@ -1876,9 +1877,6 @@ extern void wait_task_inactive(struct task_struct * p); #define wait_task_inactive(p) do { } while (0) #endif -#define remove_parent(p) list_del_init(&(p)->sibling) -#define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) - #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) #define for_each_process(p) \ diff --git a/kernel/exit.c b/kernel/exit.c index 7453356..1e90982 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -71,7 +71,7 @@ static void __unhash_process(struct task_struct *p) __get_cpu_var(process_counts)--; } list_del_rcu(&p->thread_group); - remove_parent(p); + list_del_init(&p->sibling); } /* @@ -152,6 +152,18 @@ static void delayed_put_task_struct(struct rcu_head *rhp) put_task_struct(container_of(rhp, struct task_struct, rcu)); } +/* + * Do final ptrace-related cleanup of a zombie being reaped. + * + * Called with write_lock(&tasklist_lock) held. + */ +static void ptrace_release_task(struct task_struct *p) +{ + BUG_ON(!list_empty(&p->ptraced)); + ptrace_unlink(p); + BUG_ON(!list_empty(&p->ptrace_entry)); +} + void release_task(struct task_struct * p) { struct task_struct *leader; @@ -160,8 +172,7 @@ repeat: atomic_dec(&p->user->processes); proc_flush_task(p); write_lock_irq(&tasklist_lock); - ptrace_unlink(p); - BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); + ptrace_release_task(p); __exit_signal(p); /* @@ -315,9 +326,8 @@ static void reparent_to_kthreadd(void) ptrace_unlink(current); /* Reparent to init */ - remove_parent(current); current->real_parent = current->parent = kthreadd_task; - add_parent(current); + list_move_tail(¤t->sibling, ¤t->real_parent->children); /* Set the exit signal to SIGCHLD so we signal init on exit */ current->exit_signal = SIGCHLD; @@ -692,37 +702,71 @@ static void exit_mm(struct task_struct * tsk) mmput(mm); } -static void -reparent_thread(struct task_struct *p, struct task_struct *father, int traced) +/* + * Detach all tasks we were using ptrace on. + * Any that need to be release_task'd are put on the @dead list. + * + * Called with write_lock(&tasklist_lock) held. + */ +static void ptrace_exit(struct task_struct *parent, struct list_head *dead) { - if (p->pdeath_signal) - /* We already hold the tasklist_lock here. */ - group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); + struct task_struct *p, *n; - /* Move the child from its dying parent to the new one. */ - if (unlikely(traced)) { - /* Preserve ptrace links if someone else is tracing this child. */ - list_del_init(&p->ptrace_list); - if (ptrace_reparented(p)) - list_add(&p->ptrace_list, &p->real_parent->ptrace_children); - } else { - /* If this child is being traced, then we're the one tracing it - * anyway, so let go of it. + list_for_each_entry_safe(p, n, &parent->ptraced, ptrace_entry) { + __ptrace_unlink(p); + + if (p->exit_state != EXIT_ZOMBIE) + continue; + + /* + * If it's a zombie, our attachedness prevented normal + * parent notification or self-reaping. Do notification + * now if it would have happened earlier. If it should + * reap itself, add it to the @dead list. We can't call + * release_task() here because we already hold tasklist_lock. + * + * If it's our own child, there is no notification to do. */ - p->ptrace = 0; - remove_parent(p); - p->parent = p->real_parent; - add_parent(p); + if (!task_detached(p) && thread_group_empty(p)) { + if (!same_thread_group(p->real_parent, parent)) + do_notify_parent(p, p->exit_signal); + } - if (task_is_traced(p)) { + if (task_detached(p)) { /* - * If it was at a trace stop, turn it into - * a normal stop since it's no longer being - * traced. + * Mark it as in the process of being reaped. */ - ptrace_untrace(p); + p->exit_state = EXIT_DEAD; + list_add(&p->ptrace_entry, dead); } } +} + +/* + * Finish up exit-time ptrace cleanup. + * + * Called without locks. + */ +static void ptrace_exit_finish(struct task_struct *parent, + struct list_head *dead) +{ + struct task_struct *p, *n; + + BUG_ON(!list_empty(&parent->ptraced)); + + list_for_each_entry_safe(p, n, dead, ptrace_entry) { + list_del_init(&p->ptrace_entry); + release_task(p); + } +} + +static void reparent_thread(struct task_struct *p, struct task_struct *father) +{ + if (p->pdeath_signal) + /* We already hold the tasklist_lock here. */ + group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); + + list_move_tail(&p->sibling, &p->real_parent->children); /* If this is a threaded reparent there is no need to * notify anyone anything has happened. @@ -737,7 +781,8 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) /* If we'd notified the old parent about this child's death, * also notify the new parent. */ - if (!traced && p->exit_state == EXIT_ZOMBIE && + if (!ptrace_reparented(p) && + p->exit_state == EXIT_ZOMBIE && !task_detached(p) && thread_group_empty(p)) do_notify_parent(p, p->exit_signal); @@ -754,12 +799,15 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) static void forget_original_parent(struct task_struct *father) { struct task_struct *p, *n, *reaper = father; - struct list_head ptrace_dead; - - INIT_LIST_HEAD(&ptrace_dead); + LIST_HEAD(ptrace_dead); write_lock_irq(&tasklist_lock); + /* + * First clean up ptrace if we were using it. + */ + ptrace_exit(father, &ptrace_dead); + do { reaper = next_thread(reaper); if (reaper == father) { @@ -768,58 +816,19 @@ static void forget_original_parent(struct task_struct *father) } } while (reaper->flags & PF_EXITING); - /* - * There are only two places where our children can be: - * - * - in our child list - * - in our ptraced child list - * - * Search them and reparent children. - */ list_for_each_entry_safe(p, n, &father->children, sibling) { - int ptrace; - - ptrace = p->ptrace; - - /* if father isn't the real parent, then ptrace must be enabled */ - BUG_ON(father != p->real_parent && !ptrace); - - if (father == p->real_parent) { - /* reparent with a reaper, real father it's us */ - p->real_parent = reaper; - reparent_thread(p, father, 0); - } else { - /* reparent ptraced task to its real parent */ - __ptrace_unlink (p); - if (p->exit_state == EXIT_ZOMBIE && !task_detached(p) && - thread_group_empty(p)) - do_notify_parent(p, p->exit_signal); - } - - /* - * if the ptraced child is a detached zombie we must collect - * it before we exit, or it will remain zombie forever since - * we prevented it from self-reap itself while it was being - * traced by us, to be able to see it in wait4. - */ - if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && task_detached(p))) - list_add(&p->ptrace_list, &ptrace_dead); - } - - list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) { p->real_parent = reaper; - reparent_thread(p, father, 1); + if (p->parent == father) { + BUG_ON(p->ptrace); + p->parent = p->real_parent; + } + reparent_thread(p, father); } write_unlock_irq(&tasklist_lock); BUG_ON(!list_empty(&father->children)); - BUG_ON(!list_empty(&father->ptrace_children)); - - list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) { - list_del_init(&p->ptrace_list); - release_task(p); - } + ptrace_exit_finish(father, &ptrace_dead); } /* @@ -1180,13 +1189,6 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options, return 0; } - /* - * Do not consider detached threads that are - * not ptraced: - */ - if (task_detached(p) && !p->ptrace) - return 0; - /* Wait for all children (clone and not) if __WALL is set; * otherwise, wait for clone children *only* if __WCLONE is * set; otherwise, wait for non-clone children *only*. (Note: @@ -1399,7 +1401,7 @@ static int wait_task_zombie(struct task_struct *p, int options, * the lock and this task is uninteresting. If we return nonzero, we have * released the lock and the system call should return. */ -static int wait_task_stopped(struct task_struct *p, +static int wait_task_stopped(int ptrace, struct task_struct *p, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { @@ -1407,7 +1409,7 @@ static int wait_task_stopped(struct task_struct *p, uid_t uid = 0; /* unneeded, required by compiler */ pid_t pid; - if (!(p->ptrace & PT_PTRACED) && !(options & WUNTRACED)) + if (!(options & WUNTRACED)) return 0; exit_code = 0; @@ -1416,7 +1418,7 @@ static int wait_task_stopped(struct task_struct *p, if (unlikely(!task_is_stopped_or_traced(p))) goto unlock_sig; - if (!(p->ptrace & PT_PTRACED) && p->signal->group_stop_count > 0) + if (!ptrace && p->signal->group_stop_count > 0) /* * A group stop is in progress and this is the group leader. * We won't report until all threads have stopped. @@ -1445,7 +1447,7 @@ unlock_sig: */ get_task_struct(p); pid = task_pid_vnr(p); - why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED; + why = ptrace ? CLD_TRAPPED : CLD_STOPPED; read_unlock(&tasklist_lock); if (unlikely(options & WNOWAIT)) @@ -1536,7 +1538,7 @@ static int wait_task_continued(struct task_struct *p, int options, * Returns zero if the search for a child should continue; * then *@notask_error is 0 if @p is an eligible child, or still -ECHILD. */ -static int wait_consider_task(struct task_struct *parent, +static int wait_consider_task(struct task_struct *parent, int ptrace, struct task_struct *p, int *notask_error, enum pid_type type, struct pid *pid, int options, struct siginfo __user *infop, @@ -1546,6 +1548,15 @@ static int wait_consider_task(struct task_struct *parent, if (ret <= 0) return ret; + if (likely(!ptrace) && unlikely(p->ptrace)) { + /* + * This child is hidden by ptrace. + * We aren't allowed to see it now, but eventually we will. + */ + *notask_error = 0; + return 0; + } + if (p->exit_state == EXIT_DEAD) return 0; @@ -1562,7 +1573,8 @@ static int wait_consider_task(struct task_struct *parent, *notask_error = 0; if (task_is_stopped_or_traced(p)) - return wait_task_stopped(p, options, infop, stat_addr, ru); + return wait_task_stopped(ptrace, p, options, + infop, stat_addr, ru); return wait_task_continued(p, options, infop, stat_addr, ru); } @@ -1583,11 +1595,16 @@ static int do_wait_thread(struct task_struct *tsk, int *notask_error, struct task_struct *p; list_for_each_entry(p, &tsk->children, sibling) { - int ret = wait_consider_task(tsk, p, notask_error, - type, pid, options, - infop, stat_addr, ru); - if (ret) - return ret; + /* + * Do not consider detached threads. + */ + if (!task_detached(p)) { + int ret = wait_consider_task(tsk, 0, p, notask_error, + type, pid, options, + infop, stat_addr, ru); + if (ret) + return ret; + } } return 0; @@ -1601,21 +1618,16 @@ static int ptrace_do_wait(struct task_struct *tsk, int *notask_error, struct task_struct *p; /* - * If we never saw an eligile child, check for children stolen by - * ptrace. We don't leave -ECHILD in *@notask_error if there are any, - * because we will eventually be allowed to wait for them again. + * Traditionally we see ptrace'd stopped tasks regardless of options. */ - if (!*notask_error) - return 0; + options |= WUNTRACED; - list_for_each_entry(p, &tsk->ptrace_children, ptrace_list) { - int ret = eligible_child(type, pid, options, p); - if (unlikely(ret < 0)) + list_for_each_entry(p, &tsk->ptraced, ptrace_entry) { + int ret = wait_consider_task(tsk, 1, p, notask_error, + type, pid, options, + infop, stat_addr, ru); + if (ret) return ret; - if (ret) { - *notask_error = 0; - return 0; - } } return 0; diff --git a/kernel/fork.c b/kernel/fork.c index 4bd2f51..adefc11 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1125,8 +1125,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, */ p->group_leader = p; INIT_LIST_HEAD(&p->thread_group); - INIT_LIST_HEAD(&p->ptrace_children); - INIT_LIST_HEAD(&p->ptrace_list); + INIT_LIST_HEAD(&p->ptrace_entry); + INIT_LIST_HEAD(&p->ptraced); /* Now that the task is set up, run cgroup callbacks if * necessary. We need to run them before the task is visible @@ -1198,7 +1198,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, } if (likely(p->pid)) { - add_parent(p); + list_add_tail(&p->sibling, &p->real_parent->children); if (unlikely(p->ptrace & PT_PTRACED)) __ptrace_link(p, current->parent); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index e337390..8392a9d 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -33,13 +33,9 @@ */ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) { - BUG_ON(!list_empty(&child->ptrace_list)); - if (child->parent == new_parent) - return; - list_add(&child->ptrace_list, &child->parent->ptrace_children); - remove_parent(child); + BUG_ON(!list_empty(&child->ptrace_entry)); + list_add(&child->ptrace_entry, &new_parent->ptraced); child->parent = new_parent; - add_parent(child); } /* @@ -73,12 +69,8 @@ void __ptrace_unlink(struct task_struct *child) BUG_ON(!child->ptrace); child->ptrace = 0; - if (ptrace_reparented(child)) { - list_del_init(&child->ptrace_list); - remove_parent(child); - child->parent = child->real_parent; - add_parent(child); - } + child->parent = child->real_parent; + list_del_init(&child->ptrace_entry); if (task_is_traced(child)) ptrace_untrace(child); @@ -492,15 +484,34 @@ int ptrace_traceme(void) /* * Are we already being traced? */ +repeat: task_lock(current); if (!(current->ptrace & PT_PTRACED)) { + /* + * See ptrace_attach() comments about the locking here. + */ + unsigned long flags; + if (!write_trylock_irqsave(&tasklist_lock, flags)) { + task_unlock(current); + do { + cpu_relax(); + } while (!write_can_lock(&tasklist_lock)); + goto repeat; + } + ret = security_ptrace(current->parent, current, PTRACE_MODE_ATTACH); + /* * Set the ptrace bit in the process ptrace flags. + * Then link us on our parent's ptraced list. */ - if (!ret) + if (!ret) { current->ptrace |= PT_PTRACED; + __ptrace_link(current, current->real_parent); + } + + write_unlock_irqrestore(&tasklist_lock, flags); } task_unlock(current); return ret; -- cgit v0.10.2 From 14dd0b81414a58caf0296dbeace016bb0a5d11ab Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 30 Mar 2008 18:41:25 -0700 Subject: do_wait: return security_task_wait() error code in place of -ECHILD This reverts the effect of commit f2cc3eb133baa2e9dc8efd40f417106b2ee520f3 "do_wait: fix security checks". That change reverted the effect of commit 73243284463a761e04d69d22c7516b2be7de096c. The rationale for the original commit still stands. The inconsistent treatment of children hidden by ptrace was an unintended omission in the original change and in no way invalidates its purpose. This makes do_wait return the error returned by security_task_wait() (usually -EACCES) in place of -ECHILD when there are some children the caller would be able to wait for if not for the permission failure. A permission error will give the user a clue to look for security policy problems, rather than for mysterious wait bugs. Signed-off-by: Roland McGrath diff --git a/kernel/exit.c b/kernel/exit.c index 1e90982..a2af6ca 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1199,14 +1199,10 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options, return 0; err = security_task_wait(p); - if (likely(!err)) - return 1; + if (err) + return err; - if (type != PIDTYPE_PID) - return 0; - /* This child was explicitly requested, abort */ - read_unlock(&tasklist_lock); - return err; + return 1; } static int wait_noreap_copyout(struct task_struct *p, pid_t pid, uid_t uid, @@ -1536,7 +1532,8 @@ static int wait_task_continued(struct task_struct *p, int options, * -ECHILD should be in *@notask_error before the first call. * Returns nonzero for a final return, when we have unlocked tasklist_lock. * Returns zero if the search for a child should continue; - * then *@notask_error is 0 if @p is an eligible child, or still -ECHILD. + * then *@notask_error is 0 if @p is an eligible child, + * or another error from security_task_wait(), or still -ECHILD. */ static int wait_consider_task(struct task_struct *parent, int ptrace, struct task_struct *p, int *notask_error, @@ -1545,9 +1542,21 @@ static int wait_consider_task(struct task_struct *parent, int ptrace, int __user *stat_addr, struct rusage __user *ru) { int ret = eligible_child(type, pid, options, p); - if (ret <= 0) + if (!ret) return ret; + if (unlikely(ret < 0)) { + /* + * If we have not yet seen any eligible child, + * then let this error code replace -ECHILD. + * A permission error will give the user a clue + * to look for security policy problems, rather + * than for mysterious wait bugs. + */ + if (*notask_error) + *notask_error = ret; + } + if (likely(!ptrace) && unlikely(p->ptrace)) { /* * This child is hidden by ptrace. @@ -1585,7 +1594,8 @@ static int wait_consider_task(struct task_struct *parent, int ptrace, * -ECHILD should be in *@notask_error before the first call. * Returns nonzero for a final return, when we have unlocked tasklist_lock. * Returns zero if the search for a child should continue; then - * *@notask_error is 0 if there were any eligible children, or still -ECHILD. + * *@notask_error is 0 if there were any eligible children, + * or another error from security_task_wait(), or still -ECHILD. */ static int do_wait_thread(struct task_struct *tsk, int *notask_error, enum pid_type type, struct pid *pid, int options, -- cgit v0.10.2 From 666f164f4fbfa78bd00fb4b74788b42a39842c64 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 8 Apr 2008 23:12:30 -0700 Subject: fix dangling zombie when new parent ignores children This fixes an arcane bug that we think was a regression introduced by commit b2b2cbc4b2a2f389442549399a993a8306420baf. When a parent ignores SIGCHLD (or uses SA_NOCLDWAIT), its children would self-reap but they don't if it's using ptrace on them. When the parent thread later exits and ceases to ptrace a child but leaves other live threads in the parent's thread group, any zombie children are left dangling. The fix makes them self-reap then, as they would have done earlier if ptrace had not been in use. Signed-off-by: Roland McGrath diff --git a/kernel/exit.c b/kernel/exit.c index a2af6ca..93d2711 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -703,6 +703,23 @@ static void exit_mm(struct task_struct * tsk) } /* + * Return nonzero if @parent's children should reap themselves. + * + * Called with write_lock_irq(&tasklist_lock) held. + */ +static int ignoring_children(struct task_struct *parent) +{ + int ret; + struct sighand_struct *psig = parent->sighand; + unsigned long flags; + spin_lock_irqsave(&psig->siglock, flags); + ret = (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN || + (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT)); + spin_unlock_irqrestore(&psig->siglock, flags); + return ret; +} + +/* * Detach all tasks we were using ptrace on. * Any that need to be release_task'd are put on the @dead list. * @@ -711,6 +728,7 @@ static void exit_mm(struct task_struct * tsk) static void ptrace_exit(struct task_struct *parent, struct list_head *dead) { struct task_struct *p, *n; + int ign = -1; list_for_each_entry_safe(p, n, &parent->ptraced, ptrace_entry) { __ptrace_unlink(p); @@ -726,10 +744,18 @@ static void ptrace_exit(struct task_struct *parent, struct list_head *dead) * release_task() here because we already hold tasklist_lock. * * If it's our own child, there is no notification to do. + * But if our normal children self-reap, then this child + * was prevented by ptrace and we must reap it now. */ if (!task_detached(p) && thread_group_empty(p)) { if (!same_thread_group(p->real_parent, parent)) do_notify_parent(p, p->exit_signal); + else { + if (ign < 0) + ign = ignoring_children(parent); + if (ign) + p->exit_signal = -1; + } } if (task_detached(p)) { -- cgit v0.10.2 From 8e9509c827a28e2f365c203c04224f9e9dd1b63a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Jul 2008 13:26:50 +0200 Subject: ftrace: fix merge buglet -tip testing found a bootup hang here: initcall anon_inode_init+0x0/0x130 returned 0 after 0 msecs calling acpi_event_init+0x0/0x57 the bootup should have continued with: initcall acpi_event_init+0x0/0x57 returned 0 after 45 msecs but it hung hard there instead. bisection led to this commit: | commit 5806b81ac1c0c52665b91723fd4146a4f86e386b | Merge: d14c8a6... 6712e29... | Author: Ingo Molnar | Date: Mon Jul 14 16:11:52 2008 +0200 | Merge branch 'auto-ftrace-next' into tracing/for-linus turns out that i made this mistake in the merge: ifdef CONFIG_FTRACE # Do not profile debug utilities CFLAGS_REMOVE_tsc_64.o = -pg CFLAGS_REMOVE_tsc_32.o = -pg those two files got unified meanwhile - so the dont-profile annotation got lost. The proper rule is: CFLAGS_REMOVE_tsc.o = -pg i guess this could have been caught sooner if the CFLAGS_REMOVE* kbuild rule aborted the build if it met a target that does not exist anymore? Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 5112c84..da14061 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -8,8 +8,7 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) ifdef CONFIG_FTRACE # Do not profile debug utilities -CFLAGS_REMOVE_tsc_64.o = -pg -CFLAGS_REMOVE_tsc_32.o = -pg +CFLAGS_REMOVE_tsc.o = -pg CFLAGS_REMOVE_rtc.o = -pg endif -- cgit v0.10.2 From 12e0c95e0ca99f633c9d9f90773037eb178685ad Mon Sep 17 00:00:00 2001 From: Frank Munzert Date: Thu, 17 Jul 2008 17:16:40 +0200 Subject: [S390] zfcpdump: Make SCSI disk dump tool recognize storage holes The kernel part of zfcpdump establishes a new debugfs file zcore/memmap which exports information on memory layout (start address and length of each memory chunk) to its userspace counterpart. Signed-off-by: Frank Munzert Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 047dd92..7fd84be 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -29,6 +29,7 @@ #define TO_USER 0 #define TO_KERNEL 1 +#define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */ enum arch_id { ARCH_S390 = 0, @@ -51,6 +52,7 @@ static struct debug_info *zcore_dbf; static int hsa_available; static struct dentry *zcore_dir; static struct dentry *zcore_file; +static struct dentry *zcore_memmap_file; /* * Copy memory from HSA to kernel or user memory (not reentrant): @@ -476,6 +478,54 @@ static const struct file_operations zcore_fops = { .release = zcore_release, }; +static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + return simple_read_from_buffer(buf, count, ppos, filp->private_data, + MEMORY_CHUNKS * CHUNK_INFO_SIZE); +} + +static int zcore_memmap_open(struct inode *inode, struct file *filp) +{ + int i; + char *buf; + struct mem_chunk *chunk_array; + + chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk), + GFP_KERNEL); + if (!chunk_array) + return -ENOMEM; + detect_memory_layout(chunk_array); + buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL); + if (!buf) { + kfree(chunk_array); + return -ENOMEM; + } + for (i = 0; i < MEMORY_CHUNKS; i++) { + sprintf(buf + (i * CHUNK_INFO_SIZE), "%016llx %016llx ", + (unsigned long long) chunk_array[i].addr, + (unsigned long long) chunk_array[i].size); + if (chunk_array[i].size == 0) + break; + } + kfree(chunk_array); + filp->private_data = buf; + return 0; +} + +static int zcore_memmap_release(struct inode *inode, struct file *filp) +{ + kfree(filp->private_data); + return 0; +} + +static const struct file_operations zcore_memmap_fops = { + .owner = THIS_MODULE, + .read = zcore_memmap_read, + .open = zcore_memmap_open, + .release = zcore_memmap_release, +}; + static void __init set_s390_lc_mask(union save_area *map) { @@ -554,18 +604,44 @@ static int __init check_sdias(void) return 0; } -static void __init zcore_header_init(int arch, struct zcore_header *hdr) +static int __init get_mem_size(unsigned long *mem) +{ + int i; + struct mem_chunk *chunk_array; + + chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk), + GFP_KERNEL); + if (!chunk_array) + return -ENOMEM; + detect_memory_layout(chunk_array); + for (i = 0; i < MEMORY_CHUNKS; i++) { + if (chunk_array[i].size == 0) + break; + *mem += chunk_array[i].size; + } + kfree(chunk_array); + return 0; +} + +static int __init zcore_header_init(int arch, struct zcore_header *hdr) { + int rc; + unsigned long memory = 0; + if (arch == ARCH_S390X) hdr->arch_id = DUMP_ARCH_S390X; else hdr->arch_id = DUMP_ARCH_S390; - hdr->mem_size = sys_info.mem_size; - hdr->rmem_size = sys_info.mem_size; + rc = get_mem_size(&memory); + if (rc) + return rc; + hdr->mem_size = memory; + hdr->rmem_size = memory; hdr->mem_end = sys_info.mem_size; - hdr->num_pages = sys_info.mem_size / PAGE_SIZE; + hdr->num_pages = memory / PAGE_SIZE; hdr->tod = get_clock(); get_cpu_id(&hdr->cpu_id); + return 0; } static int __init zcore_init(void) @@ -608,7 +684,9 @@ static int __init zcore_init(void) if (rc) goto fail; - zcore_header_init(arch, &zcore_header); + rc = zcore_header_init(arch, &zcore_header); + if (rc) + goto fail; zcore_dir = debugfs_create_dir("zcore" , NULL); if (!zcore_dir) { @@ -618,13 +696,22 @@ static int __init zcore_init(void) zcore_file = debugfs_create_file("mem", S_IRUSR, zcore_dir, NULL, &zcore_fops); if (!zcore_file) { - debugfs_remove(zcore_dir); rc = -ENOMEM; - goto fail; + goto fail_dir; + } + zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir, + NULL, &zcore_memmap_fops); + if (!zcore_memmap_file) { + rc = -ENOMEM; + goto fail_file; } hsa_available = 1; return 0; +fail_file: + debugfs_remove(zcore_file); +fail_dir: + debugfs_remove(zcore_dir); fail: diag308(DIAG308_REL_HSA, NULL); return rc; -- cgit v0.10.2 From 9d853caf44e6f969a9ad056a9937e8d97bc2c761 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 17 Jul 2008 17:16:41 +0200 Subject: [S390] dasd: fix unsolicited SIM handling. Add missing schedule_bh and check that there is 32 bit sense data. Signed-off-by: Stefan Haberland Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index e0b7721..3590fdb 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1418,8 +1418,10 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, /* service information message SIM */ - if ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE) { + if (irb->esw.esw0.erw.cons && (irb->ecw[27] & DASD_SENSE_BIT_0) && + ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) { dasd_3990_erp_handle_sim(device, irb->ecw); + dasd_schedule_device_bh(device); return; } -- cgit v0.10.2 From 626f311737770f0fb5c09a6da2ea795a559aa42a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 17 Jul 2008 17:16:42 +0200 Subject: [S390] chsc headers userspace cleanup Kernel headers shouldn't expose functions to userspace. Cc: Cornelia Huck Signed-off-by: Adrian Bunk Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild index 09f3125..bb5e9ed 100644 --- a/include/asm-s390/Kbuild +++ b/include/asm-s390/Kbuild @@ -8,9 +8,9 @@ header-y += ucontext.h header-y += vtoc.h header-y += zcrypt.h header-y += kvm.h -header-y += schid.h header-y += chsc.h unifdef-y += cmb.h unifdef-y += debug.h unifdef-y += chpid.h +unifdef-y += schid.h diff --git a/include/asm-s390/chpid.h b/include/asm-s390/chpid.h index 606844d..dfe3c7f 100644 --- a/include/asm-s390/chpid.h +++ b/include/asm-s390/chpid.h @@ -20,6 +20,9 @@ struct chp_id { u8 id; } __attribute__((packed)); +#ifdef __KERNEL__ +#include + static inline void chp_id_init(struct chp_id *chpid) { memset(chpid, 0, sizeof(struct chp_id)); @@ -40,9 +43,6 @@ static inline void chp_id_next(struct chp_id *chpid) } } -#ifdef __KERNEL__ -#include - static inline int chp_id_is_valid(struct chp_id *chpid) { return (chpid->cssid <= __MAX_CSSID); diff --git a/include/asm-s390/schid.h b/include/asm-s390/schid.h index 5017ffa..7bdc0fe 100644 --- a/include/asm-s390/schid.h +++ b/include/asm-s390/schid.h @@ -10,6 +10,7 @@ struct subchannel_id { __u32 sch_no : 16; } __attribute__ ((packed, aligned(4))); +#ifdef __KERNEL__ /* Helper function for sane state of pre-allocated subchannel_id. */ static inline void @@ -25,4 +26,6 @@ schid_equal(struct subchannel_id *schid1, struct subchannel_id *schid2) return !memcmp(schid1, schid2, sizeof(struct subchannel_id)); } +#endif /* __KERNEL__ */ + #endif /* ASM_SCHID_H */ -- cgit v0.10.2 From 7337194f708bac977511c7890d7038ded187041a Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 17 Jul 2008 17:16:43 +0200 Subject: [S390] dasd: Fix cleanup in dasd_{fba,diag}_check_characteristics(). Signed-off-by: Cornelia Huck Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index d91df38..ab5c5b4 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -333,7 +333,8 @@ dasd_diag_check_device(struct dasd_device *device) if (IS_ERR(block)) { DEV_MESSAGE(KERN_WARNING, device, "%s", "could not allocate dasd block structure"); - kfree(device->private); + device->private = NULL; + kfree(private); return PTR_ERR(block); } device->block = block; @@ -348,7 +349,8 @@ dasd_diag_check_device(struct dasd_device *device) if (rc) { DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device " "information (rc=%d)", rc); - return -ENOTSUPP; + rc = -ENOTSUPP; + goto out; } /* Figure out position of label block */ @@ -362,7 +364,8 @@ dasd_diag_check_device(struct dasd_device *device) default: DEV_MESSAGE(KERN_WARNING, device, "unsupported device class " "(class=%d)", private->rdc_data.vdev_class); - return -ENOTSUPP; + rc = -ENOTSUPP; + goto out; } DBF_DEV_EVENT(DBF_INFO, device, @@ -379,7 +382,8 @@ dasd_diag_check_device(struct dasd_device *device) if (label == NULL) { DEV_MESSAGE(KERN_WARNING, device, "%s", "No memory to allocate initialization request"); - return -ENOMEM; + rc = -ENOMEM; + goto out; } rc = 0; end_block = 0; @@ -403,7 +407,7 @@ dasd_diag_check_device(struct dasd_device *device) DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed"); rc = -EOPNOTSUPP; - goto out; + goto out_label; } mdsk_term_io(device); if (rc == 0) @@ -413,7 +417,7 @@ dasd_diag_check_device(struct dasd_device *device) DEV_MESSAGE(KERN_WARNING, device, "device access failed " "(rc=%d)", rc); rc = -EIO; - goto out; + goto out_label; } /* check for label block */ if (memcmp(label->label_id, DASD_DIAG_CMS1, @@ -439,8 +443,15 @@ dasd_diag_check_device(struct dasd_device *device) (unsigned long) (block->blocks << block->s2b_shift) >> 1); } -out: +out_label: free_page((long) label); +out: + if (rc) { + device->block = NULL; + dasd_free_block(block); + device->private = NULL; + kfree(private); + } return rc; } diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index aee4656..aa0c533 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -139,7 +139,8 @@ dasd_fba_check_characteristics(struct dasd_device *device) if (IS_ERR(block)) { DEV_MESSAGE(KERN_WARNING, device, "%s", "could not allocate dasd block structure"); - kfree(device->private); + device->private = NULL; + kfree(private); return PTR_ERR(block); } device->block = block; @@ -152,6 +153,10 @@ dasd_fba_check_characteristics(struct dasd_device *device) DEV_MESSAGE(KERN_WARNING, device, "Read device characteristics returned error %d", rc); + device->block = NULL; + dasd_free_block(block); + device->private = NULL; + kfree(private); return rc; } -- cgit v0.10.2 From c5a37255493a3a8bf527534c8700dd73bd591fc7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 17 Jul 2008 17:16:44 +0200 Subject: [S390] Increase default warning stacksize. Compiling a kernel with allmodconfig or allyesconfig results in tons of gcc warnings, because the default maximum stacksize from which on gcc will emit a warning is just 256 bytes. Increase this to 2048, so these warnings don't distract from the real warnings that we need to watch at. Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dc8f80..eb530b4 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -289,7 +289,7 @@ config WARN_STACK_SIZE int "Maximum frame size considered safe (128-2048)" range 128 2048 depends on WARN_STACK - default "256" + default "2048" help This allows you to specify the maximum frame size a function may have without the compiler complaining about it. -- cgit v0.10.2 From 8de2ce86cdde64d00fc4a4034008b35d8fc0dc83 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 17 Jul 2008 17:16:45 +0200 Subject: [S390] Fix stacktrace compile bug. Add missing module.h include to fix this: CC arch/s390/kernel/stacktrace.o arch/s390/kernel/stacktrace.c:84: warning: data definition has no type or storage class arch/s390/kernel/stacktrace.c:84: warning: type defaults to 'int' in declaration of 'EXPORT_SYMBOL_GPL' arch/s390/kernel/stacktrace.c:84: warning: parameter names (without types) in function declaration arch/s390/kernel/stacktrace.c:97: warning: data definition has no type or storage class arch/s390/kernel/stacktrace.c:97: warning: type defaults to 'int' in declaration of 'EXPORT_SYMBOL_GPL' arch/s390/kernel/stacktrace.c:97: warning: parameter names (without types) in function declaration Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index 57571f1..8841919 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -10,6 +10,7 @@ #include #include #include +#include static unsigned long save_context_stack(struct stack_trace *trace, unsigned long sp, -- cgit v0.10.2 From b9993a38a9b491a9df48a5bc82d2e03ab44e352a Mon Sep 17 00:00:00 2001 From: Frank Munzert Date: Thu, 17 Jul 2008 17:16:46 +0200 Subject: [S390] vmur: Fix return code handling. Use -EOPNOTSUPP instead of -ENOTSUPP. Signed-off-by: Frank Munzert Signed-off-by: Heiko Carstens Cc: Martin Schwidefsky diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 0a9f1cc..b0ac44b 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -345,7 +345,7 @@ static int get_urd_class(struct urdev *urd) cc = diag210(&ur_diag210); switch (cc) { case 0: - return -ENOTSUPP; + return -EOPNOTSUPP; case 2: return ur_diag210.vrdcvcla; /* virtual device class */ case 3: @@ -621,7 +621,7 @@ static int verify_device(struct urdev *urd) case DEV_CLASS_UR_I: return verify_uri_device(urd); default: - return -ENOTSUPP; + return -EOPNOTSUPP; } } @@ -654,7 +654,7 @@ static int get_file_reclen(struct urdev *urd) case DEV_CLASS_UR_I: return get_uri_file_reclen(urd); default: - return -ENOTSUPP; + return -EOPNOTSUPP; } } @@ -827,7 +827,7 @@ static int ur_probe(struct ccw_device *cdev) goto fail_remove_attr; } if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; goto fail_remove_attr; } spin_lock_irq(get_ccwdev_lock(cdev)); @@ -892,7 +892,7 @@ static int ur_set_online(struct ccw_device *cdev) } else if (urd->cdev->id.cu_type == PRINTER_DEVTYPE) { sprintf(node_id, "vmprt-%s", cdev->dev.bus_id); } else { - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; goto fail_free_cdev; } -- cgit v0.10.2 From dae39843f478d181da5b5e1c2c703dfcaaf838c1 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 17 Jul 2008 17:16:47 +0200 Subject: [S390] cio: Export chsc_error_from_response(). Make chsc_error_from_response() available to chsc callers outside of chsc.c (namely qdio) to avoid duplicating error checking code. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 65264a3..29826fd 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -27,7 +27,13 @@ static void *sei_page; -static int chsc_error_from_response(int response) +/** + * chsc_error_from_response() - convert a chsc response to an error + * @response: chsc response code + * + * Returns an appropriate Linux error code for @response. + */ +int chsc_error_from_response(int response) { switch (response) { case 0x0001: @@ -45,6 +51,7 @@ static int chsc_error_from_response(int response) return -EIO; } } +EXPORT_SYMBOL_GPL(chsc_error_from_response); struct chsc_ssd_area { struct chsc_header request; diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index fb6c4d6..ba59bce 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -101,4 +101,6 @@ void chsc_chp_online(struct chp_id chpid); void chsc_chp_offline(struct chp_id chpid); int chsc_get_channel_measurement_chars(struct channel_path *chp); +int chsc_error_from_response(int response); + #endif -- cgit v0.10.2 From 779e6e1c724d30e0fd1baca78b852e41e3a23c1d Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Thu, 17 Jul 2008 17:16:48 +0200 Subject: [S390] qdio: new qdio driver. List of major changes: - split qdio driver into several files - seperation of thin interrupt code - improved handling for multiple thin interrupt devices - inbound and outbound processing now always runs in tasklet context - significant less tasklet schedules per interrupt needed - merged qebsm with non-qebsm handling - cleanup qdio interface and added kerneldoc - coding style Reviewed-by: Cornelia Huck Reviewed-by: Utz Bacher Reviewed-by: Ursula Braun Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 91e9e3f..bd79bd1 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile @@ -9,4 +9,6 @@ ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o obj-$(CONFIG_CHSC_SCH) += chsc_sch.o obj-$(CONFIG_CCWGROUP) += ccwgroup.o + +qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_perf.o qdio_setup.o obj-$(CONFIG_QDIO) += qdio.o diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c deleted file mode 100644 index 2bf36e1..0000000 --- a/drivers/s390/cio/qdio.c +++ /dev/null @@ -1,3929 +0,0 @@ -/* - * - * linux/drivers/s390/cio/qdio.c - * - * Linux for S/390 QDIO base support, Hipersocket base support - * version 2 - * - * Copyright 2000,2002 IBM Corporation - * Author(s): Utz Bacher - * 2.6 cio integration by Cornelia Huck - * - * Restriction: only 63 iqdio subchannels would have its own indicator, - * after that, subsequent subchannels share one indicator - * - * - * - * - * 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, 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "cio.h" -#include "css.h" -#include "device.h" -#include "qdio.h" -#include "ioasm.h" -#include "chsc.h" - -/****************** MODULE PARAMETER VARIABLES ********************/ -MODULE_AUTHOR("Utz Bacher "); -MODULE_DESCRIPTION("QDIO base support version 2, " \ - "Copyright 2000 IBM Corporation"); -MODULE_LICENSE("GPL"); - -/******************** HERE WE GO ***********************************/ - -static const char version[] = "QDIO base support version 2"; - -static int qdio_performance_stats = 0; -static int proc_perf_file_registration; -static struct qdio_perf_stats perf_stats; - -static int hydra_thinints; -static int is_passthrough = 0; -static int omit_svs; - -static int indicator_used[INDICATORS_PER_CACHELINE]; -static __u32 * volatile indicators; -static __u32 volatile spare_indicator; -static atomic_t spare_indicator_usecount; -#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2 -static mempool_t *qdio_mempool_scssc; -static struct kmem_cache *qdio_q_cache; - -static debug_info_t *qdio_dbf_setup; -static debug_info_t *qdio_dbf_sbal; -static debug_info_t *qdio_dbf_trace; -static debug_info_t *qdio_dbf_sense; -#ifdef CONFIG_QDIO_DEBUG -static debug_info_t *qdio_dbf_slsb_out; -static debug_info_t *qdio_dbf_slsb_in; -#endif /* CONFIG_QDIO_DEBUG */ - -/* iQDIO stuff: */ -static volatile struct qdio_q *tiq_list=NULL; /* volatile as it could change - during a while loop */ -static DEFINE_SPINLOCK(ttiq_list_lock); -static void *tiqdio_ind; -static void tiqdio_tl(unsigned long); -static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0); - -/* not a macro, as one of the arguments is atomic_read */ -static inline int -qdio_min(int a,int b) -{ - if (a> 12); /* time>>12 is microseconds */ -} - -/* - * unfortunately, we can't just xchg the values; in do_QDIO we want to reserve - * the q in any case, so that we'll not be interrupted when we are in - * qdio_mark_tiq... shouldn't have a really bad impact, as reserving almost - * ever works (last famous words) - */ -static inline int -qdio_reserve_q(struct qdio_q *q) -{ - return atomic_add_return(1,&q->use_count) - 1; -} - -static inline void -qdio_release_q(struct qdio_q *q) -{ - atomic_dec(&q->use_count); -} - -/*check ccq */ -static int -qdio_check_ccq(struct qdio_q *q, unsigned int ccq) -{ - char dbf_text[15]; - - if (ccq == 0 || ccq == 32) - return 0; - if (ccq == 96 || ccq == 97) - return 1; - /*notify devices immediately*/ - sprintf(dbf_text,"%d", ccq); - QDIO_DBF_TEXT2(1,trace,dbf_text); - return -EIO; -} -/* EQBS: extract buffer states */ -static int -qdio_do_eqbs(struct qdio_q *q, unsigned char *state, - unsigned int *start, unsigned int *cnt) -{ - struct qdio_irq *irq; - unsigned int tmp_cnt, q_no, ccq; - int rc ; - char dbf_text[15]; - - ccq = 0; - tmp_cnt = *cnt; - irq = (struct qdio_irq*)q->irq_ptr; - q_no = q->q_no; - if(!q->is_input_q) - q_no += irq->no_input_qs; -again: - ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); - rc = qdio_check_ccq(q, ccq); - if ((ccq == 96) && (tmp_cnt != *cnt)) - rc = 0; - if (rc == 1) { - QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); - goto again; - } - if (rc < 0) { - QDIO_DBF_TEXT2(1,trace,"eqberr"); - sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt, *cnt, ccq, q_no); - QDIO_DBF_TEXT2(1,trace,dbf_text); - q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION| - QDIO_STATUS_LOOK_FOR_ERROR, - 0, 0, 0, -1, -1, q->int_parm); - return 0; - } - return (tmp_cnt - *cnt); -} - -/* SQBS: set buffer states */ -static int -qdio_do_sqbs(struct qdio_q *q, unsigned char state, - unsigned int *start, unsigned int *cnt) -{ - struct qdio_irq *irq; - unsigned int tmp_cnt, q_no, ccq; - int rc; - char dbf_text[15]; - - ccq = 0; - tmp_cnt = *cnt; - irq = (struct qdio_irq*)q->irq_ptr; - q_no = q->q_no; - if(!q->is_input_q) - q_no += irq->no_input_qs; -again: - ccq = do_sqbs(irq->sch_token, state, q_no, start, cnt); - rc = qdio_check_ccq(q, ccq); - if (rc == 1) { - QDIO_DBF_TEXT5(1,trace,"sqAGAIN"); - goto again; - } - if (rc < 0) { - QDIO_DBF_TEXT3(1,trace,"sqberr"); - sprintf(dbf_text,"%2x,%2x",tmp_cnt,*cnt); - QDIO_DBF_TEXT3(1,trace,dbf_text); - sprintf(dbf_text,"%d,%d",ccq,q_no); - QDIO_DBF_TEXT3(1,trace,dbf_text); - q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION| - QDIO_STATUS_LOOK_FOR_ERROR, - 0, 0, 0, -1, -1, q->int_parm); - return 0; - } - return (tmp_cnt - *cnt); -} - -static inline int -qdio_set_slsb(struct qdio_q *q, unsigned int *bufno, - unsigned char state, unsigned int *count) -{ - volatile char *slsb; - struct qdio_irq *irq; - - irq = (struct qdio_irq*)q->irq_ptr; - if (!irq->is_qebsm) { - slsb = (char *)&q->slsb.acc.val[(*bufno)]; - xchg(slsb, state); - return 1; - } - return qdio_do_sqbs(q, state, bufno, count); -} - -#ifdef CONFIG_QDIO_DEBUG -static inline void -qdio_trace_slsb(struct qdio_q *q) -{ - if (q->queue_type==QDIO_TRACE_QTYPE) { - if (q->is_input_q) - QDIO_DBF_HEX2(0,slsb_in,&q->slsb, - QDIO_MAX_BUFFERS_PER_Q); - else - QDIO_DBF_HEX2(0,slsb_out,&q->slsb, - QDIO_MAX_BUFFERS_PER_Q); - } -} -#endif - -static inline int -set_slsb(struct qdio_q *q, unsigned int *bufno, - unsigned char state, unsigned int *count) -{ - int rc; -#ifdef CONFIG_QDIO_DEBUG - qdio_trace_slsb(q); -#endif - rc = qdio_set_slsb(q, bufno, state, count); -#ifdef CONFIG_QDIO_DEBUG - qdio_trace_slsb(q); -#endif - return rc; -} -static inline int -qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, - unsigned int gpr3) -{ - int cc; - - QDIO_DBF_TEXT4(0,trace,"sigasync"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - qdio_perf_stat_inc(&perf_stats.siga_syncs); - - cc = do_siga_sync(q->schid, gpr2, gpr3); - if (cc) - QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); - - return cc; -} - -static inline int -qdio_siga_sync_q(struct qdio_q *q) -{ - if (q->is_input_q) - return qdio_siga_sync(q, 0, q->mask); - return qdio_siga_sync(q, q->mask, 0); -} - -static int -__do_siga_output(struct qdio_q *q, unsigned int *busy_bit) -{ - struct qdio_irq *irq; - unsigned int fc = 0; - unsigned long schid; - - irq = (struct qdio_irq *) q->irq_ptr; - if (!irq->is_qebsm) - schid = *((u32 *)&q->schid); - else { - schid = irq->sch_token; - fc |= 0x80; - } - return do_siga_output(schid, q->mask, busy_bit, fc); -} - -/* - * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns - * an access exception - */ -static int -qdio_siga_output(struct qdio_q *q) -{ - int cc; - __u32 busy_bit; - __u64 start_time=0; - - qdio_perf_stat_inc(&perf_stats.siga_outs); - - QDIO_DBF_TEXT4(0,trace,"sigaout"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - for (;;) { - cc = __do_siga_output(q, &busy_bit); -//QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit); - if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) { - if (!start_time) - start_time=NOW; - if ((NOW-start_time)>QDIO_BUSY_BIT_PATIENCE) - break; - } else - break; - } - - if ((cc==2) && (busy_bit)) - cc |= QDIO_SIGA_ERROR_B_BIT_SET; - - if (cc) - QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); - - return cc; -} - -static int -qdio_siga_input(struct qdio_q *q) -{ - int cc; - - QDIO_DBF_TEXT4(0,trace,"sigain"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - qdio_perf_stat_inc(&perf_stats.siga_ins); - - cc = do_siga_input(q->schid, q->mask); - - if (cc) - QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); - - return cc; -} - -/* locked by the locks in qdio_activate and qdio_cleanup */ -static __u32 * -qdio_get_indicator(void) -{ - int i; - - for (i = 0; i < INDICATORS_PER_CACHELINE; i++) - if (!indicator_used[i]) { - indicator_used[i]=1; - return indicators+i; - } - atomic_inc(&spare_indicator_usecount); - return (__u32 * volatile) &spare_indicator; -} - -/* locked by the locks in qdio_activate and qdio_cleanup */ -static void -qdio_put_indicator(__u32 *addr) -{ - int i; - - if ( (addr) && (addr!=&spare_indicator) ) { - i=addr-indicators; - indicator_used[i]=0; - } - if (addr == &spare_indicator) - atomic_dec(&spare_indicator_usecount); -} - -static inline void -tiqdio_clear_summary_bit(__u32 *location) -{ - QDIO_DBF_TEXT5(0,trace,"clrsummb"); - QDIO_DBF_HEX5(0,trace,&location,sizeof(void*)); - - xchg(location,0); -} - -static inline void -tiqdio_set_summary_bit(__u32 *location) -{ - QDIO_DBF_TEXT5(0,trace,"setsummb"); - QDIO_DBF_HEX5(0,trace,&location,sizeof(void*)); - - xchg(location,-1); -} - -static inline void -tiqdio_sched_tl(void) -{ - tasklet_hi_schedule(&tiqdio_tasklet); -} - -static void -qdio_mark_tiq(struct qdio_q *q) -{ - unsigned long flags; - - QDIO_DBF_TEXT4(0,trace,"mark iq"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - spin_lock_irqsave(&ttiq_list_lock,flags); - if (unlikely(atomic_read(&q->is_in_shutdown))) - goto out_unlock; - - if (!q->is_input_q) - goto out_unlock; - - if ((q->list_prev) || (q->list_next)) - goto out_unlock; - - if (!tiq_list) { - tiq_list=q; - q->list_prev=q; - q->list_next=q; - } else { - q->list_next=tiq_list; - q->list_prev=tiq_list->list_prev; - tiq_list->list_prev->list_next=q; - tiq_list->list_prev=q; - } - spin_unlock_irqrestore(&ttiq_list_lock,flags); - - tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); - tiqdio_sched_tl(); - return; -out_unlock: - spin_unlock_irqrestore(&ttiq_list_lock,flags); - return; -} - -static inline void -qdio_mark_q(struct qdio_q *q) -{ - QDIO_DBF_TEXT4(0,trace,"mark q"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - if (unlikely(atomic_read(&q->is_in_shutdown))) - return; - - tasklet_schedule(&q->tasklet); -} - -static int -qdio_stop_polling(struct qdio_q *q) -{ -#ifdef QDIO_USE_PROCESSING_STATE - unsigned int tmp, gsf, count = 1; - unsigned char state = 0; - struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; - - if (!atomic_xchg(&q->polling,0)) - return 1; - - QDIO_DBF_TEXT4(0,trace,"stoppoll"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - /* show the card that we are not polling anymore */ - if (!q->is_input_q) - return 1; - - tmp = gsf = GET_SAVED_FRONTIER(q); - tmp = ((tmp + QDIO_MAX_BUFFERS_PER_Q-1) & (QDIO_MAX_BUFFERS_PER_Q-1) ); - set_slsb(q, &tmp, SLSB_P_INPUT_NOT_INIT, &count); - - /* - * we don't issue this SYNC_MEMORY, as we trust Rick T and - * moreover will not use the PROCESSING state under VM, so - * q->polling was 0 anyway - */ - /*SYNC_MEMORY;*/ - if (irq->is_qebsm) { - count = 1; - qdio_do_eqbs(q, &state, &gsf, &count); - } else - state = q->slsb.acc.val[gsf]; - if (state != SLSB_P_INPUT_PRIMED) - return 1; - /* - * set our summary bit again, as otherwise there is a - * small window we can miss between resetting it and - * checking for PRIMED state - */ - if (q->is_thinint_q) - tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); - return 0; - -#else /* QDIO_USE_PROCESSING_STATE */ - return 1; -#endif /* QDIO_USE_PROCESSING_STATE */ -} - -/* - * see the comment in do_QDIO and before qdio_reserve_q about the - * sophisticated locking outside of unmark_q, so that we don't need to - * disable the interrupts :-) -*/ -static void -qdio_unmark_q(struct qdio_q *q) -{ - unsigned long flags; - - QDIO_DBF_TEXT4(0,trace,"unmark q"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - if ((!q->list_prev)||(!q->list_next)) - return; - - if ((q->is_thinint_q)&&(q->is_input_q)) { - /* iQDIO */ - spin_lock_irqsave(&ttiq_list_lock,flags); - /* in case cleanup has done this already and simultanously - * qdio_unmark_q is called from the interrupt handler, we've - * got to check this in this specific case again */ - if ((!q->list_prev)||(!q->list_next)) - goto out; - if (q->list_next==q) { - /* q was the only interesting q */ - tiq_list=NULL; - q->list_next=NULL; - q->list_prev=NULL; - } else { - q->list_next->list_prev=q->list_prev; - q->list_prev->list_next=q->list_next; - tiq_list=q->list_next; - q->list_next=NULL; - q->list_prev=NULL; - } -out: - spin_unlock_irqrestore(&ttiq_list_lock,flags); - } -} - -static inline unsigned long -tiqdio_clear_global_summary(void) -{ - unsigned long time; - - QDIO_DBF_TEXT5(0,trace,"clrglobl"); - - time = do_clear_global_summary(); - - QDIO_DBF_HEX5(0,trace,&time,sizeof(unsigned long)); - - return time; -} - - -/************************* OUTBOUND ROUTINES *******************************/ -static int -qdio_qebsm_get_outbound_buffer_frontier(struct qdio_q *q) -{ - struct qdio_irq *irq; - unsigned char state; - unsigned int cnt, count, ftc; - - irq = (struct qdio_irq *) q->irq_ptr; - if ((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) - SYNC_MEMORY; - - ftc = q->first_to_check; - count = qdio_min(atomic_read(&q->number_of_buffers_used), - (QDIO_MAX_BUFFERS_PER_Q-1)); - if (count == 0) - return q->first_to_check; - cnt = qdio_do_eqbs(q, &state, &ftc, &count); - if (cnt == 0) - return q->first_to_check; - switch (state) { - case SLSB_P_OUTPUT_ERROR: - QDIO_DBF_TEXT3(0,trace,"outperr"); - atomic_sub(cnt , &q->number_of_buffers_used); - if (q->qdio_error) - q->error_status_flags |= - QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; - q->qdio_error = SLSB_P_OUTPUT_ERROR; - q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR; - q->first_to_check = ftc; - break; - case SLSB_P_OUTPUT_EMPTY: - QDIO_DBF_TEXT5(0,trace,"outpempt"); - atomic_sub(cnt, &q->number_of_buffers_used); - q->first_to_check = ftc; - break; - case SLSB_CU_OUTPUT_PRIMED: - /* all buffers primed */ - QDIO_DBF_TEXT5(0,trace,"outpprim"); - break; - default: - break; - } - QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); - return q->first_to_check; -} - -static int -qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q) -{ - struct qdio_irq *irq; - unsigned char state; - int tmp, ftc, count, cnt; - char dbf_text[15]; - - - irq = (struct qdio_irq *) q->irq_ptr; - ftc = q->first_to_check; - count = qdio_min(atomic_read(&q->number_of_buffers_used), - (QDIO_MAX_BUFFERS_PER_Q-1)); - if (count == 0) - return q->first_to_check; - cnt = qdio_do_eqbs(q, &state, &ftc, &count); - if (cnt == 0) - return q->first_to_check; - switch (state) { - case SLSB_P_INPUT_ERROR : -#ifdef CONFIG_QDIO_DEBUG - QDIO_DBF_TEXT3(1,trace,"inperr"); - sprintf(dbf_text,"%2x,%2x",ftc,count); - QDIO_DBF_TEXT3(1,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - if (q->qdio_error) - q->error_status_flags |= - QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; - q->qdio_error = SLSB_P_INPUT_ERROR; - q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR; - atomic_sub(cnt, &q->number_of_buffers_used); - q->first_to_check = ftc; - break; - case SLSB_P_INPUT_PRIMED : - QDIO_DBF_TEXT3(0,trace,"inptprim"); - sprintf(dbf_text,"%2x,%2x",ftc,count); - QDIO_DBF_TEXT3(1,trace,dbf_text); - tmp = 0; - ftc = q->first_to_check; -#ifdef QDIO_USE_PROCESSING_STATE - if (cnt > 1) { - cnt -= 1; - tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt); - if (!tmp) - break; - } - cnt = 1; - tmp += set_slsb(q, &ftc, - SLSB_P_INPUT_PROCESSING, &cnt); - atomic_set(&q->polling, 1); -#else - tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt); -#endif - atomic_sub(tmp, &q->number_of_buffers_used); - q->first_to_check = ftc; - break; - case SLSB_CU_INPUT_EMPTY: - case SLSB_P_INPUT_NOT_INIT: - case SLSB_P_INPUT_PROCESSING: - QDIO_DBF_TEXT5(0,trace,"inpnipro"); - break; - default: - break; - } - QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); - return q->first_to_check; -} - -static int -qdio_get_outbound_buffer_frontier(struct qdio_q *q) -{ - struct qdio_irq *irq; - volatile char *slsb; - unsigned int count = 1; - int first_not_to_check, f, f_mod_no; - char dbf_text[15]; - - QDIO_DBF_TEXT4(0,trace,"getobfro"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - irq = (struct qdio_irq *) q->irq_ptr; - if (irq->is_qebsm) - return qdio_qebsm_get_outbound_buffer_frontier(q); - - slsb=&q->slsb.acc.val[0]; - f_mod_no=f=q->first_to_check; - /* - * f points to already processed elements, so f+no_used is correct... - * ... but: we don't check 128 buffers, as otherwise - * qdio_has_outbound_q_moved would return 0 - */ - first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), - (QDIO_MAX_BUFFERS_PER_Q-1)); - - if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || - (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) - SYNC_MEMORY; - -check_next: - if (f==first_not_to_check) - goto out; - - switch(slsb[f_mod_no]) { - - /* the adapter has not fetched the output yet */ - case SLSB_CU_OUTPUT_PRIMED: - QDIO_DBF_TEXT5(0,trace,"outpprim"); - break; - - /* the adapter got it */ - case SLSB_P_OUTPUT_EMPTY: - atomic_dec(&q->number_of_buffers_used); - f++; - f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1); - QDIO_DBF_TEXT5(0,trace,"outpempt"); - goto check_next; - - case SLSB_P_OUTPUT_ERROR: - QDIO_DBF_TEXT3(0,trace,"outperr"); - sprintf(dbf_text,"%x-%x-%x",f_mod_no, - q->sbal[f_mod_no]->element[14].sbalf.value, - q->sbal[f_mod_no]->element[15].sbalf.value); - QDIO_DBF_TEXT3(1,trace,dbf_text); - QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); - - /* kind of process the buffer */ - set_slsb(q, &f_mod_no, SLSB_P_OUTPUT_NOT_INIT, &count); - - /* - * we increment the frontier, as this buffer - * was processed obviously - */ - atomic_dec(&q->number_of_buffers_used); - f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1); - - if (q->qdio_error) - q->error_status_flags|= - QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; - q->qdio_error=SLSB_P_OUTPUT_ERROR; - q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR; - - break; - - /* no new buffers */ - default: - QDIO_DBF_TEXT5(0,trace,"outpni"); - } -out: - return (q->first_to_check=f_mod_no); -} - -/* all buffers are processed */ -static int -qdio_is_outbound_q_done(struct qdio_q *q) -{ - int no_used; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; -#endif - - no_used=atomic_read(&q->number_of_buffers_used); - -#ifdef CONFIG_QDIO_DEBUG - if (no_used) { - sprintf(dbf_text,"oqisnt%02x",no_used); - QDIO_DBF_TEXT4(0,trace,dbf_text); - } else { - QDIO_DBF_TEXT4(0,trace,"oqisdone"); - } - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); -#endif /* CONFIG_QDIO_DEBUG */ - return (no_used==0); -} - -static int -qdio_has_outbound_q_moved(struct qdio_q *q) -{ - int i; - - i=qdio_get_outbound_buffer_frontier(q); - - if ( (i!=GET_SAVED_FRONTIER(q)) || - (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) { - SAVE_FRONTIER(q,i); - QDIO_DBF_TEXT4(0,trace,"oqhasmvd"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - return 1; - } else { - QDIO_DBF_TEXT4(0,trace,"oqhsntmv"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - return 0; - } -} - -static void -qdio_kick_outbound_q(struct qdio_q *q) -{ - int result; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; - - QDIO_DBF_TEXT4(0,trace,"kickoutq"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); -#endif /* CONFIG_QDIO_DEBUG */ - - if (!q->siga_out) - return; - - /* here's the story with cc=2 and busy bit set (thanks, Rick): - * VM's CP could present us cc=2 and busy bit set on SIGA-write - * during reconfiguration of their Guest LAN (only in HIPERS mode, - * QDIO mode is asynchronous -- cc=2 and busy bit there will take - * the queues down immediately; and not being under VM we have a - * problem on cc=2 and busy bit set right away). - * - * Therefore qdio_siga_output will try for a short time constantly, - * if such a condition occurs. If it doesn't change, it will - * increase the busy_siga_counter and save the timestamp, and - * schedule the queue for later processing (via mark_q, using the - * queue tasklet). __qdio_outbound_processing will check out the - * counter. If non-zero, it will call qdio_kick_outbound_q as often - * as the value of the counter. This will attempt further SIGA - * instructions. For each successful SIGA, the counter is - * decreased, for failing SIGAs the counter remains the same, after - * all. - * After some time of no movement, qdio_kick_outbound_q will - * finally fail and reflect corresponding error codes to call - * the upper layer module and have it take the queues down. - * - * Note that this is a change from the original HiperSockets design - * (saying cc=2 and busy bit means take the queues down), but in - * these days Guest LAN didn't exist... excessive cc=2 with busy bit - * conditions will still take the queues down, but the threshold is - * higher due to the Guest LAN environment. - */ - - - result=qdio_siga_output(q); - - switch (result) { - case 0: - /* went smooth this time, reset timestamp */ -#ifdef CONFIG_QDIO_DEBUG - QDIO_DBF_TEXT3(0,trace,"cc2reslv"); - sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no, - atomic_read(&q->busy_siga_counter)); - QDIO_DBF_TEXT3(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - q->timing.busy_start=0; - break; - case (2|QDIO_SIGA_ERROR_B_BIT_SET): - /* cc=2 and busy bit: */ - atomic_inc(&q->busy_siga_counter); - - /* if the last siga was successful, save - * timestamp here */ - if (!q->timing.busy_start) - q->timing.busy_start=NOW; - - /* if we're in time, don't touch error_status_flags - * and siga_error */ - if (NOW-q->timing.busy_startschid.sch_no,q->q_no, - atomic_read(&q->busy_siga_counter)); - QDIO_DBF_TEXT3(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - /* else fallthrough and report error */ - default: - /* for plain cc=1, 2 or 3: */ - if (q->siga_error) - q->error_status_flags|= - QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR; - q->error_status_flags|= - QDIO_STATUS_LOOK_FOR_ERROR; - q->siga_error=result; - } -} - -static void -qdio_kick_outbound_handler(struct qdio_q *q) -{ - int start, end, real_end, count; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; -#endif - - start = q->first_element_to_kick; - /* last_move_ftc was just updated */ - real_end = GET_SAVED_FRONTIER(q); - end = (real_end+QDIO_MAX_BUFFERS_PER_Q-1)& - (QDIO_MAX_BUFFERS_PER_Q-1); - count = (end+QDIO_MAX_BUFFERS_PER_Q+1-start)& - (QDIO_MAX_BUFFERS_PER_Q-1); - -#ifdef CONFIG_QDIO_DEBUG - QDIO_DBF_TEXT4(0,trace,"kickouth"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - sprintf(dbf_text,"s=%2xc=%2x",start,count); - QDIO_DBF_TEXT4(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - if (q->state==QDIO_IRQ_STATE_ACTIVE) - q->handler(q->cdev,QDIO_STATUS_OUTBOUND_INT| - q->error_status_flags, - q->qdio_error,q->siga_error,q->q_no,start,count, - q->int_parm); - - /* for the next time: */ - q->first_element_to_kick=real_end; - q->qdio_error=0; - q->siga_error=0; - q->error_status_flags=0; -} - -static void -__qdio_outbound_processing(struct qdio_q *q) -{ - int siga_attempts; - - QDIO_DBF_TEXT4(0,trace,"qoutproc"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - if (unlikely(qdio_reserve_q(q))) { - qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.outbound_tl_runs_resched); - /* as we're sissies, we'll check next time */ - if (likely(!atomic_read(&q->is_in_shutdown))) { - qdio_mark_q(q); - QDIO_DBF_TEXT4(0,trace,"busy,agn"); - } - return; - } - qdio_perf_stat_inc(&perf_stats.outbound_tl_runs); - qdio_perf_stat_inc(&perf_stats.tl_runs); - - /* see comment in qdio_kick_outbound_q */ - siga_attempts=atomic_read(&q->busy_siga_counter); - while (siga_attempts) { - atomic_dec(&q->busy_siga_counter); - qdio_kick_outbound_q(q); - siga_attempts--; - } - - if (qdio_has_outbound_q_moved(q)) - qdio_kick_outbound_handler(q); - - if (q->queue_type == QDIO_ZFCP_QFMT) { - if ((!q->hydra_gives_outbound_pcis) && - (!qdio_is_outbound_q_done(q))) - qdio_mark_q(q); - } - else if (((!q->is_iqdio_q) && (!q->is_pci_out)) || - (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) { - /* - * make sure buffer switch from PRIMED to EMPTY is noticed - * and outbound_handler is called - */ - if (qdio_is_outbound_q_done(q)) { - del_timer(&q->timer); - } else { - if (!timer_pending(&q->timer)) - mod_timer(&q->timer, jiffies + - QDIO_FORCE_CHECK_TIMEOUT); - } - } - - qdio_release_q(q); -} - -static void -qdio_outbound_processing(unsigned long q) -{ - __qdio_outbound_processing((struct qdio_q *) q); -} - -/************************* INBOUND ROUTINES *******************************/ - - -static int -qdio_get_inbound_buffer_frontier(struct qdio_q *q) -{ - struct qdio_irq *irq; - int f,f_mod_no; - volatile char *slsb; - unsigned int count = 1; - int first_not_to_check; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; -#endif /* CONFIG_QDIO_DEBUG */ -#ifdef QDIO_USE_PROCESSING_STATE - int last_position=-1; -#endif /* QDIO_USE_PROCESSING_STATE */ - - QDIO_DBF_TEXT4(0,trace,"getibfro"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - irq = (struct qdio_irq *) q->irq_ptr; - if (irq->is_qebsm) - return qdio_qebsm_get_inbound_buffer_frontier(q); - - slsb=&q->slsb.acc.val[0]; - f_mod_no=f=q->first_to_check; - /* - * we don't check 128 buffers, as otherwise qdio_has_inbound_q_moved - * would return 0 - */ - first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), - (QDIO_MAX_BUFFERS_PER_Q-1)); - - /* - * we don't use this one, as a PCI or we after a thin interrupt - * will sync the queues - */ - /* SYNC_MEMORY;*/ - -check_next: - f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1); - if (f==first_not_to_check) - goto out; - switch (slsb[f_mod_no]) { - - /* CU_EMPTY means frontier is reached */ - case SLSB_CU_INPUT_EMPTY: - QDIO_DBF_TEXT5(0,trace,"inptempt"); - break; - - /* P_PRIMED means set slsb to P_PROCESSING and move on */ - case SLSB_P_INPUT_PRIMED: - QDIO_DBF_TEXT5(0,trace,"inptprim"); - -#ifdef QDIO_USE_PROCESSING_STATE - /* - * as soon as running under VM, polling the input queues will - * kill VM in terms of CP overhead - */ - if (q->siga_sync) { - set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count); - } else { - /* set the previous buffer to NOT_INIT. The current - * buffer will be set to PROCESSING at the end of - * this function to avoid further interrupts. */ - if (last_position>=0) - set_slsb(q, &last_position, - SLSB_P_INPUT_NOT_INIT, &count); - atomic_set(&q->polling,1); - last_position=f_mod_no; - } -#else /* QDIO_USE_PROCESSING_STATE */ - set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count); -#endif /* QDIO_USE_PROCESSING_STATE */ - /* - * not needed, as the inbound queue will be synced on the next - * siga-r, resp. tiqdio_is_inbound_q_done will do the siga-s - */ - /*SYNC_MEMORY;*/ - f++; - atomic_dec(&q->number_of_buffers_used); - goto check_next; - - case SLSB_P_INPUT_NOT_INIT: - case SLSB_P_INPUT_PROCESSING: - QDIO_DBF_TEXT5(0,trace,"inpnipro"); - break; - - /* P_ERROR means frontier is reached, break and report error */ - case SLSB_P_INPUT_ERROR: -#ifdef CONFIG_QDIO_DEBUG - sprintf(dbf_text,"inperr%2x",f_mod_no); - QDIO_DBF_TEXT3(1,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); - - /* kind of process the buffer */ - set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count); - - if (q->qdio_error) - q->error_status_flags|= - QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; - q->qdio_error=SLSB_P_INPUT_ERROR; - q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR; - - /* we increment the frontier, as this buffer - * was processed obviously */ - f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1); - atomic_dec(&q->number_of_buffers_used); - -#ifdef QDIO_USE_PROCESSING_STATE - last_position=-1; -#endif /* QDIO_USE_PROCESSING_STATE */ - - break; - - /* everything else means frontier not changed (HALTED or so) */ - default: - break; - } -out: - q->first_to_check=f_mod_no; - -#ifdef QDIO_USE_PROCESSING_STATE - if (last_position>=0) - set_slsb(q, &last_position, SLSB_P_INPUT_PROCESSING, &count); -#endif /* QDIO_USE_PROCESSING_STATE */ - - QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); - - return q->first_to_check; -} - -static int -qdio_has_inbound_q_moved(struct qdio_q *q) -{ - int i; - - i=qdio_get_inbound_buffer_frontier(q); - if ( (i!=GET_SAVED_FRONTIER(q)) || - (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) { - SAVE_FRONTIER(q,i); - if ((!q->siga_sync)&&(!q->hydra_gives_outbound_pcis)) - SAVE_TIMESTAMP(q); - - QDIO_DBF_TEXT4(0,trace,"inhasmvd"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - return 1; - } else { - QDIO_DBF_TEXT4(0,trace,"inhsntmv"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - return 0; - } -} - -/* means, no more buffers to be filled */ -static int -tiqdio_is_inbound_q_done(struct qdio_q *q) -{ - int no_used; - unsigned int start_buf, count; - unsigned char state = 0; - struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; - -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; -#endif - - no_used=atomic_read(&q->number_of_buffers_used); - - /* propagate the change from 82 to 80 through VM */ - SYNC_MEMORY; - -#ifdef CONFIG_QDIO_DEBUG - if (no_used) { - sprintf(dbf_text,"iqisnt%02x",no_used); - QDIO_DBF_TEXT4(0,trace,dbf_text); - } else { - QDIO_DBF_TEXT4(0,trace,"iniqisdo"); - } - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); -#endif /* CONFIG_QDIO_DEBUG */ - - if (!no_used) - return 1; - if (irq->is_qebsm) { - count = 1; - start_buf = q->first_to_check; - qdio_do_eqbs(q, &state, &start_buf, &count); - } else - state = q->slsb.acc.val[q->first_to_check]; - if (state != SLSB_P_INPUT_PRIMED) - /* - * nothing more to do, if next buffer is not PRIMED. - * note that we did a SYNC_MEMORY before, that there - * has been a sychnronization. - * we will return 0 below, as there is nothing to do - * (stop_polling not necessary, as we have not been - * using the PROCESSING state - */ - return 0; - - /* - * ok, the next input buffer is primed. that means, that device state - * change indicator and adapter local summary are set, so we will find - * it next time. - * we will return 0 below, as there is nothing to do, except scheduling - * ourselves for the next time. - */ - tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); - tiqdio_sched_tl(); - return 0; -} - -static int -qdio_is_inbound_q_done(struct qdio_q *q) -{ - int no_used; - unsigned int start_buf, count; - unsigned char state = 0; - struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; - -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; -#endif - - no_used=atomic_read(&q->number_of_buffers_used); - - /* - * we need that one for synchronization with the adapter, as it - * does a kind of PCI avoidance - */ - SYNC_MEMORY; - - if (!no_used) { - QDIO_DBF_TEXT4(0,trace,"inqisdnA"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - return 1; - } - if (irq->is_qebsm) { - count = 1; - start_buf = q->first_to_check; - qdio_do_eqbs(q, &state, &start_buf, &count); - } else - state = q->slsb.acc.val[q->first_to_check]; - if (state == SLSB_P_INPUT_PRIMED) { - /* we got something to do */ - QDIO_DBF_TEXT4(0,trace,"inqisntA"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - return 0; - } - - /* on VM, we don't poll, so the q is always done here */ - if (q->siga_sync) - return 1; - if (q->hydra_gives_outbound_pcis) - return 1; - - /* - * at this point we know, that inbound first_to_check - * has (probably) not moved (see qdio_inbound_processing) - */ - if (NOW>GET_SAVED_TIMESTAMP(q)+q->timing.threshold) { -#ifdef CONFIG_QDIO_DEBUG - QDIO_DBF_TEXT4(0,trace,"inqisdon"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used); - QDIO_DBF_TEXT4(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - return 1; - } else { -#ifdef CONFIG_QDIO_DEBUG - QDIO_DBF_TEXT4(0,trace,"inqisntd"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used); - QDIO_DBF_TEXT4(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - return 0; - } -} - -static void -qdio_kick_inbound_handler(struct qdio_q *q) -{ - int count, start, end, real_end, i; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; -#endif - - QDIO_DBF_TEXT4(0,trace,"kickinh"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - start=q->first_element_to_kick; - real_end=q->first_to_check; - end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&(QDIO_MAX_BUFFERS_PER_Q-1); - - i=start; - count=0; - while (1) { - count++; - if (i==end) - break; - i=(i+1)&(QDIO_MAX_BUFFERS_PER_Q-1); - } - -#ifdef CONFIG_QDIO_DEBUG - sprintf(dbf_text,"s=%2xc=%2x",start,count); - QDIO_DBF_TEXT4(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - if (likely(q->state==QDIO_IRQ_STATE_ACTIVE)) - q->handler(q->cdev, - QDIO_STATUS_INBOUND_INT|q->error_status_flags, - q->qdio_error,q->siga_error,q->q_no,start,count, - q->int_parm); - - /* for the next time: */ - q->first_element_to_kick=real_end; - q->qdio_error=0; - q->siga_error=0; - q->error_status_flags=0; - - qdio_perf_stat_inc(&perf_stats.inbound_cnt); -} - -static void -__tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) -{ - struct qdio_irq *irq_ptr; - struct qdio_q *oq; - int i; - - QDIO_DBF_TEXT4(0,trace,"iqinproc"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - /* - * we first want to reserve the q, so that we know, that we don't - * interrupt ourselves and call qdio_unmark_q, as is_in_shutdown might - * be set - */ - if (unlikely(qdio_reserve_q(q))) { - qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs_resched); - /* - * as we might just be about to stop polling, we make - * sure that we check again at least once more - */ - tiqdio_sched_tl(); - return; - } - qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs); - if (unlikely(atomic_read(&q->is_in_shutdown))) { - qdio_unmark_q(q); - goto out; - } - - /* - * we reset spare_ind_was_set, when the queue does not use the - * spare indicator - */ - if (spare_ind_was_set) - spare_ind_was_set = (q->dev_st_chg_ind == &spare_indicator); - - if (!(*(q->dev_st_chg_ind)) && !spare_ind_was_set) - goto out; - /* - * q->dev_st_chg_ind is the indicator, be it shared or not. - * only clear it, if indicator is non-shared - */ - if (q->dev_st_chg_ind != &spare_indicator) - tiqdio_clear_summary_bit((__u32*)q->dev_st_chg_ind); - - if (q->hydra_gives_outbound_pcis) { - if (!q->siga_sync_done_on_thinints) { - SYNC_MEMORY_ALL; - } else if (!q->siga_sync_done_on_outb_tis) { - SYNC_MEMORY_ALL_OUTB; - } - } else { - SYNC_MEMORY; - } - /* - * maybe we have to do work on our outbound queues... at least - * we have to check the outbound-int-capable thinint-capable - * queues - */ - if (q->hydra_gives_outbound_pcis) { - irq_ptr = (struct qdio_irq*)q->irq_ptr; - for (i=0;ino_output_qs;i++) { - oq = irq_ptr->output_qs[i]; - if (!qdio_is_outbound_q_done(oq)) { - qdio_perf_stat_dec(&perf_stats.tl_runs); - __qdio_outbound_processing(oq); - } - } - } - - if (!qdio_has_inbound_q_moved(q)) - goto out; - - qdio_kick_inbound_handler(q); - if (tiqdio_is_inbound_q_done(q)) - if (!qdio_stop_polling(q)) { - /* - * we set the flags to get into the stuff next time, - * see also comment in qdio_stop_polling - */ - tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); - tiqdio_sched_tl(); - } -out: - qdio_release_q(q); -} - -static void -tiqdio_inbound_processing(unsigned long q) -{ - __tiqdio_inbound_processing((struct qdio_q *) q, - atomic_read(&spare_indicator_usecount)); -} - -static void -__qdio_inbound_processing(struct qdio_q *q) -{ - int q_laps=0; - - QDIO_DBF_TEXT4(0,trace,"qinproc"); - QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - - if (unlikely(qdio_reserve_q(q))) { - qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.inbound_tl_runs_resched); - /* as we're sissies, we'll check next time */ - if (likely(!atomic_read(&q->is_in_shutdown))) { - qdio_mark_q(q); - QDIO_DBF_TEXT4(0,trace,"busy,agn"); - } - return; - } - qdio_perf_stat_inc(&perf_stats.inbound_tl_runs); - qdio_perf_stat_inc(&perf_stats.tl_runs); - -again: - if (qdio_has_inbound_q_moved(q)) { - qdio_kick_inbound_handler(q); - if (!qdio_stop_polling(q)) { - q_laps++; - if (q_lapssiga_sync) - return 2; - - if (unlikely(qdio_reserve_q(q))) { - qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs_resched); - /* - * as we might just be about to stop polling, we make - * sure that we check again at least once more - */ - - /* - * sanity -- we'd get here without setting the - * dev st chg ind - */ - tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind); - tiqdio_sched_tl(); - return 0; - } - if (qdio_stop_polling(q)) { - qdio_release_q(q); - return 2; - } - if (q_lapsdev_st_chg_ind); - tiqdio_sched_tl(); - qdio_release_q(q); - return 1; - -} -#endif /* QDIO_USE_PROCESSING_STATE */ - -static void -tiqdio_inbound_checks(void) -{ - struct qdio_q *q; - int spare_ind_was_set=0; -#ifdef QDIO_USE_PROCESSING_STATE - int q_laps=0; -#endif /* QDIO_USE_PROCESSING_STATE */ - - QDIO_DBF_TEXT4(0,trace,"iqdinbck"); - QDIO_DBF_TEXT5(0,trace,"iqlocsum"); - -#ifdef QDIO_USE_PROCESSING_STATE -again: -#endif /* QDIO_USE_PROCESSING_STATE */ - - /* when the spare indicator is used and set, save that and clear it */ - if ((atomic_read(&spare_indicator_usecount)) && spare_indicator) { - spare_ind_was_set = 1; - tiqdio_clear_summary_bit((__u32*)&spare_indicator); - } - - q=(struct qdio_q*)tiq_list; - do { - if (!q) - break; - __tiqdio_inbound_processing(q, spare_ind_was_set); - q=(struct qdio_q*)q->list_next; - } while (q!=(struct qdio_q*)tiq_list); - -#ifdef QDIO_USE_PROCESSING_STATE - q=(struct qdio_q*)tiq_list; - do { - int ret; - - ret = tiqdio_reset_processing_state(q, q_laps); - switch (ret) { - case 0: - return; - case 1: - q_laps++; - case 2: - q = (struct qdio_q*)q->list_next; - break; - default: - q_laps++; - goto again; - } - } while (q!=(struct qdio_q*)tiq_list); -#endif /* QDIO_USE_PROCESSING_STATE */ -} - -static void -tiqdio_tl(unsigned long data) -{ - QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); - - qdio_perf_stat_inc(&perf_stats.tl_runs); - - tiqdio_inbound_checks(); -} - -/********************* GENERAL HELPER_ROUTINES ***********************/ - -static void -qdio_release_irq_memory(struct qdio_irq *irq_ptr) -{ - int i; - struct qdio_q *q; - - for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) { - q = irq_ptr->input_qs[i]; - if (q) { - free_page((unsigned long) q->slib); - kmem_cache_free(qdio_q_cache, q); - } - q = irq_ptr->output_qs[i]; - if (q) { - free_page((unsigned long) q->slib); - kmem_cache_free(qdio_q_cache, q); - } - } - free_page((unsigned long) irq_ptr->qdr); - free_page((unsigned long) irq_ptr); -} - -static void -qdio_set_impl_params(struct qdio_irq *irq_ptr, - unsigned int qib_param_field_format, - /* pointer to 128 bytes or NULL, if no param field */ - unsigned char *qib_param_field, - /* pointer to no_queues*128 words of data or NULL */ - unsigned int no_input_qs, - unsigned int no_output_qs, - unsigned long *input_slib_elements, - unsigned long *output_slib_elements) -{ - int i,j; - - if (!irq_ptr) - return; - - irq_ptr->qib.pfmt=qib_param_field_format; - if (qib_param_field) - memcpy(irq_ptr->qib.parm,qib_param_field, - QDIO_MAX_BUFFERS_PER_Q); - - if (input_slib_elements) - for (i=0;iinput_qs[i]->slib->slibe[j].parms= - input_slib_elements[ - i*QDIO_MAX_BUFFERS_PER_Q+j]; - } - if (output_slib_elements) - for (i=0;ioutput_qs[i]->slib->slibe[j].parms= - output_slib_elements[ - i*QDIO_MAX_BUFFERS_PER_Q+j]; - } -} - -static int -qdio_alloc_qs(struct qdio_irq *irq_ptr, - int no_input_qs, int no_output_qs) -{ - int i; - struct qdio_q *q; - - for (i = 0; i < no_input_qs; i++) { - q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); - if (!q) - return -ENOMEM; - memset(q, 0, sizeof(*q)); - - q->slib = (struct slib *) __get_free_page(GFP_KERNEL); - if (!q->slib) { - kmem_cache_free(qdio_q_cache, q); - return -ENOMEM; - } - irq_ptr->input_qs[i]=q; - } - - for (i = 0; i < no_output_qs; i++) { - q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); - if (!q) - return -ENOMEM; - memset(q, 0, sizeof(*q)); - - q->slib = (struct slib *) __get_free_page(GFP_KERNEL); - if (!q->slib) { - kmem_cache_free(qdio_q_cache, q); - return -ENOMEM; - } - irq_ptr->output_qs[i]=q; - } - return 0; -} - -static void -qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, - int no_input_qs, int no_output_qs, - qdio_handler_t *input_handler, - qdio_handler_t *output_handler, - unsigned long int_parm,int q_format, - unsigned long flags, - void **inbound_sbals_array, - void **outbound_sbals_array) -{ - struct qdio_q *q; - int i,j; - char dbf_text[20]; /* see qdio_initialize */ - void *ptr; - int available; - - sprintf(dbf_text,"qfqs%4x",cdev->private->schid.sch_no); - QDIO_DBF_TEXT0(0,setup,dbf_text); - for (i=0;iinput_qs[i]; - - memset(q,0,((char*)&q->slib)-((char*)q)); - sprintf(dbf_text,"in-q%4x",i); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_HEX0(0,setup,&q,sizeof(void*)); - - memset(q->slib,0,PAGE_SIZE); - q->sl=(struct sl*)(((char*)q->slib)+PAGE_SIZE/2); - - available=0; - - for (j=0;jsbal[j]=*(inbound_sbals_array++); - - q->queue_type=q_format; - q->int_parm=int_parm; - q->schid = irq_ptr->schid; - q->irq_ptr = irq_ptr; - q->cdev = cdev; - q->mask=1<<(31-i); - q->q_no=i; - q->is_input_q=1; - q->first_to_check=0; - q->last_move_ftc=0; - q->handler=input_handler; - q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind; - - /* q->is_thinint_q isn't valid at this time, but - * irq_ptr->is_thinint_irq is - */ - if (irq_ptr->is_thinint_irq) - tasklet_init(&q->tasklet, tiqdio_inbound_processing, - (unsigned long) q); - else - tasklet_init(&q->tasklet, qdio_inbound_processing, - (unsigned long) q); - - /* actually this is not used for inbound queues. yet. */ - atomic_set(&q->busy_siga_counter,0); - q->timing.busy_start=0; - -/* for (j=0;jtiming.last_transfer_times[j]=(qdio_get_micros()/ - QDIO_STATS_NUMBER)*j; - q->timing.last_transfer_index=QDIO_STATS_NUMBER-1; -*/ - - /* fill in slib */ - if (i>0) irq_ptr->input_qs[i-1]->slib->nsliba= - (unsigned long)(q->slib); - q->slib->sla=(unsigned long)(q->sl); - q->slib->slsba=(unsigned long)(&q->slsb.acc.val[0]); - - /* fill in sl */ - for (j=0;jsl->element[j].sbal=(unsigned long)(q->sbal[j]); - - QDIO_DBF_TEXT2(0,setup,"sl-sb-b0"); - ptr=(void*)q->sl; - QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); - ptr=(void*)&q->slsb; - QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); - ptr=(void*)q->sbal[0]; - QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); - - /* fill in slsb */ - if (!irq_ptr->is_qebsm) { - unsigned int count = 1; - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) - set_slsb(q, &j, SLSB_P_INPUT_NOT_INIT, &count); - } - } - - for (i=0;ioutput_qs[i]; - memset(q,0,((char*)&q->slib)-((char*)q)); - - sprintf(dbf_text,"outq%4x",i); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_HEX0(0,setup,&q,sizeof(void*)); - - memset(q->slib,0,PAGE_SIZE); - q->sl=(struct sl*)(((char*)q->slib)+PAGE_SIZE/2); - - available=0; - - for (j=0;jsbal[j]=*(outbound_sbals_array++); - - q->queue_type=q_format; - if ((q->queue_type == QDIO_IQDIO_QFMT) && - (no_output_qs > 1) && - (i == no_output_qs-1)) - q->queue_type = QDIO_IQDIO_QFMT_ASYNCH; - q->int_parm=int_parm; - q->is_input_q=0; - q->is_pci_out = 0; - q->schid = irq_ptr->schid; - q->cdev = cdev; - q->irq_ptr = irq_ptr; - q->mask=1<<(31-i); - q->q_no=i; - q->first_to_check=0; - q->last_move_ftc=0; - q->handler=output_handler; - - tasklet_init(&q->tasklet, qdio_outbound_processing, - (unsigned long) q); - setup_timer(&q->timer, qdio_outbound_processing, - (unsigned long) q); - - atomic_set(&q->busy_siga_counter,0); - q->timing.busy_start=0; - - /* fill in slib */ - if (i>0) irq_ptr->output_qs[i-1]->slib->nsliba= - (unsigned long)(q->slib); - q->slib->sla=(unsigned long)(q->sl); - q->slib->slsba=(unsigned long)(&q->slsb.acc.val[0]); - - /* fill in sl */ - for (j=0;jsl->element[j].sbal=(unsigned long)(q->sbal[j]); - - QDIO_DBF_TEXT2(0,setup,"sl-sb-b0"); - ptr=(void*)q->sl; - QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); - ptr=(void*)&q->slsb; - QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); - ptr=(void*)q->sbal[0]; - QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); - - /* fill in slsb */ - if (!irq_ptr->is_qebsm) { - unsigned int count = 1; - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) - set_slsb(q, &j, SLSB_P_OUTPUT_NOT_INIT, &count); - } - } -} - -static void -qdio_fill_thresholds(struct qdio_irq *irq_ptr, - unsigned int no_input_qs, - unsigned int no_output_qs, - unsigned int min_input_threshold, - unsigned int max_input_threshold, - unsigned int min_output_threshold, - unsigned int max_output_threshold) -{ - int i; - struct qdio_q *q; - - for (i=0;iinput_qs[i]; - q->timing.threshold=max_input_threshold; -/* for (j=0;jthreshold_classes[j].threshold= - min_input_threshold+ - (max_input_threshold-min_input_threshold)/ - QDIO_STATS_CLASSES; - } - qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/ - } - for (i=0;ioutput_qs[i]; - q->timing.threshold=max_output_threshold; -/* for (j=0;jthreshold_classes[j].threshold= - min_output_threshold+ - (max_output_threshold-min_output_threshold)/ - QDIO_STATS_CLASSES; - } - qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/ - } -} - -static void tiqdio_thinint_handler(void *ind, void *drv_data) -{ - QDIO_DBF_TEXT4(0,trace,"thin_int"); - - qdio_perf_stat_inc(&perf_stats.thinints); - - /* SVS only when needed: - * issue SVS to benefit from iqdio interrupt avoidance - * (SVS clears AISOI)*/ - if (!omit_svs) - tiqdio_clear_global_summary(); - - tiqdio_inbound_checks(); -} - -static void -qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state) -{ - int i; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]; - - QDIO_DBF_TEXT5(0,trace,"newstate"); - sprintf(dbf_text,"%4x%4x",irq_ptr->schid.sch_no,state); - QDIO_DBF_TEXT5(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - irq_ptr->state=state; - for (i=0;ino_input_qs;i++) - irq_ptr->input_qs[i]->state=state; - for (i=0;ino_output_qs;i++) - irq_ptr->output_qs[i]->state=state; - mb(); -} - -static void -qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) -{ - char dbf_text[15]; - - if (irb->esw.esw0.erw.cons) { - sprintf(dbf_text,"sens%4x",schid.sch_no); - QDIO_DBF_TEXT2(1,trace,dbf_text); - QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN); - - QDIO_PRINT_WARN("sense data available on qdio channel.\n"); - QDIO_HEXDUMP16(WARN,"irb: ",irb); - QDIO_HEXDUMP16(WARN,"sense data: ",irb->ecw); - } - -} - -static void -qdio_handle_pci(struct qdio_irq *irq_ptr) -{ - int i; - struct qdio_q *q; - - qdio_perf_stat_inc(&perf_stats.pcis); - for (i=0;ino_input_qs;i++) { - q=irq_ptr->input_qs[i]; - if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) - qdio_mark_q(q); - else { - qdio_perf_stat_dec(&perf_stats.tl_runs); - __qdio_inbound_processing(q); - } - } - if (!irq_ptr->hydra_gives_outbound_pcis) - return; - for (i=0;ino_output_qs;i++) { - q=irq_ptr->output_qs[i]; - if (qdio_is_outbound_q_done(q)) - continue; - qdio_perf_stat_dec(&perf_stats.tl_runs); - if (!irq_ptr->sync_done_on_outb_pcis) - SYNC_MEMORY; - __qdio_outbound_processing(q); - } -} - -static void qdio_establish_handle_irq(struct ccw_device*, int, int); - -static void -qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm, - int cstat, int dstat) -{ - struct qdio_irq *irq_ptr; - struct qdio_q *q; - char dbf_text[15]; - - irq_ptr = cdev->private->qdio_data; - - QDIO_DBF_TEXT2(1, trace, "ick2"); - sprintf(dbf_text,"%s", cdev->dev.bus_id); - QDIO_DBF_TEXT2(1,trace,dbf_text); - QDIO_DBF_HEX2(0,trace,&intparm,sizeof(int)); - QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); - QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); - QDIO_PRINT_ERR("received check condition on activate " \ - "queues on device %s (cs=x%x, ds=x%x).\n", - cdev->dev.bus_id, cstat, dstat); - if (irq_ptr->no_input_qs) { - q=irq_ptr->input_qs[0]; - } else if (irq_ptr->no_output_qs) { - q=irq_ptr->output_qs[0]; - } else { - QDIO_PRINT_ERR("oops... no queue registered for device %s!?\n", - cdev->dev.bus_id); - goto omit_handler_call; - } - q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION| - QDIO_STATUS_LOOK_FOR_ERROR, - 0,0,0,-1,-1,q->int_parm); -omit_handler_call: - qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED); - -} - -static void -qdio_call_shutdown(struct work_struct *work) -{ - struct ccw_device_private *priv; - struct ccw_device *cdev; - - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; - qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); - put_device(&cdev->dev); -} - -static void -qdio_timeout_handler(struct ccw_device *cdev) -{ - struct qdio_irq *irq_ptr; - char dbf_text[15]; - - QDIO_DBF_TEXT2(0, trace, "qtoh"); - sprintf(dbf_text, "%s", cdev->dev.bus_id); - QDIO_DBF_TEXT2(0, trace, dbf_text); - - irq_ptr = cdev->private->qdio_data; - sprintf(dbf_text, "state:%d", irq_ptr->state); - QDIO_DBF_TEXT2(0, trace, dbf_text); - - switch (irq_ptr->state) { - case QDIO_IRQ_STATE_INACTIVE: - QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: timed out\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no); - QDIO_DBF_TEXT2(1,setup,"eq:timeo"); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); - break; - case QDIO_IRQ_STATE_CLEANUP: - QDIO_PRINT_INFO("Did not get interrupt on cleanup, " - "irq=0.%x.%x.\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); - break; - case QDIO_IRQ_STATE_ESTABLISHED: - case QDIO_IRQ_STATE_ACTIVE: - /* I/O has been terminated by common I/O layer. */ - QDIO_PRINT_INFO("Queues on irq 0.%x.%04x killed by cio.\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no); - QDIO_DBF_TEXT2(1, trace, "cio:term"); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); - if (get_device(&cdev->dev)) { - /* Can't call shutdown from interrupt context. */ - PREPARE_WORK(&cdev->private->kick_work, - qdio_call_shutdown); - queue_work(ccw_device_work, &cdev->private->kick_work); - } - break; - default: - BUG(); - } - wake_up(&cdev->private->wait_q); -} - -static void -qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) -{ - struct qdio_irq *irq_ptr; - int cstat,dstat; - char dbf_text[15]; - -#ifdef CONFIG_QDIO_DEBUG - QDIO_DBF_TEXT4(0, trace, "qint"); - sprintf(dbf_text, "%s", cdev->dev.bus_id); - QDIO_DBF_TEXT4(0, trace, dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - if (!intparm) { - QDIO_PRINT_ERR("got unsolicited interrupt in qdio " \ - "handler, device %s\n", cdev->dev.bus_id); - return; - } - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) { - QDIO_DBF_TEXT2(1, trace, "uint"); - sprintf(dbf_text,"%s", cdev->dev.bus_id); - QDIO_DBF_TEXT2(1,trace,dbf_text); - QDIO_PRINT_ERR("received interrupt on unused device %s!\n", - cdev->dev.bus_id); - return; - } - - if (IS_ERR(irb)) { - /* Currently running i/o is in error. */ - switch (PTR_ERR(irb)) { - case -EIO: - QDIO_PRINT_ERR("i/o error on device %s\n", - cdev->dev.bus_id); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); - wake_up(&cdev->private->wait_q); - return; - case -ETIMEDOUT: - qdio_timeout_handler(cdev); - return; - default: - QDIO_PRINT_ERR("unknown error state %ld on device %s\n", - PTR_ERR(irb), cdev->dev.bus_id); - return; - } - } - - qdio_irq_check_sense(irq_ptr->schid, irb); - -#ifdef CONFIG_QDIO_DEBUG - sprintf(dbf_text, "state:%d", irq_ptr->state); - QDIO_DBF_TEXT4(0, trace, dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - cstat = irb->scsw.cmd.cstat; - dstat = irb->scsw.cmd.dstat; - - switch (irq_ptr->state) { - case QDIO_IRQ_STATE_INACTIVE: - qdio_establish_handle_irq(cdev, cstat, dstat); - break; - - case QDIO_IRQ_STATE_CLEANUP: - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); - break; - - case QDIO_IRQ_STATE_ESTABLISHED: - case QDIO_IRQ_STATE_ACTIVE: - if (cstat & SCHN_STAT_PCI) { - qdio_handle_pci(irq_ptr); - break; - } - - if ((cstat&~SCHN_STAT_PCI)||dstat) { - qdio_handle_activate_check(cdev, intparm, cstat, dstat); - break; - } - default: - QDIO_PRINT_ERR("got interrupt for queues in state %d on " \ - "device %s?!\n", - irq_ptr->state, cdev->dev.bus_id); - } - wake_up(&cdev->private->wait_q); - -} - -int -qdio_synchronize(struct ccw_device *cdev, unsigned int flags, - unsigned int queue_number) -{ - int cc = 0; - struct qdio_q *q; - struct qdio_irq *irq_ptr; - void *ptr; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[15]="SyncXXXX"; -#endif - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -ENODEV; - -#ifdef CONFIG_QDIO_DEBUG - *((int*)(&dbf_text[4])) = irq_ptr->schid.sch_no; - QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); - *((int*)(&dbf_text[0]))=flags; - *((int*)(&dbf_text[4]))=queue_number; - QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); -#endif /* CONFIG_QDIO_DEBUG */ - - if (flags&QDIO_FLAG_SYNC_INPUT) { - q=irq_ptr->input_qs[queue_number]; - if (!q) - return -EINVAL; - if (!(irq_ptr->is_qebsm)) - cc = do_siga_sync(q->schid, 0, q->mask); - } else if (flags&QDIO_FLAG_SYNC_OUTPUT) { - q=irq_ptr->output_qs[queue_number]; - if (!q) - return -EINVAL; - if (!(irq_ptr->is_qebsm)) - cc = do_siga_sync(q->schid, q->mask, 0); - } else - return -EINVAL; - - ptr=&cc; - if (cc) - QDIO_DBF_HEX3(0,trace,&ptr,sizeof(int)); - - return cc; -} - -static int -qdio_get_ssqd_information(struct subchannel_id *schid, - struct qdio_chsc_ssqd **ssqd_area) -{ - int result; - - QDIO_DBF_TEXT0(0, setup, "getssqd"); - *ssqd_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC); - if (!ssqd_area) { - QDIO_PRINT_WARN("Could not get memory for chsc on sch x%x.\n", - schid->sch_no); - return -ENOMEM; - } - - (*ssqd_area)->request = (struct chsc_header) { - .length = 0x0010, - .code = 0x0024, - }; - (*ssqd_area)->first_sch = schid->sch_no; - (*ssqd_area)->last_sch = schid->sch_no; - (*ssqd_area)->ssid = schid->ssid; - result = chsc(*ssqd_area); - - if (result) { - QDIO_PRINT_WARN("CHSC returned cc %i on sch 0.%x.%x.\n", - result, schid->ssid, schid->sch_no); - goto out; - } - - if ((*ssqd_area)->response.code != QDIO_CHSC_RESPONSE_CODE_OK) { - QDIO_PRINT_WARN("CHSC response is 0x%x on sch 0.%x.%x.\n", - (*ssqd_area)->response.code, - schid->ssid, schid->sch_no); - goto out; - } - if (!((*ssqd_area)->flags & CHSC_FLAG_QDIO_CAPABILITY) || - !((*ssqd_area)->flags & CHSC_FLAG_VALIDITY) || - ((*ssqd_area)->sch != schid->sch_no)) { - QDIO_PRINT_WARN("huh? problems checking out sch 0.%x.%x... " \ - "using all SIGAs.\n", - schid->ssid, schid->sch_no); - goto out; - } - return 0; -out: - return -EINVAL; -} - -int -qdio_get_ssqd_pct(struct ccw_device *cdev) -{ - struct qdio_chsc_ssqd *ssqd_area; - struct subchannel_id schid; - char dbf_text[15]; - int rc; - int pct = 0; - - QDIO_DBF_TEXT0(0, setup, "getpct"); - schid = ccw_device_get_subchannel_id(cdev); - rc = qdio_get_ssqd_information(&schid, &ssqd_area); - if (!rc) - pct = (int)ssqd_area->pct; - if (rc != -ENOMEM) - mempool_free(ssqd_area, qdio_mempool_scssc); - sprintf(dbf_text, "pct: %d", pct); - QDIO_DBF_TEXT2(0, setup, dbf_text); - return pct; -} -EXPORT_SYMBOL(qdio_get_ssqd_pct); - -static void -qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned long token) -{ - struct qdio_q *q; - int i; - unsigned int count, start_buf; - char dbf_text[15]; - - /*check if QEBSM is disabled */ - if (!(irq_ptr->is_qebsm) || !(irq_ptr->qdioac & 0x01)) { - irq_ptr->is_qebsm = 0; - irq_ptr->sch_token = 0; - irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM; - QDIO_DBF_TEXT0(0,setup,"noV=V"); - return; - } - irq_ptr->sch_token = token; - /*input queue*/ - for (i = 0; i < irq_ptr->no_input_qs;i++) { - q = irq_ptr->input_qs[i]; - count = QDIO_MAX_BUFFERS_PER_Q; - start_buf = 0; - set_slsb(q, &start_buf, SLSB_P_INPUT_NOT_INIT, &count); - } - sprintf(dbf_text,"V=V:%2x",irq_ptr->is_qebsm); - QDIO_DBF_TEXT0(0,setup,dbf_text); - sprintf(dbf_text,"%8lx",irq_ptr->sch_token); - QDIO_DBF_TEXT0(0,setup,dbf_text); - /*output queue*/ - for (i = 0; i < irq_ptr->no_output_qs; i++) { - q = irq_ptr->output_qs[i]; - count = QDIO_MAX_BUFFERS_PER_Q; - start_buf = 0; - set_slsb(q, &start_buf, SLSB_P_OUTPUT_NOT_INIT, &count); - } -} - -static void -qdio_get_ssqd_siga(struct qdio_irq *irq_ptr) -{ - int rc; - struct qdio_chsc_ssqd *ssqd_area; - - QDIO_DBF_TEXT0(0,setup,"getssqd"); - irq_ptr->qdioac = 0; - rc = qdio_get_ssqd_information(&irq_ptr->schid, &ssqd_area); - if (rc) { - QDIO_PRINT_WARN("using all SIGAs for sch x%x.n", - irq_ptr->schid.sch_no); - irq_ptr->qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY | - CHSC_FLAG_SIGA_OUTPUT_NECESSARY | - CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ - irq_ptr->is_qebsm = 0; - } else - irq_ptr->qdioac = ssqd_area->qdioac1; - - qdio_check_subchannel_qebsm(irq_ptr, ssqd_area->sch_token); - if (rc != -ENOMEM) - mempool_free(ssqd_area, qdio_mempool_scssc); -} - -static unsigned int -tiqdio_check_chsc_availability(void) -{ - char dbf_text[15]; - - /* Check for bit 41. */ - if (!css_general_characteristics.aif) { - QDIO_PRINT_WARN("Adapter interruption facility not " \ - "installed.\n"); - return -ENOENT; - } - - /* Check for bits 107 and 108. */ - if (!css_chsc_characteristics.scssc || - !css_chsc_characteristics.scsscf) { - QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \ - "not available.\n"); - return -ENOENT; - } - - /* Check for OSA/FCP thin interrupts (bit 67). */ - hydra_thinints = css_general_characteristics.aif_osa; - sprintf(dbf_text,"hydrati%1x", hydra_thinints); - QDIO_DBF_TEXT0(0,setup,dbf_text); - -#ifdef CONFIG_64BIT - /* Check for QEBSM support in general (bit 58). */ - is_passthrough = css_general_characteristics.qebsm; -#endif - sprintf(dbf_text,"cssQBS:%1x", is_passthrough); - QDIO_DBF_TEXT0(0,setup,dbf_text); - - /* Check for aif time delay disablement fac (bit 56). If installed, - * omit svs even under lpar (good point by rick again) */ - omit_svs = css_general_characteristics.aif_tdd; - sprintf(dbf_text,"omitsvs%1x", omit_svs); - QDIO_DBF_TEXT0(0,setup,dbf_text); - return 0; -} - - -static unsigned int -tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) -{ - unsigned long real_addr_local_summary_bit; - unsigned long real_addr_dev_st_chg_ind; - void *ptr; - char dbf_text[15]; - - unsigned int resp_code; - int result; - - struct { - struct chsc_header request; - u16 operation_code; - u16 reserved1; - u32 reserved2; - u32 reserved3; - u64 summary_indicator_addr; - u64 subchannel_indicator_addr; - u32 ks:4; - u32 kc:4; - u32 reserved4:21; - u32 isc:3; - u32 word_with_d_bit; - /* set to 0x10000000 to enable - * time delay disablement facility */ - u32 reserved5; - struct subchannel_id schid; - u32 reserved6[1004]; - struct chsc_header response; - u32 reserved7; - } *scssc_area; - - if (!irq_ptr->is_thinint_irq) - return -ENODEV; - - if (reset_to_zero) { - real_addr_local_summary_bit=0; - real_addr_dev_st_chg_ind=0; - } else { - real_addr_local_summary_bit= - virt_to_phys((volatile void *)tiqdio_ind); - real_addr_dev_st_chg_ind= - virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind); - } - - scssc_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC); - if (!scssc_area) { - QDIO_PRINT_WARN("No memory for setting indicators on " \ - "subchannel 0.%x.%x.\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no); - return -ENOMEM; - } - scssc_area->request = (struct chsc_header) { - .length = 0x0fe0, - .code = 0x0021, - }; - scssc_area->operation_code = 0; - - scssc_area->summary_indicator_addr = real_addr_local_summary_bit; - scssc_area->subchannel_indicator_addr = real_addr_dev_st_chg_ind; - scssc_area->ks = QDIO_STORAGE_KEY; - scssc_area->kc = QDIO_STORAGE_KEY; - scssc_area->isc = TIQDIO_THININT_ISC; - scssc_area->schid = irq_ptr->schid; - /* enables the time delay disablement facility. Don't care - * whether it is really there (i.e. we haven't checked for - * it) */ - if (css_general_characteristics.aif_tdd) - scssc_area->word_with_d_bit = 0x10000000; - else - QDIO_PRINT_WARN("Time delay disablement facility " \ - "not available\n"); - - result = chsc(scssc_area); - if (result) { - QDIO_PRINT_WARN("could not set indicators on irq 0.%x.%x, " \ - "cc=%i.\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no,result); - result = -EIO; - goto out; - } - - resp_code = scssc_area->response.code; - if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) { - QDIO_PRINT_WARN("response upon setting indicators " \ - "is 0x%x.\n",resp_code); - sprintf(dbf_text,"sidR%4x",resp_code); - QDIO_DBF_TEXT1(0,trace,dbf_text); - QDIO_DBF_TEXT1(0,setup,dbf_text); - ptr=&scssc_area->response; - QDIO_DBF_HEX2(1,setup,&ptr,QDIO_DBF_SETUP_LEN); - result = -EIO; - goto out; - } - - QDIO_DBF_TEXT2(0,setup,"setscind"); - QDIO_DBF_HEX2(0,setup,&real_addr_local_summary_bit, - sizeof(unsigned long)); - QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long)); - result = 0; -out: - mempool_free(scssc_area, qdio_mempool_scssc); - return result; - -} - -static unsigned int -tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target) -{ - unsigned int resp_code; - int result; - void *ptr; - char dbf_text[15]; - - struct { - struct chsc_header request; - u16 operation_code; - u16 reserved1; - u32 reserved2; - u32 reserved3; - u32 reserved4[2]; - u32 delay_target; - u32 reserved5[1009]; - struct chsc_header response; - u32 reserved6; - } *scsscf_area; - - if (!irq_ptr->is_thinint_irq) - return -ENODEV; - - scsscf_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC); - if (!scsscf_area) { - QDIO_PRINT_WARN("No memory for setting delay target on " \ - "subchannel 0.%x.%x.\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no); - return -ENOMEM; - } - scsscf_area->request = (struct chsc_header) { - .length = 0x0fe0, - .code = 0x1027, - }; - - scsscf_area->delay_target = delay_target<<16; - - result=chsc(scsscf_area); - if (result) { - QDIO_PRINT_WARN("could not set delay target on irq 0.%x.%x, " \ - "cc=%i. Continuing.\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no, - result); - result = -EIO; - goto out; - } - - resp_code = scsscf_area->response.code; - if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) { - QDIO_PRINT_WARN("response upon setting delay target " \ - "is 0x%x. Continuing.\n",resp_code); - sprintf(dbf_text,"sdtR%4x",resp_code); - QDIO_DBF_TEXT1(0,trace,dbf_text); - QDIO_DBF_TEXT1(0,setup,dbf_text); - ptr=&scsscf_area->response; - QDIO_DBF_HEX2(1,trace,&ptr,QDIO_DBF_TRACE_LEN); - } - QDIO_DBF_TEXT2(0,trace,"delytrgt"); - QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long)); - result = 0; /* not critical */ -out: - mempool_free(scsscf_area, qdio_mempool_scssc); - return result; -} - -int -qdio_cleanup(struct ccw_device *cdev, int how) -{ - struct qdio_irq *irq_ptr; - char dbf_text[15]; - int rc; - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -ENODEV; - - sprintf(dbf_text,"qcln%4x",irq_ptr->schid.sch_no); - QDIO_DBF_TEXT1(0,trace,dbf_text); - QDIO_DBF_TEXT0(0,setup,dbf_text); - - rc = qdio_shutdown(cdev, how); - if ((rc == 0) || (rc == -EINPROGRESS)) - rc = qdio_free(cdev); - return rc; -} - -int -qdio_shutdown(struct ccw_device *cdev, int how) -{ - struct qdio_irq *irq_ptr; - int i; - int result = 0; - int rc; - unsigned long flags; - int timeout; - char dbf_text[15]; - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -ENODEV; - - down(&irq_ptr->setting_up_sema); - - sprintf(dbf_text,"qsqs%4x",irq_ptr->schid.sch_no); - QDIO_DBF_TEXT1(0,trace,dbf_text); - QDIO_DBF_TEXT0(0,setup,dbf_text); - - /* mark all qs as uninteresting */ - for (i=0;ino_input_qs;i++) - atomic_set(&irq_ptr->input_qs[i]->is_in_shutdown,1); - - for (i=0;ino_output_qs;i++) - atomic_set(&irq_ptr->output_qs[i]->is_in_shutdown,1); - - tasklet_kill(&tiqdio_tasklet); - - for (i=0;ino_input_qs;i++) { - qdio_unmark_q(irq_ptr->input_qs[i]); - tasklet_kill(&irq_ptr->input_qs[i]->tasklet); - wait_event_interruptible_timeout(cdev->private->wait_q, - !atomic_read(&irq_ptr-> - input_qs[i]-> - use_count), - QDIO_NO_USE_COUNT_TIMEOUT); - if (atomic_read(&irq_ptr->input_qs[i]->use_count)) - result=-EINPROGRESS; - } - - for (i=0;ino_output_qs;i++) { - tasklet_kill(&irq_ptr->output_qs[i]->tasklet); - del_timer(&irq_ptr->output_qs[i]->timer); - wait_event_interruptible_timeout(cdev->private->wait_q, - !atomic_read(&irq_ptr-> - output_qs[i]-> - use_count), - QDIO_NO_USE_COUNT_TIMEOUT); - if (atomic_read(&irq_ptr->output_qs[i]->use_count)) - result=-EINPROGRESS; - } - - /* cleanup subchannel */ - spin_lock_irqsave(get_ccwdev_lock(cdev),flags); - if (how&QDIO_FLAG_CLEANUP_USING_CLEAR) { - rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP); - timeout=QDIO_CLEANUP_CLEAR_TIMEOUT; - } else if (how&QDIO_FLAG_CLEANUP_USING_HALT) { - rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP); - timeout=QDIO_CLEANUP_HALT_TIMEOUT; - } else { /* default behaviour */ - rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP); - timeout=QDIO_CLEANUP_HALT_TIMEOUT; - } - if (rc == -ENODEV) { - /* No need to wait for device no longer present. */ - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - } else if (((void *)cdev->handler != (void *)qdio_handler) && rc == 0) { - /* - * Whoever put another handler there, has to cope with the - * interrupt theirself. Might happen if qdio_shutdown was - * called on already shutdown queues, but this shouldn't have - * bad side effects. - */ - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - } else if (rc == 0) { - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP); - spin_unlock_irqrestore(get_ccwdev_lock(cdev),flags); - - wait_event_interruptible_timeout(cdev->private->wait_q, - irq_ptr->state == QDIO_IRQ_STATE_INACTIVE || - irq_ptr->state == QDIO_IRQ_STATE_ERR, - timeout); - } else { - QDIO_PRINT_INFO("ccw_device_{halt,clear} returned %d for " - "device %s\n", result, cdev->dev.bus_id); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - result = rc; - goto out; - } - if (irq_ptr->is_thinint_irq) { - qdio_put_indicator((__u32*)irq_ptr->dev_st_chg_ind); - tiqdio_set_subchannel_ind(irq_ptr,1); - /* reset adapter interrupt indicators */ - } - - /* exchange int handlers, if necessary */ - if ((void*)cdev->handler == (void*)qdio_handler) - cdev->handler=irq_ptr->original_int_handler; - - /* Ignore errors. */ - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); -out: - up(&irq_ptr->setting_up_sema); - return result; -} - -int -qdio_free(struct ccw_device *cdev) -{ - struct qdio_irq *irq_ptr; - char dbf_text[15]; - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -ENODEV; - - down(&irq_ptr->setting_up_sema); - - sprintf(dbf_text,"qfqs%4x",irq_ptr->schid.sch_no); - QDIO_DBF_TEXT1(0,trace,dbf_text); - QDIO_DBF_TEXT0(0,setup,dbf_text); - - cdev->private->qdio_data = NULL; - - up(&irq_ptr->setting_up_sema); - - qdio_release_irq_memory(irq_ptr); - module_put(THIS_MODULE); - return 0; -} - -static void -qdio_allocate_do_dbf(struct qdio_initialize *init_data) -{ - char dbf_text[20]; /* if a printf printed out more than 8 chars */ - - sprintf(dbf_text,"qfmt:%x",init_data->q_format); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_HEX0(0,setup,init_data->adapter_name,8); - sprintf(dbf_text,"qpff%4x",init_data->qib_param_field_format); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_HEX0(0,setup,&init_data->qib_param_field,sizeof(char*)); - QDIO_DBF_HEX0(0,setup,&init_data->input_slib_elements,sizeof(long*)); - QDIO_DBF_HEX0(0,setup,&init_data->output_slib_elements,sizeof(long*)); - sprintf(dbf_text,"miit%4x",init_data->min_input_threshold); - QDIO_DBF_TEXT0(0,setup,dbf_text); - sprintf(dbf_text,"mait%4x",init_data->max_input_threshold); - QDIO_DBF_TEXT0(0,setup,dbf_text); - sprintf(dbf_text,"miot%4x",init_data->min_output_threshold); - QDIO_DBF_TEXT0(0,setup,dbf_text); - sprintf(dbf_text,"maot%4x",init_data->max_output_threshold); - QDIO_DBF_TEXT0(0,setup,dbf_text); - sprintf(dbf_text,"niq:%4x",init_data->no_input_qs); - QDIO_DBF_TEXT0(0,setup,dbf_text); - sprintf(dbf_text,"noq:%4x",init_data->no_output_qs); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_HEX0(0,setup,&init_data->input_handler,sizeof(void*)); - QDIO_DBF_HEX0(0,setup,&init_data->output_handler,sizeof(void*)); - QDIO_DBF_HEX0(0,setup,&init_data->int_parm,sizeof(long)); - QDIO_DBF_HEX0(0,setup,&init_data->flags,sizeof(long)); - QDIO_DBF_HEX0(0,setup,&init_data->input_sbal_addr_array,sizeof(void*)); - QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*)); -} - -static void -qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt) -{ - irq_ptr->input_qs[i]->is_iqdio_q = iqfmt; - irq_ptr->input_qs[i]->is_thinint_q = irq_ptr->is_thinint_irq; - - irq_ptr->qdr->qdf0[i].sliba=(unsigned long)(irq_ptr->input_qs[i]->slib); - - irq_ptr->qdr->qdf0[i].sla=(unsigned long)(irq_ptr->input_qs[i]->sl); - - irq_ptr->qdr->qdf0[i].slsba= - (unsigned long)(&irq_ptr->input_qs[i]->slsb.acc.val[0]); - - irq_ptr->qdr->qdf0[i].akey=QDIO_STORAGE_KEY; - irq_ptr->qdr->qdf0[i].bkey=QDIO_STORAGE_KEY; - irq_ptr->qdr->qdf0[i].ckey=QDIO_STORAGE_KEY; - irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY; -} - -static void -qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i, - int j, int iqfmt) -{ - irq_ptr->output_qs[i]->is_iqdio_q = iqfmt; - irq_ptr->output_qs[i]->is_thinint_q = irq_ptr->is_thinint_irq; - - irq_ptr->qdr->qdf0[i+j].sliba=(unsigned long)(irq_ptr->output_qs[i]->slib); - - irq_ptr->qdr->qdf0[i+j].sla=(unsigned long)(irq_ptr->output_qs[i]->sl); - - irq_ptr->qdr->qdf0[i+j].slsba= - (unsigned long)(&irq_ptr->output_qs[i]->slsb.acc.val[0]); - - irq_ptr->qdr->qdf0[i+j].akey=QDIO_STORAGE_KEY; - irq_ptr->qdr->qdf0[i+j].bkey=QDIO_STORAGE_KEY; - irq_ptr->qdr->qdf0[i+j].ckey=QDIO_STORAGE_KEY; - irq_ptr->qdr->qdf0[i+j].dkey=QDIO_STORAGE_KEY; -} - - -static void -qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr) -{ - int i; - - for (i=0;ino_input_qs;i++) { - irq_ptr->input_qs[i]->siga_sync= - irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY; - irq_ptr->input_qs[i]->siga_in= - irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY; - irq_ptr->input_qs[i]->siga_out= - irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY; - irq_ptr->input_qs[i]->siga_sync_done_on_thinints= - irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS; - irq_ptr->input_qs[i]->hydra_gives_outbound_pcis= - irq_ptr->hydra_gives_outbound_pcis; - irq_ptr->input_qs[i]->siga_sync_done_on_outb_tis= - ((irq_ptr->qdioac& - (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| - CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS))== - (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| - CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS)); - - } -} - -static void -qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr) -{ - int i; - - for (i=0;ino_output_qs;i++) { - irq_ptr->output_qs[i]->siga_sync= - irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY; - irq_ptr->output_qs[i]->siga_in= - irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY; - irq_ptr->output_qs[i]->siga_out= - irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY; - irq_ptr->output_qs[i]->siga_sync_done_on_thinints= - irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS; - irq_ptr->output_qs[i]->hydra_gives_outbound_pcis= - irq_ptr->hydra_gives_outbound_pcis; - irq_ptr->output_qs[i]->siga_sync_done_on_outb_tis= - ((irq_ptr->qdioac& - (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| - CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS))== - (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS| - CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS)); - - } -} - -static int -qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, - int dstat) -{ - char dbf_text[15]; - struct qdio_irq *irq_ptr; - - irq_ptr = cdev->private->qdio_data; - - if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) { - sprintf(dbf_text,"ick1%4x",irq_ptr->schid.sch_no); - QDIO_DBF_TEXT2(1,trace,dbf_text); - QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); - QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); - QDIO_PRINT_ERR("received check condition on establish " \ - "queues on irq 0.%x.%x (cs=x%x, ds=x%x).\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no, - cstat,dstat); - qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ERR); - } - - if (!(dstat & DEV_STAT_DEV_END)) { - QDIO_DBF_TEXT2(1,setup,"eq:no de"); - QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat)); - QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); - QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: didn't get " - "device end: dstat=%02x, cstat=%02x\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no, - dstat, cstat); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); - return 1; - } - - if (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) { - QDIO_DBF_TEXT2(1,setup,"eq:badio"); - QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat)); - QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); - QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: got " - "the following devstat: dstat=%02x, " - "cstat=%02x\n", irq_ptr->schid.ssid, - irq_ptr->schid.sch_no, dstat, cstat); - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); - return 1; - } - return 0; -} - -static void -qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat) -{ - struct qdio_irq *irq_ptr; - char dbf_text[15]; - - irq_ptr = cdev->private->qdio_data; - - sprintf(dbf_text,"qehi%4x",cdev->private->schid.sch_no); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_TEXT0(0,trace,dbf_text); - - if (qdio_establish_irq_check_for_errors(cdev, cstat, dstat)) - return; - - qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED); -} - -int -qdio_initialize(struct qdio_initialize *init_data) -{ - int rc; - char dbf_text[15]; - - sprintf(dbf_text,"qini%4x",init_data->cdev->private->schid.sch_no); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_TEXT0(0,trace,dbf_text); - - rc = qdio_allocate(init_data); - if (rc == 0) { - rc = qdio_establish(init_data); - if (rc != 0) - qdio_free(init_data->cdev); - } - - return rc; -} - - -int -qdio_allocate(struct qdio_initialize *init_data) -{ - struct qdio_irq *irq_ptr; - char dbf_text[15]; - - sprintf(dbf_text,"qalc%4x",init_data->cdev->private->schid.sch_no); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_TEXT0(0,trace,dbf_text); - if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || - (init_data->no_output_qs>QDIO_MAX_QUEUES_PER_IRQ) || - ((init_data->no_input_qs) && (!init_data->input_handler)) || - ((init_data->no_output_qs) && (!init_data->output_handler)) ) - return -EINVAL; - - if (!init_data->input_sbal_addr_array) - return -EINVAL; - - if (!init_data->output_sbal_addr_array) - return -EINVAL; - - qdio_allocate_do_dbf(init_data); - - /* create irq */ - irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); - - QDIO_DBF_TEXT0(0,setup,"irq_ptr:"); - QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*)); - - if (!irq_ptr) { - QDIO_PRINT_ERR("allocation of irq_ptr failed!\n"); - return -ENOMEM; - } - - init_MUTEX(&irq_ptr->setting_up_sema); - - /* QDR must be in DMA area since CCW data address is only 32 bit */ - irq_ptr->qdr = (struct qdr *) __get_free_page(GFP_KERNEL | GFP_DMA); - if (!(irq_ptr->qdr)) { - free_page((unsigned long) irq_ptr); - QDIO_PRINT_ERR("allocation of irq_ptr->qdr failed!\n"); - return -ENOMEM; - } - QDIO_DBF_TEXT0(0,setup,"qdr:"); - QDIO_DBF_HEX0(0,setup,&irq_ptr->qdr,sizeof(void*)); - - if (qdio_alloc_qs(irq_ptr, - init_data->no_input_qs, - init_data->no_output_qs)) { - QDIO_PRINT_ERR("queue allocation failed!\n"); - qdio_release_irq_memory(irq_ptr); - return -ENOMEM; - } - - init_data->cdev->private->qdio_data = irq_ptr; - - qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE); - - return 0; -} - -static int qdio_fill_irq(struct qdio_initialize *init_data) -{ - int i; - char dbf_text[15]; - struct ciw *ciw; - int is_iqdio; - struct qdio_irq *irq_ptr; - - irq_ptr = init_data->cdev->private->qdio_data; - - memset(irq_ptr,0,((char*)&irq_ptr->qdr)-((char*)irq_ptr)); - - /* wipes qib.ac, required by ar7063 */ - memset(irq_ptr->qdr,0,sizeof(struct qdr)); - - irq_ptr->int_parm=init_data->int_parm; - - irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev); - irq_ptr->no_input_qs=init_data->no_input_qs; - irq_ptr->no_output_qs=init_data->no_output_qs; - - if (init_data->q_format==QDIO_IQDIO_QFMT) { - irq_ptr->is_iqdio_irq=1; - irq_ptr->is_thinint_irq=1; - } else { - irq_ptr->is_iqdio_irq=0; - irq_ptr->is_thinint_irq=hydra_thinints; - } - sprintf(dbf_text,"is_i_t%1x%1x", - irq_ptr->is_iqdio_irq,irq_ptr->is_thinint_irq); - QDIO_DBF_TEXT2(0,setup,dbf_text); - - if (irq_ptr->is_thinint_irq) { - irq_ptr->dev_st_chg_ind = qdio_get_indicator(); - QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*)); - if (!irq_ptr->dev_st_chg_ind) { - QDIO_PRINT_WARN("no indicator location available " \ - "for irq 0.%x.%x\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no); - qdio_release_irq_memory(irq_ptr); - return -ENOBUFS; - } - } - - /* defaults */ - irq_ptr->equeue.cmd=DEFAULT_ESTABLISH_QS_CMD; - irq_ptr->equeue.count=DEFAULT_ESTABLISH_QS_COUNT; - irq_ptr->aqueue.cmd=DEFAULT_ACTIVATE_QS_CMD; - irq_ptr->aqueue.count=DEFAULT_ACTIVATE_QS_COUNT; - - qdio_fill_qs(irq_ptr, init_data->cdev, - init_data->no_input_qs, - init_data->no_output_qs, - init_data->input_handler, - init_data->output_handler,init_data->int_parm, - init_data->q_format,init_data->flags, - init_data->input_sbal_addr_array, - init_data->output_sbal_addr_array); - - if (!try_module_get(THIS_MODULE)) { - QDIO_PRINT_CRIT("try_module_get() failed!\n"); - qdio_release_irq_memory(irq_ptr); - return -EINVAL; - } - - qdio_fill_thresholds(irq_ptr,init_data->no_input_qs, - init_data->no_output_qs, - init_data->min_input_threshold, - init_data->max_input_threshold, - init_data->min_output_threshold, - init_data->max_output_threshold); - - /* fill in qdr */ - irq_ptr->qdr->qfmt=init_data->q_format; - irq_ptr->qdr->iqdcnt=init_data->no_input_qs; - irq_ptr->qdr->oqdcnt=init_data->no_output_qs; - irq_ptr->qdr->iqdsz=sizeof(struct qdesfmt0)/4; /* size in words */ - irq_ptr->qdr->oqdsz=sizeof(struct qdesfmt0)/4; - - irq_ptr->qdr->qiba=(unsigned long)&irq_ptr->qib; - irq_ptr->qdr->qkey=QDIO_STORAGE_KEY; - - /* fill in qib */ - irq_ptr->is_qebsm = is_passthrough; - if (irq_ptr->is_qebsm) - irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM; - - irq_ptr->qib.qfmt=init_data->q_format; - if (init_data->no_input_qs) - irq_ptr->qib.isliba=(unsigned long)(irq_ptr->input_qs[0]->slib); - if (init_data->no_output_qs) - irq_ptr->qib.osliba=(unsigned long)(irq_ptr->output_qs[0]->slib); - memcpy(irq_ptr->qib.ebcnam,init_data->adapter_name,8); - - qdio_set_impl_params(irq_ptr,init_data->qib_param_field_format, - init_data->qib_param_field, - init_data->no_input_qs, - init_data->no_output_qs, - init_data->input_slib_elements, - init_data->output_slib_elements); - - /* first input descriptors, then output descriptors */ - is_iqdio = (init_data->q_format == QDIO_IQDIO_QFMT) ? 1 : 0; - for (i=0;ino_input_qs;i++) - qdio_allocate_fill_input_desc(irq_ptr, i, is_iqdio); - - for (i=0;ino_output_qs;i++) - qdio_allocate_fill_output_desc(irq_ptr, i, - init_data->no_input_qs, - is_iqdio); - - /* qdr, qib, sls, slsbs, slibs, sbales filled. */ - - /* get qdio commands */ - ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE); - if (!ciw) { - QDIO_DBF_TEXT2(1,setup,"no eq"); - QDIO_PRINT_INFO("No equeue CIW found for QDIO commands. " - "Trying to use default.\n"); - } else - irq_ptr->equeue = *ciw; - ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE); - if (!ciw) { - QDIO_DBF_TEXT2(1,setup,"no aq"); - QDIO_PRINT_INFO("No aqueue CIW found for QDIO commands. " - "Trying to use default.\n"); - } else - irq_ptr->aqueue = *ciw; - - /* Set new interrupt handler. */ - irq_ptr->original_int_handler = init_data->cdev->handler; - init_data->cdev->handler = qdio_handler; - - return 0; -} - -int -qdio_establish(struct qdio_initialize *init_data) -{ - struct qdio_irq *irq_ptr; - unsigned long saveflags; - int result, result2; - struct ccw_device *cdev; - char dbf_text[20]; - - cdev=init_data->cdev; - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -EINVAL; - - if (cdev->private->state != DEV_STATE_ONLINE) - return -EINVAL; - - down(&irq_ptr->setting_up_sema); - - qdio_fill_irq(init_data); - - /* the thinint CHSC stuff */ - if (irq_ptr->is_thinint_irq) { - - result = tiqdio_set_subchannel_ind(irq_ptr,0); - if (result) { - up(&irq_ptr->setting_up_sema); - qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); - return result; - } - tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); - } - - sprintf(dbf_text,"qest%4x",cdev->private->schid.sch_no); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_DBF_TEXT0(0,trace,dbf_text); - - /* establish q */ - irq_ptr->ccw.cmd_code=irq_ptr->equeue.cmd; - irq_ptr->ccw.flags=CCW_FLAG_SLI; - irq_ptr->ccw.count=irq_ptr->equeue.count; - irq_ptr->ccw.cda=QDIO_GET_ADDR(irq_ptr->qdr); - - spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); - - ccw_device_set_options_mask(cdev, 0); - result = ccw_device_start(cdev, &irq_ptr->ccw, - QDIO_DOING_ESTABLISH, 0, 0); - if (result) { - result2 = ccw_device_start(cdev, &irq_ptr->ccw, - QDIO_DOING_ESTABLISH, 0, 0); - sprintf(dbf_text,"eq:io%4x",result); - QDIO_DBF_TEXT2(1,setup,dbf_text); - if (result2) { - sprintf(dbf_text,"eq:io%4x",result); - QDIO_DBF_TEXT2(1,setup,dbf_text); - } - QDIO_PRINT_WARN("establish queues on irq 0.%x.%04x: do_IO " \ - "returned %i, next try returned %i\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no, - result, result2); - result=result2; - } - - spin_unlock_irqrestore(get_ccwdev_lock(cdev),saveflags); - - if (result) { - up(&irq_ptr->setting_up_sema); - qdio_shutdown(cdev,QDIO_FLAG_CLEANUP_USING_CLEAR); - return result; - } - - wait_event_interruptible_timeout(cdev->private->wait_q, - irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || - irq_ptr->state == QDIO_IRQ_STATE_ERR, - QDIO_ESTABLISH_TIMEOUT); - - if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED) - result = 0; - else { - up(&irq_ptr->setting_up_sema); - qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); - return -EIO; - } - - qdio_get_ssqd_siga(irq_ptr); - /* if this gets set once, we're running under VM and can omit SVSes */ - if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY) - omit_svs=1; - - sprintf(dbf_text,"qdioac%2x",irq_ptr->qdioac); - QDIO_DBF_TEXT2(0,setup,dbf_text); - - sprintf(dbf_text,"qib ac%2x",irq_ptr->qib.ac); - QDIO_DBF_TEXT2(0,setup,dbf_text); - - irq_ptr->hydra_gives_outbound_pcis= - irq_ptr->qib.ac&QIB_AC_OUTBOUND_PCI_SUPPORTED; - irq_ptr->sync_done_on_outb_pcis= - irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS; - - qdio_initialize_set_siga_flags_input(irq_ptr); - qdio_initialize_set_siga_flags_output(irq_ptr); - - up(&irq_ptr->setting_up_sema); - - return result; - -} - -int -qdio_activate(struct ccw_device *cdev, int flags) -{ - struct qdio_irq *irq_ptr; - int i,result=0,result2; - unsigned long saveflags; - char dbf_text[20]; /* see qdio_initialize */ - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -ENODEV; - - if (cdev->private->state != DEV_STATE_ONLINE) - return -EINVAL; - - down(&irq_ptr->setting_up_sema); - if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) { - result=-EBUSY; - goto out; - } - - sprintf(dbf_text,"qact%4x", irq_ptr->schid.sch_no); - QDIO_DBF_TEXT2(0,setup,dbf_text); - QDIO_DBF_TEXT2(0,trace,dbf_text); - - /* activate q */ - irq_ptr->ccw.cmd_code=irq_ptr->aqueue.cmd; - irq_ptr->ccw.flags=CCW_FLAG_SLI; - irq_ptr->ccw.count=irq_ptr->aqueue.count; - irq_ptr->ccw.cda=QDIO_GET_ADDR(0); - - spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); - - ccw_device_set_options(cdev, CCWDEV_REPORT_ALL); - result=ccw_device_start(cdev,&irq_ptr->ccw,QDIO_DOING_ACTIVATE, - 0, DOIO_DENY_PREFETCH); - if (result) { - result2=ccw_device_start(cdev,&irq_ptr->ccw, - QDIO_DOING_ACTIVATE,0,0); - sprintf(dbf_text,"aq:io%4x",result); - QDIO_DBF_TEXT2(1,setup,dbf_text); - if (result2) { - sprintf(dbf_text,"aq:io%4x",result); - QDIO_DBF_TEXT2(1,setup,dbf_text); - } - QDIO_PRINT_WARN("activate queues on irq 0.%x.%04x: do_IO " \ - "returned %i, next try returned %i\n", - irq_ptr->schid.ssid, irq_ptr->schid.sch_no, - result, result2); - result=result2; - } - - spin_unlock_irqrestore(get_ccwdev_lock(cdev),saveflags); - if (result) - goto out; - - for (i=0;ino_input_qs;i++) { - if (irq_ptr->is_thinint_irq) { - /* - * that way we know, that, if we will get interrupted - * by tiqdio_inbound_processing, qdio_unmark_q will - * not be called - */ - qdio_reserve_q(irq_ptr->input_qs[i]); - qdio_mark_tiq(irq_ptr->input_qs[i]); - qdio_release_q(irq_ptr->input_qs[i]); - } - } - - if (flags&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) { - for (i=0;ino_input_qs;i++) { - irq_ptr->input_qs[i]->is_input_q|= - QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT; - } - } - - msleep(QDIO_ACTIVATE_TIMEOUT); - switch (irq_ptr->state) { - case QDIO_IRQ_STATE_STOPPED: - case QDIO_IRQ_STATE_ERR: - up(&irq_ptr->setting_up_sema); - qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); - down(&irq_ptr->setting_up_sema); - result = -EIO; - break; - default: - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE); - result = 0; - } - out: - up(&irq_ptr->setting_up_sema); - - return result; -} - -/* buffers filled forwards again to make Rick happy */ -static void -qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, - unsigned int count, struct qdio_buffer *buffers) -{ - struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; - int tmp = 0; - - qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1); - if (irq->is_qebsm) { - while (count) { - tmp = set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count); - if (!tmp) - return; - } - return; - } - for (;;) { - set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count); - count--; - if (!count) break; - qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1); - } -} - -static void -qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, - unsigned int count, struct qdio_buffer *buffers) -{ - struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; - int tmp = 0; - - qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1); - if (irq->is_qebsm) { - while (count) { - tmp = set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count); - if (!tmp) - return; - } - return; - } - - for (;;) { - set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count); - count--; - if (!count) break; - qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1); - } -} - -static void -do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags, - unsigned int qidx, unsigned int count, - struct qdio_buffer *buffers) -{ - int used_elements; - - /* This is the inbound handling of queues */ - used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; - - qdio_do_qdio_fill_input(q,qidx,count,buffers); - - if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&& - (callflags&QDIO_FLAG_UNDER_INTERRUPT)) - atomic_xchg(&q->polling,0); - - if (used_elements) - return; - if (callflags&QDIO_FLAG_DONT_SIGA) - return; - if (q->siga_in) { - int result; - - result=qdio_siga_input(q); - if (result) { - if (q->siga_error) - q->error_status_flags|= - QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR; - q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR; - q->siga_error=result; - } - } - - qdio_mark_q(q); -} - -static void -do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, - unsigned int qidx, unsigned int count, - struct qdio_buffer *buffers) -{ - int used_elements; - unsigned int cnt, start_buf; - unsigned char state = 0; - struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; - - /* This is the outbound handling of queues */ - qdio_do_qdio_fill_output(q,qidx,count,buffers); - - used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; - - if (callflags&QDIO_FLAG_DONT_SIGA) { - qdio_perf_stat_inc(&perf_stats.outbound_cnt); - return; - } - if (callflags & QDIO_FLAG_PCI_OUT) - q->is_pci_out = 1; - else - q->is_pci_out = 0; - if (q->is_iqdio_q) { - /* one siga for every sbal */ - while (count--) - qdio_kick_outbound_q(q); - - __qdio_outbound_processing(q); - } else { - /* under VM, we do a SIGA sync unconditionally */ - SYNC_MEMORY; - else { - /* - * w/o shadow queues (else branch of - * SYNC_MEMORY :-/ ), we try to - * fast-requeue buffers - */ - if (irq->is_qebsm) { - cnt = 1; - start_buf = ((qidx+QDIO_MAX_BUFFERS_PER_Q-1) & - (QDIO_MAX_BUFFERS_PER_Q-1)); - qdio_do_eqbs(q, &state, &start_buf, &cnt); - } else - state = q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1) - &(QDIO_MAX_BUFFERS_PER_Q-1) ]; - if (state != SLSB_CU_OUTPUT_PRIMED) { - qdio_kick_outbound_q(q); - } else { - QDIO_DBF_TEXT3(0,trace, "fast-req"); - qdio_perf_stat_inc(&perf_stats.fast_reqs); - } - } - /* - * only marking the q could take too long, - * the upper layer module could do a lot of - * traffic in that time - */ - __qdio_outbound_processing(q); - } - - qdio_perf_stat_inc(&perf_stats.outbound_cnt); -} - -/* count must be 1 in iqdio */ -int -do_QDIO(struct ccw_device *cdev,unsigned int callflags, - unsigned int queue_number, unsigned int qidx, - unsigned int count,struct qdio_buffer *buffers) -{ - struct qdio_irq *irq_ptr; -#ifdef CONFIG_QDIO_DEBUG - char dbf_text[20]; - - sprintf(dbf_text,"doQD%04x",cdev->private->schid.sch_no); - QDIO_DBF_TEXT3(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - if ( (qidx>QDIO_MAX_BUFFERS_PER_Q) || - (count>QDIO_MAX_BUFFERS_PER_Q) || - (queue_number>QDIO_MAX_QUEUES_PER_IRQ) ) - return -EINVAL; - - if (count==0) - return 0; - - irq_ptr = cdev->private->qdio_data; - if (!irq_ptr) - return -ENODEV; - -#ifdef CONFIG_QDIO_DEBUG - if (callflags&QDIO_FLAG_SYNC_INPUT) - QDIO_DBF_HEX3(0,trace,&irq_ptr->input_qs[queue_number], - sizeof(void*)); - else - QDIO_DBF_HEX3(0,trace,&irq_ptr->output_qs[queue_number], - sizeof(void*)); - sprintf(dbf_text,"flag%04x",callflags); - QDIO_DBF_TEXT3(0,trace,dbf_text); - sprintf(dbf_text,"qi%02xct%02x",qidx,count); - QDIO_DBF_TEXT3(0,trace,dbf_text); -#endif /* CONFIG_QDIO_DEBUG */ - - if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) - return -EBUSY; - - if (callflags&QDIO_FLAG_SYNC_INPUT) - do_qdio_handle_inbound(irq_ptr->input_qs[queue_number], - callflags, qidx, count, buffers); - else if (callflags&QDIO_FLAG_SYNC_OUTPUT) - do_qdio_handle_outbound(irq_ptr->output_qs[queue_number], - callflags, qidx, count, buffers); - else { - QDIO_DBF_TEXT3(1,trace,"doQD:inv"); - return -EINVAL; - } - return 0; -} - -static int -qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, - int buffer_length, int *eof, void *data) -{ - int c=0; - - /* we are always called with buffer_length=4k, so we all - deliver on the first read */ - if (offset>0) - return 0; - -#define _OUTP_IT(x...) c+=sprintf(buffer+c,x) -#ifdef CONFIG_64BIT - _OUTP_IT("Number of tasklet runs (total) : %li\n", - (long)atomic64_read(&perf_stats.tl_runs)); - _OUTP_IT("Inbound tasklet runs tried/retried : %li/%li\n", - (long)atomic64_read(&perf_stats.inbound_tl_runs), - (long)atomic64_read(&perf_stats.inbound_tl_runs_resched)); - _OUTP_IT("Inbound-thin tasklet runs tried/retried : %li/%li\n", - (long)atomic64_read(&perf_stats.inbound_thin_tl_runs), - (long)atomic64_read(&perf_stats.inbound_thin_tl_runs_resched)); - _OUTP_IT("Outbound tasklet runs tried/retried : %li/%li\n", - (long)atomic64_read(&perf_stats.outbound_tl_runs), - (long)atomic64_read(&perf_stats.outbound_tl_runs_resched)); - _OUTP_IT("\n"); - _OUTP_IT("Number of SIGA sync's issued : %li\n", - (long)atomic64_read(&perf_stats.siga_syncs)); - _OUTP_IT("Number of SIGA in's issued : %li\n", - (long)atomic64_read(&perf_stats.siga_ins)); - _OUTP_IT("Number of SIGA out's issued : %li\n", - (long)atomic64_read(&perf_stats.siga_outs)); - _OUTP_IT("Number of PCIs caught : %li\n", - (long)atomic64_read(&perf_stats.pcis)); - _OUTP_IT("Number of adapter interrupts caught : %li\n", - (long)atomic64_read(&perf_stats.thinints)); - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %li\n", - (long)atomic64_read(&perf_stats.fast_reqs)); - _OUTP_IT("\n"); - _OUTP_IT("Number of inbound transfers : %li\n", - (long)atomic64_read(&perf_stats.inbound_cnt)); - _OUTP_IT("Number of do_QDIOs outbound : %li\n", - (long)atomic64_read(&perf_stats.outbound_cnt)); -#else /* CONFIG_64BIT */ - _OUTP_IT("Number of tasklet runs (total) : %i\n", - atomic_read(&perf_stats.tl_runs)); - _OUTP_IT("Inbound tasklet runs tried/retried : %i/%i\n", - atomic_read(&perf_stats.inbound_tl_runs), - atomic_read(&perf_stats.inbound_tl_runs_resched)); - _OUTP_IT("Inbound-thin tasklet runs tried/retried : %i/%i\n", - atomic_read(&perf_stats.inbound_thin_tl_runs), - atomic_read(&perf_stats.inbound_thin_tl_runs_resched)); - _OUTP_IT("Outbound tasklet runs tried/retried : %i/%i\n", - atomic_read(&perf_stats.outbound_tl_runs), - atomic_read(&perf_stats.outbound_tl_runs_resched)); - _OUTP_IT("\n"); - _OUTP_IT("Number of SIGA sync's issued : %i\n", - atomic_read(&perf_stats.siga_syncs)); - _OUTP_IT("Number of SIGA in's issued : %i\n", - atomic_read(&perf_stats.siga_ins)); - _OUTP_IT("Number of SIGA out's issued : %i\n", - atomic_read(&perf_stats.siga_outs)); - _OUTP_IT("Number of PCIs caught : %i\n", - atomic_read(&perf_stats.pcis)); - _OUTP_IT("Number of adapter interrupts caught : %i\n", - atomic_read(&perf_stats.thinints)); - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %i\n", - atomic_read(&perf_stats.fast_reqs)); - _OUTP_IT("\n"); - _OUTP_IT("Number of inbound transfers : %i\n", - atomic_read(&perf_stats.inbound_cnt)); - _OUTP_IT("Number of do_QDIOs outbound : %i\n", - atomic_read(&perf_stats.outbound_cnt)); -#endif /* CONFIG_64BIT */ - _OUTP_IT("\n"); - - return c; -} - -static struct proc_dir_entry *qdio_perf_proc_file; - -static void -qdio_add_procfs_entry(void) -{ - proc_perf_file_registration=0; - qdio_perf_proc_file=create_proc_entry(QDIO_PERF, - S_IFREG|0444,NULL); - if (qdio_perf_proc_file) { - qdio_perf_proc_file->read_proc=&qdio_perf_procfile_read; - } else proc_perf_file_registration=-1; - - if (proc_perf_file_registration) - QDIO_PRINT_WARN("was not able to register perf. " \ - "proc-file (%i).\n", - proc_perf_file_registration); -} - -static void -qdio_remove_procfs_entry(void) -{ - if (!proc_perf_file_registration) /* means if it went ok earlier */ - remove_proc_entry(QDIO_PERF,NULL); -} - -/** - * attributes in sysfs - *****************************************************************************/ - -static ssize_t -qdio_performance_stats_show(struct bus_type *bus, char *buf) -{ - return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); -} - -static ssize_t -qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count) -{ - unsigned long i; - int ret; - - ret = strict_strtoul(buf, 16, &i); - if (!ret && ((i == 0) || (i == 1))) { - if (i == qdio_performance_stats) - return count; - qdio_performance_stats = i; - if (i==0) { - /* reset perf. stat. info */ -#ifdef CONFIG_64BIT - atomic64_set(&perf_stats.tl_runs, 0); - atomic64_set(&perf_stats.outbound_tl_runs, 0); - atomic64_set(&perf_stats.inbound_tl_runs, 0); - atomic64_set(&perf_stats.inbound_tl_runs_resched, 0); - atomic64_set(&perf_stats.inbound_thin_tl_runs, 0); - atomic64_set(&perf_stats.inbound_thin_tl_runs_resched, - 0); - atomic64_set(&perf_stats.siga_outs, 0); - atomic64_set(&perf_stats.siga_ins, 0); - atomic64_set(&perf_stats.siga_syncs, 0); - atomic64_set(&perf_stats.pcis, 0); - atomic64_set(&perf_stats.thinints, 0); - atomic64_set(&perf_stats.fast_reqs, 0); - atomic64_set(&perf_stats.outbound_cnt, 0); - atomic64_set(&perf_stats.inbound_cnt, 0); -#else /* CONFIG_64BIT */ - atomic_set(&perf_stats.tl_runs, 0); - atomic_set(&perf_stats.outbound_tl_runs, 0); - atomic_set(&perf_stats.inbound_tl_runs, 0); - atomic_set(&perf_stats.inbound_tl_runs_resched, 0); - atomic_set(&perf_stats.inbound_thin_tl_runs, 0); - atomic_set(&perf_stats.inbound_thin_tl_runs_resched, 0); - atomic_set(&perf_stats.siga_outs, 0); - atomic_set(&perf_stats.siga_ins, 0); - atomic_set(&perf_stats.siga_syncs, 0); - atomic_set(&perf_stats.pcis, 0); - atomic_set(&perf_stats.thinints, 0); - atomic_set(&perf_stats.fast_reqs, 0); - atomic_set(&perf_stats.outbound_cnt, 0); - atomic_set(&perf_stats.inbound_cnt, 0); -#endif /* CONFIG_64BIT */ - } - } else { - QDIO_PRINT_ERR("QDIO performance_stats: write 0 or 1 to this file!\n"); - return -EINVAL; - } - return count; -} - -static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show, - qdio_performance_stats_store); - -static void -tiqdio_register_thinints(void) -{ - char dbf_text[20]; - - tiqdio_ind = - s390_register_adapter_interrupt(&tiqdio_thinint_handler, NULL, - TIQDIO_THININT_ISC); - if (IS_ERR(tiqdio_ind)) { - sprintf(dbf_text, "regthn%lx", PTR_ERR(tiqdio_ind)); - QDIO_DBF_TEXT0(0,setup,dbf_text); - QDIO_PRINT_ERR("failed to register adapter handler " \ - "(rc=%li).\nAdapter interrupts might " \ - "not work. Continuing.\n", - PTR_ERR(tiqdio_ind)); - tiqdio_ind = NULL; - } -} - -static void -tiqdio_unregister_thinints(void) -{ - if (tiqdio_ind) - s390_unregister_adapter_interrupt(tiqdio_ind, - TIQDIO_THININT_ISC); -} - -static int -qdio_get_qdio_memory(void) -{ - int i; - indicator_used[0]=1; - - for (i=1;i + * Jan Glauber + */ #ifndef _CIO_QDIO_H #define _CIO_QDIO_H #include -#include #include +#include "chsc.h" -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_VERBOSE_LEVEL 9 -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_VERBOSE_LEVEL 5 -#endif /* CONFIG_QDIO_DEBUG */ -#define QDIO_USE_PROCESSING_STATE - -#define QDIO_MINIMAL_BH_RELIEF_TIME 16 -#define QDIO_TIMER_POLL_VALUE 1 -#define IQDIO_TIMER_POLL_VALUE 1 - -/* - * unfortunately this can't be (QDIO_MAX_BUFFERS_PER_Q*4/3) or so -- as - * we never know, whether we'll get initiative again, e.g. to give the - * transmit skb's back to the stack, however the stack may be waiting for - * them... therefore we define 4 as threshold to start polling (which - * will stop as soon as the asynchronous queue catches up) - * btw, this only applies to the asynchronous HiperSockets queue - */ -#define IQDIO_FILL_LEVEL_TO_POLL 4 - -#define TIQDIO_THININT_ISC QDIO_AIRQ_ISC -#define TIQDIO_DELAY_TARGET 0 -#define QDIO_BUSY_BIT_PATIENCE 100 /* in microsecs */ -#define QDIO_BUSY_BIT_GIVE_UP 10000000 /* 10 seconds */ -#define IQDIO_GLOBAL_LAPS 2 /* GLOBAL_LAPS are not used as we */ -#define IQDIO_GLOBAL_LAPS_INT 1 /* don't global summary */ -#define IQDIO_LOCAL_LAPS 4 -#define IQDIO_LOCAL_LAPS_INT 1 -#define IQDIO_GLOBAL_SUMMARY_CC_MASK 2 -/*#define IQDIO_IQDC_INT_PARM 0x1234*/ - -#define QDIO_Q_LAPS 5 - -#define QDIO_STORAGE_KEY PAGE_DEFAULT_KEY - -#define L2_CACHELINE_SIZE 256 -#define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32)) - -#define QDIO_PERF "qdio_perf" - -/* must be a power of 2 */ -/*#define QDIO_STATS_NUMBER 4 - -#define QDIO_STATS_CLASSES 2 -#define QDIO_STATS_COUNT_NEEDED 2*/ - -#define QDIO_NO_USE_COUNT_TIMEOUT (1*HZ) /* wait for 1 sec on each q before - exiting without having use_count - of the queue to 0 */ - -#define QDIO_ESTABLISH_TIMEOUT (1*HZ) -#define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) -#define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) -#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) -#define QDIO_ACTIVATE_TIMEOUT (5) /* 5 ms */ +#define QDIO_BUSY_BIT_PATIENCE 100 /* 100 microseconds */ +#define QDIO_BUSY_BIT_GIVE_UP 2000000 /* 2 seconds = eternity */ +#define QDIO_INPUT_THRESHOLD 500 /* 500 microseconds */ enum qdio_irq_states { QDIO_IRQ_STATE_INACTIVE, @@ -72,565 +26,352 @@ enum qdio_irq_states { NR_QDIO_IRQ_STATES, }; -/* used as intparm in do_IO: */ -#define QDIO_DOING_SENSEID 0 -#define QDIO_DOING_ESTABLISH 1 -#define QDIO_DOING_ACTIVATE 2 -#define QDIO_DOING_CLEANUP 3 - -/************************* DEBUG FACILITY STUFF *********************/ - -#define QDIO_DBF_HEX(ex,name,level,addr,len) \ - do { \ - if (ex) \ - debug_exception(qdio_dbf_##name,level,(void*)(addr),len); \ - else \ - debug_event(qdio_dbf_##name,level,(void*)(addr),len); \ - } while (0) -#define QDIO_DBF_TEXT(ex,name,level,text) \ - do { \ - if (ex) \ - debug_text_exception(qdio_dbf_##name,level,text); \ - else \ - debug_text_event(qdio_dbf_##name,level,text); \ - } while (0) - - -#define QDIO_DBF_HEX0(ex,name,addr,len) QDIO_DBF_HEX(ex,name,0,addr,len) -#define QDIO_DBF_HEX1(ex,name,addr,len) QDIO_DBF_HEX(ex,name,1,addr,len) -#define QDIO_DBF_HEX2(ex,name,addr,len) QDIO_DBF_HEX(ex,name,2,addr,len) -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_DBF_HEX3(ex,name,addr,len) QDIO_DBF_HEX(ex,name,3,addr,len) -#define QDIO_DBF_HEX4(ex,name,addr,len) QDIO_DBF_HEX(ex,name,4,addr,len) -#define QDIO_DBF_HEX5(ex,name,addr,len) QDIO_DBF_HEX(ex,name,5,addr,len) -#define QDIO_DBF_HEX6(ex,name,addr,len) QDIO_DBF_HEX(ex,name,6,addr,len) -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_DBF_HEX3(ex,name,addr,len) do {} while (0) -#define QDIO_DBF_HEX4(ex,name,addr,len) do {} while (0) -#define QDIO_DBF_HEX5(ex,name,addr,len) do {} while (0) -#define QDIO_DBF_HEX6(ex,name,addr,len) do {} while (0) -#endif /* CONFIG_QDIO_DEBUG */ - -#define QDIO_DBF_TEXT0(ex,name,text) QDIO_DBF_TEXT(ex,name,0,text) -#define QDIO_DBF_TEXT1(ex,name,text) QDIO_DBF_TEXT(ex,name,1,text) -#define QDIO_DBF_TEXT2(ex,name,text) QDIO_DBF_TEXT(ex,name,2,text) -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_DBF_TEXT3(ex,name,text) QDIO_DBF_TEXT(ex,name,3,text) -#define QDIO_DBF_TEXT4(ex,name,text) QDIO_DBF_TEXT(ex,name,4,text) -#define QDIO_DBF_TEXT5(ex,name,text) QDIO_DBF_TEXT(ex,name,5,text) -#define QDIO_DBF_TEXT6(ex,name,text) QDIO_DBF_TEXT(ex,name,6,text) -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_DBF_TEXT3(ex,name,text) do {} while (0) -#define QDIO_DBF_TEXT4(ex,name,text) do {} while (0) -#define QDIO_DBF_TEXT5(ex,name,text) do {} while (0) -#define QDIO_DBF_TEXT6(ex,name,text) do {} while (0) -#endif /* CONFIG_QDIO_DEBUG */ - -#define QDIO_DBF_SETUP_NAME "qdio_setup" -#define QDIO_DBF_SETUP_LEN 8 -#define QDIO_DBF_SETUP_PAGES 4 -#define QDIO_DBF_SETUP_NR_AREAS 1 -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_DBF_SETUP_LEVEL 6 -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_DBF_SETUP_LEVEL 2 -#endif /* CONFIG_QDIO_DEBUG */ - -#define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */ -#define QDIO_DBF_SBAL_LEN 256 -#define QDIO_DBF_SBAL_PAGES 4 -#define QDIO_DBF_SBAL_NR_AREAS 2 -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_DBF_SBAL_LEVEL 6 -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_DBF_SBAL_LEVEL 2 -#endif /* CONFIG_QDIO_DEBUG */ - -#define QDIO_DBF_TRACE_NAME "qdio_trace" -#define QDIO_DBF_TRACE_LEN 8 -#define QDIO_DBF_TRACE_NR_AREAS 2 -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_DBF_TRACE_PAGES 16 -#define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_DBF_TRACE_PAGES 4 -#define QDIO_DBF_TRACE_LEVEL 2 -#endif /* CONFIG_QDIO_DEBUG */ - -#define QDIO_DBF_SENSE_NAME "qdio_sense" -#define QDIO_DBF_SENSE_LEN 64 -#define QDIO_DBF_SENSE_PAGES 2 -#define QDIO_DBF_SENSE_NR_AREAS 1 -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_DBF_SENSE_LEVEL 6 -#else /* CONFIG_QDIO_DEBUG */ -#define QDIO_DBF_SENSE_LEVEL 2 -#endif /* CONFIG_QDIO_DEBUG */ - -#ifdef CONFIG_QDIO_DEBUG -#define QDIO_TRACE_QTYPE QDIO_ZFCP_QFMT - -#define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out" -#define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q -#define QDIO_DBF_SLSB_OUT_PAGES 256 -#define QDIO_DBF_SLSB_OUT_NR_AREAS 1 -#define QDIO_DBF_SLSB_OUT_LEVEL 6 - -#define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in" -#define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q -#define QDIO_DBF_SLSB_IN_PAGES 256 -#define QDIO_DBF_SLSB_IN_NR_AREAS 1 -#define QDIO_DBF_SLSB_IN_LEVEL 6 -#endif /* CONFIG_QDIO_DEBUG */ - -#define QDIO_PRINTK_HEADER QDIO_NAME ": " - -#if QDIO_VERBOSE_LEVEL>8 -#define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_STUPID(x...) do { } while (0) -#endif +/* used as intparm in do_IO */ +#define QDIO_DOING_ESTABLISH 1 +#define QDIO_DOING_ACTIVATE 2 +#define QDIO_DOING_CLEANUP 3 + +#define SLSB_STATE_NOT_INIT 0x0 +#define SLSB_STATE_EMPTY 0x1 +#define SLSB_STATE_PRIMED 0x2 +#define SLSB_STATE_HALTED 0xe +#define SLSB_STATE_ERROR 0xf +#define SLSB_TYPE_INPUT 0x0 +#define SLSB_TYPE_OUTPUT 0x20 +#define SLSB_OWNER_PROG 0x80 +#define SLSB_OWNER_CU 0x40 + +#define SLSB_P_INPUT_NOT_INIT \ + (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_NOT_INIT) /* 0x80 */ +#define SLSB_P_INPUT_ACK \ + (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x81 */ +#define SLSB_CU_INPUT_EMPTY \ + (SLSB_OWNER_CU | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x41 */ +#define SLSB_P_INPUT_PRIMED \ + (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_PRIMED) /* 0x82 */ +#define SLSB_P_INPUT_HALTED \ + (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_HALTED) /* 0x8e */ +#define SLSB_P_INPUT_ERROR \ + (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_ERROR) /* 0x8f */ +#define SLSB_P_OUTPUT_NOT_INIT \ + (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_NOT_INIT) /* 0xa0 */ +#define SLSB_P_OUTPUT_EMPTY \ + (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_EMPTY) /* 0xa1 */ +#define SLSB_CU_OUTPUT_PRIMED \ + (SLSB_OWNER_CU | SLSB_TYPE_OUTPUT | SLSB_STATE_PRIMED) /* 0x62 */ +#define SLSB_P_OUTPUT_HALTED \ + (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_HALTED) /* 0xae */ +#define SLSB_P_OUTPUT_ERROR \ + (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_ERROR) /* 0xaf */ + +#define SLSB_ERROR_DURING_LOOKUP 0xff + +/* additional CIWs returned by extended Sense-ID */ +#define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */ +#define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */ -#if QDIO_VERBOSE_LEVEL>7 -#define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_ALL(x...) do { } while (0) -#endif - -#if QDIO_VERBOSE_LEVEL>6 -#define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_INFO(x...) do { } while (0) -#endif - -#if QDIO_VERBOSE_LEVEL>5 -#define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_WARN(x...) do { } while (0) -#endif - -#if QDIO_VERBOSE_LEVEL>4 -#define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_ERR(x...) do { } while (0) -#endif - -#if QDIO_VERBOSE_LEVEL>3 -#define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_CRIT(x...) do { } while (0) -#endif - -#if QDIO_VERBOSE_LEVEL>2 -#define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_ALERT(x...) do { } while (0) -#endif +/* flags for st qdio sch data */ +#define CHSC_FLAG_QDIO_CAPABILITY 0x80 +#define CHSC_FLAG_VALIDITY 0x40 + +/* qdio adapter-characteristics-1 flag */ +#define AC1_SIGA_INPUT_NEEDED 0x40 /* process input queues */ +#define AC1_SIGA_OUTPUT_NEEDED 0x20 /* process output queues */ +#define AC1_SIGA_SYNC_NEEDED 0x10 /* ask hypervisor to sync */ +#define AC1_AUTOMATIC_SYNC_ON_THININT 0x08 /* set by hypervisor */ +#define AC1_AUTOMATIC_SYNC_ON_OUT_PCI 0x04 /* set by hypervisor */ +#define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */ +#define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */ -#if QDIO_VERBOSE_LEVEL>1 -#define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x) -#else -#define QDIO_PRINT_EMERG(x...) do { } while (0) -#endif - -#define QDIO_HEXDUMP16(importance,header,ptr) \ -QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \ - "%02x %02x %02x %02x %02x %02x %02x %02x " \ - "%02x %02x %02x %02x\n",*(((char*)ptr)), \ - *(((char*)ptr)+1),*(((char*)ptr)+2), \ - *(((char*)ptr)+3),*(((char*)ptr)+4), \ - *(((char*)ptr)+5),*(((char*)ptr)+6), \ - *(((char*)ptr)+7),*(((char*)ptr)+8), \ - *(((char*)ptr)+9),*(((char*)ptr)+10), \ - *(((char*)ptr)+11),*(((char*)ptr)+12), \ - *(((char*)ptr)+13),*(((char*)ptr)+14), \ - *(((char*)ptr)+15)); \ -QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ - "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ - *(((char*)ptr)+16),*(((char*)ptr)+17), \ - *(((char*)ptr)+18),*(((char*)ptr)+19), \ - *(((char*)ptr)+20),*(((char*)ptr)+21), \ - *(((char*)ptr)+22),*(((char*)ptr)+23), \ - *(((char*)ptr)+24),*(((char*)ptr)+25), \ - *(((char*)ptr)+26),*(((char*)ptr)+27), \ - *(((char*)ptr)+28),*(((char*)ptr)+29), \ - *(((char*)ptr)+30),*(((char*)ptr)+31)); - -/****************** END OF DEBUG FACILITY STUFF *********************/ +#ifdef CONFIG_64BIT +static inline int do_sqbs(u64 token, unsigned char state, int queue, + int *start, int *count) +{ + register unsigned long _ccq asm ("0") = *count; + register unsigned long _token asm ("1") = token; + unsigned long _queuestart = ((unsigned long)queue << 32) | *start; -/* - * Some instructions as assembly - */ + asm volatile( + " .insn rsy,0xeb000000008A,%1,0,0(%2)" + : "+d" (_ccq), "+d" (_queuestart) + : "d" ((unsigned long)state), "d" (_token) + : "memory", "cc"); + *count = _ccq & 0xff; + *start = _queuestart & 0xff; -static inline int -do_sqbs(unsigned long sch, unsigned char state, int queue, - unsigned int *start, unsigned int *count) -{ -#ifdef CONFIG_64BIT - register unsigned long _ccq asm ("0") = *count; - register unsigned long _sch asm ("1") = sch; - unsigned long _queuestart = ((unsigned long)queue << 32) | *start; - - asm volatile( - " .insn rsy,0xeb000000008A,%1,0,0(%2)" - : "+d" (_ccq), "+d" (_queuestart) - : "d" ((unsigned long)state), "d" (_sch) - : "memory", "cc"); - *count = _ccq & 0xff; - *start = _queuestart & 0xff; - - return (_ccq >> 32) & 0xff; -#else - return 0; -#endif + return (_ccq >> 32) & 0xff; } -static inline int -do_eqbs(unsigned long sch, unsigned char *state, int queue, - unsigned int *start, unsigned int *count) +static inline int do_eqbs(u64 token, unsigned char *state, int queue, + int *start, int *count) { -#ifdef CONFIG_64BIT register unsigned long _ccq asm ("0") = *count; - register unsigned long _sch asm ("1") = sch; + register unsigned long _token asm ("1") = token; unsigned long _queuestart = ((unsigned long)queue << 32) | *start; unsigned long _state = 0; asm volatile( " .insn rrf,0xB99c0000,%1,%2,0,0" : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) - : "d" (_sch) - : "memory", "cc" ); + : "d" (_token) + : "memory", "cc"); *count = _ccq & 0xff; *start = _queuestart & 0xff; *state = _state & 0xff; return (_ccq >> 32) & 0xff; -#else - return 0; -#endif -} - - -static inline int -do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) -{ - register unsigned long reg0 asm ("0") = 2; - register struct subchannel_id reg1 asm ("1") = schid; - register unsigned long reg2 asm ("2") = mask1; - register unsigned long reg3 asm ("3") = mask2; - int cc; - - asm volatile( - " siga 0\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc) - : "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc"); - return cc; -} - -static inline int -do_siga_input(struct subchannel_id schid, unsigned int mask) -{ - register unsigned long reg0 asm ("0") = 1; - register struct subchannel_id reg1 asm ("1") = schid; - register unsigned long reg2 asm ("2") = mask; - int cc; - - asm volatile( - " siga 0\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc) - : "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory"); - return cc; -} - -static inline int -do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, - unsigned int fc) -{ - register unsigned long __fc asm("0") = fc; - register unsigned long __schid asm("1") = schid; - register unsigned long __mask asm("2") = mask; - int cc; - - asm volatile( - " siga 0\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "=d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask) - : "0" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) - : "cc", "memory"); - (*bb) = ((unsigned int) __fc) >> 31; - return cc; -} - -static inline unsigned long -do_clear_global_summary(void) -{ - register unsigned long __fn asm("1") = 3; - register unsigned long __tmp asm("2"); - register unsigned long __time asm("3"); - - asm volatile( - " .insn rre,0xb2650000,2,0" - : "+d" (__fn), "=d" (__tmp), "=d" (__time)); - return __time; } - -/* - * QDIO device commands returned by extended Sense-ID - */ -#define DEFAULT_ESTABLISH_QS_CMD 0x1b -#define DEFAULT_ESTABLISH_QS_COUNT 0x1000 -#define DEFAULT_ACTIVATE_QS_CMD 0x1f -#define DEFAULT_ACTIVATE_QS_COUNT 0 - -/* - * additional CIWs returned by extended Sense-ID - */ -#define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */ -#define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */ +#else +static inline int do_sqbs(u64 token, unsigned char state, int queue, + int *start, int *count) { return 0; } +static inline int do_eqbs(u64 token, unsigned char *state, int queue, + int *start, int *count) { return 0; } +#endif /* CONFIG_64BIT */ -#define QDIO_CHSC_RESPONSE_CODE_OK 1 -/* flags for st qdio sch data */ -#define CHSC_FLAG_QDIO_CAPABILITY 0x80 -#define CHSC_FLAG_VALIDITY 0x40 +struct qdio_irq; -#define CHSC_FLAG_SIGA_INPUT_NECESSARY 0x40 -#define CHSC_FLAG_SIGA_OUTPUT_NECESSARY 0x20 -#define CHSC_FLAG_SIGA_SYNC_NECESSARY 0x10 -#define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08 -#define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 +struct siga_flag { + u8 input:1; + u8 output:1; + u8 sync:1; + u8 no_sync_ti:1; + u8 no_sync_out_ti:1; + u8 no_sync_out_pci:1; + u8:2; +} __attribute__ ((packed)); -struct qdio_chsc_ssqd { +struct chsc_ssqd_area { struct chsc_header request; - u16 reserved1:10; - u16 ssid:2; - u16 fmt:4; + u16:10; + u8 ssid:2; + u8 fmt:4; u16 first_sch; - u16 reserved2; + u16:16; u16 last_sch; - u32 reserved3; + u32:32; struct chsc_header response; - u32 reserved4; - u8 flags; - u8 reserved5; - u16 sch; - u8 qfmt; - u8 parm; - u8 qdioac1; - u8 sch_class; - u8 pct; - u8 icnt; - u8 reserved7; - u8 ocnt; - u8 reserved8; - u8 mbccnt; - u16 qdioac2; - u64 sch_token; -}; + u32:32; + struct qdio_ssqd_desc qdio_ssqd; +} __attribute__ ((packed)); -struct qdio_perf_stats { -#ifdef CONFIG_64BIT - atomic64_t tl_runs; - atomic64_t outbound_tl_runs; - atomic64_t outbound_tl_runs_resched; - atomic64_t inbound_tl_runs; - atomic64_t inbound_tl_runs_resched; - atomic64_t inbound_thin_tl_runs; - atomic64_t inbound_thin_tl_runs_resched; - - atomic64_t siga_outs; - atomic64_t siga_ins; - atomic64_t siga_syncs; - atomic64_t pcis; - atomic64_t thinints; - atomic64_t fast_reqs; - - atomic64_t outbound_cnt; - atomic64_t inbound_cnt; -#else /* CONFIG_64BIT */ - atomic_t tl_runs; - atomic_t outbound_tl_runs; - atomic_t outbound_tl_runs_resched; - atomic_t inbound_tl_runs; - atomic_t inbound_tl_runs_resched; - atomic_t inbound_thin_tl_runs; - atomic_t inbound_thin_tl_runs_resched; - - atomic_t siga_outs; - atomic_t siga_ins; - atomic_t siga_syncs; - atomic_t pcis; - atomic_t thinints; - atomic_t fast_reqs; - - atomic_t outbound_cnt; - atomic_t inbound_cnt; -#endif /* CONFIG_64BIT */ +struct scssc_area { + struct chsc_header request; + u16 operation_code; + u16:16; + u32:32; + u32:32; + u64 summary_indicator_addr; + u64 subchannel_indicator_addr; + u32 ks:4; + u32 kc:4; + u32:21; + u32 isc:3; + u32 word_with_d_bit; + u32:32; + struct subchannel_id schid; + u32 reserved[1004]; + struct chsc_header response; + u32:32; +} __attribute__ ((packed)); + +struct qdio_input_q { + /* input buffer acknowledgement flag */ + int polling; + + /* last time of noticing incoming data */ + u64 timestamp; + + /* lock for clearing the acknowledgement */ + spinlock_t lock; }; -/* unlikely as the later the better */ -#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) -#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ - qdio_siga_sync(q,~0U,~0U) -#define SYNC_MEMORY_ALL_OUTB if (unlikely(q->siga_sync)) \ - qdio_siga_sync(q,~0U,0) +struct qdio_output_q { + /* failed siga-w attempts*/ + atomic_t busy_siga_counter; -#define NOW qdio_get_micros() -#define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW -#define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time) -#define SAVE_FRONTIER(q,val) q->last_move_ftc=val -#define GET_SAVED_FRONTIER(q) (q->last_move_ftc) + /* start time of busy condition */ + u64 timestamp; -#define MY_MODULE_STRING(x) #x + /* PCIs are enabled for the queue */ + int pci_out_enabled; -#ifdef CONFIG_64BIT -#define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x) -#else /* CONFIG_64BIT */ -#define QDIO_GET_ADDR(x) ((__u32)(long)x) -#endif /* CONFIG_64BIT */ + /* timer to check for more outbound work */ + struct timer_list timer; +}; struct qdio_q { - volatile struct slsb slsb; + struct slsb slsb; + union { + struct qdio_input_q in; + struct qdio_output_q out; + } u; - char unused[QDIO_MAX_BUFFERS_PER_Q]; + /* queue number */ + int nr; - __u32 * dev_st_chg_ind; + /* bitmask of queue number */ + int mask; + /* input or output queue */ int is_input_q; - struct subchannel_id schid; - struct ccw_device *cdev; - - unsigned int is_iqdio_q; - unsigned int is_thinint_q; - /* bit 0 means queue 0, bit 1 means queue 1, ... */ - unsigned int mask; - unsigned int q_no; + /* list of thinint input queues */ + struct list_head entry; + /* upper-layer program handler */ qdio_handler_t (*handler); - /* points to the next buffer to be checked for having - * been processed by the card (outbound) - * or to the next buffer the program should check for (inbound) */ - volatile int first_to_check; - /* and the last time it was: */ - volatile int last_move_ftc; + /* + * inbound: next buffer the program should check for + * outbound: next buffer to check for having been processed + * by the card + */ + int first_to_check; - atomic_t number_of_buffers_used; - atomic_t polling; + /* first_to_check of the last time */ + int last_move_ftc; - unsigned int siga_in; - unsigned int siga_out; - unsigned int siga_sync; - unsigned int siga_sync_done_on_thinints; - unsigned int siga_sync_done_on_outb_tis; - unsigned int hydra_gives_outbound_pcis; + /* beginning position for calling the program */ + int first_to_kick; - /* used to save beginning position when calling dd_handlers */ - int first_element_to_kick; + /* number of buffers in use by the adapter */ + atomic_t nr_buf_used; - atomic_t use_count; - atomic_t is_in_shutdown; - - void *irq_ptr; - - struct timer_list timer; -#ifdef QDIO_USE_TIMERS_FOR_POLLING - atomic_t timer_already_set; - spinlock_t timer_lock; -#else /* QDIO_USE_TIMERS_FOR_POLLING */ + struct qdio_irq *irq_ptr; struct tasklet_struct tasklet; -#endif /* QDIO_USE_TIMERS_FOR_POLLING */ - - enum qdio_irq_states state; - - /* used to store the error condition during a data transfer */ + /* error condition during a data transfer */ unsigned int qdio_error; - unsigned int siga_error; - unsigned int error_status_flags; - - /* list of interesting queues */ - volatile struct qdio_q *list_next; - volatile struct qdio_q *list_prev; struct sl *sl; - volatile struct sbal *sbal[QDIO_MAX_BUFFERS_PER_Q]; - - struct qdio_buffer *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q]; - - unsigned long int_parm; - - /*struct { - int in_bh_check_limit; - int threshold; - } threshold_classes[QDIO_STATS_CLASSES];*/ - - struct { - /* inbound: the time to stop polling - outbound: the time to kick peer */ - int threshold; /* the real value */ - - /* outbound: last time of do_QDIO - inbound: last time of noticing incoming data */ - /*__u64 last_transfer_times[QDIO_STATS_NUMBER]; - int last_transfer_index; */ - - __u64 last_transfer_time; - __u64 busy_start; - } timing; - atomic_t busy_siga_counter; - unsigned int queue_type; - unsigned int is_pci_out; - - /* leave this member at the end. won't be cleared in qdio_fill_qs */ - struct slib *slib; /* a page is allocated under this pointer, - sl points into this page, offset PAGE_SIZE/2 - (after slib) */ + struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; + + /* + * Warning: Leave this member at the end so it won't be cleared in + * qdio_fill_qs. A page is allocated under this pointer and used for + * slib and sl. slib is 2048 bytes big and sl points to offset + * PAGE_SIZE / 2. + */ + struct slib *slib; } __attribute__ ((aligned(256))); struct qdio_irq { - __u32 * volatile dev_st_chg_ind; + struct qib qib; + u32 *dsci; /* address of device state change indicator */ + struct ccw_device *cdev; unsigned long int_parm; struct subchannel_id schid; - - unsigned int is_iqdio_irq; - unsigned int is_thinint_irq; - unsigned int hydra_gives_outbound_pcis; - unsigned int sync_done_on_outb_pcis; - - /* QEBSM facility */ - unsigned int is_qebsm; - unsigned long sch_token; + unsigned long sch_token; /* QEBSM facility */ enum qdio_irq_states state; - unsigned int no_input_qs; - unsigned int no_output_qs; + struct siga_flag siga_flag; /* siga sync information from qdioac */ - unsigned char qdioac; + int nr_input_qs; + int nr_output_qs; struct ccw1 ccw; - struct ciw equeue; struct ciw aqueue; - struct qib qib; - - void (*original_int_handler) (struct ccw_device *, - unsigned long, struct irb *); + struct qdio_ssqd_desc ssqd_desc; + + void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); - /* leave these four members together at the end. won't be cleared in qdio_fill_irq */ + /* + * Warning: Leave these members together at the end so they won't be + * cleared in qdio_setup_irq. + */ struct qdr *qdr; + unsigned long chsc_page; + struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; - struct semaphore setting_up_sema; + + struct mutex setup_mutex; }; -#endif + +/* helper functions */ +#define queue_type(q) q->irq_ptr->qib.qfmt + +#define is_thinint_irq(irq) \ + (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ + css_general_characteristics.aif_osa) + +/* the highest iqdio queue is used for multicast */ +static inline int multicast_outbound(struct qdio_q *q) +{ + return (q->irq_ptr->nr_output_qs > 1) && + (q->nr == q->irq_ptr->nr_output_qs - 1); +} + +static inline unsigned long long get_usecs(void) +{ + return monotonic_clock() >> 12; +} + +#define pci_out_supported(q) \ + (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) +#define is_qebsm(q) (q->irq_ptr->sch_token != 0) + +#define need_siga_sync_thinint(q) (!q->irq_ptr->siga_flag.no_sync_ti) +#define need_siga_sync_out_thinint(q) (!q->irq_ptr->siga_flag.no_sync_out_ti) +#define need_siga_in(q) (q->irq_ptr->siga_flag.input) +#define need_siga_out(q) (q->irq_ptr->siga_flag.output) +#define need_siga_sync(q) (q->irq_ptr->siga_flag.sync) +#define siga_syncs_out_pci(q) (q->irq_ptr->siga_flag.no_sync_out_pci) + +#define for_each_input_queue(irq_ptr, q, i) \ + for (i = 0, q = irq_ptr->input_qs[0]; \ + i < irq_ptr->nr_input_qs; \ + q = irq_ptr->input_qs[++i]) +#define for_each_output_queue(irq_ptr, q, i) \ + for (i = 0, q = irq_ptr->output_qs[0]; \ + i < irq_ptr->nr_output_qs; \ + q = irq_ptr->output_qs[++i]) + +#define prev_buf(bufnr) \ + ((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) +#define next_buf(bufnr) \ + ((bufnr + 1) & QDIO_MAX_BUFFERS_MASK) +#define add_buf(bufnr, inc) \ + ((bufnr + inc) & QDIO_MAX_BUFFERS_MASK) + +/* prototypes for thin interrupt */ +void qdio_sync_after_thinint(struct qdio_q *q); +int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state); +void qdio_check_outbound_after_thinint(struct qdio_q *q); +int qdio_inbound_q_moved(struct qdio_q *q); +void qdio_kick_inbound_handler(struct qdio_q *q); +void qdio_stop_polling(struct qdio_q *q); +int qdio_siga_sync_q(struct qdio_q *q); + +void qdio_setup_thinint(struct qdio_irq *irq_ptr); +int qdio_establish_thinint(struct qdio_irq *irq_ptr); +void qdio_shutdown_thinint(struct qdio_irq *irq_ptr); +void tiqdio_add_input_queues(struct qdio_irq *irq_ptr); +void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr); +void tiqdio_inbound_processing(unsigned long q); +int tiqdio_allocate_memory(void); +void tiqdio_free_memory(void); +int tiqdio_register_thinints(void); +void tiqdio_unregister_thinints(void); + +/* prototypes for setup */ +void qdio_inbound_processing(unsigned long data); +void qdio_outbound_processing(unsigned long data); +void qdio_outbound_timer(unsigned long data); +void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, + struct irb *irb); +int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, + int nr_output_qs); +void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr); +int qdio_setup_irq(struct qdio_initialize *init_data); +void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, + struct ccw_device *cdev); +void qdio_release_memory(struct qdio_irq *irq_ptr); +int qdio_setup_init(void); +void qdio_setup_exit(void); + +#endif /* _CIO_QDIO_H */ diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c new file mode 100644 index 0000000..337aa30 --- /dev/null +++ b/drivers/s390/cio/qdio_debug.c @@ -0,0 +1,240 @@ +/* + * drivers/s390/cio/qdio_debug.c + * + * Copyright IBM Corp. 2008 + * + * Author: Jan Glauber (jang@linux.vnet.ibm.com) + */ +#include +#include +#include +#include +#include +#include "qdio_debug.h" +#include "qdio.h" + +debug_info_t *qdio_dbf_setup; +debug_info_t *qdio_dbf_trace; + +static struct dentry *debugfs_root; +#define MAX_DEBUGFS_QUEUES 32 +static struct dentry *debugfs_queues[MAX_DEBUGFS_QUEUES] = { NULL }; +static DEFINE_MUTEX(debugfs_mutex); + +void qdio_allocate_do_dbf(struct qdio_initialize *init_data) +{ + char dbf_text[20]; + + sprintf(dbf_text, "qfmt:%x", init_data->q_format); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_HEX0(0, setup, init_data->adapter_name, 8); + sprintf(dbf_text, "qpff%4x", init_data->qib_param_field_format); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_HEX0(0, setup, &init_data->qib_param_field, sizeof(void *)); + QDIO_DBF_HEX0(0, setup, &init_data->input_slib_elements, sizeof(void *)); + QDIO_DBF_HEX0(0, setup, &init_data->output_slib_elements, sizeof(void *)); + sprintf(dbf_text, "niq:%4x", init_data->no_input_qs); + QDIO_DBF_TEXT0(0, setup, dbf_text); + sprintf(dbf_text, "noq:%4x", init_data->no_output_qs); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_HEX0(0, setup, &init_data->input_handler, sizeof(void *)); + QDIO_DBF_HEX0(0, setup, &init_data->output_handler, sizeof(void *)); + QDIO_DBF_HEX0(0, setup, &init_data->int_parm, sizeof(long)); + QDIO_DBF_HEX0(0, setup, &init_data->flags, sizeof(long)); + QDIO_DBF_HEX0(0, setup, &init_data->input_sbal_addr_array, sizeof(void *)); + QDIO_DBF_HEX0(0, setup, &init_data->output_sbal_addr_array, sizeof(void *)); +} + +static void qdio_unregister_dbf_views(void) +{ + if (qdio_dbf_setup) + debug_unregister(qdio_dbf_setup); + if (qdio_dbf_trace) + debug_unregister(qdio_dbf_trace); +} + +static int qdio_register_dbf_views(void) +{ + qdio_dbf_setup = debug_register("qdio_setup", QDIO_DBF_SETUP_PAGES, + QDIO_DBF_SETUP_NR_AREAS, + QDIO_DBF_SETUP_LEN); + if (!qdio_dbf_setup) + goto oom; + debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view); + debug_set_level(qdio_dbf_setup, QDIO_DBF_SETUP_LEVEL); + + qdio_dbf_trace = debug_register("qdio_trace", QDIO_DBF_TRACE_PAGES, + QDIO_DBF_TRACE_NR_AREAS, + QDIO_DBF_TRACE_LEN); + if (!qdio_dbf_trace) + goto oom; + debug_register_view(qdio_dbf_trace, &debug_hex_ascii_view); + debug_set_level(qdio_dbf_trace, QDIO_DBF_TRACE_LEVEL); + return 0; +oom: + qdio_unregister_dbf_views(); + return -ENOMEM; +} + +static int qstat_show(struct seq_file *m, void *v) +{ + unsigned char state; + struct qdio_q *q = m->private; + int i; + + if (!q) + return 0; + + seq_printf(m, "device state indicator: %d\n", *q->irq_ptr->dsci); + seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used)); + seq_printf(m, "ftc: %d\n", q->first_to_check); + seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc); + seq_printf(m, "polling: %d\n", q->u.in.polling); + seq_printf(m, "slsb buffer states:\n"); + + qdio_siga_sync_q(q); + for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) { + get_buf_state(q, i, &state); + switch (state) { + case SLSB_P_INPUT_NOT_INIT: + case SLSB_P_OUTPUT_NOT_INIT: + seq_printf(m, "N"); + break; + case SLSB_P_INPUT_PRIMED: + case SLSB_CU_OUTPUT_PRIMED: + seq_printf(m, "+"); + break; + case SLSB_P_INPUT_ACK: + seq_printf(m, "A"); + break; + case SLSB_P_INPUT_ERROR: + case SLSB_P_OUTPUT_ERROR: + seq_printf(m, "x"); + break; + case SLSB_CU_INPUT_EMPTY: + case SLSB_P_OUTPUT_EMPTY: + seq_printf(m, "-"); + break; + case SLSB_P_INPUT_HALTED: + case SLSB_P_OUTPUT_HALTED: + seq_printf(m, "."); + break; + default: + seq_printf(m, "?"); + } + if (i == 63) + seq_printf(m, "\n"); + } + seq_printf(m, "\n"); + return 0; +} + +static ssize_t qstat_seq_write(struct file *file, const char __user *buf, + size_t count, loff_t *off) +{ + struct seq_file *seq = file->private_data; + struct qdio_q *q = seq->private; + + if (!q) + return 0; + + if (q->is_input_q) + xchg(q->irq_ptr->dsci, 1); + local_bh_disable(); + tasklet_schedule(&q->tasklet); + local_bh_enable(); + return count; +} + +static int qstat_seq_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, qstat_show, + filp->f_path.dentry->d_inode->i_private); +} + +static void get_queue_name(struct qdio_q *q, struct ccw_device *cdev, char *name) +{ + memset(name, 0, sizeof(name)); + sprintf(name, "%s", cdev->dev.bus_id); + if (q->is_input_q) + sprintf(name + strlen(name), "_input"); + else + sprintf(name + strlen(name), "_output"); + sprintf(name + strlen(name), "_%d", q->nr); +} + +static void remove_debugfs_entry(struct qdio_q *q) +{ + int i; + + for (i = 0; i < MAX_DEBUGFS_QUEUES; i++) { + if (!debugfs_queues[i]) + continue; + if (debugfs_queues[i]->d_inode->i_private == q) { + debugfs_remove(debugfs_queues[i]); + debugfs_queues[i] = NULL; + } + } +} + +static struct file_operations debugfs_fops = { + .owner = THIS_MODULE, + .open = qstat_seq_open, + .read = seq_read, + .write = qstat_seq_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) +{ + int i = 0; + char name[40]; + + while (debugfs_queues[i] != NULL) { + i++; + if (i >= MAX_DEBUGFS_QUEUES) + return; + } + get_queue_name(q, cdev, name); + debugfs_queues[i] = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR, + debugfs_root, q, &debugfs_fops); +} + +void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) +{ + struct qdio_q *q; + int i; + + mutex_lock(&debugfs_mutex); + for_each_input_queue(irq_ptr, q, i) + setup_debugfs_entry(q, cdev); + for_each_output_queue(irq_ptr, q, i) + setup_debugfs_entry(q, cdev); + mutex_unlock(&debugfs_mutex); +} + +void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) +{ + struct qdio_q *q; + int i; + + mutex_lock(&debugfs_mutex); + for_each_input_queue(irq_ptr, q, i) + remove_debugfs_entry(q); + for_each_output_queue(irq_ptr, q, i) + remove_debugfs_entry(q); + mutex_unlock(&debugfs_mutex); +} + +int __init qdio_debug_init(void) +{ + debugfs_root = debugfs_create_dir("qdio_queues", NULL); + return qdio_register_dbf_views(); +} + +void qdio_debug_exit(void) +{ + debugfs_remove(debugfs_root); + qdio_unregister_dbf_views(); +} diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h new file mode 100644 index 0000000..8484b83 --- /dev/null +++ b/drivers/s390/cio/qdio_debug.h @@ -0,0 +1,91 @@ +/* + * drivers/s390/cio/qdio_debug.h + * + * Copyright IBM Corp. 2008 + * + * Author: Jan Glauber (jang@linux.vnet.ibm.com) + */ +#ifndef QDIO_DEBUG_H +#define QDIO_DEBUG_H + +#include +#include +#include "qdio.h" + +#define QDIO_DBF_HEX(ex, name, level, addr, len) \ + do { \ + if (ex) \ + debug_exception(qdio_dbf_##name, level, (void *)(addr), len); \ + else \ + debug_event(qdio_dbf_##name, level, (void *)(addr), len); \ + } while (0) +#define QDIO_DBF_TEXT(ex, name, level, text) \ + do { \ + if (ex) \ + debug_text_exception(qdio_dbf_##name, level, text); \ + else \ + debug_text_event(qdio_dbf_##name, level, text); \ + } while (0) + +#define QDIO_DBF_HEX0(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 0, addr, len) +#define QDIO_DBF_HEX1(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 1, addr, len) +#define QDIO_DBF_HEX2(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 2, addr, len) + +#ifdef CONFIG_QDIO_DEBUG +#define QDIO_DBF_HEX3(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 3, addr, len) +#define QDIO_DBF_HEX4(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 4, addr, len) +#define QDIO_DBF_HEX5(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 5, addr, len) +#define QDIO_DBF_HEX6(ex, name, addr, len) QDIO_DBF_HEX(ex, name, 6, addr, len) +#else +#define QDIO_DBF_HEX3(ex, name, addr, len) do {} while (0) +#define QDIO_DBF_HEX4(ex, name, addr, len) do {} while (0) +#define QDIO_DBF_HEX5(ex, name, addr, len) do {} while (0) +#define QDIO_DBF_HEX6(ex, name, addr, len) do {} while (0) +#endif /* CONFIG_QDIO_DEBUG */ + +#define QDIO_DBF_TEXT0(ex, name, text) QDIO_DBF_TEXT(ex, name, 0, text) +#define QDIO_DBF_TEXT1(ex, name, text) QDIO_DBF_TEXT(ex, name, 1, text) +#define QDIO_DBF_TEXT2(ex, name, text) QDIO_DBF_TEXT(ex, name, 2, text) + +#ifdef CONFIG_QDIO_DEBUG +#define QDIO_DBF_TEXT3(ex, name, text) QDIO_DBF_TEXT(ex, name, 3, text) +#define QDIO_DBF_TEXT4(ex, name, text) QDIO_DBF_TEXT(ex, name, 4, text) +#define QDIO_DBF_TEXT5(ex, name, text) QDIO_DBF_TEXT(ex, name, 5, text) +#define QDIO_DBF_TEXT6(ex, name, text) QDIO_DBF_TEXT(ex, name, 6, text) +#else +#define QDIO_DBF_TEXT3(ex, name, text) do {} while (0) +#define QDIO_DBF_TEXT4(ex, name, text) do {} while (0) +#define QDIO_DBF_TEXT5(ex, name, text) do {} while (0) +#define QDIO_DBF_TEXT6(ex, name, text) do {} while (0) +#endif /* CONFIG_QDIO_DEBUG */ + +/* s390dbf views */ +#define QDIO_DBF_SETUP_LEN 8 +#define QDIO_DBF_SETUP_PAGES 4 +#define QDIO_DBF_SETUP_NR_AREAS 1 + +#define QDIO_DBF_TRACE_LEN 8 +#define QDIO_DBF_TRACE_NR_AREAS 2 + +#ifdef CONFIG_QDIO_DEBUG +#define QDIO_DBF_TRACE_PAGES 16 +#define QDIO_DBF_SETUP_LEVEL 6 +#define QDIO_DBF_TRACE_LEVEL 4 +#else /* !CONFIG_QDIO_DEBUG */ +#define QDIO_DBF_TRACE_PAGES 4 +#define QDIO_DBF_SETUP_LEVEL 2 +#define QDIO_DBF_TRACE_LEVEL 2 +#endif /* CONFIG_QDIO_DEBUG */ + +extern debug_info_t *qdio_dbf_setup; +extern debug_info_t *qdio_dbf_trace; + +void qdio_allocate_do_dbf(struct qdio_initialize *init_data); +void debug_print_bstat(struct qdio_q *q); +void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, + struct ccw_device *cdev); +void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, + struct ccw_device *cdev); +int qdio_debug_init(void); +void qdio_debug_exit(void); +#endif diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c new file mode 100644 index 0000000..d10c73c --- /dev/null +++ b/drivers/s390/cio/qdio_main.c @@ -0,0 +1,1755 @@ +/* + * linux/drivers/s390/cio/qdio_main.c + * + * Linux for s390 qdio support, buffer handling, qdio API and module support. + * + * Copyright 2000,2008 IBM Corp. + * Author(s): Utz Bacher + * Jan Glauber + * 2.6 cio integration by Cornelia Huck + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cio.h" +#include "css.h" +#include "device.h" +#include "qdio.h" +#include "qdio_debug.h" +#include "qdio_perf.h" + +MODULE_AUTHOR("Utz Bacher ,"\ + "Jan Glauber "); +MODULE_DESCRIPTION("QDIO base support"); +MODULE_LICENSE("GPL"); + +static inline int do_siga_sync(struct subchannel_id schid, + unsigned int out_mask, unsigned int in_mask) +{ + register unsigned long __fc asm ("0") = 2; + register struct subchannel_id __schid asm ("1") = schid; + register unsigned long out asm ("2") = out_mask; + register unsigned long in asm ("3") = in_mask; + int cc; + + asm volatile( + " siga 0\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (cc) + : "d" (__fc), "d" (__schid), "d" (out), "d" (in) : "cc"); + return cc; +} + +static inline int do_siga_input(struct subchannel_id schid, unsigned int mask) +{ + register unsigned long __fc asm ("0") = 1; + register struct subchannel_id __schid asm ("1") = schid; + register unsigned long __mask asm ("2") = mask; + int cc; + + asm volatile( + " siga 0\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (cc) + : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory"); + return cc; +} + +/** + * do_siga_output - perform SIGA-w/wt function + * @schid: subchannel id or in case of QEBSM the subchannel token + * @mask: which output queues to process + * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer + * @fc: function code to perform + * + * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION. + * Note: For IQDC unicast queues only the highest priority queue is processed. + */ +static inline int do_siga_output(unsigned long schid, unsigned long mask, + u32 *bb, unsigned int fc) +{ + register unsigned long __fc asm("0") = fc; + register unsigned long __schid asm("1") = schid; + register unsigned long __mask asm("2") = mask; + int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION; + + asm volatile( + " siga 0\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask) + : : "cc", "memory"); + *bb = ((unsigned int) __fc) >> 31; + return cc; +} + +static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq) +{ + char dbf_text[15]; + + /* all done or next buffer state different */ + if (ccq == 0 || ccq == 32) + return 0; + /* not all buffers processed */ + if (ccq == 96 || ccq == 97) + return 1; + /* notify devices immediately */ + sprintf(dbf_text, "%d", ccq); + QDIO_DBF_TEXT2(1, trace, dbf_text); + return -EIO; +} + +/** + * qdio_do_eqbs - extract buffer states for QEBSM + * @q: queue to manipulate + * @state: state of the extracted buffers + * @start: buffer number to start at + * @count: count of buffers to examine + * + * Returns the number of successfull extracted equal buffer states. + * Stops processing if a state is different from the last buffers state. + */ +static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, + int start, int count) +{ + unsigned int ccq = 0; + int tmp_count = count, tmp_start = start; + int nr = q->nr; + int rc; + char dbf_text[15]; + + BUG_ON(!q->irq_ptr->sch_token); + + if (!q->is_input_q) + nr += q->irq_ptr->nr_input_qs; +again: + ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); + rc = qdio_check_ccq(q, ccq); + + /* At least one buffer was processed, return and extract the remaining + * buffers later. + */ + if ((ccq == 96) && (count != tmp_count)) + return (count - tmp_count); + if (rc == 1) { + QDIO_DBF_TEXT5(1, trace, "eqAGAIN"); + goto again; + } + + if (rc < 0) { + QDIO_DBF_TEXT2(1, trace, "eqberr"); + sprintf(dbf_text, "%2x,%2x,%d,%d", count, tmp_count, ccq, nr); + QDIO_DBF_TEXT2(1, trace, dbf_text); + q->handler(q->irq_ptr->cdev, + QDIO_ERROR_ACTIVATE_CHECK_CONDITION, + 0, -1, -1, q->irq_ptr->int_parm); + return 0; + } + return count - tmp_count; +} + +/** + * qdio_do_sqbs - set buffer states for QEBSM + * @q: queue to manipulate + * @state: new state of the buffers + * @start: first buffer number to change + * @count: how many buffers to change + * + * Returns the number of successfully changed buffers. + * Does retrying until the specified count of buffer states is set or an + * error occurs. + */ +static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start, + int count) +{ + unsigned int ccq = 0; + int tmp_count = count, tmp_start = start; + int nr = q->nr; + int rc; + char dbf_text[15]; + + BUG_ON(!q->irq_ptr->sch_token); + + if (!q->is_input_q) + nr += q->irq_ptr->nr_input_qs; +again: + ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); + rc = qdio_check_ccq(q, ccq); + if (rc == 1) { + QDIO_DBF_TEXT5(1, trace, "sqAGAIN"); + goto again; + } + if (rc < 0) { + QDIO_DBF_TEXT3(1, trace, "sqberr"); + sprintf(dbf_text, "%2x,%2x", count, tmp_count); + QDIO_DBF_TEXT3(1, trace, dbf_text); + sprintf(dbf_text, "%d,%d", ccq, nr); + QDIO_DBF_TEXT3(1, trace, dbf_text); + + q->handler(q->irq_ptr->cdev, + QDIO_ERROR_ACTIVATE_CHECK_CONDITION, + 0, -1, -1, q->irq_ptr->int_parm); + return 0; + } + WARN_ON(tmp_count); + return count - tmp_count; +} + +/* returns number of examined buffers and their common state in *state */ +static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, + unsigned char *state, unsigned int count) +{ + unsigned char __state = 0; + int i; + + BUG_ON(bufnr > QDIO_MAX_BUFFERS_MASK); + BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q); + + if (is_qebsm(q)) + return qdio_do_eqbs(q, state, bufnr, count); + + for (i = 0; i < count; i++) { + if (!__state) + __state = q->slsb.val[bufnr]; + else if (q->slsb.val[bufnr] != __state) + break; + bufnr = next_buf(bufnr); + } + *state = __state; + return i; +} + +inline int get_buf_state(struct qdio_q *q, unsigned int bufnr, + unsigned char *state) +{ + return get_buf_states(q, bufnr, state, 1); +} + +/* wrap-around safe setting of slsb states, returns number of changed buffers */ +static inline int set_buf_states(struct qdio_q *q, int bufnr, + unsigned char state, int count) +{ + int i; + + BUG_ON(bufnr > QDIO_MAX_BUFFERS_MASK); + BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q); + + if (is_qebsm(q)) + return qdio_do_sqbs(q, state, bufnr, count); + + for (i = 0; i < count; i++) { + xchg(&q->slsb.val[bufnr], state); + bufnr = next_buf(bufnr); + } + return count; +} + +static inline int set_buf_state(struct qdio_q *q, int bufnr, + unsigned char state) +{ + return set_buf_states(q, bufnr, state, 1); +} + +/* set slsb states to initial state */ +void qdio_init_buf_states(struct qdio_irq *irq_ptr) +{ + struct qdio_q *q; + int i; + + for_each_input_queue(irq_ptr, q, i) + set_buf_states(q, 0, SLSB_P_INPUT_NOT_INIT, + QDIO_MAX_BUFFERS_PER_Q); + for_each_output_queue(irq_ptr, q, i) + set_buf_states(q, 0, SLSB_P_OUTPUT_NOT_INIT, + QDIO_MAX_BUFFERS_PER_Q); +} + +static int qdio_siga_sync(struct qdio_q *q, unsigned int output, + unsigned int input) +{ + int cc; + + if (!need_siga_sync(q)) + return 0; + + qdio_perf_stat_inc(&perf_stats.siga_sync); + + cc = do_siga_sync(q->irq_ptr->schid, output, input); + if (cc) { + QDIO_DBF_TEXT4(0, trace, "sigasync"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + QDIO_DBF_HEX3(0, trace, &cc, sizeof(int *)); + } + return cc; +} + +inline int qdio_siga_sync_q(struct qdio_q *q) +{ + if (q->is_input_q) + return qdio_siga_sync(q, 0, q->mask); + else + return qdio_siga_sync(q, q->mask, 0); +} + +static inline int qdio_siga_sync_out(struct qdio_q *q) +{ + return qdio_siga_sync(q, ~0U, 0); +} + +static inline int qdio_siga_sync_all(struct qdio_q *q) +{ + return qdio_siga_sync(q, ~0U, ~0U); +} + +static inline int qdio_do_siga_output(struct qdio_q *q, unsigned int *busy_bit) +{ + unsigned int fc = 0; + unsigned long schid; + + if (!is_qebsm(q)) + schid = *((u32 *)&q->irq_ptr->schid); + else { + schid = q->irq_ptr->sch_token; + fc |= 0x80; + } + return do_siga_output(schid, q->mask, busy_bit, fc); +} + +static int qdio_siga_output(struct qdio_q *q) +{ + int cc; + u32 busy_bit; + u64 start_time = 0; + + QDIO_DBF_TEXT5(0, trace, "sigaout"); + QDIO_DBF_HEX5(0, trace, &q, sizeof(void *)); + + qdio_perf_stat_inc(&perf_stats.siga_out); +again: + cc = qdio_do_siga_output(q, &busy_bit); + if (queue_type(q) == QDIO_IQDIO_QFMT && cc == 2 && busy_bit) { + if (!start_time) + start_time = get_usecs(); + else if ((get_usecs() - start_time) < QDIO_BUSY_BIT_PATIENCE) + goto again; + } + + if (cc == 2 && busy_bit) + cc |= QDIO_ERROR_SIGA_BUSY; + if (cc) + QDIO_DBF_HEX3(0, trace, &cc, sizeof(int *)); + return cc; +} + +static inline int qdio_siga_input(struct qdio_q *q) +{ + int cc; + + QDIO_DBF_TEXT4(0, trace, "sigain"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + + qdio_perf_stat_inc(&perf_stats.siga_in); + + cc = do_siga_input(q->irq_ptr->schid, q->mask); + if (cc) + QDIO_DBF_HEX3(0, trace, &cc, sizeof(int *)); + return cc; +} + +/* called from thinint inbound handler */ +void qdio_sync_after_thinint(struct qdio_q *q) +{ + if (pci_out_supported(q)) { + if (need_siga_sync_thinint(q)) + qdio_siga_sync_all(q); + else if (need_siga_sync_out_thinint(q)) + qdio_siga_sync_out(q); + } else + qdio_siga_sync_q(q); +} + +inline void qdio_stop_polling(struct qdio_q *q) +{ + spin_lock_bh(&q->u.in.lock); + if (!q->u.in.polling) { + spin_unlock_bh(&q->u.in.lock); + return; + } + q->u.in.polling = 0; + qdio_perf_stat_inc(&perf_stats.debug_stop_polling); + + /* show the card that we are not polling anymore */ + set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT); + spin_unlock_bh(&q->u.in.lock); +} + +static void announce_buffer_error(struct qdio_q *q) +{ + char dbf_text[15]; + + if (q->is_input_q) + QDIO_DBF_TEXT3(1, trace, "inperr"); + else + QDIO_DBF_TEXT3(0, trace, "outperr"); + + sprintf(dbf_text, "%x-%x-%x", q->first_to_check, + q->sbal[q->first_to_check]->element[14].flags, + q->sbal[q->first_to_check]->element[15].flags); + QDIO_DBF_TEXT3(1, trace, dbf_text); + QDIO_DBF_HEX2(1, trace, q->sbal[q->first_to_check], 256); + + q->qdio_error = QDIO_ERROR_SLSB_STATE; +} + +static int get_inbound_buffer_frontier(struct qdio_q *q) +{ + int count, stop; + unsigned char state; + + /* + * If we still poll don't update last_move_ftc, keep the + * previously ACK buffer there. + */ + if (!q->u.in.polling) + q->last_move_ftc = q->first_to_check; + + /* + * Don't check 128 buffers, as otherwise qdio_inbound_q_moved + * would return 0. + */ + count = min(atomic_read(&q->nr_buf_used), QDIO_MAX_BUFFERS_MASK); + stop = add_buf(q->first_to_check, count); + + /* + * No siga sync here, as a PCI or we after a thin interrupt + * will sync the queues. + */ + + /* need to set count to 1 for non-qebsm */ + if (!is_qebsm(q)) + count = 1; + +check_next: + if (q->first_to_check == stop) + goto out; + + count = get_buf_states(q, q->first_to_check, &state, count); + if (!count) + goto out; + + switch (state) { + case SLSB_P_INPUT_PRIMED: + QDIO_DBF_TEXT5(0, trace, "inptprim"); + + /* + * Only ACK the first buffer. The ACK will be removed in + * qdio_stop_polling. + */ + if (q->u.in.polling) + state = SLSB_P_INPUT_NOT_INIT; + else { + q->u.in.polling = 1; + state = SLSB_P_INPUT_ACK; + } + set_buf_state(q, q->first_to_check, state); + + /* + * Need to change all PRIMED buffers to NOT_INIT, otherwise + * we're loosing initiative in the thinint code. + */ + if (count > 1) + set_buf_states(q, next_buf(q->first_to_check), + SLSB_P_INPUT_NOT_INIT, count - 1); + + /* + * No siga-sync needed for non-qebsm here, as the inbound queue + * will be synced on the next siga-r, resp. + * tiqdio_is_inbound_q_done will do the siga-sync. + */ + q->first_to_check = add_buf(q->first_to_check, count); + atomic_sub(count, &q->nr_buf_used); + goto check_next; + case SLSB_P_INPUT_ERROR: + announce_buffer_error(q); + /* process the buffer, the upper layer will take care of it */ + q->first_to_check = add_buf(q->first_to_check, count); + atomic_sub(count, &q->nr_buf_used); + break; + case SLSB_CU_INPUT_EMPTY: + case SLSB_P_INPUT_NOT_INIT: + case SLSB_P_INPUT_ACK: + QDIO_DBF_TEXT5(0, trace, "inpnipro"); + break; + default: + BUG(); + } +out: + QDIO_DBF_HEX4(0, trace, &q->first_to_check, sizeof(int)); + return q->first_to_check; +} + +int qdio_inbound_q_moved(struct qdio_q *q) +{ + int bufnr; + + bufnr = get_inbound_buffer_frontier(q); + + if ((bufnr != q->last_move_ftc) || q->qdio_error) { + if (!need_siga_sync(q) && !pci_out_supported(q)) + q->u.in.timestamp = get_usecs(); + + QDIO_DBF_TEXT4(0, trace, "inhasmvd"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + return 1; + } else + return 0; +} + +static int qdio_inbound_q_done(struct qdio_q *q) +{ + unsigned char state; +#ifdef CONFIG_QDIO_DEBUG + char dbf_text[15]; +#endif + + if (!atomic_read(&q->nr_buf_used)) + return 1; + + /* + * We need that one for synchronization with the adapter, as it + * does a kind of PCI avoidance. + */ + qdio_siga_sync_q(q); + + get_buf_state(q, q->first_to_check, &state); + if (state == SLSB_P_INPUT_PRIMED) + /* we got something to do */ + return 0; + + /* on VM, we don't poll, so the q is always done here */ + if (need_siga_sync(q) || pci_out_supported(q)) + return 1; + + /* + * At this point we know, that inbound first_to_check + * has (probably) not moved (see qdio_inbound_processing). + */ + if (get_usecs() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) { +#ifdef CONFIG_QDIO_DEBUG + QDIO_DBF_TEXT4(0, trace, "inqisdon"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + sprintf(dbf_text, "pf%02x", q->first_to_check); + QDIO_DBF_TEXT4(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + return 1; + } else { +#ifdef CONFIG_QDIO_DEBUG + QDIO_DBF_TEXT4(0, trace, "inqisntd"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + sprintf(dbf_text, "pf%02x", q->first_to_check); + QDIO_DBF_TEXT4(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + return 0; + } +} + +void qdio_kick_inbound_handler(struct qdio_q *q) +{ + int count, start, end; +#ifdef CONFIG_QDIO_DEBUG + char dbf_text[15]; +#endif + + qdio_perf_stat_inc(&perf_stats.inbound_handler); + + start = q->first_to_kick; + end = q->first_to_check; + if (end >= start) + count = end - start; + else + count = end + QDIO_MAX_BUFFERS_PER_Q - start; + +#ifdef CONFIG_QDIO_DEBUG + sprintf(dbf_text, "s=%2xc=%2x", start, count); + QDIO_DBF_TEXT4(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + + if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) + return; + + q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, + start, count, q->irq_ptr->int_parm); + + /* for the next time */ + q->first_to_kick = q->first_to_check; + q->qdio_error = 0; +} + +static void __qdio_inbound_processing(struct qdio_q *q) +{ + qdio_perf_stat_inc(&perf_stats.tasklet_inbound); +again: + if (!qdio_inbound_q_moved(q)) + return; + + qdio_kick_inbound_handler(q); + + if (!qdio_inbound_q_done(q)) + /* means poll time is not yet over */ + goto again; + + qdio_stop_polling(q); + /* + * We need to check again to not lose initiative after + * resetting the ACK state. + */ + if (!qdio_inbound_q_done(q)) + goto again; +} + +/* inbound tasklet */ +void qdio_inbound_processing(unsigned long data) +{ + struct qdio_q *q = (struct qdio_q *)data; + __qdio_inbound_processing(q); +} + +static int get_outbound_buffer_frontier(struct qdio_q *q) +{ + int count, stop; + unsigned char state; + + if (((queue_type(q) != QDIO_IQDIO_QFMT) && !pci_out_supported(q)) || + (queue_type(q) == QDIO_IQDIO_QFMT && multicast_outbound(q))) + qdio_siga_sync_q(q); + + /* + * Don't check 128 buffers, as otherwise qdio_inbound_q_moved + * would return 0. + */ + count = min(atomic_read(&q->nr_buf_used), QDIO_MAX_BUFFERS_MASK); + stop = add_buf(q->first_to_check, count); + + /* need to set count to 1 for non-qebsm */ + if (!is_qebsm(q)) + count = 1; + +check_next: + if (q->first_to_check == stop) + return q->first_to_check; + + count = get_buf_states(q, q->first_to_check, &state, count); + if (!count) + return q->first_to_check; + + switch (state) { + case SLSB_P_OUTPUT_EMPTY: + /* the adapter got it */ + QDIO_DBF_TEXT5(0, trace, "outpempt"); + + atomic_sub(count, &q->nr_buf_used); + q->first_to_check = add_buf(q->first_to_check, count); + /* + * We fetch all buffer states at once. get_buf_states may + * return count < stop. For QEBSM we do not loop. + */ + if (is_qebsm(q)) + break; + goto check_next; + case SLSB_P_OUTPUT_ERROR: + announce_buffer_error(q); + /* process the buffer, the upper layer will take care of it */ + q->first_to_check = add_buf(q->first_to_check, count); + atomic_sub(count, &q->nr_buf_used); + break; + case SLSB_CU_OUTPUT_PRIMED: + /* the adapter has not fetched the output yet */ + QDIO_DBF_TEXT5(0, trace, "outpprim"); + break; + case SLSB_P_OUTPUT_NOT_INIT: + case SLSB_P_OUTPUT_HALTED: + break; + default: + BUG(); + } + return q->first_to_check; +} + +/* all buffers processed? */ +static inline int qdio_outbound_q_done(struct qdio_q *q) +{ + return atomic_read(&q->nr_buf_used) == 0; +} + +static inline int qdio_outbound_q_moved(struct qdio_q *q) +{ + int bufnr; + + bufnr = get_outbound_buffer_frontier(q); + + if ((bufnr != q->last_move_ftc) || q->qdio_error) { + q->last_move_ftc = bufnr; + QDIO_DBF_TEXT4(0, trace, "oqhasmvd"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + return 1; + } else + return 0; +} + +/* + * VM could present us cc=2 and busy bit set on SIGA-write + * during reconfiguration of their Guest LAN (only in iqdio mode, + * otherwise qdio is asynchronous and cc=2 and busy bit there will take + * the queues down immediately). + * + * Therefore qdio_siga_output will try for a short time constantly, + * if such a condition occurs. If it doesn't change, it will + * increase the busy_siga_counter and save the timestamp, and + * schedule the queue for later processing. qdio_outbound_processing + * will check out the counter. If non-zero, it will call qdio_kick_outbound_q + * as often as the value of the counter. This will attempt further SIGA + * instructions. For each successful SIGA, the counter is + * decreased, for failing SIGAs the counter remains the same, after + * all. After some time of no movement, qdio_kick_outbound_q will + * finally fail and reflect corresponding error codes to call + * the upper layer module and have it take the queues down. + * + * Note that this is a change from the original HiperSockets design + * (saying cc=2 and busy bit means take the queues down), but in + * these days Guest LAN didn't exist... excessive cc=2 with busy bit + * conditions will still take the queues down, but the threshold is + * higher due to the Guest LAN environment. + * + * Called from outbound tasklet and do_QDIO handler. + */ +static void qdio_kick_outbound_q(struct qdio_q *q) +{ + int rc; +#ifdef CONFIG_QDIO_DEBUG + char dbf_text[15]; + + QDIO_DBF_TEXT5(0, trace, "kickoutq"); + QDIO_DBF_HEX5(0, trace, &q, sizeof(void *)); +#endif /* CONFIG_QDIO_DEBUG */ + + if (!need_siga_out(q)) + return; + + rc = qdio_siga_output(q); + switch (rc) { + case 0: + /* went smooth this time, reset timestamp */ + q->u.out.timestamp = 0; + + /* TODO: improve error handling for CC=0 case */ +#ifdef CONFIG_QDIO_DEBUG + QDIO_DBF_TEXT3(0, trace, "cc2reslv"); + sprintf(dbf_text, "%4x%2x%2x", q->irq_ptr->schid.sch_no, q->nr, + atomic_read(&q->u.out.busy_siga_counter)); + QDIO_DBF_TEXT3(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + break; + /* cc=2 and busy bit */ + case (2 | QDIO_ERROR_SIGA_BUSY): + atomic_inc(&q->u.out.busy_siga_counter); + + /* if the last siga was successful, save timestamp here */ + if (!q->u.out.timestamp) + q->u.out.timestamp = get_usecs(); + + /* if we're in time, don't touch qdio_error */ + if (get_usecs() - q->u.out.timestamp < QDIO_BUSY_BIT_GIVE_UP) { + tasklet_schedule(&q->tasklet); + break; + } + QDIO_DBF_TEXT2(0, trace, "cc2REPRT"); +#ifdef CONFIG_QDIO_DEBUG + sprintf(dbf_text, "%4x%2x%2x", q->irq_ptr->schid.sch_no, q->nr, + atomic_read(&q->u.out.busy_siga_counter)); + QDIO_DBF_TEXT3(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + default: + /* for plain cc=1, 2 or 3 */ + q->qdio_error = rc; + } +} + +static void qdio_kick_outbound_handler(struct qdio_q *q) +{ + int start, end, count; +#ifdef CONFIG_QDIO_DEBUG + char dbf_text[15]; +#endif + + start = q->first_to_kick; + end = q->last_move_ftc; + if (end >= start) + count = end - start; + else + count = end + QDIO_MAX_BUFFERS_PER_Q - start; + +#ifdef CONFIG_QDIO_DEBUG + QDIO_DBF_TEXT4(0, trace, "kickouth"); + QDIO_DBF_HEX4(0, trace, &q, sizeof(void *)); + + sprintf(dbf_text, "s=%2xc=%2x", start, count); + QDIO_DBF_TEXT4(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + + if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) + return; + + q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, + q->irq_ptr->int_parm); + + /* for the next time: */ + q->first_to_kick = q->last_move_ftc; + q->qdio_error = 0; +} + +static void __qdio_outbound_processing(struct qdio_q *q) +{ + int siga_attempts; + + qdio_perf_stat_inc(&perf_stats.tasklet_outbound); + + /* see comment in qdio_kick_outbound_q */ + siga_attempts = atomic_read(&q->u.out.busy_siga_counter); + while (siga_attempts--) { + atomic_dec(&q->u.out.busy_siga_counter); + qdio_kick_outbound_q(q); + } + + BUG_ON(atomic_read(&q->nr_buf_used) < 0); + + if (qdio_outbound_q_moved(q)) + qdio_kick_outbound_handler(q); + + if (queue_type(q) == QDIO_ZFCP_QFMT) { + if (!pci_out_supported(q) && !qdio_outbound_q_done(q)) + tasklet_schedule(&q->tasklet); + return; + } + + /* bail out for HiperSockets unicast queues */ + if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) + return; + + if (q->u.out.pci_out_enabled) + return; + + /* + * Now we know that queue type is either qeth without pci enabled + * or HiperSockets multicast. Make sure buffer switch from PRIMED to + * EMPTY is noticed and outbound_handler is called after some time. + */ + if (qdio_outbound_q_done(q)) + del_timer(&q->u.out.timer); + else { + if (!timer_pending(&q->u.out.timer)) { + mod_timer(&q->u.out.timer, jiffies + 10 * HZ); + qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer); + } + } +} + +/* outbound tasklet */ +void qdio_outbound_processing(unsigned long data) +{ + struct qdio_q *q = (struct qdio_q *)data; + __qdio_outbound_processing(q); +} + +void qdio_outbound_timer(unsigned long data) +{ + struct qdio_q *q = (struct qdio_q *)data; + tasklet_schedule(&q->tasklet); +} + +/* called from thinint inbound tasklet */ +void qdio_check_outbound_after_thinint(struct qdio_q *q) +{ + struct qdio_q *out; + int i; + + if (!pci_out_supported(q)) + return; + + for_each_output_queue(q->irq_ptr, out, i) + if (!qdio_outbound_q_done(out)) + tasklet_schedule(&out->tasklet); +} + +static inline void qdio_set_state(struct qdio_irq *irq_ptr, + enum qdio_irq_states state) +{ +#ifdef CONFIG_QDIO_DEBUG + char dbf_text[15]; + + QDIO_DBF_TEXT5(0, trace, "newstate"); + sprintf(dbf_text, "%4x%4x", irq_ptr->schid.sch_no, state); + QDIO_DBF_TEXT5(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + + irq_ptr->state = state; + mb(); +} + +static void qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) +{ + char dbf_text[15]; + + if (irb->esw.esw0.erw.cons) { + sprintf(dbf_text, "sens%4x", schid.sch_no); + QDIO_DBF_TEXT2(1, trace, dbf_text); + QDIO_DBF_HEX0(0, trace, irb, 64); + QDIO_DBF_HEX0(0, trace, irb->ecw, 64); + } +} + +/* PCI interrupt handler */ +static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) +{ + int i; + struct qdio_q *q; + + qdio_perf_stat_inc(&perf_stats.pci_int); + + for_each_input_queue(irq_ptr, q, i) + tasklet_schedule(&q->tasklet); + + if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) + return; + + for_each_output_queue(irq_ptr, q, i) { + if (qdio_outbound_q_done(q)) + continue; + + if (!siga_syncs_out_pci(q)) + qdio_siga_sync_q(q); + + tasklet_schedule(&q->tasklet); + } +} + +static void qdio_handle_activate_check(struct ccw_device *cdev, + unsigned long intparm, int cstat, int dstat) +{ + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + struct qdio_q *q; + char dbf_text[15]; + + QDIO_DBF_TEXT2(1, trace, "ick2"); + sprintf(dbf_text, "%s", cdev->dev.bus_id); + QDIO_DBF_TEXT2(1, trace, dbf_text); + QDIO_DBF_HEX2(0, trace, &intparm, sizeof(int)); + QDIO_DBF_HEX2(0, trace, &dstat, sizeof(int)); + QDIO_DBF_HEX2(0, trace, &cstat, sizeof(int)); + + if (irq_ptr->nr_input_qs) { + q = irq_ptr->input_qs[0]; + } else if (irq_ptr->nr_output_qs) { + q = irq_ptr->output_qs[0]; + } else { + dump_stack(); + goto no_handler; + } + q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, + 0, -1, -1, irq_ptr->int_parm); +no_handler: + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); +} + +static void qdio_call_shutdown(struct work_struct *work) +{ + struct ccw_device_private *priv; + struct ccw_device *cdev; + + priv = container_of(work, struct ccw_device_private, kick_work); + cdev = priv->cdev; + qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); + put_device(&cdev->dev); +} + +static void qdio_int_error(struct ccw_device *cdev) +{ + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + switch (irq_ptr->state) { + case QDIO_IRQ_STATE_INACTIVE: + case QDIO_IRQ_STATE_CLEANUP: + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); + break; + case QDIO_IRQ_STATE_ESTABLISHED: + case QDIO_IRQ_STATE_ACTIVE: + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); + if (get_device(&cdev->dev)) { + /* Can't call shutdown from interrupt context. */ + PREPARE_WORK(&cdev->private->kick_work, + qdio_call_shutdown); + queue_work(ccw_device_work, &cdev->private->kick_work); + } + break; + default: + WARN_ON(1); + } + wake_up(&cdev->private->wait_q); +} + +static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat, + int dstat) +{ + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (cstat || (dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) { + QDIO_DBF_TEXT2(1, setup, "eq:ckcon"); + goto error; + } + + if (!(dstat & DEV_STAT_DEV_END)) { + QDIO_DBF_TEXT2(1, setup, "eq:no de"); + goto error; + } + + if (dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) { + QDIO_DBF_TEXT2(1, setup, "eq:badio"); + goto error; + } + return 0; +error: + QDIO_DBF_HEX2(0, trace, &cstat, sizeof(int)); + QDIO_DBF_HEX2(0, trace, &dstat, sizeof(int)); + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); + return 1; +} + +static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, + int dstat) +{ + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + char dbf_text[15]; + + sprintf(dbf_text, "qehi%4x", cdev->private->schid.sch_no); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_TEXT0(0, trace, dbf_text); + + if (!qdio_establish_check_errors(cdev, cstat, dstat)) + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ESTABLISHED); +} + +/* qdio interrupt handler */ +void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, + struct irb *irb) +{ + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + int cstat, dstat; + char dbf_text[15]; + + qdio_perf_stat_inc(&perf_stats.qdio_int); + + if (!intparm || !irq_ptr) { + sprintf(dbf_text, "qihd%4x", cdev->private->schid.sch_no); + QDIO_DBF_TEXT2(1, setup, dbf_text); + return; + } + + if (IS_ERR(irb)) { + switch (PTR_ERR(irb)) { + case -EIO: + sprintf(dbf_text, "ierr%4x", + cdev->private->schid.sch_no); + QDIO_DBF_TEXT2(1, setup, dbf_text); + qdio_int_error(cdev); + return; + case -ETIMEDOUT: + sprintf(dbf_text, "qtoh%4x", + cdev->private->schid.sch_no); + QDIO_DBF_TEXT2(1, setup, dbf_text); + qdio_int_error(cdev); + return; + default: + WARN_ON(1); + return; + } + } + qdio_irq_check_sense(irq_ptr->schid, irb); + + cstat = irb->scsw.cmd.cstat; + dstat = irb->scsw.cmd.dstat; + + switch (irq_ptr->state) { + case QDIO_IRQ_STATE_INACTIVE: + qdio_establish_handle_irq(cdev, cstat, dstat); + break; + + case QDIO_IRQ_STATE_CLEANUP: + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); + break; + + case QDIO_IRQ_STATE_ESTABLISHED: + case QDIO_IRQ_STATE_ACTIVE: + if (cstat & SCHN_STAT_PCI) { + qdio_int_handler_pci(irq_ptr); + /* no state change so no need to wake up wait_q */ + return; + } + if ((cstat & ~SCHN_STAT_PCI) || dstat) { + qdio_handle_activate_check(cdev, intparm, cstat, + dstat); + break; + } + default: + WARN_ON(1); + } + wake_up(&cdev->private->wait_q); +} + +/** + * qdio_get_ssqd_desc - get qdio subchannel description + * @cdev: ccw device to get description for + * + * Returns a pointer to the saved qdio subchannel description, + * or NULL for not setup qdio devices. + */ +struct qdio_ssqd_desc *qdio_get_ssqd_desc(struct ccw_device *cdev) +{ + struct qdio_irq *irq_ptr; + + QDIO_DBF_TEXT0(0, setup, "getssqd"); + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return NULL; + + return &irq_ptr->ssqd_desc; +} +EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc); + +/** + * qdio_cleanup - shutdown queues and free data structures + * @cdev: associated ccw device + * @how: use halt or clear to shutdown + * + * This function calls qdio_shutdown() for @cdev with method @how + * and on success qdio_free() for @cdev. + */ +int qdio_cleanup(struct ccw_device *cdev, int how) +{ + struct qdio_irq *irq_ptr; + char dbf_text[15]; + int rc; + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return -ENODEV; + + sprintf(dbf_text, "qcln%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT1(0, trace, dbf_text); + QDIO_DBF_TEXT0(0, setup, dbf_text); + + rc = qdio_shutdown(cdev, how); + if (rc == 0) + rc = qdio_free(cdev); + return rc; +} +EXPORT_SYMBOL_GPL(qdio_cleanup); + +static void qdio_shutdown_queues(struct ccw_device *cdev) +{ + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + struct qdio_q *q; + int i; + + for_each_input_queue(irq_ptr, q, i) + tasklet_disable(&q->tasklet); + + for_each_output_queue(irq_ptr, q, i) { + tasklet_disable(&q->tasklet); + del_timer(&q->u.out.timer); + } +} + +/** + * qdio_shutdown - shut down a qdio subchannel + * @cdev: associated ccw device + * @how: use halt or clear to shutdown + */ +int qdio_shutdown(struct ccw_device *cdev, int how) +{ + struct qdio_irq *irq_ptr; + int rc; + unsigned long flags; + char dbf_text[15]; + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return -ENODEV; + + mutex_lock(&irq_ptr->setup_mutex); + /* + * Subchannel was already shot down. We cannot prevent being called + * twice since cio may trigger a shutdown asynchronously. + */ + if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) { + mutex_unlock(&irq_ptr->setup_mutex); + return 0; + } + + sprintf(dbf_text, "qsqs%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT1(0, trace, dbf_text); + QDIO_DBF_TEXT0(0, setup, dbf_text); + + tiqdio_remove_input_queues(irq_ptr); + qdio_shutdown_queues(cdev); + qdio_shutdown_debug_entries(irq_ptr, cdev); + + /* cleanup subchannel */ + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + + if (how & QDIO_FLAG_CLEANUP_USING_CLEAR) + rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP); + else + /* default behaviour is halt */ + rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP); + if (rc) { + sprintf(dbf_text, "sher%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT0(0, setup, dbf_text); + sprintf(dbf_text, "rc=%d", rc); + QDIO_DBF_TEXT0(0, setup, dbf_text); + goto no_cleanup; + } + + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + wait_event_interruptible_timeout(cdev->private->wait_q, + irq_ptr->state == QDIO_IRQ_STATE_INACTIVE || + irq_ptr->state == QDIO_IRQ_STATE_ERR, + 10 * HZ); + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + +no_cleanup: + qdio_shutdown_thinint(irq_ptr); + + /* restore interrupt handler */ + if ((void *)cdev->handler == (void *)qdio_int_handler) + cdev->handler = irq_ptr->orig_handler; + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); + mutex_unlock(&irq_ptr->setup_mutex); + module_put(THIS_MODULE); + if (rc) + return rc; + return 0; +} +EXPORT_SYMBOL_GPL(qdio_shutdown); + +/** + * qdio_free - free data structures for a qdio subchannel + * @cdev: associated ccw device + */ +int qdio_free(struct ccw_device *cdev) +{ + struct qdio_irq *irq_ptr; + char dbf_text[15]; + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return -ENODEV; + + mutex_lock(&irq_ptr->setup_mutex); + + sprintf(dbf_text, "qfqs%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT1(0, trace, dbf_text); + QDIO_DBF_TEXT0(0, setup, dbf_text); + + cdev->private->qdio_data = NULL; + mutex_unlock(&irq_ptr->setup_mutex); + + qdio_release_memory(irq_ptr); + return 0; +} +EXPORT_SYMBOL_GPL(qdio_free); + +/** + * qdio_initialize - allocate and establish queues for a qdio subchannel + * @init_data: initialization data + * + * This function first allocates queues via qdio_allocate() and on success + * establishes them via qdio_establish(). + */ +int qdio_initialize(struct qdio_initialize *init_data) +{ + int rc; + char dbf_text[15]; + + sprintf(dbf_text, "qini%4x", init_data->cdev->private->schid.sch_no); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_TEXT0(0, trace, dbf_text); + + rc = qdio_allocate(init_data); + if (rc) + return rc; + + rc = qdio_establish(init_data); + if (rc) + qdio_free(init_data->cdev); + return rc; +} +EXPORT_SYMBOL_GPL(qdio_initialize); + +/** + * qdio_allocate - allocate qdio queues and associated data + * @init_data: initialization data + */ +int qdio_allocate(struct qdio_initialize *init_data) +{ + struct qdio_irq *irq_ptr; + char dbf_text[15]; + + sprintf(dbf_text, "qalc%4x", init_data->cdev->private->schid.sch_no); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_TEXT0(0, trace, dbf_text); + + if ((init_data->no_input_qs && !init_data->input_handler) || + (init_data->no_output_qs && !init_data->output_handler)) + return -EINVAL; + + if ((init_data->no_input_qs > QDIO_MAX_QUEUES_PER_IRQ) || + (init_data->no_output_qs > QDIO_MAX_QUEUES_PER_IRQ)) + return -EINVAL; + + if ((!init_data->input_sbal_addr_array) || + (!init_data->output_sbal_addr_array)) + return -EINVAL; + + qdio_allocate_do_dbf(init_data); + + /* irq_ptr must be in GFP_DMA since it contains ccw1.cda */ + irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!irq_ptr) + goto out_err; + QDIO_DBF_TEXT0(0, setup, "irq_ptr:"); + QDIO_DBF_HEX0(0, setup, &irq_ptr, sizeof(void *)); + + mutex_init(&irq_ptr->setup_mutex); + + /* + * Allocate a page for the chsc calls in qdio_establish. + * Must be pre-allocated since a zfcp recovery will call + * qdio_establish. In case of low memory and swap on a zfcp disk + * we may not be able to allocate memory otherwise. + */ + irq_ptr->chsc_page = get_zeroed_page(GFP_KERNEL); + if (!irq_ptr->chsc_page) + goto out_rel; + + /* qdr is used in ccw1.cda which is u32 */ + irq_ptr->qdr = kzalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA); + if (!irq_ptr->qdr) + goto out_rel; + WARN_ON((unsigned long)irq_ptr->qdr & 0xfff); + + QDIO_DBF_TEXT0(0, setup, "qdr:"); + QDIO_DBF_HEX0(0, setup, &irq_ptr->qdr, sizeof(void *)); + + if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs, + init_data->no_output_qs)) + goto out_rel; + + init_data->cdev->private->qdio_data = irq_ptr; + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); + return 0; +out_rel: + qdio_release_memory(irq_ptr); +out_err: + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(qdio_allocate); + +/** + * qdio_establish - establish queues on a qdio subchannel + * @init_data: initialization data + */ +int qdio_establish(struct qdio_initialize *init_data) +{ + char dbf_text[20]; + struct qdio_irq *irq_ptr; + struct ccw_device *cdev = init_data->cdev; + unsigned long saveflags; + int rc; + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return -ENODEV; + + if (cdev->private->state != DEV_STATE_ONLINE) + return -EINVAL; + + if (!try_module_get(THIS_MODULE)) + return -EINVAL; + + sprintf(dbf_text, "qest%4x", cdev->private->schid.sch_no); + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_TEXT0(0, trace, dbf_text); + + mutex_lock(&irq_ptr->setup_mutex); + qdio_setup_irq(init_data); + + rc = qdio_establish_thinint(irq_ptr); + if (rc) { + mutex_unlock(&irq_ptr->setup_mutex); + qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); + return rc; + } + + /* establish q */ + irq_ptr->ccw.cmd_code = irq_ptr->equeue.cmd; + irq_ptr->ccw.flags = CCW_FLAG_SLI; + irq_ptr->ccw.count = irq_ptr->equeue.count; + irq_ptr->ccw.cda = (u32)((addr_t)irq_ptr->qdr); + + spin_lock_irqsave(get_ccwdev_lock(cdev), saveflags); + ccw_device_set_options_mask(cdev, 0); + + rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ESTABLISH, 0, 0); + if (rc) { + sprintf(dbf_text, "eq:io%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT2(1, setup, dbf_text); + sprintf(dbf_text, "eq:rc%4x", rc); + QDIO_DBF_TEXT2(1, setup, dbf_text); + } + spin_unlock_irqrestore(get_ccwdev_lock(cdev), saveflags); + + if (rc) { + mutex_unlock(&irq_ptr->setup_mutex); + qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); + return rc; + } + + wait_event_interruptible_timeout(cdev->private->wait_q, + irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || + irq_ptr->state == QDIO_IRQ_STATE_ERR, HZ); + + if (irq_ptr->state != QDIO_IRQ_STATE_ESTABLISHED) { + mutex_unlock(&irq_ptr->setup_mutex); + qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); + return -EIO; + } + + qdio_setup_ssqd_info(irq_ptr); + sprintf(dbf_text, "qib ac%2x", irq_ptr->qib.ac); + QDIO_DBF_TEXT2(0, setup, dbf_text); + + /* qebsm is now setup if available, initialize buffer states */ + qdio_init_buf_states(irq_ptr); + + mutex_unlock(&irq_ptr->setup_mutex); + qdio_print_subchannel_info(irq_ptr, cdev); + qdio_setup_debug_entries(irq_ptr, cdev); + return 0; +} +EXPORT_SYMBOL_GPL(qdio_establish); + +/** + * qdio_activate - activate queues on a qdio subchannel + * @cdev: associated cdev + */ +int qdio_activate(struct ccw_device *cdev) +{ + struct qdio_irq *irq_ptr; + int rc; + unsigned long saveflags; + char dbf_text[20]; + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return -ENODEV; + + if (cdev->private->state != DEV_STATE_ONLINE) + return -EINVAL; + + mutex_lock(&irq_ptr->setup_mutex); + if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) { + rc = -EBUSY; + goto out; + } + + sprintf(dbf_text, "qact%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT2(0, setup, dbf_text); + QDIO_DBF_TEXT2(0, trace, dbf_text); + + irq_ptr->ccw.cmd_code = irq_ptr->aqueue.cmd; + irq_ptr->ccw.flags = CCW_FLAG_SLI; + irq_ptr->ccw.count = irq_ptr->aqueue.count; + irq_ptr->ccw.cda = 0; + + spin_lock_irqsave(get_ccwdev_lock(cdev), saveflags); + ccw_device_set_options(cdev, CCWDEV_REPORT_ALL); + + rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ACTIVATE, + 0, DOIO_DENY_PREFETCH); + if (rc) { + sprintf(dbf_text, "aq:io%4x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT2(1, setup, dbf_text); + sprintf(dbf_text, "aq:rc%4x", rc); + QDIO_DBF_TEXT2(1, setup, dbf_text); + } + spin_unlock_irqrestore(get_ccwdev_lock(cdev), saveflags); + + if (rc) + goto out; + + if (is_thinint_irq(irq_ptr)) + tiqdio_add_input_queues(irq_ptr); + + /* wait for subchannel to become active */ + msleep(5); + + switch (irq_ptr->state) { + case QDIO_IRQ_STATE_STOPPED: + case QDIO_IRQ_STATE_ERR: + mutex_unlock(&irq_ptr->setup_mutex); + qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); + return -EIO; + default: + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE); + rc = 0; + } +out: + mutex_unlock(&irq_ptr->setup_mutex); + return rc; +} +EXPORT_SYMBOL_GPL(qdio_activate); + +static inline int buf_in_between(int bufnr, int start, int count) +{ + int end = add_buf(start, count); + + if (end > start) { + if (bufnr >= start && bufnr < end) + return 1; + else + return 0; + } + + /* wrap-around case */ + if ((bufnr >= start && bufnr <= QDIO_MAX_BUFFERS_PER_Q) || + (bufnr < end)) + return 1; + else + return 0; +} + +/** + * handle_inbound - reset processed input buffers + * @q: queue containing the buffers + * @callflags: flags + * @bufnr: first buffer to process + * @count: how many buffers are emptied + */ +static void handle_inbound(struct qdio_q *q, unsigned int callflags, + int bufnr, int count) +{ + unsigned long flags; + int used, rc; + + /* + * do_QDIO could run in parallel with the queue tasklet so the + * upper-layer programm could empty the ACK'ed buffer here. + * If that happens we must clear the polling flag, otherwise + * qdio_stop_polling() could set the buffer to NOT_INIT after + * it was set to EMPTY which would kill us. + */ + spin_lock_irqsave(&q->u.in.lock, flags); + if (q->u.in.polling) + if (buf_in_between(q->last_move_ftc, bufnr, count)) + q->u.in.polling = 0; + + count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count); + spin_unlock_irqrestore(&q->u.in.lock, flags); + + used = atomic_add_return(count, &q->nr_buf_used) - count; + BUG_ON(used + count > QDIO_MAX_BUFFERS_PER_Q); + + /* no need to signal as long as the adapter had free buffers */ + if (used) + return; + + if (need_siga_in(q)) { + rc = qdio_siga_input(q); + if (rc) + q->qdio_error = rc; + } +} + +/** + * handle_outbound - process filled outbound buffers + * @q: queue containing the buffers + * @callflags: flags + * @bufnr: first buffer to process + * @count: how many buffers are filled + */ +static void handle_outbound(struct qdio_q *q, unsigned int callflags, + int bufnr, int count) +{ + unsigned char state; + int used; + + qdio_perf_stat_inc(&perf_stats.outbound_handler); + + count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); + used = atomic_add_return(count, &q->nr_buf_used); + BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); + + if (callflags & QDIO_FLAG_PCI_OUT) + q->u.out.pci_out_enabled = 1; + else + q->u.out.pci_out_enabled = 0; + + if (queue_type(q) == QDIO_IQDIO_QFMT) { + if (multicast_outbound(q)) + qdio_kick_outbound_q(q); + else + /* + * One siga-w per buffer required for unicast + * HiperSockets. + */ + while (count--) + qdio_kick_outbound_q(q); + goto out; + } + + if (need_siga_sync(q)) { + qdio_siga_sync_q(q); + goto out; + } + + /* try to fast requeue buffers */ + get_buf_state(q, prev_buf(bufnr), &state); + if (state != SLSB_CU_OUTPUT_PRIMED) + qdio_kick_outbound_q(q); + else { + QDIO_DBF_TEXT5(0, trace, "fast-req"); + qdio_perf_stat_inc(&perf_stats.fast_requeue); + } +out: + /* Fixme: could wait forever if called from process context */ + tasklet_schedule(&q->tasklet); +} + +/** + * do_QDIO - process input or output buffers + * @cdev: associated ccw_device for the qdio subchannel + * @callflags: input or output and special flags from the program + * @q_nr: queue number + * @bufnr: buffer number + * @count: how many buffers to process + */ +int do_QDIO(struct ccw_device *cdev, unsigned int callflags, + int q_nr, int bufnr, int count) +{ + struct qdio_irq *irq_ptr; +#ifdef CONFIG_QDIO_DEBUG + char dbf_text[20]; + + sprintf(dbf_text, "doQD%04x", cdev->private->schid.sch_no); + QDIO_DBF_TEXT3(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + + if ((bufnr > QDIO_MAX_BUFFERS_PER_Q) || + (count > QDIO_MAX_BUFFERS_PER_Q) || + (q_nr > QDIO_MAX_QUEUES_PER_IRQ)) + return -EINVAL; + + if (!count) + return 0; + + irq_ptr = cdev->private->qdio_data; + if (!irq_ptr) + return -ENODEV; + +#ifdef CONFIG_QDIO_DEBUG + if (callflags & QDIO_FLAG_SYNC_INPUT) + QDIO_DBF_HEX3(0, trace, &irq_ptr->input_qs[q_nr], + sizeof(void *)); + else + QDIO_DBF_HEX3(0, trace, &irq_ptr->output_qs[q_nr], + sizeof(void *)); + + sprintf(dbf_text, "flag%04x", callflags); + QDIO_DBF_TEXT3(0, trace, dbf_text); + sprintf(dbf_text, "qi%02xct%02x", bufnr, count); + QDIO_DBF_TEXT3(0, trace, dbf_text); +#endif /* CONFIG_QDIO_DEBUG */ + + if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) + return -EBUSY; + + if (callflags & QDIO_FLAG_SYNC_INPUT) + handle_inbound(irq_ptr->input_qs[q_nr], + callflags, bufnr, count); + else if (callflags & QDIO_FLAG_SYNC_OUTPUT) + handle_outbound(irq_ptr->output_qs[q_nr], + callflags, bufnr, count); + else { + QDIO_DBF_TEXT3(1, trace, "doQD:inv"); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL_GPL(do_QDIO); + +static int __init init_QDIO(void) +{ + int rc; + + rc = qdio_setup_init(); + if (rc) + return rc; + rc = tiqdio_allocate_memory(); + if (rc) + goto out_cache; + rc = qdio_debug_init(); + if (rc) + goto out_ti; + rc = qdio_setup_perf_stats(); + if (rc) + goto out_debug; + rc = tiqdio_register_thinints(); + if (rc) + goto out_perf; + return 0; + +out_perf: + qdio_remove_perf_stats(); +out_debug: + qdio_debug_exit(); +out_ti: + tiqdio_free_memory(); +out_cache: + qdio_setup_exit(); + return rc; +} + +static void __exit exit_QDIO(void) +{ + tiqdio_unregister_thinints(); + tiqdio_free_memory(); + qdio_remove_perf_stats(); + qdio_debug_exit(); + qdio_setup_exit(); +} + +module_init(init_QDIO); +module_exit(exit_QDIO); diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c new file mode 100644 index 0000000..ea01b85 --- /dev/null +++ b/drivers/s390/cio/qdio_perf.c @@ -0,0 +1,151 @@ +/* + * drivers/s390/cio/qdio_perf.c + * + * Copyright IBM Corp. 2008 + * + * Author: Jan Glauber (jang@linux.vnet.ibm.com) + */ +#include +#include +#include +#include + +#include "cio.h" +#include "css.h" +#include "device.h" +#include "ioasm.h" +#include "chsc.h" +#include "qdio_debug.h" +#include "qdio_perf.h" + +int qdio_performance_stats; +struct qdio_perf_stats perf_stats; + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *qdio_perf_pde; +#endif + +inline void qdio_perf_stat_inc(atomic_long_t *count) +{ + if (qdio_performance_stats) + atomic_long_inc(count); +} + +inline void qdio_perf_stat_dec(atomic_long_t *count) +{ + if (qdio_performance_stats) + atomic_long_dec(count); +} + +/* + * procfs functions + */ +static int qdio_perf_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.qdio_int)); + seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.pci_int)); + seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.thin_int)); + seq_printf(m, "\n"); + seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.tasklet_inbound)); + seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.tasklet_outbound)); + seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n", + (long)atomic_long_read(&perf_stats.tasklet_thinint), + (long)atomic_long_read(&perf_stats.tasklet_thinint_loop)); + seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n", + (long)atomic_long_read(&perf_stats.thinint_inbound), + (long)atomic_long_read(&perf_stats.thinint_inbound_loop)); + seq_printf(m, "\n"); + seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.siga_in)); + seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.siga_out)); + seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.siga_sync)); + seq_printf(m, "\n"); + seq_printf(m, "Number of inbound transfers\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.inbound_handler)); + seq_printf(m, "Number of outbound transfers\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.outbound_handler)); + seq_printf(m, "\n"); + seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n", + (long)atomic_long_read(&perf_stats.fast_requeue)); + seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", + (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); + seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", + (long)atomic_long_read(&perf_stats.debug_stop_polling)); + seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n", + (long)atomic_long_read(&perf_stats.thinint_inbound_loop2)); + seq_printf(m, "\n"); + return 0; +} +static int qdio_perf_seq_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, qdio_perf_proc_show, NULL); +} + +static struct file_operations qdio_perf_proc_fops = { + .owner = THIS_MODULE, + .open = qdio_perf_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * sysfs functions + */ +static ssize_t qdio_perf_stats_show(struct bus_type *bus, char *buf) +{ + return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); +} + +static ssize_t qdio_perf_stats_store(struct bus_type *bus, + const char *buf, size_t count) +{ + unsigned long i; + + if (strict_strtoul(buf, 16, &i) != 0) + return -EINVAL; + if ((i != 0) && (i != 1)) + return -EINVAL; + if (i == qdio_performance_stats) + return count; + + qdio_performance_stats = i; + /* reset performance statistics */ + if (i == 0) + memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); + return count; +} + +static BUS_ATTR(qdio_performance_stats, 0644, qdio_perf_stats_show, + qdio_perf_stats_store); + +int __init qdio_setup_perf_stats(void) +{ + int rc; + + rc = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); + if (rc) + return rc; + +#ifdef CONFIG_PROC_FS + memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); + qdio_perf_pde = proc_create("qdio_perf", S_IFREG | S_IRUGO, + NULL, &qdio_perf_proc_fops); +#endif + return 0; +} + +void __exit qdio_remove_perf_stats(void) +{ +#ifdef CONFIG_PROC_FS + remove_proc_entry("qdio_perf", NULL); +#endif + bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); +} diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h new file mode 100644 index 0000000..5c406a8 --- /dev/null +++ b/drivers/s390/cio/qdio_perf.h @@ -0,0 +1,54 @@ +/* + * drivers/s390/cio/qdio_perf.h + * + * Copyright IBM Corp. 2008 + * + * Author: Jan Glauber (jang@linux.vnet.ibm.com) + */ +#ifndef QDIO_PERF_H +#define QDIO_PERF_H + +#include +#include +#include + +struct qdio_perf_stats { + /* interrupt handler calls */ + atomic_long_t qdio_int; + atomic_long_t pci_int; + atomic_long_t thin_int; + + /* tasklet runs */ + atomic_long_t tasklet_inbound; + atomic_long_t tasklet_outbound; + atomic_long_t tasklet_thinint; + atomic_long_t tasklet_thinint_loop; + atomic_long_t thinint_inbound; + atomic_long_t thinint_inbound_loop; + atomic_long_t thinint_inbound_loop2; + + /* signal adapter calls */ + atomic_long_t siga_out; + atomic_long_t siga_in; + atomic_long_t siga_sync; + + /* misc */ + atomic_long_t inbound_handler; + atomic_long_t outbound_handler; + atomic_long_t fast_requeue; + + /* for debugging */ + atomic_long_t debug_tl_out_timer; + atomic_long_t debug_stop_polling; +}; + +extern struct qdio_perf_stats perf_stats; +extern int qdio_performance_stats; + +int qdio_setup_perf_stats(void); +void qdio_remove_perf_stats(void); + +extern void qdio_perf_stat_inc(atomic_long_t *count); +extern void qdio_perf_stat_dec(atomic_long_t *count); + +#endif diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c new file mode 100644 index 0000000..f0923a8 --- /dev/null +++ b/drivers/s390/cio/qdio_setup.c @@ -0,0 +1,521 @@ +/* + * driver/s390/cio/qdio_setup.c + * + * qdio queue initialization + * + * Copyright (C) IBM Corp. 2008 + * Author(s): Jan Glauber + */ +#include +#include +#include + +#include "cio.h" +#include "css.h" +#include "device.h" +#include "ioasm.h" +#include "chsc.h" +#include "qdio.h" +#include "qdio_debug.h" + +static struct kmem_cache *qdio_q_cache; + +/* + * qebsm is only available under 64bit but the adapter sets the feature + * flag anyway, so we manually override it. + */ +static inline int qebsm_possible(void) +{ +#ifdef CONFIG_64BIT + return css_general_characteristics.qebsm; +#endif + return 0; +} + +/* + * qib_param_field: pointer to 128 bytes or NULL, if no param field + * nr_input_qs: pointer to nr_queues*128 words of data or NULL + */ +static void set_impl_params(struct qdio_irq *irq_ptr, + unsigned int qib_param_field_format, + unsigned char *qib_param_field, + unsigned long *input_slib_elements, + unsigned long *output_slib_elements) +{ + struct qdio_q *q; + int i, j; + + if (!irq_ptr) + return; + + WARN_ON((unsigned long)&irq_ptr->qib & 0xff); + irq_ptr->qib.pfmt = qib_param_field_format; + if (qib_param_field) + memcpy(irq_ptr->qib.parm, qib_param_field, + QDIO_MAX_BUFFERS_PER_Q); + + if (!input_slib_elements) + goto output; + + for_each_input_queue(irq_ptr, q, i) { + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) + q->slib->slibe[j].parms = + input_slib_elements[i * QDIO_MAX_BUFFERS_PER_Q + j]; + } +output: + if (!output_slib_elements) + return; + + for_each_output_queue(irq_ptr, q, i) { + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) + q->slib->slibe[j].parms = + output_slib_elements[i * QDIO_MAX_BUFFERS_PER_Q + j]; + } +} + +static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) +{ + struct qdio_q *q; + int i; + + for (i = 0; i < nr_queues; i++) { + q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); + if (!q) + return -ENOMEM; + WARN_ON((unsigned long)q & 0xff); + + q->slib = (struct slib *) __get_free_page(GFP_KERNEL); + if (!q->slib) { + kmem_cache_free(qdio_q_cache, q); + return -ENOMEM; + } + WARN_ON((unsigned long)q->slib & 0x7ff); + irq_ptr_qs[i] = q; + } + return 0; +} + +int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, int nr_output_qs) +{ + int rc; + + rc = __qdio_allocate_qs(irq_ptr->input_qs, nr_input_qs); + if (rc) + return rc; + rc = __qdio_allocate_qs(irq_ptr->output_qs, nr_output_qs); + return rc; +} + +static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr, + qdio_handler_t *handler, int i) +{ + /* must be cleared by every qdio_establish */ + memset(q, 0, ((char *)&q->slib) - ((char *)q)); + memset(q->slib, 0, PAGE_SIZE); + + q->irq_ptr = irq_ptr; + q->mask = 1 << (31 - i); + q->nr = i; + q->handler = handler; +} + +static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, + void **sbals_array, char *dbf_text, int i) +{ + struct qdio_q *prev; + int j; + + QDIO_DBF_TEXT0(0, setup, dbf_text); + QDIO_DBF_HEX0(0, setup, &q, sizeof(void *)); + + q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2); + + /* fill in sbal */ + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { + q->sbal[j] = *sbals_array++; + WARN_ON((unsigned long)q->sbal[j] & 0xff); + } + + /* fill in slib */ + if (i > 0) { + prev = (q->is_input_q) ? irq_ptr->input_qs[i - 1] + : irq_ptr->output_qs[i - 1]; + prev->slib->nsliba = (unsigned long)q->slib; + } + + q->slib->sla = (unsigned long)q->sl; + q->slib->slsba = (unsigned long)&q->slsb.val[0]; + + /* fill in sl */ + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) + q->sl->element[j].sbal = (unsigned long)q->sbal[j]; + + QDIO_DBF_TEXT2(0, setup, "sl-sb-b0"); + QDIO_DBF_HEX2(0, setup, q->sl, sizeof(void *)); + QDIO_DBF_HEX2(0, setup, &q->slsb, sizeof(void *)); + QDIO_DBF_HEX2(0, setup, q->sbal, sizeof(void *)); +} + +static void setup_queues(struct qdio_irq *irq_ptr, + struct qdio_initialize *qdio_init) +{ + char dbf_text[20]; + struct qdio_q *q; + void **input_sbal_array = qdio_init->input_sbal_addr_array; + void **output_sbal_array = qdio_init->output_sbal_addr_array; + int i; + + sprintf(dbf_text, "qfqs%4x", qdio_init->cdev->private->schid.sch_no); + QDIO_DBF_TEXT0(0, setup, dbf_text); + + for_each_input_queue(irq_ptr, q, i) { + sprintf(dbf_text, "in-q%4x", i); + setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); + + q->is_input_q = 1; + spin_lock_init(&q->u.in.lock); + setup_storage_lists(q, irq_ptr, input_sbal_array, dbf_text, i); + input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; + + if (is_thinint_irq(irq_ptr)) + tasklet_init(&q->tasklet, tiqdio_inbound_processing, + (unsigned long) q); + else + tasklet_init(&q->tasklet, qdio_inbound_processing, + (unsigned long) q); + } + + for_each_output_queue(irq_ptr, q, i) { + sprintf(dbf_text, "outq%4x", i); + setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i); + + q->is_input_q = 0; + setup_storage_lists(q, irq_ptr, output_sbal_array, + dbf_text, i); + output_sbal_array += QDIO_MAX_BUFFERS_PER_Q; + + tasklet_init(&q->tasklet, qdio_outbound_processing, + (unsigned long) q); + setup_timer(&q->u.out.timer, (void(*)(unsigned long)) + &qdio_outbound_timer, (unsigned long)q); + } +} + +static void process_ac_flags(struct qdio_irq *irq_ptr, unsigned char qdioac) +{ + if (qdioac & AC1_SIGA_INPUT_NEEDED) + irq_ptr->siga_flag.input = 1; + if (qdioac & AC1_SIGA_OUTPUT_NEEDED) + irq_ptr->siga_flag.output = 1; + if (qdioac & AC1_SIGA_SYNC_NEEDED) + irq_ptr->siga_flag.sync = 1; + if (qdioac & AC1_AUTOMATIC_SYNC_ON_THININT) + irq_ptr->siga_flag.no_sync_ti = 1; + if (qdioac & AC1_AUTOMATIC_SYNC_ON_OUT_PCI) + irq_ptr->siga_flag.no_sync_out_pci = 1; + + if (irq_ptr->siga_flag.no_sync_out_pci && + irq_ptr->siga_flag.no_sync_ti) + irq_ptr->siga_flag.no_sync_out_ti = 1; +} + +static void check_and_setup_qebsm(struct qdio_irq *irq_ptr, + unsigned char qdioac, unsigned long token) +{ + char dbf_text[15]; + + if (!(irq_ptr->qib.rflags & QIB_RFLAGS_ENABLE_QEBSM)) + goto no_qebsm; + if (!(qdioac & AC1_SC_QEBSM_AVAILABLE) || + (!(qdioac & AC1_SC_QEBSM_ENABLED))) + goto no_qebsm; + + irq_ptr->sch_token = token; + + QDIO_DBF_TEXT0(0, setup, "V=V:1"); + sprintf(dbf_text, "%8lx", irq_ptr->sch_token); + QDIO_DBF_TEXT0(0, setup, dbf_text); + return; + +no_qebsm: + irq_ptr->sch_token = 0; + irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM; + QDIO_DBF_TEXT0(0, setup, "noV=V"); +} + +static int __get_ssqd_info(struct qdio_irq *irq_ptr) +{ + struct chsc_ssqd_area *ssqd; + int rc; + + QDIO_DBF_TEXT0(0, setup, "getssqd"); + ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page; + memset(ssqd, 0, PAGE_SIZE); + + ssqd->request = (struct chsc_header) { + .length = 0x0010, + .code = 0x0024, + }; + ssqd->first_sch = irq_ptr->schid.sch_no; + ssqd->last_sch = irq_ptr->schid.sch_no; + ssqd->ssid = irq_ptr->schid.ssid; + + if (chsc(ssqd)) + return -EIO; + rc = chsc_error_from_response(ssqd->response.code); + if (rc) + return rc; + + if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) || + !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) || + (ssqd->qdio_ssqd.sch != irq_ptr->schid.sch_no)) + return -EINVAL; + + memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd, + sizeof(struct qdio_ssqd_desc)); + return 0; +} + +void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr) +{ + unsigned char qdioac; + char dbf_text[15]; + int rc; + + rc = __get_ssqd_info(irq_ptr); + if (rc) { + QDIO_DBF_TEXT2(0, setup, "ssqdasig"); + sprintf(dbf_text, "schno%x", irq_ptr->schid.sch_no); + QDIO_DBF_TEXT2(0, setup, dbf_text); + sprintf(dbf_text, "rc:%d", rc); + QDIO_DBF_TEXT2(0, setup, dbf_text); + /* all flags set, worst case */ + qdioac = AC1_SIGA_INPUT_NEEDED | AC1_SIGA_OUTPUT_NEEDED | + AC1_SIGA_SYNC_NEEDED; + } else + qdioac = irq_ptr->ssqd_desc.qdioac1; + + check_and_setup_qebsm(irq_ptr, qdioac, irq_ptr->ssqd_desc.sch_token); + process_ac_flags(irq_ptr, qdioac); + + sprintf(dbf_text, "qdioac%2x", qdioac); + QDIO_DBF_TEXT2(0, setup, dbf_text); +} + +void qdio_release_memory(struct qdio_irq *irq_ptr) +{ + struct qdio_q *q; + int i; + + /* + * Must check queue array manually since irq_ptr->nr_input_queues / + * irq_ptr->nr_input_queues may not yet be set. + */ + for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) { + q = irq_ptr->input_qs[i]; + if (q) { + free_page((unsigned long) q->slib); + kmem_cache_free(qdio_q_cache, q); + } + } + for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) { + q = irq_ptr->output_qs[i]; + if (q) { + free_page((unsigned long) q->slib); + kmem_cache_free(qdio_q_cache, q); + } + } + kfree(irq_ptr->qdr); + free_page(irq_ptr->chsc_page); + free_page((unsigned long) irq_ptr); +} + +static void __qdio_allocate_fill_qdr(struct qdio_irq *irq_ptr, + struct qdio_q **irq_ptr_qs, + int i, int nr) +{ + irq_ptr->qdr->qdf0[i + nr].sliba = + (unsigned long)irq_ptr_qs[i]->slib; + + irq_ptr->qdr->qdf0[i + nr].sla = + (unsigned long)irq_ptr_qs[i]->sl; + + irq_ptr->qdr->qdf0[i + nr].slsba = + (unsigned long)&irq_ptr_qs[i]->slsb.val[0]; + + irq_ptr->qdr->qdf0[i + nr].akey = PAGE_DEFAULT_KEY; + irq_ptr->qdr->qdf0[i + nr].bkey = PAGE_DEFAULT_KEY; + irq_ptr->qdr->qdf0[i + nr].ckey = PAGE_DEFAULT_KEY; + irq_ptr->qdr->qdf0[i + nr].dkey = PAGE_DEFAULT_KEY; +} + +static void setup_qdr(struct qdio_irq *irq_ptr, + struct qdio_initialize *qdio_init) +{ + int i; + + irq_ptr->qdr->qfmt = qdio_init->q_format; + irq_ptr->qdr->iqdcnt = qdio_init->no_input_qs; + irq_ptr->qdr->oqdcnt = qdio_init->no_output_qs; + irq_ptr->qdr->iqdsz = sizeof(struct qdesfmt0) / 4; /* size in words */ + irq_ptr->qdr->oqdsz = sizeof(struct qdesfmt0) / 4; + irq_ptr->qdr->qiba = (unsigned long)&irq_ptr->qib; + irq_ptr->qdr->qkey = PAGE_DEFAULT_KEY; + + for (i = 0; i < qdio_init->no_input_qs; i++) + __qdio_allocate_fill_qdr(irq_ptr, irq_ptr->input_qs, i, 0); + + for (i = 0; i < qdio_init->no_output_qs; i++) + __qdio_allocate_fill_qdr(irq_ptr, irq_ptr->output_qs, i, + qdio_init->no_input_qs); +} + +static void setup_qib(struct qdio_irq *irq_ptr, + struct qdio_initialize *init_data) +{ + if (qebsm_possible()) + irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM; + + irq_ptr->qib.qfmt = init_data->q_format; + if (init_data->no_input_qs) + irq_ptr->qib.isliba = + (unsigned long)(irq_ptr->input_qs[0]->slib); + if (init_data->no_output_qs) + irq_ptr->qib.osliba = + (unsigned long)(irq_ptr->output_qs[0]->slib); + memcpy(irq_ptr->qib.ebcnam, init_data->adapter_name, 8); +} + +int qdio_setup_irq(struct qdio_initialize *init_data) +{ + struct ciw *ciw; + struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data; + int rc; + + memset(irq_ptr, 0, ((char *)&irq_ptr->qdr) - ((char *)irq_ptr)); + /* wipes qib.ac, required by ar7063 */ + memset(irq_ptr->qdr, 0, sizeof(struct qdr)); + + irq_ptr->int_parm = init_data->int_parm; + irq_ptr->nr_input_qs = init_data->no_input_qs; + irq_ptr->nr_output_qs = init_data->no_output_qs; + + irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev); + irq_ptr->cdev = init_data->cdev; + setup_queues(irq_ptr, init_data); + + setup_qib(irq_ptr, init_data); + qdio_setup_thinint(irq_ptr); + set_impl_params(irq_ptr, init_data->qib_param_field_format, + init_data->qib_param_field, + init_data->input_slib_elements, + init_data->output_slib_elements); + + /* fill input and output descriptors */ + setup_qdr(irq_ptr, init_data); + + /* qdr, qib, sls, slsbs, slibs, sbales are filled now */ + + /* get qdio commands */ + ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE); + if (!ciw) { + QDIO_DBF_TEXT2(1, setup, "no eq"); + rc = -EINVAL; + goto out_err; + } + irq_ptr->equeue = *ciw; + + ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE); + if (!ciw) { + QDIO_DBF_TEXT2(1, setup, "no aq"); + rc = -EINVAL; + goto out_err; + } + irq_ptr->aqueue = *ciw; + + /* set new interrupt handler */ + irq_ptr->orig_handler = init_data->cdev->handler; + init_data->cdev->handler = qdio_int_handler; + return 0; +out_err: + qdio_release_memory(irq_ptr); + return rc; +} + +void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, + struct ccw_device *cdev) +{ + char s[80]; + + sprintf(s, "%s ", cdev->dev.bus_id); + + switch (irq_ptr->qib.qfmt) { + case QDIO_QETH_QFMT: + sprintf(s + strlen(s), "OSADE "); + break; + case QDIO_ZFCP_QFMT: + sprintf(s + strlen(s), "ZFCP "); + break; + case QDIO_IQDIO_QFMT: + sprintf(s + strlen(s), "HiperSockets "); + break; + } + sprintf(s + strlen(s), "using: "); + + if (!is_thinint_irq(irq_ptr)) + sprintf(s + strlen(s), "no"); + sprintf(s + strlen(s), "AdapterInterrupts "); + if (!(irq_ptr->sch_token != 0)) + sprintf(s + strlen(s), "no"); + sprintf(s + strlen(s), "QEBSM "); + if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) + sprintf(s + strlen(s), "no"); + sprintf(s + strlen(s), "OutboundPCI "); + if (!css_general_characteristics.aif_tdd) + sprintf(s + strlen(s), "no"); + sprintf(s + strlen(s), "TDD\n"); + printk(KERN_INFO "qdio: %s", s); + + memset(s, 0, sizeof(s)); + sprintf(s, "%s SIGA required: ", cdev->dev.bus_id); + if (irq_ptr->siga_flag.input) + sprintf(s + strlen(s), "Read "); + if (irq_ptr->siga_flag.output) + sprintf(s + strlen(s), "Write "); + if (irq_ptr->siga_flag.sync) + sprintf(s + strlen(s), "Sync "); + if (!irq_ptr->siga_flag.no_sync_ti) + sprintf(s + strlen(s), "SyncAI "); + if (!irq_ptr->siga_flag.no_sync_out_ti) + sprintf(s + strlen(s), "SyncOutAI "); + if (!irq_ptr->siga_flag.no_sync_out_pci) + sprintf(s + strlen(s), "SyncOutPCI"); + sprintf(s + strlen(s), "\n"); + printk(KERN_INFO "qdio: %s", s); +} + +int __init qdio_setup_init(void) +{ + char dbf_text[15]; + + qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q), + 256, 0, NULL); + if (!qdio_q_cache) + return -ENOMEM; + + /* Check for OSA/FCP thin interrupts (bit 67). */ + sprintf(dbf_text, "thini%1x", + (css_general_characteristics.aif_osa) ? 1 : 0); + QDIO_DBF_TEXT0(0, setup, dbf_text); + + /* Check for QEBSM support in general (bit 58). */ + sprintf(dbf_text, "cssQBS:%1x", + (qebsm_possible()) ? 1 : 0); + QDIO_DBF_TEXT0(0, setup, dbf_text); + return 0; +} + +void __exit qdio_setup_exit(void) +{ + kmem_cache_destroy(qdio_q_cache); +} diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c new file mode 100644 index 0000000..9291a77 --- /dev/null +++ b/drivers/s390/cio/qdio_thinint.c @@ -0,0 +1,380 @@ +/* + * linux/drivers/s390/cio/thinint_qdio.c + * + * thin interrupt support for qdio + * + * Copyright 2000-2008 IBM Corp. + * Author(s): Utz Bacher + * Cornelia Huck + * Jan Glauber + */ +#include +#include +#include +#include +#include +#include + +#include "cio.h" +#include "ioasm.h" +#include "qdio.h" +#include "qdio_debug.h" +#include "qdio_perf.h" + +/* + * Restriction: only 63 iqdio subchannels would have its own indicator, + * after that, subsequent subchannels share one indicator + */ +#define TIQDIO_NR_NONSHARED_IND 63 +#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) +#define TIQDIO_SHARED_IND 63 + +/* list of thin interrupt input queues */ +static LIST_HEAD(tiq_list); + +/* adapter local summary indicator */ +static unsigned char *tiqdio_alsi; + +/* device state change indicators */ +struct indicator_t { + u32 ind; /* u32 because of compare-and-swap performance */ + atomic_t count; /* use count, 0 or 1 for non-shared indicators */ +}; +static struct indicator_t *q_indicators; + +static void tiqdio_tasklet_fn(unsigned long data); +static DECLARE_TASKLET(tiqdio_tasklet, tiqdio_tasklet_fn, 0); + +static int css_qdio_omit_svs; + +static inline unsigned long do_clear_global_summary(void) +{ + register unsigned long __fn asm("1") = 3; + register unsigned long __tmp asm("2"); + register unsigned long __time asm("3"); + + asm volatile( + " .insn rre,0xb2650000,2,0" + : "+d" (__fn), "=d" (__tmp), "=d" (__time)); + return __time; +} + +/* returns addr for the device state change indicator */ +static u32 *get_indicator(void) +{ + int i; + + for (i = 0; i < TIQDIO_NR_NONSHARED_IND; i++) + if (!atomic_read(&q_indicators[i].count)) { + atomic_set(&q_indicators[i].count, 1); + return &q_indicators[i].ind; + } + + /* use the shared indicator */ + atomic_inc(&q_indicators[TIQDIO_SHARED_IND].count); + return &q_indicators[TIQDIO_SHARED_IND].ind; +} + +static void put_indicator(u32 *addr) +{ + int i; + + if (!addr) + return; + i = ((unsigned long)addr - (unsigned long)q_indicators) / + sizeof(struct indicator_t); + atomic_dec(&q_indicators[i].count); +} + +void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) +{ + struct qdio_q *q; + int i; + + /* No TDD facility? If we must use SIGA-s we can also omit SVS. */ + if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync) + css_qdio_omit_svs = 1; + + for_each_input_queue(irq_ptr, q, i) { + list_add_rcu(&q->entry, &tiq_list); + synchronize_rcu(); + } + xchg(irq_ptr->dsci, 1); + tasklet_schedule(&tiqdio_tasklet); +} + +/* + * we cannot stop the tiqdio tasklet here since it is for all + * thinint qdio devices and it must run as long as there is a + * thinint device left + */ +void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) +{ + struct qdio_q *q; + int i; + + for_each_input_queue(irq_ptr, q, i) { + list_del_rcu(&q->entry); + synchronize_rcu(); + } +} + +static inline int tiqdio_inbound_q_done(struct qdio_q *q) +{ + unsigned char state; + + if (!atomic_read(&q->nr_buf_used)) + return 1; + + qdio_siga_sync_q(q); + get_buf_state(q, q->first_to_check, &state); + + if (state == SLSB_P_INPUT_PRIMED) + /* more work coming */ + return 0; + return 1; +} + +static inline int shared_ind(struct qdio_irq *irq_ptr) +{ + return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; +} + +static void __tiqdio_inbound_processing(struct qdio_q *q) +{ + qdio_perf_stat_inc(&perf_stats.thinint_inbound); + qdio_sync_after_thinint(q); + + /* + * Maybe we have work on our outbound queues... at least + * we have to check the PCI capable queues. + */ + qdio_check_outbound_after_thinint(q); + +again: + if (!qdio_inbound_q_moved(q)) + return; + + qdio_kick_inbound_handler(q); + + if (!tiqdio_inbound_q_done(q)) { + qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop); + goto again; + } + + qdio_stop_polling(q); + /* + * We need to check again to not lose initiative after + * resetting the ACK state. + */ + if (!tiqdio_inbound_q_done(q)) { + qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2); + goto again; + } +} + +void tiqdio_inbound_processing(unsigned long data) +{ + struct qdio_q *q = (struct qdio_q *)data; + + __tiqdio_inbound_processing(q); +} + +/* check for work on all inbound thinint queues */ +static void tiqdio_tasklet_fn(unsigned long data) +{ + struct qdio_q *q; + + qdio_perf_stat_inc(&perf_stats.tasklet_thinint); +again: + + /* protect tiq_list entries, only changed in activate or shutdown */ + rcu_read_lock(); + + list_for_each_entry_rcu(q, &tiq_list, entry) + /* only process queues from changed sets */ + if (*q->irq_ptr->dsci) { + + /* only clear it if the indicator is non-shared */ + if (!shared_ind(q->irq_ptr)) + xchg(q->irq_ptr->dsci, 0); + /* + * don't call inbound processing directly since + * that could starve other thinint queues + */ + tasklet_schedule(&q->tasklet); + } + + rcu_read_unlock(); + + /* + * if we used the shared indicator clear it now after all queues + * were processed + */ + if (atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) { + xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); + + /* prevent racing */ + if (*tiqdio_alsi) + xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 1); + } + + /* check for more work */ + if (*tiqdio_alsi) { + xchg(tiqdio_alsi, 0); + qdio_perf_stat_inc(&perf_stats.tasklet_thinint_loop); + goto again; + } +} + +/** + * tiqdio_thinint_handler - thin interrupt handler for qdio + * @ind: pointer to adapter local summary indicator + * @drv_data: NULL + */ +static void tiqdio_thinint_handler(void *ind, void *drv_data) +{ + qdio_perf_stat_inc(&perf_stats.thin_int); + + /* + * SVS only when needed: issue SVS to benefit from iqdio interrupt + * avoidance (SVS clears adapter interrupt suppression overwrite) + */ + if (!css_qdio_omit_svs) + do_clear_global_summary(); + + /* + * reset local summary indicator (tiqdio_alsi) to stop adapter + * interrupts for now, the tasklet will clean all dsci's + */ + xchg((u8 *)ind, 0); + tasklet_hi_schedule(&tiqdio_tasklet); +} + +static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) +{ + struct scssc_area *scssc_area; + char dbf_text[15]; + void *ptr; + int rc; + + scssc_area = (struct scssc_area *)irq_ptr->chsc_page; + memset(scssc_area, 0, PAGE_SIZE); + + if (reset) { + scssc_area->summary_indicator_addr = 0; + scssc_area->subchannel_indicator_addr = 0; + } else { + scssc_area->summary_indicator_addr = virt_to_phys(tiqdio_alsi); + scssc_area->subchannel_indicator_addr = + virt_to_phys(irq_ptr->dsci); + } + + scssc_area->request = (struct chsc_header) { + .length = 0x0fe0, + .code = 0x0021, + }; + scssc_area->operation_code = 0; + scssc_area->ks = PAGE_DEFAULT_KEY; + scssc_area->kc = PAGE_DEFAULT_KEY; + scssc_area->isc = QDIO_AIRQ_ISC; + scssc_area->schid = irq_ptr->schid; + + /* enable the time delay disablement facility */ + if (css_general_characteristics.aif_tdd) + scssc_area->word_with_d_bit = 0x10000000; + + rc = chsc(scssc_area); + if (rc) + return -EIO; + + rc = chsc_error_from_response(scssc_area->response.code); + if (rc) { + sprintf(dbf_text, "sidR%4x", scssc_area->response.code); + QDIO_DBF_TEXT1(0, trace, dbf_text); + QDIO_DBF_TEXT1(0, setup, dbf_text); + ptr = &scssc_area->response; + QDIO_DBF_HEX2(1, setup, &ptr, QDIO_DBF_SETUP_LEN); + return rc; + } + + QDIO_DBF_TEXT2(0, setup, "setscind"); + QDIO_DBF_HEX2(0, setup, &scssc_area->summary_indicator_addr, + sizeof(unsigned long)); + QDIO_DBF_HEX2(0, setup, &scssc_area->subchannel_indicator_addr, + sizeof(unsigned long)); + return 0; +} + +/* allocate non-shared indicators and shared indicator */ +int __init tiqdio_allocate_memory(void) +{ + q_indicators = kzalloc(sizeof(struct indicator_t) * TIQDIO_NR_INDICATORS, + GFP_KERNEL); + if (!q_indicators) + return -ENOMEM; + return 0; +} + +void tiqdio_free_memory(void) +{ + kfree(q_indicators); +} + +int __init tiqdio_register_thinints(void) +{ + char dbf_text[20]; + + isc_register(QDIO_AIRQ_ISC); + tiqdio_alsi = s390_register_adapter_interrupt(&tiqdio_thinint_handler, + NULL, QDIO_AIRQ_ISC); + if (IS_ERR(tiqdio_alsi)) { + sprintf(dbf_text, "regthn%lx", PTR_ERR(tiqdio_alsi)); + QDIO_DBF_TEXT0(0, setup, dbf_text); + tiqdio_alsi = NULL; + isc_unregister(QDIO_AIRQ_ISC); + return -ENOMEM; + } + return 0; +} + +int qdio_establish_thinint(struct qdio_irq *irq_ptr) +{ + if (!is_thinint_irq(irq_ptr)) + return 0; + + /* Check for aif time delay disablement. If installed, + * omit SVS even under LPAR + */ + if (css_general_characteristics.aif_tdd) + css_qdio_omit_svs = 1; + return set_subchannel_ind(irq_ptr, 0); +} + +void qdio_setup_thinint(struct qdio_irq *irq_ptr) +{ + if (!is_thinint_irq(irq_ptr)) + return; + irq_ptr->dsci = get_indicator(); + QDIO_DBF_HEX1(0, setup, &irq_ptr->dsci, sizeof(void *)); +} + +void qdio_shutdown_thinint(struct qdio_irq *irq_ptr) +{ + if (!is_thinint_irq(irq_ptr)) + return; + + /* reset adapter interrupt indicators */ + put_indicator(irq_ptr->dsci); + set_subchannel_ind(irq_ptr, 1); +} + +void __exit tiqdio_unregister_thinints(void) +{ + tasklet_disable(&tiqdio_tasklet); + + if (tiqdio_alsi) { + s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC); + isc_unregister(QDIO_AIRQ_ISC); + } +} diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 699ac11..1895dbb 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -239,11 +239,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, /*not used unless the microcode gets patched*/ #define QETH_PCI_TIMER_VALUE(card) 3 -#define QETH_MIN_INPUT_THRESHOLD 1 -#define QETH_MAX_INPUT_THRESHOLD 500 -#define QETH_MIN_OUTPUT_THRESHOLD 1 -#define QETH_MAX_OUTPUT_THRESHOLD 300 - /* priority queing */ #define QETH_PRIOQ_DEFAULT QETH_NO_PRIO_QUEUEING #define QETH_DEFAULT_QUEUE 2 @@ -811,17 +806,14 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, enum qeth_ipa_cmds, enum qeth_prot_versions); int qeth_query_setadapterparms(struct qeth_card *); -int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, - unsigned int, const char *); +int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, const char *); void qeth_queue_input_buffer(struct qeth_card *, int); struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qdio_buffer *, struct qdio_buffer_element **, int *, struct qeth_hdr **); void qeth_schedule_recovery(struct qeth_card *); void qeth_qdio_output_handler(struct ccw_device *, unsigned int, - unsigned int, unsigned int, - unsigned int, int, int, - unsigned long); + int, int, int, unsigned long); void qeth_clear_ipacmd_list(struct qeth_card *); int qeth_qdio_clear_card(struct qeth_card *, int); void qeth_clear_working_pool_list(struct qeth_card *); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 0ac54dc..c3ad89e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2073,7 +2073,7 @@ static void qeth_create_qib_param_field_blkt(struct qeth_card *card, static int qeth_qdio_activate(struct qeth_card *card) { QETH_DBF_TEXT(SETUP, 3, "qdioact"); - return qdio_activate(CARD_DDEV(card), 0); + return qdio_activate(CARD_DDEV(card)); } static int qeth_dm_act(struct qeth_card *card) @@ -2349,16 +2349,11 @@ int qeth_init_qdio_queues(struct qeth_card *card) card->qdio.in_q->next_buf_to_init = card->qdio.in_buf_pool.buf_count - 1; rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, - card->qdio.in_buf_pool.buf_count - 1, NULL); + card->qdio.in_buf_pool.buf_count - 1); if (rc) { QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); return rc; } - rc = qdio_synchronize(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0); - if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); - return rc; - } /* outbound queue */ for (i = 0; i < card->qdio.no_out_queues; ++i) { memset(card->qdio.out_qs[i]->qdio_bufs, 0, @@ -2559,9 +2554,9 @@ int qeth_query_setadapterparms(struct qeth_card *card) EXPORT_SYMBOL_GPL(qeth_query_setadapterparms); int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, - unsigned int siga_error, const char *dbftext) + const char *dbftext) { - if (qdio_error || siga_error) { + if (qdio_error) { QETH_DBF_TEXT(TRACE, 2, dbftext); QETH_DBF_TEXT(QERR, 2, dbftext); QETH_DBF_TEXT_(QERR, 2, " F15=%02X", @@ -2569,7 +2564,6 @@ int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, QETH_DBF_TEXT_(QERR, 2, " F14=%02X", buf->element[14].flags & 0xff); QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error); - QETH_DBF_TEXT_(QERR, 2, " serr=%X", siga_error); return 1; } return 0; @@ -2622,9 +2616,8 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) card->perf_stats.inbound_do_qdio_start_time = qeth_get_micros(); } - rc = do_QDIO(CARD_DDEV(card), - QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, - 0, queue->next_buf_to_init, count, NULL); + rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, + queue->next_buf_to_init, count); if (card->options.performance_stats) card->perf_stats.inbound_do_qdio_time += qeth_get_micros() - @@ -2643,14 +2636,13 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) EXPORT_SYMBOL_GPL(qeth_queue_input_buffer); static int qeth_handle_send_error(struct qeth_card *card, - struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err, - unsigned int siga_err) + struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err) { int sbalf15 = buffer->buffer->element[15].flags & 0xff; - int cc = siga_err & 3; + int cc = qdio_err & 3; QETH_DBF_TEXT(TRACE, 6, "hdsnderr"); - qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr"); + qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr"); switch (cc) { case 0: if (qdio_err) { @@ -2662,7 +2654,7 @@ static int qeth_handle_send_error(struct qeth_card *card, } return QETH_SEND_ERROR_NONE; case 2: - if (siga_err & QDIO_SIGA_ERROR_B_BIT_SET) { + if (qdio_err & QDIO_ERROR_SIGA_BUSY) { QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B"); QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card)); return QETH_SEND_ERROR_KICK_IT; @@ -2758,8 +2750,8 @@ static int qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue) return 0; } -static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, - int index, int count) +static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, + int count) { struct qeth_qdio_out_buffer *buf; int rc; @@ -2807,12 +2799,10 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, qeth_get_micros(); } qdio_flags = QDIO_FLAG_SYNC_OUTPUT; - if (under_int) - qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT; if (atomic_read(&queue->set_pci_flags_count)) qdio_flags |= QDIO_FLAG_PCI_OUT; rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags, - queue->queue_no, index, count, NULL); + queue->queue_no, index, count); if (queue->card->options.performance_stats) queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - @@ -2866,16 +2856,15 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue) queue->card->perf_stats.bufs_sent_pack += flush_cnt; if (flush_cnt) - qeth_flush_buffers(queue, 1, index, flush_cnt); + qeth_flush_buffers(queue, index, flush_cnt); atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); } } } -void qeth_qdio_output_handler(struct ccw_device *ccwdev, unsigned int status, - unsigned int qdio_error, unsigned int siga_error, - unsigned int __queue, int first_element, int count, - unsigned long card_ptr) +void qeth_qdio_output_handler(struct ccw_device *ccwdev, + unsigned int qdio_error, int __queue, int first_element, + int count, unsigned long card_ptr) { struct qeth_card *card = (struct qeth_card *) card_ptr; struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue]; @@ -2883,15 +2872,12 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, unsigned int status, int i; QETH_DBF_TEXT(TRACE, 6, "qdouhdl"); - if (status & QDIO_STATUS_LOOK_FOR_ERROR) { - if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { - QETH_DBF_TEXT(TRACE, 2, "achkcond"); - QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_BUS_ID(card)); - QETH_DBF_TEXT_(TRACE, 2, "%08x", status); - netif_stop_queue(card->dev); - qeth_schedule_recovery(card); - return; - } + if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { + QETH_DBF_TEXT(TRACE, 2, "achkcond"); + QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_BUS_ID(card)); + netif_stop_queue(card->dev); + qeth_schedule_recovery(card); + return; } if (card->options.performance_stats) { card->perf_stats.outbound_handler_cnt++; @@ -2901,8 +2887,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, unsigned int status, for (i = first_element; i < (first_element + count); ++i) { buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; /*we only handle the KICK_IT error by doing a recovery */ - if (qeth_handle_send_error(card, buffer, - qdio_error, siga_error) + if (qeth_handle_send_error(card, buffer, qdio_error) == QETH_SEND_ERROR_KICK_IT){ netif_stop_queue(card->dev); qeth_schedule_recovery(card); @@ -3164,11 +3149,11 @@ int qeth_do_send_packet_fast(struct qeth_card *card, atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); if (ctx == NULL) { qeth_fill_buffer(queue, buffer, skb); - qeth_flush_buffers(queue, 0, index, 1); + qeth_flush_buffers(queue, index, 1); } else { flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index); WARN_ON(buffers_needed != flush_cnt); - qeth_flush_buffers(queue, 0, index, flush_cnt); + qeth_flush_buffers(queue, index, flush_cnt); } return 0; out: @@ -3221,8 +3206,8 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, * again */ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ - qeth_flush_buffers(queue, 0, - start_index, flush_count); + qeth_flush_buffers(queue, start_index, + flush_count); atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); return -EBUSY; @@ -3253,7 +3238,7 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, flush_count += tmp; out: if (flush_count) - qeth_flush_buffers(queue, 0, start_index, flush_count); + qeth_flush_buffers(queue, start_index, flush_count); else if (!atomic_read(&queue->set_pci_flags_count)) atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH); /* @@ -3274,7 +3259,7 @@ out: if (!flush_count && !atomic_read(&queue->set_pci_flags_count)) flush_count += qeth_flush_buffers_on_no_pci(queue); if (flush_count) - qeth_flush_buffers(queue, 0, start_index, flush_count); + qeth_flush_buffers(queue, start_index, flush_count); } /* at this point the queue is UNLOCKED again */ if (queue->card->options.performance_stats && do_pack) @@ -3686,10 +3671,6 @@ static int qeth_qdio_establish(struct qeth_card *card) init_data.q_format = qeth_get_qdio_q_format(card); init_data.qib_param_field_format = 0; init_data.qib_param_field = qib_param_field; - init_data.min_input_threshold = QETH_MIN_INPUT_THRESHOLD; - init_data.max_input_threshold = QETH_MAX_INPUT_THRESHOLD; - init_data.min_output_threshold = QETH_MIN_OUTPUT_THRESHOLD; - init_data.max_output_threshold = QETH_MAX_OUTPUT_THRESHOLD; init_data.no_input_qs = 1; init_data.no_output_qs = card->qdio.no_out_queues; init_data.input_handler = card->discipline.input_handler; @@ -3751,8 +3732,9 @@ static int qeth_core_driver_group(const char *buf, struct device *root_dev, int qeth_core_hardsetup_card(struct qeth_card *card) { + struct qdio_ssqd_desc *qdio_ssqd; int retries = 3; - int mpno; + int mpno = 0; int rc; QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); @@ -3784,7 +3766,10 @@ retry: QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); return rc; } - mpno = qdio_get_ssqd_pct(CARD_DDEV(card)); + + qdio_ssqd = qdio_get_ssqd_desc(CARD_DDEV(card)); + if (qdio_ssqd) + mpno = qdio_ssqd->pcnt; if (mpno) mpno = min(mpno - 1, QETH_MAX_PORTNO); if (card->info.portno > mpno) { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index f682f7b..3fbc3bd 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -726,8 +726,7 @@ tx_drop: } static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, - unsigned int status, unsigned int qdio_err, - unsigned int siga_err, unsigned int queue, + unsigned int qdio_err, unsigned int queue, int first_element, int count, unsigned long card_ptr) { struct net_device *net_dev; @@ -742,23 +741,20 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, card->perf_stats.inbound_cnt++; card->perf_stats.inbound_start_time = qeth_get_micros(); } - if (status & QDIO_STATUS_LOOK_FOR_ERROR) { - if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { - QETH_DBF_TEXT(TRACE, 1, "qdinchk"); - QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card)); - QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", first_element, - count); - QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", queue, status); - qeth_schedule_recovery(card); - return; - } + if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { + QETH_DBF_TEXT(TRACE, 1, "qdinchk"); + QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card)); + QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", first_element, + count); + QETH_DBF_TEXT_(TRACE, 1, "%04X", queue); + qeth_schedule_recovery(card); + return; } for (i = first_element; i < (first_element + count); ++i) { index = i % QDIO_MAX_BUFFERS_PER_Q; buffer = &card->qdio.in_q->bufs[index]; - if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) && - qeth_check_qdio_errors(buffer->buffer, - qdio_err, siga_err, "qinerr"))) + if (!(qdio_err && + qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr"))) qeth_l2_process_inbound_buffer(card, buffer, index); /* clear buffer and give back to hardware */ qeth_put_buffer_pool_entry(card, buffer->pool_entry); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 06deaee..22f64aa 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2939,8 +2939,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) } static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev, - unsigned int status, unsigned int qdio_err, - unsigned int siga_err, unsigned int queue, int first_element, + unsigned int qdio_err, unsigned int queue, int first_element, int count, unsigned long card_ptr) { struct net_device *net_dev; @@ -2955,23 +2954,21 @@ static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev, card->perf_stats.inbound_cnt++; card->perf_stats.inbound_start_time = qeth_get_micros(); } - if (status & QDIO_STATUS_LOOK_FOR_ERROR) { - if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) { - QETH_DBF_TEXT(TRACE, 1, "qdinchk"); - QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card)); - QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", - first_element, count); - QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", queue, status); - qeth_schedule_recovery(card); - return; - } + if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { + QETH_DBF_TEXT(TRACE, 1, "qdinchk"); + QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card)); + QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", + first_element, count); + QETH_DBF_TEXT_(TRACE, 1, "%04X", queue); + qeth_schedule_recovery(card); + return; } for (i = first_element; i < (first_element + count); ++i) { index = i % QDIO_MAX_BUFFERS_PER_Q; buffer = &card->qdio.in_q->bufs[index]; - if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) && + if (!(qdio_err && qeth_check_qdio_errors(buffer->buffer, - qdio_err, siga_err, "qinerr"))) + qdio_err, "qinerr"))) qeth_l3_process_inbound_buffer(card, buffer, index); /* clear buffer and give back to hardware */ qeth_put_buffer_pool_entry(card, buffer->pool_entry); diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 36169c6..fca48b8 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -297,15 +297,13 @@ void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, /** * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure * @adapter: adapter affected by this QDIO related event - * @status: as passed by qdio module * @qdio_error: as passed by qdio module - * @siga_error: as passed by qdio module * @sbal_index: first buffer with error condition, as passed by qdio module * @sbal_count: number of buffers affected, as passed by qdio module */ -void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, - unsigned int qdio_error, unsigned int siga_error, - int sbal_index, int sbal_count) +void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, + unsigned int qdio_error, int sbal_index, + int sbal_count) { struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf; unsigned long flags; @@ -313,9 +311,7 @@ void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, spin_lock_irqsave(&adapter->hba_dbf_lock, flags); memset(r, 0, sizeof(*r)); strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE); - r->u.qdio.status = status; r->u.qdio.qdio_error = qdio_error; - r->u.qdio.siga_error = siga_error; r->u.qdio.sbal_index = sbal_index; r->u.qdio.sbal_count = sbal_count; debug_event(adapter->hba_dbf, 0, r, sizeof(*r)); @@ -398,9 +394,7 @@ static void zfcp_hba_dbf_view_status(char **p, static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r) { - zfcp_dbf_out(p, "status", "0x%08x", r->status); zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error); - zfcp_dbf_out(p, "siga_error", "0x%08x", r->siga_error); zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index); zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); } diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index d04aea6..0ddb184 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -139,9 +139,7 @@ struct zfcp_hba_dbf_record_status { } __attribute__ ((packed)); struct zfcp_hba_dbf_record_qdio { - u32 status; u32 qdio_error; - u32 siga_error; u8 sbal_index; u8 sbal_count; } __attribute__ ((packed)); diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 8065b2b..edfdb21 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -48,9 +48,8 @@ extern void zfcp_rec_dbf_event_action(u8, struct zfcp_erp_action *); extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *); extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, struct fsf_status_read_buffer *); -extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, - unsigned int, unsigned int, unsigned int, - int, int); +extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, unsigned int, int, + int); extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *); extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *); extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *); diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 72e3094..d6dbd65 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -74,17 +74,15 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) } } -static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int status, - unsigned int qdio_err, unsigned int siga_err, - unsigned int queue_no, int first, int count, +static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, + int queue_no, int first, int count, unsigned long parm) { struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; struct zfcp_qdio_queue *queue = &adapter->req_q; - if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { - zfcp_hba_dbf_event_qdio(adapter, status, qdio_err, siga_err, - first, count); + if (unlikely(qdio_err)) { + zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); zfcp_qdio_handler_error(adapter, 140); return; } @@ -129,8 +127,7 @@ static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed) count = atomic_read(&queue->count) + processed; - retval = do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, - 0, start, count, NULL); + retval = do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, start, count); if (unlikely(retval)) { atomic_set(&queue->count, count); @@ -142,9 +139,8 @@ static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed) } } -static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int status, - unsigned int qdio_err, unsigned int siga_err, - unsigned int queue_no, int first, int count, +static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, + int queue_no, int first, int count, unsigned long parm) { struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; @@ -152,9 +148,8 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int status, volatile struct qdio_buffer_element *sbale; int sbal_idx, sbale_idx, sbal_no; - if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { - zfcp_hba_dbf_event_qdio(adapter, status, qdio_err, siga_err, - first, count); + if (unlikely(qdio_err)) { + zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); zfcp_qdio_handler_error(adapter, 147); return; } @@ -362,7 +357,7 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) } retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first, - count, NULL); + count); if (unlikely(retval)) { zfcp_qdio_zero_sbals(req_q->sbal, first, count); return retval; @@ -400,10 +395,6 @@ int zfcp_qdio_allocate(struct zfcp_adapter *adapter) init_data->qib_param_field = NULL; init_data->input_slib_elements = NULL; init_data->output_slib_elements = NULL; - init_data->min_input_threshold = 1; - init_data->max_input_threshold = 5000; - init_data->min_output_threshold = 1; - init_data->max_output_threshold = 1000; init_data->no_input_qs = 1; init_data->no_output_qs = 1; init_data->input_handler = zfcp_qdio_int_resp; @@ -436,9 +427,7 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); spin_unlock(&req_q->lock); - while (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR) - == -EINPROGRESS) - ssleep(1); + qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); /* cleanup used outbound sbals */ count = atomic_read(&req_q->count); @@ -473,7 +462,7 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter) return -EIO; } - if (qdio_activate(adapter->ccw_device, 0)) { + if (qdio_activate(adapter->ccw_device)) { dev_err(&adapter->ccw_device->dev, "Activate of QDIO queues failed.\n"); goto failed_qdio; @@ -487,7 +476,7 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter) } if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0, - QDIO_MAX_BUFFERS_PER_Q, NULL)) { + QDIO_MAX_BUFFERS_PER_Q)) { dev_err(&adapter->ccw_device->dev, "Init of QDIO response queue failed.\n"); goto failed_qdio; @@ -501,9 +490,6 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter) return 0; failed_qdio: - while (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR) - == -EINPROGRESS) - ssleep(1); - + qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); return -EIO; } diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h index 1124034..6813772 100644 --- a/include/asm-s390/qdio.h +++ b/include/asm-s390/qdio.h @@ -1,404 +1,382 @@ /* * linux/include/asm-s390/qdio.h * - * Linux for S/390 QDIO base support, Hipersocket base support - * version 2 - * - * Copyright 2000,2002 IBM Corporation + * Copyright 2000,2008 IBM Corp. * Author(s): Utz Bacher + * Jan Glauber * */ #ifndef __QDIO_H__ #define __QDIO_H__ -/* note, that most of the typedef's are from ingo. */ - #include #include #include -#define QDIO_NAME "qdio " - -#ifndef __s390x__ -#define QDIO_32_BIT -#endif /* __s390x__ */ - -/**** CONSTANTS, that are relied on without using these symbols *****/ -#define QDIO_MAX_QUEUES_PER_IRQ 32 /* used in width of unsigned int */ -/************************ END of CONSTANTS **************************/ -#define QDIO_MAX_BUFFERS_PER_Q 128 /* must be a power of 2 (%x=&(x-1)*/ -#define QDIO_BUF_ORDER 7 /* 2**this == number of pages used for sbals in 1 q */ -#define QDIO_MAX_ELEMENTS_PER_BUFFER 16 -#define SBAL_SIZE 256 - -#define QDIO_QETH_QFMT 0 -#define QDIO_ZFCP_QFMT 1 -#define QDIO_IQDIO_QFMT 2 -#define QDIO_IQDIO_QFMT_ASYNCH 3 - -struct qdio_buffer_element{ - unsigned int flags; - unsigned int length; -#ifdef QDIO_32_BIT - void *reserved; -#endif /* QDIO_32_BIT */ - void *addr; -} __attribute__ ((packed,aligned(16))); - -struct qdio_buffer{ - volatile struct qdio_buffer_element element[16]; -} __attribute__ ((packed,aligned(256))); - - -/* params are: ccw_device, status, qdio_error, siga_error, - queue_number, first element processed, number of elements processed, - int_parm */ -typedef void qdio_handler_t(struct ccw_device *,unsigned int,unsigned int, - unsigned int,unsigned int,int,int,unsigned long); - - -#define QDIO_STATUS_INBOUND_INT 0x01 -#define QDIO_STATUS_OUTBOUND_INT 0x02 -#define QDIO_STATUS_LOOK_FOR_ERROR 0x04 -#define QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR 0x08 -#define QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR 0x10 -#define QDIO_STATUS_ACTIVATE_CHECK_CONDITION 0x20 - -#define QDIO_SIGA_ERROR_ACCESS_EXCEPTION 0x10 -#define QDIO_SIGA_ERROR_B_BIT_SET 0x20 - -/* for qdio_initialize */ -#define QDIO_INBOUND_0COPY_SBALS 0x01 -#define QDIO_OUTBOUND_0COPY_SBALS 0x02 -#define QDIO_USE_OUTBOUND_PCIS 0x04 - -/* for qdio_cleanup */ -#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 -#define QDIO_FLAG_CLEANUP_USING_HALT 0x02 - -struct qdio_initialize { - struct ccw_device *cdev; - unsigned char q_format; - unsigned char adapter_name[8]; - unsigned int qib_param_field_format; /*adapter dependent*/ - /* pointer to 128 bytes or NULL, if no param field */ - unsigned char *qib_param_field; /* adapter dependent */ - /* pointer to no_queues*128 words of data or NULL */ - unsigned long *input_slib_elements; - unsigned long *output_slib_elements; - unsigned int min_input_threshold; - unsigned int max_input_threshold; - unsigned int min_output_threshold; - unsigned int max_output_threshold; - unsigned int no_input_qs; - unsigned int no_output_qs; - qdio_handler_t *input_handler; - qdio_handler_t *output_handler; - unsigned long int_parm; - unsigned long flags; - void **input_sbal_addr_array; /* addr of n*128 void ptrs */ - void **output_sbal_addr_array; /* addr of n*128 void ptrs */ -}; - -extern int qdio_initialize(struct qdio_initialize *init_data); -extern int qdio_allocate(struct qdio_initialize *init_data); -extern int qdio_establish(struct qdio_initialize *init_data); - -extern int qdio_activate(struct ccw_device *,int flags); - -#define QDIO_STATE_MUST_USE_OUTB_PCI 0x00000001 -#define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ -#define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_initialize */ -#define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ -#define QDIO_STATE_STOPPED 0x00000010 /* after queues went down */ -extern unsigned long qdio_get_status(int irq); - - -#define QDIO_FLAG_SYNC_INPUT 0x01 -#define QDIO_FLAG_SYNC_OUTPUT 0x02 -#define QDIO_FLAG_UNDER_INTERRUPT 0x04 -#define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on - adapter interrupts */ -#define QDIO_FLAG_DONT_SIGA 0x10 -#define QDIO_FLAG_PCI_OUT 0x20 - -extern int do_QDIO(struct ccw_device*, unsigned int flags, - unsigned int queue_number, - unsigned int qidx,unsigned int count, - struct qdio_buffer *buffers); - -extern int qdio_get_ssqd_pct(struct ccw_device*); -extern int qdio_synchronize(struct ccw_device*, unsigned int flags, - unsigned int queue_number); - -extern int qdio_cleanup(struct ccw_device*, int how); -extern int qdio_shutdown(struct ccw_device*, int how); -extern int qdio_free(struct ccw_device*); - -unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag, - unsigned int queue_number, - unsigned int qidx); - -extern void qdio_init_scrubber(void); - +#define QDIO_MAX_QUEUES_PER_IRQ 32 +#define QDIO_MAX_BUFFERS_PER_Q 128 +#define QDIO_MAX_BUFFERS_MASK (QDIO_MAX_BUFFERS_PER_Q - 1) +#define QDIO_MAX_ELEMENTS_PER_BUFFER 16 +#define QDIO_SBAL_SIZE 256 + +#define QDIO_QETH_QFMT 0 +#define QDIO_ZFCP_QFMT 1 +#define QDIO_IQDIO_QFMT 2 + +/** + * struct qdesfmt0 - queue descriptor, format 0 + * @sliba: storage list information block address + * @sla: storage list address + * @slsba: storage list state block address + * @akey: access key for DLIB + * @bkey: access key for SL + * @ckey: access key for SBALs + * @dkey: access key for SLSB + */ struct qdesfmt0 { -#ifdef QDIO_32_BIT - unsigned long res1; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long sliba; /* storage-list-information-block - address */ -#ifdef QDIO_32_BIT - unsigned long res2; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long sla; /* storage-list address */ -#ifdef QDIO_32_BIT - unsigned long res3; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long slsba; /* storage-list-state-block address */ - unsigned int res4; /* reserved */ - unsigned int akey : 4; /* access key for DLIB */ - unsigned int bkey : 4; /* access key for SL */ - unsigned int ckey : 4; /* access key for SBALs */ - unsigned int dkey : 4; /* access key for SLSB */ - unsigned int res5 : 16; /* reserved */ + u64 sliba; + u64 sla; + u64 slsba; + u32 : 32; + u32 akey : 4; + u32 bkey : 4; + u32 ckey : 4; + u32 dkey : 4; + u32 : 16; } __attribute__ ((packed)); -/* - * Queue-Description record (QDR) +/** + * struct qdr - queue description record (QDR) + * @qfmt: queue format + * @pfmt: implementation dependent parameter format + * @ac: adapter characteristics + * @iqdcnt: input queue descriptor count + * @oqdcnt: output queue descriptor count + * @iqdsz: inpout queue descriptor size + * @oqdsz: output queue descriptor size + * @qiba: queue information block address + * @qkey: queue information block key + * @qdf0: queue descriptions */ struct qdr { - unsigned int qfmt : 8; /* queue format */ - unsigned int pfmt : 8; /* impl. dep. parameter format */ - unsigned int res1 : 8; /* reserved */ - unsigned int ac : 8; /* adapter characteristics */ - unsigned int res2 : 8; /* reserved */ - unsigned int iqdcnt : 8; /* input-queue-descriptor count */ - unsigned int res3 : 8; /* reserved */ - unsigned int oqdcnt : 8; /* output-queue-descriptor count */ - unsigned int res4 : 8; /* reserved */ - unsigned int iqdsz : 8; /* input-queue-descriptor size */ - unsigned int res5 : 8; /* reserved */ - unsigned int oqdsz : 8; /* output-queue-descriptor size */ - unsigned int res6[9]; /* reserved */ -#ifdef QDIO_32_BIT - unsigned long res7; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long qiba; /* queue-information-block address */ - unsigned int res8; /* reserved */ - unsigned int qkey : 4; /* queue-information-block key */ - unsigned int res9 : 28; /* reserved */ -/* union _qd {*/ /* why this? */ - struct qdesfmt0 qdf0[126]; -/* } qd;*/ -} __attribute__ ((packed,aligned(4096))); - - -/* - * queue information block (QIB) - */ -#define QIB_AC_INBOUND_PCI_SUPPORTED 0x80 -#define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 + u32 qfmt : 8; + u32 pfmt : 8; + u32 : 8; + u32 ac : 8; + u32 : 8; + u32 iqdcnt : 8; + u32 : 8; + u32 oqdcnt : 8; + u32 : 8; + u32 iqdsz : 8; + u32 : 8; + u32 oqdsz : 8; + /* private: */ + u32 res[9]; + /* public: */ + u64 qiba; + u32 : 32; + u32 qkey : 4; + u32 : 28; + struct qdesfmt0 qdf0[126]; +} __attribute__ ((packed, aligned(4096))); + +#define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 #define QIB_RFLAGS_ENABLE_QEBSM 0x80 +/** + * struct qib - queue information block (QIB) + * @qfmt: queue format + * @pfmt: implementation dependent parameter format + * @rflags: QEBSM + * @ac: adapter characteristics + * @isliba: absolute address of first input SLIB + * @osliba: absolute address of first output SLIB + * @ebcnam: adapter identifier in EBCDIC + * @parm: implementation dependent parameters + */ struct qib { - unsigned int qfmt : 8; /* queue format */ - unsigned int pfmt : 8; /* impl. dep. parameter format */ - unsigned int rflags : 8; /* QEBSM */ - unsigned int ac : 8; /* adapter characteristics */ - unsigned int res2; /* reserved */ -#ifdef QDIO_32_BIT - unsigned long res3; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long isliba; /* absolute address of 1st - input SLIB */ -#ifdef QDIO_32_BIT - unsigned long res4; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long osliba; /* absolute address of 1st - output SLIB */ - unsigned int res5; /* reserved */ - unsigned int res6; /* reserved */ - unsigned char ebcnam[8]; /* adapter identifier in EBCDIC */ - unsigned char res7[88]; /* reserved */ - unsigned char parm[QDIO_MAX_BUFFERS_PER_Q]; - /* implementation dependent - parameters */ -} __attribute__ ((packed,aligned(256))); - - -/* - * storage-list-information block element (SLIBE) + u32 qfmt : 8; + u32 pfmt : 8; + u32 rflags : 8; + u32 ac : 8; + u32 : 32; + u64 isliba; + u64 osliba; + u32 : 32; + u32 : 32; + u8 ebcnam[8]; + /* private: */ + u8 res[88]; + /* public: */ + u8 parm[QDIO_MAX_BUFFERS_PER_Q]; +} __attribute__ ((packed, aligned(256))); + +/** + * struct slibe - storage list information block element (SLIBE) + * @parms: implementation dependent parameters */ struct slibe { -#ifdef QDIO_32_BIT - unsigned long res; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long parms; /* implementation dependent - parameters */ + u64 parms; }; -/* - * storage-list-information block (SLIB) +/** + * struct slib - storage list information block (SLIB) + * @nsliba: next SLIB address (if any) + * @sla: SL address + * @slsba: SLSB address + * @slibe: SLIB elements */ struct slib { -#ifdef QDIO_32_BIT - unsigned long res1; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long nsliba; /* next SLIB address (if any) */ -#ifdef QDIO_32_BIT - unsigned long res2; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long sla; /* SL address */ -#ifdef QDIO_32_BIT - unsigned long res3; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long slsba; /* SLSB address */ - unsigned char res4[1000]; /* reserved */ - struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q]; /* SLIB elements */ -} __attribute__ ((packed,aligned(2048))); - + u64 nsliba; + u64 sla; + u64 slsba; + /* private: */ + u8 res[1000]; + /* public: */ + struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q]; +} __attribute__ ((packed, aligned(2048))); + +/** + * struct sbal_flags - storage block address list flags + * @last: last entry + * @cont: contiguous storage + * @frag: fragmentation + */ struct sbal_flags { - unsigned char res1 : 1; /* reserved */ - unsigned char last : 1; /* last entry */ - unsigned char cont : 1; /* contiguous storage */ - unsigned char res2 : 1; /* reserved */ - unsigned char frag : 2; /* fragmentation (s.below) */ - unsigned char res3 : 2; /* reserved */ + u8 : 1; + u8 last : 1; + u8 cont : 1; + u8 : 1; + u8 frag : 2; + u8 : 2; } __attribute__ ((packed)); -#define SBAL_FLAGS_FIRST_FRAG 0x04000000UL -#define SBAL_FLAGS_MIDDLE_FRAG 0x08000000UL -#define SBAL_FLAGS_LAST_FRAG 0x0c000000UL -#define SBAL_FLAGS_LAST_ENTRY 0x40000000UL -#define SBAL_FLAGS_CONTIGUOUS 0x20000000UL +#define SBAL_FLAGS_FIRST_FRAG 0x04000000UL +#define SBAL_FLAGS_MIDDLE_FRAG 0x08000000UL +#define SBAL_FLAGS_LAST_FRAG 0x0c000000UL +#define SBAL_FLAGS_LAST_ENTRY 0x40000000UL +#define SBAL_FLAGS_CONTIGUOUS 0x20000000UL -#define SBAL_FLAGS0_DATA_CONTINUATION 0x20UL +#define SBAL_FLAGS0_DATA_CONTINUATION 0x20UL /* Awesome OpenFCP extensions */ -#define SBAL_FLAGS0_TYPE_STATUS 0x00UL -#define SBAL_FLAGS0_TYPE_WRITE 0x08UL -#define SBAL_FLAGS0_TYPE_READ 0x10UL -#define SBAL_FLAGS0_TYPE_WRITE_READ 0x18UL -#define SBAL_FLAGS0_MORE_SBALS 0x04UL -#define SBAL_FLAGS0_COMMAND 0x02UL -#define SBAL_FLAGS0_LAST_SBAL 0x00UL -#define SBAL_FLAGS0_ONLY_SBAL SBAL_FLAGS0_COMMAND -#define SBAL_FLAGS0_MIDDLE_SBAL SBAL_FLAGS0_MORE_SBALS -#define SBAL_FLAGS0_FIRST_SBAL SBAL_FLAGS0_MORE_SBALS | SBAL_FLAGS0_COMMAND -/* Naught of interest beyond this point */ - -#define SBAL_FLAGS0_PCI 0x40 +#define SBAL_FLAGS0_TYPE_STATUS 0x00UL +#define SBAL_FLAGS0_TYPE_WRITE 0x08UL +#define SBAL_FLAGS0_TYPE_READ 0x10UL +#define SBAL_FLAGS0_TYPE_WRITE_READ 0x18UL +#define SBAL_FLAGS0_MORE_SBALS 0x04UL +#define SBAL_FLAGS0_COMMAND 0x02UL +#define SBAL_FLAGS0_LAST_SBAL 0x00UL +#define SBAL_FLAGS0_ONLY_SBAL SBAL_FLAGS0_COMMAND +#define SBAL_FLAGS0_MIDDLE_SBAL SBAL_FLAGS0_MORE_SBALS +#define SBAL_FLAGS0_FIRST_SBAL SBAL_FLAGS0_MORE_SBALS | SBAL_FLAGS0_COMMAND +#define SBAL_FLAGS0_PCI 0x40 + +/** + * struct sbal_sbalf_0 - sbal flags for sbale 0 + * @pci: PCI indicator + * @cont: data continuation + * @sbtype: storage-block type (FCP) + */ struct sbal_sbalf_0 { - unsigned char res1 : 1; /* reserved */ - unsigned char pci : 1; /* PCI indicator */ - unsigned char cont : 1; /* data continuation */ - unsigned char sbtype: 2; /* storage-block type (OpenFCP) */ - unsigned char res2 : 3; /* reserved */ + u8 : 1; + u8 pci : 1; + u8 cont : 1; + u8 sbtype : 2; + u8 : 3; } __attribute__ ((packed)); +/** + * struct sbal_sbalf_1 - sbal flags for sbale 1 + * @key: storage key + */ struct sbal_sbalf_1 { - unsigned char res1 : 4; /* reserved */ - unsigned char key : 4; /* storage key */ + u8 : 4; + u8 key : 4; } __attribute__ ((packed)); +/** + * struct sbal_sbalf_14 - sbal flags for sbale 14 + * @erridx: error index + */ struct sbal_sbalf_14 { - unsigned char res1 : 4; /* reserved */ - unsigned char erridx : 4; /* error index */ + u8 : 4; + u8 erridx : 4; } __attribute__ ((packed)); +/** + * struct sbal_sbalf_15 - sbal flags for sbale 15 + * @reason: reason for error state + */ struct sbal_sbalf_15 { - unsigned char reason; /* reserved */ + u8 reason; } __attribute__ ((packed)); +/** + * union sbal_sbalf - storage block address list flags + * @i0: sbalf0 + * @i1: sbalf1 + * @i14: sbalf14 + * @i15: sblaf15 + * @value: raw value + */ union sbal_sbalf { struct sbal_sbalf_0 i0; struct sbal_sbalf_1 i1; struct sbal_sbalf_14 i14; struct sbal_sbalf_15 i15; - unsigned char value; + u8 value; }; -struct sbal_element { - union { - struct sbal_flags bits; /* flags */ - unsigned char value; - } flags; - unsigned int res1 : 16; /* reserved */ - union sbal_sbalf sbalf; /* SBAL flags */ - unsigned int res2 : 16; /* reserved */ - unsigned int count : 16; /* data count */ -#ifdef QDIO_32_BIT - unsigned long res3; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long addr; /* absolute data address */ -} __attribute__ ((packed,aligned(16))); +/** + * struct qdio_buffer_element - SBAL entry + * @flags: flags + * @length: length + * @addr: address +*/ +struct qdio_buffer_element { + u32 flags; + u32 length; +#ifdef CONFIG_32BIT + /* private: */ + void *reserved; + /* public: */ +#endif + void *addr; +} __attribute__ ((packed, aligned(16))); -/* - * strorage-block access-list (SBAL) +/** + * struct qdio_buffer - storage block address list (SBAL) + * @element: SBAL entries */ -struct sbal { - struct sbal_element element[QDIO_MAX_ELEMENTS_PER_BUFFER]; -} __attribute__ ((packed,aligned(256))); +struct qdio_buffer { + struct qdio_buffer_element element[QDIO_MAX_ELEMENTS_PER_BUFFER]; +} __attribute__ ((packed, aligned(256))); -/* - * storage-list (SL) +/** + * struct sl_element - storage list entry + * @sbal: absolute SBAL address */ struct sl_element { -#ifdef QDIO_32_BIT - unsigned long res; /* reserved */ -#endif /* QDIO_32_BIT */ - unsigned long sbal; /* absolute SBAL address */ +#ifdef CONFIG_32BIT + /* private: */ + unsigned long reserved; + /* public: */ +#endif + unsigned long sbal; } __attribute__ ((packed)); +/** + * struct sl - storage list (SL) + * @element: SL entries + */ struct sl { struct sl_element element[QDIO_MAX_BUFFERS_PER_Q]; -} __attribute__ ((packed,aligned(1024))); +} __attribute__ ((packed, aligned(1024))); -/* - * storage-list-state block (SLSB) +/** + * struct slsb - storage list state block (SLSB) + * @val: state per buffer */ -struct slsb_flags { - unsigned char owner : 2; /* SBAL owner */ - unsigned char type : 1; /* buffer type */ - unsigned char state : 5; /* processing state */ +struct slsb { + u8 val[QDIO_MAX_BUFFERS_PER_Q]; +} __attribute__ ((packed, aligned(256))); + +struct qdio_ssqd_desc { + u8 flags; + u8:8; + u16 sch; + u8 qfmt; + u8 parm; + u8 qdioac1; + u8 sch_class; + u8 pcnt; + u8 icnt; + u8:8; + u8 ocnt; + u8:8; + u8 mbccnt; + u16 qdioac2; + u64 sch_token; + u64:64; } __attribute__ ((packed)); +/* params are: ccw_device, qdio_error, queue_number, + first element processed, number of elements processed, int_parm */ +typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, + int, int, unsigned long); -struct slsb { - union { - unsigned char val[QDIO_MAX_BUFFERS_PER_Q]; - struct slsb_flags flags[QDIO_MAX_BUFFERS_PER_Q]; - } acc; -} __attribute__ ((packed,aligned(256))); +/* qdio errors reported to the upper-layer program */ +#define QDIO_ERROR_SIGA_ACCESS_EXCEPTION 0x10 +#define QDIO_ERROR_SIGA_BUSY 0x20 +#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 +#define QDIO_ERROR_SLSB_STATE 0x80 -/* - * SLSB values +/* for qdio_initialize */ +#define QDIO_INBOUND_0COPY_SBALS 0x01 +#define QDIO_OUTBOUND_0COPY_SBALS 0x02 +#define QDIO_USE_OUTBOUND_PCIS 0x04 + +/* for qdio_cleanup */ +#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 +#define QDIO_FLAG_CLEANUP_USING_HALT 0x02 + +/** + * struct qdio_initialize - qdio initalization data + * @cdev: associated ccw device + * @q_format: queue format + * @adapter_name: name for the adapter + * @qib_param_field_format: format for qib_parm_field + * @qib_param_field: pointer to 128 bytes or NULL, if no param field + * @input_slib_elements: pointer to no_input_qs * 128 words of data or NULL + * @output_slib_elements: pointer to no_output_qs * 128 words of data or NULL + * @no_input_qs: number of input queues + * @no_output_qs: number of output queues + * @input_handler: handler to be called for input queues + * @output_handler: handler to be called for output queues + * @int_parm: interruption parameter + * @flags: initialization flags + * @input_sbal_addr_array: address of no_input_qs * 128 pointers + * @output_sbal_addr_array: address of no_output_qs * 128 pointers */ -#define SLSB_OWNER_PROG 1 -#define SLSB_OWNER_CU 2 - -#define SLSB_TYPE_INPUT 0 -#define SLSB_TYPE_OUTPUT 1 - -#define SLSB_STATE_NOT_INIT 0 -#define SLSB_STATE_EMPTY 1 -#define SLSB_STATE_PRIMED 2 -#define SLSB_STATE_HALTED 0xe -#define SLSB_STATE_ERROR 0xf - -#define SLSB_P_INPUT_NOT_INIT 0x80 -#define SLSB_P_INPUT_PROCESSING 0x81 -#define SLSB_CU_INPUT_EMPTY 0x41 -#define SLSB_P_INPUT_PRIMED 0x82 -#define SLSB_P_INPUT_HALTED 0x8E -#define SLSB_P_INPUT_ERROR 0x8F - -#define SLSB_P_OUTPUT_NOT_INIT 0xA0 -#define SLSB_P_OUTPUT_EMPTY 0xA1 -#define SLSB_CU_OUTPUT_PRIMED 0x62 -#define SLSB_P_OUTPUT_HALTED 0xAE -#define SLSB_P_OUTPUT_ERROR 0xAF - -#define SLSB_ERROR_DURING_LOOKUP 0xFF +struct qdio_initialize { + struct ccw_device *cdev; + unsigned char q_format; + unsigned char adapter_name[8]; + unsigned int qib_param_field_format; + unsigned char *qib_param_field; + unsigned long *input_slib_elements; + unsigned long *output_slib_elements; + unsigned int no_input_qs; + unsigned int no_output_qs; + qdio_handler_t *input_handler; + qdio_handler_t *output_handler; + unsigned long int_parm; + unsigned long flags; + void **input_sbal_addr_array; + void **output_sbal_addr_array; +}; + +#define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ +#define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */ +#define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ +#define QDIO_STATE_STOPPED 0x00000010 /* after queues went down */ + +#define QDIO_FLAG_SYNC_INPUT 0x01 +#define QDIO_FLAG_SYNC_OUTPUT 0x02 +#define QDIO_FLAG_PCI_OUT 0x10 + +extern int qdio_initialize(struct qdio_initialize *init_data); +extern int qdio_allocate(struct qdio_initialize *init_data); +extern int qdio_establish(struct qdio_initialize *init_data); +extern int qdio_activate(struct ccw_device *); + +extern int do_QDIO(struct ccw_device*, unsigned int flags, + int q_nr, int qidx, int count); +extern int qdio_cleanup(struct ccw_device*, int how); +extern int qdio_shutdown(struct ccw_device*, int how); +extern int qdio_free(struct ccw_device *); +extern struct qdio_ssqd_desc *qdio_get_ssqd_desc(struct ccw_device *cdev); #endif /* __QDIO_H__ */ diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index f09ee3f..4ba14e4 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -65,6 +65,7 @@ extern unsigned long machine_flags; #define MACHINE_FLAG_VM (1UL << 0) #define MACHINE_FLAG_IEEE (1UL << 1) +#define MACHINE_FLAG_P390 (1UL << 2) #define MACHINE_FLAG_CSP (1UL << 3) #define MACHINE_FLAG_MVPG (1UL << 4) #define MACHINE_FLAG_DIAG44 (1UL << 5) @@ -77,7 +78,6 @@ extern unsigned long machine_flags; #define MACHINE_IS_VM (machine_flags & MACHINE_FLAG_VM) #define MACHINE_IS_KVM (machine_flags & MACHINE_FLAG_KVM) -#define MACHINE_IS_P390 (machine_flags & MACHINE_FLAG_P390) #define MACHINE_HAS_DIAG9C (machine_flags & MACHINE_FLAG_DIAG9C) #ifndef __s390x__ -- cgit v0.10.2 From 8586cb60ce85f40431cf06fe97512269d3992f03 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 17 Jul 2008 17:16:49 +0200 Subject: [S390] dasd: use -EOPNOTSUPP instead of -ENOTSUPP return value -ENOTSUPP is not valid in userspace context, use -EOPNOTSUPP instead Signed-off-by: Stefan Haberland Cc: Martin Schwidefsky Signed-off-by: Heiko Carstens diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index ab5c5b4..85fcb43 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -349,7 +349,7 @@ dasd_diag_check_device(struct dasd_device *device) if (rc) { DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device " "information (rc=%d)", rc); - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; goto out; } @@ -364,7 +364,7 @@ dasd_diag_check_device(struct dasd_device *device) default: DEV_MESSAGE(KERN_WARNING, device, "unsupported device class " "(class=%d)", private->rdc_data.vdev_class); - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; goto out; } -- cgit v0.10.2 From 9fa111372a54f695f65e0de2f2a2108fe6cf3584 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Jul 2008 17:38:17 +0200 Subject: ftrace: fix lockup with MAXSMP MAXSMP brings in lots of use of various bitops in smp_processor_id() and friends - causing ftrace to lock up during bootup: calling anon_inode_init+0x0/0x130 initcall anon_inode_init+0x0/0x130 returned 0 after 0 msecs calling acpi_event_init+0x0/0x57 [ hard hang ] So exclude the bitops facilities from tracing. Signed-off-by: Ingo Molnar diff --git a/lib/Makefile b/lib/Makefile index 2c62a9c..d90d311 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -15,6 +15,9 @@ CFLAGS_REMOVE_string.o = -pg CFLAGS_REMOVE_spinlock_debug.o = -pg CFLAGS_REMOVE_list_debug.o = -pg CFLAGS_REMOVE_debugobjects.o = -pg +CFLAGS_REMOVE_find_next_bit.o = -pg +CFLAGS_REMOVE_cpumask.o = -pg +CFLAGS_REMOVE_bitmap.o = -pg endif lib-$(CONFIG_MMU) += ioremap.o -- cgit v0.10.2 From c349e0a01c3e0f70913db6a5bb61ab204e0602de Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 15 Apr 2008 22:39:31 +0200 Subject: ftrace: do not trace scheduler functions do not trace scheduler functions - it's still a bit fragile and can lock up with: http://redhat.com/~mingo/misc/config-Thu_Jul_17_13_34_52_CEST_2008 Signed-off-by: Ingo Molnar diff --git a/kernel/Makefile b/kernel/Makefile index 0a7ed83..985ddb7 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -11,8 +11,6 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o -CFLAGS_REMOVE_sched.o = -mno-spe - ifdef CONFIG_FTRACE # Do not trace debug files and internal ftrace files CFLAGS_REMOVE_lockdep.o = -pg @@ -21,6 +19,7 @@ CFLAGS_REMOVE_mutex-debug.o = -pg CFLAGS_REMOVE_rtmutex-debug.o = -pg CFLAGS_REMOVE_cgroup-debug.o = -pg CFLAGS_REMOVE_sched_clock.o = -pg +CFLAGS_REMOVE_sched.o = -mno-spe -pg endif obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o -- cgit v0.10.2 From 2464a609ded094204a3aed24823745ec58e3c879 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Jul 2008 17:40:48 +0200 Subject: ftrace: do not trace library functions make function tracing more robust: do not trace library functions. We've already got a sizable list of exceptions: ifdef CONFIG_FTRACE # Do not profile string.o, since it may be used in early boot or vdso CFLAGS_REMOVE_string.o = -pg # Also do not profile any debug utilities CFLAGS_REMOVE_spinlock_debug.o = -pg CFLAGS_REMOVE_list_debug.o = -pg CFLAGS_REMOVE_debugobjects.o = -pg CFLAGS_REMOVE_find_next_bit.o = -pg CFLAGS_REMOVE_cpumask.o = -pg CFLAGS_REMOVE_bitmap.o = -pg endif ... and the pattern has been that random library functionality showed up in ftrace's critical path (outside of its recursion check), causing hard to debug lockups. So be a bit defensive about it and exclude all lib/*.o functions by default. It's not that they are overly interesting for tracing purposes anyway. Specific ones can still be traced, in an opt-in manner. Signed-off-by: Ingo Molnar diff --git a/lib/Makefile b/lib/Makefile index d90d311..818c4d4 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,24 +2,17 @@ # Makefile for some libs needed in the kernel. # +ifdef CONFIG_FTRACE +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) +endif + lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o prio_heap.o ratelimit.o -ifdef CONFIG_FTRACE -# Do not profile string.o, since it may be used in early boot or vdso -CFLAGS_REMOVE_string.o = -pg -# Also do not profile any debug utilities -CFLAGS_REMOVE_spinlock_debug.o = -pg -CFLAGS_REMOVE_list_debug.o = -pg -CFLAGS_REMOVE_debugobjects.o = -pg -CFLAGS_REMOVE_find_next_bit.o = -pg -CFLAGS_REMOVE_cpumask.o = -pg -CFLAGS_REMOVE_bitmap.o = -pg -endif - lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o -- cgit v0.10.2 From 7023cc61292f9cd61d99521206480f6e387132ff Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 17 Jul 2008 01:06:55 -0600 Subject: Fix collateral damage to top level Makefile The patch named "powerpc/mpc5121: Add clock driver", also contained an unrelated and bogus change to the top-level makefile. This patch backs out the bad bit. SHA1 of offending patch: 137e95906e294913fab02162e8a1948ade49acb5) Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt Repented-by: John Rigby [ Heh. Normally I pick these out from the diffstats, but I guess I've grown to trust the ppc tree too much ;) - Linus ] Signed-off-by: Linus Torvalds diff --git a/Makefile b/Makefile index 1564577..6192922 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -FRED=42 VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 -- cgit v0.10.2 From 7259d936c6af216198ae6af3a25ac6c9dbdbe779 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 16 Jul 2008 23:44:32 -0700 Subject: Update scripts/Makefile.fwinst to cope with older make Also fix unwanted rebuilds of the firmware/ihex2fw tool by including the .ihex2fw.cmd file when present. Signed-off-by: David Woodhouse Reported-and-tested-by: Wang Chen Signed-off-by: Linus Torvalds diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index 3d2f460..c972c0f 100644 --- a/scripts/Makefile.fwinst +++ b/scripts/Makefile.fwinst @@ -28,18 +28,39 @@ endif installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all)) installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/. +# Workaround for make < 3.81, where .SECONDEXPANSION doesn't work. +PHONY += $(INSTALL_FW_PATH)/$$(%) install-all-dirs +$(INSTALL_FW_PATH)/$$(%): install-all-dirs + @true +install-all-dirs: $(installed-fw-dirs) + @true + quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@) cmd_install = $(INSTALL) -m0644 $< $@ $(installed-fw-dirs): $(call cmd,mkdir) -$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)/ +$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %) $(call cmd,install) -.PHONY: __fw_install __fw_modinst FORCE +PHONY += __fw_install __fw_modinst FORCE + +.PHONY: $(PHONY) __fw_install: $(installed-fw) __fw_modinst: $(mod-fw) FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building using $(if_changed{,_dep}). As an optimization, we +# don't need to read them if the target does not exist; we will rebuild +# anyway in that case. + +targets := $(wildcard $(sort $(targets))) +cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + include $(cmd_files) +endif -- cgit v0.10.2 From 2f73ccab5628b4f8e8f4b93fea8082dd31a87a10 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Jul 2008 18:09:12 +0200 Subject: fix build error of arch/ia64/kvm/* Fix calls of smp_call_function*() in arch/ia64/kvm for recent API changes. CC [M] arch/ia64/kvm/kvm-ia64.o arch/ia64/kvm/kvm-ia64.c: In function 'handle_global_purge': arch/ia64/kvm/kvm-ia64.c:398: error: too many arguments to function 'smp_call_function_single' arch/ia64/kvm/kvm-ia64.c: In function 'kvm_vcpu_kick': arch/ia64/kvm/kvm-ia64.c:1696: error: too many arguments to function 'smp_call_function_single' Signed-off-by: Takashi Iwai Acked-by Xiantao Zhang Signed-off-by: Linus Torvalds diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 318b811..68c978b 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -395,7 +395,7 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (kvm->vcpus[i]->cpu != -1) { call_data.vcpu = kvm->vcpus[i]; smp_call_function_single(kvm->vcpus[i]->cpu, - vcpu_global_purge, &call_data, 0, 1); + vcpu_global_purge, &call_data, 1); } else printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); @@ -1693,7 +1693,7 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu) wake_up_interruptible(&vcpu->wq); if (vcpu->guest_mode) - smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0); + smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0); } int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c index 091f936..0c69d9e 100644 --- a/arch/ia64/kvm/kvm_fw.c +++ b/arch/ia64/kvm/kvm_fw.c @@ -130,7 +130,7 @@ static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu) args.cache_type = gr29; args.operation = gr30; smp_call_function(remote_pal_cache_flush, - (void *)&args, 1, 1); + (void *)&args, 1); if (args.status != 0) printk(KERN_ERR"pal_cache_flush error!," "status:0x%lx\n", args.status); -- cgit v0.10.2 From 9354094a95aed456a46b353b1051a7e2fab29045 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 14 Jul 2008 23:29:01 -0700 Subject: x86: fix numaq_tsc_disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: arch/x86/kernel/numaq_32.c: In function ‘numaq_tsc_disable’: arch/x86/kernel/numaq_32.c:99: warning: ‘return’ with a value, in function returning void Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 5b20a5e..a23e823 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -96,7 +96,7 @@ int __init get_memcfg_numaq(void) void __init numaq_tsc_disable(void) { if (!found_numaq) - return -1; + return; if (num_online_nodes() > 1) { printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); -- cgit v0.10.2 From 2567d71cc7acd99f0a0dd02e17fe17fd7df7b30c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Jul 2008 15:02:27 +1000 Subject: x86: fix asm/e820.h for userspace inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit asm-x86/e820.h is included from userspace. 'x86: make e820.c to have common functions' (b79cd8f1268bab57ff85b19d131f7f23deab2dee) broke it: make -C Documentation/lguest cc -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include lguest.c -lz -o lguest In file included from ../../include/asm-x86/bootparam.h:8, from lguest.c:45: ../../include/asm/e820.h:66: error: expected ‘)’ before ‘start’ ../../include/asm/e820.h:67: error: expected ‘)’ before ‘start’ ../../include/asm/e820.h:68: error: expected ‘)’ before ‘start’ ../../include/asm/e820.h:72: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘e820_update_range’ ... Signed-off-by: Rusty Russell Cc: Yinghai Lu Signed-off-by: Ingo Molnar diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 33e793e..06633b0 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -59,6 +59,7 @@ struct e820map { struct e820entry map[E820_X_MAX]; }; +#ifdef __KERNEL__ /* see comment in arch/x86/kernel/e820.c */ extern struct e820map e820; extern struct e820map e820_saved; @@ -115,7 +116,7 @@ extern void setup_memory_map(void); extern char *default_machine_specific_memory_setup(void); extern char *machine_specific_memory_setup(void); extern char *memory_setup(void); - +#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #define ISA_START_ADDRESS 0xa0000 -- cgit v0.10.2